Repository: JetBrains/kotlin-native Branch: archive Commit: 9fb0a75ab17e Files: 2783 Total size: 16.8 MB Directory structure: gitextract__wch_4po/ ├── .clang-format ├── .github/ │ └── ISSUE_TEMPLATE/ │ └── config.yml ├── .gitignore ├── .gitmodules ├── BUILDING_LLVM.md ├── CHANGELOG.md ├── COCOAPODS.md ├── CODE_COVERAGE.md ├── CONCURRENCY.md ├── DEBUGGING.md ├── DISTRO_README.md ├── FAQ.md ├── GRADLE_PLUGIN.md ├── HACKING.md ├── IMMUTABILITY.md ├── INTEROP.md ├── IOS_SYMBOLICATION.md ├── Interop/ │ ├── .idea/ │ │ ├── compiler.xml │ │ ├── gradle.xml │ │ ├── libraries/ │ │ │ ├── Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml │ │ │ └── Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml │ │ └── modules.xml │ ├── Indexer/ │ │ ├── build.gradle │ │ ├── clang.def │ │ ├── prebuilt/ │ │ │ └── nativeInteropStubs/ │ │ │ ├── c/ │ │ │ │ └── clangstubs.c │ │ │ └── kotlin/ │ │ │ └── clang/ │ │ │ └── clang.kt │ │ └── src/ │ │ ├── main/ │ │ │ └── kotlin/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── native/ │ │ │ └── interop/ │ │ │ └── indexer/ │ │ │ ├── HeaderToIdMapper.kt │ │ │ ├── Indexer.kt │ │ │ ├── MacroConstants.kt │ │ │ ├── ModuleSupport.kt │ │ │ ├── NativeIndex.kt │ │ │ └── Utils.kt │ │ └── nativeInteropStubs/ │ │ └── cpp/ │ │ ├── disable-abi-checks.cpp │ │ └── signalChaining.cpp │ ├── JsRuntime/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ ├── js/ │ │ │ └── jsinterop.js │ │ └── kotlin/ │ │ └── jsinterop.kt │ ├── README.md │ ├── Runtime/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── callbacks/ │ │ │ └── c/ │ │ │ └── callbacks.c │ │ ├── jvm/ │ │ │ └── kotlin/ │ │ │ └── kotlinx/ │ │ │ └── cinterop/ │ │ │ ├── JvmCallbacks.kt │ │ │ ├── JvmNativeMem.kt │ │ │ ├── JvmTypes.kt │ │ │ └── JvmUtils.kt │ │ ├── main/ │ │ │ └── kotlin/ │ │ │ └── kotlinx/ │ │ │ └── cinterop/ │ │ │ ├── Generated.kt │ │ │ ├── StableRef.kt │ │ │ ├── Types.kt │ │ │ ├── Utils.kt │ │ │ └── package-info.java │ │ └── native/ │ │ └── kotlin/ │ │ └── kotlinx/ │ │ └── cinterop/ │ │ ├── ForeignException.kt │ │ ├── FunctionPointers.kt │ │ ├── NativeMem.kt │ │ ├── NativeStableRef.kt │ │ ├── NativeTypes.kt │ │ ├── NativeUtils.kt │ │ ├── ObjectiveCImpl.kt │ │ ├── ObjectiveCKClassSupport.kt │ │ ├── ObjectiveCUtils.kt │ │ ├── Pinning.kt │ │ └── internal/ │ │ └── Annotations.kt │ └── StubGenerator/ │ ├── build.gradle │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── native/ │ │ └── interop/ │ │ └── gen/ │ │ ├── AbiSpecific.kt │ │ ├── CWrapperGenerator.kt │ │ ├── CodeBuilders.kt │ │ ├── CodeUtils.kt │ │ ├── Imports.kt │ │ ├── KotlinCodeModel.kt │ │ ├── LibraryUtils.kt │ │ ├── MappingBridgeGenerator.kt │ │ ├── MappingBridgeGeneratorImpl.kt │ │ ├── Mappings.kt │ │ ├── ObjCStubs.kt │ │ ├── SimpleBridgeGenerator.kt │ │ ├── SimpleBridgeGeneratorImpl.kt │ │ ├── StructRendering.kt │ │ ├── StubIr.kt │ │ ├── StubIrBridgeBuilder.kt │ │ ├── StubIrBuilder.kt │ │ ├── StubIrDriver.kt │ │ ├── StubIrElementBuilders.kt │ │ ├── StubIrExtensions.kt │ │ ├── StubIrMetadataEmitter.kt │ │ ├── StubIrTextEmitter.kt │ │ ├── StubIrType.kt │ │ ├── StubIrVisitor.kt │ │ ├── TypeUtils.kt │ │ ├── defFileDependencies.kt │ │ ├── jvm/ │ │ │ ├── CommandLine.kt │ │ │ ├── GenerationMode.kt │ │ │ ├── InteropConfiguration.kt │ │ │ ├── InteropLibraryCreation.kt │ │ │ ├── ToolConfig.kt │ │ │ └── main.kt │ │ └── wasm/ │ │ ├── StubGenerator.kt │ │ └── idl/ │ │ ├── dom.kt │ │ ├── idl.kt │ │ └── idlMath.kt │ └── test/ │ └── kotlin/ │ └── org/ │ └── jetbrains/ │ └── kotlin/ │ └── native/ │ └── interop/ │ └── gen/ │ └── StubIrToMetadataTests.kt ├── LIBRARIES.md ├── LICENSE ├── MULTIPLATFORM.md ├── OBJC_INTEROP.md ├── PLATFORM_LIBS.md ├── README.md ├── RELEASE_NOTES.md ├── _nav_reference.yml ├── backend.native/ │ ├── build.gradle │ ├── compiler/ │ │ └── ir/ │ │ └── backend.native/ │ │ ├── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition │ │ └── src/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ ├── backend/ │ │ │ ├── common/ │ │ │ │ └── AbstractValueUsageTransformer.kt │ │ │ └── konan/ │ │ │ ├── BinaryType.kt │ │ │ ├── BitcodeCompiler.kt │ │ │ ├── BitcodeEmbedding.kt │ │ │ ├── Boxing.kt │ │ │ ├── BuiltInFictitiousFunctionIrClassFactory.kt │ │ │ ├── CAdapterCompile.kt │ │ │ ├── CAdapterGenerator.kt │ │ │ ├── CStubsManager.kt │ │ │ ├── CacheSupport.kt │ │ │ ├── CachedLibraries.kt │ │ │ ├── CodeGenerationInfo.kt │ │ │ ├── CompilerOutput.kt │ │ │ ├── Context.kt │ │ │ ├── DestroyRuntimeMode.kt │ │ │ ├── EntryPoint.kt │ │ │ ├── EnumSpecialDescriptorsFactory.kt │ │ │ ├── Exceptions.kt │ │ │ ├── FeaturedLibraries.kt │ │ │ ├── GraphAlgorithms.kt │ │ │ ├── InlineClasses.kt │ │ │ ├── InternalAbi.kt │ │ │ ├── InteropUtils.kt │ │ │ ├── KonanBackendContext.kt │ │ │ ├── KonanCompilerFrontendServices.kt │ │ │ ├── KonanConfig.kt │ │ │ ├── KonanConfigurationKeys.kt │ │ │ ├── KonanDriver.kt │ │ │ ├── KonanFqNames.kt │ │ │ ├── KonanLibrariesResolveSupport.kt │ │ │ ├── KonanLoweringPhases.kt │ │ │ ├── KonanReflectionTypes.kt │ │ │ ├── Linker.kt │ │ │ ├── LlvmModuleSpecification.kt │ │ │ ├── LlvmModuleSpecificationImpl.kt │ │ │ ├── MemoryModel.kt │ │ │ ├── ObjCInterop.kt │ │ │ ├── OptimizationPipeline.kt │ │ │ ├── OutputFiles.kt │ │ │ ├── PsiToIr.kt │ │ │ ├── Reporting.kt │ │ │ ├── RuntimeNames.kt │ │ │ ├── TestRunnerKind.kt │ │ │ ├── TopDownAnalyzerFacadeForKonan.kt │ │ │ ├── ToplevelPhases.kt │ │ │ ├── cgen/ │ │ │ │ ├── CBridgeGen.kt │ │ │ │ ├── CBridgeGenUtils.kt │ │ │ │ ├── CSyntaxSupport.kt │ │ │ │ └── InteropIrUtils.kt │ │ │ ├── descriptors/ │ │ │ │ ├── ClassLayoutBuilder.kt │ │ │ │ ├── DeepPrintVisitor.kt │ │ │ │ ├── DeepVisitor.kt │ │ │ │ ├── DescriptorUtils.kt │ │ │ │ ├── KonanSharedVariablesManager.kt │ │ │ │ ├── LegacyDescriptorUtils.kt │ │ │ │ └── utils.kt │ │ │ ├── injection.kt │ │ │ ├── ir/ │ │ │ │ ├── FakeIrUtils.kt │ │ │ │ ├── Ir.kt │ │ │ │ ├── IrTypeAsKotlinType.kt │ │ │ │ ├── ModuleIndex.kt │ │ │ │ ├── NewIrUtils.kt │ │ │ │ └── interop/ │ │ │ │ ├── DescriptorToIrTranslationUtils.kt │ │ │ │ ├── IrProviderForCEnumAndCStructStubs.kt │ │ │ │ ├── cenum/ │ │ │ │ │ ├── CEnumByValueFunctionGenerator.kt │ │ │ │ │ ├── CEnumClassGenerator.kt │ │ │ │ │ ├── CEnumCompanionGenerator.kt │ │ │ │ │ └── CEnumVarClassGenerator.kt │ │ │ │ └── cstruct/ │ │ │ │ ├── CStructVarClassGenerator.kt │ │ │ │ └── CStructVarCompanionGenerator.kt │ │ │ ├── llvm/ │ │ │ │ ├── BinaryInterface.kt │ │ │ │ ├── BitcodePhases.kt │ │ │ │ ├── CodeGenerator.kt │ │ │ │ ├── ContextUtils.kt │ │ │ │ ├── DataLayout.kt │ │ │ │ ├── DebugUtils.kt │ │ │ │ ├── Dwarf.kt │ │ │ │ ├── EntryPoint.kt │ │ │ │ ├── HashUtils.kt │ │ │ │ ├── Imports.kt │ │ │ │ ├── IntrinsicGenerator.kt │ │ │ │ ├── IrToBitcode.kt │ │ │ │ ├── KotlinObjCClassInfoGenerator.kt │ │ │ │ ├── LlvmAttributes.kt │ │ │ │ ├── LlvmDeclarations.kt │ │ │ │ ├── LlvmLinkOptions.kt │ │ │ │ ├── LlvmUtils.kt │ │ │ │ ├── RTTIGenerator.kt │ │ │ │ ├── RetainAnnotation.kt │ │ │ │ ├── Runtime.kt │ │ │ │ ├── StaticData.kt │ │ │ │ ├── StaticDataUtils.kt │ │ │ │ ├── StaticObjects.kt │ │ │ │ ├── VariableManager.kt │ │ │ │ ├── VerifyModule.kt │ │ │ │ ├── coverage/ │ │ │ │ │ ├── CoverageInformation.kt │ │ │ │ │ ├── CoverageManager.kt │ │ │ │ │ ├── CoverageRegionCollector.kt │ │ │ │ │ ├── LLVMCoverageInstrumentation.kt │ │ │ │ │ └── LLVMCoverageWriter.kt │ │ │ │ ├── objc/ │ │ │ │ │ ├── ObjCCodeGenerator.kt │ │ │ │ │ ├── ObjCDataGenerator.kt │ │ │ │ │ └── linkObjC.kt │ │ │ │ ├── objcexport/ │ │ │ │ │ ├── BlockPointerSupport.kt │ │ │ │ │ └── ObjCExportCodeGenerator.kt │ │ │ │ └── visibility.kt │ │ │ ├── lower/ │ │ │ │ ├── Autoboxing.kt │ │ │ │ ├── BridgesBuilding.kt │ │ │ │ ├── BuiltinOperatorLowering.kt │ │ │ │ ├── CompileTimeEvaluateLowering.kt │ │ │ │ ├── ContractsDslRemover.kt │ │ │ │ ├── DataClassOperatorsLowering.kt │ │ │ │ ├── DelegationLowering.kt │ │ │ │ ├── EnumClassLowering.kt │ │ │ │ ├── EnumConstructorsLowering.kt │ │ │ │ ├── ExpectDeclarationsRemoving.kt │ │ │ │ ├── FinallyBlocksLowering.kt │ │ │ │ ├── FunctionReferenceLowering.kt │ │ │ │ ├── InitializersLowering.kt │ │ │ │ ├── InnerClassLowering.kt │ │ │ │ ├── InteropCallConvertors.kt │ │ │ │ ├── InteropLowering.kt │ │ │ │ ├── KonanDefaultArgumentStubGenerator.kt │ │ │ │ ├── KonanDefaultParameterInjector.kt │ │ │ │ ├── NativeInlineFunctionResolver.kt │ │ │ │ ├── NativeSingleAbstractMethodLowering.kt │ │ │ │ ├── NativeSuspendFunctionLowering.kt │ │ │ │ ├── PostInlineLowering.kt │ │ │ │ ├── PreInlineLowering.kt │ │ │ │ ├── RedundantCoercionsCleaner.kt │ │ │ │ ├── ReflectionSupport.kt │ │ │ │ ├── ReturnsInsertionLowering.kt │ │ │ │ ├── SpecialBackendChecksTraversal.kt │ │ │ │ ├── StringConcatenationLowering.kt │ │ │ │ ├── TestProcessor.kt │ │ │ │ ├── TypeOperatorLowering.kt │ │ │ │ ├── VarargLowering.kt │ │ │ │ └── matchers/ │ │ │ │ ├── IrCallMatcher.kt │ │ │ │ └── IrFunctionMatcher.kt │ │ │ ├── objcexport/ │ │ │ │ ├── CustomTypeMapper.kt │ │ │ │ ├── MethodBridge.kt │ │ │ │ ├── ObjCExport.kt │ │ │ │ ├── ObjCExportCodeSpec.kt │ │ │ │ ├── ObjCExportHeaderGenerator.kt │ │ │ │ ├── ObjCExportHeaderGeneratorImpl.kt │ │ │ │ ├── ObjCExportLazy.kt │ │ │ │ ├── ObjCExportLazyUtils.kt │ │ │ │ ├── ObjCExportMapper.kt │ │ │ │ ├── ObjCExportNamer.kt │ │ │ │ ├── ObjCExportedStubs.kt │ │ │ │ ├── ObjcExportHeaderGeneratorMobile.kt │ │ │ │ ├── StubBuilder.kt │ │ │ │ ├── StubRenderer.kt │ │ │ │ ├── objcTypes.kt │ │ │ │ └── stubs.kt │ │ │ ├── optimizations/ │ │ │ │ ├── CallGraphBuilder.kt │ │ │ │ ├── DFGBuilder.kt │ │ │ │ ├── DataFlowIR.kt │ │ │ │ ├── Devirtualization.kt │ │ │ │ ├── EscapeAnalysis.kt │ │ │ │ └── LocalEscapeAnalysis.kt │ │ │ ├── serialization/ │ │ │ │ ├── IrSerializationUtil.kt │ │ │ │ ├── KonanDeclarationTable.kt │ │ │ │ ├── KonanIdSignaturer.kt │ │ │ │ ├── KonanIrFileSerializer.kt │ │ │ │ ├── KonanIrModuleSerializer.kt │ │ │ │ ├── KonanIrlinker.kt │ │ │ │ ├── KonanMangler.kt │ │ │ │ ├── StringTableUtil.kt │ │ │ │ └── google_descriptor.proto1 │ │ │ └── util/ │ │ │ └── PrimitiveLists.kt │ │ └── ir/ │ │ └── util/ │ │ └── IrUtils2.kt │ ├── llvm.def │ ├── llvm.list │ └── tests/ │ ├── build.gradle │ ├── codegen/ │ │ ├── annotations/ │ │ │ └── annotations0.kt │ │ ├── arithmetic/ │ │ │ ├── basic.kt │ │ │ ├── division.kt │ │ │ └── github1856.kt │ │ ├── associatedObjects/ │ │ │ └── associatedObjects1.kt │ │ ├── basics/ │ │ │ ├── array_to_any.kt │ │ │ ├── canonical_name.kt │ │ │ ├── cast_null.kt │ │ │ ├── cast_simple.kt │ │ │ ├── check_type.kt │ │ │ ├── companion.kt │ │ │ ├── concatenation.kt │ │ │ ├── const_infinity.kt │ │ │ ├── expression_as_statement.kt │ │ │ ├── k42000_1.kt │ │ │ ├── k42000_2.kt │ │ │ ├── local_variable.kt │ │ │ ├── null_check.kt │ │ │ ├── safe_cast.kt │ │ │ ├── spread_operator_0.kt │ │ │ ├── superFunCall.kt │ │ │ ├── superGetterCall.kt │ │ │ ├── superSetterCall.kt │ │ │ ├── typealias1.kt │ │ │ ├── unchecked_cast1.kt │ │ │ ├── unchecked_cast2.kt │ │ │ ├── unchecked_cast3.kt │ │ │ ├── unchecked_cast4.kt │ │ │ ├── unit1.kt │ │ │ ├── unit2.kt │ │ │ ├── unit3.kt │ │ │ └── unit4.kt │ │ ├── boxing/ │ │ │ ├── box_cache0.kt │ │ │ ├── boxing0.kt │ │ │ ├── boxing1.kt │ │ │ ├── boxing10.kt │ │ │ ├── boxing11.kt │ │ │ ├── boxing12.kt │ │ │ ├── boxing13.kt │ │ │ ├── boxing14.kt │ │ │ ├── boxing15.kt │ │ │ ├── boxing2.kt │ │ │ ├── boxing3.kt │ │ │ ├── boxing4.kt │ │ │ ├── boxing5.kt │ │ │ ├── boxing6.kt │ │ │ ├── boxing7.kt │ │ │ ├── boxing8.kt │ │ │ └── boxing9.kt │ │ ├── branching/ │ │ │ ├── advanced_when2.kt │ │ │ ├── advanced_when5.kt │ │ │ ├── if_else.kt │ │ │ ├── when2.kt │ │ │ ├── when4.kt │ │ │ ├── when5.kt │ │ │ ├── when6.kt │ │ │ ├── when7.kt │ │ │ ├── when8.kt │ │ │ ├── when9.kt │ │ │ ├── when_through.kt │ │ │ └── when_with_try1.kt │ │ ├── bridges/ │ │ │ ├── linkTest2_lib.kt │ │ │ ├── linkTest2_main.kt │ │ │ ├── linkTest_lib.kt │ │ │ ├── linkTest_main.kt │ │ │ ├── nativePointed.kt │ │ │ ├── returnTypeSignature.kt │ │ │ ├── special.kt │ │ │ ├── specialGeneric.kt │ │ │ ├── test0.kt │ │ │ ├── test1.kt │ │ │ ├── test10.kt │ │ │ ├── test11.kt │ │ │ ├── test12.kt │ │ │ ├── test13.kt │ │ │ ├── test14.kt │ │ │ ├── test15.kt │ │ │ ├── test16.kt │ │ │ ├── test17.kt │ │ │ ├── test18.kt │ │ │ ├── test2.kt │ │ │ ├── test3.kt │ │ │ ├── test4.kt │ │ │ ├── test5.kt │ │ │ ├── test6.kt │ │ │ ├── test7.kt │ │ │ ├── test8.kt │ │ │ └── test9.kt │ │ ├── classDelegation/ │ │ │ ├── generic.kt │ │ │ ├── linkTest_lib.kt │ │ │ ├── linkTest_main.kt │ │ │ ├── method.kt │ │ │ ├── property.kt │ │ │ └── withBridge.kt │ │ ├── contracts/ │ │ │ └── contracts.kt │ │ ├── controlflow/ │ │ │ ├── break.kt │ │ │ ├── break1.kt │ │ │ ├── for_loops.kt │ │ │ ├── for_loops_array.kt │ │ │ ├── for_loops_array_break_continue.kt │ │ │ ├── for_loops_array_indices.kt │ │ │ ├── for_loops_array_mutation.kt │ │ │ ├── for_loops_array_nested.kt │ │ │ ├── for_loops_array_nullable.kt │ │ │ ├── for_loops_array_side_effects.kt │ │ │ ├── for_loops_call_order.kt │ │ │ ├── for_loops_coroutines.kt │ │ │ ├── for_loops_empty_range.kt │ │ │ ├── for_loops_errors.kt │ │ │ ├── for_loops_let_with_nullable.kt │ │ │ ├── for_loops_nested.kt │ │ │ ├── for_loops_overflow.kt │ │ │ ├── for_loops_types.kt │ │ │ └── unreachable1.kt │ │ ├── coroutines/ │ │ │ ├── anonymousObject.kt │ │ │ ├── controlFlow_chain.kt │ │ │ ├── controlFlow_finally1.kt │ │ │ ├── controlFlow_finally2.kt │ │ │ ├── controlFlow_finally3.kt │ │ │ ├── controlFlow_finally4.kt │ │ │ ├── controlFlow_finally5.kt │ │ │ ├── controlFlow_finally6.kt │ │ │ ├── controlFlow_finally7.kt │ │ │ ├── controlFlow_if1.kt │ │ │ ├── controlFlow_if2.kt │ │ │ ├── controlFlow_inline1.kt │ │ │ ├── controlFlow_inline2.kt │ │ │ ├── controlFlow_inline3.kt │ │ │ ├── controlFlow_tryCatch1.kt │ │ │ ├── controlFlow_tryCatch2.kt │ │ │ ├── controlFlow_tryCatch3.kt │ │ │ ├── controlFlow_tryCatch4.kt │ │ │ ├── controlFlow_tryCatch5.kt │ │ │ ├── controlFlow_while1.kt │ │ │ ├── controlFlow_while2.kt │ │ │ ├── coroutineContext1.kt │ │ │ ├── coroutineContext2.kt │ │ │ ├── correctOrder1.kt │ │ │ ├── degenerate1.kt │ │ │ ├── degenerate2.kt │ │ │ ├── functionReference_eqeq_name.kt │ │ │ ├── functionReference_invokeAsFunction.kt │ │ │ ├── functionReference_lambdaAsSuspendLambda.kt │ │ │ ├── functionReference_simple.kt │ │ │ ├── kt41394.kt │ │ │ ├── returnsNothing1.kt │ │ │ ├── returnsUnit1.kt │ │ │ ├── simple.kt │ │ │ ├── suspendConversion.kt │ │ │ └── withReceiver.kt │ │ ├── cycles/ │ │ │ ├── cycle.kt │ │ │ ├── cycle_do.kt │ │ │ └── cycle_for.kt │ │ ├── dataflow/ │ │ │ ├── scope1.kt │ │ │ └── uninitialized_val.kt │ │ ├── delegatedProperty/ │ │ │ ├── correctFieldsOrder_lib.kt │ │ │ ├── correctFieldsOrder_main.kt │ │ │ ├── delegatedOverride_lib.kt │ │ │ ├── delegatedOverride_main.kt │ │ │ ├── lazy.kt │ │ │ ├── local.kt │ │ │ ├── map.kt │ │ │ ├── observable.kt │ │ │ ├── packageLevel.kt │ │ │ ├── simpleVal.kt │ │ │ └── simpleVar.kt │ │ ├── devirtualization/ │ │ │ ├── anonymousObject.kt │ │ │ ├── getter_looking_as_box_function.kt │ │ │ └── lateinitInterface.kt │ │ ├── enum/ │ │ │ ├── companionObject.kt │ │ │ ├── interfaceCallNoEntryClass.kt │ │ │ ├── interfaceCallWithEntryClass.kt │ │ │ ├── isFrozen.kt │ │ │ ├── kt38540.kt │ │ │ ├── lambdaInDefault.kt │ │ │ ├── linkTest_lib.kt │ │ │ ├── linkTest_main.kt │ │ │ ├── loop.kt │ │ │ ├── nested.kt │ │ │ ├── reorderedArguments.kt │ │ │ ├── switchLowering.kt │ │ │ ├── test0.kt │ │ │ ├── test1.kt │ │ │ ├── vCallNoEntryClass.kt │ │ │ ├── vCallWithEntryClass.kt │ │ │ ├── valueOf.kt │ │ │ ├── values.kt │ │ │ └── varargParam.kt │ │ ├── escapeAnalysis/ │ │ │ ├── recursion.kt │ │ │ ├── test1.kt │ │ │ ├── test10.kt │ │ │ ├── test11.kt │ │ │ ├── test12.kt │ │ │ ├── test13.kt │ │ │ ├── test2.kt │ │ │ ├── test3.kt │ │ │ ├── test4.kt │ │ │ ├── test5.kt │ │ │ ├── test6.kt │ │ │ ├── test7.kt │ │ │ ├── test8.kt │ │ │ ├── test9.kt │ │ │ └── zeroOutObjectOnAlloc.kt │ │ ├── funInterface/ │ │ │ ├── implIsNotFunction.kt │ │ │ ├── kt43887.kt │ │ │ └── nonTrivialProjectionInSuperType.kt │ │ ├── function/ │ │ │ ├── arithmetic.kt │ │ │ ├── boolean.kt │ │ │ ├── defaults.kt │ │ │ ├── defaults1.kt │ │ │ ├── defaults10.kt │ │ │ ├── defaults2.kt │ │ │ ├── defaults3.kt │ │ │ ├── defaults4.kt │ │ │ ├── defaults5.kt │ │ │ ├── defaults6.kt │ │ │ ├── defaults7.kt │ │ │ ├── defaults8.kt │ │ │ ├── defaults9.kt │ │ │ ├── defaultsFromFakeOverride.kt │ │ │ ├── defaultsWithInlineClasses.kt │ │ │ ├── defaultsWithVarArg1.kt │ │ │ ├── defaultsWithVarArg2.kt │ │ │ ├── eqeq.kt │ │ │ ├── extension.kt │ │ │ ├── intrinsic.kt │ │ │ ├── localFunction.kt │ │ │ ├── localFunction2.kt │ │ │ ├── localFunction3.kt │ │ │ ├── minus_eq.kt │ │ │ ├── named.kt │ │ │ ├── plus_eq.kt │ │ │ ├── referenceBigArity.kt │ │ │ ├── sum.kt │ │ │ ├── sum_3const.kt │ │ │ ├── sum_foo_bar.kt │ │ │ ├── sum_func.kt │ │ │ ├── sum_imm.kt │ │ │ ├── sum_mixed.kt │ │ │ └── sum_silly.kt │ │ ├── initializers/ │ │ │ ├── correctOrder1.kt │ │ │ ├── correctOrder2.kt │ │ │ ├── linkTest1_lib.kt │ │ │ ├── linkTest1_main.kt │ │ │ ├── linkTest2_lib.kt │ │ │ ├── linkTest2_main.kt │ │ │ ├── sharedVarInInitBlock_lib.kt │ │ │ └── sharedVarInInitBlock_main.kt │ │ ├── inline/ │ │ │ ├── changingCapturedLocal.kt │ │ │ ├── classDeclarationInsideInline.kt │ │ │ ├── coercionToUnit.kt │ │ │ ├── correctOrderFunctionReference.kt │ │ │ ├── defaultArgs.kt │ │ │ ├── defaultArgs_linkTest_lib.kt │ │ │ ├── defaultArgs_linkTest_main.kt │ │ │ ├── genericFunctionReference.kt │ │ │ ├── getClass.kt │ │ │ ├── inline0.kt │ │ │ ├── inline1.kt │ │ │ ├── inline10.kt │ │ │ ├── inline11.kt │ │ │ ├── inline12.kt │ │ │ ├── inline13.kt │ │ │ ├── inline14.kt │ │ │ ├── inline15.kt │ │ │ ├── inline16.kt │ │ │ ├── inline17.kt │ │ │ ├── inline18.kt │ │ │ ├── inline19.kt │ │ │ ├── inline2.kt │ │ │ ├── inline20.kt │ │ │ ├── inline21.kt │ │ │ ├── inline22.kt │ │ │ ├── inline23.kt │ │ │ ├── inline24.kt │ │ │ ├── inline25.kt │ │ │ ├── inline26.kt │ │ │ ├── inline3.kt │ │ │ ├── inline4.kt │ │ │ ├── inline5.kt │ │ │ ├── inline6.kt │ │ │ ├── inline7.kt │ │ │ ├── inline8.kt │ │ │ ├── inline9.kt │ │ │ ├── inlineCtor_linkTest_lib.kt │ │ │ ├── inlineCtor_linkTest_main.kt │ │ │ ├── lambdaAsAny.kt │ │ │ ├── lambdaInDefaultValue.kt │ │ │ ├── lateinitProperty_linkTest_lib.kt │ │ │ ├── lateinitProperty_linkTest_main.kt │ │ │ ├── localFunctionInInitializerBlock.kt │ │ │ ├── localObjectReturnedFromWhen.kt │ │ │ ├── propertyAccessorInline.kt │ │ │ ├── returnLocalClassFromBlock.kt │ │ │ ├── sharedVar_linkTest_lib.kt │ │ │ ├── sharedVar_linkTest_main.kt │ │ │ ├── statementAsLastExprInBlock.kt │ │ │ ├── twiceInlinedObject.kt │ │ │ └── typeSubstitutionInFakeOverride.kt │ │ ├── inlineClass/ │ │ │ ├── customEquals.kt │ │ │ ├── defaultEquals.kt │ │ │ ├── inlineClass0.kt │ │ │ ├── nestedInlineClasses.kt │ │ │ ├── secondaryConstructorWithGenerics.kt │ │ │ └── valueClass0.kt │ │ ├── innerClass/ │ │ │ ├── doubleInner.kt │ │ │ ├── generic.kt │ │ │ ├── getOuterVal.kt │ │ │ ├── linkTest_lib.kt │ │ │ ├── linkTest_main.kt │ │ │ ├── noPrimaryConstructor.kt │ │ │ ├── qualifiedThis.kt │ │ │ ├── secondaryConstructor.kt │ │ │ ├── simple.kt │ │ │ └── superOuter.kt │ │ ├── interfaceCallsNCasts/ │ │ │ └── conservativeItable.kt │ │ ├── intrinsics/ │ │ │ ├── interop_convert.kt │ │ │ └── interop_sourceCodeStruct.kt │ │ ├── kclass/ │ │ │ ├── kClassEnumArgument.kt │ │ │ ├── kclass0.kt │ │ │ └── kclass1.kt │ │ ├── ktype/ │ │ │ ├── ktype1.kt │ │ │ └── nonReified.kt │ │ ├── lambda/ │ │ │ ├── lambda1.kt │ │ │ ├── lambda10.kt │ │ │ ├── lambda11.kt │ │ │ ├── lambda12.kt │ │ │ ├── lambda13.kt │ │ │ ├── lambda14.kt │ │ │ ├── lambda2.kt │ │ │ ├── lambda3.kt │ │ │ ├── lambda4.kt │ │ │ ├── lambda5.kt │ │ │ ├── lambda6.kt │ │ │ ├── lambda7.kt │ │ │ ├── lambda8.kt │ │ │ └── lambda9.kt │ │ ├── lateinit/ │ │ │ ├── globalIsInitialized.kt │ │ │ ├── inBaseClass.kt │ │ │ ├── initialized.kt │ │ │ ├── innerIsInitialized.kt │ │ │ ├── isInitialized.kt │ │ │ ├── localCapturedInitialized.kt │ │ │ ├── localCapturedNotInitialized.kt │ │ │ ├── localInitialized.kt │ │ │ ├── localNotInitialized.kt │ │ │ └── notInitialized.kt │ │ ├── localClass/ │ │ │ ├── innerTakesCapturedFromOuter.kt │ │ │ ├── innerWithCapture.kt │ │ │ ├── localFunctionCallFromLocalClass.kt │ │ │ ├── localFunctionInLocalClass.kt │ │ │ ├── localHierarchy.kt │ │ │ ├── noPrimaryConstructor.kt │ │ │ ├── objectExpressionInInitializer.kt │ │ │ ├── objectExpressionInProperty.kt │ │ │ ├── tryCatch.kt │ │ │ └── virtualCallFromConstructor.kt │ │ ├── localEscapeAnalysis/ │ │ │ └── arraysFieldWrite.kt │ │ ├── mpp/ │ │ │ ├── libmpp2.kt │ │ │ ├── mpp1.kt │ │ │ ├── mpp2.kt │ │ │ ├── mpp_default_args.kt │ │ │ └── mpp_optional_expectation.kt │ │ ├── object/ │ │ │ ├── constructor.kt │ │ │ ├── constructor0.kt │ │ │ ├── fields.kt │ │ │ ├── fields1.kt │ │ │ ├── fields2.kt │ │ │ ├── globalInitializer.kt │ │ │ ├── init0.kt │ │ │ ├── initialization.kt │ │ │ ├── initialization1.kt │ │ │ └── method_call.kt │ │ ├── objectExpression/ │ │ │ ├── expr1.kt │ │ │ ├── expr2.kt │ │ │ └── expr3.kt │ │ ├── propertyCallableReference/ │ │ │ ├── dynamicReceiver.kt │ │ │ ├── linkTest_lib.kt │ │ │ ├── linkTest_main.kt │ │ │ ├── valClass.kt │ │ │ ├── valExtension.kt │ │ │ ├── valModule.kt │ │ │ ├── varClass.kt │ │ │ ├── varExtension.kt │ │ │ └── varModule.kt │ │ ├── stringTrim/ │ │ │ └── stringTrim.kt │ │ └── try/ │ │ ├── catch3.kt │ │ ├── catch4.kt │ │ ├── catch5.kt │ │ ├── catch6.kt │ │ ├── catch8.kt │ │ ├── finally1.kt │ │ ├── finally10.kt │ │ ├── finally11.kt │ │ ├── finally2.kt │ │ ├── finally3.kt │ │ ├── finally4.kt │ │ ├── finally5.kt │ │ ├── finally6.kt │ │ ├── finally7.kt │ │ ├── finally8.kt │ │ ├── finally9.kt │ │ ├── returnsDifferentTypes.kt │ │ ├── try1.kt │ │ ├── try2.kt │ │ ├── try3.kt │ │ └── try4.kt │ ├── compilerChecks/ │ │ ├── README.md │ │ ├── t1.kt │ │ ├── t10.kt │ │ ├── t11.kt │ │ ├── t12.kt │ │ ├── t13.kt │ │ ├── t14.kt │ │ ├── t15.kt │ │ ├── t16.kt │ │ ├── t17.kt │ │ ├── t18.kt │ │ ├── t2.kt │ │ ├── t20.kt │ │ ├── t21.kt │ │ ├── t22.kt │ │ ├── t23.kt │ │ ├── t24.kt │ │ ├── t25.kt │ │ ├── t26.kt │ │ ├── t27.kt │ │ ├── t28.kt │ │ ├── t29.kt │ │ ├── t3.kt │ │ ├── t30.kt │ │ ├── t31.kt │ │ ├── t32.kt │ │ ├── t33.kt │ │ ├── t34.kt │ │ ├── t35.kt │ │ ├── t36.kt │ │ ├── t37.kt │ │ ├── t38.kt │ │ ├── t4.kt │ │ ├── t40.kt │ │ ├── t41.kt │ │ ├── t42.kt │ │ ├── t43.kt │ │ ├── t44.kt │ │ ├── t45.kt │ │ ├── t46.kt │ │ ├── t47.kt │ │ ├── t48.kt │ │ ├── t49.kt │ │ ├── t5.kt │ │ ├── t50.kt │ │ ├── t51.kt │ │ ├── t52.kt │ │ ├── t53.kt │ │ ├── t54.kt │ │ ├── t55.kt │ │ ├── t56.kt │ │ ├── t57.kt │ │ ├── t58.kt │ │ ├── t59.kt │ │ ├── t6.kt │ │ ├── t60.kt │ │ ├── t7.kt │ │ ├── t8.kt │ │ └── t9.kt │ ├── coverage/ │ │ └── basic/ │ │ ├── controlflow/ │ │ │ └── main.kt │ │ ├── jumps/ │ │ │ └── main.kt │ │ ├── library/ │ │ │ ├── library.kt │ │ │ └── main.kt │ │ ├── program/ │ │ │ └── main.kt │ │ ├── smoke0/ │ │ │ └── smoke0.kt │ │ └── smoke1/ │ │ └── smoke1.kt │ ├── datagen/ │ │ ├── literals/ │ │ │ ├── empty_string.kt │ │ │ ├── listof1.kt │ │ │ ├── strdedup1.kt │ │ │ └── strdedup2.kt │ │ └── rtti/ │ │ ├── abstract_super.kt │ │ ├── vtable1.kt │ │ └── vtable_any.kt │ ├── debugger/ │ │ └── src/ │ │ └── test/ │ │ └── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── native/ │ │ └── test/ │ │ └── debugger/ │ │ ├── DistProperties.kt │ │ ├── Driver.kt │ │ ├── DwarfDumpParser.kt │ │ ├── DwarfTests.kt │ │ ├── LldbTests.kt │ │ └── Matchers.kt │ ├── extensions/ │ │ └── nop/ │ │ └── src/ │ │ └── main/ │ │ └── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── konan/ │ │ └── test/ │ │ └── plugin/ │ │ └── nop/ │ │ └── NopPlugin.kt │ ├── external/ │ │ └── codegen/ │ │ └── box/ │ │ └── properties/ │ │ └── lateinit/ │ │ └── accessor.kt │ ├── framework/ │ │ ├── gh3343/ │ │ │ ├── ktlib.kt │ │ │ ├── objclib.def │ │ │ ├── objclib.h │ │ │ └── uselib.swift │ │ ├── kt42397/ │ │ │ ├── knlibrary.kt │ │ │ └── test.swift │ │ ├── kt43517/ │ │ │ ├── kt43517.def │ │ │ ├── kt43517.kt │ │ │ └── kt43517.swift │ │ ├── main.swift │ │ ├── multiple/ │ │ │ ├── framework1/ │ │ │ │ ├── first.kt │ │ │ │ └── test.kt │ │ │ ├── framework2/ │ │ │ │ ├── second.kt │ │ │ │ └── test.kt │ │ │ ├── multiple.swift │ │ │ └── shared/ │ │ │ └── shared.kt │ │ ├── stdlib/ │ │ │ ├── stdlib.kt │ │ │ └── stdlib.swift │ │ └── values_generics/ │ │ ├── values.swift │ │ └── values_generics.kt │ ├── harmony_regex/ │ │ ├── AllCodePointsTest.kt │ │ ├── MatchResultTest.kt │ │ ├── MatchResultTest2.kt │ │ ├── ModeTest.kt │ │ ├── PatternErrorTest.kt │ │ ├── PatternSyntaxExceptionTest.kt │ │ ├── PatternTest.kt │ │ ├── PatternTest2.kt │ │ ├── ReplaceTest.kt │ │ └── SplitTest.kt │ ├── interop/ │ │ ├── auxiliary_sources/ │ │ │ ├── auxiliaryCppSources.def │ │ │ ├── main.kt │ │ │ ├── name.cpp │ │ │ └── name.h │ │ ├── basics/ │ │ │ ├── 0.kt │ │ │ ├── 1.kt │ │ │ ├── 2.kt │ │ │ ├── 3.kt │ │ │ ├── 4.kt │ │ │ ├── 5.kt │ │ │ ├── arrayPointers.kt │ │ │ ├── bf.kt │ │ │ ├── bitfields.def │ │ │ ├── callbacksAndVarargs.kt │ │ │ ├── carrayPointers.def │ │ │ ├── ccallbacksAndVarargs.def │ │ │ ├── cenums.def │ │ │ ├── cfunptr.def │ │ │ ├── cglobals.def │ │ │ ├── cmacros.def │ │ │ ├── cstdio.def │ │ │ ├── cstructs.def │ │ │ ├── ctoKString.def │ │ │ ├── ctypes.def │ │ │ ├── cunion.def │ │ │ ├── cunsupported.def │ │ │ ├── custom headers/ │ │ │ │ └── custom.h │ │ │ ├── cvalues.def │ │ │ ├── cvectors.def │ │ │ ├── echo_server.kt │ │ │ ├── enums.kt │ │ │ ├── funptr.kt │ │ │ ├── globals.kt │ │ │ ├── macros.kt │ │ │ ├── mangling.def │ │ │ ├── mangling.kt │ │ │ ├── mangling2.def │ │ │ ├── mangling2.kt │ │ │ ├── mangling_keywords.def │ │ │ ├── mangling_keywords.kt │ │ │ ├── mangling_keywords2.def │ │ │ ├── mangling_keywords2.kt │ │ │ ├── opengl_teapot.kt │ │ │ ├── pinning.kt │ │ │ ├── sockets.def │ │ │ ├── structs.kt │ │ │ ├── toKString.kt │ │ │ ├── typedefs.def │ │ │ ├── types.kt │ │ │ ├── unable_to_import.def │ │ │ ├── union.kt │ │ │ ├── unsupported.kt │ │ │ ├── values.kt │ │ │ ├── vectors.kt │ │ │ └── withSpaces.kt │ │ ├── cleaners/ │ │ │ ├── cleaners.kt │ │ │ ├── leak.cpp │ │ │ ├── main_thread.cpp │ │ │ └── second_thread.cpp │ │ ├── concurrentTerminate/ │ │ │ ├── async.cpp │ │ │ ├── async.h │ │ │ ├── concurrentTerminate.def │ │ │ ├── main.cpp │ │ │ ├── main.kt │ │ │ └── reverseInterop.kt │ │ ├── embedStaticLibraries/ │ │ │ ├── 1.c │ │ │ ├── 2.c │ │ │ ├── 3.c │ │ │ ├── 4.c │ │ │ ├── embedStaticLibraries.def │ │ │ ├── embedStaticLibraries.h │ │ │ └── main.kt │ │ ├── incomplete_types/ │ │ │ ├── library.cpp │ │ │ ├── library.def │ │ │ ├── library.h │ │ │ └── main.kt │ │ ├── kt42397/ │ │ │ ├── knlibrary.kt │ │ │ └── test.cpp │ │ ├── kt43265/ │ │ │ ├── kt43265.def │ │ │ └── usage.kt │ │ ├── kt43502/ │ │ │ ├── kt43502.c │ │ │ ├── kt43502.def │ │ │ ├── kt43502.h │ │ │ ├── main.c │ │ │ └── main.kt │ │ ├── leakMemoryWithRunningThread/ │ │ │ ├── checked.kt │ │ │ ├── leakMemory.cpp │ │ │ ├── leakMemory.def │ │ │ ├── leakMemory.h │ │ │ └── unchecked.kt │ │ ├── libiconv.kt │ │ ├── memory_leaks/ │ │ │ ├── lib.kt │ │ │ └── main.cpp │ │ ├── migrating_main_thread/ │ │ │ ├── lib.kt │ │ │ └── main.cpp │ │ ├── objc/ │ │ │ ├── Localizable.stringsdict │ │ │ ├── allocException.kt │ │ │ ├── foreignException/ │ │ │ │ ├── objcExceptionMode.def │ │ │ │ ├── objcExceptionMode.kt │ │ │ │ ├── objc_wrap.def │ │ │ │ ├── objc_wrap.h │ │ │ │ ├── objc_wrap.kt │ │ │ │ └── objc_wrap.m │ │ │ ├── illegal_sharing.kt │ │ │ ├── illegal_sharing_with_weak/ │ │ │ │ ├── main.kt │ │ │ │ ├── objclib.def │ │ │ │ └── objclib.h │ │ │ ├── kt34467/ │ │ │ │ ├── foo.h │ │ │ │ ├── foo.kt │ │ │ │ ├── module_library.def │ │ │ │ ├── module_library.modulemap │ │ │ │ └── module_library_umbrella.h │ │ │ ├── kt42172/ │ │ │ │ ├── main.kt │ │ │ │ ├── objclib.def │ │ │ │ ├── objclib.h │ │ │ │ └── objclib.m │ │ │ ├── msg_send/ │ │ │ │ ├── main.kt │ │ │ │ ├── messaging.def │ │ │ │ ├── messaging.h │ │ │ │ └── messaging.m │ │ │ ├── objcSmoke.def │ │ │ ├── objcTests.def │ │ │ ├── smoke.h │ │ │ ├── smoke.kt │ │ │ ├── smoke.m │ │ │ └── tests/ │ │ │ ├── KT37067_prefix.h │ │ │ ├── KT37067_prefix.kt │ │ │ ├── KT37067_prefix.m │ │ │ ├── KT38234_override.h │ │ │ ├── KT38234_override.kt │ │ │ ├── KT38234_override.m │ │ │ ├── allocNoRetain.h │ │ │ ├── allocNoRetain.kt │ │ │ ├── allocNoRetain.m │ │ │ ├── blocks.h │ │ │ ├── blocks.kt │ │ │ ├── blocks.m │ │ │ ├── callableReferences.h │ │ │ ├── callableReferences.kt │ │ │ ├── callableReferences.m │ │ │ ├── clashingWithAny.h │ │ │ ├── clashingWithAny.kt │ │ │ ├── clashingWithAny.m │ │ │ ├── constructorReturnsNull.h │ │ │ ├── constructorReturnsNull.kt │ │ │ ├── constructorReturnsNull.m │ │ │ ├── conversions.kt │ │ │ ├── customString.h │ │ │ ├── customString.kt │ │ │ ├── customString.m │ │ │ ├── exceptions.h │ │ │ ├── exceptions.kt │ │ │ ├── exceptions.m │ │ │ ├── initWithCustomSelector.h │ │ │ ├── initWithCustomSelector.kt │ │ │ ├── initWithCustomSelector.m │ │ │ ├── kt36766.h │ │ │ ├── kt36766.kt │ │ │ ├── kt41811.h │ │ │ ├── kt41811.kt │ │ │ ├── kt41811.m │ │ │ ├── kt42482.h │ │ │ ├── kt42482.kt │ │ │ ├── kt42482.m │ │ │ ├── main.kt │ │ │ ├── mangling.h │ │ │ ├── mangling.kt │ │ │ ├── mangling.m │ │ │ ├── multipleInheritanceClash.h │ │ │ ├── multipleInheritanceClash.kt │ │ │ ├── multipleInheritanceClash.m │ │ │ ├── nsOutputStream.kt │ │ │ ├── objcWeakRefs.h │ │ │ ├── objcWeakRefs.kt │ │ │ ├── objcWeakRefs.m │ │ │ ├── overrideInit.h │ │ │ ├── overrideInit.kt │ │ │ ├── overrideInit.m │ │ │ ├── sharing.kt │ │ │ ├── structWithNSObject.h │ │ │ ├── structWithNSObject.kt │ │ │ ├── tryRetainGC.h │ │ │ ├── tryRetainGC.kt │ │ │ ├── tryRetainGC.m │ │ │ ├── utils.kt │ │ │ ├── varargs.h │ │ │ ├── varargs.kt │ │ │ ├── varargs.m │ │ │ ├── weakRefs.h │ │ │ ├── weakRefs.kt │ │ │ ├── workerAutoreleasePool.h │ │ │ ├── workerAutoreleasePool.kt │ │ │ └── workerAutoreleasePool.m │ │ ├── objc_with_initializer/ │ │ │ ├── objc_misc.def │ │ │ ├── objc_misc.h │ │ │ ├── objc_misc.m │ │ │ └── objc_test.kt │ │ └── platform_zlib.kt │ ├── iosLauncher/ │ │ ├── .gitignore │ │ ├── KonanTestLauncher/ │ │ │ ├── Assets.xcassets/ │ │ │ │ └── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj/ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ └── Info.plist │ │ └── KonanTestLauncher.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ ├── jsinterop/ │ │ └── math.kt │ ├── link/ │ │ ├── default/ │ │ │ └── default.kt │ │ ├── fake_overrides/ │ │ │ ├── base.kt │ │ │ ├── main.kt │ │ │ ├── move.kt │ │ │ ├── move2.kt │ │ │ └── use.kt │ │ ├── ir_providers/ │ │ │ ├── hello.kt │ │ │ └── library/ │ │ │ ├── empty.kt │ │ │ └── manifest.properties │ │ ├── omit/ │ │ │ ├── hello.kt │ │ │ └── lib.kt │ │ ├── private_fake_overrides/ │ │ │ ├── inherit_lib.kt │ │ │ ├── inherit_main.kt │ │ │ ├── override_lib.kt │ │ │ └── override_main.kt │ │ ├── purge1/ │ │ │ ├── lib.kt │ │ │ └── prog.kt │ │ ├── src/ │ │ │ └── bar.kt │ │ └── versioning/ │ │ ├── empty.kt │ │ └── hello.kt │ ├── lower/ │ │ ├── immutable_blob_in_lambda.kt │ │ ├── local_delegated_property_link/ │ │ │ ├── lib.kt │ │ │ └── main.kt │ │ ├── tailrec.kt │ │ ├── vararg.kt │ │ └── vararg_of_literals.kt │ ├── mangling/ │ │ ├── mangling.kt │ │ └── manglinglib.kt │ ├── objcexport/ │ │ ├── coroutines.kt │ │ ├── coroutines.swift │ │ ├── deallocRetain.kt │ │ ├── deallocRetain.swift │ │ ├── enumValues.kt │ │ ├── enumValues.swift │ │ ├── expectedLazy.h │ │ ├── expectedLazyNoGenerics.h │ │ ├── funInterfaces.kt │ │ ├── funInterfaces.swift │ │ ├── functionalTypes.kt │ │ ├── functionalTypes.swift │ │ ├── gh4002.kt │ │ ├── gh4002.swift │ │ ├── headerWarnings.kt │ │ ├── headerWarnings.swift │ │ ├── kt35940.kt │ │ ├── kt35940.swift │ │ ├── kt38641.kt │ │ ├── kt38641.swift │ │ ├── kt39206.kt │ │ ├── kt39206.swift │ │ ├── kt41907.kt │ │ ├── kt41907.swift │ │ ├── kt43599.kt │ │ ├── kt43599.swift │ │ ├── library/ │ │ │ └── library.kt │ │ ├── library.kt │ │ ├── library.swift │ │ ├── localEA.kt │ │ ├── localEA.swift │ │ ├── overrideKotlinMethods.kt │ │ ├── overrideKotlinMethods.swift │ │ ├── overrideMethodsOfAny.kt │ │ ├── overrideMethodsOfAny.swift │ │ ├── throwsEmpty.kt │ │ ├── topLevelMangling.swift │ │ ├── topLevelManglingA.kt │ │ ├── topLevelManglingB.kt │ │ ├── values.kt │ │ ├── values.swift │ │ ├── variance.kt │ │ └── variance.swift │ ├── produce_dynamic/ │ │ ├── kt-36639/ │ │ │ ├── main.c │ │ │ └── main.kt │ │ └── simple/ │ │ ├── hello.kt │ │ └── main.c │ ├── runtime/ │ │ ├── basic/ │ │ │ ├── args0.kt │ │ │ ├── assert_failed.kt │ │ │ ├── assert_passed.kt │ │ │ ├── cleaner_basic.kt │ │ │ ├── cleaner_in_main_with_checker.kt │ │ │ ├── cleaner_in_main_without_checker.kt │ │ │ ├── cleaner_in_tls_main_with_checker.kt │ │ │ ├── cleaner_in_tls_main_without_checker.kt │ │ │ ├── cleaner_in_tls_worker.kt │ │ │ ├── cleaner_leak_with_checker.kt │ │ │ ├── cleaner_leak_without_checker.kt │ │ │ ├── cleaner_workers.kt │ │ │ ├── driver0.kt │ │ │ ├── empty_substring.kt │ │ │ ├── entry0.kt │ │ │ ├── entry1.kt │ │ │ ├── entry2.kt │ │ │ ├── entry4.kt │ │ │ ├── enum_equals.kt │ │ │ ├── exit.kt │ │ │ ├── for0.kt │ │ │ ├── hash0.kt │ │ │ ├── hello0.kt │ │ │ ├── hello1.kt │ │ │ ├── hello2.kt │ │ │ ├── hello3.kt │ │ │ ├── hello4.kt │ │ │ ├── hypot.kt │ │ │ ├── ieee754.kt │ │ │ ├── init.kt │ │ │ ├── initializers0.kt │ │ │ ├── initializers1.kt │ │ │ ├── initializers2.kt │ │ │ ├── initializers3.kt │ │ │ ├── initializers4.kt │ │ │ ├── initializers5.kt │ │ │ ├── initializers6.kt │ │ │ ├── initializers7.kt │ │ │ ├── initializers8.kt │ │ │ ├── interface0.kt │ │ │ ├── libentry2.kt │ │ │ ├── main_exception.kt │ │ │ ├── random.kt │ │ │ ├── readline0.kt │ │ │ ├── readline1.kt │ │ │ ├── simd.kt │ │ │ ├── standard.kt │ │ │ ├── statements0.kt │ │ │ ├── throw0.kt │ │ │ ├── tostring0.kt │ │ │ ├── tostring1.kt │ │ │ ├── tostring2.kt │ │ │ ├── tostring3.kt │ │ │ └── worker_random.kt │ │ ├── collections/ │ │ │ ├── AbstractMutableCollection.kt │ │ │ ├── BitSet.kt │ │ │ ├── SortWith.kt │ │ │ ├── array0.kt │ │ │ ├── array1.kt │ │ │ ├── array2.kt │ │ │ ├── array3.kt │ │ │ ├── array4.kt │ │ │ ├── array5.kt │ │ │ ├── array_list1.kt │ │ │ ├── array_list2.kt │ │ │ ├── hash_map0.kt │ │ │ ├── hash_map1.kt │ │ │ ├── hash_set0.kt │ │ │ ├── listof0.kt │ │ │ ├── moderately_large_array.kt │ │ │ ├── moderately_large_array1.kt │ │ │ ├── range0.kt │ │ │ ├── sort0.kt │ │ │ ├── sort1.kt │ │ │ ├── stack_array.kt │ │ │ ├── typed_array0.kt │ │ │ └── typed_array1.kt │ │ ├── concurrent/ │ │ │ └── worker_bound_reference0.kt │ │ ├── exceptions/ │ │ │ ├── catch1.kt │ │ │ ├── catch2.kt │ │ │ ├── catch7.kt │ │ │ ├── check_stacktrace_format.kt │ │ │ ├── custom_hook.kt │ │ │ ├── exception_in_global_init.kt │ │ │ ├── extend0.kt │ │ │ ├── kt-37572.kt │ │ │ ├── rethrow.kt │ │ │ ├── stack_trace_inline.kt │ │ │ └── throw_from_catch.kt │ │ ├── memory/ │ │ │ ├── basic0.kt │ │ │ ├── cycle_collector.kt │ │ │ ├── cycle_collector_deadlock1.kt │ │ │ ├── cycle_detector.kt │ │ │ ├── cycles0.kt │ │ │ ├── cycles1.kt │ │ │ ├── escape0.kt │ │ │ ├── escape1.kt │ │ │ ├── escape2.kt │ │ │ ├── leak_memory.kt │ │ │ ├── leak_memory_test_runner.kt │ │ │ ├── only_gc.kt │ │ │ ├── stable_ref_cross_thread_check.kt │ │ │ ├── throw_cleanup.kt │ │ │ ├── var1.kt │ │ │ ├── var2.kt │ │ │ ├── var3.kt │ │ │ ├── var4.kt │ │ │ ├── weak0.kt │ │ │ └── weak1.kt │ │ ├── text/ │ │ │ ├── chars0.kt │ │ │ ├── indexof.kt │ │ │ ├── parse0.kt │ │ │ ├── string0.kt │ │ │ ├── string_builder0.kt │ │ │ ├── string_builder1.kt │ │ │ ├── to_string0.kt │ │ │ ├── trim.kt │ │ │ └── utf8.kt │ │ └── workers/ │ │ ├── atomic0.kt │ │ ├── atomic1.kt │ │ ├── enum_identity.kt │ │ ├── freeze0.kt │ │ ├── freeze1.kt │ │ ├── freeze2.kt │ │ ├── freeze3.kt │ │ ├── freeze4.kt │ │ ├── freeze5.kt │ │ ├── freeze6.kt │ │ ├── freeze_stress.kt │ │ ├── lazy0.kt │ │ ├── lazy1.kt │ │ ├── lazy2.kt │ │ ├── lazy3.kt │ │ ├── leak_memory_with_worker_termination.kt │ │ ├── leak_worker.kt │ │ ├── mutableData1.kt │ │ ├── worker0.kt │ │ ├── worker1.kt │ │ ├── worker10.kt │ │ ├── worker11.kt │ │ ├── worker2.kt │ │ ├── worker3.kt │ │ ├── worker4.kt │ │ ├── worker5.kt │ │ ├── worker6.kt │ │ ├── worker7.kt │ │ ├── worker8.kt │ │ ├── worker9.kt │ │ └── worker_threadlocal_no_leak.kt │ ├── serialization/ │ │ ├── catch.kt │ │ ├── char_const.kt │ │ ├── default_args.kt │ │ ├── deserialize_members.kt │ │ ├── deserialized_fields.kt │ │ ├── deserialized_inline0.kt │ │ ├── deserialized_listof0.kt │ │ ├── do_while.kt │ │ ├── enum_ordinal/ │ │ │ ├── library.kt │ │ │ └── main.kt │ │ ├── prop.kt │ │ ├── regression/ │ │ │ └── no_type_map.kt │ │ ├── serialize_members.kt │ │ ├── use.kt │ │ ├── use_char_const.kt │ │ └── vararg.kt │ ├── stdlib_external/ │ │ ├── collections/ │ │ │ └── KT42428Test.kt │ │ ├── jsCollectionFactoriesActuals.kt │ │ ├── numbers/ │ │ │ ├── HarmonyMathTests.kt │ │ │ ├── MathExceptionTest.kt │ │ │ └── MathTest.kt │ │ ├── text/ │ │ │ ├── CharNativeTest.kt │ │ │ ├── StringEncodingTestNative.kt │ │ │ ├── StringNativeTest.kt │ │ │ ├── _IsCaseIgnorableTest.kt │ │ │ └── _IsCasedTest.kt │ │ └── utils.kt │ ├── testLibrary/ │ │ └── kotlin/ │ │ └── test_platform_lib.kt │ └── testing/ │ ├── annotations.kt │ ├── assertions.kt │ ├── custom_main.kt │ ├── filtered_suites.kt │ ├── filters.kt │ ├── library.kt │ ├── library_user.kt │ └── stacktrace.kt ├── build-tools/ │ ├── build.gradle.kts │ ├── settings.gradle.kts │ └── src/ │ └── main/ │ ├── groovy/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ ├── KonanTest.groovy │ │ └── NativeInteropPlugin.groovy │ └── kotlin/ │ └── org/ │ └── jetbrains/ │ └── kotlin/ │ ├── BenchmarkRepeatingType.kt │ ├── BuildRegister.kt │ ├── CacheTesting.kt │ ├── CollisionDetector.kt │ ├── CollisionTransformer.kt │ ├── CompareDistributionSignatures.kt │ ├── CompilationDatabase.kt │ ├── CopyCommonSources.kt │ ├── CopySamples.kt │ ├── CoverageTest.kt │ ├── EndorsedLibraryInfo.kt │ ├── ExecClang.kt │ ├── ExecLlvm.kt │ ├── ExecutorService.kt │ ├── ExternalReportUtils.kt │ ├── FrameworkTest.kt │ ├── Internals.kt │ ├── KLibInstall.kt │ ├── KonanTestExecutable.kt │ ├── KonanTestSuiteReport.kt │ ├── KotlinBuildPusher.kt │ ├── KotlinNativeTest.kt │ ├── LlvmCovReport.kt │ ├── MPPTools.kt │ ├── MetadataComparisonTest.kt │ ├── MultiModule.kt │ ├── PlatformInfo.kt │ ├── PropertiesProvider.kt │ ├── RegressionsReporter.kt │ ├── RegressionsSummaryReporter.kt │ ├── Reporter.kt │ ├── RunJvmTask.kt │ ├── RunKotlinNativeTask.kt │ ├── TestDirectives.kt │ ├── Utils.kt │ ├── Wrappers.kt │ ├── XcRunRuntimeUtils.kt │ ├── benchmark/ │ │ ├── BenchmarkLogger.kt │ │ ├── BenchmarkingPlugin.kt │ │ ├── CompileBenchmarkingPlugin.kt │ │ ├── KotlinNativeBenchmarkingPlugin.kt │ │ └── SwiftBenchmarkingPlugin.kt │ ├── bitcode/ │ │ ├── CompileToBitcode.kt │ │ └── CompileToBitcodePlugin.kt │ ├── coroutineTestUtil.kt │ ├── genTestKT39548.kt │ ├── klib/ │ │ └── metadata/ │ │ ├── KmComparator.kt │ │ ├── KmComparatorUtils.kt │ │ ├── SortedMergeStrategy.kt │ │ ├── TrivialLibraryProvider.kt │ │ └── comparison.kt │ ├── testing/ │ │ └── native/ │ │ ├── GitDownloadTask.kt │ │ ├── NativeTest.kt │ │ └── RuntimeTestingPlugin.kt │ └── utils/ │ └── DFS.kt ├── build.gradle ├── cmd/ │ ├── cinterop │ ├── cinterop.bat │ ├── generate-platform │ ├── generate-platform.bat │ ├── jsinterop │ ├── jsinterop.bat │ ├── klib │ ├── klib.bat │ ├── konan-lldb │ ├── konanc │ ├── konanc.bat │ ├── kotlinc │ ├── kotlinc-native │ ├── kotlinc-native.bat │ ├── kotlinc.bat │ ├── run_konan │ └── run_konan.bat ├── codestyle/ │ └── cpp/ │ ├── CLionFormat.xml │ └── README.md ├── common/ │ ├── build.gradle.kts │ └── src/ │ ├── files/ │ │ ├── cpp/ │ │ │ └── Files.cpp │ │ └── headers/ │ │ └── Files.h │ └── hash/ │ ├── cpp/ │ │ ├── Base64.cpp │ │ ├── City.cpp │ │ ├── Names.cpp │ │ └── Sha1.cpp │ └── headers/ │ ├── Base64.h │ ├── City.h │ ├── Names.h │ └── Sha1.h ├── dependencies/ │ └── build.gradle ├── dependencyPacker/ │ ├── build.gradle.kts │ ├── linux_llvm_blacklist │ ├── linux_llvm_whitelist │ ├── macos_llvm_whitelist │ ├── mingw_llvm_blacklist │ └── mingw_llvm_whitelist ├── endorsedLibraries/ │ ├── build.gradle │ └── kotlinx.cli/ │ ├── build.gradle │ ├── gradle.properties │ └── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── kotlinx/ │ │ │ └── cli/ │ │ │ ├── ArgParser.kt │ │ │ ├── ArgType.kt │ │ │ ├── ArgumentValues.kt │ │ │ ├── Arguments.kt │ │ │ ├── Descriptors.kt │ │ │ ├── ExperimentalCli.kt │ │ │ └── Options.kt │ │ ├── kotlin-js/ │ │ │ └── kotlinx.cli/ │ │ │ └── Utils.kt │ │ ├── kotlin-jvm/ │ │ │ └── kotlinx/ │ │ │ └── cli/ │ │ │ └── nonStdlibUtils.kt │ │ └── kotlin-native/ │ │ └── kotlinx/ │ │ └── cli/ │ │ └── Utils.kt │ └── tests/ │ ├── ArgumentsTests.kt │ ├── DataSourceEnum.kt │ ├── ErrorTests.kt │ ├── HelpTests.kt │ ├── OptionsTests.kt │ └── SubcommandsTests.kt ├── gradle/ │ ├── kotlinGradlePlugin.gradle │ ├── loadRootProperties.gradle │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── klib/ │ ├── build.gradle │ └── src/ │ ├── main/ │ │ └── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── cli/ │ │ └── klib/ │ │ ├── DeclarationHeaderRenderer.kt │ │ ├── DeclarationPrinter.kt │ │ ├── DefaultDeclarationHeaderRenderer.kt │ │ ├── DefaultIdSignatureRenderer.kt │ │ ├── IdSignatureRenderer.kt │ │ ├── SignaturePrinter.kt │ │ └── main.kt │ └── test/ │ ├── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── cli/ │ │ └── klib/ │ │ └── test/ │ │ └── ContentsTest.kt │ └── testData/ │ ├── Accessors.kt │ ├── Classes.kt │ ├── Constructors.kt │ ├── Enum.kt │ ├── FunctionModifiers.kt │ ├── MethodModality.kt │ ├── Objects.kt │ ├── TopLevelFunctions.kt │ ├── TopLevelPropertiesCustomPackage.kt │ ├── TopLevelPropertiesRootPackage.kt │ ├── TopLevelPropertiesWithClassesCustomPackage.kt │ └── TopLevelPropertiesWithClassesRootPackage.kt ├── konan/ │ ├── konan.properties │ └── platforms/ │ └── zephyr/ │ └── stm32f4_disco ├── libclangext/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── cpp/ │ │ ├── ClangExt.cpp │ │ └── ExtVector.cpp │ └── include/ │ └── clang-c/ │ ├── ExtVector.h │ └── ext.h ├── licenses/ │ ├── LICENSE.txt │ ├── NOTICE.txt │ └── third_party/ │ ├── args4j_LICENSE.txt │ ├── asm_license.txt │ ├── boost_LICENSE.txt │ ├── closure-compiler_LICENSE.txt │ ├── dart_LICENSE.txt │ ├── glibc_license.txt │ ├── harmony_LICENSE.txt │ ├── jshashtable_license.txt │ ├── json_LICENSE.txt │ ├── libffi_license.txt │ ├── llvm_license.txt │ ├── maven_LICENSE.txt │ ├── mimalloc_LICENSE.txt │ ├── pcollections_LICENSE.txt │ ├── prototype_license.txt │ ├── rhino_LICENSE.txt │ ├── scala_license.txt │ ├── sdl_license.txt │ ├── trove_license.txt │ ├── trove_readme_license.txt │ ├── unicode_LICENSE.txt │ ├── zephyr_LICENSE.txt │ └── zlib_license.txt ├── llvmCoverageMappingC/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── cpp/ │ │ └── CoverageMappingC.cpp │ └── include/ │ └── CoverageMappingC.h ├── llvmDebugInfoC/ │ ├── build.gradle │ └── src/ │ ├── dwarf/ │ │ └── include/ │ │ └── dwarf_util.kt.pp │ ├── main/ │ │ ├── cpp/ │ │ │ └── DebugInfoC.cpp │ │ └── include/ │ │ └── DebugInfoC.h │ └── scripts/ │ └── konan_lldb.py ├── performance/ │ ├── KotlinVsSwift/ │ │ ├── build.gradle │ │ └── ring/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ ├── AbstractMethodBenchmark.swift │ │ ├── CallsBenchmark.swift │ │ ├── CastsBenchmark.swift │ │ ├── ClassArrayBenchmark.swift │ │ ├── ClassBaselineBenchmark.swift │ │ ├── ClassListBenchmark.swift │ │ ├── ClassStreamBenchmark.swift │ │ ├── CompanionObjectBenchmark.swift │ │ ├── CoordinatesSolver.swift │ │ ├── Data.swift │ │ ├── DefaultArgumentBenchmark.swift │ │ ├── ElvisBenchmark.swift │ │ ├── EulerBenchmark.swift │ │ ├── FibonacciBenchmark.swift │ │ ├── ForLoopsBenchmark.swift │ │ ├── GraphSolverBenchmark.swift │ │ ├── InlineBenchmark.swift │ │ ├── IntArrayBenchmark.swift │ │ ├── IntBaselineBenchmark.swift │ │ ├── IntStreamBenchmark.swift │ │ ├── LambdaBenchmark.swift │ │ ├── LoopBenchmark.swift │ │ ├── MatrixMapBenchmark.swift │ │ ├── OctoTest.swift │ │ ├── ParameterNotNullAssertionBenchmark.swift │ │ ├── PrimeListBenchmark.swift │ │ ├── StringBenchmark.swift │ │ ├── SwitchBenchmark.swift │ │ ├── Utils.swift │ │ ├── WithIndiciesBenchmark.swift │ │ ├── main.swift │ │ └── zdf_win.swift │ ├── build.gradle │ ├── cinterop/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ ├── main.kt │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── cinteropBenchmarks/ │ │ │ │ ├── structsBenchmark.kt │ │ │ │ ├── structsProducedByMacrosBenchmark.kt │ │ │ │ └── typesBenchmark.kt │ │ │ ├── kotlin-jvm/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── cinteropBenchmarks/ │ │ │ │ ├── structsBenchmark.kt │ │ │ │ ├── structsProducedByMacrosBenchmark.kt │ │ │ │ └── typesBenchmark.kt │ │ │ └── kotlin-native/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── cinteropBenchmarks/ │ │ │ ├── structsBenchmark.kt │ │ │ ├── structsProducedByMacrosBenchmark.kt │ │ │ └── typesBenchmark.kt │ │ └── nativeInterop/ │ │ └── cinterop/ │ │ ├── macros.def │ │ ├── struct.def │ │ └── types.def │ ├── framework/ │ │ ├── build.gradle │ │ └── gradle.properties │ ├── gradle/ │ │ └── compileBenchmark.gradle │ ├── gradle.properties │ ├── helloworld/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ └── kotlin/ │ │ └── main.kt │ ├── numerical/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ ├── main.kt │ │ │ │ └── pi.kt │ │ │ ├── kotlin-jvm/ │ │ │ │ └── launcher.kt │ │ │ └── kotlin-native/ │ │ │ └── launcher.kt │ │ └── nativeInterop/ │ │ └── cinterop/ │ │ ├── cinterop.def │ │ ├── pi.c │ │ └── pi.h │ ├── objcinterop/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ ├── main.kt │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── objCinteropBenchmarks/ │ │ │ │ └── complexNumbers.kt │ │ │ ├── kotlin-jvm/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── objCInteropBenchmarks/ │ │ │ │ └── complexNumbers.kt │ │ │ └── kotlin-native/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── objCinteropBenchmarks/ │ │ │ └── complexNumbers.kt │ │ └── nativeInterop/ │ │ └── cinterop/ │ │ ├── classes.def │ │ ├── complexNumbers.h │ │ └── complexNumbers.m │ ├── ring/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── kotlin/ │ │ │ ├── cleanup.kt │ │ │ ├── main.kt │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── ring/ │ │ │ ├── AbstractMethodBenchmark.kt │ │ │ ├── AllocationBenchmark.kt │ │ │ ├── CallsBenchmark.kt │ │ │ ├── CastsBenchmark.kt │ │ │ ├── ClassArrayBenchmark.kt │ │ │ ├── ClassBaselineBenchmark.kt │ │ │ ├── ClassListBenchmark.kt │ │ │ ├── ClassStreamBenchmark.kt │ │ │ ├── CompanionObjectBenchmark.kt │ │ │ ├── CoordinatesSolver.kt │ │ │ ├── Data.kt │ │ │ ├── DefaultArgumentBenchmark.kt │ │ │ ├── ElvisBenchmark.kt │ │ │ ├── EulerBenchmark.kt │ │ │ ├── FibonacciBenchmark.kt │ │ │ ├── ForLoopsBenchmark.kt │ │ │ ├── GraphSolverBenchmark.kt │ │ │ ├── InheritanceBenchmark.kt │ │ │ ├── InlineBenchmark.kt │ │ │ ├── IntArrayBenchmark.kt │ │ │ ├── IntBaselineBenchmark.kt │ │ │ ├── IntListBenchmark.kt │ │ │ ├── IntStreamBenchmark.kt │ │ │ ├── LambdaBenchmark.kt │ │ │ ├── LinkedListWithAtomicsBenchmark.kt │ │ │ ├── LocalObjectsBenchmark.kt │ │ │ ├── LoopBenchmark.kt │ │ │ ├── MatrixMapBenchmark.kt │ │ │ ├── OctoTest/ │ │ │ │ ├── basicTest.kt │ │ │ │ └── ocTree.kt │ │ │ ├── ParameterNotNullAssertionBenchmark.kt │ │ │ ├── PrimeListBenchmark.kt │ │ │ ├── SingletonBenchmark.kt │ │ │ ├── StringBenchmark.kt │ │ │ ├── SwitchBenchmark.kt │ │ │ ├── Utils.kt │ │ │ ├── WithIndiciesBenchmark.kt │ │ │ └── zdf-win.kt │ │ ├── kotlin-jvm/ │ │ │ ├── FakeKonanNamespace.kt │ │ │ ├── cleanup.kt │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── ring/ │ │ │ └── UtilsJVM.kt │ │ └── kotlin-native/ │ │ ├── cleanup.kt │ │ └── org/ │ │ └── jetbrains/ │ │ └── ring/ │ │ └── Utils.kt │ ├── scripts/ │ │ ├── linux_services.list │ │ └── services.sh │ ├── settings.gradle │ ├── shared/ │ │ └── src/ │ │ └── main/ │ │ ├── kotlin/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── benchmarksLauncher/ │ │ │ ├── BenchmarksCollection.kt │ │ │ ├── JsonReportCreator.kt │ │ │ ├── SwiftLauncher.kt │ │ │ ├── Utils.kt │ │ │ └── launcher.kt │ │ ├── kotlin-jvm/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── benchmarksLauncher/ │ │ │ └── Utils.kt │ │ └── kotlin-native/ │ │ ├── common/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── benchmarksLauncher/ │ │ │ └── Utils.kt │ │ ├── mingw/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── benchmarksLauncher/ │ │ │ └── Utils.kt │ │ └── posix/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── benchmarksLauncher/ │ │ └── Utils.kt │ ├── startup/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ └── kotlin/ │ │ ├── main.kt │ │ └── org/ │ │ └── jetbrains/ │ │ └── startup/ │ │ └── SingletonInitBenchmark.kt │ ├── swiftinterop/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── src/ │ │ │ └── main/ │ │ │ └── kotlin/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ ├── model/ │ │ │ │ └── CityMap.kt │ │ │ └── multigraph/ │ │ │ └── Multigraph.kt │ │ └── swiftSrc/ │ │ ├── benchmarks.swift │ │ └── main.swift │ └── videoplayer/ │ ├── build.gradle.kts │ └── gradle.properties ├── platformLibs/ │ ├── build.gradle │ └── src/ │ └── platform/ │ ├── android/ │ │ ├── android.def │ │ ├── builtin.def │ │ ├── egl.def │ │ ├── gles.def │ │ ├── gles2.def │ │ ├── gles3.def │ │ ├── gles31.def │ │ ├── glesCommon.def │ │ ├── linux.def │ │ ├── media.def │ │ ├── omxal.def │ │ ├── posix.def │ │ ├── sles.def │ │ └── zlib.def │ ├── ios/ │ │ ├── ARKit.def │ │ ├── AVFoundation.def │ │ ├── AVKit.def │ │ ├── Accelerate.def │ │ ├── Accessibility.def │ │ ├── Accounts.def │ │ ├── AdSupport.def │ │ ├── AddressBook.def │ │ ├── AddressBookUI.def │ │ ├── AppClip.def │ │ ├── AppTrackingTransparency.def │ │ ├── AssetsLibrary.def │ │ ├── AudioToolbox.def │ │ ├── AudioUnit.def.disabled │ │ ├── AuthenticationServices.def │ │ ├── AutomaticAssessmentConfiguration.def │ │ ├── BackgroundTasks.def │ │ ├── BusinessChat.def │ │ ├── CFNetwork.def │ │ ├── CallKit.def │ │ ├── CarPlay.def │ │ ├── ClassKit.def │ │ ├── ClockKit.def │ │ ├── CloudKit.def │ │ ├── Combine.def.disabled │ │ ├── CommonCrypto.def │ │ ├── Contacts.def │ │ ├── ContactsUI.def │ │ ├── CoreAudio.def │ │ ├── CoreAudioKit.def │ │ ├── CoreAudioTypes.def │ │ ├── CoreBluetooth.def │ │ ├── CoreData.def │ │ ├── CoreFoundation.def │ │ ├── CoreGraphics.def │ │ ├── CoreHaptics.def │ │ ├── CoreImage.def │ │ ├── CoreLocation.def │ │ ├── CoreMIDI.def │ │ ├── CoreML.def │ │ ├── CoreMedia.def │ │ ├── CoreMotion.def │ │ ├── CoreNFC.def │ │ ├── CoreServices.def │ │ ├── CoreSpotlight.def │ │ ├── CoreTelephony.def │ │ ├── CoreText.def │ │ ├── CoreVideo.def │ │ ├── CryptoKit.def.disabled │ │ ├── CryptoTokenKit.def │ │ ├── DeveloperToolsSupport.def.disabled │ │ ├── DeviceCheck.def │ │ ├── EAGL.def │ │ ├── EventKit.def │ │ ├── EventKitUI.def │ │ ├── ExposureNotification.def │ │ ├── ExternalAccessory.def │ │ ├── FileProvider.def │ │ ├── FileProviderUI.def │ │ ├── Foundation.def │ │ ├── GLKit.def │ │ ├── GSS.def │ │ ├── GameController.def │ │ ├── GameKit.def │ │ ├── GameplayKit.def │ │ ├── HealthKit.def │ │ ├── HealthKitUI.def │ │ ├── HomeKit.def │ │ ├── IOKit.def.disabled │ │ ├── IOSurface.def │ │ ├── IdentityLookup.def │ │ ├── IdentityLookupUI.def │ │ ├── ImageCaptureCore.def │ │ ├── ImageIO.def │ │ ├── Intents.def │ │ ├── IntentsUI.def │ │ ├── JavaScriptCore.def │ │ ├── LinkPresentation.def │ │ ├── LocalAuthentication.def │ │ ├── MLCompute.def │ │ ├── MapKit.def │ │ ├── MediaAccessibility.def │ │ ├── MediaPlayer.def │ │ ├── MediaSetup.def │ │ ├── MediaToolbox.def │ │ ├── MessageUI.def │ │ ├── Messages.def │ │ ├── Metal.def │ │ ├── MetalKit.def │ │ ├── MetalPerformanceShaders.def │ │ ├── MetalPerformanceShadersGraph.def │ │ ├── MetricKit.def │ │ ├── MobileCoreServices.def │ │ ├── ModelIO.def │ │ ├── MultipeerConnectivity.def │ │ ├── NaturalLanguage.def │ │ ├── NearbyInteraction.def │ │ ├── Network.def │ │ ├── NetworkExtension.def │ │ ├── NewsstandKit.def │ │ ├── NotificationCenter.def │ │ ├── OSLog.def.disabled │ │ ├── OpenAL.def │ │ ├── OpenGLES.def │ │ ├── OpenGLES2.def │ │ ├── OpenGLES3.def │ │ ├── OpenGLESCommon.def │ │ ├── PDFKit.def │ │ ├── PassKit.def │ │ ├── PencilKit.def │ │ ├── Photos.def │ │ ├── PhotosUI.def │ │ ├── PushKit.def │ │ ├── QuartzCore.def │ │ ├── QuickLook.def │ │ ├── QuickLookThumbnailing.def │ │ ├── RealityKit.def.disabled │ │ ├── ReplayKit.def │ │ ├── SafariServices.def │ │ ├── SceneKit.def │ │ ├── ScreenTime.def │ │ ├── Security.def │ │ ├── SensorKit.def │ │ ├── Social.def │ │ ├── SoundAnalysis.def │ │ ├── Speech.def │ │ ├── SpriteKit.def │ │ ├── StoreKit.def │ │ ├── SwiftUI.def.disabled │ │ ├── SystemConfiguration.def │ │ ├── Twitter.def │ │ ├── UIKit.def │ │ ├── UniformTypeIdentifiers.def │ │ ├── UserNotifications.def │ │ ├── UserNotificationsUI.def │ │ ├── VideoSubscriberAccount.def │ │ ├── VideoToolbox.def │ │ ├── Vision.def │ │ ├── VisionKit.def │ │ ├── WatchConnectivity.def │ │ ├── WebKit.def │ │ ├── WidgetKit.def.disabled │ │ ├── _AVKit_SwiftUI.def.disabled │ │ ├── _AuthenticationServices_SwiftUI.def.disabled │ │ ├── _HomeKit_SwiftUI.def.disabled │ │ ├── _MapKit_SwiftUI.def.disabled │ │ ├── _QuickLook_SwiftUI.def.disabled │ │ ├── _SceneKit_SwiftUI.def.disabled │ │ ├── _SpriteKit_SwiftUI.def.disabled │ │ ├── _StoreKit_SwiftUI.def.disabled │ │ ├── builtin.def │ │ ├── darwin.def │ │ ├── iAd.def │ │ ├── iconv.def │ │ ├── objc.def │ │ ├── posix.def │ │ ├── set_depends.sh │ │ └── zlib.def │ ├── linux/ │ │ ├── builtin.def │ │ ├── iconv.def │ │ ├── linux.def │ │ ├── posix.def │ │ └── zlib.def │ ├── mingw/ │ │ ├── builtin.def │ │ ├── gdiplus.def │ │ ├── iconv.def │ │ ├── opengl32.def │ │ ├── posix.def │ │ ├── windows.def │ │ └── zlib.def │ ├── osx/ │ │ ├── AGL.def.disabled │ │ ├── AVFoundation.def │ │ ├── AVKit.def │ │ ├── Accelerate.def │ │ ├── Accessibility.def │ │ ├── Accounts.def │ │ ├── AdSupport.def │ │ ├── AddressBook.def │ │ ├── AppKit.def │ │ ├── AppTrackingTransparency.def │ │ ├── AppleScriptKit.def.disabled │ │ ├── AppleScriptObjC.def.disabled │ │ ├── ApplicationServices.def │ │ ├── AudioToolbox.def │ │ ├── AudioUnit.def │ │ ├── AudioVideoBridging.def.disabled │ │ ├── AuthenticationServices.def │ │ ├── AutomaticAssessmentConfiguration.def │ │ ├── Automator.def.disabled │ │ ├── BackgroundTasks.def │ │ ├── BusinessChat.def │ │ ├── CFNetwork.def │ │ ├── CalendarStore.def.disabled │ │ ├── CallKit.def │ │ ├── Carbon.def.disabled │ │ ├── ClassKit.def │ │ ├── CloudKit.def │ │ ├── Cocoa.def │ │ ├── Collaboration.def │ │ ├── ColorSync.def.disabled │ │ ├── Combine.def.disabled │ │ ├── CommonCrypto.def │ │ ├── Contacts.def │ │ ├── ContactsUI.def │ │ ├── CoreAudio.def │ │ ├── CoreAudioKit.def │ │ ├── CoreAudioTypes.def │ │ ├── CoreBluetooth.def │ │ ├── CoreData.def │ │ ├── CoreDisplay.def.disabled │ │ ├── CoreFoundation.def │ │ ├── CoreGraphics.def │ │ ├── CoreHaptics.def │ │ ├── CoreImage.def │ │ ├── CoreLocation.def │ │ ├── CoreMIDI.def │ │ ├── CoreMIDIServer.def.disabled │ │ ├── CoreML.def │ │ ├── CoreMedia.def │ │ ├── CoreMediaIO.def.disabled │ │ ├── CoreMotion.def │ │ ├── CoreServices.def │ │ ├── CoreSpotlight.def │ │ ├── CoreTelephony.def │ │ ├── CoreText.def │ │ ├── CoreVideo.def │ │ ├── CoreWLAN.def │ │ ├── CryptoKit.def.disabled │ │ ├── CryptoTokenKit.def │ │ ├── DVDPlayback.def.disabled │ │ ├── DeveloperToolsSupport.def.disabled │ │ ├── DeviceCheck.def │ │ ├── DirectoryService.def.disabled │ │ ├── DiscRecording.def.disabled │ │ ├── DiscRecordingUI.def.disabled │ │ ├── DiskArbitration.def │ │ ├── DriverKit.def.disabled │ │ ├── EventKit.def │ │ ├── ExceptionHandling.def │ │ ├── ExecutionPolicy.def │ │ ├── ExternalAccessory.def │ │ ├── FWAUserLib.def │ │ ├── FileProvider.def │ │ ├── FileProviderUI.def │ │ ├── FinderSync.def │ │ ├── ForceFeedback.def │ │ ├── Foundation.def │ │ ├── GLKit.def │ │ ├── GLUT.def │ │ ├── GSS.def │ │ ├── GameController.def │ │ ├── GameKit.def │ │ ├── GameplayKit.def │ │ ├── HIDDriverKit.def.disabled │ │ ├── Hypervisor.def │ │ ├── ICADevices.def.disabled │ │ ├── IMServicePlugIn.def.disabled │ │ ├── IOBluetooth.def │ │ ├── IOBluetoothUI.def │ │ ├── IOKit.def │ │ ├── IOSurface.def │ │ ├── IOUSBHost.def │ │ ├── IdentityLookup.def │ │ ├── ImageCaptureCore.def │ │ ├── ImageIO.def │ │ ├── InputMethodKit.def.disabled │ │ ├── InstallerPlugins.def.disabled │ │ ├── InstantMessage.def.disabled │ │ ├── Intents.def │ │ ├── JavaFrameEmbedding.def.disabled │ │ ├── JavaNativeFoundation.def │ │ ├── JavaRuntimeSupport.def │ │ ├── JavaScriptCore.def │ │ ├── JavaVM.def.disabled │ │ ├── Kerberos.def.disabled │ │ ├── Kernel.def.disabled │ │ ├── KernelManagement.def │ │ ├── LDAP.def.disabled │ │ ├── LatentSemanticMapping.def.disabled │ │ ├── LinkPresentation.def │ │ ├── LocalAuthentication.def │ │ ├── MLCompute.def │ │ ├── MapKit.def │ │ ├── MediaAccessibility.def │ │ ├── MediaLibrary.def │ │ ├── MediaPlayer.def │ │ ├── MediaToolbox.def │ │ ├── Message.def.disabled │ │ ├── Metal.def │ │ ├── MetalKit.def │ │ ├── MetalPerformanceShaders.def │ │ ├── MetalPerformanceShadersGraph.def │ │ ├── MetricKit.def │ │ ├── ModelIO.def │ │ ├── MorphunAssetsUpdater.def.disabled │ │ ├── MultipeerConnectivity.def │ │ ├── NaturalLanguage.def │ │ ├── NearbyInteraction.def │ │ ├── NetFS.def.disabled │ │ ├── Network.def │ │ ├── NetworkExtension.def │ │ ├── NetworkingDriverKit.def.disabled │ │ ├── NotificationCenter.def │ │ ├── OSAKit.def.disabled │ │ ├── OSLog.def │ │ ├── OpenAL.def.disabled │ │ ├── OpenCL.def.disabled │ │ ├── OpenDirectory.def │ │ ├── OpenGL.def │ │ ├── OpenGL3.def │ │ ├── OpenGLCommon.def │ │ ├── PCIDriverKit.def.disabled │ │ ├── PCSC.def.disabled │ │ ├── PDFKit.def │ │ ├── ParavirtualizedGraphics.def │ │ ├── PassKit.def │ │ ├── PencilKit.def │ │ ├── Photos.def │ │ ├── PhotosUI.def │ │ ├── PreferencePanes.def │ │ ├── PushKit.def │ │ ├── Python.def.disabled │ │ ├── QTKit.def.disabled │ │ ├── Quartz.def │ │ ├── QuartzCore.def │ │ ├── QuickLook.def │ │ ├── QuickLookThumbnailing.def │ │ ├── RealityKit.def.disabled │ │ ├── ReplayKit.def │ │ ├── Ruby.def.disabled │ │ ├── SafariServices.def │ │ ├── SceneKit.def │ │ ├── ScreenSaver.def │ │ ├── ScreenTime.def │ │ ├── ScriptingBridge.def │ │ ├── Security.def │ │ ├── SecurityFoundation.def │ │ ├── SecurityInterface.def │ │ ├── SensorKit.def │ │ ├── ServiceManagement.def │ │ ├── Social.def │ │ ├── SoundAnalysis.def │ │ ├── Speech.def │ │ ├── SpriteKit.def │ │ ├── StoreKit.def │ │ ├── SwiftUI.def.disabled │ │ ├── SyncServices.def.disabled │ │ ├── System.def.disabled │ │ ├── SystemConfiguration.def │ │ ├── SystemExtensions.def │ │ ├── TWAIN.def.disabled │ │ ├── Tcl.def.disabled │ │ ├── Tk.def.disabled │ │ ├── USBDriverKit.def.disabled │ │ ├── UniformTypeIdentifiers.def │ │ ├── UserNotifications.def │ │ ├── UserNotificationsUI.def │ │ ├── VideoDecodeAcceleration.def.disabled │ │ ├── VideoSubscriberAccount.def │ │ ├── VideoToolbox.def │ │ ├── Virtualization.def │ │ ├── Vision.def │ │ ├── WebKit.def │ │ ├── WidgetKit.def.disabled │ │ ├── _AVKit_SwiftUI.def.disabled │ │ ├── _AuthenticationServices_SwiftUI.def.disabled │ │ ├── _MapKit_SwiftUI.def.disabled │ │ ├── _QuickLook_SwiftUI.def.disabled │ │ ├── _SceneKit_SwiftUI.def.disabled │ │ ├── _SpriteKit_SwiftUI.def.disabled │ │ ├── _StoreKit_SwiftUI.def.disabled │ │ ├── builtin.def │ │ ├── darwin.def │ │ ├── iTunesLibrary.def │ │ ├── iconv.def │ │ ├── libkern.def │ │ ├── objc.def │ │ ├── osx.def │ │ ├── posix.def │ │ ├── set_depends.sh │ │ ├── vmnet.def │ │ └── zlib.def │ ├── tvos/ │ │ ├── AVFoundation.def │ │ ├── AVKit.def │ │ ├── Accelerate.def │ │ ├── Accessibility.def │ │ ├── AdSupport.def │ │ ├── AppTrackingTransparency.def │ │ ├── AudioToolbox.def │ │ ├── AudioUnit.def.disabled │ │ ├── AuthenticationServices.def │ │ ├── BackgroundTasks.def │ │ ├── CFNetwork.def │ │ ├── CloudKit.def │ │ ├── Combine.def.disabled │ │ ├── CommonCrypto.def │ │ ├── CoreAudio.def │ │ ├── CoreAudioKit.def.disabled │ │ ├── CoreAudioTypes.def │ │ ├── CoreBluetooth.def │ │ ├── CoreData.def │ │ ├── CoreFoundation.def │ │ ├── CoreGraphics.def │ │ ├── CoreHaptics.def │ │ ├── CoreImage.def │ │ ├── CoreLocation.def │ │ ├── CoreML.def │ │ ├── CoreMedia.def │ │ ├── CoreServices.def │ │ ├── CoreSpotlight.def │ │ ├── CoreText.def │ │ ├── CoreVideo.def │ │ ├── CryptoKit.def.disabled │ │ ├── CryptoTokenKit.def │ │ ├── DeveloperToolsSupport.def.disabled │ │ ├── DeviceCheck.def │ │ ├── EAGL.def │ │ ├── ExposureNotification.def.disabled │ │ ├── ExternalAccessory.def │ │ ├── Foundation.def │ │ ├── GLKit.def │ │ ├── GameController.def │ │ ├── GameKit.def │ │ ├── GameplayKit.def │ │ ├── HomeKit.def │ │ ├── IOKit.def.disabled │ │ ├── IOSurface.def │ │ ├── ImageIO.def │ │ ├── Intents.def │ │ ├── IntentsUI.def │ │ ├── JavaScriptCore.def │ │ ├── LinkPresentation.def │ │ ├── LocalAuthentication.def.disabled │ │ ├── MLCompute.def │ │ ├── MapKit.def │ │ ├── MediaAccessibility.def │ │ ├── MediaPlayer.def │ │ ├── MediaToolbox.def │ │ ├── MessageUI.def.disabled │ │ ├── Metal.def │ │ ├── MetalKit.def │ │ ├── MetalPerformanceShaders.def │ │ ├── MetalPerformanceShadersGraph.def │ │ ├── MetricKit.def │ │ ├── MobileCoreServices.def │ │ ├── ModelIO.def │ │ ├── MultipeerConnectivity.def │ │ ├── NaturalLanguage.def │ │ ├── Network.def │ │ ├── OSLog.def.disabled │ │ ├── OpenAL.def │ │ ├── OpenGLES.def │ │ ├── OpenGLES2.def │ │ ├── OpenGLES3.def │ │ ├── OpenGLESCommon.def │ │ ├── Photos.def │ │ ├── PhotosUI.def │ │ ├── QuartzCore.def │ │ ├── ReplayKit.def │ │ ├── SceneKit.def │ │ ├── Security.def │ │ ├── SoundAnalysis.def │ │ ├── SpriteKit.def │ │ ├── StoreKit.def │ │ ├── SwiftUI.def.disabled │ │ ├── SystemConfiguration.def │ │ ├── TVMLKit.def │ │ ├── TVServices.def │ │ ├── TVUIKit.def │ │ ├── UIKit.def │ │ ├── UniformTypeIdentifiers.def │ │ ├── UserNotifications.def │ │ ├── VideoSubscriberAccount.def │ │ ├── VideoToolbox.def │ │ ├── Vision.def │ │ ├── _AVKit_SwiftUI.def.disabled │ │ ├── _AuthenticationServices_SwiftUI.def.disabled │ │ ├── _HomeKit_SwiftUI.def.disabled │ │ ├── _MapKit_SwiftUI.def.disabled │ │ ├── _SceneKit_SwiftUI.def.disabled │ │ ├── _SpriteKit_SwiftUI.def.disabled │ │ ├── _StoreKit_SwiftUI.def.disabled │ │ ├── builtin.def │ │ ├── darwin.def │ │ ├── iconv.def │ │ ├── objc.def │ │ ├── posix.def │ │ ├── set_depends.sh │ │ └── zlib.def │ └── watchos/ │ ├── AVFoundation.def │ ├── AVKit.def │ ├── Accelerate.def │ ├── Accessibility.def │ ├── AuthenticationServices.def │ ├── CFNetwork.def.disabled │ ├── ClockKit.def │ ├── CloudKit.def │ ├── Combine.def.disabled │ ├── CommonCrypto.def │ ├── Contacts.def │ ├── CoreAudio.def │ ├── CoreAudioTypes.def │ ├── CoreBluetooth.def │ ├── CoreData.def │ ├── CoreFoundation.def │ ├── CoreGraphics.def │ ├── CoreLocation.def │ ├── CoreML.def │ ├── CoreMedia.def │ ├── CoreMotion.def │ ├── CoreServices.def │ ├── CoreText.def │ ├── CoreVideo.def │ ├── CryptoKit.def.disabled │ ├── DeveloperToolsSupport.def.disabled │ ├── EventKit.def │ ├── Foundation.def │ ├── GameKit.def │ ├── HealthKit.def │ ├── HomeKit.def │ ├── ImageIO.def │ ├── Intents.def │ ├── MapKit.def │ ├── MediaPlayer.def │ ├── MobileCoreServices.def │ ├── NaturalLanguage.def │ ├── Network.def │ ├── NetworkExtension.def │ ├── PassKit.def │ ├── PushKit.def │ ├── SceneKit.def │ ├── Security.def │ ├── SoundAnalysis.def │ ├── SpriteKit.def │ ├── StoreKit.def │ ├── SwiftUI.def.disabled │ ├── UIKit.def │ ├── UniformTypeIdentifiers.def │ ├── UserNotifications.def │ ├── WatchConnectivity.def │ ├── WatchKit.def │ ├── _AVKit_SwiftUI.def.disabled │ ├── _AuthenticationServices_SwiftUI.def.disabled │ ├── _ClockKit_SwiftUI.def.disabled │ ├── _HomeKit_SwiftUI.def.disabled │ ├── _MapKit_SwiftUI.def.disabled │ ├── _SceneKit_SwiftUI.def.disabled │ ├── _SpriteKit_SwiftUI.def.disabled │ ├── _StoreKit_SwiftUI.def.disabled │ ├── _WatchKit_SwiftUI.def.disabled │ ├── builtin.def │ ├── darwin.def │ ├── iconv.def │ ├── objc.def │ ├── posix.def │ ├── set_depends.sh │ └── zlib.def ├── runtime/ │ ├── CMakeLists.txt │ ├── build.gradle.kts │ ├── generator/ │ │ └── build.gradle │ ├── src/ │ │ ├── debug/ │ │ │ └── cpp/ │ │ │ ├── KDebug.cpp │ │ │ └── SourceInfo.cpp │ │ ├── exceptions_support/ │ │ │ └── cpp/ │ │ │ └── ExceptionsSupport.cpp │ │ ├── launcher/ │ │ │ ├── cpp/ │ │ │ │ ├── androidLauncher.cpp │ │ │ │ ├── androidLauncher.h │ │ │ │ └── launcher.cpp │ │ │ └── js/ │ │ │ ├── index.html │ │ │ └── launcher.js │ │ ├── legacymm/ │ │ │ └── cpp/ │ │ │ ├── CyclicCollector.cpp │ │ │ ├── CyclicCollector.h │ │ │ ├── Memory.cpp │ │ │ └── MemoryPrivate.hpp │ │ ├── main/ │ │ │ ├── cpp/ │ │ │ │ ├── Alignment.hpp │ │ │ │ ├── AlignmentTest.cpp │ │ │ │ ├── Alloc.h │ │ │ │ ├── AllocTest.cpp │ │ │ │ ├── Arrays.cpp │ │ │ │ ├── Atomic.cpp │ │ │ │ ├── Atomic.h │ │ │ │ ├── Boxing.cpp │ │ │ │ ├── Cleaner.cpp │ │ │ │ ├── Cleaner.h │ │ │ │ ├── CleanerTest.cpp │ │ │ │ ├── Common.h │ │ │ │ ├── CompilerExport.cpp │ │ │ │ ├── Console.cpp │ │ │ │ ├── CppSupport.hpp │ │ │ │ ├── DoubleConversions.h │ │ │ │ ├── Exceptions.cpp │ │ │ │ ├── Exceptions.h │ │ │ │ ├── ExecFormat.cpp │ │ │ │ ├── ExecFormat.h │ │ │ │ ├── FinalizerHooks.cpp │ │ │ │ ├── FinalizerHooks.hpp │ │ │ │ ├── FinalizerHooksTest.cpp │ │ │ │ ├── FinalizerHooksTestSupport.cpp │ │ │ │ ├── FinalizerHooksTestSupport.hpp │ │ │ │ ├── FreezeHooks.cpp │ │ │ │ ├── FreezeHooks.hpp │ │ │ │ ├── FreezeHooksTest.cpp │ │ │ │ ├── FreezeHooksTestSupport.cpp │ │ │ │ ├── FreezeHooksTestSupport.hpp │ │ │ │ ├── Interop.cpp │ │ │ │ ├── JSInterop.cpp │ │ │ │ ├── KAssert.cpp │ │ │ │ ├── KAssert.h │ │ │ │ ├── KAssertTest.cpp │ │ │ │ ├── KDebug.h │ │ │ │ ├── KString.cpp │ │ │ │ ├── KString.h │ │ │ │ ├── KotlinMath.cpp │ │ │ │ ├── KotlinMath.h │ │ │ │ ├── Memory.h │ │ │ │ ├── MemorySharedRefs.cpp │ │ │ │ ├── MemorySharedRefs.hpp │ │ │ │ ├── MultiSourceQueue.hpp │ │ │ │ ├── MultiSourceQueueTest.cpp │ │ │ │ ├── Mutex.hpp │ │ │ │ ├── Natives.cpp │ │ │ │ ├── Natives.h │ │ │ │ ├── ObjCExceptions.cpp │ │ │ │ ├── ObjCExceptions.h │ │ │ │ ├── ObjCExport.h │ │ │ │ ├── ObjCExport.mm │ │ │ │ ├── ObjCExportCollectionUtils.mm │ │ │ │ ├── ObjCExportCollections.h │ │ │ │ ├── ObjCExportCoroutines.mm │ │ │ │ ├── ObjCExportErrors.h │ │ │ │ ├── ObjCExportErrors.mm │ │ │ │ ├── ObjCExportExceptionDetails.h │ │ │ │ ├── ObjCExportExceptionDetails.mm │ │ │ │ ├── ObjCExportInit.h │ │ │ │ ├── ObjCExportPrivate.h │ │ │ │ ├── ObjCInterop.h │ │ │ │ ├── ObjCInterop.mm │ │ │ │ ├── ObjCInteropUtils.mm │ │ │ │ ├── ObjCInteropUtilsPrivate.h │ │ │ │ ├── ObjCMMAPI.h │ │ │ │ ├── ObjectTraversal.hpp │ │ │ │ ├── ObjectTraversalTest.cpp │ │ │ │ ├── Operator.cpp │ │ │ │ ├── PointerBits.h │ │ │ │ ├── Porting.cpp │ │ │ │ ├── Porting.h │ │ │ │ ├── PthreadUtils.cpp │ │ │ │ ├── PthreadUtils.h │ │ │ │ ├── Regex.cpp │ │ │ │ ├── ReturnSlot.cpp │ │ │ │ ├── ReturnSlot.h │ │ │ │ ├── Runtime.cpp │ │ │ │ ├── Runtime.h │ │ │ │ ├── SingleLockList.hpp │ │ │ │ ├── SingleLockListTest.cpp │ │ │ │ ├── SourceInfo.h │ │ │ │ ├── StdCppStubs.cpp │ │ │ │ ├── TestSupport.hpp │ │ │ │ ├── TestSupportCompilerGenerated.hpp │ │ │ │ ├── Time.cpp │ │ │ │ ├── ToString.cpp │ │ │ │ ├── TypeInfo.cpp │ │ │ │ ├── TypeInfo.h │ │ │ │ ├── Types.cpp │ │ │ │ ├── Types.h │ │ │ │ ├── Utils.hpp │ │ │ │ ├── UtilsTest.cpp │ │ │ │ ├── Weak.cpp │ │ │ │ ├── Weak.h │ │ │ │ ├── Worker.cpp │ │ │ │ ├── Worker.h │ │ │ │ ├── WorkerBoundReference.cpp │ │ │ │ ├── WorkerBoundReference.h │ │ │ │ ├── dlmalloc/ │ │ │ │ │ └── malloc.cpp │ │ │ │ ├── dtoa/ │ │ │ │ │ ├── cbigint.cpp │ │ │ │ │ ├── cbigint.h │ │ │ │ │ ├── dblparse.cpp │ │ │ │ │ ├── fltconst.h │ │ │ │ │ ├── fltparse.cpp │ │ │ │ │ └── hycomp.h │ │ │ │ ├── math/ │ │ │ │ │ ├── COPYRIGHT │ │ │ │ │ ├── endian.h │ │ │ │ │ ├── fmod.cpp │ │ │ │ │ ├── fmodf.cpp │ │ │ │ │ ├── libm.h │ │ │ │ │ └── scalbn.cpp │ │ │ │ ├── polyhash/ │ │ │ │ │ ├── PolyHash.cpp │ │ │ │ │ ├── PolyHash.h │ │ │ │ │ ├── PolyHashTest.cpp │ │ │ │ │ ├── arm.cpp │ │ │ │ │ ├── arm.h │ │ │ │ │ ├── common.h │ │ │ │ │ ├── naive.h │ │ │ │ │ ├── x86.cpp │ │ │ │ │ └── x86.h │ │ │ │ ├── snprintf/ │ │ │ │ │ ├── AUTHORS │ │ │ │ │ ├── COPYING │ │ │ │ │ └── snprintf.cpp │ │ │ │ ├── utf8/ │ │ │ │ │ ├── checked.h │ │ │ │ │ ├── core.h │ │ │ │ │ ├── unchecked.h │ │ │ │ │ └── with_replacement.h │ │ │ │ └── utf8.h │ │ │ ├── js/ │ │ │ │ └── math.js │ │ │ └── kotlin/ │ │ │ ├── generated/ │ │ │ │ ├── _ArraysNative.kt │ │ │ │ ├── _CharCategories.kt │ │ │ │ ├── _CollectionsNative.kt │ │ │ │ ├── _ComparisonsNative.kt │ │ │ │ ├── _DigitChars.kt │ │ │ │ ├── _LetterChars.kt │ │ │ │ ├── _LowercaseMappings.kt │ │ │ │ ├── _OneToManyLowercaseMappings.kt │ │ │ │ ├── _OneToManyUppercaseMappings.kt │ │ │ │ ├── _StringLowercase.kt │ │ │ │ ├── _StringUppercase.kt │ │ │ │ ├── _StringsNative.kt │ │ │ │ ├── _TitlecaseMappings.kt │ │ │ │ ├── _UArraysNative.kt │ │ │ │ ├── _UppercaseMappings.kt │ │ │ │ └── _WhitespaceChars.kt │ │ │ └── kotlin/ │ │ │ ├── Annotation.kt │ │ │ ├── Annotations.kt │ │ │ ├── Any.kt │ │ │ ├── Array.kt │ │ │ ├── Arrays.kt │ │ │ ├── Assertions.kt │ │ │ ├── Boolean.kt │ │ │ ├── Char.kt │ │ │ ├── CharCode.kt │ │ │ ├── CharSequence.kt │ │ │ ├── Comparable.kt │ │ │ ├── Comparator.kt │ │ │ ├── Enum.kt │ │ │ ├── Exceptions.kt │ │ │ ├── Experimental.kt │ │ │ ├── Function.kt │ │ │ ├── Lazy.kt │ │ │ ├── Nothing.kt │ │ │ ├── Number.kt │ │ │ ├── Numbers.kt │ │ │ ├── Primitives.kt │ │ │ ├── String.kt │ │ │ ├── Throwable.kt │ │ │ ├── Unit.kt │ │ │ ├── annotation/ │ │ │ │ └── Annotations.kt │ │ │ ├── collections/ │ │ │ │ ├── AbstractMutableCollection.kt │ │ │ │ ├── AbstractMutableList.kt │ │ │ │ ├── AbstractMutableMap.kt │ │ │ │ ├── AbstractMutableSet.kt │ │ │ │ ├── ArrayList.kt │ │ │ │ ├── ArraySorting.kt │ │ │ │ ├── ArrayUtil.kt │ │ │ │ ├── Arrays.kt │ │ │ │ ├── Collection.kt │ │ │ │ ├── Collections.kt │ │ │ │ ├── HashMap.kt │ │ │ │ ├── HashSet.kt │ │ │ │ ├── Iterator.kt │ │ │ │ ├── Iterators.kt │ │ │ │ ├── List.kt │ │ │ │ ├── Map.kt │ │ │ │ ├── Maps.kt │ │ │ │ ├── MutableCollections.kt │ │ │ │ ├── RandomAccess.kt │ │ │ │ ├── Set.kt │ │ │ │ └── Sets.kt │ │ │ ├── coroutines/ │ │ │ │ ├── ContinuationImpl.kt │ │ │ │ ├── DebugProbes.kt │ │ │ │ ├── SafeContinuationNative.kt │ │ │ │ ├── SuspendFunction.kt │ │ │ │ ├── cancellation/ │ │ │ │ │ └── CancellationException.kt │ │ │ │ └── intrinsics/ │ │ │ │ └── IntrinsicsNative.kt │ │ │ ├── internal/ │ │ │ │ ├── Annotations.kt │ │ │ │ └── ProgressionUtil.kt │ │ │ ├── io/ │ │ │ │ ├── Console.kt │ │ │ │ └── Serializable.kt │ │ │ ├── math/ │ │ │ │ └── math.kt │ │ │ ├── native/ │ │ │ │ ├── Annotations.kt │ │ │ │ ├── BitSet.kt │ │ │ │ ├── Blob.kt │ │ │ │ ├── Platform.kt │ │ │ │ ├── Runtime.kt │ │ │ │ ├── Text.kt │ │ │ │ ├── ThrowableExtensions.kt │ │ │ │ ├── TypedArrays.kt │ │ │ │ ├── concurrent/ │ │ │ │ │ ├── Annotations.kt │ │ │ │ │ ├── Atomics.kt │ │ │ │ │ ├── Continuation.kt │ │ │ │ │ ├── Freezing.kt │ │ │ │ │ ├── Future.kt │ │ │ │ │ ├── Internal.kt │ │ │ │ │ ├── Lazy.kt │ │ │ │ │ ├── Lock.kt │ │ │ │ │ ├── MutableData.kt │ │ │ │ │ ├── ObjectTransfer.kt │ │ │ │ │ ├── Worker.kt │ │ │ │ │ └── WorkerBoundReference.kt │ │ │ │ ├── internal/ │ │ │ │ │ ├── Annotations.kt │ │ │ │ │ ├── Boxing.kt │ │ │ │ │ ├── Cleaner.kt │ │ │ │ │ ├── Coroutines.kt │ │ │ │ │ ├── Debugging.kt │ │ │ │ │ ├── DefaultConstructorMarker.kt │ │ │ │ │ ├── Enums.kt │ │ │ │ │ ├── FloatingPointParser.kt │ │ │ │ │ ├── FunctionAdapter.kt │ │ │ │ │ ├── GC.kt │ │ │ │ │ ├── HexStringParser.kt │ │ │ │ │ ├── InteropBoxing.kt │ │ │ │ │ ├── IntrinsicType.kt │ │ │ │ │ ├── Intrinsics.kt │ │ │ │ │ ├── KClassImpl.kt │ │ │ │ │ ├── KFunctionImpl.kt │ │ │ │ │ ├── KPropertyImpl.kt │ │ │ │ │ ├── KSuspendFunctionImpl.kt │ │ │ │ │ ├── KTypeImpl.kt │ │ │ │ │ ├── KTypeParameterImpl.kt │ │ │ │ │ ├── KonanCollections.kt │ │ │ │ │ ├── KonanRuntimeTypes.kt │ │ │ │ │ ├── NativePtr.kt │ │ │ │ │ ├── NumberConverter.kt │ │ │ │ │ ├── ObjCExportCoroutines.kt │ │ │ │ │ ├── ObjCExportUtils.kt │ │ │ │ │ ├── Ref.kt │ │ │ │ │ ├── RuntimeUtils.kt │ │ │ │ │ ├── Undefined.kt │ │ │ │ │ ├── Utils.kt │ │ │ │ │ └── test/ │ │ │ │ │ ├── GTestLogger.kt │ │ │ │ │ ├── Launcher.kt │ │ │ │ │ ├── TeamCityLogger.kt │ │ │ │ │ ├── TestListener.kt │ │ │ │ │ ├── TestLogger.kt │ │ │ │ │ ├── TestRunner.kt │ │ │ │ │ ├── TestStatistics.kt │ │ │ │ │ └── TestSuite.kt │ │ │ │ ├── ref/ │ │ │ │ │ ├── Weak.kt │ │ │ │ │ └── WeakPrivate.kt │ │ │ │ └── simd.kt │ │ │ ├── random/ │ │ │ │ └── Random.kt │ │ │ ├── ranges/ │ │ │ │ ├── ProgressionIterators.kt │ │ │ │ ├── Progressions.kt │ │ │ │ ├── Range.kt │ │ │ │ └── Ranges.kt │ │ │ ├── reflect/ │ │ │ │ ├── AssociatedObjects.kt │ │ │ │ ├── KAnnotatedElement.kt │ │ │ │ ├── KCallable.kt │ │ │ │ ├── KClass.kt │ │ │ │ ├── KClassesImpl.kt │ │ │ │ ├── KDeclarationContainer.kt │ │ │ │ ├── KFunction.kt │ │ │ │ ├── KProperty.kt │ │ │ │ └── KType.kt │ │ │ ├── sequences/ │ │ │ │ └── Sequences.kt │ │ │ ├── system/ │ │ │ │ ├── Process.kt │ │ │ │ └── Timing.kt │ │ │ ├── test/ │ │ │ │ ├── Annotation.kt │ │ │ │ └── Assertions.kt │ │ │ ├── text/ │ │ │ │ ├── Appendable.kt │ │ │ │ ├── Char.kt │ │ │ │ ├── CharCategory.kt │ │ │ │ ├── CharacterCodingException.kt │ │ │ │ ├── PatternSyntaxException.kt │ │ │ │ ├── Regex.kt │ │ │ │ ├── StringBuilder.kt │ │ │ │ ├── StringBuilderNative.kt │ │ │ │ ├── StringNumberConversions.kt │ │ │ │ ├── Strings.kt │ │ │ │ └── regex/ │ │ │ │ ├── AbstractCharClass.kt │ │ │ │ ├── AbstractLineTerminator.kt │ │ │ │ ├── CharClass.kt │ │ │ │ ├── Lexer.kt │ │ │ │ ├── MatchResultImpl.kt │ │ │ │ ├── Pattern.kt │ │ │ │ ├── Quantifier.kt │ │ │ │ └── sets/ │ │ │ │ ├── AbstractSet.kt │ │ │ │ ├── AtomicJointSet.kt │ │ │ │ ├── BackReferenceSet.kt │ │ │ │ ├── CharSet.kt │ │ │ │ ├── CompositeRangeSet.kt │ │ │ │ ├── DecomposedCharSet.kt │ │ │ │ ├── DotQuantifierSet.kt │ │ │ │ ├── DotSet.kt │ │ │ │ ├── EOISet.kt │ │ │ │ ├── EOLSet.kt │ │ │ │ ├── EmptySet.kt │ │ │ │ ├── FSets.kt │ │ │ │ ├── GroupQuantifierSet.kt │ │ │ │ ├── HangulDecomposedCharSet.kt │ │ │ │ ├── JointSet.kt │ │ │ │ ├── LeafQuantifierSet.kt │ │ │ │ ├── LeafSet.kt │ │ │ │ ├── LookAheadSets.kt │ │ │ │ ├── LookBehindSets.kt │ │ │ │ ├── NonCapturingJointSet.kt │ │ │ │ ├── PossessiveGroupQuantifierSet.kt │ │ │ │ ├── PossessiveLeafQuantifierSet.kt │ │ │ │ ├── PreviousMatchSet.kt │ │ │ │ ├── QuantifierSet.kt │ │ │ │ ├── RangeSet.kt │ │ │ │ ├── ReluctantGroupQuantifierSet.kt │ │ │ │ ├── ReluctantLeafQuantifierSet.kt │ │ │ │ ├── SOLSet.kt │ │ │ │ ├── SequenceSet.kt │ │ │ │ ├── SingleSet.kt │ │ │ │ ├── SupplementaryCharSet.kt │ │ │ │ ├── SupplementaryRangeSet.kt │ │ │ │ ├── SurrogateCharSets.kt │ │ │ │ ├── SurrogateRangeSet.kt │ │ │ │ ├── UnifiedQuantifierSet.kt │ │ │ │ └── WordBoundarySet.kt │ │ │ └── time/ │ │ │ ├── DurationUnit.kt │ │ │ ├── MonotonicTimeSource.kt │ │ │ └── formatToDecimals.kt │ │ ├── mimalloc/ │ │ │ ├── README.md │ │ │ └── c/ │ │ │ ├── alloc-aligned.c │ │ │ ├── alloc-override-osx.c │ │ │ ├── alloc-override.c │ │ │ ├── alloc-posix.c │ │ │ ├── alloc.c │ │ │ ├── arena.c │ │ │ ├── bitmap.inc.c │ │ │ ├── heap.c │ │ │ ├── include/ │ │ │ │ ├── mimalloc-atomic.h │ │ │ │ ├── mimalloc-internal.h │ │ │ │ ├── mimalloc-new-delete.h │ │ │ │ ├── mimalloc-override.h │ │ │ │ ├── mimalloc-types.h │ │ │ │ └── mimalloc.h │ │ │ ├── init.c │ │ │ ├── options.c │ │ │ ├── os.c │ │ │ ├── page-queue.c │ │ │ ├── page.c │ │ │ ├── random.c │ │ │ ├── region.c │ │ │ ├── segment.c │ │ │ ├── static.c │ │ │ └── stats.c │ │ ├── mm/ │ │ │ └── cpp/ │ │ │ ├── ExceptionObjHolder.cpp │ │ │ ├── ExceptionObjHolderTest.cpp │ │ │ ├── ExtraObjectData.cpp │ │ │ ├── ExtraObjectData.hpp │ │ │ ├── ExtraObjectDataTest.cpp │ │ │ ├── GC.hpp │ │ │ ├── GlobalData.cpp │ │ │ ├── GlobalData.hpp │ │ │ ├── GlobalsRegistry.cpp │ │ │ ├── GlobalsRegistry.hpp │ │ │ ├── InitializationScheme.cpp │ │ │ ├── InitializationScheme.hpp │ │ │ ├── InitializationSchemeTest.cpp │ │ │ ├── Memory.cpp │ │ │ ├── MemoryPrivate.hpp │ │ │ ├── ObjectFactory.hpp │ │ │ ├── ObjectFactoryTest.cpp │ │ │ ├── ObjectOps.cpp │ │ │ ├── ObjectOps.hpp │ │ │ ├── RootSet.cpp │ │ │ ├── RootSet.hpp │ │ │ ├── RootSetTest.cpp │ │ │ ├── ShadowStack.cpp │ │ │ ├── ShadowStack.hpp │ │ │ ├── ShadowStackTest.cpp │ │ │ ├── StableRefRegistry.cpp │ │ │ ├── StableRefRegistry.hpp │ │ │ ├── Stubs.cpp │ │ │ ├── TestSupport.hpp │ │ │ ├── ThreadData.hpp │ │ │ ├── ThreadLocalStorage.cpp │ │ │ ├── ThreadLocalStorage.hpp │ │ │ ├── ThreadLocalStorageTest.cpp │ │ │ ├── ThreadRegistry.cpp │ │ │ ├── ThreadRegistry.hpp │ │ │ ├── ThreadRegistryTest.cpp │ │ │ ├── ThreadState.cpp │ │ │ ├── ThreadState.hpp │ │ │ ├── ThreadStateTest.cpp │ │ │ └── gc/ │ │ │ └── NoOpGC.hpp │ │ ├── objc/ │ │ │ └── cpp/ │ │ │ ├── ObjCExportClasses.mm │ │ │ ├── ObjCExportCollections.mm │ │ │ ├── ObjCExportNumbers.mm │ │ │ └── ObjCInteropUtilsClasses.mm │ │ ├── opt_alloc/ │ │ │ └── cpp/ │ │ │ └── AllocImpl.cpp │ │ ├── profile_runtime/ │ │ │ └── cpp/ │ │ │ └── ProfileRuntime.cpp │ │ ├── relaxed/ │ │ │ └── cpp/ │ │ │ └── MemoryImpl.cpp │ │ ├── release/ │ │ │ └── cpp/ │ │ │ └── SourceInfo.cpp │ │ ├── std_alloc/ │ │ │ └── cpp/ │ │ │ └── AllocImpl.cpp │ │ ├── strict/ │ │ │ └── cpp/ │ │ │ └── MemoryImpl.cpp │ │ └── test_support/ │ │ └── cpp/ │ │ ├── CompilerGenerated.cpp │ │ ├── CompilerGeneratedObjC.mm │ │ └── TestLauncher.cpp │ └── tsan_suppressions.txt ├── samples/ │ ├── README.md │ ├── androidNativeActivity/ │ │ └── README.md │ ├── calculator/ │ │ └── README.md │ ├── cocoapods/ │ │ └── README.md │ ├── coverage/ │ │ └── README.md │ ├── csvparser/ │ │ └── README.md │ ├── curl/ │ │ └── README.md │ ├── echoServer/ │ │ └── README.md │ ├── gitchurn/ │ │ └── README.md │ ├── globalState/ │ │ └── README.md │ ├── gtk/ │ │ └── README.md │ ├── html5Canvas/ │ │ └── README.md │ ├── libcurl/ │ │ └── README.md │ ├── nonBlockingEchoServer/ │ │ └── README.md │ ├── objc/ │ │ └── README.md │ ├── opengl/ │ │ └── README.md │ ├── python_extension/ │ │ └── README.md │ ├── simd/ │ │ └── README.md │ ├── tensorflow/ │ │ └── README.md │ ├── tetris/ │ │ └── README.md │ ├── torch/ │ │ └── README.md │ ├── uikit/ │ │ └── README.md │ ├── videoplayer/ │ │ └── README.md │ ├── watchos/ │ │ └── README.md │ ├── weather_function/ │ │ └── readme.md │ ├── win32/ │ │ └── README.md │ ├── workers/ │ │ └── README.md │ └── zephyr/ │ └── README.md ├── settings.gradle ├── shared/ │ ├── build.gradle.kts │ ├── buildSrc/ │ │ ├── build.gradle │ │ ├── settings.gradle │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── VersionGenerator.java │ ├── settings.gradle.kts │ └── src/ │ ├── library/ │ │ └── kotlin/ │ │ └── org/ │ │ └── jetbrains/ │ │ └── kotlin/ │ │ └── konan/ │ │ └── library/ │ │ ├── KonanLibrary.kt │ │ ├── KonanLibraryLayout.kt │ │ ├── KonanLibraryWriter.kt │ │ ├── SearchPathResolver.kt │ │ └── impl/ │ │ ├── BitcodeWriterImpl.kt │ │ ├── KonanLibraryImpl.kt │ │ ├── KonanLibraryLayoutImpl.kt │ │ └── KonanLibraryWriterImpl.kt │ └── main/ │ └── kotlin/ │ └── org/ │ └── jetbrains/ │ └── kotlin/ │ └── konan/ │ ├── Exceptions.kt │ ├── KonanAbiVersion.kt │ ├── TempFiles.kt │ ├── exec/ │ │ └── ExecuteCommand.kt │ ├── file/ │ │ └── NativeFileType.kt │ ├── target/ │ │ ├── Apple.kt │ │ ├── ClangArgs.kt │ │ ├── Configurables.kt │ │ ├── ConfigurablesExtensions.kt │ │ ├── ConfigurablesImpl.kt │ │ ├── KonanProperties.kt │ │ ├── KonanTargetExtenstions.kt │ │ ├── Linker.kt │ │ ├── Platform.kt │ │ ├── Sanitizer.kt │ │ ├── TargetProperties.kt │ │ └── Xcode.kt │ └── util/ │ ├── DefFile.kt │ ├── DependencyDownloader.kt │ ├── DependencyExtractor.kt │ ├── DependencyProcessor.kt │ ├── PlatformLibsInfo.kt │ └── Substitution.kt ├── tools/ │ ├── benchmarks/ │ │ └── shared/ │ │ └── src/ │ │ └── main/ │ │ └── kotlin/ │ │ ├── analyzer/ │ │ │ ├── FieldChange.kt │ │ │ ├── Statistics.kt │ │ │ ├── SummaryBenchmarksReport.kt │ │ │ └── Utils.kt │ │ └── report/ │ │ ├── BenchmarksReport.kt │ │ └── json/ │ │ ├── ConvertedFromJson.kt │ │ ├── JsonElement.kt │ │ ├── JsonExceptions.kt │ │ ├── JsonParser.kt │ │ ├── JsonTreeParser.kt │ │ └── StringOps.kt │ ├── benchmarksAnalyzer/ │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── settings.gradle │ │ └── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ ├── main.kt │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── renders/ │ │ │ │ ├── HTMLRender.kt │ │ │ │ ├── JsonResultsRender.kt │ │ │ │ ├── MetricResultsRender.kt │ │ │ │ ├── Render.kt │ │ │ │ ├── StatisticsRender.kt │ │ │ │ └── TeamCityStatisticsRender.kt │ │ │ ├── kotlin-js/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── analyzer/ │ │ │ │ └── Utils.kt │ │ │ ├── kotlin-jvm/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── analyzer/ │ │ │ │ └── Utils.kt │ │ │ └── kotlin-native/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── analyzer/ │ │ │ └── Utils.kt │ │ ├── nativeInterop/ │ │ │ └── cinterop/ │ │ │ └── libcurl.def │ │ └── tests/ │ │ └── AnalyzerTests.kt │ ├── kotlin-native-gradle-plugin/ │ │ ├── build.gradle │ │ ├── settings.gradle │ │ └── src/ │ │ ├── main/ │ │ │ ├── kotlin/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── kotlin/ │ │ │ │ └── gradle/ │ │ │ │ └── plugin/ │ │ │ │ ├── experimental/ │ │ │ │ │ └── internal/ │ │ │ │ │ └── KotlinNativePlatform.kt │ │ │ │ └── konan/ │ │ │ │ ├── EnvironmentVariables.kt │ │ │ │ ├── KonanArtifactContainer.kt │ │ │ │ ├── KonanBuildingConfig.kt │ │ │ │ ├── KonanCompileConfig.kt │ │ │ │ ├── KonanInteropLibrary.kt │ │ │ │ ├── KonanLibrariesSpec.kt │ │ │ │ ├── KonanPlugin.kt │ │ │ │ ├── KonanSpecs.kt │ │ │ │ ├── KonanToolRunner.kt │ │ │ │ ├── KotlinNativePlatformPlugin.kt │ │ │ │ └── tasks/ │ │ │ │ ├── KonanBaseTasks.kt │ │ │ │ ├── KonanBuildingTask.kt │ │ │ │ ├── KonanCacheTask.kt │ │ │ │ ├── KonanCompileTask.kt │ │ │ │ ├── KonanCompilerDownloadTask.kt │ │ │ │ └── KonanInteropTask.kt │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── shadow.org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin │ │ └── test/ │ │ ├── groovy/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── gradle/ │ │ │ └── plugin/ │ │ │ └── test/ │ │ │ ├── BaseKonanSpecification.groovy │ │ │ ├── DefaultSpecification.groovy │ │ │ ├── EnvVariableSpecification.groovy │ │ │ ├── IncrementalSpecification.groovy │ │ │ ├── KonanProject.groovy │ │ │ ├── LibrarySpecification.groovy │ │ │ ├── MultiplatformSpecification.groovy │ │ │ ├── PathSpecification.groovy │ │ │ ├── RegressionSpecification.groovy │ │ │ └── TaskSpecification.groovy │ │ └── kotlin/ │ │ ├── CompatibilityTests.kt │ │ ├── PropertiesAsEnvVariablesTest.kt │ │ └── TaskTests.kt │ ├── performance-server/ │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── package.json │ │ ├── settings.gradle │ │ ├── shared/ │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── kotlin/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ ├── buildInfo/ │ │ │ │ └── BuildInfo.kt │ │ │ ├── elastic/ │ │ │ │ ├── ElasticSearchConnector.kt │ │ │ │ └── ElasticSearchIndex.kt │ │ │ └── network/ │ │ │ ├── NetworkConnector.kt │ │ │ └── UrlNetworkConnector.kt │ │ ├── src/ │ │ │ └── main/ │ │ │ ├── kotlin/ │ │ │ │ ├── database/ │ │ │ │ │ ├── BenchmarksIndexesDispatcher.kt │ │ │ │ │ └── DatabaseRequests.kt │ │ │ │ ├── main.kt │ │ │ │ ├── network/ │ │ │ │ │ ├── CachableResponseDispatcher.kt │ │ │ │ │ └── aws/ │ │ │ │ │ └── AWSNetworkUtils.kt │ │ │ │ ├── routes/ │ │ │ │ │ └── route.kt │ │ │ │ └── utils/ │ │ │ │ └── AsyncUtils.kt │ │ │ └── kotlin-js/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── analyzer/ │ │ │ └── Utils.kt │ │ └── ui/ │ │ ├── build.gradle │ │ ├── css/ │ │ │ └── style.css │ │ ├── index.ejs │ │ ├── settings.gradle │ │ └── src/ │ │ └── main/ │ │ └── kotlin/ │ │ └── main.kt │ ├── qemu/ │ │ ├── Dockerfile │ │ ├── build.sh │ │ ├── create_image.sh │ │ └── run_container.sh │ ├── scripts/ │ │ ├── repack_bundles.py │ │ ├── update_apple_frameworks.sh │ │ ├── update_xcode.sh │ │ └── update_zephyr.sh │ └── toolchain_builder/ │ ├── Dockerfile │ ├── README.md │ ├── build_toolchain.sh │ ├── create_image.sh │ ├── patches/ │ │ └── github_pull_1244.patch │ ├── run_container.sh │ └── toolchains/ │ ├── aarch64-unknown-linux-gnu/ │ │ └── gcc-8.3.0-glibc-2.25-kernel-4.9.config │ ├── arm-unknown-linux-gnueabihf/ │ │ └── gcc-8.3.0-glibc-2.19-kernel-4.9.config │ ├── mips-unknown-linux-gnu/ │ │ └── gcc-8.3.0-glibc-2.19-kernel-4.9.config │ ├── mipsel-unknown-linux-gnu/ │ │ └── gcc-8.3.0-glibc-2.19-kernel-4.9.config │ └── x86_64-unknown-linux-gnu/ │ └── gcc-8.3.0-glibc-2.19-kernel-4.9.config └── utilities/ ├── basic-utils/ │ ├── build.gradle.kts │ └── src/ │ └── main/ │ └── kotlin/ │ ├── KonanHomeProvider.kt │ └── NativeMemoryAllocator.kt ├── cli-runner/ │ ├── build.gradle │ └── src/ │ └── main/ │ └── kotlin/ │ └── org/ │ └── jetbrains/ │ └── kotlin/ │ └── cli/ │ └── utilities/ │ ├── GeneratePlatformLibraries.kt │ ├── InteropCompiler.kt │ ├── LlvmClang.kt │ └── main.kt └── env_blacklist ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ # Also see codestyle/cpp/README.md # For documentation on options see: https://releases.llvm.org/8.0.0/tools/clang/docs/ClangFormatStyleOptions.html # "Kt N/A" means that this C/C++/ObjC construct have no corresponding Kotlin construct to refer to # "Kt U" means that formatting is unspecified in Kotlin formatting guide # "Kt " means that this is specified in Kotlin formatting guide with url pointing to it --- DisableFormat: false Standard: Cpp11 # Kt N/A. Different from 0 to make modifiers stand out. An alternative is -2, but it introduces another level of indentation. AccessModifierOffset: -4 # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#method-call-formatting AlignAfterOpenBracket: AlwaysBreak # Kt U. Not touching AlignConsecutiveAssignments: false # Kt U. Not touching AlignConsecutiveDeclarations: false # Kt N/A. Not touching AlignEscapedNewlines: DontAlign # Kt U. Not touching AlignOperands: false # Kt U. Not touching AlignTrailingComments: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#function-formatting AllowAllParametersOfDeclarationOnNextLine: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting-control-flow-statements AllowShortBlocksOnASingleLine: false # Kt U. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#formatting-control-flow-statements # Using false, because case statements usually contain at least 2 statements: doing something + break, which makes them multiline AllowShortCaseLabelsOnASingleLine: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#function-formatting Inline is somewhat close to "single expression" functions AllowShortFunctionsOnASingleLine: Inline # Kt U. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#using-conditional-statements however it mostly refers to the ternary operator. AllowShortIfStatementsOnASingleLine: true # Kt U. Same as previous AllowShortLoopsOnASingleLine: true # Kt N/A. In Kotlin return type is in a trailing position. AlwaysBreakAfterReturnType: None # Kt U. Not touching. AlwaysBreakBeforeMultilineStrings: false # Kt N/A. In Kotlin type parameters are declared inline in a much more compact way. # Using Yes to make it easy to detect function name AlwaysBreakTemplateDeclarations: Yes # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#method-call-formatting BinPackArguments: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#function-formatting BinPackParameters: false BraceWrapping: # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterClass: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterControlStatement: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterEnum: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterFunction: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterNamespace: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterObjCDeclaration: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterStruct: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterUnion: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting AfterExternBlock: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting-control-flow-statements BeforeCatch: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting-control-flow-statements BeforeElse: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting IndentBraces: false # Only used when AfterFunction is true SplitEmptyFunction: true # Only used when AfterRecord is true SplitEmptyRecord: true # Only used if AfterNamespace is true SplitEmptyNamespace: true # Kt U. Break after operators BreakBeforeBinaryOperators: None # Configured by BraceWrapping BreakBeforeBraces: Custom # Kt U. Using true because it looks more like an if-expression with "then" and "else" branches marked "?" and ":" BreakBeforeTernaryOperators: true # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#class-header-formatting AfterColon looks the most consistent BreakConstructorInitializers: AfterColon # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#class-header-formatting BreakInheritanceList: AfterColon # Kt U. Choosing to break long strings to fit into line length BreakStringLiterals: true # Kt U. IDEA displays a vertical guide at 120. Choosing it to avoid very long lines. ColumnLimit: 140 # Kt N/A. Probably should use nested namespaces instead. CompactNamespaces: false # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#class-header-formatting ConstructorInitializerAllOnOneLineOrOnePerLine: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting ConstructorInitializerIndentWidth: 4 # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting IDEA seems to indent continuations with 8 ContinuationIndentWidth: 8 # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace # Braced initalizer braces are close to parens in function call or to brackets in array initialier. And styleguide asks not to put spaces in them. Cpp11BracedListStyle: true # Configured by PointerAlignment DerivePointerAlignment: false # Confgured by BinPack* ExperimentalAutoDetectBinPacking: false # Kt N/A. Setting to true because it helps to see when anonymous namespace ends FixNamespaceComments: true # Kt U. Not touching manually created including blocks IncludeBlocks: Preserve # Kt U. Sorting: main header (priority 0) > system headers > project headers IncludeCategories: - Regex: '^<.*' Priority: 1 - Regex: '.*' Priority: 2 # Kt N/A. Main header must match current filename (modulo extension) exactly. IncludeIsMainRegex: '$' # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting-control-flow-statements IndentCaseLabels: true # Kt N/A. Do not indent macro code IndentPPDirectives: None # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting IndentWidth: 4 # Kt U. IDEA seems to indent IndentWrappedFunctionNames: true # Kt U. Do not touch. KeepEmptyLinesAtTheStartOfBlocks: false # Kt U. IDEA keeps 1 empty line by default. MaxEmptyLinesToKeep: 1 # Kt N/A. NamespaceIndentation: None # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#class-header-formatting ObjCBinPackProtocolList: Never # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting ObjCBlockIndentWidth: 4 # Kt N/A. Following Google and LLVM styleguides. ObjCSpaceAfterProperty: false # Kt N/A. The closest is class inheritance list. Following Google and LLVM styleguides. ObjCSpaceBeforeProtocolList: true # Kt N/A. PointerAlignment: Left # Kt U. Reflow comments to fit into line width ReflowComments: true # Kt U. IDEA does not sort by default, but allows this option. Do not touch. SortIncludes: false # Kt U. Like SortIncludes. SortUsingDeclarations: false # Kt N/A. SpaceAfterCStyleCast: false # Kt N/A. IDEA puts space in `fun ` SpaceAfterTemplateKeyword: true # Kt U. https://kotlinlang.org/docs/reference/coding-conventions.html puts spaces SpaceBeforeAssignmentOperators: true # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace which does not put space before parens and brackets. SpaceBeforeCpp11BracedList: false # Kt N/A. The closest is https://kotlinlang.org/docs/reference/coding-conventions.html#colon SpaceBeforeCtorInitializerColon: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#colon SpaceBeforeInheritanceColon: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpaceBeforeParens: ControlStatements # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpaceBeforeRangeBasedForLoopColon: true # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpaceInEmptyParentheses: false # Kt U. https://kotlinlang.org/docs/reference/coding-conventions.html uses 1 SpacesBeforeTrailingComments: 1 # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpacesInAngles: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpacesInContainerLiterals: false # Kt N/A. SpacesInCStyleCastParentheses: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpacesInParentheses: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#horizontal-whitespace SpacesInSquareBrackets: false # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting TabWidth: 4 # Kt https://kotlinlang.org/docs/reference/coding-conventions.html#formatting UseTab: Never PenaltyBreakAssignment: 2 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 ... ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Report a bug or request a feature url: https://kotl.in/issue about: Use YouTrack for new issues. - name: Ask a question url: https://stackoverflow.com/questions/ask?tags=kotlin-native about: Use StackOverflow with `kotlin-native` tag. - name: Discuss url: https://slack.kotl.in about: Feel free to discuss anything on `#kotlin-native` and `#multiplatform` channels in Slack. ================================================ FILE: .gitignore ================================================ .DS_Store .idea/shelf *.iml /dependencies/all dist kotlin-native-*.tar.gz kotlin-native-*.zip translator/src/test/kotlin/tests/*/linked out tmp workspace.xml *.versionsBackup local.properties .gradle build translator/.gradle/2.9/taskArtifacts kotstd/kotstd.iml # test suit products. *.bc *.bc.o *.kt.S *.kt.exe *.log test.output *.kexe # Ignore Gradle GUI config gradle-app.setting # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar # Cache of project .gradletasknamecache # local project files lib/ .idea/* proto/compiler/protoc-artifacts proto/compiler/tests proto/compiler/google/src/google/protobuf/compiler/kotlin/bin proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc peformance/build # translator auto generated artifacts kotstd/ll # test teamcity property: commitable only with -f backend.native/tests/teamcity-test.property # Sample output samples/**/*.kt.bc-build samples/androidNativeActivity/Polyhedron # CMake llvmCoverageMappingC/CMakeLists.txt tools/performance-server/node_modules tools/performance-server/server tools/performance-server/ui/js runtime/cmake-build-debug/ # compilation database compile_commands.json # clangd caches .clangd/ # googletest framework used by runtime tests runtime/googletest/ # code style !.idea/codeStyles/ # Toolchain builder artifacts tools/toolchain_builder/artifacts # ignore the project model created by CLion (for now). runtime/.idea ================================================ FILE: .gitmodules ================================================ ================================================ FILE: BUILDING_LLVM.md ================================================ # Building LLVM for Kotlin/Native The content of this page is moved to https://github.com/JetBrains/kotlin/blob/master/kotlin-native/BUILDING_LLVM.md ================================================ FILE: CHANGELOG.md ================================================ See also overview here: https://kotlinlang.org/docs/releases.html # 1.5.0 and newer https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md # 1.4.31 (Feb 2021) * [KT-44295](https://youtrack.jetbrains.com/issue/KT-44295) Fix Kotlin/Native compiler crash on Android NDK * [KT-44826](https://youtrack.jetbrains.com/issue/KT-44826) Fix failing build with "Backend Internal error: Exception during IR lowering" * [KT-44764](https://youtrack.jetbrains.com/issue/KT-44764) Fix failing build with "AssertionError: FUN name:onError_6 visibility:public modality:OPEN" * [GH-4588](https://github.com/JetBrains/kotlin-native/pull/4588) Fix runtime crash in createTypeInfo in release framework binaries # 1.4.30 (Feb 2021) * [KT-44083](https://youtrack.jetbrains.com/issue/KT-44083) Fix NSUInteger size for Watchos x64 # 1.4.30-RC (Jan 2021) * [KT-44271](https://youtrack.jetbrains.com/issue/KT-44271) Incorrect linking when targeting linux_x64 from mingw_x64 host * [KT-44219](https://youtrack.jetbrains.com/issue/KT-44219) Non-reified type parameters with recursive bounds are not supported yet * [KT-43599](https://youtrack.jetbrains.com/issue/KT-43599) K/N: Unbound symbols not allowed * [KT-42172](https://youtrack.jetbrains.com/issue/KT-42172) Kotlin/Native: StableRef.dispose race condition on Kotlin deinitRuntime * [KT-42482](https://youtrack.jetbrains.com/issue/KT-42482) Kotlin subclasses of Obj-C classes are incompatible with ISA swizzling (it causes crashes) # 1.4.30-M1 (Dec 2020) * [KT-43597](https://youtrack.jetbrains.com/issue/KT-43597) Xcode 12.2 support * [KT-43276](https://youtrack.jetbrains.com/issue/KT-43276) Add watchos_x64 target * [KT-43198](https://youtrack.jetbrains.com/issue/KT-43198) Init blocks inside of inline classes * [KT-42649](https://youtrack.jetbrains.com/issue/KT-42649) Fix secondary constructors of generic inline classes * [KT-38772](https://youtrack.jetbrains.com/issue/KT-38772) Support non-reified type parameters in typeOf * [KT-42428](https://youtrack.jetbrains.com/issue/KT-42428) Inconsistent behavior of map.entries on Kotlin.Native * Compiler customization * [KT-40584](https://youtrack.jetbrains.com/issue/KT-40584) Untie Kotlin/Native from the fixed LLVM distribution * [KT-42234](https://youtrack.jetbrains.com/issue/KT-42234) Move LLVM optimization parameters into konan.properties * [KT-40670](https://youtrack.jetbrains.com/issue/KT-40670) Allow to override konan.properties via CLI * Runtime * [KT-42822](https://youtrack.jetbrains.com/issue/KT-42822) Kotlin/Native Worker leaks ObjC/Swift autorelease references (and indirectly bridged K/N references) on Darwin targets * [KT-42397](https://youtrack.jetbrains.com/issue/KT-42397) Reverse-C interop usage of companion object reports spurious leaks * [GH-4482](https://github.com/JetBrains/kotlin-native/pull/4482) Add a switch to destroy runtime only on shutdown * [GH-4575](https://github.com/JetBrains/kotlin-native/pull/4575) Fix unchecked runtime shutdown * [GH-4194](https://github.com/JetBrains/kotlin-native/pull/4194) Fix possible race in terminate handler * C-interop * [KT-42412](https://youtrack.jetbrains.com/issue/KT-42412) Modality of generated property accessors is always FINAL * [KT-38530](https://youtrack.jetbrains.com/issue/KT-38530) values() method of enum classes is not exposed to Objective-C/Swift * [GH-4572](https://github.com/JetBrains/kotlin-native/pull/4572) Fix for interop enum and struct generation * Optimizations * [KT-42294](https://youtrack.jetbrains.com/issue/KT-42294) Significantly improved compilation time * [KT-42942](https://youtrack.jetbrains.com/issue/KT-42942) Optimize peak backend memory by clearing BindingContext after psi2ir * [KT-31072](https://youtrack.jetbrains.com/issue/KT-31072) Don't use non-reified arguments to specialize type operations in IR inliner # 1.4.21 (Dec 2020) * Fixed [KT-43517](https://youtrack.jetbrains.com/issue/KT-43517) * Fixed [KT-43530](https://youtrack.jetbrains.com/issue/KT-43530) * Fixed [KT-43265](https://youtrack.jetbrains.com/issue/KT-43265) # 1.4.20 (Nov 2020) * XCode 12 support * Completely reworked escape analysis for object allocation * Use ForeignException wrapper to handle native exceptions ([GH-3553](https://github.com/JetBrains/kotlin-native/issues/3553)) * CocoaPods plugin improvements * equals/hashCode support for adapted callable references ([KT-39800](https://youtrack.jetbrains.com/issue/KT-39800)) * equals/hashCode support for fun interfaces ([KT-39798](https://youtrack.jetbrains.com/issue/KT-39798)) * IR-level optimizations * Constant folding * String concatenation flattening * Various fixes/improvements to compiler caches * Some fixes to samples (calculator, tensorflow) * Bug fixes * Eliminate recursive GC calls ([KT-42275](https://youtrack.jetbrains.com/issue/KT-42275)) * Fix support for @OverrideInit constructors with default arguments ([KT-41910](https://youtrack.jetbrains.com/issue/KT-41910)) * Fix support for forward declarations ([KT-41655](https://youtrack.jetbrains.com/issue/KT-41655)) * [KT-41394](https://youtrack.jetbrains.com/issue/KT-41394) * [KT-41811](https://youtrack.jetbrains.com/issue/KT-41811) * [KT-41716](https://youtrack.jetbrains.com/issue/KT-41716) * [KT-41250](https://youtrack.jetbrains.com/issue/KT-41250) * [KT-42000](https://youtrack.jetbrains.com/issue/KT-42000) * [KT-41907](https://youtrack.jetbrains.com/issue/KT-41907) # 1.4.10 (Sep 2020) * Fixed a newline handling in @Deprecated annotation in ObjCExport ([KT-39206](https://youtrack.jetbrains.com/issue/KT-39206)) * Fixed suspend function types in ObjCExport ([KT-40976](https://youtrack.jetbrains.com/issue/KT-40976)) * Fixed support for unsupported C declarations in cinterop ([KT-39762](https://youtrack.jetbrains.com/issue/KT-39762)) # v1.4.0 (Aug 2020) * Objective-C/Swift interop: * Reworked exception handling ([GH-3822](https://github.com/JetBrains/kotlin-native/pull/3822), [GH-3842](https://github.com/JetBrains/kotlin-native/pull/3842)) * Enabled support for Objective-C generics by default ([GH-3778](https://github.com/JetBrains/kotlin-native/pull/3778)) * Support for Kotlin’s suspending functions ([GH-3915](https://github.com/JetBrains/kotlin-native/pull/3915)) * Handle variadic block types in ObjC interop ([`KT-36766`](https://youtrack.jetbrains.com/issue/KT-36766)) * Added native-specific frontend checkers (implemented in the main Kotlin repository: [GH-3293](https://github.com/JetBrains/kotlin/pull/3293), [GH-3091](https://github.com/JetBrains/kotlin/pull/3091), [GH-3172](https://github.com/JetBrains/kotlin/pull/3172)) * .dSYMs for release binaries on Apple platforms ([GH-4085](https://github.com/JetBrains/kotlin-native/pull/4085)) * Improved compilation time of builds with interop libraries by reworking cinterop under the hood. * Experimental mimalloc allocator support (-Xallocator=mimalloc) to improve execution time performance. ([GH-3704](https://github.com/JetBrains/kotlin-native/pull/3704)) * Tune GC to improve execution time performance * Various fixes to compiler caches and Gradle daemon usage # v1.3.72 (April 2020) * Fix ios_x64 platform libs cache for iOS 11 and 12 (GH-4071) # v1.3.71 (March 2020) * Fix `lazy {}` memory leak regression ([`KT-37232`](https://youtrack.jetbrains.com/issue/KT-37232), GH-3944) * Fix using cached Kotlin subclasses of Objective-C classes (GH-3986) # v1.3.70 (Dec 2019) * Support compiler caches for debug mode (GH-3650) * Support running Kotlin/Native compiler from Gradle daemon (GH-3442) * Support multiple independent Kotlin frameworks in the same application (GH-3457) * Compile-time allocation for some singleton objects (GH-3645) * Native support for SIMD vector types in compiler and interop (GH-3498) * API for runtime detector of cyclic garbage (GH-3616) * Commonized StringBuilder (GH-3593) and Float.rangeTo (KT-35299) * Fix interop with localized strings (GH-3562) * Provide utility for user-side generation of platform libraries (GH-3538) * On-stack allocation using local escape analysis (GH-3625) * Code coverage support on Linux and Windows (GH-3403) * Debugging experience improvements (GH-3561, GH-3638, GH-3606) # v1.3.60 (Oct 2019) * Support XCode 11 * Switch to LLVM 8.0 * New compiler targets: * watchOS targets, watchos_x86, watchos_arm64 and watchos_arm32 (GH-3323, GH-3404, GH-3344) * tvOS targets tvos_x64 and tvos_arm64 (GH-3303, GH-3363) * native Android targets android_x86 and android_x64 (GH-3306, GH-3314) * Standard CLI library kotlinx.cli is shipped with the compiler distribution (GH-3215) * Improved debug information for inline functions (KT-28929, GH-3292) * Improved runtime performance of interface calls, up to 5x faster (GH-3377) * Improved runtime performance of type checks, up to 50x faster (GH-3291) * Produce native binaries directly from klibs, speeds up large project compilation (GH-3246) * Supported arbitrary (up to 255 inclusive) function arity (GH-3253) * Supported callable references to suspend functions (GH-3197) * Implemented experimental -Xg0 switch, symbolication of release binaries for iOS (GH-3233, GH-3367) * Interop: * Allow passing untyped null as variadic function's parameter (GH-3312, KT-33525) * Standard library: * Allow scheduling jobs in arbitrary K/N context, not only Worker (GH-3316) * Important bug fixes: * Boxed negative values can lead to crashes on ios_arm64 (GH-3296) * Implemented thread-safe tracking of Objective-C references to Kotlin objects (GH-3267) # v1.3.50 (Aug 2019) * Kotlin/Native versioning now aligned with Kotlin versioning * Exhaustive platform libraries on macOS (GH-3141) * Update to Gradle 5.5 (GH-3166) * Improved debug information correctness (GH-3130) * Major memory manager refactoring (GH-3129) * Embed actual bitcode in produced frameworks (GH-2974) * Compilation speed improvements * Interop: * Support kotlin.Deprecated when producing framework (GH-3114) * Ensure produced Objective-C header does not have warnings (GH-3101) * Speed up interop stub generator (GH-3082, GH-3050) * getOriginalKotlinClass() to get KClass for Kotlin classes in Objective-C (GH-3036) * Supported nullable primitive types in reverse C interop (GH-3198) * Standard library * API for delayed job execution on worker (GH-2971) * API for running via worker's job queue (GH-3078) * MonoClock and Duration support (GH-3028) * Support typeOf (KT-29917, KT-28625) * New zero-terminated utf8 to String conversion API (GH-3116) * Optimize StringBuilder for certain cases (GH-3202) * Implemented Array.fill API (GH-3244) # v1.3.0 (Jun 2019) * CoreLocation platform library on macOS (GH-3041) * Converting Unit type to Void during producing framework for Objective-C/Swift (GH-2549, GH-1271) * Support linux/arm64 targets (GH-2917) * Performance improvements of memory manager (GH-2813) * FreezableAtomicReference prototype (GH-2776) * Logging and error messages enhancements * Interop: * Support nullable String return type in reverse C interop (GH-2956) * Support setting custom exception hook in reverse C interop (GH-2941) * Experimental generics support for produced frameworks for Objective-C/Swift implemented by Kevin Galligan (GH-2850) * Improve support for Objective-C methods clashing with methods of Any (GH-2914) * Support variadic Objective-C functions (GH-2896) # v1.2.1 (Apr 2019) * Fix Objective-C interop with React (GH-2872) * Fix “not in vtable” compiler crash when generating frameworks (GH-2865) * Implement some optimizations (GH-2854) * Fix release build for 32-bit Windows (GH-2848) * Fix casts to type parameters with multiple bounds (GH-2888) * Fix “could not get descriptor uniq id for deserialized class FlagEnum” compiler crash when generating framework (GH-2874) # v1.2.0 (Apr 2019) * New intermediate representation based library format allowing global optimizations * Exception backtraces in debug mode on macOS and iOS targets contains symbolic information * Support for 32-bit Windows targets (target mingw_x86) * Support for cross-compilation to Linux (x86-64 and arm32) from macOS and Windows hosts * Static Apple frameworks can be produced * Support Gradle 5.1 * Fix alignment-related issues on ARM32 and MIPS platforms * Write unhandled exceptions stacktrace on device to iOS crash log * Fix undefined behavior in some arithmetic operations * Interop: * Get rid of libffi dependency * Support returning struct from C callbacks * Support passing Kotlin strings to C interop functions accepting UTF-32 arguments * Fix bool conversion * Support variable length arrays * Provide Kotlin access to C compiler intrinsics via platform.builtins package * Support clang modules (for Objective-C only) * Experimental integration with CocoaPods * IDE * Kotlin/Native plugin is supported in CLion 2018.3 and AppCode/CLion 2019.1 * Basic highlighting support for .def files * Navigation to source files from exception backtrace ## v1.1.0 (Dec 2018) * Performance optimizations: * runtime: optimization of queue of finalization * compiler: loop generation optimization * compiler: reduce RTTI size * runtime: reduce size of the object header * Contracts support * Regex engine: fix quantifier processing ## v0.9.3 (Sep 2018) * Bugfixes ## v0.9.2 (Sep 2018) * Support Xcode 10.0 * iOS 9.0 is the minimal supported version for all targets * Swift interop improvements * Support shared top level values of some immutable types (i.e. String and atomic references) * Support release Kotlin 1.3.0 ## v0.9.1 (Sep 2018) * Improve naming in produced Objective-C frameworks. Use ‘Kotlin’ prefix instead of ‘Stdlib’ prefix. * Improvements in KLIB: Library versioning, IDEA-friendly internal format. # v0.9 (Sep 2018) * Support Kotlin 1.3M2 * Note: Common modules of multiplatform projects also should use Kotlin 1.3 * Major standard library (native parts) rework and rename * New Gradle plugin with multiplatform integration and reworked DSL * Support unsigned types in Kotlin and interop * Support non-experimental coroutines API (kotlin.coroutines) * Top level object var/val can only be accessed from the main thread * Support lazy properties in singleton objects * Update LLVM to 6.0.1 ## v0.8 (Jul 2018) * Singleton objects are frozen after creation, and shared between threads * String and primitives types are frozen by default * Common stdlib with Kotlin/JVM and Kotlin/JS * Implemented `kotlin.random.*` and `Collection.shuffle` * Implemented atomic integers and atomic references * Multiple bugfixes in compiler (coroutines, inliner) * Support 32-bit iOS (target `ios_arm32`) * New experimental Gradle plugin * Support Xcode 9.4.1 * Optimizations (switch by enum, memory management) ## v0.7.1 (Jun 2018) * Bugfixes in the runtime (indexOf, GC for kotlin.Array, enum equality) and the compiler * Fix NSBlock problem, preventing upload of binaries to the AppStore * Create primitive type boxes and kotlin.String as frozen by default * Support Gradle 4.7, provide separate run task for each executable * Support Xcode 9.4 and CoreML and ClassKit frameworks on Apple platforms * Improved runtime Kotlin variable examination * Minor performance optimizations in compiled code and runtime * Add `disableDesignatedInitializerChecks` definition file support ## v0.7 (May 2018) * Interop with Objective-C/Swift changes: * Uniform direct and reverse interops (values could be passed in both directions now) * Interop by exceptions * Type conversion and checks (`as`, `is`) for interop types * Seamless interop on numbers, strings, lists, maps and sets * Better interop on constructors and initializers * Switched to Xcode 9.3 on Apple platforms * Introduced object freezing API, frozen object could be used from multiple threads * Kotlin enums are frozen by default * Switch to Gradle 4.6 * Use Gradle native dependency model, allowing to use `.klib` as Maven artifacts * Introduced typed arrays API * Introduced weak references API * Activated global devirtualization analysis * Performance improvements (box caching, bridge inlining, others) ## v0.6.2 (Mar 2018) * Support several `expectedBy`-dependencies in Gradle plugin. * Improved interaction between Gradle plugin and IDE. * Various bugfixes ## v0.6.1 (Mar 2018) * Various bugfixes * Support total ordering in FP comparisons * Interop generates string constants from string macrodefinitions * STM32 blinky demo in pure Kotlin/Native * Top level variables initialization redesign (proper dependency order) * Support kotlin.math on WebAssembly targets * Support embedded targets on Windows hosts ## v0.6 (Feb 2018) * Support multiplatform projects (expect/actual) in compiler and Gradle plugin * Support first embedded target (STM32 board) * Support Kotlin 1.2.20 * Support Java 9 * Support Gradle 4.5 * Transparent Objective-C/Kotlin container classes interoperability * Produce optimized WebAssembly binaries (10x smaller than it used to be) * Improved APIs for object transfer between threads and workers * Allow exporting top level C function in reverse interop with @CName annotation * Supported debugging of code with inline functions * Multiple bugfixes and performance optimizations ## v0.5 (Dec 2017) * Reverse interop allowing to call Kotlin/Native code compiled as framework from Objective-C/Swift programs * Reverse interop allowing to call Kotlin/Native code compiled as shared object from C/C++ programs * Support generation of shared objects and DLLs by the compiler * Migration to LLVM 5.0 * Support WebAssembly target on Linux and Windows hosts * Make string conversions more robust * Support kotlin.math package * Refine workers and string conversion APIs ## v0.4 (Nov 2017) ## * Objective-C frameworks interop for iOS and macOS targets * Platform API libraries for Linux, iOS, macOS and Windows * Kotlin 1.2 supported * `val` and function parameters can be inspected in debugger * Experimental support for WebAssembly (wasm32 target) * Linux MIPS support (little and big endian, mips and mipsel targets) * Gradle plugin DSL fully reworked * Support for unit testing annotations and automatic test runner generation * Final executable size reduced * Various interop improvements (forward declaration, better handling of unsupported types) * Workers object subgraph transfer checks implemented * Optimized low level memory management using more efficient cycle tracing algorithm ## v0.3.4 (Oct 2017) ## * Intermediate release ## v0.3.2 (Sep 2017) ## * Bug fixes ## v0.3.1 (Aug 2017) ## * Improvements in C interop tools (function pointers, bitfields, bugfixes) * Improvements to Gradle plugin and dependency downloader * Support for immutable data linked into an executable via ImmutableDataBlob class * Kotlin 1.1.4 supported * Basic variable inspection support in the debugger * Some performance improvements ("for" loops, memory management) * .klib improvements (keep options from .def file, faster inline handling) * experimental workers API added (see [`sample`](https://github.com/JetBrains/kotlin-native/blob/master/samples/workers)) ## v0.3 (Jun 2017) ## * Preliminary support for x86-64 Windows hosts and targets * Support for producing native activities on 32- and 64-bit Android targets * Extended standard library (bitsets, character classification, regular expression) * Preliminary support for Kotlin/Native library format (.klib) * Preliminary source-level debugging support (stepping only, no variable inspection) * Compiler switch `-entry` to select entry point * Symbolic backtrace in runtime for unstripped binaries, for all supported targets ## v0.2 (May 2017) ## * Added support for coroutines * Fixed most stdlib incompatibilities * Improved memory management performance * Cross-module inline function support * Unicode support independent from installed system locales * Interoperability improvements * file-based filtering in definition file * stateless lambdas could be used as C callbacks * any Unicode string could be passed to C function * Very basic debugging support * Improve compilation and linking performance ## v0.1 (Mar 2017) ## Initial technical preview of Kotlin/Native ================================================ FILE: COCOAPODS.md ================================================ # CocoaPods integration The content of this page is moved to https://kotlinlang.org/docs/native-cocoapods.html ================================================ FILE: CODE_COVERAGE.md ================================================ # Code Coverage The content of this page is moved to https://github.com/JetBrains/kotlin/blob/master/kotlin-native/CODE_COVERAGE.md ================================================ FILE: CONCURRENCY.md ================================================ ## Concurrency in Kotlin/Native The content of this page is moved to https://kotlinlang.org/docs/native-concurrency.html ================================================ FILE: DEBUGGING.md ================================================ ## Debugging The content of this page is moved to https://kotlinlang.org/docs/native-debugging.html ================================================ FILE: DISTRO_README.md ================================================ The development of Kotlin/Native was moved to https://github.com/JetBrains/kotlin. ================================================ FILE: FAQ.md ================================================ The content of this page is moved to https://kotlinlang.org/docs/native-faq.html ================================================ FILE: GRADLE_PLUGIN.md ================================================ # Kotlin/Native Gradle plugin Since 1.3.40, a separate Gradle plugin for Kotlin/Native is deprecated in favor of the `kotlin-multiplatform` plugin. This plugin provides an IDE support along with support of the new multiplatform project model introduced in Kotlin 1.3.0. For more information see the `kotlin-muliplatform` [documentation page](https://kotlinlang.org/docs/mpp-discover-project.html). ================================================ FILE: HACKING.md ================================================ The content of this page is moved to https://github.com/JetBrains/kotlin/blob/master/kotlin-native/HACKING.md ================================================ FILE: IMMUTABILITY.md ================================================ # Immutability in Kotlin/Native The content of this page is moved to https://kotlinlang.org/docs/native-immutability.html ================================================ FILE: INTEROP.md ================================================ # _Kotlin/Native_ interoperability # The content of this page is moved to https://kotlinlang.org/docs/native-c-interop.html ================================================ FILE: IOS_SYMBOLICATION.md ================================================ # Symbolicating iOS crash reports The content of this page is moved to https://kotlinlang.org/docs/native-ios-symbolication.html ================================================ FILE: Interop/.idea/compiler.xml ================================================ ================================================ FILE: Interop/.idea/gradle.xml ================================================ ================================================ FILE: Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml ================================================ ================================================ FILE: Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml ================================================ ================================================ FILE: Interop/.idea/modules.xml ================================================ ================================================ FILE: Interop/Indexer/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ buildscript { ext.rootBuildDirectory = file('../..') apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } apply plugin: 'kotlin' apply plugin: org.jetbrains.kotlin.NativeInteropPlugin apply plugin: 'c' apply plugin: 'cpp' import org.jetbrains.kotlin.konan.target.ClangArgs final Project libclangextProject = project(":libclangext") final String libclangextTask = libclangextProject.path + ":build" File libclangextDir = new File(libclangextProject.buildDir, "libs/clangext/static") final boolean libclangextIsEnabled = libclangextProject.isEnabled final String libclang if (isWindows()) { libclang = "bin/libclang.dll" } else { libclang = "lib/${System.mapLibraryName("clang")}" } List cflags = [ "-I$llvmDir/include", "-I${project(":libclangext").projectDir.absolutePath + "/src/main/include"}" ]*.toString() List ldflags = ["$llvmDir/$libclang", "-L$libclangextDir.absolutePath", "-lclangext"]*.toString() if (libclangextIsEnabled) { assert(isMac()) ldflags.addAll(['-Wl,--no-demangle', '-Wl,-search_paths_first', '-Wl,-headerpad_max_install_names', '-Wl,-U,_futimens', '-Wl,-U,__ZN4llvm7remarks11parseFormatENS_9StringRefE', '-Wl,-U,__ZN4llvm7remarks22createRemarkSerializerENS0_6FormatENS0_14SerializerModeERNS_11raw_ostreamE', '-Wl,-U,__ZN4llvm7remarks14YAMLSerializerC1ERNS_11raw_ostreamENS0_14UseStringTableE']) List llvmLibs = [ "clangAST", "clangASTMatchers", "clangAnalysis", "clangBasic", "clangDriver", "clangEdit", "clangFrontend", "clangFrontendTool", "clangLex", "clangParse", "clangSema", "clangEdit", "clangRewrite", "clangRewriteFrontend", "clangStaticAnalyzerFrontend", "clangStaticAnalyzerCheckers", "clangStaticAnalyzerCore", "clangSerialization", "clangToolingCore", "clangTooling", "clangFormat", "LLVMTarget", "LLVMMC", "LLVMLinker", "LLVMTransformUtils", "LLVMBitWriter", "LLVMBitReader", "LLVMAnalysis", "LLVMProfileData", "LLVMCore", "LLVMSupport", "LLVMBinaryFormat", "LLVMDemangle" ].collect { "$llvmDir/lib/lib${it}.a".toString() } ldflags.addAll(llvmLibs) ldflags.addAll(['-lpthread', '-lz', '-lm', '-lcurses']) } model { components { clangstubs(NativeLibrarySpec) { sources { c.source.srcDir 'prebuilt/nativeInteropStubs/c' cpp.source.srcDir 'src/nativeInteropStubs/cpp' } binaries.all { cCompiler.args hostPlatform.clang.hostCompilerArgsForJni cCompiler.args.addAll(cflags) } binaries.withType(SharedLibraryBinarySpec) { linker.args.addAll(ldflags) } } } toolChains { clang(Clang) { eachPlatform { cppCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) cCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) } } } } sourceSets { main { kotlin { srcDirs 'prebuilt/nativeInteropStubs/kotlin' } } } repositories { maven { url buildKotlinCompilerRepo } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" compile project(':Interop:Runtime') } task nativelibs(type: Copy) { dependsOn 'clangstubsSharedLibrary' from "$buildDir/libs/clangstubs/shared/" into "$buildDir/nativelibs/" } classes.dependsOn nativelibs kotlinNativeInterop { clang { defFile 'clang.def' compilerOpts cflags linkerOpts ldflags genTask.dependsOn libclangextTask genTask.inputs.dir libclangextDir } } compileKotlin { kotlinOptions { allWarningsAsErrors=true kotlinOptions.freeCompilerArgs = ["-Xskip-prerelease-check"] } } tasks.matching { it.name == 'linkClangstubsSharedLibrary' }.all { it.dependsOn libclangextTask it.inputs.dir libclangextDir } task updatePrebuilt { dependsOn genClangInteropStubs doLast { copy { from("$buildDir/nativeInteropStubs/clang/kotlin") { include 'clang/clang.kt' } into 'prebuilt/nativeInteropStubs/kotlin' } copy { from("$buildDir/interopTemp") { include 'clangstubs.c' } into 'prebuilt/nativeInteropStubs/c' } } } ================================================ FILE: Interop/Indexer/clang.def ================================================ headers = clang-c/Index.h clang-c/ext.h clang-c/ExtVector.h headerFilter = clang-c/** compiler = clang compilerOpts = -std=c99 -fPIC linkerOpts.linux = -Wl,-z,noexecstack linker = clang++ linkerOpts = -fPIC strictEnums = CXErrorCode CXCursorKind CXTypeKind CXDiagnosticSeverity CXLoadDiag_Error CXSaveError \ CXTUResourceUsageKind CXLinkageKind CXVisibilityKind CXLanguageKind CXCallingConv CXChildVisitResult \ CXTokenKind CXEvalResultKind CXVisitorResult CXResult CXIdxEntityKind ================================================ FILE: Interop/Indexer/prebuilt/nativeInteropStubs/c/clangstubs.c ================================================ #include #include #include #include #include // NOTE THIS FILE IS AUTO-GENERATED JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge0 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getCString(*(CXString*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge1 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeString(*(CXString*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge2 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeStringSet((CXStringSet*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge3 (JNIEnv* jniEnv, jclass jclss) { return (jlong)clang_getBuildSessionTimestamp(); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge4 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jlong)clang_VirtualFileOverlay_create(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge5 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_VirtualFileOverlay_addFileMapping((struct CXVirtualFileOverlayImpl*)p0, (char*)p1, (char*)p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge6 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_VirtualFileOverlay_setCaseSensitivity((struct CXVirtualFileOverlayImpl*)p0, p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge7 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jlong p3) { return (jint)clang_VirtualFileOverlay_writeToBuffer((struct CXVirtualFileOverlayImpl*)p0, p1, (char**)p2, (unsigned int*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge8 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_free((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge9 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_VirtualFileOverlay_dispose((struct CXVirtualFileOverlayImpl*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge10 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jlong)clang_ModuleMapDescriptor_create(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge11 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_ModuleMapDescriptor_setFrameworkModuleName((struct CXModuleMapDescriptorImpl*)p0, (char*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge12 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_ModuleMapDescriptor_setUmbrellaHeader((struct CXModuleMapDescriptorImpl*)p0, (char*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge13 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jlong p3) { return (jint)clang_ModuleMapDescriptor_writeToBuffer((struct CXModuleMapDescriptorImpl*)p0, p1, (char**)p2, (unsigned int*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge14 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_ModuleMapDescriptor_dispose((struct CXModuleMapDescriptorImpl*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge15 (JNIEnv* jniEnv, jclass jclss, jint p0, jint p1) { return (jlong)clang_createIndex(p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge16 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeIndex((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge17 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { clang_CXIndex_setGlobalOptions((void*)p0, p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge18 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXIndex_getGlobalOptions((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge19 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { clang_CXIndex_setInvocationEmissionPathOption((void*)p0, (char*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge20 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getFileName((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge21 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getFileTime((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge22 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_getFileUniqueID((void*)p0, (CXFileUniqueID*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge23 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_isFileMultipleIncludeGuarded((struct CXTranslationUnitImpl*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge24 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_getFile((struct CXTranslationUnitImpl*)p0, (char*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge25 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jlong)clang_getFileContents((struct CXTranslationUnitImpl*)p0, (void*)p1, (unsigned long*)p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge26 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_File_isEqual((void*)p0, (void*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge27 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_File_tryGetRealPathName((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge28 (JNIEnv* jniEnv, jclass jclss, jlong p0) { CXSourceLocation kniStructResult = clang_getNullLocation(); memcpy(p0, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge29 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_equalLocations(*(CXSourceLocation*)p0, *(CXSourceLocation*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge30 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2, jint p3, jlong p4) { CXSourceLocation kniStructResult = clang_getLocation((struct CXTranslationUnitImpl*)p0, (void*)p1, p2, p3); memcpy(p4, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge31 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2, jlong p3) { CXSourceLocation kniStructResult = clang_getLocationForOffset((struct CXTranslationUnitImpl*)p0, (void*)p1, p2); memcpy(p3, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge32 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Location_isInSystemHeader(*(CXSourceLocation*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge33 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Location_isFromMainFile(*(CXSourceLocation*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge34 (JNIEnv* jniEnv, jclass jclss, jlong p0) { CXSourceRange kniStructResult = clang_getNullRange(); memcpy(p0, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge35 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXSourceRange kniStructResult = clang_getRange(*(CXSourceLocation*)p0, *(CXSourceLocation*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge36 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_equalRanges(*(CXSourceRange*)p0, *(CXSourceRange*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge37 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Range_isNull(*(CXSourceRange*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge38 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4) { clang_getExpansionLocation(*(CXSourceLocation*)p0, (void*)p1, (unsigned int*)p2, (unsigned int*)p3, (unsigned int*)p4); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge39 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3) { clang_getPresumedLocation(*(CXSourceLocation*)p0, (CXString*)p1, (unsigned int*)p2, (unsigned int*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge40 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4) { clang_getInstantiationLocation(*(CXSourceLocation*)p0, (void*)p1, (unsigned int*)p2, (unsigned int*)p3, (unsigned int*)p4); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge41 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4) { clang_getSpellingLocation(*(CXSourceLocation*)p0, (void*)p1, (unsigned int*)p2, (unsigned int*)p3, (unsigned int*)p4); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge42 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4) { clang_getFileLocation(*(CXSourceLocation*)p0, (void*)p1, (unsigned int*)p2, (unsigned int*)p3, (unsigned int*)p4); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge43 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceLocation kniStructResult = clang_getRangeStart(*(CXSourceRange*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge44 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceLocation kniStructResult = clang_getRangeEnd(*(CXSourceRange*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge45 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_getSkippedRanges((struct CXTranslationUnitImpl*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge46 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getAllSkippedRanges((struct CXTranslationUnitImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge47 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeSourceRangeList((CXSourceRangeList*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge48 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getNumDiagnosticsInSet((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge49 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_getDiagnosticInSet((void*)p0, p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge50 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jlong)clang_loadDiagnostics((char*)p0, (void*)p1, (CXString*)p2); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge51 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeDiagnosticSet((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge52 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getChildDiagnostics((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge53 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getNumDiagnostics((struct CXTranslationUnitImpl*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge54 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_getDiagnostic((struct CXTranslationUnitImpl*)p0, p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge55 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getDiagnosticSetFromTU((struct CXTranslationUnitImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge56 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeDiagnostic((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge57 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXString kniStructResult = clang_formatDiagnostic((void*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge58 (JNIEnv* jniEnv, jclass jclss) { return (jint)clang_defaultDiagnosticDisplayOptions(); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge59 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getDiagnosticSeverity((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge60 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceLocation kniStructResult = clang_getDiagnosticLocation((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge61 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getDiagnosticSpelling((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge62 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_getDiagnosticOption((void*)p0, (CXString*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge63 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getDiagnosticCategory((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge64 (JNIEnv* jniEnv, jclass jclss, jint p0, jlong p1) { CXString kniStructResult = clang_getDiagnosticCategoryName(p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge65 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getDiagnosticCategoryText((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge66 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getDiagnosticNumRanges((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge67 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXSourceRange kniStructResult = clang_getDiagnosticRange((void*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge68 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getDiagnosticNumFixIts((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge69 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jlong p3) { CXString kniStructResult = clang_getDiagnosticFixIt((void*)p0, p1, (CXSourceRange*)p2); memcpy(p3, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge70 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getTranslationUnitSpelling((struct CXTranslationUnitImpl*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge71 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2, jlong p3, jint p4, jlong p5) { return (jlong)clang_createTranslationUnitFromSourceFile((void*)p0, (char*)p1, p2, (char**)p3, p4, (struct CXUnsavedFile*)p5); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge72 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_createTranslationUnit((void*)p0, (char*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge73 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_createTranslationUnit2((void*)p0, (char*)p1, (struct CXTranslationUnitImpl**)p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge74 (JNIEnv* jniEnv, jclass jclss) { return (jint)clang_defaultEditingTranslationUnitOptions(); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge75 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jlong p4, jint p5, jint p6) { return (jlong)clang_parseTranslationUnit((void*)p0, (char*)p1, (char**)p2, p3, (struct CXUnsavedFile*)p4, p5, p6); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge76 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jlong p4, jint p5, jint p6, jlong p7) { return (jint)clang_parseTranslationUnit2((void*)p0, (char*)p1, (char**)p2, p3, (struct CXUnsavedFile*)p4, p5, p6, (struct CXTranslationUnitImpl**)p7); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge77 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jlong p4, jint p5, jint p6, jlong p7) { return (jint)clang_parseTranslationUnit2FullArgv((void*)p0, (char*)p1, (char**)p2, p3, (struct CXUnsavedFile*)p4, p5, p6, (struct CXTranslationUnitImpl**)p7); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge78 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_defaultSaveOptions((struct CXTranslationUnitImpl*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge79 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2) { return (jint)clang_saveTranslationUnit((struct CXTranslationUnitImpl*)p0, (char*)p1, p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge80 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_suspendTranslationUnit((struct CXTranslationUnitImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge81 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeTranslationUnit((struct CXTranslationUnitImpl*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge82 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_defaultReparseOptions((struct CXTranslationUnitImpl*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge83 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jint p3) { return (jint)clang_reparseTranslationUnit((struct CXTranslationUnitImpl*)p0, p1, (struct CXUnsavedFile*)p2, p3); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge84 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jlong)clang_getTUResourceUsageName(p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge85 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { struct CXTUResourceUsage kniStructResult = clang_getCXTUResourceUsage((struct CXTranslationUnitImpl*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge86 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeCXTUResourceUsage(*(struct CXTUResourceUsage*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge87 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getTranslationUnitTargetInfo((struct CXTranslationUnitImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge88 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_TargetInfo_dispose((struct CXTargetInfoImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge89 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_TargetInfo_getTriple((struct CXTargetInfoImpl*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge90 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_TargetInfo_getPointerWidth((struct CXTargetInfoImpl*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge91 (JNIEnv* jniEnv, jclass jclss, jlong p0) { CXCursor kniStructResult = clang_getNullCursor(); memcpy(p0, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge92 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getTranslationUnitCursor((struct CXTranslationUnitImpl*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge93 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_equalCursors(*(CXCursor*)p0, *(CXCursor*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge94 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isNull(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge95 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_hashCursor(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge96 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorKind(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge97 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isDeclaration(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge98 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isInvalidDeclaration(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge99 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isReference(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge100 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isExpression(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge101 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isStatement(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge102 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isAttribute(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge103 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_hasAttrs(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge104 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isInvalid(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge105 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isTranslationUnit(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge106 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isPreprocessing(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge107 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_isUnexposed(p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge108 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorLinkage(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge109 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorVisibility(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge110 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorAvailability(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge111 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jint p6) { return (jint)clang_getCursorPlatformAvailability(*(CXCursor*)p0, (int*)p1, (CXString*)p2, (int*)p3, (CXString*)p4, (struct CXPlatformAvailability*)p5, p6); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge112 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeCXPlatformAvailability((struct CXPlatformAvailability*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge113 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorLanguage(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge114 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorTLSKind(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge115 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getTranslationUnit(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge116 (JNIEnv* jniEnv, jclass jclss) { return (jlong)clang_createCXCursorSet(); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge117 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeCXCursorSet((struct CXCursorSetImpl*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge118 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_CXCursorSet_contains((struct CXCursorSetImpl*)p0, *(CXCursor*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge119 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_CXCursorSet_insert((struct CXCursorSetImpl*)p0, *(CXCursor*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge120 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getCursorSemanticParent(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge121 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getCursorLexicalParent(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge122 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { clang_getOverriddenCursors(*(CXCursor*)p0, (CXCursor**)p1, (unsigned int*)p2); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge123 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeOverriddenCursors((CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge124 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getIncludedFile(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge125 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXCursor kniStructResult = clang_getCursor((struct CXTranslationUnitImpl*)p0, *(CXSourceLocation*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge126 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceLocation kniStructResult = clang_getCursorLocation(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge127 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceRange kniStructResult = clang_getCursorExtent(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge128 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getCursorType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge129 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getTypeSpelling(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge130 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getTypedefDeclUnderlyingType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge131 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getEnumDeclIntegerType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge132 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getEnumConstantDeclValue(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge133 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getEnumConstantDeclUnsignedValue(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge134 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getFieldDeclBitWidth(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge135 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_getNumArguments(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge136 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXCursor kniStructResult = clang_Cursor_getArgument(*(CXCursor*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge137 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_getNumTemplateArguments(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge138 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_Cursor_getTemplateArgumentKind(*(CXCursor*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge139 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXType kniStructResult = clang_Cursor_getTemplateArgumentType(*(CXCursor*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge140 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_Cursor_getTemplateArgumentValue(*(CXCursor*)p0, p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge141 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_Cursor_getTemplateArgumentUnsignedValue(*(CXCursor*)p0, p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge142 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_equalTypes(*(CXType*)p0, *(CXType*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge143 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getCanonicalType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge144 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isConstQualifiedType(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge145 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isMacroFunctionLike(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge146 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isMacroBuiltin(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge147 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isFunctionInlined(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge148 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isVolatileQualifiedType(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge149 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isRestrictQualifiedType(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge150 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getAddressSpace(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge151 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getTypedefName(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge152 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getPointeeType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge153 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getTypeDeclaration(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge154 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getDeclObjCTypeEncoding(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge155 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Type_getObjCEncoding(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge156 (JNIEnv* jniEnv, jclass jclss, jint p0, jlong p1) { CXString kniStructResult = clang_getTypeKindSpelling(p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge157 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getFunctionTypeCallingConv(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge158 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getResultType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge159 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getExceptionSpecificationType(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge160 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getNumArgTypes(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge161 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXType kniStructResult = clang_getArgType(*(CXType*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge162 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_Type_getObjCObjectBaseType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge163 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getNumObjCProtocolRefs(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge164 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXCursor kniStructResult = clang_Type_getObjCProtocolDecl(*(CXType*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge165 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getNumObjCTypeArgs(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge166 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXType kniStructResult = clang_Type_getObjCTypeArg(*(CXType*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge167 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isFunctionTypeVariadic(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge168 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getCursorResultType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge169 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCursorExceptionSpecificationType(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge170 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isPODType(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge171 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getElementType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge172 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getNumElements(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge173 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getArrayElementType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge174 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getArraySize(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge175 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_Type_getNamedType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge176 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_isTransparentTagTypedef(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge177 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getNullability(*(CXType*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge178 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Type_getAlignOf(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge179 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_Type_getClassType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge180 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Type_getSizeOf(*(CXType*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge181 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_Type_getOffsetOf(*(CXType*)p0, (char*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge182 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_Type_getModifiedType(*(CXType*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge183 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getOffsetOfField(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge184 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isAnonymous(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge185 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getNumTemplateArguments(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge186 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXType kniStructResult = clang_Type_getTemplateArgumentAsType(*(CXType*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge187 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getCXXRefQualifier(*(CXType*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge188 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isBitField(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge189 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isVirtualBase(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge190 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCXXAccessSpecifier(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge191 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_getStorageClass(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge192 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getNumOverloadedDecls(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge193 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXCursor kniStructResult = clang_getOverloadedDecl(*(CXCursor*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge194 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_getIBOutletCollectionType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge195 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_visitChildren(*(CXCursor*)p0, (void*)p1, (void*)p2); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge196 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getCursorUSR(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge197 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_constructUSR_ObjCClass((char*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge198 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_constructUSR_ObjCCategory((char*)p0, (char*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge199 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_constructUSR_ObjCProtocol((char*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge200 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_constructUSR_ObjCIvar((char*)p0, *(CXString*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge201 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jlong p3) { CXString kniStructResult = clang_constructUSR_ObjCMethod((char*)p0, p1, *(CXString*)p2); memcpy(p3, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge202 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_constructUSR_ObjCProperty((char*)p0, *(CXString*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge203 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getCursorSpelling(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge204 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jint p2, jlong p3) { CXSourceRange kniStructResult = clang_Cursor_getSpellingNameRange(*(CXCursor*)p0, p1, p2); memcpy(p3, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge205 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_PrintingPolicy_getProperty((void*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge206 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jint p2) { clang_PrintingPolicy_setProperty((void*)p0, p1, p2); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge207 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getCursorPrintingPolicy(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge208 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_PrintingPolicy_dispose((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge209 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_getCursorPrettyPrinted(*(CXCursor*)p0, (void*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge210 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getCursorDisplayName(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge211 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getCursorReferenced(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge212 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getCursorDefinition(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge213 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isCursorDefinition(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge214 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getCanonicalCursor(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge215 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_getObjCSelectorIndex(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge216 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isDynamicCall(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge217 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXType kniStructResult = clang_Cursor_getReceiverType(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge218 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_Cursor_getObjCPropertyAttributes(*(CXCursor*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge219 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Cursor_getObjCPropertyGetterName(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge220 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Cursor_getObjCPropertySetterName(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge221 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_getObjCDeclQualifiers(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge222 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isObjCOptional(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge223 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isVariadic(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge224 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3) { return (jint)clang_Cursor_isExternalSymbol(*(CXCursor*)p0, (CXString*)p1, (CXString*)p2, (unsigned int*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge225 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceRange kniStructResult = clang_Cursor_getCommentRange(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge226 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Cursor_getRawCommentText(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge227 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Cursor_getBriefCommentText(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge228 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Cursor_getMangling(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge229 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getCXXManglings(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge230 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getObjCManglings(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge231 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getModule(*(CXCursor*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge232 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_getModuleForFile((struct CXTranslationUnitImpl*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge233 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Module_getASTFile((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge234 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Module_getParent((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge235 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Module_getName((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge236 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_Module_getFullName((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge237 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Module_isSystem((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge238 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_Module_getNumTopLevelHeaders((struct CXTranslationUnitImpl*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge239 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2) { return (jlong)clang_Module_getTopLevelHeader((struct CXTranslationUnitImpl*)p0, (void*)p1, p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge240 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXConstructor_isConvertingConstructor(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge241 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXConstructor_isCopyConstructor(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge242 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXConstructor_isDefaultConstructor(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge243 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXConstructor_isMoveConstructor(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge244 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXField_isMutable(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge245 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXMethod_isDefaulted(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge246 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXMethod_isPureVirtual(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge247 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXMethod_isStatic(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge248 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXMethod_isVirtual(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge249 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXRecord_isAbstract(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge250 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_EnumDecl_isScoped(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge251 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_CXXMethod_isConst(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge252 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getTemplateCursorKind(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge253 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXCursor kniStructResult = clang_getSpecializedCursorTemplate(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge254 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jint p2, jlong p3) { CXSourceRange kniStructResult = clang_getCursorReferenceNameRange(*(CXCursor*)p0, p1, p2); memcpy(p3, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge255 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jlong)clang_getToken((struct CXTranslationUnitImpl*)p0, *(CXSourceLocation*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge256 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getTokenKind(*(CXToken*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge257 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_getTokenSpelling((struct CXTranslationUnitImpl*)p0, *(CXToken*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge258 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXSourceLocation kniStructResult = clang_getTokenLocation((struct CXTranslationUnitImpl*)p0, *(CXToken*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge259 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXSourceRange kniStructResult = clang_getTokenExtent((struct CXTranslationUnitImpl*)p0, *(CXToken*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge260 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3) { clang_tokenize((struct CXTranslationUnitImpl*)p0, *(CXSourceRange*)p1, (CXToken**)p2, (unsigned int*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge261 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2, jlong p3) { clang_annotateTokens((struct CXTranslationUnitImpl*)p0, (CXToken*)p1, p2, (CXCursor*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge262 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2) { clang_disposeTokens((struct CXTranslationUnitImpl*)p0, (CXToken*)p1, p2); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge263 (JNIEnv* jniEnv, jclass jclss, jint p0, jlong p1) { CXString kniStructResult = clang_getCursorKindSpelling(p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge264 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4, jlong p5, jlong p6) { clang_getDefinitionSpellingAndExtent(*(CXCursor*)p0, (char**)p1, (char**)p2, (unsigned int*)p3, (unsigned int*)p4, (unsigned int*)p5, (unsigned int*)p6); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge265 (JNIEnv* jniEnv, jclass jclss) { clang_enableStackTraces(); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge266 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2) { clang_executeOnThread((void*)p0, (void*)p1, p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge267 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_getCompletionChunkKind((void*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge268 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXString kniStructResult = clang_getCompletionChunkText((void*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge269 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_getCompletionChunkCompletionString((void*)p0, p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge270 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getNumCompletionChunks((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge271 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCompletionPriority((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge272 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCompletionAvailability((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge273 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_getCompletionNumAnnotations((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge274 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXString kniStructResult = clang_getCompletionAnnotation((void*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge275 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { CXString kniStructResult = clang_getCompletionParent((void*)p0, (void*)p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge276 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_getCompletionBriefComment((void*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge277 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getCursorCompletionString(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge278 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jint)clang_getCompletionNumFixIts((CXCodeCompleteResults*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge279 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jint p2, jlong p3, jlong p4) { CXString kniStructResult = clang_getCompletionFixIt((CXCodeCompleteResults*)p0, p1, p2, (CXSourceRange*)p3); memcpy(p4, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge280 (JNIEnv* jniEnv, jclass jclss) { return (jint)clang_defaultCodeCompleteOptions(); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge281 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jint p2, jint p3, jlong p4, jint p5, jint p6) { return (jlong)clang_codeCompleteAt((struct CXTranslationUnitImpl*)p0, (char*)p1, p2, p3, (struct CXUnsavedFile*)p4, p5, p6); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge282 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { clang_sortCodeCompletionResults((CXCompletionResult*)p0, p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge283 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_disposeCodeCompleteResults((CXCodeCompleteResults*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge284 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_codeCompleteGetNumDiagnostics((CXCodeCompleteResults*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge285 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_codeCompleteGetDiagnostic((CXCodeCompleteResults*)p0, p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge286 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_codeCompleteGetContexts((CXCodeCompleteResults*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge287 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_codeCompleteGetContainerKind((CXCodeCompleteResults*)p0, (unsigned int*)p1); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge288 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_codeCompleteGetContainerUSR((CXCodeCompleteResults*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge289 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXString kniStructResult = clang_codeCompleteGetObjCSelector((CXCodeCompleteResults*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge290 (JNIEnv* jniEnv, jclass jclss, jlong p0) { CXString kniStructResult = clang_getClangVersion(); memcpy(p0, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge291 (JNIEnv* jniEnv, jclass jclss, jint p0) { clang_toggleCrashRecovery(p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge292 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { clang_getInclusions((struct CXTranslationUnitImpl*)p0, (void*)p1, (void*)p2); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge293 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_Evaluate(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge294 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_EvalResult_getKind((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge295 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_EvalResult_getAsInt((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge296 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_EvalResult_getAsLongLong((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge297 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_EvalResult_isUnsignedInt((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge298 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_EvalResult_getAsUnsigned((void*)p0); } JNIEXPORT jdouble JNICALL Java_clang_clang_kniBridge299 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jdouble)clang_EvalResult_getAsDouble((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge300 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_EvalResult_getAsStr((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge301 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_EvalResult_dispose((void*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge302 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_getRemappings((char*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge303 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1) { return (jlong)clang_getRemappingsFromFileList((char**)p0, p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge304 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_remap_getNumFiles((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge305 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2, jlong p3) { clang_remap_getFilenames((void*)p0, p1, (CXString*)p2, (CXString*)p3); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge306 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_remap_dispose((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge307 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_findReferencesInFile(*(CXCursor*)p0, (void*)p1, *(struct CXCursorAndRangeVisitor*)p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge308 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_findIncludesInFile((struct CXTranslationUnitImpl*)p0, (void*)p1, *(struct CXCursorAndRangeVisitor*)p2); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge309 (JNIEnv* jniEnv, jclass jclss, jint p0) { return (jint)clang_index_isEntityObjCContainerKind(p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge310 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getObjCContainerDeclInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge311 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getObjCInterfaceDeclInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge312 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getObjCCategoryDeclInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge313 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getObjCProtocolRefListInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge314 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getObjCPropertyDeclInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge315 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getIBOutletCollectionAttrInfo((CXIdxAttrInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge316 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getCXXClassDeclInfo((CXIdxDeclInfo*)p0); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge317 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getClientContainer((CXIdxContainerInfo*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge318 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { clang_index_setClientContainer((CXIdxContainerInfo*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge319 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_index_getClientEntity((CXIdxEntityInfo*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge320 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { clang_index_setClientEntity((CXIdxEntityInfo*)p0, (void*)p1); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge321 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_IndexAction_create((void*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge322 (JNIEnv* jniEnv, jclass jclss, jlong p0) { clang_IndexAction_dispose((void*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge323 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jint p4, jlong p5, jlong p6, jint p7, jlong p8, jint p9, jlong p10, jint p11) { return (jint)clang_indexSourceFile((void*)p0, (void*)p1, (IndexerCallbacks*)p2, p3, p4, (char*)p5, (char**)p6, p7, (struct CXUnsavedFile*)p8, p9, (struct CXTranslationUnitImpl**)p10, p11); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge324 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jint p4, jlong p5, jlong p6, jint p7, jlong p8, jint p9, jlong p10, jint p11) { return (jint)clang_indexSourceFileFullArgv((void*)p0, (void*)p1, (IndexerCallbacks*)p2, p3, p4, (char*)p5, (char**)p6, p7, (struct CXUnsavedFile*)p8, p9, (struct CXTranslationUnitImpl**)p10, p11); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge325 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jint p3, jint p4, jlong p5) { return (jint)clang_indexTranslationUnit((void*)p0, (void*)p1, (IndexerCallbacks*)p2, p3, p4, (struct CXTranslationUnitImpl*)p5); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge326 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2, jlong p3, jlong p4, jlong p5) { clang_indexLoc_getFileLocation(*(CXIdxLoc*)p0, (void*)p1, (void*)p2, (unsigned int*)p3, (unsigned int*)p4, (unsigned int*)p5); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge327 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXSourceLocation kniStructResult = clang_indexLoc_getCXSourceLocation(*(CXIdxLoc*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge328 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1, jlong p2) { return (jint)clang_Type_visitFields(*(CXType*)p0, (void*)p1, (void*)p2); } JNIEXPORT jlong JNICALL Java_clang_clang_kniBridge329 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jlong)clang_Cursor_getAttributeSpelling(*(CXCursor*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge330 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXTypeAttributes kniStructResult = clang_getDeclTypeAttributes(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge331 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXTypeAttributes kniStructResult = clang_getResultTypeAttributes(*(CXTypeAttributes*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge332 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { CXTypeAttributes kniStructResult = clang_getCursorResultTypeAttributes(*(CXCursor*)p0); memcpy(p1, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge333 (JNIEnv* jniEnv, jclass jclss, jlong p0, jlong p1) { return (jint)clang_Type_getNullabilityKind(*(CXType*)p0, *(CXTypeAttributes*)p1); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge334 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Type_getNumProtocols(*(CXType*)p0); } JNIEXPORT void JNICALL Java_clang_clang_kniBridge335 (JNIEnv* jniEnv, jclass jclss, jlong p0, jint p1, jlong p2) { CXCursor kniStructResult = clang_Type_getProtocol(*(CXType*)p0, p1); memcpy(p2, &kniStructResult, sizeof(kniStructResult)); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge336 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isObjCInitMethod(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge337 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isObjCReturningRetainedMethod(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge338 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_Cursor_isObjCConsumingSelfMethod(*(CXCursor*)p0); } JNIEXPORT jint JNICALL Java_clang_clang_kniBridge339 (JNIEnv* jniEnv, jclass jclss, jlong p0) { return (jint)clang_isExtVectorType(*(CXType*)p0); } ================================================ FILE: Interop/Indexer/prebuilt/nativeInteropStubs/kotlin/clang/clang.kt ================================================ @file:JvmName("clang") @file:Suppress("UNUSED_VARIABLE", "UNUSED_EXPRESSION", "DEPRECATION") package clang import kotlinx.cinterop.* // NOTE THIS FILE IS AUTO-GENERATED @CNaturalStruct("data", "private_flags") class CXString(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var data: COpaquePointer? get() = memberAt(0).value set(value) { memberAt(0).value = value } var private_flags: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("Strings", "Count") class CXStringSet(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var Strings: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var Count: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } } class CXVirtualFileOverlayImpl(rawPtr: NativePtr) : COpaque(rawPtr) class CXModuleMapDescriptorImpl(rawPtr: NativePtr) : COpaque(rawPtr) class CXTargetInfoImpl(rawPtr: NativePtr) : COpaque(rawPtr) class CXTranslationUnitImpl(rawPtr: NativePtr) : COpaque(rawPtr) @CNaturalStruct("Filename", "Contents", "Length") class CXUnsavedFile(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var Filename: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var Contents: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } var Length: Long get() = memberAt(16).value set(value) { memberAt(16).value = value } } @CNaturalStruct("Major", "Minor", "Subminor") class CXVersion(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(12, 4) var Major: Int get() = memberAt(0).value set(value) { memberAt(0).value = value } var Minor: Int get() = memberAt(4).value set(value) { memberAt(4).value = value } var Subminor: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("data") class CXFileUniqueID(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) @CLength(3) val data: CArrayPointer get() = arrayMemberAt(0) } @CNaturalStruct("ptr_data", "int_data") class CXSourceLocation(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) @CLength(2) val ptr_data: CArrayPointer get() = arrayMemberAt(0) var int_data: Int get() = memberAt(16).value set(value) { memberAt(16).value = value } } @CNaturalStruct("ptr_data", "begin_int_data", "end_int_data") class CXSourceRange(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) @CLength(2) val ptr_data: CArrayPointer get() = arrayMemberAt(0) var begin_int_data: Int get() = memberAt(16).value set(value) { memberAt(16).value = value } var end_int_data: Int get() = memberAt(20).value set(value) { memberAt(20).value = value } } @CNaturalStruct("count", "ranges") class CXSourceRangeList(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var count: Int get() = memberAt(0).value set(value) { memberAt(0).value = value } var ranges: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } } @CNaturalStruct("kind", "amount") class CXTUResourceUsageEntry(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var kind: CXTUResourceUsageKind get() = memberAt(0).value set(value) { memberAt(0).value = value } var amount: Long get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("data", "numEntries", "entries") class CXTUResourceUsage(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var data: COpaquePointer? get() = memberAt(0).value set(value) { memberAt(0).value = value } var numEntries: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } var entries: CPointer? get() = memberAt>(16).value set(value) { memberAt>(16).value = value } } @CNaturalStruct("kind", "xdata", "data") class CXCursor(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(32, 8) var kind: CXCursorKind get() = memberAt(0).value set(value) { memberAt(0).value = value } var xdata: Int get() = memberAt(4).value set(value) { memberAt(4).value = value } @CLength(3) val data: CArrayPointer get() = arrayMemberAt(8) } @CNaturalStruct("Platform", "Introduced", "Deprecated", "Obsoleted", "Unavailable", "Message") class CXPlatformAvailability(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(72, 8) val Platform: CXString get() = memberAt(0) val Introduced: CXVersion get() = memberAt(16) val Deprecated: CXVersion get() = memberAt(28) val Obsoleted: CXVersion get() = memberAt(40) var Unavailable: Int get() = memberAt(52).value set(value) { memberAt(52).value = value } val Message: CXString get() = memberAt(56) } class CXCursorSetImpl(rawPtr: NativePtr) : COpaque(rawPtr) @CNaturalStruct("kind", "data") class CXType(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var kind: CXTypeKind get() = memberAt(0).value set(value) { memberAt(0).value = value } @CLength(2) val data: CArrayPointer get() = arrayMemberAt(8) } @CNaturalStruct("int_data", "ptr_data") class CXToken(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) @CLength(4) val int_data: CArrayPointer get() = arrayMemberAt(0) var ptr_data: COpaquePointer? get() = memberAt(16).value set(value) { memberAt(16).value = value } } @CNaturalStruct("CursorKind", "CompletionString") class CXCompletionResult(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var CursorKind: CXCursorKind get() = memberAt(0).value set(value) { memberAt(0).value = value } var CompletionString: CXCompletionString? get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("Results", "NumResults") class CXCodeCompleteResults(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var Results: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var NumResults: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("context", "visit") class CXCursorAndRangeVisitor(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var context: COpaquePointer? get() = memberAt(0).value set(value) { memberAt(0).value = value } var visit: CPointer, CValue) -> CXVisitorResult>>? get() = memberAt, CValue) -> CXVisitorResult>>>(8).value set(value) { memberAt, CValue) -> CXVisitorResult>>>(8).value = value } } @CNaturalStruct("ptr_data", "int_data") class CXIdxLoc(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) @CLength(2) val ptr_data: CArrayPointer get() = arrayMemberAt(0) var int_data: Int get() = memberAt(16).value set(value) { memberAt(16).value = value } } @CNaturalStruct("hashLoc", "filename", "file", "isImport", "isAngled", "isModuleImport") class CXIdxIncludedFileInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(56, 8) val hashLoc: CXIdxLoc get() = memberAt(0) var filename: CPointer? get() = memberAt>(24).value set(value) { memberAt>(24).value = value } var file: CXFile? get() = memberAt(32).value set(value) { memberAt(32).value = value } var isImport: Int get() = memberAt(40).value set(value) { memberAt(40).value = value } var isAngled: Int get() = memberAt(44).value set(value) { memberAt(44).value = value } var isModuleImport: Int get() = memberAt(48).value set(value) { memberAt(48).value = value } } @CNaturalStruct("file", "module", "loc", "isImplicit") class CXIdxImportedASTFileInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(48, 8) var file: CXFile? get() = memberAt(0).value set(value) { memberAt(0).value = value } var module: CXModule? get() = memberAt(8).value set(value) { memberAt(8).value = value } val loc: CXIdxLoc get() = memberAt(16) var isImplicit: Int get() = memberAt(40).value set(value) { memberAt(40).value = value } } @CNaturalStruct("kind", "cursor", "loc") class CXIdxAttrInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(64, 8) var kind: CXIdxAttrKind get() = memberAt(0).value set(value) { memberAt(0).value = value } val cursor: CXCursor get() = memberAt(8) val loc: CXIdxLoc get() = memberAt(40) } @CNaturalStruct("kind", "templateKind", "lang", "name", "USR", "cursor", "attributes", "numAttributes") class CXIdxEntityInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(80, 8) var kind: CXIdxEntityKind get() = memberAt(0).value set(value) { memberAt(0).value = value } var templateKind: CXIdxEntityCXXTemplateKind get() = memberAt(4).value set(value) { memberAt(4).value = value } var lang: CXIdxEntityLanguage get() = memberAt(8).value set(value) { memberAt(8).value = value } var name: CPointer? get() = memberAt>(16).value set(value) { memberAt>(16).value = value } var USR: CPointer? get() = memberAt>(24).value set(value) { memberAt>(24).value = value } val cursor: CXCursor get() = memberAt(32) var attributes: CPointer>? get() = memberAt>>(64).value set(value) { memberAt>>(64).value = value } var numAttributes: Int get() = memberAt(72).value set(value) { memberAt(72).value = value } } @CNaturalStruct("cursor") class CXIdxContainerInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(32, 8) val cursor: CXCursor get() = memberAt(0) } @CNaturalStruct("attrInfo", "objcClass", "classCursor", "classLoc") class CXIdxIBOutletCollectionAttrInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(72, 8) var attrInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var objcClass: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } val classCursor: CXCursor get() = memberAt(16) val classLoc: CXIdxLoc get() = memberAt(48) } @CNaturalStruct("entityInfo", "cursor", "loc", "semanticContainer", "lexicalContainer", "isRedeclaration", "isDefinition", "isContainer", "declAsContainer", "isImplicit", "attributes", "numAttributes", "flags") class CXIdxDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(128, 8) var entityInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } val cursor: CXCursor get() = memberAt(8) val loc: CXIdxLoc get() = memberAt(40) var semanticContainer: CPointer? get() = memberAt>(64).value set(value) { memberAt>(64).value = value } var lexicalContainer: CPointer? get() = memberAt>(72).value set(value) { memberAt>(72).value = value } var isRedeclaration: Int get() = memberAt(80).value set(value) { memberAt(80).value = value } var isDefinition: Int get() = memberAt(84).value set(value) { memberAt(84).value = value } var isContainer: Int get() = memberAt(88).value set(value) { memberAt(88).value = value } var declAsContainer: CPointer? get() = memberAt>(96).value set(value) { memberAt>(96).value = value } var isImplicit: Int get() = memberAt(104).value set(value) { memberAt(104).value = value } var attributes: CPointer>? get() = memberAt>>(112).value set(value) { memberAt>>(112).value = value } var numAttributes: Int get() = memberAt(120).value set(value) { memberAt(120).value = value } var flags: Int get() = memberAt(124).value set(value) { memberAt(124).value = value } } @CNaturalStruct("declInfo", "kind") class CXIdxObjCContainerDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var declInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var kind: CXIdxObjCContainerKind get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("base", "cursor", "loc") class CXIdxBaseClassInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(64, 8) var base: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } val cursor: CXCursor get() = memberAt(8) val loc: CXIdxLoc get() = memberAt(40) } @CNaturalStruct("protocol", "cursor", "loc") class CXIdxObjCProtocolRefInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(64, 8) var protocol: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } val cursor: CXCursor get() = memberAt(8) val loc: CXIdxLoc get() = memberAt(40) } @CNaturalStruct("protocols", "numProtocols") class CXIdxObjCProtocolRefListInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(16, 8) var protocols: CPointer>? get() = memberAt>>(0).value set(value) { memberAt>>(0).value = value } var numProtocols: Int get() = memberAt(8).value set(value) { memberAt(8).value = value } } @CNaturalStruct("containerInfo", "superInfo", "protocols") class CXIdxObjCInterfaceDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var containerInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var superInfo: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } var protocols: CPointer? get() = memberAt>(16).value set(value) { memberAt>(16).value = value } } @CNaturalStruct("containerInfo", "objcClass", "classCursor", "classLoc", "protocols") class CXIdxObjCCategoryDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(80, 8) var containerInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var objcClass: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } val classCursor: CXCursor get() = memberAt(16) val classLoc: CXIdxLoc get() = memberAt(48) var protocols: CPointer? get() = memberAt>(72).value set(value) { memberAt>(72).value = value } } @CNaturalStruct("declInfo", "getter", "setter") class CXIdxObjCPropertyDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var declInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var getter: CPointer? get() = memberAt>(8).value set(value) { memberAt>(8).value = value } var setter: CPointer? get() = memberAt>(16).value set(value) { memberAt>(16).value = value } } @CNaturalStruct("declInfo", "bases", "numBases") class CXIdxCXXClassDeclInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(24, 8) var declInfo: CPointer? get() = memberAt>(0).value set(value) { memberAt>(0).value = value } var bases: CPointer>? get() = memberAt>>(8).value set(value) { memberAt>>(8).value = value } var numBases: Int get() = memberAt(16).value set(value) { memberAt(16).value = value } } @CNaturalStruct("kind", "cursor", "loc", "referencedEntity", "parentEntity", "container", "role") class CXIdxEntityRefInfo(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(96, 8) var kind: CXIdxEntityRefKind get() = memberAt(0).value set(value) { memberAt(0).value = value } val cursor: CXCursor get() = memberAt(8) val loc: CXIdxLoc get() = memberAt(40) var referencedEntity: CPointer? get() = memberAt>(64).value set(value) { memberAt>(64).value = value } var parentEntity: CPointer? get() = memberAt>(72).value set(value) { memberAt>(72).value = value } var container: CPointer? get() = memberAt>(80).value set(value) { memberAt>(80).value = value } var role: CXSymbolRole get() = memberAt(88).value set(value) { memberAt(88).value = value } } @CNaturalStruct("abortQuery", "diagnostic", "enteredMainFile", "ppIncludedFile", "importedASTFile", "startedTranslationUnit", "indexDeclaration", "indexEntityReference") class IndexerCallbacks(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(64, 8) var abortQuery: CPointer Int>>? get() = memberAt Int>>>(0).value set(value) { memberAt Int>>>(0).value = value } var diagnostic: CPointer Unit>>? get() = memberAt Unit>>>(8).value set(value) { memberAt Unit>>>(8).value = value } var enteredMainFile: CPointer CXIdxClientFile?>>? get() = memberAt CXIdxClientFile?>>>(16).value set(value) { memberAt CXIdxClientFile?>>>(16).value = value } var ppIncludedFile: CPointer?) -> CXIdxClientFile?>>? get() = memberAt?) -> CXIdxClientFile?>>>(24).value set(value) { memberAt?) -> CXIdxClientFile?>>>(24).value = value } var importedASTFile: CPointer?) -> CXIdxClientASTFile?>>? get() = memberAt?) -> CXIdxClientASTFile?>>>(32).value set(value) { memberAt?) -> CXIdxClientASTFile?>>>(32).value = value } var startedTranslationUnit: CPointer CXIdxClientContainer?>>? get() = memberAt CXIdxClientContainer?>>>(40).value set(value) { memberAt CXIdxClientContainer?>>>(40).value = value } var indexDeclaration: CPointer?) -> Unit>>? get() = memberAt?) -> Unit>>>(48).value set(value) { memberAt?) -> Unit>>>(48).value = value } var indexEntityReference: CPointer?) -> Unit>>? get() = memberAt?) -> Unit>>>(56).value set(value) { memberAt?) -> Unit>>>(56).value = value } } @CNaturalStruct("typeOpaquePtr") class CXTypeAttributes(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(8, 8) var typeOpaquePtr: COpaquePointer? get() = memberAt(0).value set(value) { memberAt(0).value = value } } enum class CXErrorCode(override val value: Int) : CEnum { CXError_Success(0), CXError_Failure(1), CXError_Crashed(2), CXError_InvalidArguments(3), CXError_ASTReadError(4), CXError_RefactoringActionUnavailable(5), CXError_RefactoringNameSizeMismatch(6), CXError_RefactoringNameInvalid(7), ; companion object { fun byValue(value: Int) = CXErrorCode.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXErrorCode get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXAvailabilityKind(override val value: Int) : CEnum { CXAvailability_Available(0), CXAvailability_Deprecated(1), CXAvailability_NotAvailable(2), CXAvailability_NotAccessible(3), ; companion object { fun byValue(value: Int) = CXAvailabilityKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXAvailabilityKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXCursor_ExceptionSpecificationKind(override val value: Int) : CEnum { CXCursor_ExceptionSpecificationKind_None(0), CXCursor_ExceptionSpecificationKind_DynamicNone(1), CXCursor_ExceptionSpecificationKind_Dynamic(2), CXCursor_ExceptionSpecificationKind_MSAny(3), CXCursor_ExceptionSpecificationKind_BasicNoexcept(4), CXCursor_ExceptionSpecificationKind_ComputedNoexcept(5), CXCursor_ExceptionSpecificationKind_Unevaluated(6), CXCursor_ExceptionSpecificationKind_Uninstantiated(7), CXCursor_ExceptionSpecificationKind_Unparsed(8), ; companion object { fun byValue(value: Int) = CXCursor_ExceptionSpecificationKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXCursor_ExceptionSpecificationKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXDiagnosticSeverity(override val value: Int) : CEnum { CXDiagnostic_Ignored(0), CXDiagnostic_Note(1), CXDiagnostic_Warning(2), CXDiagnostic_Error(3), CXDiagnostic_Fatal(4), ; companion object { fun byValue(value: Int) = CXDiagnosticSeverity.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXDiagnosticSeverity get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXLoadDiag_Error(override val value: Int) : CEnum { CXLoadDiag_None(0), CXLoadDiag_Unknown(1), CXLoadDiag_CannotLoad(2), CXLoadDiag_InvalidFile(3), ; companion object { fun byValue(value: Int) = CXLoadDiag_Error.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXLoadDiag_Error get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXSaveError(override val value: Int) : CEnum { CXSaveError_None(0), CXSaveError_Unknown(1), CXSaveError_TranslationErrors(2), CXSaveError_InvalidTU(3), ; companion object { fun byValue(value: Int) = CXSaveError.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXSaveError get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXTUResourceUsageKind(override val value: Int) : CEnum { CXTUResourceUsage_AST(1), CXTUResourceUsage_Identifiers(2), CXTUResourceUsage_Selectors(3), CXTUResourceUsage_GlobalCompletionResults(4), CXTUResourceUsage_SourceManagerContentCache(5), CXTUResourceUsage_AST_SideTables(6), CXTUResourceUsage_SourceManager_Membuffer_Malloc(7), CXTUResourceUsage_SourceManager_Membuffer_MMap(8), CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc(9), CXTUResourceUsage_ExternalASTSource_Membuffer_MMap(10), CXTUResourceUsage_Preprocessor(11), CXTUResourceUsage_PreprocessingRecord(12), CXTUResourceUsage_SourceManager_DataStructures(13), CXTUResourceUsage_Preprocessor_HeaderSearch(14), ; companion object { val CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST val CXTUResourceUsage_First = CXTUResourceUsage_AST val CXTUResourceUsage_MEMORY_IN_BYTES_END = CXTUResourceUsage_Preprocessor_HeaderSearch val CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch fun byValue(value: Int) = CXTUResourceUsageKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXTUResourceUsageKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXCursorKind(override val value: Int) : CEnum { CXCursor_UnexposedDecl(1), CXCursor_StructDecl(2), CXCursor_UnionDecl(3), CXCursor_ClassDecl(4), CXCursor_EnumDecl(5), CXCursor_FieldDecl(6), CXCursor_EnumConstantDecl(7), CXCursor_FunctionDecl(8), CXCursor_VarDecl(9), CXCursor_ParmDecl(10), CXCursor_ObjCInterfaceDecl(11), CXCursor_ObjCCategoryDecl(12), CXCursor_ObjCProtocolDecl(13), CXCursor_ObjCPropertyDecl(14), CXCursor_ObjCIvarDecl(15), CXCursor_ObjCInstanceMethodDecl(16), CXCursor_ObjCClassMethodDecl(17), CXCursor_ObjCImplementationDecl(18), CXCursor_ObjCCategoryImplDecl(19), CXCursor_TypedefDecl(20), CXCursor_CXXMethod(21), CXCursor_Namespace(22), CXCursor_LinkageSpec(23), CXCursor_Constructor(24), CXCursor_Destructor(25), CXCursor_ConversionFunction(26), CXCursor_TemplateTypeParameter(27), CXCursor_NonTypeTemplateParameter(28), CXCursor_TemplateTemplateParameter(29), CXCursor_FunctionTemplate(30), CXCursor_ClassTemplate(31), CXCursor_ClassTemplatePartialSpecialization(32), CXCursor_NamespaceAlias(33), CXCursor_UsingDirective(34), CXCursor_UsingDeclaration(35), CXCursor_TypeAliasDecl(36), CXCursor_ObjCSynthesizeDecl(37), CXCursor_ObjCDynamicDecl(38), CXCursor_CXXAccessSpecifier(39), CXCursor_ObjCSuperClassRef(40), CXCursor_ObjCProtocolRef(41), CXCursor_ObjCClassRef(42), CXCursor_TypeRef(43), CXCursor_CXXBaseSpecifier(44), CXCursor_TemplateRef(45), CXCursor_NamespaceRef(46), CXCursor_MemberRef(47), CXCursor_LabelRef(48), CXCursor_OverloadedDeclRef(49), CXCursor_VariableRef(50), CXCursor_InvalidFile(70), CXCursor_NoDeclFound(71), CXCursor_NotImplemented(72), CXCursor_InvalidCode(73), CXCursor_UnexposedExpr(100), CXCursor_DeclRefExpr(101), CXCursor_MemberRefExpr(102), CXCursor_CallExpr(103), CXCursor_ObjCMessageExpr(104), CXCursor_BlockExpr(105), CXCursor_IntegerLiteral(106), CXCursor_FloatingLiteral(107), CXCursor_ImaginaryLiteral(108), CXCursor_StringLiteral(109), CXCursor_CharacterLiteral(110), CXCursor_ParenExpr(111), CXCursor_UnaryOperator(112), CXCursor_ArraySubscriptExpr(113), CXCursor_BinaryOperator(114), CXCursor_CompoundAssignOperator(115), CXCursor_ConditionalOperator(116), CXCursor_CStyleCastExpr(117), CXCursor_CompoundLiteralExpr(118), CXCursor_InitListExpr(119), CXCursor_AddrLabelExpr(120), CXCursor_StmtExpr(121), CXCursor_GenericSelectionExpr(122), CXCursor_GNUNullExpr(123), CXCursor_CXXStaticCastExpr(124), CXCursor_CXXDynamicCastExpr(125), CXCursor_CXXReinterpretCastExpr(126), CXCursor_CXXConstCastExpr(127), CXCursor_CXXFunctionalCastExpr(128), CXCursor_CXXTypeidExpr(129), CXCursor_CXXBoolLiteralExpr(130), CXCursor_CXXNullPtrLiteralExpr(131), CXCursor_CXXThisExpr(132), CXCursor_CXXThrowExpr(133), CXCursor_CXXNewExpr(134), CXCursor_CXXDeleteExpr(135), CXCursor_UnaryExpr(136), CXCursor_ObjCStringLiteral(137), CXCursor_ObjCEncodeExpr(138), CXCursor_ObjCSelectorExpr(139), CXCursor_ObjCProtocolExpr(140), CXCursor_ObjCBridgedCastExpr(141), CXCursor_PackExpansionExpr(142), CXCursor_SizeOfPackExpr(143), CXCursor_LambdaExpr(144), CXCursor_ObjCBoolLiteralExpr(145), CXCursor_ObjCSelfExpr(146), CXCursor_OMPArraySectionExpr(147), CXCursor_ObjCAvailabilityCheckExpr(148), CXCursor_FixedPointLiteral(149), CXCursor_UnexposedStmt(200), CXCursor_LabelStmt(201), CXCursor_CompoundStmt(202), CXCursor_CaseStmt(203), CXCursor_DefaultStmt(204), CXCursor_IfStmt(205), CXCursor_SwitchStmt(206), CXCursor_WhileStmt(207), CXCursor_DoStmt(208), CXCursor_ForStmt(209), CXCursor_GotoStmt(210), CXCursor_IndirectGotoStmt(211), CXCursor_ContinueStmt(212), CXCursor_BreakStmt(213), CXCursor_ReturnStmt(214), CXCursor_GCCAsmStmt(215), CXCursor_ObjCAtTryStmt(216), CXCursor_ObjCAtCatchStmt(217), CXCursor_ObjCAtFinallyStmt(218), CXCursor_ObjCAtThrowStmt(219), CXCursor_ObjCAtSynchronizedStmt(220), CXCursor_ObjCAutoreleasePoolStmt(221), CXCursor_ObjCForCollectionStmt(222), CXCursor_CXXCatchStmt(223), CXCursor_CXXTryStmt(224), CXCursor_CXXForRangeStmt(225), CXCursor_SEHTryStmt(226), CXCursor_SEHExceptStmt(227), CXCursor_SEHFinallyStmt(228), CXCursor_MSAsmStmt(229), CXCursor_NullStmt(230), CXCursor_DeclStmt(231), CXCursor_OMPParallelDirective(232), CXCursor_OMPSimdDirective(233), CXCursor_OMPForDirective(234), CXCursor_OMPSectionsDirective(235), CXCursor_OMPSectionDirective(236), CXCursor_OMPSingleDirective(237), CXCursor_OMPParallelForDirective(238), CXCursor_OMPParallelSectionsDirective(239), CXCursor_OMPTaskDirective(240), CXCursor_OMPMasterDirective(241), CXCursor_OMPCriticalDirective(242), CXCursor_OMPTaskyieldDirective(243), CXCursor_OMPBarrierDirective(244), CXCursor_OMPTaskwaitDirective(245), CXCursor_OMPFlushDirective(246), CXCursor_SEHLeaveStmt(247), CXCursor_OMPOrderedDirective(248), CXCursor_OMPAtomicDirective(249), CXCursor_OMPForSimdDirective(250), CXCursor_OMPParallelForSimdDirective(251), CXCursor_OMPTargetDirective(252), CXCursor_OMPTeamsDirective(253), CXCursor_OMPTaskgroupDirective(254), CXCursor_OMPCancellationPointDirective(255), CXCursor_OMPCancelDirective(256), CXCursor_OMPTargetDataDirective(257), CXCursor_OMPTaskLoopDirective(258), CXCursor_OMPTaskLoopSimdDirective(259), CXCursor_OMPDistributeDirective(260), CXCursor_OMPTargetEnterDataDirective(261), CXCursor_OMPTargetExitDataDirective(262), CXCursor_OMPTargetParallelDirective(263), CXCursor_OMPTargetParallelForDirective(264), CXCursor_OMPTargetUpdateDirective(265), CXCursor_OMPDistributeParallelForDirective(266), CXCursor_OMPDistributeParallelForSimdDirective(267), CXCursor_OMPDistributeSimdDirective(268), CXCursor_OMPTargetParallelForSimdDirective(269), CXCursor_OMPTargetSimdDirective(270), CXCursor_OMPTeamsDistributeDirective(271), CXCursor_OMPTeamsDistributeSimdDirective(272), CXCursor_OMPTeamsDistributeParallelForSimdDirective(273), CXCursor_OMPTeamsDistributeParallelForDirective(274), CXCursor_OMPTargetTeamsDirective(275), CXCursor_OMPTargetTeamsDistributeDirective(276), CXCursor_OMPTargetTeamsDistributeParallelForDirective(277), CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective(278), CXCursor_OMPTargetTeamsDistributeSimdDirective(279), CXCursor_TranslationUnit(300), CXCursor_UnexposedAttr(400), CXCursor_IBActionAttr(401), CXCursor_IBOutletAttr(402), CXCursor_IBOutletCollectionAttr(403), CXCursor_CXXFinalAttr(404), CXCursor_CXXOverrideAttr(405), CXCursor_AnnotateAttr(406), CXCursor_AsmLabelAttr(407), CXCursor_PackedAttr(408), CXCursor_PureAttr(409), CXCursor_ConstAttr(410), CXCursor_NoDuplicateAttr(411), CXCursor_CUDAConstantAttr(412), CXCursor_CUDADeviceAttr(413), CXCursor_CUDAGlobalAttr(414), CXCursor_CUDAHostAttr(415), CXCursor_CUDASharedAttr(416), CXCursor_VisibilityAttr(417), CXCursor_DLLExport(418), CXCursor_DLLImport(419), CXCursor_NSReturnsRetained(420), CXCursor_NSReturnsNotRetained(421), CXCursor_NSReturnsAutoreleased(422), CXCursor_NSConsumesSelf(423), CXCursor_NSConsumed(424), CXCursor_ObjCException(425), CXCursor_ObjCNSObject(426), CXCursor_ObjCIndependentClass(427), CXCursor_ObjCPreciseLifetime(428), CXCursor_ObjCReturnsInnerPointer(429), CXCursor_ObjCRequiresSuper(430), CXCursor_ObjCRootClass(431), CXCursor_ObjCSubclassingRestricted(432), CXCursor_ObjCExplicitProtocolImpl(433), CXCursor_ObjCDesignatedInitializer(434), CXCursor_ObjCRuntimeVisible(435), CXCursor_ObjCBoxable(436), CXCursor_FlagEnum(437), CXCursor_PreprocessingDirective(500), CXCursor_MacroDefinition(501), CXCursor_MacroExpansion(502), CXCursor_InclusionDirective(503), CXCursor_ModuleImportDecl(600), CXCursor_TypeAliasTemplateDecl(601), CXCursor_StaticAssert(602), CXCursor_LastExtraDecl(603), CXCursor_OverloadCandidate(700), ; companion object { val CXCursor_FirstDecl = CXCursor_UnexposedDecl val CXCursor_LastDecl = CXCursor_CXXAccessSpecifier val CXCursor_FirstRef = CXCursor_ObjCSuperClassRef val CXCursor_LastRef = CXCursor_VariableRef val CXCursor_FirstInvalid = CXCursor_InvalidFile val CXCursor_LastInvalid = CXCursor_InvalidCode val CXCursor_FirstExpr = CXCursor_UnexposedExpr val CXCursor_LastExpr = CXCursor_FixedPointLiteral val CXCursor_FirstStmt = CXCursor_UnexposedStmt val CXCursor_AsmStmt = CXCursor_GCCAsmStmt val CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeSimdDirective val CXCursor_FirstAttr = CXCursor_UnexposedAttr val CXCursor_LastAttr = CXCursor_FlagEnum val CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective val CXCursor_MacroInstantiation = CXCursor_MacroExpansion val CXCursor_LastPreprocessing = CXCursor_InclusionDirective val CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl val CXCursor_FriendDecl = CXCursor_LastExtraDecl fun byValue(value: Int) = CXCursorKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXCursorKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXLinkageKind(override val value: Int) : CEnum { CXLinkage_Invalid(0), CXLinkage_NoLinkage(1), CXLinkage_Internal(2), CXLinkage_UniqueExternal(3), CXLinkage_External(4), ; companion object { fun byValue(value: Int) = CXLinkageKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXLinkageKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXVisibilityKind(override val value: Int) : CEnum { CXVisibility_Invalid(0), CXVisibility_Hidden(1), CXVisibility_Protected(2), CXVisibility_Default(3), ; companion object { fun byValue(value: Int) = CXVisibilityKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXVisibilityKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXLanguageKind(override val value: Int) : CEnum { CXLanguage_Invalid(0), CXLanguage_C(1), CXLanguage_ObjC(2), CXLanguage_CPlusPlus(3), ; companion object { fun byValue(value: Int) = CXLanguageKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXLanguageKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXTypeKind(override val value: Int) : CEnum { CXType_Invalid(0), CXType_Unexposed(1), CXType_Void(2), CXType_Bool(3), CXType_Char_U(4), CXType_UChar(5), CXType_Char16(6), CXType_Char32(7), CXType_UShort(8), CXType_UInt(9), CXType_ULong(10), CXType_ULongLong(11), CXType_UInt128(12), CXType_Char_S(13), CXType_SChar(14), CXType_WChar(15), CXType_Short(16), CXType_Int(17), CXType_Long(18), CXType_LongLong(19), CXType_Int128(20), CXType_Float(21), CXType_Double(22), CXType_LongDouble(23), CXType_NullPtr(24), CXType_Overload(25), CXType_Dependent(26), CXType_ObjCId(27), CXType_ObjCClass(28), CXType_ObjCSel(29), CXType_Float128(30), CXType_Half(31), CXType_Float16(32), CXType_ShortAccum(33), CXType_Accum(34), CXType_LongAccum(35), CXType_UShortAccum(36), CXType_UAccum(37), CXType_ULongAccum(38), CXType_Complex(100), CXType_Pointer(101), CXType_BlockPointer(102), CXType_LValueReference(103), CXType_RValueReference(104), CXType_Record(105), CXType_Enum(106), CXType_Typedef(107), CXType_ObjCInterface(108), CXType_ObjCObjectPointer(109), CXType_FunctionNoProto(110), CXType_FunctionProto(111), CXType_ConstantArray(112), CXType_Vector(113), CXType_IncompleteArray(114), CXType_VariableArray(115), CXType_DependentSizedArray(116), CXType_MemberPointer(117), CXType_Auto(118), CXType_Elaborated(119), CXType_Pipe(120), CXType_OCLImage1dRO(121), CXType_OCLImage1dArrayRO(122), CXType_OCLImage1dBufferRO(123), CXType_OCLImage2dRO(124), CXType_OCLImage2dArrayRO(125), CXType_OCLImage2dDepthRO(126), CXType_OCLImage2dArrayDepthRO(127), CXType_OCLImage2dMSAARO(128), CXType_OCLImage2dArrayMSAARO(129), CXType_OCLImage2dMSAADepthRO(130), CXType_OCLImage2dArrayMSAADepthRO(131), CXType_OCLImage3dRO(132), CXType_OCLImage1dWO(133), CXType_OCLImage1dArrayWO(134), CXType_OCLImage1dBufferWO(135), CXType_OCLImage2dWO(136), CXType_OCLImage2dArrayWO(137), CXType_OCLImage2dDepthWO(138), CXType_OCLImage2dArrayDepthWO(139), CXType_OCLImage2dMSAAWO(140), CXType_OCLImage2dArrayMSAAWO(141), CXType_OCLImage2dMSAADepthWO(142), CXType_OCLImage2dArrayMSAADepthWO(143), CXType_OCLImage3dWO(144), CXType_OCLImage1dRW(145), CXType_OCLImage1dArrayRW(146), CXType_OCLImage1dBufferRW(147), CXType_OCLImage2dRW(148), CXType_OCLImage2dArrayRW(149), CXType_OCLImage2dDepthRW(150), CXType_OCLImage2dArrayDepthRW(151), CXType_OCLImage2dMSAARW(152), CXType_OCLImage2dArrayMSAARW(153), CXType_OCLImage2dMSAADepthRW(154), CXType_OCLImage2dArrayMSAADepthRW(155), CXType_OCLImage3dRW(156), CXType_OCLSampler(157), CXType_OCLEvent(158), CXType_OCLQueue(159), CXType_OCLReserveID(160), CXType_ObjCObject(161), CXType_ObjCTypeParam(162), CXType_Attributed(163), CXType_OCLIntelSubgroupAVCMcePayload(164), CXType_OCLIntelSubgroupAVCImePayload(165), CXType_OCLIntelSubgroupAVCRefPayload(166), CXType_OCLIntelSubgroupAVCSicPayload(167), CXType_OCLIntelSubgroupAVCMceResult(168), CXType_OCLIntelSubgroupAVCImeResult(169), CXType_OCLIntelSubgroupAVCRefResult(170), CXType_OCLIntelSubgroupAVCSicResult(171), CXType_OCLIntelSubgroupAVCImeResultSingleRefStreamout(172), CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout(173), CXType_OCLIntelSubgroupAVCImeSingleRefStreamin(174), CXType_OCLIntelSubgroupAVCImeDualRefStreamin(175), ; companion object { val CXType_FirstBuiltin = CXType_Void val CXType_LastBuiltin = CXType_ULongAccum fun byValue(value: Int) = CXTypeKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXTypeKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXCallingConv(override val value: Int) : CEnum { CXCallingConv_Default(0), CXCallingConv_C(1), CXCallingConv_X86StdCall(2), CXCallingConv_X86FastCall(3), CXCallingConv_X86ThisCall(4), CXCallingConv_X86Pascal(5), CXCallingConv_AAPCS(6), CXCallingConv_AAPCS_VFP(7), CXCallingConv_X86RegCall(8), CXCallingConv_IntelOclBicc(9), CXCallingConv_Win64(10), CXCallingConv_X86_64SysV(11), CXCallingConv_X86VectorCall(12), CXCallingConv_Swift(13), CXCallingConv_PreserveMost(14), CXCallingConv_PreserveAll(15), CXCallingConv_AArch64VectorCall(16), CXCallingConv_Invalid(100), CXCallingConv_Unexposed(200), ; companion object { val CXCallingConv_X86_64Win64 = CXCallingConv_Win64 fun byValue(value: Int) = CXCallingConv.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXCallingConv get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXTemplateArgumentKind(override val value: Int) : CEnum { CXTemplateArgumentKind_Null(0), CXTemplateArgumentKind_Type(1), CXTemplateArgumentKind_Declaration(2), CXTemplateArgumentKind_NullPtr(3), CXTemplateArgumentKind_Integral(4), CXTemplateArgumentKind_Template(5), CXTemplateArgumentKind_TemplateExpansion(6), CXTemplateArgumentKind_Expression(7), CXTemplateArgumentKind_Pack(8), CXTemplateArgumentKind_Invalid(9), ; companion object { fun byValue(value: Int) = CXTemplateArgumentKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXTemplateArgumentKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CX_CXXAccessSpecifier(override val value: Int) : CEnum { CX_CXXInvalidAccessSpecifier(0), CX_CXXPublic(1), CX_CXXProtected(2), CX_CXXPrivate(3), ; companion object { fun byValue(value: Int) = CX_CXXAccessSpecifier.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CX_CXXAccessSpecifier get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CX_StorageClass(override val value: Int) : CEnum { CX_SC_Invalid(0), CX_SC_None(1), CX_SC_Extern(2), CX_SC_Static(3), CX_SC_PrivateExtern(4), CX_SC_OpenCLWorkGroupLocal(5), CX_SC_Auto(6), CX_SC_Register(7), ; companion object { fun byValue(value: Int) = CX_StorageClass.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CX_StorageClass get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXChildVisitResult(override val value: Int) : CEnum { CXChildVisit_Break(0), CXChildVisit_Continue(1), CXChildVisit_Recurse(2), ; companion object { fun byValue(value: Int) = CXChildVisitResult.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXChildVisitResult get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXTokenKind(override val value: Int) : CEnum { CXToken_Punctuation(0), CXToken_Keyword(1), CXToken_Identifier(2), CXToken_Literal(3), CXToken_Comment(4), ; companion object { fun byValue(value: Int) = CXTokenKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXTokenKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXCompletionChunkKind(override val value: Int) : CEnum { CXCompletionChunk_Optional(0), CXCompletionChunk_TypedText(1), CXCompletionChunk_Text(2), CXCompletionChunk_Placeholder(3), CXCompletionChunk_Informative(4), CXCompletionChunk_CurrentParameter(5), CXCompletionChunk_LeftParen(6), CXCompletionChunk_RightParen(7), CXCompletionChunk_LeftBracket(8), CXCompletionChunk_RightBracket(9), CXCompletionChunk_LeftBrace(10), CXCompletionChunk_RightBrace(11), CXCompletionChunk_LeftAngle(12), CXCompletionChunk_RightAngle(13), CXCompletionChunk_Comma(14), CXCompletionChunk_ResultType(15), CXCompletionChunk_Colon(16), CXCompletionChunk_SemiColon(17), CXCompletionChunk_Equal(18), CXCompletionChunk_HorizontalSpace(19), CXCompletionChunk_VerticalSpace(20), ; companion object { fun byValue(value: Int) = CXCompletionChunkKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXCompletionChunkKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXEvalResultKind(override val value: Int) : CEnum { CXEval_Int(1), CXEval_Float(2), CXEval_ObjCStrLiteral(3), CXEval_StrLiteral(4), CXEval_CFStr(5), CXEval_Other(6), CXEval_UnExposed(0), ; companion object { fun byValue(value: Int) = CXEvalResultKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXEvalResultKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXVisitorResult(override val value: Int) : CEnum { CXVisit_Break(0), CXVisit_Continue(1), ; companion object { fun byValue(value: Int) = CXVisitorResult.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXVisitorResult get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXResult(override val value: Int) : CEnum { CXResult_Success(0), CXResult_Invalid(1), CXResult_VisitBreak(2), ; companion object { fun byValue(value: Int) = CXResult.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXResult get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXIdxEntityKind(override val value: Int) : CEnum { CXIdxEntity_Unexposed(0), CXIdxEntity_Typedef(1), CXIdxEntity_Function(2), CXIdxEntity_Variable(3), CXIdxEntity_Field(4), CXIdxEntity_EnumConstant(5), CXIdxEntity_ObjCClass(6), CXIdxEntity_ObjCProtocol(7), CXIdxEntity_ObjCCategory(8), CXIdxEntity_ObjCInstanceMethod(9), CXIdxEntity_ObjCClassMethod(10), CXIdxEntity_ObjCProperty(11), CXIdxEntity_ObjCIvar(12), CXIdxEntity_Enum(13), CXIdxEntity_Struct(14), CXIdxEntity_Union(15), CXIdxEntity_CXXClass(16), CXIdxEntity_CXXNamespace(17), CXIdxEntity_CXXNamespaceAlias(18), CXIdxEntity_CXXStaticVariable(19), CXIdxEntity_CXXStaticMethod(20), CXIdxEntity_CXXInstanceMethod(21), CXIdxEntity_CXXConstructor(22), CXIdxEntity_CXXDestructor(23), CXIdxEntity_CXXConversionFunction(24), CXIdxEntity_CXXTypeAlias(25), CXIdxEntity_CXXInterface(26), ; companion object { fun byValue(value: Int) = CXIdxEntityKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXIdxEntityKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } enum class CXNullabilityKind(override val value: Int) : CEnum { CXNullabilityKind_Nullable(0), CXNullabilityKind_NonNull(1), CXNullabilityKind_Unspecified(2), ; companion object { fun byValue(value: Int) = CXNullabilityKind.values().find { it.value == value }!! } class Var(rawPtr: NativePtr) : CEnumVar(rawPtr) { companion object : Type(IntVar.size.toInt()) var value: CXNullabilityKind get() = byValue(this.reinterpret().value) set(value) { this.reinterpret().value = value.value } } } fun clang_getCString(string: CValue): CPointer? { memScoped { return interpretCPointer(kniBridge0(string.getPointer(memScope).rawValue)) } } fun clang_disposeString(string: CValue): Unit { memScoped { return kniBridge1(string.getPointer(memScope).rawValue) } } fun clang_disposeStringSet(set: CValuesRef?): Unit { memScoped { return kniBridge2(set?.getPointer(memScope).rawValue) } } fun clang_getBuildSessionTimestamp(): Long { return kniBridge3() } fun clang_VirtualFileOverlay_create(options: Int): CXVirtualFileOverlay? { return interpretCPointer(kniBridge4(options)) } fun clang_VirtualFileOverlay_addFileMapping(arg0: CXVirtualFileOverlay?, virtualPath: String?, realPath: String?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge5(arg0.rawValue, virtualPath?.cstr?.getPointer(memScope).rawValue, realPath?.cstr?.getPointer(memScope).rawValue)) } } fun clang_VirtualFileOverlay_setCaseSensitivity(arg0: CXVirtualFileOverlay?, caseSensitive: Int): CXErrorCode { return CXErrorCode.byValue(kniBridge6(arg0.rawValue, caseSensitive)) } fun clang_VirtualFileOverlay_writeToBuffer(arg0: CXVirtualFileOverlay?, options: Int, out_buffer_ptr: CValuesRef>?, out_buffer_size: CValuesRef?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge7(arg0.rawValue, options, out_buffer_ptr?.getPointer(memScope).rawValue, out_buffer_size?.getPointer(memScope).rawValue)) } } fun clang_free(buffer: CValuesRef<*>?): Unit { memScoped { return kniBridge8(buffer?.getPointer(memScope).rawValue) } } fun clang_VirtualFileOverlay_dispose(arg0: CXVirtualFileOverlay?): Unit { return kniBridge9(arg0.rawValue) } fun clang_ModuleMapDescriptor_create(options: Int): CXModuleMapDescriptor? { return interpretCPointer(kniBridge10(options)) } fun clang_ModuleMapDescriptor_setFrameworkModuleName(arg0: CXModuleMapDescriptor?, name: String?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge11(arg0.rawValue, name?.cstr?.getPointer(memScope).rawValue)) } } fun clang_ModuleMapDescriptor_setUmbrellaHeader(arg0: CXModuleMapDescriptor?, name: String?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge12(arg0.rawValue, name?.cstr?.getPointer(memScope).rawValue)) } } fun clang_ModuleMapDescriptor_writeToBuffer(arg0: CXModuleMapDescriptor?, options: Int, out_buffer_ptr: CValuesRef>?, out_buffer_size: CValuesRef?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge13(arg0.rawValue, options, out_buffer_ptr?.getPointer(memScope).rawValue, out_buffer_size?.getPointer(memScope).rawValue)) } } fun clang_ModuleMapDescriptor_dispose(arg0: CXModuleMapDescriptor?): Unit { return kniBridge14(arg0.rawValue) } fun clang_createIndex(excludeDeclarationsFromPCH: Int, displayDiagnostics: Int): CXIndex? { return interpretCPointer(kniBridge15(excludeDeclarationsFromPCH, displayDiagnostics)) } fun clang_disposeIndex(index: CXIndex?): Unit { return kniBridge16(index.rawValue) } fun clang_CXIndex_setGlobalOptions(arg0: CXIndex?, options: Int): Unit { return kniBridge17(arg0.rawValue, options) } fun clang_CXIndex_getGlobalOptions(arg0: CXIndex?): Int { return kniBridge18(arg0.rawValue) } fun clang_CXIndex_setInvocationEmissionPathOption(arg0: CXIndex?, Path: String?): Unit { memScoped { return kniBridge19(arg0.rawValue, Path?.cstr?.getPointer(memScope).rawValue) } } fun clang_getFileName(SFile: CXFile?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge20(SFile.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getFileTime(SFile: CXFile?): time_t { return kniBridge21(SFile.rawValue) } fun clang_getFileUniqueID(file: CXFile?, outID: CValuesRef?): Int { memScoped { return kniBridge22(file.rawValue, outID?.getPointer(memScope).rawValue) } } fun clang_isFileMultipleIncludeGuarded(tu: CXTranslationUnit?, file: CXFile?): Int { return kniBridge23(tu.rawValue, file.rawValue) } fun clang_getFile(tu: CXTranslationUnit?, file_name: String?): CXFile? { memScoped { return interpretCPointer(kniBridge24(tu.rawValue, file_name?.cstr?.getPointer(memScope).rawValue)) } } fun clang_getFileContents(tu: CXTranslationUnit?, file: CXFile?, size: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge25(tu.rawValue, file.rawValue, size?.getPointer(memScope).rawValue)) } } fun clang_File_isEqual(file1: CXFile?, file2: CXFile?): Int { return kniBridge26(file1.rawValue, file2.rawValue) } fun clang_File_tryGetRealPathName(file: CXFile?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge27(file.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getNullLocation(): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge28(kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_equalLocations(loc1: CValue, loc2: CValue): Int { memScoped { return kniBridge29(loc1.getPointer(memScope).rawValue, loc2.getPointer(memScope).rawValue) } } fun clang_getLocation(tu: CXTranslationUnit?, file: CXFile?, line: Int, column: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge30(tu.rawValue, file.rawValue, line, column, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getLocationForOffset(tu: CXTranslationUnit?, file: CXFile?, offset: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge31(tu.rawValue, file.rawValue, offset, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_Location_isInSystemHeader(location: CValue): Int { memScoped { return kniBridge32(location.getPointer(memScope).rawValue) } } fun clang_Location_isFromMainFile(location: CValue): Int { memScoped { return kniBridge33(location.getPointer(memScope).rawValue) } } fun clang_getNullRange(): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge34(kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getRange(begin: CValue, end: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge35(begin.getPointer(memScope).rawValue, end.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_equalRanges(range1: CValue, range2: CValue): Int { memScoped { return kniBridge36(range1.getPointer(memScope).rawValue, range2.getPointer(memScope).rawValue) } } fun clang_Range_isNull(range: CValue): Int { memScoped { return kniBridge37(range.getPointer(memScope).rawValue) } } fun clang_getExpansionLocation(location: CValue, file: CValuesRef?, line: CValuesRef?, column: CValuesRef?, offset: CValuesRef?): Unit { memScoped { return kniBridge38(location.getPointer(memScope).rawValue, file?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue, offset?.getPointer(memScope).rawValue) } } fun clang_getPresumedLocation(location: CValue, filename: CValuesRef?, line: CValuesRef?, column: CValuesRef?): Unit { memScoped { return kniBridge39(location.getPointer(memScope).rawValue, filename?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue) } } fun clang_getInstantiationLocation(location: CValue, file: CValuesRef?, line: CValuesRef?, column: CValuesRef?, offset: CValuesRef?): Unit { memScoped { return kniBridge40(location.getPointer(memScope).rawValue, file?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue, offset?.getPointer(memScope).rawValue) } } fun clang_getSpellingLocation(location: CValue, file: CValuesRef?, line: CValuesRef?, column: CValuesRef?, offset: CValuesRef?): Unit { memScoped { return kniBridge41(location.getPointer(memScope).rawValue, file?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue, offset?.getPointer(memScope).rawValue) } } fun clang_getFileLocation(location: CValue, file: CValuesRef?, line: CValuesRef?, column: CValuesRef?, offset: CValuesRef?): Unit { memScoped { return kniBridge42(location.getPointer(memScope).rawValue, file?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue, offset?.getPointer(memScope).rawValue) } } fun clang_getRangeStart(range: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge43(range.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getRangeEnd(range: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge44(range.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getSkippedRanges(tu: CXTranslationUnit?, file: CXFile?): CPointer? { return interpretCPointer(kniBridge45(tu.rawValue, file.rawValue)) } fun clang_getAllSkippedRanges(tu: CXTranslationUnit?): CPointer? { return interpretCPointer(kniBridge46(tu.rawValue)) } fun clang_disposeSourceRangeList(ranges: CValuesRef?): Unit { memScoped { return kniBridge47(ranges?.getPointer(memScope).rawValue) } } fun clang_getNumDiagnosticsInSet(Diags: CXDiagnosticSet?): Int { return kniBridge48(Diags.rawValue) } fun clang_getDiagnosticInSet(Diags: CXDiagnosticSet?, Index: Int): CXDiagnostic? { return interpretCPointer(kniBridge49(Diags.rawValue, Index)) } fun clang_loadDiagnostics(file: String?, error: CValuesRef?, errorString: CValuesRef?): CXDiagnosticSet? { memScoped { return interpretCPointer(kniBridge50(file?.cstr?.getPointer(memScope).rawValue, error?.getPointer(memScope).rawValue, errorString?.getPointer(memScope).rawValue)) } } fun clang_disposeDiagnosticSet(Diags: CXDiagnosticSet?): Unit { return kniBridge51(Diags.rawValue) } fun clang_getChildDiagnostics(D: CXDiagnostic?): CXDiagnosticSet? { return interpretCPointer(kniBridge52(D.rawValue)) } fun clang_getNumDiagnostics(Unit: CXTranslationUnit?): Int { return kniBridge53(Unit.rawValue) } fun clang_getDiagnostic(Unit: CXTranslationUnit?, Index: Int): CXDiagnostic? { return interpretCPointer(kniBridge54(Unit.rawValue, Index)) } fun clang_getDiagnosticSetFromTU(Unit: CXTranslationUnit?): CXDiagnosticSet? { return interpretCPointer(kniBridge55(Unit.rawValue)) } fun clang_disposeDiagnostic(Diagnostic: CXDiagnostic?): Unit { return kniBridge56(Diagnostic.rawValue) } fun clang_formatDiagnostic(Diagnostic: CXDiagnostic?, Options: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge57(Diagnostic.rawValue, Options, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_defaultDiagnosticDisplayOptions(): Int { return kniBridge58() } fun clang_getDiagnosticSeverity(arg0: CXDiagnostic?): CXDiagnosticSeverity { return CXDiagnosticSeverity.byValue(kniBridge59(arg0.rawValue)) } fun clang_getDiagnosticLocation(arg0: CXDiagnostic?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge60(arg0.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDiagnosticSpelling(arg0: CXDiagnostic?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge61(arg0.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDiagnosticOption(Diag: CXDiagnostic?, Disable: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge62(Diag.rawValue, Disable?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getDiagnosticCategory(arg0: CXDiagnostic?): Int { return kniBridge63(arg0.rawValue) } fun clang_getDiagnosticCategoryName(Category: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge64(Category, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDiagnosticCategoryText(arg0: CXDiagnostic?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge65(arg0.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDiagnosticNumRanges(arg0: CXDiagnostic?): Int { return kniBridge66(arg0.rawValue) } fun clang_getDiagnosticRange(Diagnostic: CXDiagnostic?, Range: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge67(Diagnostic.rawValue, Range, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDiagnosticNumFixIts(Diagnostic: CXDiagnostic?): Int { return kniBridge68(Diagnostic.rawValue) } fun clang_getDiagnosticFixIt(Diagnostic: CXDiagnostic?, FixIt: Int, ReplacementRange: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge69(Diagnostic.rawValue, FixIt, ReplacementRange?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTranslationUnitSpelling(CTUnit: CXTranslationUnit?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge70(CTUnit.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_createTranslationUnitFromSourceFile(CIdx: CXIndex?, source_filename: String?, num_clang_command_line_args: Int, clang_command_line_args: CValuesRef>?, num_unsaved_files: Int, unsaved_files: CValuesRef?): CXTranslationUnit? { memScoped { return interpretCPointer(kniBridge71(CIdx.rawValue, source_filename?.cstr?.getPointer(memScope).rawValue, num_clang_command_line_args, clang_command_line_args?.getPointer(memScope).rawValue, num_unsaved_files, unsaved_files?.getPointer(memScope).rawValue)) } } fun clang_createTranslationUnit(CIdx: CXIndex?, ast_filename: String?): CXTranslationUnit? { memScoped { return interpretCPointer(kniBridge72(CIdx.rawValue, ast_filename?.cstr?.getPointer(memScope).rawValue)) } } fun clang_createTranslationUnit2(CIdx: CXIndex?, ast_filename: String?, out_TU: CValuesRef?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge73(CIdx.rawValue, ast_filename?.cstr?.getPointer(memScope).rawValue, out_TU?.getPointer(memScope).rawValue)) } } fun clang_defaultEditingTranslationUnitOptions(): Int { return kniBridge74() } fun clang_parseTranslationUnit(CIdx: CXIndex?, source_filename: String?, command_line_args: CValuesRef>?, num_command_line_args: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, options: Int): CXTranslationUnit? { memScoped { return interpretCPointer(kniBridge75(CIdx.rawValue, source_filename?.cstr?.getPointer(memScope).rawValue, command_line_args?.getPointer(memScope).rawValue, num_command_line_args, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, options)) } } fun clang_parseTranslationUnit2(CIdx: CXIndex?, source_filename: String?, command_line_args: CValuesRef>?, num_command_line_args: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, options: Int, out_TU: CValuesRef?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge76(CIdx.rawValue, source_filename?.cstr?.getPointer(memScope).rawValue, command_line_args?.getPointer(memScope).rawValue, num_command_line_args, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, options, out_TU?.getPointer(memScope).rawValue)) } } fun clang_parseTranslationUnit2FullArgv(CIdx: CXIndex?, source_filename: String?, command_line_args: CValuesRef>?, num_command_line_args: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, options: Int, out_TU: CValuesRef?): CXErrorCode { memScoped { return CXErrorCode.byValue(kniBridge77(CIdx.rawValue, source_filename?.cstr?.getPointer(memScope).rawValue, command_line_args?.getPointer(memScope).rawValue, num_command_line_args, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, options, out_TU?.getPointer(memScope).rawValue)) } } fun clang_defaultSaveOptions(TU: CXTranslationUnit?): Int { return kniBridge78(TU.rawValue) } fun clang_saveTranslationUnit(TU: CXTranslationUnit?, FileName: String?, options: Int): Int { memScoped { return kniBridge79(TU.rawValue, FileName?.cstr?.getPointer(memScope).rawValue, options) } } fun clang_suspendTranslationUnit(arg0: CXTranslationUnit?): Int { return kniBridge80(arg0.rawValue) } fun clang_disposeTranslationUnit(arg0: CXTranslationUnit?): Unit { return kniBridge81(arg0.rawValue) } fun clang_defaultReparseOptions(TU: CXTranslationUnit?): Int { return kniBridge82(TU.rawValue) } fun clang_reparseTranslationUnit(TU: CXTranslationUnit?, num_unsaved_files: Int, unsaved_files: CValuesRef?, options: Int): Int { memScoped { return kniBridge83(TU.rawValue, num_unsaved_files, unsaved_files?.getPointer(memScope).rawValue, options) } } fun clang_getTUResourceUsageName(kind: CXTUResourceUsageKind): CPointer? { return interpretCPointer(kniBridge84(kind.value)) } fun clang_getCXTUResourceUsage(TU: CXTranslationUnit?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge85(TU.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_disposeCXTUResourceUsage(usage: CValue): Unit { memScoped { return kniBridge86(usage.getPointer(memScope).rawValue) } } fun clang_getTranslationUnitTargetInfo(CTUnit: CXTranslationUnit?): CXTargetInfo? { return interpretCPointer(kniBridge87(CTUnit.rawValue)) } fun clang_TargetInfo_dispose(Info: CXTargetInfo?): Unit { return kniBridge88(Info.rawValue) } fun clang_TargetInfo_getTriple(Info: CXTargetInfo?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge89(Info.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_TargetInfo_getPointerWidth(Info: CXTargetInfo?): Int { return kniBridge90(Info.rawValue) } fun clang_getNullCursor(): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge91(kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getTranslationUnitCursor(arg0: CXTranslationUnit?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge92(arg0.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_equalCursors(arg0: CValue, arg1: CValue): Int { memScoped { return kniBridge93(arg0.getPointer(memScope).rawValue, arg1.getPointer(memScope).rawValue) } } fun clang_Cursor_isNull(cursor: CValue): Int { memScoped { return kniBridge94(cursor.getPointer(memScope).rawValue) } } fun clang_hashCursor(arg0: CValue): Int { memScoped { return kniBridge95(arg0.getPointer(memScope).rawValue) } } fun clang_getCursorKind(arg0: CValue): CXCursorKind { memScoped { return CXCursorKind.byValue(kniBridge96(arg0.getPointer(memScope).rawValue)) } } fun clang_isDeclaration(arg0: CXCursorKind): Int { return kniBridge97(arg0.value) } fun clang_isInvalidDeclaration(arg0: CValue): Int { memScoped { return kniBridge98(arg0.getPointer(memScope).rawValue) } } fun clang_isReference(arg0: CXCursorKind): Int { return kniBridge99(arg0.value) } fun clang_isExpression(arg0: CXCursorKind): Int { return kniBridge100(arg0.value) } fun clang_isStatement(arg0: CXCursorKind): Int { return kniBridge101(arg0.value) } fun clang_isAttribute(arg0: CXCursorKind): Int { return kniBridge102(arg0.value) } fun clang_Cursor_hasAttrs(C: CValue): Int { memScoped { return kniBridge103(C.getPointer(memScope).rawValue) } } fun clang_isInvalid(arg0: CXCursorKind): Int { return kniBridge104(arg0.value) } fun clang_isTranslationUnit(arg0: CXCursorKind): Int { return kniBridge105(arg0.value) } fun clang_isPreprocessing(arg0: CXCursorKind): Int { return kniBridge106(arg0.value) } fun clang_isUnexposed(arg0: CXCursorKind): Int { return kniBridge107(arg0.value) } fun clang_getCursorLinkage(cursor: CValue): CXLinkageKind { memScoped { return CXLinkageKind.byValue(kniBridge108(cursor.getPointer(memScope).rawValue)) } } fun clang_getCursorVisibility(cursor: CValue): CXVisibilityKind { memScoped { return CXVisibilityKind.byValue(kniBridge109(cursor.getPointer(memScope).rawValue)) } } fun clang_getCursorAvailability(cursor: CValue): CXAvailabilityKind { memScoped { return CXAvailabilityKind.byValue(kniBridge110(cursor.getPointer(memScope).rawValue)) } } fun clang_getCursorPlatformAvailability(cursor: CValue, always_deprecated: CValuesRef?, deprecated_message: CValuesRef?, always_unavailable: CValuesRef?, unavailable_message: CValuesRef?, availability: CValuesRef?, availability_size: Int): Int { memScoped { return kniBridge111(cursor.getPointer(memScope).rawValue, always_deprecated?.getPointer(memScope).rawValue, deprecated_message?.getPointer(memScope).rawValue, always_unavailable?.getPointer(memScope).rawValue, unavailable_message?.getPointer(memScope).rawValue, availability?.getPointer(memScope).rawValue, availability_size) } } fun clang_disposeCXPlatformAvailability(availability: CValuesRef?): Unit { memScoped { return kniBridge112(availability?.getPointer(memScope).rawValue) } } fun clang_getCursorLanguage(cursor: CValue): CXLanguageKind { memScoped { return CXLanguageKind.byValue(kniBridge113(cursor.getPointer(memScope).rawValue)) } } fun clang_getCursorTLSKind(cursor: CValue): CXTLSKind { memScoped { return kniBridge114(cursor.getPointer(memScope).rawValue) } } fun clang_Cursor_getTranslationUnit(arg0: CValue): CXTranslationUnit? { memScoped { return interpretCPointer(kniBridge115(arg0.getPointer(memScope).rawValue)) } } fun clang_createCXCursorSet(): CXCursorSet? { return interpretCPointer(kniBridge116()) } fun clang_disposeCXCursorSet(cset: CXCursorSet?): Unit { return kniBridge117(cset.rawValue) } fun clang_CXCursorSet_contains(cset: CXCursorSet?, cursor: CValue): Int { memScoped { return kniBridge118(cset.rawValue, cursor.getPointer(memScope).rawValue) } } fun clang_CXCursorSet_insert(cset: CXCursorSet?, cursor: CValue): Int { memScoped { return kniBridge119(cset.rawValue, cursor.getPointer(memScope).rawValue) } } fun clang_getCursorSemanticParent(cursor: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge120(cursor.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorLexicalParent(cursor: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge121(cursor.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getOverriddenCursors(cursor: CValue, overridden: CValuesRef>?, num_overridden: CValuesRef?): Unit { memScoped { return kniBridge122(cursor.getPointer(memScope).rawValue, overridden?.getPointer(memScope).rawValue, num_overridden?.getPointer(memScope).rawValue) } } fun clang_disposeOverriddenCursors(overridden: CValuesRef?): Unit { memScoped { return kniBridge123(overridden?.getPointer(memScope).rawValue) } } fun clang_getIncludedFile(cursor: CValue): CXFile? { memScoped { return interpretCPointer(kniBridge124(cursor.getPointer(memScope).rawValue)) } } fun clang_getCursor(arg0: CXTranslationUnit?, arg1: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge125(arg0.rawValue, arg1.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorLocation(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge126(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorExtent(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge127(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorType(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge128(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTypeSpelling(CT: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge129(CT.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTypedefDeclUnderlyingType(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge130(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getEnumDeclIntegerType(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge131(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getEnumConstantDeclValue(C: CValue): Long { memScoped { return kniBridge132(C.getPointer(memScope).rawValue) } } fun clang_getEnumConstantDeclUnsignedValue(C: CValue): Long { memScoped { return kniBridge133(C.getPointer(memScope).rawValue) } } fun clang_getFieldDeclBitWidth(C: CValue): Int { memScoped { return kniBridge134(C.getPointer(memScope).rawValue) } } fun clang_Cursor_getNumArguments(C: CValue): Int { memScoped { return kniBridge135(C.getPointer(memScope).rawValue) } } fun clang_Cursor_getArgument(C: CValue, i: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge136(C.getPointer(memScope).rawValue, i, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getNumTemplateArguments(C: CValue): Int { memScoped { return kniBridge137(C.getPointer(memScope).rawValue) } } fun clang_Cursor_getTemplateArgumentKind(C: CValue, I: Int): CXTemplateArgumentKind { memScoped { return CXTemplateArgumentKind.byValue(kniBridge138(C.getPointer(memScope).rawValue, I)) } } fun clang_Cursor_getTemplateArgumentType(C: CValue, I: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge139(C.getPointer(memScope).rawValue, I, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getTemplateArgumentValue(C: CValue, I: Int): Long { memScoped { return kniBridge140(C.getPointer(memScope).rawValue, I) } } fun clang_Cursor_getTemplateArgumentUnsignedValue(C: CValue, I: Int): Long { memScoped { return kniBridge141(C.getPointer(memScope).rawValue, I) } } fun clang_equalTypes(A: CValue, B: CValue): Int { memScoped { return kniBridge142(A.getPointer(memScope).rawValue, B.getPointer(memScope).rawValue) } } fun clang_getCanonicalType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge143(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_isConstQualifiedType(T: CValue): Int { memScoped { return kniBridge144(T.getPointer(memScope).rawValue) } } fun clang_Cursor_isMacroFunctionLike(C: CValue): Int { memScoped { return kniBridge145(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isMacroBuiltin(C: CValue): Int { memScoped { return kniBridge146(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isFunctionInlined(C: CValue): Int { memScoped { return kniBridge147(C.getPointer(memScope).rawValue) } } fun clang_isVolatileQualifiedType(T: CValue): Int { memScoped { return kniBridge148(T.getPointer(memScope).rawValue) } } fun clang_isRestrictQualifiedType(T: CValue): Int { memScoped { return kniBridge149(T.getPointer(memScope).rawValue) } } fun clang_getAddressSpace(T: CValue): Int { memScoped { return kniBridge150(T.getPointer(memScope).rawValue) } } fun clang_getTypedefName(CT: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge151(CT.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getPointeeType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge152(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTypeDeclaration(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge153(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getDeclObjCTypeEncoding(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge154(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getObjCEncoding(type: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge155(type.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTypeKindSpelling(K: CXTypeKind): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge156(K.value, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getFunctionTypeCallingConv(T: CValue): CXCallingConv { memScoped { return CXCallingConv.byValue(kniBridge157(T.getPointer(memScope).rawValue)) } } fun clang_getResultType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge158(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getExceptionSpecificationType(T: CValue): Int { memScoped { return kniBridge159(T.getPointer(memScope).rawValue) } } fun clang_getNumArgTypes(T: CValue): Int { memScoped { return kniBridge160(T.getPointer(memScope).rawValue) } } fun clang_getArgType(T: CValue, i: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge161(T.getPointer(memScope).rawValue, i, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getObjCObjectBaseType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge162(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getNumObjCProtocolRefs(T: CValue): Int { memScoped { return kniBridge163(T.getPointer(memScope).rawValue) } } fun clang_Type_getObjCProtocolDecl(T: CValue, i: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge164(T.getPointer(memScope).rawValue, i, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getNumObjCTypeArgs(T: CValue): Int { memScoped { return kniBridge165(T.getPointer(memScope).rawValue) } } fun clang_Type_getObjCTypeArg(T: CValue, i: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge166(T.getPointer(memScope).rawValue, i, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_isFunctionTypeVariadic(T: CValue): Int { memScoped { return kniBridge167(T.getPointer(memScope).rawValue) } } fun clang_getCursorResultType(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge168(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorExceptionSpecificationType(C: CValue): Int { memScoped { return kniBridge169(C.getPointer(memScope).rawValue) } } fun clang_isPODType(T: CValue): Int { memScoped { return kniBridge170(T.getPointer(memScope).rawValue) } } fun clang_getElementType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge171(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getNumElements(T: CValue): Long { memScoped { return kniBridge172(T.getPointer(memScope).rawValue) } } fun clang_getArrayElementType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge173(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getArraySize(T: CValue): Long { memScoped { return kniBridge174(T.getPointer(memScope).rawValue) } } fun clang_Type_getNamedType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge175(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_isTransparentTagTypedef(T: CValue): Int { memScoped { return kniBridge176(T.getPointer(memScope).rawValue) } } fun clang_Type_getNullability(T: CValue): CXTypeNullabilityKind { memScoped { return kniBridge177(T.getPointer(memScope).rawValue) } } fun clang_Type_getAlignOf(T: CValue): Long { memScoped { return kniBridge178(T.getPointer(memScope).rawValue) } } fun clang_Type_getClassType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge179(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getSizeOf(T: CValue): Long { memScoped { return kniBridge180(T.getPointer(memScope).rawValue) } } fun clang_Type_getOffsetOf(T: CValue, S: String?): Long { memScoped { return kniBridge181(T.getPointer(memScope).rawValue, S?.cstr?.getPointer(memScope).rawValue) } } fun clang_Type_getModifiedType(T: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge182(T.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getOffsetOfField(C: CValue): Long { memScoped { return kniBridge183(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isAnonymous(C: CValue): Int { memScoped { return kniBridge184(C.getPointer(memScope).rawValue) } } fun clang_Type_getNumTemplateArguments(T: CValue): Int { memScoped { return kniBridge185(T.getPointer(memScope).rawValue) } } fun clang_Type_getTemplateArgumentAsType(T: CValue, i: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge186(T.getPointer(memScope).rawValue, i, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getCXXRefQualifier(T: CValue): CXRefQualifierKind { memScoped { return kniBridge187(T.getPointer(memScope).rawValue) } } fun clang_Cursor_isBitField(C: CValue): Int { memScoped { return kniBridge188(C.getPointer(memScope).rawValue) } } fun clang_isVirtualBase(arg0: CValue): Int { memScoped { return kniBridge189(arg0.getPointer(memScope).rawValue) } } fun clang_getCXXAccessSpecifier(arg0: CValue): CX_CXXAccessSpecifier { memScoped { return CX_CXXAccessSpecifier.byValue(kniBridge190(arg0.getPointer(memScope).rawValue)) } } fun clang_Cursor_getStorageClass(arg0: CValue): CX_StorageClass { memScoped { return CX_StorageClass.byValue(kniBridge191(arg0.getPointer(memScope).rawValue)) } } fun clang_getNumOverloadedDecls(cursor: CValue): Int { memScoped { return kniBridge192(cursor.getPointer(memScope).rawValue) } } fun clang_getOverloadedDecl(cursor: CValue, index: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge193(cursor.getPointer(memScope).rawValue, index, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getIBOutletCollectionType(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge194(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_visitChildren(parent: CValue, visitor: CXCursorVisitor?, client_data: CXClientData?): Int { memScoped { return kniBridge195(parent.getPointer(memScope).rawValue, visitor.rawValue, client_data.rawValue) } } fun clang_getCursorUSR(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge196(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCClass(class_name: String?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge197(class_name?.cstr?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCCategory(class_name: String?, category_name: String?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge198(class_name?.cstr?.getPointer(memScope).rawValue, category_name?.cstr?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCProtocol(protocol_name: String?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge199(protocol_name?.cstr?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCIvar(name: String?, classUSR: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge200(name?.cstr?.getPointer(memScope).rawValue, classUSR.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCMethod(name: String?, isInstanceMethod: Int, classUSR: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge201(name?.cstr?.getPointer(memScope).rawValue, isInstanceMethod, classUSR.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_constructUSR_ObjCProperty(property: String?, classUSR: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge202(property?.cstr?.getPointer(memScope).rawValue, classUSR.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorSpelling(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge203(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getSpellingNameRange(arg0: CValue, pieceIndex: Int, options: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge204(arg0.getPointer(memScope).rawValue, pieceIndex, options, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_PrintingPolicy_getProperty(Policy: CXPrintingPolicy?, Property: CXPrintingPolicyProperty): Int { return kniBridge205(Policy.rawValue, Property) } fun clang_PrintingPolicy_setProperty(Policy: CXPrintingPolicy?, Property: CXPrintingPolicyProperty, Value: Int): Unit { return kniBridge206(Policy.rawValue, Property, Value) } fun clang_getCursorPrintingPolicy(arg0: CValue): CXPrintingPolicy? { memScoped { return interpretCPointer(kniBridge207(arg0.getPointer(memScope).rawValue)) } } fun clang_PrintingPolicy_dispose(Policy: CXPrintingPolicy?): Unit { return kniBridge208(Policy.rawValue) } fun clang_getCursorPrettyPrinted(Cursor: CValue, Policy: CXPrintingPolicy?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge209(Cursor.getPointer(memScope).rawValue, Policy.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorDisplayName(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge210(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorReferenced(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge211(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorDefinition(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge212(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_isCursorDefinition(arg0: CValue): Int { memScoped { return kniBridge213(arg0.getPointer(memScope).rawValue) } } fun clang_getCanonicalCursor(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge214(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getObjCSelectorIndex(arg0: CValue): Int { memScoped { return kniBridge215(arg0.getPointer(memScope).rawValue) } } fun clang_Cursor_isDynamicCall(C: CValue): Int { memScoped { return kniBridge216(C.getPointer(memScope).rawValue) } } fun clang_Cursor_getReceiverType(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge217(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getObjCPropertyAttributes(C: CValue, reserved: Int): Int { memScoped { return kniBridge218(C.getPointer(memScope).rawValue, reserved) } } fun clang_Cursor_getObjCPropertyGetterName(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge219(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getObjCPropertySetterName(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge220(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getObjCDeclQualifiers(C: CValue): Int { memScoped { return kniBridge221(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isObjCOptional(C: CValue): Int { memScoped { return kniBridge222(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isVariadic(C: CValue): Int { memScoped { return kniBridge223(C.getPointer(memScope).rawValue) } } fun clang_Cursor_isExternalSymbol(C: CValue, language: CValuesRef?, definedIn: CValuesRef?, isGenerated: CValuesRef?): Int { memScoped { return kniBridge224(C.getPointer(memScope).rawValue, language?.getPointer(memScope).rawValue, definedIn?.getPointer(memScope).rawValue, isGenerated?.getPointer(memScope).rawValue) } } fun clang_Cursor_getCommentRange(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge225(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getRawCommentText(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge226(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getBriefCommentText(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge227(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getMangling(arg0: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge228(arg0.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_getCXXManglings(arg0: CValue): CPointer? { memScoped { return interpretCPointer(kniBridge229(arg0.getPointer(memScope).rawValue)) } } fun clang_Cursor_getObjCManglings(arg0: CValue): CPointer? { memScoped { return interpretCPointer(kniBridge230(arg0.getPointer(memScope).rawValue)) } } fun clang_Cursor_getModule(C: CValue): CXModule? { memScoped { return interpretCPointer(kniBridge231(C.getPointer(memScope).rawValue)) } } fun clang_getModuleForFile(arg0: CXTranslationUnit?, arg1: CXFile?): CXModule? { return interpretCPointer(kniBridge232(arg0.rawValue, arg1.rawValue)) } fun clang_Module_getASTFile(Module: CXModule?): CXFile? { return interpretCPointer(kniBridge233(Module.rawValue)) } fun clang_Module_getParent(Module: CXModule?): CXModule? { return interpretCPointer(kniBridge234(Module.rawValue)) } fun clang_Module_getName(Module: CXModule?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge235(Module.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_Module_getFullName(Module: CXModule?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge236(Module.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_Module_isSystem(Module: CXModule?): Int { return kniBridge237(Module.rawValue) } fun clang_Module_getNumTopLevelHeaders(arg0: CXTranslationUnit?, Module: CXModule?): Int { return kniBridge238(arg0.rawValue, Module.rawValue) } fun clang_Module_getTopLevelHeader(arg0: CXTranslationUnit?, Module: CXModule?, Index: Int): CXFile? { return interpretCPointer(kniBridge239(arg0.rawValue, Module.rawValue, Index)) } fun clang_CXXConstructor_isConvertingConstructor(C: CValue): Int { memScoped { return kniBridge240(C.getPointer(memScope).rawValue) } } fun clang_CXXConstructor_isCopyConstructor(C: CValue): Int { memScoped { return kniBridge241(C.getPointer(memScope).rawValue) } } fun clang_CXXConstructor_isDefaultConstructor(C: CValue): Int { memScoped { return kniBridge242(C.getPointer(memScope).rawValue) } } fun clang_CXXConstructor_isMoveConstructor(C: CValue): Int { memScoped { return kniBridge243(C.getPointer(memScope).rawValue) } } fun clang_CXXField_isMutable(C: CValue): Int { memScoped { return kniBridge244(C.getPointer(memScope).rawValue) } } fun clang_CXXMethod_isDefaulted(C: CValue): Int { memScoped { return kniBridge245(C.getPointer(memScope).rawValue) } } fun clang_CXXMethod_isPureVirtual(C: CValue): Int { memScoped { return kniBridge246(C.getPointer(memScope).rawValue) } } fun clang_CXXMethod_isStatic(C: CValue): Int { memScoped { return kniBridge247(C.getPointer(memScope).rawValue) } } fun clang_CXXMethod_isVirtual(C: CValue): Int { memScoped { return kniBridge248(C.getPointer(memScope).rawValue) } } fun clang_CXXRecord_isAbstract(C: CValue): Int { memScoped { return kniBridge249(C.getPointer(memScope).rawValue) } } fun clang_EnumDecl_isScoped(C: CValue): Int { memScoped { return kniBridge250(C.getPointer(memScope).rawValue) } } fun clang_CXXMethod_isConst(C: CValue): Int { memScoped { return kniBridge251(C.getPointer(memScope).rawValue) } } fun clang_getTemplateCursorKind(C: CValue): CXCursorKind { memScoped { return CXCursorKind.byValue(kniBridge252(C.getPointer(memScope).rawValue)) } } fun clang_getSpecializedCursorTemplate(C: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge253(C.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorReferenceNameRange(C: CValue, NameFlags: Int, PieceIndex: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge254(C.getPointer(memScope).rawValue, NameFlags, PieceIndex, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getToken(TU: CXTranslationUnit?, Location: CValue): CPointer? { memScoped { return interpretCPointer(kniBridge255(TU.rawValue, Location.getPointer(memScope).rawValue)) } } fun clang_getTokenKind(arg0: CValue): CXTokenKind { memScoped { return CXTokenKind.byValue(kniBridge256(arg0.getPointer(memScope).rawValue)) } } fun clang_getTokenSpelling(arg0: CXTranslationUnit?, arg1: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge257(arg0.rawValue, arg1.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTokenLocation(arg0: CXTranslationUnit?, arg1: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge258(arg0.rawValue, arg1.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getTokenExtent(arg0: CXTranslationUnit?, arg1: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge259(arg0.rawValue, arg1.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_tokenize(TU: CXTranslationUnit?, Range: CValue, Tokens: CValuesRef>?, NumTokens: CValuesRef?): Unit { memScoped { return kniBridge260(TU.rawValue, Range.getPointer(memScope).rawValue, Tokens?.getPointer(memScope).rawValue, NumTokens?.getPointer(memScope).rawValue) } } fun clang_annotateTokens(TU: CXTranslationUnit?, Tokens: CValuesRef?, NumTokens: Int, Cursors: CValuesRef?): Unit { memScoped { return kniBridge261(TU.rawValue, Tokens?.getPointer(memScope).rawValue, NumTokens, Cursors?.getPointer(memScope).rawValue) } } fun clang_disposeTokens(TU: CXTranslationUnit?, Tokens: CValuesRef?, NumTokens: Int): Unit { memScoped { return kniBridge262(TU.rawValue, Tokens?.getPointer(memScope).rawValue, NumTokens) } } fun clang_getCursorKindSpelling(Kind: CXCursorKind): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge263(Kind.value, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getDefinitionSpellingAndExtent(arg0: CValue, startBuf: CValuesRef>?, endBuf: CValuesRef>?, startLine: CValuesRef?, startColumn: CValuesRef?, endLine: CValuesRef?, endColumn: CValuesRef?): Unit { memScoped { return kniBridge264(arg0.getPointer(memScope).rawValue, startBuf?.getPointer(memScope).rawValue, endBuf?.getPointer(memScope).rawValue, startLine?.getPointer(memScope).rawValue, startColumn?.getPointer(memScope).rawValue, endLine?.getPointer(memScope).rawValue, endColumn?.getPointer(memScope).rawValue) } } fun clang_enableStackTraces(): Unit { return kniBridge265() } fun clang_executeOnThread(fn: CPointer Unit>>?, user_data: CValuesRef<*>?, stack_size: Int): Unit { memScoped { return kniBridge266(fn.rawValue, user_data?.getPointer(memScope).rawValue, stack_size) } } fun clang_getCompletionChunkKind(completion_string: CXCompletionString?, chunk_number: Int): CXCompletionChunkKind { return CXCompletionChunkKind.byValue(kniBridge267(completion_string.rawValue, chunk_number)) } fun clang_getCompletionChunkText(completion_string: CXCompletionString?, chunk_number: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge268(completion_string.rawValue, chunk_number, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getCompletionChunkCompletionString(completion_string: CXCompletionString?, chunk_number: Int): CXCompletionString? { return interpretCPointer(kniBridge269(completion_string.rawValue, chunk_number)) } fun clang_getNumCompletionChunks(completion_string: CXCompletionString?): Int { return kniBridge270(completion_string.rawValue) } fun clang_getCompletionPriority(completion_string: CXCompletionString?): Int { return kniBridge271(completion_string.rawValue) } fun clang_getCompletionAvailability(completion_string: CXCompletionString?): CXAvailabilityKind { return CXAvailabilityKind.byValue(kniBridge272(completion_string.rawValue)) } fun clang_getCompletionNumAnnotations(completion_string: CXCompletionString?): Int { return kniBridge273(completion_string.rawValue) } fun clang_getCompletionAnnotation(completion_string: CXCompletionString?, annotation_number: Int): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge274(completion_string.rawValue, annotation_number, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getCompletionParent(completion_string: CXCompletionString?, kind: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge275(completion_string.rawValue, kind?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCompletionBriefComment(completion_string: CXCompletionString?): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge276(completion_string.rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_getCursorCompletionString(cursor: CValue): CXCompletionString? { memScoped { return interpretCPointer(kniBridge277(cursor.getPointer(memScope).rawValue)) } } fun clang_getCompletionNumFixIts(results: CValuesRef?, completion_index: Int): Int { memScoped { return kniBridge278(results?.getPointer(memScope).rawValue, completion_index) } } fun clang_getCompletionFixIt(results: CValuesRef?, completion_index: Int, fixit_index: Int, replacement_range: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge279(results?.getPointer(memScope).rawValue, completion_index, fixit_index, replacement_range?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_defaultCodeCompleteOptions(): Int { return kniBridge280() } fun clang_codeCompleteAt(TU: CXTranslationUnit?, complete_filename: String?, complete_line: Int, complete_column: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, options: Int): CPointer? { memScoped { return interpretCPointer(kniBridge281(TU.rawValue, complete_filename?.cstr?.getPointer(memScope).rawValue, complete_line, complete_column, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, options)) } } fun clang_sortCodeCompletionResults(Results: CValuesRef?, NumResults: Int): Unit { memScoped { return kniBridge282(Results?.getPointer(memScope).rawValue, NumResults) } } fun clang_disposeCodeCompleteResults(Results: CValuesRef?): Unit { memScoped { return kniBridge283(Results?.getPointer(memScope).rawValue) } } fun clang_codeCompleteGetNumDiagnostics(Results: CValuesRef?): Int { memScoped { return kniBridge284(Results?.getPointer(memScope).rawValue) } } fun clang_codeCompleteGetDiagnostic(Results: CValuesRef?, Index: Int): CXDiagnostic? { memScoped { return interpretCPointer(kniBridge285(Results?.getPointer(memScope).rawValue, Index)) } } fun clang_codeCompleteGetContexts(Results: CValuesRef?): Long { memScoped { return kniBridge286(Results?.getPointer(memScope).rawValue) } } fun clang_codeCompleteGetContainerKind(Results: CValuesRef?, IsIncomplete: CValuesRef?): CXCursorKind { memScoped { return CXCursorKind.byValue(kniBridge287(Results?.getPointer(memScope).rawValue, IsIncomplete?.getPointer(memScope).rawValue)) } } fun clang_codeCompleteGetContainerUSR(Results: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge288(Results?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_codeCompleteGetObjCSelector(Results: CValuesRef?): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge289(Results?.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getClangVersion(): CValue { val kniRetVal = nativeHeap.alloc() try { kniBridge290(kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } fun clang_toggleCrashRecovery(isEnabled: Int): Unit { return kniBridge291(isEnabled) } fun clang_getInclusions(tu: CXTranslationUnit?, visitor: CXInclusionVisitor?, client_data: CXClientData?): Unit { return kniBridge292(tu.rawValue, visitor.rawValue, client_data.rawValue) } fun clang_Cursor_Evaluate(C: CValue): CXEvalResult? { memScoped { return interpretCPointer(kniBridge293(C.getPointer(memScope).rawValue)) } } fun clang_EvalResult_getKind(E: CXEvalResult?): CXEvalResultKind { return CXEvalResultKind.byValue(kniBridge294(E.rawValue)) } fun clang_EvalResult_getAsInt(E: CXEvalResult?): Int { return kniBridge295(E.rawValue) } fun clang_EvalResult_getAsLongLong(E: CXEvalResult?): Long { return kniBridge296(E.rawValue) } fun clang_EvalResult_isUnsignedInt(E: CXEvalResult?): Int { return kniBridge297(E.rawValue) } fun clang_EvalResult_getAsUnsigned(E: CXEvalResult?): Long { return kniBridge298(E.rawValue) } fun clang_EvalResult_getAsDouble(E: CXEvalResult?): Double { return kniBridge299(E.rawValue) } fun clang_EvalResult_getAsStr(E: CXEvalResult?): CPointer? { return interpretCPointer(kniBridge300(E.rawValue)) } fun clang_EvalResult_dispose(E: CXEvalResult?): Unit { return kniBridge301(E.rawValue) } fun clang_getRemappings(path: String?): CXRemapping? { memScoped { return interpretCPointer(kniBridge302(path?.cstr?.getPointer(memScope).rawValue)) } } fun clang_getRemappingsFromFileList(filePaths: CValuesRef>?, numFiles: Int): CXRemapping? { memScoped { return interpretCPointer(kniBridge303(filePaths?.getPointer(memScope).rawValue, numFiles)) } } fun clang_remap_getNumFiles(arg0: CXRemapping?): Int { return kniBridge304(arg0.rawValue) } fun clang_remap_getFilenames(arg0: CXRemapping?, index: Int, original: CValuesRef?, transformed: CValuesRef?): Unit { memScoped { return kniBridge305(arg0.rawValue, index, original?.getPointer(memScope).rawValue, transformed?.getPointer(memScope).rawValue) } } fun clang_remap_dispose(arg0: CXRemapping?): Unit { return kniBridge306(arg0.rawValue) } fun clang_findReferencesInFile(cursor: CValue, file: CXFile?, visitor: CValue): CXResult { memScoped { return CXResult.byValue(kniBridge307(cursor.getPointer(memScope).rawValue, file.rawValue, visitor.getPointer(memScope).rawValue)) } } fun clang_findIncludesInFile(TU: CXTranslationUnit?, file: CXFile?, visitor: CValue): CXResult { memScoped { return CXResult.byValue(kniBridge308(TU.rawValue, file.rawValue, visitor.getPointer(memScope).rawValue)) } } fun clang_index_isEntityObjCContainerKind(arg0: CXIdxEntityKind): Int { return kniBridge309(arg0.value) } fun clang_index_getObjCContainerDeclInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge310(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getObjCInterfaceDeclInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge311(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getObjCCategoryDeclInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge312(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getObjCProtocolRefListInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge313(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getObjCPropertyDeclInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge314(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getIBOutletCollectionAttrInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge315(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getCXXClassDeclInfo(arg0: CValuesRef?): CPointer? { memScoped { return interpretCPointer(kniBridge316(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_getClientContainer(arg0: CValuesRef?): CXIdxClientContainer? { memScoped { return interpretCPointer(kniBridge317(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_setClientContainer(arg0: CValuesRef?, arg1: CXIdxClientContainer?): Unit { memScoped { return kniBridge318(arg0?.getPointer(memScope).rawValue, arg1.rawValue) } } fun clang_index_getClientEntity(arg0: CValuesRef?): CXIdxClientEntity? { memScoped { return interpretCPointer(kniBridge319(arg0?.getPointer(memScope).rawValue)) } } fun clang_index_setClientEntity(arg0: CValuesRef?, arg1: CXIdxClientEntity?): Unit { memScoped { return kniBridge320(arg0?.getPointer(memScope).rawValue, arg1.rawValue) } } fun clang_IndexAction_create(CIdx: CXIndex?): CXIndexAction? { return interpretCPointer(kniBridge321(CIdx.rawValue)) } fun clang_IndexAction_dispose(arg0: CXIndexAction?): Unit { return kniBridge322(arg0.rawValue) } fun clang_indexSourceFile(arg0: CXIndexAction?, client_data: CXClientData?, index_callbacks: CValuesRef?, index_callbacks_size: Int, index_options: Int, source_filename: String?, command_line_args: CValuesRef>?, num_command_line_args: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, out_TU: CValuesRef?, TU_options: Int): Int { memScoped { return kniBridge323(arg0.rawValue, client_data.rawValue, index_callbacks?.getPointer(memScope).rawValue, index_callbacks_size, index_options, source_filename?.cstr?.getPointer(memScope).rawValue, command_line_args?.getPointer(memScope).rawValue, num_command_line_args, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, out_TU?.getPointer(memScope).rawValue, TU_options) } } fun clang_indexSourceFileFullArgv(arg0: CXIndexAction?, client_data: CXClientData?, index_callbacks: CValuesRef?, index_callbacks_size: Int, index_options: Int, source_filename: String?, command_line_args: CValuesRef>?, num_command_line_args: Int, unsaved_files: CValuesRef?, num_unsaved_files: Int, out_TU: CValuesRef?, TU_options: Int): Int { memScoped { return kniBridge324(arg0.rawValue, client_data.rawValue, index_callbacks?.getPointer(memScope).rawValue, index_callbacks_size, index_options, source_filename?.cstr?.getPointer(memScope).rawValue, command_line_args?.getPointer(memScope).rawValue, num_command_line_args, unsaved_files?.getPointer(memScope).rawValue, num_unsaved_files, out_TU?.getPointer(memScope).rawValue, TU_options) } } fun clang_indexTranslationUnit(arg0: CXIndexAction?, client_data: CXClientData?, index_callbacks: CValuesRef?, index_callbacks_size: Int, index_options: Int, arg5: CXTranslationUnit?): Int { memScoped { return kniBridge325(arg0.rawValue, client_data.rawValue, index_callbacks?.getPointer(memScope).rawValue, index_callbacks_size, index_options, arg5.rawValue) } } fun clang_indexLoc_getFileLocation(loc: CValue, indexFile: CValuesRef?, file: CValuesRef?, line: CValuesRef?, column: CValuesRef?, offset: CValuesRef?): Unit { memScoped { return kniBridge326(loc.getPointer(memScope).rawValue, indexFile?.getPointer(memScope).rawValue, file?.getPointer(memScope).rawValue, line?.getPointer(memScope).rawValue, column?.getPointer(memScope).rawValue, offset?.getPointer(memScope).rawValue) } } fun clang_indexLoc_getCXSourceLocation(loc: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge327(loc.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_visitFields(T: CValue, visitor: CXFieldVisitor?, client_data: CXClientData?): Int { memScoped { return kniBridge328(T.getPointer(memScope).rawValue, visitor.rawValue, client_data.rawValue) } } fun clang_Cursor_getAttributeSpelling(cursor: CValue): CPointer? { memScoped { return interpretCPointer(kniBridge329(cursor.getPointer(memScope).rawValue)) } } fun clang_getDeclTypeAttributes(cursor: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge330(cursor.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getResultTypeAttributes(typeAttributes: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge331(typeAttributes.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_getCursorResultTypeAttributes(cursor: CValue): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge332(cursor.getPointer(memScope).rawValue, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Type_getNullabilityKind(type: CValue, attributes: CValue): CXNullabilityKind { memScoped { return CXNullabilityKind.byValue(kniBridge333(type.getPointer(memScope).rawValue, attributes.getPointer(memScope).rawValue)) } } fun clang_Type_getNumProtocols(type: CValue): Int { memScoped { return kniBridge334(type.getPointer(memScope).rawValue) } } fun clang_Type_getProtocol(type: CValue, index: Int): CValue { memScoped { val kniRetVal = nativeHeap.alloc() try { kniBridge335(type.getPointer(memScope).rawValue, index, kniRetVal.rawPtr) return kniRetVal.readValue() } finally { nativeHeap.free(kniRetVal) } } } fun clang_Cursor_isObjCInitMethod(cursor: CValue): Int { memScoped { return kniBridge336(cursor.getPointer(memScope).rawValue) } } fun clang_Cursor_isObjCReturningRetainedMethod(cursor: CValue): Int { memScoped { return kniBridge337(cursor.getPointer(memScope).rawValue) } } fun clang_Cursor_isObjCConsumingSelfMethod(cursor: CValue): Int { memScoped { return kniBridge338(cursor.getPointer(memScope).rawValue) } } fun clang_isExtVectorType(type: CValue): Int { memScoped { return kniBridge339(type.getPointer(memScope).rawValue) } } val CINDEX_VERSION_MAJOR: Int get() = 0 val CINDEX_VERSION_MINOR: Int get() = 50 val CINDEX_VERSION: Int get() = 50 val CINDEX_VERSION_STRING: String get() = "0.50" typealias CXVirtualFileOverlayVar = CPointerVarOf typealias CXVirtualFileOverlay = CPointer typealias CXModuleMapDescriptorVar = CPointerVarOf typealias CXModuleMapDescriptor = CPointer typealias CXIndexVar = CPointerVarOf typealias CXIndex = COpaquePointer typealias CXTargetInfoVar = CPointerVarOf typealias CXTargetInfo = CPointer typealias CXTranslationUnitVar = CPointerVarOf typealias CXTranslationUnit = CPointer typealias CXClientDataVar = CPointerVarOf typealias CXClientData = COpaquePointer typealias CXFileVar = CPointerVarOf typealias CXFile = COpaquePointer typealias __darwin_time_tVar = LongVarOf<__darwin_time_t> typealias __darwin_time_t = Long typealias time_tVar = LongVarOf typealias time_t = __darwin_time_t typealias __darwin_size_tVar = LongVarOf<__darwin_size_t> typealias __darwin_size_t = Long typealias size_tVar = LongVarOf typealias size_t = __darwin_size_t typealias CXDiagnosticVar = CPointerVarOf typealias CXDiagnostic = COpaquePointer typealias CXDiagnosticSetVar = CPointerVarOf typealias CXDiagnosticSet = COpaquePointer typealias CXCursorSetVar = CPointerVarOf typealias CXCursorSet = CPointer typealias CXCursorVisitorVar = CPointerVarOf typealias CXCursorVisitor = CPointer, CValue, CXClientData?) -> CXChildVisitResult>> typealias CXPrintingPolicyVar = CPointerVarOf typealias CXPrintingPolicy = COpaquePointer typealias CXModuleVar = CPointerVarOf typealias CXModule = COpaquePointer typealias CXCompletionStringVar = CPointerVarOf typealias CXCompletionString = COpaquePointer typealias CXInclusionVisitorVar = CPointerVarOf typealias CXInclusionVisitor = CPointer?, Int, CXClientData?) -> Unit>> typealias CXEvalResultVar = CPointerVarOf typealias CXEvalResult = COpaquePointer typealias CXRemappingVar = CPointerVarOf typealias CXRemapping = COpaquePointer typealias CXIdxClientFileVar = CPointerVarOf typealias CXIdxClientFile = COpaquePointer typealias CXIdxClientEntityVar = CPointerVarOf typealias CXIdxClientEntity = COpaquePointer typealias CXIdxClientContainerVar = CPointerVarOf typealias CXIdxClientContainer = COpaquePointer typealias CXIdxClientASTFileVar = CPointerVarOf typealias CXIdxClientASTFile = COpaquePointer typealias CXIndexActionVar = CPointerVarOf typealias CXIndexAction = COpaquePointer typealias CXFieldVisitorVar = CPointerVarOf typealias CXFieldVisitor = CPointer, CXClientData?) -> CXVisitorResult>> val CXGlobalOpt_None: CXGlobalOptFlags get() = 0 val CXGlobalOpt_ThreadBackgroundPriorityForIndexing: CXGlobalOptFlags get() = 1 val CXGlobalOpt_ThreadBackgroundPriorityForEditing: CXGlobalOptFlags get() = 2 val CXGlobalOpt_ThreadBackgroundPriorityForAll: CXGlobalOptFlags get() = 3 typealias CXGlobalOptFlagsVar = IntVarOf typealias CXGlobalOptFlags = Int val CXDiagnostic_DisplaySourceLocation: CXDiagnosticDisplayOptions get() = 1 val CXDiagnostic_DisplayColumn: CXDiagnosticDisplayOptions get() = 2 val CXDiagnostic_DisplaySourceRanges: CXDiagnosticDisplayOptions get() = 4 val CXDiagnostic_DisplayOption: CXDiagnosticDisplayOptions get() = 8 val CXDiagnostic_DisplayCategoryId: CXDiagnosticDisplayOptions get() = 16 val CXDiagnostic_DisplayCategoryName: CXDiagnosticDisplayOptions get() = 32 typealias CXDiagnosticDisplayOptionsVar = IntVarOf typealias CXDiagnosticDisplayOptions = Int val CXTranslationUnit_None: CXTranslationUnit_Flags get() = 0 val CXTranslationUnit_DetailedPreprocessingRecord: CXTranslationUnit_Flags get() = 1 val CXTranslationUnit_Incomplete: CXTranslationUnit_Flags get() = 2 val CXTranslationUnit_PrecompiledPreamble: CXTranslationUnit_Flags get() = 4 val CXTranslationUnit_CacheCompletionResults: CXTranslationUnit_Flags get() = 8 val CXTranslationUnit_ForSerialization: CXTranslationUnit_Flags get() = 16 val CXTranslationUnit_CXXChainedPCH: CXTranslationUnit_Flags get() = 32 val CXTranslationUnit_SkipFunctionBodies: CXTranslationUnit_Flags get() = 64 val CXTranslationUnit_IncludeBriefCommentsInCodeCompletion: CXTranslationUnit_Flags get() = 128 val CXTranslationUnit_CreatePreambleOnFirstParse: CXTranslationUnit_Flags get() = 256 val CXTranslationUnit_KeepGoing: CXTranslationUnit_Flags get() = 512 val CXTranslationUnit_SingleFileParse: CXTranslationUnit_Flags get() = 1024 val CXTranslationUnit_LimitSkipFunctionBodiesToPreamble: CXTranslationUnit_Flags get() = 2048 val CXTranslationUnit_IncludeAttributedTypes: CXTranslationUnit_Flags get() = 4096 val CXTranslationUnit_VisitImplicitAttributes: CXTranslationUnit_Flags get() = 8192 typealias CXTranslationUnit_FlagsVar = IntVarOf typealias CXTranslationUnit_Flags = Int val CXSaveTranslationUnit_None: CXSaveTranslationUnit_Flags get() = 0 typealias CXSaveTranslationUnit_FlagsVar = IntVarOf typealias CXSaveTranslationUnit_Flags = Int val CXReparse_None: CXReparse_Flags get() = 0 typealias CXReparse_FlagsVar = IntVarOf typealias CXReparse_Flags = Int val CXTLS_None: CXTLSKind get() = 0 val CXTLS_Dynamic: CXTLSKind get() = 1 val CXTLS_Static: CXTLSKind get() = 2 typealias CXTLSKindVar = IntVarOf typealias CXTLSKind = Int val CXTypeNullability_NonNull: CXTypeNullabilityKind get() = 0 val CXTypeNullability_Nullable: CXTypeNullabilityKind get() = 1 val CXTypeNullability_Unspecified: CXTypeNullabilityKind get() = 2 val CXTypeNullability_Invalid: CXTypeNullabilityKind get() = 3 typealias CXTypeNullabilityKindVar = IntVarOf typealias CXTypeNullabilityKind = Int val CXTypeLayoutError_Invalid: CXTypeLayoutError get() = -1 val CXTypeLayoutError_Incomplete: CXTypeLayoutError get() = -2 val CXTypeLayoutError_Dependent: CXTypeLayoutError get() = -3 val CXTypeLayoutError_NotConstantSize: CXTypeLayoutError get() = -4 val CXTypeLayoutError_InvalidFieldName: CXTypeLayoutError get() = -5 typealias CXTypeLayoutErrorVar = IntVarOf typealias CXTypeLayoutError = Int val CXRefQualifier_None: CXRefQualifierKind get() = 0 val CXRefQualifier_LValue: CXRefQualifierKind get() = 1 val CXRefQualifier_RValue: CXRefQualifierKind get() = 2 typealias CXRefQualifierKindVar = IntVarOf typealias CXRefQualifierKind = Int val CXPrintingPolicy_Indentation: CXPrintingPolicyProperty get() = 0 val CXPrintingPolicy_SuppressSpecifiers: CXPrintingPolicyProperty get() = 1 val CXPrintingPolicy_SuppressTagKeyword: CXPrintingPolicyProperty get() = 2 val CXPrintingPolicy_IncludeTagDefinition: CXPrintingPolicyProperty get() = 3 val CXPrintingPolicy_SuppressScope: CXPrintingPolicyProperty get() = 4 val CXPrintingPolicy_SuppressUnwrittenScope: CXPrintingPolicyProperty get() = 5 val CXPrintingPolicy_SuppressInitializers: CXPrintingPolicyProperty get() = 6 val CXPrintingPolicy_ConstantArraySizeAsWritten: CXPrintingPolicyProperty get() = 7 val CXPrintingPolicy_AnonymousTagLocations: CXPrintingPolicyProperty get() = 8 val CXPrintingPolicy_SuppressStrongLifetime: CXPrintingPolicyProperty get() = 9 val CXPrintingPolicy_SuppressLifetimeQualifiers: CXPrintingPolicyProperty get() = 10 val CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors: CXPrintingPolicyProperty get() = 11 val CXPrintingPolicy_Bool: CXPrintingPolicyProperty get() = 12 val CXPrintingPolicy_Restrict: CXPrintingPolicyProperty get() = 13 val CXPrintingPolicy_Alignof: CXPrintingPolicyProperty get() = 14 val CXPrintingPolicy_UnderscoreAlignof: CXPrintingPolicyProperty get() = 15 val CXPrintingPolicy_UseVoidForZeroParams: CXPrintingPolicyProperty get() = 16 val CXPrintingPolicy_TerseOutput: CXPrintingPolicyProperty get() = 17 val CXPrintingPolicy_PolishForDeclaration: CXPrintingPolicyProperty get() = 18 val CXPrintingPolicy_Half: CXPrintingPolicyProperty get() = 19 val CXPrintingPolicy_MSWChar: CXPrintingPolicyProperty get() = 20 val CXPrintingPolicy_IncludeNewlines: CXPrintingPolicyProperty get() = 21 val CXPrintingPolicy_MSVCFormatting: CXPrintingPolicyProperty get() = 22 val CXPrintingPolicy_ConstantsAsWritten: CXPrintingPolicyProperty get() = 23 val CXPrintingPolicy_SuppressImplicitBase: CXPrintingPolicyProperty get() = 24 val CXPrintingPolicy_FullyQualifiedName: CXPrintingPolicyProperty get() = 25 val CXPrintingPolicy_LastProperty: CXPrintingPolicyProperty get() = 25 typealias CXPrintingPolicyPropertyVar = IntVarOf typealias CXPrintingPolicyProperty = Int val CXObjCPropertyAttr_noattr: CXObjCPropertyAttrKind get() = 0 val CXObjCPropertyAttr_readonly: CXObjCPropertyAttrKind get() = 1 val CXObjCPropertyAttr_getter: CXObjCPropertyAttrKind get() = 2 val CXObjCPropertyAttr_assign: CXObjCPropertyAttrKind get() = 4 val CXObjCPropertyAttr_readwrite: CXObjCPropertyAttrKind get() = 8 val CXObjCPropertyAttr_retain: CXObjCPropertyAttrKind get() = 16 val CXObjCPropertyAttr_copy: CXObjCPropertyAttrKind get() = 32 val CXObjCPropertyAttr_nonatomic: CXObjCPropertyAttrKind get() = 64 val CXObjCPropertyAttr_setter: CXObjCPropertyAttrKind get() = 128 val CXObjCPropertyAttr_atomic: CXObjCPropertyAttrKind get() = 256 val CXObjCPropertyAttr_weak: CXObjCPropertyAttrKind get() = 512 val CXObjCPropertyAttr_strong: CXObjCPropertyAttrKind get() = 1024 val CXObjCPropertyAttr_unsafe_unretained: CXObjCPropertyAttrKind get() = 2048 val CXObjCPropertyAttr_class: CXObjCPropertyAttrKind get() = 4096 typealias CXObjCPropertyAttrKindVar = IntVarOf typealias CXObjCPropertyAttrKind = Int val CXObjCDeclQualifier_None: CXObjCDeclQualifierKind get() = 0 val CXObjCDeclQualifier_In: CXObjCDeclQualifierKind get() = 1 val CXObjCDeclQualifier_Inout: CXObjCDeclQualifierKind get() = 2 val CXObjCDeclQualifier_Out: CXObjCDeclQualifierKind get() = 4 val CXObjCDeclQualifier_Bycopy: CXObjCDeclQualifierKind get() = 8 val CXObjCDeclQualifier_Byref: CXObjCDeclQualifierKind get() = 16 val CXObjCDeclQualifier_Oneway: CXObjCDeclQualifierKind get() = 32 typealias CXObjCDeclQualifierKindVar = IntVarOf typealias CXObjCDeclQualifierKind = Int val CXNameRange_WantQualifier: CXNameRefFlags get() = 1 val CXNameRange_WantTemplateArgs: CXNameRefFlags get() = 2 val CXNameRange_WantSinglePiece: CXNameRefFlags get() = 4 typealias CXNameRefFlagsVar = IntVarOf typealias CXNameRefFlags = Int val CXCodeComplete_IncludeMacros: CXCodeComplete_Flags get() = 1 val CXCodeComplete_IncludeCodePatterns: CXCodeComplete_Flags get() = 2 val CXCodeComplete_IncludeBriefComments: CXCodeComplete_Flags get() = 4 val CXCodeComplete_SkipPreamble: CXCodeComplete_Flags get() = 8 val CXCodeComplete_IncludeCompletionsWithFixIts: CXCodeComplete_Flags get() = 16 typealias CXCodeComplete_FlagsVar = IntVarOf typealias CXCodeComplete_Flags = Int val CXCompletionContext_Unexposed: CXCompletionContext get() = 0 val CXCompletionContext_AnyType: CXCompletionContext get() = 1 val CXCompletionContext_AnyValue: CXCompletionContext get() = 2 val CXCompletionContext_ObjCObjectValue: CXCompletionContext get() = 4 val CXCompletionContext_ObjCSelectorValue: CXCompletionContext get() = 8 val CXCompletionContext_CXXClassTypeValue: CXCompletionContext get() = 16 val CXCompletionContext_DotMemberAccess: CXCompletionContext get() = 32 val CXCompletionContext_ArrowMemberAccess: CXCompletionContext get() = 64 val CXCompletionContext_ObjCPropertyAccess: CXCompletionContext get() = 128 val CXCompletionContext_EnumTag: CXCompletionContext get() = 256 val CXCompletionContext_UnionTag: CXCompletionContext get() = 512 val CXCompletionContext_StructTag: CXCompletionContext get() = 1024 val CXCompletionContext_ClassTag: CXCompletionContext get() = 2048 val CXCompletionContext_Namespace: CXCompletionContext get() = 4096 val CXCompletionContext_NestedNameSpecifier: CXCompletionContext get() = 8192 val CXCompletionContext_ObjCInterface: CXCompletionContext get() = 16384 val CXCompletionContext_ObjCProtocol: CXCompletionContext get() = 32768 val CXCompletionContext_ObjCCategory: CXCompletionContext get() = 65536 val CXCompletionContext_ObjCInstanceMessage: CXCompletionContext get() = 131072 val CXCompletionContext_ObjCClassMessage: CXCompletionContext get() = 262144 val CXCompletionContext_ObjCSelectorName: CXCompletionContext get() = 524288 val CXCompletionContext_MacroName: CXCompletionContext get() = 1048576 val CXCompletionContext_NaturalLanguage: CXCompletionContext get() = 2097152 val CXCompletionContext_IncludedFile: CXCompletionContext get() = 4194304 val CXCompletionContext_Unknown: CXCompletionContext get() = 8388607 typealias CXCompletionContextVar = IntVarOf typealias CXCompletionContext = Int val CXIdxEntityLang_None: CXIdxEntityLanguage get() = 0 val CXIdxEntityLang_C: CXIdxEntityLanguage get() = 1 val CXIdxEntityLang_ObjC: CXIdxEntityLanguage get() = 2 val CXIdxEntityLang_CXX: CXIdxEntityLanguage get() = 3 val CXIdxEntityLang_Swift: CXIdxEntityLanguage get() = 4 typealias CXIdxEntityLanguageVar = IntVarOf typealias CXIdxEntityLanguage = Int val CXIdxEntity_NonTemplate: CXIdxEntityCXXTemplateKind get() = 0 val CXIdxEntity_Template: CXIdxEntityCXXTemplateKind get() = 1 val CXIdxEntity_TemplatePartialSpecialization: CXIdxEntityCXXTemplateKind get() = 2 val CXIdxEntity_TemplateSpecialization: CXIdxEntityCXXTemplateKind get() = 3 typealias CXIdxEntityCXXTemplateKindVar = IntVarOf typealias CXIdxEntityCXXTemplateKind = Int val CXIdxAttr_Unexposed: CXIdxAttrKind get() = 0 val CXIdxAttr_IBAction: CXIdxAttrKind get() = 1 val CXIdxAttr_IBOutlet: CXIdxAttrKind get() = 2 val CXIdxAttr_IBOutletCollection: CXIdxAttrKind get() = 3 typealias CXIdxAttrKindVar = IntVarOf typealias CXIdxAttrKind = Int val CXIdxDeclFlag_Skipped: CXIdxDeclInfoFlags get() = 1 typealias CXIdxDeclInfoFlagsVar = IntVarOf typealias CXIdxDeclInfoFlags = Int val CXIdxObjCContainer_ForwardRef: CXIdxObjCContainerKind get() = 0 val CXIdxObjCContainer_Interface: CXIdxObjCContainerKind get() = 1 val CXIdxObjCContainer_Implementation: CXIdxObjCContainerKind get() = 2 typealias CXIdxObjCContainerKindVar = IntVarOf typealias CXIdxObjCContainerKind = Int val CXIdxEntityRef_Direct: CXIdxEntityRefKind get() = 1 val CXIdxEntityRef_Implicit: CXIdxEntityRefKind get() = 2 typealias CXIdxEntityRefKindVar = IntVarOf typealias CXIdxEntityRefKind = Int val CXSymbolRole_None: CXSymbolRole get() = 0 val CXSymbolRole_Declaration: CXSymbolRole get() = 1 val CXSymbolRole_Definition: CXSymbolRole get() = 2 val CXSymbolRole_Reference: CXSymbolRole get() = 4 val CXSymbolRole_Read: CXSymbolRole get() = 8 val CXSymbolRole_Write: CXSymbolRole get() = 16 val CXSymbolRole_Call: CXSymbolRole get() = 32 val CXSymbolRole_Dynamic: CXSymbolRole get() = 64 val CXSymbolRole_AddressOf: CXSymbolRole get() = 128 val CXSymbolRole_Implicit: CXSymbolRole get() = 256 typealias CXSymbolRoleVar = IntVarOf typealias CXSymbolRole = Int val CXIndexOpt_None: CXIndexOptFlags get() = 0 val CXIndexOpt_SuppressRedundantRefs: CXIndexOptFlags get() = 1 val CXIndexOpt_IndexFunctionLocalSymbols: CXIndexOptFlags get() = 2 val CXIndexOpt_IndexImplicitTemplateInstantiations: CXIndexOptFlags get() = 4 val CXIndexOpt_SuppressWarnings: CXIndexOptFlags get() = 8 val CXIndexOpt_SkipParsedBodiesInSession: CXIndexOptFlags get() = 16 typealias CXIndexOptFlagsVar = IntVarOf typealias CXIndexOptFlags = Int private external fun kniBridge0(p0: NativePtr): NativePtr private external fun kniBridge1(p0: NativePtr): Unit private external fun kniBridge2(p0: NativePtr): Unit private external fun kniBridge3(): Long private external fun kniBridge4(p0: Int): NativePtr private external fun kniBridge5(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge6(p0: NativePtr, p1: Int): Int private external fun kniBridge7(p0: NativePtr, p1: Int, p2: NativePtr, p3: NativePtr): Int private external fun kniBridge8(p0: NativePtr): Unit private external fun kniBridge9(p0: NativePtr): Unit private external fun kniBridge10(p0: Int): NativePtr private external fun kniBridge11(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge12(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge13(p0: NativePtr, p1: Int, p2: NativePtr, p3: NativePtr): Int private external fun kniBridge14(p0: NativePtr): Unit private external fun kniBridge15(p0: Int, p1: Int): NativePtr private external fun kniBridge16(p0: NativePtr): Unit private external fun kniBridge17(p0: NativePtr, p1: Int): Unit private external fun kniBridge18(p0: NativePtr): Int private external fun kniBridge19(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge20(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge21(p0: NativePtr): Long private external fun kniBridge22(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge23(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge24(p0: NativePtr, p1: NativePtr): NativePtr private external fun kniBridge25(p0: NativePtr, p1: NativePtr, p2: NativePtr): NativePtr private external fun kniBridge26(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge27(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge28(p0: NativePtr): Unit private external fun kniBridge29(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge30(p0: NativePtr, p1: NativePtr, p2: Int, p3: Int, p4: NativePtr): Unit private external fun kniBridge31(p0: NativePtr, p1: NativePtr, p2: Int, p3: NativePtr): Unit private external fun kniBridge32(p0: NativePtr): Int private external fun kniBridge33(p0: NativePtr): Int private external fun kniBridge34(p0: NativePtr): Unit private external fun kniBridge35(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge36(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge37(p0: NativePtr): Int private external fun kniBridge38(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr): Unit private external fun kniBridge39(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr): Unit private external fun kniBridge40(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr): Unit private external fun kniBridge41(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr): Unit private external fun kniBridge42(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr): Unit private external fun kniBridge43(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge44(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge45(p0: NativePtr, p1: NativePtr): NativePtr private external fun kniBridge46(p0: NativePtr): NativePtr private external fun kniBridge47(p0: NativePtr): Unit private external fun kniBridge48(p0: NativePtr): Int private external fun kniBridge49(p0: NativePtr, p1: Int): NativePtr private external fun kniBridge50(p0: NativePtr, p1: NativePtr, p2: NativePtr): NativePtr private external fun kniBridge51(p0: NativePtr): Unit private external fun kniBridge52(p0: NativePtr): NativePtr private external fun kniBridge53(p0: NativePtr): Int private external fun kniBridge54(p0: NativePtr, p1: Int): NativePtr private external fun kniBridge55(p0: NativePtr): NativePtr private external fun kniBridge56(p0: NativePtr): Unit private external fun kniBridge57(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge58(): Int private external fun kniBridge59(p0: NativePtr): Int private external fun kniBridge60(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge61(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge62(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge63(p0: NativePtr): Int private external fun kniBridge64(p0: Int, p1: NativePtr): Unit private external fun kniBridge65(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge66(p0: NativePtr): Int private external fun kniBridge67(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge68(p0: NativePtr): Int private external fun kniBridge69(p0: NativePtr, p1: Int, p2: NativePtr, p3: NativePtr): Unit private external fun kniBridge70(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge71(p0: NativePtr, p1: NativePtr, p2: Int, p3: NativePtr, p4: Int, p5: NativePtr): NativePtr private external fun kniBridge72(p0: NativePtr, p1: NativePtr): NativePtr private external fun kniBridge73(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge74(): Int private external fun kniBridge75(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: NativePtr, p5: Int, p6: Int): NativePtr private external fun kniBridge76(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: NativePtr, p5: Int, p6: Int, p7: NativePtr): Int private external fun kniBridge77(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: NativePtr, p5: Int, p6: Int, p7: NativePtr): Int private external fun kniBridge78(p0: NativePtr): Int private external fun kniBridge79(p0: NativePtr, p1: NativePtr, p2: Int): Int private external fun kniBridge80(p0: NativePtr): Int private external fun kniBridge81(p0: NativePtr): Unit private external fun kniBridge82(p0: NativePtr): Int private external fun kniBridge83(p0: NativePtr, p1: Int, p2: NativePtr, p3: Int): Int private external fun kniBridge84(p0: Int): NativePtr private external fun kniBridge85(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge86(p0: NativePtr): Unit private external fun kniBridge87(p0: NativePtr): NativePtr private external fun kniBridge88(p0: NativePtr): Unit private external fun kniBridge89(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge90(p0: NativePtr): Int private external fun kniBridge91(p0: NativePtr): Unit private external fun kniBridge92(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge93(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge94(p0: NativePtr): Int private external fun kniBridge95(p0: NativePtr): Int private external fun kniBridge96(p0: NativePtr): Int private external fun kniBridge97(p0: Int): Int private external fun kniBridge98(p0: NativePtr): Int private external fun kniBridge99(p0: Int): Int private external fun kniBridge100(p0: Int): Int private external fun kniBridge101(p0: Int): Int private external fun kniBridge102(p0: Int): Int private external fun kniBridge103(p0: NativePtr): Int private external fun kniBridge104(p0: Int): Int private external fun kniBridge105(p0: Int): Int private external fun kniBridge106(p0: Int): Int private external fun kniBridge107(p0: Int): Int private external fun kniBridge108(p0: NativePtr): Int private external fun kniBridge109(p0: NativePtr): Int private external fun kniBridge110(p0: NativePtr): Int private external fun kniBridge111(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr, p5: NativePtr, p6: Int): Int private external fun kniBridge112(p0: NativePtr): Unit private external fun kniBridge113(p0: NativePtr): Int private external fun kniBridge114(p0: NativePtr): Int private external fun kniBridge115(p0: NativePtr): NativePtr private external fun kniBridge116(): NativePtr private external fun kniBridge117(p0: NativePtr): Unit private external fun kniBridge118(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge119(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge120(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge121(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge122(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge123(p0: NativePtr): Unit private external fun kniBridge124(p0: NativePtr): NativePtr private external fun kniBridge125(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge126(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge127(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge128(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge129(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge130(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge131(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge132(p0: NativePtr): Long private external fun kniBridge133(p0: NativePtr): Long private external fun kniBridge134(p0: NativePtr): Int private external fun kniBridge135(p0: NativePtr): Int private external fun kniBridge136(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge137(p0: NativePtr): Int private external fun kniBridge138(p0: NativePtr, p1: Int): Int private external fun kniBridge139(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge140(p0: NativePtr, p1: Int): Long private external fun kniBridge141(p0: NativePtr, p1: Int): Long private external fun kniBridge142(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge143(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge144(p0: NativePtr): Int private external fun kniBridge145(p0: NativePtr): Int private external fun kniBridge146(p0: NativePtr): Int private external fun kniBridge147(p0: NativePtr): Int private external fun kniBridge148(p0: NativePtr): Int private external fun kniBridge149(p0: NativePtr): Int private external fun kniBridge150(p0: NativePtr): Int private external fun kniBridge151(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge152(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge153(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge154(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge155(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge156(p0: Int, p1: NativePtr): Unit private external fun kniBridge157(p0: NativePtr): Int private external fun kniBridge158(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge159(p0: NativePtr): Int private external fun kniBridge160(p0: NativePtr): Int private external fun kniBridge161(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge162(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge163(p0: NativePtr): Int private external fun kniBridge164(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge165(p0: NativePtr): Int private external fun kniBridge166(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge167(p0: NativePtr): Int private external fun kniBridge168(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge169(p0: NativePtr): Int private external fun kniBridge170(p0: NativePtr): Int private external fun kniBridge171(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge172(p0: NativePtr): Long private external fun kniBridge173(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge174(p0: NativePtr): Long private external fun kniBridge175(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge176(p0: NativePtr): Int private external fun kniBridge177(p0: NativePtr): Int private external fun kniBridge178(p0: NativePtr): Long private external fun kniBridge179(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge180(p0: NativePtr): Long private external fun kniBridge181(p0: NativePtr, p1: NativePtr): Long private external fun kniBridge182(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge183(p0: NativePtr): Long private external fun kniBridge184(p0: NativePtr): Int private external fun kniBridge185(p0: NativePtr): Int private external fun kniBridge186(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge187(p0: NativePtr): Int private external fun kniBridge188(p0: NativePtr): Int private external fun kniBridge189(p0: NativePtr): Int private external fun kniBridge190(p0: NativePtr): Int private external fun kniBridge191(p0: NativePtr): Int private external fun kniBridge192(p0: NativePtr): Int private external fun kniBridge193(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge194(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge195(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge196(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge197(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge198(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge199(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge200(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge201(p0: NativePtr, p1: Int, p2: NativePtr, p3: NativePtr): Unit private external fun kniBridge202(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge203(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge204(p0: NativePtr, p1: Int, p2: Int, p3: NativePtr): Unit private external fun kniBridge205(p0: NativePtr, p1: Int): Int private external fun kniBridge206(p0: NativePtr, p1: Int, p2: Int): Unit private external fun kniBridge207(p0: NativePtr): NativePtr private external fun kniBridge208(p0: NativePtr): Unit private external fun kniBridge209(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge210(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge211(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge212(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge213(p0: NativePtr): Int private external fun kniBridge214(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge215(p0: NativePtr): Int private external fun kniBridge216(p0: NativePtr): Int private external fun kniBridge217(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge218(p0: NativePtr, p1: Int): Int private external fun kniBridge219(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge220(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge221(p0: NativePtr): Int private external fun kniBridge222(p0: NativePtr): Int private external fun kniBridge223(p0: NativePtr): Int private external fun kniBridge224(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr): Int private external fun kniBridge225(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge226(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge227(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge228(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge229(p0: NativePtr): NativePtr private external fun kniBridge230(p0: NativePtr): NativePtr private external fun kniBridge231(p0: NativePtr): NativePtr private external fun kniBridge232(p0: NativePtr, p1: NativePtr): NativePtr private external fun kniBridge233(p0: NativePtr): NativePtr private external fun kniBridge234(p0: NativePtr): NativePtr private external fun kniBridge235(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge236(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge237(p0: NativePtr): Int private external fun kniBridge238(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge239(p0: NativePtr, p1: NativePtr, p2: Int): NativePtr private external fun kniBridge240(p0: NativePtr): Int private external fun kniBridge241(p0: NativePtr): Int private external fun kniBridge242(p0: NativePtr): Int private external fun kniBridge243(p0: NativePtr): Int private external fun kniBridge244(p0: NativePtr): Int private external fun kniBridge245(p0: NativePtr): Int private external fun kniBridge246(p0: NativePtr): Int private external fun kniBridge247(p0: NativePtr): Int private external fun kniBridge248(p0: NativePtr): Int private external fun kniBridge249(p0: NativePtr): Int private external fun kniBridge250(p0: NativePtr): Int private external fun kniBridge251(p0: NativePtr): Int private external fun kniBridge252(p0: NativePtr): Int private external fun kniBridge253(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge254(p0: NativePtr, p1: Int, p2: Int, p3: NativePtr): Unit private external fun kniBridge255(p0: NativePtr, p1: NativePtr): NativePtr private external fun kniBridge256(p0: NativePtr): Int private external fun kniBridge257(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge258(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge259(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge260(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr): Unit private external fun kniBridge261(p0: NativePtr, p1: NativePtr, p2: Int, p3: NativePtr): Unit private external fun kniBridge262(p0: NativePtr, p1: NativePtr, p2: Int): Unit private external fun kniBridge263(p0: Int, p1: NativePtr): Unit private external fun kniBridge264(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr, p5: NativePtr, p6: NativePtr): Unit private external fun kniBridge265(): Unit private external fun kniBridge266(p0: NativePtr, p1: NativePtr, p2: Int): Unit private external fun kniBridge267(p0: NativePtr, p1: Int): Int private external fun kniBridge268(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge269(p0: NativePtr, p1: Int): NativePtr private external fun kniBridge270(p0: NativePtr): Int private external fun kniBridge271(p0: NativePtr): Int private external fun kniBridge272(p0: NativePtr): Int private external fun kniBridge273(p0: NativePtr): Int private external fun kniBridge274(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge275(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge276(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge277(p0: NativePtr): NativePtr private external fun kniBridge278(p0: NativePtr, p1: Int): Int private external fun kniBridge279(p0: NativePtr, p1: Int, p2: Int, p3: NativePtr, p4: NativePtr): Unit private external fun kniBridge280(): Int private external fun kniBridge281(p0: NativePtr, p1: NativePtr, p2: Int, p3: Int, p4: NativePtr, p5: Int, p6: Int): NativePtr private external fun kniBridge282(p0: NativePtr, p1: Int): Unit private external fun kniBridge283(p0: NativePtr): Unit private external fun kniBridge284(p0: NativePtr): Int private external fun kniBridge285(p0: NativePtr, p1: Int): NativePtr private external fun kniBridge286(p0: NativePtr): Long private external fun kniBridge287(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge288(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge289(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge290(p0: NativePtr): Unit private external fun kniBridge291(p0: Int): Unit private external fun kniBridge292(p0: NativePtr, p1: NativePtr, p2: NativePtr): Unit private external fun kniBridge293(p0: NativePtr): NativePtr private external fun kniBridge294(p0: NativePtr): Int private external fun kniBridge295(p0: NativePtr): Int private external fun kniBridge296(p0: NativePtr): Long private external fun kniBridge297(p0: NativePtr): Int private external fun kniBridge298(p0: NativePtr): Long private external fun kniBridge299(p0: NativePtr): Double private external fun kniBridge300(p0: NativePtr): NativePtr private external fun kniBridge301(p0: NativePtr): Unit private external fun kniBridge302(p0: NativePtr): NativePtr private external fun kniBridge303(p0: NativePtr, p1: Int): NativePtr private external fun kniBridge304(p0: NativePtr): Int private external fun kniBridge305(p0: NativePtr, p1: Int, p2: NativePtr, p3: NativePtr): Unit private external fun kniBridge306(p0: NativePtr): Unit private external fun kniBridge307(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge308(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge309(p0: Int): Int private external fun kniBridge310(p0: NativePtr): NativePtr private external fun kniBridge311(p0: NativePtr): NativePtr private external fun kniBridge312(p0: NativePtr): NativePtr private external fun kniBridge313(p0: NativePtr): NativePtr private external fun kniBridge314(p0: NativePtr): NativePtr private external fun kniBridge315(p0: NativePtr): NativePtr private external fun kniBridge316(p0: NativePtr): NativePtr private external fun kniBridge317(p0: NativePtr): NativePtr private external fun kniBridge318(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge319(p0: NativePtr): NativePtr private external fun kniBridge320(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge321(p0: NativePtr): NativePtr private external fun kniBridge322(p0: NativePtr): Unit private external fun kniBridge323(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: Int, p5: NativePtr, p6: NativePtr, p7: Int, p8: NativePtr, p9: Int, p10: NativePtr, p11: Int): Int private external fun kniBridge324(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: Int, p5: NativePtr, p6: NativePtr, p7: Int, p8: NativePtr, p9: Int, p10: NativePtr, p11: Int): Int private external fun kniBridge325(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: Int, p4: Int, p5: NativePtr): Int private external fun kniBridge326(p0: NativePtr, p1: NativePtr, p2: NativePtr, p3: NativePtr, p4: NativePtr, p5: NativePtr): Unit private external fun kniBridge327(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge328(p0: NativePtr, p1: NativePtr, p2: NativePtr): Int private external fun kniBridge329(p0: NativePtr): NativePtr private external fun kniBridge330(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge331(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge332(p0: NativePtr, p1: NativePtr): Unit private external fun kniBridge333(p0: NativePtr, p1: NativePtr): Int private external fun kniBridge334(p0: NativePtr): Int private external fun kniBridge335(p0: NativePtr, p1: Int, p2: NativePtr): Unit private external fun kniBridge336(p0: NativePtr): Int private external fun kniBridge337(p0: NativePtr): Int private external fun kniBridge338(p0: NativePtr): Int private external fun kniBridge339(p0: NativePtr): Int private val loadLibrary = loadKonanLibrary("clangstubs") ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/HeaderToIdMapper.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.indexer import java.io.File class HeaderToIdMapper(sysRoot: String) { private val headerPathToId = mutableMapOf() private val sysRoot = File(sysRoot).canonicalFile.toPath() internal fun getHeaderId(filePath: String) = headerPathToId.getOrPut(filePath) { val path = File(filePath).canonicalFile.toPath() val headerIdValue = if (path.startsWith(sysRoot)) { val relative = sysRoot.relativize(path) relative.toString() } else { headerContentsHash(filePath) } HeaderId(headerIdValue) } } ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Indexer.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.indexer import clang.* import clang.CXIdxEntityKind.* import clang.CXTypeKind.* import kotlinx.cinterop.* private class StructDeclImpl(spelling: String, override val location: Location) : StructDecl(spelling) { override var def: StructDefImpl? = null } private class StructDefImpl( size: Long, align: Int, decl: StructDecl, override val kind: Kind ) : StructDef( size, align, decl ) { override val members = mutableListOf() } private class EnumDefImpl(spelling: String, type: Type, override val location: Location) : EnumDef(spelling, type) { override val constants = mutableListOf() } private interface ObjCContainerImpl { val protocols: MutableList val methods: MutableList val properties: MutableList } private class ObjCProtocolImpl( name: String, override val location: Location, override val isForwardDeclaration: Boolean ) : ObjCProtocol(name), ObjCContainerImpl { override val protocols = mutableListOf() override val methods = mutableListOf() override val properties = mutableListOf() } private class ObjCClassImpl( name: String, override val location: Location, override val isForwardDeclaration: Boolean, override val binaryName: String? ) : ObjCClass(name), ObjCContainerImpl { override val protocols = mutableListOf() override val methods = mutableListOf() override val properties = mutableListOf() override var baseClass: ObjCClass? = null } private class ObjCCategoryImpl( name: String, clazz: ObjCClass ) : ObjCCategory(name, clazz), ObjCContainerImpl { override val protocols = mutableListOf() override val methods = mutableListOf() override val properties = mutableListOf() } internal class NativeIndexImpl(val library: NativeLibrary, val verbose: Boolean = false) : NativeIndex() { private sealed class DeclarationID { data class USR(val usr: String) : DeclarationID() object VaList : DeclarationID() object VaListTag : DeclarationID() object BuiltinVaList : DeclarationID() object Protocol : DeclarationID() } private inner class TypeDeclarationRegistry { private val all = mutableMapOf() val included = mutableListOf() inline fun getOrPut(cursor: CValue, create: () -> D) = getOrPut(cursor, create, configure = {}) inline fun getOrPut(cursor: CValue, create: () -> D, configure: (D) -> Unit): D { val key = getDeclarationId(cursor) return all.getOrElse(key) { val value = create() all[key] = value val headerId = getHeaderId(getContainingFile(cursor)) if (!library.headerExclusionPolicy.excludeAll(headerId)) { // This declaration is used, and thus should be included: included.add(value) } configure(value) value } } } internal fun getHeaderId(file: CXFile?): HeaderId = getHeaderId(this.library, file) private fun getLocation(cursor: CValue): Location { val headerId = getHeaderId(getContainingFile(cursor)) return Location(headerId) } override val structs: List get() = structRegistry.included private val structRegistry = TypeDeclarationRegistry() override val enums: List get() = enumRegistry.included private val enumRegistry = TypeDeclarationRegistry() override val objCClasses: List get() = objCClassRegistry.included private val objCClassRegistry = TypeDeclarationRegistry() override val objCProtocols: List get() = objCProtocolRegistry.included private val objCProtocolRegistry = TypeDeclarationRegistry() override val objCCategories: Collection get() = objCCategoryById.values private val objCCategoryById = mutableMapOf() override val typedefs get() = typedefRegistry.included private val typedefRegistry = TypeDeclarationRegistry() private val functionById = mutableMapOf() override val functions: Collection get() = functionById.values override val macroConstants = mutableListOf() override val wrappedMacros = mutableListOf() private val globalById = mutableMapOf() override val globals: Collection get() = globalById.values override lateinit var includedHeaders: List private fun log(message: String) { if (verbose) { println(message) } } private fun getDeclarationId(cursor: CValue): DeclarationID { val usr = clang_getCursorUSR(cursor).convertAndDispose() if (usr == "") { val kind = cursor.kind val spelling = getCursorSpelling(cursor) return when (kind to spelling) { CXCursorKind.CXCursor_StructDecl to "__va_list_tag" -> DeclarationID.VaListTag CXCursorKind.CXCursor_StructDecl to "__va_list" -> DeclarationID.VaList CXCursorKind.CXCursor_TypedefDecl to "__builtin_va_list" -> DeclarationID.BuiltinVaList CXCursorKind.CXCursor_ObjCInterfaceDecl to "Protocol" -> DeclarationID.Protocol else -> error(kind to spelling) } } return DeclarationID.USR(usr) } private fun getStructDeclAt( cursor: CValue ): StructDeclImpl = structRegistry.getOrPut(cursor, { createStructDecl(cursor) }) { decl -> val definitionCursor = clang_getCursorDefinition(cursor) if (clang_Cursor_isNull(definitionCursor) == 0) { assert(clang_isCursorDefinition(definitionCursor) != 0) createStructDef(decl, cursor) } } private fun createStructDecl(cursor: CValue): StructDeclImpl { val cursorType = clang_getCursorType(cursor) val typeSpelling = clang_getTypeSpelling(cursorType).convertAndDispose() return StructDeclImpl(typeSpelling, getLocation(cursor)) } private fun createStructDef(structDecl: StructDeclImpl, cursor: CValue) { val type = clang_getCursorType(cursor) val fields = mutableListOf() addDeclaredFields(fields, type, type) val size = clang_Type_getSizeOf(type) val align = clang_Type_getAlignOf(type).toInt() val structDef = StructDefImpl( size, align, structDecl, when (cursor.kind) { CXCursorKind.CXCursor_UnionDecl -> StructDef.Kind.UNION CXCursorKind.CXCursor_StructDecl -> StructDef.Kind.STRUCT else -> error(cursor.kind) } ) structDef.members += fields structDecl.def = structDef } private fun addDeclaredFields(result: MutableList, structType: CValue, containerType: CValue) { getFields(containerType).forEach { fieldCursor -> val name = getCursorSpelling(fieldCursor) if (name.isNotEmpty()) { val fieldType = convertCursorType(fieldCursor) val offset = clang_Type_getOffsetOf(structType, name) val member = if (offset < 0) { IncompleteField(name, fieldType) } else if (clang_Cursor_isBitField(fieldCursor) == 0) { val canonicalFieldType = clang_getCanonicalType(clang_getCursorType(fieldCursor)) Field( name, fieldType, offset, clang_Type_getSizeOf(canonicalFieldType), clang_Type_getAlignOf(canonicalFieldType) ) } else { val size = clang_getFieldDeclBitWidth(fieldCursor) BitField(name, fieldType, offset, size) } result.add(member) } else { // Unnamed field. val fieldType = clang_getCursorType(fieldCursor) when (fieldType.kind) { CXTypeKind.CXType_Record -> { // Unnamed struct fields also contribute their fields: addDeclaredFields(result, structType, fieldType) } else -> { // Nothing. } } } } } private fun getEnumDefAt(cursor: CValue): EnumDefImpl { if (clang_isCursorDefinition(cursor) == 0) { val definitionCursor = clang_getCursorDefinition(cursor) if (clang_isCursorDefinition(definitionCursor) != 0) { return getEnumDefAt(definitionCursor) } else { TODO("support enum forward declarations: " + clang_getTypeSpelling(clang_getCursorType(cursor)).convertAndDispose()) } } return enumRegistry.getOrPut(cursor) { val cursorType = clang_getCursorType(cursor) val typeSpelling = clang_getTypeSpelling(cursorType).convertAndDispose() val baseType = convertType(clang_getEnumDeclIntegerType(cursor)) val enumDef = EnumDefImpl(typeSpelling, baseType, getLocation(cursor)) visitChildren(cursor) { childCursor, _ -> if (clang_getCursorKind(childCursor) == CXCursorKind.CXCursor_EnumConstantDecl) { val name = clang_getCursorSpelling(childCursor).convertAndDispose() val value = clang_getEnumConstantDeclValue(childCursor) val constant = EnumConstant(name, value, isExplicitlyDefined = childCursor.hasExpressionChild()) enumDef.constants.add(constant) } CXChildVisitResult.CXChildVisit_Continue } enumDef } } private fun getObjCCategoryClassCursor(cursor: CValue): CValue { assert(cursor.kind == CXCursorKind.CXCursor_ObjCCategoryDecl) var classRef: CValue? = null visitChildren(cursor) { child, _ -> if (child.kind == CXCursorKind.CXCursor_ObjCClassRef) { classRef = child CXChildVisitResult.CXChildVisit_Break } else { CXChildVisitResult.CXChildVisit_Continue } } return clang_getCursorReferenced(classRef!!).apply { assert(this.kind == CXCursorKind.CXCursor_ObjCInterfaceDecl) } } private fun isObjCInterfaceDeclForward(cursor: CValue): Boolean { assert(cursor.kind == CXCursorKind.CXCursor_ObjCInterfaceDecl) { cursor.kind } // It is forward declaration <=> the first child is reference to it: var result = false visitChildren(cursor) { child, _ -> result = (child.kind == CXCursorKind.CXCursor_ObjCClassRef && clang_getCursorReferenced(child) == cursor) CXChildVisitResult.CXChildVisit_Break } return result } private fun getObjCClassAt(cursor: CValue): ObjCClassImpl { assert(cursor.kind == CXCursorKind.CXCursor_ObjCInterfaceDecl) { cursor.kind } val name = clang_getCursorDisplayName(cursor).convertAndDispose() if (isObjCInterfaceDeclForward(cursor)) { return objCClassRegistry.getOrPut(cursor) { ObjCClassImpl(name, getLocation(cursor), isForwardDeclaration = true, binaryName = null) } } return objCClassRegistry.getOrPut(cursor, { ObjCClassImpl(name, getLocation(cursor), isForwardDeclaration = false, binaryName = getObjCBinaryName(cursor).takeIf { it != name }) }) { addChildrenToObjCContainer(cursor, it) } } private fun getObjCProtocolAt(cursor: CValue): ObjCProtocolImpl { assert(cursor.kind == CXCursorKind.CXCursor_ObjCProtocolDecl) { cursor.kind } val name = clang_getCursorDisplayName(cursor).convertAndDispose() if (clang_isCursorDefinition(cursor) == 0) { val definition = clang_getCursorDefinition(cursor) return if (clang_isCursorDefinition(definition) != 0) { getObjCProtocolAt(definition) } else { objCProtocolRegistry.getOrPut(cursor) { ObjCProtocolImpl(name, getLocation(cursor), isForwardDeclaration = true) } } } return objCProtocolRegistry.getOrPut(cursor, { ObjCProtocolImpl(name, getLocation(cursor), isForwardDeclaration = false) }) { addChildrenToObjCContainer(cursor, it) } } private fun getObjCBinaryName(cursor: CValue): String { val prefix = "_OBJC_CLASS_\$_" val symbolName = clang_Cursor_getObjCManglings(cursor)!!.convertAndDispose() .single { it.startsWith(prefix) } return symbolName.substring(prefix.length) } private fun getObjCCategoryAt(cursor: CValue): ObjCCategoryImpl? { assert(cursor.kind == CXCursorKind.CXCursor_ObjCCategoryDecl) { cursor.kind } val classCursor = getObjCCategoryClassCursor(cursor) if (!isAvailable(classCursor)) return null val name = clang_getCursorDisplayName(cursor).convertAndDispose() val declarationId = getDeclarationId(cursor) return objCCategoryById.getOrPut(declarationId) { val clazz = getObjCClassAt(classCursor) val category = ObjCCategoryImpl(name, clazz) addChildrenToObjCContainer(cursor, category) category } } private fun addChildrenToObjCContainer(cursor: CValue, result: ObjCContainerImpl) { visitChildren(cursor) { child, _ -> when (child.kind) { CXCursorKind.CXCursor_ObjCSuperClassRef -> { assert(cursor.kind == CXCursorKind.CXCursor_ObjCInterfaceDecl) result as ObjCClassImpl assert(result.baseClass == null) result.baseClass = getObjCClassAt(clang_getCursorReferenced(child)) } CXCursorKind.CXCursor_ObjCProtocolRef -> { val protocol = getObjCProtocolAt(clang_getCursorReferenced(child)) if (protocol !in result.protocols) { result.protocols.add(protocol) } } CXCursorKind.CXCursor_ObjCClassMethodDecl, CXCursorKind.CXCursor_ObjCInstanceMethodDecl -> { getObjCMethod(child)?.let { method -> result.methods.removeAll { method.replaces(it) } result.methods.add(method) } } else -> { } } CXChildVisitResult.CXChildVisit_Continue } } fun getTypedef(type: CValue): Type { val declCursor = clang_getTypeDeclaration(type) val name = getCursorSpelling(declCursor) val underlying = convertType(clang_getTypedefDeclUnderlyingType(declCursor)) if (underlying == UnsupportedType) return underlying if (clang_getCursorLexicalParent(declCursor).kind != CXCursorKind.CXCursor_TranslationUnit) { // Objective-C type parameters are represented as non-top-level typedefs. // Erase for now: return underlying } if (library.language == Language.OBJECTIVE_C) { if (name == "BOOL" || name == "Boolean") { assert(clang_Type_getSizeOf(type) == 1L) return ObjCBoolType } if (underlying is ObjCPointer && (name == "Class" || name == "id") || underlying is PointerType && name == "SEL") { // Ignore implicit Objective-C typedefs: return underlying } } if ((underlying is RecordType && underlying.decl.spelling.split(' ').last() == name) || (underlying is EnumType && underlying.def.spelling.split(' ').last() == name)) { // special handling for: // typedef struct { ... } name; // typedef enum { ... } name; // FIXME: implement better solution return underlying } val typedefDef = typedefRegistry.getOrPut(declCursor) { TypedefDef(underlying, name, getLocation(declCursor)) } return Typedef(typedefDef) } private fun convertCursorType(cursor: CValue) = convertType(clang_getCursorType(cursor), clang_getDeclTypeAttributes(cursor)) private inline fun objCType(supplier: () -> ObjCPointer) = when (library.language) { Language.C -> UnsupportedType Language.OBJECTIVE_C -> supplier() } // We omit `const` qualifier for IntegerType and FloatingType to make `CBridgeGen` simpler. // See KT-28102. private fun String.dropConstQualifier() = substringAfterLast("const ") private fun convertUnqualifiedPrimitiveType(type: CValue): Type = when (type.kind) { CXTypeKind.CXType_Char_U, CXTypeKind.CXType_Char_S -> { assert(type.getSize() == 1L) CharType } CXTypeKind.CXType_UChar, CXTypeKind.CXType_UShort, CXTypeKind.CXType_UInt, CXTypeKind.CXType_ULong, CXTypeKind.CXType_ULongLong -> IntegerType( size = type.getSize().toInt(), isSigned = false, spelling = clang_getTypeSpelling(type).convertAndDispose().dropConstQualifier() ) CXTypeKind.CXType_SChar, CXTypeKind.CXType_Short, CXTypeKind.CXType_Int, CXTypeKind.CXType_Long, CXTypeKind.CXType_LongLong -> IntegerType( size = type.getSize().toInt(), isSigned = true, spelling = clang_getTypeSpelling(type).convertAndDispose().dropConstQualifier() ) CXTypeKind.CXType_Float, CXTypeKind.CXType_Double -> FloatingType( size = type.getSize().toInt(), spelling = clang_getTypeSpelling(type).convertAndDispose().dropConstQualifier() ) CXType_Unexposed -> { // FIXME Remove this cludge for libclang version >= 9 (CINDEX_VERSION > 55) if (clang_isExtVectorType(type) != 0) { val size = clang_Type_getSizeOf(type) if (size == 16L) { // ExtVector elementType and elementCount are ignored for now but stubs are still needed for // CXType_Vector compatibility. Incoming clang v9 provide CXType_ExtVector compatible with CXType_Vector val spelling = "__attribute__((__vector_size__($size))) float" VectorType(FloatingType(4, "float"), 4, spelling) } else { UnsupportedType } } else { UnsupportedType } } CXType_Vector -> { val elementCXType = clang_getElementType(type) val elementType = convertType(elementCXType) val size = clang_Type_getSizeOf(type) val elemSize = clang_Type_getSizeOf(elementCXType) val elementCount = clang_getNumElements(type) assert(size >= elemSize * elementCount && size % elemSize == 0L) // Spelling example: `__attribute__((__vector_size__(4 * sizeof(float)))) const float` // Re-generate spelling removing constness and typedefs to limit number of variants for bridge generator // Supposed to be the same (i.e. natively compatible) as clang_getTypeSpelling(type) aka type.name val spelling = "__attribute__((__vector_size__($size))) ${clang_getCanonicalType(elementCXType).name}" if (size == 16L) { VectorType(elementType, elementCount.toInt(), spelling) } else { UnsupportedType } } CXTypeKind.CXType_Bool -> CBoolType else -> UnsupportedType } fun convertType(type: CValue, typeAttributes: CValue? = null): Type { val primitiveType = convertUnqualifiedPrimitiveType(type) if (primitiveType != UnsupportedType) { return primitiveType } val kind = type.kind return when (kind) { CXType_Elaborated -> convertType(clang_Type_getNamedType(type)) CXType_Unexposed -> { if (clang_getResultType(type).kind != CXTypeKind.CXType_Invalid) { convertFunctionType(type) } else { val canonicalType = clang_getCanonicalType(type) if (canonicalType.kind != CXType_Unexposed) { convertType(canonicalType) } else { UnsupportedType } } } CXType_Void -> VoidType CXType_Typedef -> { val declCursor = clang_getTypeDeclaration(type) val declSpelling = getCursorSpelling(declCursor) val underlying = convertType(clang_getTypedefDeclUnderlyingType(declCursor)) when { declSpelling == "instancetype" && underlying is ObjCPointer -> ObjCInstanceType(getNullability(type, typeAttributes)) else -> getTypedef(type) } } CXType_Record -> RecordType(getStructDeclAt(clang_getTypeDeclaration(type))) CXType_Enum -> EnumType(getEnumDefAt(clang_getTypeDeclaration(type))) CXType_Pointer -> { val pointeeType = clang_getPointeeType(type) val pointeeIsConst = (clang_isConstQualifiedType(clang_getCanonicalType(pointeeType)) != 0) val convertedPointeeType = convertType(pointeeType) PointerType( if (convertedPointeeType == UnsupportedType) VoidType else convertedPointeeType, pointeeIsConst = pointeeIsConst ) } CXType_ConstantArray -> { val elementType = convertType(clang_getArrayElementType(type)) val length = clang_getArraySize(type) ConstArrayType(elementType, length) } CXType_IncompleteArray -> { val elementType = convertType(clang_getArrayElementType(type)) IncompleteArrayType(elementType) } CXType_VariableArray -> { val elementType = convertType(clang_getArrayElementType(type)) VariableArrayType(elementType) } CXType_FunctionProto -> { convertFunctionType(type) } CXType_ObjCObjectPointer -> objCType { val declaration = clang_getTypeDeclaration(clang_getPointeeType(type)) val declarationKind = declaration.kind val nullability = getNullability(type, typeAttributes) when (declarationKind) { CXCursorKind.CXCursor_NoDeclFound -> ObjCIdType(nullability, getProtocols(type)) CXCursorKind.CXCursor_ObjCInterfaceDecl -> ObjCObjectPointer(getObjCClassAt(declaration), nullability, getProtocols(type)) CXCursorKind.CXCursor_TypedefDecl -> // typedef to Objective-C class itself, e.g. `typedef NSObject Object;`, // (as opposed to `typedef NSObject* Object;`). // Note: it is not yet represented as Kotlin `typealias`. ObjCObjectPointer( getObjCClassAt(getTypedefUnderlyingObjCClass(declaration)), nullability, getProtocols(type) ) else -> TODO("${declarationKind.toString()} ${clang_getTypeSpelling(type).convertAndDispose()}") } } CXType_ObjCId -> objCType { ObjCIdType(getNullability(type, typeAttributes), getProtocols(type)) } CXType_ObjCClass -> objCType { ObjCClassPointer(getNullability(type, typeAttributes), getProtocols(type)) } CXType_ObjCSel -> PointerType(VoidType) CXType_BlockPointer -> objCType { convertBlockPointerType(type, typeAttributes) } else -> UnsupportedType } } private tailrec fun getTypedefUnderlyingObjCClass(typedefDecl: CValue): CValue { assert(typedefDecl.kind == CXCursorKind.CXCursor_TypedefDecl) val underlyingType = clang_getTypedefDeclUnderlyingType(typedefDecl) val underlyingTypeDecl = clang_getTypeDeclaration(underlyingType) return when (underlyingTypeDecl.kind) { CXCursorKind.CXCursor_TypedefDecl -> getTypedefUnderlyingObjCClass(underlyingTypeDecl) CXCursorKind.CXCursor_ObjCInterfaceDecl -> underlyingTypeDecl else -> TODO( """typedef = ${getCursorSpelling(typedefDecl)} |underlying decl kind = ${underlyingTypeDecl.kind} |underlying = ${clang_getTypeSpelling(underlyingType).convertAndDispose()}""".trimMargin() ) } } private fun getNullability( type: CValue, typeAttributes: CValue? ): ObjCPointer.Nullability { if (typeAttributes == null) return ObjCPointer.Nullability.Unspecified return when (clang_Type_getNullabilityKind(type, typeAttributes)) { CXNullabilityKind.CXNullabilityKind_Nullable -> ObjCPointer.Nullability.Nullable CXNullabilityKind.CXNullabilityKind_NonNull -> ObjCPointer.Nullability.NonNull CXNullabilityKind.CXNullabilityKind_Unspecified -> ObjCPointer.Nullability.Unspecified } } private fun getProtocols(type: CValue): List { val num = clang_Type_getNumProtocols(type) return (0 until num).map { index -> getObjCProtocolAt(clang_Type_getProtocol(type, index)) } } private fun convertFunctionType(type: CValue): Type { val kind = type.kind assert(kind == CXType_Unexposed || kind == CXType_FunctionProto || kind == CXType_FunctionNoProto) { kind } if (clang_isFunctionTypeVariadic(type) != 0) { return VoidType // make this function pointer opaque. } else { val returnType = convertType(clang_getResultType(type)) val numArgs = clang_getNumArgTypes(type) // Ignore functions with long signatures since we have no basic class for such functional types in the stdlib. // TODO: Remove this limitation when functional types with long signatures are supported. if (numArgs > 22) { log("Warning: cannot generate a Kotlin functional type for a pointer to a function with more than 22 parameters. " + "An opaque pointer will be used instead.") return VoidType } val paramTypes = (0..numArgs - 1).map { convertType(clang_getArgType(type, it)) } return if (returnType == UnsupportedType || paramTypes.any { it == UnsupportedType }) { VoidType } else { FunctionType(paramTypes, returnType) } } } private fun convertBlockPointerType(type: CValue, typeAttributes: CValue?): ObjCPointer { val kind = type.kind assert(kind == CXType_BlockPointer) val pointee = clang_getPointeeType(type) val nullability = getNullability(type, typeAttributes) // TODO: also use nullability attributes of parameters and return value. val functionType = convertFunctionType(pointee) as? FunctionType ?: return ObjCIdType(nullability, protocols = emptyList()) return ObjCBlockPointer(nullability, functionType.parameterTypes, functionType.returnType) } private val TARGET_ATTRIBUTE = "__target__" private fun isSuitableFunction(cursor: CValue): Boolean { if (!isAvailable(cursor)) return false // If function is specific for certain target, ignore that, as we may be // unable to generate machine code for bridge from the bitcode. return !functionHasTargetAttribute(cursor) } private fun functionHasTargetAttribute(cursor: CValue): Boolean { // TODO: this must be implemented with hasAttribute(), but hasAttribute() // works for Mac hosts only so far. var result = false visitChildren(cursor) { child, _ -> if (isTargetAttribute(child)) { result = true CXChildVisitResult.CXChildVisit_Break } else { CXChildVisitResult.CXChildVisit_Continue } } return result } private fun isTargetAttribute(cursor: CValue): Boolean = clang_isAttribute(cursor.kind) != 0 && getExtentFirstToken(cursor) == TARGET_ATTRIBUTE private fun getExtentFirstToken(cursor: CValue) = getToken(clang_Cursor_getTranslationUnit(cursor)!!, clang_getRangeStart(clang_getCursorExtent(cursor))) // TODO: implement with clang_getToken after updating libclang. private fun getToken(translationUnit: CXTranslationUnit, location: CValue): String? = memScoped { val range = clang_getRange(location, location) // Seems to work. val tokensVar = alloc>() val numTokensVar = alloc() clang_tokenize(translationUnit, range, tokensVar.ptr, numTokensVar.ptr) val numTokens = numTokensVar.value val tokens = tokensVar.value ?: return null try { when (numTokens) { 0 -> null 1 -> clang_getTokenSpelling(translationUnit, tokens[0].readValue()).convertAndDispose() else -> error("Unexpected number of tokens: $numTokens") } } finally { clang_disposeTokens(translationUnit, tokens, numTokens) } } fun indexDeclaration(info: CXIdxDeclInfo): Unit { val cursor = info.cursor.readValue() val entityInfo = info.entityInfo!!.pointed val entityName = entityInfo.name?.toKString() val kind = entityInfo.kind if (!this.library.includesDeclaration(cursor)) { return } when (kind) { CXIdxEntity_Struct, CXIdxEntity_Union -> { if (entityName == null) { // Skip anonymous struct. // (It gets included anyway if used as a named field type). } else { getStructDeclAt(cursor) } } CXIdxEntity_Typedef -> { val type = clang_getCursorType(cursor) getTypedef(type) } CXIdxEntity_Function -> { if (isSuitableFunction(cursor)) { functionById.getOrPut(getDeclarationId(cursor)) { getFunction(cursor) } } } CXIdxEntity_Enum -> { getEnumDefAt(cursor) } CXIdxEntity_Variable -> { if (info.semanticContainer!!.pointed.cursor.kind == CXCursorKind.CXCursor_TranslationUnit) { // Top-level variable. globalById.getOrPut(getDeclarationId(cursor)) { GlobalDecl( name = entityName!!, type = convertCursorType(cursor), isConst = clang_isConstQualifiedType(clang_getCursorType(cursor)) != 0 ) } } } CXIdxEntity_ObjCClass -> if (cursor.kind != CXCursorKind.CXCursor_ObjCClassRef /* not a forward declaration */) { indexObjCClass(cursor) } CXIdxEntity_ObjCCategory -> { if (isAvailable(cursor)) { getObjCCategoryAt(cursor) } } CXIdxEntity_ObjCProtocol -> if (cursor.kind != CXCursorKind.CXCursor_ObjCProtocolRef /* not a forward declaration */) { indexObjCProtocol(cursor) } CXIdxEntity_ObjCProperty -> { val container = clang_getCursorSemanticParent(cursor) if (isAvailable(cursor) && isAvailable(container)) { val propertyInfo = clang_index_getObjCPropertyDeclInfo(info.ptr)!!.pointed val getter = getObjCMethod(propertyInfo.getter!!.pointed.cursor.readValue()) val setter = propertyInfo.setter?.let { getObjCMethod(it.pointed.cursor.readValue()) } if (getter != null) { val property = ObjCProperty(entityName!!, getter, setter) val objCContainer: ObjCContainerImpl? = when (container.kind) { CXCursorKind.CXCursor_ObjCCategoryDecl -> getObjCCategoryAt(container) CXCursorKind.CXCursor_ObjCInterfaceDecl -> getObjCClassAt(container) CXCursorKind.CXCursor_ObjCProtocolDecl -> getObjCProtocolAt(container) else -> error(container.kind) } if (objCContainer != null) { objCContainer.properties.removeAll { property.replaces(it) } objCContainer.properties.add(property) } } } } else -> { // Ignore declaration. } } } fun indexObjCClass(cursor: CValue) { if (isAvailable(cursor)) { getObjCClassAt(cursor) } } fun indexObjCProtocol(cursor: CValue) { if (isAvailable(cursor)) { getObjCProtocolAt(cursor) } } private fun getFunction(cursor: CValue): FunctionDecl { val name = clang_getCursorSpelling(cursor).convertAndDispose() val returnType = convertType(clang_getCursorResultType(cursor), clang_getCursorResultTypeAttributes(cursor)) val parameters = getFunctionParameters(cursor) val binaryName = when (library.language) { Language.C, Language.OBJECTIVE_C -> clang_Cursor_getMangling(cursor).convertAndDispose() } val definitionCursor = clang_getCursorDefinition(cursor) val isDefined = (clang_Cursor_isNull(definitionCursor) == 0) val isVararg = clang_Cursor_isVariadic(cursor) != 0 return FunctionDecl(name, parameters, returnType, binaryName, isDefined, isVararg) } private fun getObjCMethod(cursor: CValue): ObjCMethod? { if (!isAvailable(cursor)) { return null } val selector = clang_getCursorDisplayName(cursor).convertAndDispose() // Ignore some very special methods: when (selector) { "dealloc", "retain", "release", "autorelease", "retainCount", "self" -> return null } val encoding = clang_getDeclObjCTypeEncoding(cursor).convertAndDispose() val returnType = convertType(clang_getCursorResultType(cursor), clang_getCursorResultTypeAttributes(cursor)) val parameters = getFunctionParameters(cursor) if (returnType == UnsupportedType || parameters.any { it.type == UnsupportedType }) { return null // TODO: make a more universal fix. } val isClass = when (cursor.kind) { CXCursorKind.CXCursor_ObjCClassMethodDecl -> true CXCursorKind.CXCursor_ObjCInstanceMethodDecl -> false else -> error(cursor.kind) } return ObjCMethod( selector, encoding, parameters, returnType, isVariadic = clang_Cursor_isVariadic(cursor) != 0, isClass = isClass, nsConsumesSelf = clang_Cursor_isObjCConsumingSelfMethod(cursor) != 0, nsReturnsRetained = clang_Cursor_isObjCReturningRetainedMethod(cursor) != 0, isOptional = (clang_Cursor_isObjCOptional(cursor) != 0), isInit = (clang_Cursor_isObjCInitMethod(cursor) != 0), isExplicitlyDesignatedInitializer = hasAttribute(cursor, OBJC_DESGINATED_INITIALIZER) ) } // TODO: unavailable declarations should be imported as deprecated. private fun isAvailable(cursor: CValue): Boolean = when (clang_getCursorAvailability(cursor)) { CXAvailabilityKind.CXAvailability_Available, CXAvailabilityKind.CXAvailability_Deprecated -> true CXAvailabilityKind.CXAvailability_NotAvailable, CXAvailabilityKind.CXAvailability_NotAccessible -> false } private fun getFunctionParameters(cursor: CValue): List { val argNum = clang_Cursor_getNumArguments(cursor) val args = (0..argNum - 1).map { val argCursor = clang_Cursor_getArgument(cursor, it) val argName = getCursorSpelling(argCursor) val type = convertCursorType(argCursor) Parameter(argName, type, nsConsumed = hasAttribute(argCursor, NS_CONSUMED)) } return args } private val NS_CONSUMED = "ns_consumed" private val OBJC_DESGINATED_INITIALIZER = "objc_designated_initializer" private fun hasAttribute(cursor: CValue, name: String): Boolean { var result = false visitChildren(cursor) { child, _ -> if (clang_isAttribute(child.kind) != 0 && clang_Cursor_getAttributeSpelling(child)?.toKString() == name) { result = true CXChildVisitResult.CXChildVisit_Break } else { CXChildVisitResult.CXChildVisit_Continue } } return result } } fun buildNativeIndexImpl(library: NativeLibrary, verbose: Boolean): IndexerResult { val result = NativeIndexImpl(library, verbose) val compilation = indexDeclarations(result) return IndexerResult(result, compilation) } private fun indexDeclarations(nativeIndex: NativeIndexImpl): CompilationWithPCH { withIndex { index -> val translationUnit = nativeIndex.library.copyWithArgsForPCH().parse( index, options = CXTranslationUnit_DetailedPreprocessingRecord or CXTranslationUnit_ForSerialization ) try { translationUnit.ensureNoCompileErrors() val compilation = nativeIndex.library.withPrecompiledHeader(translationUnit) val headers = getFilteredHeaders(nativeIndex, index, translationUnit) nativeIndex.includedHeaders = headers.map { nativeIndex.getHeaderId(it) } indexTranslationUnit(index, translationUnit, 0, object : Indexer { override fun indexDeclaration(info: CXIdxDeclInfo) { val file = memScoped { val fileVar = alloc() clang_indexLoc_getFileLocation(info.loc.readValue(), null, fileVar.ptr, null, null, null) fileVar.value } if (file in headers) { nativeIndex.indexDeclaration(info) } } }) visitChildren(clang_getTranslationUnitCursor(translationUnit)) { cursor, _ -> val file = getContainingFile(cursor) if (file in headers && nativeIndex.library.includesDeclaration(cursor)) { when (cursor.kind) { CXCursorKind.CXCursor_ObjCInterfaceDecl -> nativeIndex.indexObjCClass(cursor) CXCursorKind.CXCursor_ObjCProtocolDecl -> nativeIndex.indexObjCProtocol(cursor) else -> {} } } CXChildVisitResult.CXChildVisit_Continue } findMacros(nativeIndex, compilation, translationUnit, headers) return compilation } finally { clang_disposeTranslationUnit(translationUnit) } } } ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/MacroConstants.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.indexer import clang.* import kotlinx.cinterop.* import java.io.File /** * Finds all "macro constants" and registers them as [NativeIndex.constants] in given index. */ internal fun findMacros( nativeIndex: NativeIndexImpl, compilation: CompilationWithPCH, translationUnit: CXTranslationUnit, headers: Set ) { val names = collectMacroNames(nativeIndex, translationUnit, headers) // TODO: apply user-defined filters. val macros = expandMacros(compilation, names, typeConverter = { nativeIndex.convertType(it) }) macros.filterIsInstanceTo(nativeIndex.macroConstants) macros.filterIsInstanceTo(nativeIndex.wrappedMacros) } private typealias TypeConverter = (CValue) -> Type /** * For each name expands the macro with this name declared in the library, * checking if it gets expanded to a constant expression. * * Note: in the worst case this method parses the code against the library a lot of times, * so it requires library headers precompiled to significantly speed up the parsing and avoid visiting headers' AST. * * @return the list of constants. */ private fun expandMacros( library: CompilationWithPCH, names: List, typeConverter: TypeConverter ): List { withIndex(excludeDeclarationsFromPCH = true) { index -> val sourceFile = library.createTempSource() val compilerArgs = library.compilerArgs.toMutableList() // We disable implicit function declaration to filter out cases when a macro is expanded as a function // or function-like construction (e.g. #define FOO throw()) but such a function is undeclared. compilerArgs += "-Werror=implicit-function-declaration" // Ensure libclang reports all errors: compilerArgs += "-ferror-limit=0" val translationUnit = parseTranslationUnit(index, sourceFile, compilerArgs, options = 0) try { val nameToMacroDef = mutableMapOf() val unprocessedMacros = names.toMutableList() // Note: will be slow for a library with a lot of macros having unbalanced '{'. TODO: Optimize this case too. while (unprocessedMacros.isNotEmpty()) { val processedMacros = tryExpandMacros(library, translationUnit, sourceFile, unprocessedMacros, typeConverter) unprocessedMacros -= (processedMacros.keys + unprocessedMacros.first()) // Note: removing first macro should not have any effect, doing this to ensure the loop is finite. processedMacros.forEach { (name, macroDef) -> if (macroDef != null) nameToMacroDef[name] = macroDef } } return names.mapNotNull { nameToMacroDef[it] } } finally { clang_disposeTranslationUnit(translationUnit) } } } /** * Tries to expand macros [names] defined in [library]. * Returns the map of successfully processed macros with resulting constant as a value * or `null` if the result is not a constant (expression). * * As a side effect, modifies the [sourceFile] and reparses the [translationUnit]. */ private fun tryExpandMacros( library: CompilationWithPCH, translationUnit: CXTranslationUnit, sourceFile: File, names: List, typeConverter: TypeConverter ): Map { reparseWithCodeSnippets(library, translationUnit, sourceFile, names) val macrosWithErrorsInSnippetFunctionHeader = mutableSetOf() val macrosWithErrorsInSnippetFunctionBody = mutableSetOf() val preambleSize = library.preambleLines.size translationUnit.getErrorLineNumbers().map { it - preambleSize - 1 }.forEach { lineNumber -> val index = lineNumber / CODE_SNIPPET_LINES_NUMBER if (index >= 0 && index < names.size) { when (lineNumber % CODE_SNIPPET_LINES_NUMBER) { 0 -> macrosWithErrorsInSnippetFunctionHeader += names[index] 1 -> macrosWithErrorsInSnippetFunctionBody += names[index] else -> {} } } } val result = mutableMapOf() visitChildren(translationUnit) { cursor, _ -> if (cursor.kind == CXCursorKind.CXCursor_FunctionDecl) { val functionName = getCursorSpelling(cursor) if (functionName.startsWith(CODE_SNIPPET_FUNCTION_NAME_PREFIX)) { val macroName = functionName.removePrefix(CODE_SNIPPET_FUNCTION_NAME_PREFIX) if (macroName in macrosWithErrorsInSnippetFunctionHeader) { // Code snippet is likely affected by previous macros' snippets, skip it for now. } else { result[macroName] = if (macroName in macrosWithErrorsInSnippetFunctionBody) { // Code snippet is likely unaffected by previous ones but parsed with its own errors, // so suppose macro is processed successfully as non-expression: null } else { processCodeSnippet(cursor, macroName, typeConverter) } } } } CXChildVisitResult.CXChildVisit_Continue } return result } private const val CODE_SNIPPET_LINES_NUMBER = 3 private const val CODE_SNIPPET_FUNCTION_NAME_PREFIX = "kni_indexer_function_" /** * Adds code snippets to be then processed with [processCodeSnippet] to the [sourceFile] * and reparses the [translationUnit]. * * - If a code snippet allows extracting the constant value using libclang API, we'll add a [ConstantDef] in the * native index and generate a Kotlin constant for it. * - If the expression type can be inferred by libclang, we'll add a [WrappedMacroDef] in the native index and * generate a bridge for this macro. * - Otherwise the macro is skipped. */ private fun reparseWithCodeSnippets(library: CompilationWithPCH, translationUnit: CXTranslationUnit, sourceFile: File, names: List) { // TODO: consider using CXUnsavedFile instead of writing the modified file to OS file system. sourceFile.bufferedWriter().use { writer -> writer.appendPreamble(library) names.forEach { name -> val codeSnippetLines = when (library.language) { Language.C, Language.OBJECTIVE_C -> listOf("void $CODE_SNIPPET_FUNCTION_NAME_PREFIX$name() {", " __auto_type KNI_INDEXER_VARIABLE_$name = $name;", "}") } assert(codeSnippetLines.size == CODE_SNIPPET_LINES_NUMBER) codeSnippetLines.forEach { writer.appendLine(it) } } } clang_reparseTranslationUnit(translationUnit, 0, null, 0) } /** * Checks that [functionCursor] is parsed exactly as expected for the code appended by [reparseWithCodeSnippets], * and returns the constant on success. */ private fun processCodeSnippet( functionCursor: CValue, name: String, typeConverter: TypeConverter ): MacroDef? { val kindsToSkip = setOf(CXCursorKind.CXCursor_CompoundStmt) var state = VisitorState.EXPECT_NODES_TO_SKIP var evalResultOrNull: CXEvalResult? = null var typeOrNull: Type? = null val visitor: CursorVisitor = { cursor, _ -> val kind = cursor.kind when { state == VisitorState.EXPECT_VARIABLE && kind == CXCursorKind.CXCursor_VarDecl -> { evalResultOrNull = clang_Cursor_Evaluate(cursor) state = VisitorState.EXPECT_VARIABLE_VALUE CXChildVisitResult.CXChildVisit_Recurse } state == VisitorState.EXPECT_VARIABLE_VALUE && clang_isExpression(kind) != 0 -> { typeOrNull = typeConverter(clang_getCursorType(cursor)) state = VisitorState.EXPECT_END CXChildVisitResult.CXChildVisit_Continue } // Skip auxiliary elements. state == VisitorState.EXPECT_NODES_TO_SKIP && kind in kindsToSkip -> CXChildVisitResult.CXChildVisit_Recurse state == VisitorState.EXPECT_NODES_TO_SKIP && kind == CXCursorKind.CXCursor_DeclStmt -> { state = VisitorState.EXPECT_VARIABLE CXChildVisitResult.CXChildVisit_Recurse } else -> { state = VisitorState.INVALID CXChildVisitResult.CXChildVisit_Break } } } try { visitChildren(functionCursor, visitor) if (state != VisitorState.EXPECT_END) { return null } val type = typeOrNull!! return if (evalResultOrNull == null) { // The macro cannot be evaluated as a constant so we will wrap it in a bridge. when(type.unwrapTypedefs()) { is PrimitiveType, is PointerType, is ObjCPointer -> WrappedMacroDef(name, type) else -> null } } else { // Otherwise we can evaluate the expression and create a Kotlin constant for it. val evalResult = evalResultOrNull!! val evalResultKind = clang_EvalResult_getKind(evalResult) when (evalResultKind) { CXEvalResultKind.CXEval_Int -> IntegerConstantDef(name, type, clang_EvalResult_getAsLongLong(evalResult)) CXEvalResultKind.CXEval_Float -> FloatingConstantDef(name, type, clang_EvalResult_getAsDouble(evalResult)) CXEvalResultKind.CXEval_CFStr, CXEvalResultKind.CXEval_ObjCStrLiteral, CXEvalResultKind.CXEval_StrLiteral -> if (evalResultKind == CXEvalResultKind.CXEval_StrLiteral && !type.canonicalIsPointerToChar()) { // libclang doesn't seem to support wide string literals properly in this API; // thus disable wide literals here: null } else { StringConstantDef(name, type, clang_EvalResult_getAsStr(evalResult)!!.toKString()) } CXEvalResultKind.CXEval_Other, CXEvalResultKind.CXEval_UnExposed -> null } } } finally { evalResultOrNull?.let { clang_EvalResult_dispose(it) } } } enum class VisitorState { EXPECT_NODES_TO_SKIP, EXPECT_VARIABLE, EXPECT_VARIABLE_VALUE, EXPECT_END, INVALID } private fun collectMacroNames(nativeIndex: NativeIndexImpl, translationUnit: CXTranslationUnit, headers: Set): List { val result = mutableSetOf() visitChildren(translationUnit) { cursor, _ -> val file = memScoped { val fileVar = alloc() clang_getFileLocation(clang_getCursorLocation(cursor), fileVar.ptr, null, null, null) fileVar.value } if (cursor.kind == CXCursorKind.CXCursor_MacroDefinition && nativeIndex.library.includesDeclaration(cursor) && file != null && // Builtin macros mostly seem to be useless. file in headers && canMacroBeConstant(cursor)) { val spelling = getCursorSpelling(cursor) result.add(spelling) } CXChildVisitResult.CXChildVisit_Continue } return result.toList() } private fun canMacroBeConstant(cursor: CValue): Boolean { if (clang_Cursor_isMacroFunctionLike(cursor) != 0) { return false } // TODO: check number of tokens and filter out empty definitions; // Requires updating to 3.9.1 due to https://bugs.llvm.org//show_bug.cgi?id=9069 return true } ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/ModuleSupport.kt ================================================ package org.jetbrains.kotlin.native.interop.indexer import clang.* import kotlinx.cinterop.* import java.nio.file.Files data class ModulesInfo(val topLevelHeaders: List, val ownHeaders: Set) fun getModulesInfo(compilation: Compilation, modules: List): ModulesInfo { if (modules.isEmpty()) return ModulesInfo(emptyList(), emptySet()) withIndex { index -> ModularCompilation(compilation).use { val modulesASTFiles = getModulesASTFiles(index, it, modules) return buildModulesInfo(index, modules, modulesASTFiles) } } } private fun buildModulesInfo(index: CXIndex, modules: List, modulesASTFiles: List): ModulesInfo { val ownHeaders = mutableSetOf() val topLevelHeaders = linkedSetOf() modulesASTFiles.forEach { val moduleTranslationUnit = clang_createTranslationUnit(index, it)!! try { val modulesHeaders = getModulesHeaders(index, moduleTranslationUnit, modules.toSet(), topLevelHeaders) modulesHeaders.mapTo(ownHeaders) { it.canonicalPath } } finally { clang_disposeTranslationUnit(moduleTranslationUnit) } } return ModulesInfo(topLevelHeaders.toList(), ownHeaders) } internal open class ModularCompilation(compilation: Compilation): Compilation by compilation, Disposable { companion object { private const val moduleCacheFlag = "-fmodules-cache-path=" } private val moduleCacheDirectory = if (compilation.compilerArgs.none { it.startsWith(moduleCacheFlag) }) { Files.createTempDirectory("ModuleCache").toAbsolutePath().toFile() } else { null } override val compilerArgs: List = compilation.compilerArgs + listOfNotNull("-fmodules", moduleCacheDirectory?.let { "$moduleCacheFlag${it}" }) override fun dispose() { moduleCacheDirectory?.deleteRecursively() } } private fun getModulesASTFiles(index: CXIndex, compilation: ModularCompilation, modules: List): List { val compilationWithImports = compilation.copy( additionalPreambleLines = modules.map { "@import $it;" } + compilation.additionalPreambleLines ) val result = linkedSetOf() val translationUnit = compilationWithImports.parse( index, options = CXTranslationUnit_DetailedPreprocessingRecord ) try { translationUnit.ensureNoCompileErrors() indexTranslationUnit(index, translationUnit, 0, object : Indexer { override fun importedASTFile(info: CXIdxImportedASTFileInfo) { result += info.file!!.canonicalPath } }) } finally { clang_disposeTranslationUnit(translationUnit) } return result.toList() } private fun getModulesHeaders( index: CXIndex, translationUnit: CXTranslationUnit, modules: Set, topLevelHeaders: LinkedHashSet ): Set { val nonModularIncludes = mutableMapOf>() val result = mutableSetOf() indexTranslationUnit(index, translationUnit, 0, object : Indexer { override fun ppIncludedFile(info: CXIdxIncludedFileInfo) { val file = info.file!! val includer = clang_indexLoc_getCXSourceLocation(info.hashLoc.readValue()).getContainingFile() if (includer == null) { // i.e. the header is included by the module itself. topLevelHeaders += file.path } val module = clang_getModuleForFile(translationUnit, file) if (module != null) { val moduleWithParents = generateSequence(module, { clang_Module_getParent(it) }).map { clang_Module_getFullName(it).convertAndDispose() } if (moduleWithParents.any { it in modules }) { result += file } } else if (includer != null) { nonModularIncludes.getOrPut(includer, { mutableSetOf() }) += file } } }) // There are cases when non-modular includes should also be considered as a part of module. For example: // 1. Some module maps are broken, // e.g. system header `IOKit/hid/IOHIDProperties.h` isn't included to framework module map at all. // 2. Textual headers are reported as non-modular by libclang. // // Find and include non-modular headers too: result += findReachable(roots = result, arcs = nonModularIncludes) return result } private fun findReachable(roots: Set, arcs: Map>): Set { val visited = mutableSetOf() fun dfs(vertex: T) { if (!visited.add(vertex)) return arcs[vertex].orEmpty().forEach { dfs(it) } } roots.forEach { dfs(it) } return visited } ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.indexer enum class Language(val sourceFileExtension: String) { C("c"), OBJECTIVE_C("m") } interface HeaderInclusionPolicy { /** * Whether unused declarations from given header should be excluded. * * @param headerName header path relative to the appropriate include path element (e.g. `time.h` or `curl/curl.h`), * or `null` for builtin declarations. */ fun excludeUnused(headerName: String?): Boolean } interface HeaderExclusionPolicy { /** * Whether all declarations from this header should be excluded. * * Note: the declarations from such headers can be actually present in the internal representation, * but not included into the root collections. */ fun excludeAll(headerId: HeaderId): Boolean } sealed class NativeLibraryHeaderFilter { class NameBased( val policy: HeaderInclusionPolicy, val excludeDepdendentModules: Boolean ) : NativeLibraryHeaderFilter() class Predefined(val headers: Set) : NativeLibraryHeaderFilter() } interface Compilation { val includes: List val additionalPreambleLines: List val compilerArgs: List val language: Language } data class CompilationWithPCH( override val compilerArgs: List, override val language: Language ) : Compilation { constructor(compilerArgs: List, precompiledHeader: String, language: Language) : this(compilerArgs + listOf("-include-pch", precompiledHeader), language) override val includes: List get() = emptyList() override val additionalPreambleLines: List get() = emptyList() } // TODO: Compilation hierarchy seems to require some refactoring. data class NativeLibrary(override val includes: List, override val additionalPreambleLines: List, override val compilerArgs: List, val headerToIdMapper: HeaderToIdMapper, override val language: Language, val excludeSystemLibs: Boolean, // TODO: drop? val headerExclusionPolicy: HeaderExclusionPolicy, val headerFilter: NativeLibraryHeaderFilter) : Compilation data class IndexerResult(val index: NativeIndex, val compilation: CompilationWithPCH) /** * Retrieves the definitions from given C header file using given compiler arguments (e.g. defines). */ fun buildNativeIndex(library: NativeLibrary, verbose: Boolean): IndexerResult = buildNativeIndexImpl(library, verbose) /** * This class describes the IR of definitions from C header file(s). */ abstract class NativeIndex { abstract val structs: Collection abstract val enums: Collection abstract val objCClasses: Collection abstract val objCProtocols: Collection abstract val objCCategories: Collection abstract val typedefs: Collection abstract val functions: Collection abstract val macroConstants: Collection abstract val wrappedMacros: Collection abstract val globals: Collection abstract val includedHeaders: Collection } /** * The (contents-based) header id. * Its [value] remains valid across different runs of the indexer and the process, * and thus can be used to 'serialize' the id. */ data class HeaderId(val value: String) data class Location(val headerId: HeaderId) interface TypeDeclaration { val location: Location } sealed class StructMember(val name: String, val type: Type) { abstract val offset: Long? } /** * C struct field. */ class Field(name: String, type: Type, override val offset: Long, val typeSize: Long, val typeAlign: Long) : StructMember(name, type) val Field.isAligned: Boolean get() = offset % (typeAlign * 8) == 0L class BitField(name: String, type: Type, override val offset: Long, val size: Int) : StructMember(name, type) class IncompleteField(name: String, type: Type) : StructMember(name, type) { override val offset: Long? get() = null } /** * C struct declaration. */ abstract class StructDecl(val spelling: String) : TypeDeclaration { abstract val def: StructDef? } /** * C struct definition. * * @param hasNaturalLayout must be `false` if the struct has unnatural layout, e.g. it is `packed`. * May be `false` even if the struct has natural layout. */ abstract class StructDef(val size: Long, val align: Int, val decl: StructDecl) { enum class Kind { STRUCT, UNION } abstract val members: List abstract val kind: Kind val fields: List get() = members.filterIsInstance() val bitFields: List get() = members.filterIsInstance() } /** * C enum value. */ class EnumConstant(val name: String, val value: Long, val isExplicitlyDefined: Boolean) /** * C enum definition. */ abstract class EnumDef(val spelling: String, val baseType: Type) : TypeDeclaration { abstract val constants: List } sealed class ObjCContainer { abstract val protocols: List abstract val methods: List abstract val properties: List } sealed class ObjCClassOrProtocol(val name: String) : ObjCContainer(), TypeDeclaration { abstract val isForwardDeclaration: Boolean } data class ObjCMethod( val selector: String, val encoding: String, val parameters: List, private val returnType: Type, val isVariadic: Boolean, val isClass: Boolean, val nsConsumesSelf: Boolean, val nsReturnsRetained: Boolean, val isOptional: Boolean, val isInit: Boolean, val isExplicitlyDesignatedInitializer: Boolean ) { fun returnsInstancetype(): Boolean = returnType is ObjCInstanceType fun getReturnType(container: ObjCClassOrProtocol): Type = if (returnType is ObjCInstanceType) { when (container) { is ObjCClass -> ObjCObjectPointer(container, returnType.nullability, protocols = emptyList()) is ObjCProtocol -> ObjCIdType(returnType.nullability, protocols = listOf(container)) } } else { returnType } } data class ObjCProperty(val name: String, val getter: ObjCMethod, val setter: ObjCMethod?) { fun getType(container: ObjCClassOrProtocol): Type = getter.getReturnType(container) } abstract class ObjCClass(name: String) : ObjCClassOrProtocol(name) { abstract val binaryName: String? abstract val baseClass: ObjCClass? } abstract class ObjCProtocol(name: String) : ObjCClassOrProtocol(name) abstract class ObjCCategory(val name: String, val clazz: ObjCClass) : ObjCContainer() /** * C function parameter. */ data class Parameter(val name: String?, val type: Type, val nsConsumed: Boolean) /** * C function declaration. */ class FunctionDecl(val name: String, val parameters: List, val returnType: Type, val binaryName: String, val isDefined: Boolean, val isVararg: Boolean) /** * C typedef definition. * * ``` * typedef $aliased $name; * ``` */ class TypedefDef(val aliased: Type, val name: String, override val location: Location) : TypeDeclaration abstract class MacroDef(val name: String) abstract class ConstantDef(name: String, val type: Type): MacroDef(name) class IntegerConstantDef(name: String, type: Type, val value: Long) : ConstantDef(name, type) class FloatingConstantDef(name: String, type: Type, val value: Double) : ConstantDef(name, type) class StringConstantDef(name: String, type: Type, val value: String) : ConstantDef(name, type) class WrappedMacroDef(name: String, val type: Type) : MacroDef(name) class GlobalDecl(val name: String, val type: Type, val isConst: Boolean) /** * C type. */ interface Type interface PrimitiveType : Type object CharType : PrimitiveType open class BoolType: PrimitiveType object CBoolType : BoolType() object ObjCBoolType : BoolType() // We omit `const` qualifier for IntegerType and FloatingType to make `CBridgeGen` simpler. // See KT-28102. data class IntegerType(val size: Int, val isSigned: Boolean, val spelling: String) : PrimitiveType // TODO: floating type is not actually defined entirely by its size. data class FloatingType(val size: Int, val spelling: String) : PrimitiveType data class VectorType(val elementType: Type, val elementCount: Int, val spelling: String) : PrimitiveType object VoidType : Type data class RecordType(val decl: StructDecl) : Type data class EnumType(val def: EnumDef) : Type data class PointerType(val pointeeType: Type, val pointeeIsConst: Boolean = false) : Type // TODO: refactor type representation and support type modifiers more generally. data class FunctionType(val parameterTypes: List, val returnType: Type) : Type interface ArrayType : Type { val elemType: Type } data class ConstArrayType(override val elemType: Type, val length: Long) : ArrayType data class IncompleteArrayType(override val elemType: Type) : ArrayType data class VariableArrayType(override val elemType: Type) : ArrayType data class Typedef(val def: TypedefDef) : Type sealed class ObjCPointer : Type { enum class Nullability { Nullable, NonNull, Unspecified } abstract val nullability: Nullability } sealed class ObjCQualifiedPointer : ObjCPointer() { abstract val protocols: List } data class ObjCObjectPointer( val def: ObjCClass, override val nullability: Nullability, override val protocols: List ) : ObjCQualifiedPointer() data class ObjCClassPointer( override val nullability: Nullability, override val protocols: List ) : ObjCQualifiedPointer() data class ObjCIdType( override val nullability: Nullability, override val protocols: List ) : ObjCQualifiedPointer() data class ObjCInstanceType(override val nullability: Nullability) : ObjCPointer() data class ObjCBlockPointer( override val nullability: Nullability, val parameterTypes: List, val returnType: Type ) : ObjCPointer() object UnsupportedType : Type ================================================ FILE: Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.indexer import clang.* import kotlinx.cinterop.* import java.io.Closeable import java.io.File import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.security.DigestInputStream import java.security.MessageDigest internal val CValue.kind: CXTypeKind get() = this.useContents { kind } internal val CValue.kind: CXCursorKind get() = this.useContents { kind } internal val CValue.type: CValue get() = clang_getCursorType(this) internal val CValue.spelling: String get() = clang_getCursorSpelling(this).convertAndDispose() internal val CValue.name: String get() = clang_getTypeSpelling(this).convertAndDispose() internal val CXTypeKind.spelling: String get() = clang_getTypeKindSpelling(this).convertAndDispose() internal val CXCursorKind.spelling: String get() = clang_getCursorKindSpelling(this).convertAndDispose() internal fun CValue.convertAndDispose(): String { try { return clang_getCString(this)!!.toKString() } finally { clang_disposeString(this) } } internal fun CPointer.convertAndDispose(): Set = try { (0 until this.pointed.Count).mapTo(mutableSetOf()) { clang_getCString(this.pointed.Strings!![it].readValue())!!.toKString() } } finally { clang_disposeStringSet(this) } internal fun getCursorSpelling(cursor: CValue) = clang_getCursorSpelling(cursor).convertAndDispose() internal fun CValue.getSize(): Long { val size = clang_Type_getSizeOf(this) if (size < 0) { throw Error(size.toString()) } return size } internal inline fun withIndex( excludeDeclarationsFromPCH: Boolean = false, displayDiagnostics: Boolean = false, block: (index: CXIndex) -> R ): R { val index = clang_createIndex( excludeDeclarationsFromPCH = if (excludeDeclarationsFromPCH) 1 else 0, displayDiagnostics = if (displayDiagnostics) 1 else 0 )!! return try { block(index) } finally { clang_disposeIndex(index) } } internal fun parseTranslationUnit( index: CXIndex, sourceFile: File, compilerArgs: List, options: Int ): CXTranslationUnit { memScoped { val resultVar = alloc() val errorCode = clang_parseTranslationUnit2( index, sourceFile.absolutePath, compilerArgs.toNativeStringArray(memScope), compilerArgs.size, null, 0, options, resultVar.ptr ) if (errorCode != CXErrorCode.CXError_Success) { val copiedSourceFile = sourceFile.copyTo(Files.createTempFile(null, sourceFile.name).toFile(), overwrite = true) error(""" clang_parseTranslationUnit2 failed with $errorCode; sourceFile = ${copiedSourceFile.absolutePath} arguments = ${compilerArgs.joinToString(" ")} """.trimIndent()) } return resultVar.value!! } } internal fun Compilation.parse(index: CXIndex, options: Int = 0): CXTranslationUnit = parseTranslationUnit(index, this.createTempSource(), this.compilerArgs, options) internal data class Diagnostic(val severity: CXDiagnosticSeverity, val format: String, val location: CValue) internal fun CXTranslationUnit.getDiagnostics(): Sequence { val numDiagnostics = clang_getNumDiagnostics(this) return (0 until numDiagnostics).asSequence() .map { index -> val diagnostic = clang_getDiagnostic(this, index) try { val severity = clang_getDiagnosticSeverity(diagnostic) val format = clang_formatDiagnostic(diagnostic, clang_defaultDiagnosticDisplayOptions()) .convertAndDispose() val location = clang_getDiagnosticLocation(diagnostic) Diagnostic(severity, format, location) } finally { clang_disposeDiagnostic(diagnostic) } } } internal fun CXTranslationUnit.getCompileErrors(): Sequence = getDiagnostics().filter { it.isError() }.map { it.format } private fun Diagnostic.isError() = (severity == CXDiagnosticSeverity.CXDiagnostic_Error) || (severity == CXDiagnosticSeverity.CXDiagnostic_Fatal) internal fun CXTranslationUnit.hasCompileErrors() = (this.getCompileErrors().firstOrNull() != null) internal fun CXTranslationUnit.ensureNoCompileErrors(): CXTranslationUnit { val firstError = this.getCompileErrors().firstOrNull() ?: return this throw Error(firstError) } internal typealias CursorVisitor = (cursor: CValue, parent: CValue) -> CXChildVisitResult internal fun visitChildren(parent: CValue, visitor: CursorVisitor) { val visitorStableRef = StableRef.create(visitor) try { val clientData = visitorStableRef.asCPointer() clang_visitChildren(parent, staticCFunction { cursorIt, parentIt, clientDataIt -> val visitorIt = clientDataIt!!.asStableRef().get() visitorIt(cursorIt, parentIt) }, clientData) } finally { visitorStableRef.dispose() } } internal fun visitChildren(translationUnit: CXTranslationUnit, visitor: CursorVisitor) = visitChildren(clang_getTranslationUnitCursor(translationUnit), visitor) internal fun getFields(type: CValue): List> { val result = mutableListOf>() val resultStableRef = StableRef.create(result) try { val clientData = resultStableRef.asCPointer() @Suppress("NAME_SHADOWING") clang_Type_visitFields(type, staticCFunction { cursor, clientData -> val result = clientData!!.asStableRef>>().get() result.add(cursor) CXVisitorResult.CXVisit_Continue }, clientData) } finally { resultStableRef.dispose() } return result } fun StructDef.fieldsHaveDefaultAlignment(): Boolean { fun alignUp(x: Long, alignment: Long): Long = (x + alignment - 1) and (alignment - 1).inv() var offset = 0L this.members.forEach { when (it) { is Field -> { if (alignUp(offset, it.typeAlign) * 8 != it.offset) return false offset = it.offset / 8 + it.typeSize } is BitField -> return false } } return true } internal fun CValue.hasExpressionChild(): Boolean { var result = false visitChildren(this) { cursor, _ -> if (clang_isExpression(cursor.kind) != 0) { result = true CXChildVisitResult.CXChildVisit_Break } else { CXChildVisitResult.CXChildVisit_Continue } } return result } internal fun List.toNativeStringArray(scope: AutofreeScope): CArrayPointer> { return scope.allocArray(this.size) { index -> this.value = this@toNativeStringArray[index].cstr.getPointer(scope) } } val Compilation.preambleLines: List get() = this.includes.map { "#include <$it>" } + this.additionalPreambleLines internal fun Appendable.appendPreamble(compilation: Compilation) = this.apply { compilation.preambleLines.forEach { this.appendLine(it) } } /** * Creates temporary source file which includes the library. */ internal fun Compilation.createTempSource(): File { val result = Files.createTempFile(null, ".${language.sourceFileExtension}").toFile() result.deleteOnExit() result.bufferedWriter().use { writer -> writer.appendPreamble(this) } return result } fun Compilation.copy( includes: List = this.includes, additionalPreambleLines: List = this.additionalPreambleLines, compilerArgs: List = this.compilerArgs, language: Language = this.language ): Compilation = CompilationImpl( includes = includes, additionalPreambleLines = additionalPreambleLines, compilerArgs = compilerArgs, language = language ) // Clang-8 crashes when consuming a precompiled header built with -fmodule-map-file argument (see KT-34467). // We ignore this argument when building a pch to workaround this crash. fun Compilation.copyWithArgsForPCH(): Compilation = copy(compilerArgs = compilerArgs.filterNot { it.startsWith("-fmodule-map-file") }) data class CompilationImpl( override val includes: List, override val additionalPreambleLines: List, override val compilerArgs: List, override val language: Language ) : Compilation /** * Precompiles the headers of this library. * * @return the library which includes the precompiled header instead of original ones. */ fun Compilation.precompileHeaders(): CompilationWithPCH = withIndex { index -> val options = CXTranslationUnit_ForSerialization val translationUnit = copyWithArgsForPCH().parse(index, options) try { translationUnit.ensureNoCompileErrors() withPrecompiledHeader(translationUnit) } finally { clang_disposeTranslationUnit(translationUnit) } } internal fun Compilation.withPrecompiledHeader(translationUnit: CXTranslationUnit): CompilationWithPCH { val precompiledHeader = Files.createTempFile(null, ".pch").toFile().apply { this.deleteOnExit() } clang_saveTranslationUnit(translationUnit, precompiledHeader.absolutePath, 0) return CompilationWithPCH(this.compilerArgs, precompiledHeader.absolutePath, this.language) } internal fun NativeLibrary.includesDeclaration(cursor: CValue): Boolean { return if (this.excludeSystemLibs) { clang_Location_isInSystemHeader(clang_getCursorLocation(cursor)) == 0 } else { true } } internal fun CXTranslationUnit.getErrorLineNumbers(): Sequence = getDiagnostics().filter { it.isError() }.map { memScoped { val lineNumberVar = alloc() clang_getFileLocation(it.location, null, lineNumberVar.ptr, null, null) lineNumberVar.value } } /** * For each list of lines, checks if the code fragment composed from these lines is compilable against given library. */ fun List>.mapFragmentIsCompilable(originalLibrary: CompilationWithPCH): List { val library: CompilationWithPCH = originalLibrary .copy(compilerArgs = originalLibrary.compilerArgs + "-ferror-limit=0") val indicesOfNonCompilable = mutableSetOf() val fragmentsToCheck = this.withIndex().toMutableList() withIndex(excludeDeclarationsFromPCH = true) { index -> val sourceFile = library.createTempSource() val translationUnit = parseTranslationUnit(index, sourceFile, library.compilerArgs, options = 0) try { translationUnit.ensureNoCompileErrors() while (fragmentsToCheck.isNotEmpty()) { // Combine all fragments to be checked in a single file: sourceFile.bufferedWriter().use { writer -> writer.appendPreamble(library) fragmentsToCheck.forEach { it.value.forEach { assert(!it.contains('\n')) writer.appendLine(it) } } } clang_reparseTranslationUnit(translationUnit, 0, null, 0) val errorLineNumbers = translationUnit.getErrorLineNumbers().toSet() // Retain only those fragments that contain compilation error locations: var lastLineNumber = library.preambleLines.size fragmentsToCheck.retainAll { val firstLineNumber = lastLineNumber + 1 lastLineNumber += it.value.size (firstLineNumber .. lastLineNumber).any { it in errorLineNumbers } } if (fragmentsToCheck.isNotEmpty()) { // The first fragment is now known to be non-compilable. val firstFragment = fragmentsToCheck.removeAt(0) indicesOfNonCompilable.add(firstFragment.index) } // The remaining fragments was potentially influenced by the first one, // and thus require to be checked again. } } finally { clang_disposeTranslationUnit(translationUnit) } } return this.indices.map { it !in indicesOfNonCompilable } } internal interface Indexer { /** * Called when entered main file. */ fun enteredMainFile(file: CXFile) {} /** * Called when a file gets #included/#imported. */ fun ppIncludedFile(info: CXIdxIncludedFileInfo) {} /** * Called when a AST file (PCH or module) gets imported. */ fun importedASTFile(info: CXIdxImportedASTFileInfo) {} /** * Called to index a declaration. */ fun indexDeclaration(info: CXIdxDeclInfo) {} } internal fun indexTranslationUnit(index: CXIndex, translationUnit: CXTranslationUnit, options: Int, indexer: Indexer) { val indexerStableRef = StableRef.create(indexer) try { val clientData = indexerStableRef.asCPointer() memScoped { val indexerCallbacks = alloc().apply { abortQuery = null diagnostic = null enteredMainFile = staticCFunction { clientData, mainFile, _ -> @Suppress("NAME_SHADOWING") val indexer = clientData!!.asStableRef().get() indexer.enteredMainFile(mainFile!!) // We must ensure only interop types exist in function signature. @Suppress("USELESS_CAST") null as CXIdxClientFile? } ppIncludedFile = staticCFunction { clientData, info -> @Suppress("NAME_SHADOWING") val indexer = clientData!!.asStableRef().get() indexer.ppIncludedFile(info!!.pointed) // We must ensure only interop types exist in function signature. @Suppress("USELESS_CAST") null as CXIdxClientFile? } importedASTFile = staticCFunction { clientData, info -> @Suppress("NAME_SHADOWING") val indexer = clientData!!.asStableRef().get() indexer.importedASTFile(info!!.pointed) // We must ensure only interop types exist in function signature. @Suppress("USELESS_CAST") null as CXIdxClientFile? } startedTranslationUnit = null indexDeclaration = staticCFunction { clientData, info -> @Suppress("NAME_SHADOWING") val nativeIndex = clientData!!.asStableRef().get() nativeIndex.indexDeclaration(info!!.pointed) } indexEntityReference = null } val indexAction = clang_IndexAction_create(index) try { val result = clang_indexTranslationUnit(indexAction, clientData, indexerCallbacks.ptr, sizeOf().toInt(), options, translationUnit) if (result != 0) { throw Error("clang_indexTranslationUnit returned $result") } } finally { clang_IndexAction_dispose(indexAction) } } } finally { indexerStableRef.dispose() } } internal class ModulesMap( val compilation: Compilation, val translationUnit: CXTranslationUnit ) : Closeable { private val modularCompilation: ModularCompilation private val index: CXIndex private val translationUnitWithModules: CXTranslationUnit private val arena = Arena() private inline fun T.toBeDisposedWith(crossinline block: (T) -> Unit): T = apply { arena.defer { block(this) } } override fun close() { arena.clear() } init { try { modularCompilation = ModularCompilation(compilation) .toBeDisposedWith { it.dispose() } index = clang_createIndex(0, 0)!! .toBeDisposedWith { clang_disposeIndex(it) } translationUnitWithModules = modularCompilation.parse(index) .toBeDisposedWith { clang_disposeTranslationUnit(it) } translationUnitWithModules.ensureNoCompileErrors() } catch (e: Throwable) { this.close() throw e } } data class Module(private val cxModule: CXModule) fun getModule(file: CXFile): Module? { // `file` is bound to `translationUnit`, however `translationUnitWithModules` is used to access modules. // Find the corresponding file in `translationUnitWithModules`: val fileInTuWithModules = clang_getFile(translationUnitWithModules, clang_getFileName(file).convertAndDispose())!! return clang_getModuleForFile(translationUnitWithModules, fileInTuWithModules)?.let { Module(it) } } } internal fun getHeaderId(library: NativeLibrary, header: CXFile?): HeaderId { if (header == null) { return HeaderId("builtins") } val filePath = header.path return library.headerToIdMapper.getHeaderId(filePath) } internal fun getFilteredHeaders( nativeIndex: NativeIndexImpl, index: CXIndex, translationUnit: CXTranslationUnit ): Set = getHeaders(nativeIndex.library, index, translationUnit).ownHeaders class NativeLibraryHeaders
(val ownHeaders: Set
, val importedHeaders: Set
) internal fun getHeaders( library: NativeLibrary, index: CXIndex, translationUnit: CXTranslationUnit ): NativeLibraryHeaders { val ownHeaders = mutableSetOf() val allHeaders = mutableSetOf(null) val filter = library.headerFilter when (filter) { is NativeLibraryHeaderFilter.NameBased -> filterHeadersByName(library, filter, index, translationUnit, ownHeaders, allHeaders) is NativeLibraryHeaderFilter.Predefined -> filterHeadersByPredefined(filter, index, translationUnit, ownHeaders, allHeaders) } ownHeaders.removeAll { library.headerExclusionPolicy.excludeAll(getHeaderId(library, it)) } return NativeLibraryHeaders(ownHeaders, allHeaders - ownHeaders) } private fun filterHeadersByName( compilation: Compilation, filter: NativeLibraryHeaderFilter.NameBased, index: CXIndex, translationUnit: CXTranslationUnit, ownHeaders: MutableSet, allHeaders: MutableSet ) { val topLevelFiles = mutableListOf() var mainFile: CXFile? = null indexTranslationUnit(index, translationUnit, 0, object : Indexer { val headerToName = mutableMapOf() // The *name* of the header here is the path relative to the include path element., e.g. `curl/curl.h`. override fun enteredMainFile(file: CXFile) { mainFile = file allHeaders += file } override fun ppIncludedFile(info: CXIdxIncludedFileInfo) { val includeLocation = clang_indexLoc_getCXSourceLocation(info.hashLoc.readValue()) val file = info.file!! allHeaders += file if (clang_Location_isFromMainFile(includeLocation) != 0) { topLevelFiles.add(file) } val name = info.filename!!.toKString() val headerName = if (info.isAngled != 0) { // If the header is included with `#include <$name>`, then `name` is probably // the path relative to the include path element. name } else { // If it is included with `#include "$name"`, then `name` can also be the path relative to the includer. val includerFile = includeLocation.getContainingFile()!! val includerName = headerToName[includerFile] ?: "" val includerPath = includerFile.path if (clang_getFile(translationUnit, Paths.get(includerPath).resolveSibling(name).toString()) == file) { // included file is accessible from the includer by `name` used as relative path, so // `name` seems to be relative to the includer: Paths.get(includerName).resolveSibling(name).normalize().toString() } else { name } } headerToName[file] = headerName if (!filter.policy.excludeUnused(headerName)) { ownHeaders.add(file) } } }) if (filter.excludeDepdendentModules) { ModulesMap(compilation, translationUnit).use { modulesMap -> val topLevelModules = topLevelFiles.map { modulesMap.getModule(it) }.toSet() ownHeaders.removeAll { val module = modulesMap.getModule(it!!) module !in topLevelModules } // Note: if some of the top-level headers don't belong to modules, // then all non-modular headers are included. } } else { if (!filter.policy.excludeUnused(headerName = null)) { // Builtins. ownHeaders.add(null) } } ownHeaders.add(mainFile!!) } private fun filterHeadersByPredefined( filter: NativeLibraryHeaderFilter.Predefined, index: CXIndex, translationUnit: CXTranslationUnit, ownHeaders: MutableSet, allHeaders: MutableSet ) { // Note: suboptimal but simple. indexTranslationUnit(index, translationUnit, 0, object : Indexer { override fun ppIncludedFile(info: CXIdxIncludedFileInfo) { val file = info.file allHeaders += file if (file?.canonicalPath in filter.headers) { ownHeaders += file } } }) } fun NativeLibrary.getHeaderPaths(): NativeLibraryHeaders { withIndex { index -> val translationUnit = this.parse(index, options = CXTranslationUnit_DetailedPreprocessingRecord).ensureNoCompileErrors() try { fun getPath(file: CXFile?) = if (file == null) "" else file.canonicalPath val headers = getHeaders(this, index, translationUnit) return NativeLibraryHeaders( headers.ownHeaders.map(::getPath).toSet(), headers.importedHeaders.map(::getPath).toSet() ) } finally { clang_disposeTranslationUnit(translationUnit) } } } fun ObjCMethod.replaces(other: ObjCMethod): Boolean = this.isClass == other.isClass && this.selector == other.selector fun ObjCProperty.replaces(other: ObjCProperty): Boolean = this.getter.replaces(other.getter) fun File.sha256(): String { val digest = MessageDigest.getInstance("SHA-256") DigestInputStream(this.inputStream(), digest).use { dis -> val buffer = ByteArray(8192) // Read all bytes: while (dis.read(buffer, 0, buffer.size) != -1) {} } // Convert to hex: return digest.digest().joinToString("") { Integer.toHexString((it.toInt() and 0xff) + 0x100).substring(1) } } fun headerContentsHash(filePath: String) = File(filePath).sha256() internal fun CValue.getContainingFile(): CXFile? = memScoped { val fileVar = alloc() clang_getFileLocation(this@getContainingFile, fileVar.ptr, null, null, null) fileVar.value } @JvmName("getFileContainingCursor") internal fun getContainingFile(cursor: CValue): CXFile? { return clang_getCursorLocation(cursor).getContainingFile() } internal val CXFile.path: String get() = clang_getFileName(this).convertAndDispose() internal val CXFile.canonicalPath: String get() = File(this.path).canonicalPath private fun createVfsOverlayFileContents(virtualPathToReal: Map): ByteArray { val overlay = clang_VirtualFileOverlay_create(0) try { fun addFileMapping(realPath: Path, virtualPath: Path) { clang_VirtualFileOverlay_addFileMapping( overlay, virtualPath = virtualPath.toAbsolutePath().toString(), realPath = realPath.toAbsolutePath().toString() ) } virtualPathToReal.forEach { virtualPath, realPath -> if (Files.isDirectory(realPath)) { realPath.toFile().walkTopDown().forEach { if (!it.isDirectory) { addFileMapping( realPath = it.toPath(), virtualPath = virtualPath.resolve(realPath.relativize(it.toPath())) ) } } } else { addFileMapping(realPath = realPath, virtualPath = virtualPath) } } memScoped { val bufferVar = alloc>().apply { value = null } val bufferSizeVar = alloc() val res = clang_VirtualFileOverlay_writeToBuffer(overlay, 0, bufferVar.ptr, bufferSizeVar.ptr) if (res != CXErrorCode.CXError_Success) { // TODO: shall we free the buffer in this case? error(res) } return bufferVar.value!!.readBytes(bufferSizeVar.value) } } finally { clang_VirtualFileOverlay_dispose(overlay) } } fun createVfsOverlayFile(virtualPathToReal: Map): Path { val bytes = createVfsOverlayFileContents(virtualPathToReal) return Files.createTempFile("konan", ".vfsoverlay").also { Files.write(it, bytes) it.toFile().deleteOnExit() } } tailrec fun Type.unwrapTypedefs(): Type = if (this is Typedef) { this.def.aliased.unwrapTypedefs() } else { this } fun Type.canonicalIsPointerToChar(): Boolean { val unwrappedType = this.unwrapTypedefs() return unwrappedType is PointerType && unwrappedType.pointeeType.unwrapTypedefs() == CharType } internal interface Disposable { fun dispose() } internal inline fun T.use(block: (T) -> R): R = try { block(this) } finally { this.dispose() } ================================================ FILE: Interop/Indexer/src/nativeInteropStubs/cpp/disable-abi-checks.cpp ================================================ #ifdef __linux__ namespace llvm { /** * http://lists.llvm.org/pipermail/llvm-dev/2017-January/109621.html * We can't rebuild llvm, but we can define symbol missed in llvm build. */ int DisableABIBreakingChecks = 1; } #endif ================================================ FILE: Interop/Indexer/src/nativeInteropStubs/cpp/signalChaining.cpp ================================================ #if defined(__linux__) || defined(__APPLE__) #include #if defined(__linux__) #include #endif #include #include extern "C" void clang_toggleCrashRecovery(unsigned isEnabled); constexpr int signalsToCover[] = { SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGUSR1, SIGUSR2 }; struct { void* handler; bool isSigaction; } oldSignalHandlers[sizeof(signalsToCover)/sizeof(signalsToCover[0])] = { 0 }; static int mySigaction(int sig, const struct sigaction *act, struct sigaction * oact) { for (int i = 0; i < sizeof(signalsToCover)/sizeof(signalsToCover[0]); i++) { if (sig == signalsToCover[i]) return 0; } return sigaction(sig, act, oact); } static void checkSignalChaining() { struct sigaction oact; clang_toggleCrashRecovery(1); for (int i = 0; i < sizeof(signalsToCover)/sizeof(signalsToCover[0]); i++) { int sig = signalsToCover[i]; if (sigaction(sig, nullptr, &oact) != 0) continue; if ((oact.sa_flags & SA_SIGINFO) == 0) { if (oldSignalHandlers[i].isSigaction) { fprintf(stderr, "ERROR: improperly changed signal flag for %d\n", sig); continue; } if (oldSignalHandlers[i].handler != (void*)oact.sa_handler) { fprintf(stderr, "ERROR: improperly changed signal handler for %d\n", sig); continue; } } else { if (!oldSignalHandlers[i].isSigaction) { fprintf(stderr, "ERROR: improperly changed signal flag for %d\n", sig); continue; } void* action = (void*)oact.sa_sigaction; if (oldSignalHandlers[i].handler != action) { Dl_info info; const char* soname = ""; if (dladdr(action, &info) != 0) { soname = info.dli_fname; } fprintf(stderr, "ERROR: changed signal handler for %d from %p to %p: coming from %s\n", sig, oldSignalHandlers[i].handler, action, soname); } } } clang_toggleCrashRecovery(0); } __attribute__((constructor)) static void initSignalChaining() { void** base = 0; Dl_info info; for (int i = 0; i < sizeof(signalsToCover)/sizeof(signalsToCover[0]); i++) { struct sigaction oact; int sig = signalsToCover[i]; if (sigaction(signalsToCover[i], nullptr, &oact) == 0) { if ((oact.sa_flags & SA_SIGINFO) == 0) { oldSignalHandlers[i] = {(void*)oact.sa_handler, false}; } else { oldSignalHandlers[i] = {(void*)oact.sa_sigaction, true}; } } } if (dladdr((void*)&clang_toggleCrashRecovery, &info) == 0) return; base = (void**)info.dli_fbase; // Force resolving of lazy symbols. clang_toggleCrashRecovery(1); clang_toggleCrashRecovery(0); // And then patch GOT. #if defined(__linux__) { // On Linux we have to be a bit tricky, as there's unmapped gap between code and GOT. struct link_map* linkmap = 0; if (dladdr1((void*)&clang_toggleCrashRecovery, &info, (void**)&linkmap, RTLD_DL_LINKMAP) == 0) return; base = (void**)linkmap->l_ld; } #endif for (int index = 0, patched = 0; patched < 1; index++) { void* value = base[index]; if (value == &sigaction) { base[index] = (void*)mySigaction; patched++; } if (value == mySigaction) { patched++; } } checkSignalChaining(); } #endif // defined(__linux__) || defined(__APPLE__) ================================================ FILE: Interop/JsRuntime/build.gradle ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" } ================================================ FILE: Interop/JsRuntime/src/main/js/jsinterop.js ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ konan.libraries.push ({ arenas: new Map(), nextArena: 0, Konan_js_allocateArena: function (array) { var index = konan_dependencies.env.nextArena++; konan_dependencies.env.arenas.set(index, array || []); return index; }, Konan_js_freeArena: function(arenaIndex) { var arena = konan_dependencies.env.arenas.get(arenaIndex); arena.forEach(function(element, index) { arena[index] = null; }); konan_dependencies.env.arenas.delete(arenaIndex); }, Konan_js_pushIntToArena: function (arenaIndex, value) { var arena = konan_dependencies.env.arenas.get(arenaIndex); arena.push(value); return arena.length - 1; }, Konan_js_addObjectToArena: function (arenaIndex, object) { var arena = konan_dependencies.env.arenas.get(arenaIndex); arena.push(object); return arena.length - 1; }, Konan_js_wrapLambda: function (functionArenaIndex, index) { return (function () { var functionArena = konan_dependencies.env.arenas.get(functionArenaIndex); // convert Arguments to an array // to be provided by launcher.js var argumentArenaIndex = konan_dependencies.env.Konan_js_allocateArena(Array.prototype.slice.call(arguments)); var resultIndex = instance.exports.Konan_js_runLambda(index, argumentArenaIndex, arguments.length); var result = kotlinObject(argumentArenaIndex, resultIndex); konan_dependencies.env.Konan_js_freeArena(argumentArenaIndex); return result; }); }, Konan_js_getInt: function(arenaIndex, objIndex, propertyNamePtr, propertyNameLength) { // TODO: The toUTF16String() is to be resolved by launcher.js runtime. var property = toUTF16String(propertyNamePtr, propertyNameLength); var value = kotlinObject(arenaIndex, objIndex)[property]; return value; }, Konan_js_getProperty: function(arenaIndex, objIndex, propertyNamePtr, propertyNameLength) { // TODO: The toUTF16String() is to be resolved by launcher.js runtime. var property = toUTF16String(propertyNamePtr, propertyNameLength); var arena = konan_dependencies.env.arenas.get(arenaIndex); var value = arena[objIndex][property]; arena.push(value); return arena.length - 1; }, Konan_js_setFunction: function (arena, obj, propertyName, propertyNameLength, func) { var name = toUTF16String(propertyName, propertyNameLength); kotlinObject(arena, obj)[name] = konan_dependencies.env.Konan_js_wrapLambda(arena, func); }, Konan_js_setString: function (arena, obj, propertyName, propertyNameLength, stringPtr, stringLength) { var name = toUTF16String(propertyName, propertyNameLength); var string = toUTF16String(stringPtr, stringLength); kotlinObject(arena, obj)[name] = string; }, }); // TODO: This is just a shorthand notation. function kotlinObject(arenaIndex, objectIndex) { var arena = konan_dependencies.env.arenas.get(arenaIndex); if (typeof arena == "undefined") { console.log("No arena index " + arenaIndex + "for object" + objectIndex); console.trace() } return arena[objectIndex] } function toArena(arenaIndex, object) { return konan_dependencies.env.Konan_js_addObjectToArena(arenaIndex, object); } ================================================ FILE: Interop/JsRuntime/src/main/kotlin/jsinterop.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.wasm.jsinterop import kotlin.native.* import kotlin.native.internal.ExportForCppRuntime import kotlinx.cinterop.* typealias Arena = Int typealias Object = Int typealias Pointer = Int /** * @Retain annotation is required to preserve functions from internalization and DCE. */ @RetainForTarget("wasm32") @SymbolName("Konan_js_allocateArena") external public fun allocateArena(): Arena @RetainForTarget("wasm32") @SymbolName("Konan_js_freeArena") external public fun freeArena(arena: Arena) @RetainForTarget("wasm32") @SymbolName("Konan_js_pushIntToArena") external public fun pushIntToArena(arena: Arena, value: Int) const val upperWord = 0xffffffff.toLong() shl 32 @ExportForCppRuntime fun doubleUpper(value: Double): Int = ((value.toBits() and upperWord) ushr 32) .toInt() @ExportForCppRuntime fun doubleLower(value: Double): Int = (value.toBits() and 0x00000000ffffffff) .toInt() @RetainForTarget("wasm32") @SymbolName("ReturnSlot_getDouble") external public fun ReturnSlot_getDouble(): Double @RetainForTarget("wasm32") @SymbolName("Kotlin_String_utf16pointer") external public fun stringPointer(message: String): Pointer @RetainForTarget("wasm32") @SymbolName("Kotlin_String_utf16length") external public fun stringLengthBytes(message: String): Int typealias KtFunction = ((ArrayList)->R) fun wrapFunction(func: KtFunction): Int { val ptr: Long = StableRef.create(func).asCPointer().toLong() return ptr.toInt() // TODO: LP64 unsafe. } @RetainForTarget("wasm32") @ExportForCppRuntime("Konan_js_runLambda") fun runLambda(pointer: Int, argumentsArena: Arena, argumentsArenaSize: Int): Int { val arguments = arrayListOf() for (i in 0 until argumentsArenaSize) { arguments.add(JsValue(argumentsArena, i)); } val previousArena = ArenaManager.currentArena ArenaManager.currentArena = argumentsArena // TODO: LP64 unsafe: wasm32 passes Int, not Long. val func = pointer.toLong().toCPointer()!!.asStableRef>().get() val result = func(arguments) ArenaManager.currentArena = previousArena return result.index } open class JsValue(val arena: Arena, val index: Object) { fun getInt(property: String): Int { return getInt(ArenaManager.currentArena, index, stringPointer(property), stringLengthBytes(property)) } fun getProperty(property: String): JsValue { return JsValue(ArenaManager.currentArena, Konan_js_getProperty(ArenaManager.currentArena, index, stringPointer(property), stringLengthBytes(property))) } } open class JsArray(arena: Arena, index: Object): JsValue(arena, index) { constructor(jsValue: JsValue): this(jsValue.arena, jsValue.index) operator fun get(index: Int): JsValue { // TODO: we could pass an integer index to index arrays. return getProperty(index.toString()) } val size: Int get() = this.getInt("length") } @RetainForTarget("wasm32") @SymbolName("Konan_js_getInt") external public fun getInt(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int; @RetainForTarget("wasm32") @SymbolName("Konan_js_getProperty") external public fun Konan_js_getProperty(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int; @RetainForTarget("wasm32") @SymbolName("Konan_js_setFunction") external public fun setFunction(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int , function: Int) @RetainForTarget("wasm32") @SymbolName("Konan_js_setString") external public fun setString(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int, stringPtr: Pointer, stringLength: Int ) fun setter(obj: JsValue, property: String, string: String) { setString(obj.arena, obj.index, stringPointer(property), stringLengthBytes(property), stringPointer(string), stringLengthBytes(string)) } fun setter(obj: JsValue, property: String, lambda: KtFunction) { val pointer = wrapFunction(lambda); setFunction(obj.arena, obj.index, stringPointer(property), stringLengthBytes(property), pointer) } fun JsValue.setter(property: String, lambda: KtFunction) { setter(this, property, lambda) } fun JsValue.setter(property: String, string: String) { setter(this, property, string) } object ArenaManager { val globalArena = allocateArena() @Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL") var currentArena = globalArena } ================================================ FILE: Interop/README.md ================================================ # Kotlin-native interop ## Usage Create file `../gradle.properties` with contents: llvmInstallPath=/path/to/llvm Create a Gradle subproject somewhere under `../`, using `../InteropExample` as a template. To generate the interop stubs and libraries and build all sources you can run the following command from `../`: ./gradlew InteropExample:build To run the example (if 'application' plugin is enabled): ./gradlew InteropExample:run ================================================ FILE: Interop/Runtime/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ apply plugin: 'kotlin' apply plugin: 'c' buildscript { ext.rootBuildDirectory = file('../..') apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } import org.jetbrains.kotlin.konan.target.ClangArgs model { components { callbacks(NativeLibrarySpec) { sources.c.source { srcDir 'src/callbacks/c' include '**/*.c' } binaries.all { def host = rootProject.ext.hostName def hostLibffiDir = rootProject.ext.get("${host}LibffiDir") cCompiler.args hostPlatform.clang.hostCompilerArgsForJni cCompiler.args "-I$hostLibffiDir/include" linker.args "$hostLibffiDir/lib/libffi.a" } } } toolChains { clang(Clang) { eachPlatform { cCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) } } } } repositories { maven { url buildKotlinCompilerRepo } } dependencies { compile project(":utilities:basic-utils") compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" } sourceSets.main.kotlin.srcDirs += "src/jvm/kotlin" compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xuse-experimental=kotlin.ExperimentalUnsignedTypes', '-Xuse-experimental=kotlin.Experimental', '-Xopt-in=kotlin.RequiresOptIn', '-Xinline-classes', '-Xskip-prerelease-check'] allWarningsAsErrors=true } } task nativelibs(type: Copy) { dependsOn 'callbacksSharedLibrary' from "$buildDir/libs/callbacks/shared/" into "$buildDir/nativelibs/" } classes.dependsOn nativelibs ================================================ FILE: Interop/Runtime/src/callbacks/c/callbacks.c ================================================ #include #include #include #include #include /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeVoid * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeVoid(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_void; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeUInt8 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeUInt8(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_uint8; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeSInt8 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeSInt8(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_sint8; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeUInt16 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeUInt16(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_uint16; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeSInt16 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeSInt16(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_sint16; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeUInt32 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeUInt32(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_uint32; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeSInt32 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeSInt32(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_sint32; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeUInt64 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeUInt64(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_uint64; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeSInt64 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeSInt64(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_sint64; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypePointer * Signature: ()J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypePointer(JNIEnv *env, jclass cls) { return (jlong) &ffi_type_pointer; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiTypeStruct0 * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiTypeStruct0(JNIEnv *env, jclass cls, jlong elements) { ffi_type* res = malloc(sizeof(ffi_type)); if (res != NULL) { res->size = 0; res->alignment = 0; res->elements = (ffi_type**) elements; res->type = FFI_TYPE_STRUCT; } return (jlong) res; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiCreateCif0 * Signature: (IJJ)J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiCreateCif0(JNIEnv *env, jclass cls, jint nArgs, jlong rType, jlong argTypes) { ffi_cif* res = malloc(sizeof(ffi_cif)); if (res != NULL) { ffi_status status = ffi_prep_cif(res, FFI_DEFAULT_ABI, nArgs, (ffi_type*)rType, (ffi_type**)argTypes); if (status != FFI_OK) { if (status == FFI_BAD_TYPEDEF) { return -(jlong)1; } else if (status == FFI_BAD_ABI) { return -(jlong)2; } else { return -(jlong)3; } } } return (jlong) res; } static JavaVM *vm = NULL; // Returns the JNI env which can be used by the caller. // If current thread is not attached to JVM, then it gets attached as daemon. static JNIEnv* getCurrentEnv() { JNIEnv* env; assert(vm != NULL); jint res = (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_1); if (res != JNI_OK) { assert(res == JNI_EDETACHED); res = (*vm)->AttachCurrentThreadAsDaemon(vm, (void**)&env, NULL); assert(res == JNI_OK); } return env; } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm_, void *reserved) { vm = vm_; return JNI_VERSION_1_1; } // Checks for pending exception. If there is one, describes it and terminates the process. static void checkException(JNIEnv *env) { if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionDescribe(env); abort(); } } static void ffi_fun(ffi_cif *cif, void *ret, void **args, void *user_data) { JNIEnv* env = getCurrentEnv(); static jmethodID acceptFun = NULL; static jclass cls = NULL; if (acceptFun == NULL) { // Note: in some cases [FindClass] below may use a classloader different from the one loaded interop classes, // so stick to JVM-provided class: jclass clsLocal = (*env)->FindClass(env, "java/util/function/LongConsumer"); checkException(env); assert(clsLocal != NULL); cls = (jclass) (*env)->NewGlobalRef(env, clsLocal); checkException(env); assert(cls != NULL); acceptFun = (*env)->GetMethodID(env, cls, "accept", "(J)V"); checkException(env); assert(acceptFun != NULL); } jlong retAndArgs[2] = { (jlong)ret, (jlong)args }; // Unpacked in [ffiClosureImpl]. (*env)->CallVoidMethod(env, (jobject) user_data, acceptFun, (jlong)(intptr_t)&retAndArgs[0]); checkException(env); } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: ffiCreateClosure0 * Signature: (JLjava/lang/Object;)J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_ffiCreateClosure0(JNIEnv *env, jclass cls, jlong ffiCif, jobject userData) { jobject userDataGlobalRef = (*env)->NewGlobalRef(env, userData); if (userDataGlobalRef == NULL) { return (jlong)0; } assert(sizeof(jobject) == sizeof(void*)); // TODO: check statically void* userDataPtr = (void*) userDataGlobalRef; void* res; ffi_closure *closure = ffi_closure_alloc(sizeof(ffi_closure), &res); if (closure == NULL) { return (jlong)0; } ffi_status status = ffi_prep_closure_loc(closure, (ffi_cif*)ffiCif, ffi_fun, userDataPtr, res); if (status != FFI_OK) { return -(jlong)1; } return (jlong) res; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: newGlobalRef * Signature: (Ljava/lang/Object;)J */ JNIEXPORT jlong JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_newGlobalRef(JNIEnv *env, jclass cls, jobject obj) { jobject res = (*env)->NewGlobalRef(env, obj); return (jlong) res; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: derefGlobalRef * Signature: (J)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_derefGlobalRef(JNIEnv *env, jclass cls, jlong ref) { return (jobject) ref; } /* * Class: kotlinx_cinterop_JvmCallbacksKt * Method: deleteGlobalRef * Signature: (J)V */ JNIEXPORT void JNICALL Java_kotlinx_cinterop_JvmCallbacksKt_deleteGlobalRef(JNIEnv *env, jclass cls, jlong ref) { (*env)->DeleteGlobalRef(env, (jobject) ref); } ================================================ FILE: Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmCallbacks.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import java.util.concurrent.ConcurrentHashMap import java.util.function.LongConsumer import kotlin.reflect.KClass import kotlin.reflect.KFunction import kotlin.reflect.KType import kotlin.reflect.full.companionObjectInstance import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.full.isSubclassOf import kotlin.reflect.jvm.reflect internal fun createStablePointer(any: Any): COpaquePointer = newGlobalRef(any).toCPointer()!! internal fun disposeStablePointer(pointer: COpaquePointer) = deleteGlobalRef(pointer.toLong()) @PublishedApi internal fun derefStablePointer(pointer: COpaquePointer): Any = derefGlobalRef(pointer.toLong()) private fun getFieldCType(type: KType): CType<*> { val classifier = type.classifier if (classifier is KClass<*> && classifier.isSubclassOf(CStructVar::class)) { return getStructCType(classifier) } return getArgOrRetValCType(type) } private fun getVariableCType(type: KType): CType<*>? { val classifier = type.classifier return when (classifier) { !is KClass<*> -> null ByteVarOf::class -> SInt8 ShortVarOf::class -> SInt16 IntVarOf::class -> SInt32 LongVarOf::class -> SInt64 CPointerVarOf::class -> Pointer // TODO: floats, enums. else -> if (classifier.isSubclassOf(CStructVar::class)) { getStructCType(classifier) } else { null } } } private val structTypeCache = ConcurrentHashMap, CType<*>>() private fun getStructCType(structClass: KClass<*>): CType<*> = structTypeCache.computeIfAbsent(structClass.java) { // Note that struct classes are not supposed to be user-defined, // so they don't require to be checked strictly. val annotations = structClass.annotations val cNaturalStruct = annotations.filterIsInstance().firstOrNull() ?: error("struct ${structClass.simpleName} has custom layout") val propertiesByName = structClass.declaredMemberProperties.groupBy { it.name } val fields = cNaturalStruct.fieldNames.map { propertiesByName[it]!!.single() } val fieldCTypes = mutableListOf>() for (field in fields) { val lengthAnnotation = field.annotations.filterIsInstance().firstOrNull() if (lengthAnnotation == null) { val fieldType = getFieldCType(field.returnType) fieldCTypes.add(fieldType) } else { assert(field.returnType.classifier == CPointer::class) val length = lengthAnnotation.value if (length != 0) { val pointed = field.returnType.arguments.single().type!! val pointedCType = getVariableCType(pointed) ?: TODO("array element type '$pointed'") // Represent array field as repeated element-typed fields: repeat(length) { fieldCTypes.add(pointedCType) } } } } @Suppress("DEPRECATION") val structType = structClass.companionObjectInstance as CVariable.Type Struct(structType.size, structType.align, fieldCTypes) } private fun getStructValueCType(type: KType): CType<*> { val structClass = type.arguments.singleOrNull()?.type?.classifier as? KClass<*> ?: error("'$type' type is incomplete") return getStructCType(structClass) } private fun getEnumCType(classifier: KClass<*>): CEnumType? { val rawValueType = classifier.declaredMemberProperties.single().returnType val rawValueCType = when (rawValueType.classifier) { Byte::class -> SInt8 Short::class -> SInt16 Int::class -> SInt32 Long::class -> SInt64 else -> error("'${classifier.simpleName}' has unexpected value type '$rawValueType'") } @Suppress("UNCHECKED_CAST") return CEnumType(rawValueCType as CType) } private fun getArgOrRetValCType(type: KType): CType<*> { val classifier = type.classifier val result = when (classifier) { !is KClass<*> -> null Unit::class -> Void Byte::class -> SInt8 Short::class -> SInt16 Int::class -> SInt32 Long::class -> SInt64 CPointer::class -> Pointer // TODO: floats CValue::class -> getStructValueCType(type) else -> if (classifier.isSubclassOf(@Suppress("DEPRECATION") CEnum::class)) { getEnumCType(classifier) } else { null } } ?: error("$type is not supported in callback signature") if (type.isMarkedNullable != (classifier == CPointer::class)) { if (type.isMarkedNullable) { error("$type must not be nullable when used in callback signature") } else { error("$type must be nullable when used in callback signature") } } return result } private fun createStaticCFunction(function: Function<*>): CPointer> { val errorMessage = "staticCFunction must take an unbound, non-capturing function" if (!isStatic(function)) { throw IllegalArgumentException(errorMessage) } val kFunction = function as? KFunction<*> ?: function.reflect() ?: throw IllegalArgumentException(errorMessage) val returnType = getArgOrRetValCType(kFunction.returnType) val paramTypes = kFunction.parameters.map { getArgOrRetValCType(it.type) } @Suppress("UNCHECKED_CAST") return interpretCPointer(createStaticCFunctionImpl(returnType as CType, paramTypes, function))!! } /** * Returns `true` if given function is *static* as defined in [staticCFunction]. */ private fun isStatic(function: Function<*>): Boolean { // TODO: revise try { with(function.javaClass.getDeclaredField("INSTANCE")) { if (!java.lang.reflect.Modifier.isStatic(modifiers) || !java.lang.reflect.Modifier.isFinal(modifiers)) { return false } isAccessible = true // TODO: undo return get(null) == function // If the class has static final "INSTANCE" field, and only the value of this field is accepted, // then each class is handled at most once, so these checks prevent memory leaks. } } catch (e: NoSuchFieldException) { return false } } private val createdStaticFunctions = ConcurrentHashMap, CPointer>>() @Suppress("UNCHECKED_CAST") internal fun > staticCFunctionImpl(function: F) = createdStaticFunctions.computeIfAbsent(function.javaClass) { createStaticCFunction(function) } as CPointer> private val invokeMethods = (0 .. 22).map { arity -> Class.forName("kotlin.jvm.functions.Function$arity").getMethod("invoke", *Array>(arity) { java.lang.Object::class.java }) } private fun createStaticCFunctionImpl( returnType: CType, paramTypes: List>, function: Function<*> ): NativePtr { val ffiCif = ffiCreateCif(returnType.ffiType, paramTypes.map { it.ffiType }) val arity = paramTypes.size val pt = paramTypes.toTypedArray() @Suppress("UNCHECKED_CAST") val impl: FfiClosureImpl = when (arity) { 0 -> { val f = function as () -> Any? ffiClosureImpl(returnType) { _ -> f() } } 1 -> { val f = function as (Any?) -> Any? ffiClosureImpl(returnType) { args -> f(pt.read(args, 0)) } } 2 -> { val f = function as (Any?, Any?) -> Any? ffiClosureImpl(returnType) { args -> f(pt.read(args, 0), pt.read(args, 1)) } } 3 -> { val f = function as (Any?, Any?, Any?) -> Any? ffiClosureImpl(returnType) { args -> f(pt.read(args, 0), pt.read(args, 1), pt.read(args, 2)) } } 4 -> { val f = function as (Any?, Any?, Any?, Any?) -> Any? ffiClosureImpl(returnType) { args -> f(pt.read(args, 0), pt.read(args, 1), pt.read(args, 2), pt.read(args, 3)) } } 5 -> { val f = function as (Any?, Any?, Any?, Any?, Any?) -> Any? ffiClosureImpl(returnType) { args -> f(pt.read(args, 0), pt.read(args, 1), pt.read(args, 2), pt.read(args, 3), pt.read(args, 4)) } } else -> { val invokeMethod = invokeMethods[arity] ffiClosureImpl(returnType) { args -> val arguments = Array(arity) { pt.read(args, it) } invokeMethod.invoke(function, *arguments) } } } return ffiCreateClosure(ffiCif, impl) } @Suppress("NOTHING_TO_INLINE") private inline fun Array>.read(args: CArrayPointer, index: Int) = this[index].read(args[index].rawValue) private inline fun ffiClosureImpl( returnType: CType, crossinline invoke: (args: CArrayPointer) -> Any? ): FfiClosureImpl { // Called through [ffi_fun] when a native function created with [ffiCreateClosure] is invoked. return LongConsumer { retAndArgsRaw -> val retAndArgs = retAndArgsRaw.toCPointer>()!! // Pointer to memory to be filled with return value of the invoked native function: val ret = retAndArgs[0]!! // Pointer to array of pointers to arguments passed to the invoked native function: val args = retAndArgs[1]!!.reinterpret() val result = invoke(args) returnType.write(ret.rawValue, result) } } /** * Describes the bridge between Kotlin type `T` and the corresponding C type of a function's parameter or return value. * It is supposed to be constructed using the primitive types (such as [SInt32]), the [Struct] combinator * and the [CEnumType] wrapper. * * This description omits the details that are irrelevant for the ABI. */ private abstract class CType internal constructor(val ffiType: ffi_type) { internal constructor(ffiTypePtr: Long) : this(interpretPointed(ffiTypePtr)) abstract fun read(location: NativePtr): T abstract fun write(location: NativePtr, value: T): Unit } private object Void : CType(ffiTypeVoid()) { override fun read(location: NativePtr) = throw UnsupportedOperationException() override fun write(location: NativePtr, value: Any?) { // nothing to do. } } private object SInt8 : CType(ffiTypeSInt8()) { override fun read(location: NativePtr) = interpretPointed(location).value override fun write(location: NativePtr, value: Byte) { interpretPointed(location).value = value } } private object SInt16 : CType(ffiTypeSInt16()) { override fun read(location: NativePtr) = interpretPointed(location).value override fun write(location: NativePtr, value: Short) { interpretPointed(location).value = value } } private object SInt32 : CType(ffiTypeSInt32()) { override fun read(location: NativePtr) = interpretPointed(location).value override fun write(location: NativePtr, value: Int) { interpretPointed(location).value = value } } private object SInt64 : CType(ffiTypeSInt64()) { override fun read(location: NativePtr) = interpretPointed(location).value override fun write(location: NativePtr, value: Long) { interpretPointed(location).value = value } } private object Pointer : CType?>(ffiTypePointer()) { override fun read(location: NativePtr) = interpretPointed>(location).value override fun write(location: NativePtr, value: CPointer<*>?) { interpretPointed>(location).value = value } } private class Struct(val size: Long, val align: Int, elementTypes: List>) : CType>( ffiTypeStruct( elementTypes.map { it.ffiType } ) ) { override fun read(location: NativePtr) = interpretPointed(location).readValue(size, align) override fun write(location: NativePtr, value: CValue<*>) = value.write(location) } @Suppress("DEPRECATION") private class CEnumType(private val rawValueCType: CType) : CType(rawValueCType.ffiType) { override fun read(location: NativePtr): CEnum { TODO("enum-typed callback parameters") } override fun write(location: NativePtr, value: CEnum) { rawValueCType.write(location, value.value) } } private typealias FfiClosureImpl = LongConsumer private typealias UserData = FfiClosureImpl private val topLevelInitializer = loadKonanLibrary("callbacks") /** * Reference to `ffi_type` struct instance. */ internal class ffi_type(rawPtr: NativePtr) : COpaque(rawPtr) /** * Reference to `ffi_cif` struct instance. */ internal class ffi_cif(rawPtr: NativePtr) : COpaque(rawPtr) private external fun ffiTypeVoid(): Long private external fun ffiTypeUInt8(): Long private external fun ffiTypeSInt8(): Long private external fun ffiTypeUInt16(): Long private external fun ffiTypeSInt16(): Long private external fun ffiTypeUInt32(): Long private external fun ffiTypeSInt32(): Long private external fun ffiTypeUInt64(): Long private external fun ffiTypeSInt64(): Long private external fun ffiTypePointer(): Long private external fun ffiTypeStruct0(elements: Long): Long /** * Allocates and initializes `ffi_type` describing the struct. * * @param elements types of the struct elements */ private fun ffiTypeStruct(elementTypes: List): ffi_type { val elements = nativeHeap.allocArrayOfPointersTo(*elementTypes.toTypedArray(), null) val res = ffiTypeStruct0(elements.rawValue) if (res == 0L) { throw OutOfMemoryError() } return interpretPointed(res) } private external fun ffiCreateCif0(nArgs: Int, rType: Long, argTypes: Long): Long /** * Creates and prepares an `ffi_cif`. * * @param returnType native function return value type * @param paramTypes native function parameter types * * @return the initialized `ffi_cif` */ private fun ffiCreateCif(returnType: ffi_type, paramTypes: List): ffi_cif { val nArgs = paramTypes.size val argTypes = nativeHeap.allocArrayOfPointersTo(*paramTypes.toTypedArray(), null) val res = ffiCreateCif0(nArgs, returnType.rawPtr, argTypes.rawValue) when (res) { 0L -> throw OutOfMemoryError() -1L -> throw Error("FFI_BAD_TYPEDEF") -2L -> throw Error("FFI_BAD_ABI") -3L -> throw Error("libffi error occurred") } return interpretPointed(res) } private external fun ffiCreateClosure0(ffiCif: Long, userData: Any): Long /** * Uses libffi to allocate a native function which will call [impl] when invoked. * * @param ffiCif describes the type of the function to create */ private fun ffiCreateClosure(ffiCif: ffi_cif, impl: FfiClosureImpl): NativePtr { val res = ffiCreateClosure0(ffiCif.rawPtr, userData = impl) when (res) { 0L -> throw OutOfMemoryError() -1L -> throw Error("libffi error occurred") } return res } private external fun newGlobalRef(any: Any): Long private external fun derefGlobalRef(ref: Long): Any private external fun deleteGlobalRef(ref: Long) ================================================ FILE: Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmNativeMem.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import org.jetbrains.kotlin.konan.util.nativeMemoryAllocator import sun.misc.Unsafe private val NativePointed.address: Long get() = this.rawPtr private enum class DataModel(val pointerSize: Long) { _32BIT(4), _64BIT(8) } private val dataModel: DataModel = when (System.getProperty("sun.arch.data.model")) { null -> TODO() "32" -> DataModel._32BIT "64" -> DataModel._64BIT else -> throw IllegalStateException() } // Must be only used in interop, contains host pointer size, not target! @PublishedApi internal val pointerSize: Int = dataModel.pointerSize.toInt() @PublishedApi internal object nativeMemUtils { fun getByte(mem: NativePointed) = unsafe.getByte(mem.address) fun putByte(mem: NativePointed, value: Byte) = unsafe.putByte(mem.address, value) fun getShort(mem: NativePointed) = unsafe.getShort(mem.address) fun putShort(mem: NativePointed, value: Short) = unsafe.putShort(mem.address, value) fun getInt(mem: NativePointed) = unsafe.getInt(mem.address) fun putInt(mem: NativePointed, value: Int) = unsafe.putInt(mem.address, value) fun getLong(mem: NativePointed) = unsafe.getLong(mem.address) fun putLong(mem: NativePointed, value: Long) = unsafe.putLong(mem.address, value) fun getFloat(mem: NativePointed) = unsafe.getFloat(mem.address) fun putFloat(mem: NativePointed, value: Float) = unsafe.putFloat(mem.address, value) fun getDouble(mem: NativePointed) = unsafe.getDouble(mem.address) fun putDouble(mem: NativePointed, value: Double) = unsafe.putDouble(mem.address, value) fun getNativePtr(mem: NativePointed): NativePtr = when (dataModel) { DataModel._32BIT -> getInt(mem).toLong() DataModel._64BIT -> getLong(mem) } fun putNativePtr(mem: NativePointed, value: NativePtr) = when (dataModel) { DataModel._32BIT -> putInt(mem, value.toInt()) DataModel._64BIT -> putLong(mem, value) } fun getByteArray(source: NativePointed, dest: ByteArray, length: Int) { unsafe.copyMemory(null, source.address, dest, byteArrayBaseOffset, length.toLong()) } fun putByteArray(source: ByteArray, dest: NativePointed, length: Int) { unsafe.copyMemory(source, byteArrayBaseOffset, null, dest.address, length.toLong()) } fun getCharArray(source: NativePointed, dest: CharArray, length: Int) { unsafe.copyMemory(null, source.address, dest, charArrayBaseOffset, length.toLong() * 2) } fun putCharArray(source: CharArray, dest: NativePointed, length: Int) { unsafe.copyMemory(source, charArrayBaseOffset, null, dest.address, length.toLong() * 2) } fun zeroMemory(dest: NativePointed, length: Int): Unit = unsafe.setMemory(dest.address, length.toLong(), 0) fun copyMemory(dest: NativePointed, length: Int, src: NativePointed) = unsafe.copyMemory(src.address, dest.address, length.toLong()) @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun allocateInstance(): T { return unsafe.allocateInstance(T::class.java) as T } internal fun allocRaw(size: Long, align: Int): NativePtr { val address = unsafe.allocateMemory(size) if (address % align != 0L) TODO(align.toString()) return address } internal fun freeRaw(mem: NativePtr) { unsafe.freeMemory(mem) } fun alloc(size: Long, align: Int) = interpretOpaquePointed(nativeMemoryAllocator.alloc(size, align)) fun free(mem: NativePtr) = nativeMemoryAllocator.free(mem) private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) { isAccessible = true return@with this.get(null) as Unsafe } private val byteArrayBaseOffset = unsafe.arrayBaseOffset(ByteArray::class.java).toLong() private val charArrayBaseOffset = unsafe.arrayBaseOffset(CharArray::class.java).toLong() } ================================================ FILE: Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmTypes.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import java.util.concurrent.ConcurrentHashMap import kotlin.reflect.full.companionObjectInstance typealias NativePtr = Long internal typealias NonNullNativePtr = NativePtr @PublishedApi internal fun NonNullNativePtr.toNativePtr() = this internal fun NativePtr.toNonNull(): NonNullNativePtr = this public val nativeNullPtr: NativePtr = 0L // TODO: the functions below should eventually be intrinsified @Suppress("DEPRECATION") private val typeOfCache = ConcurrentHashMap, CVariable.Type>() @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun typeOf() = @Suppress("DEPRECATION") typeOfCache.computeIfAbsent(T::class.java) { T::class.companionObjectInstance as CVariable.Type } /** * Returns interpretation of entity with given pointer, or `null` if it is null. * * @param T must not be abstract */ @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun interpretNullablePointed(ptr: NativePtr): T? { if (ptr == nativeNullPtr) { return null } else { val result = nativeMemUtils.allocateInstance() result.rawPtr = ptr return result } } /** * Creates a [CPointer] from the raw pointer of [NativePtr]. * * @return a [CPointer] representation, or `null` if the [rawValue] represents native `nullptr`. */ fun interpretCPointer(rawValue: NativePtr) = if (rawValue == nativeNullPtr) { null } else { CPointer(rawValue) } internal fun CPointer<*>.cPointerToString() = "CPointer(raw=0x%x)".format(rawValue) @Target(AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.RUNTIME) annotation class CLength(val value: Int) @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) annotation class CNaturalStruct(vararg val fieldNames: String) fun staticCFunction(function: () -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R): CPointer R>> = staticCFunctionImpl(function) fun staticCFunction(function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R): CPointer R>> = staticCFunctionImpl(function) ================================================ FILE: Interop/Runtime/src/jvm/kotlin/kotlinx/cinterop/JvmUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import org.jetbrains.kotlin.konan.util.KonanHomeProvider import java.io.File import java.nio.file.Files import java.nio.file.Paths private fun decodeFromUtf8(bytes: ByteArray) = String(bytes) internal fun encodeToUtf8(str: String) = str.toByteArray() internal fun CPointer.toKStringFromUtf8Impl(): String { val nativeBytes = this var length = 0 while (nativeBytes[length] != 0.toByte()) { ++length } val bytes = ByteArray(length) nativeMemUtils.getByteArray(nativeBytes.pointed, bytes, length) return decodeFromUtf8(bytes) } fun bitsToFloat(bits: Int): Float = java.lang.Float.intBitsToFloat(bits) fun bitsToDouble(bits: Long): Double = java.lang.Double.longBitsToDouble(bits) // TODO: the functions below should eventually be intrinsified inline fun Byte.signExtend(): R = when (R::class.java) { java.lang.Byte::class.java -> this.toByte() as R java.lang.Short::class.java -> this.toShort() as R java.lang.Integer::class.java -> this.toInt() as R java.lang.Long::class.java -> this.toLong() as R else -> this.invalidSignExtension() } inline fun Short.signExtend(): R = when (R::class.java) { java.lang.Short::class.java -> this.toShort() as R java.lang.Integer::class.java -> this.toInt() as R java.lang.Long::class.java -> this.toLong() as R else -> this.invalidSignExtension() } inline fun Int.signExtend(): R = when (R::class.java) { java.lang.Integer::class.java -> this.toInt() as R java.lang.Long::class.java -> this.toLong() as R else -> this.invalidSignExtension() } inline fun Long.signExtend(): R = when (R::class.java) { java.lang.Long::class.java -> this.toLong() as R else -> this.invalidSignExtension() } inline fun Number.invalidSignExtension(): R { throw Error("unable to sign extend ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}") } inline fun Byte.narrow(): R = when (R::class.java) { java.lang.Byte::class.java -> this.toByte() as R else -> this.invalidNarrowing() } inline fun Short.narrow(): R = when (R::class.java) { java.lang.Byte::class.java -> this.toByte() as R java.lang.Short::class.java -> this.toShort() as R else -> this.invalidNarrowing() } inline fun Int.narrow(): R = when (R::class.java) { java.lang.Byte::class.java -> this.toByte() as R java.lang.Short::class.java -> this.toShort() as R java.lang.Integer::class.java -> this.toInt() as R else -> this.invalidNarrowing() } inline fun Long.narrow(): R = when (R::class.java) { java.lang.Byte::class.java -> this.toByte() as R java.lang.Short::class.java -> this.toShort() as R java.lang.Integer::class.java -> this.toInt() as R java.lang.Long::class.java -> this.toLong() as R else -> this.invalidNarrowing() } inline fun Number.invalidNarrowing(): R { throw Error("unable to narrow ${this.javaClass.simpleName} \"${this}\" to ${R::class.java.simpleName}") } fun loadKonanLibrary(name: String) { try { System.loadLibrary(name) } catch (e: UnsatisfiedLinkError) { val fullLibraryName = System.mapLibraryName(name) val dir = "${KonanHomeProvider.determineKonanHome()}/konan/nativelib" try { System.load("$dir/$fullLibraryName") } catch (e: UnsatisfiedLinkError) { val tempDir = Files.createTempDirectory(Paths.get(dir), null).toAbsolutePath().toString() Files.createLink(Paths.get(tempDir, fullLibraryName), Paths.get(dir, fullLibraryName)) // TODO: Does not work on Windows. May be use FILE_FLAG_DELETE_ON_CLOSE? File(tempDir).deleteOnExit() File("$tempDir/$fullLibraryName").deleteOnExit() System.load("$tempDir/$fullLibraryName") } } } ================================================ FILE: Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Generated.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("FINAL_UPPER_BOUND", "NOTHING_TO_INLINE") package kotlinx.cinterop @JvmName("plus\$Byte") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 1) @JvmName("plus\$Byte") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Byte") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Byte") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Byte") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Byte") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$Short") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 2) @JvmName("plus\$Short") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Short") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Short") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Short") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Short") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$Int") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 4) @JvmName("plus\$Int") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Int") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Int") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Int") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Int") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$Long") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 8) @JvmName("plus\$Long") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Long") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Long") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Long") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Long") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$UByte") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 1) @JvmName("plus\$UByte") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$UByte") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$UShort") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 2) @JvmName("plus\$UShort") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$UShort") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$UShort") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$UInt") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 4) @JvmName("plus\$UInt") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$UInt") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$UInt") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$ULong") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 8) @JvmName("plus\$ULong") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$ULong") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$ULong") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$Float") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 4) @JvmName("plus\$Float") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Float") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Float") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Float") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Float") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } @JvmName("plus\$Double") inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * 8) @JvmName("plus\$Double") inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @JvmName("get\$Double") inline operator fun CPointer>.get(index: Int): T = (this + index)!!.pointed.value @JvmName("set\$Double") inline operator fun CPointer>.set(index: Int, value: T) { (this + index)!!.pointed.value = value } @JvmName("get\$Double") inline operator fun CPointer>.get(index: Long): T = (this + index)!!.pointed.value @JvmName("set\$Double") inline operator fun CPointer>.set(index: Long, value: T) { (this + index)!!.pointed.value = value } /* Generated by: #!/bin/bash function gen { echo "@JvmName(\"plus\\\$$1\")" echo "inline operator fun > CPointer?.plus(index: Long): CPointer? =" echo " interpretCPointer(this.rawValue + index * ${2})" echo echo "@JvmName(\"plus\\\$$1\")" echo "inline operator fun > CPointer?.plus(index: Int): CPointer? =" echo " this + index.toLong()" echo echo "@JvmName(\"get\\\$$1\")" echo "inline operator fun CPointer<${1}VarOf>.get(index: Int): T =" echo " (this + index)!!.pointed.value" echo echo "@JvmName(\"set\\\$$1\")" echo "inline operator fun CPointer<${1}VarOf>.set(index: Int, value: T) {" echo " (this + index)!!.pointed.value = value" echo '}' echo echo "@JvmName(\"get\\\$$1\")" echo "inline operator fun CPointer<${1}VarOf>.get(index: Long): T =" echo " (this + index)!!.pointed.value" echo echo "@JvmName(\"set\\\$$1\")" echo "inline operator fun CPointer<${1}VarOf>.set(index: Long, value: T) {" echo " (this + index)!!.pointed.value = value" echo '}' echo } gen Byte 1 gen Short 2 gen Int 4 gen Long 8 gen UByte 1 gen UShort 2 gen UInt 4 gen ULong 8 gen Float 4 gen Double 8 */ ================================================ FILE: Interop/Runtime/src/main/kotlin/kotlinx/cinterop/StableRef.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop @Deprecated("Use StableRef instead", ReplaceWith("StableRef"), DeprecationLevel.ERROR) typealias StableObjPtr = StableRef<*> /** * This class provides a way to create a stable handle to any Kotlin object. * After [converting to CPointer][asCPointer] it can be safely passed to native code e.g. to be received * in a Kotlin callback. * * Any [StableRef] should be manually [disposed][dispose] */ @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") public inline class StableRef @PublishedApi internal constructor( private val stablePtr: COpaquePointer ) { companion object { /** * Creates a handle for given object. */ fun create(any: T) = StableRef(createStablePointer(any)) /** * Creates [StableRef] from given raw value. * * @param value must be a [value] of some [StableRef] */ @Deprecated("Use CPointer<*>.asStableRef() instead", ReplaceWith("ptr.asStableRef()"), DeprecationLevel.ERROR) fun fromValue(value: COpaquePointer) = value.asStableRef() } @Deprecated("Use .asCPointer() instead", ReplaceWith("this.asCPointer()"), DeprecationLevel.ERROR) val value: COpaquePointer get() = this.asCPointer() /** * Converts the handle to C pointer. * @see [asStableRef] */ fun asCPointer(): COpaquePointer = this.stablePtr /** * Disposes the handle. It must not be used after that. */ fun dispose() { disposeStablePointer(this.stablePtr) } /** * Returns the object this handle was [created][StableRef.create] for. */ @Suppress("UNCHECKED_CAST") fun get() = derefStablePointer(this.stablePtr) as T } /** * Converts to [StableRef] this opaque pointer produced by [StableRef.asCPointer]. */ inline fun CPointer<*>.asStableRef(): StableRef = StableRef(this).also { it.get() } ================================================ FILE: Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop /** * The entity which has an associated native pointer. * Subtypes are supposed to represent interpretations of the pointed data or code. * * This interface is likely to be handled by compiler magic and shouldn't be subtyped by arbitrary classes. * * TODO: the behavior of [equals], [hashCode] and [toString] differs on Native and JVM backends. */ public open class NativePointed internal constructor(rawPtr: NonNullNativePtr) { var rawPtr = rawPtr.toNativePtr() internal set } // `null` value of `NativePointed?` is mapped to `nativeNullPtr`. public val NativePointed?.rawPtr: NativePtr get() = if (this != null) this.rawPtr else nativeNullPtr /** * Returns interpretation of entity with given pointer. * * @param T must not be abstract */ public inline fun interpretPointed(ptr: NativePtr): T = interpretNullablePointed(ptr)!! private class OpaqueNativePointed(rawPtr: NativePtr) : NativePointed(rawPtr.toNonNull()) public fun interpretOpaquePointed(ptr: NativePtr): NativePointed = interpretPointed(ptr) public fun interpretNullableOpaquePointed(ptr: NativePtr): NativePointed? = interpretNullablePointed(ptr) /** * Changes the interpretation of the pointed data or code. */ public inline fun NativePointed.reinterpret(): T = interpretPointed(this.rawPtr) /** * C data or code. */ public abstract class CPointed(rawPtr: NativePtr) : NativePointed(rawPtr.toNonNull()) /** * Represents a reference to (possibly empty) sequence of C values. * It can be either a stable pointer [CPointer] or a sequence of immutable values [CValues]. * * [CValuesRef] is designed to be used as Kotlin representation of pointer-typed parameters of C functions. * When passing [CPointer] as [CValuesRef] to the Kotlin binding method, the C function receives exactly this pointer. * Passing [CValues] has nearly the same semantics as passing by value: the C function receives * the pointer to the temporary copy of these values, and the caller can't observe the modifications to this copy. * The copy is valid until the C function returns. * There are also other implementations of [CValuesRef] that provide temporary pointer, * e.g. Kotlin Native specific [refTo] functions to pass primitive arrays directly to native. */ public abstract class CValuesRef { /** * If this reference is [CPointer], returns this pointer, otherwise * allocate storage value in the scope and return it. */ public abstract fun getPointer(scope: AutofreeScope): CPointer } /** * The (possibly empty) sequence of immutable C values. * It is self-contained and doesn't depend on native memory. */ public abstract class CValues : CValuesRef() { /** * Copies the values to [placement] and returns the pointer to the copy. */ public override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } // TODO: optimize public override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is CValues<*>) return false val thisBytes = this.getBytes() val otherBytes = other.getBytes() if (thisBytes.size != otherBytes.size) { return false } for (index in 0 .. thisBytes.size - 1) { if (thisBytes[index] != otherBytes[index]) { return false } } return true } public override fun hashCode(): Int { var result = 0 for (byte in this.getBytes()) { result = result * 31 + byte } return result } public abstract val size: Int public abstract val align: Int /** * Copy the referenced values to [placement] and return placement pointer. */ public abstract fun place(placement: CPointer): CPointer } public fun CValues.placeTo(scope: AutofreeScope) = this.getPointer(scope) /** * The single immutable C value. * It is self-contained and doesn't depend on native memory. * * TODO: consider providing an adapter instead of subtyping [CValues]. */ public abstract class CValue : CValues() /** * C pointer. */ public class CPointer internal constructor(@PublishedApi internal val value: NonNullNativePtr) : CValuesRef() { // TODO: replace by [value]. @Suppress("NOTHING_TO_INLINE") public inline val rawValue: NativePtr get() = value.toNativePtr() public override fun equals(other: Any?): Boolean { if (this === other) { return true // fast path } return (other is CPointer<*>) && (rawValue == other.rawValue) } public override fun hashCode(): Int { return rawValue.hashCode() } public override fun toString() = this.cPointerToString() public override fun getPointer(scope: AutofreeScope) = this } /** * Returns the pointer to this data or code. */ public val T.ptr: CPointer get() = interpretCPointer(this.rawPtr)!! /** * Returns the corresponding [CPointed]. * * @param T must not be abstract */ public inline val CPointer.pointed: T get() = interpretPointed(this.rawValue) // `null` value of `CPointer?` is mapped to `nativeNullPtr` public val CPointer<*>?.rawValue: NativePtr get() = if (this != null) this.rawValue else nativeNullPtr public fun CPointer<*>.reinterpret(): CPointer = interpretCPointer(this.rawValue)!! public fun CPointer?.toLong() = this.rawValue.toLong() public fun Long.toCPointer(): CPointer? = interpretCPointer(nativeNullPtr + this) /** * The [CPointed] without any specified interpretation. */ public abstract class COpaque(rawPtr: NativePtr) : CPointed(rawPtr) // TODO: should it correspond to COpaquePointer? /** * The pointer with an opaque type. */ public typealias COpaquePointer = CPointer // FIXME /** * The variable containing a [COpaquePointer]. */ public typealias COpaquePointerVar = CPointerVarOf /** * The C data variable located in memory. * * The non-abstract subclasses should represent the (complete) C data type and thus specify size and alignment. * Each such subclass must have a companion object which is a [Type]. */ public abstract class CVariable(rawPtr: NativePtr) : CPointed(rawPtr) { /** * The (complete) C data type. * * @param size the size in bytes of data of this type * @param align the alignments in bytes that is enough for this data type. * It may be greater than actually required for simplicity. */ @Deprecated("Use sizeOf() or alignOf() instead.") public open class Type(val size: Long, val align: Int) { init { require(size % align == 0L) } } } @Suppress("DEPRECATION") public inline fun sizeOf() = typeOf().size @Suppress("DEPRECATION") public inline fun alignOf() = typeOf().align /** * Returns the member of this [CStructVar] which is located by given offset in bytes. */ public inline fun CStructVar.memberAt(offset: Long): T { return interpretPointed(this.rawPtr + offset) } public inline fun CStructVar.arrayMemberAt(offset: Long): CArrayPointer { return interpretCPointer(this.rawPtr + offset)!! } /** * The C struct-typed variable located in memory. */ public abstract class CStructVar(rawPtr: NativePtr) : CVariable(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") open class Type(size: Long, align: Int) : CVariable.Type(size, align) } /** * The C primitive-typed variable located in memory. */ sealed class CPrimitiveVar(rawPtr: NativePtr) : CVariable(rawPtr) { // aligning by size is obviously enough @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") open class Type(size: Int) : CVariable.Type(size.toLong(), align = size) } @Deprecated("Will be removed.") public interface CEnum { public val value: Any } public abstract class CEnumVar(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) // generics below are used for typedef support // these classes are not supposed to be used directly, instead the typealiases are provided. @Suppress("FINAL_UPPER_BOUND") public class BooleanVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(1) } @Suppress("FINAL_UPPER_BOUND") public class ByteVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(1) } @Suppress("FINAL_UPPER_BOUND") public class ShortVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(2) } @Suppress("FINAL_UPPER_BOUND") public class IntVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(4) } @Suppress("FINAL_UPPER_BOUND") public class LongVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(8) } @Suppress("FINAL_UPPER_BOUND") public class UByteVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(1) } @Suppress("FINAL_UPPER_BOUND") public class UShortVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(2) } @Suppress("FINAL_UPPER_BOUND") public class UIntVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(4) } @Suppress("FINAL_UPPER_BOUND") public class ULongVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(8) } @Suppress("FINAL_UPPER_BOUND") public class FloatVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(4) } @Suppress("FINAL_UPPER_BOUND") public class DoubleVarOf(rawPtr: NativePtr) : CPrimitiveVar(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(8) } public typealias BooleanVar = BooleanVarOf public typealias ByteVar = ByteVarOf public typealias ShortVar = ShortVarOf public typealias IntVar = IntVarOf public typealias LongVar = LongVarOf public typealias UByteVar = UByteVarOf public typealias UShortVar = UShortVarOf public typealias UIntVar = UIntVarOf public typealias ULongVar = ULongVarOf public typealias FloatVar = FloatVarOf public typealias DoubleVar = DoubleVarOf @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var BooleanVarOf.value: T get() { val byte = nativeMemUtils.getByte(this) return byte.toBoolean() as T } set(value) = nativeMemUtils.putByte(this, value.toByte()) @Suppress("NOTHING_TO_INLINE") public inline fun Boolean.toByte(): Byte = if (this) 1 else 0 @Suppress("NOTHING_TO_INLINE") public inline fun Byte.toBoolean() = (this.toInt() != 0) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var ByteVarOf.value: T get() = nativeMemUtils.getByte(this) as T set(value) = nativeMemUtils.putByte(this, value) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var ShortVarOf.value: T get() = nativeMemUtils.getShort(this) as T set(value) = nativeMemUtils.putShort(this, value) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var IntVarOf.value: T get() = nativeMemUtils.getInt(this) as T set(value) = nativeMemUtils.putInt(this, value) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var LongVarOf.value: T get() = nativeMemUtils.getLong(this) as T set(value) = nativeMemUtils.putLong(this, value) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var UByteVarOf.value: T get() = nativeMemUtils.getByte(this).toUByte() as T set(value) = nativeMemUtils.putByte(this, value.toByte()) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var UShortVarOf.value: T get() = nativeMemUtils.getShort(this).toUShort() as T set(value) = nativeMemUtils.putShort(this, value.toShort()) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var UIntVarOf.value: T get() = nativeMemUtils.getInt(this).toUInt() as T set(value) = nativeMemUtils.putInt(this, value.toInt()) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var ULongVarOf.value: T get() = nativeMemUtils.getLong(this).toULong() as T set(value) = nativeMemUtils.putLong(this, value.toLong()) // TODO: ensure native floats have the appropriate binary representation @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var FloatVarOf.value: T get() = nativeMemUtils.getFloat(this) as T set(value) = nativeMemUtils.putFloat(this, value) @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var DoubleVarOf.value: T get() = nativeMemUtils.getDouble(this) as T set(value) = nativeMemUtils.putDouble(this, value) public class CPointerVarOf>(rawPtr: NativePtr) : CVariable(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : CVariable.Type(pointerSize.toLong(), pointerSize) } /** * The C data variable containing the pointer to `T`. */ public typealias CPointerVar = CPointerVarOf> /** * The value of this variable. */ @Suppress("UNCHECKED_CAST") public inline var

> CPointerVarOf

.value: P? get() = interpretCPointer(nativeMemUtils.getNativePtr(this)) as P? set(value) = nativeMemUtils.putNativePtr(this, value.rawValue) /** * The code or data pointed by the value of this variable. * * @param T must not be abstract */ public inline var > CPointerVarOf

.pointed: T? get() = this.value?.pointed set(value) { this.value = value?.ptr as P? } public inline operator fun CPointer.get(index: Long): T { val offset = if (index == 0L) { 0L // optimization for JVM impl which uses reflection for now. } else { index * sizeOf() } return interpretPointed(this.rawValue + offset) } public inline operator fun CPointer.get(index: Int): T = this.get(index.toLong()) @Suppress("NOTHING_TO_INLINE") @JvmName("plus\$CPointer") public inline operator fun > CPointer?.plus(index: Long): CPointer? = interpretCPointer(this.rawValue + index * pointerSize) @Suppress("NOTHING_TO_INLINE") @JvmName("plus\$CPointer") public inline operator fun > CPointer?.plus(index: Int): CPointer? = this + index.toLong() @Suppress("NOTHING_TO_INLINE") public inline operator fun > CPointer>.get(index: Int): T? = (this + index)!!.pointed.value @Suppress("NOTHING_TO_INLINE") public inline operator fun > CPointer>.set(index: Int, value: T?) { (this + index)!!.pointed.value = value } @Suppress("NOTHING_TO_INLINE") public inline operator fun > CPointer>.get(index: Long): T? = (this + index)!!.pointed.value @Suppress("NOTHING_TO_INLINE") public inline operator fun > CPointer>.set(index: Long, value: T?) { (this + index)!!.pointed.value = value } public typealias CArrayPointer = CPointer public typealias CArrayPointerVar = CPointerVar /** * The C function. */ public class CFunction>(rawPtr: NativePtr) : CPointed(rawPtr) ================================================ FILE: Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop public interface NativePlacement { public fun alloc(size: Long, align: Int): NativePointed public fun alloc(size: Int, align: Int): NativePointed = alloc(size.toLong(), align) } public interface NativeFreeablePlacement : NativePlacement { public fun free(mem: NativePtr) } public fun NativeFreeablePlacement.free(pointer: CPointer<*>) = this.free(pointer.rawValue) public fun NativeFreeablePlacement.free(pointed: NativePointed) = this.free(pointed.rawPtr) public object nativeHeap : NativeFreeablePlacement { override fun alloc(size: Long, align: Int) = nativeMemUtils.alloc(size, align) override fun free(mem: NativePtr) = nativeMemUtils.free(mem) } private typealias Deferred = () -> Unit public open class DeferScope { @PublishedApi internal var topDeferred: Deferred? = null internal fun executeAllDeferred() { topDeferred?.let { it.invoke() topDeferred = null } } inline fun defer(crossinline block: () -> Unit) { val currentTop = topDeferred topDeferred = { try { block() } finally { // TODO: it is possible to implement chaining without recursion, // but it would require using an anonymous object here // which is not yet supported in Kotlin Native inliner. currentTop?.invoke() } } } } public abstract class AutofreeScope : DeferScope(), NativePlacement { abstract override fun alloc(size: Long, align: Int): NativePointed } public open class ArenaBase(private val parent: NativeFreeablePlacement = nativeHeap) : AutofreeScope() { private var lastChunk: NativePointed? = null final override fun alloc(size: Long, align: Int): NativePointed { // Reserve space for a pointer: val gapForPointer = maxOf(pointerSize, align) val chunk = parent.alloc(size = gapForPointer + size, align = gapForPointer) nativeMemUtils.putNativePtr(chunk, lastChunk.rawPtr) lastChunk = chunk return interpretOpaquePointed(chunk.rawPtr + gapForPointer.toLong()) } @PublishedApi internal fun clearImpl() { this.executeAllDeferred() var chunk = lastChunk while (chunk != null) { val nextChunk = nativeMemUtils.getNativePtr(chunk) parent.free(chunk) chunk = interpretNullableOpaquePointed(nextChunk) } } } public class Arena(parent: NativeFreeablePlacement = nativeHeap) : ArenaBase(parent) { fun clear() = this.clearImpl() } /** * Allocates variable of given type. * * @param T must not be abstract */ public inline fun NativePlacement.alloc(): T = @Suppress("DEPRECATION") alloc(typeOf()).reinterpret() @PublishedApi @Suppress("DEPRECATION") internal fun NativePlacement.alloc(type: CVariable.Type): NativePointed = alloc(type.size, type.align) /** * Allocates variable of given type and initializes it applying given block. * * @param T must not be abstract */ public inline fun NativePlacement.alloc(initialize: T.() -> Unit): T = alloc().also { it.initialize() } /** * Allocates C array of given elements type and length. * * @param T must not be abstract */ public inline fun NativePlacement.allocArray(length: Long): CArrayPointer = alloc(sizeOf() * length, alignOf()).reinterpret().ptr /** * Allocates C array of given elements type and length. * * @param T must not be abstract */ public inline fun NativePlacement.allocArray(length: Int): CArrayPointer = allocArray(length.toLong()) /** * Allocates C array of given elements type and length, and initializes its elements applying given block. * * @param T must not be abstract */ public inline fun NativePlacement.allocArray(length: Long, initializer: T.(index: Long)->Unit): CArrayPointer { val res = allocArray(length) (0 .. length - 1).forEach { index -> res[index].initializer(index) } return res } /** * Allocates C array of given elements type and length, and initializes its elements applying given block. * * @param T must not be abstract */ public inline fun NativePlacement.allocArray( length: Int, initializer: T.(index: Int)->Unit): CArrayPointer = allocArray(length.toLong()) { index -> this.initializer(index.toInt()) } /** * Allocates C array of pointers to given elements. */ public fun NativePlacement.allocArrayOfPointersTo(elements: List): CArrayPointer> { val res = allocArray>(elements.size) elements.forEachIndexed { index, value -> res[index] = value?.ptr } return res } /** * Allocates C array of pointers to given elements. */ public fun NativePlacement.allocArrayOfPointersTo(vararg elements: T?) = allocArrayOfPointersTo(listOf(*elements)) /** * Allocates C array of given values. */ public inline fun > NativePlacement.allocArrayOf(vararg elements: T?): CArrayPointer> { return allocArrayOf(listOf(*elements)) } /** * Allocates C array of given values. */ public inline fun > NativePlacement.allocArrayOf(elements: List): CArrayPointer> { val res = allocArray>(elements.size) var index = 0 while (index < elements.size) { res[index] = elements[index] ++index } return res } public fun NativePlacement.allocArrayOf(elements: ByteArray): CArrayPointer { val result = allocArray(elements.size) nativeMemUtils.putByteArray(elements, result.pointed, elements.size) return result } public fun NativePlacement.allocArrayOf(vararg elements: Float): CArrayPointer { val res = allocArray(elements.size) var index = 0 while (index < elements.size) { res[index] = elements[index] ++index } return res } public fun NativePlacement.allocPointerTo() = alloc>() @PublishedApi internal class ZeroValue(private val sizeBytes: Int, private val alignBytes: Int): CValue() { // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { nativeMemUtils.zeroMemory(interpretPointed(placement.rawValue), sizeBytes) return placement } override val size get() = sizeBytes override val align get() = alignBytes } @Suppress("NOTHING_TO_INLINE") public inline fun zeroValue(size: Int, align: Int): CValue = ZeroValue(size, align) public inline fun zeroValue(): CValue = zeroValue(sizeOf().toInt(), alignOf()) public inline fun cValue(): CValue = zeroValue() public fun CPointed.readValues(size: Int, align: Int): CValues { val bytes = ByteArray(size) nativeMemUtils.getByteArray(this, bytes, size) return object : CValue() { // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { nativeMemUtils.putByteArray(bytes, interpretPointed(placement.rawValue), bytes.size) return placement } override val size get() = size override val align get() = align } } public inline fun T.readValues(count: Int): CValues = this.readValues(size = count * sizeOf().toInt(), align = alignOf()) public fun CPointed.readValue(size: Long, align: Int): CValue { val bytes = ByteArray(size.toInt()) nativeMemUtils.getByteArray(this, bytes, size.toInt()) return object : CValue() { override fun place(placement: CPointer): CPointer { nativeMemUtils.putByteArray(bytes, interpretPointed(placement.rawValue), bytes.size) return placement } // Optimization to avoid unneeded virtual calls in base class implementation. public override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override val size get() = size.toInt() override val align get() = align } } @Suppress("DEPRECATION") @PublishedApi internal fun CPointed.readValue(type: CVariable.Type): CValue = readValue(type.size, type.align) // Note: can't be declared as property due to possible clash with a struct field. // TODO: find better name. @Suppress("DEPRECATION") public inline fun T.readValue(): CValue = this.readValue(typeOf()) public fun CValue.write(location: NativePtr) { this.place(interpretCPointer(location)!!) } // TODO: optimize public fun CValues.getBytes(): ByteArray = memScoped { val result = ByteArray(size) nativeMemUtils.getByteArray( source = this@getBytes.placeTo(memScope).reinterpret().pointed, dest = result, length = result.size ) result } /** * Calls the [block] with temporary copy of this value as receiver. */ public inline fun CValue.useContents(block: T.() -> R): R = memScoped { this@useContents.placeTo(memScope).pointed.block() } public inline fun CValue.copy(modify: T.() -> Unit): CValue = useContents { this.modify() this.readValue() } public inline fun cValue(initialize: T.() -> Unit): CValue = zeroValue().copy(modify = initialize) public inline fun createValues(count: Int, initializer: T.(index: Int) -> Unit) = memScoped { val array = allocArray(count, initializer) array[0].readValues(count) } // TODO: optimize other [cValuesOf] methods: /** * Returns sequence of immutable values [CValues] to pass them to C code. */ fun cValuesOf(vararg elements: Byte): CValues = object : CValues() { // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { nativeMemUtils.putByteArray(elements, interpretPointed(placement.rawValue), elements.size) return placement } override val size get() = 1 * elements.size override val align get() = 1 } public fun cValuesOf(vararg elements: Short): CValues = createValues(elements.size) { index -> this.value = elements[index] } public fun cValuesOf(vararg elements: Int): CValues = createValues(elements.size) { index -> this.value = elements[index] } public fun cValuesOf(vararg elements: Long): CValues = createValues(elements.size) { index -> this.value = elements[index] } public fun cValuesOf(vararg elements: Float): CValues = createValues(elements.size) { index -> this.value = elements[index] } public fun cValuesOf(vararg elements: Double): CValues = createValues(elements.size) { index -> this.value = elements[index] } public fun cValuesOf(vararg elements: CPointer?): CValues> = createValues(elements.size) { index -> this.value = elements[index] } public fun ByteArray.toCValues() = cValuesOf(*this) public fun ShortArray.toCValues() = cValuesOf(*this) public fun IntArray.toCValues() = cValuesOf(*this) public fun LongArray.toCValues() = cValuesOf(*this) public fun FloatArray.toCValues() = cValuesOf(*this) public fun DoubleArray.toCValues() = cValuesOf(*this) public fun Array?>.toCValues() = cValuesOf(*this) public fun List?>.toCValues() = this.toTypedArray().toCValues() private class CString(val bytes: ByteArray): CValues() { override val size get() = bytes.size + 1 override val align get() = 1 // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { nativeMemUtils.putByteArray(bytes, placement.pointed, bytes.size) placement[bytes.size] = 0.toByte() return placement } } private object EmptyCString: CValues() { override val size get() = 1 override val align get() = 1 private val placement = interpretCPointer(nativeMemUtils.allocRaw(1, 1))!!.also { it[0] = 0.toByte() } override fun getPointer(scope: AutofreeScope): CPointer { return placement } override fun place(placement: CPointer): CPointer { placement[0] = 0.toByte() return placement } } /** * @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String]. */ public val String.cstr: CValues get() = if (isEmpty()) EmptyCString else CString(encodeToUtf8(this)) /** * @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String]. */ public val String.utf8: CValues get() = CString(encodeToUtf8(this)) /** * Convert this list of Kotlin strings to C array of C strings, * allocating memory for the array and C strings with given [AutofreeScope]. */ public fun List.toCStringArray(autofreeScope: AutofreeScope): CPointer> = autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) }) /** * Convert this array of Kotlin strings to C array of C strings, * allocating memory for the array and C strings with given [AutofreeScope]. */ public fun Array.toCStringArray(autofreeScope: AutofreeScope): CPointer> = autofreeScope.allocArrayOf(this.map { it.cstr.getPointer(autofreeScope) }) private class U16CString(val chars: CharArray): CValues() { override val size get() = 2 * (chars.size + 1) override val align get() = 2 // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { nativeMemUtils.putCharArray(chars, placement.pointed, chars.size) // TODO: fix, after KT-29627 is fixed. nativeMemUtils.putShort((placement + chars.size)!!.pointed, 0) return placement } } /** * @return the value of zero-terminated UTF-16-encoded C string constructed from given [kotlin.String]. */ public val String.wcstr: CValues get() = U16CString(this.toCharArray()) /** * @return the value of zero-terminated UTF-16-encoded C string constructed from given [kotlin.String]. */ public val String.utf16: CValues get() = U16CString(this.toCharArray()) private class U32CString(val chars: CharArray): CValues() { override val size get() = 4 * (chars.size + 1) override val align get() = 4 // Optimization to avoid unneeded virtual calls in base class implementation. override fun getPointer(scope: AutofreeScope): CPointer { return place(interpretCPointer(scope.alloc(size, align).rawPtr)!!) } override fun place(placement: CPointer): CPointer { var indexIn = 0 var indexOut = 0 while (indexIn < chars.size) { var value = chars[indexIn++].toInt() if (value >= 0xd800 && value < 0xdc00) { // Surrogate pair. if (indexIn >= chars.size - 1) throw IllegalArgumentException() indexIn++ val next = chars[indexIn].toInt() if (next < 0xdc00 || next >= 0xe000) throw IllegalArgumentException() value = 0x10000 + ((value and 0x3ff) shl 10) + (next and 0x3ff) } nativeMemUtils.putInt((placement + indexOut)!!.pointed, value) indexOut++ } nativeMemUtils.putInt((placement + indexOut)!!.pointed, 0) return placement } } /** * @return the value of zero-terminated UTF-32-encoded C string constructed from given [kotlin.String]. */ public val String.utf32: CValues get() = U32CString(this.toCharArray()) // TODO: optimize /** * @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string. */ public fun CPointer.toKStringFromUtf8(): String = this.toKStringFromUtf8Impl() /** * @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string. */ public fun CPointer.toKString(): String = this.toKStringFromUtf8() /** * @return the [kotlin.String] decoded from given zero-terminated UTF-16-encoded C string. */ public fun CPointer.toKStringFromUtf16(): String { val nativeBytes = this var length = 0 while (nativeBytes[length] != 0.toShort()) { ++length } val chars = CharArray(length) var index = 0 while (index < length) { chars[index] = nativeBytes[index].toChar() ++index } return chars.concatToString() } /** * @return the [kotlin.String] decoded from given zero-terminated UTF-32-encoded C string. */ public fun CPointer.toKStringFromUtf32(): String { val nativeBytes = this var fromIndex = 0 var toIndex = 0 while (true) { val value = nativeBytes[fromIndex++] if (value == 0) break toIndex++ if (value >= 0x10000 && value <= 0x10ffff) { toIndex++ } } val length = toIndex val chars = CharArray(length) fromIndex = 0 toIndex = 0 while (toIndex < length) { var value = nativeBytes[fromIndex++] if (value >= 0x10000 && value <= 0x10ffff) { chars[toIndex++] = (((value - 0x10000) shr 10) or 0xd800).toChar() chars[toIndex++] = (((value - 0x10000) and 0x3ff) or 0xdc00).toChar() } else { chars[toIndex++] = value.toChar() } } return chars.concatToString() } /** * Decodes a string from the bytes in UTF-8 encoding in this array. * Bytes following the first occurrence of `0` byte, if it occurs, are not decoded. * * Malformed byte sequences are replaced by the replacement char `\uFFFD`. */ @OptIn(ExperimentalStdlibApi::class) @SinceKotlin("1.3") public fun ByteArray.toKString() : String { val realEndIndex = realEndIndex(this, 0, this.size) return decodeToString(0, realEndIndex) } /** * Decodes a string from the bytes in UTF-8 encoding in this array or its subrange. * Bytes following the first occurrence of `0` byte, if it occurs, are not decoded. * * @param startIndex the beginning (inclusive) of the subrange to decode, 0 by default. * @param endIndex the end (exclusive) of the subrange to decode, size of this array by default. * @param throwOnInvalidSequence specifies whether to throw an exception on malformed byte sequence or replace it by the replacement char `\uFFFD`. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. * @throws CharacterCodingException if the byte array contains malformed UTF-8 byte sequence and [throwOnInvalidSequence] is true. */ @OptIn(ExperimentalStdlibApi::class) @SinceKotlin("1.3") public fun ByteArray.toKString( startIndex: Int = 0, endIndex: Int = this.size, throwOnInvalidSequence: Boolean = false ) : String { checkBoundsIndexes(startIndex, endIndex, this.size) val realEndIndex = realEndIndex(this, startIndex, endIndex) return decodeToString(startIndex, realEndIndex, throwOnInvalidSequence) } private fun realEndIndex(byteArray: ByteArray, startIndex: Int, endIndex: Int): Int { var index = startIndex while (index < endIndex && byteArray[index] != 0.toByte()) { index++ } return index } private fun checkBoundsIndexes(startIndex: Int, endIndex: Int, size: Int) { if (startIndex < 0 || endIndex > size) { throw IndexOutOfBoundsException("startIndex: $startIndex, endIndex: $endIndex, size: $size") } if (startIndex > endIndex) { throw IllegalArgumentException("startIndex: $startIndex > endIndex: $endIndex") } } public class MemScope : ArenaBase() { val memScope: MemScope get() = this val CValues.ptr: CPointer get() = this@ptr.getPointer(this@MemScope) } // TODO: consider renaming `memScoped` because it now supports `defer`. /** * Runs given [block] providing allocation of memory * which will be automatically disposed at the end of this scope. */ public inline fun memScoped(block: MemScope.()->R): R { val memScope = MemScope() try { return memScope.block() } finally { memScope.clearImpl() } } public fun COpaquePointer.readBytes(count: Int): ByteArray { val result = ByteArray(count) nativeMemUtils.getByteArray(this.reinterpret().pointed, result, count) return result } ================================================ FILE: Interop/Runtime/src/main/kotlin/kotlinx/cinterop/package-info.java ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This package contains API and runtime support for calling C code from Kotlin (aka Kotlin C interop). * * TODO: decide about package location. */ package kotlinx.cinterop; ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ForeignException.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cinterop import kotlin.native.internal.ExportForCppRuntime public class ForeignException internal constructor(val nativeException: Any?): Exception() { override val message: String = nativeException?.let { kotlin_ObjCExport_ExceptionDetails(nativeException) }?: "" // Current implementation expects NSException type only, which is ensured by CodeGenerator. @SymbolName("Kotlin_ObjCExport_ExceptionDetails") private external fun kotlin_ObjCExport_ExceptionDetails(nativeException: Any): String? } @ExportForCppRuntime internal fun CreateForeignException(payload: NativePtr): Throwable = ForeignException(interpretObjCPointerOrNull(payload)) ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/FunctionPointers.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType import kotlin.native.internal.ExportForCompiler @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21): R @TypedIntrinsic(IntrinsicType.INTEROP_FUNPTR_INVOKE) external operator fun CPointer R>>.invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeMem.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.* import kotlin.native.internal.Intrinsic import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType @PublishedApi internal inline val pointerSize: Int get() = getPointerSize() @PublishedApi @TypedIntrinsic(IntrinsicType.INTEROP_GET_POINTER_SIZE) internal external fun getPointerSize(): Int // TODO: do not use singleton because it leads to init-check on any access. @PublishedApi internal object nativeMemUtils { @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getByte(mem: NativePointed): Byte @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putByte(mem: NativePointed, value: Byte) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getShort(mem: NativePointed): Short @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putShort(mem: NativePointed, value: Short) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getInt(mem: NativePointed): Int @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putInt(mem: NativePointed, value: Int) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getLong(mem: NativePointed): Long @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putLong(mem: NativePointed, value: Long) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getFloat(mem: NativePointed): Float @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putFloat(mem: NativePointed, value: Float) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getDouble(mem: NativePointed): Double @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putDouble(mem: NativePointed, value: Double) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getNativePtr(mem: NativePointed): NativePtr @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putNativePtr(mem: NativePointed, value: NativePtr) @TypedIntrinsic(IntrinsicType.INTEROP_READ_PRIMITIVE) external fun getVector(mem: NativePointed): Vector128 @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_PRIMITIVE) external fun putVector(mem: NativePointed, value: Vector128) // TODO: optimize fun getByteArray(source: NativePointed, dest: ByteArray, length: Int) { val sourceArray = source.reinterpret().ptr var index = 0 while (index < length) { dest[index] = sourceArray[index] ++index } } // TODO: optimize fun putByteArray(source: ByteArray, dest: NativePointed, length: Int) { val destArray = dest.reinterpret().ptr var index = 0 while (index < length) { destArray[index] = source[index] ++index } } // TODO: optimize fun getCharArray(source: NativePointed, dest: CharArray, length: Int) { val sourceArray = source.reinterpret().ptr var index = 0 while (index < length) { dest[index] = sourceArray[index].toChar() ++index } } // TODO: optimize fun putCharArray(source: CharArray, dest: NativePointed, length: Int) { val destArray = dest.reinterpret().ptr var index = 0 while (index < length) { destArray[index] = source[index].toShort() ++index } } // TODO: optimize fun zeroMemory(dest: NativePointed, length: Int): Unit { val destArray = dest.reinterpret().ptr var index = 0 while (index < length) { destArray[index] = 0 ++index } } // TODO: optimize fun copyMemory(dest: NativePointed, length: Int, src: NativePointed): Unit { val destArray = dest.reinterpret().ptr val srcArray = src.reinterpret().ptr var index = 0 while (index < length) { destArray[index] = srcArray[index] ++index } } fun alloc(size: Long, align: Int): NativePointed { return interpretOpaquePointed(allocRaw(size, align)) } fun free(mem: NativePtr) { freeRaw(mem) } internal fun allocRaw(size: Long, align: Int): NativePtr { val ptr = malloc(size, align) if (ptr == nativeNullPtr) { throw OutOfMemoryError("unable to allocate native memory") } return ptr } internal fun freeRaw(mem: NativePtr) { cfree(mem) } } public fun CPointer.toKStringFromUtf16(): String { val nativeBytes = this var length = 0 while (nativeBytes[length] != 0.toUShort()) { ++length } val chars = kotlin.CharArray(length) var index = 0 while (index < length) { chars[index] = nativeBytes[index].toShort().toChar() ++index } return chars.concatToString() } public fun CPointer.toKString(): String = this.toKStringFromUtf16() public fun CPointer.toKString(): String = this.toKStringFromUtf16() @SymbolName("Kotlin_interop_malloc") private external fun malloc(size: Long, align: Int): NativePtr @SymbolName("Kotlin_interop_free") private external fun cfree(ptr: NativePtr) @TypedIntrinsic(IntrinsicType.INTEROP_READ_BITS) external fun readBits(ptr: NativePtr, offset: Long, size: Int, signed: Boolean): Long @TypedIntrinsic(IntrinsicType.INTEROP_WRITE_BITS) external fun writeBits(ptr: NativePtr, offset: Long, size: Int, value: Long) ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeStableRef.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.* @SymbolName("Kotlin_Interop_createStablePointer") internal external fun createStablePointer(any: Any): COpaquePointer @SymbolName("Kotlin_Interop_disposeStablePointer") internal external fun disposeStablePointer(pointer: COpaquePointer) @PublishedApi @SymbolName("Kotlin_Interop_derefStablePointer") internal external fun derefStablePointer(pointer: COpaquePointer): Any ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeTypes.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.internal.getNativeNullPtr import kotlin.native.internal.reinterpret import kotlin.native.internal.Intrinsic import kotlin.native.internal.VolatileLambda import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType typealias NativePtr = kotlin.native.internal.NativePtr internal typealias NonNullNativePtr = kotlin.native.internal.NonNullNativePtr @Suppress("NOTHING_TO_INLINE") internal inline fun NativePtr.toNonNull() = this.reinterpret() inline val nativeNullPtr: NativePtr get() = getNativeNullPtr() @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") fun typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument") /** * Performs type cast of the native pointer to given interop type, including null values. * * @param T must not be abstract */ @TypedIntrinsic(IntrinsicType.IDENTITY) external fun interpretNullablePointed(ptr: NativePtr): T? /** * Performs type cast of the [CPointer] from the given raw pointer. */ @TypedIntrinsic(IntrinsicType.IDENTITY) external fun interpretCPointer(rawValue: NativePtr): CPointer? @TypedIntrinsic(IntrinsicType.IDENTITY) external fun NativePointed.getRawPointer(): NativePtr @TypedIntrinsic(IntrinsicType.IDENTITY) external fun CPointer<*>.getRawValue(): NativePtr internal fun CPointer<*>.cPointerToString() = "CPointer(raw=$rawValue)" @Suppress("FINAL_UPPER_BOUND") public class Vector128VarOf(rawPtr: NativePtr) : CVariable(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : Type(size = 16, align = 16) } public typealias Vector128Var = Vector128VarOf @Suppress("FINAL_UPPER_BOUND", "UNCHECKED_CAST") public var Vector128VarOf.value: T get() = nativeMemUtils.getVector(this) as T set(value) = nativeMemUtils.putVector(this, value) /** * Returns a pointer to C function which calls given Kotlin *static* function. * * @param function must be *static*, i.e. an (unbound) reference to a Kotlin function or * a closure which doesn't capture any variable */ @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: () -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21) -> R): CPointer R>> @TypedIntrinsic(IntrinsicType.INTEROP_STATIC_C_FUNCTION) external fun staticCFunction(@VolatileLambda function: (P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22) -> R): CPointer R>> ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/NativeUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.internal.Intrinsic import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType internal fun encodeToUtf8(str: String): ByteArray = str.encodeToByteArray() @SymbolName("Kotlin_CString_toKStringFromUtf8Impl") internal external fun CPointer.toKStringFromUtf8Impl(): String @TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_FLOAT) external fun bitsToFloat(bits: Int): Float @TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_DOUBLE) external fun bitsToDouble(bits: Long): Double // TODO: deprecate. @TypedIntrinsic(IntrinsicType.INTEROP_SIGN_EXTEND) external inline fun Number.signExtend(): R // TODO: deprecate. @TypedIntrinsic(IntrinsicType.INTEROP_NARROW) external inline fun Number.narrow(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun Byte.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun Short.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun Int.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun Long.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun UByte.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun UShort.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun UInt.convert(): R @TypedIntrinsic(IntrinsicType.INTEROP_CONVERT) external inline fun ULong.convert(): R @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FILE) @Retention(AnnotationRetention.SOURCE) internal annotation class JvmName(val name: String) fun cValuesOf(vararg elements: UByte): CValues = createValues(elements.size) { index -> this.value = elements[index] } fun cValuesOf(vararg elements: UShort): CValues = createValues(elements.size) { index -> this.value = elements[index] } fun cValuesOf(vararg elements: UInt): CValues = createValues(elements.size) { index -> this.value = elements[index] } fun cValuesOf(vararg elements: ULong): CValues = createValues(elements.size) { index -> this.value = elements[index] } fun UByteArray.toCValues() = cValuesOf(*this) fun UShortArray.toCValues() = cValuesOf(*this) fun UIntArray.toCValues() = cValuesOf(*this) fun ULongArray.toCValues() = cValuesOf(*this) ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCImpl.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("NOTHING_TO_INLINE") package kotlinx.cinterop import kotlin.native.* import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType import kotlin.native.internal.FilterExceptions interface ObjCObject interface ObjCClass : ObjCObject interface ObjCClassOf : ObjCClass // TODO: T should be added to ObjCClass and all meta-classes instead. typealias ObjCObjectMeta = ObjCClass interface ObjCProtocol : ObjCObject @ExportTypeInfo("theForeignObjCObjectTypeInfo") @kotlin.native.internal.Frozen internal open class ForeignObjCObject : kotlin.native.internal.ObjCObjectWrapper abstract class ObjCObjectBase protected constructor() : ObjCObject { @Target(AnnotationTarget.CONSTRUCTOR) @Retention(AnnotationRetention.SOURCE) annotation class OverrideInit } abstract class ObjCObjectBaseMeta protected constructor() : ObjCObjectBase(), ObjCObjectMeta {} fun optional(): Nothing = throw RuntimeException("Do not call me!!!") @Deprecated( "Add @OverrideInit to constructor to make it override Objective-C initializer", level = DeprecationLevel.ERROR ) @TypedIntrinsic(IntrinsicType.OBJC_INIT_BY) external fun T.initBy(constructorCall: T): T @kotlin.native.internal.ExportForCompiler private fun ObjCObjectBase.superInitCheck(superInitCallResult: ObjCObject?) { if (superInitCallResult == null) throw RuntimeException("Super initialization failed") if (superInitCallResult.objcPtr() != this.objcPtr()) throw UnsupportedOperationException("Super initializer has replaced object") } internal fun Any?.uncheckedCast(): T = @Suppress("UNCHECKED_CAST") (this as T) // Note: if this is called for non-frozen object on a wrong worker, the program will terminate. @SymbolName("Kotlin_Interop_refFromObjC") external fun interpretObjCPointerOrNull(objcPtr: NativePtr): T? @ExportForCppRuntime inline fun interpretObjCPointer(objcPtr: NativePtr): T = interpretObjCPointerOrNull(objcPtr)!! @SymbolName("Kotlin_Interop_refToObjC") external fun Any?.objcPtr(): NativePtr @SymbolName("Kotlin_Interop_createKotlinObjectHolder") external fun createKotlinObjectHolder(any: Any?): NativePtr // Note: if this is called for non-frozen underlying ref on a wrong worker, the program will terminate. inline fun unwrapKotlinObjectHolder(holder: Any?): T { return unwrapKotlinObjectHolderImpl(holder!!.objcPtr()) as T } @PublishedApi @SymbolName("Kotlin_Interop_unwrapKotlinObjectHolder") external internal fun unwrapKotlinObjectHolderImpl(ptr: NativePtr): Any class ObjCObjectVar(rawPtr: NativePtr) : CVariable(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : CVariable.Type(pointerSize.toLong(), pointerSize) } class ObjCNotImplementedVar(rawPtr: NativePtr) : CVariable(rawPtr) { @Deprecated("Use sizeOf() or alignOf() instead.") @Suppress("DEPRECATION") companion object : CVariable.Type(pointerSize.toLong(), pointerSize) } var ObjCNotImplementedVar.value: T get() = TODO() set(_) = TODO() typealias ObjCStringVarOf = ObjCNotImplementedVar typealias ObjCBlockVar = ObjCNotImplementedVar @TypedIntrinsic(IntrinsicType.OBJC_CREATE_SUPER_STRUCT) @PublishedApi internal external fun createObjCSuperStruct(receiver: NativePtr, superClass: NativePtr): NativePtr @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) annotation class ExternalObjCClass(val protocolGetter: String = "", val binaryName: String = "") @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Retention(AnnotationRetention.BINARY) annotation class ObjCMethod(val selector: String, val encoding: String, val isStret: Boolean = false) @Target(AnnotationTarget.CONSTRUCTOR) @Retention(AnnotationRetention.BINARY) annotation class ObjCConstructor(val initSelector: String, val designated: Boolean) @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) annotation class ObjCFactory(val selector: String, val encoding: String, val isStret: Boolean = false) @Target(AnnotationTarget.FILE) @Retention(AnnotationRetention.BINARY) annotation class InteropStubs() @PublishedApi @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) internal annotation class ObjCMethodImp(val selector: String, val encoding: String) @PublishedApi @TypedIntrinsic(IntrinsicType.OBJC_GET_SELECTOR) internal external fun objCGetSelector(selector: String): COpaquePointer @kotlin.native.internal.ExportForCppRuntime("Kotlin_Interop_getObjCClass") private fun getObjCClassByName(name: NativePtr): NativePtr { val result = objc_lookUpClass(name) if (result == nativeNullPtr) { val className = interpretCPointer(name)!!.toKString() val message = """Objective-C class '$className' not found. |Ensure that the containing framework or library was linked.""".trimMargin() throw RuntimeException(message) } return result } @kotlin.native.internal.ExportForCompiler private fun allocObjCObject(clazz: NativePtr): NativePtr { val rawResult = objc_allocWithZone(clazz) if (rawResult == nativeNullPtr) { throw OutOfMemoryError("Unable to allocate Objective-C object") } // Note: `objc_allocWithZone` returns retained pointer, and thus it must be balanced by the caller. return rawResult } @TypedIntrinsic(IntrinsicType.OBJC_GET_OBJC_CLASS) @kotlin.native.internal.ExportForCompiler private external fun getObjCClass(): NativePtr @PublishedApi @TypedIntrinsic(IntrinsicType.OBJC_GET_MESSENGER) internal external fun getMessenger(superClass: NativePtr): COpaquePointer? @PublishedApi @TypedIntrinsic(IntrinsicType.OBJC_GET_MESSENGER_STRET) internal external fun getMessengerStret(superClass: NativePtr): COpaquePointer? internal class ObjCWeakReferenceImpl : kotlin.native.ref.WeakReferenceImpl() { @SymbolName("Konan_ObjCInterop_getWeakReference") external override fun get(): Any? } @SymbolName("Konan_ObjCInterop_initWeakReference") private external fun ObjCWeakReferenceImpl.init(objcPtr: NativePtr) @kotlin.native.internal.ExportForCppRuntime internal fun makeObjCWeakReferenceImpl(objcPtr: NativePtr): ObjCWeakReferenceImpl { val result = ObjCWeakReferenceImpl() result.init(objcPtr) return result } // Konan runtme: @Deprecated("Use plain Kotlin cast of String to NSString", level = DeprecationLevel.ERROR) @SymbolName("Kotlin_Interop_CreateNSStringFromKString") external fun CreateNSStringFromKString(str: String?): NativePtr @Deprecated("Use plain Kotlin cast of NSString to String", level = DeprecationLevel.ERROR) @SymbolName("Kotlin_Interop_CreateKStringFromNSString") external fun CreateKStringFromNSString(ptr: NativePtr): String? @PublishedApi @SymbolName("Kotlin_Interop_CreateObjCObjectHolder") internal external fun createObjCObjectHolder(ptr: NativePtr): Any? // Objective-C runtime: @SymbolName("objc_retainAutoreleaseReturnValue") external fun objc_retainAutoreleaseReturnValue(ptr: NativePtr): NativePtr @SymbolName("Kotlin_objc_autoreleasePoolPush") external fun objc_autoreleasePoolPush(): NativePtr @SymbolName("Kotlin_objc_autoreleasePoolPop") external fun objc_autoreleasePoolPop(ptr: NativePtr) @SymbolName("Kotlin_objc_allocWithZone") @FilterExceptions private external fun objc_allocWithZone(clazz: NativePtr): NativePtr @SymbolName("Kotlin_objc_retain") external fun objc_retain(ptr: NativePtr): NativePtr @SymbolName("Kotlin_objc_release") external fun objc_release(ptr: NativePtr) @SymbolName("Kotlin_objc_lookUpClass") external fun objc_lookUpClass(name: NativePtr): NativePtr ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCKClassSupport.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cinterop import kotlin.native.internal.KClassImpl import kotlin.reflect.KClass /** * If [objCClass] is a class generated to Objective-C header for Kotlin class, * returns [KClass] for that original Kotlin class. * * Otherwise returns `null`. */ fun getOriginalKotlinClass(objCClass: ObjCClass): KClass<*>? { val typeInfo = getTypeInfoForClass(objCClass.objcPtr()) if (typeInfo.isNull()) return null return KClassImpl(typeInfo) } /** * If [objCProtocol] is a protocol generated to Objective-C header for Kotlin class, * returns [KClass] for that original Kotlin class. * * Otherwise returns `null`. */ fun getOriginalKotlinClass(objCProtocol: ObjCProtocol): KClass<*>? { val typeInfo = getTypeInfoForProtocol(objCProtocol.objcPtr()) if (typeInfo.isNull()) return null return KClassImpl(typeInfo) } @SymbolName("Kotlin_ObjCInterop_getTypeInfoForClass") private external fun getTypeInfoForClass(ptr: NativePtr): NativePtr @SymbolName("Kotlin_ObjCInterop_getTypeInfoForProtocol") private external fun getTypeInfoForProtocol(ptr: NativePtr): NativePtr ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop inline fun autoreleasepool(block: () -> R): R { val pool = objc_autoreleasePoolPush() return try { block() } finally { objc_autoreleasePoolPop(pool) } } @Deprecated("Use plain Kotlin cast", ReplaceWith("this as T"), DeprecationLevel.ERROR) fun ObjCObject.reinterpret() = @Suppress("DEPRECATION") this.uncheckedCast() // TODO: null checks var ObjCObjectVar.value: T @Suppress("DEPRECATION") get() = interpretObjCPointerOrNull(nativeMemUtils.getNativePtr(this)).uncheckedCast() set(value) = nativeMemUtils.putNativePtr(this, value.objcPtr()) /** * Makes Kotlin method in Objective-C class accessible through Objective-C dispatch * to be used as action sent by control in UIKit or AppKit. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) annotation class ObjCAction /** * Makes Kotlin property in Objective-C class settable through Objective-C dispatch * to be used as IB outlet. */ @Target(AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.SOURCE) annotation class ObjCOutlet /** * Makes Kotlin subclass of Objective-C class visible for runtime lookup * after Kotlin `main` function gets invoked. * * Note: runtime lookup can be forced even when the class is referenced statically from * Objective-C source code by adding `__attribute__((objc_runtime_visible))` to its `@interface`. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) annotation class ExportObjCClass(val name: String = "") ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/Pinning.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlinx.cinterop import kotlin.native.* data class Pinned internal constructor(private val stablePtr: COpaquePointer) { /** * Disposes the handle. It must not be [used][get] after that. */ fun unpin() { disposeStablePointer(this.stablePtr) } /** * Returns the underlying pinned object. */ fun get(): T = @Suppress("UNCHECKED_CAST") (derefStablePointer(stablePtr) as T) } fun T.pin() = Pinned(createStablePointer(this)) inline fun T.usePinned(block: (Pinned) -> R): R { val pinned = this.pin() return try { block(pinned) } finally { pinned.unpin() } } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun ByteArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun String.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun CharArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun ShortArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun IntArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun LongArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } // TODO: pinning of unsigned arrays involves boxing as they are inline classes wrapping signed arrays. fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun UByteArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun UShortArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun UIntArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun ULongArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun FloatArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } fun Pinned.addressOf(index: Int): CPointer = this.get().addressOfElement(index) fun DoubleArray.refTo(index: Int): CValuesRef = this.usingPinned { addressOf(index) } private inline fun T.usingPinned( crossinline block: Pinned.() -> CPointer

) = object : CValuesRef

() { override fun getPointer(scope: AutofreeScope): CPointer

{ val pinned = this@usingPinned.pin() scope.defer { pinned.unpin() } return pinned.block() } } @SymbolName("Kotlin_Arrays_getByteArrayAddressOfElement") private external fun ByteArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getStringAddressOfElement") private external fun String.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getCharArrayAddressOfElement") private external fun CharArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getShortArrayAddressOfElement") private external fun ShortArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getIntArrayAddressOfElement") private external fun IntArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getLongArrayAddressOfElement") private external fun LongArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getByteArrayAddressOfElement") private external fun UByteArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getShortArrayAddressOfElement") private external fun UShortArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getIntArrayAddressOfElement") private external fun UIntArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getLongArrayAddressOfElement") private external fun ULongArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getFloatArrayAddressOfElement") private external fun FloatArray.addressOfElement(index: Int): CPointer @SymbolName("Kotlin_Arrays_getDoubleArrayAddressOfElement") private external fun DoubleArray.addressOfElement(index: Int): CPointer ================================================ FILE: Interop/Runtime/src/native/kotlin/kotlinx/cinterop/internal/Annotations.kt ================================================ package kotlinx.cinterop.internal @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) annotation class CStruct(val spelling: String) { @Retention(AnnotationRetention.BINARY) @Target( AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) annotation class MemberAt(val offset: Long) @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.PROPERTY_GETTER) annotation class ArrayMemberAt(val offset: Long) @Retention(AnnotationRetention.BINARY) @Target( AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) annotation class BitField(val offset: Long, val size: Int) @Retention(AnnotationRetention.BINARY) annotation class VarType(val size: Long, val align: Int) } @Target( AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) @Retention(AnnotationRetention.BINARY) public annotation class CCall(val id: String) { @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.BINARY) annotation class CString @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.BINARY) annotation class WCString @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) annotation class ReturnsRetained @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) annotation class ConsumesReceiver @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.BINARY) annotation class Consumed } /** * Collection of annotations that allow to store * constant values. */ public object ConstantValue { @Retention(AnnotationRetention.BINARY) annotation class Byte(val value: kotlin.Byte) @Retention(AnnotationRetention.BINARY) annotation class Short(val value: kotlin.Short) @Retention(AnnotationRetention.BINARY) annotation class Int(val value: kotlin.Int) @Retention(AnnotationRetention.BINARY) annotation class Long(val value: kotlin.Long) @Retention(AnnotationRetention.BINARY) annotation class UByte(val value: kotlin.UByte) @Retention(AnnotationRetention.BINARY) annotation class UShort(val value: kotlin.UShort) @Retention(AnnotationRetention.BINARY) annotation class UInt(val value: kotlin.UInt) @Retention(AnnotationRetention.BINARY) annotation class ULong(val value: kotlin.ULong) @Retention(AnnotationRetention.BINARY) annotation class Float(val value: kotlin.Float) @Retention(AnnotationRetention.BINARY) annotation class Double(val value: kotlin.Double) @Retention(AnnotationRetention.BINARY) annotation class String(val value: kotlin.String) } /** * Denotes property that is an alias to some enum entry. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class CEnumEntryAlias(val entryName: String) /** * Stores instance size of the type T: CEnumVar. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class CEnumVarTypeSize(val size: Int) ================================================ FILE: Interop/StubGenerator/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" } apply plugin: 'kotlin' apply plugin: 'application' mainClassName = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" repositories { maven { url buildKotlinCompilerRepo } } dependencies { implementation project(":Interop:Indexer") implementation project(":utilities:basic-utils") api project(path: ":endorsedLibraries:kotlinx.cli", configuration: "jvmRuntimeElements") api "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" api "org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion" api "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" api "org.jetbrains.kotlinx:kotlinx-metadata-klib:$metadataVersion" testImplementation "junit:junit:4.12" testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$buildKotlinVersion" testImplementation "org.jetbrains.kotlin:kotlin-test:$buildKotlinVersion" } compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xopt-in=kotlin.ExperimentalUnsignedTypes', '-Xskip-metadata-version-check'] allWarningsAsErrors=true } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/AbiSpecific.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.native.interop.indexer.* /** * objc_msgSend*_stret functions must be used when return value is returned through memory * pointed by implicit argument, which is passed on the register that would otherwise be used for receiver. * * The entire implementation is just the real ABI approximation which is enough for practical cases. */ internal fun Type.isStret(target: KonanTarget): Boolean { val unwrappedType = this.unwrapTypedefs() val abiInfo: ObjCAbiInfo = when (target) { KonanTarget.IOS_ARM64, KonanTarget.TVOS_ARM64, KonanTarget.MACOS_ARM64 -> DarwinArm64AbiInfo() KonanTarget.IOS_X64, KonanTarget.MACOS_X64, KonanTarget.WATCHOS_X64, KonanTarget.TVOS_X64 -> DarwinX64AbiInfo() KonanTarget.WATCHOS_X86 -> DarwinX86AbiInfo() KonanTarget.IOS_ARM32, KonanTarget.WATCHOS_ARM32 -> DarwinArm32AbiInfo(target) else -> error("Cannot generate ObjC stubs for $target.") } return abiInfo.shouldUseStret(unwrappedType) } /** * Provides ABI-specific information about target for Objective C interop. */ interface ObjCAbiInfo { fun shouldUseStret(returnType: Type): Boolean } class DarwinX64AbiInfo : ObjCAbiInfo { override fun shouldUseStret(returnType: Type): Boolean { return when (returnType) { is RecordType -> returnType.decl.def!!.size > 16 || returnType.hasUnalignedMembers() else -> false } } } class DarwinX86AbiInfo : ObjCAbiInfo { override fun shouldUseStret(returnType: Type): Boolean { // https://github.com/llvm/llvm-project/blob/6c8a34ed9b49704bdd60838143047c62ba9f2502/clang/lib/CodeGen/TargetInfo.cpp#L1243 return when (returnType) { is RecordType -> { val size = returnType.decl.def!!.size val canBePassedInRegisters = (size == 1L || size == 2L || size == 4L || size == 8L) return !canBePassedInRegisters } else -> false } } } class DarwinArm32AbiInfo(private val target: KonanTarget) : ObjCAbiInfo { override fun shouldUseStret(returnType: Type): Boolean = when (target) { KonanTarget.IOS_ARM32 -> when (returnType) { is RecordType -> !returnType.isIntegerLikeType() else -> false } // 32-bit watchOS uses armv7k which is effectively Cortex-A7 and // uses AAPCS16 VPF. KonanTarget.WATCHOS_ARM32 -> when (returnType) { is RecordType -> { // https://github.com/llvm/llvm-project/blob/6c8a34ed9b49704bdd60838143047c62ba9f2502/clang/lib/CodeGen/TargetInfo.cpp#L6165 when { returnType.decl.def!!.size <= 16 -> false else -> true } } else -> false } else -> error("Unexpected target") } } class DarwinArm64AbiInfo : ObjCAbiInfo { override fun shouldUseStret(returnType: Type): Boolean { // On aarch64 stret is never the case, since an implicit argument gets passed on x8. return false } } private fun Type.isIntegerLikeType(): Boolean = when (this) { is RecordType -> { val def = this.decl.def if (def == null) { false } else { def.size <= 4 && def.members.all { when (it) { is BitField -> it.type.isIntegerLikeType() is Field -> it.offset == 0L && it.type.isIntegerLikeType() is IncompleteField -> false } } } } is ObjCPointer, is PointerType, CharType, is BoolType -> true is IntegerType -> this.size <= 4 is Typedef -> this.def.aliased.isIntegerLikeType() is EnumType -> this.def.baseType.isIntegerLikeType() else -> false } private fun Type.hasUnalignedMembers(): Boolean = when (this) { is Typedef -> this.def.aliased.hasUnalignedMembers() is RecordType -> this.decl.def!!.let { def -> def.fields.any { !it.isAligned || // Check members of fields too: it.type.hasUnalignedMembers() } } is ArrayType -> this.elemType.hasUnalignedMembers() else -> false // TODO: should the recursive checks be made in indexer when computing `hasUnalignedFields`? } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CWrapperGenerator.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.FunctionDecl import org.jetbrains.kotlin.native.interop.indexer.GlobalDecl import org.jetbrains.kotlin.native.interop.indexer.VoidType import org.jetbrains.kotlin.native.interop.indexer.unwrapTypedefs internal data class CCalleeWrapper(val lines: List) /** * Some functions don't have an address (e.g. macros-based or builtins). * To solve this problem we generate a wrapper function. */ internal class CWrappersGenerator(private val context: StubIrContext) { private var currentFunctionWrapperId = 0 private val packageName = context.configuration.pkgName.replace(INVALID_CLANG_IDENTIFIER_REGEX, "_") private fun generateFunctionWrapperName(functionName: String): String { return "${packageName}_${functionName}_wrapper${currentFunctionWrapperId++}" } private fun bindSymbolToFunction(symbol: String, function: String): List = listOf( "const void* $symbol __asm(${symbol.quoteAsKotlinLiteral()});", "const void* $symbol = &$function;" ) private data class Parameter(val type: String, val name: String) private fun createWrapper( symbolName: String, wrapperName: String, returnType: String, parameters: List, body: String ): List = listOf( "__attribute__((always_inline))", "$returnType $wrapperName(${parameters.joinToString { "${it.type} ${it.name}" }}) {", body, "}", *bindSymbolToFunction(symbolName, wrapperName).toTypedArray() ) fun generateCCalleeWrapper(function: FunctionDecl, symbolName: String): CCalleeWrapper = if (function.isVararg) { CCalleeWrapper(bindSymbolToFunction(symbolName, function.name)) } else { val wrapperName = generateFunctionWrapperName(function.name) val returnType = function.returnType.getStringRepresentation() val parameters = function.parameters.mapIndexed { index, parameter -> Parameter(parameter.type.getStringRepresentation(), "p$index") } val callExpression = "${function.name}(${parameters.joinToString { it.name }});" val wrapperBody = if (function.returnType.unwrapTypedefs() is VoidType) { callExpression } else { "return $callExpression" } val wrapper = createWrapper(symbolName, wrapperName, returnType, parameters, wrapperBody) CCalleeWrapper(wrapper) } fun generateCGlobalGetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper { val wrapperName = generateFunctionWrapperName("${globalDecl.name}_getter") val returnType = globalDecl.type.getStringRepresentation() val wrapperBody = "return ${globalDecl.name};" val wrapper = createWrapper(symbolName, wrapperName, returnType, emptyList(), wrapperBody) return CCalleeWrapper(wrapper) } fun generateCGlobalByPointerGetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper { val wrapperName = generateFunctionWrapperName("${globalDecl.name}_getter") val returnType = "void*" val wrapperBody = "return &${globalDecl.name};" val wrapper = createWrapper(symbolName, wrapperName, returnType, emptyList(), wrapperBody) return CCalleeWrapper(wrapper) } fun generateCGlobalSetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper { val wrapperName = generateFunctionWrapperName("${globalDecl.name}_setter") val globalType = globalDecl.type.getStringRepresentation() val parameter = Parameter(globalType, "p1") val wrapperBody = "${globalDecl.name} = ${parameter.name};" val wrapper = createWrapper(symbolName, wrapperName, "void", listOf(parameter), wrapperBody) return CCalleeWrapper(wrapper) } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CodeBuilders.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen interface NativeScope { val mappingBridgeGenerator: MappingBridgeGenerator } class NativeCodeBuilder(val scope: NativeScope) { val lines = mutableListOf() fun out(line: String): Unit { lines.add(line) } } inline fun buildNativeCodeLines(scope: NativeScope, block: NativeCodeBuilder.() -> Unit): List { val builder = NativeCodeBuilder(scope) builder.block() return builder.lines } private class Block(val nesting: Int, val start: String, val end: String) { val prologue = mutableListOf() val body = mutableListOf() val epilogue = mutableListOf() fun indent(line: String) = " ".repeat(nesting) + line fun indentBraces(line: String) = " ".repeat(nesting - 1) + line } class KotlinCodeBuilder(val scope: KotlinScope) { private val blocks = mutableListOf() init { pushBlock("", "") } fun out(line: String) { currentBlock().body += line } private var memScoped = false fun pushMemScoped() { if (!memScoped) { memScoped = true pushBlock("memScoped {") } } fun getNativePointer(name: String): String { return "$name?.getPointer(memScope)" } fun returnResult(result: String) { currentBlock().body += "return $result" } private fun currentBlock() = blocks.last() fun pushBlock(start: String, end: String = "}") { val block = Block(blocks.size, start = start, end = end) blocks += block } private fun emitBlockAndNested(position: Int, lines: MutableList) { if (position >= blocks.size) return val block = blocks[position] if (block.start.isNotEmpty()) lines += block.indentBraces(block.start) lines += block.prologue.map { block.indent(it) } lines += block.body.map { block.indent(it) } emitBlockAndNested(position + 1, lines) lines += block.epilogue.map { block.indent(it) } if (block.end.isNotEmpty()) lines += block.indentBraces(block.end) } fun build(): List { val lines = mutableListOf() emitBlockAndNested(0, lines) return lines.toList() } } inline fun buildKotlinCodeLines(scope: KotlinScope, block: KotlinCodeBuilder.() -> Unit): List { val builder = KotlinCodeBuilder(scope) builder.block() return builder.build() } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CodeUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen val kotlinKeywords = setOf( "as", "break", "class", "continue", "do", "dynamic", "else", "false", "for", "fun", "if", "in", "interface", "is", "null", "object", "package", "return", "super", "this", "throw", "true", "try", "typealias", "val", "var", "when", "while", // While not technically keywords, those shall be escaped as well. "_", "__", "___" ) /** * The expression written in native language. */ typealias NativeExpression = String /** * The expression written in Kotlin. */ typealias KotlinExpression = String /** * For this identifier constructs the string to be parsed by Kotlin as `SimpleName` * defined [here](https://kotlinlang.org/docs/reference/grammar.html#SimpleName). */ fun String.asSimpleName(): String = if (this in kotlinKeywords || this.contains("$")) { "`$this`" } else { this } /** * Yet another mangler, particularly to avoid secondary clash, e.g. when a property * in prototype (interface) is mangled and that will cause another clash in the class * which implements this interface. * Rationale: keep algorithm simple but use the mangling characters which are rare * in normal code, and keep mangling easy readable. */ internal fun mangleSimple(name: String): String { val reserved = setOf("Companion") val postfix = "\$" return if (name in reserved) "$name$postfix" else name } /** * Returns the expression to be parsed by Kotlin as string literal with given contents, * i.e. transforms `foo$bar` to `"foo\$bar"`. */ fun String.quoteAsKotlinLiteral(): KotlinExpression = buildString { append('"') this@quoteAsKotlinLiteral.forEach { c -> when (c) { in charactersAllowedInKotlinStringLiterals -> append(c) '$' -> append("\\$") else -> append("\\u" + "%04X".format(c.toInt())) } } append('"') } // TODO: improve literal readability by preserving more characters. private val charactersAllowedInKotlinStringLiterals: Set = mutableSetOf().apply { addAll('a' .. 'z') addAll('A' .. 'Z') addAll('0' .. '9') addAll(listOf('_', '@', ':', ';', '.', ',', '{', '}', '=', '[', ']', '^', '#', '*', ' ', '(', ')')) } val annotationForUnableToImport get() = "@Deprecated(${"Unable to import this declaration".quoteAsKotlinLiteral()}, level = DeprecationLevel.ERROR)" ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Imports.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.native.interop.indexer.* interface Imports { fun getPackage(location: Location): String? } class PackageInfo(val name: String, val library: KonanLibrary) class ImportsImpl(internal val headerIdToPackage: Map) : Imports { override fun getPackage(location: Location): String? { val packageInfo = headerIdToPackage[location.headerId] ?: return null accessedLibraries += packageInfo.library return packageInfo.name } private val accessedLibraries = mutableSetOf() val requiredLibraries: Set get() = accessedLibraries.toSet() } class HeaderInclusionPolicyImpl(private val nameGlobs: List) : HeaderInclusionPolicy { override fun excludeUnused(headerName: String?): Boolean { if (nameGlobs.isEmpty()) { return false } if (headerName == null) { // Builtins; included only if no globs are specified: return true } return nameGlobs.all { !headerName.matchesToGlob(it) } } } class HeaderExclusionPolicyImpl( private val importsImpl: ImportsImpl ) : HeaderExclusionPolicy { override fun excludeAll(headerId: HeaderId): Boolean { return headerId in importsImpl.headerIdToPackage } } private fun String.matchesToGlob(glob: String): Boolean = java.nio.file.FileSystems.getDefault() .getPathMatcher("glob:$glob").matches(java.nio.file.Paths.get(this)) ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/KotlinCodeModel.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import kotlin.reflect.KProperty interface KotlinScope { /** * @return the string to be used to reference the classifier in current scope. */ fun reference(classifier: Classifier): String /** * @return the string to be used as a name in the declaration of the classifier in current scope. */ fun declare(classifier: Classifier): String /** * @return the string to be used as a name in the declaration of the property in current scope, * or `null` if the property with given name can't be declared. */ fun declareProperty(receiver: String?, name: String): String? val mappingBridgeGenerator: MappingBridgeGenerator } data class Classifier( val pkg: String, val topLevelName: String, private val nestedNames: List = emptyList() ) { companion object { fun topLevel(pkg: String, name: String): Classifier { assert(!name.contains('.')) assert(!name.contains('`')) return Classifier(pkg, name) } } val isTopLevel: Boolean get() = this.nestedNames.isEmpty() fun nested(name: String): Classifier { assert(!name.contains('.')) assert(!name.contains('`')) return this.copy(nestedNames = nestedNames + name) } fun getRelativeFqName(asSimpleName: Boolean = true): String = buildString { append(topLevelName.run { if (asSimpleName) asSimpleName() else this }) nestedNames.forEach { append('.') append(it.run { if (asSimpleName) asSimpleName() else this }) } } val fqName: String get() = buildString { if (pkg.isNotEmpty()) { append(pkg) append('.') } append(getRelativeFqName()) } } val Classifier.type get() = KotlinClassifierType(this, arguments = emptyList(), nullable = false, underlyingType = null) fun Classifier.typeWith(vararg arguments: KotlinTypeArgument) = KotlinClassifierType(this, arguments.toList(), nullable = false, underlyingType = null) fun Classifier.typeAbbreviation(expandedType: KotlinType) = KotlinClassifierType(this, arguments = emptyList(), nullable = false, underlyingType = expandedType) interface KotlinTypeArgument { /** * @return the string to be used in the given scope to denote this. */ fun render(scope: KotlinScope): String } object StarProjection : KotlinTypeArgument { override fun render(scope: KotlinScope) = "*" } interface KotlinType : KotlinTypeArgument { val classifier: Classifier fun makeNullableAsSpecified(nullable: Boolean): KotlinType } /** * @property underlyingType is non-null if this type is an alias to another type. */ data class KotlinClassifierType( override val classifier: Classifier, val arguments: List, val nullable: Boolean, val underlyingType: KotlinType? ) : KotlinType { override fun makeNullableAsSpecified(nullable: Boolean) = if (this.nullable == nullable) { this } else { this.copy(nullable = nullable) } override fun render(scope: KotlinScope): String = buildString { append(scope.reference(classifier)) if (arguments.isNotEmpty()) { append('<') arguments.joinTo(this) { it.render(scope) } append('>') } if (nullable) { append('?') } } } fun KotlinType.makeNullable() = this.makeNullableAsSpecified(true) data class KotlinFunctionType( val parameterTypes: List, val returnType: KotlinType, val nullable: Boolean = false ) : KotlinType { override fun makeNullableAsSpecified(nullable: Boolean) = if (this.nullable == nullable) { this } else { this.copy(nullable = nullable) } override val classifier by lazy { Classifier.topLevel("kotlin", "Function${parameterTypes.size}") } override fun render(scope: KotlinScope) = buildString { if (nullable) append("(") append('(') parameterTypes.joinTo(this) { it.render(scope) } append(") -> ") append(returnType.render(scope)) if (nullable) append(")?") } } internal val cnamesStructsPackageName = "cnames.structs" object KotlinTypes { val independent = Classifier.topLevel("kotlin.native.internal", "Independent") val boolean by BuiltInType val byte by BuiltInType val short by BuiltInType val int by BuiltInType val long by BuiltInType val uByte by BuiltInType val uShort by BuiltInType val uInt by BuiltInType val uLong by BuiltInType val float by BuiltInType val double by BuiltInType val unit by BuiltInType val string by BuiltInType val any by BuiltInType val list by CollectionClassifier val mutableList by CollectionClassifier val set by CollectionClassifier val map by CollectionClassifier val nativePtr by InteropType val vector128 by KotlinNativeType val cOpaque by InteropType val cOpaquePointer by InteropType val cOpaquePointerVar by InteropType val booleanVarOf by InteropClassifier val objCObject by InteropClassifier val objCObjectMeta by InteropClassifier val objCClass by InteropClassifier val objCClassOf by InteropClassifier val objCProtocol by InteropClassifier val cValuesRef by InteropClassifier val cPointed by InteropClassifier val cPointer by InteropClassifier val cPointerVar by InteropClassifier val cArrayPointer by InteropClassifier val cArrayPointerVar by InteropClassifier val cPointerVarOf by InteropClassifier val cFunction by InteropClassifier val objCObjectVar by InteropClassifier val objCObjectBase by InteropClassifier val objCObjectBaseMeta by InteropClassifier val objCBlockVar by InteropClassifier val objCNotImplementedVar by InteropClassifier val cValue by InteropClassifier private open class ClassifierAtPackage(val pkg: String) { operator fun getValue(thisRef: KotlinTypes, property: KProperty<*>): Classifier = Classifier.topLevel(pkg, property.name.capitalize()) } private open class TypeAtPackage(val pkg: String) { operator fun getValue(thisRef: KotlinTypes, property: KProperty<*>): KotlinClassifierType = Classifier.topLevel(pkg, property.name.capitalize()).type } private object BuiltInType : TypeAtPackage("kotlin") private object CollectionClassifier : ClassifierAtPackage("kotlin.collections") private object InteropClassifier : ClassifierAtPackage("kotlinx.cinterop") private object InteropType : TypeAtPackage("kotlinx.cinterop") private object KotlinNativeType : TypeAtPackage("kotlin.native") } abstract class KotlinFile( val pkg: String, namesToBeDeclared: List ) : KotlinScope { // Note: all names are related to classifiers currently. private val namesToBeDeclared: Set init { this.namesToBeDeclared = mutableSetOf() namesToBeDeclared.forEach { if (it in this.namesToBeDeclared) { throw IllegalArgumentException("'$it' is going to be declared twice") } else { this.namesToBeDeclared.add(it) } } } private val importedNameToPkg = mutableMapOf() private val declaredProperties = mutableSetOf() override fun reference(classifier: Classifier): String = if (classifier.topLevelName in namesToBeDeclared) { if (classifier.pkg == this.pkg) { classifier.getRelativeFqName() } else { // Don't import if would clash with own declaration: classifier.fqName } } else if (classifier.pkg == this.pkg) { throw IllegalArgumentException( "'${classifier.topLevelName}' from the file package was not reserved for declaration" ) } else { if (tryImport(classifier)) { // Is successfully imported: classifier.getRelativeFqName() } else { classifier.fqName } } private fun tryImport(classifier: Classifier): Boolean { if (classifier.topLevelName in declaredProperties) { return false } return importedNameToPkg.getOrPut(classifier.topLevelName) { classifier.pkg } == classifier.pkg } private val alreadyDeclared = mutableSetOf() override fun declare(classifier: Classifier): String { if (classifier.pkg != this.pkg) { throw IllegalArgumentException("wrong package for classifier ${classifier.fqName}; expected '$pkg', got '${classifier.pkg}'") } if (!classifier.isTopLevel) { throw IllegalArgumentException( "'${classifier.getRelativeFqName()}' is not top-level thus can't be declared at file scope" ) } val topLevelName = classifier.topLevelName if (topLevelName in alreadyDeclared) { throw IllegalStateException("'$topLevelName' is already declared") } alreadyDeclared.add(topLevelName) return topLevelName } override fun declareProperty(receiver: String?, name: String): String? { val fullName = receiver?.let { "$it.${name}" } ?: name return if (fullName in declaredProperties || name in namesToBeDeclared || name in importedNameToPkg) { null // TODO: using original global name should be preferred to importing the clashed name. } else { declaredProperties.add(fullName) name } } fun buildImports(): List = importedNameToPkg.mapNotNull { (name, pkg) -> if (pkg == "kotlin" || pkg == "kotlinx.cinterop") { // Is already imported either by default or with '*': null } else { "import $pkg.${name.asSimpleName()}" } }.sorted() } internal fun getTopLevelPropertyDeclarationName(scope: KotlinScope, property: PropertyStub): String { val receiverName = property.receiverType?.underlyingTypeFqName return getTopLevelPropertyDeclarationName(scope, receiverName, property.name) } // Try to use the provided name. If failed, mangle it with underscore and try again: private tailrec fun getTopLevelPropertyDeclarationName(scope: KotlinScope, receiver: String?, name: String): String = scope.declareProperty(receiver, name) ?: getTopLevelPropertyDeclarationName(scope, receiver, name + "_") ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/LibraryUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.konan.file.File internal fun resolveLibraries(staticLibraries: List, libraryPaths: List): List { val result = mutableListOf() staticLibraries.forEach { library -> val resolution = libraryPaths.map { "$it/$library" } .find { File(it).exists } if (resolution != null) { result.add(resolution) } else { error("Could not find '$library' binary in neither of $libraryPaths") } } return result } internal fun argsToCompiler(staticLibraries: Array, libraryPaths: Array) = argsToCompiler(staticLibraries.toList(), libraryPaths.toList()) internal fun argsToCompiler(staticLibraries: List, libraryPaths: List) = resolveLibraries(staticLibraries, libraryPaths) .map { it -> listOf("-include-binary", it) } .flatten() .toTypedArray() ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/MappingBridgeGenerator.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.Type data class TypedKotlinValue(val type: Type, val value: KotlinExpression) data class TypedNativeValue(val type: Type, val value: NativeExpression) /** * Generates bridges between Kotlin and native, passing arbitrary native-typed values. * * It does the same as [SimpleBridgeGenerator] except that it supports any native types, e.g. struct values. */ interface MappingBridgeGenerator { fun kotlinToNative( builder: KotlinCodeBuilder, nativeBacked: NativeBacked, returnType: Type, kotlinValues: List, independent: Boolean, block: NativeCodeBuilder.(nativeValues: List) -> NativeExpression ): KotlinExpression fun nativeToKotlin( builder: NativeCodeBuilder, nativeBacked: NativeBacked, returnType: Type, nativeValues: List, block: KotlinCodeBuilder.(kotlinValues: List) -> KotlinExpression ): NativeExpression } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/MappingBridgeGeneratorImpl.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.RecordType import org.jetbrains.kotlin.native.interop.indexer.Type import org.jetbrains.kotlin.native.interop.indexer.VoidType import org.jetbrains.kotlin.native.interop.indexer.unwrapTypedefs /** * The [MappingBridgeGenerator] implementation which uses [SimpleBridgeGenerator] as the backend and * maps the type using [mirror]. */ class MappingBridgeGeneratorImpl( val declarationMapper: DeclarationMapper, val simpleBridgeGenerator: SimpleBridgeGenerator ) : MappingBridgeGenerator { override fun kotlinToNative( builder: KotlinCodeBuilder, nativeBacked: NativeBacked, returnType: Type, kotlinValues: List, independent: Boolean, block: NativeCodeBuilder.(nativeValues: List) -> NativeExpression ): KotlinExpression { val bridgeArguments = mutableListOf() kotlinValues.forEach { (type, value) -> if (type.unwrapTypedefs() is RecordType) { builder.pushMemScoped() val bridgeArgument = "$value.getPointer(memScope).rawValue" bridgeArguments.add(BridgeTypedKotlinValue(BridgedType.NATIVE_PTR, bridgeArgument)) } else { val info = mirror(declarationMapper, type).info bridgeArguments.add(BridgeTypedKotlinValue(info.bridgedType, info.argToBridged(value))) } } val unwrappedReturnType = returnType.unwrapTypedefs() val kniRetVal = "kniRetVal" val bridgeReturnType = when (unwrappedReturnType) { VoidType -> BridgedType.VOID is RecordType -> { val mirror = mirror(declarationMapper, returnType) val tmpVarName = kniRetVal // We clear in the finally block. builder.out("val $tmpVarName = nativeHeap.alloc<${mirror.pointedType.render(builder.scope)}>()") builder.pushBlock(start = "try {", end = "} finally { nativeHeap.free($tmpVarName) }") bridgeArguments.add(BridgeTypedKotlinValue(BridgedType.NATIVE_PTR, "$tmpVarName.rawPtr")) BridgedType.VOID } else -> { val mirror = mirror(declarationMapper, returnType) mirror.info.bridgedType } } val callExpr = simpleBridgeGenerator.kotlinToNative( nativeBacked, bridgeReturnType, bridgeArguments, independent ) { bridgeNativeValues -> val nativeValues = mutableListOf() kotlinValues.forEachIndexed { index, (type, _) -> val unwrappedType = type.unwrapTypedefs() if (unwrappedType is RecordType) { nativeValues.add("*(${unwrappedType.decl.spelling}*)${bridgeNativeValues[index]}") } else { nativeValues.add( mirror(declarationMapper, type).info.cFromBridged( bridgeNativeValues[index], scope, nativeBacked ) ) } } val nativeResult = block(nativeValues) when (unwrappedReturnType) { is VoidType -> { out(nativeResult + ";") "" } is RecordType -> { val kniStructResult = "kniStructResult" out("${unwrappedReturnType.decl.spelling} $kniStructResult = $nativeResult;") out("memcpy(${bridgeNativeValues.last()}, &$kniStructResult, sizeof($kniStructResult));") "" } else -> { nativeResult } } } val result = when (unwrappedReturnType) { is VoidType -> callExpr is RecordType -> { builder.out(callExpr) "$kniRetVal.readValue()" } else -> { val mirror = mirror(declarationMapper, returnType) mirror.info.argFromBridged(callExpr, builder.scope, nativeBacked) } } return result } override fun nativeToKotlin( builder: NativeCodeBuilder, nativeBacked: NativeBacked, returnType: Type, nativeValues: List, block: KotlinCodeBuilder.(kotlinValues: List) -> KotlinExpression ): NativeExpression { val bridgeArguments = mutableListOf() nativeValues.forEachIndexed { _, (type, value) -> val bridgeArgument = if (type.unwrapTypedefs() is RecordType) { BridgeTypedNativeValue(BridgedType.NATIVE_PTR, "&$value") } else { val info = mirror(declarationMapper, type).info BridgeTypedNativeValue(info.bridgedType, value) } bridgeArguments.add(bridgeArgument) } val unwrappedReturnType = returnType.unwrapTypedefs() val kniRetVal = "kniRetVal" val bridgeReturnType = when (unwrappedReturnType) { VoidType -> BridgedType.VOID is RecordType -> { val tmpVarName = kniRetVal builder.out("${unwrappedReturnType.decl.spelling} $tmpVarName;") bridgeArguments.add(BridgeTypedNativeValue(BridgedType.NATIVE_PTR, "&$tmpVarName")) BridgedType.VOID } else -> { val mirror = mirror(declarationMapper, returnType) mirror.info.bridgedType } } val callExpr = simpleBridgeGenerator.nativeToKotlin( nativeBacked, bridgeReturnType, bridgeArguments ) { bridgeKotlinValues -> val kotlinValues = mutableListOf() nativeValues.forEachIndexed { index, (type, _) -> val mirror = mirror(declarationMapper, type) if (type.unwrapTypedefs() is RecordType) { val pointedTypeName = mirror.pointedType.render(this.scope) kotlinValues.add( "interpretPointed<$pointedTypeName>(${bridgeKotlinValues[index]}).readValue()" ) } else { kotlinValues.add(mirror.info.argFromBridged(bridgeKotlinValues[index], this.scope, nativeBacked)) } } val kotlinResult = block(kotlinValues) when (unwrappedReturnType) { is RecordType -> { "$kotlinResult.write(${bridgeKotlinValues.last()})" } is VoidType -> { kotlinResult } else -> { mirror(declarationMapper, returnType).info.argToBridged(kotlinResult) } } } val result = when (unwrappedReturnType) { is VoidType -> callExpr is RecordType -> { builder.out("$callExpr;") kniRetVal } else -> { mirror(declarationMapper, returnType).info.cFromBridged(callExpr, builder.scope, nativeBacked) } } return result } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/Mappings.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.* interface DeclarationMapper { fun getKotlinClassForPointed(structDecl: StructDecl): Classifier fun isMappedToStrict(enumDef: EnumDef): Boolean fun getKotlinNameForValue(enumDef: EnumDef): String fun getPackageFor(declaration: TypeDeclaration): String val useUnsignedTypes: Boolean } fun DeclarationMapper.isMappedToSigned(integerType: IntegerType): Boolean = integerType.isSigned || !useUnsignedTypes fun DeclarationMapper.getKotlinClassFor( objCClassOrProtocol: ObjCClassOrProtocol, isMeta: Boolean = false ): Classifier { val pkg = if (objCClassOrProtocol.isForwardDeclaration) { when (objCClassOrProtocol) { is ObjCClass -> "objcnames.classes" is ObjCProtocol -> "objcnames.protocols" } } else { this.getPackageFor(objCClassOrProtocol) } val className = objCClassOrProtocol.kotlinClassName(isMeta) return Classifier.topLevel(pkg, className) } fun PrimitiveType.getKotlinType(declarationMapper: DeclarationMapper): KotlinClassifierType = when (this) { is CharType -> KotlinTypes.byte is BoolType -> KotlinTypes.boolean // TODO: C primitive types should probably be generated as type aliases for Kotlin types. is IntegerType -> if (declarationMapper.isMappedToSigned(this)) { when (this.size) { 1 -> KotlinTypes.byte 2 -> KotlinTypes.short 4 -> KotlinTypes.int 8 -> KotlinTypes.long else -> TODO(this.toString()) } } else { when (this.size) { 1 -> KotlinTypes.uByte 2 -> KotlinTypes.uShort 4 -> KotlinTypes.uInt 8 -> KotlinTypes.uLong else -> TODO(this.toString()) } } is FloatingType -> when (this.size) { 4 -> KotlinTypes.float 8 -> KotlinTypes.double else -> TODO(this.toString()) } is VectorType -> { /// @todo assert elementType and size here KotlinTypes.vector128 } else -> throw NotImplementedError() } private fun PrimitiveType.getBridgedType(declarationMapper: DeclarationMapper): BridgedType { val kotlinType = this.getKotlinType(declarationMapper) return BridgedType.values().single { it.kotlinType == kotlinType } } internal val ObjCPointer.isNullable: Boolean get() = this.nullability != ObjCPointer.Nullability.NonNull /** * Describes the Kotlin types used to represent some C type. */ sealed class TypeMirror(val pointedType: KotlinClassifierType, val info: TypeInfo) { /** * Type to be used in bindings for argument or return value. */ abstract val argType: KotlinType /** * Mirror for C type to be represented in Kotlin as by-value type. */ class ByValue( pointedType: KotlinClassifierType, info: TypeInfo, val valueType: KotlinType, val nullable: Boolean = (info is TypeInfo.Pointer) ) : TypeMirror(pointedType, info) { override val argType: KotlinType get() = valueType.makeNullableAsSpecified(nullable) } /** * Mirror for C type to be represented in Kotlin as by-ref type. */ class ByRef(pointedType: KotlinClassifierType, info: TypeInfo) : TypeMirror(pointedType, info) { override val argType: KotlinType get() = KotlinTypes.cValue.typeWith(pointedType) } } /** * Describes various type conversions for [TypeMirror]. */ sealed class TypeInfo { /** * The conversion from [TypeMirror.argType] to [bridgedType]. */ abstract fun argToBridged(expr: KotlinExpression): KotlinExpression /** * The conversion from [bridgedType] to [TypeMirror.argType]. */ abstract fun argFromBridged( expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked ): KotlinExpression abstract val bridgedType: BridgedType open fun cFromBridged( expr: NativeExpression, scope: NativeScope, nativeBacked: NativeBacked ): NativeExpression = expr open fun cToBridged(expr: NativeExpression): NativeExpression = expr /** * If this info is for [TypeMirror.ByValue], then this method describes how to * construct pointed-type from value type. */ abstract fun constructPointedType(valueType: KotlinType): KotlinClassifierType class Primitive(override val bridgedType: BridgedType, val varClass: Classifier) : TypeInfo() { override fun argToBridged(expr: KotlinExpression) = expr override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = expr override fun constructPointedType(valueType: KotlinType) = varClass.typeWith(valueType) } class Boolean : TypeInfo() { override fun argToBridged(expr: KotlinExpression) = "$expr.toByte()" override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = "$expr.toBoolean()" override val bridgedType: BridgedType get() = BridgedType.BYTE override fun cFromBridged(expr: NativeExpression, scope: NativeScope, nativeBacked: NativeBacked) = "($expr) ? 1 : 0" override fun cToBridged(expr: NativeExpression) = "($expr) ? 1 : 0" override fun constructPointedType(valueType: KotlinType) = KotlinTypes.booleanVarOf.typeWith(valueType) } class Enum(val clazz: Classifier, override val bridgedType: BridgedType) : TypeInfo() { override fun argToBridged(expr: KotlinExpression) = "$expr.value" override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = scope.reference(clazz) + ".byValue($expr)" override fun constructPointedType(valueType: KotlinType) = clazz.nested("Var").type // TODO: improve } class Pointer(val pointee: KotlinType, val cPointee: Type) : TypeInfo() { override fun argToBridged(expr: String) = "$expr.rawValue" override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = "interpretCPointer<${pointee.render(scope)}>($expr)" override val bridgedType: BridgedType get() = BridgedType.NATIVE_PTR override fun cFromBridged(expr: NativeExpression, scope: NativeScope, nativeBacked: NativeBacked) = "(${getPointerTypeStringRepresentation(cPointee)})$expr" override fun constructPointedType(valueType: KotlinType) = KotlinTypes.cPointerVarOf.typeWith(valueType) } class ObjCPointerInfo(val kotlinType: KotlinType, val type: ObjCPointer) : TypeInfo() { override fun argToBridged(expr: String) = "$expr.objcPtr()" override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = "interpretObjCPointerOrNull<${kotlinType.render(scope)}>($expr)" + if (type.isNullable) "" else "!!" override val bridgedType: BridgedType get() = BridgedType.OBJC_POINTER override fun constructPointedType(valueType: KotlinType) = KotlinTypes.objCObjectVar.typeWith(valueType) } class ObjCBlockPointerInfo(val kotlinType: KotlinFunctionType, val type: ObjCBlockPointer) : TypeInfo() { override val bridgedType: BridgedType get() = BridgedType.OBJC_POINTER // When passing Kotlin function as block pointer from Kotlin to native, // it first gets wrapped by a holder in [argToBridged], // and then converted to block in [cFromBridged]. override fun argToBridged(expr: KotlinExpression): KotlinExpression = "createKotlinObjectHolder($expr)" override fun cFromBridged( expr: NativeExpression, scope: NativeScope, nativeBacked: NativeBacked ): NativeExpression { val mappingBridgeGenerator = scope.mappingBridgeGenerator val blockParameters = type.parameterTypes.mapIndexed { index, it -> "p$index" to it.getStringRepresentation() }.joinToString { "${it.second} ${it.first}" } val blockReturnType = type.returnType.getStringRepresentation() val kniFunction = "kniFunction" val codeBuilder = NativeCodeBuilder(scope) return buildString { append("({ ") // Statement expression begins. append("id $kniFunction = $expr; ") // Note: it gets captured below. append("($kniFunction == nil) ? nil : ") append("(id)") // Cast the block to `id`. append("^$blockReturnType($blockParameters) {") // Block begins. // As block body, generate the code which simply bridges to Kotlin and calls the Kotlin function: mappingBridgeGenerator.nativeToKotlin( codeBuilder, nativeBacked, type.returnType, type.parameterTypes.mapIndexed { index, it -> TypedNativeValue(it, "p$index") } + TypedNativeValue(ObjCIdType(ObjCPointer.Nullability.Nullable, emptyList()), kniFunction) ) { kotlinValues -> val kotlinFunctionType = kotlinType.render(this.scope) val kotlinFunction = "unwrapKotlinObjectHolder<$kotlinFunctionType>(${kotlinValues.last()})" "$kotlinFunction(${kotlinValues.dropLast(1).joinToString()})" }.let { codeBuilder.out("return $it;") } codeBuilder.lines.joinTo(this, separator = " ") append(" };") // Block ends. append(" })") // Statement expression ends. } } // When passing block pointer as Kotlin function from native to Kotlin, // it is converted to Kotlin function in [cFromBridged]. override fun cToBridged(expr: NativeExpression): NativeExpression = expr override fun argFromBridged( expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked ): KotlinExpression { val mappingBridgeGenerator = scope.mappingBridgeGenerator val funParameters = type.parameterTypes.mapIndexed { index, _ -> "p$index" to kotlinType.parameterTypes[index] }.joinToString { "${it.first}: ${it.second.render(scope)}" } val funReturnType = kotlinType.returnType.render(scope) val codeBuilder = KotlinCodeBuilder(scope) val kniBlockPtr = "kniBlockPtr" // Build the anonymous function expression: val anonymousFun = buildString { append("fun($funParameters): $funReturnType {\n") // Anonymous function begins. // As function body, generate the code which simply bridges to native and calls the block: mappingBridgeGenerator.kotlinToNative( codeBuilder, nativeBacked, type.returnType, type.parameterTypes.mapIndexed { index, it -> TypedKotlinValue(it, "p$index") } + TypedKotlinValue(PointerType(VoidType), "interpretCPointer($kniBlockPtr)"), independent = true ) { nativeValues -> val type = type val blockType = blockTypeStringRepresentation(type) val objCBlock = "((__bridge $blockType)${nativeValues.last()})" "$objCBlock(${nativeValues.dropLast(1).joinToString()})" }.let { codeBuilder.returnResult(it) } codeBuilder.build().joinTo(this, separator = "\n") append("}") // Anonymous function ends. } val nullOutput = if (type.isNullable) "null" else "throw NullPointerException()" return "$expr.let { $kniBlockPtr -> if (kniBlockPtr == nativeNullPtr) $nullOutput else $anonymousFun }" } override fun constructPointedType(valueType: KotlinType): KotlinClassifierType { return Classifier.topLevel("kotlinx.cinterop", "ObjCBlockVar").typeWith(valueType) } } class ByRef(val pointed: KotlinType) : TypeInfo() { override fun argToBridged(expr: String) = error(pointed) override fun argFromBridged(expr: KotlinExpression, scope: KotlinScope, nativeBacked: NativeBacked) = error(pointed) override val bridgedType: BridgedType get() = error(pointed) override fun cFromBridged(expr: NativeExpression, scope: NativeScope, nativeBacked: NativeBacked) = error(pointed) override fun cToBridged(expr: String) = error(pointed) // TODO: this method must not exist. override fun constructPointedType(valueType: KotlinType): KotlinClassifierType = error(pointed) } } fun mirrorPrimitiveType(type: PrimitiveType, declarationMapper: DeclarationMapper): TypeMirror.ByValue { val varClassName = when (type) { is CharType -> "ByteVar" is BoolType -> "BooleanVar" is IntegerType -> if (declarationMapper.isMappedToSigned(type)) { when (type.size) { 1 -> "ByteVar" 2 -> "ShortVar" 4 -> "IntVar" 8 -> "LongVar" else -> TODO(type.toString()) } } else { when (type.size) { 1 -> "UByteVar" 2 -> "UShortVar" 4 -> "UIntVar" 8 -> "ULongVar" else -> TODO(type.toString()) } } is FloatingType -> when (type.size) { 4 -> "FloatVar" 8 -> "DoubleVar" else -> TODO(type.toString()) } is VectorType -> { "Vector128Var" } else -> TODO(type.toString()) } val varClass = Classifier.topLevel("kotlinx.cinterop", varClassName) val varClassOf = Classifier.topLevel("kotlinx.cinterop", "${varClassName}Of") val info = if (type is BoolType) { TypeInfo.Boolean() } else { TypeInfo.Primitive(type.getBridgedType(declarationMapper), varClassOf) } return TypeMirror.ByValue(varClass.type, info, type.getKotlinType(declarationMapper)) } private fun byRefTypeMirror(pointedType: KotlinClassifierType) : TypeMirror.ByRef { val info = TypeInfo.ByRef(pointedType) return TypeMirror.ByRef(pointedType, info) } fun mirror(declarationMapper: DeclarationMapper, type: Type): TypeMirror = when (type) { is PrimitiveType -> mirrorPrimitiveType(type, declarationMapper) is RecordType -> byRefTypeMirror(declarationMapper.getKotlinClassForPointed(type.decl).type) is EnumType -> { val pkg = declarationMapper.getPackageFor(type.def) val kotlinName = declarationMapper.getKotlinNameForValue(type.def) .let { mangleSimple(it) } // enum class requires additional mangling when { declarationMapper.isMappedToStrict(type.def) -> { val bridgedType = (type.def.baseType.unwrapTypedefs() as PrimitiveType).getBridgedType(declarationMapper) val clazz = Classifier.topLevel(pkg, kotlinName) val info = TypeInfo.Enum(clazz, bridgedType) TypeMirror.ByValue(clazz.nested("Var").type, info, clazz.type) } !type.def.isAnonymous -> { val baseTypeMirror = mirror(declarationMapper, type.def.baseType) TypeMirror.ByValue( Classifier.topLevel(pkg, kotlinName + "Var").typeAbbreviation(baseTypeMirror.pointedType), baseTypeMirror.info, Classifier.topLevel(pkg, kotlinName).typeAbbreviation(baseTypeMirror.argType) ) } else -> mirror(declarationMapper, type.def.baseType) } } is PointerType -> { val pointeeType = type.pointeeType val unwrappedPointeeType = pointeeType.unwrapTypedefs() if (unwrappedPointeeType is VoidType) { val info = TypeInfo.Pointer(KotlinTypes.cOpaque, pointeeType) TypeMirror.ByValue(KotlinTypes.cOpaquePointerVar, info, KotlinTypes.cOpaquePointer) } else if (unwrappedPointeeType is ArrayType) { mirror(declarationMapper, pointeeType) } else { val pointeeMirror = mirror(declarationMapper, pointeeType) val info = TypeInfo.Pointer(pointeeMirror.pointedType, pointeeType) TypeMirror.ByValue( KotlinTypes.cPointerVar.typeWith(pointeeMirror.pointedType), info, KotlinTypes.cPointer.typeWith(pointeeMirror.pointedType) ) } } is ArrayType -> { // TODO: array type doesn't exactly correspond neither to pointer nor to value. val elemTypeMirror = mirror(declarationMapper, type.elemType) if (type.elemType.unwrapTypedefs() is ArrayType) { elemTypeMirror } else { val info = TypeInfo.Pointer(elemTypeMirror.pointedType, type.elemType) TypeMirror.ByValue( KotlinTypes.cArrayPointerVar.typeWith(elemTypeMirror.pointedType), info, KotlinTypes.cArrayPointer.typeWith(elemTypeMirror.pointedType) ) } } is FunctionType -> byRefTypeMirror(KotlinTypes.cFunction.typeWith(getKotlinFunctionType(declarationMapper, type))) is Typedef -> { val baseType = mirror(declarationMapper, type.def.aliased) val pkg = declarationMapper.getPackageFor(type.def) val name = type.def.name when (baseType) { is TypeMirror.ByValue -> { val valueType = Classifier.topLevel(pkg, name).typeAbbreviation(baseType.valueType) val underlyingPointedType = if (baseType.info is TypeInfo.Pointer) { KotlinTypes.cPointerVarOf.typeWith(valueType) } else { baseType.pointedType } val pointedType = Classifier.topLevel(pkg, "${name}Var").typeAbbreviation(underlyingPointedType) TypeMirror.ByValue( pointedType, baseType.info, valueType, nullable = baseType.nullable) } is TypeMirror.ByRef -> TypeMirror.ByRef( Classifier.topLevel(pkg, name).typeAbbreviation(baseType.pointedType), baseType.info ) } } is ObjCPointer -> objCPointerMirror(declarationMapper, type) else -> TODO(type.toString()) } internal tailrec fun ObjCClass.isNSStringOrSubclass(): Boolean = when (this.name) { "NSMutableString", // fast path and handling for forward declarations. "NSString" -> true else -> { val baseClass = this.baseClass if (baseClass != null) { baseClass.isNSStringOrSubclass() } else { false } } } internal fun ObjCClass.isNSStringSubclass(): Boolean = this.baseClass?.isNSStringOrSubclass() == true private fun objCPointerMirror(declarationMapper: DeclarationMapper, type: ObjCPointer): TypeMirror.ByValue { if (type is ObjCObjectPointer && type.def.isNSStringOrSubclass()) { val valueType = KotlinTypes.string return objCMirror(valueType, TypeInfo.ObjCPointerInfo(valueType, type), type.isNullable) } val valueType = when (type) { is ObjCIdType -> { type.protocols.firstOrNull()?.let { declarationMapper.getKotlinClassFor(it) }?.type ?: KotlinTypes.any } is ObjCClassPointer -> KotlinTypes.objCClass.type is ObjCObjectPointer -> { when (type.def.name) { "NSArray" -> KotlinTypes.list.typeWith(StarProjection) "NSMutableArray" -> KotlinTypes.mutableList.typeWith(KotlinTypes.any.makeNullable()) "NSSet" -> KotlinTypes.set.typeWith(StarProjection) "NSDictionary" -> KotlinTypes.map.typeWith(KotlinTypes.any.makeNullable(), StarProjection) else -> declarationMapper.getKotlinClassFor(type.def).type } } is ObjCInstanceType -> TODO(type.toString()) // Must have already been handled. is ObjCBlockPointer -> return objCBlockPointerMirror(declarationMapper, type) } return objCMirror(valueType, TypeInfo.ObjCPointerInfo(valueType, type), type.isNullable) } private fun objCBlockPointerMirror(declarationMapper: DeclarationMapper, type: ObjCBlockPointer): TypeMirror.ByValue { val returnType = if (type.returnType.unwrapTypedefs() is VoidType) { KotlinTypes.unit } else { mirror(declarationMapper, type.returnType).argType } val kotlinType = KotlinFunctionType( type.parameterTypes.map { mirror(declarationMapper, it).argType }, returnType ) val info = TypeInfo.ObjCBlockPointerInfo(kotlinType, type) return objCMirror(kotlinType, info, type.isNullable) } private fun objCMirror(valueType: KotlinType, info: TypeInfo, nullable: Boolean) = TypeMirror.ByValue( info.constructPointedType(valueType.makeNullableAsSpecified(nullable)), info, valueType.makeNullable(), // All typedefs to Objective-C pointers would be nullable for simplicity nullable ) fun getKotlinFunctionType(declarationMapper: DeclarationMapper, type: FunctionType): KotlinFunctionType { val returnType = if (type.returnType.unwrapTypedefs() is VoidType) { KotlinTypes.unit } else { mirror(declarationMapper, type.returnType).argType } return KotlinFunctionType( type.parameterTypes.map { mirror(declarationMapper, it).argType }, returnType, nullable = false ) } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/ObjCStubs.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.* internal fun ObjCMethod.getKotlinParameterNames(forConstructorOrFactory: Boolean = false): List { val selectorParts = this.selector.split(":") val result = mutableListOf() fun String.mangled(): String { var mangled = this while (mangled in result) { mangled = "_$mangled" } return mangled } // The names of all parameters except first must depend only on the selector: this.parameters.forEachIndexed { index, _ -> if (index > 0) { val name = selectorParts[index].takeIf { it.isNotEmpty() } ?: "_$index" result.add(name.mangled()) } } this.parameters.firstOrNull()?.let { val name = this.getFirstKotlinParameterNameCandidate(forConstructorOrFactory) result.add(0, name.mangled()) } if (this.isVariadic) { result.add("args".mangled()) } return result } private fun ObjCMethod.getFirstKotlinParameterNameCandidate(forConstructorOrFactory: Boolean): String { if (forConstructorOrFactory) { val selectorPart = this.selector.takeWhile { it != ':' }.trimStart('_') if (selectorPart.startsWith("init")) { selectorPart.removePrefix("init").removePrefix("With") .takeIf { it.isNotEmpty() }?.let { return it.decapitalize() } } } return this.parameters.first().name?.takeIf { it.isNotEmpty() } ?: "_0" } private fun ObjCMethod.getKotlinParameters( stubIrBuilder: StubsBuildingContext, forConstructorOrFactory: Boolean ): List { if (this.isInit && this.parameters.isEmpty() && this.selector != "init") { // Create synthetic Unit parameter, just like Swift does in this case: val parameterName = this.selector.removePrefix("init").removePrefix("With").decapitalize() return listOf(FunctionParameterStub(parameterName, KotlinTypes.unit.toStubIrType())) // Note: this parameter is explicitly handled in compiler. } val names = getKotlinParameterNames(forConstructorOrFactory) // TODO: consider refactoring. val result = mutableListOf() this.parameters.mapIndexedTo(result) { index, it -> val kotlinType = stubIrBuilder.mirror(it.type).argType val name = names[index] val annotations = if (it.nsConsumed) listOf(AnnotationStub.ObjC.Consumed) else emptyList() FunctionParameterStub(name, kotlinType.toStubIrType(), isVararg = false, annotations = annotations) } if (this.isVariadic) { result += FunctionParameterStub( names.last(), KotlinTypes.any.makeNullable().toStubIrType(), isVararg = true, annotations = emptyList() ) } return result } private class ObjCMethodStubBuilder( private val method: ObjCMethod, private val container: ObjCContainer, private val isDesignatedInitializer: Boolean, override val context: StubsBuildingContext ) : StubElementBuilder { private val isStret: Boolean private val stubReturnType: StubType val annotations = mutableListOf() private val kotlinMethodParameters: List private val external: Boolean private val receiver: ReceiverParameterStub? private val name: String = method.kotlinName private val origin = StubOrigin.ObjCMethod(method, container) private val modality: MemberStubModality private val isOverride: Boolean = container is ObjCClassOrProtocol && method.isOverride(container) init { val returnType = method.getReturnType(container.classOrProtocol) isStret = returnType.isStret(context.configuration.target) stubReturnType = if (returnType.unwrapTypedefs() is VoidType) { KotlinTypes.unit } else { context.mirror(returnType).argType }.toStubIrType() val methodAnnotation = AnnotationStub.ObjC.Method( method.selector, method.encoding, isStret ) annotations += buildObjCMethodAnnotations(methodAnnotation) kotlinMethodParameters = method.getKotlinParameters(context, forConstructorOrFactory = false) external = (container !is ObjCProtocol) modality = when (container) { is ObjCClass -> MemberStubModality.OPEN is ObjCProtocol -> if (method.isOptional) MemberStubModality.OPEN else MemberStubModality.ABSTRACT is ObjCCategory -> MemberStubModality.FINAL } receiver = if (container is ObjCCategory) { val receiverType = ClassifierStubType(context.getKotlinClassFor(container.clazz, isMeta = method.isClass)) ReceiverParameterStub(receiverType) } else null } private fun buildObjCMethodAnnotations(main: AnnotationStub): List = listOfNotNull( main, AnnotationStub.ObjC.ConsumesReceiver.takeIf { method.nsConsumesSelf }, AnnotationStub.ObjC.ReturnsRetained.takeIf { method.nsReturnsRetained } ) fun isDefaultConstructor(): Boolean = method.isInit && method.parameters.isEmpty() override fun build(): List { val replacement = if (method.isInit) { val parameters = method.getKotlinParameters(context, forConstructorOrFactory = true) when (container) { is ObjCClass -> { annotations.add(0, deprecatedInit( container.kotlinClassName(method.isClass), kotlinMethodParameters.map { it.name }, factory = false )) val designated = isDesignatedInitializer || context.configuration.disableDesignatedInitializerChecks val annotations = listOf(AnnotationStub.ObjC.Constructor(method.selector, designated)) val constructor = ConstructorStub(parameters, annotations, isPrimary = false, origin = origin) constructor } is ObjCCategory -> { assert(!method.isClass) val clazz = context.getKotlinClassFor(container.clazz, isMeta = false).type annotations.add(0, deprecatedInit( clazz.classifier.getRelativeFqName(), kotlinMethodParameters.map { it.name }, factory = true )) val factoryAnnotation = AnnotationStub.ObjC.Factory( method.selector, method.encoding, isStret ) val annotations = buildObjCMethodAnnotations(factoryAnnotation) val originalReturnType = method.getReturnType(container.clazz) val typeParameter = TypeParameterStub("T", clazz.toStubIrType()) val returnType = if (originalReturnType is ObjCPointer) { typeParameter.getStubType(originalReturnType.isNullable) } else { // This shouldn't happen actually. this.stubReturnType } val typeArgument = TypeArgumentStub(typeParameter.getStubType(false)) val receiverType = ClassifierStubType(KotlinTypes.objCClassOf, listOf(typeArgument)) val receiver = ReceiverParameterStub(receiverType) val createMethod = FunctionStub( "create", returnType, parameters, receiver = receiver, typeParameters = listOf(typeParameter), external = true, origin = StubOrigin.ObjCCategoryInitMethod(method), annotations = annotations, modality = MemberStubModality.FINAL ) createMethod } is ObjCProtocol -> null } } else { null } return listOfNotNull( FunctionStub( name, stubReturnType, kotlinMethodParameters.toList(), origin, annotations.toList(), external, receiver, modality, emptyList(), isOverride), replacement ) } } internal val ObjCContainer.classOrProtocol: ObjCClassOrProtocol get() = when (this) { is ObjCClassOrProtocol -> this is ObjCCategory -> this.clazz } private fun deprecatedInit(className: String, initParameterNames: List, factory: Boolean): AnnotationStub { val replacement = if (factory) "$className.create" else className val replacementKind = if (factory) "factory method" else "constructor" val replaceWith = "$replacement(${initParameterNames.joinToString { it.asSimpleName() }})" return AnnotationStub.Deprecated("Use $replacementKind instead", replaceWith, DeprecationLevel.ERROR) } internal val ObjCMethod.kotlinName: String get() { val candidate = selector.split(":").first() val trimmed = candidate.trimEnd('_') return if (trimmed == "equals" && parameters.size == 1 || (trimmed == "hashCode" || trimmed == "toString") && parameters.size == 0) { candidate + "_" } else { candidate } } internal val ObjCClassOrProtocol.protocolsWithSupers: Sequence get() = this.protocols.asSequence().flatMap { sequenceOf(it) + it.protocolsWithSupers } internal val ObjCClassOrProtocol.immediateSuperTypes: Sequence get() { val baseClass = (this as? ObjCClass)?.baseClass if (baseClass != null) { return sequenceOf(baseClass) + this.protocols.asSequence() } return this.protocols.asSequence() } internal val ObjCClassOrProtocol.selfAndSuperTypes: Sequence get() = sequenceOf(this) + this.superTypes internal val ObjCClassOrProtocol.superTypes: Sequence get() = this.immediateSuperTypes.flatMap { it.selfAndSuperTypes }.distinct() internal fun ObjCClassOrProtocol.declaredMethods(isClass: Boolean): Sequence = this.methods.asSequence().filter { it.isClass == isClass } @Suppress("UNUSED_PARAMETER") internal fun Sequence.inheritedTo(container: ObjCClassOrProtocol, isMeta: Boolean): Sequence = this // TODO: exclude methods that are marked as unavailable in [container]. internal fun ObjCClassOrProtocol.inheritedMethods(isClass: Boolean): Sequence = this.immediateSuperTypes.flatMap { it.methodsWithInherited(isClass) } .distinctBy { it.selector } .inheritedTo(this, isClass) internal fun ObjCClassOrProtocol.methodsWithInherited(isClass: Boolean): Sequence = (this.declaredMethods(isClass) + this.inheritedMethods(isClass)).distinctBy { it.selector } internal fun ObjCClass.getDesignatedInitializerSelectors(result: MutableSet): Set { // Note: Objective-C initializers act as usual methods and thus are inherited by subclasses. // Swift considers all super initializers to be available (unless otherwise specified explicitly), // but seems to consider them as non-designated if class declares its own ones explicitly. // Simulate the similar behaviour: val explicitlyDesignatedInitializers = this.methods.filter { it.isExplicitlyDesignatedInitializer && !it.isClass } if (explicitlyDesignatedInitializers.isNotEmpty()) { explicitlyDesignatedInitializers.mapTo(result) { it.selector } } else { this.declaredMethods(isClass = false).filter { it.isInit }.mapTo(result) { it.selector } this.baseClass?.getDesignatedInitializerSelectors(result) } this.superTypes.filterIsInstance() .flatMap { it.declaredMethods(isClass = false) }.filter { it.isInit } .mapTo(result) { it.selector } return result } internal fun ObjCMethod.isOverride(container: ObjCClassOrProtocol): Boolean = container.superTypes.any { superType -> superType.methods.any(this::replaces) } internal abstract class ObjCContainerStubBuilder( final override val context: StubsBuildingContext, private val container: ObjCClassOrProtocol, protected val metaContainerStub: ObjCContainerStubBuilder? ) : StubElementBuilder { private val isMeta: Boolean get() = metaContainerStub == null private val designatedInitializerSelectors = if (container is ObjCClass && !isMeta) { container.getDesignatedInitializerSelectors(mutableSetOf()) } else { emptySet() } private val methods: List private val properties: List private val protocolGetter: String? init { val superMethods = container.inheritedMethods(isMeta) // Add all methods declared in the class or protocol: var methods = container.declaredMethods(isMeta) // Exclude those which are identically declared in super types: methods -= superMethods // Add some special methods from super types: methods += superMethods.filter { it.returnsInstancetype() || it.isInit } // Add methods from adopted protocols that must be implemented according to Kotlin rules: if (container is ObjCClass) { methods += container.protocolsWithSupers.flatMap { it.declaredMethods(isMeta) }.filter { !it.isOptional } } // Add methods inherited from multiple supertypes that must be defined according to Kotlin rules: methods += container.immediateSuperTypes .flatMap { superType -> val methodsWithInherited = superType.methodsWithInherited(isMeta).inheritedTo(container, isMeta) // Select only those which are represented as non-abstract in Kotlin: when (superType) { is ObjCClass -> methodsWithInherited is ObjCProtocol -> methodsWithInherited.filter { it.isOptional } } } .groupBy { it.selector } .mapNotNull { (_, inheritedMethods) -> if (inheritedMethods.size > 1) inheritedMethods.first() else null } this.methods = methods.distinctBy { it.selector }.toList() this.properties = container.properties.filter { property -> property.getter.isClass == isMeta && // Select only properties that don't override anything: superMethods.none { property.getter.replaces(it) || property.setter?.replaces(it) ?: false } } } private val methodToStub = methods.map { it to ObjCMethodStubBuilder(it, container, it.selector in designatedInitializerSelectors, context) }.toMap() private val propertyBuilders = properties.mapNotNull { createObjCPropertyBuilder(context, it, container, this.methodToStub) } private val modality = when (container) { is ObjCClass -> ClassStubModality.OPEN is ObjCProtocol -> ClassStubModality.INTERFACE } private val classifier = context.getKotlinClassFor(container, isMeta) private val externalObjCAnnotation = when (container) { is ObjCProtocol -> { protocolGetter = if (metaContainerStub != null) { metaContainerStub.protocolGetter!! } else { // TODO: handle the case when protocol getter stub can't be compiled. context.generateNextUniqueId("kniprot_") } AnnotationStub.ObjC.ExternalClass(protocolGetter) } is ObjCClass -> { protocolGetter = null val binaryName = container.binaryName AnnotationStub.ObjC.ExternalClass("", binaryName ?: "") } } private val interfaces: List by lazy { val interfaces = mutableListOf() if (container is ObjCClass) { val baseClass = container.baseClass val baseClassifier = if (baseClass != null) { context.getKotlinClassFor(baseClass, isMeta) } else { if (isMeta) KotlinTypes.objCObjectBaseMeta else KotlinTypes.objCObjectBase } interfaces += baseClassifier.type.toStubIrType() } container.protocols.forEach { interfaces += context.getKotlinClassFor(it, isMeta).type.toStubIrType() } if (interfaces.isEmpty()) { assert(container is ObjCProtocol) val classifier = if (isMeta) KotlinTypes.objCObjectMeta else KotlinTypes.objCObject interfaces += classifier.type.toStubIrType() } if (!isMeta && container.isProtocolClass()) { // TODO: map Protocol type to ObjCProtocol instead. interfaces += KotlinTypes.objCProtocol.type.toStubIrType() } interfaces } private fun buildBody(): Pair, List> { val defaultConstructor = if (container is ObjCClass && methodToStub.values.none { it.isDefaultConstructor() }) { // Always generate default constructor. // If it is not produced for an init method, then include it manually: ConstructorStub( isPrimary = false, visibility = VisibilityModifier.PROTECTED, origin = StubOrigin.Synthetic.DefaultConstructor) } else null return Pair( propertyBuilders.flatMap { it.build() }, methodToStub.values.flatMap { it.build() } + listOfNotNull(defaultConstructor) ) } protected fun buildClassStub(origin: StubOrigin, companion: ClassStub.Companion? = null): ClassStub { val (properties, methods) = buildBody() return ClassStub.Simple( classifier, properties = properties, methods = methods.filterIsInstance(), constructors = methods.filterIsInstance(), origin = origin, modality = modality, annotations = listOf(externalObjCAnnotation), interfaces = interfaces, companion = companion ) } } internal sealed class ObjCClassOrProtocolStubBuilder( context: StubsBuildingContext, private val container: ObjCClassOrProtocol ) : ObjCContainerStubBuilder( context, container, metaContainerStub = object : ObjCContainerStubBuilder(context, container, metaContainerStub = null) { override fun build(): List { val origin = when (container) { is ObjCProtocol -> StubOrigin.ObjCProtocol(container, isMeta = true) is ObjCClass -> StubOrigin.ObjCClass(container, isMeta = true) } return listOf(buildClassStub(origin)) } } ) internal class ObjCProtocolStubBuilder( context: StubsBuildingContext, private val protocol: ObjCProtocol ) : ObjCClassOrProtocolStubBuilder(context, protocol), StubElementBuilder { override fun build(): List { val classStub = buildClassStub(StubOrigin.ObjCProtocol(protocol, isMeta = false)) return listOf(*metaContainerStub!!.build().toTypedArray(), classStub) } } internal class ObjCClassStubBuilder( context: StubsBuildingContext, private val clazz: ObjCClass ) : ObjCClassOrProtocolStubBuilder(context, clazz), StubElementBuilder { override fun build(): List { val companionSuper = ClassifierStubType(context.getKotlinClassFor(clazz, isMeta = true)) val objCClassType = KotlinTypes.objCClassOf.typeWith( context.getKotlinClassFor(clazz, isMeta = false).type ).toStubIrType() val superClassInit = SuperClassInit(companionSuper) val companionClassifier = context.getKotlinClassFor(clazz, isMeta = false).nested("Companion") val companion = ClassStub.Companion(companionClassifier, emptyList(), superClassInit, listOf(objCClassType)) val classStub = buildClassStub(StubOrigin.ObjCClass(clazz, isMeta = false), companion) return listOf(*metaContainerStub!!.build().toTypedArray(), classStub) } } class GeneratedObjCCategoriesMembers { private val propertyNames = mutableSetOf() private val instanceMethodSelectors = mutableSetOf() private val classMethodSelectors = mutableSetOf() fun register(method: ObjCMethod): Boolean = (if (method.isClass) classMethodSelectors else instanceMethodSelectors).add(method.selector) fun register(property: ObjCProperty): Boolean = propertyNames.add(property.name) } internal class ObjCCategoryStubBuilder( override val context: StubsBuildingContext, private val category: ObjCCategory ) : StubElementBuilder { private val generatedMembers = context.generatedObjCCategoriesMembers .getOrPut(category.clazz, { GeneratedObjCCategoriesMembers() }) private val methodToBuilder = category.methods.filter { generatedMembers.register(it) }.map { it to ObjCMethodStubBuilder(it, category, isDesignatedInitializer = false, context = context) }.toMap() private val methodBuilders get() = methodToBuilder.values private val propertyBuilders = category.properties.filter { generatedMembers.register(it) }.mapNotNull { createObjCPropertyBuilder(context, it, category, methodToBuilder) } override fun build(): List { val description = "${category.clazz.name} (${category.name})" val meta = StubContainerMeta( "// @interface $description", "// @end; // $description" ) val container = SimpleStubContainer( meta = meta, functions = methodBuilders.flatMap { it.build() }, properties = propertyBuilders.flatMap { it.build() } ) return listOf(container) } } private fun createObjCPropertyBuilder( context: StubsBuildingContext, property: ObjCProperty, container: ObjCContainer, methodToStub: Map ): ObjCPropertyStubBuilder? { // Note: the code below assumes that if the property is generated, // then its accessors are also generated as explicit methods. val getterStub = methodToStub[property.getter] ?: return null val setterStub = property.setter?.let { methodToStub[it] ?: return null } return ObjCPropertyStubBuilder(context, property, container, getterStub, setterStub) } private class ObjCPropertyStubBuilder( override val context: StubsBuildingContext, private val property: ObjCProperty, private val container: ObjCContainer, private val getterBuilder: ObjCMethodStubBuilder, private val setterMethod: ObjCMethodStubBuilder? ) : StubElementBuilder { override fun build(): List { val type = property.getType(container.classOrProtocol) val kotlinType = context.mirror(type).argType val getter = PropertyAccessor.Getter.ExternalGetter(annotations = getterBuilder.annotations) val setter = property.setter?.let { PropertyAccessor.Setter.ExternalSetter(annotations = setterMethod!!.annotations) } val kind = setter?.let { PropertyStub.Kind.Var(getter, it) } ?: PropertyStub.Kind.Val(getter) val modality = MemberStubModality.FINAL val receiver = when (container) { is ObjCClassOrProtocol -> null is ObjCCategory -> ClassifierStubType(context.getKotlinClassFor(container.clazz, isMeta = property.getter.isClass)) } val origin = StubOrigin.ObjCProperty(property, container) return listOf(PropertyStub(mangleSimple(property.name), kotlinType.toStubIrType(), kind, modality, receiver, origin = origin)) } } fun ObjCClassOrProtocol.kotlinClassName(isMeta: Boolean): String { val baseClassName = when (this) { is ObjCClass -> this.name is ObjCProtocol -> "${this.name}Protocol" } return if (isMeta) "${baseClassName}Meta" else baseClassName } internal fun ObjCClassOrProtocol.isProtocolClass(): Boolean = when (this) { is ObjCClass -> (name == "Protocol" || binaryName == "Protocol") is ObjCProtocol -> false } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/SimpleBridgeGenerator.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen /** * The type which has exact counterparts on both Kotlin and native side and can be directly passed through bridges. */ enum class BridgedType(val kotlinType: KotlinClassifierType, val convertor: String? = null) { BYTE(KotlinTypes.byte, "toByte"), SHORT(KotlinTypes.short, "toShort"), INT(KotlinTypes.int, "toInt"), LONG(KotlinTypes.long, "toLong"), UBYTE(KotlinTypes.uByte, "toUByte"), USHORT(KotlinTypes.uShort, "toUShort"), UINT(KotlinTypes.uInt, "toUInt"), ULONG(KotlinTypes.uLong, "toULong"), FLOAT(KotlinTypes.float, "toFloat"), DOUBLE(KotlinTypes.double, "toDouble"), VECTOR128(KotlinTypes.vector128), NATIVE_PTR(KotlinTypes.nativePtr), OBJC_POINTER(KotlinTypes.nativePtr), VOID(KotlinTypes.unit) } data class BridgeTypedKotlinValue(val type: BridgedType, val value: KotlinExpression) data class BridgeTypedNativeValue(val type: BridgedType, val value: NativeExpression) /** * The entity which depends on native bridges. */ interface NativeBacked /** * Generates simple bridges between Kotlin and native, passing [BridgedType] values. */ interface SimpleBridgeGenerator { val topLevelNativeScope: NativeScope /** * Generates the expression to convert given Kotlin values to native counterparts, pass through the bridge, * use inside the native code produced by [block] and then return the result back. * * @param block produces native code lines into the builder and returns the expression to be used as the result. */ fun kotlinToNative( nativeBacked: NativeBacked, returnType: BridgedType, kotlinValues: List, independent: Boolean, block: NativeCodeBuilder.(nativeValues: List) -> NativeExpression ): KotlinExpression /** * Generates the expression to convert given native values to Kotlin counterparts, pass through the bridge, * use inside the Kotlin code produced by [block] and then return the result back. */ fun nativeToKotlin( nativeBacked: NativeBacked, returnType: BridgedType, nativeValues: List, block: KotlinCodeBuilder.(kotlinValues: List) -> KotlinExpression ): NativeExpression fun insertNativeBridge( nativeBacked: NativeBacked, kotlinLines: List, nativeLines: List ) /** * Prepares all requested native bridges. */ fun prepare(): NativeBridges } interface NativeBridges { /** * @return `true` iff given entity is supported by these bridges, * i.e. all bridges it depends on can be successfully generated. */ fun isSupported(nativeBacked: NativeBacked): Boolean val kotlinLines: Sequence val nativeLines: Sequence } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/SimpleBridgeGeneratorImpl.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.CompilationWithPCH import org.jetbrains.kotlin.native.interop.indexer.Language import org.jetbrains.kotlin.native.interop.indexer.mapFragmentIsCompilable internal val INVALID_CLANG_IDENTIFIER_REGEX = "[^a-zA-Z1-9_]".toRegex() class SimpleBridgeGeneratorImpl( private val platform: KotlinPlatform, private val pkgName: String, private val jvmFileClassName: String, private val libraryForCStubs: CompilationWithPCH, override val topLevelNativeScope: NativeScope, private val topLevelKotlinScope: KotlinScope ) : SimpleBridgeGenerator { private var nextUniqueId = 0 private val BridgedType.nativeType: String get() = when (platform) { KotlinPlatform.JVM -> when (this) { BridgedType.BYTE -> "jbyte" BridgedType.SHORT -> "jshort" BridgedType.INT -> "jint" BridgedType.LONG -> "jlong" BridgedType.UBYTE -> "jbyte" BridgedType.USHORT -> "jshort" BridgedType.UINT -> "jint" BridgedType.ULONG -> "jlong" BridgedType.FLOAT -> "jfloat" BridgedType.DOUBLE -> "jdouble" BridgedType.VECTOR128 -> TODO() BridgedType.NATIVE_PTR -> "jlong" BridgedType.OBJC_POINTER -> TODO() BridgedType.VOID -> "void" } KotlinPlatform.NATIVE -> when (this) { BridgedType.BYTE -> "int8_t" BridgedType.SHORT -> "int16_t" BridgedType.INT -> "int32_t" BridgedType.LONG -> "int64_t" BridgedType.UBYTE -> "uint8_t" BridgedType.USHORT -> "uint16_t" BridgedType.UINT -> "uint32_t" BridgedType.ULONG -> "uint64_t" BridgedType.FLOAT -> "float" BridgedType.DOUBLE -> "double" BridgedType.VECTOR128 -> TODO() // "float __attribute__ ((__vector_size__ (16)))" BridgedType.NATIVE_PTR -> "void*" BridgedType.OBJC_POINTER -> "id" BridgedType.VOID -> "void" } } private inner class NativeBridge(val kotlinLines: List, val nativeLines: List) override fun kotlinToNative( nativeBacked: NativeBacked, returnType: BridgedType, kotlinValues: List, independent: Boolean, block: NativeCodeBuilder.(nativeValues: List) -> NativeExpression ): KotlinExpression { val kotlinLines = mutableListOf() val nativeLines = mutableListOf() val kotlinFunctionName = "kniBridge${nextUniqueId++}" val kotlinParameters = kotlinValues.withIndex().joinToString { "p${it.index}: ${it.value.type.kotlinType.render(topLevelKotlinScope)}" } val callExpr = "$kotlinFunctionName(${kotlinValues.joinToString { it.value }})" val cFunctionParameters = when (platform) { KotlinPlatform.JVM -> mutableListOf( "jniEnv" to "JNIEnv*", "jclss" to "jclass" ) KotlinPlatform.NATIVE -> mutableListOf() } kotlinValues.withIndex().mapTo(cFunctionParameters) { "p${it.index}" to it.value.type.nativeType } val joinedCParameters = cFunctionParameters.joinToString { (name, type) -> "$type $name" } val cReturnType = returnType.nativeType val cFunctionHeader = when (platform) { KotlinPlatform.JVM -> { val funcFullName = buildString { if (pkgName.isNotEmpty()) { append(pkgName) append('.') } append(jvmFileClassName) append('.') append(kotlinFunctionName) } val functionName = "Java_" + funcFullName.replace("_", "_1").replace('.', '_').replace("$", "_00024") "JNIEXPORT $cReturnType JNICALL $functionName ($joinedCParameters)" } KotlinPlatform.NATIVE -> { val functionName = pkgName.replace(INVALID_CLANG_IDENTIFIER_REGEX, "_") + "_$kotlinFunctionName" if (independent) kotlinLines.add("@" + topLevelKotlinScope.reference(KotlinTypes.independent)) kotlinLines.add("@SymbolName(${functionName.quoteAsKotlinLiteral()})") "$cReturnType $functionName ($joinedCParameters)" } } nativeLines.add(cFunctionHeader + " {") buildNativeCodeLines(topLevelNativeScope) { val cExpr = block(cFunctionParameters.takeLast(kotlinValues.size).map { (name, _) -> name }) if (returnType != BridgedType.VOID) { out("return ($cReturnType)$cExpr;") } }.forEach { nativeLines.add(" $it") } if (libraryForCStubs.language == Language.OBJECTIVE_C) { // Prevent Objective-C exceptions from passing to Kotlin: nativeLines.add(1, "@try {") nativeLines.add("} @catch (id e) { objc_terminate(); }") // 'objc_terminate' will report the exception. // TODO: consider implementing this in bitcode generator. } nativeLines.add("}") val kotlinReturnType = returnType.kotlinType.render(topLevelKotlinScope) kotlinLines.add("private external fun $kotlinFunctionName($kotlinParameters): $kotlinReturnType") val nativeBridge = NativeBridge(kotlinLines, nativeLines) nativeBridges.add(nativeBacked to nativeBridge) return callExpr } override fun nativeToKotlin( nativeBacked: NativeBacked, returnType: BridgedType, nativeValues: List, block: KotlinCodeBuilder.(arguments: List) -> KotlinExpression ): NativeExpression { if (platform != KotlinPlatform.NATIVE) TODO() val kotlinLines = mutableListOf() val nativeLines = mutableListOf() val kotlinFunctionName = "kniBridge${nextUniqueId++}" val kotlinParameters = nativeValues.withIndex().map { "p${it.index}" to it.value.type.kotlinType } val joinedKotlinParameters = kotlinParameters.joinToString { "${it.first}: ${it.second.render(topLevelKotlinScope)}" } val cFunctionParameters = nativeValues.withIndex().map { "p${it.index}" to it.value.type.nativeType } val joinedCParameters = cFunctionParameters.joinToString { (name, type) -> "$type $name" } val cReturnType = returnType.nativeType val symbolName = pkgName.replace(INVALID_CLANG_IDENTIFIER_REGEX, "_") + "_$kotlinFunctionName" kotlinLines.add("@kotlin.native.internal.ExportForCppRuntime(${symbolName.quoteAsKotlinLiteral()})") val cFunctionHeader = "$cReturnType $symbolName($joinedCParameters)" nativeLines.add("$cFunctionHeader;") val kotlinReturnType = returnType.kotlinType.render(topLevelKotlinScope) kotlinLines.add("private fun $kotlinFunctionName($joinedKotlinParameters): $kotlinReturnType {") buildKotlinCodeLines(topLevelKotlinScope) { var kotlinExpr = block(kotlinParameters.map { (name, _) -> name }) if (returnType == BridgedType.OBJC_POINTER) { // The Kotlin code may lose the ownership on this pointer after returning from the bridge, // so retain the pointer and autorelease it: kotlinExpr = "objc_retainAutoreleaseReturnValue($kotlinExpr)" // (Objective-C does the same for returned pointers). } returnResult(kotlinExpr) }.forEach { kotlinLines.add(" $it") } kotlinLines.add("}") insertNativeBridge(nativeBacked, kotlinLines, nativeLines) return "$symbolName(${nativeValues.joinToString { it.value }})" } override fun insertNativeBridge(nativeBacked: NativeBacked, kotlinLines: List, nativeLines: List) { val nativeBridge = NativeBridge(kotlinLines, nativeLines) nativeBridges.add(nativeBacked to nativeBridge) } private val nativeBridges = mutableListOf>() override fun prepare(): NativeBridges { val includedBridges = mutableListOf() val excludedClients = mutableSetOf() nativeBridges.map { it.second.nativeLines } .mapFragmentIsCompilable(libraryForCStubs) .forEachIndexed { index, isCompilable -> if (!isCompilable) { excludedClients.add(nativeBridges[index].first) } } nativeBridges.mapNotNullTo(includedBridges) { (nativeBacked, nativeBridge) -> if (nativeBacked in excludedClients) { null } else { nativeBridge } } // TODO: exclude unused bridges. return object : NativeBridges { override val kotlinLines: Sequence get() = includedBridges.asSequence().flatMap { it.kotlinLines.asSequence() } override val nativeLines: Sequence get() = includedBridges.asSequence().flatMap { it.nativeLines.asSequence() } override fun isSupported(nativeBacked: NativeBacked): Boolean = nativeBacked !in excludedClients } } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StructRendering.kt ================================================ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.* fun tryRenderStructOrUnion(def: StructDef): String? = when (def.kind) { StructDef.Kind.STRUCT -> tryRenderStruct(def) StructDef.Kind.UNION -> tryRenderUnion(def) } private fun tryRenderStruct(def: StructDef): String? { val isPackedStruct = def.fields.any { !it.isAligned } var offset = 0L return buildString { append("struct") if (isPackedStruct) append(" __attribute__((packed))") append(" { ") def.members.forEachIndexed { index, it -> val name = "p$index" val decl = when (it) { is Field -> { val defaultAlignment = if (isPackedStruct) 1L else it.typeAlign val alignment = guessAlignment(offset, it.offsetBytes, defaultAlignment) ?: return null offset = it.offsetBytes + it.typeSize tryRenderVar(it.type, name) ?.plus(if (alignment == defaultAlignment) "" else "__attribute__((aligned($alignment)))") } is BitField, // TODO: tryRenderVar(it.type, name)?.plus(" : ${it.size}") is IncompleteField -> null // e.g. flexible array member. } ?: return null append("$decl; ") } append("}") } } private fun guessAlignment(offset: Long, paddedOffset: Long, defaultAlignment: Long): Long? = longArrayOf(defaultAlignment, 1L, 2L, 4L, 8L, 16L, 32L).firstOrNull { alignUp(offset, it) == paddedOffset } private fun alignUp(x: Long, alignment: Long): Long = (x + alignment - 1) and ((alignment - 1).inv()) private fun tryRenderUnion(def: StructDef): String? = if (def.members.any { it.offset != 0L }) null else buildString { append("union { ") def.members.forEachIndexed { index, it -> val decl = when (it) { is Field -> tryRenderVar(it.type, "p$index") is BitField, is IncompleteField -> null } ?: return null append("$decl; ") } append("}") } private fun tryRenderVar(type: Type, name: String): String? = when (type) { CharType, is BoolType -> "char $name" is IntegerType -> "${type.spelling} $name" is FloatingType -> "${type.spelling} $name" is VectorType -> "${type.spelling} $name" is RecordType -> "${tryRenderStructOrUnion(type.decl.def!!)} $name" is EnumType -> tryRenderVar(type.def.baseType, name) is PointerType -> "void* $name" is ConstArrayType -> tryRenderVar(type.elemType, "$name[${type.length}]") is IncompleteArrayType -> tryRenderVar(type.elemType, "$name[]") is Typedef -> tryRenderVar(type.def.aliased, name) is ObjCPointer -> "void* $name" else -> null } private val Field.offsetBytes: Long get() { require(this.offset % 8 == 0L) return this.offset / 8 } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIr.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.* // TODO: Replace all usages of these strings with constants. const val cinteropPackage = "kotlinx.cinterop" const val cinteropInternalPackage = "$cinteropPackage.internal" interface StubIrElement { fun accept(visitor: StubIrVisitor, data: T): R } sealed class StubContainer : StubIrElement { abstract val meta: StubContainerMeta abstract val classes: List abstract val functions: List abstract val properties: List abstract val typealiases: List abstract val simpleContainers: List } /** * Meta information about [StubContainer]. * For example, can be used for comments in textual representation. */ class StubContainerMeta( val textAtStart: String = "", val textAtEnd: String = "" ) class SimpleStubContainer( override val meta: StubContainerMeta = StubContainerMeta(), override val classes: List = emptyList(), override val functions: List = emptyList(), override val properties: List = emptyList(), override val typealiases: List = emptyList(), override val simpleContainers: List = emptyList() ) : StubContainer() { override fun accept(visitor: StubIrVisitor, data: T): R { return visitor.visitSimpleStubContainer(this, data) } } val StubContainer.children: List get() = (classes as List) + properties + functions + typealiases /** * Marks that abstract value of such type can be passed as value. */ sealed class ValueStub class TypeParameterStub( val name: String, val upperBound: StubType? = null ) { fun getStubType(nullable: Boolean) = TypeParameterType(name, nullable = nullable, typeParameterDeclaration = this) } interface TypeArgument { object StarProjection : TypeArgument { override fun toString(): String = "*" } enum class Variance { INVARIANT, IN, OUT } } class TypeArgumentStub( val type: StubType, val variance: TypeArgument.Variance = TypeArgument.Variance.INVARIANT ) : TypeArgument { override fun toString(): String = type.toString() } /** * Represents a source of StubIr element. */ sealed class StubOrigin { /** * Special case when element of IR was generated. */ sealed class Synthetic : StubOrigin() { object CompanionObject : Synthetic() /** * Denotes default constructor that was generated and has no real origin. */ object DefaultConstructor : Synthetic() /** * CEnum.Companion.byValue. */ class EnumByValue(val enum: EnumDef) : Synthetic() /** * CEnum.value. */ class EnumValueField(val enum: EnumDef) : Synthetic() /** * E.CEnumVar.value. */ class EnumVarValueField(val enum: EnumDef) : Synthetic() } class ObjCCategoryInitMethod( val method: org.jetbrains.kotlin.native.interop.indexer.ObjCMethod ) : StubOrigin() class ObjCMethod( val method: org.jetbrains.kotlin.native.interop.indexer.ObjCMethod, val container: ObjCContainer ) : StubOrigin() class ObjCProperty( val property: org.jetbrains.kotlin.native.interop.indexer.ObjCProperty, val container: ObjCContainer ) : StubOrigin() class ObjCClass( val clazz: org.jetbrains.kotlin.native.interop.indexer.ObjCClass, val isMeta: Boolean ) : StubOrigin() class ObjCProtocol( val protocol: org.jetbrains.kotlin.native.interop.indexer.ObjCProtocol, val isMeta: Boolean ) : StubOrigin() class Enum(val enum: EnumDef) : StubOrigin() class EnumEntry(val constant: EnumConstant) : StubOrigin() class Function(val function: FunctionDecl) : StubOrigin() class Struct(val struct: StructDecl) : StubOrigin() class StructMember( val member: org.jetbrains.kotlin.native.interop.indexer.StructMember ) : StubOrigin() class Constant(val constantDef: ConstantDef): StubOrigin() class Global(val global: GlobalDecl) : StubOrigin() class TypeDef(val typedefDef: TypedefDef) : StubOrigin() class VarOf(val typeOrigin: StubOrigin) : StubOrigin() } interface StubElementWithOrigin : StubIrElement { val origin: StubOrigin } interface AnnotationHolder { val annotations: List } sealed class AnnotationStub(val classifier: Classifier) { sealed class ObjC(classifier: Classifier) : AnnotationStub(classifier) { object ConsumesReceiver : ObjC(cCallClassifier.nested("ConsumesReceiver")) object ReturnsRetained : ObjC(cCallClassifier.nested("ReturnsRetained")) class Method(val selector: String, val encoding: String, val isStret: Boolean = false) : ObjC(Classifier.topLevel(cinteropPackage, "ObjCMethod")) class Factory(val selector: String, val encoding: String, val isStret: Boolean = false) : ObjC(Classifier.topLevel(cinteropPackage, "ObjCFactory")) object Consumed : ObjC(cCallClassifier.nested("Consumed")) class Constructor(val selector: String, val designated: Boolean) : ObjC(Classifier.topLevel(cinteropPackage, "ObjCConstructor")) class ExternalClass(val protocolGetter: String = "", val binaryName: String = "") : ObjC(Classifier.topLevel(cinteropPackage, "ExternalObjCClass")) } sealed class CCall(classifier: Classifier) : AnnotationStub(classifier) { object CString : CCall(cCallClassifier.nested("CString")) object WCString : CCall(cCallClassifier.nested("WCString")) class Symbol(val symbolName: String) : CCall(cCallClassifier) } class CStruct(val struct: String) : AnnotationStub(cStructClassifier) { class MemberAt(val offset: Long) : AnnotationStub(cStructClassifier.nested("MemberAt")) class ArrayMemberAt(val offset: Long) : AnnotationStub(cStructClassifier.nested("ArrayMemberAt")) class BitField(val offset: Long, val size: Int) : AnnotationStub(cStructClassifier.nested("BitField")) class VarType(val size: Long, val align: Int) : AnnotationStub(cStructClassifier.nested("VarType")) } class CNaturalStruct(val members: List) : AnnotationStub(Classifier.topLevel(cinteropPackage, "CNaturalStruct")) class CLength(val length: Long) : AnnotationStub(Classifier.topLevel(cinteropPackage, "CLength")) class Deprecated(val message: String, val replaceWith: String, val level: DeprecationLevel) : AnnotationStub(Classifier.topLevel("kotlin", "Deprecated")) { companion object { val unableToImport = Deprecated( "Unable to import this declaration", "", DeprecationLevel.ERROR ) val deprecatedCVariableCompanion = Deprecated( "Use sizeOf() or alignOf() instead.", "", DeprecationLevel.WARNING ) val deprecatedCEnumByValue = Deprecated( "Will be removed.", "", DeprecationLevel.WARNING ) } } class CEnumEntryAlias(val entryName: String) : AnnotationStub(Classifier.topLevel(cinteropInternalPackage, "CEnumEntryAlias")) class CEnumVarTypeSize(val size: Int) : AnnotationStub(Classifier.topLevel(cinteropInternalPackage, "CEnumVarTypeSize")) private companion object { val cCallClassifier = Classifier.topLevel(cinteropInternalPackage, "CCall") val cStructClassifier = Classifier.topLevel(cinteropInternalPackage, "CStruct") } } /** * Compile-time known values. */ sealed class ConstantStub : ValueStub() class StringConstantStub(val value: String) : ConstantStub() data class IntegralConstantStub(val value: Long, val size: Int, val isSigned: Boolean) : ConstantStub() data class DoubleConstantStub(val value: Double, val size: Int) : ConstantStub() data class PropertyStub( val name: String, val type: StubType, val kind: Kind, val modality: MemberStubModality = MemberStubModality.FINAL, val receiverType: StubType? = null, override val annotations: List = emptyList(), val origin: StubOrigin, val isOverride: Boolean = false ) : StubIrElement, AnnotationHolder { sealed class Kind { class Val( val getter: PropertyAccessor.Getter ) : Kind() class Var( val getter: PropertyAccessor.Getter, val setter: PropertyAccessor.Setter ) : Kind() class Constant(val constant: ConstantStub) : Kind() } override fun accept(visitor: StubIrVisitor, data: T): R { return visitor.visitProperty(this, data) } } enum class ClassStubModality { INTERFACE, OPEN, ABSTRACT, NONE } enum class VisibilityModifier { PRIVATE, PROTECTED, INTERNAL, PUBLIC } class GetConstructorParameter( val constructorParameterStub: FunctionParameterStub ) : ValueStub() class SuperClassInit( val type: StubType, val arguments: List = listOf() ) // TODO: Consider unifying these classes. sealed class ClassStub : StubContainer(), StubElementWithOrigin, AnnotationHolder { abstract val superClassInit: SuperClassInit? abstract val interfaces: List abstract val childrenClasses: List abstract val companion : Companion? abstract val classifier: Classifier class Simple( override val classifier: Classifier, val modality: ClassStubModality, constructors: List = emptyList(), methods: List = emptyList(), override val superClassInit: SuperClassInit? = null, override val interfaces: List = emptyList(), override val properties: List = emptyList(), override val origin: StubOrigin, override val annotations: List = emptyList(), override val childrenClasses: List = emptyList(), override val companion: Companion? = null, override val simpleContainers: List = emptyList() ) : ClassStub() { override val functions: List = constructors + methods } class Companion( override val classifier: Classifier, methods: List = emptyList(), override val superClassInit: SuperClassInit? = null, override val interfaces: List = emptyList(), override val properties: List = emptyList(), override val origin: StubOrigin = StubOrigin.Synthetic.CompanionObject, override val annotations: List = emptyList(), override val childrenClasses: List = emptyList(), override val simpleContainers: List = emptyList() ) : ClassStub() { override val companion: Companion? = null override val functions: List = methods } class Enum( override val classifier: Classifier, val entries: List, constructors: List, override val superClassInit: SuperClassInit? = null, override val interfaces: List = emptyList(), override val properties: List = emptyList(), override val origin: StubOrigin, override val annotations: List = emptyList(), override val childrenClasses: List = emptyList(), override val companion: Companion?= null, override val simpleContainers: List = emptyList() ) : ClassStub() { override val functions: List = constructors } override val meta: StubContainerMeta = StubContainerMeta() override val classes: List get() = childrenClasses + listOfNotNull(companion) override fun accept(visitor: StubIrVisitor, data: T) = visitor.visitClass(this, data) override val typealiases: List = emptyList() } class ReceiverParameterStub( val type: StubType ) class FunctionParameterStub( val name: String, val type: StubType, override val annotations: List = emptyList(), val isVararg: Boolean = false ) : AnnotationHolder enum class MemberStubModality { OPEN, FINAL, ABSTRACT } interface FunctionalStub : AnnotationHolder, StubIrElement, NativeBacked { val parameters: List } sealed class PropertyAccessor : FunctionalStub { sealed class Getter : PropertyAccessor() { override val parameters: List = emptyList() class SimpleGetter( override val annotations: List = emptyList(), val constant: ConstantStub? = null ) : Getter() class GetConstructorParameter( val constructorParameter: FunctionParameterStub, override val annotations: List = emptyList() ) : Getter() class ExternalGetter( override val annotations: List = emptyList() ) : Getter() class ArrayMemberAt( val offset: Long ) : Getter() { override val parameters: List = emptyList() override val annotations: List = emptyList() } class MemberAt( val offset: Long, val typeArguments: List = emptyList(), val hasValueAccessor: Boolean ) : Getter() { override val annotations: List = emptyList() } class ReadBits( val offset: Long, val size: Int, val signed: Boolean ) : Getter() { override val annotations: List = emptyList() } class InterpretPointed(val cGlobalName:String, pointedType: StubType) : Getter() { override val annotations: List = emptyList() val typeParameters: List = listOf(pointedType) } class GetEnumEntry( val enumEntryStub: EnumEntryStub, override val annotations: List = emptyList() ) : Getter() } sealed class Setter : PropertyAccessor() { override val parameters: List = emptyList() class SimpleSetter( override val annotations: List = emptyList() ) : Setter() class ExternalSetter( override val annotations: List = emptyList() ) : Setter() class MemberAt( val offset: Long, override val annotations: List = emptyList(), val typeArguments: List = emptyList() ) : Setter() class WriteBits( val offset: Long, val size: Int, override val annotations: List = emptyList() ) : Setter() } override fun accept(visitor: StubIrVisitor, data: T) = visitor.visitPropertyAccessor(this, data) } data class FunctionStub( val name: String, val returnType: StubType, override val parameters: List, override val origin: StubOrigin, override val annotations: List, val external: Boolean = false, val receiver: ReceiverParameterStub?, val modality: MemberStubModality, val typeParameters: List = emptyList(), val isOverride: Boolean = false, val hasStableParameterNames: Boolean = true ) : StubElementWithOrigin, FunctionalStub { override fun accept(visitor: StubIrVisitor, data: T) = visitor.visitFunction(this, data) } // TODO: should we support non-trivial constructors? class ConstructorStub( override val parameters: List = emptyList(), override val annotations: List = emptyList(), val isPrimary: Boolean, val visibility: VisibilityModifier = VisibilityModifier.PUBLIC, val origin: StubOrigin ) : FunctionalStub { override fun accept(visitor: StubIrVisitor, data: T) = visitor.visitConstructor(this, data) } class EnumEntryStub( val name: String, val constant: IntegralConstantStub, val origin: StubOrigin.EnumEntry, val ordinal: Int ) class TypealiasStub( val alias: Classifier, val aliasee: StubType, val origin: StubOrigin ) : StubIrElement { override fun accept(visitor: StubIrVisitor, data: T) = visitor.visitTypealias(this, data) } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.* import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull class BridgeBuilderResult( val kotlinFile: KotlinFile, val nativeBridges: NativeBridges, val propertyAccessorBridgeBodies: Map, val functionBridgeBodies: Map>, val excludedStubs: Set ) /** * Generates [NativeBridges] and corresponding function bodies and property accessors. */ class StubIrBridgeBuilder( private val context: StubIrContext, private val builderResult: StubIrBuilderResult) { private val globalAddressExpressions = mutableMapOf, KotlinExpression>() private val wrapperGenerator = CWrappersGenerator(context) private fun getGlobalAddressExpression(cGlobalName: String, accessor: PropertyAccessor) = globalAddressExpressions.getOrPut(Pair(cGlobalName, accessor)) { simpleBridgeGenerator.kotlinToNative( nativeBacked = accessor, returnType = BridgedType.NATIVE_PTR, kotlinValues = emptyList(), independent = false ) { "&$cGlobalName" } } private val declarationMapper = builderResult.declarationMapper private val kotlinFile = object : KotlinFile( context.configuration.pkgName, namesToBeDeclared = builderResult.stubs.computeNamesToBeDeclared(context.configuration.pkgName) ) { override val mappingBridgeGenerator: MappingBridgeGenerator get() = this@StubIrBridgeBuilder.mappingBridgeGenerator } private val simpleBridgeGenerator: SimpleBridgeGenerator = SimpleBridgeGeneratorImpl( context.platform, context.configuration.pkgName, context.jvmFileClassName, context.libraryForCStubs, topLevelNativeScope = object : NativeScope { override val mappingBridgeGenerator: MappingBridgeGenerator get() = this@StubIrBridgeBuilder.mappingBridgeGenerator }, topLevelKotlinScope = kotlinFile ) private val mappingBridgeGenerator: MappingBridgeGenerator = MappingBridgeGeneratorImpl(declarationMapper, simpleBridgeGenerator) private val propertyAccessorBridgeBodies = mutableMapOf() private val functionBridgeBodies = mutableMapOf>() private val excludedStubs = mutableSetOf() private val bridgeGeneratingVisitor = object : StubIrVisitor { override fun visitClass(element: ClassStub, data: StubContainer?) { element.annotations.filterIsInstance().firstOrNull()?.let { val origin = element.origin if (it.protocolGetter.isNotEmpty() && origin is StubOrigin.ObjCProtocol && !origin.isMeta) { val protocol = (element.origin as StubOrigin.ObjCProtocol).protocol // TODO: handle the case when protocol getter stub can't be compiled. generateProtocolGetter(it.protocolGetter, protocol) } } element.children.forEach { it.accept(this, element) } } override fun visitTypealias(element: TypealiasStub, data: StubContainer?) { } override fun visitFunction(element: FunctionStub, data: StubContainer?) { try { when { element.external -> tryProcessCCallAnnotation(element) element.isOptionalObjCMethod() -> { } element.origin is StubOrigin.Synthetic.EnumByValue -> { } data != null && data.isInterface -> { } else -> generateBridgeBody(element) } } catch (e: Throwable) { context.log("Warning: cannot generate bridge for ${element.name}.") excludedStubs += element } } private fun tryProcessCCallAnnotation(function: FunctionStub) { val origin = function.origin as? StubOrigin.Function ?: return val cCallAnnotation = function.annotations.firstIsInstanceOrNull() ?: return val wrapper = wrapperGenerator.generateCCalleeWrapper(origin.function, cCallAnnotation.symbolName) simpleBridgeGenerator.insertNativeBridge(function, emptyList(), wrapper.lines) } override fun visitProperty(element: PropertyStub, data: StubContainer?) { try { when (val kind = element.kind) { is PropertyStub.Kind.Constant -> { } is PropertyStub.Kind.Val -> { visitPropertyAccessor(kind.getter, data) } is PropertyStub.Kind.Var -> { visitPropertyAccessor(kind.getter, data) visitPropertyAccessor(kind.setter, data) } } } catch (e: Throwable) { context.log("Warning: cannot generate bridge for ${element.name}.") excludedStubs += element } } override fun visitConstructor(constructorStub: ConstructorStub, data: StubContainer?) { } override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: StubContainer?) { when (propertyAccessor) { is PropertyAccessor.Getter.SimpleGetter -> { when (propertyAccessor) { in builderResult.bridgeGenerationComponents.getterToBridgeInfo -> { val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(propertyAccessor) val typeInfo = extra.typeInfo propertyAccessorBridgeBodies[propertyAccessor] = typeInfo.argFromBridged(simpleBridgeGenerator.kotlinToNative( nativeBacked = propertyAccessor, returnType = typeInfo.bridgedType, kotlinValues = emptyList(), independent = false ) { typeInfo.cToBridged(expr = extra.cGlobalName) }, kotlinFile, nativeBacked = propertyAccessor) } in builderResult.bridgeGenerationComponents.arrayGetterInfo -> { val extra = builderResult.bridgeGenerationComponents.arrayGetterInfo.getValue(propertyAccessor) val typeInfo = extra.typeInfo val getAddressExpression = getGlobalAddressExpression(extra.cGlobalName, propertyAccessor) propertyAccessorBridgeBodies[propertyAccessor] = typeInfo.argFromBridged(getAddressExpression, kotlinFile, nativeBacked = propertyAccessor) + "!!" } } } is PropertyAccessor.Getter.ReadBits -> { val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(propertyAccessor) val rawType = extra.typeInfo.bridgedType val readBits = "readBits(this.rawPtr, ${propertyAccessor.offset}, ${propertyAccessor.size}, ${propertyAccessor.signed}).${rawType.convertor!!}()" val getExpr = extra.typeInfo.argFromBridged(readBits, kotlinFile, object : NativeBacked {}) propertyAccessorBridgeBodies[propertyAccessor] = getExpr } is PropertyAccessor.Setter.SimpleSetter -> when (propertyAccessor) { in builderResult.bridgeGenerationComponents.setterToBridgeInfo -> { val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(propertyAccessor) val typeInfo = extra.typeInfo val bridgedValue = BridgeTypedKotlinValue(typeInfo.bridgedType, typeInfo.argToBridged("value")) val setter = simpleBridgeGenerator.kotlinToNative( nativeBacked = propertyAccessor, returnType = BridgedType.VOID, kotlinValues = listOf(bridgedValue), independent = false ) { nativeValues -> out("${extra.cGlobalName} = ${typeInfo.cFromBridged( nativeValues.single(), scope, nativeBacked = propertyAccessor )};") "" } propertyAccessorBridgeBodies[propertyAccessor] = setter } } is PropertyAccessor.Setter.WriteBits -> { val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(propertyAccessor) val rawValue = extra.typeInfo.argToBridged("value") propertyAccessorBridgeBodies[propertyAccessor] = "writeBits(this.rawPtr, ${propertyAccessor.offset}, ${propertyAccessor.size}, $rawValue.toLong())" } is PropertyAccessor.Getter.InterpretPointed -> { val getAddressExpression = getGlobalAddressExpression(propertyAccessor.cGlobalName, propertyAccessor) propertyAccessorBridgeBodies[propertyAccessor] = getAddressExpression } is PropertyAccessor.Getter.ExternalGetter -> { if (propertyAccessor in builderResult.wrapperGenerationComponents.getterToWrapperInfo) { val extra = builderResult.wrapperGenerationComponents.getterToWrapperInfo.getValue(propertyAccessor) val cCallAnnotation = propertyAccessor.annotations.firstIsInstanceOrNull() ?: error("external getter for ${extra.global.name} wasn't marked with @CCall") val wrapper = if (extra.passViaPointer) { wrapperGenerator.generateCGlobalByPointerGetter(extra.global, cCallAnnotation.symbolName) } else { wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName) } simpleBridgeGenerator.insertNativeBridge(propertyAccessor, emptyList(), wrapper.lines) } } is PropertyAccessor.Setter.ExternalSetter -> { if (propertyAccessor in builderResult.wrapperGenerationComponents.setterToWrapperInfo) { val extra = builderResult.wrapperGenerationComponents.setterToWrapperInfo.getValue(propertyAccessor) val cCallAnnotation = propertyAccessor.annotations.firstIsInstanceOrNull() ?: error("external setter for ${extra.global.name} wasn't marked with @CCall") val wrapper = wrapperGenerator.generateCGlobalSetter(extra.global, cCallAnnotation.symbolName) simpleBridgeGenerator.insertNativeBridge(propertyAccessor, emptyList(), wrapper.lines) } } } } override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: StubContainer?) { simpleStubContainer.classes.forEach { it.accept(this, simpleStubContainer) } simpleStubContainer.functions.forEach { it.accept(this, simpleStubContainer) } simpleStubContainer.properties.forEach { it.accept(this, simpleStubContainer) } simpleStubContainer.typealiases.forEach { it.accept(this, simpleStubContainer) } simpleStubContainer.simpleContainers.forEach { it.accept(this, simpleStubContainer) } } } private fun isCValuesRef(type: StubType): Boolean = (type as? ClassifierStubType)?.let { it.classifier == KotlinTypes.cValuesRef } ?: false private fun generateBridgeBody(function: FunctionStub) { assert(context.platform == KotlinPlatform.JVM) { "Function ${function.name} was not marked as external." } assert(function.origin is StubOrigin.Function) { "Can't create bridge for ${function.name}" } val origin = function.origin as StubOrigin.Function val bodyGenerator = KotlinCodeBuilder(scope = kotlinFile) val bridgeArguments = mutableListOf() var isVararg = false function.parameters.forEachIndexed { index, parameter -> isVararg = isVararg or parameter.isVararg val parameterName = parameter.name.asSimpleName() val bridgeArgument = when { parameter in builderResult.bridgeGenerationComponents.cStringParameters -> { bodyGenerator.pushMemScoped() "$parameterName?.cstr?.getPointer(memScope)" } parameter in builderResult.bridgeGenerationComponents.wCStringParameters -> { bodyGenerator.pushMemScoped() "$parameterName?.wcstr?.getPointer(memScope)" } isCValuesRef(parameter.type) -> { bodyGenerator.pushMemScoped() bodyGenerator.getNativePointer(parameterName) } else -> { parameterName } } bridgeArguments += TypedKotlinValue(origin.function.parameters[index].type, bridgeArgument) } // TODO: Improve assertion message. assert(!isVararg || context.platform != KotlinPlatform.NATIVE) { "Function ${function.name} was processed incorrectly." } val result = mappingBridgeGenerator.kotlinToNative( bodyGenerator, function, origin.function.returnType, bridgeArguments, independent = false ) { nativeValues -> "${origin.function.name}(${nativeValues.joinToString()})" } bodyGenerator.returnResult(result) functionBridgeBodies[function] = bodyGenerator.build() } private fun generateProtocolGetter(protocolGetterName: String, protocol: ObjCProtocol) { val builder = NativeCodeBuilder(simpleBridgeGenerator.topLevelNativeScope) val nativeBacked = object : NativeBacked {} with(builder) { out("Protocol* $protocolGetterName() {") out(" return @protocol(${protocol.name});") out("}") } simpleBridgeGenerator.insertNativeBridge(nativeBacked, emptyList(), builder.lines) } fun build(): BridgeBuilderResult { bridgeGeneratingVisitor.visitSimpleStubContainer(builderResult.stubs, null) return BridgeBuilderResult( kotlinFile, simpleBridgeGenerator.prepare(), propertyAccessorBridgeBodies.toMap(), functionBridgeBodies.toMap(), excludedStubs.toSet() ) } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBuilder.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode import org.jetbrains.kotlin.native.interop.gen.jvm.InteropConfiguration import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.* /** * Components that are not passed via StubIr but required for bridge generation. */ class BridgeGenerationInfo(val cGlobalName: String, val typeInfo: TypeInfo) /** * Additional components that are required to generate bridges. * TODO: Metadata-based interop should not depend on these components. */ interface BridgeGenerationComponents { val setterToBridgeInfo: Map val getterToBridgeInfo: Map val arrayGetterInfo: Map val enumToTypeMirror: Map val wCStringParameters: Set val cStringParameters: Set } class BridgeGenerationComponentsBuilder { val getterToBridgeInfo = mutableMapOf() val setterToBridgeInfo = mutableMapOf() val arrayGetterBridgeInfo = mutableMapOf() val enumToTypeMirror = mutableMapOf() val wCStringParameters = mutableSetOf() val cStringParameters = mutableSetOf() fun build(): BridgeGenerationComponents = object : BridgeGenerationComponents { override val getterToBridgeInfo = this@BridgeGenerationComponentsBuilder.getterToBridgeInfo.toMap() override val setterToBridgeInfo = this@BridgeGenerationComponentsBuilder.setterToBridgeInfo.toMap() override val enumToTypeMirror = this@BridgeGenerationComponentsBuilder.enumToTypeMirror.toMap() override val wCStringParameters: Set = this@BridgeGenerationComponentsBuilder.wCStringParameters.toSet() override val cStringParameters: Set = this@BridgeGenerationComponentsBuilder.cStringParameters.toSet() override val arrayGetterInfo: Map = this@BridgeGenerationComponentsBuilder.arrayGetterBridgeInfo.toMap() } } /** * Components that are not passed via StubIr but required for generation of wrappers. */ class WrapperGenerationInfo(val global: GlobalDecl, val passViaPointer: Boolean = false) interface WrapperGenerationComponents { val getterToWrapperInfo: Map val setterToWrapperInfo: Map } class WrapperGenerationComponentsBuilder { val getterToWrapperInfo = mutableMapOf() val setterToWrapperInfo = mutableMapOf() fun build(): WrapperGenerationComponents = object : WrapperGenerationComponents { override val getterToWrapperInfo = this@WrapperGenerationComponentsBuilder.getterToWrapperInfo.toMap() override val setterToWrapperInfo = this@WrapperGenerationComponentsBuilder.setterToWrapperInfo.toMap() } } /** * Common part of all [StubIrBuilder] implementations. */ interface StubsBuildingContext { val configuration: InteropConfiguration fun mirror(type: Type): TypeMirror val declarationMapper: DeclarationMapper fun generateNextUniqueId(prefix: String): String val generatedObjCCategoriesMembers: MutableMap val platform: KotlinPlatform /** * In some cases StubIr should be different for metadata and sourcecode modes. * For example, it is impossible to represent call to superclass constructor in * metadata directly and arguments should be passed via annotations instead. */ val generationMode: GenerationMode fun isStrictEnum(enumDef: EnumDef): Boolean val macroConstantsByName: Map fun tryCreateIntegralStub(type: Type, value: Long): IntegralConstantStub? fun tryCreateDoubleStub(type: Type, value: Double): DoubleConstantStub? val bridgeComponentsBuilder: BridgeGenerationComponentsBuilder val wrapperComponentsBuilder: WrapperGenerationComponentsBuilder fun getKotlinClassFor(objCClassOrProtocol: ObjCClassOrProtocol, isMeta: Boolean = false): Classifier fun getKotlinClassForPointed(structDecl: StructDecl): Classifier fun isOverloading(func: FunctionDecl): Boolean } /** * */ internal interface StubElementBuilder { val context: StubsBuildingContext fun build(): List } class StubsBuildingContextImpl( private val stubIrContext: StubIrContext ) : StubsBuildingContext { override val configuration: InteropConfiguration = stubIrContext.configuration override val platform: KotlinPlatform = stubIrContext.platform override val generationMode: GenerationMode = stubIrContext.generationMode val imports: Imports = stubIrContext.imports private val nativeIndex: NativeIndex = stubIrContext.nativeIndex private var theCounter = 0 private val uniqFunctions = mutableSetOf() override fun isOverloading(func: FunctionDecl) = !uniqFunctions.add(func.name) // TODO: params & return type. override fun generateNextUniqueId(prefix: String) = prefix + pkgName.replace('.', '_') + theCounter++ override fun mirror(type: Type): TypeMirror = mirror(declarationMapper, type) /** * Indicates whether this enum should be represented as Kotlin enum. */ override fun isStrictEnum(enumDef: EnumDef): Boolean = with(enumDef) { if (this.isAnonymous) { return false } val name = this.kotlinName if (name in configuration.strictEnums) { return true } if (name in configuration.nonStrictEnums) { return false } // Let the simple heuristic decide: return !this.constants.any { it.isExplicitlyDefined } } override val generatedObjCCategoriesMembers = mutableMapOf() override val declarationMapper = object : DeclarationMapper { override fun getKotlinClassForPointed(structDecl: StructDecl): Classifier { val baseName = structDecl.kotlinName val pkg = when (platform) { KotlinPlatform.JVM -> pkgName KotlinPlatform.NATIVE -> if (structDecl.def == null) { cnamesStructsPackageName // to be imported as forward declaration. } else { getPackageFor(structDecl) } } return Classifier.topLevel(pkg, baseName) } override fun isMappedToStrict(enumDef: EnumDef): Boolean = isStrictEnum(enumDef) override fun getKotlinNameForValue(enumDef: EnumDef): String = enumDef.kotlinName override fun getPackageFor(declaration: TypeDeclaration): String { return imports.getPackage(declaration.location) ?: pkgName } override val useUnsignedTypes: Boolean get() = when (platform) { KotlinPlatform.JVM -> false KotlinPlatform.NATIVE -> true } } override val macroConstantsByName: Map = (nativeIndex.macroConstants + nativeIndex.wrappedMacros).associateBy { it.name } /** * The name to be used for this enum in Kotlin */ val EnumDef.kotlinName: String get() = if (spelling.startsWith("enum ")) { spelling.substringAfter(' ') } else { assert (!isAnonymous) spelling } private val pkgName: String get() = configuration.pkgName /** * The name to be used for this struct in Kotlin */ val StructDecl.kotlinName: String get() = stubIrContext.getKotlinName(this) override fun tryCreateIntegralStub(type: Type, value: Long): IntegralConstantStub? { val integerType = when (val unwrappedType = type.unwrapTypedefs()) { is IntegerType -> unwrappedType CharType -> IntegerType(1, true, "char") else -> return null } val size = integerType.size if (size != 1 && size != 2 && size != 4 && size != 8) return null return IntegralConstantStub(value, size, declarationMapper.isMappedToSigned(integerType)) } override fun tryCreateDoubleStub(type: Type, value: Double): DoubleConstantStub? { val unwrappedType = type.unwrapTypedefs() as? FloatingType ?: return null val size = unwrappedType.size if (size != 4 && size != 8) return null return DoubleConstantStub(value, size) } override val bridgeComponentsBuilder = BridgeGenerationComponentsBuilder() override val wrapperComponentsBuilder = WrapperGenerationComponentsBuilder() override fun getKotlinClassFor(objCClassOrProtocol: ObjCClassOrProtocol, isMeta: Boolean): Classifier { return declarationMapper.getKotlinClassFor(objCClassOrProtocol, isMeta) } override fun getKotlinClassForPointed(structDecl: StructDecl): Classifier { val classifier = declarationMapper.getKotlinClassForPointed(structDecl) return classifier } } data class StubIrBuilderResult( val stubs: SimpleStubContainer, val declarationMapper: DeclarationMapper, val bridgeGenerationComponents: BridgeGenerationComponents, val wrapperGenerationComponents: WrapperGenerationComponents ) /** * Produces [StubIrBuilderResult] for given [KotlinPlatform] using [InteropConfiguration]. */ class StubIrBuilder(private val context: StubIrContext) { private val configuration = context.configuration private val nativeIndex: NativeIndex = context.nativeIndex private val classes = mutableListOf() private val functions = mutableListOf() private val globals = mutableListOf() private val typealiases = mutableListOf() private val containers = mutableListOf() private fun addStubs(stubs: List) = stubs.forEach(this::addStub) private fun addStub(stub: StubIrElement) { when(stub) { is ClassStub -> classes += stub is FunctionStub -> functions += stub is PropertyStub -> globals += stub is TypealiasStub -> typealiases += stub is SimpleStubContainer -> containers += stub else -> error("Unexpected stub: $stub") } } private val excludedFunctions: Set get() = configuration.excludedFunctions private val excludedMacros: Set get() = configuration.excludedMacros private val buildingContext = StubsBuildingContextImpl(context) fun build(): StubIrBuilderResult { nativeIndex.objCProtocols.filter { !it.isForwardDeclaration }.forEach { generateStubsForObjCProtocol(it) } nativeIndex.objCClasses.filter { !it.isForwardDeclaration && !it.isNSStringSubclass()} .forEach { generateStubsForObjCClass(it) } nativeIndex.objCCategories.filter { !it.clazz.isNSStringSubclass() }.forEach { generateStubsForObjCCategory(it) } nativeIndex.structs.forEach { generateStubsForStruct(it) } nativeIndex.enums.forEach { generateStubsForEnum(it) } nativeIndex.functions.filter { it.name !in excludedFunctions }.forEach { generateStubsForFunction(it) } nativeIndex.typedefs.forEach { generateStubsForTypedef(it) } nativeIndex.globals.filter { it.name !in excludedFunctions }.forEach { generateStubsForGlobal(it) } nativeIndex.macroConstants.filter { it.name !in excludedMacros }.forEach { generateStubsForMacroConstant(it) } nativeIndex.wrappedMacros.filter { it.name !in excludedMacros }.forEach { generateStubsForWrappedMacro(it) } val meta = StubContainerMeta() val stubs = SimpleStubContainer( meta, classes.toList(), functions.toList(), globals.toList(), typealiases.toList(), containers.toList() ) return StubIrBuilderResult( stubs, buildingContext.declarationMapper, buildingContext.bridgeComponentsBuilder.build(), buildingContext.wrapperComponentsBuilder.build() ) } private fun generateStubsForWrappedMacro(macro: WrappedMacroDef) { try { generateStubsForGlobal(GlobalDecl(macro.name, macro.type, isConst = true)) } catch (e: Throwable) { context.log("Warning: cannot generate stubs for macro ${macro.name}") } } private fun generateStubsForMacroConstant(constant: ConstantDef) { try { addStubs(MacroConstantStubBuilder(buildingContext, constant).build()) } catch (e: Throwable) { context.log("Warning: cannot generate stubs for constant ${constant.name}") } } private fun generateStubsForEnum(enumDef: EnumDef) { try { addStubs(EnumStubBuilder(buildingContext, enumDef).build()) } catch (e: Throwable) { context.log("Warning: cannot generate definition for enum ${enumDef.spelling}") } } private fun generateStubsForFunction(func: FunctionDecl) { try { addStubs(FunctionStubBuilder(buildingContext, func, skipOverloads = true).build()) } catch (e: Throwable) { context.log("Warning: cannot generate stubs for function ${func.name}") } } private fun generateStubsForStruct(decl: StructDecl) { try { addStubs(StructStubBuilder(buildingContext, decl).build()) } catch (e: Throwable) { context.log("Warning: cannot generate definition for struct ${decl.spelling}") } } private fun generateStubsForTypedef(typedefDef: TypedefDef) { try { addStubs(TypedefStubBuilder(buildingContext, typedefDef).build()) } catch (e: Throwable) { context.log("Warning: cannot generate typedef ${typedefDef.name}") } } private fun generateStubsForGlobal(global: GlobalDecl) { try { addStubs(GlobalStubBuilder(buildingContext, global).build()) } catch (e: Throwable) { context.log("Warning: cannot generate stubs for global ${global.name}") } } private fun generateStubsForObjCProtocol(objCProtocol: ObjCProtocol) { addStubs(ObjCProtocolStubBuilder(buildingContext, objCProtocol).build()) } private fun generateStubsForObjCClass(objCClass: ObjCClass) { addStubs(ObjCClassStubBuilder(buildingContext, objCClass).build()) } private fun generateStubsForObjCCategory(objCCategory: ObjCCategory) { addStubs(ObjCCategoryStubBuilder(buildingContext, objCCategory).build()) } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrDriver.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import kotlinx.metadata.klib.KlibModuleMetadata import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode import org.jetbrains.kotlin.native.interop.gen.jvm.InteropConfiguration import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.* import java.io.File import java.util.* class StubIrContext( val log: (String) -> Unit, val configuration: InteropConfiguration, val nativeIndex: NativeIndex, val imports: Imports, val platform: KotlinPlatform, val generationMode: GenerationMode, val libName: String ) { val libraryForCStubs = configuration.library.copy( includes = mutableListOf().apply { add("stdint.h") add("string.h") if (platform == KotlinPlatform.JVM) { add("jni.h") } addAll(configuration.library.includes) }, compilerArgs = configuration.library.compilerArgs, additionalPreambleLines = configuration.library.additionalPreambleLines + when (configuration.library.language) { Language.C -> emptyList() Language.OBJECTIVE_C -> listOf("void objc_terminate();") } ).precompileHeaders() // TODO: Used only for JVM. val jvmFileClassName = if (configuration.pkgName.isEmpty()) { libName } else { configuration.pkgName.substringAfterLast('.') } val validPackageName = configuration.pkgName.split(".").joinToString(".") { if (it.matches(VALID_PACKAGE_NAME_REGEX)) it else "`$it`" } private val anonymousStructKotlinNames = mutableMapOf() private val forbiddenStructNames = run { val typedefNames = nativeIndex.typedefs.map { it.name } typedefNames.toSet() } /** * The name to be used for this struct in Kotlin */ fun getKotlinName(decl: StructDecl): String { val spelling = decl.spelling if (decl.isAnonymous) { val names = anonymousStructKotlinNames return names.getOrPut(decl) { "anonymousStruct${names.size + 1}" } } val strippedCName = if (spelling.startsWith("struct ") || spelling.startsWith("union ")) { spelling.substringAfter(' ') } else { spelling } // TODO: don't mangle struct names because it wouldn't work if the struct // is imported into another interop library. return if (strippedCName !in forbiddenStructNames) strippedCName else (strippedCName + "Struct") } fun addManifestProperties(properties: Properties) { val exportForwardDeclarations = configuration.exportForwardDeclarations.toMutableList() nativeIndex.structs .filter { it.def == null } .mapTo(exportForwardDeclarations) { "$cnamesStructsPackageName.${getKotlinName(it)}" } properties["exportForwardDeclarations"] = exportForwardDeclarations.joinToString(" ") // TODO: consider exporting Objective-C class and protocol forward refs. } companion object { private val VALID_PACKAGE_NAME_REGEX = "[a-zA-Z0-9_.]+".toRegex() } } class StubIrDriver( private val context: StubIrContext, private val options: DriverOptions ) { data class DriverOptions( val entryPoint: String?, val moduleName: String, val outCFile: File, val outKtFileCreator: () -> File ) sealed class Result { object SourceCode : Result() class Metadata(val metadata: KlibModuleMetadata): Result() } fun run(): Result { val (entryPoint, moduleName, outCFile, outKtFile) = options val builderResult = StubIrBuilder(context).build() val bridgeBuilderResult = StubIrBridgeBuilder(context, builderResult).build() outCFile.bufferedWriter().use { emitCFile(context, it, entryPoint, bridgeBuilderResult.nativeBridges) } return when (context.generationMode) { GenerationMode.SOURCE_CODE -> { emitSourceCode(outKtFile(), builderResult, bridgeBuilderResult) } GenerationMode.METADATA -> emitMetadata(builderResult, moduleName, bridgeBuilderResult) } } private fun emitSourceCode( outKtFile: File, builderResult: StubIrBuilderResult, bridgeBuilderResult: BridgeBuilderResult ): Result.SourceCode { outKtFile.bufferedWriter().use { ktFile -> StubIrTextEmitter(context, builderResult, bridgeBuilderResult).emit(ktFile) } return Result.SourceCode } private fun emitMetadata( builderResult: StubIrBuilderResult, moduleName: String, bridgeBuilderResult: BridgeBuilderResult ) = Result.Metadata(StubIrMetadataEmitter(context, builderResult, moduleName, bridgeBuilderResult).emit()) private fun emitCFile(context: StubIrContext, cFile: Appendable, entryPoint: String?, nativeBridges: NativeBridges) { val out = { it: String -> cFile.appendLine(it) } context.libraryForCStubs.preambleLines.forEach { out(it) } out("") out("// NOTE THIS FILE IS AUTO-GENERATED") out("") nativeBridges.nativeLines.forEach { out(it) } if (entryPoint != null) { out("extern int Konan_main(int argc, char** argv);") out("") out("__attribute__((__used__))") out("int $entryPoint(int argc, char** argv) {") out(" return Konan_main(argc, argv);") out("}") } } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.* internal class MacroConstantStubBuilder( override val context: StubsBuildingContext, private val constant: ConstantDef ) : StubElementBuilder { override fun build(): List { val kotlinName = constant.name val origin = StubOrigin.Constant(constant) val declaration = when (constant) { is IntegerConstantDef -> { val literal = context.tryCreateIntegralStub(constant.type, constant.value) ?: return emptyList() val kotlinType = context.mirror(constant.type).argType.toStubIrType() when (context.platform) { KotlinPlatform.NATIVE -> PropertyStub(kotlinName, kotlinType, PropertyStub.Kind.Constant(literal), origin = origin) // No reason to make it const val with backing field on Kotlin/JVM yet: KotlinPlatform.JVM -> { val getter = PropertyAccessor.Getter.SimpleGetter(constant = literal) PropertyStub(kotlinName, kotlinType, PropertyStub.Kind.Val(getter), origin = origin) } } } is FloatingConstantDef -> { val literal = context.tryCreateDoubleStub(constant.type, constant.value) ?: return emptyList() val kind = when (context.generationMode) { GenerationMode.SOURCE_CODE -> { PropertyStub.Kind.Val(PropertyAccessor.Getter.SimpleGetter(constant = literal)) } GenerationMode.METADATA -> { PropertyStub.Kind.Constant(literal) } } val kotlinType = context.mirror(constant.type).argType.toStubIrType() PropertyStub(kotlinName, kotlinType, kind, origin = origin) } is StringConstantDef -> { val literal = StringConstantStub(constant.value) val kind = when (context.generationMode) { GenerationMode.SOURCE_CODE -> { PropertyStub.Kind.Val(PropertyAccessor.Getter.SimpleGetter(constant = literal)) } GenerationMode.METADATA -> { PropertyStub.Kind.Constant(literal) } } PropertyStub(kotlinName, KotlinTypes.string.toStubIrType(), kind, origin = origin) } else -> return emptyList() } return listOf(declaration) } } internal class StructStubBuilder( override val context: StubsBuildingContext, private val decl: StructDecl ) : StubElementBuilder { override fun build(): List { val platform = context.platform val def = decl.def ?: return generateForwardStruct(decl) val structAnnotation: AnnotationStub? = if (platform == KotlinPlatform.JVM) { if (def.kind == StructDef.Kind.STRUCT && def.fieldsHaveDefaultAlignment()) { AnnotationStub.CNaturalStruct(def.members) } else { null } } else { tryRenderStructOrUnion(def)?.let { AnnotationStub.CStruct(it) } } val classifier = context.getKotlinClassForPointed(decl) val fields: List = def.fields.map { field -> try { assert(field.name.isNotEmpty()) assert(field.offset % 8 == 0L) val offset = field.offset / 8 val fieldRefType = context.mirror(field.type) val unwrappedFieldType = field.type.unwrapTypedefs() val origin = StubOrigin.StructMember(field) val fieldName = mangleSimple(field.name) if (unwrappedFieldType is ArrayType) { val type = (fieldRefType as TypeMirror.ByValue).valueType val annotations = if (platform == KotlinPlatform.JVM) { val length = getArrayLength(unwrappedFieldType) // TODO: @CLength should probably be used on types instead of properties. listOf(AnnotationStub.CLength(length)) } else { emptyList() } val getter = when (context.generationMode) { GenerationMode.SOURCE_CODE -> PropertyAccessor.Getter.ArrayMemberAt(offset) GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.ArrayMemberAt(offset))) } val kind = PropertyStub.Kind.Val(getter) // TODO: Should receiver be added? PropertyStub(fieldName, type.toStubIrType(), kind, annotations = annotations, origin = origin) } else { val pointedType = fieldRefType.pointedType.toStubIrType() val pointedTypeArgument = TypeArgumentStub(pointedType) if (fieldRefType is TypeMirror.ByValue) { val getter: PropertyAccessor.Getter val setter: PropertyAccessor.Setter when (context.generationMode) { GenerationMode.SOURCE_CODE -> { getter = PropertyAccessor.Getter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument), hasValueAccessor = true) setter = PropertyAccessor.Setter.MemberAt(offset, typeArguments = listOf(pointedTypeArgument)) } GenerationMode.METADATA -> { getter = PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset))) setter = PropertyAccessor.Setter.ExternalSetter(listOf(AnnotationStub.CStruct.MemberAt(offset))) } } val kind = PropertyStub.Kind.Var(getter, setter) PropertyStub(fieldName, fieldRefType.argType.toStubIrType(), kind, origin = origin) } else { val accessor = when (context.generationMode) { GenerationMode.SOURCE_CODE -> PropertyAccessor.Getter.MemberAt(offset, hasValueAccessor = false) GenerationMode.METADATA -> PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.MemberAt(offset))) } val kind = PropertyStub.Kind.Val(accessor) PropertyStub(fieldName, pointedType, kind, origin = origin) } } } catch (e: Throwable) { null } } val bitFields: List = def.bitFields.map { field -> val typeMirror = context.mirror(field.type) val typeInfo = typeMirror.info val kotlinType = typeMirror.argType val signed = field.type.isIntegerTypeSigned() val fieldName = mangleSimple(field.name) val kind = when (context.generationMode) { GenerationMode.SOURCE_CODE -> { val readBits = PropertyAccessor.Getter.ReadBits(field.offset, field.size, signed) val writeBits = PropertyAccessor.Setter.WriteBits(field.offset, field.size) context.bridgeComponentsBuilder.getterToBridgeInfo[readBits] = BridgeGenerationInfo("", typeInfo) context.bridgeComponentsBuilder.setterToBridgeInfo[writeBits] = BridgeGenerationInfo("", typeInfo) PropertyStub.Kind.Var(readBits, writeBits) } GenerationMode.METADATA -> { val readBits = PropertyAccessor.Getter.ExternalGetter(listOf(AnnotationStub.CStruct.BitField(field.offset, field.size))) val writeBits = PropertyAccessor.Setter.ExternalSetter(listOf(AnnotationStub.CStruct.BitField(field.offset, field.size))) PropertyStub.Kind.Var(readBits, writeBits) } } PropertyStub(fieldName, kotlinType.toStubIrType(), kind, origin = StubOrigin.StructMember(field)) } val superClass = context.platform.getRuntimeType("CStructVar") require(superClass is ClassifierStubType) val rawPtrConstructorParam = FunctionParameterStub("rawPtr", context.platform.getRuntimeType("NativePtr")) val origin = StubOrigin.Struct(decl) val primaryConstructor = ConstructorStub( parameters = listOf(rawPtrConstructorParam), isPrimary = true, annotations = emptyList(), origin = origin ) val superClassInit = SuperClassInit(superClass, listOf(GetConstructorParameter(rawPtrConstructorParam))) val companionSuper = superClass.nested("Type") val typeSize = listOf(IntegralConstantStub(def.size, 4, true), IntegralConstantStub(def.align.toLong(), 4, true)) val companionSuperInit = SuperClassInit(companionSuper, typeSize) val companionClassifier = classifier.nested("Companion") val annotation = AnnotationStub.CStruct.VarType(def.size, def.align).takeIf { context.generationMode == GenerationMode.METADATA } val companion = ClassStub.Companion( companionClassifier, superClassInit = companionSuperInit, annotations = listOfNotNull(annotation, AnnotationStub.Deprecated.deprecatedCVariableCompanion) ) return listOf(ClassStub.Simple( classifier, origin = origin, properties = fields.filterNotNull() + if (platform == KotlinPlatform.NATIVE) bitFields else emptyList(), constructors = listOf(primaryConstructor), methods = emptyList(), modality = ClassStubModality.NONE, annotations = listOfNotNull(structAnnotation), superClassInit = superClassInit, companion = companion )) } private fun getArrayLength(type: ArrayType): Long { val unwrappedElementType = type.elemType.unwrapTypedefs() val elementLength = if (unwrappedElementType is ArrayType) { getArrayLength(unwrappedElementType) } else { 1L } val elementCount = when (type) { is ConstArrayType -> type.length is IncompleteArrayType -> 0L else -> TODO(type.toString()) } return elementLength * elementCount } private tailrec fun Type.isIntegerTypeSigned(): Boolean = when (this) { is IntegerType -> this.isSigned is BoolType -> false is EnumType -> this.def.baseType.isIntegerTypeSigned() is Typedef -> this.def.aliased.isIntegerTypeSigned() else -> error(this) } /** * Produces to [out] the definition of Kotlin class representing the reference to given forward (incomplete) struct. */ private fun generateForwardStruct(s: StructDecl): List = when (context.platform) { KotlinPlatform.JVM -> { val classifier = context.getKotlinClassForPointed(s) val superClass = context.platform.getRuntimeType("COpaque") val rawPtrConstructorParam = FunctionParameterStub("rawPtr", context.platform.getRuntimeType("NativePtr")) val superClassInit = SuperClassInit(superClass, listOf(GetConstructorParameter(rawPtrConstructorParam))) val origin = StubOrigin.Struct(s) val primaryConstructor = ConstructorStub(listOf(rawPtrConstructorParam), emptyList(), isPrimary = true, origin = origin) listOf(ClassStub.Simple( classifier, ClassStubModality.NONE, constructors = listOf(primaryConstructor), superClassInit = superClassInit, origin = origin)) } KotlinPlatform.NATIVE -> emptyList() } } internal class EnumStubBuilder( override val context: StubsBuildingContext, private val enumDef: EnumDef ) : StubElementBuilder { private val classifier = (context.mirror(EnumType(enumDef)) as TypeMirror.ByValue).valueType.classifier private val baseTypeMirror = context.mirror(enumDef.baseType) private val baseType = baseTypeMirror.argType.toStubIrType() override fun build(): List { if (!context.isStrictEnum(enumDef)) { return generateEnumAsConstants(enumDef) } val constructorParameter = FunctionParameterStub("value", baseType) val valueProperty = PropertyStub( name = "value", type = baseType, kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.GetConstructorParameter(constructorParameter)), modality = MemberStubModality.OPEN, origin = StubOrigin.Synthetic.EnumValueField(enumDef), isOverride = true) val canonicalsByValue = enumDef.constants .groupingBy { it.value } .reduce { _, accumulator, element -> if (element.isMoreCanonicalThan(accumulator)) { element } else { accumulator } } val (canonicalConstants, aliasConstants) = enumDef.constants.partition { canonicalsByValue[it.value] == it } val canonicalEntriesWithAliases = canonicalConstants .sortedBy { it.value } // TODO: Is it stable enough? .mapIndexed { index, constant -> val literal = context.tryCreateIntegralStub(enumDef.baseType, constant.value) ?: error("Cannot create enum value ${constant.value} of type ${enumDef.baseType}") val entry = EnumEntryStub(mangleSimple(constant.name), literal, StubOrigin.EnumEntry(constant), index) val aliases = aliasConstants .filter { it.value == constant.value } .map { constructAliasProperty(it, entry) } entry to aliases } val origin = StubOrigin.Enum(enumDef) val primaryConstructor = ConstructorStub( parameters = listOf(constructorParameter), annotations = emptyList(), isPrimary = true, origin = origin, visibility = VisibilityModifier.PRIVATE ) val byValueFunction = FunctionStub( name = "byValue", returnType = ClassifierStubType(classifier), parameters = listOf(FunctionParameterStub("value", baseType)), origin = StubOrigin.Synthetic.EnumByValue(enumDef), receiver = null, modality = MemberStubModality.FINAL, annotations = listOf(AnnotationStub.Deprecated.deprecatedCEnumByValue) ) val companion = ClassStub.Companion( classifier = classifier.nested("Companion"), properties = canonicalEntriesWithAliases.flatMap { it.second }, methods = listOf(byValueFunction) ) val enumVarClass = constructEnumVarClass().takeIf { context.generationMode == GenerationMode.METADATA } val kotlinEnumType = ClassifierStubType(Classifier.topLevel("kotlin", "Enum"), listOf(TypeArgumentStub(ClassifierStubType(classifier)))) val enum = ClassStub.Enum( classifier = classifier, superClassInit = SuperClassInit(kotlinEnumType), entries = canonicalEntriesWithAliases.map { it.first }, companion = companion, constructors = listOf(primaryConstructor), properties = listOf(valueProperty), origin = origin, interfaces = listOf(context.platform.getRuntimeType("CEnum")), childrenClasses = listOfNotNull(enumVarClass) ) context.bridgeComponentsBuilder.enumToTypeMirror[enum] = baseTypeMirror return listOf(enum) } private fun constructAliasProperty(enumConstant: EnumConstant, entry: EnumEntryStub): PropertyStub { val aliasAnnotation = AnnotationStub.CEnumEntryAlias(entry.name) .takeIf { context.generationMode == GenerationMode.METADATA } return PropertyStub( enumConstant.name, ClassifierStubType(classifier), kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.GetEnumEntry(entry)), origin = StubOrigin.EnumEntry(enumConstant), annotations = listOfNotNull(aliasAnnotation) ) } private fun constructEnumVarClass(): ClassStub.Simple { val enumVarClassifier = classifier.nested("Var") val rawPtrConstructorParam = FunctionParameterStub("rawPtr", context.platform.getRuntimeType("NativePtr")) val superClass = context.platform.getRuntimeType("CEnumVar") require(superClass is ClassifierStubType) val primaryConstructor = ConstructorStub( parameters = listOf(rawPtrConstructorParam), isPrimary = true, annotations = emptyList(), origin = StubOrigin.Synthetic.DefaultConstructor ) val superClassInit = SuperClassInit(superClass, listOf(GetConstructorParameter(rawPtrConstructorParam))) val baseIntegerTypeSize = when (val unwrappedType = enumDef.baseType.unwrapTypedefs()) { is IntegerType -> unwrappedType.size.toLong() CharType -> 1L else -> error("Incorrect base type for enum ${classifier.fqName}") } val typeSize = IntegralConstantStub(baseIntegerTypeSize, 4, true) val companionSuper = (context.platform.getRuntimeType("CPrimitiveVar") as ClassifierStubType).nested("Type") val varSizeAnnotation = AnnotationStub.CEnumVarTypeSize(baseIntegerTypeSize.toInt()) .takeIf { context.generationMode == GenerationMode.METADATA } val companion = ClassStub.Companion( classifier = enumVarClassifier.nested("Companion"), superClassInit = SuperClassInit(companionSuper, listOf(typeSize)), annotations = listOfNotNull(varSizeAnnotation, AnnotationStub.Deprecated.deprecatedCVariableCompanion) ) val valueProperty = PropertyStub( name = "value", type = ClassifierStubType(classifier), kind = PropertyStub.Kind.Var( PropertyAccessor.Getter.ExternalGetter(), PropertyAccessor.Setter.ExternalSetter() ), origin = StubOrigin.Synthetic.EnumVarValueField(enumDef) ) return ClassStub.Simple( classifier = enumVarClassifier, constructors = listOf(primaryConstructor), superClassInit = superClassInit, companion = companion, modality = ClassStubModality.NONE, origin = StubOrigin.VarOf(StubOrigin.Enum(enumDef)), properties = listOf(valueProperty) ) } private fun EnumConstant.isMoreCanonicalThan(other: EnumConstant): Boolean = with(other.name.toLowerCase()) { contains("min") || contains("max") || contains("first") || contains("last") || contains("begin") || contains("end") } /** * Produces to [out] the Kotlin definitions for given enum which shouldn't be represented as Kotlin enum. */ private fun generateEnumAsConstants(enumDef: EnumDef): List { // TODO: if this enum defines e.g. a type of struct field, then it should be generated inside the struct class // to prevent name clashing val entries = mutableListOf() val typealiases = mutableListOf() val constants = enumDef.constants.filter { // Macro "overrides" the original enum constant. it.name !in context.macroConstantsByName } val kotlinType: KotlinType val baseKotlinType = context.mirror(enumDef.baseType).argType val meta = if (enumDef.isAnonymous) { kotlinType = baseKotlinType StubContainerMeta(textAtStart = if (constants.isNotEmpty()) "// ${enumDef.spelling}:" else "") } else { val typeMirror = context.mirror(EnumType(enumDef)) if (typeMirror !is TypeMirror.ByValue) { error("unexpected enum type mirror: $typeMirror") } val varTypeName = typeMirror.info.constructPointedType(typeMirror.valueType) val varTypeClassifier = typeMirror.pointedType.classifier val valueTypeClassifier = typeMirror.valueType.classifier val origin = StubOrigin.Enum(enumDef) typealiases += TypealiasStub(varTypeClassifier, varTypeName.toStubIrType(), StubOrigin.VarOf(origin)) typealiases += TypealiasStub(valueTypeClassifier, baseKotlinType.toStubIrType(), origin) kotlinType = typeMirror.valueType StubContainerMeta() } for (constant in constants) { val literal = context.tryCreateIntegralStub(enumDef.baseType, constant.value) ?: continue val kind = when (context.generationMode) { GenerationMode.SOURCE_CODE -> { val getter = PropertyAccessor.Getter.SimpleGetter(constant = literal) PropertyStub.Kind.Val(getter) } GenerationMode.METADATA -> { PropertyStub.Kind.Constant(literal) } } entries += PropertyStub( constant.name, kotlinType.toStubIrType(), kind, MemberStubModality.FINAL, null, origin = StubOrigin.EnumEntry(constant) ) } val container = SimpleStubContainer( meta, properties = entries.toList(), typealiases = typealiases.toList() ) return listOf(container) } } internal class FunctionStubBuilder( override val context: StubsBuildingContext, private val func: FunctionDecl, private val skipOverloads: Boolean = false ) : StubElementBuilder { override fun build(): List { val platform = context.platform val parameters = mutableListOf() var hasStableParameterNames = true func.parameters.forEachIndexed { index, parameter -> val parameterName = parameter.name.let { if (it == null || it.isEmpty()) { hasStableParameterNames = false "arg$index" } else { it } } val representAsValuesRef = representCFunctionParameterAsValuesRef(parameter.type) parameters += when { representCFunctionParameterAsString(func, parameter.type) -> { val annotations = when (platform) { KotlinPlatform.JVM -> emptyList() KotlinPlatform.NATIVE -> listOf(AnnotationStub.CCall.CString) } val type = KotlinTypes.string.makeNullable().toStubIrType() val functionParameterStub = FunctionParameterStub(parameterName, type, annotations) context.bridgeComponentsBuilder.cStringParameters += functionParameterStub functionParameterStub } representCFunctionParameterAsWString(func, parameter.type) -> { val annotations = when (platform) { KotlinPlatform.JVM -> emptyList() KotlinPlatform.NATIVE -> listOf(AnnotationStub.CCall.WCString) } val type = KotlinTypes.string.makeNullable().toStubIrType() val functionParameterStub = FunctionParameterStub(parameterName, type, annotations) context.bridgeComponentsBuilder.wCStringParameters += functionParameterStub functionParameterStub } representAsValuesRef != null -> { FunctionParameterStub(parameterName, representAsValuesRef.toStubIrType()) } else -> { val mirror = context.mirror(parameter.type) val type = mirror.argType.toStubIrType() FunctionParameterStub(parameterName, type) } } } val returnType = if (func.returnsVoid()) { KotlinTypes.unit } else { context.mirror(func.returnType).argType }.toStubIrType() if (skipOverloads && context.isOverloading(func)) return emptyList() val annotations: List val mustBeExternal: Boolean if (platform == KotlinPlatform.JVM) { annotations = emptyList() mustBeExternal = false } else { if (func.isVararg) { val type = KotlinTypes.any.makeNullable().toStubIrType() parameters += FunctionParameterStub("variadicArguments", type, isVararg = true) } annotations = listOf(AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${func.name}")) mustBeExternal = true } val functionStub = FunctionStub( func.name, returnType, parameters.toList(), StubOrigin.Function(func), annotations, mustBeExternal, null, MemberStubModality.FINAL, hasStableParameterNames = hasStableParameterNames ) return listOf(functionStub) } private fun FunctionDecl.returnsVoid(): Boolean = this.returnType.unwrapTypedefs() is VoidType private fun representCFunctionParameterAsValuesRef(type: Type): KotlinType? { val pointeeType = when (type) { is PointerType -> type.pointeeType is ArrayType -> type.elemType else -> return null } val unwrappedPointeeType = pointeeType.unwrapTypedefs() if (unwrappedPointeeType is VoidType) { // Represent `void*` as `CValuesRef<*>?`: return KotlinTypes.cValuesRef.typeWith(StarProjection).makeNullable() } if (unwrappedPointeeType is FunctionType) { // Don't represent function pointer as `CValuesRef?` currently: return null } if (unwrappedPointeeType is ArrayType) { return representCFunctionParameterAsValuesRef(pointeeType) } return KotlinTypes.cValuesRef.typeWith(context.mirror(pointeeType).pointedType).makeNullable() } private val platformWStringTypes = setOf("LPCWSTR") private val noStringConversion: Set get() = context.configuration.noStringConversion private fun Type.isAliasOf(names: Set): Boolean { var type = this while (type is Typedef) { if (names.contains(type.def.name)) return true type = type.def.aliased } return false } private fun representCFunctionParameterAsString(function: FunctionDecl, type: Type): Boolean { val unwrappedType = type.unwrapTypedefs() return unwrappedType is PointerType && unwrappedType.pointeeIsConst && unwrappedType.pointeeType.unwrapTypedefs() == CharType && !noStringConversion.contains(function.name) } // We take this approach as generic 'const short*' shall not be used as String. private fun representCFunctionParameterAsWString(function: FunctionDecl, type: Type) = type.isAliasOf(platformWStringTypes) && !noStringConversion.contains(function.name) } internal class GlobalStubBuilder( override val context: StubsBuildingContext, private val global: GlobalDecl ) : StubElementBuilder { override fun build(): List { val mirror = context.mirror(global.type) val unwrappedType = global.type.unwrapTypedefs() val origin = StubOrigin.Global(global) val kotlinType: KotlinType val kind: PropertyStub.Kind if (unwrappedType is ArrayType) { kotlinType = (mirror as TypeMirror.ByValue).valueType val getter = when (context.platform) { KotlinPlatform.JVM -> { PropertyAccessor.Getter.SimpleGetter().also { val extra = BridgeGenerationInfo(global.name, mirror.info) context.bridgeComponentsBuilder.arrayGetterBridgeInfo[it] = extra } } KotlinPlatform.NATIVE -> { val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_getter") PropertyAccessor.Getter.ExternalGetter(listOf(cCallAnnotation)).also { context.wrapperComponentsBuilder.getterToWrapperInfo[it] = WrapperGenerationInfo(global) } } } kind = PropertyStub.Kind.Val(getter) } else { when (mirror) { is TypeMirror.ByValue -> { kotlinType = mirror.argType val getter = when (context.platform) { KotlinPlatform.JVM -> { PropertyAccessor.Getter.SimpleGetter().also { val getterExtra = BridgeGenerationInfo(global.name, mirror.info) context.bridgeComponentsBuilder.getterToBridgeInfo[it] = getterExtra } } KotlinPlatform.NATIVE -> { val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_getter") PropertyAccessor.Getter.ExternalGetter(listOf(cCallAnnotation)).also { context.wrapperComponentsBuilder.getterToWrapperInfo[it] = WrapperGenerationInfo(global) } } } kind = if (global.isConst) { PropertyStub.Kind.Val(getter) } else { val setter = when (context.platform) { KotlinPlatform.JVM -> { PropertyAccessor.Setter.SimpleSetter().also { val setterExtra = BridgeGenerationInfo(global.name, mirror.info) context.bridgeComponentsBuilder.setterToBridgeInfo[it] = setterExtra } } KotlinPlatform.NATIVE -> { val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_setter") PropertyAccessor.Setter.ExternalSetter(listOf(cCallAnnotation)).also { context.wrapperComponentsBuilder.setterToWrapperInfo[it] = WrapperGenerationInfo(global) } } } PropertyStub.Kind.Var(getter, setter) } } is TypeMirror.ByRef -> { kotlinType = mirror.pointedType val getter = when (context.generationMode) { GenerationMode.SOURCE_CODE -> { PropertyAccessor.Getter.InterpretPointed(global.name, kotlinType.toStubIrType()) } GenerationMode.METADATA -> { val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_getter") PropertyAccessor.Getter.ExternalGetter(listOf(cCallAnnotation)).also { context.wrapperComponentsBuilder.getterToWrapperInfo[it] = WrapperGenerationInfo(global, passViaPointer = true) } } } kind = PropertyStub.Kind.Val(getter) } } } return listOf(PropertyStub(global.name, kotlinType.toStubIrType(), kind, origin = origin)) } } internal class TypedefStubBuilder( override val context: StubsBuildingContext, private val typedefDef: TypedefDef ) : StubElementBuilder { override fun build(): List { val mirror = context.mirror(Typedef(typedefDef)) val baseMirror = context.mirror(typedefDef.aliased) val varType = mirror.pointedType.classifier val origin = StubOrigin.TypeDef(typedefDef) return when (baseMirror) { is TypeMirror.ByValue -> { val valueType = (mirror as TypeMirror.ByValue).valueType val varTypeAliasee = mirror.info.constructPointedType(valueType) val valueTypeAliasee = baseMirror.valueType listOf( TypealiasStub(varType, varTypeAliasee.toStubIrType(), StubOrigin.VarOf(origin)), TypealiasStub(valueType.classifier, valueTypeAliasee.toStubIrType(), origin) ) } is TypeMirror.ByRef -> { val varTypeAliasee = baseMirror.pointedType listOf(TypealiasStub(varType, varTypeAliasee.toStubIrType(), origin)) } } } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrExtensions.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.ObjCProtocol private val StubOrigin.ObjCMethod.isOptional: Boolean get() = container is ObjCProtocol && method.isOptional fun FunctionStub.isOptionalObjCMethod(): Boolean = this.origin is StubOrigin.ObjCMethod && this.origin.isOptional val StubContainer.isInterface: Boolean get() = if (this is ClassStub.Simple) { modality == ClassStubModality.INTERFACE } else { false } /** * Compute which names will be declared by [StubContainer] in the given [pkgName] */ fun StubContainer.computeNamesToBeDeclared(pkgName: String): List { fun checkPackageCorrectness(classifier: Classifier) { assert(classifier.pkg == pkgName) { """Wrong classifier package. |Expected: $pkgName |Got: ${classifier.pkg} |""".trimMargin() } } val classNames = classes.mapNotNull { when (it) { is ClassStub.Simple -> it.classifier is ClassStub.Companion -> null is ClassStub.Enum -> it.classifier } }.onEach { checkPackageCorrectness(it) }.map { it.topLevelName } val typealiasNames = typealiases .onEach { checkPackageCorrectness(it.alias) } .map { it.alias.topLevelName } val namesFromNestedContainers = simpleContainers .flatMap { it.computeNamesToBeDeclared(pkgName) } return classNames + typealiasNames + namesFromNestedContainers } val StubContainer.defaultMemberModality: MemberStubModality get() = when (this) { is SimpleStubContainer -> MemberStubModality.FINAL is ClassStub.Simple -> if (this.modality == ClassStubModality.INTERFACE) { MemberStubModality.ABSTRACT } else { MemberStubModality.FINAL } is ClassStub.Companion -> MemberStubModality.FINAL is ClassStub.Enum -> MemberStubModality.FINAL } /** * Returns constructor that should be rendered in class header. */ val ClassStub.explicitPrimaryConstructor: ConstructorStub? get() = functions.filterIsInstance().firstOrNull(ConstructorStub::isPrimary) fun ClassStub.nestedName(): String = classifier.getRelativeFqName().substringAfterLast('.') fun ConstantStub.determineConstantAnnotationClassifier(): Classifier = when (this) { is StringConstantStub -> "String" is IntegralConstantStub -> when (size) { 1 -> if (isSigned) "Byte" else "UByte" 2 -> if (isSigned) "Short" else "UShort" 4 -> if (isSigned) "Int" else "UInt" 8 -> if (isSigned) "Long" else "ULong" else -> error("Integral constant with unexpected size of $size.") } is DoubleConstantStub -> when (size) { 4 -> "Float" 8 -> "Double" else -> error("Real constant with unexpected size of $size.") } }.let { Classifier.topLevel(cinteropInternalPackage, "ConstantValue").nested(it) } /** * Returns the original name of the given type. */ val StubType.underlyingTypeFqName: String get() = when (this) { is ClassifierStubType -> classifier.fqName is AbbreviatedType -> underlyingType.underlyingTypeFqName is FunctionalType -> classifier.fqName is TypeParameterType -> name } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import kotlinx.metadata.* import kotlinx.metadata.klib.* import org.jetbrains.kotlin.metadata.serialization.Interner import org.jetbrains.kotlin.utils.addIfNotNull class StubIrMetadataEmitter( private val context: StubIrContext, private val builderResult: StubIrBuilderResult, private val moduleName: String, private val bridgeBuilderResult: BridgeBuilderResult ) { fun emit(): KlibModuleMetadata { val annotations = emptyList() val fragments = emitModuleFragments() return KlibModuleMetadata(moduleName, fragments, annotations) } private fun emitModuleFragments(): List = ModuleMetadataEmitter( context.configuration.pkgName, builderResult.stubs, bridgeBuilderResult ).emit().let { kmModuleFragment -> // We need to create module fragment for each part of package name. val pkgName = context.configuration.pkgName val fakePackages = pkgName.mapIndexedNotNull { idx, char -> if (char == '.') idx else null }.map { dotPosition -> KmModuleFragment().also { it.fqName = pkgName.substring(0, dotPosition) } } fakePackages + kmModuleFragment } } /** * Translates single [StubContainer] to [KmModuleFragment]. */ internal class ModuleMetadataEmitter( private val packageFqName: String, private val module: SimpleStubContainer, private val bridgeBuilderResult: BridgeBuilderResult ) { fun emit(): KmModuleFragment { val context = VisitingContext(bridgeBuilderResult = bridgeBuilderResult) val elements = KmElements(visitor.visitSimpleStubContainer(module, context)) return writeModule(elements) } private fun writeModule(elements: KmElements) = KmModuleFragment().also { km -> km.fqName = packageFqName km.classes += elements.classes.toList() km.className += elements.classes.map(KmClass::name) km.pkg = writePackage(elements) } private fun writePackage(elements: KmElements) = KmPackage().also { km -> km.fqName = packageFqName km.typeAliases += elements.typeAliases.toList() km.properties += elements.properties.toList() km.functions += elements.functions.toList() } /** * StubIr translation result. Since Km* classes don't have common hierarchy we need * to use list of Any. */ private class KmElements(result: List) { val classes: List = result.filterIsInstance>().flatten() val properties: List = result.filterIsInstance() val typeAliases: List = result.filterIsInstance() val functions: List = result.filterIsInstance() val constructors: List = result.filterIsInstance() } /** * Used to pass data between parents and children when visiting StubIr elements. */ private data class VisitingContext( val container: StubContainer? = null, val typeParametersInterner: Interner = Interner(), val bridgeBuilderResult: BridgeBuilderResult ) { inline fun withMappingExtensions(block: MappingExtensions.() -> R) = with (MappingExtensions(typeParametersInterner, bridgeBuilderResult), block) } private fun isTopLevelContainer(container: StubContainer?): Boolean = container == null private fun getPropertyNameInScope(property: PropertyStub, container: StubContainer?): String = if (isTopLevelContainer(container)) { getTopLevelPropertyDeclarationName(bridgeBuilderResult.kotlinFile, property) } else { property.name } private val visitor = object : StubIrVisitor { override fun visitClass(element: ClassStub, data: VisitingContext): List { val classVisitingContext = VisitingContext( container = element, typeParametersInterner = Interner(data.typeParametersInterner), bridgeBuilderResult = data.bridgeBuilderResult ) val children = element.children + if (element is ClassStub.Companion) { listOf(ConstructorStub(isPrimary = true, visibility = VisibilityModifier.PRIVATE, origin = StubOrigin.Synthetic.DefaultConstructor)) } else emptyList() val elements = KmElements(children.mapNotNull { it.accept(this, classVisitingContext) }) val kmClass = data.withMappingExtensions { KmClass().also { km -> element.annotations.mapTo(km.annotations) { it.map() } km.flags = element.flags km.name = element.classifier.fqNameSerialized element.superClassInit?.let { km.supertypes += it.type.map() } element.interfaces.mapTo(km.supertypes) { it.map() } element.classes.mapTo(km.nestedClasses) { it.nestedName() } km.typeAliases += elements.typeAliases.toList() km.properties += elements.properties.toList() km.functions += elements.functions.toList() km.constructors += elements.constructors.toList() km.companionObject = element.companion?.nestedName() if (element is ClassStub.Enum) { element.entries.mapTo(km.klibEnumEntries) { mapEnumEntry(it, classVisitingContext) } } } } // Metadata stores classes as flat list. return listOf(kmClass) + elements.classes } override fun visitTypealias(element: TypealiasStub, data: VisitingContext): KmTypeAlias = data.withMappingExtensions { KmTypeAlias(element.flags, element.alias.topLevelName).also { km -> km.underlyingType = element.aliasee.map(shouldExpandTypeAliases = false) km.expandedType = element.aliasee.map() } } override fun visitFunction(element: FunctionStub, data: VisitingContext) = data.withMappingExtensions { val function = if (bridgeBuilderResult.nativeBridges.isSupported(element)) { element } else { element.copy( external = false, annotations = listOf(AnnotationStub.Deprecated.unableToImport) ) } KmFunction(function.flags, function.name).also { km -> km.receiverParameterType = function.receiver?.type?.map() function.typeParameters.mapTo(km.typeParameters) { it.map() } function.parameters.mapTo(km.valueParameters) { it.map() } function.annotations.mapTo(km.annotations) { it.map() } km.returnType = function.returnType.map() } } override fun visitProperty(element: PropertyStub, data: VisitingContext) = data.withMappingExtensions { val property = when (val bridgeSupportedKind = element.bridgeSupportedKind) { null -> element.copy( kind = PropertyStub.Kind.Val(PropertyAccessor.Getter.SimpleGetter()), annotations = listOf(AnnotationStub.Deprecated.unableToImport) ) element.kind -> element else -> element.copy(kind = bridgeSupportedKind) } val name = getPropertyNameInScope(property, data.container) KmProperty(property.flags, name, property.getterFlags, property.setterFlags).also { km -> property.annotations.mapTo(km.annotations) { it.map() } km.receiverParameterType = property.receiverType?.map() km.returnType = property.type.map() val kind = property.kind if (kind is PropertyStub.Kind.Var) { kind.setter.annotations.mapTo(km.setterAnnotations) { it.map() } // TODO: Maybe it's better to explicitly add setter parameter in stub. km.setterParameter = FunctionParameterStub("value", property.type).map() } km.getterAnnotations += when (kind) { is PropertyStub.Kind.Val -> kind.getter.annotations.map { it.map() } is PropertyStub.Kind.Var -> kind.getter.annotations.map { it.map() } is PropertyStub.Kind.Constant -> emptyList() } if (kind is PropertyStub.Kind.Constant) { km.compileTimeValue = kind.constant.mapToAnnotationArgument() } } } override fun visitConstructor(constructorStub: ConstructorStub, data: VisitingContext) = data.withMappingExtensions { KmConstructor(constructorStub.flags).apply { constructorStub.parameters.mapTo(valueParameters, { it.map() }) constructorStub.annotations.mapTo(annotations, { it.map() }) } } override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: VisitingContext) { // TODO("not implemented") } override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: VisitingContext): List = simpleStubContainer.children.mapNotNull { it.accept(this, data) } + simpleStubContainer.simpleContainers.flatMap { visitSimpleStubContainer(it, data) } private fun mapEnumEntry(enumEntry: EnumEntryStub, data: VisitingContext): KlibEnumEntry = data.withMappingExtensions { KlibEnumEntry( name = enumEntry.name, ordinal = enumEntry.ordinal, annotations = mutableListOf(enumEntry.constant.mapToConstantAnnotation()) ) } } } /** * Collection of extension functions that simplify translation of * StubIr elements to Kotlin Metadata. */ private class MappingExtensions( private val typeParametersInterner: Interner, private val bridgeBuilderResult: BridgeBuilderResult ) { private fun flagsOfNotNull(vararg flags: Flag?): Flags = flagsOf(*listOfNotNull(*flags).toTypedArray()) private fun mapOfNotNull(vararg entries: Pair?): Map = listOfNotNull(*entries).toMap() private val VisibilityModifier.flags: Flags get() = flagsOfNotNull( Flag.IS_PUBLIC.takeIf { this == VisibilityModifier.PUBLIC }, Flag.IS_PROTECTED.takeIf { this == VisibilityModifier.PROTECTED }, Flag.IS_INTERNAL.takeIf { this == VisibilityModifier.INTERNAL }, Flag.IS_PRIVATE.takeIf { this == VisibilityModifier.PRIVATE } ) private val MemberStubModality.flags: Flags get() = flagsOfNotNull( Flag.IS_FINAL.takeIf { this == MemberStubModality.FINAL }, Flag.IS_OPEN.takeIf { this == MemberStubModality.OPEN }, Flag.IS_ABSTRACT.takeIf { this == MemberStubModality.ABSTRACT } ) val FunctionStub.flags: Flags get() = flagsOfNotNull( Flag.IS_PUBLIC, Flag.Function.IS_EXTERNAL.takeIf { this.external }, Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }, Flag.Function.HAS_NON_STABLE_PARAMETER_NAMES.takeIf { !this.hasStableParameterNames } ) or modality.flags val Classifier.fqNameSerialized: String get() = buildString { if (pkg.isNotEmpty()) { append(pkg.replace('.', '/')) append('/') } // Nested classes should dot-separated. append(getRelativeFqName(asSimpleName = false)) } val PropertyStub.flags: Flags get() = flagsOfNotNull( Flag.IS_PUBLIC, Flag.Property.IS_DECLARATION, Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }, Flag.Property.HAS_CONSTANT.takeIf { kind is PropertyStub.Kind.Constant }, Flag.Property.HAS_GETTER, Flag.Property.HAS_SETTER.takeIf { kind is PropertyStub.Kind.Var }, when (kind) { is PropertyStub.Kind.Val -> null is PropertyStub.Kind.Var -> Flag.Property.IS_VAR is PropertyStub.Kind.Constant -> Flag.Property.IS_CONST } ) or modality.flags val PropertyStub.getterFlags: Flags get() = when (val kind = kind) { is PropertyStub.Kind.Val -> kind.getter.flags(modality) is PropertyStub.Kind.Var -> kind.getter.flags(modality) is PropertyStub.Kind.Constant -> kind.flags } val PropertyStub.Kind.Constant.flags: Flags get() = flagsOfNotNull( Flag.IS_PUBLIC, Flag.IS_FINAL ) private fun PropertyAccessor.Getter.flags(propertyModality: MemberStubModality): Flags = flagsOfNotNull( Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }, Flag.IS_PUBLIC, Flag.PropertyAccessor.IS_NOT_DEFAULT, Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Getter.ExternalGetter } ) or propertyModality.flags val PropertyStub.setterFlags: Flags get() = when (val kind = kind) { is PropertyStub.Kind.Var -> kind.setter.flags(modality) else -> flagsOf() } private fun PropertyAccessor.Setter.flags(propertyModality: MemberStubModality): Flags = flagsOfNotNull( Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }, Flag.IS_PUBLIC, Flag.PropertyAccessor.IS_NOT_DEFAULT, Flag.PropertyAccessor.IS_EXTERNAL.takeIf { this is PropertyAccessor.Setter.ExternalSetter } ) or propertyModality.flags val StubType.flags: Flags get() = flagsOfNotNull( Flag.Type.IS_NULLABLE.takeIf { nullable } ) val AbbreviatedType.expandedTypeFlags: Flags get() = flagsOfNotNull( Flag.Type.IS_NULLABLE.takeIf { isEffectivelyNullable() } ) val TypealiasStub.flags: Flags get() = flagsOfNotNull( Flag.IS_PUBLIC ) val FunctionParameterStub.flags: Flags get() = flagsOfNotNull( Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() } ) val ClassStub.flags: Flags get() = flagsOfNotNull( Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() }, Flag.IS_PUBLIC, Flag.IS_OPEN.takeIf { this is ClassStub.Simple && modality == ClassStubModality.OPEN }, Flag.IS_FINAL.takeIf { this is ClassStub.Simple && modality == ClassStubModality.NONE }, Flag.IS_ABSTRACT.takeIf { this is ClassStub.Simple && (modality == ClassStubModality.ABSTRACT || modality == ClassStubModality.INTERFACE) }, Flag.Class.IS_INTERFACE.takeIf { this is ClassStub.Simple && modality == ClassStubModality.INTERFACE }, Flag.Class.IS_COMPANION_OBJECT.takeIf { this is ClassStub.Companion }, Flag.Class.IS_CLASS.takeIf { this is ClassStub.Simple && modality != ClassStubModality.INTERFACE }, Flag.Class.IS_ENUM_CLASS.takeIf { this is ClassStub.Enum } ) val ConstructorStub.flags: Flags get() = flagsOfNotNull( Flag.Constructor.IS_SECONDARY.takeIf { !isPrimary }, Flag.HAS_ANNOTATIONS.takeIf { annotations.isNotEmpty() } ) or visibility.flags private tailrec fun StubType.isEffectivelyNullable(): Boolean = when { nullable -> true this !is AbbreviatedType -> false else -> underlyingType.isEffectivelyNullable() } fun AnnotationStub.map(): KmAnnotation { fun Pair.asAnnotationArgument() = (first to KmAnnotationArgument.StringValue(second)).takeIf { second.isNotEmpty() } fun replaceWith(replaceWith: String) = KmAnnotationArgument.AnnotationValue(KmAnnotation( Classifier.topLevel("kotlin", "ReplaceWith").fqNameSerialized, mapOfNotNull( "imports" to KmAnnotationArgument.ArrayValue(emptyList()), ("expression" to replaceWith).asAnnotationArgument() ) )) fun deprecationLevel(level: DeprecationLevel) = KmAnnotationArgument.EnumValue( Classifier.topLevel("kotlin", "DeprecationLevel").fqNameSerialized, level.name ) val args = when (this) { AnnotationStub.ObjC.ConsumesReceiver -> emptyMap() AnnotationStub.ObjC.ReturnsRetained -> emptyMap() is AnnotationStub.ObjC.Method -> mapOfNotNull( ("selector" to selector).asAnnotationArgument(), ("encoding" to encoding).asAnnotationArgument(), ("isStret" to KmAnnotationArgument.BooleanValue(isStret)) ) is AnnotationStub.ObjC.Factory -> mapOfNotNull( ("selector" to selector).asAnnotationArgument(), ("encoding" to encoding).asAnnotationArgument(), ("isStret" to KmAnnotationArgument.BooleanValue(isStret)) ) AnnotationStub.ObjC.Consumed -> emptyMap() is AnnotationStub.ObjC.Constructor -> mapOfNotNull( ("designated" to KmAnnotationArgument.BooleanValue(designated)), ("initSelector" to selector).asAnnotationArgument() ) is AnnotationStub.ObjC.ExternalClass -> mapOfNotNull( ("protocolGetter" to protocolGetter).asAnnotationArgument(), ("binaryName" to binaryName).asAnnotationArgument() ) AnnotationStub.CCall.CString -> emptyMap() AnnotationStub.CCall.WCString -> emptyMap() is AnnotationStub.CCall.Symbol -> mapOfNotNull( ("id" to symbolName).asAnnotationArgument() ) is AnnotationStub.CStruct -> mapOfNotNull( ("spelling" to struct).asAnnotationArgument() ) is AnnotationStub.CNaturalStruct -> error("@CNaturalStruct should not be used for Kotlin/Native interop") is AnnotationStub.CLength -> mapOfNotNull( "value" to KmAnnotationArgument.LongValue(length) ) is AnnotationStub.Deprecated -> mapOfNotNull( ("message" to message).asAnnotationArgument(), ("replaceWith" to replaceWith(replaceWith)), ("level" to deprecationLevel(level)) ) is AnnotationStub.CEnumEntryAlias -> mapOfNotNull( ("entryName" to entryName).asAnnotationArgument() ) is AnnotationStub.CEnumVarTypeSize -> mapOfNotNull( ("size" to KmAnnotationArgument.IntValue(size)) ) is AnnotationStub.CStruct.MemberAt -> mapOfNotNull( ("offset" to KmAnnotationArgument.LongValue(offset)) ) is AnnotationStub.CStruct.ArrayMemberAt -> mapOfNotNull( ("offset" to KmAnnotationArgument.LongValue(offset)) ) is AnnotationStub.CStruct.BitField -> mapOfNotNull( ("offset" to KmAnnotationArgument.LongValue(offset)), ("size" to KmAnnotationArgument.IntValue(size)) ) is AnnotationStub.CStruct.VarType -> mapOfNotNull( ("size" to KmAnnotationArgument.LongValue(size)), ("align" to KmAnnotationArgument.IntValue(align)) ) } return KmAnnotation(classifier.fqNameSerialized, args) } /** * @param shouldExpandTypeAliases describes how should we write type aliases. * If [shouldExpandTypeAliases] is true then type alias-based types are written as * ``` * Type { * abbreviatedType = AbbreviatedType.abbreviatedClassifier * classifier = AbbreviatedType.underlyingType * arguments = AbbreviatedType.underlyingType.typeArguments * } * ``` * So we basically replacing type alias with underlying class. * Otherwise: * ``` * Type { * classifier = AbbreviatedType.abbreviatedClassifier * } * ``` * As of 25 Nov 2019, the latter form is used only for KmTypeAlias.underlyingType. */ // TODO: Add caching if needed. fun StubType.map(shouldExpandTypeAliases: Boolean = true): KmType = when (this) { is AbbreviatedType -> { val typeAliasClassifier = KmClassifier.TypeAlias(abbreviatedClassifier.fqNameSerialized) val typeArguments = typeArguments.map { it.map(shouldExpandTypeAliases) } val abbreviatedType = KmType(flags).also { km -> km.classifier = typeAliasClassifier km.arguments += typeArguments } if (shouldExpandTypeAliases) { KmType(expandedTypeFlags).also { km -> km.abbreviatedType = abbreviatedType val kmUnderlyingType = underlyingType.map(true) km.arguments += kmUnderlyingType.arguments km.classifier = kmUnderlyingType.classifier } } else { abbreviatedType } } is ClassifierStubType -> KmType(flags).also { km -> typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) } km.classifier = KmClassifier.Class(classifier.fqNameSerialized) } is FunctionalType -> KmType(flags).also { km -> typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) } km.classifier = KmClassifier.Class(classifier.fqNameSerialized) } is TypeParameterType -> KmType(flags).also { km -> km.classifier = KmClassifier.TypeParameter(id) } } fun FunctionParameterStub.map(): KmValueParameter = KmValueParameter(flags, name).also { km -> val kmType = type.map() if (isVararg) { km.varargElementType = kmType km.type = ClassifierStubType( Classifier.topLevel("kotlin", "Array"), listOf(TypeArgumentStub(type)) ).map() } else { km.type = kmType } annotations.mapTo(km.annotations, { it.map() }) } fun TypeParameterStub.map(): KmTypeParameter = KmTypeParameter(flagsOf(), name, id, KmVariance.INVARIANT).also { km -> km.upperBounds.addIfNotNull(upperBound?.map()) } private fun TypeArgument.map(expanded: Boolean = true): KmTypeProjection = when (this) { TypeArgument.StarProjection -> KmTypeProjection.STAR is TypeArgumentStub -> KmTypeProjection(variance.map(), type.map(expanded)) else -> error("Unexpected TypeArgument: $this") } private fun TypeArgument.Variance.map(): KmVariance = when (this) { TypeArgument.Variance.INVARIANT -> KmVariance.INVARIANT TypeArgument.Variance.IN -> KmVariance.IN TypeArgument.Variance.OUT -> KmVariance.OUT } fun ConstantStub.mapToAnnotationArgument(): KmAnnotationArgument<*> = when (this) { is StringConstantStub -> KmAnnotationArgument.StringValue(value) is IntegralConstantStub -> when (size) { 1 -> if (isSigned) { KmAnnotationArgument.ByteValue(value.toByte()) } else { KmAnnotationArgument.UByteValue(value.toByte()) } 2 -> if (isSigned) { KmAnnotationArgument.ShortValue(value.toShort()) } else { KmAnnotationArgument.UShortValue(value.toShort()) } 4 -> if (isSigned) { KmAnnotationArgument.IntValue(value.toInt()) } else { KmAnnotationArgument.UIntValue(value.toInt()) } 8 -> if (isSigned) { KmAnnotationArgument.LongValue(value) } else { KmAnnotationArgument.ULongValue(value) } else -> error("Integral constant of value $value with unexpected size of $size.") } is DoubleConstantStub -> when (size) { 4 -> KmAnnotationArgument.FloatValue(value.toFloat()) 8 -> KmAnnotationArgument.DoubleValue(value) else -> error("Floating-point constant of value $value with unexpected size of $size.") } } fun ConstantStub.mapToConstantAnnotation(): KmAnnotation = KmAnnotation( determineConstantAnnotationClassifier().fqNameSerialized, mapOf("value" to mapToAnnotationArgument()) ) private val TypeParameterType.id: Int get() = typeParameterDeclaration.id private val TypeParameterStub.id: Int get() = typeParametersInterner.intern(this) /** * Sometimes we can't generate bridge for getter or setter. * For example, it may happen due to bug in libclang which may * erroneously skip `const` qualifier of global variable. * * In this case we should change effective property's kind to either `val` * or even omit the declaration at all. */ val PropertyStub.bridgeSupportedKind: PropertyStub.Kind? get() = when (kind) { is PropertyStub.Kind.Var -> { val isGetterSupported = bridgeBuilderResult.nativeBridges.isSupported(kind.getter) val isSetterSupported = bridgeBuilderResult.nativeBridges.isSupported(kind.setter) when { isGetterSupported && isSetterSupported -> kind !isGetterSupported -> null else -> PropertyStub.Kind.Val(kind.getter) } } is PropertyStub.Kind.Val -> { val isGetterSupported = bridgeBuilderResult.nativeBridges.isSupported(kind.getter) if (isGetterSupported) { kind } else { null } } is PropertyStub.Kind.Constant -> kind } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrTextEmitter.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.indexer.* import org.jetbrains.kotlin.utils.addIfNotNull import java.lang.IllegalStateException /** * Emits stubs and bridge functions as *.kt and *.c files. * Many unintuitive printings are made for compatability with previous version of stub generator. * * [omitEmptyLines] is useful for testing output (e.g. diff calculating). */ class StubIrTextEmitter( private val context: StubIrContext, private val builderResult: StubIrBuilderResult, private val bridgeBuilderResult: BridgeBuilderResult, private val omitEmptyLines: Boolean = false ) { private val kotlinFile = bridgeBuilderResult.kotlinFile private val nativeBridges = bridgeBuilderResult.nativeBridges private val propertyAccessorBridgeBodies = bridgeBuilderResult.propertyAccessorBridgeBodies private val functionBridgeBodies = bridgeBuilderResult.functionBridgeBodies private val pkgName: String get() = context.configuration.pkgName private val StubContainer.isTopLevelContainer: Boolean get() = this == builderResult.stubs || this in builderResult.stubs.simpleContainers /** * The output currently used by the generator. * Should append line separator after any usage. */ private var out: (String) -> Unit = { throw IllegalStateException() } private fun emitEmptyLine() { if (!omitEmptyLines) { out("") } } private fun withOutput(output: (String) -> Unit, action: () -> R): R { val oldOut = out out = output try { return action() } finally { out = oldOut } } private fun withOutput(appendable: Appendable, action: () -> R): R { return withOutput({ appendable.appendLine(it) }, action) } private fun generateLinesBy(action: () -> Unit): List { val result = mutableListOf() withOutput({ result.add(it) }, action) return result } private fun generateKotlinFragmentBy(block: () -> Unit): Sequence { val lines = generateLinesBy(block) return lines.asSequence() } private fun indent(action: () -> R): R { val oldOut = out return withOutput({ oldOut(" $it") }, action) } private fun block(header: String, body: () -> R): R { out("$header {") val res = indent { body() } out("}") return res } private fun emitKotlinFileHeader() { if (context.platform == KotlinPlatform.JVM) { out("@file:JvmName(${context.jvmFileClassName.quoteAsKotlinLiteral()})") } if (context.platform == KotlinPlatform.NATIVE) { out("@file:kotlinx.cinterop.InteropStubs") } val suppress = mutableListOf("UNUSED_VARIABLE", "UNUSED_EXPRESSION").apply { add("DEPRECATION") // CVariable.Type and CEnum companion deprecations. if (context.configuration.library.language == Language.OBJECTIVE_C) { add("CONFLICTING_OVERLOADS") add("RETURN_TYPE_MISMATCH_ON_INHERITANCE") add("PROPERTY_TYPE_MISMATCH_ON_INHERITANCE") // Multiple-inheriting property with conflicting types add("VAR_TYPE_MISMATCH_ON_INHERITANCE") // Multiple-inheriting mutable property with conflicting types add("RETURN_TYPE_MISMATCH_ON_OVERRIDE") add("WRONG_MODIFIER_CONTAINING_DECLARATION") // For `final val` in interface. add("PARAMETER_NAME_CHANGED_ON_OVERRIDE") add("UNUSED_PARAMETER") // For constructors. add("MANY_IMPL_MEMBER_NOT_IMPLEMENTED") // Workaround for multiple-inherited properties. add("MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED") // Workaround for multiple-inherited properties. add("EXTENSION_SHADOWED_BY_MEMBER") // For Objective-C categories represented as extensions. add("REDUNDANT_NULLABLE") // This warning appears due to Obj-C typedef nullability incomplete support. add("DEPRECATION") // For uncheckedCast. add("DEPRECATION_ERROR") // For initializers. } } out("@file:Suppress(${suppress.joinToString { it.quoteAsKotlinLiteral() }})") if (pkgName != "") { out("package ${context.validPackageName}") out("") } if (context.platform == KotlinPlatform.NATIVE) { out("import kotlin.native.SymbolName") out("import kotlinx.cinterop.internal.*") } out("import kotlinx.cinterop.*") kotlinFile.buildImports().forEach { out(it) } out("") out("// NOTE THIS FILE IS AUTO-GENERATED") } fun emit(ktFile: Appendable) { // Stubs generation may affect imports list so do it before header generation. val stubLines = generateKotlinFragmentBy { printer.visitSimpleStubContainer(builderResult.stubs, null) } withOutput(ktFile) { emitKotlinFileHeader() stubLines.forEach(out) nativeBridges.kotlinLines.forEach(out) if (context.platform == KotlinPlatform.JVM) out("private val loadLibrary = loadKonanLibrary(\"${context.libName}\")") } } private val printer = object : StubIrVisitor { override fun visitClass(element: ClassStub, data: StubContainer?) { element.annotations.forEach { out(renderAnnotation(it)) } val header = renderClassHeader(element) when { element.children.isEmpty() -> out(header) else -> block(header) { if (element is ClassStub.Enum) { emitEnumEntries(element) } element.children // We render a primary constructor as part of a header. .filterNot { it is ConstructorStub && it.isPrimary } .forEach { emitEmptyLine() it.accept(this, element) } if (element is ClassStub.Enum) { emitEnumVarClass(element) } } } } override fun visitTypealias(element: TypealiasStub, data: StubContainer?) { val alias = renderClassifierDeclaration(element.alias) val aliasee = renderStubType(element.aliasee) out("typealias $alias = $aliasee") } override fun visitFunction(element: FunctionStub, data: StubContainer?) { if (element in bridgeBuilderResult.excludedStubs) return val header = run { val parameters = element.parameters.joinToString(prefix = "(", postfix = ")") { renderFunctionParameter(it) } val receiver = element.receiver?.let { renderFunctionReceiver(it) + "." } ?: "" val typeParameters = renderTypeParameters(element.typeParameters) val override = if (element.isOverride) "override " else "" val modality = renderMemberModality(element.modality, data) "$override${modality}fun$typeParameters $receiver${element.name.asSimpleName()}$parameters: ${renderStubType(element.returnType)}" } if (!nativeBridges.isSupported(element)) { sequenceOf( annotationForUnableToImport, "$header = throw UnsupportedOperationException()" ).forEach(out) return } element.annotations.forEach { out(renderAnnotation(it)) } when { element.external -> out("external $header") element.isOptionalObjCMethod() -> out("$header = optional()") element.origin is StubOrigin.Synthetic.EnumByValue -> out("$header = values().find { it.value == value }!!") data != null && data.isInterface -> out(header) else -> block(header) { functionBridgeBodies.getValue(element).forEach(out) } } } override fun visitProperty(element: PropertyStub, data: StubContainer?) = emitProperty(element, data) override fun visitConstructor(constructorStub: ConstructorStub, data: StubContainer?) { constructorStub.annotations.forEach { out(renderAnnotation(it)) } val visibility = renderVisibilityModifier(constructorStub.visibility) out("${visibility}constructor(${constructorStub.parameters.joinToString { renderFunctionParameter(it) }}) {}") } override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: StubContainer?) { } override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: StubContainer?) { if (simpleStubContainer.meta.textAtStart.isNotEmpty()) { out(simpleStubContainer.meta.textAtStart) } simpleStubContainer.classes.forEach { emitEmptyLine() it.accept(this, simpleStubContainer) } simpleStubContainer.functions.forEach { emitEmptyLine() it.accept(this, simpleStubContainer) } simpleStubContainer.properties.forEach { emitEmptyLine() it.accept(this, simpleStubContainer) } simpleStubContainer.typealiases.forEach { emitEmptyLine() it.accept(this, simpleStubContainer) } simpleStubContainer.simpleContainers.forEach { emitEmptyLine() it.accept(this, simpleStubContainer) } if (simpleStubContainer.meta.textAtEnd.isNotEmpty()) { out(simpleStubContainer.meta.textAtEnd) } } } // About method naming convention: // - "emit" prefix means that method will call `out` by itself. // - "render" prefix means that method returns string that should be emitted by caller. private fun emitEnumEntries(enum: ClassStub.Enum) { enum.entries.forEach { out(renderEnumEntry(it) + ",") } out(";") } private fun emitEnumVarClass(enum: ClassStub.Enum) { val simpleKotlinName = enum.classifier.topLevelName.asSimpleName() val typeMirror = builderResult.bridgeGenerationComponents.enumToTypeMirror.getValue(enum) val basePointedTypeName = typeMirror.pointedType.render(kotlinFile) block("class Var(rawPtr: NativePtr) : CEnumVar(rawPtr)") { out("@Deprecated(\"Use sizeOf() or alignOf() instead.\")") out("companion object : Type(sizeOf<$basePointedTypeName>().toInt())") out("var value: $simpleKotlinName") out(" get() = byValue(this.reinterpret<$basePointedTypeName>().value)") out(" set(value) { this.reinterpret<$basePointedTypeName>().value = value.value }") } } private fun emitProperty(element: PropertyStub, owner: StubContainer?) { if (element in bridgeBuilderResult.excludedStubs) return val override = if (element.isOverride) "override " else "" val modality = "$override${renderMemberModality(element.modality, owner)}" val receiver = if (element.receiverType != null) "${renderStubType(element.receiverType)}." else "" val name = if (owner?.isTopLevelContainer == true) { getTopLevelPropertyDeclarationName(kotlinFile, element).asSimpleName() } else { element.name.asSimpleName() } val header = "$receiver$name: ${renderStubType(element.type)}" if (element.kind is PropertyStub.Kind.Val && !nativeBridges.isSupported(element.kind.getter) || element.kind is PropertyStub.Kind.Var && !nativeBridges.isSupported(element.kind.getter)) { out(annotationForUnableToImport) out("val $header") out(" get() = TODO()") } else { element.annotations.forEach { out(renderAnnotation(it)) } when (val kind = element.kind) { is PropertyStub.Kind.Constant -> { out("${modality}const val $header = ${renderValueUsage(kind.constant)}") } is PropertyStub.Kind.Val -> { val shouldWriteInline = kind.getter.let { (it is PropertyAccessor.Getter.SimpleGetter && it.constant != null) // We should render access to constructor parameter inline. // Otherwise, it may be access to the property itself. (val f: Any get() = f) || it is PropertyAccessor.Getter.GetConstructorParameter } if (shouldWriteInline) { out("${modality}val $header ${renderGetter(kind.getter)}") } else { out("${modality}val $header") indent { out(renderGetter(kind.getter)) } } } is PropertyStub.Kind.Var -> { val isSupported = nativeBridges.isSupported(kind.setter) val variableKind = if (isSupported) "var" else "val" out("$modality$variableKind $header") indent { out(renderGetter(kind.getter)) if (isSupported) { out(renderSetter(kind.setter)) } } } } } } private fun renderFunctionReceiver(receiver: ReceiverParameterStub): String { return renderStubType(receiver.type) } private fun renderFunctionParameter(parameter: FunctionParameterStub): String { val annotations = if (parameter.annotations.isEmpty()) "" else parameter.annotations.joinToString(separator = " ") { renderAnnotation(it) } + " " val vararg = if (parameter.isVararg) "vararg " else "" return "$annotations$vararg${parameter.name.asSimpleName()}: ${renderStubType(parameter.type)}" } private fun renderMemberModality(modality: MemberStubModality, container: StubContainer?): String = if (container?.defaultMemberModality == modality) { "" } else when (modality) { MemberStubModality.OPEN -> "open " MemberStubModality.FINAL -> "final " MemberStubModality.ABSTRACT -> "abstract " } private fun renderVisibilityModifier(visibilityModifier: VisibilityModifier) = when (visibilityModifier) { VisibilityModifier.PRIVATE -> "private " VisibilityModifier.PROTECTED -> "protected " VisibilityModifier.INTERNAL -> "internal " VisibilityModifier.PUBLIC -> "" } private fun renderClassHeader(classStub: ClassStub): String { val modality = when (classStub) { is ClassStub.Simple -> renderClassStubModality(classStub.modality) is ClassStub.Companion -> "" is ClassStub.Enum -> "enum class " } val className = when (classStub) { is ClassStub.Simple -> renderClassifierDeclaration(classStub.classifier) is ClassStub.Companion -> "companion object" is ClassStub.Enum -> renderClassifierDeclaration(classStub.classifier) } val constructorParams = classStub.explicitPrimaryConstructor?.parameters?.let(this::renderConstructorParams) ?: "" val inheritance = mutableListOf().apply { // Enum inheritance is implicit. if (classStub !is ClassStub.Enum) { addIfNotNull(classStub.superClassInit?.let { renderSuperInit(it) }) } addAll(classStub.interfaces.map { renderStubType(it) }) }.let { if (it.isNotEmpty()) " : ${it.joinToString()}" else "" } return "$modality$className$constructorParams$inheritance" } private fun renderClassifierDeclaration(classifier: Classifier): String = kotlinFile.declare(classifier).asSimpleName() private fun renderClassStubModality(classStubModality: ClassStubModality): String = when (classStubModality) { ClassStubModality.INTERFACE -> "interface " ClassStubModality.OPEN -> "open class " ClassStubModality.ABSTRACT -> "abstract class " ClassStubModality.NONE -> "class " } private fun renderConstructorParams(parameters: List): String = if (parameters.isEmpty()) { "" } else { parameters.joinToString(prefix = "(", postfix = ")") { renderFunctionParameter(it) } } private fun renderSuperInit(superClassInit: SuperClassInit): String { val parameters = superClassInit.arguments.joinToString(prefix = "(", postfix = ")") { renderValueUsage(it) } return "${renderStubType(superClassInit.type)}$parameters" } private fun renderStubType(stubType: StubType): String { val nullable = if (stubType.nullable) "?" else "" return when (stubType) { is ClassifierStubType -> { val classifier = kotlinFile.reference(stubType.classifier) val typeArguments = renderTypeArguments(stubType.typeArguments) "$classifier$typeArguments$nullable" } is FunctionalType -> buildString { if (stubType.nullable) append("(") append('(') stubType.parameterTypes.joinTo(this) { renderStubType(it) } append(") -> ") append(renderStubType(stubType.returnType)) if (stubType.nullable) append(")?") } is TypeParameterType -> "${stubType.name}$nullable" is AbbreviatedType -> { val classifier = kotlinFile.reference(stubType.abbreviatedClassifier) val typeArguments = renderTypeArguments(stubType.typeArguments) "$classifier$typeArguments$nullable" } } } private fun renderValueUsage(value: ValueStub): String = when (value) { is StringConstantStub -> value.value.quoteAsKotlinLiteral() is IntegralConstantStub -> renderIntegralConstant(value)!! is DoubleConstantStub -> renderDoubleConstant(value)!! is GetConstructorParameter -> value.constructorParameterStub.name } private fun renderAnnotation(annotationStub: AnnotationStub): String = when (annotationStub) { AnnotationStub.ObjC.ConsumesReceiver -> "@CCall.ConsumesReceiver" AnnotationStub.ObjC.ReturnsRetained -> "@CCall.ReturnsRetained" is AnnotationStub.ObjC.Method -> { val stret = if (annotationStub.isStret) ", true" else "" val selector = annotationStub.selector.quoteAsKotlinLiteral() val encoding = annotationStub.encoding.quoteAsKotlinLiteral() "@ObjCMethod($selector, $encoding$stret)" } is AnnotationStub.ObjC.Factory -> { val stret = if (annotationStub.isStret) ", true" else "" val selector = annotationStub.selector.quoteAsKotlinLiteral() val encoding = annotationStub.encoding.quoteAsKotlinLiteral() "@ObjCFactory($selector, $encoding$stret)" } AnnotationStub.ObjC.Consumed -> "@CCall.Consumed" is AnnotationStub.ObjC.Constructor -> "@ObjCConstructor(${annotationStub.selector.quoteAsKotlinLiteral()}, ${annotationStub.designated})" is AnnotationStub.ObjC.ExternalClass -> { val protocolGetter = annotationStub.protocolGetter.quoteAsKotlinLiteral() val binaryName = annotationStub.binaryName.quoteAsKotlinLiteral() "@ExternalObjCClass" + when { annotationStub.protocolGetter.isEmpty() && annotationStub.binaryName.isEmpty() -> "" annotationStub.protocolGetter.isEmpty() -> "(\"\", $binaryName)" annotationStub.binaryName.isEmpty() -> "($protocolGetter)" else -> "($protocolGetter, $binaryName)" } } AnnotationStub.CCall.CString -> "@CCall.CString" AnnotationStub.CCall.WCString -> "@CCall.WCString" is AnnotationStub.CCall.Symbol -> "@CCall(${annotationStub.symbolName.quoteAsKotlinLiteral()})" is AnnotationStub.CStruct -> "@CStruct(${annotationStub.struct.quoteAsKotlinLiteral()})" is AnnotationStub.CNaturalStruct -> "@CNaturalStruct(${annotationStub.members.joinToString { it.name.quoteAsKotlinLiteral() }})" is AnnotationStub.CLength -> "@CLength(${annotationStub.length})" is AnnotationStub.Deprecated -> "@Deprecated(${annotationStub.message.quoteAsKotlinLiteral()}, " + "ReplaceWith(${annotationStub.replaceWith.quoteAsKotlinLiteral()}), " + "DeprecationLevel.${annotationStub.level.name})" is AnnotationStub.CEnumEntryAlias, is AnnotationStub.CEnumVarTypeSize, is AnnotationStub.CStruct.MemberAt, is AnnotationStub.CStruct.ArrayMemberAt, is AnnotationStub.CStruct.BitField, is AnnotationStub.CStruct.VarType -> error("${annotationStub.classifier.fqName} annotation is unsupported in textual mode") } private fun renderEnumEntry(enumEntryStub: EnumEntryStub): String = "${enumEntryStub.name.asSimpleName()}(${renderValueUsage(enumEntryStub.constant)})" private fun renderGetter(accessor: PropertyAccessor.Getter): String { val annotations = accessor.annotations.joinToString(separator = "") { renderAnnotation(it) + " " } return annotations + when (accessor) { is PropertyAccessor.Getter.ExternalGetter -> { "external get" } is PropertyAccessor.Getter.GetConstructorParameter -> "= ${renderPropertyAccessorBody(accessor)}" else -> { "get() = ${renderPropertyAccessorBody(accessor)}" } } } private fun renderSetter(accessor: PropertyAccessor.Setter): String { val annotations = accessor.annotations.joinToString(separator = "") { renderAnnotation(it) + " " } return annotations + if (accessor is PropertyAccessor.Setter.ExternalSetter) { "external set" } else { "set(value) { ${renderPropertyAccessorBody(accessor)} }" } } private fun renderPropertyAccessorBody(accessor: PropertyAccessor): String = when (accessor) { is PropertyAccessor.Getter.SimpleGetter -> { when { accessor in propertyAccessorBridgeBodies -> propertyAccessorBridgeBodies.getValue(accessor) accessor.constant != null -> renderValueUsage(accessor.constant) else -> error("Bridge body for getter was not generated") } } is PropertyAccessor.Getter.GetConstructorParameter -> accessor.constructorParameter.name is PropertyAccessor.Getter.ArrayMemberAt -> "arrayMemberAt(${accessor.offset})" is PropertyAccessor.Getter.MemberAt -> { val typeArguments = renderTypeArguments(accessor.typeArguments) val valueAccess = if (accessor.hasValueAccessor) ".value" else "" "memberAt$typeArguments(${accessor.offset})$valueAccess" } is PropertyAccessor.Getter.ReadBits -> { propertyAccessorBridgeBodies.getValue(accessor) } is PropertyAccessor.Getter.GetEnumEntry -> accessor.enumEntryStub.name is PropertyAccessor.Setter.SimpleSetter -> when { accessor in propertyAccessorBridgeBodies -> propertyAccessorBridgeBodies.getValue(accessor) else -> error("Bridge body for setter was not generated") } is PropertyAccessor.Setter.MemberAt -> { if (accessor.typeArguments.isEmpty()) { error("Unexpected memberAt setter without type parameters!") } else { val typeArguments = renderTypeArguments(accessor.typeArguments) "memberAt$typeArguments(${accessor.offset}).value = value" } } is PropertyAccessor.Setter.WriteBits -> { propertyAccessorBridgeBodies.getValue(accessor) } is PropertyAccessor.Getter.InterpretPointed -> { val typeParameters = accessor.typeParameters.joinToString(prefix = "<", postfix = ">") { renderStubType(it) } val getAddressExpression = propertyAccessorBridgeBodies.getValue(accessor) "interpretPointed$typeParameters($getAddressExpression)" } is PropertyAccessor.Getter.ExternalGetter, is PropertyAccessor.Setter.ExternalSetter -> error("External property accessor shouldn't have a body!") } private fun renderIntegralConstant(integralValue: IntegralConstantStub): String? { val (value, size, isSigned) = integralValue return if (isSigned) { if (value == Long.MIN_VALUE) { return "${value + 1} - 1" // Workaround for "The value is out of range" compile error. } val narrowedValue: Number = when (size) { 1 -> value.toByte() 2 -> value.toShort() 4 -> value.toInt() 8 -> value else -> return null } narrowedValue.toString() } else { // Note: stub generator is built and run with different ABI versions, // so Kotlin unsigned types can't be used here currently. val narrowedValue: String = when (size) { 1 -> (value and 0xFF).toString() 2 -> (value and 0xFFFF).toString() 4 -> (value and 0xFFFFFFFF).toString() 8 -> java.lang.Long.toUnsignedString(value) else -> return null } "${narrowedValue}u" } } private fun renderDoubleConstant(doubleValue: DoubleConstantStub): String? { val (value, size) = doubleValue return when (size) { 4 -> { val floatValue = value.toFloat() val bits = java.lang.Float.floatToRawIntBits(floatValue) "bitsToFloat($bits) /* == $floatValue */" } 8 -> { val bits = java.lang.Double.doubleToRawLongBits(value) "bitsToDouble($bits) /* == $value */" } else -> null } } private fun renderTypeArguments(typeArguments: List) = if (typeArguments.isNotEmpty()) { typeArguments.joinToString(", ", "<", ">") { renderTypeArgument(it) } } else { "" } private fun renderTypeArgument(typeArgument: TypeArgument) = when (typeArgument) { is TypeArgumentStub -> { val variance = when (typeArgument.variance) { TypeArgument.Variance.INVARIANT -> "" TypeArgument.Variance.IN -> "in " TypeArgument.Variance.OUT -> "out " } "$variance${renderStubType(typeArgument.type)}" } TypeArgument.StarProjection -> "*" else -> error("Unexpected type argument: $typeArgument") } private fun renderTypeParameters(typeParameters: List) = if (typeParameters.isNotEmpty()) { typeParameters.joinToString(", ", " <", ">") { renderTypeParameter(it) } } else { "" } private fun renderTypeParameter(typeParameterStub: TypeParameterStub): String { val name = typeParameterStub.name return typeParameterStub.upperBound?.let { "$name : ${renderStubType(it)}" } ?: name } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrType.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty sealed class StubType { abstract val nullable: Boolean abstract val typeArguments: List } /** * Wrapper over [Classifier]. */ class ClassifierStubType( val classifier: Classifier, override val typeArguments: List = emptyList(), override val nullable: Boolean = false ) : StubType() { fun nested(name: String): ClassifierStubType = ClassifierStubType(classifier.nested(name)) override fun toString(): String = "${classifier.topLevelName}${typeArguments.ifNotEmpty { joinToString(prefix = "<", postfix = ">") } ?: ""}" } class AbbreviatedType( val underlyingType: StubType, val abbreviatedClassifier: Classifier, override val typeArguments: List, override val nullable: Boolean = false ) : StubType() { override fun toString(): String = "${abbreviatedClassifier.topLevelName}${typeArguments.ifNotEmpty { joinToString(prefix = "<", postfix = ">") } ?: ""}" } /** * @return type from kotlinx.cinterop package */ fun KotlinPlatform.getRuntimeType(name: String, nullable: Boolean = false): StubType { val classifier = Classifier.topLevel(cinteropPackage, name) PredefinedTypesHandler.tryExpandPlatformDependentTypealias(classifier, this, nullable)?.let { return it } return ClassifierStubType(classifier, nullable = nullable) } /** * Functional type from kotlin package: ([parameterTypes]) -> [returnType] */ class FunctionalType( val parameterTypes: List, // TODO: Use TypeArguments. val returnType: StubType, override val nullable: Boolean = false ) : StubType() { val classifier: Classifier = Classifier.topLevel("kotlin", "Function${parameterTypes.size}") override val typeArguments: List by lazy { listOf(*parameterTypes.toTypedArray(), returnType).map { TypeArgumentStub(it) } } } class TypeParameterType( val name: String, override val nullable: Boolean, val typeParameterDeclaration: TypeParameterStub ) : StubType() { override val typeArguments: List = emptyList() } fun KotlinType.toStubIrType(): StubType = when (this) { is KotlinFunctionType -> this.toStubIrType() is KotlinClassifierType -> this.toStubIrType() else -> error("Unexpected KotlinType: $this") } private fun KotlinFunctionType.toStubIrType(): StubType = FunctionalType(parameterTypes.map(KotlinType::toStubIrType), returnType.toStubIrType(), nullable) private fun KotlinClassifierType.toStubIrType(): StubType { val typeArguments = arguments.map(KotlinTypeArgument::toStubIrType) PredefinedTypesHandler.tryExpandPredefinedTypealias(classifier, nullable, typeArguments)?.let { return it } return if (underlyingType == null) { ClassifierStubType(classifier, typeArguments, nullable) } else { AbbreviatedType(underlyingType.toStubIrType(), classifier, typeArguments, nullable) } } private fun KotlinTypeArgument.toStubIrType(): TypeArgument = when (this) { is KotlinType -> TypeArgumentStub(this.toStubIrType()) StarProjection -> TypeArgument.StarProjection else -> error("Unexpected KotlinTypeArgument: $this") } /** * Types that come from kotlinx.cinterop require special handling because we * don't have explicit information about their structure. * For example, to be able to produce metadata-based interop library we need to know * that ByteVar is a typealias to ByteVarOf. */ private object PredefinedTypesHandler { private const val cInteropPackage = "kotlinx.cinterop" private val nativePtrClassifier = Classifier.topLevel(cInteropPackage, "NativePtr") private val primitives = setOf( KotlinTypes.boolean, KotlinTypes.byte, KotlinTypes.short, KotlinTypes.int, KotlinTypes.long, KotlinTypes.uByte, KotlinTypes.uShort, KotlinTypes.uInt, KotlinTypes.uLong, KotlinTypes.float, KotlinTypes.double, KotlinTypes.vector128 ) /** * kotlinx.cinterop.{primitive}Var -> kotlin.{primitive} */ private val primitiveVarClassifierToPrimitiveType: Map = primitives.associateBy { val typeVar = "${it.classifier.topLevelName}Var" Classifier.topLevel(cInteropPackage, typeVar) } /** * @param primitiveType primitive type from kotlin package. * @return kotlinx.cinterop.[primitiveType]VarOf<[primitiveType]> */ private fun getVarOfTypeFor(primitiveType: KotlinClassifierType, nullable: Boolean): ClassifierStubType { val typeVarOf = "${primitiveType.classifier.topLevelName}VarOf" val classifier = Classifier.topLevel(cInteropPackage, typeVarOf) return ClassifierStubType(classifier, listOf(TypeArgumentStub(primitiveType.toStubIrType())), nullable = nullable) } private fun expandCOpaquePointerVar(nullable: Boolean): AbbreviatedType { val typeArgument = TypeArgumentStub(expandCOpaquePointer(nullable=false)) val underlyingType = ClassifierStubType( KotlinTypes.cPointerVarOf, listOf(typeArgument), nullable = nullable ) return AbbreviatedType(underlyingType, KotlinTypes.cOpaquePointerVar.classifier, emptyList(), nullable) } private fun expandCOpaquePointer(nullable: Boolean): AbbreviatedType { val typeArgument = TypeArgumentStub(ClassifierStubType(KotlinTypes.cPointed), TypeArgument.Variance.OUT) val underlyingType = ClassifierStubType( KotlinTypes.cPointer, listOf(typeArgument), nullable = nullable ) return AbbreviatedType(underlyingType, KotlinTypes.cOpaquePointer.classifier, emptyList(), nullable) } private fun expandCPointerVar(typeArguments: List, nullable: Boolean): AbbreviatedType { require(typeArguments.size == 1) { "CPointerVar has only one type argument." } val cPointer = ClassifierStubType(KotlinTypes.cPointer, typeArguments) val cPointerVarOfTypeArgument = TypeArgumentStub(cPointer) val underlyingType = ClassifierStubType( KotlinTypes.cPointerVarOf, listOf(cPointerVarOfTypeArgument), nullable = nullable ) return AbbreviatedType(underlyingType, KotlinTypes.cPointerVar, typeArguments, nullable) } /** * @param primitiveVarType one of kotlinx.cinterop.{primitive}Var types. * @return typealias in terms of StubIR types. */ private fun expandPrimitiveVarType(primitiveVarClassifier: Classifier, nullable: Boolean): AbbreviatedType { val primitiveType = primitiveVarClassifierToPrimitiveType.getValue(primitiveVarClassifier) val underlyingType = getVarOfTypeFor(primitiveType, nullable) return AbbreviatedType(underlyingType, primitiveVarClassifier, listOf(), nullable) } private fun expandNativePtr(platform: KotlinPlatform, nullable: Boolean): StubType { val underlyingTypeClassifier = when (platform) { KotlinPlatform.JVM -> KotlinTypes.long.classifier KotlinPlatform.NATIVE -> Classifier.topLevel("kotlin.native.internal", "NativePtr") } val underlyingType = ClassifierStubType(underlyingTypeClassifier, nullable = nullable) return AbbreviatedType(underlyingType, nativePtrClassifier, listOf(), nullable) } private fun expandObjCObjectMeta(typeArguments: List, nullable: Boolean): AbbreviatedType { require(typeArguments.isEmpty()) val objCClass = ClassifierStubType(KotlinTypes.objCClass, emptyList(), nullable) return AbbreviatedType(objCClass, KotlinTypes.objCObjectMeta, emptyList(), nullable) } private fun expandCArrayPointer(typeArguments: List, nullable: Boolean): AbbreviatedType { val cPointer = ClassifierStubType(KotlinTypes.cPointer, typeArguments) return AbbreviatedType(cPointer, KotlinTypes.cArrayPointer, typeArguments, nullable) } private fun expandObjCBlockVar(typeArguments: List, nullable: Boolean): AbbreviatedType { val underlyingType = ClassifierStubType(KotlinTypes.objCNotImplementedVar, typeArguments, nullable) return AbbreviatedType(underlyingType, KotlinTypes.objCBlockVar, typeArguments, nullable) } /** * @return [ClassifierStubType] if [classifier] is a typealias from [kotlinx.cinterop] package. */ fun tryExpandPredefinedTypealias(classifier: Classifier, nullable: Boolean, typeArguments: List): AbbreviatedType? = when (classifier) { in primitiveVarClassifierToPrimitiveType.keys -> expandPrimitiveVarType(classifier, nullable) KotlinTypes.cOpaquePointer.classifier -> expandCOpaquePointer(nullable) KotlinTypes.cOpaquePointerVar.classifier -> expandCOpaquePointerVar(nullable) KotlinTypes.cPointerVar -> expandCPointerVar(typeArguments, nullable) KotlinTypes.objCObjectMeta -> expandObjCObjectMeta(typeArguments, nullable) KotlinTypes.cArrayPointer -> expandCArrayPointer(typeArguments, nullable) KotlinTypes.objCBlockVar -> expandObjCBlockVar(typeArguments, nullable) else -> null } /** * Variant of [tryExpandPredefinedTypealias] with [platform]-dependent result. */ fun tryExpandPlatformDependentTypealias( classifier: Classifier, platform: KotlinPlatform, nullable: Boolean ): StubType? = when (classifier) { nativePtrClassifier -> expandNativePtr(platform, nullable) else -> null } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrVisitor.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen interface StubIrVisitor { fun visitClass(element: ClassStub, data: T): R fun visitTypealias(element: TypealiasStub, data: T): R fun visitFunction(element: FunctionStub, data: T): R fun visitProperty(element: PropertyStub, data: T): R fun visitConstructor(constructorStub: ConstructorStub, data: T): R fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: T): R fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: T): R } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/TypeUtils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.native.interop.indexer.* val EnumDef.isAnonymous: Boolean get() = spelling.contains("(anonymous ") // TODO: it is a hack val StructDecl.isAnonymous: Boolean get() = spelling.contains("(anonymous ") // TODO: it is a hack /** * Returns the expression which could be used for this type in C code. * Note: the resulting string doesn't exactly represent this type, but it is enough for current purposes. * * TODO: use libclang to implement? */ fun Type.getStringRepresentation(): String = when (this) { VoidType -> "void" CharType -> "char" CBoolType -> "_Bool" ObjCBoolType -> "BOOL" is IntegerType -> this.spelling is FloatingType -> this.spelling is VectorType -> this.spelling is PointerType -> getPointerTypeStringRepresentation(this.pointeeType) is ArrayType -> getPointerTypeStringRepresentation(this.elemType) is RecordType -> this.decl.spelling is EnumType -> if (this.def.isAnonymous) { this.def.baseType.getStringRepresentation() } else { this.def.spelling } is Typedef -> this.def.aliased.getStringRepresentation() is ObjCPointer -> when (this) { is ObjCIdType -> "id$protocolQualifier" is ObjCClassPointer -> "Class$protocolQualifier" is ObjCObjectPointer -> "${def.name}$protocolQualifier*" is ObjCInstanceType -> TODO(this.toString()) // Must have already been handled. is ObjCBlockPointer -> "id" } else -> throw NotImplementedError() } fun getPointerTypeStringRepresentation(pointee: Type): String = (getStringRepresentationOfPointee(pointee) ?: "void") + "*" private fun getStringRepresentationOfPointee(type: Type): String? { val unwrapped = type.unwrapTypedefs() return when (unwrapped) { is PrimitiveType -> unwrapped.getStringRepresentation() is PointerType -> getStringRepresentationOfPointee(unwrapped.pointeeType)?.plus("*") is RecordType -> if (unwrapped.decl.isAnonymous || unwrapped.decl.spelling == "struct __va_list_tag") { null } else { unwrapped.decl.spelling } else -> null } } private val ObjCQualifiedPointer.protocolQualifier: String get() = if (this.protocols.isEmpty()) "" else " <${protocols.joinToString { it.name }}>" fun blockTypeStringRepresentation(type: ObjCBlockPointer): String { return buildString { append(type.returnType.getStringRepresentation()) append("(^)") append("(") val blockParameters = if (type.parameterTypes.isEmpty()) { "void" } else { type.parameterTypes.joinToString { it.getStringRepresentation() } } append(blockParameters) append(")") } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/defFileDependencies.kt ================================================ package org.jetbrains.kotlin.native.interop.gen import org.jetbrains.kotlin.konan.util.DefFile import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform import org.jetbrains.kotlin.native.interop.gen.jvm.buildNativeLibrary import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool import org.jetbrains.kotlin.native.interop.indexer.NativeLibraryHeaders import org.jetbrains.kotlin.native.interop.indexer.getHeaderPaths import org.jetbrains.kotlin.native.interop.tool.CInteropArguments import java.io.File fun defFileDependencies(args: Array) { val defFiles = mutableListOf() val targets = mutableListOf() var index = 0 while (index < args.size) { val arg = args[index] ++index when (arg) { "-target" -> { targets += args[index] ++index } else -> { defFiles.add(File(arg)) } } } defFileDependencies(makeDependencyAssigner(targets, defFiles)) } private fun makeDependencyAssigner(targets: List, defFiles: List) = CompositeDependencyAssigner(targets.map { makeDependencyAssignerForTarget(it, defFiles) }) private fun makeDependencyAssignerForTarget(target: String, defFiles: List): SingleTargetDependencyAssigner { val tool = prepareTool(target, KotlinPlatform.NATIVE) val cinteropArguments = CInteropArguments() cinteropArguments.argParser.parse(arrayOf()) val libraries = defFiles.associateWith { buildNativeLibrary( tool, DefFile(it, tool.substitutions), cinteropArguments, ImportsImpl(emptyMap()) ).getHeaderPaths() } return SingleTargetDependencyAssigner(libraries) } private fun defFileDependencies(dependencyAssigner: DependencyAssigner) { while (!dependencyAssigner.isDone()) { val (file, depends) = dependencyAssigner.getReady().entries.sortedBy { it.key }.first() dependencyAssigner.markDone(file) patchDepends(file, depends.sorted()) println("${file.name} done.") } } private fun patchDepends(file: File, newDepends: List) { val defFileLines = file.readLines() val dependsLine = buildString { append("depends =") newDepends.forEach { append(" ") append(it) } } val newDefFileLines = listOf(dependsLine) + defFileLines.filter { !it.startsWith("depends =") } file.bufferedWriter().use { writer -> newDefFileLines.forEach { writer.appendLine(it) } } } private interface DependencyAssigner { fun isDone(): Boolean fun getReady(): Map> fun markDone(file: File) } private class CompositeDependencyAssigner(val dependencyAssigners: List) : DependencyAssigner { override fun isDone(): Boolean = dependencyAssigners.all { it.isDone() } override fun getReady(): Map> { return dependencyAssigners.map { it.getReady() }.reduce { left, right -> (left.keys intersect right.keys) .associateWith { left.getValue(it) union right.getValue(it) } }.also { require(it.isNotEmpty()) { "incompatible dependencies" } // TODO: add more info. } } override fun markDone(file: File) { dependencyAssigners.forEach { it.markDone(file) } } } private class SingleTargetDependencyAssigner( defFilesToHeaders: Map> ) : DependencyAssigner { private val pendingDefFilesToHeaders = defFilesToHeaders.toMutableMap() private val processedHeadersToDefFiles = mutableMapOf() init { val ownedHeaders = pendingDefFilesToHeaders.values.flatMap { it.ownHeaders } val unownedHeadersToDefFiles = mutableMapOf() pendingDefFilesToHeaders.forEach { (def, lib) -> (lib.importedHeaders - ownedHeaders).forEach { unownedHeadersToDefFiles.putIfAbsent(it, def) } } if (unownedHeadersToDefFiles.isNotEmpty()) { error("Unowned headers:\n" + unownedHeadersToDefFiles.entries.joinToString("\n") { "${it.key}\n imported by: ${it.value.name}" }) } } override fun isDone(): Boolean = pendingDefFilesToHeaders.isEmpty() override fun getReady(): Map> { val result = mutableMapOf>() defFiles@for ((defFile, headers) in pendingDefFilesToHeaders) { val depends = mutableSetOf() headers@for (header in (headers.ownHeaders + headers.importedHeaders)) { val dependency = processedHeadersToDefFiles[header] ?: if (header in headers.ownHeaders) continue@headers else continue@defFiles depends.add(dependency.nameWithoutExtension) } result[defFile] = depends } if (result.isEmpty()) { pendingDefFilesToHeaders.entries.forEach { (def, headers) -> println(def.name) println("Own headers:") headers.ownHeaders.forEach { println(it) } println("Unowned imported headers:") headers.importedHeaders.forEach { if (it !in processedHeadersToDefFiles) println(it) } println() } error("Cyclic dependency? Remaining libs:\n" + pendingDefFilesToHeaders.keys.joinToString("\n") { it.name }) } return result } override fun markDone(file: File) { val headers = pendingDefFilesToHeaders.remove(file)!! headers.ownHeaders.forEach { processedHeadersToDefFiles.putIfAbsent(it, file) } } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.tool import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlinx.cli.* import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode const val HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX = "headerFilterAdditionalSearchPrefix" const val NODEFAULTLIBS_DEPRECATED = "nodefaultlibs" const val NODEFAULTLIBS = "no-default-libs" const val NOENDORSEDLIBS = "no-endorsed-libs" const val PURGE_USER_LIBS = "Xpurge-user-libs" const val TEMP_DIR = "Xtemporary-files-dir" const val NOPACK = "nopack" const val COMPILE_SOURCES = "Xcompile-source" const val SHORT_MODULE_NAME = "Xshort-module-name" const val FOREIGN_EXCEPTION_MODE = "Xforeign-exception-mode" // TODO: unify camel and snake cases. // Possible solution is to accept both cases open class CommonInteropArguments(val argParser: ArgParser) { val verbose by argParser.option(ArgType.Boolean, description = "Enable verbose logging output").default(false) val pkg by argParser.option(ArgType.String, description = "place generated bindings to the package") val output by argParser.option(ArgType.String, shortName = "o", description = "specifies the resulting library file") .default("nativelib") val libraryPath by argParser.option(ArgType.String, description = "add a library search path") .multiple().delimiter(",") val staticLibrary by argParser.option(ArgType.String, description = "embed static library to the result") .multiple().delimiter(",") val library by argParser.option(ArgType.String, shortName = "l", description = "library to use for building") .multiple() val repo by argParser.option(ArgType.String, shortName = "r", description = "repository to resolve dependencies") .multiple() val mode by argParser.option(ArgType.Choice(), description = "the way interop library is generated") .default(DEFAULT_MODE) val nodefaultlibs by argParser.option(ArgType.Boolean, NODEFAULTLIBS, description = "don't link the libraries from dist/klib automatically").default(false) val nodefaultlibsDeprecated by argParser.option(ArgType.Boolean, NODEFAULTLIBS_DEPRECATED, description = "don't link the libraries from dist/klib automatically", deprecatedWarning = "Old form of flag. Please, use $NODEFAULTLIBS.").default(false) val noendorsedlibs by argParser.option(ArgType.Boolean, NOENDORSEDLIBS, description = "don't link the endorsed libraries from dist automatically").default(false) val purgeUserLibs by argParser.option(ArgType.Boolean, PURGE_USER_LIBS, description = "don't link unused libraries even explicitly specified").default(false) val nopack by argParser.option(ArgType.Boolean, fullName = NOPACK, description = "Don't pack the produced library into a klib file").default(false) val tempDir by argParser.option(ArgType.String, TEMP_DIR, description = "save temporary files to the given directory") val kotlincOption by argParser.option(ArgType.String, "Xkotlinc-option", description = "additional kotlinc compiler option").multiple() companion object { val DEFAULT_MODE = GenerationMode.METADATA } } open class CInteropArguments(argParser: ArgParser = ArgParser("cinterop", prefixStyle = ArgParser.OptionPrefixStyle.JVM)): CommonInteropArguments(argParser) { val target by argParser.option(ArgType.String, description = "native target to compile to").default("host") val def by argParser.option(ArgType.String, description = "the library definition file") val header by argParser.option(ArgType.String, description = "header file to produce kotlin bindings for") .multiple().delimiter(",") val headerFilterPrefix by argParser.option(ArgType.String, HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX, "hfasp", "header file to produce kotlin bindings for").multiple().delimiter(",") val compilerOpts by argParser.option(ArgType.String, description = "additional compiler options (allows to add several options separated by spaces)", deprecatedWarning = "-compilerOpts is deprecated. Please use -compiler-options.") .multiple().delimiter(" ") val compilerOptions by argParser.option(ArgType.String, "compiler-options", description = "additional compiler options (allows to add several options separated by spaces)") .multiple().delimiter(" ") val linkerOpts = argParser.option(ArgType.String, "linkerOpts", description = "additional linker options (allows to add several options separated by spaces)", deprecatedWarning = "-linkerOpts is deprecated. Please use -linker-options.") .multiple().delimiter(" ") val linkerOptions = argParser.option(ArgType.String, "linker-options", description = "additional linker options (allows to add several options separated by spaces)") .multiple().delimiter(" ") val compilerOption by argParser.option(ArgType.String, "compiler-option", description = "additional compiler option").multiple() val linkerOption = argParser.option(ArgType.String, "linker-option", description = "additional linker option").multiple() val linker by argParser.option(ArgType.String, description = "use specified linker") val compileSource by argParser.option(ArgType.String, fullName = COMPILE_SOURCES, description = "additional C/C++ sources to be compiled into resulting library" ).multiple() val sourceCompileOptions by argParser.option(ArgType.String, fullName = "Xsource-compiler-option", description = "compiler options for sources provided via -$COMPILE_SOURCES" ).multiple() val shortModuleName by argParser.option(ArgType.String, fullName = SHORT_MODULE_NAME, description = "A short name used to denote this library in the IDE" ) val moduleName by argParser.option(ArgType.String, fullName = "Xmodule-name", description = "A full name of the library used for dependency resolution" ) val foreignExceptionMode by argParser.option(ArgType.String, FOREIGN_EXCEPTION_MODE, description = "Handle native exception in Kotlin: ") } class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop", prefixStyle = ArgParser.OptionPrefixStyle.JVM)): CommonInteropArguments(argParser) { enum class TargetType { WASM32; override fun toString() = name.toLowerCase() } val target by argParser.option(ArgType.Choice(), description = "wasm target to compile to").default(TargetType.WASM32) } internal fun warn(msg: String) { println("warning: $msg") } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/GenerationMode.kt ================================================ package org.jetbrains.kotlin.native.interop.gen.jvm enum class GenerationMode(val modeName: String) { SOURCE_CODE("sourcecode"), METADATA("metadata"); override fun toString(): String = modeName } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/InteropConfiguration.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen.jvm import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.native.interop.indexer.CompilationWithPCH /** * Describes the native library and the options for adjusting the Kotlin API to be generated for this library. */ class InteropConfiguration( val library: CompilationWithPCH, val pkgName: String, val excludedFunctions: Set, val excludedMacros: Set, val strictEnums: Set, val nonStrictEnums: Set, val noStringConversion: Set, val exportForwardDeclarations: List, val disableDesignatedInitializerChecks: Boolean, val target: KonanTarget ) enum class KotlinPlatform { JVM, NATIVE } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/InteropLibraryCreation.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.interop.gen.jvm import kotlinx.metadata.* import kotlinx.metadata.KmModuleFragment import kotlinx.metadata.klib.fqName import kotlinx.metadata.klib.className import kotlinx.metadata.klib.KlibModuleFragmentWriteStrategy import kotlinx.metadata.klib.KlibModuleMetadata import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.impl.KonanLibraryLayoutForWriter import org.jetbrains.kotlin.konan.library.impl.KonanLibraryWriterImpl import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibraryVersioning import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.library.impl.BuiltInsPlatform import java.util.* fun createInteropLibrary( metadata: KlibModuleMetadata, outputPath: String, moduleName: String, nativeBitcodeFiles: List, target: KonanTarget, manifest: Properties, dependencies: List, nopack: Boolean, shortName: String?, staticLibraries: List ) { val version = KotlinLibraryVersioning( libraryVersion = null, abiVersion = KotlinAbiVersion.CURRENT, compilerVersion = CompilerVersion.CURRENT.toString(), metadataVersion = KlibMetadataVersion.INSTANCE.toString(), irVersion = KlibIrVersion.INSTANCE.toString() ) val libFile = File(outputPath) val unzippedDir = if (nopack) libFile else org.jetbrains.kotlin.konan.file.createTempDir("klib") val layout = KonanLibraryLayoutForWriter(libFile, unzippedDir, target) KonanLibraryWriterImpl( moduleName, version, target, BuiltInsPlatform.NATIVE, nopack = nopack, shortName = shortName, layout = layout ).apply { val serializedMetadata = metadata.write(ChunkingWriteStrategy()) addMetadata(SerializedMetadata(serializedMetadata.header, serializedMetadata.fragments, serializedMetadata.fragmentNames)) nativeBitcodeFiles.forEach(this::addNativeBitcode) addManifestAddend(manifest) addLinkDependencies(dependencies) staticLibraries.forEach(this::addIncludedBinary) commit() } } // TODO: Consider adding it to kotlinx-metadata-klib. class ChunkingWriteStrategy( private val classesChunkSize: Int = 128, private val packagesChunkSize: Int = 128 ) : KlibModuleFragmentWriteStrategy { override fun processPackageParts(parts: List): List { if (parts.isEmpty()) return emptyList() val fqName = parts.first().fqName ?: error("KmModuleFragment should have a not-null fqName!") val classFragments = parts.flatMap(KmModuleFragment::classes) .chunked(classesChunkSize) { chunk -> KmModuleFragment().also { fragment -> fragment.fqName = fqName fragment.classes += chunk chunk.mapTo(fragment.className, KmClass::name) } } val packageFragments = parts.mapNotNull(KmModuleFragment::pkg) .flatMap { it.functions + it.typeAliases + it.properties } .chunked(packagesChunkSize) { chunk -> KmModuleFragment().also { fragment -> fragment.fqName = fqName fragment.pkg = KmPackage().also { pkg -> pkg.fqName = fqName pkg.properties += chunk.filterIsInstance() pkg.functions += chunk.filterIsInstance() pkg.typeAliases += chunk.filterIsInstance() } } } val result = classFragments + packageFragments return if (result.isEmpty()) { // We still need to emit empty packages because they may // represent parts of package declaration (e.g. platform.[]). // Tooling (e.g. `klib contents`) expects this kind of behavior. parts } else { result } } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/ToolConfig.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.tool import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.target.customerDistribution import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform class ToolConfig(userProvidedTargetName: String?, flavor: KotlinPlatform) { private val konanHome = KonanHomeProvider.determineKonanHome() private val distribution = customerDistribution(konanHome) private val platformManager = PlatformManager(distribution) private val targetManager = platformManager.targetManager(userProvidedTargetName) private val host = HostManager.host val target = targetManager.target private val platform = platformManager.platform(target) val clang = platform.clang val substitutions = defaultTargetSubstitutions(target) fun downloadDependencies() = platform.downloadDependencies() val defaultCompilerOpts = platform.clang.targetLibclangArgs.toList() val platformCompilerOpts = if (flavor == KotlinPlatform.JVM) platform.clang.hostCompilerArgsForJni.toList() else emptyList() val llvmHome = platform.absoluteLlvmHome val sysRoot = platform.absoluteTargetSysRoot val libclang = when (host) { KonanTarget.MINGW_X64 -> "$llvmHome/bin/libclang.dll" else -> "$llvmHome/lib/${System.mapLibraryName("clang")}" } } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen.jvm import org.jetbrains.kotlin.konan.TempFiles import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.util.DefFile import org.jetbrains.kotlin.native.interop.gen.* import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib import org.jetbrains.kotlin.native.interop.indexer.* import org.jetbrains.kotlin.native.interop.tool.* import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlinx.cli.default import kotlinx.cli.required import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.konan.library.* import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.packageFqName import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.library.resolver.impl.KotlinLibraryResolverImpl import org.jetbrains.kotlin.library.resolver.impl.libraryResolver import org.jetbrains.kotlin.library.toUnresolvedLibraries import org.jetbrains.kotlin.util.removeSuffixIfPresent import org.jetbrains.kotlin.util.suffixIfNot import java.io.File import java.lang.IllegalArgumentException import java.nio.file.* import java.util.* data class InternalInteropOptions(val generated: String, val natives: String, val manifest: String? = null, val cstubsName: String? = null) fun main(args: Array) { // Adding flavor option for interop plugin. class FullCInteropArguments: CInteropArguments() { val flavor by argParser.option(ArgType.Choice(), description = "Interop target") .default(KotlinPlatform.JVM) val generated by argParser.option(ArgType.String, description = "place generated bindings to the directory") .required() val natives by argParser.option(ArgType.String, description = "where to put the built native files") .required() } val arguments = FullCInteropArguments() arguments.argParser.parse(args) val flavorName = arguments.flavor processCLib(flavorName, arguments, InternalInteropOptions(arguments.generated, arguments.natives)) } fun interop( flavor: String, args: Array, additionalArgs: InternalInteropOptions ): Array? = when(flavor) { "jvm", "native" -> { val cinteropArguments = CInteropArguments() cinteropArguments.argParser.parse(args) val platform = KotlinPlatform.values().single { it.name.equals(flavor, ignoreCase = true) } processCLib(platform, cinteropArguments, additionalArgs) } "wasm" -> processIdlLib(args, additionalArgs) else -> error("Unexpected flavor") } // Options, whose values are space-separated and can be escaped. val escapedOptions = setOf("-compilerOpts", "-linkerOpts", "-compiler-options", "-linker-options") private fun String.asArgList(key: String) = if (escapedOptions.contains(key)) this.split(Regex("(? Collection.atMostOne(): T? { return when (this.size) { 0 -> null 1 -> this.iterator().next() else -> throw IllegalArgumentException("Collection has more than one element.") } } private fun List?.isTrue(): Boolean { // The rightmost wins, null != "true". return this?.last() == "true" } private fun runCmd(command: Array, verbose: Boolean = false) { Command(*command).getOutputLines(true).let { lines -> if (verbose) lines.forEach(::println) } } private fun Properties.storeProperties(file: File) { file.outputStream().use { this.store(it, null) } } private fun Properties.putAndRunOnReplace(key: Any, newValue: Any, beforeReplace: (Any, Any, Any) -> Unit) { val oldValue = this[key] if (oldValue != null && oldValue != newValue) { beforeReplace(key, oldValue, newValue) } this[key] = newValue } private fun selectNativeLanguage(config: DefFile.DefFileConfig): Language { val languages = mapOf( "C" to Language.C, "Objective-C" to Language.OBJECTIVE_C ) val language = config.language ?: return Language.C return languages[language] ?: error("Unexpected language '$language'. Possible values are: ${languages.keys.joinToString { "'$it'" }}") } private fun parseImports(dependencies: List): ImportsImpl = dependencies.filterIsInstance().mapNotNull { library -> // TODO: handle missing properties? library.packageFqName?.let { packageFqName -> val headerIds = library.includedHeaders headerIds.map { HeaderId(it) to PackageInfo(packageFqName, library) } } }.reversed().flatten().toMap().let(::ImportsImpl) fun getCompilerFlagsForVfsOverlay(headerFilterPrefix: Array, def: DefFile): List { val relativeToRoot = mutableMapOf() // TODO: handle clashes val filteredIncludeDirs = headerFilterPrefix .map { Paths.get(it) } if (filteredIncludeDirs.isNotEmpty()) { val headerFilterGlobs = def.config.headerFilter if (headerFilterGlobs.isEmpty()) { error("'$HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX' option requires " + "'headerFilter' to be specified in .def file") } relativeToRoot += findFilesByGlobs(roots = filteredIncludeDirs, globs = headerFilterGlobs) } if (relativeToRoot.isEmpty()) { return emptyList() } val virtualRoot = Paths.get(System.getProperty("java.io.tmpdir")).resolve("konanSystemInclude") val virtualPathToReal = relativeToRoot.map { (relativePath, realRoot) -> virtualRoot.resolve(relativePath) to realRoot.resolve(relativePath) }.toMap() val vfsOverlayFile = createVfsOverlayFile(virtualPathToReal) return listOf("-I${virtualRoot.toAbsolutePath()}", "-ivfsoverlay", vfsOverlayFile.toAbsolutePath().toString()) } private fun findFilesByGlobs(roots: List, globs: List): Map { val relativeToRoot = mutableMapOf() val pathMatchers = globs.map { FileSystems.getDefault().getPathMatcher("glob:$it") } roots.reversed() .filter { path -> return@filter when { path.toFile().exists() -> true else -> { warn("$path doesn't exist"); false } } } .forEach { root -> // TODO: don't scan the entire tree, skip subdirectories according to globs. Files.walk(root, FileVisitOption.FOLLOW_LINKS).forEach { path -> val relativePath = root.relativize(path) if (!Files.isDirectory(path) && pathMatchers.any { it.matches(relativePath) }) { relativeToRoot[relativePath] = root } } } return relativeToRoot } private fun processCLib(flavor: KotlinPlatform, cinteropArguments: CInteropArguments, additionalArgs: InternalInteropOptions): Array? { val ktGenRoot = additionalArgs.generated val nativeLibsDir = additionalArgs.natives val defFile = cinteropArguments.def?.let { File(it) } val manifestAddend = additionalArgs.manifest?.let { File(it) } if (defFile == null && cinteropArguments.pkg == null) { cinteropArguments.argParser.printError("-def or -pkg should be provided!") } val tool = prepareTool(cinteropArguments.target, flavor) val def = DefFile(defFile, tool.substitutions) val isLinkerOptsSetByUser = (cinteropArguments.linkerOpts.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) || (cinteropArguments.linkerOptions.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) || (cinteropArguments.linkerOption.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) if (flavor == KotlinPlatform.NATIVE && isLinkerOptsSetByUser) { warn("-linker-option(s)/-linkerOpts option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.") } val additionalLinkerOpts = cinteropArguments.linkerOpts.value.toTypedArray() + cinteropArguments.linkerOption.value.toTypedArray() + cinteropArguments.linkerOptions.value.toTypedArray() val verbose = cinteropArguments.verbose val language = selectNativeLanguage(def.config) val entryPoint = def.config.entryPoints.atMostOne() val linkerOpts = def.config.linkerOpts.toTypedArray() + tool.defaultCompilerOpts + additionalLinkerOpts val linkerName = cinteropArguments.linker ?: def.config.linker val linker = "${tool.llvmHome}/bin/$linkerName" val compiler = "${tool.llvmHome}/bin/clang" val excludedFunctions = def.config.excludedFunctions.toSet() val excludedMacros = def.config.excludedMacros.toSet() val staticLibraries = def.config.staticLibraries + cinteropArguments.staticLibrary.toTypedArray() val libraryPaths = def.config.libraryPaths + cinteropArguments.libraryPath.toTypedArray() val fqParts = (cinteropArguments.pkg ?: def.config.packageName)?.split('.') ?: defFile!!.name.split('.').reversed().drop(1) val outKtPkg = fqParts.joinToString(".") val mode = run { val providedMode = cinteropArguments.mode if (providedMode == GenerationMode.METADATA && flavor == KotlinPlatform.JVM) { warn("Metadata mode isn't supported for Kotlin/JVM! Falling back to sourcecode.") GenerationMode.SOURCE_CODE } else { providedMode } } val resolver = getLibraryResolver(cinteropArguments, tool.target) val allLibraryDependencies = when (flavor) { KotlinPlatform.NATIVE -> resolveDependencies(resolver, cinteropArguments) else -> listOf() } val libName = additionalArgs.cstubsName ?: fqParts.joinToString("") + "stubs" val tempFiles = TempFiles(libName, cinteropArguments.tempDir) val imports = parseImports(allLibraryDependencies) val library = buildNativeLibrary(tool, def, cinteropArguments, imports) val (nativeIndex, compilation) = buildNativeIndex(library, verbose) // Our current approach to arm64_32 support is to compile armv7k version of bitcode // for arm64_32. That's the reason for this substitution. // TODO: Add proper support with the next LLVM update. val target = when (tool.target) { KonanTarget.WATCHOS_ARM64 -> KonanTarget.WATCHOS_ARM32 else -> tool.target } val klibSuffix = CompilerOutputKind.LIBRARY.suffix(target) val moduleName = cinteropArguments.moduleName ?: File(cinteropArguments.output).name.removeSuffixIfPresent(klibSuffix) val configuration = InteropConfiguration( library = compilation, pkgName = outKtPkg, excludedFunctions = excludedFunctions, excludedMacros = excludedMacros, strictEnums = def.config.strictEnums.toSet(), nonStrictEnums = def.config.nonStrictEnums.toSet(), noStringConversion = def.config.noStringConversion.toSet(), exportForwardDeclarations = def.config.exportForwardDeclarations, disableDesignatedInitializerChecks = def.config.disableDesignatedInitializerChecks, target = target ) File(nativeLibsDir).mkdirs() val outCFile = tempFiles.create(libName, ".${language.sourceFileExtension}") val logger = if (verbose) { { message: String -> println(message) } } else { {} } val stubIrContext = StubIrContext(logger, configuration, nativeIndex, imports, flavor, mode, libName) val stubIrOutput = run { val outKtFileCreator = { val outKtFileName = fqParts.last() + ".kt" val outKtFileRelative = (fqParts + outKtFileName).joinToString("/") val file = File(ktGenRoot, outKtFileRelative) file.parentFile.mkdirs() file } val driverOptions = StubIrDriver.DriverOptions(entryPoint, moduleName, File(outCFile.absolutePath), outKtFileCreator) val stubIrDriver = StubIrDriver(stubIrContext, driverOptions) stubIrDriver.run() } // TODO: if a library has partially included headers, then it shouldn't be used as a dependency. def.manifestAddendProperties["includedHeaders"] = nativeIndex.includedHeaders.joinToString(" ") { it.value } def.manifestAddendProperties.putAndRunOnReplace("package", outKtPkg) { _, oldValue, newValue -> warn("The package value `$oldValue` specified in .def file is overridden with explicit $newValue") } def.manifestAddendProperties["interop"] = "true" if (stubIrOutput is StubIrDriver.Result.Metadata) { def.manifestAddendProperties["ir_provider"] = KLIB_INTEROP_IR_PROVIDER_IDENTIFIER } stubIrContext.addManifestProperties(def.manifestAddendProperties) // cinterop command line option overrides def file property val foreignExceptionMode = cinteropArguments.foreignExceptionMode?: def.config.foreignExceptionMode foreignExceptionMode?.let { def.manifestAddendProperties[ForeignExceptionMode.manifestKey] = ForeignExceptionMode.byValue(it).value // may throw IllegalArgumentException } manifestAddend?.parentFile?.mkdirs() manifestAddend?.let { def.manifestAddendProperties.storeProperties(it) } val compilerArgs = stubIrContext.libraryForCStubs.compilerArgs.toTypedArray() val nativeOutputPath: String = when (flavor) { KotlinPlatform.JVM -> { val outOFile = tempFiles.create(libName,".o") val compilerCmd = arrayOf(compiler, *compilerArgs, "-c", outCFile.absolutePath, "-o", outOFile.absolutePath) runCmd(compilerCmd, verbose) val outLib = File(nativeLibsDir, System.mapLibraryName(libName)) val linkerCmd = arrayOf(linker, outOFile.absolutePath, "-shared", "-o", outLib.absolutePath, *linkerOpts) runCmd(linkerCmd, verbose) outOFile.absolutePath } KotlinPlatform.NATIVE -> { val outLib = File(nativeLibsDir, "$libName.bc") val compilerCmd = arrayOf(compiler, *compilerArgs, "-emit-llvm", "-c", outCFile.absolutePath, "-o", outLib.absolutePath) runCmd(compilerCmd, verbose) outLib.absolutePath } } val compiledFiles = compileSources(nativeLibsDir, tool, cinteropArguments) return when (stubIrOutput) { is StubIrDriver.Result.SourceCode -> { val bitcodePaths = compiledFiles.map { listOf("-native-library", it) }.flatten() argsToCompiler(staticLibraries, libraryPaths) + bitcodePaths } is StubIrDriver.Result.Metadata -> { val stdlibDependency = resolver.resolveWithDependencies( emptyList(), noDefaultLibs = true, noEndorsedLibs = true ).getFullList() val nopack = cinteropArguments.nopack val outputPath = cinteropArguments.output.let { val suffix = CompilerOutputKind.LIBRARY.suffix(tool.target) if (nopack) it.removeSuffixIfPresent(suffix) else it.suffixIfNot(suffix) } createInteropLibrary( metadata = stubIrOutput.metadata, nativeBitcodeFiles = compiledFiles + nativeOutputPath, target = tool.target, moduleName = moduleName, outputPath = outputPath, manifest = def.manifestAddendProperties, dependencies = stdlibDependency + imports.requiredLibraries.toList(), nopack = nopack, shortName = cinteropArguments.shortModuleName, staticLibraries = resolveLibraries(staticLibraries, libraryPaths) ) return null } } } private fun compileSources( nativeLibsDir: String, toolConfig: ToolConfig, cinteropArguments: CInteropArguments ): List = cinteropArguments.compileSource.mapIndexed { index, source -> // Mangle file name to avoid collisions. val mangledFileName = "${index}_${File(source).nameWithoutExtension}" val outputFileName = "$nativeLibsDir/${mangledFileName}.bc" val compilerArgs = cinteropArguments.sourceCompileOptions.toTypedArray() val compilerCmd = toolConfig.clang.clangCXX(*compilerArgs, source, "-emit-llvm", "-c", "-o", outputFileName) runCmd(compilerCmd.toTypedArray(), verbose = cinteropArguments.verbose) outputFileName } private fun getLibraryResolver( cinteropArguments: CInteropArguments, target: KonanTarget ): KotlinLibraryResolverImpl { val libraries = cinteropArguments.library val repos = cinteropArguments.repo return defaultResolver( repos, libraries.filter { it.contains(org.jetbrains.kotlin.konan.file.File.separator) }, target, Distribution(KonanHomeProvider.determineKonanHome()) ).libraryResolver() } private fun resolveDependencies( resolver: KotlinLibraryResolverImpl, cinteropArguments: CInteropArguments ): List { val libraries = cinteropArguments.library val noDefaultLibs = cinteropArguments.nodefaultlibs || cinteropArguments.nodefaultlibsDeprecated val noEndorsedLibs = cinteropArguments.noendorsedlibs return resolver.resolveWithDependencies( libraries.toUnresolvedLibraries, noStdLib = false, noDefaultLibs = noDefaultLibs, noEndorsedLibs = noEndorsedLibs ).getFullList(TopologicalLibraryOrder) } internal fun prepareTool(target: String?, flavor: KotlinPlatform): ToolConfig { val tool = ToolConfig(target, flavor) tool.downloadDependencies() System.load(tool.libclang) return tool } internal fun buildNativeLibrary( tool: ToolConfig, def: DefFile, arguments: CInteropArguments, imports: ImportsImpl ): NativeLibrary { val additionalHeaders = (arguments.header).toTypedArray() val additionalCompilerOpts = (arguments.compilerOpts + arguments.compilerOptions + arguments.compilerOption).toTypedArray() val headerFiles = def.config.headers + additionalHeaders val language = selectNativeLanguage(def.config) val compilerOpts: List = mutableListOf().apply { addAll(def.config.compilerOpts) addAll(tool.defaultCompilerOpts) // We compile with -O2 because Clang may insert inline asm in bitcode at -O0. // It is undesirable in case of watchos_arm64 since we target armv7k // for this target instead of arm64_32 because it is not supported in LLVM 8. // // Note that PCH and the *.c file should be compiled with the same optimization level. add("-O2") addAll(additionalCompilerOpts) addAll(getCompilerFlagsForVfsOverlay(arguments.headerFilterPrefix.toTypedArray(), def)) addAll(when (language) { Language.C -> emptyList() Language.OBJECTIVE_C -> { // "Objective-C" within interop means "Objective-C with ARC": listOf("-fobjc-arc") // Using this flag here has two effects: // 1. The headers are parsed with ARC enabled, thus the API is visible correctly. // 2. The generated Objective-C stubs are compiled with ARC enabled, so reference counting // calls are inserted automatically. } }) } val compilation = CompilationImpl( includes = headerFiles, additionalPreambleLines = def.defHeaderLines, compilerArgs = compilerOpts + tool.platformCompilerOpts, language = language ) val headerFilter: NativeLibraryHeaderFilter val includes: List val modules = def.config.modules if (modules.isEmpty()) { val excludeDependentModules = def.config.excludeDependentModules val headerFilterGlobs = def.config.headerFilter val headerInclusionPolicy = HeaderInclusionPolicyImpl(headerFilterGlobs) headerFilter = NativeLibraryHeaderFilter.NameBased(headerInclusionPolicy, excludeDependentModules) includes = headerFiles } else { require(language == Language.OBJECTIVE_C) { "cinterop supports 'modules' only when 'language = Objective-C'" } require(headerFiles.isEmpty()) { "cinterop doesn't support having headers and modules specified at the same time" } require(def.config.headerFilter.isEmpty()) { "cinterop doesn't support 'headerFilter' with 'modules'" } val modulesInfo = getModulesInfo(compilation, modules) headerFilter = NativeLibraryHeaderFilter.Predefined(modulesInfo.ownHeaders) includes = modulesInfo.topLevelHeaders } val excludeSystemLibs = def.config.excludeSystemLibs val headerExclusionPolicy = HeaderExclusionPolicyImpl(imports) return NativeLibrary( includes = includes, additionalPreambleLines = compilation.additionalPreambleLines, compilerArgs = compilation.compilerArgs, headerToIdMapper = HeaderToIdMapper(sysRoot = tool.sysRoot), language = compilation.language, excludeSystemLibs = excludeSystemLibs, headerExclusionPolicy = headerExclusionPolicy, headerFilter = headerFilter ) } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/StubGenerator.kt ================================================ package org.jetbrains.kotlin.native.interop.gen.wasm import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.native.interop.gen.argsToCompiler import org.jetbrains.kotlin.native.interop.gen.wasm.idl.* import org.jetbrains.kotlin.native.interop.gen.jvm.InternalInteropOptions import org.jetbrains.kotlin.native.interop.tool.JSInteropArguments fun kotlinHeader(packageName: String): String { return "package $packageName\n" + "import kotlinx.wasm.jsinterop.*\n" } fun Type.toKotlinType(argName: String? = null): String = when (this) { is idlVoid -> "Unit" is idlInt -> "Int" is idlFloat -> "Float" is idlDouble -> "Double" is idlString -> "String" is idlObject -> "JsValue" is idlFunction -> "KtFunction" is idlInterfaceRef -> name else -> error("Unexpected type") } fun Arg.wasmMapping(): String = when (type) { is idlVoid -> error("An arg can not be idlVoid") is idlInt -> name is idlFloat -> name is idlDouble -> "doubleUpper($name), doubleLower($name)" is idlString -> "stringPointer($name), stringLengthBytes($name)" is idlObject -> TODO("implement me") is idlFunction -> "wrapFunction($name), ArenaManager.currentArena" is idlInterfaceRef -> TODO("Implement me") else -> error("Unexpected type") } fun Type.wasmReturnArg(): String = when (this) { is idlVoid -> "ArenaManager.currentArena" // TODO: optimize. is idlInt -> "ArenaManager.currentArena" is idlFloat -> "ArenaManager.currentArena" is idlDouble -> "ArenaManager.currentArena" is idlString -> "ArenaManager.currentArena" is idlObject -> "ArenaManager.currentArena" is idlFunction -> "ArenaManager.currentArena" is idlInterfaceRef -> "ArenaManager.currentArena" else -> error("Unexpected type") } val Operation.wasmReturnArg: String get() = returnType.wasmReturnArg() val Attribute.wasmReturnArg: String get() = type.wasmReturnArg() fun Arg.wasmArgNames(): List = when (type) { is idlVoid -> error("An arg can not be idlVoid") is idlInt -> listOf(name) is idlFloat -> listOf(name) is idlDouble -> listOf("${name}Upper", "${name}Lower") is idlString -> listOf("${name}Ptr", "${name}Len") is idlObject -> TODO("implement me (idlObject)") is idlFunction -> listOf("${name}Index", "${name}ResultArena") is idlInterfaceRef -> TODO("Implement me (idlInterfaceRef)") else -> error("Unexpected type") } fun Type.wasmReturnMapping(value: String): String = when (this) { is idlVoid -> "" is idlInt -> value is idlFloat -> value is idlDouble -> value is idlString -> "TODO(\"Implement me\")" is idlObject -> "JsValue(ArenaManager.currentArena, $value)" is idlFunction -> "TODO(\"Implement me\")" is idlInterfaceRef -> "$name(ArenaManager.currentArena, $value)" else -> error("Unexpected type") } fun wasmFunctionName(functionName: String, interfaceName: String) = "knjs__${interfaceName}_$functionName" fun wasmSetterName(propertyName: String, interfaceName: String) = "knjs_set__${interfaceName}_$propertyName" fun wasmGetterName(propertyName: String, interfaceName: String) = "knjs_get__${interfaceName}_$propertyName" val Operation.kotlinTypeParameters: String get() { val lambdaRetTypes = args.filter { it.type is idlFunction } .map { "R${it.name}" }. joinToString(", ") return if (lambdaRetTypes == "") "" else "<$lambdaRetTypes>" } val Interface.wasmReceiverArgs get() = if (isGlobal) emptyList() else listOf("this.arena", "this.index") fun Member.wasmReceiverArgs(parent: Interface) = if (isStatic) emptyList() else parent.wasmReceiverArgs fun Type.generateKotlinCall(name: String, wasmArgList: String) = "$name($wasmArgList)" fun Type.generateKotlinCallWithReturn(name: String, wasmArgList: String) = when(this) { is idlVoid -> " ${generateKotlinCall(name, wasmArgList)}\n" is idlDouble -> " ${generateKotlinCall(name, wasmArgList)}\n" + " val wasmRetVal = ReturnSlot_getDouble()\n" else -> " val wasmRetVal = ${generateKotlinCall(name, wasmArgList)}\n" } fun Operation.generateKotlinCallWithReturn(parent_name: String, wasmArgList: String) = returnType.generateKotlinCallWithReturn( wasmFunctionName(name, parent_name), wasmArgList) fun Attribute.generateKotlinGetterCallWithReturn(parent_name: String, wasmArgList: String) = type.generateKotlinCallWithReturn( wasmGetterName(name, parent_name), wasmArgList) fun Operation.generateKotlin(parent: Interface): String { val argList = args.map { "${it.name}: ${it.type.toKotlinType(it.name)}" }.joinToString(", ") val wasmArgList = (wasmReceiverArgs(parent) + args.map(Arg::wasmMapping) + wasmReturnArg).joinToString(", ") // TODO: there can be multiple Rs. return " fun $kotlinTypeParameters $name(" + argList + "): ${returnType.toKotlinType()} {\n" + generateKotlinCallWithReturn(parent.name, wasmArgList) + " return ${returnType.wasmReturnMapping("wasmRetVal")}\n"+ " }\n\n" } fun Attribute.generateKotlinSetter(parent: Interface): String { val kotlinType = type.toKotlinType(name) return " set(value: $kotlinType) {\n" + " ${wasmSetterName(name, parent.name)}(" + (wasmReceiverArgs(parent) + Arg("value", type).wasmMapping()).joinToString(", ") + ")\n" + " }\n\n" } fun Attribute.generateKotlinGetter(parent: Interface): String { val wasmArgList = (wasmReceiverArgs(parent) + wasmReturnArg).joinToString(", ") return " get() {\n" + generateKotlinGetterCallWithReturn(parent.name, wasmArgList) + " return ${type.wasmReturnMapping("wasmRetVal")}\n"+ " }\n\n" } fun Attribute.generateKotlin(parent: Interface): String { val kotlinType = type.toKotlinType(name) val varOrVal = if (readOnly) "val" else "var" return " $varOrVal $name: $kotlinType\n" + generateKotlinGetter(parent) + if (!readOnly) generateKotlinSetter(parent) else "" } val Interface.wasmTypedReceiverArgs get() = if (isGlobal) emptyList() else listOf("arena: Int", "index: Int") fun Member.wasmTypedReceiverArgs(parent: Interface) = if (isStatic) emptyList() else parent.wasmTypedReceiverArgs fun Operation.generateWasmStub(parent: Interface): String { val wasmName = wasmFunctionName(this.name, parent.name) val allArgs = (wasmTypedReceiverArgs(parent) + args.toList().wasmTypedMapping() + wasmTypedReturnMapping).joinToString(", ") return "@SymbolName(\"$wasmName\")\n" + "external public fun $wasmName($allArgs): ${returnType.wasmReturnTypeMapping()}\n\n" } fun Attribute.generateWasmSetterStub(parent: Interface): String { val wasmSetter = wasmSetterName(this.name, parent.name) val allArgs = (wasmTypedReceiverArgs(parent) + Arg("value", this.type).wasmTypedMapping()).joinToString(", ") return "@SymbolName(\"$wasmSetter\")\n" + "external public fun $wasmSetter($allArgs): Unit\n\n" } fun Attribute.generateWasmGetterStub(parent: Interface): String { val wasmGetter = wasmGetterName(this.name, parent.name) val allArgs = (wasmTypedReceiverArgs(parent) + wasmTypedReturnMapping).joinToString(", ") return "@SymbolName(\"$wasmGetter\")\n" + "external public fun $wasmGetter($allArgs): Int\n\n" } fun Attribute.generateWasmStubs(parent: Interface) = generateWasmGetterStub(parent) + if (!readOnly) generateWasmSetterStub(parent) else "" // TODO: consider using virtual methods fun Member.generateKotlin(parent: Interface): String = when (this) { is Operation -> this.generateKotlin(parent) is Attribute -> this.generateKotlin(parent) else -> error("Unexpected member") } // TODO: consider using virtual methods fun Member.generateWasmStub(parent: Interface) = when (this) { is Operation -> this.generateWasmStub(parent) is Attribute -> this.generateWasmStubs(parent) else -> error("Unexpected member") } fun Arg.wasmTypedMapping() = this.wasmArgNames().map { "$it: Int" } .joinToString(", ") // TODO: Optimize for simple types. fun Type.wasmTypedReturnMapping(): String = "resultArena: Int" val Operation.wasmTypedReturnMapping get() = returnType.wasmTypedReturnMapping() val Attribute.wasmTypedReturnMapping get() = type.wasmTypedReturnMapping() fun List.wasmTypedMapping():List = this.map(Arg::wasmTypedMapping) // TODO: more complex return types, such as returning a pair of Ints // will require a more complex approach. fun Type.wasmReturnTypeMapping() = if (this == idlVoid) "Unit" else "Int" fun Interface.generateMemberWasmStubs() = members.map { it.generateWasmStub(this) }.joinToString("") fun Interface.generateKotlinMembers() = members.filterNot { it.isStatic } .map { it.generateKotlin(this) }.joinToString("") fun Interface.generateKotlinCompanion() = " companion object {\n" + members.filter { it.isStatic } .map { it.generateKotlin(this) }.joinToString("") + " }\n" fun Interface.generateKotlinClassHeader() = "open class $name(arena: Int, index: Int): JsValue(arena, index) {\n" + " constructor(jsValue: JsValue): this(jsValue.arena, jsValue.index)\n" fun Interface.generateKotlinClassFooter() = "}\n" fun Interface.generateKotlinClassConverter() = "val JsValue.as$name: $name\n" + " get() {\n" + " return $name(this.arena, this.index)\n"+ " }\n" fun Interface.generateKotlin(): String { fun unlessGlobal(value: () -> String): String { return if (this.isGlobal) "" else value() } return generateMemberWasmStubs() + unlessGlobal { generateKotlinClassHeader() } + generateKotlinMembers() + unlessGlobal { generateKotlinCompanion() + generateKotlinClassFooter() + generateKotlinClassConverter() } } fun generateKotlin(pkg: String, interfaces: List) = kotlinHeader(pkg) + interfaces.map { it.generateKotlin() }.joinToString("\n") + if (pkg == "kotlinx.interop.wasm.dom") // TODO: make it a general solution. "fun setInterval(interval: Int, lambda: KtFunction) = setInterval(lambda, interval)\n" else "" ///////////////////////////////////////////////////////// fun Arg.composeWasmArgs(): String = when (type) { is idlVoid -> error("An arg can not be idlVoid") is idlInt -> "" is idlFloat -> "" is idlDouble -> " var $name = twoIntsToDouble(${name}Upper, ${name}Lower);\n" is idlString -> " var $name = toUTF16String(${name}Ptr, ${name}Len);\n" is idlObject -> TODO("implement me") is idlFunction -> " var $name = konan_dependencies.env.Konan_js_wrapLambda(lambdaResultArena, ${name}Index);\n" is idlInterfaceRef -> TODO("Implement me") else -> error("Unexpected type") } val Interface.receiver get() = if (isGlobal) "" else "kotlinObject(arena, obj)." fun Member.receiver(parent: Interface) = if (isStatic) "${parent.name}." else parent.receiver val Interface.wasmReceiverArgName get() = if (isGlobal) emptyList() else listOf("arena", "obj") fun Member.wasmReceiverArgName(parent: Interface) = if (isStatic) emptyList() else parent.wasmReceiverArgName val Operation.wasmReturnArgName get() = returnType.wasmReturnArgName val Attribute.wasmReturnArgName get() = type.wasmReturnArgName val Type.wasmReturnArgName get() = when (this) { is idlVoid -> emptyList() is idlInt -> emptyList() is idlFloat -> emptyList() is idlDouble -> emptyList() is idlString -> listOf("resultArena") is idlObject -> listOf("resultArena") is idlInterfaceRef -> listOf("resultArena") else -> error("Unexpected type: $this") } val Type.wasmReturnExpression get() = when(this) { is idlVoid -> "" is idlInt -> "result" is idlFloat -> "result" // TODO: can we really pass floats as is? is idlDouble -> "doubleToReturnSlot(result)" is idlString -> "toArena(resultArena, result)" is idlObject -> "toArena(resultArena, result)" is idlInterfaceRef -> "toArena(resultArena, result)" else -> error("Unexpected type: $this") } fun Operation.generateJs(parent: Interface): String { val allArgs = wasmReceiverArgName(parent) + args.map { it.wasmArgNames() }.flatten() + wasmReturnArgName val wasmMapping = allArgs.joinToString(", ") val argList = args.map { it.name }. joinToString(", ") val composedArgsList = args.map { it.composeWasmArgs() }. joinToString("") return "\n ${wasmFunctionName(this.name, parent.name)}: function($wasmMapping) {\n" + composedArgsList + " var result = ${receiver(parent)}$name($argList);\n" + " return ${returnType.wasmReturnExpression};\n" + " }" } fun Attribute.generateJsSetter(parent: Interface): String { val valueArg = Arg("value", type) val allArgs = wasmReceiverArgName(parent) + valueArg.wasmArgNames() val wasmMapping = allArgs.joinToString(", ") return "\n ${wasmSetterName(name, parent.name)}: function($wasmMapping) {\n" + valueArg.composeWasmArgs() + " ${receiver(parent)}$name = value;\n" + " }" } fun Attribute.generateJsGetter(parent: Interface): String { val allArgs = wasmReceiverArgName(parent) + wasmReturnArgName val wasmMapping = allArgs.joinToString(", ") return "\n ${wasmGetterName(name, parent.name)}: function($wasmMapping) {\n" + " var result = ${receiver(parent)}$name;\n" + " return ${type.wasmReturnExpression};\n" + " }" } fun Attribute.generateJs(parent: Interface) = generateJsGetter(parent) + if (!readOnly) ",\n${generateJsSetter(parent)}" else "" fun Member.generateJs(parent: Interface): String = when (this) { is Operation -> this.generateJs(parent) is Attribute -> this.generateJs(parent) else -> error("Unexpected member") } fun generateJs(interfaces: List): String = "konan.libraries.push ({\n" + interfaces.map { interf -> interf.members.map { member -> member.generateJs(interf) } }.flatten() .joinToString(",\n") + "\n})\n" const val idlMathPackage = "kotlinx.interop.wasm.math" const val idlDomPackage = "kotlinx.interop.wasm.dom" fun processIdlLib(args: Array, additionalArgs: InternalInteropOptions): Array { val jsInteropArguments = JSInteropArguments() jsInteropArguments.argParser.parse(args) // TODO: Refactor me. val ktGenRoot = File(additionalArgs.generated).mkdirs() val nativeLibsDir = File(additionalArgs.natives).mkdirs() val idl = when (jsInteropArguments.pkg) { idlMathPackage -> idlMath idlDomPackage -> idlDom else -> throw IllegalArgumentException("Please choose either $idlMathPackage or $idlDomPackage for -pkg argument") } File(ktGenRoot, "kotlin_stubs.kt").writeText(generateKotlin(jsInteropArguments.pkg!!, idl)) File(nativeLibsDir, "js_stubs.js").writeText(generateJs(idl)) File((additionalArgs.manifest)!!).writeText("") // The manifest is currently unused for wasm. return argsToCompiler(jsInteropArguments.staticLibrary.toTypedArray(), jsInteropArguments.libraryPath.toTypedArray()) } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/dom.kt ================================================ package org.jetbrains.kotlin.native.interop.gen.wasm.idl // This shall be an output of Web IDL parser. val idlDom = listOf( Interface("Context", Attribute("lineWidth", idlInt), Attribute("fillStyle", idlString), Attribute("strokeStyle", idlString), Operation("lineTo", idlVoid, Arg("x", idlInt), Arg("y", idlInt)), Operation("moveTo", idlVoid, Arg("x", idlInt), Arg("y", idlInt)), Operation("beginPath", idlVoid), Operation("stroke", idlVoid), Operation("fillRect", idlVoid, Arg("x", idlInt), Arg("y", idlInt), Arg("width", idlInt), Arg("height", idlInt)), Operation("fillText", idlVoid, Arg("test", idlString), Arg("x", idlInt), Arg("y", idlInt), Arg("maxWidth", idlInt)), Operation("fill", idlVoid), Operation("closePath", idlVoid) ), Interface("DOMRect", Attribute("left", idlInt), Attribute("right", idlInt), Attribute("top", idlInt), Attribute("bottom", idlInt) ), Interface("Canvas", Operation("getContext", idlInterfaceRef("Context"), Arg("context", idlString)), Operation("getBoundingClientRect", idlInterfaceRef("DOMRect")) ), Interface("Document", Operation("getElementById", idlObject, Arg("id", idlString)) ), Interface("MouseEvent", Attribute("clientX", idlInt, readOnly = true), Attribute("clientY", idlInt, readOnly = true) ), Interface("Response", Operation("json", idlObject) ), Interface("Promise", Operation("then", idlInterfaceRef("Promise"), Arg("lambda", idlFunction)) ), Interface("__Global", Attribute("document", idlInterfaceRef("Document"), readOnly = true), Operation("fetch", idlInterfaceRef("Promise"), Arg("url", idlString)), Operation("setInterval", idlVoid, Arg("lambda", idlFunction), Arg("interval", idlInt)) ) ) ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idl.kt ================================================ package org.jetbrains.kotlin.native.interop.gen.wasm.idl // This is (as of now) a poor man's IDL representation. interface Type interface Member { val isStatic: Boolean get() = false } object idlVoid: Type object idlInt: Type object idlFloat: Type object idlDouble: Type object idlString: Type object idlObject: Type object idlFunction: Type data class Attribute(val name: String, val type: Type, val readOnly: Boolean = false, override val isStatic: Boolean = false): Member data class Arg(val name: String, val type: Type) class Operation(val name: String, val returnType: Type, override val isStatic: Boolean = false, vararg val args: Arg): Member { constructor(name: String, returnType: Type, vararg args: Arg) : this(name, returnType, false, *args) } data class idlInterfaceRef(val name: String): Type class Interface(val name: String, vararg val members: Member) { val isGlobal = (name == "__Global") } ================================================ FILE: Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idlMath.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.native.interop.gen.wasm.idl // There are no WebIDL descriptions of Math, // so in any case this one will be a part of the project. // Although, may be in the form of our own WebIDL source. val idlMath = listOf( Interface("Math", Attribute("E", idlDouble, readOnly = true, isStatic = true), Attribute("LN2", idlDouble, readOnly = true, isStatic = true), Attribute("LN10", idlDouble, readOnly = true, isStatic = true), Attribute("LOG2E", idlDouble, readOnly = true, isStatic = true), Attribute("LOG10E", idlDouble, readOnly = true, isStatic = true), Attribute("PI", idlDouble, readOnly = true, isStatic = true), Attribute("SQRT1_2", idlDouble, readOnly = true, isStatic = true), Attribute("SQRT2", idlDouble, readOnly = true, isStatic = true), Operation("abs", idlDouble, true, Arg("x", idlDouble)), Operation("acos", idlDouble, true, Arg("x", idlDouble)), Operation("acosh", idlDouble, true, Arg("x", idlDouble)), Operation("asin", idlDouble, true, Arg("x", idlDouble)), Operation("asinh", idlDouble, true, Arg("x", idlDouble)), Operation("atan", idlDouble, true, Arg("x", idlDouble)), Operation("atanh", idlDouble, true, Arg("x", idlDouble)), Operation("atan2", idlDouble, true, Arg("y", idlDouble), Arg("x", idlDouble)), Operation("cbrt", idlDouble, true, Arg("x", idlDouble)), Operation("ceil", idlDouble, true, Arg("x", idlDouble)), Operation("clz32", idlDouble, true, Arg("x", idlDouble)), Operation("cos", idlDouble, true, Arg("x", idlDouble)), Operation("cosh", idlDouble, true, Arg("x", idlDouble)), Operation("exp", idlDouble, true, Arg("x", idlDouble)), Operation("expm1", idlDouble, true, Arg("x", idlDouble)), Operation("floor", idlDouble, true, Arg("x", idlDouble)), Operation("fround", idlDouble, true, Arg("x", idlDouble)), //Operation("imul(x, y), Operation("log", idlDouble, true, Arg("x", idlDouble)), Operation("log1p", idlDouble, true, Arg("x", idlDouble)), Operation("log10", idlDouble, true, Arg("x", idlDouble)), Operation("log2", idlDouble, true, Arg("x", idlDouble)), Operation("pow", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), Operation("random", idlDouble, true), Operation("round", idlDouble, true, Arg("x", idlDouble)), Operation("sign", idlDouble, true, Arg("x", idlDouble)), Operation("sin", idlDouble, true, Arg("x", idlDouble)), Operation("sinh", idlDouble, true, Arg("x", idlDouble)), Operation("sqrt", idlDouble, true, Arg("x", idlDouble)), Operation("tan", idlDouble, true, Arg("x", idlDouble)), Operation("tanh", idlDouble, true, Arg("x", idlDouble)), Operation("trunc", idlDouble, true, Arg("x", idlDouble)), // Actually these functions have vararg parameter. // But their kotlin analogs have only 2 parameters so we don't need to support varargs here. Operation("hypot", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), Operation("max", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), Operation("min", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)) ) ) ================================================ FILE: Interop/StubGenerator/src/test/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrToMetadataTests.kt ================================================ package org.jetbrains.kotlin.native.interop.gen import kotlinx.metadata.KmAnnotationArgument import kotlinx.metadata.KmClassifier import kotlinx.metadata.KmModuleFragment import kotlinx.metadata.klib.compileTimeValue import kotlinx.metadata.klib.uniqId import org.jetbrains.kotlin.native.interop.indexer.FunctionDecl import org.jetbrains.kotlin.native.interop.indexer.IntegerConstantDef import org.jetbrains.kotlin.native.interop.indexer.IntegerType import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue class StubIrToMetadataTests { companion object { val intStubType = ClassifierStubType(Classifier.topLevel("kotlin", "Int")) val intType = IntegerType(4, true, "int") } private fun createTrivialFunction(name: String): FunctionStub { val cDeclaration = FunctionDecl(name, emptyList(), intType, "", false, false) val origin = StubOrigin.Function(cDeclaration) return FunctionStub( name = cDeclaration.name, returnType = intStubType, parameters = listOf(), origin = origin, annotations = emptyList(), external = true, receiver = null, modality = MemberStubModality.FINAL ) } private fun createTrivialIntegerConstantProperty(name: String, value: Long): PropertyStub { val origin = StubOrigin.Constant(IntegerConstantDef(name, intType, value)) return PropertyStub( name = name, type = intStubType, kind = PropertyStub.Kind.Constant(IntegralConstantStub(value, intType.size, true)), origin = origin ) } private fun createMetadata( fqName: String, functions: List = emptyList(), properties: List = emptyList() ) = SimpleStubContainer(functions = functions, properties = properties) .let { ModuleMetadataEmitter(fqName, it).emit() } .also(this::checkUniqIdPresence) private fun checkUniqIdPresence(metadata: KmModuleFragment) { metadata.classes.forEach { assertNotNull(it.uniqId) } metadata.pkg?.let { pkg -> pkg.functions.forEach { assertNotNull(it.uniqId) } pkg.properties.forEach { assertNotNull(it.uniqId) } pkg.typeAliases.forEach { assertNotNull(it.uniqId) } } } @Test fun `single simple function`() { val packageName = "single_function" val function = createTrivialFunction("hello") val metadata = createMetadata(packageName, functions = listOf(function)) with (metadata) { assertEquals(packageName, packageName) assertTrue(classes.isEmpty()) assertNotNull(pkg) assertTrue(pkg!!.functions.size == 1) val kmFunction = pkg!!.functions[0] assertEquals(kmFunction.name, function.name) assertEquals(0, kmFunction.valueParameters.size) val returnTypeClassifier = kmFunction.returnType.classifier assertTrue(returnTypeClassifier is KmClassifier.Class) assertEquals("kotlin/Int", returnTypeClassifier.name) } } @Test fun `single constant`() { val property = createTrivialIntegerConstantProperty("meaning", 42) val metadata = createMetadata("single_property", properties = listOf(property)) with (metadata) { assertNotNull(pkg) assertTrue(pkg!!.properties.size == 1) val kmProperty = pkg!!.properties[0] assertEquals(kmProperty.name, property.name) val compileTimeValue = kmProperty.compileTimeValue assertNotNull(compileTimeValue) assertTrue(compileTimeValue is KmAnnotationArgument.IntValue) assertEquals(42, compileTimeValue.value) } } } ================================================ FILE: LIBRARIES.md ================================================ # Kotlin/Native libraries The content of this page is moved to https://kotlinlang.org/docs/native-libraries.html ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2000-2020 JetBrains s.r.o. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: MULTIPLATFORM.md ================================================ Please refer to the tutorial at https://kotlinlang.org/docs/reference/multiplatform.html for documentation on how to create multiplatform project. ================================================ FILE: OBJC_INTEROP.md ================================================ # _Kotlin/Native_ interoperability with Swift/Objective-C The content of this page is moved to https://kotlinlang.org/docs/native-objc-interop.html ================================================ FILE: PLATFORM_LIBS.md ================================================ # Platform libraries The content of this page is moved to https://kotlinlang.org/docs/native-platform-libs.html ================================================ FILE: README.md ================================================ [![official project](http://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) # Kotlin/Native # The development of Kotlin/Native was moved to https://github.com/JetBrains/kotlin. Because of that, this repository was archived. Instead of creating new issues in this repository or commenting the existing ones, please use other ways to communicate: https://github.com/JetBrains/kotlin-native/issues/4079 ================================================ FILE: RELEASE_NOTES.md ================================================ The content of this page is moved to https://github.com/JetBrains/kotlin/blob/master/kotlin-native/RELEASE_NOTES.md ================================================ FILE: _nav_reference.yml ================================================ - md: CONCURRENCY.md url: concurrency.html title: "Concurrency" - md: IMMUTABILITY.md url: immutability.html title: "Immutability" - md: LIBRARIES.md url: libraries.html title: "Kotlin Libraries" - md: PLATFORM_LIBS.md url: platform_libs.html title: "Platform Libraries" - md: INTEROP.md url: c_interop.html title: "C Interop" - md: OBJC_INTEROP.md url: objc_interop.html title: "Objective-C and Swift Interop" - md: IOS_SYMBOLICATION.md url: ios_symbolication.html title: "Symbolicating iOS crash reports" - md: COCOAPODS.md url: cocoapods.html title: "CocoaPods Integration" - md: GRADLE_PLUGIN.md url: gradle_plugin.html title: "Gradle Plugin" - md: DEBUGGING.md url: debugging.html title: "Debugging" - md: FAQ.md url: faq.html title: "FAQ" ================================================ FILE: backend.native/build.gradle ================================================ import org.jetbrains.kotlin.CopyCommonSources import org.jetbrains.kotlin.konan.target.HostManager /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" apply plugin: 'project-report' dependencies { classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.8" } } String protobufVersion = '2.6.1' apply plugin: "com.google.protobuf" apply plugin: 'java' apply plugin: 'kotlin' apply plugin: org.jetbrains.kotlin.NativeInteropPlugin apply plugin: "maven-publish" // (gets applied to this project and all its subprojects) allprojects { repositories { maven { url buildKotlinCompilerRepo } } } sourceSets { compiler { proto.srcDir 'compiler/ir/backend.native/src/' java { srcDir 'compiler/ir/backend.native/src/' srcDir 'build/renamed/source/proto/compiler/java' } kotlin { srcDir 'compiler/ir/backend.native/src/' } resources.srcDir 'compiler/ir/backend.native/resources/' } cli_bc { java.srcDir 'cli.bc/src' kotlin.srcDir 'cli.bc/src' } bc_frontend { java.srcDir 'bc.frontend/src' kotlin.srcDir 'bc.frontend/src' } } compileCompilerKotlin { dependsOn('renamePackage') // The protobuf plugin specifies this dependency for java by itself, // but not for Kotlin. dependsOn('generateCompilerProto') kotlinOptions.jvmTarget = "1.8" kotlinOptions.allWarningsAsErrors=true kotlinOptions.freeCompilerArgs += ['-Xopt-in=kotlin.RequiresOptIn', '-Xopt-in=org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI', '-Xskip-prerelease-check'] } compileCli_bcKotlin { kotlinOptions.freeCompilerArgs += ['-Xskip-prerelease-check'] } compileCompilerJava { dependsOn('renamePackage') } task copyGenerated(type: Copy) { dependsOn('generateCompilerProto') from 'build/generated/source/proto/compiler/java' into 'build/renamed/source/proto/compiler/java' filter { line -> line.replaceAll("com.google.protobuf", "org.jetbrains.kotlin.protobuf") } outputs.dir('build/renamed') } task deleteGenerated(type: Delete) { dependsOn('copyGenerated') delete 'build/generated/source/proto/compiler/java' } task renamePackage { dependsOn('copyGenerated', 'deleteGenerated') } kotlinNativeInterop { llvm { dependsOn ":llvmDebugInfoC:debugInfoStaticLibrary" dependsOn ":llvmCoverageMappingC:coverageMappingStaticLibrary" defFile 'llvm.def' if (!project.parent.convention.plugins.platformInfo.isWindows()) compilerOpts "-fPIC" compilerOpts "-I$llvmDir/include", "-I${project(':llvmDebugInfoC').projectDir}/src/main/include", "-I${project(':llvmCoverageMappingC').projectDir}/src/main/include" linkerOpts "-L$llvmDir/lib", "-L${project(':llvmDebugInfoC').buildDir}/libs/debugInfo/static", "-L${project(':llvmCoverageMappingC').buildDir}/libs/coverageMapping/static" } hash { // TODO: copy-pasted from ':common:compileHash' if (!project.parent.convention.plugins.platformInfo.isWindows()) { compilerOpts '-fPIC' linkerOpts '-fPIC' } linker 'clang++' linkOutputs ":common:${hostName}Hash" headers fileTree('../common/src/hash/headers') { include '**/*.h' include '**/*.hpp' } pkg 'org.jetbrains.kotlin.backend.konan.hash' } files { if (!project.parent.convention.plugins.platformInfo.isWindows()) { compilerOpts '-fPIC' linkerOpts '-fPIC' } linker 'clang++' linkOutputs ":common:${hostName}Files" headers fileTree('../common/src/files/headers') { include '**/*.h' include '**/*.hpp' } pkg 'org.jetbrains.kotlin.backend.konan.files' } } configurations { kotlin_compiler_jar kotlin_stdlib_jar kotlin_reflect_jar kotlin_script_runtime_jar trove4j_jar kotlinCommonSources cli_bcRuntime { extendsFrom compilerRuntime extendsFrom kotlin_script_runtime_jar } cli_bc { extendsFrom cli_bcRuntime } } dependencies { trove4j_jar "org.jetbrains.intellij.deps:trove4j:1.0.20181211@jar" kotlin_compiler_jar "$kotlinCompilerModule@jar" kotlin_stdlib_jar "$kotlinStdLibModule@jar" kotlin_reflect_jar "$kotlinReflectModule@jar" kotlin_script_runtime_jar "$kotlinScriptRuntimeModule@jar" [kotlinCommonStdlibModule, kotlinTestCommonModule, kotlinTestAnnotationsCommonModule].each { kotlinCommonSources(it) { transitive = false } } compilerCompile project(":utilities:basic-utils") compilerCompile "com.google.protobuf:protobuf-java:${protobufVersion}" compilerCompile kotlinCompilerModule compilerCompile kotlinNativeInterop['llvm'].configuration compilerCompile kotlinNativeInterop['hash'].configuration compilerCompile kotlinNativeInterop['files'].configuration compilerCompile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" cli_bcCompile kotlinCompilerModule cli_bcCompile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" cli_bcCompile sourceSets.compiler.output bc_frontendCompile kotlinCompilerModule cli_bc sourceSets.cli_bc.output } classes.dependsOn 'compilerClasses', 'cli_bcClasses', 'bc_frontendClasses' // These are just a couple of aliases task stdlib(dependsOn: "${hostName}Stdlib") def commonSrc = file('build/stdlib') task unzipStdlibSources(type: CopyCommonSources) { outputDir commonSrc sourcePaths configurations.kotlinCommonSources } final List stdLibSrc = [ project(':Interop:Runtime').file('src/main/kotlin'), project(':Interop:Runtime').file('src/native/kotlin'), project(':Interop:JsRuntime').file('src/main/kotlin'), project(':runtime').file('src/main/kotlin') ] // These files are built before the 'dist' is complete, // so we provide a custom value for --runtime targetList.each { target -> def konanJvmArgs = [*HostManager.regularJvmArgs] def defaultArgs = ['-nopack', '-nostdlib', '-no-default-libs', '-no-endorsed-libs', //Uncomment this '-Werror' when common stdlib will be ready ] if (target != "wasm32") defaultArgs += '-g' def konanArgs = [*defaultArgs, '-target', target, "-Xruntime=${project(':runtime').file('build/bitcode/main/' + target + '/runtime.bc')}", *project.globalBuildArgs] task("${target}Stdlib", type: JavaExec) { main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' // This task depends on distCompiler, so the compiler jar is already in the dist directory. classpath = fileTree("${rootProject.projectDir}/dist/konan/lib") { include "*.jar" } jvmArgs = konanJvmArgs args = [*konanArgs, '-output', project(':runtime').file("build/${target}Stdlib"), '-produce', 'library', '-module-name', 'stdlib', '-Xmulti-platform', '-Xopt-in=kotlin.RequiresOptIn', '-Xinline-classes', '-Xopt-in=kotlin.contracts.ExperimentalContracts', '-Xopt-in=kotlin.ExperimentalMultiplatform', '-Xallow-result-return-type', commonSrc.absolutePath, "-Xcommon-sources=${commonSrc.absolutePath}", *stdLibSrc] stdLibSrc.forEach { inputs.dir(it) } inputs.dir(commonSrc) outputs.dir(project(':runtime').file("build/${target}Stdlib")) dependsOn 'unzipStdlibSources' dependsOn ":runtime:${target}Runtime" dependsOn ":distCompiler" } } task run { doLast { logger.quiet("Run the outer project 'demo' target to compile the test source.") } } jar { from sourceSets.cli_bc.output, sourceSets.compiler.output, sourceSets.hashInteropStubs.output, sourceSets.filesInteropStubs.output, sourceSets.llvmInteropStubs.output dependsOn ':runtime:hostRuntime', 'external_jars' } def externalJars = ['compiler', 'stdlib', 'reflect', 'script_runtime'] task trove4jCopy(type: Copy) { from configurations.getByName("trove4j_jar") { include "trove4j*.jar" rename "trove4j(.*).jar", "trove4j.jar" into 'build/external_jars' } } externalJars.each { arg -> def jar = arg.replace('_', '-') // :( task("${arg}Copy", type: Copy) { from configurations.getByName("kotlin_${arg}_jar") { include "kotlin-${jar}*.jar" rename "kotlin-${jar}(.*).jar", "kotlin-${jar}.jar" into 'build/external_jars' } } } task external_jars(type: Copy) { dependsOn externalJars.collect { "${it}Copy" } dependsOn trove4jCopy from configurations.compilerCompile { include "protobuf-java-${protobufVersion}.jar" into 'build/external_jars' } } protobuf { protoc { artifact = "com.google.protobuf:protoc:${protobufVersion}" } } task debugCompiler(type: JavaExec) { dependsOn ':dist' main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' classpath = project.fileTree("${distDir.canonicalPath}/konan/lib/") { include '*.jar' } jvmArgs "-Dorg.jetbrains.kotlin.native.home=${distDir.canonicalPath}" enableAssertions = true args = findProperty("konan.debug.args").toString().tokenize() ?: [] } publishing { repositories { maven { url = "$buildDir/repo" } } publications { maven(MavenPublication) { groupId = 'org.jetbrains.kotlin' artifactId = 'backend.native' version = konanVersionFull from components.java } } } ================================================ FILE: backend.native/compiler/ir/backend.native/resources/META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition ================================================ org.jetbrains.kotlin.backend.konan.ObjCOverridabilityCondition ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/AbstractValueUsageTransformer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.common import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid /** * Transforms expressions depending on the context they are used in. * * The transformations are defined with `IrExpression.use*` methods in this class, * the most common are [useAs], [useAsStatement], [useInTypeOperator]. * * TODO: the implementation is originally based on [org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts] * and should probably be used as its base. * * TODO: consider making this visitor non-recursive to make it more general. */ internal abstract class AbstractValueUsageTransformer( val builtIns: KotlinBuiltIns, val symbols: KonanSymbols, val irBuiltIns: IrBuiltIns ): IrElementTransformerVoid() { protected open fun IrExpression.useAs(type: IrType): IrExpression = this protected open fun IrExpression.useAsStatement(): IrExpression = this protected open fun IrExpression.useInTypeOperator(operator: IrTypeOperator, typeOperand: IrType): IrExpression = this protected open fun IrExpression.useAsValue(value: IrValueDeclaration): IrExpression = this.useAs(value.type) protected open fun IrExpression.useAsArgument(parameter: IrValueParameter): IrExpression = this.useAsValue(parameter) protected open fun IrExpression.useAsDispatchReceiver(expression: IrFunctionAccessExpression): IrExpression = this.useAsArgument(expression.symbol.owner.dispatchReceiverParameter!!) protected open fun IrExpression.useAsExtensionReceiver(expression: IrFunctionAccessExpression): IrExpression = this.useAsArgument(expression.symbol.owner.extensionReceiverParameter!!) protected open fun IrExpression.useAsValueArgument(expression: IrFunctionAccessExpression, parameter: IrValueParameter ): IrExpression = this.useAsArgument(parameter) private fun IrExpression.useForVariable(variable: IrVariable): IrExpression = this.useAsValue(variable) private fun IrExpression.useForValue(value: IrValueDeclaration) = this.useAsValue(value) private fun IrExpression.useForField(field: IrField): IrExpression = this.useAs(field.type) protected open fun IrExpression.useAsReturnValue(returnTarget: IrReturnTargetSymbol): IrExpression = when (returnTarget) { is IrSimpleFunctionSymbol -> this.useAs(returnTarget.owner.returnType) is IrConstructorSymbol -> this.useAs(irBuiltIns.unitType) is IrReturnableBlockSymbol -> this.useAs(returnTarget.owner.type) else -> error(returnTarget) } protected open fun IrExpression.useAsResult(enclosing: IrExpression): IrExpression = this.useAs(enclosing.type) override fun visitPropertyReference(expression: IrPropertyReference): IrExpression { TODO() } override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrExpression { TODO() } override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { TODO() } override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression { expression.transformChildrenVoid(this) with(expression) { dispatchReceiver = dispatchReceiver?.useAsDispatchReceiver(expression) extensionReceiver = extensionReceiver?.useAsExtensionReceiver(expression) for (index in symbol.owner.valueParameters.indices) { val argument = getValueArgument(index) ?: continue val parameter = symbol.owner.valueParameters[index] putValueArgument(index, argument.useAsValueArgument(expression, parameter)) } } return expression } override fun visitBlockBody(body: IrBlockBody): IrBody { body.transformChildrenVoid(this) body.statements.forEachIndexed { i, irStatement -> if (irStatement is IrExpression) { body.statements[i] = irStatement.useAsStatement() } } return body } override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { expression.transformChildrenVoid(this) if (expression.statements.isEmpty()) { return expression } val lastIndex = expression.statements.lastIndex expression.statements.forEachIndexed { i, irStatement -> if (irStatement is IrExpression) { expression.statements[i] = if (i == lastIndex) irStatement.useAsResult(expression) else irStatement.useAsStatement() } } return expression } override fun visitReturn(expression: IrReturn): IrExpression { expression.transformChildrenVoid(this) expression.value = expression.value.useAsReturnValue(expression.returnTargetSymbol) return expression } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid(this) expression.value = expression.value.useForValue(expression.symbol.owner) return expression } override fun visitSetField(expression: IrSetField): IrExpression { expression.transformChildrenVoid(this) expression.value = expression.value.useForField(expression.symbol.owner) return expression } override fun visitField(declaration: IrField): IrStatement { declaration.transformChildrenVoid(this) declaration.initializer?.let { it.expression = it.expression.useForField(declaration) } return declaration } override fun visitVariable(declaration: IrVariable): IrVariable { declaration.transformChildrenVoid(this) declaration.initializer = declaration.initializer?.useForVariable(declaration) return declaration } override fun visitWhen(expression: IrWhen): IrExpression { expression.transformChildrenVoid(this) for (irBranch in expression.branches) { irBranch.condition = irBranch.condition.useAs(irBuiltIns.booleanType) irBranch.result = irBranch.result.useAsResult(expression) } return expression } override fun visitLoop(loop: IrLoop): IrExpression { loop.transformChildrenVoid(this) loop.condition = loop.condition.useAs(irBuiltIns.booleanType) loop.body = loop.body?.useAsStatement() return loop } override fun visitThrow(expression: IrThrow): IrExpression { expression.transformChildrenVoid(this) expression.value = expression.value.useAs(symbols.throwable.owner.defaultType) return expression } override fun visitTry(aTry: IrTry): IrExpression { aTry.transformChildrenVoid(this) aTry.tryResult = aTry.tryResult.useAsResult(aTry) for (aCatch in aTry.catches) { aCatch.result = aCatch.result.useAsResult(aTry) } aTry.finallyExpression = aTry.finallyExpression?.useAsStatement() return aTry } override fun visitVararg(expression: IrVararg): IrExpression { expression.transformChildrenVoid(this) expression.elements.forEachIndexed { i, element -> when (element) { is IrSpreadElement -> element.expression = element.expression.useAs(expression.type) is IrExpression -> expression.putElement(i, element.useAs(expression.varargElementType)) } } return expression } override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { expression.transformChildrenVoid(this) expression.argument = expression.argument.useInTypeOperator(expression.operator, expression.typeOperand) return expression } override fun visitFunction(declaration: IrFunction): IrStatement { declaration.transformChildrenVoid(this) declaration.valueParameters.forEach { parameter -> val defaultValue = parameter.defaultValue if (defaultValue is IrExpressionBody) { defaultValue.expression = defaultValue.expression.useAsArgument(parameter) } } declaration.body?.let { if (it is IrExpressionBody) { it.expression = it.expression.useAsReturnValue(declaration.symbol) } } return declaration } // TODO: IrStringConcatenation, IrEnumEntry? } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BinaryType.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan sealed class BinaryType { class Primitive(val type: PrimitiveBinaryType) : BinaryType() class Reference(val types: Sequence, val nullable: Boolean) : BinaryType() } fun BinaryType<*>.primitiveBinaryTypeOrNull(): PrimitiveBinaryType? = when (this) { is BinaryType.Primitive -> this.type is BinaryType.Reference -> null } enum class PrimitiveBinaryType { BOOLEAN, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, POINTER, VECTOR128 } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeCompiler.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.target.* typealias BitcodeFile = String typealias ObjectFile = String typealias ExecutableFile = String internal class BitcodeCompiler(val context: Context) { private val platform = context.config.platform private val optimize = context.shouldOptimize() private val debug = context.config.debug private val overrideClangOptions = context.configuration.getList(KonanConfigKeys.OVERRIDE_CLANG_OPTIONS) private fun MutableList.addNonEmpty(elements: List) { addAll(elements.filter { it.isNotEmpty() }) } private fun runTool(vararg command: String) = Command(*command) .logWith(context::log) .execute() private fun temporary(name: String, suffix: String): String = context.config.tempFiles.create(name, suffix).absolutePath private fun targetTool(tool: String, vararg arg: String) { val absoluteToolName = if (platform.configurables is AppleConfigurables) { "${platform.absoluteTargetToolchain}/usr/bin/$tool" } else { "${platform.absoluteTargetToolchain}/bin/$tool" } runTool(absoluteToolName, *arg) } private fun hostLlvmTool(tool: String, vararg arg: String) { val absoluteToolName = "${platform.absoluteLlvmHome}/bin/$tool" runTool(absoluteToolName, *arg) } private fun clang(configurables: ClangFlags, file: BitcodeFile): ObjectFile { val objectFile = temporary("result", ".o") val profilingFlags = llvmProfilingFlags().map { listOf("-mllvm", it) }.flatten() // TODO: fix with LLVM update. val targetTriple = when (context.config.target) { // LLVM we use does not have support for arm64_32. KonanTarget.WATCHOS_ARM64 -> { require(configurables is AppleConfigurables) "arm64_32-apple-watchos${configurables.osVersionMin}" } // Runtime generates bitcode for mythical macos 10.16 because of old Clang. // Let's fix it. KonanTarget.MACOS_ARM64 -> { require(configurables is AppleConfigurables) "arm64-apple-macos${configurables.osVersionMin}" } else -> context.llvm.targetTriple } val flags = overrideClangOptions.takeIf(List::isNotEmpty) ?: mutableListOf().apply { addNonEmpty(configurables.clangFlags) addNonEmpty(listOf("-triple", targetTriple)) if (configurables is ZephyrConfigurables) { addNonEmpty(configurables.constructClangCC1Args()) } addNonEmpty(when { optimize -> configurables.clangOptFlags debug -> configurables.clangDebugFlags else -> configurables.clangNooptFlags }) addNonEmpty(BitcodeEmbedding.getClangOptions(context.config)) addNonEmpty(configurables.currentRelocationMode(context).translateToClangCc1Flag()) addNonEmpty(profilingFlags) } if (configurables is AppleConfigurables) { targetTool("clang++", *flags.toTypedArray(), file, "-o", objectFile) } else { hostLlvmTool("clang++", *flags.toTypedArray(), file, "-o", objectFile) } return objectFile } private fun RelocationModeFlags.Mode.translateToClangCc1Flag() = when (this) { RelocationModeFlags.Mode.PIC -> listOf("-mrelocation-model", "pic") RelocationModeFlags.Mode.STATIC -> listOf("-mrelocation-model", "static") RelocationModeFlags.Mode.DEFAULT -> emptyList() } private fun llvmProfilingFlags(): List { val flags = mutableListOf() if (context.shouldProfilePhases()) { flags += "-time-passes" } if (context.inVerbosePhase) { flags += "-debug-pass=Structure" } return flags } fun makeObjectFiles(bitcodeFile: BitcodeFile): List = listOf(when (val configurables = platform.configurables) { is ClangFlags -> clang(configurables, bitcodeFile) else -> error("Unsupported configurables kind: ${configurables::class.simpleName}!") }) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BitcodeEmbedding.kt ================================================ package org.jetbrains.kotlin.backend.konan object BitcodeEmbedding { enum class Mode { NONE, MARKER, FULL } internal fun getLinkerOptions(config: KonanConfig): List = when (config.bitcodeEmbeddingMode) { Mode.NONE -> emptyList() Mode.MARKER -> listOf("-bitcode_bundle", "-bitcode_process_mode", "marker") Mode.FULL -> listOf("-bitcode_bundle") } internal fun getClangOptions(config: KonanConfig): List = when (config.bitcodeEmbeddingMode) { Mode.NONE -> listOf("-fembed-bitcode=off") Mode.MARKER -> listOf("-fembed-bitcode=marker") Mode.FULL -> listOf("-fembed-bitcode=all") } private val KonanConfig.bitcodeEmbeddingMode get() = configuration.get(KonanConfigKeys.BITCODE_EMBEDDING_MODE)!! } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import llvm.* import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.name.Name internal fun KonanSymbols.getTypeConversion(actualType: IrType, expectedType: IrType): IrSimpleFunctionSymbol? = getTypeConversionImpl(actualType.getInlinedClassNative(), expectedType.getInlinedClassNative()) private fun KonanSymbols.getTypeConversionImpl( actualInlinedClass: IrClass?, expectedInlinedClass: IrClass? ): IrSimpleFunctionSymbol? { if (actualInlinedClass == expectedInlinedClass) return null return when { actualInlinedClass == null && expectedInlinedClass == null -> null actualInlinedClass != null && expectedInlinedClass == null -> context.getBoxFunction(actualInlinedClass) actualInlinedClass == null && expectedInlinedClass != null -> context.getUnboxFunction(expectedInlinedClass) else -> error("actual type is ${actualInlinedClass?.fqNameForIrSerialization}, expected ${expectedInlinedClass?.fqNameForIrSerialization}") }?.symbol } internal object DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION : IrDeclarationOriginImpl("INLINE_CLASS_SPECIAL_FUNCTION") internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass -> require(inlinedClass.isUsedAsBoxClass()) val classes = mutableListOf(inlinedClass) var parent = inlinedClass.parent while (parent is IrClass) { classes.add(parent) parent = parent.parent } require(parent is IrFile) { "Local inline classes are not supported" } val symbols = ir.symbols val isNullable = inlinedClass.inlinedClassIsNullable() val unboxedType = inlinedClass.defaultOrNullableType(isNullable) val boxedType = symbols.any.owner.defaultOrNullableType(isNullable) val parameterType = unboxedType val returnType = boxedType val startOffset = inlinedClass.startOffset val endOffset = inlinedClass.endOffset IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION, IrSimpleFunctionSymbolImpl(), Name.special("<${classes.reversed().joinToString(".") { it.name.asString() }}-box>"), DescriptorVisibilities.PUBLIC, Modality.FINAL, returnType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).also { function -> function.valueParameters = listOf( IrValueParameterImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(), Name.identifier("value"), index = 0, varargElementType = null, isCrossinline = false, type = parameterType, isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = function }) function.parent = inlinedClass.getContainingFile()!! } } internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass -> require(inlinedClass.isUsedAsBoxClass()) val classes = mutableListOf(inlinedClass) var parent = inlinedClass.parent while (parent is IrClass) { classes.add(parent) parent = parent.parent } require(parent is IrFile) { "Local inline classes are not supported" } val symbols = ir.symbols val isNullable = inlinedClass.inlinedClassIsNullable() val unboxedType = inlinedClass.defaultOrNullableType(isNullable) val boxedType = symbols.any.owner.defaultOrNullableType(isNullable) val parameterType = boxedType val returnType = unboxedType val startOffset = inlinedClass.startOffset val endOffset = inlinedClass.endOffset IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION, IrSimpleFunctionSymbolImpl(), Name.special("<${classes.reversed().joinToString(".") { it.name.asString() } }-unbox>"), DescriptorVisibilities.PUBLIC, Modality.FINAL, returnType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).also { function -> function.valueParameters = listOf( IrValueParameterImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(), Name.identifier("value"), index = 0, varargElementType = null, isCrossinline = false, type = parameterType, isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = function }) function.parent = inlinedClass.getContainingFile()!! } } /** * Initialize static boxing. * If output target is native binary then the cache is created. */ internal fun initializeCachedBoxes(context: Context) { if (context.producedLlvmModuleContainsStdlib) { BoxCache.values().forEach { cache -> val cacheName = "${cache.name}_CACHE" val rangeStart = "${cache.name}_RANGE_FROM" val rangeEnd = "${cache.name}_RANGE_TO" initCache(cache, context, cacheName, rangeStart, rangeEnd) } } } /** * Adds global that refers to the cache. */ private fun initCache(cache: BoxCache, context: Context, cacheName: String, rangeStartName: String, rangeEndName: String) { val kotlinType = context.irBuiltIns.getKotlinClass(cache) val staticData = context.llvm.staticData val llvmType = staticData.getLLVMType(kotlinType.defaultType) val (start, end) = context.config.target.getBoxCacheRange(cache) // Constancy of these globals allows LLVM's constant propagation and DCE // to remove fast path of boxing function in case of empty range. staticData.placeGlobal(rangeStartName, createConstant(llvmType, start), true) .setConstant(true) staticData.placeGlobal(rangeEndName, createConstant(llvmType, end), true) .setConstant(true) val values = (start..end).map { staticData.createInitializer(kotlinType, createConstant(llvmType, it)) } val llvmBoxType = structType(context.llvm.runtime.objHeaderType, llvmType) staticData.placeGlobalConstArray(cacheName, llvmBoxType, values, true).llvm } private fun createConstant(llvmType: LLVMTypeRef, value: Int): ConstValue = constValue(LLVMConstInt(llvmType, value.toLong(), 1)!!) // When start is greater than end then `inRange` check is always false // and can be eliminated by LLVM. private val emptyRange = 1 to 0 // Memory usage is around 20kb. private val BoxCache.defaultRange get() = when (this) { BoxCache.BOOLEAN -> (0 to 1) BoxCache.BYTE -> (-128 to 127) BoxCache.SHORT -> (-128 to 127) BoxCache.CHAR -> (0 to 255) BoxCache.INT -> (-128 to 127) BoxCache.LONG -> (-128 to 127) } private fun KonanTarget.getBoxCacheRange(cache: BoxCache): Pair = when (this) { is KonanTarget.ZEPHYR -> emptyRange else -> cache.defaultRange } internal fun IrBuiltIns.getKotlinClass(cache: BoxCache): IrClass = when (cache) { BoxCache.BOOLEAN -> booleanClass BoxCache.BYTE -> byteClass BoxCache.SHORT -> shortClass BoxCache.CHAR -> charClass BoxCache.INT -> intClass BoxCache.LONG -> longClass }.owner // TODO: consider adding box caches for unsigned types. enum class BoxCache { BOOLEAN, BYTE, SHORT, CHAR, INT, LONG } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/BuiltInFictitiousFunctionIrClassFactory.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.konan.descriptors.findPackage import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.util.OperatorNameConventions internal object DECLARATION_ORIGIN_FUNCTION_CLASS : IrDeclarationOriginImpl("DECLARATION_ORIGIN_FUNCTION_CLASS") internal class BuiltInFictitiousFunctionIrClassFactory( var symbolTable: SymbolTable?, private val irBuiltIns: IrBuiltIns, private val reflectionTypes: KonanReflectionTypes ) : IrAbstractFunctionFactory(), IrProvider { override fun getDeclaration(symbol: IrSymbol) = (symbol.descriptor as? FunctionClassDescriptor)?.let { descriptor -> buildClass(descriptor) { declareClass(descriptor) { createIrClass(it, descriptor) } } } var module: IrModuleFragment? = null set(value) { if (value == null) error("Provide a valid non-null module") if (field != null) error("Module has already been set") field = value value.files += filesMap.values // builtClasses.forEach { it.addFakeOverrides() } } class FunctionalInterface(val irClass: IrClass, val descriptor: FunctionClassDescriptor, val arity: Int) fun buildAllClasses() { val maxArity = 255 // See [BuiltInFictitiousFunctionClassFactory]. (0 .. maxArity).forEach { arity -> functionN(arity) kFunctionN(arity) suspendFunctionN(arity) kSuspendFunctionN(arity) } } override fun functionClassDescriptor(arity: Int): FunctionClassDescriptor = irBuiltIns.builtIns.getFunction(arity) as FunctionClassDescriptor override fun kFunctionClassDescriptor(arity: Int): FunctionClassDescriptor = reflectionTypes.getKFunction(arity) as FunctionClassDescriptor override fun suspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor = irBuiltIns.builtIns.getSuspendFunction(arity) as FunctionClassDescriptor override fun kSuspendFunctionClassDescriptor(arity: Int): FunctionClassDescriptor = reflectionTypes.getKSuspendFunction(arity) as FunctionClassDescriptor override fun functionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = buildClass(irBuiltIns.builtIns.getFunction(arity) as FunctionClassDescriptor, declarator) override fun kFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = buildClass(reflectionTypes.getKFunction(arity) as FunctionClassDescriptor, declarator) override fun suspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = buildClass(irBuiltIns.builtIns.getSuspendFunction(arity) as FunctionClassDescriptor, declarator) override fun kSuspendFunctionN(arity: Int, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = buildClass(reflectionTypes.getKSuspendFunction(arity) as FunctionClassDescriptor, declarator) private val functionSymbol = symbolTable!!.referenceClass( irBuiltIns.builtIns.builtInsModule.findClassAcrossModuleDependencies( ClassId.topLevel(KonanFqNames.function))!!) private val kFunctionSymbol = symbolTable!!.referenceClass( irBuiltIns.builtIns.builtInsModule.findClassAcrossModuleDependencies( ClassId.topLevel(KonanFqNames.kFunction))!!) private val filesMap = mutableMapOf() private val builtClassesMap = mutableMapOf() val builtClasses get() = builtClassesMap.values val builtFunctionNClasses get() = builtClassesMap.entries.mapNotNull { (descriptor, irClass) -> with(descriptor) { if (functionKind == FunctionClassKind.Function) FunctionalInterface(irClass, descriptor, arity) else null } } private fun createTypeParameter(descriptor: TypeParameterDescriptor): IrTypeParameter = symbolTable?.declareGlobalTypeParameter( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_FUNCTION_CLASS, descriptor ) ?: IrTypeParameterImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_FUNCTION_CLASS, IrTypeParameterSymbolImpl(descriptor), descriptor.name, descriptor.index, descriptor.isReified, descriptor.variance ) private fun createSimpleFunction( descriptor: FunctionDescriptor, origin: IrDeclarationOrigin, returnType: IrType ): IrSimpleFunction { val functionFactory: (IrSimpleFunctionSymbol) -> IrSimpleFunction = { with(descriptor) { IrFunctionImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, origin, it, name, visibility, modality, returnType, isInline, isExternal, isTailrec, isSuspend, isOperator, isInfix, isExpect ) } } return symbolTable?.declareSimpleFunction(descriptor, functionFactory) ?: functionFactory(IrSimpleFunctionSymbolImpl(descriptor)) } private fun createIrClass(symbol: IrClassSymbol, descriptor: ClassDescriptor): IrClass = IrFactoryImpl.createIrClassFromDescriptor(offset, offset, DECLARATION_ORIGIN_FUNCTION_CLASS, symbol, descriptor) private fun createClass(descriptor: FunctionClassDescriptor, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = symbolTable?.declarator { createIrClass(it, descriptor) } ?: createIrClass(IrClassSymbolImpl(descriptor), descriptor) private fun buildClass(descriptor: FunctionClassDescriptor, declarator: SymbolTable.((IrClassSymbol) -> IrClass) -> IrClass): IrClass = builtClassesMap.getOrPut(descriptor) { createClass(descriptor, declarator).apply { val functionClass = this typeParameters += descriptor.declaredTypeParameters.map { typeParameterDescriptor -> createTypeParameter(typeParameterDescriptor).also { it.parent = this it.superTypes += irBuiltIns.anyNType } } val descriptorToIrParametersMap = typeParameters.map { it.descriptor to it }.toMap() superTypes += descriptor.typeConstructor.supertypes.map { superType -> val arguments = superType.arguments.map { argument -> val argumentClassifierDescriptor = argument.type.constructor.declarationDescriptor val argumentClassifierSymbol = argumentClassifierDescriptor?.let { descriptorToIrParametersMap[it] } ?: error("Unexpected super type argument: $argumentClassifierDescriptor") makeTypeProjection(argumentClassifierSymbol.defaultType, argument.projectionKind) } val superTypeSymbol = when (val superTypeDescriptor = superType.constructor.declarationDescriptor) { is FunctionClassDescriptor -> buildClass(superTypeDescriptor) { declareClass(superTypeDescriptor) { createIrClass(it, superTypeDescriptor) } }.symbol functionSymbol.descriptor -> functionSymbol kFunctionSymbol.descriptor -> kFunctionSymbol else -> error("Unexpected super type: $superTypeDescriptor") } IrSimpleTypeImpl(superTypeSymbol, superType.isMarkedNullable, arguments, emptyList()) } createParameterDeclarations() val invokeFunctionDescriptor = descriptor.unsubstitutedMemberScope.getContributedFunctions( OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).single() val isFakeOverride = invokeFunctionDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE if (!isFakeOverride) { val invokeFunctionOrigin = if (isFakeOverride) IrDeclarationOrigin.FAKE_OVERRIDE else DECLARATION_ORIGIN_FUNCTION_CLASS declarations += createSimpleFunction( invokeFunctionDescriptor, invokeFunctionOrigin, typeParameters.last().defaultType ).apply { parent = functionClass valueParameters += invokeFunctionDescriptor.valueParameters.map { IrValueParameterImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, invokeFunctionOrigin, IrValueParameterSymbolImpl(it), it.name, it.index, functionClass.typeParameters[it.index].defaultType, null, it.isCrossinline, it.isNoinline, isHidden = false, isAssignable = false ).also { it.parent = this } } if (!isFakeOverride) createDispatchReceiverParameter(invokeFunctionOrigin) else { val overriddenFunction = superTypes .mapNotNull { it.classOrNull?.owner } .single { it.descriptor is FunctionClassDescriptor } .simpleFunctions() .single { it.name == OperatorNameConventions.INVOKE } overriddenSymbols += overriddenFunction.symbol dispatchReceiverParameter = overriddenFunction.dispatchReceiverParameter?.copyTo(this) } } } // Unfortunately, addFakeOverrides() uses some parents but they are only set after PsiToIr phase. // So we add all the fake overrides only when we're supplied with the module (this is done after PsiToIr). // if (this@BuiltInFictitiousFunctionIrClassFactory.module != null) addFakeOverrides() val packageFragmentDescriptor = descriptor.findPackage() val file = filesMap.getOrPut(packageFragmentDescriptor) { IrFileImpl(NaiveSourceBasedFileEntryImpl("[K][Suspend]Functions"), packageFragmentDescriptor).also { this@BuiltInFictitiousFunctionIrClassFactory.module?.files?.add(it) } } parent = file file.declarations += this } } private fun toIrType(wrapped: KotlinType): IrType { val kotlinType = wrapped.unwrap() return with(IrSimpleTypeBuilder()) { classifier = symbolTable?.referenceClassifier(kotlinType.constructor.declarationDescriptor ?: error("No classifier for type $kotlinType")) hasQuestionMark = kotlinType.isMarkedNullable arguments = kotlinType.arguments.map { if (it.isStarProjection) IrStarProjectionImpl else makeTypeProjection(toIrType(it.type), it.projectionKind) } buildSimpleType() } } private fun IrFunction.createValueParameter(descriptor: ParameterDescriptor): IrValueParameter { val varargType = if (descriptor is ValueParameterDescriptor) descriptor.varargElementType else null return IrValueParameterImpl( offset, offset, memberOrigin, IrValueParameterSymbolImpl(descriptor), descriptor.name, descriptor.indexOrMinusOne, toIrType(descriptor.type), varargType?.let { toIrType(it) }, descriptor.isCrossinline, descriptor.isNoinline, isHidden = false, isAssignable = false ).also { it.parent = this } } private fun IrClass.addFakeOverrides() { val fakeOverrideDescriptors = descriptor.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.CALLABLES) .filterIsInstance().filter { it.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE } fun createFakeOverrideFunction(descriptor: FunctionDescriptor, property: IrPropertySymbol?): IrSimpleFunction { val returnType = descriptor.returnType?.let { toIrType(it) } ?: error("No return type for $descriptor") val functionDeclare = { s: IrSimpleFunctionSymbol -> descriptor.run { IrFunctionImpl( offset, offset, memberOrigin, s, name, visibility, modality, returnType, isInline, isExternal, isTailrec, isSuspend, isOperator, isInfix, isExpect, isFakeOverride = true ) } } val newFunction = symbolTable?.declareSimpleFunction(descriptor, functionDeclare) ?: functionDeclare(IrSimpleFunctionSymbolImpl(descriptor)) newFunction.parent = this newFunction.overriddenSymbols = descriptor.overriddenDescriptors.mapNotNull { symbolTable?.referenceSimpleFunction(it.original) } newFunction.dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.let { newFunction.createValueParameter(it) } newFunction.extensionReceiverParameter = descriptor.extensionReceiverParameter?.let { newFunction.createValueParameter(it) } newFunction.valueParameters = descriptor.valueParameters.map { newFunction.createValueParameter(it) } newFunction.correspondingPropertySymbol = property return newFunction } fun createFakeOverrideProperty(descriptor: PropertyDescriptor): IrProperty { val propertyDeclare = { s: IrPropertySymbol -> IrPropertyImpl( startOffset = offset, endOffset = offset, origin = memberOrigin, symbol = s, name = descriptor.name, visibility = descriptor.visibility, modality = descriptor.modality, isVar = descriptor.isVar, isConst = descriptor.isConst, isLateinit = descriptor.isLateInit, isDelegated = descriptor.isDelegated, isExternal = descriptor.isExternal, isExpect = descriptor.isExpect, isFakeOverride = memberOrigin == IrDeclarationOrigin.FAKE_OVERRIDE) } val property = symbolTable?.declareProperty(offset, offset, memberOrigin, descriptor, propertyFactory = propertyDeclare) ?: propertyDeclare(IrPropertySymbolImpl(descriptor)) property.parent = this property.getter = descriptor.getter?.let { g -> createFakeOverrideFunction(g, property.symbol) } property.setter = descriptor.setter?.let { s -> createFakeOverrideFunction(s, property.symbol) } return property } fun createFakeOverride(descriptor: CallableMemberDescriptor): IrDeclaration { return when (descriptor) { is FunctionDescriptor -> createFakeOverrideFunction(descriptor, null) is PropertyDescriptor -> createFakeOverrideProperty(descriptor) else -> error("Unexpected member $descriptor") } } declarations += fakeOverrideDescriptors.map { createFakeOverride(it) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterCompile.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.exec.* import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.file.* fun produceCAdapterBitcode(clang: ClangArgs, cppFileName: String, bitcodeFileName: String) { val clangCommand = clang.clangCXX("-std=c++17", cppFileName, "-emit-llvm", "-c", "-o", bitcodeFileName) Command(clangCommand).execute() } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import kotlinx.cinterop.cValuesOf import java.io.PrintWriter import llvm.* import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.ir.isOverridable import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.referenceFunction import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.name.isChildOf import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.annotations.* import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.addIfNotNull private enum class ScopeKind { TOP, CLASS, PACKAGE } private enum class ElementKind { FUNCTION, PROPERTY, TYPE } private enum class DefinitionKind { C_HEADER_DECLARATION, C_HEADER_STRUCT, C_SOURCE_DECLARATION, C_SOURCE_STRUCT } private enum class Direction { KOTLIN_TO_C, C_TO_KOTLIN } private operator fun String.times(count: Int): String { val builder = StringBuilder() repeat(count, { builder.append(this) }) return builder.toString() } private val KotlinType.shortNameForPredefinedType get() = this.toString().split('.').last() private val KotlinType.createNullableNameForPredefinedType get() = "createNullable${this.shortNameForPredefinedType}" internal val cKeywords = setOf( // Actual C keywords. "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while", // C99-specific. "_Bool", "_Complex", "_Imaginary", "inline", "restrict", // C11-specific. "_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local", // Not exactly keywords, but reserved or standard-defined. "and", "not", "or", "xor", "bool", "complex", "imaginary", // C++ keywords not listed above. "alignas", "alignof", "and_eq", "asm", "bitand", "bitor", "bool", "catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast", "decltype", "delete", "dynamic_cast", "explicit", "export", "false", "friend", "inline", "mutable", "namespace", "new", "noexcept", "not_eq", "nullptr", "operator", "or_eq", "private", "protected", "public", "reinterpret_cast", "static_assert", "template", "this", "thread_local", "throw", "true", "try", "typeid", "typename", "using", "virtual", "wchar_t", "xor_eq" ) private fun isExportedFunction(descriptor: FunctionDescriptor): Boolean { if (!descriptor.isEffectivelyPublicApi || !descriptor.kind.isReal || descriptor.isExpect) return false if (descriptor.isSuspend) return false return !descriptor.typeParameters.any() } private fun isExportedClass(descriptor: ClassDescriptor): Boolean { if (!descriptor.isEffectivelyPublicApi) return false // No sense to export annotations. if (DescriptorUtils.isAnnotationClass(descriptor)) return false // Do not export expect classes. if (descriptor.isExpect) return false // Do not export types with type parameters. // TODO: is it correct? if (!descriptor.declaredTypeParameters.isEmpty()) return false // Do not export inline classes for now. TODO: add proper support. if (descriptor.isInlined()) return false return true } internal fun AnnotationDescriptor.properValue(key: String) = this.argumentValue(key)?.toString()?.removeSurrounding("\"") private fun functionImplName(descriptor: DeclarationDescriptor, default: String, shortName: Boolean): String { assert(descriptor is FunctionDescriptor) val annotation = descriptor.annotations.findAnnotation(RuntimeNames.cnameAnnotation) ?: return default val key = if (shortName) "shortName" else "externName" val value = annotation.properValue(key) return value.takeIf { value != null && value.isNotEmpty() } ?: default } internal data class SignatureElement(val name: String, val type: KotlinType) private class ExportedElementScope(val kind: ScopeKind, val name: String) { val elements = mutableListOf() val scopes = mutableListOf() private val scopeNames = mutableSetOf() private val scopeNamesMap = mutableMapOf, String>() override fun toString(): String { return "$kind: $name ${elements.joinToString(", ")} ${scopes.joinToString("\n")}" } fun generateCAdapters() { elements.forEach { it.generateCAdapter() } scopes.forEach { it.generateCAdapters() } } fun scopeUniqueName(descriptor: DeclarationDescriptor, shortName: Boolean): String { scopeNamesMap[descriptor to shortName]?.apply { return this } var computedName = when (descriptor) { is ConstructorDescriptor -> "${descriptor.constructedClass.fqNameSafe.shortName().asString()}" is PropertyGetterDescriptor -> "get_${descriptor.correspondingProperty.name.asString()}" is PropertySetterDescriptor -> "set_${descriptor.correspondingProperty.name.asString()}" is FunctionDescriptor -> functionImplName(descriptor, descriptor.fqNameSafe.shortName().asString(), shortName) else -> descriptor.fqNameSafe.shortName().asString() } while (scopeNames.contains(computedName) || cKeywords.contains(computedName)) { computedName += "_" } scopeNames += computedName scopeNamesMap[descriptor to shortName] = computedName return computedName } } private class ExportedElement(val kind: ElementKind, val scope: ExportedElementScope, val declaration: DeclarationDescriptor, val owner: CAdapterGenerator) : ContextUtils { init { scope.elements.add(this) } val name: String get() = declaration.fqNameSafe.shortName().asString() lateinit var cname: String override fun toString(): String { return "$kind: $name (aliased to ${if (::cname.isInitialized) cname.toString() else ""})" } override val context = owner.context fun generateCAdapter() { when { isFunction -> { val function = declaration as FunctionDescriptor val irFunction = irSymbol.owner as IrFunction cname = "_konan_function_${owner.nextFunctionIndex()}" val llvmFunction = owner.codegen.llvmFunction(irFunction) // If function is virtual, we need to resolve receiver properly. val bridge = if (!DescriptorUtils.isTopLevelDeclaration(function) && irFunction.isOverridable) { // We need LLVMGetElementType() as otherwise type is function pointer. generateFunction(owner.codegen, LLVMGetElementType(llvmFunction.type)!!, cname) { val receiver = param(0) val numParams = LLVMCountParams(llvmFunction) val args = (0 .. numParams - 1).map { index -> param(index) } val callee = lookupVirtualImpl(receiver, irFunction) val result = call(callee, args, exceptionHandler = ExceptionHandler.Caller, verbatim = true) ret(result) } } else { LLVMAddAlias(context.llvmModule, llvmFunction.type, llvmFunction, cname)!! } LLVMSetLinkage(bridge, LLVMLinkage.LLVMExternalLinkage) } isClass -> { val irClass = irSymbol.owner as IrClass cname = "_konan_function_${owner.nextFunctionIndex()}" // Produce type getter. val getTypeFunction = addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, "${cname}_type", owner.kGetTypeFuncType ) val builder = LLVMCreateBuilderInContext(llvmContext)!! val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!! LLVMPositionBuilderAtEnd(builder, bb) LLVMBuildRet(builder, irClass.typeInfoPtr.llvm) LLVMDisposeBuilder(builder) // Produce instance getter if needed. if (isSingletonObject) { generateFunction(owner.codegen, owner.kGetObjectFuncType, "${cname}_instance") { val value = getObjectValue(irClass, ExceptionHandler.Caller, null) ret(value) } } } isEnumEntry -> { // Produce entry getter. cname = "_konan_function_${owner.nextFunctionIndex()}" generateFunction(owner.codegen, owner.kGetObjectFuncType, cname) { val irEnumEntry = irSymbol.owner as IrEnumEntry val value = getEnumEntry(irEnumEntry, ExceptionHandler.Caller) ret(value) } } } } fun uniqueName(descriptor: DeclarationDescriptor, shortName: Boolean) = scope.scopeUniqueName(descriptor, shortName) val isFunction = declaration is FunctionDescriptor val isTopLevelFunction: Boolean get() { if (declaration !is FunctionDescriptor || !declaration.annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) return false val annotation = declaration.annotations.findAnnotation(RuntimeNames.cnameAnnotation)!! val externName = annotation.properValue("externName") return externName != null && externName.isNotEmpty() } val isClass = declaration is ClassDescriptor && declaration.kind != ClassKind.ENUM_ENTRY val isEnumEntry = declaration is ClassDescriptor && declaration.kind == ClassKind.ENUM_ENTRY val isSingletonObject = declaration is ClassDescriptor && DescriptorUtils.isObject(declaration) private val irSymbol = when { isFunction -> owner.symbolTable.referenceFunction(declaration as FunctionDescriptor) isClass -> owner.symbolTable.referenceClass(declaration as ClassDescriptor) isEnumEntry -> owner.symbolTable.referenceEnumEntry(declaration as ClassDescriptor) else -> error("unexpected $kind element: $declaration") } fun KotlinType.includeToSignature() = !this.isUnit() fun makeCFunctionSignature(shortName: Boolean): List { if (!isFunction) { throw Error("only for functions") } val descriptor = declaration val original = descriptor.original as FunctionDescriptor val returned = when { original is ConstructorDescriptor -> SignatureElement(uniqueName(original, shortName), original.constructedClass.defaultType) else -> SignatureElement(uniqueName(original, shortName), original.returnType!!) } val uniqueNames = owner.paramsToUniqueNames(original.explicitParameters) val params = ArrayList(original.explicitParameters .filter { it.type.includeToSignature() } .map { SignatureElement(uniqueNames[it]!!, it.type) }) return listOf(returned) + params } fun makeBridgeSignature(): List { if (!isFunction) { throw Error("only for functions") } val descriptor = declaration val original = descriptor.original as FunctionDescriptor val returnedType = when { original is ConstructorDescriptor -> owner.context.builtIns.unitType else -> original.returnType!! } val params = ArrayList(original.allParameters .filter { it.type.includeToSignature() } .map { owner.translateTypeBridge(it.type) }) if (owner.isMappedToReference(returnedType) || owner.isMappedToString(returnedType)) { params += "KObjHeader**" } return listOf(owner.translateTypeBridge(returnedType)) + params } fun makeFunctionPointerString(): String { val signature = makeCFunctionSignature(true) return "${owner.translateType(signature[0])} (*${signature[0].name})(${signature.drop(1).map { it -> "${owner.translateType(it)} ${it.name}" }.joinToString(", ")});" } fun makeTopLevelFunctionString(): Pair { val signature = makeCFunctionSignature(false) val name = signature[0].name return (name to "extern ${owner.translateType(signature[0])} $name(${signature.drop(1).map { it -> "${owner.translateType(it)} ${it.name}" }.joinToString(", ")});") } fun makeFunctionDeclaration(): String { assert(isFunction) val bridge = makeBridgeSignature() val builder = StringBuilder() builder.append("extern \"C\" ${bridge[0]} $cname") builder.append("(${bridge.drop(1).joinToString(", ")});\n") // Now the C function body. builder.append(translateBody(makeCFunctionSignature(false))) return builder.toString() } fun makeClassDeclaration(): String { assert(isClass) val typeGetter = "extern \"C\" ${owner.prefix}_KType* ${cname}_type(void);" val instanceGetter = if (isSingletonObject) { val objectClassC = owner.translateType((declaration as ClassDescriptor).defaultType) """ | |extern "C" KObjHeader* ${cname}_instance(KObjHeader**); |static $objectClassC ${cname}_instance_impl(void) { | Kotlin_initRuntimeIfNeeded(); | KObjHolder result_holder; | KObjHeader* result = ${cname}_instance(result_holder.slot()); | return $objectClassC { .pinned = CreateStablePointer(result)}; |} """.trimMargin() } else "" return "$typeGetter$instanceGetter" } fun makeEnumEntryDeclaration(): String { assert(isEnumEntry) val enumClass = declaration.containingDeclaration as ClassDescriptor val enumClassC = owner.translateType(enumClass.defaultType) return """ |extern "C" KObjHeader* $cname(KObjHeader**); |static $enumClassC ${cname}_impl(void) { | Kotlin_initRuntimeIfNeeded(); | KObjHolder result_holder; | KObjHeader* result = $cname(result_holder.slot()); | return $enumClassC { .pinned = CreateStablePointer(result)}; |} """.trimMargin() } private fun translateArgument(name: String, signatureElement: SignatureElement, direction: Direction, builder: StringBuilder): String { return when { owner.isMappedToString(signatureElement.type) -> if (direction == Direction.C_TO_KOTLIN) { builder.append(" KObjHolder ${name}_holder;\n") "CreateStringFromCString($name, ${name}_holder.slot())" } else { "CreateCStringFromString($name)" } owner.isMappedToReference(signatureElement.type) -> if (direction == Direction.C_TO_KOTLIN) { builder.append(" KObjHolder ${name}_holder2;\n") "DerefStablePointer(${name}.pinned, ${name}_holder2.slot())" } else { "((${owner.translateType(signatureElement.type)}){ .pinned = CreateStablePointer(${name})})" } else -> { assert(!signatureElement.type.binaryTypeIsReference()) { println(signatureElement.toString()) } name } } } val cnameImpl: String get() = if (isTopLevelFunction) functionImplName(declaration, "******" /* Default value must never be used. */, false) else "${cname}_impl" private fun translateBody(cfunction: List): String { val visibility = if (isTopLevelFunction) "RUNTIME_USED extern \"C\"" else "static" val builder = StringBuilder() builder.append("$visibility ${owner.translateType(cfunction[0])} ${cnameImpl}(${cfunction.drop(1). mapIndexed { index, it -> "${owner.translateType(it)} arg${index}" }.joinToString(", ")}) {\n") val args = ArrayList(cfunction.drop(1).mapIndexed { index, pair -> translateArgument("arg$index", pair, Direction.C_TO_KOTLIN, builder) }) val isVoidReturned = owner.isMappedToVoid(cfunction[0].type) val isConstructor = declaration is ConstructorDescriptor val isObjectReturned = !isConstructor && owner.isMappedToReference(cfunction[0].type) val isStringReturned = owner.isMappedToString(cfunction[0].type) // TODO: do we really need that in every function? builder.append(" Kotlin_initRuntimeIfNeeded();\n") builder.append(" try {\n") if (isObjectReturned || isStringReturned) { builder.append(" KObjHolder result_holder;\n") args += "result_holder.slot()" } if (isConstructor) { builder.append(" KObjHolder result_holder;\n") val clazz = scope.elements[0] assert(clazz.kind == ElementKind.TYPE) builder.append(" KObjHeader* result = AllocInstance((const KTypeInfo*)${clazz.cname}_type(), result_holder.slot());\n") args.add(0, "result") } if (!isVoidReturned && !isConstructor) { builder.append(" auto result = ") } builder.append(" $cname(") builder.append(args.joinToString(", ")) builder.append(");\n") if (!isVoidReturned) { val result = translateArgument( "result", cfunction[0], Direction.KOTLIN_TO_C, builder) builder.append(" return $result;\n") } builder.append(" } catch (ExceptionObjHolder& e) { TerminateWithUnhandledException(e.GetExceptionObject()); } \n") builder.append("}\n") return builder.toString() } private fun addUsedType(type: KotlinType, set: MutableSet) { if (type.constructor.declarationDescriptor is TypeParameterDescriptor) return set.addIfNotNull(TypeUtils.getClassDescriptor(type)) } fun addUsedTypes(set: MutableSet) { val descriptor = declaration when (descriptor) { is FunctionDescriptor -> { val original = descriptor.original original.allParameters.forEach { addUsedType(it.type, set) } original.returnType?.let { addUsedType(it, set) } } is PropertyAccessorDescriptor -> { val original = descriptor.original addUsedType(original.correspondingProperty.type, set) } is ClassDescriptor -> { set += descriptor } } } } private fun getPackagesFqNames(module: ModuleDescriptor): Set { val result = mutableSetOf() fun getSubPackages(fqName: FqName) { result.add(fqName) module.getSubPackagesOf(fqName) { true }.forEach { getSubPackages(it) } } getSubPackages(FqName.ROOT) return result } private fun ModuleDescriptor.getPackageFragments(): List = getPackagesFqNames(this).flatMap { getPackage(it).fragments.filter { it.module == this } } internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVisitor { private val scopes = mutableListOf() internal val prefix = context.config.moduleId private lateinit var outputStreamWriter: PrintWriter private val paramNamesRecorded = mutableMapOf() private var codegenOrNull: CodeGenerator? = null internal val codegen get() = codegenOrNull!! private var symbolTableOrNull: SymbolTable? = null internal val symbolTable get() = symbolTableOrNull!! private val predefinedTypes = listOf( context.builtIns.byteType, context.builtIns.shortType, context.builtIns.intType, context.builtIns.longType, context.builtIns.floatType, context.builtIns.doubleType, context.builtIns.charType, context.builtIns.booleanType, context.builtIns.unitType) internal fun paramsToUniqueNames(params: List): Map { paramNamesRecorded.clear() return params.associate { val name = translateName(it.name.asString()) val count = paramNamesRecorded.getOrDefault(name, 0) paramNamesRecorded[name] = count + 1 if (count == 0) { it to name } else { it to "$name${count.toString()}" } } } private fun visitChildren(descriptors: Collection) { for (descriptor in descriptors) { descriptor.accept(this, null) } } private fun visitChildren(descriptor: DeclarationDescriptor) { descriptor.accept(this, null) } override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, ignored: Void?): Boolean { if (!isExportedFunction(descriptor)) return true ExportedElement(ElementKind.FUNCTION, scopes.last(), descriptor, this) return true } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, ignored: Void?): Boolean { if (!isExportedFunction(descriptor)) return true ExportedElement(ElementKind.FUNCTION, scopes.last(), descriptor, this) return true } override fun visitClassDescriptor(descriptor: ClassDescriptor, ignored: Void?): Boolean { if (!isExportedClass(descriptor)) return true // TODO: fix me! val shortName = descriptor.fqNameSafe.shortName() if (shortName.isSpecial || shortName.asString().contains("")) return true val classScope = ExportedElementScope(ScopeKind.CLASS, shortName.asString()) scopes.last().scopes += classScope scopes.push(classScope) // Add type getter. ExportedElement(ElementKind.TYPE, scopes.last(), descriptor, this) visitChildren(descriptor.getConstructors()) visitChildren(DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().memberScope)) scopes.pop() return true } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, ignored: Void?): Boolean { if (descriptor.isExpect) return true descriptor.getter?.let { visitChildren(it) } descriptor.setter?.let { visitChildren(it) } return true } override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, ignored: Void?): Boolean { if (!isExportedFunction(descriptor)) return true ExportedElement(ElementKind.FUNCTION, scopes.last(), descriptor, this) return true } override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, ignored: Void?): Boolean { if (!isExportedFunction(descriptor)) return true ExportedElement(ElementKind.FUNCTION, scopes.last(), descriptor, this) return true } override fun visitScriptDescriptor(descriptor: ScriptDescriptor, ignored: Void?) = true override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, ignored: Void?): Boolean { if (descriptor.module !in moduleDescriptors) return true val fragments = descriptor.module.getPackage(FqName.ROOT).fragments.filter { it.module in moduleDescriptors } visitChildren(fragments) return true } override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, ignored: Void?): Boolean { TODO("visitValueParameterDescriptor() shall not be seen") } override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, ignored: Void?): Boolean { TODO("visitReceiverParameterDescriptor() shall not be seen") } override fun visitVariableDescriptor(descriptor: VariableDescriptor, ignored: Void?) = true override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, ignored: Void?) = true private val seenPackageFragments = mutableSetOf() private var currentPackageFragments: List = emptyList() private val packageScopes = mutableMapOf() override fun visitModuleDeclaration(descriptor: ModuleDescriptor, ignored: Void?): Boolean { TODO("Shall not be called directly") } override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, ignored: Void?) = true override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, ignored: Void?): Boolean { val fqName = descriptor.fqName val packageScope = packageScopes.getOrPut(fqName) { val name = if (fqName.isRoot) "root" else translateName(fqName.shortName().asString()) val scope = ExportedElementScope(ScopeKind.PACKAGE, name) scopes.last().scopes += scope scope } scopes.push(packageScope) visitChildren(DescriptorUtils.getAllDescriptors(descriptor.getMemberScope())) for (currentPackageFragment in currentPackageFragments) { if (!seenPackageFragments.contains(currentPackageFragment) && currentPackageFragment.fqName.isChildOf(descriptor.fqName)) { seenPackageFragments += currentPackageFragment visitChildren(currentPackageFragment) } } scopes.pop() return true } private val moduleDescriptors = mutableSetOf() fun buildExports(symbolTable: SymbolTable) { this.symbolTableOrNull = symbolTable try { buildExports() } finally { this.symbolTableOrNull = null } } fun generateBindings(codegen: CodeGenerator) { this.codegenOrNull = codegen try { generateBindings() } finally { this.codegenOrNull = null } } private fun buildExports() { scopes.push(ExportedElementScope(ScopeKind.TOP, "kotlin")) moduleDescriptors += context.moduleDescriptor moduleDescriptors += context.getExportedDependencies() currentPackageFragments = moduleDescriptors.flatMap { it.getPackageFragments() }.toSet().sortedWith( Comparator { o1, o2 -> o1.fqName.toString().compareTo(o2.fqName.toString()) }) context.moduleDescriptor.getPackage(FqName.ROOT).accept(this, null) } private fun generateBindings() { val top = scopes.pop() assert(scopes.isEmpty() && top.kind == ScopeKind.TOP) // Now, let's generate C world adapters for all functions. top.generateCAdapters() // Then generate data structure, describing generated adapters. makeGlobalStruct(top) } private fun output(string: String, indent: Int = 0) { if (indent != 0) outputStreamWriter.print(" " * indent) outputStreamWriter.println(string) } private fun makeElementDefinition(element: ExportedElement, kind: DefinitionKind, indent: Int) { when (kind) { DefinitionKind.C_HEADER_DECLARATION -> { when { element.isTopLevelFunction -> { val (name, declaration) = element.makeTopLevelFunctionString() exportedSymbols += name output(declaration, 0) } } } DefinitionKind.C_HEADER_STRUCT -> { when { element.isFunction -> output(element.makeFunctionPointerString(), indent) element.isClass -> { output("${prefix}_KType* (*_type)(void);", indent) if (element.isSingletonObject) { output("${translateType((element.declaration as ClassDescriptor).defaultType)} (*_instance)();", indent) } } element.isEnumEntry -> { val enumClass = element.declaration.containingDeclaration as ClassDescriptor output("${translateType(enumClass.defaultType)} (*get)(); /* enum entry for ${element.name}. */", indent) } // TODO: handle properties. } } DefinitionKind.C_SOURCE_DECLARATION -> { when { element.isFunction -> output(element.makeFunctionDeclaration(), 0) element.isClass -> output(element.makeClassDeclaration(), 0) element.isEnumEntry -> output(element.makeEnumEntryDeclaration(), 0) // TODO: handle properties. } } DefinitionKind.C_SOURCE_STRUCT -> { when { element.isFunction -> output("/* ${element.name} = */ ${element.cnameImpl}, ", indent) element.isClass -> { output("/* Type for ${element.name} = */ ${element.cname}_type, ", indent) if (element.isSingletonObject) output("/* Instance for ${element.name} = */ ${element.cname}_instance_impl, ", indent) } element.isEnumEntry -> output("/* enum entry getter ${element.name} = */ ${element.cname}_impl,", indent) // TODO: handle properties. } } } } private fun makeScopeDefinitions(scope: ExportedElementScope, kind: DefinitionKind, indent: Int) { if (kind == DefinitionKind.C_HEADER_STRUCT) output("struct {", indent) if (kind == DefinitionKind.C_SOURCE_STRUCT) output(".${scope.name} = {", indent) scope.elements.forEach { makeElementDefinition(it, kind, indent + 1) } scope.scopes.forEach { makeScopeDefinitions(it, kind, indent + 1) } if (kind == DefinitionKind.C_HEADER_STRUCT) output("} ${scope.name};", indent) if (kind == DefinitionKind.C_SOURCE_STRUCT) output("},", indent) } private fun defineUsedTypesImpl(scope: ExportedElementScope, set: MutableSet) { scope.elements.forEach { it.addUsedTypes(set) } scope.scopes.forEach { defineUsedTypesImpl(it, set) } } private fun defineUsedTypes(scope: ExportedElementScope, indent: Int) { val set = mutableSetOf() defineUsedTypesImpl(scope, set) // Add nullable primitives. predefinedTypes.forEach { val nullableIt = it.makeNullable() output("typedef struct {", indent) output("${prefix}_KNativePtr pinned;", indent + 1) output("} ${translateType(nullableIt)};", indent) } set.forEach { val type = it.defaultType if (isMappedToReference(type) && !it.isInlined()) { output("typedef struct {", indent) output("${prefix}_KNativePtr pinned;", indent + 1) output("} ${translateType(type)};", indent) } } } val exportedSymbols = mutableListOf() private fun makeGlobalStruct(top: ExportedElementScope) { val headerFile = context.config.outputFiles.cAdapterHeader outputStreamWriter = headerFile.printWriter() val exportedSymbol = "${prefix}_symbols" exportedSymbols += exportedSymbol output("#ifndef KONAN_${prefix.toUpperCase()}_H") output("#define KONAN_${prefix.toUpperCase()}_H") // TODO: use namespace for C++ case? output(""" #ifdef __cplusplus extern "C" { #endif""".trimIndent()) output(""" #ifdef __cplusplus typedef bool ${prefix}_KBoolean; #else typedef _Bool ${prefix}_KBoolean; #endif """.trimIndent()) output("typedef unsigned short ${prefix}_KChar;") output("typedef signed char ${prefix}_KByte;") output("typedef short ${prefix}_KShort;") output("typedef int ${prefix}_KInt;") output("typedef long long ${prefix}_KLong;") output("typedef unsigned char ${prefix}_KUByte;") output("typedef unsigned short ${prefix}_KUShort;") output("typedef unsigned int ${prefix}_KUInt;") output("typedef unsigned long long ${prefix}_KULong;") output("typedef float ${prefix}_KFloat;") output("typedef double ${prefix}_KDouble;") val typedef_KVector128 = "typedef float __attribute__ ((__vector_size__ (16))) ${prefix}_KVector128;" if (context.config.target.family == Family.MINGW) { // Separate `output` for each line to ensure Windows EOL (LFCR), otherwise generated file will have inconsistent line ending. output("#ifndef _MSC_VER") output(typedef_KVector128) output("#else") output("#include ") output("typedef __m128 ${prefix}_KVector128;") output("#endif") } else { output(typedef_KVector128) } output("typedef void* ${prefix}_KNativePtr;") output("struct ${prefix}_KType;") output("typedef struct ${prefix}_KType ${prefix}_KType;") output("") defineUsedTypes(top, 0) output("") makeScopeDefinitions(top, DefinitionKind.C_HEADER_DECLARATION, 0) output("") output("typedef struct {") output("/* Service functions. */", 1) output("void (*DisposeStablePointer)(${prefix}_KNativePtr ptr);", 1) output("void (*DisposeString)(const char* string);", 1) output("${prefix}_KBoolean (*IsInstance)(${prefix}_KNativePtr ref, const ${prefix}_KType* type);", 1) predefinedTypes.forEach { val nullableIt = it.makeNullable() val argument = if (!it.isUnit()) translateType(it) else "void" output("${translateType(nullableIt)} (*${it.createNullableNameForPredefinedType})($argument);", 1) } output("") output("/* User functions. */", 1) makeScopeDefinitions(top, DefinitionKind.C_HEADER_STRUCT, 1) output("} ${prefix}_ExportedSymbols;") output("extern ${prefix}_ExportedSymbols* $exportedSymbol(void);") output(""" #ifdef __cplusplus } /* extern "C" */ #endif""".trimIndent()) output("#endif /* KONAN_${prefix.toUpperCase()}_H */") outputStreamWriter.close() println("Produced library API in ${prefix}_api.h") outputStreamWriter = context.config.tempFiles .cAdapterCpp .printWriter() // Include header into C++ source. headerFile.forEachLine { it -> output(it) } output(""" |struct KObjHeader; |typedef struct KObjHeader KObjHeader; |struct KTypeInfo; |typedef struct KTypeInfo KTypeInfo; | |#define RUNTIME_NOTHROW __attribute__((nothrow)) |#define RUNTIME_USED __attribute__((used)) |#define RUNTIME_NORETURN __attribute__((noreturn)) | |extern "C" { |void UpdateStackRef(KObjHeader**, const KObjHeader*) RUNTIME_NOTHROW; |KObjHeader* AllocInstance(const KTypeInfo*, KObjHeader**) RUNTIME_NOTHROW; |KObjHeader* DerefStablePointer(void*, KObjHeader**) RUNTIME_NOTHROW; |void* CreateStablePointer(KObjHeader*) RUNTIME_NOTHROW; |void DisposeStablePointer(void*) RUNTIME_NOTHROW; |${prefix}_KBoolean IsInstance(const KObjHeader*, const KTypeInfo*) RUNTIME_NOTHROW; |void EnterFrame(KObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; |void LeaveFrame(KObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; |void Kotlin_initRuntimeIfNeeded(); |void TerminateWithUnhandledException(KObjHeader*) RUNTIME_NORETURN; | |KObjHeader* CreateStringFromCString(const char*, KObjHeader**); |char* CreateCStringFromString(const KObjHeader*); |void DisposeCString(char* cstring); |} // extern "C" | |struct ${prefix}_FrameOverlay { | void* arena; | ${prefix}_FrameOverlay* previous; | ${prefix}_KInt parameters; | ${prefix}_KInt count; |}; | |class KObjHolder { |public: | KObjHolder() : obj_(nullptr) { | EnterFrame(frame(), 0, sizeof(*this)/sizeof(void*)); | } | explicit KObjHolder(const KObjHeader* obj) : obj_(nullptr) { | EnterFrame(frame(), 0, sizeof(*this)/sizeof(void*)); | UpdateStackRef(&obj_, obj); | } | ~KObjHolder() { | LeaveFrame(frame(), 0, sizeof(*this)/sizeof(void*)); | } | KObjHeader* obj() { return obj_; } | KObjHeader** slot() { return &obj_; } | private: | ${prefix}_FrameOverlay frame_; | KObjHeader* obj_; | | KObjHeader** frame() { return reinterpret_cast(&frame_); } |}; | |class ExceptionObjHolder { |public: | virtual ~ExceptionObjHolder() = default; | | KObjHeader* GetExceptionObject() noexcept; |}; | |static void DisposeStablePointerImpl(${prefix}_KNativePtr ptr) { | DisposeStablePointer(ptr); |} |static void DisposeStringImpl(const char* ptr) { | DisposeCString((char*)ptr); |} |static ${prefix}_KBoolean IsInstanceImpl(${prefix}_KNativePtr ref, const ${prefix}_KType* type) { | KObjHolder holder; | return IsInstance(DerefStablePointer(ref, holder.slot()), (const KTypeInfo*)type); |} """.trimMargin()) predefinedTypes.forEach { assert(!it.isNothing()) val nullableIt = it.makeNullable() val needArgument = !it.isUnit() val (parameter, maybeComma) = if (needArgument) ("${translateType(it)} value" to ",") else ("" to "") val argument = if (needArgument) "value, " else "" output("extern \"C\" KObjHeader* Kotlin_box${it.shortNameForPredefinedType}($parameter$maybeComma KObjHeader**);") output("static ${translateType(nullableIt)} ${it.createNullableNameForPredefinedType}Impl($parameter) {") output("Kotlin_initRuntimeIfNeeded();", 1) output("KObjHolder result_holder;", 1) output("KObjHeader* result = Kotlin_box${it.shortNameForPredefinedType}($argument result_holder.slot());", 1) output("return ${translateType(nullableIt)} { .pinned = CreateStablePointer(result) };", 1) output("}") } makeScopeDefinitions(top, DefinitionKind.C_SOURCE_DECLARATION, 0) output("static ${prefix}_ExportedSymbols __konan_symbols = {") output(".DisposeStablePointer = DisposeStablePointerImpl,", 1) output(".DisposeString = DisposeStringImpl,", 1) output(".IsInstance = IsInstanceImpl,", 1) predefinedTypes.forEach { output(".${it.createNullableNameForPredefinedType} = ${it.createNullableNameForPredefinedType}Impl,", 1) } makeScopeDefinitions(top, DefinitionKind.C_SOURCE_STRUCT, 1) output("};") output("RUNTIME_USED ${prefix}_ExportedSymbols* $exportedSymbol(void) { return &__konan_symbols;}") outputStreamWriter.close() if (context.config.target.family == Family.MINGW) { outputStreamWriter = context.config.outputFiles .cAdapterDef .printWriter() output("EXPORTS") exportedSymbols.forEach { output(it) } outputStreamWriter.close() } } private val simpleNameMapping = mapOf( "" to "thiz", "" to "set" ) private val primitiveTypeMapping = KonanPrimitiveType.values().associate { it to when (it) { KonanPrimitiveType.BOOLEAN -> "${prefix}_KBoolean" KonanPrimitiveType.CHAR -> "${prefix}_KChar" KonanPrimitiveType.BYTE -> "${prefix}_KByte" KonanPrimitiveType.SHORT -> "${prefix}_KShort" KonanPrimitiveType.INT -> "${prefix}_KInt" KonanPrimitiveType.LONG -> "${prefix}_KLong" KonanPrimitiveType.FLOAT -> "${prefix}_KFloat" KonanPrimitiveType.DOUBLE -> "${prefix}_KDouble" KonanPrimitiveType.NON_NULL_NATIVE_PTR -> "void*" KonanPrimitiveType.VECTOR128 -> "${prefix}_KVector128" } } private val unsignedTypeMapping = UnsignedType.values().associate { it.classId to when (it) { UnsignedType.UBYTE -> "${prefix}_KUByte" UnsignedType.USHORT -> "${prefix}_KUShort" UnsignedType.UINT -> "${prefix}_KUInt" UnsignedType.ULONG -> "${prefix}_KULong" } } internal fun isMappedToString(type: KotlinType): Boolean = isMappedToString(type.computeBinaryType()) private fun isMappedToString(binaryType: BinaryType): Boolean = when (binaryType) { is BinaryType.Primitive -> false is BinaryType.Reference -> binaryType.types.first() == context.builtIns.string } internal fun isMappedToReference(type: KotlinType) = !isMappedToVoid(type) && !isMappedToString(type) && type.binaryTypeIsReference() internal fun isMappedToVoid(type: KotlinType): Boolean { return type.isUnit() || type.isNothing() } fun translateName(name: String): String { return when { simpleNameMapping.contains(name) -> simpleNameMapping[name]!! cKeywords.contains(name) -> "${name}_" else -> name } } private fun translateTypeFull(type: KotlinType): Pair = if (isMappedToVoid(type)) { "void" to "void" } else { translateNonVoidTypeFull(type) } private fun translateNonVoidTypeFull(type: KotlinType): Pair = type.unwrapToPrimitiveOrReference( eachInlinedClass = { inlinedClass, _ -> unsignedTypeMapping[inlinedClass.classId]?.let { return it to it } }, ifPrimitive = { primitiveType, _ -> primitiveTypeMapping[primitiveType]!!.let { it to it } }, ifReference = { val clazz = (it.computeBinaryType() as BinaryType.Reference).types.first() if (clazz == context.builtIns.string) { "const char*" to "KObjHeader*" } else { "${prefix}_kref_${translateTypeFqName(clazz.fqNameSafe.asString())}" to "KObjHeader*" } } ) fun translateType(element: SignatureElement): String = translateTypeFull(element.type).first fun translateType(type: KotlinType): String = translateTypeFull(type).first fun translateTypeBridge(type: KotlinType): String = translateTypeFull(type).second fun translateTypeFqName(name: String): String { return name.replace('.', '_') } private var functionIndex = 0 fun nextFunctionIndex() = functionIndex++ internal val kGetTypeFuncType get() = LLVMFunctionType(codegen.kTypeInfoPtr, null, 0, 0)!! // Abstraction leak for slot :(. internal val kGetObjectFuncType get() = LLVMFunctionType(codegen.kObjHeaderPtr, cValuesOf(codegen.kObjHeaderPtrPtr), 1, 0)!! } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CStubsManager.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.* import org.jetbrains.kotlin.konan.target.ClangArgs import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.KonanTarget class CStubsManager(private val target: KonanTarget) { fun getUniqueName(prefix: String) = "$prefix${counter++}" fun addStub(kotlinLocation: CompilerMessageLocation?, lines: List) { stubs += Stub(kotlinLocation, lines) } fun compile(clang: ClangArgs, messageCollector: MessageCollector, verbose: Boolean): File? { if (stubs.isEmpty()) return null val compilerOptions = mutableListOf() val sourceFileExtension = when { target.family.isAppleFamily -> { compilerOptions += "-fobjc-arc" ".m" // TODO: consider managing C and Objective-C stubs separately. } else -> ".c" } val cSource = createTempFile("cstubs", sourceFileExtension).deleteOnExit() cSource.writeLines(stubs.flatMap { it.lines }) val bitcode = createTempFile("cstubs", ".bc").deleteOnExit() val cSourcePath = cSource.absolutePath val clangCommand = clang.clangC(*compilerOptions.toTypedArray(), "-O2", cSourcePath, "-emit-llvm", "-c", "-o", bitcode.absolutePath) val result = Command(clangCommand).getResult(withErrors = true) if (result.exitCode != 0) { reportCompilationErrors(cSourcePath, result, messageCollector, verbose) } return bitcode } private fun reportCompilationErrors( cSourcePath: String, result: Command.Result, messageCollector: MessageCollector, verbose: Boolean ): Nothing { val regex = Regex("${Regex.escape(cSourcePath)}:([0-9]+):[0-9]+: error: .*") val errorLines = result.outputLines.mapNotNull { line -> regex.matchEntire(line)?.let { matchResult -> matchResult.groupValues[1].toInt() } } val lineToStub = ArrayList() stubs.forEach { stub -> repeat(stub.lines.size) { lineToStub.add(stub) } } val cSourceCopyPath = "cstubs.c" if (verbose) { File(cSourcePath).copyTo(File(cSourceCopyPath)) } if (errorLines.isNotEmpty()) { errorLines.forEach { messageCollector.report( CompilerMessageSeverity.ERROR, "Unable to compile C bridge" + if (verbose) " at $cSourceCopyPath:$it" else "", lineToStub[it - 1].kotlinLocation ) } } else { messageCollector.report( CompilerMessageSeverity.ERROR, "Unable to compile C bridges", null ) } throw KonanCompilationException() } private val stubs = mutableListOf() private class Stub(val kotlinLocation: CompilerMessageLocation?, val lines: List) private var counter = 0 } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult class CacheSupport( val configuration: CompilerConfiguration, resolvedLibraries: KotlinLibraryResolveResult, target: KonanTarget, produce: CompilerOutputKind ) { private val allLibraries = resolvedLibraries.getFullList() // TODO: consider using [FeaturedLibraries.kt]. private val fileToLibrary = allLibraries.associateBy { it.libraryFile } private val implicitCacheDirectories = configuration.get(KonanConfigKeys.CACHE_DIRECTORIES)!! .map { File(it).takeIf { it.isDirectory } ?: configuration.reportCompilationError("cache directory $it is not found or not a directory") } internal fun tryGetImplicitOutput(): String? { val libraryToAddToCache = configuration.get(KonanConfigKeys.LIBRARY_TO_ADD_TO_CACHE) ?: return null // Put the resulting library in the first cache directory. val cacheDirectory = implicitCacheDirectories.firstOrNull() ?: return null val libraryToAddToCacheFile = File(libraryToAddToCache) val library = allLibraries.single { it.libraryFile == libraryToAddToCacheFile } return cacheDirectory.child(CachedLibraries.getCachedLibraryName(library)).absolutePath } internal val cachedLibraries: CachedLibraries = run { val explicitCacheFiles = configuration.get(KonanConfigKeys.CACHED_LIBRARIES)!! val explicitCaches = explicitCacheFiles.entries.associate { (libraryPath, cachePath) -> val library = fileToLibrary[File(libraryPath)] ?: configuration.reportCompilationError("cache not applied: library $libraryPath in $cachePath") library to cachePath } val optimized = configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) if (optimized && (explicitCacheFiles.isNotEmpty() || implicitCacheDirectories.isNotEmpty())) configuration.report(CompilerMessageSeverity.WARNING, "Cached libraries will not be used for optimized compilation") CachedLibraries( target = target, allLibraries = allLibraries, explicitCaches = if (optimized) emptyMap() else explicitCaches, implicitCacheDirectories = if (optimized) emptyList() else implicitCacheDirectories ) } private fun getLibrary(file: File) = fileToLibrary[file] ?: error("library to cache\n" + " ${file.absolutePath}\n" + "not found among resolved libraries:\n " + allLibraries.joinToString("\n ") { it.libraryFile.absolutePath }) internal val librariesToCache: Set = run { val libraryToAddToCachePath = configuration.get(KonanConfigKeys.LIBRARY_TO_ADD_TO_CACHE) if (libraryToAddToCachePath.isNullOrEmpty()) { configuration.get(KonanConfigKeys.LIBRARIES_TO_CACHE)!! .map { getLibrary(File(it)) } .toSet() .also { if (!produce.isCache) check(it.isEmpty()) } } else { val libraryToAddToCacheFile = File(libraryToAddToCachePath) val libraryToAddToCache = getLibrary(libraryToAddToCacheFile) val libraryCache = cachedLibraries.getLibraryCache(libraryToAddToCache) if (libraryCache == null) setOf(libraryToAddToCache) else emptySet() } } internal val preLinkCaches: Boolean = configuration.get(KonanConfigKeys.PRE_LINK_CACHES, false) init { // Ensure dependencies of every cached library are cached too: resolvedLibraries.getFullList { libraries -> libraries.map { library -> val cache = cachedLibraries.getLibraryCache(library.library) if (cache != null || library.library in librariesToCache) { library.resolvedDependencies.forEach { if (!cachedLibraries.isLibraryCached(it.library) && it.library !in librariesToCache) { val description = if (cache != null) { "cached (in ${cache.path})" } else { "going to be cached" } configuration.reportCompilationError( "${library.library.libraryName} is $description, " + "but its dependency isn't: ${it.library.libraryName}" ) } } } library } } // Ensure not making cache for libraries that are already cached: librariesToCache.forEach { val cache = cachedLibraries.getLibraryCache(it) if (cache != null) { configuration.reportCompilationError("Can't cache library '${it.libraryName}' " + "that is already cached in '${cache.path}'") } } if ((librariesToCache.isNotEmpty() || cachedLibraries.hasDynamicCaches || cachedLibraries.hasStaticCaches) && configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)) { configuration.reportCompilationError("Cache cannot be used in optimized compilation") } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult class CachedLibraries( private val target: KonanTarget, allLibraries: List, explicitCaches: Map, implicitCacheDirectories: List ) { class Cache(val kind: Kind, val path: String) { enum class Kind { DYNAMIC, STATIC } val bitcodeDependencies by lazy { val directory = File(path).absoluteFile.parent File(directory, BITCODE_DEPENDENCIES_FILE_NAME).readStrings() } } private val cacheDirsContents = mutableMapOf>() private fun selectCache(library: KotlinLibrary, cacheDir: File): Cache? { // See Linker.renameOutput why is it ok to have an empty cache directory. val cacheDirContents = cacheDirsContents.getOrPut(cacheDir.absolutePath) { cacheDir.listFilesOrEmpty.map { it.absolutePath }.toSet() } if (cacheDirContents.isEmpty()) return null val baseName = getCachedLibraryName(library) val dynamicFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.DYNAMIC_CACHE)) val staticFile = cacheDir.child(getArtifactName(baseName, CompilerOutputKind.STATIC_CACHE)) if (dynamicFile.absolutePath in cacheDirContents && staticFile.absolutePath in cacheDirContents) error("Both dynamic and static caches files cannot be in the same directory." + " Library: ${library.libraryName}, path to cache: ${cacheDir.absolutePath}") return when { dynamicFile.absolutePath in cacheDirContents -> Cache(Cache.Kind.DYNAMIC, dynamicFile.absolutePath) staticFile.absolutePath in cacheDirContents -> Cache(Cache.Kind.STATIC, staticFile.absolutePath) else -> error("No cache found for library ${library.libraryName} at ${cacheDir.absolutePath}") } } private val allCaches: Map = allLibraries.mapNotNull { library -> val explicitPath = explicitCaches[library] val cache = if (explicitPath != null) { selectCache(library, File(explicitPath)) ?: error("No cache found for library ${library.libraryName} at $explicitPath") } else { implicitCacheDirectories.firstNotNullResult { dir -> selectCache(library, dir.child(getCachedLibraryName(library))) } } cache?.let { library to it } }.toMap() private fun getArtifactName(baseName: String, kind: CompilerOutputKind) = "${kind.prefix(target)}$baseName${kind.suffix(target)}" fun isLibraryCached(library: KotlinLibrary): Boolean = getLibraryCache(library) != null fun getLibraryCache(library: KotlinLibrary): Cache? = allCaches[library] val hasStaticCaches = allCaches.values.any { when (it.kind) { Cache.Kind.STATIC -> true Cache.Kind.DYNAMIC -> false } } val hasDynamicCaches = allCaches.values.any { when (it.kind) { Cache.Kind.STATIC -> false Cache.Kind.DYNAMIC -> true } } companion object { fun getCachedLibraryName(library: KotlinLibrary): String = getCachedLibraryName(library.uniqueName) fun getCachedLibraryName(libraryName: String): String = "$libraryName-cache" const val BITCODE_DEPENDENCIES_FILE_NAME = "bitcode_deps" } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CodeGenerationInfo.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.name.FqName internal fun IrClass.isNonGeneratedAnnotation(): Boolean = this.kind == ClassKind.ANNOTATION_CLASS && !this.annotations.hasAnnotation(serialInfoAnnotationFqName) private val serialInfoAnnotationFqName = FqName("kotlinx.serialization.SerialInfo") /** * We don't need to generate RTTI in some cases, e.g. Objective-C external classes. */ internal fun IrClass.requiresRtti(): Boolean = when { // TODO: Support more cases // Sadly, we still need to emit RTTI for Kotlin inheritors of Obj-C classes. // The reason for it is that we need to know a layout of the object to correctly // deinitialize it. this.isExternalObjCClass() -> false else -> true } internal fun IrClass.requiresCodeGeneration(): Boolean = // For now these two sets (classes that require RTTI and classes that require codegen) // are the same, but they might diverge later. requiresRtti() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import llvm.* import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.Llvm import org.jetbrains.kotlin.backend.konan.llvm.objc.linkObjC import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.isBitcode import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.library.impl.buildLibrary /** * Supposed to be true for a single LLVM module within final binary. */ val CompilerOutputKind.isFinalBinary: Boolean get() = when (this) { CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC, CompilerOutputKind.STATIC, CompilerOutputKind.FRAMEWORK -> true CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE, CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false } val CompilerOutputKind.involvesBitcodeGeneration: Boolean get() = this != CompilerOutputKind.LIBRARY internal val Context.producedLlvmModuleContainsStdlib: Boolean get() = this.llvmModuleSpecification.containsModule(this.stdlibModule) val CompilerOutputKind.involvesLinkStage: Boolean get() = when (this) { CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC, CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE, CompilerOutputKind.STATIC, CompilerOutputKind.FRAMEWORK -> true CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false } val CompilerOutputKind.isCache: Boolean get() = (this == CompilerOutputKind.STATIC_CACHE || this == CompilerOutputKind.DYNAMIC_CACHE) internal fun produceCStubs(context: Context) { val llvmModule = context.llvmModule!! context.cStubsManager.compile(context.config.clang, context.messageCollector, context.inVerbosePhase)?.let { parseAndLinkBitcodeFile(llvmModule, it.absolutePath) } } private fun linkAllDependencies(context: Context, generatedBitcodeFiles: List) { val config = context.config val runtimeNativeLibraries = config.runtimeNativeLibraries .takeIf { context.producedLlvmModuleContainsStdlib }.orEmpty() val launcherNativeLibraries = config.launcherNativeLibraries .takeIf { config.produce == CompilerOutputKind.PROGRAM }.orEmpty() linkObjC(context) val nativeLibraries = config.nativeLibraries + runtimeNativeLibraries + launcherNativeLibraries val bitcodeLibraries = context.llvm.bitcodeToLink.map { it.bitcodePaths }.flatten().filter { it.isBitcode } val additionalBitcodeFilesToLink = context.llvm.additionalProducedBitcodeFiles val exceptionsSupportNativeLibrary = config.exceptionsSupportNativeLibrary val bitcodeFiles = (nativeLibraries + generatedBitcodeFiles + additionalBitcodeFilesToLink + bitcodeLibraries).toMutableSet() if (config.produce == CompilerOutputKind.DYNAMIC_CACHE) bitcodeFiles += exceptionsSupportNativeLibrary val llvmModule = context.llvmModule!! bitcodeFiles.forEach { parseAndLinkBitcodeFile(llvmModule, it) } } private fun insertAliasToEntryPoint(context: Context) { val nomain = context.config.configuration.get(KonanConfigKeys.NOMAIN) ?: false if (context.config.produce != CompilerOutputKind.PROGRAM || nomain) return val module = context.llvmModule val entryPoint = LLVMGetNamedFunction(module, "Konan_main") ?: error("Module doesn't contain `Konan_main`") LLVMAddAlias(module, LLVMTypeOf(entryPoint)!!, entryPoint, "main") } internal fun linkBitcodeDependencies(context: Context) { val config = context.config.configuration val tempFiles = context.config.tempFiles val produce = config.get(KonanConfigKeys.PRODUCE) val generatedBitcodeFiles = if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) { produceCAdapterBitcode( context.config.clang, tempFiles.cAdapterCppName, tempFiles.cAdapterBitcodeName) listOf(tempFiles.cAdapterBitcodeName) } else emptyList() if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) { embedAppleLinkerOptionsToBitcode(context.llvm, context.config) } linkAllDependencies(context, generatedBitcodeFiles) } internal fun produceOutput(context: Context) { val config = context.config.configuration val tempFiles = context.config.tempFiles val produce = config.get(KonanConfigKeys.PRODUCE) when (produce) { CompilerOutputKind.STATIC, CompilerOutputKind.DYNAMIC, CompilerOutputKind.FRAMEWORK, CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.STATIC_CACHE, CompilerOutputKind.PROGRAM -> { val output = tempFiles.nativeBinaryFileName context.bitcodeFileName = output // Insert `_main` after pipeline so we won't worry about optimizations // corrupting entry point. insertAliasToEntryPoint(context) LLVMWriteBitcodeToFile(context.llvmModule!!, output) } CompilerOutputKind.LIBRARY -> { val nopack = config.getBoolean(KonanConfigKeys.NOPACK) val output = context.config.outputFiles.klibOutputFileName(!nopack) val libraryName = context.config.moduleId val shortLibraryName = context.config.shortModuleName val neededLibraries = context.librariesWithDependencies val abiVersion = KotlinAbiVersion.CURRENT val compilerVersion = CompilerVersion.CURRENT.toString() val libraryVersion = config.get(KonanConfigKeys.LIBRARY_VERSION) val metadataVersion = KlibMetadataVersion.INSTANCE.toString() val irVersion = KlibIrVersion.INSTANCE.toString() val versions = KotlinLibraryVersioning( abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion, metadataVersion = metadataVersion, irVersion = irVersion ) val target = context.config.target val manifestProperties = context.config.manifestProperties if (!nopack) { val suffix = context.config.outputFiles.produce.suffix(target) if (!output.endsWith(suffix)) { error("please specify correct output: packed: ${!nopack}, $output$suffix") } } val library = buildLibrary( context.config.nativeLibraries, context.config.includeBinaries, neededLibraries, context.serializedMetadata!!, context.serializedIr, versions, target, output, libraryName, nopack, shortLibraryName, manifestProperties, context.dataFlowGraph) context.bitcodeFileName = library.mainBitcodeFileName } CompilerOutputKind.BITCODE -> { val output = context.config.outputFile context.bitcodeFileName = output LLVMWriteBitcodeToFile(context.llvmModule!!, output) } } } private fun parseAndLinkBitcodeFile(llvmModule: LLVMModuleRef, path: String) { val parsedModule = parseBitcodeFile(path) val failed = LLVMLinkModules2(llvmModule, parsedModule) if (failed != 0) { throw Error("failed to link $path") // TODO: retrieve error message from LLVM. } } private fun embedAppleLinkerOptionsToBitcode(llvm: Llvm, config: KonanConfig) { fun findEmbeddableOptions(options: List): List> { val result = mutableListOf>() val iterator = options.iterator() loop@while (iterator.hasNext()) { val option = iterator.next() result += when { option.startsWith("-l") -> listOf(option) option == "-framework" && iterator.hasNext() -> listOf(option, iterator.next()) else -> break@loop // Ignore the rest. } } return result } val optionsToEmbed = findEmbeddableOptions(config.platform.configurables.linkerKonanFlags) + llvm.allNativeDependencies.flatMap { findEmbeddableOptions(it.linkerOpts) } embedLlvmLinkOptions(llvm.llvmModule, optionsToEmbed) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import llvm.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.library.SerializedMetadata import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD import org.jetbrains.kotlin.backend.konan.optimizations.Devirtualization import org.jetbrains.kotlin.backend.konan.optimizations.ExternalModulesDFG import org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFG import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import java.lang.System.out import kotlin.LazyThreadSafetyMode.PUBLICATION import kotlin.reflect.KProperty import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.konan.library.KonanLibraryLayout import org.jetbrains.kotlin.konan.util.disposeNativeMemoryAllocator import org.jetbrains.kotlin.library.SerializedIrModule import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal /** * Offset for synthetic elements created by lowerings and not attributable to other places in the source code. */ internal class SpecialDeclarationsFactory(val context: Context) { private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) } private val outerThisFields = mutableMapOf() private val internalLoweredEnums = mutableMapOf() private val externalLoweredEnums = mutableMapOf() private data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections) private val bridges = mutableMapOf() val loweredInlineFunctions = mutableSetOf() object DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS") fun getOuterThisField(innerClass: IrClass): IrField = if (!innerClass.isInner) throw AssertionError("Class is not inner: ${innerClass.descriptor}") else outerThisFields.getOrPut(innerClass) { val outerClass = innerClass.parent as? IrClass ?: throw AssertionError("No containing class for inner class ${innerClass.descriptor}") val receiver = ReceiverParameterDescriptorImpl( innerClass.descriptor, ImplicitClassReceiver(innerClass.descriptor, null), Annotations.EMPTY ) val descriptor = PropertyDescriptorImpl.create( innerClass.descriptor, Annotations.EMPTY, Modality.FINAL, DescriptorVisibilities.PRIVATE, false, "this$0".synthesizedName, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, false, false, false, false, false, false ).apply { this.setType(outerClass.descriptor.defaultType, emptyList(), receiver, null) initialize(null, null) } IrFieldImpl( startOffset = innerClass.startOffset, endOffset = innerClass.endOffset, origin = DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS, symbol = IrFieldSymbolImpl(descriptor), name = descriptor.name, type = outerClass.defaultType, visibility = descriptor.visibility, isFinal = !descriptor.isVar, isExternal = descriptor.isEffectivelyExternal(), isStatic = descriptor.dispatchReceiverParameter == null ).apply { parent = innerClass } } fun getLoweredEnum(enumClass: IrClass): LoweredEnumAccess { assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { externalLoweredEnums.getOrPut(enumClass) { enumSpecialDeclarationsFactory.createExternalLoweredEnum(enumClass) } } else { internalLoweredEnums.getOrPut(enumClass) { enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) } } } fun getInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum { assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } assert(context.llvmModuleSpecification.containsDeclaration(enumClass)) { "Expected enum class from current module." } return internalLoweredEnums.getOrPut(enumClass) { enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) } } fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) = enumEntry.parentAsClass.declarations.filterIsInstance().indexOf(enumEntry) fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction { val irFunction = overriddenFunction.function assert(overriddenFunction.needBridge) { "Function ${irFunction.descriptor} is not needed in a bridge to call overridden function ${overriddenFunction.overriddenFunction.descriptor}" } val key = BridgeKey(irFunction, overriddenFunction.bridgeDirections) return bridges.getOrPut(key) { createBridge(key) } } private fun createBridge(key: BridgeKey): IrSimpleFunction { val (function, bridgeDirections) = key val startOffset = function.startOffset val endOffset = function.endOffset fun BridgeDirection.type() = if (this.kind == BridgeDirectionKind.NONE) null else this.irClass?.defaultType ?: context.irBuiltIns.anyNType return IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_BRIDGE_METHOD(function), IrSimpleFunctionSymbolImpl(), "${function.computeFunctionName()}".synthesizedName, function.visibility, function.modality, isInline = false, isExternal = false, isTailrec = false, isSuspend = function.isSuspend, returnType = bridgeDirections.returnDirection.type() ?: function.returnType, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { val bridge = this parent = function.parent dispatchReceiverParameter = function.dispatchReceiverParameter?.let { it.copyTo(bridge, type = bridgeDirections.dispatchReceiverDirection.type() ?: it.type) } extensionReceiverParameter = function.extensionReceiverParameter?.let { it.copyTo(bridge, type = bridgeDirections.extensionReceiverDirection.type() ?: it.type) } valueParameters += function.valueParameters.map { it.copyTo(bridge, type = bridgeDirections.parameterDirectionAt(it.index).type() ?: it.type) } typeParameters += function.typeParameters.map { parameter -> parameter.copyToWithoutSuperTypes(bridge).also { it.superTypes += parameter.superTypes } } } } } internal class Context(config: KonanConfig) : KonanBackendContext(config) { lateinit var frontendServices: FrontendServices lateinit var environment: KotlinCoreEnvironment lateinit var bindingContext: BindingContext lateinit var moduleDescriptor: ModuleDescriptor lateinit var objCExport: ObjCExport lateinit var cAdapterGenerator: CAdapterGenerator lateinit var expectDescriptorToSymbol: MutableMap override val builtIns: KonanBuiltIns by lazy(PUBLICATION) { moduleDescriptor.builtIns as KonanBuiltIns } override val configuration get() = config.configuration override val internalPackageFqn: FqName = RuntimeNames.kotlinNativeInternalPackageName val phaseConfig = config.phaseConfig private val packageScope by lazy { builtIns.builtInsModule.getPackage(KonanFqNames.internalPackageName).memberScope } val nativePtr by lazy { packageScope.getContributedClassifier(NATIVE_PTR_NAME) as ClassDescriptor } val nonNullNativePtr by lazy { packageScope.getContributedClassifier(NON_NULL_NATIVE_PTR_NAME) as ClassDescriptor } val getNativeNullPtr by lazy { packageScope.getContributedFunctions("getNativeNullPtr").single() } val immutableBlobOf by lazy { builtIns.builtInsModule.getPackage(KonanFqNames.packageName).memberScope.getContributedFunctions("immutableBlobOf").single() } val specialDeclarationsFactory = SpecialDeclarationsFactory(this) open class LazyMember(val initializer: Context.() -> T) { operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this) } class LazyVarMember(initializer: Context.() -> T) : LazyMember(initializer) { operator fun setValue(thisRef: Context, property: KProperty<*>, newValue: T) = thisRef.setValue(this, newValue) } companion object { fun lazyMember(initializer: Context.() -> T) = LazyMember(initializer) fun lazyMapMember(initializer: Context.(K) -> V): LazyMember<(K) -> V> = lazyMember { val storage = mutableMapOf() val result: (K) -> V = { storage.getOrPut(it, { initializer(it) }) } result } fun nullValue() = LazyVarMember({ null }) } private val lazyValues = mutableMapOf, Any?>() fun getValue(member: LazyMember): T = @Suppress("UNCHECKED_CAST") (lazyValues.getOrPut(member, { member.initializer(this) }) as T) fun setValue(member: LazyVarMember, newValue: T) { lazyValues[member] = newValue } val reflectionTypes: KonanReflectionTypes by lazy(PUBLICATION) { KonanReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName) } // TODO: Remove after adding special property to IrDeclaration. private val layoutBuilders = mutableMapOf() fun getLayoutBuilder(irClass: IrClass): ClassLayoutBuilder { if (irClass is IrLazyClass) return layoutBuilders.getOrPut(irClass) { ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass)) } val metadata = irClass.metadata as? CodegenClassMetadata ?: CodegenClassMetadata(irClass).also { irClass.metadata = it } metadata.layoutBuilder?.let { return it } val layoutBuilder = ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass)) metadata.layoutBuilder = layoutBuilder return layoutBuilder } lateinit var globalHierarchyAnalysisResult: GlobalHierarchyAnalysisResult // We serialize untouched descriptor tree and IR. // But we have to wait until the code generation phase, // to dump this information into generated file. var serializedMetadata: SerializedMetadata? = null var serializedIr: SerializedIrModule? = null var dataFlowGraph: ByteArray? = null val librariesWithDependencies by lazy { config.librariesWithDependencies(moduleDescriptor) } var functionReferenceCount = 0 var coroutineCount = 0 fun needGlobalInit(field: IrField): Boolean { if (field.descriptor.containingDeclaration !is PackageFragmentDescriptor) return false // TODO: add some smartness here. Maybe if package of the field is in never accessed // assume its global init can be actually omitted. return true } lateinit var irModules: Map // TODO: make lateinit? var irModule: IrModuleFragment? = null set(module) { if (field != null) { throw Error("Another IrModule in the context.") } field = module!! ir = KonanIr(this, module) } override lateinit var ir: KonanIr override val irBuiltIns get() = ir.irModule.irBuiltins val interopBuiltIns by lazy { InteropBuiltIns(this.builtIns) } var llvmModule: LLVMModuleRef? = null set(module) { if (field != null) { throw Error("Another LLVMModule in the context.") } field = module!! llvm = Llvm(this, module) debugInfo = DebugInfo(this) } lateinit var llvm: Llvm val llvmImports: LlvmImports = Llvm.ImportsImpl(this) lateinit var llvmDeclarations: LlvmDeclarations lateinit var bitcodeFileName: String lateinit var library: KonanLibraryLayout private var llvmDisposed = false fun disposeLlvm() { if (llvmDisposed) return if (::debugInfo.isInitialized) LLVMDisposeDIBuilder(debugInfo.builder) if (llvmModule != null) LLVMDisposeModule(llvmModule) if (::llvm.isInitialized) { LLVMDisposeTargetData(llvm.runtime.targetData) LLVMDisposeModule(llvm.runtime.llvmModule) } tryDisposeLLVMContext() llvmDisposed = true } private var nativeMemFreed = false fun freeNativeMem() { if (nativeMemFreed) return disposeNativeMemoryAllocator() nativeMemFreed = true } val cStubsManager = CStubsManager(config.target) val coverage = CoverageManager(this) protected fun separator(title: String) { println("\n\n--- ${title} ----------------------\n") } fun verifyDescriptors() { // TODO: Nothing here for now. } fun printDescriptors() { if (!::moduleDescriptor.isInitialized) return separator("Descriptors:") moduleDescriptor.deepPrint() } fun printIr() { if (irModule == null) return separator("IR:") irModule!!.accept(DumpIrTreeVisitor(out), "") } fun verifyBitCode() { if (llvmModule == null) return verifyModule(llvmModule!!) } fun printBitCode() { if (llvmModule == null) return separator("BitCode:") LLVMDumpModule(llvmModule!!) } fun verify() { verifyDescriptors() verifyBitCode() } fun print() { printDescriptors() printIr() printBitCode() } fun shouldVerifyBitCode() = config.configuration.getBoolean(KonanConfigKeys.VERIFY_BITCODE) fun shouldPrintBitCode() = config.configuration.getBoolean(KonanConfigKeys.PRINT_BITCODE) fun shouldPrintLocations() = config.configuration.getBoolean(KonanConfigKeys.PRINT_LOCATIONS) fun shouldProfilePhases() = config.phaseConfig.needProfiling fun shouldContainDebugInfo() = config.debug fun shouldContainLocationDebugInfo() = shouldContainDebugInfo() || config.lightDebug fun shouldContainAnyDebugInfo() = shouldContainDebugInfo() || shouldContainLocationDebugInfo() fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) fun ghaEnabled() = ::globalHierarchyAnalysisResult.isInitialized val memoryModel = config.memoryModel override var inVerbosePhase = false override fun log(message: () -> String) { if (inVerbosePhase) { println(message()) } } lateinit var debugInfo: DebugInfo var moduleDFG: ModuleDFG? = null var externalModulesDFG: ExternalModulesDFG? = null lateinit var lifetimes: MutableMap lateinit var codegenVisitor: CodeGeneratorVisitor var devirtualizationAnalysisResult: Devirtualization.AnalysisResult? = null var referencedFunctions: Set? = null val isNativeLibrary: Boolean by lazy { val kind = config.configuration.get(KonanConfigKeys.PRODUCE) kind == CompilerOutputKind.DYNAMIC || kind == CompilerOutputKind.STATIC } internal val stdlibModule get() = this.builtIns.any.module lateinit var compilerOutput: List val llvmModuleSpecification: LlvmModuleSpecification by lazy { when { config.produce.isCache -> CacheLlvmModuleSpecification(config.cachedLibraries, config.librariesToCache) else -> DefaultLlvmModuleSpecification(config.cachedLibraries) } } val declaredLocalArrays: MutableMap = HashMap() /** * Manages internal ABI references and declarations. */ val internalAbi = InternalAbi(this) } private fun MemberScope.getContributedClassifier(name: String) = this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) private fun MemberScope.getContributedFunctions(name: String) = this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) internal class ContextLogger(val context: Context) { operator fun String.unaryPlus() = context.log { this } } internal fun Context.logMultiple(messageBuilder: ContextLogger.() -> Unit) { if (!inVerbosePhase) return with(ContextLogger(this)) { messageBuilder() } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DestroyRuntimeMode.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan // Must match `DestroyRuntimeMode` in Runtime.h enum class DestroyRuntimeMode(val value: Int) { LEGACY(0), ON_SHUTDOWN(1), } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.irCatch import org.jetbrains.kotlin.name.Name internal fun makeEntryPoint(context: Context): IrFunction { val actualMain = context.ir.symbols.entryPoint!!.owner val entryPoint = IrFunctionImpl( actualMain.startOffset, actualMain.startOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), Name.identifier("Konan_start"), DescriptorVisibilities.PRIVATE, Modality.FINAL, context.irBuiltIns.intType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).also { function -> function.valueParameters = listOf( IrValueParameterImpl( actualMain.startOffset, actualMain.startOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(), Name.identifier("args"), index = 0, varargElementType = null, isCrossinline = false, type = context.irBuiltIns.arrayClass.typeWith(context.irBuiltIns.stringType), isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = function }) } entryPoint.annotations += buildSimpleAnnotation(context.irBuiltIns, actualMain.startOffset, actualMain.startOffset, context.ir.symbols.exportForCppRuntime.owner, "Konan_start") val builder = context.createIrBuilder(entryPoint.symbol) entryPoint.body = builder.irBlockBody(entryPoint) { +IrTryImpl( startOffset = actualMain.startOffset, endOffset = actualMain.startOffset, type = context.irBuiltIns.nothingType ).apply { tryResult = irBlock { +irCall(actualMain).apply { if (actualMain.valueParameters.size != 0) putValueArgument(0, irGet(entryPoint.valueParameters[0])) } +irReturn(irInt(0)) } catches += irCatch(context.irBuiltIns.throwableType).apply { result = irBlock { +irCall(context.ir.symbols.onUnhandledException).apply { putValueArgument(0, irGet(catchParameter)) } +irReturn(irInt(1)) } } } } return entryPoint } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides import org.jetbrains.kotlin.backend.common.ir.addSimpleDelegatingConstructor import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") /** * Common interface for both [InternalLoweredEnum] and [ExternalLoweredEnum] * that allows to work with lowered enum regardless of its location. */ internal interface LoweredEnumAccess { val valuesGetter: IrSimpleFunction val itemGetterSymbol: IrSimpleFunctionSymbol val entriesMap: Map fun getValuesField(startOffset: Int, endOffset: Int): IrExpression } /** * Represents lowered enum from current module. */ internal data class InternalLoweredEnum( val implObject: IrClass, val valuesField: IrField, val valuesGetterWrapper: IrSimpleFunction, override val valuesGetter: IrSimpleFunction, override val itemGetterSymbol: IrSimpleFunctionSymbol, override val entriesMap: Map ) : LoweredEnumAccess { private fun internalObjectGetter(startOffset: Int, endOffset: Int) = IrGetObjectValueImpl(startOffset, endOffset, implObject.defaultType, implObject.symbol ) override fun getValuesField(startOffset: Int, endOffset: Int): IrExpression = IrGetFieldImpl( startOffset, endOffset, valuesField.symbol, valuesField.type, internalObjectGetter(startOffset, endOffset) ) } /** * Represents lowered enum that's located in external module. */ internal data class ExternalLoweredEnum( override val valuesGetter: IrSimpleFunction, override val itemGetterSymbol: IrSimpleFunctionSymbol, override val entriesMap: Map ) : LoweredEnumAccess { override fun getValuesField(startOffset: Int, endOffset: Int): IrExpression = IrCallImpl(startOffset, endOffset, valuesGetter.returnType, valuesGetter.symbol, valuesGetter.typeParameters.size, valuesGetter.valueParameters.size) } internal class EnumSpecialDeclarationsFactory(val context: Context) { private val symbols = context.ir.symbols private fun enumEntriesMap(enumClass: IrClass): Map = enumClass.declarations .filterIsInstance() .sortedBy { it.name } .withIndex() .associate { it.value.name to it.index } .toMap() private fun findItemGetterSymbol(): IrSimpleFunctionSymbol = symbols.array.functions.single { it.descriptor.name == Name.identifier("get") } private fun valuesArrayType(enumClass: IrClass): IrType = symbols.array.typeWith(enumClass.defaultType) // We can't move property getter to the top-level scope. // So add a wrapper instead. private fun createValuesGetterWrapper(enumClass: IrClass, isExternal: Boolean): IrSimpleFunction = context.irFactory.buildFun { name = InternalAbi.getEnumValuesAccessorName(enumClass) returnType = valuesArrayType(enumClass) origin = InternalAbi.INTERNAL_ABI_ORIGIN this.isExternal = isExternal }.also { if (isExternal) { context.internalAbi.reference(it, enumClass.module) } else { context.internalAbi.declare(it, enumClass.module) } } fun createExternalLoweredEnum(enumClass: IrClass): ExternalLoweredEnum { val enumEntriesMap = enumEntriesMap(enumClass) val itemGetterSymbol = findItemGetterSymbol() val valuesGetterWrapper = createValuesGetterWrapper(enumClass, isExternal = true) return ExternalLoweredEnum(valuesGetterWrapper, itemGetterSymbol, enumEntriesMap) } fun createInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum { val startOffset = enumClass.startOffset val endOffset = enumClass.endOffset val implObject = IrClassImpl( startOffset, endOffset, DECLARATION_ORIGIN_ENUM, IrClassSymbolImpl(), "OBJECT".synthesizedName, ClassKind.OBJECT, DescriptorVisibilities.PUBLIC, Modality.FINAL, isCompanion = false, isInner = false, isData = false, isExternal = false, isInline = false, isExpect = false, isFun = false ).apply { parent = enumClass createParameterDeclarations() } val valuesType = valuesArrayType(enumClass) val valuesField = IrFieldImpl( startOffset, endOffset, DECLARATION_ORIGIN_ENUM, IrFieldSymbolImpl(), "VALUES".synthesizedName, valuesType, DescriptorVisibilities.PRIVATE, isFinal = true, isExternal = false, isStatic = false, ).apply { parent = implObject } val valuesGetter = IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_ENUM, IrSimpleFunctionSymbolImpl(), "get-VALUES".synthesizedName, DescriptorVisibilities.PUBLIC, Modality.FINAL, valuesType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { parent = implObject } val constructorOfAny = context.irBuiltIns.anyClass.owner.constructors.first() implObject.addSimpleDelegatingConstructor( constructorOfAny, context.irBuiltIns, true // TODO: why primary? ) implObject.superTypes += context.irBuiltIns.anyType implObject.addFakeOverrides(context.irBuiltIns) val itemGetterSymbol = findItemGetterSymbol() val enumEntriesMap = enumEntriesMap(enumClass) val valuesGetterWrapper = createValuesGetterWrapper(enumClass, isExternal = false) context.createIrBuilder(valuesGetterWrapper.symbol).run { valuesGetterWrapper.body = irBlockBody { +irReturn(irCall(valuesGetter)) } } return InternalLoweredEnum( implObject, valuesField, valuesGetterWrapper, valuesGetter, itemGetterSymbol, enumEntriesMap) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Exceptions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.KonanException import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments /** * Represents a compilation error caused by mistakes in an input file, e.g. undefined reference. */ class KonanCompilationException( message: String = "", cause: Throwable? = null ) : KotlinExceptionWithAttachments(message, cause) /** * Internal compiler error: could not deserialize IR for inline function body. */ class KonanIrDeserializationException(message: String = "", cause: Throwable? = null) : KonanException(message, cause) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FeaturedLibraries.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.* import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.library.SearchPathResolver import org.jetbrains.kotlin.library.isInterop import org.jetbrains.kotlin.library.toUnresolvedLibraries import org.jetbrains.kotlin.utils.addToStdlib.cast internal fun Context.getExportedDependencies(): List = getDescriptorsFromLibraries((config.resolve.exportedLibraries + config.resolve.includedLibraries).toSet()) internal fun Context.getIncludedLibraryDescriptors(): List = getDescriptorsFromLibraries(config.resolve.includedLibraries.toSet()) private fun Context.getDescriptorsFromLibraries(libraries: Set) = moduleDescriptor.allDependencyModules.filter { when (val origin = it.klibModuleOrigin) { CurrentKlibModuleOrigin, SyntheticModulesOrigin -> false is DeserializedKlibModuleOrigin -> origin.library in libraries } } internal fun getExportedLibraries( configuration: CompilerConfiguration, resolvedLibraries: KotlinLibraryResolveResult, resolver: SearchPathResolver, report: Boolean ): List = getFeaturedLibraries( configuration.getList(KonanConfigKeys.EXPORTED_LIBRARIES), resolvedLibraries, resolver, if (report) FeaturedLibrariesReporter.forExportedLibraries(configuration) else FeaturedLibrariesReporter.Silent, allowDefaultLibs = false ) internal fun getIncludedLibraries( includedLibraryFiles: List, configuration: CompilerConfiguration, resolvedLibraries: KotlinLibraryResolveResult ): List = getFeaturedLibraries( includedLibraryFiles.toSet(), resolvedLibraries, FeaturedLibrariesReporter.forIncludedLibraries(configuration), allowDefaultLibs = false ) internal fun getCoveredLibraries( configuration: CompilerConfiguration, resolvedLibraries: KotlinLibraryResolveResult, resolver: SearchPathResolver ): List = getFeaturedLibraries( configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER), resolvedLibraries, resolver, FeaturedLibrariesReporter.forCoveredLibraries(configuration), allowDefaultLibs = true ) private sealed class FeaturedLibrariesReporter { abstract fun reportIllegalKind(library: KonanLibrary) abstract fun reportNotIncludedLibraries(includedLibraries: List, remainingFeaturedLibraries: Set) protected val KonanLibrary.reportedKind: String get() = when { isInterop -> "Interop" isDefault -> "Default" else -> "Unknown kind" } object Silent: FeaturedLibrariesReporter() { override fun reportIllegalKind(library: KonanLibrary) {} override fun reportNotIncludedLibraries(includedLibraries: List, remainingFeaturedLibraries: Set) {} } abstract class BaseReporter(val configuration: CompilerConfiguration) : FeaturedLibrariesReporter() { protected abstract fun illegalKindMessage(kind: String, libraryName: String): String protected abstract fun notIncludedLibraryMessageTitle(): String override fun reportIllegalKind(library: KonanLibrary) { configuration.report( CompilerMessageSeverity.STRONG_WARNING, illegalKindMessage(library.reportedKind, library.libraryName) ) } override fun reportNotIncludedLibraries(includedLibraries: List, remainingFeaturedLibraries: Set) { val message = buildString { appendLine(notIncludedLibraryMessageTitle()) remainingFeaturedLibraries.forEach { appendLine(it) } appendLine() appendLine("Included libraries:") includedLibraries.forEach { appendLine(it.libraryFile) } } configuration.report(CompilerMessageSeverity.STRONG_WARNING, message) } } private class IncludedLibrariesReporter(val configuration: CompilerConfiguration) : FeaturedLibrariesReporter() { override fun reportIllegalKind(library: KonanLibrary) = with(library) { val message = "$reportedKind library $libraryName cannot be passed with -Xinclude " + "(library path: ${libraryFile.absolutePath})" configuration.report(CompilerMessageSeverity.STRONG_WARNING, message) } override fun reportNotIncludedLibraries(includedLibraries: List, remainingFeaturedLibraries: Set) { error("An included library is not found among resolved libraries") } } private class ExportedLibrariesReporter(configuration: CompilerConfiguration) : BaseReporter(configuration) { override fun illegalKindMessage(kind: String, libraryName: String): String = "$kind library $libraryName can't be exported with -Xexport-library" override fun notIncludedLibraryMessageTitle(): String = "Following libraries are specified to be exported with -Xexport-library, but not included to the build:" } private class CoveredLibraryReporter(configuration: CompilerConfiguration): BaseReporter(configuration) { override fun illegalKindMessage(kind: String, libraryName: String): String = "Cannot provide the code coverage for the $kind library $libraryName." override fun notIncludedLibraryMessageTitle(): String = "The code coverage is enabled for the following libraries, but they are not included to the build:" } companion object { fun forExportedLibraries(configuration: CompilerConfiguration): FeaturedLibrariesReporter = ExportedLibrariesReporter(configuration) fun forCoveredLibraries(configuration: CompilerConfiguration): FeaturedLibrariesReporter = CoveredLibraryReporter(configuration) fun forIncludedLibraries(configuration: CompilerConfiguration): FeaturedLibrariesReporter = IncludedLibrariesReporter(configuration) } } private fun getFeaturedLibraries( featuredLibraries: List, resolvedLibraries: KotlinLibraryResolveResult, resolver: SearchPathResolver, reporter: FeaturedLibrariesReporter, allowDefaultLibs: Boolean ) = getFeaturedLibraries( featuredLibraries.toUnresolvedLibraries.map { resolver.resolve(it).libraryFile }.toSet(), resolvedLibraries, reporter, allowDefaultLibs ) private fun getFeaturedLibraries( featuredLibraryFiles: Set, resolvedLibraries: KotlinLibraryResolveResult, reporter: FeaturedLibrariesReporter, allowDefaultLibs: Boolean ) : List { val remainingFeaturedLibraries = featuredLibraryFiles.toMutableSet() val result = mutableListOf() //TODO: please add type checks before cast. val libraries = resolvedLibraries.getFullList(null).cast>() for (library in libraries) { val libraryFile = library.libraryFile if (libraryFile in featuredLibraryFiles) { remainingFeaturedLibraries -= libraryFile if (library.isInterop || (!allowDefaultLibs && library.isDefault)) { reporter.reportIllegalKind(library) } else { result += library } } } if (remainingFeaturedLibraries.isNotEmpty()) { reporter.reportNotIncludedLibraries(libraries, remainingFeaturedLibraries) } return result } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/GraphAlgorithms.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan internal interface DirectedGraphNode { val key: K val directEdges: List? val reversedEdges: List? } internal interface DirectedGraph> { val nodes: Collection fun get(key: K): N } internal class DirectedGraphMultiNode(val nodes: Set) internal class DirectedGraphCondensation(val topologicalOrder: List>) // The Kosoraju-Sharir algorithm. internal class DirectedGraphCondensationBuilder>(private val graph: DirectedGraph) { private val visited = mutableSetOf() private val order = mutableListOf() private val nodeToMultiNodeMap = mutableMapOf>() private val multiNodesOrder = mutableListOf>() fun build(): DirectedGraphCondensation { // First phase. graph.nodes.forEach { if (!visited.contains(it.key)) findOrder(it) } // Second phase. visited.clear() val multiNodes = mutableListOf>() order.reversed().forEach { if (!visited.contains(it.key)) { val nodes = mutableSetOf() paint(it, nodes) multiNodes += DirectedGraphMultiNode(nodes) } } // Topsort of built condensation. multiNodes.forEach { multiNode -> multiNode.nodes.forEach { nodeToMultiNodeMap.put(graph.get(it), multiNode) } } visited.clear() multiNodes.forEach { if (!visited.contains(it.nodes.first())) findMultiNodesOrder(it) } return DirectedGraphCondensation(multiNodesOrder.reversed()) } private fun findOrder(node: N) { visited += node.key node.directEdges?.forEach { if (!visited.contains(it)) findOrder(graph.get(it)) } order += node } private fun paint(node: N, multiNode: MutableSet) { visited += node.key multiNode += node.key node.reversedEdges?.forEach { if (!visited.contains(it)) paint(graph.get(it), multiNode) } } private fun findMultiNodesOrder(node: DirectedGraphMultiNode) { visited.addAll(node.nodes) node.nodes.forEach { graph.get(it).directEdges?.forEach { if (!visited.contains(it)) findMultiNodesOrder(nodeToMultiNodeMap[graph.get(it)]!!) } } multiNodesOrder += node } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InlineClasses.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.ir.isTopLevel import org.jetbrains.kotlin.backend.konan.descriptors.findPackage import org.jetbrains.kotlin.backend.konan.ir.containsNull import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.isPublicApi import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.packageFqName import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers import org.jetbrains.kotlin.resolve.isInlineClass import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.isNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable /** * TODO: there is [IrType::getInlinedClass] in [org.jetbrains.kotlin.ir.util] which isn't compatible with * Native's implementation. Please take a look while commonization. */ fun IrType.getInlinedClassNative(): IrClass? = IrTypeInlineClassesSupport.getInlinedClass(this) /** * TODO: there is [IrType::isInlined] in [org.jetbrains.kotlin.ir.util] which isn't compatible with * Native's implementation. Please take a look while commonization. */ fun IrType.isInlinedNative(): Boolean = IrTypeInlineClassesSupport.isInlined(this) fun IrClass.isInlined(): Boolean = IrTypeInlineClassesSupport.isInlined(this) fun IrClass.isNativePrimitiveType() = IrTypeInlineClassesSupport.isTopLevelClass(this) && KonanPrimitiveType.byFqNameParts[packageFqName]?.get(name) != null fun KotlinType.getInlinedClass(): ClassDescriptor? = KotlinTypeInlineClassesSupport.getInlinedClass(this) fun ClassDescriptor.isInlined(): Boolean = KotlinTypeInlineClassesSupport.isInlined(this) fun KotlinType.binaryRepresentationIsNullable() = KotlinTypeInlineClassesSupport.representationIsNullable(this) internal inline fun KotlinType.unwrapToPrimitiveOrReference( eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit, ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, ifReference: (type: KotlinType) -> R ): R = KotlinTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference) // TODO: consider renaming to `isReference`. fun KotlinType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null fun IrType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null fun KotlinType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? = this.computeBinaryType().primitiveBinaryTypeOrNull() fun KotlinType.computeBinaryType(): BinaryType = KotlinTypeInlineClassesSupport.computeBinaryType(this) fun IrType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? = this.computeBinaryType().primitiveBinaryTypeOrNull() fun IrType.computeBinaryType(): BinaryType = IrTypeInlineClassesSupport.computeBinaryType(this) fun IrClass.inlinedClassIsNullable(): Boolean = this.defaultType.makeNullable().getInlinedClassNative() == this // TODO: optimize fun IrClass.isUsedAsBoxClass(): Boolean = IrTypeInlineClassesSupport.isUsedAsBoxClass(this) /** * Most "underlying" user-visible non-reference type. * It is visible as inlined to compiler for simplicity. */ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.Primitive) { BOOLEAN(PrimitiveType.BOOLEAN, PrimitiveBinaryType.BOOLEAN), CHAR(PrimitiveType.CHAR, PrimitiveBinaryType.SHORT), BYTE(PrimitiveType.BYTE, PrimitiveBinaryType.BYTE), SHORT(PrimitiveType.SHORT, PrimitiveBinaryType.SHORT), INT(PrimitiveType.INT, PrimitiveBinaryType.INT), LONG(PrimitiveType.LONG, PrimitiveBinaryType.LONG), FLOAT(PrimitiveType.FLOAT, PrimitiveBinaryType.FLOAT), DOUBLE(PrimitiveType.DOUBLE, PrimitiveBinaryType.DOUBLE), NON_NULL_NATIVE_PTR(ClassId.topLevel(KonanFqNames.nonNullNativePtr.toSafe()), PrimitiveBinaryType.POINTER), VECTOR128(ClassId.topLevel(KonanFqNames.Vector128), PrimitiveBinaryType.VECTOR128) ; constructor(primitiveType: PrimitiveType, primitiveBinaryType: PrimitiveBinaryType) : this(ClassId.topLevel(primitiveType.typeFqName), primitiveBinaryType) constructor(classId: ClassId, primitiveBinaryType: PrimitiveBinaryType) : this(classId, BinaryType.Primitive(primitiveBinaryType)) val fqName: FqNameUnsafe get() = this.classId.asSingleFqName().toUnsafe() companion object { val byFqNameParts = KonanPrimitiveType.values().groupingBy { assert(!it.classId.isNestedClass) it.classId.packageFqName }.fold({ _, _ -> mutableMapOf() }, { _, accumulator, element -> accumulator.also { it[element.classId.shortClassName] = element } }) } } internal abstract class InlineClassesSupport { protected abstract fun isNullable(type: Type): Boolean protected abstract fun makeNullable(type: Type): Type protected abstract fun erase(type: Type): Class protected abstract fun computeFullErasure(type: Type): Sequence protected abstract fun hasInlineModifier(clazz: Class): Boolean protected abstract fun getNativePointedSuperclass(clazz: Class): Class? protected abstract fun getInlinedClassUnderlyingType(clazz: Class): Type protected abstract fun getPackageFqName(clazz: Class): FqName? protected abstract fun getName(clazz: Class): Name? abstract fun isTopLevelClass(clazz: Class): Boolean @JvmName("classIsInlined") fun isInlined(clazz: Class): Boolean = getInlinedClass(clazz) != null fun isInlined(type: Type): Boolean = getInlinedClass(type) != null fun isUsedAsBoxClass(clazz: Class) = getInlinedClass(clazz) == clazz // To handle NativePointed subclasses. fun getInlinedClass(type: Type): Class? = getInlinedClass(erase(type), isNullable(type)) protected fun getKonanPrimitiveType(clazz: Class): KonanPrimitiveType? = if (isTopLevelClass(clazz)) KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz)) else null protected fun isImplicitInlineClass(clazz: Class): Boolean = isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null || getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName || getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent().toSafe()) private fun getInlinedClass(erased: Class, isNullable: Boolean): Class? { val inlinedClass = getInlinedClass(erased) ?: return null return if (!isNullable || representationIsNonNullReferenceOrPointer(inlinedClass)) { inlinedClass } else { null } } tailrec fun representationIsNonNullReferenceOrPointer(clazz: Class): Boolean { val konanPrimitiveType = getKonanPrimitiveType(clazz) if (konanPrimitiveType != null) { return konanPrimitiveType == KonanPrimitiveType.NON_NULL_NATIVE_PTR } val inlinedClass = getInlinedClass(clazz) ?: return true val underlyingType = getInlinedClassUnderlyingType(inlinedClass) return if (isNullable(underlyingType)) { false } else { representationIsNonNullReferenceOrPointer(erase(underlyingType)) } } @JvmName("classGetInlinedClass") private fun getInlinedClass(clazz: Class): Class? = if (hasInlineModifier(clazz) || isImplicitInlineClass(clazz)) { clazz } else { getNativePointedSuperclass(clazz) } inline fun unwrapToPrimitiveOrReference( type: Type, eachInlinedClass: (inlinedClass: Class, nullable: Boolean) -> Unit, ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R, ifReference: (type: Type) -> R ): R { var currentType: Type = type while (true) { val inlinedClass = getInlinedClass(currentType) if (inlinedClass == null) { return ifReference(currentType) } val nullable = isNullable(currentType) getKonanPrimitiveType(inlinedClass)?.let { primitiveType -> return ifPrimitive(primitiveType, nullable) } eachInlinedClass(inlinedClass, nullable) val underlyingType = getInlinedClassUnderlyingType(inlinedClass) currentType = if (nullable) makeNullable(underlyingType) else underlyingType } } fun representationIsNullable(type: Type): Boolean { unwrapToPrimitiveOrReference( type, eachInlinedClass = { _, nullable -> if (nullable) return true }, ifPrimitive = { _, nullable -> return nullable }, ifReference = { return isNullable(it) } ) } // TODO: optimize. fun computeBinaryType(type: Type): BinaryType { val erased = erase(type) val inlinedClass = getInlinedClass(erased, isNullable(type)) ?: return createReferenceBinaryType(type) getKonanPrimitiveType(inlinedClass)?.let { return it.binaryType } val underlyingBinaryType = computeBinaryType(getInlinedClassUnderlyingType(inlinedClass)) return if (isNullable(type) && underlyingBinaryType is BinaryType.Reference) { BinaryType.Reference(underlyingBinaryType.types, true) } else { underlyingBinaryType } } private fun createReferenceBinaryType(type: Type): BinaryType.Reference = BinaryType.Reference(computeFullErasure(type), true) } internal object KotlinTypeInlineClassesSupport : InlineClassesSupport() { override fun isNullable(type: KotlinType): Boolean = type.isNullable() override fun makeNullable(type: KotlinType): KotlinType = type.makeNullable() override tailrec fun erase(type: KotlinType): ClassDescriptor { val descriptor = type.constructor.declarationDescriptor return if (descriptor is ClassDescriptor) { descriptor } else { erase(type.constructor.supertypes.first()) } } override fun computeFullErasure(type: KotlinType): Sequence { val classifier = type.constructor.declarationDescriptor return if (classifier is ClassDescriptor) sequenceOf(classifier) else type.constructor.supertypes.asSequence().flatMap { computeFullErasure(it) } } override fun hasInlineModifier(clazz: ClassDescriptor): Boolean = clazz.isInlineClass() override fun getNativePointedSuperclass(clazz: ClassDescriptor): ClassDescriptor? = clazz.getAllSuperClassifiers() .firstOrNull { it.fqNameUnsafe == InteropFqNames.nativePointed } as ClassDescriptor? override fun getInlinedClassUnderlyingType(clazz: ClassDescriptor): KotlinType = clazz.unsubstitutedPrimaryConstructor!!.valueParameters.single().type override fun getPackageFqName(clazz: ClassDescriptor) = clazz.findPackage().fqName override fun getName(clazz: ClassDescriptor) = clazz.name override fun isTopLevelClass(clazz: ClassDescriptor): Boolean = clazz.containingDeclaration is PackageFragmentDescriptor } private object IrTypeInlineClassesSupport : InlineClassesSupport() { override fun isNullable(type: IrType): Boolean = type.containsNull() override fun makeNullable(type: IrType): IrType = type.makeNullable() override tailrec fun erase(type: IrType): IrClass { val classifier = type.classifierOrFail return when (classifier) { is IrClassSymbol -> classifier.owner is IrTypeParameterSymbol -> erase(classifier.owner.superTypes.first()) else -> error(classifier) } } override fun computeFullErasure(type: IrType): Sequence { val classifier = type.classifierOrFail return when (classifier) { is IrClassSymbol -> sequenceOf(classifier.owner) is IrTypeParameterSymbol -> classifier.owner.superTypes.asSequence().flatMap { computeFullErasure(it) } else -> error(classifier) } } override fun hasInlineModifier(clazz: IrClass): Boolean = clazz.isInline override fun getNativePointedSuperclass(clazz: IrClass): IrClass? { var superClass: IrClass? = clazz while (superClass != null && (!superClass.symbol.isPublicApi || InteropIdSignatures.nativePointed != superClass.symbol.signature)) superClass = superClass.getSuperClassNotAny() return superClass } override fun getInlinedClassUnderlyingType(clazz: IrClass): IrType = clazz.constructors.firstOrNull { it.isPrimary }?.valueParameters?.single()?.type ?: clazz.declarations.filterIsInstance().single { it.backingField != null }.backingField!!.type override fun getPackageFqName(clazz: IrClass) = clazz.packageFqName override fun getName(clazz: IrClass): Name? = clazz.name override fun isTopLevelClass(clazz: IrClass): Boolean = clazz.isTopLevel } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InternalAbi.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.ir.addChild import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.llvm.llvmSymbolOrigin import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl import org.jetbrains.kotlin.ir.util.addFile import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name /** * Sometimes we need to reference symbols that are not declared in metadata. * For example, symbol might be declared during lowering. * In case of compiler caches, this means that it is not accessible as Lazy IR * and we have to explicitly add an external declaration. */ internal class InternalAbi(private val context: Context) { /** * Files that stores all internal ABI declarations. * We use per-module files so that global initializer will be stored * in the appropriate modules. * * We have to store such declarations in top-level to avoid mangling that * makes referencing harder. * A bit better solution is to add files with proper packages, but it is impossible * during FileLowering (hello, ConcurrentModificationException). */ private lateinit var internalAbiFiles: Map /** * Representation of ABI files from external modules. */ private val externalAbiFiles = mutableMapOf() fun init(modules: List) { internalAbiFiles = modules.associate { it.descriptor to createAbiFile(it) } } private fun createAbiFile(module: IrModuleFragment): IrFile = module.addFile(NaiveSourceBasedFileEntryImpl("internal"), FqName("kotlin.native.caches.abi")) /** * Adds external [function] from [module] to a list of external references. */ fun reference(function: IrFunction, module: ModuleDescriptor) { assert(function.isExternal) { "Function that represents external ABI should be marked as external" } context.llvmImports.add(module.llvmSymbolOrigin) externalAbiFiles.getOrPut(module) { createAbiFile(IrModuleFragmentImpl(module, context.irBuiltIns)) }.addChild(function) } /** * Adds [function] to a list of [module]'s publicly available symbols. */ fun declare(function: IrFunction, module: ModuleDescriptor) { internalAbiFiles.getValue(module).addChild(function) } companion object { /** * Allows to distinguish external declarations to internal ABI. */ val INTERNAL_ABI_ORIGIN = object : IrDeclarationOriginImpl("INTERNAL_ABI") {} fun getCompanionObjectAccessorName(companion: IrClass): Name = getMangledNameFor("globalAccessor", companion) fun getEnumValuesAccessorName(enum: IrClass): Name = getMangledNameFor("getValues", enum) /** * Generate name for declaration that will be a part of internal ABI. */ private fun getMangledNameFor(declarationName: String, parent: IrDeclarationParent): Name { val prefix = parent.fqNameForIrSerialization return "$prefix.$declarationName".synthesizedName } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.types.getPublicSignature import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.TypeUtils object InteropFqNames { const val cPointerName = "CPointer" const val nativePointedName = "NativePointed" val packageName = FqName("kotlinx.cinterop") val cPointer = packageName.child(Name.identifier(cPointerName)).toUnsafe() val nativePointed = packageName.child(Name.identifier(nativePointedName)).toUnsafe() } object InteropIdSignatures { val nativePointed = getPublicSignature(InteropFqNames.packageName, InteropFqNames.nativePointedName) } internal class InteropBuiltIns(builtIns: KonanBuiltIns) { val packageScope = builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope val nativePointed = packageScope.getContributedClass(InteropFqNames.nativePointedName) val cValuesRef = this.packageScope.getContributedClass("CValuesRef") val cValues = this.packageScope.getContributedClass("CValues") val cValue = this.packageScope.getContributedClass("CValue") val cOpaque = this.packageScope.getContributedClass("COpaque") val cValueWrite = this.packageScope.getContributedFunctions("write") .single { it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == cValue } val cValueRead = this.packageScope.getContributedFunctions("readValue") .single { it.valueParameters.size == 1 } val cEnum = this.packageScope.getContributedClass("CEnum") val cEnumVar = this.packageScope.getContributedClass("CEnumVar") val cStructVar = this.packageScope.getContributedClass("CStructVar") val cStructVarType = cStructVar.defaultType.memberScope.getContributedClass("Type") val cPrimitiveVar = this.packageScope.getContributedClass("CPrimitiveVar") val cPrimitiveVarType = cPrimitiveVar.defaultType.memberScope.getContributedClass("Type") val nativeMemUtils = this.packageScope.getContributedClass("nativeMemUtils") val allocType = this.packageScope.getContributedFunctions("alloc") .single { it.extensionReceiverParameter != null && it.valueParameters.singleOrNull()?.name?.toString() == "type" } val cPointer = this.packageScope.getContributedClass(InteropFqNames.cPointerName) val cPointerRawValue = cPointer.unsubstitutedMemberScope.getContributedVariables("rawValue").single() val cPointerGetRawValue = packageScope.getContributedFunctions("getRawValue").single { val extensionReceiverParameter = it.extensionReceiverParameter extensionReceiverParameter != null && TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == cPointer } val cstr = packageScope.getContributedVariables("cstr").single() val wcstr = packageScope.getContributedVariables("wcstr").single() val memScope = packageScope.getContributedClass("MemScope") val nativePointedRawPtrGetter = nativePointed.unsubstitutedMemberScope.getContributedVariables("rawPtr").single().getter!! val nativePointedGetRawPointer = packageScope.getContributedFunctions("getRawPointer").single { val extensionReceiverParameter = it.extensionReceiverParameter extensionReceiverParameter != null && TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == nativePointed } val typeOf = packageScope.getContributedFunctions("typeOf").single() private fun KonanBuiltIns.getUnsignedClass(unsignedType: UnsignedType): ClassDescriptor = this.builtInsModule.findClassAcrossModuleDependencies(unsignedType.classId)!! val objCObject = packageScope.getContributedClass("ObjCObject") val objCObjectBase = packageScope.getContributedClass("ObjCObjectBase") val allocObjCObject = packageScope.getContributedFunctions("allocObjCObject").single() val getObjCClass = packageScope.getContributedFunctions("getObjCClass").single() val objCObjectRawPtr = packageScope.getContributedFunctions("objcPtr").single() val interpretObjCPointerOrNull = packageScope.getContributedFunctions("interpretObjCPointerOrNull").single() val interpretObjCPointer = packageScope.getContributedFunctions("interpretObjCPointer").single() val interpretNullablePointed = packageScope.getContributedFunctions("interpretNullablePointed").single() val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single() val objCObjectSuperInitCheck = packageScope.getContributedFunctions("superInitCheck").single() val objCObjectInitBy = packageScope.getContributedFunctions("initBy").single() val objCAction = packageScope.getContributedClass("ObjCAction") val objCOutlet = packageScope.getContributedClass("ObjCOutlet") val objCOverrideInit = objCObjectBase.unsubstitutedMemberScope.getContributedClass("OverrideInit") val objCMethodImp = packageScope.getContributedClass("ObjCMethodImp") val exportObjCClass = packageScope.getContributedClass("ExportObjCClass") val CreateNSStringFromKString = packageScope.getContributedFunctions("CreateNSStringFromKString").single() } private fun MemberScope.getContributedVariables(name: String) = this.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) private fun MemberScope.getContributedClass(name: String): ClassDescriptor = this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) as ClassDescriptor private fun MemberScope.getContributedFunctions(name: String) = this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanBackendContext.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DefaultMapping import org.jetbrains.kotlin.backend.common.Mapping import org.jetbrains.kotlin.backend.konan.descriptors.KonanSharedVariablesManager import org.jetbrains.kotlin.backend.konan.descriptors.findPackage import org.jetbrains.kotlin.backend.konan.descriptors.kotlinNativeInternal import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.name.Name internal abstract class KonanBackendContext(val config: KonanConfig) : CommonBackendContext { abstract override val builtIns: KonanBuiltIns abstract override val ir: KonanIr override val scriptMode: Boolean = false override val sharedVariablesManager by lazy { // Creating lazily because builtIns module seems to be incomplete during `link` test; // TODO: investigate this. KonanSharedVariablesManager(this) } fun getKonanInternalClass(name: String): ClassDescriptor = builtIns.kotlinNativeInternal.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND) as ClassDescriptor fun getKonanInternalFunctions(name: String): List = builtIns.kotlinNativeInternal.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).toList() val messageCollector: MessageCollector get() = config.configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) override fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean) { val location = element?.getCompilerMessageLocation(irFile ?: error("irFile should be not null for $element")) this.messageCollector.report( if (isError) CompilerMessageSeverity.ERROR else CompilerMessageSeverity.WARNING, message, location ) } override val internalPackageFqn = KonanFqNames.internalPackageName override val mapping: Mapping = DefaultMapping() override val irFactory: IrFactory = IrFactoryImpl } internal fun IrElement.getCompilerMessageLocation(containingFile: IrFile): CompilerMessageLocation? = createCompilerMessageLocation(containingFile, this.startOffset, this.endOffset) internal fun IrBuilderWithScope.getCompilerMessageLocation(): CompilerMessageLocation? { val declaration = this.scope.scopeOwnerSymbol.owner as? IrDeclaration ?: return null val file = declaration.findPackage() as? IrFile ?: return null return createCompilerMessageLocation(file, startOffset, endOffset) } private fun createCompilerMessageLocation(containingFile: IrFile, startOffset: Int, endOffset: Int): CompilerMessageLocation? { val sourceRangeInfo = containingFile.fileEntry.getSourceRangeInfo(startOffset, endOffset) return CompilerMessageLocation.create( path = sourceRangeInfo.filePath, line = sourceRangeInfo.startLineNumber + 1, column = sourceRangeInfo.startColumnNumber + 1, lineContent = null // TODO: retrieve the line content. ) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanCompilerFrontendServices.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportLazy import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportLazyImpl import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportProblemCollector import org.jetbrains.kotlin.backend.konan.objcexport.dumpObjCHeader import org.jetbrains.kotlin.container.* import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver internal fun StorageComponentContainer.initContainer(config: KonanConfig) { useImpl() if (config.configuration.get(KonanConfigKeys.EMIT_LAZY_OBJC_HEADER_FILE) != null) { useImpl() useInstance(object : ObjCExportProblemCollector { override fun reportWarning(text: String) {} override fun reportWarning(method: FunctionDescriptor, text: String) {} override fun reportException(throwable: Throwable) = throw throwable }) useInstance(object : ObjCExportLazy.Configuration { override val frameworkName: String get() = config.moduleId override fun isIncluded(moduleInfo: ModuleInfo): Boolean = true override fun getCompilerModuleName(moduleInfo: ModuleInfo): String { TODO() } override val objcGenerics: Boolean get() = config.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS) }) } } internal fun ComponentProvider.postprocessComponents(context: Context, files: Collection) { context.frontendServices = this.get() context.config.configuration.get(KonanConfigKeys.EMIT_LAZY_OBJC_HEADER_FILE)?.let { this.get().dumpObjCHeader(files, it) } } class FrontendServices(val deprecationResolver: DeprecationResolver) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import com.intellij.openapi.project.Project import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.MetaVersion import org.jetbrains.kotlin.konan.TempFiles import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.properties.loadProperties import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.utils.addToStdlib.cast class KonanConfig(val project: Project, val configuration: CompilerConfiguration) { internal val distribution = Distribution( configuration.get(KonanConfigKeys.KONAN_HOME) ?: KonanHomeProvider.determineKonanHome(), false, configuration.get(KonanConfigKeys.RUNTIME_FILE), configuration.get(KonanConfigKeys.OVERRIDE_KONAN_PROPERTIES) ) private val platformManager = PlatformManager(distribution) internal val targetManager = platformManager.targetManager(configuration.get(KonanConfigKeys.TARGET)) internal val target = targetManager.target internal val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)!! // TODO: debug info generation mode and debug/release variant selection probably requires some refactoring. val debug: Boolean get() = configuration.getBoolean(KonanConfigKeys.DEBUG) val lightDebug: Boolean = configuration.get(KonanConfigKeys.LIGHT_DEBUG) ?: target.family.isAppleFamily // Default is true for Apple targets. val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!! val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!! val needVerifyIr: Boolean get() = configuration.get(KonanConfigKeys.VERIFY_IR) == true val needCompilerVerification: Boolean get() = configuration.get(KonanConfigKeys.VERIFY_COMPILER) ?: (configuration.getBoolean(KonanConfigKeys.OPTIMIZATION) || CompilerVersion.CURRENT.meta != MetaVersion.RELEASE) init { if (!platformManager.isEnabled(target)) { error("Target ${target.visibleName} is not available on the ${HostManager.hostName} host") } } val platform = platformManager.platform(target).apply { if (configuration.getBoolean(KonanConfigKeys.CHECK_DEPENDENCIES)) { downloadDependencies() } } internal val clang = platform.clang val indirectBranchesAreAllowed = target != KonanTarget.WASM32 val threadsAreAllowed = (target != KonanTarget.WASM32) && (target !is KonanTarget.ZEPHYR) internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!! internal val metadataKlib get() = configuration.get(KonanConfigKeys.METADATA_KLIB)!! internal val produceStaticFramework get() = configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK) internal val purgeUserLibs: Boolean get() = configuration.getBoolean(KonanConfigKeys.PURGE_USER_LIBS) internal val resolve = KonanLibrariesResolveSupport(configuration, target, distribution) internal val resolvedLibraries get() = resolve.resolvedLibraries internal val cacheSupport = CacheSupport(configuration, resolvedLibraries, target, produce) internal val cachedLibraries: CachedLibraries get() = cacheSupport.cachedLibraries internal val librariesToCache: Set get() = cacheSupport.librariesToCache val outputFiles = OutputFiles(configuration.get(KonanConfigKeys.OUTPUT) ?: cacheSupport.tryGetImplicitOutput(), target, produce) val tempFiles = TempFiles(outputFiles.outputName, configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR)) val outputFile get() = outputFiles.mainFile val moduleId: String get() = configuration.get(KonanConfigKeys.MODULE_NAME) ?: File(outputFiles.outputName).name val shortModuleName: String? get() = configuration.get(KonanConfigKeys.SHORT_MODULE_NAME) val infoArgsOnly = configuration.kotlinSourceRoots.isEmpty() && configuration[KonanConfigKeys.INCLUDED_LIBRARIES].isNullOrEmpty() && librariesToCache.isEmpty() fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List { if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.") return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).cast() } val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE) private val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty() internal val runtimeNativeLibraries: List = mutableListOf().apply { add(if (debug) "debug.bc" else "release.bc") val effectiveMemoryModel = when (memoryModel) { MemoryModel.STRICT -> MemoryModel.STRICT MemoryModel.RELAXED -> MemoryModel.RELAXED MemoryModel.EXPERIMENTAL -> { if (!target.supportsThreads()) { configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Experimental memory model requires threads, which are not supported on target ${target.name}. Used strict memory model.") MemoryModel.STRICT } else if (destroyRuntimeMode == DestroyRuntimeMode.LEGACY) { configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Experimental memory model is incompatible with 'legacy' destroy runtime mode. Used strict memory model.") MemoryModel.STRICT } else { MemoryModel.EXPERIMENTAL } } } val useMimalloc = if (configuration.get(KonanConfigKeys.ALLOCATION_MODE) == "mimalloc") { if (target.supportsMimallocAllocator()) { true } else { configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Mimalloc allocator isn't supported on target ${target.name}. Used standard mode.") false } } else { false } when (effectiveMemoryModel) { MemoryModel.STRICT -> { add("strict.bc") add("legacy_memory_manager.bc") } MemoryModel.RELAXED -> { add("relaxed.bc") add("legacy_memory_manager.bc") } MemoryModel.EXPERIMENTAL -> { add("experimental_memory_manager.bc") } } if (shouldCoverLibraries || shouldCoverSources) add("profileRuntime.bc") if (useMimalloc) { add("opt_alloc.bc") add("mimalloc.bc") } else { add("std_alloc.bc") } }.map { File(distribution.defaultNatives(target)).child(it).absolutePath } internal val launcherNativeLibraries: List = distribution.launcherFiles.map { File(distribution.defaultNatives(target)).child(it).absolutePath } internal val objCNativeLibrary: String = File(distribution.defaultNatives(target)).child("objc.bc").absolutePath internal val exceptionsSupportNativeLibrary: String = File(distribution.defaultNatives(target)).child("exceptionsSupport.bc").absolutePath internal val nativeLibraries: List = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES) internal val includeBinaries: List = configuration.getList(KonanConfigKeys.INCLUDED_BINARY_FILES) internal val languageVersionSettings = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!! internal val friendModuleFiles: Set = configuration.get(KonanConfigKeys.FRIEND_MODULES)?.map { File(it) }?.toSet() ?: emptySet() internal val manifestProperties = configuration.get(KonanConfigKeys.MANIFEST_FILE)?.let { File(it).loadProperties() } internal val isInteropStubs: Boolean get() = manifestProperties?.getProperty("interop") == "true" } fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String) = this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind class KonanConfigKeys { companion object { // Keep the list lexically sorted. val CHECK_DEPENDENCIES: CompilerConfigurationKey = CompilerConfigurationKey.create("check dependencies and download the missing ones") val DEBUG: CompilerConfigurationKey = CompilerConfigurationKey.create("add debug information") val FAKE_OVERRIDE_VALIDATOR: CompilerConfigurationKey = CompilerConfigurationKey.create("fake override validator") val DISABLED_PHASES: CompilerConfigurationKey> = CompilerConfigurationKey.create("disable backend phases") val BITCODE_EMBEDDING_MODE: CompilerConfigurationKey = CompilerConfigurationKey.create("bitcode embedding mode") val EMIT_LAZY_OBJC_HEADER_FILE: CompilerConfigurationKey = CompilerConfigurationKey.create("output file to emit lazy Obj-C header") val ENABLE_ASSERTIONS: CompilerConfigurationKey = CompilerConfigurationKey.create("enable runtime assertions in generated code") val ENABLED_PHASES: CompilerConfigurationKey> = CompilerConfigurationKey.create("enable backend phases") val ENTRY: CompilerConfigurationKey = CompilerConfigurationKey.create("fully qualified main() name") val EXPORTED_LIBRARIES: CompilerConfigurationKey> = CompilerConfigurationKey.create>("libraries included into produced framework API") val LIBRARIES_TO_CACHE: CompilerConfigurationKey> = CompilerConfigurationKey.create>("paths to libraries that to be compiled to cache") val LIBRARY_TO_ADD_TO_CACHE: CompilerConfigurationKey = CompilerConfigurationKey.create("path to library that to be added to cache") val CACHE_DIRECTORIES: CompilerConfigurationKey> = CompilerConfigurationKey.create>("paths to directories containing caches") val CACHED_LIBRARIES: CompilerConfigurationKey> = CompilerConfigurationKey.create>("mapping from library paths to cache paths") val FRAMEWORK_IMPORT_HEADERS: CompilerConfigurationKey> = CompilerConfigurationKey.create>("headers imported to framework header") val FRIEND_MODULES: CompilerConfigurationKey> = CompilerConfigurationKey.create>("friend module paths") val GENERATE_TEST_RUNNER: CompilerConfigurationKey = CompilerConfigurationKey.create("generate test runner") val INCLUDED_BINARY_FILES: CompilerConfigurationKey> = CompilerConfigurationKey.create("included binary file paths") val KONAN_HOME: CompilerConfigurationKey = CompilerConfigurationKey.create("overridden compiler distribution path") val LIBRARY_FILES: CompilerConfigurationKey> = CompilerConfigurationKey.create("library file paths") val LIBRARY_VERSION: CompilerConfigurationKey = CompilerConfigurationKey.create("library version") val LIGHT_DEBUG: CompilerConfigurationKey = CompilerConfigurationKey.create("add light debug information") val LINKER_ARGS: CompilerConfigurationKey> = CompilerConfigurationKey.create("additional linker arguments") val LIST_PHASES: CompilerConfigurationKey = CompilerConfigurationKey.create("list backend phases") val LIST_TARGETS: CompilerConfigurationKey = CompilerConfigurationKey.create("list available targets") val MANIFEST_FILE: CompilerConfigurationKey = CompilerConfigurationKey.create("provide manifest addend file") val MEMORY_MODEL: CompilerConfigurationKey = CompilerConfigurationKey.create("memory model") val META_INFO: CompilerConfigurationKey> = CompilerConfigurationKey.create("generate metadata") val METADATA_KLIB: CompilerConfigurationKey = CompilerConfigurationKey.create("metadata klib") val MODULE_KIND: CompilerConfigurationKey = CompilerConfigurationKey.create("module kind") val MODULE_NAME: CompilerConfigurationKey = CompilerConfigurationKey.create("module name") val NATIVE_LIBRARY_FILES: CompilerConfigurationKey> = CompilerConfigurationKey.create("native library file paths") val NODEFAULTLIBS: CompilerConfigurationKey = CompilerConfigurationKey.create("don't link with the default libraries") val NOENDORSEDLIBS: CompilerConfigurationKey = CompilerConfigurationKey.create("don't link with the endorsed libraries") val NOMAIN: CompilerConfigurationKey = CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries") val NOSTDLIB: CompilerConfigurationKey = CompilerConfigurationKey.create("don't link with stdlib") val NOPACK: CompilerConfigurationKey = CompilerConfigurationKey.create("don't the library into a klib file") val OPTIMIZATION: CompilerConfigurationKey = CompilerConfigurationKey.create("optimized compilation") val OUTPUT: CompilerConfigurationKey = CompilerConfigurationKey.create("program or library name") val OVERRIDE_CLANG_OPTIONS: CompilerConfigurationKey> = CompilerConfigurationKey.create("arguments for clang") val ALLOCATION_MODE: CompilerConfigurationKey = CompilerConfigurationKey.create("allocation mode") val PRINT_BITCODE: CompilerConfigurationKey = CompilerConfigurationKey.create("print bitcode") val PRINT_DESCRIPTORS: CompilerConfigurationKey = CompilerConfigurationKey.create("print descriptors") val PRINT_IR: CompilerConfigurationKey = CompilerConfigurationKey.create("print ir") val PRINT_IR_WITH_DESCRIPTORS: CompilerConfigurationKey = CompilerConfigurationKey.create("print ir with descriptors") val PRINT_LOCATIONS: CompilerConfigurationKey = CompilerConfigurationKey.create("print locations") val PRODUCE: CompilerConfigurationKey = CompilerConfigurationKey.create("compiler output kind") val PURGE_USER_LIBS: CompilerConfigurationKey = CompilerConfigurationKey.create("purge user-specified libs too") val REPOSITORIES: CompilerConfigurationKey> = CompilerConfigurationKey.create("library search path repositories") val RUNTIME_FILE: CompilerConfigurationKey = CompilerConfigurationKey.create("override default runtime file path") val INCLUDED_LIBRARIES: CompilerConfigurationKey> = CompilerConfigurationKey("klibs processed in the same manner as source files") val SOURCE_MAP: CompilerConfigurationKey> = CompilerConfigurationKey.create("generate source map") val SHORT_MODULE_NAME: CompilerConfigurationKey = CompilerConfigurationKey("short module name for IDE and export") val STATIC_FRAMEWORK: CompilerConfigurationKey = CompilerConfigurationKey.create("produce a static library for a framework") val TARGET: CompilerConfigurationKey = CompilerConfigurationKey.create("target we compile for") val TEMPORARY_FILES_DIR: CompilerConfigurationKey = CompilerConfigurationKey.create("directory for temporary files") val VERIFY_BITCODE: CompilerConfigurationKey = CompilerConfigurationKey.create("verify bitcode") val VERIFY_IR: CompilerConfigurationKey = CompilerConfigurationKey.create("verify IR") val VERIFY_COMPILER: CompilerConfigurationKey = CompilerConfigurationKey.create("verify compiler") val DEBUG_INFO_VERSION: CompilerConfigurationKey = CompilerConfigurationKey.create("debug info format version") val COVERAGE: CompilerConfigurationKey = CompilerConfigurationKey.create("emit coverage info for sources") val LIBRARIES_TO_COVER: CompilerConfigurationKey> = CompilerConfigurationKey.create("libraries that should be covered") val PROFRAW_PATH: CompilerConfigurationKey = CompilerConfigurationKey.create("path to *.profraw coverage output") val OBJC_GENERICS: CompilerConfigurationKey = CompilerConfigurationKey.create("write objc header with generics support") val DEBUG_PREFIX_MAP: CompilerConfigurationKey> = CompilerConfigurationKey.create("remap file source paths in debug info") val PRE_LINK_CACHES: CompilerConfigurationKey = CompilerConfigurationKey.create("perform compiler caches pre-link") val OVERRIDE_KONAN_PROPERTIES: CompilerConfigurationKey> = CompilerConfigurationKey.create("override konan.properties values") val DESTROY_RUNTIME_MODE: CompilerConfigurationKey = CompilerConfigurationKey.create("when to destroy runtime") } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.utils.addToStdlib.cast fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironment) { val config = konanConfig.configuration val targets = konanConfig.targetManager if (config.get(KonanConfigKeys.LIST_TARGETS) ?: false) { targets.list() } val context = Context(konanConfig) context.environment = environment context.phaseConfig.konanPhasesConfig(konanConfig) // TODO: Wrong place to call it if (konanConfig.infoArgsOnly) return try { toplevelPhase.cast>().invokeToplevel(context.phaseConfig, context, Unit) } finally { try { context.disposeLlvm() } finally { context.freeNativeMem() } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanFqNames.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name internal const val NATIVE_PTR_NAME = "NativePtr" internal const val NON_NULL_NATIVE_PTR_NAME = "NonNullNativePtr" internal const val VECTOR128 = "Vector128" object KonanFqNames { val function = FqName("kotlin.Function") val kFunction = FqName("kotlin.reflect.KFunction") val packageName = FqName("kotlin.native") val internalPackageName = FqName("kotlin.native.internal") val nativePtr = internalPackageName.child(Name.identifier(NATIVE_PTR_NAME)).toUnsafe() val nonNullNativePtr = internalPackageName.child(Name.identifier(NON_NULL_NATIVE_PTR_NAME)).toUnsafe() val Vector128 = packageName.child(Name.identifier(VECTOR128)) val throws = FqName("kotlin.Throws") val cancellationException = FqName("kotlin.coroutines.cancellation.CancellationException") val threadLocal = FqName("kotlin.native.concurrent.ThreadLocal") val sharedImmutable = FqName("kotlin.native.concurrent.SharedImmutable") val frozen = FqName("kotlin.native.internal.Frozen") val leakDetectorCandidate = FqName("kotlin.native.internal.LeakDetectorCandidate") val canBePrecreated = FqName("kotlin.native.internal.CanBePrecreated") val typedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic") val objCMethod = FqName("kotlinx.cinterop.ObjCMethod") val hasFinalizer = FqName("kotlin.native.internal.HasFinalizer") val hasFreezeHook = FqName("kotlin.native.internal.HasFreezeHook") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrariesResolveSupport.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.parseCompilerVersion import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.UnresolvedLibrary import org.jetbrains.kotlin.library.resolver.impl.libraryResolver import org.jetbrains.kotlin.library.toUnresolvedLibraries import org.jetbrains.kotlin.util.Logger import kotlin.system.exitProcess class KonanLibrariesResolveSupport( configuration: CompilerConfiguration, target: KonanTarget, distribution: Distribution ) { private val includedLibraryFiles = configuration.getList(KonanConfigKeys.INCLUDED_LIBRARIES).map { File(it) } private val librariesToCacheFiles = configuration.getList(KonanConfigKeys.LIBRARIES_TO_CACHE).map { File(it) } + configuration.get(KonanConfigKeys.LIBRARY_TO_ADD_TO_CACHE).let { if (it.isNullOrEmpty()) emptyList() else listOf(File(it)) } private val libraryNames = configuration.getList(KonanConfigKeys.LIBRARY_FILES) private val unresolvedLibraries = libraryNames.toUnresolvedLibraries private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES) private val resolverLogger = object : Logger { private val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) override fun warning(message: String)= collector.report(CompilerMessageSeverity.STRONG_WARNING, message) override fun error(message: String) = collector.report(CompilerMessageSeverity.ERROR, message) override fun log(message: String) = collector.report(CompilerMessageSeverity.LOGGING, message) override fun fatal(message: String): Nothing { collector.report(CompilerMessageSeverity.ERROR, message) (collector as? GroupingMessageCollector)?.flush() exitProcess(1) } } private val resolver = defaultResolver( repositories, libraryNames.filter { it.contains(File.separator) }, target, distribution, resolverLogger ).libraryResolver() // We pass included libraries by absolute paths to avoid repository-based resolution for them. // Strictly speaking such "direct" libraries should be specially handled by the resolver, not by KonanConfig. // But currently the resolver is in the middle of a complex refactoring so it was decided to avoid changes in its logic. // TODO: Handle included libraries in KonanLibraryResolver when it's refactored and moved into the big Kotlin repo. internal val resolvedLibraries = run { val additionalLibraryFiles = includedLibraryFiles + librariesToCacheFiles resolver.resolveWithDependencies( unresolvedLibraries + additionalLibraryFiles.map { UnresolvedLibrary(it.absolutePath, null) }, noStdLib = configuration.getBoolean(KonanConfigKeys.NOSTDLIB), noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS), noEndorsedLibs = configuration.getBoolean(KonanConfigKeys.NOENDORSEDLIBS) ) } internal val exportedLibraries = getExportedLibraries(configuration, resolvedLibraries, resolver.searchPathResolver, report = true) internal val coveredLibraries = getCoveredLibraries(configuration, resolvedLibraries, resolver.searchPathResolver) internal val includedLibraries = getIncludedLibraries(includedLibraryFiles, configuration, resolvedLibraries) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesExtractionFromInlineFunctionsLowering import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunctionsLowering import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLowering import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.konan.lower.* import org.jetbrains.kotlin.backend.konan.lower.FinallyBlocksLowering import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering import org.jetbrains.kotlin.backend.konan.lower.StringConcatenationLowering import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment private val validateAll = false private val filePhaseActions = if (validateAll) setOf(defaultDumper, ::fileValidationCallback) else setOf(defaultDumper) private val modulePhaseActions = if (validateAll) setOf(defaultDumper, ::moduleValidationCallback) else setOf(defaultDumper) private fun makeKonanFileLoweringPhase( lowering: (Context) -> FileLoweringPass, name: String, description: String, prerequisite: Set> = emptySet() ) = makeIrFilePhase(lowering, name, description, prerequisite, actions = filePhaseActions) private fun makeKonanModuleLoweringPhase( lowering: (Context) -> FileLoweringPass, name: String, description: String, prerequisite: Set> = emptySet() ) = makeIrModulePhase(lowering, name, description, prerequisite, actions = modulePhaseActions) internal fun makeKonanFileOpPhase( op: (Context, IrFile) -> Unit, name: String, description: String, prerequisite: Set> = emptySet() ) = NamedCompilerPhase( name, description, prerequisite, nlevels = 0, lower = object : SameTypeCompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrFile): IrFile { op(context, input) return input } }, actions = filePhaseActions ) internal fun makeKonanModuleOpPhase( op: (Context, IrModuleFragment) -> Unit, name: String, description: String, prerequisite: Set> = emptySet() ) = NamedCompilerPhase( name, description, prerequisite, nlevels = 0, lower = object : SameTypeCompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment { op(context, input) return input } }, actions = modulePhaseActions ) internal val specialBackendChecksPhase = konanUnitPhase( op = { irModule!!.files.forEach { SpecialBackendChecksTraversal(this).lower(it) } }, name = "SpecialBackendChecks", description = "Special backend checks" ) internal val removeExpectDeclarationsPhase = makeKonanModuleLoweringPhase( ::ExpectDeclarationsRemoving, name = "RemoveExpectDeclarations", description = "Expect declarations removing" ) internal val stripTypeAliasDeclarationsPhase = makeKonanModuleLoweringPhase( { StripTypeAliasDeclarationsLowering() }, name = "StripTypeAliasDeclarations", description = "Strip typealias declarations" ) internal val lowerBeforeInlinePhase = makeKonanModuleLoweringPhase( ::PreInlineLowering, name = "LowerBeforeInline", description = "Special operations processing before inlining" ) internal val arrayConstructorPhase = makeKonanModuleLoweringPhase( ::ArrayConstructorLowering, name = "ArrayConstructor", description = "Transform `Array(size) { index -> value }` into a loop" ) internal val lateinitPhase = makeKonanModuleOpPhase( { context, irModule -> NullableFieldsForLateinitCreationLowering(context).lower(irModule) NullableFieldsDeclarationLowering(context).lower(irModule) LateinitUsageLowering(context).lower(irModule) }, name = "Lateinit", description = "Lateinit properties lowering" ) internal val propertyAccessorInlinePhase = makeKonanModuleLoweringPhase( ::PropertyAccessorInlineLowering, name = "PropertyAccessorInline", description = "Property accessor inline lowering" ) internal val sharedVariablesPhase = makeKonanModuleLoweringPhase( ::SharedVariablesLowering, name = "SharedVariables", description = "Shared variable lowering", prerequisite = setOf(lateinitPhase) ) internal val extractLocalClassesFromInlineBodies = NamedCompilerPhase( lower = object : SameTypeCompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment { LocalClassesInInlineLambdasLowering(context).run { input.files.forEach { lower(it) } } LocalClassesInInlineFunctionsLowering(context).run { input.files.forEach { lower(it) } } LocalClassesExtractionFromInlineFunctionsLowering(context).run { input.files.forEach { lower(it) } } return input } }, name = "ExtractLocalClassesFromInlineBodies", description = "Extraction of local classes from inline bodies", prerequisite = setOf(sharedVariablesPhase), nlevels = 0, actions = modulePhaseActions ) internal val inlinePhase = NamedCompilerPhase( lower = object : SameTypeCompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment { FunctionInlining(context, NativeInlineFunctionResolver(context)).run { input.files.forEach { lower(it) } } return input } }, name = "Inline", description = "Functions inlining", prerequisite = setOf(lowerBeforeInlinePhase, arrayConstructorPhase, extractLocalClassesFromInlineBodies), nlevels = 0, actions = modulePhaseActions ) internal val lowerAfterInlinePhase = makeKonanModuleOpPhase( { context, irModule -> irModule.files.forEach(PostInlineLowering(context)::lower) // TODO: Seems like this should be deleted in PsiToIR. irModule.files.forEach(ContractsDslRemover(context)::lower) }, name = "LowerAfterInline", description = "Special operations processing after inlining" ) /* IrFile phases */ // TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase (see kotlin: dd3f8ecaacd) internal val provisionalFunctionExpressionPhase = makeKonanModuleLoweringPhase( { ProvisionalFunctionExpressionLowering() }, name = "FunctionExpression-before-inliner", description = "Transform IrFunctionExpression to a local function reference" ) internal val flattenStringConcatenationPhase = makeKonanFileLoweringPhase( ::FlattenStringConcatenationLowering, name = "FlattenStringConcatenationLowering", description = "Flatten nested string concatenation expressions into a single IrStringConcatenation" ) internal val stringConcatenationPhase = makeKonanFileLoweringPhase( ::StringConcatenationLowering, name = "StringConcatenation", description = "String concatenation lowering" ) internal val kotlinNothingValueExceptionPhase = makeKonanFileLoweringPhase( ::KotlinNothingValueExceptionLowering, name = "KotlinNothingValueException", description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'" ) internal val enumConstructorsPhase = makeKonanFileLoweringPhase( ::EnumConstructorsLowering, name = "EnumConstructors", description = "Enum constructors lowering" ) internal val initializersPhase = makeKonanFileLoweringPhase( ::InitializersLowering, name = "Initializers", description = "Initializers lowering", prerequisite = setOf(enumConstructorsPhase) ) internal val localFunctionsPhase = makeKonanFileOpPhase( op = { context, irFile -> LocalDelegatedPropertiesLowering().lower(irFile) LocalDeclarationsLowering(context).lower(irFile) LocalClassPopupLowering(context).lower(irFile) }, name = "LocalFunctions", description = "Local function lowering", prerequisite = setOf(sharedVariablesPhase) ) internal val tailrecPhase = makeKonanFileLoweringPhase( ::TailrecLowering, name = "Tailrec", description = "Tailrec lowering", prerequisite = setOf(localFunctionsPhase) ) internal val defaultParameterExtentPhase = makeKonanFileOpPhase( { context, irFile -> KonanDefaultArgumentStubGenerator(context).lower(irFile) DefaultParameterCleaner(context, replaceDefaultValuesWithStubs = true).lower(irFile) KonanDefaultParameterInjector(context).lower(irFile) }, name = "DefaultParameterExtent", description = "Default parameter extent lowering", prerequisite = setOf(tailrecPhase, enumConstructorsPhase) ) internal val innerClassPhase = makeKonanFileLoweringPhase( ::InnerClassLowering, name = "InnerClasses", description = "Inner classes lowering", prerequisite = setOf(defaultParameterExtentPhase) ) internal val rangeContainsLoweringPhase = makeKonanFileLoweringPhase( ::RangeContainsLowering, name = "RangeContains", description = "Optimizes calls to contains() for ClosedRanges" ) internal val forLoopsPhase = makeKonanFileLoweringPhase( ::ForLoopsLowering, name = "ForLoops", description = "For loops lowering" ) internal val dataClassesPhase = makeKonanFileLoweringPhase( ::DataClassOperatorsLowering, name = "DataClasses", description = "Data classes lowering" ) internal val finallyBlocksPhase = makeKonanFileLoweringPhase( ::FinallyBlocksLowering, name = "FinallyBlocks", description = "Finally blocks lowering", prerequisite = setOf(initializersPhase, localFunctionsPhase, tailrecPhase) ) internal val testProcessorPhase = makeKonanFileOpPhase( { context, irFile -> TestProcessor(context).process(irFile) }, name = "TestProcessor", description = "Unit test processor" ) internal val delegationPhase = makeKonanFileLoweringPhase( ::PropertyDelegationLowering, name = "Delegation", description = "Delegation lowering" ) internal val functionReferencePhase = makeKonanFileLoweringPhase( ::FunctionReferenceLowering, name = "FunctionReference", description = "Function references lowering", prerequisite = setOf(delegationPhase, localFunctionsPhase) // TODO: make weak dependency on `testProcessorPhase` ) internal val enumClassPhase = makeKonanFileOpPhase( { context, irFile -> EnumClassLowering(context).run(irFile) }, name = "Enums", description = "Enum classes lowering", prerequisite = setOf(enumConstructorsPhase, functionReferencePhase) // TODO: make weak dependency on `testProcessorPhase` ) internal val singleAbstractMethodPhase = makeKonanFileLoweringPhase( ::NativeSingleAbstractMethodLowering, name = "SingleAbstractMethod", description = "Replace SAM conversions with instances of interface-implementing classes", prerequisite = setOf(functionReferencePhase) ) internal val builtinOperatorPhase = makeKonanFileLoweringPhase( ::BuiltinOperatorLowering, name = "BuiltinOperators", description = "BuiltIn operators lowering", prerequisite = setOf(defaultParameterExtentPhase, singleAbstractMethodPhase) ) internal val interopPhase = makeKonanFileLoweringPhase( ::InteropLowering, name = "Interop", description = "Interop lowering", prerequisite = setOf(inlinePhase, localFunctionsPhase, functionReferencePhase) ) internal val varargPhase = makeKonanFileLoweringPhase( ::VarargInjectionLowering, name = "Vararg", description = "Vararg lowering", prerequisite = setOf(functionReferencePhase, defaultParameterExtentPhase, interopPhase) ) internal val compileTimeEvaluatePhase = makeKonanFileLoweringPhase( ::CompileTimeEvaluateLowering, name = "CompileTimeEvaluate", description = "Compile time evaluation lowering", prerequisite = setOf(varargPhase) ) internal val coroutinesPhase = makeKonanFileLoweringPhase( ::NativeSuspendFunctionsLowering, name = "Coroutines", description = "Coroutines lowering", prerequisite = setOf(localFunctionsPhase, finallyBlocksPhase, kotlinNothingValueExceptionPhase) ) internal val typeOperatorPhase = makeKonanFileLoweringPhase( ::TypeOperatorLowering, name = "TypeOperators", description = "Type operators lowering", prerequisite = setOf(coroutinesPhase) ) internal val bridgesPhase = makeKonanFileOpPhase( { context, irFile -> BridgesBuilding(context).runOnFilePostfix(irFile) WorkersBridgesBuilding(context).lower(irFile) }, name = "Bridges", description = "Bridges building", prerequisite = setOf(coroutinesPhase) ) internal val autoboxPhase = makeKonanFileLoweringPhase( ::Autoboxing, name = "Autobox", description = "Autoboxing of primitive types", prerequisite = setOf(bridgesPhase, coroutinesPhase) ) internal val returnsInsertionPhase = makeKonanFileLoweringPhase( ::ReturnsInsertionLowering, name = "ReturnsInsertion", description = "Returns insertion for Unit functions", prerequisite = setOf(autoboxPhase, coroutinesPhase, enumClassPhase) ) internal val ifNullExpressionsFusionPhase = makeKonanFileLoweringPhase( ::IfNullExpressionsFusionLowering, name = "IfNullExpressionsFusionLowering", description = "Simplify '?.' and '?:' operator chains" ) internal val foldConstantLoweringPhase = makeKonanFileOpPhase( { context, irFile -> FoldConstantLowering(context).lower(irFile) }, name = "FoldConstantLowering", description = "Constant Folding", prerequisite = setOf(flattenStringConcatenationPhase) ) internal val computeStringTrimPhase = makeKonanFileLoweringPhase( ::StringTrimLowering, name = "StringTrimLowering", description = "Compute trimIndent and trimMargin operations on constant strings" ) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanReflectionTypes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.builtins.StandardNames.KOTLIN_REFLECT_FQ_NAME import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import kotlin.reflect.KProperty class KonanReflectionTypes(module: ModuleDescriptor, internalPackage: FqName) { private val kotlinReflectScope: MemberScope by lazy(LazyThreadSafetyMode.PUBLICATION) { module.getPackage(KOTLIN_REFLECT_FQ_NAME).memberScope } private val internalScope: MemberScope by lazy(LazyThreadSafetyMode.PUBLICATION) { module.getPackage(internalPackage).memberScope } private fun find(memberScope: MemberScope, className: String): ClassDescriptor { val name = Name.identifier(className) return memberScope.getContributedClassifier(name, NoLookupLocation.FROM_REFLECTION) as ClassDescriptor } private class ClassLookup(val memberScope: MemberScope) { operator fun getValue(types: KonanReflectionTypes, property: KProperty<*>): ClassDescriptor { return types.find(memberScope, property.name.capitalize()) } } fun getKFunction(n: Int): ClassDescriptor = find(kotlinReflectScope, "KFunction$n") fun getKSuspendFunction(n: Int): ClassDescriptor = find(kotlinReflectScope, "KSuspendFunction$n") val kProperty0: ClassDescriptor by ClassLookup(kotlinReflectScope) val kMutableProperty0: ClassDescriptor by ClassLookup(kotlinReflectScope) val kMutableProperty1: ClassDescriptor by ClassLookup(kotlinReflectScope) val kMutableProperty2: ClassDescriptor by ClassLookup(kotlinReflectScope) val kTypeProjection: ClassDescriptor by ClassLookup(kotlinReflectScope) val kType: ClassDescriptor by ClassLookup(kotlinReflectScope) val kVariance: ClassDescriptor by ClassLookup(kotlinReflectScope) val kFunctionImpl: ClassDescriptor by ClassLookup(internalScope) val kSuspendFunctionImpl: ClassDescriptor by ClassLookup(internalScope) val kProperty0Impl: ClassDescriptor by ClassLookup(internalScope) val kProperty1Impl: ClassDescriptor by ClassLookup(internalScope) val kProperty2Impl: ClassDescriptor by ClassLookup(internalScope) val kMutableProperty0Impl: ClassDescriptor by ClassLookup(internalScope) val kMutableProperty1Impl: ClassDescriptor by ClassLookup(internalScope) val kMutableProperty2Impl: ClassDescriptor by ClassLookup(internalScope) val kLocalDelegatedPropertyImpl: ClassDescriptor by ClassLookup(internalScope) val kLocalDelegatedMutablePropertyImpl: ClassDescriptor by ClassLookup(internalScope) val typeOf = kotlinReflectScope.getContributedFunctions(Name.identifier("typeOf"), NoLookupLocation.FROM_REFLECTION).single() } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.konan.KonanExternalToolFailure import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.utils.addToStdlib.cast internal fun determineLinkerOutput(context: Context): LinkerOutputKind = when (context.config.produce) { CompilerOutputKind.FRAMEWORK -> { val staticFramework = context.config.produceStaticFramework if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY } CompilerOutputKind.DYNAMIC_CACHE, CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY CompilerOutputKind.STATIC_CACHE, CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE else -> TODO("${context.config.produce} should not reach native linker stage") } // TODO: We have a Linker.kt file in the shared module. internal class Linker(val context: Context) { private val platform = context.config.platform private val config = context.config.configuration private val linkerOutput = determineLinkerOutput(context) private val linker = platform.linker private val target = context.config.target private val optimize = context.shouldOptimize() private val debug = context.config.debug || context.config.lightDebug fun link(objectFiles: List) { val nativeDependencies = context.llvm.nativeDependenciesToLink val includedBinariesLibraries = if (context.config.produce.isCache) { context.config.librariesToCache } else { nativeDependencies.filterNot { context.config.cachedLibraries.isLibraryCached(it) } } val includedBinaries = includedBinariesLibraries.map { (it as? KonanLibrary)?.includedPaths.orEmpty() }.flatten() val libraryProvidedLinkerFlags = context.llvm.allNativeDependencies.map { it.linkerOpts }.flatten() if (context.config.produce.isCache) { context.config.outputFiles.tempCacheDirectory!!.mkdirs() saveAdditionalInfoForCache() } runLinker(objectFiles, includedBinaries, libraryProvidedLinkerFlags) renameOutput() } private fun saveAdditionalInfoForCache() { saveCacheBitcodeDependencies() } private fun saveCacheBitcodeDependencies() { val outputFiles = context.config.outputFiles val bitcodeDependenciesFile = File(outputFiles.bitcodeDependenciesFile!!) val bitcodeDependencies = context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) .filter { require(it is KonanLibrary) context.llvmImports.bitcodeIsUsed(it) && it !in context.config.cacheSupport.librariesToCache // Skip loops. }.cast>() bitcodeDependenciesFile.writeLines(bitcodeDependencies.map { it.uniqueName }) } private fun renameOutput() { if (context.config.produce.isCache) { val outputFiles = context.config.outputFiles // For caches the output file is a directory. It might be created by someone else, // We have to delete it in order to the next renaming operation to succeed. java.io.File(outputFiles.mainFile).delete() if (!java.io.File(outputFiles.tempCacheDirectory!!.absolutePath).renameTo(java.io.File(outputFiles.mainFile))) outputFiles.tempCacheDirectory.deleteRecursively() } } private fun asLinkerArgs(args: List): List { if (linker.useCompilerDriverAsLinker) { return args } val result = mutableListOf() for (arg in args) { // If user passes compiler arguments to us - transform them to linker ones. if (arg.startsWith("-Wl,")) { result.addAll(arg.substring(4).split(',')) } else { result.add(arg) } } return result } private fun runLinker(objectFiles: List, includedBinaries: List, libraryProvidedLinkerFlags: List): ExecutableFile? { val additionalLinkerArgs: List val executable: String if (context.config.produce != CompilerOutputKind.FRAMEWORK) { additionalLinkerArgs = if (target.family.isAppleFamily) { when (context.config.produce) { CompilerOutputKind.DYNAMIC_CACHE -> listOf("-install_name", context.config.outputFiles.dynamicCacheInstallName) else -> listOf("-dead_strip") } } else { emptyList() } executable = context.config.outputFiles.nativeBinaryFile } else { val framework = File(context.config.outputFile) val dylibName = framework.name.removeSuffix(".framework") val dylibRelativePath = when (target.family) { Family.IOS, Family.TVOS, Family.WATCHOS -> dylibName Family.OSX -> "Versions/A/$dylibName" else -> error(target) } additionalLinkerArgs = listOf("-dead_strip", "-install_name", "@rpath/${framework.name}/$dylibRelativePath") val dylibPath = framework.child(dylibRelativePath) dylibPath.parentFile.mkdirs() executable = dylibPath.absolutePath } val needsProfileLibrary = context.coverage.enabled val mimallocEnabled = config.get(KonanConfigKeys.ALLOCATION_MODE) == "mimalloc" && target.supportsMimallocAllocator() val linkerInput = determineLinkerInput(objectFiles, linkerOutput) try { File(executable).delete() val linkerArgs = asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + BitcodeEmbedding.getLinkerOptions(context.config) + linkerInput.caches.dynamic + libraryProvidedLinkerFlags + additionalLinkerArgs val finalOutputCommands = linker.finalLinkCommands( objectFiles = linkerInput.objectFiles, executable = executable, libraries = linker.linkStaticLibraries(includedBinaries) + linkerInput.caches.static, linkerArgs = linkerArgs, optimize = optimize, debug = debug, kind = linkerOutput, outputDsymBundle = context.config.outputFiles.symbolicInfoFile, needsProfileLibrary = needsProfileLibrary, mimallocEnabled = mimallocEnabled) (linkerInput.preLinkCommands + finalOutputCommands).forEach { it.logWith(context::log) it.execute() } } catch (e: KonanExternalToolFailure) { val extraUserInfo = if (linkerInput.cachingInvolved) """ Please try to disable compiler caches and rerun the build. To disable compiler caches, add the following line to the gradle.properties file in the project's root directory: kotlin.native.cacheKind.${target.presetName}=none Also, consider filing an issue with full Gradle log here: https://kotl.in/issue """.trimIndent() else "" context.reportCompilationError("${e.toolName} invocation reported errors\n$extraUserInfo\n${e.message}") } return executable } private fun shouldPerformPreLink(caches: CachesToLink, linkerOutputKind: LinkerOutputKind): Boolean { // Pre-link is only useful when producing static library. Otherwise its just a waste of time. val isStaticLibrary = linkerOutputKind == LinkerOutputKind.STATIC_LIBRARY && context.config.produce.isFinalBinary val enabled = context.config.cacheSupport.preLinkCaches val nonEmptyCaches = caches.static.isNotEmpty() return isStaticLibrary && enabled && nonEmptyCaches } private fun determineLinkerInput(objectFiles: List, linkerOutputKind: LinkerOutputKind): LinkerInput { val caches = determineCachesToLink(context) // Since we have several linker stages that involve caching, // we should detect cache usage early to report errors correctly. val cachingInvolved = caches.static.isNotEmpty() || caches.dynamic.isNotEmpty() return when { context.config.produce == CompilerOutputKind.STATIC_CACHE -> { // Do not link static cache dependencies. LinkerInput(objectFiles, CachesToLink(emptyList(), caches.dynamic), emptyList(), cachingInvolved) } shouldPerformPreLink(caches, linkerOutputKind) -> { val preLinkResult = context.config.tempFiles.create("withStaticCaches", ".o").absolutePath val preLinkCommands = linker.preLinkCommands(objectFiles + caches.static, preLinkResult) LinkerInput(listOf(preLinkResult), CachesToLink(emptyList(), caches.dynamic), preLinkCommands, cachingInvolved) } else -> LinkerInput(objectFiles, caches, emptyList(), cachingInvolved) } } } private class LinkerInput( val objectFiles: List, val caches: CachesToLink, val preLinkCommands: List, val cachingInvolved: Boolean ) private class CachesToLink(val static: List, val dynamic: List) private fun determineCachesToLink(context: Context): CachesToLink { val staticCaches = mutableListOf() val dynamicCaches = mutableListOf() context.llvm.allCachedBitcodeDependencies.forEach { library -> val currentBinaryContainsLibrary = context.llvmModuleSpecification.containsLibrary(library) val cache = context.config.cachedLibraries.getLibraryCache(library) ?: error("Library $library is expected to be cached") // Consistency check. Generally guaranteed by implementation. if (currentBinaryContainsLibrary) error("Library ${library.libraryName} is found in both cache and current binary") val list = when (cache.kind) { CachedLibraries.Cache.Kind.DYNAMIC -> dynamicCaches CachedLibraries.Cache.Kind.STATIC -> staticCaches } list += cache.path } return CachesToLink(static = staticCaches, dynamic = dynamicCaches) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecification.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.library.KotlinLibrary /** * Defines what LLVM module should consist of. */ interface LlvmModuleSpecification { val isFinal: Boolean fun importsKotlinDeclarationsFromOtherObjectFiles(): Boolean fun importsKotlinDeclarationsFromOtherSharedLibraries(): Boolean fun containsLibrary(library: KotlinLibrary): Boolean fun containsModule(module: ModuleDescriptor): Boolean fun containsModule(module: IrModuleFragment): Boolean fun containsPackageFragment(packageFragment: IrPackageFragment): Boolean fun containsDeclaration(declaration: IrDeclaration): Boolean } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.library.KotlinLibrary internal abstract class LlvmModuleSpecificationBase(protected val cachedLibraries: CachedLibraries) : LlvmModuleSpecification { override fun importsKotlinDeclarationsFromOtherObjectFiles(): Boolean = cachedLibraries.hasStaticCaches // A bit conservative but still valid. override fun importsKotlinDeclarationsFromOtherSharedLibraries(): Boolean = cachedLibraries.hasDynamicCaches // A bit conservative but still valid. override fun containsModule(module: IrModuleFragment): Boolean = containsModule(module.descriptor) override fun containsModule(module: ModuleDescriptor): Boolean = module.konanLibrary.let { it == null || containsLibrary(it) } override fun containsPackageFragment(packageFragment: IrPackageFragment): Boolean = packageFragment.konanLibrary.let { it == null || containsLibrary(it) } override fun containsDeclaration(declaration: IrDeclaration): Boolean = declaration.konanLibrary.let { it == null || containsLibrary(it) } } internal class DefaultLlvmModuleSpecification(cachedLibraries: CachedLibraries) : LlvmModuleSpecificationBase(cachedLibraries) { override val isFinal = true override fun containsLibrary(library: KotlinLibrary): Boolean = !cachedLibraries.isLibraryCached(library) } internal class CacheLlvmModuleSpecification( cachedLibraries: CachedLibraries, private val librariesToCache: Set ) : LlvmModuleSpecificationBase(cachedLibraries) { override val isFinal = false override fun containsLibrary(library: KotlinLibrary): Boolean = library in librariesToCache } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/MemoryModel.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan enum class MemoryModel { STRICT, RELAXED, EXPERIMENTAL, } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ObjCInterop.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.konan.descriptors.findPackage import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationValueOrNull import org.jetbrains.kotlin.backend.konan.descriptors.getStringValue import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.isPublicApi import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.getPublicSignature import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition import org.jetbrains.kotlin.resolve.constants.BooleanValue import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult internal val interopPackageName = InteropFqNames.packageName internal val objCObjectFqName = interopPackageName.child(Name.identifier("ObjCObject")) internal val objCObjectIdSignature = getTopLevelPublicSignature(objCObjectFqName) private val objCClassFqName = interopPackageName.child(Name.identifier("ObjCClass")) private val objCClassIdSignature = getTopLevelPublicSignature(objCClassFqName) private val objCProtocolFqName = interopPackageName.child(Name.identifier("ObjCProtocol")) private val objCProtocolIdSignature = getTopLevelPublicSignature(objCProtocolFqName) internal val externalObjCClassFqName = interopPackageName.child(Name.identifier("ExternalObjCClass")) private val objCMethodFqName = interopPackageName.child(Name.identifier("ObjCMethod")) private val objCConstructorFqName = FqName("kotlinx.cinterop.ObjCConstructor") private val objCFactoryFqName = interopPackageName.child(Name.identifier("ObjCFactory")) private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames") private fun getTopLevelPublicSignature(fqName: FqName): IdSignature.PublicSignature = getPublicSignature(fqName.parent(), fqName.shortName().asString()) fun ClassDescriptor.isObjCClass(): Boolean = this.containingDeclaration.fqNameSafe != interopPackageName && this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } // TODO: this is not cheap. Cache me! fun KotlinType.isObjCObjectType(): Boolean = (this.supertypes() + this).any { TypeUtils.getClassDescriptor(it)?.fqNameSafe == objCObjectFqName } private fun IrClass.selfOrAnySuperClass(pred: (IrClass) -> Boolean): Boolean { if (pred(this)) return true return superTypes.any { it.classOrNull!!.owner.selfOrAnySuperClass(pred) } } internal fun IrClass.isObjCClass() = this.packageFqName != interopPackageName && selfOrAnySuperClass { it.symbol.isPublicApi && objCObjectIdSignature == it.symbol.signature } fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() && this.parentsWithSelf.filterIsInstance().any { it.annotations.findAnnotation(externalObjCClassFqName) != null } fun IrClass.isExternalObjCClass(): Boolean = this.isObjCClass() && (this as IrDeclaration).parentDeclarationsWithSelf.filterIsInstance().any { it.annotations.hasAnnotation(externalObjCClassFqName) } fun ClassDescriptor.isObjCForwardDeclaration(): Boolean = this.findPackage().fqName.startsWith(objcnamesForwardDeclarationsPackageName) fun ClassDescriptor.isObjCMetaClass(): Boolean = this.getAllSuperClassifiers().any { it.fqNameSafe == objCClassFqName } fun IrClass.isObjCMetaClass(): Boolean = selfOrAnySuperClass { it.symbol.isPublicApi && objCClassIdSignature == it.symbol.signature } fun IrClass.isObjCProtocolClass(): Boolean = symbol.isPublicApi && objCProtocolIdSignature == symbol.signature fun ClassDescriptor.isObjCProtocolClass(): Boolean = this.fqNameSafe == objCProtocolFqName fun FunctionDescriptor.isObjCClassMethod() = this.containingDeclaration.let { it is ClassDescriptor && it.isObjCClass() } fun IrFunction.isObjCClassMethod() = this.parent.let { it is IrClass && it.isObjCClass() } fun FunctionDescriptor.isExternalObjCClassMethod() = this.containingDeclaration.let { it is ClassDescriptor && it.isExternalObjCClass() } internal fun IrFunction.isExternalObjCClassMethod() = this.parent.let {it is IrClass && it.isExternalObjCClass()} // Special case: methods from Kotlin Objective-C classes can be called virtually from bridges. fun FunctionDescriptor.canObjCClassMethodBeCalledVirtually(overriddenDescriptor: FunctionDescriptor) = overriddenDescriptor.isOverridable && this.kind.isReal && !this.isExternalObjCClassMethod() internal fun IrFunction.canObjCClassMethodBeCalledVirtually(overridden: IrFunction) = overridden.isOverridable && this.origin != IrDeclarationOrigin.FAKE_OVERRIDE && !this.isExternalObjCClassMethod() fun ClassDescriptor.isKotlinObjCClass(): Boolean = this.isObjCClass() && !this.isExternalObjCClass() fun IrClass.isKotlinObjCClass(): Boolean = this.isObjCClass() && !this.isExternalObjCClass() data class ObjCMethodInfo(val selector: String, val encoding: String, val isStret: Boolean) private fun FunctionDescriptor.decodeObjCMethodAnnotation(): ObjCMethodInfo? { assert (this.kind.isReal) val methodAnnotation = this.annotations.findAnnotation(objCMethodFqName) ?: return null return objCMethodInfo(methodAnnotation) } private fun IrFunction.decodeObjCMethodAnnotation(): ObjCMethodInfo? { assert (this.isReal) val methodAnnotation = this.annotations.findAnnotation(objCMethodFqName) ?: return null return objCMethodInfo(methodAnnotation) } private fun objCMethodInfo(annotation: AnnotationDescriptor) = ObjCMethodInfo( selector = annotation.getStringValue("selector"), encoding = annotation.getStringValue("encoding"), isStret = annotation.getArgumentValueOrNull("isStret") ?: false ) private fun objCMethodInfo(annotation: IrConstructorCall) = ObjCMethodInfo( selector = annotation.getAnnotationStringValue("selector"), encoding = annotation.getAnnotationStringValue("encoding"), isStret = annotation.getAnnotationValueOrNull("isStret") ?: false ) /** * @param onlyExternal indicates whether to accept overriding methods from Kotlin classes */ private fun FunctionDescriptor.getObjCMethodInfo(onlyExternal: Boolean): ObjCMethodInfo? { if (this.kind.isReal) { this.decodeObjCMethodAnnotation()?.let { return it } if (onlyExternal) { return null } } return overriddenDescriptors.firstNotNullResult { it.getObjCMethodInfo(onlyExternal) } } /** * @param onlyExternal indicates whether to accept overriding methods from Kotlin classes */ private fun IrSimpleFunction.getObjCMethodInfo(onlyExternal: Boolean): ObjCMethodInfo? { if (this.isReal) { this.decodeObjCMethodAnnotation()?.let { return it } if (onlyExternal) { return null } } return overriddenSymbols.firstNotNullResult { it.owner.getObjCMethodInfo(onlyExternal) } } fun FunctionDescriptor.getExternalObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethodInfo(onlyExternal = true) fun IrFunction.getExternalObjCMethodInfo(): ObjCMethodInfo? = (this as? IrSimpleFunction)?.getObjCMethodInfo(onlyExternal = true) fun FunctionDescriptor.getObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethodInfo(onlyExternal = false) fun IrFunction.getObjCMethodInfo(): ObjCMethodInfo? = (this as? IrSimpleFunction)?.getObjCMethodInfo(onlyExternal = false) fun IrFunction.isObjCBridgeBased(): Boolean { assert(this.isReal) return this.annotations.hasAnnotation(objCMethodFqName) || this.annotations.hasAnnotation(objCFactoryFqName) || this.annotations.hasAnnotation(objCConstructorFqName) } /** * Describes method overriding rules for Objective-C methods. * * This class is applied at [org.jetbrains.kotlin.resolve.OverridingUtil] as configured with * `META-INF/services/org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition` resource. */ class ObjCOverridabilityCondition : ExternalOverridabilityCondition { override fun getContract() = ExternalOverridabilityCondition.Contract.BOTH override fun isOverridable( superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor? ): ExternalOverridabilityCondition.Result { if (superDescriptor.name == subDescriptor.name) { // Slow path: if (superDescriptor is FunctionDescriptor && subDescriptor is FunctionDescriptor) { superDescriptor.getExternalObjCMethodInfo()?.let { superInfo -> val subInfo = subDescriptor.getExternalObjCMethodInfo() if (subInfo != null) { // Overriding Objective-C method by Objective-C method in interop stubs. // Don't even check method signatures: return if (superInfo.selector == subInfo.selector) { ExternalOverridabilityCondition.Result.OVERRIDABLE } else { ExternalOverridabilityCondition.Result.INCOMPATIBLE } } else { // Overriding Objective-C method by Kotlin method. if (!parameterNamesMatch(superDescriptor, subDescriptor)) { return ExternalOverridabilityCondition.Result.INCOMPATIBLE } } } } else if (superDescriptor.isExternalObjCClassProperty() && subDescriptor.isExternalObjCClassProperty()) { return ExternalOverridabilityCondition.Result.OVERRIDABLE } } return ExternalOverridabilityCondition.Result.UNKNOWN } private fun CallableDescriptor.isExternalObjCClassProperty() = this is PropertyDescriptor && (this.containingDeclaration as? ClassDescriptor)?.isExternalObjCClass() == true private fun parameterNamesMatch(first: FunctionDescriptor, second: FunctionDescriptor): Boolean { // The original Objective-C method selector is represented as // function name and parameter names (except first). if (first.valueParameters.size != second.valueParameters.size) { return false } first.valueParameters.forEachIndexed { index, parameter -> if (index > 0 && parameter.name != second.valueParameters[index].name) { return false } } return true } } fun IrConstructor.objCConstructorIsDesignated(): Boolean = this.getAnnotationArgumentValue(objCConstructorFqName, "designated") ?: error("Could not find 'designated' argument") fun ConstructorDescriptor.objCConstructorIsDesignated(): Boolean { val annotation = this.annotations.findAnnotation(objCConstructorFqName)!! val value = annotation.allValueArguments[Name.identifier("designated")]!! return (value as BooleanValue).value } val IrConstructor.isObjCConstructor get() = this.annotations.hasAnnotation(objCConstructorFqName) val ConstructorDescriptor.isObjCConstructor get() = this.annotations.hasAnnotation(objCConstructorFqName) // TODO-DCE-OBJC-INIT: Selector should be preserved by DCE. fun IrConstructor.getObjCInitMethod(): IrSimpleFunction? { return this.annotations.findAnnotation(objCConstructorFqName)?.let { val initSelector = it.getAnnotationStringValue("initSelector") this.constructedClass.declarations.asSequence() .filterIsInstance() .single { it.getExternalObjCMethodInfo()?.selector == initSelector } } } fun ConstructorDescriptor.getObjCInitMethod(): FunctionDescriptor? { return this.annotations.findAnnotation(objCConstructorFqName)?.let { val initSelector = it.getAnnotationStringValue("initSelector") val memberScope = constructedClass.unsubstitutedMemberScope val functionNames = memberScope.getFunctionNames() for (name in functionNames) { val functions = memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) for (function in functions) { val objectInfo = function.getExternalObjCMethodInfo() ?: continue if (objectInfo.selector == initSelector) return function } } error("Cannot find ObjInitMethod for $this") } } val IrFunction.hasObjCFactoryAnnotation get() = this.annotations.hasAnnotation(objCFactoryFqName) val FunctionDescriptor.hasObjCFactoryAnnotation get() = this.annotations.hasAnnotation(objCFactoryFqName) val IrFunction.hasObjCMethodAnnotation get() = this.annotations.hasAnnotation(objCMethodFqName) val FunctionDescriptor.hasObjCMethodAnnotation get() = this.annotations.hasAnnotation(objCMethodFqName) fun FunctionDescriptor.getObjCFactoryInitMethodInfo(): ObjCMethodInfo? { val factoryAnnotation = this.annotations.findAnnotation(objCFactoryFqName) ?: return null return objCMethodInfo(factoryAnnotation) } fun IrFunction.getObjCFactoryInitMethodInfo(): ObjCMethodInfo? { val factoryAnnotation = this.annotations.findAnnotation(objCFactoryFqName) ?: return null return objCMethodInfo(factoryAnnotation) } fun inferObjCSelector(descriptor: FunctionDescriptor): String = if (descriptor.valueParameters.isEmpty()) { descriptor.name.asString() } else { buildString { append(descriptor.name) append(':') descriptor.valueParameters.drop(1).forEach { append(it.name) append(':') } } } fun ClassDescriptor.getExternalObjCClassBinaryName(): String = this.getExplicitExternalObjCClassBinaryName() ?: this.name.asString() fun ClassDescriptor.getExternalObjCMetaClassBinaryName(): String = this.getExplicitExternalObjCClassBinaryName() ?: this.name.asString().removeSuffix("Meta") private fun ClassDescriptor.getExplicitExternalObjCClassBinaryName() = this.annotations.findAnnotation(externalObjCClassFqName)!!.getStringValueOrNull("binaryName") ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt ================================================ package org.jetbrains.kotlin.backend.konan import kotlinx.cinterop.alloc import kotlinx.cinterop.memScoped import kotlinx.cinterop.ptr import kotlinx.cinterop.value import llvm.* import org.jetbrains.kotlin.backend.konan.llvm.makeVisibilityHiddenLikeLlvmInternalizePass import org.jetbrains.kotlin.konan.target.* private fun initializeLlvmGlobalPassRegistry() { val passRegistry = LLVMGetGlobalPassRegistry() LLVMInitializeCore(passRegistry) LLVMInitializeTransformUtils(passRegistry) LLVMInitializeScalarOpts(passRegistry) LLVMInitializeVectorization(passRegistry) LLVMInitializeInstCombine(passRegistry) LLVMInitializeIPO(passRegistry) LLVMInitializeInstrumentation(passRegistry) LLVMInitializeAnalysis(passRegistry) LLVMInitializeIPA(passRegistry) LLVMInitializeCodeGen(passRegistry) LLVMInitializeTarget(passRegistry) } internal fun shouldRunLateBitcodePasses(context: Context): Boolean { return context.coverage.enabled } internal fun runLateBitcodePasses(context: Context, llvmModule: LLVMModuleRef) { val passManager = LLVMCreatePassManager()!! LLVMKotlinAddTargetLibraryInfoWrapperPass(passManager, context.llvm.targetTriple) context.coverage.addLateLlvmPasses(passManager) LLVMRunPassManager(passManager, llvmModule) LLVMDisposePassManager(passManager) } private class LlvmPipelineConfiguration(context: Context) { private val target = context.config.target private val configurables: Configurables = context.config.platform.configurables val targetTriple: String = context.llvm.targetTriple val cpuModel: String = configurables.targetCpu ?: run { context.reportCompilationWarning("targetCpu for target $target was not set. Targeting `generic` cpu.") "generic" } val cpuFeatures: String = configurables.targetCpuFeatures ?: "" /** * Null value means that LLVM should use default inliner params * for the provided optimization and size level. */ val customInlineThreshold: Int? = when { context.shouldOptimize() -> configurables.llvmInlineThreshold?.let { it.toIntOrNull() ?: run { context.reportCompilationWarning( "`llvmInlineThreshold` should be an integer. Got `$it` instead. Using default value." ) null } } context.shouldContainDebugInfo() -> null else -> null } val optimizationLevel: LlvmOptimizationLevel = when { context.shouldOptimize() -> LlvmOptimizationLevel.AGGRESSIVE context.shouldContainDebugInfo() -> LlvmOptimizationLevel.NONE else -> LlvmOptimizationLevel.DEFAULT } val sizeLevel: LlvmSizeLevel = when { // We try to optimize code as much as possible on embedded targets. target is KonanTarget.ZEPHYR || target == KonanTarget.WASM32 -> LlvmSizeLevel.AGGRESSIVE context.shouldOptimize() -> LlvmSizeLevel.NONE context.shouldContainDebugInfo() -> LlvmSizeLevel.NONE else -> LlvmSizeLevel.NONE } val codegenOptimizationLevel: LLVMCodeGenOptLevel = when { context.shouldOptimize() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive context.shouldContainDebugInfo() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelNone else -> LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault } val relocMode: LLVMRelocMode = configurables.currentRelocationMode(context).translateToLlvmRelocMode() private fun RelocationModeFlags.Mode.translateToLlvmRelocMode() = when (this) { RelocationModeFlags.Mode.PIC -> LLVMRelocMode.LLVMRelocPIC RelocationModeFlags.Mode.STATIC -> LLVMRelocMode.LLVMRelocStatic RelocationModeFlags.Mode.DEFAULT -> LLVMRelocMode.LLVMRelocDefault } val codeModel: LLVMCodeModel = LLVMCodeModel.LLVMCodeModelDefault enum class LlvmOptimizationLevel(val value: Int) { NONE(0), DEFAULT(1), AGGRESSIVE(3) } enum class LlvmSizeLevel(val value: Int) { NONE(0), DEFAULT(1), AGGRESSIVE(2) } } internal fun runLlvmOptimizationPipeline(context: Context) { val llvmModule = context.llvmModule!! val config = LlvmPipelineConfiguration(context) context.log { """ Running LLVM optimizations with the following parameters: target_triple: ${config.targetTriple} cpu_model: ${config.cpuModel} cpu_features: ${config.cpuFeatures} optimization_level: ${config.optimizationLevel.value} size_level: ${config.sizeLevel.value} inline_threshold: ${config.customInlineThreshold ?: "default"} """.trimIndent() } memScoped { LLVMKotlinInitializeTargets() initializeLlvmGlobalPassRegistry() val passBuilder = LLVMPassManagerBuilderCreate() val modulePasses = LLVMCreatePassManager() LLVMPassManagerBuilderSetOptLevel(passBuilder, config.optimizationLevel.value) LLVMPassManagerBuilderSetSizeLevel(passBuilder, config.sizeLevel.value) // TODO: use LLVMGetTargetFromName instead. val target = alloc() val foundLlvmTarget = LLVMGetTargetFromTriple(config.targetTriple, target.ptr, null) == 0 check(foundLlvmTarget) { "Cannot get target from triple ${config.targetTriple}." } val targetMachine = LLVMCreateTargetMachine( target.value, config.targetTriple, config.cpuModel, config.cpuFeatures, config.codegenOptimizationLevel, config.relocMode, config.codeModel) LLVMKotlinAddTargetLibraryInfoWrapperPass(modulePasses, config.targetTriple) // TargetTransformInfo pass. LLVMAddAnalysisPasses(targetMachine, modulePasses) if (context.llvmModuleSpecification.isFinal) { // Since we are in a "closed world" internalization can be safely used // to reduce size of a bitcode with global dce. LLVMAddInternalizePass(modulePasses, 0) } else if (context.config.produce == CompilerOutputKind.STATIC_CACHE) { // Hidden visibility makes symbols internal when linking the binary. // When producing dynamic library, this enables stripping unused symbols from binary with -dead_strip flag, // similar to DCE enabled by internalize but later: makeVisibilityHiddenLikeLlvmInternalizePass(llvmModule) // Important for binary size, workarounds references to undefined symbols from interop libraries. } LLVMAddGlobalDCEPass(modulePasses) config.customInlineThreshold?.let { threshold -> LLVMPassManagerBuilderUseInlinerWithThreshold(passBuilder, threshold) } // Pipeline that is similar to `llvm-lto`. // TODO: Add ObjC optimization passes. LLVMPassManagerBuilderPopulateLTOPassManager(passBuilder, modulePasses, Internalize = 0, RunInliner = 1) LLVMRunPassManager(modulePasses, llvmModule) LLVMPassManagerBuilderDispose(passBuilder) LLVMDisposeTargetMachine(targetMachine) LLVMDisposePassManager(modulePasses) } if (shouldRunLateBitcodePasses(context)) { runLateBitcodePasses(context, llvmModule) } } internal fun RelocationModeFlags.currentRelocationMode(context: Context): RelocationModeFlags.Mode = when (determineLinkerOutput(context)) { LinkerOutputKind.DYNAMIC_LIBRARY -> dynamicLibraryRelocationMode LinkerOutputKind.STATIC_LIBRARY -> staticLibraryRelocationMode LinkerOutputKind.EXECUTABLE -> executableRelocationMode } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OutputFiles.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.util.prefixBaseNameIfNot import org.jetbrains.kotlin.util.removeSuffixIfPresent import org.jetbrains.kotlin.util.suffixIfNot import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.visibleName import kotlin.random.Random /** * Creates and stores terminal compiler outputs. */ class OutputFiles(outputPath: String?, target: KonanTarget, val produce: CompilerOutputKind) { private val prefix = produce.prefix(target) private val suffix = produce.suffix(target) val outputName = outputPath?.removeSuffixIfPresent(suffix) ?: produce.visibleName fun klibOutputFileName(isPacked: Boolean): String = if (isPacked) "$outputName$suffix" else outputName /** * Header file for dynamic library. */ val cAdapterHeader by lazy { File("${outputName}_api.h") } val cAdapterDef by lazy { File("${outputName}.def") } /** * Main compiler's output file. */ val mainFile = if (produce.isCache) outputName else outputName.fullOutputName() private val cacheFile = File(outputName.fullOutputName()).absoluteFile.name val dynamicCacheInstallName = File(outputName).child(cacheFile).absolutePath val tempCacheDirectory = if (produce.isCache) File(outputName + Random.nextLong().toString()) else null val nativeBinaryFile = if (produce.isCache) tempCacheDirectory!!.child(cacheFile).absolutePath else mainFile val symbolicInfoFile = "$nativeBinaryFile.dSYM" val bitcodeDependenciesFile = if (produce.isCache) tempCacheDirectory!!.child(CachedLibraries.BITCODE_DEPENDENCIES_FILE_NAME).absolutePath else null private fun String.fullOutputName() = prefixBaseNameIfNeeded(prefix).suffixIfNeeded(suffix) private fun String.prefixBaseNameIfNeeded(prefix: String) = if (produce.isCache) prefixBaseNameAlways(prefix) else prefixBaseNameIfNot(prefix) private fun String.suffixIfNeeded(prefix: String) = if (produce.isCache) suffixAlways(prefix) else suffixIfNot(prefix) private fun String.prefixBaseNameAlways(prefix: String): String { val file = File(this).absoluteFile val name = file.name val directory = file.parent return "$directory/$prefix$name" } private fun String.suffixAlways(suffix: String) = "$this$suffix" } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.backend.konan.serialization.* import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.CleanableBindingContext import org.jetbrains.kotlin.utils.DFS internal fun Context.psiToIr( symbolTable: SymbolTable, isProducingLibrary: Boolean, useLinkerWhenProducingLibrary: Boolean ) { // Translate AST to high level IR. val expectActualLinker = config.configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER)?:false val messageLogger = config.configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None val translator = Psi2IrTranslator(config.configuration.languageVersionSettings, Psi2IrConfiguration(false)) val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable) val pluginExtensions = IrGenerationExtension.getInstances(config.project) val forwardDeclarationsModuleDescriptor = moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule } val modulesWithoutDCE = moduleDescriptor.allDependencyModules .filter { !llvmModuleSpecification.isFinal && llvmModuleSpecification.containsModule(it) } // Note: using [llvmModuleSpecification] since this phase produces IR for generating single LLVM module. val exportedDependencies = (getExportedDependencies() + modulesWithoutDCE).distinct() val functionIrClassFactory = BuiltInFictitiousFunctionIrClassFactory( symbolTable, generatorContext.irBuiltIns, reflectionTypes) generatorContext.irBuiltIns.functionFactory = functionIrClassFactory val stubGenerator = DeclarationStubGeneratorImpl( moduleDescriptor, symbolTable, config.configuration.languageVersionSettings ) val symbols = KonanSymbols(this, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper, functionIrClassFactory) val irDeserializer = if (isProducingLibrary && !useLinkerWhenProducingLibrary) { // Enable lazy IR generation for newly-created symbols inside BE stubGenerator.unboundSymbolGeneration = true object : IrDeserializer { override fun getDeclaration(symbol: IrSymbol) = stubGenerator.getDeclaration(symbol) override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol { error("Should not be called") } } } else { val irProviderForCEnumsAndCStructs = IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols) val translationContext = object : TranslationPluginContext { override val moduleDescriptor: ModuleDescriptor get() = generatorContext.moduleDescriptor override val symbolTable: ReferenceSymbolTable get() = symbolTable override val typeTranslator: TypeTranslator get() = generatorContext.typeTranslator override val irBuiltIns: IrBuiltIns get() = generatorContext.irBuiltIns } KonanIrLinker( moduleDescriptor, functionIrClassFactory, translationContext, messageLogger, generatorContext.irBuiltIns, symbolTable, forwardDeclarationsModuleDescriptor, stubGenerator, irProviderForCEnumsAndCStructs, exportedDependencies, config.cachedLibraries ).also { linker -> // context.config.librariesWithDependencies could change at each iteration. var dependenciesCount = 0 while (true) { // context.config.librariesWithDependencies could change at each iteration. val dependencies = moduleDescriptor.allDependencyModules.filter { config.librariesWithDependencies(moduleDescriptor).contains(it.konanLibrary) } fun sortDependencies(dependencies: List): Collection { return DFS.topologicalOrder(dependencies) { it.allDependencyModules }.reversed() } for (dependency in sortDependencies(dependencies).filter { it != moduleDescriptor }) { val kotlinLibrary = dependency.getCapability(KlibModuleOrigin.CAPABILITY)?.let { (it as? DeserializedKlibModuleOrigin)?.library } when { isProducingLibrary -> linker.deserializeOnlyHeaderModule(dependency, kotlinLibrary) kotlinLibrary != null && config.cachedLibraries.isLibraryCached(kotlinLibrary) -> linker.deserializeHeadersWithInlineBodies(dependency, kotlinLibrary) else -> linker.deserializeIrModuleHeader(dependency, kotlinLibrary) } } if (dependencies.size == dependenciesCount) break dependenciesCount = dependencies.size } // We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable // that should be bound. modulesWithoutDCE .filter(ModuleDescriptor::isFromInteropLibrary) .forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom) translator.addPostprocessingStep { irProviderForCEnumsAndCStructs.generateBodies() } } } translator.addPostprocessingStep { module -> val pluginContext = IrPluginContextImpl( generatorContext.moduleDescriptor, generatorContext.bindingContext, generatorContext.languageVersionSettings, generatorContext.symbolTable, generatorContext.typeTranslator, generatorContext.irBuiltIns, linker = irDeserializer, diagnosticReporter = messageLogger ) pluginExtensions.forEach { extension -> extension.generate(module, pluginContext) } } expectDescriptorToSymbol = mutableMapOf() val mainModule = translator.generateModuleFragment( generatorContext, environment.getSourceFiles(), irProviders = listOf(irDeserializer), linkerExtensions = pluginExtensions, // TODO: This is a hack to allow platform libs to build in reasonable time. // referenceExpectsForUsedActuals() appears to be quadratic in time because of // how ExpectedActualResolver is implemented. // Need to fix ExpectActualResolver to either cache expects or somehow reduce the member scope searches. expectDescriptorToSymbol = if (expectActualLinker) expectDescriptorToSymbol else null ).toKonanModule() irDeserializer.postProcess() // Enable lazy IR genration for newly-created symbols inside BE stubGenerator.unboundSymbolGeneration = true symbolTable.noUnboundLeft("Unbound symbols left after linker") mainModule.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc))) val modules = if (isProducingLibrary) emptyMap() else (irDeserializer as KonanIrLinker).modules if (config.configuration.getBoolean(KonanConfigKeys.FAKE_OVERRIDE_VALIDATOR)) { val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc) modules.values.forEach { fakeOverrideChecker.check(it) } } irModule = mainModule // Note: coupled with [shouldLower] below. irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) } ir.symbols = symbols if (!isProducingLibrary) { if (this.stdlibModule in modulesWithoutDCE) functionIrClassFactory.buildAllClasses() internalAbi.init(irModules.values + irModule!!) functionIrClassFactory.module = (modules.values + irModule!!).single { it.descriptor.isNativeStdlib() } } mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) } modules.values.forEach { module -> module.files.forEach { it.metadata = KonanFileMetadataSource(module as KonanIrModuleFragmentImpl) } } val originalBindingContext = bindingContext as? CleanableBindingContext ?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext") originalBindingContext.clear() this.bindingContext = BindingContext.EMPTY } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Reporting.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.render internal fun CommonBackendContext.reportCompilationError(message: String, irFile: IrFile, irElement: IrElement): Nothing { report(irElement, irFile, message, true) throw KonanCompilationException() } internal fun CommonBackendContext.reportCompilationError(message: String): Nothing { report(null, null, message, true) throw KonanCompilationException() } internal fun CompilerConfiguration.reportCompilationError(message: String): Nothing { report(CompilerMessageSeverity.ERROR, message) throw KonanCompilationException() } internal fun CommonBackendContext.reportCompilationWarning(message: String) { report(null, null, message, false) } internal fun error(irFile: IrFile?, element: IrElement?, message: String): Nothing { error(renderCompilerError(irFile, element, message)) } internal fun renderCompilerError(irFile: IrFile?, element: IrElement?, message: String) = buildString { append("Internal compiler error: $message\n") if (element == null) { append("(IR element is null)") } else { if (irFile != null) { val location = element.getCompilerMessageLocation(irFile) append("at $location\n") } val renderedElement = try { element.render() } catch (e: Throwable) { "(unable to render IR element)" } append(renderedElement) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/RuntimeNames.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.name.FqName object RuntimeNames { val symbolNameAnnotation = FqName("kotlin.native.SymbolName") val cnameAnnotation = FqName("kotlin.native.CName") val frozenAnnotation = FqName("kotlin.native.internal.Frozen") val exportForCppRuntime = FqName("kotlin.native.internal.ExportForCppRuntime") val exportForCompilerAnnotation = FqName("kotlin.native.internal.ExportForCompiler") val exportTypeInfoAnnotation = FqName("kotlin.native.internal.ExportTypeInfo") val cCall = FqName("kotlinx.cinterop.internal.CCall") val cStructMemberAt = FqName("kotlinx.cinterop.internal.CStruct.MemberAt") val cStructArrayMemberAt = FqName("kotlinx.cinterop.internal.CStruct.ArrayMemberAt") val cStructBitField = FqName("kotlinx.cinterop.internal.CStruct.BitField") val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod") val objCMethodImp = FqName("kotlinx.cinterop.ObjCMethodImp") val independent = FqName("kotlin.native.internal.Independent") val filterExceptions = FqName("kotlin.native.internal.FilterExceptions") val kotlinNativeInternalPackageName = FqName.fromSegments(listOf("kotlin", "native", "internal")) val associatedObjectKey = FqName("kotlin.reflect.AssociatedObjectKey") val typedIntrinsicAnnotation = FqName("kotlin.native.internal.TypedIntrinsic") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TestRunnerKind.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan enum class TestRunnerKind { NONE, MAIN_THREAD, WORKER, MAIN_THREAD_NO_EXIT } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.context.MutableModuleContextImpl import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.util.KlibMetadataFactories import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory import org.jetbrains.kotlin.serialization.konan.KotlinResolvedModuleDescriptors import org.jetbrains.kotlin.storage.StorageManager internal object TopDownAnalyzerFacadeForKonan { fun analyzeFiles(files: Collection, context: Context): AnalysisResult { val config = context.config val moduleName = Name.special("<${config.moduleId}>") val projectContext = ProjectContext(config.project, "TopDownAnalyzer for Konan") val module = NativeFactories.DefaultDescriptorFactory.createDescriptorAndNewBuiltIns( moduleName, projectContext.storageManager, origin = CurrentKlibModuleOrigin) val moduleContext = MutableModuleContextImpl(module, projectContext) val resolvedDependencies = ResolvedDependencies( config.resolvedLibraries, projectContext.storageManager, module.builtIns, config.languageVersionSettings, config.friendModuleFiles, module ) val additionalPackages = mutableListOf() if (!module.isNativeStdlib()) { val dependencies = listOf(module) + resolvedDependencies.moduleDescriptors.resolvedDescriptors + resolvedDependencies.moduleDescriptors.forwardDeclarationsModule module.setDependencies(dependencies, resolvedDependencies.friends) } else { assert (resolvedDependencies.moduleDescriptors.resolvedDescriptors.isEmpty()) moduleContext.setDependencies(module) // [K][Suspend]FunctionN belong to stdlib. additionalPackages += functionInterfacePackageFragmentProvider(projectContext.storageManager, module) } return analyzeFilesWithGivenTrace(files, BindingTraceContext(), moduleContext, context, additionalPackages) } fun analyzeFilesWithGivenTrace( files: Collection, trace: BindingTrace, moduleContext: ModuleContext, context: Context, additionalPackages: List = emptyList() ): AnalysisResult { // we print out each file we compile if frontend phase is verbose files.takeIf { frontendPhase in context.phaseConfig.verbose } ?.forEach(::println) val analyzerForKonan = createTopDownAnalyzerProviderForKonan( moduleContext, trace, FileBasedDeclarationProviderFactory(moduleContext.storageManager, files), context.config.configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!!, additionalPackages ) { initContainer(context.config) }.apply { postprocessComponents(context, files) }.get() analyzerForKonan.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files) return AnalysisResult.success(trace.bindingContext, moduleContext.module) } fun checkForErrors(files: Collection, bindingContext: BindingContext) { AnalyzingUtils.throwExceptionOnErrors(bindingContext) for (file in files) { AnalyzingUtils.checkForSyntacticErrors(file) } } } private class ResolvedDependencies( resolvedLibraries: KotlinLibraryResolveResult, storageManager: StorageManager, builtIns: KotlinBuiltIns, specifics: LanguageVersionSettings, friendModuleFiles: Set, currentModuleDescriptor: ModuleDescriptorImpl ) { val moduleDescriptors: KotlinResolvedModuleDescriptors val friends: Set init { val collectedFriends = mutableListOf() val customAction: (KotlinLibrary, ModuleDescriptorImpl) -> Unit = { library, moduleDescriptor -> if (friendModuleFiles.contains(library.libraryFile)) { collectedFriends.add(moduleDescriptor) } } this.moduleDescriptors = NativeFactories.DefaultResolvedDescriptorsFactory.createResolved( resolvedLibraries, storageManager, builtIns, specifics, customAction, listOf(currentModuleDescriptor)) this.friends = collectedFriends.toSet() } } val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer()) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt ================================================ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.CheckDeclarationParentsVisitor import org.jetbrains.kotlin.backend.common.IrValidator import org.jetbrains.kotlin.backend.common.IrValidatorConfig import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.serialization.* import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irGetObjectValue import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.konan.target.CompilerOutputKind internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) { if (!context.config.needVerifyIr) return val validatorConfig = IrValidatorConfig( abortOnError = false, ensureAllNodesAreDifferent = true, checkTypes = true, checkDescriptors = false ) try { module.accept(IrValidator(context, validatorConfig), null) module.accept(CheckDeclarationParentsVisitor, null) } catch (t: Throwable) { // TODO: Add reference to source. if (validatorConfig.abortOnError) throw IllegalStateException("Failed IR validation ${state.beforeOrAfter} ${state.phase}", t) else context.reportCompilationWarning("[IR VALIDATION] ${state.beforeOrAfter} ${state.phase}: ${t.message}") } } internal fun fileValidationCallback(state: ActionState, irFile: IrFile, context: Context) { val validatorConfig = IrValidatorConfig( abortOnError = false, ensureAllNodesAreDifferent = true, checkTypes = true, checkDescriptors = false ) try { irFile.accept(IrValidator(context, validatorConfig), null) irFile.accept(CheckDeclarationParentsVisitor, null) } catch (t: Throwable) { // TODO: Add reference to source. if (validatorConfig.abortOnError) throw IllegalStateException("Failed IR validation ${state.beforeOrAfter} ${state.phase}", t) else context.reportCompilationWarning("[IR VALIDATION] ${state.beforeOrAfter} ${state.phase}: ${t.message}") } } internal fun konanUnitPhase( name: String, description: String, prerequisite: Set = emptySet(), op: Context.() -> Unit ) = namedOpUnitPhase(name, description, prerequisite, op) internal val frontendPhase = konanUnitPhase( op = { val environment = environment val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector, environment.configuration.languageVersionSettings) // Build AST and binding info. analyzerWithCompilerReport.analyzeAndReport(environment.getSourceFiles()) { TopDownAnalyzerFacadeForKonan.analyzeFiles(environment.getSourceFiles(), this) } if (analyzerWithCompilerReport.hasErrors()) { throw KonanCompilationException() } moduleDescriptor = analyzerWithCompilerReport.analysisResult.moduleDescriptor bindingContext = analyzerWithCompilerReport.analysisResult.bindingContext }, name = "Frontend", description = "Frontend builds AST" ) /** * Valid from [createSymbolTablePhase] until [destroySymbolTablePhase]. */ private var Context.symbolTable: SymbolTable? by Context.nullValue() internal val createSymbolTablePhase = konanUnitPhase( op = { this.symbolTable = SymbolTable(KonanIdSignaturer(KonanManglerDesc), IrFactoryImpl) }, name = "CreateSymbolTable", description = "Create SymbolTable" ) internal val objCExportPhase = konanUnitPhase( op = { objCExport = ObjCExport(this, symbolTable!!) }, name = "ObjCExport", description = "Objective-C header generation", prerequisite = setOf(createSymbolTablePhase) ) internal val buildCExportsPhase = konanUnitPhase( op = { if (this.isNativeLibrary) { this.cAdapterGenerator = CAdapterGenerator(this).also { it.buildExports(this.symbolTable!!) } } }, name = "BuildCExports", description = "Build C exports", prerequisite = setOf(createSymbolTablePhase) ) internal val psiToIrPhase = konanUnitPhase( op = { this.psiToIr(symbolTable!!, isProducingLibrary = config.produce == CompilerOutputKind.LIBRARY, useLinkerWhenProducingLibrary = false) }, name = "Psi2Ir", description = "Psi to IR conversion and klib linkage", prerequisite = setOf(createSymbolTablePhase) ) // Coupled with [psiToIrPhase] logic above. internal fun shouldLower(context: Context, declaration: IrDeclaration): Boolean { return context.llvmModuleSpecification.containsDeclaration(declaration) } internal val destroySymbolTablePhase = konanUnitPhase( op = { this.symbolTable = null // TODO: invalidate symbolTable itself. }, name = "DestroySymbolTable", description = "Destroy SymbolTable", prerequisite = setOf(createSymbolTablePhase) ) // TODO: We copy default value expressions from expects to actuals before IR serialization, // because the current infrastructure doesn't allow us to get them at deserialization stage. // That requires some design and implementation work. internal val copyDefaultValuesToActualPhase = konanUnitPhase( op = { ExpectToActualDefaultValueCopier(irModule!!).process() }, name = "CopyDefaultValuesToActual", description = "Copy default values from expect to actual declarations" ) internal val serializerPhase = konanUnitPhase( op = { val expectActualLinker = config.configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) ?: false val messageLogger = config.configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None serializedIr = irModule?.let { ir -> KonanIrModuleSerializer( messageLogger, ir.irBuiltins, expectDescriptorToSymbol, skipExpects = !expectActualLinker ).serializedIrModule(ir) } val serializer = KlibMetadataMonolithicSerializer( this.config.configuration.languageVersionSettings, config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, config.project, !expectActualLinker, includeOnlyModuleContent = true) serializedMetadata = serializer.serializeModule(moduleDescriptor) }, name = "Serializer", description = "Serialize descriptor tree and inline IR bodies" ) internal val objectFilesPhase = konanUnitPhase( op = { compilerOutput = BitcodeCompiler(this).makeObjectFiles(bitcodeFileName) }, name = "ObjectFiles", description = "Bitcode to object file" ) internal val linkerPhase = konanUnitPhase( op = { Linker(this).link(compilerOutput) }, name = "Linker", description = "Linker" ) internal val allLoweringsPhase = NamedCompilerPhase( name = "IrLowering", description = "IR Lowering", // TODO: The lowerings before inlinePhase should be aligned with [NativeInlineFunctionResolver.kt] lower = removeExpectDeclarationsPhase then stripTypeAliasDeclarationsPhase then lowerBeforeInlinePhase then arrayConstructorPhase then lateinitPhase then sharedVariablesPhase then extractLocalClassesFromInlineBodies then inlinePhase then provisionalFunctionExpressionPhase then lowerAfterInlinePhase then performByIrFile( name = "IrLowerByFile", description = "IR Lowering by file", lower = listOf( rangeContainsLoweringPhase, forLoopsPhase, flattenStringConcatenationPhase, foldConstantLoweringPhase, computeStringTrimPhase, stringConcatenationPhase, enumConstructorsPhase, initializersPhase, localFunctionsPhase, tailrecPhase, defaultParameterExtentPhase, innerClassPhase, dataClassesPhase, ifNullExpressionsFusionPhase, testProcessorPhase, delegationPhase, functionReferencePhase, singleAbstractMethodPhase, builtinOperatorPhase, finallyBlocksPhase, enumClassPhase, interopPhase, varargPhase, compileTimeEvaluatePhase, kotlinNothingValueExceptionPhase, coroutinesPhase, typeOperatorPhase, bridgesPhase, autoboxPhase, returnsInsertionPhase, ) ), actions = setOf(defaultDumper, ::moduleValidationCallback) ) internal val dependenciesLowerPhase = NamedCompilerPhase( name = "LowerLibIR", description = "Lower library's IR", prerequisite = emptySet(), lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment { val files = mutableListOf() files += input.files input.files.clear() // TODO: KonanLibraryResolver.TopologicalLibraryOrder actually returns libraries in the reverse topological order. context.librariesWithDependencies .reversed() .forEach { val libModule = context.irModules[it.libraryName] ?: return@forEach input.files += libModule.files allLoweringsPhase.invoke(phaseConfig, phaserState, context, input) input.files.clear() } // Save all files for codegen in reverse topological order. // This guarantees that libraries initializers are emitted in correct order. context.librariesWithDependencies .forEach { val libModule = context.irModules[it.libraryName] ?: return@forEach input.files += libModule.files } input.files += files return input } }) internal val entryPointPhase = makeCustomPhase( name = "addEntryPoint", description = "Add entry point for program", prerequisite = emptySet(), op = { context, _ -> assert(context.config.produce == CompilerOutputKind.PROGRAM) val originalFile = context.ir.symbols.entryPoint!!.owner.file val originalModule = originalFile.packageFragmentDescriptor.containingDeclaration val file = if (context.llvmModuleSpecification.containsModule(originalModule)) { originalFile } else { // `main` function is compiled to other LLVM module. // For example, test running support uses `main` defined in stdlib. context.irModule!!.addFile(originalFile.fileEntry, originalFile.fqName) } require(context.llvmModuleSpecification.containsModule( file.packageFragmentDescriptor.containingDeclaration)) file.addChild(makeEntryPoint(context)) } ) internal val exportInternalAbiPhase = makeKonanModuleOpPhase( name = "exportInternalAbi", description = "Add accessors to private entities", prerequisite = emptySet(), op = { context, module -> val visitor = object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { declaration.acceptChildrenVoid(this) if (declaration.isCompanion) { val function = context.irFactory.buildFun { name = InternalAbi.getCompanionObjectAccessorName(declaration) origin = InternalAbi.INTERNAL_ABI_ORIGIN returnType = declaration.defaultType } context.createIrBuilder(function.symbol).apply { function.body = irBlockBody { +irReturn(irGetObjectValue(declaration.defaultType, declaration.symbol)) } } context.internalAbi.declare(function, declaration.module) } } } module.acceptChildrenVoid(visitor) } ) internal val useInternalAbiPhase = makeKonanModuleOpPhase( name = "useInternalAbi", description = "Use internal ABI functions to access private entities", prerequisite = emptySet(), op = { context, module -> val accessors = mutableMapOf() val transformer = object : IrElementTransformerVoid() { override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression { val irClass = expression.symbol.owner if (!irClass.isCompanion || context.llvmModuleSpecification.containsDeclaration(irClass)) { return expression } val parent = irClass.parentAsClass if (parent.isObjCClass()) { // Access to Obj-C metaclass is done via intrinsic. return expression } val accessor = accessors.getOrPut(irClass) { context.irFactory.buildFun { name = InternalAbi.getCompanionObjectAccessorName(irClass) returnType = irClass.defaultType origin = InternalAbi.INTERNAL_ABI_ORIGIN isExternal = true }.also { context.internalAbi.reference(it, irClass.module) } } return IrCallImpl(expression.startOffset, expression.endOffset, expression.type, accessor.symbol, accessor.typeParameters.size, accessor.valueParameters.size) } } module.transformChildrenVoid(transformer) } ) internal val bitcodePhase = NamedCompilerPhase( name = "Bitcode", description = "LLVM Bitcode generation", lower = contextLLVMSetupPhase then buildDFGPhase then devirtualizationPhase then redundantCoercionsCleaningPhase then dcePhase then createLLVMDeclarationsPhase then ghaPhase then RTTIPhase then generateDebugInfoHeaderPhase then propertyAccessorInlinePhase then // Have to run after link dependencies phase, because fields // from dependencies can be changed during lowerings. escapeAnalysisPhase then localEscapeAnalysisPhase then codegenPhase then finalizeDebugInfoPhase then cStubsPhase ) private val backendCodegen = namedUnitPhase( name = "Backend codegen", description = "Backend code generation", lower = takeFromContext { it.irModule!! } then allLoweringsPhase then // Lower current module first. dependenciesLowerPhase then // Then lower all libraries in topological order. // With that we guarantee that inline functions are unlowered while being inlined. entryPointPhase then exportInternalAbiPhase then useInternalAbiPhase then bitcodePhase then verifyBitcodePhase then printBitcodePhase then linkBitcodeDependenciesPhase then bitcodeOptimizationPhase then unitSink() ) // Have to hide Context as type parameter in order to expose toplevelPhase outside of this module. val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase( name = "Compiler", description = "The whole compilation process", lower = frontendPhase then createSymbolTablePhase then objCExportPhase then buildCExportsPhase then psiToIrPhase then destroySymbolTablePhase then copyDefaultValuesToActualPhase then serializerPhase then specialBackendChecksPhase then namedUnitPhase( name = "Backend", description = "All backend", lower = backendCodegen then produceOutputPhase then disposeLLVMPhase then unitSink() ) then objectFilesPhase then linkerPhase then freeNativeMemPhase ) internal fun PhaseConfig.disableIf(phase: AnyNamedPhase, condition: Boolean) { if (condition) disable(phase) } internal fun PhaseConfig.disableUnless(phase: AnyNamedPhase, condition: Boolean) { if (!condition) disable(phase) } internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) { with(config.configuration) { disable(compileTimeEvaluatePhase) disable(localEscapeAnalysisPhase) // Don't serialize anything to a final executable. disableUnless(serializerPhase, config.produce == CompilerOutputKind.LIBRARY) disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM) disableUnless(exportInternalAbiPhase, config.produce.isCache) disableIf(backendCodegen, config.produce == CompilerOutputKind.LIBRARY) disableUnless(bitcodeOptimizationPhase, config.produce.involvesLinkStage) disableUnless(linkBitcodeDependenciesPhase, config.produce.involvesLinkStage) disableUnless(objectFilesPhase, config.produce.involvesLinkStage) disableUnless(linkerPhase, config.produce.involvesLinkStage) disableIf(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) == TestRunnerKind.NONE) disableUnless(buildDFGPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(devirtualizationPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(escapeAnalysisPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) // Inline accessors only in optimized builds due to separate compilation and possibility to get broken // debug information. disableUnless(propertyAccessorInlinePhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(dcePhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(ghaPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(verifyBitcodePhase, config.needCompilerVerification || getBoolean(KonanConfigKeys.VERIFY_BITCODE)) val isDescriptorsOnlyLibrary = config.metadataKlib == true disableIf(psiToIrPhase, isDescriptorsOnlyLibrary) disableIf(destroySymbolTablePhase, isDescriptorsOnlyLibrary) disableIf(copyDefaultValuesToActualPhase, isDescriptorsOnlyLibrary) disableIf(specialBackendChecksPhase, isDescriptorsOnlyLibrary) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGen.kt ================================================ package org.jetbrains.kotlin.backend.konan.cgen import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.backend.konan.ir.getAnnotationArgumentValue import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections import org.jetbrains.kotlin.backend.konan.isObjCMetaClass import org.jetbrains.kotlin.backend.konan.lower.FunctionReferenceLowering import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions internal interface KotlinStubs { val irBuiltIns: IrBuiltIns val symbols: KonanSymbols val target: KonanTarget fun addKotlin(declaration: IrDeclaration) fun addC(lines: List) fun getUniqueCName(prefix: String): String fun getUniqueKotlinFunctionReferenceClassName(prefix: String): String fun throwCompilerError(element: IrElement?, message: String): Nothing fun renderCompilerError(element: IrElement?, message: String = "Failed requirement."): String } private class KotlinToCCallBuilder( val irBuilder: IrBuilderWithScope, val stubs: KotlinStubs, val isObjCMethod: Boolean, foreignExceptionMode: ForeignExceptionMode.Mode ) { val cBridgeName = stubs.getUniqueCName("knbridge") val symbols: KonanSymbols get() = stubs.symbols val bridgeCallBuilder = KotlinCallBuilder(irBuilder, symbols) val bridgeBuilder = KotlinCBridgeBuilder(irBuilder.startOffset, irBuilder.endOffset, cBridgeName, stubs, isKotlinToC = true, foreignExceptionMode) val cBridgeBodyLines = mutableListOf() val cCallBuilder = CCallBuilder() val cFunctionBuilder = CFunctionBuilder() } private fun KotlinToCCallBuilder.passThroughBridge(argument: IrExpression, kotlinType: IrType, cType: CType): CVariable { bridgeCallBuilder.arguments += argument return bridgeBuilder.addParameter(kotlinType, cType).second } private fun KotlinToCCallBuilder.addArgument( argument: IrExpression, type: IrType, variadic: Boolean, parameter: IrValueParameter? ) { val argumentPassing = mapCalleeFunctionParameter(type, variadic, parameter, argument) addArgument(argument, argumentPassing, variadic) } private fun KotlinToCCallBuilder.addArgument( argument: IrExpression, argumentPassing: KotlinToCArgumentPassing, variadic: Boolean ) { val cArgument = with(argumentPassing) { passValue(argument) } ?: return cCallBuilder.arguments += cArgument.expression if (!variadic) cFunctionBuilder.addParameter(cArgument.type) } private fun KotlinToCCallBuilder.buildKotlinBridgeCall(transformCall: (IrMemberAccessExpression<*>) -> IrExpression = { it }): IrExpression = bridgeCallBuilder.build( bridgeBuilder.buildKotlinBridge().also { this.stubs.addKotlin(it) }, transformCall ) internal fun KotlinStubs.generateCCall(expression: IrCall, builder: IrBuilderWithScope, isInvoke: Boolean, foreignExceptionMode: ForeignExceptionMode.Mode = ForeignExceptionMode.default): IrExpression { require(expression.dispatchReceiver == null) { renderCompilerError(expression) } val callBuilder = KotlinToCCallBuilder(builder, this, isObjCMethod = false, foreignExceptionMode) val callee = expression.symbol.owner // TODO: consider computing all arguments before converting. val targetPtrParameter: String? val targetFunctionName: String if (isInvoke) { targetPtrParameter = callBuilder.passThroughBridge( expression.extensionReceiver!!, symbols.interopCPointer.typeWithStarProjections, CTypes.voidPtr ).name targetFunctionName = "targetPtr" (0 until expression.valueArgumentsCount).forEach { callBuilder.addArgument( expression.getValueArgument(it)!!, type = expression.getTypeArgument(it)!!, variadic = false, parameter = null ) } } else { require(expression.extensionReceiver == null) { renderCompilerError(expression) } targetPtrParameter = null targetFunctionName = this.getUniqueCName("target") val arguments = (0 until expression.valueArgumentsCount).map { expression.getValueArgument(it) } callBuilder.addArguments(arguments, callee) } val returnValuePassing = if (isInvoke) { val returnType = expression.getTypeArgument(expression.typeArgumentsCount - 1)!! mapReturnType(returnType, expression, signature = null) } else { mapReturnType(callee.returnType, expression, signature = callee) } val result = callBuilder.buildCall(targetFunctionName, returnValuePassing) val targetFunctionVariable = CVariable(CTypes.pointer(callBuilder.cFunctionBuilder.getType()), targetFunctionName) if (isInvoke) { callBuilder.cBridgeBodyLines.add(0, "$targetFunctionVariable = ${targetPtrParameter!!};") } else { val cCallSymbolName = callee.getAnnotationArgumentValue(RuntimeNames.cCall, "id")!! this.addC(listOf("extern const $targetFunctionVariable __asm(\"$cCallSymbolName\");")) // Exported from cinterop stubs. } callBuilder.emitCBridge() return result } private fun KotlinToCCallBuilder.addArguments(arguments: List, callee: IrFunction) { arguments.forEachIndexed { index, argument -> val parameter = callee.valueParameters[index] if (parameter.isVararg) { require(index == arguments.lastIndex) { stubs.renderCompilerError(argument) } addVariadicArguments(argument) cFunctionBuilder.variadic = true } else { addArgument(argument!!, parameter.type, variadic = false, parameter = parameter) } } } private fun KotlinToCCallBuilder.addVariadicArguments( argumentForVarargParameter: IrExpression? ) = handleArgumentForVarargParameter(argumentForVarargParameter) { variable, elements -> if (variable == null) { unwrapVariadicArguments(elements).forEach { addArgument(it, it.type, variadic = true, parameter = null) } } else { // See comment in [handleArgumentForVarargParameter]. // Array for this vararg parameter is already computed before the call, // so query statically known typed arguments from this array. with(irBuilder) { val argumentTypes = unwrapVariadicArguments(elements).map { it.type } argumentTypes.forEachIndexed { index, type -> val untypedArgument = irCall(symbols.arrayGet[symbols.array]!!.owner).apply { dispatchReceiver = irGet(variable) putValueArgument(0, irInt(index)) } val argument = irAs(untypedArgument, type) // Note: this cast always succeeds. addArgument(argument, type, variadic = true, parameter = null) } } } } private fun KotlinToCCallBuilder.unwrapVariadicArguments( elements: List ): List = elements.flatMap { when (it) { is IrExpression -> listOf(it) is IrSpreadElement -> { val expression = it.expression require(expression is IrCall && expression.symbol == symbols.arrayOf) { stubs.renderCompilerError(it) } handleArgumentForVarargParameter(expression.getValueArgument(0)) { _, elements -> unwrapVariadicArguments(elements) } } else -> stubs.throwCompilerError(it, "unexpected IrVarargElement") } } private fun KotlinToCCallBuilder.handleArgumentForVarargParameter( argument: IrExpression?, block: (variable: IrVariable?, elements: List) -> R ): R = when (argument) { null -> block(null, emptyList()) is IrVararg -> block(null, argument.elements) is IrGetValue -> { /* This is possible when using named arguments with reordering, i.e. * * foo(second = *arrayOf(...), first = ...) * * psi2ir generates as * * val secondTmp = *arrayOf(...) * val firstTmp = ... * foo(firstTmp, secondTmp) * * **/ val variable = argument.symbol.owner if (variable is IrVariable && variable.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE && !variable.isVar) { val initializer = variable.initializer require(initializer is IrVararg) { stubs.renderCompilerError(initializer) } block(variable, initializer.elements) } else if (variable is IrValueParameter && FunctionReferenceLowering.isLoweredFunctionReference(variable)) { val location = variable.parent // Parameter itself has incorrect location. val kind = if (this.isObjCMethod) "Objective-C methods" else "C functions" stubs.throwCompilerError(location, "callable references to variadic $kind are not supported") } else { stubs.throwCompilerError(variable, "unexpected value declaration") } } else -> stubs.throwCompilerError(argument, "unexpected vararg") } private fun KotlinToCCallBuilder.emitCBridge() { val cLines = mutableListOf() cLines += "${bridgeBuilder.buildCSignature(cBridgeName)} {" cLines += cBridgeBodyLines cLines += "}" stubs.addC(cLines) } private fun KotlinToCCallBuilder.buildCall( targetFunctionName: String, returnValuePassing: ValueReturning ): IrExpression = with(returnValuePassing) { returnValue(cCallBuilder.build(targetFunctionName)) } internal sealed class ObjCCallReceiver { class Regular(val rawPtr: IrExpression) : ObjCCallReceiver() class Retained(val rawPtr: IrExpression) : ObjCCallReceiver() } internal fun KotlinStubs.generateObjCCall( builder: IrBuilderWithScope, method: IrSimpleFunction, isStret: Boolean, selector: String, call: IrFunctionAccessExpression, superQualifier: IrClassSymbol?, receiver: ObjCCallReceiver, arguments: List ) = builder.irBlock { val resolved = method.resolveFakeOverride(allowAbstract = true)?: method val exceptionMode = ForeignExceptionMode.byValue( resolved.konanLibrary?.manifestProperties ?.getProperty(ForeignExceptionMode.manifestKey) ) val callBuilder = KotlinToCCallBuilder(builder, this@generateObjCCall, isObjCMethod = true, exceptionMode) val superClass = irTemporary( superQualifier?.let { getObjCClass(symbols, it) } ?: irNullNativePtr(symbols), isMutable = true ) val messenger = irCall(if (isStret) { symbols.interopGetMessengerStret } else { symbols.interopGetMessenger }.owner).apply { putValueArgument(0, irGet(superClass)) // TODO: check superClass statically. } val targetPtrParameter = callBuilder.passThroughBridge( messenger, symbols.interopCPointer.typeWithStarProjections, CTypes.voidPtr ).name val targetFunctionName = "targetPtr" val preparedReceiver = if (method.objCConsumesReceiver()) { when (receiver) { is ObjCCallReceiver.Regular -> irCall(symbols.interopObjCRetain.owner).apply { putValueArgument(0, receiver.rawPtr) } is ObjCCallReceiver.Retained -> receiver.rawPtr } } else { when (receiver) { is ObjCCallReceiver.Regular -> receiver.rawPtr is ObjCCallReceiver.Retained -> { // Note: shall not happen: Retained is used only for alloc result currently, // which is used only as receiver for init methods, which are always receiver-consuming. // Can't even add a test for the code below. val rawPtrVar = scope.createTemporaryVariable(receiver.rawPtr) callBuilder.bridgeCallBuilder.prepare += rawPtrVar callBuilder.bridgeCallBuilder.cleanup += { irCall(symbols.interopObjCRelease).apply { putValueArgument(0, irGet(rawPtrVar)) // Balance retained pointer. } } irGet(rawPtrVar) } } } val receiverOrSuper = if (superQualifier != null) { irCall(symbols.interopCreateObjCSuperStruct.owner).apply { putValueArgument(0, preparedReceiver) putValueArgument(1, irGet(superClass)) } } else { preparedReceiver } callBuilder.cCallBuilder.arguments += callBuilder.passThroughBridge( receiverOrSuper, symbols.nativePtrType, CTypes.voidPtr).name callBuilder.cFunctionBuilder.addParameter(CTypes.voidPtr) callBuilder.cCallBuilder.arguments += "@selector($selector)" callBuilder.cFunctionBuilder.addParameter(CTypes.voidPtr) callBuilder.addArguments(arguments, method) val returnValuePassing = mapReturnType(method.returnType, call, signature = method) val result = callBuilder.buildCall(targetFunctionName, returnValuePassing) val targetFunctionVariable = CVariable(CTypes.pointer(callBuilder.cFunctionBuilder.getType()), targetFunctionName) callBuilder.cBridgeBodyLines.add(0, "$targetFunctionVariable = $targetPtrParameter;") callBuilder.emitCBridge() +result } internal fun IrBuilderWithScope.getObjCClass(symbols: KonanSymbols, symbol: IrClassSymbol): IrExpression { val classDescriptor = symbol.descriptor require(!classDescriptor.isObjCMetaClass()) return irCall(symbols.interopGetObjCClass, symbols.nativePtrType, listOf(symbol.typeWithStarProjections)) } private fun IrBuilderWithScope.irNullNativePtr(symbols: KonanSymbols) = irCall(symbols.getNativeNullPtr.owner) private class CCallbackBuilder( val stubs: KotlinStubs, val location: IrElement, val isObjCMethod: Boolean ) { val irBuiltIns: IrBuiltIns get() = stubs.irBuiltIns val symbols: KonanSymbols get() = stubs.symbols private val cBridgeName = stubs.getUniqueCName("knbridge") fun buildCBridgeCall(): String = cBridgeCallBuilder.build(cBridgeName) fun buildCBridge(): String = bridgeBuilder.buildCSignature(cBridgeName) val bridgeBuilder = KotlinCBridgeBuilder(location.startOffset, location.endOffset, cBridgeName, stubs, isKotlinToC = false) val kotlinCallBuilder = KotlinCallBuilder(bridgeBuilder.kotlinIrBuilder, symbols) val kotlinBridgeStatements = mutableListOf() val cBridgeCallBuilder = CCallBuilder() val cBodyLines = mutableListOf() val cFunctionBuilder = CFunctionBuilder() } private fun CCallbackBuilder.passThroughBridge( cBridgeArgument: String, cBridgeParameterType: CType, kotlinBridgeParameterType: IrType ): IrValueParameter { cBridgeCallBuilder.arguments += cBridgeArgument return bridgeBuilder.addParameter(kotlinBridgeParameterType, cBridgeParameterType).first } private fun CCallbackBuilder.addParameter(it: IrValueParameter, functionParameter: IrValueParameter) { val location = if (isObjCMethod) functionParameter else location require(!functionParameter.isVararg) { stubs.renderCompilerError(location) } val valuePassing = stubs.mapFunctionParameterType( it.type, retained = it.isObjCConsumed(), variadic = false, location = location ) val kotlinArgument = with(valuePassing) { receiveValue() } kotlinCallBuilder.arguments += kotlinArgument } private fun CCallbackBuilder.build(function: IrSimpleFunction, signature: IrSimpleFunction): String { val valueReturning = stubs.mapReturnType( signature.returnType, location = if (isObjCMethod) function else location, signature = signature ) buildValueReturn(function, valueReturning) return buildCFunction() } private fun CCallbackBuilder.buildValueReturn(function: IrSimpleFunction, valueReturning: ValueReturning) { val kotlinCall = kotlinCallBuilder.build(function) with(valueReturning) { returnValue(kotlinCall) } val kotlinBridge = bridgeBuilder.buildKotlinBridge() kotlinBridge.body = bridgeBuilder.kotlinIrBuilder.irBlockBody { kotlinBridgeStatements.forEach { +it } } stubs.addKotlin(kotlinBridge) stubs.addC(listOf("${buildCBridge()};")) } private fun CCallbackBuilder.buildCFunction(): String { val result = stubs.getUniqueCName("kncfun") val cLines = mutableListOf() cLines += "${cFunctionBuilder.buildSignature(result)} {" cLines += cBodyLines cLines += "}" stubs.addC(cLines) return result } private fun KotlinStubs.generateCFunction( function: IrSimpleFunction, signature: IrSimpleFunction, isObjCMethod: Boolean, location: IrElement ): String { val callbackBuilder = CCallbackBuilder(this, location, isObjCMethod) if (isObjCMethod) { val receiver = signature.dispatchReceiverParameter!! require(receiver.type.isObjCReferenceType(target, irBuiltIns)) { renderCompilerError(signature) } val valuePassing = ObjCReferenceValuePassing(symbols, receiver.type, retained = signature.objCConsumesReceiver()) val kotlinArgument = with(valuePassing) { callbackBuilder.receiveValue() } callbackBuilder.kotlinCallBuilder.arguments += kotlinArgument // Selector is ignored: with(TrivialValuePassing(symbols.nativePtrType, CTypes.voidPtr)) { callbackBuilder.receiveValue() } } else { require(signature.dispatchReceiverParameter == null) { renderCompilerError(signature) } } signature.extensionReceiverParameter?.let { callbackBuilder.addParameter(it, function.extensionReceiverParameter!!) } signature.valueParameters.forEach { callbackBuilder.addParameter(it, function.valueParameters[it.index]) } return callbackBuilder.build(function, signature) } internal fun KotlinStubs.generateCFunctionPointer( function: IrSimpleFunction, signature: IrSimpleFunction, expression: IrExpression ): IrExpression { val fakeFunction = generateCFunctionAndFakeKotlinExternalFunction( function, signature, isObjCMethod = false, location = expression ) addKotlin(fakeFunction) return IrFunctionReferenceImpl.fromSymbolDescriptor( expression.startOffset, expression.endOffset, expression.type, fakeFunction.symbol, typeArgumentsCount = 0, reflectionTarget = null ) } internal fun KotlinStubs.generateCFunctionAndFakeKotlinExternalFunction( function: IrSimpleFunction, signature: IrSimpleFunction, isObjCMethod: Boolean, location: IrElement ): IrSimpleFunction { val cFunction = generateCFunction(function, signature, isObjCMethod, location) return createFakeKotlinExternalFunction(signature, cFunction, isObjCMethod) } private fun KotlinStubs.createFakeKotlinExternalFunction( signature: IrSimpleFunction, cFunctionName: String, isObjCMethod: Boolean ): IrSimpleFunction { val bridge = IrFunctionImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), Name.identifier(cFunctionName), DescriptorVisibilities.PRIVATE, Modality.FINAL, signature.returnType, isInline = false, isExternal = true, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) bridge.annotations += buildSimpleAnnotation(irBuiltIns, UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbols.symbolName.owner, cFunctionName) if (isObjCMethod) { val methodInfo = signature.getObjCMethodInfo()!! bridge.annotations += buildSimpleAnnotation(irBuiltIns, UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbols.objCMethodImp.owner, methodInfo.selector, methodInfo.encoding) } return bridge } private fun getCStructType(kotlinClass: IrClass): CType? = kotlinClass.getCStructSpelling()?.let { CTypes.simple(it) } private fun KotlinStubs.getNamedCStructType(kotlinClass: IrClass): CType? { val cStructType = getCStructType(kotlinClass) ?: return null val name = getUniqueCName("struct") addC(listOf("typedef ${cStructType.render(name)};")) return CTypes.simple(name) } // TODO: rework Boolean support. // TODO: What should be used on watchOS? internal fun cBoolType(target: KonanTarget): CType? = when (target.family) { Family.IOS, Family.TVOS, Family.WATCHOS -> CTypes.C99Bool else -> CTypes.signedChar } private fun KotlinToCCallBuilder.mapCalleeFunctionParameter( type: IrType, variadic: Boolean, parameter: IrValueParameter?, argument: IrExpression ): KotlinToCArgumentPassing { val classifier = type.classifierOrNull return when { classifier == symbols.interopCValues || // Note: this should not be accepted, but is required for compatibility classifier == symbols.interopCValuesRef -> CValuesRefArgumentPassing classifier == symbols.string && (variadic || parameter?.isCStringParameter() == true) -> { require(!variadic || !isObjCMethod) { stubs.renderCompilerError(argument) } CStringArgumentPassing() } classifier == symbols.string && parameter?.isWCStringParameter() == true -> WCStringArgumentPassing() else -> stubs.mapFunctionParameterType( type, retained = parameter?.isObjCConsumed() ?: false, variadic = variadic, location = argument ) } } private fun KotlinStubs.mapFunctionParameterType( type: IrType, retained: Boolean, variadic: Boolean, location: IrElement ): ArgumentPassing = when { type.isUnit() && !variadic -> IgnoredUnitArgumentPassing else -> mapType(type, retained = retained, variadic = variadic, location = location) } private fun KotlinStubs.mapReturnType( type: IrType, location: IrElement, signature: IrSimpleFunction? ): ValueReturning = when { type.isUnit() -> VoidReturning else -> mapType(type, retained = signature?.objCReturnsRetained() ?: false, variadic = false, location = location) } private fun KotlinStubs.mapBlockType( type: IrType, retained: Boolean, location: IrElement ): ObjCBlockPointerValuePassing { require(type is IrSimpleType) { renderCompilerError(location) } require(type.classifier == symbols.functionN(type.arguments.size - 1)) { renderCompilerError(location) } val returnTypeArgument = type.arguments.last() require(returnTypeArgument is IrTypeProjection) { renderCompilerError(location) } require(returnTypeArgument.variance == Variance.INVARIANT) { renderCompilerError(location) } val valueReturning = mapReturnType(returnTypeArgument.type, location, null) val parameterValuePassings = type.arguments.dropLast(1).map { argument -> require(argument is IrTypeProjection) { renderCompilerError(location) } require(argument.variance == Variance.INVARIANT) { renderCompilerError(location) } mapType( argument.type, retained = false, variadic = false, location = location ) } return ObjCBlockPointerValuePassing( this, location, type, valueReturning, parameterValuePassings, retained ) } private fun KotlinStubs.mapType( type: IrType, retained: Boolean, variadic: Boolean, location: IrElement ): ValuePassing = when { type.isBoolean() -> { val cBoolType = cBoolType(target) require(cBoolType != null) { renderCompilerError(location) } BooleanValuePassing(cBoolType, irBuiltIns) } type.isByte() -> TrivialValuePassing(irBuiltIns.byteType, CTypes.signedChar) type.isShort() -> TrivialValuePassing(irBuiltIns.shortType, CTypes.short) type.isInt() -> TrivialValuePassing(irBuiltIns.intType, CTypes.int) type.isLong() -> TrivialValuePassing(irBuiltIns.longType, CTypes.longLong) type.isFloat() -> TrivialValuePassing(irBuiltIns.floatType, CTypes.float) type.isDouble() -> TrivialValuePassing(irBuiltIns.doubleType, CTypes.double) type.isCPointer(symbols) -> TrivialValuePassing(type, CTypes.voidPtr) type.isTypeOfNullLiteral() && variadic -> TrivialValuePassing(symbols.interopCPointer.typeWithStarProjections.makeNullable(), CTypes.voidPtr) type.isUByte() -> UnsignedValuePassing(type, CTypes.signedChar, CTypes.unsignedChar) type.isUShort() -> UnsignedValuePassing(type, CTypes.short, CTypes.unsignedShort) type.isUInt() -> UnsignedValuePassing(type, CTypes.int, CTypes.unsignedInt) type.isULong() -> UnsignedValuePassing(type, CTypes.longLong, CTypes.unsignedLongLong) type.isVector() -> TrivialValuePassing(type, CTypes.vector128) type.isCEnumType() -> { val enumClass = type.getClass()!! val value = enumClass.declarations .filterIsInstance() .single { it.name.asString() == "value" } CEnumValuePassing( enumClass, value, mapType(value.getter!!.returnType, retained, variadic, location) as SimpleValuePassing ) } type.isCValue(symbols) -> { require(!type.isNullable()) { renderCompilerError(location) } val kotlinClass = (type as IrSimpleType).arguments.singleOrNull()?.typeOrNull?.getClass() require(kotlinClass != null) { renderCompilerError(location) } val cStructType = getNamedCStructType(kotlinClass) require(cStructType != null) { renderCompilerError(location) } StructValuePassing(kotlinClass, cStructType) } type.classOrNull?.isSubtypeOfClass(symbols.nativePointed) == true -> { TrivialValuePassing(type, CTypes.voidPtr) } type.isFunction() -> { require(!variadic) { renderCompilerError(location) } mapBlockType(type, retained = retained, location = location) } type.isObjCReferenceType(target, irBuiltIns) -> ObjCReferenceValuePassing(symbols, type, retained = retained) else -> throwCompilerError(location, "doesn't correspond to any C type") } private class CExpression(val expression: String, val type: CType) private interface KotlinToCArgumentPassing { fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression? } private interface ValueReturning { val cType: CType fun KotlinToCCallBuilder.returnValue(expression: String): IrExpression fun CCallbackBuilder.returnValue(expression: IrExpression) } private interface ArgumentPassing : KotlinToCArgumentPassing { fun CCallbackBuilder.receiveValue(): IrExpression } private interface ValuePassing : ArgumentPassing, ValueReturning private abstract class SimpleValuePassing : ValuePassing { abstract val kotlinBridgeType: IrType abstract val cBridgeType: CType override abstract val cType: CType open val callbackParameterCType get() = cType abstract fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression open fun IrBuilderWithScope.kotlinCallbackResultToBridged(expression: IrExpression): IrExpression = kotlinToBridged(expression) abstract fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression abstract fun bridgedToC(expression: String): String abstract fun cToBridged(expression: String): String override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression { val bridgeArgument = irBuilder.kotlinToBridged(expression) val cBridgeValue = passThroughBridge(bridgeArgument, kotlinBridgeType, cBridgeType).name return CExpression(bridgedToC(cBridgeValue), cType) } override fun KotlinToCCallBuilder.returnValue(expression: String): IrExpression { cFunctionBuilder.setReturnType(cType) bridgeBuilder.setReturnType(kotlinBridgeType, cBridgeType) cBridgeBodyLines.add("return ${cToBridged(expression)};") val kotlinBridgeCall = buildKotlinBridgeCall() return irBuilder.bridgedToKotlin(kotlinBridgeCall, symbols) } override fun CCallbackBuilder.receiveValue(): IrExpression { val cParameter = cFunctionBuilder.addParameter(callbackParameterCType) val cBridgeArgument = cToBridged(cParameter.name) val kotlinParameter = passThroughBridge(cBridgeArgument, cBridgeType, kotlinBridgeType) return with(bridgeBuilder.kotlinIrBuilder) { bridgedToKotlin(irGet(kotlinParameter), symbols) } } override fun CCallbackBuilder.returnValue(expression: IrExpression) { cFunctionBuilder.setReturnType(cType) bridgeBuilder.setReturnType(kotlinBridgeType, cBridgeType) kotlinBridgeStatements += with(bridgeBuilder.kotlinIrBuilder) { irReturn(kotlinCallbackResultToBridged(expression)) } val cBridgeCall = buildCBridgeCall() cBodyLines += "return ${bridgedToC(cBridgeCall)};" } } private class TrivialValuePassing(val kotlinType: IrType, override val cType: CType) : SimpleValuePassing() { override val kotlinBridgeType: IrType get() = kotlinType override val cBridgeType: CType get() = cType override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression = expression override fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression = expression override fun bridgedToC(expression: String): String = expression override fun cToBridged(expression: String): String = expression } private class UnsignedValuePassing(val kotlinType: IrType, val cSignedType: CType, override val cType: CType) : SimpleValuePassing() { override val kotlinBridgeType: IrType get() = kotlinType override val cBridgeType: CType get() = cSignedType override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression = expression override fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression = expression override fun bridgedToC(expression: String): String = cType.cast(expression) override fun cToBridged(expression: String): String = cBridgeType.cast(expression) } private class BooleanValuePassing(override val cType: CType, private val irBuiltIns: IrBuiltIns) : SimpleValuePassing() { override val cBridgeType: CType get() = CTypes.signedChar override val kotlinBridgeType: IrType get() = irBuiltIns.byteType override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression = irIfThenElse( irBuiltIns.byteType, condition = expression, thenPart = IrConstImpl.byte(startOffset, endOffset, irBuiltIns.byteType, 1), elsePart = IrConstImpl.byte(startOffset, endOffset, irBuiltIns.byteType, 0) ) override fun IrBuilderWithScope.bridgedToKotlin( expression: IrExpression, symbols: KonanSymbols ): IrExpression = irNot(irCall(symbols.areEqualByValue[PrimitiveBinaryType.BYTE]!!.owner).apply { putValueArgument(0, expression) putValueArgument(1, IrConstImpl.byte(startOffset, endOffset, irBuiltIns.byteType, 0)) }) override fun bridgedToC(expression: String): String = cType.cast(expression) override fun cToBridged(expression: String): String = cBridgeType.cast(expression) } private class StructValuePassing(private val kotlinClass: IrClass, override val cType: CType) : ValuePassing { override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression { val cBridgeValue = passThroughBridge( cValuesRefToPointer(expression), symbols.interopCPointer.typeWithStarProjections, CTypes.pointer(cType) ).name return CExpression("*$cBridgeValue", cType) } override fun KotlinToCCallBuilder.returnValue(expression: String): IrExpression = with(irBuilder) { cFunctionBuilder.setReturnType(cType) bridgeBuilder.setReturnType(context.irBuiltIns.unitType, CTypes.void) val kotlinPointed = scope.createTemporaryVariable(irCall(symbols.interopAllocType.owner).apply { extensionReceiver = bridgeCallBuilder.getMemScope() putValueArgument(0, getTypeObject()) }) bridgeCallBuilder.prepare += kotlinPointed val cPointer = passThroughBridge(irGet(kotlinPointed), kotlinPointedType, CTypes.pointer(cType)) cBridgeBodyLines += "*${cPointer.name} = $expression;" buildKotlinBridgeCall { irBlock { at(it) +it +readCValue(irGet(kotlinPointed), symbols) } } } override fun CCallbackBuilder.receiveValue(): IrExpression = with(bridgeBuilder.kotlinIrBuilder) { val cParameter = cFunctionBuilder.addParameter(cType) val kotlinPointed = passThroughBridge("&${cParameter.name}", CTypes.voidPtr, kotlinPointedType) readCValue(irGet(kotlinPointed), symbols) } private fun IrBuilderWithScope.readCValue(kotlinPointed: IrExpression, symbols: KonanSymbols): IrExpression = irCall(symbols.interopCValueRead.owner).apply { extensionReceiver = kotlinPointed putValueArgument(0, getTypeObject()) } override fun CCallbackBuilder.returnValue(expression: IrExpression) = with(bridgeBuilder.kotlinIrBuilder) { bridgeBuilder.setReturnType(irBuiltIns.unitType, CTypes.void) cFunctionBuilder.setReturnType(cType) val result = "callbackResult" val cReturnValue = CVariable(cType, result) cBodyLines += "$cReturnValue;" val kotlinPtr = passThroughBridge("&$result", CTypes.voidPtr, symbols.nativePtrType) kotlinBridgeStatements += irCall(symbols.interopCValueWrite.owner).apply { extensionReceiver = expression putValueArgument(0, irGet(kotlinPtr)) } val cBridgeCall = buildCBridgeCall() cBodyLines += "$cBridgeCall;" cBodyLines += "return $result;" } private val kotlinPointedType: IrType get() = kotlinClass.defaultType private fun IrBuilderWithScope.getTypeObject() = irGetObject( kotlinClass.declarations.filterIsInstance() .single { it.isCompanion }.symbol ) } private class CEnumValuePassing( val enumClass: IrClass, val value: IrProperty, val baseValuePassing: SimpleValuePassing ) : SimpleValuePassing() { override val kotlinBridgeType: IrType get() = baseValuePassing.kotlinBridgeType override val cBridgeType: CType get() = baseValuePassing.cBridgeType override val cType: CType get() = baseValuePassing.cType override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression { val value = irCall(value.getter!!).apply { dispatchReceiver = expression } return with(baseValuePassing) { kotlinToBridged(value) } } override fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression { val companionClass = enumClass.declarations.filterIsInstance().single { it.isCompanion } val byValue = companionClass.simpleFunctions().single { it.name.asString() == "byValue" } return irCall(byValue).apply { dispatchReceiver = irGetObject(companionClass.symbol) putValueArgument(0, expression) } } override fun bridgedToC(expression: String): String = with(baseValuePassing) { bridgedToC(expression) } override fun cToBridged(expression: String): String = with(baseValuePassing) { cToBridged(expression) } } private class ObjCReferenceValuePassing( private val symbols: KonanSymbols, private val type: IrType, private val retained: Boolean ) : SimpleValuePassing() { override val kotlinBridgeType: IrType get() = symbols.nativePtrType override val cBridgeType: CType get() = CTypes.voidPtr override val cType: CType get() = CTypes.voidPtr override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression { val ptr = irCall(symbols.interopObjCObjectRawValueGetter.owner).apply { extensionReceiver = expression } return if (retained) { irCall(symbols.interopObjCRetain).apply { putValueArgument(0, ptr) } } else { ptr } } override fun IrBuilderWithScope.kotlinCallbackResultToBridged(expression: IrExpression): IrExpression { if (retained) return kotlinToBridged(expression) // Optimization. // Kotlin code may loose the ownership on this pointer after returning from the bridge, // so retain the pointer and autorelease it: return irCall(symbols.interopObjcRetainAutoreleaseReturnValue.owner).apply { putValueArgument(0, kotlinToBridged(expression)) } // TODO: optimize by using specialized Kotlin-to-ObjC converter. } override fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression = convertPossiblyRetainedObjCPointer(symbols, retained, expression) { irCall(symbols.interopInterpretObjCPointerOrNull, listOf(type)).apply { putValueArgument(0, it) } } override fun bridgedToC(expression: String): String = expression override fun cToBridged(expression: String): String = expression } private fun IrBuilderWithScope.convertPossiblyRetainedObjCPointer( symbols: KonanSymbols, retained: Boolean, pointer: IrExpression, convert: (IrExpression) -> IrExpression ): IrExpression = if (retained) { irBlock(startOffset, endOffset) { val ptrVar = irTemporary(pointer) val resultVar = irTemporary(convert(irGet(ptrVar))) +irCall(symbols.interopObjCRelease.owner).apply { putValueArgument(0, irGet(ptrVar)) } +irGet(resultVar) } } else { convert(pointer) } private class ObjCBlockPointerValuePassing( val stubs: KotlinStubs, private val location: IrElement, private val functionType: IrSimpleType, private val valueReturning: ValueReturning, private val parameterValuePassings: List, private val retained: Boolean ) : SimpleValuePassing() { val symbols get() = stubs.symbols override val kotlinBridgeType: IrType get() = symbols.nativePtrType override val cBridgeType: CType get() = CTypes.id override val cType: CType get() = CTypes.id /** * Callback can receive stack-allocated block. Using block type for parameter and passing it as `id` to the bridge * makes Objective-C compiler generate proper copying to heap. */ override val callbackParameterCType: CType get() = CTypes.blockPointer( CTypes.function( valueReturning.cType, parameterValuePassings.map { it.cType }, variadic = false )) override fun IrBuilderWithScope.kotlinToBridged(expression: IrExpression): IrExpression = irCall(symbols.interopCreateKotlinObjectHolder.owner).apply { putValueArgument(0, expression) } override fun IrBuilderWithScope.bridgedToKotlin(expression: IrExpression, symbols: KonanSymbols): IrExpression = irLetS(expression) { blockPointerVarSymbol -> val blockPointerVar = blockPointerVarSymbol.owner irIfThenElse( functionType.makeNullable(), condition = irCall(symbols.areEqualByValue.getValue(PrimitiveBinaryType.POINTER).owner).apply { putValueArgument(0, irGet(blockPointerVar)) putValueArgument(1, irNullNativePtr(symbols)) }, thenPart = irNull(), elsePart = convertPossiblyRetainedObjCPointer(symbols, retained, irGet(blockPointerVar)) { createKotlinFunctionObject(it) } ) } private object OBJC_BLOCK_FUNCTION_IMPL : IrDeclarationOriginImpl("OBJC_BLOCK_FUNCTION_IMPL") private fun IrBuilderWithScope.createKotlinFunctionObject(blockPointer: IrExpression): IrExpression { val constructor = generateKotlinFunctionClass() return irCall(constructor).apply { putValueArgument(0, blockPointer) } } private fun IrBuilderWithScope.generateKotlinFunctionClass(): IrConstructor { val symbols = stubs.symbols val irClass = IrClassImpl( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, IrClassSymbolImpl(), Name.identifier(stubs.getUniqueKotlinFunctionReferenceClassName("BlockFunctionImpl")), ClassKind.CLASS, DescriptorVisibilities.PRIVATE, Modality.FINAL, isCompanion = false, isInner = false, isData = false, isExternal = false, isInline = false, isExpect = false, isFun = false ) irClass.createParameterDeclarations() irClass.superTypes += stubs.irBuiltIns.anyType irClass.superTypes += functionType.makeNotNull() val blockHolderField = createField( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, stubs.irBuiltIns.anyType, Name.identifier("blockHolder"), isMutable = false, owner = irClass ) val constructor = IrConstructorImpl( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, IrConstructorSymbolImpl(), Name.special(""), DescriptorVisibilities.PUBLIC, irClass.defaultType, isInline = false, isExternal = false, isPrimary = true, isExpect = false ) irClass.addChild(constructor) val constructorParameter = IrValueParameterImpl( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, IrValueParameterSymbolImpl(), Name.identifier("blockPointer"), 0, symbols.nativePtrType, varargElementType = null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false ) constructor.valueParameters += constructorParameter constructorParameter.parent = constructor constructor.body = irBuilder(stubs.irBuiltIns, constructor.symbol).irBlockBody(startOffset, endOffset) { +irDelegatingConstructorCall(symbols.any.owner.constructors.single()) +irSetField(irGet(irClass.thisReceiver!!), blockHolderField, irCall(symbols.interopCreateObjCObjectHolder.owner).apply { putValueArgument(0, irGet(constructorParameter)) }) } val parameterCount = parameterValuePassings.size require(functionType.arguments.size == parameterCount + 1) { stubs.renderCompilerError(location) } val overriddenInvokeMethod = (functionType.classifier.owner as IrClass).simpleFunctions() .single { it.name == OperatorNameConventions.INVOKE } val invokeMethod = IrFunctionImpl( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, IrSimpleFunctionSymbolImpl(), overriddenInvokeMethod.name, DescriptorVisibilities.PUBLIC, Modality.FINAL, returnType = functionType.arguments.last().typeOrNull!!, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) invokeMethod.overriddenSymbols += overriddenInvokeMethod.symbol irClass.addChild(invokeMethod) invokeMethod.createDispatchReceiverParameter() invokeMethod.valueParameters += (0 until parameterCount).map { index -> val parameter = IrValueParameterImpl( startOffset, endOffset, OBJC_BLOCK_FUNCTION_IMPL, IrValueParameterSymbolImpl(), Name.identifier("p$index"), index, functionType.arguments[index].typeOrNull!!, varargElementType = null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false ) parameter.parent = invokeMethod parameter } invokeMethod.body = irBuilder(stubs.irBuiltIns, invokeMethod.symbol).irBlockBody(startOffset, endOffset) { val blockPointer = irCall(symbols.interopObjCObjectRawValueGetter.owner).apply { extensionReceiver = irGetField(irGet(invokeMethod.dispatchReceiverParameter!!), blockHolderField) } val arguments = (0 until parameterCount).map { index -> irGet(invokeMethod.valueParameters[index]) } +irReturn(callBlock(blockPointer, arguments)) } irClass.addFakeOverrides(stubs.irBuiltIns) stubs.addKotlin(irClass) return constructor } private fun IrBuilderWithScope.callBlock(blockPtr: IrExpression, arguments: List): IrExpression { val callBuilder = KotlinToCCallBuilder(this, stubs, isObjCMethod = false, ForeignExceptionMode.default) val rawBlockPointerParameter = callBuilder.passThroughBridge(blockPtr, blockPtr.type, CTypes.id) val blockVariableName = "block" arguments.forEachIndexed { index, argument -> callBuilder.addArgument(argument, parameterValuePassings[index], variadic = false) } val result = callBuilder.buildCall(blockVariableName, valueReturning) val blockVariableType = CTypes.blockPointer(callBuilder.cFunctionBuilder.getType()) val blockVariable = CVariable(blockVariableType, blockVariableName) callBuilder.cBridgeBodyLines.add(0, "$blockVariable = ${rawBlockPointerParameter.name};") callBuilder.emitCBridge() return result } override fun bridgedToC(expression: String): String { val callbackBuilder = CCallbackBuilder(stubs, location, isObjCMethod = false) val kotlinFunctionHolder = "kotlinFunctionHolder" callbackBuilder.cBridgeCallBuilder.arguments += kotlinFunctionHolder val (kotlinFunctionHolderParameter, _) = callbackBuilder.bridgeBuilder.addParameter(symbols.nativePtrType, CTypes.id) callbackBuilder.kotlinCallBuilder.arguments += with(callbackBuilder.bridgeBuilder.kotlinIrBuilder) { // TODO: consider casting to [functionType]. irCall(symbols.interopUnwrapKotlinObjectHolderImpl.owner).apply { putValueArgument(0, irGet(kotlinFunctionHolderParameter) ) } } parameterValuePassings.forEach { callbackBuilder.kotlinCallBuilder.arguments += with(it) { callbackBuilder.receiveValue() } } require(functionType.isFunction()) { stubs.renderCompilerError(location) } val invokeFunction = (functionType.classifier.owner as IrClass) .simpleFunctions().single { it.name == OperatorNameConventions.INVOKE } callbackBuilder.buildValueReturn(invokeFunction, valueReturning) val block = buildString { append('^') append(callbackBuilder.cFunctionBuilder.buildSignature("")) append(" { ") callbackBuilder.cBodyLines.forEach { append(it) append(' ') } append(" }") } val blockAsId = if (retained) { "(__bridge id)(__bridge_retained void*)$block" // Retain and convert to id. } else { "(id)$block" } return "({ id $kotlinFunctionHolder = $expression; $kotlinFunctionHolder ? $blockAsId : (id)0; })" } override fun cToBridged(expression: String) = expression } private class WCStringArgumentPassing : KotlinToCArgumentPassing { override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression { val wcstr = irBuilder.irSafeTransform(expression) { irCall(symbols.interopWcstr.owner).apply { extensionReceiver = it } } return with(CValuesRefArgumentPassing) { passValue(wcstr) } } } private class CStringArgumentPassing : KotlinToCArgumentPassing { override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression { val cstr = irBuilder.irSafeTransform(expression) { irCall(symbols.interopCstr.owner).apply { extensionReceiver = it } } return with(CValuesRefArgumentPassing) { passValue(cstr) } } } private object CValuesRefArgumentPassing : KotlinToCArgumentPassing { override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression { val bridgeArgument = cValuesRefToPointer(expression) val cBridgeValue = passThroughBridge( bridgeArgument, symbols.interopCPointer.typeWithStarProjections.makeNullable(), CTypes.voidPtr ) return CExpression(cBridgeValue.name, cBridgeValue.type) } } private fun KotlinToCCallBuilder.cValuesRefToPointer( value: IrExpression ): IrExpression = if (value.type.classifierOrNull == symbols.interopCPointer) { value // Optimization } else { val getPointerFunction = symbols.interopCValuesRef.owner .simpleFunctions() .single { it.name.asString() == "getPointer" } irBuilder.irSafeTransform(value) { irCall(getPointerFunction).apply { dispatchReceiver = it putValueArgument(0, bridgeCallBuilder.getMemScope()) } } } private fun IrBuilderWithScope.irSafeTransform( value: IrExpression, block: IrBuilderWithScope.(IrExpression) -> IrExpression ): IrExpression = if (!value.type.isNullable()) { block(value) // Optimization } else { irLetS(value) { valueVarSymbol -> val valueVar = valueVarSymbol.owner val transformed = block(irGet(valueVar)) irIfThenElse( type = transformed.type.makeNullable(), condition = irEqeqeq(irGet(valueVar), irNull()), thenPart = irNull(), elsePart = transformed ) } } private object VoidReturning : ValueReturning { override val cType: CType get() = CTypes.void override fun KotlinToCCallBuilder.returnValue(expression: String): IrExpression { bridgeBuilder.setReturnType(irBuilder.context.irBuiltIns.unitType, CTypes.void) cFunctionBuilder.setReturnType(CTypes.void) cBridgeBodyLines += "$expression;" return buildKotlinBridgeCall() } override fun CCallbackBuilder.returnValue(expression: IrExpression) { bridgeBuilder.setReturnType(irBuiltIns.unitType, CTypes.void) cFunctionBuilder.setReturnType(CTypes.void) kotlinBridgeStatements += bridgeBuilder.kotlinIrBuilder.irReturn(expression) cBodyLines += "${buildCBridgeCall()};" } } private object IgnoredUnitArgumentPassing : ArgumentPassing { override fun KotlinToCCallBuilder.passValue(expression: IrExpression): CExpression? { // Note: it is not correct to just drop the expression (due to possible side effects), // so (in lack of other options) evaluate the expression and pass ignored value to the bridge: val bridgeArgument = irBuilder.irBlock { +expression +irInt(0) } passThroughBridge(bridgeArgument, irBuilder.context.irBuiltIns.intType, CTypes.int).name return null } override fun CCallbackBuilder.receiveValue(): IrExpression { return bridgeBuilder.kotlinIrBuilder.irGetObject(irBuiltIns.unitClass) } } internal fun CType.cast(expression: String): String = "((${this.render("")})$expression)" ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGenUtils.kt ================================================ package org.jetbrains.kotlin.backend.konan.cgen import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.common.lower.irThrow import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.irBuilder import org.jetbrains.kotlin.ir.util.irCatch import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.name.Name internal class CFunctionBuilder { private val parameters = mutableListOf() private lateinit var returnType: CType var variadic: Boolean = false fun setReturnType(type: CType) { require(!::returnType.isInitialized) returnType = type } fun addParameter(type: CType): CVariable { val result = CVariable(type, "p${counter++}") parameters += result return result } val numberOfParameters: Int get() = parameters.size private var counter = 1 fun getType(): CType = CTypes.function(returnType, parameters.map { it.type }, variadic) fun buildSignature(name: String): String = returnType.render(buildString { append(name) append('(') parameters.joinTo(this) if (parameters.isEmpty()) { if (!variadic) append("void") } else { if (variadic) append(", ...") } append(')') }) } internal class KotlinBridgeBuilder( startOffset: Int, endOffset: Int, cName: String, stubs: KotlinStubs, isExternal: Boolean, foreignExceptionMode: ForeignExceptionMode.Mode ) { private var counter = 0 private val bridge: IrFunction = createKotlinBridge(startOffset, endOffset, cName, stubs, isExternal, foreignExceptionMode) val irBuilder: IrBuilderWithScope = irBuilder(stubs.irBuiltIns, bridge.symbol).at(startOffset, endOffset) fun addParameter(type: IrType): IrValueParameter { val index = counter++ return IrValueParameterImpl( bridge.startOffset, bridge.endOffset, bridge.origin, IrValueParameterSymbolImpl(), Name.identifier("p$index"), index, type, null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = bridge bridge.valueParameters += this } } fun setReturnType(type: IrType) { bridge.returnType = type } fun build(): IrFunction = bridge } private fun createKotlinBridge( startOffset: Int, endOffset: Int, cBridgeName: String, stubs: KotlinStubs, isExternal: Boolean, foreignExceptionMode: ForeignExceptionMode.Mode ): IrFunction { val bridge = IrFunctionImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), Name.identifier(cBridgeName), DescriptorVisibilities.PRIVATE, Modality.FINAL, IrUninitializedType, isInline = false, isExternal = isExternal, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) if (isExternal) { bridge.annotations += buildSimpleAnnotation(stubs.irBuiltIns, startOffset, endOffset, stubs.symbols.symbolName.owner, cBridgeName) bridge.annotations += buildSimpleAnnotation(stubs.irBuiltIns, startOffset, endOffset, stubs.symbols.filterExceptions.owner, foreignExceptionMode.value) } else { bridge.annotations += buildSimpleAnnotation(stubs.irBuiltIns, startOffset, endOffset, stubs.symbols.exportForCppRuntime.owner, cBridgeName) } return bridge } internal class KotlinCBridgeBuilder( startOffset: Int, endOffset: Int, cName: String, stubs: KotlinStubs, isKotlinToC: Boolean, foreignExceptionMode: ForeignExceptionMode.Mode = ForeignExceptionMode.default ) { private val kotlinBridgeBuilder = KotlinBridgeBuilder(startOffset, endOffset, cName, stubs, isExternal = isKotlinToC, foreignExceptionMode) private val cBridgeBuilder = CFunctionBuilder() val kotlinIrBuilder: IrBuilderWithScope get() = kotlinBridgeBuilder.irBuilder fun addParameter(kotlinType: IrType, cType: CType): Pair { return kotlinBridgeBuilder.addParameter(kotlinType) to cBridgeBuilder.addParameter(cType) } fun setReturnType(kotlinReturnType: IrType, cReturnType: CType) { kotlinBridgeBuilder.setReturnType(kotlinReturnType) cBridgeBuilder.setReturnType(cReturnType) } fun buildCSignature(name: String): String = cBridgeBuilder.buildSignature(name) fun buildKotlinBridge() = kotlinBridgeBuilder.build() } internal class KotlinCallBuilder(private val irBuilder: IrBuilderWithScope, private val symbols: KonanSymbols) { val prepare = mutableListOf() val arguments = mutableListOf() val cleanup = mutableListOf IrStatement>() private var memScope: IrVariable? = null fun getMemScope(): IrExpression = with(irBuilder) { memScope?.let { return irGet(it) } val newMemScope = scope.createTemporaryVariable(irCall(symbols.interopMemScope.owner.constructors.single())) memScope = newMemScope prepare += newMemScope val clearImpl = symbols.interopMemScope.owner.simpleFunctions().single { it.name.asString() == "clearImpl" } cleanup += { irCall(clearImpl).apply { dispatchReceiver = irGet(memScope!!) } } irGet(newMemScope) } fun build( function: IrFunction, transformCall: (IrMemberAccessExpression<*>) -> IrExpression = { it } ): IrExpression { val arguments = this.arguments.toMutableList() val kotlinCall = irBuilder.irCall(function).run { if (function.dispatchReceiverParameter != null) { dispatchReceiver = arguments.removeAt(0) } if (function.extensionReceiverParameter != null) { extensionReceiver = arguments.removeAt(0) } assert(arguments.size == function.valueParameters.size) arguments.forEachIndexed { index, it -> putValueArgument(index, it) } transformCall(this) } return if (prepare.isEmpty() && cleanup.isEmpty()) { kotlinCall } else { irBuilder.irBlock(kotlinCall) { prepare.forEach { +it } if (cleanup.isEmpty()) { +kotlinCall } else { // Note: generating try-catch as finally blocks are already lowered. val result = irTemporary(IrTryImpl(startOffset, endOffset, kotlinCall.type).apply { tryResult = kotlinCall catches += irCatch(context.irBuiltIns.throwableType).apply { result = irBlock(kotlinCall) { cleanup.forEach { +it() } +irThrow(irGet(catchParameter)) } } }) // TODO: consider handling a cleanup failure properly. cleanup.forEach { +it() } +irGet(result) } } } } } internal class CCallBuilder { val arguments = mutableListOf() fun build(function: String) = buildString { append(function) append('(') arguments.joinTo(this) append(')') } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CSyntaxSupport.kt ================================================ package org.jetbrains.kotlin.backend.konan.cgen internal interface CType { fun render(name: String): String } internal class CVariable(val type: CType, val name: String) { override fun toString() = type.render(name) } internal object CTypes { fun simple(type: String): CType = SimpleCType(type) fun pointer(pointee: CType): CType = PointerCType(pointee) fun function(returnType: CType, parameterTypes: List, variadic: Boolean): CType = FunctionCType(returnType, parameterTypes, variadic) fun blockPointer(pointee: CType): CType = object : CType { override fun render(name: String): String = pointee.render("^$name") } val void = simple("void") val voidPtr = pointer(void) val signedChar = simple("signed char") val unsignedChar = simple("unsigned char") val short = simple("short") val unsignedShort = simple("unsigned short") val int = simple("int") val unsignedInt = simple("unsigned int") val longLong = simple("long long") val unsignedLongLong = simple("unsigned long long") val float = simple("float") val double = simple("double") val C99Bool = simple("_Bool") val char = simple("char") val vector128 = simple("float __attribute__ ((__vector_size__ (16)))") val id = simple("id") } private class SimpleCType(private val type: String) : CType { override fun render(name: String): String = if (name.isEmpty()) type else "$type $name" } private class PointerCType(private val pointee: CType) : CType { override fun render(name: String): String = pointee.render("*$name") } private class FunctionCType( private val returnType: CType, private val parameterTypes: List, private val variadic: Boolean ) : CType { override fun render(name: String): String = returnType.render(buildString { append("(") append(name) append(")(") parameterTypes.joinTo(this) { it.render("") } if (parameterTypes.isEmpty()) { if (!variadic) append("void") } else { if (variadic) append(", ...") } append(')') }) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/InteropIrUtils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.cgen import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor import org.jetbrains.kotlin.backend.konan.KonanFqNames import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.isObjCObjectType import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name internal fun IrType.isCEnumType(): Boolean { val simpleType = this as? IrSimpleType ?: return false if (simpleType.hasQuestionMark) return false val enumClass = simpleType.classifier.owner as? IrClass ?: return false if (!enumClass.isEnumClass) return false return enumClass.superTypes .any { (it.classifierOrNull?.owner as? IrClass)?.fqNameForIrSerialization == FqName("kotlinx.cinterop.CEnum") } } private val cCall = RuntimeNames.cCall // Make sure external stubs always get proper annotaions. private fun IrDeclaration.hasCCallAnnotation(name: String): Boolean = this.annotations.hasAnnotation(cCall.child(Name.identifier(name))) // LazyIr doesn't pass annotations from descriptor to IrValueParameter. || this.descriptor.annotations.hasAnnotation(cCall.child(Name.identifier(name))) internal fun IrValueParameter.isWCStringParameter() = hasCCallAnnotation("WCString") internal fun IrValueParameter.isCStringParameter() = hasCCallAnnotation("CString") internal fun IrValueParameter.isObjCConsumed() = hasCCallAnnotation("Consumed") internal fun IrSimpleFunction.objCConsumesReceiver() = hasCCallAnnotation("ConsumesReceiver") internal fun IrSimpleFunction.objCReturnsRetained() = hasCCallAnnotation("ReturnsRetained") internal fun IrClass.getCStructSpelling(): String? = getAnnotationArgumentValue(FqName("kotlinx.cinterop.internal.CStruct"), "spelling") internal fun IrType.isTypeOfNullLiteral(): Boolean = this is IrSimpleType && hasQuestionMark && classifier.isClassWithFqName(StandardNames.FqNames.nothing) internal fun IrType.isVector(): Boolean { if (this is IrSimpleType && !this.hasQuestionMark) { return classifier.isClassWithFqName(KonanFqNames.Vector128.toUnsafe()) } return false } internal fun IrType.isObjCReferenceType(target: KonanTarget, irBuiltIns: IrBuiltIns): Boolean { if (!target.family.isAppleFamily) return false // Handle the same types as produced by [objCPointerMirror] in Interop/StubGenerator/.../Mappings.kt. if (isObjCObjectType()) return true val descriptor = classifierOrNull?.descriptor ?: return false val builtIns = irBuiltIns.builtIns return when (descriptor) { builtIns.any, builtIns.string, builtIns.list, builtIns.mutableList, builtIns.set, builtIns.map -> true else -> false } } internal fun IrType.isCPointer(symbols: KonanSymbols): Boolean = this.classOrNull == symbols.interopCPointer internal fun IrType.isCValue(symbols: KonanSymbols): Boolean = this.classOrNull == symbols.interopCValue internal fun IrType.isNativePointed(symbols: KonanSymbols): Boolean = isSubtypeOfClass(symbols.nativePointed) internal fun IrType.isCStructFieldTypeStoredInMemoryDirectly(): Boolean = isPrimitiveType() || isUnsigned() || isVector() internal fun IrType.isCStructFieldSupportedReferenceType(symbols: KonanSymbols): Boolean = isObjCObjectType() || getClass()?.isAny() == true || isStringClassType() || classOrNull == symbols.list || classOrNull == symbols.mutableList || classOrNull == symbols.set || classOrNull == symbols.map /** * Check given function is a getter or setter * for `value` property of CEnumVar subclass. */ internal fun IrFunction.isCEnumVarValueAccessor(symbols: KonanSymbols): Boolean { val parent = parent as? IrClass ?: return false return if (symbols.interopCEnumVar in parent.superClasses && isPropertyAccessor) { (propertyIfAccessor as IrProperty).name.asString() == "value" } else { false } } internal fun IrFunction.isCStructMemberAtAccessor() = hasAnnotation(RuntimeNames.cStructMemberAt) internal fun IrFunction.isCStructArrayMemberAtAccessor() = hasAnnotation(RuntimeNames.cStructArrayMemberAt) internal fun IrFunction.isCStructBitFieldAccessor() = hasAnnotation(RuntimeNames.cStructBitField) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassLayoutBuilder.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import llvm.LLVMStoreSizeOfType import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName import org.jetbrains.kotlin.backend.konan.llvm.llvmType import org.jetbrains.kotlin.backend.konan.llvm.localHash import org.jetbrains.kotlin.backend.konan.lower.InnerClassLowering import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrClassReference import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.FqName internal class OverriddenFunctionInfo( val function: IrSimpleFunction, val overriddenFunction: IrSimpleFunction ) { val needBridge: Boolean get() = function.target.needBridgeTo(overriddenFunction) val bridgeDirections: BridgeDirections get() = function.target.bridgeDirectionsTo(overriddenFunction) val canBeCalledVirtually: Boolean get() { if (overriddenFunction.isObjCClassMethod()) { return function.canObjCClassMethodBeCalledVirtually(overriddenFunction) } return overriddenFunction.isOverridable } val inheritsBridge: Boolean get() = !function.isReal && function.target.overrides(overriddenFunction) && function.bridgeDirectionsTo(overriddenFunction).allNotNeeded() fun getImplementation(context: Context): IrSimpleFunction? { val target = function.target val implementation = if (!needBridge) target else { val bridgeOwner = if (inheritsBridge) { target // Bridge is inherited from superclass. } else { function } context.specialDeclarationsFactory.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction)) } return if (implementation.modality == Modality.ABSTRACT) null else implementation } override fun toString(): String { return "(descriptor=$function, overriddenDescriptor=$overriddenFunction)" } override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is OverriddenFunctionInfo) return false if (function != other.function) return false if (overriddenFunction != other.overriddenFunction) return false return true } override fun hashCode(): Int { var result = function.hashCode() result = 31 * result + overriddenFunction.hashCode() return result } } internal class ClassGlobalHierarchyInfo(val classIdLo: Int, val classIdHi: Int, val interfaceId: Int, val interfaceColor: Int) { companion object { val DUMMY = ClassGlobalHierarchyInfo(0, 0, 0, 0) // 32-items table seems like a good threshold. val MAX_BITS_PER_COLOR = 5 } } internal class GlobalHierarchyAnalysisResult(val bitsPerColor: Int) internal class GlobalHierarchyAnalysis(val context: Context, val irModule: IrModuleFragment) { fun run() { /* * The algorithm for fast interface call and check: * Consider the following graph: the vertices are interfaces and two interfaces are * connected with an edge if there exists a class which inherits both of them. * Now find a proper vertex-coloring of that graph (such that no edge connects vertices of same color). * Assign to each interface a unique id in such a way that its color is stored in the lower bits of its id. * Assuming the number of colors used is reasonably small build then a perfect hash table for each class: * for each interfaceId inherited: itable[interfaceId % size] == interfaceId * Since we store the color in the lower bits the division can be replaced with (interfaceId & (size - 1)). * This is indeed a perfect hash table by construction of the coloring of the interface graph. * Now to perform an interface call store in all itables pointers to vtables of that particular interface. * Interface call: *(itable[interfaceId & (size - 1)].vtable[methodIndex])(...) * Interface check: itable[interfaceId & (size - 1)].id == interfaceId * * Note that we have a fallback to a more conservative version if the size of an itable is too large: * just save all interface ids and vtables in sorted order and find the needed one with the binary search. * We can signal that using the sign bit of the type info's size field: * if (size >= 0) { .. fast path .. } * else binary_search(0, -size) */ val interfaceColors = assignColorsToInterfaces() val maxColor = interfaceColors.values.maxOrNull() ?: 0 var bitsPerColor = 0 var x = maxColor while (x > 0) { ++bitsPerColor x /= 2 } val maxInterfaceId = Int.MAX_VALUE shr bitsPerColor val colorCounts = IntArray(maxColor + 1) /* * Here's the explanation of what's happening here: * Given a tree we can traverse it with the DFS and save for each vertex two times: * the enter time (the first time we saw this vertex) and the exit time (the last time we saw it). * It turns out that if we assign then for each vertex the interval (enterTime, exitTime), * then the following claim holds for any two vertices v and w: * ----- v is ancestor of w iff interval(v) contains interval(w) ------ * Now apply this idea to the classes hierarchy tree and we'll get a fast type check. * * And one more observation: for each pair of intervals they either don't intersect or * one contains the other. With that in mind, we can save in a type info only one end of an interval. */ val root = context.irBuiltIns.anyClass.owner val immediateInheritors = mutableMapOf>() val allClasses = mutableListOf() irModule.acceptVoid(object: IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { if (declaration.isInterface) { val color = interfaceColors[declaration]!! // Numerate from 1 (reserve 0 for invalid value). val interfaceId = ++colorCounts[color] assert (interfaceId <= maxInterfaceId) { "Unable to assign interface id to ${declaration.name}" } context.getLayoutBuilder(declaration).hierarchyInfo = ClassGlobalHierarchyInfo(0, 0, color or (interfaceId shl bitsPerColor), color) } else { allClasses += declaration if (declaration != root) { val superClass = declaration.getSuperClassNotAny() ?: root val inheritors = immediateInheritors.getOrPut(superClass) { mutableListOf() } inheritors.add(declaration) } } super.visitClass(declaration) } }) var time = 0 fun dfs(irClass: IrClass) { ++time // Make the Any's interval's left border -1 in order to correctly generate classes for ObjC blocks. val enterTime = if (irClass == root) -1 else time immediateInheritors[irClass]?.forEach { dfs(it) } val exitTime = time context.getLayoutBuilder(irClass).hierarchyInfo = ClassGlobalHierarchyInfo(enterTime, exitTime, 0, 0) } dfs(root) context.globalHierarchyAnalysisResult = GlobalHierarchyAnalysisResult(bitsPerColor) } class InterfacesForbiddennessGraph(val nodes: List, val forbidden: List>) { fun computeColoringGreedy(): IntArray { val colors = IntArray(nodes.size) { -1 } var numberOfColors = 0 val usedColors = BooleanArray(nodes.size) for (v in nodes.indices) { for (c in 0 until numberOfColors) usedColors[c] = false for (u in forbidden[v]) if (colors[u] >= 0) usedColors[colors[u]] = true var found = false for (c in 0 until numberOfColors) if (!usedColors[c]) { colors[v] = c found = true break } if (!found) colors[v] = numberOfColors++ } return colors } companion object { fun build(irModuleFragment: IrModuleFragment): InterfacesForbiddennessGraph { val interfaceIndices = mutableMapOf() val interfaces = mutableListOf() val forbidden = mutableListOf>() irModuleFragment.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } fun registerInterface(iface: IrClass) { interfaceIndices.getOrPut(iface) { forbidden.add(mutableListOf()) interfaces.add(iface) interfaces.size - 1 } } override fun visitClass(declaration: IrClass) { if (declaration.isInterface) registerInterface(declaration) else { val implementedInterfaces = declaration.implementedInterfaces implementedInterfaces.forEach { registerInterface(it) } for (i in 0 until implementedInterfaces.size) for (j in i + 1 until implementedInterfaces.size) { val v = interfaceIndices[implementedInterfaces[i]]!! val u = interfaceIndices[implementedInterfaces[j]]!! forbidden[v].add(u) forbidden[u].add(v) } } super.visitClass(declaration) } }) return InterfacesForbiddennessGraph(interfaces, forbidden) } } } private fun assignColorsToInterfaces(): Map { val graph = InterfacesForbiddennessGraph.build(irModule) val coloring = graph.computeColoringGreedy() return graph.nodes.mapIndexed { v, irClass -> irClass to coloring[v] }.toMap() } } internal class ClassLayoutBuilder(val irClass: IrClass, val context: Context, val isLowered: Boolean) { val vtableEntries: List by lazy { assert(!irClass.isInterface) context.logMultiple { +"" +"BUILDING vTable for ${irClass.render()}" } val superVtableEntries = if (irClass.isSpecialClassWithNoSupertypes()) { emptyList() } else { val superClass = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner context.getLayoutBuilder(superClass).vtableEntries } val methods = irClass.sortedOverridableOrOverridingMethods val newVtableSlots = mutableListOf() val overridenVtableSlots = mutableMapOf() context.logMultiple { +"" +"SUPER vTable:" superVtableEntries.forEach { +" ${it.overriddenFunction.render()} -> ${it.function.render()}" } +"" +"METHODS:" methods.forEach { +" ${it.render()}" } +"" +"BUILDING INHERITED vTable" } val superVtableMap = superVtableEntries.groupBy { it.function } methods.forEach { overridingMethod -> overridingMethod.allOverriddenFunctions.forEach { val superMethods = superVtableMap[it] if (superMethods?.isNotEmpty() == true) { newVtableSlots.add(OverriddenFunctionInfo(overridingMethod, it)) superMethods.forEach { superMethod -> overridenVtableSlots[superMethod.overriddenFunction] = OverriddenFunctionInfo(overridingMethod, superMethod.overriddenFunction) } } } } val inheritedVtableSlots = superVtableEntries.map { superMethod -> overridenVtableSlots[superMethod.overriddenFunction]?.also { context.log { "Taking overridden ${superMethod.overriddenFunction.render()} -> ${it.function.render()}" } } ?: superMethod.also { context.log { "Taking super ${superMethod.overriddenFunction.render()} -> ${superMethod.function.render()}" } } } // Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later. methods.mapTo(newVtableSlots) { OverriddenFunctionInfo(it, it) } val inheritedVtableSlotsSet = inheritedVtableSlots.map { it.function to it.bridgeDirections }.toSet() val filteredNewVtableSlots = newVtableSlots .filterNot { inheritedVtableSlotsSet.contains(it.function to it.bridgeDirections) } .distinctBy { it.function to it.bridgeDirections } .filter { it.function.isOverridable } context.logMultiple { +"" +"INHERITED vTable slots:" inheritedVtableSlots.forEach { +" ${it.overriddenFunction.render()} -> ${it.function.render()}" } +"" +"MY OWN vTable slots:" filteredNewVtableSlots.forEach { +" ${it.overriddenFunction.render()} -> ${it.function.render()} ${it.function}" } +"DONE vTable for ${irClass.render()}" } inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenFunction.uniqueId } } fun vtableIndex(function: IrSimpleFunction): Int { val bridgeDirections = function.target.bridgeDirectionsTo(function) val index = vtableEntries.indexOfFirst { it.function == function && it.bridgeDirections == bridgeDirections } if (index < 0) throw Error(function.render() + " $function " + " (${function.symbol.descriptor}) not in vtable of " + irClass.render()) return index } val methodTableEntries: List by lazy { irClass.sortedOverridableOrOverridingMethods .flatMap { method -> method.allOverriddenFunctions.map { OverriddenFunctionInfo(method, it) } } .filter { it.canBeCalledVirtually } .distinctBy { it.overriddenFunction.uniqueId } .sortedBy { it.overriddenFunction.uniqueId } // TODO: probably method table should contain all accessible methods to improve binary compatibility } val interfaceTableEntries: List by lazy { irClass.sortedOverridableOrOverridingMethods .filter { f -> f.isReal || f.overriddenSymbols.any { OverriddenFunctionInfo(f, it.owner).needBridge } } .toList() } data class InterfaceTablePlace(val interfaceId: Int, val itableSize: Int, val methodIndex: Int) { companion object { val INVALID = InterfaceTablePlace(0, -1, -1) } } fun itablePlace(function: IrSimpleFunction): InterfaceTablePlace { assert (irClass.isInterface) { "An interface expected but was ${irClass.name}" } val itable = interfaceTableEntries val index = itable.indexOf(function) if (index >= 0) return InterfaceTablePlace(hierarchyInfo.interfaceId, itable.size, index) val superFunction = function.overriddenSymbols.first().owner return context.getLayoutBuilder(superFunction.parentAsClass).itablePlace(superFunction) } /** * All fields of the class instance. * The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix. */ val fields: List by lazy { val superClass = irClass.getSuperClassNotAny() // TODO: what if Any has fields? val superFields = if (superClass != null) context.getLayoutBuilder(superClass).fields else emptyList() superFields + getDeclaredFields() } val associatedObjects by lazy { val result = mutableMapOf() irClass.annotations.forEach { val irFile = irClass.getContainingFile() val annotationClass = (it.symbol.owner as? IrConstructor)?.constructedClass ?: error(irFile, it, "unexpected annotation") if (annotationClass.hasAnnotation(RuntimeNames.associatedObjectKey)) { val argument = it.getValueArgument(0) val irClassReference = argument as? IrClassReference ?: error(irFile, argument, "unexpected annotation argument") val associatedObject = irClassReference.symbol.owner if (associatedObject !is IrClass || !associatedObject.isObject) { error(irFile, irClassReference, "argument is not a singleton") } if (annotationClass in result) { error( irFile, it, "duplicate value for ${annotationClass.name}, previous was ${result[annotationClass]?.name}" ) } result[annotationClass] = associatedObject } } result } lateinit var hierarchyInfo: ClassGlobalHierarchyInfo /** * Fields declared in the class. */ private fun getDeclaredFields(): List { val declarations: List = if (irClass.isInner && !isLowered) { // Note: copying to avoid mutation of the original class. irClass.declarations.toMutableList() .also { InnerClassLowering.addOuterThisField(it, irClass, context) } } else { irClass.declarations } val fields = declarations.mapNotNull { when (it) { is IrField -> it.takeIf { it.isReal } is IrProperty -> it.takeIf { it.isReal }?.backingField else -> null } } if (irClass.hasAnnotation(FqName.fromSegments(listOf("kotlin", "native", "internal", "NoReorderFields")))) return fields return fields.sortedByDescending{ LLVMStoreSizeOfType(context.llvm.runtime.targetData, it.type.llvmType(context)) } } private val IrClass.sortedOverridableOrOverridingMethods: List get() = this.simpleFunctions() .filter { it.isOverridableOrOverrides && it.bridgeTarget == null } .sortedBy { it.uniqueId } private val functionIds = mutableMapOf() private val IrFunction.uniqueId get() = functionIds.getOrPut(this) { computeFunctionName().localHash.value } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DeepPrintVisitor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.util.nTabs import org.jetbrains.kotlin.descriptors.* class DeepPrintVisitor(worker: DeclarationDescriptorVisitor): DeepVisitor(worker) { override fun visitChildren(descriptor: DeclarationDescriptor?, data: Int): Boolean { return super.visitChildren(descriptor, data+1) } override fun visitChildren(descriptors: Collection, data: Int): Boolean { return super.visitChildren(descriptors, data+1) } } class PrintVisitor: DeclarationDescriptorVisitor { fun printDescriptor(descriptor: DeclarationDescriptor, amount: Int): Boolean { println("${nTabs(amount)} ${descriptor.toString()}") return true; } override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitScriptDescriptor(descriptor: ScriptDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: Int): Boolean = printDescriptor(descriptor, data) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DeepVisitor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils open class DeepVisitor(val worker: DeclarationDescriptorVisitor) : DeclarationDescriptorVisitor { open fun visitChildren(descriptors: Collection, data: D): Boolean { for (descriptor in descriptors) { if (!descriptor.accept(this, data)) return false } return true } open fun visitChildren(descriptor: DeclarationDescriptor?, data: D): Boolean { if (descriptor == null) return true return descriptor.accept(this, data) } fun applyWorker(descriptor: DeclarationDescriptor, data: D): Boolean { return descriptor.accept(worker, data) } fun processCallable(descriptor: CallableDescriptor, data: D): Boolean { return applyWorker(descriptor, data) && visitChildren(descriptor.getTypeParameters(), data) && visitChildren(descriptor.getExtensionReceiverParameter(), data) && visitChildren(descriptor.getValueParameters(), data) } override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) && visitChildren(DescriptorUtils.getAllDescriptors(descriptor.getMemberScope()), data) } override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) && visitChildren(DescriptorUtils.getAllDescriptors(descriptor.memberScope), data) } override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: D): Boolean? { return processCallable(descriptor, data) } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: D): Boolean? { return processCallable(descriptor, data) && visitChildren(descriptor.getter, data) && visitChildren(descriptor.setter, data) } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: D): Boolean? { return processCallable(descriptor, data) } override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) } override fun visitClassDescriptor(descriptor: ClassDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) && visitChildren(descriptor.getThisAsReceiverParameter(), data) && visitChildren(descriptor.getConstructors(), data) && visitChildren(descriptor.getTypeConstructor().getParameters(), data) && visitChildren(DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().memberScope), data) } override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) && visitChildren(descriptor.getDeclaredTypeParameters(), data) } override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) && visitChildren(descriptor.getPackage(FqName.ROOT), data) } override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: D): Boolean? { return visitFunctionDescriptor(constructorDescriptor, data) } override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, data: D): Boolean? { return visitClassDescriptor(scriptDescriptor, data) } override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: D): Boolean? { return visitVariableDescriptor(descriptor, data) } override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: D): Boolean? { return visitFunctionDescriptor(descriptor, data) } override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: D): Boolean? { return visitFunctionDescriptor(descriptor, data) } override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: D): Boolean? { return applyWorker(descriptor, data) } } open public class EmptyDescriptorVisitorVoid: DeclarationDescriptorVisitor { override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) = true override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: Unit) = true override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: Unit) = true override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) = true override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: Unit) = true override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) = true override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) = true override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) = true override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) = true override fun visitScriptDescriptor(descriptor: ScriptDescriptor, data: Unit) = true override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) = true override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: Unit) = true override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Unit) = true override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Unit) = true override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: Unit) = true } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.isVoidAsReturnType import org.jetbrains.kotlin.backend.konan.llvm.longName import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs /** * List of all implemented interfaces (including those which implemented by a super class) */ internal val IrClass.implementedInterfaces: List get() { val superClassImplementedInterfaces = this.getSuperClassNotAny()?.implementedInterfaces ?: emptyList() val superInterfaces = this.getSuperInterfaces() val superInterfacesImplementedInterfaces = superInterfaces.flatMap { it.implementedInterfaces } return (superClassImplementedInterfaces + superInterfacesImplementedInterfaces + superInterfaces).distinct() } internal val IrFunction.isTypedIntrinsic: Boolean get() = annotations.hasAnnotation(KonanFqNames.typedIntrinsic) internal val arrayTypes = setOf( "kotlin.Array", "kotlin.ByteArray", "kotlin.CharArray", "kotlin.ShortArray", "kotlin.IntArray", "kotlin.LongArray", "kotlin.FloatArray", "kotlin.DoubleArray", "kotlin.BooleanArray", "kotlin.native.ImmutableBlob", "kotlin.native.internal.NativePtrArray" ) internal val arraysWithFixedSizeItems = setOf( "kotlin.ByteArray", "kotlin.CharArray", "kotlin.ShortArray", "kotlin.IntArray", "kotlin.LongArray", "kotlin.FloatArray", "kotlin.DoubleArray", "kotlin.BooleanArray" ) internal val IrClass.isArray: Boolean get() = this.fqNameForIrSerialization.asString() in arrayTypes internal val IrClass.isArrayWithFixedSizeItems: Boolean get() = this.fqNameForIrSerialization.asString() in arraysWithFixedSizeItems fun IrClass.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT private enum class TypeKind { ABSENT, VOID, VALUE_TYPE, REFERENCE } private data class TypeWithKind(val irType: IrType?, val kind: TypeKind) { companion object { fun fromType(irType: IrType?) = when { irType == null -> TypeWithKind(null, TypeKind.ABSENT) irType.isInlinedNative() -> TypeWithKind(irType, TypeKind.VALUE_TYPE) else -> TypeWithKind(irType, TypeKind.REFERENCE) } } } private fun IrFunction.typeWithKindAt(index: ParameterIndex) = when (index) { ParameterIndex.RETURN_INDEX -> when { isSuspend -> TypeWithKind(null, TypeKind.REFERENCE) returnType.isVoidAsReturnType() -> TypeWithKind(returnType, TypeKind.VOID) else -> TypeWithKind.fromType(returnType) } ParameterIndex.DISPATCH_RECEIVER_INDEX -> TypeWithKind.fromType(dispatchReceiverParameter?.type) ParameterIndex.EXTENSION_RECEIVER_INDEX -> TypeWithKind.fromType(extensionReceiverParameter?.type) else -> TypeWithKind.fromType(this.valueParameters[index.unmap()].type) } private fun IrFunction.needBridgeToAt(target: IrFunction, index: ParameterIndex) = bridgeDirectionToAt(target, index).kind != BridgeDirectionKind.NONE @Suppress("EXPERIMENTAL_FEATURE_WARNING") private inline class ParameterIndex(val index: Int) { companion object { val RETURN_INDEX = ParameterIndex(0) val DISPATCH_RECEIVER_INDEX = ParameterIndex(1) val EXTENSION_RECEIVER_INDEX = ParameterIndex(2) fun map(index: Int) = ParameterIndex(index + 3) fun allParametersCount(irFunction: IrFunction) = irFunction.valueParameters.size + 3 inline fun forEachIndex(irFunction: IrFunction, block: (ParameterIndex) -> Unit) = (0 until allParametersCount(irFunction)).forEach { block(ParameterIndex(it)) } } fun unmap() = index - 3 } internal fun IrFunction.needBridgeTo(target: IrFunction): Boolean { ParameterIndex.forEachIndex(this) { if (needBridgeToAt(target, it)) return true } return false } internal enum class BridgeDirectionKind { NONE, BOX, UNBOX } internal data class BridgeDirection(val irClass: IrClass?, val kind: BridgeDirectionKind) { companion object { val NONE = BridgeDirection(null, BridgeDirectionKind.NONE) } } private fun IrFunction.bridgeDirectionToAt(overriddenFunction: IrFunction, index: ParameterIndex): BridgeDirection { val kind = typeWithKindAt(index).kind val (irClass, otherKind) = overriddenFunction.typeWithKindAt(index) return if (otherKind == kind) BridgeDirection.NONE else when (kind) { TypeKind.VOID, TypeKind.REFERENCE -> BridgeDirection(irClass?.erasure(), BridgeDirectionKind.UNBOX) TypeKind.VALUE_TYPE -> BridgeDirection( irClass?.erasure().takeIf { otherKind == TypeKind.VOID } /* Otherwise erase to [Any?] */, BridgeDirectionKind.BOX) TypeKind.ABSENT -> error("TypeKind.ABSENT should be on both sides") } } private tailrec fun IrType.erasure(): IrClass = when (val classifier = classifierOrFail) { is IrClassSymbol -> classifier.owner is IrTypeParameterSymbol -> classifier.owner.superTypes.first().erasure() else -> error(classifier) } internal class BridgeDirections(private val array: Array) { constructor(irFunction: IrSimpleFunction, overriddenFunction: IrSimpleFunction) : this(Array(ParameterIndex.allParametersCount(irFunction)) { irFunction.bridgeDirectionToAt(overriddenFunction, ParameterIndex(it)) }) fun allNotNeeded(): Boolean = array.all { it.kind == BridgeDirectionKind.NONE } private fun getDirectionAt(index: ParameterIndex) = array[index.index] val returnDirection get() = getDirectionAt(ParameterIndex.RETURN_INDEX) val dispatchReceiverDirection get() = getDirectionAt(ParameterIndex.DISPATCH_RECEIVER_INDEX) val extensionReceiverDirection get() = getDirectionAt(ParameterIndex.EXTENSION_RECEIVER_INDEX) fun parameterDirectionAt(index: Int) = getDirectionAt(ParameterIndex.map(index)) override fun toString(): String { val result = StringBuilder() array.forEach { result.append(when (it.kind) { BridgeDirectionKind.BOX -> 'B' BridgeDirectionKind.UNBOX -> 'U' BridgeDirectionKind.NONE -> 'N' }) } return result.toString() } override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is BridgeDirections) return false return array.size == other.array.size && array.indices.all { array[it] == other.array[it] } } override fun hashCode(): Int { var result = 0 array.forEach { result = result * 31 + it.hashCode() } return result } companion object { fun none(irFunction: IrSimpleFunction) = BridgeDirections(irFunction, irFunction) } } val IrSimpleFunction.allOverriddenFunctions: Set get() { val result = mutableSetOf() fun traverse(function: IrSimpleFunction) { if (function in result) return result += function function.overriddenSymbols.forEach { traverse(it.owner) } } traverse(this) return result } internal fun IrSimpleFunction.bridgeDirectionsTo(overriddenFunction: IrSimpleFunction): BridgeDirections { val ourDirections = BridgeDirections(this, overriddenFunction) val target = this.target if (!this.isReal && modality != Modality.ABSTRACT && target.overrides(overriddenFunction) && ourDirections == target.bridgeDirectionsTo(overriddenFunction)) { // Bridge is inherited from superclass. return BridgeDirections.none(this) } return ourDirections } internal tailrec fun IrDeclaration.findPackage(): IrPackageFragment { val parent = this.parent return parent as? IrPackageFragment ?: (parent as IrDeclaration).findPackage() } fun IrFunctionSymbol.isComparisonFunction(map: Map): Boolean = this in map.values val IrDeclaration.isPropertyAccessor get() = this is IrSimpleFunction && this.correspondingPropertySymbol != null val IrDeclaration.isPropertyField get() = this is IrField && this.correspondingPropertySymbol != null val IrDeclaration.isTopLevelDeclaration get() = parent !is IrDeclaration && !this.isPropertyAccessor && !this.isPropertyField fun IrDeclaration.findTopLevelDeclaration(): IrDeclaration = when { this.isTopLevelDeclaration -> this this.isPropertyAccessor -> (this as IrSimpleFunction).correspondingPropertySymbol!!.owner.findTopLevelDeclaration() this.isPropertyField -> (this as IrField).correspondingPropertySymbol!!.owner.findTopLevelDeclaration() else -> (this.parent as IrDeclaration).findTopLevelDeclaration() } internal val IrClass.isFrozen: Boolean get() = annotations.hasAnnotation(KonanFqNames.frozen) || // RTTI is used for non-reference type box: !this.defaultType.binaryTypeIsReference() fun IrConstructorCall.getAnnotationStringValue() = getValueArgument(0).safeAs>()?.value fun IrConstructorCall.getAnnotationStringValue(name: String): String { val parameter = symbol.owner.valueParameters.single { it.name.asString() == name } return getValueArgument(parameter.index).cast>().value } fun AnnotationDescriptor.getAnnotationStringValue(name: String): String { return argumentValue(name)?.safeAs()?.value ?: error("Expected value $name at annotation $this") } fun IrConstructorCall.getAnnotationValueOrNull(name: String): T? { val parameter = symbol.owner.valueParameters.atMostOne { it.name.asString() == name } return parameter?.let { getValueArgument(it.index)?.let { (it.cast>()).value } } } fun IrFunction.externalSymbolOrThrow(): String? { annotations.findAnnotation(RuntimeNames.symbolNameAnnotation)?.let { return it.getAnnotationStringValue() } if (annotations.hasAnnotation(KonanFqNames.objCMethod)) return null if (annotations.hasAnnotation(KonanFqNames.typedIntrinsic)) return null if (annotations.hasAnnotation(RuntimeNames.cCall)) return null if (origin == InternalAbi.INTERNAL_ABI_ORIGIN) return null throw Error("external function ${this.longName} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation") } val IrFunction.isBuiltInOperator get() = origin == IrBuiltIns.BUILTIN_OPERATOR fun IrDeclaration.isFromMetadataInteropLibrary() = descriptor.module.isFromInteropLibrary() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/KonanSharedVariablesManager.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager import org.jetbrains.kotlin.backend.konan.KonanBackendContext import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrSetValue import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.constructors internal class KonanSharedVariablesManager(val context: KonanBackendContext) : SharedVariablesManager { private val refClass = context.ir.symbols.refClass private val refClassConstructor = refClass.constructors.single() private val elementProperty = refClass.owner.declarations.filterIsInstance().single() override fun declareSharedVariable(originalDeclaration: IrVariable): IrVariable { val valueType = originalDeclaration.type val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner( originalDeclaration.startOffset, originalDeclaration.endOffset, refClass.typeWith(valueType), refClassConstructor ).apply { putTypeArgument(0, valueType) } return with(originalDeclaration) { IrVariableImpl( startOffset, endOffset, origin, IrVariableSymbolImpl(), name, refConstructorCall.type, isVar = false, isConst = false, isLateinit = false ).apply { initializer = refConstructorCall } } } override fun defineSharedValue(originalDeclaration: IrVariable, sharedVariableDeclaration: IrVariable): IrStatement { val initializer = originalDeclaration.initializer ?: return sharedVariableDeclaration val sharedVariableInitialization = IrCallImpl(initializer.startOffset, initializer.endOffset, context.irBuiltIns.unitType, elementProperty.setter!!.symbol, elementProperty.setter!!.typeParameters.size, elementProperty.setter!!.valueParameters.size) sharedVariableInitialization.dispatchReceiver = IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDeclaration.type, sharedVariableDeclaration.symbol) sharedVariableInitialization.putValueArgument(0, initializer) return IrCompositeImpl( originalDeclaration.startOffset, originalDeclaration.endOffset, context.irBuiltIns.unitType, null, listOf(sharedVariableDeclaration, sharedVariableInitialization) ) } override fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue) = IrCallImpl(originalGet.startOffset, originalGet.endOffset, originalGet.type, elementProperty.getter!!.symbol, elementProperty.getter!!.typeParameters.size, elementProperty.getter!!.valueParameters.size).apply { dispatchReceiver = IrGetValueImpl( originalGet.startOffset, originalGet.endOffset, sharedVariableSymbol.owner.type, sharedVariableSymbol ) } override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue) = IrCallImpl(originalSet.startOffset, originalSet.endOffset, context.irBuiltIns.unitType, elementProperty.setter!!.symbol, elementProperty.setter!!.typeParameters.size, elementProperty.setter!!.valueParameters.size).apply { dispatchReceiver = IrGetValueImpl( originalSet.startOffset, originalSet.endOffset, sharedVariableSymbol.owner.type, sharedVariableSymbol ) putValueArgument(0, originalSet.value) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/LegacyDescriptorUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isUnit /** * Implementation of given method. * * TODO: this method is actually a part of resolve and probably duplicates another one */ internal fun T.resolveFakeOverride(allowAbstract: Boolean = false): T { if (this.kind.isReal) { return this } else { val overridden = OverridingUtil.getOverriddenDeclarations(this) val filtered = OverridingUtil.filterOutOverridden(overridden) // TODO: is it correct to take first? @Suppress("UNCHECKED_CAST") return filtered.first { allowAbstract || it.modality != Modality.ABSTRACT } as T } } internal val ClassDescriptor.isArray: Boolean get() = this.fqNameSafe.asString() in arrayTypes internal val ClassDescriptor.isInterface: Boolean get() = (this.kind == ClassKind.INTERFACE) /** * @return `konan.internal` member scope */ internal val KonanBuiltIns.kotlinNativeInternal: MemberScope get() = this.builtInsModule.getPackage(RuntimeNames.kotlinNativeInternalPackageName).memberScope internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit() internal fun ClassDescriptor.isNothing() = this.defaultType.isNothing() internal val T.allOverriddenDescriptors: List get() { val result = mutableListOf() fun traverse(descriptor: T) { result.add(descriptor) @Suppress("UNCHECKED_CAST") descriptor.overriddenDescriptors.forEach { traverse(it as T) } } traverse(this) return result } internal val ClassDescriptor.contributedMethods: List get () = unsubstitutedMemberScope.contributedMethods internal val MemberScope.contributedMethods: List get () { val contributedDescriptors = this.getContributedDescriptors() val functions = contributedDescriptors.filterIsInstance() val properties = contributedDescriptors.filterIsInstance() val getters = properties.mapNotNull { it.getter } val setters = properties.mapNotNull { it.setter } return functions + getters + setters } fun ClassDescriptor.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT internal val FunctionDescriptor.target: FunctionDescriptor get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { return if (this is PackageFragmentDescriptor) this else this.containingDeclaration!!.findPackage() } internal fun DeclarationDescriptor.findPackageView(): PackageViewDescriptor { val packageFragment = this.findPackage() return packageFragment.module.getPackage(packageFragment.fqName) } internal fun DeclarationDescriptor.allContainingDeclarations(): List { var list = mutableListOf() var current = this.containingDeclaration while (current != null) { list.add(current) current = current.containingDeclaration } return list } fun AnnotationDescriptor.getStringValueOrNull(name: String): String? { val constantValue = this.allValueArguments.entries.atMostOne { it.key.asString() == name }?.value return constantValue?.value as String? } inline fun AnnotationDescriptor.getArgumentValueOrNull(name: String): T? { val constantValue = this.allValueArguments.entries.atMostOne { it.key.asString() == name }?.value return constantValue?.value as T? } fun AnnotationDescriptor.getStringValue(name: String): String = this.getStringValueOrNull(name)!! private fun getPackagesFqNames(module: ModuleDescriptor): Set { val result = mutableSetOf() val packageFragmentProvider = (module as? ModuleDescriptorImpl)?.packageFragmentProviderForModuleContentWithoutDependencies fun getSubPackages(fqName: FqName) { result.add(fqName) val subPackages = packageFragmentProvider?.getSubPackagesOf(fqName) { true } ?: module.getSubPackagesOf(fqName) { true } subPackages.forEach { getSubPackages(it) } } getSubPackages(FqName.ROOT) return result } fun ModuleDescriptor.getPackageFragments(): List = getPackagesFqNames(this).flatMap { getPackage(it).fragments.filter { it.module == this }.toSet() } val ClassDescriptor.enumEntries: List get() { assert(this.kind == ClassKind.ENUM_CLASS) return this.unsubstitutedMemberScope.getContributedDescriptors() .filterIsInstance() .filter { it.kind == ClassKind.ENUM_ENTRY } } internal val DeclarationDescriptor.isExpectMember: Boolean get() = this is MemberDescriptor && this.isExpect internal val DeclarationDescriptor.isSerializableExpectClass: Boolean get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/utils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER import org.jetbrains.kotlin.library.BaseKotlinLibrary import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.deserialization.descriptors.* fun DeclarationDescriptor.deepPrint() { this.accept(DeepPrintVisitor(PrintVisitor()), 0) } internal val String.synthesizedName get() = Name.identifier(this.synthesizedString) internal val String.synthesizedString get() = "\$$this" internal val DeclarationDescriptor.propertyIfAccessor get() = if (this is PropertyAccessorDescriptor) this.correspondingProperty else this internal val CallableMemberDescriptor.propertyIfAccessor get() = if (this is PropertyAccessorDescriptor) this.correspondingProperty else this internal val FunctionDescriptor.deserializedPropertyIfAccessor: DeserializedCallableMemberDescriptor get() { val member = this.propertyIfAccessor if (member is DeserializedCallableMemberDescriptor) return member else error("Unexpected deserializable callable descriptor") } internal val CallableMemberDescriptor.isDeserializableCallable get () = (this.propertyIfAccessor is DeserializedCallableMemberDescriptor) fun DeclarationDescriptor.findTopLevelDescriptor(): DeclarationDescriptor { return if (this.containingDeclaration is org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor) this.propertyIfAccessor else this.containingDeclaration!!.findTopLevelDescriptor() } val ModuleDescriptor.isForwardDeclarationModule: Boolean get() { // TODO: use KlibResolvedModuleDescriptorsFactoryImpl.FORWARD_DECLARATIONS_MODULE_NAME instead of // manually created Name instance return name == Name.special("") } fun BaseKotlinLibrary.isInteropLibrary() = manifestProperties["ir_provider"] == KLIB_INTEROP_IR_PROVIDER_IDENTIFIER fun ModuleDescriptor.isFromInteropLibrary() = if (klibModuleOrigin !is DeserializedKlibModuleOrigin) false else kotlinLibrary.isInteropLibrary() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/injection.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.* import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.frontend.di.configureModule import org.jetbrains.kotlin.platform.konan.NativePlatforms import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory fun createTopDownAnalyzerProviderForKonan( moduleContext: ModuleContext, bindingTrace: BindingTrace, declarationProviderFactory: DeclarationProviderFactory, languageVersionSettings: LanguageVersionSettings, additionalPackages: List, initContainer: StorageComponentContainer.() -> Unit ): ComponentProvider { return createContainer("TopDownAnalyzerForKonan", NativePlatformAnalyzerServices) { configureModule(moduleContext, NativePlatforms.unspecifiedNativePlatform, NativePlatformAnalyzerServices, bindingTrace, languageVersionSettings) useInstance(declarationProviderFactory) useImpl() CompilerEnvironment.configure(this) useImpl() useImpl() initContainer() }.apply { val packagePartProviders = mutableListOf(get().packageFragmentProvider) val moduleDescriptor = get() packagePartProviders += additionalPackages moduleDescriptor.initialize(CompositePackageFragmentProvider(packagePartProviders)) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/FakeIrUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.llvm.llvmSymbolOrigin import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.util.file // This file contains some IR utilities which actually use descriptors. // TODO: port this code to IR. internal val IrDeclaration.llvmSymbolOrigin get() = when (this) { is IrLazyDeclarationBase -> descriptor.llvmSymbolOrigin else -> file.packageFragmentDescriptor.llvmSymbolOrigin } internal fun IrType.isObjCObjectType() = this.toKotlinType().isObjCObjectType() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.kotlinNativeInternal import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint import org.jetbrains.kotlin.backend.konan.lower.TestProcessor import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName import org.jetbrains.kotlin.config.coroutinesPackageFqName import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance import kotlin.properties.Delegates // This is what Context collects about IR. internal class KonanIr(context: Context, irModule: IrModuleFragment): Ir(context, irModule) { override var symbols: KonanSymbols by Delegates.notNull() } internal class KonanSymbols( context: Context, irBuiltIns: IrBuiltIns, private val symbolTable: SymbolTable, lazySymbolTable: ReferenceSymbolTable, val functionIrClassFactory: BuiltInFictitiousFunctionIrClassFactory ): Symbols(context, irBuiltIns, symbolTable) { val entryPoint = findMainEntryPoint(context)?.let { symbolTable.referenceSimpleFunction(it) } override val externalSymbolTable = lazySymbolTable val nothing = symbolTable.referenceClass(builtIns.nothing) val throwable = symbolTable.referenceClass(builtIns.throwable) val enum = symbolTable.referenceClass(builtIns.enum) val nativePtr = symbolTable.referenceClass(context.nativePtr) val nativePointed = symbolTable.referenceClass(context.interopBuiltIns.nativePointed) val nativePtrType = nativePtr.typeWith(arguments = emptyList()) val nonNullNativePtr = symbolTable.referenceClass(context.nonNullNativePtr) val immutableBlobOf = symbolTable.referenceSimpleFunction(context.immutableBlobOf) private fun unsignedClass(unsignedType: UnsignedType): IrClassSymbol = classById(unsignedType.classId) override val uByte = unsignedClass(UnsignedType.UBYTE) override val uShort = unsignedClass(UnsignedType.USHORT) override val uInt = unsignedClass(UnsignedType.UINT) override val uLong = unsignedClass(UnsignedType.ULONG) val signedIntegerClasses = setOf(byte, short, int, long) val unsignedIntegerClasses = setOf(uByte, uShort, uInt, uLong) val allIntegerClasses = signedIntegerClasses + unsignedIntegerClasses val unsignedToSignedOfSameBitWidth = unsignedIntegerClasses.associate { it to when (it) { uByte -> byte uShort -> short uInt -> int uLong -> long else -> error(it.descriptor) } } val integerConversions = allIntegerClasses.flatMap { fromClass -> allIntegerClasses.map { toClass -> val name = Name.identifier("to${toClass.descriptor.name.asString().capitalize()}") val descriptor = if (fromClass in signedIntegerClasses && toClass in unsignedIntegerClasses) { builtInsPackage("kotlin") .getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) .single { it.dispatchReceiverParameter == null && it.extensionReceiverParameter?.type == fromClass.descriptor.defaultType && it.valueParameters.isEmpty() } } else { fromClass.descriptor.unsubstitutedMemberScope .getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) .single { it.extensionReceiverParameter == null && it.valueParameters.isEmpty() } } val symbol = symbolTable.referenceSimpleFunction(descriptor) (fromClass to toClass) to symbol } }.toMap() val arrayList = symbolTable.referenceClass(getArrayListClassDescriptor(context)) val symbolName = topLevelClass(RuntimeNames.symbolNameAnnotation) val filterExceptions = topLevelClass(RuntimeNames.filterExceptions) val exportForCppRuntime = topLevelClass(RuntimeNames.exportForCppRuntime) val objCMethodImp = symbolTable.referenceClass(context.interopBuiltIns.objCMethodImp) val onUnhandledException = internalFunction("OnUnhandledException") val interopNativePointedGetRawPointer = symbolTable.referenceSimpleFunction(context.interopBuiltIns.nativePointedGetRawPointer) val interopCPointer = symbolTable.referenceClass(context.interopBuiltIns.cPointer) val interopCstr = symbolTable.referenceSimpleFunction(context.interopBuiltIns.cstr.getter!!) val interopWcstr = symbolTable.referenceSimpleFunction(context.interopBuiltIns.wcstr.getter!!) val interopMemScope = symbolTable.referenceClass(context.interopBuiltIns.memScope) val interopCValue = symbolTable.referenceClass(context.interopBuiltIns.cValue) val interopCValues = symbolTable.referenceClass(context.interopBuiltIns.cValues) val interopCValuesRef = symbolTable.referenceClass(context.interopBuiltIns.cValuesRef) val interopCValueWrite = symbolTable.referenceSimpleFunction(context.interopBuiltIns.cValueWrite) val interopCValueRead = symbolTable.referenceSimpleFunction(context.interopBuiltIns.cValueRead) val interopAllocType = symbolTable.referenceSimpleFunction(context.interopBuiltIns.allocType) val interopTypeOf = symbolTable.referenceSimpleFunction(context.interopBuiltIns.typeOf) val interopCPointerGetRawValue = symbolTable.referenceSimpleFunction(context.interopBuiltIns.cPointerGetRawValue) val interopAllocObjCObject = symbolTable.referenceSimpleFunction(context.interopBuiltIns.allocObjCObject) val interopForeignObjCObject = interopClass("ForeignObjCObject") // These are possible supertypes of forward declarations - we need to reference them explicitly to force their deserialization. // TODO: Do it lazily. val interopCOpaque = symbolTable.referenceClass(context.interopBuiltIns.cOpaque) val interopObjCObject = symbolTable.referenceClass(context.interopBuiltIns.objCObject) val interopObjCObjectBase = symbolTable.referenceClass(context.interopBuiltIns.objCObjectBase) val interopObjCRelease = interopFunction("objc_release") val interopObjCRetain = interopFunction("objc_retain") val interopObjcRetainAutoreleaseReturnValue = interopFunction("objc_retainAutoreleaseReturnValue") val interopCreateObjCObjectHolder = interopFunction("createObjCObjectHolder") val interopCreateKotlinObjectHolder = interopFunction("createKotlinObjectHolder") val interopUnwrapKotlinObjectHolderImpl = interopFunction("unwrapKotlinObjectHolderImpl") val interopCreateObjCSuperStruct = interopFunction("createObjCSuperStruct") val interopGetMessenger = interopFunction("getMessenger") val interopGetMessengerStret = interopFunction("getMessengerStret") val interopGetObjCClass = symbolTable.referenceSimpleFunction(context.interopBuiltIns.getObjCClass) val interopObjCObjectSuperInitCheck = symbolTable.referenceSimpleFunction(context.interopBuiltIns.objCObjectSuperInitCheck) val interopObjCObjectInitBy = symbolTable.referenceSimpleFunction(context.interopBuiltIns.objCObjectInitBy) val interopObjCObjectRawValueGetter = symbolTable.referenceSimpleFunction(context.interopBuiltIns.objCObjectRawPtr) val interopNativePointedRawPtrGetter = symbolTable.referenceSimpleFunction(context.interopBuiltIns.nativePointedRawPtrGetter) val interopCPointerRawValue = symbolTable.referenceProperty(context.interopBuiltIns.cPointerRawValue) val interopInterpretObjCPointer = symbolTable.referenceSimpleFunction(context.interopBuiltIns.interpretObjCPointer) val interopInterpretObjCPointerOrNull = symbolTable.referenceSimpleFunction(context.interopBuiltIns.interpretObjCPointerOrNull) val interopInterpretNullablePointed = symbolTable.referenceSimpleFunction(context.interopBuiltIns.interpretNullablePointed) val interopInterpretCPointer = symbolTable.referenceSimpleFunction(context.interopBuiltIns.interpretCPointer) val interopCreateNSStringFromKString = symbolTable.referenceSimpleFunction(context.interopBuiltIns.CreateNSStringFromKString) val createForeignException = interopFunction("CreateForeignException") val interopObjCGetSelector = interopFunction("objCGetSelector") val interopCEnumVar = interopClass("CEnumVar") val nativeMemUtils = symbolTable.referenceClass(context.interopBuiltIns.nativeMemUtils) val readBits = interopFunction("readBits") val writeBits = interopFunction("writeBits") val objCExportTrapOnUndeclaredException = symbolTable.referenceSimpleFunction(context.builtIns.kotlinNativeInternal.getContributedFunctions( Name.identifier("trapOnUndeclaredException"), NoLookupLocation.FROM_BACKEND ).single()) val objCExportResumeContinuation = internalFunction("resumeContinuation") val objCExportResumeContinuationWithException = internalFunction("resumeContinuationWithException") val objCExportGetCoroutineSuspended = internalFunction("getCoroutineSuspended") val objCExportInterceptedContinuation = internalFunction("interceptedContinuation") val getNativeNullPtr = symbolTable.referenceSimpleFunction(context.getNativeNullPtr) val boxCachePredicates = BoxCache.values().associate { it to internalFunction("in${it.name.toLowerCase().capitalize()}BoxCache") } val boxCacheGetters = BoxCache.values().associate { it to internalFunction("getCached${it.name.toLowerCase().capitalize()}Box") } val immutableBlob = symbolTable.referenceClass( builtInsPackage("kotlin", "native").getContributedClassifier( Name.identifier("ImmutableBlob"), NoLookupLocation.FROM_BACKEND ) as ClassDescriptor ) val executeImpl = symbolTable.referenceSimpleFunction( builtIns.builtInsModule.getPackage(FqName("kotlin.native.concurrent")).memberScope .getContributedFunctions(Name.identifier("executeImpl"), NoLookupLocation.FROM_BACKEND) .single() ) val createCleaner = symbolTable.referenceSimpleFunction( builtIns.builtInsModule.getPackage(FqName("kotlin.native.internal")).memberScope .getContributedFunctions(Name.identifier("createCleaner"), NoLookupLocation.FROM_BACKEND) .single() ) val areEqualByValue = context.getKonanInternalFunctions("areEqualByValue").map { symbolTable.referenceSimpleFunction(it) }.associateBy { it.descriptor.valueParameters[0].type.computePrimitiveBinaryTypeOrNull()!! } val reinterpret = internalFunction("reinterpret") val ieee754Equals = context.getKonanInternalFunctions("ieee754Equals").map { symbolTable.referenceSimpleFunction(it) } val equals = context.builtIns.any.unsubstitutedMemberScope .getContributedFunctions(Name.identifier("equals"), NoLookupLocation.FROM_BACKEND) .single().let { symbolTable.referenceSimpleFunction(it) } val throwArithmeticException = internalFunction("ThrowArithmeticException") val throwIndexOutOfBoundsException = internalFunction("ThrowIndexOutOfBoundsException") override val throwNullPointerException = internalFunction("ThrowNullPointerException") override val throwNoWhenBranchMatchedException = internalFunction("ThrowNoWhenBranchMatchedException") override val throwTypeCastException = internalFunction("ThrowTypeCastException") override val throwKotlinNothingValueException = internalFunction("ThrowKotlinNothingValueException") val throwClassCastException = internalFunction("ThrowClassCastException") val throwInvalidReceiverTypeException = internalFunction("ThrowInvalidReceiverTypeException") val throwIllegalStateException = internalFunction("ThrowIllegalStateException") val throwIllegalStateExceptionWithMessage = internalFunction("ThrowIllegalStateExceptionWithMessage") val throwIllegalArgumentException = internalFunction("ThrowIllegalArgumentException") val throwIllegalArgumentExceptionWithMessage = internalFunction("ThrowIllegalArgumentExceptionWithMessage") override val throwUninitializedPropertyAccessException = internalFunction("ThrowUninitializedPropertyAccessException") override val stringBuilder = symbolTable.referenceClass( builtInsPackage("kotlin", "text").getContributedClassifier( Name.identifier("StringBuilder"), NoLookupLocation.FROM_BACKEND ) as ClassDescriptor ) override val defaultConstructorMarker = symbolTable.referenceClass( context.getKonanInternalClass("DefaultConstructorMarker") ) val checkProgressionStep = context.getKonanInternalFunctions("checkProgressionStep") .map { Pair(it.returnType, symbolTable.referenceSimpleFunction(it)) }.toMap() val getProgressionLast = context.getKonanInternalFunctions("getProgressionLast") .map { Pair(it.returnType, symbolTable.referenceSimpleFunction(it)) }.toMap() val arrayContentToString = arrays.associateBy( { it }, { findArrayExtension(it.descriptor, "contentToString") } ) val arrayContentHashCode = arrays.associateBy( { it }, { findArrayExtension(it.descriptor, "contentHashCode") } ) private val kotlinCollectionsPackageScope: MemberScope get() = builtInsPackage("kotlin", "collections") private fun findArrayExtension(descriptor: ClassDescriptor, name: String): IrSimpleFunctionSymbol { val functionDescriptor = kotlinCollectionsPackageScope .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND) .singleOrNull { it.valueParameters.isEmpty() && it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == descriptor && it.extensionReceiverParameter?.type?.isMarkedNullable == false && !it.isExpect } ?: error(descriptor.toString()) return symbolTable.referenceSimpleFunction(functionDescriptor) } override val copyRangeTo get() = TODO() fun getNoParamFunction(name: Name, receiverType: KotlinType): IrFunctionSymbol { val descriptor = receiverType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) .first { it.valueParameters.isEmpty() } return symbolTable.referenceFunction(descriptor) } val copyInto = arrays.map { symbol -> val packageViewDescriptor = builtIns.builtInsModule.getPackage(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME) val functionDescriptor = packageViewDescriptor.memberScope .getContributedFunctions(Name.identifier("copyInto"), NoLookupLocation.FROM_BACKEND) .single { !it.isExpect && it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == symbol.descriptor } symbol.descriptor to symbolTable.referenceSimpleFunction(functionDescriptor) }.toMap() val arrayGet = arrays.associateWith { it.descriptor.unsubstitutedMemberScope .getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND) .single().let { symbolTable.referenceSimpleFunction(it) } } val arraySet = arrays.associateWith { it.descriptor.unsubstitutedMemberScope .getContributedFunctions(Name.identifier("set"), NoLookupLocation.FROM_BACKEND) .single().let { symbolTable.referenceSimpleFunction(it) } } val arraySize = arrays.associateWith { it.descriptor.unsubstitutedMemberScope .getContributedVariables(Name.identifier("size"), NoLookupLocation.FROM_BACKEND) .single().let { symbolTable.referenceSimpleFunction(it.getter!!) } } val valuesForEnum = internalFunction("valuesForEnum") val valueOfForEnum = internalFunction("valueOfForEnum") val createUninitializedInstance = internalFunction("createUninitializedInstance") val initInstance = internalFunction("initInstance") val freeze = symbolTable.referenceSimpleFunction( builtInsPackage("kotlin", "native", "concurrent").getContributedFunctions( Name.identifier("freeze"), NoLookupLocation.FROM_BACKEND).single()) val println = symbolTable.referenceSimpleFunction( builtInsPackage("kotlin", "io").getContributedFunctions( Name.identifier("println"), NoLookupLocation.FROM_BACKEND) .single { it.valueParameters.singleOrNull()?.type == builtIns.stringType }) val anyNToString = symbolTable.referenceSimpleFunction( builtInsPackage("kotlin").getContributedFunctions( Name.identifier("toString"), NoLookupLocation.FROM_BACKEND) .single { it.extensionReceiverParameter?.type == builtIns.nullableAnyType}) override val getContinuation = internalFunction("getContinuation") override val returnIfSuspended = internalFunction("returnIfSuspended") val coroutineLaunchpad = internalFunction("coroutineLaunchpad") override val suspendCoroutineUninterceptedOrReturn = internalFunction("suspendCoroutineUninterceptedOrReturn") private val coroutinesIntrinsicsPackage = context.builtIns.builtInsModule.getPackage( context.config.configuration.languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope private val coroutinesPackage = context.builtIns.builtInsModule.getPackage( context.config.configuration.languageVersionSettings.coroutinesPackageFqName()).memberScope override val coroutineContextGetter = symbolTable.referenceSimpleFunction( coroutinesPackage .getContributedVariables(Name.identifier("coroutineContext"), NoLookupLocation.FROM_BACKEND) .single() .getter!!) override val coroutineGetContext = internalFunction("getCoroutineContext") override val coroutineImpl get() = TODO() val baseContinuationImpl = topLevelClass("kotlin.coroutines.native.internal.BaseContinuationImpl") val restrictedContinuationImpl = topLevelClass("kotlin.coroutines.native.internal.RestrictedContinuationImpl") val continuationImpl = topLevelClass("kotlin.coroutines.native.internal.ContinuationImpl") val invokeSuspendFunction = symbolTable.referenceSimpleFunction( baseContinuationImpl.descriptor.unsubstitutedMemberScope .getContributedFunctions(Name.identifier("invokeSuspend"), NoLookupLocation.FROM_BACKEND) .single() ) override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction( coroutinesIntrinsicsPackage .getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND) .filterNot { it.isExpect }.single().getter!! ) val cancellationException = topLevelClass(KonanFqNames.cancellationException) val kotlinResult = topLevelClass("kotlin.Result") val kotlinResultGetOrThrow = symbolTable.referenceSimpleFunction( builtInsPackage("kotlin") .getContributedFunctions(Name.identifier("getOrThrow"), NoLookupLocation.FROM_BACKEND) .single { it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == kotlinResult.descriptor } ) override val functionAdapter = symbolTable.referenceClass(context.getKonanInternalClass("FunctionAdapter")) val refClass = symbolTable.referenceClass(context.getKonanInternalClass("Ref")) val kFunctionImpl = symbolTable.referenceClass(context.reflectionTypes.kFunctionImpl) val kSuspendFunctionImpl = symbolTable.referenceClass(context.reflectionTypes.kSuspendFunctionImpl) val kMutableProperty0 = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0) val kMutableProperty1 = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1) val kMutableProperty2 = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2) val kProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty0Impl) val kProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty1Impl) val kProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kProperty2Impl) val kMutableProperty0Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty0Impl) val kMutableProperty1Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty1Impl) val kMutableProperty2Impl = symbolTable.referenceClass(context.reflectionTypes.kMutableProperty2Impl) val kLocalDelegatedPropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedPropertyImpl) val kLocalDelegatedMutablePropertyImpl = symbolTable.referenceClass(context.reflectionTypes.kLocalDelegatedMutablePropertyImpl) val typeOf = symbolTable.referenceSimpleFunction(context.reflectionTypes.typeOf) val kType = symbolTable.referenceClass(context.reflectionTypes.kType) val kVariance = symbolTable.referenceClass(context.reflectionTypes.kVariance) val getClassTypeInfo = internalFunction("getClassTypeInfo") val getObjectTypeInfo = internalFunction("getObjectTypeInfo") val kClassImpl = internalClass("KClassImpl") val kClassImplConstructor by lazy { kClassImpl.constructors.single() } val kClassUnsupportedImpl = internalClass("KClassUnsupportedImpl") val kClassUnsupportedImplConstructor by lazy { kClassUnsupportedImpl.constructors.single() } val kTypeParameterImpl = internalClass("KTypeParameterImpl") val kTypeImpl = internalClass("KTypeImpl") val kTypeImplForTypeParametersWithRecursiveBounds = internalClass("KTypeImplForTypeParametersWithRecursiveBounds") val kTypeProjection = symbolTable.referenceClass(context.reflectionTypes.kTypeProjection) private val kTypeProjectionCompanionDescriptor = context.reflectionTypes.kTypeProjection.companionObjectDescriptor!! val kTypeProjectionCompanion = symbolTable.referenceClass(kTypeProjectionCompanionDescriptor) val kTypeProjectionStar = symbolTable.referenceProperty( kTypeProjectionCompanionDescriptor.unsubstitutedMemberScope .getContributedVariables(Name.identifier("STAR"), NoLookupLocation.FROM_BACKEND).single() ) val kTypeProjectionFactories: Map = Variance.values().toList().associateWith { val factoryName = when (it) { Variance.INVARIANT -> "invariant" Variance.IN_VARIANCE -> "contravariant" Variance.OUT_VARIANCE -> "covariant" } symbolTable.referenceSimpleFunction( kTypeProjectionCompanionDescriptor.unsubstitutedMemberScope .getContributedFunctions(Name.identifier(factoryName), NoLookupLocation.FROM_BACKEND).single() ) } val emptyList = symbolTable.referenceSimpleFunction( kotlinCollectionsPackageScope .getContributedFunctions(Name.identifier("emptyList"), NoLookupLocation.FROM_BACKEND) .single { it.valueParameters.isEmpty() } ) val listOf = symbolTable.referenceSimpleFunction( kotlinCollectionsPackageScope .getContributedFunctions(Name.identifier("listOf"), NoLookupLocation.FROM_BACKEND) .single { it.valueParameters.size == 1 && it.valueParameters[0].isVararg } ) val listOfInternal = internalFunction("listOfInternal") val threadLocal = symbolTable.referenceClass( context.builtIns.builtInsModule.findClassAcrossModuleDependencies( ClassId.topLevel(KonanFqNames.threadLocal))!!) val sharedImmutable = symbolTable.referenceClass( context.builtIns.builtInsModule.findClassAcrossModuleDependencies( ClassId.topLevel(KonanFqNames.sharedImmutable))!!) private fun topLevelClass(fqName: String): IrClassSymbol = topLevelClass(FqName(fqName)) private fun topLevelClass(fqName: FqName): IrClassSymbol = classById(ClassId.topLevel(fqName)) private fun classById(classId: ClassId): IrClassSymbol = symbolTable.referenceClass(builtIns.builtInsModule.findClassAcrossModuleDependencies(classId)!!) private fun internalFunction(name: String): IrSimpleFunctionSymbol = symbolTable.referenceSimpleFunction(context.getKonanInternalFunctions(name).single()) private fun internalClass(name: String): IrClassSymbol = symbolTable.referenceClass(context.getKonanInternalClass(name)) private fun getKonanTestClass(className: String) = symbolTable.referenceClass( builtInsPackage("kotlin", "native", "internal", "test").getContributedClassifier( Name.identifier(className), NoLookupLocation.FROM_BACKEND ) as ClassDescriptor) private fun interopFunction(name: String) = symbolTable.referenceSimpleFunction( context.interopBuiltIns.packageScope .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND) .single() ) private fun interopClass(name: String) = symbolTable.referenceClass( context.interopBuiltIns.packageScope .getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND) as ClassDescriptor ) override fun functionN(n: Int) = functionIrClassFactory.functionN(n).symbol override fun suspendFunctionN(n: Int) = functionIrClassFactory.suspendFunctionN(n).symbol fun kFunctionN(n: Int) = functionIrClassFactory.kFunctionN(n).symbol fun kSuspendFunctionN(n: Int) = functionIrClassFactory.kSuspendFunctionN(n).symbol fun getKFunctionType(returnType: IrType, parameterTypes: List) = kFunctionN(parameterTypes.size).typeWith(parameterTypes + returnType) val baseClassSuite = getKonanTestClass("BaseClassSuite") val topLevelSuite = getKonanTestClass("TopLevelSuite") val testFunctionKind = getKonanTestClass("TestFunctionKind") private val testFunctionKindCache = TestProcessor.FunctionKind.values().associate { val symbol = if (it.runtimeKindString.isEmpty()) null else symbolTable.referenceEnumEntry(testFunctionKind.descriptor.unsubstitutedMemberScope.getContributedClassifier( Name.identifier(it.runtimeKindString), NoLookupLocation.FROM_BACKEND ) as ClassDescriptor) it to symbol } fun getTestFunctionKind(kind: TestProcessor.FunctionKind) = testFunctionKindCache[kind]!! } private fun getArrayListClassDescriptor(context: Context): ClassDescriptor { val module = context.builtIns.builtInsModule val pkg = module.getPackage(FqName.fromSegments(listOf("kotlin", "collections"))) val classifier = pkg.memberScope.getContributedClassifier(Name.identifier("ArrayList"), NoLookupLocation.FROM_BACKEND) return classifier as ClassDescriptor } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/IrTypeAsKotlinType.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf val IrClassifierSymbol.typeWithoutArguments: IrType get() = when (this) { is IrClassSymbol -> { require(this.descriptor.declaredTypeParameters.isEmpty()) this.typeWith(arguments = emptyList()) } is IrTypeParameterSymbol -> this.defaultType else -> error(this) } val IrClassifierSymbol.typeWithStarProjections get() = when (this) { is IrClassSymbol -> createType( hasQuestionMark = false, arguments = this.descriptor.declaredTypeParameters.map { IrStarProjectionImpl } ) is IrTypeParameterSymbol -> this.defaultType else -> error(this) } val IrTypeParameterSymbol.defaultType: IrType get() = IrSimpleTypeImpl( this, false, emptyList(), emptyList() ) fun IrClass.typeWith(arguments: List) = this.symbol.typeWith(arguments) fun IrType.containsNull(): Boolean = if (this is IrSimpleType) { if (this.hasQuestionMark) { true } else { val classifier = this.classifier when (classifier) { is IrClassSymbol -> false is IrTypeParameterSymbol -> classifier.owner.superTypes.any { it.containsNull() } else -> error(classifier) } } } else { true } // TODO: get rid of these: fun IrType.isSubtypeOf(other: KotlinType): Boolean = this.toKotlinType().isSubtypeOf(other) fun IrType.isSubtypeOf(other: IrType): Boolean = this.isSubtypeOf(other.toKotlinType()) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid class ModuleIndex(val module: IrModuleFragment) { /** * Contains all classes declared in [module] */ val classes: Map /** * Contains all functions declared in [module] */ val functions: Map init { classes = mutableMapOf() functions = mutableMapOf() module.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { super.visitClass(declaration) classes[declaration.descriptor] = declaration } override fun visitFunction(declaration: IrFunction) { super.visitFunction(declaration) functions[declaration.descriptor] = declaration } }) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/NewIrUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary import org.jetbrains.kotlin.backend.konan.llvm.KonanMetadata import org.jetbrains.kotlin.backend.konan.serialization.KonanFileMetadataSource import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.isPublicApi import org.jetbrains.kotlin.ir.types.IdSignatureValues import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.isMarkedNullable import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.safeAs private fun IrClass.isClassTypeWithSignature(signature: IdSignature.PublicSignature): Boolean { if (!symbol.isPublicApi) return false return signature == symbol.signature } fun IrClass.isUnit() = this.isClassTypeWithSignature(IdSignatureValues.unit) fun IrClass.isKotlinArray() = this.isClassTypeWithSignature(IdSignatureValues.array) val IrClass.superClasses get() = this.superTypes.map { it.classifierOrFail as IrClassSymbol } fun IrClass.getSuperClassNotAny() = this.superClasses.map { it.owner }.atMostOne { !it.isInterface && !it.isAny() } fun IrClass.isAny() = this.isClassTypeWithSignature(IdSignatureValues.any) fun IrClass.isNothing() = this.isClassTypeWithSignature(IdSignatureValues.nothing) fun IrClass.getSuperInterfaces() = this.superClasses.map { it.owner }.filter { it.isInterface } // Note: psi2ir doesn't set `origin = FAKE_OVERRIDE` for fields and properties yet. val IrProperty.isReal: Boolean get() = this.descriptor.kind.isReal val IrField.isReal: Boolean get() = this.descriptor.kind.isReal val IrSimpleFunction.isOverridable: Boolean get() = visibility != DescriptorVisibilities.PRIVATE && modality != Modality.FINAL && (parent as? IrClass)?.isFinalClass != true val IrFunction.isOverridable get() = this is IrSimpleFunction && this.isOverridable val IrFunction.isOverridableOrOverrides get() = this is IrSimpleFunction && (this.isOverridable || this.overriddenSymbols.isNotEmpty()) val IrClass.isFinalClass: Boolean get() = modality == Modality.FINAL fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing() inline fun IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? { val annotation = this.annotations.findAnnotation(fqName) ?: return null for (index in 0 until annotation.valueArgumentsCount) { val parameter = annotation.symbol.owner.valueParameters[index] if (parameter.name == Name.identifier(argumentName)) { val actual = annotation.getValueArgument(index).safeAs>() return actual?.value } } return null } fun IrValueParameter.isInlineParameter(): Boolean = !this.isNoinline && (this.type.isFunction() || this.type.isSuspendFunction()) && !this.type.isMarkedNullable() val IrDeclaration.parentDeclarationsWithSelf: Sequence get() = generateSequence(this, { it.parent as? IrDeclaration }) fun IrClass.companionObject() = this.declarations.filterIsInstance().atMostOne { it.isCompanion } fun buildSimpleAnnotation(irBuiltIns: IrBuiltIns, startOffset: Int, endOffset: Int, annotationClass: IrClass, vararg args: String): IrConstructorCall { val constructor = annotationClass.constructors.let { it.singleOrNull() ?: it.single { ctor -> ctor.valueParameters.size == args.size } } return IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, constructor.returnType, constructor.symbol).apply { args.forEachIndexed { index, arg -> assert(constructor.valueParameters[index].type == irBuiltIns.stringType) { "String type expected but was ${constructor.valueParameters[index].type}" } putValueArgument(index, IrConstImpl.string(startOffset, endOffset, irBuiltIns.stringType, arg)) } } } internal fun IrExpression.isBoxOrUnboxCall() = (this is IrCall && symbol.owner.origin == DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION) val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library val IrModuleFragment.konanLibrary get() = (this as? KonanIrModuleFragmentImpl)?.konanLibrary ?: descriptor.konanLibrary val IrPackageFragment.konanLibrary get() = if (this is IrFile) this.konanLibrary else this.packageFragmentDescriptor.containingDeclaration.konanLibrary val IrFile.konanLibrary get() = (metadata as? KonanFileMetadataSource)?.module?.konanLibrary ?: packageFragmentDescriptor.containingDeclaration.konanLibrary val IrDeclaration.konanLibrary: KotlinLibrary? get() { ((this as? IrMetadataSourceOwner)?.metadata as? KonanMetadata)?.let { return it.konanLibrary } val result = when (val parent = parent) { is IrFile -> parent.konanLibrary is IrPackageFragment -> parent.packageFragmentDescriptor.containingDeclaration.konanLibrary is IrDeclaration -> parent.konanLibrary else -> TODO("Unexpected declaration parent: $parent") } if (this is IrMetadataSourceOwner && this !is IrLazyDeclarationBase) metadata = KonanMetadata(metadata?.name, result) return result } fun IrDeclaration.isFromInteropLibrary() = konanLibrary?.isInteropLibrary() == true ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.backend.konan.InteropBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.builders.IrBuilder import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf import org.jetbrains.kotlin.types.KotlinType internal inline fun ClassDescriptor.findDeclarationByName(name: String): T? = unsubstitutedMemberScope .getContributedDescriptors() .filterIsInstance() .firstOrNull { it.name.identifier == name } /** * Provides a set of functions and properties that helps * to translate descriptor declarations to corresponding IR. */ internal interface DescriptorToIrTranslationMixin { val symbolTable: SymbolTable val irBuiltIns: IrBuiltIns val typeTranslator: TypeTranslator val postLinkageSteps: MutableList<() -> Unit> fun invokePostLinkageSteps() { postLinkageSteps.forEach { it() } } fun KotlinType.toIrType() = typeTranslator.translateType(this) /** * Declares [IrClass] instance from [descriptor] and populates it with * supertypes, parameter declaration and fake overrides. * Additional elements are passed via [builder] callback. */ fun createClass(descriptor: ClassDescriptor, builder: (IrClass) -> Unit): IrClass = symbolTable.declareClass(descriptor) { symbolTable.irFactory.createIrClassFromDescriptor( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, it, descriptor ) }.also { irClass -> symbolTable.withScope(irClass) { irClass.superTypes += descriptor.typeConstructor.supertypes.map { it.toIrType() } irClass.generateAnnotations() irClass.createParameterDeclarations() builder(irClass) createFakeOverrides(descriptor).forEach(irClass::addMember) } } private fun createFakeOverrides(classDescriptor: ClassDescriptor): List { val fakeOverrides = classDescriptor.unsubstitutedMemberScope .getContributedDescriptors() .filterIsInstance() .filter { it.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE } return fakeOverrides.map { when (it) { is PropertyDescriptor -> createProperty(it) is FunctionDescriptor -> createFunction(it, IrDeclarationOrigin.FAKE_OVERRIDE) else -> error("Unexpected fake override descriptor: $it") } } } fun createConstructor(constructorDescriptor: ClassConstructorDescriptor): IrConstructor { val irConstructor = symbolTable.declareConstructor(constructorDescriptor) { with(constructorDescriptor) { IrConstructorImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, it, name, visibility, IrUninitializedType, isInline, isEffectivelyExternal(), isPrimary, isExpect ) } } irConstructor.valueParameters += constructorDescriptor.valueParameters.map { valueParameterDescriptor -> symbolTable.declareValueParameter( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, valueParameterDescriptor, valueParameterDescriptor.type.toIrType()).also { it.parent = irConstructor } } irConstructor.returnType = constructorDescriptor.returnType.toIrType() irConstructor.generateAnnotations() return irConstructor } fun createProperty(propertyDescriptor: PropertyDescriptor): IrProperty { val origin = if (propertyDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { IrDeclarationOrigin.FAKE_OVERRIDE } else { IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB } val irProperty = symbolTable.declareProperty(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, origin, propertyDescriptor) irProperty.getter = propertyDescriptor.getter?.let { val irGetter = createFunction(it, origin) irGetter.correspondingPropertySymbol = irProperty.symbol irGetter } irProperty.setter = propertyDescriptor.setter?.let { val irSetter = createFunction(it, origin) irSetter.correspondingPropertySymbol = irProperty.symbol irSetter } irProperty.generateAnnotations() return irProperty } fun createFunction( functionDescriptor: FunctionDescriptor, origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB ): IrSimpleFunction { val irFunction = symbolTable.declareSimpleFunctionWithOverrides(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, origin, functionDescriptor) symbolTable.withScope(irFunction) { irFunction.returnType = functionDescriptor.returnType!!.toIrType() irFunction.valueParameters += functionDescriptor.valueParameters.map { symbolTable.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) } irFunction.dispatchReceiverParameter = functionDescriptor.dispatchReceiverParameter?.let { symbolTable.declareValueParameter(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, it, it.type.toIrType()) } irFunction.generateAnnotations() } return irFunction } private fun IrDeclaration.generateAnnotations() { annotations += descriptor.annotations.map { typeTranslator.constantValueGenerator.generateAnnotationConstructorCall(it)!! } } } internal fun IrBuilder.irInstanceInitializer(classSymbol: IrClassSymbol): IrExpression = IrInstanceInitializerCallImpl( startOffset, endOffset, classSymbol, context.irBuiltIns.unitType ) internal fun ClassDescriptor.implementsCEnum(interopBuiltIns: InteropBuiltIns): Boolean = interopBuiltIns.cEnum in this.getSuperInterfaces() internal fun ClassDescriptor.inheritsFromCStructVar(interopBuiltIns: InteropBuiltIns): Boolean = interopBuiltIns.cStructVar == this.getSuperClassNotAny() /** * All enums that come from interop library implement CEnum interface. * This function checks that given symbol located in subtree of * CEnum inheritor. */ internal fun IrSymbol.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? = descriptor.findCEnumDescriptor(interopBuiltIns) internal fun DeclarationDescriptor.findCEnumDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? = parentsWithSelf.filterIsInstance().firstOrNull { it.implementsCEnum(interopBuiltIns) } /** * All structs that come from interop library inherit from CStructVar class. * This function checks that given symbol located in subtree of * CStructVar inheritor. */ internal fun IrSymbol.findCStructDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? = descriptor.findCStructDescriptor(interopBuiltIns) internal fun DeclarationDescriptor.findCStructDescriptor(interopBuiltIns: InteropBuiltIns): ClassDescriptor? = parentsWithSelf.filterIsInstance().firstOrNull { it.inheritsFromCStructVar(interopBuiltIns) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForCEnumAndCStructStubs.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.backend.konan.InteropBuiltIns import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumByValueFunctionGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumClassGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarCompanionGenerator import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter /** * For the most of descriptors that come from metadata-based interop libraries * we generate a lazy IR. * We use a different approach for CEnums and CStructVars and generate IR eagerly. Motivation: * 1. CEnums are "real" Kotlin enums. Thus, we need apply the same compilation approach * as we use for usual Kotlin enums. * Eager generation allows to reuse [EnumClassLowering], [EnumConstructorsLowering] and other * compiler phases. * 2. It is an easier and more obvious approach. Since implementation of metadata-based * libraries generation already took too much time we take an easier approach here. */ internal class IrProviderForCEnumAndCStructStubs( context: GeneratorContext, private val interopBuiltIns: InteropBuiltIns, symbols: KonanSymbols ) { /** * TODO: integrate this provider into [KonanIrLinker.KonanInteropModuleDeserializer] */ private val symbolTable: SymbolTable = context.symbolTable private val cEnumByValueFunctionGenerator = CEnumByValueFunctionGenerator(context, symbols) private val cEnumCompanionGenerator = CEnumCompanionGenerator(context, cEnumByValueFunctionGenerator) private val cEnumVarClassGenerator = CEnumVarClassGenerator(context, interopBuiltIns) private val cEnumClassGenerator = CEnumClassGenerator(context, cEnumCompanionGenerator, cEnumVarClassGenerator) private val cStructCompanionGenerator = CStructVarCompanionGenerator(context, interopBuiltIns) private val cStructClassGenerator = CStructVarClassGenerator(context, interopBuiltIns, cStructCompanionGenerator) fun isCEnumOrCStruct(declarationDescriptor: DeclarationDescriptor): Boolean = declarationDescriptor.run { findCEnumDescriptor(interopBuiltIns) ?: findCStructDescriptor(interopBuiltIns) } != null fun referenceAllEnumsAndStructsFrom(interopModule: ModuleDescriptor) = interopModule.getPackageFragments() .flatMap { it.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) } .filterIsInstance() .filter { it.implementsCEnum(interopBuiltIns) || it.inheritsFromCStructVar(interopBuiltIns) } .forEach { symbolTable.referenceClass(it) } private fun generateIrIfNeeded(symbol: IrSymbol, file: IrFile) { // TODO: These `findOrGenerate` calls generate a whole subtree. // This a simple but clearly suboptimal solution. symbol.findCEnumDescriptor(interopBuiltIns)?.let { enumDescriptor -> cEnumClassGenerator.findOrGenerateCEnum(enumDescriptor, file) } symbol.findCStructDescriptor(interopBuiltIns)?.let { structDescriptor -> cStructClassGenerator.findOrGenerateCStruct(structDescriptor, file) } } /** * We postpone generation of bodies until IR linkage is complete. * This way we ensure that all used symbols are resolved. */ fun generateBodies() { cEnumCompanionGenerator.invokePostLinkageSteps() cEnumByValueFunctionGenerator.invokePostLinkageSteps() cEnumClassGenerator.invokePostLinkageSteps() cEnumVarClassGenerator.invokePostLinkageSteps() cStructClassGenerator.invokePostLinkageSteps() cStructCompanionGenerator.invokePostLinkageSteps() } fun getDeclaration(descriptor: DeclarationDescriptor, idSignature: IdSignature, file: IrFile, symbolKind: BinarySymbolData.SymbolKind): IrSymbolOwner { return symbolTable.run { when (symbolKind) { BinarySymbolData.SymbolKind.CLASS_SYMBOL -> declareClassFromLinker(descriptor as ClassDescriptor, idSignature) { s -> generateIrIfNeeded(s, file) s.owner } BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> declareEnumEntryFromLinker(descriptor as ClassDescriptor, idSignature) { s -> generateIrIfNeeded(s, file) s.owner } BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> declareSimpleFunctionFromLinker(descriptor as FunctionDescriptor, idSignature) { s -> generateIrIfNeeded(s, file) s.owner } BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> declarePropertyFromLinker(descriptor as PropertyDescriptor, idSignature) { s -> generateIrIfNeeded(s, file) s.owner } else -> error("Unexpected symbol kind $symbolKind for sig $idSignature") } } } companion object { const val cTypeDefinitionsFileName = "CTypeDefinitions" } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cenum import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.findDeclarationByName import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.util.OperatorNameConventions /** * Generate IR for function that returns appropriate enum entry for the provided integral value. */ internal class CEnumByValueFunctionGenerator( context: GeneratorContext, private val symbols: KonanSymbols ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generateByValueFunction( companionIrClass: IrClass, valuesIrFunctionSymbol: IrSimpleFunctionSymbol ): IrFunction { val byValueFunctionDescriptor = companionIrClass.descriptor.findDeclarationByName("byValue")!! val byValueIrFunction = createFunction(byValueFunctionDescriptor) val irValueParameter = byValueIrFunction.valueParameters.first() // val values: Array = values() // var i: Int = 0 // val size: Int = values.size // while (i < size) { // val entry: E = values[i] // if (entry.value == arg) { // return entry // } // i++ // } // throw NPE postLinkageSteps.add { byValueIrFunction.body = irBuilder(irBuiltIns, byValueIrFunction.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +irReturn(irBlock { val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true) val inductionVariable = irTemporary(irInt(0), isMutable = true) val arrayClass = values.type.classOrNull!! val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall -> irCall.dispatchReceiver = irGet(values) } val getElementFn = symbols.arrayGet.getValue(arrayClass) val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType) val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass) +irWhile().also { loop -> loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall -> irCall.putValueArgument(0, irGet(inductionVariable)) irCall.putValueArgument(1, valuesSize) } loop.body = irBlock { val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall -> irCall.dispatchReceiver = irGet(values) irCall.putValueArgument(0, irGet(inductionVariable)) }, isMutable = true) val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!! val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter) +irIfThenElse( type = irBuiltIns.unitType, condition = irEquals(entryValue, irGet(irValueParameter)), thenPart = irReturn(irGet(entry)), elsePart = irSetVar( inductionVariable, irCallOp(plusFun, irBuiltIns.intType, irGet(inductionVariable), irInt(1) ) ) ) } } +IrCallImpl.fromSymbolOwner(startOffset, endOffset, irBuiltIns.nothingType, symbols.throwNullPointerException) }) } } return byValueIrFunction } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cenum import org.jetbrains.kotlin.backend.konan.descriptors.enumEntries import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.findDeclarationByName import org.jetbrains.kotlin.backend.konan.ir.interop.irInstanceInitializer import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.generators.DeclarationGenerator import org.jetbrains.kotlin.psi2ir.generators.EnumClassMembersGenerator import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult private fun extractConstantValue(descriptor: DeclarationDescriptor, type: String): ConstantValue<*>? = descriptor.annotations .findAnnotation(cEnumEntryValueAnnotationName.child(Name.identifier(type))) ?.allValueArguments ?.getValue(Name.identifier("value")) private val cEnumEntryValueAnnotationName = FqName("kotlinx.cinterop.internal.ConstantValue") private val cEnumEntryValueTypes = setOf( "Byte", "Short", "Int", "Long", "UByte", "UShort", "UInt", "ULong" ) internal class CEnumClassGenerator( val context: GeneratorContext, private val cEnumCompanionGenerator: CEnumCompanionGenerator, private val cEnumVarClassGenerator: CEnumVarClassGenerator ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() private val enumClassMembersGenerator = EnumClassMembersGenerator(DeclarationGenerator(context)) /** * Searches for an IR class for [classDescriptor] in symbol table. * Generates one if absent. */ fun findOrGenerateCEnum(classDescriptor: ClassDescriptor, parent: IrDeclarationContainer): IrClass { val irClassSymbol = symbolTable.referenceClass(classDescriptor) return if (!irClassSymbol.isBound) { provideIrClassForCEnum(classDescriptor).also { it.patchDeclarationParents(parent) parent.declarations += it } } else { irClassSymbol.owner } } /** * The main function that for given [descriptor] of the enum generates the whole * IR tree including entries, CEnumVar class, and companion objects. */ private fun provideIrClassForCEnum(descriptor: ClassDescriptor): IrClass = createClass(descriptor) { enumIrClass -> enumIrClass.addMember(createEnumPrimaryConstructor(descriptor)) enumIrClass.addMember(createValueProperty(enumIrClass)) descriptor.enumEntries.mapTo(enumIrClass.declarations) { entryDescriptor -> createEnumEntry(descriptor, entryDescriptor) } enumClassMembersGenerator.generateSpecialMembers(enumIrClass) enumIrClass.addChild(cEnumCompanionGenerator.generate(enumIrClass)) enumIrClass.addChild(cEnumVarClassGenerator.generate(enumIrClass)) } /** * Creates `value` property that stores integral value of the enum. */ private fun createValueProperty(irClass: IrClass): IrProperty { val propertyDescriptor = irClass.descriptor .findDeclarationByName("value") ?: error("No `value` property in ${irClass.name}") val irProperty = createProperty(propertyDescriptor) symbolTable.withScope(irProperty) { irProperty.backingField = symbolTable.declareField( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor, propertyDescriptor.type.toIrType(), DescriptorVisibilities.PRIVATE ).also { postLinkageSteps.add { it.initializer = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run { irExprBody(irGet(irClass.primaryConstructor!!.valueParameters[0])) } } } } val getter = irProperty.getter!! getter.correspondingPropertySymbol = irProperty.symbol postLinkageSteps.add { getter.body = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +irReturn( irGetField( irGet(getter.dispatchReceiverParameter!!), irProperty.backingField!! ) ) } } return irProperty } private fun createEnumEntry(enumDescriptor: ClassDescriptor, entryDescriptor: ClassDescriptor): IrEnumEntry { val enumEntry = symbolTable.declareEnumEntry( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, entryDescriptor ) val constructorSymbol = symbolTable.referenceConstructor(enumDescriptor.unsubstitutedPrimaryConstructor!!) postLinkageSteps.add { enumEntry.initializerExpression = IrExpressionBodyImpl(IrEnumConstructorCallImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, type = irBuiltIns.unitType, symbol = constructorSymbol, typeArgumentsCount = 0, valueArgumentsCount = constructorSymbol.owner.valueParameters.size ).also { it.putValueArgument(0, extractEnumEntryValue(entryDescriptor)) }) } return enumEntry } /** * Every enum entry that came from metadata-based interop library is annotated with * [kotlinx.cinterop.internal.ConstantValue] annotation that holds internal constant value of the * corresponding entry. * * This function extracts value from the annotation. */ private fun extractEnumEntryValue(entryDescriptor: ClassDescriptor): IrExpression = cEnumEntryValueTypes.firstNotNullResult { extractConstantValue(entryDescriptor, it) } ?.let { context.constantValueGenerator.generateConstantValueAsExpression(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, it) } ?: error("Enum entry $entryDescriptor has no appropriate @$cEnumEntryValueAnnotationName annotation!") private fun createEnumPrimaryConstructor(descriptor: ClassDescriptor): IrConstructor { val irConstructor = createConstructor(descriptor.unsubstitutedPrimaryConstructor!!) val enumConstructor = context.builtIns.enum.constructors.single() val constructorSymbol = symbolTable.referenceConstructor(enumConstructor) val classSymbol = symbolTable.referenceClass(descriptor) val type = descriptor.defaultType.toIrType() postLinkageSteps.add { irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) .irBlockBody { +IrEnumConstructorCallImpl( startOffset, endOffset, context.irBuiltIns.unitType, constructorSymbol, typeArgumentsCount = 1, // kotlin.Enum has a single type parameter. valueArgumentsCount = constructorSymbol.owner.valueParameters.size ).apply { putTypeArgument(0, type) } +irInstanceInitializer(classSymbol) } } return irConstructor } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumCompanionGenerator.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cenum import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.irInstanceInitializer import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns private val cEnumEntryAliasAnnonation = FqName("kotlinx.cinterop.internal.CEnumEntryAlias") internal class CEnumCompanionGenerator( context: GeneratorContext, private val cEnumByValueFunctionGenerator: CEnumByValueFunctionGenerator ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() // Depends on already generated `.values()` irFunction. fun generate(enumClass: IrClass): IrClass = createClass(enumClass.descriptor.companionObjectDescriptor!!) { companionIrClass -> companionIrClass.superTypes += irBuiltIns.anyType companionIrClass.addMember(createCompanionConstructor(companionIrClass.descriptor)) val valuesFunction = enumClass.functions.single { it.name.identifier == "values" }.symbol val byValueIrFunction = cEnumByValueFunctionGenerator .generateByValueFunction(companionIrClass, valuesFunction) companionIrClass.addMember(byValueIrFunction) findEntryAliases(companionIrClass.descriptor) .map { declareEntryAliasProperty(it, enumClass) } .forEach(companionIrClass::addMember) } private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor): IrConstructor { val anyPrimaryConstructor = companionObjectDescriptor.builtIns.any.unsubstitutedPrimaryConstructor!! val superConstructorSymbol = symbolTable.referenceConstructor(anyPrimaryConstructor) val classSymbol = symbolTable.referenceClass(companionObjectDescriptor) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { postLinkageSteps.add { it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +IrDelegatingConstructorCallImpl.fromSymbolOwner( startOffset, endOffset, context.irBuiltIns.unitType, superConstructorSymbol ) +irInstanceInitializer(classSymbol) } } } } /** * Returns all properties in companion object that represent aliases to * enum entries. */ private fun findEntryAliases(companionDescriptor: ClassDescriptor) = companionDescriptor.defaultType.memberScope.getContributedDescriptors() .filterIsInstance() .filter { it.annotations.hasAnnotation(cEnumEntryAliasAnnonation) } private fun fundCorrespondingEnumEntrySymbol(aliasDescriptor: PropertyDescriptor, irClass: IrClass): IrEnumEntrySymbol { val enumEntryName = aliasDescriptor.annotations .findAnnotation(cEnumEntryAliasAnnonation)!! .getArgumentValueOrNull("entryName") return irClass.declarations.filterIsInstance() .single { it.name.identifier == enumEntryName }.symbol } private fun generateAliasGetterBody(getter: IrSimpleFunction, entrySymbol: IrEnumEntrySymbol, enumClass: IrClass): IrBody = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +irReturn( IrGetEnumValueImpl(startOffset, endOffset, enumClass.defaultType, entrySymbol) ) } private fun declareEntryAliasProperty(propertyDescriptor: PropertyDescriptor, enumClass: IrClass): IrProperty { val entrySymbol = fundCorrespondingEnumEntrySymbol(propertyDescriptor, enumClass) return createProperty(propertyDescriptor).also { postLinkageSteps.add { it.getter!!.body = generateAliasGetterBody(it.getter!!, entrySymbol, enumClass) } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumVarClassGenerator.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cenum import org.jetbrains.kotlin.backend.konan.InteropBuiltIns import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.irInstanceInitializer import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irInt import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.addMember import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext private val typeSizeAnnotation = FqName("kotlinx.cinterop.internal.CEnumVarTypeSize") internal class CEnumVarClassGenerator( context: GeneratorContext, private val interopBuiltIns: InteropBuiltIns ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generate(enumIrClass: IrClass): IrClass { val enumVarClassDescriptor = enumIrClass.descriptor.unsubstitutedMemberScope .getContributedClassifier(Name.identifier("Var"), NoLookupLocation.FROM_BACKEND)!! as ClassDescriptor return createClass(enumVarClassDescriptor) { enumVarClass -> enumVarClass.addMember(createPrimaryConstructor(enumVarClass)) enumVarClass.addMember(createCompanionObject(enumVarClass)) enumVarClass.addMember(createValueProperty(enumVarClass)) } } private fun createValueProperty(enumVarClass: IrClass): IrProperty { val valuePropertyDescriptor = enumVarClass.descriptor.unsubstitutedMemberScope .getContributedVariables(Name.identifier("value"), NoLookupLocation.FROM_BACKEND).single() return createProperty(valuePropertyDescriptor) } private fun createPrimaryConstructor(enumVarClass: IrClass): IrConstructor { val irConstructor = createConstructor(enumVarClass.descriptor.unsubstitutedPrimaryConstructor!!) val enumVarConstructorSymbol = symbolTable.referenceConstructor( interopBuiltIns.cEnumVar.unsubstitutedPrimaryConstructor!! ) val classSymbol = symbolTable.referenceClass(enumVarClass.descriptor) postLinkageSteps.add { irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +IrDelegatingConstructorCallImpl.fromSymbolOwner( startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol ).also { it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) } +irInstanceInitializer(classSymbol) } } return irConstructor } private fun createCompanionObject(enumVarClass: IrClass): IrClass = createClass(enumVarClass.descriptor.companionObjectDescriptor!!) { companionIrClass -> val typeSize = companionIrClass.descriptor.annotations .findAnnotation(typeSizeAnnotation)!! .getArgumentValueOrNull("size")!! companionIrClass.addMember(createCompanionConstructor(companionIrClass.descriptor, typeSize)) } private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, typeSize: Int): IrConstructor { val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cPrimitiveVarType.unsubstitutedPrimaryConstructor!!) val classSymbol = symbolTable.referenceClass(companionObjectDescriptor) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { postLinkageSteps.add { it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +IrDelegatingConstructorCallImpl.fromSymbolOwner( startOffset, endOffset, context.irBuiltIns.unitType, superConstructorSymbol ).also { it.putValueArgument(0, irInt(typeSize)) } +irInstanceInitializer(classSymbol) } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cstruct import org.jetbrains.kotlin.backend.konan.InteropBuiltIns import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.irInstanceInitializer import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.declarations.addMember import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext internal class CStructVarClassGenerator( context: GeneratorContext, private val interopBuiltIns: InteropBuiltIns, private val companionGenerator: CStructVarCompanionGenerator ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun findOrGenerateCStruct(classDescriptor: ClassDescriptor, parent: IrDeclarationContainer): IrClass { val irClassSymbol = symbolTable.referenceClass(classDescriptor) return if (!irClassSymbol.isBound) { provideIrClassForCStruct(classDescriptor).also { it.patchDeclarationParents(parent) parent.declarations += it } } else { irClassSymbol.owner } } private fun provideIrClassForCStruct(descriptor: ClassDescriptor): IrClass = createClass(descriptor) { irClass -> irClass.addMember(createPrimaryConstructor(irClass)) irClass.addMember(companionGenerator.generate(descriptor)) descriptor.unsubstitutedMemberScope .getContributedDescriptors() .filterIsInstance() .filter { it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE } .map(this::createProperty) .forEach(irClass::addMember) } private fun createPrimaryConstructor(irClass: IrClass): IrConstructor { val enumVarConstructorSymbol = symbolTable.referenceConstructor( interopBuiltIns.cStructVar.unsubstitutedPrimaryConstructor!! ) return createConstructor(irClass.descriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor -> postLinkageSteps.add { irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +IrDelegatingConstructorCallImpl.fromSymbolOwner( startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol ).also { it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) } +irInstanceInitializer(symbolTable.referenceClass(irClass.descriptor)) } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarCompanionGenerator.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.ir.interop.cstruct import org.jetbrains.kotlin.backend.konan.InteropBuiltIns import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull import org.jetbrains.kotlin.backend.konan.ir.interop.DescriptorToIrTranslationMixin import org.jetbrains.kotlin.backend.konan.ir.interop.irInstanceInitializer import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irInt import org.jetbrains.kotlin.ir.builders.irLong import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.addMember import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.irBuilder import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext private val varTypeAnnotationFqName = FqName("kotlinx.cinterop.internal.CStruct.VarType") internal class CStructVarCompanionGenerator( context: GeneratorContext, private val interopBuiltIns: InteropBuiltIns ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generate(structDescriptor: ClassDescriptor): IrClass = createClass(structDescriptor.companionObjectDescriptor!!) { companionIrClass -> val annotation = companionIrClass.descriptor.annotations .findAnnotation(varTypeAnnotationFqName)!! val size = annotation.getArgumentValueOrNull("size")!! val align = annotation.getArgumentValueOrNull("align")!! companionIrClass.addMember(createCompanionConstructor(companionIrClass.descriptor, size, align)) } private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, size: Long, align: Int): IrConstructor { val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cStructVarType.unsubstitutedPrimaryConstructor!!) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor -> postLinkageSteps.add { irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { +IrDelegatingConstructorCallImpl.fromSymbolOwner( startOffset, endOffset, context.irBuiltIns.unitType, superConstructorSymbol ).also { it.putValueArgument(0, irLong(size)) it.putValueArgument(1, irInt(align)) } +irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor)) } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.LLVMTypeRef import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant import org.jetbrains.kotlin.backend.common.serialization.mangle.SpecialDeclarationType import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.descriptors.externalSymbolOrThrow import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.ir.isUnit import org.jetbrains.kotlin.backend.konan.isExternalObjCClass import org.jetbrains.kotlin.backend.konan.isKotlinObjCClass import org.jetbrains.kotlin.backend.konan.serialization.AbstractKonanIrMangler import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.findAnnotation import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.isSuspend import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.name.Name // This file describes the ABI for Kotlin descriptors of exported declarations. // TODO: revise the naming scheme to ensure it produces unique names. // TODO: do not serialize descriptors of non-exported declarations. object KonanBinaryInterface { private val mangler = object : AbstractKonanIrMangler(true) {} private val exportChecker = mangler.getExportChecker() val IrFunction.functionName: String get() = mangler.run { signatureString } val IrFunction.symbolName: String get() = funSymbolNameImpl() val IrField.symbolName: String get() = withPrefix(MangleConstant.FIELD_PREFIX, fieldSymbolNameImpl()) val IrClass.typeInfoSymbolName: String get() = withPrefix(MangleConstant.CLASS_PREFIX, typeInfoSymbolNameImpl()) fun isExported(declaration: IrDeclaration) = exportChecker.run { check(declaration, SpecialDeclarationType.REGULAR) || declaration.isPlatformSpecificExported() } private fun withPrefix(prefix: String, mangle: String) = "$prefix:$mangle" private fun IrFunction.funSymbolNameImpl(): String { if (!isExported(this)) { throw AssertionError(render()) } if (isExternal) { this.externalSymbolOrThrow()?.let { return it } } this.annotations.findAnnotation(RuntimeNames.exportForCppRuntime)?.let { val name = it.getAnnotationStringValue() ?: this.name.asString() return name // no wrapping currently required } return withPrefix(MangleConstant.FUN_PREFIX, mangler.run { mangleString }) } private fun IrField.fieldSymbolNameImpl(): String { val containingDeclarationPart = parent.fqNameForIrSerialization.let { if (it.isRoot) "" else "$it." } return "$containingDeclarationPart$name" } private fun IrClass.typeInfoSymbolNameImpl(): String { return this.fqNameForIrSerialization.toString() } } internal val IrClass.writableTypeInfoSymbolName: String get() { assert (this.isExported()) return "ktypew:" + this.fqNameForIrSerialization.toString() } internal val IrClass.globalObjectStorageSymbolName: String get() { assert (this.isExported()) assert (this.kind.isSingleton) assert (!this.isUnit()) return "kobjref:$fqNameForIrSerialization" } internal val IrClass.threadLocalObjectStorageGetterSymbolName: String get() { assert (this.isExported()) assert (this.kind.isSingleton) assert (!this.isUnit()) return "kobjget:$fqNameForIrSerialization" } internal val IrClass.kotlinObjCClassInfoSymbolName: String get() { assert (this.isExported()) assert (this.isKotlinObjCClass()) return "kobjcclassinfo:$fqNameForIrSerialization" } fun IrFunction.computeFunctionName() = with(KonanBinaryInterface) { functionName } fun IrFunction.computeFullName() = parent.fqNameForIrSerialization.child(Name.identifier(computeFunctionName())).asString() fun IrFunction.computeSymbolName() = with(KonanBinaryInterface) { symbolName }.replaceSpecialSymbols() fun IrField.computeSymbolName() = with(KonanBinaryInterface) { symbolName }.replaceSpecialSymbols() fun IrClass.computeTypeInfoSymbolName() = with(KonanBinaryInterface) { typeInfoSymbolName }.replaceSpecialSymbols() private fun String.replaceSpecialSymbols() = // '@' is used for symbol versioning in GCC: https://gcc.gnu.org/wiki/SymbolVersioning. this.replace("@", "__at__") fun IrDeclaration.isExported() = KonanBinaryInterface.isExported(this) // TODO: bring here dependencies of this method? internal fun RuntimeAware.getLlvmFunctionType(function: IrFunction): LLVMTypeRef { val returnType = when { function is IrConstructor -> voidType function.isSuspend -> kObjHeaderPtr // Suspend functions return Any?. else -> getLLVMReturnType(function.returnType) } val paramTypes = ArrayList(function.allParameters.map { getLLVMType(it.type) }) if (function.isSuspend) paramTypes.add(kObjHeaderPtr) // Suspend functions have implicit parameter of type Continuation<>. if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr) return functionType(returnType, isVarArg = false, paramTypes = paramTypes.toTypedArray()) } internal val IrClass.typeInfoHasVtableAttached: Boolean get() = !this.isAbstract() && !this.isExternalObjCClass() internal val String.moduleConstructorName get() = "_Konan_init_${this}" internal val KonanLibrary.moduleConstructorName get() = uniqueName.moduleConstructorName ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.PhaserState import org.jetbrains.kotlin.backend.common.phaser.namedUnitPhase import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysis import org.jetbrains.kotlin.backend.konan.lower.RedundantCoercionsCleaner import org.jetbrains.kotlin.backend.konan.optimizations.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addToStdlib.cast internal val contextLLVMSetupPhase = makeKonanModuleOpPhase( name = "ContextLLVMSetup", description = "Set up Context for LLVM Bitcode generation", op = { context, _ -> // Note that we don't set module target explicitly. // It is determined by the target of runtime.bc // (see Llvm class in ContextUtils) // Which in turn is determined by the clang flags // used to compile runtime.bc. llvmContext = LLVMContextCreate()!! val llvmModule = LLVMModuleCreateWithNameInContext("out", llvmContext)!! context.llvmModule = llvmModule context.debugInfo.builder = LLVMCreateDIBuilder(llvmModule) // we don't split path to filename and directory to provide enough level uniquely for dsymutil to avoid symbol // clashing, which happens on linking with libraries produced from intercepting sources. val filePath = context.config.outputFile.toFileAndFolder(context).path() context.debugInfo.compilationUnit = if (context.shouldContainLocationDebugInfo()) DICreateCompilationUnit( builder = context.debugInfo.builder, lang = DWARF.language(context.config), File = filePath, dir = "", producer = DWARF.producer, isOptimized = 0, flags = "", rv = DWARF.runtimeVersion(context.config)).cast() else null } ) internal val createLLVMDeclarationsPhase = makeKonanModuleOpPhase( name = "CreateLLVMDeclarations", description = "Map IR declarations to LLVM", prerequisite = setOf(contextLLVMSetupPhase), op = { context, _ -> context.llvmDeclarations = createLlvmDeclarations(context) context.lifetimes = mutableMapOf() context.codegenVisitor = CodeGeneratorVisitor(context, context.lifetimes) } ) internal val disposeLLVMPhase = namedUnitPhase( name = "DisposeLLVM", description = "Dispose LLVM", lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Unit) { context.disposeLlvm() } } ) internal val freeNativeMemPhase = namedUnitPhase( name = "FreeNativeMem", description = "Free native memory used by interop", lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Unit) { context.freeNativeMem() } } ) internal val RTTIPhase = makeKonanModuleOpPhase( name = "RTTI", description = "RTTI generation", op = { context, irModule -> val visitor = RTTIGeneratorVisitor(context) irModule.acceptVoid(visitor) visitor.dispose() } ) internal val generateDebugInfoHeaderPhase = makeKonanModuleOpPhase( name = "GenerateDebugInfoHeader", description = "Generate debug info header", op = { context, _ -> generateDebugInfoHeader(context) } ) internal val buildDFGPhase = makeKonanModuleOpPhase( name = "BuildDFG", description = "Data flow graph building", op = { context, irModule -> context.moduleDFG = ModuleDFGBuilder(context, irModule).build() } ) internal val devirtualizationPhase = makeKonanModuleOpPhase( name = "Devirtualization", description = "Devirtualization", prerequisite = setOf(buildDFGPhase), op = { context, irModule -> context.devirtualizationAnalysisResult = Devirtualization.run( irModule, context, context.moduleDFG!!, ExternalModulesDFG(emptyList(), emptyMap(), emptyMap(), emptyMap()) ) } ) internal val redundantCoercionsCleaningPhase = makeKonanModuleOpPhase( name = "RedundantCoercionsCleaning", description = "Redundant coercions cleaning", op = { context, irModule -> irModule.files.forEach { RedundantCoercionsCleaner(context).lower(it) } } ) internal val ghaPhase = makeKonanModuleOpPhase( name = "GHAPhase", description = "Global hierarchy analysis", op = { context, irModule -> GlobalHierarchyAnalysis(context, irModule).run() } ) internal val IrFunction.longName: String get() = "${(parent as? IrClass)?.name?.asString() ?: ""}.${(this as? IrSimpleFunction)?.name ?: ""}" internal val dcePhase = makeKonanModuleOpPhase( name = "DCEPhase", description = "Dead code elimination", prerequisite = setOf(devirtualizationPhase), op = { context, _ -> val externalModulesDFG = ExternalModulesDFG(emptyList(), emptyMap(), emptyMap(), emptyMap()) val callGraph = CallGraphBuilder( context, context.moduleDFG!!, externalModulesDFG, context.devirtualizationAnalysisResult!!, // For DCE we don't wanna miss any potentially reachable function. nonDevirtualizedCallSitesUnfoldFactor = Int.MAX_VALUE ).build() val referencedFunctions = mutableSetOf() callGraph.rootExternalFunctions.forEach { if (!it.isGlobalInitializer) referencedFunctions.add(it.irFunction ?: error("No IR for: $it")) } for (node in callGraph.directEdges.values) { if (!node.symbol.isGlobalInitializer) referencedFunctions.add(node.symbol.irFunction ?: error("No IR for: ${node.symbol}")) node.callSites.forEach { assert (!it.isVirtual) { "There should be no virtual calls in the call graph, but was: ${it.actualCallee}" } referencedFunctions.add(it.actualCallee.irFunction ?: error("No IR for: ${it.actualCallee}")) } } context.irModule!!.acceptChildrenVoid(object: IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitFunction(declaration: IrFunction) { // TODO: Generalize somehow, not that graceful. if (declaration.name == OperatorNameConventions.INVOKE && declaration.parent.let { it is IrClass && it.defaultType.isFunction() }) { referencedFunctions.add(declaration) } super.visitFunction(declaration) } override fun visitConstructor(declaration: IrConstructor) { // TODO: NativePointed is the only inline class for which the field's type and // the constructor parameter's type are different. // Thus we need to conserve the constructor no matter if it was actually referenced somehow or not. // See [IrTypeInlineClassesSupport.getInlinedClassUnderlyingType] why. if (declaration.parentAsClass.name.asString() == InteropFqNames.nativePointedName && declaration.isPrimary) referencedFunctions.add(declaration) super.visitConstructor(declaration) } }) context.irModule!!.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitFile(declaration: IrFile): IrFile { declaration.declarations.removeAll { (it is IrFunction && !referencedFunctions.contains(it)) } return super.visitFile(declaration) } override fun visitClass(declaration: IrClass): IrStatement { if (declaration == context.ir.symbols.nativePointed) return super.visitClass(declaration) declaration.declarations.removeAll { (it is IrFunction && it.isReal && !referencedFunctions.contains(it)) } return super.visitClass(declaration) } override fun visitProperty(declaration: IrProperty): IrStatement { if (declaration.getter.let { it != null && it.isReal && !referencedFunctions.contains(it) }) { declaration.getter = null } if (declaration.setter.let { it != null && it.isReal && !referencedFunctions.contains(it) }) { declaration.setter = null } return super.visitProperty(declaration) } }) context.referencedFunctions = referencedFunctions } ) internal val escapeAnalysisPhase = makeKonanModuleOpPhase( name = "EscapeAnalysis", description = "Escape analysis", prerequisite = setOf(buildDFGPhase, devirtualizationPhase), op = { context, _ -> val entryPoint = context.ir.symbols.entryPoint?.owner val externalModulesDFG = ExternalModulesDFG(emptyList(), emptyMap(), emptyMap(), emptyMap()) val nonDevirtualizedCallSitesUnfoldFactor = if (entryPoint != null) { // For a final program it can be safely assumed that what classes we see is what we got, // so can take those. In theory we can always unfold call sites using type hierarchy, but // the analysis might converge much, much slower, so take only reasonably small for now. 5 } else { // Can't tolerate any non-devirtualized call site for a library. // TODO: What about private virtual functions? // Note: 0 is also bad - this means that there're no inheritors in the current source set, // but there might be some provided by the users of the library being produced. -1 } val callGraph = CallGraphBuilder( context, context.moduleDFG!!, externalModulesDFG, context.devirtualizationAnalysisResult!!, nonDevirtualizedCallSitesUnfoldFactor ).build() EscapeAnalysis.computeLifetimes( context, context.moduleDFG!!, externalModulesDFG, callGraph, context.lifetimes ) } ) internal val localEscapeAnalysisPhase = makeKonanModuleOpPhase( name = "LocalEscapeAnalysis", description = "Local escape analysis", prerequisite = setOf(buildDFGPhase, devirtualizationPhase), op = { context, _ -> LocalEscapeAnalysis.computeLifetimes(context, context.moduleDFG!!, context.lifetimes) } ) internal val codegenPhase = makeKonanModuleOpPhase( name = "Codegen", description = "Code generation", op = { context, irModule -> irModule.acceptVoid(context.codegenVisitor) } ) internal val finalizeDebugInfoPhase = makeKonanModuleOpPhase( name = "FinalizeDebugInfo", description = "Finalize debug info", op = { context, _ -> if (context.shouldContainAnyDebugInfo()) { DIFinalize(context.debugInfo.builder) } } ) internal val cStubsPhase = makeKonanModuleOpPhase( name = "CStubs", description = "C stubs compilation", op = { context, _ -> produceCStubs(context) } ) internal val linkBitcodeDependenciesPhase = makeKonanModuleOpPhase( name = "LinkBitcodeDependencies", description = "Link bitcode dependencies", op = { context, _ -> linkBitcodeDependencies(context) } ) internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase( name = "BitcodeOptimization", description = "Optimize bitcode", op = { context, _ -> runLlvmOptimizationPipeline(context) } ) internal val produceOutputPhase = namedUnitPhase( name = "ProduceOutput", description = "Produce output", lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Unit) { produceOutput(context) } } ) internal val verifyBitcodePhase = makeKonanModuleOpPhase( name = "VerifyBitcode", description = "Verify bitcode", op = { context, _ -> context.verifyBitCode() } ) internal val printBitcodePhase = makeKonanModuleOpPhase( name = "PrintBitcode", description = "Print bitcode", op = { context, _ -> if (context.shouldPrintBitCode()) { context.printBitCode() } } ) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.ClassGlobalHierarchyInfo import org.jetbrains.kotlin.backend.konan.llvm.objc.* import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.konan.ForeignExceptionMode private fun IrConstructor.isAnyConstructorDelegation(context: Context): Boolean { val statements = this.body?.statements ?: return false if (statements.size != 2) return false val lastStatement = statements[1] if (lastStatement !is IrReturn || (lastStatement.value as? IrGetObjectValue)?.symbol != context.irBuiltIns.unitClass) return false val constructorCall = statements[0] as? IrDelegatingConstructorCall ?: return false val constructor = constructorCall.symbol.owner as? IrConstructor ?: return false return constructor.constructedClass.isAny() } // TODO: shall we memoize that property? internal fun IrClass.hasConstStateAndNoSideEffects(context: Context): Boolean { if (!context.shouldOptimize()) return false if (this.hasAnnotation(KonanFqNames.canBePrecreated)) return true val fields = context.getLayoutBuilder(this).fields return fields.isEmpty() && this.constructors.all { it.isAnyConstructorDelegation(context) } } internal class CodeGenerator(override val context: Context) : ContextUtils { fun llvmFunction(function: IrFunction): LLVMValueRef = llvmFunctionOrNull(function) ?: error("no function ${function.name} in ${function.file.fqName}") fun llvmFunctionOrNull(function: IrFunction): LLVMValueRef? = function.llvmFunctionOrNull val intPtrType = LLVMIntPtrTypeInContext(llvmContext, llvmTargetData)!! internal val immOneIntPtrType = LLVMConstInt(intPtrType, 1, 1)!! internal val immThreeIntPtrType = LLVMConstInt(intPtrType, 3, 1)!! // Keep in sync with OBJECT_TAG_MASK in C++. internal val immTypeInfoMask = LLVMConstNot(LLVMConstInt(intPtrType, 3, 0)!!)!! //-------------------------------------------------------------------------// fun typeInfoValue(irClass: IrClass): LLVMValueRef = irClass.llvmTypeInfoPtr fun param(fn: IrFunction, i: Int): LLVMValueRef { assert(i >= 0 && i < countParams(fn)) return LLVMGetParam(fn.llvmFunction, i)!! } private fun countParams(fn: IrFunction) = LLVMCountParams(fn.llvmFunction) fun functionEntryPointAddress(function: IrFunction) = function.entryPointAddress.llvm fun functionHash(function: IrFunction): LLVMValueRef = function.computeFunctionName().localHash.llvm fun typeInfoForAllocation(constructedClass: IrClass): LLVMValueRef { assert(!constructedClass.isObjCClass()) return typeInfoValue(constructedClass) } fun generateLocationInfo(locationInfo: LocationInfo): DILocationRef? = if (locationInfo.inlinedAt != null) LLVMCreateLocationInlinedAt(LLVMGetModuleContext(context.llvmModule), locationInfo.line, locationInfo.column, locationInfo.scope, generateLocationInfo(locationInfo.inlinedAt)) else LLVMCreateLocation(LLVMGetModuleContext(context.llvmModule), locationInfo.line, locationInfo.column, locationInfo.scope) val objCDataGenerator = when { context.config.target.family.isAppleFamily -> ObjCDataGenerator(this) else -> null } } internal sealed class ExceptionHandler { object None : ExceptionHandler() object Caller : ExceptionHandler() abstract class Local : ExceptionHandler() { abstract val unwind: LLVMBasicBlockRef } } val LLVMValueRef.name:String? get() = LLVMGetValueName(this)?.toKString() val LLVMValueRef.isConst:Boolean get() = (LLVMIsConstant(this) == 1) internal inline fun generateFunction(codegen: CodeGenerator, function: IrFunction, startLocation: LocationInfo? = null, endLocation: LocationInfo? = null, code: FunctionGenerationContext.(FunctionGenerationContext) -> R) { val llvmFunction = codegen.llvmFunction(function) val functionGenerationContext = FunctionGenerationContext( llvmFunction, codegen, startLocation, endLocation, function) try { generateFunctionBody(functionGenerationContext, code) } finally { functionGenerationContext.dispose() } // To perform per-function validation. if (false) LLVMVerifyFunction(llvmFunction, LLVMVerifierFailureAction.LLVMAbortProcessAction) } internal inline fun generateFunction(codegen: CodeGenerator, function: LLVMValueRef, startLocation: LocationInfo? = null, endLocation: LocationInfo? = null, code:FunctionGenerationContext.(FunctionGenerationContext) -> R) { val functionGenerationContext = FunctionGenerationContext(function, codegen, startLocation, endLocation) try { generateFunctionBody(functionGenerationContext, code) } finally { functionGenerationContext.dispose() } } internal inline fun generateFunction( codegen: CodeGenerator, functionType: LLVMTypeRef, name: String, block: FunctionGenerationContext.(FunctionGenerationContext) -> Unit ): LLVMValueRef { val function = addLlvmFunctionWithDefaultAttributes( codegen.context, codegen.context.llvmModule!!, name, functionType ) generateFunction(codegen, function, startLocation = null, endLocation = null, code = block) return function } // TODO: Consider using different abstraction than `FunctionGenerationContext` for `generateFunctionNoRuntime`. internal inline fun generateFunctionNoRuntime( codegen: CodeGenerator, function: LLVMValueRef, code: FunctionGenerationContext.(FunctionGenerationContext) -> R, ) { val functionGenerationContext = FunctionGenerationContext(function, codegen, null, null) try { functionGenerationContext.forbidRuntime = true require(!functionGenerationContext.isObjectType(functionGenerationContext.returnType!!)) { "Cannot return object from function without Kotlin runtime" } generateFunctionBody(functionGenerationContext, code) } finally { functionGenerationContext.dispose() } } internal inline fun generateFunctionNoRuntime( codegen: CodeGenerator, functionType: LLVMTypeRef, name: String, code: FunctionGenerationContext.(FunctionGenerationContext) -> Unit, ): LLVMValueRef { val function = addLlvmFunctionWithDefaultAttributes( codegen.context, codegen.context.llvmModule!!, name, functionType ) generateFunctionNoRuntime(codegen, function, code) return function } private inline fun generateFunctionBody( functionGenerationContext: FunctionGenerationContext, code: FunctionGenerationContext.(FunctionGenerationContext) -> R) { functionGenerationContext.prologue() functionGenerationContext.code(functionGenerationContext) if (!functionGenerationContext.isAfterTerminator()) functionGenerationContext.unreachable() functionGenerationContext.epilogue() functionGenerationContext.resetDebugLocation() } /** * There're cases when we don't need end position or it is meaningless. */ internal data class LocationInfoRange(var start: LocationInfo, var end: LocationInfo?) internal interface StackLocalsManager { fun alloc(irClass: IrClass, cleanFieldsExplicitly: Boolean): LLVMValueRef fun allocArray(irClass: IrClass, count: LLVMValueRef): LLVMValueRef fun clean(refsOnly: Boolean) } internal class StackLocalsManagerImpl( val functionGenerationContext: FunctionGenerationContext, val bbInitStackLocals: LLVMBasicBlockRef ) : StackLocalsManager { private class StackLocal(val isArray: Boolean, val irClass: IrClass, val bodyPtr: LLVMValueRef, val objHeaderPtr: LLVMValueRef) private val stackLocals = mutableListOf() override fun alloc(irClass: IrClass, cleanFieldsExplicitly: Boolean): LLVMValueRef = with(functionGenerationContext) { val type = context.llvmDeclarations.forClass(irClass).bodyType val stackLocal = appendingTo(bbInitStackLocals) { val stackSlot = LLVMBuildAlloca(builder, type, "")!! call(context.llvm.memsetFunction, listOf(bitcast(kInt8Ptr, stackSlot), Int8(0).llvm, Int32(LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8).llvm, Int1(0).llvm)) val objectHeader = structGep(stackSlot, 0, "objHeader") val typeInfo = codegen.typeInfoForAllocation(irClass) setTypeInfoForLocalObject(objectHeader, typeInfo) StackLocal(false, irClass, stackSlot, objectHeader) } stackLocals += stackLocal if (cleanFieldsExplicitly) clean(stackLocal, false) stackLocal.objHeaderPtr } // Returns generated special type for local array. // It's needed to prevent changing variables order on stack. private fun localArrayType(irClass: IrClass, count: Int) = with(functionGenerationContext) { val name = "local#${irClass.name}${count}#internal" // Create new type or get already created. context.declaredLocalArrays.getOrPut(name) { val fieldTypes = listOf(kArrayHeader, LLVMArrayType(arrayToElementType[irClass.symbol]!!, count)) val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!! LLVMStructSetBody(classType, fieldTypes.toCValues(), fieldTypes.size, 1) classType } } private val symbols = functionGenerationContext.context.ir.symbols // TODO: find better place? private val arrayToElementType = mapOf( symbols.array to functionGenerationContext.kObjHeaderPtr, symbols.byteArray to int8Type, symbols.charArray to int16Type, symbols.shortArray to int16Type, symbols.intArray to int32Type, symbols.longArray to int64Type, symbols.floatArray to floatType, symbols.doubleArray to doubleType, symbols.booleanArray to int8Type ) override fun allocArray(irClass: IrClass, count: LLVMValueRef) = with(functionGenerationContext) { val stackLocal = appendingTo(bbInitStackLocals) { val constCount = extractConstUnsignedInt(count).toInt() val arrayType = localArrayType(irClass, constCount) val typeInfo = codegen.typeInfoValue(irClass) val arraySlot = LLVMBuildAlloca(builder, arrayType, "")!! // Set array size in ArrayHeader. val arrayHeaderSlot = structGep(arraySlot, 0, "arrayHeader") setTypeInfoForLocalObject(arrayHeaderSlot, typeInfo) val sizeField = structGep(arrayHeaderSlot, 1, "count_") store(count, sizeField) call(context.llvm.memsetFunction, listOf(bitcast(kInt8Ptr, structGep(arraySlot, 1, "arrayBody")), Int8(0).llvm, Int32(constCount * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[irClass.symbol]).toInt() / 8).llvm, Int1(0).llvm)) StackLocal(true, irClass, arraySlot, arrayHeaderSlot) } stackLocals += stackLocal bitcast(kObjHeaderPtr, stackLocal.objHeaderPtr) } override fun clean(refsOnly: Boolean) = stackLocals.forEach { clean(it, refsOnly) } private fun clean(stackLocal: StackLocal, refsOnly: Boolean) = with(functionGenerationContext) { if (stackLocal.isArray) { if (stackLocal.irClass.symbol == context.ir.symbols.array) call(context.llvm.zeroArrayRefsFunction, listOf(stackLocal.objHeaderPtr)) } else { val type = context.llvmDeclarations.forClass(stackLocal.irClass).bodyType for (field in context.getLayoutBuilder(stackLocal.irClass).fields) { val fieldIndex = context.llvmDeclarations.forField(field).index val fieldType = LLVMStructGetTypeAtIndex(type, fieldIndex)!! if (isObjectType(fieldType)) { val fieldPtr = LLVMBuildStructGEP(builder, stackLocal.bodyPtr, fieldIndex, "")!! if (refsOnly) storeHeapRef(kNullObjHeaderPtr, fieldPtr) else call(context.llvm.zeroHeapRefFunction, listOf(fieldPtr)) } } if (!refsOnly) { val bodyPtr = ptrToInt(stackLocal.bodyPtr, codegen.intPtrType) val bodySize = LLVMSizeOfTypeInBits(codegen.llvmTargetData, type).toInt() / 8 val serviceInfoSize = runtime.pointerSize val serviceInfoSizeLlvm = LLVMConstInt(codegen.intPtrType, serviceInfoSize.toLong(), 1)!! val bodyWithSkippedServiceInfoPtr = intToPtr(add(bodyPtr, serviceInfoSizeLlvm), kInt8Ptr) call(context.llvm.memsetFunction, listOf(bodyWithSkippedServiceInfoPtr, Int8(0).llvm, Int32(bodySize - serviceInfoSize).llvm, Int1(0).llvm)) } } } private fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef, typeInfoPointer: LLVMValueRef) = with(functionGenerationContext) { val typeInfo = structGep(objectHeader, 0, "typeInfoOrMeta_") // Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER. val typeInfoValue = intToPtr(or(ptrToInt(typeInfoPointer, codegen.intPtrType), codegen.immThreeIntPtrType), kTypeInfoPtr) store(typeInfoValue, typeInfo) } } internal class FunctionGenerationContext(val function: LLVMValueRef, val codegen: CodeGenerator, startLocation: LocationInfo?, endLocation: LocationInfo?, internal val irFunction: IrFunction? = null): ContextUtils { override val context = codegen.context val vars = VariableManager(this) private val basicBlockToLastLocation = mutableMapOf() private fun update(block: LLVMBasicBlockRef, startLocationInfo: LocationInfo?, endLocation: LocationInfo? = startLocationInfo) { startLocationInfo ?: return basicBlockToLastLocation.put(block, LocationInfoRange(startLocationInfo, endLocation)) } var returnType: LLVMTypeRef? = LLVMGetReturnType(getFunctionType(function)) private val returns: MutableMap = mutableMapOf() val constructedClass: IrClass? get() = (irFunction as? IrConstructor)?.constructedClass private var returnSlot: LLVMValueRef? = null private var slotsPhi: LLVMValueRef? = null private val frameOverlaySlotCount = (LLVMStoreSizeOfType(llvmTargetData, runtime.frameOverlayType) / runtime.pointerSize).toInt() private var slotCount = frameOverlaySlotCount private var localAllocs = 0 // TODO: remove if exactly unused. //private var arenaSlot: LLVMValueRef? = null private val slotToVariableLocation = mutableMapOf() private val prologueBb = basicBlockInFunction("prologue", startLocation) private val localsInitBb = basicBlockInFunction("locals_init", startLocation) private val stackLocalsInitBb = basicBlockInFunction("stack_locals_init", startLocation) private val entryBb = basicBlockInFunction("entry", startLocation) private val epilogueBb = basicBlockInFunction("epilogue", endLocation) private val cleanupLandingpad = basicBlockInFunction("cleanup_landingpad", endLocation) val stackLocalsManager = StackLocalsManagerImpl(this, stackLocalsInitBb) /** * TODO: consider merging this with [ExceptionHandler]. */ var forwardingForeignExceptionsTerminatedWith: LLVMValueRef? = null // Whether the generating function needs to initialize Kotlin runtime before execution. Useful for interop bridges, // for example. var needsRuntimeInit = false // Marks that function is not allowed to call into Kotlin runtime. For this function no safepoints, no enter/leave // frames are generated. // TODO: Should forbid all calls into runtime except for explicitly allowed. Also should impose the same restriction // on function being called from this one. // TODO: Consider using a different abstraction than `FunctionGenerationContext`. var forbidRuntime = false init { irFunction?.let { if (!irFunction.isExported()) { LLVMSetLinkage(function, LLVMLinkage.LLVMInternalLinkage) // (Cannot do this before the function body is created). } } } fun dispose() { currentPositionHolder.dispose() } private fun basicBlockInFunction(name: String, locationInfo: LocationInfo?): LLVMBasicBlockRef { val bb = LLVMAppendBasicBlockInContext(llvmContext, function, name)!! update(bb, locationInfo) return bb } fun basicBlock(name: String = "label_", startLocationInfo: LocationInfo?, endLocationInfo: LocationInfo? = startLocationInfo): LLVMBasicBlockRef { val result = LLVMInsertBasicBlockInContext(llvmContext, this.currentBlock, name)!! update(result, startLocationInfo, endLocationInfo) LLVMMoveBasicBlockAfter(result, this.currentBlock) return result } fun alloca(type: LLVMTypeRef?, name: String = "", variableLocation: VariableDebugLocation? = null): LLVMValueRef { if (isObjectType(type!!)) { appendingTo(localsInitBb) { val slotAddress = gep(slotsPhi!!, Int32(slotCount).llvm, name) variableLocation?.let { slotToVariableLocation[slotCount] = it } slotCount++ return slotAddress } } appendingTo(prologueBb) { val slotAddress = LLVMBuildAlloca(builder, type, name)!! variableLocation?.let { DIInsertDeclaration( builder = codegen.context.debugInfo.builder, value = slotAddress, localVariable = it.localVariable, location = it.location, bb = prologueBb, expr = null, exprCount = 0) } return slotAddress } } fun ret(value: LLVMValueRef?): LLVMValueRef { val res = LLVMBuildBr(builder, epilogueBb)!! if (returns.containsKey(currentBlock)) { // TODO: enable error throwing. throw Error("ret() in the same basic block twice! in ${function.name}") } if (value != null) returns[currentBlock] = value currentPositionHolder.setAfterTerminator() return res } fun param(index: Int): LLVMValueRef = LLVMGetParam(this.function, index)!! fun load(value: LLVMValueRef, name: String = ""): LLVMValueRef { val result = LLVMBuildLoad(builder, value, name)!! // Use loadSlot() API for that. assert(!isObjectRef(value)) return result } fun loadSlot(address: LLVMValueRef, isVar: Boolean, name: String = ""): LLVMValueRef { val value = LLVMBuildLoad(builder, address, name)!! if (isObjectRef(value) && isVar) { val slot = alloca(LLVMTypeOf(value), variableLocation = null) storeStackRef(value, slot) } return value } fun store(value: LLVMValueRef, ptr: LLVMValueRef) { LLVMBuildStore(builder, value, ptr) } fun storeHeapRef(value: LLVMValueRef, ptr: LLVMValueRef) { updateRef(value, ptr, onStack = false) } fun storeStackRef(value: LLVMValueRef, ptr: LLVMValueRef) { updateRef(value, ptr, onStack = true) } fun storeAny(value: LLVMValueRef, ptr: LLVMValueRef, onStack: Boolean) = if (isObjectRef(value)) { if (onStack) storeStackRef(value, ptr) else storeHeapRef(value, ptr) null } else { LLVMBuildStore(builder, value, ptr) } fun freeze(value: LLVMValueRef, exceptionHandler: ExceptionHandler) { if (isObjectRef(value)) call(context.llvm.freezeSubgraph, listOf(value), Lifetime.IRRELEVANT, exceptionHandler) } fun checkGlobalsAccessible(exceptionHandler: ExceptionHandler) { if (context.memoryModel == MemoryModel.STRICT) call(context.llvm.checkGlobalsAccessible, emptyList(), Lifetime.IRRELEVANT, exceptionHandler) } private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) { if (context.memoryModel == MemoryModel.STRICT) store(value, address) else call(context.llvm.updateReturnRefFunction, listOf(address, value)) } private fun updateRef(value: LLVMValueRef, address: LLVMValueRef, onStack: Boolean) { if (onStack) { if (context.memoryModel == MemoryModel.STRICT) store(value, address) else call(context.llvm.updateStackRefFunction, listOf(address, value)) } else { call(context.llvm.updateHeapRefFunction, listOf(address, value)) } } //-------------------------------------------------------------------------// fun call(llvmFunction: LLVMValueRef, args: List, resultLifetime: Lifetime = Lifetime.IRRELEVANT, exceptionHandler: ExceptionHandler = ExceptionHandler.None, verbatim: Boolean = false): LLVMValueRef { val callArgs = if (verbatim || !isObjectReturn(llvmFunction.type)) { args } else { // If function returns an object - create slot for the returned value or give local arena. // This allows appropriate rootset accounting by just looking at the stack slots, // along with ability to allocate in appropriate arena. val resultSlot = when (resultLifetime.slotType) { SlotType.STACK -> { localAllocs++ // Case of local call. Use memory allocated on stack. val type = LLVMGetReturnType(LLVMGetElementType(llvmFunction.type))!! val stackPointer = alloca(type) //val objectHeader = structGep(stackPointer, 0) //setTypeInfoForLocalObject(objectHeader) stackPointer //arenaSlot!! } SlotType.RETURN -> returnSlot!! SlotType.ANONYMOUS -> vars.createAnonymousSlot() else -> throw Error("Incorrect slot type: ${resultLifetime.slotType}") } args + resultSlot } return callRaw(llvmFunction, callArgs, exceptionHandler) } private fun callRaw(llvmFunction: LLVMValueRef, args: List, exceptionHandler: ExceptionHandler): LLVMValueRef { val rargs = args.toCValues() if (LLVMIsAFunction(llvmFunction) != null /* the function declaration */ && isFunctionNoUnwind(llvmFunction)) { return LLVMBuildCall(builder, llvmFunction, rargs, args.size, "")!! } else { val unwind = when (exceptionHandler) { ExceptionHandler.Caller -> cleanupLandingpad is ExceptionHandler.Local -> exceptionHandler.unwind ExceptionHandler.None -> { // When calling a function that is not marked as nounwind (can throw an exception), // it is required to specify an unwind label to handle exceptions properly. // Runtime C++ function can be marked as non-throwing using `RUNTIME_NOTHROW`. val functionName = llvmFunction.name val message = "no exception handler specified when calling function $functionName without nounwind attr" throw IllegalArgumentException(message) } } val position = position() val endLocation = position?.end val success = basicBlock("call_success", endLocation) val result = LLVMBuildInvoke(builder, llvmFunction, rargs, args.size, success, unwind, "")!! update(success, endLocation) positionAtEnd(success) return result } } //-------------------------------------------------------------------------// fun phi(type: LLVMTypeRef, name: String = ""): LLVMValueRef { return LLVMBuildPhi(builder, type, name)!! } fun addPhiIncoming(phi: LLVMValueRef, vararg incoming: Pair) { memScoped { val incomingValues = incoming.map { it.second }.toCValues() val incomingBlocks = incoming.map { it.first }.toCValues() LLVMAddIncoming(phi, incomingValues, incomingBlocks, incoming.size) } } fun assignPhis(vararg phiToValue: Pair) { phiToValue.forEach { addPhiIncoming(it.first, currentBlock to it.second) } } fun allocInstance(typeInfo: LLVMValueRef, lifetime: Lifetime): LLVMValueRef = call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime) fun allocInstance(irClass: IrClass, lifetime: Lifetime, stackLocalsManager: StackLocalsManager) = if (lifetime == Lifetime.STACK) stackLocalsManager.alloc(irClass, // In case the allocation is not from the root scope, fields must be cleaned up explicitly, // as the object might be being reused. cleanFieldsExplicitly = stackLocalsManager != this.stackLocalsManager) else allocInstance(codegen.typeInfoForAllocation(irClass), lifetime) fun allocArray( irClass: IrClass, count: LLVMValueRef, lifetime: Lifetime, exceptionHandler: ExceptionHandler ): LLVMValueRef { val typeInfo = codegen.typeInfoValue(irClass) return if (lifetime == Lifetime.STACK) { stackLocalsManager.allocArray(irClass, count) } else { call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler) } } fun unreachable(): LLVMValueRef? { if (context.config.debug) { call(context.llvm.llvmTrap, emptyList()) } val res = LLVMBuildUnreachable(builder) currentPositionHolder.setAfterTerminator() return res } fun br(bbLabel: LLVMBasicBlockRef): LLVMValueRef { val res = LLVMBuildBr(builder, bbLabel)!! currentPositionHolder.setAfterTerminator() return res } fun condBr(condition: LLVMValueRef?, bbTrue: LLVMBasicBlockRef?, bbFalse: LLVMBasicBlockRef?): LLVMValueRef? { val res = LLVMBuildCondBr(builder, condition, bbTrue, bbFalse) currentPositionHolder.setAfterTerminator() return res } fun blockAddress(bbLabel: LLVMBasicBlockRef): LLVMValueRef { return LLVMBlockAddress(function, bbLabel)!! } fun not(arg: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildNot(builder, arg, name)!! fun and(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildAnd(builder, arg0, arg1, name)!! fun or(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildOr(builder, arg0, arg1, name)!! fun xor(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildXor(builder, arg0, arg1, name)!! fun zext(arg: LLVMValueRef, type: LLVMTypeRef): LLVMValueRef = LLVMBuildZExt(builder, arg, type, "")!! fun sext(arg: LLVMValueRef, type: LLVMTypeRef): LLVMValueRef = LLVMBuildSExt(builder, arg, type, "")!! fun ext(arg: LLVMValueRef, type: LLVMTypeRef, signed: Boolean): LLVMValueRef = if (signed) { sext(arg, type) } else { zext(arg, type) } fun trunc(arg: LLVMValueRef, type: LLVMTypeRef): LLVMValueRef = LLVMBuildTrunc(builder, arg, type, "")!! private fun shift(op: LLVMOpcode, arg: LLVMValueRef, amount: Int) = if (amount == 0) { arg } else { LLVMBuildBinOp(builder, op, arg, LLVMConstInt(arg.type, amount.toLong(), 0), "")!! } fun shl(arg: LLVMValueRef, amount: Int) = shift(LLVMOpcode.LLVMShl, arg, amount) fun shr(arg: LLVMValueRef, amount: Int, signed: Boolean) = shift(if (signed) LLVMOpcode.LLVMAShr else LLVMOpcode.LLVMLShr, arg, amount) /* integers comparisons */ fun icmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntEQ, arg0, arg1, name)!! fun icmpGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSGT, arg0, arg1, name)!! fun icmpGe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSGE, arg0, arg1, name)!! fun icmpLt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLT, arg0, arg1, name)!! fun icmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, arg0, arg1, name)!! fun icmpNe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntNE, arg0, arg1, name)!! fun icmpULt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULT, arg0, arg1, name)!! fun icmpULe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntULE, arg0, arg1, name)!! fun icmpUGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGT, arg0, arg1, name)!! fun icmpUGe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildICmp(builder, LLVMIntPredicate.LLVMIntUGE, arg0, arg1, name)!! /* floating-point comparisons */ fun fcmpEq(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, arg0, arg1, name)!! fun fcmpGt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOGT, arg0, arg1, name)!! fun fcmpGe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOGE, arg0, arg1, name)!! fun fcmpLt(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOLT, arg0, arg1, name)!! fun fcmpLe(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFCmp(builder, LLVMRealPredicate.LLVMRealOLE, arg0, arg1, name)!! fun sub(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildSub(builder, arg0, arg1, name)!! fun add(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildAdd(builder, arg0, arg1, name)!! fun fsub(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFSub(builder, arg0, arg1, name)!! fun fadd(arg0: LLVMValueRef, arg1: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFAdd(builder, arg0, arg1, name)!! fun fneg(arg: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildFNeg(builder, arg, name)!! fun select(ifValue: LLVMValueRef, thenValue: LLVMValueRef, elseValue: LLVMValueRef, name: String = ""): LLVMValueRef = LLVMBuildSelect(builder, ifValue, thenValue, elseValue, name)!! fun bitcast(type: LLVMTypeRef?, value: LLVMValueRef, name: String = "") = LLVMBuildBitCast(builder, value, type, name)!! fun intToPtr(value: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String = "") = LLVMBuildIntToPtr(builder, value, DestTy, Name)!! fun ptrToInt(value: LLVMValueRef?, DestTy: LLVMTypeRef, Name: String = "") = LLVMBuildPtrToInt(builder, value, DestTy, Name)!! fun gep(base: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef { return LLVMBuildGEP(builder, base, cValuesOf(index), 1, name)!! } fun structGep(base: LLVMValueRef, index: Int, name: String = ""): LLVMValueRef = LLVMBuildStructGEP(builder, base, index, name)!! fun extractValue(aggregate: LLVMValueRef, index: Int, name: String = ""): LLVMValueRef = LLVMBuildExtractValue(builder, aggregate, index, name)!! fun gxxLandingpad(numClauses: Int, name: String = ""): LLVMValueRef { val personalityFunction = context.llvm.gxxPersonalityFunction // Type of `landingpad` instruction result (depends on personality function): val landingpadType = structType(int8TypePtr, int32Type) return LLVMBuildLandingPad(builder, landingpadType, personalityFunction, numClauses, name)!! } fun extractElement(vector: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef { return LLVMBuildExtractElement(builder, vector, index, name)!! } fun filteringExceptionHandler(codeContext: CodeContext, foreignExceptionMode: ForeignExceptionMode.Mode): ExceptionHandler { val lpBlock = basicBlockInFunction("filteringExceptionHandler", position()?.start) val wrapExceptionMode = context.config.target.family.isAppleFamily && foreignExceptionMode == ForeignExceptionMode.Mode.OBJC_WRAP appendingTo(lpBlock) { val landingpad = gxxLandingpad(2) LLVMAddClause(landingpad, kotlinExceptionRtti.llvm) if (wrapExceptionMode) { LLVMAddClause(landingpad, objcNSExceptionRtti.llvm) } LLVMAddClause(landingpad, LLVMConstNull(kInt8Ptr)) val fatalForeignExceptionBlock = basicBlock("fatalForeignException", position()?.start) val forwardKotlinExceptionBlock = basicBlock("forwardKotlinException", position()?.start) val typeId = extractValue(landingpad, 1) val isKotlinException = icmpEq( typeId, call(context.llvm.llvmEhTypeidFor, listOf(kotlinExceptionRtti.llvm)) ) if (wrapExceptionMode) { val foreignExceptionBlock = basicBlock("foreignException", position()?.start) val forwardNativeExceptionBlock = basicBlock("forwardNativeException", position()?.start) condBr(isKotlinException, forwardKotlinExceptionBlock, foreignExceptionBlock) appendingTo(foreignExceptionBlock) { val isObjCException = icmpEq( typeId, call(context.llvm.llvmEhTypeidFor, listOf(objcNSExceptionRtti.llvm)) ) condBr(isObjCException, forwardNativeExceptionBlock, fatalForeignExceptionBlock) appendingTo(forwardNativeExceptionBlock) { val exception = createForeignException(landingpad, codeContext.exceptionHandler) codeContext.genThrow(exception) } } } else { condBr(isKotlinException, forwardKotlinExceptionBlock, fatalForeignExceptionBlock) } appendingTo(forwardKotlinExceptionBlock) { // Rethrow Kotlin exception to real handler. codeContext.genThrow(extractKotlinException(landingpad)) } appendingTo(fatalForeignExceptionBlock) { val exceptionRecord = extractValue(landingpad, 0) call(context.llvm.cxaBeginCatchFunction, listOf(exceptionRecord)) terminate() } } return object : ExceptionHandler.Local() { override val unwind: LLVMBasicBlockRef get() = lpBlock } } fun terminate() { call(context.llvm.cxxStdTerminate, emptyList()) // Note: unreachable instruction to be generated here, but debug information is improper in this case. val loopBlock = basicBlock("loop", position()?.start) br(loopBlock) appendingTo(loopBlock) { br(loopBlock) } } fun kotlinExceptionHandler( block: FunctionGenerationContext.(exception: LLVMValueRef) -> Unit ): ExceptionHandler { val lpBlock = basicBlock("kotlinExceptionHandler", position()?.end) appendingTo(lpBlock) { val exception = catchKotlinException() block(exception) } return object : ExceptionHandler.Local() { override val unwind: LLVMBasicBlockRef get() = lpBlock } } fun catchKotlinException(): LLVMValueRef { val landingpadResult = gxxLandingpad(numClauses = 1, name = "lp") LLVMAddClause(landingpadResult, LLVMConstNull(kInt8Ptr)) // TODO: properly handle C++ exceptions: currently C++ exception can be thrown out from try-finally // bypassing the finally block. return extractKotlinException(landingpadResult) } private fun extractKotlinException(landingpadResult: LLVMValueRef): LLVMValueRef { val exceptionRecord = extractValue(landingpadResult, 0, "er") // __cxa_begin_catch returns pointer to C++ exception object. val beginCatch = context.llvm.cxaBeginCatchFunction val exceptionRawPtr = call(beginCatch, listOf(exceptionRecord)) // Pointer to Kotlin exception object: val exceptionPtr = call(context.llvm.Kotlin_getExceptionObject, listOf(exceptionRawPtr), Lifetime.GLOBAL) // __cxa_end_catch performs some C++ cleanup, including calling `ExceptionObjHolder` class destructor. val endCatch = context.llvm.cxaEndCatchFunction call(endCatch, listOf()) return exceptionPtr } private fun createForeignException(landingpadResult: LLVMValueRef, exceptionHandler: ExceptionHandler): LLVMValueRef { val exceptionRecord = extractValue(landingpadResult, 0, "er") // __cxa_begin_catch returns pointer to C++ exception object. val exceptionRawPtr = call(context.llvm.cxaBeginCatchFunction, listOf(exceptionRecord)) // This will take care of ARC - need to be done in the catching scope, i.e. before __cxa_end_catch val exception = call(context.ir.symbols.createForeignException.owner.llvmFunction, listOf(exceptionRawPtr), Lifetime.GLOBAL, exceptionHandler) call(context.llvm.cxaEndCatchFunction, listOf()) return exception } inline fun ifThenElse( condition: LLVMValueRef, thenValue: LLVMValueRef, elseBlock: () -> LLVMValueRef ): LLVMValueRef { val resultType = thenValue.type val position = position() val endPosition = position()?.end val bbExit = basicBlock(startLocationInfo = endPosition) val resultPhi = appendingTo(bbExit) { phi(resultType) } val bbElse = basicBlock(startLocationInfo = position?.start, endLocationInfo = endPosition) condBr(condition, bbExit, bbElse) assignPhis(resultPhi to thenValue) appendingTo(bbElse) { val elseValue = elseBlock() br(bbExit) assignPhis(resultPhi to elseValue) } positionAtEnd(bbExit) return resultPhi } inline fun ifThen(condition: LLVMValueRef, thenBlock: () -> Unit) { val endPosition = position()?.end val bbExit = basicBlock(startLocationInfo = endPosition) val bbThen = basicBlock(startLocationInfo = endPosition) condBr(condition, bbThen, bbExit) appendingTo(bbThen) { thenBlock() if (!isAfterTerminator()) br(bbExit) } positionAtEnd(bbExit) } internal fun debugLocation(startLocationInfo: LocationInfo, endLocation: LocationInfo?): DILocationRef? { if (!context.shouldContainLocationDebugInfo()) return null update(currentBlock, startLocationInfo, endLocation) val debugLocation = codegen.generateLocationInfo(startLocationInfo) currentPositionHolder.setBuilderDebugLocation(debugLocation) return debugLocation } fun indirectBr(address: LLVMValueRef, destinations: Collection): LLVMValueRef? { val indirectBr = LLVMBuildIndirectBr(builder, address, destinations.size) destinations.forEach { LLVMAddDestination(indirectBr, it) } currentPositionHolder.setAfterTerminator() return indirectBr } fun switch(value: LLVMValueRef, cases: Collection>, elseBB: LLVMBasicBlockRef): LLVMValueRef? { val switch = LLVMBuildSwitch(builder, value, elseBB, cases.size) cases.forEach { LLVMAddCase(switch, it.first, it.second) } currentPositionHolder.setAfterTerminator() return switch } fun loadTypeInfo(objPtr: LLVMValueRef): LLVMValueRef { val typeInfoOrMetaPtr = structGep(objPtr, 0 /* typeInfoOrMeta_ */) val typeInfoOrMetaWithFlags = load(typeInfoOrMetaPtr) // Clear two lower bits. val typeInfoOrMetaWithFlagsRaw = ptrToInt(typeInfoOrMetaWithFlags, codegen.intPtrType) val typeInfoOrMetaRaw = and(typeInfoOrMetaWithFlagsRaw, codegen.immTypeInfoMask) val typeInfoOrMeta = intToPtr(typeInfoOrMetaRaw, kTypeInfoPtr) val typeInfoPtrPtr = structGep(typeInfoOrMeta, 0 /* typeInfo */) return load(typeInfoPtrPtr) } fun lookupInterfaceTableRecord(typeInfo: LLVMValueRef, interfaceId: Int): LLVMValueRef { val interfaceTableSize = load(structGep(typeInfo, 11 /* interfaceTableSize_ */)) val interfaceTable = load(structGep(typeInfo, 12 /* interfaceTable_ */)) fun fastPath(): LLVMValueRef { // The fastest optimistic version. val interfaceTableIndex = and(interfaceTableSize, Int32(interfaceId).llvm) return gep(interfaceTable, interfaceTableIndex) } // See details in ClassLayoutBuilder. return if (context.globalHierarchyAnalysisResult.bitsPerColor <= ClassGlobalHierarchyInfo.MAX_BITS_PER_COLOR && context.config.produce != CompilerOutputKind.FRAMEWORK) { // All interface tables are small and no unknown interface inheritance. fastPath() } else { val startLocationInfo = position()?.start val fastPathBB = basicBlock("fast_path", startLocationInfo) val slowPathBB = basicBlock("slow_path", startLocationInfo) val takeResBB = basicBlock("take_res", startLocationInfo) condBr(icmpGe(interfaceTableSize, kImmInt32Zero), fastPathBB, slowPathBB) positionAtEnd(takeResBB) val resultPhi = phi(pointerType(runtime.interfaceTableRecordType)) appendingTo(fastPathBB) { val fastValue = fastPath() br(takeResBB) addPhiIncoming(resultPhi, currentBlock to fastValue) } appendingTo(slowPathBB) { val actualInterfaceTableSize = sub(kImmInt32Zero, interfaceTableSize) // -interfaceTableSize val slowValue = call(context.llvm.lookupInterfaceTableRecord, listOf(interfaceTable, actualInterfaceTableSize, Int32(interfaceId).llvm)) br(takeResBB) addPhiIncoming(resultPhi, currentBlock to slowValue) } resultPhi } } fun lookupVirtualImpl(receiver: LLVMValueRef, irFunction: IrFunction): LLVMValueRef { assert(LLVMTypeOf(receiver) == codegen.kObjHeaderPtr) val typeInfoPtr: LLVMValueRef = if (irFunction.getObjCMethodInfo() != null) call(context.llvm.getObjCKotlinTypeInfo, listOf(receiver)) else loadTypeInfo(receiver) assert(typeInfoPtr.type == codegen.kTypeInfoPtr) { LLVMPrintTypeToString(typeInfoPtr.type)!!.toKString() } /* * Resolve owner of the call with special handling of Any methods: * if toString/eq/hc is invoked on an interface instance, we resolve * owner as Any and dispatch it via vtable. */ val anyMethod = (irFunction as IrSimpleFunction).findOverriddenMethodOfAny() val owner = (anyMethod ?: irFunction).parentAsClass val methodHash = codegen.functionHash(irFunction) val llvmMethod = when { !owner.isInterface -> { // If this is a virtual method of the class - we can call via vtable. val index = context.getLayoutBuilder(owner).vtableIndex(anyMethod ?: irFunction) val vtablePlace = gep(typeInfoPtr, Int32(1).llvm) // typeInfoPtr + 1 val vtable = bitcast(kInt8PtrPtr, vtablePlace) val slot = gep(vtable, Int32(index).llvm) load(slot) } !context.ghaEnabled() -> call(context.llvm.lookupOpenMethodFunction, listOf(typeInfoPtr, methodHash)) else -> { // Essentially: typeInfo.itable[place(interfaceId)].vtable[method] val itablePlace = context.getLayoutBuilder(owner).itablePlace(irFunction) val interfaceTableRecord = lookupInterfaceTableRecord(typeInfoPtr, itablePlace.interfaceId) load(gep(load(structGep(interfaceTableRecord, 2 /* vtable */)), Int32(itablePlace.methodIndex).llvm)) } } val functionPtrType = pointerType(codegen.getLlvmFunctionType(irFunction)) return bitcast(functionPtrType, llvmMethod) } private fun IrSimpleFunction.findOverriddenMethodOfAny(): IrSimpleFunction? { if (modality == Modality.ABSTRACT) return null val resolved = resolveFakeOverride()!! if ((resolved.parent as IrClass).isAny()) { return resolved } return null } fun getObjectValue(irClass: IrClass, exceptionHandler: ExceptionHandler, startLocationInfo: LocationInfo?, endLocationInfo: LocationInfo? = null ): LLVMValueRef { // TODO: could be processed the same way as other stateless objects. if (irClass.isUnit()) { return codegen.theUnitInstanceRef.llvm } if (irClass.isCompanion) { val parent = irClass.parent as IrClass if (parent.isObjCClass()) { // TODO: cache it too. return call( codegen.llvmFunction(context.ir.symbols.interopInterpretObjCPointer.owner), listOf(getObjCClass(parent, exceptionHandler)), Lifetime.GLOBAL, exceptionHandler ) } } val storageKind = irClass.storageKind(context) val objectPtr = if (isExternal(irClass)) { when (storageKind) { // If thread local object is imported - access it via getter function. ObjectStorageKind.THREAD_LOCAL -> { val valueGetterName = irClass.threadLocalObjectStorageGetterSymbolName val valueGetterFunction = LLVMGetNamedFunction(context.llvmModule, valueGetterName) ?: addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, valueGetterName, functionType(kObjHeaderPtrPtr, false) ) call(valueGetterFunction, listOf(), resultLifetime = Lifetime.GLOBAL, exceptionHandler = exceptionHandler) } // If global object is imported - import it's storage directly. ObjectStorageKind.PERMANENT, ObjectStorageKind.SHARED -> { val llvmType = getLLVMType(irClass.defaultType) importGlobal( irClass.globalObjectStorageSymbolName, llvmType, origin = irClass.llvmSymbolOrigin ) } } } else { // Local globals and thread locals storage info is stored in our map. val singleton = context.llvmDeclarations.forSingleton(irClass) val instanceAddress = singleton.instanceStorage instanceAddress.getAddress(this) } when (storageKind) { ObjectStorageKind.SHARED -> // If current file used a shared object, make file's (de)initializer function deinit it. context.llvm.globalSharedObjects += objectPtr ObjectStorageKind.THREAD_LOCAL -> // If current file used locally defined TLS objects, make file's (de)initializer function // init and deinit TLS. // Note: for exported TLS objects a getter is generated in a file they're defined in. Which // adds TLS init and deinit to that file's (de)initializer function. if (!isExternal(irClass)) context.llvm.fileUsesThreadLocalObjects = true ObjectStorageKind.PERMANENT -> { /* Do nothing, no need to free such an instance. */ } } if (storageKind == ObjectStorageKind.PERMANENT) { return loadSlot(objectPtr, false) } val bbInit = basicBlock("label_init", startLocationInfo, endLocationInfo) val bbExit = basicBlock("label_continue", startLocationInfo, endLocationInfo) val objectVal = loadSlot(objectPtr, false) val objectInitialized = icmpUGt(ptrToInt(objectVal, codegen.intPtrType), codegen.immOneIntPtrType) val bbCurrent = currentBlock condBr(objectInitialized, bbExit, bbInit) positionAtEnd(bbInit) val typeInfo = codegen.typeInfoForAllocation(irClass) val defaultConstructor = irClass.constructors.single { it.valueParameters.size == 0 } val ctor = codegen.llvmFunction(defaultConstructor) val initFunction = if (storageKind == ObjectStorageKind.SHARED && context.config.threadsAreAllowed) { context.llvm.initSingletonFunction } else { context.llvm.initThreadLocalSingleton } val args = listOf(objectPtr, typeInfo, ctor) val newValue = call(initFunction, args, Lifetime.GLOBAL, exceptionHandler) val bbInitResult = currentBlock br(bbExit) positionAtEnd(bbExit) val valuePhi = phi(codegen.getLLVMType(irClass.defaultType)) addPhiIncoming(valuePhi, bbCurrent to objectVal, bbInitResult to newValue) return valuePhi } /** * Note: the same code is generated as IR in [org.jetbrains.kotlin.backend.konan.lower.EnumUsageLowering]. */ fun getEnumEntry(enumEntry: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { val enumClass = enumEntry.parentAsClass val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) val ordinal = loweredEnum.entriesMap[enumEntry.name]!! val values = call( loweredEnum.valuesGetter.llvmFunction, emptyList(), Lifetime.ARGUMENT, exceptionHandler ) return call( loweredEnum.itemGetterSymbol.owner.llvmFunction, listOf(values, Int32(ordinal).llvm), Lifetime.GLOBAL, exceptionHandler ) } // TODO: get rid of exceptionHandler argument by ensuring that all called functions are non-throwing. fun getObjCClass(irClass: IrClass, exceptionHandler: ExceptionHandler): LLVMValueRef { assert(!irClass.isInterface) return if (irClass.isExternalObjCClass()) { val llvmSymbolOrigin = irClass.llvmSymbolOrigin if (irClass.isObjCMetaClass()) { val name = irClass.descriptor.getExternalObjCMetaClassBinaryName() val objCClass = getObjCClass(name, llvmSymbolOrigin) val getClass = context.llvm.externalFunction( "object_getClass", functionType(int8TypePtr, false, int8TypePtr), origin = context.standardLlvmSymbolsOrigin ) call(getClass, listOf(objCClass), exceptionHandler = exceptionHandler) } else { getObjCClass(irClass.descriptor.getExternalObjCClassBinaryName(), llvmSymbolOrigin) } } else { if (irClass.isObjCMetaClass()) { error("type-checking against Kotlin classes inheriting Objective-C meta-classes isn't supported yet") } val classInfo = codegen.kotlinObjCClassInfo(irClass) val classPointerGlobal = load(structGep(classInfo, KotlinObjCClassInfoGenerator.createdClassFieldIndex)) val storedClass = this.load(classPointerGlobal) val storedClassIsNotNull = this.icmpNe(storedClass, kNullInt8Ptr) return this.ifThenElse(storedClassIsNotNull, storedClass) { call( context.llvm.createKotlinObjCClass, listOf(classInfo), exceptionHandler = exceptionHandler ) } } } fun getObjCClass(binaryName: String, llvmSymbolOrigin: CompiledKlibModuleOrigin): LLVMValueRef { context.llvm.imports.add(llvmSymbolOrigin) return load(codegen.objCDataGenerator!!.genClassRef(binaryName).llvm) } fun resetDebugLocation() { if (!context.shouldContainLocationDebugInfo()) return currentPositionHolder.resetBuilderDebugLocation() } private fun position() = basicBlockToLastLocation[currentBlock] internal fun mapParameterForDebug(index: Int, value: LLVMValueRef) { appendingTo(localsInitBb) { LLVMBuildStore(builder, value, vars.addressOf(index)) } } internal fun prologue() { assert(returns.isEmpty()) if (isObjectType(returnType!!)) { returnSlot = LLVMGetParam(function, numParameters(function.type) - 1) } positionAtEnd(localsInitBb) slotsPhi = phi(kObjHeaderPtrPtr) // Is removed by DCE trivially, if not needed. /*arenaSlot = intToPtr( or(ptrToInt(slotsPhi, codegen.intPtrType), codegen.immOneIntPtrType), kObjHeaderPtrPtr)*/ positionAtEnd(entryBb) } internal fun epilogue() { appendingTo(prologueBb) { if (needsRuntimeInit) { check(!forbidRuntime) { "Attempt to init runtime where runtime usage is forbidden" } call(context.llvm.initRuntimeIfNeeded, emptyList()) } val slots = if (needSlotsPhi) LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!! else kNullObjHeaderPtrPtr if (needSlots) { check(!forbidRuntime) { "Attempt to start a frame where runtime usage is forbidden" } // Zero-init slots. val slotsMem = bitcast(kInt8Ptr, slots) call(context.llvm.memsetFunction, listOf(slotsMem, Int8(0).llvm, Int32(slotCount * codegen.runtime.pointerSize).llvm, Int1(0).llvm)) call(context.llvm.enterFrameFunction, listOf(slots, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) } addPhiIncoming(slotsPhi!!, prologueBb to slots) memScoped { slotToVariableLocation.forEach { slot, variable -> val expr = longArrayOf(DwarfOp.DW_OP_plus_uconst.value, runtime.pointerSize * slot.toLong()).toCValues() DIInsertDeclaration( builder = codegen.context.debugInfo.builder, value = slots, localVariable = variable.localVariable, location = variable.location, bb = prologueBb, expr = expr, exprCount = 2) } } br(localsInitBb) } appendingTo(localsInitBb) { br(stackLocalsInitBb) } appendingTo(stackLocalsInitBb) { br(entryBb) } appendingTo(epilogueBb) { when { returnType == voidType -> { releaseVars() assert(returnSlot == null) if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList()) LLVMBuildRetVoid(builder) } returns.isNotEmpty() -> { val returnPhi = phi(returnType!!) addPhiIncoming(returnPhi, *returns.toList().toTypedArray()) if (returnSlot != null) { updateReturnRef(returnPhi, returnSlot!!) } releaseVars() if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList()) LLVMBuildRet(builder, returnPhi) } // Do nothing, all paths throw. else -> LLVMBuildUnreachable(builder) } } appendingTo(cleanupLandingpad) { val landingpad = gxxLandingpad(numClauses = 0) LLVMSetCleanup(landingpad, 1) forwardingForeignExceptionsTerminatedWith?.let { terminator -> // Catch all but Kotlin exceptions. val clause = ConstArray(int8TypePtr, listOf(kotlinExceptionRtti)) LLVMAddClause(landingpad, clause.llvm) val bbCleanup = basicBlock("forwardException", position()?.end) val bbUnexpected = basicBlock("unexpectedException", position()?.end) val selector = extractValue(landingpad, 1) condBr( icmpLt(selector, Int32(0).llvm), bbUnexpected, bbCleanup ) appendingTo(bbUnexpected) { val exceptionRecord = extractValue(landingpad, 0) val beginCatch = context.llvm.cxaBeginCatchFunction // So `terminator` is called from C++ catch block: call(beginCatch, listOf(exceptionRecord)) call(terminator, emptyList()) unreachable() } positionAtEnd(bbCleanup) } releaseVars() if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointExceptionUnwind, emptyList()) LLVMBuildResume(builder, landingpad) } returns.clear() vars.clear() returnSlot = null slotsPhi = null } private val kotlinExceptionRtti: ConstPointer get() = constPointer(importGlobal( "_ZTI18ExceptionObjHolder", // typeinfo for ObjHolder int8TypePtr, origin = context.stdlibModule.llvmSymbolOrigin )).bitcast(int8TypePtr) private val objcNSExceptionRtti: ConstPointer by lazy { constPointer(importGlobal( "OBJC_EHTYPE_\$_NSException", // typeinfo for NSException* int8TypePtr, origin = context.stdlibModule.llvmSymbolOrigin )).bitcast(int8TypePtr) } //-------------------------------------------------------------------------// /** * Represents the mutable position of instructions being inserted. * * This class is introduced to workaround unreachable code handling. */ inner class PositionHolder { private val builder: LLVMBuilderRef = LLVMCreateBuilderInContext(llvmContext)!! fun getBuilder(): LLVMBuilderRef { if (isAfterTerminator) { val position = position() positionAtEnd(basicBlock("unreachable", position?.start, position?.end)) } return builder } /** * Should be `true` iff the position is located after terminator instruction. */ var isAfterTerminator: Boolean = false private set fun setAfterTerminator() { isAfterTerminator = true } val currentBlock: LLVMBasicBlockRef get() = LLVMGetInsertBlock(builder)!! fun positionAtEnd(block: LLVMBasicBlockRef) { LLVMPositionBuilderAtEnd(builder, block) basicBlockToLastLocation[block]?.let{ debugLocation(it.start, it.end) } val lastInstr = LLVMGetLastInstruction(block) isAfterTerminator = lastInstr != null && (LLVMIsATerminatorInst(lastInstr) != null) } fun dispose() { LLVMDisposeBuilder(builder) } fun resetBuilderDebugLocation() { if (!context.shouldContainLocationDebugInfo()) return LLVMBuilderResetDebugLocation(builder) } fun setBuilderDebugLocation(debugLocation: DILocationRef?) { if (!context.shouldContainLocationDebugInfo()) return LLVMBuilderSetDebugLocation(builder, debugLocation) } } private var currentPositionHolder: PositionHolder = PositionHolder() /** * Returns `true` iff the current code generation position is located after terminator instruction. */ fun isAfterTerminator() = currentPositionHolder.isAfterTerminator val currentBlock: LLVMBasicBlockRef get() = currentPositionHolder.currentBlock /** * The builder representing the current code generation position. * * Note that it shouldn't be positioned directly using LLVM API due to some hacks. * Use e.g. [positionAtEnd] instead. See [PositionHolder] for details. */ val builder: LLVMBuilderRef get() = currentPositionHolder.getBuilder() fun positionAtEnd(bbLabel: LLVMBasicBlockRef) = currentPositionHolder.positionAtEnd(bbLabel) inline private fun preservingPosition(code: () -> R): R { val oldPositionHolder = currentPositionHolder val newPositionHolder = PositionHolder() currentPositionHolder = newPositionHolder try { return code() } finally { currentPositionHolder = oldPositionHolder newPositionHolder.dispose() } } inline fun appendingTo(block: LLVMBasicBlockRef, code: FunctionGenerationContext.() -> R) = preservingPosition { positionAtEnd(block) code() } private val needSlots: Boolean get() { return slotCount - vars.skipSlots > frameOverlaySlotCount } private val needSlotsPhi: Boolean get() { return slotCount > frameOverlaySlotCount || localAllocs > 0 } private fun releaseVars() { if (needSlots) { check(!forbidRuntime) { "Attempt to leave a frame where runtime usage is forbidden" } call(context.llvm.leaveFrameFunction, listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) } stackLocalsManager.clean(refsOnly = true) // Only bother about not leaving any dangling references. } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.allocArray import kotlinx.cinterop.get import kotlinx.cinterop.memScoped import kotlinx.cinterop.toKString import llvm.* import org.jetbrains.kotlin.backend.konan.CachedLibraries import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.hash.GlobalHash import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.isReal import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.cast import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty internal sealed class SlotType { // An object is statically allocated on stack. object STACK : SlotType() // Frame local arena slot can be used. object ARENA : SlotType() // Return slot can be used. object RETURN : SlotType() // Return slot, if it is an arena, can be used. object RETURN_IF_ARENA : SlotType() // Param slot, if it is an arena, can be used. class PARAM_IF_ARENA(val parameter: Int) : SlotType() // Params slot, if it is an arena, can be used. class PARAMS_IF_ARENA(val parameters: IntArray, val useReturnSlot: Boolean) : SlotType() // Anonymous slot. object ANONYMOUS : SlotType() // Unknown slot type. object UNKNOWN : SlotType() } // Lifetimes class of reference, computed by escape analysis. internal sealed class Lifetime(val slotType: SlotType) { object STACK : Lifetime(SlotType.STACK) { override fun toString(): String { return "STACK" } } // If reference is frame-local (only obtained from some call and never leaves). object LOCAL : Lifetime(SlotType.ARENA) { override fun toString(): String { return "LOCAL" } } // If reference is only returned. object RETURN_VALUE : Lifetime(SlotType.ANONYMOUS) { override fun toString(): String { return "RETURN_VALUE" } } // If reference is set as field of references of class RETURN_VALUE or INDIRECT_RETURN_VALUE. object INDIRECT_RETURN_VALUE : Lifetime(SlotType.RETURN_IF_ARENA) { override fun toString(): String { return "INDIRECT_RETURN_VALUE" } } // If reference is stored to the field of an incoming parameters. class PARAMETER_FIELD(val parameter: Int) : Lifetime(SlotType.PARAM_IF_ARENA(parameter)) { override fun toString(): String { return "PARAMETER_FIELD($parameter)" } } // If reference is stored to the field of an incoming parameters. class PARAMETERS_FIELD(val parameters: IntArray, val useReturnSlot: Boolean) : Lifetime(SlotType.PARAMS_IF_ARENA(parameters, useReturnSlot)) { override fun toString(): String { return "PARAMETERS_FIELD(${parameters.contentToString()}, useReturnSlot='$useReturnSlot')" } } // If reference refers to the global (either global object or global variable). object GLOBAL : Lifetime(SlotType.ANONYMOUS) { override fun toString(): String { return "GLOBAL" } } // If reference used to throw. object THROW : Lifetime(SlotType.ANONYMOUS) { override fun toString(): String { return "THROW" } } // If reference used as an argument of outgoing function. Class can be improved by escape analysis // of called function. object ARGUMENT : Lifetime(SlotType.ANONYMOUS) { override fun toString(): String { return "ARGUMENT" } } // If reference class is unknown. object UNKNOWN : Lifetime(SlotType.UNKNOWN) { override fun toString(): String { return "UNKNOWN" } } // If reference class is irrelevant. object IRRELEVANT : Lifetime(SlotType.UNKNOWN) { override fun toString(): String { return "IRRELEVANT" } } } /** * Provides utility methods to the implementer. */ internal interface ContextUtils : RuntimeAware { val context: Context override val runtime: Runtime get() = context.llvm.runtime /** * Describes the target platform. * * TODO: using [llvmTargetData] usually results in generating non-portable bitcode. */ val llvmTargetData: LLVMTargetDataRef get() = runtime.targetData val staticData: StaticData get() = context.llvm.staticData /** * TODO: maybe it'd be better to replace with [IrDeclaration::isEffectivelyExternal()], * or just drop all [else] branches of corresponding conditionals. */ fun isExternal(declaration: IrDeclaration): Boolean { return !context.llvmModuleSpecification.containsDeclaration(declaration) } /** * LLVM function generated from the Kotlin function. * It may be declared as external function prototype. */ val IrFunction.llvmFunction: LLVMValueRef get() = llvmFunctionOrNull ?: error("$name in $file/${parent.fqNameForIrSerialization}") val IrFunction.llvmFunctionOrNull: LLVMValueRef? get() { assert(this.isReal) return if (isExternal(this)) { runtime.addedLLVMExternalFunctions.getOrPut(this) { context.llvm.externalFunction(this.computeSymbolName(), getLlvmFunctionType(this), origin = this.llvmSymbolOrigin) } } else { context.llvmDeclarations.forFunctionOrNull(this)?.llvmFunction } } /** * Address of entry point of [llvmFunction]. */ val IrFunction.entryPointAddress: ConstPointer get() { val result = LLVMConstBitCast(this.llvmFunction, int8TypePtr)!! return constPointer(result) } val IrClass.typeInfoPtr: ConstPointer get() { return if (isExternal(this)) { constPointer(importGlobal(this.computeTypeInfoSymbolName(), runtime.typeInfoType, origin = this.llvmSymbolOrigin)) } else { context.llvmDeclarations.forClass(this).typeInfo } } /** * Pointer to type info for given class. * It may be declared as pointer to external variable. */ val IrClass.llvmTypeInfoPtr: LLVMValueRef get() = typeInfoPtr.llvm /** * Returns contents of this [GlobalHash]. * * It must be declared identically with [Runtime.globalHashType]. */ fun GlobalHash.getBytes(): ByteArray { @Suppress("DEPRECATION") val size = GlobalHash.size assert(size == LLVMStoreSizeOfType(llvmTargetData, runtime.globalHashType)) return this.bits.getBytes(size) } /** * Returns global hash of this string contents. */ val String.globalHashBytes: ByteArray get() = memScoped { val hash = globalHash(stringAsBytes(this@globalHashBytes), memScope) hash.getBytes() } /** * Return base64 representation for global hash of this string contents. */ val String.globalHashBase64: String get() { return base64Encode(globalHashBytes) } val String.globalHash: ConstValue get() = memScoped { val hashBytes = this@globalHash.globalHashBytes return Struct(runtime.globalHashType, ConstArray(int8Type, hashBytes.map { Int8(it) })) } val FqName.globalHash: ConstValue get() = this.toString().globalHash } /** * Converts this string to the sequence of bytes to be used for hashing/storing to binary/etc. */ internal fun stringAsBytes(str: String) = str.toByteArray(Charsets.UTF_8) internal val String.localHash: LocalHash get() = LocalHash(localHash(stringAsBytes(this))) internal val Name.localHash: LocalHash get() = this.toString().localHash internal val FqName.localHash: LocalHash get() = this.toString().localHash internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { private fun importFunction(name: String, otherModule: LLVMModuleRef): LLVMValueRef { if (LLVMGetNamedFunction(llvmModule, name) != null) { throw IllegalArgumentException("function $name already exists") } val externalFunction = LLVMGetNamedFunction(otherModule, name) ?: throw Error("function $name not found") val functionType = getFunctionType(externalFunction) val function = LLVMAddFunction(llvmModule, name, functionType)!! copyFunctionAttributes(externalFunction, function) return function } private fun importGlobal(name: String, otherModule: LLVMModuleRef): LLVMValueRef { if (LLVMGetNamedGlobal(llvmModule, name) != null) { throw IllegalArgumentException("global $name already exists") } val externalGlobal = LLVMGetNamedGlobal(otherModule, name)!! val globalType = getGlobalType(externalGlobal) val global = LLVMAddGlobal(llvmModule, globalType, name)!! return global } private fun copyFunctionAttributes(source: LLVMValueRef, destination: LLVMValueRef) { // TODO: consider parameter attributes val attributeIndex = LLVMAttributeFunctionIndex val count = LLVMGetAttributeCountAtIndex(source, attributeIndex) memScoped { val attributes = allocArray(count) LLVMGetAttributesAtIndex(source, attributeIndex, attributes) (0 until count).forEach { LLVMAddAttributeAtIndex(destination, attributeIndex, attributes[it]) } } } private fun importMemset(): LLVMValueRef { val functionType = functionType(voidType, false, int8TypePtr, int8Type, int32Type, int1Type) return llvmIntrinsic("llvm.memset.p0i8.i32", functionType) } private fun llvmIntrinsic(name: String, type: LLVMTypeRef, vararg attributes: String): LLVMValueRef { val result = LLVMAddFunction(llvmModule, name, type)!! attributes.forEach { val kindId = getLlvmAttributeKindId(it) addLlvmFunctionEnumAttribute(result, kindId) } return result } internal fun externalFunction( name: String, type: LLVMTypeRef, origin: CompiledKlibModuleOrigin, independent: Boolean = false ): LLVMValueRef { this.imports.add(origin, onlyBitcode = independent) val found = LLVMGetNamedFunction(llvmModule, name) if (found != null) { assert(getFunctionType(found) == type) { "Expected: ${LLVMPrintTypeToString(type)!!.toKString()} " + "found: ${LLVMPrintTypeToString(getFunctionType(found))!!.toKString()}" } assert(LLVMGetLinkage(found) == LLVMLinkage.LLVMExternalLinkage) return found } else { // As exported functions are written in C++ they assume sign extension for promoted types - // mention that in attributes. val function = addLlvmFunctionWithDefaultAttributes(context, llvmModule, name, type) return memScoped { val paramCount = LLVMCountParamTypes(type) val paramTypes = allocArray(paramCount) LLVMGetParamTypes(type, paramTypes) (0 until paramCount).forEach { index -> val paramType = paramTypes[index] addFunctionSignext(function, index + 1, paramType) } val returnType = LLVMGetReturnType(type) addFunctionSignext(function, 0, returnType) function } } } private fun externalNounwindFunction(name: String, type: LLVMTypeRef, origin: CompiledKlibModuleOrigin): LLVMValueRef { val function = externalFunction(name, type, origin) setFunctionNoUnwind(function) return function } val imports get() = context.llvmImports class ImportsImpl(private val context: Context) : LlvmImports { private val usedBitcode = mutableSetOf() private val usedNativeDependencies = mutableSetOf() private val allLibraries by lazy { context.librariesWithDependencies.toSet() } override fun add(origin: CompiledKlibModuleOrigin, onlyBitcode: Boolean) { val library = when (origin) { CurrentKlibModuleOrigin -> return is DeserializedKlibModuleOrigin -> origin.library } if (library !in allLibraries) { error("Library (${library.libraryName}) is used but not requested.\nRequested libraries: ${allLibraries.joinToString { it.libraryName }}") } usedBitcode.add(library) if (!onlyBitcode) { usedNativeDependencies.add(library) } } override fun bitcodeIsUsed(library: KonanLibrary) = library in usedBitcode override fun nativeDependenciesAreUsed(library: KonanLibrary) = library in usedNativeDependencies } val nativeDependenciesToLink: List by lazy { context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) .filter { require(it is KonanLibrary) (!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it) }.cast>() } private val immediateBitcodeDependencies: List by lazy { context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast>() .filter { (!it.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(it) } } val allCachedBitcodeDependencies: List by lazy { val allLibraries = context.config.resolvedLibraries.getFullList().associateBy { it.uniqueName } val result = mutableSetOf() fun addDependencies(cachedLibrary: CachedLibraries.Cache) { cachedLibrary.bitcodeDependencies.forEach { val library = allLibraries[it] ?: error("Bitcode dependency to an unknown library: $it") result.add(library as KonanLibrary) addDependencies(context.config.cachedLibraries.getLibraryCache(library) ?: error("Library $it is expected to be cached")) } } for (library in immediateBitcodeDependencies) { val cache = context.config.cachedLibraries.getLibraryCache(library) if (cache != null) { result += library addDependencies(cache) } } result.toList() } val allNativeDependencies: List by lazy { (nativeDependenciesToLink + allCachedBitcodeDependencies).distinct() } val allBitcodeDependencies: List by lazy { val allNonCachedDependencies = context.librariesWithDependencies.filter { context.config.cachedLibraries.getLibraryCache(it) == null } val set = (allNonCachedDependencies + allCachedBitcodeDependencies).toSet() // This list is used in particular to build the libraries' initializers chain. // The initializers must be called in the topological order, so make sure that the // libraries list being returned is also toposorted. context.config.resolvedLibraries .getFullList(TopologicalLibraryOrder) .cast>() .filter { it in set } } val bitcodeToLink: List by lazy { (context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast>()) .filter { shouldContainBitcode(it) } } private fun shouldContainBitcode(library: KonanLibrary): Boolean { if (!context.llvmModuleSpecification.containsLibrary(library)) { return false } if (!context.llvmModuleSpecification.isFinal) { return true } // Apply some DCE: return (!library.isDefault && !context.config.purgeUserLibs) || imports.bitcodeIsUsed(library) } val additionalProducedBitcodeFiles = mutableListOf() val staticData = StaticData(context) private val target = context.config.target val runtimeFile = context.config.distribution.runtime(target) val runtime = Runtime(runtimeFile) // TODO: dispose val targetTriple = runtime.target init { LLVMSetDataLayout(llvmModule, runtime.dataLayout) LLVMSetTarget(llvmModule, targetTriple) } private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule) private fun importRtGlobal(name: String) = importGlobal(name, runtime.llvmModule) val allocInstanceFunction = importRtFunction("AllocInstance") val allocArrayFunction = importRtFunction("AllocArrayInstance") val initThreadLocalSingleton = importRtFunction("InitThreadLocalSingleton") val initSingletonFunction = importRtFunction("InitSingleton") val initAndRegisterGlobalFunction = importRtFunction("InitAndRegisterGlobal") val updateHeapRefFunction = importRtFunction("UpdateHeapRef") val updateStackRefFunction = importRtFunction("UpdateStackRef") val updateReturnRefFunction = importRtFunction("UpdateReturnRef") val zeroHeapRefFunction = importRtFunction("ZeroHeapRef") val zeroArrayRefsFunction = importRtFunction("ZeroArrayRefs") val enterFrameFunction = importRtFunction("EnterFrame") val leaveFrameFunction = importRtFunction("LeaveFrame") val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod") val lookupInterfaceTableRecord = importRtFunction("LookupInterfaceTableRecord") val isInstanceFunction = importRtFunction("IsInstance") val isInstanceOfClassFastFunction = importRtFunction("IsInstanceOfClassFast") val throwExceptionFunction = importRtFunction("ThrowException") val appendToInitalizersTail = importRtFunction("AppendToInitializersTail") val addTLSRecord = importRtFunction("AddTLSRecord") val lookupTLS = importRtFunction("LookupTLS") val initRuntimeIfNeeded = importRtFunction("Kotlin_initRuntimeIfNeeded") val mutationCheck = importRtFunction("MutationCheck") val checkLifetimesConstraint = importRtFunction("CheckLifetimesConstraint") val freezeSubgraph = importRtFunction("FreezeSubgraph") val checkGlobalsAccessible = importRtFunction("CheckGlobalsAccessible") val Kotlin_getExceptionObject = importRtFunction("Kotlin_getExceptionObject") val kRefSharedHolderInitLocal = importRtFunction("KRefSharedHolder_initLocal") val kRefSharedHolderInit = importRtFunction("KRefSharedHolder_init") val kRefSharedHolderDispose = importRtFunction("KRefSharedHolder_dispose") val kRefSharedHolderRef = importRtFunction("KRefSharedHolder_ref") val createKotlinObjCClass by lazy { importRtFunction("CreateKotlinObjCClass") } val getObjCKotlinTypeInfo by lazy { importRtFunction("GetObjCKotlinTypeInfo") } val missingInitImp by lazy { importRtFunction("MissingInitImp") } val Kotlin_Interop_DoesObjectConformToProtocol by lazyRtFunction val Kotlin_Interop_IsObjectKindOfClass by lazyRtFunction val Kotlin_ObjCExport_refToObjC by lazyRtFunction val Kotlin_ObjCExport_refFromObjC by lazyRtFunction val Kotlin_ObjCExport_CreateNSStringFromKString by lazyRtFunction val Kotlin_ObjCExport_convertUnit by lazyRtFunction val Kotlin_ObjCExport_GetAssociatedObject by lazyRtFunction val Kotlin_ObjCExport_AbstractMethodCalled by lazyRtFunction val Kotlin_ObjCExport_RethrowExceptionAsNSError by lazyRtFunction val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction val Kotlin_ObjCExport_AllocInstanceWithAssociatedObject by lazyRtFunction val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction val Kotlin_ObjCExport_resumeContinuation by lazyRtFunction val Kotlin_mm_safePointFunctionEpilogue by lazyRtFunction val Kotlin_mm_safePointWhileLoopBody by lazyRtFunction val Kotlin_mm_safePointExceptionUnwind by lazyRtFunction val tlsMode by lazy { when (target) { KonanTarget.WASM32, is KonanTarget.ZEPHYR -> LLVMThreadLocalMode.LLVMNotThreadLocal else -> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel } } var tlsCount = 0 val tlsKey by lazy { val global = LLVMAddGlobal(llvmModule, kInt8Ptr, "__KonanTlsKey")!! LLVMSetLinkage(global, LLVMLinkage.LLVMInternalLinkage) LLVMSetInitializer(global, LLVMConstNull(kInt8Ptr)) global } private val personalityFunctionName = when (target) { KonanTarget.IOS_ARM32 -> "__gxx_personality_sj0" KonanTarget.MINGW_X64 -> "__gxx_personality_seh0" else -> "__gxx_personality_v0" } val cxxStdTerminate = externalNounwindFunction( "_ZSt9terminatev", // mangled C++ 'std::terminate' functionType(voidType, false), origin = context.standardLlvmSymbolsOrigin ) val gxxPersonalityFunction = externalNounwindFunction( personalityFunctionName, functionType(int32Type, true), origin = context.standardLlvmSymbolsOrigin ) val cxaBeginCatchFunction = externalNounwindFunction( "__cxa_begin_catch", functionType(int8TypePtr, false, int8TypePtr), origin = context.standardLlvmSymbolsOrigin ) val cxaEndCatchFunction = externalNounwindFunction( "__cxa_end_catch", functionType(voidType, false), origin = context.standardLlvmSymbolsOrigin ) val memsetFunction = importMemset() //val memcpyFunction = importMemcpy() val llvmTrap = llvmIntrinsic( "llvm.trap", functionType(voidType, false), "cold", "noreturn", "nounwind" ) val llvmEhTypeidFor = llvmIntrinsic( "llvm.eh.typeid.for", functionType(int32Type, false, int8TypePtr), "nounwind", "readnone" ) val usedFunctions = mutableListOf() val usedGlobals = mutableListOf() val compilerUsedGlobals = mutableListOf() val irStaticInitializers = mutableListOf() val otherStaticInitializers = mutableListOf() val fileInitializers = mutableListOf() var fileUsesThreadLocalObjects = false val globalSharedObjects = mutableSetOf() private object lazyRtFunction { operator fun provideDelegate( thisRef: Llvm, property: KProperty<*> ) = object : ReadOnlyProperty { val value by lazy { thisRef.importRtFunction(property.name) } override fun getValue(thisRef: Llvm, property: KProperty<*>): LLVMValueRef = value } } val llvmInt8 = int8Type val llvmInt16 = int16Type val llvmInt32 = int32Type val llvmInt64 = int64Type val llvmFloat = floatType val llvmDouble = doubleType val llvmVector128 = vector128Type } class IrStaticInitializer(val konanLibrary: KotlinLibrary?, val initializer: LLVMValueRef) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.types.isUnit private fun RuntimeAware.getLlvmType(primitiveBinaryType: PrimitiveBinaryType?) = when (primitiveBinaryType) { null -> this.kObjHeaderPtr PrimitiveBinaryType.BOOLEAN -> int1Type PrimitiveBinaryType.BYTE -> int8Type PrimitiveBinaryType.SHORT -> int16Type PrimitiveBinaryType.INT -> int32Type PrimitiveBinaryType.LONG -> int64Type PrimitiveBinaryType.FLOAT -> floatType PrimitiveBinaryType.DOUBLE -> doubleType PrimitiveBinaryType.VECTOR128 -> vector128Type PrimitiveBinaryType.POINTER -> int8TypePtr } internal fun RuntimeAware.getLLVMType(type: IrType): LLVMTypeRef = runtime.calculatedLLVMTypes.getOrPut(type) { getLlvmType(type.computePrimitiveBinaryTypeOrNull()) } internal fun RuntimeAware.getLLVMType(type: DataFlowIR.Type) = getLlvmType(type.primitiveBinaryType) internal fun IrType.isVoidAsReturnType() = isUnit() || isNothing() internal fun RuntimeAware.getLLVMReturnType(type: IrType): LLVMTypeRef { return when { type.isVoidAsReturnType() -> voidType else -> getLLVMType(type) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.allocArrayOf import kotlinx.cinterop.memScoped import kotlinx.cinterop.reinterpret import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.ir.SourceManager.FileEntry import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET import org.jetbrains.kotlin.ir.util.isTypeParameter import org.jetbrains.kotlin.ir.util.isUnsigned import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.utils.addToStdlib.cast internal object DWARF { val producer = "konanc ${CompilerVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}" /* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */ val dwarfVersionMetaDataNodeName get() = "Dwarf Version".mdString() val dwarfDebugInfoMetaDataNodeName get() = "Debug Info Version".mdString() const val debugInfoVersion = 3 /* TODO: configurable? */ /** * This is the value taken from [DIFlags.FlagFwdDecl], to mark type declaration as * forward one. */ const val flagsForwardDeclaration = 4 fun runtimeVersion(config: KonanConfig) = when (config.debugInfoVersion()) { 2 -> 0 1 -> 2 /* legacy :/ */ else -> TODO("unsupported debug info format version") } /** * Note: Kotlin language constant appears in DWARF v6, while modern linker fails to links DWARF other then [2;4], * that why we emit version 4 actually. */ fun dwarfVersion(config : KonanConfig) = when (config.debugInfoVersion()) { 1 -> 2 2 -> 4 /* likely the most of the future kotlin native debug info format versions will emit DWARF v4 */ else -> TODO("unsupported debug info format version") } fun language(config: KonanConfig) = when (config.debugInfoVersion()) { 1 -> DwarfLanguage.DW_LANG_C89.value else -> DwarfLanguage.DW_LANG_Kotlin.value } } fun KonanConfig.debugInfoVersion():Int = configuration[KonanConfigKeys.DEBUG_INFO_VERSION] ?: 1 internal class DebugInfo internal constructor(override val context: Context):ContextUtils { val files = mutableMapOf() val subprograms = mutableMapOf() /* Some functions are inlined on all callsites and body is eliminated by DCE, so there's no LLVM value */ val inlinedSubprograms = mutableMapOf() var builder: DIBuilderRef? = null var module: DIModuleRef? = null var compilationUnit: DIScopeOpaqueRef? = null var objHeaderPointerType: DITypeOpaqueRef? = null var types = mutableMapOf() val llvmTypes = mapOf( context.irBuiltIns.booleanType to context.llvm.llvmInt8, context.irBuiltIns.byteType to context.llvm.llvmInt8, context.irBuiltIns.charType to context.llvm.llvmInt16, context.irBuiltIns.shortType to context.llvm.llvmInt16, context.irBuiltIns.intType to context.llvm.llvmInt32, context.irBuiltIns.longType to context.llvm.llvmInt64, context.irBuiltIns.floatType to context.llvm.llvmFloat, context.irBuiltIns.doubleType to context.llvm.llvmDouble) val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap() val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap() val otherLlvmType = LLVMPointerType(int64Type, 0)!! val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType) val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType) val compilerGeneratedFile by lazy { DICreateFile(builder, "", "")!! } } /** * File entry starts offsets from zero while dwarf number lines/column starting from 1. */ private val NO_SOURCE_FILE = "no source file" private fun FileEntry.location(offset: Int, offsetToNumber: (Int) -> Int): Int { assert(offset != UNDEFINED_OFFSET) // Part "name.isEmpty() || name == NO_SOURCE_FILE" is an awful hack, @minamoto, please fix properly. if (offset == SYNTHETIC_OFFSET || name.isEmpty() || name == NO_SOURCE_FILE) return 1 // lldb uses 1-based unsigned integers, so 0 is "no-info". val result = offsetToNumber(offset) + 1 assert(result != 0) return result } internal fun FileEntry.line(offset: Int) = location(offset, this::getLineNumber) internal fun FileEntry.column(offset: Int) = location(offset, this::getColumnNumber) internal data class FileAndFolder(val file: String, val folder: String) { companion object { val NOFILE = FileAndFolder("-", "") } fun path() = if (this == NOFILE) file else "$folder/$file" } internal fun String?.toFileAndFolder(context: Context):FileAndFolder { this ?: return FileAndFolder.NOFILE val file = File(this).absoluteFile var parent = file.parent context.configuration.get(KonanConfigKeys.DEBUG_PREFIX_MAP)?.let { debugPrefixMap -> for ((key, value) in debugPrefixMap) { if (parent.startsWith(key)) { parent = value + parent.removePrefix(key) } } } return FileAndFolder(file.name, parent) } internal fun generateDebugInfoHeader(context: Context) { if (context.shouldContainAnyDebugInfo()) { val path = context.config.outputFile .toFileAndFolder(context) @Suppress("UNCHECKED_CAST") context.debugInfo.module = DICreateModule( builder = context.debugInfo.builder, scope = null, name = path.path(), configurationMacro = "", includePath = "", iSysRoot = "") /* TODO: figure out what here 2 means: * * 0:b-backend-dwarf:minamoto@minamoto-osx(0)# cat /dev/null | clang -xc -S -emit-llvm -g -o - - * ; ModuleID = '-' * source_filename = "-" * target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" * target triple = "x86_64-apple-macosx10.12.0" * * !llvm.dbg.cu = !{!0} * !llvm.module.flags = !{!3, !4, !5} * !llvm.ident = !{!6} * * !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Apple LLVM version 8.0.0 (clang-800.0.38)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) * !1 = !DIFile(filename: "-", directory: "/Users/minamoto/ws/.git-trees/backend-dwarf") * !2 = !{} * !3 = !{i32 2, !"Dwarf Version", i32 2} ; <- * !4 = !{i32 2, !"Debug Info Version", i32 700000003} ; <- * !5 = !{i32 1, !"PIC Level", i32 2} * !6 = !{!"Apple LLVM version 8.0.0 (clang-800.0.38)"} */ val llvmTwo = Int32(2).llvm val dwarfVersion = node(llvmTwo, DWARF.dwarfVersionMetaDataNodeName, Int32(DWARF.dwarfVersion(context.config)).llvm) val nodeDebugInfoVersion = node(llvmTwo, DWARF.dwarfDebugInfoMetaDataNodeName, Int32(DWARF.debugInfoVersion).llvm) val llvmModuleFlags = "llvm.module.flags" LLVMAddNamedMetadataOperand(context.llvmModule, llvmModuleFlags, dwarfVersion) LLVMAddNamedMetadataOperand(context.llvmModule, llvmModuleFlags, nodeDebugInfoVersion) val objHeaderType = DICreateStructType( refBuilder = context.debugInfo.builder, // TODO: here should be DIFile as scope. scope = null, name = "ObjHeader", file = null, lineNumber = 0, sizeInBits = 0, alignInBits = 0, flags = DWARF.flagsForwardDeclaration, derivedFrom = null, elements = null, elementsCount = 0, refPlace = null).cast() context.debugInfo.objHeaderPointerType = dwarfPointerType(context, objHeaderType) } } @Suppress("UNCHECKED_CAST") internal fun IrType.dwarfType(context: Context, targetData: LLVMTargetDataRef): DITypeOpaqueRef { when { this.computePrimitiveBinaryTypeOrNull() != null -> return debugInfoBaseType(context, targetData, this.render(), llvmType(context), encoding().value.toInt()) else -> { return when { classOrNull != null || this.isTypeParameter() -> context.debugInfo.objHeaderPointerType!! else -> TODO("$this: Does this case really exist?") } } } } internal fun IrType.diType(context: Context, llvmTargetData: LLVMTargetDataRef): DITypeOpaqueRef = context.debugInfo.types.getOrPut(this) { dwarfType(context, llvmTargetData) } @Suppress("UNCHECKED_CAST") private fun debugInfoBaseType(context:Context, targetData:LLVMTargetDataRef, typeName:String, type:LLVMTypeRef, encoding:Int) = DICreateBasicType( context.debugInfo.builder, typeName, LLVMSizeOfTypeInBits(targetData, type), LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef internal val IrFunction.types:List get() { val parameters = valueParameters.map { it.type } return listOf(returnType, *parameters.toTypedArray()) } internal fun IrType.size(context:Context) = context.debugInfo.llvmTypeSizes.getOrDefault(this, context.debugInfo.otherTypeSize) internal fun IrType.alignment(context:Context) = context.debugInfo.llvmTypeAlignments.getOrDefault(this, context.debugInfo.otherTypeAlignment).toLong() internal fun IrType.llvmType(context:Context): LLVMTypeRef = context.debugInfo.llvmTypes.getOrElse(this) { when(computePrimitiveBinaryTypeOrNull()) { PrimitiveBinaryType.BYTE -> context.llvm.llvmInt8 PrimitiveBinaryType.SHORT -> context.llvm.llvmInt16 PrimitiveBinaryType.INT -> context.llvm.llvmInt32 PrimitiveBinaryType.LONG -> context.llvm.llvmInt64 PrimitiveBinaryType.FLOAT -> context.llvm.llvmFloat PrimitiveBinaryType.DOUBLE -> context.llvm.llvmDouble PrimitiveBinaryType.VECTOR128 -> context.llvm.llvmVector128 else -> context.debugInfo.otherLlvmType } } internal fun IrType.encoding(): DwarfTypeKind = when(computePrimitiveBinaryTypeOrNull()) { PrimitiveBinaryType.FLOAT -> DwarfTypeKind.DW_ATE_float PrimitiveBinaryType.DOUBLE -> DwarfTypeKind.DW_ATE_float PrimitiveBinaryType.BOOLEAN -> DwarfTypeKind.DW_ATE_boolean PrimitiveBinaryType.POINTER -> DwarfTypeKind.DW_ATE_address else -> { //TODO: not recursive. if (this.isUnsigned()) DwarfTypeKind.DW_ATE_unsigned else DwarfTypeKind.DW_ATE_signed } } internal fun alignTo(value:Long, align:Long):Long = (value + align - 1) / align * align internal fun IrFunction.subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef): DISubroutineTypeRef { val types = this@subroutineType.types return subroutineType(context, llvmTargetData, types) } internal fun subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef, types: List): DISubroutineTypeRef { return memScoped { DICreateSubroutineType(context.debugInfo.builder, allocArrayOf( types.map { it.diType(context, llvmTargetData) }), types.size)!! } } @Suppress("UNCHECKED_CAST") private fun dwarfPointerType(context: Context, type: DITypeOpaqueRef) = DICreatePointerType(context.debugInfo.builder, type) as DITypeOpaqueRef internal fun setupBridgeDebugInfo(context: Context, function: LLVMValueRef): LocationInfo? { if (!context.shouldContainLocationDebugInfo()) { return null } val file = context.debugInfo.compilerGeneratedFile // TODO: can we share the scope among all bridges? val scope: DIScopeOpaqueRef = DICreateFunction( builder = context.debugInfo.builder, scope = file.reinterpret(), name = function.name, linkageName = function.name, file = file, lineNo = 0, type = subroutineType(context, context.llvm.runtime.targetData, emptyList()), // TODO: use proper type. isLocal = 0, isDefinition = 1, scopeLine = 0 )!!.also { DIFunctionAddSubprogram(function, it) }.reinterpret() return LocationInfo(scope, 1, 0) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Dwarf.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm /** * This code was generated with following command: * $ clang -xc -E -Idist/dependencies/clang-llvm-3.9.0-darwin-macos/include/ llvmDebugInfoC/src/dwarf/include/dwarf_util.kt.pp -Wp,-P -Wp,-CC -o - | sed -e '/^$/d' -e '/^\ *\/\/.*$/d' > backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Dwarf.kt * */ internal enum class DwarfTag(val value:Int) { DW_TAG_array_type(0x0001), DW_TAG_class_type(0x0002), DW_TAG_entry_point(0x0003), DW_TAG_enumeration_type(0x0004), DW_TAG_formal_parameter(0x0005), DW_TAG_imported_declaration(0x0008), DW_TAG_label(0x000a), DW_TAG_lexical_block(0x000b), DW_TAG_member(0x000d), DW_TAG_pointer_type(0x000f), DW_TAG_reference_type(0x0010), DW_TAG_compile_unit(0x0011), DW_TAG_string_type(0x0012), DW_TAG_structure_type(0x0013), DW_TAG_subroutine_type(0x0015), DW_TAG_typedef(0x0016), DW_TAG_union_type(0x0017), DW_TAG_unspecified_parameters(0x0018), DW_TAG_variant(0x0019), DW_TAG_common_block(0x001a), DW_TAG_common_inclusion(0x001b), DW_TAG_inheritance(0x001c), DW_TAG_inlined_subroutine(0x001d), DW_TAG_module(0x001e), DW_TAG_ptr_to_member_type(0x001f), DW_TAG_set_type(0x0020), DW_TAG_subrange_type(0x0021), DW_TAG_with_stmt(0x0022), DW_TAG_access_declaration(0x0023), DW_TAG_base_type(0x0024), DW_TAG_catch_block(0x0025), DW_TAG_const_type(0x0026), DW_TAG_constant(0x0027), DW_TAG_enumerator(0x0028), DW_TAG_file_type(0x0029), DW_TAG_friend(0x002a), DW_TAG_namelist(0x002b), DW_TAG_namelist_item(0x002c), DW_TAG_packed_type(0x002d), DW_TAG_subprogram(0x002e), DW_TAG_template_type_parameter(0x002f), DW_TAG_template_value_parameter(0x0030), DW_TAG_thrown_type(0x0031), DW_TAG_try_block(0x0032), DW_TAG_variant_part(0x0033), DW_TAG_variable(0x0034), DW_TAG_volatile_type(0x0035), DW_TAG_dwarf_procedure(0x0036), DW_TAG_restrict_type(0x0037), DW_TAG_interface_type(0x0038), DW_TAG_namespace(0x0039), DW_TAG_imported_module(0x003a), DW_TAG_unspecified_type(0x003b), DW_TAG_partial_unit(0x003c), DW_TAG_imported_unit(0x003d), DW_TAG_condition(0x003f), DW_TAG_shared_type(0x0040), DW_TAG_type_unit(0x0041), DW_TAG_rvalue_reference_type(0x0042), DW_TAG_template_alias(0x0043), DW_TAG_coarray_type(0x0044), DW_TAG_generic_subrange(0x0045), DW_TAG_dynamic_type(0x0046), DW_TAG_MIPS_loop(0x4081), DW_TAG_format_label(0x4101), DW_TAG_function_template(0x4102), DW_TAG_class_template(0x4103), DW_TAG_GNU_template_template_param(0x4106), DW_TAG_GNU_template_parameter_pack(0x4107), DW_TAG_GNU_formal_parameter_pack(0x4108), DW_TAG_APPLE_property(0x4200), DW_TAG_BORLAND_property(0xb000), DW_TAG_BORLAND_Delphi_string(0xb001), DW_TAG_BORLAND_Delphi_dynamic_array(0xb002), DW_TAG_BORLAND_Delphi_set(0xb003), DW_TAG_BORLAND_Delphi_variant(0xb004), } internal enum class DwarfTypeKind(val value:Byte) { DW_ATE_address(0x01), DW_ATE_boolean(0x02), DW_ATE_complex_float(0x03), DW_ATE_float(0x04), DW_ATE_signed(0x05), DW_ATE_signed_char(0x06), DW_ATE_unsigned(0x07), DW_ATE_unsigned_char(0x08), DW_ATE_imaginary_float(0x09), DW_ATE_packed_decimal(0x0a), DW_ATE_numeric_string(0x0b), DW_ATE_edited(0x0c), DW_ATE_signed_fixed(0x0d), DW_ATE_unsigned_fixed(0x0e), DW_ATE_decimal_float(0x0f), DW_ATE_UTF(0x10), } internal enum class DwarfOp(val value:Long) { DW_OP_addr(0x03), DW_OP_deref(0x06), DW_OP_const1u(0x08), DW_OP_const1s(0x09), DW_OP_const2u(0x0a), DW_OP_const2s(0x0b), DW_OP_const4u(0x0c), DW_OP_const4s(0x0d), DW_OP_const8u(0x0e), DW_OP_const8s(0x0f), DW_OP_constu(0x10), DW_OP_consts(0x11), DW_OP_dup(0x12), DW_OP_drop(0x13), DW_OP_over(0x14), DW_OP_pick(0x15), DW_OP_swap(0x16), DW_OP_rot(0x17), DW_OP_xderef(0x18), DW_OP_abs(0x19), DW_OP_and(0x1a), DW_OP_div(0x1b), DW_OP_minus(0x1c), DW_OP_mod(0x1d), DW_OP_mul(0x1e), DW_OP_neg(0x1f), DW_OP_not(0x20), DW_OP_or(0x21), DW_OP_plus(0x22), DW_OP_plus_uconst(0x23), DW_OP_shl(0x24), DW_OP_shr(0x25), DW_OP_shra(0x26), DW_OP_xor(0x27), DW_OP_skip(0x2f), DW_OP_bra(0x28), DW_OP_eq(0x29), DW_OP_ge(0x2a), DW_OP_gt(0x2b), DW_OP_le(0x2c), DW_OP_lt(0x2d), DW_OP_ne(0x2e), DW_OP_lit0(0x30), DW_OP_lit1(0x31), DW_OP_lit2(0x32), DW_OP_lit3(0x33), DW_OP_lit4(0x34), DW_OP_lit5(0x35), DW_OP_lit6(0x36), DW_OP_lit7(0x37), DW_OP_lit8(0x38), DW_OP_lit9(0x39), DW_OP_lit10(0x3a), DW_OP_lit11(0x3b), DW_OP_lit12(0x3c), DW_OP_lit13(0x3d), DW_OP_lit14(0x3e), DW_OP_lit15(0x3f), DW_OP_lit16(0x40), DW_OP_lit17(0x41), DW_OP_lit18(0x42), DW_OP_lit19(0x43), DW_OP_lit20(0x44), DW_OP_lit21(0x45), DW_OP_lit22(0x46), DW_OP_lit23(0x47), DW_OP_lit24(0x48), DW_OP_lit25(0x49), DW_OP_lit26(0x4a), DW_OP_lit27(0x4b), DW_OP_lit28(0x4c), DW_OP_lit29(0x4d), DW_OP_lit30(0x4e), DW_OP_lit31(0x4f), DW_OP_reg0(0x50), DW_OP_reg1(0x51), DW_OP_reg2(0x52), DW_OP_reg3(0x53), DW_OP_reg4(0x54), DW_OP_reg5(0x55), DW_OP_reg6(0x56), DW_OP_reg7(0x57), DW_OP_reg8(0x58), DW_OP_reg9(0x59), DW_OP_reg10(0x5a), DW_OP_reg11(0x5b), DW_OP_reg12(0x5c), DW_OP_reg13(0x5d), DW_OP_reg14(0x5e), DW_OP_reg15(0x5f), DW_OP_reg16(0x60), DW_OP_reg17(0x61), DW_OP_reg18(0x62), DW_OP_reg19(0x63), DW_OP_reg20(0x64), DW_OP_reg21(0x65), DW_OP_reg22(0x66), DW_OP_reg23(0x67), DW_OP_reg24(0x68), DW_OP_reg25(0x69), DW_OP_reg26(0x6a), DW_OP_reg27(0x6b), DW_OP_reg28(0x6c), DW_OP_reg29(0x6d), DW_OP_reg30(0x6e), DW_OP_reg31(0x6f), DW_OP_breg0(0x70), DW_OP_breg1(0x71), DW_OP_breg2(0x72), DW_OP_breg3(0x73), DW_OP_breg4(0x74), DW_OP_breg5(0x75), DW_OP_breg6(0x76), DW_OP_breg7(0x77), DW_OP_breg8(0x78), DW_OP_breg9(0x79), DW_OP_breg10(0x7a), DW_OP_breg11(0x7b), DW_OP_breg12(0x7c), DW_OP_breg13(0x7d), DW_OP_breg14(0x7e), DW_OP_breg15(0x7f), DW_OP_breg16(0x80), DW_OP_breg17(0x81), DW_OP_breg18(0x82), DW_OP_breg19(0x83), DW_OP_breg20(0x84), DW_OP_breg21(0x85), DW_OP_breg22(0x86), DW_OP_breg23(0x87), DW_OP_breg24(0x88), DW_OP_breg25(0x89), DW_OP_breg26(0x8a), DW_OP_breg27(0x8b), DW_OP_breg28(0x8c), DW_OP_breg29(0x8d), DW_OP_breg30(0x8e), DW_OP_breg31(0x8f), DW_OP_regx(0x90), DW_OP_fbreg(0x91), DW_OP_bregx(0x92), DW_OP_piece(0x93), DW_OP_deref_size(0x94), DW_OP_xderef_size(0x95), DW_OP_nop(0x96), DW_OP_push_object_address(0x97), DW_OP_call2(0x98), DW_OP_call4(0x99), DW_OP_call_ref(0x9a), DW_OP_form_tls_address(0x9b), DW_OP_call_frame_cfa(0x9c), DW_OP_bit_piece(0x9d), DW_OP_implicit_value(0x9e), DW_OP_stack_value(0x9f), DW_OP_GNU_push_tls_address(0xe0), DW_OP_GNU_addr_index(0xfb), DW_OP_GNU_const_index(0xfc), } internal enum class DwarfLanguage(val value:Int) { DW_LANG_C89(0x0001), DW_LANG_C(0x0002), DW_LANG_Ada83(0x0003), DW_LANG_C_plus_plus(0x0004), DW_LANG_Cobol74(0x0005), DW_LANG_Cobol85(0x0006), DW_LANG_Fortran77(0x0007), DW_LANG_Fortran90(0x0008), DW_LANG_Pascal83(0x0009), DW_LANG_Modula2(0x000a), DW_LANG_Java(0x000b), DW_LANG_C99(0x000c), DW_LANG_Ada95(0x000d), DW_LANG_Fortran95(0x000e), DW_LANG_PLI(0x000f), DW_LANG_ObjC(0x0010), DW_LANG_ObjC_plus_plus(0x0011), DW_LANG_UPC(0x0012), DW_LANG_D(0x0013), DW_LANG_Python(0x0014), DW_LANG_OpenCL(0x0015), DW_LANG_Go(0x0016), DW_LANG_Modula3(0x0017), DW_LANG_Haskell(0x0018), DW_LANG_C_plus_plus_03(0x0019), DW_LANG_C_plus_plus_11(0x001a), DW_LANG_OCaml(0x001b), DW_LANG_Rust(0x001c), DW_LANG_C11(0x001d), DW_LANG_Swift(0x001e), DW_LANG_Julia(0x001f), DW_LANG_Dylan(0x0020), DW_LANG_C_plus_plus_14(0x0021), DW_LANG_Fortran03(0x0022), DW_LANG_Fortran08(0x0023), DW_LANG_Mips_Assembler(0x8001), DW_LANG_GOOGLE_RenderScript(0x8e57), DW_LANG_BORLAND_Delphi(0xb000), DW_LANG_Kotlin(0x0026) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/EntryPoint.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.konan.target.CompilerOutputKind.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.isUnit internal fun findMainEntryPoint(context: Context): FunctionDescriptor? { val config = context.config.configuration if (config.get(KonanConfigKeys.PRODUCE) != PROGRAM) return null val entryPoint = FqName(config.get(KonanConfigKeys.ENTRY) ?: defaultEntryName(config)) val entryName = entryPoint.shortName() val packageName = entryPoint.parent() val packageScope = context.builtIns.builtInsModule.getPackage(packageName).memberScope val candidates = packageScope.getContributedFunctions(entryName, NoLookupLocation.FROM_BACKEND).filter { it.returnType?.isUnit() == true && it.typeParameters.isEmpty() && it.visibility.isPublicAPI } val main = candidates.singleOrNull { it.hasSingleArrayOfStringParameter } ?: candidates.singleOrNull { it.hasNoParameters } ?: context.reportCompilationError("Could not find '$entryName' in '$packageName' package.") if (main.isSuspend) context.reportCompilationError("Entry point can not be a suspend function.") return main } private fun defaultEntryName(config: CompilerConfiguration): String = when (config.get(KonanConfigKeys.GENERATE_TEST_RUNNER)) { TestRunnerKind.MAIN_THREAD -> "kotlin.native.internal.test.main" TestRunnerKind.WORKER -> "kotlin.native.internal.test.worker" TestRunnerKind.MAIN_THREAD_NO_EXIT -> "kotlin.native.internal.test.mainNoExit" else -> "main" } private val KotlinType.filterClass: ClassDescriptor? get() { val constr = constructor.declarationDescriptor return constr as? ClassDescriptor } private val ClassDescriptor.isString get() = fqNameSafe.asString() == "kotlin.String" private val KotlinType.isString get() = filterClass?.isString ?: false private val KotlinType.isArrayOfString: Boolean get() = (filterClass?.isArray ?: false) && (arguments.singleOrNull()?.type?.isString ?: false) private val FunctionDescriptor.hasSingleArrayOfStringParameter: Boolean get() = valueParameters.singleOrNull()?.type?.isArrayOfString ?: false private val FunctionDescriptor.hasNoParameters: Boolean get() = valueParameters.isEmpty() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import org.jetbrains.kotlin.backend.konan.hash.* internal fun localHash(data: ByteArray): Long { memScoped { val res = alloc() val bytes = allocArrayOf(data) MakeLocalHash(bytes, data.size, res.ptr) return res.value } } internal fun globalHash(data: ByteArray, retValPlacement: NativePlacement): GlobalHash { val res = retValPlacement.alloc() memScoped { val bytes = allocArrayOf(data) MakeGlobalHash(bytes, data.size, res.ptr) } return res } public fun base64Encode(data: ByteArray): String { memScoped { val resultSize = 4 * data.size / 3 + 3 + 1 val result = allocArray(resultSize) val bytes = allocArrayOf(data) EncodeBase64(bytes, data.size, result, resultSize) // TODO: any better way to do that without two copies? return result.toKString() } } public fun base64Decode(encoded: String): ByteArray { memScoped { val bufferSize: Int = 3 * encoded.length / 4 val result = allocArray(bufferSize) val resultSize = allocArray(1) resultSize[0] = bufferSize val errorCode = DecodeBase64(encoded, encoded.length, result, resultSize) if (errorCode != 0) throw Error("Non-zero exit code of DecodeBase64: ${errorCode}") val realSize = resultSize[0] return result.readBytes(realSize) } } internal class LocalHash(val value: Long) : ConstValue by Int64(value) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Imports.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.resolve.descriptorUtil.module internal interface LlvmImports { fun add(origin: CompiledKlibModuleOrigin, onlyBitcode: Boolean = false) fun bitcodeIsUsed(library: KonanLibrary): Boolean fun nativeDependenciesAreUsed(library: KonanLibrary): Boolean } internal val DeclarationDescriptor.llvmSymbolOrigin: CompiledKlibModuleOrigin get() { assert(!this.isExpectMember) { this } val module = this.module val moduleOrigin = module.klibModuleOrigin when (moduleOrigin) { is CompiledKlibModuleOrigin -> return moduleOrigin SyntheticModulesOrigin -> error("Declaration is synthetic and can't be an origin of LLVM symbol:\n${this}") } } internal val Context.standardLlvmSymbolsOrigin: CompiledKlibModuleOrigin get() = this.stdlibModule.llvmSymbolOrigin ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IntrinsicGenerator.kt ================================================ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.cValuesOf import llvm.* import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.backend.konan.descriptors.isTypedIntrinsic import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.findAnnotation import org.jetbrains.kotlin.ir.util.isSuspend internal enum class IntrinsicType { PLUS, MINUS, TIMES, SIGNED_DIV, SIGNED_REM, UNSIGNED_DIV, UNSIGNED_REM, INC, DEC, UNARY_PLUS, UNARY_MINUS, SHL, SHR, USHR, AND, OR, XOR, INV, SIGN_EXTEND, ZERO_EXTEND, INT_TRUNCATE, FLOAT_TRUNCATE, FLOAT_EXTEND, SIGNED_TO_FLOAT, UNSIGNED_TO_FLOAT, FLOAT_TO_SIGNED, SIGNED_COMPARE_TO, UNSIGNED_COMPARE_TO, NOT, REINTERPRET, EXTRACT_ELEMENT, ARE_EQUAL_BY_VALUE, IEEE_754_EQUALS, // OBJC OBJC_GET_MESSENGER, OBJC_GET_MESSENGER_STRET, OBJC_GET_OBJC_CLASS, OBJC_CREATE_SUPER_STRUCT, OBJC_INIT_BY, OBJC_GET_SELECTOR, // Other GET_CLASS_TYPE_INFO, CREATE_UNINITIALIZED_INSTANCE, LIST_OF_INTERNAL, IDENTITY, IMMUTABLE_BLOB, INIT_INSTANCE, // Enums ENUM_VALUES, ENUM_VALUE_OF, // Coroutines GET_CONTINUATION, RETURN_IF_SUSPENDED, COROUTINE_LAUNCHPAD, // Interop INTEROP_READ_BITS, INTEROP_WRITE_BITS, INTEROP_READ_PRIMITIVE, INTEROP_WRITE_PRIMITIVE, INTEROP_GET_POINTER_SIZE, INTEROP_NATIVE_PTR_TO_LONG, INTEROP_NATIVE_PTR_PLUS_LONG, INTEROP_GET_NATIVE_NULL_PTR, INTEROP_CONVERT, INTEROP_BITS_TO_FLOAT, INTEROP_BITS_TO_DOUBLE, INTEROP_SIGN_EXTEND, INTEROP_NARROW, INTEROP_STATIC_C_FUNCTION, INTEROP_FUNPTR_INVOKE, INTEROP_MEMORY_COPY, // Worker WORKER_EXECUTE } // Explicit and single interface between Intrinsic Generator and IrToBitcode. internal interface IntrinsicGeneratorEnvironment { val codegen: CodeGenerator val functionGenerationContext: FunctionGenerationContext val continuation: LLVMValueRef val exceptionHandler: ExceptionHandler val stackLocalsManager: StackLocalsManager fun calculateLifetime(element: IrElement): Lifetime fun evaluateCall(function: IrFunction, args: List, resultLifetime: Lifetime, superClass: IrClass? = null): LLVMValueRef fun evaluateExplicitArgs(expression: IrFunctionAccessExpression): List fun evaluateExpression(value: IrExpression): LLVMValueRef } internal fun tryGetIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicType? = if (callSite.symbol.owner.isTypedIntrinsic) getIntrinsicType(callSite) else null private fun getIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicType { val function = callSite.symbol.owner val annotation = function.annotations.findAnnotation(RuntimeNames.typedIntrinsicAnnotation)!! val value = annotation.getAnnotationStringValue()!! return IntrinsicType.valueOf(value) } internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnvironment) { private val codegen = environment.codegen private val context = codegen.context private val IrCall.llvmReturnType: LLVMTypeRef get() = LLVMGetReturnType(codegen.getLlvmFunctionType(symbol.owner))!! private fun LLVMTypeRef.sizeInBits() = LLVMSizeOfTypeInBits(codegen.llvmTargetData, this).toInt() /** * Some intrinsics have to be processed before evaluation of their arguments. * So this method looks at [callSite] and if it is call to "special" intrinsic * processes it. Otherwise it returns null. */ fun tryEvaluateSpecialCall(callSite: IrFunctionAccessExpression): LLVMValueRef? { val function = callSite.symbol.owner if (!function.isTypedIntrinsic) { return null } return when (getIntrinsicType(callSite)) { IntrinsicType.IMMUTABLE_BLOB -> { @Suppress("UNCHECKED_CAST") val arg = callSite.getValueArgument(0) as IrConst context.llvm.staticData.createImmutableBlob(arg) } IntrinsicType.OBJC_GET_SELECTOR -> { val selector = (callSite.getValueArgument(0) as IrConst<*>).value as String environment.functionGenerationContext.genObjCSelector(selector) } IntrinsicType.INIT_INSTANCE -> { val initializer = callSite.getValueArgument(1) as IrConstructorCall val thiz = environment.evaluateExpression(callSite.getValueArgument(0)!!) environment.evaluateCall( initializer.symbol.owner, listOf(thiz) + environment.evaluateExplicitArgs(initializer), environment.calculateLifetime(initializer) ) codegen.theUnitInstanceRef.llvm } IntrinsicType.COROUTINE_LAUNCHPAD -> { val suspendFunctionCall = callSite.getValueArgument(0) as IrCall val continuation = environment.evaluateExpression(callSite.getValueArgument(1)!!) val suspendFunction = suspendFunctionCall.symbol.owner assert(suspendFunction.isSuspend) { "Call to a suspend function expected but was ${suspendFunction.dump()}" } environment.evaluateCall(suspendFunction, environment.evaluateExplicitArgs(suspendFunctionCall) + listOf(continuation), environment.calculateLifetime(suspendFunctionCall), suspendFunction.parent as? IrClass // Call non-virtually. ) } else -> null } } fun evaluateCall(callSite: IrCall, args: List): LLVMValueRef = environment.functionGenerationContext.evaluateCall(callSite, args) // Assuming that we checked for `TypedIntrinsic` annotation presence. private fun FunctionGenerationContext.evaluateCall(callSite: IrCall, args: List): LLVMValueRef = when (val intrinsicType = getIntrinsicType(callSite)) { IntrinsicType.PLUS -> emitPlus(args) IntrinsicType.MINUS -> emitMinus(args) IntrinsicType.TIMES -> emitTimes(args) IntrinsicType.SIGNED_DIV -> emitSignedDiv(args) IntrinsicType.SIGNED_REM -> emitSignedRem(args) IntrinsicType.UNSIGNED_DIV -> emitUnsignedDiv(args) IntrinsicType.UNSIGNED_REM -> emitUnsignedRem(args) IntrinsicType.INC -> emitInc(args) IntrinsicType.DEC -> emitDec(args) IntrinsicType.UNARY_PLUS -> emitUnaryPlus(args) IntrinsicType.UNARY_MINUS -> emitUnaryMinus(args) IntrinsicType.SHL -> emitShl(args) IntrinsicType.SHR -> emitShr(args) IntrinsicType.USHR -> emitUshr(args) IntrinsicType.AND -> emitAnd(args) IntrinsicType.OR -> emitOr(args) IntrinsicType.XOR -> emitXor(args) IntrinsicType.INV -> emitInv(args) IntrinsicType.SIGNED_COMPARE_TO -> emitSignedCompareTo(args) IntrinsicType.UNSIGNED_COMPARE_TO -> emitUnsignedCompareTo(args) IntrinsicType.NOT -> emitNot(args) IntrinsicType.REINTERPRET -> emitReinterpret(callSite, args) IntrinsicType.EXTRACT_ELEMENT -> emitExtractElement(callSite, args) IntrinsicType.SIGN_EXTEND -> emitSignExtend(callSite, args) IntrinsicType.ZERO_EXTEND -> emitZeroExtend(callSite, args) IntrinsicType.INT_TRUNCATE -> emitIntTruncate(callSite, args) IntrinsicType.SIGNED_TO_FLOAT -> emitSignedToFloat(callSite, args) IntrinsicType.UNSIGNED_TO_FLOAT -> emitUnsignedToFloat(callSite, args) IntrinsicType.FLOAT_TO_SIGNED -> emitFloatToSigned(callSite, args) IntrinsicType.FLOAT_EXTEND -> emitFloatExtend(callSite, args) IntrinsicType.FLOAT_TRUNCATE -> emitFloatTruncate(callSite, args) IntrinsicType.ARE_EQUAL_BY_VALUE -> emitAreEqualByValue(args) IntrinsicType.IEEE_754_EQUALS -> emitIeee754Equals(args) IntrinsicType.OBJC_GET_MESSENGER -> emitObjCGetMessenger(args, isStret = false) IntrinsicType.OBJC_GET_MESSENGER_STRET -> emitObjCGetMessenger(args, isStret = true) IntrinsicType.OBJC_GET_OBJC_CLASS -> emitGetObjCClass(callSite) IntrinsicType.OBJC_CREATE_SUPER_STRUCT -> emitObjCCreateSuperStruct(args) IntrinsicType.GET_CLASS_TYPE_INFO -> emitGetClassTypeInfo(callSite) IntrinsicType.INTEROP_READ_BITS -> emitReadBits(args) IntrinsicType.INTEROP_WRITE_BITS -> emitWriteBits(args) IntrinsicType.INTEROP_READ_PRIMITIVE -> emitReadPrimitive(callSite, args) IntrinsicType.INTEROP_WRITE_PRIMITIVE -> emitWritePrimitive(callSite, args) IntrinsicType.INTEROP_GET_POINTER_SIZE -> emitGetPointerSize() IntrinsicType.CREATE_UNINITIALIZED_INSTANCE -> emitCreateUninitializedInstance(callSite) IntrinsicType.INTEROP_NATIVE_PTR_TO_LONG -> emitNativePtrToLong(callSite, args) IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG -> emitNativePtrPlusLong(args) IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR -> emitGetNativeNullPtr() IntrinsicType.LIST_OF_INTERNAL -> emitListOfInternal(callSite, args) IntrinsicType.IDENTITY -> emitIdentity(args) IntrinsicType.GET_CONTINUATION -> emitGetContinuation() IntrinsicType.INTEROP_MEMORY_COPY -> emitMemoryCopy(callSite, args) IntrinsicType.RETURN_IF_SUSPENDED, IntrinsicType.INTEROP_BITS_TO_FLOAT, IntrinsicType.INTEROP_BITS_TO_DOUBLE, IntrinsicType.INTEROP_SIGN_EXTEND, IntrinsicType.INTEROP_NARROW, IntrinsicType.INTEROP_STATIC_C_FUNCTION, IntrinsicType.INTEROP_FUNPTR_INVOKE, IntrinsicType.INTEROP_CONVERT, IntrinsicType.ENUM_VALUES, IntrinsicType.ENUM_VALUE_OF, IntrinsicType.WORKER_EXECUTE -> reportNonLoweredIntrinsic(intrinsicType) IntrinsicType.INIT_INSTANCE, IntrinsicType.OBJC_INIT_BY, IntrinsicType.COROUTINE_LAUNCHPAD, IntrinsicType.OBJC_GET_SELECTOR, IntrinsicType.IMMUTABLE_BLOB -> reportSpecialIntrinsic(intrinsicType) } private fun reportSpecialIntrinsic(intrinsicType: IntrinsicType): Nothing = context.reportCompilationError("$intrinsicType should be handled by `tryEvaluateSpecialCall`") private fun reportNonLoweredIntrinsic(intrinsicType: IntrinsicType): Nothing = context.reportCompilationError("Intrinsic of type $intrinsicType should be handled by previos lowering phase") private fun FunctionGenerationContext.emitGetContinuation(): LLVMValueRef = environment.continuation private fun FunctionGenerationContext.emitIdentity(args: List): LLVMValueRef = args.single() private fun FunctionGenerationContext.emitListOfInternal(callSite: IrCall, args: List): LLVMValueRef { val varargExpression = callSite.getValueArgument(0) as IrVararg val vararg = args.single() val length = varargExpression.elements.size // TODO: store length in `vararg` itself when more abstract types will be used for values. val array = constPointer(vararg) // Note: dirty hack here: `vararg` has type `Array`, but `createConstArrayList` expects `Array`; // however `vararg` is immutable, and in current implementation it has type `Array`, // so let's ignore this mismatch currently for simplicity. return context.llvm.staticData.createConstArrayList(array, length).llvm } private fun FunctionGenerationContext.emitGetNativeNullPtr(): LLVMValueRef = kNullInt8Ptr private fun FunctionGenerationContext.emitNativePtrPlusLong(args: List): LLVMValueRef = gep(args[0], args[1]) private fun FunctionGenerationContext.emitNativePtrToLong(callSite: IrCall, args: List): LLVMValueRef { val intPtrValue = ptrToInt(args.single(), codegen.intPtrType) val resultType = callSite.llvmReturnType return if (resultType == intPtrValue.type) { intPtrValue } else { LLVMBuildSExt(builder, intPtrValue, resultType, "")!! } } private fun FunctionGenerationContext.emitCreateUninitializedInstance(callSite: IrCall): LLVMValueRef { val typeParameterT = context.ir.symbols.createUninitializedInstance.descriptor.typeParameters[0] val enumClass = callSite.getTypeArgument(typeParameterT)!! val enumIrClass = enumClass.getClass()!! return allocInstance(enumIrClass, environment.calculateLifetime(callSite), environment.stackLocalsManager) } private fun FunctionGenerationContext.emitGetPointerSize(): LLVMValueRef = Int32(LLVMPointerSize(codegen.llvmTargetData)).llvm private fun FunctionGenerationContext.emitReadPrimitive(callSite: IrCall, args: List): LLVMValueRef { val pointerType = pointerType(callSite.llvmReturnType) val rawPointer = args.last() val pointer = bitcast(pointerType, rawPointer) return load(pointer) } private fun FunctionGenerationContext.emitWritePrimitive(callSite: IrCall, args: List): LLVMValueRef { val function = callSite.symbol.owner val pointerType = pointerType(codegen.getLLVMType(function.valueParameters.last().type)) val rawPointer = args[1] val pointer = bitcast(pointerType, rawPointer) store(args[2], pointer) return codegen.theUnitInstanceRef.llvm } private fun FunctionGenerationContext.emitReadBits(args: List): LLVMValueRef { val ptr = args[0] assert(ptr.type == int8TypePtr) val offset = extractConstUnsignedInt(args[1]) val size = extractConstUnsignedInt(args[2]).toInt() val signed = extractConstUnsignedInt(args[3]) != 0L val prefixBitsNum = (offset % 8).toInt() val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8 // Note: LLVM allows to read without padding tail up to byte boundary, but the result seems to be incorrect. val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!! val bitsWithPaddingPtr = bitcast(org.jetbrains.kotlin.backend.konan.llvm.pointerType(bitsWithPaddingType), gep(ptr, org.jetbrains.kotlin.backend.konan.llvm.Int64(offset / 8).llvm)) val bitsWithPadding = load(bitsWithPaddingPtr).setUnaligned() val bits = shr( shl(bitsWithPadding, suffixBitsNum), prefixBitsNum + suffixBitsNum, signed ) return when { bitsWithPaddingNum == 64 -> bits bitsWithPaddingNum > 64 -> trunc(bits, org.jetbrains.kotlin.backend.konan.llvm.int64Type) else -> ext(bits, org.jetbrains.kotlin.backend.konan.llvm.int64Type, signed) } } private fun FunctionGenerationContext.emitWriteBits(args: List): LLVMValueRef { val ptr = args[0] assert(ptr.type == int8TypePtr) val offset = extractConstUnsignedInt(args[1]) val size = extractConstUnsignedInt(args[2]).toInt() val value = args[3] assert(value.type == int64Type) val bitsType = LLVMIntTypeInContext(llvmContext, size)!! val prefixBitsNum = (offset % 8).toInt() val suffixBitsNum = (8 - ((size + offset) % 8).toInt()) % 8 val bitsWithPaddingNum = prefixBitsNum + size + suffixBitsNum val bitsWithPaddingType = LLVMIntTypeInContext(llvmContext, bitsWithPaddingNum)!! // 0011111000: val discardBitsMask = LLVMConstShl( LLVMConstZExt( LLVMConstAllOnes(bitsType), // 11111 bitsWithPaddingType ), // 1111100000 LLVMConstInt(bitsWithPaddingType, prefixBitsNum.toLong(), 0) ) val preservedBitsMask = LLVMConstNot(discardBitsMask)!! val bitsWithPaddingPtr = bitcast(pointerType(bitsWithPaddingType), gep(ptr, Int64(offset / 8).llvm)) val bits = trunc(value, bitsType) val bitsToStore = if (prefixBitsNum == 0 && suffixBitsNum == 0) { bits } else { val previousValue = load(bitsWithPaddingPtr).setUnaligned() val preservedBits = and(previousValue, preservedBitsMask) val bitsWithPadding = shl(zext(bits, bitsWithPaddingType), prefixBitsNum) or(bitsWithPadding, preservedBits) } llvm.LLVMBuildStore(builder, bitsToStore, bitsWithPaddingPtr)!!.setUnaligned() return codegen.theUnitInstanceRef.llvm } private fun FunctionGenerationContext.emitMemoryCopy(callSite: IrCall, args: List): LLVMValueRef { println("memcpy at ${callSite}") args.map { println(llvm2string(it)) } TODO("Implement me") } private fun FunctionGenerationContext.emitGetClassTypeInfo(callSite: IrCall): LLVMValueRef { val typeArgument = callSite.getTypeArgument(0)!! val typeArgumentClass = typeArgument.getClass() return if (typeArgumentClass == null) { // Should not happen anymore, but it is safer to handle this case. unreachable() kNullInt8Ptr } else { val typeInfo = codegen.typeInfoValue(typeArgumentClass) LLVMConstBitCast(typeInfo, kInt8Ptr)!! } } private fun FunctionGenerationContext.emitObjCCreateSuperStruct(args: List): LLVMValueRef { assert(args.size == 2) val receiver = args[0] val superClass = args[1] val structType = structType(kInt8Ptr, kInt8Ptr) val ptr = alloca(structType) store(receiver, LLVMBuildGEP(builder, ptr, cValuesOf(kImmZero, kImmZero), 2, "")!!) store(superClass, LLVMBuildGEP(builder, ptr, cValuesOf(kImmZero, kImmOne), 2, "")!!) return bitcast(int8TypePtr, ptr) } // TODO: Find better place for these guys. private val kImmZero = LLVMConstInt(int32Type, 0, 1)!! private val kImmOne = LLVMConstInt(int32Type, 1, 1)!! private fun FunctionGenerationContext.emitGetObjCClass(callSite: IrCall): LLVMValueRef { val typeArgument = callSite.getTypeArgument(0) return getObjCClass(typeArgument!!.getClass()!!, environment.exceptionHandler) } private fun FunctionGenerationContext.emitObjCGetMessenger(args: List, isStret: Boolean): LLVMValueRef { val messengerNameSuffix = if (isStret) "_stret" else "" val functionType = functionType(int8TypePtr, true, int8TypePtr, int8TypePtr) val libobjc = context.standardLlvmSymbolsOrigin val normalMessenger = context.llvm.externalFunction( "objc_msgSend$messengerNameSuffix", functionType, origin = libobjc ) val superMessenger = context.llvm.externalFunction( "objc_msgSendSuper$messengerNameSuffix", functionType, origin = libobjc ) val superClass = args.single() val messenger = LLVMBuildSelect(builder, If = icmpEq(superClass, kNullInt8Ptr), Then = normalMessenger, Else = superMessenger, Name = "" )!! return bitcast(int8TypePtr, messenger) } private fun FunctionGenerationContext.emitAreEqualByValue(args: List): LLVMValueRef { val (first, second) = args assert (first.type == second.type) { "Types are different: '${llvmtype2string(first.type)}' and '${llvmtype2string(second.type)}'" } return when (val typeKind = LLVMGetTypeKind(first.type)) { llvm.LLVMTypeKind.LLVMFloatTypeKind, llvm.LLVMTypeKind.LLVMDoubleTypeKind, LLVMTypeKind.LLVMVectorTypeKind -> { // TODO LLVM API does not provide guarantee for LLVMIntTypeInContext availability for longer types; consider meaningful diag message instead of NPE val integerType = LLVMIntTypeInContext(llvmContext, first.type.sizeInBits())!! icmpEq(bitcast(integerType, first), bitcast(integerType, second)) } llvm.LLVMTypeKind.LLVMIntegerTypeKind, llvm.LLVMTypeKind.LLVMPointerTypeKind -> icmpEq(first, second) else -> error(typeKind) } } private fun FunctionGenerationContext.emitIeee754Equals(args: List): LLVMValueRef { val (first, second) = args assert (first.type == second.type) { "Types are different: '${llvmtype2string(first.type)}' and '${llvmtype2string(second.type)}'" } val type = LLVMGetTypeKind(first.type) assert (type == LLVMTypeKind.LLVMFloatTypeKind || type == LLVMTypeKind.LLVMDoubleTypeKind) { "Should be of floating point kind, not: '${llvmtype2string(first.type)}'"} return fcmpEq(first, second) } private fun FunctionGenerationContext.emitReinterpret(callSite: IrCall, args: List) = bitcast(callSite.llvmReturnType, args[0]) private fun FunctionGenerationContext.emitExtractElement(callSite: IrCall, args: List): LLVMValueRef { val (vector, index) = args val elementSize = LLVMSizeOfTypeInBits(codegen.llvmTargetData, callSite.llvmReturnType).toInt() val vectorSize = LLVMSizeOfTypeInBits(codegen.llvmTargetData, vector.type).toInt() assert(callSite.llvmReturnType.isVectorElementType() && vectorSize % elementSize == 0 ) { "Invalid vector element type ${LLVMGetTypeKind(callSite.llvmReturnType)}"} val elementCount = vectorSize / elementSize emitThrowIfOOB(index, Int32((elementCount)).llvm) val targetType = LLVMVectorType(callSite.llvmReturnType, elementCount)!! return extractElement( (if (targetType == vector.type) vector else bitcast(targetType, vector)), index) } private fun FunctionGenerationContext.emitNot(args: List) = not(args[0]) private fun FunctionGenerationContext.emitPlus(args: List): LLVMValueRef { val (first, second) = args return if (first.type.isFloatingPoint()) { fadd(first, second) } else { add(first, second) } } private fun FunctionGenerationContext.emitSignExtend(callSite: IrCall, args: List) = sext(args[0], callSite.llvmReturnType) private fun FunctionGenerationContext.emitZeroExtend(callSite: IrCall, args: List) = zext(args[0], callSite.llvmReturnType) private fun FunctionGenerationContext.emitIntTruncate(callSite: IrCall, args: List) = trunc(args[0], callSite.llvmReturnType) private fun FunctionGenerationContext.emitSignedToFloat(callSite: IrCall, args: List) = LLVMBuildSIToFP(builder, args[0], callSite.llvmReturnType, "")!! private fun FunctionGenerationContext.emitUnsignedToFloat(callSite: IrCall, args: List) = LLVMBuildUIToFP(builder, args[0], callSite.llvmReturnType, "")!! private fun FunctionGenerationContext.emitFloatToSigned(callSite: IrCall, args: List) = LLVMBuildFPToSI(builder, args[0], callSite.llvmReturnType, "")!! private fun FunctionGenerationContext.emitFloatExtend(callSite: IrCall, args: List) = LLVMBuildFPExt(builder, args[0], callSite.llvmReturnType, "")!! private fun FunctionGenerationContext.emitFloatTruncate(callSite: IrCall, args: List) = LLVMBuildFPTrunc(builder, args[0], callSite.llvmReturnType, "")!! private fun FunctionGenerationContext.emitShift(op: LLVMOpcode, args: List): LLVMValueRef { val (first, second) = args val shift = if (first.type == int64Type) { val tmp = and(second, Int32(63).llvm) zext(tmp, int64Type) } else { and(second, Int32(31).llvm) } return LLVMBuildBinOp(builder, op, first, shift, "")!! } private fun FunctionGenerationContext.emitShl(args: List) = emitShift(LLVMOpcode.LLVMShl, args) private fun FunctionGenerationContext.emitShr(args: List) = emitShift(LLVMOpcode.LLVMAShr, args) private fun FunctionGenerationContext.emitUshr(args: List) = emitShift(LLVMOpcode.LLVMLShr, args) private fun FunctionGenerationContext.emitAnd(args: List): LLVMValueRef { val (first, second) = args return and(first, second) } private fun FunctionGenerationContext.emitOr(args: List): LLVMValueRef { val (first, second) = args return or(first, second) } private fun FunctionGenerationContext.emitXor(args: List): LLVMValueRef { val (first, second) = args return xor(first, second) } private fun FunctionGenerationContext.emitInv(args: List): LLVMValueRef { val first = args[0] val mask = makeConstOfType(first.type, -1) return xor(first, mask) } private fun FunctionGenerationContext.emitMinus(args: List): LLVMValueRef { val (first, second) = args return if (first.type.isFloatingPoint()) { fsub(first, second) } else { sub(first, second) } } private fun FunctionGenerationContext.emitTimes(args: List): LLVMValueRef { val (first, second) = args return if (first.type.isFloatingPoint()) { LLVMBuildFMul(builder, first, second, "") } else { LLVMBuildMul(builder, first, second, "") }!! } private fun FunctionGenerationContext.emitThrowIfZero(divider: LLVMValueRef) { ifThen(icmpEq(divider, Zero(divider.type).llvm)) { val throwArithExc = codegen.llvmFunction(context.ir.symbols.throwArithmeticException.owner) call(throwArithExc, emptyList(), Lifetime.GLOBAL, environment.exceptionHandler) unreachable() } } private fun FunctionGenerationContext.emitThrowIfOOB(index: LLVMValueRef, size: LLVMValueRef) { ifThen(icmpUGe(index, size)) { val throwIndexOutOfBoundsException = codegen.llvmFunction(context.ir.symbols.throwIndexOutOfBoundsException.owner) call(throwIndexOutOfBoundsException, emptyList(), Lifetime.GLOBAL, environment.exceptionHandler) unreachable() } } private fun FunctionGenerationContext.emitSignedDiv(args: List): LLVMValueRef { val (first, second) = args if (!second.type.isFloatingPoint()) { emitThrowIfZero(second) } return if (first.type.isFloatingPoint()) { LLVMBuildFDiv(builder, first, second, "") } else { LLVMBuildSDiv(builder, first, second, "") }!! } private fun FunctionGenerationContext.emitSignedRem(args: List): LLVMValueRef { val (first, second) = args if (!second.type.isFloatingPoint()) { emitThrowIfZero(second) } return if (first.type.isFloatingPoint()) { LLVMBuildFRem(builder, first, second, "") } else { LLVMBuildSRem(builder, first, second, "") }!! } private fun FunctionGenerationContext.emitUnsignedDiv(args: List): LLVMValueRef { val (first, second) = args emitThrowIfZero(second) return LLVMBuildUDiv(builder, first, second, "")!! } private fun FunctionGenerationContext.emitUnsignedRem(args: List): LLVMValueRef { val (first, second) = args emitThrowIfZero(second) return LLVMBuildURem(builder, first, second, "")!! } private fun FunctionGenerationContext.emitInc(args: List): LLVMValueRef { val first = args[0] val const1 = makeConstOfType(first.type, 1) return if (first.type.isFloatingPoint()) { fadd(first, const1) } else { add(first, const1) } } private fun FunctionGenerationContext.emitDec(args: List): LLVMValueRef { val first = args[0] val const1 = makeConstOfType(first.type, 1) return if (first.type.isFloatingPoint()) { fsub(first, const1) } else { sub(first, const1) } } private fun FunctionGenerationContext.emitUnaryPlus(args: List) = args[0] private fun FunctionGenerationContext.emitUnaryMinus(args: List): LLVMValueRef { val first = args[0] val destTy = first.type return if (destTy.isFloatingPoint()) { fneg(first) } else { val const0 = makeConstOfType(destTy, 0) sub(const0, first) } } private fun FunctionGenerationContext.emitCompareTo(args: List, signed: Boolean): LLVMValueRef { val (first, second) = args val equal = icmpEq(first, second) val less = if (signed) icmpLt(first, second) else icmpULt(first, second) val tmp = select(less, Int32(-1).llvm, Int32(1).llvm) return select(equal, Int32(0).llvm, tmp) } private fun FunctionGenerationContext.emitSignedCompareTo(args: List) = emitCompareTo(args, signed = true) private fun FunctionGenerationContext.emitUnsignedCompareTo(args: List) = emitCompareTo(args, signed = false) private fun makeConstOfType(type: LLVMTypeRef, value: Int): LLVMValueRef = when (type) { int8Type -> Int8(value.toByte()).llvm int16Type -> Char16(value.toChar()).llvm int32Type -> Int32(value).llvm int64Type -> Int64(value.toLong()).llvm floatType -> Float32(value.toFloat()).llvm doubleType -> Float64(value.toDouble()).llvm else -> context.reportCompilationError("Unexpected primitive type: $type") } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.ir.allParametersCount import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.konan.ForeignExceptionMode import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.classId internal enum class FieldStorageKind { GLOBAL, // In the old memory model these are only accessible from the "main" thread. SHARED_FROZEN, THREAD_LOCAL } internal enum class ObjectStorageKind { PERMANENT, THREAD_LOCAL, SHARED } // TODO: maybe unannotated singleton objects shall be accessed from main thread only as well? internal val IrField.storageKind: FieldStorageKind get() { // TODO: Is this correct? val annotations = correspondingPropertySymbol?.owner?.annotations ?: annotations return when { annotations.hasAnnotation(KonanFqNames.threadLocal) -> FieldStorageKind.THREAD_LOCAL !isFinal -> FieldStorageKind.GLOBAL annotations.hasAnnotation(KonanFqNames.sharedImmutable) -> FieldStorageKind.SHARED_FROZEN // TODO: simplify, once IR types are fully there. (type.classifierOrNull?.owner as? IrAnnotationContainer) ?.annotations?.hasAnnotation(KonanFqNames.frozen) == true -> FieldStorageKind.SHARED_FROZEN else -> FieldStorageKind.GLOBAL } } internal fun IrClass.storageKind(context: Context): ObjectStorageKind = when { this.annotations.hasAnnotation(KonanFqNames.threadLocal) && context.config.threadsAreAllowed -> ObjectStorageKind.THREAD_LOCAL this.hasConstStateAndNoSideEffects(context) -> ObjectStorageKind.PERMANENT else -> ObjectStorageKind.SHARED } val IrField.isGlobalNonPrimitive get() = when { type.computePrimitiveBinaryTypeOrNull() != null -> false else -> storageKind == FieldStorageKind.GLOBAL } internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid { val generator = RTTIGenerator(context) val kotlinObjCClassInfoGenerator = KotlinObjCClassInfoGenerator(context) override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { super.visitClass(declaration) if (declaration.requiresRtti()) { generator.generate(declaration) } if (declaration.isKotlinObjCClass()) { kotlinObjCClassInfoGenerator.generate(declaration) } } fun dispose() { generator.dispose() } } //-------------------------------------------------------------------------// /** * Defines how to generate context-dependent operations. */ internal interface CodeContext { /** * Generates `return` [value] operation. * * @param value may be null iff target type is `Unit`. */ fun genReturn(target: IrSymbolOwner, value: LLVMValueRef?) fun genBreak(destination: IrBreak) fun genContinue(destination: IrContinue) val exceptionHandler: ExceptionHandler fun genThrow(exception: LLVMValueRef) val stackLocalsManager: StackLocalsManager /** * Declares the variable. * @return index of declared variable. */ fun genDeclareVariable(variable: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int /** * @return index of value declared before, or -1 if no such variable has been declared yet. */ fun getDeclaredValue(value: IrValueDeclaration): Int /** * Generates the code to obtain a value available in this context. * * @return the requested value */ fun genGetValue(value: IrValueDeclaration): LLVMValueRef /** * Returns owning function scope. * * @return the requested value */ fun functionScope(): CodeContext? /** * Returns owning file scope. * * @return the requested value if in the file scope or null. */ fun fileScope(): CodeContext? /** * Returns owning class scope [ClassScope]. * * @returns the requested value if in the class scope or null. */ fun classScope(): CodeContext? fun addResumePoint(bbLabel: LLVMBasicBlockRef): Int /** * Returns owning returnable block scope [ReturnableBlockScope]. * * @returns the requested value if in the returnableBlockScope scope or null. */ fun returnableBlockScope(): CodeContext? /** * Returns location information for given source location [LocationInfo]. */ fun location(offset: Int): LocationInfo? /** * Returns [DIScopeOpaqueRef] instance for corresponding scope. */ fun scope(): DIScopeOpaqueRef? } //-------------------------------------------------------------------------// internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) : IrElementVisitorVoid { val codegen = CodeGenerator(context) // TODO: consider eliminating mutable state private var currentCodeContext: CodeContext = TopLevelCodeContext private val intrinsicGeneratorEnvironment = object : IntrinsicGeneratorEnvironment { override val codegen: CodeGenerator get() = this@CodeGeneratorVisitor.codegen override val functionGenerationContext: FunctionGenerationContext get() = this@CodeGeneratorVisitor.functionGenerationContext override fun calculateLifetime(element: IrElement): Lifetime = resultLifetime(element) override val continuation: LLVMValueRef get() = getContinuation() override val exceptionHandler: ExceptionHandler get() = currentCodeContext.exceptionHandler override val stackLocalsManager: StackLocalsManager get() = currentCodeContext.stackLocalsManager override fun evaluateCall(function: IrFunction, args: List, resultLifetime: Lifetime, superClass: IrClass?) = evaluateSimpleFunctionCall(function, args, resultLifetime, superClass) override fun evaluateExplicitArgs(expression: IrFunctionAccessExpression): List = this@CodeGeneratorVisitor.evaluateExplicitArgs(expression) override fun evaluateExpression(value: IrExpression): LLVMValueRef = this@CodeGeneratorVisitor.evaluateExpression(value) } private val intrinsicGenerator = IntrinsicGenerator(intrinsicGeneratorEnvironment) /** * Fake [CodeContext] that doesn't support any operation. * * During function code generation [FunctionScope] should be set up. */ private object TopLevelCodeContext : CodeContext { private fun unsupported(any: Any? = null): Nothing = throw UnsupportedOperationException(any?.toString() ?: "") override fun genReturn(target: IrSymbolOwner, value: LLVMValueRef?) = unsupported(target) override fun genBreak(destination: IrBreak) = unsupported() override fun genContinue(destination: IrContinue) = unsupported() override val exceptionHandler get() = unsupported() override fun genThrow(exception: LLVMValueRef) = unsupported() override val stackLocalsManager: StackLocalsManager get() = unsupported() override fun genDeclareVariable(variable: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?) = unsupported(variable) override fun getDeclaredValue(value: IrValueDeclaration) = -1 override fun genGetValue(value: IrValueDeclaration) = unsupported(value) override fun functionScope(): CodeContext? = null override fun fileScope(): CodeContext? = null override fun classScope(): CodeContext? = null override fun addResumePoint(bbLabel: LLVMBasicBlockRef) = unsupported(bbLabel) override fun returnableBlockScope(): CodeContext? = null override fun location(offset: Int): LocationInfo? = unsupported() override fun scope(): DIScopeOpaqueRef? = unsupported() } /** * The [CodeContext] which can define some operations and delegate other ones to [outerContext] */ private abstract class InnerScope(val outerContext: CodeContext) : CodeContext by outerContext /** * Convenient [InnerScope] implementation that is bound to the [currentCodeContext]. */ private abstract inner class InnerScopeImpl : InnerScope(currentCodeContext) /** * Executes [block] with [codeContext] substituted as [currentCodeContext]. */ private inline fun using(codeContext: CodeContext?, block: () -> R): R { val oldCodeContext = currentCodeContext if (codeContext != null) { currentCodeContext = codeContext } try { return block() } finally { currentCodeContext = oldCodeContext } } private fun findCodeContext(entry: T, context:CodeContext?, predicate: CodeContext.(T) -> Boolean): CodeContext? { if(context == null) //TODO: replace `return null` with `throw NoContextFound()` ASAP. return null if (context.predicate(entry)) return context return findCodeContext(entry, (context as? InnerScope)?.outerContext, predicate) } private inline fun switchSymbolizationContextTo(symbol: IrFunctionSymbol, block: () -> R): R? { val functionContext = findCodeContext(symbol.owner, currentCodeContext) { val declaration = (this as? FunctionScope)?.declaration val returnableBlock = (this as? ReturnableBlockScope)?.returnableBlock val inlinedFunction = returnableBlock?.inlineFunctionSymbol?.owner declaration == it || inlinedFunction == it } ?: return null /** * We can't switch context safely, only for symbolzation needs: location, scope detection. */ using(object: InnerScopeImpl() { override fun location(offset: Int): LocationInfo? = functionContext.location(offset) override fun scope(): DIScopeOpaqueRef? = functionContext.scope() }) { return block() } } private fun appendCAdapters() { context.cAdapterGenerator.generateBindings(codegen) } private fun runAndProcessInitializers(konanLibrary: KotlinLibrary?, f: () -> Unit) { // TODO: collect those two in one place. context.llvm.fileInitializers.clear() context.llvm.fileUsesThreadLocalObjects = false context.llvm.globalSharedObjects.clear() f() if (context.llvm.fileInitializers.isEmpty() && !context.llvm.fileUsesThreadLocalObjects && context.llvm.globalSharedObjects.isEmpty()) { return } // Create global initialization records. val initNode = createInitNode(createInitBody()) context.llvm.irStaticInitializers.add(IrStaticInitializer(konanLibrary, createInitCtor(initNode))) } //-------------------------------------------------------------------------// override fun visitElement(element: IrElement) { TODO(ir2string(element)) } //-------------------------------------------------------------------------// override fun visitModuleFragment(declaration: IrModuleFragment) { context.log{"visitModule : ${ir2string(declaration)}"} context.coverage.collectRegions(declaration) initializeCachedBoxes(context) declaration.acceptChildrenVoid(this) runAndProcessInitializers(null) { // Note: it is here because it also generates some bitcode. context.objCExport.generate(codegen) codegen.objCDataGenerator?.finishModule() context.coverage.writeRegionInfo() appendDebugSelector() overrideRuntimeGlobals() appendLlvmUsed("llvm.used", context.llvm.usedFunctions + context.llvm.usedGlobals) appendLlvmUsed("llvm.compiler.used", context.llvm.compilerUsedGlobals) if (context.isNativeLibrary) { appendCAdapters() } } appendStaticInitializers() } //-------------------------------------------------------------------------// val kVoidFuncType = functionType(voidType) val kNodeInitType = LLVMGetTypeByName(context.llvmModule, "struct.InitNode")!! val kMemoryStateType = LLVMGetTypeByName(context.llvmModule, "struct.MemoryState")!! val kInitFuncType = functionType(voidType, false, int32Type, pointerType(kMemoryStateType)) //-------------------------------------------------------------------------// // Must be synchronized with Runtime.cpp val ALLOC_THREAD_LOCAL_GLOBALS = 0 val INIT_GLOBALS = 1 val INIT_THREAD_LOCAL_GLOBALS = 2 val DEINIT_GLOBALS = 3 private fun createInitBody(): LLVMValueRef { val initFunction = addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, "", kInitFuncType ) LLVMSetLinkage(initFunction, LLVMLinkage.LLVMPrivateLinkage) generateFunction(codegen, initFunction) { using(FunctionScope(initFunction, "init_body", it)) { val bbInit = basicBlock("init", null) val bbLocalInit = basicBlock("local_init", null) val bbLocalAlloc = basicBlock("local_alloc", null) val bbGlobalDeinit = basicBlock("global_deinit", null) val bbDefault = basicBlock("default", null) { unreachable() } switch(LLVMGetParam(initFunction, 0)!!, listOf(Int32(INIT_GLOBALS).llvm to bbInit, Int32(INIT_THREAD_LOCAL_GLOBALS).llvm to bbLocalInit, Int32(ALLOC_THREAD_LOCAL_GLOBALS).llvm to bbLocalAlloc, Int32(DEINIT_GLOBALS).llvm to bbGlobalDeinit), bbDefault) // Globals initalizers may contain accesses to objects, so visit them first. appendingTo(bbInit) { context.llvm.fileInitializers .forEach { irField -> if (irField.storageKind != FieldStorageKind.THREAD_LOCAL) { val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( functionGenerationContext ) val initialValue = if (irField.initializer?.expression !is IrConst<*>?) { val initialization = evaluateExpression(irField.initializer!!.expression) if (irField.storageKind == FieldStorageKind.SHARED_FROZEN) freeze(initialization, currentCodeContext.exceptionHandler) initialization } else { null } val needRegistration = context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM irField.type.binaryTypeIsReference() && // only for references (initialValue != null || // which are initialized from heap object !irField.isFinal) // or are not final if (needRegistration) { call(context.llvm.initAndRegisterGlobalFunction, listOf(address, initialValue ?: kNullObjHeaderPtr)) } else if (initialValue != null) { storeAny(initialValue, address, false) } } } ret(null) } appendingTo(bbLocalInit) { context.llvm.fileInitializers .forEach { irField -> if (irField.initializer != null && irField.storageKind == FieldStorageKind.THREAD_LOCAL) { val initialization = evaluateExpression(irField.initializer!!.expression) val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( functionGenerationContext ) storeAny(initialization, address, false) } } ret(null) } appendingTo(bbLocalAlloc) { if (context.llvm.tlsCount > 0) { val memory = LLVMGetParam(initFunction, 1)!! call(context.llvm.addTLSRecord, listOf(memory, context.llvm.tlsKey, Int32(context.llvm.tlsCount).llvm)) } ret(null) } appendingTo(bbGlobalDeinit) { context.llvm.fileInitializers // Only if a subject for memory management. .forEach {irField -> if (irField.type.binaryTypeIsReference() && irField.storageKind != FieldStorageKind.THREAD_LOCAL) { val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress( functionGenerationContext ) storeHeapRef(codegen.kNullObjHeaderPtr, address) } } context.llvm.globalSharedObjects.forEach { address -> storeHeapRef(codegen.kNullObjHeaderPtr, address) } ret(null) } } } return initFunction } //-------------------------------------------------------------------------// // Creates static struct InitNode $nodeName = {$initName, NULL}; private fun createInitNode(initFunction: LLVMValueRef): LLVMValueRef { val nextInitNode = LLVMConstNull(pointerType(kNodeInitType)) val argList = cValuesOf(initFunction, nextInitNode) // Create static object of class InitNode. val initNode = LLVMConstNamedStruct(kNodeInitType, argList, 2)!! // Create global variable with init record data. return context.llvm.staticData.placeGlobal( "init_node", constPointer(initNode), isExported = false).llvmGlobal } //-------------------------------------------------------------------------// private fun createInitCtor(initNodePtr: LLVMValueRef): LLVMValueRef { val ctorFunction = generateFunctionNoRuntime(codegen, kVoidFuncType, "") { call(context.llvm.appendToInitalizersTail, listOf(initNodePtr)) ret(null) } LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMPrivateLinkage) return ctorFunction } //-------------------------------------------------------------------------// override fun visitFile(declaration: IrFile) { @Suppress("UNCHECKED_CAST") using(FileScope(declaration)) { runAndProcessInitializers(declaration.konanLibrary) { declaration.acceptChildrenVoid(this) } } } //-------------------------------------------------------------------------// private inner class LoopScope(val loop: IrLoop) : InnerScopeImpl() { val loopExit = functionGenerationContext.basicBlock("loop_exit", loop.endLocation) val loopCheck = functionGenerationContext.basicBlock("loop_check", loop.condition.startLocation) override fun genBreak(destination: IrBreak) { if (destination.loop == loop) functionGenerationContext.br(loopExit) else super.genBreak(destination) } override fun genContinue(destination: IrContinue) { if (destination.loop == loop) { functionGenerationContext.br(loopCheck) } else super.genContinue(destination) } override val stackLocalsManager: StackLocalsManager = object : StackLocalsManager by functionGenerationContext.stackLocalsManager { } } //-------------------------------------------------------------------------// fun evaluateBreak(destination: IrBreak): LLVMValueRef { currentCodeContext.genBreak(destination) return codegen.kNothingFakeValue } //-------------------------------------------------------------------------// fun evaluateContinue(destination: IrContinue): LLVMValueRef { currentCodeContext.genContinue(destination) return codegen.kNothingFakeValue } //-------------------------------------------------------------------------// override fun visitConstructor(declaration: IrConstructor) { context.log{"visitConstructor : ${ir2string(declaration)}"} if (declaration.constructedClass.isInlined()) { // Do not generate any ctors for value types. return } if (declaration.isObjCConstructor) { // Do not generate any ctors for external Objective-C classes. return } visitFunction(declaration) } //-------------------------------------------------------------------------// override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { context.log{"visitAnonymousInitializer : ${ir2string(declaration)}"} } //-------------------------------------------------------------------------// /** * The scope of variable visibility. */ private inner class VariableScope : InnerScopeImpl() { override fun genDeclareVariable(variable: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int { return functionGenerationContext.vars.createVariable(variable, value, variableLocation) } override fun getDeclaredValue(value: IrValueDeclaration): Int { val index = functionGenerationContext.vars.indexOf(value) return if (index < 0) super.getDeclaredValue(value) else index } override fun genGetValue(value: IrValueDeclaration): LLVMValueRef { val index = functionGenerationContext.vars.indexOf(value) if (index < 0) { return super.genGetValue(value) } else { return functionGenerationContext.vars.load(index) } } } /** * The scope of parameter visibility. */ private open inner class ParameterScope( function: IrFunction?, private val functionGenerationContext: FunctionGenerationContext): InnerScopeImpl() { val parameters = bindParameters(function) init { if (function != null) { parameters.forEach{ val parameter = it.key val local = functionGenerationContext.vars.createParameter( parameter, debugInfoIfNeeded(function, parameter)) functionGenerationContext.mapParameterForDebug(local, it.value) } } } override fun genGetValue(value: IrValueDeclaration): LLVMValueRef { val index = functionGenerationContext.vars.indexOf(value) if (index < 0) { return super.genGetValue(value) } else { return functionGenerationContext.vars.load(index) } } } /** * The [CodeContext] enclosing the entire function body. */ private inner class FunctionScope(val declaration: IrFunction?, val functionGenerationContext: FunctionGenerationContext) : InnerScopeImpl() { constructor(llvmFunction:LLVMValueRef, name:String, functionGenerationContext: FunctionGenerationContext): this(null, functionGenerationContext) { this.llvmFunction = llvmFunction this.name = name } var llvmFunction: LLVMValueRef? = declaration?.let{ codegen.llvmFunction(it) } val coverageInstrumentation: LLVMCoverageInstrumentation? = context.coverage.tryGetInstrumentation(declaration) { function, args -> functionGenerationContext.call(function, args) } private var name:String? = declaration?.name?.asString() override fun genReturn(target: IrSymbolOwner, value: LLVMValueRef?) { if (declaration == null || target == declaration) { if ((target as IrFunction).returnsUnit()) { functionGenerationContext.ret(null) } else { functionGenerationContext.ret(value!!) } } else { super.genReturn(target, value) } } override val exceptionHandler get() = ExceptionHandler.Caller override fun genThrow(exception: LLVMValueRef) { val objHeaderPtr = functionGenerationContext.bitcast(codegen.kObjHeaderPtr, exception) val args = listOf(objHeaderPtr) functionGenerationContext.call( context.llvm.throwExceptionFunction, args, Lifetime.IRRELEVANT, this.exceptionHandler ) functionGenerationContext.unreachable() } override val stackLocalsManager get() = functionGenerationContext.stackLocalsManager override fun functionScope(): CodeContext = this private val scope by lazy { if (!context.shouldContainLocationDebugInfo()) return@lazy null declaration?.scope() ?: llvmFunction!!.scope(0, subroutineType(context, codegen.llvmTargetData, listOf(context.irBuiltIns.intType))) } private val fileScope = (fileScope() as? FileScope) override fun location(offset: Int) = scope?.let { scope -> fileScope?.let{LocationInfo(scope, it.file.fileEntry.line(offset), it.file.fileEntry.column(offset)) } } override fun scope() = scope } private val functionGenerationContext get() = (currentCodeContext.functionScope() as FunctionScope).functionGenerationContext /** * Binds LLVM function parameters to IR parameter descriptors. */ private fun bindParameters(function: IrFunction?): Map { if (function == null) return emptyMap() return function.allParameters.mapIndexed { i, irParameter -> val parameter = codegen.param(function, i) assert(codegen.getLLVMType(irParameter.type) == parameter.type) irParameter to parameter }.toMap() } override fun visitFunction(declaration: IrFunction) { context.log{"visitFunction : ${ir2string(declaration)}"} val body = declaration.body if ((declaration as? IrSimpleFunction)?.modality == Modality.ABSTRACT || declaration.isExternal || body == null) return val isNotInlinedLambda = declaration.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA val file = ((declaration as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.file.takeIf { it ?: return@takeIf false (currentCodeContext.fileScope() as FileScope).file != it && isNotInlinedLambda } val scope = file?.let { FileScope(it) } using(scope) { generateFunction(codegen, declaration, declaration.location(start = true), declaration.location(start = false)) { using(FunctionScope(declaration, it)) { val parameterScope = ParameterScope(declaration, functionGenerationContext) using(parameterScope) usingParameterScope@{ using(VariableScope()) usingVariableScope@{ recordCoverage(body) if (declaration.isReifiedInline) { callDirect(context.ir.symbols.throwIllegalStateExceptionWithMessage.owner, listOf(context.llvm.staticData.kotlinStringLiteral( "unsupported call of reified inlined function `${declaration.fqNameForIrSerialization}`").llvm), Lifetime.IRRELEVANT) return@usingVariableScope } when (body) { is IrBlockBody -> body.statements.forEach { generateStatement(it) } is IrExpressionBody -> error("IrExpressionBody should've been lowered") is IrSyntheticBody -> throw AssertionError("Synthetic body ${body.kind} has not been lowered") else -> TODO(ir2string(body)) } } } } } } if (declaration.retainAnnotation(context.config.target)) { context.llvm.usedFunctions.add(codegen.llvmFunction(declaration)) } if (context.shouldVerifyBitCode()) verifyModule(context.llvmModule!!, "${declaration.descriptor.containingDeclaration}::${ir2string(declaration)}") } private fun IrFunction.location(start: Boolean) = if (context.shouldContainLocationDebugInfo() && startOffset != UNDEFINED_OFFSET) LocationInfo( scope = scope()!!, line = if (start) startLine() else endLine(), column = if (start) startColumn() else endColumn()) else null //-------------------------------------------------------------------------// override fun visitClass(declaration: IrClass) { context.log{"visitClass : ${ir2string(declaration)}"} if (declaration.isNonGeneratedAnnotation() || !declaration.requiresCodeGeneration()) { // For non-generated annotation classes generate only nested classes. declaration.declarations .filterIsInstance() .forEach { it.acceptVoid(this) } return } using(ClassScope(declaration)) { declaration.declarations.forEach { it.acceptVoid(this) } } if (declaration.kind.isSingleton && !declaration.isUnit()) { val singleton = context.llvmDeclarations.forSingleton(declaration) val access = singleton.instanceStorage if (access is GlobalAddressAccess) { // Global objects are kept in a data segment and can be accessed by any module (if exported) and also // they need to be initialized statically. LLVMSetInitializer(access.getAddress(null), if (declaration.storageKind(context) == ObjectStorageKind.PERMANENT) context.llvm.staticData.createConstKotlinObject(declaration, *computeFields(declaration)).llvm else codegen.kNullObjHeaderPtr) } else { // Thread local objects are kept in a special map, so they need a getter function to be accessible // by other modules. val isObjCCompanion = declaration.isCompanion && declaration.parentAsClass.isObjCClass() // If can be exported and can be instantiated. if (declaration.isExported() && !isObjCCompanion && declaration.constructors.singleOrNull() { it.valueParameters.size == 0 } != null) { val valueGetterName = declaration.threadLocalObjectStorageGetterSymbolName generateFunction(codegen, functionType(codegen.kObjHeaderPtrPtr, false), valueGetterName) { val value = access.getAddress(this) ret(value) } // Getter uses TLS object, so need to ensure that this file's (de)initializer function // inits and deinits TLS. context.llvm.fileUsesThreadLocalObjects = true } } } } private fun computeFields(declaration: IrClass): Array { val fields = context.getLayoutBuilder(declaration).fields return Array(fields.size) { index -> val initializer = fields[index].initializer!!.expression as IrConst<*> constValue(evaluateConst(initializer)) } } override fun visitProperty(declaration: IrProperty) { declaration.getter?.acceptVoid(this) declaration.setter?.acceptVoid(this) declaration.backingField?.acceptVoid(this) } //-------------------------------------------------------------------------// override fun visitField(declaration: IrField) { context.log{"visitField : ${ir2string(declaration)}"} debugFieldDeclaration(declaration) if (context.needGlobalInit(declaration)) { val type = codegen.getLLVMType(declaration.type) val globalPropertyAccess = context.llvmDeclarations.forStaticField(declaration).storageAddressAccess val initializer = declaration.initializer?.expression as? IrConst<*> val globalProperty = (globalPropertyAccess as? GlobalAddressAccess)?.getAddress(null) if (globalProperty != null) { LLVMSetInitializer(globalProperty, if (initializer != null) evaluateExpression(initializer) else LLVMConstNull(type)) // (Cannot do this before the global is initialized). LLVMSetLinkage(globalProperty, LLVMLinkage.LLVMInternalLinkage) } context.llvm.fileInitializers.add(declaration) } } private fun recordCoverage(irElement: IrElement) { val scope = currentCodeContext.functionScope() if (scope is FunctionScope) { scope.coverageInstrumentation?.instrumentIrElement(irElement) } } //-------------------------------------------------------------------------// private fun evaluateExpression(value: IrExpression): LLVMValueRef { updateBuilderDebugLocation(value) recordCoverage(value) when (value) { is IrTypeOperatorCall -> return evaluateTypeOperator (value) is IrCall -> return evaluateCall (value) is IrDelegatingConstructorCall -> return evaluateCall (value) is IrConstructorCall -> return evaluateCall (value) is IrInstanceInitializerCall -> return evaluateInstanceInitializerCall(value) is IrGetValue -> return evaluateGetValue (value) is IrSetValue -> return evaluateSetValue (value) is IrGetField -> return evaluateGetField (value) is IrSetField -> return evaluateSetField (value) is IrConst<*> -> return evaluateConst (value) is IrReturn -> return evaluateReturn (value) is IrWhen -> return evaluateWhen (value) is IrThrow -> return evaluateThrow (value) is IrTry -> return evaluateTry (value) is IrReturnableBlock -> return evaluateReturnableBlock (value) is IrContainerExpression -> return evaluateContainerExpression (value) is IrWhileLoop -> return evaluateWhileLoop (value) is IrDoWhileLoop -> return evaluateDoWhileLoop (value) is IrVararg -> return evaluateVararg (value) is IrBreak -> return evaluateBreak (value) is IrContinue -> return evaluateContinue (value) is IrGetObjectValue -> return evaluateGetObjectValue (value) is IrFunctionReference -> return evaluateFunctionReference (value) is IrSuspendableExpression -> return evaluateSuspendableExpression (value) is IrSuspensionPoint -> return evaluateSuspensionPoint (value) is IrClassReference -> return evaluateClassReference (value) else -> { TODO(ir2string(value)) } } } private fun generateStatement(statement: IrStatement) { when (statement) { is IrExpression -> evaluateExpression(statement) is IrVariable -> generateVariable(statement) else -> TODO(ir2string(statement)) } } private fun IrStatement.generate() = generateStatement(this) //-------------------------------------------------------------------------// private fun evaluateGetObjectValue(value: IrGetObjectValue): LLVMValueRef = functionGenerationContext.getObjectValue( value.symbol.owner, currentCodeContext.exceptionHandler, value.startLocation, value.endLocation ) //-------------------------------------------------------------------------// private fun evaluateExpressionAndJump(expression: IrExpression, destination: ContinuationBlock) { val result = evaluateExpression(expression) // It is possible to check here whether the generated code has the normal continuation path // and do not generate any jump if not; // however such optimization can lead to phi functions with zero entries, which is not allowed by LLVM; // TODO: find the better solution. jump(destination, result) } //-------------------------------------------------------------------------// /** * Represents the basic block which may expect a value: * when generating a [jump] to this block, one should provide the value. * Inside the block that value is accessible as [valuePhi]. * * This class is designed to be used to generate Kotlin expressions that have a value and require branching. * * [valuePhi] may be `null`, which would mean `Unit` value is passed. */ private data class ContinuationBlock(val block: LLVMBasicBlockRef, val valuePhi: LLVMValueRef?) private val ContinuationBlock.value: LLVMValueRef get() = this.valuePhi ?: codegen.theUnitInstanceRef.llvm /** * Jumps to [target] passing [value]. */ private fun jump(target: ContinuationBlock, value: LLVMValueRef?) { val entry = target.block functionGenerationContext.br(entry) if (target.valuePhi != null) { functionGenerationContext.assignPhis(target.valuePhi to value!!) } } /** * Creates new [ContinuationBlock] that receives the value of given Kotlin type * and generates [code] starting from its beginning. */ private fun continuationBlock( type: IrType, locationInfo: LocationInfo?, code: (ContinuationBlock) -> Unit = {}): ContinuationBlock { val entry = functionGenerationContext.basicBlock("continuation_block", locationInfo) functionGenerationContext.appendingTo(entry) { val valuePhi = if (type.isUnit()) { null } else { functionGenerationContext.phi(codegen.getLLVMType(type)) } val result = ContinuationBlock(entry, valuePhi) code(result) return result } } //-------------------------------------------------------------------------// private fun evaluateVararg(value: IrVararg): LLVMValueRef { val elements = value.elements.map { if (it is IrExpression) { val mapped = evaluateExpression(it) if (mapped.isConst) { return@map mapped } } throw IllegalStateException("IrVararg neither was lowered nor can be statically evaluated") } val arrayClass = value.type.getClass()!! // Note: even if all elements are const, they aren't guaranteed to be statically initialized. // E.g. an element may be a pointer to lazy-initialized object (aka singleton). // However it is guaranteed that all elements are already initialized at this point. return codegen.staticData.createConstKotlinArray(arrayClass, elements) } //-------------------------------------------------------------------------// private fun evaluateThrow(expression: IrThrow): LLVMValueRef { val exception = evaluateExpression(expression.value) currentCodeContext.genThrow(exception) return codegen.kNothingFakeValue } //-------------------------------------------------------------------------// /** * The [CodeContext] that catches exceptions. */ private inner abstract class CatchingScope : InnerScopeImpl() { /** * The LLVM `landingpad` such that if invoked function throws an exception, * then this exception is passed to [handler]. */ private val landingpad: LLVMBasicBlockRef by lazy { using(outerContext) { functionGenerationContext.basicBlock("landingpad", endLocationInfoFromScope()) { genLandingpad() } } } /** * The Kotlin exception handler, i.e. the [ContinuationBlock] which gets started * when the exception is caught, receiving this exception as its value. */ private val handler by lazy { using(outerContext) { continuationBlock(context.ir.symbols.throwable.owner.defaultType, endLocationInfoFromScope()) { genHandler(it.value) } } } private fun endLocationInfoFromScope(): LocationInfo? { val functionScope = currentCodeContext.functionScope() val irFunction = functionScope?.let { (functionScope as FunctionScope).declaration } return irFunction?.endLocation } private fun jumpToHandler(exception: LLVMValueRef) { jump(this.handler, exception) } /** * Generates the LLVM `landingpad` that catches C++ exception with type `KotlinException`, * unwraps the Kotlin exception object and jumps to [handler]. * * This method generates nearly the same code as `clang++` does for the following: * ``` * catch (KotlinException& e) { * KRef exception = e.exception_; * return exception; * } * ``` * except that our code doesn't check exception `typeid`. * * TODO: why does `clang++` check `typeid` even if there is only one catch clause? */ private fun genLandingpad() { with(functionGenerationContext) { val exceptionPtr = catchKotlinException() jumpToHandler(exceptionPtr) } } override val exceptionHandler: ExceptionHandler get() = object : ExceptionHandler.Local() { override val unwind get() = landingpad } override fun genThrow(exception: LLVMValueRef) { jumpToHandler(exception) } protected abstract fun genHandler(exception: LLVMValueRef) } /** * The [CatchingScope] that handles exceptions using Kotlin `catch` clauses. * * @param success the block to be used when the exception is successfully handled; * expects `catch` expression result as its value. */ private inner class CatchScope(private val catches: List, private val success: ContinuationBlock) : CatchingScope() { override fun genHandler(exception: LLVMValueRef) { for (catch in catches) { fun genCatchBlock() { using(VariableScope()) { currentCodeContext.genDeclareVariable(catch.catchParameter, exception, null) evaluateExpressionAndJump(catch.result, success) } } if (catch.catchParameter.descriptor.type == context.builtIns.throwable.defaultType) { genCatchBlock() return // Remaining catch clauses are unreachable. } else { val isInstance = genInstanceOf(exception, catch.catchParameter.type.getClass()!!) val body = functionGenerationContext.basicBlock("catch", catch.startLocation) val nextCheck = functionGenerationContext.basicBlock("catchCheck", catch.endLocation) functionGenerationContext.condBr(isInstance, body, nextCheck) functionGenerationContext.appendingTo(body) { genCatchBlock() } functionGenerationContext.positionAtEnd(nextCheck) } } // rethrow the exception if no clause can handle it. outerContext.genThrow(exception) } } private fun evaluateTry(expression: IrTry): LLVMValueRef { // TODO: does basic block order influence machine code order? // If so, consider reordering blocks to reduce exception tables size. assert (expression.finallyExpression == null, { "All finally blocks should've been lowered" }) val continuation = continuationBlock(expression.type, expression.endLocation) val catchScope = if (expression.catches.isEmpty()) null else CatchScope(expression.catches, continuation) using(catchScope) { evaluateExpressionAndJump(expression.tryResult, continuation) } functionGenerationContext.positionAtEnd(continuation.block) return continuation.value } //-------------------------------------------------------------------------// /* FIXME. Fix "when" type in frontend. * For the following code: * fun foo(x: Int) { * when (x) { * 0 -> 0 * } * } * we cannot determine if the result of when is assigned or not. */ private inner class WhenEmittingContext(val expression: IrWhen) { val needsPhi = isUnconditional(expression.branches.last()) && !expression.type.isUnit() val llvmType = codegen.getLLVMType(expression.type) val bbExit = lazy { functionGenerationContext.basicBlock("when_exit", expression.endLocation) } val resultPhi = lazy { functionGenerationContext.appendingTo(bbExit.value) { functionGenerationContext.phi(llvmType) } } } private fun evaluateWhen(expression: IrWhen): LLVMValueRef { context.log{"evaluateWhen : ${ir2string(expression)}"} val whenEmittingContext = WhenEmittingContext(expression) expression.branches.forEach { val bbNext = if (it == expression.branches.last()) null else functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation) generateWhenCase(whenEmittingContext, it, bbNext) } if (whenEmittingContext.bbExit.isInitialized()) functionGenerationContext.positionAtEnd(whenEmittingContext.bbExit.value) return when { expression.type.isUnit() -> functionGenerationContext.theUnitInstanceRef.llvm expression.type.isNothing() -> functionGenerationContext.kNothingFakeValue whenEmittingContext.resultPhi.isInitialized() -> whenEmittingContext.resultPhi.value else -> LLVMGetUndef(whenEmittingContext.llvmType)!! } } private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branch: IrBranch, bbNext: LLVMBasicBlockRef?) { val brResult = if (isUnconditional(branch)) evaluateExpression(branch.result) else { val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation, branch.endLocation) val condition = evaluateExpression(branch.condition) functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value) functionGenerationContext.positionAtEnd(bbCase) evaluateExpression(branch.result) } if (!functionGenerationContext.isAfterTerminator()) { if (whenEmittingContext.needsPhi) functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult) functionGenerationContext.br(whenEmittingContext.bbExit.value) } if (bbNext != null) functionGenerationContext.positionAtEnd(bbNext) } //-------------------------------------------------------------------------// // Checks if the branch is unconditional private fun isUnconditional(branch: IrBranch): Boolean = branch.condition is IrConst<*> // If branch condition is constant. && (branch.condition as IrConst<*>).value as Boolean // If condition is "true" //-------------------------------------------------------------------------// private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef { val loopScope = LoopScope(loop) using(loopScope) { val loopBody = functionGenerationContext.basicBlock("while_loop", loop.startLocation) functionGenerationContext.br(loopScope.loopCheck) functionGenerationContext.positionAtEnd(loopScope.loopCheck) val condition = evaluateExpression(loop.condition) functionGenerationContext.condBr(condition, loopBody, loopScope.loopExit) functionGenerationContext.positionAtEnd(loopBody) if (context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList()) loop.body?.generate() functionGenerationContext.br(loopScope.loopCheck) functionGenerationContext.positionAtEnd(loopScope.loopExit) } assert(loop.type.isUnit()) return functionGenerationContext.theUnitInstanceRef.llvm } //-------------------------------------------------------------------------// private fun evaluateDoWhileLoop(loop: IrDoWhileLoop): LLVMValueRef { val loopScope = LoopScope(loop) using(loopScope) { val loopBody = functionGenerationContext.basicBlock("do_while_loop", loop.body?.startLocation ?: loop.startLocation) functionGenerationContext.br(loopBody) functionGenerationContext.positionAtEnd(loopBody) if (context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointWhileLoopBody, emptyList()) loop.body?.generate() functionGenerationContext.br(loopScope.loopCheck) functionGenerationContext.positionAtEnd(loopScope.loopCheck) val condition = evaluateExpression(loop.condition) functionGenerationContext.condBr(condition, loopBody, loopScope.loopExit) functionGenerationContext.positionAtEnd(loopScope.loopExit) } assert(loop.type.isUnit()) return functionGenerationContext.theUnitInstanceRef.llvm } //-------------------------------------------------------------------------// private fun evaluateGetValue(value: IrGetValue): LLVMValueRef { context.log{"evaluateGetValue : ${ir2string(value)}"} return currentCodeContext.genGetValue(value.symbol.owner) } //-------------------------------------------------------------------------// private fun evaluateSetValue(value: IrSetValue): LLVMValueRef { context.log{"evaluateSetValue : ${ir2string(value)}"} val result = evaluateExpression(value.value) val variable = currentCodeContext.getDeclaredValue(value.symbol.owner) functionGenerationContext.vars.store(result, variable) assert(value.type.isUnit()) return functionGenerationContext.theUnitInstanceRef.llvm } //-------------------------------------------------------------------------// private fun debugInfoIfNeeded(function: IrFunction?, element: IrElement): VariableDebugLocation? { if (function == null || !element.needDebugInfo(context) || currentCodeContext.scope() == null) return null val locationInfo = element.startLocation ?: return null val location = codegen.generateLocationInfo(locationInfo) val file = (currentCodeContext.fileScope() as FileScope).file.file() return when (element) { is IrVariable -> if (shouldGenerateDebugInfo(element)) debugInfoLocalVariableLocation( builder = context.debugInfo.builder, functionScope = locationInfo.scope, diType = element.type.diType(context, codegen.llvmTargetData), name = element.debugNameConversion(), file = file, line = locationInfo.line, location = location) else null is IrValueParameter -> debugInfoParameterLocation( builder = context.debugInfo.builder, functionScope = locationInfo.scope, diType = element.type.diType(context, codegen.llvmTargetData), name = element.debugNameConversion(), argNo = function.allParameters.indexOf(element) + 1, file = file, line = locationInfo.line, location = location) else -> throw Error("Unsupported element type: ${ir2string(element)}") } } private fun shouldGenerateDebugInfo(variable: IrVariable) = when(variable.origin) { IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE, IrDeclarationOrigin.FOR_LOOP_ITERATOR, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE -> false else -> true } private fun generateVariable(variable: IrVariable) { context.log{"generateVariable : ${ir2string(variable)}"} val value = variable.initializer?.let { val callSiteOrigin = (it as? IrBlock)?.origin as? InlinerExpressionLocationHint val inlineAtFunctionSymbol = callSiteOrigin?.inlineAtSymbol as? IrFunctionSymbol inlineAtFunctionSymbol?.run { switchSymbolizationContextTo(inlineAtFunctionSymbol) { evaluateExpression(it) } } ?: evaluateExpression(it) } currentCodeContext.genDeclareVariable( variable, value, debugInfoIfNeeded( (currentCodeContext.functionScope() as FunctionScope).declaration, variable)) } //-------------------------------------------------------------------------// private fun evaluateTypeOperator(value: IrTypeOperatorCall): LLVMValueRef { return when (value.operator) { IrTypeOperator.CAST -> evaluateCast(value) IrTypeOperator.IMPLICIT_INTEGER_COERCION -> evaluateIntegerCoercion(value) IrTypeOperator.IMPLICIT_CAST -> evaluateExpression(value.argument) IrTypeOperator.IMPLICIT_NOTNULL -> TODO(ir2string(value)) IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> { evaluateExpression(value.argument) functionGenerationContext.theUnitInstanceRef.llvm } IrTypeOperator.SAFE_CAST -> throw IllegalStateException("safe cast wasn't lowered") IrTypeOperator.INSTANCEOF -> evaluateInstanceOf(value) IrTypeOperator.NOT_INSTANCEOF -> evaluateNotInstanceOf(value) IrTypeOperator.SAM_CONVERSION -> TODO(ir2string(value)) IrTypeOperator.IMPLICIT_DYNAMIC_CAST -> TODO(ir2string(value)) IrTypeOperator.REINTERPRET_CAST -> TODO(ir2string(value)) } } //-------------------------------------------------------------------------// private fun IrType.isPrimitiveInteger(): Boolean { return this.isPrimitiveType() && !this.isBoolean() && !this.isFloat() && !this.isDouble() && !this.isChar() } private fun IrType.isUnsignedInteger(): Boolean = this is IrSimpleType && !this.hasQuestionMark && UnsignedType.values().any { it.classId == this.getClass()?.descriptor?.classId } private fun evaluateIntegerCoercion(value: IrTypeOperatorCall): LLVMValueRef { context.log{"evaluateIntegerCoercion : ${ir2string(value)}"} val type = value.typeOperand assert(type.isPrimitiveInteger() || type.isUnsignedInteger()) val result = evaluateExpression(value.argument) assert(value.argument.type.isInt()) val llvmSrcType = codegen.getLLVMType(value.argument.type) val llvmDstType = codegen.getLLVMType(type) val srcWidth = LLVMGetIntTypeWidth(llvmSrcType) val dstWidth = LLVMGetIntTypeWidth(llvmDstType) return when { srcWidth == dstWidth -> result srcWidth > dstWidth -> LLVMBuildTrunc(functionGenerationContext.builder, result, llvmDstType, "")!! else /* srcWidth < dstWidth */ -> LLVMBuildSExt(functionGenerationContext.builder, result, llvmDstType, "")!! } } //-------------------------------------------------------------------------// // table of conversion with llvm for primitive types // to be used in replacement fo primitive.toX() calls with // translator intrinsics. // | byte short int long float double //------------|---------------------------------------------------- // byte | x sext sext sext sitofp sitofp // short | trunc x sext sext sitofp sitofp // int | trunc trunc x sext sitofp sitofp // long | trunc trunc trunc x sitofp sitofp // float | fptosi fptosi fptosi fptosi x fpext // double | fptosi fptosi fptosi fptosi fptrunc x private fun evaluateCast(value: IrTypeOperatorCall): LLVMValueRef { context.log{"evaluateCast : ${ir2string(value)}"} val dstClass = value.typeOperand.getClass()!! val srcArg = evaluateExpression(value.argument) assert(srcArg.type == codegen.kObjHeaderPtr) with(functionGenerationContext) { ifThen(not(genInstanceOf(srcArg, dstClass))) { if (dstClass.defaultType.isObjCObjectType()) { callDirect( context.ir.symbols.throwTypeCastException.owner, emptyList(), Lifetime.GLOBAL ) } else { val dstTypeInfo = functionGenerationContext.bitcast(kInt8Ptr, codegen.typeInfoValue(dstClass)) callDirect( context.ir.symbols.throwClassCastException.owner, listOf(srcArg, dstTypeInfo), Lifetime.GLOBAL ) } } } return srcArg } //-------------------------------------------------------------------------// private fun evaluateInstanceOf(value: IrTypeOperatorCall): LLVMValueRef { context.log{"evaluateInstanceOf : ${ir2string(value)}"} val type = value.typeOperand val srcArg = evaluateExpression(value.argument) // Evaluate src expression. val bbExit = functionGenerationContext.basicBlock("instance_of_exit", value.startLocation) val bbInstanceOf = functionGenerationContext.basicBlock("instance_of_notnull", value.startLocation) val bbNull = functionGenerationContext.basicBlock("instance_of_null", value.startLocation) val condition = functionGenerationContext.icmpEq(srcArg, codegen.kNullObjHeaderPtr) functionGenerationContext.condBr(condition, bbNull, bbInstanceOf) functionGenerationContext.positionAtEnd(bbNull) val resultNull = if (type.containsNull()) kTrue else kFalse functionGenerationContext.br(bbExit) functionGenerationContext.positionAtEnd(bbInstanceOf) val typeOperandClass = value.typeOperand.getClass() val resultInstanceOf = if (typeOperandClass != null) { genInstanceOf(srcArg, typeOperandClass) } else { // E.g. when generating type operation with reified type parameter in the original body of inline function. kTrue // TODO: this code should be unreachable, recheck. } functionGenerationContext.br(bbExit) val bbInstanceOfResult = functionGenerationContext.currentBlock functionGenerationContext.positionAtEnd(bbExit) val result = functionGenerationContext.phi(kBoolean) functionGenerationContext.addPhiIncoming(result, bbNull to resultNull, bbInstanceOfResult to resultInstanceOf) return result } //-------------------------------------------------------------------------// private fun genInstanceOf(obj: LLVMValueRef, dstClass: IrClass): LLVMValueRef { if (dstClass.defaultType.isObjCObjectType()) { return genInstanceOfObjC(obj, dstClass) } val srcObjInfoPtr = functionGenerationContext.bitcast(codegen.kObjHeaderPtr, obj) return if (!context.ghaEnabled()) { call(context.llvm.isInstanceFunction, listOf(srcObjInfoPtr, codegen.typeInfoValue(dstClass))) } else { val dstHierarchyInfo = context.getLayoutBuilder(dstClass).hierarchyInfo if (!dstClass.isInterface) { call(context.llvm.isInstanceOfClassFastFunction, listOf(srcObjInfoPtr, Int32(dstHierarchyInfo.classIdLo).llvm, Int32(dstHierarchyInfo.classIdHi).llvm)) } else { // Essentially: typeInfo.itable[place(interfaceId)].id == interfaceId val interfaceId = dstHierarchyInfo.interfaceId val typeInfo = functionGenerationContext.loadTypeInfo(srcObjInfoPtr) with(functionGenerationContext) { val interfaceTableRecord = lookupInterfaceTableRecord(typeInfo, interfaceId) icmpEq(load(structGep(interfaceTableRecord, 0 /* id */)), Int32(interfaceId).llvm) } } } } private fun genInstanceOfObjC(obj: LLVMValueRef, dstClass: IrClass): LLVMValueRef { val objCObject = callDirect( context.ir.symbols.interopObjCObjectRawValueGetter.owner, listOf(obj), Lifetime.IRRELEVANT ) return if (dstClass.isObjCClass()) { if (dstClass.isInterface) { val isMeta = if (dstClass.isObjCMetaClass()) kTrue else kFalse call( context.llvm.Kotlin_Interop_DoesObjectConformToProtocol, listOf( objCObject, genGetObjCProtocol(dstClass), isMeta ) ) } else { call( context.llvm.Kotlin_Interop_IsObjectKindOfClass, listOf(objCObject, genGetObjCClass(dstClass)) ) }.let { functionGenerationContext.icmpNe(it, kFalse) } } else { // e.g. ObjCObject, ObjCObjectBase etc. if (dstClass.isObjCMetaClass()) { val isClass = context.llvm.externalFunction( "object_isClass", functionType(int8Type, false, int8TypePtr), context.standardLlvmSymbolsOrigin ) call(isClass, listOf(objCObject)).let { functionGenerationContext.icmpNe(it, Int8(0).llvm) } } else if (dstClass.isObjCProtocolClass()) { // Note: it is not clear whether this class should be looked up this way. // clang does the same, however swiftc uses dynamic lookup. val protocolClass = functionGenerationContext.getObjCClass("Protocol", context.standardLlvmSymbolsOrigin) call( context.llvm.Kotlin_Interop_IsObjectKindOfClass, listOf(objCObject, protocolClass) ) } else { kTrue } } } //-------------------------------------------------------------------------// private fun evaluateNotInstanceOf(value: IrTypeOperatorCall): LLVMValueRef { val instanceOfResult = evaluateInstanceOf(value) return functionGenerationContext.not(instanceOfResult) } //-------------------------------------------------------------------------// private fun evaluateGetField(value: IrGetField): LLVMValueRef { context.log { "evaluateGetField : ${ir2string(value)}" } return if (!value.symbol.owner.isStatic) { val thisPtr = evaluateExpression(value.receiver!!) functionGenerationContext.loadSlot( fieldPtrOfClass(thisPtr, value.symbol.owner), !value.symbol.owner.isFinal) } else { assert(value.receiver == null) if (value.symbol.owner.correspondingPropertySymbol?.owner?.isConst == true) { evaluateConst(value.symbol.owner.initializer?.expression as IrConst<*>) } else { if (context.config.threadsAreAllowed && value.symbol.owner.isGlobalNonPrimitive) { functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler) } val ptr = context.llvmDeclarations.forStaticField(value.symbol.owner).storageAddressAccess.getAddress( functionGenerationContext ) functionGenerationContext.loadSlot(ptr, !value.symbol.owner.isFinal) } }.also { if (value.type.classifierOrNull?.isClassWithFqName(vectorType) == true) LLVMSetAlignment(it, 8) } } //-------------------------------------------------------------------------// private fun needMutationCheck(irClass: IrClass): Boolean { // For now we omit mutation checks on immutable types, as this allows initialization in constructor // and it is assumed that API doesn't allow to change them. return !irClass.isFrozen } private fun isZeroConstValue(value: IrExpression): Boolean { if (value !is IrConst<*>) return false return when (value.kind) { IrConstKind.Null -> true IrConstKind.Boolean -> (value.value as Boolean) == false IrConstKind.Byte -> (value.value as Byte) == 0.toByte() IrConstKind.Char -> (value.value as Char) == 0.toChar() IrConstKind.Short -> (value.value as Short) == 0.toShort() IrConstKind.Int -> (value.value as Int) == 0 IrConstKind.Long -> (value.value as Long) == 0L IrConstKind.Float -> (value.value as Float).toRawBits() == 0 IrConstKind.Double -> (value.value as Double).toRawBits() == 0L IrConstKind.String -> false } } private fun evaluateSetField(value: IrSetField): LLVMValueRef { context.log{"evaluateSetField : ${ir2string(value)}"} if (value.origin == IrStatementOrigin.INITIALIZE_FIELD && isZeroConstValue(value.value)) { check(value.receiver is IrGetValue) { "Only IrGetValue expected for receiver of a field initializer" } // All newly allocated objects are zeroed out, so it is redundant to initialize their // fields with the default values. This is also aligned with the Kotlin/JVM behavior. // See https://youtrack.jetbrains.com/issue/KT-39100 for details. return codegen.theUnitInstanceRef.llvm } val valueToAssign = evaluateExpression(value.value) val store = if (!value.symbol.owner.isStatic) { val thisPtr = evaluateExpression(value.receiver!!) assert(thisPtr.type == codegen.kObjHeaderPtr) { LLVMPrintTypeToString(thisPtr.type)?.toKString().toString() } if (needMutationCheck(value.symbol.owner.parentAsClass)) { functionGenerationContext.call(context.llvm.mutationCheck, listOf(functionGenerationContext.bitcast(codegen.kObjHeaderPtr, thisPtr)), Lifetime.IRRELEVANT, ExceptionHandler.Caller) if (functionGenerationContext.isObjectType(valueToAssign.type)) functionGenerationContext.call(context.llvm.checkLifetimesConstraint, listOf(thisPtr, valueToAssign)) } functionGenerationContext.storeAny(valueToAssign, fieldPtrOfClass(thisPtr, value.symbol.owner), false) } else { assert(value.receiver == null) val globalAddress = context.llvmDeclarations.forStaticField(value.symbol.owner).storageAddressAccess.getAddress( functionGenerationContext ) if (context.config.threadsAreAllowed && value.symbol.owner.storageKind == FieldStorageKind.GLOBAL) functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler) if (value.symbol.owner.storageKind == FieldStorageKind.SHARED_FROZEN) functionGenerationContext.freeze(valueToAssign, currentCodeContext.exceptionHandler) functionGenerationContext.storeAny(valueToAssign, globalAddress, false) } if (store != null && value.value.type.classifierOrNull?.isClassWithFqName(vectorType) == true) { LLVMSetAlignment(store, 8) } assert (value.type.isUnit()) return codegen.theUnitInstanceRef.llvm } private val vectorType = FqName("kotlin.native.Vector128").toUnsafe() //-------------------------------------------------------------------------// private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef { val fieldInfo = context.llvmDeclarations.forField(value) val typePtr = pointerType(fieldInfo.classBodyType) val typedBodyPtr = functionGenerationContext.bitcast(typePtr, thisPtr) val fieldPtr = LLVMBuildStructGEP(functionGenerationContext.builder, typedBodyPtr, fieldInfo.index, "") return fieldPtr!! } //-------------------------------------------------------------------------// private fun evaluateStringConst(value: IrConst) = context.llvm.staticData.kotlinStringLiteral(value.value).llvm private fun evaluateConst(value: IrConst<*>): LLVMValueRef { context.log{"evaluateConst : ${ir2string(value)}"} /* This suppression against IrConst */ @Suppress("UNCHECKED_CAST") when (value.kind) { IrConstKind.Null -> return codegen.kNullObjHeaderPtr IrConstKind.Boolean -> when (value.value) { true -> return kTrue false -> return kFalse } IrConstKind.Char -> return Char16(value.value as Char).llvm IrConstKind.Byte -> return Int8(value.value as Byte).llvm IrConstKind.Short -> return Int16(value.value as Short).llvm IrConstKind.Int -> return Int32(value.value as Int).llvm IrConstKind.Long -> return Int64(value.value as Long).llvm IrConstKind.String -> return evaluateStringConst(value as IrConst) IrConstKind.Float -> return Float32(value.value as Float).llvm IrConstKind.Double -> return Float64(value.value as Double).llvm } TODO(ir2string(value)) } //-------------------------------------------------------------------------// private fun evaluateReturn(expression: IrReturn): LLVMValueRef { context.log{"evaluateReturn : ${ir2string(expression)}"} val value = expression.value val evaluated = evaluateExpression(value) val target = expression.returnTargetSymbol.owner currentCodeContext.genReturn(target, evaluated) return codegen.kNothingFakeValue } //-------------------------------------------------------------------------// private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlock) : FileScope(returnableBlock.sourceFileSymbol?.owner ?: (currentCodeContext.fileScope() as? FileScope)?.file ?: error("returnable block should belong to current file at least") ) { var bbExit : LLVMBasicBlockRef? = null var resultPhi : LLVMValueRef? = null private val functionScope by lazy { returnableBlock.inlineFunctionSymbol?.owner?.scope() } private fun getExit(): LLVMBasicBlockRef { val location = returnableBlock.inlineFunctionSymbol?.let { location(it.owner.endOffset) } ?: returnableBlock.statements.lastOrNull()?.let { location(it.endOffset) } if (bbExit == null) bbExit = functionGenerationContext.basicBlock("returnable_block_exit", location) return bbExit!! } private fun getResult(): LLVMValueRef { if (resultPhi == null) { val bbCurrent = functionGenerationContext.currentBlock functionGenerationContext.positionAtEnd(getExit()) resultPhi = functionGenerationContext.phi(codegen.getLLVMType(returnableBlock.type)) functionGenerationContext.positionAtEnd(bbCurrent) } return resultPhi!! } override fun genReturn(target: IrSymbolOwner, value: LLVMValueRef?) { if (target != returnableBlock) { // It is not our "local return". super.genReturn(target, value) return } // It is local return from current function. functionGenerationContext.br(getExit()) // Generate branch on exit block. if (!returnableBlock.type.isUnit()) { // If function returns more then "unit" functionGenerationContext.assignPhis(getResult() to value!!) // Assign return value to result PHI node. } } override fun returnableBlockScope(): CodeContext? = this override fun location(offset: Int): LocationInfo? { return if (returnableBlock.inlineFunctionSymbol != null) { val diScope = functionScope ?: return null val inlinedAt = outerContext.location(returnableBlock.startOffset) ?: error("no location for inlinedAt:\n" + "${returnableBlock.startOffset} ${returnableBlock.endOffset}\n" + returnableBlock.render()) LocationInfo(diScope, file.fileEntry.line(offset), file.fileEntry.column(offset), inlinedAt) } else { outerContext.location(offset) } } /** * Note: DILexicalBlocks aren't nested, they should be scoped with the parent function. */ private val scope by lazy { if (!context.shouldContainLocationDebugInfo() || returnableBlock.startOffset == UNDEFINED_OFFSET) return@lazy null val lexicalBlockFile = DICreateLexicalBlockFile(context.debugInfo.builder, functionScope()!!.scope(), super.file.file()) DICreateLexicalBlock(context.debugInfo.builder, lexicalBlockFile, super.file.file(), returnableBlock.startLine(), returnableBlock.startColumn())!! } override fun scope() = scope } //-------------------------------------------------------------------------// private open inner class FileScope(val file: IrFile) : InnerScopeImpl() { override fun fileScope(): CodeContext? = this override fun location(offset: Int) = scope()?.let { LocationInfo(it, file.fileEntry.line(offset), file.fileEntry.column(offset)) } @Suppress("UNCHECKED_CAST") private val scope by lazy { if (!context.shouldContainLocationDebugInfo()) return@lazy null file.file() as DIScopeOpaqueRef? } override fun scope() = scope } //-------------------------------------------------------------------------// private inner class ClassScope(val clazz:IrClass) : InnerScopeImpl() { val isExported get() = clazz.isExported() var offsetInBits = 0L val members = mutableListOf() @Suppress("UNCHECKED_CAST") val scope = if (isExported && context.shouldContainDebugInfo()) context.debugInfo.objHeaderPointerType else null override fun classScope(): CodeContext? = this } //-------------------------------------------------------------------------// private fun evaluateReturnableBlock(value: IrReturnableBlock): LLVMValueRef { context.log{"evaluateReturnableBlock : ${value.statements.forEach { ir2string(it) }}"} val returnableBlockScope = ReturnableBlockScope(value) using(returnableBlockScope) { using(VariableScope()) { value.statements.forEach { generateStatement(it) } } } val bbExit = returnableBlockScope.bbExit if (bbExit != null) { if (!functionGenerationContext.isAfterTerminator()) { // TODO should we solve this problem once and for all functionGenerationContext.unreachable() } functionGenerationContext.positionAtEnd(bbExit) } return returnableBlockScope.resultPhi ?: if (value.type.isUnit()) { codegen.theUnitInstanceRef.llvm } else { LLVMGetUndef(codegen.getLLVMType(value.type))!! } } //-------------------------------------------------------------------------// private fun evaluateContainerExpression(value: IrContainerExpression): LLVMValueRef { context.log{"evaluateContainerExpression : ${value.statements.forEach { ir2string(it) }}"} val scope = if (value.isTransparentScope) { null } else { VariableScope() } using(scope) { value.statements.dropLast(1).forEach { generateStatement(it) } value.statements.lastOrNull()?.let { if (it is IrExpression) { return evaluateExpression(it) } else { generateStatement(it) } } assert(value.type.isUnit()) return codegen.theUnitInstanceRef.llvm } } private fun evaluateInstanceInitializerCall(expression: IrInstanceInitializerCall): LLVMValueRef { assert (expression.type.isUnit()) return codegen.theUnitInstanceRef.llvm } //-------------------------------------------------------------------------// private fun evaluateCall(value: IrFunctionAccessExpression): LLVMValueRef { context.log{"evaluateCall : ${ir2string(value)}"} intrinsicGenerator.tryEvaluateSpecialCall(value)?.let { return it } val args = evaluateExplicitArgs(value) updateBuilderDebugLocation(value) return when (value) { is IrDelegatingConstructorCall -> delegatingConstructorCall(value.symbol.owner, args) is IrConstructorCall -> evaluateConstructorCall(value, args) else -> evaluateFunctionCall(value as IrCall, args, resultLifetime(value)) } } //-------------------------------------------------------------------------// private fun file() = (currentCodeContext.fileScope() as FileScope).file //-------------------------------------------------------------------------// private fun updateBuilderDebugLocation(element: IrElement) { if (!context.shouldContainLocationDebugInfo() || currentCodeContext.functionScope() == null || element.startLocation == null) return functionGenerationContext.debugLocation(element.startLocation!!, element.endLocation!!) } private val IrElement.startLocation: LocationInfo? get() = if (!context.shouldContainLocationDebugInfo() || startOffset == UNDEFINED_OFFSET) null else currentCodeContext.location(startOffset) private val IrElement.endLocation: LocationInfo? get() = if (!context.shouldContainLocationDebugInfo() || startOffset == UNDEFINED_OFFSET) null else currentCodeContext.location(endOffset) //-------------------------------------------------------------------------// private fun IrElement.startLine() = file().fileEntry.line(this.startOffset) //-------------------------------------------------------------------------// private fun IrElement.startColumn() = file().fileEntry.column(this.startOffset) //-------------------------------------------------------------------------// private fun IrElement.endLine() = file().fileEntry.line(this.endOffset) //-------------------------------------------------------------------------// private fun IrElement.endColumn() = file().fileEntry.column(this.endOffset) //-------------------------------------------------------------------------// private fun debugFieldDeclaration(expression: IrField) { val scope = currentCodeContext.classScope() as? ClassScope ?: return if (!scope.isExported || !context.shouldContainDebugInfo()) return val irFile = (currentCodeContext.fileScope() as FileScope).file val sizeInBits = expression.type.size(context) scope.offsetInBits += sizeInBits val alignInBits = expression.type.alignment(context) scope.offsetInBits = alignTo(scope.offsetInBits, alignInBits) @Suppress("UNCHECKED_CAST") scope.members.add(DICreateMemberType( refBuilder = context.debugInfo.builder, refScope = scope.scope as DIScopeOpaqueRef, name = expression.computeSymbolName(), file = irFile.file(), lineNum = expression.startLine(), sizeInBits = sizeInBits, alignInBits = alignInBits, offsetInBits = scope.offsetInBits, flags = 0, type = expression.type.diType(context, codegen.llvmTargetData) )!!) } //-------------------------------------------------------------------------// private fun IrFile.file(): DIFileRef { return context.debugInfo.files.getOrPut(this.fileEntry.name) { val path = this.fileEntry.name.toFileAndFolder(context) DICreateFile(context.debugInfo.builder, path.file, path.folder)!! } } //-------------------------------------------------------------------------// // Saved calculated IrFunction scope which is used several time for getting locations and generating debug info. private var irFunctionSavedScope: Pair? = null private fun IrFunction.scope(): DIScopeOpaqueRef? = if (startOffset != UNDEFINED_OFFSET) ( if (irFunctionSavedScope != null && this == irFunctionSavedScope!!.first) irFunctionSavedScope!!.second else this.scope(startLine()).also { irFunctionSavedScope = Pair(this, it) } ) else null private val IrFunction.isReifiedInline:Boolean get() = isInline && typeParameters.any { it.isReified } @Suppress("UNCHECKED_CAST") private fun IrFunction.scope(startLine:Int): DIScopeOpaqueRef? { if (!context.shouldContainLocationDebugInfo()) return null val functionLlvmValue = // TODO: May be tie up inline lambdas to their outer function? if (codegen.isExternal(this) && !KonanBinaryInterface.isExported(this)) null else codegen.llvmFunctionOrNull(this) return if (!isReifiedInline && functionLlvmValue != null) { context.debugInfo.subprograms.getOrPut(functionLlvmValue) { memScoped { val subroutineType = subroutineType(context, codegen.llvmTargetData) val llvmFunnction = codegen.llvmFunction(this@scope) diFunctionScope(name.asString(), llvmFunnction.name!!, startLine, subroutineType).also { if (!this@scope.isInline) DIFunctionAddSubprogram(llvmFunnction, it) } } } as DIScopeOpaqueRef } else { context.debugInfo.inlinedSubprograms.getOrPut(this) { memScoped { val subroutineType = subroutineType(context, codegen.llvmTargetData) diFunctionScope(name.asString(), "", startLine, subroutineType) } } as DIScopeOpaqueRef } } @Suppress("UNCHECKED_CAST") private fun LLVMValueRef.scope(startLine:Int, subroutineType: DISubroutineTypeRef): DIScopeOpaqueRef? { return context.debugInfo.subprograms.getOrPut(this) { diFunctionScope(name!!, name!!, startLine, subroutineType).also { DIFunctionAddSubprogram(this@scope, it) } } as DIScopeOpaqueRef } @Suppress("UNCHECKED_CAST") private fun diFunctionScope(name: String, linkageName: String, startLine: Int, subroutineType: DISubroutineTypeRef) = DICreateFunction( builder = context.debugInfo.builder, scope = context.debugInfo.compilationUnit, name = name, linkageName = linkageName, file = file().file(), lineNo = startLine, type = subroutineType, //TODO: need more investigations. isLocal = 0, isDefinition = 1, scopeLine = 0)!! //-------------------------------------------------------------------------// private fun getContinuation(): LLVMValueRef { val caller = functionGenerationContext.irFunction!! return if (caller.isSuspend) codegen.param(caller, caller.allParametersCount) // The last argument. else { // Suspend call from non-suspend function - must be [invokeSuspend]. assert ((caller as IrSimpleFunction).overrides(context.ir.symbols.invokeSuspendFunction.owner), { "Expected 'BaseContinuationImpl.invokeSuspend' but was '$caller'" }) currentCodeContext.genGetValue(caller.dispatchReceiverParameter!!) } } private fun IrFunction.returnsUnit() = returnType.isUnit() && !isSuspend /** * Evaluates all arguments of [expression] that are explicitly represented in the IR. * Returns results in the same order as LLVM function expects, assuming that all explicit arguments * exactly correspond to a tail of LLVM parameters. */ private fun evaluateExplicitArgs(expression: IrFunctionAccessExpression): List { val result = expression.getArgumentsWithIr().map { (_, argExpr) -> evaluateExpression(argExpr) } val explicitParametersCount = expression.symbol.owner.explicitParametersCount if (result.size != explicitParametersCount) { error("Number of arguments explicitly represented in the IR ${result.size} differs from expected " + "$explicitParametersCount in ${ir2string(expression)}") } return result } //-------------------------------------------------------------------------// private fun evaluateFunctionReference(expression: IrFunctionReference): LLVMValueRef { // TODO: consider creating separate IR element for pointer to function. assert (expression.type.getClass()?.descriptor == context.interopBuiltIns.cPointer) { "assert: ${expression.type.getClass()?.descriptor} == ${context.interopBuiltIns.cPointer}" } assert (expression.getArguments().isEmpty()) val function = expression.symbol.owner assert (function.dispatchReceiverParameter == null) return codegen.functionEntryPointAddress(function) } //-------------------------------------------------------------------------// private inner class SuspendableExpressionScope(val resumePoints: MutableList) : InnerScopeImpl() { override fun addResumePoint(bbLabel: LLVMBasicBlockRef): Int { val result = resumePoints.size resumePoints.add(bbLabel) return result } } private fun evaluateSuspendableExpression(expression: IrSuspendableExpression): LLVMValueRef { val suspensionPointId = evaluateExpression(expression.suspensionPointId) val bbStart = functionGenerationContext.basicBlock("start", expression.result.startLocation) val bbDispatch = functionGenerationContext.basicBlock("dispatch", expression.suspensionPointId.startLocation) val resumePoints = mutableListOf() using (SuspendableExpressionScope(resumePoints)) { functionGenerationContext.condBr(functionGenerationContext.icmpEq(suspensionPointId, kNullInt8Ptr), bbStart, bbDispatch) functionGenerationContext.positionAtEnd(bbStart) val result = evaluateExpression(expression.result) functionGenerationContext.appendingTo(bbDispatch) { if (context.config.indirectBranchesAreAllowed) functionGenerationContext.indirectBr(suspensionPointId, resumePoints) else { val bbElse = functionGenerationContext.basicBlock("else", null) { functionGenerationContext.unreachable() } val cases = resumePoints.withIndex().map { Int32(it.index + 1).llvm to it.value } functionGenerationContext.switch(functionGenerationContext.ptrToInt(suspensionPointId, int32Type), cases, bbElse) } } return result } } private inner class SuspensionPointScope(val suspensionPointId: IrVariable, val bbResume: LLVMBasicBlockRef, val bbResumeId: Int): InnerScopeImpl() { override fun genGetValue(value: IrValueDeclaration): LLVMValueRef { if (value == suspensionPointId) { return if (context.config.indirectBranchesAreAllowed) functionGenerationContext.blockAddress(bbResume) else functionGenerationContext.intToPtr(Int32(bbResumeId + 1).llvm, int8TypePtr) } return super.genGetValue(value) } } private fun evaluateSuspensionPoint(expression: IrSuspensionPoint): LLVMValueRef { val bbResume = functionGenerationContext.basicBlock("resume", expression.resumeResult.startLocation) val id = currentCodeContext.addResumePoint(bbResume) using (SuspensionPointScope(expression.suspensionPointIdParameter, bbResume, id)) { continuationBlock(expression.type, expression.result.startLocation).run { val normalResult = evaluateExpression(expression.result) jump(this, normalResult) functionGenerationContext.positionAtEnd(bbResume) val resumeResult = evaluateExpression(expression.resumeResult) jump(this, resumeResult) functionGenerationContext.positionAtEnd(this.block) return this.value } } } //-------------------------------------------------------------------------// private fun evaluateFunctionCall(callee: IrCall, args: List, resultLifetime: Lifetime): LLVMValueRef { val function = callee.symbol.owner val argsWithContinuationIfNeeded = if (function.isSuspend) args + getContinuation() else args return when { function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args) function.isBuiltInOperator -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded) else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner) } } //-------------------------------------------------------------------------// private fun evaluateClassReference(classReference: IrClassReference): LLVMValueRef { val typeInfoPtr = codegen.typeInfoValue(classReference.symbol.owner as IrClass) return functionGenerationContext.bitcast(int8TypePtr, typeInfoPtr) } //-------------------------------------------------------------------------// private fun evaluateSimpleFunctionCall( function: IrFunction, args: List, resultLifetime: Lifetime, superClass: IrClass? = null): LLVMValueRef { //context.log{"evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}"} if (superClass == null && function is IrSimpleFunction && function.isOverridable) return callVirtual(function, args, resultLifetime) else return callDirect(function, args, resultLifetime) } //-------------------------------------------------------------------------// private fun resultLifetime(callee: IrElement): Lifetime { return lifetimes.getOrElse(callee) { /* TODO: make IRRELEVANT */ Lifetime.GLOBAL } } private fun evaluateConstructorCall(callee: IrConstructorCall, args: List): LLVMValueRef { context.log{"evaluateConstructorCall : ${ir2string(callee)}"} return memScoped { val constructedClass = callee.symbol.owner.constructedClass val thisValue = when { constructedClass.isArray -> { assert(args.isNotEmpty() && args[0].type == int32Type) functionGenerationContext.allocArray(constructedClass, args[0], resultLifetime(callee), currentCodeContext.exceptionHandler) } constructedClass == context.ir.symbols.string.owner -> { // TODO: consider returning the empty string literal instead. assert(args.isEmpty()) functionGenerationContext.allocArray(constructedClass, count = kImmZero, lifetime = resultLifetime(callee), exceptionHandler = currentCodeContext.exceptionHandler) } constructedClass.isObjCClass() -> error("Call should've been lowered: ${callee.dump()}") else -> functionGenerationContext.allocInstance(constructedClass, resultLifetime(callee), currentCodeContext.stackLocalsManager) } evaluateSimpleFunctionCall(callee.symbol.owner, listOf(thisValue) + args, Lifetime.IRRELEVANT /* constructor doesn't return anything */) thisValue } } private fun genGetObjCClass(irClass: IrClass): LLVMValueRef { return functionGenerationContext.getObjCClass(irClass, currentCodeContext.exceptionHandler) } private fun genGetObjCProtocol(irClass: IrClass): LLVMValueRef { // Note: this function will return the same result for Obj-C protocol and corresponding meta-class. assert(irClass.isInterface) assert(irClass.isExternalObjCClass()) val annotation = irClass.annotations.findAnnotation(externalObjCClassFqName)!! val protocolGetterName = annotation.getAnnotationStringValue("protocolGetter") val protocolGetter = context.llvm.externalFunction( protocolGetterName, functionType(int8TypePtr, false), irClass.llvmSymbolOrigin, independent = true // Protocol is header-only declaration. ) return call(protocolGetter, emptyList()) } //-------------------------------------------------------------------------// private val kImmZero = Int32(0).llvm private val kImmOne = Int32(1).llvm private val kTrue = Int1(1).llvm private val kFalse = Int1(0).llvm // TODO: Intrinsify? private fun evaluateOperatorCall(callee: IrCall, args: List): LLVMValueRef { context.log{"evaluateOperatorCall : origin:${ir2string(callee)}"} val function = callee.symbol.owner val ib = context.irModule!!.irBuiltins with(functionGenerationContext) { val functionSymbol = function.symbol return when (functionSymbol) { ib.eqeqeqSymbol -> icmpEq(args[0], args[1]) ib.booleanNotSymbol -> icmpNe(args[0], kTrue) else -> { val isFloatingPoint = args[0].type.isFloatingPoint() // LLVM does not distinguish between signed/unsigned integers, so we must check // the parameter type. val shouldUseUnsignedComparison = function.valueParameters[0].type.isChar() when { functionSymbol.isComparisonFunction(ib.greaterFunByOperandType) -> { when { isFloatingPoint -> fcmpGt(args[0], args[1]) shouldUseUnsignedComparison -> icmpUGt(args[0], args[1]) else -> icmpGt(args[0], args[1]) } } functionSymbol.isComparisonFunction(ib.greaterOrEqualFunByOperandType) -> { when { isFloatingPoint -> fcmpGe(args[0], args[1]) shouldUseUnsignedComparison -> icmpUGe(args[0], args[1]) else -> icmpGe(args[0], args[1]) } } functionSymbol.isComparisonFunction(ib.lessFunByOperandType) -> { when { isFloatingPoint -> fcmpLt(args[0], args[1]) shouldUseUnsignedComparison -> icmpULt(args[0], args[1]) else -> icmpLt(args[0], args[1]) } } functionSymbol.isComparisonFunction(ib.lessOrEqualFunByOperandType) -> { when { isFloatingPoint -> fcmpLe(args[0], args[1]) shouldUseUnsignedComparison -> icmpULe(args[0], args[1]) else -> icmpLe(args[0], args[1]) } } functionSymbol == context.irBuiltIns.illegalArgumentExceptionSymbol -> { callDirect( context.ir.symbols.throwIllegalArgumentExceptionWithMessage.owner, args, Lifetime.GLOBAL ) } else -> TODO(function.name.toString()) } } } } } //-------------------------------------------------------------------------// fun callDirect(function: IrFunction, args: List, resultLifetime: Lifetime): LLVMValueRef { val llvmFunction = codegen.llvmFunction(function.target) return call(function, llvmFunction, args, resultLifetime) } //-------------------------------------------------------------------------// fun callVirtual(function: IrFunction, args: List, resultLifetime: Lifetime): LLVMValueRef { val llvmFunction = functionGenerationContext.lookupVirtualImpl(args.first(), function) return call(function, llvmFunction, args, resultLifetime) // Invoke the method } //-------------------------------------------------------------------------// private fun call(function: IrFunction, llvmFunction: LLVMValueRef, args: List, resultLifetime: Lifetime): LLVMValueRef { val exceptionHandler = function.annotations.findAnnotation(RuntimeNames.filterExceptions)?.let { val foreignExceptionMode = ForeignExceptionMode.byValue(it.getAnnotationValueOrNull("mode")) functionGenerationContext.filteringExceptionHandler(currentCodeContext, foreignExceptionMode) } ?: currentCodeContext.exceptionHandler val result = call(llvmFunction, args, resultLifetime, exceptionHandler) if (!function.isSuspend && function.returnType.isNothing()) { functionGenerationContext.unreachable() } if (LLVMGetReturnType(getFunctionType(llvmFunction)) == voidType) { return codegen.theUnitInstanceRef.llvm } return result } private fun call(function: LLVMValueRef, args: List, resultLifetime: Lifetime = Lifetime.IRRELEVANT, exceptionHandler: ExceptionHandler = currentCodeContext.exceptionHandler): LLVMValueRef { return functionGenerationContext.call(function, args, resultLifetime, exceptionHandler) } //-------------------------------------------------------------------------// private fun delegatingConstructorCall(constructor: IrConstructor, args: List): LLVMValueRef { val constructedClass = functionGenerationContext.constructedClass!! val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!) if (constructor.constructedClass.isExternalObjCClass() || constructor.constructedClass.isAny()) { assert(args.isEmpty()) return codegen.theUnitInstanceRef.llvm } val thisPtrArgType = codegen.getLLVMType(constructor.allParameters[0].type) val thisPtrArg = if (thisPtr.type == thisPtrArgType) { thisPtr } else { // e.g. when array constructor calls super (i.e. Any) constructor. functionGenerationContext.bitcast(thisPtrArgType, thisPtr) } return callDirect(constructor, listOf(thisPtrArg) + args, Lifetime.IRRELEVANT /* no value returned */) } //-------------------------------------------------------------------------// private fun appendLlvmUsed(name: String, args: List) { if (args.isEmpty()) return val argsCasted = args.map { it -> constPointer(it).bitcast(int8TypePtr) } val llvmUsedGlobal = context.llvm.staticData.placeGlobalArray(name, int8TypePtr, argsCasted) LLVMSetLinkage(llvmUsedGlobal.llvmGlobal, LLVMLinkage.LLVMAppendingLinkage) LLVMSetSection(llvmUsedGlobal.llvmGlobal, "llvm.metadata") } // TODO: Consider migrating `KonanNeedDebugInfo` to the `overrideRuntimeGlobal` mechanism from below. private fun appendDebugSelector() { if (!context.producedLlvmModuleContainsStdlib) return val llvmDebugSelector = context.llvm.staticData.placeGlobal("KonanNeedDebugInfo", Int32(if (context.shouldContainDebugInfo()) 1 else 0)) llvmDebugSelector.setConstant(true) llvmDebugSelector.setLinkage(LLVMLinkage.LLVMExternalLinkage) } private fun overrideRuntimeGlobal(name: String, value: ConstValue) { // TODO: A similar mechanism is used in `ObjCExportCodeGenerator`. Consider merging them. if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { // When some dynamic caches are used, we consider that stdlib is in the dynamic cache as well. // Runtime is linked into stdlib module only, so import runtime global from it. val global = codegen.importGlobal(name, value.llvmType, context.standardLlvmSymbolsOrigin) val initializer = generateFunctionNoRuntime(codegen, functionType(voidType, false), "") { store(value.llvm, global) ret(null) } LLVMSetLinkage(initializer, LLVMLinkage.LLVMPrivateLinkage) context.llvm.otherStaticInitializers += initializer } else { context.llvmImports.add(context.standardLlvmSymbolsOrigin) // Define a strong runtime global. It'll overrule a weak global defined in a statically linked runtime. val global = context.llvm.staticData.placeGlobal(name, value, true) if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { context.llvm.usedGlobals += global.llvmGlobal LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) } } } private fun overrideRuntimeGlobals() { if (!context.config.produce.isFinalBinary) return overrideRuntimeGlobal("Kotlin_destroyRuntimeMode", Int32(context.config.destroyRuntimeMode.value)) } //-------------------------------------------------------------------------// // Create type { i32, void ()*, i8* } val kCtorType = structType(int32Type, pointerType(kVoidFuncType), kInt8Ptr) //-------------------------------------------------------------------------// // Create object { i32, void ()*, i8* } { i32 1, void ()* @ctorFunction, i8* null } fun createGlobalCtor(ctorFunction: LLVMValueRef): ConstPointer { val priority = if (context.config.target.family == Family.MINGW) { // Workaround MinGW bug. Using this value makes the compiler generate // '.ctors' section instead of '.ctors.XXXXX', which can't be recognized by ld // when string table is too long. // More details: https://youtrack.jetbrains.com/issue/KT-39548 Int32(65535).llvm // Note: this difference in priorities doesn't actually make initializers // platform-dependent, because handling priorities for initializers // from different object files is platform-dependent anyway. } else { kImmInt32One } val data = kNullInt8Ptr val argList = cValuesOf(priority, ctorFunction, data) val ctorItem = LLVMConstNamedStruct(kCtorType, argList, 3)!! return constPointer(ctorItem) } //-------------------------------------------------------------------------// fun appendStaticInitializers() { // Note: the list of libraries is topologically sorted (in order for initializers to be called correctly). val libraries = (context.llvm.allBitcodeDependencies + listOf(null)/* Null for "current" non-library module */) val libraryToInitializers = libraries.associateWith { mutableListOf() } context.llvm.irStaticInitializers.forEach { val library = it.konanLibrary val initializers = libraryToInitializers[library] ?: error("initializer for not included library ${library?.libraryFile}") initializers.add(it.initializer) } val ctorFunctions = libraries.map { library -> val ctorName = if (library != null) { library.moduleConstructorName } else { context.config.moduleId.moduleConstructorName } val ctorFunction = addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, ctorName, kVoidFuncType ) LLVMSetLinkage(ctorFunction, LLVMLinkage.LLVMExternalLinkage) val initializers = libraryToInitializers.getValue(library) if (library == null || context.llvmModuleSpecification.containsLibrary(library)) { val otherInitializers = context.llvm.otherStaticInitializers.takeIf { library == null }.orEmpty() appendStaticInitializers(ctorFunction, initializers + otherInitializers) } else { check(initializers.isEmpty()) { "found initializer from ${library.libraryFile}, which is not included into compilation" } } ctorFunction } appendGlobalCtors(ctorFunctions) } private fun appendStaticInitializers(ctorFunction: LLVMValueRef, initializers: List) { generateFunctionNoRuntime(codegen, ctorFunction) { val initGuardName = ctorFunction.name.orEmpty() + "_guard" val initGuard = LLVMAddGlobal(context.llvmModule, int32Type, initGuardName) LLVMSetInitializer(initGuard, kImmZero) LLVMSetLinkage(initGuard, LLVMLinkage.LLVMPrivateLinkage) val bbInited = basicBlock("inited", null) val bbNeedInit = basicBlock("need_init", null) val value = LLVMBuildLoad(builder, initGuard, "")!! condBr(icmpEq(value, kImmZero), bbNeedInit, bbInited) appendingTo(bbInited) { ret(null) } appendingTo(bbNeedInit) { LLVMBuildStore(builder, kImmOne, initGuard) // TODO: shall we put that into the try block? initializers.forEach { call(it, emptyList(), Lifetime.IRRELEVANT, exceptionHandler = ExceptionHandler.Caller, verbatim = true) } ret(null) } } } private fun appendGlobalCtors(ctorFunctions: List) { if (context.config.produce.isFinalBinary) { // Generate function calling all [ctorFunctions]. val globalCtorFunction = generateFunctionNoRuntime(codegen, kVoidFuncType, "_Konan_constructors") { ctorFunctions.forEach { call(it, emptyList(), Lifetime.IRRELEVANT, exceptionHandler = ExceptionHandler.Caller, verbatim = true) } ret(null) } LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage) // Append initializers of global variables in "llvm.global_ctors" array. val globalCtors = context.llvm.staticData.placeGlobalArray("llvm.global_ctors", kCtorType, listOf(createGlobalCtor(globalCtorFunction))) LLVMSetLinkage(globalCtors.llvmGlobal, LLVMLinkage.LLVMAppendingLinkage) if (context.config.produce == CompilerOutputKind.PROGRAM) { // Provide an optional handle for calling .ctors, if standard constructors mechanism // is not available on the platform (i.e. WASM, embedded). LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMExternalLinkage) appendLlvmUsed("llvm.used", listOf(globalCtorFunction)) } } } //-------------------------------------------------------------------------// fun FunctionGenerationContext.basicBlock(name: String, locationInfo: LocationInfo?, code: () -> Unit) = functionGenerationContext.basicBlock(name, locationInfo).apply { appendingTo(this) { code() } } } private fun IrValueParameter.debugNameConversion() = descriptor.name.debugNameConversion() private fun IrVariable.debugNameConversion() = descriptor.name.debugNameConversion() private val thisName = Name.special("") private val underscoreThisName = Name.identifier("_this") /** * HACK: this is workaround for GH-2316, to let IDE some how operate with this. * We're experiencing issue with libclang which is used as compiler of expression in lldb * for current state support Kotlin in lldb: * 1. isn't accepted by libclang as valid variable name. * 2. this is reserved name and compiled in special way. */ private fun Name.debugNameConversion(): Name = when(this) { thisName -> underscoreThisName else -> this } internal class LocationInfo(val scope: DIScopeOpaqueRef, val line: Int, val column: Int, val inlinedAt: LocationInfo? = null) { init { assert(line != 0) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/KotlinObjCClassInfoGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.LLVMLinkage import llvm.LLVMSetLinkage import llvm.LLVMValueRef import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.findAnnotation import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe internal class KotlinObjCClassInfoGenerator(override val context: Context) : ContextUtils { fun generate(irClass: IrClass) { assert(irClass.isFinalClass) val objCLLvmDeclarations = context.llvmDeclarations.forClass(irClass).objCDeclarations!! val instanceMethods = generateInstanceMethodDescs(irClass) val companionObject = irClass.companionObject() val classMethods = companionObject?.generateMethodDescs().orEmpty() val superclassName = irClass.getSuperClassNotAny()!!.let { context.llvm.imports.add(it.llvmSymbolOrigin) it.descriptor.getExternalObjCClassBinaryName() } val protocolNames = irClass.getSuperInterfaces().map { context.llvm.imports.add(it.llvmSymbolOrigin) it.name.asString().removeSuffix("Protocol") } val exportedClassName = selectExportedClassName(irClass) val className = exportedClassName ?: selectInternalClassName(irClass) val classNameLiteral = className?.let { staticData.cStringLiteral(it) } ?: NullPointer(int8Type) val info = Struct(runtime.kotlinObjCClassInfo, classNameLiteral, Int32(if (exportedClassName != null) 1 else 0), staticData.cStringLiteral(superclassName), staticData.placeGlobalConstArray("", int8TypePtr, protocolNames.map { staticData.cStringLiteral(it) } + NullPointer(int8Type)), staticData.placeGlobalConstArray("", runtime.objCMethodDescription, instanceMethods), Int32(instanceMethods.size), staticData.placeGlobalConstArray("", runtime.objCMethodDescription, classMethods), Int32(classMethods.size), objCLLvmDeclarations.bodyOffsetGlobal.pointer, irClass.typeInfoPtr, companionObject?.typeInfoPtr ?: NullPointer(runtime.typeInfoType), staticData.placeGlobal( "kobjcclassptr:${irClass.fqNameForIrSerialization}#internal", NullPointer(int8Type) ).pointer, generateClassDataImp(irClass) ) objCLLvmDeclarations.classInfoGlobal.setInitializer(info) objCLLvmDeclarations.bodyOffsetGlobal.setInitializer(Int32(0)) } private fun IrClass.generateMethodDescs(): List = this.generateImpMethodDescs() private fun generateInstanceMethodDescs( irClass: IrClass ): List = mutableListOf().apply { addAll(irClass.generateMethodDescs()) val allImplementedSelectors = this.map { it.selector }.toSet() assert(irClass.getSuperClassNotAny()!!.isExternalObjCClass()) val allInitMethodsInfo = irClass.getSuperClassNotAny()!!.constructors .mapNotNull { it.getObjCInitMethod()?.getExternalObjCMethodInfo() } .filter { it.selector !in allImplementedSelectors } .distinctBy { it.selector } allInitMethodsInfo.mapTo(this) { ObjCMethodDesc(it.selector, it.encoding, context.llvm.missingInitImp) } } private fun selectExportedClassName(irClass: IrClass): String? { val exportObjCClassAnnotation = context.interopBuiltIns.exportObjCClass.fqNameSafe val explicitName = irClass.getAnnotationArgumentValue(exportObjCClassAnnotation, "name") if (explicitName != null) return explicitName return if (irClass.annotations.hasAnnotation(exportObjCClassAnnotation)) irClass.name.asString() else null } private fun selectInternalClassName(irClass: IrClass): String? = if (irClass.isExported()) { irClass.fqNameForIrSerialization.asString() } else { null // Generate as anonymous. } private val impType = pointerType(functionType(int8TypePtr, true, int8TypePtr, int8TypePtr)) private inner class ObjCMethodDesc( val selector: String, val encoding: String, val impFunction: LLVMValueRef ) : Struct( runtime.objCMethodDescription, constPointer(impFunction).bitcast(impType), staticData.cStringLiteral(selector), staticData.cStringLiteral(encoding) ) private fun IrClass.generateImpMethodDescs(): List = this.declarations .filterIsInstance() .mapNotNull { val annotation = it.annotations.findAnnotation(context.interopBuiltIns.objCMethodImp.fqNameSafe) ?: return@mapNotNull null ObjCMethodDesc( annotation.getAnnotationStringValue("selector"), annotation.getAnnotationStringValue("encoding"), it.llvmFunction ) } private fun generateClassDataImp(irClass: IrClass): ConstPointer { val classDataPointer = staticData.placeGlobal( "kobjcclassdata:${irClass.fqNameForIrSerialization}#internal", Zero(runtime.kotlinObjCClassData) ).pointer val functionType = functionType(classDataPointer.llvmType, false, int8TypePtr, int8TypePtr) val functionName = "kobjcclassdataimp:${irClass.fqNameForIrSerialization}#internal" val function = generateFunctionNoRuntime(codegen, functionType, functionName) { ret(classDataPointer.llvm) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMPrivateLinkage) } return constPointer(function) } private val codegen = CodeGenerator(context) companion object { const val createdClassFieldIndex = 11 } } internal fun CodeGenerator.kotlinObjCClassInfo(irClass: IrClass): LLVMValueRef { require(irClass.isKotlinObjCClass()) return if (isExternal(irClass)) { importGlobal( irClass.kotlinObjCClassInfoSymbolName, runtime.kotlinObjCClassInfo, origin = irClass.llvmSymbolOrigin ) } else { context.llvmDeclarations.forClass(irClass).objCDeclarations!!.classInfoGlobal.llvmGlobal } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.isThrowable import org.jetbrains.kotlin.konan.target.Family internal fun addLlvmFunctionWithDefaultAttributes( context: Context, module: LLVMModuleRef, name: String, type: LLVMTypeRef ): LLVMValueRef = LLVMAddFunction(module, name, type)!!.also { addDefaultLlvmFunctionAttributes(context, it) } /** * Mimics parts of clang's `CodeGenModule::getDefaultFunctionAttributes` * that are required for Kotlin/Native compiler. */ private fun addDefaultLlvmFunctionAttributes(context: Context, llvmFunction: LLVMValueRef) { if (shouldEnforceFramePointer(context)) { // Note: this is default for clang on at least on iOS and macOS. enforceFramePointer(llvmFunction) } } internal fun addLlvmAttributesForKotlinFunction(context: Context, irFunction: IrFunction, llvmFunction: LLVMValueRef) { if (irFunction.returnType.isNothing()) { setFunctionNoReturn(llvmFunction) } if (mustNotInline(context, irFunction)) { setFunctionNoInline(llvmFunction) } } private fun mustNotInline(context: Context, irFunction: IrFunction): Boolean { if (context.shouldContainLocationDebugInfo()) { if (irFunction is IrConstructor && irFunction.isPrimary && irFunction.returnType.isThrowable()) { // To simplify skipping this constructor when scanning call stack in Kotlin_getCurrentStackTrace. return true } } return false } private fun shouldEnforceFramePointer(context: Context): Boolean { // TODO: do we still need it? if (!context.shouldOptimize()) { return true } return when (context.config.target.family) { Family.OSX, Family.IOS, Family.WATCHOS, Family.TVOS -> context.shouldContainLocationDebugInfo() Family.LINUX, Family.MINGW, Family.ANDROID, Family.WASM, Family.ZEPHYR -> false } } private fun enforceFramePointer(llvmFunction: LLVMValueRef) { LLVMAddTargetDependentFunctionAttr(llvmFunction, "no-frame-pointer-elim", "true") LLVMAddTargetDependentFunctionAttr(llvmFunction, "no-frame-pointer-elim-non-leaf", "") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name internal fun createLlvmDeclarations(context: Context): LlvmDeclarations { val generator = DeclarationsGeneratorVisitor(context) context.ir.irModule.acceptChildrenVoid(generator) return LlvmDeclarations(generator.uniques) } // Please note, that llvmName is part of the ABI, and cannot be liberally changed. enum class UniqueKind(val llvmName: String) { UNIT("theUnitInstance"), EMPTY_ARRAY("theEmptyArray") } internal class LlvmDeclarations(private val unique: Map) { fun forFunction(function: IrFunction) = forFunctionOrNull(function) ?: with(function){error("$name in $file/${parent.fqNameForIrSerialization}")} fun forFunctionOrNull(function: IrFunction) = (function.metadata as? CodegenFunctionMetadata)?.llvm fun forClass(irClass: IrClass) = (irClass.metadata as? CodegenClassMetadata)?.llvm ?: error(irClass.descriptor.toString()) fun forField(field: IrField) = (field.metadata as? CodegenInstanceFieldMetadata)?.llvm ?: error(field.descriptor.toString()) fun forStaticField(field: IrField) = (field.metadata as? CodegenStaticFieldMetadata)?.llvm ?: error(field.descriptor.toString()) fun forSingleton(irClass: IrClass) = forClass(irClass).singletonDeclarations ?: error(irClass.descriptor.toString()) fun forUnique(kind: UniqueKind) = unique[kind] ?: error("No unique $kind") } internal class ClassLlvmDeclarations( val bodyType: LLVMTypeRef, val typeInfoGlobal: StaticData.Global, val writableTypeInfoGlobal: StaticData.Global?, val typeInfo: ConstPointer, val singletonDeclarations: SingletonLlvmDeclarations?, val objCDeclarations: KotlinObjCClassLlvmDeclarations?) internal class SingletonLlvmDeclarations(val instanceStorage: AddressAccess) internal class KotlinObjCClassLlvmDeclarations( val classInfoGlobal: StaticData.Global, val bodyOffsetGlobal: StaticData.Global ) internal class FunctionLlvmDeclarations(val llvmFunction: LLVMValueRef) internal class FieldLlvmDeclarations(val index: Int, val classBodyType: LLVMTypeRef) internal class StaticFieldLlvmDeclarations(val storageAddressAccess: AddressAccess) internal class UniqueLlvmDeclarations(val pointer: ConstPointer) private fun ContextUtils.createClassBodyType(name: String, fields: List): LLVMTypeRef { val fieldTypes = listOf(runtime.objHeaderType) + fields.map { getLLVMType(it.type) } // TODO: consider adding synthetic ObjHeader field to Any. val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!! // LLVMStructSetBody expects the struct to be properly aligned and will insert padding accordingly. In our case // `allocInstance` returns 16x + 8 address, i.e. always misaligned for vector types. Workaround is to use packed struct. val hasBigAlignment = fields.any { LLVMABIAlignmentOfType(context.llvm.runtime.targetData, getLLVMType(it.type)) > 8 } val packed = if (hasBigAlignment) 1 else 0 LLVMStructSetBody(classType, fieldTypes.toCValues(), fieldTypes.size, packed) return classType } private class DeclarationsGeneratorVisitor(override val context: Context) : IrElementVisitorVoid, ContextUtils { val uniques = mutableMapOf() private class Namer(val prefix: String) { private val names = mutableMapOf() private val counts = mutableMapOf() fun getName(parent: FqName, declaration: IrDeclaration): Name { return names.getOrPut(declaration) { val count = counts.getOrDefault(parent, 0) + 1 counts[parent] = count Name.identifier(prefix + count) } } } val objectNamer = Namer("object-") private fun getLocalName(parent: FqName, declaration: IrDeclaration): Name { if (declaration.isAnonymousObject) { return objectNamer.getName(parent, declaration) } return declaration.nameForIrSerialization } private fun getFqName(declaration: IrDeclaration): FqName { val parent = declaration.parent val parentFqName = when (parent) { is IrPackageFragment -> parent.fqName is IrDeclaration -> getFqName(parent) else -> error(parent) } val localName = getLocalName(parentFqName, declaration) return parentFqName.child(localName) } /** * Produces the name to be used for non-exported LLVM declarations corresponding to [declaration]. * * Note: since these declarations are going to be private, the name is only required not to clash with any * exported declarations. */ private fun qualifyInternalName(declaration: IrDeclaration): String { return getFqName(declaration).asString() + "#internal" } override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { if (declaration.requiresRtti()) { val classLlvmDeclarations = createClassDeclarations(declaration) val metadata = declaration.metadata as? CodegenClassMetadata ?: CodegenClassMetadata(declaration).also { declaration.metadata = it } metadata.llvm = classLlvmDeclarations } super.visitClass(declaration) } private fun createClassDeclarations(declaration: IrClass): ClassLlvmDeclarations { val internalName = qualifyInternalName(declaration) val fields = context.getLayoutBuilder(declaration).fields val bodyType = createClassBodyType("kclassbody:$internalName", fields) val typeInfoPtr: ConstPointer val typeInfoGlobal: StaticData.Global val typeInfoSymbolName = if (declaration.isExported()) { declaration.computeTypeInfoSymbolName() } else { "ktype:$internalName" } if (declaration.typeInfoHasVtableAttached) { // Create the special global consisting of TypeInfo and vtable. val typeInfoGlobalName = "ktypeglobal:$internalName" val typeInfoWithVtableType = structType( runtime.typeInfoType, LLVMArrayType(int8TypePtr, context.getLayoutBuilder(declaration).vtableEntries.size)!! ) typeInfoGlobal = staticData.createGlobal(typeInfoWithVtableType, typeInfoGlobalName, isExported = false) val llvmTypeInfoPtr = LLVMAddAlias(context.llvmModule, kTypeInfoPtr, typeInfoGlobal.pointer.getElementPtr(0).llvm, typeInfoSymbolName)!! if (declaration.isExported()) { if (llvmTypeInfoPtr.name != typeInfoSymbolName) { // So alias name has been mangled by LLVM to avoid name clash. throw IllegalArgumentException("Global '$typeInfoSymbolName' already exists") } } else { LLVMSetLinkage(llvmTypeInfoPtr, LLVMLinkage.LLVMInternalLinkage) } typeInfoPtr = constPointer(llvmTypeInfoPtr) } else { typeInfoGlobal = staticData.createGlobal(runtime.typeInfoType, typeInfoSymbolName, isExported = declaration.isExported()) typeInfoPtr = typeInfoGlobal.pointer } if (declaration.isUnit() || declaration.isKotlinArray()) createUniqueDeclarations(declaration, typeInfoPtr, bodyType) val singletonDeclarations = if (declaration.kind.isSingleton) { createSingletonDeclarations(declaration) } else { null } val objCDeclarations = if (declaration.isKotlinObjCClass()) { createKotlinObjCClassDeclarations(declaration) } else { null } val writableTypeInfoType = runtime.writableTypeInfoType val writableTypeInfoGlobal = if (writableTypeInfoType == null) { null } else if (declaration.isExported()) { val name = declaration.writableTypeInfoSymbolName staticData.createGlobal(writableTypeInfoType, name, isExported = true).also { it.setLinkage(LLVMLinkage.LLVMCommonLinkage) // Allows to be replaced by other bitcode module. } } else { staticData.createGlobal(writableTypeInfoType, "") }.also { it.setZeroInitializer() } return ClassLlvmDeclarations(bodyType, typeInfoGlobal, writableTypeInfoGlobal, typeInfoPtr, singletonDeclarations, objCDeclarations) } private fun createUniqueDeclarations( irClass: IrClass, typeInfoPtr: ConstPointer, bodyType: LLVMTypeRef) { when { irClass.isUnit() -> { uniques[UniqueKind.UNIT] = UniqueLlvmDeclarations(staticData.createUniqueInstance(UniqueKind.UNIT, bodyType, typeInfoPtr)) } irClass.isKotlinArray() -> { uniques[UniqueKind.EMPTY_ARRAY] = UniqueLlvmDeclarations(staticData.createUniqueInstance(UniqueKind.EMPTY_ARRAY, bodyType, typeInfoPtr)) } else -> TODO("Unsupported unique $irClass") } } private fun createSingletonDeclarations(irClass: IrClass): SingletonLlvmDeclarations? { if (irClass.isUnit()) { return null } val storageKind = irClass.storageKind(context) val threadLocal = storageKind == ObjectStorageKind.THREAD_LOCAL val isExported = irClass.isExported() val symbolName = if (isExported) { irClass.globalObjectStorageSymbolName } else { "kobjref:" + qualifyInternalName(irClass) } val instanceAddress = if (threadLocal) { addKotlinThreadLocal(symbolName, getLLVMType(irClass.defaultType)) } else { addKotlinGlobal(symbolName, getLLVMType(irClass.defaultType), isExported) } return SingletonLlvmDeclarations(instanceAddress) } private fun createKotlinObjCClassDeclarations(irClass: IrClass): KotlinObjCClassLlvmDeclarations { val internalName = qualifyInternalName(irClass) val isExported = irClass.isExported() val classInfoSymbolName = if (isExported) { irClass.kotlinObjCClassInfoSymbolName } else { "kobjcclassinfo:$internalName" } val classInfoGlobal = staticData.createGlobal( context.llvm.runtime.kotlinObjCClassInfo, classInfoSymbolName, isExported = isExported ).apply { setConstant(true) } val bodyOffsetGlobal = staticData.createGlobal(int32Type, "kobjcbodyoffs:$internalName") return KotlinObjCClassLlvmDeclarations(classInfoGlobal, bodyOffsetGlobal) } override fun visitField(declaration: IrField) { super.visitField(declaration) val containingClass = declaration.parent as? IrClass if (containingClass != null) { if (!containingClass.requiresRtti()) return val classDeclarations = (containingClass.metadata as? CodegenClassMetadata)?.llvm ?: error(containingClass.descriptor.toString()) val allFields = context.getLayoutBuilder(containingClass).fields declaration.metadata = CodegenInstanceFieldMetadata( declaration.metadata?.name, containingClass.konanLibrary, FieldLlvmDeclarations( allFields.indexOf(declaration) + 1, // First field is ObjHeader. classDeclarations.bodyType ) ) } else { // Fields are module-private, so we use internal name: val name = "kvar:" + qualifyInternalName(declaration) val storage = if (declaration.storageKind == FieldStorageKind.THREAD_LOCAL) { addKotlinThreadLocal(name, getLLVMType(declaration.type)) } else { addKotlinGlobal(name, getLLVMType(declaration.type), isExported = false) } declaration.metadata = CodegenStaticFieldMetadata( declaration.metadata?.name, declaration.konanLibrary, StaticFieldLlvmDeclarations(storage) ) } } override fun visitFunction(declaration: IrFunction) { super.visitFunction(declaration) if (!declaration.isReal) return val llvmFunctionType = getLlvmFunctionType(declaration) if ((declaration is IrConstructor && declaration.isObjCConstructor)) { return } val llvmFunction = if (declaration.isExternal) { if (declaration.isTypedIntrinsic || declaration.isObjCBridgeBased() // All call-sites to external accessors to interop properties // are lowered by InteropLowering. || (declaration.isAccessor && declaration.isFromInteropLibrary()) || declaration.annotations.hasAnnotation(RuntimeNames.cCall)) return context.llvm.externalFunction(declaration.computeSymbolName(), llvmFunctionType, // Assume that `external fun` is defined in native libs attached to this module: origin = declaration.llvmSymbolOrigin, independent = declaration.hasAnnotation(RuntimeNames.independent) ) } else { val symbolName = if (declaration.isExported()) { declaration.computeSymbolName().also { if (declaration.name.asString() != "main") { assert(LLVMGetNamedFunction(context.llvm.llvmModule, it) == null) { it } } else { // As a workaround, allow `main` functions to clash because frontend accepts this. // See [OverloadResolver.isTopLevelMainInDifferentFiles] usage. } } } else { "kfun:" + qualifyInternalName(declaration) } addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, symbolName, llvmFunctionType ).also { addLlvmAttributesForKotlinFunction(context, declaration, it) } } declaration.metadata = CodegenFunctionMetadata( declaration.metadata?.name, declaration.konanLibrary, FunctionLlvmDeclarations(llvmFunction) ) } } internal open class KonanMetadata(override val name: Name?, val konanLibrary: KotlinLibrary?) : MetadataSource internal class CodegenClassMetadata(irClass: IrClass) : KonanMetadata(irClass.metadata?.name, irClass.konanLibrary), MetadataSource.Class { var layoutBuilder: ClassLayoutBuilder? = null var llvm: ClassLlvmDeclarations? = null } private class CodegenFunctionMetadata( name: Name?, konanLibrary: KotlinLibrary?, val llvm: FunctionLlvmDeclarations ) : KonanMetadata(name, konanLibrary), MetadataSource.Function private class CodegenInstanceFieldMetadata( name: Name?, konanLibrary: KotlinLibrary?, val llvm: FieldLlvmDeclarations ) : KonanMetadata(name, konanLibrary), MetadataSource.Property { override val isConst = false } private class CodegenStaticFieldMetadata( name: Name?, konanLibrary: KotlinLibrary?, val llvm: StaticFieldLlvmDeclarations ) : KonanMetadata(name, konanLibrary), MetadataSource.Property { override val isConst = false } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmLinkOptions.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.LLVMAddNamedMetadataOperand import llvm.LLVMModuleRef fun embedLlvmLinkOptions(module: LLVMModuleRef, options: List>) { options.forEach { val node = node(*it.map { it.mdString() }.toTypedArray()) LLVMAddNamedMetadataOperand(module, "llvm.linker.options", node) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin private val llvmContextHolder = ThreadLocal() internal var llvmContext: LLVMContextRef get() = llvmContextHolder.get() set(value) { llvmContextHolder.set(value) } internal fun tryDisposeLLVMContext() { val llvmContext = llvmContextHolder.get() if (llvmContext != null) LLVMContextDispose(llvmContext) llvmContextHolder.remove() } internal val LLVMTypeRef.context: LLVMContextRef get() = LLVMGetTypeContext(this)!! internal val List.context: LLVMContextRef get() { val context = this[0].context for (i in 1 until this.size) assert(this[i].context == context) { "Expected the same context for all types in a list" } return context } internal val LLVMValueRef.type: LLVMTypeRef get() = LLVMTypeOf(this)!! /** * Represents the value which can be emitted as bitcode const value */ internal interface ConstValue { val llvm: LLVMValueRef } internal val ConstValue.llvmType: LLVMTypeRef get() = this.llvm.type internal interface ConstPointer : ConstValue { fun getElementPtr(index: Int): ConstPointer = ConstGetElementPtr(this, index) } internal fun constPointer(value: LLVMValueRef) = object : ConstPointer { init { assert(LLVMIsConstant(value) == 1) } override val llvm = value } private class ConstGetElementPtr(val pointer: ConstPointer, val index: Int) : ConstPointer { override val llvm = LLVMConstInBoundsGEP(pointer.llvm, cValuesOf(Int32(0).llvm, Int32(index).llvm), 2)!! // TODO: squash multiple GEPs } internal fun ConstPointer.bitcast(toType: LLVMTypeRef) = constPointer(LLVMConstBitCast(this.llvm, toType)!!) internal class ConstArray(elementType: LLVMTypeRef?, val elements: List) : ConstValue { init { elements.forEach { assert(it.llvmType == elementType) { "Expected element type: ${llvmtype2string(elementType)}, actual: ${llvmtype2string(it.llvmType)}" } } } override val llvm = LLVMConstArray(elementType, elements.map { it.llvm }.toCValues(), elements.size)!! } internal open class Struct(val type: LLVMTypeRef?, val elements: List) : ConstValue { constructor(type: LLVMTypeRef?, vararg elements: ConstValue?) : this(type, elements.toList()) constructor(vararg elements: ConstValue) : this(structType(elements.map { it.llvmType }), *elements) override val llvm = LLVMConstNamedStruct(type, elements.mapIndexed { index, element -> val expectedType = LLVMStructGetTypeAtIndex(type, index) if (element == null) { LLVMConstNull(expectedType)!! } else { element.llvm.also { assert(it.type == expectedType) { "Unexpected type at $index: expected ${LLVMPrintTypeToString(expectedType)!!.toKString()} " + "got ${LLVMPrintTypeToString(it.type)!!.toKString()}" } } } }.toCValues(), elements.size)!! init { assert(elements.size == LLVMCountStructElementTypes(type)) } } internal val int1Type get() = LLVMInt1TypeInContext(llvmContext)!! internal val int8Type get() = LLVMInt8TypeInContext(llvmContext)!! internal val int16Type get() = LLVMInt16TypeInContext(llvmContext)!! internal val int32Type get() = LLVMInt32TypeInContext(llvmContext)!! internal val int64Type get() = LLVMInt64TypeInContext(llvmContext)!! internal val int8TypePtr get() = pointerType(int8Type) internal val floatType get() = LLVMFloatTypeInContext(llvmContext)!! internal val doubleType get() = LLVMDoubleTypeInContext(llvmContext)!! internal val vector128Type get() = LLVMVectorType(floatType, 4)!! internal val voidType get() = LLVMVoidTypeInContext(llvmContext)!! internal class Int1(val value: Byte) : ConstValue { override val llvm = LLVMConstInt(int1Type, value.toLong(), 1)!! } internal class Int8(val value: Byte) : ConstValue { override val llvm = LLVMConstInt(int8Type, value.toLong(), 1)!! } internal class Int16(val value: Short) : ConstValue { override val llvm = LLVMConstInt(int16Type, value.toLong(), 1)!! } internal class Char16(val value: Char) : ConstValue { override val llvm = LLVMConstInt(int16Type, value.toLong(), 1)!! } internal class Int32(val value: Int) : ConstValue { override val llvm = LLVMConstInt(int32Type, value.toLong(), 1)!! } internal class Int64(val value: Long) : ConstValue { override val llvm = LLVMConstInt(int64Type, value, 1)!! } internal class Float32(val value: Float) : ConstValue { override val llvm = LLVMConstReal(floatType, value.toDouble())!! } internal class Float64(val value: Double) : ConstValue { override val llvm = LLVMConstReal(doubleType, value)!! } internal class Zero(val type: LLVMTypeRef) : ConstValue { override val llvm = LLVMConstNull(type)!! } internal class NullPointer(pointeeType: LLVMTypeRef): ConstPointer { override val llvm = LLVMConstNull(pointerType(pointeeType))!! } internal fun constValue(value: LLVMValueRef) = object : ConstValue { init { assert (LLVMIsConstant(value) == 1) } override val llvm = value } internal val RuntimeAware.kTypeInfo: LLVMTypeRef get() = runtime.typeInfoType internal val RuntimeAware.kObjHeader: LLVMTypeRef get() = runtime.objHeaderType internal val RuntimeAware.kObjHeaderPtr: LLVMTypeRef get() = pointerType(kObjHeader) internal val RuntimeAware.kObjHeaderPtrPtr: LLVMTypeRef get() = pointerType(kObjHeaderPtr) internal val RuntimeAware.kArrayHeader: LLVMTypeRef get() = runtime.arrayHeaderType internal val RuntimeAware.kArrayHeaderPtr: LLVMTypeRef get() = pointerType(kArrayHeader) internal val RuntimeAware.kTypeInfoPtr: LLVMTypeRef get() = pointerType(kTypeInfo) internal val kInt1 get() = int1Type internal val kBoolean get() = kInt1 internal val kInt8Ptr get() = pointerType(int8Type) internal val kInt8PtrPtr get() = pointerType(kInt8Ptr) internal val kNullInt8Ptr get() = LLVMConstNull(kInt8Ptr)!! internal val kImmInt32Zero get() = Int32(0).llvm internal val kImmInt32One get() = Int32(1).llvm internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef get() = LLVMConstNull(this.kObjHeaderPtr)!! internal val ContextUtils.kNullObjHeaderPtrPtr: LLVMValueRef get() = LLVMConstNull(this.kObjHeaderPtrPtr)!! // Nothing type has no values, but we do generate unreachable code and thus need some fake value: internal val ContextUtils.kNothingFakeValue: LLVMValueRef get() = LLVMGetUndef(kObjHeaderPtr)!! internal fun pointerType(pointeeType: LLVMTypeRef) = LLVMPointerType(pointeeType, 0)!! internal fun structType(vararg types: LLVMTypeRef): LLVMTypeRef = structType(types.toList()) internal fun structType(types: List): LLVMTypeRef = LLVMStructTypeInContext(llvmContext, types.toCValues(), types.size, 0)!! internal fun ContextUtils.numParameters(functionType: LLVMTypeRef) : Int { // Note that type is usually function pointer, so we have to dereference it. return LLVMCountParamTypes(LLVMGetElementType(functionType)) } fun extractConstUnsignedInt(value: LLVMValueRef): Long { assert(LLVMIsConstant(value) != 0) return LLVMConstIntGetZExtValue(value) } internal fun ContextUtils.isObjectReturn(functionType: LLVMTypeRef) : Boolean { // Note that type is usually function pointer, so we have to dereference it. val returnType = LLVMGetReturnType(LLVMGetElementType(functionType))!! return isObjectType(returnType) } internal fun ContextUtils.isObjectRef(value: LLVMValueRef): Boolean { return isObjectType(value.type) } internal fun RuntimeAware.isObjectType(type: LLVMTypeRef): Boolean { return type == kObjHeaderPtr || type == kArrayHeaderPtr } /** * Reads [size] bytes contained in this array. */ internal fun CArrayPointer.getBytes(size: Long) = (0 .. size-1).map { this[it] }.toByteArray() internal fun getFunctionType(ptrToFunction: LLVMValueRef): LLVMTypeRef { return getGlobalType(ptrToFunction) } internal fun getGlobalType(ptrToGlobal: LLVMValueRef): LLVMTypeRef { return LLVMGetElementType(ptrToGlobal.type)!! } internal fun ContextUtils.addGlobal(name: String, type: LLVMTypeRef, isExported: Boolean): LLVMValueRef { if (isExported) assert(LLVMGetNamedGlobal(context.llvmModule, name) == null) return LLVMAddGlobal(context.llvmModule, type, name)!! } internal fun ContextUtils.importGlobal(name: String, type: LLVMTypeRef, origin: CompiledKlibModuleOrigin): LLVMValueRef { context.llvm.imports.add(origin) val found = LLVMGetNamedGlobal(context.llvmModule, name) return if (found != null) { assert (getGlobalType(found) == type) assert (LLVMGetInitializer(found) == null) { "$name is already declared in the current module" } found } else { addGlobal(name, type, isExported = false) } } internal abstract class AddressAccess { abstract fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef } internal class GlobalAddressAccess(private val address: LLVMValueRef): AddressAccess() { override fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef = address } internal class TLSAddressAccess( private val context: Context, private val index: Int): AddressAccess() { override fun getAddress(generationContext: FunctionGenerationContext?): LLVMValueRef { return generationContext!!.call(context.llvm.lookupTLS, listOf(context.llvm.tlsKey, Int32(index).llvm)) } } internal fun ContextUtils.addKotlinThreadLocal(name: String, type: LLVMTypeRef): AddressAccess { return if (isObjectType(type)) { val index = context.llvm.tlsCount++ TLSAddressAccess(context, index) } else { // TODO: This will break if Workers get decoupled from host threads. GlobalAddressAccess(LLVMAddGlobal(context.llvmModule, type, name)!!.also { LLVMSetThreadLocalMode(it, context.llvm.tlsMode) LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) }) } } internal fun ContextUtils.addKotlinGlobal(name: String, type: LLVMTypeRef, isExported: Boolean): AddressAccess { return GlobalAddressAccess(LLVMAddGlobal(context.llvmModule, type, name)!!.also { if (!isExported) LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) }) } internal fun functionType(returnType: LLVMTypeRef, isVarArg: Boolean = false, vararg paramTypes: LLVMTypeRef) = LLVMFunctionType( returnType, cValuesOf(*paramTypes), paramTypes.size, if (isVarArg) 1 else 0 )!! internal fun functionType(returnType: LLVMTypeRef, isVarArg: Boolean = false, paramTypes: List) = functionType(returnType, isVarArg, *paramTypes.toTypedArray()) fun llvm2string(value: LLVMValueRef?): String { if (value == null) return "" return LLVMPrintValueToString(value)!!.toKString() } fun llvmtype2string(type: LLVMTypeRef?): String { if (type == null) return "" return LLVMPrintTypeToString(type)!!.toKString() } fun getStructElements(type: LLVMTypeRef): List { val count = LLVMCountStructElementTypes(type) return (0 until count).map { LLVMStructGetTypeAtIndex(type, it)!! } } fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped { val bufRef = alloc() val errorRef = allocPointerTo() val res = LLVMCreateMemoryBufferWithContentsOfFile(path, bufRef.ptr, errorRef.ptr) if (res != 0) { throw Error(errorRef.value?.toKString()) } val memoryBuffer = bufRef.value try { val moduleRef = alloc() val parseRes = LLVMParseBitcodeInContext2(llvmContext, memoryBuffer, moduleRef.ptr) if (parseRes != 0) { throw Error(parseRes.toString()) } moduleRef.value!! } finally { LLVMDisposeMemoryBuffer(memoryBuffer) } } private val nounwindAttrKindId by lazy { getLlvmAttributeKindId("nounwind") } private val noreturnAttrKindId by lazy { getLlvmAttributeKindId("noreturn") } private val noinlineAttrKindId by lazy { getLlvmAttributeKindId("noinline") } private val signextAttrKindId by lazy { getLlvmAttributeKindId("signext") } fun isFunctionNoUnwind(function: LLVMValueRef): Boolean { val attribute = LLVMGetEnumAttributeAtIndex(function, LLVMAttributeFunctionIndex, nounwindAttrKindId.value) return attribute != null } internal fun getLlvmAttributeKindId(attributeName: String): LLVMAttributeKindId { val attrKindId = LLVMGetEnumAttributeKindForName(attributeName, attributeName.length.signExtend()) if (attrKindId == 0) { throw Error("Unable to find '$attributeName' attribute kind id") } return LLVMAttributeKindId(attrKindId) } data class LLVMAttributeKindId(val value: Int) fun setFunctionNoUnwind(function: LLVMValueRef) { addLlvmFunctionEnumAttribute(function, nounwindAttrKindId) } fun setFunctionNoReturn(function: LLVMValueRef) { addLlvmFunctionEnumAttribute(function, noreturnAttrKindId) } fun setFunctionNoInline(function: LLVMValueRef) { addLlvmFunctionEnumAttribute(function, noinlineAttrKindId) } internal fun addLlvmFunctionEnumAttribute(function: LLVMValueRef, attrKindId: LLVMAttributeKindId, value: Long = 0) { val attribute = createLlvmEnumAttribute(LLVMGetTypeContext(function.type)!!, attrKindId, value) addLlvmFunctionAttribute(function, attribute) } internal fun createLlvmEnumAttribute(llvmContext: LLVMContextRef, attrKindId: LLVMAttributeKindId, value: Long = 0) = LLVMCreateEnumAttribute(llvmContext, attrKindId.value, value)!! internal fun addLlvmFunctionAttribute(function: LLVMValueRef, attribute: LLVMAttributeRef) { LLVMAddAttributeAtIndex(function, LLVMAttributeFunctionIndex, attribute) } fun addFunctionSignext(function: LLVMValueRef, index: Int, type: LLVMTypeRef?) { if (type == int1Type || type == int8Type || type == int16Type) { val attribute = createLlvmEnumAttribute(LLVMGetTypeContext(function.type)!!, signextAttrKindId) LLVMAddAttributeAtIndex(function, index, attribute) } } internal fun String.mdString() = LLVMMDStringInContext(llvmContext, this, this.length)!! internal fun node(vararg it:LLVMValueRef) = LLVMMDNodeInContext(llvmContext, it.toList().toCValues(), it.size) internal fun LLVMValueRef.setUnaligned() = apply { LLVMSetAlignment(this, 1) } internal fun getOperands(value: LLVMValueRef) = (0 until LLVMGetNumOperands(value)).map { LLVMGetOperand(value, it)!! } internal fun getGlobalAliases(module: LLVMModuleRef) = generateSequence(LLVMGetFirstGlobalAlias(module), { LLVMGetNextGlobalAlias(it) }) internal fun getFunctions(module: LLVMModuleRef) = generateSequence(LLVMGetFirstFunction(module), { LLVMGetNextFunction(it) }) internal fun getGlobals(module: LLVMModuleRef) = generateSequence(LLVMGetFirstGlobal(module), { LLVMGetNextGlobal(it) }) fun LLVMTypeRef.isFloatingPoint(): Boolean = when (llvm.LLVMGetTypeKind(this)) { LLVMTypeKind.LLVMFloatTypeKind, LLVMTypeKind.LLVMDoubleTypeKind -> true else -> false } fun LLVMTypeRef.isVectorElementType(): Boolean = when (llvm.LLVMGetTypeKind(this)) { LLVMTypeKind.LLVMIntegerTypeKind, LLVMTypeKind.LLVMFloatTypeKind, LLVMTypeKind.LLVMDoubleTypeKind -> true else -> false } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.isExternalObjCClassMethod import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.isPublicApi import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.isAnnotationClass import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.name.FqName internal class RTTIGenerator(override val context: Context) : ContextUtils { private val acyclicCache = mutableMapOf() private val safeAcyclicFieldTypes = setOf( context.irBuiltIns.stringClass, context.irBuiltIns.booleanClass, context.irBuiltIns.charClass, context.irBuiltIns.byteClass, context.irBuiltIns.shortClass, context.irBuiltIns.intClass, context.irBuiltIns.longClass, context.irBuiltIns.floatClass,context.irBuiltIns.doubleClass) + context.ir.symbols.primitiveArrays.values + context.ir.symbols.unsignedArrays.values // TODO: extend logic here by taking into account final acyclic classes. private fun checkAcyclicFieldType(type: IrType): Boolean = acyclicCache.getOrPut(type) { when { type.isInterface() -> false type.computePrimitiveBinaryTypeOrNull() != null -> true else -> { val classifier = type.classifierOrNull (classifier != null && classifier in safeAcyclicFieldTypes) } } } private fun checkAcyclicClass(irClass: IrClass): Boolean = when { irClass.symbol == context.ir.symbols.array -> false irClass.isArray -> true context.getLayoutBuilder(irClass).fields.all { checkAcyclicFieldType(it.type) } -> true else -> false } private fun flagsFromClass(irClass: IrClass): Int { var result = 0 if (irClass.isFrozen) result = result or TF_IMMUTABLE // TODO: maybe perform deeper analysis to find surely acyclic types. if (!irClass.isInterface && !irClass.isAbstract() && !irClass.isAnnotationClass) { if (checkAcyclicClass(irClass)) { result = result or TF_ACYCLIC } } if (irClass.hasAnnotation(KonanFqNames.leakDetectorCandidate)) { result = result or TF_LEAK_DETECTOR_CANDIDATE } if (irClass.isInterface) result = result or TF_INTERFACE if (irClass.defaultType.isSuspendFunction()) { result = result or TF_SUSPEND_FUNCTION } if (irClass.hasAnnotation(KonanFqNames.hasFinalizer)) { result = result or TF_HAS_FINALIZER } if (irClass.hasAnnotation(KonanFqNames.hasFreezeHook)) { result = result or TF_HAS_FREEZE_HOOK } return result } inner class MethodTableRecord(val nameSignature: LocalHash, methodEntryPoint: ConstPointer?) : Struct(runtime.methodTableRecordType, nameSignature, methodEntryPoint) inner class InterfaceTableRecord(id: Int32, vtableSize: Int32, vtable: ConstPointer?) : Struct(runtime.interfaceTableRecordType, id, vtableSize, vtable) private inner class TypeInfo( selfPtr: ConstPointer, extendedInfo: ConstPointer, size: Int, superType: ConstValue, objOffsets: ConstValue, objOffsetsCount: Int, interfaces: ConstValue, interfacesCount: Int, methods: ConstValue, methodsCount: Int, interfaceTableSize: Int, interfaceTable: ConstValue, packageName: String?, relativeName: String?, flags: Int, classId: Int, writableTypeInfo: ConstPointer?, associatedObjects: ConstPointer?) : Struct( runtime.typeInfoType, selfPtr, extendedInfo, // TODO: it used to be a single int32 ABI version, // but klib abi version is not an int anymore. // So now this field is just reserved to preserve the layout. Int32(0), Int32(size), superType, objOffsets, Int32(objOffsetsCount), interfaces, Int32(interfacesCount), methods, Int32(methodsCount), Int32(interfaceTableSize), interfaceTable, kotlinStringLiteral(packageName), kotlinStringLiteral(relativeName), Int32(flags), Int32(classId), *listOfNotNull(writableTypeInfo).toTypedArray(), associatedObjects ) private fun kotlinStringLiteral(string: String?): ConstPointer = if (string == null) { NullPointer(runtime.objHeaderType) } else { staticData.kotlinStringLiteral(string) } private val EXPORT_TYPE_INFO_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "ExportTypeInfo")) private fun exportTypeInfoIfRequired(irClass: IrClass, typeInfoGlobal: LLVMValueRef?) { val annotation = irClass.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME) if (annotation != null) { val name = annotation.getAnnotationStringValue()!! // TODO: use LLVMAddAlias. val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true) LLVMSetInitializer(global, typeInfoGlobal) } } private val arrayClasses = mapOf( IdSignatureValues.array to kObjHeaderPtr, primitiveArrayTypesSignatures[PrimitiveType.BYTE] to int8Type, primitiveArrayTypesSignatures[PrimitiveType.CHAR] to int16Type, primitiveArrayTypesSignatures[PrimitiveType.SHORT] to int16Type, primitiveArrayTypesSignatures[PrimitiveType.INT] to int32Type, primitiveArrayTypesSignatures[PrimitiveType.LONG] to int64Type, primitiveArrayTypesSignatures[PrimitiveType.FLOAT] to floatType, primitiveArrayTypesSignatures[PrimitiveType.DOUBLE] to doubleType, primitiveArrayTypesSignatures[PrimitiveType.BOOLEAN] to int8Type, IdSignatureValues.string to int16Type, getPublicSignature(KonanFqNames.packageName, "ImmutableBlob") to int8Type, getPublicSignature(KonanFqNames.internalPackageName, "NativePtrArray") to kInt8Ptr ) // Keep in sync with Konan_RuntimeType. private val runtimeTypeMap = mapOf( kObjHeaderPtr to 1, int8Type to 2, int16Type to 3, int32Type to 4, int64Type to 5, floatType to 6, doubleType to 7, kInt8Ptr to 8, int1Type to 9, vector128Type to 10 ) private fun getElementType(irClass: IrClass): LLVMTypeRef? = if (irClass.symbol.isPublicApi) arrayClasses[irClass.symbol.signature as IdSignature.PublicSignature] else null private fun getInstanceSize(classType: LLVMTypeRef?, irClass: IrClass) : Int { val elementType = getElementType(irClass) // Check if it is an array. if (elementType != null) return -LLVMABISizeOfType(llvmTargetData, elementType).toInt() return LLVMStoreSizeOfType(llvmTargetData, classType).toInt() } private fun getClassId(irClass: IrClass): Int { if (irClass.isKotlinObjCClass()) return 0 val hierarchyInfo = if (context.ghaEnabled()) { context.getLayoutBuilder(irClass).hierarchyInfo } else { ClassGlobalHierarchyInfo.DUMMY } return if (irClass.isInterface) { hierarchyInfo.interfaceId } else { hierarchyInfo.classIdLo } } fun generate(irClass: IrClass) { val className = irClass.fqNameForIrSerialization val llvmDeclarations = context.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType val instanceSize = getInstanceSize(bodyType, irClass) val superType = when { irClass.isAny() -> NullPointer(runtime.typeInfoType) irClass.isKotlinObjCClass() -> context.ir.symbols.any.owner.typeInfoPtr else -> { val superTypeOrAny = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner superTypeOrAny.typeInfoPtr } } val implementedInterfaces = irClass.implementedInterfaces.filter { it.requiresRtti() } val interfaces = implementedInterfaces.map { it.typeInfoPtr } val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className", pointerType(runtime.typeInfoType), interfaces) val objOffsets = getObjOffsets(bodyType) val objOffsetsPtr = staticData.placeGlobalConstArray("krefs:$className", int32Type, objOffsets) val objOffsetsCount = if (irClass.descriptor == context.builtIns.array) { 1 // To mark it as non-leaf. } else { objOffsets.size } val methods = if (irClass.isAbstract()) { emptyList() } else { methodTableRecords(irClass) } val methodsPtr = staticData.placeGlobalConstArray("kmethods:$className", runtime.methodTableRecordType, methods) val needInterfaceTable = context.ghaEnabled() && !irClass.isInterface && !irClass.isAbstract() && !irClass.isObjCClass() val (interfaceTable, interfaceTableSize) = if (needInterfaceTable) { interfaceTableRecords(irClass) } else { Pair(emptyList(), -1) } val interfaceTablePtr = staticData.placeGlobalConstArray("kifacetable:$className", runtime.interfaceTableRecordType, interfaceTable) val reflectionInfo = getReflectionInfo(irClass) val typeInfoGlobal = llvmDeclarations.typeInfoGlobal val typeInfo = TypeInfo( irClass.typeInfoPtr, makeExtendedInfo(irClass), instanceSize, superType, objOffsetsPtr, objOffsetsCount, interfacesPtr, interfaces.size, methodsPtr, methods.size, interfaceTableSize, interfaceTablePtr, reflectionInfo.packageName, reflectionInfo.relativeName, flagsFromClass(irClass), getClassId(irClass), llvmDeclarations.writableTypeInfoGlobal?.pointer, associatedObjects = genAssociatedObjects(irClass) ) val typeInfoGlobalValue = if (!irClass.typeInfoHasVtableAttached) { typeInfo } else { val vtable = vtable(irClass) Struct(typeInfo, vtable) } typeInfoGlobal.setInitializer(typeInfoGlobalValue) typeInfoGlobal.setConstant(true) exportTypeInfoIfRequired(irClass, irClass.llvmTypeInfoPtr) } private fun getObjOffsets(bodyType: LLVMTypeRef): List = getStructElements(bodyType).mapIndexedNotNull { index, type -> if (isObjectType(type)) { LLVMOffsetOfElement(llvmTargetData, bodyType, index) } else { null } }.map { Int32(it.toInt()) } fun vtable(irClass: IrClass): ConstArray { // TODO: compile-time resolution limits binary compatibility. val vtableEntries = context.getLayoutBuilder(irClass).vtableEntries.map { val implementation = it.implementation if (implementation == null || implementation.isExternalObjCClassMethod() || context.referencedFunctions?.contains(implementation) == false) { NullPointer(int8Type) } else { implementation.entryPointAddress } } return ConstArray(int8TypePtr, vtableEntries) } fun methodTableRecords(irClass: IrClass): List { val functionNames = mutableMapOf() return context.getLayoutBuilder(irClass).methodTableEntries.map { val functionName = it.overriddenFunction.computeFunctionName() val nameSignature = functionName.localHash val previous = functionNames.putIfAbsent(nameSignature.value, it) if (previous != null) throw AssertionError("Duplicate method table entry: functionName = '$functionName', hash = '${nameSignature.value}', entry1 = $previous, entry2 = $it") // TODO: compile-time resolution limits binary compatibility. val implementation = it.implementation val methodEntryPoint = if (implementation == null || context.referencedFunctions?.contains(implementation) == false) null else implementation.entryPointAddress MethodTableRecord(nameSignature, methodEntryPoint) }.sortedBy { it.nameSignature.value } } fun interfaceTableRecords(irClass: IrClass): Pair, Int> { // The details are in ClassLayoutBuilder. val interfaces = irClass.implementedInterfaces val (interfaceTableSkeleton, interfaceTableSize) = interfaceTableSkeleton(interfaces) val interfaceTableEntries = interfaceTableRecords(irClass, interfaceTableSkeleton) return Pair(interfaceTableEntries, interfaceTableSize) } private fun interfaceTableSkeleton(interfaces: List): Pair, Int> { val interfaceLayouts = interfaces.map { context.getLayoutBuilder(it) } val interfaceColors = interfaceLayouts.map { it.hierarchyInfo.interfaceColor } // Find the optimal size. It must be a power of 2. var size = 1 val maxSize = 1 shl ClassGlobalHierarchyInfo.MAX_BITS_PER_COLOR val used = BooleanArray(maxSize) while (size <= maxSize) { for (i in 0 until size) used[i] = false // Check for collisions. var ok = true for (color in interfaceColors) { val index = color % size if (used[index]) { ok = false break } used[index] = true } if (ok) break size *= 2 } val conservative = size > maxSize val interfaceTableSkeleton = if (conservative) { size = interfaceLayouts.size interfaceLayouts.sortedBy { it.hierarchyInfo.interfaceId }.toTypedArray() } else arrayOfNulls(size).also { for (interfaceLayout in interfaceLayouts) it[interfaceLayout.hierarchyInfo.interfaceId % size] = interfaceLayout } val interfaceTableSize = if (conservative) -size else (size - 1) return Pair(interfaceTableSkeleton, interfaceTableSize) } private fun interfaceTableRecords( irClass: IrClass, interfaceTableSkeleton: Array ): List { val methodTableEntries = context.getLayoutBuilder(irClass).methodTableEntries val className = irClass.fqNameForIrSerialization return interfaceTableSkeleton.map { iface -> val interfaceId = iface?.hierarchyInfo?.interfaceId ?: 0 InterfaceTableRecord( Int32(interfaceId), Int32(iface?.interfaceTableEntries?.size ?: 0), if (iface == null) NullPointer(kInt8Ptr) else { val vtableEntries = iface.interfaceTableEntries.map { ifaceFunction -> val impl = OverriddenFunctionInfo( methodTableEntries.first { ifaceFunction in it.function.allOverriddenFunctions }.function, ifaceFunction ).implementation if (impl == null || context.referencedFunctions?.contains(impl) == false) NullPointer(int8Type) else impl.entryPointAddress } staticData.placeGlobalConstArray("kifacevtable:${className}_$interfaceId", kInt8Ptr, vtableEntries ) } ) } } private fun mapRuntimeType(type: LLVMTypeRef): Int = runtimeTypeMap[type] ?: throw Error("Unmapped type: ${llvmtype2string(type)}") private val debugRuntimeOrNull: LLVMModuleRef? by lazy { context.config.runtimeNativeLibraries.singleOrNull { it.endsWith("debug.bc")}?.let { parseBitcodeFile(it) } } private val debugOperations: ConstValue by lazy { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! val local = LLVMAddGlobal(context.llvmModule, LLVMGetElementType(LLVMTypeOf(external)),"Konan_debugOperationsList")!! constPointer(LLVMConstBitCast(local, kInt8PtrPtr)!!) } else { Zero(kInt8PtrPtr) } } val debugOperationsSize: ConstValue by lazy { if (debugRuntimeOrNull != null) { val external = LLVMGetNamedGlobal(debugRuntimeOrNull, "Konan_debugOperationsList")!! Int32(LLVMGetArrayLength(LLVMGetElementType(LLVMTypeOf(external)))) } else Int32(0) } private fun makeExtendedInfo(irClass: IrClass): ConstPointer { // TODO: shall we actually do that? if (context.shouldOptimize()) return NullPointer(runtime.extendedTypeInfoType) val className = irClass.fqNameForIrSerialization.toString() val llvmDeclarations = context.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType val elementType = getElementType(irClass) val value = if (elementType != null) { // An array type. val runtimeElementType = mapRuntimeType(elementType) Struct(runtime.extendedTypeInfoType, Int32(-runtimeElementType), NullPointer(int32Type), NullPointer(int8Type), NullPointer(kInt8Ptr), debugOperationsSize, debugOperations) } else { data class FieldRecord(val offset: Int, val type: Int, val name: String) val fields = getStructElements(bodyType).drop(1).mapIndexed { index, type -> FieldRecord( LLVMOffsetOfElement(llvmTargetData, bodyType, index + 1).toInt(), mapRuntimeType(type), context.getLayoutBuilder(irClass).fields[index].name.asString()) } val offsetsPtr = staticData.placeGlobalConstArray("kextoff:$className", int32Type, fields.map { Int32(it.offset) }) val typesPtr = staticData.placeGlobalConstArray("kexttype:$className", int8Type, fields.map { Int8(it.type.toByte()) }) val namesPtr = staticData.placeGlobalConstArray("kextname:$className", kInt8Ptr, fields.map { staticData.placeCStringLiteral(it.name) }) Struct(runtime.extendedTypeInfoType, Int32(fields.size), offsetsPtr, typesPtr, namesPtr, debugOperationsSize, debugOperations) } val result = staticData.placeGlobal("", value) result.setConstant(true) return result.pointer } private fun genAssociatedObjects(irClass: IrClass): ConstPointer? { val associatedObjects = context.getLayoutBuilder(irClass).associatedObjects if (associatedObjects.isEmpty()) { return null } val associatedObjectTableRecords = associatedObjects.map { (key, value) -> val associatedObjectGetter = generateFunction( CodeGenerator(context), functionType(kObjHeaderPtr, false, kObjHeaderPtrPtr), "" ) { ret(getObjectValue(value, ExceptionHandler.Caller, startLocationInfo = null)) } Struct(runtime.associatedObjectTableRecordType, key.typeInfoPtr, constPointer(associatedObjectGetter)) } return staticData.placeGlobalConstArray( name = "kassociatedobjects:${irClass.fqNameForIrSerialization}", elemType = runtime.associatedObjectTableRecordType, elements = associatedObjectTableRecords + Struct(runtime.associatedObjectTableRecordType, null, null) ) } // TODO: extract more code common with generate(). fun generateSyntheticInterfaceImpl( irClass: IrClass, methodImpls: Map, bodyType: LLVMTypeRef, immutable: Boolean = false ): ConstPointer { assert(irClass.isInterface) val size = LLVMStoreSizeOfType(llvmTargetData, bodyType).toInt() val superClass = context.ir.symbols.any.owner assert(superClass.implementedInterfaces.isEmpty()) val interfaces = (listOf(irClass) + irClass.implementedInterfaces) val interfacesPtr = staticData.placeGlobalConstArray("", pointerType(runtime.typeInfoType), interfaces.map { it.typeInfoPtr }) assert(superClass.declarations.all { it !is IrProperty && it !is IrField }) val objOffsets = getObjOffsets(bodyType) val objOffsetsPtr = staticData.placeGlobalConstArray("", int32Type, objOffsets) val objOffsetsCount = objOffsets.size val methods = (methodTableRecords(superClass) + methodImpls.map { (method, impl) -> assert(method.parent == irClass) MethodTableRecord(method.computeFunctionName().localHash, impl.bitcast(int8TypePtr)) }).sortedBy { it.nameSignature.value }.also { assert(it.distinctBy { it.nameSignature.value } == it) } val methodsPtr = staticData.placeGlobalConstArray("", runtime.methodTableRecordType, methods) val reflectionInfo = ReflectionInfo(null, null) val writableTypeInfoType = runtime.writableTypeInfoType val writableTypeInfo = if (writableTypeInfoType == null) { null } else { staticData.createGlobal(writableTypeInfoType, "") .also { it.setZeroInitializer() } .pointer } val vtable = vtable(superClass) val typeInfoWithVtableType = structType(runtime.typeInfoType, vtable.llvmType) val typeInfoWithVtableGlobal = staticData.createGlobal(typeInfoWithVtableType, "", isExported = false) val result = typeInfoWithVtableGlobal.pointer.getElementPtr(0) val typeHierarchyInfo = if (!context.ghaEnabled()) ClassGlobalHierarchyInfo.DUMMY else ClassGlobalHierarchyInfo(-1, -1, 0, 0) // TODO: interfaces (e.g. FunctionN and Function) should have different colors. val (interfaceTableSkeleton, interfaceTableSize) = if (context.ghaEnabled()) interfaceTableSkeleton(interfaces) else Pair(emptyArray(), -1) val interfaceTable = interfaceTableSkeleton.map { layoutBuilder -> if (layoutBuilder == null) { InterfaceTableRecord(Int32(0), Int32(0), null) } else { val vtableEntries = layoutBuilder.interfaceTableEntries.map { methodImpls[it]!!.bitcast(int8TypePtr) } val interfaceVTable = staticData.placeGlobalArray("", kInt8Ptr, vtableEntries) InterfaceTableRecord( Int32(layoutBuilder.hierarchyInfo.interfaceId), Int32(layoutBuilder.interfaceTableEntries.size), interfaceVTable.pointer.getElementPtr(0) ) } } val interfaceTablePtr = staticData.placeGlobalConstArray("", runtime.interfaceTableRecordType, interfaceTable) val typeInfoWithVtable = Struct(TypeInfo( selfPtr = result, extendedInfo = NullPointer(runtime.extendedTypeInfoType), size = size, superType = superClass.typeInfoPtr, objOffsets = objOffsetsPtr, objOffsetsCount = objOffsetsCount, interfaces = interfacesPtr, interfacesCount = interfaces.size, methods = methodsPtr, methodsCount = methods.size, interfaceTableSize = interfaceTableSize, interfaceTable = interfaceTablePtr, packageName = reflectionInfo.packageName, relativeName = reflectionInfo.relativeName, flags = flagsFromClass(irClass) or (if (immutable) TF_IMMUTABLE else 0), classId = typeHierarchyInfo.classIdLo, writableTypeInfo = writableTypeInfo, associatedObjects = null ), vtable) typeInfoWithVtableGlobal.setInitializer(typeInfoWithVtable) typeInfoWithVtableGlobal.setConstant(true) return result } private val OverriddenFunctionInfo.implementation get() = getImplementation(context) data class ReflectionInfo(val packageName: String?, val relativeName: String?) private fun getReflectionInfo(irClass: IrClass): ReflectionInfo = when { irClass.isAnonymousObject -> ReflectionInfo(packageName = null, relativeName = null) irClass.isLocal -> ReflectionInfo(packageName = null, relativeName = irClass.name.asString()) else -> ReflectionInfo( packageName = irClass.findPackage().fqNameForIrSerialization.asString(), relativeName = generateSequence(irClass) { it.parent as? IrClass } .toList().reversed() .joinToString(".") { it.name.asString() } ) } fun dispose() { debugRuntimeOrNull?.let { LLVMDisposeModule(it) } } } // Keep in sync with Konan_TypeFlags in TypeInfo.h. private const val TF_IMMUTABLE = 1 private const val TF_ACYCLIC = 2 private const val TF_INTERFACE = 4 private const val TF_OBJC_DYNAMIC = 8 private const val TF_LEAK_DETECTOR_CANDIDATE = 16 private const val TF_SUSPEND_FUNCTION = 32 private const val TF_HAS_FINALIZER = 64 private const val TF_HAS_FREEZE_HOOK = 128 ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RetainAnnotation.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.util.findAnnotation import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.name.FqName private val retainAnnotationName = FqName("kotlin.native.Retain") private val retainForTargetAnnotationName = FqName("kotlin.native.RetainForTarget") internal fun IrFunction.retainAnnotation(target: KonanTarget): Boolean { if (this.annotations.findAnnotation(retainAnnotationName) != null) return true val forTarget = this.annotations.findAnnotation(retainForTargetAnnotationName) if (forTarget != null && forTarget.getAnnotationStringValue() == target.name) return true return false } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.declarations.IrFunction interface RuntimeAware { val runtime: Runtime } class Runtime(bitcodeFile: String) { val llvmModule: LLVMModuleRef = parseBitcodeFile(bitcodeFile) val calculatedLLVMTypes: MutableMap = HashMap() val addedLLVMExternalFunctions: MutableMap = HashMap() internal fun getStructTypeOrNull(name: String) = LLVMGetTypeByName(llvmModule, "struct.$name") internal fun getStructType(name: String) = getStructTypeOrNull(name) ?: throw Error("struct.$name is not found in the Runtime module.") val typeInfoType = getStructType("TypeInfo") val extendedTypeInfoType = getStructType("ExtendedTypeInfo") val writableTypeInfoType = getStructTypeOrNull("WritableTypeInfo") val methodTableRecordType = getStructType("MethodTableRecord") val interfaceTableRecordType = getStructType("InterfaceTableRecord") val globalHashType = getStructType("GlobalHash") val associatedObjectTableRecordType = getStructType("AssociatedObjectTableRecord") val objHeaderType = getStructType("ObjHeader") val objHeaderPtrType = pointerType(objHeaderType) val objHeaderPtrPtrType = pointerType(objHeaderType) val arrayHeaderType = getStructType("ArrayHeader") val frameOverlayType = getStructType("FrameOverlay") val target = LLVMGetTarget(llvmModule)!!.toKString() val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString() val targetData = LLVMCreateTargetData(dataLayout)!! val kotlinObjCClassData by lazy { getStructType("KotlinObjCClassData") } val kotlinObjCClassInfo by lazy { getStructType("KotlinObjCClassInfo") } val objCMethodDescription by lazy { getStructType("ObjCMethodDescription") } val objCTypeAdapter by lazy { getStructType("ObjCTypeAdapter") } val objCToKotlinMethodAdapter by lazy { getStructType("ObjCToKotlinMethodAdapter") } val kotlinToObjCMethodAdapter by lazy { getStructType("KotlinToObjCMethodAdapter") } val typeInfoObjCExportAddition by lazy { getStructType("TypeInfoObjCExportAddition") } val pointerSize: Int by lazy { LLVMABISizeOfType(targetData, objHeaderPtrType).toInt() } val pointerAlignment: Int by lazy { LLVMABIAlignmentOfType(targetData, objHeaderPtrType) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.expressions.IrConst /** * Provides utilities to create static data. */ internal class StaticData(override val context: Context): ContextUtils { /** * Represents the LLVM global variable. */ class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMValueRef) { companion object { private fun createLlvmGlobal(module: LLVMModuleRef, type: LLVMTypeRef, name: String, isExported: Boolean ): LLVMValueRef { if (isExported && LLVMGetNamedGlobal(module, name) != null) { throw IllegalArgumentException("Global '$name' already exists") } // Globals created with this API are *not* thread local. val llvmGlobal = LLVMAddGlobal(module, type, name)!! if (!isExported) { LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMInternalLinkage) } return llvmGlobal } fun create(staticData: StaticData, type: LLVMTypeRef, name: String, isExported: Boolean): Global { val module = staticData.context.llvmModule val isUnnamed = (name == "") // LLVM will select the unique index and represent the global as `@idx`. if (isUnnamed && isExported) { throw IllegalArgumentException("unnamed global can't be exported") } val llvmGlobal = createLlvmGlobal(module!!, type, name, isExported) return Global(staticData, llvmGlobal) } } val type get() = getGlobalType(this.llvmGlobal) fun setInitializer(value: ConstValue) { LLVMSetInitializer(llvmGlobal, value.llvm) } fun setZeroInitializer() { LLVMSetInitializer(llvmGlobal, LLVMConstNull(this.type)!!) } fun setConstant(value: Boolean) { LLVMSetGlobalConstant(llvmGlobal, if (value) 1 else 0) } fun setLinkage(value: LLVMLinkage) { LLVMSetLinkage(llvmGlobal, value) } fun setAlignment(value: Int) { LLVMSetAlignment(llvmGlobal, value) } fun setSection(name: String) { LLVMSetSection(llvmGlobal, name) } val pointer = Pointer.to(this) } /** * Represents the pointer to static data. * It can be a pointer to either a global or any its element. * * TODO: this class is probably should be implemented more optimally */ class Pointer private constructor(val global: Global, private val delegate: ConstPointer, val offsetInGlobal: Long) : ConstPointer by delegate { companion object { fun to(global: Global) = Pointer(global, constPointer(global.llvmGlobal), 0L) } private fun getElementOffset(index: Int): Long { val llvmTargetData = global.staticData.llvmTargetData val type = LLVMGetElementType(delegate.llvmType) return when (LLVMGetTypeKind(type)) { LLVMTypeKind.LLVMStructTypeKind -> LLVMOffsetOfElement(llvmTargetData, type, index) LLVMTypeKind.LLVMArrayTypeKind -> LLVMABISizeOfType(llvmTargetData, LLVMGetElementType(type)) * index else -> TODO() } } override fun getElementPtr(index: Int): Pointer { return Pointer(global, delegate.getElementPtr(index), offsetInGlobal + this.getElementOffset(index)) } /** * @return the distance from other pointer to this. * * @throws UnsupportedOperationException if it is not possible to represent the distance as [Int] value */ fun sub(other: Pointer): Int { if (this.global != other.global) { throw UnsupportedOperationException("pointers must belong to the same global") } val res = this.offsetInGlobal - other.offsetInGlobal if (res.toInt().toLong() != res) { throw UnsupportedOperationException("result doesn't fit into Int") } return res.toInt() } } /** * Creates [Global] with given type and name. * * It is external until explicitly initialized with [Global.setInitializer]. */ fun createGlobal(type: LLVMTypeRef, name: String, isExported: Boolean = false): Global { return Global.create(this, type, name, isExported) } /** * Creates [Global] with given name and value. */ fun placeGlobal(name: String, initializer: ConstValue, isExported: Boolean = false): Global { val global = createGlobal(initializer.llvmType, name, isExported) global.setInitializer(initializer) return global } /** * Creates array-typed global with given name and value. */ fun placeGlobalArray(name: String, elemType: LLVMTypeRef?, elements: List, isExported: Boolean = false): Global { val initializer = ConstArray(elemType, elements) val global = placeGlobal(name, initializer, isExported) return global } private val stringLiterals = mutableMapOf() private val cStringLiterals = mutableMapOf() fun cStringLiteral(value: String) = cStringLiterals.getOrPut(value) { placeCStringLiteral(value) } fun kotlinStringLiteral(value: String) = stringLiterals.getOrPut(value) { createKotlinStringLiteral(value) } } /** * Creates static instance of `konan.ImmutableByteArray` with given values of elements. * * @param args data for constant creation. */ internal fun StaticData.createImmutableBlob(value: IrConst): LLVMValueRef { val args = value.value.map { Int8(it.toByte()).llvm } return createConstKotlinArray(context.ir.symbols.immutableBlob.owner, args) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticDataUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* /** * Creates const array-typed global with given name and value. * Returns pointer to the first element of the array. * * If [elements] is empty, then null pointer is returned. */ internal fun StaticData.placeGlobalConstArray(name: String, elemType: LLVMTypeRef, elements: List, isExported: Boolean = false): ConstPointer { if (elements.isNotEmpty() || isExported) { val global = this.placeGlobalArray(name, elemType, elements, isExported) global.setConstant(true) return global.pointer.getElementPtr(0) } else { return NullPointer(elemType) } } internal fun StaticData.createAlias(name: String, aliasee: ConstPointer): ConstPointer { val alias = LLVMAddAlias(context.llvmModule, aliasee.llvmType, aliasee.llvm, name)!! return constPointer(alias) } internal fun StaticData.placeCStringLiteral(value: String): ConstPointer { val chars = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0) return placeGlobalConstArray("", int8Type, chars) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.cValuesOf import llvm.* import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin import org.jetbrains.kotlin.ir.declarations.IrClass private fun ConstPointer.add(index: Int): ConstPointer { return constPointer(LLVMConstGEP(llvm, cValuesOf(Int32(index).llvm), 1)!!) } // Must match OBJECT_TAG_PERMANENT_CONTAINER in C++. private fun StaticData.permanentTag(typeInfo: ConstPointer): ConstPointer { // Only pointer arithmetic via GEP works on constant pointers in LLVM. return typeInfo.bitcast(int8TypePtr).add(1).bitcast(kTypeInfoPtr) } private fun StaticData.objHeader(typeInfo: ConstPointer): Struct { return Struct(runtime.objHeaderType, permanentTag(typeInfo)) } private fun StaticData.arrayHeader(typeInfo: ConstPointer, length: Int): Struct { assert (length >= 0) return Struct(runtime.arrayHeaderType, permanentTag(typeInfo), Int32(length)) } internal fun StaticData.createKotlinStringLiteral(value: String): ConstPointer { val elements = value.toCharArray().map(::Char16) val objRef = createConstKotlinArray(context.ir.symbols.string.owner, elements) return objRef } private fun StaticData.createRef(objHeaderPtr: ConstPointer) = objHeaderPtr.bitcast(kObjHeaderPtr) internal fun StaticData.createConstKotlinArray(arrayClass: IrClass, elements: List) = createConstKotlinArray(arrayClass, elements.map { constValue(it) }).llvm internal fun StaticData.createConstKotlinArray(arrayClass: IrClass, elements: List): ConstPointer { val typeInfo = arrayClass.typeInfoPtr val bodyElementType: LLVMTypeRef = elements.firstOrNull()?.llvmType ?: int8Type // (use [0 x i8] as body if there are no elements) val arrayBody = ConstArray(bodyElementType, elements) val compositeType = structType(runtime.arrayHeaderType, arrayBody.llvmType) val global = this.createGlobal(compositeType, "") val objHeaderPtr = global.pointer.getElementPtr(0) val arrayHeader = arrayHeader(typeInfo, elements.size) global.setInitializer(Struct(compositeType, arrayHeader, arrayBody)) global.setConstant(true) return createRef(objHeaderPtr) } internal fun StaticData.createConstKotlinObject(type: IrClass, vararg fields: ConstValue): ConstPointer { val typeInfo = type.typeInfoPtr val objHeader = objHeader(typeInfo) val global = this.placeGlobal("", Struct(objHeader, *fields)) global.setConstant(true) val objHeaderPtr = global.pointer.getElementPtr(0) return createRef(objHeaderPtr) } internal fun StaticData.createInitializer(type: IrClass, vararg fields: ConstValue): ConstValue = Struct(objHeader(type.typeInfoPtr), *fields) /** * Creates static instance of `kotlin.collections.ArrayList` with given values of fields. * * @param array value for `array: Array` field. * @param length value for `length: Int` field. */ internal fun StaticData.createConstArrayList(array: ConstPointer, length: Int): ConstPointer { val arrayListClass = context.ir.symbols.arrayList.owner val arrayListFields = mapOf( "array" to array, "offset" to Int32(0), "length" to Int32(length), "backing" to NullPointer(kObjHeader)) // Now sort these values according to the order of fields returned by getFields() // to match the sorting order of the real ArrayList(). val sorted = mutableListOf() context.getLayoutBuilder(arrayListClass).fields.forEach { require (it.parent == arrayListClass) sorted.add(arrayListFields[it.name.asString()]!!) } return createConstKotlinObject(arrayListClass, *sorted.toTypedArray()) } internal fun StaticData.createUniqueInstance( kind: UniqueKind, bodyType: LLVMTypeRef, typeInfo: ConstPointer): ConstPointer { assert (getStructElements(bodyType).size == 1) // ObjHeader only. val objHeader = when (kind) { UniqueKind.UNIT -> objHeader(typeInfo) UniqueKind.EMPTY_ARRAY -> arrayHeader(typeInfo, 0) } val global = this.placeGlobal(kind.llvmName, objHeader, isExported = true) global.setConstant(true) return global.pointer } internal fun ContextUtils.unique(kind: UniqueKind): ConstPointer { val descriptor = when (kind) { UniqueKind.UNIT -> context.ir.symbols.unit.owner UniqueKind.EMPTY_ARRAY -> context.ir.symbols.array.owner } return if (isExternal(descriptor)) { constPointer(importGlobal( kind.llvmName, context.llvm.runtime.objHeaderType, origin = descriptor.llvmSymbolOrigin )) } else { context.llvmDeclarations.forUnique(kind).pointer } } internal val ContextUtils.theUnitInstanceRef: ConstPointer get() = this.unique(UniqueKind.UNIT) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.name.Name internal fun IrElement.needDebugInfo(context: Context) = context.shouldContainDebugInfo() || (this is IrVariable && this.isVar) internal class VariableManager(val functionGenerationContext: FunctionGenerationContext) { internal interface Record { fun load() : LLVMValueRef fun store(value: LLVMValueRef) fun address() : LLVMValueRef } inner class SlotRecord(val address: LLVMValueRef, val refSlot: Boolean, val isVar: Boolean) : Record { override fun load() : LLVMValueRef = functionGenerationContext.loadSlot(address, isVar) override fun store(value: LLVMValueRef) { functionGenerationContext.storeAny(value, address, true) } override fun address() : LLVMValueRef = this.address override fun toString() = (if (refSlot) "refslot" else "slot") + " for ${address}" } inner class ParameterRecord(val address: LLVMValueRef, val refSlot: Boolean) : Record { override fun load() : LLVMValueRef = functionGenerationContext.loadSlot(address, false) override fun store(value: LLVMValueRef) = functionGenerationContext.store(value, address) override fun address() : LLVMValueRef = this.address override fun toString() = (if (refSlot) "refslot" else "slot") + " for ${address}" } class ValueRecord(val value: LLVMValueRef, val name: Name) : Record { override fun load() : LLVMValueRef = value override fun store(value: LLVMValueRef) = throw Error("writing to immutable: ${name}") override fun address() : LLVMValueRef = throw Error("no address for: ${name}") override fun toString() = "value of ${value} from ${name}" } val variables: ArrayList = arrayListOf() val contextVariablesToIndex: HashMap = hashMapOf() // Clears inner state of variable manager. fun clear() { skipSlots = 0 variables.clear() contextVariablesToIndex.clear() } fun createVariable(valueDeclaration: IrValueDeclaration, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { val isVar = valueDeclaration is IrVariable && valueDeclaration.isVar // Note that we always create slot for object references for memory management. if (!functionGenerationContext.context.shouldContainDebugInfo() && !isVar && value != null) return createImmutable(valueDeclaration, value) else // Unfortunately, we have to create mutable slots here, // as even vals can be assigned on multiple paths. However, we use varness // knowledge, as anonymous slots are created only for true vars (for vals // their single assigner already have slot). return createMutable(valueDeclaration, isVar, value, variableLocation) } internal fun createMutable(valueDeclaration: IrValueDeclaration, isVar: Boolean, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { assert(!contextVariablesToIndex.contains(valueDeclaration)) val index = variables.size val type = functionGenerationContext.getLLVMType(valueDeclaration.type) val slot = functionGenerationContext.alloca(type, valueDeclaration.name.asString(), variableLocation) if (value != null) functionGenerationContext.storeAny(value, slot, true) variables.add(SlotRecord(slot, functionGenerationContext.isObjectType(type), isVar)) contextVariablesToIndex[valueDeclaration] = index return index } internal var skipSlots = 0 internal fun createParameter(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int { assert(!contextVariablesToIndex.contains(valueDeclaration)) val index = variables.size val type = functionGenerationContext.getLLVMType(valueDeclaration.type) val slot = functionGenerationContext.alloca( type, "p-${valueDeclaration.name.asString()}", variableLocation) val isObject = functionGenerationContext.isObjectType(type) variables.add(ParameterRecord(slot, isObject)) contextVariablesToIndex[valueDeclaration] = index if (isObject) skipSlots++ return index } // Creates anonymous mutable variable. // Think of slot reuse. fun createAnonymousSlot(value: LLVMValueRef? = null) : LLVMValueRef { val index = createAnonymousMutable(functionGenerationContext.kObjHeaderPtr, value) return addressOf(index) } private fun createAnonymousMutable(type: LLVMTypeRef, value: LLVMValueRef? = null) : Int { val index = variables.size val slot = functionGenerationContext.alloca(type, variableLocation = null) if (value != null) functionGenerationContext.storeAny(value, slot, true) variables.add(SlotRecord(slot, functionGenerationContext.isObjectType(type), true)) return index } internal fun createImmutable(valueDeclaration: IrValueDeclaration, value: LLVMValueRef) : Int { if (contextVariablesToIndex.containsKey(valueDeclaration)) throw Error("${ir2string(valueDeclaration)} is already defined") val index = variables.size variables.add(ValueRecord(value, valueDeclaration.name)) contextVariablesToIndex[valueDeclaration] = index return index } fun indexOf(valueDeclaration: IrValueDeclaration) : Int { return contextVariablesToIndex.getOrElse(valueDeclaration) { -1 } } fun addressOf(index: Int): LLVMValueRef { return variables[index].address() } fun load(index: Int): LLVMValueRef { return variables[index].load() } fun store(value: LLVMValueRef, index: Int) { variables[index].store(value) } } internal data class VariableDebugLocation(val localVariable: DILocalVariableRef, val location:DILocationRef?, val file:DIFileRef, val line:Int) internal fun debugInfoLocalVariableLocation(builder: DIBuilderRef?, functionScope: DIScopeOpaqueRef, diType: DITypeOpaqueRef, name:Name, file: DIFileRef, line: Int, location: DILocationRef?): VariableDebugLocation { val variableDeclaration = DICreateAutoVariable( builder = builder, scope = functionScope, name = name.asString(), file = file, line = line, type = diType) return VariableDebugLocation(localVariable = variableDeclaration!!, location = location, file = file, line = line) } internal fun debugInfoParameterLocation(builder: DIBuilderRef?, functionScope: DIScopeOpaqueRef, diType: DITypeOpaqueRef, name:Name, argNo: Int, file: DIFileRef, line: Int, location: DILocationRef?): VariableDebugLocation { val variableDeclaration = DICreateParameterVariable( builder = builder, scope = functionScope, name = name.asString(), argNo = argNo, file = file, line = line, type = diType) return VariableDebugLocation(localVariable = variableDeclaration!!, location = location, file = file, line = line) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VerifyModule.kt ================================================ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* import java.io.File import java.nio.file.Files internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") = memScoped { val errorRef = allocPointerTo() errorRef.value = null val verificationResult = LLVMVerifyModule( llvmModule, LLVMVerifierFailureAction.LLVMReturnStatusAction, errorRef.ptr ) val verificationError = convertAndDisposeLlvmMessage(errorRef.value) if (verificationResult != 0) { throwModuleVerificationError(llvmModule, current, verificationError) } } private fun throwModuleVerificationError( llvmModule: LLVMModuleRef, current: String, verificationError: String? ): Nothing { val exceptionMessage = buildString { try { appendModuleVerificationFailureDetails(llvmModule, current, verificationError) } catch (e: Throwable) { appendLine("Failed to make full error message: ${e.message}") } } throw Error(exceptionMessage) } private fun StringBuilder.appendModuleVerificationFailureDetails( llvmModule: LLVMModuleRef, current: String, verificationError: String? ) { appendLine("Invalid LLVM module") if (current.isNotEmpty()) appendLine("Error in $current") appendVerificationError(verificationError) val moduleDumpFile = Files.createTempFile("kotlin_native_llvm_module_dump", ".ll").toFile() dumpModuleAndAppendDetails(llvmModule, moduleDumpFile) moduleDumpFile.appendText(verificationError.orEmpty()) } private fun StringBuilder.appendVerificationError(error: String?) { if (error == null) return val lines = error.lines() appendLine("Verification errors:") val maxLines = 12 lines.take(maxLines).forEach { appendLine(" $it") } if (lines.size > maxLines) { appendLine(" ... (full error is available at the LLVM module dump file)") } } private fun StringBuilder.dumpModuleAndAppendDetails(llvmModule: LLVMModuleRef, moduleDumpFile: File) = memScoped { val errorRef = allocPointerTo() errorRef.value = null val printedWithErrors = LLVMPrintModuleToFile(llvmModule, moduleDumpFile.absolutePath, errorRef.ptr) appendLine() appendLine("LLVM module dump: ${moduleDumpFile.absolutePath}") val modulePrintError = convertAndDisposeLlvmMessage(errorRef.value) if (printedWithErrors != 0) { appendLine(" (printed with errors: $modulePrintError)") } } private fun convertAndDisposeLlvmMessage(message: CPointer?): String? = try { message?.toKString() } finally { LLVMDisposeMessage(message) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageInformation.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.coverage import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.llvm.column import org.jetbrains.kotlin.backend.konan.llvm.line import org.jetbrains.kotlin.backend.konan.llvm.computeSymbolName import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.name /** * The most important class in the coverage package. * It describes textual region of the code that is associated with IrElement. * Besides the obvious [file] and line/column borders, it has [RegionKind] which is described later. */ class Region( val startOffset: Int, val endOffset: Int, val file: IrFile, val kind: RegionKind ) { val startLine: Int get() = file.fileEntry.line(startOffset) val startColumn: Int get() = file.fileEntry.column(startOffset) val endLine: Int get() = file.fileEntry.line(endOffset) val endColumn: Int get() = file.fileEntry.column(endOffset) companion object { fun fromIr(irElement: IrElement, irFile: IrFile, kind: RegionKind = RegionKind.Code) = fromOffset(irElement.startOffset, irElement.endOffset, irFile, kind) fun fromOffset(startOffset: Int, endOffset: Int, irFile: IrFile, kind: RegionKind = RegionKind.Code) = if (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET || startOffset == endOffset) null else Region(startOffset, endOffset, irFile, kind) } override fun toString(): String { val expansion = (kind as? RegionKind.Expansion)?.let { " expand to " + it.expandedFile.name } ?: "" return "${file.name}$expansion: ${kind::class.simpleName} $startLine, $startColumn -> $endLine, $endColumn" } } /** * Describes what is the given code region. * Based on llvm::coverage::CounterMappingRegion. * Currently only [RegionKind.Code] is used. */ sealed class RegionKind { /** * Regular peace of code. */ object Code : RegionKind() /** * Empty line. */ object Gap : RegionKind() /** * Region of code that is an expansion of another source file. * Used for inline function. */ class Expansion(val expandedFile: IrFile) : RegionKind() } /** * "Regional" description of the [function]. */ class FunctionRegions( val function: IrFunction, val regions: Map ) { // Enumeration is required for serialization and instrumentation calls. val regionEnumeration = regions.values.mapIndexed { index, region -> region to index }.toMap() // Actually, it should be computed. // But since we don't support PGO structural hash doesn't really matter for now. val structuralHash: Long = 0 override fun toString(): String = buildString { appendLine("${function.computeSymbolName()} regions:") regions.forEach { (irElem, region) -> appendLine("${ir2string(irElem)} -> ($region)") } } } /** * Since file is the biggest unit in terms of the code coverage * we aggregate [FunctionRegions] per [file]. */ class FileRegionInfo( val file: IrFile, val functions: List ) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageManager.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.coverage import llvm.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.supportsCodeCoverage import org.jetbrains.kotlin.resolve.descriptorUtil.module /** * "Umbrella" class of all the of the code coverage related logic. */ internal class CoverageManager(val context: Context) { private val shouldCoverSources: Boolean = context.config.shouldCoverSources private val librariesToCover: Set = context.config.resolve.coveredLibraries.map { it.libraryName }.toSet() private val llvmProfileFilenameGlobal = "__llvm_profile_filename" private val defaultOutputFilePath: String by lazy { "${context.config.outputFile}.profraw" } private val outputFileName: String = context.config.configuration.get(KonanConfigKeys.PROFRAW_PATH) ?.let { File(it).absolutePath } ?: defaultOutputFilePath val enabled: Boolean = shouldCoverSources || librariesToCover.isNotEmpty() init { if (enabled && !checkRestrictions()) { context.reportCompilationError("Coverage is not supported for ${context.config.target}.") } } private fun checkRestrictions(): Boolean { val isKindAllowed = context.config.produce.involvesBitcodeGeneration val target = context.config.target val isTargetAllowed = target.supportsCodeCoverage() return isKindAllowed && isTargetAllowed } private val filesRegionsInfo = mutableListOf() private fun getFunctionRegions(irFunction: IrFunction) = filesRegionsInfo.flatMap { it.functions }.firstOrNull { it.function == irFunction } private val coveredModules: Set by lazy { val coveredUserCode = if (shouldCoverSources) setOf(context.moduleDescriptor) else emptySet() val coveredLibs = context.irModules.filter { it.key in librariesToCover }.values .map { it.descriptor }.toSet() val coveredIncludedLibs = if (shouldCoverSources) context.getIncludedLibraryDescriptors().toSet() else emptySet() coveredLibs + coveredUserCode + coveredIncludedLibs } private fun fileCoverageFilter(file: IrFile) = file.packageFragmentDescriptor.module in coveredModules /** * Walk [irModuleFragment] subtree and collect [FileRegionInfo] for files that are part of [coveredModules]. */ fun collectRegions(irModuleFragment: IrModuleFragment) { if (enabled) { val regions = CoverageRegionCollector(this::fileCoverageFilter).collectFunctionRegions(irModuleFragment) filesRegionsInfo += regions } } /** * @return [LLVMCoverageInstrumentation] instance if [irFunction] should be covered. */ fun tryGetInstrumentation(irFunction: IrFunction?, callSitePlacer: (function: LLVMValueRef, args: List) -> Unit) = if (enabled && irFunction != null) { getFunctionRegions(irFunction)?.let { LLVMCoverageInstrumentation(context, it, callSitePlacer) } } else { null } /** * Add __llvm_coverage_mapping to the LLVM module. */ fun writeRegionInfo() { if (enabled) { LLVMCoverageWriter(context, filesRegionsInfo).write() } } /** * Add passes that should be executed after main LLVM optimization pipeline. */ fun addLateLlvmPasses(passManager: LLVMPassManagerRef) { if (enabled) { // It's a late pass since DCE can kill __llvm_profile_filename global. LLVMAddInstrProfPass(passManager, outputFileName) } } /** * Since we performing instruction profiling before internalization and global dce * __llvm_profile_filename need to be added to exported symbols. */ fun addExportedSymbols(): List = if (enabled) { listOf(llvmProfileFilenameGlobal) } else { emptyList() } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageRegionCollector.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.coverage import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.util.nameForIrSerialization import org.jetbrains.kotlin.ir.util.statements import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid /** * Collect all regions in the module. * @param fileFilter filters files that should be processed. */ internal class CoverageRegionCollector(private val fileFilter: (IrFile) -> Boolean) { fun collectFunctionRegions(irModuleFragment: IrModuleFragment): List = irModuleFragment.files .filter(fileFilter) .map { file -> val collector = FunctionsCollector(file) collector.visitFile(file) FileRegionInfo(file, collector.functionRegions) } private inner class FunctionsCollector(val file: IrFile) : IrElementVisitorVoid { val functionRegions = mutableListOf() override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitFunction(declaration: IrFunction) { if (!declaration.isInline && !declaration.isExternal && !declaration.isGeneratedByCompiler) { val regionsCollector = IrFunctionRegionsCollector(fileFilter, file) declaration.acceptVoid(regionsCollector) if (regionsCollector.regions.isNotEmpty()) { functionRegions += FunctionRegions(declaration, regionsCollector.regions) } } // TODO: Decide how to work with local functions. Should they be process separately? declaration.acceptChildrenVoid(this) } } } // User doesn't bother about compiler-generated declarations. // So lets filter them. private val IrDeclaration.isGeneratedByCompiler: Boolean get() { return origin != IrDeclarationOrigin.DEFINED || nameForIrSerialization.asString() == "Konan_start" } /** * Very similar to [org.jetbrains.kotlin.backend.konan.llvm.CodeGeneratorVisitor] but instead of bitcode generation we collect regions. * [fileFilter]: specify which files should be processed by code coverage. Here it is required * for checking calls to inline functions from other files. * TODO: for now it is very inaccurate. */ private class IrFunctionRegionsCollector( val fileFilter: (IrFile) -> Boolean, val irFile: IrFile ) : IrElementVisitorVoid { private data class StatementContext(val current: IrStatement, val next: IrStatement?) val regions = mutableMapOf() private val irFileStack = mutableListOf(irFile) private val regionStack = mutableListOf() private val irStatementsStack = mutableListOf() private val currentFile: IrFile get() = irFileStack.last() private val currentRegion: Region get() = regionStack.last() override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitSimpleFunction(declaration: IrSimpleFunction) { declaration.body?.let { body -> visitInRegionContext(recordRegion(body) ?: return) { body.acceptVoid(this) } } } override fun visitConstructor(declaration: IrConstructor) { val statements = declaration.body?.statements ?: return visitInStatementContext(statements) { statement -> if (statement is IrDelegatingConstructorCall && !declaration.isPrimary || statement !is IrDelegatingConstructorCall && statement !is IrReturn) { recordRegion(statement) statement.acceptVoid(this) } } } override fun visitBody(body: IrBody) = visitInStatementContext(body.statements) override fun visitContainerExpression(expression: IrContainerExpression) { val statements = expression.statements when (expression) { is IrReturnableBlock -> { val file = expression.sourceFileSymbol?.owner if (file != null && file != currentFile && fileFilter(file)) { recordRegion(expression) visitInFileContext(file) { visitInStatementContext(statements) } } } else -> visitInStatementContext(statements) } } // TODO: The following implementation produces correct region mapping, but something goes wrong later // override fun visitFieldAccess(expression: IrFieldAccessExpression) { // expression.receiver?.let { recordRegion(it) } // expression.acceptChildrenVoid(this) // } override fun visitWhen(expression: IrWhen) { val branches = expression.branches branches.forEach { val condition = it.condition val result = it.result if (condition is IrConst<*> && condition.value == true && condition.endOffset == result.endOffset) { // Probably an 'else' branch. // Note: can't rely on [IrElseBranch], because IR deserializer doesn't emit it. recordRegion(result) } else { recordRegion(condition) recordRegion(result, condition.endOffset, result.endOffset) condition.acceptVoid(this) } result.acceptVoid(this) } } override fun visitLoop(loop: IrLoop) { val condition = loop.condition recordRegion(condition) condition.acceptVoid(this) val body = loop.body ?: return when (loop) { is IrWhileLoop -> recordRegion(body, condition.endOffset, body.endOffset) is IrDoWhileLoop -> recordRegion(body, body.startOffset, condition.startOffset) } body.acceptVoid(this) } override fun visitBreakContinue(jump: IrBreakContinue) { val (current, next) = irStatementsStack.lastOrNull() ?: return recordRegion(next ?: return, current.endOffset, jump.loop.endOffset) } override fun visitReturn(expression: IrReturn) { irStatementsStack.subList(0, irStatementsStack.lastIndex) .filter { (current, next) -> next != null && current.endOffset > expression.endOffset } .forEach { (current, next) -> recordRegion(next!!, expression.endOffset, current.endOffset) } val next = irStatementsStack.lastOrNull()?.next ?: return val nextRegion = recordRegion(next, expression.endOffset, currentRegion.endOffset) ?: return regionStack.pop() regionStack.push(nextRegion) } private fun visitInFileContext(file: IrFile, visit: () -> Unit) { irFileStack.push(file) visit() irFileStack.pop() } private fun visitInRegionContext(region: Region, visit: () -> Unit) { regionStack.push(region) visit() regionStack.pop() } private fun visitInStatementContext( statements: List, visit: (IrStatement) -> Unit = { statement -> statement.acceptVoid(this) } ) { for (i in 0..statements.lastIndex) { val current = statements[i] if (!current.hasValidOffsets()) { continue } val nextInContext = irStatementsStack.lastOrNull()?.next val next = if (i < statements.lastIndex && statements[i + 1].hasValidOffsets()) statements[i + 1] else nextInContext irStatementsStack.push(StatementContext(current, next)) visit(current) irStatementsStack.pop() } } private fun recordRegion(irElement: IrElement, kind: RegionKind = RegionKind.Code) = Region.fromIr(irElement, currentFile, kind)?.also { regions[irElement] = it } private fun recordRegion(irElement: IrElement, startOffset: Int, endOffset: Int, kind: RegionKind = RegionKind.Code) = Region.fromOffset(startOffset, endOffset, currentFile, kind)?.also { regions[irElement] = it } private fun IrElement.hasValidOffsets() = startOffset != UNDEFINED_OFFSET && endOffset != UNDEFINED_OFFSET && startOffset != endOffset } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageInstrumentation.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.coverage import llvm.LLVMConstBitCast import llvm.LLVMCreatePGOFunctionNameVar import llvm.LLVMInstrProfIncrement import llvm.LLVMValueRef import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFunction /** * Places calls to `llvm.instrprof.increment` in the beginning of the each * region in [functionRegions]. */ internal class LLVMCoverageInstrumentation( override val context: Context, private val functionRegions: FunctionRegions, private val callSitePlacer: (function: LLVMValueRef, args: List) -> Unit ) : ContextUtils { private val functionNameGlobal = createFunctionNameGlobal(functionRegions.function) private val functionHash = Int64(functionRegions.structuralHash).llvm // TODO: It's a great place for some debug output. fun instrumentIrElement(element: IrElement) { functionRegions.regions[element]?.let { placeRegionIncrement(it) } } /** * See https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic */ private fun placeRegionIncrement(region: Region) { val numberOfRegions = Int32(functionRegions.regions.size).llvm val regionNumber = Int32(functionRegions.regionEnumeration.getValue(region)).llvm val args = listOf(functionNameGlobal, functionHash, numberOfRegions, regionNumber) callSitePlacer(LLVMInstrProfIncrement(context.llvmModule)!!, args) } // Each profiled function should have a global with its name in a specific format. private fun createFunctionNameGlobal(function: IrFunction): LLVMValueRef { val name = function.llvmFunction.name val pgoFunctionName = LLVMCreatePGOFunctionNameVar(function.llvmFunction, name)!! return LLVMConstBitCast(pgoFunctionName, int8TypePtr)!! } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/LLVMCoverageWriter.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.coverage import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.llvm.name import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.path import org.jetbrains.kotlin.konan.file.File private fun RegionKind.toLLVMCoverageRegionKind(): LLVMCoverageRegionKind = when (this) { RegionKind.Code -> LLVMCoverageRegionKind.CODE RegionKind.Gap -> LLVMCoverageRegionKind.GAP is RegionKind.Expansion -> LLVMCoverageRegionKind.EXPANSION } private fun LLVMCoverageRegion.populateFrom(region: Region, regionId: Int, filesIndex: Map) = apply { fileId = filesIndex.getValue(region.file) lineStart = region.startLine columnStart = region.startColumn lineEnd = region.endLine columnEnd = region.endColumn counterId = regionId kind = region.kind.toLLVMCoverageRegionKind() expandedFileId = if (region.kind is RegionKind.Expansion) filesIndex.getValue(region.kind.expandedFile) else 0 } /** * Writes all of the coverage information to the [org.jetbrains.kotlin.backend.konan.Context.llvmModule]. * See http://llvm.org/docs/CoverageMappingFormat.html for the format description. */ internal class LLVMCoverageWriter( private val context: Context, private val filesRegionsInfo: List ) { fun write() { if (filesRegionsInfo.isEmpty()) return val module = context.llvmModule ?: error("LLVM module should be initialized.") val filesIndex = filesRegionsInfo.mapIndexed { index, fileRegionInfo -> fileRegionInfo.file to index }.toMap() val coverageGlobal = memScoped { val (functionMappingRecords, functionCoverages) = filesRegionsInfo.flatMap { it.functions }.map { functionRegions -> val regions = (functionRegions.regions.values).map { region -> alloc().populateFrom(region, functionRegions.regionEnumeration.getValue(region), filesIndex).ptr } val fileIds = functionRegions.regions.map { filesIndex.getValue(it.value.file) }.toSet().toIntArray() val functionCoverage = LLVMWriteCoverageRegionMapping( fileIds.toCValues(), fileIds.size.signExtend(), regions.toCValues(), regions.size.signExtend()) val functionName = context.llvmDeclarations.forFunction(functionRegions.function).llvmFunction.name val functionMappingRecord = LLVMAddFunctionMappingRecord(LLVMGetModuleContext(context.llvmModule), functionName, functionRegions.structuralHash, functionCoverage)!! Pair(functionMappingRecord, functionCoverage) }.unzip() val (filenames, fileIds) = filesIndex.entries.toList().map { File(it.key.path).absolutePath to it.value }.unzip() val retval = LLVMCoverageEmit(module, functionMappingRecords.toCValues(), functionMappingRecords.size.signExtend(), filenames.toCStringArray(this), fileIds.toIntArray().toCValues(), fileIds.size.signExtend(), functionCoverages.map { it }.toCValues(), functionCoverages.size.signExtend())!! // TODO: Is there a better way to cleanup fields of T* type in `memScoped`? functionCoverages.forEach { LLVMFunctionCoverageDispose(it) } retval } context.llvm.usedGlobals.add(coverageGlobal) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCCodeGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.objc import llvm.LLVMTypeRef import llvm.LLVMValueRef import org.jetbrains.kotlin.backend.konan.llvm.* internal open class ObjCCodeGenerator(val codegen: CodeGenerator) { val context = codegen.context val dataGenerator = codegen.objCDataGenerator!! fun FunctionGenerationContext.genSelector(selector: String): LLVMValueRef = genObjCSelector(selector) fun FunctionGenerationContext.genGetLinkedClass(name: String): LLVMValueRef { val classRef = dataGenerator.genClassRef(name) return load(classRef.llvm) } private val objcMsgSend = constPointer( context.llvm.externalFunction( "objc_msgSend", functionType(int8TypePtr, true, int8TypePtr, int8TypePtr), context.stdlibModule.llvmSymbolOrigin ) ) val objcRelease = context.llvm.externalFunction( "objc_release", functionType(voidType, false, int8TypePtr), context.stdlibModule.llvmSymbolOrigin ) // TODO: this doesn't support stret. fun msgSender(functionType: LLVMTypeRef): LLVMValueRef = objcMsgSend.bitcast(pointerType(functionType)).llvm } internal fun FunctionGenerationContext.genObjCSelector(selector: String): LLVMValueRef { val selectorRef = codegen.objCDataGenerator!!.genSelectorRef(selector) // TODO: clang emits it with `invariant.load` metadata. return load(selectorRef.llvm) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/ObjCDataGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.objc import llvm.* import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin /** * This class provides methods to generate Objective-C RTTI and other data. * It is mostly based on `clang/lib/CodeGen/CGObjCMac.cpp`, and supports only subset of operations * required for our purposes (thus simplified). * * [finishModule] must be called exactly once after all required data was generated. */ internal class ObjCDataGenerator(val codegen: CodeGenerator) { val context = codegen.context fun finishModule() { addModuleClassList( definedClasses, "OBJC_LABEL_CLASS_$", "__DATA,__objc_classlist,regular,no_dead_strip" ) } private val selectorRefs = mutableMapOf() private val classRefs = mutableMapOf() fun genSelectorRef(selector: String): ConstPointer = selectorRefs.getOrPut(selector) { val literal = selectors.get(selector) val global = codegen.staticData.placeGlobal("OBJC_SELECTOR_REFERENCES_", literal) global.setLinkage(LLVMLinkage.LLVMPrivateLinkage) LLVMSetExternallyInitialized(global.llvmGlobal, 1) global.setAlignment(codegen.runtime.pointerAlignment) global.setSection("__DATA,__objc_selrefs,literal_pointers,no_dead_strip") context.llvm.compilerUsedGlobals += global.llvmGlobal global.pointer } fun genClassRef(name: String): ConstPointer = classRefs.getOrPut(name) { val classGlobal = getClassGlobal(name, isMetaclass = false) val global = codegen.staticData.placeGlobal("OBJC_CLASSLIST_REFERENCES_\$_", classGlobal).also { it.setLinkage(LLVMLinkage.LLVMPrivateLinkage) it.setSection("__DATA,__objc_classrefs,regular,no_dead_strip") it.setAlignment(codegen.runtime.pointerAlignment) } context.llvm.compilerUsedGlobals += global.pointer.llvm global.pointer.bitcast(pointerType(int8TypePtr)) } val classObjectType = codegen.runtime.getStructType("_class_t") fun exportClass(name: String) { context.llvm.usedGlobals += getClassGlobal(name, isMetaclass = false).llvm context.llvm.usedGlobals += getClassGlobal(name, isMetaclass = true).llvm } private fun getClassGlobal(name: String, isMetaclass: Boolean): ConstPointer { val prefix = if (isMetaclass) { "OBJC_METACLASS_\$_" } else { "OBJC_CLASS_\$_" } val globalName = prefix + name // TODO: refactor usages and use [Global] class. val llvmGlobal = LLVMGetNamedGlobal(context.llvmModule, globalName) ?: codegen.importGlobal(globalName, classObjectType, CurrentKlibModuleOrigin) return constPointer(llvmGlobal) } private val emptyCache = constPointer( codegen.importGlobal( "_objc_empty_cache", codegen.runtime.getStructType("_objc_cache"), CurrentKlibModuleOrigin ) ) fun emitEmptyClass(name: String, superName: String) { emitClass(name, superName, instanceMethods = emptyList()) } class Method(val selector: String, val encoding: String, val imp: ConstPointer) fun emitClass(name: String, superName: String, instanceMethods: List) { val runtime = context.llvm.runtime fun struct(name: String) = runtime.getStructType(name) val classRoType = struct("_class_ro_t") val methodType = struct("_objc_method") val methodListType = struct("__method_list_t") val protocolListType = struct("_objc_protocol_list") val ivarListType = struct("_ivar_list_t") val propListType = struct("_prop_list_t") val classNameLiteral = classNames.get(name) fun emitInstanceMethodList(): ConstPointer { if (instanceMethods.isEmpty()) return NullPointer(methodListType) val methodStructs = instanceMethods.map { Struct(methodType, selectors.get(it.selector), encodings.get(it.encoding), it.imp.bitcast(int8TypePtr)) } val methodList = Struct( Int32(LLVMABISizeOfType(codegen.llvmTargetData, methodType).toInt()), Int32(instanceMethods.size), ConstArray(methodType, methodStructs) ) val globalName = "\u0001l_OBJC_\$_INSTANCE_METHODS_$name" val global = context.llvm.staticData.placeGlobal(globalName, methodList).also { it.setLinkage(LLVMLinkage.LLVMPrivateLinkage) it.setAlignment(runtime.pointerAlignment) it.setSection("__DATA, __objc_const") } context.llvm.compilerUsedGlobals += global.llvmGlobal return global.pointer.bitcast(pointerType(methodListType)) } fun buildClassRo(isMetaclass: Boolean): ConstPointer { // TODO: add NonFragileABI_Class_CompiledByARC flag? val flags: Int val start: Int val size: Int // TODO: stop using hard-coded values. if (isMetaclass) { flags = 1 start = 40 size = 40 } else { flags = 0 start = 8 size = 8 } val fields = mutableListOf() fields += Int32(flags) fields += Int32(start) fields += Int32(size) fields += NullPointer(int8Type) // ivar layout name fields += classNameLiteral fields += if (isMetaclass) NullPointer(methodListType) else emitInstanceMethodList() fields += NullPointer(protocolListType) fields += NullPointer(ivarListType) fields += NullPointer(int8Type) // ivar layout fields += NullPointer(propListType) val roValue = Struct(classRoType, fields) val roLabel = if (isMetaclass) { "\u0001l_OBJC_METACLASS_RO_\$_" } else { "\u0001l_OBJC_CLASS_RO_\$_" } + name val roGlobal = context.llvm.staticData.placeGlobal(roLabel, roValue).also { it.setLinkage(LLVMLinkage.LLVMPrivateLinkage) it.setAlignment(runtime.pointerAlignment) it.setSection("__DATA, __objc_const") } return roGlobal.pointer } fun buildClassObject( isMetaclass: Boolean, isa: ConstPointer, superClass: ConstPointer, classRo: ConstPointer ): ConstPointer { val fields = mutableListOf() fields += isa fields += superClass fields += emptyCache val vtableEntryType = pointerType(functionType(int8TypePtr, false, int8TypePtr, int8TypePtr)) fields += NullPointer(vtableEntryType) // empty vtable fields += classRo val classObjectValue = Struct(classObjectType, fields) val classGlobal = getClassGlobal(name, isMetaclass = isMetaclass) LLVMSetInitializer(classGlobal.llvm, classObjectValue.llvm) LLVMSetSection(classGlobal.llvm, "__DATA, __objc_data") LLVMSetAlignment(classGlobal.llvm, LLVMABIAlignmentOfType(runtime.targetData, classObjectType)) context.llvm.usedGlobals.add(classGlobal.llvm) return classGlobal } val metaclassObject = buildClassObject( isMetaclass = true, isa = getClassGlobal("NSObject", isMetaclass = true), superClass = getClassGlobal(superName, isMetaclass = true), classRo = buildClassRo(isMetaclass = true) ) val classObject = buildClassObject( isMetaclass = false, isa = metaclassObject, superClass = getClassGlobal(superName, isMetaclass = false), classRo = buildClassRo(isMetaclass = false) ) definedClasses.add(classObject) } private val definedClasses = mutableListOf() private fun addModuleClassList(elements: List, name: String, section: String) { if (elements.isEmpty()) return val global = context.llvm.staticData.placeGlobalArray( name, int8TypePtr, elements.map { it.bitcast(int8TypePtr) } ) global.setAlignment( LLVMABIAlignmentOfType( context.llvm.runtime.targetData, LLVMGetInitializer(global.llvmGlobal)!!.type ) ) global.setSection(section) context.llvm.compilerUsedGlobals += global.llvmGlobal } private val classNames = CStringLiteralsTable(classNameGenerator) private val selectors = CStringLiteralsTable(selectorGenerator) private val encodings = CStringLiteralsTable(encodingGenerator) private inner class CStringLiteralsTable(val generator: CStringLiteralsGenerator) { private val literals = mutableMapOf() fun get(value: String) = literals.getOrPut(value) { val globalPointer = generator.generate(context.llvmModule!!, value) context.llvm.compilerUsedGlobals += globalPointer.llvm globalPointer.getElementPtr(0) } } companion object { val classNameGenerator = CStringLiteralsGenerator("OBJC_CLASS_NAME_", "__TEXT,__objc_classname,cstring_literals") val selectorGenerator = CStringLiteralsGenerator("OBJC_METH_VAR_NAME_", "__TEXT,__objc_methname,cstring_literals") private val encodingGenerator = CStringLiteralsGenerator("OBJC_METH_VAR_TYPE_", "__TEXT,__objc_methtype,cstring_literals") } class CStringLiteralsGenerator(val label: String, val section: String) { fun generate(module: LLVMModuleRef, value: String): ConstPointer { val bytes = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0) val initializer = ConstArray(int8Type, bytes) val llvmGlobal = LLVMAddGlobal(module, initializer.llvmType, label)!! LLVMSetInitializer(llvmGlobal, initializer.llvm) LLVMSetGlobalConstant(llvmGlobal, 1) LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMPrivateLinkage) LLVMSetSection(llvmGlobal, section) LLVMSetUnnamedAddr(llvmGlobal, 1) LLVMSetAlignment(llvmGlobal, 1) return constPointer(llvmGlobal) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objc/linkObjC.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.objc import kotlinx.cinterop.* import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.isFinalBinary import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.objcexport.NSNumberKind import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamer internal fun linkObjC(context: Context) { val config = context.config if (!(config.produce.isFinalBinary && config.target.family.isAppleFamily)) return val patchBuilder = PatchBuilder(context) patchBuilder.addObjCPatches() val bitcodeFile = config.objCNativeLibrary val parsedModule = parseBitcodeFile(bitcodeFile) patchBuilder.buildAndApply(parsedModule) val failed = LLVMLinkModules2(context.llvmModule!!, parsedModule) if (failed != 0) { throw Error("failed to link $bitcodeFile") } } private class PatchBuilder(val context: Context) { enum class GlobalKind(val prefix: String) { OBJC_CLASS("OBJC_CLASS_\$_"), OBJC_METACLASS("OBJC_METACLASS_\$_"), OBJC_IVAR("OBJC_IVAR_\$_"), } data class GlobalPatch(val kind: GlobalKind, val suffix: String, val newSuffix: String) { val globalName: String get() = "${kind.prefix}$suffix" val newGlobalName: String get() = "${kind.prefix}$newSuffix" } data class LiteralPatch( val generator: ObjCDataGenerator.CStringLiteralsGenerator, val value: String, val newValue: String ) val globalPatches = mutableListOf() val literalPatches = mutableListOf() val objCExportNamer = context.objCExport.namer // Note: exported classes anyway use the same prefix, // so using more unique private prefix wouldn't help to prevent any clashes. private val privatePrefix = objCExportNamer.topLevelNamePrefix fun addProtocolImport(name: String) { literalPatches += LiteralPatch(ObjCDataGenerator.classNameGenerator, name, name) // So that protocol name literal wouldn't be detected as unhandled class. } fun addExportedClass(publicName: ObjCExportNamer.ClassOrProtocolName, runtimeName: String, vararg ivars: String) { addRenameClass(runtimeName, publicName.binaryName, ivars) } fun addPrivateClass(name: String, vararg ivars: String) { addRenameClass(name, "$privatePrefix$name", ivars) } private fun addRenameClass(oldName: String, newName: String, ivars: Array) { globalPatches += GlobalPatch(GlobalKind.OBJC_CLASS, oldName, newName) globalPatches += GlobalPatch(GlobalKind.OBJC_METACLASS, oldName, newName) ivars.mapTo(globalPatches) { GlobalPatch(GlobalKind.OBJC_IVAR, "$oldName.$it", "$newName.$it") } literalPatches += LiteralPatch(ObjCDataGenerator.classNameGenerator, oldName, newName) } fun addPrivateCategory(name: String) { literalPatches += LiteralPatch(ObjCDataGenerator.classNameGenerator, name, "$privatePrefix$name") } fun addPrivateSelector(name: String) { literalPatches += LiteralPatch(ObjCDataGenerator.selectorGenerator, name, "${privatePrefix}_$name") } } /** * Add patches for objc.bc. */ private fun PatchBuilder.addObjCPatches() { addProtocolImport("NSCopying") addPrivateSelector("toKotlin:") addPrivateSelector("releaseAsAssociatedObject") addPrivateClass("KIteratorAsNSEnumerator", "iteratorHolder") addPrivateClass("KListAsNSArray", "listHolder") addPrivateClass("KMutableListAsNSMutableArray", "listHolder") addPrivateClass("KSetAsNSSet", "setHolder") addPrivateClass("KMapAsNSDictionary", "mapHolder") addPrivateClass("KotlinObjectHolder", "refHolder") addPrivateClass("KotlinObjCWeakReference", "referred") addPrivateCategory("NSObjectToKotlin") addPrivateCategory("NSStringToKotlin") addPrivateCategory("NSNumberToKotlin") addPrivateCategory("NSDecimalNumberToKotlin") addPrivateCategory("NSArrayToKotlin") addPrivateCategory("NSSetToKotlin") addPrivateCategory("NSDictionaryToKotlin") addPrivateCategory("NSEnumeratorAsAssociatedObject") addExportedClass(objCExportNamer.kotlinAnyName, "KotlinBase", "refHolder", "permanent") addExportedClass(objCExportNamer.mutableSetName, "KotlinMutableSet", "setHolder") addExportedClass(objCExportNamer.mutableMapName, "KotlinMutableDictionary", "mapHolder") addExportedClass(objCExportNamer.kotlinNumberName, "KotlinNumber") NSNumberKind.values().mapNotNull { it.mappedKotlinClassId }.forEach { addExportedClass(objCExportNamer.numberBoxName(it), "Kotlin${it.shortClassName}", "value_") } } private fun PatchBuilder.buildAndApply(llvmModule: LLVMModuleRef) { val nameToGlobalPatch = globalPatches.associateNonRepeatingBy { it.globalName } val sectionToValueToLiteralPatch = literalPatches.groupBy { it.generator.section } .mapValues { (_, patches) -> patches.associateNonRepeatingBy { it.value } } val unusedPatches = (globalPatches + literalPatches).toMutableSet() val globals = generateSequence(LLVMGetFirstGlobal(llvmModule), { LLVMGetNextGlobal(it) }).toList() for (global in globals) { val initializer = LLVMGetInitializer(global) ?: continue val name = LLVMGetValueName(global)?.toKString().orEmpty() val globalPatch = nameToGlobalPatch[name] if (globalPatch != null) { LLVMSetValueName(global, globalPatch.newGlobalName) unusedPatches -= globalPatch } else if (PatchBuilder.GlobalKind.values().any { name.startsWith(it.prefix) }) { error("Objective-C global '$name' is not patched") } val section = LLVMGetSection(global)?.toKString() sectionToValueToLiteralPatch[section]?.let { valueToLiteralPatch -> val value = getStringValue(initializer) val patch = valueToLiteralPatch[value] if (patch != null) { if (patch.newValue != value) patchLiteral(global, patch.generator, patch.newValue) unusedPatches -= patch } else if (section == ObjCDataGenerator.classNameGenerator.section) { error("Objective-C class name literal is not patched: $value") } } } unusedPatches.firstOrNull()?.let { error("Patch is not applied: $it") } } private fun getStringValue(initializer: LLVMValueRef): String? = when (LLVMGetValueKind(initializer)) { LLVMValueKind.LLVMConstantDataArrayValueKind -> memScoped { require(LLVMIsConstantString(initializer) != 0) { "not a constant string: ${llvm2string(initializer)}" } val lengthVar = alloc() val bytePtr = LLVMGetAsString(initializer, lengthVar.ptr)!! val length = lengthVar.value val lastByte = bytePtr[length - 1] require(lastByte == 0.toByte()) { "${llvm2string(initializer)}:\n expected zero terminator, found $lastByte" } bytePtr.toKString() } LLVMValueKind.LLVMConstantAggregateZeroValueKind -> "" else -> error("Unexpected literal initializer: ${llvm2string(initializer)}") } private fun List.associateNonRepeatingBy(keySelector: (T) -> K): Map = this.groupBy(keySelector) .mapValues { (key, values) -> values.singleOrNull() ?: error("multiple values found for $key: ${values.joinToString()}") } private fun patchLiteral( global: LLVMValueRef, generator: ObjCDataGenerator.CStringLiteralsGenerator, newValue: String ) { val module = LLVMGetGlobalParent(global)!! val newFirstCharPtr = generator.generate(module, newValue).getElementPtr(0).llvm generateSequence(LLVMGetFirstUse(global), { LLVMGetNextUse(it) }).forEach { use -> val firstCharPtr = LLVMGetUser(use)!!.also { require(it.isFirstCharPtr(global)) { "Unexpected literal usage: ${llvm2string(it)}" } } LLVMReplaceAllUsesWith(firstCharPtr, newFirstCharPtr) } } private fun LLVMValueRef.isFirstCharPtr(global: LLVMValueRef): Boolean = this.type == int8TypePtr && LLVMIsConstant(this) != 0 && LLVMGetConstOpcode(this) == LLVMOpcode.LLVMGetElementPtr && LLVMGetNumOperands(this) == 3 && LLVMGetOperand(this, 0) == global && LLVMGetOperand(this, 1).isZeroConst() && LLVMGetOperand(this, 2).isZeroConst() private fun LLVMValueRef?.isZeroConst(): Boolean = this != null && LLVMGetValueKind(this) == LLVMValueKind.LLVMConstantIntValueKind && LLVMConstIntGetZExtValue(this) == 0L ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/BlockPointerSupport.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.objcexport import llvm.* import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.objcexport.BlockPointerBridge import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.util.OperatorNameConventions internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter( bridge: BlockPointerBridge ): LLVMValueRef { val irInterface = symbols.functionN(bridge.numberOfParameters).owner val invokeMethod = irInterface.declarations.filterIsInstance() .single { it.name == OperatorNameConventions.INVOKE } // Note: we can store Objective-C block pointer as associated object of Kotlin function object itself, // but only if it is equivalent to its dynamic translation result. If block returns void, then it's not like that: val useSeparateHolder = bridge.returnsVoid val bodyType = if (useSeparateHolder) { structType(codegen.kObjHeader, codegen.kObjHeaderPtr) } else { structType(codegen.kObjHeader) } val invokeImpl = generateFunction( codegen, codegen.getLlvmFunctionType(invokeMethod), "invokeFunction${bridge.nameSuffix}" ) { val args = (0 until bridge.numberOfParameters).map { index -> kotlinReferenceToObjC(param(index + 1)) } val thisRef = param(0) val associatedObjectHolder = if (useSeparateHolder) { val bodyPtr = bitcast(pointerType(bodyType), thisRef) loadSlot(structGep(bodyPtr, 1), isVar = false) } else { thisRef } val blockPtr = callFromBridge( context.llvm.Kotlin_ObjCExport_GetAssociatedObject, listOf(associatedObjectHolder) ) val invoke = loadBlockInvoke(blockPtr, bridge) val result = callFromBridge(invoke, listOf(blockPtr) + args) val kotlinResult = if (bridge.returnsVoid) { theUnitInstanceRef.llvm } else { objCReferenceToKotlin(result, Lifetime.RETURN_VALUE) } ret(kotlinResult) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } val typeInfo = rttiGenerator.generateSyntheticInterfaceImpl( irInterface, mapOf(invokeMethod to constPointer(invokeImpl)), bodyType, immutable = true ) return generateFunction( codegen, functionType(codegen.kObjHeaderPtr, false, int8TypePtr, codegen.kObjHeaderPtrPtr), "convertBlock${bridge.nameSuffix}" ) { val blockPtr = param(0) ifThen(icmpEq(blockPtr, kNullInt8Ptr)) { ret(kNullObjHeaderPtr) } val retainedBlockPtr = callFromBridge(retainBlock, listOf(blockPtr)) val result = if (useSeparateHolder) { val result = allocInstance(typeInfo.llvm, Lifetime.RETURN_VALUE) val bodyPtr = bitcast(pointerType(bodyType), result) val holder = allocInstanceWithAssociatedObject( symbols.interopForeignObjCObject.owner.typeInfoPtr, retainedBlockPtr, Lifetime.ARGUMENT ) storeHeapRef(holder, structGep(bodyPtr, 1)) result } else { allocInstanceWithAssociatedObject(typeInfo, retainedBlockPtr, Lifetime.RETURN_VALUE) } ret(result) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } } private fun FunctionGenerationContext.loadBlockInvoke( blockPtr: LLVMValueRef, bridge: BlockPointerBridge ): LLVMValueRef { val blockLiteralType = codegen.runtime.getStructType("Block_literal_1") val invokePtr = structGep(bitcast(pointerType(blockLiteralType), blockPtr), 3) return bitcast(pointerType(bridge.blockType.blockInvokeLlvmType), load(invokePtr)) } private fun FunctionGenerationContext.allocInstanceWithAssociatedObject( typeInfo: ConstPointer, associatedObject: LLVMValueRef, resultLifetime: Lifetime ): LLVMValueRef = call( context.llvm.Kotlin_ObjCExport_AllocInstanceWithAssociatedObject, listOf(typeInfo.llvm, associatedObject), resultLifetime ) private val BlockPointerBridge.blockType: BlockType get() = BlockType(numberOfParameters = this.numberOfParameters, returnsVoid = this.returnsVoid) /** * Type of block having [numberOfParameters] reference-typed parameters and reference- or void-typed return value. */ internal data class BlockType(val numberOfParameters: Int, val returnsVoid: Boolean) private val BlockType.blockInvokeLlvmType: LLVMTypeRef get() = functionType( if (returnsVoid) voidType else int8TypePtr, false, (0..numberOfParameters).map { int8TypePtr } ) private val BlockPointerBridge.nameSuffix: String get() = numberOfParameters.toString() + if (returnsVoid) "V" else "" internal class BlockGenerator(private val codegen: CodeGenerator) { private val kRefSharedHolderType = LLVMGetTypeByName(codegen.runtime.llvmModule, "class.KRefSharedHolder")!! private val blockLiteralType = structType( codegen.runtime.getStructType("Block_literal_1"), kRefSharedHolderType ) private val blockDescriptorType = codegen.runtime.getStructType("Block_descriptor_1") val disposeHelper = generateFunction( codegen, functionType(voidType, false, int8TypePtr), "blockDisposeHelper" ) { val blockPtr = bitcast(pointerType(blockLiteralType), param(0)) val refHolder = structGep(blockPtr, 1) call(context.llvm.kRefSharedHolderDispose, listOf(refHolder)) ret(null) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } val copyHelper = generateFunction( codegen, functionType(voidType, false, int8TypePtr, int8TypePtr), "blockCopyHelper" ) { val dstBlockPtr = bitcast(pointerType(blockLiteralType), param(0)) val dstRefHolder = structGep(dstBlockPtr, 1) val srcBlockPtr = bitcast(pointerType(blockLiteralType), param(1)) val srcRefHolder = structGep(srcBlockPtr, 1) // Note: in current implementation copy helper is invoked only for stack-allocated blocks from the same thread, // so it is technically not necessary to check owner. // However this is not guaranteed by Objective-C runtime, so keep it suboptimal but reliable: val ref = call( context.llvm.kRefSharedHolderRef, listOf(srcRefHolder), exceptionHandler = ExceptionHandler.Caller, verbatim = true ) call(context.llvm.kRefSharedHolderInit, listOf(dstRefHolder, ref)) ret(null) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } fun org.jetbrains.kotlin.backend.konan.Context.LongInt(value: Long) = if (is64BitLong()) Int64(value) else Int32(value.toInt()) private fun generateDescriptorForBlock(blockType: BlockType): ConstValue { val numberOfParameters = blockType.numberOfParameters val signature = buildString { append(if (blockType.returnsVoid) 'v' else '@') val pointerSize = codegen.runtime.pointerSize append(pointerSize * (numberOfParameters + 1)) var paramOffset = 0L (0 .. numberOfParameters).forEach { index -> append('@') if (index == 0) append('?') append(paramOffset) paramOffset += pointerSize } } return Struct(blockDescriptorType, codegen.context.LongInt(0L), codegen.context.LongInt(LLVMStoreSizeOfType(codegen.runtime.targetData, blockLiteralType)), constPointer(copyHelper), constPointer(disposeHelper), codegen.staticData.cStringLiteral(signature), NullPointer(int8Type) ) } private fun ObjCExportCodeGeneratorBase.generateInvoke( blockType: BlockType, invokeName: String, genBody: FunctionGenerationContext.(LLVMValueRef, List) -> Unit ): ConstPointer { val result = generateFunction(codegen, blockType.blockInvokeLlvmType, invokeName) { val blockPtr = bitcast(pointerType(blockLiteralType), param(0)) val kotlinObject = call( context.llvm.kRefSharedHolderRef, listOf(structGep(blockPtr, 1)), exceptionHandler = ExceptionHandler.Caller, verbatim = true ) val arguments = (1 .. blockType.numberOfParameters).map { index -> param(index) } genBody(kotlinObject, arguments) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } return constPointer(result) } fun ObjCExportCodeGeneratorBase.generateConvertFunctionToBlock( bridge: BlockPointerBridge ): LLVMValueRef { return generateWrapKotlinObjectToBlock( bridge.blockType, convertName = "convertFunction${bridge.nameSuffix}", invokeName = "invokeBlock${bridge.nameSuffix}" ) { kotlinFunction, arguments -> val numberOfParameters = bridge.numberOfParameters val kotlinArguments = arguments.map { objCReferenceToKotlin(it, Lifetime.ARGUMENT) } val invokeMethod = context.ir.symbols.functionN(numberOfParameters).owner.simpleFunctions() .single { it.name == OperatorNameConventions.INVOKE } val callee = lookupVirtualImpl(kotlinFunction, invokeMethod) val result = callFromBridge(callee, listOf(kotlinFunction) + kotlinArguments, Lifetime.ARGUMENT) if (bridge.returnsVoid) { ret(null) } else { ret(kotlinReferenceToObjC(result)) } } } internal fun ObjCExportCodeGeneratorBase.generateWrapKotlinObjectToBlock( blockType: BlockType, convertName: String, invokeName: String, genBlockBody: FunctionGenerationContext.(LLVMValueRef, List) -> Unit ): LLVMValueRef { val blockDescriptor = codegen.staticData.placeGlobal( "", generateDescriptorForBlock(blockType) ) return generateFunction( codegen, functionType(int8TypePtr, false, codegen.kObjHeaderPtr), convertName ) { val kotlinRef = param(0) ifThen(icmpEq(kotlinRef, kNullObjHeaderPtr)) { ret(kNullInt8Ptr) } val isa = codegen.importGlobal( "_NSConcreteStackBlock", int8TypePtr, CurrentKlibModuleOrigin ) val flags = Int32((1 shl 25) or (1 shl 30) or (1 shl 31)).llvm val reserved = Int32(0).llvm val invokeType = pointerType(functionType(voidType, true, int8TypePtr)) val invoke = generateInvoke(blockType, invokeName, genBlockBody).bitcast(invokeType).llvm val descriptor = blockDescriptor.llvmGlobal val blockOnStack = alloca(blockLiteralType) val blockOnStackBase = structGep(blockOnStack, 0) val refHolder = structGep(blockOnStack, 1) listOf(bitcast(int8TypePtr, isa), flags, reserved, invoke, descriptor).forEachIndexed { index, value -> // Although value is actually on the stack, it's not in normal slot area, so we cannot handle it // as if it was on the stack. store(value, structGep(blockOnStackBase, index)) } call(context.llvm.kRefSharedHolderInitLocal, listOf(refHolder, kotlinRef)) val copiedBlock = callFromBridge(retainBlock, listOf(bitcast(int8TypePtr, blockOnStack))) val autoreleaseReturnValue = context.llvm.externalFunction( "objc_autoreleaseReturnValue", functionType(int8TypePtr, false, int8TypePtr), CurrentKlibModuleOrigin ) ret(callFromBridge(autoreleaseReturnValue, listOf(copiedBlock))) }.also { LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage) } } } private val ObjCExportCodeGeneratorBase.retainBlock get() = context.llvm.externalFunction( "objc_retainBlock", functionType(int8TypePtr, false, int8TypePtr), CurrentKlibModuleOrigin ) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm.objcexport import llvm.* import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.ir.allParametersCount import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.objc.ObjCCodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objc.ObjCDataGenerator import org.jetbrains.kotlin.backend.konan.objcexport.* import org.jetbrains.kotlin.backend.konan.serialization.resolveFakeOverrideMaybeAbstract import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrClassReference import org.jetbrains.kotlin.ir.expressions.IrVararg import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.LinkerOutputKind import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.DFS internal fun TypeBridge.makeNothing() = when (this) { is ReferenceBridge, is BlockPointerBridge -> kNullInt8Ptr is ValueTypeBridge -> LLVMConstNull(this.objCValueType.llvmType)!! } internal open class ObjCExportCodeGeneratorBase(codegen: CodeGenerator) : ObjCCodeGenerator(codegen) { val symbols get() = context.ir.symbols val runtime get() = codegen.runtime val staticData get() = codegen.staticData val rttiGenerator = RTTIGenerator(context) private val objcTerminate: LLVMValueRef by lazy { context.llvm.externalFunction( "objc_terminate", functionType(voidType, false), CurrentKlibModuleOrigin ).also { setFunctionNoUnwind(it) } } fun dispose() { rttiGenerator.dispose() } // TODO: currently bridges don't have any custom `landingpad`s, // so it is correct to use [callAtFunctionScope] here. // However, exception handling probably should be refactored // (e.g. moved from `IrToBitcode.kt` to [FunctionGenerationContext]). fun FunctionGenerationContext.callFromBridge( function: LLVMValueRef, args: List, resultLifetime: Lifetime = Lifetime.IRRELEVANT ): LLVMValueRef { // TODO: it is required only for Kotlin-to-Objective-C bridges. this.forwardingForeignExceptionsTerminatedWith = objcTerminate return call(function, args, resultLifetime, ExceptionHandler.Caller) } fun FunctionGenerationContext.kotlinReferenceToObjC(value: LLVMValueRef) = callFromBridge(context.llvm.Kotlin_ObjCExport_refToObjC, listOf(value)) fun FunctionGenerationContext.objCReferenceToKotlin(value: LLVMValueRef, resultLifetime: Lifetime) = callFromBridge(context.llvm.Kotlin_ObjCExport_refFromObjC, listOf(value), resultLifetime) private val blockToKotlinFunctionConverterCache = mutableMapOf() internal fun blockToKotlinFunctionConverter(bridge: BlockPointerBridge): LLVMValueRef = blockToKotlinFunctionConverterCache.getOrPut(bridge) { generateBlockToKotlinFunctionConverter(bridge) } protected val blockGenerator = BlockGenerator(this.codegen) private val functionToBlockConverterCache = mutableMapOf() internal fun kotlinFunctionToBlockConverter(bridge: BlockPointerBridge): LLVMValueRef = functionToBlockConverterCache.getOrPut(bridge) { blockGenerator.run { generateConvertFunctionToBlock(bridge) } } } internal class ObjCExportBlockCodeGenerator(codegen: CodeGenerator) : ObjCExportCodeGeneratorBase(codegen) { init { // Must be generated along with stdlib: // 1. Enumerates [BuiltInFictitiousFunctionIrClassFactory] built classes, which may be incomplete otherwise. // 2. Modifies stdlib global initializers. // 3. Defines runtime-declared globals. require(context.producedLlvmModuleContainsStdlib) } fun generate() { emitFunctionConverters() emitBlockToKotlinFunctionConverters() dispose() } } internal class ObjCExportCodeGenerator( codegen: CodeGenerator, val namer: ObjCExportNamer, val mapper: ObjCExportMapper ) : ObjCExportCodeGeneratorBase(codegen) { val selectorsToDefine = mutableMapOf() val externalGlobalInitializers = mutableMapOf() internal val continuationToCompletionConverter: LLVMValueRef by lazy { generateContinuationToCompletionConverter(blockGenerator) } fun FunctionGenerationContext.genSendMessage( returnType: LLVMTypeRef, receiver: LLVMValueRef, selector: String, vararg args: LLVMValueRef ): LLVMValueRef { val objcMsgSendType = functionType( returnType, false, listOf(int8TypePtr, int8TypePtr) + args.map { it.type } ) return callFromBridge(msgSender(objcMsgSendType), listOf(receiver, genSelector(selector)) + args) } fun FunctionGenerationContext.kotlinToObjC( value: LLVMValueRef, valueType: ObjCValueType ): LLVMValueRef = when (valueType) { ObjCValueType.BOOL -> zext(value, int8Type) // TODO: zext behaviour may be strange on bit types. ObjCValueType.UNICHAR, ObjCValueType.CHAR, ObjCValueType.SHORT, ObjCValueType.INT, ObjCValueType.LONG_LONG, ObjCValueType.UNSIGNED_CHAR, ObjCValueType.UNSIGNED_SHORT, ObjCValueType.UNSIGNED_INT, ObjCValueType.UNSIGNED_LONG_LONG, ObjCValueType.FLOAT, ObjCValueType.DOUBLE, ObjCValueType.POINTER -> value } private fun FunctionGenerationContext.objCToKotlin( value: LLVMValueRef, valueType: ObjCValueType ): LLVMValueRef = when (valueType) { ObjCValueType.BOOL -> icmpNe(value, Int8(0).llvm) ObjCValueType.UNICHAR, ObjCValueType.CHAR, ObjCValueType.SHORT, ObjCValueType.INT, ObjCValueType.LONG_LONG, ObjCValueType.UNSIGNED_CHAR, ObjCValueType.UNSIGNED_SHORT, ObjCValueType.UNSIGNED_INT, ObjCValueType.UNSIGNED_LONG_LONG, ObjCValueType.FLOAT, ObjCValueType.DOUBLE, ObjCValueType.POINTER -> value } private fun FunctionGenerationContext.objCBlockPointerToKotlin( value: LLVMValueRef, typeBridge: BlockPointerBridge, resultLifetime: Lifetime ) = callFromBridge( blockToKotlinFunctionConverter(typeBridge), listOf(value), resultLifetime ) private fun FunctionGenerationContext.kotlinFunctionToObjCBlockPointer( typeBridge: BlockPointerBridge, value: LLVMValueRef ) = callFromBridge(kotlinFunctionToBlockConverter(typeBridge), listOf(value)) fun FunctionGenerationContext.kotlinToObjC( value: LLVMValueRef, typeBridge: TypeBridge ): LLVMValueRef = if (LLVMTypeOf(value) == voidType) { typeBridge.makeNothing() } else { when (typeBridge) { is ReferenceBridge -> kotlinReferenceToObjC(value) is BlockPointerBridge -> kotlinFunctionToObjCBlockPointer(typeBridge, value) is ValueTypeBridge -> kotlinToObjC(value, typeBridge.objCValueType) } } fun FunctionGenerationContext.objCToKotlin( value: LLVMValueRef, typeBridge: TypeBridge, resultLifetime: Lifetime ): LLVMValueRef = when (typeBridge) { is ReferenceBridge -> objCReferenceToKotlin(value, resultLifetime) is BlockPointerBridge -> objCBlockPointerToKotlin(value, typeBridge, resultLifetime) is ValueTypeBridge -> objCToKotlin(value, typeBridge.objCValueType) } fun FunctionGenerationContext.initRuntimeIfNeeded() { this.needsRuntimeInit = true } inline fun FunctionGenerationContext.convertKotlin( genValue: (Lifetime) -> LLVMValueRef, actualType: IrType, expectedType: IrType, resultLifetime: Lifetime ): LLVMValueRef { val conversion = symbols.getTypeConversion(actualType, expectedType) ?: return genValue(resultLifetime) val value = genValue(Lifetime.ARGUMENT) return callFromBridge(conversion.owner.llvmFunction, listOf(value), resultLifetime) } private fun generateTypeAdaptersForKotlinTypes(spec: ObjCExportCodeSpec?): List { val types = spec?.types.orEmpty() + objCClassForAny val allReverseAdapters = createReverseAdapters(types) return types.map { val reverseAdapters = allReverseAdapters.getValue(it).adapters when (it) { objCClassForAny -> { createTypeAdapter(it, superClass = null, reverseAdapters) } is ObjCClassForKotlinClass -> { val superClass = it.superClassNotAny ?: objCClassForAny dataGenerator.emitEmptyClass(it.binaryName, superClass.binaryName) // Note: it is generated only to be visible for linker. // Methods will be added at runtime. createTypeAdapter(it, superClass, reverseAdapters) } is ObjCProtocolForKotlinInterface -> createTypeAdapter(it, superClass = null, reverseAdapters) } } } private fun generateTypeAdapters(spec: ObjCExportCodeSpec?) { val objCTypeAdapters = mutableListOf() objCTypeAdapters += generateTypeAdaptersForKotlinTypes(spec) spec?.files?.forEach { objCTypeAdapters += createTypeAdapterForFileClass(it) dataGenerator.emitEmptyClass(it.binaryName, namer.kotlinAnyName.binaryName) } emitTypeAdapters(objCTypeAdapters) } internal fun generate(spec: ObjCExportCodeSpec?) { generateTypeAdapters(spec) NSNumberKind.values().mapNotNull { it.mappedKotlinClassId }.forEach { dataGenerator.exportClass(namer.numberBoxName(it).binaryName) } dataGenerator.exportClass(namer.mutableSetName.binaryName) dataGenerator.exportClass(namer.mutableMapName.binaryName) dataGenerator.exportClass(namer.kotlinAnyName.binaryName) emitSpecialClassesConvertions() // Replace runtime global with weak linkage: replaceExternalWeakOrCommonGlobal( "Kotlin_ObjCInterop_uniquePrefix", codegen.staticData.cStringLiteral(namer.topLevelNamePrefix), context.standardLlvmSymbolsOrigin ) emitSelectorsHolder() emitStaticInitializers() emitKt42254Hint() } private fun emitTypeAdapters(objCTypeAdapters: List) { val placedClassAdapters = mutableMapOf() val placedInterfaceAdapters = mutableMapOf() objCTypeAdapters.forEach { adapter -> val typeAdapter = staticData.placeGlobal("", adapter).pointer val irClass = adapter.irClass val descriptorToAdapter = if (irClass?.isInterface == true) { placedInterfaceAdapters } else { // Objective-C class for Kotlin class or top-level declarations. placedClassAdapters } descriptorToAdapter[adapter.objCName] = typeAdapter if (irClass != null) { if (!context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { setObjCExportTypeInfo(irClass, typeAdapter = typeAdapter) } else { // Optimization: avoid generating huge initializers; // handled with "Kotlin_ObjCExport_initTypeAdapters" below. } } } fun emitSortedAdapters(nameToAdapter: Map, prefix: String) { val sortedAdapters = nameToAdapter.toList().sortedBy { it.first }.map { it.second } if (sortedAdapters.isNotEmpty()) { val type = sortedAdapters.first().llvmType val sortedAdaptersPointer = staticData.placeGlobalConstArray("", type, sortedAdapters) // Note: this globals replace runtime globals with weak linkage: val origin = context.standardLlvmSymbolsOrigin replaceExternalWeakOrCommonGlobal(prefix, sortedAdaptersPointer, origin) replaceExternalWeakOrCommonGlobal("${prefix}Num", Int32(sortedAdapters.size), origin) } } emitSortedAdapters(placedClassAdapters, "Kotlin_ObjCExport_sortedClassAdapters") emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters") if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { replaceExternalWeakOrCommonGlobal( "Kotlin_ObjCExport_initTypeAdapters", Int1(1), context.standardLlvmSymbolsOrigin ) } } private fun emitStaticInitializers() { if (externalGlobalInitializers.isEmpty()) return val initializer = generateFunctionNoRuntime(codegen, functionType(voidType, false), "initObjCExportGlobals") { externalGlobalInitializers.forEach { (global, value) -> store(value.llvm, global) } ret(null) } LLVMSetLinkage(initializer, LLVMLinkage.LLVMInternalLinkage) context.llvm.otherStaticInitializers += initializer } private fun emitKt42254Hint() { if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) { // Might be affected by https://youtrack.jetbrains.com/issue/KT-42254. // The code below generally follows [replaceExternalWeakOrCommonGlobal] implementation. if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // So the compiler uses caches. If a user is linking two such static frameworks into a single binary, // the linker might fail with a lot of "duplicate symbol" errors due to KT-42254. // Adding a similar symbol that would explicitly hint to take a look at the YouTrack issue if reported. // Note: for some reason this symbol is reported as the last one, which is good for its purpose. val name = "See https://youtrack.jetbrains.com/issue/KT-42254" val global = staticData.placeGlobal(name, Int8(0), isExported = true) context.llvm.usedGlobals += global.llvmGlobal LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) } } } // TODO: consider including this into ObjCExportCodeSpec. private val objCClassForAny = ObjCClassForKotlinClass( namer.kotlinAnyName.binaryName, symbols.any, methods = listOf("equals", "hashCode", "toString").map { nameString -> val name = Name.identifier(nameString) val irFunction = symbols.any.owner.simpleFunctions().single { it.name == name } val descriptor = context.builtIns.any.unsubstitutedMemberScope .getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).single() val baseMethod = createObjCMethodSpecBaseMethod(mapper, namer, irFunction.symbol, descriptor) ObjCMethodForKotlinMethod(baseMethod) }, categoryMethods = emptyList(), superClassNotAny = null ) private fun emitSelectorsHolder() { val impType = functionType(voidType, false, int8TypePtr, int8TypePtr) val imp = generateFunctionNoRuntime(codegen, impType, "") { unreachable() } val methods = selectorsToDefine.map { (selector, bridge) -> ObjCDataGenerator.Method(selector, getEncoding(bridge), constPointer(imp)) } dataGenerator.emitClass( "${namer.topLevelNamePrefix}KotlinSelectorsHolder", superName = "NSObject", instanceMethods = methods ) } private val impType = pointerType(functionType(voidType, false)) internal val directMethodAdapters = mutableMapOf() internal val exceptionTypeInfoArrays = mutableMapOf() internal val typeInfoArrays = mutableMapOf, ConstPointer>() inner class ObjCToKotlinMethodAdapter( selector: String, encoding: String, imp: ConstPointer ) : Struct( runtime.objCToKotlinMethodAdapter, staticData.cStringLiteral(selector), staticData.cStringLiteral(encoding), imp.bitcast(impType) ) inner class KotlinToObjCMethodAdapter( selector: String, nameSignature: Long, itablePlace: ClassLayoutBuilder.InterfaceTablePlace, vtableIndex: Int, kotlinImpl: ConstPointer ) : Struct( runtime.kotlinToObjCMethodAdapter, staticData.cStringLiteral(selector), Int64(nameSignature), Int32(itablePlace.interfaceId), Int32(itablePlace.itableSize), Int32(itablePlace.methodIndex), Int32(vtableIndex), kotlinImpl ) inner class ObjCTypeAdapter( val irClass: IrClass?, typeInfo: ConstPointer?, vtable: ConstPointer?, vtableSize: Int, methodTable: List, itable: List, itableSize: Int, val objCName: String, directAdapters: List, classAdapters: List, virtualAdapters: List, reverseAdapters: List ) : Struct( runtime.objCTypeAdapter, typeInfo, vtable, Int32(vtableSize), staticData.placeGlobalConstArray("", runtime.methodTableRecordType, methodTable), Int32(methodTable.size), staticData.placeGlobalConstArray("", runtime.interfaceTableRecordType, itable), Int32(itableSize), staticData.cStringLiteral(objCName), staticData.placeGlobalConstArray( "", runtime.objCToKotlinMethodAdapter, directAdapters ), Int32(directAdapters.size), staticData.placeGlobalConstArray( "", runtime.objCToKotlinMethodAdapter, classAdapters ), Int32(classAdapters.size), staticData.placeGlobalConstArray( "", runtime.objCToKotlinMethodAdapter, virtualAdapters ), Int32(virtualAdapters.size), staticData.placeGlobalConstArray( "", runtime.kotlinToObjCMethodAdapter, reverseAdapters ), Int32(reverseAdapters.size) ) } private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal( name: String, value: ConstValue, origin: CompiledKlibModuleOrigin ) { // TODO: A similar mechanism is used in `IrToBitcode.overrideRuntimeGlobal`. Consider merging them. if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { val global = codegen.importGlobal(name, value.llvmType, origin) externalGlobalInitializers[global] = value } else { context.llvmImports.add(origin) val global = staticData.placeGlobal(name, value, isExported = true) if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // Note: actually this is required only if global's weak/common definition is in another object file, // but it is simpler to do this for all globals, considering that all usages can't be removed by DCE anyway. context.llvm.usedGlobals += global.llvmGlobal LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility) // See also [emitKt42254Hint]. } } } private fun ObjCExportCodeGenerator.setObjCExportTypeInfo( irClass: IrClass, converter: ConstPointer? = null, objCClass: ConstPointer? = null, typeAdapter: ConstPointer? = null ) { val writableTypeInfoValue = buildWritableTypeInfoValue( converter = converter, objCClass = objCClass, typeAdapter = typeAdapter ) if (codegen.isExternal(irClass)) { // Note: this global replaces the external one with common linkage. replaceExternalWeakOrCommonGlobal( irClass.writableTypeInfoSymbolName, writableTypeInfoValue, irClass.llvmSymbolOrigin ) } else { setOwnWritableTypeInfo(irClass, writableTypeInfoValue) } } private fun ObjCExportCodeGeneratorBase.setOwnWritableTypeInfo(irClass: IrClass, writableTypeInfoValue: Struct) { require(!codegen.isExternal(irClass)) val writeableTypeInfoGlobal = context.llvmDeclarations.forClass(irClass).writableTypeInfoGlobal!! writeableTypeInfoGlobal.setLinkage(LLVMLinkage.LLVMExternalLinkage) writeableTypeInfoGlobal.setInitializer(writableTypeInfoValue) } private fun ObjCExportCodeGeneratorBase.buildWritableTypeInfoValue( converter: ConstPointer? = null, objCClass: ConstPointer? = null, typeAdapter: ConstPointer? = null ): Struct { if (converter != null) { assert(converter.llvmType == pointerType(functionType(int8TypePtr, false, codegen.kObjHeaderPtr))) } val objCExportAddition = Struct(runtime.typeInfoObjCExportAddition, converter?.bitcast(int8TypePtr), objCClass, typeAdapter ) val writableTypeInfoType = runtime.writableTypeInfoType!! return Struct(writableTypeInfoType, objCExportAddition) } private val ObjCExportCodeGenerator.kotlinToObjCFunctionType: LLVMTypeRef get() = functionType(int8TypePtr, false, codegen.kObjHeaderPtr) private val ObjCExportCodeGeneratorBase.objCToKotlinFunctionType: LLVMTypeRef get() = functionType(codegen.kObjHeaderPtr, false, int8TypePtr, codegen.kObjHeaderPtrPtr) private fun ObjCExportCodeGenerator.emitBoxConverters() { val irBuiltIns = context.irBuiltIns emitBoxConverter(irBuiltIns.booleanClass, ObjCValueType.BOOL, "numberWithBool:") emitBoxConverter(irBuiltIns.byteClass, ObjCValueType.CHAR, "numberWithChar:") emitBoxConverter(irBuiltIns.shortClass, ObjCValueType.SHORT, "numberWithShort:") emitBoxConverter(irBuiltIns.intClass, ObjCValueType.INT, "numberWithInt:") emitBoxConverter(irBuiltIns.longClass, ObjCValueType.LONG_LONG, "numberWithLongLong:") emitBoxConverter(symbols.uByte, ObjCValueType.UNSIGNED_CHAR, "numberWithUnsignedChar:") emitBoxConverter(symbols.uShort, ObjCValueType.UNSIGNED_SHORT, "numberWithUnsignedShort:") emitBoxConverter(symbols.uInt, ObjCValueType.UNSIGNED_INT, "numberWithUnsignedInt:") emitBoxConverter(symbols.uLong, ObjCValueType.UNSIGNED_LONG_LONG, "numberWithUnsignedLongLong:") emitBoxConverter(irBuiltIns.floatClass, ObjCValueType.FLOAT, "numberWithFloat:") emitBoxConverter(irBuiltIns.doubleClass, ObjCValueType.DOUBLE, "numberWithDouble:") } private fun ObjCExportCodeGenerator.emitBoxConverter( boxClassSymbol: IrClassSymbol, objCValueType: ObjCValueType, nsNumberFactorySelector: String ) { val boxClass = boxClassSymbol.owner val name = "${boxClass.name}ToNSNumber" val converter = generateFunction(codegen, kotlinToObjCFunctionType, name) { val unboxFunction = context.getUnboxFunction(boxClass).llvmFunction val kotlinValue = callFromBridge( unboxFunction, listOf(param(0)), Lifetime.IRRELEVANT ) val value = kotlinToObjC(kotlinValue, objCValueType) val nsNumberSubclass = genGetLinkedClass(namer.numberBoxName(boxClass.classId!!).binaryName) ret(genSendMessage(int8TypePtr, nsNumberSubclass, nsNumberFactorySelector, value)) } LLVMSetLinkage(converter, LLVMLinkage.LLVMPrivateLinkage) setObjCExportTypeInfo(boxClass, constPointer(converter)) } private fun ObjCExportCodeGenerator.generateContinuationToCompletionConverter( blockGenerator: BlockGenerator ): LLVMValueRef = with(blockGenerator) { generateWrapKotlinObjectToBlock( BlockType(numberOfParameters = 2, returnsVoid = true), convertName = "convertContinuation", invokeName = "invokeCompletion" ) { continuation, arguments -> check(arguments.size == 2) callFromBridge(context.llvm.Kotlin_ObjCExport_resumeContinuation, listOf(continuation) + arguments) ret(null) } } private val ObjCExportBlockCodeGenerator.mappedFunctionNClasses get() = context.ir.symbols.functionIrClassFactory.builtFunctionNClasses .filter { it.descriptor.isMappedFunctionClass() } private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() { require(context.producedLlvmModuleContainsStdlib) mappedFunctionNClasses.forEach { functionClass -> val converter = kotlinFunctionToBlockConverter(BlockPointerBridge(functionClass.arity, returnsVoid = false)) val writableTypeInfoValue = buildWritableTypeInfoValue(converter = constPointer(converter)) setOwnWritableTypeInfo(functionClass.irClass, writableTypeInfoValue) } } private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() { require(context.producedLlvmModuleContainsStdlib) val functionClassesByArity = mappedFunctionNClasses.associateBy { it.arity } val arityLimit = (functionClassesByArity.keys.maxOrNull() ?: -1) + 1 val converters = (0 until arityLimit).map { arity -> functionClassesByArity[arity]?.let { val bridge = BlockPointerBridge(numberOfParameters = arity, returnsVoid = false) constPointer(blockToKotlinFunctionConverter(bridge)) } ?: NullPointer(objCToKotlinFunctionType) } val ptr = staticData.placeGlobalArray( "", pointerType(objCToKotlinFunctionType), converters ).pointer.getElementPtr(0) // Note: defining globals declared in runtime. staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters", ptr, isExported = true) staticData.placeGlobal("Kotlin_ObjCExport_blockToFunctionConverters_size", Int32(arityLimit), isExported = true) } private fun ObjCExportCodeGenerator.emitSpecialClassesConvertions() { setObjCExportTypeInfo( symbols.string.owner, constPointer(context.llvm.Kotlin_ObjCExport_CreateNSStringFromKString) ) emitCollectionConverters() emitBoxConverters() } private fun ObjCExportCodeGenerator.emitCollectionConverters() { fun importConverter(name: String): ConstPointer = constPointer(context.llvm.externalFunction( name, kotlinToObjCFunctionType, CurrentKlibModuleOrigin )) setObjCExportTypeInfo( symbols.list.owner, importConverter("Kotlin_Interop_CreateNSArrayFromKList") ) setObjCExportTypeInfo( symbols.mutableList.owner, importConverter("Kotlin_Interop_CreateNSMutableArrayFromKList") ) setObjCExportTypeInfo( symbols.set.owner, importConverter("Kotlin_Interop_CreateNSSetFromKSet") ) setObjCExportTypeInfo( symbols.mutableSet.owner, importConverter("Kotlin_Interop_CreateKotlinMutableSetFromKSet") ) setObjCExportTypeInfo( symbols.map.owner, importConverter("Kotlin_Interop_CreateNSDictionaryFromKMap") ) setObjCExportTypeInfo( symbols.mutableMap.owner, importConverter("Kotlin_Interop_CreateKotlinMutableDictonaryFromKMap") ) } private inline fun ObjCExportCodeGenerator.generateObjCImpBy( methodBridge: MethodBridge, debugInfo: Boolean = false, genBody: FunctionGenerationContext.() -> Unit ): LLVMValueRef { val result = addLlvmFunctionWithDefaultAttributes( context, context.llvmModule!!, "objc2kotlin", objCFunctionType(context, methodBridge) ) val location = if (debugInfo) { setupBridgeDebugInfo(context, result) } else { null } generateFunction(codegen, result, startLocation = location, endLocation = location) { genBody() } LLVMSetLinkage(result, LLVMLinkage.LLVMInternalLinkage) return result } private fun ObjCExportCodeGenerator.generateAbstractObjCImp(methodBridge: MethodBridge): LLVMValueRef = generateObjCImpBy(methodBridge) { callFromBridge( context.llvm.Kotlin_ObjCExport_AbstractMethodCalled, listOf(param(0), param(1)) ) unreachable() } private fun ObjCExportCodeGenerator.generateObjCImp( target: IrFunction?, baseMethod: IrFunction, methodBridge: MethodBridge, isVirtual: Boolean = false ) = if (target == null) { generateAbstractObjCImp(methodBridge) } else { generateObjCImp( methodBridge, isDirect = !isVirtual, baseMethod = baseMethod ) { args, resultLifetime, exceptionHandler -> val llvmTarget = if (!isVirtual) { codegen.llvmFunction(target) } else { lookupVirtualImpl(args.first(), target) } call(llvmTarget, args, resultLifetime, exceptionHandler) } } private fun ObjCExportCodeGenerator.generateObjCImp( methodBridge: MethodBridge, isDirect: Boolean, baseMethod: IrFunction? = null, callKotlin: FunctionGenerationContext.( args: List, resultLifetime: Lifetime, exceptionHandler: ExceptionHandler ) -> LLVMValueRef? ): LLVMValueRef = generateObjCImpBy(methodBridge, debugInfo = isDirect /* see below */) { // Considering direct calls inlinable above. If such a call is inlined into a bridge with no debug information, // lldb will not decode the inlined frame even if the callee has debug information. // So generate dummy debug information for bridge in this case. // TODO: consider adding debug info to other bridges. val returnType = methodBridge.returnBridge // TODO: call [NSObject init] if it is a constructor? // TODO: check for abstract class if it is a constructor. if (!methodBridge.isInstance) { initRuntimeIfNeeded() // For instance methods it gets called when allocating. } var errorOutPtr: LLVMValueRef? = null var continuation: LLVMValueRef? = null val kotlinArgs = methodBridge.paramBridges.mapIndexedNotNull { index, paramBridge -> val parameter = param(index) when (paramBridge) { is MethodBridgeValueParameter.Mapped -> objCToKotlin(parameter, paramBridge.bridge, Lifetime.ARGUMENT) MethodBridgeReceiver.Static, MethodBridgeSelector -> null MethodBridgeReceiver.Instance -> objCReferenceToKotlin(parameter, Lifetime.ARGUMENT) MethodBridgeReceiver.Factory -> null // actual value added by [callKotlin]. MethodBridgeValueParameter.ErrorOutParameter -> { assert(errorOutPtr == null) errorOutPtr = parameter null } MethodBridgeValueParameter.SuspendCompletion -> { callFromBridge( context.llvm.Kotlin_ObjCExport_createContinuationArgument, listOf(parameter, generateExceptionTypeInfoArray(baseMethod!!)), Lifetime.ARGUMENT ).also { continuation = it } } } } // TODO: consider merging this handler with function cleanup. val exceptionHandler = when { errorOutPtr != null -> kotlinExceptionHandler { exception -> callFromBridge( context.llvm.Kotlin_ObjCExport_RethrowExceptionAsNSError, listOf(exception, errorOutPtr!!, generateExceptionTypeInfoArray(baseMethod!!)) ) val returnValue = when (returnType) { !is MethodBridge.ReturnValue.WithError -> error("bridge with error parameter has unexpected return type: $returnType") MethodBridge.ReturnValue.WithError.Success -> Int8(0).llvm // false is MethodBridge.ReturnValue.WithError.ZeroForError -> { if (returnType.successBridge == MethodBridge.ReturnValue.Instance.InitResult) { // Release init receiver, as required by convention. callFromBridge(objcRelease, listOf(param(0))) } Zero(returnType.objCType(context)).llvm } } ret(returnValue) } continuation != null -> kotlinExceptionHandler { exception -> // Callee haven't suspended, so it isn't going to call the completion. Call it here: callFromBridge( context.ir.symbols.objCExportResumeContinuationWithException.owner.llvmFunction, listOf(continuation!!, exception) ) // Note: completion block could be called directly instead, but this implementation is // simpler and avoids duplication. ret(null) } else -> kotlinExceptionHandler { exception -> callFromBridge(symbols.objCExportTrapOnUndeclaredException.owner.llvmFunction, listOf(exception)) unreachable() } } val targetResult = callKotlin(kotlinArgs, Lifetime.ARGUMENT, exceptionHandler) tailrec fun genReturnValueOnSuccess(returnBridge: MethodBridge.ReturnValue): LLVMValueRef? = when (returnBridge) { MethodBridge.ReturnValue.Void -> null MethodBridge.ReturnValue.HashCode -> { val kotlinHashCode = targetResult!! if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, int64Type) else kotlinHashCode } is MethodBridge.ReturnValue.Mapped -> kotlinToObjC(targetResult!!, returnBridge.bridge) MethodBridge.ReturnValue.WithError.Success -> Int8(1).llvm // true is MethodBridge.ReturnValue.WithError.ZeroForError -> genReturnValueOnSuccess(returnBridge.successBridge) MethodBridge.ReturnValue.Instance.InitResult -> param(0) MethodBridge.ReturnValue.Instance.FactoryResult -> kotlinReferenceToObjC(targetResult!!) // provided by [callKotlin] MethodBridge.ReturnValue.Suspend -> { val coroutineSuspended = callFromBridge( codegen.llvmFunction(context.ir.symbols.objCExportGetCoroutineSuspended.owner), emptyList(), Lifetime.STACK ) ifThen(icmpNe(targetResult!!, coroutineSuspended)) { // Callee haven't suspended, so it isn't going to call the completion. Call it here: callFromBridge( context.ir.symbols.objCExportResumeContinuation.owner.llvmFunction, listOf(continuation!!, targetResult) ) // Note: completion block could be called directly instead, but this implementation is // simpler and avoids duplication. } null } } ret(genReturnValueOnSuccess(returnType)) } private fun ObjCExportCodeGenerator.generateExceptionTypeInfoArray(baseMethod: IrFunction): LLVMValueRef = exceptionTypeInfoArrays.getOrPut(baseMethod) { val types = effectiveThrowsClasses(baseMethod, symbols) generateTypeInfoArray(types.toSet()) }.llvm private fun ObjCExportCodeGenerator.generateTypeInfoArray(types: Set): ConstPointer = typeInfoArrays.getOrPut(types) { val typeInfos = types.map { with(codegen) { it.typeInfoPtr } } + NullPointer(codegen.kTypeInfo) codegen.staticData.placeGlobalConstArray("", codegen.kTypeInfoPtr, typeInfos) } private fun effectiveThrowsClasses(method: IrFunction, symbols: KonanSymbols): List { if (method is IrSimpleFunction && method.overriddenSymbols.isNotEmpty()) { return effectiveThrowsClasses(method.overriddenSymbols.first().owner, symbols) } val throwsAnnotation = method.annotations.findAnnotation(KonanFqNames.throws) ?: return if (method.isSuspend) { listOf(symbols.cancellationException.owner) } else { // Note: frontend ensures that all topmost overridden methods have (equal) @Throws annotations. // However due to linking different versions of libraries IR could end up not meeting this condition. // Handling missing annotation gracefully: emptyList() } val throwsVararg = throwsAnnotation.getValueArgument(0) ?: return emptyList() if (throwsVararg !is IrVararg) error(method.getContainingFile(), throwsVararg, "unexpected vararg") return throwsVararg.elements.map { (it as? IrClassReference)?.symbol?.owner as? IrClass ?: error(method.getContainingFile(), it, "unexpected @Throws argument") } } private fun ObjCExportCodeGenerator.generateObjCImpForArrayConstructor( target: IrConstructor, methodBridge: MethodBridge ): LLVMValueRef = generateObjCImp(methodBridge, isDirect = true) { args, resultLifetime, exceptionHandler -> val arrayInstance = callFromBridge( context.llvm.allocArrayFunction, listOf(target.constructedClass.llvmTypeInfoPtr, args.first()), resultLifetime = Lifetime.ARGUMENT ) call(target.llvmFunction, listOf(arrayInstance) + args, resultLifetime, exceptionHandler) arrayInstance } // TODO: cache bridges. private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge( irFunction: IrFunction, baseMethod: ObjCMethodSpec.BaseMethod ): ConstPointer { val baseIrFunction = baseMethod.symbol.owner val methodBridge = baseMethod.bridge val parameterToBase = irFunction.allParameters.zip(baseIrFunction.allParameters).toMap() val objcMsgSend = msgSender(objCFunctionType(context, methodBridge)) val functionType = codegen.getLlvmFunctionType(irFunction) val result = generateFunction(codegen, functionType, "kotlin2objc") { var errorOutPtr: LLVMValueRef? = null val parameters = irFunction.allParameters.mapIndexed { index, parameterDescriptor -> parameterDescriptor to param(index) }.toMap() val objCArgs = methodBridge.parametersAssociated(irFunction).map { (bridge, parameter) -> when (bridge) { is MethodBridgeValueParameter.Mapped -> { parameter!! val kotlinValue = convertKotlin( { parameters[parameter]!! }, actualType = parameter.type, expectedType = parameterToBase[parameter]!!.type, resultLifetime = Lifetime.ARGUMENT ) kotlinToObjC(kotlinValue, bridge.bridge) } MethodBridgeReceiver.Instance -> kotlinReferenceToObjC(parameters[parameter]!!) MethodBridgeSelector -> { val selector = baseMethod.selector // Selector is referenced thus should be defined to avoid false positive non-public API rejection: selectorsToDefine[selector] = methodBridge genSelector(selector) } MethodBridgeReceiver.Static, MethodBridgeReceiver.Factory -> error("Method is not instance and thus can't have bridge for overriding: $baseMethod") MethodBridgeValueParameter.ErrorOutParameter -> alloca(int8TypePtr).also { store(kNullInt8Ptr, it) errorOutPtr = it } MethodBridgeValueParameter.SuspendCompletion -> { val continuation = param(irFunction.allParametersCount) // The last argument. // TODO: consider placing interception into the converter to reduce code size. val intercepted = callFromBridge( context.ir.symbols.objCExportInterceptedContinuation.owner.llvmFunction, listOf(continuation), Lifetime.ARGUMENT ) callFromBridge(continuationToCompletionConverter, listOf(intercepted)) } } } val targetResult = callFromBridge(objcMsgSend, objCArgs) assert(baseMethod.symbol !is IrConstructorSymbol) fun rethrow() { val error = load(errorOutPtr!!) callFromBridge(context.llvm.Kotlin_ObjCExport_RethrowNSErrorAsException, listOf(error)) unreachable() } fun genKotlinBaseMethodResult( lifetime: Lifetime, returnBridge: MethodBridge.ReturnValue ): LLVMValueRef? = when (returnBridge) { MethodBridge.ReturnValue.Void -> null MethodBridge.ReturnValue.HashCode -> { if (codegen.context.is64BitNSInteger()) { val low = trunc(targetResult, int32Type) val high = trunc(shr(targetResult, 32, signed = false), int32Type) xor(low, high) } else { targetResult } } is MethodBridge.ReturnValue.Mapped -> { objCToKotlin(targetResult, returnBridge.bridge, lifetime) } MethodBridge.ReturnValue.WithError.Success -> { ifThen(icmpEq(targetResult, Int8(0).llvm)) { rethrow() } null } is MethodBridge.ReturnValue.WithError.ZeroForError -> { if (returnBridge.successMayBeZero) { val error = load(errorOutPtr!!) ifThen(icmpNe(error, kNullInt8Ptr)) { rethrow() } } else { ifThen(icmpEq(targetResult, kNullInt8Ptr)) { rethrow() } } genKotlinBaseMethodResult(lifetime, returnBridge.successBridge) } MethodBridge.ReturnValue.Instance.InitResult, MethodBridge.ReturnValue.Instance.FactoryResult -> error("init or factory method can't have bridge for overriding: $baseMethod") MethodBridge.ReturnValue.Suspend -> { // Objective-C implementation of Kotlin suspend function is always responsible // for calling the completion, so in Kotlin coroutines machinery terms it suspends, // which is indicated by the return value: callFromBridge( context.ir.symbols.objCExportGetCoroutineSuspended.owner.llvmFunction, emptyList(), Lifetime.RETURN_VALUE ) } } val baseReturnType = baseIrFunction.returnType val actualReturnType = irFunction.returnType val retVal = when { baseIrFunction.isSuspend -> genKotlinBaseMethodResult(Lifetime.RETURN_VALUE, methodBridge.returnBridge) actualReturnType.isUnit() || actualReturnType.isNothing() -> { genKotlinBaseMethodResult(Lifetime.ARGUMENT, methodBridge.returnBridge) null } baseReturnType.isUnit() || baseReturnType.isNothing() -> { genKotlinBaseMethodResult(Lifetime.ARGUMENT, methodBridge.returnBridge) codegen.theUnitInstanceRef.llvm } else -> convertKotlin( { lifetime -> genKotlinBaseMethodResult(lifetime, methodBridge.returnBridge)!! }, actualType = baseReturnType, expectedType = actualReturnType, resultLifetime = Lifetime.RETURN_VALUE ) } ret(retVal) } LLVMSetLinkage(result, LLVMLinkage.LLVMPrivateLinkage) return constPointer(result) } private fun ObjCExportCodeGenerator.createReverseAdapter( irFunction: IrFunction, baseMethod: ObjCMethodSpec.BaseMethod, functionName: String, vtableIndex: Int?, itablePlace: ClassLayoutBuilder.InterfaceTablePlace? ): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter { val nameSignature = functionName.localHash.value val selector = baseMethod.selector val kotlinToObjC = generateKotlinToObjCBridge( irFunction, baseMethod ).bitcast(int8TypePtr) return KotlinToObjCMethodAdapter(selector, nameSignature, itablePlace ?: ClassLayoutBuilder.InterfaceTablePlace.INVALID, vtableIndex ?: -1, kotlinToObjC) } private fun ObjCExportCodeGenerator.createMethodVirtualAdapter( baseMethod: ObjCMethodSpec.BaseMethod ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val selector = baseMethod.selector val methodBridge = baseMethod.bridge val irFunction = baseMethod.symbol.owner val imp = generateObjCImp(irFunction, irFunction, methodBridge, isVirtual = true) return objCToKotlinMethodAdapter(selector, methodBridge, imp) } private fun ObjCExportCodeGenerator.createMethodAdapter( implementation: IrFunction?, baseMethod: ObjCMethodSpec.BaseMethod<*> ) = createMethodAdapter(DirectAdapterRequest(implementation, baseMethod)) private fun ObjCExportCodeGenerator.createFinalMethodAdapter( baseMethod: ObjCMethodSpec.BaseMethod ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val irFunction = baseMethod.symbol.owner require(irFunction.modality == Modality.FINAL) return createMethodAdapter(irFunction, baseMethod) } private fun ObjCExportCodeGenerator.createMethodAdapter( request: DirectAdapterRequest ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = this.directMethodAdapters.getOrPut(request) { val selectorName = request.base.selector val methodBridge = request.base.bridge val imp = generateObjCImp(request.implementation, request.base.symbol.owner, methodBridge) objCToKotlinMethodAdapter(selectorName, methodBridge, imp) } private fun ObjCExportCodeGenerator.createConstructorAdapter( baseMethod: ObjCMethodSpec.BaseMethod ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter = createMethodAdapter(baseMethod.symbol.owner, baseMethod) private fun ObjCExportCodeGenerator.createArrayConstructorAdapter( baseMethod: ObjCMethodSpec.BaseMethod ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val selectorName = baseMethod.selector val methodBridge = baseMethod.bridge val irConstructor = baseMethod.symbol.owner val imp = generateObjCImpForArrayConstructor(irConstructor, methodBridge) return objCToKotlinMethodAdapter(selectorName, methodBridge, imp) } private fun ObjCExportCodeGenerator.vtableIndex(irFunction: IrSimpleFunction): Int? { assert(irFunction.isOverridable) val irClass = irFunction.parentAsClass return if (irClass.isInterface) { null } else { context.getLayoutBuilder(irClass).vtableIndex(irFunction) } } private fun ObjCExportCodeGenerator.itablePlace(irFunction: IrSimpleFunction): ClassLayoutBuilder.InterfaceTablePlace? { assert(irFunction.isOverridable) val irClass = irFunction.parentAsClass return if (irClass.isInterface && context.ghaEnabled() && (irFunction.isReal || irFunction.resolveFakeOverrideMaybeAbstract().parent != context.irBuiltIns.anyClass.owner)) { context.getLayoutBuilder(irClass).itablePlace(irFunction) } else { null } } private fun ObjCExportCodeGenerator.createTypeAdapterForFileClass( fileClass: ObjCClassForKotlinFile ): ObjCExportCodeGenerator.ObjCTypeAdapter { val name = fileClass.binaryName val adapters = fileClass.methods.map { createFinalMethodAdapter(it.baseMethod) } return ObjCTypeAdapter( irClass = null, typeInfo = null, vtable = null, vtableSize = -1, methodTable = emptyList(), itable = emptyList(), itableSize = -1, objCName = name, directAdapters = emptyList(), classAdapters = adapters, virtualAdapters = emptyList(), reverseAdapters = emptyList() ) } private fun ObjCExportCodeGenerator.createTypeAdapter( type: ObjCTypeForKotlinType, superClass: ObjCClassForKotlinClass?, reverseAdapters: List ): ObjCExportCodeGenerator.ObjCTypeAdapter { val irClass = type.irClassSymbol.owner val adapters = mutableListOf() val classAdapters = mutableListOf() type.methods.forEach { when (it) { is ObjCInitMethodForKotlinConstructor -> { adapters += createConstructorAdapter(it.baseMethod) } is ObjCFactoryMethodForKotlinArrayConstructor -> { classAdapters += createArrayConstructorAdapter(it.baseMethod) } is ObjCGetterForKotlinEnumEntry -> { classAdapters += createEnumEntryAdapter(it.irEnumEntrySymbol.owner, it.selector) } is ObjCClassMethodForKotlinEnumValues -> { classAdapters += createEnumValuesAdapter(it.valuesFunctionSymbol.owner, it.selector) } is ObjCGetterForObjectInstance -> { classAdapters += if (irClass.isUnit()) { createUnitInstanceAdapter(it.selector) } else { createObjectInstanceAdapter(irClass, it.selector) } } is ObjCMethodForKotlinMethod -> {} // Handled below. }.let {} // Force exhaustive. } val additionalReverseAdapters = mutableListOf() if (type is ObjCClassForKotlinClass) { type.categoryMethods.forEach { adapters += createFinalMethodAdapter(it.baseMethod) additionalReverseAdapters += nonOverridableAdapter(it.baseMethod.selector, hasSelectorAmbiguity = false) } adapters += createDirectAdapters(type, superClass) } val virtualAdapters = type.kotlinMethods .filter { val irFunction = it.baseMethod.symbol.owner irFunction.parentAsClass == irClass && irFunction.isOverridable }.map { createMethodVirtualAdapter(it.baseMethod) } val typeInfo = constPointer(codegen.typeInfoValue(irClass)) val objCName = type.binaryName val vtableSize = if (irClass.kind == ClassKind.INTERFACE) { -1 } else { context.getLayoutBuilder(irClass).vtableEntries.size } val vtable = if (!irClass.isInterface && !irClass.typeInfoHasVtableAttached) { staticData.placeGlobal("", rttiGenerator.vtable(irClass)).also { it.setConstant(true) }.pointer.getElementPtr(0) } else { null } val methodTable = if (!irClass.isInterface && irClass.isAbstract()) { rttiGenerator.methodTableRecords(irClass) } else { emptyList() } val (itable, itableSize) = when { irClass.isInterface -> Pair(emptyList(), context.getLayoutBuilder(irClass).interfaceTableEntries.size) irClass.isAbstract() && context.ghaEnabled() -> rttiGenerator.interfaceTableRecords(irClass) else -> Pair(emptyList(), -1) } return ObjCTypeAdapter( irClass, typeInfo, vtable, vtableSize, methodTable, itable, itableSize, objCName, adapters, classAdapters, virtualAdapters, reverseAdapters + additionalReverseAdapters ) } private fun ObjCExportCodeGenerator.createReverseAdapters( types: List ): Map { val irClassSymbolToType = types.associateBy { it.irClassSymbol } val result = mutableMapOf() fun getOrCreateFor(type: ObjCTypeForKotlinType): ReverseAdapters = result.getOrPut(type) { // Each type also inherits reverse adapters from super types. // This is handled in runtime when building TypeInfo for Swift or Obj-C type // subclassing Kotlin classes or interfaces. See [createTypeInfo] in ObjCExport.mm. val allSuperClasses = DFS.dfs( type.irClassSymbol.owner.superClasses, { it.owner.superClasses }, object : DFS.NodeHandlerWithListResult() { override fun afterChildren(current: IrClassSymbol) { this.result += current } } ) val inheritsAdaptersFrom = allSuperClasses.mapNotNull { irClassSymbolToType[it] } val inheritedAdapters = inheritsAdaptersFrom.map { getOrCreateFor(it) } createReverseAdapters(type, inheritedAdapters) } types.forEach { getOrCreateFor(it) } return result } private class ReverseAdapters( val adapters: List, val coveredMethods: Set ) private fun ObjCExportCodeGenerator.createReverseAdapters( type: ObjCTypeForKotlinType, inheritedAdapters: List ): ReverseAdapters { val result = mutableListOf() val coveredMethods = mutableSetOf() val methodsCoveredByInheritedAdapters = inheritedAdapters.flatMapTo(mutableSetOf()) { it.coveredMethods } val allBaseMethodsByIr = type.kotlinMethods.map { it.baseMethod }.associateBy { it.symbol.owner } for (method in type.irClassSymbol.owner.simpleFunctions()) { val baseMethods = method.allOverriddenFunctions.mapNotNull { allBaseMethodsByIr[it] } if (baseMethods.isEmpty()) continue val hasSelectorAmbiguity = baseMethods.map { it.selector }.distinct().size > 1 if (method.isOverridable && !hasSelectorAmbiguity) { val baseMethod = baseMethods.first() val presentVtableBridges = mutableSetOf(null) val presentMethodTableBridges = mutableSetOf() val presentItableBridges = mutableSetOf(null) val allOverriddenMethods = method.allOverriddenFunctions val (inherited, uninherited) = allOverriddenMethods.partition { it in methodsCoveredByInheritedAdapters } inherited.forEach { presentVtableBridges += vtableIndex(it) presentMethodTableBridges += it.computeFunctionName() presentItableBridges += itablePlace(it) } uninherited.forEach { val vtableIndex = vtableIndex(it) val functionName = it.computeFunctionName() val itablePlace = itablePlace(it) if (vtableIndex !in presentVtableBridges || functionName !in presentMethodTableBridges || itablePlace !in presentItableBridges) { presentVtableBridges += vtableIndex presentMethodTableBridges += functionName presentItableBridges += itablePlace result += createReverseAdapter(it, baseMethod, functionName, vtableIndex, itablePlace) coveredMethods += it } } } else { // Mark it as non-overridable: baseMethods.map { it.selector }.distinct().forEach { result += nonOverridableAdapter(it, hasSelectorAmbiguity) } } } return ReverseAdapters(result, coveredMethods) } private fun ObjCExportCodeGenerator.nonOverridableAdapter( selector: String, hasSelectorAmbiguity: Boolean ): ObjCExportCodeGenerator.KotlinToObjCMethodAdapter = KotlinToObjCMethodAdapter( selector, -1, vtableIndex = if (hasSelectorAmbiguity) -2 else -1, // Describes the reason. kotlinImpl = NullPointer(int8Type), itablePlace = ClassLayoutBuilder.InterfaceTablePlace.INVALID ) private val ObjCTypeForKotlinType.kotlinMethods: List get() = this.methods.filterIsInstance() internal data class DirectAdapterRequest(val implementation: IrFunction?, val base: ObjCMethodSpec.BaseMethod<*>) private fun ObjCExportCodeGenerator.createDirectAdapters( typeDeclaration: ObjCClassForKotlinClass, superClass: ObjCClassForKotlinClass? ): List { fun ObjCClassForKotlinClass.getAllRequiredDirectAdapters() = this.kotlinMethods.map { method -> DirectAdapterRequest( findImplementation(irClassSymbol.owner, method.baseMethod.symbol.owner, context), method.baseMethod ) } val inheritedAdapters = superClass?.getAllRequiredDirectAdapters().orEmpty() val requiredAdapters = typeDeclaration.getAllRequiredDirectAdapters() - inheritedAdapters return requiredAdapters.distinctBy { it.base.selector }.map { createMethodAdapter(it) } } private fun findImplementation(irClass: IrClass, method: IrSimpleFunction, context: Context): IrSimpleFunction? { val override = irClass.simpleFunctions().singleOrNull { method in it.allOverriddenFunctions } ?: error("no implementation for ${method.render()}\nin ${irClass.fqNameWhenAvailable}") return OverriddenFunctionInfo(override, method).getImplementation(context) } private inline fun ObjCExportCodeGenerator.generateObjCToKotlinSyntheticGetter( selector: String, block: FunctionGenerationContext.() -> Unit ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val methodBridge = MethodBridge( MethodBridge.ReturnValue.Mapped(ReferenceBridge), MethodBridgeReceiver.Static, valueParameters = emptyList() ) val imp = generateFunction(codegen, objCFunctionType(context, methodBridge), "objc2kotlin") { block() } LLVMSetLinkage(imp, LLVMLinkage.LLVMPrivateLinkage) return objCToKotlinMethodAdapter(selector, methodBridge, imp) } private fun ObjCExportCodeGenerator.objCToKotlinMethodAdapter( selector: String, methodBridge: MethodBridge, imp: LLVMValueRef ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { selectorsToDefine[selector] = methodBridge return ObjCToKotlinMethodAdapter(selector, getEncoding(methodBridge), constPointer(imp)) } private fun ObjCExportCodeGenerator.createUnitInstanceAdapter(selector: String) = generateObjCToKotlinSyntheticGetter(selector) { initRuntimeIfNeeded() // For instance methods it gets called when allocating. ret(callFromBridge(context.llvm.Kotlin_ObjCExport_convertUnit, listOf(codegen.theUnitInstanceRef.llvm))) } private fun ObjCExportCodeGenerator.createObjectInstanceAdapter( irClass: IrClass, selector: String ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { assert(irClass.kind == ClassKind.OBJECT) assert(!irClass.isUnit()) return generateObjCToKotlinSyntheticGetter(selector) { initRuntimeIfNeeded() // For instance methods it gets called when allocating. val value = getObjectValue(irClass, startLocationInfo = null, exceptionHandler = ExceptionHandler.Caller) ret(kotlinToObjC(value, ReferenceBridge)) } } private fun ObjCExportCodeGenerator.createEnumEntryAdapter( irEnumEntry: IrEnumEntry, selector: String ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { return generateObjCToKotlinSyntheticGetter(selector) { initRuntimeIfNeeded() // For instance methods it gets called when allocating. val value = getEnumEntry(irEnumEntry, ExceptionHandler.Caller) ret(kotlinToObjC(value, ReferenceBridge)) } } private fun ObjCExportCodeGenerator.createEnumValuesAdapter( valuesFunction: IrFunction, selector: String ): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter { val methodBridge = MethodBridge( returnBridge = MethodBridge.ReturnValue.Mapped(ReferenceBridge), receiver = MethodBridgeReceiver.Static, valueParameters = emptyList() ) val imp = generateObjCImp(valuesFunction, valuesFunction, methodBridge, isVirtual = false) return objCToKotlinMethodAdapter(selector, methodBridge, imp) } private fun objCFunctionType(context: Context, methodBridge: MethodBridge): LLVMTypeRef { val paramTypes = methodBridge.paramBridges.map { it.objCType } val returnType = methodBridge.returnBridge.objCType(context) return functionType(returnType, false, *(paramTypes.toTypedArray())) } private val ObjCValueType.llvmType: LLVMTypeRef get() = when (this) { ObjCValueType.BOOL -> int8Type ObjCValueType.UNICHAR -> int16Type ObjCValueType.CHAR -> int8Type ObjCValueType.SHORT -> int16Type ObjCValueType.INT -> int32Type ObjCValueType.LONG_LONG -> int64Type ObjCValueType.UNSIGNED_CHAR -> int8Type ObjCValueType.UNSIGNED_SHORT -> int16Type ObjCValueType.UNSIGNED_INT -> int32Type ObjCValueType.UNSIGNED_LONG_LONG -> int64Type ObjCValueType.FLOAT -> floatType ObjCValueType.DOUBLE -> doubleType ObjCValueType.POINTER -> kInt8Ptr } private val MethodBridgeParameter.objCType: LLVMTypeRef get() = when (this) { is MethodBridgeValueParameter.Mapped -> this.bridge.objCType is MethodBridgeReceiver -> ReferenceBridge.objCType MethodBridgeSelector -> int8TypePtr MethodBridgeValueParameter.ErrorOutParameter -> pointerType(ReferenceBridge.objCType) MethodBridgeValueParameter.SuspendCompletion -> int8TypePtr } private fun MethodBridge.ReturnValue.objCType(context: Context): LLVMTypeRef { return when (this) { MethodBridge.ReturnValue.Suspend, MethodBridge.ReturnValue.Void -> voidType MethodBridge.ReturnValue.HashCode -> if (context.is64BitNSInteger()) int64Type else int32Type is MethodBridge.ReturnValue.Mapped -> this.bridge.objCType MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.llvmType MethodBridge.ReturnValue.Instance.InitResult, MethodBridge.ReturnValue.Instance.FactoryResult -> ReferenceBridge.objCType is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.objCType(context) } } private val TypeBridge.objCType: LLVMTypeRef get() = when (this) { is ReferenceBridge, is BlockPointerBridge -> int8TypePtr is ValueTypeBridge -> this.objCValueType.llvmType } internal fun ObjCExportCodeGenerator.getEncoding(methodBridge: MethodBridge): String { var paramOffset = 0 val params = buildString { methodBridge.paramBridges.forEach { append(it.objCEncoding) append(paramOffset) paramOffset += LLVMStoreSizeOfType(runtime.targetData, it.objCType).toInt() } } val returnTypeEncoding = methodBridge.returnBridge.getObjCEncoding(context) val paramSize = paramOffset return "$returnTypeEncoding$paramSize$params" } private fun MethodBridge.ReturnValue.getObjCEncoding(context: Context): String = when (this) { MethodBridge.ReturnValue.Suspend, MethodBridge.ReturnValue.Void -> "v" MethodBridge.ReturnValue.HashCode -> if (context.is64BitNSInteger()) "Q" else "I" is MethodBridge.ReturnValue.Mapped -> this.bridge.objCEncoding MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.encoding MethodBridge.ReturnValue.Instance.InitResult, MethodBridge.ReturnValue.Instance.FactoryResult -> ReferenceBridge.objCEncoding is MethodBridge.ReturnValue.WithError.ZeroForError -> this.successBridge.getObjCEncoding(context) } private val MethodBridgeParameter.objCEncoding: String get() = when (this) { is MethodBridgeValueParameter.Mapped -> this.bridge.objCEncoding is MethodBridgeReceiver -> ReferenceBridge.objCEncoding MethodBridgeSelector -> ":" MethodBridgeValueParameter.ErrorOutParameter -> "^${ReferenceBridge.objCEncoding}" MethodBridgeValueParameter.SuspendCompletion -> "@" } private val TypeBridge.objCEncoding: String get() = when (this) { ReferenceBridge, is BlockPointerBridge -> "@" is ValueTypeBridge -> this.objCValueType.encoding } private fun Context.is64BitNSInteger(): Boolean = when (val target = this.config.target) { KonanTarget.IOS_X64, KonanTarget.IOS_ARM64, KonanTarget.TVOS_ARM64, KonanTarget.TVOS_X64, KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64, KonanTarget.WATCHOS_X64 -> true KonanTarget.WATCHOS_ARM64, KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_X86, KonanTarget.IOS_ARM32 -> false KonanTarget.ANDROID_X64, KonanTarget.ANDROID_X86, KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64, KonanTarget.LINUX_X64, KonanTarget.MINGW_X86, KonanTarget.MINGW_X64, KonanTarget.LINUX_ARM64, KonanTarget.LINUX_ARM32_HFP, KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32, KonanTarget.WASM32, is KonanTarget.ZEPHYR -> error("Target $target has no support for NSInteger type.") } internal fun Context.is64BitLong(): Boolean = when (this.config.target) { KonanTarget.IOS_X64, KonanTarget.IOS_ARM64, KonanTarget.TVOS_ARM64, KonanTarget.TVOS_X64, KonanTarget.ANDROID_X64, KonanTarget.ANDROID_ARM64, KonanTarget.LINUX_ARM64, KonanTarget.MINGW_X64, KonanTarget.LINUX_X64, KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64, KonanTarget.WATCHOS_X64 -> true KonanTarget.WATCHOS_ARM64, KonanTarget.WATCHOS_ARM32, KonanTarget.ANDROID_X86, KonanTarget.ANDROID_ARM32, KonanTarget.WATCHOS_X86, KonanTarget.MINGW_X86, KonanTarget.LINUX_ARM32_HFP, KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32, KonanTarget.WASM32, is KonanTarget.ZEPHYR, KonanTarget.IOS_ARM32 -> false } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/visibility.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.utils.DFS /** * Applies hidden visibility to symbols similarly to LLVM's internalize pass: * it makes hidden the symbols that are made internal by internalize. */ fun makeVisibilityHiddenLikeLlvmInternalizePass(module: LLVMModuleRef) { // Note: the implementation below generally follows InternalizePass::internalizeModule, // but omits some details for simplicity. // TODO: LLVM handles some additional cases. val alwaysPreserved = getLlvmUsed(module) (getFunctions(module) + getGlobals(module) + getGlobalAliases(module)) .filter { when (LLVMGetLinkage(it)) { LLVMLinkage.LLVMInternalLinkage, LLVMLinkage.LLVMPrivateLinkage -> false else -> true } } .filter { LLVMIsDeclaration(it) == 0 } .minus(alwaysPreserved) .forEach { LLVMSetVisibility(it, LLVMVisibility.LLVMHiddenVisibility) } } private fun getLlvmUsed(module: LLVMModuleRef): Set { val llvmUsed = LLVMGetNamedGlobal(module, "llvm.used") ?: return emptySet() val llvmUsedValue = LLVMGetInitializer(llvmUsed) ?: return emptySet() // Note: llvm.used value is an array of globals, wrapped into bitcasts, GEPs and other instructions; // see llvm::collectUsedGlobalVariables. // Conservatively extract all involved globals for simplicity: return DFS.dfs( /* nodes = */ listOf(llvmUsedValue), /* neighbors = */ { value -> getOperands(value) }, object : DFS.CollectingNodeHandler>(mutableSetOf()) { override fun beforeChildren(current: LLVMValueRef): Boolean = when (LLVMGetValueKind(current)) { LLVMValueKind.LLVMGlobalAliasValueKind, LLVMValueKind.LLVMGlobalVariableValueKind, LLVMValueKind.LLVMFunctionValueKind -> { result.add(current) false // Skip children. } else -> true } } ) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.transformStatement import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name /** * Boxes and unboxes values of value types when necessary. */ internal class Autoboxing(val context: Context) : FileLoweringPass { private val transformer = AutoboxingTransformer(context) override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(transformer) irFile.transform(InlineClassTransformer(context), data = null) } } private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTransformer( context.builtIns, context.ir.symbols, context.irBuiltIns ) { // TODO: should we handle the cases when expression type // is not equal to e.g. called function return type? override fun IrExpression.useInTypeOperator(operator: IrTypeOperator, typeOperand: IrType): IrExpression { return if (operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT || operator == IrTypeOperator.IMPLICIT_INTEGER_COERCION) { this } else { // Codegen expects the argument of type-checking operator to be an object reference: this.useAs(context.irBuiltIns.anyNType) } } private var currentFunction: IrFunction? = null override fun visitFunction(declaration: IrFunction): IrStatement { currentFunction = declaration val result = super.visitFunction(declaration) currentFunction = null return result } override fun IrExpression.useAsReturnValue(returnTarget: IrReturnTargetSymbol): IrExpression = when (returnTarget) { is IrSimpleFunctionSymbol -> if (returnTarget.owner.isSuspend && returnTarget == currentFunction?.symbol) { this.useAs(irBuiltIns.anyNType) } else { this.useAs(returnTarget.owner.returnType) } is IrConstructorSymbol -> this.useAs(irBuiltIns.unitType) is IrReturnableBlockSymbol -> this.useAs(returnTarget.owner.type) else -> error(returnTarget) } override fun IrExpression.useAs(type: IrType): IrExpression { if (this.isNullConst() && type.isNullablePointer()) { // TODO: consider using IrConst with proper type. return IrCallImpl.fromSymbolDescriptor( startOffset, endOffset, symbols.getNativeNullPtr.owner.returnType, symbols.getNativeNullPtr, symbols.getNativeNullPtr.owner.typeParameters.size, symbols.getNativeNullPtr.owner.valueParameters.size ).uncheckedCast(type) } val actualType = when (this) { is IrCall -> { if (this.symbol.owner.isSuspend) irBuiltIns.anyNType else if (this.symbol == symbols.reinterpret) this.getTypeArgument(1)!! else this.callTarget.returnType } is IrGetField -> this.symbol.owner.type is IrTypeOperatorCall -> when (this.operator) { IrTypeOperator.IMPLICIT_INTEGER_COERCION -> // TODO: is it a workaround for inconsistent IR? this.typeOperand IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> context.irBuiltIns.anyNType else -> this.type } else -> this.type } return this.adaptIfNecessary(actualType, type) } private fun IrType.isNullablePointer(): Boolean = this.containsNull() && this.computePrimitiveBinaryTypeOrNull() == PrimitiveBinaryType.POINTER private val IrFunctionAccessExpression.target: IrFunction get() = when (this) { is IrCall -> this.callTarget is IrDelegatingConstructorCall -> this.symbol.owner is IrConstructorCall -> this.symbol.owner else -> TODO(this.render()) } private val IrCall.callTarget: IrFunction get() = if (superQualifierSymbol == null && symbol.owner.isOverridable) { // A virtual call. symbol.owner } else { symbol.owner.target } override fun IrExpression.useAsDispatchReceiver(expression: IrFunctionAccessExpression): IrExpression { return this.useAsArgument(expression.target.dispatchReceiverParameter!!) } override fun IrExpression.useAsExtensionReceiver(expression: IrFunctionAccessExpression): IrExpression { return this.useAsArgument(expression.target.extensionReceiverParameter!!) } override fun IrExpression.useAsValueArgument(expression: IrFunctionAccessExpression, parameter: IrValueParameter): IrExpression { return this.useAsArgument(expression.target.valueParameters[parameter.index]) } private fun IrExpression.adaptIfNecessary(actualType: IrType, expectedType: IrType): IrExpression { val conversion = symbols.getTypeConversion(actualType, expectedType) return if (conversion == null) { this } else { val parameter = conversion.owner.explicitParameters.single() val argument = this.uncheckedCast(parameter.type) IrCallImpl(startOffset, endOffset, conversion.owner.returnType, conversion, conversion.owner.typeParameters.size, conversion.owner.valueParameters.size).apply { addArguments(mapOf(parameter to argument)) }.uncheckedCast(this.type) // Try not to bring new type incompatibilities. } } override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { expression.transformChildrenVoid() assert(expression.getArgumentsWithIr().isEmpty()) return expression } /** * Casts this expression to `type` without changing its representation in generated code. */ @Suppress("UNUSED_PARAMETER") private fun IrExpression.uncheckedCast(type: IrType): IrExpression { // TODO: apply some cast if types are incompatible; not required currently. return this } override fun visitCall(expression: IrCall): IrExpression { return when (expression.symbol) { symbols.reinterpret -> { expression.transformChildrenVoid() // TODO: check types has the same binary representation. val oldType = expression.getTypeArgument(0)!! val newType = expression.getTypeArgument(1)!! assert(oldType.computePrimitiveBinaryTypeOrNull() == newType.computePrimitiveBinaryTypeOrNull()) expression.extensionReceiver = expression.extensionReceiver!!.useAs(oldType) expression } else -> super.visitCall(expression) } } } private class InlineClassTransformer(private val context: Context) : IrBuildingTransformer(context) { private val symbols = context.ir.symbols private val irBuiltIns = context.irBuiltIns private val builtBoxUnboxFunctions = mutableListOf() override fun visitFile(declaration: IrFile): IrFile { declaration.transformChildrenVoid(this) declaration.declarations.addAll(builtBoxUnboxFunctions) builtBoxUnboxFunctions.clear() return declaration } override fun visitClass(declaration: IrClass): IrStatement { super.visitClass(declaration) if (declaration.isInlined()) { if (declaration.isUsedAsBoxClass()) { if (declaration.isNativePrimitiveType()) { buildBoxField(declaration) } buildBoxFunction(declaration, context.getBoxFunction(declaration)) buildUnboxFunction(declaration, context.getUnboxFunction(declaration)) } if (declaration.isNativePrimitiveType()) { // Constructors for these types aren't used and actually are malformed (e.g. lack the parameter). // Skipping here for simplicity. } else { declaration.constructors.toList().mapTo(declaration.declarations) { context.getLoweredInlineClassConstructor(it) } } } return declaration } override fun visitGetField(expression: IrGetField): IrExpression { super.visitGetField(expression) val field = expression.symbol.owner val parentClass = field.parentClassOrNull return if (parentClass == null || !parentClass.isInlined()) expression else { builder.at(expression) .irCall(symbols.reinterpret, field.type, listOf(parentClass.defaultType, field.type) ).apply { extensionReceiver = expression.receiver!! } } } override fun visitSetField(expression: IrSetField): IrExpression { super.visitSetField(expression) return if (expression.symbol.owner.parentClassOrNull?.isInlined() == true) { // Happens in one of the cases: // 1. In primary constructor of the inlined class. Makes no sense, "has no effect", can be removed. // The constructor will be lowered and used. // 2. In setter of NativePointed.rawPtr. It is generally a hack and isn't actually used. // TODO: it is better to get rid of it. // // So drop the entire IrSetField: return builder.irComposite(expression) {} } else { expression } } override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { super.visitConstructorCall(expression) val constructor = expression.symbol.owner return if (constructor.constructedClass.isInlined()) { builder.lowerConstructorCallToValue(expression, constructor) } else { expression } } override fun visitConstructor(declaration: IrConstructor): IrStatement { super.visitConstructor(declaration) if (declaration.constructedClass.isInlined()) { if (declaration.constructedClass.isNativePrimitiveType()) { // Constructors for these types aren't used and actually are malformed (e.g. lack the parameter). // Skipping here for simplicity. } else { buildLoweredConstructor(declaration) } // TODO: fix DFG building and nullify the body instead. (declaration.body as IrBlockBody).statements.clear() } return declaration } override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) // Make replacement only in optimized builds due to separate compilation and possibility to get broken // debug information. if (!context.shouldOptimize()) return expression val property = expression.symbol.owner.correspondingPropertySymbol?.owner ?: return expression property.parent.let { if (it is IrClass && it.isInline && property.backingField != null) { expression.dispatchReceiver?.let { receiver -> return builder.at(expression) .irCall(symbols.reinterpret, expression.type, listOf(receiver.type, expression.type)) .apply { extensionReceiver = receiver } } } } return expression } private fun IrBuilderWithScope.irIsNull(expression: IrExpression): IrExpression { val binary = expression.type.computeBinaryType() return when (binary) { is BinaryType.Primitive -> { assert(binary.type == PrimitiveBinaryType.POINTER) irCall(symbols.areEqualByValue[binary.type]!!.owner).apply { putValueArgument(0, expression) putValueArgument(1, irNullPointer()) } } is BinaryType.Reference -> irCall(context.irBuiltIns.eqeqeqSymbol).apply { putValueArgument(0, expression) putValueArgument(1, irNull()) } } } private fun buildBoxFunction(irClass: IrClass, function: IrFunction) { val builder = context.createIrBuilder(function.symbol) val cache = BoxCache.values().toList().atMostOne { context.irBuiltIns.getKotlinClass(it) == irClass } function.body = builder.irBlockBody(function) { val valueToBox = function.valueParameters[0] if (valueToBox.type.containsNull()) { +irIfThen( condition = irIsNull(irGet(valueToBox)), thenPart = irReturn(irNull()) ) } if (cache != null) { +irIfThen( condition = irCall(symbols.boxCachePredicates[cache]!!.owner).apply { putValueArgument(0, irGet(valueToBox)) }, thenPart = irReturn(irCall(symbols.boxCacheGetters[cache]!!.owner).apply { putValueArgument(0, irGet(valueToBox)) }) ) } // Note: IR variable created below has reference type intentionally. val box = irTemporary(irCall(symbols.createUninitializedInstance.owner).also { it.putTypeArgument(0, irClass.defaultType) }) +irSetField(irGet(box), getInlineClassBackingField(irClass), irGet(valueToBox)) +irReturn(irGet(box)) } builtBoxUnboxFunctions += function } private fun IrBuilderWithScope.irNullPointerOrReference(type: IrType): IrExpression = if (type.binaryTypeIsReference()) { irNull() } else { irNullPointer() } private fun IrBuilderWithScope.irNullPointer(): IrExpression = irCall(symbols.getNativeNullPtr.owner) private fun buildUnboxFunction(irClass: IrClass, function: IrFunction) { val builder = context.createIrBuilder(function.symbol) function.body = builder.irBlockBody(function) { val boxParameter = function.valueParameters.single() if (boxParameter.type.containsNull()) { +irIfThen( condition = irEqeqeq(irGet(boxParameter), irNull()), thenPart = irReturn(irNullPointerOrReference(function.returnType)) ) } +irReturn(irGetField(irGet(boxParameter), getInlineClassBackingField(irClass))) } builtBoxUnboxFunctions += function } private fun buildBoxField(declaration: IrClass) { val startOffset = declaration.startOffset val endOffset = declaration.endOffset val irField = IrFieldImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrFieldSymbolImpl(), Name.identifier("value"), declaration.defaultType, DescriptorVisibilities.PRIVATE, isFinal = true, isExternal = false, isStatic = false, ) irField.parent = declaration val irProperty = IrPropertyImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrPropertySymbolImpl(), irField.name, irField.visibility, Modality.FINAL, isVar = false, isConst = false, isLateinit = false, isDelegated = false, isExternal = false ) irProperty.backingField = irField declaration.addChild(irProperty) } private fun IrBuilderWithScope.lowerConstructorCallToValue( expression: IrMemberAccessExpression<*>, callee: IrConstructor ): IrExpression { this.at(expression) val loweredConstructor = this@InlineClassTransformer.context.getLoweredInlineClassConstructor(callee) return if (callee.isPrimary) this.irBlock { val argument = irTemporary(expression.getValueArgument(0)!!) +irCall(loweredConstructor).apply { putValueArgument(0, irGet(argument)) } +irGet(argument) } else this.irCall(loweredConstructor).apply { (0 until expression.valueArgumentsCount).forEach { putValueArgument(it, expression.getValueArgument(it)!!) } } } private fun buildLoweredConstructor(irConstructor: IrConstructor) { val result = context.getLoweredInlineClassConstructor(irConstructor) val irClass = irConstructor.parentAsClass result.body = context.createIrBuilder(result.symbol).irBlockBody(result) { lateinit var thisVar: IrValueDeclaration fun IrBuilderWithScope.genReturnValue(): IrExpression = if (irConstructor.isPrimary) { irGetObject(irBuiltIns.unitClass) } else { irGet(thisVar) } val parameterMapping = result.valueParameters.associateBy { irConstructor.valueParameters[it.index].symbol } (irConstructor.body as IrBlockBody).statements.forEach { statement -> statement.setDeclarationsParent(result) +statement.transformStatement(object : IrElementTransformerVoid() { override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { expression.transformChildrenVoid() return irBlock(expression) { thisVar = if (irConstructor.isPrimary) { // Note: block is empty in this case. result.valueParameters.single() } else { val value = lowerConstructorCallToValue(expression, expression.symbol.owner) irTemporary(value) } } } override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid() if (expression.symbol == irClass.thisReceiver?.symbol) { return irGet(thisVar) } parameterMapping[expression.symbol]?.let { return irGet(it) } return expression } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid() parameterMapping[expression.symbol]?.let { return irSet(it.symbol, expression.value) } return expression } override fun visitReturn(expression: IrReturn): IrExpression { expression.transformChildrenVoid() if (expression.returnTargetSymbol == irConstructor.symbol) { return irReturn(irBlock(expression.startOffset, expression.endOffset) { +expression.value +genReturnValue() }) } return expression } }) } +irReturn(genReturnValue()) } } private fun getInlineClassBackingField(irClass: IrClass): IrField = irClass.declarations.filterIsInstance().mapNotNull { it.backingField }.single() } private val Context.getLoweredInlineClassConstructor: (IrConstructor) -> IrSimpleFunction by Context.lazyMapMember { irConstructor -> require(irConstructor.constructedClass.isInlined()) val returnType = if (irConstructor.isPrimary) { // Optimization. When constructor is primary, the return value will be the same as the argument. // So we can just use the argument on the call site. // This might be especially important for reference types, // to avoid redundant suboptimal "slot" machinery messing with this code. irBuiltIns.unitType } else { irConstructor.returnType } IrFunctionImpl( irConstructor.startOffset, irConstructor.endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), Name.special(""), irConstructor.visibility, Modality.FINAL, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, returnType = returnType, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { parent = irConstructor.parent // Note: technically speaking, this function doesn't have access to class type parameters (since it is "static"). // But, technically speaking, otherwise we would have to remap types in the entire IR subtree, // which is an overkill here, because type parameters don't matter at this phase of compilation and later. // So it is just a trick to make [copyTo] happy: val remapTypeMap = irConstructor.constructedClass.typeParameters.associateBy { it } valueParameters += irConstructor.valueParameters.map { it.copyTo(this, remapTypeMap = remapTypeMap) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.lower.irIfThen import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNullableAny import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.SpecialGenericSignatures internal class WorkersBridgesBuilding(val context: Context) : DeclarationContainerLoweringPass, IrElementTransformerVoid() { val symbols = context.ir.symbols lateinit var runtimeJobFunction: IrSimpleFunction override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.declarations.transformFlat { listOf(it) + buildWorkerBridges(it).also { bridges -> // `buildWorkerBridges` builds bridges for all declarations inside `it` and nested declarations, // so some bridges get incorrect parent. Fix it: bridges.forEach { bridge -> bridge.parent = irDeclarationContainer } } } } private fun buildWorkerBridges(declaration: IrDeclaration): List { val bridges = mutableListOf() declaration.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested. return declaration } override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) if (expression.symbol != symbols.executeImpl) return expression val job = expression.getValueArgument(3) as IrFunctionReference val jobFunction = (job.symbol as IrSimpleFunctionSymbol).owner if (!::runtimeJobFunction.isInitialized) { val arg = jobFunction.valueParameters[0] val startOffset = jobFunction.startOffset val endOffset = jobFunction.endOffset runtimeJobFunction = IrFunctionImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), jobFunction.name, jobFunction.visibility, jobFunction.modality, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, returnType = context.irBuiltIns.anyNType, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) runtimeJobFunction.valueParameters += IrValueParameterImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(), arg.name, arg.index, type = context.irBuiltIns.anyNType, varargElementType = null, isCrossinline = arg.isCrossinline, isNoinline = arg.isNoinline, isHidden = arg.isHidden, isAssignable = arg.isAssignable ) } val overriddenJobDescriptor = OverriddenFunctionInfo(jobFunction, runtimeJobFunction) if (!overriddenJobDescriptor.needBridge) return expression val bridge = context.buildBridge( startOffset = job.startOffset, endOffset = job.endOffset, overriddenFunction = overriddenJobDescriptor, targetSymbol = jobFunction.symbol) bridges += bridge expression.putValueArgument(3, IrFunctionReferenceImpl.fromSymbolDescriptor( startOffset = job.startOffset, endOffset = job.endOffset, type = job.type, symbol = bridge.symbol, typeArgumentsCount = 0, reflectionTarget = null) ) return expression } }) return bridges } } internal class BridgesBuilding(val context: Context) : ClassLoweringPass { override fun lower(irClass: IrClass) { val builtBridges = mutableSetOf() for (function in irClass.simpleFunctions()) { val set = mutableSetOf() for (overriddenFunction in function.allOverriddenFunctions) { val overriddenFunctionInfo = OverriddenFunctionInfo(function, overriddenFunction) val bridgeDirections = overriddenFunctionInfo.bridgeDirections if (!bridgeDirections.allNotNeeded() && overriddenFunctionInfo.canBeCalledVirtually && !overriddenFunctionInfo.inheritsBridge && set.add(bridgeDirections)) { buildBridge(overriddenFunctionInfo, irClass) builtBridges += function } } } irClass.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested. return declaration } override fun visitFunction(declaration: IrFunction): IrStatement { declaration.transformChildrenVoid(this) val body = declaration.body ?: return declaration val descriptor = declaration.descriptor val typeSafeBarrierDescription = BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor) if (typeSafeBarrierDescription == null || builtBridges.contains(declaration)) return declaration val irBuilder = context.createIrBuilder(declaration.symbol, declaration.startOffset, declaration.endOffset) declaration.body = irBuilder.irBlockBody(declaration) { buildTypeSafeBarrier(declaration, declaration, typeSafeBarrierDescription) (body as IrBlockBody).statements.forEach { +it } } return declaration } }) } private fun buildBridge(overriddenFunction: OverriddenFunctionInfo, irClass: IrClass) { irClass.declarations.add(context.buildBridge( startOffset = irClass.startOffset, endOffset = irClass.endOffset, overriddenFunction = overriddenFunction, targetSymbol = overriddenFunction.function.symbol, superQualifierSymbol = irClass.symbol) ) } } internal class DECLARATION_ORIGIN_BRIDGE_METHOD(val bridgeTarget: IrFunction) : IrDeclarationOrigin { override fun toString(): String { return "BRIDGE_METHOD(target=${bridgeTarget.descriptor})" } } internal val IrFunction.bridgeTarget: IrFunction? get() = (origin as? DECLARATION_ORIGIN_BRIDGE_METHOD)?.bridgeTarget private fun IrBuilderWithScope.returnIfBadType(value: IrExpression, type: IrType, returnValueOnFail: IrExpression) = irIfThen(irNotIs(value, type), irReturn(returnValueOnFail)) private fun IrBuilderWithScope.irConst(value: Any?) = when (value) { null -> irNull() is Int -> irInt(value) is Boolean -> if (value) irTrue() else irFalse() else -> TODO() } private fun IrBlockBodyBuilder.buildTypeSafeBarrier(function: IrFunction, originalFunction: IrFunction, typeSafeBarrierDescription: SpecialGenericSignatures.TypeSafeBarrierDescription) { val valueParameters = function.valueParameters val originalValueParameters = originalFunction.valueParameters for (i in valueParameters.indices) { if (!typeSafeBarrierDescription.checkParameter(i)) continue val type = originalValueParameters[i].type.erasureForTypeOperation() // Note: erasing to single type is not entirely correct if type parameter has multiple upper bounds. // In this case the compiler could generate multiple type checks, one for each upper bound. // But let's keep it simple here for now; JVM backend doesn't do this anyway. if (!type.isNullableAny()) { +returnIfBadType(irGet(valueParameters[i]), type, if (typeSafeBarrierDescription == SpecialGenericSignatures.TypeSafeBarrierDescription.MAP_GET_OR_DEFAULT) irGet(valueParameters[2]) else irConst(typeSafeBarrierDescription.defaultValue) ) } } } private fun Context.buildBridge(startOffset: Int, endOffset: Int, overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrSimpleFunctionSymbol, superQualifierSymbol: IrClassSymbol? = null): IrFunction { val bridge = specialDeclarationsFactory.getBridge(overriddenFunction) if (bridge.modality == Modality.ABSTRACT) { return bridge } val irBuilder = createIrBuilder(bridge.symbol, startOffset, endOffset) bridge.body = irBuilder.irBlockBody(bridge) { val typeSafeBarrierDescription = BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(overriddenFunction.overriddenFunction.descriptor) typeSafeBarrierDescription?.let { buildTypeSafeBarrier(bridge, overriddenFunction.function, it) } val delegatingCall = IrCallImpl.fromSymbolDescriptor( startOffset, endOffset, targetSymbol.owner.returnType, targetSymbol, typeArgumentsCount = targetSymbol.owner.typeParameters.size, valueArgumentsCount = targetSymbol.owner.valueParameters.size, superQualifierSymbol = superQualifierSymbol /* Call non-virtually */ ).apply { bridge.dispatchReceiverParameter?.let { dispatchReceiver = irGet(it) } bridge.extensionReceiverParameter?.let { extensionReceiver = irGet(it) } bridge.valueParameters.forEachIndexed { index, parameter -> this.putValueArgument(index, irGet(parameter)) } } +irReturn(delegatingCall) } return bridge } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BuiltinOperatorLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.containsNull import org.jetbrains.kotlin.backend.konan.ir.isSubtypeOf import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptor import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.defaultOrNullableType import org.jetbrains.kotlin.ir.util.isNullConst import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid /** * This lowering pass lowers some calls to [IrBuiltinOperatorDescriptor]s. */ internal class BuiltinOperatorLowering(val context: Context) : FileLoweringPass, IrBuildingTransformer(context) { private val irBuiltins = context.irModule!!.irBuiltins private val symbols = context.ir.symbols override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) } override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) return when (expression.symbol) { irBuiltins.eqeqSymbol, in ieee754EqualsSymbols() -> lowerEqeq(expression) irBuiltins.eqeqeqSymbol -> lowerEqeqeq(expression) irBuiltins.checkNotNullSymbol -> lowerCheckNotNull(expression) irBuiltins.noWhenBranchMatchedExceptionSymbol -> IrCallImpl.fromSymbolDescriptor( expression.startOffset, expression.endOffset, context.ir.symbols.throwNoWhenBranchMatchedException.owner.returnType, context.ir.symbols.throwNoWhenBranchMatchedException, context.ir.symbols.throwNoWhenBranchMatchedException.owner.typeParameters.size, context.ir.symbols.throwNoWhenBranchMatchedException.owner.valueParameters.size) else -> expression } } override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { expression.transformChildrenVoid(this) if (expression.argument.type.isNothing()) { return expression.argument } return expression } private fun ieee754EqualsSymbols(): List = irBuiltins.ieee754equalsFunByOperandType.values.toList() private fun lowerEqeqeq(expression: IrCall): IrExpression { val lhs = expression.getValueArgument(0)!! val rhs = expression.getValueArgument(1)!! return if (lhs.type.isInlinedNative() && rhs.type.isInlinedNative()) { // Achieve the same behavior as with JVM BE: if both sides of `===` are values, then compare by value: lowerEqeq(expression) // Note: such comparisons are deprecated. } else { expression } } private fun IrBuilderWithScope.reinterpret(expression: IrExpression, toType: IrType) = reinterpret(expression, expression.type, toType) private fun IrBuilderWithScope.reinterpret(expression: IrExpression, fromType: IrType, toType: IrType) = irCall(symbols.reinterpret.owner, listOf(fromType, toType)).apply { extensionReceiver = expression } private val anyEquals = irBuiltins.anyClass.owner.simpleFunctions().single { it.name.asString() == "equals" } private fun lowerEqeq(expression: IrCall): IrExpression { // TODO: optimize boxing? builder.at(expression).run { val lhs = expression.getValueArgument(0)!! val rhs = expression.getValueArgument(1)!! if (rhs.isNullConst()) { return irEqeqNull(lhs) } if (lhs.isNullConst()) { return irEqeqNull(rhs) } if (expression.symbol == irBuiltins.eqeqSymbol) { lhs.type.getInlinedClassNative()?.let { if (it == rhs.type.getInlinedClassNative() && inlinedClassHasDefaultEquals(it)) { return genInlineClassEquals(expression.symbol, rhs, lhs) } } } return genFloatingOrReferenceEquals(expression.symbol, lhs, rhs) } } private fun inlinedClassHasDefaultEquals(irClass: IrClass): Boolean { if (!irClass.isInline) { // Implicitly-inlined class, e.g. primitive one. return true } val equals = irClass.simpleFunctions() .single { it.name.asString() == "equals" && it.valueParameters.size == 1 && it.overrides(anyEquals) } return equals.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER } fun IrBuilderWithScope.genInlineClassEquals( symbol: IrFunctionSymbol, rhs: IrExpression, lhs: IrExpression ): IrExpression { val lhsBinaryType = lhs.type.computeBinaryType() return when (lhsBinaryType) { is BinaryType.Primitive -> { val areEqualByValue = symbols.areEqualByValue[lhsBinaryType.type]!!.owner irCall(areEqualByValue).apply { putValueArgument(0, reinterpret(lhs, areEqualByValue.valueParameters[0].type)) putValueArgument(1, reinterpret(rhs, areEqualByValue.valueParameters[1].type)) } } is BinaryType.Reference -> { // TODO: don't use binaryType.nullable. val lhsRawType = irBuiltins.anyClass.owner.defaultOrNullableType(lhsBinaryType.nullable) val rhsBinaryType = rhs.type.computeBinaryType() as BinaryType.Reference<*> val rhsRawType = irBuiltins.anyClass.owner.defaultOrNullableType(rhsBinaryType.nullable) genFloatingOrReferenceEquals( symbol, reinterpret(lhs, lhsRawType), reinterpret(rhs, rhsRawType) ) } } } private fun IrBuilderWithScope.irEqeqNull(expression: IrExpression): IrExpression { val type = expression.type.makeNullable() return when (val primitiveBinaryTypeOrNull = type.computePrimitiveBinaryTypeOrNull()) { null -> irEqeqeq(reinterpret(expression, type, irBuiltins.anyNType), irNull()) PrimitiveBinaryType.POINTER -> irCall(symbols.areEqualByValue[PrimitiveBinaryType.POINTER]!!.owner).apply { putValueArgument(0, reinterpret(expression, type, symbols.nativePtrType)) putValueArgument(1, reinterpret(irNull(), type, symbols.nativePtrType)) } else -> error("Nullable type ${type.render()} is $primitiveBinaryTypeOrNull") } } private fun lowerCheckNotNull(expression: IrCall) = builder.at(expression).irBlock(resultType = expression.type) { val temp = irTemporary(expression.getValueArgument(0)!!) +irIfThen(context.irBuiltIns.unitType, irEqeqNull(irGet(temp)), irCall(symbols.throwNullPointerException)) +irGet(temp) } private fun IrBuilderWithScope.irLogicalAnd(lhs: IrExpression, rhs: IrExpression) = context.andand(lhs, rhs) private fun IrBuilderWithScope.irIsNull(exp: IrExpression) = irEqeqeq(exp, irNull()) private fun IrBuilderWithScope.irIsNotNull(exp: IrExpression) = irNot(irEqeqeq(exp, irNull())) private fun IrBuilderWithScope.genFloatingOrReferenceEquals(symbol: IrFunctionSymbol, lhs: IrExpression, rhs: IrExpression): IrExpression { // TODO: areEqualByValue and ieee754Equals intrinsics are specially treated by code generator // and thus can be declared synthetically in the compiler instead of explicitly in the runtime. fun callEquals(lhs: IrExpression, rhs: IrExpression) = if (symbol in ieee754EqualsSymbols()) // Find a type-compatible `konan.internal.ieee754Equals` intrinsic: irCall(selectIntrinsic(symbols.ieee754Equals, lhs.type, rhs.type, true)!!).apply { putValueArgument(0, lhs) putValueArgument(1, rhs) } else irCall(symbols.equals).apply { dispatchReceiver = lhs putValueArgument(0, rhs) } val lhsIsNotNullable = !lhs.type.containsNull() val rhsIsNotNullable = !rhs.type.containsNull() return if (symbol in ieee754EqualsSymbols()) { if (lhsIsNotNullable && rhsIsNotNullable) callEquals(lhs, rhs) else irBlock { val lhsTemp = irTemporary(lhs) val rhsTemp = irTemporary(rhs) if (lhsIsNotNullable xor rhsIsNotNullable) { // Exactly one nullable. +irLogicalAnd( irIsNotNull(irGet(if (lhsIsNotNullable) rhsTemp else lhsTemp)), callEquals(irGet(lhsTemp), irGet(rhsTemp)) ) } else { // Both are nullable. +irIfThenElse(context.irBuiltIns.booleanType, irIsNull(irGet(lhsTemp)), irIsNull(irGet(rhsTemp)), irLogicalAnd( irIsNotNull(irGet(rhsTemp)), callEquals(irGet(lhsTemp), irGet(rhsTemp)) ) ) } } } else { if (lhsIsNotNullable) callEquals(lhs, rhs) else { irBlock { val lhsTemp = irTemporary(lhs) if (rhsIsNotNullable) +irLogicalAnd(irIsNotNull(irGet(lhsTemp)), callEquals(irGet(lhsTemp), rhs)) else { val rhsTemp = irTemporary(rhs) +irIfThenElse(irBuiltins.booleanType, irIsNull(irGet(lhsTemp)), irIsNull(irGet(rhsTemp)), callEquals(irGet(lhsTemp), irGet(rhsTemp)) ) } } } } } private fun selectIntrinsic(from: List, lhsType: IrType, rhsType: IrType, allowNullable: Boolean) = from.atMostOne { val leftParamType = it.owner.valueParameters[0].type val rightParamType = it.owner.valueParameters[1].type (lhsType.isSubtypeOf(leftParamType) || (allowNullable && lhsType.isSubtypeOf(leftParamType.makeNullable()))) && (rhsType.isSubtypeOf(rightParamType) || (allowNullable && rhsType.isSubtypeOf(rightParamType.makeNullable()))) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CompileTimeEvaluateLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal class CompileTimeEvaluateLowering(val context: Context): FileLoweringPass { override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object: IrBuildingTransformer(context) { override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) val callee = expression.symbol.owner // TODO if (callee.fqNameForIrSerialization.asString() != "kotlin.collections.listOf" || callee.valueParameters.size != 1) return expression val elementsArr = expression.getValueArgument(0) as? IrVararg ?: return expression // The function is kotlin.collections.listOf(vararg args: T). // TODO: refer functions more reliably. if (elementsArr.elements.any { it is IrSpreadElement } || !elementsArr.elements.all { it is IrConst<*> && it.type.isString() }) return expression builder.at(expression) val typeArgument = expression.getTypeArgument(0)!! return builder.irCall(context.ir.symbols.listOfInternal.owner, listOf(typeArgument)).apply { putValueArgument(0, elementsArr) } } }) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ContractsDslRemover.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.contracts.parsing.ContractsDslNames import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.transformFlat internal class ContractsDslRemover(val context: Context) : DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.declarations.transformFlat { if (it is IrClass && it.annotations.hasAnnotation(ContractsDslNames.CONTRACTS_DSL_ANNOTATION_FQN)) null else listOf(it) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DataClassOperatorsLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.isSimpleTypeWithQuestionMark import org.jetbrains.kotlin.ir.visitors.IrElementTransformer internal class DataClassOperatorsLowering(val context: Context) : FileLoweringPass, IrElementTransformer { private val irBuiltins = context.irModule!!.irBuiltins override fun lower(irFile: IrFile) { irFile.transformChildren(this, null) } override fun visitFunction(declaration: IrFunction, data: IrFunction?): IrStatement = super.visitFunction(declaration, declaration) override fun visitCall(expression: IrCall, data: IrFunction?): IrExpression { expression.transformChildren(this, data) if (expression.symbol != irBuiltins.dataClassArrayMemberToStringSymbol && expression.symbol != irBuiltins.dataClassArrayMemberHashCodeSymbol) return expression val argument = expression.getValueArgument(0)!! val argumentClassifier = argument.type.classifierOrFail val isToString = expression.symbol == irBuiltins.dataClassArrayMemberToStringSymbol val newCalleeSymbol = if (isToString) context.ir.symbols.arrayContentToString[argumentClassifier]!! else context.ir.symbols.arrayContentHashCode[argumentClassifier]!! val newCallee = newCalleeSymbol.owner val startOffset = expression.startOffset val endOffset = expression.endOffset val irBuilder = context.createIrBuilder(data!!.symbol, startOffset, endOffset) return irBuilder.run { // TODO: use more precise type arguments. val typeArguments = (0 until newCallee.typeParameters.size).map { irBuiltins.anyNType } if (!argument.type.isSimpleTypeWithQuestionMark) { irCall(newCallee, typeArguments).apply { extensionReceiver = argument } } else { irBlock(argument) { val tmp = irTemporary(argument) val call = irCall(newCallee, typeArguments).apply { extensionReceiver = irGet(tmp) } +irIfThenElse(call.type, irEqeqeq(irGet(tmp), irNull()), if (isToString) irString("null") else irInt(0), call) } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrLocalDelegatedPropertyReference import org.jetbrains.kotlin.ir.expressions.IrPropertyReference import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name internal class PropertyDelegationLowering(val context: Context) : FileLoweringPass { private var tempIndex = 0 private fun getKPropertyImplConstructor(receiverTypes: List, returnType: IrType, isLocal: Boolean, isMutable: Boolean) : Pair> { val symbols = context.ir.symbols val classSymbol = if (isLocal) { assert(receiverTypes.isEmpty()) { "Local delegated property cannot have explicit receiver" } when { isMutable -> symbols.kLocalDelegatedMutablePropertyImpl else -> symbols.kLocalDelegatedPropertyImpl } } else { when (receiverTypes.size) { 0 -> when { isMutable -> symbols.kMutableProperty0Impl else -> symbols.kProperty0Impl } 1 -> when { isMutable -> symbols.kMutableProperty1Impl else -> symbols.kProperty1Impl } 2 -> when { isMutable -> symbols.kMutableProperty2Impl else -> symbols.kProperty2Impl } else -> throw AssertionError("More than 2 receivers is not allowed") } } val arguments = (receiverTypes + listOf(returnType)) return classSymbol.constructors.single() to arguments } override fun lower(irFile: IrFile) { // Somehow there is no reasonable common ancestor for IrProperty and IrLocalDelegatedProperty, // so index by IrDeclaration. val kProperties = mutableMapOf>() val arrayClass = context.ir.symbols.array.owner val arrayItemGetter = arrayClass.functions.single { it.name == Name.identifier("get") } val anyType = context.irBuiltIns.anyType val kPropertyImplType = context.ir.symbols.kProperty1Impl.typeWith(anyType, anyType) val kPropertiesFieldType: IrType = context.ir.symbols.array.typeWith(kPropertyImplType) val kPropertiesField = IrFieldImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION, IrFieldSymbolImpl(), "KPROPERTIES".synthesizedName, kPropertiesFieldType, DescriptorVisibilities.PRIVATE, isFinal = true, isExternal = false, isStatic = true, ).apply { parent = irFile annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.sharedImmutable.owner) } irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { override fun visitPropertyReference(expression: IrPropertyReference): IrExpression { expression.transformChildrenVoid(this) val kTypeGenerator = KTypeGenerator(context, irFile, expression) val startOffset = expression.startOffset val endOffset = expression.endOffset val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) irBuilder.run { val receiversCount = listOf(expression.dispatchReceiver, expression.extensionReceiver).count { it != null } return when (receiversCount) { 1 -> createKProperty(expression, kTypeGenerator, this) // Has receiver. 2 -> error("Callable reference to properties with two receivers is not allowed: ${expression.symbol.owner.name}") else -> { // Cache KProperties with no arguments. val field = kProperties.getOrPut(expression.symbol.owner) { createKProperty(expression, kTypeGenerator, this) to kProperties.size } irCall(arrayItemGetter).apply { dispatchReceiver = irGetField(null, kPropertiesField) putValueArgument(0, irInt(field.second)) } } } } } override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrExpression { expression.transformChildrenVoid(this) val startOffset = expression.startOffset val endOffset = expression.endOffset val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) irBuilder.run { val receiversCount = listOf(expression.dispatchReceiver, expression.extensionReceiver).count { it != null } if (receiversCount == 2) throw AssertionError("Callable reference to properties with two receivers is not allowed: ${expression}") else { // Cache KProperties with no arguments. // TODO: what about `receiversCount == 1` case? val field = kProperties.getOrPut(expression.symbol.owner) { createLocalKProperty( expression.symbol.owner.name.asString(), expression.getter.owner.returnType, KTypeGenerator(this@PropertyDelegationLowering.context, irFile, expression), this ) to kProperties.size } return irCall(arrayItemGetter).apply { dispatchReceiver = irGetField(null, kPropertiesField) putValueArgument(0, irInt(field.second)) } } } } }) if (kProperties.isNotEmpty()) { val initializers = kProperties.values.sortedBy { it.second }.map { it.first } // TODO: move to object for lazy initialization. irFile.declarations.add(0, kPropertiesField.apply { initializer = IrExpressionBodyImpl(startOffset, endOffset, context.createArrayOfExpression(startOffset, endOffset, kPropertyImplType, initializers)) }) } } private fun createKProperty( expression: IrPropertyReference, kTypeGenerator: KTypeGenerator, irBuilder: IrBuilderWithScope ): IrExpression { val startOffset = expression.startOffset val endOffset = expression.endOffset return irBuilder.irBlock(expression) { val receiverTypes = mutableListOf() val dispatchReceiver = expression.dispatchReceiver.let { if (it == null) null else irTemporary(value = it, nameHint = "\$dispatchReceiver${tempIndex++}") } val extensionReceiver = expression.extensionReceiver.let { if (it == null) null else irTemporary(value = it, nameHint = "\$extensionReceiver${tempIndex++}") } val returnType = expression.getter?.owner?.returnType ?: expression.field!!.owner.type val getterCallableReference = expression.getter?.owner?.let { getter -> getter.extensionReceiverParameter.let { if (it != null && expression.extensionReceiver == null) receiverTypes.add(it.type) } getter.dispatchReceiverParameter.let { if (it != null && expression.dispatchReceiver == null) receiverTypes.add(it.type) } val getterKFunctionType = this@PropertyDelegationLowering.context.ir.symbols.getKFunctionType( returnType, receiverTypes ) IrFunctionReferenceImpl( startOffset = startOffset, endOffset = endOffset, type = getterKFunctionType, symbol = expression.getter!!, typeArgumentsCount = getter.typeParameters.size, valueArgumentsCount = getter.valueParameters.size, reflectionTarget = expression.getter!! ).apply { this.dispatchReceiver = dispatchReceiver?.let { irGet(it) } this.extensionReceiver = extensionReceiver?.let { irGet(it) } for (index in 0 until expression.typeArgumentsCount) putTypeArgument(index, expression.getTypeArgument(index)) } } val setterCallableReference = expression.setter?.owner?.let { setter -> if (!isKMutablePropertyType(expression.type)) null else { val setterKFunctionType = this@PropertyDelegationLowering.context.ir.symbols.getKFunctionType( context.irBuiltIns.unitType, receiverTypes + returnType ) IrFunctionReferenceImpl( startOffset = startOffset, endOffset = endOffset, type = setterKFunctionType, symbol = expression.setter!!, typeArgumentsCount = setter.typeParameters.size, valueArgumentsCount = setter.valueParameters.size, reflectionTarget = expression.setter!! ).apply { this.dispatchReceiver = dispatchReceiver?.let { irGet(it) } this.extensionReceiver = extensionReceiver?.let { irGet(it) } for (index in 0 until expression.typeArgumentsCount) putTypeArgument(index, expression.getTypeArgument(index)) } } } val (symbol, constructorTypeArguments) = getKPropertyImplConstructor( receiverTypes = receiverTypes, returnType = returnType, isLocal = false, isMutable = setterCallableReference != null) val initializer = irCall(symbol.owner, constructorTypeArguments).apply { putValueArgument(0, irString(expression.symbol.owner.name.asString())) putValueArgument(1, with(kTypeGenerator) { irKType(returnType) }) if (getterCallableReference != null) putValueArgument(2, getterCallableReference) if (setterCallableReference != null) putValueArgument(3, setterCallableReference) } +initializer } } private fun createLocalKProperty(propertyName: String, propertyType: IrType, kTypeGenerator: KTypeGenerator, irBuilder: IrBuilderWithScope): IrExpression { irBuilder.run { val (symbol, constructorTypeArguments) = getKPropertyImplConstructor( receiverTypes = emptyList(), returnType = propertyType, isLocal = true, isMutable = false) val initializer = irCall(symbol.owner, constructorTypeArguments).apply { putValueArgument(0, irString(propertyName)) putValueArgument(1, with(kTypeGenerator) { irKType(propertyType) }) } return initializer } } private fun isKMutablePropertyType(type: IrType): Boolean { if (type !is IrSimpleType) return false val expectedClass = when (type.arguments.size) { 0 -> return false 1 -> context.ir.symbols.kMutableProperty0 2 -> context.ir.symbols.kMutableProperty1 3 -> context.ir.symbols.kMutableProperty2 else -> throw AssertionError("More than 2 receivers is not allowed") } return type.classifier == expectedClass } private object DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION : IrDeclarationOriginImpl("KPROPERTIES_FOR_DELEGATION") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.EnumWhenLowering import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_ENUM import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name private class EnumSyntheticFunctionsBuilder(val context: Context) { fun buildValuesExpression(startOffset: Int, endOffset: Int, enumClass: IrClass): IrExpression { val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) return irCall(startOffset, endOffset, genericValuesSymbol.owner, listOf(enumClass.defaultType)) .apply { putValueArgument(0, loweredEnum.getValuesField(startOffset, endOffset)) } } fun buildValueOfExpression(startOffset: Int, endOffset: Int, enumClass: IrClass, value: IrExpression): IrExpression { val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) return irCall(startOffset, endOffset, genericValueOfSymbol.owner, listOf(enumClass.defaultType)) .apply { putValueArgument(0, value) putValueArgument(1, loweredEnum.getValuesField(startOffset, endOffset)) } } private val genericValueOfSymbol = context.ir.symbols.valueOfForEnum private val genericValuesSymbol = context.ir.symbols.valuesForEnum } internal class EnumUsageLowering(val context: Context) : IrElementTransformerVoid(), FileLoweringPass { private val enumSyntheticFunctionsBuilder = EnumSyntheticFunctionsBuilder(context) override fun lower(irFile: IrFile) { visitFile(irFile) } override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression { val entry = expression.symbol.owner return loadEnumEntry( expression.startOffset, expression.endOffset, entry.parentAsClass, entry.name ) } override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) val intrinsicType = tryGetIntrinsicType(expression) if (intrinsicType != IntrinsicType.ENUM_VALUES && intrinsicType != IntrinsicType.ENUM_VALUE_OF) return expression val startOffset = expression.startOffset val endOffset = expression.endOffset val irClassSymbol = expression.getTypeArgument(0)!!.classifierOrNull as? IrClassSymbol if (irClassSymbol == null || irClassSymbol == context.ir.symbols.enum) { // Either a type parameter or a type parameter erased to 'Enum'. return irCall(startOffset, endOffset, context.ir.symbols.throwIllegalStateException.owner, emptyList()) } val irClass = irClassSymbol.owner assert (irClass.kind == ClassKind.ENUM_CLASS) return if (intrinsicType == IntrinsicType.ENUM_VALUES) { enumSyntheticFunctionsBuilder.buildValuesExpression(startOffset, endOffset, irClass) } else { val value = expression.getValueArgument(0)!! enumSyntheticFunctionsBuilder.buildValueOfExpression(startOffset, endOffset, irClass, value) } } private fun loadEnumEntry(startOffset: Int, endOffset: Int, enumClass: IrClass, name: Name): IrExpression { val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) val ordinal = loweredEnum.entriesMap.getValue(name) return IrCallImpl.fromSymbolDescriptor( startOffset, endOffset, enumClass.defaultType, loweredEnum.itemGetterSymbol.owner.symbol, typeArgumentsCount = 0, loweredEnum.itemGetterSymbol.owner.valueParameters.size ).apply { dispatchReceiver = IrCallImpl(startOffset, endOffset, loweredEnum.valuesGetter.returnType, loweredEnum.valuesGetter.symbol, loweredEnum.valuesGetter.typeParameters.size, loweredEnum.valuesGetter.valueParameters.size) putValueArgument(0, IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, ordinal)) } } } internal class EnumClassLowering(val context: Context) : FileLoweringPass { fun run(irFile: IrFile) { // EnumWhenLowering should be performed before EnumUsageLowering because // the latter performs lowering of IrGetEnumValue EnumWhenLowering(context).lower(irFile) lower(irFile) EnumUsageLowering(context).lower(irFile) } override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { declaration.transformChildrenVoid() if (declaration.kind == ClassKind.ENUM_CLASS) EnumClassTransformer(declaration).run() return declaration } }) } private inner class EnumClassTransformer(val irClass: IrClass) { private val loweredEnum = context.specialDeclarationsFactory.getInternalLoweredEnum(irClass) private val enumSyntheticFunctionsBuilder = EnumSyntheticFunctionsBuilder(context) fun run() { pullUpEnumEntriesClasses() createImplObject() } private fun pullUpEnumEntriesClasses() { irClass.declarations.transformFlat { declaration -> if (declaration is IrEnumEntry) { val correspondingClass = declaration.correspondingClass declaration.correspondingClass = null listOfNotNull(declaration, correspondingClass) } else null } } private fun createImplObject() { val implObject = loweredEnum.implObject val enumEntries = mutableListOf() var i = 0 while (i < irClass.declarations.size) { val declaration = irClass.declarations[i] var delete = false when (declaration) { is IrEnumEntry -> { enumEntries.add(declaration) delete = true } is IrFunction -> { val body = declaration.body if (body is IrSyntheticBody) { when (body.kind) { IrSyntheticBodyKind.ENUM_VALUEOF -> declaration.body = createSyntheticValueOfMethodBody(declaration) IrSyntheticBodyKind.ENUM_VALUES -> declaration.body = createSyntheticValuesMethodBody(declaration) } } } } if (delete) irClass.declarations.removeAt(i) else ++i } implObject.declarations += createSyntheticValuesPropertyDeclaration(enumEntries) irClass.declarations += implObject } private val createUninitializedInstance = context.ir.symbols.createUninitializedInstance.owner private fun createSyntheticValuesPropertyDeclaration(enumEntries: List): IrProperty { val startOffset = irClass.startOffset val endOffset = irClass.endOffset val implObject = loweredEnum.implObject val constructor = implObject.constructors.single() val irValuesInitializer = context.createArrayOfExpression( startOffset, endOffset, irClass.defaultType, enumEntries .sortedBy { it.name } .map { val initializer = it.initializerExpression?.expression val entryConstructorCall = when { initializer is IrConstructorCall -> initializer initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL -> initializer.statements.last() as IrConstructorCall else -> error("Unexpected initializer: $initializer") } val entryClass = entryConstructorCall.symbol.owner.constructedClass irCall(startOffset, endOffset, createUninitializedInstance, listOf(entryClass.defaultType) ) } ) val irField = loweredEnum.valuesField context.createIrBuilder(constructor.symbol).run { (constructor.body as IrBlockBody).statements += irSetField(irGet(implObject.thisReceiver!!), irField, irValuesInitializer) } val getter = loweredEnum.valuesGetter context.createIrBuilder(getter.symbol).run { getter.body = irBlockBody(irClass) { +irReturn(irGetField(irGetObject(implObject.symbol), irField)) } } createValuesPropertyInitializer(enumEntries) return with(loweredEnum.valuesField.descriptor) { IrPropertyImpl( startOffset, endOffset, DECLARATION_ORIGIN_ENUM, IrPropertySymbolImpl(this), name, visibility, modality, isVar, isConst, isLateInit, isDelegated, isExternal ).apply { this.backingField = irField this.getter = getter this.parent = implObject } } } private val initInstanceSymbol = context.ir.symbols.initInstance private val arrayGetSymbol = context.ir.symbols.array.functions.single { it.owner.name == Name.identifier("get") } private val arrayType = context.ir.symbols.array.typeWith(irClass.defaultType) private fun createValuesPropertyInitializer(enumEntries: List) { val startOffset = irClass.startOffset val endOffset = irClass.endOffset fun IrBlockBuilder.initInstanceCall(instance: IrCall, constructor: IrConstructorCall): IrCall = irCall(initInstanceSymbol).apply { putValueArgument(0, instance) putValueArgument(1, constructor) } val implObject = loweredEnum.implObject val constructor = implObject.constructors.single() val irBuilder = context.createIrBuilder(constructor.symbol, startOffset, endOffset) val valuesInitializer = irBuilder.irBlock(startOffset, endOffset) { val receiver = implObject.thisReceiver!! val instances = irTemporary(irGetField(irGet(receiver), loweredEnum.valuesField)) val enumIndices = enumEntries.sortedBy { it.name }.withIndex().associate { it.value to it.index } enumEntries.forEach { val instance = irCall(arrayGetSymbol).apply { dispatchReceiver = irGet(instances) putValueArgument(0, irInt(enumIndices[it]!!)) } val initializer = it.initializerExpression!!.expression initializer.setDeclarationsParent(constructor) when { initializer is IrConstructorCall -> +initInstanceCall(instance, initializer) initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL -> { val statements = initializer.statements val constructorCall = statements.last() as IrConstructorCall statements[statements.lastIndex] = initInstanceCall(instance, constructorCall) +initializer } else -> error("Unexpected initializer: $initializer") } } +irCall(this@EnumClassLowering.context.ir.symbols.freeze, listOf(arrayType)).apply { extensionReceiver = irGet(receiver) } } (constructor.body as IrBlockBody).statements += valuesInitializer } private fun createSyntheticValuesMethodBody(declaration: IrFunction): IrBody { val startOffset = irClass.startOffset val endOffset = irClass.endOffset val valuesExpression = enumSyntheticFunctionsBuilder.buildValuesExpression(startOffset, endOffset, irClass) return IrBlockBodyImpl(startOffset, endOffset).apply { statements += IrReturnImpl( startOffset, endOffset, context.irBuiltIns.nothingType, declaration.symbol, valuesExpression ) } } private fun createSyntheticValueOfMethodBody(declaration: IrFunction): IrBody { val startOffset = irClass.startOffset val endOffset = irClass.endOffset val parameter = declaration.valueParameters[0] val value = IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol) val valueOfExpression = enumSyntheticFunctionsBuilder.buildValueOfExpression(startOffset, endOffset, irClass, value) return IrBlockBodyImpl(startOffset, endOffset).apply { statements += IrReturnImpl( startOffset, endOffset, context.irBuiltIns.nothingType, declaration.symbol, valueOfExpression ) } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumConstructorsLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_ENUM import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPass { fun run(irFile: IrFile) { runOnFilePostfix(irFile) } override fun lower(irClass: IrClass) { if (irClass.kind != ClassKind.ENUM_CLASS) return EnumClassTransformer(irClass).run() } private interface EnumConstructorCallTransformer { fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression } private inner class EnumClassTransformer(val irClass: IrClass) { private val loweredEnumConstructors = mutableMapOf() private val loweredEnumConstructorParameters = mutableMapOf() fun run() { insertInstanceInitializerCall() lowerEnumConstructors(irClass) lowerEnumEntriesClasses() lowerEnumClassBody() } private fun insertInstanceInitializerCall() { irClass.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested return declaration } override fun visitConstructor(declaration: IrConstructor): IrStatement { declaration.transformChildrenVoid(this) val blockBody = declaration.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${declaration.body}") if (blockBody.statements.all { it !is IrInstanceInitializerCall }) { blockBody.statements.transformFlat { if (it is IrEnumConstructorCall) listOf(it, IrInstanceInitializerCallImpl(declaration.startOffset, declaration.startOffset, irClass.symbol, context.irBuiltIns.unitType)) else null } } return declaration } }) } private fun lowerEnumEntriesClasses() { for (enumEntry in irClass.declarations.filterIsInstance()) enumEntry.correspondingClass?.let { lowerEnumConstructors(it) } } private fun lowerEnumConstructors(irClass: IrClass) { irClass.declarations.forEachIndexed { index, declaration -> if (declaration is IrConstructor) irClass.declarations[index] = transformEnumConstructor(declaration) } } private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor { val loweredEnumConstructor = lowerEnumConstructor(enumConstructor) for (parameter in enumConstructor.valueParameters) { val defaultValue = parameter.defaultValue ?: continue defaultValue.transformChildrenVoid(ParameterMapper(enumConstructor, loweredEnumConstructor, true)) loweredEnumConstructor.valueParameters[parameter.loweredIndex].defaultValue = defaultValue defaultValue.setDeclarationsParent(loweredEnumConstructor) } return loweredEnumConstructor } private fun lowerEnumConstructor(constructor: IrConstructor): IrConstructor { val startOffset = constructor.startOffset val endOffset = constructor.endOffset val loweredConstructor = IrConstructorImpl( startOffset, endOffset, constructor.origin, IrConstructorSymbolImpl(), constructor.name, DescriptorVisibilities.PROTECTED, constructor.returnType, isInline = false, isExternal = false, isPrimary = constructor.isPrimary, isExpect = false ).apply { parent = constructor.parent val body = constructor.body!! this.body = body // Will be transformed later. body.setDeclarationsParent(this) } fun createSynthesizedValueParameter(index: Int, name: String, type: IrType): IrValueParameter = IrValueParameterImpl( startOffset, endOffset, DECLARATION_ORIGIN_ENUM, IrValueParameterSymbolImpl(), Name.identifier(name), index, type, varargElementType = null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = loweredConstructor } loweredConstructor.valueParameters += createSynthesizedValueParameter(0, "name", context.irBuiltIns.stringType) loweredConstructor.valueParameters += createSynthesizedValueParameter(1, "ordinal", context.irBuiltIns.intType) loweredConstructor.valueParameters += constructor.valueParameters.map { it.copyTo(loweredConstructor, index = it.loweredIndex).apply { loweredEnumConstructorParameters[it] = this } } loweredEnumConstructors[constructor] = loweredConstructor return loweredConstructor } private fun lowerEnumClassBody() { val transformer = EnumClassBodyTransformer() irClass.transformChildrenVoid(transformer) irClass.declarations.filterIsInstance().forEach { it.correspondingClass?.transformChildrenVoid(transformer) } } private inner class InEnumClassConstructor(val enumClassConstructor: IrConstructor) : EnumConstructorCallTransformer { override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { val startOffset = enumConstructorCall.startOffset val endOffset = enumConstructorCall.endOffset val origin = enumConstructorCall.origin val result = IrDelegatingConstructorCallImpl.fromSymbolDescriptor( startOffset, endOffset, context.irBuiltIns.unitType, enumConstructorCall.symbol ) assert(result.symbol.owner.valueParameters.size == 2) { "Enum(String, Int) constructor call expected:\n${result.dump()}" } val nameParameter = enumClassConstructor.valueParameters.getOrElse(0) { throw AssertionError("No 'name' parameter in enum constructor: $enumClassConstructor") } val ordinalParameter = enumClassConstructor.valueParameters.getOrElse(1) { throw AssertionError("No 'ordinal' parameter in enum constructor: $enumClassConstructor") } result.putValueArgument(0, IrGetValueImpl(startOffset, endOffset, nameParameter.type, nameParameter.symbol, origin) ) result.putValueArgument(1, IrGetValueImpl(startOffset, endOffset, ordinalParameter.type, ordinalParameter.symbol, origin) ) return result } override fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression { val startOffset = delegatingConstructorCall.startOffset val endOffset = delegatingConstructorCall.endOffset val delegatingConstructor = delegatingConstructorCall.symbol.owner val loweredDelegatingConstructor = loweredEnumConstructors.getOrElse(delegatingConstructor) { throw AssertionError("Constructor called in enum entry initializer should've been lowered: $delegatingConstructor") } val result = IrDelegatingConstructorCallImpl.fromSymbolDescriptor( startOffset, endOffset, context.irBuiltIns.unitType, loweredDelegatingConstructor.symbol ) val firstParameter = enumClassConstructor.valueParameters[0] result.putValueArgument(0, IrGetValueImpl(startOffset, endOffset, firstParameter.type, firstParameter.symbol)) val secondParameter = enumClassConstructor.valueParameters[1] result.putValueArgument(1, IrGetValueImpl(startOffset, endOffset, secondParameter.type, secondParameter.symbol)) delegatingConstructor.valueParameters.forEach { result.putValueArgument(it.loweredIndex, delegatingConstructorCall.getValueArgument(it.index)) } return result } } private abstract inner class InEnumEntry(private val enumEntry: IrEnumEntry) : EnumConstructorCallTransformer { override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { val name = enumEntry.name.asString() val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(enumEntry) val startOffset = enumConstructorCall.startOffset val endOffset = enumConstructorCall.endOffset val enumConstructor = enumConstructorCall.symbol.owner val loweredConstructor = loweredEnumConstructors.getOrElse(enumConstructor) { throw AssertionError("Constructor called in enum entry initializer should've been lowered: $enumConstructor") } val result = createConstructorCall(startOffset, endOffset, loweredConstructor.symbol) result.putValueArgument(0, IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, name)) result.putValueArgument(1, IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, ordinal)) enumConstructor.valueParameters.forEach { result.putValueArgument(it.loweredIndex, enumConstructorCall.getValueArgument(it.index)) } return result } override fun transform(delegatingConstructorCall: IrDelegatingConstructorCall): IrExpression { throw AssertionError("Unexpected delegating constructor call within enum entry: $enumEntry") } abstract fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol): IrMemberAccessExpression<*> } private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) { override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) = IrDelegatingConstructorCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, loweredConstructor, loweredConstructor.owner.typeParameters.size, loweredConstructor.owner.valueParameters.size) } private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) { override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) = IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, loweredConstructor.owner.returnType, loweredConstructor) } private inner class EnumClassBodyTransformer : IrElementTransformerVoid() { private var enumConstructorCallTransformer: EnumConstructorCallTransformer? = null override fun visitClass(declaration: IrClass): IrStatement { if (declaration.kind == ClassKind.ENUM_CLASS) return declaration return super.visitClass(declaration) } override fun visitEnumEntry(declaration: IrEnumEntry): IrStatement { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" } enumConstructorCallTransformer = InEnumEntryInitializer(declaration) declaration.initializerExpression = declaration.initializerExpression?.transform(this, data = null) enumConstructorCallTransformer = null return declaration } override fun visitConstructor(declaration: IrConstructor): IrStatement { val containingClass = declaration.parentAsClass // TODO local (non-enum) class in enum class constructor? val previous = enumConstructorCallTransformer if (containingClass.kind == ClassKind.ENUM_ENTRY) { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" } val entry = irClass.declarations.filterIsInstance().single { it.correspondingClass == containingClass } enumConstructorCallTransformer = InEnumEntryClassConstructor(entry) } else if (containingClass.kind == ClassKind.ENUM_CLASS) { assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" } enumConstructorCallTransformer = InEnumClassConstructor(declaration) } val result = super.visitConstructor(declaration) enumConstructorCallTransformer = previous return result } override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression { expression.transformChildrenVoid(this) val callTransformer = enumConstructorCallTransformer ?: throw AssertionError("Enum constructor call outside of enum entry initialization or enum class constructor:\n" + irClass.dump()) return callTransformer.transform(expression) } override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { expression.transformChildrenVoid(this) if (expression.symbol.owner.parentAsClass.kind == ClassKind.ENUM_CLASS) { val callTransformer = enumConstructorCallTransformer ?: throw AssertionError("Enum constructor call outside of enum entry initialization or enum class constructor:\n" + irClass.dump()) return callTransformer.transform(expression) } return expression } override fun visitGetValue(expression: IrGetValue): IrExpression { val parameter = expression.symbol.owner val loweredParameter = loweredEnumConstructorParameters[parameter] return if (loweredParameter == null) { expression } else { IrGetValueImpl(expression.startOffset, expression.endOffset, loweredParameter.type, loweredParameter.symbol, expression.origin) } } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid() return loweredEnumConstructorParameters[expression.symbol.owner]?.let { IrSetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.value, expression.origin) } ?: expression } } } } private val IrValueParameter.loweredIndex: Int get() = index + 2 private class ParameterMapper(superConstructor: IrConstructor, val constructor: IrConstructor, val useLoweredIndex: Boolean) : IrElementTransformerVoid() { private val valueParameters = superConstructor.valueParameters.toSet() override fun visitGetValue(expression: IrGetValue): IrExpression { val superParameter = expression.symbol.owner as? IrValueParameter ?: return expression if (valueParameters.contains(superParameter)) { val index = if (useLoweredIndex) superParameter.loweredIndex else superParameter.index val parameter = constructor.valueParameters[index] return IrGetValueImpl( expression.startOffset, expression.endOffset, parameter.type, parameter.symbol) } return expression } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid() val superParameter = expression.symbol.owner as? IrValueParameter ?: return expression if (valueParameters.contains(superParameter)) { val index = if (useLoweredIndex) superParameter.loweredIndex else superParameter.index val parameter = constructor.valueParameters[index] return IrSetValueImpl( expression.startOffset, expression.endOffset, parameter.type, parameter.symbol, expression.value, expression.origin) } return expression } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ExpectDeclarationsRemoving.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver /** * This pass removes all declarations with `isExpect == true`. * Note: org.jetbrains.kotlin.backend.common.lower.ExpectDeclarationsRemoving is copy of this lower. */ internal class ExpectDeclarationsRemoving(val context: Context) : FileLoweringPass { override fun lower(irFile: IrFile) { // All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`. irFile.declarations.removeAll { it.descriptor.isExpectMember } } } internal class ExpectToActualDefaultValueCopier(private val irModule: IrModuleFragment) { // Note: local declarations aren't required here; TODO: use more lightweight index. private val moduleIndex = ModuleIndex(irModule) fun process() { irModule.files.forEach { this.process(it) } } private fun process(irFile: IrFile) { // All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`. irFile.declarations.forEach { if (it.descriptor.isExpectMember) { copyDefaultArgumentsFromExpectToActual(it) } } } private fun copyDefaultArgumentsFromExpectToActual(declaration: IrDeclaration) { declaration.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitValueParameter(declaration: IrValueParameter) { super.visitValueParameter(declaration) val defaultValue = declaration.defaultValue ?: return val function = declaration.parent as IrFunction val index = declaration.index assert(function.valueParameters[index] == declaration) if (function is IrConstructor && ExpectedActualDeclarationChecker.isOptionalAnnotationClass( function.descriptor.constructedClass ) ) { return } val actualForExpected = function.findActualForExpected() actualForExpected.valueParameters[index].defaultValue = IrExpressionBodyImpl( defaultValue.startOffset, defaultValue.endOffset, defaultValue.expression.remapExpectValueSymbols().patchDeclarationParents(actualForExpected) ) } }) } private inline fun T.findActualForExpected(): T = moduleIndex.functions[descriptor.findActualForExpect()] as T private fun IrClass.findActualForExpected(): IrClass = moduleIndex.classes[descriptor.findActualForExpect()]!! private inline fun T.findActualForExpect() = with(ExpectedActualResolver) { val descriptor = this@findActualForExpect if (!descriptor.isExpect) error(this) findCompatibleActualForExpected(descriptor.module).singleOrNull() ?: error(descriptor) } as T private fun IrExpression.remapExpectValueSymbols(): IrExpression { class SymbolRemapper : DeepCopySymbolRemapper() { override fun getReferencedClass(symbol: IrClassSymbol) = if (symbol.descriptor.isExpect) symbol.owner.findActualForExpected().symbol else super.getReferencedClass(symbol) override fun getReferencedClassOrNull(symbol: IrClassSymbol?) = symbol?.let { getReferencedClass(it) } override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol = when (symbol) { is IrClassSymbol -> getReferencedClass(symbol) is IrTypeParameterSymbol -> remapExpectTypeParameter(symbol).symbol else -> error("Unexpected symbol $symbol ${symbol.descriptor}") } override fun getReferencedConstructor(symbol: IrConstructorSymbol) = if (symbol.descriptor.isExpect) symbol.owner.findActualForExpected().symbol else super.getReferencedConstructor(symbol) override fun getReferencedFunction(symbol: IrFunctionSymbol): IrFunctionSymbol = when (symbol) { is IrSimpleFunctionSymbol -> getReferencedSimpleFunction(symbol) is IrConstructorSymbol -> getReferencedConstructor(symbol) else -> error("Unexpected symbol $symbol ${symbol.descriptor}") } override fun getReferencedSimpleFunction(symbol: IrSimpleFunctionSymbol) = when { symbol.descriptor.isExpect -> symbol.owner.findActualForExpected().symbol symbol.descriptor.propertyIfAccessor.isExpect -> { val property = symbol.owner.correspondingPropertySymbol!!.owner val actualPropertyDescriptor = property.descriptor.findActualForExpect() val accessorDescriptor = when (symbol.owner) { property.getter -> actualPropertyDescriptor.getter!! property.setter -> actualPropertyDescriptor.setter!! else -> error("Unexpected accessor of $symbol ${symbol.descriptor}") } moduleIndex.functions[accessorDescriptor]!!.symbol as IrSimpleFunctionSymbol } else -> super.getReferencedSimpleFunction(symbol) } override fun getReferencedValue(symbol: IrValueSymbol) = remapExpectValue(symbol)?.symbol ?: super.getReferencedValue(symbol) } val symbolRemapper = SymbolRemapper() acceptVoid(symbolRemapper) return transform(DeepCopyIrTreeWithSymbols(symbolRemapper, DeepCopyTypeRemapper(symbolRemapper)), data = null) } private fun remapExpectTypeParameter(symbol: IrTypeParameterSymbol): IrTypeParameter { val parameter = symbol.owner val parent = parameter.parent return when (parent) { is IrClass -> if (!parent.descriptor.isExpect) parameter else parent.findActualForExpected().typeParameters[parameter.index] is IrFunction -> if (!parent.descriptor.isExpect) parameter else parent.findActualForExpected().typeParameters[parameter.index] else -> error(parent) } } private fun remapExpectValue(symbol: IrValueSymbol): IrValueParameter? { if (symbol !is IrValueParameterSymbol) { return null } val parameter = symbol.owner val parent = parameter.parent return when (parent) { is IrClass -> if (!parent.descriptor.isExpect) null else { assert(parameter == parent.thisReceiver) parent.findActualForExpected().thisReceiver!! } is IrFunction -> if (!parent.descriptor.isExpect) null else when (parameter) { parent.dispatchReceiverParameter -> parent.findActualForExpected().dispatchReceiverParameter!! parent.extensionReceiverParameter -> parent.findActualForExpected().extensionReceiverParameter!! else -> { assert(parent.valueParameters[parameter.index] == parameter) parent.findActualForExpected().valueParameters[parameter.index] } } else -> error(parent) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FinallyBlocksLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.setDeclarationsParent import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name internal class FinallyBlocksLowering(val context: Context): FileLoweringPass, IrElementTransformerVoidWithContext() { private val symbols = context.ir.symbols private interface HighLevelJump { fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression): IrExpression } private data class Return(val target: IrReturnTargetSymbol): HighLevelJump { override fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression) = IrReturnImpl(startOffset, endOffset, context.irBuiltIns.nothingType, target, value) } private data class Break(val loop: IrLoop): HighLevelJump { override fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression) = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.nothingType, null, statements = listOf( value, IrBreakImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop) )) } private data class Continue(val loop: IrLoop): HighLevelJump { override fun toIr(context: Context, startOffset: Int, endOffset: Int, value: IrExpression) = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.nothingType, null, statements = listOf( value, IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop) )) } private abstract class Scope private class ReturnableScope(val symbol: IrReturnTargetSymbol): Scope() private class LoopScope(val loop: IrLoop): Scope() private class TryScope(var expression: IrExpression, val finallyExpression: IrExpression, val irBuilder: IrBuilderWithScope): Scope() { val jumps = mutableMapOf() } private val scopeStack = mutableListOf() private inline fun using(scope: S, block: (S) -> R): R { scopeStack.push(scope) try { return block(scope) } finally { scopeStack.pop() } } override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) } override fun visitFunctionNew(declaration: IrFunction): IrStatement { using(ReturnableScope(declaration.symbol)) { return super.visitFunctionNew(declaration) } } override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression) using(ReturnableScope(expression.symbol)) { return super.visitContainerExpression(expression) } } override fun visitLoop(loop: IrLoop): IrExpression { using(LoopScope(loop)) { return super.visitLoop(loop) } } override fun visitBreak(jump: IrBreak): IrExpression { val startOffset = jump.startOffset val endOffset = jump.endOffset val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) return performHighLevelJump( targetScopePredicate = { it is LoopScope && it.loop == jump.loop }, jump = Break(jump.loop), startOffset = startOffset, endOffset = endOffset, value = irBuilder.irGetObject(context.ir.symbols.unit) ) ?: jump } override fun visitContinue(jump: IrContinue): IrExpression { val startOffset = jump.startOffset val endOffset = jump.endOffset val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) return performHighLevelJump( targetScopePredicate = { it is LoopScope && it.loop == jump.loop }, jump = Continue(jump.loop), startOffset = startOffset, endOffset = endOffset, value = irBuilder.irGetObject(context.ir.symbols.unit) ) ?: jump } override fun visitReturn(expression: IrReturn): IrExpression { expression.transformChildrenVoid(this) return performHighLevelJump( targetScopePredicate = { it is ReturnableScope && it.symbol == expression.returnTargetSymbol }, jump = Return(expression.returnTargetSymbol), startOffset = expression.startOffset, endOffset = expression.endOffset, value = expression.value ) ?: expression } private fun performHighLevelJump(targetScopePredicate: (Scope) -> Boolean, jump: HighLevelJump, startOffset: Int, endOffset: Int, value: IrExpression): IrExpression? { val tryScopes = scopeStack.reversed() .takeWhile { !targetScopePredicate(it) } .filterIsInstance() .toList() if (tryScopes.isEmpty()) return null return performHighLevelJump(tryScopes, 0, jump, startOffset, endOffset, value) } private val IrReturnTarget.returnType: IrType get() = when (this) { is IrConstructor -> context.irBuiltIns.unitType is IrFunction -> returnType is IrReturnableBlock -> type else -> error("Unknown ReturnTarget: $this") } private fun performHighLevelJump(tryScopes: List, index: Int, jump: HighLevelJump, startOffset: Int, endOffset: Int, value: IrExpression): IrExpression { if (index == tryScopes.size) return jump.toIr(context, startOffset, endOffset, value) val currentTryScope = tryScopes[index] currentTryScope.jumps.getOrPut(jump) { val type = (jump as? Return)?.target?.owner?.returnType ?: value.type val symbol = IrReturnableBlockSymbolImpl() with(currentTryScope) { irBuilder.run { val inlinedFinally = irInlineFinally(symbol, type, expression, finallyExpression) expression = performHighLevelJump( tryScopes = tryScopes, index = index + 1, jump = jump, startOffset = startOffset, endOffset = endOffset, value = inlinedFinally) } } symbol }.let { return IrReturnImpl( startOffset = startOffset, endOffset = endOffset, type = context.irBuiltIns.nothingType, returnTargetSymbol = it, value = value) } } override fun visitTry(aTry: IrTry): IrExpression { val finallyExpression = aTry.finallyExpression ?: return super.visitTry(aTry) val startOffset = aTry.startOffset val endOffset = aTry.endOffset val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) val transformer = this irBuilder.run { val transformedTry = IrTryImpl( startOffset = startOffset, endOffset = endOffset, type = context.irBuiltIns.nothingType ) val transformedFinallyExpression = finallyExpression.transform(transformer, null) val catchParameter = IrVariableImpl( startOffset, endOffset, IrDeclarationOrigin.CATCH_PARAMETER, IrVariableSymbolImpl(), Name.identifier("t"), symbols.throwable.owner.defaultType, isVar = false, isConst = false, isLateinit = false ).apply { parent = this@run.parent } val syntheticTry = IrTryImpl( startOffset = startOffset, endOffset = endOffset, type = context.irBuiltIns.nothingType, tryResult = transformedTry, catches = listOf( irCatch(catchParameter, irBlock { +copy(finallyExpression) +irThrow(irGet(catchParameter)) }) ), finallyExpression = null ) using(TryScope(syntheticTry, transformedFinallyExpression, this)) { val fallThroughType = aTry.type val fallThroughSymbol = IrReturnableBlockSymbolImpl() val transformedResult = aTry.tryResult.transform(transformer, null) transformedTry.tryResult = irReturn(fallThroughSymbol, transformedResult) for (aCatch in aTry.catches) { val transformedCatch = aCatch.transform(transformer, null) transformedCatch.result = irReturn(fallThroughSymbol, transformedCatch.result) transformedTry.catches.add(transformedCatch) } return irInlineFinally(fallThroughSymbol, fallThroughType, it.expression, it.finallyExpression) } } } private fun IrBuilderWithScope.irInlineFinally(symbol: IrReturnableBlockSymbol, type: IrType, value: IrExpression, finallyExpression: IrExpression): IrExpression { val returnTypeClassifier = (type as? IrSimpleType)?.classifier return when (returnTypeClassifier) { symbols.unit, symbols.nothing -> irBlock(value, null, type) { +irReturnableBlock(finallyExpression.startOffset, finallyExpression.endOffset, symbol, type) { +value } +copy(finallyExpression) } else -> irBlock(value, null, type) { val tmp = irTemporary(irReturnableBlock(finallyExpression.startOffset, finallyExpression.endOffset, symbol, type) { +irReturn(symbol, value) }) +copy(finallyExpression) +irGet(tmp) } } } private inline fun IrBuilderWithScope.copy(element: T) = element.deepCopyWithVariables().setDeclarationsParent(parent) fun IrBuilderWithScope.irReturn(target: IrReturnTargetSymbol, value: IrExpression) = IrReturnImpl(startOffset, endOffset, context.irBuiltIns.nothingType, target, value) private inline fun IrBuilderWithScope.irReturnableBlock(startOffset: Int, endOffset: Int, symbol: IrReturnableBlockSymbol, type: IrType, body: IrBlockBuilder.() -> Unit) = IrReturnableBlockImpl(startOffset, endOffset, type, symbol, null, IrBlockBuilder(context, scope, startOffset, endOffset, null, type) .block(body).statements) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.llvm.computeFullName import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance internal class FunctionReferenceLowering(val context: Context): FileLoweringPass { private object DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL") companion object { fun isLoweredFunctionReference(declaration: IrDeclaration): Boolean = declaration.origin == DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL } override fun lower(irFile: IrFile) { var generatedClasses = mutableListOf() irFile.transform(object: IrElementTransformerVoidWithContext() { private val stack = mutableListOf() override fun visitElement(element: IrElement): IrElement { stack.push(element) val result = super.visitElement(element) stack.pop() return result } override fun visitExpression(expression: IrExpression): IrExpression { stack.push(expression) val result = super.visitExpression(expression) stack.pop() return result } override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement { lateinit var tempGeneratedClasses: MutableList if (declaration is IrClass) { tempGeneratedClasses = generatedClasses generatedClasses = mutableListOf() } stack.push(declaration) val result = super.visitDeclaration(declaration) stack.pop() if (declaration is IrClass) { declaration.declarations += generatedClasses generatedClasses = tempGeneratedClasses } return result } override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement { stack.push(spread) val result = super.visitSpreadElement(spread) stack.pop() return result } // TODO: Move to common IR utils. fun IrType.eraseProjections(): IrType { if (this !is IrSimpleType) return this return buildSimpleType { this.classifier = this@eraseProjections.classifier this.hasQuestionMark = this@eraseProjections.hasQuestionMark this.annotations = this@eraseProjections.annotations this.arguments = this@eraseProjections.arguments.map { if (it !is IrTypeProjection) it else makeTypeProjection(it.type.eraseProjections(), Variance.INVARIANT) } } } // Handle SAM conversions which wrap a function reference: // class sam$n(private val receiver: R) : Interface { override fun method(...) = receiver.target(...) } // // This avoids materializing an invokable KFunction representing, thus producing one less class. // This is actually very common, as `Interface { something }` is a local function + a SAM-conversion // of a reference to it into an implementation. override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { if (expression.operator == IrTypeOperator.SAM_CONVERSION) { val invokable = expression.argument val reference = if (invokable is IrFunctionReference) { invokable } else if (invokable is IrBlock && (invokable.origin.isLambda) && invokable.statements.last() is IrFunctionReference) { // By this point the lambda's function has been replaced with empty IrComposite by LocalDeclarationsLowering. val statements = invokable.statements require(statements.size == 2) require((statements[0] as? IrComposite)?.statements?.isEmpty() == true) statements[1] as IrFunctionReference } else { return super.visitTypeOperator(expression) } reference.transformChildrenVoid() return transformFunctionReference(reference, expression.typeOperand.eraseProjections()) } return super.visitTypeOperator(expression) } override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { expression.transformChildrenVoid(this) for (i in stack.size - 1 downTo 0) { val cur = stack[i] if (cur is IrBlock) continue if (cur !is IrCall) break val argument = if (i < stack.size - 1) stack[i + 1] else expression val parameter = cur.symbol.owner.valueParameters.singleOrNull { cur.getValueArgument(it.index) == argument } if (parameter?.annotations?.findAnnotation(VOLATILE_LAMBDA_FQ_NAME) != null) { return expression } break } if (!expression.type.isFunction() && !expression.type.isKFunction() && !expression.type.isKSuspendFunction()) { // Not a subject of this lowering. return expression } return transformFunctionReference(expression) } fun transformFunctionReference(expression: IrFunctionReference, samSuperType: IrType? = null): IrExpression { val parent: IrDeclarationContainer = (currentClass?.irElement as? IrClass) ?: irFile val loweredFunctionReference = FunctionReferenceBuilder(irFile, parent, expression, samSuperType).build() generatedClasses.add(loweredFunctionReference.functionReferenceClass) val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset) return irBuilder.irCall(loweredFunctionReference.functionReferenceConstructor.symbol).apply { expression.getArguments().forEachIndexed { index, argument -> putValueArgument(index, argument.second) } } } }, data = null) irFile.declarations += generatedClasses } private class BuiltFunctionReference(val functionReferenceClass: IrClass, val functionReferenceConstructor: IrConstructor) private val VOLATILE_LAMBDA_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "VolatileLambda")) private val symbols = context.ir.symbols private val irBuiltIns = context.irBuiltIns private val getContinuationSymbol = symbols.getContinuation private val continuationClassSymbol = getContinuationSymbol.owner.returnType.classifierOrFail as IrClassSymbol private inner class FunctionReferenceBuilder( val irFile: IrFile, val parent: IrDeclarationParent, val functionReference: IrFunctionReference, val samSuperType: IrType? ) { private val startOffset = functionReference.startOffset private val endOffset = functionReference.endOffset private val referencedFunction = functionReference.symbol.owner private val functionParameters = referencedFunction.explicitParameters private val boundFunctionParameters = functionReference.getArgumentsWithIr().map { it.first } private val unboundFunctionParameters = functionParameters - boundFunctionParameters private val typeArgumentsMap = referencedFunction.typeParameters.associate { typeParam -> typeParam.symbol to functionReference.getTypeArgument(typeParam.index)!! } private val isLambda = functionReference.origin.isLambda private val isKFunction = functionReference.type.isKFunction() private val isKSuspendFunction = functionReference.type.isKSuspendFunction() private val samSuperClass = samSuperType?.let { it.classOrNull ?: error("Expected a class but was: ${it.render()}") } private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction private val functionReferenceClass: IrClass = IrClassImpl( startOffset,endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, IrClassSymbolImpl(), "${functionReferenceTarget.name}\$FUNCTION_REFERENCE\$${context.functionReferenceCount++}".synthesizedName, ClassKind.CLASS, DescriptorVisibilities.PRIVATE, Modality.FINAL, isCompanion = false, isInner = false, isData = false, isExternal = false, isInline = false, isExpect = false, isFun = false ).apply { parent = this@FunctionReferenceBuilder.parent createParameterDeclarations() } private val functionReferenceThis = functionReferenceClass.thisReceiver!! private val argumentToPropertiesMap = boundFunctionParameters.associate { it to createField( startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, it.type, it.name, isMutable = false, owner = functionReferenceClass ) } private fun IrClass.getInvokeFunction() = simpleFunctions().single { it.name.asString() == "invoke" } private val kFunctionImplSymbol = symbols.kFunctionImpl private val kFunctionImplConstructorSymbol = kFunctionImplSymbol.constructors.single() private val kSuspendFunctionImplSymbol = symbols.kSuspendFunctionImpl private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single() fun build(): BuiltFunctionReference { val superClass = when { isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType) isLambda -> irBuiltIns.anyType else -> kFunctionImplSymbol.typeWith(referencedFunction.returnType) } val superTypes = mutableListOf(superClass) if (samSuperType != null) { superTypes += samSuperType val sam = samSuperClass!!.functions.single { it.owner.modality == Modality.ABSTRACT } buildInvokeMethod(sam.owner) } else { val numberOfParameters = unboundFunctionParameters.size val functionParameterTypes = unboundFunctionParameters.map { it.type } val functionClass: IrClass val suspendFunctionClass: IrClass? if (isKSuspendFunction) { functionClass = symbols.functionN(numberOfParameters + 1).owner val continuationType = continuationClassSymbol.typeWith(referencedFunction.returnType) superTypes += functionClass.typeWith(functionParameterTypes + continuationType + irBuiltIns.anyNType) suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner superTypes += suspendFunctionClass.typeWith(functionParameterTypes + referencedFunction.returnType) } else { functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner superTypes += functionClass.typeWith(functionParameterTypes + referencedFunction.returnType) val lastParameterType = unboundFunctionParameters.lastOrNull()?.type if (lastParameterType?.classifierOrNull != continuationClassSymbol) suspendFunctionClass = null else { lastParameterType as IrSimpleType // If the last parameter is Continuation<> inherit from SuspendFunction. suspendFunctionClass = symbols.suspendFunctionN(numberOfParameters - 1).owner val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + (lastParameterType.arguments.single().typeOrNull ?: irBuiltIns.anyNType) superTypes += suspendFunctionClass.symbol.typeWith(suspendFunctionClassTypeParameters) } } if (!isKSuspendFunction) buildInvokeMethod(functionClass.getInvokeFunction()) if (suspendFunctionClass != null) { buildInvokeMethod(suspendFunctionClass.getInvokeFunction()).also { if (isKSuspendFunction) it.overriddenSymbols += functionClass.getInvokeFunction().symbol } } } functionReferenceClass.superTypes += superTypes functionReferenceClass.addFakeOverrides(context.irBuiltIns) return BuiltFunctionReference(functionReferenceClass, buildConstructor()) } private fun buildConstructor(): IrConstructor = IrConstructorImpl( startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, IrConstructorSymbolImpl(), Name.special(""), DescriptorVisibilities.PUBLIC, functionReferenceClass.defaultType, isInline = false, isExternal = false, isPrimary = true, isExpect = false ).apply { parent = functionReferenceClass functionReferenceClass.declarations += this valueParameters += boundFunctionParameters.mapIndexed { index, parameter -> parameter.copyTo(this, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, index, type = parameter.type.substitute(typeArgumentsMap)) } val kTypeGenerator = KTypeGenerator(context, irFile, functionReference) body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody { val superConstructor = when { isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner isLambda -> irBuiltIns.anyClass.owner.constructors.single() else -> kFunctionImplConstructorSymbol.owner } +irDelegatingConstructorCall(superConstructor).apply applyIrDelegationConstructorCall@ { if (isLambda) return@applyIrDelegationConstructorCall val name = ((functionReferenceTarget as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.name ?: functionReferenceTarget.name val needReceiver = boundFunctionParameters.singleOrNull()?.descriptor is ReceiverParameterDescriptor val receiver = if (needReceiver) irGet(valueParameters.single()) else irNull() val arity = unboundFunctionParameters.size + if (functionReferenceTarget.isSuspend) 1 else 0 putValueArgument(0, irString(name.asString())) putValueArgument(1, irString(functionReferenceTarget.computeFullName())) putValueArgument(2, receiver) putValueArgument(3, irInt(arity)) putValueArgument(4, irInt(getFlags())) putValueArgument(5, with(kTypeGenerator) { irKType(referencedFunction.returnType) }) } +IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, irBuiltIns.unitType) // Save all arguments to fields. boundFunctionParameters.forEachIndexed { index, parameter -> +irSetField(irGet(functionReferenceThis), argumentToPropertiesMap[parameter]!!, irGet(valueParameters[index])) } } } private fun getFlags() = (if (referencedFunction.isSuspend) 1 else 0) + getAdaptedCallableReferenceFlags() shl 1 private fun getAdaptedCallableReferenceFlags(): Int { if (adaptedReferenceOriginalTarget == null) return 0 val isVarargMappedToElementBit = if (hasVarargMappedToElement()) 1 else 0 val isSuspendConvertedBit = if (!adaptedReferenceOriginalTarget.isSuspend && referencedFunction.isSuspend) 1 else 0 val isCoercedToUnitBit = if (!adaptedReferenceOriginalTarget.returnType.isUnit() && referencedFunction.returnType.isUnit()) 1 else 0 return isVarargMappedToElementBit + (isSuspendConvertedBit shl 1) + (isCoercedToUnitBit shl 2) } private fun hasVarargMappedToElement(): Boolean { if (adaptedReferenceOriginalTarget == null) return false val originalParameters = adaptedReferenceOriginalTarget.allParameters val adaptedParameters = functionReference.symbol.owner.allParameters var index = 0 // TODO: There should be similar code somewhere in the resolve. while (index < originalParameters.size && index < adaptedParameters.size) { val originalParameter = originalParameters[index] val adaptedParameter = adaptedParameters[index] if (originalParameter.defaultValue != null) return false if (originalParameter.isVararg) { if (originalParameter.varargElementType!!.erasureForTypeOperation() == adaptedParameter.type.erasureForTypeOperation()) return true } ++index } return false } private fun buildInvokeMethod(superFunction: IrSimpleFunction): IrSimpleFunction = IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, IrSimpleFunctionSymbolImpl(), superFunction.name, DescriptorVisibilities.PRIVATE, Modality.FINAL, referencedFunction.returnType, isInline = false, isExternal = false, isTailrec = false, isSuspend = superFunction.isSuspend, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { val function = this parent = functionReferenceClass functionReferenceClass.declarations += function this.createDispatchReceiverParameter() extensionReceiverParameter = superFunction.extensionReceiverParameter?.copyTo(function) valueParameters += superFunction.valueParameters.mapIndexed { index, parameter -> parameter.copyTo(function, DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL, index, type = parameter.type.substitute(typeArgumentsMap)) } overriddenSymbols += superFunction.symbol body = context.createIrBuilder(function.symbol, startOffset, endOffset).irBlockBody(startOffset, endOffset) { +irReturn( irCall(functionReference.symbol).apply { var unboundIndex = 0 val unboundArgsSet = unboundFunctionParameters.toSet() for (parameter in functionParameters) { val argument = if (!unboundArgsSet.contains(parameter)) // Bound parameter - read from field. irGetField( irGet(function.dispatchReceiverParameter!!), argumentToPropertiesMap[parameter]!! ) else { if (parameter == referencedFunction.extensionReceiverParameter && extensionReceiverParameter != null) irGet(extensionReceiverParameter!!) else if (function.isSuspend && unboundIndex == valueParameters.size) // For suspend functions the last argument is continuation and it is implicit. irCall(getContinuationSymbol.owner, listOf(returnType)) else irGet(valueParameters[unboundIndex++]) } when (parameter) { referencedFunction.dispatchReceiverParameter -> dispatchReceiver = argument referencedFunction.extensionReceiverParameter -> extensionReceiver = argument else -> putValueArgument(parameter.index, argument) } } assert(unboundIndex == valueParameters.size) { "Not all arguments of are used" } } ) } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InitializersLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.isNonGeneratedAnnotation import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal class InitializersLowering(val context: CommonBackendContext) : ClassLoweringPass { object STATEMENT_ORIGIN_ANONYMOUS_INITIALIZER : IrStatementOriginImpl("ANONYMOUS_INITIALIZER") object DECLARATION_ORIGIN_ANONYMOUS_INITIALIZER : IrDeclarationOriginImpl("ANONYMOUS_INITIALIZER") override fun lower(irClass: IrClass) { if (irClass.isInterface) return InitializersTransformer(irClass).lowerInitializers() } private inner class InitializersTransformer(val irClass: IrClass) { val initializers = mutableListOf() fun lowerInitializers() { collectAndRemoveInitializers() val initializeMethodSymbol = createInitializerMethod() lowerConstructors(initializeMethodSymbol) } private fun collectAndRemoveInitializers() { // Do with one traversal in order to preserve initializers order. irClass.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested. return declaration } override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement { initializers.add(IrBlockImpl(declaration.startOffset, declaration.endOffset, context.irBuiltIns.unitType, STATEMENT_ORIGIN_ANONYMOUS_INITIALIZER, declaration.body.statements)) return declaration } override fun visitField(declaration: IrField): IrStatement { val initializer = declaration.initializer ?: return declaration val startOffset = initializer.startOffset val endOffset = initializer.endOffset val initExpression = initializer.expression initializers.add(IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.INITIALIZE_FIELD, listOf( IrSetFieldImpl(startOffset, endOffset, declaration.symbol, IrGetValueImpl( startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol ), initExpression, context.irBuiltIns.unitType, IrStatementOrigin.INITIALIZE_FIELD))) ) // We shall keep initializer for constants for compile-time instantiation. // We suppose that if the property is const, then its initializer is IrConst. // If this requirement isn't satisfied, then PropertyAccessorInlineLowering can fail. declaration.initializer = if (initExpression is IrConst<*> && declaration.correspondingPropertySymbol?.owner?.isConst == true) { IrExpressionBodyImpl(initExpression.copy()) } else { null } return declaration } }) irClass.declarations.transformFlat { if (it !is IrAnonymousInitializer) null else listOf() } } private fun createInitializerMethod(): IrSimpleFunctionSymbol? { if (irClass.declarations.any { it is IrConstructor && it.isPrimary }) return null // Place initializers in the primary constructor. val startOffset = irClass.startOffset val endOffset = irClass.endOffset val initializeFun = IrFunctionImpl( startOffset, endOffset, DECLARATION_ORIGIN_ANONYMOUS_INITIALIZER, IrSimpleFunctionSymbolImpl(), "INITIALIZER".synthesizedName, DescriptorVisibilities.PRIVATE, Modality.FINAL, context.irBuiltIns.unitType, isInline = false, isSuspend = false, isExternal = false, isTailrec = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { parent = irClass irClass.declarations.add(this) createDispatchReceiverParameter() body = IrBlockBodyImpl(startOffset, endOffset, initializers) } for (initializer in initializers) { initializer.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { if (expression.symbol == irClass.thisReceiver!!.symbol) { return IrGetValueImpl( expression.startOffset, expression.endOffset, initializeFun.dispatchReceiverParameter!!.type, initializeFun.dispatchReceiverParameter!!.symbol ) } return expression } }) initializer.setDeclarationsParent(initializeFun) } return initializeFun.symbol } private fun lowerConstructors(initializeMethodSymbol: IrSimpleFunctionSymbol?) { if (irClass.kind == ClassKind.ANNOTATION_CLASS) { if (irClass.isNonGeneratedAnnotation()) return val irConstructor = irClass.declarations.filterIsInstance().single() assert(irConstructor.body == null) irConstructor.body = context.createIrBuilder(irConstructor.symbol).irBlockBody(irConstructor) { +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single()) +IrInstanceInitializerCallImpl(startOffset, endOffset, irClass.symbol, context.irBuiltIns.unitType) } } irClass.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested. return declaration } override fun visitConstructor(declaration: IrConstructor): IrStatement { val body = declaration.body ?: return declaration val blockBody = body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${declaration.body}") blockBody.statements.transformFlat { when { it is IrInstanceInitializerCall -> { if (initializeMethodSymbol == null) { assert(declaration.isPrimary) for (initializer in initializers) initializer.setDeclarationsParent(declaration) initializers } else { val startOffset = it.startOffset val endOffset = it.endOffset listOf(IrCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, initializeMethodSymbol, initializeMethodSymbol.owner.typeParameters.size, initializeMethodSymbol.owner.valueParameters.size ).apply { dispatchReceiver = IrGetValueImpl( startOffset, endOffset, irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol ) }) } } /** * IR for kotlin.Any is: * BLOCK_BODY * DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' * INSTANCE_INITIALIZER_CALL classDescriptor='Any' * * to avoid possible recursion we manually reject body generation for Any. */ it is IrDelegatingConstructorCall && irClass.symbol == context.irBuiltIns.anyClass && it.symbol == declaration.symbol -> { listOf() } else -> null } } return declaration } }) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InnerClassLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.lower.callsSuper import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal class InnerClassLowering(val context: Context) : ClassLoweringPass { override fun lower(irClass: IrClass) { InnerClassTransformer(irClass).lowerInnerClass() } companion object { fun addOuterThisField(declarations: MutableList, irClass: IrClass, context: Context): IrField { val outerThisField = context.specialDeclarationsFactory.getOuterThisField(irClass) declarations += outerThisField return outerThisField } } private inner class InnerClassTransformer(val irClass: IrClass) { lateinit var outerThisFieldSymbol: IrFieldSymbol fun lowerInnerClass() { if (!irClass.isInner) return createOuterThisField() lowerOuterThisReferences() lowerConstructors() } private fun createOuterThisField() { val outerThisField = addOuterThisField(irClass.declarations, irClass, context) outerThisFieldSymbol = outerThisField.symbol } private fun lowerConstructors() { irClass.declarations.transformFlat { irMember -> if (irMember is IrConstructor) listOf(lowerConstructor(irMember)) else null } } private fun lowerConstructor(irConstructor: IrConstructor): IrConstructor { if (irConstructor.callsSuper(context.irBuiltIns)) { // Initializing constructor: initialize 'this.this$0' with '$outer'. val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}") val startOffset = irConstructor.startOffset val endOffset = irConstructor.endOffset val thisReceiver = irClass.thisReceiver!! val outerReceiver = irConstructor.dispatchReceiverParameter!! blockBody.statements.add( 0, IrSetFieldImpl( startOffset, endOffset, outerThisFieldSymbol, IrGetValueImpl(startOffset, endOffset, thisReceiver.type, thisReceiver.symbol), IrGetValueImpl(startOffset, endOffset, outerReceiver.type, outerReceiver.symbol), context.irBuiltIns.unitType ) ) } return irConstructor } private fun lowerOuterThisReferences() { irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { override fun visitClassNew(declaration: IrClass): IrStatement { // Skip nested. return declaration } override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid(this) val implicitThisClass = (expression.symbol.owner.parent as? IrClass) ?: return expression if (implicitThisClass == irClass) return expression val constructorSymbol = currentFunction!!.scope.scopeOwnerSymbol as? IrConstructorSymbol val startOffset = expression.startOffset val endOffset = expression.endOffset val origin = expression.origin var irThis: IrExpression var innerClass: IrClass if (constructorSymbol == null || constructorSymbol.owner.parentAsClass != irClass) { innerClass = irClass val currentIrFunction = currentFunction!!.scope.scopeOwnerSymbol.owner as IrFunction val currentFunctionReceiver = currentIrFunction.dispatchReceiverParameter val thisParameter = if (currentFunctionReceiver?.type?.classifierOrNull == irClass.symbol) currentFunctionReceiver else irClass.thisReceiver!! irThis = IrGetValueImpl(startOffset, endOffset, thisParameter.type, thisParameter.symbol, origin) } else { // For constructor we have outer class as dispatchReceiverParameter. innerClass = irClass.parent as? IrClass ?: throw AssertionError("No containing class for inner class ${irClass.dump()}") val thisParameter = constructorSymbol.owner.dispatchReceiverParameter!! irThis = IrGetValueImpl(startOffset, endOffset, thisParameter.type, thisParameter.symbol, origin) } while (innerClass != implicitThisClass) { if (!innerClass.isInner) { // Captured 'this' unrelated to inner classes nesting hierarchy, leave it as is - // should be transformed by closures conversion. return expression } val outerThisField = context.specialDeclarationsFactory.getOuterThisField(innerClass) irThis = IrGetFieldImpl( startOffset, endOffset, outerThisField.symbol, outerThisField.type, irThis, origin ) val outer = innerClass.parent innerClass = outer as? IrClass ?: throw AssertionError("Unexpected containing declaration for inner class ${innerClass.dump()}: $outer") } return irThis } }) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropCallConvertors.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.backend.konan.cgen.* import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationStringValue import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.utils.addToStdlib.cast private class InteropCallContext( val symbols: KonanSymbols, val builder: IrBuilderWithScope, val failCompilation: (String) -> Nothing ) { fun IrType.isCPointer() = this.isCPointer(symbols) fun IrType.isNativePointed() = this.isNativePointed(symbols) fun IrType.isSupportedReference() = this.isCStructFieldSupportedReferenceType(symbols) val irBuiltIns: IrBuiltIns = builder.context.irBuiltIns } private inline fun generateInteropCall( symbols: KonanSymbols, builder: IrBuilderWithScope, noinline failCompilation: (String) -> Nothing, block: InteropCallContext.() -> T ) = InteropCallContext(symbols, builder, failCompilation).block() /** * Search for memory read/write function in [kotlinx.cinterop.nativeMemUtils] of a given [valueType]. */ private fun InteropCallContext.findMemoryAccessFunction(isRead: Boolean, valueType: IrType): IrFunction { val requiredType = if (isRead) { IntrinsicType.INTEROP_READ_PRIMITIVE } else { IntrinsicType.INTEROP_WRITE_PRIMITIVE } val nativeMemUtilsClass = symbols.nativeMemUtils.owner return nativeMemUtilsClass.functions.filter { val annotationArgument = it.annotations .findAnnotation(RuntimeNames.typedIntrinsicAnnotation) ?.getAnnotationStringValue() annotationArgument == requiredType.name }.firstOrNull { if (isRead) { it.returnType.classOrNull == valueType.classOrNull } else { it.valueParameters.last().type.classOrNull == valueType.classOrNull } } ?: error("No memory access function for ${valueType.classOrNull?.owner?.name}") } private fun InteropCallContext.readValueFromMemory( nativePtr: IrExpression, returnType: IrType ): IrExpression { val memoryValueType = determineInMemoryType(returnType) val memReadFn = findMemoryAccessFunction(isRead = true, valueType = memoryValueType) val memRead = builder.irCall(memReadFn).also { memRead -> memRead.dispatchReceiver = builder.irGetObject(symbols.nativeMemUtils) memRead.putValueArgument(0, builder.irCall(symbols.interopInterpretNullablePointed).also { it.putValueArgument(0, nativePtr) }) } return castPrimitiveIfNeeded(memRead, memoryValueType, returnType) } private fun InteropCallContext.writeValueToMemory( nativePtr: IrExpression, value: IrExpression, targetType: IrType ): IrExpression { val memoryValueType = determineInMemoryType(targetType) val memWriteFn = findMemoryAccessFunction(isRead = false, valueType = memoryValueType) val valueToWrite = castPrimitiveIfNeeded(value, targetType, memoryValueType) return with(builder) { irCall(memWriteFn).also { memWrite -> memWrite.dispatchReceiver = irGetObject(symbols.nativeMemUtils) memWrite.putValueArgument(0, irCall(symbols.interopInterpretNullablePointed).also { it.putValueArgument(0, nativePtr) }) memWrite.putValueArgument(1, valueToWrite) } } } private fun InteropCallContext.determineInMemoryType(type: IrType): IrType { val classifier = type.classOrNull!! return when (classifier) { in symbols.unsignedIntegerClasses -> { symbols.unsignedToSignedOfSameBitWidth.getValue(classifier).owner.defaultType } // Assuming that _Bool is stored as single byte. irBuiltIns.booleanClass -> symbols.byte.defaultType else -> type } } private fun InteropCallContext.castPrimitiveIfNeeded( value: IrExpression, fromType: IrType, toType: IrType ): IrExpression { val sourceClass = fromType.classOrNull!! val targetClass = toType.classOrNull!! return if (sourceClass != targetClass) { when { targetClass == irBuiltIns.booleanClass -> castToBoolean(sourceClass, value) sourceClass == irBuiltIns.booleanClass -> castFromBoolean(targetClass, value) else -> { val conversion = symbols.integerConversions[sourceClass to targetClass] ?: error("There is no conversion from ${sourceClass.owner.name} to ${targetClass.owner.name}") builder.irCall(conversion.owner).apply { if (conversion.owner.dispatchReceiverParameter != null) { dispatchReceiver = value } else { extensionReceiver = value } } } } } else { value } } /** * Perform (value != 0) */ private fun InteropCallContext.castToBoolean(sourceClass: IrClassSymbol, value: IrExpression): IrExpression { val (primitiveBinaryType, immZero) = when (sourceClass) { // Case of regular struct field. symbols.byte -> PrimitiveBinaryType.BYTE to builder.irByte(0) // Case of bitfield. symbols.long -> PrimitiveBinaryType.LONG to builder.irLong(0) else -> error("Unsupported cast to boolean from ${sourceClass.owner.name}") } val areEqualByValuesBytes = symbols.areEqualByValue.getValue(primitiveBinaryType) val compareToZero = builder.irCall(areEqualByValuesBytes).apply { putValueArgument(0, value) putValueArgument(1, immZero) } return builder.irCall(irBuiltIns.booleanNotSymbol).apply { dispatchReceiver = compareToZero } } /** * Perform if (value) 1 else 0 */ private fun InteropCallContext.castFromBoolean(targetClass: IrClassSymbol, value: IrExpression): IrExpression { val (thenPart, elsePart) = when (targetClass) { // Case of regular struct field. symbols.byte -> builder.irByte(1) to builder.irByte(0) // Case of bitfield. symbols.long -> builder.irLong(1) to builder.irLong(0) else -> error("Unsupported cast from boolean to ${targetClass.owner.name}") } return builder.irIfThenElse(targetClass.defaultType, value, thenPart, elsePart) } private fun InteropCallContext.convertEnumToIntegral(enumValue: IrExpression, targetEnumType: IrType): IrExpression { val enumClass = targetEnumType.getClass()!! val valueProperty = enumClass.properties.single { it.name.asString() == "value" } return builder.irCall(valueProperty.getter!!).also { it.dispatchReceiver = enumValue } } private fun InteropCallContext.convertIntegralToEnum( value: IrExpression, intergralType: IrType, enumType: IrType ): IrExpression { val enumClass = enumType.getClass()!! val companionClass = enumClass.companionObject()!! val byValue = companionClass.simpleFunctions().single { it.name.asString() == "byValue" } val byValueArg = castPrimitiveIfNeeded(value, intergralType, byValue.valueParameters.first().type) return builder.irCall(byValue).apply { dispatchReceiver = builder.irGetObject(companionClass.symbol) putValueArgument(0, byValueArg) } } private fun IrType.getCEnumPrimitiveType(): IrType { assert(this.isCEnumType()) val enumClass = this.getClass()!! return enumClass.properties.single { it.name.asString() == "value" } .getter!!.returnType } private fun InteropCallContext.readEnumValueFromMemory(nativePtr: IrExpression, enumType: IrType): IrExpression { val enumPrimitiveType = enumType.getCEnumPrimitiveType() val readMemory = readValueFromMemory(nativePtr, enumPrimitiveType) return convertIntegralToEnum(readMemory, readMemory.type, enumType) } private fun InteropCallContext.writeEnumValueToMemory( nativePtr: IrExpression, value: IrExpression, targetEnumType: IrType ): IrExpression { val valueToWrite = convertEnumToIntegral(value, targetEnumType) return writeValueToMemory(nativePtr, valueToWrite, targetEnumType.getCEnumPrimitiveType()) } private fun InteropCallContext.convertCPointerToNativePtr(cPointer: IrExpression): IrExpression { return builder.irCall(symbols.interopCPointerGetRawValue).also { it.extensionReceiver = cPointer } } private fun InteropCallContext.writePointerToMemory( nativePtr: IrExpression, value: IrExpression, pointerType: IrType ): IrExpression { val valueToWrite = when { pointerType.isCPointer() -> convertCPointerToNativePtr(value) else -> error("Unsupported pointer type") } return writeValueToMemory(nativePtr, valueToWrite, valueToWrite.type) } private fun InteropCallContext.writeObjCReferenceToMemory( nativePtr: IrExpression, value: IrExpression ): IrExpression { val valueToWrite = builder.irCall(symbols.interopObjCObjectRawValueGetter).also { it.extensionReceiver = value } return writeValueToMemory(nativePtr, valueToWrite, valueToWrite.type) } private fun InteropCallContext.calculateFieldPointer(receiver: IrExpression, offset: Long): IrExpression { val base = builder.irCall(symbols.interopNativePointedRawPtrGetter).also { it.dispatchReceiver = receiver } val nativePtrPlusLong = symbols.nativePtrType.getClass()!! .functions.single { it.name.identifier == "plus" } return with (builder) { irCall(nativePtrPlusLong).also { it.dispatchReceiver = base it.putValueArgument(0, irLong(offset)) } } } private fun InteropCallContext.readPointerFromMemory(nativePtr: IrExpression): IrExpression { val readMemory = readValueFromMemory(nativePtr, symbols.nativePtrType) return builder.irCall(symbols.interopInterpretCPointer).also { it.putValueArgument(0, readMemory) } } private fun InteropCallContext.readPointed(nativePtr: IrExpression): IrExpression { return builder.irCall(symbols.interopInterpretNullablePointed).also { it.putValueArgument(0, nativePtr) } } private fun InteropCallContext.readObjectiveCReferenceFromMemory( nativePtr: IrExpression, type: IrType ): IrExpression { val readMemory = readValueFromMemory(nativePtr, symbols.nativePtrType) return builder.irCall(symbols.interopInterpretObjCPointerOrNull, listOf(type)).apply { putValueArgument(0, readMemory) } } /** Returns non-null result if [callSite] is accessor to: * 1. T.value, T : CEnumVar * 2. T., T : CStructVar and accessor is annotated with * [kotlinx.cinterop.internal.CStruct.MemberAt] or [kotlinx.cinterop.internal.CStruct.BitField] */ internal fun tryGenerateInteropMemberAccess( callSite: IrCall, symbols: KonanSymbols, builder: IrBuilderWithScope, failCompilation: (String) -> Nothing ): IrExpression? = when { callSite.symbol.owner.isCEnumVarValueAccessor(symbols) -> generateInteropCall(symbols, builder, failCompilation) { generateEnumVarValueAccess(callSite) } callSite.symbol.owner.isCStructMemberAtAccessor() -> generateInteropCall(symbols, builder, failCompilation) { generateMemberAtAccess(callSite) } callSite.symbol.owner.isCStructBitFieldAccessor() -> generateInteropCall(symbols, builder, failCompilation) { generateBitFieldAccess(callSite) } callSite.symbol.owner.isCStructArrayMemberAtAccessor() -> generateInteropCall(symbols, builder, failCompilation) { generateArrayMemberAtAccess(callSite) } else -> null } private fun InteropCallContext.generateEnumVarValueAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val nativePtr = builder.irCall(symbols.interopNativePointedRawPtrGetter).also { it.dispatchReceiver = callSite.dispatchReceiver!! } return when { accessor.isGetter -> readEnumValueFromMemory(nativePtr, accessor.returnType) accessor.isSetter -> { val type = accessor.valueParameters[0].type writeEnumValueToMemory(nativePtr, callSite.getValueArgument(0)!!, type) } else -> error("") } } private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val memberAt = accessor.getAnnotation(RuntimeNames.cStructMemberAt)!! val offset = memberAt.getValueArgument(0).cast>().value val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset) return when { accessor.isGetter -> { val type = accessor.returnType when { type.isCEnumType() -> readEnumValueFromMemory(fieldPointer, type) type.isCStructFieldTypeStoredInMemoryDirectly() -> readValueFromMemory(fieldPointer, type) type.isCPointer() -> readPointerFromMemory(fieldPointer) type.isNativePointed() -> readPointed(fieldPointer) type.isSupportedReference() -> readObjectiveCReferenceFromMemory(fieldPointer, type) else -> failCompilation("Unsupported struct field type: ${type.getClass()?.name}") } } accessor.isSetter -> { val value = callSite.getValueArgument(0)!! val type = accessor.valueParameters[0].type when { type.isCEnumType() -> writeEnumValueToMemory(fieldPointer, value, type) type.isCStructFieldTypeStoredInMemoryDirectly() -> writeValueToMemory(fieldPointer, value, type) type.isCPointer() -> writePointerToMemory(fieldPointer, value, type) type.isSupportedReference() -> writeObjCReferenceToMemory(fieldPointer, value) else -> failCompilation("Unsupported struct field type: ${type.getClass()?.name}") } } else -> failCompilation("Unexpected accessor function: ${accessor.name}") } } private fun InteropCallContext.generateArrayMemberAtAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val memberAt = accessor.getAnnotation(RuntimeNames.cStructArrayMemberAt)!! val offset = memberAt.getValueArgument(0).cast>().value val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset) return builder.irCall(symbols.interopInterpretCPointer).also { it.putValueArgument(0, fieldPointer) } } private fun InteropCallContext.writeBits( base: IrExpression, offset: Long, size: Int, value: IrExpression, type: IrType ): IrExpression { val (integralValue, fromType) = when { type.isCEnumType() -> convertEnumToIntegral(value, type) to type.getCEnumPrimitiveType() else -> value to type } val targetType = symbols.writeBits.owner.valueParameters.last().type val valueToWrite = castPrimitiveIfNeeded(integralValue, fromType, targetType) return with(builder) { irCall(symbols.writeBits).also { it.putValueArgument(0, base) it.putValueArgument(1, irLong(offset)) it.putValueArgument(2, irInt(size)) it.putValueArgument(3, valueToWrite) } } } private fun InteropCallContext.readBits( base: IrExpression, offset: Long, size: Int, type: IrType ): IrExpression { val isSigned = when { type.isCEnumType() -> !type.getCEnumPrimitiveType().isUnsigned() else -> !type.isUnsigned() } val integralValue = with (builder) { irCall(symbols.readBits).also { it.putValueArgument(0, base) it.putValueArgument(1, irLong(offset)) it.putValueArgument(2, irInt(size)) it.putValueArgument(3, irBoolean(isSigned)) } } return when { type.isCEnumType() -> convertIntegralToEnum(integralValue, integralValue.type, type) else -> castPrimitiveIfNeeded(integralValue, integralValue.type, type) } } private fun InteropCallContext.generateBitFieldAccess(callSite: IrCall): IrExpression { val accessor = callSite.symbol.owner val bitField = accessor.getAnnotation(RuntimeNames.cStructBitField)!! val offset = bitField.getValueArgument(0).cast>().value val size = bitField.getValueArgument(1).cast>().value val base = builder.irCall(symbols.interopNativePointedRawPtrGetter).also { it.dispatchReceiver = callSite.dispatchReceiver!! } return when { accessor.isSetter -> { val argument = callSite.getValueArgument(0)!! val type = accessor.valueParameters[0].type writeBits(base, offset, size, argument, type) } accessor.isGetter -> { val type = accessor.returnType readBits(base, offset, size, type) } else -> error("Unexpected accessor function: ${accessor.name}") } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.cgen.* import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.ir.companionObject import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType import org.jetbrains.kotlin.backend.konan.serialization.resolveFakeOverrideMaybeAbstract import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.konan.ForeignExceptionMode internal class InteropLowering(context: Context) : FileLoweringPass { // TODO: merge these lowerings. private val part1 = InteropLoweringPart1(context) private val part2 = InteropLoweringPart2(context) override fun lower(irFile: IrFile) { part1.lower(irFile) part2.lower(irFile) } } private abstract class BaseInteropIrTransformer(private val context: Context) : IrBuildingTransformer(context) { protected inline fun generateWithStubs(element: IrElement? = null, block: KotlinStubs.() -> T): T = createKotlinStubs(element).block() protected fun createKotlinStubs(element: IrElement?): KotlinStubs { val location = if (element != null) { element.getCompilerMessageLocation(irFile) } else { builder.getCompilerMessageLocation() } val uniqueModuleName = irFile.packageFragmentDescriptor.module.name.asString() .let { it.substring(1, it.lastIndex) } val uniquePrefix = buildString { append('_') uniqueModuleName.toByteArray().joinTo(this, "") { (0xFF and it.toInt()).toString(16).padStart(2, '0') } append('_') } return object : KotlinStubs { override val irBuiltIns get() = context.irBuiltIns override val symbols get() = context.ir.symbols override fun addKotlin(declaration: IrDeclaration) { addTopLevel(declaration) } override fun addC(lines: List) { context.cStubsManager.addStub(location, lines) } override fun getUniqueCName(prefix: String) = "$uniquePrefix${context.cStubsManager.getUniqueName(prefix)}" override fun getUniqueKotlinFunctionReferenceClassName(prefix: String) = "$prefix${context.functionReferenceCount++}" override val target get() = context.config.target override fun throwCompilerError(element: IrElement?, message: String): Nothing { error(irFile, element, message) } override fun renderCompilerError(element: IrElement?, message: String) = renderCompilerError(irFile, element, message) } } protected fun renderCompilerError(element: IrElement?, message: String = "Failed requirement") = renderCompilerError(irFile, element, message) protected abstract val irFile: IrFile protected abstract fun addTopLevel(declaration: IrDeclaration) } private class InteropLoweringPart1(val context: Context) : BaseInteropIrTransformer(context), FileLoweringPass { private val symbols get() = context.ir.symbols lateinit var currentFile: IrFile private val topLevelInitializers = mutableListOf() private val newTopLevelDeclarations = mutableListOf() override val irFile: IrFile get() = currentFile override fun addTopLevel(declaration: IrDeclaration) { declaration.parent = currentFile newTopLevelDeclarations += declaration } override fun lower(irFile: IrFile) { currentFile = irFile irFile.transformChildrenVoid(this) topLevelInitializers.forEach { irFile.addTopLevelInitializer(it, context, false) } topLevelInitializers.clear() irFile.addChildren(newTopLevelDeclarations) newTopLevelDeclarations.clear() } private fun IrBuilderWithScope.callAlloc(classPtr: IrExpression): IrExpression = irCall(symbols.interopAllocObjCObject).apply { putValueArgument(0, classPtr) } private val outerClasses = mutableListOf() override fun visitClass(declaration: IrClass): IrStatement { if (declaration.isKotlinObjCClass()) { lowerKotlinObjCClass(declaration) } outerClasses.push(declaration) try { return super.visitClass(declaration) } finally { outerClasses.pop() } } private fun lowerKotlinObjCClass(irClass: IrClass) { checkKotlinObjCClass(irClass) val interop = context.interopBuiltIns irClass.declarations.toList().mapNotNull { when { it is IrSimpleFunction && it.annotations.hasAnnotation(interop.objCAction.fqNameSafe) -> generateActionImp(it) it is IrProperty && it.annotations.hasAnnotation(interop.objCOutlet.fqNameSafe) -> generateOutletSetterImp(it) it is IrConstructor && it.isOverrideInit() -> generateOverrideInit(irClass, it) else -> null } }.let { irClass.addChildren(it) } if (irClass.annotations.hasAnnotation(interop.exportObjCClass.fqNameSafe)) { val irBuilder = context.createIrBuilder(currentFile.symbol).at(irClass) topLevelInitializers.add(irBuilder.getObjCClass(symbols, irClass.symbol)) } } private fun IrConstructor.isOverrideInit(): Boolean { if (this.origin != IrDeclarationOrigin.DEFINED) { // Make best efforts to skip generated stubs that might have got annotations // copied from original declarations. // For example, default argument stubs (https://youtrack.jetbrains.com/issue/KT-41910). return false } return this.annotations.hasAnnotation(context.interopBuiltIns.objCOverrideInit.fqNameSafe) } private fun generateOverrideInit(irClass: IrClass, constructor: IrConstructor): IrSimpleFunction { val superClass = irClass.getSuperClassNotAny()!! val superConstructors = superClass.constructors.filter { constructor.overridesConstructor(it) }.toList() val superConstructor = superConstructors.singleOrNull() require(superConstructor != null) { renderCompilerError(constructor) } val initMethod = superConstructor.getObjCInitMethod()!! // Remove fake overrides of this init method, also check for explicit overriding: irClass.declarations.removeAll { if (it is IrSimpleFunction && initMethod.symbol in it.overriddenSymbols) { require(it.isFakeOverride) { renderCompilerError(constructor) } true } else { false } } // Generate `override fun init...(...) = this.initBy(...)`: return IrFunctionImpl( constructor.startOffset, constructor.endOffset, OVERRIDING_INITIALIZER_BY_CONSTRUCTOR, IrSimpleFunctionSymbolImpl(), initMethod.name, DescriptorVisibilities.PUBLIC, Modality.OPEN, irClass.defaultType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).also { result -> result.parent = irClass result.createDispatchReceiverParameter() result.valueParameters += constructor.valueParameters.map { it.copyTo(result) } result.overriddenSymbols += initMethod.symbol result.body = context.createIrBuilder(result.symbol).irBlockBody(result) { +irReturn( irCall(symbols.interopObjCObjectInitBy, listOf(irClass.defaultType)).apply { extensionReceiver = irGet(result.dispatchReceiverParameter!!) putValueArgument(0, irCall(constructor).also { result.valueParameters.forEach { parameter -> it.putValueArgument(parameter.index, irGet(parameter)) } }) } ) } // Ensure it gets correctly recognized by the compiler. require(result.getObjCMethodInfo() != null) { renderCompilerError(constructor) } } } private object OVERRIDING_INITIALIZER_BY_CONSTRUCTOR : IrDeclarationOriginImpl("OVERRIDING_INITIALIZER_BY_CONSTRUCTOR") private fun IrConstructor.overridesConstructor(other: IrConstructor): Boolean { return this.descriptor.valueParameters.size == other.descriptor.valueParameters.size && this.descriptor.valueParameters.all { val otherParameter = other.descriptor.valueParameters[it.index] it.name == otherParameter.name && it.type == otherParameter.type } } private fun generateActionImp(function: IrSimpleFunction): IrSimpleFunction { require(function.extensionReceiverParameter == null) { renderCompilerError(function) } require(function.valueParameters.all { it.type.isObjCObjectType() }) { renderCompilerError(function) } require(function.returnType.isUnit()) { renderCompilerError(function) } return generateFunctionImp(inferObjCSelector(function.descriptor), function) } private fun generateOutletSetterImp(property: IrProperty): IrSimpleFunction { require(property.isVar) { renderCompilerError(property) } require(property.getter?.extensionReceiverParameter == null) { renderCompilerError(property) } require(property.descriptor.type.isObjCObjectType()) { renderCompilerError(property) } val name = property.name.asString() val selector = "set${name.capitalize()}:" return generateFunctionImp(selector, property.setter!!) } private fun getMethodSignatureEncoding(function: IrFunction): String { require(function.extensionReceiverParameter == null) { renderCompilerError(function) } require(function.valueParameters.all { it.type.isObjCObjectType() }) { renderCompilerError(function) } require(function.returnType.isUnit()) { renderCompilerError(function) } // Note: these values are valid for x86_64 and arm64. return when (function.valueParameters.size) { 0 -> "v16@0:8" 1 -> "v24@0:8@16" 2 -> "v32@0:8@16@24" else -> error(irFile, function, "Only 0, 1 or 2 parameters are supported here") } } private fun generateFunctionImp(selector: String, function: IrFunction): IrSimpleFunction { val signatureEncoding = getMethodSignatureEncoding(function) val nativePtrType = context.ir.symbols.nativePtrType val parameterTypes = mutableListOf(nativePtrType) // id self parameterTypes.add(nativePtrType) // SEL _cmd function.valueParameters.mapTo(parameterTypes) { nativePtrType } val newFunction = IrFunctionImpl( function.startOffset, function.endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), ("imp:$selector").synthesizedName, DescriptorVisibilities.PRIVATE, Modality.FINAL, function.returnType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) newFunction.valueParameters += parameterTypes.mapIndexed { index, type -> IrValueParameterImpl( function.startOffset, function.endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(), Name.identifier("p$index"), index, type, varargElementType = null, isCrossinline = false, isNoinline = false, isHidden = false, isAssignable = false ).apply { parent = newFunction } } // Annotations to be detected in KotlinObjCClassInfoGenerator: newFunction.annotations += buildSimpleAnnotation(context.irBuiltIns, function.startOffset, function.endOffset, symbols.objCMethodImp.owner, selector, signatureEncoding) val builder = context.createIrBuilder(newFunction.symbol) newFunction.body = builder.irBlockBody(newFunction) { +irCall(function).apply { dispatchReceiver = interpretObjCPointer( irGet(newFunction.valueParameters[0]), function.dispatchReceiverParameter!!.type ) function.valueParameters.forEachIndexed { index, parameter -> putValueArgument(index, interpretObjCPointer( irGet(newFunction.valueParameters[index + 2]), parameter.type ) ) } } } return newFunction } private fun IrBuilderWithScope.interpretObjCPointer(expression: IrExpression, type: IrType): IrExpression { val callee: IrFunctionSymbol = if (type.containsNull()) { symbols.interopInterpretObjCPointerOrNull } else { symbols.interopInterpretObjCPointer } return irCall(callee, listOf(type)).apply { putValueArgument(0, expression) } } private fun IrClass.hasFields() = this.declarations.any { when (it) { is IrField -> it.isReal is IrProperty -> it.isReal && it.backingField != null else -> false } } private fun checkKotlinObjCClass(irClass: IrClass) { val kind = irClass.kind require(kind == ClassKind.CLASS || kind == ClassKind.OBJECT) { renderCompilerError(irClass) } require(irClass.isFinalClass) { renderCompilerError(irClass) } require(irClass.companionObject()?.hasFields() != true) { renderCompilerError(irClass) } require(irClass.companionObject()?.getSuperClassNotAny()?.hasFields() != true) { renderCompilerError(irClass) } var hasObjCClassSupertype = false irClass.descriptor.defaultType.constructor.supertypes.forEach { val descriptor = it.constructor.declarationDescriptor as ClassDescriptor require(descriptor.isObjCClass()) { renderCompilerError(irClass) } if (descriptor.kind == ClassKind.CLASS) { hasObjCClassSupertype = true } } require(hasObjCClassSupertype) { renderCompilerError(irClass) } val methodsOfAny = context.ir.symbols.any.owner.declarations.filterIsInstance().toSet() irClass.declarations.filterIsInstance().filter { it.isReal }.forEach { method -> val overriddenMethodOfAny = method.allOverriddenFunctions.firstOrNull { it in methodsOfAny } require(overriddenMethodOfAny == null) { renderCompilerError(method) } } } override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { expression.transformChildrenVoid() builder.at(expression) val constructedClass = outerClasses.peek()!! if (!constructedClass.isObjCClass()) { return expression } constructedClass.parent.let { parent -> if (parent is IrClass && parent.isObjCClass() && constructedClass.isCompanion) { // Note: it is actually not used; getting values of such objects is handled by code generator // in [FunctionGenerationContext.getObjectValue]. return expression } } val delegatingCallConstructingClass = expression.symbol.owner.constructedClass if (!constructedClass.isExternalObjCClass() && delegatingCallConstructingClass.isExternalObjCClass()) { // Calling super constructor from Kotlin Objective-C class. require(constructedClass.getSuperClassNotAny() == delegatingCallConstructingClass) { renderCompilerError(expression) } require(expression.symbol.owner.objCConstructorIsDesignated()) { renderCompilerError(expression) } require(expression.dispatchReceiver == null) { renderCompilerError(expression) } require(expression.extensionReceiver == null) { renderCompilerError(expression) } val initMethod = expression.symbol.owner.getObjCInitMethod()!! val initMethodInfo = initMethod.getExternalObjCMethodInfo()!! val initCall = builder.genLoweredObjCMethodCall( initMethodInfo, superQualifier = delegatingCallConstructingClass.symbol, receiver = builder.irGet(constructedClass.thisReceiver!!), arguments = initMethod.valueParameters.map { expression.getValueArgument(it.index) }, call = expression, method = initMethod ) val superConstructor = delegatingCallConstructingClass .constructors.single { it.valueParameters.size == 0 }.symbol return builder.irBlock(expression) { // Required for the IR to be valid, will be ignored in codegen: +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( startOffset, endOffset, context.irBuiltIns.unitType, superConstructor ) +irCall(symbols.interopObjCObjectSuperInitCheck).apply { extensionReceiver = irGet(constructedClass.thisReceiver!!) putValueArgument(0, initCall) } } } return expression } private fun IrBuilderWithScope.genLoweredObjCMethodCall( info: ObjCMethodInfo, superQualifier: IrClassSymbol?, receiver: IrExpression, arguments: List, call: IrFunctionAccessExpression, method: IrSimpleFunction ): IrExpression = genLoweredObjCMethodCall( info = info, superQualifier = superQualifier, receiver = ObjCCallReceiver.Regular(rawPtr = getRawPtr(receiver)), arguments = arguments, call = call, method = method ) private fun IrBuilderWithScope.genLoweredObjCMethodCall( info: ObjCMethodInfo, superQualifier: IrClassSymbol?, receiver: ObjCCallReceiver, arguments: List, call: IrFunctionAccessExpression, method: IrSimpleFunction ): IrExpression = generateWithStubs(call) { if (method.parent !is IrClass) { // Category-provided. this@InteropLoweringPart1.context.llvmImports.add(method.llvmSymbolOrigin) } this.generateObjCCall( this@genLoweredObjCMethodCall, method, info.isStret, info.selector, call, superQualifier, receiver, arguments ) } override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { expression.transformChildrenVoid() val callee = expression.symbol.owner val initMethod = callee.getObjCInitMethod() if (initMethod != null) { val arguments = callee.valueParameters.map { expression.getValueArgument(it.index) } require(expression.extensionReceiver == null) { renderCompilerError(expression) } require(expression.dispatchReceiver == null) { renderCompilerError(expression) } val constructedClass = callee.constructedClass val initMethodInfo = initMethod.getExternalObjCMethodInfo()!! return builder.at(expression).run { val classPtr = getObjCClass(symbols, constructedClass.symbol) ensureObjCReferenceNotNull(callAllocAndInit(classPtr, initMethodInfo, arguments, expression, initMethod)) } } return expression } private fun IrBuilderWithScope.ensureObjCReferenceNotNull(expression: IrExpression): IrExpression = if (!expression.type.containsNull()) { expression } else { irBlock(resultType = expression.type) { val temp = irTemporary(expression) +irIfThen( context.irBuiltIns.unitType, irEqeqeq(irGet(temp), irNull()), irCall(symbols.throwNullPointerException) ) +irGet(temp) } } override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid() val callee = expression.symbol.owner callee.getObjCFactoryInitMethodInfo()?.let { initMethodInfo -> val arguments = (0 until expression.valueArgumentsCount) .map { index -> expression.getValueArgument(index) } return builder.at(expression).run { val classPtr = getRawPtr(expression.extensionReceiver!!) callAllocAndInit(classPtr, initMethodInfo, arguments, expression, callee) } } callee.getExternalObjCMethodInfo()?.let { methodInfo -> val isInteropStubsFile = currentFile.annotations.hasAnnotation(FqName("kotlinx.cinterop.InteropStubs")) // Special case: bridge from Objective-C method implementation template to Kotlin method; // handled in CodeGeneratorVisitor.callVirtual. val useKotlinDispatch = isInteropStubsFile && (builder.scope.scopeOwnerSymbol.owner as? IrAnnotationContainer) ?.hasAnnotation(FqName("kotlin.native.internal.ExportForCppRuntime")) == true if (!useKotlinDispatch) { val arguments = callee.valueParameters.map { expression.getValueArgument(it.index) } require(expression.dispatchReceiver == null || expression.extensionReceiver == null) { renderCompilerError(expression) } require(expression.superQualifierSymbol?.owner?.isObjCMetaClass() != true) { renderCompilerError(expression) } require(expression.superQualifierSymbol?.owner?.isInterface != true) { renderCompilerError(expression) } builder.at(expression) return builder.genLoweredObjCMethodCall( methodInfo, superQualifier = expression.superQualifierSymbol, receiver = expression.dispatchReceiver ?: expression.extensionReceiver!!, arguments = arguments, call = expression, method = callee ) } } return when (callee.symbol) { symbols.interopTypeOf -> { val typeArgument = expression.getSingleTypeArgument() val classSymbol = typeArgument.classifierOrNull as? IrClassSymbol if (classSymbol == null) { expression } else { val irClass = classSymbol.owner val companionObject = irClass.companionObject() ?: error(irFile, expression, "native variable class ${irClass.descriptor} must have the companion object") builder.at(expression).irGetObject(companionObject.symbol) } } else -> expression } } override fun visitProperty(declaration: IrProperty): IrStatement { val backingField = declaration.backingField return if (declaration.isConst && backingField?.isStatic == true && context.config.isInteropStubs) { // Transform top-level `const val x = 42` to `val x get() = 42`. // Generally this transformation is just an optimization to ensure that interop constants // don't require any storage and/or initialization at program startup. // Also it is useful due to uncertain design of top-level stored properties in Kotlin/Native. val initializer = backingField.initializer!!.expression declaration.backingField = null val getter = declaration.getter!! val getterBody = getter.body!! as IrBlockBody getterBody.statements.clear() getterBody.statements += IrReturnImpl( declaration.startOffset, declaration.endOffset, context.irBuiltIns.nothingType, getter.symbol, initializer ) // Note: in interop stubs const val initializer is either `IrConst` or quite simple expression, // so it is ok to compute it every time. require(declaration.setter == null) { renderCompilerError(declaration) } require(!declaration.isVar) { renderCompilerError(declaration) } declaration.transformChildrenVoid() declaration } else { super.visitProperty(declaration) } } private fun IrBuilderWithScope.callAllocAndInit( classPtr: IrExpression, initMethodInfo: ObjCMethodInfo, arguments: List, call: IrFunctionAccessExpression, initMethod: IrSimpleFunction ): IrExpression = genLoweredObjCMethodCall( initMethodInfo, superQualifier = null, receiver = ObjCCallReceiver.Retained(rawPtr = callAlloc(classPtr)), arguments = arguments, call = call, method = initMethod ) private fun IrBuilderWithScope.getRawPtr(receiver: IrExpression) = irCall(symbols.interopObjCObjectRawValueGetter).apply { extensionReceiver = receiver } } /** * Lowers some interop intrinsic calls. */ private class InteropLoweringPart2(val context: Context) : FileLoweringPass { override fun lower(irFile: IrFile) { val transformer = InteropTransformer(context, irFile) irFile.transformChildrenVoid(transformer) while (transformer.newTopLevelDeclarations.isNotEmpty()) { val newTopLevelDeclarations = transformer.newTopLevelDeclarations.toList() transformer.newTopLevelDeclarations.clear() // Assuming these declarations contain only new IR (i.e. existing lowered IR has not been moved there). // TODO: make this more reliable. val loweredNewTopLevelDeclarations = newTopLevelDeclarations.map { it.transform(transformer, null) as IrDeclaration } irFile.addChildren(loweredNewTopLevelDeclarations) } } } private class InteropTransformer(val context: Context, override val irFile: IrFile) : BaseInteropIrTransformer(context) { val newTopLevelDeclarations = mutableListOf() val interop = context.interopBuiltIns val symbols = context.ir.symbols override fun addTopLevel(declaration: IrDeclaration) { declaration.parent = irFile newTopLevelDeclarations += declaration } override fun visitClass(declaration: IrClass): IrStatement { super.visitClass(declaration) if (declaration.isKotlinObjCClass()) { val uniq = mutableSetOf() // remove duplicates [KT-38234] val imps = declaration.simpleFunctions().filter { it.isReal }.flatMap { function -> function.overriddenSymbols.mapNotNull { val selector = it.owner.getExternalObjCMethodInfo()?.selector if (selector == null || selector in uniq) { null } else { uniq += selector generateWithStubs(it.owner) { generateCFunctionAndFakeKotlinExternalFunction( function, it.owner, isObjCMethod = true, location = function ) } } } } declaration.addChildren(imps) } return declaration } private fun generateCFunctionPointer(function: IrSimpleFunction, expression: IrExpression): IrExpression = generateWithStubs { generateCFunctionPointer(function, function, expression) } override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { expression.transformChildrenVoid(this) val callee = expression.symbol.owner val inlinedClass = callee.returnType.getInlinedClassNative() require(inlinedClass?.descriptor != interop.cPointer) { renderCompilerError(expression) } require(inlinedClass?.descriptor != interop.nativePointed) { renderCompilerError(expression) } val constructedClass = callee.constructedClass if (!constructedClass.isObjCClass()) return expression // Calls to other ObjC class constructors must be lowered. require(constructedClass.isKotlinObjCClass()) { renderCompilerError(expression) } return builder.at(expression).irBlock { val rawPtr = irTemporary(irCall(symbols.interopAllocObjCObject.owner).apply { putValueArgument(0, getObjCClass(symbols, constructedClass.symbol)) }) val instance = irTemporary(irCall(symbols.interopInterpretObjCPointer.owner).apply { putValueArgument(0, irGet(rawPtr)) }) // Balance pointer retained by alloc: +irCall(symbols.interopObjCRelease.owner).apply { putValueArgument(0, irGet(rawPtr)) } +irCall(symbols.initInstance).apply { putValueArgument(0, irGet(instance)) putValueArgument(1, expression) } +irGet(instance) } } /** * Handle `const val`s that come from interop libraries. * * We extract constant value from the backing field, and replace getter invocation with it. */ private fun tryGenerateInteropConstantRead(expression: IrCall): IrExpression? { val function = expression.symbol.owner if (!function.isFromInteropLibrary()) return null if (!function.isGetter) return null val constantProperty = (function as? IrSimpleFunction) ?.correspondingPropertySymbol ?.owner ?.takeIf { it.isConst } ?: return null val initializer = constantProperty.backingField?.initializer?.expression require(initializer is IrConst<*>) { renderCompilerError(expression) } // Avoid node duplication return initializer.copy() } override fun visitCall(expression: IrCall): IrExpression { val intrinsicType = tryGetIntrinsicType(expression) if (intrinsicType == IntrinsicType.OBJC_INIT_BY) { // Need to do this separately as otherwise [expression.transformChildrenVoid(this)] would be called // and the [IrConstructorCall] would be transformed which is not what we want. val argument = expression.getValueArgument(0)!! require(argument is IrConstructorCall) { renderCompilerError(argument) } val constructedClass = argument.symbol.owner.constructedClass val extensionReceiver = expression.extensionReceiver!! require(extensionReceiver is IrGetValue && extensionReceiver.symbol.owner.isDispatchReceiverFor(constructedClass)) { renderCompilerError(extensionReceiver) } argument.transformChildrenVoid(this) return builder.at(expression).irBlock { val instance = extensionReceiver.symbol.owner +irCall(symbols.initInstance).apply { putValueArgument(0, irGet(instance)) putValueArgument(1, argument) } +irGet(instance) } } expression.transformChildrenVoid(this) builder.at(expression) val function = expression.symbol.owner if ((function as? IrSimpleFunction)?.resolveFakeOverrideMaybeAbstract()?.symbol == symbols.interopNativePointedRawPtrGetter) { // Replace by the intrinsic call to be handled by code generator: return builder.irCall(symbols.interopNativePointedGetRawPointer).apply { extensionReceiver = expression.dispatchReceiver } } if (function.annotations.hasAnnotation(RuntimeNames.cCall)) { context.llvmImports.add(function.llvmSymbolOrigin) val exceptionMode = ForeignExceptionMode.byValue( function.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey) ) return generateWithStubs { generateCCall(expression, builder, isInvoke = false, exceptionMode) } } val failCompilation = { msg: String -> error(irFile, expression, msg) } tryGenerateInteropMemberAccess(expression, symbols, builder, failCompilation)?.let { return it } tryGenerateInteropConstantRead(expression)?.let { return it } if (intrinsicType != null) { return when (intrinsicType) { IntrinsicType.INTEROP_BITS_TO_FLOAT -> { val argument = expression.getValueArgument(0) if (argument is IrConst<*> && argument.kind == IrConstKind.Int) { val floatValue = kotlinx.cinterop.bitsToFloat(argument.value as Int) builder.irFloat(floatValue) } else { expression } } IntrinsicType.INTEROP_BITS_TO_DOUBLE -> { val argument = expression.getValueArgument(0) if (argument is IrConst<*> && argument.kind == IrConstKind.Long) { val doubleValue = kotlinx.cinterop.bitsToDouble(argument.value as Long) builder.irDouble(doubleValue) } else { expression } } IntrinsicType.INTEROP_STATIC_C_FUNCTION -> { val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(0)!!) require(irCallableReference != null && irCallableReference.getArguments().isEmpty() && irCallableReference.symbol is IrSimpleFunctionSymbol) { renderCompilerError(expression) } val targetSymbol = irCallableReference.symbol val target = targetSymbol.owner val signatureTypes = target.allParameters.map { it.type } + target.returnType function.typeParameters.indices.forEach { index -> val typeArgument = expression.getTypeArgument(index)!!.toKotlinType() val signatureType = signatureTypes[index].toKotlinType() require(typeArgument.constructor == signatureType.constructor && typeArgument.isMarkedNullable == signatureType.isMarkedNullable) { renderCompilerError(expression) } } generateCFunctionPointer(target as IrSimpleFunction, expression) } IntrinsicType.INTEROP_FUNPTR_INVOKE -> { generateWithStubs { generateCCall(expression, builder, isInvoke = true) } } IntrinsicType.INTEROP_SIGN_EXTEND, IntrinsicType.INTEROP_NARROW -> { val integerTypePredicates = arrayOf( IrType::isByte, IrType::isShort, IrType::isInt, IrType::isLong ) val receiver = expression.extensionReceiver!! val typeOperand = expression.getSingleTypeArgument() val receiverTypeIndex = integerTypePredicates.indexOfFirst { it(receiver.type) } val typeOperandIndex = integerTypePredicates.indexOfFirst { it(typeOperand) } require(receiverTypeIndex >= 0) { renderCompilerError(receiver) } require(typeOperandIndex >= 0) { renderCompilerError(expression) } when (intrinsicType) { IntrinsicType.INTEROP_SIGN_EXTEND -> require(receiverTypeIndex <= typeOperandIndex) { renderCompilerError(expression) } IntrinsicType.INTEROP_NARROW -> require(receiverTypeIndex >= typeOperandIndex) { renderCompilerError(expression) } else -> error(intrinsicType) } val receiverClass = symbols.integerClasses.single { receiver.type.isSubtypeOf(it.owner.defaultType) } val targetClass = symbols.integerClasses.single { typeOperand.isSubtypeOf(it.owner.defaultType) } val conversionSymbol = receiverClass.functions.single { it.owner.name == Name.identifier("to${targetClass.owner.name}") } builder.irCall(conversionSymbol).apply { dispatchReceiver = receiver } } IntrinsicType.INTEROP_CONVERT -> { val integerClasses = symbols.allIntegerClasses val typeOperand = expression.getTypeArgument(0)!! val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type val source = receiverType.classifierOrFail as IrClassSymbol require(source in integerClasses) { renderCompilerError(expression) } require(typeOperand is IrSimpleType && typeOperand.classifier in integerClasses && !typeOperand.hasQuestionMark) { renderCompilerError(expression) } val target = typeOperand.classifier as IrClassSymbol val valueToConvert = expression.extensionReceiver!! if (source in symbols.signedIntegerClasses && target in symbols.unsignedIntegerClasses) { // Default Kotlin signed-to-unsigned widening integer conversions don't follow C rules. val signedTarget = symbols.unsignedToSignedOfSameBitWidth[target]!! val widened = builder.irConvertInteger(source, signedTarget, valueToConvert) builder.irConvertInteger(signedTarget, target, widened) } else { builder.irConvertInteger(source, target, valueToConvert) } } IntrinsicType.INTEROP_MEMORY_COPY -> { TODO("So far unsupported") } IntrinsicType.WORKER_EXECUTE -> { val irCallableReference = unwrapStaticFunctionArgument(expression.getValueArgument(2)!!) require(irCallableReference != null && irCallableReference.getArguments().isEmpty()) { renderCompilerError(expression) } val targetSymbol = irCallableReference.symbol val jobPointer = IrFunctionReferenceImpl.fromSymbolDescriptor( builder.startOffset, builder.endOffset, symbols.executeImpl.owner.valueParameters[3].type, targetSymbol, typeArgumentsCount = 0, reflectionTarget = null) builder.irCall(symbols.executeImpl).apply { putValueArgument(0, expression.dispatchReceiver) putValueArgument(1, expression.getValueArgument(0)) putValueArgument(2, expression.getValueArgument(1)) putValueArgument(3, jobPointer) } } else -> expression } } return when (function) { symbols.interopCPointerRawValue.owner.getter -> // Replace by the intrinsic call to be handled by code generator: builder.irCall(symbols.interopCPointerGetRawValue).apply { extensionReceiver = expression.dispatchReceiver } else -> expression } } private fun IrBuilderWithScope.irConvertInteger( source: IrClassSymbol, target: IrClassSymbol, value: IrExpression ): IrExpression { val conversion = symbols.integerConversions[source to target]!! return irCall(conversion.owner).apply { if (conversion.owner.dispatchReceiverParameter != null) { dispatchReceiver = value } else { extensionReceiver = value } } } private fun unwrapStaticFunctionArgument(argument: IrExpression): IrFunctionReference? { if (argument is IrFunctionReference) { return argument } // Otherwise check whether it is a lambda: // 1. It is a container with two statements and expected origin: if (argument !is IrContainerExpression || argument.statements.size != 2) { return null } if (argument.origin != IrStatementOrigin.LAMBDA && argument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION) { return null } // 2. First statement is an empty container (created during local functions lowering): val firstStatement = argument.statements.first() if (firstStatement !is IrContainerExpression || firstStatement.statements.size != 0) { return null } // 3. Second statement is IrCallableReference: return argument.statements.last() as? IrFunctionReference } val IrValueParameter.isDispatchReceiver: Boolean get() = when(val parent = this.parent) { is IrClass -> true is IrFunction -> parent.dispatchReceiverParameter == this else -> false } private fun IrValueDeclaration.isDispatchReceiverFor(irClass: IrClass): Boolean = this is IrValueParameter && isDispatchReceiver && type.getClass() == irClass } private fun IrCall.getSingleTypeArgument(): IrType { val typeParameter = symbol.owner.typeParameters.single() return getTypeArgument(typeParameter.index)!! } private fun IrBuilder.irFloat(value: Float) = IrConstImpl.float(startOffset, endOffset, context.irBuiltIns.floatType, value) private fun IrBuilder.irDouble(value: Double) = IrConstImpl.double(startOffset, endOffset, context.irBuiltIns.doubleType, value) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/KonanDefaultArgumentStubGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.IrExpression internal class KonanDefaultArgumentStubGenerator(override val context: Context) : DefaultArgumentStubGenerator(context, skipInlineMethods = false) { override fun IrBlockBodyBuilder.selectArgumentOrDefault( defaultFlag: IrExpression, parameter: IrValueParameter, default: IrExpression ): IrValueDeclaration { val value = irIfThenElse(parameter.type, irNotEquals(defaultFlag, irInt(0)), default, irGet(parameter)) return createTmpVariable(value, nameHint = parameter.name.asString()) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/KonanDefaultParameterInjector.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.lower.DefaultParameterInjector import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.irCall internal class KonanDefaultParameterInjector(private val konanContext: KonanBackendContext) : DefaultParameterInjector(konanContext, skipInline = false) { override fun nullConst(startOffset: Int, endOffset: Int, type: IrType): IrExpression { val symbols = konanContext.ir.symbols val nullConstOfEquivalentType = when (type.computePrimitiveBinaryTypeOrNull()) { null -> IrConstImpl.constNull(startOffset, endOffset, context.irBuiltIns.nothingNType) PrimitiveBinaryType.BOOLEAN -> IrConstImpl.boolean(startOffset, endOffset, type, false) PrimitiveBinaryType.BYTE -> IrConstImpl.byte(startOffset, endOffset, type, 0) PrimitiveBinaryType.SHORT -> when (type.getInlinedClassNative()) { context.irBuiltIns.char -> IrConstImpl.char(startOffset, endOffset, type, 0.toChar()) else -> IrConstImpl.short(startOffset, endOffset, type, 0) } PrimitiveBinaryType.INT -> IrConstImpl.int(startOffset, endOffset, type, 0) PrimitiveBinaryType.LONG -> IrConstImpl.long(startOffset, endOffset, type, 0) PrimitiveBinaryType.FLOAT -> IrConstImpl.float(startOffset, endOffset, type, 0.0F) PrimitiveBinaryType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, type, 0.0) PrimitiveBinaryType.POINTER -> irCall(startOffset, endOffset, symbols.getNativeNullPtr.owner, emptyList()) PrimitiveBinaryType.VECTOR128 -> TODO() } return irCall( startOffset, endOffset, symbols.reinterpret.owner, listOf(nullConstOfEquivalentType.type, type) ).apply { extensionReceiver = nullConstOfEquivalentType } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.inline.DefaultInlineFunctionResolver import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesExtractionFromInlineFunctionsLowering import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunctionsLowering import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.fileOrNull import org.jetbrains.kotlin.ir.util.getPackageFragment // TODO: This is a bit hacky. Think about adopting persistent IR ideas. internal class NativeInlineFunctionResolver(override val context: Context) : DefaultInlineFunctionResolver(context) { override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { val function = super.getFunctionDeclaration(symbol) val body = function.body ?: return function if (function in context.specialDeclarationsFactory.loweredInlineFunctions) return function context.specialDeclarationsFactory.loweredInlineFunctions.add(function) PreInlineLowering(context).lower(body, function) ArrayConstructorLowering(context).lower(body, function) NullableFieldsForLateinitCreationLowering(context).lowerWithLocalDeclarations(function) NullableFieldsDeclarationLowering(context).lowerWithLocalDeclarations(function) LateinitUsageLowering(context).lower(body, function) SharedVariablesLowering(context).lower(body, function) LocalClassesInInlineLambdasLowering(context).lower(body, function) if (context.llvmModuleSpecification.containsPackageFragment(function.getPackageFragment()!!)) { // Do not extract local classes off of inline functions from cached libraries. LocalClassesInInlineFunctionsLowering(context).lower(body, function) LocalClassesExtractionFromInlineFunctionsLowering(context).lower(body, function) } return function } private fun DeclarationTransformer.lowerWithLocalDeclarations(function: IrFunction) { if (transformFlat(function) != null) error("Unexpected transformation of function ${function.dump()}") } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSingleAbstractMethodLowering.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ScopeWithIr import org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.render internal class NativeSingleAbstractMethodLowering(context: Context) : SingleAbstractMethodLowering(context) { override fun getWrapperVisibility(expression: IrTypeOperatorCall, scopes: List) = DescriptorVisibilities.PRIVATE override fun getSuperTypeForWrapper(typeOperand: IrType): IrType { return typeOperand.classOrNull?.defaultType ?: error("Unsupported SAM conversion: ${typeOperand.render()}") } override val IrType.needEqualsHashCodeMethods get() = true } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeSuspendFunctionLowering.kt ================================================ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.ir.isSuspend import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSuspendableExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSuspensionPointImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name internal class NativeSuspendFunctionsLowering(ctx: Context): AbstractSuspendFunctionsLowering(ctx) { private val symbols = context.ir.symbols override val stateMachineMethodName = Name.identifier("invokeSuspend") override fun getCoroutineBaseClass(function: IrFunction): IrClassSymbol = (if (function.isRestrictedSuspendFunction(context.irBuiltIns.languageVersionSettings)) { symbols.restrictedContinuationImpl } else { symbols.continuationImpl }) override fun nameForCoroutineClass(function: IrFunction) = "${function.name}COROUTINE\$${context.coroutineCount++}".synthesizedName override fun initializeStateMachine(coroutineConstructors: List, coroutineClassThis: IrValueDeclaration) { // Nothing to do: it's redundant to initialize the "label" field with null // since all freshly allocated objects are zeroed out. } override fun IrBlockBodyBuilder.generateCoroutineStart(invokeSuspendFunction: IrFunction, receiver: IrExpression) { +irReturn( irCall(invokeSuspendFunction).apply { dispatchReceiver = receiver putValueArgument(0, irSuccess(irGetObject(symbols.unit))) } ) } override fun buildStateMachine(stateMachineFunction: IrFunction, transformingFunction: IrFunction, argumentToPropertiesMap: Map) { val originalBody = transformingFunction.body!! val resultArgument = stateMachineFunction.valueParameters.single() val coroutineClass = stateMachineFunction.parentAsClass val labelField = coroutineClass.addField(Name.identifier("label"), symbols.nativePtrType, true) val startOffset = transformingFunction.startOffset val endOffset = transformingFunction.endOffset val irBuilder = context.createIrBuilder(stateMachineFunction.symbol, startOffset, endOffset) stateMachineFunction.body = irBuilder.irBlockBody(startOffset, endOffset) { val suspendResult = irVar("suspendResult".synthesizedName, context.irBuiltIns.anyNType, true) // Extract all suspend calls to temporaries in order to make correct jumps to them. originalBody.transformChildrenVoid(ExpressionSlicer(labelField.type, transformingFunction, saveState, restoreState, suspendResult, resultArgument)) val liveLocals = computeLivenessAtSuspensionPoints(originalBody) val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.isVar }.toSet() val localsMap = immutableLiveLocals.associate { it to irVar(it.name, it.type, true) } if (localsMap.isNotEmpty()) transformVariables(originalBody, localsMap) // Make variables mutable in order to save/restore them. val localToPropertyMap = mutableMapOf() // TODO: optimize by using the same property for different locals. liveLocals.values.forEach { scope -> scope.forEach { localToPropertyMap.getOrPut(it.symbol) { coroutineClass.addField(it.name, it.type, true) } } } originalBody.transformChildrenVoid(object : IrElementTransformerVoid() { private val thisReceiver = stateMachineFunction.dispatchReceiverParameter!! // Replace returns to refer to the new function. override fun visitReturn(expression: IrReturn): IrExpression { expression.transformChildrenVoid(this) return if (expression.returnTargetSymbol != transformingFunction.symbol) expression else irReturn(expression.value) } // Replace function arguments loading with properties reading. override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid(this) val capturedValue = argumentToPropertiesMap[expression.symbol.owner] ?: return expression return irGetField(irGet(thisReceiver), capturedValue) } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid(this) val capturedValue = argumentToPropertiesMap[expression.symbol.owner] ?: return expression return irSetField(irGet(thisReceiver), capturedValue, expression.value) } // Save/restore state at suspension points. override fun visitExpression(expression: IrExpression): IrExpression { expression.transformChildrenVoid(this) val suspensionPoint = expression as? IrSuspensionPoint ?: return expression suspensionPoint.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) when (expression.symbol) { saveState.symbol -> { val scope = liveLocals[suspensionPoint]!! return irBlock(expression) { scope.forEach { val variable = localsMap[it] ?: it +irSetField(irGet(thisReceiver), localToPropertyMap[it.symbol]!!, irGet(variable)) } +irSetField( irGet(thisReceiver), labelField, irGet(suspensionPoint.suspensionPointIdParameter) ) } } restoreState.symbol -> { val scope = liveLocals[suspensionPoint]!! return irBlock(expression) { scope.forEach { +irSetVar(localsMap[it] ?: it, irGetField(irGet(thisReceiver), localToPropertyMap[it.symbol]!!)) } } } } return expression } }) return suspensionPoint } }) originalBody.setDeclarationsParent(stateMachineFunction) val statements = (originalBody as IrBlockBody).statements +suspendResult +IrSuspendableExpressionImpl( startOffset, endOffset, context.irBuiltIns.unitType, suspensionPointId = irGetField(irGet(stateMachineFunction.dispatchReceiverParameter!!), labelField), result = irBlock(startOffset, endOffset) { +irThrowIfNotNull(irExceptionOrNull(irGet(resultArgument))) // Coroutine might start with an exception. statements.forEach { +it } }) if (transformingFunction.returnType.isUnit()) +irReturn(irGetObject(symbols.unit)) // Insert explicit return for Unit functions. } } private var tempIndex = 0 private var suspensionPointIdIndex = 0 private fun transformVariables(element: IrElement, variablesMap: Map) { element.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { expression.transformChildrenVoid(this) val newVariable = variablesMap[expression.symbol.owner] ?: return expression return IrGetValueImpl( startOffset = expression.startOffset, endOffset = expression.endOffset, type = newVariable.type, symbol = newVariable.symbol, origin = expression.origin) } override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid(this) val newVariable = variablesMap[expression.symbol.owner] ?: return expression return IrSetValueImpl( startOffset = expression.startOffset, endOffset = expression.endOffset, type = context.irBuiltIns.unitType, symbol = newVariable.symbol, value = expression.value, origin = expression.origin) } override fun visitVariable(declaration: IrVariable): IrStatement { declaration.transformChildrenVoid(this) val newVariable = variablesMap[declaration] ?: return declaration newVariable.initializer = declaration.initializer return newVariable } }) } private fun computeLivenessAtSuspensionPoints(body: IrBody): Map> { // TODO: data flow analysis. // Just save all visible for now. val result = mutableMapOf>() body.acceptChildrenVoid(object: VariablesScopeTracker() { override fun visitExpression(expression: IrExpression) { val suspensionPoint = expression as? IrSuspensionPoint if (suspensionPoint == null) { super.visitExpression(expression) return } suspensionPoint.result.acceptChildrenVoid(this) suspensionPoint.resumeResult.acceptChildrenVoid(this) val visibleVariables = mutableListOf() scopeStack.forEach { visibleVariables += it } result[suspensionPoint] = visibleVariables } }) return result } private inner class ExpressionSlicer(val suspensionPointIdType: IrType, val irFunction: IrFunction, val saveState: IrFunction, val restoreState: IrFunction, val suspendResult: IrVariable, val resultArgument: IrValueParameter): IrElementTransformerVoid() { // TODO: optimize - it has square complexity. override fun visitSetField(expression: IrSetField): IrExpression { expression.transformChildrenVoid(this) return sliceExpression(expression) } override fun visitMemberAccess(expression: IrMemberAccessExpression<*>): IrExpression { expression.transformChildrenVoid(this) return sliceExpression(expression) } private fun sliceExpression(expression: IrExpression): IrExpression { val irBuilder = context.createIrBuilder(irFunction.symbol, expression.startOffset, expression.endOffset) irBuilder.run { val children = when (expression) { is IrSetField -> listOf(expression.receiver, expression.value) is IrMemberAccessExpression<*> -> ( listOf(expression.dispatchReceiver, expression.extensionReceiver) + (0 until expression.valueArgumentsCount).map { expression.getValueArgument(it) } ) else -> throw Error("Unexpected expression: $expression") } val numberOfChildren = children.size val hasSuspendCallInTail = BooleanArray(numberOfChildren + 1) for (i in numberOfChildren - 1 downTo 0) hasSuspendCallInTail[i] = hasSuspendCallInTail[i + 1] || children[i].let { it != null && it.hasSuspendCalls() } val newChildren = arrayOfNulls(numberOfChildren) val tempStatements = mutableListOf() var first = true for ((index, child) in children.withIndex()) { if (child == null) continue val transformedChild = if (!child.isSpecialBlock()) child else { val statements = (child as IrBlock).statements tempStatements += statements.take(statements.size - 1) statements.last() as IrExpression } if (first && !hasSuspendCallInTail[index + 1]) { // Don't extract suspend call to a temporary if it is the first argument and is the only suspend call. newChildren[index] = transformedChild first = false continue } first = false if (transformedChild.isPure() || !hasSuspendCallInTail[index]) newChildren[index] = transformedChild else { // Save to temporary in order to save execution order. val tmp = irVar(transformedChild) tempStatements += tmp newChildren[index] = irGet(tmp) } } var calledSaveState = false var suspendCall: IrExpression? = null when { expression.isReturnIfSuspendedCall -> { calledSaveState = true val firstArgument = newChildren[2]!! newChildren[2] = irBlock(firstArgument) { +irCall(saveState) +firstArgument } suspendCall = newChildren[2] } expression.isSuspendCall -> { val lastChildIndex = newChildren.indexOfLast { it != null } if (lastChildIndex != -1) { // Save state as late as possible. val lastChild = newChildren[lastChildIndex]!! calledSaveState = true newChildren[lastChildIndex] = irBlock(lastChild) { if (lastChild.isPure()) { +irCall(saveState) +lastChild } else { val tmp = irVar(lastChild) +tmp +irCall(saveState) +irGet(tmp) } } } suspendCall = expression } } when (expression) { is IrSetField -> { expression.receiver = newChildren[0] expression.value = newChildren[1]!! } is IrMemberAccessExpression<*> -> { expression.dispatchReceiver = newChildren[0] expression.extensionReceiver = newChildren[1] newChildren.drop(2).forEachIndexed { index, newChild -> expression.putValueArgument(index, newChild) } } } if (suspendCall == null) return irWrap(expression, tempStatements) val suspensionPoint = IrSuspensionPointImpl( startOffset = startOffset, endOffset = endOffset, type = context.irBuiltIns.anyNType, suspensionPointIdParameter = irVar( "suspensionPointId${suspensionPointIdIndex++}".synthesizedName, suspensionPointIdType ), result = irBlock(startOffset, endOffset) { if (!calledSaveState) +irCall(saveState) +irSet(suspendResult.symbol, suspendCall) +irReturnIfSuspended(suspendResult) +irGet(suspendResult) }, resumeResult = irBlock(startOffset, endOffset) { +irCall(restoreState) +irGetOrThrow(irGet(resultArgument)) }) val expressionResult = when { suspendCall.type.isUnit() -> irImplicitCoercionToUnit(suspensionPoint) else -> irAs(suspensionPoint, suspendCall.type) } return irBlock(expression) { tempStatements.forEach { +it } +expressionResult } } } } private fun IrBuilderWithScope.irWrap(expression: IrExpression, tempStatements: List) = if (tempStatements.isEmpty()) expression else irBlock(expression, STATEMENT_ORIGIN_COROUTINE_IMPL) { tempStatements.forEach { +it } +expression } private fun IrBuilderWithScope.irThrowIfNotNull(exception: IrExpression) = irLetS(exception) { irThrowIfNotNull(it.owner) } fun IrBuilderWithScope.irThrowIfNotNull(exception: IrValueDeclaration) = irIfThen(irNot(irEqeqeq(irGet(exception), irNull())), irThrow(irImplicitCast(irGet(exception), exception.type.makeNotNull()))) private val IrExpression.isSuspendCall: Boolean get() = this is IrCall && this.isSuspend private fun IrElement.isSpecialBlock() = this is IrBlock && this.origin == STATEMENT_ORIGIN_COROUTINE_IMPL private fun IrElement.hasSuspendCalls(): Boolean { var hasSuspendCalls = false acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitCall(expression: IrCall) { expression.acceptChildrenVoid(this) hasSuspendCalls = hasSuspendCalls || expression.isSuspendCall } override fun visitExpression(expression: IrExpression) { expression.acceptChildrenVoid(this) hasSuspendCalls = hasSuspendCalls || expression is IrSuspensionPointImpl } }) return hasSuspendCalls } private val IrExpression.isReturnIfSuspendedCall: Boolean get() = this is IrCall && isReturnIfSuspendedCall() private fun IrBuilderWithScope.irVar(initializer: IrExpression) = irVar("tmp${tempIndex++}".synthesizedName, initializer.type, false, initializer) private fun IrBuilderWithScope.irReturnIfSuspended(value: IrValueDeclaration) = irIfThen(irEqeqeq(irGet(value), irCall(symbols.coroutineSuspendedGetter)), irReturn(irGet(value))) private fun IrExpression.isPure(): Boolean { return when (this) { is IrConst<*> -> true is IrCall -> false // TODO: skip builtin operators. is IrTypeOperatorCall -> this.argument.isPure() && this.operator != IrTypeOperator.CAST is IrGetValue -> !this.symbol.owner.let { it is IrVariable && it.isVar } else -> false } } // These are marker functions to split up the lowering on two parts. private val saveState = IrFunctionImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), "saveState".synthesizedName, DescriptorVisibilities.PRIVATE, Modality.ABSTRACT, context.irBuiltIns.unitType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) private val restoreState = IrFunctionImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(), "restoreState".synthesizedName, DescriptorVisibilities.PRIVATE, Modality.ABSTRACT, context.irBuiltIns.unitType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ) private fun IrBuilderWithScope.irVar(name: Name, type: IrType, isMutable: Boolean = false, initializer: IrExpression? = null) = IrVariableImpl( startOffset, endOffset, DECLARATION_ORIGIN_COROUTINE_IMPL, IrVariableSymbolImpl(), name, type, isMutable, isConst = false, isLateinit = false ).apply { this.initializer = initializer this.parent = this@irVar.parent } private fun IrBuilderWithScope.irGetOrThrow(result: IrExpression): IrExpression = irCall(symbols.kotlinResultGetOrThrow.owner).apply { extensionReceiver = result } // TODO: consider inlining getOrThrow function body here. private fun IrBuilderWithScope.irExceptionOrNull(result: IrExpression): IrExpression { val resultClass = symbols.kotlinResult.owner val exceptionOrNull = resultClass.simpleFunctions().single { it.name.asString() == "exceptionOrNull" } return irCall(exceptionOrNull).apply { dispatchReceiver = result } } fun IrBlockBodyBuilder.irSuccess(value: IrExpression): IrMemberAccessExpression<*> { val createResult = symbols.kotlinResult.owner.constructors.single { it.isPrimary } return irCall(createResult).apply { putValueArgument(0, value) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/PostInlineLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.renderCompilerError import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.visitors.IrElementTransformer /** * This pass runs after inlining and performs the following additional transformations over some operations: * - Convert immutableBlobOf() arguments to special IrConst. * - Convert `obj::class` and `Class::class` to calls. */ internal class PostInlineLowering(val context: Context) : BodyLoweringPass { private val symbols get() = context.ir.symbols override fun lower(irBody: IrBody, container: IrDeclaration) { val irFile = container.file irBody.transformChildren(object : IrElementTransformer { override fun visitDeclaration(declaration: IrDeclarationBase, data: IrBuilderWithScope) = super.visitDeclaration(declaration, data = (declaration as? IrSymbolOwner)?.let { context.createIrBuilder(it.symbol, it.startOffset, it.endOffset) } ?: data ) override fun visitClassReference(expression: IrClassReference, data: IrBuilderWithScope): IrExpression { expression.transformChildren(this, data) return data.at(expression).run { (expression.symbol as? IrClassSymbol)?.let { irKClass(this@PostInlineLowering.context, it) } ?: // E.g. for `T::class` in a body of an inline function itself. irCall(symbols.throwNullPointerException.owner) } } override fun visitGetClass(expression: IrGetClass, data: IrBuilderWithScope): IrExpression { expression.transformChildren(this, data) return data.at(expression).run { irCall(symbols.kClassImplConstructor, listOf(expression.argument.type)).apply { val typeInfo = irCall(symbols.getObjectTypeInfo).apply { putValueArgument(0, expression.argument) } putValueArgument(0, typeInfo) } } } override fun visitCall(expression: IrCall, data: IrBuilderWithScope): IrExpression { expression.transformChildren(this, data) // Function inlining is changing function symbol at callsite // and unbound symbol replacement is happening later. // So we compare descriptors for now. if (expression.symbol == symbols.immutableBlobOf) { // Convert arguments of the binary blob to special IrConst structure, so that // vararg lowering will not affect it. val args = expression.getValueArgument(0) as? IrVararg ?: error("varargs shall not be lowered yet") val builder = StringBuilder() args.elements.forEach { require(it is IrConst<*>) { renderCompilerError(irFile, it, "expected const") } val value = (it as? IrConst<*>)?.value require(value is Short && value >= 0 && value <= 0xff) { renderCompilerError(irFile, it, "incorrect value for binary data: $value") } // Luckily, all values in range 0x00 .. 0xff represent valid UTF-16 symbols, // block 0 (Basic Latin) and block 1 (Latin-1 Supplement) in // Basic Multilingual Plane, so we could just append data "as is". builder.append(value.toChar()) } expression.putValueArgument(0, IrConstImpl( expression.startOffset, expression.endOffset, context.irBuiltIns.stringType, IrConstKind.String, builder.toString())) } else if (Symbols.isTypeOfIntrinsic(expression.symbol)) { // Inline functions themselves are not called (they have been inlined at all call sites), // so it is ok not to build exact type parameters for them. val needExactTypeParameters = (container as? IrSimpleFunction)?.isInline != true return with (KTypeGenerator(context, irFile, expression, needExactTypeParameters)) { data.at(expression).irKType(expression.getTypeArgument(0)!!, leaveReifiedForLater = false) } } return expression } }, data = context.createIrBuilder((container as IrSymbolOwner).symbol, irBody.startOffset, irBody.endOffset)) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/PreInlineLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.visitors.IrElementTransformer /** * This pass runs before inlining and performs the following additional transformations over some operations: * - Assertion call removal. * - First phase of typeOf intrinsic lowering. */ internal class PreInlineLowering(val context: Context) : BodyLoweringPass { private val symbols get() = context.ir.symbols private val asserts = symbols.asserts private val enableAssertions = context.config.configuration.getBoolean(KonanConfigKeys.ENABLE_ASSERTIONS) override fun lower(irBody: IrBody, container: IrDeclaration) { irBody.transformChildren(object : IrElementTransformer { override fun visitDeclaration(declaration: IrDeclarationBase, data: IrBuilderWithScope) = super.visitDeclaration(declaration, data = (declaration as? IrSymbolOwner)?.let { context.createIrBuilder(it.symbol, it.startOffset, it.endOffset) } ?: data ) override fun visitCall(expression: IrCall, data: IrBuilderWithScope): IrExpression { expression.transformChildren(this, data) return when { !enableAssertions && expression.symbol in asserts -> { // Replace assert() call with an empty composite if assertions are not enabled. require(expression.type.isUnit()) IrCompositeImpl(expression.startOffset, expression.endOffset, expression.type) } Symbols.isTypeOfIntrinsic(expression.symbol) -> { with (KTypeGenerator(context, container.file, expression, needExactTypeParameters = true)) { data.at(expression).irKType(expression.getTypeArgument(0)!!, leaveReifiedForLater = true) } } else -> expression } } }, data = context.createIrBuilder((container as IrSymbolOwner).symbol, irBody.startOffset, irBody.endOffset)) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/RedundantCoercionsCleaner.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION import org.jetbrains.kotlin.backend.konan.getInlinedClassNative import org.jetbrains.kotlin.backend.konan.ir.isBoxOrUnboxCall import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal class RedundantCoercionsCleaner(val context: Context) : FileLoweringPass, IrElementTransformerVoid() { private class PossiblyFoldedExpression(val expression: IrExpression, val folded: Boolean) { fun getFullExpression(coercion: IrCall, cast: IrTypeOperatorCall?): IrExpression { if (folded) return expression require (coercion.dispatchReceiver == null && coercion.extensionReceiver == null) { "Expected either or function without any receivers" } val castedExpression = if (cast == null) expression else with (cast) { IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeOperand, expression) } with (coercion) { return IrCallImpl(startOffset, endOffset, type, symbol, typeArgumentsCount, symbol.owner.valueParameters.size, origin).apply { putValueArgument(0, castedExpression) } } } } private val returnableBlockValues = mutableMapOf>() private fun computeReturnableBlockValues(irFile: IrFile) { irFile.acceptChildrenVoid(object: IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitContainerExpression(expression: IrContainerExpression) { if (expression is IrReturnableBlock) returnableBlockValues[expression] = mutableListOf() super.visitContainerExpression(expression) } override fun visitReturn(expression: IrReturn) { val returnableBlock = expression.returnTargetSymbol.owner as? IrReturnableBlock if (returnableBlock != null) returnableBlockValues[returnableBlock]!!.add(expression.value) super.visitReturn(expression) } }) } override fun lower(irFile: IrFile) { computeReturnableBlockValues(irFile) irFile.transformChildrenVoid(this) } override fun visitCall(expression: IrCall): IrExpression { if (!expression.isBoxOrUnboxCall()) return super.visitCall(expression) val argument = expression.getArguments().single().second val foldedArgument = fold( expression = argument, coercion = expression, cast = null, transformRecursively = true) return foldedArgument.getFullExpression(expression, null) } private fun IrFunction.getCoercedClass(): IrClass { if (name.asString().endsWith("-box>")) return valueParameters[0].type.classifierOrFail.owner as IrClass if (name.asString().endsWith("-unbox>")) return returnType.classifierOrFail.owner as IrClass error("Unexpected coercion: ${this.dump()}") } private fun IrExpression.unwrapImplicitCasts(): IrExpression { var expression = this while (expression is IrTypeOperatorCall && expression.operator == IrTypeOperator.IMPLICIT_CAST) expression = expression.argument return expression } /** * TODO: JVM inliner crashed on attempt inline this function from transform.kt with: * j.l.IllegalStateException: Couldn't obtain compiled function body for * public inline fun kotlin.collections.MutableList.transform... */ private inline fun MutableList.transform(transformation: (T) -> IrElement) { forEachIndexed { i, item -> set(i, transformation(item) as T) } } private fun fold(expression: IrExpression, coercion: IrCall, cast: IrTypeOperatorCall?, transformRecursively: Boolean): PossiblyFoldedExpression { val transformer = this fun IrExpression.transformIfAsked() = if (transformRecursively) this.transform(transformer, data = null) else this fun IrElement.transformIfAsked() = if (transformRecursively) this.transform(transformer, data = null) else this val coercionDeclaringClass = coercion.symbol.owner.getCoercedClass() expression.unwrapImplicitCasts().let { if (it.isBoxOrUnboxCall()) { val result = if (coercionDeclaringClass == (it as IrCall).symbol.owner.getCoercedClass()) it.getArguments().single().second else expression return PossiblyFoldedExpression(result.transformIfAsked(), result != expression) } } return when (expression) { is IrReturnableBlock -> { val foldedReturnableBlockValues = returnableBlockValues[expression]!!.associate { it to fold(it, coercion, cast, false) } val someoneFolded = foldedReturnableBlockValues.any { it.value.folded } val transformedReturnableBlock = if (!someoneFolded) expression else { val oldSymbol = expression.symbol val newSymbol = IrReturnableBlockSymbolImpl() val transformedReturnableBlock = with(expression) { IrReturnableBlockImpl( startOffset = startOffset, endOffset = endOffset, type = coercion.type, symbol = newSymbol, origin = origin, statements = statements, inlineFunctionSymbol = inlineFunctionSymbol) } transformedReturnableBlock.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitExpression(expression: IrExpression): IrExpression { foldedReturnableBlockValues[expression]?.let { return it.getFullExpression(coercion, cast) } return super.visitExpression(expression) } override fun visitReturn(expression: IrReturn): IrExpression { expression.transformChildrenVoid(this) return if (expression.returnTargetSymbol != oldSymbol) expression else with(expression) { IrReturnImpl( startOffset = startOffset, endOffset = endOffset, type = context.irBuiltIns.nothingType, returnTargetSymbol = newSymbol, value = value) } } }) transformedReturnableBlock } if (transformRecursively) transformedReturnableBlock.transformChildrenVoid(this) PossiblyFoldedExpression(transformedReturnableBlock, someoneFolded) } is IrBlock -> { val statements = expression.statements if (statements.isEmpty()) PossiblyFoldedExpression(expression, false) else { val lastStatement = statements.last() as IrExpression val foldedLastStatement = fold(lastStatement, coercion, cast, transformRecursively) statements.transform { if (it == lastStatement) foldedLastStatement.expression else it.transformIfAsked() } val transformedBlock = if (!foldedLastStatement.folded) expression else with(expression) { IrBlockImpl( startOffset = startOffset, endOffset = endOffset, type = coercion.type, origin = origin, statements = statements) } PossiblyFoldedExpression(transformedBlock, foldedLastStatement.folded) } } is IrWhen -> { val foldedBranches = expression.branches.map { fold(it.result, coercion, cast, transformRecursively) } val someoneFolded = foldedBranches.any { it.folded } val transformedWhen = with(expression) { IrWhenImpl(startOffset, endOffset, if (someoneFolded) coercion.type else type, origin, branches.asSequence().withIndex().map { (index, branch) -> IrBranchImpl( startOffset = branch.startOffset, endOffset = branch.endOffset, condition = branch.condition.transformIfAsked(), result = if (someoneFolded) foldedBranches[index].getFullExpression(coercion, cast) else foldedBranches[index].expression) }.toList()) } return PossiblyFoldedExpression(transformedWhen, someoneFolded) } is IrTypeOperatorCall -> if (expression.operator != IrTypeOperator.CAST && expression.operator != IrTypeOperator.IMPLICIT_CAST && expression.operator != IrTypeOperator.SAFE_CAST) PossiblyFoldedExpression(expression.transformIfAsked(), false) else { if (expression.typeOperand.getInlinedClassNative() != coercionDeclaringClass) PossiblyFoldedExpression(expression.transformIfAsked(), false) else { val foldedArgument = fold(expression.argument, coercion, expression, transformRecursively) if (foldedArgument.folded) foldedArgument else PossiblyFoldedExpression(expression.apply { argument = foldedArgument.expression }, false) } } else -> PossiblyFoldedExpression(expression.transformIfAsked(), false) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReflectionSupport.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.konan.InteropFqNames import org.jetbrains.kotlin.backend.konan.KonanBackendContext import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections import org.jetbrains.kotlin.backend.konan.ir.typeWithoutArguments import org.jetbrains.kotlin.backend.konan.isObjCClass import org.jetbrains.kotlin.backend.konan.llvm.computeFullName import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers import org.jetbrains.kotlin.types.Variance internal class KTypeGenerator( val context: KonanBackendContext, val irFile: IrFile, val irElement: IrElement, val needExactTypeParameters: Boolean = false ) { private val symbols = context.ir.symbols fun IrBuilderWithScope.irKType(type: IrType, leaveReifiedForLater: Boolean = false) = irKType(type, leaveReifiedForLater, mutableSetOf()) private class RecursiveBoundsException(message: String) : Throwable(message) private fun IrBuilderWithScope.irKType( type: IrType, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ): IrExpression { if (type !is IrSimpleType) { // Represent as non-denotable type: return irKTypeImpl( kClassifier = irNull(), irTypeArguments = emptyList(), isMarkedNullable = false, leaveReifiedForLater = leaveReifiedForLater, seenTypeParameters = seenTypeParameters ) } try { val kClassifier = when (val classifier = type.classifier) { is IrClassSymbol -> irKClass(classifier) is IrTypeParameterSymbol -> { if (classifier.owner.isReified && leaveReifiedForLater) { // Leave as is for reification. return irCall(symbols.typeOf).apply { putTypeArgument(0, type) } } // Leave upper bounds of non-reified type parameters as is, even if they are reified themselves. irKTypeParameter(classifier.owner, leaveReifiedForLater = false, seenTypeParameters = seenTypeParameters) } else -> TODO("Unexpected classifier: $classifier") } return irKTypeImpl( kClassifier = kClassifier, irTypeArguments = type.arguments, isMarkedNullable = type.hasQuestionMark, leaveReifiedForLater = leaveReifiedForLater, seenTypeParameters = seenTypeParameters ) } catch (t: RecursiveBoundsException) { if (needExactTypeParameters) this@KTypeGenerator.context.reportCompilationError(t.message!!, irFile, irElement) return irCall(symbols.kTypeImplForTypeParametersWithRecursiveBounds.constructors.single()) } } private fun IrBuilderWithScope.irKTypeImpl( kClassifier: IrExpression, irTypeArguments: List, isMarkedNullable: Boolean, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ): IrExpression = irCall(symbols.kTypeImpl.constructors.single()).apply { putValueArgument(0, kClassifier) putValueArgument(1, irKTypeProjectionsList(irTypeArguments, leaveReifiedForLater, seenTypeParameters)) putValueArgument(2, irBoolean(isMarkedNullable)) } private fun IrBuilderWithScope.irKClass(symbol: IrClassSymbol) = irKClass(this@KTypeGenerator.context, symbol) private fun IrBuilderWithScope.irKTypeParameter( typeParameter: IrTypeParameter, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ): IrMemberAccessExpression<*> { if (!seenTypeParameters.add(typeParameter)) throw RecursiveBoundsException("Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.render()}") val result = irCall(symbols.kTypeParameterImpl.constructors.single()).apply { putValueArgument(0, irString(typeParameter.name.asString())) putValueArgument(1, irString(typeParameter.parentUniqueName)) putValueArgument(2, irKTypeList(typeParameter.superTypes, leaveReifiedForLater, seenTypeParameters)) putValueArgument(3, irKVariance(typeParameter.variance)) putValueArgument(4, irBoolean(typeParameter.isReified)) } seenTypeParameters.remove(typeParameter) return result } private val IrTypeParameter.parentUniqueName get() = when (val parent = parent) { is IrFunction -> parent.computeFullName() else -> parent.fqNameForIrSerialization.asString() } private val Variance.kVarianceName: String get() = when (this) { Variance.INVARIANT -> "INVARIANT" Variance.IN_VARIANCE -> "IN" Variance.OUT_VARIANCE -> "OUT" } private fun IrBuilderWithScope.irKVariance(variance: Variance) = IrGetEnumValueImpl( startOffset, endOffset, symbols.kVariance.defaultType, symbols.kVariance.owner.declarations .filterIsInstance() .single { it.name.asString() == variance.kVarianceName }.symbol ) private fun IrBuilderWithScope.irKTypeLikeList( types: List, itemType: IrType, itemBuilder: (T) -> IrExpression ) = if (types.isEmpty()) { irCall(symbols.emptyList, listOf(itemType)) } else { irCall(symbols.listOf, listOf(itemType)).apply { putValueArgument(0, IrVarargImpl( startOffset, endOffset, type = symbols.array.typeWith(itemType), varargElementType = itemType, elements = types.map { itemBuilder(it) } )) } } private fun IrBuilderWithScope.irKTypeList( types: List, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ) = irKTypeLikeList(types, symbols.kType.defaultType) { irKType(it, leaveReifiedForLater, seenTypeParameters) } private fun IrBuilderWithScope.irKTypeProjectionsList( irTypeArguments: List, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ) = irKTypeLikeList(irTypeArguments, symbols.kTypeProjection.typeWithoutArguments) { irKTypeProjection(it, leaveReifiedForLater, seenTypeParameters) } private fun IrBuilderWithScope.irKTypeProjection( argument: IrTypeArgument, leaveReifiedForLater: Boolean, seenTypeParameters: MutableSet ) = when (argument) { is IrTypeProjection -> irCall(symbols.kTypeProjectionFactories.getValue(argument.variance)).apply { dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion) putValueArgument(0, irKType(argument.type, leaveReifiedForLater, seenTypeParameters)) } is IrStarProjection -> irCall(symbols.kTypeProjectionStar.owner.getter!!).apply { dispatchReceiver = irGetObject(symbols.kTypeProjectionCompanion) } else -> error("Unexpected IrTypeArgument: $argument (${argument::class})") } } internal fun IrBuilderWithScope.irKClass(context: KonanBackendContext, symbol: IrClassSymbol): IrExpression { val symbols = context.ir.symbols return when { symbol.descriptor.isObjCClass() -> irKClassUnsupported(context, "KClass for Objective-C classes is not supported yet") symbol.descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && it.fqNameUnsafe == InteropFqNames.nativePointed } -> irKClassUnsupported(context, "KClass for interop types is not supported yet") else -> irCall(symbols.kClassImplConstructor.owner).apply { putValueArgument(0, irCall(symbols.getClassTypeInfo, listOf(symbol.typeWithStarProjections))) } } } private fun IrBuilderWithScope.irKClassUnsupported(context: KonanBackendContext, message: String) = irCall(context.ir.symbols.kClassUnsupportedImplConstructor.owner).apply { putValueArgument(0, irString(message)) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.irGetObject import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid internal class ReturnsInsertionLowering(val context: Context) : FileLoweringPass { private val symbols = context.ir.symbols override fun lower(irFile: IrFile) { irFile.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitFunction(declaration: IrFunction) { declaration.acceptChildrenVoid(this) context.createIrBuilder(declaration.symbol, declaration.endOffset, declaration.endOffset).run { when (val body = declaration.body) { is IrExpressionBody -> { declaration.body = IrBlockBodyImpl(body.startOffset, body.endOffset) { statements += irReturn(body.expression) } } is IrBlockBody -> { if (declaration is IrConstructor || declaration.returnType == context.irBuiltIns.unitType) body.statements += irReturn(irGetObject(symbols.unit)) } } } } override fun visitBlock(expression: IrBlock) { expression.acceptChildrenVoid(this) if (expression !is IrReturnableBlock) return if (expression.inlineFunctionSymbol?.owner?.returnType == context.irBuiltIns.unitType) { val irBuilder = context.createIrBuilder(expression.symbol, expression.endOffset, expression.endOffset) irBuilder.run { expression.statements += irReturn(irGetObject(symbols.unit)) } } } }) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/SpecialBackendChecksTraversal.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.lower.Closure import org.jetbrains.kotlin.backend.common.lower.ClosureAnnotator import org.jetbrains.kotlin.backend.common.peek import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.cgen.* import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.ir.companionObject import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny import org.jetbrains.kotlin.backend.konan.ir.isReal import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.isFinalClass import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.fileUtils.descendantRelativeTo import java.io.File internal class SpecialBackendChecksTraversal(val context: Context) : FileLoweringPass { override fun lower(irFile: IrFile) = irFile.acceptChildrenVoid(BackendChecker(context, irFile)) } private class BackendChecker(val context: Context, val irFile: IrFile) : IrElementVisitorVoid { val interop = context.interopBuiltIns val symbols = context.ir.symbols val irBuiltIns = context.irBuiltIns val target = context.config.target fun reportError(location: IrElement, message: String): Nothing = context.reportCompilationError(message, irFile, location) private val outerDeclarations = mutableListOf() private val outerClass: IrClass? get() = outerDeclarations.last { it is IrClass } as? IrClass private val outerFunction: IrFunction? get() = outerDeclarations.last { it is IrFunction } as? IrFunction private val outerAnnotators = mutableListOf>() private val functionAnnotators = mutableMapOf>() private val functionClosures = mutableMapOf() private fun captures(function: IrFunction): List { if (function.visibility != DescriptorVisibilities.LOCAL) return emptyList() val closure = functionClosures.getOrPut(function) { functionAnnotators[function]!!.value.getFunctionClosure(function) } return closure.capturedValues.map { it.owner } } override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitDeclaration(declaration: IrDeclarationBase) { if (declaration is IrClass && declaration.isKotlinObjCClass()) { checkKotlinObjCClass(declaration) } outerDeclarations.push(declaration) try { super.visitDeclaration(declaration) } finally { outerDeclarations.pop() } } override fun visitBody(body: IrBody) { val declaration = outerDeclarations.peek()!! if ((declaration as? IrFunction)?.visibility == DescriptorVisibilities.LOCAL) { functionAnnotators[declaration] = outerAnnotators.peek()!! super.visitBody(body) return } outerAnnotators.push(lazy { ClosureAnnotator(body, declaration) }) try { super.visitBody(body) } finally { outerAnnotators.pop() } } private fun IrConstructor.isOverrideInit() = this.annotations.hasAnnotation(context.interopBuiltIns.objCOverrideInit.fqNameSafe) private fun checkCanGenerateOverrideInit(irClass: IrClass, constructor: IrConstructor) { val superClass = irClass.getSuperClassNotAny()!! val superConstructors = superClass.constructors.filter { constructor.overridesConstructor(it) }.toList() val superConstructor = superConstructors.singleOrNull() ?: run { val annotation = context.interopBuiltIns.objCOverrideInit.name if (superConstructors.isEmpty()) reportError(constructor, """ constructor with @$annotation doesn't override any super class constructor. It must completely match by parameter names and types.""".trimIndent() ) else reportError(constructor, "constructor with @$annotation matches more than one of super constructors" ) } val initMethod = superConstructor.getObjCInitMethod()!! // Remove fake overrides of this init method, also check for explicit overriding: irClass.declarations.forEach { if (it is IrSimpleFunction && initMethod.symbol in it.overriddenSymbols && it.isReal) { val annotation = context.interopBuiltIns.objCOverrideInit.name reportError(constructor, "constructor with @$annotation overrides initializer that is already overridden explicitly" ) } } } private fun IrConstructor.overridesConstructor(other: IrConstructor) = this.descriptor.valueParameters.size == other.descriptor.valueParameters.size && this.descriptor.valueParameters.all { val otherParameter = other.descriptor.valueParameters[it.index] it.name == otherParameter.name && it.type == otherParameter.type } private fun checkCanGenerateActionImp(function: IrSimpleFunction) { val action = "@${context.interopBuiltIns.objCAction.name}" function.extensionReceiverParameter?.let { reportError(it, "$action method must not have extension receiver") } function.valueParameters.forEach { val kotlinType = it.descriptor.type if (!kotlinType.isObjCObjectType()) reportError(it, "Unexpected $action method parameter type: $kotlinType\n" + "Only Objective-C object types are supported here") } val returnType = function.returnType if (!returnType.isUnit()) reportError(function, "Unexpected $action method return type: ${returnType.toKotlinType()}\n" + "Only 'Unit' is supported here") checkCanGenerateFunctionImp(function) } private fun checkCanGenerateOutletSetterImp(property: IrProperty) { val descriptor = property.descriptor val outlet = "@${context.interopBuiltIns.objCOutlet.name}" if (!descriptor.isVar) reportError(property, "$outlet property must be var") property.getter?.extensionReceiverParameter?.let { reportError(it, "$outlet must not have extension receiver") } val type = descriptor.type if (!type.isObjCObjectType()) reportError(property, "Unexpected $outlet type: $type\n" + "Only Objective-C object types are supported here") checkCanGenerateFunctionImp(property.setter!!) } private fun checkCanGenerateFunctionImp(function: IrFunction) { if (function.valueParameters.size > 2) reportError(function, "Only 0, 1 or 2 parameters are supported here") } private fun IrClass.hasFields() = this.declarations.any { when (it) { is IrField -> it.isReal is IrProperty -> it.isReal && it.backingField != null else -> false } } private fun checkKotlinObjCClass(irClass: IrClass) { for (declaration in irClass.declarations) { if (declaration is IrSimpleFunction && declaration.annotations.hasAnnotation(interop.objCAction.fqNameSafe)) checkCanGenerateActionImp(declaration) if (declaration is IrProperty && declaration.annotations.hasAnnotation(interop.objCOutlet.fqNameSafe)) checkCanGenerateOutletSetterImp(declaration) if (declaration is IrConstructor && declaration.isOverrideInit()) checkCanGenerateOverrideInit(irClass, declaration) if (declaration is IrSimpleFunction && declaration.isReal) { for (overriddenSymbol in declaration.overriddenSymbols) overriddenSymbol.owner.getExternalObjCMethodInfo()?.selector?.let { checkCanGenerateCFunction( function = declaration, signature = overriddenSymbol.owner, isObjCMethod = true, location = declaration ) } } } val kind = irClass.descriptor.kind if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) reportError(irClass, "Only classes are supported as subtypes of Objective-C types") if (!irClass.descriptor.isFinalClass) reportError(irClass, "Non-final Kotlin subclasses of Objective-C classes are not yet supported") irClass.companionObject()?.let { if (it.hasFields() || it.getSuperClassNotAny()?.hasFields() == true) reportError(irClass, "Fields are not supported for Companion of subclass of ObjC type") } var hasObjCClassSupertype = false irClass.descriptor.defaultType.constructor.supertypes.forEach { val descriptor = it.constructor.declarationDescriptor as ClassDescriptor if (!descriptor.isObjCClass()) reportError(irClass, "Mixing Kotlin and Objective-C supertypes is not supported") if (descriptor.kind == ClassKind.CLASS) hasObjCClassSupertype = true } if (!hasObjCClassSupertype) reportError(irClass, "Kotlin implementation of Objective-C protocol must have Objective-C superclass (e.g. NSObject)") val methodsOfAny = context.ir.symbols.any.owner.declarations.filterIsInstance().toSet() irClass.declarations.filterIsInstance().filter { it.isReal }.forEach { method -> val overriddenMethodOfAny = method.allOverriddenFunctions.firstOrNull { it in methodsOfAny } if (overriddenMethodOfAny != null) { val correspondingObjCMethod = when (method.name.asString()) { "toString" -> "'description'" "hashCode" -> "'hash'" "equals" -> "'isEqual:'" else -> "corresponding Objective-C method" } context.report( method, "can't override '${method.name}', override $correspondingObjCMethod instead", isError = true ) } } } override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) { expression.acceptChildrenVoid(this) val constructedClass = outerClass!! if (!constructedClass.isObjCClass()) return constructedClass.parent.let { parent -> if (parent is IrClass && parent.isObjCClass() && constructedClass.isCompanion) { // Note: it is actually not used; getting values of such objects is handled by code generator // in [FunctionGenerationContext.getObjectValue]. return } } val delegatingCallConstructingClass = expression.symbol.owner.constructedClass if (!constructedClass.isExternalObjCClass() && delegatingCallConstructingClass.isExternalObjCClass()) { // Calling super constructor from Kotlin Objective-C class. val initMethod = expression.symbol.owner.getObjCInitMethod()!! if (!expression.symbol.owner.objCConstructorIsDesignated()) reportError(expression, "Unable to call non-designated initializer as super constructor") checkCanGenerateObjCCall( method = initMethod, call = expression, arguments = initMethod.valueParameters.map { expression.getValueArgument(it.index) } ) } } override fun visitConstructorCall(expression: IrConstructorCall) { expression.acceptChildrenVoid(this) val callee = expression.symbol.owner val initMethod = callee.getObjCInitMethod() if (initMethod != null) { val arguments = callee.valueParameters.map { expression.getValueArgument(it.index) } checkCanGenerateObjCCall( method = initMethod, call = expression, arguments = arguments ) } if (callee.returnType.isNativePointed(symbols)) reportError(expression, "Native interop types constructors must not be called directly") } override fun visitField(declaration: IrField) { if (declaration.isFakeOverride) return // Can't happen now, just trying to be future-proof here. val parent = declaration.parent if (parent is IrClass && parent.defaultType.isNativePointed(symbols) && parent.symbol != symbols.nativePointed) { val nativePointed = symbols.nativePointed.owner.name reportError(declaration, "Subclasses of $nativePointed cannot have properties with backing fields") } } private val cwd = File(".").absoluteFile private fun reportBoundFunctionReferenceError(expression: IrExpression, callee: IrFunction, captures: List): Nothing { val formattedCaptures = if (captures.isEmpty()) "" else ", but captures at:\n ${captures.joinToString("\n ") { val location = it.getCompilerMessageLocation(irFile)!! val relativePath = File(location.path).descendantRelativeTo(cwd).path val capturedValueName = if (it is IrGetValue) ": ${it.symbol.owner.name.asString()}" else "" "$relativePath:${location.line}:${location.column}$capturedValueName" }}" reportError(expression, "${callee.fqNameForIrSerialization} must take an unbound, non-capturing function or lambda$formattedCaptures") } override fun visitCall(expression: IrCall) { expression.acceptChildrenVoid(this) val callee = expression.symbol.owner callee.getObjCFactoryInitMethodInfo()?.let { _ -> val arguments = (0 until expression.valueArgumentsCount).map(expression::getValueArgument) checkCanGenerateObjCCall( method = callee, call = expression, arguments = arguments ) } callee.getExternalObjCMethodInfo()?.let { _ -> val isInteropStubsFile = irFile.annotations.hasAnnotation(FqName("kotlinx.cinterop.InteropStubs")) // Special case: bridge from Objective-C method implementation template to Kotlin method; // handled in CodeGeneratorVisitor.callVirtual. val useKotlinDispatch = isInteropStubsFile && outerFunction!!.annotations.hasAnnotation(FqName("kotlin.native.internal.ExportForCppRuntime")) if (!useKotlinDispatch) { val arguments = callee.valueParameters.map { expression.getValueArgument(it.index) } if (expression.superQualifierSymbol?.owner?.isObjCMetaClass() == true) reportError(expression, "Super calls to Objective-C meta classes are not supported yet") if (expression.superQualifierSymbol?.owner?.isInterface == true) reportError(expression, "Super calls to Objective-C protocols are not allowed") checkCanGenerateObjCCall( method = callee, call = expression, arguments = arguments ) } } if (callee.annotations.hasAnnotation(RuntimeNames.cCall)) checkCanGenerateCCall(expression, isInvoke = false) when (val intrinsicType = tryGetIntrinsicType(expression)) { IntrinsicType.INTEROP_STATIC_C_FUNCTION -> { val (target, captures) = getUnboundReferencedFunction(expression.getValueArgument(0)!!) if (target == null || target.symbol !is IrSimpleFunctionSymbol) reportBoundFunctionReferenceError(expression, callee, captures) val signatureTypes = target.allParameters.map { it.type } + target.returnType callee.typeParameters.indices.forEach { index -> val typeArgument = expression.getTypeArgument(index)!!.toKotlinType() val signatureType = signatureTypes[index].toKotlinType() if (typeArgument.constructor != signatureType.constructor || typeArgument.isMarkedNullable != signatureType.isMarkedNullable ) { reportError(expression, "C function signature element mismatch: expected '$signatureType', got '$typeArgument'") } } checkCanGenerateCFunctionPointer(target as IrSimpleFunction, expression) } IntrinsicType.INTEROP_FUNPTR_INVOKE -> { checkCanGenerateCCall(expression, isInvoke = true) } IntrinsicType.INTEROP_SIGN_EXTEND, IntrinsicType.INTEROP_NARROW -> { val integerTypePredicates = arrayOf( IrType::isByte, IrType::isShort, IrType::isInt, IrType::isLong ) val receiver = expression.extensionReceiver!! val typeOperand = expression.getSingleTypeArgument() val kotlinTypeOperand = typeOperand.toKotlinType() val receiverTypeIndex = integerTypePredicates.indexOfFirst { it(receiver.type) } val typeOperandIndex = integerTypePredicates.indexOfFirst { it(typeOperand) } val receiverKotlinType = receiver.type.toKotlinType() if (receiverTypeIndex == -1) reportError(receiver, "Receiver's type $receiverKotlinType is not an integer type") if (typeOperandIndex == -1) reportError(expression, "Type argument $kotlinTypeOperand is not an integer type") when (intrinsicType) { IntrinsicType.INTEROP_SIGN_EXTEND -> if (receiverTypeIndex > typeOperandIndex) reportError(expression, "unable to sign extend $receiverKotlinType to $kotlinTypeOperand") IntrinsicType.INTEROP_NARROW -> if (receiverTypeIndex < typeOperandIndex) reportError(expression, "unable to narrow $receiverKotlinType to $kotlinTypeOperand") else -> error(intrinsicType) } } IntrinsicType.INTEROP_CONVERT -> { val integerClasses = symbols.allIntegerClasses val typeOperand = expression.getTypeArgument(0)!! val receiverType = expression.symbol.owner.extensionReceiverParameter!!.type if (typeOperand !is IrSimpleType || typeOperand.classifier !in integerClasses || typeOperand.hasQuestionMark) reportError(expression, "unable to convert ${receiverType.toKotlinType()} to ${typeOperand.toKotlinType()}") } IntrinsicType.WORKER_EXECUTE -> { val (function, captures) = getUnboundReferencedFunction(expression.getValueArgument(2)!!) if (function == null) reportBoundFunctionReferenceError(expression, callee, captures) } else -> when { callee.symbol == symbols.createCleaner -> { val (function, captures) = getUnboundReferencedFunction(expression.getValueArgument(1)!!) if (function == null) reportBoundFunctionReferenceError(expression, callee, captures) } callee.symbol == symbols.immutableBlobOf -> { val args = expression.getValueArgument(0) ?: reportError(expression, "expected at least one element") val elements = (args as IrVararg).elements if (elements.any { it is IrSpreadElement }) reportError(args, "no spread elements allowed here") elements.forEach { if (it !is IrConst<*>) reportError(args, "all elements of binary blob must be constants") val value = it.value as Short if (value < 0 || value > 0xff) reportError(it, "incorrect value for binary data: $value") } } Symbols.isTypeOfIntrinsic(callee.symbol) -> checkIrKType(expression, expression.getTypeArgument(0)!!) } } } override fun visitFunctionExpression(expression: IrFunctionExpression) { expression.acceptChildrenVoid(this) checkCanReferenceFunction(expression.function, expression) } override fun visitFunctionReference(expression: IrFunctionReference) { expression.acceptChildrenVoid(this) checkCanReferenceFunction(expression.symbol.owner, expression) } private fun checkCanReferenceFunction(callee: IrFunction, expression: IrExpression) { // Corresponds to the check in [KotlinToCCallBuilder.handleArgumentForVarargParameter]. if (callee.valueParameters.any { it.isVararg }) { if (callee.annotations.hasAnnotation(RuntimeNames.cCall)) reportError(expression, "callable references to variadic C functions are not supported") if (callee is IrConstructor && callee.getObjCInitMethod() != null || callee.getObjCFactoryInitMethodInfo() != null || callee.getExternalObjCMethodInfo() != null ) { reportError(expression, "callable references to variadic Objective-C methods are not supported") } } } private data class ReferencedFunctionWithCapture(val function: IrFunction?, val captures: List) private fun searchForReferences(function: IrFunction, targetValues: Set): List { if (targetValues.isEmpty()) return emptyList() val result = mutableListOf() function.acceptChildrenVoid(object: IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitGetValue(expression: IrGetValue) { if (expression.symbol.owner in targetValues) result += expression } }) return result } private fun getUnboundReferencedFunction(expression: IrExpression) = when (expression) { is IrFunctionReference -> { val arguments = expression.getArguments() val capturedVariables = captures(expression.symbol.owner) ReferencedFunctionWithCapture( expression.symbol.owner.takeIf { arguments.isEmpty() && capturedVariables.isEmpty() }, arguments.map { it.second } + searchForReferences(expression.symbol.owner, capturedVariables.toSet()) ) } is IrFunctionExpression -> { val capturedVariables = captures(expression.function) ReferencedFunctionWithCapture( expression.function.takeIf { capturedVariables.isEmpty() }, searchForReferences(expression.function, capturedVariables.toSet()) ) } else -> ReferencedFunctionWithCapture(null, emptyList()) } private fun IrCall.getSingleTypeArgument(): IrType { val typeParameter = symbol.owner.typeParameters.single() return getTypeArgument(typeParameter.index)!! } private fun checkIrKType( irElement: IrElement, type: IrType, seenTypeParameters: MutableSet = mutableSetOf() ) { if (type !is IrSimpleType) return val classifier = type.classifier if (classifier is IrTypeParameterSymbol && !classifier.owner.isReified /* Reified may be substituted with valid types later */) checkIrKTypeParameter(irElement, classifier.owner, seenTypeParameters) type.arguments.forEach { if (it is IrTypeProjection) checkIrKType(irElement, it.type, seenTypeParameters) } } private fun checkIrKTypeParameter( irElement: IrElement, typeParameter: IrTypeParameter, seenTypeParameters: MutableSet ) { if (!seenTypeParameters.add(typeParameter)) reportError(irElement, "Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.render()}") typeParameter.superTypes.forEach { checkIrKType(irElement, it, seenTypeParameters) } seenTypeParameters.remove(typeParameter) } } private fun BackendChecker.checkCanGenerateCCall(expression: IrCall, isInvoke: Boolean) { val callee = expression.symbol.owner if (isInvoke) { (0 until expression.valueArgumentsCount).forEach { checkCanMapCalleeFunctionParameter( type = expression.getTypeArgument(it)!!, isObjCMethod = false, variadic = false, parameter = null, argument = expression.getValueArgument(it)!!) } val returnType = expression.getTypeArgument(expression.typeArgumentsCount - 1)!! checkCanMapReturnType(returnType, TypeLocation.FunctionCallResult(expression)) } else { val arguments = (0 until expression.valueArgumentsCount).map(expression::getValueArgument) checkCanAddArguments(arguments, callee, isObjCMethod = false) checkCanMapReturnType(callee.returnType, TypeLocation.FunctionCallResult(expression)) } } private fun BackendChecker.checkCanAddArguments(arguments: List, callee: IrFunction, isObjCMethod: Boolean) { arguments.forEachIndexed { index, argument -> val parameter = callee.valueParameters[index] if (parameter.isVararg) checkCanHandleArgumentForVarargParameter(argument, isObjCMethod) else checkCanMapCalleeFunctionParameter(parameter.type, isObjCMethod, variadic = false, parameter = parameter, argument = argument!!) } } private fun BackendChecker.checkCanUnwrapVariadicArguments(elements: List, isObjCMethod: Boolean) { for (element in elements) when (element) { is IrExpression -> checkCanMapCalleeFunctionParameter(element.type, isObjCMethod, variadic = true, parameter = null, argument = element) is IrSpreadElement -> { val expression = element.expression if (expression is IrCall && expression.symbol == symbols.arrayOf) checkCanHandleArgumentForVarargParameter(expression.getValueArgument(0), isObjCMethod) else reportError(element, "When calling variadic " + (if (isObjCMethod) "Objective-C methods " else "C functions ") + "spread operator is supported only for *arrayOf(...)") } } } private fun BackendChecker.checkCanHandleArgumentForVarargParameter(argument: IrExpression?, isObjCMethod: Boolean) { when (argument) { is IrVararg -> checkCanUnwrapVariadicArguments(argument.elements, isObjCMethod) is IrGetValue -> { /* This is possible when using named arguments with reordering, i.e. * * foo(second = *arrayOf(...), first = ...) * * psi2ir generates as * * val secondTmp = *arrayOf(...) * val firstTmp = ... * foo(firstTmp, secondTmp) * * **/ val variable = argument.symbol.owner if (variable is IrVariable && variable.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE && !variable.isVar) checkCanUnwrapVariadicArguments((variable.initializer as IrVararg).elements, isObjCMethod) } } } private fun BackendChecker.checkCanGenerateObjCCall( method: IrSimpleFunction, call: IrFunctionAccessExpression, arguments: List ) { checkCanAddArguments(arguments, method, isObjCMethod = true) checkCanMapReturnType(method.returnType, TypeLocation.FunctionCallResult(call)) } private fun BackendChecker.checkParameter(it: IrValueParameter, functionParameter: IrValueParameter, isObjCMethod: Boolean, location: IrElement) { val typeLocation = if (isObjCMethod) TypeLocation.ObjCMethodParameter(it.index, functionParameter) else TypeLocation.FunctionPointerParameter(it.index, location) if (functionParameter.isVararg) reportError(typeLocation.element, if (isObjCMethod) { "overriding variadic Objective-C methods is not supported" } else { "variadic function pointers are not supported" }) checkCanMapFunctionParameterType(it.type, variadic = false, location = typeLocation) } private fun BackendChecker.checkCanGenerateCFunction( function: IrSimpleFunction, signature: IrSimpleFunction, isObjCMethod: Boolean, location: IrElement ) { signature.extensionReceiverParameter?.let { checkParameter(it, function.extensionReceiverParameter!!, isObjCMethod, location) } signature.valueParameters.forEach { checkParameter(it, function.valueParameters[it.index], isObjCMethod, location) } } private fun BackendChecker.checkCanGenerateCFunctionPointer(function: IrSimpleFunction, expression: IrExpression) = checkCanGenerateCFunction( function = function, signature = function, isObjCMethod = false, location = expression ) private fun BackendChecker.checkCanMapCalleeFunctionParameter( type: IrType, isObjCMethod: Boolean, variadic: Boolean, parameter: IrValueParameter?, argument: IrExpression ) { val classifier = type.classifierOrNull when { classifier == symbols.interopCValues || // Note: this should not be accepted, but is required for compatibility classifier == symbols.interopCValuesRef -> return classifier == symbols.string && (variadic || parameter?.isCStringParameter() == true) -> { if (variadic && isObjCMethod) { reportError(argument, "Passing String as variadic Objective-C argument is ambiguous; " + "cast it to NSString or pass with '.cstr' as C string") // TODO: consider reporting a warning for C functions. } } classifier == symbols.string && parameter?.isWCStringParameter() == true -> return else -> checkCanMapFunctionParameterType(type, variadic = variadic, location = TypeLocation.FunctionArgument(argument)) } } private sealed class TypeLocation(val element: IrElement) { class FunctionArgument(val argument: IrExpression) : TypeLocation(argument) class FunctionCallResult(val call: IrFunctionAccessExpression) : TypeLocation(call) class FunctionPointerParameter(val index: Int, element: IrElement) : TypeLocation(element) class FunctionPointerReturnValue(element: IrElement) : TypeLocation(element) class ObjCMethodParameter(val index: Int, element: IrElement) : TypeLocation(element) class ObjCMethodReturnValue(element: IrElement) : TypeLocation(element) class BlockParameter(val index: Int, val blockLocation: TypeLocation) : TypeLocation(blockLocation.element) class BlockReturnValue(val blockLocation: TypeLocation) : TypeLocation(blockLocation.element) } private fun BackendChecker.checkCanMapFunctionParameterType(type: IrType, variadic: Boolean, location: TypeLocation) { if (!type.isUnit() || variadic) checkCanMapType(type, variadic = variadic, location = location) } private fun BackendChecker.checkCanMapReturnType(type: IrType, location: TypeLocation) { if (!type.isUnit()) checkCanMapType(type, variadic = false, location = location) } private fun BackendChecker.checkCanMapBlockType(type: IrType, location: TypeLocation) { when (val returnTypeArgument = (type as IrSimpleType).arguments.last()) { is IrTypeProjection -> if (returnTypeArgument.variance == Variance.INVARIANT) checkCanMapReturnType(returnTypeArgument.type, TypeLocation.BlockReturnValue(location)) else reportUnsupportedType("${returnTypeArgument.variance.label}-variance of return type", type, location) is IrStarProjection -> reportUnsupportedType("* as return type", type, location) } type.arguments.dropLast(1).forEachIndexed { index, argument -> when (argument) { is IrTypeProjection -> if (argument.variance == Variance.INVARIANT) checkCanMapType(argument.type, variadic = false, location = TypeLocation.BlockParameter(index, location)) else reportUnsupportedType("${argument.variance.label}-variance of ${index + 1} parameter type", type, location) is IrStarProjection -> reportUnsupportedType("* as ${index + 1} parameter type", type, location) } } } private fun BackendChecker.checkCanMapType(type: IrType, variadic: Boolean, location: TypeLocation) = checkCanMapType(type, variadic, location) { reportUnsupportedType(it, type, location) } private fun BackendChecker.checkCanMapType( type: IrType, variadic: Boolean, typeLocation: TypeLocation, reportUnsupportedType: (String) -> Nothing ) { when { type.isBoolean() -> { if (cBoolType(target) == null) reportUnsupportedType("unavailable on target platform") } type.isByte() -> return type.isShort() -> return type.isInt() -> return type.isLong() -> return type.isFloat() -> return type.isDouble() -> return type.isCPointer(symbols) -> return type.isTypeOfNullLiteral() && variadic -> return type.isUByte() -> return type.isUShort() -> return type.isUInt() -> return type.isULong() -> return type.isVector() -> return type.isCEnumType() -> return type.isCValue(symbols) -> if (type.isNullable()) reportUnsupportedType("must not be nullable") else { val kotlinClass = (type as IrSimpleType).arguments.singleOrNull()?.typeOrNull?.getClass() ?: reportUnsupportedType("must be parameterized with concrete class") kotlinClass.getCStructSpelling() ?: reportUnsupportedType("not a structure or too complex") } type.isNativePointed(symbols) -> return type.isFunction() -> if (variadic) reportUnsupportedType("not supported as variadic argument") else checkCanMapBlockType(type, location = typeLocation) type.isObjCReferenceType(target, irBuiltIns) -> return else -> reportUnsupportedType("doesn't correspond to any C type") } } private fun BackendChecker.reportUnsupportedType(reason: String, type: IrType, location: TypeLocation): Nothing { // TODO: report errors in frontend instead. fun TypeLocation.render(): String = when (this) { is TypeLocation.FunctionArgument -> "" is TypeLocation.FunctionCallResult -> " of return value" is TypeLocation.FunctionPointerParameter -> " of callback parameter ${index + 1}" is TypeLocation.FunctionPointerReturnValue -> " of callback return value" is TypeLocation.ObjCMethodParameter -> " of overridden Objective-C method parameter" is TypeLocation.ObjCMethodReturnValue -> " of overridden Objective-C method return value" is TypeLocation.BlockParameter -> " of ${index + 1} parameter in Objective-C block type${blockLocation.render()}" is TypeLocation.BlockReturnValue -> " of return value of Objective-C block type${blockLocation.render()}" } val typeLocation: String = location.render() reportError(location.element, "type ${type.render()} $typeLocation is not supported here" + if (reason.isNotEmpty()) ": $reason" else "") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/StringConcatenationLowering.kt ================================================ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.lower.IrBuildingTransformer import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions /** * This lowering pass replaces [IrStringConcatenation]s with StringBuilder appends. */ internal class StringConcatenationLowering(context: Context) : FileLoweringPass, IrBuildingTransformer(context) { override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) } private val irBuiltIns = context.irBuiltIns private val symbols = context.ir.symbols private val typesWithSpecialAppendFunction = irBuiltIns.primitiveIrTypes + irBuiltIns.stringType private val nameToString = Name.identifier("toString") private val nameAppend = Name.identifier("append") private val stringBuilder = context.ir.symbols.stringBuilder.owner //TODO: calculate and pass string length to the constructor. private val constructor = stringBuilder.constructors.single { it.valueParameters.isEmpty() } private val toStringFunction = stringBuilder.functions.single { it.valueParameters.isEmpty() && it.name == nameToString } private val defaultAppendFunction = stringBuilder.functions.single { it.name == nameAppend && it.valueParameters.size == 1 && it.valueParameters.single().type.isNullableAny() } private val appendFunctions: Map = typesWithSpecialAppendFunction.map { type -> type to stringBuilder.functions.toList().atMostOne { it.name == nameAppend && it.valueParameters.singleOrNull()?.type == type } }.toMap() private fun typeToAppendFunction(type: IrType): IrSimpleFunction { return appendFunctions[type] ?: defaultAppendFunction } override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression { expression.transformChildrenVoid(this) builder.at(expression) val arguments = expression.arguments return when { arguments.isEmpty() -> builder.irString("") arguments.size == 1 -> { val argument = arguments[0] if (argument.type.isNullable()) builder.irCall(symbols.extensionToString).apply { extensionReceiver = argument } else builder.irCall( irBuiltIns.anyClass.functions .single { it.owner.name.asString() == "toString" }).apply { dispatchReceiver = argument } } arguments.size == 2 && arguments[0].type.isStringClassType() -> if (arguments[0].type.isNullable()) builder.irCall(symbols.stringPlus).apply { extensionReceiver = arguments[0] putValueArgument(0, arguments[1]) } else builder.irCall(symbols.string.functions .single { it.owner.name == OperatorNameConventions.PLUS }).apply { dispatchReceiver = arguments[0] putValueArgument(0, arguments[1]) } else -> builder.irBlock(expression) { val stringBuilderImpl = createTmpVariable(irCall(constructor)) expression.arguments.forEach { arg -> val appendFunction = typeToAppendFunction(arg.type) +irCall(appendFunction).apply { dispatchReceiver = irGet(stringBuilderImpl) putValueArgument(0, arg) } } +irCall(toStringFunction).apply { dispatchReceiver = irGet(stringBuilderImpl) } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TestProcessor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.reportWarning import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.getIncludedLibraryDescriptors import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections import org.jetbrains.kotlin.backend.konan.ir.typeWithoutArguments import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.addChild import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult internal class TestProcessor (val context: Context) { object TEST_SUITE_CLASS: IrDeclarationOriginImpl("TEST_SUITE_CLASS") object TEST_SUITE_GENERATED_MEMBER: IrDeclarationOriginImpl("TEST_SUITE_GENERATED_MEMBER") companion object { val COMPANION_GETTER_NAME = Name.identifier("getCompanion") val INSTANCE_GETTER_NAME = Name.identifier("createInstance") val IGNORE_FQ_NAME = FqName.fromSegments(listOf("kotlin", "test" , "Ignore")) } private val symbols = context.ir.symbols private val baseClassSuite = symbols.baseClassSuite.owner private val topLevelSuiteNames = mutableSetOf() // region Useful extensions. private var testSuiteCnt = 0 private fun Name.synthesizeSuiteClassName() = identifier.synthesizeSuiteClassName() private fun String.synthesizeSuiteClassName() = "$this\$test\$${testSuiteCnt++}".synthesizedName // IrFile always uses a forward slash as a directory separator. private val IrFile.fileName get() = name.substringAfterLast('/') private val IrFile.topLevelSuiteName: String get() { val packageFqName = fqName val shortFileName = PackagePartClassUtils.getFilePartShortName(fileName) return if (packageFqName.isRoot) shortFileName else "$packageFqName.$shortFileName" } private fun MutableList.registerFunction( function: IrFunction, kinds: Collection>) = kinds.forEach { (kind, ignored) -> add(TestFunction(function, kind, ignored)) } private fun MutableList.registerFunction( function: IrFunction, kind: FunctionKind, ignored: Boolean ) = add(TestFunction(function, kind, ignored)) private fun IrStatementsBuilder.generateFunctionRegistration( receiver: IrValueDeclaration, registerTestCase: IrFunction, registerFunction: IrFunction, functions: Collection) { functions.forEach { if (it.kind == FunctionKind.TEST) { // Call registerTestCase(name: String, testFunction: () -> Unit) method. +irCall(registerTestCase).apply { dispatchReceiver = irGet(receiver) putValueArgument(0, irString(it.function.name.identifier)) putValueArgument(1, IrFunctionReferenceImpl( it.function.startOffset, it.function.endOffset, registerTestCase.valueParameters[1].type, it.function.symbol, typeArgumentsCount = 0, valueArgumentsCount = 0, reflectionTarget = null)) putValueArgument(2, irBoolean(it.ignored)) } } else { // Call registerFunction(kind: TestFunctionKind, () -> Unit) method. +irCall(registerFunction).apply { dispatchReceiver = irGet(receiver) val testKindEntry = it.kind.runtimeKind putValueArgument(0, IrGetEnumValueImpl( it.function.startOffset, it.function.endOffset, symbols.testFunctionKind.typeWithoutArguments, testKindEntry) ) putValueArgument(1, IrFunctionReferenceImpl( it.function.startOffset, it.function.endOffset, registerFunction.valueParameters[1].type, it.function.symbol, typeArgumentsCount = 0, valueArgumentsCount = 0, reflectionTarget = null)) } } } } // endregion // region Classes for annotation collection. internal enum class FunctionKind(annotationNameString: String, val runtimeKindString: String) { TEST("kotlin.test.Test", ""), BEFORE_TEST("kotlin.test.BeforeTest", "BEFORE_TEST"), AFTER_TEST("kotlin.test.AfterTest", "AFTER_TEST"), BEFORE_CLASS("kotlin.test.BeforeClass", "BEFORE_CLASS"), AFTER_CLASS("kotlin.test.AfterClass", "AFTER_CLASS"); val annotationFqName = FqName(annotationNameString) companion object { val INSTANCE_KINDS = listOf(TEST, BEFORE_TEST, AFTER_TEST) val COMPANION_KINDS = listOf(BEFORE_CLASS, AFTER_CLASS) } } private val FunctionKind.runtimeKind: IrEnumEntrySymbol get() = symbols.getTestFunctionKind(this) private fun IrType.isTestFunctionKind() = classifierOrNull == symbols.testFunctionKind private data class TestFunction( val function: IrFunction, val kind: FunctionKind, val ignored: Boolean ) private inner class TestClass(val ownerClass: IrClass) { var companion: IrClass? = null val functions = mutableListOf() fun registerFunction( function: IrFunction, kinds: Collection> ) = functions.registerFunction(function, kinds) fun registerFunction(function: IrFunction, kind: FunctionKind, ignored: Boolean) = functions.registerFunction(function, kind, ignored) } private inner class AnnotationCollector(val irFile: IrFile) : IrElementVisitorVoid { val testClasses = mutableMapOf() val topLevelFunctions = mutableListOf() private fun MutableMap.getTestClass(key: IrClass) = getOrPut(key) { TestClass(key) } override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } fun IrFunctionSymbol.hasAnnotation(fqName: FqName) = descriptor.annotations.any { it.fqName == fqName } /** * Checks if [this] or any of its parent functions has the annotation with the given [testAnnotation]. * If [this] contains the given annotation, returns [this]. * If one of the parent functions contains the given annotation, returns the [IrFunctionSymbol] for it. * If the annotation isn't found or found only in interface methods, returns null. */ fun IrFunctionSymbol.findAnnotatedFunction(testAnnotation: FqName): IrFunctionSymbol? { val owner = this.owner val parent = owner.parent if (parent is IrClass && parent.isInterface) { return null } if (hasAnnotation(testAnnotation)) { return this } return (owner as? IrSimpleFunction) ?.overriddenSymbols ?.firstNotNullResult { it.findAnnotatedFunction(testAnnotation) } } fun registerClassFunction(irClass: IrClass, function: IrFunction, kinds: Collection>) { fun warn(msg: String) = context.reportWarning(msg, irFile, function) kinds.forEach { (kind, ignored) -> val annotation = kind.annotationFqName when (kind) { in FunctionKind.INSTANCE_KINDS -> with(irClass) { when { isInner -> warn("Annotation $annotation is not allowed for methods of an inner class") isAbstract() -> { // We cannot create an abstract test class but it's allowed to mark its methods as // tests because the class can be extended. So skip this case without warnings. } isCompanion -> warn("Annotation $annotation is not allowed for methods of a companion object") constructors.none { it.valueParameters.size == 0 } -> warn("Test class has no default constructor: $fqNameForIrSerialization") else -> testClasses.getTestClass(irClass).registerFunction(function, kind, ignored) } } in FunctionKind.COMPANION_KINDS -> when { irClass.isCompanion -> { val containingClass = irClass.parentAsClass val testClass = testClasses.getTestClass(containingClass) testClass.companion = irClass testClass.registerFunction(function, kind, ignored) } irClass.kind == ClassKind.OBJECT -> { testClasses.getTestClass(irClass).registerFunction(function, kind, ignored) } else -> warn("Annotation $annotation is only allowed for methods of an object " + "(named or companion) or top level functions") } else -> throw IllegalStateException("Unreachable") } } } fun IrFunction.checkFunctionSignature() { // Test runner requires test functions to have the following signature: () -> Unit. if (!returnType.isUnit()) { context.reportCompilationError( "Test function must return Unit: $fqNameForIrSerialization", irFile, this ) } if (valueParameters.isNotEmpty()) { context.reportCompilationError( "Test function must have no arguments: $fqNameForIrSerialization", irFile, this ) } } private fun warnAboutInheritedAnnotations( kind: FunctionKind, function: IrFunctionSymbol, annotatedFunction: IrFunctionSymbol ) { if (function.owner != annotatedFunction.owner) { context.reportWarning( "Super method has a test annotation ${kind.annotationFqName} but the overriding method doesn't. " + "Note that the overriding method will still be executed.", irFile, function.owner ) } } private fun warnAboutLoneIgnore(functionSymbol: IrFunctionSymbol): Unit = with(functionSymbol) { if (hasAnnotation(IGNORE_FQ_NAME) && !hasAnnotation(FunctionKind.TEST.annotationFqName)) { context.reportWarning( "Unused $IGNORE_FQ_NAME annotation (not paired with ${FunctionKind.TEST.annotationFqName}).", irFile, owner ) } } // TODO: Use symbols instead of containingDeclaration when such information is available. override fun visitFunction(declaration: IrFunction) { val symbol = declaration.symbol val parent = declaration.parent warnAboutLoneIgnore(symbol) val kinds = FunctionKind.values().mapNotNull { kind -> symbol.findAnnotatedFunction(kind.annotationFqName)?.let { annotatedFunction -> warnAboutInheritedAnnotations(kind, symbol, annotatedFunction) kind to (kind == FunctionKind.TEST && annotatedFunction.hasAnnotation(IGNORE_FQ_NAME)) } } if (kinds.isEmpty()) { return } declaration.checkFunctionSignature() when (parent) { is IrPackageFragment -> topLevelFunctions.registerFunction(declaration, kinds) is IrClass -> registerClassFunction(parent, declaration, kinds) else -> UnsupportedOperationException("Cannot create test function $declaration (defined in $parent") } } } // endregion //region Symbol and IR builders /** * Builds a method in `[owner]` class with name `[getterName]` * returning a reference to an object represented by `[objectSymbol]`. */ private fun buildObjectGetter(objectSymbol: IrClassSymbol, owner: IrClass, getterName: Name): IrSimpleFunction = IrFunctionImpl( owner.startOffset, owner.endOffset, TEST_SUITE_GENERATED_MEMBER, IrSimpleFunctionSymbolImpl(), getterName, DescriptorVisibilities.PROTECTED, Modality.FINAL, objectSymbol.typeWithStarProjections, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { parent = owner val superFunction = baseClassSuite.simpleFunctions() .single { it.name == getterName && it.valueParameters.isEmpty() } createDispatchReceiverParameter() overriddenSymbols += superFunction.symbol body = context.createIrBuilder(symbol, symbol.owner.startOffset, symbol.owner.endOffset).irBlockBody { +irReturn(irGetObjectValue(objectSymbol.typeWithoutArguments, objectSymbol) ) } } /** * Builds a method in `[testSuite]` class with name `[getterName]` * returning a new instance of class referenced by [classSymbol]. */ private fun buildInstanceGetter(classSymbol: IrClassSymbol, owner: IrClass, getterName: Name): IrSimpleFunction = IrFunctionImpl( owner.startOffset, owner.endOffset, TEST_SUITE_GENERATED_MEMBER, IrSimpleFunctionSymbolImpl(), getterName, DescriptorVisibilities.PROTECTED, Modality.FINAL, classSymbol.typeWithStarProjections, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, isOperator = false, isInfix = false ).apply { parent = owner val superFunction = baseClassSuite.simpleFunctions() .single { it.name == getterName && it.valueParameters.isEmpty() } createDispatchReceiverParameter() overriddenSymbols += superFunction.symbol body = context.createIrBuilder(symbol, symbol.owner.startOffset, symbol.owner.endOffset).irBlockBody { val constructor = classSymbol.owner.constructors.single { it.valueParameters.isEmpty() } +irReturn(irCall(constructor)) } } private val baseClassSuiteConstructor = baseClassSuite.constructors.single { it.valueParameters.size == 2 && it.valueParameters[0].type.isString() // name: String && it.valueParameters[1].type.isBoolean() // ignored: Boolean } /** * Builds a constructor for a test suite class representing a test class (any class in the original IrFile with * method(s) annotated with @Test). The test suite class is a subclass of ClassTestSuite * where T is the test class. */ private fun buildClassSuiteConstructor(suiteName: String, testClassType: IrType, testCompanionType: IrType, testSuite: IrClassSymbol, owner: IrClass, functions: Collection, ignored: Boolean): IrConstructor = IrConstructorImpl( testSuite.owner.startOffset, testSuite.owner.endOffset, TEST_SUITE_GENERATED_MEMBER, IrConstructorSymbolImpl(), Name.special(""), DescriptorVisibilities.PUBLIC, testSuite.typeWithStarProjections, isInline = false, isExternal = false, isPrimary = true, isExpect = false ).apply { parent = owner fun IrClass.getFunction(name: String, predicate: (IrSimpleFunction) -> Boolean) = simpleFunctions().single { it.name.asString() == name && predicate(it) } val registerTestCase = baseClassSuite.getFunction("registerTestCase") { it.valueParameters.size == 3 && it.valueParameters[0].type.isString() // name: String && it.valueParameters[1].type.isFunction() // function: testClassType.() -> Unit && it.valueParameters[2].type.isBoolean() // ignored: Boolean } val registerFunction = baseClassSuite.getFunction("registerFunction") { it.valueParameters.size == 2 && it.valueParameters[0].type.isTestFunctionKind() // kind: TestFunctionKind && it.valueParameters[1].type.isFunction() // function: () -> Unit } body = context.createIrBuilder(symbol, symbol.owner.startOffset, symbol.owner.endOffset).irBlockBody { +irDelegatingConstructorCall(baseClassSuiteConstructor).apply { putTypeArgument(0, testClassType) putTypeArgument(1, testCompanionType) putValueArgument(0, irString(suiteName)) putValueArgument(1, irBoolean(ignored)) } generateFunctionRegistration(testSuite.owner.thisReceiver!!, registerTestCase, registerFunction, functions) } } private val IrClass.ignored: Boolean get() = annotations.hasAnnotation(IGNORE_FQ_NAME) /** * Builds a test suite class representing a test class (any class in the original IrFile with method(s) * annotated with @Test). The test suite class is a subclass of ClassTestSuite where T is the test class. */ private fun buildClassSuite(testClass: IrClass, testCompanion: IrClass?, functions: Collection): IrClass = IrClassImpl( testClass.startOffset, testClass.endOffset, TEST_SUITE_CLASS, IrClassSymbolImpl(), testClass.name.synthesizeSuiteClassName(), ClassKind.CLASS, DescriptorVisibilities.PRIVATE, Modality.FINAL, isCompanion = false, isInner = false, isData = false, isExternal = false, isInline = false, isExpect = false, isFun = false ).apply { createParameterDeclarations() val testClassType = testClass.defaultType val testCompanionType = if (testClass.kind == ClassKind.OBJECT) { testClassType } else { testCompanion?.defaultType ?: context.irBuiltIns.nothingType } val constructor = buildClassSuiteConstructor( testClass.fqNameForIrSerialization.toString(), testClassType, testCompanionType, symbol, this, functions, testClass.ignored ) val instanceGetter: IrFunction val companionGetter: IrFunction? if (testClass.kind == ClassKind.OBJECT) { instanceGetter = buildObjectGetter(testClass.symbol, this, INSTANCE_GETTER_NAME) companionGetter = buildObjectGetter(testClass.symbol, this, COMPANION_GETTER_NAME) } else { instanceGetter = buildInstanceGetter(testClass.symbol, this, INSTANCE_GETTER_NAME) companionGetter = testCompanion?.let { buildObjectGetter(it.symbol, this, COMPANION_GETTER_NAME) } } declarations += constructor declarations += instanceGetter companionGetter?.let { declarations += it } superTypes += symbols.baseClassSuite.typeWith(listOf(testClassType, testCompanionType)) addFakeOverrides(context.irBuiltIns) } //endregion // region IR generation methods private fun generateClassSuite(irFile: IrFile, testClass: TestClass) = with(buildClassSuite(testClass.ownerClass, testClass.companion,testClass.functions)) { irFile.addChild(this) val irConstructor = constructors.single() context.createIrBuilder(irFile.symbol, testClass.ownerClass.startOffset, testClass.ownerClass.endOffset).run { irFile.addTopLevelInitializer( irCall(irConstructor), this@TestProcessor.context, threadLocal = true) } } /** Check if this fqName already used or not. */ private fun checkSuiteName(irFile: IrFile, name: String): Boolean { if (topLevelSuiteNames.contains(name)) { context.reportCompilationError("Package '${irFile.fqName}' has top-level test " + "functions in several files with the same name: '${irFile.fileName}'") } topLevelSuiteNames.add(name) return true } private val topLevelSuite = symbols.topLevelSuite.owner private val topLevelSuiteConstructor = topLevelSuite.constructors.single { it.valueParameters.size == 1 && it.valueParameters[0].type.isString() } private val topLevelSuiteRegisterFunction = topLevelSuite.simpleFunctions().single { it.name.asString() == "registerFunction" && it.valueParameters.size == 2 && it.valueParameters[0].type.isTestFunctionKind() && it.valueParameters[1].type.isFunction() } private val topLevelSuiteRegisterTestCase = topLevelSuite.simpleFunctions().single { it.name.asString() == "registerTestCase" && it.valueParameters.size == 3 && it.valueParameters[0].type.isString() && it.valueParameters[1].type.isFunction() && it.valueParameters[2].type.isBoolean() } private fun generateTopLevelSuite(irFile: IrFile, functions: Collection) { val builder = context.createIrBuilder(irFile.symbol) val suiteName = irFile.topLevelSuiteName if (!checkSuiteName(irFile, suiteName)) { return } // TODO: an awful hack, we make this initializer thread local, so that it doesn't freeze suite, // and later on we could modify some suite's properties. This shall be redesigned. irFile.addTopLevelInitializer(builder.irBlock { val constructorCall = irCall(topLevelSuiteConstructor).apply { putValueArgument(0, IrConstImpl.string(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, context.irBuiltIns.stringType, suiteName)) } val testSuiteVal = irTemporary(constructorCall, "topLevelTestSuite") generateFunctionRegistration(testSuiteVal, topLevelSuiteRegisterTestCase, topLevelSuiteRegisterFunction, functions) }, context, threadLocal = true) } private fun createTestSuites(irFile: IrFile, annotationCollector: AnnotationCollector) { annotationCollector.testClasses.filter { it.value.functions.any { it.kind == FunctionKind.TEST } }.forEach { _, testClass -> generateClassSuite(irFile, testClass) } if (annotationCollector.topLevelFunctions.isNotEmpty()) { generateTopLevelSuite(irFile, annotationCollector.topLevelFunctions) } } // endregion private fun shouldProcessFile(irFile: IrFile): Boolean = irFile.packageFragmentDescriptor.module.let { // Process test annotations in source libraries too. it == context.moduleDescriptor || it in context.getIncludedLibraryDescriptors() } fun process(irFile: IrFile) { // TODO: uses descriptors. if (!shouldProcessFile(irFile)) { return } val annotationCollector = AnnotationCollector(irFile) irFile.acceptChildrenVoid(annotationCollector) createTestSuites(irFile, annotationCollector) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/TypeOperatorLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.konan.ir.containsNull import org.jetbrains.kotlin.backend.konan.ir.isSubtypeOf import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrTypeOperator import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.isSimpleTypeWithQuestionMark import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal fun IrType.erasureForTypeOperation(): IrType { if (this !is IrSimpleType) return this return when (val classifier = classifier) { is IrClassSymbol -> this is IrTypeParameterSymbol -> { val upperBound = classifier.owner.superTypes.firstOrNull() ?: TODO("${classifier.descriptor} : ${classifier.descriptor.upperBounds}") if (this.hasQuestionMark) { // `T?` upperBound.erasureForTypeOperation().makeNullable() } else { upperBound.erasureForTypeOperation() } } else -> TODO(classifier.toString()) } } internal class TypeOperatorLowering(val context: CommonBackendContext) : FileLoweringPass, IrBuildingTransformer(context) { override fun lower(irFile: IrFile) { irFile.transformChildren(this, null) } private fun IrType.erasure(): IrType = this.erasureForTypeOperation() private fun lowerCast(expression: IrTypeOperatorCall): IrExpression { builder.at(expression) val typeOperand = expression.typeOperand.erasure() // assert (!TypeUtils.hasNullableSuperType(typeOperand)) // So that `isNullable()` <=> `isMarkedNullable`. // TODO: consider the case when expression type is wrong e.g. due to generics-related unchecked casts. return when { expression.argument.type.isSubtypeOf(typeOperand) -> expression.argument expression.argument.type.containsNull() -> { with(builder) { irLetS(expression.argument) { argument -> irIfThenElse( type = expression.type, condition = irEqeqeq(irGet(argument.owner), irNull()), thenPart = if (typeOperand.isSimpleTypeWithQuestionMark) irNull() else irCall(this@TypeOperatorLowering.context.ir.symbols.throwNullPointerException.owner), elsePart = irAs(irGet(argument.owner), typeOperand.makeNotNull()) ) } } } typeOperand.isSimpleTypeWithQuestionMark -> builder.irAs(expression.argument, typeOperand.makeNotNull()) typeOperand == expression.typeOperand -> expression else -> builder.irAs(expression.argument, typeOperand) } } private fun lowerSafeCast(expression: IrTypeOperatorCall): IrExpression { val typeOperand = expression.typeOperand.erasure() return builder.irBlock(expression) { +irLetS(expression.argument) { variable -> irIfThenElse(expression.type, condition = irIs(irGet(variable.owner), typeOperand), thenPart = irImplicitCast(irGet(variable.owner), typeOperand), elsePart = irNull()) } } } override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression { expression.transformChildrenVoid(this) return when (expression.operator) { IrTypeOperator.SAFE_CAST -> lowerSafeCast(expression) IrTypeOperator.CAST -> lowerCast(expression) else -> expression } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/VarargLowering.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.KonanBackendContext import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.util.OperatorNameConventions internal class VarargInjectionLowering constructor(val context: KonanBackendContext): DeclarationContainerLoweringPass { override fun lower(irDeclarationContainer: IrDeclarationContainer) { irDeclarationContainer.declarations.forEach{ when (it) { is IrField -> lower(it.symbol, it.initializer) is IrFunction -> lower(it.symbol, it.body) is IrProperty -> { it.backingField?.let { field -> lower(field.symbol, field) } it.getter?.let { getter -> lower(getter.symbol, getter) } it.setter?.let { setter -> lower(setter.symbol, setter) } } } } } private fun lower(owner: IrSymbol, element: IrElement?) { element?.transformChildrenVoid(object: IrElementTransformerVoid() { override fun visitClass(declaration: IrClass): IrStatement { // Skip nested. return declaration } val transformer = this private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) { val callee = expression.symbol.owner log { "call of: ${callee.fqNameForIrSerialization}" } context.createIrBuilder(owner, expression.startOffset, expression.endOffset).apply { callee.valueParameters.forEach { log { "varargElementType: ${it.varargElementType} expr: ${ir2string(expression.getValueArgument(it.index))}" } } callee.valueParameters .filter { it.varargElementType != null && expression.getValueArgument(it.index) == null } .forEach { expression.putValueArgument( it.index, IrVarargImpl( startOffset = startOffset, endOffset = endOffset, type = it.type, varargElementType = it.varargElementType!! ) ) } } expression.transformChildrenVoid(this) } override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression { replaceEmptyParameterWithEmptyArray(expression) return expression } override fun visitVararg(expression: IrVararg): IrExpression { expression.transformChildrenVoid(transformer) val hasSpreadElement = hasSpreadElement(expression) val irBuilder = context.createIrBuilder(owner, expression.startOffset, expression.endOffset) return irBuilder.irBlock(expression, null, expression.type) { val type = expression.varargElementType log { "$expression: array type:$type, is array of primitives ${!expression.type.isArray()}" } val arrayHandle = arrayType(expression.type) val vars = expression.elements.map { it to irTemporary( (it as? IrSpreadElement)?.expression ?: it as IrExpression, "elem".synthesizedString, isMutable = true ) }.toMap() val arraySize = calculateArraySize(arrayHandle, hasSpreadElement, scope, expression, vars) val array = arrayHandle.createArray(this, expression.varargElementType, arraySize) val arrayTmpVariable = irTemporary(array, "array".synthesizedString, isMutable = true) lateinit var indexTmpVariable: IrVariable if (hasSpreadElement) indexTmpVariable = irTemporary(kIntZero, "index".synthesizedString, isMutable = true) expression.elements.forEachIndexed { i, element -> irBuilder.at(element.startOffset, element.endOffset) log { "element:$i> ${ir2string(element)}" } val dst = vars[element]!! if (element !is IrSpreadElement) { +irCall(arrayHandle.setMethodSymbol.owner).apply { dispatchReceiver = irGet(arrayTmpVariable) putValueArgument(0, if (hasSpreadElement) irGet(indexTmpVariable) else irConstInt(i)) putValueArgument(1, irGet(dst)) } if (hasSpreadElement) +incrementVariable(indexTmpVariable, kIntOne) } else { val arraySizeVariable = irTemporary(irArraySize(arrayHandle, irGet(dst)), "length".synthesizedString) +irCall(arrayHandle.copyIntoSymbol.owner).apply { extensionReceiver = irGet(dst) putValueArgument(0, irGet(arrayTmpVariable)) /* destination */ putValueArgument(1, irGet(indexTmpVariable)) /* destinationOffset */ putValueArgument(2, kIntZero) /* startIndex */ putValueArgument(3, irGet(arraySizeVariable)) /* endIndex */ } +incrementVariable(indexTmpVariable, irGet(arraySizeVariable)) log { "element:$i:spread element> ${ir2string(element.expression)}" } } } +irGet(arrayTmpVariable) } } }) } private val symbols = context.ir.symbols private val intPlusInt = symbols.getBinaryOperator( OperatorNameConventions.PLUS, context.irBuiltIns.intType, context.irBuiltIns.intType ).owner private fun arrayType(type: IrType): ArrayHandle { val arrayClass = type.classifierOrFail return arrayToHandle[arrayClass] ?: error(arrayClass.descriptor) } private fun IrBuilderWithScope.intPlus() = irCall(intPlusInt) private fun IrBuilderWithScope.increment(expression: IrExpression, value: IrExpression): IrExpression { return intPlus().apply { dispatchReceiver = expression putValueArgument(0, value) } } private fun IrBuilderWithScope.incrementVariable(variable: IrVariable, value: IrExpression): IrExpression { return irSet(variable.symbol, intPlus().apply { dispatchReceiver = irGet(variable) putValueArgument(0, value) }) } private fun calculateArraySize(arrayHandle: ArrayHandle, hasSpreadElement: Boolean, scope:Scope, expression: IrVararg, vars: Map): IrExpression { context.createIrBuilder(scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset).run { if (!hasSpreadElement) return irConstInt(expression.elements.size) val notSpreadElementCount = expression.elements.filter { it !is IrSpreadElement}.size val initialValue = irConstInt(notSpreadElementCount) as IrExpression return vars.filter{it.key is IrSpreadElement}.toList().fold( initial = initialValue) { result, it -> val arraySize = irArraySize(arrayHandle, irGet(it.second)) increment(result, arraySize) } } } private fun IrBuilderWithScope.irArraySize(arrayHandle: ArrayHandle, expression: IrExpression): IrExpression { val arraySize = irCall(arrayHandle.sizeGetterSymbol.owner).apply { dispatchReceiver = expression } return arraySize } private fun hasSpreadElement(expression: IrVararg?) = expression?.elements?.any { it is IrSpreadElement }?:false private fun log(msg:() -> String) { context.log { "VARARG-INJECTOR: ${msg()}" } } abstract inner class ArrayHandle(val arraySymbol: IrClassSymbol) { val setMethodSymbol = arraySymbol.functions.single { it.descriptor.name == OperatorNameConventions.SET } val sizeGetterSymbol = arraySymbol.getPropertyGetter("size")!! val copyIntoSymbol = symbols.copyInto[arraySymbol.descriptor]!! protected val singleParameterConstructor = arraySymbol.owner.constructors.find { it.valueParameters.size == 1 }!! abstract fun createArray(builder: IrBuilderWithScope, elementType: IrType, size: IrExpression): IrExpression } inner class ReferenceArrayHandle : ArrayHandle(symbols.array) { override fun createArray(builder: IrBuilderWithScope, elementType: IrType, size: IrExpression): IrExpression { return builder.irCall(singleParameterConstructor).apply { putTypeArgument(0, elementType) putValueArgument(0, size) } } } inner class PrimitiveArrayHandle(primitiveType: PrimitiveType) : ArrayHandle(symbols.primitiveArrays[primitiveType]!!) { override fun createArray(builder: IrBuilderWithScope, elementType: IrType, size: IrExpression): IrExpression { return builder.irCall(singleParameterConstructor).apply { putValueArgument(0, size) } } } inner class UnsignedArrayHandle( arraySymbol: IrClassSymbol, private val wrappedArrayHandle: PrimitiveArrayHandle ) : ArrayHandle(arraySymbol) { override fun createArray(builder: IrBuilderWithScope, elementType: IrType, size: IrExpression): IrExpression { val wrappedArray = wrappedArrayHandle.createArray(builder, elementType, size) return builder.irCall(singleParameterConstructor).apply { putValueArgument(0, wrappedArray) } } } private val primitiveArrayHandles = PrimitiveType.values().associate { it to PrimitiveArrayHandle(it) } private val unsignedArrayHandles = UnsignedType.values().mapNotNull { unsignedType -> symbols.unsignedArrays[unsignedType]?.let { val primitiveType = when (unsignedType) { UnsignedType.UBYTE -> PrimitiveType.BYTE UnsignedType.USHORT -> PrimitiveType.SHORT UnsignedType.UINT -> PrimitiveType.INT UnsignedType.ULONG -> PrimitiveType.LONG } UnsignedArrayHandle(it, primitiveArrayHandles[primitiveType]!!) } } val arrayToHandle = (primitiveArrayHandles.values + unsignedArrayHandles + ReferenceArrayHandle()).associateBy { it.arraySymbol } } private fun IrBuilderWithScope.irConstInt(value: Int): IrConst = IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value) private val IrBuilderWithScope.kIntZero get() = irConstInt(0) private val IrBuilderWithScope.kIntOne get() = irConstInt(1) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/matchers/IrCallMatcher.kt ================================================ package org.jetbrains.kotlin.backend.konan.lower.matchers import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin internal interface IrCallMatcher : (IrCall) -> Boolean /** * IrCallMatcher that puts restrictions only on its callee. */ internal class SimpleCalleeMatcher( restrictions: IrFunctionMatcherContainer.() -> Unit ) : IrCallMatcher { private val calleeRestriction: IrFunctionMatcher = createIrFunctionRestrictions(restrictions) override fun invoke(call: IrCall) = calleeRestriction(call.symbol.owner) } internal class IrCallExtensionReceiverMatcher( val restriction: (IrExpression?) -> Boolean ) : IrCallMatcher { override fun invoke(call: IrCall) = restriction(call.extensionReceiver) } internal class IrCallDispatchReceiverMatcher( val restriction: (IrExpression?) -> Boolean ) : IrCallMatcher { override fun invoke(call: IrCall) = restriction(call.dispatchReceiver) } internal class IrCallOriginMatcher( val restriction: (IrStatementOrigin?) -> Boolean ) : IrCallMatcher { override fun invoke(call: IrCall) = restriction(call.origin) } internal open class IrCallMatcherContainer : IrCallMatcher { private val matchers = mutableListOf() fun add(matcher: IrCallMatcher) { matchers += matcher } fun extensionReceiver(restriction: (IrExpression?) -> Boolean) = add(IrCallExtensionReceiverMatcher(restriction)) fun origin(restriction: (IrStatementOrigin?) -> Boolean) = add(IrCallOriginMatcher(restriction)) fun callee(restrictions: IrFunctionMatcherContainer.() -> Unit) { add(SimpleCalleeMatcher(restrictions)) } fun dispatchReceiver(restriction: (IrExpression?) -> Boolean) = add(IrCallDispatchReceiverMatcher(restriction)) override fun invoke(call: IrCall) = matchers.all { it(call) } } internal fun createIrCallMatcher(restrictions: IrCallMatcherContainer.() -> Unit) = IrCallMatcherContainer().apply(restrictions) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/matchers/IrFunctionMatcher.kt ================================================ package org.jetbrains.kotlin.backend.konan.lower.matchers import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.name.FqName internal interface IrFunctionMatcher : (IrFunction) -> Boolean internal class ParameterMatcher( val index: Int, val restriction: (IrValueParameter) -> Boolean ) : IrFunctionMatcher { override fun invoke(function: IrFunction): Boolean { val params = function.valueParameters return params.size > index && restriction(params[index]) } } internal class DispatchReceiverMatcher( val restriction: (IrValueParameter?) -> Boolean ) : IrFunctionMatcher { override fun invoke(function: IrFunction): Boolean { return restriction(function.dispatchReceiverParameter) } } internal class ExtensionReceiverMatcher( val restriction: (IrValueParameter?) -> Boolean ) : IrFunctionMatcher { override fun invoke(function: IrFunction): Boolean { return restriction(function.extensionReceiverParameter) } } internal class ParameterCountMatcher( val restriction: (Int) -> Boolean ) : IrFunctionMatcher { override fun invoke(function: IrFunction): Boolean { return restriction(function.valueParameters.size) } } internal class FqNameMatcher( val restriction: (FqName) -> Boolean ) : IrFunctionMatcher { override fun invoke(function: IrFunction): Boolean { return restriction(function.fqNameForIrSerialization) } } internal open class IrFunctionMatcherContainer : IrFunctionMatcher { private val restrictions = mutableListOf() fun add(restriction: IrFunctionMatcher) { restrictions += restriction } fun fqName(restriction: (FqName) -> Boolean) = add(FqNameMatcher(restriction)) fun parameterCount(restriction: (Int) -> Boolean) = add(ParameterCountMatcher(restriction)) fun extensionReceiver(restriction: (IrValueParameter?) -> Boolean) = add(ExtensionReceiverMatcher(restriction)) fun dispatchReceiver(restriction: (IrValueParameter?) -> Boolean) = add(DispatchReceiverMatcher(restriction)) fun parameter(index: Int, restriction: (IrValueParameter) -> Boolean) = add(ParameterMatcher(index, restriction)) override fun invoke(function: IrFunction) = restrictions.all { it(function) } } internal fun createIrFunctionRestrictions(restrictions: IrFunctionMatcherContainer.() -> Unit) = IrFunctionMatcherContainer().apply(restrictions) internal fun IrFunctionMatcherContainer.singleArgumentExtension( fqName: FqName, classes: Collection ): IrFunctionMatcherContainer { extensionReceiver { it != null && it.type.classifierOrNull in classes } parameterCount { it == 1 } fqName { it == fqName } return this } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/CustomTypeMapper.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import org.jetbrains.kotlin.builtins.getFunctionalClassKind import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils internal fun ClassDescriptor.isMappedFunctionClass() = this.getFunctionalClassKind() == FunctionClassKind.Function && // Type parameters include return type. declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit internal interface CustomTypeMapper { val mappedClassId: ClassId fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType } internal object CustomTypeMappers { /** * Custom type mappers. * * Don't forget to update [hiddenTypes] after adding new one. */ private val predefined: Map = with(StandardNames.FqNames) { val result = mutableListOf() result += Collection(list, "NSArray") result += Collection(mutableList, "NSMutableArray") result += Collection(set, "NSSet") result += Collection(mutableSet, { namer.mutableSetName.objCName }) result += Collection(map, "NSDictionary") result += Collection(mutableMap, { namer.mutableMapName.objCName }) NSNumberKind.values().forEach { // TODO: NSNumber seem to have different equality semantics. val classId = it.mappedKotlinClassId if (classId != null) { result += Simple(classId, { namer.numberBoxName(classId).objCName }) } } result += Simple(ClassId.topLevel(string.toSafe()), "NSString") result.associateBy { it.mappedClassId } } internal val functionTypeMappersArityLimit = 33 // not including, i.e. [0..33) fun hasMapper(descriptor: ClassDescriptor): Boolean { // Should be equivalent to `getMapper(descriptor) != null`. if (descriptor.classId in predefined) return true if (descriptor.isMappedFunctionClass()) return true return false } fun getMapper(descriptor: ClassDescriptor): CustomTypeMapper? { val classId = descriptor.classId predefined[classId]?.let { return it } if (descriptor.isMappedFunctionClass()) { // TODO: somewhat hacky, consider using FunctionClassDescriptor.arity later. val arity = descriptor.declaredTypeParameters.size - 1 // Type parameters include return type. assert(classId == StandardNames.getFunctionClassId(arity)) return Function(arity) } return null } /** * Types to be "hidden" during mapping, i.e. represented as `id`. * * Currently contains super types of classes handled by custom type mappers. * Note: can be generated programmatically, but requires stdlib in this case. */ val hiddenTypes: Set = listOf( "kotlin.Any", "kotlin.CharSequence", "kotlin.Comparable", "kotlin.Function", "kotlin.Number", "kotlin.collections.Collection", "kotlin.collections.Iterable", "kotlin.collections.MutableCollection", "kotlin.collections.MutableIterable" ).map { ClassId.topLevel(FqName(it)) }.toSet() private class Simple( override val mappedClassId: ClassId, private val getObjCClassName: ObjCExportTranslatorImpl.() -> String ) : CustomTypeMapper { constructor( mappedClassId: ClassId, objCClassName: String ) : this(mappedClassId, { objCClassName }) override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType = ObjCClassType(translator.getObjCClassName()) } private class Collection( mappedClassFqName: FqName, private val getObjCClassName: ObjCExportTranslatorImpl.() -> String ) : CustomTypeMapper { constructor( mappedClassFqName: FqName, objCClassName: String ) : this(mappedClassFqName, { objCClassName }) override val mappedClassId = ClassId.topLevel(mappedClassFqName) override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { val typeArguments = mappedSuperType.arguments.map { val argument = it.type if (TypeUtils.isNullableType(argument)) { // Kotlin `null` keys and values are represented as `NSNull` singleton. ObjCIdType } else { translator.mapReferenceTypeIgnoringNullability(argument, objCExportScope) } } return ObjCClassType(translator.getObjCClassName(), typeArguments) } } private class Function(private val parameterCount: Int) : CustomTypeMapper { override val mappedClassId: ClassId get() = StandardNames.getFunctionClassId(parameterCount) override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { return translator.mapFunctionTypeIgnoringNullability(mappedSuperType, objCExportScope, returnsVoid = false) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/MethodBridge.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter internal sealed class TypeBridge internal object ReferenceBridge : TypeBridge() internal data class BlockPointerBridge( val numberOfParameters: Int, val returnsVoid: Boolean ) : TypeBridge() internal data class ValueTypeBridge(val objCValueType: ObjCValueType) : TypeBridge() internal sealed class MethodBridgeParameter internal sealed class MethodBridgeReceiver : MethodBridgeParameter() { object Static : MethodBridgeReceiver() object Factory : MethodBridgeReceiver() object Instance : MethodBridgeReceiver() } internal object MethodBridgeSelector : MethodBridgeParameter() internal sealed class MethodBridgeValueParameter : MethodBridgeParameter() { data class Mapped(val bridge: TypeBridge) : MethodBridgeValueParameter() object ErrorOutParameter : MethodBridgeValueParameter() object SuspendCompletion : MethodBridgeValueParameter() } internal data class MethodBridge( val returnBridge: ReturnValue, val receiver: MethodBridgeReceiver, val valueParameters: List ) { sealed class ReturnValue { object Void : ReturnValue() object HashCode : ReturnValue() data class Mapped(val bridge: TypeBridge) : ReturnValue() sealed class Instance : ReturnValue() { object InitResult : Instance() object FactoryResult : Instance() } sealed class WithError : ReturnValue() { object Success : WithError() data class ZeroForError(val successBridge: ReturnValue, val successMayBeZero: Boolean) : WithError() } object Suspend : ReturnValue() } val paramBridges: List = listOf(receiver) + MethodBridgeSelector + valueParameters // TODO: it is not exactly true in potential future cases. val isInstance: Boolean get() = when (receiver) { MethodBridgeReceiver.Static, MethodBridgeReceiver.Factory -> false MethodBridgeReceiver.Instance -> true } val returnsError: Boolean get() = returnBridge is ReturnValue.WithError } internal fun MethodBridge.valueParametersAssociated( descriptor: FunctionDescriptor ): List> { val kotlinParameters = descriptor.allParameters.iterator() val skipFirstKotlinParameter = when (this.receiver) { MethodBridgeReceiver.Static -> false MethodBridgeReceiver.Factory, MethodBridgeReceiver.Instance -> true } if (skipFirstKotlinParameter) { kotlinParameters.next() } return this.valueParameters.map { when (it) { is MethodBridgeValueParameter.Mapped -> it to kotlinParameters.next() MethodBridgeValueParameter.SuspendCompletion, is MethodBridgeValueParameter.ErrorOutParameter -> it to null } }.also { assert(!kotlinParameters.hasNext()) } } internal fun MethodBridge.parametersAssociated( irFunction: IrFunction ): List> { val kotlinParameters = irFunction.allParameters.iterator() return this.paramBridges.map { when (it) { is MethodBridgeValueParameter.Mapped, MethodBridgeReceiver.Instance -> it to kotlinParameters.next() MethodBridgeValueParameter.SuspendCompletion, MethodBridgeReceiver.Static, MethodBridgeSelector, MethodBridgeValueParameter.ErrorOutParameter -> it to null MethodBridgeReceiver.Factory -> { kotlinParameters.next() it to null } } }.also { assert(!kotlinParameters.hasNext()) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.getExportedDependencies import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.createTempFile import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.isSubpackageOf internal class ObjCExportedInterface( val generatedClasses: Set, val categoryMembers: Map>, val topLevel: Map>, val headerLines: List, val namer: ObjCExportNamer, val mapper: ObjCExportMapper ) internal class ObjCExport(val context: Context, symbolTable: SymbolTable) { private val target get() = context.config.target private val exportedInterface = produceInterface() private val codeSpec = exportedInterface?.createCodeSpec(symbolTable) private fun produceInterface(): ObjCExportedInterface? { if (!target.family.isAppleFamily) return null if (!context.config.produce.isFinalBinary) return null // TODO: emit RTTI to the same modules as classes belong to. // Not possible yet, since ObjCExport translates the entire "world" API at once // and can't do this per-module, e.g. due to global name conflict resolution. val produceFramework = context.config.produce == CompilerOutputKind.FRAMEWORK return if (produceFramework) { val mapper = ObjCExportMapper(context.frontendServices.deprecationResolver) val moduleDescriptors = listOf(context.moduleDescriptor) + context.getExportedDependencies() val objcGenerics = context.configuration.getBoolean(KonanConfigKeys.OBJC_GENERICS) val namer = ObjCExportNamerImpl( moduleDescriptors.toSet(), context.moduleDescriptor.builtIns, mapper, context.moduleDescriptor.namePrefix, local = false, objcGenerics = objcGenerics ) val headerGenerator = ObjCExportHeaderGeneratorImpl(context, moduleDescriptors, mapper, namer, objcGenerics) headerGenerator.translateModule() headerGenerator.buildInterface() } else { null } } lateinit var namer: ObjCExportNamer internal fun generate(codegen: CodeGenerator) { if (!target.family.isAppleFamily) return if (context.producedLlvmModuleContainsStdlib) { ObjCExportBlockCodeGenerator(codegen).generate() } if (!context.config.produce.isFinalBinary) return // TODO: emit RTTI to the same modules as classes belong to. val mapper = exportedInterface?.mapper ?: ObjCExportMapper() namer = exportedInterface?.namer ?: ObjCExportNamerImpl( setOf(codegen.context.moduleDescriptor), context.moduleDescriptor.builtIns, mapper, context.moduleDescriptor.namePrefix, local = false ) val objCCodeGenerator = ObjCExportCodeGenerator(codegen, namer, mapper) if (exportedInterface != null) { produceFrameworkSpecific(exportedInterface.headerLines) exportedInterface.generateWorkaroundForSwiftSR10177() } objCCodeGenerator.generate(codeSpec) objCCodeGenerator.dispose() } private fun produceFrameworkSpecific(headerLines: List) { val framework = File(context.config.outputFile) val frameworkContents = when(target.family) { Family.IOS, Family.WATCHOS, Family.TVOS -> framework Family.OSX -> framework.child("Versions/A") else -> error(target) } val headers = frameworkContents.child("Headers") val frameworkName = framework.name.removeSuffix(".framework") val headerName = frameworkName + ".h" val header = headers.child(headerName) headers.mkdirs() header.writeLines(headerLines) val modules = frameworkContents.child("Modules") modules.mkdirs() val moduleMap = """ |framework module $frameworkName { | umbrella header "$headerName" | | export * | module * { export * } |} """.trimMargin() modules.child("module.modulemap").writeBytes(moduleMap.toByteArray()) emitInfoPlist(frameworkContents, frameworkName) if (target.family == Family.OSX) { framework.child("Versions/Current").createAsSymlink("A") for (child in listOf(frameworkName, "Headers", "Modules", "Resources")) { framework.child(child).createAsSymlink("Versions/Current/$child") } } } private fun emitInfoPlist(frameworkContents: File, name: String) { val directory = when (target.family) { Family.IOS, Family.WATCHOS, Family.TVOS -> frameworkContents Family.OSX -> frameworkContents.child("Resources").also { it.mkdirs() } else -> error(target) } val file = directory.child("Info.plist") val pkg = guessMainPackage() // TODO: consider showing warning if it is root. val bundleId = pkg.child(Name.identifier(name)).asString() val platform = when (target) { KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64 -> "iPhoneOS" KonanTarget.IOS_X64 -> "iPhoneSimulator" KonanTarget.TVOS_ARM64 -> "AppleTVOS" KonanTarget.TVOS_X64 -> "AppleTVSimulator" KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64 -> "MacOSX" KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_ARM64 -> "WatchOS" KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64 -> "WatchSimulator" else -> error(target) } val properties = context.config.platform.configurables as AppleConfigurables val minimumOsVersion = properties.osVersionMin val contents = StringBuilder() contents.append(""" CFBundleExecutable $name CFBundleIdentifier $bundleId CFBundleInfoDictionaryVersion 6.0 CFBundleName $name CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSupportedPlatforms $platform CFBundleVersion 1 """.trimIndent()) fun addUiDeviceFamilies(vararg values: Int) { val xmlValues = values.joinToString(separator = "\n") { " $it" } contents.append(""" | MinimumOSVersion | $minimumOsVersion | UIDeviceFamily | |$xmlValues | """.trimMargin()) } // UIDeviceFamily mapping: // 1 - iPhone // 2 - iPad // 3 - AppleTV // 4 - Apple Watch when (target.family) { Family.IOS -> addUiDeviceFamilies(1, 2) Family.TVOS -> addUiDeviceFamilies(3) Family.WATCHOS -> addUiDeviceFamilies(4) else -> {} } if (target == KonanTarget.IOS_ARM64) { contents.append(""" | UIRequiredDeviceCapabilities | | arm64 | """.trimMargin() ) } if (target == KonanTarget.IOS_ARM32) { contents.append(""" | UIRequiredDeviceCapabilities | | armv7 | """.trimMargin() ) } contents.append(""" """.trimIndent()) // TODO: Xcode also add some number of DT* keys. file.writeBytes(contents.toString().toByteArray()) } // See https://bugs.swift.org/browse/SR-10177 private fun ObjCExportedInterface.generateWorkaroundForSwiftSR10177() { // Code for all protocols from the header should get into the binary. // Objective-C protocols ABI is complicated (consider e.g. undocumented extended type encoding), // so the easiest way to achieve this (quickly) is to compile a stub by clang. val protocolsStub = listOf( "__attribute__((used)) static void __workaroundSwiftSR10177() {", buildString { append(" ") generatedClasses.forEach { if (it.isInterface) { val protocolName = namer.getClassOrProtocolName(it).objCName append("@protocol($protocolName); ") } } }, "}" ) val source = createTempFile("protocols", ".m").deleteOnExit() source.writeLines(headerLines + protocolsStub) val bitcode = createTempFile("protocols", ".bc").deleteOnExit() val clangCommand = context.config.clang.clangC( source.absolutePath, "-O2", "-emit-llvm", "-c", "-o", bitcode.absolutePath ) val result = Command(clangCommand).getResult(withErrors = true) if (result.exitCode == 0) { context.llvm.additionalProducedBitcodeFiles += bitcode.absolutePath } else { // Note: ignoring compile errors intentionally. // In this case resulting framework will likely be unusable due to compile errors when importing it. } } private fun guessMainPackage(): FqName { val allPackages = (context.getIncludedLibraryDescriptors() + context.moduleDescriptor).flatMap { it.getPackageFragments() // Includes also all parent packages, e.g. the root one. } val nonEmptyPackages = allPackages .filter { it.getMemberScope().getContributedDescriptors().isNotEmpty() } .map { it.fqName }.distinct() return allPackages.map { it.fqName }.distinct() .filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } } // Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor: .maxByOrNull { it.asString().length }!! } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportCodeSpec.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.konan.descriptors.contributedMethods import org.jetbrains.kotlin.backend.konan.descriptors.enumEntries import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny internal fun ObjCExportedInterface.createCodeSpec(symbolTable: SymbolTable): ObjCExportCodeSpec { fun createObjCMethods(methods: List) = methods.map { ObjCMethodForKotlinMethod( createObjCMethodSpecBaseMethod( mapper, namer, symbolTable.referenceSimpleFunction(it), it ) ) } fun List.toObjCMethods() = createObjCMethods(this.flatMap { when (it) { is PropertyDescriptor -> listOfNotNull( it.getter, it.setter?.takeIf(mapper::shouldBeExposed) // Similar to [ObjCExportTranslatorImpl.buildProperty]. ) is FunctionDescriptor -> listOf(it) else -> error(it) } }) val files = topLevel.map { (sourceFile, declarations) -> val binaryName = namer.getFileClassName(sourceFile).binaryName val methods = declarations.toObjCMethods() ObjCClassForKotlinFile(binaryName, methods) } val classToType = mutableMapOf() fun getType(descriptor: ClassDescriptor): ObjCTypeForKotlinType = classToType.getOrPut(descriptor) { val methods = mutableListOf() // Note: contributedMethods includes fake overrides too. val allBaseMethods = descriptor.contributedMethods.filter { mapper.shouldBeExposed(it) } .flatMap { mapper.getBaseMethods(it) }.distinct() methods += createObjCMethods(allBaseMethods) val binaryName = namer.getClassOrProtocolName(descriptor).binaryName val irClassSymbol = symbolTable.referenceClass(descriptor) if (descriptor.isInterface) { ObjCProtocolForKotlinInterface(binaryName, irClassSymbol, methods) } else { descriptor.constructors.filter { mapper.shouldBeExposed(it) }.mapTo(methods) { val irConstructorSymbol = symbolTable.referenceConstructor(it) val baseMethod = createObjCMethodSpecBaseMethod(mapper, namer, irConstructorSymbol, it) if (descriptor.isArray) { ObjCFactoryMethodForKotlinArrayConstructor(baseMethod) } else { ObjCInitMethodForKotlinConstructor(baseMethod) } } if (descriptor.kind == ClassKind.OBJECT) { methods += ObjCGetterForObjectInstance(namer.getObjectInstanceSelector(descriptor)) } if (descriptor.kind == ClassKind.ENUM_CLASS) { descriptor.enumEntries.mapTo(methods) { ObjCGetterForKotlinEnumEntry(symbolTable.referenceEnumEntry(it), namer.getEnumEntrySelector(it)) } descriptor.getEnumValuesFunctionDescriptor()?.let { methods += ObjCClassMethodForKotlinEnumValues( symbolTable.referenceSimpleFunction(it), namer.getEnumValuesSelector(it) ) } } val categoryMethods = categoryMembers[descriptor].orEmpty().toObjCMethods() val superClassNotAny = descriptor.getSuperClassNotAny() ?.let { getType(it) as ObjCClassForKotlinClass } ObjCClassForKotlinClass(binaryName, irClassSymbol, methods, categoryMethods, superClassNotAny) } } val types = generatedClasses.map { getType(it) } return ObjCExportCodeSpec(files, types) } internal fun createObjCMethodSpecBaseMethod( mapper: ObjCExportMapper, namer: ObjCExportNamer, symbol: S, descriptor: FunctionDescriptor ): ObjCMethodSpec.BaseMethod { require(mapper.isBaseMethod(descriptor)) val selector = namer.getSelector(descriptor) val bridge = mapper.bridgeMethod(descriptor) return ObjCMethodSpec.BaseMethod(symbol, bridge, selector) } internal class ObjCExportCodeSpec( val files: List, val types: List ) internal sealed class ObjCMethodSpec { /** * Aggregates base method (as defined by [ObjCExportMapper.isBaseMethod]) * and details required to generate code for bridges between Kotlin and Obj-C methods. */ data class BaseMethod(val symbol: S, val bridge: MethodBridge, val selector: String) } internal class ObjCMethodForKotlinMethod(val baseMethod: BaseMethod) : ObjCMethodSpec() internal class ObjCInitMethodForKotlinConstructor(val baseMethod: BaseMethod) : ObjCMethodSpec() internal class ObjCFactoryMethodForKotlinArrayConstructor( val baseMethod: BaseMethod ) : ObjCMethodSpec() internal class ObjCGetterForKotlinEnumEntry( val irEnumEntrySymbol: IrEnumEntrySymbol, val selector: String ) : ObjCMethodSpec() internal class ObjCClassMethodForKotlinEnumValues( val valuesFunctionSymbol: IrFunctionSymbol, val selector: String ) : ObjCMethodSpec() internal class ObjCGetterForObjectInstance(val selector: String) : ObjCMethodSpec() internal sealed class ObjCTypeSpec(val binaryName: String) internal sealed class ObjCTypeForKotlinType( binaryName: String, val irClassSymbol: IrClassSymbol, val methods: List ) : ObjCTypeSpec(binaryName) internal class ObjCClassForKotlinClass( binaryName: String, irClassSymbol: IrClassSymbol, methods: List, val categoryMethods: List, val superClassNotAny: ObjCClassForKotlinClass? ) : ObjCTypeForKotlinType(binaryName, irClassSymbol, methods) internal class ObjCProtocolForKotlinInterface( binaryName: String, irClassSymbol: IrClassSymbol, methods: List ) : ObjCTypeForKotlinType(binaryName, irClassSymbol, methods) internal class ObjCClassForKotlinFile( binaryName: String, val methods: List ) : ObjCTypeSpec(binaryName) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGenerator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.common.serialization.findSourceFile import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.deprecation.Deprecation import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.isInterface import org.jetbrains.kotlin.types.typeUtil.isTypeParameter import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.addIfNotNull interface ObjCExportTranslator { fun generateBaseDeclarations(): List> fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor? fun translateFile(file: SourceFile, declarations: List): ObjCInterface fun translateClass(descriptor: ClassDescriptor): ObjCInterface fun translateInterface(descriptor: ClassDescriptor): ObjCProtocol fun translateExtensions(classDescriptor: ClassDescriptor, declarations: List): ObjCInterface } interface ObjCExportProblemCollector { fun reportWarning(text: String) fun reportWarning(method: FunctionDescriptor, text: String) fun reportException(throwable: Throwable) object SILENT : ObjCExportProblemCollector { override fun reportWarning(text: String) {} override fun reportWarning(method: FunctionDescriptor, text: String) {} override fun reportException(throwable: Throwable) {} } } internal class ObjCExportTranslatorImpl( private val generator: ObjCExportHeaderGenerator?, val mapper: ObjCExportMapper, val namer: ObjCExportNamer, val problemCollector: ObjCExportProblemCollector, val objcGenerics: Boolean ) : ObjCExportTranslator { private val kotlinAnyName = namer.kotlinAnyName override fun generateBaseDeclarations(): List> = buildTopLevel { add { objCInterface(namer.kotlinAnyName, superClass = "NSObject", members = buildMembers { add { ObjCMethod(null, true, ObjCInstanceType, listOf("init"), emptyList(), listOf("unavailable")) } add { ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable")) } add { ObjCMethod(null, false, ObjCVoidType, listOf("initialize"), emptyList(), listOf("objc_requires_super")) } }) } // TODO: add comment to the header. add { ObjCInterfaceImpl( namer.kotlinAnyName.objCName, superProtocols = listOf("NSCopying"), categoryName = "${namer.kotlinAnyName.objCName}Copying" ) } // TODO: only if appears add { val generics = listOf("ObjectType") objCInterface( namer.mutableSetName, generics = generics, superClass = "NSMutableSet", superClassGenerics = generics ) } // TODO: only if appears add { val generics = listOf("KeyType", "ObjectType") objCInterface( namer.mutableMapName, generics = generics, superClass = "NSMutableDictionary", superClassGenerics = generics ) } val nsErrorCategoryName = "NSError${namer.topLevelNamePrefix}KotlinException" add { ObjCInterfaceImpl("NSError", categoryName = nsErrorCategoryName, members = buildMembers { add { ObjCProperty("kotlinException", null, ObjCNullableReferenceType(ObjCIdType), listOf("readonly")) } }) } genKotlinNumbers() } private fun StubBuilder>.genKotlinNumbers() { val members = buildMembers { NSNumberKind.values().forEach { add { nsNumberFactory(it, listOf("unavailable")) } } NSNumberKind.values().forEach { add { nsNumberInit(it, listOf("unavailable")) } } } add { objCInterface( namer.kotlinNumberName, superClass = "NSNumber", members = members ) } NSNumberKind.values().forEach { if (it.mappedKotlinClassId != null) add { genKotlinNumber(it.mappedKotlinClassId, it) } } } private fun genKotlinNumber(kotlinClassId: ClassId, kind: NSNumberKind): ObjCInterface { val name = namer.numberBoxName(kotlinClassId) val members = buildMembers { add { nsNumberFactory(kind) } add { nsNumberInit(kind) } } return objCInterface( name, superClass = namer.kotlinNumberName.objCName, members = members ) } private fun nsNumberInit(kind: NSNumberKind, attributes: List = emptyList()): ObjCMethod { return ObjCMethod( null, false, ObjCInstanceType, listOf(kind.factorySelector), listOf(ObjCParameter("value", null, kind.objCType)), attributes ) } private fun nsNumberFactory(kind: NSNumberKind, attributes: List = emptyList()): ObjCMethod { return ObjCMethod( null, true, ObjCInstanceType, listOf(kind.initSelector), listOf(ObjCParameter("value", null, kind.objCType)), attributes ) } override fun getClassIfExtension(receiverType: KotlinType): ClassDescriptor? = mapper.getClassIfCategory(receiverType) internal fun translateUnexposedClassAsUnavailableStub(descriptor: ClassDescriptor): ObjCInterface = objCInterface( namer.getClassOrProtocolName(descriptor), descriptor = descriptor, superClass = "NSObject", attributes = attributesForUnexposed(descriptor) ) internal fun translateUnexposedInterfaceAsUnavailableStub(descriptor: ClassDescriptor): ObjCProtocol = objCProtocol( namer.getClassOrProtocolName(descriptor), descriptor = descriptor, superProtocols = emptyList(), members = emptyList(), attributes = attributesForUnexposed(descriptor) ) private fun attributesForUnexposed(descriptor: ClassDescriptor): List { val message = when { descriptor.isKotlinObjCClass() -> "Kotlin subclass of Objective-C class " else -> "" } + "can't be imported" return listOf("unavailable(\"$message\")") } private fun referenceClass(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName { assert(mapper.shouldBeExposed(descriptor)) { "Shouldn't be exposed: $descriptor" } assert(!descriptor.isInterface) generator?.requireClassOrInterface(descriptor) return translateClassOrInterfaceName(descriptor).also { className -> val generics = mapTypeConstructorParameters(descriptor) val forwardDeclaration = ObjCClassForwardDeclaration(className.objCName, generics) generator?.referenceClass(forwardDeclaration) } } private fun referenceProtocol(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName { assert(mapper.shouldBeExposed(descriptor)) { "Shouldn't be exposed: $descriptor" } assert(descriptor.isInterface) generator?.requireClassOrInterface(descriptor) return translateClassOrInterfaceName(descriptor).also { generator?.referenceProtocol(it.objCName) } } private fun translateClassOrInterfaceName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName { assert(mapper.shouldBeExposed(descriptor)) { "Shouldn't be exposed: $descriptor" } if (ErrorUtils.isError(descriptor)) { return ObjCExportNamer.ClassOrProtocolName("ERROR", "ERROR") } return namer.getClassOrProtocolName(descriptor) } override fun translateInterface(descriptor: ClassDescriptor): ObjCProtocol { require(descriptor.isInterface) if (!mapper.shouldBeExposed(descriptor)) { return translateUnexposedInterfaceAsUnavailableStub(descriptor) } val name = translateClassOrInterfaceName(descriptor) val members: List> = buildMembers { translateInterfaceMembers(descriptor) } val superProtocols: List = descriptor.superProtocols return objCProtocol(name, descriptor, superProtocols, members) } private val ClassDescriptor.superProtocols: List get() = getSuperInterfaces() .asSequence() .filter { mapper.shouldBeExposed(it) } .map { generator?.generateExtraInterfaceEarly(it) referenceProtocol(it).objCName } .toList() override fun translateExtensions( classDescriptor: ClassDescriptor, declarations: List ): ObjCInterface { generator?.generateExtraClassEarly(classDescriptor) val name = referenceClass(classDescriptor).objCName val members = buildMembers { translatePlainMembers(declarations, ObjCNoneExportScope) } return ObjCInterfaceImpl(name, categoryName = "Extensions", members = members) } override fun translateFile(file: SourceFile, declarations: List): ObjCInterface { val name = namer.getFileClassName(file) // TODO: stop inheriting KotlinBase. val members = buildMembers { translatePlainMembers(declarations, ObjCNoneExportScope) } return objCInterface( name, superClass = namer.kotlinAnyName.objCName, members = members, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED) ) } override fun translateClass(descriptor: ClassDescriptor): ObjCInterface { require(!descriptor.isInterface) if (!mapper.shouldBeExposed(descriptor)) { return translateUnexposedClassAsUnavailableStub(descriptor) } val genericExportScope = if (objcGenerics) { ObjCClassExportScope(descriptor, namer) } else { ObjCNoneExportScope } fun superClassGenerics(genericExportScope: ObjCExportScope): List { if (objcGenerics) { computeSuperClassType(descriptor)?.let { parentType -> return parentType.arguments.map { typeProjection -> mapReferenceTypeIgnoringNullability(typeProjection.type, genericExportScope) } } } return emptyList() } val superClass = descriptor.getSuperClassNotAny() val superName = if (superClass == null) { kotlinAnyName } else { generator?.generateExtraClassEarly(superClass) referenceClass(superClass) } val superProtocols: List = descriptor.superProtocols val members: List> = buildMembers { val presentConstructors = mutableSetOf() descriptor.constructors .asSequence() .filter { mapper.shouldBeExposed(it) } .forEach { val selector = getSelector(it) if (!descriptor.isArray) presentConstructors += selector add { buildMethod(it, it, genericExportScope) } exportThrown(it) if (selector == "init") add { ObjCMethod(it, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("availability(swift, unavailable, message=\"use object initializers instead\")")) } } if (descriptor.isArray || descriptor.kind == ClassKind.OBJECT || descriptor.kind == ClassKind.ENUM_CLASS) { add { ObjCMethod(null, false, ObjCInstanceType, listOf("alloc"), emptyList(), listOf("unavailable")) } val parameter = ObjCParameter("zone", null, ObjCRawType("struct _NSZone *")) add { ObjCMethod(descriptor, false, ObjCInstanceType, listOf("allocWithZone:"), listOf(parameter), listOf("unavailable")) } } // Hide "unimplemented" super constructors: superClass?.constructors ?.asSequence() ?.filter { mapper.shouldBeExposed(it) } ?.forEach { val selector = getSelector(it) if (selector !in presentConstructors) { add { buildMethod(it, it, ObjCNoneExportScope, unavailable = true) } if (selector == "init") { add { ObjCMethod(null, false, ObjCInstanceType, listOf("new"), emptyList(), listOf("unavailable")) } } // TODO: consider adding exception-throwing impls for these. } } // TODO: consider adding exception-throwing impls for these. when (descriptor.kind) { ClassKind.OBJECT -> add { ObjCMethod( null, false, ObjCInstanceType, listOf(namer.getObjectInstanceSelector(descriptor)), emptyList(), listOf(swiftNameAttribute("init()")) ) } ClassKind.ENUM_CLASS -> { val type = mapType(descriptor.defaultType, ReferenceBridge, ObjCNoneExportScope) descriptor.enumEntries.forEach { val entryName = namer.getEnumEntrySelector(it) add { ObjCProperty(entryName, it, type, listOf("class", "readonly"), declarationAttributes = listOf(swiftNameAttribute(entryName))) } } // Note: it is possible to support this function through a common machinery, // but it is very special (static and synthetic), so apparently it is much easier // to keep this ad hoc here than to add special cases to the most complicated parts // of the machinery. descriptor.getEnumValuesFunctionDescriptor()?.let { enumValues -> add { buildEnumValuesMethod(enumValues, genericExportScope) } } } else -> { // Nothing special. } } translateClassMembers(descriptor, genericExportScope) } val attributes = if (descriptor.isFinalOrEnum) listOf(OBJC_SUBCLASSING_RESTRICTED) else emptyList() val name = translateClassOrInterfaceName(descriptor) val generics = mapTypeConstructorParameters(descriptor) val superClassGenerics = superClassGenerics(genericExportScope) return objCInterface( name, generics = generics, descriptor = descriptor, superClass = superName.objCName, superClassGenerics = superClassGenerics, superProtocols = superProtocols, members = members, attributes = attributes ) } private fun mapTypeConstructorParameters(descriptor: ClassDescriptor): List { if (objcGenerics) { return descriptor.typeConstructor.parameters.map { ObjCGenericTypeParameterDeclaration(it, namer) } } return emptyList() } private fun buildEnumValuesMethod( enumValues: SimpleFunctionDescriptor, genericExportScope: ObjCExportScope ): ObjCMethod { val selector = namer.getEnumValuesSelector(enumValues) return ObjCMethod( enumValues, isInstanceMethod = false, returnType = mapReferenceType(enumValues.returnType!!, genericExportScope), selectors = splitSelector(selector), parameters = emptyList(), attributes = listOf(swiftNameAttribute("$selector()")) ) } private fun ClassDescriptor.getExposedMembers(): List = this.unsubstitutedMemberScope.getContributedDescriptors() .asSequence() .filterIsInstance() .filter { mapper.shouldBeExposed(it) } .toList() private fun StubBuilder>.translateClassMembers(descriptor: ClassDescriptor, objCExportScope: ObjCExportScope) { require(!descriptor.isInterface) translateClassMembers(descriptor.getExposedMembers(), objCExportScope) } private fun StubBuilder>.translateInterfaceMembers(descriptor: ClassDescriptor) { require(descriptor.isInterface) translateBaseMembers(descriptor.getExposedMembers()) } private fun List.toObjCMembers( methodsBuffer: MutableList, propertiesBuffer: MutableList ) = this.forEach { when (it) { is FunctionDescriptor -> methodsBuffer += it is PropertyDescriptor -> if (mapper.isObjCProperty(it)) { propertiesBuffer += it } else { methodsBuffer.addIfNotNull(it.getter) methodsBuffer.addIfNotNull(it.setter) } else -> error(it) } } private fun StubBuilder>.translateClassMembers( members: List, objCExportScope: ObjCExportScope ) { // TODO: add some marks about modality. val methods = mutableListOf() val properties = mutableListOf() members.toObjCMembers(methods, properties) methods.forEach { exportThrown(it) } methods.retainAll { it.kind.isReal } properties.retainAll { it.kind.isReal } methods.forEach { method -> mapper.getBaseMethods(method) .asSequence() .distinctBy { namer.getSelector(it) } .forEach { base -> add { buildMethod(method, base, objCExportScope) } } } properties.forEach { property -> mapper.getBaseProperties(property) .asSequence() .distinctBy { namer.getPropertyName(it) } .forEach { base -> add { buildProperty(property, base, objCExportScope) } } } } private fun StubBuilder>.translateBaseMembers(members: List) { // TODO: add some marks about modality. val methods = mutableListOf() val properties = mutableListOf() members.toObjCMembers(methods, properties) methods.forEach { exportThrown(it) } methods.retainAll { mapper.isBaseMethod(it) } properties.retainAll { if (mapper.isBaseProperty(it)) { true } else { methods.addIfNotNull(it.setter?.takeIf(mapper::isBaseMethod)) false } } translatePlainMembers(methods, properties, ObjCNoneExportScope) } private fun StubBuilder>.translatePlainMembers(members: List, objCExportScope: ObjCExportScope) { val methods = mutableListOf() val properties = mutableListOf() members.toObjCMembers(methods, properties) methods.forEach { exportThrown(it) } translatePlainMembers(methods, properties, objCExportScope) } private fun StubBuilder>.translatePlainMembers(methods: List, properties: List, objCExportScope: ObjCExportScope) { methods.forEach { add { buildMethod(it, it, objCExportScope) } } properties.forEach { add { buildProperty(it, it, objCExportScope) } } } // TODO: consider checking that signatures for bases with same selector/name are equal. private fun getSelector(method: FunctionDescriptor): String { return namer.getSelector(method) } private fun buildProperty(property: PropertyDescriptor, baseProperty: PropertyDescriptor, objCExportScope: ObjCExportScope): ObjCProperty { assert(mapper.isBaseProperty(baseProperty)) assert(mapper.isObjCProperty(baseProperty)) val getterBridge = mapper.bridgeMethod(baseProperty.getter!!) val type = mapReturnType(getterBridge.returnBridge, property.getter!!, objCExportScope) val name = namer.getPropertyName(baseProperty) val attributes = mutableListOf() if (!getterBridge.isInstance) { attributes += "class" } val setterName: String? val propertySetter = property.setter // Note: the condition below is similar to "toObjCMethods" logic in [ObjCExportedInterface.createCodeSpec]. if (propertySetter != null && mapper.shouldBeExposed(propertySetter)) { val setterSelector = mapper.getBaseMethods(propertySetter).map { namer.getSelector(it) }.distinct().single() setterName = if (setterSelector != "set" + name.capitalize() + ":") setterSelector else null } else { attributes += "readonly" setterName = null } val getterSelector = getSelector(baseProperty.getter!!) val getterName: String? = if (getterSelector != name) getterSelector else null val declarationAttributes = mutableListOf(swiftNameAttribute(name)) declarationAttributes.addIfNotNull(mapper.getDeprecation(property)?.toDeprecationAttribute()) return ObjCProperty(name, property, type, attributes, setterName, getterName, declarationAttributes) } private fun buildMethod( method: FunctionDescriptor, baseMethod: FunctionDescriptor, objCExportScope: ObjCExportScope, unavailable: Boolean = false ): ObjCMethod { fun collectParameters(baseMethodBridge: MethodBridge, method: FunctionDescriptor): List { fun unifyName(initialName: String, usedNames: Set): String { var unique = initialName.toValidObjCSwiftIdentifier() while (unique in usedNames || unique in cKeywords) { unique += "_" } return unique } val valueParametersAssociated = baseMethodBridge.valueParametersAssociated(method) val parameters = mutableListOf() val usedNames = mutableSetOf() valueParametersAssociated.forEach { (bridge: MethodBridgeValueParameter, p: ParameterDescriptor?) -> val candidateName: String = when (bridge) { is MethodBridgeValueParameter.Mapped -> { p!! when { p is ReceiverParameterDescriptor -> "receiver" method is PropertySetterDescriptor -> "value" else -> p.name.asString() } } MethodBridgeValueParameter.ErrorOutParameter -> "error" MethodBridgeValueParameter.SuspendCompletion -> "completionHandler" } val uniqueName = unifyName(candidateName, usedNames) usedNames += uniqueName val type = when (bridge) { is MethodBridgeValueParameter.Mapped -> mapType(p!!.type, bridge.bridge, objCExportScope) MethodBridgeValueParameter.ErrorOutParameter -> ObjCPointerType(ObjCNullableReferenceType(ObjCClassType("NSError")), nullable = true) MethodBridgeValueParameter.SuspendCompletion -> { ObjCBlockPointerType( returnType = ObjCVoidType, parameterTypes = listOf( mapReferenceType(method.returnType!!, objCExportScope).makeNullable(), ObjCNullableReferenceType(ObjCClassType("NSError")) ) ) } } parameters += ObjCParameter(uniqueName, p, type) } return parameters } assert(mapper.isBaseMethod(baseMethod)) val baseMethodBridge = mapper.bridgeMethod(baseMethod) val isInstanceMethod: Boolean = baseMethodBridge.isInstance val returnType: ObjCType = mapReturnType(baseMethodBridge.returnBridge, method, objCExportScope) val parameters = collectParameters(baseMethodBridge, method) val selector = getSelector(baseMethod) val selectorParts: List = splitSelector(selector) val swiftName = namer.getSwiftName(baseMethod) val attributes = mutableListOf() attributes += swiftNameAttribute(swiftName) if (baseMethodBridge.returnBridge is MethodBridge.ReturnValue.WithError.ZeroForError && baseMethodBridge.returnBridge.successMayBeZero) { // Method may return zero on success, but // standard Objective-C convention doesn't suppose this happening. // Add non-standard convention hint for Swift: attributes += "swift_error(nonnull_error)" // Means "failure <=> (error != nil)". } if (method is ConstructorDescriptor && !method.constructedClass.isArray) { // TODO: check methodBridge instead. attributes += "objc_designated_initializer" } if (unavailable) { attributes += "unavailable" } else { attributes.addIfNotNull(mapper.getDeprecation(method)?.toDeprecationAttribute()) } val comment = buildComment(method, baseMethodBridge) return ObjCMethod(method, isInstanceMethod, returnType, selectorParts, parameters, attributes, comment) } private fun splitSelector(selector: String): List { return if (!selector.endsWith(":")) { listOf(selector) } else { selector.trimEnd(':').split(':').map { "$it:" } } } private fun buildComment(method: FunctionDescriptor, bridge: MethodBridge): ObjCComment? { if (method.isSuspend || bridge.returnsError) { val effectiveThrows = getEffectiveThrows(method).toSet() return when { effectiveThrows.contains(throwableClassId) -> { ObjCComment("@note This method converts all Kotlin exceptions to errors.") } effectiveThrows.isNotEmpty() -> { ObjCComment( buildString { append("@note This method converts instances of ") effectiveThrows.joinTo(this) { it.relativeClassName.asString() } append(" to errors.") }, "Other uncaught Kotlin exceptions are fatal." ) } else -> { // Shouldn't happen though. ObjCComment("@warning All uncaught Kotlin exceptions are fatal.") } } } return null } private val throwableClassId = ClassId.topLevel(StandardNames.FqNames.throwable) private fun getEffectiveThrows(method: FunctionDescriptor): Sequence { method.overriddenDescriptors.firstOrNull()?.let { return getEffectiveThrows(it) } return getDefinedThrows(method).orEmpty() } private fun exportThrown(method: FunctionDescriptor) { getDefinedThrows(method) ?.mapNotNull { method.module.findClassAcrossModuleDependencies(it) } ?.forEach { generator?.requireClassOrInterface(it) } } private fun getDefinedThrows(method: FunctionDescriptor): Sequence? { if (!method.kind.isReal) return null val throwsAnnotation = method.annotations.findAnnotation(KonanFqNames.throws) if (throwsAnnotation != null) { val argumentsArrayValue = throwsAnnotation.firstArgument() as? ArrayValue return argumentsArrayValue?.value?.asSequence().orEmpty() .filterIsInstance() .mapNotNull { when (val value = it.value) { is KClassValue.Value.NormalClass -> value.classId is KClassValue.Value.LocalClass -> null } } } if (method.isSuspend && method.overriddenDescriptors.isEmpty()) { return implicitSuspendThrows } return null } private val implicitSuspendThrows = sequenceOf(ClassId.topLevel(KonanFqNames.cancellationException)) private fun mapReturnType(returnBridge: MethodBridge.ReturnValue, method: FunctionDescriptor, objCExportScope: ObjCExportScope): ObjCType = when (returnBridge) { MethodBridge.ReturnValue.Suspend, MethodBridge.ReturnValue.Void -> ObjCVoidType MethodBridge.ReturnValue.HashCode -> ObjCPrimitiveType.NSUInteger is MethodBridge.ReturnValue.Mapped -> mapType(method.returnType!!, returnBridge.bridge, objCExportScope) MethodBridge.ReturnValue.WithError.Success -> ObjCPrimitiveType.BOOL is MethodBridge.ReturnValue.WithError.ZeroForError -> { val successReturnType = mapReturnType(returnBridge.successBridge, method, objCExportScope) if (!returnBridge.successMayBeZero) { check(successReturnType is ObjCNonNullReferenceType || (successReturnType is ObjCPointerType && !successReturnType.nullable)) { "Unexpected return type: $successReturnType in $method" } } successReturnType.makeNullableIfReferenceOrPointer() } MethodBridge.ReturnValue.Instance.InitResult, MethodBridge.ReturnValue.Instance.FactoryResult -> ObjCInstanceType } internal fun mapReferenceType(kotlinType: KotlinType, objCExportScope: ObjCExportScope): ObjCReferenceType = mapReferenceTypeIgnoringNullability(kotlinType, objCExportScope).withNullabilityOf(kotlinType) private fun ObjCNonNullReferenceType.withNullabilityOf(kotlinType: KotlinType): ObjCReferenceType = if (kotlinType.binaryRepresentationIsNullable()) { ObjCNullableReferenceType(this) } else { this } internal fun mapReferenceTypeIgnoringNullability(kotlinType: KotlinType, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType { class TypeMappingMatch(val type: KotlinType, val descriptor: ClassDescriptor, val mapper: CustomTypeMapper) val typeMappingMatches = (listOf(kotlinType) + kotlinType.supertypes()).mapNotNull { type -> (type.constructor.declarationDescriptor as? ClassDescriptor)?.let { descriptor -> mapper.getCustomTypeMapper(descriptor)?.let { mapper -> TypeMappingMatch(type, descriptor, mapper) } } } val mostSpecificMatches = typeMappingMatches.filter { match -> typeMappingMatches.all { otherMatch -> otherMatch.descriptor == match.descriptor || !otherMatch.descriptor.isSubclassOf(match.descriptor) } } if (mostSpecificMatches.size > 1) { val types = mostSpecificMatches.map { it.type } val firstType = types[0] val secondType = types[1] problemCollector.reportWarning( "Exposed type '$kotlinType' is '$firstType' and '$secondType' at the same time. " + "This most likely wouldn't work as expected.") // TODO: the same warning for such classes. } mostSpecificMatches.firstOrNull()?.let { return it.mapper.mapType(it.type, this, objCExportScope) } if(objcGenerics && kotlinType.isTypeParameter()){ val genericTypeUsage = objCExportScope.getGenericTypeUsage(TypeUtils.getTypeParameterDescriptorOrNull(kotlinType)) if(genericTypeUsage != null) return genericTypeUsage } val classDescriptor = kotlinType.getErasedTypeClass() // TODO: translate `where T : BaseClass, T : SomeInterface` to `BaseClass* ` // TODO: expose custom inline class boxes properly. if (isAny(classDescriptor) || classDescriptor.classId in mapper.hiddenTypes || classDescriptor.isInlined()) { return ObjCIdType } if (classDescriptor.defaultType.isObjCObjectType()) { return mapObjCObjectReferenceTypeIgnoringNullability(classDescriptor) } if (!mapper.shouldBeExposed(classDescriptor)) { // There are number of tricky corner cases getting here. return ObjCIdType } return if (classDescriptor.isInterface) { ObjCProtocolType(referenceProtocol(classDescriptor).objCName) } else { val typeArgs = if (objcGenerics) { kotlinType.arguments.map { typeProjection -> if (typeProjection.isStarProjection) { ObjCIdType // TODO: use Kotlin upper bound. } else { mapReferenceTypeIgnoringNullability(typeProjection.type, objCExportScope) } } } else { emptyList() } ObjCClassType(referenceClass(classDescriptor).objCName, typeArgs) } } private tailrec fun mapObjCObjectReferenceTypeIgnoringNullability(descriptor: ClassDescriptor): ObjCNonNullReferenceType { // TODO: more precise types can be used. if (descriptor.isObjCMetaClass()) return ObjCMetaClassType if (descriptor.isObjCProtocolClass()) return foreignClassType("Protocol") if (descriptor.isExternalObjCClass() || descriptor.isObjCForwardDeclaration()) { return if (descriptor.isInterface) { val name = descriptor.name.asString().removeSuffix("Protocol") foreignProtocolType(name) } else { val name = descriptor.name.asString() foreignClassType(name) } } if (descriptor.isKotlinObjCClass()) { return mapObjCObjectReferenceTypeIgnoringNullability(descriptor.getSuperClassOrAny()) } return ObjCIdType } private fun foreignProtocolType(name: String): ObjCProtocolType { generator?.referenceProtocol(name) return ObjCProtocolType(name) } private fun foreignClassType(name: String): ObjCClassType { generator?.referenceClass(ObjCClassForwardDeclaration(name)) return ObjCClassType(name) } internal fun mapFunctionTypeIgnoringNullability( functionType: KotlinType, objCExportScope: ObjCExportScope, returnsVoid: Boolean ): ObjCBlockPointerType { val parameterTypes = listOfNotNull(functionType.getReceiverTypeFromFunctionType()) + functionType.getValueParameterTypesFromFunctionType().map { it.type } return ObjCBlockPointerType( if (returnsVoid) { ObjCVoidType } else { mapReferenceType(functionType.getReturnTypeFromFunctionType(), objCExportScope) }, parameterTypes.map { mapReferenceType(it, objCExportScope) } ) } private fun mapFunctionType( kotlinType: KotlinType, objCExportScope: ObjCExportScope, typeBridge: BlockPointerBridge ): ObjCReferenceType { val expectedDescriptor = kotlinType.builtIns.getFunction(typeBridge.numberOfParameters) // Somewhat similar to mapType: val functionType = if (TypeUtils.getClassDescriptor(kotlinType) == expectedDescriptor) { kotlinType } else { kotlinType.supertypes().singleOrNull { TypeUtils.getClassDescriptor(it) == expectedDescriptor } ?: expectedDescriptor.defaultType // Should not happen though. } return mapFunctionTypeIgnoringNullability(functionType, objCExportScope, typeBridge.returnsVoid) .withNullabilityOf(kotlinType) } private fun mapType(kotlinType: KotlinType, typeBridge: TypeBridge, objCExportScope: ObjCExportScope): ObjCType = when (typeBridge) { ReferenceBridge -> mapReferenceType(kotlinType, objCExportScope) is BlockPointerBridge -> mapFunctionType(kotlinType, objCExportScope, typeBridge) is ValueTypeBridge -> { when (typeBridge.objCValueType) { ObjCValueType.BOOL -> ObjCPrimitiveType.BOOL ObjCValueType.UNICHAR -> ObjCPrimitiveType.unichar ObjCValueType.CHAR -> ObjCPrimitiveType.int8_t ObjCValueType.SHORT -> ObjCPrimitiveType.int16_t ObjCValueType.INT -> ObjCPrimitiveType.int32_t ObjCValueType.LONG_LONG -> ObjCPrimitiveType.int64_t ObjCValueType.UNSIGNED_CHAR -> ObjCPrimitiveType.uint8_t ObjCValueType.UNSIGNED_SHORT -> ObjCPrimitiveType.uint16_t ObjCValueType.UNSIGNED_INT -> ObjCPrimitiveType.uint32_t ObjCValueType.UNSIGNED_LONG_LONG -> ObjCPrimitiveType.uint64_t ObjCValueType.FLOAT -> ObjCPrimitiveType.float ObjCValueType.DOUBLE -> ObjCPrimitiveType.double ObjCValueType.POINTER -> ObjCPointerType(ObjCVoidType, kotlinType.binaryRepresentationIsNullable()) } // TODO: consider other namings. } } private inline fun buildTopLevel(block: StubBuilder>.() -> Unit) = buildStubs(block) private inline fun buildMembers(block: StubBuilder>.() -> Unit) = buildStubs(block) private inline fun > buildStubs(block: StubBuilder.() -> Unit): List = StubBuilder(problemCollector).apply(block).build() } abstract class ObjCExportHeaderGenerator internal constructor( val moduleDescriptors: List, internal val mapper: ObjCExportMapper, val namer: ObjCExportNamer, val objcGenerics: Boolean, problemCollector: ObjCExportProblemCollector ) { private val stubs = mutableListOf>() private val classForwardDeclarations = linkedSetOf() private val protocolForwardDeclarations = linkedSetOf() private val extraClassesToTranslate = mutableSetOf() private val translator = ObjCExportTranslatorImpl(this, mapper, namer, problemCollector, objcGenerics) private val generatedClasses = mutableSetOf() private val extensions = mutableMapOf>() private val topLevel = mutableMapOf>() fun build(): List = mutableListOf().apply { addImports(foundationImports) addImports(getAdditionalImports()) add("") if (classForwardDeclarations.isNotEmpty()) { add("@class ${ classForwardDeclarations.joinToString { buildString { append(it.className) formatGenerics(this, it.typeDeclarations) } } };") add("") } if (protocolForwardDeclarations.isNotEmpty()) { add("@protocol ${protocolForwardDeclarations.joinToString()};") add("") } add("NS_ASSUME_NONNULL_BEGIN") add("#pragma clang diagnostic push") listOf( "-Wunknown-warning-option", // Protocols don't have generics, classes do. So generated header may contain // overriding property with "incompatible" type, e.g. `Generic`-typed property // overriding `Generic`. Suppress these warnings: "-Wincompatible-property-type", "-Wnullability" ).forEach { add("#pragma clang diagnostic ignored \"$it\"") } add("") stubs.forEach { addAll(StubRenderer.render(it)) add("") } add("#pragma clang diagnostic pop") add("NS_ASSUME_NONNULL_END") } internal fun buildInterface(): ObjCExportedInterface { val headerLines = build() return ObjCExportedInterface(generatedClasses, extensions, topLevel, headerLines, namer, mapper) } fun getExportStubs(): ObjCExportedStubs = ObjCExportedStubs(classForwardDeclarations, protocolForwardDeclarations, stubs) protected open fun getAdditionalImports(): List = emptyList() fun translateModule() { // TODO: make the translation order stable // to stabilize name mangling. translateBaseDeclarations() translateModuleDeclarations() } fun translateBaseDeclarations() { stubs += translator.generateBaseDeclarations() } fun translateModuleDeclarations() { translatePackageFragments() translateExtraClasses() } private fun translatePackageFragments() { val packageFragments = moduleDescriptors.flatMap { it.getPackageFragments() } packageFragments.forEach { packageFragment -> packageFragment.getMemberScope().getContributedDescriptors() .asSequence() .filterIsInstance() .filter { mapper.shouldBeExposed(it) } .forEach { val classDescriptor = mapper.getClassIfCategory(it) if (classDescriptor != null) { extensions.getOrPut(classDescriptor, { mutableListOf() }) += it } else { topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it } } } fun MemberScope.translateClasses() { getContributedDescriptors() .asSequence() .filterIsInstance() .forEach { if (mapper.shouldBeExposed(it)) { if (it.isInterface) { generateInterface(it) } else { generateClass(it) } it.unsubstitutedMemberScope.translateClasses() } else if (mapper.shouldBeVisible(it)) { stubs += if (it.isInterface) { translator.translateUnexposedInterfaceAsUnavailableStub(it) } else { translator.translateUnexposedClassAsUnavailableStub(it) } } } } packageFragments.forEach { packageFragment -> packageFragment.getMemberScope().translateClasses() } extensions.forEach { classDescriptor, declarations -> generateExtensions(classDescriptor, declarations) } topLevel.forEach { sourceFile, declarations -> generateFile(sourceFile, declarations) } } /** * Translates additional classes referenced from the module's declarations, such as parameter types, return types, * thrown exception types, and underlying enum types. * * This is required for classes from dependencies to be exported correctly. However, we also currently rely on this * for a few edge cases, such as some inner classes. Sub classes may reject certain descriptors to be translated. * Some referenced descriptors may be translated early for ordering reasons. * @see shouldTranslateExtraClass * @see generateExtraClassEarly * @see generateExtraInterfaceEarly */ private fun translateExtraClasses() { while (extraClassesToTranslate.isNotEmpty()) { val descriptor = extraClassesToTranslate.first() extraClassesToTranslate -= descriptor assert(shouldTranslateExtraClass(descriptor)) { "Shouldn't be queued for translation: $descriptor" } if (descriptor.isInterface) { generateInterface(descriptor) } else { generateClass(descriptor) } } } private fun generateFile(sourceFile: SourceFile, declarations: List) { stubs.add(translator.translateFile(sourceFile, declarations)) } private fun generateExtensions(classDescriptor: ClassDescriptor, declarations: List) { stubs.add(translator.translateExtensions(classDescriptor, declarations)) } protected open fun shouldTranslateExtraClass(descriptor: ClassDescriptor): Boolean = true internal fun generateExtraClassEarly(descriptor: ClassDescriptor) { if (shouldTranslateExtraClass(descriptor)) generateClass(descriptor) } internal fun generateExtraInterfaceEarly(descriptor: ClassDescriptor) { if (shouldTranslateExtraClass(descriptor)) generateInterface(descriptor) } private fun generateClass(descriptor: ClassDescriptor) { if (!generatedClasses.add(descriptor)) return stubs.add(translator.translateClass(descriptor)) } private fun generateInterface(descriptor: ClassDescriptor) { if (!generatedClasses.add(descriptor)) return stubs.add(translator.translateInterface(descriptor)) } internal fun requireClassOrInterface(descriptor: ClassDescriptor) { if (shouldTranslateExtraClass(descriptor) && descriptor !in generatedClasses) { extraClassesToTranslate += descriptor } } internal fun referenceClass(forwardDeclaration: ObjCClassForwardDeclaration) { classForwardDeclarations += forwardDeclaration } internal fun referenceProtocol(objCName: String) { protocolForwardDeclarations += objCName } companion object { val foundationImports = listOf( "Foundation/NSArray.h", "Foundation/NSDictionary.h", "Foundation/NSError.h", "Foundation/NSObject.h", "Foundation/NSSet.h", "Foundation/NSString.h", "Foundation/NSValue.h" ) private fun MutableList.addImports(imports: Iterable) { imports.forEach { add("#import <$it>") } } } } private fun objCInterface( name: ObjCExportNamer.ClassOrProtocolName, generics: List, superClass: String, superClassGenerics: List ): ObjCInterface = objCInterface( name, generics = generics.map { ObjCGenericTypeRawDeclaration(it) }, superClass = superClass, superClassGenerics = superClassGenerics.map { ObjCGenericTypeRawUsage(it) } ) private fun objCInterface( name: ObjCExportNamer.ClassOrProtocolName, generics: List = emptyList(), descriptor: ClassDescriptor? = null, superClass: String? = null, superClassGenerics: List = emptyList(), superProtocols: List = emptyList(), members: List> = emptyList(), attributes: List = emptyList() ): ObjCInterface = ObjCInterfaceImpl( name.objCName, generics, descriptor, superClass, superClassGenerics, superProtocols, null, members, attributes + name.toNameAttributes() ) private fun objCProtocol( name: ObjCExportNamer.ClassOrProtocolName, descriptor: ClassDescriptor, superProtocols: List, members: List>, attributes: List = emptyList() ): ObjCProtocol = ObjCProtocolImpl( name.objCName, descriptor, superProtocols, members, attributes + name.toNameAttributes() ) internal fun ObjCExportNamer.ClassOrProtocolName.toNameAttributes(): List = listOfNotNull( binaryName.takeIf { it != objCName }?.let { objcRuntimeNameAttribute(it) }, swiftName.takeIf { it != objCName }?.let { swiftNameAttribute(it) } ) private fun swiftNameAttribute(swiftName: String) = "swift_name(\"$swiftName\")" private fun objcRuntimeNameAttribute(name: String) = "objc_runtime_name(\"$name\")" interface ObjCExportScope{ fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? } internal class ObjCClassExportScope constructor(container:DeclarationDescriptor, val namer: ObjCExportNamer): ObjCExportScope { private val typeNames = if(container is ClassDescriptor && !container.isInterface) { container.typeConstructor.parameters } else { emptyList() } override fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? { val localTypeParam = typeNames.firstOrNull { typeParameterDescriptor != null && (it == typeParameterDescriptor || (it.isCapturedFromOuterDeclaration && it.original == typeParameterDescriptor)) } return if(localTypeParam == null) { null } else { ObjCGenericTypeParameterUsage(localTypeParam, namer) } } } internal object ObjCNoneExportScope: ObjCExportScope{ override fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? = null } private fun computeSuperClassType(descriptor: ClassDescriptor): KotlinType? = descriptor.typeConstructor.supertypes.filter { !it.isInterface() }.firstOrNull() internal const val OBJC_SUBCLASSING_RESTRICTED = "objc_subclassing_restricted" private fun Deprecation.toDeprecationAttribute(): String { val attribute = when (deprecationLevel) { DeprecationLevelValue.WARNING -> "deprecated" DeprecationLevelValue.ERROR, DeprecationLevelValue.HIDDEN -> "unavailable" } // TODO: consider avoiding code generation for unavailable. val message = this.message.orEmpty() return "$attribute(${quoteAsCStringLiteral(message)})" } private fun quoteAsCStringLiteral(str: String): String = buildString { append('"') for (c in str) { when (c) { '\n' -> append("\\n") '\r' -> append("\\r") '"', '\\' -> append('\\').append(c) // TODO: handle more special cases. else -> append(c) } } append('"') } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportHeaderGeneratorImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.KonanConfigKeys import org.jetbrains.kotlin.backend.konan.reportCompilationWarning import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageUtil import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.source.getPsi internal class ObjCExportHeaderGeneratorImpl( val context: Context, moduleDescriptors: List, mapper: ObjCExportMapper, namer: ObjCExportNamer, objcGenerics: Boolean ) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, ProblemCollector(context)) { private class ProblemCollector(val context: Context) : ObjCExportProblemCollector { override fun reportWarning(text: String) { context.reportCompilationWarning(text) } override fun reportWarning(method: FunctionDescriptor, text: String) { val psi = (method as? DeclarationDescriptorWithSource)?.source?.getPsi() ?: return reportWarning( "$text\n (at ${DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(method)})" ) val location = MessageUtil.psiElementToMessageLocation(psi) context.messageCollector.report(CompilerMessageSeverity.WARNING, text, location) } override fun reportException(throwable: Throwable) { throw throwable } } override fun getAdditionalImports(): List = context.config.configuration.getNotNull(KonanConfigKeys.FRAMEWORK_IMPORT_HEADERS) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazy.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.psi.psiUtil.modalityModifier import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierTypeOrDefault import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.DescriptorResolver import org.jetbrains.kotlin.resolve.TypeResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.resolve.scopes.LocalRedeclarationChecker import org.jetbrains.kotlin.resolve.source.PsiSourceFile import org.jetbrains.kotlin.types.ErrorUtils interface ObjCExportLazy { interface Configuration { val frameworkName: String fun isIncluded(moduleInfo: ModuleInfo): Boolean fun getCompilerModuleName(moduleInfo: ModuleInfo): String val objcGenerics: Boolean } fun generateBase(): List> fun translate(file: KtFile): List> } @JvmOverloads fun createObjCExportLazy( configuration: ObjCExportLazy.Configuration, problemCollector: ObjCExportProblemCollector, codeAnalyzer: KotlinCodeAnalyzer, typeResolver: TypeResolver, descriptorResolver: DescriptorResolver, fileScopeProvider: FileScopeProvider, builtIns: KotlinBuiltIns, deprecationResolver: DeprecationResolver? = null ): ObjCExportLazy = ObjCExportLazyImpl( configuration, problemCollector, codeAnalyzer, typeResolver, descriptorResolver, fileScopeProvider, builtIns, deprecationResolver ) internal class ObjCExportLazyImpl( private val configuration: ObjCExportLazy.Configuration, problemCollector: ObjCExportProblemCollector, private val codeAnalyzer: KotlinCodeAnalyzer, private val typeResolver: TypeResolver, private val descriptorResolver: DescriptorResolver, private val fileScopeProvider: FileScopeProvider, builtIns: KotlinBuiltIns, deprecationResolver: DeprecationResolver? ) : ObjCExportLazy { private val namerConfiguration = createNamerConfiguration(configuration) private val nameTranslator: ObjCExportNameTranslator = ObjCExportNameTranslatorImpl(namerConfiguration) private val mapper = ObjCExportMapper(deprecationResolver, local = true) private val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local = true) private val translator: ObjCExportTranslator = ObjCExportTranslatorImpl( null, mapper, namer, problemCollector, configuration.objcGenerics ) private val isValid: Boolean get() = codeAnalyzer.moduleDescriptor.isValid override fun generateBase() = translator.generateBaseDeclarations() override fun translate(file: KtFile): List> = translateClasses(file) + translateTopLevels(file) private fun translateClasses(container: KtDeclarationContainer): List> { val result = mutableListOf>() container.declarations.forEach { declaration -> // Supposed to be true if ObjCExportMapper.shouldBeVisible is true. if (declaration is KtClassOrObject && declaration.isPublic && declaration !is KtEnumEntry && !declaration.hasExpectModifier()) { if (!declaration.isAnnotation() && !declaration.hasModifier(KtTokens.INLINE_KEYWORD)) { result += translateClass(declaration) } declaration.body?.let { result += translateClasses(it) } } } return result } private fun translateClass(ktClassOrObject: KtClassOrObject): ObjCClass<*> { val name = nameTranslator.getClassOrProtocolName(ktClassOrObject) // Note: some attributes may be missing (e.g. "unavailable" for unexposed classes). return if (ktClassOrObject.isInterface) { LazyObjCProtocolImpl(name, ktClassOrObject, this) } else { val isFinal = ktClassOrObject.modalityModifier() == null || ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD) val attributes = if (isFinal) { listOf(OBJC_SUBCLASSING_RESTRICTED) } else { emptyList() } LazyObjCInterfaceImpl(name, attributes, generics = translateGenerics(ktClassOrObject), psi = ktClassOrObject, lazy = this) } } private fun translateGenerics(ktClassOrObject: KtClassOrObject): List = if (configuration.objcGenerics) { ktClassOrObject.typeParametersWithOuter .map { ObjCGenericTypeRawDeclaration( nameTranslator.getTypeParameterName(it), ObjCVariance.fromKotlinVariance(it.variance) ) } .toList() } else { emptyList() } private fun translateTopLevels(file: KtFile): List { val extensions = mutableMapOf>() val topLevel = mutableListOf() file.children.filterIsInstance().forEach { // Supposed to be similar to ObjCExportMapper.shouldBeVisible. if ((it is KtFunction || it is KtProperty) && it.isPublic && !it.hasExpectModifier()) { val classDescriptor = getClassIfExtension(it) if (classDescriptor != null) { extensions.getOrPut(classDescriptor, { mutableListOf() }) += it } else { topLevel += it } } } val result = mutableListOf() extensions.mapTo(result) { (classDescriptor, declarations) -> translateExtensions(file, classDescriptor, declarations) } if (topLevel.isNotEmpty()) result += translateFileClass(file, topLevel) return result } private fun translateFileClass(file: KtFile, declarations: List): ObjCInterface { val name = nameTranslator.getFileClassName(file) return LazyObjCFileInterface(name, file, declarations, this) } private fun translateExtensions( file: KtFile, classDescriptor: ClassDescriptor, declarations: List ): ObjCInterface { // TODO: consider using file-based categories in compiler too. val name = if (ErrorUtils.isError(classDescriptor)) { ObjCExportNamer.ClassOrProtocolName("ERROR", "ERROR") } else { namer.getClassOrProtocolName(classDescriptor) } return LazyObjCExtensionInterface(name, nameTranslator.getCategoryName(file), classDescriptor, declarations, this) } private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor = codeAnalyzer.resolveToDescriptor(ktDeclaration) private fun resolve(ktClassOrObject: KtClassOrObject) = resolveDeclaration(ktClassOrObject) as ClassDescriptor private fun resolve(ktCallableDeclaration: KtCallableDeclaration) = resolveDeclaration(ktCallableDeclaration) as CallableMemberDescriptor private fun getClassIfExtension(topLevelDeclaration: KtCallableDeclaration): ClassDescriptor? { val receiverType = topLevelDeclaration.receiverTypeReference ?: return null val fileScope = fileScopeProvider.getFileResolutionScope(topLevelDeclaration.containingKtFile) val trace = BindingTraceContext() // TODO: revise. val kotlinReceiverType = typeResolver.resolveType( createHeaderScope(topLevelDeclaration, fileScope, trace), receiverType, trace, checkBounds = false ) return translator.getClassIfExtension(kotlinReceiverType) } private fun createHeaderScope( declaration: KtCallableDeclaration, parent: LexicalScope, trace: BindingTrace ): LexicalScope { if (declaration.typeParameters.isEmpty()) return parent val fakeName = Name.special("") val sourceElement = SourceElement.NO_SOURCE val descriptor: CallableMemberDescriptor val scopeKind: LexicalScopeKind when (declaration) { is KtFunction -> { descriptor = SimpleFunctionDescriptorImpl.create( parent.ownerDescriptor, Annotations.EMPTY, fakeName, CallableMemberDescriptor.Kind.DECLARATION, sourceElement ) scopeKind = LexicalScopeKind.FUNCTION_HEADER } is KtProperty -> { descriptor = PropertyDescriptorImpl.create( parent.ownerDescriptor, Annotations.EMPTY, Modality.FINAL, DescriptorVisibilities.PUBLIC, declaration.isVar, fakeName, CallableMemberDescriptor.Kind.DECLARATION, sourceElement, false, false, false, false, false, false ) scopeKind = LexicalScopeKind.PROPERTY_HEADER } else -> TODO("${declaration::class}") } val result = LexicalWritableScope( parent, descriptor, false, LocalRedeclarationChecker.DO_NOTHING, scopeKind ) val typeParameters = descriptorResolver.resolveTypeParametersForDescriptor( descriptor, result, result, declaration.typeParameters, trace ) descriptorResolver.resolveGenericBounds(declaration, descriptor, result, typeParameters, trace) return result } private class LazyObjCProtocolImpl( name: ObjCExportNamer.ClassOrProtocolName, override val psi: KtClassOrObject, private val lazy: ObjCExportLazyImpl ) : LazyObjCProtocol(name) { override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } override val isValid: Boolean get() = lazy.isValid override fun computeRealStub(): ObjCProtocol = lazy.translator.translateInterface(descriptor) } private class LazyObjCInterfaceImpl( name: ObjCExportNamer.ClassOrProtocolName, attributes: List, generics: List, override val psi: KtClassOrObject, private val lazy: ObjCExportLazyImpl ) : LazyObjCInterface(name = name, generics = generics, categoryName = null, attributes = attributes) { override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) } override val isValid: Boolean get() = lazy.isValid override fun computeRealStub(): ObjCInterface = lazy.translator.translateClass(descriptor) } private class LazyObjCFileInterface( name: ObjCExportNamer.ClassOrProtocolName, private val file: KtFile, private val declarations: List, private val lazy: ObjCExportLazyImpl ) : LazyObjCInterface(name = name, generics = emptyList(), categoryName = null, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED)) { override val descriptor: ClassDescriptor? get() = null override val isValid: Boolean get() = lazy.isValid override val psi: PsiElement? get() = null override fun computeRealStub(): ObjCInterface = lazy.translator.translateFile( PsiSourceFile(file), declarations.mapNotNull { declaration -> lazy.resolve(declaration).takeIf { descriptor -> lazy.mapper.shouldBeExposed(descriptor) } } ) } private class LazyObjCExtensionInterface( name: ObjCExportNamer.ClassOrProtocolName, categoryName: String, private val classDescriptor: ClassDescriptor, private val declarations: List, private val lazy: ObjCExportLazyImpl ) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) { override val descriptor: ClassDescriptor? get() = null override val isValid: Boolean get() = lazy.isValid override val psi: PsiElement? get() = null override fun computeRealStub(): ObjCInterface = lazy.translator.translateExtensions( classDescriptor, declarations.mapNotNull { declaration -> lazy.resolve(declaration).takeIf { lazy.mapper.shouldBeExposed(it) } } ) } } private abstract class LazyObjCInterface : ObjCInterface { constructor( name: ObjCExportNamer.ClassOrProtocolName, generics: List, categoryName: String?, attributes: List ) : super(name.objCName, generics, categoryName, attributes + name.toNameAttributes()) constructor( name: String, generics: List, categoryName: String, attributes: List ) : super(name, generics, categoryName, attributes) protected abstract fun computeRealStub(): ObjCInterface private val realStub by lazy { computeRealStub() } override val members: List> get() = realStub.members override val superProtocols: List get() = realStub.superProtocols override val superClass: String? get() = realStub.superClass override val superClassGenerics: List get() = realStub.superClassGenerics } private abstract class LazyObjCProtocol( name: ObjCExportNamer.ClassOrProtocolName ) : ObjCProtocol(name.objCName, name.toNameAttributes()) { protected abstract fun computeRealStub(): ObjCProtocol private val realStub by lazy { computeRealStub() } override val members: List> get() = realStub.members override val superProtocols: List get() = realStub.superProtocols } internal fun createNamerConfiguration(configuration: ObjCExportLazy.Configuration): ObjCExportNamer.Configuration { return object : ObjCExportNamer.Configuration { override val topLevelNamePrefix = abbreviate(configuration.frameworkName) override fun getAdditionalPrefix(module: ModuleDescriptor): String? { if (module.isStdlib()) return "Kotlin" // Note: incorrect for compiler since it doesn't store ModuleInfo to ModuleDescriptor. val moduleInfo = module.getCapability(ModuleInfo.Capability) ?: return null if (configuration.isIncluded(moduleInfo)) return null return abbreviate(configuration.getCompilerModuleName(moduleInfo)) } override val objcGenerics = configuration.objcGenerics } } // TODO: find proper solution. private fun ModuleDescriptor.isStdlib(): Boolean = this.builtIns == this || this.isCommonStdlib() || this.isNativeStdlib() private val kotlinSequenceClassId = ClassId.topLevel(FqName("kotlin.sequences.Sequence")) private fun ModuleDescriptor.isCommonStdlib() = this.findClassAcrossModuleDependencies(kotlinSequenceClassId)?.module == this private val KtModifierListOwner.isPublic: Boolean get() = this.visibilityModifierTypeOrDefault() == KtTokens.PUBLIC_KEYWORD internal val KtPureClassOrObject.isInterface: Boolean get() = this is KtClass && this.isInterface() internal val KtClassOrObject.typeParametersWithOuter get() = generateSequence(this, { if (it is KtClass && it.isInner()) it.containingClassOrObject else null }) .flatMap { it.typeParameters.asSequence() } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportLazyUtils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.psi.KtFile internal fun ObjCExportLazy.dumpObjCHeader(files: Collection, outputFile: String) { val lines = (this.generateBase() + files.flatMap { this.translate(it) }) .flatMap { StubRenderer.render(it) + listOf("") } File(outputFile).writeLines(lines) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportMapper.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.backend.common.descriptors.isSuspend import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenDescriptors import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.deprecation.Deprecation import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isUnit internal class ObjCExportMapper( internal val deprecationResolver: DeprecationResolver? = null, private val local: Boolean = false ) { fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor) val hiddenTypes: Set get() = CustomTypeMappers.hiddenTypes fun isSpecialMapped(descriptor: ClassDescriptor): Boolean { // TODO: this method duplicates some of the [ObjCExportTranslatorImpl.mapReferenceType] logic. return KotlinBuiltIns.isAny(descriptor) || descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && CustomTypeMappers.hasMapper(it) } } private val methodBridgeCache = mutableMapOf() fun bridgeMethod(descriptor: FunctionDescriptor): MethodBridge = if (local) { bridgeMethodImpl(descriptor) } else { methodBridgeCache.getOrPut(descriptor) { bridgeMethodImpl(descriptor) } } } internal fun ObjCExportMapper.getClassIfCategory(descriptor: CallableMemberDescriptor): ClassDescriptor? { if (descriptor.dispatchReceiverParameter != null) return null val extensionReceiverType = descriptor.extensionReceiverParameter?.type ?: return null return getClassIfCategory(extensionReceiverType) } internal fun ObjCExportMapper.getClassIfCategory(extensionReceiverType: KotlinType): ClassDescriptor? { // FIXME: this code must rely on type mapping instead of copying its logic. if (extensionReceiverType.isObjCObjectType()) return null val erasedClass = extensionReceiverType.getErasedTypeClass() return if (!erasedClass.isInterface && !erasedClass.isInlined() && !this.isSpecialMapped(erasedClass)) { erasedClass } else { // E.g. receiver is protocol, or some type with custom mapping. null } } // Note: partially duplicated in ObjCExportLazyImpl.translateTopLevels. internal fun ObjCExportMapper.shouldBeExposed(descriptor: CallableMemberDescriptor): Boolean = descriptor.isEffectivelyPublicApi && !descriptor.isExpect && !isHiddenByDeprecation(descriptor) internal fun ObjCExportMapper.shouldBeExposed(descriptor: ClassDescriptor): Boolean = shouldBeVisible(descriptor) && !isSpecialMapped(descriptor) && !descriptor.defaultType.isObjCObjectType() private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: CallableMemberDescriptor): Boolean { // Note: ObjCExport generally expect overrides of exposed methods to be exposed. // So don't hide a "deprecated hidden" method which overrides non-hidden one: if (deprecationResolver != null && deprecationResolver.isDeprecatedHidden(descriptor) && descriptor.overriddenDescriptors.all { isHiddenByDeprecation(it) }) { return true } // Note: ObjCExport expects members of unexposed classes to be unexposed too. // So hide a declaration if it is from a hidden class: val containingDeclaration = descriptor.containingDeclaration if (containingDeclaration is ClassDescriptor && isHiddenByDeprecation(containingDeclaration)) { return true } return false } internal fun ObjCExportMapper.getDeprecation(descriptor: DeclarationDescriptor): Deprecation? { deprecationResolver?.getDeprecations(descriptor).orEmpty().maxByOrNull { when (it.deprecationLevel) { DeprecationLevelValue.WARNING -> 1 DeprecationLevelValue.ERROR -> 2 DeprecationLevelValue.HIDDEN -> 3 } }?.let { return it } (descriptor as? ConstructorDescriptor)?.let { // Note: a deprecation can't be applied to a class itself when generating header // since the class can be referred from the header. // Apply class deprecations to its constructors instead: return getDeprecation(it.constructedClass) } return null } private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: ClassDescriptor): Boolean { if (deprecationResolver == null) return false if (deprecationResolver.isDeprecatedHidden(descriptor)) return true // Note: ObjCExport requires super class of exposed class to be exposed. // So hide a class if its super class is hidden: val superClass = descriptor.getSuperClassNotAny() if (superClass != null && isHiddenByDeprecation(superClass)) { return true } // Note: ObjCExport requires enclosing class of exposed class to be exposed. // Also in Kotlin hidden class members (including other classes) aren't directly accessible. // So hide a class if its enclosing class is hidden: val containingDeclaration = descriptor.containingDeclaration if (containingDeclaration is ClassDescriptor && isHiddenByDeprecation(containingDeclaration)) { return true } return false } // Note: the logic is partially duplicated in ObjCExportLazyImpl.translateClasses. internal fun ObjCExportMapper.shouldBeVisible(descriptor: ClassDescriptor): Boolean = descriptor.isEffectivelyPublicApi && when (descriptor.kind) { ClassKind.CLASS, ClassKind.INTERFACE, ClassKind.ENUM_CLASS, ClassKind.OBJECT -> true ClassKind.ENUM_ENTRY, ClassKind.ANNOTATION_CLASS -> false } && !descriptor.isExpect && !descriptor.isInlined() && !isHiddenByDeprecation(descriptor) private fun ObjCExportMapper.isBase(descriptor: CallableMemberDescriptor): Boolean = descriptor.overriddenDescriptors.all { !shouldBeExposed(it) } // e.g. it is not `override`, or overrides only unexposed methods. internal fun ObjCExportMapper.isBaseMethod(descriptor: FunctionDescriptor) = this.isBase(descriptor) internal fun ObjCExportMapper.getBaseMethods(descriptor: FunctionDescriptor): List = if (isBaseMethod(descriptor)) { listOf(descriptor) } else { descriptor.overriddenDescriptors.filter { shouldBeExposed(it) } .flatMap { getBaseMethods(it.original)} .distinct() } internal fun ObjCExportMapper.isBaseProperty(descriptor: PropertyDescriptor) = isBase(descriptor) internal fun ObjCExportMapper.getBaseProperties(descriptor: PropertyDescriptor): List = if (isBaseProperty(descriptor)) { listOf(descriptor) } else { descriptor.overriddenDescriptors .flatMap { getBaseProperties(it.original) } .distinct() } internal tailrec fun KotlinType.getErasedTypeClass(): ClassDescriptor = TypeUtils.getClassDescriptor(this) ?: this.constructor.supertypes.first().getErasedTypeClass() internal fun ObjCExportMapper.isTopLevel(descriptor: CallableMemberDescriptor): Boolean = descriptor.containingDeclaration !is ClassDescriptor && this.getClassIfCategory(descriptor) == null internal fun ObjCExportMapper.isObjCProperty(property: PropertyDescriptor): Boolean = property.extensionReceiverParameter == null || getClassIfCategory(property) != null internal fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDescriptor? { require(this.kind == ClassKind.ENUM_CLASS) return this.staticScope.getContributedFunctions( StandardNames.ENUM_VALUES, NoLookupLocation.FROM_BACKEND ).singleOrNull { it.extensionReceiverParameter == null && it.valueParameters.size == 0 } } internal fun ObjCExportMapper.doesThrow(method: FunctionDescriptor): Boolean = method.allOverriddenDescriptors.any { it.overriddenDescriptors.isEmpty() && it.annotations.hasAnnotation(KonanFqNames.throws) } private fun ObjCExportMapper.bridgeType( kotlinType: KotlinType ): TypeBridge = kotlinType.unwrapToPrimitiveOrReference( eachInlinedClass = { inlinedClass, _ -> when (inlinedClass.classId) { UnsignedType.UBYTE.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_CHAR) UnsignedType.USHORT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_SHORT) UnsignedType.UINT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_INT) UnsignedType.ULONG.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_LONG_LONG) } }, ifPrimitive = { primitiveType, _ -> val objCValueType = when (primitiveType) { KonanPrimitiveType.BOOLEAN -> ObjCValueType.BOOL KonanPrimitiveType.CHAR -> ObjCValueType.UNICHAR KonanPrimitiveType.BYTE -> ObjCValueType.CHAR KonanPrimitiveType.SHORT -> ObjCValueType.SHORT KonanPrimitiveType.INT -> ObjCValueType.INT KonanPrimitiveType.LONG -> ObjCValueType.LONG_LONG KonanPrimitiveType.FLOAT -> ObjCValueType.FLOAT KonanPrimitiveType.DOUBLE -> ObjCValueType.DOUBLE KonanPrimitiveType.NON_NULL_NATIVE_PTR -> ObjCValueType.POINTER KonanPrimitiveType.VECTOR128 -> TODO() } ValueTypeBridge(objCValueType) }, ifReference = { if (kotlinType.isFunctionType) { bridgeFunctionType(kotlinType) } else { ReferenceBridge } } ) private fun ObjCExportMapper.bridgeFunctionType(kotlinType: KotlinType): TypeBridge { // kotlinType.arguments include return type: val numberOfParameters = kotlinType.arguments.size - 1 val returnType = kotlinType.getReturnTypeFromFunctionType() val returnsVoid = returnType.isUnit() || returnType.isNothing() // Note: this is correct because overriding method can't turn this into false // neither for a parameter nor for a return type. return BlockPointerBridge(numberOfParameters, returnsVoid) } private fun ObjCExportMapper.bridgeParameter(parameter: ParameterDescriptor): MethodBridgeValueParameter = MethodBridgeValueParameter.Mapped(bridgeType(parameter.type)) private fun ObjCExportMapper.bridgeReturnType( descriptor: FunctionDescriptor, convertExceptionsToErrors: Boolean ): MethodBridge.ReturnValue { val returnType = descriptor.returnType!! return when { descriptor.isSuspend -> MethodBridge.ReturnValue.Suspend descriptor is ConstructorDescriptor -> if (descriptor.constructedClass.isArray) { MethodBridge.ReturnValue.Instance.FactoryResult } else { MethodBridge.ReturnValue.Instance.InitResult }.let { if (convertExceptionsToErrors) { MethodBridge.ReturnValue.WithError.ZeroForError(it, successMayBeZero = false) } else { it } } descriptor.containingDeclaration.let { it is ClassDescriptor && KotlinBuiltIns.isAny(it) } && descriptor.name.asString() == "hashCode" -> { assert(!convertExceptionsToErrors) MethodBridge.ReturnValue.HashCode } descriptor is PropertyGetterDescriptor -> { assert(!convertExceptionsToErrors) MethodBridge.ReturnValue.Mapped(bridgePropertyType(descriptor.correspondingProperty)) } returnType.isUnit() || returnType.isNothing() -> if (convertExceptionsToErrors) { MethodBridge.ReturnValue.WithError.Success } else { MethodBridge.ReturnValue.Void } else -> { val returnTypeBridge = bridgeType(returnType) val successReturnValueBridge = MethodBridge.ReturnValue.Mapped(returnTypeBridge) if (convertExceptionsToErrors) { val canReturnZero = !returnTypeBridge.isReferenceOrPointer() || TypeUtils.isNullableType(returnType) MethodBridge.ReturnValue.WithError.ZeroForError( successReturnValueBridge, successMayBeZero = canReturnZero ) } else { successReturnValueBridge } } } } private fun TypeBridge.isReferenceOrPointer(): Boolean = when (this) { ReferenceBridge, is BlockPointerBridge -> true is ValueTypeBridge -> this.objCValueType == ObjCValueType.POINTER } private fun ObjCExportMapper.bridgeMethodImpl(descriptor: FunctionDescriptor): MethodBridge { assert(isBaseMethod(descriptor)) val convertExceptionsToErrors = this.doesThrow(descriptor) val kotlinParameters = descriptor.allParameters.iterator() val isTopLevel = isTopLevel(descriptor) val receiver = if (descriptor is ConstructorDescriptor && descriptor.constructedClass.isArray) { kotlinParameters.next() MethodBridgeReceiver.Factory } else if (isTopLevel) { MethodBridgeReceiver.Static } else { kotlinParameters.next() MethodBridgeReceiver.Instance } val valueParameters = mutableListOf() kotlinParameters.forEach { valueParameters += bridgeParameter(it) } val returnBridge = bridgeReturnType(descriptor, convertExceptionsToErrors) if (descriptor.isSuspend) { valueParameters += MethodBridgeValueParameter.SuspendCompletion } else if (convertExceptionsToErrors) { // Add error out parameter before tail block parameters. The convention allows this. // Placing it after would trigger https://bugs.swift.org/browse/SR-12201 // (see also https://github.com/JetBrains/kotlin-native/issues/3825). val tailBlocksCount = valueParameters.reversed().takeWhile { it.isBlockPointer() }.count() valueParameters.add(valueParameters.size - tailBlocksCount, MethodBridgeValueParameter.ErrorOutParameter) } return MethodBridge(returnBridge, receiver, valueParameters) } private fun MethodBridgeValueParameter.isBlockPointer(): Boolean = when (this) { is MethodBridgeValueParameter.Mapped -> when (this.bridge) { ReferenceBridge, is ValueTypeBridge -> false is BlockPointerBridge -> true } MethodBridgeValueParameter.ErrorOutParameter -> false MethodBridgeValueParameter.SuspendCompletion -> true } internal fun ObjCExportMapper.bridgePropertyType(descriptor: PropertyDescriptor): TypeBridge { assert(isBaseProperty(descriptor)) return bridgeType(descriptor.type) } internal enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCType) { CHAR(PrimitiveType.BYTE, ObjCPrimitiveType.char), UNSIGNED_CHAR(UnsignedType.UBYTE, ObjCPrimitiveType.unsigned_char), SHORT(PrimitiveType.SHORT, ObjCPrimitiveType.short), UNSIGNED_SHORT(UnsignedType.USHORT, ObjCPrimitiveType.unsigned_short), INT(PrimitiveType.INT, ObjCPrimitiveType.int), UNSIGNED_INT(UnsignedType.UINT, ObjCPrimitiveType.unsigned_int), LONG(ObjCPrimitiveType.long), UNSIGNED_LONG(ObjCPrimitiveType.unsigned_long), LONG_LONG(PrimitiveType.LONG, ObjCPrimitiveType.long_long), UNSIGNED_LONG_LONG(UnsignedType.ULONG, ObjCPrimitiveType.unsigned_long_long), FLOAT(PrimitiveType.FLOAT, ObjCPrimitiveType.float), DOUBLE(PrimitiveType.DOUBLE, ObjCPrimitiveType.double), BOOL(PrimitiveType.BOOLEAN, ObjCPrimitiveType.BOOL), INTEGER(ObjCPrimitiveType.NSInteger), UNSIGNED_INTEGER(ObjCPrimitiveType.NSUInteger) ; // UNSIGNED_SHORT -> unsignedShort private val kindName = this.name.split('_') .joinToString("") { it.toLowerCase().capitalize() }.decapitalize() val valueSelector = kindName // unsignedShort val initSelector = "initWith${kindName.capitalize()}:" // initWithUnsignedShort: val factorySelector = "numberWith${kindName.capitalize()}:" // numberWithUnsignedShort: constructor( primitiveType: PrimitiveType, objCPrimitiveType: ObjCPrimitiveType ) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType) constructor( unsignedType: UnsignedType, objCPrimitiveType: ObjCPrimitiveType ) : this(unsignedType.classId, objCPrimitiveType) constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportNamer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.backend.common.serialization.findSourceFile import org.jetbrains.kotlin.backend.konan.cKeywords import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.library.shortName import org.jetbrains.kotlin.library.uniqueName import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor import org.jetbrains.kotlin.resolve.source.PsiSourceFile internal interface ObjCExportNameTranslator { fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName fun getCategoryName(file: KtFile): String fun getClassOrProtocolName( ktClassOrObject: KtClassOrObject ): ObjCExportNamer.ClassOrProtocolName fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String } interface ObjCExportNamer { data class ClassOrProtocolName(val swiftName: String, val objCName: String, val binaryName: String = objCName) interface Configuration { val topLevelNamePrefix: String fun getAdditionalPrefix(module: ModuleDescriptor): String? val objcGenerics: Boolean } val topLevelNamePrefix: String fun getFileClassName(file: SourceFile): ClassOrProtocolName fun getClassOrProtocolName(descriptor: ClassDescriptor): ClassOrProtocolName fun getSelector(method: FunctionDescriptor): String fun getSwiftName(method: FunctionDescriptor): String fun getPropertyName(property: PropertyDescriptor): String fun getObjectInstanceSelector(descriptor: ClassDescriptor): String fun getEnumEntrySelector(descriptor: ClassDescriptor): String fun getEnumValuesSelector(descriptor: FunctionDescriptor): String fun getTypeParameterName(typeParameterDescriptor: TypeParameterDescriptor): String fun numberBoxName(classId: ClassId): ClassOrProtocolName val kotlinAnyName: ClassOrProtocolName val mutableSetName: ClassOrProtocolName val mutableMapName: ClassOrProtocolName val kotlinNumberName: ClassOrProtocolName } fun createNamer(moduleDescriptor: ModuleDescriptor, topLevelNamePrefix: String = moduleDescriptor.namePrefix): ObjCExportNamer = createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix) fun createNamer( moduleDescriptor: ModuleDescriptor, exportedDependencies: List, topLevelNamePrefix: String = moduleDescriptor.namePrefix ): ObjCExportNamer = ObjCExportNamerImpl( (exportedDependencies + moduleDescriptor).toSet(), moduleDescriptor.builtIns, ObjCExportMapper(local = true), topLevelNamePrefix, local = true ) // Note: this class duplicates some of ObjCExportNamerImpl logic, // but operates on different representation. internal open class ObjCExportNameTranslatorImpl( configuration: ObjCExportNamer.Configuration ) : ObjCExportNameTranslator { private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, configuration.objcGenerics) override fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName = helper.getFileClassName(file) override fun getCategoryName(file: KtFile): String = helper.translateFileName(file) override fun getClassOrProtocolName( ktClassOrObject: KtClassOrObject ): ObjCExportNamer.ClassOrProtocolName = helper.swiftClassNameToObjC( getClassOrProtocolSwiftName(ktClassOrObject) ) private fun getClassOrProtocolSwiftName( ktClassOrObject: KtClassOrObject ): String = buildString { val outerClass = ktClassOrObject.getStrictParentOfType() if (outerClass != null) { appendNameWithContainer(ktClassOrObject, outerClass) } else { append(ktClassOrObject.name!!.toIdentifier()) } } private fun StringBuilder.appendNameWithContainer( ktClassOrObject: KtClassOrObject, outerClass: KtClassOrObject ) = helper.appendNameWithContainer( this, ktClassOrObject, ktClassOrObject.name!!.toIdentifier(), outerClass, getClassOrProtocolSwiftName(outerClass), object : ObjCExportNamingHelper.ClassInfoProvider { override fun hasGenerics(clazz: KtClassOrObject): Boolean = clazz.typeParametersWithOuter.count() != 0 override fun isInterface(clazz: KtClassOrObject): Boolean = ktClassOrObject.isInterface } ) override fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String = buildString { append(ktTypeParameter.name!!.toIdentifier()) while (helper.isTypeParameterNameReserved(this.toString())) append('_') } } private class ObjCExportNamingHelper( private val topLevelNamePrefix: String, private val objcGenerics: Boolean ) { fun translateFileName(fileName: String): String = PackagePartClassUtils.getFilePartShortName(fileName).toIdentifier() fun translateFileName(file: KtFile): String = translateFileName(file.name) fun getFileClassName(fileName: String): ObjCExportNamer.ClassOrProtocolName { val baseName = translateFileName(fileName) return ObjCExportNamer.ClassOrProtocolName(swiftName = baseName, objCName = "$topLevelNamePrefix$baseName") } fun swiftClassNameToObjC(swiftName: String): ObjCExportNamer.ClassOrProtocolName = ObjCExportNamer.ClassOrProtocolName(swiftName, buildString { append(topLevelNamePrefix) swiftName.split('.').forEachIndexed { index, part -> append(if (index == 0) part else part.capitalize()) } }) fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName = getFileClassName(file.name) fun appendNameWithContainer( builder: StringBuilder, clazz: T, ownName: String, containingClass: T, containerName: String, provider: ClassInfoProvider ) = builder.apply { if (clazz.canBeSwiftInner(provider)) { append(containerName) if (!this.contains('.') && containingClass.canBeSwiftOuter(provider)) { // AB -> AB.C append('.') append(mangleSwiftNestedClassName(ownName)) } else { // AB -> ABC // A.B -> A.BC append(ownName.capitalize()) } } else { // AB, A.B -> ABC val dotIndex = containerName.indexOf('.') if (dotIndex == -1) { append(containerName) } else { append(containerName.substring(0, dotIndex)) append(containerName.substring(dotIndex + 1).capitalize()) } append(ownName.capitalize()) } } interface ClassInfoProvider { fun hasGenerics(clazz: T): Boolean fun isInterface(clazz: T): Boolean } private fun T.canBeSwiftOuter(provider: ClassInfoProvider): Boolean = when { objcGenerics && provider.hasGenerics(this) -> { // Swift nested classes are static but capture outer's generics. false } provider.isInterface(this) -> { // Swift doesn't support outer protocols. false } else -> true } private fun T.canBeSwiftInner(provider: ClassInfoProvider): Boolean = when { objcGenerics && provider.hasGenerics(this) -> { // Swift compiler doesn't seem to handle this case properly. false } provider.isInterface(this) -> { // Swift doesn't support nested protocols. false } else -> true } fun mangleSwiftNestedClassName(name: String): String = when (name) { "Type" -> "${name}_" // See https://github.com/JetBrains/kotlin-native/issues/3167 else -> name } fun isTypeParameterNameReserved(name: String): Boolean = name in reservedTypeParameterNames private val reservedTypeParameterNames = setOf("id", "NSObject", "NSArray", "NSCopying", "NSNumber", "NSInteger", "NSUInteger", "NSString", "NSSet", "NSDictionary", "NSMutableArray", "int", "unsigned", "short", "char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar") } internal class ObjCExportNamerImpl( private val configuration: ObjCExportNamer.Configuration, builtIns: KotlinBuiltIns, private val mapper: ObjCExportMapper, private val local: Boolean ) : ObjCExportNamer { constructor( moduleDescriptors: Set, builtIns: KotlinBuiltIns, mapper: ObjCExportMapper, topLevelNamePrefix: String, local: Boolean, objcGenerics: Boolean = false ) : this( object : ObjCExportNamer.Configuration { override val topLevelNamePrefix: String get() = topLevelNamePrefix override fun getAdditionalPrefix(module: ModuleDescriptor): String? = if (module in moduleDescriptors) null else module.namePrefix override val objcGenerics: Boolean get() = objcGenerics }, builtIns, mapper, local ) private val objcGenerics get() = configuration.objcGenerics override val topLevelNamePrefix get() = configuration.topLevelNamePrefix private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, objcGenerics) private fun String.toSpecialStandardClassOrProtocolName() = ObjCExportNamer.ClassOrProtocolName( swiftName = "Kotlin$this", objCName = "${topLevelNamePrefix}$this" ) override val kotlinAnyName = "Base".toSpecialStandardClassOrProtocolName() override val mutableSetName = "MutableSet".toSpecialStandardClassOrProtocolName() override val mutableMapName = "MutableDictionary".toSpecialStandardClassOrProtocolName() override fun numberBoxName(classId: ClassId): ObjCExportNamer.ClassOrProtocolName = classId.shortClassName.asString().toSpecialStandardClassOrProtocolName() override val kotlinNumberName = "Number".toSpecialStandardClassOrProtocolName() private val methodSelectors = object : Mapping() { // Try to avoid clashing with critical NSObject instance methods: private val reserved = setOf( "retain", "release", "autorelease", "class", "superclass", "hash" ) override fun reserved(name: String) = name in reserved override fun conflict(first: FunctionDescriptor, second: FunctionDescriptor): Boolean = !mapper.canHaveSameSelector(first, second) } private val methodSwiftNames = object : Mapping() { override fun conflict(first: FunctionDescriptor, second: FunctionDescriptor): Boolean = !mapper.canHaveSameSelector(first, second) // Note: this condition is correct but can be too strict. } private val propertyNames = object : Mapping() { override fun reserved(name: String) = name in Reserved.propertyNames override fun conflict(first: PropertyDescriptor, second: PropertyDescriptor): Boolean = !mapper.canHaveSameName(first, second) } private open inner class GlobalNameMapping : Mapping() { final override fun conflict(first: T, second: T): Boolean = true } private val objCClassNames = GlobalNameMapping() private val objCProtocolNames = GlobalNameMapping() // Classes and protocols share the same namespace in Swift. private val swiftClassAndProtocolNames = GlobalNameMapping() private val genericTypeParameterNameMapping = GenericTypeParameterNameMapping() private abstract inner class ClassSelectorNameMapping : Mapping() { // Try to avoid clashing with NSObject class methods: private val reserved = setOf( "retain", "release", "autorelease", "initialize", "load", "alloc", "new", "class", "superclass", "classFallbacksForKeyedArchiver", "classForKeyedUnarchiver", "description", "debugDescription", "version", "hash", "useStoredAccessor" ) override fun reserved(name: String) = (name in reserved) || (name in cKeywords) } private val objectInstanceSelectors = object : ClassSelectorNameMapping() { override fun conflict(first: ClassDescriptor, second: ClassDescriptor) = false } private val enumClassSelectors = object : ClassSelectorNameMapping() { override fun conflict(first: DeclarationDescriptor, second: DeclarationDescriptor) = first.containingDeclaration == second.containingDeclaration } override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName { val candidate by lazy { val fileName = when (file) { is PsiSourceFile -> { val psiFile = file.psiFile val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile") ktFile.name } else -> file.name ?: error("$file has no name") } helper.getFileClassName(fileName) } val objCName = objCClassNames.getOrPut(file) { StringBuilder(candidate.objCName).mangledBySuffixUnderscores() } val swiftName = swiftClassAndProtocolNames.getOrPut(file) { StringBuilder(candidate.swiftName).mangledBySuffixUnderscores() } return ObjCExportNamer.ClassOrProtocolName(swiftName = swiftName, objCName = objCName) } override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName = ObjCExportNamer.ClassOrProtocolName( swiftName = getClassOrProtocolSwiftName(descriptor), objCName = getClassOrProtocolObjCName(descriptor) ) private fun getClassOrProtocolSwiftName( descriptor: ClassDescriptor ): String = swiftClassAndProtocolNames.getOrPut(descriptor) { StringBuilder().apply { val containingDeclaration = descriptor.containingDeclaration if (containingDeclaration is ClassDescriptor) { appendNameWithContainer(descriptor, containingDeclaration) } else if (containingDeclaration is PackageFragmentDescriptor) { appendTopLevelClassBaseName(descriptor) } else { error("unexpected class parent: $containingDeclaration") } }.mangledBySuffixUnderscores() } private fun StringBuilder.appendNameWithContainer( clazz: ClassDescriptor, containingClass: ClassDescriptor ) = helper.appendNameWithContainer( this, clazz, clazz.name.asString().toIdentifier(), containingClass, getClassOrProtocolSwiftName(containingClass), object : ObjCExportNamingHelper.ClassInfoProvider { override fun hasGenerics(clazz: ClassDescriptor): Boolean = clazz.typeConstructor.parameters.isNotEmpty() override fun isInterface(clazz: ClassDescriptor): Boolean = clazz.isInterface } ) private fun getClassOrProtocolObjCName(descriptor: ClassDescriptor): String { val objCMapping = if (descriptor.isInterface) objCProtocolNames else objCClassNames return objCMapping.getOrPut(descriptor) { StringBuilder().apply { val containingDeclaration = descriptor.containingDeclaration if (containingDeclaration is ClassDescriptor) { append(getClassOrProtocolObjCName(containingDeclaration)) .append(descriptor.name.asString().toIdentifier().capitalize()) } else if (containingDeclaration is PackageFragmentDescriptor) { append(topLevelNamePrefix).appendTopLevelClassBaseName(descriptor) } else { error("unexpected class parent: $containingDeclaration") } }.mangledBySuffixUnderscores() } } private fun StringBuilder.appendTopLevelClassBaseName(descriptor: ClassDescriptor) = apply { configuration.getAdditionalPrefix(descriptor.module)?.let { append(it) } append(descriptor.name.asString().toIdentifier()) } override fun getSelector(method: FunctionDescriptor): String = methodSelectors.getOrPut(method) { assert(mapper.isBaseMethod(method)) getPredefined(method, Predefined.anyMethodSelectors)?.let { return it } val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method) StringBuilder().apply { append(method.getMangledName(forSwift = false)) parameters.forEachIndexed { index, (bridge, it) -> val name = when (bridge) { is MethodBridgeValueParameter.Mapped -> when { it is ReceiverParameterDescriptor -> "" method is PropertySetterDescriptor -> when (parameters.size) { 1 -> "" else -> "value" } else -> it!!.name.asString().toIdentifier() } MethodBridgeValueParameter.ErrorOutParameter -> "error" MethodBridgeValueParameter.SuspendCompletion -> "completionHandler" } if (index == 0) { append(when { bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn" bridge is MethodBridgeValueParameter.SuspendCompletion -> "With" method is ConstructorDescriptor -> "With" else -> "" }) append(name.capitalize()) } else { append(name) } append(':') } }.mangledSequence { if (parameters.isNotEmpty()) { // "foo:" -> "foo_:" insert(lastIndex, '_') } else { // "foo" -> "foo_" append("_") } } } override fun getSwiftName(method: FunctionDescriptor): String = methodSwiftNames.getOrPut(method) { assert(mapper.isBaseMethod(method)) getPredefined(method, Predefined.anyMethodSwiftNames)?.let { return it } val parameters = mapper.bridgeMethod(method).valueParametersAssociated(method) StringBuilder().apply { append(method.getMangledName(forSwift = true)) append("(") parameters@ for ((bridge, it) in parameters) { val label = when (bridge) { is MethodBridgeValueParameter.Mapped -> when { it is ReceiverParameterDescriptor -> "_" method is PropertySetterDescriptor -> when (parameters.size) { 1 -> "_" else -> "value" } else -> it!!.name.asString().toIdentifier() } MethodBridgeValueParameter.ErrorOutParameter -> continue@parameters MethodBridgeValueParameter.SuspendCompletion -> "completionHandler" } append(label) append(":") } append(")") }.mangledSequence { // "foo(label:)" -> "foo(label_:)" // "foo()" -> "foo_()" insert(lastIndex - 1, '_') } } private fun getPredefined(method: FunctionDescriptor, predefinedForAny: Map): T? { return if (method.containingDeclaration.let { it is ClassDescriptor && KotlinBuiltIns.isAny(it) }) { predefinedForAny.getValue(method.name) } else { null } } override fun getPropertyName(property: PropertyDescriptor): String = propertyNames.getOrPut(property) { assert(mapper.isBaseProperty(property)) assert(mapper.isObjCProperty(property)) StringBuilder().apply { append(property.name.asString().toIdentifier()) }.mangledSequence { append('_') } } override fun getObjectInstanceSelector(descriptor: ClassDescriptor): String { assert(descriptor.kind == ClassKind.OBJECT) return objectInstanceSelectors.getOrPut(descriptor) { val name = descriptor.name.asString().decapitalize().toIdentifier().mangleIfSpecialFamily("get") StringBuilder(name).mangledBySuffixUnderscores() } } override fun getEnumEntrySelector(descriptor: ClassDescriptor): String { assert(descriptor.kind == ClassKind.ENUM_ENTRY) return enumClassSelectors.getOrPut(descriptor) { // FOO_BAR_BAZ -> fooBarBaz: val name = descriptor.name.asString().split('_').mapIndexed { index, s -> val lower = s.toLowerCase() if (index == 0) lower else lower.capitalize() }.joinToString("").toIdentifier().mangleIfSpecialFamily("the") StringBuilder(name).mangledBySuffixUnderscores() } } override fun getEnumValuesSelector(descriptor: FunctionDescriptor): String { val containingDeclaration = descriptor.containingDeclaration require(containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.ENUM_CLASS) require(descriptor.name == StandardNames.ENUM_VALUES) require(descriptor.dispatchReceiverParameter == null) { "must be static" } require(descriptor.extensionReceiverParameter == null) { "must be static" } require(descriptor.valueParameters.isEmpty()) return enumClassSelectors.getOrPut(descriptor) { StringBuilder(descriptor.name.asString()).mangledBySuffixUnderscores() } } override fun getTypeParameterName(typeParameterDescriptor: TypeParameterDescriptor): String { return genericTypeParameterNameMapping.getOrPut(typeParameterDescriptor) { StringBuilder().apply { append(typeParameterDescriptor.name.asString().toIdentifier()) }.mangledSequence { append('_') } } } init { if (!local) { forceAssignPredefined(builtIns) } } private fun forceAssignPredefined(builtIns: KotlinBuiltIns) { val any = builtIns.any val predefinedClassNames = mapOf( builtIns.any to kotlinAnyName, builtIns.mutableSet to mutableSetName, builtIns.mutableMap to mutableMapName ) predefinedClassNames.forEach { descriptor, name -> objCClassNames.forceAssign(descriptor, name.objCName) swiftClassAndProtocolNames.forceAssign(descriptor, name.swiftName) } fun ClassDescriptor.method(name: Name) = this.unsubstitutedMemberScope.getContributedFunctions( name, NoLookupLocation.FROM_BACKEND ).single() Predefined.anyMethodSelectors.forEach { name, selector -> methodSelectors.forceAssign(any.method(name), selector) } Predefined.anyMethodSwiftNames.forEach { name, swiftName -> methodSwiftNames.forceAssign(any.method(name), swiftName) } } private object Predefined { val anyMethodSelectors = mapOf( "hashCode" to "hash", "toString" to "description", "equals" to "isEqual:" ).mapKeys { Name.identifier(it.key) } val anyMethodSwiftNames = mapOf( "hashCode" to "hash()", "toString" to "description()", "equals" to "isEqual(_:)" ).mapKeys { Name.identifier(it.key) } } private object Reserved { val propertyNames = cKeywords + setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641 } private fun FunctionDescriptor.getMangledName(forSwift: Boolean): String { if (this is ConstructorDescriptor) { return if (this.constructedClass.isArray && !forSwift) "array" else "init" } val candidate = when (this) { is PropertyGetterDescriptor -> this.correspondingProperty.name.asString() is PropertySetterDescriptor -> "set${this.correspondingProperty.name.asString().capitalize()}" else -> this.name.asString() }.toIdentifier() return candidate.mangleIfSpecialFamily("do") } private fun String.mangleIfSpecialFamily(prefix: String): String { val trimmed = this.dropWhile { it == '_' } for (family in listOf("alloc", "copy", "mutableCopy", "new", "init")) { if (trimmed.startsWithWords(family)) { // Then method can be detected as having special family by Objective-C compiler. // mangle the name: return prefix + this.capitalize() } } // TODO: handle clashes with NSObject methods etc. return this } private fun String.startsWithWords(words: String) = this.startsWith(words) && (this.length == words.length || !this[words.length].isLowerCase()) private inner class GenericTypeParameterNameMapping { private val elementToName = mutableMapOf() private val typeParameterNameClassOverrides = mutableMapOf>() fun getOrPut(element: TypeParameterDescriptor, nameCandidates: () -> Sequence): String { getIfAssigned(element)?.let { return it } nameCandidates().forEach { if (tryAssign(element, it)) { return it } } error("name candidates run out") } private fun tryAssign(element: TypeParameterDescriptor, name: String): Boolean { if (element in elementToName) error(element) if (helper.isTypeParameterNameReserved(name)) return false if (!validName(element, name)) return false assignName(element, name) return true } private fun assignName(element: TypeParameterDescriptor, name: String) { if (!local) { elementToName[element] = name classNameSet(element).add(name) } } private fun validName(element: TypeParameterDescriptor, name: String): Boolean { assert(element.containingDeclaration is ClassDescriptor) return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) && (local || name !in classNameSet(element)) } private fun classNameSet(element: TypeParameterDescriptor): MutableSet { require(!local) return typeParameterNameClassOverrides.getOrPut(element.containingDeclaration as ClassDescriptor) { mutableSetOf() } } private fun getIfAssigned(element: TypeParameterDescriptor): String? = elementToName[element] } private abstract inner class Mapping() { private val elementToName = mutableMapOf() private val nameToElements = mutableMapOf>() abstract fun conflict(first: T, second: T): Boolean open fun reserved(name: N) = false inline fun getOrPut(element: T, nameCandidates: () -> Sequence): N { getIfAssigned(element)?.let { return it } nameCandidates().forEach { if (tryAssign(element, it)) { return it } } error("name candidates run out") } fun nameExists(name: N) = nameToElements.containsKey(name) private fun getIfAssigned(element: T): N? = elementToName[element] private fun tryAssign(element: T, name: N): Boolean { if (element in elementToName) error(element) if (reserved(name)) return false if (nameToElements[name].orEmpty().any { conflict(element, it) }) { return false } if (!local) { nameToElements.getOrPut(name) { mutableListOf() } += element elementToName[element] = name } return true } fun forceAssign(element: T, name: N) { if (name in nameToElements || element in elementToName) error(element) nameToElements[name] = mutableListOf(element) elementToName[element] = name } } } private inline fun StringBuilder.mangledSequence(crossinline mangle: StringBuilder.() -> Unit) = generateSequence(this.toString()) { this@mangledSequence.mangle() this@mangledSequence.toString() } private fun StringBuilder.mangledBySuffixUnderscores() = this.mangledSequence { append("_") } private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second: ClassDescriptor): Boolean { if (first.isSubclassOf(second) || second.isSubclassOf(first)) { return true } if (first.isFinalClass || second.isFinalClass) { return false } return first.isInterface || second.isInterface } private fun ObjCExportMapper.canBeInheritedBySameClass( first: CallableMemberDescriptor, second: CallableMemberDescriptor ): Boolean { if (this.isTopLevel(first) || this.isTopLevel(second)) { return this.isTopLevel(first) && this.isTopLevel(second) && first.propertyIfAccessor.findSourceFile() == second.propertyIfAccessor.findSourceFile() } val firstClass = this.getClassIfCategory(first) ?: first.containingDeclaration as ClassDescriptor val secondClass = this.getClassIfCategory(second) ?: second.containingDeclaration as ClassDescriptor if (first is ConstructorDescriptor) { return firstClass == secondClass || second !is ConstructorDescriptor && firstClass.isSubclassOf(secondClass) } if (second is ConstructorDescriptor) { return secondClass == firstClass || first !is ConstructorDescriptor && secondClass.isSubclassOf(firstClass) } return canHaveCommonSubtype(firstClass, secondClass) } private fun ObjCExportMapper.canHaveSameSelector(first: FunctionDescriptor, second: FunctionDescriptor): Boolean { assert(isBaseMethod(first)) assert(isBaseMethod(second)) if (!canBeInheritedBySameClass(first, second)) { return true } if (first.dispatchReceiverParameter == null || second.dispatchReceiverParameter == null) { // I.e. any is category method. return false } if (first.name != second.name) { return false } if (first.extensionReceiverParameter?.type != second.extensionReceiverParameter?.type) { return false } if (first is PropertySetterDescriptor && second is PropertySetterDescriptor) { // Methods should merge in any common subclass as it can't have two properties with same name. } else if (first.valueParameters.map { it.type } == second.valueParameters.map { it.type }) { // Methods should merge in any common subclasses since they have the same signature. } else { return false } // Check if methods have the same bridge (and thus the same ABI): return bridgeMethod(first) == bridgeMethod(second) } private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second: PropertyDescriptor): Boolean { assert(isBaseProperty(first)) assert(isObjCProperty(first)) assert(isBaseProperty(second)) assert(isObjCProperty(second)) if (!canBeInheritedBySameClass(first, second)) { return true } if (first.dispatchReceiverParameter == null || second.dispatchReceiverParameter == null) { // I.e. any is category property. return false } if (first.name != second.name) { return false } return bridgePropertyType(first) == bridgePropertyType(second) } internal val ModuleDescriptor.namePrefix: String get() { if (this.isNativeStdlib()) return "Kotlin" val fullPrefix = when(val module = this.klibModuleOrigin) { CurrentKlibModuleOrigin, SyntheticModulesOrigin -> this.name.asString().let { it.substring(1, it.lastIndex) } is DeserializedKlibModuleOrigin -> module.library.let { it.shortName ?: it.uniqueName } } return abbreviate(fullPrefix) } fun abbreviate(name: String): String { val normalizedName = name .capitalize() .replace("-|\\.".toRegex(), "_") val uppers = normalizedName.filterIndexed { index, character -> index == 0 || character.isUpperCase() } if (uppers.length >= 3) return uppers return normalizedName } // Note: most usages of this method rely on the fact that concatenation of valid identifiers is valid identifier. // This may sometimes be a bit conservative (since it requires mangling non-first character as if it was first); // ignore this for simplicity as having Kotlin identifiers starting from digits is supposed to be rare case. internal fun String.toValidObjCSwiftIdentifier(): String { if (this.isEmpty()) return "__" return this.replace('$', '_') // TODO: handle more special characters. .let { if (it.first().isDigit()) "_$it" else it } .let { if (it == "_") "__" else it } } // Private shortcut. private fun String.toIdentifier(): String = this.toValidObjCSwiftIdentifier() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExportedStubs.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport data class ObjCExportedStubs( val classForwardDeclarations: Set, val protocolForwardDeclarations: Set, val stubs: List> ) ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjcExportHeaderGeneratorMobile.kt ================================================ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.module class ObjcExportHeaderGeneratorMobile internal constructor( moduleDescriptors: List, mapper: ObjCExportMapper, namer: ObjCExportNamer, problemCollector: ObjCExportProblemCollector, objcGenerics: Boolean, private val restrictToLocalModules: Boolean ) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) { companion object { fun createInstance( configuration: ObjCExportLazy.Configuration, problemCollector: ObjCExportProblemCollector, builtIns: KotlinBuiltIns, moduleDescriptors: List, deprecationResolver: DeprecationResolver? = null, local: Boolean = false, restrictToLocalModules: Boolean = false): ObjCExportHeaderGenerator { val mapper = ObjCExportMapper(deprecationResolver, local) val namerConfiguration = createNamerConfiguration(configuration) val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, local) return ObjcExportHeaderGeneratorMobile( moduleDescriptors, mapper, namer, problemCollector, configuration.objcGenerics, restrictToLocalModules ) } } override fun shouldTranslateExtraClass(descriptor: ClassDescriptor): Boolean = !restrictToLocalModules || descriptor.module in moduleDescriptors } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/StubBuilder.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport internal class StubBuilder>(private val problemCollector: ObjCExportProblemCollector) { private val children = mutableListOf() inline fun add(provider: () -> S) { try { children.add(provider()) } catch (t: Throwable) { problemCollector.reportException(t) } } operator fun plusAssign(set: Collection) { children += set } fun build(): List = children } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/StubRenderer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.descriptors.ClassDescriptor object StubRenderer { fun render(stub: Stub<*>): List = collect { stub.run { this.comment?.let { comment -> +"" // Probably makes the output more readable. +"/**" comment.contentLines.forEach { +" $it" } +"*/" } when (this) { is ObjCProtocol -> { attributes.forEach { +renderAttribute(it) } +renderProtocolHeader() +"@required" renderMembers(this) +"@end;" } is ObjCInterface -> { attributes.forEach { +renderAttribute(it) } +renderInterfaceHeader() renderMembers(this) +"@end;" } is ObjCMethod -> { +renderMethod(this) } is ObjCProperty -> { +renderProperty(this) } else -> throw IllegalArgumentException("unsupported stub: " + stub::class) } } } private fun renderProperty(property: ObjCProperty): String = buildString { fun StringBuilder.appendTypeAndName() { append(' ') append(property.type.render(property.name)) } fun ObjCProperty.getAllAttributes(): List { if (getterName == null && setterName == null) return propertyAttributes val allAttributes = propertyAttributes.toMutableList() getterName?.let { allAttributes += "getter=$it" } setterName?.let { allAttributes += "setter=$it" } return allAttributes } fun StringBuilder.appendAttributes() { val attributes = property.getAllAttributes() if (attributes.isNotEmpty()) { append(' ') attributes.joinTo(this, prefix = "(", postfix = ")") } } append("@property") appendAttributes() appendTypeAndName() appendPostfixDeclarationAttributes(property.declarationAttributes) append(';') } private fun renderMethod(method: ObjCMethod): String = buildString { fun appendStaticness() { if (method.isInstanceMethod) { append('-') } else { append('+') } } fun appendReturnType() { append(" (") append(method.returnType.render()) append(')') } fun appendParameters() { assert(method.selectors.size == method.parameters.size || method.selectors.size == 1 && method.parameters.size == 0) if (method.selectors.size == 1 && method.parameters.size == 0) { append(method.selectors[0]) } else { for (i in 0 until method.selectors.size) { if (i > 0) append(' ') val parameter = method.parameters[i] val selector = method.selectors[i] append(selector) append("(") append(parameter.type.render()) append(")") append(parameter.name) } } } fun appendAttributes() { appendPostfixDeclarationAttributes(method.attributes) } appendStaticness() appendReturnType() appendParameters() appendAttributes() append(';') } private fun Appendable.appendPostfixDeclarationAttributes(attributes: List) { if (attributes.isNotEmpty()) this.append(' ') attributes.joinTo(this, separator = " ", transform = this@StubRenderer::renderAttribute) } private fun ObjCProtocol.renderProtocolHeader() = buildString { append("@protocol ") append(name) appendSuperProtocols(this@renderProtocolHeader) } private fun StringBuilder.appendSuperProtocols(clazz: ObjCClass) { val protocols = clazz.superProtocols if (protocols.isNotEmpty()) { protocols.joinTo(this, separator = ", ", prefix = " <", postfix = ">") } } private fun ObjCInterface.renderInterfaceHeader() = buildString { fun appendSuperClass() { if (superClass != null) append(" : $superClass") formatGenerics(this, superClassGenerics) } fun appendGenerics() { formatGenerics(this, generics) } fun appendCategoryName() { if (categoryName != null) { append(" (") append(categoryName) append(')') } } append("@interface ") append(name) appendGenerics() appendCategoryName() appendSuperClass() appendSuperProtocols(this@renderInterfaceHeader) } private fun Collector.renderMembers(clazz: ObjCClass<*>) { clazz.members.forEach { +render(it) } } private fun renderAttribute(attribute: String) = "__attribute__(($attribute))" private fun collect(p: Collector.() -> Unit): List { val collector = Collector() collector.p() return collector.build() } private class Collector { private val collection: MutableList = mutableListOf() fun build(): List = collection operator fun String.unaryPlus() { collection += this } operator fun List.unaryPlus() { collection += this } } } fun formatGenerics(buffer: Appendable, generics: List) { if (generics.isNotEmpty()) { generics.joinTo(buffer, separator = ", ", prefix = "<", postfix = ">") } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/objcTypes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.types.Variance sealed class ObjCType { final override fun toString(): String = this.render() abstract fun render(attrsAndName: String): String fun render() = render("") protected fun String.withAttrsAndName(attrsAndName: String) = if (attrsAndName.isEmpty()) this else "$this ${attrsAndName.trimStart()}" } data class ObjCRawType( val rawText: String ) : ObjCType() { override fun render(attrsAndName: String): String = rawText.withAttrsAndName(attrsAndName) } sealed class ObjCReferenceType : ObjCType() sealed class ObjCNonNullReferenceType : ObjCReferenceType() data class ObjCNullableReferenceType( val nonNullType: ObjCNonNullReferenceType ) : ObjCReferenceType() { override fun render(attrsAndName: String) = nonNullType.render(" _Nullable".withAttrsAndName(attrsAndName)) } data class ObjCClassType( val className: String, val typeArguments: List = emptyList() ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = buildString { append(className) if (typeArguments.isNotEmpty()) { append("<") typeArguments.joinTo(this) { it.render() } append(">") } append(" *") append(attrsAndName) } } sealed class ObjCGenericTypeUsage: ObjCNonNullReferenceType() { abstract val typeName: String final override fun render(attrsAndName: String): String { return typeName.withAttrsAndName(attrsAndName) } } data class ObjCGenericTypeRawUsage(override val typeName: String) : ObjCGenericTypeUsage() data class ObjCGenericTypeParameterUsage( val typeParameterDescriptor: TypeParameterDescriptor, val namer: ObjCExportNamer ) : ObjCGenericTypeUsage() { override val typeName: String get() = namer.getTypeParameterName(typeParameterDescriptor) } data class ObjCProtocolType( val protocolName: String ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = "id<$protocolName>".withAttrsAndName(attrsAndName) } object ObjCIdType : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = "id".withAttrsAndName(attrsAndName) } object ObjCInstanceType : ObjCNonNullReferenceType() { override fun render(attrsAndName: String): String = "instancetype".withAttrsAndName(attrsAndName) } data class ObjCBlockPointerType( val returnType: ObjCType, val parameterTypes: List ) : ObjCNonNullReferenceType() { override fun render(attrsAndName: String) = returnType.render(buildString { append("(^") append(attrsAndName) append(")(") if (parameterTypes.isEmpty()) append("void") parameterTypes.joinTo(this) { it.render() } append(')') }) } object ObjCMetaClassType : ObjCNonNullReferenceType() { override fun render(attrsAndName: String): String = "Class".withAttrsAndName(attrsAndName) } sealed class ObjCPrimitiveType( val cName: String ) : ObjCType() { object NSUInteger : ObjCPrimitiveType("NSUInteger") object BOOL : ObjCPrimitiveType("BOOL") object unichar : ObjCPrimitiveType("unichar") object int8_t : ObjCPrimitiveType("int8_t") object int16_t : ObjCPrimitiveType("int16_t") object int32_t : ObjCPrimitiveType("int32_t") object int64_t : ObjCPrimitiveType("int64_t") object uint8_t : ObjCPrimitiveType("uint8_t") object uint16_t : ObjCPrimitiveType("uint16_t") object uint32_t : ObjCPrimitiveType("uint32_t") object uint64_t : ObjCPrimitiveType("uint64_t") object float : ObjCPrimitiveType("float") object double : ObjCPrimitiveType("double") object NSInteger : ObjCPrimitiveType("NSInteger") object char : ObjCPrimitiveType("char") object unsigned_char: ObjCPrimitiveType("unsigned char") object unsigned_short: ObjCPrimitiveType("unsigned short") object int: ObjCPrimitiveType("int") object unsigned_int: ObjCPrimitiveType("unsigned int") object long: ObjCPrimitiveType("long") object unsigned_long: ObjCPrimitiveType("unsigned long") object long_long: ObjCPrimitiveType("long long") object unsigned_long_long: ObjCPrimitiveType("unsigned long long") object short: ObjCPrimitiveType("short") override fun render(attrsAndName: String) = cName.withAttrsAndName(attrsAndName) } data class ObjCPointerType( val pointee: ObjCType, val nullable: Boolean = false ) : ObjCType() { override fun render(attrsAndName: String) = pointee.render("*${if (nullable) { " _Nullable".withAttrsAndName(attrsAndName) } else { attrsAndName }}") } object ObjCVoidType : ObjCType() { override fun render(attrsAndName: String) = "void".withAttrsAndName(attrsAndName) } internal enum class ObjCValueType(val encoding: String) { BOOL("c"), UNICHAR("S"), CHAR("c"), SHORT("s"), INT("i"), LONG_LONG("q"), UNSIGNED_CHAR("C"), UNSIGNED_SHORT("S"), UNSIGNED_INT("I"), UNSIGNED_LONG_LONG("Q"), FLOAT("f"), DOUBLE("d"), POINTER("^v") } enum class ObjCVariance(internal val declaration: String) { INVARIANT(""), COVARIANT("__covariant "), CONTRAVARIANT("__contravariant "); companion object { fun fromKotlinVariance(variance: Variance): ObjCVariance = when (variance) { Variance.OUT_VARIANCE -> COVARIANT Variance.IN_VARIANCE -> CONTRAVARIANT else -> INVARIANT } } } sealed class ObjCGenericTypeDeclaration { abstract val typeName: String abstract val variance: ObjCVariance final override fun toString(): String = variance.declaration + typeName } data class ObjCGenericTypeRawDeclaration( override val typeName: String, override val variance: ObjCVariance = ObjCVariance.INVARIANT ) : ObjCGenericTypeDeclaration() data class ObjCGenericTypeParameterDeclaration( val typeParameterDescriptor: TypeParameterDescriptor, val namer: ObjCExportNamer ) : ObjCGenericTypeDeclaration() { override val typeName: String get() = namer.getTypeParameterName(typeParameterDescriptor) override val variance: ObjCVariance get() = ObjCVariance.fromKotlinVariance(typeParameterDescriptor.variance) } internal fun ObjCType.makeNullableIfReferenceOrPointer(): ObjCType = when (this) { is ObjCPointerType -> ObjCPointerType(this.pointee, nullable = true) is ObjCNonNullReferenceType -> ObjCNullableReferenceType(this) is ObjCNullableReferenceType, is ObjCRawType, is ObjCPrimitiveType, ObjCVoidType -> this } internal fun ObjCReferenceType.makeNullable(): ObjCNullableReferenceType = when (this) { is ObjCNonNullReferenceType -> ObjCNullableReferenceType(this) is ObjCNullableReferenceType -> this } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/stubs.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.objcexport import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.source.PsiSourceElement class ObjCComment(val contentLines: List) { constructor(vararg contentLines: String) : this(contentLines.toList()) } data class ObjCClassForwardDeclaration( val className: String, val typeDeclarations: List = emptyList() ) abstract class Stub(val name: String, val comment: ObjCComment? = null) { abstract val descriptor: D? open val psi: PsiElement? get() = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi open val isValid: Boolean get() = descriptor?.module?.isValid ?: true } abstract class ObjCTopLevel(name: String) : Stub(name) abstract class ObjCClass(name: String, val attributes: List) : ObjCTopLevel(name) { abstract val superProtocols: List abstract val members: List> } abstract class ObjCProtocol(name: String, attributes: List) : ObjCClass(name, attributes) class ObjCProtocolImpl( name: String, override val descriptor: ClassDescriptor, override val superProtocols: List, override val members: List>, attributes: List = emptyList()) : ObjCProtocol(name, attributes) abstract class ObjCInterface(name: String, val generics: List, val categoryName: String?, attributes: List) : ObjCClass(name, attributes) { abstract val superClass: String? abstract val superClassGenerics: List } class ObjCInterfaceImpl( name: String, generics: List = emptyList(), override val descriptor: ClassDescriptor? = null, override val superClass: String? = null, override val superClassGenerics: List = emptyList(), override val superProtocols: List = emptyList(), categoryName: String? = null, override val members: List> = emptyList(), attributes: List = emptyList() ) : ObjCInterface(name, generics, categoryName, attributes) class ObjCMethod( override val descriptor: DeclarationDescriptor?, val isInstanceMethod: Boolean, val returnType: ObjCType, val selectors: List, val parameters: List, val attributes: List, comment: ObjCComment? = null ) : Stub(buildMethodName(selectors, parameters), comment) class ObjCParameter(name: String, override val descriptor: ParameterDescriptor?, val type: ObjCType) : Stub(name) class ObjCProperty(name: String, override val descriptor: DeclarationDescriptorWithSource?, val type: ObjCType, val propertyAttributes: List, val setterName: String? = null, val getterName: String? = null, val declarationAttributes: List = emptyList()) : Stub(name) { @Deprecated("", ReplaceWith("this.propertyAttributes"), DeprecationLevel.WARNING) val attributes: List get() = propertyAttributes } private fun buildMethodName(selectors: List, parameters: List): String = if (selectors.size == 1 && parameters.size == 0) { selectors[0] } else { assert(selectors.size == parameters.size) selectors.joinToString(separator = "") } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/CallGraphBuilder.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.DirectedGraph import org.jetbrains.kotlin.backend.konan.DirectedGraphNode import org.jetbrains.kotlin.backend.konan.Context internal class CallGraphNode(val graph: CallGraph, val symbol: DataFlowIR.FunctionSymbol.Declared) : DirectedGraphNode { override val key get() = symbol override val directEdges: List by lazy { graph.directEdges[symbol]!!.callSites .filter { !it.isVirtual } .map { it.actualCallee } .filterIsInstance() .filter { graph.directEdges.containsKey(it) } } override val reversedEdges: List by lazy { graph.reversedEdges[symbol]!! } class CallSite(val call: DataFlowIR.Node.Call, val isVirtual: Boolean, val actualCallee: DataFlowIR.FunctionSymbol) val callSites = mutableListOf() } internal class CallGraph(val directEdges: Map, val reversedEdges: Map>, val rootExternalFunctions: List) : DirectedGraph { override val nodes get() = directEdges.values override fun get(key: DataFlowIR.FunctionSymbol.Declared) = directEdges[key]!! fun addEdge(caller: DataFlowIR.FunctionSymbol.Declared, callSite: CallGraphNode.CallSite) { directEdges[caller]!!.callSites += callSite } fun addReversedEdge(caller: DataFlowIR.FunctionSymbol.Declared, callee: DataFlowIR.FunctionSymbol.Declared) { reversedEdges[callee]!!.add(caller) } } internal class CallGraphBuilder( val context: Context, val moduleDFG: ModuleDFG, val externalModulesDFG: ExternalModulesDFG, val devirtualizationAnalysisResult: Devirtualization.AnalysisResult, val nonDevirtualizedCallSitesUnfoldFactor: Int ) { private val devirtualizedCallSites = devirtualizationAnalysisResult.devirtualizedCallSites private fun DataFlowIR.FunctionSymbol.resolved(): DataFlowIR.FunctionSymbol { if (this is DataFlowIR.FunctionSymbol.External) return externalModulesDFG.publicFunctions[this.hash] ?: this return this } private val directEdges = mutableMapOf() private val reversedEdges = mutableMapOf>() private val externalRootFunctions = mutableListOf() private val callGraph = CallGraph(directEdges, reversedEdges, externalRootFunctions) private data class HandleFunctionParams(val caller: DataFlowIR.FunctionSymbol.Declared?, val calleeFunction: DataFlowIR.Function) private val functionStack = mutableListOf() fun build(): CallGraph { val rootSet = Devirtualization.computeRootSet(context, moduleDFG, externalModulesDFG) for (symbol in rootSet) { val function = moduleDFG.functions[symbol] if (function == null) externalRootFunctions.add(symbol) else functionStack.push(HandleFunctionParams(null, function)) } while (functionStack.isNotEmpty()) { val (caller, calleeFunction) = functionStack.pop() val callee = calleeFunction.symbol as DataFlowIR.FunctionSymbol.Declared val gotoCallee = !directEdges.containsKey(callee) if (gotoCallee) addNode(callee) if (caller != null) callGraph.addReversedEdge(caller, callee) if (gotoCallee) handleFunction(callee, calleeFunction) } return callGraph } private fun addNode(symbol: DataFlowIR.FunctionSymbol.Declared) { directEdges[symbol] = CallGraphNode(callGraph, symbol) reversedEdges[symbol] = mutableListOf() } private inline fun DataFlowIR.FunctionBody.forEachCallSite(block: (DataFlowIR.Node.Call) -> Unit): Unit = forEachNonScopeNode { node -> when (node) { is DataFlowIR.Node.Call -> block(node) is DataFlowIR.Node.Singleton -> node.constructor?.let { block(DataFlowIR.Node.Call(it, emptyList(), node.type, null)) } is DataFlowIR.Node.ArrayRead -> block(DataFlowIR.Node.Call( callee = node.callee, arguments = listOf(node.array, node.index), returnType = node.type, irCallSite = null) ) is DataFlowIR.Node.ArrayWrite -> block(DataFlowIR.Node.Call( callee = node.callee, arguments = listOf(node.array, node.index, node.value), returnType = moduleDFG.symbolTable.mapType(context.irBuiltIns.unitType), irCallSite = null) ) is DataFlowIR.Node.FunctionReference -> block(DataFlowIR.Node.Call( callee = node.symbol, arguments = emptyList(), returnType = node.symbol.returnParameter.type, irCallSite = null )) else -> { } } } private fun staticCall(caller: DataFlowIR.FunctionSymbol.Declared, call: DataFlowIR.Node.Call, callee: DataFlowIR.FunctionSymbol) { val resolvedCallee = callee.resolved() val callSite = CallGraphNode.CallSite(call, false, resolvedCallee) val function = moduleDFG.functions[resolvedCallee] callGraph.addEdge(caller, callSite) if (function != null) functionStack.push(HandleFunctionParams(caller, function)) } private fun handleFunction(symbol: DataFlowIR.FunctionSymbol.Declared, function: DataFlowIR.Function) { val body = function.body body.forEachCallSite { call -> val devirtualizedCallSite = (call as? DataFlowIR.Node.VirtualCall)?.let { devirtualizedCallSites[it] } when { call !is DataFlowIR.Node.VirtualCall -> staticCall(symbol, call, call.callee) devirtualizedCallSite != null -> { devirtualizedCallSite.possibleCallees.forEach { staticCall(symbol, call, it.callee) } } call.receiverType == DataFlowIR.Type.Virtual -> { // Skip callsite. This can only be for invocations Any's methods on instances of ObjC classes. } else -> { // Callsite has not been devirtualized - conservatively assume the worst: // any inheritor of the receiver type is possible here. val typeHierarchy = devirtualizationAnalysisResult.typeHierarchy val allPossibleCallees = mutableListOf() typeHierarchy.inheritorsOf(call.receiverType as DataFlowIR.Type.Declared).forEachBit { val receiverType = typeHierarchy.allTypes[it] if (receiverType.isAbstract) return@forEachBit // TODO: Unconservative way - when we can use it? //.filter { devirtualizationAnalysisResult.instantiatingClasses.contains(it) } val actualCallee = when (call) { is DataFlowIR.Node.VtableCall -> receiverType.vtable[call.calleeVtableIndex] is DataFlowIR.Node.ItableCall -> receiverType.itable[call.calleeHash]!! else -> error("Unreachable") } allPossibleCallees.add(actualCallee) } if (allPossibleCallees.size <= nonDevirtualizedCallSitesUnfoldFactor) allPossibleCallees.forEach { staticCall(symbol, call, it) } else { val callSite = CallGraphNode.CallSite(call, true, call.callee) callGraph.addEdge(symbol, callSite) } } } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.common.ir.ir2stringWhole import org.jetbrains.kotlin.backend.common.ir.simpleFunctions import org.jetbrains.kotlin.backend.common.peek import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName import org.jetbrains.kotlin.backend.konan.llvm.localHash import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.util.OperatorNameConventions internal class ExternalModulesDFG(val allTypes: List, val publicTypes: Map, val publicFunctions: Map, val functionDFGs: Map) private fun IrClass.getOverridingOf(function: IrFunction) = (function as? IrSimpleFunction)?.let { it.allOverriddenFunctions.atMostOne { it.parent == this } } private fun IrTypeOperator.isCast() = this == IrTypeOperator.CAST || this == IrTypeOperator.IMPLICIT_CAST || this == IrTypeOperator.SAFE_CAST private fun IrTypeOperator.callsInstanceOf() = this == IrTypeOperator.CAST || this == IrTypeOperator.SAFE_CAST || this == IrTypeOperator.INSTANCEOF || this == IrTypeOperator.NOT_INSTANCEOF private class VariableValues { data class Variable(val loop: IrLoop?, val values: MutableSet) val elementData = HashMap() fun addEmpty(variable: IrValueDeclaration, loop: IrLoop?) { elementData[variable] = Variable(loop, mutableSetOf()) } fun add(variable: IrValueDeclaration, element: IrExpression) = elementData[variable]?.values?.add(element) private fun add(variable: IrValueDeclaration, elements: Set) = elementData[variable]?.values?.addAll(elements) fun computeClosure() { elementData.forEach { (key, _) -> add(key, computeValueClosure(key)) } } // Computes closure of all possible values for given variable. private fun computeValueClosure(value: IrValueDeclaration): Set { val result = mutableSetOf() val seen = mutableSetOf() dfs(value, seen, result) return result } private fun dfs(value: IrValueDeclaration, seen: MutableSet, result: MutableSet) { seen += value val elements = elementData[value]?.values ?: return for (element in elements) { if (element !is IrGetValue) result += element else { val declaration = element.symbol.owner if (declaration is IrVariable && !seen.contains(declaration)) dfs(declaration, seen, result) } } } } private class ExpressionValuesExtractor(val context: Context, val returnableBlockValues: Map>, val suspendableExpressionValues: Map>) { val unit = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, context.ir.symbols.unit) val nothing = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.nothingType, context.ir.symbols.nothing) fun forEachValue(expression: IrExpression, block: (IrExpression) -> Unit) { when (expression) { is IrReturnableBlock -> returnableBlockValues[expression]!!.forEach { forEachValue(it, block) } is IrSuspendableExpression -> (suspendableExpressionValues[expression]!! + expression.result).forEach { forEachValue(it, block) } is IrSuspensionPoint -> { forEachValue(expression.result, block) forEachValue(expression.resumeResult, block) } is IrContainerExpression -> { if (expression.statements.isNotEmpty()) forEachValue( expression = (expression.statements.last() as? IrExpression) ?: unit, block = block ) } is IrWhen -> expression.branches.forEach { forEachValue(it.result, block) } is IrMemberAccessExpression<*> -> block(expression) is IrGetValue -> block(expression) is IrGetField -> block(expression) is IrVararg -> /* Sometimes, we keep vararg till codegen phase (for constant arrays). */ block(expression) is IrConst<*> -> block(expression) is IrTypeOperatorCall -> { if (!expression.operator.isCast()) block(expression) else { // Propagate cast to sub-values. forEachValue(expression.argument) { value -> with(expression) { block(IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeOperand, value)) } } } } is IrTry -> { forEachValue(expression.tryResult, block) expression.catches.forEach { forEachValue(it.result, block) } } is IrGetObjectValue -> block(expression) is IrFunctionReference -> block(expression) is IrSetField -> block(expression) else -> when { expression.type.isUnit() -> unit expression.type.isNothing() -> nothing else -> TODO(ir2stringWhole(expression)) } } } } internal class ModuleDFG(val functions: Map, val symbolTable: DataFlowIR.SymbolTable) internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFragment) { private val TAKE_NAMES = true // Take fqNames for all functions and types (for debug purposes). private inline fun takeName(block: () -> String) = if (TAKE_NAMES) block() else null private val module = DataFlowIR.Module(irModule.descriptor) private val symbolTable = DataFlowIR.SymbolTable(context, irModule, module) // Possible values of a returnable block. private val returnableBlockValues = mutableMapOf>() // All suspension points within specified suspendable expression. private val suspendableExpressionValues = mutableMapOf>() private val expressionValuesExtractor = ExpressionValuesExtractor(context, returnableBlockValues, suspendableExpressionValues) fun build(): ModuleDFG { val functions = mutableMapOf() irModule.accept(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitConstructor(declaration: IrConstructor) { val body = declaration.body assert (body != null || declaration.constructedClass.isNonGeneratedAnnotation()) { "Non-annotation class constructor has empty body" } context.logMultiple { +"Analysing function ${declaration.descriptor}" +"IR: ${ir2stringWhole(declaration)}" } analyze(declaration, body) } override fun visitFunction(declaration: IrFunction) { val body = declaration.body if (body == null) { // External function or intrinsic. symbolTable.mapFunction(declaration) } else { context.logMultiple { +"Analysing function ${declaration.descriptor}" +"IR: ${ir2stringWhole(declaration)}" } analyze(declaration, body) } } override fun visitField(declaration: IrField) { if (declaration.parent is IrFile) declaration.initializer?.let { context.logMultiple { +"Analysing global field ${declaration.descriptor}" +"IR: ${ir2stringWhole(declaration)}" } analyze(declaration, IrSetFieldImpl(it.startOffset, it.endOffset, declaration.symbol, null, it.expression, context.irBuiltIns.unitType)) } } private fun analyze(declaration: IrDeclaration, body: IrElement?) { // Find all interesting expressions, variables and functions. val visitor = ElementFinderVisitor() body?.acceptVoid(visitor) context.logMultiple { +"FIRST PHASE" visitor.variableValues.elementData.forEach { (t, u) -> +"VAR $t [LOOP ${u.loop}]:" u.values.forEach { +" ${ir2stringWhole(it)}" } } visitor.expressions.forEach { t -> +"EXP [LOOP ${t.value}] ${ir2stringWhole(t.key)}" } } // Compute transitive closure of possible values for variables. visitor.variableValues.computeClosure() context.logMultiple { +"SECOND PHASE" visitor.variableValues.elementData.forEach { (t, u) -> +"VAR $t [LOOP ${u.loop}]:" u.values.forEach { +" ${ir2stringWhole(it)}" } } } val function = FunctionDFGBuilder(expressionValuesExtractor, visitor.variableValues, declaration, visitor.expressions, visitor.parentLoops, visitor.returnValues, visitor.thrownValues, visitor.catchParameters).build() context.logMultiple { +function.debugString() +"" } functions[function.symbol] = function } }, data = null) context.logMultiple { +"SYMBOL TABLE:" symbolTable.classMap.forEach { irClass, type -> +" DESCRIPTOR: ${irClass.descriptor}" +" TYPE: $type" if (type !is DataFlowIR.Type.Declared) return@forEach +" SUPER TYPES:" type.superTypes.forEach { +" $it" } +" VTABLE:" type.vtable.forEach { +" $it" } +" ITABLE:" type.itable.forEach { +" ${it.key} -> ${it.value}" } } } return ModuleDFG(functions, symbolTable) } private inner class ElementFinderVisitor : IrElementVisitorVoid { val expressions = mutableMapOf() val parentLoops = mutableMapOf() val variableValues = VariableValues() val returnValues = mutableListOf() val thrownValues = mutableListOf() val catchParameters = mutableSetOf() private val suspendableExpressionStack = mutableListOf() private val loopStack = mutableListOf() private val currentLoop get() = loopStack.peek() override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } private fun assignValue(variable: IrValueDeclaration, value: IrExpression) { expressionValuesExtractor.forEachValue(value) { variableValues.add(variable, it) } } override fun visitExpression(expression: IrExpression) { when (expression) { is IrMemberAccessExpression<*>, is IrGetField, is IrGetObjectValue, is IrVararg, is IrConst<*>, is IrTypeOperatorCall -> expressions += expression to currentLoop } if (expression is IrCall && expression.symbol == executeImplSymbol) { // Producer and job of executeImpl are called externally, we need to reflect this somehow. val producerInvocation = IrCallImpl.fromSymbolDescriptor(expression.startOffset, expression.endOffset, executeImplProducerInvoke.returnType, executeImplProducerInvoke.symbol, executeImplProducerInvoke.symbol.owner.typeParameters.size, executeImplProducerInvoke.symbol.owner.valueParameters.size) producerInvocation.dispatchReceiver = expression.getValueArgument(2) expressions += producerInvocation to currentLoop val jobFunctionReference = expression.getValueArgument(3) as? IrFunctionReference ?: error("A function reference expected") val jobInvocation = IrCallImpl.fromSymbolDescriptor(expression.startOffset, expression.endOffset, jobFunctionReference.symbol.owner.returnType, jobFunctionReference.symbol as IrSimpleFunctionSymbol, jobFunctionReference.symbol.owner.typeParameters.size, jobFunctionReference.symbol.owner.valueParameters.size) jobInvocation.putValueArgument(0, producerInvocation) expressions += jobInvocation to currentLoop } // TODO: A little bit hacky but it is the simplest solution. // See ObjC instanceOf code generation for details. if (expression is IrTypeOperatorCall && expression.operator.callsInstanceOf() && expression.typeOperand.isObjCObjectType()) { val objcObjGetter = IrCallImpl.fromSymbolDescriptor(expression.startOffset, expression.endOffset, objCObjectRawValueGetter.owner.returnType, objCObjectRawValueGetter, objCObjectRawValueGetter.owner.typeParameters.size, objCObjectRawValueGetter.owner.valueParameters.size ).apply { extensionReceiver = expression.argument } expressions += objcObjGetter to currentLoop } if (expression is IrReturnableBlock) { returnableBlockValues.put(expression, mutableListOf()) } if (expression is IrSuspendableExpression) { suspendableExpressionStack.push(expression) suspendableExpressionValues.put(expression, mutableListOf()) } if (expression is IrSuspensionPoint) suspendableExpressionValues[suspendableExpressionStack.peek()!!]!!.add(expression) if (expression is IrLoop) { parentLoops[expression] = currentLoop loopStack.push(expression) } super.visitExpression(expression) if (expression is IrLoop) loopStack.pop() if (expression is IrSuspendableExpression) suspendableExpressionStack.pop() } override fun visitSetField(expression: IrSetField) { expressions += expression to currentLoop super.visitSetField(expression) } override fun visitReturn(expression: IrReturn) { val returnableBlock = expression.returnTargetSymbol.owner as? IrReturnableBlock if (returnableBlock != null) { returnableBlockValues[returnableBlock]!!.add(expression.value) } else { // Non-local return. if (!expression.type.isUnit()) returnValues += expression.value } super.visitReturn(expression) } override fun visitThrow(expression: IrThrow) { thrownValues += expression.value super.visitThrow(expression) } override fun visitCatch(aCatch: IrCatch) { catchParameters.add(aCatch.catchParameter) super.visitCatch(aCatch) } override fun visitSetValue(expression: IrSetValue) { super.visitSetValue(expression) assignValue(expression.symbol.owner, expression.value) } override fun visitVariable(declaration: IrVariable) { variableValues.addEmpty(declaration, currentLoop) super.visitVariable(declaration) declaration.initializer?.let { assignValue(declaration, it) } } } private val symbols = context.ir.symbols private val invokeSuspendFunctionSymbol = symbols.baseContinuationImpl.owner.declarations .filterIsInstance().single { it.name.asString() == "invokeSuspend" }.symbol private val getContinuationSymbol = symbols.getContinuation private val arrayGetSymbols = symbols.arrayGet.values private val arraySetSymbols = symbols.arraySet.values private val createUninitializedInstanceSymbol = symbols.createUninitializedInstance private val initInstanceSymbol = symbols.initInstance private val executeImplSymbol = symbols.executeImpl private val executeImplProducerClass = symbols.functionN(0).owner private val executeImplProducerInvoke = executeImplProducerClass.simpleFunctions() .single { it.name == OperatorNameConventions.INVOKE } private val reinterpret = symbols.reinterpret private val objCObjectRawValueGetter = symbols.interopObjCObjectRawValueGetter private class Scoped(val value: T, val scope: DataFlowIR.Node.Scope) private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor, val variableValues: VariableValues, val declaration: IrDeclaration, val expressions: Map, val parentLoops: Map, val returnValues: List, val thrownValues: List, val catchParameters: Set) { private val rootScope = DataFlowIR.Node.Scope(0, emptyList()) private val allParameters = (declaration as? IrFunction)?.allParameters ?: emptyList() private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { Scoped(DataFlowIR.Node.Parameter(it.index), rootScope) } ) private val continuationParameter = when { declaration !is IrSimpleFunction -> null declaration.isSuspend -> Scoped(DataFlowIR.Node.Parameter(allParameters.size), rootScope) declaration.overrides(invokeSuspendFunctionSymbol.owner) -> // is a ContinuationImpl inheritor. templateParameters[declaration.dispatchReceiverParameter!!] // It is its own continuation. else -> null } private fun getContinuation() = continuationParameter ?: error("Function ${declaration.descriptor} has no continuation parameter") private val nodes = mutableMapOf>() private val variables = mutableMapOf>() private val expressionsScopes = mutableMapOf() fun build(): DataFlowIR.Function { val isSuspend = declaration is IrSimpleFunction && declaration.isSuspend val scopes = mutableMapOf() fun transformLoop(loop: IrLoop, parentLoop: IrLoop?): DataFlowIR.Node.Scope { scopes[loop]?.let { return it } val parentScope = if (parentLoop == null) rootScope else transformLoop(parentLoop, parentLoops[parentLoop]) val scope = DataFlowIR.Node.Scope(parentScope.depth + 1, emptyList()) parentScope.nodes += scope scopes[loop] = scope return scope } parentLoops.forEach { (loop, parentLoop) -> transformLoop(loop, parentLoop) } expressions.forEach { (expression, loop) -> val scope = if (loop == null) rootScope else scopes[loop]!! expressionsScopes[expression] = scope } expressionsScopes[expressionValuesExtractor.unit] = rootScope expressionsScopes[expressionValuesExtractor.nothing] = rootScope variableValues.elementData.forEach { (irVariable, variable) -> val loop = variable.loop val scope = if (loop == null) rootScope else scopes[loop]!! val node = DataFlowIR.Node.Variable( values = mutableListOf(), type = symbolTable.mapType(irVariable.type), kind = if (catchParameters.contains(irVariable)) DataFlowIR.VariableKind.CatchParameter else DataFlowIR.VariableKind.Ordinary ) scope.nodes += node variables[irVariable] = Scoped(node, scope) } expressions.forEach { getNode(it.key) } val returnNodeType = when (declaration) { is IrField -> declaration.type is IrFunction -> declaration.returnType else -> error(declaration) } val returnsNode = DataFlowIR.Node.Variable( values = returnValues.map { expressionToEdge(it) }, type = symbolTable.mapType(returnNodeType), kind = DataFlowIR.VariableKind.Temporary ) val throwsNode = DataFlowIR.Node.Variable( values = thrownValues.map { expressionToEdge(it) }, type = symbolTable.mapClassReferenceType(symbols.throwable.owner), kind = DataFlowIR.VariableKind.Temporary ) variables.forEach { (irVariable, node) -> val values = variableValues.elementData[irVariable]!!.values values.forEach { node.value.values += expressionToEdge(it) } } rootScope.nodes += templateParameters.values.map { it.value } rootScope.nodes += returnsNode rootScope.nodes += throwsNode if (isSuspend) rootScope.nodes += continuationParameter!!.value return DataFlowIR.Function( symbol = symbolTable.mapFunction(declaration), body = DataFlowIR.FunctionBody( rootScope, listOf(rootScope) + scopes.values, returnsNode, throwsNode) ) } private fun IrType.erasure(): IrType { if (this !is IrSimpleType) return this val classifier = this.classifier return when (classifier) { is IrClassSymbol -> this is IrTypeParameterSymbol -> { val upperBound = classifier.owner.superTypes.singleOrNull() ?: TODO("${classifier.descriptor} : ${classifier.descriptor.upperBounds}") if (this.hasQuestionMark) { // `T?` upperBound.erasure().makeNullable() } else { upperBound.erasure() } } else -> TODO(classifier.toString()) } } private fun expressionToEdge(expression: IrExpression) = expressionToScopedEdge(expression).value private fun expressionToScopedEdge(expression: IrExpression) = if (expression is IrTypeOperatorCall && expression.operator.isCast()) getNode(expression.argument).let { Scoped( DataFlowIR.Edge( it.value, symbolTable.mapClassReferenceType(expression.typeOperand.erasure().getClass()!!) ), it.scope) } else { getNode(expression).let { Scoped( DataFlowIR.Edge(it.value, null), it.scope ) } } private fun mapReturnType(actualType: IrType, returnType: IrType): DataFlowIR.Type { val returnedInlinedClass = returnType.getInlinedClassNative() val actualInlinedClass = actualType.getInlinedClassNative() return if (returnedInlinedClass == null) { if (actualInlinedClass == null) symbolTable.mapType(actualType) else symbolTable.mapClassReferenceType(actualInlinedClass) } else { symbolTable.mapType(returnType) } } private fun getNode(expression: IrExpression): Scoped { if (expression is IrGetValue) { val valueDeclaration = expression.symbol.owner if (valueDeclaration is IrValueParameter) return templateParameters[valueDeclaration]!! return variables[valueDeclaration]!! } return nodes.getOrPut(expression) { context.logMultiple { +"Converting expression" +ir2stringWhole(expression) } val values = mutableListOf() val edges = mutableListOf() var highestScope: DataFlowIR.Node.Scope? = null expressionValuesExtractor.forEachValue(expression) { values += it if (it != expression || values.size > 1) { val edge = expressionToScopedEdge(it) val scope = edge.scope if (highestScope == null || highestScope!!.depth > scope.depth) highestScope = scope edges += edge.value } } if (values.size == 1 && values[0] == expression) { highestScope = expressionsScopes[expression] ?: error("Unknown expression: ${expression.dump()}") } if (values.size == 0) highestScope = rootScope val node = if (values.size != 1) { DataFlowIR.Node.Variable( values = edges, type = symbolTable.mapType(expression.type), kind = DataFlowIR.VariableKind.Temporary ) } else { val value = values[0] if (value != expression) { val edge = edges[0] if (edge.castToType == null) edge.node else DataFlowIR.Node.Variable( values = listOf(edge), type = symbolTable.mapType(expression.type), kind = DataFlowIR.VariableKind.Temporary ) } else { when (value) { is IrGetValue -> getNode(value).value is IrVararg -> DataFlowIR.Node.Const(symbolTable.mapType(value.type)) is IrFunctionReference -> { val callee = value.symbol.owner DataFlowIR.Node.FunctionReference( symbolTable.mapFunction(callee), symbolTable.mapType(value.type), /*TODO: substitute*/symbolTable.mapType(callee.returnType)) } is IrConst<*> -> if (value.value == null) DataFlowIR.Node.Null else DataFlowIR.Node.SimpleConst(symbolTable.mapType(value.type), value.value!!) is IrGetObjectValue -> { val constructor = if (value.type.isNothing()) { // is not a singleton though its instance is get with operation. null } else { val objectClass = value.symbol.owner if (objectClass is IrLazyClass) { // Singleton has a private constructor which is not deserialized. null } else { symbolTable.mapFunction(objectClass.constructors.single()) } } DataFlowIR.Node.Singleton(symbolTable.mapType(value.type), constructor) } is IrConstructorCall -> { val callee = value.symbol.owner val arguments = value.getArguments().map { expressionToEdge(it.second) } DataFlowIR.Node.NewObject( symbolTable.mapFunction(callee), arguments, symbolTable.mapClassReferenceType(callee.constructedClass), value ) } is IrCall -> when (value.symbol) { getContinuationSymbol -> getContinuation().value in arrayGetSymbols -> { val callee = value.symbol.owner val actualCallee = (value.superQualifierSymbol?.owner?.getOverridingOf(callee) ?: callee).target DataFlowIR.Node.ArrayRead( symbolTable.mapFunction(actualCallee), array = expressionToEdge(value.dispatchReceiver!!), index = expressionToEdge(value.getValueArgument(0)!!), type = mapReturnType(value.type, context.irBuiltIns.anyType), irCallSite = value) } in arraySetSymbols -> { val callee = value.symbol.owner val actualCallee = (value.superQualifierSymbol?.owner?.getOverridingOf(callee) ?: callee).target DataFlowIR.Node.ArrayWrite( symbolTable.mapFunction(actualCallee), array = expressionToEdge(value.dispatchReceiver!!), index = expressionToEdge(value.getValueArgument(0)!!), value = expressionToEdge(value.getValueArgument(1)!!), type = mapReturnType(value.getValueArgument(1)!!.type, context.irBuiltIns.anyType)) } createUninitializedInstanceSymbol -> DataFlowIR.Node.AllocInstance(symbolTable.mapClassReferenceType( value.getTypeArgument(0)!!.getClass()!! ), value) reinterpret -> getNode(value.extensionReceiver!!).value initInstanceSymbol -> { val thiz = expressionToEdge(value.getValueArgument(0)!!) val initializer = value.getValueArgument(1) as IrConstructorCall val arguments = listOf(thiz) + initializer.getArguments().map { expressionToEdge(it.second) } val callee = initializer.symbol.owner DataFlowIR.Node.StaticCall( symbolTable.mapFunction(callee), arguments, symbolTable.mapClassReferenceType(callee.constructedClass), symbolTable.mapClassReferenceType(symbols.unit.owner), null ) } else -> { val callee = value.symbol.owner val arguments = value.getArguments() .map { expressionToEdge(it.second) } .let { if (callee.isSuspend) it + DataFlowIR.Edge(getContinuation().value, null) else it } if (callee is IrConstructor) { error("Constructor call should be done with IrConstructorCall") } else { if (callee.isOverridable && value.superQualifierSymbol == null) { val owner = callee.parentAsClass val actualReceiverType = value.dispatchReceiver!!.type val actualReceiverClassifier = actualReceiverType.classifierOrFail val receiverType = if (actualReceiverClassifier is IrTypeParameterSymbol || !callee.isReal /* Could be a bridge. */) symbolTable.mapClassReferenceType(owner) else { val actualClassAtCallsite = (actualReceiverClassifier as IrClassSymbol).descriptor // assert (DescriptorUtils.isSubclass(actualClassAtCallsite, owner.descriptor)) { // "Expected an inheritor of ${owner.descriptor}, but was $actualClassAtCallsite" // } if (DescriptorUtils.isSubclass(actualClassAtCallsite, owner.descriptor)) { symbolTable.mapClassReferenceType(actualReceiverClassifier.owner) // Box if inline class. } else { symbolTable.mapClassReferenceType(owner) } } if (owner.isInterface) { val calleeHash = callee.computeFunctionName().localHash.value DataFlowIR.Node.ItableCall( symbolTable.mapFunction(callee.target), receiverType, calleeHash, arguments, mapReturnType(value.type, callee.target.returnType), value ) } else { val vtableIndex = context.getLayoutBuilder(owner).vtableIndex(callee) DataFlowIR.Node.VtableCall( symbolTable.mapFunction(callee.target), receiverType, vtableIndex, arguments, mapReturnType(value.type, callee.target.returnType), value ) } } else { val actualCallee = (value.superQualifierSymbol?.owner?.getOverridingOf(callee) ?: callee).target DataFlowIR.Node.StaticCall( symbolTable.mapFunction(actualCallee), arguments, actualCallee.dispatchReceiverParameter?.let { symbolTable.mapType(it.type) }, mapReturnType(value.type, actualCallee.returnType), value ) } } } } is IrDelegatingConstructorCall -> { val thisReceiver = (declaration as IrConstructor).constructedClass.thisReceiver!! val thiz = IrGetValueImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, thisReceiver.type, thisReceiver.symbol) val arguments = listOf(thiz) + value.getArguments().map { it.second } DataFlowIR.Node.StaticCall( symbolTable.mapFunction(value.symbol.owner), arguments.map { expressionToEdge(it) }, symbolTable.mapType(thiz.type), symbolTable.mapClassReferenceType(symbols.unit.owner), value ) } is IrGetField -> { val receiver = value.receiver?.let { expressionToEdge(it) } val receiverType = value.receiver?.let { symbolTable.mapType(it.type) } val name = value.symbol.owner.name.asString() DataFlowIR.Node.FieldRead( receiver, DataFlowIR.Field( receiverType, symbolTable.mapType(value.symbol.owner.type), name.localHash.value, takeName { name } ), mapReturnType(value.type, value.symbol.owner.type), value ) } is IrSetField -> { val receiver = value.receiver?.let { expressionToEdge(it) } val receiverType = value.receiver?.let { symbolTable.mapType(it.type) } val name = value.symbol.owner.name.asString() DataFlowIR.Node.FieldWrite( receiver, DataFlowIR.Field( receiverType, symbolTable.mapType(value.symbol.owner.type), name.localHash.value, takeName { name } ), expressionToEdge(value.value), mapReturnType(value.value.type, value.symbol.owner.type) ) } is IrTypeOperatorCall -> { assert(!value.operator.isCast()) { "Casts should've been handled earlier" } expressionToEdge(value.argument) // Put argument as a separate vertex. DataFlowIR.Node.Const(symbolTable.mapType(value.type)) // All operators except casts are basically constants. } else -> TODO("Unknown expression: ${ir2stringWhole(value)}") } } } highestScope!!.nodes += node Scoped(node, highestScope!!) } } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.descriptors.isBuiltInOperator import org.jetbrains.kotlin.backend.common.ir.allParameters import org.jetbrains.kotlin.backend.konan.ir.isOverridableOrOverrides import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName import org.jetbrains.kotlin.backend.konan.llvm.computeSymbolName import org.jetbrains.kotlin.backend.konan.llvm.isExported import org.jetbrains.kotlin.backend.konan.llvm.localHash import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name internal object DataFlowIR { abstract class Type(val isFinal: Boolean, val isAbstract: Boolean, val primitiveBinaryType: PrimitiveBinaryType?, val name: String?) { // Special marker type forbidding devirtualization on its instances. object Virtual : Declared(0, false, true, null, null, -1, null, "\$VIRTUAL") class External(val hash: Long, isFinal: Boolean, isAbstract: Boolean, primitiveBinaryType: PrimitiveBinaryType?, name: String? = null) : Type(isFinal, isAbstract, primitiveBinaryType, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is External) return false return hash == other.hash } override fun hashCode(): Int { return hash.hashCode() } override fun toString(): String { return "ExternalType(hash='$hash', name='$name')" } } abstract class Declared(val index: Int, isFinal: Boolean, isAbstract: Boolean, primitiveBinaryType: PrimitiveBinaryType?, val module: Module?, val symbolTableIndex: Int, val irClass: IrClass?, name: String?) : Type(isFinal, isAbstract, primitiveBinaryType, name) { val superTypes = mutableListOf() val vtable = mutableListOf() val itable = mutableMapOf() } class Public(val hash: Long, index: Int, isFinal: Boolean, isAbstract: Boolean, primitiveBinaryType: PrimitiveBinaryType?, module: Module, symbolTableIndex: Int, irClass: IrClass?, name: String? = null) : Declared(index, isFinal, isAbstract, primitiveBinaryType, module, symbolTableIndex, irClass, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Public) return false return hash == other.hash } override fun hashCode(): Int { return hash.hashCode() } override fun toString(): String { return "PublicType(hash='$hash', symbolTableIndex='$symbolTableIndex', name='$name')" } } class Private(index: Int, isFinal: Boolean, isAbstract: Boolean, primitiveBinaryType: PrimitiveBinaryType?, module: Module, symbolTableIndex: Int, irClass: IrClass?, name: String? = null) : Declared(index, isFinal, isAbstract, primitiveBinaryType, module, symbolTableIndex, irClass, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Private) return false return index == other.index } override fun hashCode(): Int { return index } override fun toString(): String { return "PrivateType(index=$index, symbolTableIndex='$symbolTableIndex', name='$name')" } } } class Module(val descriptor: ModuleDescriptor) { var numberOfFunctions = 0 var numberOfClasses = 0 } object FunctionAttributes { val IS_GLOBAL_INITIALIZER = 1 val RETURNS_UNIT = 2 val RETURNS_NOTHING = 4 val EXPLICITLY_EXPORTED = 8 } class FunctionParameter(val type: Type, val boxFunction: FunctionSymbol?, val unboxFunction: FunctionSymbol?) abstract class FunctionSymbol(val attributes: Int, val irFunction: IrFunction?, val name: String?) { lateinit var parameters: Array lateinit var returnParameter: FunctionParameter val isGlobalInitializer = attributes.and(FunctionAttributes.IS_GLOBAL_INITIALIZER) != 0 val returnsUnit = attributes.and(FunctionAttributes.RETURNS_UNIT) != 0 val returnsNothing = attributes.and(FunctionAttributes.RETURNS_NOTHING) != 0 val explicitlyExported = attributes.and(FunctionAttributes.EXPLICITLY_EXPORTED) != 0 var escapes: Int? = null var pointsTo: IntArray? = null class External(val hash: Long, attributes: Int, irFunction: IrFunction?, name: String? = null, val isExported: Boolean) : FunctionSymbol(attributes, irFunction, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is External) return false return hash == other.hash } override fun hashCode(): Int { return hash.hashCode() } override fun toString(): String { return "ExternalFunction(hash='$hash', name='$name', escapes='$escapes', pointsTo='${pointsTo?.contentToString()}')" } } abstract class Declared(val module: Module, val symbolTableIndex: Int, attributes: Int, irFunction: IrFunction?, var bridgeTarget: FunctionSymbol?, name: String?) : FunctionSymbol(attributes, irFunction, name) { } class Public(val hash: Long, module: Module, symbolTableIndex: Int, attributes: Int, irFunction: IrFunction?, bridgeTarget: FunctionSymbol?, name: String? = null) : Declared(module, symbolTableIndex, attributes, irFunction, bridgeTarget, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Public) return false return hash == other.hash } override fun hashCode(): Int { return hash.hashCode() } override fun toString(): String { return "PublicFunction(hash='$hash', name='$name', symbolTableIndex='$symbolTableIndex', escapes='$escapes', pointsTo='${pointsTo?.contentToString()})" } } class Private(val index: Int, module: Module, symbolTableIndex: Int, attributes: Int, irFunction: IrFunction?, bridgeTarget: FunctionSymbol?, name: String? = null) : Declared(module, symbolTableIndex, attributes, irFunction, bridgeTarget, name) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Private) return false return index == other.index } override fun hashCode(): Int { return index } override fun toString(): String { return "PrivateFunction(index=$index, symbolTableIndex='$symbolTableIndex', name='$name', escapes='$escapes', pointsTo='${pointsTo?.contentToString()})" } } } data class Field(val receiverType: Type?, val type: Type, val hash: Long, val name: String? = null) class Edge(val castToType: Type?) { lateinit var node: Node constructor(node: Node, castToType: Type?) : this(castToType) { this.node = node } } enum class VariableKind { Ordinary, Temporary, CatchParameter } sealed class Node { class Parameter(val index: Int) : Node() open class Const(val type: Type) : Node() class SimpleConst(type: Type, val value: T) : Const(type) object Null : Node() open class Call(val callee: FunctionSymbol, val arguments: List, val returnType: Type, open val irCallSite: IrFunctionAccessExpression?) : Node() class StaticCall(callee: FunctionSymbol, arguments: List, val receiverType: Type?, returnType: Type, irCallSite: IrFunctionAccessExpression?) : Call(callee, arguments, returnType, irCallSite) // TODO: It can be replaced with a pair(AllocInstance, constructor Call), remove. class NewObject(constructor: FunctionSymbol, arguments: List, val constructedType: Type, override val irCallSite: IrConstructorCall?) : Call(constructor, arguments, constructedType, irCallSite) open class VirtualCall(callee: FunctionSymbol, arguments: List, val receiverType: Type, returnType: Type, override val irCallSite: IrCall?) : Call(callee, arguments, returnType, irCallSite) class VtableCall(callee: FunctionSymbol, receiverType: Type, val calleeVtableIndex: Int, arguments: List, returnType: Type, irCallSite: IrCall?) : VirtualCall(callee, arguments, receiverType, returnType, irCallSite) class ItableCall(callee: FunctionSymbol, receiverType: Type, val calleeHash: Long, arguments: List, returnType: Type, irCallSite: IrCall?) : VirtualCall(callee, arguments, receiverType, returnType, irCallSite) class Singleton(val type: Type, val constructor: FunctionSymbol?) : Node() class AllocInstance(val type: Type, val irCallSite: IrCall?) : Node() class FunctionReference(val symbol: FunctionSymbol, val type: Type, val returnType: Type) : Node() class FieldRead(val receiver: Edge?, val field: Field, val type: Type, val ir: IrGetField?) : Node() class FieldWrite(val receiver: Edge?, val field: Field, val value: Edge, val type: Type) : Node() class ArrayRead(val callee: FunctionSymbol, val array: Edge, val index: Edge, val type: Type, val irCallSite: IrCall?) : Node() class ArrayWrite(val callee: FunctionSymbol, val array: Edge, val index: Edge, val value: Edge, val type: Type) : Node() class Variable(values: List, val type: Type, val kind: VariableKind) : Node() { val values = mutableListOf().also { it += values } } class Scope(val depth: Int, nodes: List) : Node() { val nodes = mutableSetOf().also { it += nodes } } } // Note: scopes form a tree. class FunctionBody(val rootScope: Node.Scope, val allScopes: List, val returns: Node.Variable, val throws: Node.Variable) { inline fun forEachNonScopeNode(block: (Node) -> Unit) { for (scope in allScopes) for (node in scope.nodes) if (node !is Node.Scope) block(node) } } class Function(val symbol: FunctionSymbol, val body: FunctionBody) { fun debugOutput() = println(debugString()) fun debugString() = buildString { appendLine("FUNCTION $symbol") appendLine("Params: ${symbol.parameters.contentToString()}") val nodes = listOf(body.rootScope) + body.allScopes.flatMap { it.nodes } val ids = nodes.withIndex().associateBy({ it.value }, { it.index }) nodes.forEach { appendLine(" NODE #${ids[it]!!}") appendLine(nodeToString(it, ids)) } appendLine(" RETURNS") append(nodeToString(body.returns, ids)) } companion object { fun printNode(node: Node, ids: Map) = print(nodeToString(node, ids)) fun nodeToString(node: Node, ids: Map) = when (node) { is Node.Const -> " CONST ${node.type}" Node.Null -> " NULL" is Node.Parameter -> " PARAM ${node.index}" is Node.Singleton -> " SINGLETON ${node.type}" is Node.AllocInstance -> " ALLOC INSTANCE ${node.type}" is Node.FunctionReference -> " FUNCTION REFERENCE ${node.symbol}" is Node.StaticCall -> buildString { append(" STATIC CALL ${node.callee}. Return type = ${node.returnType}") appendList(node.arguments) { append(" ARG #${ids[it.node]!!}") appendCastTo(it.castToType) } } is Node.VtableCall -> buildString { appendLine(" VIRTUAL CALL ${node.callee}. Return type = ${node.returnType}") appendLine(" RECEIVER: ${node.receiverType}") append(" VTABLE INDEX: ${node.calleeVtableIndex}") appendList(node.arguments) { append(" ARG #${ids[it.node]!!}") appendCastTo(it.castToType) } } is Node.ItableCall -> buildString { appendLine(" INTERFACE CALL ${node.callee}. Return type = ${node.returnType}") appendLine(" RECEIVER: ${node.receiverType}") append(" METHOD HASH: ${node.calleeHash}") appendList(node.arguments) { append(" ARG #${ids[it.node]!!}") appendCastTo(it.castToType) } } is Node.NewObject -> buildString { appendLine(" NEW OBJECT ${node.callee}") append(" CONSTRUCTED TYPE ${node.constructedType}") appendList(node.arguments) { append(" ARG #${ids[it.node]!!}") appendCastTo(it.castToType) } } is Node.FieldRead -> buildString { appendLine(" FIELD READ ${node.field}") append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}") appendCastTo(node.receiver?.castToType) } is Node.FieldWrite -> buildString { appendLine(" FIELD WRITE ${node.field}") append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}") appendCastTo(node.receiver?.castToType) appendLine() append(" VALUE #${ids[node.value.node]!!}") appendCastTo(node.value.castToType) } is Node.ArrayRead -> buildString { appendLine(" ARRAY READ") append(" ARRAY #${ids[node.array.node]}") appendCastTo(node.array.castToType) appendLine() append(" INDEX #${ids[node.index.node]!!}") appendCastTo(node.index.castToType) } is Node.ArrayWrite -> buildString { appendLine(" ARRAY WRITE") append(" ARRAY #${ids[node.array.node]}") appendCastTo(node.array.castToType) appendLine() append(" INDEX #${ids[node.index.node]!!}") appendCastTo(node.index.castToType) appendLine() append(" VALUE #${ids[node.value.node]!!}") appendCastTo(node.value.castToType) } is Node.Variable -> buildString { append(" ${node.kind}") appendList(node.values) { append(" VAL #${ids[it.node]!!}") appendCastTo(it.castToType) } } is Node.Scope -> buildString { append(" SCOPE ${node.depth}") appendList(node.nodes.toList()) { append(" SUBNODE #${ids[it]!!}") } } else -> " UNKNOWN: ${node::class.java}" } private fun StringBuilder.appendList(list: List, itemPrinter: StringBuilder.(T) -> Unit) { if (list.isEmpty()) return for (i in list.indices) { appendLine() itemPrinter(list[i]) } } private fun StringBuilder.appendCastTo(type: Type?) { if (type != null) append(" CASTED TO ${type}") } } } class SymbolTable(val context: Context, val irModule: IrModuleFragment, val module: Module) { private val TAKE_NAMES = true // Take fqNames for all functions and types (for debug purposes). private inline fun takeName(block: () -> String) = if (TAKE_NAMES) block() else null val classMap = mutableMapOf() val primitiveMap = mutableMapOf() val functionMap = mutableMapOf() private val NAME_ESCAPES = Name.identifier("Escapes") private val NAME_POINTS_TO = Name.identifier("PointsTo") private val FQ_NAME_KONAN = FqName.fromSegments(listOf("kotlin", "native", "internal")) private val FQ_NAME_ESCAPES = FQ_NAME_KONAN.child(NAME_ESCAPES) private val FQ_NAME_POINTS_TO = FQ_NAME_KONAN.child(NAME_POINTS_TO) private val konanPackage = context.builtIns.builtInsModule.getPackage(FQ_NAME_KONAN).memberScope private val getContinuationSymbol = context.ir.symbols.getContinuation private val continuationType = getContinuationSymbol.owner.returnType var privateTypeIndex = 1 // 0 for [Virtual] var privateFunIndex = 0 init { irModule.accept(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitFunction(declaration: IrFunction) { declaration.body?.let { mapFunction(declaration) } } override fun visitField(declaration: IrField) { if (declaration.parent is IrFile) declaration.initializer?.let { mapFunction(declaration) } } override fun visitClass(declaration: IrClass) { declaration.acceptChildrenVoid(this) mapClassReferenceType(declaration) } }, data = null) } private fun IrClass.isFinal() = modality == Modality.FINAL fun mapClassReferenceType(irClass: IrClass): Type { // Do not try to devirtualize ObjC classes. if (irClass.module.name == Name.special("") || irClass.isObjCClass()) return Type.Virtual val isFinal = irClass.isFinal() val isAbstract = irClass.isAbstract() val name = irClass.fqNameForIrSerialization.asString() classMap[irClass]?.let { return it } val placeToClassTable = true val symbolTableIndex = if (placeToClassTable) module.numberOfClasses++ else -1 val type = if (irClass.isExported()) Type.Public(name.localHash.value, privateTypeIndex++, isFinal, isAbstract, null, module, symbolTableIndex, irClass, takeName { name }) else Type.Private(privateTypeIndex++, isFinal, isAbstract, null, module, symbolTableIndex, irClass, takeName { name }) classMap[irClass] = type type.superTypes += irClass.superTypes.map { mapClassReferenceType(it.getClass()!!) } if (!isAbstract) { val layoutBuilder = context.getLayoutBuilder(irClass) type.vtable += layoutBuilder.vtableEntries.map { mapFunction(it.getImplementation(context)!!) } layoutBuilder.methodTableEntries.forEach { type.itable[it.overriddenFunction.computeFunctionName().localHash.value] = mapFunction(it.getImplementation(context)!!) } } else if (irClass.isInterface) { // Warmup interface table so it is computed before DCE. context.getLayoutBuilder(irClass).interfaceTableEntries } return type } private fun choosePrimary(erasure: List): IrClass { if (erasure.size == 1) return erasure[0] // A parameter with constraints - choose class if exists. return erasure.singleOrNull { !it.isInterface } ?: context.ir.symbols.any.owner } private fun mapPrimitiveBinaryType(primitiveBinaryType: PrimitiveBinaryType): Type = primitiveMap.getOrPut(primitiveBinaryType) { Type.Public( primitiveBinaryType.ordinal.toLong(), privateTypeIndex++, true, false, primitiveBinaryType, module, -1, null, takeName { primitiveBinaryType.name } ) } fun mapType(type: IrType): Type { val binaryType = type.computeBinaryType() return when (binaryType) { is BinaryType.Primitive -> mapPrimitiveBinaryType(binaryType.type) is BinaryType.Reference -> mapClassReferenceType(choosePrimary(binaryType.types.toList())) } } private fun mapTypeToFunctionParameter(type: IrType) = type.getInlinedClassNative().let { inlinedClass -> FunctionParameter(mapType(type), inlinedClass?.let { mapFunction(context.getBoxFunction(it)) }, inlinedClass?.let { mapFunction(context.getUnboxFunction(it)) }) } fun mapFunction(declaration: IrDeclaration): FunctionSymbol = when (declaration) { is IrFunction -> mapFunction(declaration) is IrField -> mapPropertyInitializer(declaration) else -> error("Unknown declaration: $declaration") } private fun mapFunction(function: IrFunction): FunctionSymbol = function.target.let { functionMap[it]?.let { return it } val parent = it.parent val containingDeclarationPart = parent.fqNameForIrSerialization.let { if (it.isRoot) "" else "$it." } val name = "kfun:$containingDeclarationPart${it.computeFunctionName()}" val returnsUnit = it is IrConstructor || (!it.isSuspend && it.returnType.isUnit()) val returnsNothing = !it.isSuspend && it.returnType.isNothing() var attributes = 0 if (returnsUnit) attributes = attributes or FunctionAttributes.RETURNS_UNIT if (returnsNothing) attributes = attributes or FunctionAttributes.RETURNS_NOTHING if (it.hasAnnotation(RuntimeNames.exportForCppRuntime) || it.getExternalObjCMethodInfo() != null // TODO-DCE-OBJC-INIT || it.hasAnnotation(RuntimeNames.objCMethodImp)) { attributes = attributes or FunctionAttributes.EXPLICITLY_EXPORTED } val symbol = when { it.isExternal || it.isBuiltInOperator -> { val escapesAnnotation = it.annotations.findAnnotation(FQ_NAME_ESCAPES) val pointsToAnnotation = it.annotations.findAnnotation(FQ_NAME_POINTS_TO) @Suppress("UNCHECKED_CAST") val escapesBitMask = (escapesAnnotation?.getValueArgument(0) as? IrConst)?.value @Suppress("UNCHECKED_CAST") val pointsToBitMask = (pointsToAnnotation?.getValueArgument(0) as? IrVararg)?.elements?.map { (it as IrConst).value } FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }, it.isExported()).apply { escapes = escapesBitMask pointsTo = pointsToBitMask?.toIntArray() } } else -> { val isAbstract = it is IrSimpleFunction && it.modality == Modality.ABSTRACT val irClass = it.parent as? IrClass val bridgeTarget = it.bridgeTarget val isSpecialBridge = bridgeTarget.let { it != null && BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(it.descriptor) != null } val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget) val placeToFunctionsTable = !isAbstract && it !is IrConstructor && irClass != null && !irClass.isNonGeneratedAnnotation() && (it.isOverridableOrOverrides || bridgeTarget != null || function.isSpecial || !irClass.isFinal()) val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1 val frozen = it is IrConstructor && irClass!!.annotations.findAnnotation(KonanFqNames.frozen) != null val functionSymbol = if (it.isExported()) FunctionSymbol.Public(name.localHash.value, module, symbolTableIndex, attributes, it, bridgeTargetSymbol, takeName { name }) else FunctionSymbol.Private(privateFunIndex++, module, symbolTableIndex, attributes, it, bridgeTargetSymbol, takeName { name }) if (frozen) { functionSymbol.escapes = 0b1 // Assume instances of frozen classes escape. } functionSymbol } } functionMap[it] = symbol symbol.parameters = (function.allParameters.map { it.type } + (if (function.isSuspend) listOf(continuationType) else emptyList())) .map { mapTypeToFunctionParameter(it) } .toTypedArray() symbol.returnParameter = mapTypeToFunctionParameter(if (function.isSuspend) context.irBuiltIns.anyType else function.returnType) return symbol } private val IrFunction.isSpecial get() = origin == DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION || origin is DECLARATION_ORIGIN_BRIDGE_METHOD private fun mapPropertyInitializer(irField: IrField): FunctionSymbol { functionMap[irField]?.let { return it } assert(irField.parent !is IrClass) { "All local properties initializers should've been lowered" } val attributes = FunctionAttributes.IS_GLOBAL_INITIALIZER or FunctionAttributes.RETURNS_UNIT val symbol = FunctionSymbol.Private(privateFunIndex++, module, -1, attributes, null, null, takeName { "${irField.computeSymbolName()}_init" }) functionMap[irField] = symbol symbol.parameters = emptyArray() symbol.returnParameter = mapTypeToFunctionParameter(context.irBuiltIns.unitType) return symbol } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters import org.jetbrains.kotlin.backend.common.ir.ir2stringWhole import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.ir.isBoxOrUnboxCall import org.jetbrains.kotlin.backend.konan.util.IntArrayList import org.jetbrains.kotlin.backend.konan.util.LongArrayList import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.explicitParameters import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name import java.util.* import kotlin.collections.ArrayList inline fun BitSet.forEachBit(block: (Int) -> Unit) { var i = -1 while (true) { i = nextSetBit(i + 1) if (i < 0) break block(i) } } // Devirtualization analysis is performed using Variable Type Analysis algorithm. // See http://web.cs.ucla.edu/~palsberg/tba/papers/sundaresan-et-al-oopsla00.pdf for details. internal object Devirtualization { private val TAKE_NAMES = false // Take fqNames for all functions and types (for debug purposes). private inline fun takeName(block: () -> String) = if (TAKE_NAMES) block() else null fun computeRootSet(context: Context, moduleDFG: ModuleDFG, externalModulesDFG: ExternalModulesDFG) : List { fun DataFlowIR.FunctionSymbol.resolved(): DataFlowIR.FunctionSymbol { if (this is DataFlowIR.FunctionSymbol.External) return externalModulesDFG.publicFunctions[this.hash] ?: this return this } val entryPoint = context.ir.symbols.entryPoint?.owner val exportedFunctions = if (entryPoint != null) listOf(moduleDFG.symbolTable.mapFunction(entryPoint).resolved()) else { // In a library every public function and every function accessible via virtual call belongs to the rootset. moduleDFG.symbolTable.functionMap.values.filter { it is DataFlowIR.FunctionSymbol.Public || (it as? DataFlowIR.FunctionSymbol.External)?.isExported == true } + moduleDFG.symbolTable.classMap.values .filterIsInstance() .flatMap { it.vtable + it.itable.values } .filterIsInstance() .filter { moduleDFG.functions.containsKey(it) } } // TODO: Are globals initializers always called whether they are actually reachable from roots or not? val globalInitializers = moduleDFG.symbolTable.functionMap.values.filter { it.isGlobalInitializer } + externalModulesDFG.functionDFGs.keys.filter { it.isGlobalInitializer } val explicitlyExportedFunctions = moduleDFG.symbolTable.functionMap.values.filter { it.explicitlyExported } + externalModulesDFG.functionDFGs.keys.filter { it.explicitlyExported } // Conservatively assume each associated object could be called. // Note: for constructors there is additional parameter () and its type will be added // to instantiating classes since all objects are final types. val associatedObjects = mutableListOf() context.irModule!!.acceptChildrenVoid(object: IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) } override fun visitClass(declaration: IrClass) { context.getLayoutBuilder(declaration).associatedObjects.values.forEach { assert (it.kind == ClassKind.OBJECT) { "An object expected but was ${it.dump()}" } associatedObjects += moduleDFG.symbolTable.mapFunction(it.constructors.single()) } super.visitClass(declaration) } }) return (exportedFunctions + globalInitializers + explicitlyExportedFunctions + associatedObjects).distinct() } fun BitSet.format(allTypes: Array): String { return allTypes.withIndex().filter { this[it.index] }.joinToString { it.value.toString() } } private val VIRTUAL_TYPE_ID = 0 // Id of [DataFlowIR.Type.Virtual]. internal class DevirtualizationAnalysis(val context: Context, val moduleDFG: ModuleDFG, val externalModulesDFG: ExternalModulesDFG) { private val entryPoint = context.ir.symbols.entryPoint?.owner private val symbolTable = moduleDFG.symbolTable sealed class Node(val id: Int) { var directCastEdges: MutableList? = null var reversedCastEdges: MutableList? = null val types = BitSet() var priority = -1 var multiNodeStart = -1 var multiNodeEnd = -1 val multiNodeSize get() = multiNodeEnd - multiNodeStart fun addCastEdge(edge: CastEdge) { if (directCastEdges == null) directCastEdges = ArrayList(1) directCastEdges!!.add(edge) if (edge.node.reversedCastEdges == null) edge.node.reversedCastEdges = ArrayList(1) edge.node.reversedCastEdges!!.add(CastEdge(this, edge.suitableTypes)) } abstract fun toString(allTypes: Array): String class Source(id: Int, typeId: Int, nameBuilder: () -> String): Node(id) { val name = takeName(nameBuilder) init { types.set(typeId) } override fun toString(allTypes: Array): String { return "Source(name='$name', types='${types.format(allTypes)}')" } } class Ordinary(id: Int, nameBuilder: () -> String) : Node(id) { val name = takeName(nameBuilder) override fun toString(allTypes: Array): String { return "Ordinary(name='$name', types='${types.format(allTypes)}')" } } class CastEdge(val node: Node, val suitableTypes: BitSet) } class Function(val symbol: DataFlowIR.FunctionSymbol, val parameters: Array, val returns: Node, val throws: Node) inner class ConstraintGraph { private var nodesCount = 0 val nodes = mutableListOf() val voidNode = addNode { Node.Ordinary(it, { "Void" }) } val virtualNode = addNode { Node.Source(it, VIRTUAL_TYPE_ID, { "Virtual" }) } val arrayItemField = DataFlowIR.Field(null, symbolTable.mapClassReferenceType(context.irBuiltIns.anyClass.owner), 1, "Array\$Item") val functions = mutableMapOf() val externalFunctions = mutableMapOf, Node>() val fields = mutableMapOf() // Do not distinguish receivers. val virtualCallSiteReceivers = mutableMapOf() private fun nextId(): Int = nodesCount++ fun addNode(nodeBuilder: (Int) -> Node) = nodeBuilder(nextId()).also { nodes.add(it) } } private val constraintGraph = ConstraintGraph() private fun DataFlowIR.Type.resolved(): DataFlowIR.Type.Declared { if (this is DataFlowIR.Type.Declared) return this val hash = (this as DataFlowIR.Type.External).hash return externalModulesDFG.publicTypes[hash] ?: error("Unable to resolve exported type $this") } private fun DataFlowIR.FunctionSymbol.resolved(): DataFlowIR.FunctionSymbol { if (this is DataFlowIR.FunctionSymbol.External) return externalModulesDFG.publicFunctions[this.hash] ?: this return this } private inline fun forEachBitInBoth(first: BitSet, second: BitSet, block: (Int) -> Unit) { if (first.cardinality() < second.cardinality()) first.forEachBit { if (second[it]) block(it) } else second.forEachBit { if (first[it]) block(it) } } private inline fun IntArray.forEachEdge(v: Int, block: (Int) -> Unit) { for (i in this[v] until this[v + 1]) block(this[i]) } inner class TypeHierarchy(val allTypes: Array) { private val typesSubTypes = Array(allTypes.size) { mutableListOf() } private val allInheritors = Array(allTypes.size) { BitSet() } init { val visited = BitSet() fun processType(type: DataFlowIR.Type.Declared) { if (visited[type.index]) return visited.set(type.index) type.superTypes .map { it.resolved() } .forEach { superType -> val subTypes = typesSubTypes[superType.index] subTypes += type processType(superType) } } allTypes.forEach { processType(it) } } fun inheritorsOf(type: DataFlowIR.Type.Declared): BitSet { val typeId = type.index val inheritors = allInheritors[typeId] if (!inheritors.isEmpty || type == DataFlowIR.Type.Virtual) return inheritors inheritors.set(typeId) for (subType in typesSubTypes[typeId]) inheritors.or(inheritorsOf(subType)) return inheritors } } private fun DataFlowIR.Type.Declared.calleeAt(callSite: DataFlowIR.Node.VirtualCall) = when (callSite) { is DataFlowIR.Node.VtableCall -> vtable[callSite.calleeVtableIndex] is DataFlowIR.Node.ItableCall -> itable[callSite.calleeHash]!! else -> error("Unreachable") } fun BitSet.copy() = BitSet(this.size()).apply { this.or(this@copy) } fun logPathToType(reversedEdges: IntArray, node: Node, type: Int) { val nodes = constraintGraph.nodes val visited = BitSet() val prev = mutableMapOf() var front = mutableListOf() front.add(node) visited.set(node.id) lateinit var source: Node.Source bfs@while (front.isNotEmpty()) { val prevFront = front front = mutableListOf() for (from in prevFront) { var endBfs = false reversedEdges.forEachEdge(from.id) { toId -> val to = nodes[toId] if (!visited[toId] && to.types[type]) { visited.set(toId) prev[to] = from front.add(to) if (to is Node.Source) { source = to endBfs = true return@forEachEdge } } } if (endBfs) break@bfs val reversedCastEdges = from.reversedCastEdges if (reversedCastEdges != null) for (castEdge in reversedCastEdges) { val to = castEdge.node if (!visited[to.id] && castEdge.suitableTypes[type] && to.types[type]) { visited.set(to.id) prev[to] = from front.add(to) if (to is Node.Source) { source = to break@bfs } } } } } try { var cur: Node = source do { context.log { " #${cur.id}" } cur = prev[cur]!! } while (cur != node) } catch (t: Throwable) { context.log { "Unable to print path" } } } private inner class Condensation(val multiNodes: IntArray, val topologicalOrder: IntArray) { inline fun forEachNode(node: Node, block: (Node) -> Unit) { for (i in node.multiNodeStart until node.multiNodeEnd) block(constraintGraph.nodes[multiNodes[i]]) } } private inner class CondensationBuilder(val directEdges: IntArray, val reversedEdges: IntArray) { val nodes = constraintGraph.nodes val nodesCount = nodes.size val visited = BitSet(nodesCount) var index = 0 val multiNodes = IntArray(nodesCount) fun build(): Condensation { // First phase. val order = IntArray(nodesCount) for (node in nodes) { if (!visited[node.id]) findOrder(node, order) } // Second phase. visited.clear() index = 0 var multiNodesCount = 0 val multiNodesRepresentatives = IntArray(nodesCount) for (i in order.size - 1 downTo 0) { val nodeIndex = order[i] if (visited[nodeIndex]) continue multiNodesRepresentatives[multiNodesCount++] = nodeIndex val start = index paint(nodes[nodeIndex]) val end = index for (multiNodeIndex in start until end) { val node = nodes[multiNodes[multiNodeIndex]] node.multiNodeStart = start node.multiNodeEnd = end } } // Topsort the built condensation. visited.clear() index = 0 val multiNodesOrder = IntArray(multiNodesCount) for (v in multiNodesRepresentatives) { if (!visited[v]) findMultiNodesOrder(nodes[v], multiNodesOrder) } multiNodesOrder.reverse() return Condensation(multiNodes, multiNodesOrder) } private fun findOrder(node: Node, order: IntArray) { visited.set(node.id) directEdges.forEachEdge(node.id) { if (!visited[it]) findOrder(nodes[it], order) } order[index++] = node.id } private fun paint(node: Node) { visited.set(node.id) multiNodes[index++] = node.id reversedEdges.forEachEdge(node.id) { if (!visited[it]) paint(nodes[it]) } } private fun findMultiNodesOrder(multiNode: Node, order: IntArray) { visited.set(multiNode.id) for (v in multiNode.multiNodeStart until multiNode.multiNodeEnd) { val node = nodes[multiNodes[v]] directEdges.forEachEdge(node.id) { val nextMultiNode = multiNodes[nodes[it].multiNodeStart] if (!visited[nextMultiNode]) findMultiNodesOrder(nodes[nextMultiNode], order) } } order[index++] = multiNode.id } } private fun DataFlowIR.Node.VirtualCall.debugString() = irCallSite?.let { ir2stringWhole(it).trimEnd() } ?: this.toString() fun analyze(): AnalysisResult { val functions = moduleDFG.functions + externalModulesDFG.functionDFGs assert(DataFlowIR.Type.Virtual !in symbolTable.classMap.values) { "DataFlowIR.Type.Virtual cannot be in symbolTable.classMap" } val allDeclaredTypes = listOf(DataFlowIR.Type.Virtual) + symbolTable.classMap.values.filterIsInstance() + symbolTable.primitiveMap.values.filterIsInstance() + externalModulesDFG.allTypes val allTypes = Array(allDeclaredTypes.size) { DataFlowIR.Type.Virtual } for (type in allDeclaredTypes) allTypes[type.index] = type val typeHierarchy = TypeHierarchy(allTypes) val rootSet = computeRootSet(context, moduleDFG, externalModulesDFG) val nodesMap = mutableMapOf() val (instantiatingClasses, directEdges, reversedEdges) = buildConstraintGraph(nodesMap, functions, typeHierarchy, rootSet) context.logMultiple { +"FULL CONSTRAINT GRAPH" constraintGraph.nodes.forEach { +" NODE #${it.id}" directEdges.forEachEdge(it.id) { +" EDGE: #${it}z" } it.directCastEdges?.forEach { +" CAST EDGE: #${it.node.id}z casted to ${it.suitableTypes.format(allTypes)}" } allTypes.forEachIndexed { index, type -> if (it.types[index]) +" TYPE: $type" } } +"" } constraintGraph.nodes.forEach { if (it is Node.Source) { assert(reversedEdges[it.id] == reversedEdges[it.id + 1]) { "A source node #${it.id} has incoming edges" } assert(it.reversedCastEdges?.isEmpty() ?: true) { "A source node #${it.id} has incoming edges" } } } context.logMultiple { val edgesCount = constraintGraph.nodes.sumBy { (directEdges[it.id + 1] - directEdges[it.id]) + (it.directCastEdges?.size ?: 0) } +"CONSTRAINT GRAPH: ${constraintGraph.nodes.size} nodes, $edgesCount edges" +"" } val condensation = CondensationBuilder(directEdges, reversedEdges).build() val topologicalOrder = condensation.topologicalOrder.map { constraintGraph.nodes[it] } context.logMultiple { +"CONDENSATION" topologicalOrder.forEachIndexed { index, multiNode -> +" MULTI-NODE #$index" condensation.forEachNode(multiNode) { +" #${it.id}: ${it.toString(allTypes)}" } } +"" } topologicalOrder.forEachIndexed { index, multiNode -> condensation.forEachNode(multiNode) { node -> node.priority = index } } val badEdges = mutableListOf>() for (node in constraintGraph.nodes) { node.directCastEdges ?.filter { it.node.priority < node.priority } // Contradicts topological order. ?.forEach { badEdges += node to it } } badEdges.sortBy { it.second.node.priority } // Heuristic. // First phase - greedy phase. var iterations = 0 val maxNumberOfIterations = 2 do { ++iterations // Handle all 'right-directed' edges. // TODO: this is pessimistic handling of [DataFlowIR.Type.Virtual], think how to do it better. for (multiNode in topologicalOrder) { if (multiNode.multiNodeSize == 1 && multiNode is Node.Source) continue // A source has no incoming edges. val types = BitSet() condensation.forEachNode(multiNode) { node -> reversedEdges.forEachEdge(node.id) { types.or(constraintGraph.nodes[it].types) } node.reversedCastEdges ?.filter { it.node.priority < node.priority } // Doesn't contradict topological order. ?.forEach { val sourceTypes = it.node.types.copy() sourceTypes.and(it.suitableTypes) types.or(sourceTypes) } } condensation.forEachNode(multiNode) { node -> node.types.or(types) } } if (iterations >= maxNumberOfIterations) break var end = true for ((sourceNode, edge) in badEdges) { val distNode = edge.node val missingTypes = sourceNode.types.copy().apply { andNot(distNode.types) } missingTypes.and(edge.suitableTypes) if (!missingTypes.isEmpty) { end = false distNode.types.or(missingTypes) } } } while (!end) // Second phase - do BFS. val nodesCount = constraintGraph.nodes.size val marked = BitSet(nodesCount) var front = IntArray(nodesCount) var prevFront = IntArray(nodesCount) var frontSize = 0 val tempBitSet = BitSet() for ((sourceNode, edge) in badEdges) { val distNode = edge.node tempBitSet.clear() tempBitSet.or(sourceNode.types) tempBitSet.andNot(distNode.types) tempBitSet.and(edge.suitableTypes) distNode.types.or(tempBitSet) if (!marked[distNode.id] && !tempBitSet.isEmpty) { marked.set(distNode.id) front[frontSize++] = distNode.id } } while (frontSize > 0) { val prevFrontSize = frontSize frontSize = 0 val temp = front front = prevFront prevFront = temp for (i in 0 until prevFrontSize) { marked[prevFront[i]] = false val node = constraintGraph.nodes[prevFront[i]] directEdges.forEachEdge(node.id) { distNodeId -> val distNode = constraintGraph.nodes[distNodeId] if (marked[distNode.id]) distNode.types.or(node.types) else { tempBitSet.clear() tempBitSet.or(node.types) tempBitSet.andNot(distNode.types) distNode.types.or(node.types) if (!marked[distNode.id] && !tempBitSet.isEmpty) { marked.set(distNode.id) front[frontSize++] = distNode.id } } } node.directCastEdges?.forEach { edge -> val distNode = edge.node tempBitSet.clear() tempBitSet.or(node.types) tempBitSet.andNot(distNode.types) tempBitSet.and(edge.suitableTypes) distNode.types.or(tempBitSet) if (!marked[distNode.id] && !tempBitSet.isEmpty) { marked.set(distNode.id) front[frontSize++] = distNode.id } } } } context.logMultiple { topologicalOrder.forEachIndexed { index, multiNode -> +"Types of multi-node #$index" condensation.forEachNode(multiNode) { node -> +" Node #${node.id}" allTypes.asSequence() .withIndex() .filter { node.types[it.index] }.toList() .forEach { +" ${it.value}" } } } +"" } val result = mutableMapOf>() val nothing = symbolTable.classMap[context.ir.symbols.nothing.owner] for (function in functions.values) { if (!constraintGraph.functions.containsKey(function.symbol)) continue function.body.forEachNonScopeNode { node -> val virtualCall = node as? DataFlowIR.Node.VirtualCall ?: return@forEachNonScopeNode assert(nodesMap[virtualCall] != null) { "Node for virtual call $virtualCall has not been built" } val receiverNode = constraintGraph.virtualCallSiteReceivers[virtualCall] ?: error("virtualCallSiteReceivers were not built for virtual call $virtualCall") if (receiverNode.types[VIRTUAL_TYPE_ID]) { context.logMultiple { +"Unable to devirtualize callsite ${virtualCall.debugString()}" +" receiver is Virtual" logPathToType(reversedEdges, receiverNode, VIRTUAL_TYPE_ID) +"" } return@forEachNonScopeNode } context.log { "Devirtualized callsite ${virtualCall.debugString()}" } val receiverType = virtualCall.receiverType.resolved() val possibleReceivers = mutableListOf() forEachBitInBoth(receiverNode.types, typeHierarchy.inheritorsOf(receiverType)) { val type = allTypes[it] assert(instantiatingClasses[it]) { "Non-instantiating class $type" } if (type != nothing) { context.logMultiple { +"Path to type $type" logPathToType(reversedEdges, receiverNode, it) } possibleReceivers.add(type) } } context.log { "" } result[virtualCall] = DevirtualizedCallSite(virtualCall.callee.resolved(), possibleReceivers.map { possibleReceiverType -> val callee = possibleReceiverType.calleeAt(virtualCall) if (callee is DataFlowIR.FunctionSymbol.Declared && callee.symbolTableIndex < 0) error("Function ${possibleReceiverType}.$callee cannot be called virtually," + " but actually is at call site: ${virtualCall.debugString()}") DevirtualizedCallee(possibleReceiverType, callee) }) to function.symbol } } context.logMultiple { +"Devirtualized from current module:" result.forEach { virtualCall, devirtualizedCallSite -> if (virtualCall.irCallSite != null) { +"DEVIRTUALIZED" +"FUNCTION: ${devirtualizedCallSite.second}" +"CALL SITE: ${virtualCall.debugString()}" +"POSSIBLE RECEIVERS:" devirtualizedCallSite.first.possibleCallees.forEach { +" TYPE: ${it.receiverType}" } devirtualizedCallSite.first.possibleCallees.forEach { +" FUN: ${it.callee}" } +"" } } +"Devirtualized from external modules:" result.forEach { virtualCall, devirtualizedCallSite -> if (virtualCall.irCallSite == null) { +"DEVIRTUALIZED" +"FUNCTION: ${devirtualizedCallSite.second}" +"CALL SITE: ${virtualCall.debugString()}" +"POSSIBLE RECEIVERS:" devirtualizedCallSite.first.possibleCallees.forEach { +" TYPE: ${it.receiverType}" } devirtualizedCallSite.first.possibleCallees.forEach { +" FUN: ${it.callee}" } +"" } } } return AnalysisResult(result.asSequence().associateBy({ it.key }, { it.value.first }), typeHierarchy) } // Both [directEdges] and [reversedEdges] are the array representation of a graph: // for each node v the edges of that node are stored in edges[edges[v] until edges[v + 1]]. private data class ConstraintGraphBuildResult(val instantiatingClasses: BitSet, val directEdges: IntArray, val reversedEdges: IntArray) // Here we're dividing the build process onto two phases: // 1. build bag of edges and direct edges array; // 2. build reversed edges array from the direct edges array. // This is to lower memory usage (all of these edges structures are more or less equal by size), // and by that we're only holding references to two out of three of them. private fun buildConstraintGraph(nodesMap: MutableMap, functions: Map, typeHierarchy: TypeHierarchy, rootSet: List ): ConstraintGraphBuildResult { val precursor = buildConstraintGraphPrecursor(nodesMap, functions, typeHierarchy, rootSet) return ConstraintGraphBuildResult(precursor.instantiatingClasses, precursor.directEdges, buildReversedEdges(precursor.directEdges, precursor.reversedEdgesCount)) } private class ConstraintGraphPrecursor(val instantiatingClasses: BitSet, val directEdges: IntArray, val reversedEdgesCount: IntArrayList) private fun buildReversedEdges(directEdges: IntArray, reversedEdgesCount: IntArrayList): IntArray { val numberOfNodes = constraintGraph.nodes.size var edgesArraySize = numberOfNodes + 1 for (v in 0 until numberOfNodes) edgesArraySize += reversedEdgesCount[v] val reversedEdges = IntArray(edgesArraySize) var index = numberOfNodes + 1 for (v in 0..numberOfNodes) { reversedEdges[v] = index index += reversedEdgesCount[v] reversedEdgesCount[v] = 0 } for (from in 0 until numberOfNodes) { directEdges.forEachEdge(from) { to -> reversedEdges[reversedEdges[to] + (reversedEdgesCount[to]++)] = from } } return reversedEdges } private fun buildConstraintGraphPrecursor(nodesMap: MutableMap, functions: Map, typeHierarchy: TypeHierarchy, rootSet: List ): ConstraintGraphPrecursor { val constraintGraphBuilder = ConstraintGraphBuilder(nodesMap, functions, typeHierarchy, rootSet, true) constraintGraphBuilder.build() val bagOfEdges = constraintGraphBuilder.bagOfEdges val directEdgesCount = constraintGraphBuilder.directEdgesCount val reversedEdgesCount = constraintGraphBuilder.reversedEdgesCount val numberOfNodes = constraintGraph.nodes.size // numberOfNodes + 1 for convenience. directEdgesCount.reserve(numberOfNodes + 1) reversedEdgesCount.reserve(numberOfNodes + 1) var edgesArraySize = numberOfNodes + 1 for (v in 0 until numberOfNodes) edgesArraySize += directEdgesCount[v] val directEdges = IntArray(edgesArraySize) var index = numberOfNodes + 1 for (v in 0..numberOfNodes) { directEdges[v] = index index += directEdgesCount[v] directEdgesCount[v] = 0 } for (bucket in bagOfEdges) if (bucket != null) for (edge in bucket) { val from = edge.toInt() val to = (edge shr 32).toInt() directEdges[directEdges[from] + (directEdgesCount[from]++)] = to } return ConstraintGraphPrecursor(constraintGraphBuilder.instantiatingClasses, directEdges, reversedEdgesCount) } private class ConstraintGraphVirtualCall(val caller: Function, val virtualCall: DataFlowIR.Node.VirtualCall, val arguments: List, val returnsNode: Node) private inner class ConstraintGraphBuilder(val functionNodesMap: MutableMap, val functions: Map, val typeHierarchy: TypeHierarchy, val rootSet: List, val useTypes: Boolean) { private val allTypes = typeHierarchy.allTypes private val variables = mutableMapOf() private val typesVirtualCallSites = Array(allTypes.size) { mutableListOf() } private val suitableTypes = arrayOfNulls(allTypes.size) private val concreteClasses = arrayOfNulls(allTypes.size) private val virtualTypeFilter = BitSet().apply { set(VIRTUAL_TYPE_ID) } val instantiatingClasses = BitSet() private val preliminaryNumberOfNodes = allTypes.size + // A possible source node for each type. functions.size * 2 + // and nodes for each function. functions.values.sumBy { it.body.allScopes.sumBy { it.nodes.size } // A node for each DataFlowIR.Node. } + functions.values .sumBy { function -> function.body.allScopes.sumBy { it.nodes.count { node -> // A cast if types are different. node is DataFlowIR.Node.Call && node.returnType.resolved() != node.callee.returnParameter.type.resolved() } } } private fun isPrime(x: Int): Boolean { if (x <= 3) return true if (x % 2 == 0) return false var r = 3 while (r * r <= x) { if (x % r == 0) return false r += 2 } return true } private fun makePrime(p: Int): Int { var x = p while (true) { if (isPrime(x)) return x ++x } } // A heuristic: the number of edges in the data flow graph // for any reasonable program is linear in number of nodes. val bagOfEdges = arrayOfNulls(makePrime(preliminaryNumberOfNodes * 5)) val directEdgesCount = IntArrayList() val reversedEdgesCount = IntArrayList() @OptIn(ExperimentalUnsignedTypes::class) private fun addEdge(from: Node, to: Node) { val fromId = from.id val toId = to.id val value = fromId.toLong() or (toId.toLong() shl 32) // This is 64-bit extension of a hashing method from Knuth's "The Art of Computer Programming". // The magic constant is the closest prime to 2^64 * phi, where phi is the golden ratio. val bucketIdx = ((value.toULong() * 11400714819323198393UL) % bagOfEdges.size.toULong()).toInt() val bucket = bagOfEdges[bucketIdx] ?: LongArrayList().also { bagOfEdges[bucketIdx] = it } for (x in bucket) if (x == value) return bucket.add(value) directEdgesCount.reserve(fromId + 1) directEdgesCount[fromId]++ reversedEdgesCount.reserve(toId + 1) reversedEdgesCount[toId]++ } private fun concreteType(type: DataFlowIR.Type.Declared): Int { assert(!(type.isAbstract && type.isFinal)) { "Incorrect type: $type" } return if (type.isAbstract) VIRTUAL_TYPE_ID else { if (!instantiatingClasses[type.index]) error("Type $type is not instantiated") type.index } } private fun ordinaryNode(nameBuilder: () -> String) = constraintGraph.addNode { Node.Ordinary(it, nameBuilder) } private fun sourceNode(typeId: Int, nameBuilder: () -> String) = constraintGraph.addNode { Node.Source(it, typeId, nameBuilder) } private fun concreteClass(type: DataFlowIR.Type.Declared) = concreteClasses[type.index] ?: sourceNode(concreteType(type)) { "Class\$$type" }.also { concreteClasses[type.index] = it} private fun fieldNode(field: DataFlowIR.Field) = constraintGraph.fields.getOrPut(field) { val fieldNode = ordinaryNode { "Field\$$field" } if (entryPoint == null) { // TODO: This is conservative. val fieldType = field.type.resolved() // Some user of our library might place some value into the field. if (fieldType.isFinal) addEdge(concreteClass(fieldType), fieldNode) else addEdge(constraintGraph.virtualNode, fieldNode) } fieldNode } private var stack = mutableListOf() fun build() { // Rapid Type Analysis: find all instantiations and conservatively estimate call graph. // Add all final parameters of the roots. for (root in rootSet) { root.parameters .map { it.type.resolved() } .filter { it.isFinal } .forEach { addInstantiatingClass(it) } } if (entryPoint == null) { // For library assume all public non-abstract classes could be instantiated. // Note: for constructors there is additional parameter () and for associated objects // its type will be added to instantiating classes since all objects are final types. symbolTable.classMap.values .filterIsInstance() .filter { !it.isAbstract } .forEach { addInstantiatingClass(it) } } else { // String arguments are implicitly put into the array parameter of

. addInstantiatingClass(symbolTable.mapType(context.irBuiltIns.stringType).resolved()) addEdge(concreteClass(symbolTable.mapType(context.irBuiltIns.stringType).resolved()), fieldNode(constraintGraph.arrayItemField)) } rootSet.forEach { createFunctionConstraintGraph(it, true) } while (stack.isNotEmpty()) { val symbol = stack.pop() val function = functions[symbol] ?: continue val body = function.body val functionConstraintGraph = constraintGraph.functions[symbol]!! body.forEachNonScopeNode { dfgNodeToConstraintNode(functionConstraintGraph, it) } addEdge(functionNodesMap[body.returns]!!, functionConstraintGraph.returns) addEdge(functionNodesMap[body.throws]!!, functionConstraintGraph.throws) context.logMultiple { +"CONSTRAINT GRAPH FOR $symbol" val ids = function.body.allScopes.flatMap { it.nodes }.withIndex().associateBy({ it.value }, { it.index }) function.body.forEachNonScopeNode { node -> +"FT NODE #${ids[node]}" +DataFlowIR.Function.nodeToString(node, ids) val constraintNode = functionNodesMap[node] ?: variables[node] ?: return@forEachNonScopeNode +" CG NODE #${constraintNode.id}: ${constraintNode.toString(allTypes)}" } +"Returns: #${ids[function.body.returns]}" +"" } } suitableTypes.forEach { it?.and(instantiatingClasses) it?.set(VIRTUAL_TYPE_ID) } if (entryPoint == null) { for (list in typesVirtualCallSites) for (virtualCall in list) { val returnType = virtualCall.virtualCall.returnType.resolved() val totalIncomingEdgesToReturnsNode = if (virtualCall.returnsNode.id >= reversedEdgesCount.size) 0 else reversedEdgesCount[virtualCall.returnsNode.id] if (returnType.isFinal && totalIncomingEdgesToReturnsNode == 0) { // If we are in a library and facing final return type with no possible callees - // this type still can be returned by some user of this library, so propagate it explicitly. addEdge(concreteClass(returnType), virtualCall.returnsNode) } } } } private fun createFunctionConstraintGraph(symbol: DataFlowIR.FunctionSymbol, isRoot: Boolean): Function? { if (symbol is DataFlowIR.FunctionSymbol.External) return null constraintGraph.functions[symbol]?.let { return it } val parameters = Array(symbol.parameters.size) { ordinaryNode { "Param#$it\$$symbol" } } if (isRoot) { // Exported function from the current module. symbol.parameters.forEachIndexed { index, type -> val resolvedType = type.type.resolved() val node = if (!resolvedType.isFinal) constraintGraph.virtualNode // TODO: OBJC-INTEROP-GENERATED-CLASSES else concreteClass(resolvedType) addEdge(node, parameters[index]) } } val returnsNode = ordinaryNode { "Returns\$$symbol" } val throwsNode = ordinaryNode { "Throws\$$symbol" } val functionConstraintGraph = Function(symbol, parameters, returnsNode, throwsNode) constraintGraph.functions[symbol] = functionConstraintGraph stack.push(symbol) return functionConstraintGraph } private fun addInstantiatingClass(type: DataFlowIR.Type.Declared) { if (instantiatingClasses[type.index]) return instantiatingClasses.set(type.index) context.log { "Adding instantiating class: $type" } checkSupertypes(type, type, BitSet()) } private fun processVirtualCall(virtualCall: ConstraintGraphVirtualCall, receiverType: DataFlowIR.Type.Declared) { context.logMultiple { +"Processing virtual call: ${virtualCall.virtualCall.callee}" +"Receiver type: $receiverType" } val callee = receiverType.calleeAt(virtualCall.virtualCall) addEdge(doCall(virtualCall.caller, callee, virtualCall.arguments, callee.returnParameter.type.resolved()), virtualCall.returnsNode) } private fun checkSupertypes(type: DataFlowIR.Type.Declared, inheritor: DataFlowIR.Type.Declared, seenTypes: BitSet) { seenTypes.set(type.index) context.logMultiple { +"Checking supertype $type of $inheritor" typesVirtualCallSites[type.index].let { if (it.isEmpty()) +"None virtual call sites encountered yet" else { +"Virtual call sites:" it.forEach { +" ${it.virtualCall.callee}" } } } +"" } typesVirtualCallSites[type.index].let { virtualCallSites -> var index = 0 while (index < virtualCallSites.size) { processVirtualCall(virtualCallSites[index], inheritor) ++index } } for (superType in type.superTypes) { val resolvedSuperType = superType.resolved() if (!seenTypes[resolvedSuperType.index]) checkSupertypes(resolvedSuperType, inheritor, seenTypes) } } private fun createCastEdge(node: Node, type: DataFlowIR.Type.Declared): Node.CastEdge { if (suitableTypes[type.index] == null) suitableTypes[type.index] = typeHierarchy.inheritorsOf(type).copy() return Node.CastEdge(node, suitableTypes[type.index]!!) } private fun doCast(function: Function, node: Node, type: DataFlowIR.Type.Declared): Node { val castNode = ordinaryNode { "Cast\$${function.symbol}" } val castEdge = createCastEdge(castNode, type) node.addCastEdge(castEdge) return castNode } private fun castIfNeeded(function: Function, node: Node, nodeType: DataFlowIR.Type.Declared, type: DataFlowIR.Type.Declared) = if (!useTypes || type == nodeType) node else doCast(function, node, type) private fun edgeToConstraintNode(function: Function, edge: DataFlowIR.Edge): Node { val result = dfgNodeToConstraintNode(function, edge.node) val castToType = edge.castToType?.resolved() ?: return result return doCast(function, result, castToType) } fun doCall(caller: Function, callee: Function, arguments: List, returnType: DataFlowIR.Type.Declared): Node { assert(callee.parameters.size == arguments.size) { "Function ${callee.symbol} takes ${callee.parameters.size} but caller ${caller.symbol}" + " provided ${arguments.size}" } callee.parameters.forEachIndexed { index, parameter -> addEdge(arguments[index], parameter) } return castIfNeeded(caller, callee.returns, callee.symbol.returnParameter.type.resolved(), returnType) } fun doCall(caller: Function, callee: DataFlowIR.FunctionSymbol, arguments: List, returnType: DataFlowIR.Type.Declared): Node { val resolvedCallee = callee.resolved() val calleeConstraintGraph = createFunctionConstraintGraph(resolvedCallee, false) return if (calleeConstraintGraph == null) { constraintGraph.externalFunctions.getOrPut(resolvedCallee to returnType) { val fictitiousReturnNode = ordinaryNode { "External$resolvedCallee" } if (returnType.isFinal) { addInstantiatingClass(returnType) addEdge(concreteClass(returnType), fictitiousReturnNode) } else { addEdge(constraintGraph.virtualNode, fictitiousReturnNode) // TODO: Unconservative way - when we can use it? // TODO: OBJC-INTEROP-GENERATED-CLASSES // typeHierarchy.inheritorsOf(returnType) // .filterNot { it.isAbstract } // .filter { instantiatingClasses.containsKey(it) } // .forEach { concreteClass(it).addEdge(fictitiousReturnNode) } } fictitiousReturnNode } } else { addEdge(calleeConstraintGraph.throws, caller.throws) doCall(caller, calleeConstraintGraph, arguments, returnType) } } /** * Takes a function DFG's node and creates a constraint graph node corresponding to it. * Also creates all necessary edges. */ private fun dfgNodeToConstraintNode(function: Function, node: DataFlowIR.Node): Node { fun edgeToConstraintNode(edge: DataFlowIR.Edge): Node = edgeToConstraintNode(function, edge) fun doCall(callee: DataFlowIR.FunctionSymbol, arguments: List, returnType: DataFlowIR.Type.Declared) = doCall(function, callee, arguments, returnType) fun readField(field: DataFlowIR.Field, actualType: DataFlowIR.Type.Declared): Node { val fieldNode = fieldNode(field) val expectedType = field.type.resolved() return if (!useTypes || actualType == expectedType) fieldNode else doCast(function, fieldNode, actualType) } fun writeField(field: DataFlowIR.Field, actualType: DataFlowIR.Type.Declared, value: Node) { val fieldNode = fieldNode(field) val expectedType = field.type.resolved() val castedValue = if (!useTypes || actualType == expectedType) value else doCast(function, value, actualType) addEdge(castedValue, fieldNode) } if (node is DataFlowIR.Node.Variable && node.kind != DataFlowIR.VariableKind.Temporary) { var variableNode = variables[node] if (variableNode == null) { variableNode = ordinaryNode { "Variable\$${function.symbol}" } variables[node] = variableNode for (value in node.values) { addEdge(edgeToConstraintNode(value), variableNode) } if (node.kind == DataFlowIR.VariableKind.CatchParameter) function.throws.addCastEdge(createCastEdge(variableNode, node.type.resolved())) } return variableNode } return functionNodesMap.getOrPut(node) { when (node) { is DataFlowIR.Node.Const -> { val type = node.type.resolved() addInstantiatingClass(type) sourceNode(concreteType(type)) { "Const\$${function.symbol}" } } DataFlowIR.Node.Null -> constraintGraph.voidNode is DataFlowIR.Node.Parameter -> function.parameters[node.index] is DataFlowIR.Node.StaticCall -> { val arguments = node.arguments.map(::edgeToConstraintNode) doCall(node.callee, arguments, node.returnType.resolved()) } is DataFlowIR.Node.NewObject -> { val returnType = node.constructedType.resolved() addInstantiatingClass(returnType) val instanceNode = concreteClass(returnType) val arguments = listOf(instanceNode) + node.arguments.map(::edgeToConstraintNode) doCall(node.callee, arguments, returnType) instanceNode } is DataFlowIR.Node.VirtualCall -> { val callee = node.callee val receiverType = node.receiverType.resolved() context.logMultiple { +"Virtual call" +"Caller: ${function.symbol}" +"Callee: $callee" +"Receiver type: $receiverType" +"Possible callees:" forEachBitInBoth(typeHierarchy.inheritorsOf(receiverType), instantiatingClasses) { +allTypes[it].calleeAt(node).toString() } +"" } val returnType = node.returnType.resolved() val arguments = node.arguments.map(::edgeToConstraintNode) val receiverNode = arguments[0] if (receiverType == DataFlowIR.Type.Virtual) addEdge(constraintGraph.virtualNode, receiverNode) if (entryPoint == null && returnType.isFinal) { // If we are in a library and facing final return type then // this type can be returned by some user of this library, so propagate it explicitly. addInstantiatingClass(returnType) } val returnsNode = ordinaryNode { "VirtualCallReturns\$${function.symbol}" } if (receiverType != DataFlowIR.Type.Virtual) typesVirtualCallSites[receiverType.index].add( ConstraintGraphVirtualCall(function, node, arguments, returnsNode)) forEachBitInBoth(typeHierarchy.inheritorsOf(receiverType), instantiatingClasses) { val actualCallee = allTypes[it].calleeAt(node) addEdge(doCall(actualCallee, arguments, actualCallee.returnParameter.type.resolved()), returnsNode) } // Add cast to [Virtual] edge from receiver to returns, if return type is not final. // With this we're reflecting the fact that unknown function can return anything. if (!returnType.isFinal && entryPoint == null) { receiverNode.addCastEdge(Node.CastEdge(returnsNode, virtualTypeFilter)) } // And throw anything. receiverNode.addCastEdge(Node.CastEdge(function.throws, virtualTypeFilter)) constraintGraph.virtualCallSiteReceivers[node] = receiverNode castIfNeeded(function, returnsNode, node.callee.returnParameter.type.resolved(), returnType) } is DataFlowIR.Node.Singleton -> { val type = node.type.resolved() addInstantiatingClass(type) val instanceNode = concreteClass(type) node.constructor?.let { doCall(it, listOf(instanceNode), type) } instanceNode } is DataFlowIR.Node.AllocInstance -> { val type = node.type.resolved() addInstantiatingClass(type) concreteClass(type) } is DataFlowIR.Node.FunctionReference -> { concreteClass(node.type.resolved()) } is DataFlowIR.Node.FieldRead -> { val type = node.field.type.resolved() if (entryPoint == null && type.isFinal) addInstantiatingClass(type) readField(node.field, type) } is DataFlowIR.Node.FieldWrite -> { val type = node.field.type.resolved() if (entryPoint == null && type.isFinal) addInstantiatingClass(type) writeField(node.field, type, edgeToConstraintNode(node.value)) constraintGraph.voidNode } is DataFlowIR.Node.ArrayRead -> readField(constraintGraph.arrayItemField, node.type.resolved()) is DataFlowIR.Node.ArrayWrite -> { writeField(constraintGraph.arrayItemField, node.type.resolved(), edgeToConstraintNode(node.value)) constraintGraph.voidNode } is DataFlowIR.Node.Variable -> node.values.map { edgeToConstraintNode(it) }.let { values -> ordinaryNode { "TempVar\$${function.symbol}" }.also { node -> values.forEach { addEdge(it, node) } } } else -> error("Unreachable") } } } } } class DevirtualizedCallee(val receiverType: DataFlowIR.Type, val callee: DataFlowIR.FunctionSymbol) class DevirtualizedCallSite(val callee: DataFlowIR.FunctionSymbol, val possibleCallees: List) class AnalysisResult(val devirtualizedCallSites: Map, val typeHierarchy: DevirtualizationAnalysis.TypeHierarchy) fun run(irModule: IrModuleFragment, context: Context, moduleDFG: ModuleDFG, externalModulesDFG: ExternalModulesDFG) : AnalysisResult { val devirtualizationAnalysisResult = DevirtualizationAnalysis(context, moduleDFG, externalModulesDFG).analyze() val devirtualizedCallSites = devirtualizationAnalysisResult.devirtualizedCallSites .asSequence() .filter { it.key.irCallSite != null } .associate { it.key.irCallSite!! to it.value } devirtualize(irModule, context, externalModulesDFG, devirtualizedCallSites) return devirtualizationAnalysisResult } private fun devirtualize(irModule: IrModuleFragment, context: Context, externalModulesDFG: ExternalModulesDFG, devirtualizedCallSites: Map) { val symbols = context.ir.symbols val nativePtrEqualityOperatorSymbol = symbols.areEqualByValue[PrimitiveBinaryType.POINTER]!! val optimize = context.shouldOptimize() fun DataFlowIR.Type.resolved(): DataFlowIR.Type.Declared { if (this is DataFlowIR.Type.Declared) return this val hash = (this as DataFlowIR.Type.External).hash return externalModulesDFG.publicTypes[hash] ?: error("Unable to resolve exported type $hash") } fun DataFlowIR.FunctionSymbol.resolved(): DataFlowIR.FunctionSymbol { if (this is DataFlowIR.FunctionSymbol.External) return externalModulesDFG.publicFunctions[this.hash] ?: this return this } fun IrBuilderWithScope.irCoerce(value: IrExpression, coercion: IrFunctionSymbol?) = if (coercion == null) value else irCall(coercion).apply { addArguments(listOf(coercion.descriptor.explicitParameters.single() to value)) } fun IrBuilderWithScope.irCoerce(value: IrExpression, coercion: DataFlowIR.FunctionSymbol.Declared?) = if (coercion == null) value else irCall(coercion.irFunction!!).apply { putValueArgument(0, value) } class PossiblyCoercedValue(val value: IrVariable, val coercion: IrFunctionSymbol?) { fun getFullValue(irBuilder: IrBuilderWithScope) = irBuilder.run { irCoerce(irGet(value), coercion) } } fun IrStatementsBuilder.irTemporary(value: IrExpression, tempName: String, type: IrType): IrVariable { val temporary = IrVariableImpl( value.startOffset, value.endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, IrVariableSymbolImpl(), Name.identifier(tempName), type, isVar = false, isConst = false, isLateinit = false ).apply { this.initializer = value } +temporary return temporary } fun IrStatementsBuilder.irSplitCoercion(expression: IrExpression, tempName: String, actualType: IrType) = if (!expression.isBoxOrUnboxCall()) PossiblyCoercedValue(irTemporary(expression, tempName, actualType), null) else { val coercion = expression as IrCall PossiblyCoercedValue( irTemporary(coercion.getValueArgument(0)!!, tempName, coercion.symbol.owner.explicitParameters.single().type) , coercion.symbol) } fun getTypeConversion(actualType: DataFlowIR.FunctionParameter, targetType: DataFlowIR.FunctionParameter): DataFlowIR.FunctionSymbol.Declared? { if (actualType.boxFunction == null && targetType.boxFunction == null) return null if (actualType.boxFunction != null && targetType.boxFunction != null) { assert (actualType.type.resolved() == targetType.type.resolved()) { "Inconsistent types: ${actualType.type} and ${targetType.type}" } return null } if (actualType.boxFunction == null) return targetType.unboxFunction!!.resolved() as DataFlowIR.FunctionSymbol.Declared return actualType.boxFunction.resolved() as DataFlowIR.FunctionSymbol.Declared } fun IrCallImpl.putArgument(index: Int, value: IrExpression) { var receiversCount = 0 val callee = symbol.owner if (callee.dispatchReceiverParameter != null) ++receiversCount if (callee.extensionReceiverParameter != null) ++receiversCount if (index >= receiversCount) putValueArgument(index - receiversCount, value) else { if (callee.dispatchReceiverParameter != null && index == 0) dispatchReceiver = value else extensionReceiver = value } } fun IrBuilderWithScope.irDevirtualizedCall(callSite: IrCall, actualType: IrType, devirtualizedCallee: DevirtualizedCallee, arguments: List): IrCall { val actualCallee = devirtualizedCallee.callee.irFunction as IrSimpleFunction val call = IrCallImpl( callSite.startOffset, callSite.endOffset, actualType, actualCallee.symbol, actualCallee.typeParameters.size, actualCallee.valueParameters.size, callSite.origin, actualCallee.parentAsClass.symbol ) if (actualCallee.explicitParametersCount == arguments.size) { arguments.forEachIndexed { index, argument -> call.putArgument(index, argument) } return call } assert(actualCallee.isSuspend && actualCallee.explicitParametersCount == arguments.size - 1) { "Incorrect number of arguments: expected [${actualCallee.explicitParametersCount}] but was [${arguments.size - 1}]\n" + actualCallee.dump() } val continuation = arguments.last() for (index in 0..arguments.size - 2) call.putArgument(index, arguments[index]) return irCall(context.ir.symbols.coroutineLaunchpad, actualType).apply { putValueArgument(0, call) putValueArgument(1, continuation) } } fun IrBuilderWithScope.irDevirtualizedCall(callee: IrCall, actualType: IrType, devirtualizedCallee: DevirtualizedCallee, arguments: List): IrExpression { val actualCallee = devirtualizedCallee.callee as DataFlowIR.FunctionSymbol.Declared return actualCallee.bridgeTarget.let { bridgeTarget -> if (bridgeTarget == null) irDevirtualizedCall(callee, actualType, devirtualizedCallee, arguments.map { it.getFullValue(this@irDevirtualizedCall) }) else { val callResult = irDevirtualizedCall(callee, actualType, DevirtualizedCallee(devirtualizedCallee.receiverType, bridgeTarget), arguments.mapIndexed { index, value -> val coercion = getTypeConversion(actualCallee.parameters[index], bridgeTarget.parameters[index]) val fullValue = value.getFullValue(this@irDevirtualizedCall) coercion?.let { irCoerce(fullValue, coercion) } ?: fullValue }) val returnCoercion = getTypeConversion(bridgeTarget.returnParameter, actualCallee.returnParameter) irCoerce(callResult, returnCoercion) } } } irModule.transformChildrenVoid(object: IrElementTransformerVoidWithContext() { override fun visitCall(expression: IrCall): IrExpression { expression.transformChildrenVoid(this) val devirtualizedCallSite = devirtualizedCallSites[expression] val possibleCallees = devirtualizedCallSite?.possibleCallees if (possibleCallees == null || possibleCallees.any { it.callee is DataFlowIR.FunctionSymbol.External } || possibleCallees.any { it.receiverType is DataFlowIR.Type.External }) return expression val callee = expression.symbol.owner val owner = callee.parentAsClass // TODO: Think how to evaluate different unfold factors (in terms of both execution speed and code size). val classMaxUnfoldFactor = 3 val interfaceMaxUnfoldFactor = 3 val maxUnfoldFactor = if (owner.isInterface) interfaceMaxUnfoldFactor else classMaxUnfoldFactor if (possibleCallees.size > maxUnfoldFactor) { // Callsite too complicated to devirtualize. return expression } val startOffset = expression.startOffset val endOffset = expression.endOffset val function = expression.symbol.owner val type = if (callee.isSuspend) context.irBuiltIns.anyNType else function.returnType val irBuilder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) irBuilder.run { val dispatchReceiver = expression.dispatchReceiver!! return when { possibleCallees.isEmpty() -> irBlock(expression) { val throwExpr = irCall(symbols.throwInvalidReceiverTypeException.owner).apply { putValueArgument(0, irCall(symbols.kClassImplConstructor.owner, listOf(dispatchReceiver.type)).apply { putValueArgument(0, irCall(symbols.getObjectTypeInfo.owner).apply { putValueArgument(0, dispatchReceiver) }) }) } // Insert proper unboxing (unreachable code): +irCoerce(throwExpr, symbols.getTypeConversion(throwExpr.type, type)) } optimize && possibleCallees.size == 1 -> { // Monomorphic callsite. irBlock(expression) { val parameters = expression.getArgumentsWithSymbols().mapIndexed { index, arg -> irSplitCoercion(arg.second, "arg$index", arg.first.owner.type) } +irDevirtualizedCall(expression, type, possibleCallees[0], parameters) } } else -> irBlock(expression) { val arguments = expression.getArgumentsWithSymbols().mapIndexed { index, arg -> irSplitCoercion(arg.second, "arg$index", arg.first.owner.type) } val typeInfo = irTemporary(irCall(symbols.getObjectTypeInfo).apply { putValueArgument(0, arguments[0].getFullValue(this@irBlock)) }) val branches = mutableListOf() possibleCallees.mapIndexedTo(branches) { index, devirtualizedCallee -> val actualReceiverType = devirtualizedCallee.receiverType as DataFlowIR.Type.Declared val expectedTypeInfo = IrClassReferenceImpl( startOffset, endOffset, symbols.nativePtrType, actualReceiverType.irClass!!.symbol, actualReceiverType.irClass.defaultType ) val condition = if (optimize && index == possibleCallees.size - 1) irTrue() // Don't check last type in optimize mode. else irCall(nativePtrEqualityOperatorSymbol).apply { putValueArgument(0, irGet(typeInfo)) putValueArgument(1, expectedTypeInfo) } IrBranchImpl( startOffset = startOffset, endOffset = endOffset, condition = condition, result = irDevirtualizedCall(expression, type, devirtualizedCallee, arguments) ) } if (!optimize) { // Add else branch throwing exception for debug purposes. branches.add(IrBranchImpl( startOffset = startOffset, endOffset = endOffset, condition = irTrue(), result = irCall(symbols.throwInvalidReceiverTypeException).apply { putValueArgument(0, irCall(symbols.kClassImplConstructor, listOf(dispatchReceiver.type) ).apply { putValueArgument(0, irGet(typeInfo)) } ) }) ) } +IrWhenImpl( startOffset = startOffset, endOffset = endOffset, type = type, origin = expression.origin, branches = branches ) } } } } }) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.DirectedGraphCondensationBuilder import org.jetbrains.kotlin.backend.konan.DirectedGraphMultiNode import org.jetbrains.kotlin.backend.konan.llvm.Lifetime import org.jetbrains.kotlin.backend.konan.logMultiple import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrClass import kotlin.math.min private val DataFlowIR.Node.isAlloc get() = this is DataFlowIR.Node.NewObject || this is DataFlowIR.Node.AllocInstance private val DataFlowIR.Node.ir get() = when (this) { is DataFlowIR.Node.Call -> irCallSite is DataFlowIR.Node.AllocInstance -> irCallSite is DataFlowIR.Node.ArrayRead -> irCallSite is DataFlowIR.Node.FieldRead -> ir else -> null } internal object EscapeAnalysis { /* * The goal of escape analysis is to estimate lifetimes of all expressions in a program. * Possible lifetimes are: * 0. Stack - an object is used only within its visibility scope within a function. * 1. Local - an object is used only within a function. * 2. Return value - an object is either returned or set to a field of an object being returned. * 3. Parameter - an object is set to a field of some parameters of a function. * 4. Global - otherwise. * For now only Stack and Global lifetimes are supported by the codegen, so others will be pulled up to Global. * * The analysis is performed in two main stages - intraprocedural and interprocedural. * During intraprocedural analysis we remove all control flow related expressions and compute all possible * values of all variables within a function. * The goal of interprocedural analysis is to build points-to graph (object A references object B if and only if * there is a path from the node A to the node B). This is done by building call graph (using devirtualization * for more precise result). But in practice holding this condition both ways can be difficult and bad in terms of * performance, so the algorithm tries to ensure only one part: if object A references object B then there must be * a path from the node A to the node B, with that none of the constraints from the original program will be lost. * It is ok to add some additional constraints, as long as there are not too many of those. * * How do we exactly build the points-to graph out of the call graph? * 1. Build condensation of the call graph. * 2. Handle vertices of the resulting DAG in the reversed topological order (ensuring that all functions being called * are already handled). * 3. For a strongly connected component build the points-to graph iteratively starting with empty graph * (if the process is seemed to not be converging for some function, assume the pessimistic result). * * Escape analysis result of a function is not only lifetimes for all allocations of that function * but also a snippet of its points-to graph (it's a reduced version, basically, subgraph reachable from * the function's parameters). * Assuming the function has parameters P0, P1, .., Pn, where the last parameter is the return parameter, * it turns out that the snippet can be described as an array of relations of form * v.f0.f1...fk -> w.g0.g1...gl where v, w - either one of the function's parameters or special * additional nodes called drains which will be introduced later; and f0, f1, .., fk, g0, g1, .., gl - fields. * * Building points-to graph: * 1. Seed it from the function's DataFlowIR. * There are two kinds of edges: * 1) field. The subgraph for [a.f]: * [a] * | f * V * [a.f] * Notice the label [f] on the edge. * 2) assignment. The subgraph for [a = b]: * [a] * | * V * [b] * No labels on the edge. * When calling a function, take its points-to graph snippet and embed it at the call site, * replacing parameters with actual node arguments. * 2. Build the closure. * Consider an assignment [a = b], and a usage of [a.f] somewhere. Since there is no order on nodes * of DataFlowIR (sea of nodes), the conservative assumption has to be made - [b.f] is also being used * at the same place as [a.f] is. Same applies for usages of [b.f]. * This reasoning leads to the following algorithm: * Consider for the time being all assignment edges undirected and build connected components. * Now, every field usage of any node within a component implies the same usage of any other node * from that component, so the following transformation will be performed: * 1) Consider components one by one. Select a node which has no outgoing assignment edges, * if there is no such a node, create additional node and add assignment edges from every node * to it. Call this node a drain. Then move all beginnings of field edges from all nodes to * the drain leaving the ends as is (this reflects the above consideration - any field usage * can be applied to any node within a component). * 2) After drains creation and field edges moving there might emerge multi-edges (more than one * field edge with the same label going to different components). The components these * multi-edges are pointing at must be coalesced together (this is done either by creating * a new drain or connecting one component's drain to the other). This operation must be * performed until there are no more multi-edges. * After the above transformation has been made, finally, simple lifetime propagation can be performed, * seeing all edges directed. */ // A special marker field for external types implemented in the runtime (mainly, arrays). // The types being passed to the constructor are not used in the analysis - just put there anything. private val intestinesField = DataFlowIR.Field(null, DataFlowIR.Type.Virtual, 1L, "inte\$tines") // A special marker field for return values. // Basically we substitute [return x] with [ret.v@lue = x]. // This is done in order to not handle return parameter somewhat specially. private val returnsValueField = DataFlowIR.Field(null, DataFlowIR.Type.Virtual, 2L, "v@lue") // Roles in which particular object reference is being used. private enum class Role { RETURN_VALUE, THROW_VALUE, WRITE_FIELD, READ_FIELD, WRITTEN_TO_GLOBAL, ASSIGNED, } // The less the higher an object escapes. object Depths { val INFINITY = 1_000_000 val ROOT_SCOPE = 0 val RETURN_VALUE = -1 val PARAMETER = -2 } private class RoleInfoEntry(val node: DataFlowIR.Node? = null, val field: DataFlowIR.Field?) private open class RoleInfo { val entries = mutableListOf() open fun add(entry: RoleInfoEntry) = entries.add(entry) } private class NodeInfo(val depth: Int = Depths.INFINITY) { val data = HashMap() fun add(role: Role, info: RoleInfoEntry?) { val entry = data.getOrPut(role, { RoleInfo() }) if (info != null) entry.add(info) } fun has(role: Role): Boolean = data[role] != null fun escapes() = has(Role.WRITTEN_TO_GLOBAL) || has(Role.THROW_VALUE) override fun toString() = data.keys.joinToString(separator = "; ", prefix = "Roles: ") { it.toString() } } private class FunctionAnalysisResult(val function: DataFlowIR.Function, val nodesRoles: Map) private class IntraproceduralAnalysis(val context: Context, val moduleDFG: ModuleDFG, val externalModulesDFG: ExternalModulesDFG, val callGraph: CallGraph) { val functions = moduleDFG.functions private fun DataFlowIR.Type.resolved(): DataFlowIR.Type.Declared { if (this is DataFlowIR.Type.Declared) return this val hash = (this as DataFlowIR.Type.External).hash return externalModulesDFG.publicTypes[hash] ?: error("Unable to resolve exported type $hash") } fun analyze(): Map { val nothing = moduleDFG.symbolTable.mapClassReferenceType(context.ir.symbols.nothing.owner).resolved() return callGraph.nodes.filter { functions[it.symbol] != null }.associateBy({ it.symbol }) { callGraphNode -> val function = functions[callGraphNode.symbol]!! val body = function.body val nodesRoles = mutableMapOf() fun computeDepths(node: DataFlowIR.Node, depth: Int) { if (node is DataFlowIR.Node.Scope) node.nodes.forEach { computeDepths(it, depth + 1) } else nodesRoles[node] = NodeInfo(depth) } computeDepths(body.rootScope, Depths.ROOT_SCOPE - 1) fun assignRole(node: DataFlowIR.Node, role: Role, infoEntry: RoleInfoEntry?) { nodesRoles[node]!!.add(role, infoEntry) } body.returns.values.forEach { assignRole(it.node, Role.RETURN_VALUE, null) } body.throws.values.forEach { assignRole(it.node, Role.THROW_VALUE, null) } body.forEachNonScopeNode { node -> when (node) { is DataFlowIR.Node.FieldWrite -> { val receiver = node.receiver if (receiver == null) assignRole(node.value.node, Role.WRITTEN_TO_GLOBAL, null) else assignRole(receiver.node, Role.WRITE_FIELD, RoleInfoEntry(node.value.node, node.field)) } is DataFlowIR.Node.Singleton -> { val type = node.type.resolved() if (type != nothing) assignRole(node, Role.WRITTEN_TO_GLOBAL, null) } is DataFlowIR.Node.FieldRead -> { val receiver = node.receiver if (receiver == null) assignRole(node, Role.WRITTEN_TO_GLOBAL, null) else assignRole(receiver.node, Role.READ_FIELD, RoleInfoEntry(node, node.field)) } is DataFlowIR.Node.ArrayWrite -> { assignRole(node.array.node, Role.WRITE_FIELD, RoleInfoEntry(node.value.node, intestinesField)) } is DataFlowIR.Node.ArrayRead -> { assignRole(node.array.node, Role.READ_FIELD, RoleInfoEntry(node, intestinesField)) } is DataFlowIR.Node.Variable -> { for (value in node.values) assignRole(node, Role.ASSIGNED, RoleInfoEntry(value.node, null)) } } } FunctionAnalysisResult(function, nodesRoles) } } } private inline fun > Array.sortedAndDistinct(): Array { this.sort() if (this.isEmpty()) return this val unique = mutableListOf(this[0]) for (i in 1 until this.size) if (this[i] != this[i - 1]) unique.add(this[i]) return unique.toTypedArray() } private class CompressedPointsToGraph(edges: Array) { val edges = edges.sortedAndDistinct() sealed class NodeKind { abstract val absoluteIndex: Int object Return : NodeKind() { override val absoluteIndex = 0 override fun equals(other: Any?) = other === this override fun toString() = "RET" } class Param(val index: Int) : NodeKind() { override val absoluteIndex: Int get() = -1_000_000 + index override fun equals(other: Any?) = index == (other as? Param)?.index override fun toString() = "P$index" } class Drain(val index: Int) : NodeKind() { override val absoluteIndex: Int get() = index + 1 override fun equals(other: Any?) = index == (other as? Drain)?.index override fun toString() = "D$index" } companion object { fun parameter(index: Int, total: Int) = if (index == total - 1) Return else Param(index) } } class Node(val kind: NodeKind, val path: Array) : Comparable { override fun compareTo(other: Node): Int { if (kind.absoluteIndex != other.kind.absoluteIndex) return kind.absoluteIndex.compareTo(other.kind.absoluteIndex) for (i in path.indices) { if (i >= other.path.size) return 1 if (path[i].hash != other.path[i].hash) return path[i].hash.compareTo(other.path[i].hash) } if (path.size < other.path.size) return -1 return 0 } override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Node) return false if (kind != other.kind || path.size != other.path.size) return false for (i in path.indices) if (path[i] != other.path[i]) return false return true } override fun toString() = debugString(null) fun debugString(root: String?) = buildString { append(root ?: kind.toString()) path.forEach { append('.') append(it.name ?: "") } } fun goto(field: DataFlowIR.Field?) = when (field) { null -> this else -> Node(kind, Array(path.size + 1) { if (it < path.size) path[it] else field }) } companion object { fun parameter(index: Int, total: Int) = Node(NodeKind.parameter(index, total), path = emptyArray()) fun drain(index: Int) = Node(NodeKind.Drain(index), path = emptyArray()) } } class Edge(val from: Node, val to: Node) : Comparable { override fun compareTo(other: Edge): Int { val fromCompareResult = from.compareTo(other.from) if (fromCompareResult != 0) return fromCompareResult return to.compareTo(other.to) } override fun equals(other: Any?): Boolean { if (other === this) return true if (other !is Edge) return false return from == other.from && to == other.to } override fun toString() = "$from -> $to" companion object { fun pointsTo(param1: Int, param2: Int, totalParams: Int, kind: Int): Edge { /* * Values extracted from @PointsTo annotation. * kind edge * 1 p1 -> p2 * 2 p1 -> p2.intestines * 3 p1.intestines -> p2 * 4 p1.intestines -> p2.intestines */ if (kind <= 0 || kind > 4) error("Invalid pointsTo kind: $kind") val from = if (kind < 3) Node.parameter(param1, totalParams) else Node(NodeKind.parameter(param1, totalParams), Array(1) { intestinesField }) val to = if (kind % 2 == 1) Node.parameter(param2, totalParams) else Node(NodeKind.parameter(param2, totalParams), Array(1) { intestinesField }) return Edge(from, to) } } } } private class FunctionEscapeAnalysisResult( val numberOfDrains: Int, val pointsTo: CompressedPointsToGraph, escapes: Array ) { val escapes = escapes.sortedAndDistinct() override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is FunctionEscapeAnalysisResult) return false if (escapes.size != other.escapes.size) return false for (i in escapes.indices) if (escapes[i] != other.escapes[i]) return false if (pointsTo.edges.size != other.pointsTo.edges.size) return false for (i in pointsTo.edges.indices) if (pointsTo.edges[i] != other.pointsTo.edges[i]) return false return true } override fun toString(): String { val result = StringBuilder() result.appendLine("PointsTo:") pointsTo.edges.forEach { result.appendLine(" $it") } result.append("Escapes:") escapes.forEach { result.append(' ') result.append(it) } return result.toString() } companion object { fun fromBits(escapesMask: Int, pointsToMasks: List): FunctionEscapeAnalysisResult { val paramCount = pointsToMasks.size val edges = mutableListOf() val escapes = mutableListOf() for (param1 in pointsToMasks.indices) { if (escapesMask and (1 shl param1) != 0) escapes.add(CompressedPointsToGraph.Node.parameter(param1, paramCount)) val curPointsToMask = pointsToMasks[param1] for (param2 in pointsToMasks.indices) { // Read a nibble at position [param2]. val pointsTo = (curPointsToMask shr (4 * param2)) and 15 if (pointsTo != 0) edges.add(CompressedPointsToGraph.Edge.pointsTo(param1, param2, paramCount, pointsTo)) } } return FunctionEscapeAnalysisResult( 0, CompressedPointsToGraph(edges.toTypedArray()), escapes.toTypedArray()) } fun optimistic() = FunctionEscapeAnalysisResult(0, CompressedPointsToGraph(emptyArray()), emptyArray()) fun pessimistic(numberOfParameters: Int) = FunctionEscapeAnalysisResult(0, CompressedPointsToGraph(emptyArray()), Array(numberOfParameters + 1) { CompressedPointsToGraph.Node.parameter(it, numberOfParameters + 1) }) } } private class InterproceduralAnalysis( val context: Context, val callGraph: CallGraph, val intraproceduralAnalysisResults: Map, val externalModulesDFG: ExternalModulesDFG, val lifetimes: MutableMap, val propagateExiledToHeapObjects: Boolean ) { private val symbols = context.ir.symbols private fun DataFlowIR.Type.resolved(): DataFlowIR.Type.Declared { if (this is DataFlowIR.Type.Declared) return this val hash = (this as DataFlowIR.Type.External).hash return externalModulesDFG.publicTypes[hash] ?: error("Unable to resolve exported type $hash") } val escapeAnalysisResults = mutableMapOf() fun analyze() { context.logMultiple { +"CALL GRAPH" callGraph.directEdges.forEach { (t, u) -> +" FUN $t" u.callSites.forEach { val label = when { it.isVirtual -> "VIRTUAL" callGraph.directEdges.containsKey(it.actualCallee) -> "LOCAL" else -> "EXTERNAL" } +" CALLS $label ${it.actualCallee}" } callGraph.reversedEdges[t]!!.forEach { +" CALLED BY $it" } } +"" } val condensation = DirectedGraphCondensationBuilder(callGraph).build() context.logMultiple { +"CONDENSATION" condensation.topologicalOrder.forEach { multiNode -> +" MULTI-NODE" multiNode.nodes.forEach { +" $it" } } +"" +"CONDENSATION(DETAILED)" condensation.topologicalOrder.forEach { multiNode -> +" MULTI-NODE" multiNode.nodes.forEach { +" $it" callGraph.directEdges[it]!!.callSites .filter { callGraph.directEdges.containsKey(it.actualCallee) } .forEach { +" CALLS ${it.actualCallee}" } callGraph.reversedEdges[it]!!.forEach { +" CALLED BY $it" } } } +"" } for (functionSymbol in callGraph.directEdges.keys) { if (!intraproceduralAnalysisResults.containsKey(functionSymbol)) continue // Assume trivial result at the beginning - then iteratively specify it. escapeAnalysisResults[functionSymbol] = FunctionEscapeAnalysisResult.optimistic() } for (multiNode in condensation.topologicalOrder.reversed()) analyze(callGraph, multiNode) context.logMultiple { +"Managed to alloc on stack: ${stackAllocsCount * 100.0 / (globalAllocsCount + stackAllocsCount)}%" +"Total graph size: $totalGraphSize" } } var globalAllocsCount = 0 var stackAllocsCount = 0 var totalGraphSize = 0 private fun analyze(callGraph: CallGraph, multiNode: DirectedGraphMultiNode) { val nodes = multiNode.nodes.filter { intraproceduralAnalysisResults.containsKey(it) }.toMutableSet() context.logMultiple { +"Analyzing multiNode:\n ${nodes.joinToString("\n ") { it.toString() }}" nodes.forEach { from -> +"DataFlowIR" intraproceduralAnalysisResults[from]!!.function.debugOutput() callGraph.directEdges[from]!!.callSites.forEach { to -> +"CALL" +" from $from" +" to ${to.actualCallee}" } } } val pointsToGraphs = nodes.associateBy({ it }, { PointsToGraph(it) }) val toAnalyze = mutableSetOf() toAnalyze.addAll(nodes) val numberOfRuns = nodes.associateWith { 0 }.toMutableMap() while (toAnalyze.isNotEmpty()) { val function = toAnalyze.first() toAnalyze.remove(function) numberOfRuns[function] = numberOfRuns[function]!! + 1 context.log { "Processing function $function" } val startResult = escapeAnalysisResults[function]!! context.log { "Start escape analysis result:\n$startResult" } analyze(callGraph, pointsToGraphs[function]!!, function) val endResult = escapeAnalysisResults[function]!! if (startResult == endResult) { context.log { "Escape analysis is not changed" } } else { context.log { "Escape analysis was refined:\n$endResult" } if (numberOfRuns[function]!! > 1) { // TODO: suboptimal. May be it is possible somehow handle the entire component at once? context.log { "WARNING: Escape analysis for $function seems not to be converging." + " Assuming conservative results." } escapeAnalysisResults[function] = FunctionEscapeAnalysisResult.pessimistic(function.parameters.size) nodes.remove(function) } callGraph.reversedEdges[function]?.forEach { if (nodes.contains(it)) toAnalyze.add(it) } } } pointsToGraphs.forEach { (function, graph) -> // TODO: suboptimal. if (function !in nodes) return@forEach for (node in graph.nodes.keys) { node.ir?.let { val lifetime = graph.lifetimeOf(node) if (node.isAlloc) { if (lifetime == Lifetime.GLOBAL) ++globalAllocsCount if (lifetime == Lifetime.STACK) ++stackAllocsCount lifetimes[it] = lifetime } } } } } private fun arrayLengthOf(node: DataFlowIR.Node): Int? = (node as? DataFlowIR.Node.SimpleConst<*>)?.value as? Int // In case of several possible values, it's unknown what is used. // TODO: if all values are constants which are less limit? ?: (node as? DataFlowIR.Node.Variable) ?.values?.singleOrNull()?.let { arrayLengthOf(it.node) } private val pointerSize = context.llvm.runtime.pointerSize private fun arrayItemSizeOf(irClass: IrClass): Int? = when (irClass.symbol) { symbols.array -> pointerSize symbols.booleanArray -> 1 symbols.byteArray -> 1 symbols.charArray -> 2 symbols.shortArray -> 2 symbols.intArray -> 4 symbols.floatArray -> 4 symbols.longArray -> 8 symbols.doubleArray -> 8 else -> null } private fun arraySize(itemSize: Int, length: Int) = pointerSize /* typeinfo */ + 4 /* size */ + itemSize * length private fun analyze(callGraph: CallGraph, pointsToGraph: PointsToGraph, function: DataFlowIR.FunctionSymbol.Declared) { context.log {"Before calls analysis" } pointsToGraph.log() pointsToGraph.logDigraph(false) callGraph.directEdges[function]!!.callSites.forEach { val callee = it.actualCallee val calleeEAResult = if (it.isVirtual) getExternalFunctionEAResult(it) else callGraph.directEdges[callee]?.let { escapeAnalysisResults[it.symbol]!! } ?: getExternalFunctionEAResult(it) pointsToGraph.processCall(it, calleeEAResult) } context.log { "After calls analysis" } pointsToGraph.log() pointsToGraph.logDigraph(false) // Build transitive closure. val eaResult = pointsToGraph.buildClosure() context.log { "After closure building" } pointsToGraph.log() pointsToGraph.logDigraph(true) escapeAnalysisResults[function] = eaResult totalGraphSize += eaResult.numberOfDrains + eaResult.escapes.size + eaResult.pointsTo.edges.size } private fun DataFlowIR.FunctionSymbol.resolved(): DataFlowIR.FunctionSymbol { if (this is DataFlowIR.FunctionSymbol.External) return externalModulesDFG.publicFunctions[this.hash] ?: this return this } private fun getExternalFunctionEAResult(callSite: CallGraphNode.CallSite): FunctionEscapeAnalysisResult { val callee = callSite.actualCallee.resolved() val calleeEAResult = if (callSite.isVirtual) { context.log { "A virtual call: $callee" } FunctionEscapeAnalysisResult.pessimistic(callee.parameters.size) } else { context.log { "An external call: $callee" } if (callee.name?.startsWith("kfun:kotlin.") == true // TODO: Is it possible to do it in a more fine-grained fashion? && !callee.name.startsWith("kfun:kotlin.native.concurrent")) { context.log { "A function from K/N runtime - can use annotations" } FunctionEscapeAnalysisResult.fromBits( callee.escapes ?: 0, (0..callee.parameters.size).map { callee.pointsTo?.elementAtOrNull(it) ?: 0 } ) } else { context.log { "An unknown function - assume pessimistic result" } FunctionEscapeAnalysisResult.pessimistic(callee.parameters.size) } } context.logMultiple { +"Escape analysis result" +calleeEAResult.toString() +"" } return calleeEAResult } private enum class PointsToGraphNodeKind { STACK, LOCAL, PARAMETER, RETURN_VALUE } private sealed class PointsToGraphEdge(val node: PointsToGraphNode) { class Assignment(node: PointsToGraphNode) : PointsToGraphEdge(node) class Field(node: PointsToGraphNode, val field: DataFlowIR.Field) : PointsToGraphEdge(node) } private class PointsToGraphNode(val nodeInfo: NodeInfo, val node: DataFlowIR.Node?) { val edges = mutableListOf() val reversedEdges = mutableListOf() fun addAssignmentEdge(to: PointsToGraphNode) { edges += PointsToGraphEdge.Assignment(to) to.reversedEdges += PointsToGraphEdge.Assignment(this) } private val fields = mutableMapOf() fun getFieldNode(field: DataFlowIR.Field, graph: PointsToGraph) = fields.getOrPut(field) { graph.newNode().also { edges += PointsToGraphEdge.Field(it, field) } } var depth = when { node is DataFlowIR.Node.Parameter -> Depths.PARAMETER nodeInfo.has(Role.RETURN_VALUE) -> Depths.RETURN_VALUE else -> nodeInfo.depth } val kind get() = when { depth == Depths.PARAMETER -> PointsToGraphNodeKind.PARAMETER depth == Depths.RETURN_VALUE -> PointsToGraphNodeKind.RETURN_VALUE depth != nodeInfo.depth -> PointsToGraphNodeKind.LOCAL else -> PointsToGraphNodeKind.STACK } var forcedLifetime: Lifetime? = null lateinit var drain: PointsToGraphNode val isDrain get() = this == drain val actualDrain: PointsToGraphNode get() = drain.let { if (it.isDrain) it // Flip to the real drain as it is done in the disjoint sets algorithm, // to reduce the time spent in this function. else it.actualDrain.also { drain = it } } val isActualDrain get() = this == actualDrain val beingReturned get() = nodeInfo.has(Role.RETURN_VALUE) } private data class ArrayStaticAllocation(val node: PointsToGraphNode, val irClass: IrClass, val size: Int) private enum class EdgeDirection { FORWARD, BACKWARD } private inner class PointsToGraph(val functionSymbol: DataFlowIR.FunctionSymbol) { val functionAnalysisResult = intraproceduralAnalysisResults[functionSymbol]!! val nodes = mutableMapOf() val allNodes = mutableListOf() fun newNode(nodeInfo: NodeInfo, node: DataFlowIR.Node?) = PointsToGraphNode(nodeInfo, node).also { allNodes.add(it) } fun newNode() = newNode(NodeInfo(), null) fun newDrain() = newNode().also { it.drain = it } val returnsNode = newNode(NodeInfo().also { it.data[Role.RETURN_VALUE] = RoleInfo() }, null) /* * Of all escaping nodes there are some "starting" - call them origins. * Consider a variable [v], which is assigned with two values - [a] and [b]. * Now assume [a] escapes (written to a global, for instance). This implies that [v] also escapes, * but [b] doesn't, albeit [v] (an escaping node) references it. It's because [v] is not an escape origin. */ // The origins of escaping. val escapeOrigins = mutableSetOf() // Nodes reachable from either of escape origins going along all edges (assignment and/or field). val reachableFromEscapeOrigins = mutableSetOf() // Nodes referencing any escape origin only by assignment edges. val referencingEscapeOrigins = mutableSetOf() fun escapes(node: PointsToGraphNode) = node in reachableFromEscapeOrigins || node in referencingEscapeOrigins val ids = ( listOf(functionAnalysisResult.function.body.rootScope) + functionAnalysisResult.function.body.allScopes.flatMap { it.nodes } ) .withIndex().associateBy({ it.value }, { it.index }) fun lifetimeOf(node: DataFlowIR.Node) = nodes[node]!!.let { it.forcedLifetime ?: lifetimeOf(it) } fun lifetimeOf(node: PointsToGraphNode) = if (escapes(node)) Lifetime.GLOBAL else when (node.kind) { PointsToGraphNodeKind.PARAMETER -> Lifetime.ARGUMENT PointsToGraphNodeKind.STACK -> { // A value doesn't escape from its scope - it can be allocated on the stack. Lifetime.STACK } PointsToGraphNodeKind.LOCAL -> { // A value is neither stored into a global nor into any parameter nor into the return value - // it can be allocated locally. Lifetime.LOCAL } PointsToGraphNodeKind.RETURN_VALUE -> { when { // If a value is explicitly returned. node.node?.let { it in returnValues } == true -> Lifetime.RETURN_VALUE // A value is stored into a field of the return value. else -> Lifetime.INDIRECT_RETURN_VALUE } } } private val returnValues: Set init { context.logMultiple { +"Building points-to graph for function $functionSymbol" +"Results of preliminary function analysis" } functionAnalysisResult.nodesRoles.forEach { (node, roles) -> context.log { "NODE ${nodeToString(node)}: $roles" } nodes[node] = newNode(roles, node) } val returnValues = mutableListOf() functionAnalysisResult.nodesRoles.forEach { (node, roles) -> val ptgNode = nodes[node]!! addEdges(ptgNode, roles) if (ptgNode.beingReturned) { returnsNode.getFieldNode(returnsValueField, this).addAssignmentEdge(ptgNode) returnValues += node } if (roles.escapes()) escapeOrigins += ptgNode } this.returnValues = returnValues.toSet() val escapes = functionSymbol.escapes if (escapes != null) { // Parameters are declared in the root scope val parameters = functionAnalysisResult.function.body.rootScope.nodes .filterIsInstance() for (parameter in parameters) if (escapes and (1 shl parameter.index) != 0) escapeOrigins += nodes[parameter]!! if (escapes and (1 shl parameters.size) != 0) escapeOrigins += returnsNode } } private fun addEdges(from: PointsToGraphNode, roles: NodeInfo) { val assigned = roles.data[Role.ASSIGNED] assigned?.entries?.forEach { val to = nodes[it.node!!]!! from.addAssignmentEdge(to) } roles.data[Role.WRITE_FIELD]?.entries?.forEach { roleInfo -> val value = nodes[roleInfo.node!!]!! val field = roleInfo.field!! from.getFieldNode(field, this).addAssignmentEdge(value) } roles.data[Role.READ_FIELD]?.entries?.forEach { roleInfo -> val result = nodes[roleInfo.node!!]!! val field = roleInfo.field!! result.addAssignmentEdge(from.getFieldNode(field, this)) } } private fun nodeToStringWhole(node: DataFlowIR.Node) = DataFlowIR.Function.nodeToString(node, ids) private fun nodeToString(node: DataFlowIR.Node) = ids[node].toString() fun log() = context.logMultiple { +"POINTS-TO GRAPH" +"NODES" val tempIds = mutableMapOf() var tempIndex = 0 allNodes.forEach { if (it.node == null) tempIds[it] = tempIndex++ } allNodes.forEach { val tempId = tempIds[it] +" ${lifetimeOf(it)} ${it.depth} ${if (it in escapeOrigins) "ESCAPES" else ""} ${it.node?.let { nodeToString(it) } ?: "t$tempId"}" +(it.node?.let { nodeToStringWhole(it) } ?: " t$tempId") } } fun logDigraph( markDrains: Boolean, nodeFilter: (PointsToGraphNode) -> Boolean = { true }, nodeLabel: ((PointsToGraphNode) -> String)? = null ) = context.logMultiple { +"digraph {" val tempIds = mutableMapOf() var tempIndex = 0 allNodes.forEach { if (it.node == null) tempIds[it] = tempIndex++ } fun PointsToGraphNode.format() = (nodeLabel?.invoke(this) ?: (if (markDrains && isDrain) "d" else "") + (node?.let { "n${ids[it]!!}" } ?: "t${tempIds[this]}")) + "[d=$depth,${if (this in escapeOrigins) "eo" else if (escapes(this)) "e" else ""}]" for (from in allNodes) { if (!nodeFilter(from)) continue for (it in from.edges) { val to = it.node if (!nodeFilter(to)) continue when (it) { is PointsToGraphEdge.Assignment -> +" \"${from.format()}\" -> \"${to.format()}\";" is PointsToGraphEdge.Field -> +" \"${from.format()}\" -> \"${to.format()}\" [ label=\"${it.field.name}\"];" } } } +"}" } fun processCall(callSite: CallGraphNode.CallSite, calleeEscapeAnalysisResult: FunctionEscapeAnalysisResult) { val call = callSite.call context.logMultiple { +"Processing callSite" +nodeToStringWhole(call) +"Actual callee: ${callSite.actualCallee}" +"Callee escape analysis result:" +calleeEscapeAnalysisResult.toString() } val arguments = if (call is DataFlowIR.Node.NewObject) { (0..call.arguments.size).map { if (it == 0) call else call.arguments[it - 1].node } } else { (0..call.arguments.size).map { if (it < call.arguments.size) call.arguments[it].node else call } } val calleeDrains = Array(calleeEscapeAnalysisResult.numberOfDrains) { newNode() } fun mapNode(compressedNode: CompressedPointsToGraph.Node): Pair { val (arg, rootNode) = when (val kind = compressedNode.kind) { CompressedPointsToGraph.NodeKind.Return -> if (call is DataFlowIR.Node.NewObject) // TODO: This better be an assertion. DataFlowIR.Node.Null to null else arguments.last() to nodes[arguments.last()] is CompressedPointsToGraph.NodeKind.Param -> arguments[kind.index] to nodes[arguments[kind.index]] is CompressedPointsToGraph.NodeKind.Drain -> null to calleeDrains[kind.index] } if (rootNode == null) return arg to rootNode val path = compressedNode.path var node: PointsToGraphNode = rootNode for (field in path) { node = when (field) { returnsValueField -> node else -> node.getFieldNode(field, this) } } return arg to node } calleeEscapeAnalysisResult.escapes.forEach { escapingNode -> val (arg, node) = mapNode(escapingNode) if (node == null) { context.log { "WARNING: There is no node ${nodeToString(arg!!)}" } return@forEach } escapeOrigins += node context.log { "Node ${escapingNode.debugString(arg?.let { nodeToString(it) })} escapes" } } calleeEscapeAnalysisResult.pointsTo.edges.forEach { edge -> val (fromArg, fromNode) = mapNode(edge.from) if (fromNode == null) { context.log { "WARNING: There is no node ${nodeToString(fromArg!!)}" } return@forEach } val (toArg, toNode) = mapNode(edge.to) if (toNode == null) { context.log { "WARNING: There is no node ${nodeToString(toArg!!)}" } return@forEach } fromNode.addAssignmentEdge(toNode) context.logMultiple { +"Adding edge" +" FROM ${edge.from.debugString(fromArg?.let { nodeToString(it) })}" +" TO ${edge.to.debugString(toArg?.let { nodeToString(it) })}" } } } fun buildClosure(): FunctionEscapeAnalysisResult { context.logMultiple { +"BUILDING CLOSURE" +"Return values:" returnValues.forEach { +" ${nodeToString(it)}" } } buildDrains() logDigraph(true) computeLifetimes() /* * The next part determines the function's escape analysis result. * Of course, the simplest way would be to just take the entire graph, but it might be big, * and during call graph traversal these EA graphs will continue to grow (since they are * being embedded at each call site). To overcome this, the graph must be reduced. * Let us call nodes that will be part of the result "interesting", and, obviously, * "interesting drains" - drains that are going to be in the result. */ val (numberOfDrains, nodeIds) = paintInterestingNodes() logDigraph(true, { nodeIds[it] != null }, { nodeIds[it].toString() }) // TODO: Remove redundant edges. val compressedEdges = mutableListOf() val escapingNodes = mutableListOf() for (from in allNodes) { val fromCompressedNode = nodeIds[from] ?: continue if (from in escapeOrigins) escapingNodes += fromCompressedNode for (edge in from.edges) { val toCompressedNode = nodeIds[edge.node] ?: continue when (edge) { is PointsToGraphEdge.Assignment -> compressedEdges += CompressedPointsToGraph.Edge(fromCompressedNode, toCompressedNode) is PointsToGraphEdge.Field -> if (edge.node == from /* A loop */) { compressedEdges += CompressedPointsToGraph.Edge( fromCompressedNode.goto(edge.field), toCompressedNode) } } } } return FunctionEscapeAnalysisResult( numberOfDrains, CompressedPointsToGraph(compressedEdges.toTypedArray()), escapingNodes.toTypedArray() ) } private fun buildDrains() { // TODO: This is actually conservative. If a field is being read of some node, // then here it is assumed that it might also be being read from any node reachable // by assignment edges considering them undirected. But in reality it is enough to just // merge two sets: reachable by assignment edges and reachable by reversed assignment edges. // But, there will be a downside - drains will have to be created for each field access, // thus increasing the graph size significantly. val visited = mutableSetOf() val drains = mutableListOf() val createdDrains = mutableSetOf() // Create drains. for (node in allNodes.toTypedArray() /* Copy as [allNodes] might change inside */) { if (node in visited) continue val component = mutableListOf() buildComponent(node, visited, component) val drain = trySelectDrain(component)?.also { it.drain = it } ?: newDrain().also { createdDrains += it } drains += drain component.forEach { if (it == drain) return@forEach it.drain = drain val assignmentEdges = mutableListOf() for (edge in it.edges) { if (edge is PointsToGraphEdge.Assignment) assignmentEdges += edge else drain.edges += edge } it.edges.clear() it.edges += assignmentEdges } } fun PointsToGraphNode.flipTo(otherDrain: PointsToGraphNode) { require(isDrain) require(otherDrain.isDrain) drain = otherDrain otherDrain.edges += edges edges.clear() } // Merge the components multi-edges are pointing at. // TODO: This looks very similar to the system of disjoint sets algorithm. while (true) { val toMerge = mutableListOf>() for (drain in drains) { val fields = drain.edges.groupBy { edge -> (edge as? PointsToGraphEdge.Field)?.field ?: error("A drain cannot have outgoing assignment edges") } for (nodes in fields.values) { if (nodes.size == 1) continue for (i in nodes.indices) { val firstNode = nodes[i].node val secondNode = if (i == nodes.size - 1) nodes[0].node else nodes[i + 1].node if (firstNode.actualDrain != secondNode.actualDrain) toMerge += Pair(firstNode, secondNode) } } } if (toMerge.isEmpty()) break val possibleDrains = mutableListOf() for ((first, second) in toMerge) { // Merge components: try to flip one drain to the other if possible, // otherwise just create a new one. val firstDrain = first.actualDrain val secondDrain = second.actualDrain when { firstDrain == secondDrain -> continue firstDrain in createdDrains -> { secondDrain.flipTo(firstDrain) possibleDrains += firstDrain } secondDrain in createdDrains -> { firstDrain.flipTo(secondDrain) possibleDrains += secondDrain } else -> { // Create a new drain in order to not create false constraints. val newDrain = newDrain().also { createdDrains += it } firstDrain.flipTo(newDrain) secondDrain.flipTo(newDrain) possibleDrains += newDrain } } } drains.clear() possibleDrains.filterTo(drains) { it.isDrain } } // Compute current drains. drains.clear() allNodes.filterTo(drains) { it.isActualDrain } // A validation. for (drain in drains) { val fields = mutableMapOf() for (edge in drain.edges) { val field = (edge as? PointsToGraphEdge.Field)?.field ?: error("A drain cannot have outgoing assignment edges") val node = edge.node.actualDrain fields.getOrPut(field) { node }.also { if (it != node) error("Drains have not been built correctly") } } } // Coalesce multi-edges. for (drain in drains) { val actualDrain = drain.actualDrain val fields = actualDrain.edges.groupBy { edge -> (edge as? PointsToGraphEdge.Field)?.field ?: error("A drain cannot have outgoing assignment edges") } actualDrain.edges.clear() for (nodes in fields.values) { if (nodes.size == 1) { actualDrain.edges += nodes[0] continue } // All nodes in [nodes] must be connected to each other, but a drain, by definition, // cannot have outgoing assignment edges, thus a new drain must be created here. nodes.atMostOne { it.node.isActualDrain } ?.node?.actualDrain?.flipTo(newDrain()) for (i in nodes.indices) { val firstNode = nodes[i].node val secondNode = if (i == nodes.size - 1) nodes[0].node else nodes[i + 1].node firstNode.addAssignmentEdge(secondNode) } // Can pick any. actualDrain.edges += nodes[0] } } // Make sure every node within a component points to the component's drain. for (node in allNodes) { val drain = node.actualDrain node.drain = drain if (node != drain) node.addAssignmentEdge(drain) } } // Drains, other than interesting, can be safely omitted from the result. private fun findInterestingDrains(parameters: Array): Set { // Starting with all reachable from the parameters. val interestingDrains = mutableSetOf() for (param in parameters) { val drain = param.drain if (drain !in interestingDrains) findReachableDrains(drain, interestingDrains) } // Then iteratively remove all drains forming kind of a "cactus" // (picking a leaf drain with only one incoming edge at a time). // They can be removed because they don't add any relations between the parameters. val reversedEdges = interestingDrains.associateWith { mutableListOf>() } val edgesCount = mutableMapOf() val leaves = mutableListOf() for (drain in interestingDrains) { var count = 0 for (edge in drain.edges) { val nextDrain = edge.node.drain reversedEdges[nextDrain]!! += drain to edge if (nextDrain in interestingDrains) ++count } edgesCount[drain] = count if (count == 0) leaves.push(drain) } val parameterDrains = parameters.map { it.drain }.toSet() while (leaves.isNotEmpty()) { val drain = leaves.pop() val incomingEdges = reversedEdges[drain]!! if (incomingEdges.isEmpty()) { if (drain !in parameterDrains) error("A drain with no incoming edges") if (!parameters.any { it.isDrain && escapes(it) }) interestingDrains.remove(drain) continue } if (drain in parameterDrains) continue if (incomingEdges.size == 1 && incomingEdges[0].let { (node, edge) -> escapes(node) || !escapes(edge.node) } ) { interestingDrains.remove(drain) val prevDrain = incomingEdges[0].first val count = edgesCount[prevDrain]!! - 1 edgesCount[prevDrain] = count if (count == 0) leaves.push(prevDrain) } } return interestingDrains } private fun getParameterNodes(): Array { // Put a dummyNode in order to not bother with nullability. Then rewrite it with actual values. val dummyNode = returnsNode // Anything will do. val parameters = Array(functionSymbol.parameters.size + 1) { dummyNode } // Parameters are declared in the root scope. functionAnalysisResult.function.body.rootScope.nodes .filterIsInstance() .forEach { if (parameters[it.index] != dummyNode) error("Two parameters with the same index ${it.index}: $it, ${parameters[it.index].node}") parameters[it.index] = nodes[it]!! } parameters[functionSymbol.parameters.size] = returnsNode return parameters } private fun paintInterestingNodes(): Pair> { var drainsCount = 0 val drainFactory = { CompressedPointsToGraph.Node.drain(drainsCount++) } val parameters = getParameterNodes() val interestingDrains = findInterestingDrains(parameters) val nodeIds = paintNodes(parameters, interestingDrains, drainFactory) buildComponentsClosures(nodeIds) handleNotTakenEscapeOrigins(nodeIds, drainFactory) restoreOptimizedAwayDrainsIfNeeded(interestingDrains, nodeIds, drainFactory) return Pair(drainsCount, nodeIds) } private fun handleNotTakenEscapeOrigins( nodeIds: MutableMap, drainFactory: () -> CompressedPointsToGraph.Node ) { // We've marked reachable nodes from the parameters, also taking some of the escape origins. // But there might be some escape origins that are not taken, yet referencing some of the // marked nodes. Do the following: find all escaping nodes only taking marked escape origins // into account, compare the result with all escaping nodes. Now for each non-marked escape origin // find nodes escaping because of it, take those who aren't escaping through the marked origins, // and add an additional node, pointing at those and mark it as an escape origin. val reachableFromTakenEscapeOrigins = mutableSetOf() val referencingTakenEscapeOrigins = mutableSetOf() val reachableFromNotTakenEscapeOrigins = mutableSetOf() val referencingNotTakenEscapeOrigins = mutableSetOf() val reachableFringeFromNotTakenEscapeOrigins = mutableSetOf() val fringeReferencingNotTakenEscapeOrigins = mutableSetOf() for (escapeOrigin in escapeOrigins) { if (nodeIds[escapeOrigin] == null) { if (escapeOrigin !in reachableFromNotTakenEscapeOrigins) findReachableFringe(escapeOrigin, reachableFromNotTakenEscapeOrigins, reachableFringeFromNotTakenEscapeOrigins, nodeIds) if (escapeOrigin !in referencingNotTakenEscapeOrigins) findReferencingFringe(escapeOrigin, referencingNotTakenEscapeOrigins, fringeReferencingNotTakenEscapeOrigins, nodeIds) } else { if (escapeOrigin !in reachableFromTakenEscapeOrigins) findReachable(escapeOrigin, reachableFromTakenEscapeOrigins, false, null) if (escapeOrigin !in referencingTakenEscapeOrigins) findReferencing(escapeOrigin, referencingTakenEscapeOrigins) } } fun addAdditionalEscapeOrigins(escapingNodes: List, direction: EdgeDirection) { escapingNodes .groupBy { it.drain } .forEach { (drain, nodes) -> val tempNode = newNode() nodeIds[tempNode] = drainFactory() tempNode.drain = drain tempNode.addAssignmentEdge(drain) escapeOrigins += tempNode for (node in nodes) when (direction) { EdgeDirection.FORWARD -> tempNode.addAssignmentEdge(node) EdgeDirection.BACKWARD -> node.addAssignmentEdge(tempNode) } } } addAdditionalEscapeOrigins( reachableFringeFromNotTakenEscapeOrigins .filterNot { it in reachableFromTakenEscapeOrigins }, EdgeDirection.FORWARD ) addAdditionalEscapeOrigins( fringeReferencingNotTakenEscapeOrigins .filterNot { it in referencingTakenEscapeOrigins }, EdgeDirection.BACKWARD ) } private fun restoreOptimizedAwayDrainsIfNeeded( interestingDrains: Set, nodeIds: MutableMap, drainFactory: () -> CompressedPointsToGraph.Node ) { // Here we try to find this subgraph within one component: [v -> d; w -> d; v !-> w; w !-> v]. // In most cases such a node [d] is just the drain of the component, // but it may have been optimized away. // This is needed because components are built with edges being considered undirected, so // this implicit connection between [v] and [w] may be needed. Note, however, that the // opposite subgraph: [d -> v; d -> w; v !-> w; w !-> v] is not interesting, because [d] // can't hold both values simultaneously, but two references can hold the same value // at the same time, that's the difference. // For concrete example see [codegen/escapeAnalysis/test10.kt]. val connectedNodes = mutableSetOf>() allNodes.filter { nodeIds[it] != null && nodeIds[it.drain] == null /* The drain has been optimized away */ } .forEach { node -> val referencingNodes = findReferencing(node).filter { nodeIds[it] != null } for (i in referencingNodes.indices) for (j in i + 1 until referencingNodes.size) { val firstNode = referencingNodes[i] val secondNode = referencingNodes[j] connectedNodes.add(Pair(firstNode, secondNode)) connectedNodes.add(Pair(secondNode, firstNode)) } } allNodes.filter { nodeIds[it] == null && it.drain in interestingDrains && nodeIds[it.drain] == null } .forEach { node -> val referencingNodes = findReferencing(node).filter { nodeIds[it] != null } for (i in referencingNodes.indices) for (j in i + 1 until referencingNodes.size) { val firstNode = referencingNodes[i] val secondNode = referencingNodes[j] val pair = Pair(firstNode, secondNode) if (pair in connectedNodes) continue // It is not an actual drain, but a temporary node to reflect the found constraint. val additionalDrain = newDrain() // For consistency. additionalDrain.depth = min(firstNode.depth, secondNode.depth) firstNode.addAssignmentEdge(additionalDrain) secondNode.addAssignmentEdge(additionalDrain) nodeIds[additionalDrain] = drainFactory() connectedNodes.add(pair) connectedNodes.add(Pair(secondNode, firstNode)) } } } private fun findReferencing(node: PointsToGraphNode, visited: MutableSet) { visited += node for (edge in node.reversedEdges) { val nextNode = edge.node if (nextNode !in visited) findReferencing(nextNode, visited) } } private fun findReferencing(node: PointsToGraphNode): Set { val visited = mutableSetOf() findReferencing(node, visited) return visited } private fun trySelectDrain(component: MutableList) = component.firstOrNull { node -> if (node.edges.any { it is PointsToGraphEdge.Assignment }) false else findReferencing(node).size == component.size } private fun buildComponent( node: PointsToGraphNode, visited: MutableSet, component: MutableList ) { visited += node component += node for (edge in node.edges) { if (edge is PointsToGraphEdge.Assignment && edge.node !in visited) buildComponent(edge.node, visited, component) } for (edge in node.reversedEdges) { if (edge.node !in visited) buildComponent(edge.node, visited, component) } } private fun findReachable(node: PointsToGraphNode, visited: MutableSet, assignmentOnly: Boolean, nodeIds: MutableMap?) { visited += node node.edges.forEach { val next = it.node if ((it is PointsToGraphEdge.Assignment || !assignmentOnly) && next !in visited && nodeIds?.containsKey(next) != false) findReachable(next, visited, assignmentOnly, nodeIds) } } private fun findFringe(node: PointsToGraphNode, visited: MutableSet, fringe: MutableSet, direction: EdgeDirection, nodeIds: MutableMap) { visited += node if (nodeIds[node] != null) { fringe += node return } val edges = when (direction) { EdgeDirection.FORWARD -> node.edges EdgeDirection.BACKWARD -> node.reversedEdges } for (edge in edges) { val next = edge.node if (next !in visited) findFringe(next, visited, fringe, direction, nodeIds) } } private fun findReachableFringe( node: PointsToGraphNode, visited: MutableSet, fringe: MutableSet, nodeIds: MutableMap ) = findFringe(node, visited, fringe, EdgeDirection.FORWARD, nodeIds) private fun findReferencingFringe( node: PointsToGraphNode, visited: MutableSet, fringe: MutableSet, nodeIds: MutableMap ) = findFringe(node, visited, fringe, EdgeDirection.BACKWARD, nodeIds) private fun buildComponentsClosures(nodeIds: MutableMap) { for (node in allNodes) { if (node !in nodeIds) continue val visited = mutableSetOf() findReachable(node, visited, true, null) val visitedInInterestingSubgraph = mutableSetOf() findReachable(node, visitedInInterestingSubgraph, true, nodeIds) visited.removeAll(visitedInInterestingSubgraph) for (reachable in visited) if (reachable in nodeIds) node.addAssignmentEdge(reachable) } } private fun propagateLifetimes() { val visited = mutableSetOf() fun propagate(node: PointsToGraphNode) { visited += node val depth = node.depth for (edge in node.edges) { val nextNode = edge.node if (nextNode !in visited && nextNode.depth >= depth) { nextNode.depth = depth propagate(nextNode) } } } for (node in allNodes.sortedBy { it.depth }) { if (node !in visited) propagate(node) } } private fun propagateEscapeOrigin(node: PointsToGraphNode) { if (node !in reachableFromEscapeOrigins) findReachable(node, reachableFromEscapeOrigins, false, null) if (node !in referencingEscapeOrigins) findReferencing(node, referencingEscapeOrigins) } private fun computeLifetimes() { propagateLifetimes() escapeOrigins.forEach { propagateEscapeOrigin(it) } val stackArrayCandidates = mutableListOf() for ((node, ptgNode) in nodes) { if (node.ir == null) continue val computedLifetime = lifetimeOf(node) var lifetime = computedLifetime if (lifetime != Lifetime.STACK) { // TODO: Support other lifetimes - requires arenas. lifetime = Lifetime.GLOBAL } if (lifetime == Lifetime.STACK && node is DataFlowIR.Node.NewObject) { val constructedType = node.constructedType.resolved() constructedType.irClass?.let { irClass -> val itemSize = arrayItemSizeOf(irClass) if (itemSize != null) { val sizeArgument = node.arguments.first().node val arrayLength = arrayLengthOf(sizeArgument) if (arrayLength != null) { stackArrayCandidates += ArrayStaticAllocation(ptgNode, irClass, arraySize(itemSize, arrayLength)) } else { // Can be placed into the local arena. // TODO. Support Lifetime.LOCAL lifetime = Lifetime.GLOBAL } } } } if (lifetime != computedLifetime) { if (propagateExiledToHeapObjects && node.isAlloc) { context.log { "Forcing node ${nodeToString(node)} to escape" } escapeOrigins += ptgNode propagateEscapeOrigin(ptgNode) } else { ptgNode.forcedLifetime = lifetime } } } stackArrayCandidates.sortBy { it.size } // TODO: To a setting? var allowedToAlloc = 65536 for ((ptgNode, irClass, size) in stackArrayCandidates) { if (lifetimeOf(ptgNode) != Lifetime.STACK) continue if (size <= allowedToAlloc) allowedToAlloc -= size else { allowedToAlloc = 0 // Do not exile primitive arrays - they ain't reference no object. if (irClass.symbol == symbols.array && propagateExiledToHeapObjects) { context.log { "Forcing node ${nodeToString(ptgNode.node!!)} to escape" } escapeOrigins += ptgNode propagateEscapeOrigin(ptgNode) } else { ptgNode.forcedLifetime = Lifetime.GLOBAL // TODO: Change to LOCAL when supported. } } } } private fun findReachableDrains(drain: PointsToGraphNode, visitedDrains: MutableSet) { visitedDrains += drain for (edge in drain.edges) { if (edge is PointsToGraphEdge.Assignment) error("A drain cannot have outgoing assignment edges") val nextDrain = edge.node.drain if (nextDrain !in visitedDrains) findReachableDrains(nextDrain, visitedDrains) } } private fun paintNodes( parameters: Array, interestingDrains: Set, drainFactory: () -> CompressedPointsToGraph.Node ): MutableMap { val nodeIds = mutableMapOf() for (index in parameters.indices) nodeIds[parameters[index]] = CompressedPointsToGraph.Node.parameter(index, parameters.size) val standAloneDrains = interestingDrains.toMutableSet() for (drain in interestingDrains) for (edge in drain.edges) { val node = edge.node if (node.isDrain && node != drain /* Skip loops */) standAloneDrains.remove(node) } for (drain in standAloneDrains) { if (nodeIds[drain] == null // A little optimization - skip leaf drains. && drain.edges.any { it.node.drain in interestingDrains }) nodeIds[drain] = drainFactory() } var front = nodeIds.keys.toList() while (front.isNotEmpty()) { val nextFront = mutableListOf() for (node in front) { val nodeId = nodeIds[node]!! node.edges.filterIsInstance().forEach { edge -> val field = edge.field val nextNode = edge.node if (nextNode.drain in interestingDrains && nextNode != node /* Skip loops */) { val nextNodeId = nodeId.goto(field) if (nodeIds[nextNode] != null) error("Expected only one incoming field edge. ${nodeIds[nextNode]} != $nextNodeId") nodeIds[nextNode] = nextNodeId if (nextNode.isDrain) nextFront += nextNode } } } front = nextFront } for (drain in interestingDrains) { if (nodeIds[drain] == null && drain.edges.any { it.node.drain in interestingDrains }) error("Drains have not been painted properly") } return nodeIds } } } fun computeLifetimes(context: Context, moduleDFG: ModuleDFG, externalModulesDFG: ExternalModulesDFG, callGraph: CallGraph, lifetimes: MutableMap) { assert(lifetimes.isEmpty()) try { val intraproceduralAnalysisResult = IntraproceduralAnalysis(context, moduleDFG, externalModulesDFG, callGraph).analyze() InterproceduralAnalysis(context, callGraph, intraproceduralAnalysisResult, externalModulesDFG, lifetimes, // TODO: This is a bit conservative, but for more aggressive option some support from runtime is // needed (namely, determining that a pointer is from the stack; this is easy for x86 or x64, // but what about all other platforms?). propagateExiledToHeapObjects = true ).analyze() } catch (t: Throwable) { val extraUserInfo = """ Please try to disable escape analysis and rerun the build. To do it add the following snippet to the gradle script: kotlin.targets.withType { binaries.all { freeCompilerArgs += "-Xdisable-phases=EscapeAnalysis" } } In case of using command line compiler add this option: "-Xdisable-phases=EscapeAnalysis". Also, consider filing an issue with full Gradle log here: https://kotl.in/issue """.trimIndent() context.reportCompilationError("Escape analysis failure:\n$extraUserInfo\n\n${t.message}\n${t.stackTraceToString()}") } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/LocalEscapeAnalysis.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.optimizations import org.jetbrains.kotlin.backend.konan.llvm.Lifetime import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.logMultiple import org.jetbrains.kotlin.backend.konan.descriptors.isArrayWithFixedSizeItems internal object LocalEscapeAnalysis { private enum class EscapeState { GLOBAL_ESCAPE, // escape through global reference ARG_ESCAPE, // escapes through function arguments, return or throw NO_ESCAPE // object does not escape } class FunctionAnalyzer(val function: DataFlowIR.Function, val context: Context) { // Escape states of nodes. private val nodesEscapeStates = mutableMapOf() // Connected objects map, escape state change of key node influences on all connected nodes states. private val connectedObjects = mutableMapOf>() // Maximum size of array which is allowed to allocate on stack. // TODO: replace into KonanConfigKeys? private val stackAllocationArraySizeLimit = 64 private var DataFlowIR.Node.escapeState: EscapeState set(value) { // Write state only if it has more limitations. val writeState = nodesEscapeStates[this]?.let { value < it } ?: true if (writeState) { nodesEscapeStates[this] = value } } get() = nodesEscapeStates.getOrDefault(this, EscapeState.NO_ESCAPE) private fun connectObjects(node: DataFlowIR.Node, connectedNode: DataFlowIR.Node) { connectedObjects.getOrPut(node) { mutableSetOf() }.add(connectedNode) } private fun findOutArraySize(node: DataFlowIR.Node): Int? { if (node is DataFlowIR.Node.SimpleConst<*>) { return node.value as? Int } if (node is DataFlowIR.Node.Variable) { // In case of several possible values, it's unknown what is used. // TODO: if all values are constants which are less limit? if (node.values.size == 1) { return findOutArraySize(node.values.first().node) } } return null } private fun evaluateEscapeState(node: DataFlowIR.Node) { node.escapeState = EscapeState.NO_ESCAPE when (node) { is DataFlowIR.Node.Call -> { val pointsToMasks = (0..node.callee.parameters.size) .map { node.callee.pointsTo?.elementAtOrNull(it) ?: 0 } val returnPointsToMask = pointsToMasks[node.callee.parameters.size] node.arguments.forEachIndexed { index, arg -> // Check information about arguments escaping. val escapes = node.callee.escapes?.let { it and (1 shl index) != 0 } ?: node.callee !is DataFlowIR.FunctionSymbol.External // Connect with all arguments that return value points to. if (returnPointsToMask and (1 shl index) != 0) { connectObjects(node, arg.node) } // Connect current argument with other it points to. (0..node.callee.parameters.size).filter { pointsToMasks[index] and (1 shl it) != 0 }.forEach { if (it == node.callee.parameters.size) { // Argument points to this. connectObjects(arg.node, node) } else { connectObjects(arg.node, node.arguments[it].node) } } arg.node.escapeState = if (escapes) EscapeState.ARG_ESCAPE else EscapeState.NO_ESCAPE } // Check size for array allocation. if (node is DataFlowIR.Node.NewObject && node.constructedType is DataFlowIR.Type.Declared) { node.constructedType.irClass?.let { irClass -> // Work only with arrays which elements size is known. if (irClass.isArrayWithFixedSizeItems) { val sizeArgument = node.arguments.first().node val arraySize = findOutArraySize(sizeArgument) if (arraySize == null || arraySize > stackAllocationArraySizeLimit) { node.escapeState = EscapeState.GLOBAL_ESCAPE } } else { node.escapeState = EscapeState.GLOBAL_ESCAPE } } } } is DataFlowIR.Node.Singleton -> { node.escapeState = EscapeState.GLOBAL_ESCAPE } is DataFlowIR.Node.FieldRead -> { node.receiver?.let { obj -> connectObjects(node, obj.node) } ?: run { node.escapeState = EscapeState.GLOBAL_ESCAPE } } is DataFlowIR.Node.FieldWrite -> { node.receiver?.let { obj -> connectObjects(obj.node, node.value.node) } ?: run { node.escapeState = EscapeState.GLOBAL_ESCAPE node.value.node.escapeState = EscapeState.GLOBAL_ESCAPE } } is DataFlowIR.Node.ArrayWrite -> { connectObjects(node.array.node, node.value.node) } is DataFlowIR.Node.Variable -> { node.values.forEach { connectObjects(node, it.node) } } is DataFlowIR.Node.ArrayRead -> { // If element of array(return value) points to array(this value) and escapes then array also should escape. if (((node.callee.pointsTo?.elementAtOrNull(node.callee.parameters.size) ?: 0) and (1 shl 0)) != 0) { connectObjects(node, node.array.node) } } is DataFlowIR.Node.Parameter -> { node.escapeState = EscapeState.ARG_ESCAPE } } } private inner class ConnectedObjectsVisitor { val visitedObjects = mutableSetOf() fun visit(node: DataFlowIR.Node, action: (DataFlowIR.Node) -> Unit) { action(node) visitedObjects.add(node) connectedObjects[node]?.forEach { if (!visitedObjects.contains(it)) { visit(it, action) } } } } private fun propagateState(state: EscapeState, visitor: ConnectedObjectsVisitor) { connectedObjects.filter { it.key.escapeState == state }.forEach { (key, value) -> value.forEach { obj -> visitor.visit(obj) { it.escapeState = key.escapeState } } } } fun analyze(lifetimes: MutableMap) { function.body.forEachNonScopeNode { node -> evaluateEscapeState(node) } function.body.returns.escapeState = EscapeState.ARG_ESCAPE function.body.throws.escapeState = EscapeState.ARG_ESCAPE // Change state of connected objects. val visitor = ConnectedObjectsVisitor() propagateState(EscapeState.GLOBAL_ESCAPE, visitor) propagateState(EscapeState.ARG_ESCAPE, visitor) nodesEscapeStates.filter { it.value == EscapeState.NO_ESCAPE }.forEach { (irNode, _) -> val ir = when (irNode) { is DataFlowIR.Node.Call -> irNode.irCallSite else -> null } ir?.let { lifetimes.put(it, Lifetime.STACK) context.log { "$ir does not escape" } } } } } fun analyze(context: Context, moduleDFG: ModuleDFG, lifetimes: MutableMap) { moduleDFG.functions.forEach { (name, function) -> context.logMultiple { +"===============================================" +"Visiting $name" +"DATA FLOW IR:" +function.debugString() } FunctionAnalyzer(function, context).analyze(lifetimes) } } fun computeLifetimes(context: Context, moduleDFG: ModuleDFG, lifetimes: MutableMap) { context.log { "In local EA" } assert(lifetimes.isEmpty()) analyze(context, moduleDFG, lifetimes) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrSerializationUtil.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.resolve.OverridingUtil // TODO: move me somewhere /** * Implementation of given method. * * TODO: this method is actually a part of resolve and probably duplicates another one */ internal fun IrSimpleFunction.resolveFakeOverrideMaybeAbstract() = this.resolveFakeOverride(allowAbstract = true)!! internal fun IrProperty.resolveFakeOverrideMaybeAbstract() = this.getter!!.resolveFakeOverrideMaybeAbstract().correspondingPropertySymbol!!.owner internal fun IrField.resolveFakeOverrideMaybeAbstract() = this.correspondingPropertySymbol!!.owner.resolveFakeOverrideMaybeAbstract().backingField /** * Implementation of given method. * * TODO: this method is actually a part of resolve and probably duplicates another one */ internal fun T.resolveFakeOverrideMaybeAbstract(): Set { if (this.kind.isReal) { return setOf(this) } else { val overridden = OverridingUtil.getOverriddenDeclarations(this) val filtered = OverridingUtil.filterOutOverridden(overridden) // TODO: is it correct to take first? @Suppress("UNCHECKED_CAST") return filtered as Set } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDeclarationTable.kt ================================================ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable import org.jetbrains.kotlin.backend.common.serialization.signature.DescToIrIdSignatureComputer import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.resolve.descriptorUtil.module class KonanGlobalDeclarationTable(signatureSerializer: IdSignatureSerializer, builtIns: IrBuiltIns) : GlobalDeclarationTable(signatureSerializer, KonanManglerIr) { init { loadKnownBuiltins(builtIns) } } class KonanDeclarationTable( globalDeclarationTable: GlobalDeclarationTable ) : DeclarationTable(globalDeclarationTable) { private val signatureIdComposer = DescToIrIdSignatureComputer(KonanIdSignaturer(KonanManglerDesc)) // TODO: We should get rid of this extension point in favor of proper support in IR-based mangler. override fun tryComputeBackendSpecificSignature(declaration: IrDeclaration): IdSignature? = if (declaration.descriptor.module.isFromInteropLibrary()) { signatureIdComposer.computeSignature(declaration) } else null } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIdSignaturer.kt ================================================ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.resolve.descriptorUtil.module class KonanIdSignaturer(private val mangler: KotlinMangler.DescriptorMangler) : IdSignatureDescriptor(mangler) { override fun createSignatureBuilder(): DescriptorBasedSignatureBuilder = KonanDescriptorBasedSignatureBuilder(mangler) private class KonanDescriptorBasedSignatureBuilder( mangler: KotlinMangler.DescriptorMangler ) : DescriptorBasedSignatureBuilder(mangler) { /** * We need a way to distinguish interop declarations from usual ones * to be able to link against them. We do it by marking them with * [IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY] flag. */ private fun markInteropDeclaration(descriptor: DeclarationDescriptor) { if (descriptor.module.isFromInteropLibrary()) { mask = mask or IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.encode(true) } } override fun platformSpecificAlias(descriptor: TypeAliasDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificClass(descriptor: ClassDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificConstructor(descriptor: ConstructorDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificFunction(descriptor: FunctionDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificGetter(descriptor: PropertyGetterDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificPackage(descriptor: PackageFragmentDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificProperty(descriptor: PropertyDescriptor) { markInteropDeclaration(descriptor) } override fun platformSpecificSetter(descriptor: PropertySetterDescriptor) { markInteropDeclaration(descriptor) } } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt ================================================ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer import org.jetbrains.kotlin.backend.konan.RuntimeNames import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.hasAnnotation class KonanIrFileSerializer( messageLogger: IrMessageLogger, declarationTable: DeclarationTable, expectDescriptorToSymbol: MutableMap, skipExpects: Boolean, bodiesOnlyForInlines: Boolean = false ): IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, skipExpects = skipExpects, bodiesOnlyForInlines = bodiesOnlyForInlines) { override fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean { val fqn = when (node) { is IrFunction -> RuntimeNames.exportForCppRuntime is IrClass -> RuntimeNames.exportTypeInfoAnnotation else -> return false } return node.annotations.hasAnnotation(fqn) } override fun backendSpecificSerializeAllMembers(irClass: IrClass) = !KonanFakeOverrideClassFilter.needToConstructFakeOverrides(irClass) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt ================================================ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IrMessageLogger class KonanIrModuleSerializer( messageLogger: IrMessageLogger, irBuiltIns: IrBuiltIns, private val expectDescriptorToSymbol: MutableMap, val skipExpects: Boolean ) : IrModuleSerializer(messageLogger) { private val signaturer = IdSignatureSerializer(KonanManglerIr) private val globalDeclarationTable = KonanGlobalDeclarationTable(signaturer, irBuiltIns) // We skip files with IR for C structs and enums because they should be // generated anew. // // See [IrProviderForCEnumAndCStructStubs.kt#L31] on why we generate IR. // We may switch from IR generation to LazyIR later (at least for structs; enums are tricky) // without changing kotlin libraries that depend on interop libraries. override fun backendSpecificFileFilter(file: IrFile): Boolean = file.fileEntry.name != IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName override fun createSerializerForFile(file: IrFile): KonanIrFileSerializer = KonanIrFileSerializer(messageLogger, KonanDeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects) } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.konan.CachedLibraries import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module object KonanFakeOverrideClassFilter : FakeOverrideClassFilter { private fun IdSignature.isInteropSignature(): Boolean = with(this) { IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test() } // This is an alternative to .isObjCClass that doesn't need to walk up all the class heirarchy, // rather it only looks at immediate super class symbols. private fun IrClass.hasInteropSuperClass() = this.superTypes .mapNotNull { it.classOrNull } .filter { it is IrPublicSymbolBase<*> } .any { it.signature?.isInteropSignature() ?: false } override fun needToConstructFakeOverrides(clazz: IrClass): Boolean { return !clazz.hasInteropSuperClass() } } internal class KonanIrLinker( private val currentModule: ModuleDescriptor, override val functionalInterfaceFactory: IrAbstractFunctionFactory, override val translationPluginContext: TranslationPluginContext?, messageLogger: IrMessageLogger, builtIns: IrBuiltIns, symbolTable: SymbolTable, private val forwardModuleDescriptor: ModuleDescriptor?, private val stubGenerator: DeclarationStubGenerator, private val cenumsProvider: IrProviderForCEnumAndCStructStubs, exportedDependencies: List, private val cachedLibraries: CachedLibraries ) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) { companion object { private val C_NAMES_NAME = Name.identifier("cnames") private val OBJC_NAMES_NAME = Name.identifier("objcnames") val FORWARD_DECLARATION_ORIGIN = object : IrDeclarationOriginImpl("FORWARD_DECLARATION_ORIGIN") {} const val offset = SYNTHETIC_OFFSET } override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib() private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) } override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, IdSignatureSerializer(KonanManglerIr), builtIns, KonanFakeOverrideClassFilter) override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { if (moduleDescriptor === forwardModuleDescriptor) { return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected") } if (klib is KotlinLibrary && klib.isInteropLibrary()) { // See https://youtrack.jetbrains.com/issue/KT-43517. // Disabling this flag forces linker to generate IR. val isCached = false //cachedLibraries.isLibraryCached(klib) return KonanInteropModuleDeserializer(moduleDescriptor, isCached) } return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) } private inner class KonanModuleDeserializer( moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy){ override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) } private inner class KonanInteropModuleDeserializer( moduleDescriptor: ModuleDescriptor, private val isLibraryCached: Boolean ) : IrModuleDeserializer(moduleDescriptor) { init { assert(moduleDescriptor.kotlinLibrary.isInteropLibrary()) } private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinder( moduleDescriptor, KonanManglerDesc, DescriptorByIdSignatureFinder.LookupMode.MODULE_ONLY ) private fun IdSignature.isInteropSignature(): Boolean = IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test() override fun contains(idSig: IdSignature): Boolean { if (idSig.isPublic) { if (idSig.isInteropSignature()) { // TODO: add descriptor cache?? return descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null } } return false } private fun DeclarationDescriptor.isCEnumsOrCStruct(): Boolean = cenumsProvider.isCEnumOrCStruct(this) private val fileMap = mutableMapOf() private fun getIrFile(packageFragment: PackageFragmentDescriptor): IrFile = fileMap.getOrPut(packageFragment) { IrFileImpl(NaiveSourceBasedFileEntryImpl(IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName), packageFragment).also { moduleFragment.files.add(it) } } private fun resolveCEnumsOrStruct(descriptor: DeclarationDescriptor, idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { val file = getIrFile(descriptor.findPackage()) return cenumsProvider.getDeclaration(descriptor, idSig, file, symbolKind).symbol } override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: error("Expecting descriptor for $idSig") // If library is cached we don't need to create an IrClass for struct or enum. if (!isLibraryCached && descriptor.isCEnumsOrCStruct()) return resolveCEnumsOrStruct(descriptor, idSig, symbolKind) val symbolOwner = stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner return symbolOwner.symbol } override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns) override val moduleDependencies: Collection = listOfNotNull(forwardDeclarationDeserializer) } private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) { init { assert(moduleDescriptor.isForwardDeclarationModule) } private val declaredDeclaration = mutableMapOf() private fun IdSignature.isForwardDeclarationSignature(): Boolean { if (isPublic) { return packageFqName().run { startsWith(C_NAMES_NAME) || startsWith(OBJC_NAMES_NAME) } } return false } override fun contains(idSig: IdSignature): Boolean = idSig.isForwardDeclarationSignature() private fun resolveDescriptor(idSig: IdSignature): ClassDescriptor = with(idSig as IdSignature.PublicSignature) { val classId = ClassId(packageFqName(), FqName(declarationFqName), false) moduleDescriptor.findClassAcrossModuleDependencies(classId) ?: error("No declaration found with $idSig") } private fun buildForwardDeclarationStub(descriptor: ClassDescriptor): IrClass { return stubGenerator.generateClassStub(descriptor).also { it.origin = FORWARD_DECLARATION_ORIGIN } } override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { assert(symbolKind == BinarySymbolData.SymbolKind.CLASS_SYMBOL) { "Only class could be a Forward declaration $idSig (kind $symbolKind)" } val descriptor = resolveDescriptor(idSig) val actualModule = descriptor.module if (actualModule !== moduleDescriptor) { val moduleDeserializer = deserializersForModules[actualModule] ?: error("No module deserializer for $actualModule") moduleDeserializer.addModuleReachableTopLevel(idSig) return symbolTable.referenceClassFromLinker(idSig) } return declaredDeclaration.getOrPut(idSig) { buildForwardDeclarationStub(descriptor) }.symbol } override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns) override val moduleDependencies: Collection = emptyList() } val modules: Map get() = mutableMapOf().apply { deserializersForModules .filter { !it.key.isForwardDeclarationModule && it.value.moduleDescriptor !== currentModule } .forEach { this.put(it.key.konanLibrary!!.libraryName, it.value.moduleFragment) } } class KonanPluginContext( override val moduleDescriptor: ModuleDescriptor, override val symbolTable: ReferenceSymbolTable, override val typeTranslator: TypeTranslator, override val irBuiltIns: IrBuiltIns ):TranslationPluginContext } class KonanIrModuleFragmentImpl( override val descriptor: ModuleDescriptor, override val irBuiltins: IrBuiltIns, files: List = emptyList(), ) : IrModuleFragment() { override val name: Name get() = descriptor.name // TODO override val files: MutableList = files.toMutableList() val konanLibrary = (descriptor.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitModuleFragment(this, data) override fun acceptChildren(visitor: IrElementVisitor, data: D) { files.forEach { it.accept(visitor, data) } } override fun transformChildren(transformer: IrElementTransformer, data: D) { files.forEachIndexed { i, irFile -> files[i] = irFile.transform(transformer, data) } } } fun IrModuleFragment.toKonanModule() = KonanIrModuleFragmentImpl(descriptor, irBuiltins, files) class KonanFileMetadataSource(val module: KonanIrModuleFragmentImpl) : MetadataSource.File { override val name: Name? = null } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt ================================================ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorBasedKotlinManglerImpl import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorExportCheckerVisitor import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorMangleComputer import org.jetbrains.kotlin.backend.common.serialization.mangle.ir.IrBasedKotlinManglerImpl import org.jetbrains.kotlin.backend.common.serialization.mangle.ir.IrExportCheckerVisitor import org.jetbrains.kotlin.backend.common.serialization.mangle.ir.IrMangleComputer import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.hasAnnotation abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrBasedKotlinManglerImpl() { override fun getExportChecker(): IrExportCheckerVisitor = KonanIrExportChecker() override fun getMangleComputer(mode: MangleMode): IrMangleComputer = KonanIrManglerComputer(StringBuilder(256), mode, withReturnType) private class KonanIrExportChecker : IrExportCheckerVisitor() { override fun IrDeclaration.isPlatformSpecificExported(): Boolean { if (this is IrSimpleFunction) if (isFakeOverride) return false // TODO: revise if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { // Treat any `@SymbolName` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) { // Treat any `@ExportForCppRuntime` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { // Treat `@CName` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { return true } return false } } private class KonanIrManglerComputer(builder: StringBuilder, mode: MangleMode, private val withReturnType: Boolean) : IrMangleComputer(builder, mode) { override fun copy(newMode: MangleMode): IrMangleComputer = KonanIrManglerComputer(builder, newMode, withReturnType) override fun addReturnType(): Boolean = withReturnType override fun IrFunction.platformSpecificFunctionName(): String? { (if (this is IrConstructor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo() ?.let { return buildString { if (extensionReceiverParameter != null) { append(extensionReceiverParameter!!.type.getClass()!!.name) append(".") } append("objc:") append(it.selector) if (this@platformSpecificFunctionName is IrConstructor && this@platformSpecificFunctionName.isObjCConstructor) append("#Constructor") if ((this@platformSpecificFunctionName as? IrSimpleFunction)?.correspondingPropertySymbol != null) { append("#Accessor") } } } return null } override fun IrFunction.specialValueParamPrefix(param: IrValueParameter): String { // TODO: there are clashes originating from ObjectiveC interop. // kotlinx.cinterop.ObjCClassOf.create(format: kotlin.String): T defined in platform.Foundation in file Foundation.kt // and // kotlinx.cinterop.ObjCClassOf.create(string: kotlin.String): T defined in platform.Foundation in file Foundation.kt return if (this.hasObjCMethodAnnotation || this.hasObjCFactoryAnnotation || this.isObjCClassMethod()) "${param.name}:" else "" } } } object KonanManglerIr : AbstractKonanIrMangler(false) abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl() { override fun getExportChecker(): DescriptorExportCheckerVisitor = KonanDescriptorExportChecker() override fun getMangleComputer(mode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(StringBuilder(256), mode) private class KonanDescriptorExportChecker : DescriptorExportCheckerVisitor() { override fun DeclarationDescriptor.isPlatformSpecificExported(): Boolean { if (this is SimpleFunctionDescriptor) { if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false } // TODO: revise if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { // Treat any `@SymbolName` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) { // Treat any `@ExportForCppRuntime` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { // Treat `@CName` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { return true } return false } } private class KonanDescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : DescriptorMangleComputer(builder, mode) { override fun copy(newMode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(builder, newMode) override fun FunctionDescriptor.platformSpecificFunctionName(): String? { (if (this is ConstructorDescriptor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo() ?.let { return buildString { if (extensionReceiverParameter != null) { append(extensionReceiverParameter!!.type.constructor.declarationDescriptor!!.name) append(".") } append("objc:") append(it.selector) if (this@platformSpecificFunctionName is ConstructorDescriptor && this@platformSpecificFunctionName.isObjCConstructor) append("#Constructor") if (this@platformSpecificFunctionName is PropertyAccessorDescriptor) { append("#Accessor") } } } return null } override fun FunctionDescriptor.specialValueParamPrefix(param: ValueParameterDescriptor): String { return if (this.hasObjCMethodAnnotation || this.hasObjCFactoryAnnotation || this.isObjCClassMethod()) "${param.name}:" else "" } } } object KonanManglerDesc : AbstractKonanDescriptorMangler() ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/StringTableUtil.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf.QualifiedNameTable.QualifiedName import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl import org.jetbrains.kotlin.serialization.deserialization.getClassId // TODO Come up with a better file name. internal fun NameResolverImpl.getDescriptorByFqNameIndex( module: ModuleDescriptor, nameTable: ProtoBuf.QualifiedNameTable, fqNameIndex: Int): DeclarationDescriptor { if (fqNameIndex == -1) return module.getPackage(FqName.ROOT) val packageName = this.getPackageFqName(fqNameIndex) // TODO: Here we are using internals of NameresolverImpl. // Consider extending NameResolver. val proto = nameTable.getQualifiedName(fqNameIndex) when (proto.kind!!) { QualifiedName.Kind.CLASS, QualifiedName.Kind.LOCAL -> return module.findClassAcrossModuleDependencies(this.getClassId(fqNameIndex))!! QualifiedName.Kind.PACKAGE -> return module.getPackage(FqName(packageName)) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/google_descriptor.proto1 ================================================ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // http://code.google.com/p/protobuf/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // The messages in this file describe the definitions found in .proto files. // A valid .proto file can be translated directly to a FileDescriptorProto // without any other information (e.g. without reading its imports). syntax = "proto2"; package google.protobuf; option java_package = "com.google.protobuf"; option java_outer_classname = "DescriptorProtos"; // descriptor.proto must be optimized for speed because reflection-based // algorithms don't work during bootstrapping. option optimize_for = SPEED; // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. message FileDescriptorSet { repeated FileDescriptorProto file = 1; } // Describes a complete .proto file. message FileDescriptorProto { optional string name = 1; // file name, relative to root of source tree optional string package = 2; // e.g. "foo", "foo.bar", etc. // Names of files imported by this file. repeated string dependency = 3; // Indexes of the public imported files in the dependency list above. repeated int32 public_dependency = 10; // Indexes of the weak imported files in the dependency list. // For Google-internal migration only. Do not use. repeated int32 weak_dependency = 11; // All top-level definitions in this file. repeated DescriptorProto message_type = 4; repeated EnumDescriptorProto enum_type = 5; repeated ServiceDescriptorProto service = 6; repeated FieldDescriptorProto extension = 7; optional FileOptions options = 8; // This field contains optional information about the original source code. // You may safely remove this entire field whithout harming runtime // functionality of the descriptors -- the information is needed only by // development tools. optional SourceCodeInfo source_code_info = 9; } // Describes a message type. message DescriptorProto { optional string name = 1; repeated FieldDescriptorProto field = 2; repeated FieldDescriptorProto extension = 6; repeated DescriptorProto nested_type = 3; repeated EnumDescriptorProto enum_type = 4; message ExtensionRange { optional int32 start = 1; optional int32 end = 2; } repeated ExtensionRange extension_range = 5; optional MessageOptions options = 7; } // Describes a field within a message. message FieldDescriptorProto { enum Type { // 0 is reserved for errors. // Order is weird for historical reasons. TYPE_DOUBLE = 1; TYPE_FLOAT = 2; // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if // negative values are likely. TYPE_INT64 = 3; TYPE_UINT64 = 4; // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if // negative values are likely. TYPE_INT32 = 5; TYPE_FIXED64 = 6; TYPE_FIXED32 = 7; TYPE_BOOL = 8; TYPE_STRING = 9; TYPE_GROUP = 10; // Tag-delimited aggregate. TYPE_MESSAGE = 11; // Length-delimited aggregate. // New in version 2. TYPE_BYTES = 12; TYPE_UINT32 = 13; TYPE_ENUM = 14; TYPE_SFIXED32 = 15; TYPE_SFIXED64 = 16; TYPE_SINT32 = 17; // Uses ZigZag encoding. TYPE_SINT64 = 18; // Uses ZigZag encoding. }; enum Label { // 0 is reserved for errors LABEL_OPTIONAL = 1; LABEL_REQUIRED = 2; LABEL_REPEATED = 3; // TODO(sanjay): Should we add LABEL_MAP? }; optional string name = 1; optional int32 number = 3; optional Label label = 4; // If type_name is set, this need not be set. If both this and type_name // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. optional Type type = 5; // For message and enum types, this is the name of the type. If the name // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping // rules are used to find the type (i.e. first the nested types within this // message are searched, then within the parent, on up to the root // namespace). optional string type_name = 6; // For extensions, this is the name of the type being extended. It is // resolved in the same manner as type_name. optional string extendee = 2; // For numeric types, contains the original text representation of the value. // For booleans, "true" or "false". // For strings, contains the default text contents (not escaped in any way). // For bytes, contains the C escaped value. All bytes >= 128 are escaped. // TODO(kenton): Base-64 encode? optional string default_value = 7; optional FieldOptions options = 8; } // Describes an enum type. message EnumDescriptorProto { optional string name = 1; repeated EnumValueDescriptorProto value = 2; optional EnumOptions options = 3; } // Describes a value within an enum. message EnumValueDescriptorProto { optional string name = 1; optional int32 number = 2; optional EnumValueOptions options = 3; } // Describes a service. message ServiceDescriptorProto { optional string name = 1; repeated MethodDescriptorProto method = 2; optional ServiceOptions options = 3; } // Describes a method of a service. message MethodDescriptorProto { optional string name = 1; // Input and output type names. These are resolved in the same way as // FieldDescriptorProto.type_name, but must refer to a message type. optional string input_type = 2; optional string output_type = 3; optional MethodOptions options = 4; } // =================================================================== // Options // Each of the definitions above may have "options" attached. These are // just annotations which may cause code to be generated slightly differently // or may contain hints for code that manipulates protocol messages. // // Clients may define custom options as extensions of the *Options messages. // These extensions may not yet be known at parsing time, so the parser cannot // store the values in them. Instead it stores them in a field in the *Options // message called uninterpreted_option. This field must have the same name // across all *Options messages. We then use this field to populate the // extensions when we build a descriptor, at which point all protos have been // parsed and so all extensions are known. // // Extension numbers for custom options may be chosen as follows: // * For options which will only be used within a single application or // organization, or for experimental options, use field numbers 50000 // through 99999. It is up to you to ensure that you do not use the // same number for multiple options. // * For options which will be published and used publicly by multiple // independent entities, e-mail protobuf-global-extension-registry@google.com // to reserve extension numbers. Simply provide your project name (e.g. // Object-C plugin) and your porject website (if available) -- there's no need // to explain how you intend to use them. Usually you only need one extension // number. You can declare multiple options with only one extension number by // putting them in a sub-message. See the Custom Options section of the docs // for examples: // http://code.google.com/apis/protocolbuffers/docs/proto.html#options // If this turns out to be popular, a web service will be set up // to automatically assign option numbers. message FileOptions { // Sets the Java package where classes generated from this .proto will be // placed. By default, the proto package is used, but this is often // inappropriate because proto packages do not normally start with backwards // domain names. optional string java_package = 1; // If set, all the classes from the .proto file are wrapped in a single // outer class with the given name. This applies to both Proto1 // (equivalent to the old "--one_java_file" option) and Proto2 (where // a .proto always translates to a single class, but you may want to // explicitly choose the class name). optional string java_outer_classname = 8; // If set true, then the Java code generator will generate a separate .java // file for each top-level message, enum, and service defined in the .proto // file. Thus, these types will *not* be nested inside the outer class // named by java_outer_classname. However, the outer class will still be // generated to contain the file's getDescriptor() method as well as any // top-level extensions defined in the file. optional bool java_multiple_files = 10 [default=false]; // If set true, then the Java code generator will generate equals() and // hashCode() methods for all messages defined in the .proto file. This is // purely a speed optimization, as the AbstractMessage base class includes // reflection-based implementations of these methods. optional bool java_generate_equals_and_hash = 20 [default=false]; // Generated classes can be optimized for speed or code size. enum OptimizeMode { SPEED = 1; // Generate complete code for parsing, serialization, // etc. CODE_SIZE = 2; // Use ReflectionOps to implement these methods. LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. } optional OptimizeMode optimize_for = 9 [default=SPEED]; // Sets the Go package where structs generated from this .proto will be // placed. There is no default. optional string go_package = 11; // Should generic services be generated in each language? "Generic" services // are not specific to any particular RPC system. They are generated by the // main code generators in each language (without additional plugins). // Generic services were the only kind of service generation supported by // early versions of proto2. // // Generic services are now considered deprecated in favor of using plugins // that generate code specific to your particular RPC system. Therefore, // these default to false. Old code which depends on generic services should // explicitly set them to true. optional bool cc_generic_services = 16 [default=false]; optional bool java_generic_services = 17 [default=false]; optional bool py_generic_services = 18 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message MessageOptions { // Set true to use the old proto1 MessageSet wire format for extensions. // This is provided for backwards-compatibility with the MessageSet wire // format. You should not use this for any other reason: It's less // efficient, has fewer features, and is more complicated. // // The message must be defined exactly as follows: // message Foo { // option message_set_wire_format = true; // extensions 4 to max; // } // Note that the message cannot have any defined fields; MessageSets only // have extensions. // // All extensions of your type must be singular messages; e.g. they cannot // be int32s, enums, or repeated messages. // // Because this is an option, the above two restrictions are not enforced by // the protocol compiler. optional bool message_set_wire_format = 1 [default=false]; // Disables the generation of the standard "descriptor()" accessor, which can // conflict with a field of the same name. This is meant to make migration // from proto1 easier; new code should avoid fields named "descriptor". optional bool no_standard_descriptor_accessor = 2 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message FieldOptions { // The ctype option instructs the C++ code generator to use a different // representation of the field than it normally would. See the specific // options below. This option is not yet implemented in the open source // release -- sorry, we'll try to include it in a future version! optional CType ctype = 1 [default = STRING]; enum CType { // Default mode. STRING = 0; CORD = 1; STRING_PIECE = 2; } // The packed option can be enabled for repeated primitive fields to enable // a more efficient representation on the wire. Rather than repeatedly // writing the tag and type for each element, the entire array is encoded as // a single length-delimited blob. optional bool packed = 2; // Should this field be parsed lazily? Lazy applies only to message-type // fields. It means that when the outer message is initially parsed, the // inner message's contents will not be parsed but instead stored in encoded // form. The inner message will actually be parsed when it is first accessed. // // This is only a hint. Implementations are free to choose whether to use // eager or lazy parsing regardless of the value of this option. However, // setting this option true suggests that the protocol author believes that // using lazy parsing on this field is worth the additional bookkeeping // overhead typically needed to implement it. // // This option does not affect the public interface of any generated code; // all method signatures remain the same. Furthermore, thread-safety of the // interface is not affected by this option; const methods remain safe to // call from multiple threads concurrently, while non-const methods continue // to require exclusive access. // // // Note that implementations may choose not to check required fields within // a lazy sub-message. That is, calling IsInitialized() on the outher message // may return true even if the inner message has missing required fields. // This is necessary because otherwise the inner message would have to be // parsed in order to perform the check, defeating the purpose of lazy // parsing. An implementation which chooses not to check required fields // must be consistent about it. That is, for any particular sub-message, the // implementation must either *always* check its required fields, or *never* // check its required fields, regardless of whether or not the message has // been parsed. optional bool lazy = 5 [default=false]; // Is this field deprecated? // Depending on the target platform, this can emit Deprecated annotations // for accessors, or it will be completely ignored; in the very least, this // is a formalization for deprecating fields. optional bool deprecated = 3 [default=false]; // EXPERIMENTAL. DO NOT USE. // For "map" fields, the name of the field in the enclosed type that // is the key for this map. For example, suppose we have: // message Item { // required string name = 1; // required string value = 2; // } // message Config { // repeated Item items = 1 [experimental_map_key="name"]; // } // In this situation, the map key for Item will be set to "name". // TODO: Fully-implement this, then remove the "experimental_" prefix. optional string experimental_map_key = 9; // For Google-internal migration only. Do not use. optional bool weak = 10 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message EnumOptions { // Set this option to false to disallow mapping different tag names to a same // value. optional bool allow_alias = 2 [default=true]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message EnumValueOptions { // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message ServiceOptions { // Note: Field numbers 1 through 32 are reserved for Google's internal RPC // framework. We apologize for hoarding these numbers to ourselves, but // we were already using them long before we decided to release Protocol // Buffers. // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } message MethodOptions { // Note: Field numbers 1 through 32 are reserved for Google's internal RPC // framework. We apologize for hoarding these numbers to ourselves, but // we were already using them long before we decided to release Protocol // Buffers. // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } // A message representing a option the parser does not recognize. This only // appears in options protos created by the compiler::Parser class. // DescriptorPool resolves these when building Descriptor objects. Therefore, // options protos in descriptor objects (e.g. returned by Descriptor::options(), // or produced by Descriptor::CopyTo()) will never have UninterpretedOptions // in them. message UninterpretedOption { // The name of the uninterpreted option. Each string represents a segment in // a dot-separated name. is_extension is true iff a segment represents an // extension (denoted with parentheses in options specs in .proto files). // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents // "foo.(bar.baz).qux". message NamePart { required string name_part = 1; required bool is_extension = 2; } repeated NamePart name = 2; // The value of the uninterpreted option, in whatever type the tokenizer // identified it as during parsing. Exactly one of these should be set. optional string identifier_value = 3; optional uint64 positive_int_value = 4; optional int64 negative_int_value = 5; optional double double_value = 6; optional bytes string_value = 7; optional string aggregate_value = 8; } // =================================================================== // Optional source code info // Encapsulates information about the original source file from which a // FileDescriptorProto was generated. message SourceCodeInfo { // A Location identifies a piece of source code in a .proto file which // corresponds to a particular definition. This information is intended // to be useful to IDEs, code indexers, documentation generators, and similar // tools. // // For example, say we have a file like: // message Foo { // optional string foo = 1; // } // Let's look at just the field definition: // optional string foo = 1; // ^ ^^ ^^ ^ ^^^ // a bc de f ghi // We have the following locations: // span path represents // [a,i) [ 4, 0, 2, 0 ] The whole field definition. // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). // // Notes: // - A location may refer to a repeated field itself (i.e. not to any // particular index within it). This is used whenever a set of elements are // logically enclosed in a single code segment. For example, an entire // extend block (possibly containing multiple extension definitions) will // have an outer location whose path refers to the "extensions" repeated // field without an index. // - Multiple locations may have the same path. This happens when a single // logical declaration is spread out across multiple places. The most // obvious example is the "extend" block again -- there may be multiple // extend blocks in the same scope, each of which will have the same path. // - A location's span is not always a subset of its parent's span. For // example, the "extendee" of an extension declaration appears at the // beginning of the "extend" block and is shared by all extensions within // the block. // - Just because a location's span is a subset of some other location's span // does not mean that it is a descendent. For example, a "group" defines // both a type and a field in a single declaration. Thus, the locations // corresponding to the type and field and their components will overlap. // - Code which tries to interpret locations should probably be designed to // ignore those that it doesn't understand, as more types of locations could // be recorded in the future. repeated Location location = 1; message Location { // Identifies which part of the FileDescriptorProto was defined at this // location. // // Each element is a field number or an index. They form a path from // the root FileDescriptorProto to the place where the definition. For // example, this path: // [ 4, 3, 2, 7, 1 ] // refers to: // file.message_type(3) // 4, 3 // .field(7) // 2, 7 // .name() // 1 // This is because FileDescriptorProto.message_type has field number 4: // repeated DescriptorProto message_type = 4; // and DescriptorProto.field has field number 2: // repeated FieldDescriptorProto field = 2; // and FieldDescriptorProto.name has field number 1: // optional string name = 1; // // Thus, the above path gives the location of a field name. If we removed // the last element: // [ 4, 3, 2, 7 ] // this path refers to the whole field declaration (from the beginning // of the label to the terminating semicolon). repeated int32 path = 1 [packed=true]; // Always has exactly three or four elements: start line, start column, // end line (optional, otherwise assumed same as start line), end column. // These are packed into a single field for efficiency. Note that line // and column numbers are zero-based -- typically you will want to add // 1 to each before displaying to a user. repeated int32 span = 2 [packed=true]; // If this SourceCodeInfo represents a complete declaration, these are any // comments appearing before and after the declaration which appear to be // attached to the declaration. // // A series of line comments appearing on consecutive lines, with no other // tokens appearing on those lines, will be treated as a single comment. // // Only the comment content is provided; comment markers (e.g. //) are // stripped out. For block comments, leading whitespace and an asterisk // will be stripped from the beginning of each line other than the first. // Newlines are included in the output. // // Examples: // // optional int32 foo = 1; // Comment attached to foo. // // Comment attached to bar. // optional int32 bar = 2; // // optional string baz = 3; // // Comment attached to baz. // // Another line attached to baz. // // // Comment attached to qux. // // // // Another line attached to qux. // optional double qux = 4; // // optional string corge = 5; // /* Block comment attached // * to corge. Leading asterisks // * will be removed. */ // /* Block comment attached to // * grault. */ // optional int32 grault = 6; optional string leading_comments = 3; optional string trailing_comments = 4; } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/util/PrimitiveLists.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.backend.konan.util class IntArrayList : Iterable { private var array = IntArray(3) private var length = 0 val size get() = length fun isEmpty() = size == 0 fun add(x: Int) { length++ ensureCapacity(length) set(length - 1, x) } fun reserve(minSize: Int) { if (length >= minSize) return length = minSize ensureCapacity(minSize) } operator fun get(index: Int): Int = when { index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index") else -> array[index] } operator fun set(index: Int, x: Int) = when { index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index") else -> array[index] = x } override operator fun iterator(): Iterator = Itr() private fun ensureCapacity(minCapacity: Int) { val oldArray = array if (minCapacity > oldArray.size) { var newSize = oldArray.size * 3 / 2 if (minCapacity > newSize) newSize = minCapacity array = oldArray.copyOf(newSize) } } private inner class Itr : Iterator { private var index = 0 override fun hasNext() = index < size override fun next() = get(index++) } } class LongArrayList : Iterable { private var array = LongArray(3) private var length = 0 val size get() = length fun isEmpty() = size == 0 fun add(x: Long) { length++ ensureCapacity(length) set(length - 1, x) } fun get(index: Int): Long = when { index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index") else -> array[index] } fun set(index: Int, x: Long) = when { index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index") else -> array[index] = x } override operator fun iterator(): Iterator = Itr() private fun ensureCapacity(minCapacity: Int) { val oldArray = array if (minCapacity > oldArray.size) { var newSize = oldArray.size * 3 / 2 if (minCapacity > newSize) newSize = minCapacity array = oldArray.copyOf(newSize) } } private inner class Itr : Iterator { private var index = 0 override fun hasNext() = index < size override fun next() = get(index++) } } ================================================ FILE: backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/ir/util/IrUtils2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.konan.KonanBackendContext import org.jetbrains.kotlin.backend.konan.KonanCompilationException import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.checkers.isRestrictsSuspensionReceiver import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes import java.lang.reflect.Proxy internal fun irBuilder( irBuiltIns: IrBuiltIns, scopeOwnerSymbol: IrSymbol, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET ): IrBuilderWithScope = object : IrBuilderWithScope( IrGeneratorContextBase(irBuiltIns), Scope(scopeOwnerSymbol), startOffset, endOffset ) {} //TODO: delete file on next kotlin dependency update internal fun IrExpression.isNullConst() = this is IrConst<*> && this.kind == IrConstKind.Null private var topLevelInitializersCounter = 0 internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: KonanBackendContext, threadLocal: Boolean) { val irField = IrFieldImpl( expression.startOffset, expression.endOffset, IrDeclarationOrigin.DEFINED, IrFieldSymbolImpl(), "topLevelInitializer${topLevelInitializersCounter++}".synthesizedName, expression.type, DescriptorVisibilities.PRIVATE, isFinal = true, isExternal = false, isStatic = true, ).apply { expression.setDeclarationsParent(this) if (threadLocal) annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.threadLocal.owner) initializer = IrExpressionBodyImpl(startOffset, endOffset, expression) } addChild(irField) } fun IrModuleFragment.addFile(fileEntry: SourceManager.FileEntry, packageFqName: FqName): IrFile { val packageFragmentDescriptor = object : PackageFragmentDescriptorImpl(this.descriptor, packageFqName) { override fun getMemberScope(): MemberScope = MemberScope.Empty } return IrFileImpl(fileEntry, packageFragmentDescriptor) .also { this.files += it } } inline fun stub(name: String): T { return Proxy.newProxyInstance(T::class.java.classLoader, arrayOf(T::class.java)) { _ /* proxy */, method, _ /* methodArgs */ -> if (method.name == "toString" && method.parameterCount == 0) { "${T::class.simpleName} stub for $name" } else { error("${T::class.simpleName}.${method.name} is not supported for $name") } } as T } fun IrDeclarationContainer.addChildren(declarations: List) { declarations.forEach { this.addChild(it) } } fun IrDeclarationContainer.addChild(declaration: IrDeclaration) { this.declarations += declaration declaration.accept(SetDeclarationsParentVisitor, this) } fun T.setDeclarationsParent(parent: IrDeclarationParent): T { accept(SetDeclarationsParentVisitor, parent) return this } object SetDeclarationsParentVisitor : IrElementVisitor { override fun visitElement(element: IrElement, data: IrDeclarationParent) { if (element !is IrDeclarationParent) { element.acceptChildren(this, data) } } override fun visitDeclaration(declaration: IrDeclarationBase, data: IrDeclarationParent) { declaration.parent = data super.visitDeclaration(declaration, data) } } tailrec fun IrDeclaration.getContainingFile(): IrFile? { val parent = this.parent return when (parent) { is IrFile -> parent is IrDeclaration -> parent.getContainingFile() else -> null } } internal fun KonanBackendContext.report(declaration: IrDeclaration, message: String, isError: Boolean) { val irFile = declaration.getContainingFile() this.report( declaration, irFile, if (irFile != null) { message } else { val renderer = org.jetbrains.kotlin.renderer.DescriptorRenderer.COMPACT_WITH_SHORT_TYPES "$message\n${renderer.render(declaration.descriptor)}" }, isError ) if (isError) throw KonanCompilationException() } fun IrFunctionAccessExpression.addArguments(args: Map) { val unhandledParameters = args.keys.toMutableSet() fun getArg(parameter: IrValueParameter) = args[parameter]?.also { unhandledParameters -= parameter } symbol.owner.dispatchReceiverParameter?.let { val arg = getArg(it) if (arg != null) { this.dispatchReceiver = arg } } symbol.owner.extensionReceiverParameter?.let { val arg = getArg(it) if (arg != null) { this.extensionReceiver = arg } } symbol.owner.valueParameters.forEach { val arg = getArg(it) if (arg != null) { this.putValueArgument(it.index, arg) } } } fun IrType.substitute(map: Map): IrType { if (this !is IrSimpleType) return this val classifier = this.classifier return when (classifier) { is IrTypeParameterSymbol -> map[classifier]?.let { if (this.hasQuestionMark) it.makeNullable() else it } ?: this is IrClassSymbol -> if (this.arguments.isEmpty()) { this // Fast path. } else { val newArguments = this.arguments.map { when (it) { is IrTypeProjection -> makeTypeProjection(it.type.substitute(map), it.variance) is IrStarProjection -> it else -> error(it) } } IrSimpleTypeImpl(classifier, hasQuestionMark, newArguments, annotations) } else -> error(classifier) } } private fun IrFunction.substitutedReturnType(typeArguments: List): IrType { val unsubstituted = this.returnType if (typeArguments.isEmpty()) return unsubstituted // Fast path. if (this is IrConstructor) { // Workaround for missing type parameters in constructors. TODO: remove. return this.returnType.classifierOrFail.typeWith(typeArguments) } assert(this.typeParameters.size >= typeArguments.size) // TODO: check equality. // TODO: receiver type must also be considered. return unsubstituted.substitute(this.typeParameters.map { it.symbol }.zip(typeArguments).toMap()) } // TODO: this function must be avoided since it takes symbol's owner implicitly. fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List = emptyList()) = this.irCall(symbol, symbol.owner.substitutedReturnType(typeArguments), typeArguments) fun IrBuilderWithScope.irCall(irFunction: IrFunction, typeArguments: List = emptyList()) = irCall(irFunction.symbol, typeArguments) internal fun irCall(startOffset: Int, endOffset: Int, irFunction: IrSimpleFunction, typeArguments: List): IrCall = IrCallImpl.fromSymbolDescriptor( startOffset, endOffset, irFunction.substitutedReturnType(typeArguments), irFunction.symbol, typeArguments.size, irFunction.valueParameters.size ).apply { typeArguments.forEachIndexed { index, irType -> this.putTypeArgument(index, irType) } } fun IrBuilderWithScope.irCallOp( callee: IrFunction, dispatchReceiver: IrExpression, argument: IrExpression ) = irCall(callee).apply { this.dispatchReceiver = dispatchReceiver putValueArgument(0, argument) } fun IrBuilderWithScope.irSetVar(variable: IrVariable, value: IrExpression) = irSet(variable.symbol, value) fun IrBuilderWithScope.irCatch(type: IrType) = IrCatchImpl( startOffset, endOffset, IrVariableImpl( startOffset, endOffset, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, IrVariableSymbolImpl(), Name.identifier("e"), type, false, false, false ).apply { parent = this@irCatch.parent } ) /** * Binds the arguments explicitly represented in the IR to the parameters of the accessed function. * The arguments are to be evaluated in the same order as they appear in the resulting list. */ fun IrMemberAccessExpression<*>.getArgumentsWithIr(): List> { val res = mutableListOf>() val irFunction = when (this) { is IrFunctionAccessExpression -> this.symbol.owner is IrFunctionReference -> this.symbol.owner else -> error(this) } dispatchReceiver?.let { res += (irFunction.dispatchReceiverParameter!! to it) } extensionReceiver?.let { res += (irFunction.extensionReceiverParameter!! to it) } irFunction.valueParameters.forEachIndexed { index, it -> val arg = getValueArgument(index) if (arg != null) { res += (it to arg) } } return res } fun ReferenceSymbolTable.translateErased(type: KotlinType): IrSimpleType { val descriptor = TypeUtils.getClassDescriptor(type) if (descriptor == null) return translateErased(type.immediateSupertypes().first()) val classSymbol = this.referenceClass(descriptor) val nullable = type.isMarkedNullable val arguments = type.arguments.map { IrStarProjectionImpl } return classSymbol.createType(nullable, arguments) } fun CommonBackendContext.createArrayOfExpression( startOffset: Int, endOffset: Int, arrayElementType: IrType, arrayElements: List ): IrExpression { val arrayType = ir.symbols.array.typeWith(arrayElementType) val arg0 = IrVarargImpl(startOffset, endOffset, arrayType, arrayElementType, arrayElements) return irCall(startOffset, endOffset, ir.symbols.arrayOf.owner, listOf(arrayElementType)).apply { putValueArgument(0, arg0) } } fun createField( startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, type: IrType, name: Name, isMutable: Boolean, owner: IrClass ) = IrFieldImpl( startOffset, endOffset, origin, IrFieldSymbolImpl(), name, type, DescriptorVisibilities.PRIVATE, !isMutable, false, false, ).apply { owner.declarations += this parent = owner } fun IrValueParameter.copy(newDescriptor: ParameterDescriptor): IrValueParameter { // Aggressive use of IrBasedDescriptors during deserialization // makes these types different. // Let's hope they not really used afterwards. //assert(this.descriptor.type == newDescriptor.type) { // "type1 = ${this.descriptor.type} != type2 = ${newDescriptor.type}" //} return IrValueParameterImpl( startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(newDescriptor), newDescriptor.name, newDescriptor.indexOrMinusOne, type, varargElementType, newDescriptor.isCrossinline, newDescriptor.isNoinline, isHidden = false, isAssignable = false ) } val IrType.isSimpleTypeWithQuestionMark: Boolean get() = this is IrSimpleType && this.hasQuestionMark fun IrClass.defaultOrNullableType(hasQuestionMark: Boolean) = if (hasQuestionMark) this.defaultType.makeNullable() else this.defaultType fun IrFunction.isRestrictedSuspendFunction(languageVersionSettings: LanguageVersionSettings): Boolean = this.descriptor.extensionReceiverParameter?.type?.isRestrictsSuspensionReceiver(languageVersionSettings) == true fun IrBuilderWithScope.irByte(value: Byte) = IrConstImpl.byte(startOffset, endOffset, context.irBuiltIns.byteType, value) ================================================ FILE: backend.native/llvm.def ================================================ headers = llvm-c/Core.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h \ llvm-c/BitReader.h llvm-c/Transforms/PassManagerBuilder.h llvm-c/Transforms/IPO.h \ llvm-c/TargetMachine.h llvm-c/Target.h llvm-c/Linker.h llvm-c/Initialization.h \ llvm-c/DebugInfo.h DebugInfoC.h CoverageMappingC.h headerFilter = llvm-c/* llvm-c/**/* DebugInfoC.h CoverageMappingC.h compilerOpts = -std=c99 \ -Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \ -pedantic -Wno-long-long -Wcovered-switch-default -Wdelete-non-virtual-dtor \ -DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS linker = clang++ linkerOpts = -fvisibility-inlines-hidden \ -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers \ -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor \ -std=c++17 \ -DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \ -ldebugInfo -lcoverageMapping # ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto objcarcopts arm aarch64 webassembly x86 mips linkerOpts.osx = -fPIC \ -Wl,-search_paths_first -Wl,-headerpad_max_install_names \ -lpthread -lz -lm -lcurses -Wl,-U,_futimens -Wl,-U,_LLVMDumpType \ -Wl,-exported_symbols_list,llvm.list \ -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter \ -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter \ -lLLVMX86Utils -lLLVMWebAssemblyDisassembler -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyDesc \ -lLLVMWebAssemblyAsmPrinter -lLLVMWebAssemblyAsmParser -lLLVMWebAssemblyInfo -lLLVMAArch64Disassembler \ -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter \ -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMGlobalISel -lLLVMSelectionDAG -lLLVMAsmPrinter \ -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMMCDisassembler -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMARMUtils \ -lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCodeGen -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize \ -lLLVMScalarOpts -lLLVMIRReader -lLLVMAsmParser -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMCoverage \ -lLLVMTarget -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject \ -lLLVMMCParser -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMBitReader -lLLVMCore \ -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle # ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto arm aarch64 webassembly x86 mips linkerOpts.linux = -fPIC \ -Wl,-z,noexecstack \ -lrt -ldl -lpthread -lz -lm \ -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter \ -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils \ -lLLVMWebAssemblyDisassembler -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyDesc -lLLVMWebAssemblyAsmPrinter -lLLVMWebAssemblyAsmParser \ -lLLVMWebAssemblyInfo -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info \ -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMGlobalISel -lLLVMSelectionDAG \ -lLLVMAsmPrinter -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMMCDisassembler -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMARMUtils -lLLVMLTO \ -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCodeGen -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMScalarOpts -lLLVMIRReader \ -lLLVMAsmParser -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMCoverage -lLLVMTarget -lLLVMLinker -lLLVMTransformUtils \ -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF \ -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle # ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto arm aarch64 webassembly x86 linkerOpts.mingw = -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info \ -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMWebAssemblyDisassembler -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyDesc \ -lLLVMWebAssemblyAsmPrinter -lLLVMWebAssemblyAsmParser -lLLVMWebAssemblyInfo -lLLVMAArch64Disassembler \ -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter \ -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMGlobalISel -lLLVMSelectionDAG -lLLVMAsmPrinter \ -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMMCDisassembler -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMARMUtils -lLLVMLTO \ -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCodeGen -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMScalarOpts \ -lLLVMIRReader -lLLVMAsmParser -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMCoverage -lLLVMTarget \ -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser \ -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle \ -lole32 -luuid -static-libgcc -static-libstdc++ \ -Wl,-Bstatic -lz \ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \ # It looks like mingw port compiled without LLVM_ENABLE_DUMP #Note: ld on mingw process -Wl,-U,_LLVMDumpType use different from other platform # way, using this option cause linkage error: # ld: -r and -shared may not be used together excludedFunctions.mingw = LLVMDumpType # Functions from LLVMIntPtrType to LLVMModuleCreateWithName are excluded because they work with the GlobalContext. # This might not be safe if the compiler is called from a daemon process. excludedFunctions = LLVMInitializeAllAsmParsers LLVMInitializeAllAsmPrinters LLVMInitializeAllDisassemblers \ LLVMInitializeAllTargetInfos LLVMInitializeAllTargetMCs LLVMInitializeAllTargets LLVMInitializeNativeTarget \ LLVMInitializeNativeAsmParser LLVMInitializeNativeAsmPrinter LLVMInitializeNativeDisassembler \ LLVMConstInBoundsGEP2 LLVMConstGEP2 LLVMIntPtrType LLVMIntPtrTypeForAS LLVMGetMDKindID LLVMInt1Type LLVMInt8Type \ LLVMInt16Type LLVMInt32Type LLVMInt64Type LLVMInt128Type LLVMIntType LLVMHalfType LLVMFloatType LLVMDoubleType \ LLVMX86FP80Type LLVMFP128Type LLVMPPCFP128Type LLVMX86MMXType LLVMStructType LLVMVoidType LLVMLabelType \ LLVMMDString LLVMMDNode LLVMConstString LLVMConstStruct LLVMAppendBasicBlock LLVMInsertBasicBlock LLVMCreateBuilder \ LLVMParseBitcode LLVMParseBitcode2 LLVMGetBitcodeModule LLVMGetBitcodeModule2 LLVMGetGlobalContext LLVMModuleCreateWithName strictEnums = LLVMIntPredicate LLVMOpcode LLVMDLLStorageClass LLVMCallConv LLVMThreadLocalMode LLVMAtomicOrdering ================================================ FILE: backend.native/llvm.list ================================================ _Java_* ================================================ FILE: backend.native/tests/build.gradle ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import shadow.org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompileNativeBinary import org.jetbrains.kotlin.* import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.KonanTarget import java.nio.file.Paths import static org.jetbrains.kotlin.konan.target.Architecture.* buildscript { repositories { maven { url 'https://cache-redirector.jetbrains.com/maven-central' } mavenCentral() maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:$gradlePluginVersion" } ext.useCustomDist = project.hasProperty("kotlin.native.home") || project.hasProperty("org.jetbrains.kotlin.native.home") || project.hasProperty("konan.home") ext.kotlinNativeDist = project.findProperty("kotlin.native.home") ?: project.findProperty("org.jetbrains.kotlin.native.home") ?: project.findProperty("konan.home") ?: distDir.absolutePath if (!useCustomDist) { ext.setProperty("kotlin.native.home", distDir.absolutePath) ext.setProperty("org.jetbrains.kotlin.native.home", distDir.absolutePath) ext.setProperty("konan.home", distDir.absolutePath) } } apply plugin: 'konan' apply plugin: 'kotlin' configurations { cli_bc update_tests update_stdlib_tests } repositories { ivy { ivyPattern 'https://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/teamcity-ivy.xml' artifactPattern 'https://teamcity.jetbrains.com/guestAuth/repository/download/[module]/[revision]/[artifact](.[ext])' } } dependencies { compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7' cli_bc project(path: ':backend.native', configuration: 'cli_bc') def updateTestData = true if (project.hasProperty("kotlinProjectPath")) { def kotlinProj = project.property("kotlinProjectPath").toString() def testDataZip = Paths.get(kotlinProj, "dist", "kotlin-test-data.zip").toFile() if (testDataZip.exists()) { update_tests files(testDataZip) updateTestData = false } else { println("WARN: using tests provided by gradle.properties. Please execute :kotlin:zipTestData") } def stdlibTestsZip = Paths.get(kotlinProj, "dist", "kotlin-stdlib-tests.zip").toFile() if (stdlibTestsZip.exists()) { update_stdlib_tests files(stdlibTestsZip) updateTestData = false } else { println("WARNING: using stdlib tests provided by gradle.properties. Please execute :kotlin:zipTestData") } } if (updateTestData) { update_tests(group: 'org', name: 'Kotlin_KotlinPublic_Compiler', version: testKotlinCompilerVersion) { artifact { name = 'internal/kotlin-test-data' type = 'zip' } } update_stdlib_tests (group: 'org', name: 'Kotlin_KotlinPublic_Compiler', version: kotlinStdlibTestsVersion) { artifact { name = 'internal/kotlin-stdlib-tests' type = 'zip' } } } } ext.testOutputRoot = rootProject.file("test.output").absolutePath ext.externalTestsDir = project.file("build/external") ext.externalStdlibTestsDir = project.file("build/stdlib_external/stdlib") externalTestsDir.mkdirs() externalStdlibTestsDir.mkdirs() ext.platformManager = project.rootProject.platformManager ext.target = platformManager.targetManager(project.testTarget).target ext.testLibraryDir = "${ext.kotlinNativeDist}/klib/platform/${project.target.name}" // Add executor to run tests depending on a target project.convention.plugins.executor = ExecutorServiceKt.create(project) compileTestKotlin { kotlinOptions { freeCompilerArgs += "-Xskip-prerelease-check" } } // Do not generate run tasks for konan built artifacts ext.konanNoRun = true final CacheTesting cacheTesting = CacheTestingKt.configureCacheTesting(project) if (cacheTesting != null) { // Check for debug build and set the -g option. if (project.globalTestArgs.contains("-opt")) { throw new IllegalArgumentException("Cache testing should be run with debug build. " + "Remove -opt options from the test args") } if (!project.globalTestArgs.contains("-g")) { project.globalTestArgs.add("-g") } // Note: can't do this in [CacheTesting.configure] since task classes aren't accessible there. tasks.withType(KonanCompileNativeBinary.class).configureEach { dependsOn cacheTesting.buildCacheTask extraOpts cacheTesting.compilerArgs } tasks.withType(RunExternalTestGroup.class).configureEach { dependsOn cacheTesting.buildCacheTask flags = (flags ?: []) + cacheTesting.compilerArgs } } // Enable two-stage test compilation if the test_two_stage property is set. ext.twoStageEnabled = project.hasProperty("test_two_stage") tasks.withType(KonanCompileNativeBinary.class).configureEach { enableTwoStageCompilation = twoStageEnabled } tasks.withType(RunExternalTestGroup.class).configureEach { enableTwoStageCompilation = twoStageEnabled } ext.isExperimentalMM = project.globalTestArgs.contains("-memory-model") && project.globalTestArgs.contains("experimental") allprojects { // Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set. // backend.native/tests ext.testOutputLocal = rootProject.file("$testOutputRoot/local") // backend.native/tests/external ext.testOutputExternal = rootProject.file("$testOutputRoot/external") // backend.native/tests/stdlib_external ext.testOutputStdlib = rootProject.file("$testOutputRoot/stdlib") // backend.native/tests/framework ext.testOutputFramework = rootProject.file("$testOutputRoot/framework") // backent.native/tests/coverage ext.testOutputCoverage = rootProject.file("$testOutputRoot/coverage") } testOutputExternal.mkdirs() testOutputStdlib.mkdirs() ext.dist = project.rootProject.file(project.findProperty("org.jetbrains.kotlin.native.home") ?: project.findProperty("konan.home") ?: "dist") konanArtifacts { library('testLibrary') { if (!useCustomDist) { dependsOn ':dist' } srcDir 'testLibrary' } def target = project.testTarget ?: 'host' library('baseTestClass', targets: [target]) { if (!useCustomDist) { dependsOn ':dist' } srcFiles 'testing/library.kt' } } def installTestLib = tasks.register("installTestLibrary", KlibInstall) { dependsOn "compileKonanTestLibraryHost" klib = project.provider { konanArtifacts.testLibrary.getArtifactByTarget('host') } repo = rootProject.file(testLibraryDir) doLast { // Remove the version in build/, so that we don't link two copies. def file = project.file("build/konan/libs/${project.target.name}/testLibrary.klib") file.delete() } } // Gets tests from the same Kotlin compiler build def update_external_tests() { // Copy only used tests into the test directory. if (externalTestsDir.exists()) { delete(externalTestsDir) } externalTestsDir.mkdirs() def compilerTestsFiles = configurations.update_tests.asFileTree copy { compilerTestsFiles.each { from(zipTree(it)) into(externalTestsDir) include 'compiler/codegen/box/**' include 'compiler/codegen/boxInline/**' include 'compiler/compileKotlinAgainstKotlin/**' include 'compiler/binaryCompatibility/klibEvolution/**' exclude 'stdlib/**' } } if (externalStdlibTestsDir.exists()) { delete(externalStdlibTestsDir) } externalStdlibTestsDir.mkdirs() def stdlibTestsFiles = configurations.update_stdlib_tests.asFileTree copy { stdlibTestsFiles.each { from(zipTree(it)) into(externalStdlibTestsDir) include 'common/**' include 'test/**' exclude 'test/js/**' include 'kotlin-test/**' } } } void konanc(String[] args) { def konancScript = isWindows() ? "konanc.bat" : "konanc" def konanc = "$dist/bin/$konancScript" def allArgs = args.join(" ") println("$konanc $allArgs") "$konanc $allArgs".execute().waitFor() } clean { doLast { delete(rootProject.file(testOutputRoot)) } } TaskCollection tasksOf(Class type, Closure filter = { return true }) { String prefix = project.findProperty("prefix") project.tasks.withType(type) .matching { filter(it) && it.enabled && (prefix != null ? it.name.startsWith(prefix) : true) } } run { dependsOn(tasksOf(KonanTest)) // Add framework tests dependsOn(tasksOf(FrameworkTest)) dependsOn(tasksOf(MetadataComparisonTest)) // Add regular gradle test tasks dependsOn(tasksOf(Test)) dependsOn(tasksOf(CoverageTest)) } task sanity { doFirst { if (!project.hasProperty("test.disable_update")) { update_external_tests() } } def platformLibsTasks = targetList.collect { ":${it}PlatformLibs" } + ":distPlatformLibs" dependsOn(tasksOf(KonanTest) { task -> task.getDependsOn().every { !platformLibsTasks.contains(it) } && task.name != "library_mismatch" // This test requires the wasm32 stdlib which is unavailable during a sanity run. }) dependsOn(tasksOf(FrameworkTest) { task -> task.getDependsOn().every { !platformLibsTasks.contains(it) } }) dependsOn(tasksOf(MetadataComparisonTest)) // Add regular gradle test tasks dependsOn(tasksOf(Test)) dependsOn(tasksOf(CoverageTest)) } // Collect reports in one json. task resultsTask() { doLast { List reports = [] def statistics = new Statistics() tasks.withType(RunExternalTestGroup).matching { it.state.executed }.each { reports += new KonanTestGroupReport(it.name, it.testGroupReporter.suiteReports) statistics.add(it.testGroupReporter.statistics) } tasks.withType(KonanGTest).matching { it.state.executed }.each { statistics.add(it.statistics) } ExternalReportUtilsKt.saveReport("$testOutputExternal/reports.json", statistics, reports) use(KonanTestSuiteReportKt) { project.logger.quiet("DONE.\n\n" + "TOTAL: $statistics.total\n" + "PASSED: $statistics.passed\n" + "FAILED: $statistics.failed\n" + (statistics.error != 0 ? "ERROR: $statistics.error\n" : "") + "SKIPPED: $statistics.skipped") } } } boolean isExcluded(String dir) { // List of tests that fail due to unresolved compiler bugs def excluded = [ ] boolean result = false excluded.forEach { if (dir.endsWith(it.replace("/", File.separator))) { result = true } } return result } def createTestTasks(File testRoot, Class taskType) { testRoot.eachDirRecurse { // Skip build directory and directories without *.kt files. if (it.name == "build" || it.listFiles().count { it.name.endsWith(".kt") && it.isFile() } == 0) { return } def taskDirectory = project.relativePath(it).substring("build/".length()) if (!isExcluded(taskDirectory)) { def taskName = taskDirectory.replaceAll("[-/\\\\]", '_') project.tasks.register(taskName, taskType) { it.groupDirectory = taskDirectory it.finalizedBy resultsTask } } else { println("$taskDirectory is excluded") } } } void dependsOnPlatformLibs(Task t) { if (!useCustomDist) { def testTarget = project.target if (testTarget != project.platformManager.Companion.host) { t.dependsOn(":${testTarget}PlatformLibs") } else { t.dependsOn(':distPlatformLibs') } } } /** * Creates a task for a standalone test. Configures runner and adds building task. */ Task standaloneTest(String name, Closure configureClosure) { return KotlinNativeTestKt.createTest(project, name, KonanStandaloneTest) { task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { program(name, targets: [target.name]) { baseDir "$testOutputLocal/$name" srcFiles task.getSources() extraOpts task.flags extraOpts project.globalTestArgs } } } } } /** * Creates a task for a linking test. Configures runner and adds library and test build tasks. */ Task linkTest(String name, Closure configureClosure) { return KotlinNativeTestKt.createTest(project, name, KonanLinkTest) { task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { def lib = "lib$name" def targetName = target.name // build a library from KonanLinkTest::lib property library(lib, targets: [targetName]) { srcFiles task.lib baseDir "$testOutputLocal/$name" extraOpts task.flags extraOpts project.globalTestArgs } UtilsKt.dependsOnKonanBuildingTask(task, lib, target) // Build an executable with library program(name, targets: [targetName]) { libraries { klib lib } baseDir "$testOutputLocal/$name" srcFiles task.getSources() extraOpts task.flags extraOpts project.globalTestArgs } } } } } /** * Creates a task for a dynamic test. Configures runner and adds library and test build tasks. */ Task dynamicTest(String name, Closure configureClosure) { return KotlinNativeTestKt.createTest(project, name, KonanDynamicTest) { task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { def targetName = target.name def lib = task.interop if (lib != null) { UtilsKt.dependsOnKonanBuildingTask(task, lib, target) } dynamic(name, targets: [targetName]) { if (lib != null) { libraries { artifact lib } } srcFiles task.getSources() baseDir "$testOutputLocal/$name" extraOpts task.flags extraOpts project.globalTestArgs } } def buildTask = UtilsKt.findKonanBuildTask(project, name, target) UtilsKt.dependsOnDist(buildTask) } } } task run_external () { // Set this property to disable auto update tests if (!project.hasProperty("test.disable_update")) { update_external_tests() } // Create tasks for external tests. createTestTasks(externalTestsDir, RunExternalTestGroup) // Set up dependencies. dependsOn(tasksOf(RunExternalTestGroup)) dependsOn("stdlibTest") dependsOn("stdlibTestInWorker") } task daily() { dependsOn(run_external) } task slackReport(type:Reporter) { reportHome = rootProject.file("test.output").absoluteFile } task slackReportNightly(type:NightlyReporter) { externalMacosReport = "external_macos_results/reports.json" externalLinuxReport = "external_linux_results/reports.json" externalWindowsReport = "external_windows_results/reports.json" } linkTest("localDelegatedPropertyLink") { goldValue = "OK\n" source = "lower/local_delegated_property_link/main.kt" lib = "lower/local_delegated_property_link/lib.kt" } task sum(type: KonanLocalTest) { source = "codegen/function/sum.kt" } task method_call(type: KonanLocalTest) { source = "codegen/object/method_call.kt" } task fields(type: KonanLocalTest) { source = "codegen/object/fields.kt" } task fields1(type: KonanLocalTest) { source = "codegen/object/fields1.kt" } task fields2(type: KonanLocalTest) { goldValue = "Set global = 1\n" + "Set member = 42\n" + "Get member = 42\n" + "Set global = 42\n" + "Get global = 42\n" + "Set member = 42\n" source = "codegen/object/fields2.kt" } // This test checks object layout can't be done in // KonanLocalTest paradigm //task constructor(type: UnitKonanTest) { // source = "codegen/object/constructor.kt" //} task objectInitialization(type: KonanLocalTest) { source = "codegen/object/initialization.kt" } task objectInitialization1(type: KonanLocalTest) { goldValue = "init\nfield\nconstructor1\ninit\nfield\nconstructor1\nconstructor2\n" source = "codegen/object/initialization1.kt" } standaloneTest("object_globalInitializer") { source = "codegen/object/globalInitializer.kt" } task check_type(type: KonanLocalTest) { goldValue = "true\nfalse\ntrue\ntrue\ntrue\ntrue\n" source = "codegen/basics/check_type.kt" } task safe_cast(type: KonanLocalTest) { goldValue = "safe_cast_positive: true\n" + "safe_cast_negative: true\n" source = "codegen/basics/safe_cast.kt" } task typealias1(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/basics/typealias1.kt" } task aritmetic(type: KonanLocalTest) { source = "codegen/function/arithmetic.kt" } task sum1(type: KonanLocalTest) { source = "codegen/function/sum_foo_bar.kt" } task sum2(type: KonanLocalTest) { source = "codegen/function/sum_imm.kt" } task sum_func(type: KonanLocalTest) { source = "codegen/function/sum_func.kt" } task sum_mixed(type: KonanLocalTest) { source = "codegen/function/sum_mixed.kt" } task sum_illy(type: KonanLocalTest) { source = "codegen/function/sum_silly.kt" } task function_defaults(type: KonanLocalTest) { source = "codegen/function/defaults.kt" } task function_defaults1(type: KonanLocalTest) { source = "codegen/function/defaults1.kt" } task function_defaults2(type: KonanLocalTest) { source = "codegen/function/defaults2.kt" } task function_defaults3(type: KonanLocalTest) { source = "codegen/function/defaults3.kt" } task function_defaults4(type: KonanLocalTest) { goldValue = "43\n" source = "codegen/function/defaults4.kt" } task function_defaults5(type: KonanLocalTest) { goldValue = "5\n6\n" source = "codegen/function/defaults5.kt" } task function_defaults6(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/function/defaults6.kt" } task function_defaults7(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/function/defaults7.kt" } task function_defaults8(type: KonanLocalTest) { goldValue = "2\n" source = "codegen/function/defaults8.kt" } task function_defaults9(type: KonanLocalTest) { goldValue = "1\n" source = "codegen/function/defaults9.kt" } task function_defaults10(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/function/defaults10.kt" } task function_defaults_from_fake_override(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/function/defaultsFromFakeOverride.kt" } task function_defaults_with_vararg1(type: KonanLocalTest) { goldValue = "Hello , Correct!\nHello World, Correct!\n , Correct!\n" source = "codegen/function/defaultsWithVarArg1.kt" } task function_defaults_with_vararg2(type: KonanLocalTest) { goldValue = "1\n2\n42\n" source = "codegen/function/defaultsWithVarArg2.kt" } task function_defaults_with_inline_classes(type: KonanLocalTest) { source = "codegen/function/defaultsWithInlineClasses.kt" } task sum_3const(type: KonanLocalTest) { source = "codegen/function/sum_3const.kt" } task codegen_controlflow_for_loops(type: KonanLocalTest) { source = "codegen/controlflow/for_loops.kt" goldValue = "01234\n0123\n43210\n\n024\n02\n420\n\n036\n03\n630\n\n024\n02\n420\n\n" } task codegen_controlflow_for_loops_types(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_types.kt" goldValue = "01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n01234\n" + "01234\n01234\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n0123\n" + "0123\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n43210\n" + "43210\n43210\nabcd\nabc\ndcba\n024\n024\n024\n024\n024\n024\n024\n024\n024\n024\n024\n024\n024\n024\n" + "024\n024\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n02\n420\n420\n420\n420\n420\n420\n" + "420\n420\n420\n420\n420\n420\n420\n420\n420\n420\nac\nac\ndb\n" } task codegen_controlflow_for_loops_overflow(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_overflow.kt" goldValue = "2147483646 2147483647 \n2147483646 \n-2147483647 -2147483648 \n1073741827 \n" } task codegen_controlflow_for_loops_errors(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') // Uses exceptions. source = "codegen/controlflow/for_loops_errors.kt" goldValue = "OK\n" } task codegen_controlflow_for_loops_empty_range(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_empty_range.kt" goldValue = "OK\n" } task codegen_controlflow_for_loops_nested(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_nested.kt" goldValue = "00 01 02 10 11 12 20 21 22 \n" + "00 01 10 11 20 21 \n" + "00 01 10 11 20 21 \n" + "00 01 \n" + "00 02 10 12 20 22 \n" + "00 02 10 12 20 22 \n" + "00 10 20 \n" } task codegen_controlflow_for_loops_coroutines(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_coroutines.kt" goldValue = "before: 0 after: 0\n" + "before: 2 after: 2\n" + "before: 4 after: 4\n" + "before: 6 after: 6\n" + "Got: 0 2 4 6\n" } task codegen_controlflow_for_loops_let_with_nullable(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_let_with_nullable.kt" goldValue = "012345\n012345\n024\n01234\n01234\n024\n543210\n543210\n531\n" + "012345\n012345\n024\n01234\n01234\n024\n543210\n543210\n531\n" + "abcdef\nabcdef\nace\nabcde\nabcde\nace\nfedcba\nfedcba\nfdb\n" } task codegen_controlflow_for_loops_call_order(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_call_order.kt" goldValue = "1234\n1234\n2134\n" } task codegen_controlflow_for_loops_array_indices(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_indices.kt" goldValue = "0123\n\n" } task codegen_controlflow_for_loops_array(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array.kt" goldValue = "4035\n\n0\n0\n" } task codegen_controlflow_for_loops_array_nested(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_nested.kt" goldValue = "123\nHello\n\n12345678910\n" } task codegen_controlflow_for_loops_array_side_effects(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_side_effects.kt" goldValue = "side-effect\n4035\nside-effect\n\n" } task codegen_controlflow_for_loops_array_break_continue(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_break_continue.kt" goldValue = "403\n\n" } task codegen_controlflow_for_loops_array_mutation(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_mutation.kt" goldValue = "4000" } task codegen_controlflow_for_loops_array_nullable(type: KonanLocalTest) { source = "codegen/controlflow/for_loops_array_nullable.kt" goldValue = "123" } task local_variable(type: KonanLocalTest) { source = "codegen/basics/local_variable.kt" } task canonical_name(type: KonanLocalTest) { goldValue = "A:foo\nA:qux\n" source = "codegen/basics/canonical_name.kt" } task cast_simple(type: KonanLocalTest) { source = "codegen/basics/cast_simple.kt" } task cast_null(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Ok\n" source = "codegen/basics/cast_null.kt" } task unchecked_cast1(type: KonanLocalTest) { goldValue = "17\n17\n42\n42\n" source = "codegen/basics/unchecked_cast1.kt" } task unchecked_cast2(type: KonanLocalTest) { enabled = false goldValue = "Ok\n" source = "codegen/basics/unchecked_cast2.kt" } task unchecked_cast3(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Ok\n" source = "codegen/basics/unchecked_cast3.kt" } task unchecked_cast4(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Ok\n" source = "codegen/basics/unchecked_cast4.kt" } task null_check(type: KonanLocalTest) { source = "codegen/basics/null_check.kt" } task array_to_any(type: KonanLocalTest) { source = "codegen/basics/array_to_any.kt" } standaloneTest("runtime_basic_init") { source = "runtime/basic/init.kt" expectedExitStatus = 0 } standaloneTest("runtime_basic_exit") { source = "runtime/basic/exit.kt" expectedExitStatus = 42 } task runtime_random(type: KonanLocalTest) { source = "runtime/basic/random.kt" } task runtime_basic_simd(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "runtime/basic/simd.kt" } task runtime_worker_random(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Uses workers. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/worker_random.kt" } task hello0(type: KonanLocalTest) { goldValue = "Hello, world!\n" source = "runtime/basic/hello0.kt" } task stringTrim(type: KonanLocalTest) { source = "codegen/stringTrim/stringTrim.kt" } standaloneTest("hello1") { goldValue = "Hello World" testData = "Hello World\n" source = "runtime/basic/hello1.kt" } standaloneTest("hello2") { goldValue = "you entered 'Hello World'" testData = "Hello World\n" source = "runtime/basic/hello2.kt" } task hello3(type: KonanLocalTest) { goldValue = "239\ntrue\n3.14159\nA\n" source = "runtime/basic/hello3.kt" } task hello4(type: KonanLocalTest) { goldValue = "Hello\nПока\n" source = "runtime/basic/hello4.kt" } standaloneTest('enumEquals') { goldValue = "true\nfalse\nfalse\n" source = "runtime/basic/enum_equals.kt" flags = ['-XXLanguage:-ProhibitComparisonOfIncompatibleEnums', '-e', 'runtime.basic.enum_equals.main'] } standaloneTest("entry0") { goldValue = "Hello.\n" source = "runtime/basic/entry0.kt" flags = ["-entry", "runtime.basic.entry0.main"] } standaloneTest("entry1") { goldValue = "Hello.\n" source = "runtime/basic/entry1.kt" flags = ["-entry", "foo"] } linkTest("entry2") { goldValue = "Hello.\n" source = "runtime/basic/entry2.kt" lib = "runtime/basic/libentry2.kt" flags = ["-entry", "foo"] } standaloneTest("entry3") { goldValue = "Hello, without args.\n" source = "runtime/basic/entry1.kt" flags = ["-entry", "bar"] } standaloneTest("entry4") { goldValue = "This is main without args\n" source = "runtime/basic/entry4.kt" } standaloneTest("readline0") { goldValue = "41" testData = "41\r\n" source = "runtime/basic/readline0.kt" } standaloneTest("readline1") { goldValue = "" testData = "\n" source = "runtime/basic/readline1.kt" } task tostring0(type: KonanLocalTest) { goldValue = "127\n-1\n239\nA\nЁ\nト\n1122334455\n112233445566778899\n3.14159265358\n1.0E27\n1.0E7\n1.0E-300\ntrue\nfalse\n" source = "runtime/basic/tostring0.kt" } task tostring1(type: KonanLocalTest) { goldValue = "ello\n" source = "runtime/basic/tostring1.kt" } task tostring2(type: KonanLocalTest) { goldValue = "H e l l o \nHello\n" source = "runtime/basic/tostring2.kt" } task tostring3(type: KonanLocalTest) { goldValue = "-128\n127\n-32768\n32767\n" + "-2147483648\n2147483647\n-9223372036854775808\n9223372036854775807\n" + "1.4E-45\n3.4028235E38\n-Infinity\nInfinity\n" + "NaN\n" + "4.9E-324\n1.7976931348623157E308\n-Infinity\nInfinity\n" + "NaN\n" source = "runtime/basic/tostring3.kt" } task empty_substring(type: KonanLocalTest) { goldValue = "\n" source = "runtime/basic/empty_substring.kt" } standaloneTest("cleaner_basic") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_basic.kt" flags = ['-tr', '-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } standaloneTest("cleaner_workers") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_workers.kt" flags = ['-tr', '-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } standaloneTest("cleaner_in_main_with_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_in_main_with_checker.kt" goldValue = "42\n" } standaloneTest("cleaner_in_main_without_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_in_main_without_checker.kt" goldValue = "" } standaloneTest("cleaner_leak_without_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_leak_without_checker.kt" goldValue = "" } standaloneTest("cleaner_leak_with_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_leak_with_checker.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> (s =~ /Cleaner (0x)?[0-9a-fA-F]+ was disposed during program exit/).find() } } standaloneTest("cleaner_in_tls_main_without_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_in_tls_main_without_checker.kt" } standaloneTest("cleaner_in_tls_main_with_checker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_in_tls_main_with_checker.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> (s =~ /Cleaner (0x)?[0-9a-fA-F]+ was disposed during program exit/).find() } } standaloneTest("cleaner_in_tls_worker") { enabled = (project.testTarget != 'wasm32') && // Cleaners need workers !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/cleaner_in_tls_worker.kt" flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } standaloneTest("worker_bound_reference0") { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/concurrent/worker_bound_reference0.kt" flags = ['-tr'] } task worker0(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "Got Input processed\nOK\n" source = "runtime/workers/worker0.kt" } task worker1(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\n" source = "runtime/workers/worker1.kt" } task worker2(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\n" source = "runtime/workers/worker2.kt" } task worker3(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\n" source = "runtime/workers/worker3.kt" } task worker4(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "Got 42\nOK\n" source = "runtime/workers/worker4.kt" } // This tests changes main thread worker queue state, so better be executed alone. standaloneTest("worker5") { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "Got 3\nOK\n" source = "runtime/workers/worker5.kt" } task worker6(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "Got 42\nOK\n" source = "runtime/workers/worker6.kt" } task worker7(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "Input\nGot kotlin.Unit\nOK\n" source = "runtime/workers/worker7.kt" } task worker8(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "SharedData(string=Hello, int=10, member=SharedDataMember(double=0.1))\nGot kotlin.Unit\nOK\n" source = "runtime/workers/worker8.kt" } task worker9(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "zzz\n42\nOK\nfirst 2\nsecond 3\nfrozen OK\n" source = "runtime/workers/worker9.kt" } task worker10(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\ntrue\ntrue\n" source = "runtime/workers/worker10.kt" } task worker11(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\n" source = "runtime/workers/worker11.kt" } standaloneTest("worker_threadlocal_no_leak") { disabled = (project.testTarget == 'wasm32') || // Needs pthreads. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/workers/worker_threadlocal_no_leak.kt" } task freeze0(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No workers on WASM. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "frozen bit is true\n" + "Worker: SharedData(string=Hello, int=10, member=SharedDataMember(double=0.1))\n" + "Main: SharedData(string=Hello, int=10, member=SharedDataMember(double=0.1))\n" + "OK\n" source = "runtime/workers/freeze0.kt" } task freeze1(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK, cannot mutate frozen\n" source = "runtime/workers/freeze1.kt" } task freeze_stress(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/workers/freeze_stress.kt" } task freeze2(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "Worker 1: Hello world\n" + "Worker2: 42\n" + "Worker3: 239.0\n" + "Worker4: a\n" + "OK\n" source = "runtime/workers/freeze2.kt" } task freeze3(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/workers/freeze3.kt" } task freeze4(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/workers/freeze4.kt" } task freeze5(type: KonanLocalTest) { enabled = !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/workers/freeze5.kt" } task freeze6(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\nOK\n" source = "runtime/workers/freeze6.kt" } task atomic0(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "35\n" + "20\n" + "OK\n" source = "runtime/workers/atomic0.kt" } standaloneTest("atomic1") { // Note: This test reproduces a race, so it'll start flaking if problem is reintroduced. enabled = false // Needs USE_CYCLIC_GC, which is disabled. source = "runtime/workers/atomic1.kt" } task lazy0(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "OK\n" source = "runtime/workers/lazy0.kt" } task lazy1(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Need exceptions. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/workers/lazy1.kt" } standaloneTest("lazy2") { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. goldValue = "123\nOK\n" source = "runtime/workers/lazy2.kt" } standaloneTest("lazy3") { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. source = "runtime/workers/lazy3.kt" } task mutableData1(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. Need exceptions !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/workers/mutableData1.kt" } task enumIdentity(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. goldValue = "true\n" source = "runtime/workers/enum_identity.kt" } standaloneTest("leakWorker") { disabled = (project.testTarget == 'wasm32') || // Needs pthreads. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/workers/leak_worker.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Unfinished workers detected, 1 workers leaked!") } } standaloneTest("leakMemoryWithWorkerTermination") { disabled = (project.testTarget == 'wasm32') || // Needs pthreads. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/workers/leak_memory_with_worker_termination.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } task superFunCall(type: KonanLocalTest) { goldValue = "\n\n" source = "codegen/basics/superFunCall.kt" } task superGetterCall(type: KonanLocalTest) { goldValue = "\n\n" source = "codegen/basics/superGetterCall.kt" } task superSetterCall(type: KonanLocalTest) { goldValue = "zzz\nzzz\n" source = "codegen/basics/superSetterCall.kt" } task enum0(type: KonanLocalTest) { goldValue = "VALUE\n" source = "codegen/enum/test0.kt" } task enum1(type: KonanLocalTest) { goldValue = "z12\n" source = "codegen/enum/test1.kt" } task enum_valueOf(type: KonanLocalTest) { goldValue = "E1\nE2\nE3\nE1\nE2\nE3\n" source = "codegen/enum/valueOf.kt" } task enum_values(type: KonanLocalTest) { goldValue = "E3\nE1\nE2\nE3\nE1\nE2\n" source = "codegen/enum/values.kt" } task enum_vCallNoEntryClass(type: KonanLocalTest) { goldValue = "('z3', 3)\n" source = "codegen/enum/vCallNoEntryClass.kt" } task enum_vCallWithEntryClass(type: KonanLocalTest) { goldValue = "z1z2\n" source = "codegen/enum/vCallWithEntryClass.kt" } task enum_companionObject(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/enum/companionObject.kt" } task enum_interfaceCallNoEntryClass(type: KonanLocalTest) { goldValue = "('z3', 3)\n('z3', 3)\n" source = "codegen/enum/interfaceCallNoEntryClass.kt" } task enum_interfaceCallWithEntryClass(type: KonanLocalTest) { goldValue = "z1z2\nz1z2\n" source = "codegen/enum/interfaceCallWithEntryClass.kt" } linkTest("enum_linkTest") { goldValue = "42\n117\n-1\n" source = "codegen/enum/linkTest_main.kt" lib = "codegen/enum/linkTest_lib.kt" } task enum_varargParam(type: KonanLocalTest) { goldValue = "3\n" source = "codegen/enum/varargParam.kt" } task enum_nested(type: KonanLocalTest) { goldValue = "A\nC\n" source = "codegen/enum/nested.kt" } task enum_isFrozen(type: KonanLocalTest) { enabled = !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "true\n" source = "codegen/enum/isFrozen.kt" } task enum_loop(type: KonanLocalTest) { goldValue = "Z\nZ\n" source = "codegen/enum/loop.kt" } task enum_reorderedArguments(type: KonanLocalTest) { source = "codegen/enum/reorderedArguments.kt" } task enum_kt38540(type: KonanLocalTest) { source = "codegen/enum/kt38540.kt" } standaloneTest('switchLowering') { goldValue = "EnumA.A\nok\nok\nok\nok\nok\n" source = "codegen/enum/switchLowering.kt" flags = ['-XXLanguage:-ProhibitComparisonOfIncompatibleEnums', '-e', 'codegen.enum.switchLowering.main'] } task enum_lambdaInDefault(type: KonanLocalTest) { goldValue = "Q\n" source = "codegen/enum/lambdaInDefault.kt" } linkTest("mangling") { goldValue = "Int direct [1, 2, 3, 4]\n" + "out Number direct [9, 10, 11, 12]\n" + "star direct [5, 6, 7, 8]\n" + "Int param [1, 2, 3, 4]\n" + "out Number param [9, 10, 11, 12]\n" + "star param [5, 6, 7, 8]\n" + "no constructors {}\n" + "single constructor some string\n" + "two constructors 17\n" source = "mangling/mangling.kt" lib = "mangling/manglinglib.kt" } task innerClass_simple(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/simple.kt" } task innerClass_getOuterVal(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/getOuterVal.kt" } task innerClass_generic(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/generic.kt" } task innerClass_doubleInner(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/doubleInner.kt" } task innerClass_qualifiedThis(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/qualifiedThis.kt" } task innerClass_superOuter(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/innerClass/superOuter.kt" } task innerClass_noPrimaryConstructor(type: KonanLocalTest) { goldValue = "OK\nOK\n" source = "codegen/innerClass/noPrimaryConstructor.kt" } task innerClass_secondaryConstructor(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/innerClass/secondaryConstructor.kt" } linkTest("innerClass_linkTest") { source = "codegen/innerClass/linkTest_main.kt" lib = "codegen/innerClass/linkTest_lib.kt" } task localClass_localHierarchy(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/localHierarchy.kt" } task localClass_objectExpressionInProperty(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/objectExpressionInProperty.kt" } task localClass_objectExpressionInInitializer(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/objectExpressionInInitializer.kt" } task localClass_innerWithCapture(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/innerWithCapture.kt" } task localClass_innerTakesCapturedFromOuter(type: KonanLocalTest) { goldValue = "0\n1\n" source = "codegen/localClass/innerTakesCapturedFromOuter.kt" } task localClass_virtualCallFromConstructor(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/virtualCallFromConstructor.kt" } task localClass_noPrimaryConstructor(type: KonanLocalTest) { goldValue = "OKOK\n" source = "codegen/localClass/noPrimaryConstructor.kt" } task localClass_localFunctionCallFromLocalClass(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/localFunctionCallFromLocalClass.kt" } task localClass_localFunctionInLocalClass(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/localClass/localFunctionInLocalClass.kt" } task localClass_tryCatch(type: KonanLocalTest) { goldValue = "" source = "codegen/localClass/tryCatch.kt" } task function_localFunction(type : KonanLocalTest) { goldValue = "OK\n" source = "codegen/function/localFunction.kt" } task function_localFunction2(type : KonanLocalTest) { goldValue = "OK\n" source = "codegen/function/localFunction2.kt" } task function_localFunction3(type : KonanLocalTest) { goldValue = "OK\n" source = "codegen/function/localFunction3.kt" } task initializers_correctOrder1(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/initializers/correctOrder1.kt" } task initializers_correctOrder2(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/initializers/correctOrder2.kt" } linkTest("initializers_linkTest1") { goldValue = "1200\n" source = "codegen/initializers/linkTest1_main.kt" lib = "codegen/initializers/linkTest1_lib.kt" } linkTest("initializers_linkTest2") { goldValue = "2\n" source = "codegen/initializers/linkTest2_main.kt" lib = "codegen/initializers/linkTest2_lib.kt" } linkTest("initializers_sharedVarInInitBlock") { source = "codegen/initializers/sharedVarInInitBlock_main.kt" lib = "codegen/initializers/sharedVarInInitBlock_lib.kt" } task arithmetic_basic(type: KonanLocalTest) { source = "codegen/arithmetic/basic.kt" } task arithmetic_division(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "codegen/arithmetic/division.kt" } task arithmetic_github1856(type: KonanLocalTest) { source = "codegen/arithmetic/github1856.kt" } task bridges_test0(type: KonanLocalTest) { goldValue = "42\n42\n" source = "codegen/bridges/test0.kt" } task bridges_test1(type: KonanLocalTest) { goldValue = "1042\n" source = "codegen/bridges/test1.kt" } task bridges_test2(type: KonanLocalTest) { goldValue = "42\n42\n" source = "codegen/bridges/test2.kt" } task bridges_test3(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test3.kt" } task bridges_test4(type: KonanLocalTest) { goldValue = "42\n42\n" source = "codegen/bridges/test4.kt" } task bridges_test5(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test5.kt" } task bridges_test6(type: KonanLocalTest) { goldValue = "42\n42\n42\n42\n42\n" source = "codegen/bridges/test6.kt" } task bridges_test7(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test7.kt" } task bridges_test8(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test8.kt" } task bridges_test9(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test9.kt" } task bridges_test10(type: KonanLocalTest) { goldValue = "42\n42\n" source = "codegen/bridges/test10.kt" } task bridges_test11(type: KonanLocalTest) { goldValue = "42\n42\n42\n" source = "codegen/bridges/test11.kt" } task bridges_test12(type: KonanLocalTest) { goldValue = "B: 42\nC: 42\n" source = "codegen/bridges/test12.kt" } task bridges_test13(type: KonanLocalTest) { goldValue = "42\n42\n" source = "codegen/bridges/test13.kt" } task bridges_test14(type: KonanLocalTest) { goldValue = "42\n56\n42\n56\n56\n42\n156\n142\n" source = "codegen/bridges/test14.kt" } task bridges_test15(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/bridges/test15.kt" } task bridges_test16(type: KonanLocalTest) { goldValue = "OK\nOK\n" source = "codegen/bridges/test16.kt" } task bridges_test17(type: KonanLocalTest) { goldValue = "42\n42\n42\n42\n" source = "codegen/bridges/test17.kt" } task bridges_test18(type: KonanLocalTest) { goldValue = "kotlin.Unit\n" source = "codegen/bridges/test18.kt" } linkTest("bridges_linkTest") { goldValue = "42\n42\n42\n" source = "codegen/bridges/linkTest_main.kt" lib = "codegen/bridges/linkTest_lib.kt" } linkTest("bridges_linkTest2") { goldValue = "true\n" source = "codegen/bridges/linkTest2_main.kt" lib = "codegen/bridges/linkTest2_lib.kt" } task bridges_special(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/bridges/special.kt" } task bridges_specialGeneric(type: KonanLocalTest) { source = "codegen/bridges/specialGeneric.kt" } task bridges_nativePointed(type: KonanLocalTest) { source = "codegen/bridges/nativePointed.kt" } task returnTypeSignature(type: KonanLocalTest) { source = "codegen/bridges/returnTypeSignature.kt" } task classDelegation_method(type: KonanLocalTest) { goldValue = "OKOK\n" source = "codegen/classDelegation/method.kt" } task classDelegation_property(type: KonanLocalTest) { goldValue = "4242\n" source = "codegen/classDelegation/property.kt" } task classDelegation_generic(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/classDelegation/generic.kt" } task classDelegation_withBridge(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/classDelegation/withBridge.kt" } linkTest("classDelegation_linkTest") { goldValue = "qxx\n123\n42\n117\nzzz\n" source = "codegen/classDelegation/linkTest_main.kt" lib = "codegen/classDelegation/linkTest_lib.kt" } standaloneTest("contracts") { flags = [ '-Xopt-in=kotlin.RequiresOptIn', '-tr' ] source = "codegen/contracts/contracts.kt" } task delegatedProperty_simpleVal(type: KonanLocalTest) { goldValue = "x\n42\n" source = "codegen/delegatedProperty/simpleVal.kt" } task delegatedProperty_simpleVar(type: KonanLocalTest) { goldValue = "get x\n42\nset x\nget x\n117\n" source = "codegen/delegatedProperty/simpleVar.kt" } task delegatedProperty_packageLevel(type: KonanLocalTest) { goldValue = "x\n42\n" source = "codegen/delegatedProperty/packageLevel.kt" } task delegatedProperty_local(type: KonanLocalTest) { goldValue = "x\n42\n" source = "codegen/delegatedProperty/local.kt" } linkTest("delegatedProperty_delegatedOverride") { goldValue = "156\nx\n117\n42\n" source = "codegen/delegatedProperty/delegatedOverride_main.kt" lib = "codegen/delegatedProperty/delegatedOverride_lib.kt" } linkTest("delegatedProperty_correctFieldsOrder") { goldValue = "qxx\n117\nzzz\nqzz\n" source = "codegen/delegatedProperty/correctFieldsOrder_main.kt" lib = "codegen/delegatedProperty/correctFieldsOrder_lib.kt" } task delegatedProperty_lazy(type: KonanLocalTest) { goldValue = "computed!\nHello\nHello\n" source = "codegen/delegatedProperty/lazy.kt" } task delegatedProperty_observable(type: KonanLocalTest) { goldValue = " -> first\nfirst -> second\n" source = "codegen/delegatedProperty/observable.kt" } task delegatedProperty_map(type: KonanLocalTest) { goldValue = "John Doe\n25\n" source = "codegen/delegatedProperty/map.kt" } task propertyCallableReference_valClass(type: KonanLocalTest) { goldValue = "42\n117\n" source = "codegen/propertyCallableReference/valClass.kt" } task propertyCallableReference_valModule(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/propertyCallableReference/valModule.kt" } task propertyCallableReference_varClass(type: KonanLocalTest) { goldValue = "117\n117\n42\n42\n" source = "codegen/propertyCallableReference/varClass.kt" } task propertyCallableReference_varModule(type: KonanLocalTest) { goldValue = "117\n117\n" source = "codegen/propertyCallableReference/varModule.kt" } task propertyCallableReference_valExtension(type: KonanLocalTest) { goldValue = "42\n117\n" source = "codegen/propertyCallableReference/valExtension.kt" } task propertyCallableReference_varExtension(type: KonanLocalTest) { goldValue = "117\n117\n42\n42\n" source = "codegen/propertyCallableReference/varExtension.kt" } linkTest("propertyCallableReference_linkTest") { goldValue = "42\n117\n" source = "codegen/propertyCallableReference/linkTest_main.kt" lib = "codegen/propertyCallableReference/linkTest_lib.kt" } task propertyCallableReference_dynamicReceiver(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/propertyCallableReference/dynamicReceiver.kt" } task lateinit_initialized(type: KonanLocalTest) { goldValue = "zzz\n" source = "codegen/lateinit/initialized.kt" } task lateinit_notInitialized(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "codegen/lateinit/notInitialized.kt" } task lateinit_inBaseClass(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/lateinit/inBaseClass.kt" } task lateinit_localInitialized(type: KonanLocalTest) { goldValue = "zzz\n" source = "codegen/lateinit/localInitialized.kt" } task lateinit_localNotInitialized(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "codegen/lateinit/localNotInitialized.kt" } task lateinit_localCapturedInitialized(type: KonanLocalTest) { goldValue = "zzz\n" source = "codegen/lateinit/localCapturedInitialized.kt" } task lateinit_localCapturedNotInitialized(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "codegen/lateinit/localCapturedNotInitialized.kt" } task lateinit_isInitialized(type: KonanLocalTest) { goldValue = "false\ntrue\n" source = "codegen/lateinit/isInitialized.kt" } task lateinit_globalIsInitialized(type: KonanLocalTest) { goldValue = "false\ntrue\n" source = "codegen/lateinit/globalIsInitialized.kt" } task lateinit_innerIsInitialized(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/lateinit/innerIsInitialized.kt" } task kclass0(type: KonanLocalTest) { source = "codegen/kclass/kclass0.kt" } task kclass1(type: KonanLocalTest) { goldValue = "OK :D\n" source = "codegen/kclass/kclass1.kt" } task kclassEnumArgument(type: KonanLocalTest) { goldValue = "String\n" source = "codegen/kclass/kClassEnumArgument.kt" } task ktype1(type: KonanLocalTest) { source = "codegen/ktype/ktype1.kt" } task ktype_nonReified(type: KonanLocalTest) { source = "codegen/ktype/nonReified.kt" } task associatedObjects1(type: KonanLocalTest) { source = "codegen/associatedObjects/associatedObjects1.kt" } task coroutines_simple(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/coroutines/simple.kt" } task coroutines_degenerate1(type: KonanLocalTest) { goldValue = "s1\n" source = "codegen/coroutines/degenerate1.kt" } task coroutines_degenerate2(type: KonanLocalTest) { goldValue = "s2\ns1\n" source = "codegen/coroutines/degenerate2.kt" } task coroutines_withReceiver(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/coroutines/withReceiver.kt" } task coroutines_correctOrder1(type: KonanLocalTest) { goldValue = "f1\ns1\nf2\n160\n" source = "codegen/coroutines/correctOrder1.kt" } task coroutines_controlFlow_chain(type: KonanLocalTest) { source = "codegen/coroutines/controlFlow_chain.kt" } task coroutines_controlFlow_if1(type: KonanLocalTest) { goldValue = "f1\ns1\nf3\n84\n" source = "codegen/coroutines/controlFlow_if1.kt" } task coroutines_controlFlow_if2(type: KonanLocalTest) { goldValue = "f1\ns1\nf2\n43\n" source = "codegen/coroutines/controlFlow_if2.kt" } task coroutines_controlFlow_finally1(type: KonanLocalTest) { goldValue = "f1\ns1\n117\n" source = "codegen/coroutines/controlFlow_finally1.kt" } task coroutines_controlFlow_finally2(type: KonanLocalTest) { goldValue = "f1\ns1\n117\n" source = "codegen/coroutines/controlFlow_finally2.kt" } task coroutines_controlFlow_finally3(type: KonanLocalTest) { goldValue = "f1\ns1\n117\n" source = "codegen/coroutines/controlFlow_finally3.kt" } task coroutines_controlFlow_finally4(type: KonanLocalTest) { goldValue = "s1\nfinally\n42\n" source = "codegen/coroutines/controlFlow_finally4.kt" } task coroutines_controlFlow_finally5(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s1\nf2\nfinally\n1\n" source = "codegen/coroutines/controlFlow_finally5.kt" } task coroutines_controlFlow_finally6(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s1\nfinally\nerror\n0\n" source = "codegen/coroutines/controlFlow_finally6.kt" } task coroutines_controlFlow_finally7(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s1\nf2\nfinally1\ns2\nfinally2\n42\n" source = "codegen/coroutines/controlFlow_finally7.kt" } task coroutines_controlFlow_inline1(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/coroutines/controlFlow_inline1.kt" } task coroutines_controlFlow_inline2(type: KonanLocalTest) { goldValue = "s1\n42\n" source = "codegen/coroutines/controlFlow_inline2.kt" } task coroutines_controlFlow_inline3(type: KonanLocalTest) { goldValue = "f1\ns1\n42\n" source = "codegen/coroutines/controlFlow_inline3.kt" } task coroutines_controlFlow_tryCatch1(type: KonanLocalTest) { goldValue = "s1\n42\n" source = "codegen/coroutines/controlFlow_tryCatch1.kt" } task coroutines_controlFlow_tryCatch2(type: KonanLocalTest) { goldValue = "s1\n42\n" source = "codegen/coroutines/controlFlow_tryCatch2.kt" } task coroutines_controlFlow_tryCatch3(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s2\nf2\n1\n" source = "codegen/coroutines/controlFlow_tryCatch3.kt" } task coroutines_controlFlow_tryCatch4(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s2\nf2\n1\n" source = "codegen/coroutines/controlFlow_tryCatch4.kt" } task coroutines_controlFlow_tryCatch5(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "s2\ns1\nError\n42\n" source = "codegen/coroutines/controlFlow_tryCatch5.kt" } task coroutines_controlFlow_while1(type: KonanLocalTest) { goldValue = "s3\ns3\ns3\ns3\n3\n" source = "codegen/coroutines/controlFlow_while1.kt" } task coroutines_controlFlow_while2(type: KonanLocalTest) { goldValue = "s3\ns3\ns3\n3\n" source = "codegen/coroutines/controlFlow_while2.kt" } task coroutines_returnsNothing1(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/coroutines/returnsNothing1.kt" } task coroutines_returnsUnit1(type: KonanLocalTest) { goldValue = "117\ns1\n0\n" source = "codegen/coroutines/returnsUnit1.kt" } task coroutines_coroutineContext1(type: KonanLocalTest) { goldValue = "EmptyCoroutineContext\n" source = "codegen/coroutines/coroutineContext1.kt" } task coroutines_coroutineContext2(type: KonanLocalTest) { goldValue = "EmptyCoroutineContext\n" source = "codegen/coroutines/coroutineContext2.kt" } task coroutines_anonymousObject(type: KonanLocalTest) { goldValue = "zzz\n" source = "codegen/coroutines/anonymousObject.kt" } task coroutines_functionReference_simple(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/coroutines/functionReference_simple.kt" } task coroutines_functionReference_eqeq_name(type: KonanLocalTest) { goldValue = "" source = "codegen/coroutines/functionReference_eqeq_name.kt" } task coroutines_functionReference_invokeAsFunction(type: KonanLocalTest) { goldValue = "159\n" source = "codegen/coroutines/functionReference_invokeAsFunction.kt" } task coroutines_functionReference_lambdaAsSuspendLambda(type: KonanLocalTest) { goldValue = "" source = "codegen/coroutines/functionReference_lambdaAsSuspendLambda.kt" } task coroutines_kt41394(type: KonanLocalTest) { goldValue = "" source = "codegen/coroutines/kt41394.kt" } standaloneTest('coroutines_suspendConversion') { goldValue = "" source = "codegen/coroutines/suspendConversion.kt" flags = ['-XXLanguage:+SuspendConversion'] } task AbstractMutableCollection(type: KonanLocalTest) { expectedExitStatus = 0 source = "runtime/collections/AbstractMutableCollection.kt" } task BitSet(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. expectedExitStatus = 0 source = "runtime/collections/BitSet.kt" } task stack_array(type: KonanLocalTest) { goldValue = "true\n3\n" source = "runtime/collections/stack_array.kt" } task array0(type: KonanLocalTest) { goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n" source = "runtime/collections/array0.kt" } task array1(type: KonanLocalTest) { goldValue = "4 2\n1-1\n69\n38\n" source = "runtime/collections/array1.kt" } task array2(type: KonanLocalTest) { goldValue = "0\n2\n4\n6\n8\n40\n" source = "runtime/collections/array2.kt" } task array3(type: KonanLocalTest) { goldValue = "1 2 3 7 8 9 -128 -1 \n1 2 3 7 8 9 -128 -1 \n" source = "runtime/collections/array3.kt" } task array4(type: KonanLocalTest) { disabled = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "runtime/collections/array4.kt" } task array5(type: KonanLocalTest) { disabled = (project.testTarget == 'wasm32') // Uses exceptions. source = "runtime/collections/array5.kt" } task typed_array0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/typed_array0.kt" } task typed_array1(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // No exceptions on WASM. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "OK\n" source = "runtime/collections/typed_array1.kt" } task sort0(type: KonanLocalTest) { goldValue = "[a, b, x]\n[-1, 0, 42, 239, 100500]\n" source = "runtime/collections/sort0.kt" } task sort1(type: KonanLocalTest) { goldValue = "[a, b, x]\n[-1, 0, 42, 239, 100500]\n" source = "runtime/collections/sort1.kt" } task sortWith(type: KonanLocalTest) { source = "runtime/collections/SortWith.kt" } task if_else(type: KonanLocalTest) { source = "codegen/branching/if_else.kt" } task immutable_binary_blob_in_lambda(type: KonanLocalTest) { source = "lower/immutable_blob_in_lambda.kt" goldValue = "123\n" } task when2(type: KonanLocalTest) { source = "codegen/branching/when2.kt" } task when5(type: KonanLocalTest) { source = "codegen/branching/when5.kt" } task when6(type: KonanLocalTest) { source = "codegen/branching/when6.kt" } task when7(type: KonanLocalTest) { source = "codegen/branching/when7.kt" } task when8(type: KonanLocalTest) { source = "codegen/branching/when8.kt" goldValue = "true\n" } task when9(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/branching/when9.kt" } task when_through(type: KonanLocalTest) { source = "codegen/branching/when_through.kt" } task advanced_when2(type: KonanLocalTest) { source = "codegen/branching/advanced_when2.kt" } task advanced_when5(type: KonanLocalTest) { source = "codegen/branching/advanced_when5.kt" } task when_with_try1(type: KonanLocalTest) { goldValue = "null\nnull\n42\n" source = "codegen/branching/when_with_try1.kt" } task bool_yes(type: KonanLocalTest) { source = "codegen/function/boolean.kt" } task named(type: KonanLocalTest) { source = "codegen/function/named.kt" } task plus_eq(type: KonanLocalTest) { source = "codegen/function/plus_eq.kt" } task minus_eq(type: KonanLocalTest) { source = "codegen/function/minus_eq.kt" } task eqeq(type: KonanLocalTest) { source = "codegen/function/eqeq.kt" } task function_referenceBigArity(type: KonanLocalTest) { goldValue = "528\n" source = "codegen/function/referenceBigArity" } task cycle(type: KonanLocalTest) { source = "codegen/cycles/cycle.kt" } task cycle_do(type: KonanLocalTest) { source = "codegen/cycles/cycle_do.kt" } task cycle_for(type: KonanLocalTest) { source = "codegen/cycles/cycle_for.kt" } task abstract_super(type: KonanLocalTest) { source = "datagen/rtti/abstract_super.kt" } task vtable1(type: KonanLocalTest) { source = "datagen/rtti/vtable1.kt" } task vtable_any(type: KonanLocalTest) { source = "datagen/rtti/vtable_any.kt" goldValue = "[1]\n[2]\n[3]\n[4]\n" } task strdedup1(type: KonanLocalTest) { goldValue = "true\ntrue\n" source = "datagen/literals/strdedup1.kt" } task strdedup2(type: KonanLocalTest) { // TODO: string deduplication across several components seems to require // linking them as bitcode modules before translating to machine code. enabled = false goldValue = "true\ntrue\n" source = "datagen/literals/strdedup2.kt" } task empty_string(type: KonanLocalTest) { goldValue = "\n" source = "datagen/literals/empty_string.kt" } task intrinsic(type: KonanLocalTest) { source = "codegen/function/intrinsic.kt" } /* Disabled until we extract the classes that should be always present from stdlib into a separate binary. linkTest("link") { goldValue = "0\n" source = "link/src/bar.kt" lib = "link/lib" }( */ linkTest("link_omit_unused") { goldValue = "Hello\n" source = "link/omit/hello.kt" lib = "link/omit/lib.kt" } standaloneTest("link_default_libs") { dependsOnPlatformLibs(it) enabled = (project.testTarget != 'wasm32') // there will be no posix.klib for wasm goldValue = "sizet = 0\n" source = "link/default/default.kt" } standaloneTest("link_testLib_explicitly") { // there are no testLibrary for cross targets yet. enabled = project.target.name == project.hostName dependsOn installTestLib goldValue = "This is a side effect of a test library linked into the binary.\nYou should not be seeing this.\n\nHello\n" source = "link/omit/hello.kt" // We force library inclusion, so need to see the warning banner. flags = ['-l', 'testLibrary'] doLast { def file = new File("$testLibraryDir/testLibrary") file.deleteDir() } } linkTest("no_purge_for_dependencies") { dependsOnPlatformLibs(it) enabled = (project.testTarget != 'wasm32') // there will be no posix.klib for wasm goldValue = "linked library\nand symbols from posix available: 17; 1.0\n" source = "link/purge1/prog.kt" lib = "link/purge1/lib.kt" } task for0(type: KonanLocalTest) { goldValue = "2\n3\n4\n" source = "runtime/basic/for0.kt" } task throw0(type: KonanLocalTest) { goldValue = "Done\n" source = "runtime/basic/throw0.kt" } task statements0(type: KonanLocalTest) { goldValue = "239\n238\n30\n29\n" source = "runtime/basic/statements0.kt" } standaloneTest("annotations0") { source = "codegen/annotations/annotations0.kt" flags = ['-tr'] } task boxing0(type: KonanLocalTest) { goldValue = "17\n" source = "codegen/boxing/boxing0.kt" } task boxing1(type: KonanLocalTest) { goldValue = "1\nfalse\nHello\n" source = "codegen/boxing/boxing1.kt" } task boxing2(type: KonanLocalTest) { goldValue = "1\ntrue\nother\n" source = "codegen/boxing/boxing2.kt" } task boxing3(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/boxing/boxing3.kt" } task boxing4(type: KonanLocalTest) { goldValue = "16\n" source = "codegen/boxing/boxing4.kt" } task boxing5(type: KonanLocalTest) { goldValue = "16\n42\n" source = "codegen/boxing/boxing5.kt" } task boxing6(type: KonanLocalTest) { goldValue = "42\n16\n" source = "codegen/boxing/boxing6.kt" } task boxing7(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "1\n0\n" source = "codegen/boxing/boxing7.kt" } task boxing8(type: KonanLocalTest) { goldValue = "1\nnull\ntrue\nHello\n" source = "codegen/boxing/boxing8.kt" } task boxing9(type: KonanLocalTest) { goldValue = "1\nnull\ntrue\nHello\n2\nnull\ntrue\nHello\n3\n" source = "codegen/boxing/boxing9.kt" } task boxing10(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/boxing/boxing10.kt" } task boxing11(type: KonanLocalTest) { goldValue = "17\n42\n" source = "codegen/boxing/boxing11.kt" } task boxing12(type: KonanLocalTest) { goldValue = "18\n" source = "codegen/boxing/boxing12.kt" } task boxing13(type: KonanLocalTest) { goldValue = "false\nfalse\ntrue\ntrue\nfalse\nfalse\n" source = "codegen/boxing/boxing13.kt" } task boxing14(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/boxing/boxing14.kt" } task boxing15(type: KonanLocalTest) { goldValue = "17\n" source = "codegen/boxing/boxing15.kt" } task boxCache0(type: KonanLocalTest) { goldValue = "2\n256\n256\n256\n256\n256\n" source = "codegen/boxing/box_cache0.kt" } task interface0(type: KonanLocalTest) { goldValue = "PASSED\n" source = "runtime/basic/interface0.kt" } task hash0(type: KonanLocalTest) { goldValue = "239\n0\n97\n1065353216\n1072693248\n1\n0\ntrue\ntrue\n" source = "runtime/basic/hash0.kt" } task ieee754(type: KonanLocalTest) { goldValue = "Infinity 2147483647 -1 -1\n" + "3.4028235E38\n" + "NAN2SHORT:: 0\n" + "MAX2SHORT:: -1\n" + "2147483647 -1\n" + "FLOAT:: Infinity INT:: 2147483647\n" + "FLOAT:: 1.7014117E38 INT:: 2147483647\n" + "FLOAT:: 3.4028235E38 INT:: 2147483647\n" + "FLOAT:: 3.14 INT:: 3\n" + "FLOAT:: NaN INT:: 0\n" + "FLOAT:: -33333.125 INT:: -33333\n" + "FLOAT:: 1.4E-45 INT:: 0\n" + "FLOAT:: -Infinity INT:: -2147483648\n" + "FLOAT:: -1.2 INT:: -1\n" + "FLOAT:: -12.6 INT:: -12\n" + "FLOAT:: 2.3 INT:: 2\n" + "OK\n" source = "runtime/basic/ieee754.kt" } standaloneTest("hypotenuse") { source = "runtime/basic/hypot.kt" } task array_list1(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/array_list1.kt" } task array_list2(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') // uses exceptions goldValue = "OK\n" source = "runtime/collections/array_list2.kt" } task hash_map0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/hash_map0.kt" } task hash_map1(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/hash_map1.kt" } task hash_set0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/hash_set0.kt" } task listof0(type: KonanLocalTest) { goldValue = "abc\n[a, b, c, d]\n[n, s, a]\n" source = "runtime/collections/listof0.kt" } task listof1(type: KonanLocalTest) { enabled = false goldValue = "true\n[a, b, c]\n" source = "datagen/literals/listof1.kt" } task moderately_large_array(type: KonanLocalTest) { goldValue = "0\n" source = "runtime/collections/moderately_large_array.kt" } task moderately_large_array1(type: KonanLocalTest) { goldValue = "-45392\n" source = "runtime/collections/moderately_large_array1.kt" } task string_builder0(type: KonanLocalTest) { // Cannot be executed in the two-stage mode due to KT-33175. enabled = !twoStageEnabled expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "runtime/text/string_builder0.kt" } task string_builder1(type: KonanLocalTest) { goldValue = "HelloKotlin\n42\n0.1\ntrue\n\n" source = "runtime/text/string_builder1.kt" } task string0(type: KonanLocalTest) { goldValue = "true\ntrue\nПРИВЕТ\nпривет\nПока\ntrue\n" source = "runtime/text/string0.kt" } task parse0(type: KonanLocalTest) { goldValue = "false\n" + "true\n" + "-1\n" + "10\n" + "170\n" + "30\n" + "4294967295\n" + "bad format\n" + "0.5\n" + "2.39\n" source = "runtime/text/parse0.kt" } task to_string0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/text/to_string0.kt" } task trim(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions goldValue = "OK\n" source = "runtime/text/trim.kt" } task chars0(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. source = "runtime/text/chars0.kt" expectedExitStatus = 0 } task indexof(type: KonanLocalTest) { source = "runtime/text/indexof.kt" } task utf8(type: KonanLocalTest) { // Cannot be executed in the two-stage mode due to KT-33175. // Uses exceptions so cannot run on wasm. enabled = !twoStageEnabled && (project.testTarget != 'wasm32') goldValue = "Hello\nПривет\n\uD800\uDC00\n\n\uFFFD\uFFFD\n\uFFFD12\n\uFFFD12\n12\uFFFD\n\uD83D\uDE25\n\uD83D\uDE25\n" source = "runtime/text/utf8.kt" } task catch1(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Before\nCaught Throwable\nDone\n" source = "runtime/exceptions/catch1.kt" } task catch2(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Before\nCaught Error\nDone\n" source = "runtime/exceptions/catch2.kt" } task catch7(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Error happens\n" source = "runtime/exceptions/catch7.kt" } task extend_exception(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/exceptions/extend0.kt" } standaloneTest("check_stacktrace_format") { disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64') flags = ['-g'] source = "runtime/exceptions/check_stacktrace_format.kt" } standaloneTest("stack_trace_inline") { disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64') flags = ['-g'] source = "runtime/exceptions/stack_trace_inline.kt" } standaloneTest("kt-37572") { disabled = !isAppleTarget(project) || project.globalTestArgs.contains('-opt') || (project.testTarget == 'ios_arm64') flags = ['-g'] source = "runtime/exceptions/kt-37572.kt" } standaloneTest("custom_hook") { enabled = (project.testTarget != 'wasm32') && // Uses exceptions. !isExperimentalMM // Experimental MM does not support freezing yet. goldValue = "value 42: Error\n" expectedExitStatus = 1 source = "runtime/exceptions/custom_hook.kt" } standaloneTest("exception_in_global_init") { enabled = (project.testTarget != 'wasm32') // Uses exceptions. source = "runtime/exceptions/exception_in_global_init.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Uncaught Kotlin exception: kotlin.IllegalStateException: FAIL") && !s.contains("in kotlin main") } } task rethrow_exception(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') // Uses exceptions. source = "runtime/exceptions/rethrow.kt" } task throw_from_catch(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') // Uses exceptions. source = "runtime/exceptions/throw_from_catch.kt" } standaloneTest("runtime_math_exceptions") { enabled = (project.testTarget != 'wasm32') source = "stdlib_external/numbers/MathExceptionTest.kt" flags = ['-tr'] } standaloneTest("runtime_math") { source = "stdlib_external/numbers/MathTest.kt" flags = ['-tr'] } standaloneTest("runtime_math_harmony") { source = "stdlib_external/numbers/HarmonyMathTests.kt" flags = ['-tr'] } task catch3(type: KonanLocalTest) { goldValue = "Before\nCaught Throwable\nDone\n" source = "codegen/try/catch3.kt" } task catch4(type: KonanLocalTest) { goldValue = "Before\nCaught Error\nDone\n" source = "codegen/try/catch4.kt" } task catch5(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Before\nCaught Error\nDone\n" source = "codegen/try/catch5.kt" } task catch6(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Before\nCaught Error\nDone\n" source = "codegen/try/catch6.kt" } task catch8(type: KonanLocalTest) { goldValue = "Error happens\n" source = "codegen/try/catch8.kt" } task finally1(type: KonanLocalTest) { goldValue = "Try\nFinally\nDone\n" source = "codegen/try/finally1.kt" } task finally2(type: KonanLocalTest) { goldValue = "Try\nCaught Error\nFinally\nDone\n" source = "codegen/try/finally2.kt" } task finally3(type: KonanLocalTest) { goldValue = "Try\nFinally\nCaught Error\nDone\n" source = "codegen/try/finally3.kt" } task finally4(type: KonanLocalTest) { goldValue = "Try\nCatch\nFinally\nCaught Exception\nDone\n" source = "codegen/try/finally4.kt" } task finally5(type: KonanLocalTest) { goldValue = "Done\nFinally\n0\n" source = "codegen/try/finally5.kt" } task finally6(type: KonanLocalTest) { goldValue = "Done\nFinally\n1\n" source = "codegen/try/finally6.kt" } task finally7(type: KonanLocalTest) { goldValue = "Done\nFinally\n1\n" source = "codegen/try/finally7.kt" } task finally8(type: KonanLocalTest) { goldValue = "Finally 1\nFinally 2\n42\n" source = "codegen/try/finally8.kt" } task finally9(type: KonanLocalTest) { goldValue = "Finally 1\nFinally 2\nAfter\n" source = "codegen/try/finally9.kt" } task finally10(type: KonanLocalTest) { goldValue = "Finally\nAfter\n" source = "codegen/try/finally10.kt" } task finally11(type: KonanLocalTest) { goldValue = "Finally\nCatch 2\nDone\n" source = "codegen/try/finally11.kt" } task finally_returnsDifferentTypes(type: KonanLocalTest) { goldValue = "zzz\n42\n" source = "codegen/try/returnsDifferentTypes.kt" } task scope1(type: KonanLocalTest) { goldValue = "1\n" source = "codegen/dataflow/scope1.kt" } task uninitialized_val(type: KonanLocalTest) { goldValue = "1\n2\n" source = "codegen/dataflow/uninitialized_val.kt" } task try1(type: KonanLocalTest) { goldValue = "5\n" source = "codegen/try/try1.kt" } task try2(type: KonanLocalTest) { goldValue = "6\n" source = "codegen/try/try2.kt" } task try3(type: KonanLocalTest) { goldValue = "6\n" source = "codegen/try/try3.kt" } task try4(type: KonanLocalTest) { goldValue = "Try\n5\n" source = "codegen/try/try4.kt" } task unreachable1(type: KonanLocalTest) { goldValue = "1\n" source = "codegen/controlflow/unreachable1.kt" } task break_continue(type: KonanLocalTest) { goldValue = "foo@l1\nfoo@l2\nfoo@l2\nfoo@l2\nbar@l1\nbar@l2\nbar@l2\nbar@l2\nqux@t1\nqux@l2\nqux@l2\nqux@l2\n" source = "codegen/controlflow/break.kt" } task break1(type: KonanLocalTest) { goldValue = "Body\nDone\n" source = "codegen/controlflow/break1.kt" } task range0(type: KonanLocalTest) { goldValue = "123\nabcd\n" source = "runtime/collections/range0.kt" } standaloneTest("args0") { arguments = ["AAA", "BB", "C"] goldValue = "AAA\nBB\nC\n" source = "runtime/basic/args0.kt" } standaloneTest("devirtualization_lateinitInterface") { disabled = (cacheTesting != null) || // Cache is not compatible with -opt. isExperimentalMM // Experimental MM does not support -opt yet. goldValue = "42\n" flags = ["-opt"] source = "codegen/devirtualization/lateinitInterface.kt" } standaloneTest("devirtualization_getter_looking_as_box_function") { disabled = (cacheTesting != null) || // Cache is not compatible with -opt. isExperimentalMM // Experimental MM does not support -opt yet. goldValue = "box\n" flags = ["-opt"] source = "codegen/devirtualization/getter_looking_as_box_function.kt" } standaloneTest("devirtualization_anonymousObject") { disabled = (cacheTesting != null) || // Cache is not compatible with -opt. isExperimentalMM // Experimental MM does not support -opt yet. goldValue = "zzz\n" flags = ["-opt"] source = "codegen/devirtualization/anonymousObject.kt" } task interfaceCallsNCasts_conservativeItable(type: KonanLocalTest) { goldValue = "539\n5050\n26551140\n" source = "codegen/interfaceCallsNCasts/conservativeItable.kt" } standaloneTest("multiargs") { arguments = ["AAA", "BB", "C"] multiRuns = true multiArguments = [["1", "2", "3"], ["---"], ["Hello", "world"]] goldValue = "AAA\nBB\nC\n1\n2\n3\n" + "AAA\nBB\nC\n---\n" + "AAA\nBB\nC\nHello\nworld\n" source = "runtime/basic/args0.kt" } task spread_operator_0(type: KonanLocalTest) { goldValue = "[K, o, t, l, i, n, , i, s, , c, o, o, l, , l, a, n, g, u, a, g, e]\n" source = "codegen/basics/spread_operator_0.kt" } task main_exception(type: KonanLocalTest) { outputChecker = { s -> s.contains("kotlin.Error: Hello!") } expectedExitStatus = 1 source = "runtime/basic/main_exception.kt" } task runtime_basic_standard(type: KonanLocalTest) { source = "runtime/basic/standard.kt" } standaloneTest("runtime_basic_assert_failed") { expectedExitStatus = 1 source = "runtime/basic/assert_failed.kt" } standaloneTest("runtime_basic_assert_passed") { expectedExitStatus = 0 source = "runtime/basic/assert_passed.kt" } standaloneTest("runtime_basic_assert_disabled") { expectedExitStatus = 0 enableKonanAssertions = false source = "runtime/basic/assert_failed.kt" } task initializers0(type: KonanLocalTest) { goldValue = "main\n" + "B::constructor(1)\n" + "A::companion\n" + "A::companion::foo\n" + "A::companion::foo\n" + "B::constructor(0)\n" + "B::constructor()\n" + "A::Obj\n" + "A::AObj::foo\n" + "A::AObj::foo\n" source = "runtime/basic/initializers0.kt" } task initializers1(type: KonanLocalTest) { goldValue = "Init Test\n" + "Done\n" enabled = false source = "runtime/basic/initializers1.kt" } task concatenation(type: KonanLocalTest) { goldValue = "Hello world 1 2\nHello, a\nHello, b\n" source = "codegen/basics/concatenation.kt" } task const_infinity(type: KonanLocalTest) { source = "codegen/basics/const_infinity.kt" } task lambda1(type: KonanLocalTest) { goldValue = "lambda\n" source = "codegen/lambda/lambda1.kt" } task lambda2(type: KonanLocalTest) { arguments = ["arg0"] goldValue = "arg0\n" source = "codegen/lambda/lambda2.kt" } task lambda3(type: KonanLocalTest) { goldValue = "lambda\n" source = "codegen/lambda/lambda3.kt" } task lambda4(type: KonanLocalTest) { goldValue = "1\n2\n3\n3\n4\n" source = "codegen/lambda/lambda4.kt" } task lambda5(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/lambda/lambda5.kt" } task lambda6(type: KonanLocalTest) { goldValue = "42\ncaptured\n" source = "codegen/lambda/lambda6.kt" } task lambda7(type: KonanLocalTest) { goldValue = "43\n" source = "codegen/lambda/lambda7.kt" } task lambda8(type: KonanLocalTest) { goldValue = "first\n0\nsecond\n0\nfirst\n1\nsecond\n1\n" source = "codegen/lambda/lambda8.kt" } task lambda9(type: KonanLocalTest) { goldValue = "0\n0\n1\n0\n0\n1\n1\n1\n" source = "codegen/lambda/lambda9.kt" } task lambda10(type: KonanLocalTest) { goldValue = "original\nchanged\n" source = "codegen/lambda/lambda10.kt" } task lambda11(type: KonanLocalTest) { goldValue = "first\nsecond\n" source = "codegen/lambda/lambda11.kt" } task lambda12(type: KonanLocalTest) { goldValue = "one\ntwo\n" source = "codegen/lambda/lambda12.kt" } task lambda13(type: KonanLocalTest) { goldValue = "foo\n" source = "codegen/lambda/lambda13.kt" } standaloneTest("lambda14") { source = "codegen/lambda/lambda14.kt" flags = ['-tr'] } task funInterface_implIsNotFunction(type: KonanLocalTest) { source = "codegen/funInterface/implIsNotFunction.kt" } task funInterface_nonTrivialProjectionInSuperType(type: KonanLocalTest) { source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt" } task funInterface_kt43887(type: KonanLocalTest) { source = "codegen/funInterface/kt43887.kt" } task objectExpression1(type: KonanLocalTest) { goldValue = "aabb\n" source = "codegen/objectExpression/expr1.kt" } task objectExpression2(type: KonanLocalTest) { goldValue = "a\n" source = "codegen/objectExpression/expr2.kt" } task objectExpression3(type: KonanLocalTest) { goldValue = "\n1\n2\n" source = "codegen/objectExpression/expr3.kt" } standaloneTest("initializers2") { goldValue = "init globalValue2\n" + "init globalValue3\n" + "1\n" + "globalValue2\n" + "globalValue3\n" source = "runtime/basic/initializers2.kt" } task initializers3(type: KonanLocalTest) { goldValue = "42\n" source = "runtime/basic/initializers3.kt" } task initializers4(type: KonanLocalTest) { goldValue = "1073741824\ntrue\n" source = "runtime/basic/initializers4.kt" } task initializers5(type: KonanLocalTest) { goldValue = "42\n" source = "runtime/basic/initializers5.kt" } task initializers6(type: KonanLocalTest) { disabled = (project.testTarget == 'wasm32') || // Needs workers. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/basic/initializers6.kt" } task initializers7(type: KonanLocalTest) { source = "runtime/basic/initializers7.kt" } task initializers8(type: KonanLocalTest) { source = "runtime/basic/initializers8.kt" } task expression_as_statement(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // uses exceptions. goldValue = "Ok\n" source = "codegen/basics/expression_as_statement.kt" } task codegen_escapeAnalysis_zeroOutObjectOnAlloc(type: KonanLocalTest) { source = "codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt" } task codegen_escapeAnalysis_recursion(type: KonanLocalTest) { source = "codegen/escapeAnalysis/recursion.kt" } task memory_var1(type: KonanLocalTest) { source = "runtime/memory/var1.kt" } task memory_var2(type: KonanLocalTest) { source = "runtime/memory/var2.kt" } task memory_var3(type: KonanLocalTest) { source = "runtime/memory/var3.kt" } task memory_var4(type: KonanLocalTest) { source = "runtime/memory/var4.kt" } task memory_throw_cleanup(type: KonanLocalTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "Ok\n" source = "runtime/memory/throw_cleanup.kt" } task memory_escape0(type: KonanLocalTest) { source = "runtime/memory/escape0.kt" } task memory_escape1(type: KonanLocalTest) { goldValue = "zzz\n" source = "runtime/memory/escape1.kt" } task memory_cycles0(type: KonanLocalTest) { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. goldValue = "42\n" source = "runtime/memory/cycles0.kt" } task memory_cycles1(type: KonanLocalTest) { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. source = "runtime/memory/cycles1.kt" } task memory_basic0(type: KonanLocalTest) { source = "runtime/memory/basic0.kt" } task memory_escape2(type: KonanLocalTest) { goldValue = "zzz\n" source = "runtime/memory/escape2.kt" } task memory_weak0(type: KonanLocalTest) { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. goldValue = "Data(s=Hello)\nnull\nOK\n" source = "runtime/memory/weak0.kt" } task memory_weak1(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/memory/weak1.kt" } standaloneTest("memory_only_gc") { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. source = "runtime/memory/only_gc.kt" } task memory_stable_ref_cross_thread_check(type: KonanLocalTest) { disabled = (project.testTarget == 'wasm32') || // Needs workers. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "runtime/memory/stable_ref_cross_thread_check.kt" } standaloneTest("cycle_detector") { disabled = project.globalTestArgs.contains('-opt') || // Needs debug build. (project.testTarget == 'wasm32') || // CycleDetector is disabled on WASM. isExperimentalMM // Experimental MM will not support CycleDetector. flags = ['-tr', '-g'] source = "runtime/memory/cycle_detector.kt" } standaloneTest("cycle_collector") { disabled = true // Needs USE_CYCLIC_GC, which is disabled. source = "runtime/memory/cycle_collector.kt" } standaloneTest("cycle_collector_deadlock1") { disabled = true // Needs USE_CYCLIC_GC, which is disabled. source = "runtime/memory/cycle_collector_deadlock1.kt" } standaloneTest("leakMemory") { source = "runtime/memory/leak_memory.kt" if (!isExperimentalMM) { // Experimental MM will not report memory leaks. expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } } standaloneTest("leakMemoryWithTestRunner") { source = "runtime/memory/leak_memory_test_runner.kt" flags = ['-tr'] if (!isExperimentalMM) { // Experimental MM will not report memory leaks. expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } } standaloneTest("mpp1") { source = "codegen/mpp/mpp1.kt" flags = ['-tr', '-Xmulti-platform'] } linkTest("mpp2") { goldValue = "C(arg=42)\ntrue\n1\nh\n" source = "codegen/mpp/mpp2.kt" lib = "codegen/mpp/libmpp2.kt" flags = ['-Xmulti-platform'] } standaloneTest("mpp_default_args") { source = "codegen/mpp/mpp_default_args.kt" flags = ['-tr', '-Xmulti-platform'] } standaloneTest("mpp_optional_expectation") { source = "codegen/mpp/mpp_optional_expectation.kt" def outputRoot = project.ext.testOutputLocal.toString() def srcPath = "$outputRoot/$name/mpp_optional_expectation.kt".with { isWindows() ? it.replaceAll("/", "\\\\") : it } flags = [ '-Xmulti-platform', "-Xcommon-sources=$srcPath" ] } task unit1(type: KonanLocalTest) { goldValue = "First\nkotlin.Unit\n" source = "codegen/basics/unit1.kt" } task unit2(type: KonanLocalTest) { goldValue = "kotlin.Unit\n" source = "codegen/basics/unit2.kt" } task unit3(type: KonanLocalTest) { goldValue = "kotlin.Unit\n" source = "codegen/basics/unit3.kt" } task unit4(type: KonanLocalTest) { goldValue = "Done\n" source = "codegen/basics/unit4.kt" } task kt42000_1(type: KonanLocalTest) { source = "codegen/basics/k42000_1.kt" } task kt42000_2(type: KonanLocalTest) { source = "codegen/basics/k42000_2.kt" } task inline0(type: KonanLocalTest) { goldValue = "84\n" source = "codegen/inline/inline0.kt" } task vararg0(type: KonanLocalTest) { source = "lower/vararg.kt" } task vararg_of_literals(type: KonanLocalTest) { enabled = false goldValue = "a\na\n" source = "lower/vararg_of_literals.kt" } standaloneTest('tailrec') { goldValue = "12\n100000000\n" + "8\n" + "1\n" + "3 ...\n2 ...\n1 ...\nready!\n" + "2\n-1\n" + "true\nfalse\n" + "default\n" + "42\n" source = "lower/tailrec.kt" flags = ['-XXLanguage:-ProhibitTailrecOnVirtualMember', '-e', 'lower.tailrec.main'] } task inline1(type: KonanLocalTest) { goldValue = "Hello world\n" source = "codegen/inline/inline1.kt" } task inline2(type: KonanLocalTest) { goldValue = "hello 1 8\n" source = "codegen/inline/inline2.kt" } task inline3(type: KonanLocalTest) { goldValue = "5\n" source = "codegen/inline/inline3.kt" } task inline4(type: KonanLocalTest) { goldValue = "3\n" source = "codegen/inline/inline4.kt" } task inline5(type: KonanLocalTest) { goldValue = "33\n" source = "codegen/inline/inline5.kt" } task inline6(type: KonanLocalTest) { goldValue = "hello1\nhello2\nhello3\nhello4\n" source = "codegen/inline/inline6.kt" } task inline7(type: KonanLocalTest) { goldValue = "1\n2\n3\n" source = "codegen/inline/inline7.kt" } task inline8(type: KonanLocalTest) { goldValue = "8\n" source = "codegen/inline/inline8.kt" } task inline9(type: KonanLocalTest) { goldValue = "hello\n6\n" source = "codegen/inline/inline9.kt" } task inline10(type: KonanLocalTest) { goldValue = "2\n" source = "codegen/inline/inline10.kt" } task inline13(type: KonanLocalTest) { goldValue = "true\n" source = "codegen/inline/inline13.kt" } task inline14(type: KonanLocalTest) { goldValue = "9\n" source = "codegen/inline/inline14.kt" } task inline15(type: KonanLocalTest) { goldValue = "4\n" source = "codegen/inline/inline15.kt" } task inline16(type: KonanLocalTest) { goldValue = "false\n" source = "codegen/inline/inline16.kt" } task inline17(type: KonanLocalTest) { goldValue = "[1, 2]\n" source = "codegen/inline/inline17.kt" } task inline18(type: KonanLocalTest) { goldValue = "true\n" source = "codegen/inline/inline18.kt" } task inline19(type: KonanLocalTest) { goldValue = "6\n" source = "codegen/inline/inline19.kt" } task inline20(type: KonanLocalTest) { goldValue = "def\n" source = "codegen/inline/inline20.kt" } task inline21(type: KonanLocalTest) { goldValue = "bar\nfoo1\nfoo2\n33\n" source = "codegen/inline/inline21.kt" } task inline22(type: KonanLocalTest) { goldValue = "14\n" source = "codegen/inline/inline22.kt" } task inline23(type: KonanLocalTest) { goldValue = "33\n" source = "codegen/inline/inline23.kt" } task inline24(type: KonanLocalTest) { enabled = false goldValue = "bar\nfoo\n" source = "codegen/inline/inline24.kt" } task inline25(type: KonanLocalTest) { goldValue = "Ok\nOk\n" source = "codegen/inline/inline25.kt" } task inline26(type: KonanLocalTest) { goldValue = "5\n" source = "codegen/inline/inline26.kt" } task inline_type_substitution_in_fake_override(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/typeSubstitutionInFakeOverride.kt" } task inline_localFunctionInInitializerBlock(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/inline/localFunctionInInitializerBlock.kt" } task inline_lambdaInDefaultValue(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/lambdaInDefaultValue.kt" } task inline_lambdaAsAny(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/inline/lambdaAsAny.kt" } task inline_getClass(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/getClass.kt" } task inline_statementAsLastExprInBlock(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/statementAsLastExprInBlock.kt" } task inline_returnLocalClassFromBlock(type: KonanLocalTest) { enabled = false goldValue = "Zzz\n" source = "codegen/inline/returnLocalClassFromBlock.kt" } task inline_changingCapturedLocal(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/changingCapturedLocal.kt" } task inline_defaultArgs(type: KonanLocalTest) { goldValue = "42\n" source = "codegen/inline/defaultArgs.kt" } task inline_propertyAccessorInline(type: KonanLocalTest) { goldValue = "123\n42\n" source = "codegen/inline/propertyAccessorInline.kt" } task inline_twiceInlinedObject(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/inline/twiceInlinedObject.kt" } task inline_localObjectReturnedFromWhen(type: KonanLocalTest) { goldValue = "Ok\n" source = "codegen/inline/localObjectReturnedFromWhen.kt" } task inline_genericFunctionReference(type: KonanLocalTest) { goldValue = "0\n" source = "codegen/inline/genericFunctionReference.kt" } task inline_correctOrderFunctionReference(type: KonanLocalTest) { goldValue = "OK\n" source = "codegen/inline/correctOrderFunctionReference.kt" } task inline_coercionToUnit(type: KonanLocalTest) { goldValue = "kotlin.Unit\n" source = "codegen/inline/coercionToUnit.kt" } task classDeclarationInsideInline(type: KonanLocalTest) { source = "codegen/inline/classDeclarationInsideInline.kt" goldValue = "test1: 1.0\n1\ntest2\n" } task inlineClass0(type: KonanLocalTest) { source = "codegen/inlineClass/inlineClass0.kt" } task inlineClass_customEquals(type: KonanLocalTest) { source = "codegen/inlineClass/customEquals.kt" } task inlineClass_defaultEquals(type: KonanLocalTest) { source = "codegen/inlineClass/defaultEquals.kt" } task inlineClass_secondaryConstructorWithGenerics(type: KonanLocalTest) { source = "codegen/inlineClass/secondaryConstructorWithGenerics.kt" } task inlineClass_nestedInlineClasses(type: KonanLocalTest) { source = "codegen/inlineClass/nestedInlineClasses.kt" } task valueClass0(type: KonanLocalTest) { source = "codegen/inlineClass/valueClass0.kt" } task deserialized_inline0(type: KonanLocalTest) { source = "serialization/deserialized_inline0.kt" } task deserialized_listof0(type: KonanLocalTest) { source = "serialization/deserialized_listof0.kt" } task deserialized_fields(type: KonanLocalTest) { source = "serialization/deserialized_fields.kt" } task genKt39548 { doFirst { GenTestKT39548Kt.genTestKT39548(file("$buildDir/kt39548/kt39548.kt")) } } KotlinNativeTestKt.createTest(project, "kt39548", KonanStandaloneTest) { task -> // Test infrastructure doesn't support generated source; // workaround by specifying dummy source: task.source = "does/not/exist/kt39548.dummy.kt" task.enabled = isWindowsTarget(project) if (task.enabled) { konanArtifacts { program(name, targets: [target.name]) { baseDir "$testOutputLocal/$name" srcFiles "$buildDir/kt39548/kt39548.kt" // Generated by genKt39548 task. extraOpts task.flags extraOpts project.globalTestArgs } } UtilsKt.findKonanBuildTask(project, name, target).dependsOn(genKt39548) } } linkTest("deserialized_members") { goldValue= "first level\n"+ "second level\n"+ "third levelxz\n"+ "inner first level\n"+ "inner second level\n"+ "inner third level\n"+ "types first level: 13\n"+ "types second level cha-cha-cha\n"+ "types third level 1.0\n" lib = "serialization/serialize_members.kt" source = "serialization/deserialize_members.kt" } linkTest("serialized_catch") { source = "serialization/use.kt" lib = "serialization/catch.kt" goldValue = "Gotcha1: XXX\nGotcha2: YYY\n" } linkTest("serialized_doWhile") { source = "serialization/use.kt" lib = "serialization/do_while.kt" goldValue = "999\n" } linkTest("serialized_vararg") { source = "serialization/use.kt" lib = "serialization/vararg.kt" goldValue = "17\n19\n23\n29\n31\nsize: 5\n" } linkTest("serialized_default_args") { source = "serialization/prop.kt" lib = "serialization/default_args.kt" goldValue = "SomeDataClass(first=17, second=666, third=23)\n" } standaloneTest("serialized_no_typemap") { source = "serialization/regression/no_type_map.kt" goldValue = "OK\n" } linkTest("serialized_enum_ordinal") { source = "serialization/enum_ordinal/main.kt" lib = "serialization/enum_ordinal/library.kt" goldValue = "0\n1\n2\nb\n" } linkTest("serialized_char_constant") { source = "serialization/use_char_const.kt" lib = "serialization/char_const.kt" goldValue = "Ы\n" } standaloneTest("testing_annotations") { source = "testing/annotations.kt" flags = ['-tr'] arguments = ['--ktest_logger=SIMPLE'] goldValue = 'Starting testing\nStarting iteration: 1\n' + 'Test suite ignored: kotlin.test.tests.IgnoredClass.IgnoredObject\n' + 'Test suite ignored: kotlin.test.tests.IgnoredClass\nTest suite ignored: kotlin.test.tests.IgnoredObject\n' + 'Starting test suite: kotlin.test.tests.A\nbeforeClass (A.companion)\n' + 'Starting test case: test1 (kotlin.test.tests.A)\nbefore (A)\ntest1 (A)\nafter (A)\n' + 'Passed: test1 (kotlin.test.tests.A)\nIgnore: ignoredTest (kotlin.test.tests.A)\n' + 'afterClass (A.companion)\nTest suite finished: kotlin.test.tests.A\n' + 'Starting test suite: kotlin.test.tests.A.O\nbeforeClass (A.object)\n' + 'Starting test case: test1 (kotlin.test.tests.A.O)\nbefore (A.object)\n' + 'test1 (A.object)\nafter (A.object)\nPassed: test1 (kotlin.test.tests.A.O)\n' + 'Ignore: ignoredTest (kotlin.test.tests.A.O)\nafterClass (A.object)\n' + 'Test suite finished: kotlin.test.tests.A.O\nStarting test suite: kotlin.test.tests.O\n' + 'beforeClass (object)\nStarting test case: test1 (kotlin.test.tests.O)\nbefore (object)\n' + 'test1 (object)\nafter (object)\nPassed: test1 (kotlin.test.tests.O)\n' + 'Ignore: ignoredTest (kotlin.test.tests.O)\nafterClass (object)\nTest suite finished: kotlin.test.tests.O\n' + 'Starting test suite: kotlin.test.tests.AnnotationsKt\nbeforeClass (file)\n' + 'Starting test case: test1 (kotlin.test.tests.AnnotationsKt)\nbefore (file)\n' + 'test1 (file)\nafter (file)\nPassed: test1 (kotlin.test.tests.AnnotationsKt)\n' + 'Ignore: ignoredTest (kotlin.test.tests.AnnotationsKt)\nafterClass (file)\n' + 'Test suite finished: kotlin.test.tests.AnnotationsKt\nIteration finished: 1\nTesting finished\n' } standaloneTest("testing_assertions") { source = "testing/assertions.kt" flags = ['-tr'] expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. expectedExitStatus = 0 } standaloneTest("testing_custom_main") { source = "testing/custom_main.kt" flags = ['-tr', '-e', 'kotlin.test.tests.main'] arguments = ['--ktest_logger=SIMPLE', '--ktest_repeat=2'] goldValue = 'Custom main\n' + 'Starting testing\n' + 'Starting iteration: 1\n' + 'Starting test suite: kotlin.test.tests.Custom_mainKt\n' + 'Starting test case: test (kotlin.test.tests.Custom_mainKt)\n' + 'test\n' + 'Passed: test (kotlin.test.tests.Custom_mainKt)\n' + 'Test suite finished: kotlin.test.tests.Custom_mainKt\n' + 'Iteration finished: 1\n' + 'Starting iteration: 2\n' + 'Starting test suite: kotlin.test.tests.Custom_mainKt\n' + 'Starting test case: test (kotlin.test.tests.Custom_mainKt)\n' + 'test\n' + 'Passed: test (kotlin.test.tests.Custom_mainKt)\n' + 'Test suite finished: kotlin.test.tests.Custom_mainKt\n' + 'Iteration finished: 2\n' + 'Testing finished\n' } standaloneTest("testing_library_usage") { def target = project.testTarget ?: 'host' dependsOn konanArtifacts.baseTestClass.getByTarget(target) def klib = konanArtifacts.baseTestClass.getArtifactByTarget(target) source = 'testing/library_user.kt' flags = ['-tr', '-e', 'main', '-l', klib.absolutePath] arguments = ['--ktest_logger=SILENT'] } class Filter { List positive List negative List expectedTests Filter(List positive, List negative, List expectedTests) { this.positive = positive this.negative = negative this.expectedTests = expectedTests } List args() { List result = [] if (positive != null && !positive.isEmpty()) { result += "--ktest_gradle_filter=${asListOfPatterns(positive)}" } if (negative != null && !negative.isEmpty()) { result += "--ktest_negative_gradle_filter=${asListOfPatterns(negative)}" } return result } static private String asListOfPatterns(List input) { return input.collect { "kotlin.test.tests.$it" }.join(",") } } standaloneTest("testing_filters") { source = "testing/filters.kt" flags = ['-tr', '-ea'] def filters = [ new Filter(["A.foo1", "B", "FiltersKt.foo1"], [], ["A.foo1", "B.foo1", "B.foo2", "B.bar", "FiltersKt.foo1"]), new Filter([], ["A.foo1", "B", "FiltersKt.foo1"], ["A.foo2", "A.bar", "FiltersKt.foo2", "FiltersKt.bar"]), new Filter(["A", "FiltersKt"], ["A.foo1", "FiltersKt.foo1"], ["A.foo2", "A.bar", "FiltersKt.foo2", "FiltersKt.bar"]), new Filter(["A.foo*", "B.*"], [], ["A.foo1", "A.foo2", "B.foo1", "B.foo2", "B.bar"]), new Filter([], ["A.foo*", "B.*"], ["A.bar", "FiltersKt.foo1", "FiltersKt.foo2", "FiltersKt.bar"]), new Filter(["*.foo*"], ["B"], ["A.foo1", "A.foo2", "FiltersKt.foo1", "FiltersKt.foo2"]), new Filter(["A"], ["*.foo*"], ["A.bar"]) ] multiRuns = true multiArguments = filters.collect { it.args() + '--ktest_logger=SIMPLE' } outputChecker = { String output -> // The first chunk is empty - drop it. def outputs = output.split("Starting testing\n").drop(1) if (outputs.size() != filters.size()) { println("Incorrect number of test runs. Expected: ${filters.size()}, actual: ${outputs.size()}") return false } // Check the correct set of tests was executed in each run. for (int i = 0; i < outputs.size(); i++) { def actualMessages = outputs[i].split('\n').findAll { it.startsWith("Passed: ") } def expectedMessages = filters[i].expectedTests.collect { String test -> def method = test.substring(test.lastIndexOf('.') + 1) def suite = test.substring(0, test.lastIndexOf('.')) "Passed: $method (kotlin.test.tests.$suite)".toString() } if (actualMessages.size() != expectedMessages.size()) { println("Incorrect number of tests executed for filters[$i]. Expected: ${expectedMessages.size()}. Actual: ${actualMessages.size()}") return false } for (message in expectedMessages) { if (!actualMessages.contains(message)) { println("Test run output for filters[$i] doesn't contain the expected message '$message'") return false } } } return true } } standaloneTest("testing_filtered_suites") { source = "testing/filtered_suites.kt" flags = ["-tr", "-ea"] def filters = [ ["Filtered_suitesKt.*"], // filter out a class. ["A.*"], // filter out a top-level suite. ["*.common"], // run a test from all suites -> all hooks executed. ["Ignored.*"], // an ignored suite -> no hooks executed. ["A.ignored"] // a suite with only ignored tests -> no hooks executed. ] def expectedHooks = [ ["Filtered_suitesKt.before", "Filtered_suitesKt.after"], ["A.before", "A.after"], ["A.before", "A.after", "Filtered_suitesKt.before", "Filtered_suitesKt.after"], [], [] ] multiRuns = true multiArguments = filters.collect { def filter = it.collect { "kotlin.test.tests.$it" }.join(",") ["--ktest_gradle_filter=$filter", "--ktest_logger=SIMPLE"] } outputChecker = { String output -> // The first chunk is empty - drop it. def outputs = output.split("Starting testing\n").drop(1) if (outputs.size() != expectedHooks.size()) { println("Incorrect number of test runs. Expected: ${expectedHooks.size()}, actual: ${outputs.size()}") return false } // Check the correct set of hooks was executed on each run. for (int i = 0; i < outputs.size(); i++) { def actual = outputs[i].split('\n') .findAll { it.startsWith("Hook:") } .collect { it.replace("Hook: ", "") } def expected = expectedHooks[i] if (actual.size() != expected.size()) { println("Incorrect number of executed hooks for run #$i. Expected: ${expected.size()}. Actual: ${actual.size()}") println("Expected hooks: $expected") println("Actual hooks: $actual") return false } for (expectedHook in expected) { if (!actual.contains(expectedHook)) { println("Expected hook wasn't executed for run #$i: $expectedHook") println("Expected hooks: $expected") println("Actual hooks: $actual") return false } } } return true } } // Check that stacktraces and ignored suite are correctly reported in the TC logger. standaloneTest("testing_stacktrace") { source = "testing/stacktrace.kt" flags = ['-tr', '-ea'] arguments = ["--ktest_logger=TEAMCITY", "--ktest_no_exit_code"] expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. // This test prints TeamCity service messages about failed test causing false negative failure at CI. // So we need to suppress printing these messages to stdout. // printOutput = false outputChecker = { String output -> def ignoredOutput = """\ |##teamcity[testSuiteStarted name='kotlin.test.tests.Ignored' locationHint='ktest:suite://kotlin.test.tests.Ignored'] |##teamcity[testIgnored name='foo'] |##teamcity[testSuiteFinished name='kotlin.test.tests.Ignored']""".stripMargin() def failedOutput = """\ |##teamcity[testSuiteStarted name='kotlin.test.tests.Failed' locationHint='ktest:suite://kotlin.test.tests.Failed'] |##teamcity[testStarted name='bar' locationHint='ktest:test://kotlin.test.tests.Failed.bar'] |##teamcity[testFailed name='bar' message='Bar' details='kotlin.Exception: Bar|n""".stripMargin() def shownInnerException = output.readLines() .find { it.startsWith("##teamcity[testFailed name='bar'") } ?.contains("Caused by: kotlin.Exception: Baz") ?: false return output.contains(ignoredOutput) && output.contains(failedOutput) && shownInnerException } } // Just check that the driver is able to produce runnable binaries. tasks.register("driver0", KonanDriverTest) { goldValue = "Hello, world!\n" source = "runtime/basic/driver0.kt" } tasks.register("driver_opt", KonanDriverTest) { disabled = (cacheTesting != null) || // Cache is not compatible with -opt. isExperimentalMM // Experimental MM does not support -opt yet. goldValue = "Hello, world!\n" source = "runtime/basic/driver0.kt" flags = ["-opt"] } // Enable when deserialization for default arguments is fixed. linkTest("inline_defaultArgs_linkTest") { goldValue = "122\n47\n" source = "codegen/inline/defaultArgs_linkTest_main.kt" lib = "codegen/inline/defaultArgs_linkTest_lib.kt" } linkTest("inline_sharedVar_linkTest") { goldValue = "6\n" source = "codegen/inline/sharedVar_linkTest_main.kt" lib = "codegen/inline/sharedVar_linkTest_lib.kt" } linkTest("inline_lateinitProperty_linkTest") { disabled = (project.testTarget == 'wasm32') // Uses exceptions. goldValue = "OK\n" source = "codegen/inline/lateinitProperty_linkTest_main.kt" lib = "codegen/inline/lateinitProperty_linkTest_lib.kt" } linkTest("inline_inlineCtor_linkTest") { source = "codegen/inline/inlineCtor_linkTest_main.kt" lib = "codegen/inline/inlineCtor_linkTest_lib.kt" } def generateWithSpaceDefFile() { def mapOption = "--Map \"${buildDir}/cutom map.map\"" if (isAppleTarget(project)) { mapOption = "-map \"${buildDir}/cutom map.map\"" } else if (isWindowsTarget(project)) { mapOption = "\"-Wl,--Map,${buildDir}/cutom map.map\"" } def file = new File("${buildDir}/withSpaces.def") file.write """ headers = stdio.h "${projectDir}/interop/basics/custom headers/custom.h" linkerOpts = $mapOption --- int customCompare(const char* str1, const char* str2) { return custom_strcmp(str1, str2); } """ return file.absolutePath } // A helper method to create interop artifacts void createInterop(String name, Closure conf) { konanArtifacts { interop(name, targets: [target.name]) { conf(it) noDefaultLibs(true) noEndorsedLibs(true) baseDir "$testOutputLocal/$name" } } } createInterop("sysstat") { // FIXME: creates empty file to workaround konan gradle plugin issue (should be able to have no def file) def f = File.createTempFile("sysstat.empty", ".def") it.packageName 'sysstat' // FIXME: this option doesn't work due to an issue in plugin: it tries to resolve header in project dir. //it.headers 'sys/stat.h' f.write("headers = sys/stat.h") it.defFile f } createInterop("cstdlib") { def f = File.createTempFile("cstdlib.empty", ".def") it.packageName 'cstdlib' // it.headers 'stdlib.h' f.write("headers = stdlib.h") it.defFile f } createInterop("cstdio") { it.defFile 'interop/basics/cstdio.def' } createInterop("sockets") { it.defFile 'interop/basics/sockets.def' } createInterop("bitfields") { it.defFile 'interop/basics/bitfields.def' } createInterop("cglobals") { it.defFile 'interop/basics/cglobals.def' } createInterop("cfunptr") { it.defFile 'interop/basics/cfunptr.def' } createInterop("cmacros") { it.defFile 'interop/basics/cmacros.def' } createInterop("cunsupported") { it.defFile 'interop/basics/cunsupported.def' } createInterop("ctoKString") { it.defFile 'interop/basics/ctoKString.def' } createInterop("ctypes") { it.defFile 'interop/basics/ctypes.def' } createInterop("cvalues") { it.defFile 'interop/basics/cvalues.def' } createInterop("cvectors") { it.defFile 'interop/basics/cvectors.def' } createInterop("cstructs") { it.defFile 'interop/basics/cstructs.def' } createInterop("ccallbacksAndVarargs") { it.defFile 'interop/basics/ccallbacksAndVarargs.def' } createInterop("cmangling") { it.defFile 'interop/basics/mangling.def' } createInterop("cmangling2") { it.defFile 'interop/basics/mangling2.def' } createInterop("cmangling_keywords") { it.defFile 'interop/basics/mangling_keywords.def' } createInterop("cmangling_keywords2") { it.defFile 'interop/basics/mangling_keywords2.def' } createInterop("cunion") { it.defFile 'interop/basics/cunion.def' } createInterop("cenums") { it.defFile 'interop/basics/cenums.def' } createInterop("carrayPointers") { it.defFile 'interop/basics/carrayPointers.def' } createInterop("auxiliaryCppSources") { // We need to provide empty def file to create correct `KonanInteropTask`. it.defFile 'interop/auxiliary_sources/auxiliaryCppSources.def' it.headers "$projectDir/interop/auxiliary_sources/name.h" it.extraOpts "-Xcompile-source", "$projectDir/interop/auxiliary_sources/name.cpp" it.extraOpts "-Xsource-compiler-option", "-std=c++17" } createInterop("concurrentTerminate") { it.defFile 'interop/concurrentTerminate/concurrentTerminate.def' it.headers "$projectDir/interop/concurrentTerminate/async.h" // TODO: Using `-Xcompile-source` does not imply dependency on that source, so the task will no re-run when the source is updated. it.extraOpts "-Xcompile-source", "$projectDir/interop/concurrentTerminate/async.cpp" it.extraOpts "-Xsource-compiler-option", "-std=c++17" } createInterop("incomplete_types") { it.defFile 'interop/incomplete_types/library.def' it.headers "$projectDir/interop/incomplete_types/library.h" it.extraOpts "-Xcompile-source", "$projectDir/interop/incomplete_types/library.cpp" } createInterop("embedStaticLibraries") { it.defFile 'interop/embedStaticLibraries/embedStaticLibraries.def' it.headers "$projectDir/interop/embedStaticLibraries/embedStaticLibraries.h" // Note: also hardcoded in def file. final String libDir = "$buildDir/embedStaticLibraries/" it.getByTarget(target.name).configure { doFirst { 1.upto(4) { UtilsKt.buildStaticLibrary( project, [file("$projectDir/interop/embedStaticLibraries/${it}.c")], file("$libDir/${it}.a"), file("$libDir/${it}.objs"), ) } } } it.extraOpts '-staticLibrary', "1.a" it.extraOpts '-staticLibrary', "2.a" } createInterop("kt43265") { it.defFile 'interop/kt43265/kt43265.def' } createInterop("kt43502") { it.defFile 'interop/kt43502/kt43502.def' it.headers "$projectDir/interop/kt43502/kt43502.h" // Note: also hardcoded in def file. final String libDir = "$buildDir/kt43502/" // Construct library that contains actual symbol definition. it.getByTarget(target.name).configure { doFirst { UtilsKt.buildStaticLibrary( project, [file("$projectDir/interop/kt43502/kt43502.c")], file("$libDir/kt43502.a"), file("$libDir/kt43502.objs"), ) } } } createInterop("leakMemoryWithRunningThread") { it.defFile 'interop/leakMemoryWithRunningThread/leakMemory.def' it.headers "$projectDir/interop/leakMemoryWithRunningThread/leakMemory.h" it.extraOpts "-Xcompile-source", "$projectDir/interop/leakMemoryWithRunningThread/leakMemory.cpp" } if (PlatformInfo.isAppleTarget(project)) { createInterop("objcSmoke") { it.defFile 'interop/objc/objcSmoke.def' it.headers "$projectDir/interop/objc/smoke.h" } createInterop("objcTests") { it.defFile 'interop/objc/objcTests.def' it.headers fileTree("$projectDir/interop/objc/tests") { include '**/*.h' } } createInterop("objcMisc") { it.defFile 'interop/objc_with_initializer/objc_misc.def' it.headers "$projectDir/interop/objc_with_initializer/objc_misc.h" } createInterop("objcMessaging") { it.defFile 'interop/objc/msg_send/messaging.def' it.headers "$projectDir/interop/objc/msg_send/messaging.h" } createInterop("foreignException") { it.defFile 'interop/objc/foreignException/objc_wrap.def' it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h" } createInterop("foreignExceptionMode_default") { it.defFile 'interop/objc/foreignException/objcExceptionMode.def' it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h" } createInterop("foreignExceptionMode_wrap") { it.defFile 'interop/objc/foreignException/objcExceptionMode.def' it.headers "$projectDir/interop/objc/foreignException/objc_wrap.h" it.extraOpts '-Xforeign-exception-mode', "objc-wrap" } createInterop("objcKt34467") { it.defFile 'interop/objc/kt34467/module_library.def' def moduleMap = file("interop/objc/kt34467/module_library.modulemap").absolutePath def includePath = file("interop/objc/kt34467").absolutePath it.compilerOpts "-fmodule-map-file=$moduleMap", "-I$includePath" } createInterop("objcGh3343") { it.defFile 'framework/gh3343/objclib.def' it.headers "$projectDir/framework/gh3343/objclib.h" it.linkerOpts "-lobjcgh3343" } createInterop("objc_illegal_sharing_with_weak") { it.defFile 'interop/objc/illegal_sharing_with_weak/objclib.def' it.headers "$projectDir/interop/objc/illegal_sharing_with_weak/objclib.h" } createInterop("objcKt43517") { it.defFile 'framework/kt43517/kt43517.def' } createInterop("objc_kt42172") { it.defFile 'interop/objc/kt42172/objclib.def' it.headers "$projectDir/interop/objc/kt42172/objclib.h" } } createInterop("withSpaces") { it.defFile generateWithSpaceDefFile() } /** * Creates a task for the interop test. Configures runner and adds library and test build tasks. */ Task interopTestBase(String name, boolean multiFile, Closure configureClosure) { return KotlinNativeTestKt.createTest(project, name, KonanInteropTest) { task -> task.configure(configureClosure) if (task.enabled) { konanArtifacts { def lib = task.interop UtilsKt.dependsOnKonanBuildingTask(task, lib, target) program(name, targets: [target.name]) { libraries { artifact lib } srcFiles multiFile ? fileTree(task.source) { include '**/*.kt' } : task.getSources() baseDir "$testOutputLocal/$name" linkerOpts "-L$buildDir" extraOpts task.flags extraOpts project.globalTestArgs } } } } } Task interopTest(String name, Closure configureClosure) { return interopTestBase(name, false, configureClosure) } Task interopTestMultifile(String name, Closure configureClosure) { return interopTestBase(name, true, configureClosure) } standaloneTest("interop_objc_allocException") { dependsOnPlatformLibs(it) disabled = !isAppleTarget(project) expectedExitStatus = 0 source = "interop/objc/allocException.kt" } interopTest("interop0") { disabled = (project.testTarget == 'wasm32') || // No interop for wasm yet. (project.testTarget == 'linux_mips32') || // st_uid of '/' is not equal to 0 when using qemu (project.testTarget == 'linux_mipsel32') || (project.testTarget == 'linux_arm32_hfp') || (project.testTarget == 'linux_arm64') goldValue = "0\n0\n" source = "interop/basics/0.kt" interop = 'sysstat' } interopTest("interop1") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. goldValue = "257\n-1\n-2\n" source = "interop/basics/1.kt" interop = 'cstdlib' } interopTest("interop2") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. goldValue = "Hello\n" source = "interop/basics/2.kt" interop = 'cstdio' } interopTest("interop3") { // We disable this test on Raspberry Pi because // qsort accepts size_t args. So the .kt file // should be different depending on the bitness of the target. // There are plans to provide a solution and turn this // test back on. disabled = (project.testTarget == 'raspberrypi') || (project.testTarget == 'linux_mips32') || (project.testTarget == 'linux_mipsel32') || (project.testTarget == 'wasm32') // No interop for wasm yet. goldValue = "8 9 12 13 14 \n" source = "interop/basics/3.kt" interop = 'cstdlib' } interopTest("interop4") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. goldValue = "a b -1 2 3 9223372036854775807 0.1 0.2 1 0\n1 42\n" source = "interop/basics/4.kt" interop = 'cstdio' } standaloneTest("interop5") { dependsOnPlatformLibs(it) enabled = (project.testTarget != 'wasm32') // No interop for wasm yet. goldValue = "Hello!\n" source = "interop/basics/5.kt" } interopTest("interop_bitfields") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. expectedFail = (project.testTarget == 'linux_mips32') // fails because of big-endiannes source = "interop/basics/bf.kt" interop = 'bitfields' } interopTest("interop_funptr") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. goldValue = "42\n17\n1\n0\n42\n42\n" source = "interop/basics/funptr.kt" interop = 'cfunptr' } interopTest("interop_globals") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/globals.kt" interop = 'cglobals' } interopTest("interop_macros") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/macros.kt" interop = 'cmacros' } interopTest("interop_unsupported") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/unsupported.kt" interop = 'cunsupported' } interopTest("interop_toKString") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/toKString.kt" interop = 'ctoKString' } interopTest("interop_types") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/types.kt" interop = 'ctypes' } interopTest("interop_vectors") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/vectors.kt" interop = 'cvectors' } interopTest("interop_vectors_mimalloc") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/vectors.kt" interop = 'cvectors' flags = [ "-Xallocator=mimalloc" ] arguments = [ "mimalloc" ] } interopTest("interop_mangling") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/mangling.kt" interop = 'cmangling' } interopTest("interop_mangling2") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/mangling2.kt" interop = 'cmangling2' } interopTest("interop_mangling_keywords") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/mangling_keywords.kt" interop = 'cmangling_keywords' } interopTest("interop_mangling_keywords2") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/mangling_keywords2.kt" interop = 'cmangling_keywords2' } interopTest("interop_auxiliarySources") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/auxiliary_sources/main.kt" interop = 'auxiliaryCppSources' } interopTest("interop_concurrentTerminate") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/concurrentTerminate/main.kt" interop = 'concurrentTerminate' goldValue = "Reporting error!\n" outputChecker = { str -> str.endsWith(goldValue) } expectedExitStatus = 99 } interopTest("interop_incompleteTypes") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/incomplete_types/main.kt" interop = 'incomplete_types' } interopTest("interop_embedStaticLibraries") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/embedStaticLibraries/main.kt" interop = 'embedStaticLibraries' } interopTest("interop_values") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/values.kt" interop = 'cvalues' } interopTest("interop_structs") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/structs.kt" interop = 'cstructs' } interopTest("interop_callbacksAndVarargs") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. source = "interop/basics/callbacksAndVarargs.kt" interop = 'ccallbacksAndVarargs' } interopTest("interop_withSpaces") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. interop ='withSpaces' source = "interop/basics/withSpaces.kt" doLast { assert file("${buildDir}/cutom map.map").exists() } } interopTest("interop_union") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. interop = 'cunion' source = "interop/basics/union.kt" } interopTest("interop_enums") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. interop = 'cenums' source = "interop/basics/enums.kt" } interopTest("interop_array_pointers") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. interop = 'carrayPointers' source = "interop/basics/arrayPointers.kt" } interopTest("interop_kt43265") { disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. interop = 'kt43265' source = "interop/kt43265/usage.kt" } dynamicTest("interop_kt43502") { disabled = (project.target.name != project.hostName) interop = "kt43502" source = "interop/kt43502/main.kt" cSource = "$projectDir/interop/kt43502/main.c" goldValue = "null\n" } interopTest("interop_leakMemoryWithRunningThreadUnchecked") { disabled = (project.testTarget == 'wasm32') || // No interop for wasm yet. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. interop = 'leakMemoryWithRunningThread' source = "interop/leakMemoryWithRunningThread/unchecked.kt" } interopTest("interop_leakMemoryWithRunningThreadChecked") { disabled = (project.testTarget == 'wasm32') || // No interop for wasm yet. isExperimentalMM // Experimental MM doesn't support multiple mutators yet. interop = 'leakMemoryWithRunningThread' source = "interop/leakMemoryWithRunningThread/checked.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Cannot run checkers when there are 1 alive runtimes at the shutdown") } } standaloneTest("interop_pinning") { disabled = (project.testTarget == 'wasm32') // Uses exceptions. source = "interop/basics/pinning.kt" flags = [ "-tr" ] } task interop_convert(type: KonanLocalTest) { source = "codegen/intrinsics/interop_convert.kt" } task interop_sourceCodeStruct(type: KonanLocalTest) { source = "codegen/intrinsics/interop_sourceCodeStruct.kt" } /* TODO: This test isn't run automatically task interop_echo_server(type: RunInteropKonanTest) { disabled = isWasmTarget(project) || isWindowsTarget(project) run = false source = "interop/basics/echo_server.kt" interop = 'sockets' } */ /* TODO: This test isn't run automatically standaloneTest("interop_opengl_teapot") { enabled = isAppleTarget(project) && project.testTarget != 'ios_x64' // No GLUT in iOS dependsOnPlatformLibs(it as Task) run = false source = "interop/basics/opengl_teapot.kt" } */ if (PlatformInfo.isAppleTarget(project)) { interopTest("interop_objc_smoke") { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. goldValue = "84\nFoo\nDeallocated\n" + "Hello, World!\nKotlin says: Hello, everybody!\nHello from Kotlin\n2, 1\n" + "true\ntrue\n" + "Global string\nAnother global string\nnull\nglobal object\n" + "5\n" + "String macro\n" + "CFString macro\n" + "Deallocated\nDeallocated\n" + "Class TestExportObjCClass34 has multiple implementations. Which one will be used is undefined.\n" source = "interop/objc/smoke.kt" interop = 'objcSmoke' doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/smoke.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcsmoke.dylib" // Enable ARC optimizations to prevent some objects from leaking in Obj-C code due to exceptions: args '-O2' } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcsmoke.dylib") } copy { from("interop/objc/Localizable.stringsdict") into("$testOutputLocal/$name/$target/en.lproj/") } } } interopTestMultifile("interop_objc_tests") { enabled = !isExperimentalMM // Experimental MM does not have a GC yet. source = "interop/objc/tests/" interop = 'objcTests' flags = ['-tr', '-e', 'main'] doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args fileTree("$projectDir/interop/objc/tests/") { include '**/*.m' } args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjctests.dylib" // Enable ARC optimizations to prevent some objects from leaking in Obj-C code due to exceptions: args '-O2' } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjctests.dylib") } } } interopTest("interop_objc_global_initializer") { goldValue = "OK\n" source = "interop/objc_with_initializer/objc_test.kt" interop = 'objcMisc' doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc_with_initializer/objc_misc.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcmisc.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcmisc.dylib") } } } interopTest("interop_objc_msg_send") { source = "interop/objc/msg_send/main.kt" interop = 'objcMessaging' doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/msg_send/messaging.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcmessaging.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcmessaging.dylib") } } } interopTest("interop_objc_foreignException") { source = "interop/objc/foreignException/objc_wrap.kt" interop = 'foreignException' dependsOnPlatformLibs(it) doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/foreignException/objc_wrap.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcexception.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcexception.dylib") } } } interopTest("interop_objc_foreignExceptionMode_wrap") { source = "interop/objc/foreignException/objcExceptionMode.kt" interop = 'foreignExceptionMode_wrap' goldValue = "OK: ForeignException\n" dependsOnPlatformLibs(it) doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/foreignException/objc_wrap.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcexception.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcexception.dylib") } } } interopTest("interop_objc_foreignExceptionMode_default") { source = "interop/objc/foreignException/objcExceptionMode.kt" interop = 'foreignExceptionMode_default' goldValue = "OK: Ends with uncaught exception handler\n" dependsOnPlatformLibs(it) doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/foreignException/objc_wrap.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjcexception.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjcexception.dylib") } } } interopTest("interop_objc_kt34467") { source = "interop/objc/kt34467/foo.kt" interop = 'objcKt34467' goldValue = "OK\n42\n" } interopTest("interop_objc_illegal_sharing_with_weak") { enabled = !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "interop/objc/illegal_sharing_with_weak/main.kt" interop = 'objc_illegal_sharing_with_weak' expectedExitStatusChecker = { it != 0 } outputChecker = { it.startsWith("Before") && // Should crash after "Before" !it.contains("After") && // But before "After" it.contains("isObjectAliveShouldCrash") // And should contain stack trace. } } interopTest("interop_objc_kt42172") { enabled = !isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "interop/objc/kt42172/main.kt" interop = "objc_kt42172" flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] goldValue = 'Executed finalizer\n' doBeforeBuild { mkdir(buildDir) execKonanClang(project.target) { args "$projectDir/interop/objc/kt42172/objclib.m" args "-lobjc", '-fobjc-arc' args '-fPIC', '-shared', '-o', "$buildDir/libobjc_kt42172.dylib" } if (project.target instanceof KonanTarget.IOS_X64) { UtilsKt.codesign(project, "$buildDir/libobjc_kt42172.dylib") } } } } standaloneTest("jsinterop_math") { doBeforeBuild { def jsinteropScript = isWindows() ? "jsinterop.bat" : "jsinterop" def jsinterop = "$dist/bin/$jsinteropScript" // TODO: We probably need a NativeInteropPlugin for jsinterop? "$jsinterop -pkg kotlinx.interop.wasm.math -o $buildDir/jsmath -target wasm32".execute().waitFor() } dependsOn ':wasm32PlatformLibs' enabled = (project.testTarget == 'wasm32') goldValue = "e = 2.718281828459045, pi = 3.141592653589793, sin(pi) = 1.2246467991473532E-16, sin(pi/2) = 1.0, ln(1) = 0.0, ln(e) = 1.0\n" source = "jsinterop/math.kt" flags = ["-r", "$buildDir", "-l", "jsmath"] } standaloneTest("interop_libiconv") { dependsOnPlatformLibs(it) enabled = (project.testTarget == null) source = "interop/libiconv.kt" goldValue = "72 72\n101 101\n108 108\n108 108\n111 111\n33 33\n" } standaloneTest("interop_zlib") { dependsOnPlatformLibs(it) enabled = (project.testTarget == null) source = "interop/platform_zlib.kt" goldValue = "Hello!\nHello!\n" } standaloneTest("interop_objc_illegal_sharing") { dependsOnPlatformLibs(it) disabled = !isAppleTarget(project) || isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "interop/objc/illegal_sharing.kt" expectedExitStatusChecker = { it != 0 } outputChecker = { it.startsWith("Before") && !it.contains("After") } } dynamicTest("produce_dynamic") { disabled = (project.target.name != project.hostName) source = "produce_dynamic/simple/hello.kt" cSource = "$projectDir/produce_dynamic/simple/main.c" goldValue = "Hello, dynamic!\n" + "Base.foo\n" + "Base.fooParam: a 1 q\n" + "Child.fooParam: b 2 null\n" + "Child.fooParam: c 3 null\n" + "Impl1.I: d 4 Impl1\n" + "Impl2.I: e 5 Impl2\n" + "String is Kotlin/Native nullable is Hi null is OK\n" + "RO property is 42\n" + "RW property is 239\n" + "enum100 = 100\n" + "enum42 = 42\n" + "object = 42\n" + "singleton = I am single\n" + "mutable = foo\n" + "topLevel = 777 3\n" + "IsInstance1 = PASS\n" + "IsInstance2 = PASS\n" + "getVector128 = (1, 2, 3, 4)\n" + "Error handler: kotlin.Error: Expected error\n" } dynamicTest("kt36639") { disabled = (project.target.name != project.hostName) source = "produce_dynamic/kt-36639/main.kt" cSource = "$projectDir/produce_dynamic/kt-36639/main.c" goldValue = """|CFoo1::extfoo |CFoo1::extfoo |CFoo2::extfoo |CFoo2::extfoo |Int::extfoo |Int::extfoo |""".stripMargin() } dynamicTest("interop_concurrentRuntime") { disabled = (project.target.name != project.hostName) disabled = true // KT-43180 source = "interop/concurrentTerminate/reverseInterop.kt" cSource = "$projectDir/interop/concurrentTerminate/main.cpp" clangTool = "clang++" goldValue = "Uncaught Kotlin exception: kotlin.RuntimeException: Example" outputChecker = { str -> str.startsWith(goldValue) } expectedExitStatus = 99 } dynamicTest("interop_kt42397") { disabled = project.target.name != project.hostName source = "interop/kt42397/knlibrary.kt" cSource = "$projectDir/interop/kt42397/test.cpp" clangTool = "clang++" } dynamicTest("interop_cleaners_main_thread") { disabled = (project.target.name != project.hostName) || isExperimentalMM // Experimental MM does not have a GC yet. source = "interop/cleaners/cleaners.kt" cSource = "$projectDir/interop/cleaners/main_thread.cpp" clangTool = "clang++" goldValue = "42\n" flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } dynamicTest("interop_cleaners_second_thread") { disabled = (project.target.name != project.hostName) || isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "interop/cleaners/cleaners.kt" cSource = "$projectDir/interop/cleaners/second_thread.cpp" clangTool = "clang++" goldValue = "42\n" flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } dynamicTest("interop_cleaners_leak") { disabled = (project.target.name != project.hostName) source = "interop/cleaners/cleaners.kt" cSource = "$projectDir/interop/cleaners/leak.cpp" clangTool = "clang++" goldValue = "" flags = ['-Xopt-in=kotlin.native.internal.InternalForKotlinNative'] } dynamicTest("interop_migrating_main_thread_legacy") { disabled = (project.target.name != project.hostName) || isExperimentalMM // Experimental MM will not support legacy destroy runtime mode. source = "interop/migrating_main_thread/lib.kt" flags = ['-Xdestroy-runtime-mode=legacy'] clangFlags = ['-DIS_LEGACY'] cSource = "$projectDir/interop/migrating_main_thread/main.cpp" clangTool = "clang++" } dynamicTest("interop_migrating_main_thread") { disabled = (project.target.name != project.hostName) || isExperimentalMM // Experimental MM doesn't support multiple mutators yet. source = "interop/migrating_main_thread/lib.kt" flags = ['-Xdestroy-runtime-mode=on-shutdown'] cSource = "$projectDir/interop/migrating_main_thread/main.cpp" clangTool = "clang++" } dynamicTest("interop_memory_leaks") { disabled = (project.target.name != project.hostName) || isExperimentalMM // Experimental MM will not support legacy destroy runtime mode. source = "interop/memory_leaks/lib.kt" cSource = "$projectDir/interop/memory_leaks/main.cpp" clangTool = "clang++" flags = ['-Xdestroy-runtime-mode=legacy'] // Runtime cannot be destroyed with interop with on-shutdown. expectedExitStatusChecker = { it != 0 } outputChecker = { s -> s.contains("Memory leaks detected, 1 objects leaked!") } } tasks.register("library_mismatch", KonanDriverTest) { // Does not work for cross targets yet. enabled = !(project.testTarget != null && project.target.name != project.hostName) def dir = buildDir.absolutePath def lib = "$projectDir/link/versioning/empty.kt" def currentTarget = project.target.name def someOtherTarget = (project.testTarget == 'wasm32' ? project.hostName : 'wasm32') if (!useCustomDist) { // we actually need any target other than the current one. dependsOn ':wasm32CrossDistRuntime' dependsOn ':wasm32CrossDistEndorsedLibraries' } doBeforeBuild { konanc("$lib -p library -o $dir/1.2/empty -target $currentTarget -lv 1.2") konanc("$lib -p library -o $dir/3.4/empty -target $someOtherTarget") konanc("$lib -p library -o $dir/5.6/empty -target $currentTarget -lv 5.6") konanc("$lib -p library -o $dir/7.8/empty -target $currentTarget -lv 7.8") } source = "link/versioning/hello.kt" flags = ['-l', 'empty@5.6', '-r', "$dir/1.2", '-r', "$dir/3.4", '-r', "$dir/5.6"] compilerMessages = true def messages = "warning: skipping $dir/1.2/empty.klib. The library versions don't match. Expected '5.6', found '1.2'\n" + "warning: skipping $dir/3.4/empty.klib. The target doesn't match. Expected '$currentTarget', found [$someOtherTarget]\n" + "Hello, versioned world!\n" goldValue = PlatformInfo.isWindows() ? messages.replaceAll('\\/', '\\\\') : messages outputChecker = { out -> goldValue.split("\n") .collect { line -> out.contains(line) } .every { it == true } } } tasks.register("library_ir_provider_mismatch", KonanDriverTest) { def dir = buildDir.absolutePath def lib = "$projectDir/link/ir_providers/library/empty.kt" def invalidManifest = "$projectDir/link/ir_providers/library/manifest.properties" def currentTarget = project.target.name doBeforeBuild { konanc("$lib -p library -o $dir/supported_ir_provider/empty -target $currentTarget") konanc("$lib -p library -o $dir/unsupported_ir_provider/empty -manifest $invalidManifest -target $currentTarget") } source = "link/ir_providers/hello.kt" flags = ['-target', currentTarget, '-l', 'empty', '-r', "$dir/unsupported_ir_provider", '-r', "$dir/supported_ir_provider"] compilerMessages = true def messages = "warning: skipping $dir/unsupported_ir_provider/empty.klib. The library requires unknown IR provider UNSUPPORTED.\n" + "hello\n" goldValue = PlatformInfo.isWindows() ? messages.replaceAll('\\/', '\\\\') : messages outputChecker = { out -> goldValue.split("\n") .collect { line -> out.contains(line) } .every { it == true } } } standaloneTest("fake_override_0") { def sources = "$projectDir/link/fake_overrides" def dir = buildDir.absolutePath doBeforeBuild { konanc("$sources/base.kt -p library -target ${target.name} -o $dir/base") konanc("$sources/move.kt -p library -target ${target.name} -o $dir/move -r $dir -l base") konanc("$sources/use.kt -p library -target ${target.name} -o $dir/use -r $dir -l move") konanc("$sources/move2.kt -p library -target ${target.name} -o $dir/move -r $dir -l base") } source = "$sources/main.kt" flags = ["-l", "use", "-r", "$dir"] goldValue = "Moved\nMoved\nChild\nSuper\n" } linkTest("private_fake_overrides_0") { source = "link/private_fake_overrides/inherit_main.kt" lib = "link/private_fake_overrides/inherit_lib.kt" goldValue = "PASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\n" } linkTest("private_fake_overrides_1") { source = "link/private_fake_overrides/override_main.kt" lib = "link/private_fake_overrides/override_lib.kt" goldValue = "PASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\nPASS\n" } Task frameworkTest(String name, Closure configurator) { return KotlinNativeTestKt.createTest(project, name, FrameworkTest) { task -> configurator.delegate = task configurator() if (task.enabled) { konanArtifacts { task.frameworks.forEach { fr -> framework(fr.name, targets: [target.name]) { fr.sources.forEach { src -> srcFiles src } baseDir "$testOutputFramework/${task.name}" if (fr.library != null) { dependsOn konanArtifacts[fr.library].getByTarget(target.name) libraries { file konanArtifacts[fr.library].getArtifactByTarget(target.name) } linkerOpts "-L$buildDir" UtilsKt.dependsOnKonanBuildingTask(task, fr.library, target) } if (!useCustomDist) { dependsOn ":${target.name}CrossDistRuntime", ':distCompiler' } extraOpts fr.bitcode ? "-Xembed-bitcode" : "-Xembed-bitcode-marker" if (fr.isStatic) extraOpts "-Xstatic-framework" extraOpts fr.opts extraOpts project.globalTestArgs artifactName fr.artifact } } } } } } if (isAppleTarget(project)) { frameworkTest('testObjCExport') { enabled = !isExperimentalMM // Experimental MM doesn't support ObjC blocks yet. final String frameworkName = 'Kt' final String dir = "$testOutputFramework/testObjCExport" final File lazyHeader = file("$dir/$target-lazy.h") doLast { final String expectedLazyHeaderName = "expectedLazy.h" final String expectedLazyHeaderDir = file("objcexport/") final File expectedLazyHeader = new File(expectedLazyHeaderDir, expectedLazyHeaderName) if (expectedLazyHeader.readLines() != lazyHeader.readLines()) { exec { commandLine 'diff', '-u', expectedLazyHeader, lazyHeader ignoreExitValue = true } copy { from(lazyHeader) into(expectedLazyHeaderDir) rename { expectedLazyHeaderName } } throw new Error("$expectedLazyHeader file patched;\nre-run the test and don't forget to commit the patch") } } def libraryName = frameworkName + "Library" konanArtifacts { library(libraryName, targets: [target.name]) { srcDir "objcexport/library" artifactName "test-library" if (!useCustomDist) { dependsOn ":${target.name}CrossDistRuntime", ':distCompiler' } extraOpts "-Xshort-module-name=MyLibrary" extraOpts "-module-name", "org.jetbrains.kotlin.native.test-library" } } framework(frameworkName) { sources = ['objcexport'] library = libraryName opts = ["-Xemit-lazy-objc-header=$lazyHeader"] } swiftSources = ['objcexport'] } frameworkTest('testObjCExportNoGenerics') { enabled = !isExperimentalMM // Experimental MM doesn't support ObjC blocks yet. final String frameworkName = 'KtNoGenerics' final String frameworkArtifactName = 'Kt' final String dir = "$testOutputFramework/testObjCExportNoGenerics" final File lazyHeader = file("$dir/$target-lazy.h") doLast { final String expectedLazyHeaderName = "expectedLazyNoGenerics.h" final String expectedLazyHeaderDir = file("objcexport/") final File expectedLazyHeader = new File(expectedLazyHeaderDir, expectedLazyHeaderName) if (expectedLazyHeader.readLines() != lazyHeader.readLines()) { exec { commandLine 'diff', '-u', expectedLazyHeader, lazyHeader ignoreExitValue = true } copy { from(lazyHeader) into(expectedLazyHeaderDir) rename { expectedLazyHeaderName } } throw new Error("$expectedLazyHeader file patched;\nre-run the test and don't forget to commit the patch") } } def libraryName = frameworkName + "Library" konanArtifacts { library(libraryName, targets: [target.name]) { srcDir "objcexport/library" artifactName "test-library" if (!useCustomDist) { dependsOn ":${target.name}CrossDistRuntime", ':distCompiler' } extraOpts "-Xshort-module-name=MyLibrary" extraOpts "-module-name", "org.jetbrains.kotlin.native.test-library" } } framework(frameworkName) { sources = ['objcexport'] artifact = frameworkArtifactName library = libraryName opts = ["-Xemit-lazy-objc-header=$lazyHeader", "-Xno-objc-generics"] } swiftSources = ['objcexport'] swiftExtraOpts = [ '-D', 'NO_GENERICS' ] } frameworkTest('testObjCExportStatic') { enabled = !isExperimentalMM // Experimental MM doesn't support ObjC blocks yet. final String frameworkName = 'KtStatic' final String frameworkArtifactName = 'Kt' final String libraryName = frameworkName + "Library" konanArtifacts { library(libraryName, targets: [target.name]) { srcDir "objcexport/library" artifactName "test-library" if (!useCustomDist) { dependsOn ":${target.name}CrossDistRuntime", ':distCompiler' } extraOpts "-Xshort-module-name=MyLibrary" extraOpts "-module-name", "org.jetbrains.kotlin.native.test-library" } } codesign = false framework(frameworkName) { sources = ['objcexport'] bitcode = false artifact = frameworkArtifactName library = libraryName isStatic = true } swiftSources = ['objcexport'] } frameworkTest('testValuesGenericsFramework') { framework('ValuesGenerics') { sources = ['objcexport/values.kt', 'framework/values_generics'] } swiftSources = ['framework/values_generics/'] } frameworkTest("testStdlibFramework") { enabled = !isExperimentalMM // Experimental MM does not have GC yet. framework('Stdlib') { sources = ['framework/stdlib'] bitcode = true } if (cacheTesting == null) fullBitcode = true swiftSources = ['framework/stdlib/'] } if (cacheTesting != null && cacheTesting.isDynamic) { // testMultipleFrameworks disabled until https://youtrack.jetbrains.com/issue/KT-34262 is fixed. } else frameworkTest("testMultipleFrameworks") { framework('First') { sources = ['framework/multiple/framework1', 'framework/multiple/shared'] bitcode = true } framework('Second') { sources = ['framework/multiple/framework2', 'framework/multiple/shared'] bitcode = true } swiftSources = ['framework/multiple'] } frameworkTest("testMultipleFrameworksStatic") { if (cacheTesting != null) { // See https://youtrack.jetbrains.com/issue/KT-34261. expectedExitStatus = 134 } framework('FirstStatic') { artifact = 'First' sources = ['framework/multiple/framework1', 'framework/multiple/shared'] bitcode = true isStatic = true opts = ['-Xstatic-framework', "-Xpre-link-caches=enable"] } framework('SecondStatic') { artifact = 'Second' sources = ['framework/multiple/framework2', 'framework/multiple/shared'] bitcode = true isStatic = true opts = ['-Xstatic-framework', "-Xpre-link-caches=enable"] } codesign = false swiftSources = ['framework/multiple'] } frameworkTest("testGh3343Framework") { framework('Gh3343') { sources = ['framework/gh3343'] library = 'objcGh3343' } swiftSources = ['framework/gh3343/'] } frameworkTest("testKt42397Framework") { enabled = !project.globalTestArgs.contains('-opt') framework("Kt42397") { sources = ['framework/kt42397'] } swiftSources = ['framework/kt42397'] } frameworkTest("testKt43517Framework") { framework('Kt43517') { sources = ['framework/kt43517'] library = 'objcKt43517' } swiftSources = ['framework/kt43517/'] } } /** * Creates tasks to build and execute Harmony regex tests with GTEST logger. */ KotlinNativeTestKt.createTest(project, 'harmonyRegexTest', KonanGTest) { task -> task.enabled = (project.testTarget != 'wasm32') // Uses exceptions. task.useFilter = false task.testLogger = KonanTest.Logger.GTEST if (twoStageEnabled) { // Exclude tests with lone surrogates/incorrect surrogate pairs failing due to KT-33175. def excludedTests = [ "test.text.harmony_regex.PatternTest.testCanonEqFlagWithSupplementaryCharacters", "test.text.harmony_regex.PatternTest.testRangesWithSurrogatesSupplementary", "test.text.harmony_regex.PatternTest.testSequencesWithSurrogatesSupplementary", "test.text.harmony_regex.PatternTest.testPredefinedClassesWithSurrogatesSupplementary", "test.text.harmony_regex.PatternTest.testDotConstructionWithSurrogatesSupplementary", "test.text.harmony_regex.PatternTest.testAlternationsWithSurrogatesSupplementary", "test.text.harmony_regex.PatternTest.testGroupsWithSurrogatesSupplementary" ] task.arguments += "--ktest_filter=*-${excludedTests.join(":")}" } def sources = UtilsKt.getFilesToCompile(project, ["harmony_regex"], []) konanArtifacts { program('harmonyRegexTest', targets: [target.name]) { srcFiles sources baseDir "$testOutputStdlib/harmonyRegexTest" extraOpts '-tr' extraOpts project.globalTestArgs } } task.finalizedBy("resultsTask") } if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) { task coverage_basic_program(type: CoverageTest) { binaryName = "CoverageBasic" numberOfCoveredFunctions = 1 numberOfCoveredLines = 3 konanArtifacts { program(binaryName, targets: [ target ]) { srcDir 'coverage/basic/program' baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.program.main" extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile" } } } task coverage_basic_library(type: CoverageTest) { binaryName = "CoverageBasicLibrary" numberOfCoveredFunctions = 1 numberOfCoveredLines = 1 konanArtifacts { library("lib_to_cover", targets: [target.name]) { srcFiles 'coverage/basic/library/library.kt' } program(binaryName, targets: [ target ]) { srcFiles 'coverage/basic/library/main.kt' libraries { artifact konanArtifacts.lib_to_cover } baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.library.main" extraOpts "-Xcoverage-file=$profrawFile", "-Xlibrary-to-cover=${konanArtifacts.lib_to_cover.getArtifactByTarget(target.name)}" } } } task coverage_controlflow(type: CoverageTest) { binaryName = "CoverageControlFlow" numberOfCoveredFunctions = 1 numberOfCoveredLines = 102 konanArtifacts { program(binaryName, targets: [ target ]) { srcDir 'coverage/basic/controlflow' baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.controlflow.main" extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile" } } } task coverage_jumps(type: CoverageTest) { binaryName = "CoverageJumps" numberOfCoveredFunctions = 8 numberOfCoveredLines = 74 konanArtifacts { program(binaryName, targets: [ target ]) { srcDir 'coverage/basic/jumps' baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.jumps.main" extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile" } } } task coverage_smoke0(type: CoverageTest) { binaryName = "CoverageSmoke0" numberOfCoveredFunctions = 2 numberOfCoveredLines = 5 konanArtifacts { program(binaryName, targets: [ target ]) { srcDir 'coverage/basic/smoke0' baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.smoke0.main" extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile" } } } task coverage_smoke1(type: CoverageTest) { binaryName = "CoverageSmoke1" numberOfCoveredFunctions = 9 numberOfCoveredLines = 33 konanArtifacts { program(binaryName, targets: [ target ]) { srcDir 'coverage/basic/smoke1' baseDir "$testOutputCoverage/$binaryName" entryPoint "coverage.basic.smoke1.main" extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile" } } } } tasks.register("metadata_compare_typedefs", MetadataComparisonTest) { UtilsKt.dependsOnDist(it) enabled = (project.testTarget != 'wasm32') defFile = "interop/basics/typedefs.def" } tasks.register("metadata_compare_unable_to_import", MetadataComparisonTest) { UtilsKt.dependsOnDist(it) enabled = (project.testTarget != 'wasm32') defFile = "interop/basics/unable_to_import.def" } standaloneTest("local_ea_arraysfieldwrite") { disabled = (cacheTesting != null) || // Cache is not compatible with -opt. isExperimentalMM // Experimental MM does not support -opt yet. goldValue = "Array (constructor init):\nSize: 2\nContents: [1, 2]\n" + "Array (constructor init):\nSize: 2\nContents: [3, 4]\n" + "Array (default value init):\nSize: 2\nContents: [1, 2]\n" + "Array (default value init):\nSize: 2\nContents: [3, 4]\n" + "Array (init block):\nSize: 2\nContents: [1, 2]\n" + "Array (init block):\nSize: 2\nContents: [3, 4]\n" flags = ["-opt"] source = "codegen/localEscapeAnalysis/arraysFieldWrite.kt" } tasks.register("override_konan_properties0", KonanDriverTest) { def overrides = PlatformInfo.isWindows() ? '-Xoverride-konan-properties="llvmInlineThreshold=76"' : '-Xoverride-konan-properties=llvmInlineThreshold=76' flags = [ "-opt", "-Xverbose-phases=BitcodeOptimization", overrides ] compilerMessages = true source = "link/ir_providers/hello.kt" def messages = "inline_threshold: 76\n" + "hello\n" goldValue = PlatformInfo.isWindows() ? messages.replaceAll('\\/', '\\\\') : messages outputChecker = { out -> goldValue.split("\n") .collect { line -> out.contains(line) } .every { it == true } } } createStdlibTest('stdlibTest', /* inWorker = */ false) createStdlibTest('stdlibTestInWorker', /*inWorker = */ true) /** * Creates tasks to build and execute stdlib tests. */ private void createStdlibTest(String name, boolean inWorker) { KotlinNativeTestKt.createTest(project, name, KonanGTest) { task -> configureStdlibTest(task, inWorker) } } /** * Configures tasks to build and execute stdlib tests. */ private void configureStdlibTest(KonanGTest task, boolean inWorker) { def sources = UtilsKt.getFilesToCompile(project, [ 'build/stdlib_external/stdlib', 'stdlib_external/utils.kt', 'stdlib_external/collections', 'stdlib_external/jsCollectionFactoriesActuals.kt', 'stdlib_external/text'], [ 'build/stdlib_external/stdlib/test/internalAnnotations.kt' ]) konanArtifacts { program(task.name, targets: [target.name]) { srcFiles sources baseDir "$testOutputStdlib/$task.name" enableMultiplatform true extraOpts inWorker ? '-trw' : '-tr', '-Xverify-ir', '-Xopt-in=kotlin.RequiresOptIn,kotlin.ExperimentalStdlibApi', "-friend-modules", project.rootProject.file("${project.properties['konan.home']}/klib/common/stdlib").absolutePath extraOpts project.globalTestArgs } } // Exclude test providing args to the test executable task.arguments = [ "--ktest_negative_regex_filter=test.collections.CollectionTest.abstractCollectionToArray" ] task.useFilter = false task.testLogger = KonanTest.Logger.GTEST task.finalizedBy("resultsTask") task.enabled = (project.testTarget != 'wasm32') && // Uses exceptions (!inWorker || !ext.isExperimentalMM) // Experimental MM doesn't support multiple mutators yet. } /** * Builds tests into a single binary with TestRunner */ task buildKonanTests { t -> def compileList = [ "codegen", "datagen", "lower", "runtime", "serialization" ] // These tests should not be built into the TestRunner's test executable def excludeList = [ "codegen/inline/returnLocalClassFromBlock.kt" ] project.tasks .withType(KonanStandaloneTest.class) .each { // add library and source files if (it instanceof KonanLinkTest) { excludeList += it.lib } if (it.source != null) { excludeList += it.source } } def sources = UtilsKt.getFilesToCompile(project, compileList, excludeList) konanArtifacts { program('localTest', targets: [target.name]) { srcFiles sources baseDir testOutputLocal extraOpts '-tr' extraOpts '-Xverify-ir' extraOpts project.globalTestArgs } } // Set build dependencies. dependsOn compileKonanLocalTest def buildTask = UtilsKt.findKonanBuildTask(project, "localTest", target) UtilsKt.dependsOnDist(buildTask) // Local tests build into a single binary should depend on this task project.tasks .withType(KonanLocalTest.class) .matching { !(it instanceof KonanStandaloneTest) } .configureEach { it.dependsOn(t) } } sourceSets { nopPlugin { kotlin { srcDir 'extensions/nop/src/main/kotlin' } } test { kotlin { srcDir 'debugger/src/test/kotlin' } } } compileNopPluginKotlin { kotlinOptions.freeCompilerArgs += ['-Xskip-prerelease-check'] } Task pluginTest(String name, String pluginName, Closure configureClosure) { def jarTask = project.tasks.register("jar-$pluginName", Jar) { it.dependsOn("compile${pluginName.capitalize()}Kotlin") from { sourceSets[pluginName].output } baseName = pluginName destinationDirectory = buildDir } def taskName = "$name-with-$pluginName" return KotlinNativeTestKt.createTest(project, taskName, KonanStandaloneTest) { task -> task.configure(configureClosure) task.dependsOn(jarTask) if (task.enabled) { konanArtifacts { program(taskName, targets: [target.name]) { baseDir "$testOutputLocal/$taskName" srcFiles task.getSources() extraOpts task.flags + "-Xplugin=$buildDir/nop-plugin.jar" extraOpts project.globalTestArgs } } } } } pluginTest("runtime_basic_init", "nopPlugin") { disabled = (project.testTarget == 'wasm32') source = "runtime/basic/hello3.kt" flags = ["-tr"] } dependencies { nopPluginCompile kotlinCompilerModule compile kotlinCompilerModule compile project(path: ':backend.native', configuration: 'cli_bc') compile 'junit:junit:4.12' } project.tasks.named("test").configure { // Don't run this task as it will try to execute debugger tests too // that is not desired as they are platform-specific. enabled = false } project.tasks.register("debugger_test", Test.class) { enabled = (target.family == Family.OSX) // KT-30366 testLogging { exceptionFormat = 'full' } UtilsKt.dependsOnDist(it) systemProperties = ['kotlin.native.home': dist] } // Configure build for iOS device targets. if (target.family == Family.IOS && (target.architecture == ARM32 || target.architecture == ARM64)) { project.tasks .withType(KonanTestExecutable.class) .configureEach { ExecutorServiceKt.configureXcodeBuild((KonanTestExecutable) it) } // Exclude tasks that cannot be run on device project.tasks .withType(KonanTest.class) .matching { (it instanceof KonanLocalTest && ((KonanLocalTest) it).testData != null) || // Filter out tests that depend on libs. TODO: copy them too it instanceof KonanInteropTest || it instanceof KonanDynamicTest || it instanceof KonanLinkTest } .configureEach { it.enabled = false } } ================================================ FILE: backend.native/tests/codegen/annotations/annotations0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // FILE: 1.kt package codegen.annotations.annotations0 import kotlin.test.* import kotlinx.serialization.* @SerialInfo annotation class Foo(val x: Int, val y: String) @Test fun runTest() { val foo = @Suppress("ANNOTATION_CLASS_CONSTRUCTOR_CALL") Foo(42, "17") assertEquals(foo.x, 42) assertEquals(foo.y, "17") } // FILE: 2.kt package kotlinx.serialization @Target(AnnotationTarget.ANNOTATION_CLASS) annotation class SerialInfo ================================================ FILE: backend.native/tests/codegen/arithmetic/basic.kt ================================================ package codegen.arithmetic.basic import kotlin.test.* // Check that compiler doesn't optimize it to `true` fun selfCmp1(x: Int) = x + 1 > x fun selfCmp2(x: Int) = x - 1 < x @Test fun selfComparison() { assertFalse(selfCmp1(Int.MAX_VALUE)) assertFalse(selfCmp2(Int.MIN_VALUE)) } private fun charCornersMinus(): Int { val a: Char = 0xFFFF.toChar() val b: Char = 0.toChar() return a - b } private fun charCornersComparison(): Boolean { val a = 0xFFFF.toChar() val b = 0.toChar() return a < b } @Test fun charCornerCases() { assertEquals(65535, charCornersMinus()) assertFalse(charCornersComparison()) } @Test fun shifts() { assertEquals(-2147483648, 1 shl -1) assertEquals(0, 1 shr -1) assertEquals(1, 1 shl 32) assertEquals(1073741823, -1 ushr 2) assertEquals(-1, -1 shr 2) } @Test @kotlin.ExperimentalUnsignedTypes fun uintTests() { assertEquals(UInt.MAX_VALUE, UInt.MIN_VALUE - 1u) } @Test fun charConversions() { assertEquals(97.0, 'a'.toDouble()) assertEquals(-1, Char.MAX_VALUE.toShort()) assertEquals(32768, Short.MIN_VALUE.toChar().toInt()) assertEquals(-1, Char.MAX_VALUE.toByte()) assertEquals(65408, Byte.MIN_VALUE.toChar().toInt()) assertEquals(0, Float.MIN_VALUE.toChar().toInt()) } @Test fun doubleBasic() { assertEquals(1, 0f.compareTo(-0f)) assertEquals(1, 0.0.compareTo(-0.0)) assertEquals(1.0, Double.fromBits(1.0.toBits())) assertEquals(1.0f, Float.fromBits(1.0f.toBits())) assertEquals(Double.NaN, Double.fromBits((0 / 0.0).toBits())) assertEquals(Float.NaN, Float.fromBits((0 / 0f).toBits())) } @Test fun integralToFloat() { assertEquals(9.223372E18f, Long.MAX_VALUE.toFloat()) assertEquals(-9.223372E18f, Long.MIN_VALUE.toFloat()) assertEquals(-2.147483648E9, Int.MIN_VALUE.toDouble()) assertEquals(2.147483647E9, Int.MAX_VALUE.toDouble()) assertEquals(2147483647, Double.MAX_VALUE.toInt()) assertEquals(0, Float.MIN_VALUE.toLong()) assertEquals(9223372036854775807, Float.MAX_VALUE.toLong()) assertEquals(0, Double.MIN_VALUE.toInt()) } @Test fun compareIntToFloat() { assertEquals(1, 0.compareTo(-0.0f)) assertEquals(0, 0.compareTo(+0.0f)) } @Test fun testKt37412() { val two = 2.0 assertEquals(2, two.toInt()) } ================================================ FILE: backend.native/tests/codegen/arithmetic/division.kt ================================================ package codegen.arithmetic.division import kotlin.test.* @Test fun divisionByZero() { assertFailsWith(ArithmeticException::class, { 5 / 0 }) assertFailsWith(ArithmeticException::class, { 5 % 0 }) assertEquals(1, 5 / try { 0 / 0; 1 } catch (e: ArithmeticException) { 5 }) assertEquals(Double.NaN, 0.0 / 0.0) } ================================================ FILE: backend.native/tests/codegen/arithmetic/github1856.kt ================================================ package codegen.arithmetic.github1856 import kotlin.test.* object RGBA { fun packFast(r: Int, g: Int, b: Int, a: Int) = (r shl 0) or (g shl 8) or (b shl 16) or (a shl 24) fun getFastR(v: Int): Int = (v ushr 0) and 0xFF fun getFastG(v: Int): Int = (v ushr 8) and 0xFF fun getFastB(v: Int): Int = (v ushr 16) and 0xFF fun getFastA(v: Int): Int = (v ushr 24) and 0xFF fun premultiplyFastInt(v: Int): Int { val A = getFastA(v) + 1 val RB = (((v and 0x00FF00FF) * A) ushr 8) and 0x00FF00FF val G = (((v and 0x0000FF00) * A) ushr 8) and 0x0000FF00 return (v and 0x00FFFFFF.inv()) or RB or G } } @Test fun main() { val source = listOf(0xFFFFFFFF.toInt(), 0xFFFFFF77.toInt(), 0x777777FF.toInt(), 0x77777777.toInt()) val expect = listOf(-1, -137, 2000107383, 2000107319) assertEquals(expect, source.map { RGBA.premultiplyFastInt(it) }) } ================================================ FILE: backend.native/tests/codegen/associatedObjects/associatedObjects1.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.associatedObjects.associatedObjects1 import kotlin.test.* import kotlin.reflect.* @Test @OptIn(ExperimentalAssociatedObjects::class) fun testBasics1() { assertSame(Bar, Foo::class.findAssociatedObject()) assertSame(Baz, Foo::class.findAssociatedObject()) assertSame(null, Foo::class.findAssociatedObject()) assertSame(null, Bar::class.findAssociatedObject()) } @OptIn(ExperimentalAssociatedObjects::class) @AssociatedObjectKey @Retention(AnnotationRetention.BINARY) annotation class Associated1(val kClass: KClass<*>) @OptIn(ExperimentalAssociatedObjects::class) @AssociatedObjectKey @Retention(AnnotationRetention.BINARY) annotation class Associated2(val kClass: KClass<*>) @OptIn(ExperimentalAssociatedObjects::class) @AssociatedObjectKey @Retention(AnnotationRetention.BINARY) annotation class Associated3(val kClass: KClass<*>) @Associated1(Bar::class) @Associated2(Baz::class) class Foo object Bar object Baz @Test @OptIn(ExperimentalAssociatedObjects::class) fun testGlobalOptimizations1() { val i1 = I1ImplHolder::class.findAssociatedObject()!! as I1 assertEquals(42, i1.foo()) val c = C(null) i1.bar(c) assertEquals("zzz", c.list!![0]) } private class C(var list: List?) private interface I1 { fun foo(): Int fun bar(c: C) } private object I1Impl : I1 { override fun foo() = 42 override fun bar(c: C) { c.list = mutableListOf("zzz") } } @Associated1(I1Impl::class) private class I1ImplHolder @Test @OptIn(ExperimentalAssociatedObjects::class) fun testGlobalOptimizations2() { val i2 = I2ImplHolder()::class.findAssociatedObject()!! as I2 assertEquals(17, i2.foo()) } private interface I2 { fun foo(): Int } private object I2Impl : I2 { override fun foo() = 17 } @Associated1(I2Impl::class) private class I2ImplHolder ================================================ FILE: backend.native/tests/codegen/basics/array_to_any.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.array_to_any import kotlin.test.* @Test fun runTest() { foo().hashCode() } fun foo(): Any { return Array(0, { i -> null }) } ================================================ FILE: backend.native/tests/codegen/basics/canonical_name.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.canonical_name import kotlin.test.* interface I { fun foo(a: U): T fun qux(a: T): U } //-----------------------------------------------------------------------------// class A1 class A2 //-----------------------------------------------------------------------------// class A : I { override fun foo(a: A1): A2 { println("A:foo"); return A2() } override fun qux(a: A2): A1 { println("A:qux"); return A1() } } //-----------------------------------------------------------------------------// fun baz(i: I, u: U, v:V) { i.foo(u) i.qux(v) } //-----------------------------------------------------------------------------// @Test fun runTest() { baz(A(), A1(), A2()) } ================================================ FILE: backend.native/tests/codegen/basics/cast_null.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.cast_null import kotlin.test.* @Test fun runTest() { testCast(null, false) testCastToNullable(null, true) testCastToNullable(TestKlass(), true) testCastToNullable("", false) testCastNotNullableToNullable(TestKlass(), true) testCastNotNullableToNullable("", false) println("Ok") } class TestKlass fun ensure(b: Boolean) { if (!b) { println("Error") } } fun testCast(x: Any?, expectSuccess: Boolean) { try { x as TestKlass } catch (e: Throwable) { ensure(!expectSuccess) return } ensure(expectSuccess) } fun testCastToNullable(x: Any?, expectSuccess: Boolean) { try { x as TestKlass? } catch (e: Throwable) { ensure(!expectSuccess) return } ensure(expectSuccess) } fun testCastNotNullableToNullable(x: Any, expectSuccess: Boolean) { try { x as TestKlass? } catch (e: Throwable) { ensure(!expectSuccess) return } ensure(expectSuccess) } ================================================ FILE: backend.native/tests/codegen/basics/cast_simple.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.cast_simple import kotlin.test.* open class A() {} class B(): A() {} fun castSimple(o: Any) : A = o as A fun castTest(): Boolean { val b = B() castSimple(b) return true } @Test fun runTest() { if (!castTest()) throw Error() } ================================================ FILE: backend.native/tests/codegen/basics/check_type.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.check_type import kotlin.test.* interface I class A() : I {} class B() {} //-----------------------------------------------------------------------------// fun isTypeOf(a: Any?) : Boolean { return a is A } //-----------------------------------------------------------------------------// fun isTypeNullableOf(a: Any?) : Boolean { return a is A? } //-----------------------------------------------------------------------------// fun isNotTypeOf(a: Any) : Boolean { return a !is A } //-----------------------------------------------------------------------------// fun isTypeOfInterface(a: Any) : Boolean { return a is I } //-----------------------------------------------------------------------------// @Test fun runTest() { println(isTypeOf(A())) println(isTypeOf(null)) println(isTypeNullableOf(A())) println(isTypeNullableOf(null)) println(isNotTypeOf(B())) println(isTypeOfInterface(A())) } ================================================ FILE: backend.native/tests/codegen/basics/companion.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ class A { companion object { fun foo() = "comp" } } ================================================ FILE: backend.native/tests/codegen/basics/concatenation.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.concatenation import kotlin.test.* @Test fun runTest() { val s = "world" val i = 1 println("Hello $s $i ${2*i}") for (item in listOf("a", "b")) { println("Hello, $item") } } ================================================ FILE: backend.native/tests/codegen/basics/const_infinity.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.const_infinity import kotlin.test.* //Original issue here https://youtrack.jetbrains.com/issue/KT-37212 @Suppress("DIVISION_BY_ZERO") const val fpInfConst = 1.0F / 0.0F @Suppress("DIVISION_BY_ZERO") val fpInfVal = 1.0F / 0.0F @Test fun runTest() { assertEquals(fpInfConst, Float.POSITIVE_INFINITY) assertEquals(fpInfVal, Float.POSITIVE_INFINITY) assertEquals(fpInfConst, fpInfVal) } ================================================ FILE: backend.native/tests/codegen/basics/expression_as_statement.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.expression_as_statement import kotlin.test.* fun foo() { Any() as String } @Test fun runTest() { try { foo() } catch (e: Throwable) { println("Ok") return } println("Fail") } ================================================ FILE: backend.native/tests/codegen/basics/k42000_1.kt ================================================ package codegen.basics.k42000_1 import kotlin.test.* @Test fun runTest() { assertTrue(Reproducer().repro() > 0) } // Based on https://youtrack.jetbrains.com/issue/KT-42000#focus=Comments-27-4404934.0-0 val Int.isEven get() = this % 2 == 0 inline operator fun T.plus(other: T): T = when (T::class) { Double::class -> (this as Double) + (other as Double) Int::class -> (this as Int) + (other as Int) Long::class -> (this as Long) + (other as Long) else -> TODO() } as T inline fun Collection.median(): Double { val sorted = this.sortedBy { it.toDouble() } return if (size.isEven || size == 1) { sorted[size / 2] } else { sorted[size / 2] + sorted[size / 2 + 1] }.toDouble() } class Reproducer { private var someListOfLongs = mutableListOf(1L) fun repro() = someListOfLongs.median() } ================================================ FILE: backend.native/tests/codegen/basics/k42000_2.kt ================================================ package codegen.basics.k42000_2 import kotlin.test.* // https://youtrack.jetbrains.com/issue/KT-42000 @Test fun runTest() { assertFailsWith { when (1) { else -> throw Error() } as String } } ================================================ FILE: backend.native/tests/codegen/basics/local_variable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.local_variable import kotlin.test.* fun local_variable(a: Int) : Int { var b = 0 b = a + 11 return b } @Test fun runTest() { if (local_variable(3) != 14) throw Error() } ================================================ FILE: backend.native/tests/codegen/basics/null_check.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.null_check import kotlin.test.* //--- Test "eqeq" -------------------------------------------------------------// fun check_eqeq(a: Any?) = a == null fun null_check_eqeq1() : Boolean { return check_eqeq(Any()) } fun null_check_eqeq2() : Boolean { return check_eqeq(null) } //--- Test "eqeqeq" -----------------------------------------------------------// fun check_eqeqeq(a: Any?) = a === null fun null_check_eqeqeq1() : Boolean { return check_eqeqeq(Any()) } fun null_check_eqeqeq2() : Boolean { return check_eqeqeq(null) } @Test fun runTest() { if (null_check_eqeq1()) throw Error() if (!null_check_eqeq2()) throw Error() if (null_check_eqeqeq1()) throw Error() if (!null_check_eqeqeq2()) throw Error() } ================================================ FILE: backend.native/tests/codegen/basics/safe_cast.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.safe_cast import kotlin.test.* open class A class B : A() class C fun foo(a: Any) : A? = a as? A fun safe_cast_positive(): Boolean { val b = B() return foo(b) === b } fun safe_cast_negative(): Boolean { val c = C() return foo(c) == null } @Test fun runTest() { val safeCastPositive = safe_cast_positive().toString() val safeCastNegative = safe_cast_negative().toString() println("safe_cast_positive: " + safeCastPositive) println("safe_cast_negative: " + safeCastNegative) } ================================================ FILE: backend.native/tests/codegen/basics/spread_operator_0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.spread_operator_0 import kotlin.test.* @Test fun runTest() { val list0 = _arrayOf("K", "o", "t", "l", "i", "n") val list1 = _arrayOf("l", "a","n", "g", "u", "a", "g", "e") val list = foo(list0, list1) println(list.toString()) } fun foo(a:Array, b:Array) = listOf(*a," ", "i", "s", " ", "c", "o", "o", "l", " ", *b) fun _arrayOf(vararg arg:String) = arg ================================================ FILE: backend.native/tests/codegen/basics/superFunCall.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.superFunCall import kotlin.test.* open class C { open fun f() = "" } class C1: C() { override fun f() = super.f() + "" } open class C2: C() { } class C3: C2() { override fun f() = super.f() + "" } @Test fun runTest() { println(C1().f()) println(C3().f()) } ================================================ FILE: backend.native/tests/codegen/basics/superGetterCall.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.superGetterCall import kotlin.test.* open class C { open val p1 = "" } class C1: C() { override val p1 = super.p1 + "" } open class C2: C() { } class C3: C2() { override val p1 = super.p1 + "" } @Test fun runTest() { println(C1().p1) println(C3().p1) } ================================================ FILE: backend.native/tests/codegen/basics/superSetterCall.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.superSetterCall import kotlin.test.* open class C { open var p2 = "" set(value) { field = "" + value } } class C1: C() { override var p2 = super.p2 + "" set(value) { super.p2 = value field = "" + super.p2 } } open class C2: C() { } class C3: C2() { override var p2 = super.p2 + "" set(value) { super.p2 = value field = "" + super.p2 } } @Test fun runTest() { val c1 = C1() val c3 = C3() c1.p2 = "zzz" c3.p2 = "zzz" println(c1.p2) println(c3.p2) } ================================================ FILE: backend.native/tests/codegen/basics/typealias1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.typealias1 import kotlin.test.* @Test fun runTest() { println(Bar(42).x) } class Foo(val x: Int) typealias Bar = Foo ================================================ FILE: backend.native/tests/codegen/basics/unchecked_cast1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unchecked_cast1 import kotlin.test.* @Test fun runTest() { foo("17") bar("17") foo(42) bar(42) } fun foo(x: Any?) { val y = x as T println(y.toString()) } fun bar(x: Any?) { val y = x as? T println(y.toString()) } ================================================ FILE: backend.native/tests/codegen/basics/unchecked_cast2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unchecked_cast2 import kotlin.test.* @Test fun runTest() { try { val x = cast(Any()) println(x.length) } catch (e: Throwable) { println("Ok") } } fun cast(x: Any?) = x as T ================================================ FILE: backend.native/tests/codegen/basics/unchecked_cast3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unchecked_cast3 import kotlin.test.* @Test fun runTest() { testCast(TestKlass(), true) testCast(null, false) testCastToNullable(null, true) println("Ok") } class TestKlass fun ensure(b: Boolean) { if (!b) { println("Error") } } fun testCast(x: Any?, expectSuccess: Boolean) { try { x as T } catch (e: Throwable) { ensure(!expectSuccess) return } ensure(expectSuccess) } fun testCastToNullable(x: Any?, expectSuccess: Boolean) { try { x as T? } catch (e: Throwable) { ensure(!expectSuccess) return } ensure(expectSuccess) } ================================================ FILE: backend.native/tests/codegen/basics/unchecked_cast4.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unchecked_cast4 import kotlin.test.* @Test fun runTest() { CI1I2().uncheckedCast() CI1I2().uncheckedCast() assertFailsWith { Any().uncheckedCast() } println("Ok") } fun Any?.uncheckedCast() where R : I1, R : I2 { this as R } interface I1 interface I2 open class C class CI1I2 : C(), I1, I2 class OtherCI1I2 : C(), I1, I2 ================================================ FILE: backend.native/tests/codegen/basics/unit1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unit1 import kotlin.test.* @Test fun runTest() { println(println("First").toString()) } ================================================ FILE: backend.native/tests/codegen/basics/unit2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unit2 import kotlin.test.* @Test fun runTest() { val x = foo() println(x.toString()) } fun foo() { return Unit } ================================================ FILE: backend.native/tests/codegen/basics/unit3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unit3 import kotlin.test.* @Test fun runTest() { foo(Unit) } fun foo(x: Any) { println(x.toString()) } ================================================ FILE: backend.native/tests/codegen/basics/unit4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.basics.unit4 import kotlin.test.* @Test fun runTest() { for (x in 0 .. 8) { foo(x, Unit) } println("Done") } var global = 42 fun foo(x: Int, unit: Unit) { var local = 5 val y: Unit = when (x) { 0 -> {} 1 -> local = 6 2 -> global = 43 3 -> unit 4 -> Unit 5 -> bar() 6 -> return 7 -> { 5 bar() } 8 -> { val z: Any = Unit z as Unit } else -> throw Error() } if (y !== Unit) { println("Fail at x = $x") } } fun bar() { } ================================================ FILE: backend.native/tests/codegen/boxing/box_cache0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.box_cache0 import kotlin.test.* fun areSame(arg1: T, arg2: T): Boolean { return arg1 === arg2 } @Test fun runTest() { var acc = 0 val range = 1000 for (i in arrayOf(false, true)) { for (j in arrayOf(false, true)) { acc += areSame(i, j).hashCode() } } println(acc) acc = 0 for (i in Byte.MIN_VALUE..Byte.MAX_VALUE) { acc += areSame(i, i).hashCode() } println(acc) acc = 0 for (i in Short.MIN_VALUE..Short.MAX_VALUE) { acc += areSame(i, i).hashCode() } println(acc) acc = 0 for (i in 0.toChar()..range.toChar()) { acc += areSame(i, i).hashCode() } println(acc) acc = 0 for (i in -range..range) { acc += areSame(i, i).hashCode() } println(acc) acc = 0 for (i in -range.toLong()..range.toLong()) { acc += areSame(i, i).hashCode() } println(acc) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing0 import kotlin.test.* class Box(t: T) { var value = t } @Test fun runTest() { val box: Box = Box(17) println(box.value) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing1 import kotlin.test.* fun foo(arg: Any) { println(arg.toString()) } @Test fun runTest() { foo(1) foo(false) foo("Hello") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing10 import kotlin.test.* @Test fun runTest() { val FALSE: Boolean? = false if (FALSE != null) { do { println("Ok") } while (FALSE) } } ================================================ FILE: backend.native/tests/codegen/boxing/boxing11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing11 import kotlin.test.* fun printInt(x: Int) = println(x) class Foo(val value: Int?) { fun foo() { printInt(if (value != null) value else 42) } } @Test fun runTest() { Foo(17).foo() Foo(null).foo() } ================================================ FILE: backend.native/tests/codegen/boxing/boxing12.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing12 import kotlin.test.* fun foo(x: Number) { println(x.toByte()) } @Test fun runTest() { foo(18) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing13.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing13 import kotlin.test.* fun is42(x: Any?) { println(x == 42) println(42 == x) } @Test fun runTest() { is42(16) is42(42) is42("42") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing14.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing14 import kotlin.test.* @Test fun runTest() { 42.println() } fun T.println() = println(this.toString()) ================================================ FILE: backend.native/tests/codegen/boxing/boxing15.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing15 import kotlin.test.* @Test fun runTest() { println(foo(17)) } fun foo(x: T): Int = x ================================================ FILE: backend.native/tests/codegen/boxing/boxing2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing2 import kotlin.test.* fun printInt(x: Int) = println(x) fun printBoolean(x: Boolean) = println(x) fun foo(arg: Any) { if (arg is Int) printInt(arg) else if (arg is Boolean) printBoolean(arg) else println("other") } @Test fun runTest() { foo(1) foo(true) foo("Hello") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing3 import kotlin.test.* fun printInt(x: Int) = println(x) fun foo(arg: Int?) { if (arg != null) printInt(arg) } @Test fun runTest() { foo(42) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing4 import kotlin.test.* fun printInt(x: Int) = println(x) fun foo(arg: Any?) { if (arg is Int? && arg != null) printInt(arg) } @Test fun runTest() { foo(16) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing5 import kotlin.test.* fun printInt(x: Int) = println(x) fun foo(arg: Int?) { printInt(arg ?: 16) } @Test fun runTest() { foo(null) foo(42) } ================================================ FILE: backend.native/tests/codegen/boxing/boxing6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing6 import kotlin.test.* fun printInt(x: Int) = println(x) fun foo(arg: Any) { printInt(arg as? Int ?: 16) } @Test fun runTest() { foo(42) foo("Hello") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing7 import kotlin.test.* fun printInt(x: Int) = println(x) fun foo(arg: Any) { val argAsInt = try { arg as Int } catch (e: ClassCastException) { 0 } printInt(argAsInt) } @Test fun runTest() { foo(1) foo("Hello") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing8 import kotlin.test.* fun foo(vararg args: Any?) { for (arg in args) { println(arg.toString()) } } @Test fun runTest() { foo(1, null, true, "Hello") } ================================================ FILE: backend.native/tests/codegen/boxing/boxing9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.boxing.boxing9 import kotlin.test.* fun foo(vararg args: Any?) { for (arg in args) { println(arg.toString()) } } fun bar(vararg args: Any?) { foo(1, *args, 2, *args, 3) } @Test fun runTest() { bar(null, true, "Hello") } ================================================ FILE: backend.native/tests/codegen/branching/advanced_when2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.advanced_when2 import kotlin.test.* fun advanced_when2(i: Int): Int { var value = 1 when (i) { 10 -> {val v = 42; value = v} 11 -> {val v = 43; value = v} 12 -> {val v = 44; value = v} } return value } @Test fun runTest() { if (advanced_when2(10) != 42) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/advanced_when5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.advanced_when5 import kotlin.test.* fun advanced_when5(i: Int): Int { when (i) { 0 -> { val v = 42; return v} 1 -> { val v = 42; return v} 2 -> { val v = 42; return v} 3 -> { val v = 42; return v} 4 -> { val v = 42; return v} else -> return 24 } } @Test fun runTest() { if (advanced_when5(5) != 24) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/if_else.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.if_else import kotlin.test.* fun if_else(b: Boolean): Int { if (b) return 42 else return 24 } @Test fun runTest() { if (if_else(false) != 24) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/when2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when2 import kotlin.test.* fun when2(i: Int): Int { when (i) { 0 -> return 42 else -> return 24 } } @Test fun runTest() { if (when2(0) != 42) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/when4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when4 import kotlin.test.* fun when5(i: Int): Int { when (i) { 0 -> return 42 1 -> return 4 2 -> return 3 3 -> return 2 4 -> return 1 } return 24 } ================================================ FILE: backend.native/tests/codegen/branching/when5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when5 import kotlin.test.* fun when5(i: Int): Int { when (i) { 0 -> return 42 1 -> return 4 2 -> return 3 3 -> return 2 4 -> return 1 else -> return 24 } } @Test fun runTest() { if (when5(2) != 3) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/when6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when6 import kotlin.test.* fun foo() { } @Test fun runTest() { if (true) foo() else foo() } ================================================ FILE: backend.native/tests/codegen/branching/when7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when7 import kotlin.test.* @Test fun runTest() { main(emptyArray()) } fun main(args: Array) { val b = args.size < 1 val x = if (b) Any() else throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/when8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when8 import kotlin.test.* @Test fun runTest() { when (true) { true -> println("true") false -> println("false") } } ================================================ FILE: backend.native/tests/codegen/branching/when9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when9 import kotlin.test.* @Test fun runTest() { foo(0) println("Ok") } fun foo(x: Int) { when (x) { 0 -> 0 } } ================================================ FILE: backend.native/tests/codegen/branching/when_through.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when_through import kotlin.test.* fun when_through(i: Int): Int { var value = 1 when (i) { 10 -> value = 42 11 -> value = 43 12 -> value = 44 } return value } @Test fun runTest() { if (when_through(2) != 1) throw Error() } ================================================ FILE: backend.native/tests/codegen/branching/when_with_try1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.branching.when_with_try1 import kotlin.test.* @Test fun runTest() { println(foo(Any())) println(foo("zzz")) println(foo("42")) } fun foo(value: Any): Int? { if (value is CharSequence) { try { return value.toString().toInt() } catch (e: NumberFormatException) { return null } } else { return null } } ================================================ FILE: backend.native/tests/codegen/bridges/linkTest2_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ sealed class Tag { abstract fun value(): Any } sealed class TagBoolean : Tag() { abstract override fun value(): Boolean object True : TagBoolean() { override fun value() = true } object False : TagBoolean() { override fun value() = false } } ================================================ FILE: backend.native/tests/codegen/bridges/linkTest2_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { val test: TagBoolean = TagBoolean.True println(test.value()) } ================================================ FILE: backend.native/tests/codegen/bridges/linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a interface A { fun foo(): T } open class C: A { override fun foo(): Int = 42 } ================================================ FILE: backend.native/tests/codegen/bridges/linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* class B: C() fun main(args: Array) { val b = B() println(b.foo()) val c: C = b println(c.foo()) val a: A = b println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/bridges/nativePointed.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.nativePointed import kotlinx.cinterop.* import kotlin.test.* abstract class C { abstract fun foo(x: Int): CPointer<*>? } class CImpl : C() { override fun foo(x: Int) = null } @Test fun runTest() { val c: C = CImpl() assertNull(c.foo(42)) } ================================================ FILE: backend.native/tests/codegen/bridges/returnTypeSignature.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.signature import kotlin.test.* class A { } class B { } class C { } interface Parser { fun parse(source: IN): OUT } interface MultiParser { fun parse(source: IN): Collection } interface ExtendsInterface: Parser, MultiParser { override fun parse(source: B): Collection = ArrayList() } abstract class AbstractClass(): ExtendsInterface { public override fun parse(source: A): C = C() } @Test fun runTest() { val array = object : AbstractClass() { }.parse(B()) } ================================================ FILE: backend.native/tests/codegen/bridges/special.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.special import kotlin.test.* private object NotEmptyMap : MutableMap { override fun containsKey(key: Any): Boolean = true override fun containsValue(value: Int): Boolean = true // non-special bridges get(Object)Integer -> get(Object)I override fun get(key: Any): Int = 1 override fun remove(key: Any): Int = 1 override val size: Int get() = 0 override fun isEmpty(): Boolean = true override fun put(key: Any, value: Int): Int? = throw UnsupportedOperationException() override fun putAll(from: Map): Unit = throw UnsupportedOperationException() override fun clear(): Unit = throw UnsupportedOperationException() override val entries: MutableSet> get() = null!! override val keys: MutableSet get() = null!! override val values: MutableCollection get() = null!! } fun box(): String { val n = NotEmptyMap as MutableMap if (n.get(null) != null) return "fail 1" if (n.containsKey(null)) return "fail 2" if (n.containsValue(null)) return "fail 3" if (n.remove(null) != null) return "fail 4" if (n.get(1) == null) return "fail 5" if (!n.containsKey("")) return "fail 6" if (!n.containsValue(3)) return "fail 7" if (n.remove("") == null) return "fail 8" return "Ok" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/specialGeneric.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.specialGeneric import kotlin.test.* interface Element { val isContained: Boolean } object ContainedElement : Element { override val isContained: Boolean = true } object NotContainedElement : Element { override val isContained: Boolean = false } internal class MySet : Set { override fun contains(element: E): Boolean = element.isContained override fun equals(other: Any?): Boolean = TODO() override fun hashCode(): Int = TODO() override fun toString(): String = TODO() override val size: Int get() = TODO() override fun isEmpty(): Boolean = TODO() override fun containsAll(elements: Collection): Boolean = TODO() override fun iterator(): Iterator = TODO() } fun set(): Set = MySet() @Test fun testMySet() { val set = set() assertFalse(set.contains(Any())) assertFalse(set.contains(NotContainedElement)) assertTrue(set.contains(ContainedElement)) } ================================================ FILE: backend.native/tests/codegen/bridges/test0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test0 import kotlin.test.* // vtable call open class A { open fun foo(): Any = "A" } open class C : A() { override fun foo(): Int = 42 } @Test fun runTest() { val c = C() val a: A = c println(c.foo().toString()) println(a.foo().toString()) } ================================================ FILE: backend.native/tests/codegen/bridges/test1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test1 import kotlin.test.* // interface call, bridge overridden interface Z1 { fun foo(x: Int) : Any } open class A : Z1 { override fun foo(x: Int) : Int = 5 } open class B : A() { override fun foo(x: Int) : Int = 42 } @Test fun runTest() { val z1: A = B() println((z1.foo(1) + 1000).toString()) } ================================================ FILE: backend.native/tests/codegen/bridges/test10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test10 import kotlin.test.* open class A { open fun foo(x: T) { println(x.toString()) } } interface I { fun foo(x: Int) } class B : A(), I { var z: Int = 5 override fun foo(x: Int) { z = x } } fun zzz(a: A) { a.foo(42) } @Test fun runTest() { val b = B() zzz(b) val a = A() zzz(a) println(b.z) } ================================================ FILE: backend.native/tests/codegen/bridges/test11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test11 import kotlin.test.* interface I { fun foo(x: Int) } abstract class A { abstract fun foo(x: T) } class B : A(), I { override fun foo(x: Int) = println(x) } @Test fun runTest() { val b = B() val a: A = b val c: I = b b.foo(42) a.foo(42) c.foo(42) } ================================================ FILE: backend.native/tests/codegen/bridges/test12.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test12 import kotlin.test.* abstract class A { abstract fun foo(x: T) } class B : A() { override fun foo(x: Int) { println("B: $x") } } class C : A() { override fun foo(x: Any) { println("C: $x") } } fun foo(arg: A) { arg.foo(42) } @Test fun runTest() { foo(B()) foo(C()) } ================================================ FILE: backend.native/tests/codegen/bridges/test13.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test13 import kotlin.test.* open class A { open fun T.foo() { println(this.toString()) } fun bar(x: T) { x.foo() } } open class B: A() { override fun Int.foo() { println(this) } } @Test fun runTest() { val b = B() val a = A() b.bar(42) a.bar(42) } ================================================ FILE: backend.native/tests/codegen/bridges/test14.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test14 import kotlin.test.* open class A { open fun foo(x: T, y: U) { println(x.toString()) println(y.toString()) } } interface I1 { fun foo(x: Int, y: T) } interface I2 { fun foo(x: T, y: Int) } class B : A(), I1, I2 { var z: Int = 5 var q: Int = 7 override fun foo(x: Int, y: Int) { z = x q = y } } fun zzz(a: A) { a.foo(42, 56) } @Test fun runTest() { val b = B() zzz(b) val a = A() zzz(a) println(b.z) println(b.q) val i1: I1 = b i1.foo(56, 42) println(b.z) println(b.q) val i2: I2 = b i2.foo(156, 142) println(b.z) println(b.q) } ================================================ FILE: backend.native/tests/codegen/bridges/test15.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test15 import kotlin.test.* // non-generic interface, generic impl, vtable call + interface call open class A { open var size: T = 56 as T } interface C { var size: Int } open class B : C, A() open class D: B() { override var size: Int = 117 } fun foo(a: A) { a.size = 42 as T } fun box(): String { val b = B() foo(b) if (b.size != 42) return "fail 1" val d = D() if (d.size != 117) return "fail 2" foo(d) if (d.size != 42) return "fail 3" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/test16.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test16 import kotlin.test.* interface A { fun foo(): String } abstract class C: A open class B: C() { override fun foo(): String { return "OK" } } fun bar(c: C) = c.foo() @Test fun runTest() { val b = B() val c: C = b println(bar(b)) println(bar(c)) } ================================================ FILE: backend.native/tests/codegen/bridges/test17.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test17 import kotlin.test.* // abstract bridge interface A { fun foo(): T } abstract class B: A abstract class C: B() class D: C() { override fun foo(): Int { return 42 } } @Test fun runTest() { val d = D() val c: C = d val b: B = d val a: A = d println(d.foo()) println(c.foo()) println(b.foo()) println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/bridges/test18.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test18 import kotlin.test.* // overriden function returns Unit open class A { open fun foo(): Any = 42 } open class B: A() { override fun foo(): Unit { } } @Test fun runTest() { val a: A = B() println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/bridges/test2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test2 import kotlin.test.* // vtable call, bridge inherited open class A { open fun foo(): Any = "A" } open class C : A() { override fun foo(): Int = 42 } open class D: C() @Test fun runTest() { val c = D() val a: A = c println(c.foo().toString()) println(a.foo().toString()) } ================================================ FILE: backend.native/tests/codegen/bridges/test3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test3 import kotlin.test.* // non-generic interface, generic impl, non-virtual call + interface call open class A { var size: T = 56 as T } interface C { var size: Int } class B : C, A() fun box(): String { val b = B() if (b.size != 56) return "fail 1" b.size = 55 if (b.size != 55) return "fail 2" val c: C = b if (c.size != 55) return "fail 3" c.size = 57 if (c.size != 57) return "fail 4" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/test4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test4 import kotlin.test.* // vtable call + interface call interface Z { fun foo(): Any } interface Y { fun foo(): Int } open class A { fun foo(): Int = 42 } open class B: A(), Z, Y @Test fun runTest() { val z: Z = B() val y: Y = z as Y println(z.foo().toString()) println(y.foo().toString()) } ================================================ FILE: backend.native/tests/codegen/bridges/test5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test5 import kotlin.test.* // non-generic interface, generic impl, vtable call + interface call open class A { open var size: T = 56 as T } interface C { var size: Int } open class B : C, A() fun box(): String { val b = B() if (b.size != 56) return "fail 1" b.size = 55 if (b.size != 55) return "fail 2" val c: C = b if (c.size != 55) return "fail 3" c.size = 57 if (c.size != 57) return "fail 4" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/test6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test6 import kotlin.test.* // vtable call + interface call interface Z { fun foo(): Any } interface Y { fun foo(): Int } open class A { open fun foo(): Any = "A" } open class C : A() { override fun foo(): Int = 42 } open class D: C(), Y, Z @Test fun runTest() { val d = D() val y: Y = d val z: Z = d val c: C = d val a: A = d println(d.foo().toString()) println(y.foo().toString()) println(z.foo().toString()) println(c.foo().toString()) println(a.foo().toString()) } ================================================ FILE: backend.native/tests/codegen/bridges/test7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test7 import kotlin.test.* // generic interface, non-generic impl, vtable call + interface call open class A { open var size: Int = 56 } interface C { var size: T } open class B : C, A() fun box(): String { val b = B() if (b.size != 56) return "fail 1" b.size = 55 if (b.size != 55) return "fail 2" val c: C = b if (c.size != 55) return "fail 3" c.size = 57 if (c.size != 57) return "fail 4" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/test8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test8 import kotlin.test.* // generic interface, non-generic impl, non-virtual call + interface call open class A { var size: Int = 56 } interface C { var size: T } class B : C, A() fun box(): String { val b = B() if (b.size != 56) return "fail 1" b.size = 55 if (b.size != 55) return "fail 2" val c: C = b if (c.size != 55) return "fail 3" c.size = 57 if (c.size != 57) return "fail 4" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/bridges/test9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.bridges.test9 import kotlin.test.* // abstract class vtable call abstract class A { abstract fun foo(): String } abstract class B : A() class Z : B() { override fun foo() = "Z" } fun box(): String { val z = Z() val b: B = z val a: A = z return when { z.foo() != "Z" -> "Fail #1" b.foo() != "Z" -> "Fail #2" a.foo() != "Z" -> "Fail #3" else -> "OK" } } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/classDelegation/generic.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.classDelegation.generic import kotlin.test.* open class Content() { override fun toString() = "OK" } interface Box { fun get(): E } interface ContentBox : Box object Impl : ContentBox { override fun get(): Content = Content() } class ContentBoxDelegate() : ContentBox by (Impl as ContentBox) fun box() = ContentBoxDelegate().get().toString() @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/classDelegation/linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package zzz interface I { fun foo(): Int } open class A : I { override fun foo() = 42 } open class B : I by A() { val x = 117 val y = "zzz" } ================================================ FILE: backend.native/tests/codegen/classDelegation/linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import zzz.* class C : B() { val a = "qxx" val b = 123 } fun main(args: Array) { val c = C() println(c.a) println(c.b) println(c.foo()) println(c.x) println(c.y) } ================================================ FILE: backend.native/tests/codegen/classDelegation/method.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.classDelegation.method import kotlin.test.* interface A { fun foo(): T } class B : A { override fun foo() = "OK" } class C(a: A) : A by a fun box(): String { val c = C(B()) val a: A = c return c.foo() + a.foo() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/classDelegation/property.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.classDelegation.property import kotlin.test.* interface A { val x: Int } class C: A { override val x: Int = 42 } class Q(a: A): A by a fun box(): String { val q = Q(C()) val a: A = q return q.x.toString() + a.x.toString() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/classDelegation/withBridge.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.classDelegation.withBridge import kotlin.test.* interface A { fun foo(t: T): String } interface B { fun foo(t: Int) = "B" } class Z : B class Z1 : A, B by Z() fun box(): String { val z1 = Z1() val z1a: A = z1 val z1b: B = z1 return when { z1.foo( 0) != "B" -> "Fail #1" z1a.foo( 0) != "B" -> "Fail #2" z1b.foo( 0) != "B" -> "Fail #3" else -> "OK" } } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/contracts/contracts.kt ================================================ import kotlin.test.* import kotlin.contracts.* open class S class P(val str: String = "P") : S() @OptIn(kotlin.contracts.ExperimentalContracts::class) fun check(actual: Boolean) { contract { returns() implies actual } assertTrue(actual) } @Test fun testContractForCast() { val s: S = P() check(s is P) assertEquals(s.str, "P") } @Test fun testRequire() { val s: S = P() require(s is P) assertEquals(s.str, "P") } @Test fun testNonNullSmartCast() { val i: Int? = 1234 requireNotNull(i) assertEquals(i, 1234) } @Test fun testRunLambdaForVal() { val x: Int run { x = 42 } assertEquals(x, 42) } @Test fun testIsNullString() { assertEquals("STR", nullableString("str")) assertEquals("", nullableString(null)) } private fun nullableString(string: String?): String = if (string.isNullOrBlank()) "" else "STR" ================================================ FILE: backend.native/tests/codegen/controlflow/break.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.`break` import kotlin.test.* fun foo() { var i = 0 l1@while (true) { println("foo@l1") try { l2@while (true) { if ((i++ % 2) == 0) continue@l2 println("foo@l2") if (i > 4) break@l1 } } finally { } } } fun bar() { var i = 0 l1@do { try { println("bar@l1") throw Exception() } catch (e: Exception) { l2@do { if ((i++ % 2) == 0) continue@l2 println("bar@l2") if (i > 4) break@l1 } while (true) } } while (true) } fun qux() { l1@for (i in 1..6) { t1@try { println("qux@t1") throw Exception() } finally { l2@ for (j in 1..6) { if ((j % 2) == 0) continue@l2 println("qux@l2") if (j > 4) break@l1 } } } } @Test fun runTest() { foo() bar() qux() } ================================================ FILE: backend.native/tests/codegen/controlflow/break1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.break1 import kotlin.test.* @Test fun runTest() { loop@ while (true) { println("Body") break } println("Done") } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops import kotlin.test.* @Test fun runTest() { // Simple loops for (i in 0..4) { print(i) } println() for (i in 0 until 4) { print(i) } println() for (i in 4 downTo 0) { print(i) } println() println() // Steps for (i in 0..4 step 2) { print(i) } println() for (i in 0 until 4 step 2) { print(i) } println() for (i in 4 downTo 0 step 2) { print(i) } println() println() // Two steps for (i in 0..6 step 2 step 3) { print(i) } println() for (i in 0 until 6 step 2 step 3) { print(i) } println() for (i in 6 downTo 0 step 2 step 3) { print(i) } println() println() // Without constants val a = 0 val b = 4 val s = 2 for (i in a..b step s) { print(i) } println() for (i in a until b step s) { print(i) } println() for (i in b downTo a step s) { print(i) } println() println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array.kt ================================================ package codegen.controlflow.for_loops_array import kotlin.test.* fun genericArray(data : T): Int { var sum = 0 for (element in data) { sum += element } return sum } fun IntArray.sum(): Int { var sum = 0 for (element in this) { sum += element } return sum } @Test fun runTest() { val intArray = intArrayOf(4, 0, 3, 5) val emptyArray = arrayOf() for (element in intArray) { print(element) } println() for (element in emptyArray) { print(element) } println() val byteArray = byteArrayOf(1, -1) println(genericArray(byteArray)) val fives = intArrayOf(5, 5, 5, -5, -5, -5) println(fives.sum()) } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_break_continue.kt ================================================ package codegen.controlflow.for_loops_array_break_continue import kotlin.test.* @Test fun runTest() { val intArray = intArrayOf(4, 0, 3, 5) val emptyArray = arrayOf() for (element in intArray) { print(element) if (element == 3) { break } } println() for (element in emptyArray) { print(element) } println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_indices.kt ================================================ package codegen.controlflow.for_loops_array_indices import kotlin.test.* @Test fun runTest() { val intArray = intArrayOf(4, 0, 3, 5) val emptyArray = arrayOf() for (index in intArray.indices) { print(index) } println() for (index in emptyArray.indices) { print(index) } println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_mutation.kt ================================================ package codegen.controlflow.for_loops_array_mutation import kotlin.test.* @Test fun runTest() { val intArray = arrayOf(4, 0, 3, 5) for (element in intArray) { intArray[2] = 0 intArray[3] = 0 print(element) } } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_nested.kt ================================================ package codegen.controlflow.for_loops_array_nested import kotlin.test.* @Test fun arrayOfArrays() { val metaArray = arrayOf( arrayOf(1, 2, 3), arrayOf("Hello"), arrayOf(), arrayOf(1..10) ) for (array in metaArray) { inner@for (elem in array) { if (elem is IntProgression) { for (i in elem) { print(i) } continue@inner } else { print(elem) } } println() } } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_nullable.kt ================================================ package codegen.controlflow.for_loops_array_nullable import kotlin.test.* private fun nullableArray(a: Array): Array? { return a } @Test fun nullable() { val array = arrayOf(1, 2, 3) nullableArray(array)?.let { for (elem in it) { print(elem) } } } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_array_side_effects.kt ================================================ package codegen.controlflow.for_loops_array_side_effects import kotlin.test.* private fun sideEffect(array: T): T { println("side-effect") return array } @Test fun runTest() { val intArray = intArrayOf(4, 0, 3, 5) val emptyArray = arrayOf() for (element in sideEffect(intArray)) { print(element) } println() for (element in sideEffect(emptyArray)) { print(element) } println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_call_order.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_call_order import kotlin.test.* fun f1(): Int { print("1"); return 0 } fun f2(): Int { print("2"); return 6 } fun f3(): Int { print("3"); return 2 } fun f4(): Int { print("4"); return 3 } @Test fun runTest() { for (i in f1()..f2() step f3() step f4()) { }; println() for (i in f1() until f2() step f3() step f4()) {}; println() for (i in f2() downTo f1() step f3() step f4()) {}; println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_coroutines.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_coroutines import kotlin.test.* import kotlin.coroutines.* @Test fun runTest() { val sq = sequence { for (i in 0..6 step 2) { print("before: $i ") yield(i) println("after: $i") } } println("Got: ${sq.joinToString(separator = " ")}") } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_empty_range.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_empty_range import kotlin.test.* @Test fun runTest() { // Simple loops for (i in 4..0) { print(i) } for (i in 4 until 0) { print(i) } for (i in 0 downTo 4) { print(i) } // Steps for (i in 4..0 step 2) { print(i) } for (i in 4 until 0 step 2) { print(i) } for (i in 0 downTo 4 step 2) { print(i) } // Two steps for (i in 6..0 step 2 step 3) { print(i) } for (i in 6 until 0 step 2 step 3) { print(i) } for (i in 0 downTo 6 step 2 step 3) { print(i) } println("OK") } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_errors.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_errors import kotlin.test.* @Test fun runTest() { // Negative step. try { for (i in 0 .. 4 step -2) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 0 until 4 step -2) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 4 downTo 0 step -2) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} // Zero step. try { for (i in 0 .. 4 step 0) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 0 until 4 step 0) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 4 downTo 0 step 0) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} // Two steps, one is negative. try { for (i in 0 .. 4 step -2 step 3) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 0 until 4 step -2 step 3) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} try { for (i in 4 downTo 0 step -2 step 3) print(i); println() throw AssertionError() } catch (e: IllegalArgumentException) {} println("OK") } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_let_with_nullable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_let_with_nullable import kotlin.test.* // Github issue #1012 fun testInt(left: Int?, right: Int?, step: Int?) { right?.let { for (i in 0..it) { print(i) } } println() left?.let { for (i in it..5) { print(i) } } println() step?.let { for (i in 0..5 step it) { print(i) } } println() right?.let { for (i in 0 until it) { print(i) } } println() left?.let { for (i in it until 5) { print(i) } } println() step?.let { for (i in 0 until 5 step it) { print(i) } } println() right?.let { for (i in it downTo 0) { print(i) } } println() left?.let { for (i in 5 downTo it) { print(i) } } println() step?.let { for (i in 5 downTo 0 step it) { print(i) } } println() } fun testLong(left: Long?, right: Long?, step: Long?) { right?.let { for (i in 0..it) { print(i) } } println() left?.let { for (i in it..5) { print(i) } } println() step?.let { for (i in 0..5L step it) { print(i) } } println() right?.let { for (i in 0 until it) { print(i) } } println() left?.let { for (i in it until 5) { print(i) } } println() step?.let { for (i in 0 until 5L step it) { print(i) } } println() right?.let { for (i in it downTo 0) { print(i) } } println() left?.let { for (i in 5 downTo it) { print(i) } } println() step?.let { for (i in 5 downTo 0L step it) { print(i) } } println() } fun testChar(left: Char?, right: Char?, step: Int?) { right?.let { for (i in 'a'..it) { print(i) } } println() left?.let { for (i in it..'f') { print(i) } } println() step?.let { for (i in 'a'..'f' step it) { print(i) } } println() right?.let { for (i in 'a' until it) { print(i) } } println() left?.let { for (i in it until 'f') { print(i) } } println() step?.let { for (i in 'a' until 'f' step it) { print(i) } } println() right?.let { for (i in it downTo 'a') { print(i) } } println() left?.let { for (i in 'f' downTo it) { print(i) } } println() step?.let { for (i in 'f' downTo 'a' step it) { print(i) } } println() } @Test fun runTest() { testInt(0, 5, 2) testLong(0, 5, 2) testChar('a', 'f', 2) } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_nested.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_nested import kotlin.test.* @Test fun runTest() { // Simple for (i in 0..2) { for (j in 0..2) { print("$i$j ") } } println() // Break l1@for (i in 0..2) { l2@for (j in 0..2) { print("$i$j ") if (j == 1) break } } println() l1@for (i in 0..2) { l2@for (j in 0..2) { print("$i$j ") if (j == 1) break@l2 } } println() l1@for (i in 0..2) { l2@for (j in 0..2) { print("$i$j ") if (j == 1) break@l1 } } println() // Continue l1@for (i in 0..2) { l2@for (j in 0..2) { if (j == 1) continue print("$i$j ") } } println() l1@for (i in 0..2) { l2@for (j in 0..2) { if (j == 1) continue@l2 print("$i$j ") } } println() l1@for (i in 0..2) { l2@for (j in 0..2) { if (j == 1) continue@l1 print("$i$j ") } } println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_overflow.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_overflow import kotlin.test.* @Test fun runTest() { for (i in Int.MAX_VALUE - 1 .. Int.MAX_VALUE) { print(i); print(' ') }; println() for (i in Int.MAX_VALUE - 1 until Int.MAX_VALUE) { print(i); print(' ') }; println() for (i in Int.MIN_VALUE + 1 downTo Int.MIN_VALUE) { print(i); print(' ') }; println() // Empty loops for (i in Byte.MIN_VALUE until Byte.MIN_VALUE) { print(i); print(' ') } for (i in Short.MIN_VALUE until Short.MIN_VALUE) { print(i); print(' ') } for (i in Int.MIN_VALUE until Int.MIN_VALUE) { print(i); print(' ') } for (i in Long.MIN_VALUE until Long.MIN_VALUE) { print(i); print(' ') } for (i in 0.toChar() until 0.toChar()) { print(i); print(' ') } for (i in 0 until Byte.MIN_VALUE) { print(i); print(' ') } for (i in 0 until Short.MIN_VALUE) { print(i); print(' ') } for (i in 0 until Int.MIN_VALUE) { print(i); print(' ') } for (i in 0 until Long.MIN_VALUE) { print(i); print(' ') } for (i in 'a' until 0.toChar()) { print(i); print(' ') } val M = Int.MAX_VALUE / 2 for (i in M + 4..M + 10 step M) { print(i); print(' ') }; println() } ================================================ FILE: backend.native/tests/codegen/controlflow/for_loops_types.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.for_loops_types import kotlin.test.* @Test fun runTest() { for (i in 0.toByte() .. 4.toByte()) print(i); println() for (i in 0.toByte() .. 4.toShort()) print(i); println() for (i in 0.toByte() .. 4.toInt()) print(i); println() for (i in 0.toByte() .. 4.toLong()) print(i); println() for (i in 0.toShort() .. 4.toByte()) print(i); println() for (i in 0.toShort() .. 4.toShort()) print(i); println() for (i in 0.toShort() .. 4.toInt()) print(i); println() for (i in 0.toShort() .. 4.toLong()) print(i); println() for (i in 0.toInt() .. 4.toByte()) print(i); println() for (i in 0.toInt() .. 4.toShort()) print(i); println() for (i in 0.toInt() .. 4.toInt()) print(i); println() for (i in 0.toInt() .. 4.toLong()) print(i); println() for (i in 0.toLong() .. 4.toByte()) print(i); println() for (i in 0.toLong() .. 4.toShort()) print(i); println() for (i in 0.toLong() .. 4.toInt()) print(i); println() for (i in 0.toLong() .. 4.toLong()) print(i); println() for (i in 0.toByte() until 4.toByte()) print(i); println() for (i in 0.toByte() until 4.toShort()) print(i); println() for (i in 0.toByte() until 4.toInt()) print(i); println() for (i in 0.toByte() until 4.toLong()) print(i); println() for (i in 0.toShort() until 4.toByte()) print(i); println() for (i in 0.toShort() until 4.toShort()) print(i); println() for (i in 0.toShort() until 4.toInt()) print(i); println() for (i in 0.toShort() until 4.toLong()) print(i); println() for (i in 0.toInt() until 4.toByte()) print(i); println() for (i in 0.toInt() until 4.toShort()) print(i); println() for (i in 0.toInt() until 4.toInt()) print(i); println() for (i in 0.toInt() until 4.toLong()) print(i); println() for (i in 0.toLong() until 4.toByte()) print(i); println() for (i in 0.toLong() until 4.toShort()) print(i); println() for (i in 0.toLong() until 4.toInt()) print(i); println() for (i in 0.toLong() until 4.toLong()) print(i); println() for (i in 4.toByte() downTo 0.toByte()) print(i); println() for (i in 4.toByte() downTo 0.toShort()) print(i); println() for (i in 4.toByte() downTo 0.toInt()) print(i); println() for (i in 4.toByte() downTo 0.toLong()) print(i); println() for (i in 4.toShort() downTo 0.toByte()) print(i); println() for (i in 4.toShort() downTo 0.toShort()) print(i); println() for (i in 4.toShort() downTo 0.toInt()) print(i); println() for (i in 4.toShort() downTo 0.toLong()) print(i); println() for (i in 4.toInt() downTo 0.toByte()) print(i); println() for (i in 4.toInt() downTo 0.toShort()) print(i); println() for (i in 4.toInt() downTo 0.toInt()) print(i); println() for (i in 4.toInt() downTo 0.toLong()) print(i); println() for (i in 4.toLong() downTo 0.toByte()) print(i); println() for (i in 4.toLong() downTo 0.toShort()) print(i); println() for (i in 4.toLong() downTo 0.toInt()) print(i); println() for (i in 4.toLong() downTo 0.toLong()) print(i); println() for (i in 'a' .. 'd') print(i); println() for (i in 'a' until 'd') print(i); println() for (i in 'd' downTo 'a') print(i); println() for (i in 0.toByte() .. 4.toByte() step 2) print(i); println() for (i in 0.toByte() .. 4.toShort() step 2) print(i); println() for (i in 0.toByte() .. 4.toInt() step 2) print(i); println() for (i in 0.toByte() .. 4.toLong() step 2L) print(i); println() for (i in 0.toShort() .. 4.toByte() step 2) print(i); println() for (i in 0.toShort() .. 4.toShort() step 2) print(i); println() for (i in 0.toShort() .. 4.toInt() step 2) print(i); println() for (i in 0.toShort() .. 4.toLong() step 2L) print(i); println() for (i in 0.toInt() .. 4.toByte() step 2) print(i); println() for (i in 0.toInt() .. 4.toShort() step 2) print(i); println() for (i in 0.toInt() .. 4.toInt() step 2) print(i); println() for (i in 0.toInt() .. 4.toLong() step 2L) print(i); println() for (i in 0.toLong() .. 4.toByte() step 2L) print(i); println() for (i in 0.toLong() .. 4.toShort() step 2L) print(i); println() for (i in 0.toLong() .. 4.toInt() step 2L) print(i); println() for (i in 0.toLong() .. 4.toLong() step 2L) print(i); println() for (i in 0.toByte() until 4.toByte() step 2) print(i); println() for (i in 0.toByte() until 4.toShort() step 2) print(i); println() for (i in 0.toByte() until 4.toInt() step 2) print(i); println() for (i in 0.toByte() until 4.toLong() step 2L) print(i); println() for (i in 0.toShort() until 4.toByte() step 2) print(i); println() for (i in 0.toShort() until 4.toShort() step 2) print(i); println() for (i in 0.toShort() until 4.toInt() step 2) print(i); println() for (i in 0.toShort() until 4.toLong() step 2L) print(i); println() for (i in 0.toInt() until 4.toByte() step 2) print(i); println() for (i in 0.toInt() until 4.toShort() step 2) print(i); println() for (i in 0.toInt() until 4.toInt() step 2) print(i); println() for (i in 0.toInt() until 4.toLong() step 2L) print(i); println() for (i in 0.toLong() until 4.toByte() step 2L) print(i); println() for (i in 0.toLong() until 4.toShort() step 2L) print(i); println() for (i in 0.toLong() until 4.toInt() step 2L) print(i); println() for (i in 0.toLong() until 4.toLong() step 2L) print(i); println() for (i in 4.toByte() downTo 0.toByte() step 2) print(i); println() for (i in 4.toByte() downTo 0.toShort() step 2) print(i); println() for (i in 4.toByte() downTo 0.toInt() step 2) print(i); println() for (i in 4.toByte() downTo 0.toLong() step 2L) print(i); println() for (i in 4.toShort() downTo 0.toByte() step 2) print(i); println() for (i in 4.toShort() downTo 0.toShort() step 2) print(i); println() for (i in 4.toShort() downTo 0.toInt() step 2) print(i); println() for (i in 4.toShort() downTo 0.toLong() step 2L) print(i); println() for (i in 4.toInt() downTo 0.toByte() step 2) print(i); println() for (i in 4.toInt() downTo 0.toShort() step 2) print(i); println() for (i in 4.toInt() downTo 0.toInt() step 2) print(i); println() for (i in 4.toInt() downTo 0.toLong() step 2L) print(i); println() for (i in 4.toLong() downTo 0.toByte() step 2L) print(i); println() for (i in 4.toLong() downTo 0.toShort() step 2L) print(i); println() for (i in 4.toLong() downTo 0.toInt() step 2L) print(i); println() for (i in 4.toLong() downTo 0.toLong() step 2L) print(i); println() for (i in 'a' .. 'd' step 2) print(i); println() for (i in 'a' until 'd' step 2) print(i); println() for (i in 'd' downTo 'a' step 2) print(i); println() } ================================================ FILE: backend.native/tests/codegen/controlflow/unreachable1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.controlflow.unreachable1 import kotlin.test.* @Test fun runTest() { println(foo()) } fun foo(): Int { return 1 println("After return") } ================================================ FILE: backend.native/tests/codegen/coroutines/anonymousObject.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.anonymousObject import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } interface I { suspend fun foo(lambda: suspend (String) -> Unit) suspend fun bar(s: String) } fun create() = object: I { var lambda: suspend (String) -> Unit = {} override suspend fun foo(lambda: suspend (String) -> Unit) { this.lambda = lambda } override suspend fun bar(s: String) { lambda(s) } } @Test fun runTest() { builder { val z = create() z.foo { suspendHere(); println(it) } z.bar("zzz") } } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_chain.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_chain import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } // See https://github.com/JetBrains/kotlin-native/issues/3476 @Test fun runTest() { var result = 0 builder { foo().bar() result = 1 } assertEquals(1, result) } class Foo { suspend fun bar() { suspendHere() } } suspend fun foo() = Foo() ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = try { f1() } catch (t: Throwable) { f2() } finally { s1() } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { val x = try { f1() } catch (t: Throwable) { f2() } finally { s1() } result = x } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally3 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { try { result = f1() } catch (t: Throwable) { result = f2() } finally { s1() } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally4 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { try { result = s1() } catch (t: Throwable) { result = f2() } finally { println("finally") } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally5 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resumeWithException(Error()) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { try { result = s1() } catch (t: Throwable) { result = f2() } finally { println("finally") } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally6 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resumeWithException(Error("error")) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { try { try { result = s1() } catch (t: ClassCastException) { result = f2() } finally { println("finally") } } catch(t: Error) { println(t.message) } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_finally7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_finally7 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resumeWithException(Error()) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { try { try { result = s1() } catch (t: Throwable) { result = f2() } finally { println("finally1") result = s2() } } finally { println("finally2") } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_if1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_if1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = f3(if (f1() > 100) s1() else f2(), 42) } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_if2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_if2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { if (f1() > 100) result = s1() + f2() else result = 42 } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_inline1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_inline1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } inline suspend fun inline_s2(): Int { return 42 } @Test fun runTest() { var result = 0 builder { result = inline_s2() } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_inline2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_inline2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } inline suspend fun inline_s2(): Int { var x = s1() return x } @Test fun runTest() { var result = 0 builder { result = inline_s2() } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_inline3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_inline3 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } inline suspend fun inline_s2(): Int { var x = 0 if (f1() > 0) x = s1() else x = f2() return x } @Test fun runTest() { var result = 0 builder { result = inline_s2() } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_tryCatch1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_tryCatch1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { val x = try { s1() } catch (t: Throwable) { f2() } result = x } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_tryCatch2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_tryCatch2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = try { s1() } catch (t: Throwable) { f2() } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_tryCatch3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_tryCatch3 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resumeWithException(Error()) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = try { s2() } catch (t: Throwable) { f2() } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_tryCatch4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_tryCatch4 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resumeWithException(Error()) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { val x = try { s2() } catch (t: Throwable) { f2() } result = x } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_tryCatch5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_tryCatch5 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resumeWithException(Error("Error")) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = try { s2() } catch (t: Throwable) { val x = s1() println(t.message) x } } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_while1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_while1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resumeWithException(Error("Error")) COROUTINE_SUSPENDED } suspend fun s3(value: Int): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s3") x.resume(value) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { while (s3(result) < 3) ++result } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/controlFlow_while2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.controlFlow_while2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } suspend fun s2(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s2") x.resumeWithException(Error("Error")) COROUTINE_SUSPENDED } suspend fun s3(value: Int): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s3") x.resume(value) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun f3(x: Int, y: Int): Int { println("f3") return x + y } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { while (result < 3) result = s3(result) + 1 } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/coroutineContext1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.coroutineContext1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { builder { println(coroutineContext) } } ================================================ FILE: backend.native/tests/codegen/coroutines/coroutineContext2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.coroutineContext2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } suspend fun foo() = coroutineContext @Test fun runTest() { builder { println(foo()) } } ================================================ FILE: backend.native/tests/codegen/coroutines/correctOrder1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.correctOrder1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Int = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(42) COROUTINE_SUSPENDED } fun f1(): Int { println("f1") return 117 } fun f2(): Int { println("f2") return 1 } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = f1() + s1() + f2() } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/degenerate1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.degenerate1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1() { println("s1") } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { builder { s1() } } ================================================ FILE: backend.native/tests/codegen/coroutines/degenerate2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.degenerate2 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Unit = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(Unit) COROUTINE_SUSPENDED } suspend fun s2() { println("s2") s1() } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { builder { s2() } } ================================================ FILE: backend.native/tests/codegen/coroutines/functionReference_eqeq_name.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.functionReference_eqeq_name import kotlin.test.* suspend fun foo(x: Int) = x class Foo(val x: Int) { suspend fun bar() = x } @Test fun runTest() { val ref1 = ::foo val rec = Foo(42) val ref2 = rec::bar val ref3 = ::foo val ref4 = Foo(42)::bar val ref5 = rec::bar val ref6 = Foo::bar assertEquals("foo", ref1.name) assertEquals("bar", ref2.name) assertEquals("bar", ref6.name) assertFalse(ref1 == ref2) assertTrue(ref1 == ref3) assertFalse(ref2 == ref4) assertTrue(ref2 == ref5) assertFalse(ref6 == ref2) } ================================================ FILE: backend.native/tests/codegen/coroutines/functionReference_invokeAsFunction.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.functionReference_invokeAsFunction import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } class Foo(val x: Int) { suspend fun bar(y: Int) = foo(y) + x } suspend fun foo(x: Int) = x @Test fun runTest() { val ref = Foo(42)::bar println((ref as Function2, Any?>)(117, EmptyContinuation)) } ================================================ FILE: backend.native/tests/codegen/coroutines/functionReference_lambdaAsSuspendLambda.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.functionReference_lambdaAsSuspendLambda import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* fun foo(block: (Continuation) -> Any?) { block as (suspend () -> Unit) } @Test fun runTest() { foo {} } ================================================ FILE: backend.native/tests/codegen/coroutines/functionReference_simple.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.functionReference_simple import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } suspend fun foo(x: suspend () -> Int) = x() fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 val ref = ::suspendHere builder { result = foo(ref) } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/kt41394.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.kt41394 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } suspend fun foo(label: String): String { val x = suspendHere() return label + x.toString() } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = "" builder { result = foo("zzz") } assertEquals("zzz42", result) } ================================================ FILE: backend.native/tests/codegen/coroutines/returnsNothing1.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.returnsNothing1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendForever(): Int = suspendCoroutineUninterceptedOrReturn { COROUTINE_SUSPENDED } suspend fun foo(): Nothing { suspendForever() throw Error() } suspend fun bar() { foo() } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { builder { bar() } println("OK") } ================================================ FILE: backend.native/tests/codegen/coroutines/returnsUnit1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.returnsUnit1 import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun s1(): Unit = suspendCoroutineUninterceptedOrReturn { x -> println("s1") x.resume(Unit) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } inline suspend fun inline_s2(x: Int): Unit { println(x) s1() } suspend fun s3(x: Int) { inline_s2(x) } @Test fun runTest() { var result = 0 builder { s3(117) } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/simple.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.simple import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = suspendHere() } println(result) } ================================================ FILE: backend.native/tests/codegen/coroutines/suspendConversion.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } fun builder(c: suspend () -> Unit) { c.startCoroutine(EmptyContinuation) } fun main() { var result = 0 val f: () -> Unit = { result = 42 } builder(f) assertEquals(42, result) } ================================================ FILE: backend.native/tests/codegen/coroutines/withReceiver.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.coroutines.withReceiver import kotlin.test.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { companion object : EmptyContinuation() override fun resumeWith(result: Result) { result.getOrThrow() } } class Controller { suspend fun suspendHere(): Int = suspendCoroutineUninterceptedOrReturn { x -> x.resume(42) COROUTINE_SUSPENDED } } fun builder(c: suspend Controller.() -> Unit) { c.startCoroutine(Controller(), EmptyContinuation) } @Test fun runTest() { var result = 0 builder { result = suspendHere() } println(result) } ================================================ FILE: backend.native/tests/codegen/cycles/cycle.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.cycles.cycle import kotlin.test.* fun cycle(cnt: Int): Int { var sum = 1 while (sum == cnt) { sum = sum + 1 } return sum } @Test fun runTest() { if (cycle(1) != 2) throw Error() if (cycle(0) != 1) throw Error() } ================================================ FILE: backend.native/tests/codegen/cycles/cycle_do.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.cycles.cycle_do import kotlin.test.* fun cycle_do(cnt: Int): Int { var sum = 1 do { sum = sum + 2 } while (sum == cnt) return sum } @Test fun runTest() { if (cycle_do(3) != 5) throw Error() if (cycle_do(0) != 3) throw Error() } ================================================ FILE: backend.native/tests/codegen/cycles/cycle_for.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.cycles.cycle_for import kotlin.test.* fun cycle_for(arr: Array) : Int { var sum = 0 for (i in arr) { sum += i } return sum } @Test fun runTest() { if (cycle_for(Array(4, init = { it })) != 6) throw Error() } ================================================ FILE: backend.native/tests/codegen/dataflow/scope1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.dataflow.scope1 import kotlin.test.* var b = true @Test fun runTest() { var x = 1 if (b) { var x = 2 } println(x) } ================================================ FILE: backend.native/tests/codegen/dataflow/uninitialized_val.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.dataflow.uninitialized_val import kotlin.test.* fun foo(b: Boolean): Int { val x: Int if (b) { x = 1 } else { x = 2 } return x } @Test fun runTest() { val uninitializedUnused: Int println(foo(true)) println(foo(false)) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/correctFieldsOrder_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package zzz open class B { val z by lazy { "qzz" } val x = 117 val zzz = "zzz" } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/correctFieldsOrder_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import zzz.* class C : B() { val a = "qxx" } fun main(args: Array) { val c = C() println(c.a) println(c.x) println(c.zzz) println(c.z) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/delegatedOverride_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a import kotlin.reflect.KProperty open class A { open val x = 42 } class Delegate { val f = 117 operator fun getValue(receiver: Any?, p: KProperty<*>): Int { println(p.name) return f } } open class B: A() { override val x: Int by Delegate() fun bar() { println(super.x) } } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/delegatedOverride_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* open class C: B() { override val x: Int = 156 fun foo() { println(x) println(super.x) bar() } } fun main(args: Array) { val c = C() c.foo() } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/lazy.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.lazy import kotlin.test.* val lazyValue: String by lazy { println("computed!") "Hello" } @Test fun runTest() { println(lazyValue) println(lazyValue) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/local.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.local import kotlin.test.* import kotlin.reflect.KProperty fun foo(): Int { class Delegate { operator fun getValue(receiver: Any?, p: KProperty<*>): Int { println(p.name) return 42 } } val x: Int by Delegate() return x } @Test fun runTest() { println(foo()) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/map.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.map import kotlin.test.* class User(val map: Map) { val name: String by map val age: Int by map } @Test fun runTest() { val user = User(mapOf( "name" to "John Doe", "age" to 25 )) println(user.name) // Prints "John Doe" println(user.age) // Prints 25 } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/observable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.observable import kotlin.test.* import kotlin.properties.Delegates class User { var name: String by Delegates.observable("") { prop, old, new -> println("$old -> $new") } } @Test fun runTest() { val user = User() user.name = "first" user.name = "second" } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/packageLevel.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.packageLevel import kotlin.test.* import kotlin.reflect.KProperty class Delegate { operator fun getValue(receiver: Any?, p: KProperty<*>): Int { println(p.name) return 42 } } val x: Int by Delegate() @Test fun runTest() { println(x) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/simpleVal.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.simpleVal import kotlin.test.* import kotlin.reflect.KProperty class Delegate { operator fun getValue(receiver: Any?, p: KProperty<*>): Int { println(p.name) return 42 } } class C { val x: Int by Delegate() } @Test fun runTest() { println(C().x) } ================================================ FILE: backend.native/tests/codegen/delegatedProperty/simpleVar.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.delegatedProperty.simpleVar import kotlin.test.* import kotlin.reflect.KProperty class Delegate { var f: Int = 42 operator fun getValue(receiver: Any?, p: KProperty<*>): Int { println("get ${p.name}") return f } operator fun setValue(receiver: Any?, p: KProperty<*>, value: Int) { println("set ${p.name}") f = value } } class C { var x: Int by Delegate() } @Test fun runTest() { val c = C() println(c.x) c.x = 117 println(c.x) } ================================================ FILE: backend.native/tests/codegen/devirtualization/anonymousObject.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ interface I { fun foo() } fun test() { val impl = object : I { override fun foo() { println("zzz") } } val delegating = object: I by impl { } delegating.foo() } fun main() { test() } ================================================ FILE: backend.native/tests/codegen/devirtualization/getter_looking_as_box_function.kt ================================================ class Foo(val box: String = "box") fun main() { println(Foo().box) } ================================================ FILE: backend.native/tests/codegen/devirtualization/lateinitInterface.kt ================================================ interface I { fun foo(): Int } class A : I { override fun foo() = 42 } fun main(args: Array) { lateinit var a: I if (args.size == 0) a = A() println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/enum/companionObject.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.companionObject import kotlin.test.* enum class Game { ROCK, PAPER, SCISSORS; companion object { fun foo() = ROCK val bar = PAPER val values2 = values() val scissors = valueOf("SCISSORS") } } fun box(): String { if (Game.foo() != Game.ROCK) return "Fail 1" if (Game.bar != Game.PAPER) return "Fail 2: ${Game.bar}" if (Game.values().size != 3) return "Fail 3" if (Game.valueOf("SCISSORS") != Game.SCISSORS) return "Fail 4" if (Game.values2.size != 3) return "Fail 5" if (Game.scissors != Game.SCISSORS) return "Fail 6" return "OK" } @Test fun runTest() = println(box()) ================================================ FILE: backend.native/tests/codegen/enum/interfaceCallNoEntryClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.interfaceCallNoEntryClass import kotlin.test.* interface A { fun foo(): String } enum class Zzz(val zzz: String, val x: Int) : A { Z1("z1", 1), Z2("z2", 2), Z3("z3", 3); override fun foo(): String{ return "('$zzz', $x)" } } @Test fun runTest() { println(Zzz.Z3.foo()) val a: A = Zzz.Z3 println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/enum/interfaceCallWithEntryClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.interfaceCallWithEntryClass import kotlin.test.* interface A { fun f(): String } enum class Zzz: A { Z1 { override fun f() = "z1" }, Z2 { override fun f() = "z2" }; override fun f() = "" } @Test fun runTest() { println(Zzz.Z1.f() + Zzz.Z2.f()) val a1: A = Zzz.Z1 val a2: A = Zzz.Z2 println(a1.f() + a2.f()) } ================================================ FILE: backend.native/tests/codegen/enum/isFrozen.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.isFrozen import kotlin.test.* import kotlin.native.concurrent.* enum class Zzz(val zzz: String) { Z1("z1"), Z2("z2") } @Test fun runTest() { println(Zzz.Z1.isFrozen) } ================================================ FILE: backend.native/tests/codegen/enum/kt38540.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.kt38540 import kotlin.test.* public enum class Node( public val external: Boolean, public val dependsOn: Set, public val required: Boolean ) { A( external = false, dependsOn = emptySet(), required = true ), B( external = false, dependsOn = emptySet(), required = true ), C( external = true, dependsOn = emptySet(), required = true ), D( external = true, dependsOn = emptySet(), required = true ), E( external = true, dependsOn = emptySet(), required = true ), F( external = true, dependsOn = emptySet(), required = true ), G( external = true, dependsOn = emptySet(), required = false ), H( external = true, dependsOn = emptySet(), required = true ), I( external = true, dependsOn = emptySet(), required = true ), J( external = true, dependsOn = emptySet(), required = true ), K( external = true, dependsOn = setOf(I), required = true ), L( external = true, dependsOn = setOf(I), required = true ), M( external = true, dependsOn = setOf(I), required = true ), N( external = true, dependsOn = emptySet(), required = true ), O( external = true, dependsOn = emptySet(), required = true ), AG( external = true, dependsOn = emptySet(), required = true ), FIELD_REPORT( external = true, dependsOn = setOf(AG, O, J), required = true ) } @Test fun runTest() { assertTrue(Node.FIELD_REPORT.dependsOn.contains(Node.AG)) assertTrue(Node.FIELD_REPORT.dependsOn.contains(Node.O)) assertTrue(Node.FIELD_REPORT.dependsOn.contains(Node.J)) } ================================================ FILE: backend.native/tests/codegen/enum/lambdaInDefault.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.lambdaInDefault import kotlin.test.* enum class Zzz(val value: String.() -> Int = { length }) { Q() } @Test fun runTest() { println(Zzz.Q) } ================================================ FILE: backend.native/tests/codegen/enum/linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a enum class A(val x: Int) { Z1(42), Z2(117), Z3(-1) } ================================================ FILE: backend.native/tests/codegen/enum/linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* fun main(args: Array) { println(A.Z1.x) println(A.valueOf("Z2").x) println(A.values()[2].x) } ================================================ FILE: backend.native/tests/codegen/enum/loop.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.loop import kotlin.test.* enum class Zzz { Z { init { println(Z.name) } } } @Test fun runTest() { println(Zzz.Z) } ================================================ FILE: backend.native/tests/codegen/enum/nested.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.nested import kotlin.test.* enum class Foo { A; enum class Bar { C } } @Test fun runTest() { println(Foo.A) println(Foo.Bar.C) } ================================================ FILE: backend.native/tests/codegen/enum/reorderedArguments.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.reorderedArguments import kotlin.test.* // Regression test for https://github.com/JetBrains/kotlin-native/issues/1779 enum class Foo(val a: Int, val b: Int, val c: Int = 0) { A(a = 1, b = 0), B(b = 1, a = 0), C(c = 1, b = 0, a = 0), D(0, 0), E(1, 1, 1) } interface Base { val value: T } enum class Bar(override val value: Foo) : Base { A(Foo.A), B(Foo.B), C(Foo.C), D(Foo.D), E(Foo.E) } @Test fun runTest() { assertEquals(Foo.A.a, 1) assertEquals(Foo.A.b, 0) assertEquals(Foo.A.c, 0) assertEquals(Foo.B.a, 0) assertEquals(Foo.B.b, 1) assertEquals(Foo.B.c, 0) assertEquals(Foo.C.a, 0) assertEquals(Foo.C.b, 0) assertEquals(Foo.C.c, 1) assertEquals(Foo.D.a, 0) assertEquals(Foo.D.b, 0) assertEquals(Foo.D.c, 0) assertEquals(Foo.E.a, 1) assertEquals(Foo.E.b, 1) assertEquals(Foo.E.c, 1) assertEquals(Bar.A.value.a, 1) assertEquals(Bar.A.value.b, 0) assertEquals(Bar.A.value.c, 0) assertEquals(Bar.B.value.a, 0) assertEquals(Bar.B.value.b, 1) assertEquals(Bar.B.value.c, 0) assertEquals(Bar.C.value.a, 0) assertEquals(Bar.C.value.b, 0) assertEquals(Bar.C.value.c, 1) assertEquals(Bar.D.value.a, 0) assertEquals(Bar.D.value.b, 0) assertEquals(Bar.D.value.c, 0) assertEquals(Bar.E.value.a, 1) assertEquals(Bar.E.value.b, 1) assertEquals(Bar.E.value.c, 1) } ================================================ FILE: backend.native/tests/codegen/enum/switchLowering.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.switchLowering import kotlin.test.* enum class EnumA { A, B, C } enum class EnumB { A, B } enum class E { ONE, TWO, THREE } fun produceEntry() = EnumA.A // Check that we fail on comparison of different enum types. fun differentEnums() { println(when (produceEntry()) { EnumB.A -> "EnumB.A" EnumA.A -> "EnumA.A" EnumA.B -> "EnumA.B" else -> "nah" }) } // Nullable subject shouldn't be lowered. fun nullable() { val x: EnumA? = null when(x) { EnumA.A -> println("fail") else -> println("ok") } } // Operator overloading won't trick us! fun operatorOverloading() { operator fun E.contains(other: E): Boolean = false val y = E.ONE when(y) { in E.ONE -> println("Should not reach here") else -> println("ok") } } fun smoke1() { when (produceEntry()) { EnumA.B -> println("error") EnumA.A -> println("ok") EnumA.C -> println("error") } } fun smoke2() { when (produceEntry()) { EnumA.B -> println("error") else -> println("ok") } } fun eA() = EnumA.A fun eB() = EnumA.B fun nestedWhen() { println(when (eA()) { EnumA.A, EnumA.C -> when (eB()) { EnumA.B -> "ok" else -> "nope" } else -> "nope" }) } fun main() { differentEnums() nullable() operatorOverloading() smoke1() smoke2() nestedWhen() } ================================================ FILE: backend.native/tests/codegen/enum/test0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.test0 import kotlin.test.* val TOP_LEVEL = 5 enum class MyEnum(value: Int) { VALUE(TOP_LEVEL) } @Test fun runTest() { println(MyEnum.VALUE.toString()) } ================================================ FILE: backend.native/tests/codegen/enum/test1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.test1 import kotlin.test.* enum class Zzz(val zzz: String, val x: Int) { Z1("z1", 1), Z2("z2", 2) } @Test fun runTest() { println(Zzz.Z1.zzz + Zzz.Z2.x) } ================================================ FILE: backend.native/tests/codegen/enum/vCallNoEntryClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.vCallNoEntryClass import kotlin.test.* enum class Zzz(val zzz: String, val x: Int) { Z1("z1", 1), Z2("z2", 2), Z3("z3", 3); override fun toString(): String{ return "('$zzz', $x)" } } @Test fun runTest() { println(Zzz.Z3.toString()) } ================================================ FILE: backend.native/tests/codegen/enum/vCallWithEntryClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.vCallWithEntryClass import kotlin.test.* enum class Zzz { Z1 { override fun f() = "z1" }, Z2 { override fun f() = "z2" }; open fun f() = "" } @Test fun runTest() { println(Zzz.Z1.f() + Zzz.Z2.f()) } ================================================ FILE: backend.native/tests/codegen/enum/valueOf.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.valueOf import kotlin.test.* enum class E { E3, E1, E2 } @Test fun runTest() { println(E.valueOf("E1").toString()) println(E.valueOf("E2").toString()) println(E.valueOf("E3").toString()) println(enumValueOf("E1").toString()) println(enumValueOf("E2").toString()) println(enumValueOf("E3").toString()) } ================================================ FILE: backend.native/tests/codegen/enum/values.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.values import kotlin.test.* enum class E { E3, E1, E2 } @Test fun runTest() { println(E.values()[0].toString()) println(E.values()[1].toString()) println(E.values()[2].toString()) println(enumValues()[0].toString()) println(enumValues()[1].toString()) println(enumValues()[2].toString()) } ================================================ FILE: backend.native/tests/codegen/enum/varargParam.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.enum.varargParam import kotlin.test.* enum class Piece(vararg val states: Int) { I(3, 4, 5) } @Test fun runTest() { println(Piece.I.states[0]) } ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/recursion.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.recursion import kotlin.test.* class A { var f: A? = null } fun foo(k: Int, a1: A, a2: A): A { val a3 = A() if (k == 0) return a1 a3.f = a1 return foo(k - 1, a2, a3) } @Test fun runTest() { foo(3, A(), A()).toString() } ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test1.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test1 class A(val s: String) // ----- Agressive ----- // PointsTo: // RET.v@lue -> P0 // Escapes: // ----- Passive ----- // PointsTo: // RET.v@lue -> P0 // Escapes: fun foo(a: A) = a fun main() = println(foo(A("zzz"))) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test10.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test10 class G(val x: Int) class F(val s: String) { var g = G(0) } class A { var f = F("") } // ----- Agressive ----- // PointsTo: // P0.f -> D0 // RET.v@lue -> D0 // Escapes: // ----- Passive ----- // PointsTo: // P0.f -> D0 // RET.v@lue -> D0 // Escapes: D0 fun foo(a: A): F { val v = F("zzz") a.f = v return v } fun bar(): F { val w = A() val u = foo(w) w.f.g = G(42) return u } fun main() = println(bar().g.x) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test11.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test11 class F(val x: Int) class A(val s: String) { var f = F(0) } var f: F? = null // ----- Agressive ----- // PointsTo: // RET.v@lue -> P0.f // D0 -> P0.f // Escapes: D0 // ----- Passive ----- // PointsTo: // RET.v@lue -> P0.f // D0 -> P0.f // Escapes: D0 fun foo(a: A): F { f = a.f return a.f } fun main() = println(foo(A("zzz"))) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test12.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test12 class A(val s: String) // ----- Agressive ----- // PointsTo: // RET.v@lue -> P0.inte$tines // Escapes: // ----- Passive ----- // PointsTo: // RET.v@lue -> P0.inte$tines // Escapes: fun foo(arr: Array) = arr[0] fun main() = println(foo(arrayOf(A("zzz"))).s) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test13.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test13 class A { var f: A? = null } fun foo(a: A, k: Int): A { return if (k == 0) a else foo(a.f!!, k - 1) } fun main() { val a = A() a.f = A() println(foo(a, 1)) } ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test2.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test2 class A(val s: String) // ----- Agressive ----- // PointsTo: // RET.v@lue -> P0.s // Escapes: // ----- Passive ----- // PointsTo: // RET.v@lue -> P0.s // Escapes: fun foo(a: A) = a.s fun main() = println(foo(A("zzz"))) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test3.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test3 class A(val s: String) class B { var s: String? = null } // ----- Agressive ----- // PointsTo: // P1.s -> P0.s // RET.v@lue -> P0.s // Escapes: // ----- Passive ----- // PointsTo: // P1.s -> P0.s // RET.v@lue -> P0.s // Escapes: fun foo(a: A, b: B): String { b.s = a.s return a.s } fun main() = println(foo(A("zzz"), B())) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test4.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test4 class A(val s: String) class B { var f: A = A("qzz") } class C { var g: B = B() } // ----- Agressive ----- // PointsTo: // P0.g.f -> P1.g.f // RET.v@lue -> D0 // Escapes: D0 // ----- Passive ----- // PointsTo: // P0.g.f -> P1.g.f // RET.v@lue -> D0 // Escapes: D0 fun foo(c1: C, c2: C) { c1.g.f = c2.g.f } fun main() = println(foo(C(), C())) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test5.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test5 class A(val s: String) class B { var f: A = A("qzz") } class C { var g: B = B() } // ----- Agressive ----- // PointsTo: // RET.v@lue -> D0 // D0.f -> P0.g.f // Escapes: // ----- Passive ----- // PointsTo: // P0.g.f -> D2 // RET.v@lue -> D0 // D0.f -> P0.g.f // D0.f -> D1 // D1 -> D2 // Escapes: D0 D1 fun foo(c1: C, c2: C): B { val b = B() b.f = c1.g.f return b } fun main() = println(foo(C(), C())) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test6.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test6 class A(val s: String) class B { var f: A = A("qzz") } class C { var g: B = B() } // ----- Agressive ----- // PointsTo: // P1.g -> D0 // P2.g -> D0 // RET.v@lue -> P1.g // RET.v@lue -> P2.g // RET.v@lue -> D0 // D0.f -> P3 // Escapes: // ----- Passive ----- // PointsTo: // P1.g -> D0 // P2.g -> D0 // RET.v@lue -> P1.g // RET.v@lue -> P2.g // RET.v@lue -> D0 // D0.f -> P3 // Escapes: fun foo(z: Boolean, c1: C, c2: C, a: A): B { val v = if(z) c1.g else c2.g v.f = a return v } fun main() = println(foo(true, C(), C(), A("zzz"))) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test7.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test7 class A(val s: String) { var h: String = "" var p: C = C() } class B { var f: A = A("qzz") } class C { var g: A = A("") } class D { var o: A = A("") } // ----- Agressive ----- // PointsTo: // P1.g -> D0 // P2.f -> D0 // P4.o -> P1.g // P4.o -> P2.f // P4.o -> D0 // RET.v@lue -> D1 // D0.p -> P1 // D0.h -> P3 // Escapes: D1 // ----- Passive ----- // PointsTo: // P1.g -> D0 // P2.f -> D0 // P4.o -> P1.g // P4.o -> P2.f // P4.o -> D0 // RET.v@lue -> D1 // D0.p -> P1 // D0.h -> P3 // Escapes: D1 fun foo(z: Boolean, c: C, b: B, s: String, d: D) { val v = if(z) c.g else b.f v.h = s d.o = v val u = v u.p = c } fun main() = println(foo(true, C(), B(), "zzz", D())) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test8.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test8 class F(val s: String) { var g = F("") } class A { var f = F("qzz") } // ----- Agressive ----- // PointsTo: // P0.f -> D0 // RET.v@lue -> P0.f // RET.v@lue -> D0 // RET.v@lue -> D0.g // D0.g -> P0.f // D0.g -> D0 // Escapes: // ----- Passive ----- // PointsTo: // P0.f -> D0 // RET.v@lue -> P0.f // RET.v@lue -> D0 // RET.v@lue -> D0.g // D0.g -> P0.f // D0.g -> D0 // D0.g -> D2 // D1 -> D0 // D2 -> D0 // Escapes: D1 D2 fun foo(a: A): F { a.f = F("zzz") a.f.g = a.f return a.f.g.g } fun main() = println(foo(A()).s) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/test9.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.test9 class H(val x: Int) class F(val s: String) { var g = F("") var h = H(0) } class A { var f = F("qzz") } // ----- Agressive ----- // PointsTo: // P0.f -> P1.g // RET.v@lue -> P1.g.h // Escapes: // ----- Passive ----- // PointsTo: // P0.f -> P1.g // P1.g.h -> D0 // RET.v@lue -> P1.g.h // Escapes: D0 fun foo(a: A, f: F): H { a.f = f.g a.f.h = H(42) return f.g.h } fun main() = println(foo(A(), F("zzz")).x) ================================================ FILE: backend.native/tests/codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.escapeAnalysis.zeroOutObjectOnAlloc import kotlin.test.* class A { var x = 0 } @Test fun runTest() { var sum1 = 0 var sum2 = 0 for (i in 0 until 10) { val a = A() sum1 += a.x a.x = i sum2 += a.x } assertEquals(0, sum1) assertEquals(45, sum2) } ================================================ FILE: backend.native/tests/codegen/funInterface/implIsNotFunction.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.funInterface.implIsNotFunction import kotlin.test.* fun interface Foo { fun invoke(): String } fun foo(f: Foo) = f is Function<*> @Test fun test() { assertFalse(foo { "zzz" }) } ================================================ FILE: backend.native/tests/codegen/funInterface/kt43887.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.funInterface.kt43887 import kotlin.test.* import kotlinx.cinterop.* typealias heap_t = IntVar fun heap_create(size: Long): CPointer? = null fun heap_alloc(heap: CPointer?, size: ULong): CPointer<*>? = null fun heap_free(heap: CPointer?, ptr: CPointer<*>?): CPointer? = null inline fun Heap(size: Long): CPointer? { return heap_create(size) } inline fun CPointer?.use(f: (CPointer) -> Unit) { alloc() ?.also(f) ?.also(::free) } inline fun CPointer?.alloc(): CPointer? { return heap_alloc(this, sizeOf().toULong())?.reinterpret() } inline fun CPointer?.free(ptr: CPointer<*>?): Boolean { return heap_free(this, ptr)?.pointed?.value ?: false } @Test fun runTest(): Unit = memScoped { val heap = Heap(1024) heap.use { ptr -> ptr.pointed.value = 40 //println("PTR ${ptr.pointed}") } } ================================================ FILE: backend.native/tests/codegen/funInterface/nonTrivialProjectionInSuperType.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.funInterface.nonTrivialProjectionInSuperType import kotlin.test.* fun foo(comparator: kotlin.Comparator, a: T, b: T) = comparator.compare(a, b) fun bar(x: Int, y: Int) = foo ({ a, b -> a - b}, x, y) @Test fun test() { assertTrue(bar(42, 117) < 0) } ================================================ FILE: backend.native/tests/codegen/function/arithmetic.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.arithmetic import kotlin.test.* fun square(a:Int):Int = a * a fun sumOfSquares(a:Int, b:Int):Int = square(a) + square(b) fun diffOfSquares(a:Int, b:Int):Int = square(a) - square(b) fun mod(a:Int,b:Int):Int = a / b fun remainder(a:Int, b:Int):Int = a % b @Test fun runTest() { if (square(2) != 4) throw Error() if (sumOfSquares(2, 4) != 20) throw Error() if (diffOfSquares(2, 4) != -12) throw Error() if (mod(5, 2) != 2) throw Error() if (remainder(5, 2) != 1) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/boolean.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.boolean import kotlin.test.* fun bool_yes(): Boolean = true @Test fun runTest() { if (!bool_yes()) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/defaults.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults import kotlin.test.* /** * Created by minamoto on 12/26/16. */ //package defaults open class A(val a:Int) { override fun equals(other: Any?): Boolean { if (other == null || other as? A == null) return false return (other as A).a == a // Where is smart casting? } companion object { val zero = A(0) val one = A(1) val magic = A(42) } } // FUN public fun foo(a: defaults.A = ...): kotlin.Int // a: EXPRESSION_BODY // CALL '(): A' type=defaults.A origin=GET_PROPERTY // $this: GET_OBJECT 'companion object of A' type=defaults.A.Companion // BLOCK_BODY // RETURN type=kotlin.Nothing from='foo(A = ...): Int' // CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY // $this: GET_VAR 'value-parameter a: A = ...' type=defaults.A origin=null fun foo(a: A = A.magic, b:Int = 0xdeadbeef.toInt()) = a.a // FUN public fun bar(a: defaults.A, inc: kotlin.Int = ...): defaults.A // inc: EXPRESSION_BODY // CONST Int type=kotlin.Int value='0' // BLOCK_BODY // RETURN type=kotlin.Nothing from='bar(A, Int = ...): A' // CALL 'constructor A(Int)' type=defaults.A origin=null // a: CALL 'plus(Int): Int' type=kotlin.Int origin=PLUS // $this: CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY // $this: GET_VAR 'value-parameter a: A' type=defaults.A origin=null // other: GET_VAR 'value-parameter inc: Int = ...' type=kotlin.Int origin=null fun bar(a:A, inc:Int = 0) = A(a.a + inc) @Test fun runTest() { // if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'foo(A = ...): Int' type=kotlin.Int origin=null // arg1: CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY // $this: CALL '(): A' type=defaults.A origin=GET_PROPERTY // $this: GET_OBJECT 'companion object of A' type=defaults.A.Companion if (foo() != A.magic.a) { println("magic failed") throw Error() } // if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'foo(A = ...): Int' type=kotlin.Int origin=null // a: CALL 'constructor A(Int)' type=defaults.A origin=null // a: CONST Int type=kotlin.Int value='1' // arg1: CONST Int type=kotlin.Int value='1' if (foo(A(1)) != 1) { println("one failed: foo(A(1))") throw Error() } // if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'bar(A, Int = ...): A' type=defaults.A origin=null // a: CALL '(): A' type=defaults.A origin=GET_PROPERTY <--- // $this: GET_OBJECT 'companion object of A' type=defaults.A.Companion // arg1: CALL '(): A' type=defaults.A origin=GET_PROPERTY // $this: GET_OBJECT 'companion object of A' type=defaults.A.Companion if (bar(A.one) != A.one) { println("A one failed") throw Error() } // if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ // arg0: CALL '(): Int' type=kotlin.Int origin=GET_PROPERTY // $this: CALL 'bar(A, Int = ...): A' type=defaults.A origin=null // a: CALL '(): A' type=defaults.A origin=GET_PROPERTY // $this: GET_OBJECT 'companion object of A' type=defaults.A.Companion // inc: CONST Int type=kotlin.Int value='1' // arg1: CONST Int type=kotlin.Int value='2' if (bar(A.one, 1).a != 2) { println("A one + 1 failed") throw Error() } println("all tests passed") } ================================================ FILE: backend.native/tests/codegen/function/defaults1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults1 import kotlin.test.* fun foo(x:Int = 0, y:Int = x + 1, z:Int = x + y + 1) = x + y + z @Test fun runTest() { val v = foo() if (v != 3) { println("test failed $v expected 3") throw Error() } } ================================================ FILE: backend.native/tests/codegen/function/defaults10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults10 import kotlin.test.* enum class A(one: Int, val two: Int = one) { FOO(42) } @Test fun runTest() { println(A.FOO.two) } ================================================ FILE: backend.native/tests/codegen/function/defaults2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults2 import kotlin.test.* fun Int.foo(inc0:Int, inc:Int = 0) = this + inc0 + inc @Test fun runTest() { val v = 42.foo(0) if (v != 42) { println("test failed v:$v expected:42") throw Error() } } ================================================ FILE: backend.native/tests/codegen/function/defaults3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults3 import kotlin.test.* fun foo(a:Int = 2, b:String = "Hello", c:Int = 4):String = "$b-$c$a" fun foo(a:Int = 3, b:Int = a + 1, c:Int = a + b) = a + b + c @Test fun runTest() { val a = foo(b="Universe") if (a != "Universe-42") throw Error() val b = foo(b = 5) if (b != (/* a = */ 3 + /* b = */ 5 + /* c = */ (3 + 5))) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/defaults4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults4 import kotlin.test.* open class A { open fun foo(x: Int = 42) = println(x) } open class B : A() class C : B() { override fun foo(x: Int) = println(x + 1) } @Test fun runTest() { C().foo() } ================================================ FILE: backend.native/tests/codegen/function/defaults5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults5 import kotlin.test.* class TestClass(val x: Int) { fun foo(y: Int = x) { println(y) } } fun TestClass.bar(y: Int = x) { println(y) } @Test fun runTest() { TestClass(5).foo() TestClass(6).bar() } ================================================ FILE: backend.native/tests/codegen/function/defaults6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults6 import kotlin.test.* open class Foo(val x: Int = 42) class Bar : Foo() @Test fun runTest() { println(Bar().x) } ================================================ FILE: backend.native/tests/codegen/function/defaults7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults7 import kotlin.test.* /** * Test fails with code generation: * Call parameter type does not match function signature! * %5 = invoke %struct.ObjHeader* @"kfun:kotlin.native.internal.boxInt(kotlin.Int)"(i32 1, %struct.ObjHeader** %4) * to label %label_ unwind label %cleanup_landingpad * i32 invoke void @"kfun:foo$default(kotlin.Int;kotlin.Int;kotlin.Int)"(%struct.ObjHeader* %5, i32 0, i32 2) * to label %label_1 unwind label %cleanup_landingpad */ fun foo(a : T, b : Int = 42){ println(b) } @Test fun runTest() { foo(1) } ================================================ FILE: backend.native/tests/codegen/function/defaults8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults8 import kotlin.test.* class Foo { fun test(x: Int = 1) = x } class Bar { fun test(x: Int = 2) = x } @Test fun runTest() { println(Bar().test()) } ================================================ FILE: backend.native/tests/codegen/function/defaults9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaults9 import kotlin.test.* class Foo { inner class Bar(x: Int, val y: Int = 1) { constructor() : this(42) } } @Test fun runTest() = println(Foo().Bar().y) ================================================ FILE: backend.native/tests/codegen/function/defaultsFromFakeOverride.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaultsFromFakeOverride import kotlin.test.* interface I { fun f(x: String = "42"): String } open class A { open fun f(x: String) = x } class B : A(), I @Test fun runTest() { val b = B() println(b.f()) } ================================================ FILE: backend.native/tests/codegen/function/defaultsWithInlineClasses.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaultsWithInlineClasses import kotlin.test.* inline class Foo(val value: Int) fun foo(x: Foo = Foo(42)) = x.value @Test fun runTest() { assertEquals(foo(), 42) assertEquals(foo(Foo(17)), 17) } ================================================ FILE: backend.native/tests/codegen/function/defaultsWithVarArg1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaultsWithVarArg1 import kotlin.test.* fun foo(s: String = "", vararg args: Any) { if (args == null) { println("Failed!") } else { print("$s ") args.forEach { print("$it") } println(", Correct!") } } @Test fun runTest() { foo("Hello") foo("Hello", "World") foo() } ================================================ FILE: backend.native/tests/codegen/function/defaultsWithVarArg2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.defaultsWithVarArg2 import kotlin.test.* fun foo(vararg arr: Int = intArrayOf(1, 2)) { arr.forEach { println(it) } } @Test fun runTest() { foo() foo(42) } ================================================ FILE: backend.native/tests/codegen/function/eqeq.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.eqeq import kotlin.test.* fun eqeqB (a:Byte, b:Byte ) = a == b fun eqeqS (a:Short, b:Short ) = a == b fun eqeqI (a:Int, b:Int ) = a == b fun eqeqL (a:Long, b:Long ) = a == b fun eqeqF (a:Float, b:Float ) = a == b fun eqeqD (a:Double, b:Double) = a == b fun eqeqStr(a:String, b:String) = a == b fun eqeqN (a: Nothing, b: Nothing) = a == b fun eqeqNN (a: Nothing?, b: Nothing?) = a == b fun eqeqeq (a: Any?, b: Any?) = a === b fun gtI (a:Int, b:Int ) = a > b fun ltI (a:Int, b:Int ) = a < b fun geI (a:Int, b:Int ) = a >= b fun leI (a:Int, b:Int ) = a <= b fun neI (a:Int, b:Int ) = a != b fun gtF (a:Float, b:Float ) = a > b fun ltF (a:Float, b:Float ) = a < b fun geF (a:Float, b:Float ) = a >= b fun leF (a:Float, b:Float ) = a <= b fun neF (a:Float, b:Float ) = a != b fun helloString() = "Hello" fun goodbyeString() = "Goodbye" @Test fun runTest() { if (!eqeqB(3 , 3 )) throw Error() if (!eqeqS(3 , 3 )) throw Error() if (!eqeqI(3 , 3 )) throw Error() if (!eqeqL(3L , 3L )) throw Error() if (!eqeqF(3.0f, 3.0f)) throw Error() if (!eqeqD(3.0 , 3.0 )) throw Error() if (!eqeqStr(helloString(), helloString())) throw Error() if (!eqeqNN(null, null)) throw Error() if (!eqeqeq(helloString(), helloString())) throw Error() if (eqeqeq(helloString(), goodbyeString())) throw Error() if (gtI (2 , 3 )) throw Error() if (ltI (3 , 2 )) throw Error() if (geI (2 , 3 )) throw Error() if (leI (3 , 2 )) throw Error() if (neI (2 , 2 )) throw Error() if (gtF (2.0f , 3.0f )) throw Error() if (ltF (3.0f , 2.0f )) throw Error() if (geF (2.0f , 3.0f )) throw Error() if (leF (3.0f , 2.0f )) throw Error() if (neF (2.0f , 2.0f )) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/extension.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ class B(val a: Int) fun B.foo() = this.a ================================================ FILE: backend.native/tests/codegen/function/intrinsic.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.intrinsic import kotlin.test.* // This code fails to link when bultins are taken from the // frontend generated module, instead of our library. // Because the generated module doesn't see our name changing annotations, // the function names are all wrong. fun intrinsic(b: Int): Int { var sum = 1 sum = sum + b return sum } @Test fun runTest() { if (intrinsic(3) != 4) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/localFunction.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.localFunction import kotlin.test.* @Test fun runTest() { val x = 1 fun local0() = println(x) fun local1() { fun local2() { local1() } local0() } fun l1() { var x = 1 fun l2() { fun l3() { l1() x = 5 } l3() } } println("OK") } ================================================ FILE: backend.native/tests/codegen/function/localFunction2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.localFunction2 import kotlin.test.* @Test fun runTest() { var a = 0 fun local() { class A { val b = 0 fun f() { a = b } } fun local2() : A { return A() } } println("OK") } ================================================ FILE: backend.native/tests/codegen/function/localFunction3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.localFunction3 import kotlin.test.* @Test fun runTest() { fun bar() { fun local1() { bar() } local1() var x = 0 fun local2() { x++ bar() } local2() } println("OK") } ================================================ FILE: backend.native/tests/codegen/function/minus_eq.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.minus_eq import kotlin.test.* fun minus_eq(a: Int): Int { var b = 11 b -= a return b } @Test fun runTest() { if (minus_eq(23) != -12) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/named.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.named import kotlin.test.* fun foo(a:Int, b:Int) = a - b @Test fun runTest() { if (foo(b = 24, a = 42) != 18) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/plus_eq.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.plus_eq import kotlin.test.* fun plus_eq(a: Int): Int { var b = 11 b += a return b } @Test fun runTest() { if (plus_eq(3) != 14) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/referenceBigArity.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.referenceBigArity import kotlin.test.* fun фу(а: Int, б: Int, в: Int, г: Int, д: Int, е: Int, ё: Int, ж: Int, з: Int, и: Int, й: Int, к: Int, л: Int, м: Int, н: Int, о: Int, п: Int, р: Int, с: Int, т: Int, у: Int, ф: Int, х: Int, ц: Int, ч: Int, ш: Int, щ: Int, ъ: Int, ы: Int, ь: Int, э: Int, ю: Int, я: Int): Int { return а + б + в + г + д + е + ё + ж + з + и + й + к + л + м + н + о + п + р + с + т + у + ф + х + ц + ч + ш + щ + ъ + ы + ь + э + ю + я } @Test fun runTest() { val ref = ::фу println(ref(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)) } ================================================ FILE: backend.native/tests/codegen/function/sum.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum import kotlin.test.* fun sumIB(a:Int, b:Byte ) = a + b fun sumIS(a:Int, b:Short ) = a + b fun sumII(a:Int, b:Int ) = a + b fun sumIL(a:Int, b:Long ) = a + b fun sumIF(a:Int, b:Float ) = a + b fun sumID(a:Int, b:Double) = a + b fun modID(a:Int, b:Double) = a % b @Test fun runTest() { if (sumIB(2, 3) != 5) throw Error() if (sumIS(2, 3) != 5) throw Error() if (sumII(2, 3) != 5) throw Error() if (sumIL(2, 3L) != 5L) throw Error() if (sumIF(2, 3.0f) != 5.0f) throw Error() if (sumID(2, 3.0) != 5.0) throw Error() if (modID(5, 3.0) != 2.0) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/sum_3const.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_3const import kotlin.test.* fun sum3():Int = sum(1, 2, 33) fun sum(a:Int, b:Int, c:Int): Int = a + b + c @Test fun runTest() { if (sum3() != 36) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/sum_foo_bar.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_foo_bar import kotlin.test.* fun foo(a:Int):Int = a fun bar(a:Int):Int = a fun sumFooBar(a:Int, b:Int):Int = foo(a) + bar(b) @Test fun runTest() { if (sumFooBar(2, 3) != 5) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/sum_func.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_func import kotlin.test.* fun foo():Int = 1 //fun bar():Int = 2 //fun sum():Int = foo() + bar() // FIXME: has no checks ================================================ FILE: backend.native/tests/codegen/function/sum_imm.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_imm import kotlin.test.* fun sum(a:Int): Int = a + 33 @Test fun runTest() { if (sum(2) != 35) throw Error() } ================================================ FILE: backend.native/tests/codegen/function/sum_mixed.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_mixed import kotlin.test.* // FIXME: has no checks fun sum(a:Float, b:Int) = a + b ================================================ FILE: backend.native/tests/codegen/function/sum_silly.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.function.sum_silly import kotlin.test.* // FIXME: has no checks fun sum(a:Int, b:Int):Int { var c:Int c = a + b return c } ================================================ FILE: backend.native/tests/codegen/initializers/correctOrder1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.initializers.correctOrder1 import kotlin.test.* class TestClass { val x: Int init { x = 42 } val y = x } @Test fun runTest() { println(TestClass().y) } ================================================ FILE: backend.native/tests/codegen/initializers/correctOrder2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.initializers.correctOrder2 import kotlin.test.* class TestClass { val x: Int val y = 42 init { x = y } } @Test fun runTest() { println(TestClass().x) } ================================================ FILE: backend.native/tests/codegen/initializers/linkTest1_lib.kt ================================================ val a = 10 val b = a * 6 val c = a * b * 2 ================================================ FILE: backend.native/tests/codegen/initializers/linkTest1_main.kt ================================================ fun main() = println(c) ================================================ FILE: backend.native/tests/codegen/initializers/linkTest2_lib.kt ================================================ val a = mutableListOf() val b = 1.also { a += 2 } val c = a.single() ================================================ FILE: backend.native/tests/codegen/initializers/linkTest2_main.kt ================================================ fun main() = println(c) ================================================ FILE: backend.native/tests/codegen/initializers/sharedVarInInitBlock_lib.kt ================================================ class A { val x: Int init { var y = 10 fun foo() { y = 42 } foo() x = y } } ================================================ FILE: backend.native/tests/codegen/initializers/sharedVarInInitBlock_main.kt ================================================ import kotlin.test.* fun main() = assertEquals(42, (A().x)) ================================================ FILE: backend.native/tests/codegen/inline/changingCapturedLocal.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.changingCapturedLocal import kotlin.test.* var log = "" inline fun foo(x: Int, action: (Int) -> Unit) = action(x) fun box(): String { var x = 23 foo(x) { log += "$it;" x++ log += "$it;" } if (log != "23;23;") return "fail1: $log" if (x != 24) return "fail2: $x" return "OK" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/inline/classDeclarationInsideInline.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.classDeclarationInsideInline import kotlin.test.* fun f() { run { class Test1(val x: T, val y: G) { override fun toString() = "test1: ${x.toDouble()}" } class Test2(val a: Test1) { override fun toString() = "test2" } val v = Test2(Test1(1, Test2(Test1(1, 3)))) println(v.a) println(v.a.x) println(v.a.y) } } @Test fun test() { f() } ================================================ FILE: backend.native/tests/codegen/inline/coercionToUnit.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.coercionToUnit import kotlin.test.* fun myRun(action: () -> T): T = action() fun foo(n: Number, b: Boolean) { n.let { if (b) return@let myRun() { 42 } } } @Test fun runTest() { println(foo(42, false)) } ================================================ FILE: backend.native/tests/codegen/inline/correctOrderFunctionReference.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.correctOrderFunctionReference import kotlin.test.* class Foo(val a: String) { fun test() = a } inline fun test(a: String, b: () -> String, c: () -> String, d: () -> String, e: String): String { return a + b() + c() + d() + e } var effects = "" fun create(a: String): Foo { effects += a return Foo(a) } fun create2(a: String, f: () -> String): Foo { effects += a return Foo(a) } fun box(): String { val result = test(create("A").a, create("B")::a, create("C")::test, create2("E", create("D")::test)::test, create("F").a) if (effects != "ABCDEF") return "fail 1: $effects" return if (result == "ABCEF") "OK" else "fail 2: $result" } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/inline/defaultArgs.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.defaultArgs import kotlin.test.* class Z inline fun Z.foo(x: Int = 42, y: Int = x) { println(y) } @Test fun runTest() { val z = Z() z.foo() } ================================================ FILE: backend.native/tests/codegen/inline/defaultArgs_linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a inline fun foo(x: Int, y: Int = 117) = x + y ================================================ FILE: backend.native/tests/codegen/inline/defaultArgs_linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* fun main(args: Array) { println(foo(5)) println(foo(5, 42)) } ================================================ FILE: backend.native/tests/codegen/inline/genericFunctionReference.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.genericFunctionReference import kotlin.test.* class Z(val x: T) inline fun foo(x: T, f: (T) -> R): R { return f(x) } @Test fun runTest() { val arr = Array(1) { foo(it, ::Z) } println(arr[0].x) } ================================================ FILE: backend.native/tests/codegen/inline/getClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.getClass import kotlin.test.* fun foo() { val cls1: Any? = Int val cls2: Any? = null cls1?.let { cls2?.let { var itClass = it::class } } } @Test fun runTest() { println("OK") } ================================================ FILE: backend.native/tests/codegen/inline/inline0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline0 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i1: Int, j1: Int): Int { return i1 + j1 } fun bar(i: Int, j: Int): Int { return i + foo(i, j) } @Test fun runTest() { println(bar(41, 2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline1 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(s4: String, s5: String): String { return s4 + s5 } fun bar(s1: String, s2: String, s3: String): String { return s1 + foo(s2, s3) } @Test fun runTest() { println(bar("Hello ", "wor", "ld")) } ================================================ FILE: backend.native/tests/codegen/inline/inline10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline10 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i2: Int, body: () -> Int): Int { return i2 + body() } fun bar(i1: Int): Int { return foo(i1) { 1 } } @Test fun runTest() { println(bar(1).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline11 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo (i2: Any): Boolean { return i2 is T } fun bar(i1: Int): Boolean { return foo(i1) } @Test fun runTest() { println(bar(1).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline12.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline12 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo (): Boolean { return Any() is Any } fun bar(i1: Int): Boolean { return foo() } @Test fun runTest() { println(bar(1).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline13.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline13 import kotlin.test.* open class A() class B() : A() @Suppress("NOTHING_TO_INLINE") inline fun > foo(f: Any?): Boolean { return f is T? } fun bar(): Boolean { return foo>(B()) } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline14.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline14 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo3(i3: Int): Int { return i3 + 3 } @Suppress("NOTHING_TO_INLINE") inline fun foo2(i2: Int): Int { return i2 + 2 } @Suppress("NOTHING_TO_INLINE") inline fun foo1(i1: Int): Int { return foo2(i1) } fun bar(i0: Int): Int { return foo1(i0) + foo3(i0) } @Test fun runTest() { println(bar(2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline15.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline15 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo2(i1: Int): Int { return i1 + 1 } @Suppress("NOTHING_TO_INLINE") inline fun foo1(i1: Int, body: (Int) -> Int): Int { return body(i1) } fun bar(i0: Int): Int { return foo1(i0) { foo2(it) + 1 } } @Test fun runTest() { println(bar(2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline16.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline16 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun > foo(destination: C, predicate: (T) -> Boolean): C { for (element in destination) { val value = element as T if (!predicate(value)) destination.add(value) } return destination } fun bar(): Boolean { val result = foo > (mutableListOf(1, 2, 3)) { true } return result.isEmpty() } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline17.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline17 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i1: T, i2: T): List { val j1 = i1 val j2 = i2 return listOf(j1, j2) } fun bar(): List { return foo (1, 2) } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline18.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline18 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo2(i2: T, j2: T, p2: (T, T) -> Boolean): Boolean { return p2(i2, j2) } @Suppress("NOTHING_TO_INLINE") inline fun foo1(i1: T, j1: T, p1: (T, T) -> Boolean): Boolean { return foo2(i1, j1, p1) } fun bar(): Boolean { val result = foo1 (3, 3) { x1: Int, x2: Int -> x1 == x2 } return result } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline19.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline19 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline private fun foo(i: Int): Int { val result = i return result + i } fun bar(): Int { return foo(1) + foo(2) } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline2 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i4: Int, i5: Int) { println("hello $i4 $i5") } fun bar(i1: Int, i2: Int) { foo(i1, i2) } @Test fun runTest() { bar(1, 8) } ================================================ FILE: backend.native/tests/codegen/inline/inline20.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline20 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun bar(block: () -> String) : String { return block() } fun bar2() : String { return bar { return "def" } } @Test fun runTest() { println(bar2()) } ================================================ FILE: backend.native/tests/codegen/inline/inline21.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline21 import kotlin.test.* inline fun foo2(block2: () -> Int) : Int { println("foo2") return block2() } inline fun foo1(block1: () -> Int) : Int { println("foo1") return foo2(block1) } fun bar(block: () -> Int) : Int { println("bar") return foo1(block) } @Test fun runTest() { println(bar { 33 }) } ================================================ FILE: backend.native/tests/codegen/inline/inline22.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline22 import kotlin.test.* inline fun foo2(i2: Int): Int { return i2 + 3 } inline fun foo1(i1: Int): Int { return foo2(i1) } fun bar(): Int { return foo1(11) } @Test fun runTest() { println(bar().toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline23.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline23 import kotlin.test.* inline fun foo(i2: Any): T { return i2 as T } fun bar(i1: Int): Int { return foo(i1) } @Test fun runTest() { println(bar(33)) } ================================================ FILE: backend.native/tests/codegen/inline/inline24.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline24 import kotlin.test.* fun foo() = println("foo") fun bar() = println("bar") inline fun baz(x: Unit = foo(), y: Unit) {} @Test fun runTest() { baz(y = bar()) } ================================================ FILE: backend.native/tests/codegen/inline/inline25.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline25 import kotlin.test.* inline fun foo(block: String.() -> Unit) { "Ok".block() } inline fun bar(block: (String) -> Unit) { foo(block) } inline fun baz(block: String.() -> Unit) { block("Ok") } @Test fun runTest() { bar { println(it) } baz { println(this) } } ================================================ FILE: backend.native/tests/codegen/inline/inline26.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline26 import kotlin.test.* inline fun call(block1: () -> Unit, noinline block2: () -> Int): Int { block1() return block2() } @Test fun runTest() { var x = 5 println(call({ x = 7 }, x::toInt)) } ================================================ FILE: backend.native/tests/codegen/inline/inline3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline3 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i4: Int, i5: Int): Int { try { return i4 / i5 } catch (e: Throwable) { return i4 } } fun bar(i1: Int, i2: Int, i3: Int): Int { return i1 + foo(i2, i3) } @Test fun runTest() { println(bar(1, 8, 2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline4 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i4: Int, i5: Int): Int { if (i4 > 0) return i4 return i5 } fun bar(i1: Int, i2: Int): Int { return foo(i1, i2) } @Test fun runTest() { println(bar(3, 8).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline5 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i2: Int, body: () -> Int): Int { return i2 + body() } fun bar(i1: Int): Int { return foo(i1) { return 33 } } @Test fun runTest() { println(bar(1).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline6 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(body: () -> Unit) { println("hello1") body() println("hello4") } fun bar() { foo { println("hello2") println("hello3") } } @Test fun runTest() { bar() } ================================================ FILE: backend.native/tests/codegen/inline/inline7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline7 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(vararg args: Int) { for (a in args) { println(a.toString()) } } fun bar() { foo(1, 2, 3) } @Test fun runTest() { bar() } ================================================ FILE: backend.native/tests/codegen/inline/inline8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline8 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i3: Int, i4: Int) : Int { return i3 + i3 + i4 } fun bar(i1: Int, i2: Int) : Int { return foo(i1 + i2, 2) } @Test fun runTest() { println(bar(1, 2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inline9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.inline9 import kotlin.test.* @Suppress("NOTHING_TO_INLINE") inline fun foo(i3: Int, i4: Int): Int { return i3 + i3 + i4 } fun quiz(i: Int) : Int { println("hello") return i + 1 } fun bar(i1: Int, i2: Int): Int { return foo(quiz(i1), i2) } @Test fun runTest() { println(bar(1, 2).toString()) } ================================================ FILE: backend.native/tests/codegen/inline/inlineCtor_linkTest_lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a fun foo(n: Int, block: (Int) -> Int): Int { val arr = IntArray(n) { block(it) } var sum = 0 for (x in arr) sum += x return sum } ================================================ FILE: backend.native/tests/codegen/inline/inlineCtor_linkTest_main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* import kotlin.test.* fun main() { assertEquals(42, foo(7) { it * 2 }) } ================================================ FILE: backend.native/tests/codegen/inline/lambdaAsAny.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.lambdaAsAny import kotlin.test.* inline fun foo(x: Any) { println(if (x === x) "Ok" else "Fail") } @Test fun runTest() { foo { 42 } } ================================================ FILE: backend.native/tests/codegen/inline/lambdaInDefaultValue.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.lambdaInDefaultValue import kotlin.test.* inline fun inlineFun(param: String, lambda: (String) -> String = { it }): String { return lambda(param) } fun box(): String { return inlineFun("OK") } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/inline/lateinitProperty_linkTest_lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a fun IntArray.forEachNoInline(block: (Int) -> Unit) = this.forEach { block(it) } inline fun foo(values: IntArray, crossinline block: (Int, Int, Int) -> Int): Int { val o = object { lateinit var s: String var x: Int = 42 } values.forEachNoInline { o.x = block(o.x, o.s.length, it) } return o.x } ================================================ FILE: backend.native/tests/codegen/inline/lateinitProperty_linkTest_main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* fun main() { try { val res = foo(intArrayOf(1, 2, 3)) { x, y, z -> x + y - z } println(res) } catch (t: UninitializedPropertyAccessException) { println("OK") } } ================================================ FILE: backend.native/tests/codegen/inline/localFunctionInInitializerBlock.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.localFunctionInInitializerBlock import kotlin.test.* class Foo { init { bar() } } inline fun bar() { println({ "Ok" }()) } @Test fun runTest() { Foo() } ================================================ FILE: backend.native/tests/codegen/inline/localObjectReturnedFromWhen.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.localObjectReturnedFromWhen import kotlin.test.* fun foo() { 123?.let { object : () -> Unit { override fun invoke() = Unit } } } @Test fun runTest() { foo() println("Ok") } ================================================ FILE: backend.native/tests/codegen/inline/propertyAccessorInline.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.propertyAccessorInline import kotlin.test.* object C { const val x = 42 } fun getC(): C { println(123) return C } @Test fun runTest() { println(getC().x) } ================================================ FILE: backend.native/tests/codegen/inline/returnLocalClassFromBlock.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.returnLocalClassFromBlock import kotlin.test.* inline fun call(block: ()->R): R { try { return block() } finally { println("Zzz") } } @Test fun runTest() { call { class Z(); Z() } } ================================================ FILE: backend.native/tests/codegen/inline/sharedVar_linkTest_lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a fun IntArray.forEachNoInline(block: (Int) -> Unit) = this.forEach { block(it) } inline fun fold(initial: Int, values: IntArray, crossinline block: (Int, Int) -> Int): Int { var res = initial values.forEachNoInline { res = block(res, it) } return res } ================================================ FILE: backend.native/tests/codegen/inline/sharedVar_linkTest_main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.* fun main() { println(fold(0, intArrayOf(1, 2, 3)) { x, y -> x + y }) } ================================================ FILE: backend.native/tests/codegen/inline/statementAsLastExprInBlock.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.statementAsLastExprInBlock import kotlin.test.* fun foo() { val cls1: Any? = Int val cls2: Any? = null cls1?.let { if (cls2 != null) { val zzz = 42 } } } @Test fun runTest() { println("OK") } ================================================ FILE: backend.native/tests/codegen/inline/twiceInlinedObject.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.twiceInlinedObject import kotlin.test.* inline fun exec(f: () -> Unit) = f() inline fun test2() { val obj = object { fun sayOk() = println("Ok") } obj.sayOk() } inline fun noExec(f: () -> Unit) { } @Test fun runTest() { exec { test2() } noExec { test2() } } ================================================ FILE: backend.native/tests/codegen/inline/typeSubstitutionInFakeOverride.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inline.typeSubstitutionInFakeOverride import kotlin.test.* abstract class A { inline fun baz(): String { return T::class.simpleName!! } } class B : A() { fun bar(): String { return baz() } } class OK @Test fun runTest() { println(B().bar()) } ================================================ FILE: backend.native/tests/codegen/inlineClass/customEquals.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("RESERVED_MEMBER_INSIDE_INLINE_CLASS") package codegen.inlineClass.customEquals import kotlin.test.* private inline class Z(val data: Int) { override fun equals(other: Any?) = other is Z && data % 256 == other.data % 256 } @Test fun runTest() { assertTrue(Z(0) == Z(256)) } ================================================ FILE: backend.native/tests/codegen/inlineClass/defaultEquals.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inlineClass.defaultEquals import kotlin.test.* inline class A(val x: Int) inline class B(val a: A) inline class C(val s: String) inline class D(val c: C) @Test fun runTest() { val a = A(42) val b = B(a) val c = C("zzz") val d = D(c) assertTrue(a.equals(a)) assertTrue(b.equals(b)) assertTrue(c.equals(c)) assertTrue(d.equals(d)) } ================================================ FILE: backend.native/tests/codegen/inlineClass/inlineClass0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inlineClass.inlineClass0 import kotlin.test.* // Based on KT-27225. inline class First(val value: Int) inline class Second(val value: First) { constructor(c: Int) : this(First(c)) } @Test fun runTest() { assertEquals(Second(42).value.value, 42) } ================================================ FILE: backend.native/tests/codegen/inlineClass/nestedInlineClasses.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inlineClass.nestedInlineClasses import kotlin.test.* interface I { inline class IC(val x: Int) } interface I2 { inline class IC(val x: Int) } @Test fun runTest() { assertEquals(42, I.IC(42).x) assertEquals(117, I2.IC(117).x) } ================================================ FILE: backend.native/tests/codegen/inlineClass/secondaryConstructorWithGenerics.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inlineClass.secondaryConstructorWithGenerics import kotlin.test.* // Based on KT-42649. inline class IC(val value: List) { constructor(value: T) : this(listOf(value)) } @Test fun runTest() { assertEquals("abc", IC("abc").value.singleOrNull()) } ================================================ FILE: backend.native/tests/codegen/inlineClass/valueClass0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.inlineClass.valueClass0 import kotlin.test.* // Based on KT-27225. value class First(val value: Int) value class Second(val value: First) { constructor(c: Int) : this(First(c)) } @Test fun runTest() { assertEquals(Second(42).value.value, 42) } ================================================ FILE: backend.native/tests/codegen/innerClass/doubleInner.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.doubleInner import kotlin.test.* open class Father(val param: String) { abstract inner class InClass { fun work(): String { return param } } inner class Child(p: String) : Father(p) { inner class Child2 : Father.InClass { constructor(): super() } } } fun box(): String { return Father("fail").Child("OK").Child2().work() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/innerClass/generic.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.generic import kotlin.test.* class Outer { inner class Inner(val t: T) { fun box() = t } } fun box(): String { if (Outer().Inner("OK").box() != "OK") return "Fail" val x: Outer.Inner = Outer().Inner("OK") return x.box() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/innerClass/getOuterVal.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.getOuterVal import kotlin.test.* class Outer(val s: String) { inner class Inner { fun box() = s } } fun box() = Outer("OK").Inner().box() @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/innerClass/linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ open class A { open inner class Inner { val x = 42 } } ================================================ FILE: backend.native/tests/codegen/innerClass/linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ open class B : A() { open inner class Inner : A.Inner() } fun main(args: Array) { B().Inner() } ================================================ FILE: backend.native/tests/codegen/innerClass/noPrimaryConstructor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.noPrimaryConstructor import kotlin.test.* class Outer(val s: String) { inner class Inner { constructor(x: Int) { this.x = x } constructor(z: String) { x = z.length } val x: Int fun foo() = s } } @Test fun runTest() { println(Outer("OK").Inner(42).foo()) println(Outer("OK").Inner("zzz").foo()) } ================================================ FILE: backend.native/tests/codegen/innerClass/qualifiedThis.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.qualifiedThis import kotlin.test.* open class ABase { open fun zzz() = "a_base" } open class BBase { open fun zzz() = "b_base" } class D() { val z = "d" } class A: ABase() { // implicit label @A val z = "a" override fun zzz() = "a" inner class B: BBase() { // implicit label @B val z = "b" override fun zzz() = "b" fun D.foo() : String { // implicit label @foo if(this@A.z != "a") return "Fail1" if(this@B.z != "b") return "Fail2" if(super@A.zzz() != "a_base") return "Fail3" if(super.zzz() != "b_base") return "Fail4" if(super@B.zzz() != "b_base") return "Fail5" if(this@A.zzz() != "a") return "Fail6" if(this@B.zzz() != "b") return "Fail7" if(this.z != "d") return "Fail8" return "OK" } fun bar(d: D): String { return d.foo() } } } fun box() = A().B().bar(D()) @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/innerClass/secondaryConstructor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.secondaryConstructor import kotlin.test.* class Outer(val x: Int) { inner class Inner() { inner class InnerInner() { init { println(x) } lateinit var s: String constructor(s: String) : this() { this.s = s } } } } @Test fun runTest() { Outer(42).Inner().InnerInner("zzz") } ================================================ FILE: backend.native/tests/codegen/innerClass/simple.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.simple import kotlin.test.* class Outer { inner class Inner { fun box() = "OK" } } fun box() = Outer().Inner().box() @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/innerClass/superOuter.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.innerClass.superOuter import kotlin.test.* open class Outer(val outer: String) { open inner class Inner(val inner: String): Outer(inner) { fun foo() = outer } fun value() = Inner("OK").foo() } fun box() = Outer("Fail").value() @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/interfaceCallsNCasts/conservativeItable.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.interfaceCallsNCasts.conservativeItable import kotlin.test.* interface I0 { fun foo0(x: Int): Int } interface I1 { fun foo1(x: Int): Int } interface I2 { fun foo2(x: Int): Int } interface I3 { fun foo3(x: Int): Int } interface I4 { fun foo4(x: Int): Int } interface I5 { fun foo5(x: Int): Int } interface I6 { fun foo6(x: Int): Int } interface I7 { fun foo7(x: Int): Int } interface I8 { fun foo8(x: Int): Int } interface I9 { fun foo9(x: Int): Int } interface I10 { fun foo10(x: Int): Int } interface I11 { fun foo11(x: Int): Int } interface I12 { fun foo12(x: Int): Int } interface I13 { fun foo13(x: Int): Int } interface I14 { fun foo14(x: Int): Int } interface I15 { fun foo15(x: Int): Int } interface I16 { fun foo16(x: Int): Int } interface I17 { fun foo17(x: Int): Int } interface I18 { fun foo18(x: Int): Int } interface I19 { fun foo19(x: Int): Int } interface I20 { fun foo20(x: Int): Int } interface I21 { fun foo21(x: Int): Int } interface I22 { fun foo22(x: Int): Int } interface I23 { fun foo23(x: Int): Int } interface I24 { fun foo24(x: Int): Int } interface I25 { fun foo25(x: Int): Int } interface I26 { fun foo26(x: Int): Int } interface I27 { fun foo27(x: Int): Int } interface I28 { fun foo28(x: Int): Int } interface I29 { fun foo29(x: Int): Int } interface I30 { fun foo30(x: Int): Int } interface I31 { fun foo31(x: Int): Int } interface I32 { fun foo32(x: Int): Int } interface I33 { fun foo33(x: Int): Int } interface I34 { fun foo34(x: Int): Int } interface I35 { fun foo35(x: Int): Int } interface I36 { fun foo36(x: Int): Int } interface I37 { fun foo37(x: Int): Int } interface I38 { fun foo38(x: Int): Int } interface I39 { fun foo39(x: Int): Int } interface I40 { fun foo40(x: Int): Int } interface I41 { fun foo41(x: Int): Int } interface I42 { fun foo42(x: Int): Int } interface I43 { fun foo43(x: Int): Int } interface I44 { fun foo44(x: Int): Int } interface I45 { fun foo45(x: Int): Int } interface I46 { fun foo46(x: Int): Int } interface I47 { fun foo47(x: Int): Int } interface I48 { fun foo48(x: Int): Int } interface I49 { fun foo49(x: Int): Int } interface I50 { fun foo50(x: Int): Int } interface I51 { fun foo51(x: Int): Int } interface I52 { fun foo52(x: Int): Int } interface I53 { fun foo53(x: Int): Int } interface I54 { fun foo54(x: Int): Int } interface I55 { fun foo55(x: Int): Int } interface I56 { fun foo56(x: Int): Int } interface I57 { fun foo57(x: Int): Int } interface I58 { fun foo58(x: Int): Int } interface I59 { fun foo59(x: Int): Int } interface I60 { fun foo60(x: Int): Int } interface I61 { fun foo61(x: Int): Int } interface I62 { fun foo62(x: Int): Int } interface I63 { fun foo63(x: Int): Int } interface I64 { fun foo64(x: Int): Int } interface I65 { fun foo65(x: Int): Int } interface I66 { fun foo66(x: Int): Int } interface I67 { fun foo67(x: Int): Int } interface I68 { fun foo68(x: Int): Int } interface I69 { fun foo69(x: Int): Int } interface I70 { fun foo70(x: Int): Int } interface I71 { fun foo71(x: Int): Int } interface I72 { fun foo72(x: Int): Int } interface I73 { fun foo73(x: Int): Int } interface I74 { fun foo74(x: Int): Int } interface I75 { fun foo75(x: Int): Int } interface I76 { fun foo76(x: Int): Int } interface I77 { fun foo77(x: Int): Int } interface I78 { fun foo78(x: Int): Int } interface I79 { fun foo79(x: Int): Int } interface I80 { fun foo80(x: Int): Int } interface I81 { fun foo81(x: Int): Int } interface I82 { fun foo82(x: Int): Int } interface I83 { fun foo83(x: Int): Int } interface I84 { fun foo84(x: Int): Int } interface I85 { fun foo85(x: Int): Int } interface I86 { fun foo86(x: Int): Int } interface I87 { fun foo87(x: Int): Int } interface I88 { fun foo88(x: Int): Int } interface I89 { fun foo89(x: Int): Int } interface I90 { fun foo90(x: Int): Int } interface I91 { fun foo91(x: Int): Int } interface I92 { fun foo92(x: Int): Int } interface I93 { fun foo93(x: Int): Int } interface I94 { fun foo94(x: Int): Int } interface I95 { fun foo95(x: Int): Int } interface I96 { fun foo96(x: Int): Int } interface I97 { fun foo97(x: Int): Int } interface I98 { fun foo98(x: Int): Int } interface I99 { fun foo99(x: Int): Int } class Bar : I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79, I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95, I96, I97, I98, I99 { override fun foo0(x: Int) = x + 0 override fun foo1(x: Int) = x + 1 override fun foo2(x: Int) = x + 2 override fun foo3(x: Int) = x + 3 override fun foo4(x: Int) = x + 4 override fun foo5(x: Int) = x + 5 override fun foo6(x: Int) = x + 6 override fun foo7(x: Int) = x + 7 override fun foo8(x: Int) = x + 8 override fun foo9(x: Int) = x + 9 override fun foo10(x: Int) = x + 10 override fun foo11(x: Int) = x + 11 override fun foo12(x: Int) = x + 12 override fun foo13(x: Int) = x + 13 override fun foo14(x: Int) = x + 14 override fun foo15(x: Int) = x + 15 override fun foo16(x: Int) = x + 16 override fun foo17(x: Int) = x + 17 override fun foo18(x: Int) = x + 18 override fun foo19(x: Int) = x + 19 override fun foo20(x: Int) = x + 20 override fun foo21(x: Int) = x + 21 override fun foo22(x: Int) = x + 22 override fun foo23(x: Int) = x + 23 override fun foo24(x: Int) = x + 24 override fun foo25(x: Int) = x + 25 override fun foo26(x: Int) = x + 26 override fun foo27(x: Int) = x + 27 override fun foo28(x: Int) = x + 28 override fun foo29(x: Int) = x + 29 override fun foo30(x: Int) = x + 30 override fun foo31(x: Int) = x + 31 override fun foo32(x: Int) = x + 32 override fun foo33(x: Int) = x + 33 override fun foo34(x: Int) = x + 34 override fun foo35(x: Int) = x + 35 override fun foo36(x: Int) = x + 36 override fun foo37(x: Int) = x + 37 override fun foo38(x: Int) = x + 38 override fun foo39(x: Int) = x + 39 override fun foo40(x: Int) = x + 40 override fun foo41(x: Int) = x + 41 override fun foo42(x: Int) = x + 42 override fun foo43(x: Int) = x + 43 override fun foo44(x: Int) = x + 44 override fun foo45(x: Int) = x + 45 override fun foo46(x: Int) = x + 46 override fun foo47(x: Int) = x + 47 override fun foo48(x: Int) = x + 48 override fun foo49(x: Int) = x + 49 override fun foo50(x: Int) = x + 50 override fun foo51(x: Int) = x + 51 override fun foo52(x: Int) = x + 52 override fun foo53(x: Int) = x + 53 override fun foo54(x: Int) = x + 54 override fun foo55(x: Int) = x + 55 override fun foo56(x: Int) = x + 56 override fun foo57(x: Int) = x + 57 override fun foo58(x: Int) = x + 58 override fun foo59(x: Int) = x + 59 override fun foo60(x: Int) = x + 60 override fun foo61(x: Int) = x + 61 override fun foo62(x: Int) = x + 62 override fun foo63(x: Int) = x + 63 override fun foo64(x: Int) = x + 64 override fun foo65(x: Int) = x + 65 override fun foo66(x: Int) = x + 66 override fun foo67(x: Int) = x + 67 override fun foo68(x: Int) = x + 68 override fun foo69(x: Int) = x + 69 override fun foo70(x: Int) = x + 70 override fun foo71(x: Int) = x + 71 override fun foo72(x: Int) = x + 72 override fun foo73(x: Int) = x + 73 override fun foo74(x: Int) = x + 74 override fun foo75(x: Int) = x + 75 override fun foo76(x: Int) = x + 76 override fun foo77(x: Int) = x + 77 override fun foo78(x: Int) = x + 78 override fun foo79(x: Int) = x + 79 override fun foo80(x: Int) = x + 80 override fun foo81(x: Int) = x + 81 override fun foo82(x: Int) = x + 82 override fun foo83(x: Int) = x + 83 override fun foo84(x: Int) = x + 84 override fun foo85(x: Int) = x + 85 override fun foo86(x: Int) = x + 86 override fun foo87(x: Int) = x + 87 override fun foo88(x: Int) = x + 88 override fun foo89(x: Int) = x + 89 override fun foo90(x: Int) = x + 90 override fun foo91(x: Int) = x + 91 override fun foo92(x: Int) = x + 92 override fun foo93(x: Int) = x + 93 override fun foo94(x: Int) = x + 94 override fun foo95(x: Int) = x + 95 override fun foo96(x: Int) = x + 96 override fun foo97(x: Int) = x + 97 override fun foo98(x: Int) = x + 98 override fun foo99(x: Int) = x + 99 } fun check_is_I0(x: Any) = x is I0 fun check_is_I1(x: Any) = x is I1 fun check_is_I2(x: Any) = x is I2 fun check_is_I3(x: Any) = x is I3 fun check_is_I4(x: Any) = x is I4 fun check_is_I5(x: Any) = x is I5 fun check_is_I6(x: Any) = x is I6 fun check_is_I7(x: Any) = x is I7 fun check_is_I8(x: Any) = x is I8 fun check_is_I9(x: Any) = x is I9 fun check_is_I10(x: Any) = x is I10 fun check_is_I11(x: Any) = x is I11 fun check_is_I12(x: Any) = x is I12 fun check_is_I13(x: Any) = x is I13 fun check_is_I14(x: Any) = x is I14 fun check_is_I15(x: Any) = x is I15 fun check_is_I16(x: Any) = x is I16 fun check_is_I17(x: Any) = x is I17 fun check_is_I18(x: Any) = x is I18 fun check_is_I19(x: Any) = x is I19 fun check_is_I20(x: Any) = x is I20 fun check_is_I21(x: Any) = x is I21 fun check_is_I22(x: Any) = x is I22 fun check_is_I23(x: Any) = x is I23 fun check_is_I24(x: Any) = x is I24 fun check_is_I25(x: Any) = x is I25 fun check_is_I26(x: Any) = x is I26 fun check_is_I27(x: Any) = x is I27 fun check_is_I28(x: Any) = x is I28 fun check_is_I29(x: Any) = x is I29 fun check_is_I30(x: Any) = x is I30 fun check_is_I31(x: Any) = x is I31 fun check_is_I32(x: Any) = x is I32 fun check_is_I33(x: Any) = x is I33 fun check_is_I34(x: Any) = x is I34 fun check_is_I35(x: Any) = x is I35 fun check_is_I36(x: Any) = x is I36 fun check_is_I37(x: Any) = x is I37 fun check_is_I38(x: Any) = x is I38 fun check_is_I39(x: Any) = x is I39 fun check_is_I40(x: Any) = x is I40 fun check_is_I41(x: Any) = x is I41 fun check_is_I42(x: Any) = x is I42 fun check_is_I43(x: Any) = x is I43 fun check_is_I44(x: Any) = x is I44 fun check_is_I45(x: Any) = x is I45 fun check_is_I46(x: Any) = x is I46 fun check_is_I47(x: Any) = x is I47 fun check_is_I48(x: Any) = x is I48 fun check_is_I49(x: Any) = x is I49 fun check_is_I50(x: Any) = x is I50 fun check_is_I51(x: Any) = x is I51 fun check_is_I52(x: Any) = x is I52 fun check_is_I53(x: Any) = x is I53 fun check_is_I54(x: Any) = x is I54 fun check_is_I55(x: Any) = x is I55 fun check_is_I56(x: Any) = x is I56 fun check_is_I57(x: Any) = x is I57 fun check_is_I58(x: Any) = x is I58 fun check_is_I59(x: Any) = x is I59 fun check_is_I60(x: Any) = x is I60 fun check_is_I61(x: Any) = x is I61 fun check_is_I62(x: Any) = x is I62 fun check_is_I63(x: Any) = x is I63 fun check_is_I64(x: Any) = x is I64 fun check_is_I65(x: Any) = x is I65 fun check_is_I66(x: Any) = x is I66 fun check_is_I67(x: Any) = x is I67 fun check_is_I68(x: Any) = x is I68 fun check_is_I69(x: Any) = x is I69 fun check_is_I70(x: Any) = x is I70 fun check_is_I71(x: Any) = x is I71 fun check_is_I72(x: Any) = x is I72 fun check_is_I73(x: Any) = x is I73 fun check_is_I74(x: Any) = x is I74 fun check_is_I75(x: Any) = x is I75 fun check_is_I76(x: Any) = x is I76 fun check_is_I77(x: Any) = x is I77 fun check_is_I78(x: Any) = x is I78 fun check_is_I79(x: Any) = x is I79 fun check_is_I80(x: Any) = x is I80 fun check_is_I81(x: Any) = x is I81 fun check_is_I82(x: Any) = x is I82 fun check_is_I83(x: Any) = x is I83 fun check_is_I84(x: Any) = x is I84 fun check_is_I85(x: Any) = x is I85 fun check_is_I86(x: Any) = x is I86 fun check_is_I87(x: Any) = x is I87 fun check_is_I88(x: Any) = x is I88 fun check_is_I89(x: Any) = x is I89 fun check_is_I90(x: Any) = x is I90 fun check_is_I91(x: Any) = x is I91 fun check_is_I92(x: Any) = x is I92 fun check_is_I93(x: Any) = x is I93 fun check_is_I94(x: Any) = x is I94 fun check_is_I95(x: Any) = x is I95 fun check_is_I96(x: Any) = x is I96 fun check_is_I97(x: Any) = x is I97 fun check_is_I98(x: Any) = x is I98 fun check_is_I99(x: Any) = x is I99 interface I_M1 { fun bar(x: Int): Int } class Bar2 : I_M1 { override fun bar(x: Int) = 497 * x + 42 } class I42_Impl1 : I42 { override fun foo42(x: Int) = x * 2 + 42 } class I42_Impl2 : I42 { override fun foo42(x: Int) = x * 3 + 42 } class I42_Impl3 : I42 { override fun foo42(x: Int) = x * 4 + 42 } class I42_Impl4 : I42 { override fun foo42(x: Int) = x * 5 + 42 } class I42_Impl5 : I42 { override fun foo42(x: Int) = x * 6 + 42 } class I42_Impl6 : I42 { override fun foo42(x: Int) = x * 7 + 42 } class I42_Impl7 : I42 { override fun foo42(x: Int) = x * 8 + 42 } class I42_Impl8 : I42 { override fun foo42(x: Int) = x * 9 + 42 } fun foo(i42: I42, x: Int) = i42.foo42(x) fun bar(i_m1: I_M1, x: Int) = i_m1.bar(x) @Test fun runTest() { val y = Bar2() println(bar(y, 1)) val x0 = Bar() var t = 0 if (check_is_I0(x0)) t = t + 1 if (check_is_I1(x0)) t = t + 2 if (check_is_I2(x0)) t = t + 3 if (check_is_I3(x0)) t = t + 4 if (check_is_I4(x0)) t = t + 5 if (check_is_I5(x0)) t = t + 6 if (check_is_I6(x0)) t = t + 7 if (check_is_I7(x0)) t = t + 8 if (check_is_I8(x0)) t = t + 9 if (check_is_I9(x0)) t = t + 10 if (check_is_I10(x0)) t = t + 11 if (check_is_I11(x0)) t = t + 12 if (check_is_I12(x0)) t = t + 13 if (check_is_I13(x0)) t = t + 14 if (check_is_I14(x0)) t = t + 15 if (check_is_I15(x0)) t = t + 16 if (check_is_I16(x0)) t = t + 17 if (check_is_I17(x0)) t = t + 18 if (check_is_I18(x0)) t = t + 19 if (check_is_I19(x0)) t = t + 20 if (check_is_I20(x0)) t = t + 21 if (check_is_I21(x0)) t = t + 22 if (check_is_I22(x0)) t = t + 23 if (check_is_I23(x0)) t = t + 24 if (check_is_I24(x0)) t = t + 25 if (check_is_I25(x0)) t = t + 26 if (check_is_I26(x0)) t = t + 27 if (check_is_I27(x0)) t = t + 28 if (check_is_I28(x0)) t = t + 29 if (check_is_I29(x0)) t = t + 30 if (check_is_I30(x0)) t = t + 31 if (check_is_I31(x0)) t = t + 32 if (check_is_I32(x0)) t = t + 33 if (check_is_I33(x0)) t = t + 34 if (check_is_I34(x0)) t = t + 35 if (check_is_I35(x0)) t = t + 36 if (check_is_I36(x0)) t = t + 37 if (check_is_I37(x0)) t = t + 38 if (check_is_I38(x0)) t = t + 39 if (check_is_I39(x0)) t = t + 40 if (check_is_I40(x0)) t = t + 41 if (check_is_I41(x0)) t = t + 42 if (check_is_I42(x0)) t = t + 43 if (check_is_I43(x0)) t = t + 44 if (check_is_I44(x0)) t = t + 45 if (check_is_I45(x0)) t = t + 46 if (check_is_I46(x0)) t = t + 47 if (check_is_I47(x0)) t = t + 48 if (check_is_I48(x0)) t = t + 49 if (check_is_I49(x0)) t = t + 50 if (check_is_I50(x0)) t = t + 51 if (check_is_I51(x0)) t = t + 52 if (check_is_I52(x0)) t = t + 53 if (check_is_I53(x0)) t = t + 54 if (check_is_I54(x0)) t = t + 55 if (check_is_I55(x0)) t = t + 56 if (check_is_I56(x0)) t = t + 57 if (check_is_I57(x0)) t = t + 58 if (check_is_I58(x0)) t = t + 59 if (check_is_I59(x0)) t = t + 60 if (check_is_I60(x0)) t = t + 61 if (check_is_I61(x0)) t = t + 62 if (check_is_I62(x0)) t = t + 63 if (check_is_I63(x0)) t = t + 64 if (check_is_I64(x0)) t = t + 65 if (check_is_I65(x0)) t = t + 66 if (check_is_I66(x0)) t = t + 67 if (check_is_I67(x0)) t = t + 68 if (check_is_I68(x0)) t = t + 69 if (check_is_I69(x0)) t = t + 70 if (check_is_I70(x0)) t = t + 71 if (check_is_I71(x0)) t = t + 72 if (check_is_I72(x0)) t = t + 73 if (check_is_I73(x0)) t = t + 74 if (check_is_I74(x0)) t = t + 75 if (check_is_I75(x0)) t = t + 76 if (check_is_I76(x0)) t = t + 77 if (check_is_I77(x0)) t = t + 78 if (check_is_I78(x0)) t = t + 79 if (check_is_I79(x0)) t = t + 80 if (check_is_I80(x0)) t = t + 81 if (check_is_I81(x0)) t = t + 82 if (check_is_I82(x0)) t = t + 83 if (check_is_I83(x0)) t = t + 84 if (check_is_I84(x0)) t = t + 85 if (check_is_I85(x0)) t = t + 86 if (check_is_I86(x0)) t = t + 87 if (check_is_I87(x0)) t = t + 88 if (check_is_I88(x0)) t = t + 89 if (check_is_I89(x0)) t = t + 90 if (check_is_I90(x0)) t = t + 91 if (check_is_I91(x0)) t = t + 92 if (check_is_I92(x0)) t = t + 93 if (check_is_I93(x0)) t = t + 94 if (check_is_I94(x0)) t = t + 95 if (check_is_I95(x0)) t = t + 96 if (check_is_I96(x0)) t = t + 97 if (check_is_I97(x0)) t = t + 98 if (check_is_I98(x0)) t = t + 99 if (check_is_I99(x0)) t = t + 100 println(t) val x1 = I42_Impl1() val x2 = I42_Impl2() val x3 = I42_Impl3() val x4 = I42_Impl4() val x5 = I42_Impl5() val x6 = I42_Impl6() val x7 = I42_Impl7() val x8 = I42_Impl8() t = foo(x0, 1) t = foo(x1, t) t = foo(x2, t) t = foo(x3, t) t = foo(x4, t) t = foo(x5, t) t = foo(x6, t) t = foo(x7, t) t = foo(x8, t) println(t) } ================================================ FILE: backend.native/tests/codegen/intrinsics/interop_convert.kt ================================================ package codegen.intrinsics.interop_convert import kotlin.test.* import kotlinx.cinterop.* fun convertIntToShortOrNull(i: Int, b: Boolean): Short? = if (b) i.convert() else null fun narrowIntToShortOrNull(i: Int, b: Boolean): Short? = if (b) i.narrow() else null fun signExtendShortToIntOrNull(i: Short, b: Boolean): Int? = if (b) i.signExtend() else null @Test fun testNI() { assertNull(convertIntToShortOrNull(0, false)) assertEquals(1, convertIntToShortOrNull(1, true)) assertNull(narrowIntToShortOrNull(2, false)) assertEquals(3, narrowIntToShortOrNull(3, true)) assertNull(signExtendShortToIntOrNull(4, false)) assertEquals(5, signExtendShortToIntOrNull(5, true)) } @Test fun testConvertSimple() { assertEquals(1, 257.convert()) assertEquals(255u, (-1).convert()) assertEquals(0, Long.MIN_VALUE.narrow()) assertEquals(-1, Long.MAX_VALUE.narrow()) assertEquals(-1L, (-1).signExtend()) } @Test fun convertAll() { val values = mutableListOf() for (value in listOf( 0L, Byte.MIN_VALUE.toLong(), Byte.MAX_VALUE.toLong(), UByte.MAX_VALUE.toLong(), Short.MIN_VALUE.toLong(), Short.MAX_VALUE.toLong(), UShort.MAX_VALUE.toLong(), Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong(), UInt.MAX_VALUE.toLong(), Long.MIN_VALUE.toLong(), Long.MAX_VALUE.toLong(), ULong.MAX_VALUE.toLong() )) { values.add(value - 1) values.add(value) values.add(value + 1) } for (value in values) { testConvertAll(value.toByte()) testConvertAll(value.toUByte()) testConvertAll(value.toShort()) testConvertAll(value.toUShort()) testConvertAll(value.toInt()) testConvertAll(value.toUInt()) testConvertAll(value.toLong()) testConvertAll(value.toULong()) } } fun testConvertAll(value: Byte) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) assertEquals(value.toByte(), value.narrow()) assertEquals(value.toByte(), value.signExtend()) assertEquals(value.toShort(), value.signExtend()) assertEquals(value.toInt(), value.signExtend()) assertEquals(value.toLong(), value.signExtend()) } fun testConvertAll(value: Short) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) assertEquals(value.toByte(), value.narrow()) assertEquals(value.toShort(), value.narrow()) assertEquals(value.toShort(), value.signExtend()) assertEquals(value.toInt(), value.signExtend()) assertEquals(value.toLong(), value.signExtend()) } fun testConvertAll(value: Int) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) assertEquals(value.toByte(), value.narrow()) assertEquals(value.toShort(), value.narrow()) assertEquals(value.toInt(), value.narrow()) assertEquals(value.toInt(), value.signExtend()) assertEquals(value.toLong(), value.signExtend()) } fun testConvertAll(value: Long) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) assertEquals(value.toByte(), value.narrow()) assertEquals(value.toShort(), value.narrow()) assertEquals(value.toInt(), value.narrow()) assertEquals(value.toLong(), value.narrow()) assertEquals(value.toLong(), value.signExtend()) } fun testConvertAll(value: UByte) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) } fun testConvertAll(value: UShort) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) } fun testConvertAll(value: UInt) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) } fun testConvertAll(value: ULong) { assertEquals(value.toByte(), value.convert()) assertEquals(value.toUByte(), value.convert()) assertEquals(value.toShort(), value.convert()) assertEquals(value.toUShort(), value.convert()) assertEquals(value.toInt(), value.convert()) assertEquals(value.toUInt(), value.convert()) assertEquals(value.toLong(), value.convert()) assertEquals(value.toULong(), value.convert()) } ================================================ FILE: backend.native/tests/codegen/intrinsics/interop_sourceCodeStruct.kt ================================================ package codegen.intrinsics.interop_sourceCodeStruct import kotlinx.cinterop.* import kotlinx.cinterop.internal.* import kotlin.test.* // Just making sure this doesn't get accidentally forbidden or otherwise broken. // (however defining structs this way is still strongly discouraged, please define // structs in C headers or .def files instead). @CStruct("struct { int p0; int p1; }") class S(rawPtr: NativePtr) : CStructVar(rawPtr) { companion object : CStructVar.Type(8, 4) var x: Int get() = memberAt(0).value set(value) { memberAt(0).value = value } var y: Int get() = memberAt(4).value set(value) { memberAt(4).value = value } } @Test fun test() = memScoped { val s = alloc() s.x = 123 assertEquals(123, s.x) assertEquals(123, s.ptr.reinterpret()[0]) s.y = 321 assertEquals(321, s.y) assertEquals(321, s.ptr.reinterpret()[1]) } ================================================ FILE: backend.native/tests/codegen/kclass/kClassEnumArgument.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.kclass.kClassEnumArgument import kotlin.test.* import kotlin.reflect.KClass enum class E(val arg: KClass<*>?) { A(null as KClass<*>?), B(String::class); } @Test fun runTest() { println(E.B.arg?.simpleName) } ================================================ FILE: backend.native/tests/codegen/kclass/kclass0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.kclass.kclass0 import kotlin.test.* import kotlin.reflect.KClass @Test fun runTest() { main(emptyArray()) } fun main(args: Array) { checkClass(Any::class, "kotlin.Any", "Any", Any(), null) checkClass(Int::class, "kotlin.Int", "Int", 42, "17") checkClass(String::class, "kotlin.String", "String", "17", 42) checkClass(RootClass::class, "codegen.kclass.kclass0.RootClass", "RootClass", RootClass(), Any()) checkClass(RootClass.Nested::class, "codegen.kclass.kclass0.RootClass.Nested", "Nested", RootClass.Nested(), Any()) class Local { val captured = args inner class Inner } checkClass(Local::class, null, "Local", Local(), Any()) checkClass(Local.Inner::class, null, "Inner", Local().Inner(), Any()) val obj = object : Any() { val captured = args inner class Inner val innerKClass = Inner::class } checkClass(obj::class, null, null, obj, Any()) checkClass(obj.innerKClass, null, "Inner", obj.Inner(), Any()) // Interfaces: checkClass(Comparable::class, "kotlin.Comparable", "Comparable", 42, Any()) checkClass(Interface::class, "codegen.kclass.kclass0.Interface", "Interface", object : Interface {}, Any()) checkInstanceClass(Any(), Any::class) checkInstanceClass(42, Int::class) assert(42::class == Int::class) checkReifiedClass(Int::class) checkReifiedClass(Int::class) checkReifiedClass2(Int::class) checkReifiedClass2(Int::class) checkReifiedClass(Any::class) checkReifiedClass2(Any::class) checkReifiedClass2(Any::class) checkReifiedClass(Local::class) checkReifiedClass2(Local::class) checkReifiedClass(RootClass::class) checkReifiedClass2(RootClass::class) } class RootClass { class Nested } interface Interface fun checkClass( clazz: KClass<*>, expectedQualifiedName: String?, expectedSimpleName: String?, expectedInstance: Any, expectedNotInstance: Any? ) { assert(clazz.qualifiedName == expectedQualifiedName) assert(clazz.simpleName == expectedSimpleName) assert(clazz.isInstance(expectedInstance)) if (expectedNotInstance != null) assert(!clazz.isInstance(expectedNotInstance)) } fun checkInstanceClass(instance: Any, clazz: KClass<*>) { assert(instance::class == clazz) } inline fun checkReifiedClass(expectedClass: KClass<*>) { assert(T::class == expectedClass) } inline fun checkReifiedClass2(expectedClass: KClass<*>) { checkReifiedClass(expectedClass) checkReifiedClass(expectedClass) } ================================================ FILE: backend.native/tests/codegen/kclass/kclass1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.kclass.kclass1 import kotlin.test.* // FILE: main.kt @Test fun runTest() { App(testQualified = true) } // FILE: app.kt // Taken from: // https://github.com/SalomonBrys/kmffkn/blob/master/shared/main/kotlin/com/github/salomonbrys/kmffkn/app.kt @DslMarker annotation class MyDsl @MyDsl class DslMain { fun kClass(block: KClassDsl.() -> T): T = KClassDsl().block() } @MyDsl class KClassDsl { inline fun of() = T::class } fun dsl(block: DslMain.() -> T): T = DslMain().block() class TestClass class App(testQualified: Boolean) { var type = dsl { kClass { //kClass { } // This should error if uncommented because of `@DslMarker`. of() } } init { assert(type.simpleName == "TestClass") if (testQualified) assert(type.qualifiedName == "codegen.kclass.kclass1.TestClass") // This is not really necessary, but always better :). assert(String::class == String::class) assert(String::class != Int::class) assert(TestClass()::class == TestClass()::class) assert(TestClass()::class == TestClass::class) println("OK :D") } } ================================================ FILE: backend.native/tests/codegen/ktype/ktype1.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.ktype.ktype1 import kotlin.test.* import kotlin.reflect.* @OptIn(ExperimentalStdlibApi::class) inline fun kType() = typeOf() inline fun kType(obj: R) = kType() class C class D fun kTypeForCWithTypeParameter() = kType>() class Outer { companion object Friend inner class Inner } object Object private val pkg = "codegen.ktype.ktype1" @Test fun testBasics1() { assertEquals("$pkg.C", kType>().toString()) assertEquals("$pkg.C<$pkg.C>", kType>>().toString()) assertEquals("$pkg.C", kTypeForCWithTypeParameter().toString()) assertEquals("$pkg.Object", kType().toString()) assertEquals("$pkg.Outer.Friend", kType().toString()) } @Test fun testInner() { val innerKType = kType.Inner>() assertEquals(Outer.Inner::class, innerKType.classifier) assertEquals(String::class, innerKType.arguments.first().type!!.classifier) assertEquals(D::class, innerKType.arguments.last().type!!.classifier) } @Test fun testAnonymousObject() { val obj = object {} val objType = kType(obj) assertEquals("(non-denotable type)", objType.toString()) assertEquals(obj::class, objType.classifier) assertTrue(objType.arguments.isEmpty()) assertFalse(objType.isMarkedNullable) } ================================================ FILE: backend.native/tests/codegen/ktype/nonReified.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.ktype.nonReified import kotlin.test.* import kotlin.reflect.* @OptIn(kotlin.ExperimentalStdlibApi::class) fun foo() = typeOf>() @Test fun test_fun() { val l = foo() assertEquals(List::class, l.classifier) val t = l.arguments.single().type!!.classifier assertTrue(t is KTypeParameter) assertFalse((t as KTypeParameter).isReified) assertEquals("T", (t as KTypeParameter).name) } class C { @OptIn(kotlin.ExperimentalStdlibApi::class) fun foo() = typeOf>() } @Test fun test_class() { val l = C().foo() assertEquals(List::class, l.classifier) val t = l.arguments.single().type!!.classifier assertTrue(t is KTypeParameter) assertFalse((t as KTypeParameter).isReified) assertEquals("T", (t as KTypeParameter).name) } @OptIn(kotlin.ExperimentalStdlibApi::class) fun bar1() = typeOf>() @OptIn(kotlin.ExperimentalStdlibApi::class) fun bar2() = typeOf>() class D { @OptIn(kotlin.ExperimentalStdlibApi::class) fun bar1() = typeOf>() } @Test fun test_equality() { val t1 = bar1().arguments.single().type!!.classifier val t2 = bar2().arguments.single().type!!.classifier val t3 = D().bar1().arguments.single().type!!.classifier assertNotEquals(t1, t2) assertNotEquals(t1, t3) assertNotEquals(t2, t3) assertEquals(t1, bar1().arguments.single().type!!.classifier) assertEquals(t2, bar2().arguments.single().type!!.classifier) assertEquals(t3, D().bar1().arguments.single().type!!.classifier) } @OptIn(kotlin.ExperimentalStdlibApi::class) inline fun reifiedUpperBound() = typeOf>() @Test fun test_reifiedUpperBound() { val l = reifiedUpperBound() assertEquals(List::class, l.classifier) val r = l.arguments.single().type!!.classifier assertTrue(r is KTypeParameter) assertFalse((r as KTypeParameter).isReified) assertEquals("R", (r as KTypeParameter).name) val t = (r as KTypeParameter).upperBounds.single().classifier assertTrue(t is KTypeParameter) assertTrue((t as KTypeParameter).isReified) assertEquals("T", (t as KTypeParameter).name) } @OptIn(kotlin.ExperimentalStdlibApi::class) inline fun > recursionInReified() = typeOf>() @Test fun test_recursionInReified() { val l = recursionInReified() assertEquals(List::class, l.classifier) assertEquals(Int::class, l.arguments.single().type!!.classifier) } ================================================ FILE: backend.native/tests/codegen/lambda/lambda1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda1 import kotlin.test.* @Test fun runTest() { run { println("lambda") } } fun run(f: () -> Unit) { f() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda10 import kotlin.test.* @Test fun runTest() { var str = "original" val lambda = { println(str) } lambda() str = "changed" lambda() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda11 import kotlin.test.* @Test fun runTest() { val first = "first" val second = "second" run { println(first) println(second) } } fun run(f: () -> Unit) { f() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda12.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda12 import kotlin.test.* @Test fun runTest() { val lambda = { s1: String, s2: String -> println(s1) println(s2) } lambda("one", "two") } ================================================ FILE: backend.native/tests/codegen/lambda/lambda13.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda13 import kotlin.test.* @Test fun runTest() { apply("foo") { println(this) } } fun apply(str: String, block: String.() -> Unit) { str.block() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda14.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // FILE: 1.kt package codegen.lambda.lambda14 import kotlin.test.* @Test fun runTest() { assertEquals(foo()(), "foo1") assertEquals(foo(0)(), "foo2") } fun foo() = { "foo1" } // FILE: 2.kt package codegen.lambda.lambda14 fun foo(ignored: Int) = { "foo2" } ================================================ FILE: backend.native/tests/codegen/lambda/lambda2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda2 import kotlin.test.* @Test fun runTest() { main(arrayOf("arg0")) } fun main(args : Array) { run { println(args[0]) } } fun run(f: () -> Unit) { f() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda3 import kotlin.test.* @Test fun runTest() { var str = "lambda" run { println(str) } } fun run(f: () -> Unit) { f() } ================================================ FILE: backend.native/tests/codegen/lambda/lambda4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda4 import kotlin.test.* @Test fun runTest() { val lambda = bar() lambda() lambda() } fun bar(): () -> Unit { var x = Integer(0) val lambda = { println(x.toString()) x = x + 1 } x = x + 1 lambda() lambda() println(x.toString()) return lambda } class Integer(val value: Int) { override fun toString() = value.toString() operator fun plus(other: Int) = Integer(value + other) } ================================================ FILE: backend.native/tests/codegen/lambda/lambda5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda5 import kotlin.test.* @Test fun runTest() { foo { println(it) } } fun foo(f: (Int) -> Unit) { f(42) } ================================================ FILE: backend.native/tests/codegen/lambda/lambda6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda6 import kotlin.test.* @Test fun runTest() { val str = "captured" foo { println(it) println(str) } } fun foo(f: (Int) -> Unit) { f(42) } ================================================ FILE: backend.native/tests/codegen/lambda/lambda7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda7 import kotlin.test.* @Test fun runTest() { val x = foo { it + 1 } println(x) } fun foo(f: (Int) -> Int) = f(42) ================================================ FILE: backend.native/tests/codegen/lambda/lambda8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda8 import kotlin.test.* @Test fun runTest() { val lambda1 = bar("first") val lambda2 = bar("second") lambda1() lambda2() lambda1() lambda2() } fun bar(str: String): () -> Unit { var x = Integer(0) return { println(str) println(x.toString()) x = x + 1 } } class Integer(val value: Int) { override fun toString() = value.toString() operator fun plus(other: Int) = Integer(value + other) } ================================================ FILE: backend.native/tests/codegen/lambda/lambda9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lambda.lambda9 import kotlin.test.* @Test fun runTest() { val lambdas = ArrayList<() -> Unit>() for (i in 0..1) { var x = Integer(0) val istr = i.toString() lambdas.add { println(istr) println(x.toString()) x = x + 1 } } val lambda1 = lambdas[0] val lambda2 = lambdas[1] lambda1() lambda2() lambda1() lambda2() } class Integer(val value: Int) { override fun toString() = value.toString() operator fun plus(other: Int) = Integer(value + other) } ================================================ FILE: backend.native/tests/codegen/lateinit/globalIsInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.globalIsInitialized import kotlin.test.* lateinit var s: String fun foo() { println(::s.isInitialized) } @Test fun runTest() { foo() s = "zzz" foo() } ================================================ FILE: backend.native/tests/codegen/lateinit/inBaseClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.inBaseClass import kotlin.test.* class A(val a: Int) open class B { lateinit var a: A } class C: B() { fun foo() { a = A(42) } } @Test fun runTest() { val c = C() c.foo() println(c.a.a) } ================================================ FILE: backend.native/tests/codegen/lateinit/initialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.initialized import kotlin.test.* class A { lateinit var s: String fun foo() = s } @Test fun runTest() { val a = A() a.s = "zzz" println(a.foo()) } ================================================ FILE: backend.native/tests/codegen/lateinit/innerIsInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.innerIsInitialized import kotlin.test.* open class Foo { lateinit var bar: String fun test(): String { return InnerSubclass().testInner() } inner class InnerSubclass : Foo() { fun testInner(): String { // This is access to InnerSubclass.bar which is inherited from Foo.bar if (this::bar.isInitialized) return "Fail" return "OK" } } } @Test fun runTest() { println(Foo().test()) } ================================================ FILE: backend.native/tests/codegen/lateinit/isInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.isInitialized import kotlin.test.* class A { lateinit var s: String fun foo() { println(::s.isInitialized) } } @Test fun runTest() { val a = A() a.foo() a.s = "zzz" a.foo() } ================================================ FILE: backend.native/tests/codegen/lateinit/localCapturedInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.localCapturedInitialized import kotlin.test.* @Test fun runTest() { lateinit var s: String fun foo() = s s = "zzz" println(foo()) } ================================================ FILE: backend.native/tests/codegen/lateinit/localCapturedNotInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.localCapturedNotInitialized import kotlin.test.* @Test fun runTest() { lateinit var s: String fun foo() = s try { println(foo()) } catch (e: RuntimeException) { println("OK") return } println("Fail") } ================================================ FILE: backend.native/tests/codegen/lateinit/localInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.localInitialized import kotlin.test.* @Test fun runTest() { lateinit var s: String s = "zzz" println(s) } ================================================ FILE: backend.native/tests/codegen/lateinit/localNotInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.localNotInitialized import kotlin.test.* @Test fun runTest() { lateinit var s: String try { println(s) } catch (e: RuntimeException) { println("OK") return } println("Fail") } ================================================ FILE: backend.native/tests/codegen/lateinit/notInitialized.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.lateinit.notInitialized import kotlin.test.* class A { lateinit var s: String fun foo() = s } @Test fun runTest() { val a = A() try { println(a.foo()) } catch (e: RuntimeException) { println("OK") return } println("Fail") } ================================================ FILE: backend.native/tests/codegen/localClass/innerTakesCapturedFromOuter.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.innerTakesCapturedFromOuter import kotlin.test.* fun box() { var previous: Any? = null for (i in 0 .. 2) { class Outer { inner class Inner { override fun toString() = i.toString() } override fun toString() = Inner().toString() } if (previous != null) println(previous.toString()) previous = Outer() } } @Test fun runTest() { box() } ================================================ FILE: backend.native/tests/codegen/localClass/innerWithCapture.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.innerWithCapture import kotlin.test.* fun box(s: String): String { class Local { open inner class Inner() { open fun result() = s } } return Local().Inner().result() } @Test fun runTest() { println(box("OK")) } ================================================ FILE: backend.native/tests/codegen/localClass/localFunctionCallFromLocalClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.localFunctionCallFromLocalClass import kotlin.test.* @Test fun runTest() { var x = 1 fun local1() { x++ } class A { fun bar() { local1() } } A().bar() println("OK") } ================================================ FILE: backend.native/tests/codegen/localClass/localFunctionInLocalClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.localFunctionInLocalClass import kotlin.test.* @Test fun runTest() { var x = 0 class A { fun bar() { fun local() { class B { fun baz() { fun local2() { x++ } local2() } } B().baz() } local() } } A().bar() println("OK") } ================================================ FILE: backend.native/tests/codegen/localClass/localHierarchy.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.localHierarchy import kotlin.test.* fun foo(s: String): String { open class Local { fun f() = s } open class Derived: Local() { fun g() = f() } return Derived().g() } @Test fun runTest() { println(foo("OK")) } ================================================ FILE: backend.native/tests/codegen/localClass/noPrimaryConstructor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.noPrimaryConstructor import kotlin.test.* fun box(s: String): String { class Local { constructor(x: Int) { this.x = x } constructor(z: String) { x = z.length } val x: Int fun result() = s } return Local(42).result() + Local("zzz").result() } @Test fun runTest() { println(box("OK")) } ================================================ FILE: backend.native/tests/codegen/localClass/objectExpressionInInitializer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.objectExpressionInInitializer import kotlin.test.* abstract class Father { abstract inner class InClass { abstract fun work(): String } } class Child : Father() { val ChildInClass : InClass init { ChildInClass = object : Father.InClass() { override fun work(): String { return "OK" } } } } fun box(): String { return Child().ChildInClass.work() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/localClass/objectExpressionInProperty.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.objectExpressionInProperty import kotlin.test.* abstract class Father { abstract inner class InClass { abstract fun work(): String } } class Child : Father() { val ChildInClass = object : Father.InClass() { override fun work(): String { return "OK" } } } fun box(): String { return Child().ChildInClass.work() } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/localClass/tryCatch.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.tryCatch import kotlin.test.* private fun foo() { val local = object { fun bar() { try { } catch (t: Throwable) { println(t) } } } local.bar() } @Test fun runTest() { foo() } ================================================ FILE: backend.native/tests/codegen/localClass/virtualCallFromConstructor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.localClass.virtualCallFromConstructor import kotlin.test.* abstract class WaitFor { init { condition() } abstract fun condition(): Boolean; } fun box(): String { val local = "" var result = "fail" val s = object : WaitFor() { override fun condition(): Boolean { result = "OK" return result.length == 2 } } return result; } @Test fun runTest() { println(box()) } ================================================ FILE: backend.native/tests/codegen/localEscapeAnalysis/arraysFieldWrite.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ class ArraysConstructor { private val memberArray: IntArray constructor(int1: Int, int2: Int) { memberArray = IntArray(2) set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() { println("Array (constructor init):") println("Size: ${memberArray.size}") println("Contents: ${memberArray.contentToString()}") } } class ArraysDefault { private val memberArray = IntArray(2) constructor(int1: Int, int2: Int) { set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() { println("Array (default value init):") println("Size: ${memberArray.size}") println("Contents: ${memberArray.contentToString()}") } } class ArraysInitBlock { private val memberArray : IntArray init { memberArray = IntArray(2) } constructor(int1: Int, int2: Int) { set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() { println("Array (init block):") println("Size: ${memberArray.size}") println("Contents: ${memberArray.contentToString()}") } } fun main() { val array1 = (::ArraysConstructor)(1, 2) array1.log() array1.set( 3, 4) array1.log() val array2 = (::ArraysDefault)(1, 2) array2.log() array2.set( 3, 4) array2.log() val array3 = (::ArraysInitBlock)(1, 2) array3.log() array3.set( 3, 4) array3.log() } ================================================ FILE: backend.native/tests/codegen/mpp/libmpp2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ expect class C { constructor(arg: Any?) } actual data class C actual constructor(val arg: Any?) { } expect class T actual typealias T = C expect fun f(arg: Int): Int actual fun f(arg: Int) = arg expect var p: String actual var p: String = "p" ================================================ FILE: backend.native/tests/codegen/mpp/mpp1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.mpp.mpp1 import kotlin.test.* fun box() { assertEquals(A().B().fourtyTwo(), 42) assertEquals(seventeen(), 17) } expect class A { constructor() inner class B { fun fourtyTwo(): Int constructor() } } actual class A { actual inner class B actual constructor() { actual fun fourtyTwo() = 42 } } actual fun seventeen() = 17 expect fun seventeen(): Int @Test fun runTest() { box() } ================================================ FILE: backend.native/tests/codegen/mpp/mpp2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { println(C(42)) println(C(42) is T) println(f(1)) p = "h" println(p) } ================================================ FILE: backend.native/tests/codegen/mpp/mpp_default_args.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.mpp.mpp_default_args import kotlin.test.* @Test fun runTest() { box() } fun box() { assertEquals(test1(), 42) assertEquals(test2(17), 34) assertEquals(test3(), -1) Test4().test() Test5().Inner().test() 42.test6() assertEquals(inlineFunction("OK"), "OK,0,null") } expect fun test1(x: Int = 42): Int actual fun test1(x: Int) = x expect fun test2(x: Int, y: Int = x): Int actual fun test2(x: Int, y: Int) = x + y expect fun test3(x: Int = 42, y: Int = x + 1): Int actual fun test3(x: Int, y: Int) = x - y expect class Test4 { fun test(arg: Any = this) } actual class Test4 { actual fun test(arg: Any) { assertEquals(arg, this) } } expect class Test5 { inner class Inner { constructor(arg: Any = this@Test5) fun test(arg1: Any = this@Test5, arg2: Any = this@Inner) } } actual class Test5 { actual inner class Inner { actual constructor(arg: Any) { assertEquals(arg, this@Test5) } actual fun test(arg1: Any, arg2: Any) { assertEquals(arg1, this@Test5) assertEquals(arg2, this@Inner) } } } expect fun Int.test6(arg: Int = this) actual fun Int.test6(arg: Int) { assertEquals(arg, this) } // Default parameter in inline function. expect inline fun inlineFunction(a: String, b: Int = 0, c: () -> Double? = { null }): String actual inline fun inlineFunction(a: String, b: Int, c: () -> Double?): String = a + "," + b + "," + c() ================================================ FILE: backend.native/tests/codegen/mpp/mpp_optional_expectation.kt ================================================ @file:Suppress("EXPERIMENTAL_API_USAGE_ERROR") import kotlin.js.* @OptionalExpectation expect annotation class Optional() @Optional fun foo() { println(42) } @JsName("jsBar") fun bar() { println(43) } fun main(args: Array) { foo() bar() } ================================================ FILE: backend.native/tests/codegen/object/constructor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.constructor class A() class B(val a:Int) class C(val a:Int, b:Int) ================================================ FILE: backend.native/tests/codegen/object/constructor0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.constructor0 import kotlin.test.* class A { var field0:Int = 0; constructor(arg0:Int) { field0 = arg0 } } ================================================ FILE: backend.native/tests/codegen/object/fields.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.fields import kotlin.test.* private var globalValue = 1 var global:Int get() = globalValue set(value:Int) {globalValue = value} fun globalTest(i:Int):Int { global += i return global } @Test fun runTest() { if (global != 1) throw Error() if (globalTest(41) != 42) throw Error() if (global != 42) throw Error() } ================================================ FILE: backend.native/tests/codegen/object/fields1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.fields1 import kotlin.test.* class B(val a:Int, b:Int) { constructor(pos:Int):this(1, pos) {} val pos = b + 1 } fun primaryConstructorCall(a:Int, b:Int) = B(a, b).pos fun secondaryConstructorCall(a:Int) = B(a).pos @Test fun runTest() { if (primaryConstructorCall(0xdeadbeef.toInt(), 41) != 42) throw Error() if (secondaryConstructorCall(41) != 42) throw Error() } ================================================ FILE: backend.native/tests/codegen/object/fields2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.fields2 import kotlin.test.* var global: Int = 0 get() { println("Get global = $field") return field } set(value) { println("Set global = $value") field = value } class TestClass { var member: Int = 0 get() { println("Get member = $field") return field } set(value) { println("Set member = $value") field = value } } @Test fun runTest1() { global = 1 val test = TestClass() test.member = 42 global = test.member test.member = global } @ThreadLocal val xInt = 42 @ThreadLocal val xString = "42" @ThreadLocal val xAny = Any() @Test fun runTest2() { assertEquals(42, xInt) assertEquals("42", xString) assertTrue(xAny is Any) } ================================================ FILE: backend.native/tests/codegen/object/globalInitializer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // Does not fail with TR. public val z: Any = Z private object Z fun main(args: Array) { } ================================================ FILE: backend.native/tests/codegen/object/init0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.init0 import kotlin.test.* class A(a:Int) { var i:Int = 0 init { if (a == 0) i = 1 } } ================================================ FILE: backend.native/tests/codegen/object/initialization.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.initialization import kotlin.test.* open class A(val a:Int, val b:Int) open class B(val c:Int, d:Int):A(c, d) open class C(i:Int, j:Int):B(i + j, 42) class D (i: Int, j:Int) : C(i, j){ constructor(i: Int, j:Int, k:Int) : this(i, j) { foo(i) } constructor():this(1, 2) } fun foo(i:Int) : Unit {} fun foo(i:Int, j:Int):Int { val c = D(i, j) return c.c } @Test fun runTest() { if (foo(2, 3) != 5) throw Error() } ================================================ FILE: backend.native/tests/codegen/object/initialization1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.initialization1 import kotlin.test.* class TestClass { constructor() { println("constructor1") } constructor(x: Int) : this() { println("constructor2") } init { println("init") } val f = println("field") } @Test fun runTest() { TestClass() TestClass(1) } ================================================ FILE: backend.native/tests/codegen/object/method_call.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`object`.method_call import kotlin.test.* class A(val a:Int) { fun foo(i:Int) = a + i } fun fortyTwo() = A(41).foo(1) @Test fun runTest() { if (fortyTwo() != 42) throw Error() } ================================================ FILE: backend.native/tests/codegen/objectExpression/expr1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.objectExpression.expr1 import kotlin.test.* @Test fun runTest() { val a = "a" val x = object { override fun toString(): String { return foo(a) + foo("b") } fun foo(s: String) = s + s } println(x.toString()) } ================================================ FILE: backend.native/tests/codegen/objectExpression/expr2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.objectExpression.expr2 import kotlin.test.* @Test fun runTest() { val a = "a" val x = object { override fun toString(): String { return foo { a } } fun foo(lambda: () -> String) = lambda() } print(x) } fun print(x: Any) = println(x.toString()) ================================================ FILE: backend.native/tests/codegen/objectExpression/expr3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.objectExpression.expr3 import kotlin.test.* @Test fun runTest() { var cnt = 0 var x: Any = "" for (i in 0 .. 1) { print(x) cnt++ val y = object { override fun toString() = cnt.toString() } x = y } print(x) } fun print(x: Any) = println(x.toString()) ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/dynamicReceiver.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.dynamicReceiver import kotlin.test.* class TestClass { var x: Int = 42 } fun foo(): TestClass { println(42) return TestClass() } @Test fun runTest() { foo()::x } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/linkTest_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package a class A(val x: Int) ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/linkTest_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import a.A fun main(args: Array) { val p1 = A::x println(p1.get(A(42))) val a = A(117) val p2 = a::x println(p2.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/valClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.valClass import kotlin.test.* class A(val x: Int) @Test fun runTest() { val p1 = A::x println(p1.get(A(42))) val a = A(117) val p2 = a::x println(p2.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/valExtension.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.valExtension import kotlin.test.* class A(y: Int) { var x = y } val A.z get() = this.x @Test fun runTest() { val p1 = A::z println(p1.get(A(42))) val a = A(117) val p2 = a::z println(p2.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/valModule.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.valModule import kotlin.test.* val x = 42 @Test fun runTest() { val p = ::x println(p.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/varClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.varClass import kotlin.test.* class A(var x: Int) @Test fun runTest() { val p1 = A::x val a = A(42) p1.set(a, 117) println(a.x) println(p1.get(a)) val p2 = a::x p2.set(42) println(a.x) println(p2.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/varExtension.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.varExtension import kotlin.test.* class A(y: Int) { var x = y } var A.z: Int get() = this.x set(value: Int) { this.x = value } @Test fun runTest() { val p1 = A::z val a = A(42) p1.set(a, 117) println(a.x) println(p1.get(a)) val p2 = a::z p2.set(42) println(a.x) println(p2.get()) } ================================================ FILE: backend.native/tests/codegen/propertyCallableReference/varModule.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.propertyCallableReference.varModule import kotlin.test.* var x = 42 @Test fun runTest() { val p = ::x p.set(117) println(x) println(p.get()) } ================================================ FILE: backend.native/tests/codegen/stringTrim/stringTrim.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.stringTrim.stringTrim import kotlin.test.* // TODO: check IR fun constantIndent(): String { return """ Hello, World """.trimIndent() } fun constantMargin(): String { return """ |Hello, |World """.trimMargin() } @Test fun runTest() { assertTrue(constantIndent() === constantIndent()) assertTrue(constantMargin() === constantMargin()) } ================================================ FILE: backend.native/tests/codegen/try/catch3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.catch3 import kotlin.test.* @Test fun runTest() { try { println("Before") throw Error("Error happens") println("After") } catch (e: Throwable) { println("Caught Throwable") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/catch4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.catch4 import kotlin.test.* @Test fun runTest() { try { println("Before") throw Error("Error happens") println("After") } catch (e: Exception) { println("Caught Exception") } catch (e: Error) { println("Caught Error") } catch (e: Throwable) { println("Caught Throwable") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/catch5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.catch5 import kotlin.test.* @Test fun runTest() { try { try { println("Before") foo() println("After") } catch (e: Exception) { println("Caught Exception") } println("After nested try") } catch (e: Error) { println("Caught Error") } catch (e: Throwable) { println("Caught Throwable") } println("Done") } fun foo() { throw Error("Error happens") println("After in foo()") } ================================================ FILE: backend.native/tests/codegen/try/catch6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.catch6 import kotlin.test.* @Test fun runTest() { try { println("Before") foo() println("After") } catch (e: Exception) { println("Caught Exception") } catch (e: Error) { println("Caught Error") } println("Done") } fun foo() { try { throw Error("Error happens") } catch (e: Exception) { println("Caught Exception") } } ================================================ FILE: backend.native/tests/codegen/try/catch8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.catch8 import kotlin.test.* @Test fun runTest() { try { throw Error("Error happens") } catch (e: Throwable) { val message = e.message if (message != null) { println(message) } } } ================================================ FILE: backend.native/tests/codegen/try/finally1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally1 import kotlin.test.* @Test fun runTest() { try { println("Try") } finally { println("Finally") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/finally10.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally10 import kotlin.test.* @Test fun runTest() { while (true) { try { continue } finally { println("Finally") break } } println("After") } ================================================ FILE: backend.native/tests/codegen/try/finally11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally11 import kotlin.test.* @Test fun runTest() { try { try { return } catch (e: Error) { println("Catch 1") } finally { println("Finally") throw Error() } } catch (e: Error) { println("Catch 2") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/finally2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally2 import kotlin.test.* @Test fun runTest() { try { println("Try") throw Error("Error happens") println("After throw") } catch (e: Error) { println("Caught Error") } finally { println("Finally") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/finally3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally3 import kotlin.test.* @Test fun runTest() { try { try { println("Try") throw Error("Error happens") println("After throw") } finally { println("Finally") } println("After nested try") } catch (e: Error) { println("Caught Error") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/finally4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally4 import kotlin.test.* @Test fun runTest() { try { try { println("Try") throw Error("Error happens") println("After throw") } catch (e: Error) { println("Catch") throw Exception() println("After throw") } finally { println("Finally") } println("After nested try") } catch (e: Error) { println("Caught Error") } catch (e: Exception) { println("Caught Exception") } println("Done") } ================================================ FILE: backend.native/tests/codegen/try/finally5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally5 import kotlin.test.* @Test fun runTest() { println(foo()) } fun foo(): Int { try { println("Done") return 0 } finally { println("Finally") } println("After") return 1 } ================================================ FILE: backend.native/tests/codegen/try/finally6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally6 import kotlin.test.* @Test fun runTest() { println(foo()) } fun foo(): Int { try { println("Done") return 0 } finally { println("Finally") return 1 } println("After") return 2 } ================================================ FILE: backend.native/tests/codegen/try/finally7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally7 import kotlin.test.* @Test fun runTest() { println(foo()) } fun foo(): Int { try { println("Done") throw Error() } finally { println("Finally") return 1 } println("After") return 2 } ================================================ FILE: backend.native/tests/codegen/try/finally8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally8 import kotlin.test.* @Test fun runTest() { println(foo()) } fun foo(): Int { try { try { return 42 } finally { println("Finally 1") } } finally { println("Finally 2") } println("After") return 2 } ================================================ FILE: backend.native/tests/codegen/try/finally9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.finally9 import kotlin.test.* @Test fun runTest() { do { try { break } finally { println("Finally 1") } } while (false) var stop = false while (!stop) { try { stop = true continue } finally { println("Finally 2") } } println("After") } ================================================ FILE: backend.native/tests/codegen/try/returnsDifferentTypes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.returnsDifferentTypes import kotlin.test.* class ReceiveChannel inline fun ReceiveChannel.consume(block: ReceiveChannel.() -> R): R { try { return block() } finally { println("zzz") } } inline fun ReceiveChannel.elementAtOrElse(index: Int, defaultValue: (Int) -> E): E = consume { if (index < 0) return defaultValue(index) return 42 as E } fun ReceiveChannel.elementAt(index: Int): E = elementAtOrElse(index) { throw IndexOutOfBoundsException("qxx") } @Test fun runTest() { println(ReceiveChannel().elementAt(0)) } ================================================ FILE: backend.native/tests/codegen/try/try1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.try1 import kotlin.test.* @Test fun runTest() { val x = try { 5 } catch (e: Throwable) { 6 } println(x) } ================================================ FILE: backend.native/tests/codegen/try/try2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.try2 import kotlin.test.* @Test fun runTest() { val x = try { throw Error() 5 } catch (e: Throwable) { 6 } println(x) } ================================================ FILE: backend.native/tests/codegen/try/try3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.try3 import kotlin.test.* @Test fun runTest() { val x = try { throw Error() } catch (e: Throwable) { 6 } println(x) } ================================================ FILE: backend.native/tests/codegen/try/try4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package codegen.`try`.try4 import kotlin.test.* @Test fun runTest() { val x = try { println("Try") 5 } catch (e: Throwable) { throw e } println(x) } ================================================ FILE: backend.native/tests/compilerChecks/README.md ================================================ These tests aren't invoked so far because there is no mechanism of checking compilation errors yet. ================================================ FILE: backend.native/tests/compilerChecks/t1.kt ================================================ import kotlinx.cinterop.* fun foo(x: Int, vararg s: String): Int { var sum = x s.forEach { sum += it.length } return sum } fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t10.kt ================================================ import kotlinx.cinterop.* fun foo(f: Function1<*, Int>) = f fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t11.kt ================================================ import kotlinx.cinterop.* fun foo(f: Function1) = f fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t12.kt ================================================ import kotlinx.cinterop.* fun foo(x: CValue<*>?) = x fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t13.kt ================================================ import kotlinx.cinterop.* fun bar() { fun foo(x: CValue) = x staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t14.kt ================================================ import kotlinx.cinterop.* class Z(rawPtr: NativePtr): CStructVar(rawPtr) fun foo(x: CValue) = x fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t15.kt ================================================ import platform.darwin.* import platform.Foundation.* fun foo() = NSLog("zzz", {}) ================================================ FILE: backend.native/tests/compilerChecks/t16.kt ================================================ import platform.darwin.* import platform.Foundation.* class Z fun foo() = NSLog("zzz", Z()) ================================================ FILE: backend.native/tests/compilerChecks/t17.kt ================================================ import platform.darwin.* import platform.Foundation.* class Foo : NSObject(), NSPortDelegateProtocol { fun foo() { super.handlePortMessage(TODO()) } } ================================================ FILE: backend.native/tests/compilerChecks/t18.kt ================================================ import platform.darwin.* class Foo : NSObject() { companion object : NSObjectMeta() { fun bar() { super.hash() } } } ================================================ FILE: backend.native/tests/compilerChecks/t2.kt ================================================ import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { override fun handleFailureInFunction(functionName: String, file: String, lineNumber: NSInteger /* = Long */, description: String?, vararg args: Any?) { } } ================================================ FILE: backend.native/tests/compilerChecks/t20.kt ================================================ import platform.darwin.* import platform.Foundation.* interface Zzz : NSCopyingProtocolMeta ================================================ FILE: backend.native/tests/compilerChecks/t21.kt ================================================ import platform.darwin.* import platform.Foundation.* open class Zzz : NSAssertionHandler() ================================================ FILE: backend.native/tests/compilerChecks/t22.kt ================================================ import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { companion object { val Z = 42 } } ================================================ FILE: backend.native/tests/compilerChecks/t23.kt ================================================ import platform.darwin.* import platform.Foundation.* interface I class Zzz : NSAssertionHandler(), I ================================================ FILE: backend.native/tests/compilerChecks/t24.kt ================================================ import platform.darwin.* import platform.Foundation.* class Zzz : NSCopyingProtocolMeta ================================================ FILE: backend.native/tests/compilerChecks/t25.kt ================================================ import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { override fun toString() = "zzz" } ================================================ FILE: backend.native/tests/compilerChecks/t26.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCAction fun String.foo() = println(this) } ================================================ FILE: backend.native/tests/compilerChecks/t27.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCAction fun foo(x: String) = println(x) } ================================================ FILE: backend.native/tests/compilerChecks/t28.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCAction fun foo() = 42 } ================================================ FILE: backend.native/tests/compilerChecks/t29.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCOutlet val x: NSObject get() = this } ================================================ FILE: backend.native/tests/compilerChecks/t3.kt ================================================ import platform.posix.* fun main() { println(::printf) } ================================================ FILE: backend.native/tests/compilerChecks/t30.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCOutlet var NSObject.x: NSObject get() = this set(value: NSObject) { } } ================================================ FILE: backend.native/tests/compilerChecks/t31.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCOutlet var x: String get() = "zzz" set(value: String) { } } ================================================ FILE: backend.native/tests/compilerChecks/t32.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler { @OverrideInit constructor(x: Int) { } } ================================================ FILE: backend.native/tests/compilerChecks/t33.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSString { @OverrideInit constructor(coder: NSCoder) { } override fun initWithCoder(coder: NSCoder): String? = "zzz" } ================================================ FILE: backend.native/tests/compilerChecks/t34.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSAssertionHandler() { @ObjCAction fun foo(x: NSObject, y: NSObject, z: NSObject) { } } ================================================ FILE: backend.native/tests/compilerChecks/t35.kt ================================================ import kotlinx.cinterop.* import platform.darwin.* import platform.Foundation.* class Zzz : NSValue() ================================================ FILE: backend.native/tests/compilerChecks/t36.kt ================================================ import kotlinx.cinterop.* import platform.posix.* fun foo() = stat(malloc(42)!!.rawValue) ================================================ FILE: backend.native/tests/compilerChecks/t37.kt ================================================ import kotlinx.cinterop.* import kotlinx.cinterop.internal.* @CStruct(spelling = "struct { }") class Z constructor(rawPtr: NativePtr) : CStructVar(rawPtr) { val x: Pair? = null @CStruct.MemberAt(offset = 0L) get } fun foo(z: Z) = z.x fun main() { } ================================================ FILE: backend.native/tests/compilerChecks/t38.kt ================================================ import kotlinx.cinterop.* import kotlinx.cinterop.internal.* @CStruct(spelling = "struct { }") class Z constructor(rawPtr: NativePtr) : CStructVar(rawPtr) { var x: Pair? = null @CStruct.MemberAt(offset = 0L) get @CStruct.MemberAt(offset = 0L) set } fun foo(z: Z) { z.x = 42 to 117 } fun main() { } ================================================ FILE: backend.native/tests/compilerChecks/t4.kt ================================================ import platform.darwin.* import platform.Foundation.* fun foo() = println(NSAssertionHandler()::handleFailureInFunction) ================================================ FILE: backend.native/tests/compilerChecks/t40.kt ================================================ import kotlinx.cinterop.* class Z { fun foo(x: Int) = x } fun bar() { staticCFunction(Z()::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t41.kt ================================================ import kotlinx.cinterop.* fun bar(x: Int) { fun foo() = x staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t42.kt ================================================ import kotlinx.cinterop.* fun foo(x: Any) = x fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t43.kt ================================================ import kotlinx.cinterop.* fun bar(x: Float) = x.signExtend() ================================================ FILE: backend.native/tests/compilerChecks/t44.kt ================================================ import kotlinx.cinterop.* fun bar(x: Int) = x.signExtend() ================================================ FILE: backend.native/tests/compilerChecks/t45.kt ================================================ import kotlinx.cinterop.* fun bar(x: Int) = x.signExtend() ================================================ FILE: backend.native/tests/compilerChecks/t46.kt ================================================ import kotlinx.cinterop.* fun bar(x: Int) = x.narrow() ================================================ FILE: backend.native/tests/compilerChecks/t47.kt ================================================ import kotlinx.cinterop.* fun bar(x: Int) = x.convert() ================================================ FILE: backend.native/tests/compilerChecks/t48.kt ================================================ import kotlin.native.concurrent.* class Z(val x: Int) { fun bar(s: String) = s + x.toString() } fun foo(x: Int) { val worker = Worker.start() worker.execute(TransferMode.SAFE, { "zzz" }, Z(x)::bar) } ================================================ FILE: backend.native/tests/compilerChecks/t49.kt ================================================ import kotlin.native.concurrent.* fun foo(x: Int) { val worker = Worker.start() worker.execute(TransferMode.SAFE, { "zzz" }) { s -> s + x.toString() } } ================================================ FILE: backend.native/tests/compilerChecks/t5.kt ================================================ import platform.darwin.* import platform.Foundation.* fun foo() = NSAssertionHandler().handleFailureInFunction("zzz", "zzz", 0L, null, "qzz") ================================================ FILE: backend.native/tests/compilerChecks/t50.kt ================================================ import kotlin.native.concurrent.* class Z(val x: Int) { fun bar(s: String) = s + x.toString() } class Q(x: Int) { init { val worker = Worker.start() worker.execute(TransferMode.SAFE, { "zzz" }, Z(x)::bar) } } ================================================ FILE: backend.native/tests/compilerChecks/t51.kt ================================================ import kotlin.native.concurrent.* class Z(val x: Int) { fun bar(s: String) = s + x.toString() } class Q(x: Int) { val z = Worker.start().execute(TransferMode.SAFE, { "zzz" }, Z(x)::bar) } ================================================ FILE: backend.native/tests/compilerChecks/t52.kt ================================================ import kotlin.native.internal.* @OptIn(kotlin.ExperimentalStdlibApi::class) fun foo(x: Int) { createCleaner(42) { println(x) } } ================================================ FILE: backend.native/tests/compilerChecks/t53.kt ================================================ import kotlin.native.internal.* class C(val x: Int) { fun bar(y: Int) = println(x + y) } @OptIn(kotlin.ExperimentalStdlibApi::class) fun foo(x: Int) { createCleaner(42, C(x)::bar) } ================================================ FILE: backend.native/tests/compilerChecks/t54.kt ================================================ fun foo(arr: ShortArray) = immutableBlobOf(*arr) ================================================ FILE: backend.native/tests/compilerChecks/t55.kt ================================================ fun foo(x: Short) = immutableBlobOf(x) ================================================ FILE: backend.native/tests/compilerChecks/t56.kt ================================================ fun foo() = immutableBlobOf(1000) ================================================ FILE: backend.native/tests/compilerChecks/t57.kt ================================================ fun foo() = immutableBlobOf() ================================================ FILE: backend.native/tests/compilerChecks/t58.kt ================================================ import kotlin.reflect.* @OptIn(kotlin.ExperimentalStdlibApi::class) fun > foo() { typeOf>() } ================================================ FILE: backend.native/tests/compilerChecks/t59.kt ================================================ import kotlin.reflect.* @OptIn(kotlin.ExperimentalStdlibApi::class) inline fun > foo() { typeOf>() } ================================================ FILE: backend.native/tests/compilerChecks/t6.kt ================================================ import platform.darwin.* import platform.Foundation.* fun foo(s: Array) = NSAssertionHandler().handleFailureInFunction("zzz", "zzz", 0L, null, *s) ================================================ FILE: backend.native/tests/compilerChecks/t60.kt ================================================ import kotlinx.cinterop.* class Vertex constructor(rawPtr: NativePtr) : CStructVar(rawPtr) { var x: Float = 0f var y: Float = 0f var r: Float = 0f var g: Float = 0f var b: Float = 0f companion object : CStructVar.Type(40, 8) } ================================================ FILE: backend.native/tests/compilerChecks/t7.kt ================================================ import platform.darwin.* import platform.Foundation.* fun foo(s: Array) = NSLog("zzz", *s) ================================================ FILE: backend.native/tests/compilerChecks/t8.kt ================================================ import kotlinx.cinterop.* fun foo(f: Function0<*>) = f fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/compilerChecks/t9.kt ================================================ import kotlinx.cinterop.* fun foo(f: Function0) = f fun bar() { staticCFunction(::foo) } ================================================ FILE: backend.native/tests/coverage/basic/controlflow/main.kt ================================================ package coverage.basic.controlflow fun main() { // If Expression var a = 1 var b = 2 if (a < b) println("a < b") if (a > b) { println("a > b") } else if (a == b) { println("a == b") } else { println("a < b") } if (a < b) { println("a < b") } else { println("a >= b") } var max = if (a > b) a else b max = if (a > b) { println("Choose a") a } else { println("Choose b") b } if (a < b) println("a < b") else println("a >= b") if (a > b) println("a > b") else println("a <= b") // When Expression when { a < b -> { println("a < b") } a == b -> println("a == b") a > b -> { println("a > b") } else -> { } } var x = 1 when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Note the block print("x is neither 1 nor 2") } } x = 2 when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Note the block print("x is neither 1 nor 2") } } x = 3 when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Note the block print("x is neither 1 nor 2") } } when (x) { 0, 1 -> print("x == 0 or x == 1") else -> print("otherwise") } when { else -> println("=)") } // While Loops do { b++ } while (b < 5) while (a < 10) { a++ if (a > 7) { println(a) } } while (a > 0) a-- } ================================================ FILE: backend.native/tests/coverage/basic/jumps/main.kt ================================================ package coverage.basic.jumps fun simpleReturn(n: Int) { if (n == 0) return println(n) } fun returnFromIfBranch(n: Int) { if (n > 0) { if (n > 10) { return } } else if (n < -10) { return } else if (n == 0) { return } println(n) } fun returnFromWhenBranch(n: Int) { when { n == 0 -> return n == 1 -> return n == 2 -> { println(n) return } else -> println(n) } } fun breakFromWhile() { var a = 7 while (true) { if (a < 4) break println(a) a-- } } fun continueFromDoWhile() { var a = 0 do { if (a % 3 == 0) { a++ continue } println(a) a++ } while (a < 10) } fun singleReturn() { return } fun nestedReturn() { while (true) { while (true) { while (true) { if (1 < 2) { return } println() } println() } } println() } fun main() { simpleReturn(0) simpleReturn(1) returnFromIfBranch(1) returnFromIfBranch(11) returnFromIfBranch(-11) returnFromIfBranch(0) returnFromWhenBranch(0) returnFromWhenBranch(1) returnFromWhenBranch(2) breakFromWhile() continueFromDoWhile() singleReturn() nestedReturn() } ================================================ FILE: backend.native/tests/coverage/basic/library/library.kt ================================================ package coverage_library fun foo() = "foo" ================================================ FILE: backend.native/tests/coverage/basic/library/main.kt ================================================ package coverage.basic.library fun main() { println(coverage_library.foo()) } ================================================ FILE: backend.native/tests/coverage/basic/program/main.kt ================================================ package coverage.basic.program fun main() { println("OK") } ================================================ FILE: backend.native/tests/coverage/basic/smoke0/smoke0.kt ================================================ package coverage.basic.smoke0 data class User(val name: String) fun main() { val user = User("Happy Kotlin/Native user") println(user) } ================================================ FILE: backend.native/tests/coverage/basic/smoke1/smoke1.kt ================================================ package coverage.basic.smoke1 class A(val prop: Int) { constructor() : this(1) fun action1() { println(prop) } fun action2() { } } class B private constructor(val prop: String) { init { println("init block") } constructor(prop1: String, prop2: String) : this("$prop1, $prop2") constructor() : this("dummy") { if (1 > 2) { println("uncovered") } else { println("foo") } println("bar") } override fun toString() = prop } fun main(args: Array) { val a1 = A(2) a1.action1() a1.action2() val a2 = A() a2.action1() a2.action1() val b1 = B("Hello", "world") val b2 = B() println(b1) println(b2) } ================================================ FILE: backend.native/tests/datagen/literals/empty_string.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.literals.empty_string import kotlin.test.* @Test fun runTest() { println("") } ================================================ FILE: backend.native/tests/datagen/literals/listof1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.literals.listof1 import kotlin.test.* @Test fun runTest() { val list = foo() println(list === foo()) println(list.toString()) } fun foo(): List { return listOf("a", "b", "c") } ================================================ FILE: backend.native/tests/datagen/literals/strdedup1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.literals.strdedup1 import kotlin.test.* @Test fun runTest() { val str1 = "Hello" val str2 = "Hello" println(str1 == str2) println(str1 === str2) } ================================================ FILE: backend.native/tests/datagen/literals/strdedup2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.literals.strdedup2 import kotlin.test.* @Test fun runTest() { val str1 = "" val str2 = "hello".subSequence(2, 2) println(str1 == str2) println(str1 === str2) } ================================================ FILE: backend.native/tests/datagen/rtti/abstract_super.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.rtti.abstract_super import kotlin.test.* abstract class Super class Foo : Super() @Test fun runTest() { // This test now checks that the source can be successfully compiled and linked; // TODO: check the contents of TypeInfo? } ================================================ FILE: backend.native/tests/datagen/rtti/vtable1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.rtti.vtable1 import kotlin.test.* abstract class Super { abstract fun bar() } class Foo : Super() { final override fun bar() {} } @Test fun runTest() { // This test now checks that the source can be successfully compiled and linked; // TODO: check the contents of TypeInfo? } ================================================ FILE: backend.native/tests/datagen/rtti/vtable_any.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package datagen.rtti.vtable_any import kotlin.test.* @Test fun runTest() { // Try to trick devirtualizer println(anyMethods(arrayListOf("1"))) println(anyMethods(mapOf("2" to 1).keys)) println(anyMethods(mapOf("1" to 3).values)) println(anyMethods(setOf("4"))) } fun anyMethods(iterable: Iterable<*>): String { assert(iterable.equals(iterable)) assert(iterable.hashCode() != 0) return iterable.toString() } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/DistProperties.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.test.debugger import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.HostManager import java.nio.file.Path import java.nio.file.Paths object DistProperties { private val dist: Path = Paths.get(requireProp("kotlin.native.home")) private val konancDriver = if (HostManager.host.family == Family.MINGW) "konanc.bat" else "konanc" private val cinteropDriver = if (HostManager.host.family == Family.MINGW) "cinterop.bat" else "cinterop" val konanc: Path = dist.resolve("bin/$konancDriver") val cinterop: Path = dist.resolve("bin/$cinteropDriver") val lldb: Path = Paths.get("lldb") val devToolsSecurity: Path = Paths.get("DevToolsSecurity") val dwarfDump: Path = Paths.get("dwarfdump") val swiftc: Path = Paths.get("swiftc") val lldbPrettyPrinters: Path = dist.resolve("tools/konan_lldb.py") private fun requireProp(name: String): String = System.getProperty(name) ?: error("Property `$name` is not defined") } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/Driver.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.test.debugger import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import org.jetbrains.kotlin.cli.bc.K2Native import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.StringReader import java.nio.file.Files import java.nio.file.Path import java.util.concurrent.TimeUnit class ToolDriver( private val useInProcessCompiler: Boolean = false ) { fun compile(source: Path, output: Path, vararg args: String) = compile(output, *args) { listOf("-output", output.toString(), source.toString(), *args).toTypedArray() } fun compile(output: Path, srcs:Array, vararg args: String) = compile(output, *args) { listOf("-output", output.toString(), *srcs.map{it.toString()}.toTypedArray(), *args).toTypedArray() } private fun compile(output: Path, vararg args: String, argsCalculator:() -> Array) { check(!Files.exists(output)) val allArgs = argsCalculator() if (useInProcessCompiler) { K2Native.main(allArgs) } else { subprocess(DistProperties.konanc, *allArgs).thrownIfFailed() } check(Files.exists(output)) { "Compiler has not produced an output at $output" } } fun cinterop(defFile:Path, output: Path, pkg: String, vararg args: String) { val allArgs = listOf("-o", output.toString(), "-def", defFile.toString(), "-pkg", pkg, *args).toTypedArray() //TODO: do we need in process cinterop? subprocess(DistProperties.cinterop, *allArgs).thrownIfFailed() check(Files.exists(output)) { "Compiler has not produced an output at $output" } } fun runLldb(program: Path, commands: List): String { val args = listOf("-b", "-o", "command script import \"${DistProperties.lldbPrettyPrinters}\"") + commands.flatMap { listOf("-o", it) } return subprocess(DistProperties.lldb, program.toString(), "-b", *args.toTypedArray()) .thrownIfFailed() .stdout } fun runDwarfDump(program: Path, vararg args:String = emptyArray(), processor:List.()->Unit) { val dwarfProcess = subprocess(DistProperties.dwarfDump, *args, "${program}.dSYM/Contents/Resources/DWARF/${program.fileName}") val out = dwarfProcess.takeIf { it.process.exitValue() == 0 }?.stdout ?: error(dwarfProcess.stderr) DwarfUtilParser().parse(StringReader(out)).tags.toList().processor() } fun swiftc(output: Path, swiftSrc: Path, vararg args: String) { val swiftProcess = subprocess(DistProperties.swiftc, "-o", output.toString(), swiftSrc.toString(), *args) val out = swiftProcess.takeIf { it.process.exitValue() == 0 }?.stdout ?: error(swiftProcess.stderr) } } data class ProcessOutput( val program: Path, val process: Process, val stdout: String, val stderr: String, val durationMs: Long ) { fun thrownIfFailed(): ProcessOutput { fun renderStdStream(name: String, text: String): String = if (text.isBlank()) "$name is empty" else "$name:\n$text" check(process.exitValue() == 0) { """$program exited with non-zero value: ${process.exitValue()} |${renderStdStream("stdout", stdout)} |${renderStdStream("stderr", stderr)} """.trimMargin() } return this } } fun subprocess(program: Path, vararg args: String): ProcessOutput { val start = System.currentTimeMillis() val process = ProcessBuilder(program.toString(), *args).start() val out = GlobalScope.async(Dispatchers.IO) { readStream(process, process.inputStream.buffered()) } val err = GlobalScope.async(Dispatchers.IO) { readStream(process, process.errorStream.buffered()) } return runBlocking { try { val status = process.waitFor(5L, TimeUnit.MINUTES) if (!status) { out.cancel() err.cancel() error("$program timeouted") } }catch (e:Exception) { out.cancel() err.cancel() error(e) } ProcessOutput(program, process, out.await(), err.await(), System.currentTimeMillis() - start) } } private fun readStream(process: Process, stream: InputStream): String { var size = 4096 val buffer = ByteArray(size) { 0 } val sunk = ByteArrayOutputStream() while (true) { size = stream.read(buffer, 0, buffer.size) if (size < 0 && !process.isAlive) break if (size > 0) sunk.write(buffer, 0, size) } return String(sunk.toByteArray()) } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/DwarfDumpParser.kt ================================================ package org.jetbrains.kotlin.native.test.debugger import java.io.File import java.io.Reader import java.lang.StringBuilder sealed class DwarfTag(val tag: Tag) { enum class Tag(val value: Int) { DW_TAG_array_type(0x0001), DW_TAG_class_type(0x0002), DW_TAG_entry_point(0x0003), DW_TAG_enumeration_type(0x0004), DW_TAG_formal_parameter(0x0005), DW_TAG_imported_declaration(0x0008), DW_TAG_label(0x000a), DW_TAG_lexical_block(0x000b), DW_TAG_member(0x000d), DW_TAG_pointer_type(0x000f), DW_TAG_reference_type(0x0010), DW_TAG_compile_unit(0x0011), DW_TAG_string_type(0x0012), DW_TAG_structure_type(0x0013), DW_TAG_subroutine_type(0x0015), DW_TAG_typedef(0x0016), DW_TAG_union_type(0x0017), DW_TAG_unspecified_parameters(0x0018), DW_TAG_variant(0x0019), DW_TAG_common_block(0x001a), DW_TAG_common_inclusion(0x001b), DW_TAG_inheritance(0x001c), DW_TAG_inlined_subroutine(0x001d), DW_TAG_module(0x001e), DW_TAG_ptr_to_member_type(0x001f), DW_TAG_set_type(0x0020), DW_TAG_subrange_type(0x0021), DW_TAG_with_stmt(0x0022), DW_TAG_access_declaration(0x0023), DW_TAG_base_type(0x0024), DW_TAG_catch_block(0x0025), DW_TAG_const_type(0x0026), DW_TAG_constant(0x0027), DW_TAG_enumerator(0x0028), DW_TAG_file_type(0x0029), DW_TAG_friend(0x002a), DW_TAG_namelist(0x002b), DW_TAG_namelist_item(0x002c), DW_TAG_packed_type(0x002d), DW_TAG_subprogram(0x002e), DW_TAG_template_type_parameter(0x002f), DW_TAG_template_value_parameter(0x0030), DW_TAG_thrown_type(0x0031), DW_TAG_try_block(0x0032), DW_TAG_variant_part(0x0033), DW_TAG_variable(0x0034), DW_TAG_volatile_type(0x0035), DW_TAG_dwarf_procedure(0x0036), DW_TAG_restrict_type(0x0037), DW_TAG_interface_type(0x0038), DW_TAG_namespace(0x0039), DW_TAG_imported_module(0x003a), DW_TAG_unspecified_type(0x003b), DW_TAG_partial_unit(0x003c), DW_TAG_imported_unit(0x003d), DW_TAG_condition(0x003f), DW_TAG_shared_type(0x0040), DW_TAG_type_unit(0x0041), DW_TAG_rvalue_reference_type(0x0042), DW_TAG_template_alias(0x0043), DW_TAG_coarray_type(0x0044), DW_TAG_generic_subrange(0x0045), DW_TAG_dynamic_type(0x0046), DW_TAG_MIPS_loop(0x4081), DW_TAG_format_label(0x4101), DW_TAG_function_template(0x4102), DW_TAG_class_template(0x4103), DW_TAG_GNU_template_template_param(0x4106), DW_TAG_GNU_template_parameter_pack(0x4107), DW_TAG_GNU_formal_parameter_pack(0x4108), DW_TAG_APPLE_property(0x4200), DW_TAG_BORLAND_property(0xb000), DW_TAG_BORLAND_Delphi_string(0xb001), DW_TAG_BORLAND_Delphi_dynamic_array(0xb002), DW_TAG_BORLAND_Delphi_set(0xb003), DW_TAG_BORLAND_Delphi_variant(0xb004), } val attributes = mutableMapOf() operator fun DwarfAttribute.unaryPlus() { attributes[this.attribute] = this } companion object { fun by(name: String) = by(Tag.valueOf(name)) fun by(tag: Tag) = when(tag) { Tag.DW_TAG_subprogram -> DwarfTagSubprogram() else -> DwarfTagDefault(tag) } } } class DwarfTagDefault(tag: DwarfTag.Tag): DwarfTag(tag) class DwarfTagSubprogram: DwarfTag(Tag.DW_TAG_subprogram) { val name: String get() = attributes[DwarfAttribute.Attribute.DW_AT_name]!!.rvString val path: String? get() = attributes[DwarfAttribute.Attribute.DW_AT_decl_file]?.rvString val file: File? get() = path?.run { File(this) } } class DwarfAttribute(val attribute: Attribute, val rawValue: String) { enum class Attribute(val value: Int) { DW_AT_sibling(0x01), DW_AT_location(0x02), DW_AT_name(0x03), DW_AT_ordering(0x09), DW_AT_byte_size(0x0b), DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x0d), DW_AT_stmt_list(0x10), DW_AT_low_pc(0x11), DW_AT_high_pc(0x12), DW_AT_language(0x13), DW_AT_discr(0x15), DW_AT_discr_value(0x16), DW_AT_visibility(0x17), DW_AT_import(0x18), DW_AT_string_length(0x19), DW_AT_common_reference(0x1a), DW_AT_comp_dir(0x1b), DW_AT_const_value(0x1c), DW_AT_containing_type(0x1d), DW_AT_default_value(0x1e), DW_AT_inline(0x20), DW_AT_is_optional(0x21), DW_AT_lower_bound(0x22), DW_AT_producer(0x25), DW_AT_prototyped(0x27), DW_AT_return_addr(0x2a), DW_AT_start_scope(0x2c), DW_AT_bit_stride(0x2e), DW_AT_upper_bound(0x2f), DW_AT_abstract_origin(0x31), DW_AT_accessibility(0x32), DW_AT_address_class(0x33), DW_AT_artificial(0x34), DW_AT_base_types(0x35), DW_AT_calling_convention(0x36), DW_AT_count(0x37), DW_AT_data_member_location(0x38), DW_AT_decl_column(0x39), DW_AT_decl_file(0x3a), DW_AT_decl_line(0x3b), DW_AT_declaration(0x3c), DW_AT_discr_list(0x3d), DW_AT_encoding(0x3e), DW_AT_external(0x3f), DW_AT_frame_base(0x40), DW_AT_friend(0x41), DW_AT_identifier_case(0x42), DW_AT_macro_info(0x43), DW_AT_namelist_item(0x44), DW_AT_priority(0x45), DW_AT_segment(0x46), DW_AT_specification(0x47), DW_AT_static_link(0x48), DW_AT_type(0x49), DW_AT_use_location(0x4a), DW_AT_variable_parameter(0x4b), DW_AT_virtuality(0x4c), DW_AT_vtable_elem_location(0x4d), DW_AT_allocated(0x4e), DW_AT_associated(0x4f), DW_AT_data_location(0x50), DW_AT_byte_stride(0x51), DW_AT_entry_pc(0x52), DW_AT_use_UTF8(0x53), DW_AT_extension(0x54), DW_AT_ranges(0x55), DW_AT_trampoline(0x56), DW_AT_call_column(0x57), DW_AT_call_file(0x58), DW_AT_call_line(0x59), DW_AT_description(0x5a), DW_AT_binary_scale(0x5b), DW_AT_decimal_scale(0x5c), DW_AT_small(0x5d), DW_AT_decimal_sign(0x5e), DW_AT_digit_count(0x5f), DW_AT_picture_string(0x60), DW_AT_mutable(0x61), DW_AT_threads_scaled(0x62), DW_AT_explicit(0x63), DW_AT_object_pointer(0x64), DW_AT_endianity(0x65), DW_AT_elemental(0x66), DW_AT_pure(0x67), DW_AT_recursive(0x68), DW_AT_signature(0x69), DW_AT_main_subprogram(0x6a), DW_AT_data_bit_offset(0x6b), DW_AT_const_expr(0x6c), DW_AT_enum_class(0x6d), DW_AT_linkage_name(0x6e), DW_AT_string_length_bit_size(0x6f), DW_AT_string_length_byte_size(0x70), DW_AT_rank(0x71), DW_AT_str_offsets_base(0x72), DW_AT_addr_base(0x73), DW_AT_rnglists_base(0x74), DW_AT_dwo_id(0x75), ///< Retracted from DWARF v5. DW_AT_dwo_name(0x76), DW_AT_reference(0x77), DW_AT_rvalue_reference(0x78), DW_AT_macros(0x79), DW_AT_call_all_calls(0x7a), DW_AT_call_all_source_calls(0x7b), DW_AT_call_all_tail_calls(0x7c), DW_AT_call_return_pc(0x7d), DW_AT_call_value(0x7e), DW_AT_call_origin(0x7f), DW_AT_call_parameter(0x80), DW_AT_call_pc(0x81), DW_AT_call_tail_call(0x82), DW_AT_call_target(0x83), DW_AT_call_target_clobbered(0x84), DW_AT_call_data_location(0x85), DW_AT_call_data_value(0x86), DW_AT_noreturn(0x87), DW_AT_alignment(0x88), DW_AT_export_symbols(0x89), DW_AT_deleted(0x8a), DW_AT_defaulted(0x8b), DW_AT_loclists_base(0x8c), DW_AT_MIPS_loop_begin(0x2002), DW_AT_MIPS_tail_loop_begin(0x2003), DW_AT_MIPS_epilog_begin(0x2004), DW_AT_MIPS_loop_unroll_factor(0x2005), DW_AT_MIPS_software_pipeline_depth(0x2006), DW_AT_MIPS_linkage_name(0x2007), DW_AT_MIPS_stride(0x2008), DW_AT_MIPS_abstract_name(0x2009), DW_AT_MIPS_clone_origin(0x200a), DW_AT_MIPS_has_inlines(0x200b), DW_AT_MIPS_stride_byte(0x200c), DW_AT_MIPS_stride_elem(0x200d), DW_AT_MIPS_ptr_dopetype(0x200e), DW_AT_MIPS_allocatable_dopetype(0x200f), DW_AT_MIPS_assumed_shape_dopetype(0x2010), DW_AT_MIPS_assumed_size(0x2011), DW_AT_sf_names(0x2101), DW_AT_src_info(0x2102), DW_AT_mac_info(0x2103), DW_AT_src_coords(0x2104), DW_AT_body_begin(0x2105), DW_AT_body_end(0x2106), DW_AT_GNU_vector(0x2107), DW_AT_GNU_template_name(0x2110), DW_AT_GNU_odr_signature(0x210f), DW_AT_GNU_call_site_value(0x2111), DW_AT_GNU_all_call_sites(0x2117), DW_AT_GNU_macros(0x2119), DW_AT_GNU_dwo_name(0x2130), DW_AT_GNU_dwo_id(0x2131), DW_AT_GNU_ranges_base(0x2132), DW_AT_GNU_addr_base(0x2133), DW_AT_GNU_pubnames(0x2134), DW_AT_GNU_pubtypes(0x2135), DW_AT_GNU_discriminator(0x2136), DW_AT_BORLAND_property_read(0x3b11), DW_AT_BORLAND_property_write(0x3b12), DW_AT_BORLAND_property_implements(0x3b13), DW_AT_BORLAND_property_index(0x3b14), DW_AT_BORLAND_property_default(0x3b15), DW_AT_BORLAND_Delphi_unit(0x3b20), DW_AT_BORLAND_Delphi_class(0x3b21), DW_AT_BORLAND_Delphi_record(0x3b22), DW_AT_BORLAND_Delphi_metaclass(0x3b23), DW_AT_BORLAND_Delphi_constructor(0x3b24), DW_AT_BORLAND_Delphi_destructor(0x3b25), DW_AT_BORLAND_Delphi_anonymous_method(0x3b26), DW_AT_BORLAND_Delphi_interface(0x3b27), DW_AT_BORLAND_Delphi_ABI(0x3b28), DW_AT_BORLAND_Delphi_return(0x3b29), DW_AT_BORLAND_Delphi_frameptr(0x3b30), DW_AT_BORLAND_closure(0x3b31), DW_AT_LLVM_include_path(0x3e00), DW_AT_LLVM_config_macros(0x3e01), DW_AT_LLVM_isysroot(0x3e02), DW_AT_APPLE_optimized(0x3fe1), DW_AT_APPLE_flags(0x3fe2), DW_AT_APPLE_isa(0x3fe3), DW_AT_APPLE_block(0x3fe4), DW_AT_APPLE_major_runtime_vers(0x3fe5), DW_AT_APPLE_runtime_class(0x3fe6), DW_AT_APPLE_omit_frame_ptr(0x3fe7), DW_AT_APPLE_property_name(0x3fe8), DW_AT_APPLE_property_getter(0x3fe9), DW_AT_APPLE_property_setter(0x3fea), DW_AT_APPLE_property_attribute(0x3feb), DW_AT_APPLE_objc_complete_type(0x3fec), DW_AT_APPLE_property(0x3fed), } companion object { fun by(name: String, rawValue: String): DwarfAttribute = by(Attribute.valueOf(name), rawValue) fun by(attribute: Attribute, rawValue: String) = DwarfAttribute(attribute, rawValue) } } val DwarfAttribute.rvString: String get() = rawValue.trim().substring(1, rawValue.length - 2) class DwarfUtilParser() { val tags = mutableListOf() var currentTag: DwarfTag? = null var currentAttribute: DwarfAttribute.Attribute? = null val currentAttributePayload = StringBuilder() companion object { val tagRegexp = Regex("^(0x[0-9a-f]{8}):\\ +([^\\ .]*)$") val attributeRegexp = Regex("^\\s+(DW_AT_[a-zA-Z0-9_]*)\\s+\\((.*)\\)$") } fun tag(tag: DwarfTag) { appendCurrentAttribute() tags.add(tag) currentTag = tag currentAttribute = null } private fun appendCurrentAttribute() { currentTag ?: return with(currentTag!!) { currentAttribute ?: return +DwarfAttribute.by(currentAttribute!!, currentAttributePayload.toString()) currentAttributePayload.clear() } } fun attribute(attribute: DwarfAttribute.Attribute, payload: String) { appendCurrentAttribute() currentAttribute = attribute currentAttributePayload.appendLine(payload) } fun parse(reader: Reader): DwarfUtilParser { reader.forEachLine { line -> tagRegexp.find(line)?.apply { val str = this.destructured.component2().trim() if (str == "NULL") return@forEachLine tag(DwarfTag.by(str)) return@forEachLine } attributeRegexp.find(line)?.apply { attribute(DwarfAttribute.Attribute.valueOf(destructured.component1()), destructured.component2()) return@forEachLine } currentTag ?: return@forEachLine currentAttributePayload.appendLine(line) } return this } } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/DwarfTests.kt ================================================ package org.jetbrains.kotlin.native.test.debugger import junit.framework.Assert.* import org.junit.Ignore import org.junit.Test class DwarfTests { @Test fun `prefix test`() = dwarfDumpTest(""" fun main(args: Array) { val xs = intArrayOf(3, 5, 8) return } data class Point(val x: Int, val y: Int) """.trimIndent(), listOf("-Xdebug-prefix-map=${System.getProperty("user.home")}=/xxx")){ val map = flatMap( fun (it: DwarfTag): List { return it.attributes.values.toList()}) .filter { it.attribute == DwarfAttribute.Attribute.DW_AT_decl_file }.map { it.rvString } assertNotSame(0, map.size) } /** * TODO: to enable this test it's required to fix issue with poisonig call site with wrong file owner ship of lambda * passed as parameter to inline function. */ @Test fun `address of VolatileLambda lookup`() = dwarfDumpComplexTest { val callbackLibrary = """ --- int callback(int (*f)(int)) { return 42 + f(0xdeadbeef); } """.trimIndent().cinterop("callback", "callback") val trapLibrary = """ --- void trap() { __builtin_trap(); } """.trimIndent().cinterop("trap", "trap") val poisonLibrary = """ package poison import trap.* import callback.* import kotlinx.cinterop.staticCFunction inline fun execute():Int { return callback(staticCFunction{ a -> trap() 2 * a }) } """.trimIndent().library("poison", "-l", callbackLibrary.toString(), "-l", trapLibrary.toString()) val binary = """ import poison.* fun main() { execute() } """.trimIndent().binary("poisoned", "-g", "-l", poisonLibrary.toString(), "-l", callbackLibrary.toString(), "-l", trapLibrary.toString()) binary.dwarfDumpLookup("kfun:main\$_1#internal") { assertFalse(this.isEmpty()) val subprogram = single { it.tag == DwarfTag.Tag.DW_TAG_subprogram } as DwarfTagSubprogram assertEquals(subprogram.file!!.name, "poison.kt") } } } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/LldbTests.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.native.test.debugger.lldbComplexTest import org.jetbrains.kotlin.native.test.debugger.lldbTest import org.junit.Test class LldbTests { @Test fun `can step through code`() = lldbTest(""" fun main(args: Array) { var x = 1 var y = 2 var z = x + y println(z) } """, """ > b main.kt:2 Breakpoint 1: [..] > r Process [..] stopped [..] stop reason = breakpoint 1.1 [..] at main.kt:2[..] > n Process [..] stopped [..] stop reason = step over [..] at main.kt:3[..] > n Process [..] stopped [..] stop reason = step over [..] at main.kt:4[..] > n Process [..] stopped [..] stop reason = step over [..] at main.kt:5[..] """) @Test fun `can inspect values of primitive types`() = lldbTest(""" fun main(args: Array) { var a: Byte = 1 var b: Int = 2 var c: Long = -3 var d: Char = 'c' var e: Boolean = true return } """, """ > b main.kt:7 > r > fr var (char) a = '\x01' (int) b = 2 (long) c = -3 (short) d = 99 (bool) e = true """) @Test fun `can inspect classes`() = lldbTest(""" fun main(args: Array) { val point = Point(1, 2) val person = Person() return } data class Point(val x: Int, val y: Int) class Person { override fun toString() = "John Doe" } """, """ > b main.kt:4 > r > fr var (ObjHeader *) args = [] (ObjHeader *) point = [x: ..., y: ...] (ObjHeader *) person = [] """) @Test fun `can inspect arrays`() = lldbTest(""" fun main(args: Array) { val xs = IntArray(3) xs[0] = 1 xs[1] = 2 xs[2] = 3 val ys: Array = arrayOfNulls(2) ys[0] = Point(1, 2) return } data class Point(val x: Int, val y: Int) """, """ > b main.kt:8 > r > fr var (ObjHeader *) args = [] (ObjHeader *) xs = [..., ..., ...] (ObjHeader *) ys = [..., ...] """) @Test fun `can inspect array children`() = lldbTest(""" fun main(args: Array) { val xs = intArrayOf(3, 5, 8) return } data class Point(val x: Int, val y: Int) """, """ > b main.kt:3 > r > fr var xs (ObjHeader *) xs = [..., ..., ...] """) @Test fun `swift with kotlin static framework`() = lldbComplexTest { val aKtSrc = """ fun a() = "a" """.feedOutput("a.kt") val bKtSrc = """ fun b() = "b" """.feedOutput("b.kt") arrayOf(aKtSrc, bKtSrc).framework("AandBFramework", "-g", "-Xstatic-framework") val swiftSrc = """ import AandBFramework print(AKt.a()) print(BKt.b()) """.feedOutput("test.swift") val application = swiftc("application", swiftSrc, "-F", root.toString()) """ > b kfun:#b(){}kotlin.String Breakpoint 1: where = [..]`kfun:#b(){}kotlin.String [..] at b.kt:1:1, [..] > b kfun:#a(){}kotlin.String Breakpoint 2: where = [..]`kfun:#a(){}kotlin.String [..] at a.kt:1:1, [..] """.trimIndent().lldb(application) } } ================================================ FILE: backend.native/tests/debugger/src/test/kotlin/org/jetbrains/kotlin/native/test/debugger/Matchers.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.native.test.debugger import org.intellij.lang.annotations.Language import org.junit.Assert.fail import java.io.IOException import java.nio.file.Files import java.nio.file.Path /** * An integration test for debug info. * * It works by compiling a given [programText] with debug info, * then launching lldb, feeding it commands from [lldbSession] * and matching the output. * * [lldbSession] specifies both lldb commands and expected output * using a DLS, which looks like this: * * > b main.kt:5 * Breakpoint 1: [..] * > r * Process [..] stopped * [..] at main.kt:5, [..] stop reason = breakpoint [..] * > fr var * (int) a = 92 * (int) b = 2 * * It consists of blocks of the form * * > lldb command * response line pattern * another pattern * * Command after `>` is passed to lldb exactly. The output of the command * is then matched against a set of patterns. Matching is done line by line: * for every pattern, there must be a matching line in the output, but you don't * have to specify a pattern for every line. In particular, it's possible not to * specify any patterns at all: * * > b main.kt:2 * > r * > n * [..] at main.kt:3, [..] stop reason = step over * * The patterns themselves are simple. The only special symbol is `[..]` which * means arbitrary substring, which can help match random data, timings, and OS-dependent output. * For example, to match * * Current executable set to '/tmp/debugger_test7458723719928260513/program.kexe' (x86_64). * * one writes * * Current executable set to [..]program.kexe[..] */ fun lldbTest(@Language("kotlin") programText: String, lldbSession: String) { if (!haveLldb) { println("Skipping test: no LLDB") return } if (!isOsxDevToolsEnabled) { println("""Development tools aren't available. |Please consider to execute: | ${DistProperties.devToolsSecurity} -enable |or | csrutil disable |to run lldb tests""".trimMargin()) return } val lldbSessionSpec = LldbSessionSpecification.parse(lldbSession) val tmpdir = Files.createTempDirectory("debugger_test") tmpdir.toFile().deleteOnExit() val source = tmpdir.resolve("main.kt") val output = tmpdir.resolve("program.kexe") val driver = ToolDriver() Files.write(source, programText.trimIndent().toByteArray()) driver.compile(source, output, "-g") val result = driver.runLldb(output, lldbSessionSpec.commands) lldbSessionSpec.match(result) } private val isOsxDevToolsEnabled: Boolean by lazy { //TODO: add OSX checks. val rawStatus = subprocess(DistProperties.devToolsSecurity, "-status") println("> status: $rawStatus") val r = Regex("^.*\\ (enabled|disabled).$") r.find(rawStatus.stdout)?.destructured?.component1() == "enabled" } fun dwarfDumpTest(@Language("kotlin") programText: String, flags: List, test:List.()->Unit) { if (!haveDwarfDump) { println("Skipping test: no dwarfdump") return } with(Files.createTempDirectory("dwarfdump_test")) { toFile().deleteOnExit() val source = resolve("main.kt") val output = resolve("program.kexe") val driver = ToolDriver() Files.write(source, programText.trimIndent().toByteArray()) driver.compile(source, output, "-g", *flags.toTypedArray()) driver.runDwarfDump(output, processor = test) } } class ToolDriverHelper(private val driver: ToolDriver, val root:Path) { fun String.cinterop(pkg:String, output: String):Path { val def = feedOutput("$output.def") val lib = root.resolve("$output.klib") driver.cinterop(def, lib, pkg) return lib } fun String.library(output: String, vararg flags:String) = feedOutput("$output.kt").compile(root.resolve("$output.klib"), "-p", "library", *flags) fun String.binary(output: String, vararg flags:String)= feedOutput("$output.kt").compile(root.resolve("$output.kexe"), *flags) private fun Path.compile(output: Path, vararg flags:String) = output.also{ driver.compile(source = this, it, *flags) } fun Path.dwarfDumpLookup(address: Long, parser:List.() -> Unit) = driver.runDwarfDump(this, "-lookup", address.toString(), processor = parser) fun Path.dwarfDumpLookup(name: String, parser:List.() -> Unit) = driver.runDwarfDump(this, "-find", name, processor = parser) fun String.feedOutput(output: String) = root.resolve(output).also { Files.write(it, this.trimIndent().toByteArray()) } fun Array.framework(name:String, vararg args:String = emptyArray()):Path = root.resolve("$name.framework").also { driver.compile(it, this, "-produce", "framework", *args) } fun swiftc(output: String, swiftSrc: Path, vararg args: String) = root.resolve(output).also { driver.swiftc(it, swiftSrc, *args, "-Xlinker", "-rpath", "-Xlinker", "@executable_path") } fun String.lldb(program:Path) { val lldbSessionSpec = LldbSessionSpecification.parse(this) val result = driver.runLldb(program, lldbSessionSpec.commands) lldbSessionSpec.match(result) } } fun dwarfDumpComplexTest(test:ToolDriverHelper.()->Unit) { if (!haveDwarfDump) { println("Skipping test: no dwarfdump") return } with(Files.createTempDirectory("dwarfdump_test_complex")) { toFile().deleteOnExit() val driver = ToolDriverHelper(ToolDriver(), this).test() } } fun lldbComplexTest(test:ToolDriverHelper.()->Unit) { if (!haveLldb) { println("Skipping test: no lldb") return } with(Files.createTempDirectory("lldb_test_complex")) { toFile().deleteOnExit() val driver = ToolDriverHelper(ToolDriver(), this).test() } } private val haveDwarfDump: Boolean by lazy { val version = try { subprocess(DistProperties.dwarfDump, "--version") .takeIf { it.process.exitValue() == 0 } ?.stdout } catch (e: IOException) { null } if (version == null) { println("No LLDB found") } else { println("Using $version") } version != null } private val haveLldb: Boolean by lazy { val lldbVersion = try { subprocess(DistProperties.lldb, "-version") .takeIf { it.process.exitValue() == 0 } ?.stdout } catch (e: IOException) { null } if (lldbVersion == null) { println("No LLDB found") } else { println("Using $lldbVersion") } lldbVersion != null } private class LldbSessionSpecification private constructor( val commands: List, val patterns: List> ) { fun match(output: String) { val blocks = output.split("""(?=\(lldb\))""".toRegex()).filterNot(String::isEmpty) check(blocks[0].startsWith("(lldb) target create")) { "Missing block \"target create\". Got: ${blocks[0]}" } check(blocks[1].startsWith("(lldb) command script import")) { "Missing block \"command script import\". Got: ${blocks[0]}" } val responses = blocks.drop(2) val executedCommands = responses.map { it.lines().first() } val bodies = responses.map { it.lines().drop(1) } val responsesMatch = executedCommands.size == commands.size && commands.zip(executedCommands).all { (cmd, h) -> h == "(lldb) $cmd" } if (!responsesMatch) { val message = """ |Responses do not match commands. | |COMMANDS: |$commands |RESPONSES: |$executedCommands | |FULL SESSION: |$output """.trimMargin() fail(message) } for ((patternBody, command) in patterns.zip(bodies).zip(executedCommands)) { val (pattern, body) = patternBody val mismatch = findMismatch(pattern, body) if (mismatch != null) { val message = """ |Wrong LLDB output. | |COMMAND: $command |PATTERN: $mismatch |OUTPUT: |${body.joinToString("\n")} | |FULL SESSION: |$output """.trimMargin() fail(message) } } } private fun findMismatch(patterns: List, actualLines: List): String? { val indices = mutableListOf() for (pattern in patterns) { val idx = actualLines.indexOfFirst { match(pattern, it) } if (idx == -1) { return pattern } indices += idx } check(indices == indices.sorted()) return null } private fun match(pattern: String, line: String): Boolean { val chunks = pattern.split("""\s*\[\.\.]\s*""".toRegex()) .filter { it.isNotBlank() } .map { it.trim() } check(chunks.isNotEmpty()) val trimmedLine = line.trim() val indices = chunks.map { trimmedLine.indexOf(it) } if (indices.any { it == -1 } || indices != indices.sorted()) return false if (!(trimmedLine.startsWith(chunks.first()) || pattern.startsWith("[..]"))) return false if (!(trimmedLine.endsWith(chunks.last()) || pattern.endsWith("[..]"))) return false return true } companion object { fun parse(spec: String): LldbSessionSpecification { val blocks = spec.trimIndent() .split("(?=^>)".toRegex(RegexOption.MULTILINE)) .filterNot(String::isEmpty) for (cmd in blocks) { check(cmd.startsWith(">")) { "Invalid lldb session specification: $cmd" } } val commands = blocks.map { it.lines().first().substring(1).trim() } val patterns = blocks.map { it.lines().drop(1).filter { it.isNotBlank() } } return LldbSessionSpecification(commands, patterns) } } } ================================================ FILE: backend.native/tests/extensions/nop/src/main/kotlin/org/jetbrains/konan/test/plugin/nop/NopPlugin.kt ================================================ package org.jetbrains.konan.test.plugin.nop import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.ir.declarations.IrModuleFragment open class NopExtension : IrGenerationExtension { override fun generate( moduleFragment: IrModuleFragment, pluginContext: IrPluginContext ) { } } ================================================ FILE: backend.native/tests/external/codegen/box/properties/lateinit/accessor.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ ================================================ FILE: backend.native/tests/framework/gh3343/ktlib.kt ================================================ import kotlinx.cinterop.* import objclib.* import kotlin.native.ref.* fun run(): List { val result = mutableListOf() result.add(foo1(42)) val list = foo2(117) if (list != null) { result.add(list.size) for (x in list) result.add(x) } return result } ================================================ FILE: backend.native/tests/framework/gh3343/objclib.def ================================================ language = Objective-C headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h headerFilter = **/objclib.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h ================================================ FILE: backend.native/tests/framework/gh3343/objclib.h ================================================ #import NSString* foo1(int x) { return [NSString stringWithFormat:@"%d", x]; } NSArray* foo2(int x) { NSValue* xx = @(x); NSString* s = @"zzz"; return [NSArray arrayWithObjects: xx, s, nil]; } ================================================ FILE: backend.native/tests/framework/gh3343/uselib.swift ================================================ import Foundation import Gh3343 func testGh3343() throws { let list = KtlibKt.run() try assertEquals(actual: list[0] as? String, expected: "42") try assertEquals(actual: list[1] as? Int, expected: 2) try assertEquals(actual: list[2] as? Int, expected: 117) try assertEquals(actual: list[3] as? String, expected: "zzz") } // -------- Execution of the test -------- class UselibTests : TestProvider { var tests: [TestCase] = [] init() { providers.append(self) tests = [ TestCase(name: "Gh3343", method: withAutorelease(testGh3343)), ] } } ================================================ FILE: backend.native/tests/framework/kt42397/knlibrary.kt ================================================ import kotlin.native.Platform // The following 2 singletons are unused. However, since we are generating ObjC bindings for them, // they should be marked as used, so that the code generator emits their deinitialization. object A { fun foo() = 1 } class B { companion object { fun foo() = 2 } } fun enableMemoryChecker() { Platform.isMemoryLeakCheckerActive = true } ================================================ FILE: backend.native/tests/framework/kt42397/test.swift ================================================ import Kt42397 class Results { var aFoo: Int32 = 0 var bFoo: Int32 = 0 } func runTestKt42397(pointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { autoreleasepool { KnlibraryKt.enableMemoryChecker() let results = pointer.bindMemory(to: Results.self, capacity: 1).pointee results.aFoo = A().foo() results.bFoo = B.Companion().foo() } return nil } func testKt42397() throws { let results = Results() let resultsPtr = UnsafeMutablePointer.allocate(capacity: 1) resultsPtr.initialize(to: results) var thread: pthread_t? = nil let result = pthread_create(&thread, nil, runTestKt42397, resultsPtr) try assertEquals(actual: result, expected: 0) pthread_join(thread!, nil) try assertEquals(actual: results.aFoo, expected: 1) try assertEquals(actual: results.bFoo, expected: 2) } // -------- Execution of the test -------- class TestTests : SimpleTestProvider { override init() { super.init() test("Kt42397", testKt42397) } } ================================================ FILE: backend.native/tests/framework/kt43517/kt43517.def ================================================ --- enum E { A, B, C }; struct S { int i; float f; }; struct S globalS = { .i = 3, .f = 3.14f }; enum E createEnum() { return A; } ================================================ FILE: backend.native/tests/framework/kt43517/kt43517.kt ================================================ import kt43517.* fun produceEnum(): E = createEnum() fun compareEnums(e1: E, e2: E): Boolean = e1 == e2 fun getFirstField(s: S): Int = s.i fun getGlobalS(): S = globalS ================================================ FILE: backend.native/tests/framework/kt43517/kt43517.swift ================================================ import Foundation import Kt43517 func testKt43517() throws { try assertEquals( actual: Kt43517Kt.compareEnums(e1: Kt43517Kt.produceEnum(), e2: Kt43517Kt.produceEnum()), expected: true ) try assertEquals( actual: Kt43517Kt.getFirstField(s: Kt43517Kt.getGlobalS()), expected: 3 ) } class Kt43517Tests : TestProvider { var tests: [TestCase] = [] init() { providers.append(self) tests = [ TestCase(name: "Kt43517", method: withAutorelease(testKt43517)), ] } } ================================================ FILE: backend.native/tests/framework/main.swift ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation enum TestError : Error { case assertFailed(String) case failure case testsFailed([String]) } // ---------------- Assertions ---------------- private func throwAssertFailed(message: String, file: String, line: Int) throws -> Never { throw TestError.assertFailed("\(file):\(line): \(message)") } func assertEquals(actual: T, expected: T, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line) throws { if (actual != expected) { try throwAssertFailed(message: message + " Expected value: \(expected), but got: \(actual)", file: file, line: line) } } func assertSame(actual: AnyObject?, expected: AnyObject?, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line) throws { if (actual !== expected) { try throwAssertFailed(message: message + " Expected value: \(expected), but got: \(actual)", file: file, line: line) } } func assertEquals(actual: [T], expected: [T], _ message: String = "Assertion failed: arrays not equal", file: String = #file, line: Int = #line) throws { try assertEquals(actual: actual.count, expected: expected.count, "Size differs", file: file, line: line) try assertTrue(actual.elementsEqual(expected), "Arrays elements are not equal", file: file, line: line) } func assertTrue(_ value: Bool, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line) throws { if (value != true) { try throwAssertFailed(message: message + " Expected value to be TRUE, but got: \(value)", file: file, line: line) } } func assertFalse(_ value: Bool, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line) throws { if (value != false) { try throwAssertFailed(message: message + " Expected value to be FALSE, but got: \(value)", file: file, line: line) } } func assertNil(_ value: Any?, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line) throws { if (value != nil) { try throwAssertFailed(message: message + " Expected value to be nil, but got: \(value!)", file: file, line: line) } } func fail(_ message: String = "Should not reach here", file: String = #file, line: Int = #line) throws -> Never { try throwAssertFailed(message: message, file: file, line: line) } func assertFailsWith(_ errorType: T.Type, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line, block: () throws -> Void) throws { do { try block() } catch let error { if error is T { return } try throwAssertFailed(message: message + " Expected error \(errorType), got \(error)", file: file, line: line) } try throwAssertFailed(message: message + " Expected error \(errorType), but finished successfully", file: file, line: line) } func assertFailsWithKotlin(_ exceptionType: T.Type, _ message: String = "Assertion failed:", file: String = #file, line: Int = #line, block: () throws -> Void) throws { do { try block() } catch let error { let kotlinException = error.kotlinException if kotlinException is T { return } let got = kotlinException ?? error try throwAssertFailed(message: message + " Expected Kotlin exception \(exceptionType), got \(got)", file: file, line: line) } try throwAssertFailed(message: message + " Expected Kotlin exception \(exceptionType), but finished successfully", file: file, line: line) } // ---------------- Utils -------------------- func withAutorelease( _ method: @escaping () throws -> Void) -> () throws -> Void { return { () throws -> Void in try autoreleasepool { try method() } } } extension Error { var kotlinException: Any? { get { return (self as NSError).userInfo["KotlinException"] } } } // ---------------- Execution ---------------- private final class Statistics : CustomStringConvertible { var passed: [String] = [] var failed: [String] = [] var description: String { return """ ---- RESULTS: PASSED: \(passed.count) FAILED: \(failed.count) """ } static let instance = Statistics() static func getInstance() -> Statistics { return instance } func start(_ name: String) { print("---- Starting test: \(name)") } func passed(_ name: String) { print("---- PASSED test: \(name)") passed.append(name) } func failed(_ name: String, error: Error) { print("---- FAILED test: \(name) with error: \(error)") failed.append(name) } } /** * TestCase represents a single test */ struct TestCase { let name: String let method: () throws -> Void init(name: String, method: @escaping () throws -> Void) { self.name = name self.method = method } func run() { let stats = Statistics.getInstance() stats.start(name) do { try method() stats.passed(name) } catch { stats.failed(name, error: error) } } } protocol TestProvider { var tests: [TestCase] { get } } class SimpleTestProvider : TestProvider { var tests: [TestCase] = [] init() { providers.append(self) } func test(_ name: String, _ method: @escaping () throws -> Void) { tests.append(TestCase(name: name, method: withAutorelease(method))) } } var providers: [TestProvider] = [] private func execute(tests: [TestCase]) { for test in tests { test.run() } } /** * Entry point of the test */ private func main() { // Generated method that instantiates test providers. registerProviders() let stats = Statistics.getInstance() for pr in providers { let name = String(describing: type(of: pr)) print("-- \(name) started") execute(tests: pr.tests) print("-- \(name) finished") } print(stats) let failed = stats.failed if !failed.isEmpty { print() print("Tests failed:") for testName in failed { print(":: \(testName)") } abort() } } main() ================================================ FILE: backend.native/tests/framework/multiple/framework1/first.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED") package multiple interface I1 { fun getFortyTwo(): Int } class I1Impl : I1 { override fun getFortyTwo(): Int = 42 } fun getI1() = object : I1 { override fun getFortyTwo(): Int = 42 } class C fun getUnit(): Unit? = Unit /* // Disabled for now to avoid depending on platform libs. fun getAnonymousObject() = object : platform.darwin.NSObject() {} class NamedObject : platform.darwin.NSObject() fun getNamedObject() = NamedObject() */ ================================================ FILE: backend.native/tests/framework/multiple/framework1/test.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED") package multiple val name = "first" ================================================ FILE: backend.native/tests/framework/multiple/framework2/second.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED") package multiple interface I2 { fun getFortyTwo(): Int } fun getFortyTwoFrom(i2: I2): Int = i2.getFortyTwo() fun getI2() = object : I2 { override fun getFortyTwo(): Int = 42 } class C fun isUnit(obj: Any?): Boolean = (obj === Unit) /* // Disabled for now to avoid depending on platform libs. fun getAnonymousObject() = object : platform.darwin.NSObject() {} class NamedObject : platform.darwin.NSObject() fun getNamedObject() = NamedObject() */ ================================================ FILE: backend.native/tests/framework/multiple/framework2/test.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED") package multiple val name = "second" ================================================ FILE: backend.native/tests/framework/multiple/multiple.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import First import Second func testClashingNames() throws { try assertEquals(actual: "first", expected: First.TestKt.name) try assertEquals(actual: "second", expected: Second.TestKt.name) let c1 = First.C() let c2 = Second.C() try assertTrue(type(of: c1) == First.C.self) try assertTrue(type(of: c2) == Second.C.self) try assertTrue(First.C.self != Second.C.self) try assertTrue(objc_getClass(class_getName(First.C.self)) as AnyObject === First.C.self) try assertTrue(objc_getClass(class_getName(Second.C.self)) as AnyObject === Second.C.self) } extension I1Impl : I2 {} func testInteraction() throws { try assertEquals(actual: SecondKt.getFortyTwoFrom(i2: I1Impl()), expected: 42) } func testIsolation1() throws { try assertFalse(SecondKt.isUnit(obj: FirstKt.getUnit())) // Ensure frameworks don't share the same runtime (state): try assertFalse(First.RuntimeState().consumeChange()) try assertFalse(Second.RuntimeState().consumeChange()) Second.RuntimeState().produceChange() try assertFalse(First.RuntimeState().consumeChange()) try assertTrue(Second.RuntimeState().consumeChange()) } func testIsolation2() throws { try assertEquals(actual: FirstKt.getI1().getFortyTwo(), expected: 42) try assertEquals(actual: SecondKt.getI2().getFortyTwo(), expected: 42) } func testIsolation3() throws { #if false // Disabled for now to avoid depending on platform libs. FirstKt.getAnonymousObject() SecondKt.getAnonymousObject() FirstKt.getNamedObject() SecondKt.getNamedObject() #endif } // https://youtrack.jetbrains.com/issue/KT-34261 // When First and Second are static frameworks with caches, this test fails due to bad cache isolation: // Caches included into both frameworks have 'ktypew' globals (with same name, hidden visibility and common linkage) // for writable part of this "unexposed stdlib class" TypeInfo. // ld ignores hidden visibility and merges common globals, so two independent frameworks happen to share // the same global instead of two different globals. Things go wrong at runtime then: this writable TypeInfo part // is used to store Obj-C class for this Kotlin class. So after the first object is obtained in Swift, both TypeInfos // have its class, and the second object is wrong then. func testIsolation4() throws { let obj1: Any = First.SharedKt.getUnexposedStdlibClassInstance() try assertTrue(obj1 is First.KotlinBase) try assertFalse(obj1 is Second.KotlinBase) let obj2: Any = Second.SharedKt.getUnexposedStdlibClassInstance() try assertFalse(obj2 is First.KotlinBase) try assertTrue(obj2 is Second.KotlinBase) } class MultipleTests : TestProvider { var tests: [TestCase] = [] init() { tests = [ TestCase(name: "TestClashingNames", method: withAutorelease(testClashingNames)), TestCase(name: "TestInteraction", method: withAutorelease(testInteraction)), TestCase(name: "TestIsolation1", method: withAutorelease(testIsolation1)), TestCase(name: "TestIsolation2", method: withAutorelease(testIsolation2)), TestCase(name: "TestIsolation3", method: withAutorelease(testIsolation3)), TestCase(name: "TestIsolation4", method: withAutorelease(testIsolation4)), ] providers.append(self) } } ================================================ FILE: backend.native/tests/framework/multiple/shared/shared.kt ================================================ import kotlin.native.concurrent.Worker object RuntimeState { fun produceChange() { Worker.current.executeAfter {} } fun consumeChange(): Boolean { return Worker.current.processQueue() } } // Note: this assumes that IntRange class is not exposed by the enclosing framework. fun getUnexposedStdlibClassInstance(): Any = 0..2 ================================================ FILE: backend.native/tests/framework/stdlib/stdlib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED") package stdlib fun isEmpty(map: Map) = map.isEmpty() fun getKeysAsSet(map: Map) = map.keys fun getKeysAsList(map: Map) = map.keys.toList() fun toMutableMap(map: HashMap) = map.toMutableMap() fun getFirstElement(collection: Collection) = collection.first() class GenericExtensionClass> (private val holder: T?) { fun getFirstKey(): K? = holder?.entries?.first()?.key fun getFirstValue() : V? { holder?.entries?.forEach { e -> println("KEY: ${e.key} VALUE: ${e.value}") } return holder?.entries?.first()?.value } } fun createPair(): Pair, GenericExtensionClass>> { val l = createLinkedMap() val g = GenericExtensionClass(l) return Pair(l, g) } fun createLinkedMap() = linkedMapOf() fun createTypedMutableMap() = linkedMapOf() fun addSomeElementsToMap(map: MutableMap) { map.put(key = "XYZ", value = 321) map.put(key = "TMP", value = 451) } fun list(vararg elements: Any?): Any = listOf(*elements) fun set(vararg elements: Any?): Any = setOf(*elements) fun map(vararg keysAndValues: Any?): Any = mutableMapOf().apply { (0 until keysAndValues.size step 2).forEach {index -> this[keysAndValues[index]] = keysAndValues[index + 1] } } fun emptyMutableList(): Any = mutableListOf() fun emptyMutableSet(): Any = mutableSetOf() fun emptyMutableMap(): Any = mutableMapOf() data class TripleVals(val first: T, val second: T, val third: T) data class TripleVars(var first: T, var second: T, var third: T) { override fun toString(): String { return "[$first, $second, $third]" } } fun gc() = kotlin.native.internal.GC.collect() ================================================ FILE: backend.native/tests/framework/stdlib/stdlib.swift ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation import Stdlib extension NSEnumerator { func remainingObjects() -> [Any?] { var result = [Any?]() while (true) { if let next = self.nextObject() { result.append(next as AnyObject as Any?) } else { break } } return result } } class StdlibTests : TestProvider { var tests: [TestCase] = [] init() { tests = [ TestCase(name: "TestEmptyDictionary", method: withAutorelease(testEmptyDictionary)), TestCase(name: "TestGenericMapUsage", method: withAutorelease(testGenericMapUsage)), TestCase(name: "TestOrderedMapStored", method: withAutorelease(testOrderedMapStored)), TestCase(name: "TestTypedMapUsage", method: withAutorelease(testTypedMapUsage)), TestCase(name: "TestFirstElement", method: withAutorelease(testFirstElement)), TestCase(name: "TestAddDictionary", method: withAutorelease(testAddDictionary)), TestCase(name: "TestList", method: withAutorelease(testList)), TestCase(name: "TestMutableList", method: withAutorelease(testMutableList)), TestCase(name: "TestSet", method: withAutorelease(testSet)), TestCase(name: "TestMutableSet", method: withAutorelease(testMutableSet)), TestCase(name: "TestMap", method: withAutorelease(testMap)), TestCase(name: "TestMutableMap", method: withAutorelease(testMutableMap)), TestCase(name: "TestKotlinMutableSetInit", method: withAutorelease(testKotlinMutableSetInit)), TestCase(name: "TestKotlinMutableDictionaryInit", method: withAutorelease(testKotlinMutableDictionaryInit)), ] providers.append(self) } /** * Pass empty dictionary to Kotlin. */ func testEmptyDictionary() throws { let immutableEmptyDict = [String: Int]() try assertTrue(StdlibKt.isEmpty(map: immutableEmptyDict), "Empty dictionary") let keys = StdlibKt.getKeysAsSet(map: immutableEmptyDict) try assertTrue(keys.isEmpty, "Should have empty set") } /** * Tests usage of a map with generics. */ func testGenericMapUsage() throws { let map = StdlibKt.createLinkedMap() map[1] = "One" map[10] = "Ten" map[11] = "Eleven" map["10"] = "Ten as string" for (k, v) in map { print("MAP: \(k) - \(v)") } try assertEquals(actual: map[11] as! String, expected: "Eleven", "An element of the map for key: 11") } /** * Checks order of the underlying LinkedHashMap. */ func testOrderedMapStored() throws { let pair = StdlibKt.createPair() let map = pair.first as? NSMutableDictionary map?[1] = "One" map?[10] = "Ten" map?[11] = "Eleven" map?["10"] = "Ten as string" let gen = pair.second as! GenericExtensionClass let value: String? = gen.getFirstValue() as? String try assertEquals(actual: value!, expected: "One", "First value of the map") let key: Int? = gen.getFirstKey() as? Int try assertEquals(actual: key!, expected: 1, "First key of the map") } /** * Tests typed map created in Kotlin. */ func testTypedMapUsage() throws { let map = StdlibKt.createTypedMutableMap() map[1] = "One" map[1.0 as Float] = "Float" map[11] = "Eleven" map["10"] = "Ten as string" try assertEquals(actual: map["10"] as! String, expected: "Ten as string", "String key") try assertEquals(actual: map[1.0 as Float] as! String, expected: "Float", "Float key") } /** * Get first element of the collection. */ func testFirstElement() throws { let m = StdlibKt.createTypedMutableMap() m[10] = "Str" try assertEquals(actual: StdlibKt.getFirstElement(collection: m.allKeys) as! Int, expected: 10, "First key") try assertEquals(actual: StdlibKt.getFirstElement(collection: StdlibKt.getKeysAsList(map: m as! Dictionary)) as! Int, expected: 10, "First key from a list") } /** * Add element to dictionary in Kotlin */ func testAddDictionary() throws { let m = [ "ABC": 10, "CDE": 12, "FGH": 3 ] StdlibKt.addSomeElementsToMap(map: KotlinMutableDictionary(dictionary: m)) for (k, v) in m { print("MAP: \(k) - \(v)") } var smd = KotlinMutableDictionary() smd.setObject(333, forKey: "333" as NSString) try assertEquals(actual: smd.object(forKey: "333" as NSString) as! Int, expected: 333, "Add element to dict") StdlibKt.addSomeElementsToMap(map: smd) for (k, v) in smd { print("MAP: \(k) - \(v)") } try assertEquals(actual: smd.object(forKey: "XYZ" as NSString) as! Int, expected: 321, "Get element from Kotlin") } func zeroTo(_ n: Int32) -> KotlinArray { return KotlinArray(size: n) { $0 } } func testList() throws { let elements = zeroTo(5) elements.set(index: 1, value: nil) let list = StdlibKt.list(elements: elements) as! NSArray try assertEquals(actual: list.object(at: 2) as! NSNumber, expected: NSNumber(value: 2)) try assertEquals(actual: list.object(at: 1) as! NSNull, expected: NSNull()) try assertEquals(actual: list.count, expected: 5) } func testMutableList() throws { let kotlinList = StdlibKt.emptyMutableList() as! NSMutableArray let nsList = NSMutableArray() func apply(op: (NSMutableArray)->T) throws { let actual = op(kotlinList) let expected = op(nsList) try assertEquals(actual: actual, expected: expected) try assertEquals(actual: kotlinList, expected: nsList) try assertEquals(actual: kotlinList.hash, expected: nsList.hash) } func applyVoid(op: (NSMutableArray)->Void) throws { op(kotlinList) op(nsList) try assertEquals(actual: kotlinList, expected: nsList) try assertEquals(actual: kotlinList.hash, expected: nsList.hash) } try apply { $0.count } try applyVoid { $0.insert(0, at: 0) } try applyVoid { $0.insert(1, at: 0) } try applyVoid { $0.insert(2, at: 1) } try applyVoid { $0.removeObject(at: 0) } try applyVoid { $0.add("foo") } try applyVoid { $0.removeLastObject() } try applyVoid { $0.replaceObject(at: 0, with: "bar") } let NULL: Any? = nil try applyVoid { $0.add(NULL as Any) } try applyVoid { $0.insert(NULL as Any, at: 2) } try applyVoid { $0.replaceObject(at: 1, with: NULL as Any) } try apply { $0.count } } func testMutableSet() throws { let kotlinSet = StdlibKt.emptyMutableSet() as! NSMutableSet let nsSet = NSMutableSet() func apply(op: (NSMutableSet)->T) throws { let actual = op(kotlinSet) let expected = op(nsSet) try assertEquals(actual: actual, expected: expected) try assertEquals(actual: kotlinSet, expected: nsSet) try assertEquals(actual: kotlinSet.hash, expected: nsSet.hash) } func applyVoid(op: (NSMutableSet)->Void) throws { op(kotlinSet) op(nsSet) try assertEquals(actual: kotlinSet, expected: nsSet) try assertEquals(actual: kotlinSet.hash, expected: nsSet.hash) } try apply { $0.count } try applyVoid { $0.add("foo") } try applyVoid { $0.add("bar") } try applyVoid { $0.remove("baz") } try applyVoid { $0.add("baz") } try applyVoid { $0.add(TripleVals(first: 1, second: 2, third: 3)) } try apply { $0.member(TripleVals(first: 1, second: 2, third: 3)) as! TripleVals } try apply { $0.member(42) == nil } try applyVoid { $0.remove(TripleVals(first: 1, second: 2, third: 3)) } let NULL0: Any? = nil let NULL = NULL0 as Any try applyVoid { $0.add(NULL) } try apply { $0.member(NULL) == nil } try apply { $0.member(NULL) as! NSObject } try applyVoid { $0.remove(NULL) } try apply { $0.member(NULL) == nil } try apply { NSSet(array: $0.objectEnumerator().remainingObjects()) } try apply { $0.count } } func testMutableMap() throws { // TODO: test KotlinMutableSet/Dictionary constructors let kotlinMap = StdlibKt.emptyMutableMap() as! NSMutableDictionary let nsMap = NSMutableDictionary() func apply(op: (NSMutableDictionary)->T) throws { let actual = op(kotlinMap) let expected = op(nsMap) try assertEquals(actual: actual, expected: expected) try assertEquals(actual: kotlinMap, expected: nsMap) try assertEquals(actual: kotlinMap.hash, expected: nsMap.hash) } func applyVoid(op: (NSMutableDictionary) throws -> Void) throws { try op(kotlinMap) try op(nsMap) try assertEquals(actual: kotlinMap, expected: nsMap) try assertEquals(actual: kotlinMap.hash, expected: nsMap.hash) } try apply { $0.count } try apply { $0.object(forKey: 42) == nil } try applyVoid { $0.setObject(42, forKey: 42 as NSNumber) } try applyVoid { $0.setObject(17, forKey: "foo" as NSString) } let triple = TripleVals(first: 3, second: 2, third: 1) try applyVoid { $0.setObject("bar", forKey: triple) } try applyVoid { $0.removeObject(forKey: 42) } try apply { $0.count } try apply { $0.object(forKey: 42) == nil } try apply { $0.object(forKey: "foo") as! NSObject } try apply { $0.object(forKey: triple) as! NSObject } try apply { NSSet(array: $0.keyEnumerator().remainingObjects()) } let NULL0: Any? = nil let NULL = NULL0 as Any try apply { $0.object(forKey: NULL) == nil } try applyVoid { $0.setObject(42, forKey: NULL as! NSCopying) } try applyVoid { $0.setObject(NULL, forKey: "baz" as NSString) } try apply { $0.object(forKey: NULL) as! NSObject } try apply { $0.object(forKey: "baz") as! NSObject } try apply { NSSet(array: $0.keyEnumerator().remainingObjects()) } try applyVoid { $0.removeObject(forKey: NULL) } try applyVoid { $0.removeObject(forKey: "baz") } try applyVoid { $0.removeAllObjects() } let myKey = MyKey() try applyVoid { $0.setObject(myKey, forKey: myKey) } try applyVoid { let key = $0.allKeys[0] as! MyKey let value = $0.allValues[0] as! MyKey try assertFalse(key === myKey) try assertTrue(value === myKey) } } @objc class MyKey : NSObject, NSCopying { override var hash: Int { return 42 } override func isEqual(_ object: Any?) -> Bool { return object is MyKey } func copy(with: NSZone? = nil) -> Any { return MyKey() } } func testSet() throws { let elements = KotlinArray(size: 2) { index in nil } elements.set(index: 0, value: nil) elements.set(index: 1, value: 42 as NSNumber) let set = StdlibKt.set(elements: elements) as! NSSet try assertEquals(actual: set.count, expected: 2) try assertEquals(actual: set.member(NSNull()) as! NSNull, expected: NSNull()) try assertEquals(actual: set.member(42) as! NSNumber, expected: NSNumber(value: 42 as Int32)) try assertTrue(set.member(17) == nil) try assertFalse(set.member(42) as AnyObject === NSNumber(value: 42 as Int32)) try assertTrue(set.contains(42)) try assertTrue(set.contains(nil as Any?)) try assertFalse(set.contains(17)) try assertEquals(actual: NSSet(array: set.objectEnumerator().remainingObjects()), expected: NSSet(array: [nil, 42] as [AnyObject])) } func testMap() throws { let elements = KotlinArray(size: 6) { index in nil } elements.set(index: 0, value: nil) elements.set(index: 1, value: 42 as NSNumber) elements.set(index: 2, value: "foo" as NSString) elements.set(index: 3, value: "bar" as NSString) elements.set(index: 4, value: 42 as NSNumber) elements.set(index: 5, value: nil) let map = StdlibKt.map(keysAndValues: elements) as! NSDictionary try assertEquals(actual: map.count, expected: 3) try assertEquals(actual: map.object(forKey: NSNull()) as! NSNumber, expected: NSNumber(value: 42)) try assertEquals(actual: map.object(forKey: "foo") as! String, expected: "bar") try assertEquals(actual: map.object(forKey: 42) as! NSNull, expected: NSNull()) try assertTrue(map.object(forKey: "bar") == nil) try assertEquals(actual: NSSet(array: map.keyEnumerator().remainingObjects()), expected: NSSet(array: [nil, 42, "foo"] as [AnyObject])) } func testKotlinMutableSetInit() throws { func test( _ set: KotlinMutableSet, _ check: (KotlinMutableSet) throws -> Void = { _ in } ) throws { try assertEquals(actual: String(describing: type(of: set)), expected: "StdlibMutableSet") try check(set) try assertFalse(set.contains("1")) set.add("1") try assertTrue(set.contains("1")) } try test(KotlinMutableSet()) try test(KotlinMutableSet(capacity: 1)) try test(KotlinMutableSet(object: "2")) { try assertTrue($0.contains("2")) } var threeAndFour = ["3", "4"] as [AnyObject] try test(KotlinMutableSet(objects: &threeAndFour, count: 2)) { try assertTrue($0.contains("3")) try assertTrue($0.contains("4")) } try test(KotlinMutableSet(array: ["5", "6"])) { try assertTrue($0.contains("5")) try assertTrue($0.contains("6")) } try test(KotlinMutableSet(set: ["7", "8"])) { try assertTrue($0.contains("7")) try assertTrue($0.contains("8")) } for flag in [false, true] { try test(KotlinMutableSet(set: ["9", "10"], copyItems: flag)) { try assertTrue($0.contains("9")) try assertTrue($0.contains("10")) } } /* TODO: doesn't work, KotlinMutableSet seems to be serialized as NSMutableSet. if #available(macOS 10.13, *) { let data = try! NSKeyedArchiver.archivedData( withRootObject: KotlinMutableSet(array: ["11", "12"]), requiringSecureCoding: false ) try test(try! NSKeyedUnarchiver.unarchivedObject(ofClass: KotlinMutableSet.self, from: data)!) { try assertTrue($0.contains("11")) try assertTrue($0.contains("12")) } } */ StdlibKt.gc() // To reproduce https://github.com/JetBrains/kotlin-native/issues/3259 } func testKotlinMutableDictionaryInit() throws { func test( _ dict: KotlinMutableDictionary, _ check: (KotlinMutableDictionary) throws -> Void = { _ in } ) throws { try assertEquals(actual: String(describing: type(of: dict)), expected: "StdlibMutableDictionary") try check(dict) try assertTrue(dict["1"] == nil) dict["1"] = "2" try assertTrue(dict["1"] as? NSString == "2") } try test(KotlinMutableDictionary()) try test(KotlinMutableDictionary(capacity: 4)) // TODO: test [initWithCoder:]. try test(KotlinMutableDictionary(objects: ["3", "4"], forKeys: ["4", "3"] as [NSString])) { try assertEquals(actual: $0["3"] as? String, expected: "4") try assertEquals(actual: $0["4"] as? String, expected: "3") } var fiveAndSix = ["5", "6"] as [AnyObject] var sixAndFive = ["6", "5"] as [NSCopying] try test(KotlinMutableDictionary(objects: &fiveAndSix, forKeys: &sixAndFive, count: 2)) { try assertEquals(actual: $0["5"] as? String, expected: "6") try assertEquals(actual: $0["6"] as? String, expected: "5") } try test(KotlinMutableDictionary(object: "7", forKey: "8" as NSString)) { try assertEquals(actual: $0["8"] as? String, expected: "7") } try test(KotlinMutableDictionary(dictionary: ["10" : "9"])) { try assertEquals(actual: $0["10"] as? String, expected: "9") } for flag in [false, true] { try test(KotlinMutableDictionary(dictionary: ["12" : "11"], copyItems: flag)) { try assertEquals(actual: $0["12"] as? String, expected: "11") } } try test(KotlinMutableDictionary(dictionaryLiteral: ("14", "13"))) { try assertEquals(actual: $0["14"] as? String, expected: "13") } StdlibKt.gc() // To reproduce https://github.com/JetBrains/kotlin-native/issues/3259 } } ================================================ FILE: backend.native/tests/framework/values_generics/values.swift ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation import ValuesGenerics // -------- Tests -------- func testVararg() throws { let ktArray = KotlinArray(size: 3, init: { (_) -> KotlinInt in return KotlinInt(int:42) }) let arr: [Int] = ValuesKt.varargToList(args: ktArray as! KotlinArray) as! [Int] try assertEquals(actual: arr, expected: [42, 42, 42]) } func testDataClass() throws { let f = "1" as NSString let s = "2" as NSString let t = "3" as NSString let tripleVal = TripleVals(first: f, second: s, third: t) try assertEquals(actual: tripleVal.first, expected: f, "Data class' value") try assertEquals(actual: tripleVal.first, expected: "1", "Data class' value literal") try assertEquals(actual: tripleVal.component2(), expected: s, "Data class' component") print(tripleVal) try assertEquals(actual: String(describing: tripleVal), expected: "TripleVals(first=\(f), second=\(s), third=\(t))") let tripleVar = TripleVars(first: f, second: s, third: t) try assertEquals(actual: tripleVar.first, expected: f, "Data class' value") try assertEquals(actual: tripleVar.component2(), expected: s, "Data class' component") print(tripleVar) try assertEquals(actual: String(describing: tripleVar), expected: "[\(f), \(s), \(t)]") tripleVar.first = t tripleVar.second = f tripleVar.third = s try assertEquals(actual: tripleVar.component2(), expected: f, "Data class' component") try assertEquals(actual: String(describing: tripleVar), expected: "[\(t), \(f), \(s)]") } func testInlineClasses() throws { let ic1: Int32 = 42 let ic1N = ValuesKt.box(ic1: 17) let ic2 = "foo" let ic2N = "bar" let ic3 = TripleVals(first: KotlinInt(int:1), second: KotlinInt(int:2), third: KotlinInt(int:3)) let ic3N = ValuesKt.box(ic3: nil) try assertEquals( actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: ic1N, ic2: ic2, ic2N: ic2N, ic3: ic3, ic3N: ic3N), expected: "42 17 foo bar TripleVals(first=1, second=2, third=3) null" ) try assertEquals( actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: nil, ic2: ic2, ic2N: nil, ic3: nil, ic3N: nil), expected: "42 null foo null null null" ) try assertEquals(actual: ValuesKt.getValue1(ic1), expected: 42) try assertEquals(actual: ValuesKt.getValueOrNull1(ic1N) as! Int, expected: 17) try assertEquals(actual: ValuesKt.getValue2(ic2), expected: "foo") try assertEquals(actual: ValuesKt.getValueOrNull2(ic2N), expected: "bar") try assertEquals(actual: ValuesKt.getValue3(ic3), expected: ic3) try assertEquals(actual: ValuesKt.getValueOrNull3(ic3N), expected: nil) } func testGeneric() throws { let a = SomeGeneric(t: SomeData(num: 52)) let asd : SomeData = a.myVal()! try assertEquals(actual: asd.num, expected: 52) let nulls = GenOpen(arg: SomeData(num: 62)) let nullssd : SomeData = nulls.arg! try assertEquals(actual: nullssd.num, expected: 62) let isnull = GenOpen(arg: nil) try assertEquals(actual: isnull.arg, expected: nil) let nonnulls = GenNonNull(arg: SomeData(num: 72)) let nonnullssd : SomeData = nonnulls.arg try assertEquals(actual: nonnullssd.num, expected: 72) try assertEquals(actual: (Values_genericsKt.starGeneric(arg: nonnulls as! GenNonNull) as! SomeData).num, expected: 72) let sd = SomeData(num: 33) let nullColl = GenCollectionsNull(arg: sd, coll: [sd]) let nonNullColl = GenCollectionsNonNull(arg: sd, coll: [sd]) try assertEquals(actual: (nullColl.coll[0] as! SomeData).num, expected: 33) let nonNullCollSd : SomeData = nonNullColl.coll[0] try assertEquals(actual: nonNullCollSd.num, expected: 33) try assertEquals(actual: nonNullColl.arg, expected: nonNullCollSd) let mixed = GenNullability(arg: sd, nArg: sd) try assertEquals(actual: mixed.asNullable()?.num, expected: 33) try assertEquals(actual: mixed.pAsNullable?.num, expected: 33) let mixedSd : SomeData? = mixed.pAsNullable try assertEquals(actual: mixedSd, expected: mixed.nArg) } // Swift ignores the variance and lets you force-cast to whatever you need, for better or worse. // This would *not* work with direct Swift interop. func testGenericVariance() throws { let sd = SomeData(num: 22) let variOut = GenVarOut(arg: sd) let variOutAny : GenVarOut = variOut as! GenVarOut let variOutOther : GenVarOut = variOut as! GenVarOut let variOutCheck = "variOut: \(variOut.arg.asString()), variOutAny: \(variOutAny.arg.asString()), variOutOther: \(variOutOther.arg.asString())" try assertEquals(actual: variOutCheck, expected: "variOut: 22, variOutAny: 22, variOutOther: 22") let variIn = GenVarIn(tArg: sd) let variInAny : GenVarIn = variIn as! GenVarIn let variInOther : GenVarIn = variIn as! GenVarIn let varInCheck = "variIn: \(variIn.valString()), variInAny: \(variInAny.valString()), variInOther: \(variInOther.valString())" try assertEquals(actual: varInCheck, expected: "variIn: SomeData(num=22), variInAny: SomeData(num=22), variInOther: SomeData(num=22)") let variCoType:GenVarOut = Values_genericsKt.variCoType() try assertEquals(actual: "890", expected: variCoType.arg.asString()) let variContraType:GenVarIn = Values_genericsKt.variContraType() try assertEquals(actual: "SomeData(num=1890)", expected: variContraType.valString()) } // Swift should completely ignore this, as should objc. Really verifying that the header generator // deals with this func testGenericUseSiteVariance() throws { let sd = SomeData(num: 22) let varUse = GenVarUse(arg: sd) let varUseArg = GenVarUse(arg: sd) varUse.varUse(a: varUseArg, b: GenVarUse(arg: sd) as! GenVarUse) } func testGenericInterface() throws { let a: NoGeneric = SomeGeneric(t: SomeData(num: 52)) try assertEquals(actual: (a.myVal() as! SomeData).num, expected: 52) } func testGenericInheritance() throws { let ge = GenEx(myT:SomeOtherData(str:"Hello"), baseT:SomeData(num: 11)) let geT : SomeData = ge.t try assertEquals(actual: geT.num, expected: 11) let gemyT : SomeOtherData = ge.myT try assertEquals(actual: gemyT.str, expected: "Hello") let geBase = ge as GenBase let geBaseT : SomeData = geBase.t try assertEquals(actual: geBaseT.num, expected: 11) //Similar to above but param names don't match and will dupe property definitions on child class //Functional, but should be fixed let ge2 = GenEx2(myT:SomeOtherData(str:"Hello2"), baseT:SomeData(num: 22)) let ge2Val : SomeData = ge2.t let ge2SODVal : SomeOtherData = ge2.myT let ge2base : GenBase = ge2 as GenBase let ge2BaseVal : SomeData = ge2base.t try assertEquals(actual: ge2Val, expected: ge2BaseVal) let geAny = GenExAny(myT:SomeOtherData(str:"Hello"), baseT:SomeData(num: 131)) try assertEquals(actual: (geAny.t as! SomeData).num, expected: 131) let geBaseAny = geAny as! GenBase let geBaseAnyT : SomeData = geBaseAny.t try assertEquals(actual: geBaseAnyT.num, expected: 131) } func testGenericInnerClass() throws { let nestedClass = GenOuterGenNested(b: SomeData(num: 543)) let nestedClassB : SomeData = nestedClass.b try assertEquals(actual: nestedClassB.num, expected: 543) let innerClass = GenOuterGenInner(GenOuter(a: SomeOtherData(str: "ggg")), c: SomeData(num: 66), aInner: SomeOtherData(str: "ttt")) let innerClassC : SomeData = innerClass.c try assertEquals(actual: innerClassC.num, expected: 66) let outerFun : SomeOtherData = innerClass.outerFun() let outerVal : SomeOtherData = innerClass.outerVal try assertEquals(actual: outerFun, expected: outerVal) try assertEquals(actual: outerFun.str, expected: "ggg") Values_genericsKt.genInnerFunc(obj: innerClass) Values_genericsKt.genInnerFuncAny(obj: innerClass as! GenOuterGenInner) let innerReturned : GenOuterGenInner = Values_genericsKt.genInnerCreate() let innerReturnedInner : SomeOtherData = innerReturned.c try assertEquals(actual: innerReturnedInner.str, expected: "ppp") let nestedClassSame = GenOuterSameGenNestedSame(a: SomeData(num: 545)) let nestedClassSameA : SomeData = nestedClassSame.a try assertEquals(actual: nestedClassSameA.num, expected: 545) let nested = GenOuterSameNestedNoGeneric() let innerClassSame = GenOuterSameGenInnerSame(GenOuterSame(a: SomeData(num: 44)), a: SomeOtherData(str: "rrr")) let innerClassSameA : SomeOtherData = innerClassSame.a try assertEquals(actual: innerClassSame.a.str, expected: "rrr") let gob : GenOuterBlankGenInner = GenOuterBlankGenInner(GenOuterBlank(sd: SomeData(num: 321)), arg: SomeOtherData(str: "aaa")) let gob2 : GenOuterBlank2GenInner = GenOuterBlank2GenInner(GenOuterBlank2(oarg: SomeOtherData(str: "ooo")), arg: SomeOtherData(str: "bbb")) let gobsod : SomeOtherData = gob.arg! try assertEquals(actual: gobsod.str, expected: "aaa") let gob2arg : SomeOtherData = gob2.arg! let gob2out : SomeOtherData = gob2.fromOuter()! try assertEquals(actual: gob2arg.str, expected: "bbb") try assertEquals(actual: gob2out.str, expected: "ooo") let inarg = GenOuterDeepGenShallowInner(GenOuterDeep(oarg: SomeOtherData(str: "fff"))) let godeep : GenOuterDeepGenShallowInnerGenDeepInner = GenOuterDeepGenShallowInnerGenDeepInner(inarg) let deepval : SomeOtherData = godeep.o()! try assertEquals(actual: deepval.str, expected: "fff") let deep2 = GenOuterDeep2() let deep2Before = GenOuterDeep2.Before(deep2) let deep2After = GenOuterDeep2.After(deep2) let deep2soi = GenOuterDeep2.GenShallowOuterInner(deep2) let deep2si = GenOuterDeep2GenShallowOuterInnerGenShallowInner(deep2soi) let deep2i = GenOuterDeep2GenShallowOuterInnerGenShallowInnerGenDeepInner(deep2si) let gbb : GenBothBlank.GenInner = GenBothBlank.GenInner(GenBothBlank(a: SomeData(num: 22)), b: SomeOtherData(str: "ttt")) try assertEquals(actual: gbb.b.str, expected: "ttt") } func testGenericClashing() throws { let gcId = GenClashId(arg: SomeData(num: 22), arg2: SomeOtherData(str: "lll")) try assertEquals(actual: gcId.x() as! NSString, expected: "Foo") let gcIdArg : SomeData = gcId.arg try assertEquals(actual: gcIdArg.num, expected: 22) let gcIdArg2 : SomeOtherData = gcId.arg2 try assertEquals(actual: gcIdArg2.str, expected: "lll") let gcClass = GenClashClass(arg: SomeData(num: 432), arg2: SomeOtherData(str: "lll"), arg3: "Bar") try assertEquals(actual: gcClass.int(), expected: 55) try assertEquals(actual: gcClass.sd().num, expected: 88) try assertEquals(actual: gcClass.list()[1].num, expected: 22) try assertEquals(actual: gcClass.arg.num, expected: 432) try assertEquals(actual: gcClass.clash().str, expected: "aaa") try assertEquals(actual: gcClass.arg2.str, expected: "lll") try assertEquals(actual: gcClass.arg3, expected: "Bar") //GenClashNames uses type parameter names that force the Objc class name itself to be mangled. Swift keeps names however let clashNames = GenClashNames() try assertEquals(actual: clashNames.foo().str, expected: "nnn") try assertEquals(actual: clashNames.bar().str, expected: "qqq") try assertTrue(clashNames.baz(arg: ClashnameParam(str: "meh")), "ClashnameParam issue") let clashNamesEx = GenClashEx() let geClash = GenExClash(myT:SomeOtherData(str:"Hello")) try assertEquals(actual: geClash.t.num, expected: 55) try assertEquals(actual: geClash.myT.str, expected: "Hello") } func testGenericExtensions() throws { let gnn = GenNonNull(arg: SomeData(num: 432)) try assertEquals(actual: (gnn.foo() as! SomeData).num, expected: 432) } // -------- Execution of the test -------- class ValuesTests : TestProvider { var tests: [TestCase] = [] init() { providers.append(self) tests = [ TestCase(name: "TestVararg", method: withAutorelease(testVararg)), TestCase(name: "TestDataClass", method: withAutorelease(testDataClass)), TestCase(name: "TestInlineClasses", method: withAutorelease(testInlineClasses)), TestCase(name: "TestGeneric", method: withAutorelease(testGeneric)), TestCase(name: "TestGenericVariance", method: withAutorelease(testGenericVariance)), TestCase(name: "TestGenericUseSiteVariance", method: withAutorelease(testGenericUseSiteVariance)), TestCase(name: "TestGenericInheritance", method: withAutorelease(testGenericInheritance)), TestCase(name: "TestGenericInterface", method: withAutorelease(testGenericInterface)), TestCase(name: "TestGenericInnerClass", method: withAutorelease(testGenericInnerClass)), TestCase(name: "TestGenericClashing", method: withAutorelease(testGenericClashing)), TestCase(name: "TestGenericExtensions", method: withAutorelease(testGenericExtensions)), ] } } ================================================ FILE: backend.native/tests/framework/values_generics/values_generics.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // All classes and methods should be used in tests @file:Suppress("UNUSED") package conversions import kotlin.native.concurrent.isFrozen import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty // Generics abstract class BaseData{ abstract fun asString():String } data class SomeData(val num:Int = 42):BaseData() { override fun asString(): String = num.toString() } data class SomeOtherData(val str:String):BaseData() { fun anotherFun(){} override fun asString(): String = str } interface NoGeneric { fun myVal():T } data class SomeGeneric(val t:T):NoGeneric{ override fun myVal(): T = t } class GenOpen(val arg:T) class GenNonNull(val arg:T) class GenCollectionsNull(val arg: T, val coll: List) class GenCollectionsNonNull(val arg: T, val coll: List) //Force @class declaration at top of file with Objc variance object ForceUse { val gvo = GenVarOut(SomeData()) } class GenVarOut(val arg:T) class GenVarIn(tArg:T){ private val t = tArg fun valString():String = t.toString() fun goIn(t:T){ //Just taking a val } } class GenVarUse(val arg:T){ fun varUse(a:GenVarUse, b:GenVarUse){ //Should complile but do nothing } } fun variCoType():GenVarOut{ val compileVarOutSD:GenVarOut = GenVarOut(SomeData(890)) val compileVarOut:GenVarOut = compileVarOutSD return compileVarOut } fun variContraType():GenVarIn{ val compileVariIn:GenVarIn = GenVarIn(SomeData(1890)) val compileVariInSD:GenVarIn = compileVariIn return compileVariInSD } open class GenBase(val t:T) class GenEx(val myT:T, baseT:TT):GenBase(baseT) class GenEx2(val myT:S, baseT:T):GenBase(baseT) class GenExAny(val myT:T, baseT:TT):GenBase(baseT) class GenNullability(val arg: T, val nArg:T?){ fun asNullable():T? = arg val pAsNullable:T? get() = arg } fun starGeneric(arg: GenNonNull<*>):Any{ return arg.arg } class GenOuter(val a:A){ class GenNested(val b:B) inner class GenInner(val c:C, val aInner:A) { fun outerFun(): A = a val outerVal: A = a } } class GenOuterSame(val a:A){ class GenNestedSame(val a:A) inner class GenInnerSame(val a:A) class NestedNoGeneric() } fun genInnerFunc(obj: GenOuter.GenInner) {} fun genInnerFuncAny(obj: GenOuter.GenInner){} fun genInnerCreate(): GenOuter.GenInner = GenOuter(SomeData(33)).GenInner(SomeOtherData("ppp"), SomeData(77)) class GenOuterBlank(val sd: SomeData) { inner class GenInner(val arg: T){ fun fromOuter(): SomeData = sd } } class GenOuterBlank2(val oarg: T) { inner class GenInner(val arg: T){ fun fromOuter(): T = oarg } } class GenOuterDeep(val oarg: T) { inner class GenShallowInner(){ inner class GenDeepInner(){ fun o(): T = oarg } } } class GenOuterDeep2() { inner class Before() inner class GenShallowOuterInner() { inner class GenShallowInner() { inner class GenDeepInner() } } inner class After() } class GenBothBlank(val a: SomeData) { inner class GenInner(val b: SomeOtherData) } class GenClashId(val arg: id, val arg2: id_){ fun x(): Any = "Foo" } class GenClashClass( val arg: ValuesGenericsClashingData, val arg2: NSArray, val arg3: int32_t ) { fun sd(): SomeData = SomeData(88) fun list(): List = listOf(SomeData(11), SomeData(22)) fun int(): Int = 55 fun clash(): ClashingData = ClashingData("aaa") } data class ClashingData(val str: String) class GenClashNames() { fun foo() = ClashnameClass("nnn") fun bar(): ClashnameProtocol = object : ClashnameProtocol{ override val str = "qqq" } fun baz(arg: ClashnameParam): Boolean { return arg.str == "meh" } } class GenClashEx: ClashnameClass("ttt"){ fun foo() = ClashnameClass("nnn") } open class ClashnameClass(val str: String) interface ClashnameProtocol { val str: String } data class ClashnameParam(val str: String) class GenExClash(val myT:ValuesGenericsSomeData):GenBase(SomeData(55)) class SelfRef : GenBasic() open class GenBasic() //Extensions fun GenNonNull.foo(): T = arg class StarProjectionInfiniteRecursion> fun testStarProjectionInfiniteRecursion(x: StarProjectionInfiniteRecursion<*>) {} ================================================ FILE: backend.native/tests/harmony_regex/AllCodePointsTest.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class AllCodePointsTest { fun assertTrue(msg: String, value: Boolean) = assertTrue(value, msg) fun assertFalse(msg: String, value: Boolean) = assertFalse(value, msg) fun codePointToString(codePoint: Int): String { val charArray = Char.toChars(codePoint) return String(charArray, 0, charArray.size) } // TODO: Here is a performance problem: an execution of this test requires much more time than it in Kotlin/JVM. @Test fun test() { // Regression for HARMONY-3145 var p = Regex("(\\p{all})+") var res = true var cnt = 0 var s: String for (i in 0..1114111) { s = codePointToString(i) if (!s.matches(p)) { cnt++ res = false } } assertTrue(res) assertEquals(0, cnt) p = Regex("(\\P{all})+") res = true cnt = 0 for (i in 0..1114111) { s = codePointToString(i) if (!s.matches(p)) { cnt++ res = false } } assertFalse(res) assertEquals(0x110000, cnt) } } ================================================ FILE: backend.native/tests/harmony_regex/MatchResultTest.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class MatchResultTest { fun assertTrue(msg: String, value: Boolean) = assertTrue(value, msg) fun assertFalse(msg: String, value: Boolean) = assertFalse(value, msg) internal var testPatterns = arrayOf("(a|b)*abb", "(1*2*3*4*)*567", "(a|b|c|d)*aab", "(1|2|3|4|5|6|7|8|9|0)(1|2|3|4|5|6|7|8|9|0)*", "(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)*", "(a|b)*(a|b)*A(a|b)*lice.*", "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)(a|b|c|d|e|f|g|h|" + "i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)*(1|2|3|4|5|6|7|8|9|0)*|while|for|struct|if|do") internal var groupPatterns = arrayOf("(a|b)*aabb", "((a)|b)*aabb", "((a|b)*)a(abb)", "(((a)|(b))*)aabb", "(((a)|(b))*)aa(b)b", "(((a)|(b))*)a(a(b)b)") @Test fun testReplaceAll() { val input = "aabfooaabfooabfoob" val pattern = "a*b" val regex = Regex(pattern) assertEquals("-foo-foo-foo-", regex.replace(input, "-")) } @Test fun testReplaceFirst() { val input = "zzzdogzzzdogzzz" val pattern = "dog" val regex = Regex(pattern) assertEquals("zzzcatzzzdogzzz", regex.replaceFirst(input, "cat")) } /* * Class under test for String group(int) */ @Test fun testGroupint() { val positiveTestString = "ababababbaaabb" // test IndexOutOfBoundsException // // for (i in groupPatterns.indices) { val regex = Regex(groupPatterns[i]) val result = regex.matchEntire(positiveTestString)!! try { // groupPattern equals to number of groups // of the specified pattern // // result.groups[i + 2] fail("IndexOutBoundsException expected") result.groups[i + 100] fail("IndexOutBoundsException expected") result.groups[-1] fail("IndexOutBoundsException expected") result.groups[-100] fail("IndexOutBoundsException expected") } catch (e: IndexOutOfBoundsException) { } } val groupResults = arrayOf( arrayOf("a"), arrayOf("a", "a"), arrayOf("ababababba", "a", "abb"), arrayOf("ababababba", "a", "a", "b"), arrayOf("ababababba", "a", "a", "b", "b"), arrayOf("ababababba", "a", "a", "b", "abb", "b") ) for (i in groupPatterns.indices) { val regex = Regex(groupPatterns[i]) val result = regex.matchEntire(positiveTestString)!! for (j in 0..groupResults[i].size - 1) { assertEquals(groupResults[i][j], result.groupValues[j + 1], "i: $i j: $j") } } } @Test fun testGroup() { val positiveTestString = "ababababbaaabb" val negativeTestString = "gjhfgdsjfhgcbv" for (element in groupPatterns) { val regex = Regex(element) val result = regex.matchEntire(positiveTestString)!! assertEquals(positiveTestString, result.groupValues[0]) assertEquals(positiveTestString, result.groups[0]!!.value) assertEquals(0 until positiveTestString.length, result.groups[0]!!.range) } for (element in groupPatterns) { val regex = Regex(element) val result = regex.matchEntire(negativeTestString) assertEquals(result, null) } } @Test fun testGroupPossessive() { val regex = Regex("((a)|(b))++c") assertEquals("a", regex.matchEntire("aac")!!.groupValues[1]) } @Test fun testMatchesMisc() { val posSeq = arrayOf( arrayOf("abb", "ababb", "abababbababb", "abababbababbabababbbbbabb"), arrayOf("213567", "12324567", "1234567", "213213567", "21312312312567", "444444567"), arrayOf("abcdaab", "aab", "abaab", "cdaab", "acbdadcbaab"), arrayOf("213234567", "3458", "0987654", "7689546432", "0398576", "98432", "5"), arrayOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), arrayOf("ababbaAabababblice", "ababbaAliceababab", "ababbAabliceaaa", "abbbAbbbliceaaa", "Alice"), arrayOf("a123", "bnxnvgds156", "for", "while", "if", "struct")) for (i in testPatterns.indices) { val regex = Regex(testPatterns[i]) for (j in 0..posSeq[i].size - 1) { assertTrue("Incorrect match: " + testPatterns[i] + " vs " + posSeq[i][j], regex.matches(posSeq[i][j])) } } } @Test fun testMatchesQuantifiers() { val testPatternsSingles = arrayOf("a{5}", "a{2,4}", "a{3,}") val testPatternsMultiple = arrayOf("((a)|(b)){1,2}abb", "((a)|(b)){2,4}", "((a)|(b)){3,}") val stringSingles = arrayOf( arrayOf("aaaaa", "aaa"), arrayOf("aa", "a", "aaa", "aaaaaa", "aaaa", "aaaaa"), arrayOf("aaa", "a", "aaaa", "aa") ) val stringMultiples = arrayOf( arrayOf("ababb", "aba"), arrayOf("ab", "b", "bab", "ababa", "abba", "abababbb"), arrayOf("aba", "b", "abaa", "ba") ) for (i in testPatternsSingles.indices) { val regex = Regex(testPatternsSingles[i]) for (j in 0..stringSingles.size / 2 - 1) { assertTrue("Match expected, but failed: " + regex.pattern + " : " + stringSingles[i][j], regex.matches(stringSingles[i][j * 2]) ) assertFalse("Match failure expected, but match succeed: " + regex.pattern + " : " + stringSingles[i][j * 2 + 1], regex.matches(stringSingles[i][j * 2 + 1]) ) } } for (i in testPatternsMultiple.indices) { val regex = Regex(testPatternsMultiple[i]) for (j in 0..stringMultiples.size / 2 - 1) { assertTrue("Match expected, but failed: " + regex.pattern + " : " + stringMultiples[i][j], regex.matches(stringMultiples[i][j * 2]) ) assertFalse("Match failure expected, but match succeed: " + regex.pattern + " : " + stringMultiples[i][j * 2 + 1], regex.matches(stringMultiples[i][j * 2 + 1]) ) } } // Test for the optimized '.+' quantifier node. assertFalse(Regex(".+abc").matches("abc")) assertFalse(Regex(".+\nabc", RegexOption.DOT_MATCHES_ALL).matches("\nabc")) assertFalse(Regex(".+").matches("")) assertFalse(Regex(".+\n", RegexOption.DOT_MATCHES_ALL).matches("\n")) assertFalse(Regex(".+abc").containsMatchIn("abc")) assertFalse(Regex(".+\nabc", RegexOption.DOT_MATCHES_ALL).containsMatchIn("\nabc")) assertFalse(Regex(".+").containsMatchIn("")) assertFalse(Regex(".+\n", RegexOption.DOT_MATCHES_ALL).containsMatchIn("\n")) assertTrue(Regex(".+abc").matches("aabc")) assertTrue(Regex(".+\nabc", RegexOption.DOT_MATCHES_ALL).matches("a\nabc")) assertTrue(Regex(".+").matches("a")) assertTrue(Regex(".+\n", RegexOption.DOT_MATCHES_ALL).matches("a\n")) assertTrue(Regex(".+abc").containsMatchIn("aabc")) assertTrue(Regex(".+\nabc", RegexOption.DOT_MATCHES_ALL).containsMatchIn("a\nabc")) assertTrue(Regex(".+").containsMatchIn("a")) assertTrue(Regex(".+\n", RegexOption.DOT_MATCHES_ALL).containsMatchIn("a\n")) } @Test fun testQuantVsGroup() { val patternString = "(d{1,3})((a|c)*)(d{1,3})((a|c)*)(d{1,3})" val testString = "dacaacaacaaddaaacaacaaddd" val regex = Regex(patternString) val result = regex.matchEntire(testString)!! assertEquals("dacaacaacaaddaaacaacaaddd", result.groupValues[0]) assertEquals("d", result.groupValues[1]) assertEquals("acaacaacaa", result.groupValues[2]) assertEquals("dd", result.groupValues[4]) assertEquals("aaacaacaa", result.groupValues[5]) assertEquals("ddd", result.groupValues[7]) } /* * Class under test for boolean find() */ @Test fun testFind() { var testPattern = "(abb)" var testString = "cccabbabbabbabbabb" val regex = Regex(testPattern) var result = regex.find(testString) var start = 3 var end = 6 while (result != null) { assertEquals(start, result.groups[1]!!.range.start) assertEquals(end, result.groups[1]!!.range.endInclusive + 1) start = end end += 3 result = result.next() } testPattern = "(\\d{1,3})" testString = "aaaa123456789045" val regex2 = Regex(testPattern) var result2 = regex2.find(testString) start = 4 val length = 3 while (result2 != null) { assertEquals(testString.substring(start, start + length), result2.groupValues[1]) start += length result2 = result2.next() } } @Test fun testSEOLsymbols() { val regex = Regex("^a\\(bb\\[$") assertTrue(regex.matches("a(bb[")) } @Test fun testGroupCount() { for (i in groupPatterns.indices) { val regex = Regex(groupPatterns[i]) val result = regex.matchEntire("ababababbaaabb")!! assertEquals(i + 1, result.groups.size - 1) } } @Test fun testReluctantQuantifiers() { val regex = Regex("(ab*)*b") val result = regex.matchEntire("abbbb") if (result != null) { assertEquals("abbb", result.groupValues[1]) } else { fail("Match expected: (ab*)*b vs abbbb") } } @Test fun testEnhancedFind() { val input = "foob" val pattern = "a*b" val regex = Regex(pattern) val result = regex.find(input)!! assertEquals("b", result.groupValues[0]) } @Test fun testPosCompositeGroup() { val posExamples = arrayOf("aabbcc", "aacc", "bbaabbcc") val negExamples = arrayOf("aabb", "bb", "bbaabb") val posPat = Regex("(aa|bb){1,3}+cc") val negPat = Regex("(aa|bb){1,3}+bb") for (element in posExamples) { assertTrue(posPat.matches(element)) } for (element in negExamples) { assertFalse(negPat.matches(element)) } assertTrue(Regex("(aa|bb){1,3}+bb").matches("aabbaabb")) } @Test fun testPosAltGroup() { val posExamples = arrayOf("aacc", "bbcc", "cc") val negExamples = arrayOf("bb", "aa") val posPat = Regex("(aa|bb)?+cc") val negPat = Regex("(aa|bb)?+bb") for (element in posExamples) { assertTrue(posPat.toString() + " vs: " + element, posPat.matches(element)) } for (element in negExamples) { assertFalse(negPat.matches(element)) } assertTrue(Regex("(aa|bb)?+bb").matches("aabb")) } @Test fun testRelCompGroup() { var res = "" for (i in 0..3) { val regex = Regex("((aa|bb){$i,3}?).*cc") val result = regex.matchEntire("aaaaaacc") assertTrue(regex.toString() + " vs: " + "aaaaaacc", result != null) assertEquals(res, result!!.groupValues[1]) res += "aa" } } @Test fun testRelAltGroup() { var regex = Regex("((aa|bb)??).*cc") var result = regex.matchEntire("aacc") assertTrue(regex.toString() + " vs: " + "aacc", result != null) assertEquals("", result!!.groupValues[1]) regex = Regex("((aa|bb)??)cc") result = regex.matchEntire("aacc") assertTrue(regex.toString() + " vs: " + "aacc", result != null) assertEquals("aa", result!!.groupValues[1]) } @Test fun testIgnoreCase() { var regex = Regex("(aa|bb)*", RegexOption.IGNORE_CASE) assertTrue(regex.matches("aAbb")) regex = Regex("(a|b|c|d|e)*", RegexOption.IGNORE_CASE) assertTrue(regex.matches("aAebbAEaEdebbedEccEdebbedEaedaebEbdCCdbBDcdcdADa")) regex = Regex("[a-e]*", RegexOption.IGNORE_CASE) assertTrue(regex.matches("aAebbAEaEdebbedEccEdebbedEaedaebEbdCCdbBDcdcdADa")) } @Test fun testQuoteReplacement() { assertEquals("\\\\aaCC\\$1", Regex.escapeReplacement("\\aaCC$1")) } @Test fun testOverFlow() { var regex = Regex("(a*)*") var result = regex.matchEntire("aaa") assertTrue(result != null) assertEquals("", result!!.groupValues[1]) assertTrue(Regex("(1+)\\1+").matches("11")) assertTrue(Regex("(1+)(2*)\\2+").matches("11")) regex = Regex("(1+)\\1*") result = regex.matchEntire("11") assertTrue(result != null) assertEquals("11", result!!.groupValues[1]) regex = Regex("((1+)|(2+))(\\2+)") result = regex.matchEntire("11") assertTrue(result != null) assertEquals("1", result!!.groupValues[2]) assertEquals("1", result.groupValues[1]) assertEquals("1", result.groupValues[4]) assertEquals("", result.groupValues[3]) } @Test fun testUnicode() { assertTrue(Regex("\\x61a").matches("aa")) assertTrue(Regex("\\u0061a").matches("aa")) assertTrue(Regex("\\0141a").matches("aa")) assertTrue(Regex("\\0777").matches("?7")) } @Test fun testUnicodeCategory() { assertTrue(Regex("\\p{Ll}").matches("k")) // Unicode lower case assertTrue(Regex("\\P{Ll}").matches("K")) // Unicode non-lower // case assertTrue(Regex("\\p{Lu}").matches("K")) // Unicode upper case assertTrue(Regex("\\P{Lu}").matches("k")) // Unicode non-upper // case combinations assertTrue(Regex("[\\p{L}&&[^\\p{Lu}]]").matches("k")) assertTrue(Regex("[\\p{L}&&[^\\p{Ll}]]").matches("K")) assertFalse(Regex("[\\p{L}&&[^\\p{Lu}]]").matches("K")) assertFalse(Regex("[\\p{L}&&[^\\p{Ll}]]").matches("k")) // category/character combinations assertFalse(Regex("[\\p{L}&&[^a-z]]").matches("k")) assertTrue(Regex("[\\p{L}&&[^a-z]]").matches("K")) assertTrue(Regex("[\\p{Lu}a-z]").matches("k")) assertTrue(Regex("[a-z\\p{Lu}]").matches("k")) assertFalse(Regex("[\\p{Lu}a-d]").matches("k")) assertTrue(Regex("[a-d\\p{Lu}]").matches("K")) assertFalse(Regex("[\\p{L}&&[^\\p{Lu}&&[^G]]]").matches("K")) } @Test fun testSplitEmpty() { val regex = Regex("") val s = regex.split("", 0) assertEquals(2, s.size) assertEquals("", s[0]) assertEquals("", s[1]) } @Test fun testFindDollar() { val regex = Regex("a$") val result = regex.find("a\n") assertTrue(result != null) assertEquals("a", result!!.groupValues[0]) } /* * Regression test for HARMONY-674 */ @Test fun testPatternMatcher() { assertTrue(Regex("(?:\\d+)(?:pt)").matches("14pt")) } /** * Inspired by HARMONY-3360 */ @Test fun test3360() { val str = "!\"#%&'(),-./" val regex = Regex("\\s") assertFalse(regex.containsMatchIn(str)) } /** * Regression test for HARMONY-3360 */ @Test fun testGeneralPunctuationCategory() { val s = arrayOf(",", "!", "\"", "#", "%", "&", "'", "(", ")", "-", ".", "/") val regexp = "\\p{P}" for (i in s.indices) { val regex = Regex(regexp) assertTrue(regex.containsMatchIn(s[i])) } } /** * Regression test for https://github.com/JetBrains/kotlin-native/issues/2297 */ @Test fun test2297() { assertTrue(Regex("^(:[0-5]?[0-9])+$").matches(":20:30")) assertTrue(Regex("(.{1,}){2}").matches("aa")) assertTrue(Regex("(.+b)+").matches("0b0b")) assertTrue(Regex("(.+?b)+").matches("0b0b")) assertTrue(Regex("(.?b)+").matches("0b0b")) assertTrue(Regex("(.??b)+").matches("0b0b")) assertTrue(Regex("(.*b)+").matches("0b0b")) assertTrue(Regex("(.*?b)+").matches("0b0b")) assertTrue(Regex("(.{1,2}b)+").matches("0b00b")) assertTrue(Regex("(.{1,2}?b)+").matches("0b00b")) assertTrue(Regex("([0]?[0]?)+").matches("0000")) assertTrue(Regex("([0]?[0]?b)+").matches("00b00b")) assertTrue(Regex("((b{2}){3})+").matches("bbbbbbbbbbbb")) assertTrue(Regex("[^a]").matches("b")) } @Test fun kt28158() { val comment = "😃😃😃😃😃😃" val regex = Regex("(.{3,})\\1+", RegexOption.IGNORE_CASE) assertTrue(comment.contains(regex)) } } ================================================ FILE: backend.native/tests/harmony_regex/MatchResultTest2.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class MatchResultTest2 { @Test fun testErrorConditions2() { // Test match cursors in absence of a match val regex = Regex("(foo[0-9])(bar[a-z])") var result = regex.find("foo1barzfoo2baryfoozbar5") assertTrue(result != null) assertEquals(0, result!!.range.start) assertEquals(7, result.range.endInclusive) assertEquals(0, result.groups[0]!!.range.start) assertEquals(7, result.groups[0]!!.range.endInclusive) assertEquals(0, result.groups[1]!!.range.start) assertEquals(3, result.groups[1]!!.range.endInclusive) assertEquals(4, result.groups[2]!!.range.start) assertEquals(7, result.groups[2]!!.range.endInclusive) try { result.groups[3] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groupValues[3] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groups[-1] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groupValues[-1] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } result = result.next() assertTrue(result != null) assertEquals(8, result!!.range.start) assertEquals(15, result.range.endInclusive) assertEquals(8, result.groups[0]!!.range.start) assertEquals(15, result.groups[0]!!.range.endInclusive) assertEquals(8, result.groups[1]!!.range.start) assertEquals(11, result.groups[1]!!.range.endInclusive) assertEquals(12, result.groups[2]!!.range.start) assertEquals(15, result.groups[2]!!.range.endInclusive) try { result.groups[3] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groupValues[3] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groups[-1] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } try { result.groupValues[-1] fail("IndexOutOfBoundsException expected") } catch (e: IndexOutOfBoundsException) { } result = result.next() assertFalse(result != null) } /* * Regression test for HARMONY-997 */ @Test fun testReplacementBackSlash() { val str = "replace me" val replacedString = "me" val substitutionString = "\\" val regex = Regex(replacedString) try { regex.replace(str, substitutionString) fail("IllegalArgumentException should be thrown") } catch (e: IllegalArgumentException) { } } } ================================================ FILE: backend.native/tests/harmony_regex/ModeTest.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class ModeTest { /** * Tests Pattern compilation modes and modes triggered in pattern strings */ @Test fun testCase() { var regex: Regex var result: MatchResult? regex = Regex("([a-z]+)[0-9]+") result = regex.find("cAT123#dog345") assertNotNull(result) assertEquals("dog", result!!.groupValues[1]) assertNull(result.next()) regex = Regex("([a-z]+)[0-9]+", RegexOption.IGNORE_CASE) result = regex.find("cAt123#doG345") assertNotNull(result) assertEquals("cAt", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("doG", result!!.groupValues[1]) assertNull(result.next()) regex = Regex("(?i)([a-z]+)[0-9]+") result = regex.find("cAt123#doG345") assertNotNull(result) assertEquals("cAt", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("doG", result!!.groupValues[1]) assertNull(result.next()) } @Test fun testMultiline() { var regex: Regex var result: MatchResult? regex = Regex("^foo") result = regex.find("foobar") assertNotNull(result) assertTrue(result!!.range.start == 0 && result.range.endInclusive == 2) assertTrue(result.groups[0]!!.range.start == 0 && result.groups[0]!!.range.endInclusive == 2) assertNull(result.next()) result = regex.find("barfoo") assertNull(result) regex = Regex("foo$") result = regex.find("foobar") assertNull(result) result = regex.find("barfoo") assertNotNull(result) assertTrue(result!!.range.start == 3 && result.range.endInclusive == 5) assertTrue(result.groups[0]!!.range.start == 3 && result.groups[0]!!.range.endInclusive == 5) assertNull(result.next()) regex = Regex("^foo([0-9]*)", RegexOption.MULTILINE) result = regex.find("foo1bar\nfoo2foo3\nbarfoo4") assertNotNull(result) assertEquals("1", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("2", result!!.groupValues[1]) assertNull(result.next()) regex = Regex("foo([0-9]*)$", RegexOption.MULTILINE) result = regex.find("foo1bar\nfoo2foo3\nbarfoo4") assertNotNull(result) assertEquals("3", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("4", result!!.groupValues[1]) assertNull(result.next()) regex = Regex("(?m)^foo([0-9]*)") result = regex.find("foo1bar\nfoo2foo3\nbarfoo4") assertNotNull(result) assertEquals("1", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("2", result!!.groupValues[1]) assertNull(result.next()) regex = Regex("(?m)foo([0-9]*)$") result = regex.find("foo1bar\nfoo2foo3\nbarfoo4") assertNotNull(result) assertEquals("3", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("4", result!!.groupValues[1]) assertNull(result.next()) } } ================================================ FILE: backend.native/tests/harmony_regex/PatternErrorTest.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class PatternErrorTest { @Test fun testCompileErrors() { // empty regex string - no exception should be thrown Regex("") // note: invalid regex syntax checked in PatternSyntaxExceptionTest // flags = 0 should raise no exception Regex("foo", emptySet()) // check that all valid flags accepted without exception val options = setOf( RegexOption.UNIX_LINES, RegexOption.IGNORE_CASE, RegexOption.MULTILINE, RegexOption.CANON_EQ, RegexOption.COMMENTS, RegexOption.DOT_MATCHES_ALL) Regex("foo", options) } } ================================================ FILE: backend.native/tests/harmony_regex/PatternSyntaxExceptionTest.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class PatternSyntaxExceptionTest { @Test fun testCase() { val regex = "(" try { Regex(regex) fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { // TODO: Check the exception's properties. } } @Test fun testCase2() { val regex = "[4-" try { Regex(regex) fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } } } ================================================ FILE: backend.native/tests/harmony_regex/PatternTest.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class PatternTest { fun assertTrue(msg: String, value: Boolean) = assertTrue(value, msg) fun assertFalse(msg: String, value: Boolean) = assertFalse(value, msg) internal var testPatterns = arrayOf("(a|b)*abb", "(1*2*3*4*)*567", "(a|b|c|d)*aab", "(1|2|3|4|5|6|7|8|9|0)(1|2|3|4|5|6|7|8|9|0)*", "(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)*", "(a|b)*(a|b)*A(a|b)*lice.*", "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)(a|b|c|d|e|f|g|h|" + "i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)*(1|2|3|4|5|6|7|8|9|0)*|while|for|struct|if|do", "x(?c)y", "x(?cc)y", "x(?:c)y") @Test fun testCommentsInPattern() { val p = Regex("ab# this is a comment\ncd", RegexOption.COMMENTS) assertTrue(p.matches("abcd")) } @Test fun testSplitCharSequenceint() { // Splitting CharSequence which ends with pattern. // Harmony regress tests. assertEquals(",,".split(",".toRegex(), 3).toTypedArray().size, 3) assertEquals(",,".split(",".toRegex(), 4).toTypedArray().size, 3) assertEquals(Regex("o").split("boo:and:foo", 5).size, 5) assertEquals(Regex("b").split("ab", 0).size, 2) var s: List var regex = Regex("x") s = regex.split("zxx:zzz:zxx", 10) assertEquals(s.size, 5) s = regex.split("zxx:zzz:zxx", 3) assertEquals(s.size, 3) s = regex.split("zxx:zzz:zxx", 0) assertEquals(s.size, 5) // Other splitting. // Negative limit regex = Regex("b") s = regex.split("abccbadfebb", 0) assertEquals(s.size, 5) s = regex.split("", 0) assertEquals(s.size, 1) regex = Regex("") s = regex.split("", 0) assertEquals(s.size, 2) s = regex.split("abccbadfe", 0) assertEquals(s.size, 11) // positive limit regex = Regex("b") s = regex.split("abccbadfebb", 12) assertEquals(s.size, 5) s = regex.split("", 6) assertEquals(s.size, 1) regex = Regex("") s = regex.split("", 11) assertEquals(s.size, 2) s = regex.split("abccbadfe", 15) assertEquals(s.size, 11) regex = Regex("b") s = regex.split("abccbadfebb", 5) assertEquals(s.size, 5) s = regex.split("", 1) assertEquals(s.size, 1) regex = Regex("") s = regex.split("", 1) assertEquals(s.size, 1) s = regex.split("abccbadfe", 11) assertEquals(s.size, 11) regex = Regex("b") s = regex.split("abccbadfebb", 3) assertEquals(s.size, 3) regex = Regex("") s = regex.split("abccbadfe", 5) assertEquals(s.size, 5) } @Test fun testFlags() { var baseString: String var testString: String var regex: Regex baseString = "((?i)|b)a" testString = "A" regex = Regex(baseString) assertFalse(regex.matches(testString)) baseString = "(?i)a|b" testString = "A" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)a|b" testString = "B" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "c|(?i)a|b" testString = "B" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)a|(?s)b" testString = "B" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)a|(?-i)b" testString = "B" regex = Regex(baseString) assertFalse(regex.matches(testString)) baseString = "(?i)a|(?-i)c|b" testString = "B" regex = Regex(baseString) assertFalse(regex.matches(testString)) baseString = "(?i)a|(?-i)c|(?i)b" testString = "B" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)a|(?-i)b" testString = "A" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "((?i))a" testString = "A" regex = Regex(baseString) assertFalse(regex.matches(testString)) baseString = "|(?i)|a" testString = "A" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)((?s)a.)" testString = "A\n" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)((?-i)a)" testString = "A" regex = Regex(baseString) assertFalse(regex.matches(testString)) baseString = "(?i)(?s:a.)" testString = "A\n" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)fgh(?s:aa)" testString = "fghAA" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?i)((?-i))a" testString = "A" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "abc(?i)d" testString = "ABCD" regex = Regex(baseString) assertFalse(regex.matches(testString)) testString = "abcD" assertTrue(regex.matches(testString)) baseString = "a(?i)a(?-i)a(?i)a(?-i)a" testString = "aAaAa" regex = Regex(baseString) assertTrue(regex.matches(testString)) testString = "aAAAa" assertFalse(regex.matches(testString)) } fun Set.containsOnly(vararg options: RegexOption): Boolean { val toCheck = options.toSet() return size == toCheck.size && containsAll(toCheck) } @Test fun testFlagsMethod() { val a = kotlin.text.Regex("sdf") var baseString: String var regex: Regex baseString = "(?-i)" regex = Regex(baseString) baseString = "(?idmsux)abc(?-i)vg(?-dmu)" regex = Regex(baseString) assertTrue(regex.options.containsOnly(RegexOption.DOT_MATCHES_ALL, RegexOption.COMMENTS)) baseString = "(?idmsux)abc|(?-i)vg|(?-dmu)" regex = Regex(baseString) assertTrue(regex.options.containsOnly(RegexOption.DOT_MATCHES_ALL, RegexOption.COMMENTS)) baseString = "(?is)a((?x)b.)" regex = Regex(baseString) assertTrue(regex.options.containsOnly(RegexOption.DOT_MATCHES_ALL, RegexOption.IGNORE_CASE)) baseString = "(?i)a((?-i))" regex = Regex(baseString) assertTrue(regex.options.containsOnly(RegexOption.IGNORE_CASE)) baseString = "((?i)a)" regex = Regex(baseString) assertTrue(regex.options.isEmpty()) regex = Regex("(?is)abc") assertTrue(regex.options.containsOnly(RegexOption.IGNORE_CASE, RegexOption.DOT_MATCHES_ALL)) } @Test fun testCompileStringint() { /* * this tests are needed to verify that appropriate exceptions are hrown */ var pattern = "b)a" try { Regex(pattern) fail("Expected a IllegalArgumentException when compiling pattern: " + pattern) } catch (e: IllegalArgumentException) { // pass } pattern = "bcde)a" try { Regex(pattern) fail("Expected a IllegalArgumentException when compiling pattern: " + pattern) } catch (e: IllegalArgumentException) { // pass } pattern = "bbg())a" try { Regex(pattern) fail("Expected a IllegalArgumentException when compiling pattern: " + pattern) } catch (e: IllegalArgumentException) { // pass } pattern = "cdb(?i))a" try { Regex(pattern) fail("Expected a IllegalArgumentException when compiling pattern: " + pattern) } catch (e: IllegalArgumentException) { // pass } /* * This pattern should compile (Originally it is a regression test for HARMONY-2127) */ pattern = "x(?c)y" Regex(pattern) /* * This pattern doesn't match any string, but should be compiled anyway */ pattern = "(b\\u0001)a" Regex(pattern) } @Test fun testQuantCompileNeg() { val patterns = arrayOf("5{,2}", "{5asd", "{hgdhg", "{5,hjkh", "{,5hdsh", "{5,3shdfkjh}") for (element in patterns) { try { Regex(element) fail("IllegalArgumentException was expected, but compilation succeeds") } catch (pse: IllegalArgumentException) { continue } } } @Test fun testQuantCompilePos() { val patterns = arrayOf("abc{2,}", "abc{5}") for (element in patterns) { Regex(element) } } @Test fun testQuantComposition() { val pattern = "(a{1,3})aab" val regex = Regex(pattern) val result = regex.matchEntire("aaab") assertNotNull(result) assertEquals(result!!.groups[1]!!.range.start, 0) assertEquals(result.groupValues[1], "a") } @Test fun testTimeZoneIssue() { val regex = Regex("GMT(\\+|\\-)(\\d+)(:(\\d+))?") val result = regex.matchEntire("GMT-9:45") assertNotNull(result) assertEquals("-", result!!.groupValues[1]) assertEquals("9", result.groupValues[2]) assertEquals(":45", result.groupValues[3]) assertEquals("45", result.groupValues[4]) } @Test fun testCompileRanges() { val correctTestPatterns = arrayOf("[^]*abb]*", "[^a-d[^m-p]]*abb", "[a-d\\d]*abb", "[abc]*abb", "[a-e&&[de]]*abb", "[^abc]*abb", "[a-e&&[^de]]*abb", "[a-z&&[^m-p]]*abb", "[a-d[m-p]]*abb", "[a-zA-Z]*abb", "[+*?]*abb", "[^+*?]*abb") val inputSecuence = arrayOf("kkkk", "admpabb", "abcabcd124654abb", "abcabccbacababb", "dededededededeedabb", "gfdhfghgdfghabb", "accabacbcbaabb", "acbvfgtyabb", "adbcacdbmopabcoabb", "jhfkjhaSDFGHJkdfhHNJMjkhfabb", "+*??+*abb", "sdfghjkabb") for (i in correctTestPatterns.indices) { assertTrue("pattern: " + correctTestPatterns[i] + " input: " + inputSecuence[i], Regex(correctTestPatterns[i]).matches(inputSecuence[i])) } val wrongInputSecuence = arrayOf("]", "admpkk", "abcabcd124k654abb", "abwcabccbacababb", "abababdeababdeabb", "abcabcacbacbabb", "acdcbecbaabb", "acbotyabb", "adbcaecdbmopabcoabb", "jhfkjhaSDFGHJk;dfhHNJMjkhfabb", "+*?a?+*abb", "sdf+ghjkabb") for (i in correctTestPatterns.indices) { assertFalse("pattern: " + correctTestPatterns[i] + " input: " + wrongInputSecuence[i], Regex(correctTestPatterns[i]).matches(wrongInputSecuence[i])) } } @Test fun testRangesSpecialCases() { val neg_patterns = arrayOf("[a-&&[b-c]]", "[a-\\w]", "[b-a]", "[]") for (element in neg_patterns) { try { Regex(element) fail("IllegalArgumentException was expected: " + element) } catch (pse: IllegalArgumentException) { } } val pos_patterns = arrayOf("[-]+", "----", "[a-]+", "a-a-a-a-aa--", "[\\w-a]+", "123-2312--aaa-213", "[a-]]+", "-]]]]]]]]]]]]]]]") var i = 0 while (i < pos_patterns.size) { val pat = pos_patterns[i++] val inp = pos_patterns[i] assertTrue("pattern: $pat input: $inp", Regex(pat).matches(inp)) i++ } } @Test fun testZeroSymbols() { assertTrue(Regex("[\u0000]*abb").matches("\u0000\u0000\u0000\u0000\u0000\u0000abb")) } @Test fun testEscapes() { val regex = Regex("\\Q{]()*?") assertTrue(regex.matches("{]()*?")) } @Test fun testRegressions() { // Bug 181 Regex("[\\t-\\r]") // HARMONY-4472 Regex("a*.+") // Bug187 Regex("|(?idmsux-idmsux)|(?idmsux-idmsux)|[^|\\[-\\0274|\\,-\\\\[^|W\\}\\nq\\x65\\002\\xFE\\05\\06\\00\\x66\\x47i\\,\\xF2\\=\\06\\u0EA4\\x9B\\x3C\\f\\|\\{\\xE5\\05\\r\\u944A\\xCA\\e|\\x19\\04\\x07\\04\\u607B\\023\\0073\\x91Tr\\0150\\x83]]?(?idmsux-idmsux:\\p{Alpha}{7}?)||(?<=[^\\uEC47\\01\\02\\u3421\\a\\f\\a\\013q\\035w\\e])(?<=\\p{Punct}{0,}?)(?=^\\p{Lower})(?!\\b{8,14})(?[\\x3E-\\]])|(?idmsux-idmsux:\\p{Punct})|(?[|\\n\\042\\uB09F\\06\\u0F2B\\uC96D\\x89\\uC166\\xAA|\\04-\\][^|\\a\\|\\rx\\04\\uA770\\n\\02\\t\\052\\056\\0274\\|\\=\\07\\e|\\00-\\x1D&&[^\\005\\uB15B\\uCDAC\\n\\x74\\0103\\0147\\uD91B\\n\\062G\\u9B4B\\077\\}\\0324&&[^\\0302\\,\\0221\\04\\u6D16\\04xy\\uD193\\[\\061\\06\\045\\x0F|\\e\\xBB\\f\\u1B52\\023\\u3AD2\\033\\007\\022\\}\\x66\\uA63FJ-\\0304]]]]{0,0})||(?^+)|(?![^|\\|\\nJ\\t\\<\\04E\\\\\\t\\01\\\\\\02\\|\\=\\}\\xF3\\uBEC2\\032K\\014\\uCC5F\\072q\\|\\0153\\xD9\\0322\\uC6C8[^\\t\\0342\\x34\\x91\\06\\{\\xF1\\a\\u1710\\?\\xE7\\uC106\\02pF\\<&&[^|\\]\\064\\u381D\\u50CF\\eO&&[^|\\06\\x2F\\04\\045\\032\\u8536W\\0377\\0017|\\x06\\uE5FA\\05\\xD4\\020\\04c\\xFC\\02H\\x0A\\r]]]]+?)(?idmsux-idmsux)|(?[\\{-\\0207|\\06-\\0276\\p{XDigit}])(?idmsux-idmsux:[^|\\x52\\0012\\]u\\xAD\\0051f\\0142\\\\l\\|\\050\\05\\f\\t\\u7B91\\r\\u7763\\{|h\\0104\\a\\f\\0234\\u2D4F&&^\\P{InGreek}]))") // HARMONY-5858 Regex("\\u6211", RegexOption.LITERAL) } @Test fun testOrphanQuantifiers() { try { Regex("+++++") fail("IllegalArgumentException expected") } catch (pse: IllegalArgumentException) { } } @Test fun testOrphanQuantifiers2() { try { Regex("\\d+*") fail("IllegalArgumentException expected") } catch (pse: IllegalArgumentException) { } } @Test fun testBug197() { val vals = arrayOf(":", 2, arrayOf("boo", "and:foo"), ":", 5, arrayOf("boo", "and", "foo"), ":", 0, arrayOf("boo", "and", "foo"), ":", 3, arrayOf("boo", "and", "foo"), ":", 1, arrayOf("boo:and:foo"), "o", 5, arrayOf("b", "", ":and:f", "", ""), "o", 4, arrayOf("b", "", ":and:f", "o"), "o", 0, arrayOf("b", "", ":and:f", "", "") ) var i = 0 while (i < vals.size / 3) { val res = Regex(vals[i++].toString()).split("boo:and:foo", (vals[i++] as Int)) val expectedRes = vals[i++] as Array assertEquals(expectedRes.size, res.size) for (j in expectedRes.indices) { assertEquals(expectedRes[j], res[j]) } } } @Test fun testURIPatterns() { val URI_REGEXP_STR = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"; val SCHEME_REGEXP_STR = "^[a-zA-Z]{1}[\\w+-.]+$"; val REL_URI_REGEXP_STR = "^(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"; val IPV6_REGEXP_STR = "^[0-9a-fA-F\\:\\.]+(\\%\\w+)?$"; val IPV6_REGEXP_STR2 = "^\\[[0-9a-fA-F\\:\\.]+(\\%\\w+)?\\]$"; val IPV4_REGEXP_STR = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$"; val HOSTNAME_REGEXP_STR = "\\w+[\\w\\-\\.]*"; Regex(URI_REGEXP_STR) Regex(REL_URI_REGEXP_STR) Regex(SCHEME_REGEXP_STR) Regex(IPV4_REGEXP_STR) Regex(IPV6_REGEXP_STR) Regex(IPV6_REGEXP_STR2) Regex(HOSTNAME_REGEXP_STR) } @Test fun testFindBoundaryCases1() { val regex = Regex(".*\n") val result = regex.find("a\n") assertNotNull(result) assertEquals("a\n", result!!.value) } @Test fun testFindBoundaryCases2() { val regex = Regex(".*A") val result = regex.find("aAa") assertNotNull(result) assertEquals("aA", result!!.value) } @Test fun testFindBoundaryCases3() { val regex = Regex(".*A") val result = regex.find("a\naA\n") assertNotNull(result) assertEquals("aA", result!!.value) } @Test fun testFindBoundaryCases4() { val regex = Regex("A.*") val result = regex.find("A\n") assertNotNull(result) assertEquals("A", result!!.value) } @Test fun testFindBoundaryCases5() { val regex = Regex(".*A.*") var result = regex.find("\nA\naaa\nA\naaAaa\naaaA\n") val expected = arrayOf("A", "A", "aaAaa", "aaaA") var k = 0 while (result != null) { assertEquals(expected[k], result.value) result = result.next() k++ } } @Test fun testFindBoundaryCases6() { val regex = Regex(".*") var result = regex.find("\na\n") val expected = arrayOf("", "a", "", "") var k = 0 while (result != null) { assertEquals(expected[k], result.value) k++ result = result.next() } } @Test fun testBackReferences() { var regex = Regex("(\\((\\w*):(.*):(\\2)\\))") var result = regex.find("(start1: word :start1)(start2: word :start2)") var k = 1 while (result != null) { assertEquals("start" + k, result.groupValues[2]) assertEquals(" word ", result.groupValues[3]) assertEquals("start" + k, result.groupValues[4]) k++ result = result.next() } assertEquals(3, k) regex = Regex(".*(.)\\1") assertTrue(regex.matches("saa")) } @Test fun testNewLine() { val regex = Regex("(^$)*\n", RegexOption.MULTILINE) var result = regex.find("\r\n\n") var counter = 0 while (result != null) { counter++ result = result.next() } assertEquals(2, counter) } @Test fun testFindGreedy() { val regex = Regex(".*aaa", RegexOption.DOT_MATCHES_ALL) val result = regex.matchEntire("aaaa\naaa\naaaaaa") assertNotNull(result) assertEquals(14, result!!.range.endInclusive) } @Test fun testSOLQuant() { val regex = Regex("$*", RegexOption.MULTILINE) var result = regex.find("\n\n") var counter = 0 while (result != null) { counter++ result = result.next() } assertEquals(3, counter) } @Test fun testIllegalEscape() { try { Regex("\\y") fail("IllegalArgumentException expected") } catch (pse: IllegalArgumentException) { } } @Test fun testEmptyFamily() { Regex("\\p{Lower}") } @Test fun testNonCaptConstr() { // Flags var regex = Regex("(?i)b*(?-i)a*") assertTrue(regex.matches("bBbBaaaa")) assertFalse(regex.matches("bBbBAaAa")) // Non-capturing groups regex = Regex("(?i:b*)a*") assertTrue(regex.matches("bBbBaaaa")) assertFalse(regex.matches("bBbBAaAa")) // 1 2 3 4 5 6 7 8 9 10 11 regex = Regex("(?:-|(-?\\d+\\d\\d\\d))?(?:-|-(\\d\\d))?(?:-|-(\\d\\d))?(T)?(?:(\\d\\d):(\\d\\d):(\\d\\d)(\\.\\d+)?)?(?:(?:((?:\\+|\\-)\\d\\d):(\\d\\d))|(Z))?") val result = regex.matchEntire("-1234-21-31T41:51:61.789+71:81") assertNotNull(result) assertEquals("-1234", result!!.groupValues[1]) assertEquals("21", result.groupValues[2]) assertEquals("31", result.groupValues[3]) assertEquals("T", result.groupValues[4]) assertEquals("41", result.groupValues[5]) assertEquals("51", result.groupValues[6]) assertEquals("61", result.groupValues[7]) assertEquals(".789", result.groupValues[8]) assertEquals("+71", result.groupValues[9]) assertEquals("81", result.groupValues[10]) // positive lookahead regex = Regex(".*\\.(?=log$).*$") assertTrue(regex.matches("a.b.c.log")) assertFalse(regex.matches("a.b.c.log.")) // negative lookahead regex = Regex(".*\\.(?!log$).*$") assertFalse(regex.matches("abc.log")) assertTrue(regex.matches("abc.logg")) // positive lookbehind regex = Regex(".*(?<=abc)\\.log$") assertFalse(regex.matches("cde.log")) assertTrue(regex.matches("abc.log")) // negative lookbehind regex = Regex(".*(?a*)abb") assertFalse(regex.matches("aaabb")) regex = Regex("(?>a*)bb") assertTrue(regex.matches("aaabb")) regex = Regex("(?>a|aa)aabb") assertTrue(regex.matches("aaabb")) regex = Regex("(?>aa|a)aabb") assertFalse(regex.matches("aaabb")) // quantifiers over look ahead regex = Regex(".*(?<=abc)*\\.log$") assertTrue(regex.matches("cde.log")) regex = Regex(".*(?<=abc)+\\.log$") assertFalse(regex.matches("cde.log")) } @Test fun testCompilePatternWithTerminatorMark() { val regex = Regex("a\u0000\u0000cd") assertTrue(regex.matches("a\u0000\u0000cd")) } @Test fun testAlternations() { var baseString = "|a|bc" var regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "a||bc" regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "a|bc|" regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "a|b|" regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "a(|b|cd)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "a(b||cd)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "a(b|cd|)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "a(b|c|)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "a(|)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "|" regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "a(?:|)e" regex = Regex(baseString) assertTrue(regex.matches("ae")) baseString = "a||||bc" regex = Regex(baseString) assertTrue(regex.matches("")) baseString = "(?i-is)|a" regex = Regex(baseString) assertTrue(regex.matches("a")) } @Test fun testMatchWithGroups() { var baseString = "jwkerhjwehrkwjehrkwjhrwkjehrjwkehrjkwhrkwehrkwhrkwrhwkhrwkjehr" var pattern = ".*(..).*\\1.*" assertTrue(Regex(pattern).matches(baseString)) baseString = "saa" pattern = ".*(.)\\1" assertTrue(Regex(pattern).matches(baseString)) assertTrue(Regex(pattern).containsMatchIn(baseString)) } @Test fun testSplitEmptyCharSequence() { val s1 = "" val arr = s1.split(":".toRegex()) assertEquals(arr.size, 1) } @Test fun testSplitEndsWithPattern() { assertEquals(",,".split(",".toRegex(), 3).toTypedArray().size, 3) assertEquals(",,".split(",".toRegex(), 4).toTypedArray().size, 3) assertEquals(Regex("o").split("boo:and:foo", 5).size, 5) assertEquals(Regex("b").split("ab", 0).size, 2) } @Test fun testCaseInsensitiveFlag() { assertTrue(Regex("(?i-:AbC)").matches("ABC")) } @Test fun testEmptyGroups() { var regex = Regex("ab(?>)cda") assertTrue(regex.matches("abcda")) regex = Regex("ab()") assertTrue(regex.matches("ab")) regex = Regex("abc(?:)(..)") assertTrue(regex.matches("abcgf")) } @Test fun testCompileNonCaptGroup() { var isCompiled = false try { Regex("(?:)", RegexOption.CANON_EQ) Regex("(?:)", setOf(RegexOption.CANON_EQ, RegexOption.DOT_MATCHES_ALL)) Regex("(?:)", setOf(RegexOption.CANON_EQ, RegexOption.IGNORE_CASE)) Regex("(?:)", setOf(RegexOption.CANON_EQ, RegexOption.COMMENTS, RegexOption.UNIX_LINES)) isCompiled = true } catch (e: IllegalArgumentException) { println(e) } assertTrue(isCompiled) } @Test fun testEmbeddedFlags() { var baseString = "(?i)((?s)a)" var testString = "A" var regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?x)(?i)(?s)(?d)a" testString = "A" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "(?x)(?i)(?s)(?d)a." testString = "a\n" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "abc(?x:(?i)(?s)(?d)a.)" testString = "abcA\n" regex = Regex(baseString) assertTrue(regex.matches(testString)) baseString = "abc((?x)d)(?i)(?s)a" testString = "abcdA" regex = Regex(baseString) assertTrue(regex.matches(testString)) } @Test fun testAltWithFlags() { Regex("|(?i-xi)|()") } @Test fun testRestoreFlagsAfterGroup() { val baseString = "abc((?x)d) a" val testString = "abcd a" val regex = Regex(baseString) assertTrue(regex.matches(testString)) } @Test fun testCanonEqFlag() { /* * for decompositions see * http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt * http://www.unicode.org/reports/tr15/#Decomposition */ var baseString: String var testString: String var regex: Regex baseString = "ab(a*)\\u0001" regex = Regex(baseString, RegexOption.CANON_EQ) baseString = "a(abcdf)d" regex = Regex(baseString, RegexOption.CANON_EQ) baseString = "aabcdfd" regex = Regex(baseString, RegexOption.CANON_EQ) // \u01E0 -> \u0226\u0304 ->\u0041\u0307\u0304 // \u00CC -> \u0049\u0300 baseString = "\u01E0\u00CCcdb(ac)" testString = "\u0226\u0304\u0049\u0300cdbac" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u01E0cdb(a\u00CCc)" testString = "\u0041\u0307\u0304cdba\u0049\u0300c" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "a\u00CC" testString = "a\u0049\u0300" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u0226\u0304cdb(ac\u0049\u0300)" testString = "\u01E0cdbac\u00CC" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "cdb(?:\u0041\u0307\u0304\u00CC)" testString = "cdb\u0226\u0304\u0049\u0300" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u01E0[a-c]\u0049\u0300cdb(ac)" testString = "\u01E0b\u00CCcdbac" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u01E0|\u00CCcdb(ac)" testString = "\u0041\u0307\u0304" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u00CC?cdb(ac)*(\u01E0)*[a-c]" testString = "cdb\u0041\u0307\u0304b" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "a\u0300" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.containsMatchIn("a\u00E0a")) baseString = "\u7B20\uF9F8abc" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches("\uF9F8\uF9F8abc")) // \u01F9 -> \u006E\u0300 // \u00C3 -> \u0041\u0303 baseString = "cdb(?:\u00C3\u006E\u0300)" testString = "cdb\u0041\u0303\u01F9" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) // \u014C -> \u004F\u0304 // \u0163 -> \u0074\u0327 baseString = "cdb(?:\u0163\u004F\u0304)" testString = "cdb\u0074\u0327\u014C" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) // \u00E1->a\u0301 // canonical ordering takes place \u0301\u0327 -> \u0327\u0301 baseString = "c\u0327\u0301" testString = "c\u0301\u0327" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) /* * Hangul decompositions */ // \uD4DB->\u1111\u1171\u11B6 // \uD21E->\u1110\u116D\u11B5 // \uD264->\u1110\u1170 // not Hangul:\u0453->\u0433\u0301 baseString = "a\uD4DB\u1111\u1171\u11B6\uD264" regex = Regex(baseString, RegexOption.CANON_EQ) baseString = "\u0453c\uD4DB" regex = Regex(baseString, RegexOption.CANON_EQ) baseString = "a\u1110\u116D\u11B5b\uD21Ebc" regex = Regex(baseString, RegexOption.CANON_EQ) baseString = "\uD4DB\uD21E\u1110\u1170cdb(ac)" testString = "\u1111\u1171\u11B6\u1110\u116D\u11B5\uD264cdbac" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\uD4DB\uD264cdb(a\uD21Ec)" testString = "\u1111\u1171\u11B6\u1110\u1170cdba\u1110\u116D\u11B5c" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "a\uD4DB" testString = "a\u1111\u1171\u11B6" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "a\uD21E" testString = "a\u1110\u116D\u11B5" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\u1111\u1171\u11B6cdb(ac\u1110\u116D\u11B5)" testString = "\uD4DBcdbac\uD21E" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "cdb(?:\u1111\u1171\u11B6\uD21E)" testString = "cdb\uD4DB\u1110\u116D\u11B5" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\uD4DB[a-c]\u1110\u116D\u11B5cdb(ac)" testString = "\uD4DBb\uD21Ecdbac" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\uD4DB|\u00CCcdb(ac)" testString = "\u1111\u1171\u11B6" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\uD4DB|\u00CCcdb(ac)" testString = "\u1111\u1171" regex = Regex(baseString, RegexOption.CANON_EQ) assertFalse(regex.matches(testString)) baseString = "\u00CC?cdb(ac)*(\uD4DB)*[a-c]" testString = "cdb\u1111\u1171\u11B6b" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) baseString = "\uD4DB" regex = Regex(baseString, RegexOption.CANON_EQ) assertTrue(regex.containsMatchIn("a\u1111\u1171\u11B6a")) baseString = "\u1111" regex = Regex(baseString, RegexOption.CANON_EQ) assertFalse(regex.containsMatchIn("bcda\uD4DBr")) } @Test fun testIndexesCanonicalEq() { var baseString: String var testString: String var regex: Regex var result: MatchResult? baseString = "\uD4DB" testString = "bcda\u1111\u1171\u11B6awr" regex = Regex(baseString, RegexOption.CANON_EQ) result = regex.find(testString) assertNotNull(result) assertEquals(result!!.range.start, 4) assertEquals(result.range.endInclusive, 6) baseString = "\uD4DB\u1111\u1171\u11B6" testString = "bcda\u1111\u1171\u11B6\uD4DBawr" regex = Regex(baseString, RegexOption.CANON_EQ) result = regex.find(testString) // Use the same testString assertNotNull(result) assertEquals(result!!.range.start, 4) assertEquals(result.range.endInclusive, 7) baseString = "\uD4DB\uD21E\u1110\u1170" testString = "abcabc\u1111\u1171\u11B6\u1110\u116D\u11B5\uD264cdbac" regex = Regex(baseString, RegexOption.CANON_EQ) result = regex.find(testString) assertNotNull(result) assertEquals(result!!.range.start, 6) assertEquals(result.range.endInclusive, 12) } @Test fun testCanonEqFlagWithSupplementaryCharacters() { /* * \u1D1BF->\u1D1BB\u1D16F->\u1D1B9\u1D165\u1D16F in UTF32 * \uD834\uDDBF->\uD834\uDDBB\uD834\uDD6F * ->\uD834\uDDB9\uD834\uDD65\uD834\uDD6F in UTF16 */ var patString = "abc\uD834\uDDBFef" var testString = "abc\uD834\uDDB9\uD834\uDD65\uD834\uDD6Fef" var regex = Regex(patString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) testString = "abc\uD834\uDDBB\uD834\uDD6Fef" assertTrue(regex.matches(testString)) patString = "abc\uD834\uDDBB\uD834\uDD6Fef" testString = "abc\uD834\uDDBFef" regex = Regex(patString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) testString = "abc\uD834\uDDB9\uD834\uDD65\uD834\uDD6Fef" assertTrue(regex.matches(testString)) patString = "abc\uD834\uDDB9\uD834\uDD65\uD834\uDD6Fef" testString = "abc\uD834\uDDBFef" regex = Regex(patString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) testString = "abc\uD834\uDDBB\uD834\uDD6Fef" assertTrue(regex.matches(testString)) /* * testSupplementary characters with no decomposition */ patString = "a\uD9A0\uDE8Ebc\uD834\uDDBB\uD834\uDD6Fe\uDE8Ef" testString = "a\uD9A0\uDE8Ebc\uD834\uDDBFe\uDE8Ef" regex = Regex(patString, RegexOption.CANON_EQ) assertTrue(regex.matches(testString)) } @Test fun testRangesWithSurrogatesSupplementary() { var patString = "[abc\uD8D2]" var testString = "\uD8D2" var regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "a" assertTrue(regex.matches(testString)) testString = "ef\uD8D2\uDD71gh" assertFalse(regex.containsMatchIn(testString)) testString = "ef\uD8D2gh" assertTrue(regex.containsMatchIn(testString)) patString = "[abc\uD8D3&&[c\uD8D3]]" testString = "c" regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "a" assertFalse(regex.matches(testString)) testString = "ef\uD8D3\uDD71gh" assertFalse(regex.containsMatchIn(testString)) testString = "ef\uD8D3gh" assertTrue(regex.containsMatchIn(testString)) patString = "[abc\uD8D3\uDBEE\uDF0C&&[c\uD8D3\uDBEE\uDF0C]]" testString = "c" regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "\uDBEE\uDF0C" assertTrue(regex.matches(testString)) testString = "ef\uD8D3\uDD71gh" assertFalse(regex.containsMatchIn(testString)) testString = "ef\uD8D3gh" assertTrue(regex.containsMatchIn(testString)) patString = "[abc\uDBFC]\uDDC2cd" testString = "\uDBFC\uDDC2cd" regex = Regex(patString) assertFalse(regex.matches(testString)) testString = "a\uDDC2cd" assertTrue(regex.matches(testString)) } @Test fun testSequencesWithSurrogatesSupplementary() { var patString = "abcd\uD8D3" var testString = "abcd\uD8D3\uDFFC" var regex = Regex(patString) assertFalse(regex.containsMatchIn(testString)) testString = "abcd\uD8D3abc" assertTrue(regex.containsMatchIn(testString)) patString = "ab\uDBEFcd" testString = "ab\uDBEFcd" regex = Regex(patString) assertTrue(regex.matches(testString)) patString = "\uDFFCabcd" testString = "\uD8D3\uDFFCabcd" regex = Regex(patString) assertFalse(regex.containsMatchIn(testString)) testString = "abc\uDFFCabcdecd" assertTrue(regex.containsMatchIn(testString)) patString = "\uD8D3\uDFFCabcd" testString = "abc\uD8D3\uD8D3\uDFFCabcd" regex = Regex(patString) assertTrue(regex.containsMatchIn(testString)) } @Test fun testPredefinedClassesWithSurrogatesSupplementary() { var patString = "[123\\D]" var testString = "a" var regex = Regex(patString) assertTrue(regex.containsMatchIn(testString)) testString = "5" assertFalse(regex.containsMatchIn(testString)) testString = "3" assertTrue(regex.containsMatchIn(testString)) // low surrogate testString = "\uDFC4" assertTrue(regex.containsMatchIn(testString)) // high surrogate testString = "\uDADA" assertTrue(regex.containsMatchIn(testString)) testString = "\uDADA\uDFC4" assertTrue(regex.containsMatchIn(testString)) testString = "5" assertFalse(regex.containsMatchIn(testString)) testString = "3" assertTrue(regex.containsMatchIn(testString)) // low surrogate testString = "\uDFC4" assertTrue(regex.containsMatchIn(testString)) // high surrogate testString = "\uDADA" assertTrue(regex.containsMatchIn(testString)) testString = "\uDADA\uDFC4" assertTrue(regex.containsMatchIn(testString)) // surrogate characters patString = "\\p{Cs}" testString = "\uD916\uDE27" regex = Regex(patString) /* * see http://www.unicode.org/reports/tr18/#Supplementary_Characters we * have to treat text as code points not code units. \\p{Cs} matches any * surrogate character but here testString is a one code point * consisting of two code units (two surrogate characters) so we find * nothing */ assertFalse(regex.containsMatchIn(testString)) // swap low and high surrogates testString = "\uDE27\uD916" assertTrue(regex.containsMatchIn(testString)) patString = "[\uD916\uDE271\uD91623&&[^\\p{Cs}]]" testString = "1" regex = Regex(patString) assertTrue(regex.containsMatchIn(testString)) testString = "\uD916" regex = Regex(patString) assertFalse(regex.containsMatchIn(testString)) testString = "\uD916\uDE27" regex = Regex(patString) assertTrue(regex.containsMatchIn(testString)) // \uD9A0\uDE8E=\u7828E // \u78281=\uD9A0\uDE81 patString = "[a-\uD9A0\uDE8E]" testString = "\uD9A0\uDE81" regex = Regex(patString) assertTrue(regex.matches(testString)) } @Test fun testDotConstructionWithSurrogatesSupplementary() { var patString = "." var testString = "\uD9A0\uDE81" var regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "\uDE81" assertTrue(regex.matches(testString)) testString = "\uD9A0" assertTrue(regex.matches(testString)) testString = "\n" assertFalse(regex.matches(testString)) patString = ".*\uDE81" testString = "\uD9A0\uDE81\uD9A0\uDE81\uD9A0\uDE81" regex = Regex(patString) assertFalse(regex.matches(testString)) testString = "\uD9A0\uDE81\uD9A0\uDE81\uDE81" assertTrue(regex.matches(testString)) patString = ".*" testString = "\uD9A0\uDE81\n\uD9A0\uDE81\uD9A0\n\uDE81" regex = Regex(patString, RegexOption.DOT_MATCHES_ALL) assertTrue(regex.matches(testString)) } @Test fun testQuantifiersWithSurrogatesSupplementary() { val patString = "\uD9A0\uDE81*abc" var testString = "\uD9A0\uDE81\uD9A0\uDE81abc" val regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "abc" assertTrue(regex.matches(testString)) } @Test fun testAlternationsWithSurrogatesSupplementary() { val patString = "\uDE81|\uD9A0\uDE81|\uD9A0" var testString = "\uD9A0" val regex = Regex(patString) assertTrue(regex.matches(testString)) testString = "\uDE81" assertTrue(regex.matches(testString)) testString = "\uD9A0\uDE81" assertTrue(regex.matches(testString)) testString = "\uDE81\uD9A0" assertFalse(regex.matches(testString)) } @Test fun testGroupsWithSurrogatesSupplementary() { // this pattern matches nothing var patString = "(\uD9A0)\uDE81" var testString = "\uD9A0\uDE81" var regex = Regex(patString) assertFalse(regex.matches(testString)) patString = "(\uD9A0)" testString = "\uD9A0\uDE81" regex = Regex(patString, RegexOption.DOT_MATCHES_ALL) assertFalse(regex.containsMatchIn(testString)) } } ================================================ FILE: backend.native/tests/harmony_regex/PatternTest2.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class PatternTest2 { fun assertTrue(msg: String, value: Boolean) = assertTrue(value, msg) fun assertFalse(msg: String, value: Boolean) = assertFalse(value, msg) /** * Tests simple pattern compilation and matching methods */ @Test fun testSimpleMatch() { val regex = Regex("foo.*") var testString = "foo123" assertTrue(regex.matches(testString)) assertTrue(regex in testString) assertTrue(regex.find(testString) != null) testString = "fox" assertFalse(regex.matches(testString)) assertFalse(regex in testString) assertFalse(regex.find(testString) != null) assertTrue(Regex("foo.*").matches("foo123")) assertFalse(Regex("foo.*").matches("fox")) assertFalse(Regex("bar").matches("foobar")) assertTrue(Regex("").matches("")) } @Test fun testCursors() { val regex: Regex var result: MatchResult? try { regex = Regex("foo") result = regex.find("foobar") assertNotNull(result) assertEquals(0, result!!.range.start) assertEquals(3, result.range.endInclusive + 1) assertNull(result.next()) result = regex.find("barfoobar") assertNotNull(result) assertEquals(3, result!!.range.start) assertEquals(6, result.range.endInclusive + 1) assertNull(result.next()) result = regex.find("barfoo") assertNotNull(result) assertEquals(3, result!!.range.start) assertEquals(6, result.range.endInclusive + 1) assertNull(result.next()) result = regex.find("foobarfoobarfoo") assertNotNull(result) assertEquals(0, result!!.range.start) assertEquals(3, result.range.endInclusive + 1) result = result.next() assertNotNull(result) assertEquals(6, result!!.range.start) assertEquals(9, result.range.endInclusive + 1) result = result.next() assertNotNull(result) assertEquals(12, result!!.range.start) assertEquals(15, result.range.endInclusive + 1) assertNull(result.next()) result = regex.find("foobarfoobarfoo", 0) assertNotNull(result) assertEquals(0, result!!.range.start) assertEquals(3, result.range.endInclusive + 1) result = regex.find("foobarfoobarfoo", 4) assertNotNull(result) assertEquals(6, result!!.range.start) assertEquals(9, result.range.endInclusive + 1) } catch (e: IllegalArgumentException) { println(e.message) fail() } } @Test fun testGroups() { val regex: Regex var result: MatchResult? regex = Regex("(p[0-9]*)#?(q[0-9]*)") result = regex.find("p1#q3p2q42p5p71p63#q888") assertNotNull(result) assertEquals(0, result!!.range.start) assertEquals(5, result.range.endInclusive + 1) assertEquals(3, result.groups.size) assertEquals(0, result.groups[0]!!.range.start) assertEquals(5, result.groups[0]!!.range.endInclusive + 1) assertEquals(0, result.groups[1]!!.range.start) assertEquals(2, result.groups[1]!!.range.endInclusive + 1) assertEquals(3, result.groups[2]!!.range.start) assertEquals(5, result.groups[2]!!.range.endInclusive + 1) assertEquals("p1#q3", result.value) assertEquals("p1#q3", result.groupValues[0]) assertEquals("p1", result.groupValues[1]) assertEquals("q3", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals(5, result!!.range.start) assertEquals(10, result.range.endInclusive + 1) assertEquals(3, result.groups.size) assertEquals(10, result.groups[0]!!.range.endInclusive + 1) assertEquals(5, result.groups[1]!!.range.start) assertEquals(7, result.groups[1]!!.range.endInclusive + 1) assertEquals(7, result.groups[2]!!.range.start) assertEquals(10, result.groups[2]!!.range.endInclusive + 1) assertEquals("p2q42", result.value) assertEquals("p2q42", result.groupValues[0]) assertEquals("p2", result.groupValues[1]) assertEquals("q42", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals(15, result!!.range.start) assertEquals(23, result.range.endInclusive + 1) assertEquals(3, result.groups.size) assertEquals(15, result.groups[0]!!.range.start) assertEquals(23, result.groups[0]!!.range.endInclusive + 1) assertEquals(15, result.groups[1]!!.range.start) assertEquals(18, result.groups[1]!!.range.endInclusive + 1) assertEquals(19, result.groups[2]!!.range.start) assertEquals(23, result.groups[2]!!.range.endInclusive + 1) assertEquals("p63#q888", result.value) assertEquals("p63#q888", result.groupValues[0]) assertEquals("p63", result.groupValues[1]) assertEquals("q888", result.groupValues[2]) assertNull(result.next()) } @Test fun testReplace() { var regex: Regex // Note: examples from book, // Hitchens, Ron, 2002, "Java NIO", O'Reilly, page 171 regex = Regex("a*b") var testString = "aabfooaabfooabfoob" assertTrue(regex.replace(testString, "-") == "-foo-foo-foo-") assertTrue(regex.replaceFirst(testString, "-") == "-fooaabfooabfoob") regex = Regex("([bB])yte") testString = "Byte for byte" assertTrue(regex.replaceFirst(testString, "$1ite") == "Bite for byte") assertTrue(regex.replace(testString, "$1ite") == "Bite for bite") regex = Regex("\\d\\d\\d\\d([- ])") testString = "card #1234-5678-1234" assertTrue(regex.replaceFirst(testString, "xxxx$1") == "card #xxxx-5678-1234") assertTrue(regex.replace(testString, "xxxx$1") == "card #xxxx-xxxx-1234") regex = Regex("(up|left)( *)(right|down)") testString = "left right, up down" assertTrue(regex.replaceFirst(testString, "$3$2$1") == "right left, up down") assertTrue(regex.replace(testString, "$3$2$1") == "right left, down up") regex = Regex("([CcPp][hl]e[ea]se)") testString = "I want cheese. Please." assertTrue(regex.replaceFirst(testString, " $1 ") == "I want cheese . Please.") assertTrue(regex.replace(testString, " $1 ") == "I want cheese . Please .") } @Test fun testEscapes() { var regex: Regex var result: MatchResult? // Test \\ sequence regex = Regex("([a-z]+)\\\\([a-z]+);") result = regex.find("fred\\ginger;abbott\\costello;jekell\\hyde;") assertNotNull(result) assertEquals("fred", result!!.groupValues[1]) assertEquals("ginger", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals("abbott", result!!.groupValues[1]) assertEquals("costello", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals("jekell", result!!.groupValues[1]) assertEquals("hyde", result.groupValues[2]) assertNull(result.next()) // Test \n, \t, \r, \f, \e, \a sequences regex = Regex("([a-z]+)[\\n\\t\\r\\f\\e\\a]+([a-z]+)") result = regex.find("aa\nbb;cc\u0009\rdd;ee\u000C\u001Bff;gg\n\u0007hh") assertNotNull(result) assertEquals("aa", result!!.groupValues[1]) assertEquals("bb", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals("cc", result!!.groupValues[1]) assertEquals("dd", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals("ee", result!!.groupValues[1]) assertEquals("ff", result.groupValues[2]) result = result.next() assertNotNull(result) assertEquals("gg", result!!.groupValues[1]) assertEquals("hh", result.groupValues[2]) assertNull(result.next()) // Test \\u and \\x sequences regex = Regex("([0-9]+)[\\u0020:\\x21];") result = regex.find("11:;22 ;33-;44!;") assertNotNull(result) assertEquals("11", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("22", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("44", result!!.groupValues[1]) assertNull(result.next()) // Test invalid unicode sequences // TODO: Double check it. try { regex = Regex("\\u") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\u;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\u002") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\u002;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test invalid hex sequences try { regex = Regex("\\x") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\x;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\xa") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\xa;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test \0 (octal) sequences (1, 2 and 3 digit) regex = Regex("([0-9]+)[\\07\\040\\0160];") result = regex.find("11\u0007;22:;33 ;44p;") assertNotNull(result) assertEquals("11", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("33", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("44", result!!.groupValues[1]) assertNull(result.next()) // Test invalid octal sequences try { regex = Regex("\\08") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\0") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\0;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test \c (control character) sequence regex = Regex("([0-9]+)[\\cA\\cB\\cC\\cD];") result = regex.find("11\u0001;22:;33\u0002;44p;55\u0003;66\u0004;") assertNotNull(result) assertEquals("11", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("33", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("55", result!!.groupValues[1]) result = result.next() assertNotNull(result) assertEquals("66", result!!.groupValues[1]) assertNull(result.next()) // More thorough control escape test // Ensure that each escape matches exactly the corresponding // character // code and no others (well, from 0-255 at least) for (i in 0..25) { regex = Regex("\\c${'A' + i}") var match_char = -1 for (j in 0..255) { if (regex.matches("${j.toChar()}")) { assertEquals(-1, match_char) match_char = j } } assertTrue(match_char == i + 1) } // Test invalid control escapes try { regex = Regex("\\c") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } } @Test fun testCharacterClasses() { var regex: Regex // Test one character range regex = Regex("[p].*[l]") assertTrue(regex.matches("paul")) assertTrue(regex.matches("pool")) assertFalse(regex.matches("pong")) assertTrue(regex.matches("pl")) // Test two character range regex = Regex("[pm].*[lp]") assertTrue(regex.matches("prop")) assertTrue(regex.matches("mall")) assertFalse(regex.matches("pong")) assertTrue(regex.matches("pill")) // Test range including [ and ] regex = Regex("[<\\[].*[\\]>]") assertTrue(regex.matches("")) assertTrue(regex.matches("[bar]")) assertFalse(regex.matches("{foobar]")) assertTrue(regex.matches("") assertTrue(regex.matches("")) assertFalse(regex.matches("")) val result = regex.find("xyz zzz") assertNotNull(result) assertNotNull(result!!.next()) assertNull(result.next()!!.next()) // Test \S (not whitespace) // TODO: We've removed \f from string since kotlin doesn't recognize this escape in a string. regex = Regex("<[a-z] \\S[0-9][\\S\n]+[^\\S]221>") assertTrue(regex.matches("")) assertTrue(regex.matches("")) assertFalse(regex.matches("")) assertTrue(regex.matches("")) regex = Regex("<[a-z] \\S[0-9][\\S\n]+[^\\S]221[\\S&&[^abc]]>") assertTrue(regex.matches("")) assertTrue(regex.matches("")) assertFalse(regex.matches("")) assertFalse(regex.matches("")) assertFalse(regex.matches("")) assertTrue(regex.matches("")) // Test \w (ascii word) regex = Regex("<\\w+\\s[0-9]+;[^\\w]\\w+/[\\w$]+;") assertTrue(regex.matches(""); * m = p.matcher(""); assertTrue(m.matches()); m = p.matcher(""); * assertTrue(m.matches()); m = p.matcher(""); * assertFalse(m.matches()); */ regex = Regex("\\p{Lower}+") assertTrue(regex.matches("abcdefghijklmnopqrstuvwxyz")) // Invalid uses of \p{Lower} try { regex = Regex("\\p") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{Lower") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{Lower;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test \p{Upper} /* * FIXME: Requires complex range processing p = Regex("<\\p{Upper}\\d\\P{Upper}:[\\p{Upper}z]\\s[^\\P{Upper}]>"); * m = p.matcher(""); assertTrue(m.matches()); m = p.matcher(""); * assertTrue(m.matches()); m = p.matcher(""); * assertFalse(m.matches()); */ regex = Regex("\\p{Upper}+") assertTrue(regex.matches("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) // Invalid uses of \p{Upper} try { regex = Regex("\\p{Upper") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{Upper;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test \p{ASCII} /* * FIXME: Requires complex range processing p = Regex("<\\p{ASCII}\\d\\P{ASCII}:[\\p{ASCII}\u1234]\\s[^\\P{ASCII}]>"); * m = p.matcher(""); assertTrue(m.matches()); m = * p.matcher(""); assertTrue(m.matches()); m = * p.matcher("<\u00846#:E E>"); assertFalse(m.matches()) */ regex = Regex("\\p{ASCII}") for (i in 0 until 0x80) { assertTrue(regex.matches("${i.toChar()}")) } for (i in 0x80..0xff) { assertFalse(regex.matches("${i.toChar()}")) } // Invalid uses of \p{ASCII} try { regex = Regex("\\p{ASCII") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } try { regex = Regex("\\p{ASCII;") fail("IllegalArgumentException expected") } catch (e: IllegalArgumentException) { } // Test \p{Alpha} // TODO // Test \p{Digit} // TODO // Test \p{XDigit} // TODO // Test \p{Alnum} // TODO // Test \p{Punct} // TODO // Test \p{Graph} // TODO // Test \p{Print} // TODO // Test \p{Blank} // TODO // Test \p{Space} // TODO // Test \p{Cntrl} // TODO } @Test fun testUnicodeCategories() { // Test Unicode categories using \p and \P // One letter codes: L, M, N, P, S, Z, C // Two letter codes: Lu, Nd, Sc, Sm, ... // See java.lang.Character and Unicode standard for complete list // TODO // Test \p{L} // TODO // Test \p{N} // TODO // ... etc // Test two letter codes: // From unicode.org: // Lu // Ll // Lt // Lm // Lo // Mn // Mc // Me // Nd // Nl // No // Pc // Pd // Ps // Pe // Pi // Pf // Po // Sm // Sc // Sk // So // Zs // Zl // Zp // Cc // Cf // Cs // Co // Cn } @Test fun testUnicodeBlocks() { var regex: Regex // Test Unicode blocks using \p and \P for (block in UBlocks) { regex = Regex("\\p{In" + block.name + "}") if (block.low > 0) { assertFalse(regex.matches((block.low - 1).toChar().toString())) } for (i in block.low..block.high) { assertTrue(regex.matches(i.toChar().toString())) } if (block.high < 0xFFFF) { assertFalse(regex.matches((block.high + 1).toChar().toString())) } regex = Regex("\\P{In" + block.name + "}") if (block.low > 0) { assertTrue(regex.matches((block.low - 1).toChar().toString())) } for (i in block.low..block.high) { assertFalse("assert: Regex: $regex, match to: ${i.toChar()} ($i)", regex.matches(i.toChar().toString())) } if (block.high < 0xFFFF) { assertTrue(regex.matches((block.high + 1).toChar().toString())) } } } @Test fun testCapturingGroups() { // Test simple capturing groups // TODO // Test grouping without capture (?:...) // TODO // Test combination of grouping and capture // TODO // Test \ sequence with capturing and non-capturing groups // TODO // Test \ with out of range // TODO } @Test fun testRepeats() { // Test ? // TODO // Test * // TODO // Test + // TODO // Test {}, including 0, 1 and more // TODO // Test {,}, including 0, 1 and more // TODO // Test {,}, with n1 < n2, n1 = n2 and n1 > n2 (illegal?) // TODO } @Test fun testAnchors() { // Test ^, default and MULTILINE // TODO // Test $, default and MULTILINE // TODO // Test \b (word boundary) // TODO // Test \B (not a word boundary) // TODO // Test \A (beginning of string) // TODO // Test \Z (end of string) // TODO // Test \z (end of string) // TODO // Test \G // TODO // Test positive lookahead using (?=...) // TODO // Test negative lookahead using (?!...) // TODO // Test positive lookbehind using (?<=...) // TODO // Test negative lookbehind using (?...) // TODO // Test (?onflags-offflags) // Valid flags are i,m,d,s,u,x // TODO // Test (?onflags-offflags:...) // TODO // Test \Q, \E regex = Regex("[a-z]+;\\Q[a-z]+;\\Q(foo.*);\\E[0-9]+") assertTrue(regex.matches("abc;[a-z]+;\\Q(foo.*);411")) assertFalse(regex.matches("abc;def;foo42;555")) assertFalse(regex.matches("abc;\\Qdef;\\Qfoo99;\\E123")) regex = Regex("[a-z]+;(foo[0-9]-\\Q(...)\\E);[0-9]+") val result = regex.matchEntire("abc;foo5-(...);123") assertNotNull(result) assertEquals("foo5-(...)", result!!.groupValues[1]) assertFalse(regex.matches("abc;foo9-(xxx);789")) regex = Regex("[a-z]+;(bar[0-9]-[a-z\\Q$-\\E]+);[0-9]+") assertTrue(regex.matches("abc;bar0-def$-;123")) regex = Regex("[a-z]+;(bar[0-9]-[a-z\\Q-$\\E]+);[0-9]+") assertTrue(regex.matches("abc;bar0-def$-;123")) regex = Regex("[a-z]+;(bar[0-9]-[a-z\\Q[0-9]\\E]+);[0-9]+") assertTrue(regex.matches("abc;bar0-def[99]-]0x[;123")); regex = Regex("[a-z]+;(bar[0-9]-[a-z\\[0\\-9\\]]+);[0-9]+") assertTrue(regex.matches("abc;bar0-def[99]-]0x[;123")) // Test # // TODO } @Test fun testCompile1() { val regex = Regex("[0-9A-Za-z][0-9A-Za-z\\x2e\\x3a\\x2d\\x5f]*") val name = "iso-8859-1" assertTrue(regex.matches(name)) } @Test fun testCompile2() { val findString = "\\Qimport\\E" val regex = Regex(findString) assertTrue(regex in "import a.A;\n\n import b.B;\nclass C {}") } @Test fun testCompile3() { var regex: Regex var result: MatchResult? regex = Regex("a$") result = regex.find("a\n") assertNotNull(result) assertEquals("a", result!!.value) assertNull(result.next()) regex = Regex("(a$)") result = regex.find("a\n") assertNotNull(result) assertEquals("a", result!!.value) assertEquals("a", result.groupValues[1]) assertNull(result.next()) regex = Regex("^.*$", RegexOption.MULTILINE) result = regex.find("a\n") assertNotNull(result) assertEquals("a", result!!.value) assertNull(result.next()) result = regex.find("a\nb\n") assertNotNull(result) assertEquals("a", result!!.value) result = result.next() assertNotNull(result) assertEquals("b", result!!.value) assertNull(result.next()) result = regex.find("a\nb") assertNotNull(result) assertEquals("a", result!!.value) result = result.next() assertNotNull(result) assertEquals("b", result!!.value) assertNull(result.next()) result = regex.find("\naa\r\nbb\rcc\n\n") assertNotNull(result) assertTrue(result!!.value == "") result = result.next() assertNotNull(result) assertEquals("aa", result!!.value) result = result.next() assertNotNull(result) assertEquals("bb", result!!.value) result = result.next() assertNotNull(result) assertEquals("cc", result!!.value) result = result.next() assertNotNull(result) assertTrue(result!!.value == "") assertNull(result.next()) result = regex.find("a") assertNotNull(result) assertEquals("a", result!!.value) assertNull(result.next()) result = regex.find("") assertNull(result) regex = Regex("^.*$") result = regex.find("") assertNotNull(result) assertTrue(result!!.value == "") assertNull(result.next()) } @Test fun testCompile4() { val findString = "\\Qpublic\\E" val text = StringBuilder(" public class Class {\n" + " public class Class {") val regex = Regex(findString) val result = regex.find(text) assertNotNull(result) assertEquals(4, result!!.range.start) // modify text text.setLength(0) text.append("Text have been changed.") assertNull(regex.find(text)) } @Test fun testCompile5() { val p = Regex("^[0-9]") val s = p.split("12", 0) assertEquals("", s[0]) assertEquals("2", s[1]) assertEquals(2, s.size) } private class UBInfo(var low: Int, var high: Int, var name: String) // A table representing the unicode categories // private static UBInfo[] UCategories = { // Lu // Ll // Lt // Lm // Lo // Mn // Mc // Me // Nd // Nl // No // Pc // Pd // Ps // Pe // Pi // Pf // Po // Sm // Sc // Sk // So // Zs // Zl // Zp // Cc // Cf // Cs // Co // Cn // }; // A table representing the unicode character blocks private val UBlocks = arrayOf( /* 0000; 007F; Basic Latin */ UBInfo(0x0000, 0x007F, "BasicLatin"), // Character.UnicodeBlock.BASIC_LATIN /* 0080; 00FF; Latin-1 Supplement */ UBInfo(0x0080, 0x00FF, "Latin-1Supplement"), // Character.UnicodeBlock.LATIN_1_SUPPLEMENT /* 0100; 017F; Latin Extended-A */ UBInfo(0x0100, 0x017F, "LatinExtended-A"), // Character.UnicodeBlock.LATIN_EXTENDED_A /* 0180; 024F; Latin Extended-B */ // new UBInfo (0x0180,0x024F,"InLatinExtended-B"), // // Character.UnicodeBlock.LATIN_EXTENDED_B /* 0250; 02AF; IPA Extensions */ UBInfo(0x0250, 0x02AF, "IPAExtensions"), // Character.UnicodeBlock.IPA_EXTENSIONS /* 02B0; 02FF; Spacing Modifier Letters */ UBInfo(0x02B0, 0x02FF, "SpacingModifierLetters"), // Character.UnicodeBlock.SPACING_MODIFIER_LETTERS /* 0300; 036F; Combining Diacritical Marks */ UBInfo(0x0300, 0x036F, "CombiningDiacriticalMarks"), // Character.UnicodeBlock.COMBINING_DIACRITICAL_MARKS /* 0370; 03FF; Greek */ UBInfo(0x0370, 0x03FF, "Greek"), // Character.UnicodeBlock.GREEK /* 0400; 04FF; Cyrillic */ UBInfo(0x0400, 0x04FF, "Cyrillic"), // Character.UnicodeBlock.CYRILLIC /* 0530; 058F; Armenian */ UBInfo(0x0530, 0x058F, "Armenian"), // Character.UnicodeBlock.ARMENIAN /* 0590; 05FF; Hebrew */ UBInfo(0x0590, 0x05FF, "Hebrew"), // Character.UnicodeBlock.HEBREW /* 0600; 06FF; Arabic */ UBInfo(0x0600, 0x06FF, "Arabic"), // Character.UnicodeBlock.ARABIC /* 0700; 074F; Syriac */ UBInfo(0x0700, 0x074F, "Syriac"), // Character.UnicodeBlock.SYRIAC /* 0780; 07BF; Thaana */ UBInfo(0x0780, 0x07BF, "Thaana"), // Character.UnicodeBlock.THAANA /* 0900; 097F; Devanagari */ UBInfo(0x0900, 0x097F, "Devanagari"), // Character.UnicodeBlock.DEVANAGARI /* 0980; 09FF; Bengali */ UBInfo(0x0980, 0x09FF, "Bengali"), // Character.UnicodeBlock.BENGALI /* 0A00; 0A7F; Gurmukhi */ UBInfo(0x0A00, 0x0A7F, "Gurmukhi"), // Character.UnicodeBlock.GURMUKHI /* 0A80; 0AFF; Gujarati */ UBInfo(0x0A80, 0x0AFF, "Gujarati"), // Character.UnicodeBlock.GUJARATI /* 0B00; 0B7F; Oriya */ UBInfo(0x0B00, 0x0B7F, "Oriya"), // Character.UnicodeBlock.ORIYA /* 0B80; 0BFF; Tamil */ UBInfo(0x0B80, 0x0BFF, "Tamil"), // Character.UnicodeBlock.TAMIL /* 0C00; 0C7F; Telugu */ UBInfo(0x0C00, 0x0C7F, "Telugu"), // Character.UnicodeBlock.TELUGU /* 0C80; 0CFF; Kannada */ UBInfo(0x0C80, 0x0CFF, "Kannada"), // Character.UnicodeBlock.KANNADA /* 0D00; 0D7F; Malayalam */ UBInfo(0x0D00, 0x0D7F, "Malayalam"), // Character.UnicodeBlock.MALAYALAM /* 0D80; 0DFF; Sinhala */ UBInfo(0x0D80, 0x0DFF, "Sinhala"), // Character.UnicodeBlock.SINHALA /* 0E00; 0E7F; Thai */ UBInfo(0x0E00, 0x0E7F, "Thai"), // Character.UnicodeBlock.THAI /* 0E80; 0EFF; Lao */ UBInfo(0x0E80, 0x0EFF, "Lao"), // Character.UnicodeBlock.LAO /* 0F00; 0FFF; Tibetan */ UBInfo(0x0F00, 0x0FFF, "Tibetan"), // Character.UnicodeBlock.TIBETAN /* 1000; 109F; Myanmar */ UBInfo(0x1000, 0x109F, "Myanmar"), // Character.UnicodeBlock.MYANMAR /* 10A0; 10FF; Georgian */ UBInfo(0x10A0, 0x10FF, "Georgian"), // Character.UnicodeBlock.GEORGIAN /* 1100; 11FF; Hangul Jamo */ UBInfo(0x1100, 0x11FF, "HangulJamo"), // Character.UnicodeBlock.HANGUL_JAMO /* 1200; 137F; Ethiopic */ UBInfo(0x1200, 0x137F, "Ethiopic"), // Character.UnicodeBlock.ETHIOPIC /* 13A0; 13FF; Cherokee */ UBInfo(0x13A0, 0x13FF, "Cherokee"), // Character.UnicodeBlock.CHEROKEE /* 1400; 167F; Unified Canadian Aboriginal Syllabics */ UBInfo(0x1400, 0x167F, "UnifiedCanadianAboriginalSyllabics"), // Character.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS /* 1680; 169F; Ogham */ UBInfo(0x1680, 0x169F, "Ogham"), // Character.UnicodeBlock.OGHAM /* 16A0; 16FF; Runic */ UBInfo(0x16A0, 0x16FF, "Runic"), // Character.UnicodeBlock.RUNIC /* 1780; 17FF; Khmer */ UBInfo(0x1780, 0x17FF, "Khmer"), // Character.UnicodeBlock.KHMER /* 1800; 18AF; Mongolian */ UBInfo(0x1800, 0x18AF, "Mongolian"), // Character.UnicodeBlock.MONGOLIAN /* 1E00; 1EFF; Latin Extended Additional */ UBInfo(0x1E00, 0x1EFF, "LatinExtendedAdditional"), // Character.UnicodeBlock.LATIN_EXTENDED_ADDITIONAL /* 1F00; 1FFF; Greek Extended */ UBInfo(0x1F00, 0x1FFF, "GreekExtended"), // Character.UnicodeBlock.GREEK_EXTENDED /* 2000; 206F; General Punctuation */ UBInfo(0x2000, 0x206F, "GeneralPunctuation"), // Character.UnicodeBlock.GENERAL_PUNCTUATION /* 2070; 209F; Superscripts and Subscripts */ UBInfo(0x2070, 0x209F, "SuperscriptsandSubscripts"), // Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS /* 20A0; 20CF; Currency Symbols */ UBInfo(0x20A0, 0x20CF, "CurrencySymbols"), // Character.UnicodeBlock.CURRENCY_SYMBOLS /* 20D0; 20FF; Combining Marks for Symbols */ UBInfo(0x20D0, 0x20FF, "CombiningMarksforSymbols"), // Character.UnicodeBlock.COMBINING_MARKS_FOR_SYMBOLS /* 2100; 214F; Letterlike Symbols */ UBInfo(0x2100, 0x214F, "LetterlikeSymbols"), // Character.UnicodeBlock.LETTERLIKE_SYMBOLS /* 2150; 218F; Number Forms */ UBInfo(0x2150, 0x218F, "NumberForms"), // Character.UnicodeBlock.NUMBER_FORMS /* 2190; 21FF; Arrows */ UBInfo(0x2190, 0x21FF, "Arrows"), // Character.UnicodeBlock.ARROWS /* 2200; 22FF; Mathematical Operators */ UBInfo(0x2200, 0x22FF, "MathematicalOperators"), // Character.UnicodeBlock.MATHEMATICAL_OPERATORS /* 2300; 23FF; Miscellaneous Technical */ UBInfo(0x2300, 0x23FF, "MiscellaneousTechnical"), // Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL /* 2400; 243F; Control Pictures */ UBInfo(0x2400, 0x243F, "ControlPictures"), // Character.UnicodeBlock.CONTROL_PICTURES /* 2440; 245F; Optical Character Recognition */ UBInfo(0x2440, 0x245F, "OpticalCharacterRecognition"), // Character.UnicodeBlock.OPTICAL_CHARACTER_RECOGNITION /* 2460; 24FF; Enclosed Alphanumerics */ UBInfo(0x2460, 0x24FF, "EnclosedAlphanumerics"), // Character.UnicodeBlock.ENCLOSED_ALPHANUMERICS /* 2500; 257F; Box Drawing */ UBInfo(0x2500, 0x257F, "BoxDrawing"), // Character.UnicodeBlock.BOX_DRAWING /* 2580; 259F; Block Elements */ UBInfo(0x2580, 0x259F, "BlockElements"), // Character.UnicodeBlock.BLOCK_ELEMENTS /* 25A0; 25FF; Geometric Shapes */ UBInfo(0x25A0, 0x25FF, "GeometricShapes"), // Character.UnicodeBlock.GEOMETRIC_SHAPES /* 2600; 26FF; Miscellaneous Symbols */ UBInfo(0x2600, 0x26FF, "MiscellaneousSymbols"), // Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS /* 2700; 27BF; Dingbats */ UBInfo(0x2700, 0x27BF, "Dingbats"), // Character.UnicodeBlock.DINGBATS /* 2800; 28FF; Braille Patterns */ UBInfo(0x2800, 0x28FF, "BraillePatterns"), // Character.UnicodeBlock.BRAILLE_PATTERNS /* 2E80; 2EFF; CJK Radicals Supplement */ UBInfo(0x2E80, 0x2EFF, "CJKRadicalsSupplement"), // Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT /* 2F00; 2FDF; Kangxi Radicals */ UBInfo(0x2F00, 0x2FDF, "KangxiRadicals"), // Character.UnicodeBlock.KANGXI_RADICALS /* 2FF0; 2FFF; Ideographic Description Characters */ UBInfo(0x2FF0, 0x2FFF, "IdeographicDescriptionCharacters"), // Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS /* 3000; 303F; CJK Symbols and Punctuation */ UBInfo(0x3000, 0x303F, "CJKSymbolsandPunctuation"), // Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION /* 3040; 309F; Hiragana */ UBInfo(0x3040, 0x309F, "Hiragana"), // Character.UnicodeBlock.HIRAGANA /* 30A0; 30FF; Katakana */ UBInfo(0x30A0, 0x30FF, "Katakana"), // Character.UnicodeBlock.KATAKANA /* 3100; 312F; Bopomofo */ UBInfo(0x3100, 0x312F, "Bopomofo"), // Character.UnicodeBlock.BOPOMOFO /* 3130; 318F; Hangul Compatibility Jamo */ UBInfo(0x3130, 0x318F, "HangulCompatibilityJamo"), // Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO /* 3190; 319F; Kanbun */ UBInfo(0x3190, 0x319F, "Kanbun"), // Character.UnicodeBlock.KANBUN /* 31A0; 31BF; Bopomofo Extended */ UBInfo(0x31A0, 0x31BF, "BopomofoExtended"), // Character.UnicodeBlock.BOPOMOFO_EXTENDED /* 3200; 32FF; Enclosed CJK Letters and Months */ UBInfo(0x3200, 0x32FF, "EnclosedCJKLettersandMonths"), // Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS /* 3300; 33FF; CJK Compatibility */ UBInfo(0x3300, 0x33FF, "CJKCompatibility"), // Character.UnicodeBlock.CJK_COMPATIBILITY /* 3400; 4DB5; CJK Unified Ideographs Extension A */ UBInfo(0x3400, 0x4DB5, "CJKUnifiedIdeographsExtensionA"), // Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A /* 4E00; 9FFF; CJK Unified Ideographs */ UBInfo(0x4E00, 0x9FFF, "CJKUnifiedIdeographs"), // Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS /* A000; A48F; Yi Syllables */ UBInfo(0xA000, 0xA48F, "YiSyllables"), // Character.UnicodeBlock.YI_SYLLABLES /* A490; A4CF; Yi Radicals */ UBInfo(0xA490, 0xA4CF, "YiRadicals"), // Character.UnicodeBlock.YI_RADICALS /* AC00; D7A3; Hangul Syllables */ UBInfo(0xAC00, 0xD7A3, "HangulSyllables"), // Character.UnicodeBlock.HANGUL_SYLLABLES /* D800; DB7F; High Surrogates */ /* DB80; DBFF; High Private Use Surrogates */ /* DC00; DFFF; Low Surrogates */ /* E000; F8FF; Private Use */ /* F900; FAFF; CJK Compatibility Ideographs */ UBInfo(0xF900, 0xFAFF, "CJKCompatibilityIdeographs"), // Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS /* FB00; FB4F; Alphabetic Presentation Forms */ UBInfo(0xFB00, 0xFB4F, "AlphabeticPresentationForms"), // Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS /* FB50; FDFF; Arabic Presentation Forms-A */ UBInfo(0xFB50, 0xFDFF, "ArabicPresentationForms-A"), // Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_A /* FE20; FE2F; Combining Half Marks */ UBInfo(0xFE20, 0xFE2F, "CombiningHalfMarks"), // Character.UnicodeBlock.COMBINING_HALF_MARKS /* FE30; FE4F; CJK Compatibility Forms */ UBInfo(0xFE30, 0xFE4F, "CJKCompatibilityForms"), // Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS /* FE50; FE6F; Small Form Variants */ UBInfo(0xFE50, 0xFE6F, "SmallFormVariants"), // Character.UnicodeBlock.SMALL_FORM_VARIANTS /* FE70; FEFE; Arabic Presentation Forms-B */ // new UBInfo (0xFE70,0xFEFE,"InArabicPresentationForms-B"), // // Character.UnicodeBlock.ARABIC_PRESENTATION_FORMS_B /* FEFF; FEFF; Specials */ UBInfo(0xFEFF, 0xFEFF, "Specials"), // Character.UnicodeBlock.SPECIALS /* FF00; FFEF; Halfwidth and Fullwidth Forms */ UBInfo(0xFF00, 0xFFEF, "HalfwidthandFullwidthForms"), // Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS /* FFF0; FFFD; Specials */ UBInfo(0xFFF0, 0xFFFD, "Specials") // Character.UnicodeBlock.SPECIALS ) } ================================================ FILE: backend.native/tests/harmony_regex/ReplaceTest.kt ================================================ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class ReplaceTest { @Test fun testSimpleReplace() { val target: String val pattern: String val repl: String target = "foobarfobarfoofo1" pattern = "fo[^o]" repl = "xxx" val regex = Regex(pattern) assertEquals("foobarxxxarfoofo1", regex.replaceFirst(target, repl)) assertEquals("foobarxxxarfooxxx", regex.replace(target, repl)) } @Test fun testCaptureReplace() { var target: String var pattern: String var repl: String var s: String var regex: Regex target = "[31]foo;bar[42];[99]xyz" pattern = "\\[([0-9]+)\\]([a-z]+)" repl = "$2[$1]" regex = Regex(pattern) s = regex.replaceFirst(target, repl) assertEquals("foo[31];bar[42];[99]xyz", s) s = regex.replace(target, repl) assertEquals("foo[31];bar[42];xyz[99]", s) target = "[31]foo(42)bar{63}zoo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;" pattern = "\\[([0-9]+)\\]([a-z]+)\\(([0-9]+)\\)([a-z]+)\\{([0-9]+)\\}([a-z]+)" repl = "[$5]$6($3)$4{$1}$2" regex = Regex(pattern) s = regex.replaceFirst(target, repl) assertEquals("[63]zoo(42)bar{31}foo;[12]abc(34)def{56}ghi;{99}xyz[88]xyz(77)xyz;", s) s = regex.replace(target, repl) assertEquals("[63]zoo(42)bar{31}foo;[56]ghi(34)def{12}abc;{99}xyz[88]xyz(77)xyz;", s) } @Test fun testEscapeReplace() { val target: String val pattern: String var repl: String var s: String target = "foo'bar''foo" pattern = "'" repl = "\\'" s = target.replace(pattern.toRegex(), repl) assertEquals("foo'bar''foo", s) repl = "\\\\'" s = target.replace(pattern.toRegex(), repl) assertEquals("foo\\'bar\\'\\'foo", s) repl = "\\$3" s = target.replace(pattern.toRegex(), repl) assertEquals("foo$3bar$3$3foo", s) } } ================================================ FILE: backend.native/tests/harmony_regex/SplitTest.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.text.harmony_regex import kotlin.text.* import kotlin.test.* class SplitTest { @Test fun testSimple() { val p = Regex("/") val results = p.split("have/you/done/it/right") val expected = arrayOf("have", "you", "done", "it", "right") assertEquals(expected.size, results.size) for (i in expected.indices) { assertEquals(results[i], expected[i]) } } @Test fun testSplit1() { var p = Regex(" ") val input = "poodle zoo" var tokens: List tokens = p.split(input, 1) assertEquals(1, tokens.size) assertTrue(tokens[0] == input) tokens = p.split(input, 2) assertEquals(2, tokens.size) assertEquals("poodle", tokens[0]) assertEquals("zoo", tokens[1]) tokens = p.split(input, 5) assertEquals(2, tokens.size) assertEquals("poodle", tokens[0]) assertEquals("zoo", tokens[1]) tokens = p.split(input, 0) assertEquals(2, tokens.size) assertEquals("poodle", tokens[0]) assertEquals("zoo", tokens[1]) tokens = p.split(input) assertEquals(2, tokens.size) assertEquals("poodle", tokens[0]) assertEquals("zoo", tokens[1]) p = Regex("d") tokens = p.split(input, 1) assertEquals(1, tokens.size) assertTrue(tokens[0] == input) tokens = p.split(input, 2) assertEquals(2, tokens.size) assertEquals("poo", tokens[0]) assertEquals("le zoo", tokens[1]) tokens = p.split(input, 5) assertEquals(2, tokens.size) assertEquals("poo", tokens[0]) assertEquals("le zoo", tokens[1]) tokens = p.split(input, 0) assertEquals(2, tokens.size) assertEquals("poo", tokens[0]) assertEquals("le zoo", tokens[1]) tokens = p.split(input) assertEquals(2, tokens.size) assertEquals("poo", tokens[0]) assertEquals("le zoo", tokens[1]) p = Regex("o") tokens = p.split(input, 1) assertEquals(1, tokens.size) assertTrue(tokens[0] == input) tokens = p.split(input, 2) assertEquals(2, tokens.size) assertEquals("p", tokens[0]) assertEquals("odle zoo", tokens[1]) tokens = p.split(input, 5) assertEquals(5, tokens.size) assertEquals("p", tokens[0]) assertTrue(tokens[1] == "") assertEquals("dle z", tokens[2]) assertTrue(tokens[3] == "") assertTrue(tokens[4] == "") tokens = p.split(input, 0) assertEquals(5, tokens.size) assertEquals("p", tokens[0]) assertTrue(tokens[1] == "") assertEquals("dle z", tokens[2]) assertTrue(tokens[3] == "") assertTrue(tokens[4] == "") tokens = p.split(input) assertEquals(5, tokens.size) assertEquals("p", tokens[0]) assertTrue(tokens[1] == "") assertEquals("dle z", tokens[2]) assertTrue(tokens[3] == "") assertTrue(tokens[4] == "") } @Test fun testSplit2() { val p = Regex("") var s: List s = p.split("a", 0) assertEquals(3, s.size) assertEquals("", s[0]) assertEquals("a", s[1]) assertEquals("", s[2]) s = p.split("", 0) assertEquals(2, s.size) assertEquals("", s[0]) assertEquals("", s[1]) s = p.split("abcd", 0) assertEquals(6, s.size) assertEquals("", s[0]) assertEquals("a", s[1]) assertEquals("b", s[2]) assertEquals("c", s[3]) assertEquals("d", s[4]) assertEquals("", s[5]) } @Test fun testSplitSupplementaryWithEmptyString() { /* * See http://www.unicode.org/reports/tr18/#Supplementary_Characters We * have to treat text as code points not code units. */ val p = Regex("") val s: List s = p.split("a\ud869\uded6b", 0) assertEquals(5, s.size) assertEquals("", s[0]) assertEquals("a", s[1]) assertEquals("\ud869\uded6", s[2]) assertEquals("b", s[3]) assertEquals("", s[4]) } } ================================================ FILE: backend.native/tests/interop/auxiliary_sources/auxiliaryCppSources.def ================================================ ================================================ FILE: backend.native/tests/interop/auxiliary_sources/main.kt ================================================ import auxiliaryCppSources.* import kotlin.test.* import kotlinx.cinterop.* fun main() { assertEquals(name()!!.toKString(), "Hello from C++") } ================================================ FILE: backend.native/tests/interop/auxiliary_sources/name.cpp ================================================ #include #include "name.h" static std::string _name = "Hello from C++"; const char* name() { return _name.c_str(); } ================================================ FILE: backend.native/tests/interop/auxiliary_sources/name.h ================================================ #ifdef __cplusplus extern "C" { #endif const char* name(); #ifdef __cplusplus } #endif ================================================ FILE: backend.native/tests/interop/basics/0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import sysstat.* import kotlinx.cinterop.* fun main(args: Array) { val statBuf = nativeHeap.alloc() val res = stat("/", statBuf.ptr) println(res) println(statBuf.st_uid) } ================================================ FILE: backend.native/tests/interop/basics/1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import cstdlib.* import kotlinx.cinterop.* fun main(args: Array) { println(atoi("257")) val divResult = div(-5, 3) val (quot, rem) = divResult.useContents { Pair(quot, rem) } println(quot) println(rem) } ================================================ FILE: backend.native/tests/interop/basics/2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import cstdio.* fun main(args: Array) { puts("Hello") } ================================================ FILE: backend.native/tests/interop/basics/3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* fun main(args: Array) { val values = intArrayOf(14, 12, 9, 13, 8) val count = values.size cstdlib.qsort(values.refTo(0), count.convert(), IntVar.size.convert(), staticCFunction { a, b -> val aValue = a!!.reinterpret()[0] val bValue = b!!.reinterpret()[0] (aValue - bValue) }) for (i in 0..count - 1) { print(values[i]) print(" ") } println() } ================================================ FILE: backend.native/tests/interop/basics/4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import cstdio.* import kotlinx.cinterop.* val stdout get() = getStdout() fun main(args: Array) { fprintf(stdout, "%s %s %d %d %d %lld %.1f %.1lf %d %d\n", "a", "b".cstr, (-1).toByte(), 2.toShort(), 3, Long.MAX_VALUE, 0.1.toFloat(), 0.2, true, false) memScoped { val aVar = alloc() val bVar = alloc() val sscanfResult = sscanf("42", "%d%d", aVar.ptr, bVar.ptr) printf("%d %d\n", sscanfResult, aVar.value) } } ================================================ FILE: backend.native/tests/interop/basics/5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import platform.posix.printf val golden = immutableBlobOf(0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21, 0x00).asCPointer(0) fun main(args: Array) { printf("%s\n", golden) } ================================================ FILE: backend.native/tests/interop/basics/arrayPointers.kt ================================================ import carrayPointers.* import kotlin.test.* import kotlinx.cinterop.* fun main() { arrayPointer = globalArray assertEquals(globalArray[0], arrayPointer!![0]) arrayPointer!![0] = 15 assertEquals(15, globalArray[0]) memScoped { val struct = alloc() struct.arrayPointer = globalArray assertEquals(globalArray[0], struct.arrayPointer!![0]) } } ================================================ FILE: backend.native/tests/interop/basics/bf.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import bitfields.* import kotlinx.cinterop.* fun assertEquals(value1: Any?, value2: Any?) { if (value1 != value2) throw AssertionError("Expected $value1, got $value2") } fun check(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean) { assertEquals(x1, s.x1) assertEquals(x1, getX1(s.ptr)) assertEquals(x2, s.x2) assertEquals(x2, getX2(s.ptr)) assertEquals(x3, s.x3) assertEquals(x3, getX3(s.ptr)) assertEquals(x4, s.x4) assertEquals(x4, getX4(s.ptr)) assertEquals(x5, s.x5) assertEquals(x5, getX5(s.ptr)) assertEquals(x6, s.x6) assertEquals(x6, getX6(s.ptr)) assertEquals(x7, s.x7) assertEquals(x7, getX7(s.ptr)) assertEquals(x8, s.x8) assertEquals(x8, getX8(s.ptr)) } fun assign(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean) { s.x1 = x1 s.x2 = x2 s.x3 = x3 s.x4 = x4 s.x5 = x5 s.x6 = x6 s.x7 = x7 s.x8 = x8 } fun assignReversed(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean) { s.x8 = x8 s.x7 = x7 s.x6 = x6 s.x5 = x5 s.x4 = x4 s.x3 = x3 s.x2 = x2 s.x1 = x1 } fun test(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean) { assign(s, x1, x2, x3, x4, x5, x6, x7, x8) check(s, x1, x2, x3, x4, x5, x6, x7, x8) assignReversed(s, x1, x2, x3, x4, x5, x6, x7, x8) check(s, x1, x2, x3, x4, x5, x6, x7, x8) // Also check with some insignificant bits modified: assign(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8) check(s, x1, x2, x3, x4, x5, x6, x7, x8) assignReversed(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8) check(s, x1, x2, x3, x4, x5, x6, x7, x8) } fun main(args: Array) { memScoped { val s = alloc() for (x1 in -1L..0L) for (x2 in B2.values()) for (x3 in 0..7) for (x4 in uintArrayOf(0u, 6u, 15u)) for (x5 in intArrayOf(-16, -2, -1, 0, 5, 15)) for (x6 in longArrayOf(Long.MIN_VALUE/2, -1L shl 36, -325L, 0, 1L shl 48, Long.MAX_VALUE/2)) for (x7 in E.values()) for (x8 in arrayOf(false, true)) test(s, x1, x2, x3.toUShort(), x4, x5, x6, x7, x8) } } ================================================ FILE: backend.native/tests/interop/basics/bitfields.def ================================================ --- enum B2 { ZERO, ONE, TWO, THREE }; enum E : short { A, B }; struct __attribute__((packed)) S { long long x1 : 1; enum B2 x2 : 2; unsigned short x3 : 3; unsigned int x4 : 4; int x5 : 5; long long x6 : 63; enum E x7: 2; _Bool x8 : 1; }; static long long getX1(struct S* s) { return s->x1; } static enum B2 getX2(struct S* s) { return s->x2; } static unsigned short getX3(struct S* s) { return s->x3; } static unsigned int getX4(struct S* s) { return s->x4; } static int getX5(struct S* s) { return s->x5; } static long long getX6(struct S* s) { return s->x6; } static enum E getX7(struct S* s) { return s->x7; } static _Bool getX8(struct S* s) { return s->x8; } ================================================ FILE: backend.native/tests/interop/basics/callbacksAndVarargs.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlinx.cinterop.* import ccallbacksAndVarargs.* fun main() { testStructCallbacks() testVarargs() testCallableReferences() } fun testStructCallbacks() { assertEquals(42, getX(staticCFunction { -> cValue { x = 42 } })) applyCallback(cValue { x = 17 }, staticCFunction { it: CValue -> assertEquals(17, it.useContents { x }) }) assertEquals(66, makeS(66, 111).useContents { x }) } fun testVarargs() { assertEquals(E.ONE, makeE(1)) getVarargs( 0, true, 2.toByte(), Short.MIN_VALUE, 42, Long.MAX_VALUE, 3.14f, 2.71, 0x1234ABCDL.toCPointer(), UByte.MAX_VALUE, 22.toUShort(), 111u, ULong.MAX_VALUE, E.TWO, cValue { x = 15 }, null ).useContents { assertEquals(1, a1) assertEquals(2.toByte(), a2) assertEquals(Short.MIN_VALUE, a3) assertEquals(42, a4) assertEquals(Long.MAX_VALUE, a5) assertEquals(3.14f, a6) assertEquals(2.71, a7) assertEquals(0x1234ABCDL, a8.toLong()) assertEquals(UByte.MAX_VALUE, a9) assertEquals(22.toUShort(), a10) assertEquals(111u, a11) assertEquals(ULong.MAX_VALUE, a12) assertEquals(E.TWO, a13) assertEquals(15, a14.x) assertEquals(null, a15) } } fun testCallableReferences() { val sumRef = ::sum assertEquals(3, sumRef(1, 2)) val sumPtr = staticCFunction(::sum) assertEquals(7, sumPtr(3, 4)) } ================================================ FILE: backend.native/tests/interop/basics/carrayPointers.def ================================================ --- int (*arrayPointer)[1]; int globalArray[3] = {1, 2, 3}; struct StructWithArrayPtr { int (*arrayPointer)[1]; }; ================================================ FILE: backend.native/tests/interop/basics/ccallbacksAndVarargs.def ================================================ --- #include struct S { int x; }; static int getX(struct S (*callback)(void)) { return callback().x; } static void applyCallback(struct S s, void (*callback)(struct S)) { callback(s); } static struct S makeS(int x, ...) { return (struct S){ x }; } enum E { ZERO, ONE, TWO }; static enum E makeE(int ordinal, ...) { return ordinal; } struct Args { char a1; char a2; short a3; int a4; long long a5; float a6; double a7; void* a8; unsigned char a9; unsigned short a10; unsigned int a11; unsigned long long a12; enum E a13; struct S a14; void* a15; }; static struct Args getVarargs(int ignore, ...) { va_list args; va_start(args, ignore); struct Args result = { va_arg(args, char), va_arg(args, char), va_arg(args, short), va_arg(args, int), va_arg(args, long long), va_arg(args, double), va_arg(args, double), va_arg(args, void*), va_arg(args, unsigned char), va_arg(args, unsigned short), va_arg(args, unsigned int), va_arg(args, unsigned long long), va_arg(args, enum E), va_arg(args, struct S), va_arg(args, void*) }; va_end(args); return result; } static int sum(int first, int second) { return first + second; } ================================================ FILE: backend.native/tests/interop/basics/cenums.def ================================================ --- enum E { A, B, C }; ================================================ FILE: backend.native/tests/interop/basics/cfunptr.def ================================================ headerFilter = NOTHING --- #include #include typedef int (*atoiPtrType)(const char*); static atoiPtrType getAtoiPtr() { return &atoi; } static void __printInt(int x) { printf("%d\n", x); } static void* __getPrintIntPtr() { return &__printInt; } typedef void* (*getPrintIntPtrPtrType)(void); static getPrintIntPtrPtrType getGetPrintIntPtrPtr() { return &__getPrintIntPtr; } static double __add(double x, double y) { return x + y; } typedef double (*addPtrType)(double, double); static addPtrType getAddPtr() { return &__add; } static int __doubleToInt(double x) { return (int) x; } typedef int (*doubleToIntPtrType)(double); static doubleToIntPtrType getDoubleToIntPtr() { return &__doubleToInt; } static _Bool __isIntPositive(int x) { return x > 0; } typedef _Bool (*isIntPositivePtrType)(int); static isIntPositivePtrType getIsIntPositivePtr() { return &__isIntPositive; } static unsigned int getMaxUInt(void) { return 0xffffffff; } static typeof(&getMaxUInt) getMaxUIntGetter() { return &getMaxUInt; } typedef int (*longSignatureFunctionPtrType)( int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int ); typedef int (*notSoLongSignatureFunctionPtrType)( int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int ); static int longSignatureFunction( int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12, int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22, int p23 ) { return 42; } static int notSoLongSignatureFunction( int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12, int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22 ) { return 42; } static longSignatureFunctionPtrType getLongSignatureFunctionPtr() { return &longSignatureFunction; } static notSoLongSignatureFunctionPtrType getNotSoLongSignatureFunctionPtr() { return ¬SoLongSignatureFunction; } ================================================ FILE: backend.native/tests/interop/basics/cglobals.def ================================================ --- const int g1 = 42; int g2 = 17; struct S { int x; } g3 = { 128 }; int g4[2] = { 13, 14 }; int g5[2][2] = { 15, 16, 17, 18 }; struct S* const g6 = &g3; void foo() { // Test that local vars are not treated as global ones. float g1; } // Test non-compilable variable: typedef int MyInt; MyInt g7; #define g7 bad macro // Test property name mangling: struct g1 {}; struct g1_ {}; typedef void* voidptr; _Pragma("clang assume_nonnull begin") const voidptr g8 = 0x1, g9 = 0x2; _Pragma("clang assume_nonnull end") ================================================ FILE: backend.native/tests/interop/basics/cmacros.def ================================================ excludedMacros = EXCLUDED --- int* ptr_call() { return (int*) 1; } int int_call() { return 42; } void void_call() {} int arg_call(int x) { return x; } typedef struct { int value } struct_t; struct_t getStruct() { return (struct_t){ 1 }; } int global_var = 5; #define TOO_MANY_ERRORS x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x #define LEFT_BRACE { #define ZERO 0 #define ONE 1 #define RIGHT_BRACE } #define MAX_LONG 9223372036854775807 #define FOO_STRING "foo" // This one should be ignored: #define WIDE_FOO_STRING L"foo" #define FOURTY_TWO 42 #define SEVENTEEN ((long long) 17) #define ONE_POINT_ZERO 1.0 #define ONE_POINT_FIVE 1.5f #define LEFT_PAREN ( #define NULL_PTR ((void*)0) #define VOID_PTR ((void*)1) #define INT_PTR ((int*)1) #define PTR_SUM (INT_PTR + 1) #define PTR_SUM_EXPECTED (sizeof(int) + 1) #define RIGHT_PAREN ) enum { INT_CALL = 1 // Should be replaced by macro below. }; #define PTR_CALL ptr_call() #define INT_CALL int_call() #define CALL_SUM (int_call() + int_call()) #define GLOBAL_VAR (global_var) // This one should be excluded: #define EXCLUDED 42 // These ones should be ignored: #define VOID_CALL (void_call()) #define ARG_CALL(x) (arg_call(x)) #define GET_STRUCT (getStruct()) #define UNDECLARED (undeclared()) #define BAD1 bar #define BAD2 5; #define BAD3 { foo(); } void increment(int* counter); #define increment(counter) { (*(counter))++; } ================================================ FILE: backend.native/tests/interop/basics/cstdio.def ================================================ headers = stdio.h compilerOpts.osx = -D_ANSI_SOURCE --- static inline FILE* getStdout() { return stdout; } ================================================ FILE: backend.native/tests/interop/basics/cstructs.def ================================================ nonStrictEnums = NonStrict --- typedef struct { int i; } Trivial; enum E { R, G, B }; enum NonStrict { N, S, K }; struct Complex { unsigned int ui; Trivial t; struct Complex* next; enum E e; enum NonStrict nonStrict; int arr[2]; _Bool b; }; struct __attribute__((packed)) Packed { int i : 1; enum E e : 2; }; struct Complex produceComplex() { struct Complex complex = { .ui = 128, .t = {1}, .next = 0, .e = R, .nonStrict = K, .arr = {-51, -19}, .b = 1 }; return complex; }; ================================================ FILE: backend.native/tests/interop/basics/ctoKString.def ================================================ --- const char* empty() { return ""; } const char* foo() { return "foo"; } const char* kuku() { return "куку"; } const char* invalid_utf8() { return "\x85\xAF"; } const char* zero_in_the_middle() { return "before zero\0after zero"; } ================================================ FILE: backend.native/tests/interop/basics/ctypes.def ================================================ --- // KT-28065 struct StructWithConstFields { int x; const int y; }; struct StructWithConstFields getStructWithConstFields() { struct StructWithConstFields result = { 111, 222 }; return result; } enum ForwardDeclaredEnum; enum ForwardDeclaredEnum { ZERO, ONE, TWO }; static int vlaSum(int size, int array[size]) { int result = 0; for (int i = 0; i < size; ++i) { result += array[i]; } return result; } static int vlaSum2D(int size, int array[][size]) { int result = 0; for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { result += array[i][j]; } } return result; } static int vlaSum2DBothDimensions(int rows, int columns, int array[rows][columns]) { int result = 0; for (int i = 0; i < rows; ++i) { for (int j = 0; j < columns; ++j) { result += array[i][j]; } } return result; } /* // Not supported by clang: static int vlaSum2DForward(int size; int array[][size], int size) { return vlaSum2D(size, array); } */ // "Strict" enums heuristic based on whether enum constants are defined explicitly: enum StrictEnum1 { StrictEnum1A, StrictEnum1B }; enum StrictEnum2 { StrictEnum2A __attribute__((unused)), StrictEnum2B __attribute__((unused)) }; enum NonStrictEnum1 { NonStrictEnum1A = 0, NonStrictEnum1B __attribute__((unused)) }; enum NonStrictEnum2 { NonStrictEnum2A, NonStrictEnum2B __attribute__((unused)) = 1 }; // KT-34025 typedef char Char; enum EnumCharBase : Char { EnumCharBaseA, EnumCharBaseB }; static int sendEnum(enum EnumCharBase x) { return (int)x + 2; } enum EnumExplicitChar : char { EnumExplicitCharA = 'a', EnumExplicitCharB = 'b', EnumExplicitCharDup = 'a' }; ================================================ FILE: backend.native/tests/interop/basics/cunion.def ================================================ --- typedef union { short s; long long ll; } BasicUnion; typedef struct { union { int i; float f; } as; } StructWithUnion; typedef union { unsigned int i : 31; unsigned char b : 1; } Packed; ================================================ FILE: backend.native/tests/interop/basics/cunsupported.def ================================================ compilerOpts = -mno-xsave --- static void noAttr() {} __attribute__((always_inline)) noTargetAttr() {} __attribute__((always_inline, __target__("xsave"))) void plainAttrs1() {} __attribute__((__target__("xsave"), always_inline)) void plainAttrs2() {} #define TARGET __target__ __attribute__((always_inline, TARGET("xsave"))) void macroAttr1() {} __attribute__((TARGET("xsave"), always_inline)) void macroAttr2() {} #define TARGET_ATTR __target__("xsave") __attribute__((TARGET_ATTR, always_inline)) void macroAttr3() {} __attribute__((always_inline, TARGET_ATTR)) void macroAttr4() {} #define ALL_ATTRS1 __attribute__((always_inline, __target__("xsave"))) ALL_ATTRS1 void macroAttr5() {} #define ALL_ATTRS2 __attribute__((always_inline, __target__("xsave"))) ALL_ATTRS2 void macroAttr6() {} ================================================ FILE: backend.native/tests/interop/basics/custom headers/custom.h ================================================ #include #include #include int custom_strcmp(const char* str1, const char* str2) { return strcmp(str1, str2); } ================================================ FILE: backend.native/tests/interop/basics/cvalues.def ================================================ --- _Bool isNullString(const char* str) { return str == (const char*)0; } typedef const short* LPCWSTR; _Bool isNullWString(LPCWSTR str) { return str == (LPCWSTR)0; } ================================================ FILE: backend.native/tests/interop/basics/cvectors.def ================================================ --- typedef float __attribute__ ((__vector_size__ (16))) KVector4f; typedef int __attribute__ ((__vector_size__ (16))) KVector4i32; struct Complex { unsigned int ui; KVector4f vec4f; struct Complex* next; int arr[2]; }; struct Complex produceComplex() { struct Complex complex = { .ui = 128, .vec4f = {1.0, 1.0, 1.0, 1.0}, .next = 0, .arr = {-51, -19} }; return complex; }; static float sendV4F(KVector4f v) { return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3]; } static int sendV4I(KVector4i32 v) { return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3]; } ================================================ FILE: backend.native/tests/interop/basics/echo_server.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import sockets.* fun main(args: Array) { if (args.size < 1) { println("Usage: ./echo_server ") return } val port = atoi(args[0]).toUShort() memScoped { val bufferLength = 100L val buffer = allocArray(bufferLength) val serverAddr = alloc() val listenFd = socket(AF_INET, SOCK_STREAM, 0) .toInt().ensureUnixCallResult { it >= 0 } with(serverAddr) { memset(this.ptr, 0, sockaddr_in.size.convert()) sin_family = AF_INET.convert() sin_addr.s_addr = htons(0u).convert() sin_port = htons(port) } bind(listenFd, serverAddr.ptr.reinterpret(), sockaddr_in.size.toUInt()) .toInt().ensureUnixCallResult { it == 0 } listen(listenFd, 10) .toInt().ensureUnixCallResult { it == 0 } val commFd = accept(listenFd, null, null) .toInt().ensureUnixCallResult { it >= 0 } while (true) { val length = read(commFd, buffer, bufferLength.convert()) .toInt().ensureUnixCallResult { it >= 0 } if (length == 0) { break } write(commFd, buffer, length.convert()) .toInt().ensureUnixCallResult { it >= 0 } } } } // Not available through interop because declared as macro: fun htons(value: UShort) = ((value.toInt() ushr 8) or (value.toInt() shl 8)).toUShort() fun throwUnixError(): Nothing { perror(null) // TODO: store error message to exception instead. throw Error("UNIX call failed") } inline fun Int.ensureUnixCallResult(predicate: (Int) -> Boolean): Int { if (!predicate(this)) { throwUnixError() } return this } ================================================ FILE: backend.native/tests/interop/basics/enums.kt ================================================ import cenums.* import kotlinx.cinterop.* import kotlin.test.* fun main() { memScoped { val e = alloc() e.value = E.C assertEquals(E.C, e.value) assertFailsWith { e.value = TODO() } } } ================================================ FILE: backend.native/tests/interop/basics/funptr.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import cfunptr.* import kotlin.test.* typealias NotSoLongSignatureFunction = ( Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int ) -> Int fun main(args: Array) { val atoiPtr = getAtoiPtr()!! val getPrintIntPtrPtr = getGetPrintIntPtrPtr()!! val printIntPtr = getPrintIntPtrPtr()!!.reinterpret Unit>>() val fortyTwo = memScoped { atoiPtr("42".cstr.getPointer(memScope)) } printIntPtr(fortyTwo) printIntPtr( getDoubleToIntPtr()!!( getAddPtr()!!(5.1, 12.2) ) ) val isIntPositivePtr = getIsIntPositivePtr()!! printIntPtr(isIntPositivePtr(42).ifThenOneElseZero()) printIntPtr(isIntPositivePtr(-42).ifThenOneElseZero()) assertEquals(getMaxUIntGetter()!!(), UInt.MAX_VALUE) val longSignaturePtr: COpaquePointer? = getLongSignatureFunctionPtr() val notSoLongSignaturePtr: CPointer>? = getNotSoLongSignatureFunctionPtr() printIntPtr(notSoLongSignaturePtr!!.invoke(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) printIntPtr(notSoLongSignatureFunction(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) } fun Boolean.ifThenOneElseZero() = if (this) 1 else 0 ================================================ FILE: backend.native/tests/interop/basics/globals.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import cglobals.* fun main(args: Array) { assert(g1__ == 42) assert(g2 == 17) g2 = 42 assert(g2 == 42) assert(g3.x == 128) g3.x = 7 assert(g3.x == 7) assert(g4[1] == 14) g4[1] = 15 assert(g4[1] == 15) assert(g5[0] == 15) assert(g5[3] == 18) g5[0] = 16 assert(g5[0] == 16) assert(g6 == g3.ptr) assert(g8.toLong() == 0x1L) assert(g9.toLong() == 0x2L) } ================================================ FILE: backend.native/tests/interop/basics/macros.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import cmacros.* import kotlinx.cinterop.* fun main(args: Array) { assertEquals("foo", FOO_STRING) assertEquals(0, ZERO) assertEquals(1, ONE) assertEquals(Long.MAX_VALUE, MAX_LONG) assertEquals(42, FOURTY_TWO) val seventeen: Long = SEVENTEEN assertEquals(17L, seventeen) val onePointFive: Float = ONE_POINT_FIVE val onePointZero: Double = ONE_POINT_ZERO assertEquals(1.5f, onePointFive) assertEquals(1.0, onePointZero) val nullPtr: COpaquePointer? = NULL_PTR val voidPtr: COpaquePointer? = VOID_PTR val intPtr: CPointer? = INT_PTR val ptrSum: CPointer? = PTR_SUM val ptrCall: CPointer? = PTR_CALL assertEquals(null, nullPtr) assertEquals(1L, voidPtr.rawValue.toLong()) assertEquals(1L, intPtr.rawValue.toLong()) assertEquals(PTR_SUM_EXPECTED.toLong(), ptrSum.rawValue.toLong()) assertEquals(1L, ptrCall.rawValue.toLong()) assertEquals(42, INT_CALL) assertEquals(84, CALL_SUM) assertEquals(5, GLOBAL_VAR) memScoped { val counter = alloc() counter.value = 42 increment(counter.ptr) assertEquals(43, counter.value) } } ================================================ FILE: backend.native/tests/interop/basics/mangling.def ================================================ --- // test mangling of special names enum _Companion {Companion, Any}; enum _Companion companion = Companion; ================================================ FILE: backend.native/tests/interop/basics/mangling.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import mangling.* fun main() { companion = _Companion.`Companion$` assertEquals(_Companion.`Companion$`, companion) } ================================================ FILE: backend.native/tests/interop/basics/mangling2.def ================================================ --- // test mangling of special names enum Companion {One, Two}; ================================================ FILE: backend.native/tests/interop/basics/mangling2.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import mangling2.* fun main() { val mangled = `Companion$`.Two assertEquals(`Companion$`.Two, mangled) } ================================================ FILE: backend.native/tests/interop/basics/mangling_keywords.def ================================================ --- #define as "as" #define class "class" #define dynamic "dynamic" #define false "false" #define fun "fun" #define in "in" #define interface "interface" #define is "is" #define null "null" #define object "object" #define package "package" #define super "super" #define this "this" #define throw "throw" #define true "true" #define try "try" #define typealias "typealias" #define val "val" #define var "var" #define when "when" ================================================ FILE: backend.native/tests/interop/basics/mangling_keywords.kt ================================================ import kotlin.test.* import mangling_keywords.* fun main() { // Check that all Kotlin keywords are imported and mangled. assertEquals("as", `as`) assertEquals("class", `class`) assertEquals("dynamic", `dynamic`) assertEquals("false", `false`) assertEquals("fun", `fun`) assertEquals("in", `in`) assertEquals("interface", `interface`) assertEquals("is", `is`) assertEquals("null", `null`) assertEquals("object", `object`) assertEquals("package", `package`) assertEquals("super", `super`) assertEquals("this", `this`) assertEquals("throw", `throw`) assertEquals("true", `true`) assertEquals("try", `try`) assertEquals("typealias", `typealias`) assertEquals("val", `val`) assertEquals("var", `var`) assertEquals("when", `when`) } ================================================ FILE: backend.native/tests/interop/basics/mangling_keywords2.def ================================================ --- enum KotlinKeywordsEnum { as, class, dynamic, false, fun, in, interface, is, null, object, package, super, this, throw, true, try, typealias, val, var, when, }; struct KotlinKeywordsStruct { int as; int class; int dynamic; int false; int fun; int in; int interface; int is; int null; int object; int package; int super; int this; int throw; int true; int try; int typealias; int val; int var; int when; }; struct KotlinKeywordsStruct createKotlinKeywordsStruct() { struct KotlinKeywordsStruct s = { .as = 0, .class = 0, .dynamic = 0, .false = 0, .fun = 0, .in = 0, .interface = 0, .is = 0, .null = 0, .object = 0, .package = 0, .super = 0, .this = 0, .throw = 0, .true = 0, .try = 0, .typealias = 0, .val = 0, .var = 0, .when = 0, }; return s; } ================================================ FILE: backend.native/tests/interop/basics/mangling_keywords2.kt ================================================ import kotlin.test.* import mangling_keywords2.* import kotlinx.cinterop.useContents fun main() { // Check that all Kotlin keywords are imported and mangled. createKotlinKeywordsStruct().useContents { assertEquals(0, `as`) assertEquals(0, `class`) assertEquals(0, `dynamic`) assertEquals(0, `false`) assertEquals(0, `fun`) assertEquals(0, `in`) assertEquals(0, `interface`) assertEquals(0, `is`) assertEquals(0, `null`) assertEquals(0, `object`) assertEquals(0, `package`) assertEquals(0, `super`) assertEquals(0, `this`) assertEquals(0, `throw`) assertEquals(0, `true`) assertEquals(0, `try`) assertEquals(0, `typealias`) assertEquals(0, `val`) assertEquals(0, `var`) assertEquals(0, `when`) } assertEquals(KotlinKeywordsEnum.`as`, KotlinKeywordsEnum.`as`) assertEquals(KotlinKeywordsEnum.`class`, KotlinKeywordsEnum.`class`) assertEquals(KotlinKeywordsEnum.`dynamic`, KotlinKeywordsEnum.`dynamic`) assertEquals(KotlinKeywordsEnum.`false`, KotlinKeywordsEnum.`false`) assertEquals(KotlinKeywordsEnum.`fun`, KotlinKeywordsEnum.`fun`) assertEquals(KotlinKeywordsEnum.`in`, KotlinKeywordsEnum.`in`) assertEquals(KotlinKeywordsEnum.`interface`, KotlinKeywordsEnum.`interface`) assertEquals(KotlinKeywordsEnum.`is`, KotlinKeywordsEnum.`is`) assertEquals(KotlinKeywordsEnum.`null`, KotlinKeywordsEnum.`null`) assertEquals(KotlinKeywordsEnum.`object`, KotlinKeywordsEnum.`object`) assertEquals(KotlinKeywordsEnum.`package`, KotlinKeywordsEnum.`package`) assertEquals(KotlinKeywordsEnum.`super`, KotlinKeywordsEnum.`super`) assertEquals(KotlinKeywordsEnum.`this`, KotlinKeywordsEnum.`this`) assertEquals(KotlinKeywordsEnum.`throw`, KotlinKeywordsEnum.`throw`) assertEquals(KotlinKeywordsEnum.`true`, KotlinKeywordsEnum.`true`) assertEquals(KotlinKeywordsEnum.`try`, KotlinKeywordsEnum.`try`) assertEquals(KotlinKeywordsEnum.`typealias`, KotlinKeywordsEnum.`typealias`) assertEquals(KotlinKeywordsEnum.`val`, KotlinKeywordsEnum.`val`) assertEquals(KotlinKeywordsEnum.`var`, KotlinKeywordsEnum.`var`) assertEquals(KotlinKeywordsEnum.`when`, KotlinKeywordsEnum.`when`) } ================================================ FILE: backend.native/tests/interop/basics/opengl_teapot.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import platform.GLUT.* import platform.OpenGL.* import platform.OpenGLCommon.* // Ported from http://openglsamples.sourceforge.net/projects/index.php/blog/index/ private var rotation: GLfloat = 0.0f private val rotationSpeed: GLfloat = 0.2f private val windowWidth = 640 private val windowHeight = 480 fun display() { // Clear Screen and Depth Buffer glClear((GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT).convert()) glLoadIdentity() // Define a viewing transformation gluLookAt(4.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) // Push and pop the current matrix stack. // This causes that translations and rotations on this matrix wont influence others. glPushMatrix() glColor3f(1.0f, 0.0f, 0.0f) glTranslatef(0.0f, 0.0f, 0.0f) glRotatef(rotation, 0.0f, 1.0f, 0.0f) glRotatef(90.0f, 0.0f, 1.0f, 0.0f) // Draw the teapot glutSolidTeapot(1.0) glPopMatrix() rotation += rotationSpeed glutSwapBuffers() } fun initialize() { // select projection matrix glMatrixMode(GL_PROJECTION) // set the viewport glViewport(0, 0, windowWidth, windowHeight) // set matrix mode glMatrixMode(GL_PROJECTION) // reset projection matrix glLoadIdentity() val aspect = windowWidth.toDouble() / windowHeight // set up a perspective projection matrix gluPerspective(45.0, aspect, 1.0, 500.0) // specify which matrix is the current matrix glMatrixMode(GL_MODELVIEW) glShadeModel(GL_SMOOTH) // specify the clear value for the depth buffer glClearDepth(1.0) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) // specify implementation-specific hints glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glLightModelfv(GL_LIGHT_MODEL_AMBIENT, cValuesOf(0.1f, 0.1f, 0.1f, 1.0f)) glLightfv(GL_LIGHT0, GL_DIFFUSE, cValuesOf(0.6f, 0.6f, 0.6f, 1.0f)) glLightfv(GL_LIGHT0, GL_SPECULAR, cValuesOf(0.7f, 0.7f, 0.3f, 1.0f)) glEnable(GL_LIGHT0) glEnable(GL_COLOR_MATERIAL) glShadeModel(GL_SMOOTH) glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE) glDepthFunc(GL_LEQUAL) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glClearColor(0.0f, 0.0f, 0.0f, 1.0f) } fun main(args: Array) { // initialize and run program memScoped { val argc = alloc().apply { value = 0 } glutInit(argc.ptr, null) // TODO: pass real args } // Display Mode glutInitDisplayMode((GLUT_RGB or GLUT_DOUBLE or GLUT_DEPTH).convert()) // Set window size glutInitWindowSize(windowWidth, windowHeight) // create Window glutCreateWindow("The GLUT Teapot") // register Display Function glutDisplayFunc(staticCFunction(::display)) // register Idle Function glutIdleFunc(staticCFunction(::display)) initialize() // run GLUT mainloop glutMainLoop() } ================================================ FILE: backend.native/tests/interop/basics/pinning.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlinx.cinterop.* @Test fun pinnedByteArrayAddressOf() { val arr = ByteArray(10) { 0 } arr.usePinned { assertEquals(0, it.addressOf(0).pointed.value) assertEquals(0, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedStringAddressOf() { val str = "0000000000" str.usePinned { it.addressOf(0) it.addressOf(9) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedCharArrayAddressOf() { val arr = CharArray(10) { '0' } arr.usePinned { it.addressOf(0) it.addressOf(9) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedShortArrayAddressOf() { val arr = ShortArray(10) { 0 } arr.usePinned { assertEquals(0, it.addressOf(0).pointed.value) assertEquals(0, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedIntArrayAddressOf() { val arr = IntArray(10) { 0 } arr.usePinned { assertEquals(0, it.addressOf(0).pointed.value) assertEquals(0, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedLongArrayAddressOf() { val arr = LongArray(10) { 0 } arr.usePinned { assertEquals(0, it.addressOf(0).pointed.value) assertEquals(0, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedUByteArrayAddressOf() { val arr = UByteArray(10) { 0U } arr.usePinned { assertEquals(0U, it.addressOf(0).pointed.value) assertEquals(0U, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedUShortArrayAddressOf() { val arr = UShortArray(10) { 0U } arr.usePinned { assertEquals(0U, it.addressOf(0).pointed.value) assertEquals(0U, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedUIntArrayAddressOf() { val arr = UIntArray(10) { 0U } arr.usePinned { assertEquals(0U, it.addressOf(0).pointed.value) assertEquals(0U, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedULongArrayAddressOf() { val arr = ULongArray(10) { 0U } arr.usePinned { assertEquals(0U, it.addressOf(0).pointed.value) assertEquals(0U, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedFloatArrayAddressOf() { val arr = FloatArray(10) { 0.0f } arr.usePinned { assertEquals(0.0f, it.addressOf(0).pointed.value) assertEquals(0.0f, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } @Test fun pinnedDoubleArrayAddressOf() { val arr = DoubleArray(10) { 0.0 } arr.usePinned { assertEquals(0.0, it.addressOf(0).pointed.value) assertEquals(0.0, it.addressOf(9).pointed.value) assertFailsWith { it.addressOf(10) } assertFailsWith { it.addressOf(-1) } assertFailsWith { it.addressOf(Int.MAX_VALUE) } assertFailsWith { it.addressOf(Int.MIN_VALUE) } } } ================================================ FILE: backend.native/tests/interop/basics/sockets.def ================================================ headers = sys/socket.h sys/errno.h netdb.h stdio.h string.h unistd.h stdlib.h netinet/in.h compilerOpts.osx = -D_ANSI_SOURCE -D_POSIX_SOURCE excludeFunctions.osx = addrsel_policy_init --- static int interop_errno() { return errno; } static short interop_htons(short x) { return htons(x); } ================================================ FILE: backend.native/tests/interop/basics/structs.kt ================================================ import cstructs.* import kotlinx.cinterop.* import kotlin.test.* fun main() { produceComplex().useContents { assertEquals(ui, 128u) ui = 333u assertEquals(ui, 333u) assertEquals(t.i, 1) t.i += 15 assertEquals(t.i, 16) assertEquals(next, null) next = this.ptr assertEquals(next, this.ptr) // Check null pointer because it has Nothing? type. next = null assertEquals(next, null) assertEquals(e, E.R) e = E.G assertEquals(e, E.G) assertEquals(K, nonStrict) nonStrict = S assertEquals(S, nonStrict) assertEquals(arr[0], -51) assertEquals(arr[1], -19) arr[0] = 51 arr[1] = 19 assertEquals(arr[0], 51) assertEquals(arr[1], 19) assertEquals(true, b) b = false assertEquals(false, b) // Check that subtyping via Nothing-returning functions does not break compiler. assertFailsWith { ui = TODO() t.i = TODO() next = TODO() e = TODO() nonStrict = TODO() b = TODO() } } memScoped { val packed = alloc() packed.i = -1 assertEquals(-1, packed.i) packed.e = E.R assertEquals(E.R, packed.e) // Check that subtyping via Nothing-returning functions does not break compiler. assertFailsWith { packed.i = TODO() packed.e = TODO() } } // Check that generics doesn't break anything. checkEnumSubTyping(E.R) checkIntSubTyping(630090) } fun checkEnumSubTyping(e: T) = memScoped { val s = alloc() s.e = e } fun checkIntSubTyping(x: T) = memScoped { val s = alloc() s.i = x } ================================================ FILE: backend.native/tests/interop/basics/toKString.kt ================================================ import ctoKString.* import kotlinx.cinterop.* import kotlin.native.* import kotlin.test.* fun main() { assertEquals("", empty()!!.toKStringFromUtf8()) assertEquals("foo", foo()!!.toKStringFromUtf8()) assertEquals("куку", kuku()!!.toKStringFromUtf8()) assertEquals("\uFFFD\uFFFD", invalid_utf8()!!.toKStringFromUtf8()) assertEquals("before zero", zero_in_the_middle()!!.toKStringFromUtf8()) } ================================================ FILE: backend.native/tests/interop/basics/typedefs.def ================================================ --- typedef int my_int; ================================================ FILE: backend.native/tests/interop/basics/types.kt ================================================ import kotlinx.cinterop.* import kotlin.native.* import kotlin.test.* import ctypes.* fun main() { getStructWithConstFields().useContents { assertEquals(111, x) assertEquals(222, y) } assertEquals(1u, ForwardDeclaredEnum.ONE.value) assertEquals(6, vlaSum(3, cValuesOf(1, 2, 3))) assertEquals(10, vlaSum2D(2, cValuesOf(1, 2, 3, 4))) assertEquals(21, vlaSum2DBothDimensions(2, 3, cValuesOf(1, 2, 3, 4, 5, 6))) // Not supported by clang: // assertEquals(10, vlaSum2DForward(cValuesOf(1, 2, 3, 4), 2)) assertEquals(0u, StrictEnum1.StrictEnum1A.value) assertEquals(1u, StrictEnum2.StrictEnum2B.value) assertEquals(0u, NonStrictEnum1A) assertEquals(1u, NonStrictEnum2B) assertEquals(1, EnumCharBase.EnumCharBaseB.value) assertEquals(3, sendEnum(EnumCharBase.EnumCharBaseB)) assertEquals('a'.toByte(), EnumExplicitCharA) assertEquals('b'.toByte(), EnumExplicitCharB) assertEquals(EnumExplicitCharA, EnumExplicitCharDup) } ================================================ FILE: backend.native/tests/interop/basics/unable_to_import.def ================================================ --- int global; #define global bad macro void foo(void); #define foo < // Setter for x should not be generated. typedef const int cint; cint x; ================================================ FILE: backend.native/tests/interop/basics/union.kt ================================================ import cunion.* import kotlinx.cinterop.* import kotlin.native.* import kotlin.test.* fun main() { memScoped { val basicUnion = alloc() for (value in Short.MIN_VALUE..Short.MAX_VALUE) { basicUnion.ll = value.toLong() val expected = if (Platform.isLittleEndian) { value } else { value.toLong() ushr (Long.SIZE_BITS - Short.SIZE_BITS) } assertEquals(expected.toShort(), basicUnion.s) } } memScoped { val struct = alloc() struct.`as`.i = Float.NaN.toRawBits() assertEquals(Float.NaN, struct.`as`.f) } memScoped { val union = alloc() union.b = 1u var expected = if (Platform.isLittleEndian) { 1u } else { 1u shl (Int.SIZE_BITS - Byte.SIZE_BITS) } assertEquals(expected, union.i) union.i = 0u assertEquals(0u, union.b) } } ================================================ FILE: backend.native/tests/interop/basics/unsupported.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import cunsupported.* fun main(args: Array) { noAttr() noTargetAttr() } ================================================ FILE: backend.native/tests/interop/basics/values.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import cvalues.* fun main() { assertTrue(isNullString(null)) assertTrue(isNullWString(null)) assertFalse(isNullString("a")) assertFalse(isNullWString("b")) } ================================================ FILE: backend.native/tests/interop/basics/vectors.kt ================================================ import kotlinx.cinterop.* import kotlin.native.* import kotlin.test.* import cvectors.* fun isWin32() = Platform.osFamily == OsFamily.WINDOWS && Platform.cpuArchitecture == CpuArchitecture.X86 fun main(args: Array) { val mimalloc = args.takeIf { it.size == 1 }?.get(0) == "mimalloc" // See KT-37272. Fixed in mimalloc if (mimalloc || !isWin32()) { produceComplex().useContents { assertEquals(vec4f, vectorOf(1.0f, 1.0f, 1.0f, 1.0f)) vec4f = vectorOf(0.0f, 0.0f, 0.0f, 0.0f) assertEquals(vec4f, vectorOf(0.0f, 0.0f, 0.0f, 0.0f)) } } // FIXME: KT-36285 if (Platform.osFamily != OsFamily.LINUX || Platform.cpuArchitecture != CpuArchitecture.ARM32) { assertEquals(49, sendV4I(vectorOf(1, 2, 3, 4))) } assertEquals(49, (sendV4F(vectorOf(1f, 2f, 3f, 4f)) + 0.00001).toInt()) if (mimalloc || !isWin32()) { memScoped { val vector = alloc().also { it.value = vectorOf(1, 2, 3, 4) } assertEquals(vector.value, vectorOf(1, 2, 3, 4)) } } } ================================================ FILE: backend.native/tests/interop/basics/withSpaces.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlinx.cinterop.* import withSpaces.* fun main(args: Array) { customCompare("first", "second") } ================================================ FILE: backend.native/tests/interop/cleaners/cleaners.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.native.internal.* fun ensureInitialized() {} fun createCleaner() { createCleaner(42) { println(it) } } fun performGC() { GC.collect() performGCOnCleanerWorker() } private var globalCleaner: Cleaner? = null fun initializeGlobalCleaner() { globalCleaner = createCleaner(11) { println(it) } } ================================================ FILE: backend.native/tests/interop/cleaners/leak.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "testlib_api.h" int main() { testlib_symbols()->kotlin.root.initializeGlobalCleaner(); return 0; } ================================================ FILE: backend.native/tests/interop/cleaners/main_thread.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "testlib_api.h" int main() { testlib_symbols()->kotlin.root.createCleaner(); testlib_symbols()->kotlin.root.performGC(); return 0; } ================================================ FILE: backend.native/tests/interop/cleaners/second_thread.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "testlib_api.h" #include int main() { // Make sure runtime is initialized on the main thread, so that secondary thread death // doesn't destroy the entire runtime. testlib_symbols()->kotlin.root.ensureInitialized(); std::thread t([]() { testlib_symbols()->kotlin.root.createCleaner(); }); t.join(); testlib_symbols()->kotlin.root.performGC(); return 0; } ================================================ FILE: backend.native/tests/interop/concurrentTerminate/async.cpp ================================================ #include #include #include #include #include // signal.h #include "async.h" int test_ConcurrentTerminate() { signal(SIGABRT, *[](int){ exit(99); }); // Windows does not have sigaction std::vector> futures; #ifdef __linux__ // TODO: invalid terminate handler called from bridge on non-main thread on Linux X64 throw std::runtime_error("Reporting error!"); #endif for (size_t i = 0; i < 100; ++i) { futures.emplace_back(std::async(std::launch::async, [](size_t param) { std::this_thread::sleep_for(std::chrono::milliseconds(param)); throw std::runtime_error("Reporting error!"); }, 200 - i)); } for (auto &future : futures) future.get(); return 0; } ================================================ FILE: backend.native/tests/interop/concurrentTerminate/async.h ================================================ #ifdef __cplusplus extern "C" { #endif int test_ConcurrentTerminate(); #ifdef __cplusplus } #endif ================================================ FILE: backend.native/tests/interop/concurrentTerminate/concurrentTerminate.def ================================================ package async --- int test_ConcurrentTerminate(); ================================================ FILE: backend.native/tests/interop/concurrentTerminate/main.cpp ================================================ #include "testlib_api.h" #include #include #include #include #include #include // signal.h using namespace std; static int runConcurrent() { std::vector> futures; for (size_t i = 0; i < 100; ++i) { futures.emplace_back(std::async(std::launch::async, [](auto delay) { std::this_thread::sleep_for(std::chrono::milliseconds(delay)); testlib_symbols()->kotlin.root.testTerminate(); }, 100)); } for (auto &future : futures) future.get(); return 0; } int main() { signal(SIGABRT, *[](int){ exit(99); }); // Windows does not have sigaction set_terminate([](){ cout << "This is the original terminate handler\n" << flush; std::abort(); }); try { runConcurrent(); } catch(...) { std::cerr << "Unknown exception caught\n" << std::flush; } return 0; } ================================================ FILE: backend.native/tests/interop/concurrentTerminate/main.kt ================================================ import async.* import kotlinx.cinterop.* fun main() { test_ConcurrentTerminate() println("This is not expected.") } ================================================ FILE: backend.native/tests/interop/concurrentTerminate/reverseInterop.kt ================================================ import kotlin.system.exitProcess fun testTerminate() { throw RuntimeException("Example") } ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/1.c ================================================ int get1() { return 1; } ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/2.c ================================================ int get2() { return 2; } ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/3.c ================================================ int get3() { return 3; } ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/4.c ================================================ int get4() { return 4; } ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/embedStaticLibraries.def ================================================ libraryPaths = backend.native/tests/build/embedStaticLibraries staticLibraries = 3.a 4.a ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/embedStaticLibraries.h ================================================ int get1(void); int get2(void); int get3(void); int get4(void); ================================================ FILE: backend.native/tests/interop/embedStaticLibraries/main.kt ================================================ import kotlin.test.* import embedStaticLibraries.* fun main() { assertEquals(1, get1()) assertEquals(2, get2()) assertEquals(3, get3()) assertEquals(4, get4()) } ================================================ FILE: backend.native/tests/interop/incomplete_types/library.cpp ================================================ #include #include "library.h" extern "C" { struct S { std::string name; }; S s = { .name = "initial" }; void setContent(struct S* s, const char* name) { // Note that copy here is intentional: we use it as a workaround // for short lifetime of copy of the passed Kotlin string. s->name = name; } const char* getContent(struct S* s) { return s->name.c_str(); } union U { float f; double d; }; void setDouble(union U* u, double value) { u->d = value; } double getDouble(union U* u) { return u->d; } union U u = { .d = 0.0 }; char array[5] = { 0, 0, 0, 0, 0 }; void setArrayValue(char* array, char value) { for (int i = 0; i < 5; ++i) { array[i] = value; } } int arrayLength() { return sizeof(array) / sizeof(char); } } ================================================ FILE: backend.native/tests/interop/incomplete_types/library.def ================================================ ================================================ FILE: backend.native/tests/interop/incomplete_types/library.h ================================================ #ifdef __cplusplus extern "C" { #endif // Forward declaration. struct S; extern struct S s; const char* getContent(struct S* s); void setContent(struct S* s, const char* name); union U; extern union U u; double getDouble(union U* u); void setDouble(union U* u, double value); // Global array of unknown size. extern char array[]; int arrayLength(); void setArrayValue(char* array, char value); #ifdef __cplusplus } #endif ================================================ FILE: backend.native/tests/interop/incomplete_types/main.kt ================================================ import library.* import kotlinx.cinterop.* import kotlin.test.* fun main() { assertNotNull(s.ptr) assertNotNull(u.ptr) assertNotNull(array) assertEquals("initial", getContent(s.ptr)?.toKString()) setContent(s.ptr, "yo") val ptr = getContent(s.ptr) assertEquals("yo", ptr?.toKString()) assertEquals(0.0, getDouble(u.ptr)) setDouble(u.ptr, Double.MIN_VALUE) assertEquals(Double.MIN_VALUE, getDouble(u.ptr)) for (i in 0 until arrayLength()) { assertEquals(0x0, array[i]) } setArrayValue(array, 0x1) for (i in 0 until arrayLength()) { assertEquals(0x1, array[i]) } } ================================================ FILE: backend.native/tests/interop/kt42397/knlibrary.kt ================================================ package knlibrary import kotlin.native.Platform // The following 2 singletons are unused. However, since we are generating C bindings for them, // they should be marked as used, so that the code generator emits their deinitialization. object A {} class B { companion object {} } fun enableMemoryChecker() { Platform.isMemoryLeakCheckerActive = true } ================================================ FILE: backend.native/tests/interop/kt42397/test.cpp ================================================ #include "testlib_api.h" #include int main() { auto t = std::thread([] { auto lib = testlib_symbols(); lib->kotlin.root.knlibrary.enableMemoryChecker(); // Initialize A and B.Companion and get their stable pointers. auto a = lib->kotlin.root.knlibrary.A._instance(); auto bCompanion = lib->kotlin.root.knlibrary.B.Companion._instance(); // Now, dispose of the stable pointers. lib->DisposeStablePointer(bCompanion.pinned); lib->DisposeStablePointer(a.pinned); // A and B.Companion now are owned by the global references only. }); // This causes Kotlin runtime full deinitialization, because `t` is the only thread // with the Kotlin runtime. So, all the globals will get deinitialized and memory // leak checker will get executed (because .kt code is compiled with -g). t.join(); return 0; } ================================================ FILE: backend.native/tests/interop/kt43265/kt43265.def ================================================ strictEnums = bcm2835FunctionSelect --- enum bcm2835FunctionSelect { BCM2835_GPIO_FSEL_INPT = 0x00, BCM2835_GPIO_FSEL_OUTP = 0x01, BCM2835_GPIO_FSEL_ALT0 = 0x04, BCM2835_GPIO_FSEL_ALT1 = 0x05, BCM2835_GPIO_FSEL_ALT2 = 0x06, BCM2835_GPIO_FSEL_ALT3 = 0x07, BCM2835_GPIO_FSEL_ALT4 = 0x03, BCM2835_GPIO_FSEL_ALT5 = 0x02, BCM2835_GPIO_FSEL_MASK = 0x07 }; ================================================ FILE: backend.native/tests/interop/kt43265/usage.kt ================================================ import kt43265.* import kotlin.test.* fun main() { assertEquals(bcm2835FunctionSelect.BCM2835_GPIO_FSEL_ALT3, bcm2835FunctionSelect.BCM2835_GPIO_FSEL_MASK) } ================================================ FILE: backend.native/tests/interop/kt43502/kt43502.c ================================================ char **externPtr = 0; ================================================ FILE: backend.native/tests/interop/kt43502/kt43502.def ================================================ libraryPaths = backend.native/tests/build/kt43502 staticLibraries = kt43502.a ================================================ FILE: backend.native/tests/interop/kt43502/kt43502.h ================================================ extern char **externPtr; ================================================ FILE: backend.native/tests/interop/kt43502/main.c ================================================ #include "testlib_api.h" int main() { testlib_symbols()->kotlin.root.printExternPtr(); } ================================================ FILE: backend.native/tests/interop/kt43502/main.kt ================================================ import kt43502.* fun printExternPtr() { println(externPtr) } ================================================ FILE: backend.native/tests/interop/leakMemoryWithRunningThread/checked.kt ================================================ import leakMemory.* import kotlin.native.concurrent.* import kotlin.native.Platform import kotlin.test.* import kotlinx.cinterop.* val global = AtomicInt(0) fun ensureInititalized() { kotlin.native.initRuntimeIfNeeded() // Leak memory StableRef.create(Any()) global.value = 1 } fun main() { Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.Debugging.forceCheckedShutdown = true assertTrue(global.value == 0) // Created a thread, made sure Kotlin is initialized there. test_RunInNewThread(staticCFunction(::ensureInititalized)) assertTrue(global.value == 1) // Now exiting. With checked shutdown we will fail, complaining there're // unfinished threads with runtimes. } ================================================ FILE: backend.native/tests/interop/leakMemoryWithRunningThread/leakMemory.cpp ================================================ #include "leakMemory.h" #include #include extern "C" void test_RunInNewThread(void (*f)()) { std::atomic haveRun(false); std::thread t([f, &haveRun]() { f(); haveRun = true; while (true) {} }); t.detach(); while (!haveRun) {} } ================================================ FILE: backend.native/tests/interop/leakMemoryWithRunningThread/leakMemory.def ================================================ package leakMemory --- void test_RunInNewThread(void (*)()); ================================================ FILE: backend.native/tests/interop/leakMemoryWithRunningThread/leakMemory.h ================================================ #ifdef __cplusplus extern "C" { #endif void test_RunInNewThread(void (*)()); #ifdef __cplusplus } #endif ================================================ FILE: backend.native/tests/interop/leakMemoryWithRunningThread/unchecked.kt ================================================ import leakMemory.* import kotlin.native.concurrent.* import kotlin.native.Platform import kotlin.test.* import kotlinx.cinterop.* val global = AtomicInt(0) fun ensureInititalized() { kotlin.native.initRuntimeIfNeeded() // Leak memory StableRef.create(Any()) global.value = 1 } fun main() { Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.Debugging.forceCheckedShutdown = false assertTrue(global.value == 0) // Created a thread, made sure Kotlin is initialized there. test_RunInNewThread(staticCFunction(::ensureInititalized)) assertTrue(global.value == 1) // Now exiting. With unchecked shutdown, we exit quietly, even though there're // unfinished threads with runtimes. } ================================================ FILE: backend.native/tests/interop/libiconv.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import platform.iconv.* import platform.posix.size_tVar fun main(args: Array) { val sourceByteArray = "Hello!".encodeToByteArray() val golden = listOf(0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21) memScoped { val sourceLength = alloc() val destLength = alloc() val sourceBytes = allocArrayOf(sourceByteArray) val destBytes = allocArray(golden.size) val sourcePtr = alloc>() sourcePtr.value = sourceBytes val destPtr = alloc>() destPtr.value = destBytes sourceLength.value = sourceByteArray.size.convert() destLength.value = golden.size.convert() val conversion = iconv_open("UTF-8", "LATIN1") iconv(conversion, sourcePtr.ptr, sourceLength.ptr, destPtr.ptr, destLength.ptr) golden.forEachIndexed { index, it -> println("$it ${destBytes[index]}") it == destBytes[index].toInt() } iconv_close(conversion) } } ================================================ FILE: backend.native/tests/interop/memory_leaks/lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import kotlin.native.Platform fun enableMemoryChecker() { Platform.isMemoryLeakCheckerActive = true } fun leakMemory() { StableRef.create(Any()) } ================================================ FILE: backend.native/tests/interop/memory_leaks/main.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "testlib_api.h" #include int main() { std::thread t([]() { testlib_symbols()->kotlin.root.enableMemoryChecker(); testlib_symbols()->kotlin.root.leakMemory(); }); t.join(); return 0; } ================================================ FILE: backend.native/tests/interop/migrating_main_thread/lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ class A { var i = 0 } private var globalA = A() fun writeToA(i: Int) { globalA.i = i } fun tryReadFromA(default: Int): Int { return try { globalA.i } catch (e: IncorrectDereferenceException) { default } } ================================================ FILE: backend.native/tests/interop/migrating_main_thread/main.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "testlib_api.h" #include #include constexpr int kInitialValue = 0; constexpr int kNewValue = 1; constexpr int kErrorValue = 2; int main() { std::thread main1([]() { assert(testlib_symbols()->kotlin.root.tryReadFromA(kErrorValue) == kInitialValue); testlib_symbols()->kotlin.root.writeToA(kNewValue); assert(testlib_symbols()->kotlin.root.tryReadFromA(kErrorValue) == kNewValue); }); main1.join(); std::thread main2([]() { #if defined(IS_LEGACY) // Globals were reinitialized. assert(testlib_symbols()->kotlin.root.tryReadFromA(kErrorValue) == kInitialValue); #else // Globals are not accessible. assert(testlib_symbols()->kotlin.root.tryReadFromA(kErrorValue) == kErrorValue); #endif }); main2.join(); return 0; } ================================================ FILE: backend.native/tests/interop/objc/Localizable.stringsdict ================================================ screen_main_plural_string NSStringLocalizedFormatKey %#@value@ value NSStringFormatSpecTypeKey NSStringPluralRuleType NSStringFormatValueTypeKey d other Plural: %d apples one Plural: one apple zero Plural: no apples ================================================ FILE: backend.native/tests/interop/objc/allocException.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import platform.Foundation.* import platform.objc.* import kotlin.test.* import kotlinx.cinterop.* import platform.posix.* import kotlin.system.exitProcess fun exc_handler(x: Any?) : Unit { println("Uncaught exception handler") println(x.toString()) exitProcess(0) } fun main() { // This does not work anymore, as NSException propagated as ForeignException // so we got `Uncaught Kotlin exception` instead. Use normal try/catch. objc_setUncaughtExceptionHandler(staticCFunction(::exc_handler)) try { println(NSJSONSerialization()) } catch (e: Exception) { // ForeignException expected println(e) } } ================================================ FILE: backend.native/tests/interop/objc/foreignException/objcExceptionMode.def ================================================ language = Objective-C headerFilter = **/objc_wrap.h linkerOpts = -lobjcexception ================================================ FILE: backend.native/tests/interop/objc/foreignException/objcExceptionMode.kt ================================================ /* * Test different behavior depending on foreignExceptionMode option */ import kotlin.test.* import objcExceptionMode.* import kotlinx.cinterop.* import platform.objc.* import kotlin.system.exitProcess @Suppress("VARIABLE_WITH_REDUNDANT_INITIALIZER") @Test fun testKT35056() { val name = "Some native exception" val reason = "Illegal value" var finallyBlockTest = "FAILED" var catchBlockTest = "FAILED" try { raiseExc(name, reason) assertNotEquals("FAILED", catchBlockTest) // shall not get here anyway } catch (e: ForeignException) { val ret = logExc(e.nativeException) // return NSException name assertEquals(name, ret) assertEquals("$name:: $reason", e.message) println("OK: ForeignException") catchBlockTest = "PASSED" } finally { finallyBlockTest = "PASSED" } assertEquals("PASSED", catchBlockTest) assertEquals("PASSED", finallyBlockTest) } @Suppress("UNUSED_PARAMETER") fun abnormal_handler(x: Any?) : Unit { println("OK: Ends with uncaught exception handler") exitProcess(0) } fun main() { // Depending on the `foreignxceptionMode` option (def file or cinterop cli) this test should ends // normally with `ForeignException` handled or abnormally with `abnormal_handler`. // Test shall validate output (golden value) from `abnormal_handler`. objc_setUncaughtExceptionHandler(staticCFunction(::abnormal_handler)) testKT35056() } ================================================ FILE: backend.native/tests/interop/objc/foreignException/objc_wrap.def ================================================ language = Objective-C headerFilter = **/objc_wrap.h linkerOpts = -lobjcexception foreignExceptionMode = objc-wrap ================================================ FILE: backend.native/tests/interop/objc/foreignException/objc_wrap.h ================================================ #import void raiseExc(id name, id reason); id logExc(id exception); @interface Foo : NSObject - (void)instanceMethodThrow:(id)name reason:(id)reason; + (void)classMethodThrow:(id)name reason:(id)reason; @end ================================================ FILE: backend.native/tests/interop/objc/foreignException/objc_wrap.kt ================================================ /* * Test different types of callable with foreignExceptionMode=objc-wrap */ import kotlin.test.* //import objcTests.* import objc_wrap.* import kotlinx.cinterop.* fun testInner(name: String, reason: String) { var finallyBlockTest = "FAILED" var catchBlockTest = "NOT EXPECTED" try { raiseExc(name, reason) } catch (e: RuntimeException) { catchBlockTest = "This shouldn't happen" } finally { finallyBlockTest = "PASSED" } assertEquals("NOT EXPECTED", catchBlockTest) assertEquals("PASSED", finallyBlockTest) } typealias CallMe = (String, String) -> Unit @Test fun testExceptionWrap(raise: CallMe) { val name = "Some native exception" val reason = "Illegal value" var finallyBlockTest = "FAILED" var catchBlockTest = "FAILED" try { raise(name, reason) } catch (e: ForeignException) { val ret = logExc(e.nativeException) // return NSException name assertEquals(name, ret) assertEquals("$name:: $reason", e.message) catchBlockTest = "PASSED" } finally { finallyBlockTest = "PASSED" } assertEquals("PASSED", catchBlockTest) assertEquals("PASSED", finallyBlockTest) } class Bar() : Foo() fun main() { testExceptionWrap(::raiseExc) // simple testExceptionWrap(::testInner) // nested try block testExceptionWrap(Foo::classMethodThrow) // class method testExceptionWrap(Foo()::instanceMethodThrow) // instance method testExceptionWrap(Bar()::instanceMethodThrow) // fake override } ================================================ FILE: backend.native/tests/interop/objc/foreignException/objc_wrap.m ================================================ #include "objc_wrap.h" #import void raiseExc(id name, id reason) { [NSException raise:name format:@"%@", reason]; } id logExc(id exc) { assert([exc isKindOfClass:[NSException class]]); return ((NSException*)exc).name; } @implementation Foo : NSObject - (void) instanceMethodThrow:(id)name reason:(id)reason { raiseExc(name, reason); } + (void) classMethodThrow:(id)name reason:(id)reason { raiseExc(name, reason); } @end ================================================ FILE: backend.native/tests/interop/objc/illegal_sharing.kt ================================================ import kotlin.native.concurrent.* import kotlin.test.* import platform.Foundation.* import platform.darwin.NSObject fun Worker.runInWorker(block: () -> Unit) { this.execute(TransferMode.SAFE, { block.freeze() }) { it() }.result } private class NSObjectImpl : NSObject() { var x = 111 } // Also see counterpart in interop/objc/tests/sharing.kt fun main() = withWorker { val obj = NSObjectImpl() val array: NSArray = NSMutableArray().apply { addObject(obj) } assertFalse(obj.isFrozen) println("Before") runInWorker { array.objectAtIndex(0) } println("After") } ================================================ FILE: backend.native/tests/interop/objc/illegal_sharing_with_weak/main.kt ================================================ import kotlin.native.concurrent.* import kotlinx.cinterop.autoreleasepool import objclib.* fun main() { autoreleasepool { run() } } private class NSObjectImpl : NSObject() { var x = 111 } fun run() = withWorker { val obj = NSObjectImpl() setObject(obj) println("Before") val isAlive = try { execute(TransferMode.SAFE, {}) { isObjectAliveShouldCrash() }.result } catch (e: Throwable) { false } println("After $isAlive") } ================================================ FILE: backend.native/tests/interop/objc/illegal_sharing_with_weak/objclib.def ================================================ language = Objective-C headerFilter = **/objclib.h ================================================ FILE: backend.native/tests/interop/objc/illegal_sharing_with_weak/objclib.h ================================================ #import static NSObject* __weak globalObject = nil; void setObject(NSObject* obj) { globalObject = obj; } // Make sure this function persists, because the test expects to find this function in the stack trace. __attribute__((noinline)) bool isObjectAliveShouldCrash() { return globalObject != nil; } ================================================ FILE: backend.native/tests/interop/objc/kt34467/foo.h ================================================ #define ANSWER 42 ================================================ FILE: backend.native/tests/interop/objc/kt34467/foo.kt ================================================ import module_library.* fun main() { println("OK") println(ANSWER) } ================================================ FILE: backend.native/tests/interop/objc/kt34467/module_library.def ================================================ language = Objective-C modules = module_library ================================================ FILE: backend.native/tests/interop/objc/kt34467/module_library.modulemap ================================================ module module_library { umbrella header "module_library_umbrella.h" export * module * { export * } } ================================================ FILE: backend.native/tests/interop/objc/kt34467/module_library_umbrella.h ================================================ #import ================================================ FILE: backend.native/tests/interop/objc/kt42172/main.kt ================================================ import objclib.* import kotlin.native.concurrent.* import kotlinx.cinterop.* fun main() { val worker = Worker.start() worker.execute(TransferMode.SAFE, {}) { val withFinalizer = WithFinalizer() val finalizer: Finalizer = staticCFunction { ptr: COpaquePointer? -> ptr?.asStableRef()?.dispose() println("Executed finalizer") } val arg = StableRef.create(Any()).asCPointer() withFinalizer.setFinalizer(finalizer, arg) }.result worker.requestTermination().result waitWorkerTermination(worker) } ================================================ FILE: backend.native/tests/interop/objc/kt42172/objclib.def ================================================ language = Objective-C headerFilter = **/objclib.h linkerOpts = -lobjc_kt42172 ================================================ FILE: backend.native/tests/interop/objc/kt42172/objclib.h ================================================ #import typedef void (*Finalizer)(void*); @interface WithFinalizer : NSObject - (void)setFinalizer:(Finalizer)finalizer arg:(void*)arg; @end ================================================ FILE: backend.native/tests/interop/objc/kt42172/objclib.m ================================================ #include "objclib.h" @implementation WithFinalizer { Finalizer finalizer_; void* arg_; } - (void)dealloc { if (finalizer_) { finalizer_(arg_); } } - (void)setFinalizer:(Finalizer)finalizer arg:(void*)arg { finalizer_ = finalizer; arg_ = arg; } @end ================================================ FILE: backend.native/tests/interop/objc/msg_send/main.kt ================================================ import messaging.* import kotlinx.cinterop.* import kotlin.test.* fun main(args: Array) { autoreleasepool { primitives() aggregates() } } private fun primitives() { assertEquals(3.14f, PrimitiveTestSubject.floatFn()) assertEquals(3.14, PrimitiveTestSubject.doubleFn()) assertEquals(42, PrimitiveTestSubject.intFn()) assertEquals(vectorOf(2f, 4f, 5f, 8f), PrimitiveTestSubject.simdFn()) } private fun aggregates() { AggregateTestSubject.singleFloatFn().useContents { assertEquals(3.14f, f) } AggregateTestSubject.simplePackedFn().useContents { assertEquals('0'.toByte(), f1) assertEquals(111, f2) } AggregateTestSubject.evenSmallerPackedFn().useContents { assertEquals('x'.toByte(), x) assertEquals(169, y) assertEquals('z'.toByte(), z) } AggregateTestSubject.homogeneousBigFn().useContents { assertEquals(1.0f, f1) assertEquals(2.0f, f2) assertEquals(3.0f, f3) assertEquals(4.0f, f4) assertEquals(5.0f, f5) assertEquals(6.0f, f6) assertEquals(7.0f, f7) assertEquals(8.0f, f8) } AggregateTestSubject.homogeneousSmallFn().useContents { assertEquals(1.0f, f1) assertEquals(2.0f, f2) assertEquals(3.0f, f3) assertEquals(4.0f, f4) } AggregateTestSubject.simd_quatfFn().useContents { assertEquals(vectorOf(1f, 4f, 9f, 25f), vector) } AggregateTestSubject.geterogeneousSmallFn().useContents { assertEquals(1, s1) assertEquals(vectorOf(1f, 4f, 9f, 25f), v2) assertEquals(3f, f3) assertEquals(4, i4) } } ================================================ FILE: backend.native/tests/interop/objc/msg_send/messaging.def ================================================ language = Objective-C headerFilter = **/messaging.h linkerOpts = -lobjcmessaging ================================================ FILE: backend.native/tests/interop/objc/msg_send/messaging.h ================================================ #import #include @interface PrimitiveTestSubject : NSObject + (int)intFn; + (float)floatFn; + (double)doubleFn; + (simd_float4)simdFn; @end; typedef struct { float f; } SingleFloat; typedef struct __attribute__((packed)) { char f1; short f2; char f3; char f4; } SimplePacked; typedef struct __attribute__((packed)) { char x; short y; char z; } EvenSmallerPacked; typedef struct { float f1; float f2; float f3; float f4; } HomogeneousSmall; typedef struct { float f1; float f2; float f3; float f4; float f5; float f6; float f7; float f8; } HomogeneousBig; // TODO: Add more cases later: SIMD, bitfields. typedef struct { short s1; simd_float4 v2; float f3; int i4; } GeterogeneousSmall; @interface AggregateTestSubject : NSObject + (SingleFloat)singleFloatFn; + (SimplePacked)simplePackedFn; + (EvenSmallerPacked)evenSmallerPackedFn; + (HomogeneousSmall)homogeneousSmallFn; + (HomogeneousBig)homogeneousBigFn; + (simd_quatf)simd_quatfFn; + (GeterogeneousSmall)geterogeneousSmallFn; @end; ================================================ FILE: backend.native/tests/interop/objc/msg_send/messaging.m ================================================ #import "messaging.h" @implementation PrimitiveTestSubject + (int)intFn { return 42; } + (float)floatFn { return 3.14f; } + (double)doubleFn { return 3.14; } + (simd_float4)simdFn { simd_float4 v; v.x = 2; v.y = 4; v.z = 5; v.w = 8; return v; } @end; @implementation AggregateTestSubject + (SingleFloat)singleFloatFn { SingleFloat s; s.f = 3.14f; return s; } + (SimplePacked)simplePackedFn { SimplePacked s; s.f1 = '0'; s.f2 = 111; return s; } + (EvenSmallerPacked)evenSmallerPackedFn { EvenSmallerPacked s; s.x = 'x'; s.y = 169; s.z = 'z'; return s; } + (HomogeneousSmall)homogeneousSmallFn { HomogeneousSmall s; s.f1 = 1.0f; s.f2 = 2.0f; s.f3 = 3.0f; s.f4 = 4.0f; return s; } + (HomogeneousBig)homogeneousBigFn { HomogeneousBig s; s.f1 = 1.0f; s.f2 = 2.0f; s.f3 = 3.0f; s.f4 = 4.0f; s.f5 = 5.0f; s.f6 = 6.0f; s.f7 = 7.0f; s.f8 = 8.0f; return s; } + (GeterogeneousSmall)geterogeneousSmallFn { return (GeterogeneousSmall){1, {1, 4, 9, 25}, 3, 4}; } + (simd_quatf)simd_quatfFn { return (simd_quatf){ {1, 4, 9, 25} }; } @end; ================================================ FILE: backend.native/tests/interop/objc/objcSmoke.def ================================================ language = Objective-C headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h Foundation/NSBundle.h headerFilter = **/smoke.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h \ objc/objc.h Foundation/NSBundle.h linkerOpts = -lobjcsmoke ================================================ FILE: backend.native/tests/interop/objc/objcTests.def ================================================ language = Objective-C headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h Foundation/NSBundle.h headerFilter = **/interop/objc/tests/**.h \ Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h Foundation/NSStream.h \ objc/objc.h Foundation/NSBundle.h linkerOpts = -lobjctests ================================================ FILE: backend.native/tests/interop/objc/smoke.h ================================================ #import #import @class Foo; @protocol Printer; @protocol Printer; @protocol Empty @end; @protocol Forward; @class Forward; void useForward1(Forward * p) {} void useForward2(id p) {} typedef NSString NSStringTypedef; @interface Foo : NSObject @property NSStringTypedef* name; -(void)helloWithPrinter:(id )printer; @end; @interface Foo (FooExtensions) -(void)hello; @end; @protocol Printer @required -(void)print:(const char*)string; @end; @protocol MutablePair @required @property (readonly) int first; @property (readonly) int second; -(void)update:(int)index add:(int)delta; -(void)update:(int)index sub:(int)delta; @end; void replacePairElements(id pair, int first, int second); int invoke1(int arg, int (^block)(int)) { return block(arg); } void invoke2(void (^block)(void)) { block(); } int (^getSupplier(int x))(void); Class (^ _Nonnull getClassGetter(NSObject* obj))(void); extern NSString* globalString; extern NSObject* globalObject; int formatStringLength(NSString* format, ...); #define STRING_MACRO @"String macro" #define CFSTRING_MACRO CFSTR("CFString macro") typedef NS_ENUM(int32_t, ForwardDeclaredEnum); typedef NS_ENUM(int32_t, ForwardDeclaredEnum) { ZERO, ONE, TWO, }; @protocol ObjectFactory @required -(id)create; @end; id createObjectWithFactory(id factory) { return [factory create]; } @protocol CustomRetainMethods @required -(id)returnRetained:(id)obj __attribute__((ns_returns_retained)); -(void)consume:(id) __attribute__((ns_consumed)) obj; -(void)consumeSelf __attribute__((ns_consumes_self)); -(void (^)(void))returnRetainedBlock:(void (^)(void))block __attribute__((ns_returns_retained)); @end; extern BOOL unexpectedDeallocation; @interface MustNotBeDeallocated : NSObject @end; @interface CustomRetainMethodsImpl : MustNotBeDeallocated @end; static MustNotBeDeallocated* retainedObj; static void (^retainedBlock)(void); void useCustomRetainMethods(id p) { MustNotBeDeallocated* obj = [MustNotBeDeallocated new]; retainedObj = obj; // Retain to detect possible over-release. [p returnRetained:obj]; [p consume:p]; [p consumeSelf]; MustNotBeDeallocated* capturedObj = [MustNotBeDeallocated new]; retainedBlock = ^{ [capturedObj description]; }; // Retain to detect possible over-release. [p returnRetainedBlock:retainedBlock](); } id getPrinterProtocolRaw() { return @protocol(Printer); } Protocol* getPrinterProtocol() { return @protocol(Printer); } ================================================ FILE: backend.native/tests/interop/objc/smoke.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import objcSmoke.* import kotlin.native.concurrent.* import kotlin.native.ref.* import kotlin.test.* fun main(args: Array) { // Test relies on full deinitialization at shutdown. kotlin.native.internal.Debugging.forceCheckedShutdown = true autoreleasepool { run() } } fun run() { // TODO: migrate remaining tests to interop/objc/tests/ testTypeOps() testCustomRetain() testExportObjCClass() testLocalizedStrings() assertEquals(2, ForwardDeclaredEnum.TWO.value) println( getSupplier( invoke1(42) { it * 2 } )!!() ) val foo = Foo() val classGetter = getClassGetter(foo) invoke2 { println(classGetter()) } foo.hello() foo.name = "everybody" foo.helloWithPrinter(object : NSObject(), PrinterProtocol { override fun print(string: CPointer?) { println("Kotlin says: " + string?.toKString()) } }) Bar().hello() val pair = MutablePairImpl(42, 17) replacePairElements(pair, 1, 2) pair.swap() println("${pair.first}, ${pair.second}") val defaultPair = MutablePairImpl() assertEquals(defaultPair.first(), 123) assertEquals(defaultPair.second(), 321) // equals and hashCode (virtually): val map = mapOf(foo to pair, pair to foo) // equals (directly): if (!foo.equals(pair)) { // toString (directly): println(map[pair].toString() + map[foo].toString() == foo.description() + pair.description()) } // hashCode (directly): // hash() returns value of NSUInteger type. val hash = if (sizeOf() == 4L) { foo.hash().toInt() } else { foo.hash().let { it.toInt() xor (it shr 32).toInt() } } if (foo.hashCode() == hash) { // toString (virtually): if (Platform.memoryModel == MemoryModel.STRICT) println(map.keys.map { it.toString() }.min() == foo.description()) else // TODO: hack until proper cycle collection in maps. println(true) } println(globalString) autoreleasepool { globalString = "Another global string" } println(globalString) println(globalObject) globalObject = object : NSObject() { override fun description() = "global object" } println(globalObject) globalObject = null // Prevent Kotlin object above from leaking. println(formatStringLength("%d %d", 42, 17)) println(STRING_MACRO) println(CFSTRING_MACRO) // Ensure that overriding method bridge has retain-autorelease sequence: createObjectWithFactory(object : NSObject(), ObjectFactoryProtocol { override fun create() = autoreleasepool { NSObject() } }) } fun MutablePairProtocol.swap() { update(0, add = second) update(1, sub = first) update(0, add = second) update(1, sub = second*2) } class Bar : Foo() { override fun helloWithPrinter(printer: PrinterProtocol?) = memScoped { printer!!.print("Hello from Kotlin".cstr.getPointer(memScope)) } } @Suppress("CONFLICTING_OVERLOADS") class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol { private var elements = intArrayOf(first, second) override fun first() = elements.first() override fun second() = elements.last() override fun update(index: Int, add: Int) { elements[index] += add } override fun update(index: Int, sub: Int) { elements[index] -= sub } constructor() : this(123, 321) } interface Zzz fun testTypeOps() { assertTrue(99.asAny() is NSNumber) assertTrue(null.asAny() is NSNumber?) assertFalse(null.asAny() is NSNumber) assertFalse("".asAny() is NSNumber) assertTrue("bar".asAny() is NSString) assertTrue(Foo.asAny() is FooMeta) assertFalse(Foo.asAny() is Zzz) assertTrue(Foo.asAny() is NSObjectMeta) assertTrue(Foo.asAny() is NSObject) assertFalse(Foo.asAny() is Foo) assertTrue(NSString.asAny() is NSCopyingProtocolMeta) assertFalse(NSString.asAny() is NSCopyingProtocol) assertTrue(NSValue.asAny() is NSObjectProtocolMeta) assertFalse(NSValue.asAny() is NSObjectProtocol) // Must be true, but not implemented properly yet. assertFalse(Any() is ObjCClass) assertFalse(Any() is ObjCClassOf<*>) assertFalse(NSObject().asAny() is ObjCClass) assertFalse(NSObject().asAny() is ObjCClassOf<*>) assertTrue(NSObject.asAny() is ObjCClass) assertTrue(NSObject.asAny() is ObjCClassOf<*>) assertFalse(Any() is ObjCProtocol) assertTrue(getPrinterProtocolRaw() is ObjCProtocol) val printerProtocol = getPrinterProtocol()!! assertTrue(printerProtocol.asAny() is ObjCProtocol) assertEquals(3u, ("foo" as NSString).length()) assertEquals(4u, ((1..4).joinToString("") as NSString).length()) assertEquals(2u, (listOf(0, 1) as NSArray).count()) assertEquals(42L, (42 as NSNumber).longLongValue()) assertFails { "bar" as NSNumber } assertFails { 42 as NSArray } assertFails { listOf(1) as NSString } assertFails { NSObject() as Bar } assertFails { NSObject() as NSValue } MutablePairImpl(1, 2).asAny() as MutablePairProtocol assertFails { MutablePairImpl(1, 2).asAny() as Foo } } private lateinit var retainedMustNotBeDeallocated: MustNotBeDeallocated fun testCustomRetain() { fun test() { useCustomRetainMethods(object : Foo(), CustomRetainMethodsProtocol { override fun returnRetained(obj: Any?) = obj override fun consume(obj: Any?) {} override fun consumeSelf() {} override fun returnRetainedBlock(block: (() -> Unit)?) = block }) CustomRetainMethodsImpl().let { it.returnRetained(Any()) retainedMustNotBeDeallocated = MustNotBeDeallocated() // Retain to detect possible over-release. it.consume(retainedMustNotBeDeallocated) it.consumeSelf() it.returnRetainedBlock({})!!() } } autoreleasepool { test() kotlin.native.internal.GC.collect() } assertFalse(unexpectedDeallocation) } private const val TestExportObjCClass1Name = "TestExportObjCClass" @ExportObjCClass(TestExportObjCClass1Name) class TestExportObjCClass1 : NSObject() @ExportObjCClass class TestExportObjCClass2 : NSObject() const val TestExportObjCClass34Name = "TestExportObjCClass34" @ExportObjCClass(TestExportObjCClass34Name) class TestExportObjCClass3 : NSObject() @ExportObjCClass(TestExportObjCClass34Name) class TestExportObjCClass4 : NSObject() fun testExportObjCClass() { assertEquals(TestExportObjCClass1Name, TestExportObjCClass1().objCClassName) assertEquals("TestExportObjCClass2", TestExportObjCClass2().objCClassName) assertTrue((TestExportObjCClass3().objCClassName == TestExportObjCClass34Name) xor (TestExportObjCClass4().objCClassName == TestExportObjCClass34Name)) } fun testLocalizedStrings() { val key = "screen_main_plural_string" val localizedString = NSBundle.mainBundle.localizedStringForKey(key, value = "", table = "Localizable") val string = NSString.localizedStringWithFormat(localizedString, 5) assertEquals("Plural: 5 apples", string) } private val Any.objCClassName: String get() = object_getClassName(this)!!.toKString() fun Any?.asAny(): Any? = this ================================================ FILE: backend.native/tests/interop/objc/smoke.m ================================================ #import #import #import "smoke.h" @interface CPrinter : NSObject -(void)print:(const char*)string; @end; @implementation CPrinter -(void)print:(const char*)string { printf("%s\n", string); fflush(stdout); } @end; @implementation Foo @synthesize name; -(instancetype)init { if (self = [super init]) { self.name = @"World"; } return self; } -(void)helloWithPrinter:(id )printer { NSString* message = [NSString stringWithFormat:@"Hello, %@!", self.name]; [printer print:message.UTF8String]; } -(void)dealloc { printf("Deallocated\n"); } @end; @implementation Foo (FooExtensions) -(void)hello { CPrinter* printer = [[CPrinter alloc] init]; [self helloWithPrinter:printer]; } @end; void replacePairElements(id pair, int first, int second) { [pair update:0 add:(first - pair.first)]; [pair update:1 sub:(pair.second - second)]; } int (^getSupplier(int x))(void) { return ^{ return x; }; } Class (^ _Nonnull getClassGetter(NSObject* obj))() { return ^{ return obj.class; }; } NSString* globalString = @"Global string"; NSObject* globalObject = nil; int formatStringLength(NSString* format, ...) { va_list args; va_start(args, format); NSString* result = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); return result.length; } BOOL unexpectedDeallocation = NO; @implementation MustNotBeDeallocated -(void)dealloc { unexpectedDeallocation = YES; } @end; static CustomRetainMethodsImpl* retainedCustomRetainMethodsImpl; @implementation CustomRetainMethodsImpl -(id)returnRetained:(id)obj __attribute__((ns_returns_retained)) { return obj; } -(void)consume:(id) __attribute__((ns_consumed)) obj { } -(void)consumeSelf __attribute__((ns_consumes_self)) { retainedCustomRetainMethodsImpl = self; // Retain to detect possible over-release. } -(void (^)(void))returnRetainedBlock:(void (^)(void))block __attribute__((ns_returns_retained)) { return block; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/KT37067_prefix.h ================================================ #import @interface KT37067_Impl : NSObject @property (nonatomic, readonly) NSObject *newValue; @property (nonatomic, readonly) NSObject *allocValue; @property (nonatomic, readonly) NSObject *copyValue; @property (nonatomic, readonly) NSObject *mutableCopyValue; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/KT37067_prefix.kt ================================================ import kotlin.test.* import objcTests.* /// KT-37067: attribute prefixed with "new" causes cinterop failure // No matter what is in the test: I only need to get it compilable with cinterop @Test fun testKT37067() { val impl = KT37067_Impl() assertEquals(null, impl.newValue) } ================================================ FILE: backend.native/tests/interop/objc/tests/KT37067_prefix.m ================================================ #include "KT37067_prefix.h" @implementation KT37067_Impl : NSObject /// KT-37067 is a cinterop issue, so .m implementaion is not relevant at all, // but I still need to make objc compilable with `-fobjc-arc` option - (NSObject *)newValue { return nil; } - (NSObject *)allocValue { return nil; } - (NSObject *)copyValue { return nil; } - (NSObject *)mutableCopyValue { return nil; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/KT38234_override.h ================================================ #import @protocol KT38234_P1 -(int)foo; @end; @interface KT38234_Base : NSObject -(int)callFoo; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/KT38234_override.kt ================================================ import kotlin.test.* import objcTests.* class KT38234_Impl : KT38234_P1Protocol, KT38234_Base() { override fun foo(): Int = 566 } @Test fun testKT38234() { assertEquals(566, KT38234_Impl().callFoo()) } ================================================ FILE: backend.native/tests/interop/objc/tests/KT38234_override.m ================================================ #include "KT38234_override.h" @implementation KT38234_Base -(int)foo { return 1; } -(int)callFoo { return [self foo]; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/allocNoRetain.h ================================================ #import @interface TestAllocNoRetain : NSObject @property BOOL ok; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/allocNoRetain.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testAllocNoRetain() { // Ensure that calling Kotlin constructor generated for Objective-C initializer doesn't result in // redundant retain-release sequence for `alloc` result, since it may provoke specific bugs to reproduce, e.g. // the one found in [[NSOutputStream alloc] initToMemory] sequence where initToMemory deallocates its receiver // forcibly when replacing it with other object: (to be compiled with ARC enabled) /* #import void* mem; NSOutputStream* allocated = nil; int main() { allocated = [NSOutputStream alloc]; NSOutputStream* initialized = [allocated initToMemory]; mem = calloc(1, 0x10); // To corrupt the 'allocated' object header. allocated = nil; // Crashes here in objc_release. return 0; } */ assertTrue(TestAllocNoRetain().ok) } ================================================ FILE: backend.native/tests/interop/objc/tests/allocNoRetain.m ================================================ #import "allocNoRetain.h" @implementation TestAllocNoRetain -(instancetype)init { __weak id weakSelf = self; self = [TestAllocNoRetain alloc]; if (self = [super init]) { // Ensure that original self value was deallocated: self.ok = (weakSelf == nil); // So it's RC was 1, which means there wasn't redundant retain applied to it. } return self; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/blocks.h ================================================ #import @protocol BlockProvider @required -(int (^)(int)) block; @end; int callProvidedBlock(id blockProvider, int argument) { return [blockProvider block](argument); } @protocol BlockConsumer @required -(int)callBlock:(int (^)(int))block argument:(int)argument; @end; int callPlusOneBlock(id blockConsumer, int argument) { return [blockConsumer callBlock:^int(int p) { return p + 1; } argument:argument]; } @interface Blocks : NSObject +(BOOL)blockIsNull:(void (^)(void))block; +(int (^)(int, int, int, int))same:(int (^)(int, int, int, int))block; @property (class) void (^nullBlock)(void); @property (class) void (^notNullBlock)(void); @end; ================================================ FILE: backend.native/tests/interop/objc/tests/blocks.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testBlocks() { assertTrue(Blocks.blockIsNull(null)) assertFalse(Blocks.blockIsNull({})) assertEquals(null, Blocks.nullBlock) assertNotEquals(null, Blocks.notNullBlock) assertEquals(10, Blocks.same({ a, b, c, d -> a + b + c + d })!!(1, 2, 3, 4)) assertEquals(222, callProvidedBlock(object : NSObject(), BlockProviderProtocol { override fun block(): (Int) -> Int = { it * 2 } }, 111)) assertEquals(322, callPlusOneBlock(object : NSObject(), BlockConsumerProtocol { override fun callBlock(block: ((Int) -> Int)?, argument: Int) = block!!(argument) }, 321)) } ================================================ FILE: backend.native/tests/interop/objc/tests/blocks.m ================================================ #import "blocks.h" @implementation Blocks +(BOOL)blockIsNull:(void (^)(void))block { return block == nil; } +(int (^)(int, int, int, int))same:(int (^)(int, int, int, int))block { return block; } +(void (^)(void)) nullBlock { return nil; } +(void (^)(void)) notNullBlock { return ^{}; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/callableReferences.h ================================================ #import @interface TestCallableReferences : NSObject @property int value; - (int)instanceMethod; + (int)classMethod:(int)first :(int)second; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/callableReferences.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testCallableReferences() { val createTestCallableReferences = ::TestCallableReferences assertEquals("", createTestCallableReferences.name) val testCallableReferences: Any = createTestCallableReferences() assertTrue(testCallableReferences is TestCallableReferences) val valueRef: kotlin.reflect.KMutableProperty0 = testCallableReferences::value assertEquals("value", valueRef.name) assertEquals(0, valueRef()) valueRef.set(42) assertEquals(42, valueRef()) val classMethodRef = (TestCallableReferences)::classMethod assertEquals("classMethod", classMethodRef.name) assertEquals(3, classMethodRef(1, 2)) val instanceMethodRef = TestCallableReferences::instanceMethod assertEquals("instanceMethod", instanceMethodRef.name) assertEquals(42, instanceMethodRef(testCallableReferences)) val boundInstanceMethodRef = testCallableReferences::instanceMethod assertEquals("instanceMethod", boundInstanceMethodRef.name) assertEquals(42, boundInstanceMethodRef()) } ================================================ FILE: backend.native/tests/interop/objc/tests/callableReferences.m ================================================ #import "callableReferences.h" @implementation TestCallableReferences - (int)instanceMethod { return self.value; } + (int)classMethod:(int)first :(int)second { return first + second; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/clashingWithAny.h ================================================ #import #import @interface TestClashingWithAny1 : NSObject -(NSString*)toString; -(NSString*)toString_; -(int)hashCode; -(BOOL)equals:(id _Nullable)other; @end; @interface TestClashingWithAny2 : NSObject -(void)toString; -(void)hashCode; -(void)equals:(int)p; // May clash. @end; @interface TestClashingWithAny3 : NSObject // Not clashing actually. -(NSString*)toString:(int)p; -(int)hashCode:(int)p; -(BOOL)equals; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/clashingWithAny.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testClashingWithAny() { assertEquals("description", TestClashingWithAny1().toString()) assertEquals("toString", TestClashingWithAny1().toString_()) assertEquals("toString_", TestClashingWithAny1().toString__()) assertEquals(1, TestClashingWithAny1().hashCode()) assertEquals(31, TestClashingWithAny1().hashCode_()) assertFalse(TestClashingWithAny1().equals(TestClashingWithAny1())) assertTrue(TestClashingWithAny1().equals_(TestClashingWithAny1())) assertEquals("description", TestClashingWithAny2().toString()) assertEquals(Unit, TestClashingWithAny2().toString_()) assertEquals(2, TestClashingWithAny2().hashCode()) assertEquals(Unit, TestClashingWithAny2().hashCode_()) assertFalse(TestClashingWithAny2().equals(TestClashingWithAny2())) assertEquals(Unit, TestClashingWithAny2().equals_(42)) assertEquals("description", TestClashingWithAny3().toString()) assertEquals("toString:11", TestClashingWithAny3().toString(11)) assertEquals(3, TestClashingWithAny3().hashCode()) assertEquals(4, TestClashingWithAny3().hashCode(3)) assertFalse(TestClashingWithAny3().equals(TestClashingWithAny3())) assertTrue(TestClashingWithAny3().equals()) } ================================================ FILE: backend.native/tests/interop/objc/tests/clashingWithAny.m ================================================ #import "clashingWithAny.h" @implementation TestClashingWithAny1 -(NSString*)description { return @"description"; } -(NSString*)toString { return @"toString"; } -(NSString*)toString_ { return @"toString_"; } -(NSUInteger)hash { return 1; } -(int)hashCode { return 31; } -(BOOL)equals:(id _Nullable)other { return YES; } @end; @implementation TestClashingWithAny2 -(NSString*)description { return @"description"; } -(void)toString { } -(NSUInteger)hash { return 2; } -(void)hashCode { } -(void)equals:(int)p { } @end; @implementation TestClashingWithAny3 -(NSString*)description { return @"description"; } -(NSString*)toString:(int)p { return [NSString stringWithFormat:@"%s:%d", "toString", p]; } -(NSUInteger)hash { return 3; } -(int)hashCode:(int)p { return p + 1; } -(BOOL)equals { return YES; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/constructorReturnsNull.h ================================================ #import @interface TestConstructorReturnsNull : NSObject - (instancetype)init; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/constructorReturnsNull.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testConstructorReturnsNull() { assertFailsWith() { TestConstructorReturnsNull() } } ================================================ FILE: backend.native/tests/interop/objc/tests/constructorReturnsNull.m ================================================ #import "constructorReturnsNull.h" @implementation TestConstructorReturnsNull - (instancetype)init { return nil; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/conversions.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testConversions() { testMethodsOfAny(emptyList(), NSArray()) testMethodsOfAny(listOf(1, "foo"), nsArrayOf(1, "foo")) testMethodsOfAny(42, NSNumber.numberWithInt(42), 17) testMethodsOfAny(true, NSNumber.numberWithBool(true), false) } private fun testMethodsOfAny(kotlinObject: Any, equalNsObject: NSObject, otherObject: Any = Any()) { assertEquals(kotlinObject.hashCode(), equalNsObject.hashCode()) assertEquals(kotlinObject.toString(), equalNsObject.toString()) assertEquals(kotlinObject, equalNsObject) assertEquals(equalNsObject, kotlinObject) assertNotEquals(equalNsObject, otherObject) } ================================================ FILE: backend.native/tests/interop/objc/tests/customString.h ================================================ #import @interface CustomString : NSString - (instancetype)initWithValue:(int)value; @property int value; @end; CustomString* _Nonnull createCustomString(int value) { return [[CustomString alloc] initWithValue:value]; } int getCustomStringValue(CustomString* str) { return str.value; } extern BOOL customStringDeallocated; ================================================ FILE: backend.native/tests/interop/objc/tests/customString.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testCustomString() { assertFalse(customStringDeallocated) fun test() = autoreleasepool { val str: String = createCustomString(321) assertEquals("321", str) assertEquals("CustomString", str.objCClassName) assertEquals(321, getCustomStringValue(str)) } test() kotlin.native.internal.GC.collect() assertTrue(customStringDeallocated) } private val Any.objCClassName: String get() = object_getClassName(this)!!.toKString() ================================================ FILE: backend.native/tests/interop/objc/tests/customString.m ================================================ #import "customString.h" BOOL customStringDeallocated = NO; @implementation CustomString { NSString* delegate; } - (instancetype)initWithValue:(int)value { if (self = [super init]) { self->delegate = @(value).description; self.value = value; } return self; } - (unichar)characterAtIndex:(NSUInteger)index { return [self->delegate characterAtIndex:index]; } - (NSUInteger)length { return self->delegate.length; } - (id)copyWithZone:(NSZone *)zone { return self; } - (void)dealloc { customStringDeallocated = YES; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/exceptions.h ================================================ #import @protocol ExceptionThrower -(void)throwException; @end; @interface ExceptionThrowerManager : NSObject +(void)throwExceptionWith:(id)thrower; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/exceptions.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testExceptions() { assertFailsWith { ExceptionThrowerManager.throwExceptionWith(object : NSObject(), ExceptionThrowerProtocol { override fun throwException() { throw MyException() } }) } } private class MyException : Throwable() ================================================ FILE: backend.native/tests/interop/objc/tests/exceptions.m ================================================ #import "exceptions.h" @implementation ExceptionThrowerManager +(void)throwExceptionWith:(id)thrower { [thrower throwException]; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/initWithCustomSelector.h ================================================ #import @interface TestInitWithCustomSelector : NSObject -(instancetype)initCustom; @property BOOL custom; +(instancetype _Nonnull)createCustom; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/initWithCustomSelector.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testInitWithCustomSelector() { assertFalse(TestInitWithCustomSelector().custom) assertTrue(TestInitWithCustomSelector(custom = Unit).custom) val customSubclass: TestInitWithCustomSelector = TestInitWithCustomSelectorSubclass.createCustom() assertTrue(customSubclass is TestInitWithCustomSelectorSubclass) assertTrue(customSubclass.custom) // Test side effect: var ok = false assertTrue(TestInitWithCustomSelector(run { ok = true }).custom) assertTrue(ok) } private class TestInitWithCustomSelectorSubclass : TestInitWithCustomSelector { @OverrideInit constructor(custom: Unit) : super(custom) { assertSame(Unit, custom) } companion object : TestInitWithCustomSelectorMeta() } ================================================ FILE: backend.native/tests/interop/objc/tests/initWithCustomSelector.m ================================================ #import "initWithCustomSelector.h" @implementation TestInitWithCustomSelector -(instancetype)initCustom { if (self = [super init]) { self.custom = YES; } return self; } -(instancetype)init { if (self = [super init]) { self.custom = NO; } return self; } +(instancetype)createCustom { return [[self alloc] initCustom]; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/kt36766.h ================================================ void kt36766(void (^block)()) {} ================================================ FILE: backend.native/tests/interop/objc/tests/kt36766.kt ================================================ import kotlin.test.* import objcTests.* @Test fun testKt36766() { kt36766(null) } ================================================ FILE: backend.native/tests/interop/objc/tests/kt41811.h ================================================ #import extern BOOL deallocRetainReleaseDeallocated; @interface DeallocRetainRelease : NSObject @end; extern DeallocRetainRelease* globalDeallocRetainRelease; @protocol WeakReference @required @property (weak) id referent; @end; @interface ObjCWeakReference : NSObject @property (weak) id referent; @end; extern id weakDeallocLoadWeak; extern BOOL deallocLoadWeakDeallocated; @interface DeallocLoadWeak : NSObject -(void)checkWeak; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/kt41811.kt ================================================ import kotlin.native.ref.WeakReference import kotlinx.cinterop.* import kotlin.test.* import objcTests.* // Note: these tests rely on GC assertions: without the fix and the assertions it won't actually crash. // GC should fire an assertion if it obtains a reference to Kotlin object that is being (or has been) deallocated. @Test fun testKT41811() { // Attempt to make the state predictable: kotlin.native.internal.GC.collect() deallocRetainReleaseDeallocated = false assertFalse(deallocRetainReleaseDeallocated) createGarbageDeallocRetainRelease() // Runs [DeallocRetainRelease dealloc]: kotlin.native.internal.GC.collect() assertTrue(deallocRetainReleaseDeallocated) // Might crash due to double-dispose if the dealloc applied addRef/releaseRef to reclaimed Kotlin object: kotlin.native.internal.GC.collect() } private fun createGarbageDeallocRetainRelease() { autoreleasepool { object : DeallocRetainRelease() {} } } @Test fun testKT41811LoadWeak() { testKT41811LoadWeak(ObjCWeakReference()) } @Test fun testKT41811LoadKotlinWeak() { val kotlinWeak = object : NSObject(), WeakReferenceProtocol { lateinit var weakReference: WeakReference override fun referent(): Any? { return weakReference.value } override fun setReferent(referent: Any?) { weakReference = WeakReference(referent!!) } } testKT41811LoadWeak(kotlinWeak) } private fun testKT41811LoadWeak(weakRef: WeakReferenceProtocol) { // Attempt to make the state predictable: kotlin.native.internal.GC.collect() deallocLoadWeakDeallocated = false assertFalse(deallocLoadWeakDeallocated) createGarbageDeallocLoadWeak(weakRef) // Runs [DeallocLoadWeak dealloc]: kotlin.native.internal.GC.collect() assertTrue(deallocLoadWeakDeallocated) // Might crash due to double-dispose if the dealloc applied addRef/releaseRef to reclaimed Kotlin object: kotlin.native.internal.GC.collect() weakDeallocLoadWeak = null } private fun createGarbageDeallocLoadWeak(weakRef: WeakReferenceProtocol) { autoreleasepool { val obj = object : DeallocLoadWeak() {} weakDeallocLoadWeak = weakRef.apply { referent = obj } obj.checkWeak() assertSame(obj, weakDeallocLoadWeak!!.referent) } } @Test fun testKT41811WithGlobal() { // Attempt to make the state predictable: kotlin.native.internal.GC.collect() deallocRetainReleaseDeallocated = false assertFalse(deallocRetainReleaseDeallocated) autoreleasepool { { globalDeallocRetainRelease = object: DeallocRetainRelease() {} }() } assertFalse(deallocRetainReleaseDeallocated) // Clean up local DeallocRetainRelease on Kotlin side kotlin.native.internal.GC.collect() assertFalse(deallocRetainReleaseDeallocated) // And drop the last reference to DeallocRetainRelease from ObjC global scope. globalDeallocRetainRelease = null assertFalse(deallocRetainReleaseDeallocated) // This will dispose `DeallocRetainRelease` on Kotlin side, which will cause `dealloc` // on ObjC side, which triggers `retain` and `release` of `self`. If these messages // were to reach Kotlin side, the `release` would have immediately scheduled the // second disposal of Kotlin object. kotlin.native.internal.GC.collect() assertTrue(deallocRetainReleaseDeallocated) } ================================================ FILE: backend.native/tests/interop/objc/tests/kt41811.m ================================================ #import "kt41811.h" #import "assert.h" id retainObject = nil; BOOL deallocRetainReleaseDeallocated = NO; @implementation DeallocRetainRelease -(void)dealloc { retainObject = self; assert(retainObject == self); retainObject = nil; assert(!deallocRetainReleaseDeallocated); deallocRetainReleaseDeallocated = YES; } @end; DeallocRetainRelease* globalDeallocRetainRelease = nil; @implementation ObjCWeakReference @end; id weakDeallocLoadWeak = nil; BOOL deallocLoadWeakDeallocated = NO; @implementation DeallocLoadWeak -(void)checkWeak { assert(weakDeallocLoadWeak != nil); assert(weakDeallocLoadWeak.referent == self); } -(void)dealloc { assert(weakDeallocLoadWeak != nil); assert(weakDeallocLoadWeak.referent == nil); assert(!deallocLoadWeakDeallocated); deallocLoadWeakDeallocated = YES; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/kt42482.h ================================================ #import extern BOOL kt42482Deallocated; extern id kt42482Global; @interface KT42482 : NSObject -(int)fortyTwo; @end; void kt42482Swizzle(id obj); ================================================ FILE: backend.native/tests/interop/objc/tests/kt42482.kt ================================================ import kotlin.native.ref.WeakReference import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testKT42482() { // Attempt to make the state predictable: kotlin.native.internal.GC.collect() kt42482Deallocated = false assertFalse(kt42482Deallocated); { assertEquals(41, KT42482().fortyTwo()) val obj: KT42482 = KT42482Impl() assertEquals(42, obj.fortyTwo()) kt42482Swizzle(obj) assertEquals(43, obj.fortyTwo()) // Test retain and release on swizzled object: kt42482Global = obj kt42482Global = null }() kotlin.native.internal.GC.collect() assertTrue(kt42482Deallocated) } class KT42482Impl : KT42482() { override fun fortyTwo() = 42 } ================================================ FILE: backend.native/tests/interop/objc/tests/kt42482.m ================================================ #import "kt42482.h" #import "assert.h" #import BOOL kt42482Deallocated = NO; id kt42482Global = nil; @implementation KT42482 -(int)fortyTwo { return 41; } -(void)dealloc { kt42482Deallocated = YES; } @end; int fortyTwoSwizzledImp(id self, SEL _cmd) { return 43; } void kt42482Swizzle(id obj) { Class oldClass = object_getClass(obj); SEL selector = @selector(fortyTwo); Class newClass = objc_allocateClassPair(oldClass, "KT42482Swizzled", 0); assert(newClass != nil); objc_registerClassPair(newClass); Method method = class_getInstanceMethod([KT42482 class], selector); assert(method != nil); class_addMethod(newClass, selector, (IMP)&fortyTwoSwizzledImp, method_getTypeEncoding(method)); object_setClass(obj, newClass); } ================================================ FILE: backend.native/tests/interop/objc/tests/main.kt ================================================ import kotlin.system.exitProcess import kotlinx.cinterop.autoreleasepool import kotlin.native.internal.test.testLauncherEntryPoint fun main(args: Array) { autoreleasepool { val exitCode = testLauncherEntryPoint(args) // Note: this test runner checks for memory leaks after successful execution, unlike standard one. if (exitCode != 0) exitProcess(exitCode) } } ================================================ FILE: backend.native/tests/interop/objc/tests/mangling.h ================================================ #import // [KT-36067] cinterop tool fails when there is a structure member named Companion struct EnumFieldMangleStruct { enum {Companion, Any} smth; }; struct EnumFieldMangleStruct enumMangledStruct = { Any }; struct MyStruct { int Companion; // simple clash int _Companion; int $_Companion; int super; }; struct MyStruct myStruct = {11, 12, 13, 14}; @protocol Proto @property int Companion; // clash on implementing @end; @interface FooMangled : NSObject //- (void) CompanionS; // mangleSimple does not support this: it may clash after mangling @end; ================================================ FILE: backend.native/tests/interop/objc/tests/mangling.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testMangling() { assertEquals(11, myStruct.`Companion$`) assertEquals(12, myStruct._Companion) assertEquals(13, myStruct.`$_Companion`) assertEquals(14, myStruct.`super`) val objc = FooMangled() objc.`Companion$` = 99 assertEquals(99, objc.Companion()) assertEquals(99, objc.`Companion$`) enumMangledStruct.smth = Companion assertEquals(Companion, enumMangledStruct.smth) } ================================================ FILE: backend.native/tests/interop/objc/tests/mangling.m ================================================ #import "mangling.h" // [KT-36067] mangling @implementation FooMangled : NSObject @synthesize Companion; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/multipleInheritanceClash.h ================================================ #import @interface MultipleInheritanceClashBase : NSObject @property (nonnull) MultipleInheritanceClashBase* delegate; @end; @protocol MultipleInheritanceClash @optional @property (nullable) id delegate; @end; @interface MultipleInheritanceClash1 : MultipleInheritanceClashBase @end; @interface MultipleInheritanceClash2 : MultipleInheritanceClashBase @property MultipleInheritanceClashBase* delegate; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/multipleInheritanceClash.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testMultipleInheritanceClash() { val clash1 = MultipleInheritanceClash1() val clash2 = MultipleInheritanceClash2() clash1.delegate = clash1 assertEquals(clash1, clash1.delegate) clash1.setDelegate(clash2) assertEquals(clash2, clash1.delegate()) clash2.delegate = clash1 assertEquals(clash1, clash2.delegate) clash2.setDelegate(clash2) assertEquals(clash2, clash2.delegate()) } ================================================ FILE: backend.native/tests/interop/objc/tests/multipleInheritanceClash.m ================================================ #import "multipleInheritanceClash.h" @implementation MultipleInheritanceClashBase @end; @implementation MultipleInheritanceClash1 @end; @implementation MultipleInheritanceClash2 @end; ================================================ FILE: backend.native/tests/interop/objc/tests/nsOutputStream.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testNSOutputStreamToMemoryConstructor() { val stream: Any = NSOutputStream(toMemory = Unit) assertTrue(stream is NSOutputStream) } ================================================ FILE: backend.native/tests/interop/objc/tests/objcWeakRefs.h ================================================ #import @class DeallocListener; @interface DeallocExecutor : NSObject @property DeallocListener* deallocListener; @end; @interface DeallocListener : NSObject @property (weak) DeallocExecutor* deallocExecutor; @property BOOL deallocated; -(BOOL)deallocExecutorIsNil; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/objcWeakRefs.kt ================================================ import kotlinx.cinterop.* import kotlin.native.concurrent.* import kotlin.test.* import objcTests.* @Test fun testObjCWeakRef() { val deallocListener = DeallocListener() assertFalse(deallocListener.deallocated) // [deallocListener.deallocExecutorIsNil()] calls deallocExecutor getter, which retains the result and either // puts it to autoreleasepool or releases it immediately (Obj-C ARC optimization). It seems to depend on the platform. // Wrap the call to autoreleasepool to ensure the object will be released: autoreleasepool { testObjCWeakRef0(deallocListener) } kotlin.native.internal.GC.collect() assertTrue(deallocListener.deallocated) assertTrue(deallocListener.deallocExecutorIsNil()) } private fun testObjCWeakRef0(deallocListener: DeallocListener) = withWorker { assertTrue(deallocListener.deallocExecutorIsNil()) val obj = object : DeallocExecutor() {} deallocListener.deallocExecutor = obj obj.deallocListener = deallocListener assertFalse(deallocListener.deallocExecutorIsNil()) // TODO: can't actually test, Obj-C runtime doesn't expect _tryRetain throwing an exception. // runInWorker { // assertFailsWith { // deallocListener.deallocExecutorIsNil() // } // } obj.freeze() runInWorker { // [deallocListener.deallocExecutorIsNil()] calls deallocExecutor getter, which retains [obj] and either // puts it to autoreleasepool or releases it immediately (Obj-C ARC optimization). // Wrap the call to autoreleasepool to ensure [obj] will be released: autoreleasepool { assertFalse(deallocListener.deallocExecutorIsNil()) } // Process release of Kotlin reference to [obj] in any case: kotlin.native.internal.GC.collect() } } ================================================ FILE: backend.native/tests/interop/objc/tests/objcWeakRefs.m ================================================ #import "objcWeakRefs.h" @implementation DeallocExecutor -(void)dealloc { self.deallocListener.deallocated = YES; } @end; @implementation DeallocListener -(BOOL)deallocExecutorIsNil { return self.deallocExecutor == nil; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/overrideInit.h ================================================ #import @interface TestOverrideInit : NSObject -(instancetype)initWithValue:(int)value NS_DESIGNATED_INITIALIZER; +(instancetype)createWithValue:(int)value; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/overrideInit.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testOverrideInit1() { assertEquals(42, (TestOverrideInitImpl1.createWithValue(42) as TestOverrideInitImpl1).value) } private class TestOverrideInitImpl1 @OverrideInit constructor(val value: Int) : TestOverrideInit(value) { companion object : TestOverrideInitMeta() } // See https://youtrack.jetbrains.com/issue/KT-41910 @Test fun testOverrideInitWithDefaultArguments() { assertEquals(42, (TestOverrideInitImpl2.createWithValue(42) as TestOverrideInitImpl2).value) assertEquals(123, TestOverrideInitImpl2(123).value) assertEquals(17, TestOverrideInitImpl2().value) } private class TestOverrideInitImpl2 @OverrideInit constructor(val value: Int = 17) : TestOverrideInit(value) { companion object : TestOverrideInitMeta() } ================================================ FILE: backend.native/tests/interop/objc/tests/overrideInit.m ================================================ #import "overrideInit.h" @implementation TestOverrideInit -(instancetype)initWithValue:(int)value { return self = [super init]; } +(instancetype)createWithValue:(int)value { return [[self alloc] initWithValue:value]; } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/sharing.kt ================================================ import kotlinx.cinterop.* import kotlin.native.concurrent.* import kotlin.test.* import objcTests.* private class NSObjectImpl : NSObject() { var x = 111 } // Also see counterpart interop/objc/illegal_sharing.kt @Test fun testSharing() = withWorker { val obj = NSObjectImpl() val array = nsArrayOf(obj) assertFalse(obj.isFrozen) obj.x = 222 obj.freeze() assertTrue(obj.isFrozen) runInWorker { val obj1 = array.objectAtIndex(0) as NSObjectImpl assertFailsWith { obj1.x = 333 } } assertEquals(222, obj.x) // TODO: test [obj release] etc. } ================================================ FILE: backend.native/tests/interop/objc/tests/structWithNSObject.h ================================================ #import struct CStructWithNSObjects { id any; NSString* nsString; NSString* _Nonnull nonNullString; NSObject* object; NSArray* array; NSMutableArray* mutableArray; NSSet* set; NSDictionary* dictionary; }; ================================================ FILE: backend.native/tests/interop/objc/tests/structWithNSObject.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* private class NSObjectSubClass : NSObject() { val x = 111 } @Test fun testStructWithNSObject() { memScoped { val struct = alloc() struct.any = 5 assertEquals(5, struct.any) struct.any = null assertEquals(null, struct.any) struct.nsString = "hello" assertEquals("hello", struct.nsString) struct.nsString = null assertEquals(null, struct.nsString) struct.nonNullString = "world" assertEquals("world", struct.nonNullString) struct.`object` = NSObjectSubClass() assertEquals(111, (struct.`object` as NSObjectSubClass).x) struct.`object` = null assertEquals(null, struct.`object`) struct.array = null assertEquals(null, struct.array) struct.array = listOf(1, 2, 3) assertEquals(listOf(1, 2, 3), struct.array) struct.set = null assertEquals(null, struct.set) struct.set = setOf("hello", "world") assertEquals(setOf("hello", "world"), struct.set) struct.dictionary = null assertEquals(null, struct.dictionary) struct.dictionary = mapOf("k1" to "v1", "k2" to "v2") assertEquals(mapOf("k1" to "v1", "k2" to "v2"), struct.dictionary) struct.mutableArray = null assertEquals(null, struct.mutableArray) struct.mutableArray = mutableListOf(1, 2) struct.mutableArray!! += 3 assertEquals(mutableListOf(1, 2, 3), struct.mutableArray) // Check that subtyping via Nothing-returning functions does not break compiler. assertFailsWith { struct.any = TODO() struct.nsString = TODO() struct.nonNullString = TODO() struct.`object` = TODO() struct.array = TODO() struct.set = TODO() struct.dictionary = TODO() struct.mutableArray = TODO() } } } ================================================ FILE: backend.native/tests/interop/objc/tests/tryRetainGC.h ================================================ #import @interface WeakRefHolder : NSObject @property (weak) id obj; -(void)loadManyTimes; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/tryRetainGC.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testTryRetainGC() { kotlin.native.internal.GC.collect() val weakRefHolder = WeakRefHolder() createGarbageNSObjects(weakRefHolder) weakRefHolder.obj = object : NSObject() {} // Loading weak ref takes a lock. If K/N runtime runs GC while the lock is taken, // then it releases garbage objects and thus Obj-C runtime might take a recursive lock // and abort in _os_unfair_lock_recursive_abort. weakRefHolder.loadManyTimes() } private fun createGarbageNSObjects(weakRefHolder: WeakRefHolder) { autoreleasepool { repeat(100) { // Assigning the object to a weak reference so Obj-C would take a lock when deallocating it: weakRefHolder.obj = NSObject() } weakRefHolder.obj = null } } ================================================ FILE: backend.native/tests/interop/objc/tests/tryRetainGC.m ================================================ #import "tryRetainGC.h" #import @implementation WeakRefHolder -(void)loadManyTimes { NSMutableArray* array = [NSMutableArray new]; for (int i = 0; i < 10000; ++i) { [array addObject:self.obj]; } } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/utils.kt ================================================ import kotlinx.cinterop.* import kotlin.native.concurrent.* import objcTests.* fun Worker.runInWorker(block: () -> Unit) { block.freeze() val future = this.execute(TransferMode.SAFE, { block }) { it() } future.result // Throws on failure. } fun nsArrayOf(vararg elements: Any): NSArray = NSMutableArray().apply { elements.forEach { this.addObject(it as ObjCObject) } } ================================================ FILE: backend.native/tests/interop/objc/tests/varargs.h ================================================ #import @interface TestVarargs : NSObject -(instancetype _Nonnull)initWithFormat:(NSString*)format, ...; +(instancetype _Nonnull)testVarargsWithFormat:(NSString*)format, ...; @property NSString* formatted; +(NSString* _Nonnull)stringWithFormat:(NSString*)format, ...; +(NSObject* _Nonnull)stringWithFormat:(NSString*)format args:(void*)args; @end; @interface TestVarargs (TestVarargsExtension) -(instancetype _Nonnull)initWithFormat:(NSString*)format, ...; @end; @interface TestVarargsSubclass : TestVarargs // Test clashes: -(instancetype _Nonnull)initWithFormat:(NSString*)format args:(void*)args; +(NSString* _Nonnull)stringWithFormat:(NSString*)format args:(void*)args; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/varargs.kt ================================================ import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testVarargs() { assertEquals( "a b -1", TestVarargs.testVarargsWithFormat( "%@ %s %d", "a" as NSString, "b".cstr, (-1).toByte() ).formatted ) assertEquals( "2 3 9223372036854775807", TestVarargs( "%d %d %lld", 2.toShort(), 3, Long.MAX_VALUE ).formatted ) assertEquals( "0.1 0.2 1 0", TestVarargs.create( "%.1f %.1lf %d %d", 0.1.toFloat(), 0.2, true, false ).formatted ) assertEquals( "1 2 3", TestVarargs( format = "%d %d %d", args = *arrayOf(1, 2, 3) ).formatted ) assertEquals( "4 5 6", TestVarargs( args = *arrayOf(4, *arrayOf(5, 6)), format = "%d %d %d" ).formatted ) assertEquals( "7", TestVarargsSubclass.stringWithFormat( "%d", 7 ) ) } ================================================ FILE: backend.native/tests/interop/objc/tests/varargs.m ================================================ #import #import #import "varargs.h" @implementation TestVarargs -(instancetype _Nonnull)initWithFormat:(NSString*)format, ... { self = [super init]; va_list args; va_start(args, format); self.formatted = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); return self; } +(instancetype _Nonnull)testVarargsWithFormat:(NSString*)format, ... { TestVarargs* result = [[self alloc] init]; va_list args; va_start(args, format); result.formatted = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); return result; } +(NSString* _Nonnull)stringWithFormat:(NSString*)format, ... { va_list args; va_start(args, format); NSString* result = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); return result; } +(NSObject* _Nonnull)stringWithFormat:(NSString*)format args:(void*)args { abort(); } @end; @implementation TestVarargsSubclass -(instancetype _Nonnull)initWithFormat:(NSString*)format args:(void*)args { abort(); } +(NSString* _Nonnull)stringWithFormat:(NSString*)format args:(void*)args { abort(); } @end; ================================================ FILE: backend.native/tests/interop/objc/tests/weakRefs.h ================================================ #import NSObject* createNSObject() { return [NSObject new]; } ================================================ FILE: backend.native/tests/interop/objc/tests/weakRefs.kt ================================================ import kotlin.native.ref.* import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testWeakRefs() { testWeakReference({ createNSObject()!! }) createAndAbandonWeakRef(NSObject()) testWeakReference({ NSArray.arrayWithArray(listOf(42)) as NSArray }) } private fun testWeakReference(block: () -> NSObject) { val ref = autoreleasepool { createAndTestWeakReference(block) } kotlin.native.internal.GC.collect() assertNull(ref.get()) } private fun createAndTestWeakReference(block: () -> NSObject): WeakReference { val ref = createWeakReference(block) assertNotNull(ref.get()) assertEquals(ref.get()!!.hash(), ref.get()!!.hash()) return ref } private fun createWeakReference(block: () -> NSObject) = WeakReference(block()) private fun createAndAbandonWeakRef(obj: NSObject) { WeakReference(obj) } ================================================ FILE: backend.native/tests/interop/objc/tests/workerAutoreleasePool.h ================================================ #import @interface CreateAutoreleaseDeallocated : NSObject @property BOOL value; @end; @interface CreateAutorelease : NSObject +(void)createAutorelease:(CreateAutoreleaseDeallocated*)deallocated; @end; ================================================ FILE: backend.native/tests/interop/objc/tests/workerAutoreleasePool.kt ================================================ import kotlin.native.concurrent.* import kotlinx.cinterop.* import kotlin.test.* import objcTests.* @Test fun testExecuteInMainPark() = test(Execute, InMain, Park) @Test fun testExecuteInMainProcessQueue() = test(Execute, InMain, ProcessQueue) @Test fun testExecuteInWorkerPark() = test(Execute, InWorker, Park) @Test fun testExecuteInWorkerProcessQueue() = test(Execute, InWorker, ProcessQueue) @Test fun testExecuteInMainToWorkerNoYield() = test(Execute, InMainToWorker, NoYield) @Test fun testExecuteAfter0InMainPark() = test(ExecuteAfter0, InMain, Park) @Test fun testExecuteAfter0InMainProcessQueue() = test(ExecuteAfter0, InMain, ProcessQueue) @Test fun testExecuteAfter0InWorkerPark() = test(ExecuteAfter0, InWorker, Park) @Test fun testExecuteAfter0InWorkerProcessQueue() = test(ExecuteAfter0, InWorker, ProcessQueue) @Test fun testExecuteAfter0InMainToWorkerNoYield() = test(ExecuteAfter0, InMainToWorker, NoYield) @Test fun testExecuteAfter10InMainPark() = testExecuteAfter10(InMain, Park) @Test fun testExecuteAfter10InMainProcessQueue() = testExecuteAfter10(InMain, ProcessQueue) @Test fun testExecuteAfter10InWorkerPark() = testExecuteAfter10(InWorker, Park) @Test fun testExecuteAfter10InWorkerProcessQueue() = testExecuteAfter10(InWorker, ProcessQueue) @Test fun testExecuteAfter10InMainToWorkerNoYield() = testExecuteAfter10(InMainToWorker, NoYield) private fun testExecuteAfter10(context: Context, yieldMethod: Yield) = test(ExecuteAfter10(yieldMethod), context, yieldMethod) private fun test(method: ExecuteMethod, context: Context, yieldMethod: Yield) { context.withWorker { worker -> fun execute(block: () -> Unit) { val future = method.submit(worker, block) yieldMethod.yield() method.wait(future) } val deallocated = CreateAutoreleaseDeallocated() execute { CreateAutorelease.createAutorelease(deallocated) // Object is still in autorelease pool: assertFalse(deallocated.value) } // autorelease pool is processed after the job is finished, so the object should be deallocated; // Checking in a job to make sure previous job is completely processed: execute { assertTrue(deallocated.value) } } } interface ExecuteMethod { fun submit(worker: Worker, block: () -> Unit): F fun wait(future: F) } object Execute : ExecuteMethod> { override fun submit(worker: Worker, block: () -> Unit) = worker.execute(TransferMode.SAFE, { block.freeze() }) { it() } override fun wait(future: Future) { future.result // Throws on failure. } } abstract class ExecuteAfter : ExecuteMethod> { abstract val timeout: Long abstract fun sleepAndYield() override fun submit(worker: Worker, block: () -> Unit): AtomicReference { val result = AtomicReference(null) worker.executeAfter(timeout, { try { block() result.value = true } catch (e: Throwable) { result.value = e.freeze() } }.freeze()) return result } override fun wait(future: AtomicReference) { while (true) { sleepAndYield() when (val it = future.value) { null -> continue true -> return else -> throw it as Throwable } } } } object ExecuteAfter0 : ExecuteAfter() { override val timeout = 0L override fun sleepAndYield() { // No sleep or additional yield required. } } class ExecuteAfter10(val yieldMethod: Yield) : ExecuteAfter() { override val timeout = 10L override fun sleepAndYield() { Worker.current.park(timeout + 1L, process = false) yieldMethod.yield() } } interface Context { fun withWorker(block: (worker: Worker) -> Unit) } object InMain : Context { override fun withWorker(block: (worker: Worker) -> Unit) = block(Worker.current) } object InMainToWorker : Context { override fun withWorker(block: (Worker) -> Unit) = kotlin.native.concurrent.withWorker { block(this) } } object InWorker : Context { override fun withWorker(block: (Worker) -> Unit) = kotlin.native.concurrent.withWorker { val method = Execute method.wait(method.submit(this) { block(this) }) } } interface Yield { fun yield() } object Park : Yield { override fun yield() { Worker.current.park(0L, process = true) } } object ProcessQueue : Yield { override fun yield() { Worker.current.processQueue() } } object NoYield : Yield { override fun yield() {} } ================================================ FILE: backend.native/tests/interop/objc/tests/workerAutoreleasePool.m ================================================ #import "workerAutoreleasePool.h" @implementation CreateAutoreleaseDeallocated @end; @implementation CreateAutorelease { CreateAutoreleaseDeallocated* deallocated; } +(instancetype)create:(CreateAutoreleaseDeallocated*)deallocated { CreateAutorelease* result = [self new]; result->deallocated = deallocated; return result; } +(void)createAutorelease:(CreateAutoreleaseDeallocated*)deallocated { [self create:deallocated]; } -(void)dealloc { deallocated.value = YES; } @end; ================================================ FILE: backend.native/tests/interop/objc_with_initializer/objc_misc.def ================================================ language = Objective-C headers = Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h headerFilter = **/objc_misc.h Foundation/NSArray.h Foundation/NSValue.h Foundation/NSString.h linkerOpts = -lobjcmisc ================================================ FILE: backend.native/tests/interop/objc_with_initializer/objc_misc.h ================================================ #include @interface A:NSObject @end @interface B:A +(A*)giveC; @end @interface C:A @end ================================================ FILE: backend.native/tests/interop/objc_with_initializer/objc_misc.m ================================================ #import #include "objc_misc.h" @implementation A @end @implementation B:A +(A*)giveC{ return [[C alloc] init]; } @end @implementation C:A @end #if 0 int main() { [B giveC]; } #endif ================================================ FILE: backend.native/tests/interop/objc_with_initializer/objc_test.kt ================================================ import objc_misc.* import kotlin.native.Platform val a = B.giveC()!! as C fun main() { Platform.isMemoryLeakCheckerActive = true println("OK") } ================================================ FILE: backend.native/tests/interop/platform_zlib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* import platform.zlib.* val source = immutableBlobOf(0xF3, 0x48, 0xCD, 0xC9, 0xC9, 0x57, 0x04, 0x00).asCPointer().reinterpret() val golden = immutableBlobOf(0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21, 0x00).asCPointer() fun main(args: Array) = memScoped { val buffer = ByteArray(32) buffer.usePinned { pinned -> val z = alloc().apply { next_in = source avail_in = 8u next_out = pinned.addressOf(0).reinterpret() avail_out = buffer.size.toUInt() }.ptr if (inflateInit2(z, -15) == Z_OK && inflate(z, Z_FINISH) == Z_STREAM_END && inflateEnd(z) == Z_OK) println(buffer.toKString()) } println(golden.toKString()) } ================================================ FILE: backend.native/tests/iosLauncher/.gitignore ================================================ xcuserdata ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "1x" }, { "idiom" : "ipad", "size" : "20x20", "scale" : "2x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" }, { "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher/Base.lproj/Main.storyboard ================================================ ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 6522238E98511C4FCE1C84DB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65222E77B9880A666F68B517 /* Main.storyboard */; }; 652225006B71BB79B6D0D726 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 652225CB5CBA03A47F5148C4 /* Assets.xcassets */; }; 65222623D2703AEFB363121F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6522214B5DB6829939E3F325 /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 65222402702E398002CC649E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = Info.plist; sourceTree = ""; }; 652225210978EC9016CB5EFF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 652225CB5CBA03A47F5148C4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 6522292479593142D11AD88A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65222B6AE5EB6447D2D3E6ED /* KonanTestLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KonanTestLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 65222DAFA15A9AB521E55317 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 65222113FD4C67E6BA46614D /* gradle */ = { isa = PBXGroup; children = ( 6522242531A4CAB63B2BFE71 /* wrapper */, ); path = gradle; sourceTree = ""; }; 6522238C8FBBB7F836D071CF /* KonanTestLauncher */ = { isa = PBXGroup; children = ( 65222402702E398002CC649E /* Info.plist */, 652225CB5CBA03A47F5148C4 /* Assets.xcassets */, 6522214B5DB6829939E3F325 /* LaunchScreen.storyboard */, 65222E77B9880A666F68B517 /* Main.storyboard */, ); path = KonanTestLauncher; sourceTree = ""; }; 65222469E9E3E627366829E9 /* src */ = { isa = PBXGroup; children = ( 65222A6C6191FBB233B995FB /* KonanTestLauncherMain */, ); path = src; sourceTree = ""; }; 652229EDCC8B5D981F51A0FE /* Products */ = { isa = PBXGroup; children = ( 65222B6AE5EB6447D2D3E6ED /* KonanTestLauncher.app */, ); name = Products; sourceTree = ""; }; 65222A6C6191FBB233B995FB /* KonanTestLauncherMain */ = { isa = PBXGroup; children = ( 65222B5F2F23FCBC77FE9C46 /* kotlin */, ); path = KonanTestLauncherMain; sourceTree = ""; }; 65222B5F2F23FCBC77FE9C46 /* kotlin */ = { isa = PBXGroup; children = ( ); path = kotlin; sourceTree = ""; }; 65222C68A5CC689D5AA66D3B = { isa = PBXGroup; children = ( 652229EDCC8B5D981F51A0FE /* Products */, 6522238C8FBBB7F836D071CF /* KonanTestLauncher */, ); sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 65222A26710249E058596147 /* KonanTestLauncher */ = { isa = PBXNativeTarget; buildConfigurationList = 6522285AF364E21A1540BD08 /* Build configuration list for PBXNativeTarget "KonanTestLauncher" */; buildPhases = ( 652225D77218699A3A7F6722 /* Sources */, 65222DAFA15A9AB521E55317 /* Frameworks */, 65222B3A6677E222C51FAFB8 /* Resources */, 65222EB12A851E15D756D3F8 /* Compile Kotlin/Native */, ); buildRules = ( ); dependencies = ( ); name = KonanTestLauncher; productName = KonanTestLauncher; productReference = 65222B6AE5EB6447D2D3E6ED /* KonanTestLauncher.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 65222D052D6D41A4EEFB4821 /* Project object */ = { isa = PBXProject; attributes = { CLASSPREFIX = ""; ORGANIZATIONNAME = jetbrains; TargetAttributes = { 65222A26710249E058596147 = { DevelopmentTeam = ""; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 6522294C3F904F562F8F0628 /* Build configuration list for PBXProject "KonanTestLauncher" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, en, Base, ); mainGroup = 65222C68A5CC689D5AA66D3B; productRefGroup = 652229EDCC8B5D981F51A0FE /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 65222A26710249E058596147 /* KonanTestLauncher */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 65222B3A6677E222C51FAFB8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 652225006B71BB79B6D0D726 /* Assets.xcassets in Resources */, 65222623D2703AEFB363121F /* LaunchScreen.storyboard in Resources */, 6522238E98511C4FCE1C84DB /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 65222EB12A851E15D756D3F8 /* Compile Kotlin/Native */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Compile Kotlin/Native"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; shellScript = "set -x\n\ncp \"$PROJECT_DIR/KonanTestLauncher/build/$TARGET_NAME.kexe\" \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 652225D77218699A3A7F6722 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 6522214B5DB6829939E3F325 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 652225210978EC9016CB5EFF /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; 65222E77B9880A666F68B517 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 6522292479593142D11AD88A /* Base */, ); name = Main.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 65222812DCD81B77CE1F15D9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; 65222AF1F63AE763ED0326E5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = KonanTestLauncher/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.kotlin.KonanTestLauncher; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = arm64; }; name = Debug; }; 65222BB9FE8C772F3939AE5A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; 65222EF46F1047DBF88CFC60 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = KonanTestLauncher/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.jetbrains.kotlin.KonanTestLauncher; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; TARGETED_DEVICE_FAMILY = "1,2"; VALID_ARCHS = arm64; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 6522285AF364E21A1540BD08 /* Build configuration list for PBXNativeTarget "KonanTestLauncher" */ = { isa = XCConfigurationList; buildConfigurations = ( 65222AF1F63AE763ED0326E5 /* Debug */, 65222EF46F1047DBF88CFC60 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 6522294C3F904F562F8F0628 /* Build configuration list for PBXProject "KonanTestLauncher" */ = { isa = XCConfigurationList; buildConfigurations = ( 65222BB9FE8C772F3939AE5A /* Debug */, 65222812DCD81B77CE1F15D9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 65222D052D6D41A4EEFB4821 /* Project object */; } ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: backend.native/tests/iosLauncher/KonanTestLauncher.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ BuildSystemType Original PreviewsEnabled ================================================ FILE: backend.native/tests/jsinterop/math.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.interop.wasm.math.* import kotlinx.wasm.jsinterop.* fun main(args: Array) { val e = Math.E val pi = Math.PI val sin_pi = Math.sin(pi) val sin_pi_2 = Math.sin(pi/2) val ln_1 = Math.log(1.0) val ln_e = Math.log(e) println("e = $e, pi = $pi, sin(pi) = $sin_pi, sin(pi/2) = $sin_pi_2, ln(1) = $ln_1, ln(e) = $ln_e") } ================================================ FILE: backend.native/tests/link/default/default.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.convert import platform.posix.* fun main(args: Array) { // Just check the typealias is in scope. val sizet: size_t = 0.convert() println("sizet = $sizet") } ================================================ FILE: backend.native/tests/link/fake_overrides/base.kt ================================================ package serialization.fake_overrides open class A { open fun qux() = "Super" open fun tic() = "Super" } ================================================ FILE: backend.native/tests/link/fake_overrides/main.kt ================================================ import serialization.fake_overrides.* fun test1() = println(Z().bar()) fun main() { test0() test1() test2() test3() } ================================================ FILE: backend.native/tests/link/fake_overrides/move.kt ================================================ package serialization.fake_overrides open class X { } class Y: X() { fun bar() = "Stale" } class B: A() { } class C: A() { override fun tic() = "Child" } ================================================ FILE: backend.native/tests/link/fake_overrides/move2.kt ================================================ package serialization.fake_overrides open class X { fun bar() = "Moved" } class Y: X() { } class B: A() { override fun qux() = "Child" } class C: A() { } ================================================ FILE: backend.native/tests/link/fake_overrides/use.kt ================================================ package serialization.fake_overrides class Z: X() { } fun test0() = println(Y().bar()) fun test2() = println(B().qux()) fun test3() = println(C().qux()) ================================================ FILE: backend.native/tests/link/ir_providers/hello.kt ================================================ fun main() = println("hello") ================================================ FILE: backend.native/tests/link/ir_providers/library/empty.kt ================================================ ================================================ FILE: backend.native/tests/link/ir_providers/library/manifest.properties ================================================ ir_provider=UNSUPPORTED ================================================ FILE: backend.native/tests/link/omit/hello.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { println("Hello") } ================================================ FILE: backend.native/tests/link/omit/lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package foo fun foo() {} ================================================ FILE: backend.native/tests/link/private_fake_overrides/inherit_lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // Private classes private open class A { public fun foo1() = println("PASS") internal fun foo2() = println("PASS") protected fun foo3() = println("PASS") } private class B:A() { fun foo4() = foo3() } // Private interfaces private interface C { fun foo() = println("PASS") } private class D: C fun runner() { B().foo1() B().foo2() B().foo4() D().foo() // Objects object : A(){ fun foo4() = foo3() }.apply { foo1() foo2() foo4() } // Function local classes abstract class E { public open fun foo1() = println("PASS") internal open fun foo2() = println("PASS") protected open fun foo3() = println("PASS") } class F : E() { fun foo4() = foo3() } F().foo1() F().foo2() F().foo4() } ================================================ FILE: backend.native/tests/link/private_fake_overrides/inherit_main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main() { runner() } ================================================ FILE: backend.native/tests/link/private_fake_overrides/override_lib.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // Private classes private open class A { public open fun foo1() = println("FAIL") internal open fun foo2() = println("FAIL") protected open fun foo3() = println("FAIL") private fun foo4() = println("FAIL") } private class B:A() { override public fun foo1() = println("PASS") override internal fun foo2() = println("PASS") override protected fun foo3() = println("PASS") private fun foo4() = println("PASS") fun foo5() = foo3() fun foo6() = foo4() } private abstract class G { public abstract fun foo1() internal abstract fun foo2() protected abstract fun foo3() private fun foo4() = println("FAIL") } private class H:A() { override public fun foo1() = println("PASS") override internal fun foo2() = println("PASS") override protected fun foo3() = println("PASS") private fun foo4() = println("PASS") fun foo5() = foo3() fun foo6() = foo4() } // Private interfaces private interface C { fun foo() = println("FAIL") } private class D: C { override fun foo() = println("PASS") } fun runner() { B().foo1() B().foo2() B().foo5() B().foo6() H().foo1() H().foo2() H().foo5() H().foo6() D().foo() // Objects object : A(){ override public fun foo1() = println("PASS") override internal fun foo2() = println("PASS") override protected fun foo3() = println("PASS") private fun foo4() = println("PASS") fun foo5() = foo3() fun foo6() = foo4() }.apply { foo1() foo2() foo5() foo6() } // Function local classes open class E { public open fun foo1() = println("FAIL") internal open fun foo2() = println("FAIL") protected open fun foo3() = println("FAIL") private fun foo4() = println("FAIL") } class F : E() { public override fun foo1() = println("PASS") internal override fun foo2() = println("PASS") protected override fun foo3() = println("PASS") private fun foo4() = println("PASS") fun foo5() = foo3() fun foo6() = foo4() } F().foo1() F().foo2() F().foo5() F().foo6() } ================================================ FILE: backend.native/tests/link/private_fake_overrides/override_main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main() { runner() } ================================================ FILE: backend.native/tests/link/purge1/lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.convert import platform.posix.* fun foo() { println("linked library") val size: size_t = 17.convert() val e = fabs(1.toDouble()) println("and symbols from posix available: $size; $e") } ================================================ FILE: backend.native/tests/link/purge1/prog.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { foo() } ================================================ FILE: backend.native/tests/link/src/bar.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import qwerty.* fun main(args: Array) { val size = foo(foo2(args.size)) println(size.toString()) } ================================================ FILE: backend.native/tests/link/versioning/empty.kt ================================================ /* This file has intentionally been left blank */ ================================================ FILE: backend.native/tests/link/versioning/hello.kt ================================================ fun main() { println("Hello, versioned world!") } ================================================ FILE: backend.native/tests/lower/immutable_blob_in_lambda.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package lower.immutable_blob_in_lambda import kotlin.test.* @Test fun runTest() = run { val golden = immutableBlobOf(123) println(golden[0]) } ================================================ FILE: backend.native/tests/lower/local_delegated_property_link/lib.kt ================================================ fun foo(): String{ val bar: String by lazy { "OK" } return bar } ================================================ FILE: backend.native/tests/lower/local_delegated_property_link/main.kt ================================================ fun main() { println(foo()) } ================================================ FILE: backend.native/tests/lower/tailrec.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package lower.tailrec fun main() { println(add(5, 7)) println(add(100000000, 0)) println(fib(6)) println(one(5)) countdown(3) println(listOf(1, 2, 3).indexOf(3)) println(listOf(1, 2, 3).indexOf(4)) println(Integer(5).isLessOrEqualThan(7)) println(Integer(42).isLessOrEqualThan(1)) println(DefaultArgGetter().foo("non-default")) println(EitherDelegatedOrNot(NotDelegated()).get42()) } tailrec fun add(x: Int, y: Int): Int = if (x > 0) add(x - 1, y + 1) else y fun fib(n: Int): Int { tailrec fun fibAcc(n: Int, acc: Int): Int = if (n < 2) { n + acc } else { fibAcc(n - 1, fibAcc(n - 2, acc)) } return fibAcc(n, 0) } tailrec fun one(delay: Int, result: Int = delay + 1): Int = if (delay > 0) one(delay - 1) else result tailrec fun countdown(iterations: Int): Unit { if (iterations > 0) { println("$iterations ...") countdown(iterations - 1) } else { println("ready!") } } tailrec fun List.indexOf(x: T, startIndex: Int = 0): Int { if (startIndex >= this.size) { return -1 } if (this[startIndex] != x) { return this.indexOf(x, startIndex + 1) } return startIndex } open class Integer(val value: Int) { open tailrec fun isLessOrEqualThan(value: Int): Boolean { if (this.value == value) { return true } else if (value > 0) { return this.isLessOrEqualThan(value - 1) } else { return false } } } open class DefaultArgHolder { open fun foo(s: String = "default") = s } class DefaultArgGetter : DefaultArgHolder() { override tailrec fun foo(s: String): String { return if (s == "default") s else foo() } } open class EitherDelegatedOrNot(val delegate: EitherDelegatedOrNot?) { open tailrec fun get42(): Int = if (delegate != null) { delegate.get42() } else { throw Error() } } class NotDelegated : EitherDelegatedOrNot(null) { override fun get42() = 42 } ================================================ FILE: backend.native/tests/lower/vararg.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package lower.vararg import kotlin.test.* fun foo(vararg x: Any?) {} fun bar() = foo() @Test fun runTest() { bar() } ================================================ FILE: backend.native/tests/lower/vararg_of_literals.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package lower.vararg_of_literals import kotlin.test.* @Test fun runTest() { foo() foo() } fun foo() { val array = arrayOf("a", "b") println(array[0]) array[0] = "42" } ================================================ FILE: backend.native/tests/mangling/mangling.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun test_direct() { val mutListInt = mutableListOf(1, 2, 3, 4) val mutListNum = mutableListOf(9, 10, 11, 12) val mutListAny = mutableListOf(5, 6, 7, 8) mangle1(mutListInt) mangle1(mutListNum) mangle1(mutListAny) } fun test_param() { val mutListInt = mutableListOf(1, 2, 3, 4) val mutListNum = mutableListOf(9, 10, 11, 12) val mutListAny = mutableListOf(5, 6, 7, 8) mangle2(mutListInt) mangle2(mutListNum) mangle2(mutListAny) } fun test_multiple_constructors() { val any = mapOf() val comparable = "some string" val number = 17 mangle3(any) mangle3(comparable) mangle3(number) } fun main(args: Array) { test_direct() test_param() test_multiple_constructors() } ================================================ FILE: backend.native/tests/mangling/manglinglib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ public fun mangle1(l: List) { println("Int direct $l") } public fun mangle1(l: List) { println("out Number direct $l") } public fun mangle1(l: List<*>) { println("star direct $l") } public fun mangle2(l: T) where T: List { println("Int param $l") } public fun mangle2(l: T) where T: List { println("out Number param $l") } public fun mangle2(l: T) where T: List<*> { println("star param $l") } public fun mangle3(l: T) { println("no constructors $l") } public fun mangle3(l: T) where T: Comparable { println("single constructor $l") } public fun mangle3(l: T) where T: Comparable, T: Number { println("two constructors $l") } ================================================ FILE: backend.native/tests/objcexport/coroutines.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package coroutines import kotlin.coroutines.* import kotlin.coroutines.cancellation.CancellationException import kotlin.coroutines.intrinsics.* import kotlin.native.concurrent.isFrozen import kotlin.native.internal.ObjCErrorException import kotlin.test.* class CoroutineException : Throwable() suspend fun suspendFun() = 42 @Throws(CoroutineException::class, CancellationException::class) suspend fun suspendFun(result: Any?, doSuspend: Boolean, doThrow: Boolean): Any? { if (doSuspend) { suspendCoroutineUninterceptedOrReturn { it.resume(Unit) COROUTINE_SUSPENDED } } if (doThrow) throw CoroutineException() return result } class ContinuationHolder { internal lateinit var continuation: Continuation fun resume(value: T) { continuation.resume(value) } fun resumeWithException(exception: Throwable) { continuation.resumeWithException(exception) } } @Throws(CoroutineException::class, CancellationException::class) suspend fun suspendFunAsync(result: Any?, continuationHolder: ContinuationHolder): Any? = suspendCoroutineUninterceptedOrReturn { continuationHolder.continuation = it COROUTINE_SUSPENDED } ?: result @Throws(CoroutineException::class, CancellationException::class) fun throwException(exception: Throwable) { throw exception } interface SuspendFun { @Throws(CoroutineException::class, CancellationException::class) suspend fun suspendFun(doYield: Boolean, doThrow: Boolean): Int } class ResultHolder { var completed: Int = 0 var result: T? = null var exception: Throwable? = null internal fun complete(result: Result) { this.result = result.getOrNull() this.exception = result.exceptionOrNull() this.completed += 1 } } private class ResultHolderCompletion(val resultHolder: ResultHolder) : Continuation { override val context: CoroutineContext get() = EmptyCoroutineContext override fun resumeWith(result: Result) { resultHolder.complete(result) } } fun callSuspendFun(suspendFun: SuspendFun, doYield: Boolean, doThrow: Boolean, resultHolder: ResultHolder) { suspend { suspendFun.suspendFun(doYield = doYield, doThrow = doThrow) } .startCoroutine(ResultHolderCompletion(resultHolder)) } @Throws(CoroutineException::class, CancellationException::class) suspend fun callSuspendFun2(suspendFun: SuspendFun, doYield: Boolean, doThrow: Boolean): Int { return suspendFun.suspendFun(doYield = doYield, doThrow = doThrow) } interface SuspendBridge { suspend fun int(value: T): Int suspend fun intAsAny(value: T): Any? suspend fun unit(value: T): Unit suspend fun unitAsAny(value: T): Any? @Throws(Throwable::class) suspend fun nothing(value: T): Nothing @Throws(Throwable::class) suspend fun nothingAsInt(value: T): Int @Throws(Throwable::class) suspend fun nothingAsAny(value: T): Any? @Throws(Throwable::class) suspend fun nothingAsUnit(value: T): Unit } abstract class AbstractSuspendBridge : SuspendBridge { override suspend fun intAsAny(value: Int): Int = TODO() override suspend fun unitAsAny(value: Int): Unit = TODO() override suspend fun nothingAsInt(value: Int): Nothing = TODO() override suspend fun nothingAsAny(value: Int): Nothing = TODO() override suspend fun nothingAsUnit(value: Int): Nothing = TODO() } private suspend fun callSuspendBridgeImpl(bridge: SuspendBridge) { assertEquals(1, bridge.intAsAny(1)) assertSame(Unit, bridge.unitAsAny(2)) assertFailsWith { bridge.nothingAsInt(3) } assertFailsWith { bridge.nothingAsAny(4) } assertFailsWith { bridge.nothingAsUnit(5) } } private suspend fun callAbstractSuspendBridgeImpl(bridge: AbstractSuspendBridge) { assertEquals(6, bridge.intAsAny(6)) assertSame(Unit, bridge.unitAsAny(7)) assertFailsWith { bridge.nothingAsInt(8) } assertFailsWith { bridge.nothingAsAny(9) } assertFailsWith { bridge.nothingAsUnit(10) } } @Throws(Throwable::class) fun callSuspendBridge(bridge: AbstractSuspendBridge, resultHolder: ResultHolder) { suspend { callSuspendBridgeImpl(bridge) callAbstractSuspendBridgeImpl(bridge) }.startCoroutine(ResultHolderCompletion(resultHolder)) } suspend fun throwCancellationException(): Unit { val exception = CancellationException("coroutine is cancelled") // Note: frontend checker hardcodes fq names of CancellationException super classes (see NativeThrowsChecker). // This is our best effort to keep that list in sync with actual stdlib code: assertTrue(exception is kotlin.Throwable) assertTrue(exception is kotlin.Exception) assertTrue(exception is kotlin.RuntimeException) assertTrue(exception is kotlin.IllegalStateException) assertTrue(exception is kotlin.coroutines.cancellation.CancellationException) throw exception } abstract class ThrowCancellationException { internal abstract suspend fun throwCancellationException() } class ThrowCancellationExceptionImpl : ThrowCancellationException() { public override suspend fun throwCancellationException() { throw CancellationException() } } fun getSuspendLambda0(): suspend () -> String = { "lambda 0" } private suspend fun suspendCallableReference0Target(): String = "callable reference 0" fun getSuspendCallableReference0(): suspend () -> String = ::suspendCallableReference0Target fun getSuspendLambda1(): suspend (String) -> String = { "$it 1" } private suspend fun suspendCallableReference1Target(str: String): String = "$str 1" fun getSuspendCallableReference1(): suspend (String) -> String = ::suspendCallableReference1Target suspend fun invoke1(block: suspend (Any?) -> Any?, argument: Any?): Any? = block(argument) ================================================ FILE: backend.native/tests/objcexport/coroutines.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private func testCallSimple() throws { var result: KotlinInt? = nil var error: Error? = nil var completionCalled = 0 CoroutinesKt.suspendFun { _result, _error in completionCalled += 1 result = _result error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertEquals(actual: result, expected: 42) try assertNil(error) } private func testCallSuspendFun(doSuspend: Bool, doThrow: Bool) throws { class C {} let expectedResult = C() var completionCalled = 0 var result: AnyObject? = nil var error: Error? = nil CoroutinesKt.suspendFun(result: expectedResult, doSuspend: doSuspend, doThrow: doThrow) { _result, _error in completionCalled += 1 result = _result as AnyObject? error = _error } try assertEquals(actual: completionCalled, expected: 1) if doThrow { try assertNil(result) try assertTrue(error?.kotlinException is CoroutineException) } else { try assertSame(actual: result, expected: expectedResult) try assertNil(error) } } private func testSuspendFuncAsync(doThrow: Bool) throws { var completionCalled = 0 var result: AnyObject? = nil var error: Error? = nil #if NO_GENERICS let continuationHolder = ContinuationHolder() #else let continuationHolder = ContinuationHolder() #endif CoroutinesKt.suspendFunAsync(result: nil, continuationHolder: continuationHolder) { _result, _error in completionCalled += 1 result = _result as AnyObject? error = _error } try assertEquals(actual: completionCalled, expected: 0) if doThrow { let exception = CoroutineException() continuationHolder.resumeWithException(exception: exception) try assertEquals(actual: completionCalled, expected: 1) try assertNil(result) try assertSame(actual: error?.kotlinException as AnyObject?, expected: exception) } else { class C {} let expectedResult = C() continuationHolder.resume(value: expectedResult) try assertEquals(actual: completionCalled, expected: 1) try assertSame(actual: result, expected: expectedResult) try assertNil(error) } } private func testCall() throws { try testCallSuspendFun(doSuspend: true, doThrow: false) try testCallSuspendFun(doSuspend: false, doThrow: false) try testCallSuspendFun(doSuspend: true, doThrow: true) try testCallSuspendFun(doSuspend: false, doThrow: true) try testSuspendFuncAsync(doThrow: false) try testSuspendFuncAsync(doThrow: true) } private class SuspendFunImpl : SuspendFun { class E : Error {} var completion: (() -> Void)? = nil func suspendFun(doYield: Bool, doThrow: Bool, completionHandler: @escaping (KotlinInt?, Error?) -> Void) { func callCompletion() { if doThrow { completionHandler(nil, E()) } else { completionHandler(17, nil) } } if doYield { self.completion = callCompletion } else { callCompletion() } } } private func testSuspendFunImpl(doYield: Bool, doThrow: Bool) throws { #if NO_GENERICS let resultHolder = ResultHolder() #else let resultHolder = ResultHolder() #endif let impl = SuspendFunImpl() CoroutinesKt.callSuspendFun( suspendFun: impl, doYield: doYield, doThrow: doThrow, resultHolder: resultHolder ) if doYield { try assertEquals(actual: resultHolder.completed, expected: 0) guard let completion = impl.completion else { try fail() } completion() } try assertEquals(actual: resultHolder.completed, expected: 1) if doThrow { try assertNil(resultHolder.result) if let e = resultHolder.exception { try assertFailsWith(SuspendFunImpl.E.self) { try CoroutinesKt.throwException(exception: e) } } else { try fail() } } else { try assertEquals(actual: resultHolder.result as! Int, expected: 17) try assertNil(resultHolder.exception) } } private func testSuspendFunImpl2(doYield: Bool, doThrow: Bool) throws { let impl = SuspendFunImpl() var completionCalled = 0 var result: KotlinInt? = nil var error: Error? = nil CoroutinesKt.callSuspendFun2(suspendFun: impl, doYield: doYield, doThrow: doThrow) { _result, _error in completionCalled += 1 result = _result error = _error } if doYield { try assertEquals(actual: completionCalled, expected: 0) guard let completion = impl.completion else { try fail() } completion() } try assertEquals(actual: completionCalled, expected: 1) if doThrow { try assertNil(result) try assertTrue(error is SuspendFunImpl.E) } else { try assertEquals(actual: result, expected: 17) try assertNil(error) } } private func testOverride() throws { try testSuspendFunImpl(doYield: false, doThrow: false) try testSuspendFunImpl(doYield: false, doThrow: true) try testSuspendFunImpl(doYield: true, doThrow: false) try testSuspendFunImpl(doYield: true, doThrow: true) try testSuspendFunImpl2(doYield: false, doThrow: false) try testSuspendFunImpl2(doYield: false, doThrow: true) try testSuspendFunImpl2(doYield: true, doThrow: false) try testSuspendFunImpl2(doYield: true, doThrow: true) } private class SwiftSuspendBridge : AbstractSuspendBridge { class E : Error {} override func intAsAny(value: KotlinInt, completionHandler: @escaping (KotlinInt?, Error?) -> Void) { completionHandler(value, nil) } override func unitAsAny(value: KotlinInt, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) { completionHandler(KotlinUnit(), nil) } override func nothingAsInt(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) { completionHandler(nil, E()) } override func nothingAsAny(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) { completionHandler(nil, E()) } override func nothingAsUnit(value: KotlinInt, completionHandler: @escaping (KotlinNothing?, Error?) -> Void) { completionHandler(nil, E()) } } private func testBridges() throws { #if NO_GENERICS let resultHolder = ResultHolder() #else let resultHolder = ResultHolder() #endif try CoroutinesKt.callSuspendBridge(bridge: SwiftSuspendBridge(), resultHolder: resultHolder) try assertEquals(actual: resultHolder.completed, expected: 1) try assertNil(resultHolder.exception) try assertSame(actual: resultHolder.result as AnyObject, expected: KotlinUnit()) } private func testImplicitThrows1() throws { var result: KotlinUnit? = nil var error: Error? = nil var completionCalled = 0 CoroutinesKt.throwCancellationException { _result, _error in completionCalled += 1 result = _result error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertNil(result) try assertTrue(error?.kotlinException is KotlinCancellationException) } private func testImplicitThrows2() throws { var result: KotlinUnit? = nil var error: Error? = nil var completionCalled = 0 ThrowCancellationExceptionImpl().throwCancellationException { _result, _error in completionCalled += 1 result = _result error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertNil(result) try assertTrue(error?.kotlinException is KotlinCancellationException) } private func testSuspendFunctionType0(f: KotlinSuspendFunction0, expectedResult: String) throws { try assertTrue((f as AnyObject) is KotlinSuspendFunction0) var result: String? = nil var error: Error? = nil var completionCalled = 0 f.invoke { _result, _error in completionCalled += 1 result = _result as? String error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertEquals(actual: result, expected: expectedResult) try assertNil(error) } private func testSuspendFunctionType1(f: KotlinSuspendFunction1) throws { try assertTrue((f as AnyObject) is KotlinSuspendFunction1) var result: String? = nil var error: Error? = nil var completionCalled = 0 f.invoke(p1: "suspend function type") { _result, _error in completionCalled += 1 result = _result as? String error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertEquals(actual: result, expected: "suspend function type 1") try assertNil(error) } private func testSuspendFunctionType() throws { try testSuspendFunctionType0(f: CoroutinesKt.getSuspendLambda0(), expectedResult: "lambda 0") try testSuspendFunctionType0(f: CoroutinesKt.getSuspendCallableReference0(), expectedResult: "callable reference 0") try testSuspendFunctionType1(f: CoroutinesKt.getSuspendLambda1()) try testSuspendFunctionType1(f: CoroutinesKt.getSuspendCallableReference1()) } private func testSuspendFunctionSwiftImpl() throws { var result: String? = nil var error: Error? = nil var completionCalled = 0 CoroutinesKt.invoke1(block: SuspendFunction1SwiftImpl(), argument: "suspend function") { _result, _error in completionCalled += 1 result = _result as? String error = _error } try assertEquals(actual: completionCalled, expected: 1) try assertEquals(actual: result, expected: "suspend function Swift") try assertNil(error) } private class SuspendFunction1SwiftImpl : KotlinSuspendFunction1 { func invoke(p1: Any?, completionHandler: (Any?, Error?) -> Void) { completionHandler("\(p1 ?? "nil") Swift", nil) } } class CoroutinesTests : SimpleTestProvider { override init() { super.init() test("TestCallSimple", testCallSimple) test("TestCall", testCall) test("TestOverride", testOverride) test("TestBridges", testBridges) test("TestImplicitThrows1", testImplicitThrows1) test("TestImplicitThrows2", testImplicitThrows2) test("TestSuspendFunctionType", testSuspendFunctionType) test("TestSuspendFunctionSwiftImpl", testSuspendFunctionSwiftImpl) } } ================================================ FILE: backend.native/tests/objcexport/deallocRetain.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package deallocretain open class DeallocRetainBase fun garbageCollect() = kotlin.native.internal.GC.collect() fun createWeakReference(value: Any) = kotlin.native.ref.WeakReference(value) ================================================ FILE: backend.native/tests/objcexport/deallocRetain.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt // Note: these tests rely on GC assertions: without the fix and the assertions it won't actually crash. // GC should fire an assertion if it obtains a reference to Kotlin object that is being (or has been) deallocated. private func test1() throws { // Attempt to make the state predictable: DeallocRetainKt.garbageCollect() DeallocRetain.deallocated = false try assertFalse(DeallocRetain.deallocated) try autoreleasepool { let obj = DeallocRetain() try obj.checkWeak() } // Runs DeallocRetain.deinit: DeallocRetainKt.garbageCollect() try assertTrue(DeallocRetain.deallocated) // Might crash due to double-dispose if the dealloc applied addRef/releaseRef to reclaimed Kotlin object: DeallocRetainKt.garbageCollect() } private class DeallocRetain : DeallocRetainBase { static var deallocated = false static var retainObject: DeallocRetain? = nil static weak var weakObject: DeallocRetain? = nil #if NO_GENERICS static var kotlinWeakRef: KotlinWeakReference? = nil #else static var kotlinWeakRef: KotlinWeakReference? = nil #endif override init() { super.init() DeallocRetain.weakObject = self DeallocRetain.kotlinWeakRef = DeallocRetainKt.createWeakReference(value: self) } func checkWeak() throws { try assertSame(actual: DeallocRetain.weakObject, expected: self) try assertSame(actual: DeallocRetain.kotlinWeakRef!.value as AnyObject, expected: self) } deinit { DeallocRetain.retainObject = self DeallocRetain.retainObject = nil try! assertNil(DeallocRetain.weakObject) try! assertNil(DeallocRetain.kotlinWeakRef!.value) try! assertFalse(DeallocRetain.deallocated) DeallocRetain.deallocated = true } } class DeallocRetainTests : SimpleTestProvider { override init() { super.init() test("Test1", test1) } } ================================================ FILE: backend.native/tests/objcexport/enumValues.kt ================================================ package enumValues enum class EnumLeftRightUpDown { LEFT, RIGHT, UP, DOWN } enum class EnumOneTwoThreeValues { ONE, TWO, THREE, VALUES } enum class EnumValuesValues_ { VALUES, VALUES_ } enum class EmptyEnum { } ================================================ FILE: backend.native/tests/objcexport/enumValues.swift ================================================ import Kt private func testEnumValues() throws { let values = EnumLeftRightUpDown.values() try assertEquals(actual: values.size, expected: 4) try assertSame(actual: values.get(index: 0) as AnyObject, expected: EnumLeftRightUpDown.left) try assertSame(actual: values.get(index: 1) as AnyObject, expected: EnumLeftRightUpDown.right) try assertSame(actual: values.get(index: 2) as AnyObject, expected: EnumLeftRightUpDown.up) try assertSame(actual: values.get(index: 3) as AnyObject, expected: EnumLeftRightUpDown.down) } private func testEnumValuesMangled() throws { let values = EnumOneTwoThreeValues.values_() try assertEquals(actual: values.size, expected: 4) try assertSame(actual: values.get(index: 0) as AnyObject, expected: EnumOneTwoThreeValues.one) try assertSame(actual: values.get(index: 1) as AnyObject, expected: EnumOneTwoThreeValues.two) try assertSame(actual: values.get(index: 2) as AnyObject, expected: EnumOneTwoThreeValues.three) try assertSame(actual: values.get(index: 3) as AnyObject, expected: EnumOneTwoThreeValues.values) } private func testEnumValuesMangledTwice() throws { let values = EnumValuesValues_.values__() try assertEquals(actual: values.size, expected: 2) try assertSame(actual: values.get(index: 0) as AnyObject, expected: EnumValuesValues_.values) try assertSame(actual: values.get(index: 1) as AnyObject, expected: EnumValuesValues_.values_) } private func testEnumValuesEmpty() throws { try assertEquals(actual: EmptyEnum.values().size, expected: 0) } class EnumValuesTests : SimpleTestProvider { override init() { super.init() test("TestEnumValues", testEnumValues) test("TestEnumValuesMangled", testEnumValuesMangled) test("TestEnumValuesMangledTwice", testEnumValuesMangledTwice) test("TestEnumValuesEmpty", testEnumValuesEmpty) } } ================================================ FILE: backend.native/tests/objcexport/expectedLazy.h ================================================ __attribute__((swift_name("KotlinBase"))) @interface KtBase : NSObject - (instancetype)init __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (void)initialize __attribute__((objc_requires_super)); @end; @interface KtBase (KtBaseCopying) @end; __attribute__((swift_name("KotlinMutableSet"))) @interface KtMutableSet : NSMutableSet @end; __attribute__((swift_name("KotlinMutableDictionary"))) @interface KtMutableDictionary : NSMutableDictionary @end; @interface NSError (NSErrorKtKotlinException) @property (readonly) id _Nullable kotlinException; @end; __attribute__((swift_name("KotlinNumber"))) @interface KtNumber : NSNumber - (instancetype)initWithChar:(char)value __attribute__((unavailable)); - (instancetype)initWithUnsignedChar:(unsigned char)value __attribute__((unavailable)); - (instancetype)initWithShort:(short)value __attribute__((unavailable)); - (instancetype)initWithUnsignedShort:(unsigned short)value __attribute__((unavailable)); - (instancetype)initWithInt:(int)value __attribute__((unavailable)); - (instancetype)initWithUnsignedInt:(unsigned int)value __attribute__((unavailable)); - (instancetype)initWithLong:(long)value __attribute__((unavailable)); - (instancetype)initWithUnsignedLong:(unsigned long)value __attribute__((unavailable)); - (instancetype)initWithLongLong:(long long)value __attribute__((unavailable)); - (instancetype)initWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable)); - (instancetype)initWithFloat:(float)value __attribute__((unavailable)); - (instancetype)initWithDouble:(double)value __attribute__((unavailable)); - (instancetype)initWithBool:(BOOL)value __attribute__((unavailable)); - (instancetype)initWithInteger:(NSInteger)value __attribute__((unavailable)); - (instancetype)initWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable)); + (instancetype)numberWithChar:(char)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedChar:(unsigned char)value __attribute__((unavailable)); + (instancetype)numberWithShort:(short)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedShort:(unsigned short)value __attribute__((unavailable)); + (instancetype)numberWithInt:(int)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedInt:(unsigned int)value __attribute__((unavailable)); + (instancetype)numberWithLong:(long)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedLong:(unsigned long)value __attribute__((unavailable)); + (instancetype)numberWithLongLong:(long long)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable)); + (instancetype)numberWithFloat:(float)value __attribute__((unavailable)); + (instancetype)numberWithDouble:(double)value __attribute__((unavailable)); + (instancetype)numberWithBool:(BOOL)value __attribute__((unavailable)); + (instancetype)numberWithInteger:(NSInteger)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable)); @end; __attribute__((swift_name("KotlinByte"))) @interface KtByte : KtNumber - (instancetype)initWithChar:(char)value; + (instancetype)numberWithChar:(char)value; @end; __attribute__((swift_name("KotlinUByte"))) @interface KtUByte : KtNumber - (instancetype)initWithUnsignedChar:(unsigned char)value; + (instancetype)numberWithUnsignedChar:(unsigned char)value; @end; __attribute__((swift_name("KotlinShort"))) @interface KtShort : KtNumber - (instancetype)initWithShort:(short)value; + (instancetype)numberWithShort:(short)value; @end; __attribute__((swift_name("KotlinUShort"))) @interface KtUShort : KtNumber - (instancetype)initWithUnsignedShort:(unsigned short)value; + (instancetype)numberWithUnsignedShort:(unsigned short)value; @end; __attribute__((swift_name("KotlinInt"))) @interface KtInt : KtNumber - (instancetype)initWithInt:(int)value; + (instancetype)numberWithInt:(int)value; @end; __attribute__((swift_name("KotlinUInt"))) @interface KtUInt : KtNumber - (instancetype)initWithUnsignedInt:(unsigned int)value; + (instancetype)numberWithUnsignedInt:(unsigned int)value; @end; __attribute__((swift_name("KotlinLong"))) @interface KtLong : KtNumber - (instancetype)initWithLongLong:(long long)value; + (instancetype)numberWithLongLong:(long long)value; @end; __attribute__((swift_name("KotlinULong"))) @interface KtULong : KtNumber - (instancetype)initWithUnsignedLongLong:(unsigned long long)value; + (instancetype)numberWithUnsignedLongLong:(unsigned long long)value; @end; __attribute__((swift_name("KotlinFloat"))) @interface KtFloat : KtNumber - (instancetype)initWithFloat:(float)value; + (instancetype)numberWithFloat:(float)value; @end; __attribute__((swift_name("KotlinDouble"))) @interface KtDouble : KtNumber - (instancetype)initWithDouble:(double)value; + (instancetype)numberWithDouble:(double)value; @end; __attribute__((swift_name("KotlinBoolean"))) @interface KtBoolean : KtNumber - (instancetype)initWithBool:(BOOL)value; + (instancetype)numberWithBool:(BOOL)value; @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CoroutineException"))) @interface KtCoroutineException : KtKotlinThrowable - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ContinuationHolder"))) @interface KtContinuationHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)resumeValue:(T _Nullable)value __attribute__((swift_name("resume(value:)"))); - (void)resumeWithExceptionException:(KtKotlinThrowable *)exception __attribute__((swift_name("resumeWithException(exception:)"))); @end; __attribute__((swift_name("SuspendFun"))) @protocol KtSuspendFun @required /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)suspendFunDoYield:(BOOL)doYield doThrow:(BOOL)doThrow completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(doYield:doThrow:completionHandler:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ResultHolder"))) @interface KtResultHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property int32_t completed __attribute__((swift_name("completed"))); @property T _Nullable result __attribute__((swift_name("result"))); @property KtKotlinThrowable * _Nullable exception __attribute__((swift_name("exception"))); @end; __attribute__((swift_name("SuspendBridge"))) @protocol KtSuspendBridge @required /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intValue:(id _Nullable)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("int(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothing(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsIntValue:(id _Nullable)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsInt(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)"))); @end; __attribute__((swift_name("AbstractSuspendBridge"))) @interface KtAbstractSuspendBridge : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsIntValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsInt(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)"))); @end; __attribute__((swift_name("ThrowCancellationException"))) @interface KtThrowCancellationException : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ThrowCancellationExceptionImpl"))) @interface KtThrowCancellationExceptionImpl : KtThrowCancellationException - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CoroutinesKt"))) @interface KtCoroutinesKt : KtBase /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)throwExceptionException:(KtKotlinThrowable *)exception error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("throwException(exception:)"))); + (void)callSuspendFunSuspendFun:(id)suspendFun doYield:(BOOL)doYield doThrow:(BOOL)doThrow resultHolder:(KtResultHolder *)resultHolder __attribute__((swift_name("callSuspendFun(suspendFun:doYield:doThrow:resultHolder:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)callSuspendFun2SuspendFun:(id)suspendFun doYield:(BOOL)doYield doThrow:(BOOL)doThrow completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("callSuspendFun2(suspendFun:doYield:doThrow:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)callSuspendBridgeBridge:(KtAbstractSuspendBridge *)bridge resultHolder:(KtResultHolder *)resultHolder error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callSuspendBridge(bridge:resultHolder:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)"))); + (id)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()"))); + (id)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()"))); + (id)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()"))); + (id)getSuspendCallableReference1 __attribute__((swift_name("getSuspendCallableReference1()"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)invoke1Block:(id)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)"))); @end; __attribute__((swift_name("DeallocRetainBase"))) @interface KtDeallocRetainBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DeallocRetainKt"))) @interface KtDeallocRetainKt : KtBase + (void)garbageCollect __attribute__((swift_name("garbageCollect()"))); + (KtKotlinWeakReference *)createWeakReferenceValue:(id)value __attribute__((swift_name("createWeakReference(value:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumLeftRightUpDown"))) @interface KtEnumLeftRightUpDown : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumLeftRightUpDown *left __attribute__((swift_name("left"))); @property (class, readonly) KtEnumLeftRightUpDown *right __attribute__((swift_name("right"))); @property (class, readonly) KtEnumLeftRightUpDown *up __attribute__((swift_name("up"))); @property (class, readonly) KtEnumLeftRightUpDown *down __attribute__((swift_name("down"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumOneTwoThreeValues"))) @interface KtEnumOneTwoThreeValues : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumOneTwoThreeValues *one __attribute__((swift_name("one"))); @property (class, readonly) KtEnumOneTwoThreeValues *two __attribute__((swift_name("two"))); @property (class, readonly) KtEnumOneTwoThreeValues *three __attribute__((swift_name("three"))); @property (class, readonly) KtEnumOneTwoThreeValues *values __attribute__((swift_name("values"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumValuesValues_"))) @interface KtEnumValuesValues_ : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EmptyEnum"))) @interface KtEmptyEnum : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((swift_name("FunInterface"))) @protocol KtFunInterface @required - (int32_t)run __attribute__((swift_name("run()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FunInterfacesKt"))) @interface KtFunInterfacesKt : KtBase + (id)getObject __attribute__((swift_name("getObject()"))); + (id)getLambda __attribute__((swift_name("getLambda()"))); @end; __attribute__((swift_name("FHolder"))) @interface KtFHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) id _Nullable value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F2Holder"))) @interface KtF2Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable) __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F32Holder"))) @interface KtF32Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable) __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F33Holder"))) @interface KtF33Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FunctionalTypesKt"))) @interface KtFunctionalTypesKt : KtBase + (void)callDynType2List:(NSArray *)list param:(id _Nullable)param __attribute__((swift_name("callDynType2(list:param:)"))); + (void)callStaticType2Fct:(id _Nullable (^)(id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType2(fct:param:)"))); + (void)callDynType32List:(NSArray *)list param:(id _Nullable)param __attribute__((swift_name("callDynType32(list:param:)"))); + (void)callStaticType32Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType32(fct:param:)"))); + (void)callDynType33List:(NSArray> *)list param:(id _Nullable)param __attribute__((swift_name("callDynType33(list:param:)"))); + (void)callStaticType33Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType33(fct:param:)"))); + (KtF2Holder *)getDynTypeLambda2 __attribute__((swift_name("getDynTypeLambda2()"))); + (id _Nullable (^)(id _Nullable, id _Nullable))getStaticLambda2 __attribute__((swift_name("getStaticLambda2()"))); + (KtF2Holder *)getDynTypeRef2 __attribute__((swift_name("getDynTypeRef2()"))); + (id _Nullable (^)(id _Nullable, id _Nullable))getStaticRef2 __attribute__((swift_name("getStaticRef2()"))); + (KtF32Holder *)getDynType32 __attribute__((swift_name("getDynType32()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticType32 __attribute__((swift_name("getStaticType32()"))); + (KtF33Holder *)getDynTypeRef33 __attribute__((swift_name("getDynTypeRef33()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeRef33 __attribute__((swift_name("getStaticTypeRef33()"))); + (KtF33Holder *)getDynTypeLambda33 __attribute__((swift_name("getDynTypeLambda33()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeLambda33 __attribute__((swift_name("getStaticTypeLambda33()"))); @end; __attribute__((swift_name("GH4002ArgumentBase"))) @interface KtGH4002ArgumentBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH4002Argument"))) @interface KtGH4002Argument : KtGH4002ArgumentBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarning"))) @interface KtTestIncompatiblePropertyTypeWarning : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarningGeneric"))) @interface KtTestIncompatiblePropertyTypeWarningGeneric : KtBase - (instancetype)initWithValue:(T _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); @property (readonly) T _Nullable value __attribute__((swift_name("value"))); @end; __attribute__((swift_name("TestIncompatiblePropertyTypeWarningInterfaceWithGenericProperty"))) @protocol KtTestIncompatiblePropertyTypeWarningInterfaceWithGenericProperty @required @property (readonly) KtTestIncompatiblePropertyTypeWarningGeneric *p __attribute__((swift_name("p"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarning.ClassOverridingInterfaceWithGenericProperty"))) @interface KtTestIncompatiblePropertyTypeWarningClassOverridingInterfaceWithGenericProperty : KtBase - (instancetype)initWithP:(KtTestIncompatiblePropertyTypeWarningGeneric *)p __attribute__((swift_name("init(p:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestIncompatiblePropertyTypeWarningGeneric *p __attribute__((swift_name("p"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992"))) @interface KtTestGH3992 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestGH3992.C"))) @interface KtTestGH3992C : KtBase - (instancetype)initWithA:(KtTestGH3992A *)a __attribute__((swift_name("init(a:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestGH3992A *a __attribute__((swift_name("a"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992.D"))) @interface KtTestGH3992D : KtTestGH3992C - (instancetype)initWithA:(KtTestGH3992B *)a __attribute__((swift_name("init(a:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestGH3992B *a __attribute__((swift_name("a"))); @end; __attribute__((swift_name("TestGH3992.A"))) @interface KtTestGH3992A : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992.B"))) @interface KtTestGH3992B : KtTestGH3992A - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt35940Kt"))) @interface KtKt35940Kt : KtBase + (NSString *)testKt35940 __attribute__((swift_name("testKt35940()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641"))) @interface KtKT38641 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.IntType"))) @interface KtKT38641IntType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (getter=description, setter=setDescription:) int32_t description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.Val"))) @interface KtKT38641Val : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.Var"))) @interface KtKT38641Var : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.TwoProperties"))) @interface KtKT38641TwoProperties : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @property (readonly) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((swift_name("KT38641.OverrideVal"))) @interface KtKT38641OverrideVal : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((swift_name("KT38641OverrideVar"))) @protocol KtKT38641OverrideVar @required @property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt38641Kt"))) @interface KtKt38641Kt : KtBase + (NSString *)getOverrideValDescriptionImpl:(KtKT38641OverrideVal *)impl __attribute__((swift_name("getOverrideValDescription(impl:)"))); + (NSString *)getOverrideVarDescriptionImpl:(id)impl __attribute__((swift_name("getOverrideVarDescription(impl:)"))); + (void)setOverrideVarDescriptionImpl:(id)impl newValue:(NSString *)newValue __attribute__((swift_name("setOverrideVarDescription(impl:newValue:)"))); @end; __attribute__((swift_name("JsonConfiguration"))) @interface KtJsonConfiguration : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("This class is deprecated for removal during serialization 1.0 API stabilization.\nFor configuring Json instances, the corresponding builder function can be used instead, e.g. instead of'Json(JsonConfiguration.Stable.copy(isLenient = true))' 'Json { isLenient = true }' should be used.\nInstead of storing JsonConfiguration instances of the code, Json instances can be used directly:'Json(MyJsonConfiguration.copy(prettyPrint = true))' can be replaced with 'Json(from = MyApplicationJson) { prettyPrint = true }'"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MoreTrickyChars"))) @interface KtMoreTrickyChars : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("'\"\\@$(){}\r\n"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt39206Kt"))) @interface KtKt39206Kt : KtBase + (int32_t)myFunc __attribute__((swift_name("myFunc()"))) __attribute__((deprecated("Don't call this\nPlease"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Ckt41907"))) @interface KtCkt41907 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("Ikt41907"))) @protocol KtIkt41907 @required - (void)fooC:(KtCkt41907 *)c __attribute__((swift_name("foo(c:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt41907Kt"))) @interface KtKt41907Kt : KtBase + (void)escapeCC:(KtCkt41907 *)c __attribute__((swift_name("escapeC(c:)"))); + (void)testKt41907O:(id)o __attribute__((swift_name("testKt41907(o:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT43599"))) @interface KtKT43599 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) NSString *memberProperty __attribute__((swift_name("memberProperty"))); @end; @interface KtKT43599 (Kt43599Kt) @property (readonly) NSString *extensionProperty __attribute__((swift_name("extensionProperty"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt43599Kt"))) @interface KtKt43599Kt : KtBase + (void)setTopLevelLateinitPropertyValue:(NSString *)value __attribute__((swift_name("setTopLevelLateinitProperty(value:)"))); @property (class, readonly) NSString *topLevelProperty __attribute__((swift_name("topLevelProperty"))); @property (class, readonly) NSString *topLevelLateinitProperty __attribute__((swift_name("topLevelLateinitProperty"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase + (NSString *)readDataFromLibraryClassInput:(KtA *)input __attribute__((swift_name("readDataFromLibraryClass(input:)"))); + (NSString *)readDataFromLibraryInterfaceInput:(id)input __attribute__((swift_name("readDataFromLibraryInterface(input:)"))); + (NSString *)readDataFromLibraryEnumInput:(KtE *)input __attribute__((swift_name("readDataFromLibraryEnum(input:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysConstructor"))) @interface KtArraysConstructor : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysDefault"))) @interface KtArraysDefault : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysInitBlock"))) @interface KtArraysInitBlock : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((swift_name("OverrideKotlinMethods2"))) @protocol KtOverrideKotlinMethods2 @required - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods3"))) @interface KtOverrideKotlinMethods3 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OverrideKotlinMethods4"))) @interface KtOverrideKotlinMethods4 : KtOverrideKotlinMethods3 - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods5"))) @protocol KtOverrideKotlinMethods5 @required - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods6"))) @protocol KtOverrideKotlinMethods6 @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OverrideKotlinMethodsKt"))) @interface KtOverrideKotlinMethodsKt : KtBase /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test0Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test0(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test1Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test1(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test2Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test2(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test3Obj:(KtOverrideKotlinMethods3 *)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test3(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test4Obj:(KtOverrideKotlinMethods4 *)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test4(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test5Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test5(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test6Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test6(obj:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OverrideMethodsOfAnyKt"))) @interface KtOverrideMethodsOfAnyKt : KtBase /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testObj:(id)obj other:(id)other swift:(BOOL)swift error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test(obj:other:swift:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ThrowsEmptyKt"))) @interface KtThrowsEmptyKt : KtBase /** @warning All uncaught Kotlin exceptions are fatal. */ + (BOOL)throwsEmptyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("throwsEmpty()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelManglingAKt"))) @interface KtTopLevelManglingAKt : KtBase + (NSString *)foo __attribute__((swift_name("foo()"))); + (int32_t)sameNumberValue:(int32_t)value __attribute__((swift_name("sameNumber(value:)"))); + (int64_t)sameNumberValue:(int64_t)value __attribute__((swift_name("sameNumber(value:)"))); @property (class, readonly) NSString *bar __attribute__((swift_name("bar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelManglingBKt"))) @interface KtTopLevelManglingBKt : KtBase + (NSString *)foo __attribute__((swift_name("foo()"))); @property (class, readonly) NSString *bar __attribute__((swift_name("bar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DelegateClass"))) @interface KtDelegateClass : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtKotlinArray *)getValueThisRef:(KtKotlinNothing * _Nullable)thisRef property:(id)property __attribute__((swift_name("getValue(thisRef:property:)"))); - (void)setValueThisRef:(KtKotlinNothing * _Nullable)thisRef property:(id)property value:(KtKotlinArray *)value __attribute__((swift_name("setValue(thisRef:property:value:)"))); @end; __attribute__((swift_name("I"))) @protocol KtI @required - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DefaultInterfaceExt"))) @interface KtDefaultInterfaceExt : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OpenClassI"))) @interface KtOpenClassI : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FinalClassExtOpen"))) @interface KtFinalClassExtOpen : KtOpenClassI - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((swift_name("MultiExtClass"))) @interface KtMultiExtClass : KtOpenClassI - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id)piFun __attribute__((swift_name("piFun()"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((swift_name("ConstrClass"))) @interface KtConstrClass : KtOpenClassI - (instancetype)initWithI:(int32_t)i s:(NSString *)s a:(id)a __attribute__((swift_name("init(i:s:a:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) int32_t i __attribute__((swift_name("i"))); @property (readonly) NSString *s __attribute__((swift_name("s"))); @property (readonly) id a __attribute__((swift_name("a"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ExtConstrClass"))) @interface KtExtConstrClass : KtConstrClass - (instancetype)initWithI:(int32_t)i __attribute__((swift_name("init(i:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithI:(int32_t)i s:(NSString *)s a:(id)a __attribute__((swift_name("init(i:s:a:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @property (readonly) int32_t i __attribute__((swift_name("i"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Enumeration"))) @interface KtEnumeration : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumeration *answer __attribute__((swift_name("answer"))); @property (class, readonly) KtEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) KtEnumeration *temperature __attribute__((swift_name("temperature"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TripleVals"))) @interface KtTripleVals : KtBase - (instancetype)initWithFirst:(T _Nullable)first second:(T _Nullable)second third:(T _Nullable)third __attribute__((swift_name("init(first:second:third:)"))) __attribute__((objc_designated_initializer)); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (NSString *)description __attribute__((swift_name("description()"))); - (T _Nullable)component1 __attribute__((swift_name("component1()"))); - (T _Nullable)component2 __attribute__((swift_name("component2()"))); - (T _Nullable)component3 __attribute__((swift_name("component3()"))); - (KtTripleVals *)doCopyFirst:(T _Nullable)first second:(T _Nullable)second third:(T _Nullable)third __attribute__((swift_name("doCopy(first:second:third:)"))); @property (readonly) T _Nullable first __attribute__((swift_name("first"))); @property (readonly) T _Nullable second __attribute__((swift_name("second"))); @property (readonly) T _Nullable third __attribute__((swift_name("third"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TripleVars"))) @interface KtTripleVars : KtBase - (instancetype)initWithFirst:(T _Nullable)first second:(T _Nullable)second third:(T _Nullable)third __attribute__((swift_name("init(first:second:third:)"))) __attribute__((objc_designated_initializer)); - (NSString *)description __attribute__((swift_name("description()"))); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (T _Nullable)component1 __attribute__((swift_name("component1()"))); - (T _Nullable)component2 __attribute__((swift_name("component2()"))); - (T _Nullable)component3 __attribute__((swift_name("component3()"))); - (KtTripleVars *)doCopyFirst:(T _Nullable)first second:(T _Nullable)second third:(T _Nullable)third __attribute__((swift_name("doCopy(first:second:third:)"))); @property T _Nullable first __attribute__((swift_name("first"))); @property T _Nullable second __attribute__((swift_name("second"))); @property T _Nullable third __attribute__((swift_name("third"))); @end; __attribute__((swift_name("WithCompanionAndObject"))) @interface KtWithCompanionAndObject : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithCompanionAndObject.Companion"))) @interface KtWithCompanionAndObjectCompanion : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)companion __attribute__((swift_name("init()"))); @property (readonly) NSString *str __attribute__((swift_name("str"))); @property id _Nullable named __attribute__((swift_name("named"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithCompanionAndObject.Named"))) @interface KtWithCompanionAndObjectNamed : KtOpenClassI + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (instancetype)named __attribute__((swift_name("init()"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MyException"))) @interface KtMyException : KtKotlinException - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MyError"))) @interface KtMyError : KtKotlinError - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((swift_name("SwiftOverridableMethodsWithThrows"))) @protocol KtSwiftOverridableMethodsWithThrows @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); @end; __attribute__((swift_name("MethodsWithThrows"))) @protocol KtMethodsWithThrows @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((swift_name("MethodsWithThrowsUnitCaller"))) @protocol KtMethodsWithThrowsUnitCaller @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)callMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call(methods:)"))); @end; __attribute__((swift_name("Throwing"))) @interface KtThrowing : KtBase /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (instancetype _Nullable)initWithDoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init(doThrow:)"))) __attribute__((objc_designated_initializer)); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("NotThrowing"))) @interface KtNotThrowing : KtBase /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (instancetype _Nullable)initAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((swift_name("ThrowsWithBridgeBase"))) @protocol KtThrowsWithBridgeBase @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)"))); @end; __attribute__((swift_name("ThrowsWithBridge"))) @interface KtThrowsWithBridge : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt * _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply"))) @interface KtDeeply : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply.Nested"))) @interface KtDeeplyNested : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply.NestedType"))) @interface KtDeeplyNestedType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyTwo __attribute__((swift_name("thirtyTwo"))); @end; __attribute__((swift_name("DeeplyNestedIType"))) @protocol KtDeeplyNestedIType @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeply"))) @interface KtWithGenericDeeply : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeply.Nested"))) @interface KtWithGenericDeeplyNested : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeplyNestedType"))) @interface KtWithGenericDeeplyNestedType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyThree __attribute__((swift_name("thirtyThree"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TypeOuter"))) @interface KtTypeOuter : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TypeOuter.Type_"))) @interface KtTypeOuterType_ : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyFour __attribute__((swift_name("thirtyFour"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CKeywords"))) @interface KtCKeywords : KtBase - (instancetype)initWithFloat:(float)float_ enum:(int32_t)enum_ goto:(BOOL)goto_ __attribute__((swift_name("init(float:enum:goto:)"))) __attribute__((objc_designated_initializer)); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (NSString *)description __attribute__((swift_name("description()"))); - (float)component1 __attribute__((swift_name("component1()"))); - (int32_t)component2 __attribute__((swift_name("component2()"))); - (BOOL)component3 __attribute__((swift_name("component3()"))); - (KtCKeywords *)doCopyFloat:(float)float_ enum:(int32_t)enum_ goto:(BOOL)goto_ __attribute__((swift_name("doCopy(float:enum:goto:)"))); @property (readonly, getter=float) float float_ __attribute__((swift_name("float_"))); @property (readonly, getter=enum) int32_t enum_ __attribute__((swift_name("enum_"))); @property (getter=goto, setter=setGoto:) BOOL goto_ __attribute__((swift_name("goto_"))); @end; __attribute__((swift_name("Base1"))) @protocol KtBase1 @required - (KtInt * _Nullable)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("ExtendedBase1"))) @protocol KtExtendedBase1 @required @end; __attribute__((swift_name("Base2"))) @protocol KtBase2 @required - (KtInt * _Nullable)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("Base23"))) @interface KtBase23 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtInt *)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("Transform"))) @protocol KtTransform @required - (id _Nullable)mapValue:(id _Nullable)value __attribute__((swift_name("map(value:)"))); @end; __attribute__((swift_name("TransformWithDefault"))) @protocol KtTransformWithDefault @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TransformInheritingDefault"))) @interface KtTransformInheritingDefault : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TransformIntString"))) @protocol KtTransformIntString @required - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToString"))) @interface KtTransformIntToString : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)mapValue:(KtInt *)intValue __attribute__((swift_name("map(value:)"))); - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToDecimalString"))) @interface KtTransformIntToDecimalString : KtTransformIntToString - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)mapValue:(KtInt *)intValue __attribute__((swift_name("map(value:)"))); - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToLong"))) @interface KtTransformIntToLong : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtLong *)mapValue:(KtInt *)value __attribute__((swift_name("map(value:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931"))) @interface KtGH2931 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931.Data"))) @interface KtGH2931Data : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931.Holder"))) @interface KtGH2931Holder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) KtGH2931Data *data __attribute__((swift_name("data"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2945"))) @interface KtGH2945 : KtBase - (instancetype)initWithErrno:(int32_t)errno __attribute__((swift_name("init(errno:)"))) __attribute__((objc_designated_initializer)); - (int32_t)testErrnoInSelectorP:(int32_t)p errno:(int32_t)errno __attribute__((swift_name("testErrnoInSelector(p:errno:)"))); @property int32_t errno __attribute__((swift_name("errno"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2830"))) @interface KtGH2830 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id)getI __attribute__((swift_name("getI()"))); @end; __attribute__((swift_name("GH2830I"))) @protocol KtGH2830I @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2959"))) @interface KtGH2959 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSArray> *)getIId:(int32_t)id __attribute__((swift_name("getI(id:)"))); @end; __attribute__((swift_name("GH2959I"))) @protocol KtGH2959I @required @property (readonly) int32_t id __attribute__((swift_name("id"))); @end; __attribute__((swift_name("IntBlocks"))) @protocol KtIntBlocks @required - (id _Nullable)getPlusOneBlock __attribute__((swift_name("getPlusOneBlock()"))); - (int32_t)callBlockArgument:(int32_t)argument block:(id _Nullable)block __attribute__((swift_name("callBlock(argument:block:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("IntBlocksImpl"))) @interface KtIntBlocksImpl : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)intBlocksImpl __attribute__((swift_name("init()"))); - (KtInt *(^)(KtInt *))getPlusOneBlock __attribute__((swift_name("getPlusOneBlock()"))); - (int32_t)callBlockArgument:(int32_t)argument block:(KtInt *(^)(KtInt *))block __attribute__((swift_name("callBlock(argument:block:)"))); @end; __attribute__((swift_name("UnitBlockCoercion"))) @protocol KtUnitBlockCoercion @required - (id)coerceBlock:(void (^)(void))block __attribute__((swift_name("coerce(block:)"))); - (void (^)(void))uncoerceBlock:(id)block __attribute__((swift_name("uncoerce(block:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("UnitBlockCoercionImpl"))) @interface KtUnitBlockCoercionImpl : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)unitBlockCoercionImpl __attribute__((swift_name("init()"))); - (KtKotlinUnit *(^)(void))coerceBlock:(void (^)(void))block __attribute__((swift_name("coerce(block:)"))); - (void (^)(void))uncoerceBlock:(KtKotlinUnit *(^)(void))block __attribute__((swift_name("uncoerce(block:)"))); @end; __attribute__((swift_name("MyAbstractList"))) @interface KtMyAbstractList : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestKClass"))) @interface KtTestKClass : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id _Nullable)getKotlinClassClazz:(Class)clazz __attribute__((swift_name("getKotlinClass(clazz:)"))); - (id _Nullable)getKotlinClassProtocol:(Protocol *)protocol __attribute__((swift_name("getKotlinClass(protocol:)"))); - (BOOL)isTestKClassKClass:(id)kClass __attribute__((swift_name("isTestKClass(kClass:)"))); - (BOOL)isIKClass:(id)kClass __attribute__((swift_name("isI(kClass:)"))); @end; __attribute__((swift_name("TestKClassI"))) @protocol KtTestKClassI @required @end; __attribute__((swift_name("ForwardI2"))) @protocol KtForwardI2 @required @end; __attribute__((swift_name("ForwardI1"))) @protocol KtForwardI1 @required - (id)getForwardI2 __attribute__((swift_name("getForwardI2()"))); @end; __attribute__((swift_name("ForwardC2"))) @interface KtForwardC2 : KtForwardC1 - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("ForwardC1"))) @interface KtForwardC1 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtForwardC2 *)getForwardC2 __attribute__((swift_name("getForwardC2()"))); @end; __attribute__((swift_name("TestSR10177Workaround"))) @protocol KtTestSR10177Workaround @required @end; __attribute__((swift_name("TestClashes1"))) @protocol KtTestClashes1 @required @property (readonly) int32_t clashingProperty __attribute__((swift_name("clashingProperty"))); @end; __attribute__((swift_name("TestClashes2"))) @protocol KtTestClashes2 @required @property (readonly) id clashingProperty __attribute__((swift_name("clashingProperty"))); @property (readonly) id clashingProperty_ __attribute__((swift_name("clashingProperty_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestClashesImpl"))) @interface KtTestClashesImpl : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t clashingProperty __attribute__((swift_name("clashingProperty"))); @property (readonly) KtInt *clashingProperty_ __attribute__((swift_name("clashingProperty_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers"))) @interface KtTestInvalidIdentifiers : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)a_d_d_1:(int32_t)_1 _2:(int32_t)_2 _3:(int32_t)_3 __attribute__((swift_name("a_d_d(_1:_2:_3:)"))); @property NSString *_status __attribute__((swift_name("_status"))); @property (readonly) unichar __ __attribute__((swift_name("__"))); @property (readonly) unichar __ __attribute__((swift_name("__"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers._Foo"))) @interface KtTestInvalidIdentifiers_Foo : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.Bar_"))) @interface KtTestInvalidIdentifiersBar_ : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.E"))) @interface KtTestInvalidIdentifiersE : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtTestInvalidIdentifiersE *_4_ __attribute__((swift_name("_4_"))); @property (class, readonly) KtTestInvalidIdentifiersE *_5_ __attribute__((swift_name("_5_"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.Companion_"))) @interface KtTestInvalidIdentifiersCompanion_ : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)companion_ __attribute__((swift_name("init()"))); @property (readonly) int32_t _42 __attribute__((swift_name("_42"))); @end; __attribute__((swift_name("TestDeprecation"))) @interface KtTestDeprecation : KtBase - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)callEffectivelyHiddenObj:(id)obj __attribute__((swift_name("callEffectivelyHidden(obj:)"))); - (id)getHidden __attribute__((swift_name("getHidden()"))); - (KtTestDeprecationError *)getError __attribute__((swift_name("getError()"))); - (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("error"))); - (KtTestDeprecationWarning *)getWarning __attribute__((swift_name("getWarning()"))); - (void)warning __attribute__((swift_name("warning()"))) __attribute__((deprecated("warning"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("warning"))); - (void)normal __attribute__((swift_name("normal()"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))); - (void)testHiddenNested:(id)hiddenNested __attribute__((swift_name("test(hiddenNested:)"))); - (void)testHiddenNestedNested:(id)hiddenNestedNested __attribute__((swift_name("test(hiddenNestedNested:)"))); - (void)testHiddenNestedInner:(id)hiddenNestedInner __attribute__((swift_name("test(hiddenNestedInner:)"))); - (void)testHiddenInner:(id)hiddenInner __attribute__((swift_name("test(hiddenInner:)"))); - (void)testHiddenInnerInner:(id)hiddenInnerInner __attribute__((swift_name("test(hiddenInnerInner:)"))); - (void)testTopLevelHidden:(id)topLevelHidden __attribute__((swift_name("test(topLevelHidden:)"))); - (void)testTopLevelHiddenNested:(id)topLevelHiddenNested __attribute__((swift_name("test(topLevelHiddenNested:)"))); - (void)testTopLevelHiddenNestedNested:(id)topLevelHiddenNestedNested __attribute__((swift_name("test(topLevelHiddenNestedNested:)"))); - (void)testTopLevelHiddenNestedInner:(id)topLevelHiddenNestedInner __attribute__((swift_name("test(topLevelHiddenNestedInner:)"))); - (void)testTopLevelHiddenInner:(id)topLevelHiddenInner __attribute__((swift_name("test(topLevelHiddenInner:)"))); - (void)testTopLevelHiddenInnerInner:(id)topLevelHiddenInnerInner __attribute__((swift_name("test(topLevelHiddenInnerInner:)"))); - (void)testExtendingHiddenNested:(id)extendingHiddenNested __attribute__((swift_name("test(extendingHiddenNested:)"))); - (void)testExtendingNestedInHidden:(id)extendingNestedInHidden __attribute__((swift_name("test(extendingNestedInHidden:)"))); @property (readonly) id _Nullable errorVal __attribute__((swift_name("errorVal"))) __attribute__((unavailable("error"))); @property id _Nullable errorVar __attribute__((swift_name("errorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable warningVal __attribute__((swift_name("warningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable warningVar __attribute__((swift_name("warningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable normalVal __attribute__((swift_name("normalVal"))); @property id _Nullable normalVar __attribute__((swift_name("normalVar"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))); @end; __attribute__((swift_name("TestDeprecation.OpenHidden"))) @interface KtTestDeprecationOpenHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingHidden"))) @interface KtTestDeprecationExtendingHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingHiddenNested"))) @interface KtTestDeprecationExtendingHiddenNested : NSObject @end; __attribute__((swift_name("TestDeprecationHiddenInterface"))) @protocol KtTestDeprecationHiddenInterface @required @end; __attribute__((swift_name("TestDeprecation.ImplementingHidden"))) @interface KtTestDeprecationImplementingHidden : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)effectivelyHidden __attribute__((swift_name("effectivelyHidden()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Hidden"))) @interface KtTestDeprecationHidden : NSObject @end; __attribute__((swift_name("TestDeprecation.HiddenNested"))) @interface KtTestDeprecationHiddenNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenNestedNested"))) @interface KtTestDeprecationHiddenNestedNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenNestedInner"))) @interface KtTestDeprecationHiddenNestedInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenInner"))) @interface KtTestDeprecationHiddenInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenInnerInner"))) @interface KtTestDeprecationHiddenInnerInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingNestedInHidden"))) @interface KtTestDeprecationExtendingNestedInHidden : NSObject @end; __attribute__((swift_name("TestDeprecation.OpenError"))) @interface KtTestDeprecationOpenError : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingError"))) @interface KtTestDeprecationExtendingError : KtTestDeprecationOpenError - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestDeprecationErrorInterface"))) @protocol KtTestDeprecationErrorInterface @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ImplementingError"))) @interface KtTestDeprecationImplementingError : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Error"))) @interface KtTestDeprecationError : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((swift_name("TestDeprecation.OpenWarning"))) @interface KtTestDeprecationOpenWarning : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingWarning"))) @interface KtTestDeprecationExtendingWarning : KtTestDeprecationOpenWarning - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestDeprecationWarningInterface"))) @protocol KtTestDeprecationWarningInterface @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ImplementingWarning"))) @interface KtTestDeprecationImplementingWarning : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Warning"))) @interface KtTestDeprecationWarning : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenOverride"))) @interface KtTestDeprecationHiddenOverride : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("hidden"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((unavailable("hidden"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((unavailable("hidden"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ErrorOverride"))) @interface KtTestDeprecationErrorOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openHidden __attribute__((swift_name("openHidden()"))) __attribute__((unavailable("error"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("error"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((unavailable("error"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openHiddenVal __attribute__((swift_name("openHiddenVal"))) __attribute__((unavailable("error"))); @property id _Nullable openHiddenVar __attribute__((swift_name("openHiddenVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((unavailable("error"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((unavailable("error"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((unavailable("error"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.WarningOverride"))) @interface KtTestDeprecationWarningOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openHidden __attribute__((swift_name("openHidden()"))) __attribute__((deprecated("warning"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((deprecated("warning"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("warning"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openHiddenVal __attribute__((swift_name("openHiddenVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openHiddenVar __attribute__((swift_name("openHiddenVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((deprecated("warning"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.NormalOverride"))) @interface KtTestDeprecationNormalOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden"))) @interface KtTopLevelHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.Nested"))) @interface KtTopLevelHiddenNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.NestedNested"))) @interface KtTopLevelHiddenNestedNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.NestedInner"))) @interface KtTopLevelHiddenNestedInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.Inner"))) @interface KtTopLevelHiddenInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.InnerInner"))) @interface KtTopLevelHiddenInnerInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestWeakRefs"))) @interface KtTestWeakRefs : KtBase - (instancetype)initWithFrozen:(BOOL)frozen __attribute__((swift_name("init(frozen:)"))) __attribute__((objc_designated_initializer)); - (id)getObj __attribute__((swift_name("getObj()"))); - (void)clearObj __attribute__((swift_name("clearObj()"))); - (NSArray *)createCycle __attribute__((swift_name("createCycle()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("SharedRefs"))) @interface KtSharedRefs : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtSharedRefsMutableData *)createRegularObject __attribute__((swift_name("createRegularObject()"))); - (void (^)(void))createLambda __attribute__((swift_name("createLambda()"))); - (NSMutableArray *)createCollection __attribute__((swift_name("createCollection()"))); - (KtSharedRefsMutableData *)createFrozenRegularObject __attribute__((swift_name("createFrozenRegularObject()"))); - (void (^)(void))createFrozenLambda __attribute__((swift_name("createFrozenLambda()"))); - (NSMutableArray *)createFrozenCollection __attribute__((swift_name("createFrozenCollection()"))); - (BOOL)hasAliveObjects __attribute__((swift_name("hasAliveObjects()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("SharedRefs.MutableData"))) @interface KtSharedRefsMutableData : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)update __attribute__((swift_name("update()"))); @property int32_t x __attribute__((swift_name("x"))); @end; __attribute__((swift_name("TestRememberNewObject"))) @protocol KtTestRememberNewObject @required - (id)getObject __attribute__((swift_name("getObject()"))); - (void)waitForCleanup __attribute__((swift_name("waitForCleanup()"))); @end; __attribute__((swift_name("ClassForTypeCheck"))) @interface KtClassForTypeCheck : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("InterfaceForTypeCheck"))) @protocol KtInterfaceForTypeCheck @required @end; __attribute__((swift_name("IAbstractInterface"))) @protocol KtIAbstractInterface @required - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("IAbstractInterface2"))) @protocol KtIAbstractInterface2 @required - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("AbstractInterfaceBase"))) @interface KtAbstractInterfaceBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)foo __attribute__((swift_name("foo()"))); - (int32_t)bar __attribute__((swift_name("bar()"))); @end; __attribute__((swift_name("AbstractInterfaceBase2"))) @interface KtAbstractInterfaceBase2 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("AbstractInterfaceBase3"))) @interface KtAbstractInterfaceBase3 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("GH3525Base"))) @interface KtGH3525Base : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH3525"))) @interface KtGH3525 : KtGH3525Base + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (instancetype)gH3525 __attribute__((swift_name("init()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestStringConversion"))) @interface KtTestStringConversion : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property id str __attribute__((swift_name("str"))); @end; __attribute__((swift_name("GH3825"))) @protocol KtGH3825 @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call0AndReturnError:(NSError * _Nullable * _Nullable)error callback:(KtBoolean *(^)(void))callback __attribute__((swift_name("call0(callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call1DoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error callback:(void (^)(void))callback __attribute__((swift_name("call1(doThrow:callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call2Callback:(void (^)(void))callback doThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call2(callback:doThrow:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH3825KotlinImpl"))) @interface KtGH3825KotlinImpl : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call0AndReturnError:(NSError * _Nullable * _Nullable)error callback:(KtBoolean *(^)(void))callback __attribute__((swift_name("call0(callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call1DoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error callback:(void (^)(void))callback __attribute__((swift_name("call1(doThrow:callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call2Callback:(void (^)(void))callback doThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call2(callback:doThrow:)"))); @end; __attribute__((swift_name("Foo_FakeOverrideInInterface"))) @protocol KtFoo_FakeOverrideInInterface @required - (void)fooT:(id _Nullable)t __attribute__((swift_name("foo(t:)"))); @end; __attribute__((swift_name("Bar_FakeOverrideInInterface"))) @protocol KtBar_FakeOverrideInInterface @required @end; @interface KtEnumeration (ValuesKt) - (KtEnumeration *)getAnswer __attribute__((swift_name("getAnswer()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ValuesKt"))) @interface KtValuesKt : KtBase + (KtBoolean * _Nullable)boxBooleanValue:(BOOL)booleanValue __attribute__((swift_name("box(booleanValue:)"))); + (KtByte * _Nullable)boxByteValue:(int8_t)byteValue __attribute__((swift_name("box(byteValue:)"))); + (KtShort * _Nullable)boxShortValue:(int16_t)shortValue __attribute__((swift_name("box(shortValue:)"))); + (KtInt * _Nullable)boxIntValue:(int32_t)intValue __attribute__((swift_name("box(intValue:)"))); + (KtLong * _Nullable)boxLongValue:(int64_t)longValue __attribute__((swift_name("box(longValue:)"))); + (KtUByte * _Nullable)boxUByteValue:(uint8_t)uByteValue __attribute__((swift_name("box(uByteValue:)"))); + (KtUShort * _Nullable)boxUShortValue:(uint16_t)uShortValue __attribute__((swift_name("box(uShortValue:)"))); + (KtUInt * _Nullable)boxUIntValue:(uint32_t)uIntValue __attribute__((swift_name("box(uIntValue:)"))); + (KtULong * _Nullable)boxULongValue:(uint64_t)uLongValue __attribute__((swift_name("box(uLongValue:)"))); + (KtFloat * _Nullable)boxFloatValue:(float)floatValue __attribute__((swift_name("box(floatValue:)"))); + (KtDouble * _Nullable)boxDoubleValue:(double)doubleValue __attribute__((swift_name("box(doubleValue:)"))); + (void)ensureEqualBooleansActual:(KtBoolean * _Nullable)actual expected:(BOOL)expected __attribute__((swift_name("ensureEqualBooleans(actual:expected:)"))); + (void)ensureEqualBytesActual:(KtByte * _Nullable)actual expected:(int8_t)expected __attribute__((swift_name("ensureEqualBytes(actual:expected:)"))); + (void)ensureEqualShortsActual:(KtShort * _Nullable)actual expected:(int16_t)expected __attribute__((swift_name("ensureEqualShorts(actual:expected:)"))); + (void)ensureEqualIntsActual:(KtInt * _Nullable)actual expected:(int32_t)expected __attribute__((swift_name("ensureEqualInts(actual:expected:)"))); + (void)ensureEqualLongsActual:(KtLong * _Nullable)actual expected:(int64_t)expected __attribute__((swift_name("ensureEqualLongs(actual:expected:)"))); + (void)ensureEqualUBytesActual:(KtUByte * _Nullable)actual expected:(uint8_t)expected __attribute__((swift_name("ensureEqualUBytes(actual:expected:)"))); + (void)ensureEqualUShortsActual:(KtUShort * _Nullable)actual expected:(uint16_t)expected __attribute__((swift_name("ensureEqualUShorts(actual:expected:)"))); + (void)ensureEqualUIntsActual:(KtUInt * _Nullable)actual expected:(uint32_t)expected __attribute__((swift_name("ensureEqualUInts(actual:expected:)"))); + (void)ensureEqualULongsActual:(KtULong * _Nullable)actual expected:(uint64_t)expected __attribute__((swift_name("ensureEqualULongs(actual:expected:)"))); + (void)ensureEqualFloatsActual:(KtFloat * _Nullable)actual expected:(float)expected __attribute__((swift_name("ensureEqualFloats(actual:expected:)"))); + (void)ensureEqualDoublesActual:(KtDouble * _Nullable)actual expected:(double)expected __attribute__((swift_name("ensureEqualDoubles(actual:expected:)"))); + (void)emptyFun __attribute__((swift_name("emptyFun()"))); + (NSString *)strFun __attribute__((swift_name("strFun()"))); + (id)argsFunI:(int32_t)i l:(int64_t)l d:(double)d s:(NSString *)s __attribute__((swift_name("argsFun(i:l:d:s:)"))); + (NSString *)funArgumentFoo:(NSString *(^)(void))foo __attribute__((swift_name("funArgument(foo:)"))); + (id _Nullable)genericFooT:(id _Nullable)t foo:(id _Nullable (^)(id _Nullable))foo __attribute__((swift_name("genericFoo(t:foo:)"))); + (id)fooGenericNumberR:(id)r foo:(id (^)(id))foo __attribute__((swift_name("fooGenericNumber(r:foo:)"))); + (NSArray *)varargToListArgs:(KtKotlinArray *)args __attribute__((swift_name("varargToList(args:)"))); + (NSString *)subExt:(NSString *)receiver i:(int32_t)i __attribute__((swift_name("subExt(_:i:)"))); + (NSString *)toString:(id _Nullable)receiver __attribute__((swift_name("toString(_:)"))); + (void)print:(id _Nullable)receiver __attribute__((swift_name("print(_:)"))); + (id _Nullable)boxChar:(unichar)receiver __attribute__((swift_name("boxChar(_:)"))); + (BOOL)isA:(id _Nullable)receiver __attribute__((swift_name("isA(_:)"))); + (NSString *)iFunExt:(id)receiver __attribute__((swift_name("iFunExt(_:)"))); + (KtEnumeration *)passEnum __attribute__((swift_name("passEnum()"))); + (void)receiveEnumE:(int32_t)e __attribute__((swift_name("receiveEnum(e:)"))); + (KtEnumeration *)getValue:(int32_t)value __attribute__((swift_name("get(value:)"))); + (KtWithCompanionAndObjectCompanion *)getCompanionObject __attribute__((swift_name("getCompanionObject()"))); + (KtWithCompanionAndObjectNamed *)getNamedObject __attribute__((swift_name("getNamedObject()"))); + (KtOpenClassI *)getNamedObjectInterface __attribute__((swift_name("getNamedObjectInterface()"))); + (id)boxIc1:(int32_t)ic1 __attribute__((swift_name("box(ic1:)"))); + (id)boxIc2:(id)ic2 __attribute__((swift_name("box(ic2:)"))); + (id)boxIc3:(id _Nullable)ic3 __attribute__((swift_name("box(ic3:)"))); + (NSString *)concatenateInlineClassValuesIc1:(int32_t)ic1 ic1N:(id _Nullable)ic1N ic2:(id)ic2 ic2N:(id _Nullable)ic2N ic3:(id _Nullable)ic3 ic3N:(id _Nullable)ic3N __attribute__((swift_name("concatenateInlineClassValues(ic1:ic1N:ic2:ic2N:ic3:ic3N:)"))); + (int32_t)getValue1:(int32_t)receiver __attribute__((swift_name("getValue1(_:)"))); + (KtInt * _Nullable)getValueOrNull1:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull1(_:)"))); + (NSString *)getValue2:(id)receiver __attribute__((swift_name("getValue2(_:)"))); + (NSString * _Nullable)getValueOrNull2:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull2(_:)"))); + (KtTripleVals * _Nullable)getValue3:(id _Nullable)receiver __attribute__((swift_name("getValue3(_:)"))); + (KtTripleVals * _Nullable)getValueOrNull3:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull3(_:)"))); + (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)"))); + (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)"))); + (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)"))); /** @note This method converts instances of MyException, MyError to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)throwExceptionError:(BOOL)error error:(NSError * _Nullable * _Nullable)error_ __attribute__((swift_name("throwException(error:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (KtKotlinObjCErrorException * _Nullable)testSwiftThrowingMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftNotThrowingMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(methods:)"))); /** @note This method converts instances of MyError to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)callUnitMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnit(methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)callUnitCallerCaller:(id)caller methods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnitCaller(caller:methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftThrowingTest:(id)test flag:(BOOL)flag error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(test:flag:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftNotThrowingTest:(id)test error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(test:)"))); + (id)same:(id)receiver __attribute__((swift_name("same(_:)"))); + (KtInt * _Nullable)callBase1:(id)base1 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base1:value:)"))); + (KtInt * _Nullable)callExtendedBase1:(id)extendedBase1 value:(KtInt * _Nullable)value __attribute__((swift_name("call(extendedBase1:value:)"))); + (KtInt * _Nullable)callBase2:(id)base2 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base2:value:)"))); + (int32_t)callBase3:(id)base3 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base3:value:)"))); + (int32_t)callBase23:(KtBase23 *)base23 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base23:value:)"))); + (id)createTransformDecimalStringToInt __attribute__((swift_name("createTransformDecimalStringToInt()"))); + (BOOL)runUnitBlockBlock:(void (^)(void))block __attribute__((swift_name("runUnitBlock(block:)"))); + (void (^)(void))asUnitBlockBlock:(id _Nullable (^)(void))block __attribute__((swift_name("asUnitBlock(block:)"))); + (BOOL)runNothingBlockBlock:(void (^)(void))block __attribute__((swift_name("runNothingBlock(block:)"))); + (void (^)(void))asNothingBlockBlock:(id _Nullable (^)(void))block __attribute__((swift_name("asNothingBlock(block:)"))); + (void (^ _Nullable)(void))getNullBlock __attribute__((swift_name("getNullBlock()"))); + (BOOL)isBlockNullBlock:(void (^ _Nullable)(void))block __attribute__((swift_name("isBlockNull(block:)"))); + (BOOL)isFunctionObj:(id _Nullable)obj __attribute__((swift_name("isFunction(obj:)"))); + (BOOL)isFunction0Obj:(id _Nullable)obj __attribute__((swift_name("isFunction0(obj:)"))); + (void)takeForwardDeclaredClassObj:(ForwardDeclaredClass *)obj __attribute__((swift_name("takeForwardDeclaredClass(obj:)"))); + (void)takeForwardDeclaredProtocolObj:(id)obj __attribute__((swift_name("takeForwardDeclaredProtocol(obj:)"))); + (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error"))); + (void)warning __attribute__((swift_name("warning()"))) __attribute__((deprecated("warning"))); + (void)gc __attribute__((swift_name("gc()"))); + (void)testRememberNewObjectTest:(id)test __attribute__((swift_name("testRememberNewObject(test:)"))); + (BOOL)testClassTypeCheckX:(id)x __attribute__((swift_name("testClassTypeCheck(x:)"))); + (BOOL)testInterfaceTypeCheckX:(id)x __attribute__((swift_name("testInterfaceTypeCheck(x:)"))); + (int32_t)testAbstractInterfaceCallX:(id)x __attribute__((swift_name("testAbstractInterfaceCall(x:)"))); + (int32_t)testAbstractInterfaceCall2X:(id)x __attribute__((swift_name("testAbstractInterfaceCall2(x:)"))); + (void)fooA:(KtKotlinAtomicReference *)a __attribute__((swift_name("foo(a:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testGH3825Gh3825:(id)gh3825 error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testGH3825(gh3825:)"))); + (NSDictionary *)mapBoolean2String __attribute__((swift_name("mapBoolean2String()"))); + (NSDictionary *)mapByte2Short __attribute__((swift_name("mapByte2Short()"))); + (NSDictionary *)mapShort2Byte __attribute__((swift_name("mapShort2Byte()"))); + (NSDictionary *)mapInt2Long __attribute__((swift_name("mapInt2Long()"))); + (NSDictionary *)mapLong2Long __attribute__((swift_name("mapLong2Long()"))); + (NSDictionary *)mapUByte2Boolean __attribute__((swift_name("mapUByte2Boolean()"))); + (NSDictionary *)mapUShort2Byte __attribute__((swift_name("mapUShort2Byte()"))); + (NSDictionary *)mapUInt2Long __attribute__((swift_name("mapUInt2Long()"))); + (NSDictionary *)mapULong2Long __attribute__((swift_name("mapULong2Long()"))); + (NSDictionary *)mapFloat2Float __attribute__((swift_name("mapFloat2Float()"))); + (NSDictionary *)mapDouble2String __attribute__((swift_name("mapDouble2String()"))); + (KtMutableDictionary *)mutBoolean2String __attribute__((swift_name("mutBoolean2String()"))); + (KtMutableDictionary *)mutByte2Short __attribute__((swift_name("mutByte2Short()"))); + (KtMutableDictionary *)mutShort2Byte __attribute__((swift_name("mutShort2Byte()"))); + (KtMutableDictionary *)mutInt2Long __attribute__((swift_name("mutInt2Long()"))); + (KtMutableDictionary *)mutLong2Long __attribute__((swift_name("mutLong2Long()"))); + (KtMutableDictionary *)mutUByte2Boolean __attribute__((swift_name("mutUByte2Boolean()"))); + (KtMutableDictionary *)mutUShort2Byte __attribute__((swift_name("mutUShort2Byte()"))); + (KtMutableDictionary *)mutUInt2Long __attribute__((swift_name("mutUInt2Long()"))); + (KtMutableDictionary *)mutULong2Long __attribute__((swift_name("mutULong2Long()"))); + (KtMutableDictionary *)mutFloat2Float __attribute__((swift_name("mutFloat2Float()"))); + (KtMutableDictionary *)mutDouble2String __attribute__((swift_name("mutDouble2String()"))); + (void)callFoo_FakeOverrideInInterfaceObj:(id)obj __attribute__((swift_name("callFoo_FakeOverrideInInterface(obj:)"))); @property (class, readonly) double dbl __attribute__((swift_name("dbl"))); @property (class, readonly) float flt __attribute__((swift_name("flt"))); @property (class, readonly) int32_t integer __attribute__((swift_name("integer"))); @property (class, readonly) int64_t longInt __attribute__((swift_name("longInt"))); @property (class) int32_t intVar __attribute__((swift_name("intVar"))); @property (class) NSString *str __attribute__((swift_name("str"))); @property (class) id strAsAny __attribute__((swift_name("strAsAny"))); @property (class) id minDoubleVal __attribute__((swift_name("minDoubleVal"))); @property (class) id maxDoubleVal __attribute__((swift_name("maxDoubleVal"))); @property (class, readonly) double nanDoubleVal __attribute__((swift_name("nanDoubleVal"))); @property (class, readonly) float nanFloatVal __attribute__((swift_name("nanFloatVal"))); @property (class, readonly) double infDoubleVal __attribute__((swift_name("infDoubleVal"))); @property (class, readonly) float infFloatVal __attribute__((swift_name("infFloatVal"))); @property (class, readonly) BOOL boolVal __attribute__((swift_name("boolVal"))); @property (class, readonly) id boolAnyVal __attribute__((swift_name("boolAnyVal"))); @property (class, readonly) NSArray *numbersList __attribute__((swift_name("numbersList"))); @property (class, readonly) NSArray *anyList __attribute__((swift_name("anyList"))); @property (class) id lateinitIntVar __attribute__((swift_name("lateinitIntVar"))); @property (class, readonly) NSString *lazyVal __attribute__((swift_name("lazyVal"))); @property (class) KtKotlinArray *delegatedGlobalArray __attribute__((swift_name("delegatedGlobalArray"))); @property (class, readonly) NSArray *delegatedList __attribute__((swift_name("delegatedList"))); @property (class, readonly) id _Nullable nullVal __attribute__((swift_name("nullVal"))); @property (class) NSString * _Nullable nullVar __attribute__((swift_name("nullVar"))); @property (class) id anyValue __attribute__((swift_name("anyValue"))); @property (class, readonly) KtInt *(^sumLambda)(KtInt *, KtInt *) __attribute__((swift_name("sumLambda"))); @property (class, readonly) int32_t PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT __attribute__((swift_name("PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT"))); @property (class, readonly) id _Nullable errorVal __attribute__((swift_name("errorVal"))) __attribute__((unavailable("error"))); @property (class) id _Nullable errorVar __attribute__((swift_name("errorVar"))) __attribute__((unavailable("error"))); @property (class, readonly) id _Nullable warningVal __attribute__((swift_name("warningVal"))) __attribute__((deprecated("warning"))); @property (class) id _Nullable warningVar __attribute__((swift_name("warningVar"))) __attribute__((deprecated("warning"))); @property (class) int32_t gh3525BaseInitCount __attribute__((swift_name("gh3525BaseInitCount"))); @property (class) int32_t gh3525InitCount __attribute__((swift_name("gh3525InitCount"))); @end; __attribute__((swift_name("InvariantSuper"))) @interface KtInvariantSuper : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Invariant"))) @interface KtInvariant : KtInvariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OutVariantSuper"))) @interface KtOutVariantSuper<__covariant T> : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OutVariant"))) @interface KtOutVariant<__covariant T> : KtOutVariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("InVariantSuper"))) @interface KtInVariantSuper<__contravariant T> : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("InVariant"))) @interface KtInVariant<__contravariant T> : KtInVariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; ================================================ FILE: backend.native/tests/objcexport/expectedLazyNoGenerics.h ================================================ __attribute__((swift_name("KotlinBase"))) @interface KtBase : NSObject - (instancetype)init __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (void)initialize __attribute__((objc_requires_super)); @end; @interface KtBase (KtBaseCopying) @end; __attribute__((swift_name("KotlinMutableSet"))) @interface KtMutableSet : NSMutableSet @end; __attribute__((swift_name("KotlinMutableDictionary"))) @interface KtMutableDictionary : NSMutableDictionary @end; @interface NSError (NSErrorKtKotlinException) @property (readonly) id _Nullable kotlinException; @end; __attribute__((swift_name("KotlinNumber"))) @interface KtNumber : NSNumber - (instancetype)initWithChar:(char)value __attribute__((unavailable)); - (instancetype)initWithUnsignedChar:(unsigned char)value __attribute__((unavailable)); - (instancetype)initWithShort:(short)value __attribute__((unavailable)); - (instancetype)initWithUnsignedShort:(unsigned short)value __attribute__((unavailable)); - (instancetype)initWithInt:(int)value __attribute__((unavailable)); - (instancetype)initWithUnsignedInt:(unsigned int)value __attribute__((unavailable)); - (instancetype)initWithLong:(long)value __attribute__((unavailable)); - (instancetype)initWithUnsignedLong:(unsigned long)value __attribute__((unavailable)); - (instancetype)initWithLongLong:(long long)value __attribute__((unavailable)); - (instancetype)initWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable)); - (instancetype)initWithFloat:(float)value __attribute__((unavailable)); - (instancetype)initWithDouble:(double)value __attribute__((unavailable)); - (instancetype)initWithBool:(BOOL)value __attribute__((unavailable)); - (instancetype)initWithInteger:(NSInteger)value __attribute__((unavailable)); - (instancetype)initWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable)); + (instancetype)numberWithChar:(char)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedChar:(unsigned char)value __attribute__((unavailable)); + (instancetype)numberWithShort:(short)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedShort:(unsigned short)value __attribute__((unavailable)); + (instancetype)numberWithInt:(int)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedInt:(unsigned int)value __attribute__((unavailable)); + (instancetype)numberWithLong:(long)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedLong:(unsigned long)value __attribute__((unavailable)); + (instancetype)numberWithLongLong:(long long)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable)); + (instancetype)numberWithFloat:(float)value __attribute__((unavailable)); + (instancetype)numberWithDouble:(double)value __attribute__((unavailable)); + (instancetype)numberWithBool:(BOOL)value __attribute__((unavailable)); + (instancetype)numberWithInteger:(NSInteger)value __attribute__((unavailable)); + (instancetype)numberWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable)); @end; __attribute__((swift_name("KotlinByte"))) @interface KtByte : KtNumber - (instancetype)initWithChar:(char)value; + (instancetype)numberWithChar:(char)value; @end; __attribute__((swift_name("KotlinUByte"))) @interface KtUByte : KtNumber - (instancetype)initWithUnsignedChar:(unsigned char)value; + (instancetype)numberWithUnsignedChar:(unsigned char)value; @end; __attribute__((swift_name("KotlinShort"))) @interface KtShort : KtNumber - (instancetype)initWithShort:(short)value; + (instancetype)numberWithShort:(short)value; @end; __attribute__((swift_name("KotlinUShort"))) @interface KtUShort : KtNumber - (instancetype)initWithUnsignedShort:(unsigned short)value; + (instancetype)numberWithUnsignedShort:(unsigned short)value; @end; __attribute__((swift_name("KotlinInt"))) @interface KtInt : KtNumber - (instancetype)initWithInt:(int)value; + (instancetype)numberWithInt:(int)value; @end; __attribute__((swift_name("KotlinUInt"))) @interface KtUInt : KtNumber - (instancetype)initWithUnsignedInt:(unsigned int)value; + (instancetype)numberWithUnsignedInt:(unsigned int)value; @end; __attribute__((swift_name("KotlinLong"))) @interface KtLong : KtNumber - (instancetype)initWithLongLong:(long long)value; + (instancetype)numberWithLongLong:(long long)value; @end; __attribute__((swift_name("KotlinULong"))) @interface KtULong : KtNumber - (instancetype)initWithUnsignedLongLong:(unsigned long long)value; + (instancetype)numberWithUnsignedLongLong:(unsigned long long)value; @end; __attribute__((swift_name("KotlinFloat"))) @interface KtFloat : KtNumber - (instancetype)initWithFloat:(float)value; + (instancetype)numberWithFloat:(float)value; @end; __attribute__((swift_name("KotlinDouble"))) @interface KtDouble : KtNumber - (instancetype)initWithDouble:(double)value; + (instancetype)numberWithDouble:(double)value; @end; __attribute__((swift_name("KotlinBoolean"))) @interface KtBoolean : KtNumber - (instancetype)initWithBool:(BOOL)value; + (instancetype)numberWithBool:(BOOL)value; @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CoroutineException"))) @interface KtCoroutineException : KtKotlinThrowable - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ContinuationHolder"))) @interface KtContinuationHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)resumeValue:(id _Nullable)value __attribute__((swift_name("resume(value:)"))); - (void)resumeWithExceptionException:(KtKotlinThrowable *)exception __attribute__((swift_name("resumeWithException(exception:)"))); @end; __attribute__((swift_name("SuspendFun"))) @protocol KtSuspendFun @required /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)suspendFunDoYield:(BOOL)doYield doThrow:(BOOL)doThrow completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(doYield:doThrow:completionHandler:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ResultHolder"))) @interface KtResultHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property int32_t completed __attribute__((swift_name("completed"))); @property id _Nullable result __attribute__((swift_name("result"))); @property KtKotlinThrowable * _Nullable exception __attribute__((swift_name("exception"))); @end; __attribute__((swift_name("SuspendBridge"))) @protocol KtSuspendBridge @required /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intValue:(id _Nullable)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("int(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unit(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothing(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsIntValue:(id _Nullable)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsInt(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsAnyValue:(id _Nullable)value completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsUnitValue:(id _Nullable)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)"))); @end; __attribute__((swift_name("AbstractSuspendBridge"))) @interface KtAbstractSuspendBridge : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)intAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("intAsAny(value:completionHandler:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)unitAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("unitAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsIntValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsInt(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsAnyValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsAny(value:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ - (void)nothingAsUnitValue:(KtInt *)value completionHandler:(void (^)(KtKotlinNothing * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("nothingAsUnit(value:completionHandler:)"))); @end; __attribute__((swift_name("ThrowCancellationException"))) @interface KtThrowCancellationException : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ThrowCancellationExceptionImpl"))) @interface KtThrowCancellationExceptionImpl : KtThrowCancellationException - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CoroutinesKt"))) @interface KtCoroutinesKt : KtBase /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunWithCompletionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunResult:(id _Nullable)result doSuspend:(BOOL)doSuspend doThrow:(BOOL)doThrow completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFun(result:doSuspend:doThrow:completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)suspendFunAsyncResult:(id _Nullable)result continuationHolder:(KtContinuationHolder *)continuationHolder completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("suspendFunAsync(result:continuationHolder:completionHandler:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)throwExceptionException:(KtKotlinThrowable *)exception error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("throwException(exception:)"))); + (void)callSuspendFunSuspendFun:(id)suspendFun doYield:(BOOL)doYield doThrow:(BOOL)doThrow resultHolder:(KtResultHolder *)resultHolder __attribute__((swift_name("callSuspendFun(suspendFun:doYield:doThrow:resultHolder:)"))); /** @note This method converts instances of CoroutineException, CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)callSuspendFun2SuspendFun:(id)suspendFun doYield:(BOOL)doYield doThrow:(BOOL)doThrow completionHandler:(void (^)(KtInt * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("callSuspendFun2(suspendFun:doYield:doThrow:completionHandler:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)callSuspendBridgeBridge:(KtAbstractSuspendBridge *)bridge resultHolder:(KtResultHolder *)resultHolder error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callSuspendBridge(bridge:resultHolder:)"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)throwCancellationExceptionWithCompletionHandler:(void (^)(KtKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("throwCancellationException(completionHandler:)"))); + (id)getSuspendLambda0 __attribute__((swift_name("getSuspendLambda0()"))); + (id)getSuspendCallableReference0 __attribute__((swift_name("getSuspendCallableReference0()"))); + (id)getSuspendLambda1 __attribute__((swift_name("getSuspendLambda1()"))); + (id)getSuspendCallableReference1 __attribute__((swift_name("getSuspendCallableReference1()"))); /** @note This method converts instances of CancellationException to errors. Other uncaught Kotlin exceptions are fatal. */ + (void)invoke1Block:(id)block argument:(id _Nullable)argument completionHandler:(void (^)(id _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("invoke1(block:argument:completionHandler:)"))); @end; __attribute__((swift_name("DeallocRetainBase"))) @interface KtDeallocRetainBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DeallocRetainKt"))) @interface KtDeallocRetainKt : KtBase + (void)garbageCollect __attribute__((swift_name("garbageCollect()"))); + (KtKotlinWeakReference *)createWeakReferenceValue:(id)value __attribute__((swift_name("createWeakReference(value:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumLeftRightUpDown"))) @interface KtEnumLeftRightUpDown : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumLeftRightUpDown *left __attribute__((swift_name("left"))); @property (class, readonly) KtEnumLeftRightUpDown *right __attribute__((swift_name("right"))); @property (class, readonly) KtEnumLeftRightUpDown *up __attribute__((swift_name("up"))); @property (class, readonly) KtEnumLeftRightUpDown *down __attribute__((swift_name("down"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumOneTwoThreeValues"))) @interface KtEnumOneTwoThreeValues : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumOneTwoThreeValues *one __attribute__((swift_name("one"))); @property (class, readonly) KtEnumOneTwoThreeValues *two __attribute__((swift_name("two"))); @property (class, readonly) KtEnumOneTwoThreeValues *three __attribute__((swift_name("three"))); @property (class, readonly) KtEnumOneTwoThreeValues *values __attribute__((swift_name("values"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EnumValuesValues_"))) @interface KtEnumValuesValues_ : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); @property (class, readonly) KtEnumValuesValues_ *values __attribute__((swift_name("values"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("EmptyEnum"))) @interface KtEmptyEnum : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; __attribute__((swift_name("FunInterface"))) @protocol KtFunInterface @required - (int32_t)run __attribute__((swift_name("run()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FunInterfacesKt"))) @interface KtFunInterfacesKt : KtBase + (id)getObject __attribute__((swift_name("getObject()"))); + (id)getLambda __attribute__((swift_name("getLambda()"))); @end; __attribute__((swift_name("FHolder"))) @interface KtFHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) id _Nullable value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F2Holder"))) @interface KtF2Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable) __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F32Holder"))) @interface KtF32Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id _Nullable (^value)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable) __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("F33Holder"))) @interface KtF33Holder : KtFHolder - (instancetype)initWithValue:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) id value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FunctionalTypesKt"))) @interface KtFunctionalTypesKt : KtBase + (void)callDynType2List:(NSArray *)list param:(id _Nullable)param __attribute__((swift_name("callDynType2(list:param:)"))); + (void)callStaticType2Fct:(id _Nullable (^)(id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType2(fct:param:)"))); + (void)callDynType32List:(NSArray *)list param:(id _Nullable)param __attribute__((swift_name("callDynType32(list:param:)"))); + (void)callStaticType32Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType32(fct:param:)"))); + (void)callDynType33List:(NSArray> *)list param:(id _Nullable)param __attribute__((swift_name("callDynType33(list:param:)"))); + (void)callStaticType33Fct:(id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))fct param:(id _Nullable)param __attribute__((swift_name("callStaticType33(fct:param:)"))); + (KtF2Holder *)getDynTypeLambda2 __attribute__((swift_name("getDynTypeLambda2()"))); + (id _Nullable (^)(id _Nullable, id _Nullable))getStaticLambda2 __attribute__((swift_name("getStaticLambda2()"))); + (KtF2Holder *)getDynTypeRef2 __attribute__((swift_name("getDynTypeRef2()"))); + (id _Nullable (^)(id _Nullable, id _Nullable))getStaticRef2 __attribute__((swift_name("getStaticRef2()"))); + (KtF32Holder *)getDynType32 __attribute__((swift_name("getDynType32()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticType32 __attribute__((swift_name("getStaticType32()"))); + (KtF33Holder *)getDynTypeRef33 __attribute__((swift_name("getDynTypeRef33()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeRef33 __attribute__((swift_name("getStaticTypeRef33()"))); + (KtF33Holder *)getDynTypeLambda33 __attribute__((swift_name("getDynTypeLambda33()"))); + (id _Nullable (^)(id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable, id _Nullable))getStaticTypeLambda33 __attribute__((swift_name("getStaticTypeLambda33()"))); @end; __attribute__((swift_name("GH4002ArgumentBase"))) @interface KtGH4002ArgumentBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH4002Argument"))) @interface KtGH4002Argument : KtGH4002ArgumentBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarning"))) @interface KtTestIncompatiblePropertyTypeWarning : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarning.Generic"))) @interface KtTestIncompatiblePropertyTypeWarningGeneric : KtBase - (instancetype)initWithValue:(id _Nullable)value __attribute__((swift_name("init(value:)"))) __attribute__((objc_designated_initializer)); @property (readonly) id _Nullable value __attribute__((swift_name("value"))); @end; __attribute__((swift_name("TestIncompatiblePropertyTypeWarningInterfaceWithGenericProperty"))) @protocol KtTestIncompatiblePropertyTypeWarningInterfaceWithGenericProperty @required @property (readonly) KtTestIncompatiblePropertyTypeWarningGeneric *p __attribute__((swift_name("p"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestIncompatiblePropertyTypeWarning.ClassOverridingInterfaceWithGenericProperty"))) @interface KtTestIncompatiblePropertyTypeWarningClassOverridingInterfaceWithGenericProperty : KtBase - (instancetype)initWithP:(KtTestIncompatiblePropertyTypeWarningGeneric *)p __attribute__((swift_name("init(p:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestIncompatiblePropertyTypeWarningGeneric *p __attribute__((swift_name("p"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992"))) @interface KtTestGH3992 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestGH3992.C"))) @interface KtTestGH3992C : KtBase - (instancetype)initWithA:(KtTestGH3992A *)a __attribute__((swift_name("init(a:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestGH3992A *a __attribute__((swift_name("a"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992.D"))) @interface KtTestGH3992D : KtTestGH3992C - (instancetype)initWithA:(KtTestGH3992B *)a __attribute__((swift_name("init(a:)"))) __attribute__((objc_designated_initializer)); @property (readonly) KtTestGH3992B *a __attribute__((swift_name("a"))); @end; __attribute__((swift_name("TestGH3992.A"))) @interface KtTestGH3992A : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestGH3992.B"))) @interface KtTestGH3992B : KtTestGH3992A - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt35940Kt"))) @interface KtKt35940Kt : KtBase + (NSString *)testKt35940 __attribute__((swift_name("testKt35940()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641"))) @interface KtKT38641 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.IntType"))) @interface KtKT38641IntType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (getter=description, setter=setDescription:) int32_t description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.Val"))) @interface KtKT38641Val : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.Var"))) @interface KtKT38641Var : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT38641.TwoProperties"))) @interface KtKT38641TwoProperties : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @property (readonly) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((swift_name("KT38641.OverrideVal"))) @interface KtKT38641OverrideVal : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly, getter=description) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((swift_name("KT38641OverrideVar"))) @protocol KtKT38641OverrideVar @required @property (getter=description, setter=setDescription:) NSString *description_ __attribute__((swift_name("description_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt38641Kt"))) @interface KtKt38641Kt : KtBase + (NSString *)getOverrideValDescriptionImpl:(KtKT38641OverrideVal *)impl __attribute__((swift_name("getOverrideValDescription(impl:)"))); + (NSString *)getOverrideVarDescriptionImpl:(id)impl __attribute__((swift_name("getOverrideVarDescription(impl:)"))); + (void)setOverrideVarDescriptionImpl:(id)impl newValue:(NSString *)newValue __attribute__((swift_name("setOverrideVarDescription(impl:newValue:)"))); @end; __attribute__((swift_name("JsonConfiguration"))) @interface KtJsonConfiguration : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("This class is deprecated for removal during serialization 1.0 API stabilization.\nFor configuring Json instances, the corresponding builder function can be used instead, e.g. instead of'Json(JsonConfiguration.Stable.copy(isLenient = true))' 'Json { isLenient = true }' should be used.\nInstead of storing JsonConfiguration instances of the code, Json instances can be used directly:'Json(MyJsonConfiguration.copy(prettyPrint = true))' can be replaced with 'Json(from = MyApplicationJson) { prettyPrint = true }'"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MoreTrickyChars"))) @interface KtMoreTrickyChars : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("'\"\\@$(){}\r\n"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt39206Kt"))) @interface KtKt39206Kt : KtBase + (int32_t)myFunc __attribute__((swift_name("myFunc()"))) __attribute__((deprecated("Don't call this\nPlease"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Ckt41907"))) @interface KtCkt41907 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("Ikt41907"))) @protocol KtIkt41907 @required - (void)fooC:(KtCkt41907 *)c __attribute__((swift_name("foo(c:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt41907Kt"))) @interface KtKt41907Kt : KtBase + (void)escapeCC:(KtCkt41907 *)c __attribute__((swift_name("escapeC(c:)"))); + (void)testKt41907O:(id)o __attribute__((swift_name("testKt41907(o:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("KT43599"))) @interface KtKT43599 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) NSString *memberProperty __attribute__((swift_name("memberProperty"))); @end; @interface KtKT43599 (Kt43599Kt) @property (readonly) NSString *extensionProperty __attribute__((swift_name("extensionProperty"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Kt43599Kt"))) @interface KtKt43599Kt : KtBase + (void)setTopLevelLateinitPropertyValue:(NSString *)value __attribute__((swift_name("setTopLevelLateinitProperty(value:)"))); @property (class, readonly) NSString *topLevelProperty __attribute__((swift_name("topLevelProperty"))); @property (class, readonly) NSString *topLevelLateinitProperty __attribute__((swift_name("topLevelLateinitProperty"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("LibraryKt"))) @interface KtLibraryKt : KtBase + (NSString *)readDataFromLibraryClassInput:(KtA *)input __attribute__((swift_name("readDataFromLibraryClass(input:)"))); + (NSString *)readDataFromLibraryInterfaceInput:(id)input __attribute__((swift_name("readDataFromLibraryInterface(input:)"))); + (NSString *)readDataFromLibraryEnumInput:(KtE *)input __attribute__((swift_name("readDataFromLibraryEnum(input:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysConstructor"))) @interface KtArraysConstructor : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysDefault"))) @interface KtArraysDefault : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ArraysInitBlock"))) @interface KtArraysInitBlock : KtBase - (instancetype)initWithInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("init(int1:int2:)"))) __attribute__((objc_designated_initializer)); - (void)setInt1:(int32_t)int1 int2:(int32_t)int2 __attribute__((swift_name("set(int1:int2:)"))); - (NSString *)log __attribute__((swift_name("log()"))); @end; __attribute__((swift_name("OverrideKotlinMethods2"))) @protocol KtOverrideKotlinMethods2 @required - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods3"))) @interface KtOverrideKotlinMethods3 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OverrideKotlinMethods4"))) @interface KtOverrideKotlinMethods4 : KtOverrideKotlinMethods3 - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods5"))) @protocol KtOverrideKotlinMethods5 @required - (int32_t)one __attribute__((swift_name("one()"))); @end; __attribute__((swift_name("OverrideKotlinMethods6"))) @protocol KtOverrideKotlinMethods6 @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OverrideKotlinMethodsKt"))) @interface KtOverrideKotlinMethodsKt : KtBase /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test0Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test0(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test1Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test1(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test2Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test2(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test3Obj:(KtOverrideKotlinMethods3 *)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test3(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test4Obj:(KtOverrideKotlinMethods4 *)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test4(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test5Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test5(obj:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)test6Obj:(id)obj error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test6(obj:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OverrideMethodsOfAnyKt"))) @interface KtOverrideMethodsOfAnyKt : KtBase /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testObj:(id)obj other:(id)other swift:(BOOL)swift error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("test(obj:other:swift:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ThrowsEmptyKt"))) @interface KtThrowsEmptyKt : KtBase /** @warning All uncaught Kotlin exceptions are fatal. */ + (BOOL)throwsEmptyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("throwsEmpty()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelManglingAKt"))) @interface KtTopLevelManglingAKt : KtBase + (NSString *)foo __attribute__((swift_name("foo()"))); + (int32_t)sameNumberValue:(int32_t)value __attribute__((swift_name("sameNumber(value:)"))); + (int64_t)sameNumberValue:(int64_t)value __attribute__((swift_name("sameNumber(value:)"))); @property (class, readonly) NSString *bar __attribute__((swift_name("bar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelManglingBKt"))) @interface KtTopLevelManglingBKt : KtBase + (NSString *)foo __attribute__((swift_name("foo()"))); @property (class, readonly) NSString *bar __attribute__((swift_name("bar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DelegateClass"))) @interface KtDelegateClass : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtKotlinArray *)getValueThisRef:(KtKotlinNothing * _Nullable)thisRef property:(id)property __attribute__((swift_name("getValue(thisRef:property:)"))); - (void)setValueThisRef:(KtKotlinNothing * _Nullable)thisRef property:(id)property value:(KtKotlinArray *)value __attribute__((swift_name("setValue(thisRef:property:value:)"))); @end; __attribute__((swift_name("I"))) @protocol KtI @required - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("DefaultInterfaceExt"))) @interface KtDefaultInterfaceExt : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OpenClassI"))) @interface KtOpenClassI : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("FinalClassExtOpen"))) @interface KtFinalClassExtOpen : KtOpenClassI - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((swift_name("MultiExtClass"))) @interface KtMultiExtClass : KtOpenClassI - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id)piFun __attribute__((swift_name("piFun()"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((swift_name("ConstrClass"))) @interface KtConstrClass : KtOpenClassI - (instancetype)initWithI:(int32_t)i s:(NSString *)s a:(id)a __attribute__((swift_name("init(i:s:a:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); @property (readonly) int32_t i __attribute__((swift_name("i"))); @property (readonly) NSString *s __attribute__((swift_name("s"))); @property (readonly) id a __attribute__((swift_name("a"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ExtConstrClass"))) @interface KtExtConstrClass : KtConstrClass - (instancetype)initWithI:(int32_t)i __attribute__((swift_name("init(i:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithI:(int32_t)i s:(NSString *)s a:(id)a __attribute__((swift_name("init(i:s:a:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @property (readonly) int32_t i __attribute__((swift_name("i"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Enumeration"))) @interface KtEnumeration : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtEnumeration *answer __attribute__((swift_name("answer"))); @property (class, readonly) KtEnumeration *year __attribute__((swift_name("year"))); @property (class, readonly) KtEnumeration *temperature __attribute__((swift_name("temperature"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @property (readonly) int32_t enumValue __attribute__((swift_name("enumValue"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TripleVals"))) @interface KtTripleVals : KtBase - (instancetype)initWithFirst:(id _Nullable)first second:(id _Nullable)second third:(id _Nullable)third __attribute__((swift_name("init(first:second:third:)"))) __attribute__((objc_designated_initializer)); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (NSString *)description __attribute__((swift_name("description()"))); - (id _Nullable)component1 __attribute__((swift_name("component1()"))); - (id _Nullable)component2 __attribute__((swift_name("component2()"))); - (id _Nullable)component3 __attribute__((swift_name("component3()"))); - (KtTripleVals *)doCopyFirst:(id _Nullable)first second:(id _Nullable)second third:(id _Nullable)third __attribute__((swift_name("doCopy(first:second:third:)"))); @property (readonly) id _Nullable first __attribute__((swift_name("first"))); @property (readonly) id _Nullable second __attribute__((swift_name("second"))); @property (readonly) id _Nullable third __attribute__((swift_name("third"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TripleVars"))) @interface KtTripleVars : KtBase - (instancetype)initWithFirst:(id _Nullable)first second:(id _Nullable)second third:(id _Nullable)third __attribute__((swift_name("init(first:second:third:)"))) __attribute__((objc_designated_initializer)); - (NSString *)description __attribute__((swift_name("description()"))); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (id _Nullable)component1 __attribute__((swift_name("component1()"))); - (id _Nullable)component2 __attribute__((swift_name("component2()"))); - (id _Nullable)component3 __attribute__((swift_name("component3()"))); - (KtTripleVars *)doCopyFirst:(id _Nullable)first second:(id _Nullable)second third:(id _Nullable)third __attribute__((swift_name("doCopy(first:second:third:)"))); @property id _Nullable first __attribute__((swift_name("first"))); @property id _Nullable second __attribute__((swift_name("second"))); @property id _Nullable third __attribute__((swift_name("third"))); @end; __attribute__((swift_name("WithCompanionAndObject"))) @interface KtWithCompanionAndObject : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithCompanionAndObject.Companion"))) @interface KtWithCompanionAndObjectCompanion : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)companion __attribute__((swift_name("init()"))); @property (readonly) NSString *str __attribute__((swift_name("str"))); @property id _Nullable named __attribute__((swift_name("named"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithCompanionAndObject.Named"))) @interface KtWithCompanionAndObjectNamed : KtOpenClassI + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (instancetype)named __attribute__((swift_name("init()"))); - (NSString *)iFun __attribute__((swift_name("iFun()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MyException"))) @interface KtMyException : KtKotlinException - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("MyError"))) @interface KtMyError : KtKotlinError - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithMessage:(NSString * _Nullable)message __attribute__((swift_name("init(message:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithMessage:(NSString * _Nullable)message cause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(message:cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithCause:(KtKotlinThrowable * _Nullable)cause __attribute__((swift_name("init(cause:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((swift_name("SwiftOverridableMethodsWithThrows"))) @protocol KtSwiftOverridableMethodsWithThrows @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); @end; __attribute__((swift_name("MethodsWithThrows"))) @protocol KtMethodsWithThrows @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((swift_name("MethodsWithThrowsUnitCaller"))) @protocol KtMethodsWithThrowsUnitCaller @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)callMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call(methods:)"))); @end; __attribute__((swift_name("Throwing"))) @interface KtThrowing : KtBase /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (instancetype _Nullable)initWithDoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init(doThrow:)"))) __attribute__((objc_designated_initializer)); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("NotThrowing"))) @interface KtNotThrowing : KtBase /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (instancetype _Nullable)initAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)unitAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("unit()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)nothingAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothing()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtKotlinNothing * _Nullable)nothingNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("nothingN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("any()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)anyNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("anyN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("block()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt *(^ _Nullable)(void))blockNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("blockN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointer()"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (void * _Nullable)pointerNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("pointerN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (int32_t)intAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("int()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtLong * _Nullable)longNAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("longN()"))) __attribute__((swift_error(nonnull_error))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (double)doubleAndReturnError:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("double()"))) __attribute__((swift_error(nonnull_error))); @end; __attribute__((swift_name("ThrowsWithBridgeBase"))) @protocol KtThrowsWithBridgeBase @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (id _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)"))); @end; __attribute__((swift_name("ThrowsWithBridge"))) @interface KtThrowsWithBridge : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (KtInt * _Nullable)plusOneX:(int32_t)x error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("plusOne(x:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply"))) @interface KtDeeply : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply.Nested"))) @interface KtDeeplyNested : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Deeply.NestedType"))) @interface KtDeeplyNestedType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyTwo __attribute__((swift_name("thirtyTwo"))); @end; __attribute__((swift_name("DeeplyNestedIType"))) @protocol KtDeeplyNestedIType @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeply"))) @interface KtWithGenericDeeply : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeply.Nested"))) @interface KtWithGenericDeeplyNested : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("WithGenericDeeply.NestedType"))) @interface KtWithGenericDeeplyNestedType : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyThree __attribute__((swift_name("thirtyThree"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TypeOuter"))) @interface KtTypeOuter : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TypeOuter.Type_"))) @interface KtTypeOuterType_ : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t thirtyFour __attribute__((swift_name("thirtyFour"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("CKeywords"))) @interface KtCKeywords : KtBase - (instancetype)initWithFloat:(float)float_ enum:(int32_t)enum_ goto:(BOOL)goto_ __attribute__((swift_name("init(float:enum:goto:)"))) __attribute__((objc_designated_initializer)); - (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)"))); - (NSUInteger)hash __attribute__((swift_name("hash()"))); - (NSString *)description __attribute__((swift_name("description()"))); - (float)component1 __attribute__((swift_name("component1()"))); - (int32_t)component2 __attribute__((swift_name("component2()"))); - (BOOL)component3 __attribute__((swift_name("component3()"))); - (KtCKeywords *)doCopyFloat:(float)float_ enum:(int32_t)enum_ goto:(BOOL)goto_ __attribute__((swift_name("doCopy(float:enum:goto:)"))); @property (readonly, getter=float) float float_ __attribute__((swift_name("float_"))); @property (readonly, getter=enum) int32_t enum_ __attribute__((swift_name("enum_"))); @property (getter=goto, setter=setGoto:) BOOL goto_ __attribute__((swift_name("goto_"))); @end; __attribute__((swift_name("Base1"))) @protocol KtBase1 @required - (KtInt * _Nullable)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("ExtendedBase1"))) @protocol KtExtendedBase1 @required @end; __attribute__((swift_name("Base2"))) @protocol KtBase2 @required - (KtInt * _Nullable)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("Base23"))) @interface KtBase23 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtInt *)sameValue:(KtInt * _Nullable)value __attribute__((swift_name("same(value:)"))); @end; __attribute__((swift_name("Transform"))) @protocol KtTransform @required - (id _Nullable)mapValue:(id _Nullable)value __attribute__((swift_name("map(value:)"))); @end; __attribute__((swift_name("TransformWithDefault"))) @protocol KtTransformWithDefault @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TransformInheritingDefault"))) @interface KtTransformInheritingDefault : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TransformIntString"))) @protocol KtTransformIntString @required - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToString"))) @interface KtTransformIntToString : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)mapValue:(KtInt *)intValue __attribute__((swift_name("map(value:)"))); - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToDecimalString"))) @interface KtTransformIntToDecimalString : KtTransformIntToString - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSString *)mapValue:(KtInt *)intValue __attribute__((swift_name("map(value:)"))); - (NSString *)mapIntValue:(int32_t)intValue __attribute__((swift_name("map(intValue:)"))); @end; __attribute__((swift_name("TransformIntToLong"))) @interface KtTransformIntToLong : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtLong *)mapValue:(KtInt *)value __attribute__((swift_name("map(value:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931"))) @interface KtGH2931 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931.Data"))) @interface KtGH2931Data : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2931.Holder"))) @interface KtGH2931Holder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) KtGH2931Data *data __attribute__((swift_name("data"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2945"))) @interface KtGH2945 : KtBase - (instancetype)initWithErrno:(int32_t)errno __attribute__((swift_name("init(errno:)"))) __attribute__((objc_designated_initializer)); - (int32_t)testErrnoInSelectorP:(int32_t)p errno:(int32_t)errno __attribute__((swift_name("testErrnoInSelector(p:errno:)"))); @property int32_t errno __attribute__((swift_name("errno"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2830"))) @interface KtGH2830 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id)getI __attribute__((swift_name("getI()"))); @end; __attribute__((swift_name("GH2830I"))) @protocol KtGH2830I @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH2959"))) @interface KtGH2959 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (NSArray> *)getIId:(int32_t)id __attribute__((swift_name("getI(id:)"))); @end; __attribute__((swift_name("GH2959I"))) @protocol KtGH2959I @required @property (readonly) int32_t id __attribute__((swift_name("id"))); @end; __attribute__((swift_name("IntBlocks"))) @protocol KtIntBlocks @required - (id _Nullable)getPlusOneBlock __attribute__((swift_name("getPlusOneBlock()"))); - (int32_t)callBlockArgument:(int32_t)argument block:(id _Nullable)block __attribute__((swift_name("callBlock(argument:block:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("IntBlocksImpl"))) @interface KtIntBlocksImpl : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)intBlocksImpl __attribute__((swift_name("init()"))); - (KtInt *(^)(KtInt *))getPlusOneBlock __attribute__((swift_name("getPlusOneBlock()"))); - (int32_t)callBlockArgument:(int32_t)argument block:(KtInt *(^)(KtInt *))block __attribute__((swift_name("callBlock(argument:block:)"))); @end; __attribute__((swift_name("UnitBlockCoercion"))) @protocol KtUnitBlockCoercion @required - (id)coerceBlock:(void (^)(void))block __attribute__((swift_name("coerce(block:)"))); - (void (^)(void))uncoerceBlock:(id)block __attribute__((swift_name("uncoerce(block:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("UnitBlockCoercionImpl"))) @interface KtUnitBlockCoercionImpl : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)unitBlockCoercionImpl __attribute__((swift_name("init()"))); - (KtKotlinUnit *(^)(void))coerceBlock:(void (^)(void))block __attribute__((swift_name("coerce(block:)"))); - (void (^)(void))uncoerceBlock:(KtKotlinUnit *(^)(void))block __attribute__((swift_name("uncoerce(block:)"))); @end; __attribute__((swift_name("MyAbstractList"))) @interface KtMyAbstractList : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestKClass"))) @interface KtTestKClass : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (id _Nullable)getKotlinClassClazz:(Class)clazz __attribute__((swift_name("getKotlinClass(clazz:)"))); - (id _Nullable)getKotlinClassProtocol:(Protocol *)protocol __attribute__((swift_name("getKotlinClass(protocol:)"))); - (BOOL)isTestKClassKClass:(id)kClass __attribute__((swift_name("isTestKClass(kClass:)"))); - (BOOL)isIKClass:(id)kClass __attribute__((swift_name("isI(kClass:)"))); @end; __attribute__((swift_name("TestKClassI"))) @protocol KtTestKClassI @required @end; __attribute__((swift_name("ForwardI2"))) @protocol KtForwardI2 @required @end; __attribute__((swift_name("ForwardI1"))) @protocol KtForwardI1 @required - (id)getForwardI2 __attribute__((swift_name("getForwardI2()"))); @end; __attribute__((swift_name("ForwardC2"))) @interface KtForwardC2 : KtForwardC1 - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("ForwardC1"))) @interface KtForwardC1 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtForwardC2 *)getForwardC2 __attribute__((swift_name("getForwardC2()"))); @end; __attribute__((swift_name("TestSR10177Workaround"))) @protocol KtTestSR10177Workaround @required @end; __attribute__((swift_name("TestClashes1"))) @protocol KtTestClashes1 @required @property (readonly) int32_t clashingProperty __attribute__((swift_name("clashingProperty"))); @end; __attribute__((swift_name("TestClashes2"))) @protocol KtTestClashes2 @required @property (readonly) id clashingProperty __attribute__((swift_name("clashingProperty"))); @property (readonly) id clashingProperty_ __attribute__((swift_name("clashingProperty_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestClashesImpl"))) @interface KtTestClashesImpl : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property (readonly) int32_t clashingProperty __attribute__((swift_name("clashingProperty"))); @property (readonly) KtInt *clashingProperty_ __attribute__((swift_name("clashingProperty_"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers"))) @interface KtTestInvalidIdentifiers : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)a_d_d_1:(int32_t)_1 _2:(int32_t)_2 _3:(int32_t)_3 __attribute__((swift_name("a_d_d(_1:_2:_3:)"))); @property NSString *_status __attribute__((swift_name("_status"))); @property (readonly) unichar __ __attribute__((swift_name("__"))); @property (readonly) unichar __ __attribute__((swift_name("__"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers._Foo"))) @interface KtTestInvalidIdentifiers_Foo : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.Bar_"))) @interface KtTestInvalidIdentifiersBar_ : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.E"))) @interface KtTestInvalidIdentifiersE : KtKotlinEnum + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)initWithName:(NSString *)name ordinal:(int32_t)ordinal __attribute__((swift_name("init(name:ordinal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @property (class, readonly) KtTestInvalidIdentifiersE *_4_ __attribute__((swift_name("_4_"))); @property (class, readonly) KtTestInvalidIdentifiersE *_5_ __attribute__((swift_name("_5_"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); @property (class, readonly) KtTestInvalidIdentifiersE *__ __attribute__((swift_name("__"))); + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @property (readonly) int32_t value __attribute__((swift_name("value"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestInvalidIdentifiers.Companion_"))) @interface KtTestInvalidIdentifiersCompanion_ : KtBase + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); + (instancetype)companion_ __attribute__((swift_name("init()"))); @property (readonly) int32_t _42 __attribute__((swift_name("_42"))); @end; __attribute__((swift_name("TestDeprecation"))) @interface KtTestDeprecation : KtBase - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)callEffectivelyHiddenObj:(id)obj __attribute__((swift_name("callEffectivelyHidden(obj:)"))); - (id)getHidden __attribute__((swift_name("getHidden()"))); - (KtTestDeprecationError *)getError __attribute__((swift_name("getError()"))); - (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("error"))); - (KtTestDeprecationWarning *)getWarning __attribute__((swift_name("getWarning()"))); - (void)warning __attribute__((swift_name("warning()"))) __attribute__((deprecated("warning"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("warning"))); - (void)normal __attribute__((swift_name("normal()"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))); - (void)testHiddenNested:(id)hiddenNested __attribute__((swift_name("test(hiddenNested:)"))); - (void)testHiddenNestedNested:(id)hiddenNestedNested __attribute__((swift_name("test(hiddenNestedNested:)"))); - (void)testHiddenNestedInner:(id)hiddenNestedInner __attribute__((swift_name("test(hiddenNestedInner:)"))); - (void)testHiddenInner:(id)hiddenInner __attribute__((swift_name("test(hiddenInner:)"))); - (void)testHiddenInnerInner:(id)hiddenInnerInner __attribute__((swift_name("test(hiddenInnerInner:)"))); - (void)testTopLevelHidden:(id)topLevelHidden __attribute__((swift_name("test(topLevelHidden:)"))); - (void)testTopLevelHiddenNested:(id)topLevelHiddenNested __attribute__((swift_name("test(topLevelHiddenNested:)"))); - (void)testTopLevelHiddenNestedNested:(id)topLevelHiddenNestedNested __attribute__((swift_name("test(topLevelHiddenNestedNested:)"))); - (void)testTopLevelHiddenNestedInner:(id)topLevelHiddenNestedInner __attribute__((swift_name("test(topLevelHiddenNestedInner:)"))); - (void)testTopLevelHiddenInner:(id)topLevelHiddenInner __attribute__((swift_name("test(topLevelHiddenInner:)"))); - (void)testTopLevelHiddenInnerInner:(id)topLevelHiddenInnerInner __attribute__((swift_name("test(topLevelHiddenInnerInner:)"))); - (void)testExtendingHiddenNested:(id)extendingHiddenNested __attribute__((swift_name("test(extendingHiddenNested:)"))); - (void)testExtendingNestedInHidden:(id)extendingNestedInHidden __attribute__((swift_name("test(extendingNestedInHidden:)"))); @property (readonly) id _Nullable errorVal __attribute__((swift_name("errorVal"))) __attribute__((unavailable("error"))); @property id _Nullable errorVar __attribute__((swift_name("errorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable warningVal __attribute__((swift_name("warningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable warningVar __attribute__((swift_name("warningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable normalVal __attribute__((swift_name("normalVal"))); @property id _Nullable normalVar __attribute__((swift_name("normalVar"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))); @end; __attribute__((swift_name("TestDeprecation.OpenHidden"))) @interface KtTestDeprecationOpenHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingHidden"))) @interface KtTestDeprecationExtendingHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingHiddenNested"))) @interface KtTestDeprecationExtendingHiddenNested : NSObject @end; __attribute__((swift_name("TestDeprecationHiddenInterface"))) @protocol KtTestDeprecationHiddenInterface @required @end; __attribute__((swift_name("TestDeprecation.ImplementingHidden"))) @interface KtTestDeprecationImplementingHidden : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)effectivelyHidden __attribute__((swift_name("effectivelyHidden()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Hidden"))) @interface KtTestDeprecationHidden : NSObject @end; __attribute__((swift_name("TestDeprecation.HiddenNested"))) @interface KtTestDeprecationHiddenNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenNestedNested"))) @interface KtTestDeprecationHiddenNestedNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenNestedInner"))) @interface KtTestDeprecationHiddenNestedInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenInner"))) @interface KtTestDeprecationHiddenInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenInnerInner"))) @interface KtTestDeprecationHiddenInnerInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingNestedInHidden"))) @interface KtTestDeprecationExtendingNestedInHidden : NSObject @end; __attribute__((swift_name("TestDeprecation.OpenError"))) @interface KtTestDeprecationOpenError : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingError"))) @interface KtTestDeprecationExtendingError : KtTestDeprecationOpenError - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestDeprecationErrorInterface"))) @protocol KtTestDeprecationErrorInterface @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ImplementingError"))) @interface KtTestDeprecationImplementingError : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Error"))) @interface KtTestDeprecationError : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((swift_name("TestDeprecation.OpenWarning"))) @interface KtTestDeprecationOpenWarning : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ExtendingWarning"))) @interface KtTestDeprecationExtendingWarning : KtTestDeprecationOpenWarning - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("TestDeprecationWarningInterface"))) @protocol KtTestDeprecationWarningInterface @required @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ImplementingWarning"))) @interface KtTestDeprecationImplementingWarning : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.Warning"))) @interface KtTestDeprecationWarning : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.HiddenOverride"))) @interface KtTestDeprecationHiddenOverride : KtTestDeprecation - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("hidden"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((unavailable("hidden"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((unavailable("hidden"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((unavailable("hidden"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((unavailable("hidden"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.ErrorOverride"))) @interface KtTestDeprecationErrorOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable("error"))); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openHidden __attribute__((swift_name("openHidden()"))) __attribute__((unavailable("error"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("error"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((unavailable("error"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openHiddenVal __attribute__((swift_name("openHiddenVal"))) __attribute__((unavailable("error"))); @property id _Nullable openHiddenVar __attribute__((swift_name("openHiddenVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((unavailable("error"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((unavailable("error"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((unavailable("error"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((unavailable("error"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.WarningOverride"))) @interface KtTestDeprecationWarningOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)) __attribute__((deprecated("warning"))); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openHidden __attribute__((swift_name("openHidden()"))) __attribute__((deprecated("warning"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((deprecated("warning"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("warning"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openHiddenVal __attribute__((swift_name("openHiddenVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openHiddenVar __attribute__((swift_name("openHiddenVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("warning"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))) __attribute__((deprecated("warning"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))) __attribute__((deprecated("warning"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestDeprecation.NormalOverride"))) @interface KtTestDeprecationNormalOverride : KtTestDeprecation - (instancetype)initWithHidden:(int8_t)hidden __attribute__((swift_name("init(hidden:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithError:(int16_t)error __attribute__((swift_name("init(error:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithWarning:(int32_t)warning __attribute__((swift_name("init(warning:)"))) __attribute__((objc_designated_initializer)); - (instancetype)initWithNormal:(int64_t)normal __attribute__((swift_name("init(normal:)"))) __attribute__((objc_designated_initializer)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)openError __attribute__((swift_name("openError()"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); - (void)openWarning __attribute__((swift_name("openWarning()"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); - (int32_t)openNormal __attribute__((swift_name("openNormal()"))); @property (readonly) id _Nullable openErrorVal __attribute__((swift_name("openErrorVal"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); @property id _Nullable openErrorVar __attribute__((swift_name("openErrorVar"))) __attribute__((unavailable("Overrides deprecated member in 'conversions.TestDeprecation'. error"))); @property (readonly) id _Nullable openWarningVal __attribute__((swift_name("openWarningVal"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); @property id _Nullable openWarningVar __attribute__((swift_name("openWarningVar"))) __attribute__((deprecated("Overrides deprecated member in 'conversions.TestDeprecation'. warning"))); @property (readonly) id _Nullable openNormalVal __attribute__((swift_name("openNormalVal"))); @property id _Nullable openNormalVar __attribute__((swift_name("openNormalVar"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden"))) @interface KtTopLevelHidden : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.Nested"))) @interface KtTopLevelHiddenNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.NestedNested"))) @interface KtTopLevelHiddenNestedNested : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.NestedInner"))) @interface KtTopLevelHiddenNestedInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.Inner"))) @interface KtTopLevelHiddenInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TopLevelHidden.InnerInner"))) @interface KtTopLevelHiddenInnerInner : NSObject @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestWeakRefs"))) @interface KtTestWeakRefs : KtBase - (instancetype)initWithFrozen:(BOOL)frozen __attribute__((swift_name("init(frozen:)"))) __attribute__((objc_designated_initializer)); - (id)getObj __attribute__((swift_name("getObj()"))); - (void)clearObj __attribute__((swift_name("clearObj()"))); - (NSArray *)createCycle __attribute__((swift_name("createCycle()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("SharedRefs"))) @interface KtSharedRefs : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (KtSharedRefsMutableData *)createRegularObject __attribute__((swift_name("createRegularObject()"))); - (void (^)(void))createLambda __attribute__((swift_name("createLambda()"))); - (NSMutableArray *)createCollection __attribute__((swift_name("createCollection()"))); - (KtSharedRefsMutableData *)createFrozenRegularObject __attribute__((swift_name("createFrozenRegularObject()"))); - (void (^)(void))createFrozenLambda __attribute__((swift_name("createFrozenLambda()"))); - (NSMutableArray *)createFrozenCollection __attribute__((swift_name("createFrozenCollection()"))); - (BOOL)hasAliveObjects __attribute__((swift_name("hasAliveObjects()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("SharedRefs.MutableData"))) @interface KtSharedRefsMutableData : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (void)update __attribute__((swift_name("update()"))); @property int32_t x __attribute__((swift_name("x"))); @end; __attribute__((swift_name("TestRememberNewObject"))) @protocol KtTestRememberNewObject @required - (id)getObject __attribute__((swift_name("getObject()"))); - (void)waitForCleanup __attribute__((swift_name("waitForCleanup()"))); @end; __attribute__((swift_name("ClassForTypeCheck"))) @interface KtClassForTypeCheck : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("InterfaceForTypeCheck"))) @protocol KtInterfaceForTypeCheck @required @end; __attribute__((swift_name("IAbstractInterface"))) @protocol KtIAbstractInterface @required - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("IAbstractInterface2"))) @protocol KtIAbstractInterface2 @required - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("AbstractInterfaceBase"))) @interface KtAbstractInterfaceBase : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)foo __attribute__((swift_name("foo()"))); - (int32_t)bar __attribute__((swift_name("bar()"))); @end; __attribute__((swift_name("AbstractInterfaceBase2"))) @interface KtAbstractInterfaceBase2 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("AbstractInterfaceBase3"))) @interface KtAbstractInterfaceBase3 : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); - (int32_t)foo __attribute__((swift_name("foo()"))); @end; __attribute__((swift_name("GH3525Base"))) @interface KtGH3525Base : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH3525"))) @interface KtGH3525 : KtGH3525Base + (instancetype)alloc __attribute__((unavailable)); + (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable)); - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)) __attribute__((unavailable)); + (instancetype)new __attribute__((unavailable)); + (instancetype)gH3525 __attribute__((swift_name("init()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("TestStringConversion"))) @interface KtTestStringConversion : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @property id str __attribute__((swift_name("str"))); @end; __attribute__((swift_name("GH3825"))) @protocol KtGH3825 @required /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call0AndReturnError:(NSError * _Nullable * _Nullable)error callback:(KtBoolean *(^)(void))callback __attribute__((swift_name("call0(callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call1DoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error callback:(void (^)(void))callback __attribute__((swift_name("call1(doThrow:callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call2Callback:(void (^)(void))callback doThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call2(callback:doThrow:)"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("GH3825KotlinImpl"))) @interface KtGH3825KotlinImpl : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call0AndReturnError:(NSError * _Nullable * _Nullable)error callback:(KtBoolean *(^)(void))callback __attribute__((swift_name("call0(callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call1DoThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error callback:(void (^)(void))callback __attribute__((swift_name("call1(doThrow:callback:)"))); /** @note This method converts instances of MyException to errors. Other uncaught Kotlin exceptions are fatal. */ - (BOOL)call2Callback:(void (^)(void))callback doThrow:(BOOL)doThrow error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("call2(callback:doThrow:)"))); @end; __attribute__((swift_name("Foo_FakeOverrideInInterface"))) @protocol KtFoo_FakeOverrideInInterface @required - (void)fooT:(id _Nullable)t __attribute__((swift_name("foo(t:)"))); @end; __attribute__((swift_name("Bar_FakeOverrideInInterface"))) @protocol KtBar_FakeOverrideInInterface @required @end; @interface KtEnumeration (ValuesKt) - (KtEnumeration *)getAnswer __attribute__((swift_name("getAnswer()"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("ValuesKt"))) @interface KtValuesKt : KtBase + (KtBoolean * _Nullable)boxBooleanValue:(BOOL)booleanValue __attribute__((swift_name("box(booleanValue:)"))); + (KtByte * _Nullable)boxByteValue:(int8_t)byteValue __attribute__((swift_name("box(byteValue:)"))); + (KtShort * _Nullable)boxShortValue:(int16_t)shortValue __attribute__((swift_name("box(shortValue:)"))); + (KtInt * _Nullable)boxIntValue:(int32_t)intValue __attribute__((swift_name("box(intValue:)"))); + (KtLong * _Nullable)boxLongValue:(int64_t)longValue __attribute__((swift_name("box(longValue:)"))); + (KtUByte * _Nullable)boxUByteValue:(uint8_t)uByteValue __attribute__((swift_name("box(uByteValue:)"))); + (KtUShort * _Nullable)boxUShortValue:(uint16_t)uShortValue __attribute__((swift_name("box(uShortValue:)"))); + (KtUInt * _Nullable)boxUIntValue:(uint32_t)uIntValue __attribute__((swift_name("box(uIntValue:)"))); + (KtULong * _Nullable)boxULongValue:(uint64_t)uLongValue __attribute__((swift_name("box(uLongValue:)"))); + (KtFloat * _Nullable)boxFloatValue:(float)floatValue __attribute__((swift_name("box(floatValue:)"))); + (KtDouble * _Nullable)boxDoubleValue:(double)doubleValue __attribute__((swift_name("box(doubleValue:)"))); + (void)ensureEqualBooleansActual:(KtBoolean * _Nullable)actual expected:(BOOL)expected __attribute__((swift_name("ensureEqualBooleans(actual:expected:)"))); + (void)ensureEqualBytesActual:(KtByte * _Nullable)actual expected:(int8_t)expected __attribute__((swift_name("ensureEqualBytes(actual:expected:)"))); + (void)ensureEqualShortsActual:(KtShort * _Nullable)actual expected:(int16_t)expected __attribute__((swift_name("ensureEqualShorts(actual:expected:)"))); + (void)ensureEqualIntsActual:(KtInt * _Nullable)actual expected:(int32_t)expected __attribute__((swift_name("ensureEqualInts(actual:expected:)"))); + (void)ensureEqualLongsActual:(KtLong * _Nullable)actual expected:(int64_t)expected __attribute__((swift_name("ensureEqualLongs(actual:expected:)"))); + (void)ensureEqualUBytesActual:(KtUByte * _Nullable)actual expected:(uint8_t)expected __attribute__((swift_name("ensureEqualUBytes(actual:expected:)"))); + (void)ensureEqualUShortsActual:(KtUShort * _Nullable)actual expected:(uint16_t)expected __attribute__((swift_name("ensureEqualUShorts(actual:expected:)"))); + (void)ensureEqualUIntsActual:(KtUInt * _Nullable)actual expected:(uint32_t)expected __attribute__((swift_name("ensureEqualUInts(actual:expected:)"))); + (void)ensureEqualULongsActual:(KtULong * _Nullable)actual expected:(uint64_t)expected __attribute__((swift_name("ensureEqualULongs(actual:expected:)"))); + (void)ensureEqualFloatsActual:(KtFloat * _Nullable)actual expected:(float)expected __attribute__((swift_name("ensureEqualFloats(actual:expected:)"))); + (void)ensureEqualDoublesActual:(KtDouble * _Nullable)actual expected:(double)expected __attribute__((swift_name("ensureEqualDoubles(actual:expected:)"))); + (void)emptyFun __attribute__((swift_name("emptyFun()"))); + (NSString *)strFun __attribute__((swift_name("strFun()"))); + (id)argsFunI:(int32_t)i l:(int64_t)l d:(double)d s:(NSString *)s __attribute__((swift_name("argsFun(i:l:d:s:)"))); + (NSString *)funArgumentFoo:(NSString *(^)(void))foo __attribute__((swift_name("funArgument(foo:)"))); + (id _Nullable)genericFooT:(id _Nullable)t foo:(id _Nullable (^)(id _Nullable))foo __attribute__((swift_name("genericFoo(t:foo:)"))); + (id)fooGenericNumberR:(id)r foo:(id (^)(id))foo __attribute__((swift_name("fooGenericNumber(r:foo:)"))); + (NSArray *)varargToListArgs:(KtKotlinArray *)args __attribute__((swift_name("varargToList(args:)"))); + (NSString *)subExt:(NSString *)receiver i:(int32_t)i __attribute__((swift_name("subExt(_:i:)"))); + (NSString *)toString:(id _Nullable)receiver __attribute__((swift_name("toString(_:)"))); + (void)print:(id _Nullable)receiver __attribute__((swift_name("print(_:)"))); + (id _Nullable)boxChar:(unichar)receiver __attribute__((swift_name("boxChar(_:)"))); + (BOOL)isA:(id _Nullable)receiver __attribute__((swift_name("isA(_:)"))); + (NSString *)iFunExt:(id)receiver __attribute__((swift_name("iFunExt(_:)"))); + (KtEnumeration *)passEnum __attribute__((swift_name("passEnum()"))); + (void)receiveEnumE:(int32_t)e __attribute__((swift_name("receiveEnum(e:)"))); + (KtEnumeration *)getValue:(int32_t)value __attribute__((swift_name("get(value:)"))); + (KtWithCompanionAndObjectCompanion *)getCompanionObject __attribute__((swift_name("getCompanionObject()"))); + (KtWithCompanionAndObjectNamed *)getNamedObject __attribute__((swift_name("getNamedObject()"))); + (KtOpenClassI *)getNamedObjectInterface __attribute__((swift_name("getNamedObjectInterface()"))); + (id)boxIc1:(int32_t)ic1 __attribute__((swift_name("box(ic1:)"))); + (id)boxIc2:(id)ic2 __attribute__((swift_name("box(ic2:)"))); + (id)boxIc3:(id _Nullable)ic3 __attribute__((swift_name("box(ic3:)"))); + (NSString *)concatenateInlineClassValuesIc1:(int32_t)ic1 ic1N:(id _Nullable)ic1N ic2:(id)ic2 ic2N:(id _Nullable)ic2N ic3:(id _Nullable)ic3 ic3N:(id _Nullable)ic3N __attribute__((swift_name("concatenateInlineClassValues(ic1:ic1N:ic2:ic2N:ic3:ic3N:)"))); + (int32_t)getValue1:(int32_t)receiver __attribute__((swift_name("getValue1(_:)"))); + (KtInt * _Nullable)getValueOrNull1:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull1(_:)"))); + (NSString *)getValue2:(id)receiver __attribute__((swift_name("getValue2(_:)"))); + (NSString * _Nullable)getValueOrNull2:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull2(_:)"))); + (KtTripleVals * _Nullable)getValue3:(id _Nullable)receiver __attribute__((swift_name("getValue3(_:)"))); + (KtTripleVals * _Nullable)getValueOrNull3:(id _Nullable)receiver __attribute__((swift_name("getValueOrNull3(_:)"))); + (BOOL)isFrozenObj:(id)obj __attribute__((swift_name("isFrozen(obj:)"))); + (id)kotlinLambdaBlock:(id (^)(id))block __attribute__((swift_name("kotlinLambda(block:)"))); + (int64_t)multiplyInt:(int32_t)int_ long:(int64_t)long_ __attribute__((swift_name("multiply(int:long:)"))); /** @note This method converts instances of MyException, MyError to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)throwExceptionError:(BOOL)error error:(NSError * _Nullable * _Nullable)error_ __attribute__((swift_name("throwException(error:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (KtKotlinObjCErrorException * _Nullable)testSwiftThrowingMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftNotThrowingMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(methods:)"))); /** @note This method converts instances of MyError to errors. Other uncaught Kotlin exceptions are fatal. */ + (BOOL)callUnitMethods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnit(methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)callUnitCallerCaller:(id)caller methods:(id)methods error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("callUnitCaller(caller:methods:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftThrowingTest:(id)test flag:(BOOL)flag error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftThrowing(test:flag:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testSwiftNotThrowingTest:(id)test error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testSwiftNotThrowing(test:)"))); + (id)same:(id)receiver __attribute__((swift_name("same(_:)"))); + (KtInt * _Nullable)callBase1:(id)base1 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base1:value:)"))); + (KtInt * _Nullable)callExtendedBase1:(id)extendedBase1 value:(KtInt * _Nullable)value __attribute__((swift_name("call(extendedBase1:value:)"))); + (KtInt * _Nullable)callBase2:(id)base2 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base2:value:)"))); + (int32_t)callBase3:(id)base3 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base3:value:)"))); + (int32_t)callBase23:(KtBase23 *)base23 value:(KtInt * _Nullable)value __attribute__((swift_name("call(base23:value:)"))); + (id)createTransformDecimalStringToInt __attribute__((swift_name("createTransformDecimalStringToInt()"))); + (BOOL)runUnitBlockBlock:(void (^)(void))block __attribute__((swift_name("runUnitBlock(block:)"))); + (void (^)(void))asUnitBlockBlock:(id _Nullable (^)(void))block __attribute__((swift_name("asUnitBlock(block:)"))); + (BOOL)runNothingBlockBlock:(void (^)(void))block __attribute__((swift_name("runNothingBlock(block:)"))); + (void (^)(void))asNothingBlockBlock:(id _Nullable (^)(void))block __attribute__((swift_name("asNothingBlock(block:)"))); + (void (^ _Nullable)(void))getNullBlock __attribute__((swift_name("getNullBlock()"))); + (BOOL)isBlockNullBlock:(void (^ _Nullable)(void))block __attribute__((swift_name("isBlockNull(block:)"))); + (BOOL)isFunctionObj:(id _Nullable)obj __attribute__((swift_name("isFunction(obj:)"))); + (BOOL)isFunction0Obj:(id _Nullable)obj __attribute__((swift_name("isFunction0(obj:)"))); + (void)takeForwardDeclaredClassObj:(ForwardDeclaredClass *)obj __attribute__((swift_name("takeForwardDeclaredClass(obj:)"))); + (void)takeForwardDeclaredProtocolObj:(id)obj __attribute__((swift_name("takeForwardDeclaredProtocol(obj:)"))); + (void)error __attribute__((swift_name("error()"))) __attribute__((unavailable("error"))); + (void)warning __attribute__((swift_name("warning()"))) __attribute__((deprecated("warning"))); + (void)gc __attribute__((swift_name("gc()"))); + (void)testRememberNewObjectTest:(id)test __attribute__((swift_name("testRememberNewObject(test:)"))); + (BOOL)testClassTypeCheckX:(id)x __attribute__((swift_name("testClassTypeCheck(x:)"))); + (BOOL)testInterfaceTypeCheckX:(id)x __attribute__((swift_name("testInterfaceTypeCheck(x:)"))); + (int32_t)testAbstractInterfaceCallX:(id)x __attribute__((swift_name("testAbstractInterfaceCall(x:)"))); + (int32_t)testAbstractInterfaceCall2X:(id)x __attribute__((swift_name("testAbstractInterfaceCall2(x:)"))); + (void)fooA:(KtKotlinAtomicReference *)a __attribute__((swift_name("foo(a:)"))); /** @note This method converts all Kotlin exceptions to errors. */ + (BOOL)testGH3825Gh3825:(id)gh3825 error:(NSError * _Nullable * _Nullable)error __attribute__((swift_name("testGH3825(gh3825:)"))); + (NSDictionary *)mapBoolean2String __attribute__((swift_name("mapBoolean2String()"))); + (NSDictionary *)mapByte2Short __attribute__((swift_name("mapByte2Short()"))); + (NSDictionary *)mapShort2Byte __attribute__((swift_name("mapShort2Byte()"))); + (NSDictionary *)mapInt2Long __attribute__((swift_name("mapInt2Long()"))); + (NSDictionary *)mapLong2Long __attribute__((swift_name("mapLong2Long()"))); + (NSDictionary *)mapUByte2Boolean __attribute__((swift_name("mapUByte2Boolean()"))); + (NSDictionary *)mapUShort2Byte __attribute__((swift_name("mapUShort2Byte()"))); + (NSDictionary *)mapUInt2Long __attribute__((swift_name("mapUInt2Long()"))); + (NSDictionary *)mapULong2Long __attribute__((swift_name("mapULong2Long()"))); + (NSDictionary *)mapFloat2Float __attribute__((swift_name("mapFloat2Float()"))); + (NSDictionary *)mapDouble2String __attribute__((swift_name("mapDouble2String()"))); + (KtMutableDictionary *)mutBoolean2String __attribute__((swift_name("mutBoolean2String()"))); + (KtMutableDictionary *)mutByte2Short __attribute__((swift_name("mutByte2Short()"))); + (KtMutableDictionary *)mutShort2Byte __attribute__((swift_name("mutShort2Byte()"))); + (KtMutableDictionary *)mutInt2Long __attribute__((swift_name("mutInt2Long()"))); + (KtMutableDictionary *)mutLong2Long __attribute__((swift_name("mutLong2Long()"))); + (KtMutableDictionary *)mutUByte2Boolean __attribute__((swift_name("mutUByte2Boolean()"))); + (KtMutableDictionary *)mutUShort2Byte __attribute__((swift_name("mutUShort2Byte()"))); + (KtMutableDictionary *)mutUInt2Long __attribute__((swift_name("mutUInt2Long()"))); + (KtMutableDictionary *)mutULong2Long __attribute__((swift_name("mutULong2Long()"))); + (KtMutableDictionary *)mutFloat2Float __attribute__((swift_name("mutFloat2Float()"))); + (KtMutableDictionary *)mutDouble2String __attribute__((swift_name("mutDouble2String()"))); + (void)callFoo_FakeOverrideInInterfaceObj:(id)obj __attribute__((swift_name("callFoo_FakeOverrideInInterface(obj:)"))); @property (class, readonly) double dbl __attribute__((swift_name("dbl"))); @property (class, readonly) float flt __attribute__((swift_name("flt"))); @property (class, readonly) int32_t integer __attribute__((swift_name("integer"))); @property (class, readonly) int64_t longInt __attribute__((swift_name("longInt"))); @property (class) int32_t intVar __attribute__((swift_name("intVar"))); @property (class) NSString *str __attribute__((swift_name("str"))); @property (class) id strAsAny __attribute__((swift_name("strAsAny"))); @property (class) id minDoubleVal __attribute__((swift_name("minDoubleVal"))); @property (class) id maxDoubleVal __attribute__((swift_name("maxDoubleVal"))); @property (class, readonly) double nanDoubleVal __attribute__((swift_name("nanDoubleVal"))); @property (class, readonly) float nanFloatVal __attribute__((swift_name("nanFloatVal"))); @property (class, readonly) double infDoubleVal __attribute__((swift_name("infDoubleVal"))); @property (class, readonly) float infFloatVal __attribute__((swift_name("infFloatVal"))); @property (class, readonly) BOOL boolVal __attribute__((swift_name("boolVal"))); @property (class, readonly) id boolAnyVal __attribute__((swift_name("boolAnyVal"))); @property (class, readonly) NSArray *numbersList __attribute__((swift_name("numbersList"))); @property (class, readonly) NSArray *anyList __attribute__((swift_name("anyList"))); @property (class) id lateinitIntVar __attribute__((swift_name("lateinitIntVar"))); @property (class, readonly) NSString *lazyVal __attribute__((swift_name("lazyVal"))); @property (class) KtKotlinArray *delegatedGlobalArray __attribute__((swift_name("delegatedGlobalArray"))); @property (class, readonly) NSArray *delegatedList __attribute__((swift_name("delegatedList"))); @property (class, readonly) id _Nullable nullVal __attribute__((swift_name("nullVal"))); @property (class) NSString * _Nullable nullVar __attribute__((swift_name("nullVar"))); @property (class) id anyValue __attribute__((swift_name("anyValue"))); @property (class, readonly) KtInt *(^sumLambda)(KtInt *, KtInt *) __attribute__((swift_name("sumLambda"))); @property (class, readonly) int32_t PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT __attribute__((swift_name("PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT"))); @property (class, readonly) id _Nullable errorVal __attribute__((swift_name("errorVal"))) __attribute__((unavailable("error"))); @property (class) id _Nullable errorVar __attribute__((swift_name("errorVar"))) __attribute__((unavailable("error"))); @property (class, readonly) id _Nullable warningVal __attribute__((swift_name("warningVal"))) __attribute__((deprecated("warning"))); @property (class) id _Nullable warningVar __attribute__((swift_name("warningVar"))) __attribute__((deprecated("warning"))); @property (class) int32_t gh3525BaseInitCount __attribute__((swift_name("gh3525BaseInitCount"))); @property (class) int32_t gh3525InitCount __attribute__((swift_name("gh3525InitCount"))); @end; __attribute__((swift_name("InvariantSuper"))) @interface KtInvariantSuper : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("Invariant"))) @interface KtInvariant : KtInvariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("OutVariantSuper"))) @interface KtOutVariantSuper : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("OutVariant"))) @interface KtOutVariant : KtOutVariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((swift_name("InVariantSuper"))) @interface KtInVariantSuper : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; __attribute__((objc_subclassing_restricted)) __attribute__((swift_name("InVariant"))) @interface KtInVariant : KtInVariantSuper - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead"))); @end; ================================================ FILE: backend.native/tests/objcexport/funInterfaces.kt ================================================ package funinterfaces fun interface FunInterface { fun run(): Int } fun getObject(): FunInterface { return object : FunInterface { override fun run() = 1 } } fun getLambda(): FunInterface { return FunInterface { 2 } } ================================================ FILE: backend.native/tests/objcexport/funInterfaces.swift ================================================ import Kt // Based on https://youtrack.jetbrains.com/issue/KT-44799. private func testSAMConversion() throws { try assertEquals(actual: FunInterfacesKt.getObject().run(), expected: 1) try assertEquals(actual: FunInterfacesKt.getLambda().run(), expected: 2) } class FunInterfacesTests : SimpleTestProvider { override init() { super.init() test("TestSAMConversion", testSAMConversion) } } ================================================ FILE: backend.native/tests/objcexport/functionalTypes.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package functionalTypes import kotlin.test.* typealias AN = Any? typealias F2 = (AN, AN) -> AN typealias F5 = (AN, AN, AN, AN, AN) -> AN typealias F6 = (AN, AN, AN, AN, AN, AN,) -> AN typealias F32 = (AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN) -> AN typealias F33 = (AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN) -> AN fun callDynType2(list: List, param: AN) { val fct = list.first() val ret = fct(param, null) assertEquals(param, ret) } fun callStaticType2(fct: F2, param: AN) { val ret = fct(param, null) assertEquals(param, ret) } fun callDynType32(list: List, param: AN) { val fct = list.first() val ret = fct(param , null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null ) assertEquals(param, ret) } fun callStaticType32(fct: F32, param: AN) { val ret = fct(param , null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null ) assertEquals(param, ret) } fun callDynType33(list: List, param: AN) { val fct = list.first() val ret = fct(param , null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null, null ) assertEquals(param, ret) } fun callStaticType33(fct: F33, param: AN) { val ret = fct(param , null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null , null, null, null, null, null, null, null, null, null ) assertEquals(param, ret) } abstract class FHolder { abstract val value: Any? } // Note: can't provoke dynamic function type conversion using list (as above) or generics // due to Swift <-> Obj-C interop bugs/limitations. // Use covariant return type instead: class F2Holder(override val value: F2) : FHolder() fun getDynTypeLambda2(): F2Holder = F2Holder({ p1, _ -> p1 }) fun getStaticLambda2(): F2 = { p1, _ -> p1 } private fun f2(p1: AN, p2: AN): AN = p1 fun getDynTypeRef2(): F2Holder = F2Holder(::f2) fun getStaticRef2(): F2 = ::f2 private fun f32( p1: AN, p2: AN, p3: AN, p4: AN, p5: AN, p6: AN, p7: AN, p8: AN, p9: AN, p10: AN, p11: AN, p12: AN, p13: AN, p14: AN, p15: AN, p16: AN, p17: AN, p18: AN, p19: AN, p20: AN, p21: AN, p22: AN, p23: AN, p24: AN, p25: AN, p26: AN, p27: AN, p28: AN, p29: AN, p30: AN, p31: AN, p32: AN ): AN = p1 private fun f33( p1: AN, p2: AN, p3: AN, p4: AN, p5: AN, p6: AN, p7: AN, p8: AN, p9: AN, p10: AN, p11: AN, p12: AN, p13: AN, p14: AN, p15: AN, p16: AN, p17: AN, p18: AN, p19: AN, p20: AN, p21: AN, p22: AN, p23: AN, p24: AN, p25: AN, p26: AN, p27: AN, p28: AN, p29: AN, p30: AN, p31: AN, p32: AN, p33: AN ): AN = p1 class F32Holder(override val value: F32) : FHolder() fun getDynType32(): F32Holder = F32Holder(::f32) fun getStaticType32(): F32 = ::f32 class F33Holder(override val value: F33) : FHolder() fun getDynTypeRef33(): F33Holder = F33Holder(::f33) fun getStaticTypeRef33(): F33 = ::f33 fun getDynTypeLambda33(): F33Holder = F33Holder(getStaticTypeLambda33()) fun getStaticTypeLambda33(): F33 = { p, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ -> p } ================================================ FILE: backend.native/tests/objcexport/functionalTypes.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private func test1() { FunctionalTypesKt.callStaticType2(fct: foo2, param: "from swift") FunctionalTypesKt.callDynType2(list: [ foo2 ], param: "from swift") FunctionalTypesKt.callStaticType2(fct : {a1, _ in return a1 }, param: "from swift block") FunctionalTypesKt.callDynType2(list: [ {a1, _ in return a1 } ], param: "from swift block") // 32 params is mapped as regular; block is OK FunctionalTypesKt.callStaticType32(fct : { a1, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ in return a1 }, param: "from swift block") FunctionalTypesKt.callDynType32(list : [{ a1, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ in return a1 }], param: "from swift block") // 33 params requires explicit implementation of KotlinFunction33 FunctionalTypesKt.callStaticType33(fct: foo33, param: "from swift") FunctionalTypesKt.callDynType33(list: [ Foo33() ], param: "from swift") } private func test2() throws { try assertEquals(actual: FunctionalTypesKt.getDynTypeLambda2().value("one", nil) as? String, expected: "one") try assertEquals(actual: FunctionalTypesKt.getStaticLambda2()("two", nil) as? String, expected: "two") try assertEquals(actual: FunctionalTypesKt.getDynTypeRef2().value("three", nil) as? String, expected: "three") try assertEquals(actual: FunctionalTypesKt.getStaticRef2()("four", nil) as? String, expected: "four") // 32 params is mapped as regular; calling result as block is OK try assertEquals( actual: FunctionalTypesKt.getDynType32().value( "five", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ) as? String, expected: "five" ) try assertEquals( actual: FunctionalTypesKt.getStaticType32()( "six", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ) as? String, expected: "six" ) // 33 params requires explicit invocation of KotlinFunction33.invoke try assertEquals( actual: FunctionalTypesKt.getDynTypeRef33().value.invoke( p1: "seven", p2: nil, p3: nil, p4: nil, p5: nil, p6: nil, p7: nil, p8: nil, p9: nil, p10: nil, p11: nil, p12: nil, p13: nil, p14: nil, p15: nil, p16: nil, p17: nil, p18: nil, p19: nil, p20: nil, p21: nil, p22: nil, p23: nil, p24: nil, p25: nil, p26: nil, p27: nil, p28: nil, p29: nil, p30: nil, p31: nil, p32: nil, p33: nil ) as? String, expected: "seven" ) // static conversion is ok though. try assertEquals( actual: FunctionalTypesKt.getStaticTypeRef33()( "eight", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ) as? String, expected: "eight" ) try assertEquals( actual: FunctionalTypesKt.getDynTypeLambda33().value.invoke( p1: "nine", p2: nil, p3: nil, p4: nil, p5: nil, p6: nil, p7: nil, p8: nil, p9: nil, p10: nil, p11: nil, p12: nil, p13: nil, p14: nil, p15: nil, p16: nil, p17: nil, p18: nil, p19: nil, p20: nil, p21: nil, p22: nil, p23: nil, p24: nil, p25: nil, p26: nil, p27: nil, p28: nil, p29: nil, p30: nil, p31: nil, p32: nil, p33: nil ) as? String, expected: "nine" ) try assertEquals( actual: FunctionalTypesKt.getStaticTypeLambda33()( "ten", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ) as? String, expected: "ten" ) } class FunctionalTypesTests : SimpleTestProvider { override init() { super.init() test("Test1", test1) test("Test2", test2) } } private func foo2(a1: Any?, _: Any?) -> Any? { return a1 } private func foo33(a1: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any?, _: Any? ) -> Any? { return a1 } private class Foo33 : KotlinFunction33 { func invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?, p22: Any?, p23: Any?, p24: Any?, p25: Any?, p26: Any?, p27: Any?, p28: Any?, p29: Any?, p30: Any?, p31: Any?, p32: Any?, p33: Any? ) -> Any? { return foo33(a1: p1 , nil, nil, nil, nil, nil, nil, nil, nil , nil, nil, nil, nil, nil, nil, nil, nil , nil, nil, nil, nil, nil, nil, nil, nil , nil, nil, nil, nil, nil, nil, nil, nil) } } ================================================ FILE: backend.native/tests/objcexport/gh4002.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package gh4002 open class GH4002ArgumentBase class GH4002Argument : GH4002ArgumentBase() ================================================ FILE: backend.native/tests/objcexport/gh4002.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt // See https://github.com/JetBrains/kotlin-native/issues/4002 class GH4002Base0 : NSObject, NSCoding { required init(coder: NSCoder) { fatalError() } func encode(with coder: NSCoder) { fatalError() } } class GH4002Base1 : GH4002Base0 {} @objc(ObjCGH4002) class GH4002 : GH4002Base1 {} private func test1() throws { try assertEquals(actual: String(cString: class_getName(GH4002.self)), expected: "ObjCGH4002") } class Gh4002Tests : SimpleTestProvider { override init() { super.init() test("Test1", test1) } } ================================================ FILE: backend.native/tests/objcexport/headerWarnings.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package headerWarnings // Note: the test parses the generated header with -Werror to detect warnings. class TestIncompatiblePropertyTypeWarning { class Generic(val value: T) interface InterfaceWithGenericProperty { val p: Generic } class ClassOverridingInterfaceWithGenericProperty(override val p: Generic) : InterfaceWithGenericProperty } // https://github.com/JetBrains/kotlin-native/issues/3992 class TestGH3992 { abstract class C(open val a: A) class D(override val a: B) : C(a) abstract class A class B : A() } ================================================ FILE: backend.native/tests/objcexport/headerWarnings.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt // Note: the test parses the generated header with -Werror to detect warnings. // It is enough to have just Kotlin declarations at the moment. // Adding usages for all declarations to avoid any kind of DCE that may appear later. #if !NO_GENERICS private func testIncompatiblePropertyType() throws { let c = TestIncompatiblePropertyTypeWarning.ClassOverridingInterfaceWithGenericProperty( p: TestIncompatiblePropertyTypeWarningGeneric(value: "cba") ) let pc: TestIncompatiblePropertyTypeWarningGeneric = c.p try assertEquals(actual: pc.value, expected: "cba") let i: TestIncompatiblePropertyTypeWarningInterfaceWithGenericProperty = c let pi: TestIncompatiblePropertyTypeWarningGeneric = i.p try assertEquals(actual: pi.value as! String, expected: "cba") } #endif private func testGH3992() throws { let d = TestGH3992.D(a: TestGH3992.B()) let c: TestGH3992.C = d let b: TestGH3992.B = d.a let a: TestGH3992.A = b try assertTrue(a is TestGH3992.B) } class HeaderWarningsTests : SimpleTestProvider { override init() { super.init() #if !NO_GENERICS test("TestIncompatiblePropertyType", testIncompatiblePropertyType) #endif test("TestGH3992", testGH3992) } } ================================================ FILE: backend.native/tests/objcexport/kt35940.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kt35940 import kotlin.reflect.* @OptIn(ExperimentalAssociatedObjects::class) @AssociatedObjectKey @Retention(AnnotationRetention.BINARY) annotation class Associated(val kClass: KClass<*>) private interface I1 { val s: String } private class I1Impl : I1 { override val s = "zzz" } private class C(var i1: I1?) private interface I2 { fun bar(c: C) } private object I2Impl : I2 { override fun bar(c: C) { c.i1 = I1Impl() } } @Associated(I2Impl::class) private class I2ImplHolder @OptIn(ExperimentalAssociatedObjects::class) fun testKt35940(): String { val i2 = I2ImplHolder::class.findAssociatedObject()!! as I2 val c = C(null) i2.bar(c) return c.i1!!.s } ================================================ FILE: backend.native/tests/objcexport/kt35940.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private func test1() throws { try assertEquals(actual: Kt35940Kt.testKt35940(), expected: "zzz") } class Kt35940Tests : SimpleTestProvider { override init() { super.init() test("Test1", test1) } } ================================================ FILE: backend.native/tests/objcexport/kt38641.kt ================================================ package kt38641 // See https://youtrack.jetbrains.com/issue/KT-38641. class KT38641 { class IntType { var description = 42 } class Val { val description = "val" } class Var { var description = "var" } class TwoProperties { val description = "description" val description_ = "description_" } abstract class OverrideVal { abstract val description: String } interface OverrideVar { var description: String } } fun getOverrideValDescription(impl: KT38641.OverrideVal) = impl.description fun getOverrideVarDescription(impl: KT38641.OverrideVar) = impl.description fun setOverrideVarDescription(impl: KT38641.OverrideVar, newValue: String) { impl.description = newValue } ================================================ FILE: backend.native/tests/objcexport/kt38641.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private func testIntType() throws { let i = KT38641.IntType() try assertEquals(actual: i.description_, expected: 42) i.description_ = 17 try assertEquals(actual: i.description_, expected: 17) } private func testVal() throws { try assertEquals(actual: KT38641.Val().description_, expected: "val") } private func testVar() throws { let v = KT38641.Var() try assertEquals(actual: v.description_, expected: "var") v.description_ = "newValue" try assertEquals(actual: v.description_, expected: "newValue") } private func testTwoProperties() throws { let t = KT38641.TwoProperties() try assertEquals(actual: t.description_, expected: "description") try assertEquals(actual: t.description__, expected: "description_") } private func testOverrideVal() throws { try assertEquals(actual: Kt38641Kt.getOverrideValDescription(impl: KT38641OverrideValImpl()), expected: "description_") } class KT38641OverrideValImpl : KT38641.OverrideVal { override var description_: String { get { return "description_" } } } private func testOverrideVar() throws { let impl = KT38641OverrideVarImpl() try assertEquals(actual: Kt38641Kt.getOverrideVarDescription(impl: impl), expected: "description_") Kt38641Kt.setOverrideVarDescription(impl: impl, newValue: "d") try assertEquals(actual: Kt38641Kt.getOverrideVarDescription(impl: impl), expected: "d") } class KT38641OverrideVarImpl : KT38641OverrideVar { var description_: String = "description_" } class Kt38641Tests : SimpleTestProvider { override init() { super.init() test("TestIntType", testIntType) test("TestVal", testVal) test("TestVar", testVar) test("TestTwoProperties", testTwoProperties) test("TestOverrideVal", testOverrideVal) test("TestOverrideVar", testOverrideVar) } } ================================================ FILE: backend.native/tests/objcexport/kt39206.kt ================================================ // See https://youtrack.jetbrains.com/issue/KT-39206. @Deprecated("Don't call this\nPlease") fun myFunc() = 17 // See https://youtrack.jetbrains.com/issue/KT-41193. @Deprecated( level = DeprecationLevel.ERROR, message = "This class is deprecated for removal during serialization 1.0 API stabilization.\n" + "For configuring Json instances, the corresponding builder function can be used instead, e.g. instead of" + "'Json(JsonConfiguration.Stable.copy(isLenient = true))' 'Json { isLenient = true }' should be used.\n" + "Instead of storing JsonConfiguration instances of the code, Json instances can be used directly:" + "'Json(MyJsonConfiguration.copy(prettyPrint = true))' can be replaced with 'Json(from = MyApplicationJson) { prettyPrint = true }'" ) public open class JsonConfiguration @Deprecated("'\"\\@\$(){}\r\n") class MoreTrickyChars ================================================ FILE: backend.native/tests/objcexport/kt39206.swift ================================================ import Kt private func test1() throws { try assertEquals(actual: Kt39206Kt.myFunc(), expected: 17) } private func test2() throws { try assertTrue(MoreTrickyChars() as AnyObject is MoreTrickyChars) } class Kt39206Tests : SimpleTestProvider { override init() { super.init() test("Test1", test1) test("Test2", test2) } } ================================================ FILE: backend.native/tests/objcexport/kt41907.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kt41907 class Ckt41907 interface Ikt41907 { fun foo(c: Ckt41907) } private class Bkt41907 { var c: Ckt41907? = null } private val b = Bkt41907() fun escapeC(c: Ckt41907) { b.c = c } fun testKt41907(o: Ikt41907) { val c = Ckt41907() o.foo(c) } ================================================ FILE: backend.native/tests/objcexport/kt41907.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt class Ikt41907Impl : Ikt41907 { func foo(c: Ckt41907) { Kt41907Kt.escapeC(c: c) } } private func test1() { Kt41907Kt.testKt41907(o: Ikt41907Impl()) } class Kt41907Tests : SimpleTestProvider { override init() { super.init() test("Test1", test1) } } ================================================ FILE: backend.native/tests/objcexport/kt43599.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kt43599 // Note: this test relies on two-stage compilation. class KT43599 { var memberProperty = "memberProperty" private set } var KT43599.extensionProperty get() = "extensionProperty" private set(value) { TODO() } var topLevelProperty get() = "topLevelProperty" private set(value) { TODO() } lateinit var topLevelLateinitProperty: String private set fun setTopLevelLateinitProperty(value: String) { topLevelLateinitProperty = value } ================================================ FILE: backend.native/tests/objcexport/kt43599.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private func testPropertyWithPrivateSetter() throws { try assertEquals(actual: KT43599().memberProperty, expected: "memberProperty") try assertEquals(actual: KT43599().extensionProperty, expected: "extensionProperty") try assertEquals(actual: Kt43599Kt.topLevelProperty, expected: "topLevelProperty") // Checking the reported case too: Kt43599Kt.setTopLevelLateinitProperty(value: "topLevelLateinitProperty") try assertEquals(actual: Kt43599Kt.topLevelLateinitProperty, expected: "topLevelLateinitProperty") } class Kt43599Tests : SimpleTestProvider { override init() { super.init() test("TestPropertyWithPrivateSetter", testPropertyWithPrivateSetter) } } ================================================ FILE: backend.native/tests/objcexport/library/library.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package library interface I { val data: String } class A(override val data: String): I enum class E(val data: String) { A("Enum entry A"), B("Enum entry B"), C("Enum entry C") } ================================================ FILE: backend.native/tests/objcexport/library.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package library fun readDataFromLibraryClass(input: A): String { return input.data } fun readDataFromLibraryInterface(input: I): String { return input.data } fun readDataFromLibraryEnum(input: E): String { return input.data } ================================================ FILE: backend.native/tests/objcexport/library.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt func testAccessClassFromLibraryWithShortName() throws { let object: MyLibraryA = MyLibraryA(data: "Data from Class") let interface: MyLibraryI = MyLibraryA(data: "Data from Interface") let enumObject: MyLibraryE = MyLibraryE.b let dataFromClass = LibraryKt.readDataFromLibraryClass(input: object) let dataFromInterface = LibraryKt.readDataFromLibraryInterface(input: interface) let dataFromEnum = LibraryKt.readDataFromLibraryEnum(input: enumObject) try assertEquals(actual: dataFromClass, expected: "Data from Class") try assertEquals(actual: dataFromInterface, expected: "Data from Interface") try assertEquals(actual: dataFromEnum, expected: "Enum entry B") } class LibraryTests : SimpleTestProvider { override init() { super.init() test("testAccessClassFromLibraryWithShortName", testAccessClassFromLibraryWithShortName) } } ================================================ FILE: backend.native/tests/objcexport/localEA.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // All classes and methods should be used in tests @file:Suppress("UNUSED") package localEA class ArraysConstructor { private val memberArray: IntArray constructor(int1: Int, int2: Int) { memberArray = IntArray(2) set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() = "size: ${memberArray.size}, contents: ${memberArray.contentToString()}" } class ArraysDefault { private val memberArray = IntArray(2) constructor(int1: Int, int2: Int) { set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() = "size: ${memberArray.size}, contents: ${memberArray.contentToString()}" } class ArraysInitBlock { private val memberArray : IntArray init { memberArray = IntArray(2) } constructor(int1: Int, int2: Int) { set(int1, int2) } fun set(int1: Int, int2: Int) { memberArray[0] = int1 memberArray[1] = int2 } fun log() = "size: ${memberArray.size}, contents: ${memberArray.contentToString()}" } ================================================ FILE: backend.native/tests/objcexport/localEA.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt // -------- Tests -------- func testArraysEscapeAsParameter() throws { let array1 = ArraysConstructor(int1: 1, int2: 2) try assertEquals(actual: array1.log(), expected: "size: 2, contents: [1, 2]", "Wrong array values in class ArraysConstructor.") array1.set(int1: 3, int2: 4) try assertEquals(actual: array1.log(), expected: "size: 2, contents: [3, 4]", "Wrong array values in class ArraysConstructor.") let array2 = ArraysDefault(int1: 1, int2: 2) try assertEquals(actual: array2.log(), expected: "size: 2, contents: [1, 2]", "Wrong array values in class ArraysDefault.") array2.set(int1: 3, int2: 4) try assertEquals(actual: array2.log(), expected: "size: 2, contents: [3, 4]", "Wrong array values in class ArraysDefault.") let array3 = ArraysInitBlock(int1: 1, int2: 2) try assertEquals(actual: array3.log(), expected: "size: 2, contents: [1, 2]", "Wrong array values in class ArraysInitBlock.") array3.set(int1: 3, int2: 4) try assertEquals(actual: array3.log(), expected: "size: 2, contents: [3, 4]", "Wrong array values in class ArraysInitBlock.") } // -------- Execution of the test -------- class LocalEATests : SimpleTestProvider { override init() { super.init() test("TestArraysEscapeAsParameter", testArraysEscapeAsParameter) } } ================================================ FILE: backend.native/tests/objcexport/overrideKotlinMethods.kt ================================================ package overrideKotlinMethods import kotlin.test.* internal interface OverrideKotlinMethods0 { fun one(): T } internal interface OverrideKotlinMethods1 : OverrideKotlinMethods0 interface OverrideKotlinMethods2 { fun one(): Int } open class OverrideKotlinMethods3 { internal open fun one(): Number = 3 } open class OverrideKotlinMethods4 : OverrideKotlinMethods3(), OverrideKotlinMethods1, OverrideKotlinMethods2 { override fun one(): Int = 2 } interface OverrideKotlinMethods5 { fun one(): Int } interface OverrideKotlinMethods6 : OverrideKotlinMethods5 // Using `Any` because Kotlin forbids internal type in public function signature. @Throws(Throwable::class) fun test0(obj: Any) { val obj0 = obj as OverrideKotlinMethods0<*> assertEquals(1, obj0.one()) } // Using `Any` because Kotlin forbids internal type in public function signature. @Throws(Throwable::class) fun test1(obj: Any) { val obj1 = obj as OverrideKotlinMethods1<*> assertEquals(1, obj1.one()) } @Throws(Throwable::class) fun test2(obj: OverrideKotlinMethods2) { assertEquals(1, obj.one()) } @Throws(Throwable::class) fun test3(obj: OverrideKotlinMethods3) { assertEquals(1, obj.one()) } @Throws(Throwable::class) fun test4(obj: OverrideKotlinMethods4) { assertEquals(1, obj.one()) } @Throws(Throwable::class) fun test5(obj: OverrideKotlinMethods5) { assertEquals(1, obj.one()) } @Throws(Throwable::class) fun test6(obj: OverrideKotlinMethods6) { assertEquals(1, obj.one()) } ================================================ FILE: backend.native/tests/objcexport/overrideKotlinMethods.swift ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt class OverrideKotlinMethodsImpl : OverrideKotlinMethods4, OverrideKotlinMethods6 { override func one() -> Int32 { return 1 } } private func test1() throws { let obj = OverrideKotlinMethodsImpl() try OverrideKotlinMethodsKt.test0(obj: obj) try OverrideKotlinMethodsKt.test1(obj: obj) try OverrideKotlinMethodsKt.test2(obj: obj) try OverrideKotlinMethodsKt.test3(obj: obj) try OverrideKotlinMethodsKt.test4(obj: obj) try OverrideKotlinMethodsKt.test5(obj: obj) try OverrideKotlinMethodsKt.test6(obj: obj) } class OverrideKotlinMethodsTests : SimpleTestProvider { override init() { super.init() test("Test1", test1) } } ================================================ FILE: backend.native/tests/objcexport/overrideMethodsOfAny.kt ================================================ package overrideMethodsOfAny import kotlin.test.* @Throws(Throwable::class) fun test(obj: Any, other: Any, swift: Boolean) { if (!swift) { // Doesn't work for Swift, see https://youtrack.jetbrains.com/issue/KT-44613. assertEquals(42, obj.hashCode()) assertTrue(obj.equals(other)) } assertTrue(obj.equals(obj)) assertFalse(obj.equals(null)) assertFalse(obj.equals(Any())) assertEquals("toString", obj.toString()) } ================================================ FILE: backend.native/tests/objcexport/overrideMethodsOfAny.swift ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Kt private class SwiftOverridingMethodsOfAny : Hashable, Equatable, CustomStringConvertible { var hashValue: Int { return 42 } static func == (lhs: SwiftOverridingMethodsOfAny, rhs: SwiftOverridingMethodsOfAny) -> Bool { return true } var description: String { return "toString" } } private func testSwift() throws { try OverrideMethodsOfAnyKt.test(obj: SwiftOverridingMethodsOfAny(), other: SwiftOverridingMethodsOfAny(), swift: true) } private class ObjCOverridingMethodsOfAny : NSObject { override var hash: Int { return 42 } override func isEqual(_ other: Any?) -> Bool { return other is ObjCOverridingMethodsOfAny } override var description: String { return "toString" } } private func testObjC() throws { try OverrideMethodsOfAnyKt.test(obj: ObjCOverridingMethodsOfAny(), other: ObjCOverridingMethodsOfAny(), swift: false) } class OverrideMethodsOfAnyTests : SimpleTestProvider { override init() { super.init() test("TestSwift", testSwift) test("TestObjC", testObjC) } } ================================================ FILE: backend.native/tests/objcexport/throwsEmpty.kt ================================================ package throwsEmpty // Suppressing compilation error. // Only the generated comment is checked. @Suppress("THROWS_LIST_EMPTY") @Throws fun throwsEmpty() {} ================================================ FILE: backend.native/tests/objcexport/topLevelMangling.swift ================================================ import Kt private func testFunctionsInDifferentFilesAreNotMangled() throws { try assertEquals(actual: TopLevelManglingAKt.foo(), expected: "a1") try assertEquals(actual: TopLevelManglingBKt.foo(), expected: "b1") } private func testPropertiesInDifferentFilesAreNotMangled() throws { try assertEquals(actual: TopLevelManglingAKt.bar, expected: "a2") try assertEquals(actual: TopLevelManglingBKt.bar, expected: "b2") } private func testFunctionsInSameFileAreMangled() throws { try assertEquals(actual: TopLevelManglingAKt.sameNumber(value: Int32(1)), expected: 1) try assertEquals(actual: TopLevelManglingAKt.sameNumber(value_: Int64(2)), expected: 2) } class TopLevelManglingTests : SimpleTestProvider { override init() { super.init() test("TestFunctionsInDifferentFilesAreNotMangled", testFunctionsInDifferentFilesAreNotMangled) test("TestPropertiesInDifferentFilesAreNotMangled", testPropertiesInDifferentFilesAreNotMangled) test("TestFunctionsInSameFileAreMangled", testFunctionsInSameFileAreMangled) } } ================================================ FILE: backend.native/tests/objcexport/topLevelManglingA.kt ================================================ package topLevelManglingA fun foo() = "a1" val bar = "a2" fun sameNumber(value: Int) = value fun sameNumber(value: Long) = value ================================================ FILE: backend.native/tests/objcexport/topLevelManglingB.kt ================================================ package topLevelManglingB fun foo() = "b1" val bar = "b2" ================================================ FILE: backend.native/tests/objcexport/values.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // All classes and methods should be used in tests @file:Suppress("UNUSED") package conversions import kotlin.native.concurrent.freeze import kotlin.native.concurrent.isFrozen import kotlin.native.internal.ObjCErrorException import kotlin.native.ref.WeakReference import kotlin.properties.ReadWriteProperty import kotlin.reflect.KClass import kotlin.reflect.KProperty import kotlin.test.* import kotlinx.cinterop.* // Ensure loaded function IR classes aren't ordered by arity: internal fun referenceFunction1(block: (Any?) -> Unit) {} // Constants const val dbl: Double = 3.14 const val flt: Float = 2.73F const val integer: Int = 42 const val longInt: Long = 1984 // Vars var intVar: Int = 451 var str = "Kotlin String" var strAsAny: Any = "Kotlin String as Any" // MIN/MAX values as Numbers var minDoubleVal: kotlin.Number = Double.MIN_VALUE var maxDoubleVal: kotlin.Number = Double.MAX_VALUE // Infinities and NaN val nanDoubleVal: Double = Double.NaN val nanFloatVal: Float = Float.NaN val infDoubleVal: Double = Double.POSITIVE_INFINITY val infFloatVal: Float = Float.NEGATIVE_INFINITY private fun T.toNullable(): T? = this fun box(booleanValue: Boolean) = booleanValue.toNullable() fun box(byteValue: Byte) = byteValue.toNullable() fun box(shortValue: Short) = shortValue.toNullable() fun box(intValue: Int) = intValue.toNullable() fun box(longValue: Long) = longValue.toNullable() fun box(uByteValue: UByte) = uByteValue.toNullable() fun box(uShortValue: UShort) = uShortValue.toNullable() fun box(uIntValue: UInt) = uIntValue.toNullable() fun box(uLongValue: ULong) = uLongValue.toNullable() fun box(floatValue: Float) = floatValue.toNullable() fun box(doubleValue: Double) = doubleValue.toNullable() private inline fun ensureEquals(actual: T?, expected: T) { if (actual !is T) error(T::class) if (actual != expected) error(T::class) } fun ensureEqualBooleans(actual: Boolean?, expected: Boolean) = ensureEquals(actual, expected) fun ensureEqualBytes(actual: Byte?, expected: Byte) = ensureEquals(actual, expected) fun ensureEqualShorts(actual: Short?, expected: Short) = ensureEquals(actual, expected) fun ensureEqualInts(actual: Int?, expected: Int) = ensureEquals(actual, expected) fun ensureEqualLongs(actual: Long?, expected: Long) = ensureEquals(actual, expected) fun ensureEqualUBytes(actual: UByte?, expected: UByte) = ensureEquals(actual, expected) fun ensureEqualUShorts(actual: UShort?, expected: UShort) = ensureEquals(actual, expected) fun ensureEqualUInts(actual: UInt?, expected: UInt) = ensureEquals(actual, expected) fun ensureEqualULongs(actual: ULong?, expected: ULong) = ensureEquals(actual, expected) fun ensureEqualFloats(actual: Float?, expected: Float) = ensureEquals(actual, expected) fun ensureEqualDoubles(actual: Double?, expected: Double) = ensureEquals(actual, expected) // Boolean val boolVal: Boolean = true val boolAnyVal: Any = false // Lists val numbersList: List = listOf(1.toByte(), 2.toShort(), 13) val anyList: List = listOf("Str", 42, 3.14, true) // lateinit lateinit var lateinitIntVar: Any // lazy val lazyVal: String by lazy { println("Lazy value initialization") "Lazily initialized string" } // Delegation var delegatedGlobalArray: Array by DelegateClass() class DelegateClass: ReadWriteProperty> { private var holder: Array = arrayOf("property") override fun getValue(thisRef: Nothing?, property: KProperty<*>): Array { return arrayOf("Delegated", "global", "array") + holder } override fun setValue(thisRef: Nothing?, property: KProperty<*>, value: Array) { holder = value } } // Getter with delegation val delegatedList: List get() = delegatedGlobalArray.toList() // Null val nullVal: Any? = null var nullVar: String? = "" // Any var anyValue: Any = "Str" // Functions fun emptyFun() { } fun strFun(): String = "fooStr" fun argsFun(i: Int, l: Long, d: Double, s: String): Any = s + i + l + d fun funArgument(foo: () -> String): String = foo() // Generic functions fun genericFoo(t: T, foo: (T) -> R): R = foo(t) fun fooGenericNumber(r: R, foo: (T) -> Number): Number = foo(r) fun varargToList(vararg args: T): List = args.toList() // Extensions fun String.subExt(i: Int): String { return if (i < this.length) this[i].toString() else "nothing" } fun Any?.toString(): String = this?.toString() ?: "null" fun Any?.print() = println(this.toString()) fun Char.boxChar(): Char? = this fun Char?.isA(): Boolean = (this == 'A') // Lambdas val sumLambda = { x: Int, y: Int -> x + y } // Inheritance interface I { fun iFun(): String = "I::iFun" } fun I.iFunExt() = iFun() private interface PI { fun piFun(): Any fun iFun(): String = "PI::iFun" } class DefaultInterfaceExt : I open class OpenClassI : I { override fun iFun(): String = "OpenClassI::iFun" } class FinalClassExtOpen : OpenClassI() { override fun iFun(): String = "FinalClassExtOpen::iFun" } open class MultiExtClass : OpenClassI(), PI { override fun piFun(): Any { return 42 } override fun iFun(): String = super.iFun() } open class ConstrClass(open val i: Int, val s: String, val a: Any = "AnyS") : OpenClassI() class ExtConstrClass(override val i: Int) : ConstrClass(i, "String") { override fun iFun(): String = "ExtConstrClass::iFun::$i-$s-$a" } // Enum enum class Enumeration(val enumValue: Int) { ANSWER(42), YEAR(1984), TEMPERATURE(451) } fun passEnum(): Enumeration { return Enumeration.ANSWER } fun receiveEnum(e: Int) { println("ENUM got: ${get(e).enumValue}") } fun get(value: Int): Enumeration { return Enumeration.values()[value] } // Data class values and generated properties: component# and toString() data class TripleVals(val first: T, val second: T, val third: T) data class TripleVars(var first: T, var second: T, var third: T) { override fun toString(): String { return "[$first, $second, $third]" } } open class WithCompanionAndObject { companion object { val str = "String" var named: I? = Named } object Named : OpenClassI() { override fun iFun(): String = "WithCompanionAndObject.Named::iFun" } } fun getCompanionObject() = WithCompanionAndObject.Companion fun getNamedObject() = WithCompanionAndObject.Named fun getNamedObjectInterface(): OpenClassI = WithCompanionAndObject.Named typealias EE = Enumeration fun EE.getAnswer() : EE = Enumeration.ANSWER inline class IC1(val value: Int) inline class IC2(val value: String) inline class IC3(val value: TripleVals?) fun box(ic1: IC1): Any = ic1 fun box(ic2: IC2): Any = ic2 fun box(ic3: IC3): Any = ic3 fun concatenateInlineClassValues(ic1: IC1, ic1N: IC1?, ic2: IC2, ic2N: IC2?, ic3: IC3, ic3N: IC3?): String = "${ic1.value} ${ic1N?.value} ${ic2.value} ${ic2N?.value} ${ic3.value} ${ic3N?.value}" fun IC1.getValue1() = this.value fun IC1?.getValueOrNull1() = this?.value fun IC2.getValue2() = value fun IC2?.getValueOrNull2() = this?.value fun IC3.getValue3() = value fun IC3?.getValueOrNull3() = this?.value fun isFrozen(obj: Any): Boolean = obj.isFrozen fun kotlinLambda(block: (Any) -> Any): Any = block fun multiply(int: Int, long: Long) = int * long class MyException : Exception() class MyError : Error() @Throws(MyException::class, MyError::class) fun throwException(error: Boolean): Unit { throw if (error) MyError() else MyException() } interface SwiftOverridableMethodsWithThrows { @Throws(MyException::class) fun unit(): Unit @Throws(MyException::class) fun nothing(): Nothing @Throws(MyException::class) fun any(): Any @Throws(MyException::class) fun block(): () -> Int } interface MethodsWithThrows : SwiftOverridableMethodsWithThrows { @Throws(MyException::class) fun nothingN(): Nothing? @Throws(MyException::class) fun anyN(): Any? @Throws(MyException::class) fun blockN(): (() -> Int)? @Throws(MyException::class) fun pointer(): CPointer<*> @Throws(MyException::class) fun pointerN(): CPointer<*>? @Throws(MyException::class) fun int(): Int @Throws(MyException::class) fun longN(): Long? @Throws(MyException::class) fun double(): Double interface UnitCaller { @Throws(MyException::class) fun call(methods: MethodsWithThrows): Unit } } open class Throwing : MethodsWithThrows { @Throws(MyException::class) constructor(doThrow: Boolean) { if (doThrow) throw MyException() } override fun unit(): Unit = throw MyException() override fun nothing(): Nothing = throw MyException() override fun nothingN(): Nothing? = throw MyException() override fun any(): Any = throw MyException() override fun anyN(): Any? = throw MyException() override fun block(): () -> Int = throw MyException() override fun blockN(): (() -> Int)? = throw MyException() override fun pointer(): CPointer<*> = throw MyException() override fun pointerN(): CPointer<*>? = throw MyException() override fun int(): Int = throw MyException() override fun longN(): Long? = throw MyException() override fun double(): Double = throw MyException() } class NotThrowing : MethodsWithThrows { @Throws(MyException::class) constructor() {} override fun unit(): Unit {} override fun nothing(): Nothing = throw MyException() override fun nothingN(): Nothing? = null override fun any(): Any = Any() override fun anyN(): Any? = Any() override fun block(): () -> Int = { 42 } override fun blockN(): (() -> Int)? = null override fun pointer(): CPointer<*> = 1L.toCPointer()!! override fun pointerN(): CPointer<*>? = null override fun int(): Int = 42 override fun longN(): Long? = null override fun double(): Double = 3.14 } @Throws(Throwable::class) fun testSwiftThrowing(methods: SwiftOverridableMethodsWithThrows) = with(methods) { assertSwiftThrowing { unit() } assertSwiftThrowing { nothing() } assertSwiftThrowing { any() } assertSwiftThrowing { block() } } private inline fun assertSwiftThrowing(block: () -> Unit) = assertFailsWith(block = block) @Throws(Throwable::class) fun testSwiftNotThrowing(methods: SwiftOverridableMethodsWithThrows) = with(methods) { unit() assertEquals(42, any()) assertEquals(17, block()()) } @Throws(MyError::class) fun callUnit(methods: SwiftOverridableMethodsWithThrows) = methods.unit() @Throws(Throwable::class) fun callUnitCaller(caller: MethodsWithThrows.UnitCaller, methods: MethodsWithThrows) { assertFailsWith { caller.call(methods) } } interface ThrowsWithBridgeBase { @Throws(MyException::class) fun plusOne(x: Int): Any } abstract class ThrowsWithBridge : ThrowsWithBridgeBase { abstract override fun plusOne(x: Int): Int } @Throws(Throwable::class) fun testSwiftThrowing(test: ThrowsWithBridgeBase, flag: Boolean) { assertFailsWith { if (flag) { test.plusOne(0) } else { val test1 = test as ThrowsWithBridge val ignore: Int = test1.plusOne(1) } } } @Throws(Throwable::class) fun testSwiftNotThrowing(test: ThrowsWithBridgeBase) { assertEquals(3, test.plusOne(2)) val test1 = test as ThrowsWithBridge assertEquals(4, test1.plusOne(3)) } fun Any.same() = this // https://github.com/JetBrains/kotlin-native/issues/2571 val PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT = 111 // https://github.com/JetBrains/kotlin-native/issues/2667 class Deeply { class Nested { class Type { val thirtyTwo = 32 } interface IType } } class WithGenericDeeply() { class Nested { class Type { val thirtyThree = 33 } } } // https://github.com/JetBrains/kotlin-native/issues/3167 class TypeOuter { class Type { val thirtyFour = 34 } } data class CKeywords(val float: Float, val `enum`: Int, var goto: Boolean) interface Base1 { fun same(value: Int?): Int? } interface ExtendedBase1 : Base1 { override fun same(value: Int?): Int? } interface Base2 { fun same(value: Int?): Int? } internal interface Base3 { fun same(value: Int?): Int } open class Base23 : Base2, Base3 { override fun same(value: Int?): Int = error("should not reach here") } fun call(base1: Base1, value: Int?) = base1.same(value) fun call(extendedBase1: ExtendedBase1, value: Int?) = extendedBase1.same(value) fun call(base2: Base2, value: Int?) = base2.same(value) fun call(base3: Any, value: Int?) = (base3 as Base3).same(value) fun call(base23: Base23, value: Int?) = base23.same(value) interface Transform { fun map(value: T): R } interface TransformWithDefault : Transform { override fun map(value: T): T = value } class TransformInheritingDefault : TransformWithDefault interface TransformIntString { fun map(intValue: Int): String } abstract class TransformIntToString : Transform, TransformIntString { override abstract fun map(intValue: Int): String } open class TransformIntToDecimalString : TransformIntToString() { override fun map(intValue: Int): String = intValue.toString() } private class TransformDecimalStringToInt : Transform { override fun map(stringValue: String): Int = stringValue.toInt() } fun createTransformDecimalStringToInt(): Transform = TransformDecimalStringToInt() open class TransformIntToLong : Transform { override fun map(value: Int): Long = value.toLong() } class GH2931 { class Data class Holder { val data = Data() init { freeze() } } } class GH2945(var errno: Int) { fun testErrnoInSelector(p: Int, errno: Int) = p + errno } class GH2830 { interface I private class PrivateImpl : I fun getI(): Any = PrivateImpl() } class GH2959 { interface I { val id: Int } private class PrivateImpl(override val id: Int) : I fun getI(id: Int): List = listOf(PrivateImpl(id)) } fun runUnitBlock(block: () -> Unit): Boolean { val blockAny: () -> Any? = block return blockAny() === Unit } fun asUnitBlock(block: () -> Any?): () -> Unit = { block() } fun runNothingBlock(block: () -> Nothing) = try { block() false } catch (e: Throwable) { true } fun asNothingBlock(block: () -> Any?): () -> Nothing = { block() TODO() } fun getNullBlock(): (() -> Unit)? = null fun isBlockNull(block: (() -> Unit)?): Boolean = block == null interface IntBlocks { fun getPlusOneBlock(): T fun callBlock(argument: Int, block: T): Int } object IntBlocksImpl : IntBlocks<(Int) -> Int> { override fun getPlusOneBlock(): (Int) -> Int = { it: Int -> it + 1 } override fun callBlock(argument: Int, block: (Int) -> Int): Int = block(argument) } interface UnitBlockCoercion { fun coerce(block: () -> Unit): T fun uncoerce(block: T): () -> Unit } object UnitBlockCoercionImpl : UnitBlockCoercion<() -> Unit> { override fun coerce(block: () -> Unit): () -> Unit = block override fun uncoerce(block: () -> Unit): () -> Unit = block } fun isFunction(obj: Any?): Boolean = obj is Function<*> fun isFunction0(obj: Any?): Boolean = obj is Function0<*> abstract class MyAbstractList : List fun takeForwardDeclaredClass(obj: objcnames.classes.ForwardDeclaredClass) {} fun takeForwardDeclaredProtocol(obj: objcnames.protocols.ForwardDeclaredProtocol) {} class TestKClass { fun getKotlinClass(clazz: ObjCClass) = getOriginalKotlinClass(clazz) fun getKotlinClass(protocol: ObjCProtocol) = getOriginalKotlinClass(protocol) fun isTestKClass(kClass: KClass<*>): Boolean = (kClass == TestKClass::class) fun isI(kClass: KClass<*>): Boolean = (kClass == TestKClass.I::class) interface I } // https://kotlinlang.slack.com/archives/C3SGXARS6/p1560954372179300 interface ForwardI2 : ForwardI1 interface ForwardI1 { fun getForwardI2(): ForwardI2 } abstract class ForwardC2 : ForwardC1() abstract class ForwardC1 { abstract fun getForwardC2(): ForwardC2 } interface TestSR10177Workaround interface TestClashes1 { val clashingProperty: Int } interface TestClashes2 { val clashingProperty: Any val clashingProperty_: Any } class TestClashesImpl : TestClashes1, TestClashes2 { override val clashingProperty: Int get() = 1 override val clashingProperty_: Int get() = 2 } class TestInvalidIdentifiers { class `$Foo` class `Bar$` fun `a$d$d`(`$1`: Int, `2`: Int, `3`: Int): Int = `$1` + `2` + `3` var `$status`: String = "" enum class E(val value: Int) { `4$`(4), `5$`(5), `_`(6), `__`(7) } companion object `Companion$` { val `42` = 42 } val `$` = '$' val `_` = '_' } @Suppress("UNUSED_PARAMETER") open class TestDeprecation() { @Deprecated("hidden", level = DeprecationLevel.HIDDEN) open class OpenHidden : TestDeprecation() @Suppress("DEPRECATION_ERROR") class ExtendingHidden : OpenHidden() { class Nested } @Deprecated("hidden", level = DeprecationLevel.HIDDEN) interface HiddenInterface { fun effectivelyHidden(): Any } @Suppress("DEPRECATION_ERROR") open class ImplementingHidden : Any(), HiddenInterface { override fun effectivelyHidden(): Int = -1 } @Suppress("DEPRECATION_ERROR") fun callEffectivelyHidden(obj: Any): Int = (obj as HiddenInterface).effectivelyHidden() as Int @Deprecated("hidden", level = DeprecationLevel.HIDDEN) class Hidden : TestDeprecation() { open class Nested { class Nested inner class Inner } inner class Inner { inner class Inner } } @Suppress("DEPRECATION_ERROR") class ExtendingNestedInHidden : Hidden.Nested() @Suppress("DEPRECATION_ERROR") fun getHidden() = Hidden() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) constructor(hidden: Byte) : this() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) fun hidden() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) val hiddenVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) var hiddenVar: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) open fun openHidden() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) open val openHiddenVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) open var openHiddenVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) open class OpenError : TestDeprecation() @Suppress("DEPRECATION_ERROR") class ExtendingError : OpenError() @Deprecated("error", level = DeprecationLevel.ERROR) interface ErrorInterface @Suppress("DEPRECATION_ERROR") class ImplementingError : ErrorInterface @Deprecated("error", level = DeprecationLevel.ERROR) class Error : TestDeprecation() @Suppress("DEPRECATION_ERROR") fun getError() = Error() @Deprecated("error", level = DeprecationLevel.ERROR) constructor(error: Short) : this() @Deprecated("error", level = DeprecationLevel.ERROR) fun error() {} @Deprecated("error", level = DeprecationLevel.ERROR) val errorVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) var errorVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) open fun openError() {} @Deprecated("error", level = DeprecationLevel.ERROR) open val openErrorVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) open var openErrorVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) open class OpenWarning : TestDeprecation() @Suppress("DEPRECATION") class ExtendingWarning : OpenWarning() @Deprecated("warning", level = DeprecationLevel.WARNING) interface WarningInterface @Suppress("DEPRECATION") class ImplementingWarning : WarningInterface @Deprecated("warning", level = DeprecationLevel.WARNING) class Warning : TestDeprecation() @Suppress("DEPRECATION") fun getWarning() = Warning() @Deprecated("warning", level = DeprecationLevel.WARNING) constructor(warning: Int) : this() @Deprecated("warning", level = DeprecationLevel.WARNING) fun warning() {} @Deprecated("warning", level = DeprecationLevel.WARNING) val warningVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) var warningVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) open fun openWarning() {} @Deprecated("warning", level = DeprecationLevel.WARNING) open val openWarningVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) open var openWarningVar: Any? = null constructor(normal: Long) : this() fun normal() {} val normalVal: Any? = null var normalVar: Any? = null open fun openNormal(): Int = 1 open val openNormalVal: Any? = null open var openNormalVar: Any? = null class HiddenOverride() : TestDeprecation() { @Deprecated("hidden", level = DeprecationLevel.HIDDEN) constructor(hidden: Byte) : this() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override fun openHidden() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override val openHiddenVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override var openHiddenVar: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) constructor(error: Short) : this() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override fun openError() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override val openErrorVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override var openErrorVar: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) constructor(warning: Int) : this() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override fun openWarning() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override val openWarningVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override var openWarningVar: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) constructor(normal: Long) : this() @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override fun openNormal(): Int = 2 @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override val openNormalVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) override var openNormalVar: Any? = null } class ErrorOverride() : TestDeprecation() { @Deprecated("error", level = DeprecationLevel.ERROR) constructor(hidden: Byte) : this() @Deprecated("error", level = DeprecationLevel.ERROR) override fun openHidden() {} @Deprecated("error", level = DeprecationLevel.ERROR) override val openHiddenVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) override var openHiddenVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) constructor(error: Short) : this() @Deprecated("error", level = DeprecationLevel.ERROR) override fun openError() {} @Deprecated("error", level = DeprecationLevel.ERROR) override val openErrorVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) override var openErrorVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) constructor(warning: Int) : this() @Deprecated("error", level = DeprecationLevel.ERROR) override fun openWarning() {} @Deprecated("error", level = DeprecationLevel.ERROR) override val openWarningVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) override var openWarningVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) constructor(normal: Long) : this() @Deprecated("error", level = DeprecationLevel.ERROR) override fun openNormal(): Int = 3 @Deprecated("error", level = DeprecationLevel.ERROR) override val openNormalVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) override var openNormalVar: Any? = null } class WarningOverride() : TestDeprecation() { @Deprecated("warning", level = DeprecationLevel.WARNING) constructor(hidden: Byte) : this() @Deprecated("warning", level = DeprecationLevel.WARNING) override fun openHidden() {} @Deprecated("warning", level = DeprecationLevel.WARNING) override val openHiddenVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) override var openHiddenVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) constructor(error: Short) : this() @Deprecated("warning", level = DeprecationLevel.WARNING) override fun openError() {} @Deprecated("warning", level = DeprecationLevel.WARNING) override val openErrorVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) override var openErrorVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) constructor(warning: Int) : this() @Deprecated("warning", level = DeprecationLevel.WARNING) override fun openWarning() {} @Deprecated("warning", level = DeprecationLevel.WARNING) override val openWarningVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) override var openWarningVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) constructor(normal: Long) : this() @Deprecated("warning", level = DeprecationLevel.WARNING) override fun openNormal(): Int = 4 @Deprecated("warning", level = DeprecationLevel.WARNING) override val openNormalVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) override var openNormalVar: Any? = null } class NormalOverride() : TestDeprecation() { constructor(hidden: Byte) : this() override fun openHidden() {} override val openHiddenVal: Any? = null override var openHiddenVar: Any? = null constructor(error: Short) : this() override fun openError() {} override val openErrorVal: Any? = null override var openErrorVar: Any? = null constructor(warning: Int) : this() override fun openWarning() {} override val openWarningVal: Any? = null override var openWarningVar: Any? = null constructor(normal: Long) : this() override fun openNormal(): Int = 5 override val openNormalVal: Any? = null override var openNormalVar: Any? = null } @Suppress("DEPRECATION_ERROR") fun test(hiddenNested: Hidden.Nested) {} @Suppress("DEPRECATION_ERROR") fun test(hiddenNestedNested: Hidden.Nested.Nested) {} @Suppress("DEPRECATION_ERROR") fun test(hiddenNestedInner: Hidden.Nested.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(hiddenInner: Hidden.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(hiddenInnerInner: Hidden.Inner.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHidden: TopLevelHidden) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHiddenNested: TopLevelHidden.Nested) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHiddenNestedNested: TopLevelHidden.Nested.Nested) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHiddenNestedInner: TopLevelHidden.Nested.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHiddenInner: TopLevelHidden.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(topLevelHiddenInnerInner: TopLevelHidden.Inner.Inner) {} @Suppress("DEPRECATION_ERROR") fun test(extendingHiddenNested: ExtendingHidden.Nested) {} @Suppress("DEPRECATION_ERROR") fun test(extendingNestedInHidden: ExtendingNestedInHidden) {} } @Deprecated("hidden", level = DeprecationLevel.HIDDEN) class TopLevelHidden { class Nested { class Nested inner class Inner } inner class Inner { inner class Inner } } @Deprecated("hidden", level = DeprecationLevel.HIDDEN) fun hidden() {} @Deprecated("hidden", level = DeprecationLevel.HIDDEN) val hiddenVal: Any? = null @Deprecated("hidden", level = DeprecationLevel.HIDDEN) var hiddenVar: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) fun error() {} @Deprecated("error", level = DeprecationLevel.ERROR) val errorVal: Any? = null @Deprecated("error", level = DeprecationLevel.ERROR) var errorVar: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) fun warning() {} @Deprecated("warning", level = DeprecationLevel.WARNING) val warningVal: Any? = null @Deprecated("warning", level = DeprecationLevel.WARNING) var warningVar: Any? = null fun gc() { kotlin.native.internal.GC.collect() } class TestWeakRefs(private val frozen: Boolean) { private var obj: Any? = Any().also { if (frozen) it.freeze() } fun getObj() = obj!! fun clearObj() { obj = null } fun createCycle(): List { val node1 = Node(null) val node2 = Node(node1) node1.next = node2 if (frozen) node1.freeze() return listOf(node1, node2) } private class Node(var next: Node?) } class SharedRefs { class MutableData { var x = 0 fun update() { x += 1 } } fun createRegularObject(): MutableData = create { MutableData() } fun createLambda(): () -> Unit = create { var mutableData = 0 { println(mutableData++) } } fun createCollection(): MutableList = create { mutableListOf() } fun createFrozenRegularObject() = createRegularObject().freeze() fun createFrozenLambda() = createLambda().freeze() fun createFrozenCollection() = createCollection().freeze() fun hasAliveObjects(): Boolean { kotlin.native.internal.GC.collect() return mustBeRemoved.any { it.get() != null } } private fun create(block: () -> T) = block() .also { mustBeRemoved += WeakReference(it) } private val mustBeRemoved = mutableListOf>() } interface TestRememberNewObject { fun getObject(): Any fun waitForCleanup() } fun testRememberNewObject(test: TestRememberNewObject) { val obj = autoreleasepool { test.getObject() } test.waitForCleanup() assertNotEquals("", obj.toString()) // Likely crashes if object is removed. } open class ClassForTypeCheck fun testClassTypeCheck(x: Any) = x is ClassForTypeCheck interface InterfaceForTypeCheck fun testInterfaceTypeCheck(x: Any) = x is InterfaceForTypeCheck interface IAbstractInterface { fun foo(): Int } interface IAbstractInterface2 { fun foo() = 42 } fun testAbstractInterfaceCall(x: IAbstractInterface) = x.foo() fun testAbstractInterfaceCall2(x: IAbstractInterface2) = x.foo() abstract class AbstractInterfaceBase : IAbstractInterface { override fun foo() = bar() abstract fun bar(): Int } abstract class AbstractInterfaceBase2 : IAbstractInterface2 abstract class AbstractInterfaceBase3 : IAbstractInterface { abstract override fun foo(): Int } var gh3525BaseInitCount = 0 open class GH3525Base { init { gh3525BaseInitCount++ } } var gh3525InitCount = 0 object GH3525 : GH3525Base() { init { gh3525InitCount++ } } class TestStringConversion { lateinit var str: Any } fun foo(a: kotlin.native.concurrent.AtomicReference<*>) {} interface GH3825 { @Throws(MyException::class) fun call0(callback: () -> Boolean) @Throws(MyException::class) fun call1(doThrow: Boolean, callback: () -> Unit) @Throws(MyException::class) fun call2(callback: () -> Unit, doThrow: Boolean) } class GH3825KotlinImpl : GH3825 { override fun call0(callback: () -> Boolean) { if (callback()) throw MyException() } override fun call1(doThrow: Boolean, callback: () -> Unit) { if (doThrow) throw MyException() callback() } override fun call2(callback: () -> Unit, doThrow: Boolean) { if (doThrow) throw MyException() callback() } } @Throws(Throwable::class) fun testGH3825(gh3825: GH3825) { var count = 0 assertFailsWith { gh3825.call0({ true }) } gh3825.call0({ count += 1; false }) assertEquals(1, count) assertFailsWith { gh3825.call1(true, { fail() }) } gh3825.call1(false, { count += 1 }) assertEquals(2, count) assertFailsWith { gh3825.call2({ fail() }, true) } gh3825.call2({ count += 1 }, false) assertEquals(3, count) } fun mapBoolean2String(): Map = mapOf(Pair(false, "false"), Pair(true, "true")) fun mapByte2Short(): Map = mapOf(Pair(-1, 2)) fun mapShort2Byte(): Map = mapOf(Pair(-2, 1)) fun mapInt2Long(): Map = mapOf(Pair(-4, 8)) fun mapLong2Long(): Map = mapOf(Pair(-8, 8)) fun mapUByte2Boolean(): Map = mapOf(Pair(0x80U, true)) fun mapUShort2Byte(): Map = mapOf(Pair(0x8000U, 1)) fun mapUInt2Long(): Map = mapOf(Pair(0x7FFF_FFFFU, 7), Pair(0x8000_0000U, 8)) fun mapULong2Long(): Map = mapOf(Pair(0x8000_0000_0000_0000UL, 8)) fun mapFloat2Float(): Map = mapOf(Pair(3.14f, 100f)) fun mapDouble2String(): Map = mapOf(Pair(2.718281828459045, "2.718281828459045")) fun mutBoolean2String(): MutableMap = mutableMapOf(Pair(false, "false"), Pair(true, "true")) fun mutByte2Short(): MutableMap = mutableMapOf(Pair(-1, 2)) fun mutShort2Byte(): MutableMap = mutableMapOf(Pair(-2, 1)) fun mutInt2Long(): MutableMap = mutableMapOf(Pair(-4, 8)) fun mutLong2Long(): MutableMap = mutableMapOf(Pair(-8, 8)) fun mutUByte2Boolean(): MutableMap = mutableMapOf(Pair(128U, true)) fun mutUShort2Byte(): MutableMap = mutableMapOf(Pair(32768U, 1)) fun mutUInt2Long(): MutableMap = mutableMapOf(Pair(0x8000_0000U, 8)) fun mutULong2Long(): MutableMap = mutableMapOf(Pair(0x8000_0000_0000_0000UL, 8)) fun mutFloat2Float(): MutableMap = mutableMapOf(Pair(3.14f, 100f)) fun mutDouble2String(): MutableMap = mutableMapOf(Pair(2.718281828459045, "2.718281828459045")) interface Foo_FakeOverrideInInterface { fun foo(t: T?) } interface Bar_FakeOverrideInInterface : Foo_FakeOverrideInInterface fun callFoo_FakeOverrideInInterface(obj: Bar_FakeOverrideInInterface) { obj.foo(null) } ================================================ FILE: backend.native/tests/objcexport/values.swift ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation import Kt // -------- Tests -------- func testVals() throws { print("Values from Swift") let dbl = ValuesKt.dbl let flt = ValuesKt.flt let int = ValuesKt.integer let long = ValuesKt.longInt print(dbl) print(flt) print(int) print(long) try assertEquals(actual: dbl, expected: 3.14 as Double, "Double value isn't equal.") try assertEquals(actual: flt, expected: 2.73 as Float, "Float value isn't equal.") try assertEquals(actual: int, expected: 42) try assertEquals(actual: long, expected: 1984) } func testVars() throws { print("Variables from Swift") var intVar = ValuesKt.intVar var strVar = ValuesKt.str var strAsId = ValuesKt.strAsAny print(intVar) print(strVar) print(strAsId) try assertEquals(actual: intVar, expected: 451) try assertEquals(actual: strVar, expected: "Kotlin String") try assertEquals(actual: strAsId as! String, expected: "Kotlin String as Any") strAsId = "Swift str" ValuesKt.strAsAny = strAsId print(ValuesKt.strAsAny) try assertEquals(actual: ValuesKt.strAsAny as! String, expected: strAsId as! String) // property with custom getter/setter backed by the Kotlin's var var intProp : Int32 { get { return ValuesKt.intVar * 2 } set(value) { ValuesKt.intVar = 123 + value } } intProp += 10 print(intProp) print(ValuesKt.intVar) try assertEquals(actual: ValuesKt.intVar * 2, expected: intProp, "Property backed by var") } func testDoubles() throws { print("Doubles in Swift") let minDouble = ValuesKt.minDoubleVal as! Double let maxDouble = ValuesKt.maxDoubleVal as! NSNumber print(minDouble) print(maxDouble) print(ValuesKt.nanDoubleVal) print(ValuesKt.nanFloatVal) print(ValuesKt.infDoubleVal) print(ValuesKt.infFloatVal) try assertEquals(actual: minDouble, expected: Double.leastNonzeroMagnitude, "Min double") try assertEquals(actual: maxDouble, expected: Double.greatestFiniteMagnitude as NSNumber, "Max double") try assertTrue(ValuesKt.nanDoubleVal.isNaN, "NaN double") try assertTrue(ValuesKt.nanFloatVal.isNaN, "NaN float") try assertEquals(actual: ValuesKt.infDoubleVal, expected: Double.infinity, "Inf double") try assertEquals(actual: ValuesKt.infFloatVal, expected: -Float.infinity, "-Inf float") } func testNumbers() throws { try assertEquals(actual: KotlinBoolean(value: true).boolValue, expected: true) try assertEquals(actual: KotlinBoolean(value: false).intValue, expected: 0) try assertEquals(actual: KotlinBoolean(value: true), expected: true) try assertFalse(KotlinBoolean(value: false) as! Bool) try assertEquals(actual: KotlinByte(value: -1).int8Value, expected: -1) try assertEquals(actual: KotlinByte(value: -1).int32Value, expected: -1) try assertEquals(actual: KotlinByte(value: -1).doubleValue, expected: -1.0) try assertEquals(actual: KotlinByte(value: -1), expected: NSNumber(value: Int64(-1))) try assertFalse(KotlinByte(value: -1) == NSNumber(value: -1.5)) try assertEquals(actual: KotlinByte(value: -1), expected: -1) try assertTrue(KotlinByte(value: -1) == -1) try assertFalse(KotlinByte(value: -1) == 1) try assertEquals(actual: KotlinByte(value: -1) as! Int32, expected: -1) try assertEquals(actual: KotlinShort(value: 111).int16Value, expected: 111) try assertEquals(actual: KotlinShort(value: -15) as! Int16, expected: -15) try assertEquals(actual: KotlinShort(value: 47), expected: 47) try assertEquals(actual: KotlinInt(value: 99).int32Value, expected: 99) try assertEquals(actual: KotlinInt(value: -1) as! Int32, expected: -1) try assertEquals(actual: KotlinInt(value: 72), expected: 72) try assertEquals(actual: KotlinLong(value: 65).int64Value, expected: 65) try assertEquals(actual: KotlinLong(value: 10000000000) as! Int64, expected: 10000000000) try assertEquals(actual: KotlinLong(value: 8), expected: 8) try assertEquals(actual: KotlinUByte(value: 17).uint8Value, expected: 17) try assertEquals(actual: KotlinUByte(value: 42) as! UInt8, expected: 42) try assertEquals(actual: 88, expected: KotlinUByte(value: 88)) try assertEquals(actual: KotlinUShort(value: 40000).uint16Value, expected: 40000) try assertEquals(actual: KotlinUShort(value: 1) as! UInt16, expected: UInt16(1)) try assertEquals(actual: KotlinUShort(value: 65000), expected: 65000) try assertEquals(actual: KotlinUInt(value: 3).uint32Value, expected: 3) try assertEquals(actual: KotlinUInt(value: UInt32.max) as! UInt32, expected: UInt32.max) try assertEquals(actual: KotlinUInt(value: 2), expected: 2) try assertEquals(actual: KotlinULong(value: 55).uint64Value, expected: 55) try assertEquals(actual: KotlinULong(value: 0) as! UInt64, expected: 0) try assertEquals(actual: KotlinULong(value: 7), expected: 7) try assertEquals(actual: KotlinFloat(value: 1.0).floatValue, expected: 1.0) try assertEquals(actual: KotlinFloat(value: 22.0) as! Float, expected: 22) try assertEquals(actual: KotlinFloat(value: 41.0), expected: 41) try assertEquals(actual: KotlinFloat(value: -5.5), expected: -5.5) try assertEquals(actual: KotlinDouble(value: 0.5).doubleValue, expected: 0.5) try assertEquals(actual: KotlinDouble(value: 45.0) as! Double, expected: 45) try assertEquals(actual: KotlinDouble(value: 89.0), expected: 89) try assertEquals(actual: KotlinDouble(value: -3.7), expected: -3.7) ValuesKt.ensureEqualBooleans(actual: KotlinBoolean(value: true), expected: true) ValuesKt.ensureEqualBooleans(actual: false, expected: false) ValuesKt.ensureEqualBytes(actual: KotlinByte(value: 42), expected: 42) ValuesKt.ensureEqualBytes(actual: -11, expected: -11) ValuesKt.ensureEqualShorts(actual: KotlinShort(value: 256), expected: 256) ValuesKt.ensureEqualShorts(actual: -1, expected: -1) ValuesKt.ensureEqualInts(actual: KotlinInt(value: 100000), expected: 100000) ValuesKt.ensureEqualInts(actual: -7, expected: -7) ValuesKt.ensureEqualLongs(actual: KotlinLong(value: Int64.max), expected: Int64.max) ValuesKt.ensureEqualLongs(actual: 17, expected: 17) ValuesKt.ensureEqualUBytes(actual: KotlinUByte(value: 6), expected: 6) ValuesKt.ensureEqualUBytes(actual: 255, expected: 255) ValuesKt.ensureEqualUShorts(actual: KotlinUShort(value: 300), expected: 300) ValuesKt.ensureEqualUShorts(actual: 65535, expected: UInt16.max) ValuesKt.ensureEqualUInts(actual: KotlinUInt(value: 70000), expected: 70000) ValuesKt.ensureEqualUInts(actual: 48, expected: 48) ValuesKt.ensureEqualULongs(actual: KotlinULong(value: UInt64.max), expected: UInt64.max) ValuesKt.ensureEqualULongs(actual: 39, expected: 39) ValuesKt.ensureEqualFloats(actual: KotlinFloat(value: 36.6), expected: 36.6) ValuesKt.ensureEqualFloats(actual: 49.5, expected: 49.5) ValuesKt.ensureEqualFloats(actual: 18, expected: 18.0) ValuesKt.ensureEqualDoubles(actual: KotlinDouble(value: 12.34), expected: 12.34) ValuesKt.ensureEqualDoubles(actual: 56.78, expected: 56.78) ValuesKt.ensureEqualDoubles(actual: 3, expected: 3) func checkBox(_ value: T, _ boxFunction: (T) -> B?) throws { let box = boxFunction(value)! try assertEquals(actual: box as! T, expected: value) print(type(of: box)) print(B.self) try assertTrue(box.isKind(of: B.self)) } try checkBox(true, ValuesKt.box) try checkBox(Int8(-1), ValuesKt.box) try checkBox(Int16(-2), ValuesKt.box) try checkBox(Int32(-3), ValuesKt.box) try checkBox(Int64(-4), ValuesKt.box) try checkBox(UInt8(5), ValuesKt.box) try checkBox(UInt16(6), ValuesKt.box) try checkBox(UInt32(7), ValuesKt.box) try checkBox(UInt64(8), ValuesKt.box) try checkBox(Float(8.7), ValuesKt.box) try checkBox(Double(9.4), ValuesKt.box) } func testLists() throws { let numbersList = ValuesKt.numbersList let gold = [1, 2, 13] for i in 0.. Void { throw E() } func nothing() throws -> Void { throw E() } func any() throws -> Any { throw E() } func block() throws -> () -> KotlinInt { throw E() } } class TestThrowingConstructorRelease : Throwing { static var deinitialized = false deinit { TestThrowingConstructorRelease.deinitialized = true } } class SwiftNotThrowing : SwiftOverridableMethodsWithThrows { func unit() throws -> Void { } func nothing() throws -> Void { throw SwiftThrowing.E() } func any() throws -> Any { return 42 as Int32 } func block() throws -> () -> KotlinInt { return { 17 } } } class SwiftUnitCaller : MethodsWithThrowsUnitCaller { func call(methods: MethodsWithThrows) throws -> Void { try methods.unit() } } class SwiftThrowingWithBridge : ThrowsWithBridge { override func plusOne(x: Int32) throws -> KotlinInt { throw SwiftThrowing.E() } } class SwiftNotThrowingWithBridge : ThrowsWithBridge { override func plusOne(x: Int32) throws -> KotlinInt { return KotlinInt(value: x + 1) } } private func testThrowing(file: String = #file, line: Int = #line, _ block: () throws -> Void) throws { try assertFailsWithKotlin(MyException.self, file: file, line: line, block: block) } func testExceptions() throws { try testThrowing { try ValuesKt.throwException(error: false) } do { try ValuesKt.throwException(error: true) } catch let error as NSError { try assertTrue(error.kotlinException is MyError) } try assertFalse(TestThrowingConstructorRelease.deinitialized) try testThrowing { try TestThrowingConstructorRelease(doThrow: true) } ValuesKt.gc() try assertTrue(TestThrowingConstructorRelease.deinitialized) try testThrowing { try Throwing(doThrow: true) } let throwing = try Throwing(doThrow: false) try testThrowing { try throwing.unit() } try testThrowing { try throwing.nothing() } try testThrowing { try throwing.nothingN() } try testThrowing { try throwing.any() } try testThrowing { try throwing.anyN() } try testThrowing { try throwing.block()() } try testThrowing { try throwing.blockN() } try testThrowing { try throwing.pointer() } try testThrowing { try throwing.pointerN() } try testThrowing { try throwing.int() } try testThrowing { try throwing.longN() } try testThrowing { try throwing.double() } let notThrowing = try NotThrowing() try notThrowing.unit() try assertEquals(actual: notThrowing.nothingN(), expected: nil) try assertTrue(notThrowing.any() is KotlinBase) try assertTrue(notThrowing.anyN() is KotlinBase) try assertEquals(actual: notThrowing.block()(), expected: 42) try assertTrue(notThrowing.blockN() == nil) try assertEquals(actual: Int(bitPattern: notThrowing.pointer()), expected: 1) try assertEquals(actual: notThrowing.pointerN(), expected: nil) try assertEquals(actual: notThrowing.int(), expected: 42) try assertEquals(actual: notThrowing.longN(), expected: nil) try assertEquals(actual: notThrowing.double(), expected: 3.14) try ValuesKt.testSwiftThrowing(methods: SwiftThrowing()) try ValuesKt.testSwiftNotThrowing(methods: SwiftNotThrowing()) do { try ValuesKt.callUnit(methods: SwiftThrowing()) } catch let e as SwiftThrowing.E { // Ok. } try ValuesKt.callUnitCaller(caller: SwiftUnitCaller(), methods: throwing) try ValuesKt.testSwiftThrowing(test: SwiftThrowingWithBridge(), flag: false) try ValuesKt.testSwiftThrowing(test: SwiftThrowingWithBridge(), flag: true) try ValuesKt.testSwiftNotThrowing(test: SwiftNotThrowingWithBridge()) } func testFuncType() throws { let s = "str" let fFunc: () -> String = { return s } try assertEquals(actual: ValuesKt.funArgument(foo: fFunc), expected: s, "Using function type arguments failed") } func testGenericsFoo() throws { let fun = { (i: Int) -> String in return "S \(i)" } // wrap lambda to workaround issue with type conversion inability: // (Int) -> String can't be cast to (Any?) -> Any? let wrapper = { (t: Any?) -> Any? in return fun(t as! Int) } let res = ValuesKt.genericFoo(t: 42, foo: wrapper) try assertEquals(actual: res as! String, expected: "S 42") } func testVararg() throws { #if NO_GENERICS let ktArray = KotlinArray(size: 3, init: { (_) -> NSNumber in return 42 }) #else let ktArray = KotlinArray(size: 3, init: { (_) -> NSNumber in return 42 }) #endif let arr: [Int] = ValuesKt.varargToList(args: ktArray) as! [Int] try assertEquals(actual: arr, expected: [42, 42, 42]) } func testStrExtFun() throws { try assertEquals(actual: ValuesKt.subExt("String", i: 2), expected: "r") try assertEquals(actual: ValuesKt.subExt("A", i: 2), expected: "nothing") } func testAnyToString() throws { try assertEquals(actual: ValuesKt.toString(nil), expected: "null") try assertEquals(actual: ValuesKt.toString(42), expected: "42") } func testAnyPrint() throws { print("BEGIN") ValuesKt.print(nil) ValuesKt.print("Print") ValuesKt.print(123456789) ValuesKt.print(3.14) ValuesKt.print([3, 2, 1]) print("END") } func testCharExtensions() throws { try assertTrue(ValuesKt.isA(ValuesKt.boxChar(65))) try assertFalse(ValuesKt.isA(ValuesKt.boxChar(66))) } func testLambda() throws { try assertEquals(actual: ValuesKt.sumLambda(3, 4), expected: 7) var blockRuns = 0 try assertTrue(ValuesKt.runUnitBlock { blockRuns += 1 }) try assertEquals(actual: blockRuns, expected: 1) let unitBlock: () -> Void = ValuesKt.asUnitBlock { blockRuns += 1 return 42 } try assertTrue(unitBlock() == Void()) try assertEquals(actual: blockRuns, expected: 2) let nothingBlock: () -> Void = ValuesKt.asNothingBlock { blockRuns += 1 } try assertTrue(ValuesKt.runNothingBlock(block: nothingBlock)) try assertEquals(actual: blockRuns, expected: 3) try assertTrue(ValuesKt.getNullBlock() == nil) try assertTrue(ValuesKt.isBlockNull(block: nil)) // Test dynamic conversion: let intBlocks = IntBlocksImpl() try assertEquals(actual: intBlocks.getPlusOneBlock()(1), expected: 2) try assertEquals(actual: intBlocks.callBlock(argument: 2) { KotlinInt(value: $0.int32Value + 2) }, expected: 4) // Test round trip with dynamic conversion: let coercedUnitBlock: () -> KotlinUnit = UnitBlockCoercionImpl().coerce { blockRuns += 1 } try assertTrue(coercedUnitBlock() === KotlinUnit()) try assertEquals(actual: blockRuns, expected: 4) let uncoercedUnitBlock: () -> Void = UnitBlockCoercionImpl().uncoerce { blockRuns += 1 return KotlinUnit() } try assertTrue(uncoercedUnitBlock() == Void()) try assertEquals(actual: blockRuns, expected: 5) let blockMustBeFunction0: @convention(block) () -> AnyObject? = { return nil } try assertTrue(ValuesKt.isFunction(obj: blockMustBeFunction0)) try assertTrue(ValuesKt.isFunction0(obj: blockMustBeFunction0)) try assertFalse(ValuesKt.isFunction(obj: NSObject())) try assertFalse(ValuesKt.isFunction0(obj: NSObject())) // Test no function class for dynamic conversion: let blockAsMissingFunction: @convention(block) (AnyObject?, AnyObject?, AnyObject?, AnyObject?, AnyObject?) -> AnyObject? = { return $0 ?? $1 ?? $2 ?? $3 ?? $4 } try assertTrue(ValuesKt.isFunction(obj: blockAsMissingFunction)) try assertFalse(ValuesKt.isFunction0(obj: blockAsMissingFunction)) } // -------- Tests for classes and interfaces ------- class ValIEmptyExt : I { func iFun() -> String { return "ValIEmptyExt::iFun" } } class ValIExt : I { func iFun() -> String { return "ValIExt::iFun" } } func testInterfaceExtension() throws { try assertEquals(actual: ValIEmptyExt().iFun(), expected: "ValIEmptyExt::iFun") try assertEquals(actual: ValIExt().iFun(), expected: "ValIExt::iFun") } func testClassInstances() throws { try assertEquals(actual: OpenClassI().iFun(), expected: "OpenClassI::iFun") try assertEquals(actual: DefaultInterfaceExt().iFun(), expected: "I::iFun") try assertEquals(actual: FinalClassExtOpen().iFun(), expected: "FinalClassExtOpen::iFun") try assertEquals(actual: MultiExtClass().iFun(), expected: "PI::iFun") try assertEquals(actual: MultiExtClass().piFun() as! Int, expected: 42) try assertEquals(actual: ConstrClass(i: 1, s: "str", a: "Any").iFun(), expected: "OpenClassI::iFun") try assertEquals(actual: ExtConstrClass(i: 123).iFun(), expected: "ExtConstrClass::iFun::123-String-AnyS") } func testEnum() throws { try assertEquals(actual: ValuesKt.passEnum(), expected: Enumeration.answer) try assertEquals(actual: ValuesKt.passEnum().enumValue, expected: 42) try assertEquals(actual: ValuesKt.passEnum().name, expected: "ANSWER") ValuesKt.receiveEnum(e: 1) } func testDataClass() throws { let f = "1" let s = "2" let t = "3" #if NO_GENERICS let tripleVal = TripleVals(first: f as NSString, second: s as NSString, third: t as NSString) #else let tripleVal = TripleVals(first: f as NSString, second: s as NSString, third: t as NSString) #endif try assertEquals(actual: tripleVal.first as! String, expected: f, "Data class' value") try assertEquals(actual: tripleVal.component2() as! String, expected: s, "Data class' component") print(tripleVal) try assertEquals(actual: String(describing: tripleVal), expected: "TripleVals(first=\(f), second=\(s), third=\(t))") #if NO_GENERICS let tripleVar = TripleVars(first: f as NSString, second: s as NSString, third: t as NSString) #else let tripleVar = TripleVars(first: f as NSString, second: s as NSString, third: t as NSString) #endif try assertEquals(actual: tripleVar.first as! String, expected: f, "Data class' value") try assertEquals(actual: tripleVar.component2() as! String, expected: s, "Data class' component") print(tripleVar) try assertEquals(actual: String(describing: tripleVar), expected: "[\(f), \(s), \(t)]") tripleVar.first = t as NSString tripleVar.second = f as NSString tripleVar.third = s as NSString try assertEquals(actual: tripleVar.component2() as! String, expected: f, "Data class' component") try assertEquals(actual: String(describing: tripleVar), expected: "[\(t), \(f), \(s)]") } func testCompanionObj() throws { try assertEquals(actual: WithCompanionAndObject.Companion().str, expected: "String") try assertEquals(actual: ValuesKt.getCompanionObject().str, expected: "String") let namedFromCompanion = ValuesKt.getCompanionObject().named let named = ValuesKt.getNamedObject() try assertTrue(named === namedFromCompanion, "Should be the same Named object") try assertEquals(actual: ValuesKt.getNamedObjectInterface().iFun(), expected: named.iFun(), "Named object's method") } func testInlineClasses() throws { let ic1: Int32 = 42 let ic1N = ValuesKt.box(ic1: 17) let ic2 = "foo" let ic2N = "bar" #if NO_GENERICS let ic3 = TripleVals(first: 1, second: 2, third: 3) #else let ic3 = TripleVals(first: 1, second: 2, third: 3) #endif let ic3N = ValuesKt.box(ic3: nil) try assertEquals( actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: ic1N, ic2: ic2, ic2N: ic2N, ic3: ic3, ic3N: ic3N), expected: "42 17 foo bar TripleVals(first=1, second=2, third=3) null" ) try assertEquals( actual: ValuesKt.concatenateInlineClassValues(ic1: ic1, ic1N: nil, ic2: ic2, ic2N: nil, ic3: nil, ic3N: nil), expected: "42 null foo null null null" ) try assertEquals(actual: ValuesKt.getValue1(ic1), expected: 42) try assertEquals(actual: ValuesKt.getValueOrNull1(ic1N) as! Int, expected: 17) try assertEquals(actual: ValuesKt.getValue2(ic2), expected: "foo") try assertEquals(actual: ValuesKt.getValueOrNull2(ic2N), expected: "bar") try assertEquals(actual: ValuesKt.getValue3(ic3), expected: ic3) try assertEquals(actual: ValuesKt.getValueOrNull3(ic3N), expected: nil) } class TestSharedIImpl : NSObject, I { func iFun() -> String { return "TestSharedIImpl::iFun" } } func testShared() throws { func assertFrozen(_ obj: AnyObject) throws { try assertTrue(ValuesKt.isFrozen(obj: obj), "isFrozen(\(obj))") } func assertNotFrozen(_ obj: AnyObject) throws { try assertFalse(ValuesKt.isFrozen(obj: obj), "isFrozen(\(obj))") } try assertFrozen(NSObject()) try assertFrozen(TestSharedIImpl()) try assertFrozen(ValuesKt.kotlinLambda(block: { return $0 }) as AnyObject) try assertNotFrozen(FinalClassExtOpen()) } class PureSwiftClass { } struct PureSwiftStruct { var x: Int } class PureSwiftKotlinInterfaceImpl : I { func iFun() -> String { return "pure" } } func testPureSwiftClasses() throws { let pureSwiftClass = PureSwiftClass() try assertTrue(ValuesKt.same(pureSwiftClass) as? AnyObject === pureSwiftClass) try assertEquals(actual: 123, expected: (ValuesKt.same(PureSwiftStruct(x: 123)) as? PureSwiftStruct)?.x) try assertEquals(actual: "pure", expected: ValuesKt.iFunExt(PureSwiftKotlinInterfaceImpl())) } func testNames() throws { try assertEquals(actual: ValuesKt.PROPERTY_NAME_MUST_NOT_BE_ALTERED_BY_SWIFT, expected: 111) try assertEquals(actual: Deeply.NestedType().thirtyTwo, expected: 32) #if NO_GENERICS try assertEquals(actual: WithGenericDeeply.NestedType().thirtyThree, expected: 33) #else try assertEquals(actual: WithGenericDeeplyNestedType().thirtyThree, expected: 33) #endif try assertEquals(actual: CKeywords(float: 1.0, enum : 42, goto: true).goto_, expected: true) try assertEquals(actual: TypeOuter.Type_().thirtyFour, expected: 34) try assertTrue(String(describing: DeeplyNestedIType.self).hasSuffix("DeeplyNestedIType")) } class Base123 : Base23, ExtendedBase1 { override func same(value: KotlinInt?) -> KotlinInt { return value! } } func testSwiftOverride() throws { let impl = Base123() try assertEquals(actual: ValuesKt.call(base1: impl, value: 1), expected: 1) try assertEquals(actual: ValuesKt.call(extendedBase1: impl, value: 2), expected: 2) try assertEquals(actual: ValuesKt.call(base2: impl, value: 3), expected: 3) try assertEquals(actual: ValuesKt.call(base3: impl, value: 4), expected: 4) try assertEquals(actual: ValuesKt.call(base23: impl, value: 5), expected: 5) } class TransformIntToLongCallingSuper : TransformIntToLong { override func map(value: KotlinInt) -> KotlinLong { return super.map(value: value) } } func testKotlinOverride() throws { #if NO_GENERICS try assertEquals(actual: TransformInheritingDefault().map(value: 1) as! Int32, expected: 1) #else try assertEquals(actual: TransformInheritingDefault().map(value: 1) as! Int32, expected: 1) #endif try assertEquals(actual: TransformIntToDecimalString().map(value: 2), expected: "2") try assertEquals(actual: TransformIntToDecimalString().map(intValue: 3), expected: "3") try assertEquals(actual: ValuesKt.createTransformDecimalStringToInt().map(value: "4") as! Int32, expected: 4) try assertEquals(actual: TransformIntToLongCallingSuper().map(value: 5), expected: 5) } // See https://github.com/JetBrains/kotlin-native/issues/2945 func testGH2945() throws { let gh2945 = GH2945(errno: 1) try assertEquals(actual: 1, expected: gh2945.errno) gh2945.errno = 2 try assertEquals(actual: 2, expected: gh2945.errno) try assertEquals(actual: 7, expected: gh2945.testErrnoInSelector(p: 3, errno: 4)) } // See https://github.com/JetBrains/kotlin-native/issues/2830 func testGH2830() throws { try assertTrue(GH2830().getI() is GH2830I) } // See https://github.com/JetBrains/kotlin-native/issues/2959 func testGH2959() throws { try assertEquals(actual: GH2959().getI(id: 2959)[0].id, expected: 2959) } func testKClass() throws { let test = TestKClass() let testKClass = test.getKotlinClass(clazz: TestKClass.self)! try assertTrue(test.isTestKClass(kClass: testKClass)) try assertFalse(test.isI(kClass: testKClass)) try assertEquals(actual: testKClass.simpleName, expected: "TestKClass") let iKClass = test.getKotlinClass(protocol: TestKClassI.self)! try assertFalse(test.isTestKClass(kClass: iKClass)) try assertTrue(test.isI(kClass: iKClass)) try assertEquals(actual: iKClass.simpleName, expected: "I") try assertTrue(test.getKotlinClass(clazz: NSObject.self) == nil) try assertTrue(test.getKotlinClass(clazz: PureSwiftClass.self) == nil) try assertTrue(test.getKotlinClass(clazz: PureSwiftKotlinInterfaceImpl.self) == nil) try assertTrue(test.getKotlinClass(clazz: Base123.self) == nil) try assertTrue(test.getKotlinClass(protocol: NSObjectProtocol.self) == nil) } open class TestSR10177WorkaroundBase {} class TestSR10177WorkaroundDerived : TestSR10177WorkaroundBase {} // See https://bugs.swift.org/browse/SR-10177 and https://bugs.swift.org/browse/SR-10217 func testSR10177Workaround() throws { let test = TestSR10177WorkaroundDerived() try assertTrue(String(describing: test).contains("TestSR10177WorkaroundDerived")) } func testClashes() throws { let test = TestClashesImpl() let test1: TestClashes1 = test let test2: TestClashes2 = test try assertEquals(actual: 1, expected: test1.clashingProperty) try assertEquals(actual: 1, expected: test2.clashingProperty_ as! Int32) try assertEquals(actual: 2, expected: test2.clashingProperty__ as! Int32) } func testInvalidIdentifiers() throws { let test = TestInvalidIdentifiers() try assertTrue(TestInvalidIdentifiers._Foo() is TestInvalidIdentifiers._Foo) try assertFalse(TestInvalidIdentifiers.Bar_() is TestInvalidIdentifiers._Foo) try assertEquals(actual: 42, expected: test.a_d_d(_1: 13, _2: 14, _3: 15)) test._status = "OK" try assertEquals(actual: "OK", expected: test._status) try assertEquals(actual: TestInvalidIdentifiers.E._4_.value, expected: 4) try assertEquals(actual: TestInvalidIdentifiers.E._5_.value, expected: 5) try assertEquals(actual: TestInvalidIdentifiers.E.__.value, expected: 6) try assertEquals(actual: TestInvalidIdentifiers.E.___.value, expected: 7) try assertEquals(actual: TestInvalidIdentifiers.Companion_()._42, expected: 42) try assertEquals(actual: Set([test.__, test.___]), expected: Set(["$".utf16.first, "_".utf16.first])) } class ImplementingHiddenSubclass : TestDeprecation.ImplementingHidden { override func effectivelyHidden() -> Int32 { return -2 } } func testDeprecation() throws { let test = TestDeprecation() try assertEquals(actual: test.openNormal(), expected: 1) let testHiddenOverride: TestDeprecation = TestDeprecation.HiddenOverride() try assertEquals(actual: testHiddenOverride.openNormal(), expected: 2) let testErrorOverride: TestDeprecation = TestDeprecation.ErrorOverride() try assertEquals(actual: testErrorOverride.openNormal(), expected: 3) let testWarningOverride: TestDeprecation = TestDeprecation.WarningOverride() try assertEquals(actual: testWarningOverride.openNormal(), expected: 4) try assertEquals(actual: test.callEffectivelyHidden(obj: ImplementingHiddenSubclass()), expected: -2) } func setAssociatedObject(object: AnyObject, value: AnyObject) { objc_setAssociatedObject( object, UnsafeRawPointer(bitPattern: 1)!, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN ) } func testWeakRefs() throws { try testWeakRefs0(frozen: false) try testWeakRefs0(frozen: true) } func testWeakRefs0(frozen: Bool) throws { func getObj(test: TestWeakRefs) -> AnyObject { return autoreleasepool { test.getObj() as AnyObject } } func test1() throws { var test = TestWeakRefs(frozen: frozen) var obj: AnyObject? = getObj(test: test) weak var ref = getObj(test: test) ValuesKt.gc() try assertTrue(ref === getObj(test: test)) // There are both Kotlin and Swift references to the object. obj = nil ValuesKt.gc() try assertTrue(ref === getObj(test: test)) // There are only Kotlin references to the object. test.clearObj() ValuesKt.gc() try assertTrue(ref === nil) } func test2() throws { var test = TestWeakRefs(frozen: frozen) var obj: AnyObject? = getObj(test: test) weak var ref = getObj(test: test) ValuesKt.gc() try assertTrue(ref === obj!) // There are both Kotlin and Swift references to the object. test.clearObj() ValuesKt.gc() try assertTrue(ref === obj!) // There are only Swift references to the object. obj = nil ValuesKt.gc() try assertTrue(ref === nil) } func test3() throws { class Holder { static weak var ref: AnyObject? = nil static var deinitialized = false deinit { // Access weak ref to Kotlin object during its counterpart dealloc: try! assertTrue(Holder.ref === nil) Holder.deinitialized = true } } Holder.deinitialized = false Holder.ref = nil var test = TestWeakRefs(frozen: frozen) Holder.ref = getObj(test: test) // Prepare Holder() to get deinitialized along with getObj(test: test): setAssociatedObject( object: getObj(test: test), value: Holder() ) try assertFalse(Holder.ref === nil) try assertFalse(Holder.deinitialized) test.clearObj() ValuesKt.gc() try assertTrue(Holder.ref === nil) try assertTrue(Holder.deinitialized) } func test4() throws { class Holder { static weak var ref1: AnyObject? = nil static weak var ref2: AnyObject? = nil static var deinitialized: Int = 0 deinit { // Access weak ref to Kotlin object during its counterpart dealloc: try! assertTrue(Holder.ref1 === nil) try! assertTrue(Holder.ref2 === nil) Holder.deinitialized += 1 } } Holder.deinitialized = 0 Holder.ref1 = nil Holder.ref2 = nil var test = TestWeakRefs(frozen: frozen) autoreleasepool { let cycle = test.createCycle() let obj1 = cycle[0] as AnyObject let obj2 = cycle[1] as AnyObject // Prepare Holders to get deinitialized along with obj1 and obj2: setAssociatedObject(object: obj1, value: Holder()) setAssociatedObject(object: obj2, value: Holder()) Holder.ref1 = obj1 Holder.ref2 = obj2 } try assertFalse(Holder.ref1 === nil) try assertFalse(Holder.ref2 === nil) try assertEquals(actual: Holder.deinitialized, expected: 0) ValuesKt.gc() try assertTrue(Holder.ref1 === nil) try assertTrue(Holder.ref2 === nil) try assertEquals(actual: Holder.deinitialized, expected: 2) } try test1() try test2() try test3() try test4() } var falseFlag = false class TestSharedRefs { private func testLambdaSimple() throws { func getClosure() -> (() -> Void) { let lambda = autoreleasepool { SharedRefs().createLambda() } return { if falseFlag { lambda() } } } DispatchQueue.global().async(execute: getClosure()) } private static func launchInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) -> pthread_t { class Closure { static var currentBlock: (() -> Void)? = nil static var initializeKotlinRuntime: Bool = false } Closure.currentBlock = block Closure.initializeKotlinRuntime = initializeKotlinRuntime var thread: pthread_t? = nil let createCode = pthread_create(&thread, nil, { _ in if Closure.initializeKotlinRuntime { let ignore = SharedRefs() // Ensures that Kotlin runtime gets initialized. } Closure.currentBlock!() Closure.currentBlock = nil return nil }, nil) try! assertEquals(actual: createCode, expected: 0) return thread! } private static func joinThread(thread: pthread_t) { let joinCode = pthread_join(thread, nil) try! assertEquals(actual: joinCode, expected: 0) } private static func runInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) { let thread = launchInNewThread(initializeKotlinRuntime: initializeKotlinRuntime, block: block) joinThread(thread: thread) } private func runInNewThread(initializeKotlinRuntime: Bool, block: @escaping () -> Void) { return TestSharedRefs.runInNewThread(initializeKotlinRuntime: initializeKotlinRuntime, block: block) } private func testObjectPartialRelease() { let object = autoreleasepool { SharedRefs().createRegularObject() } var objectVar: AnyObject? = object runInNewThread(initializeKotlinRuntime: true) { objectVar = nil } } private func testRunRefCount( run: (@escaping () -> Void) -> Void, createObject: @escaping (SharedRefs) -> T ) throws { let refs = SharedRefs() var objectVar1: T? = autoreleasepool { createObject(refs) } var objectVar2: T? = nil try assertTrue(refs.hasAliveObjects()) run { objectVar2 = objectVar1! objectVar1 = nil } try assertTrue(refs.hasAliveObjects()) run { objectVar2 = nil } try assertFalse(refs.hasAliveObjects()) } private func testBackgroundRefCount(createObject: @escaping (SharedRefs) -> T) throws { try testRunRefCount( run: { runInNewThread(initializeKotlinRuntime: false, block: $0) }, createObject: createObject ) try testRunRefCount( run: { runInNewThread(initializeKotlinRuntime: true, block: $0) }, createObject: createObject ) } private func testReferenceOutlivesThread(releaseWithKotlinRuntime: Bool) throws { var objectVar: AnyObject? = nil weak var objectWeakVar: AnyObject? = nil var collection: AnyObject? = nil runInNewThread(initializeKotlinRuntime: false) { autoreleasepool { let refs = SharedRefs() collection = refs.createCollection() let object = refs.createRegularObject() objectVar = object objectWeakVar = object try! assertTrue(objectWeakVar === object) } } runInNewThread(initializeKotlinRuntime: releaseWithKotlinRuntime) { objectVar = nil collection = nil ValuesKt.gc() try! assertTrue(objectWeakVar === nil) } } private func testMoreWorkBeforeThreadExit() throws { class Deinit { static var object1: AnyObject? = nil static var object2: AnyObject? = nil static weak var weakVar2: AnyObject? = nil deinit { TestSharedRefs.runInNewThread(initializeKotlinRuntime: false) { Deinit.object2 = nil } } } runInNewThread(initializeKotlinRuntime: false) { autoreleasepool { let object1 = SharedRefs.MutableData() Deinit.object1 = object1 setAssociatedObject(object: object1, value: Deinit()) let object2 = SharedRefs.MutableData() Deinit.object2 = object2 Deinit.weakVar2 = object2 } TestSharedRefs.runInNewThread(initializeKotlinRuntime: false) { Deinit.object1 = nil } } try assertTrue(Deinit.weakVar2 === nil) } func testRememberNewObject(createObject: @escaping (SharedRefs) -> AnyObject) throws { class TestImpl : TestRememberNewObject { let cleanupFinishedSemaphore = DispatchSemaphore(value: 0) let threadWaitingForCleanupSemaphore = DispatchSemaphore(value: 0) var obj: AnyObject? = nil func getObject() -> Any { return obj! } func waitForCleanup() { threadWaitingForCleanupSemaphore.signal() cleanupFinishedSemaphore.wait() } } let test = TestImpl() let refs = SharedRefs() try assertFalse(refs.hasAliveObjects()) autoreleasepool { test.obj = createObject(refs) } try assertTrue(refs.hasAliveObjects()) let thread = TestSharedRefs.launchInNewThread(initializeKotlinRuntime: false) { ValuesKt.testRememberNewObject(test: test) } test.threadWaitingForCleanupSemaphore.wait() test.obj = nil ValuesKt.gc() try assertTrue(refs.hasAliveObjects()) test.cleanupFinishedSemaphore.signal() TestSharedRefs.joinThread(thread: thread) try assertFalse(refs.hasAliveObjects()) } func test() throws { try testLambdaSimple() try testObjectPartialRelease() try testBackgroundRefCount(createObject: { $0.createLambda() }) try testBackgroundRefCount(createObject: { $0.createRegularObject() }) try testBackgroundRefCount(createObject: { $0.createCollection() }) try testBackgroundRefCount(createObject: { $0.createFrozenLambda() }) try testBackgroundRefCount(createObject: { $0.createFrozenRegularObject() }) try testBackgroundRefCount(createObject: { $0.createFrozenCollection() }) try testReferenceOutlivesThread(releaseWithKotlinRuntime: false) try testReferenceOutlivesThread(releaseWithKotlinRuntime: true) try testMoreWorkBeforeThreadExit() try testRememberNewObject(createObject: { $0.createFrozenRegularObject() }) try testRememberNewObject(createObject: { $0.createFrozenCollection() }) usleep(300 * 1000) } } // See https://github.com/JetBrains/kotlin-native/issues/2931 func testGH2931() throws { for i in 0..<50000 { let holder = GH2931.Holder() let queue = DispatchQueue.global(qos: .background) let group = DispatchGroup() for j in 0..<2 { group.enter() queue.async { autoreleasepool { holder.data } group.leave() } } group.wait() } } class ClassForTypeCheckInheritor : ClassForTypeCheck { } func testClassTypeCheck() throws { try assertTrue(ValuesKt.testClassTypeCheck(x: ClassForTypeCheckInheritor())) } class ClassForInterfaceTypeCheckInheritor1 : InterfaceForTypeCheck { } class ClassForInterfaceTypeCheckInheritor2 : Base23, InterfaceForTypeCheck { } class ClassForInterfaceTypeCheckInheritor3 : Base23, ExtendedBase1, InterfaceForTypeCheck { } class ClassForInterfaceTypeCheck_Fail : Base23 { } func testInterfaceTypeCheck() throws { try assertTrue(ValuesKt.testInterfaceTypeCheck(x: ClassForInterfaceTypeCheckInheritor1())) try assertTrue(ValuesKt.testInterfaceTypeCheck(x: ClassForInterfaceTypeCheckInheritor2())) try assertTrue(ValuesKt.testInterfaceTypeCheck(x: ClassForInterfaceTypeCheckInheritor3())) try assertFalse(ValuesKt.testInterfaceTypeCheck(x: ClassForInterfaceTypeCheck_Fail())) } class AbstractInterface : AbstractInterfaceBase { override func bar() -> Int32 { return 42 } } // See https://github.com/JetBrains/kotlin-native/issues/3503 func testGH3503_1() throws { try assertEquals(actual: ValuesKt.testAbstractInterfaceCall(x: AbstractInterface()), expected: 42) } class AbstractInterface2 : AbstractInterfaceBase2 { } func testGH3503_2() throws { try assertEquals(actual: ValuesKt.testAbstractInterfaceCall2(x: AbstractInterface2()), expected: 42) } class AbstractInterface3 : AbstractInterfaceBase3 { override func foo() -> Int32 { return 42 } } func testGH3503_3() throws { try assertEquals(actual: ValuesKt.testAbstractInterfaceCall(x: AbstractInterface3()), expected: 42) } func testGH3525() throws { try assertEquals(actual: ValuesKt.gh3525BaseInitCount, expected: 0) try assertEquals(actual: ValuesKt.gh3525InitCount, expected: 0) let gh3525_1 = GH3525() try assertTrue(gh3525_1 is GH3525) try assertEquals(actual: ValuesKt.gh3525BaseInitCount, expected: 1) try assertEquals(actual: ValuesKt.gh3525InitCount, expected: 1) let gh3525_2 = GH3525() try assertTrue(gh3525_2 is GH3525) try assertEquals(actual: ValuesKt.gh3525BaseInitCount, expected: 1) try assertEquals(actual: ValuesKt.gh3525InitCount, expected: 1) try assertTrue(gh3525_1 === gh3525_2) } func testStringConversion() throws { func test1() throws { let test = TestStringConversion() let buffer = NSMutableString() buffer.append("a") test.str = buffer buffer.append("b") try assertEquals(actual: buffer, expected: "ab") // Ensure test.str isn't affected by buffer mutation: try assertEquals(actual: test.str as! NSString, expected: "a") } func ensureNoCopy(nsStr: NSString) throws { let test = TestStringConversion() test.str = nsStr let nsStr2 = test.str as! NSString // Ensure no additional NSString created on both conversions: try assertTrue(nsStr === nsStr2) } func test2() throws { var str = "a" str += NSObject().description try ensureNoCopy(nsStr: str as NSString) try ensureNoCopy(nsStr: NSString("abc")) try ensureNoCopy(nsStr: NSString(format: "%d%d%d", 3, 2, 1)) } try test1() try test2() } class GH3825SwiftImpl : GH3825 { class E : Error {} func call0(callback: () -> KotlinBoolean) throws { if callback().boolValue { throw E() } } func call1(doThrow: Bool, callback: () -> Void) throws { if doThrow { throw E() } callback() } func call2(callback: () -> Void, doThrow: Bool) throws { if doThrow { throw E() } callback() } } func testGH3825() throws { try ValuesKt.testGH3825(gh3825: GH3825SwiftImpl()) let test = GH3825KotlinImpl() var count = 0 try testThrowing { try test.call0 { true } } try test.call0 { count += 1 return false } try assertEquals(actual: count, expected: 1) try testThrowing { try test.call1(doThrow: true) { count += 1 } } try test.call1(doThrow: false) { count += 1 } try assertEquals(actual: count, expected: 2) try testThrowing { try test.call2(callback: { count += 1 }, doThrow: true)} try test.call2(callback: { count += 1 }, doThrow: false) try assertEquals(actual: count, expected: 3) } func testMapsExport() throws { // Original reproducer failed in different way for MutableMap (iOS 11) and Map (MacOS 10.14, iOS 13) try assertEquals(actual: ValuesKt.mapBoolean2String()[true], expected: "true") try assertEquals(actual: ValuesKt.mapByte2Short()[-1], expected: 2) try assertEquals(actual: ValuesKt.mapShort2Byte()[-2], expected: 1) try assertEquals(actual: ValuesKt.mapInt2Long()[-4], expected: 8) try assertEquals(actual: ValuesKt.mapLong2Long()[-8], expected: 8) try assertEquals(actual: ValuesKt.mapUByte2Boolean()[128], expected: true) try assertEquals(actual: ValuesKt.mapUShort2Byte()[0x8000], expected: 1) try assertEquals(actual: ValuesKt.mapUInt2Long()[0x7FFFFFFF], expected: 7) // the following samples require explicit cast to KotlinUInt or KotlinULong try assertEquals(actual: ValuesKt.mapUInt2Long()[KotlinUInt(-0x8000_0000)], expected: 8) _ = ValuesKt.mapULong2Long() as! [KotlinULong: KotlinLong] // test cast var u64: UInt64 = 0x8000_0000_0000_0000 try assertEquals(actual: ValuesKt.mapULong2Long()[KotlinULong(value: u64)], expected: 8) _ = ValuesKt.mapFloat2Float() as! [KotlinFloat: KotlinFloat] // test cast try assertEquals(actual: ValuesKt.mapFloat2Float()[3.14], expected: 100.0) try assertEquals(actual: ValuesKt.mapDouble2String()[2.718281828459045], expected: "2.718281828459045") // test also explicit cast to [:] of primitiva types, e.g. [Int: Int] try assertEquals(actual: (ValuesKt.mutBoolean2String() as! [Bool: String])[true], expected: "true") try assertEquals(actual: (ValuesKt.mutByte2Short() as! [Int8: Int16])[-1], expected: 2) try assertEquals(actual: (ValuesKt.mutShort2Byte() as! [Int16: Int8])[-2], expected: 1) try assertEquals(actual: (ValuesKt.mutInt2Long() as! [Int: Int64])[-4], expected: 8) try assertEquals(actual: (ValuesKt.mutLong2Long() as! [Int64: Int64])[-8], expected: 8) try assertEquals(actual: (ValuesKt.mutUByte2Boolean() as! [UInt8: Bool])[128], expected: true) try assertEquals(actual: (ValuesKt.mutUShort2Byte() as! [UInt16: Int8])[0x8000], expected: 1) // the following samples require explicit cast to KotlinUInt or KotlinULong try assertEquals(actual: (ValuesKt.mutUInt2Long() as! [UInt: Int64])[UInt(0x8000_0000)], expected: 8) try assertEquals(actual: (ValuesKt.mutULong2Long() as! [UInt64: Int64])[u64], expected: 8) try assertEquals(actual: (ValuesKt.mutFloat2Float() as! [Float: Float])[3.14], expected: 100.0) try assertEquals(actual: (ValuesKt.mutDouble2String() as! [Double: String])[2.718281828459045], expected: "2.718281828459045") } class Baz_FakeOverrideInInterface : Bar_FakeOverrideInInterface { func foo(t: Any?) {} } func testFakeOverrideInInterface() throws { ValuesKt.callFoo_FakeOverrideInInterface(obj: Baz_FakeOverrideInInterface()) } // -------- Execution of the test -------- class ValuesTests : SimpleTestProvider { override init() { super.init() test("TestValues", testVals) test("TestVars", testVars) test("TestDoubles", testDoubles) test("TestNumbers", testNumbers) test("TestLists", testLists) test("TestLazyValues", testLazyVal) test("TestDelegatedProperties", testDelegatedProp) test("TestGetterDelegate", testGetterDelegate) test("TestNulls", testNulls) test("TestAnyVar", testAnyVar) test("TestFunctions", testFunctions) test("TestExceptions", testExceptions) test("TestFuncType", testFuncType) test("TestGenericsFoo", testGenericsFoo) test("TestVararg", testVararg) test("TestStringExtension", testStrExtFun) test("TestAnyToString", testAnyToString) test("TestAnyPrint", testAnyPrint) test("TestCharExtensions", testCharExtensions) test("TestLambda", testLambda) test("TestInterfaceExtension", testInterfaceExtension) test("TestClassInstances", testClassInstances) test("TestEnum", testEnum) test("TestDataClass", testDataClass) test("TestCompanionObj", testCompanionObj) test("TestInlineClasses", testInlineClasses) test("TestShared", testShared) test("TestPureSwiftClasses", testPureSwiftClasses) test("TestNames", testNames) test("TestSwiftOverride", testSwiftOverride) test("TestKotlinOverride", testKotlinOverride) test("TestGH2945", testGH2945) test("TestGH2830", testGH2830) test("TestGH2959", testGH2959) test("TestKClass", testKClass) test("TestSR10177Workaround", testSR10177Workaround) test("TestClashes", testClashes) test("TestInvalidIdentifiers", testInvalidIdentifiers) test("TestDeprecation", testDeprecation) test("TestWeakRefs", testWeakRefs) test("TestSharedRefs", TestSharedRefs().test) test("TestClassTypeCheck", testClassTypeCheck) test("TestInterfaceTypeCheck", testInterfaceTypeCheck) test("TestGH3503_1", testGH3503_1) test("TestGH3503_2", testGH3503_2) test("TestGH3503_3", testGH3503_3) test("TestGH3525", testGH3525) test("TestStringConversion", testStringConversion) test("TestGH3825", testGH3825) test("TestMapsExport", testMapsExport) test("TestFakeOverrideInInterface", testFakeOverrideInInterface) // Stress test, must remain the last one: test("TestGH2931", testGH2931) } } ================================================ FILE: backend.native/tests/objcexport/variance.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package variance sealed class InvariantSuper class Invariant : InvariantSuper() sealed class OutVariantSuper class OutVariant : OutVariantSuper() sealed class InVariantSuper class InVariant : InVariantSuper() ================================================ FILE: backend.native/tests/objcexport/variance.swift ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation import Kt // -------- Tests -------- func testInstantiation() { #if NO_GENERICS Invariant() OutVariant() InVariant() #else Invariant() OutVariant() InVariant() #endif } // -------- Execution of the test -------- class VarianceTests : SimpleTestProvider { override init() { super.init() test("TestInstantiation", testInstantiation) } } ================================================ FILE: backend.native/tests/produce_dynamic/kt-36639/main.c ================================================ #include "testlib_api.h" #define __ testlib_symbols()-> #define T_(x) testlib_kref_ ## x int main() { T_(CFoo1) foo1 = __ kotlin.root.CFoo1.CFoo1(); T_(CFoo2) foo2 = __ kotlin.root.CFoo2.CFoo2(); T_(kotlin_Int) intV = __ createNullableInt(42); T_(kotlin_Any) any; T_(Foo) foo = { .pinned = foo1.pinned }; any.pinned = foo1.pinned; __ kotlin.root.CFoo1.callMe(foo1, any); __ kotlin.root.Foo.extfoo(foo, any); any.pinned = foo2.pinned; __ kotlin.root.CFoo1.callMe(foo1, any); __ kotlin.root.Foo.extfoo(foo, any); any.pinned = intV.pinned; __ kotlin.root.CFoo1.callMe(foo1, any); __ kotlin.root.Foo.extfoo(foo, any); __ DisposeStablePointer(foo1.pinned); __ DisposeStablePointer(foo2.pinned); __ DisposeStablePointer(intV.pinned); } ================================================ FILE: backend.native/tests/produce_dynamic/kt-36639/main.kt ================================================ interface Foo { fun Any.extfoo() } class CFoo1:Foo { override fun Any.extfoo() { when(this) { is CFoo1 -> println("CFoo1::extfoo") is CFoo2 -> println("CFoo2::extfoo") is Int -> println("Int::extfoo") } } fun callMe(arg: Any) = arg.extfoo() } class CFoo2:Foo { override fun Any.extfoo() { TODO("Not yet implemented") } } ================================================ FILE: backend.native/tests/produce_dynamic/simple/hello.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // FILE: hello.kt import kotlinx.cinterop.* import kotlin.native.CName import kotlin.native.concurrent.freeze // Top level functions. fun hello() { println("Hello, dynamic!") } fun getString() = "Kotlin/Native" data class Data(var string: String) fun getMutable() = Data("foo") // Class with inheritance. open class Base { open fun foo() = println("Base.foo") open fun fooParam(arg0: String, arg1: Int, arg2: String?) = println("Base.fooParam: $arg0 $arg1 ${arg2 ?: "null"}") @CName(externName = "", shortName = "strangeName") fun странноеИмя() = 111 } // Top level functions. @CName(externName = "topLevelFunctionFromC", shortName = "topLevelFunctionFromCShort") fun topLevelFunction(x1: Int, x2: Int) = x1 - x2 @CName("topLevelFunctionVoidFromC") fun topLevelFunctionVoid(x1: Int, x2: Int?, x3: Unit?, pointer: COpaquePointer?) { assert(x1 == 42) assert(x2 == 77) assert(x3 != null) assert(pointer == null) } // Enum. enum class Enum(val code: Int) { ONE(1), TWO(2), HUNDRED(100) } interface Interface { fun foo(): Int } enum class EnumWithInterface : Interface { ZERO ; override fun foo(): Int = 42 } // Object. interface Codeable { fun asCode(): Int } val an_object = object : Codeable { override fun asCode() = 42 } object Singleton { override fun toString() = "I am single" } class Child : Base() { override fun fooParam(arg0: String, arg1: Int, arg2: String?) = println("Child.fooParam: $arg0 $arg1 ${arg2 ?: "null"}") val roProperty: Int get() = 42 var rwProperty: Int = 0 get() = field set(value) { field = value + 1 } } // Interface. interface I { fun foo(arg0: String, arg1: Int, arg2: I) fun fooImpl() = foo("Hi", 239, this) } open class Impl1: I { override fun foo(arg0: String, arg1: Int, arg2: I) { println("Impl1.I: $arg0 $arg1 ${arg2::class.qualifiedName}") } } class Impl2 : Impl1() { override fun foo(arg0: String, arg1: Int, arg2: I) { println("Impl2.I: $arg0 $arg1 ${arg2::class.qualifiedName}") } } inline class IC1(val value: Int) inline class IC2(val value: String) inline class IC3(val value: Base?) fun useInlineClasses(ic1: IC1, ic2: IC2, ic3: IC3) { assert(ic1.value == 42) assert(ic2.value == "bar") assert(ic3.value is Base) } fun testNullableWithNulls(arg1: Int?, arg2: Unit?) { assert(arg1 == null) assert(arg2 == null) } fun setCErrorHandler(callback: CPointer) -> Unit>>?) { setUnhandledExceptionHook({ throwable: Throwable -> memScoped { callback!!(throwable.toString().cstr.ptr) } kotlin.system.exitProcess(0) }.freeze()) } fun throwException() { throw Error("Expected error") } fun getNullableString(param: Int) : String? { if (param == 0) { return "Hi" } else { return null } } fun getVector128() = vectorOf(1, 2, 3, 4) // FILE: gh3952.sync.kt package gh3952.sync class PlainSync {} // FILE: gh3952.nested.sync.kt package gh3952.nested.sync class NestedSync {} ================================================ FILE: backend.native/tests/produce_dynamic/simple/main.c ================================================ #include #include "testlib_api.h" #define __ testlib_symbols()-> #define T_(x) testlib_kref_ ## x #define CAST(T, v) testlib_kref_ ## T { .pinned = v } void errorHandler(const char* str) { printf("Error handler: %s\n", str); } void testVector128() { int __attribute__ ((__vector_size__ (16))) v4f = __ kotlin.root.getVector128(); printf("getVector128 = (%d, %d, %d, %d)\n", v4f[0], v4f[1], v4f[2], v4f[3]); } // See https://github.com/JetBrains/kotlin-native/issues/3952 void testGH3952() { T_(gh3952_nested_sync_NestedSync) good = __ kotlin.root.gh3952.nested.sync.NestedSync.NestedSync(); T_(gh3952_sync_PlainSync) alsoGood = __ kotlin.root.gh3952.sync.PlainSync.PlainSync(); __ DisposeStablePointer(good.pinned); __ DisposeStablePointer(alsoGood.pinned); } int main(void) { T_(Singleton) singleton = __ kotlin.root.Singleton._instance(); T_(Base) base = __ kotlin.root.Base.Base(); T_(Child) child = __ kotlin.root.Child.Child(); T_(Impl1) impl1 = __ kotlin.root.Impl1.Impl1(); T_(Impl2) impl2 = __ kotlin.root.Impl2.Impl2(); T_(Base) casted_child = { .pinned = child.pinned }; T_(I) casted_impl1 = { .pinned = impl1.pinned }; T_(I) casted_impl2 = { .pinned = impl2.pinned }; T_(Enum) enum1 = __ kotlin.root.Enum.HUNDRED.get(); T_(Codeable) object1 = __ kotlin.root.get_an_object(); T_(Data) data = __ kotlin.root.getMutable(); T_(kotlin_Int) nullableInt = __ createNullableInt(77); T_(kotlin_Unit) nullableUnit = __ createNullableUnit(); T_(kotlin_Int) nullableIntNull = { .pinned = 0 }; T_(kotlin_Unit) nullableUnitNull = { .pinned = 0 }; T_(EnumWithInterface) enum2 = __ kotlin.root.EnumWithInterface.ZERO.get(); const char* string1 = __ kotlin.root.getString(); const char* string2 = __ kotlin.root.Singleton.toString(singleton); const char* string3 = __ kotlin.root.Data.get_string(data); const char* string4 = __ kotlin.root.getNullableString(0); const char* string5 = __ kotlin.root.getNullableString(1); __ kotlin.root.hello(); __ kotlin.root.Base.foo(base); __ kotlin.root.Base.fooParam(base, "a", 1, "q"); __ kotlin.root.Child.fooParam(child, "b", 2, (char*)0); __ kotlin.root.Base.fooParam(casted_child, "c", 3, (char*)0); __ kotlin.root.I.foo(casted_impl1, "d", 4, casted_impl1); __ kotlin.root.I.foo(casted_impl2, "e", 5, casted_impl2); printf("String is %s nullable is %s null is %s\n", string1, string4, string5 ? "BAD" : "OK"); printf("RO property is %d\n", __ kotlin.root.Child.get_roProperty(child)); __ kotlin.root.Child.set_rwProperty(child, 238); printf("RW property is %d\n", __ kotlin.root.Child.get_rwProperty(child)); printf("enum100 = %d\n", __ kotlin.root.Enum.get_code(enum1)); printf("enum42 = %d\n", __ kotlin.root.EnumWithInterface.foo(enum2)); printf("object = %d\n", __ kotlin.root.Codeable.asCode(object1)); printf("singleton = %s\n", string2); printf("mutable = %s\n", string3); topLevelFunctionVoidFromC(42, nullableInt, nullableUnit, 0); __ kotlin.root.topLevelFunctionVoid(42, nullableInt, nullableUnit, 0); printf("topLevel = %d %d\n", topLevelFunctionFromC(780, 3), __ kotlin.root.topLevelFunctionFromCShort(5, 2)); __ kotlin.root.useInlineClasses(42, "bar", base); __ kotlin.root.testNullableWithNulls(nullableIntNull, nullableUnitNull); printf("IsInstance1 = %s\n", __ IsInstance(singleton.pinned, __ kotlin.root.Singleton._type()) ? "PASS" : "FAIL"); printf("IsInstance2 = %s\n", !(__ IsInstance(singleton.pinned, __ kotlin.root.Codeable._type())) ? "PASS" : "FAIL"); testVector128(); testGH3952(); __ DisposeStablePointer(singleton.pinned); __ DisposeString(string1); __ DisposeString(string2); __ DisposeString(string3); __ DisposeString(string4); __ DisposeString(string5); __ DisposeStablePointer(base.pinned); __ DisposeStablePointer(child.pinned); __ DisposeStablePointer(impl1.pinned); __ DisposeStablePointer(impl2.pinned); __ DisposeStablePointer(enum1.pinned); __ DisposeStablePointer(object1.pinned); __ DisposeStablePointer(data.pinned); __ DisposeStablePointer(nullableInt.pinned); __ DisposeStablePointer(nullableUnit.pinned); __ DisposeStablePointer(enum2.pinned); __ kotlin.root.setCErrorHandler(&errorHandler); __ kotlin.root.throwException(); return 0; } ================================================ FILE: backend.native/tests/runtime/basic/args0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args : Array) { for (s in args) { println(s) } } ================================================ FILE: backend.native/tests/runtime/basic/assert_failed.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { assert(false) } ================================================ FILE: backend.native/tests/runtime/basic/assert_passed.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { assert(true) } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_basic.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) package runtime.basic.cleaner_basic import kotlin.test.* import kotlin.native.internal.* import kotlin.native.concurrent.* import kotlin.native.ref.WeakReference class AtomicBoolean(initialValue: Boolean) { private val impl = AtomicInt(if (initialValue) 1 else 0) init { freeze() } public var value: Boolean get() = impl.value != 0 set(new) { impl.value = if (new) 1 else 0 } } class FunBox(private val impl: () -> Unit) { fun call() { impl() } } @Test fun testCleanerLambda() { val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val cleaner = { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) createCleaner(funBox) { it.call() } }() GC.collect() // Make sure local funBox reference is gone cleanerWeak = WeakReference(cleaner) assertFalse(called.value) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) } @Test fun testCleanerAnonymousFunction() { val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val cleaner = { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) createCleaner(funBox, fun (it: FunBox) { it.call() }) }() GC.collect() // Make sure local funBox reference is gone cleanerWeak = WeakReference(cleaner) assertFalse(called.value) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) } @Test fun testCleanerFunctionReference() { val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val cleaner = { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) createCleaner(funBox, FunBox::call) }() GC.collect() // Make sure local funBox reference is gone cleanerWeak = WeakReference(cleaner) assertFalse(called.value) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) } @Test fun testCleanerFailWithNonShareableArgument() { val funBox = FunBox {} assertFailsWith { createCleaner(funBox) {} } } @Test fun testCleanerCleansWithoutGC() { val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val cleaner = { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) createCleaner(funBox) { it.call() } }() GC.collect() // Make sure local funBox reference is gone cleaner.freeze() cleanerWeak = WeakReference(cleaner) assertFalse(called.value) }() GC.collect() assertNull(cleanerWeak!!.value) waitCleanerWorker() assertTrue(called.value) // If this fails, GC has somehow ran on the cleaners worker. assertNotNull(funBoxWeak!!.value) } val globalInt = AtomicInt(0) @Test fun testCleanerWithInt() { var cleanerWeak: WeakReference? = null { val cleaner = createCleaner(42) { globalInt.value = it }.freeze() cleanerWeak = WeakReference(cleaner) assertEquals(0, globalInt.value) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertEquals(42, globalInt.value) } val globalPtr = AtomicNativePtr(NativePtr.NULL) @Test fun testCleanerWithNativePtr() { var cleanerWeak: WeakReference? = null { val cleaner = createCleaner(NativePtr.NULL + 42L) { globalPtr.value = it } cleanerWeak = WeakReference(cleaner) assertEquals(NativePtr.NULL, globalPtr.value) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertEquals(NativePtr.NULL + 42L, globalPtr.value) } @Test fun testCleanerWithException() { val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) val cleaner = createCleaner(funBox) { it.call() error("Cleaner block failed") } cleanerWeak = WeakReference(cleaner) }() GC.collect() performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) // Cleaners block started executing. assertTrue(called.value) // Even though the block failed, the captured funBox is freed. assertNull(funBoxWeak!!.value) } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_in_main_with_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.native.internal.* import kotlin.native.Platform fun main() { // Cleaner holds onto a finalization lambda. If it doesn't get executed, // the memory will leak. Suppress memory leak checker to check for cleaners // leak only. Platform.isMemoryLeakCheckerActive = false Platform.isCleanersLeakCheckerActive = true // This cleaner will run, because with the checker active this cleaner // will get collected, block scheduled and executed before cleaners are disabled. createCleaner(42) { println(it) } } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_in_main_without_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.native.internal.* import kotlin.native.Platform fun main() { // Cleaner holds onto a finalization lambda. If it doesn't get executed, // the memory will leak. Suppress memory leak checker to check for cleaners // leak only. Platform.isMemoryLeakCheckerActive = false Platform.isCleanersLeakCheckerActive = false // This cleaner will not run, because with the checker inactive this cleaner // will not get collected before cleaners are disabled. createCleaner(42) { println(it) } } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_in_tls_main_with_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.* import kotlin.native.Platform @ThreadLocal var tlsCleaner: Cleaner? = null fun main() { // Cleaner holds onto a finalization lambda. If it doesn't get executed, // the memory will leak. Suppress memory leak checker to check for cleaners // leak only. Platform.isMemoryLeakCheckerActive = false Platform.isCleanersLeakCheckerActive = true // This cleaner won't be run tlsCleaner = createCleaner(42) { println(it) } } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_in_tls_main_without_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.* import kotlin.native.Platform @ThreadLocal var tlsCleaner: Cleaner? = null fun main() { // Cleaner holds onto a finalization lambda. If it doesn't get executed, // the memory will leak. Suppress memory leak checker to check for cleaners // leak only. Platform.isMemoryLeakCheckerActive = false Platform.isCleanersLeakCheckerActive = false // This cleaner won't be run tlsCleaner = createCleaner(42) { println(it) } } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_in_tls_worker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.* @ThreadLocal var tlsCleaner: Cleaner? = null val value = AtomicInt(0) fun main() { val worker = Worker.start() worker.execute(TransferMode.SAFE, {}) { tlsCleaner = createCleaner(42) { value.value = it } } worker.requestTermination().result waitWorkerTermination(worker) waitCleanerWorker() assertEquals(42, value.value) } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_leak_with_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.test.* import kotlin.native.internal.* import kotlin.native.Platform // This cleaner won't be run, because it's deinitialized with globals after // cleaners are disabled. val globalCleaner = createCleaner(42) { println(it) } fun main() { Platform.isCleanersLeakCheckerActive = true // Make sure cleaner is initialized. assertNotNull(globalCleaner) } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_leak_without_checker.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) import kotlin.test.* import kotlin.native.internal.* import kotlin.native.Platform // This cleaner won't be run, because it's deinitialized with globals after // cleaners are disabled. val globalCleaner = createCleaner(42) { println(it) } fun main() { // Make sure cleaner is initialized. assertNotNull(globalCleaner) } ================================================ FILE: backend.native/tests/runtime/basic/cleaner_workers.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalStdlibApi::class) package runtime.basic.cleaner_workers import kotlin.test.* import kotlin.native.internal.* import kotlin.native.concurrent.* import kotlin.native.ref.WeakReference class AtomicBoolean(initialValue: Boolean) { private val impl = AtomicInt(if (initialValue) 1 else 0) init { freeze() } public var value: Boolean get() = impl.value != 0 set(new) { impl.value = if (new) 1 else 0 } } class FunBox(private val impl: () -> Unit) { fun call() { impl() } } @Test fun testCleanerDestroyInChild() { val worker = Worker.start() val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null worker.execute(TransferMode.SAFE, { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) val cleaner = createCleaner(funBox) { it.call() } cleanerWeak = WeakReference(cleaner) Pair(called, cleaner) }) { (called, cleaner) -> assertFalse(called.value) }.result GC.collect() worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) worker.requestTermination().result } @Test fun testCleanerDestroyWithChild() { val worker = Worker.start() val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null worker.execute(TransferMode.SAFE, { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) val cleaner = createCleaner(funBox) { it.call() } cleanerWeak = WeakReference(cleaner) Pair(called, cleaner) }) { (called, cleaner) -> assertFalse(called.value) }.result GC.collect() worker.requestTermination().result waitWorkerTermination(worker) performGCOnCleanerWorker() // Collect cleaners stack assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) } @Test fun testCleanerDestroyInMain() { val worker = Worker.start() val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null { val result = worker.execute(TransferMode.SAFE, { called }) { called -> val funBox = FunBox { called.value = true }.freeze() val cleaner = createCleaner(funBox) { it.call() } Triple(cleaner, WeakReference(funBox), WeakReference(cleaner)) }.result val cleaner = result.first funBoxWeak = result.second cleanerWeak = result.third assertFalse(called.value) }() GC.collect() worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) worker.requestTermination().result } @Test fun testCleanerDestroyShared() { val worker = Worker.start() val called = AtomicBoolean(false); var funBoxWeak: WeakReference? = null var cleanerWeak: WeakReference? = null val cleanerHolder: AtomicReference = AtomicReference(null); { val funBox = FunBox { called.value = true }.freeze() funBoxWeak = WeakReference(funBox) val cleaner = createCleaner(funBox) { it.call() } cleanerWeak = WeakReference(cleaner) cleanerHolder.value = cleaner worker.execute(TransferMode.SAFE, { Pair(called, cleanerHolder) }) { (called, cleanerHolder) -> cleanerHolder.value = null assertFalse(called.value) }.result }() GC.collect() worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result performGCOnCleanerWorker() assertNull(cleanerWeak!!.value) assertTrue(called.value) assertNull(funBoxWeak!!.value) worker.requestTermination().result } @ThreadLocal var tlsValue = 11 @Test fun testCleanerWithTLS() { val worker = Worker.start() tlsValue = 12 val value = AtomicInt(0) worker.execute(TransferMode.SAFE, {value}) { tlsValue = 13 createCleaner(it) { it.value = tlsValue } Unit }.result worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result performGCOnCleanerWorker() assertEquals(11, value.value) worker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/basic/driver0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // TODO: remove kotlin_native.io once overrides are in place. fun main(args : Array) { println("Hello, world!") } ================================================ FILE: backend.native/tests/runtime/basic/empty_substring.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.empty_substring import kotlin.test.* @Test fun runTest() { val hello = "Hello world" println(hello.subSequence(1, 1).toString()) } ================================================ FILE: backend.native/tests/runtime/basic/entry0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.entry0 fun fail() { println("Test failed, this is a wrong main() function.") } fun main() { fail() } fun main(args: Array) { fail() } fun main(args: Array) { fail() } fun main(args: Array, second_arg: Int) { fail() } class Foo { fun main(args: Array) { fail() } } fun main(args: Array) { println("Hello.") } ================================================ FILE: backend.native/tests/runtime/basic/entry1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun fail() { println("Test failed, this is a wrong main() function.") } fun foo(args: Array) { println("Hello.") } fun bar() { println("Hello, without args.") } fun main(args: Array) { fail() } ================================================ FILE: backend.native/tests/runtime/basic/entry2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { fail() } ================================================ FILE: backend.native/tests/runtime/basic/entry4.kt ================================================ fun main() { println("This is main without args") } ================================================ FILE: backend.native/tests/runtime/basic/enum_equals.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.enum_equals import kotlin.test.* enum class EnumA { A, B } enum class EnumB { B } fun main() { println(EnumA.A == EnumA.A) println(EnumA.A == EnumA.B) println(EnumA.A == EnumB.B) } ================================================ FILE: backend.native/tests/runtime/basic/exit.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.system.* fun main(args: Array) { exitProcess(42) @Suppress("UNREACHABLE_CODE") throw RuntimeException("Exit function call returned normally") } ================================================ FILE: backend.native/tests/runtime/basic/for0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.for0 import kotlin.test.* @Test fun runTest() { val byteArray = ByteArray(3) byteArray[0] = 2 byteArray[1] = 3 byteArray[2] = 4 for (item in byteArray) { println(item) } } ================================================ FILE: backend.native/tests/runtime/basic/hash0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.hash0 import kotlin.test.* @Test fun runTest() { println(239.hashCode()) println((-1L).hashCode()) println('a'.hashCode()) println(1.0f.hashCode()) println(1.0.hashCode()) println(true.hashCode()) println(false.hashCode()) println(Any().hashCode() != Any().hashCode()) val a = CharArray(5) a[0] = 'H' a[1] = 'e' a[2] = 'l' a[3] = 'l' a[4] = 'o' println("Hello".hashCode() == String(a, 0, 5).hashCode()) } ================================================ FILE: backend.native/tests/runtime/basic/hello0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.hello0 import kotlin.test.* @Test fun runTest() { println("Hello, world!") } ================================================ FILE: backend.native/tests/runtime/basic/hello1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // TODO: TestRuner should be able to pass input to stdin // TODO: remove kotlin_native.io once overrides are in place. fun main(args: Array) { print(readLine().toString()) } ================================================ FILE: backend.native/tests/runtime/basic/hello2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // TODO: TestRuner should be able to pass input to stdin // TODO: remove kotlin_native.io once overrides are in place. fun main(args : Array) { print("you entered '" + readLine() + "'") } ================================================ FILE: backend.native/tests/runtime/basic/hello3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.hello3 import kotlin.test.* @Test fun runTest() { println(239) // TODO: enable, once override by name is implemented. println(true) println(3.14159) println('A') } ================================================ FILE: backend.native/tests/runtime/basic/hello4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.hello4 import kotlin.test.* @Test fun runTest() { val x = 2 println(if (x == 2) "Hello" else "Привет") println(if (x == 3) "Bye" else "Пока") } ================================================ FILE: backend.native/tests/runtime/basic/hypot.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlin.math.* fun main() { val hf = hypot(Float.NEGATIVE_INFINITY, Float.NaN) println("float hypot: $hf ${hf.toRawBits().toString(16)}") println("Float.NaN: ${Float.NaN.toRawBits().toString(16)}") println("Float.+Inf: ${Float.POSITIVE_INFINITY} ${Float.POSITIVE_INFINITY.toRawBits().toString(16)}") println("Float.-Inf: ${Float.NEGATIVE_INFINITY} ${Float.NEGATIVE_INFINITY.toRawBits().toUInt().toString(16)}") println(Float.POSITIVE_INFINITY == Float.NEGATIVE_INFINITY) assertEquals(Float.POSITIVE_INFINITY, hypot(Float.NEGATIVE_INFINITY, Float.NaN)) val hd = hypot(Double.NEGATIVE_INFINITY, Double.NaN) println("Double hypot: $hd ${hd.toRawBits().toString(16)}") println("Double.NaN: ${Double.NaN.toRawBits().toString(16)}") println("Double.+Inf: ${Double.POSITIVE_INFINITY} ${Double.POSITIVE_INFINITY.toRawBits().toString(16)}") println("Double.-Inf: ${Double.NEGATIVE_INFINITY} ${Double.NEGATIVE_INFINITY.toRawBits().toUInt().toString(16)}") println(Double.POSITIVE_INFINITY == Double.NEGATIVE_INFINITY) assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.NaN)) println("hypot NaN, 0: ${hypot(Double.NaN, 0.0).toRawBits().toString(16)}") assertTrue(hypot(Double.NaN, 0.0).isNaN()) } ================================================ FILE: backend.native/tests/runtime/basic/ieee754.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.ieee754 import kotlin.test.* @Test fun runTest() { val v = Float.POSITIVE_INFINITY val i = v.toInt() println("$v $i ${v.toShort()} ${i.toShort()}") val a = 42 val b = Float.MAX_VALUE println("${a + b}") val s = Float.NaN.toShort() println("NAN2SHORT:: $s") val d: Float = Float.MAX_VALUE println("MAX2SHORT:: ${d.toShort()}") val d2i = d.toInt() println("$d2i ${d2i.toShort()}") for (f in arrayOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE / 2, Float.MAX_VALUE, 3.14f, Float.NaN, -33333.12312f, Float.MIN_VALUE, Float.NEGATIVE_INFINITY, -1.2f, -12.6f, 2.3f)) { println("FLOAT:: $f INT:: ${f.toInt()}") } println("OK") } ================================================ FILE: backend.native/tests/runtime/basic/init.kt ================================================ val x = initRuntimeIfNeeded() fun main() { } ================================================ FILE: backend.native/tests/runtime/basic/initializers0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers0 import kotlin.test.* class A { init{ println ("A::init") } val a = 1 companion object :B(1) { init { println ("A::companion") } fun foo() { println("A::companion::foo") } } object AObj : B(){ init { println("A::Obj") } fun foo() { println("A::AObj::foo") } } } @Test fun runTest() { println("main") A.foo() A.foo() A.AObj.foo() A.AObj.foo() } open class B(val a:Int, val b:Int) { constructor(a:Int):this (a, 0) { println("B::constructor(" + a.toString()+ ")") } constructor():this(0) { println("B::constructor()") } } ================================================ FILE: backend.native/tests/runtime/basic/initializers1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers1 import kotlin.test.* class TestClass { companion object { init { println("Init Test") } } } @Test fun runTest() { val t1 = TestClass() val t2 = TestClass() println("Done") } ================================================ FILE: backend.native/tests/runtime/basic/initializers2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ class A(val msg: String) { init { println("init $msg") } override fun toString(): String = msg } val globalValue1 = 1 val globalValue2 = A("globalValue2") val globalValue3 = A("globalValue3") fun main(args: Array) { println(globalValue1.toString()) println(globalValue2.toString()) println(globalValue3.toString()) } ================================================ FILE: backend.native/tests/runtime/basic/initializers3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers3 import kotlin.test.* class Foo(val bar: Int) var x = Foo(42) @Test fun runTest() { println(x.bar) } ================================================ FILE: backend.native/tests/runtime/basic/initializers4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers4 import kotlin.test.* const val INT_MAX_POWER_OF_TWO: Int = Int.MAX_VALUE / 2 + 1 val DOUBLE = Double.MAX_VALUE - 1.0 @Test fun runTest() { println(INT_MAX_POWER_OF_TWO) println(DOUBLE > 0.0) } ================================================ FILE: backend.native/tests/runtime/basic/initializers5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers5 import kotlin.test.* object A { val a = 42 val b = A.a } @Test fun runTest() { println(A.b) } ================================================ FILE: backend.native/tests/runtime/basic/initializers6.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers6 import kotlin.test.* import kotlin.native.concurrent.* val aWorkerId = AtomicInt(0) val bWorkersCount = 3 val aWorkerUnlocker = AtomicInt(0) val bWorkerUnlocker = AtomicInt(0) object A { init { // Must be called by aWorker only. assertEquals(aWorkerId.value, Worker.current.id) // Only allow b workers to run, when a worker has started initialization. bWorkerUnlocker.increment() // Only proceed with initialization, when all b workers have started executing. while (aWorkerUnlocker.value < bWorkersCount) {} // And now wait a bit, to increase probability of races. Worker.current.park(100 * 1000L) } val a = produceA() val b = produceB() } fun produceA(): String { // Must've been called by aWorker only. assertEquals(aWorkerId.value, Worker.current.id) return "A" } fun produceB(): String { // Must've been called by aWorker only. assertEquals(aWorkerId.value, Worker.current.id) // Also check that it's ok to get A.a while initializing A.b. return "B+${A.a}" } @Test fun runTest() { val aWorker = Worker.start() aWorkerId.value = aWorker.id val bWorkers = Array(bWorkersCount, { _ -> Worker.start() }) val aFuture = aWorker.execute(TransferMode.SAFE, {}, { A.b }) val bFutures = Array(bWorkers.size, { bWorkers[it].execute(TransferMode.SAFE, {}, { // Wait until A has started to initialize. while (bWorkerUnlocker.value < 1) {} // Now allow A initialization to continue. aWorkerUnlocker.increment() // And this should not've tried to init A itself. A.a + A.b }) }) for (future in bFutures) { assertEquals("AB+A", future.result) } assertEquals("B+A", aFuture.result) for (worker in bWorkers) { worker.requestTermination().result } aWorker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/basic/initializers7.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers7 import kotlin.test.* object A { init { assertAUninitialized() } val a1 = 7 val a2 = 12 } // Check that A is initialized dynamically. fun assertAUninitialized() { assertEquals(0, A.a1) assertEquals(0, A.a2) } object B { init { assertBUninitialized() } val b1 = A.a2 val b2 = C.c1 } // Check that B is initialized dynamically. fun assertBUninitialized() { assertEquals(0, B.b1) assertEquals(0, B.b2) } object C { init { assertCUninitialized() } val c1 = 42 val c2 = A.a1 val c3 = B.b1 val c4 = B.b2 } // Check that C is initialized dynamically. fun assertCUninitialized() { assertEquals(0, C.c1) assertEquals(0, C.c2) assertEquals(0, C.c3) assertEquals(0, C.c4) } @Test fun runTest() { assertEquals(A.a1, C.c2) assertEquals(A.a2, C.c3) assertEquals(C.c1, C.c4) } ================================================ FILE: backend.native/tests/runtime/basic/initializers8.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.initializers8 import kotlin.test.* var globalString = "abc" @Test fun runTest() { assertEquals("abc", globalString) } ================================================ FILE: backend.native/tests/runtime/basic/interface0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.interface0 import kotlin.test.* interface A { fun b() = c() fun c() } class B(): A { override fun c() { println("PASSED") } } @Test fun runTest() { val a:A = B() a.b() } ================================================ FILE: backend.native/tests/runtime/basic/libentry2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun fail() { println("Test failed, this is a wrong main() function.") } fun foo(args: Array) { println("Hello.") } ================================================ FILE: backend.native/tests/runtime/basic/main_exception.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.main_exception import kotlin.test.* @Test fun runTest() { throw Error("Hello!") } ================================================ FILE: backend.native/tests/runtime/basic/random.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.random import kotlin.collections.* import kotlin.random.* import kotlin.system.* import kotlin.test.* /** * Tests that setting the same seed make random generate the same sequence */ private inline fun testReproducibility(seed: Long, generator: Random.() -> T) { // Reset seed. This will make Random to start a new sequence val r1 = Random(seed) val first = Array(50, { i -> r1.generator() }).toList() // Reset seed and try again val r2 = Random(seed) val second = Array(50, { i -> r2.generator() }).toList() assertTrue(first == second, "FAIL: got different sequences of generated values " + "first: $first, second: $second") } /** * Tests that setting seed makes random generate different sequence. */ private inline fun testDifference(generator: Random.() -> T) { val r1 = Random(12345678L) val first = Array(100, { i -> r1.generator() }).toList() val r2 = Random(87654321L) val second = Array(100, { i -> r2.generator() }).toList() assertTrue(first != second, "FAIL: got the same sequence of generated values " + "first: $first, second: $second") } @Test fun testInts() { testReproducibility(getTimeMillis(), { nextInt() }) testReproducibility(Long.MAX_VALUE, { nextInt() }) } @Test fun testLong() { testReproducibility(getTimeMillis(), { nextLong() }) testReproducibility(Long.MAX_VALUE, { nextLong() }) } @Test fun testDiffInt() = testDifference { nextInt() } @Test fun testDiffLong() = testDifference { nextLong() } @Test fun testNextInt() { testReproducibility(getTimeMillis(), { nextInt(1000) }) testReproducibility(1000L, { nextInt(1024) }) } ================================================ FILE: backend.native/tests/runtime/basic/readline0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { print(readLine()!!.toInt()) } ================================================ FILE: backend.native/tests/runtime/basic/readline1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { print(readLine()!!) } ================================================ FILE: backend.native/tests/runtime/basic/simd.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.simd import kotlin.test.* @Test fun runTest() { testBoxingSimple() testBoxing() testSetGet() testString() testOOB() testEquals() testHash() testDefaultValue() } class Box(t: T) { var value = t } class UnalignedC(t: Vector128) { var smth = 1 var value = t } fun testBoxingSimple() { val v = vectorOf(1f, 3.162f, 10f, 31f) val box: Box = Box(v) assertEquals(v, box.value, "testBoxingSimple FAILED") } fun testBoxing() { var u = UnalignedC(vectorOf(0, 1, 2, 3)) assertEquals(3, u.value.getIntAt(3)) u.value = vectorOf(0f, 1f, 2f, 3f) assertEquals(vectorOf(0f, 1f, 2f, 3f), u.value, "testBoxing FAILED") } fun testSetGet() { var v4any = vectorOf(0, 1, 2, 3) (0 until 4).forEach { assertEquals(it, v4any.getIntAt(it), "testSetGet FAILED for <4 x i32>") } // type punning: set the variable to another runtime type val a = arrayOf(1f, 3.162f, 10f, 31f) v4any = vectorOf(a[0], a[1], a[2], a[3]) (0 until 4).forEach { assertEquals(a[it], v4any.getFloatAt(it), "testSetGet FAILED for <4 x float>") } } fun testString() { val v4i = vectorOf(100, 1024, Int.MAX_VALUE, Int.MIN_VALUE) assertEquals("(0x64, 0x400, 0x7fffffff, 0x80000000)", v4i.toString(), "testString FAILED") } fun testOOB() { val f = vectorOf(1f, 3.162f, 10f, 31f) println("f.getByteAt(15) is OK ${f.getByteAt(15)}") assertFailsWith("f.getByteAt(16) should fail") { f.getByteAt(16) } assertFailsWith("f.getIntAt(-1) should fail") { f.getIntAt(-1) } assertFailsWith("f.getFloatAt(4) should fail") { f.getFloatAt(4) } } fun testEquals() { var v1 = vectorOf(-1f, 0f, 0f, -7f) var v2 = vectorOf(1f, 4f, 3f, 7f) assertEquals(false, v1 == v2) assertEquals(false, v1.equals(v2)) assertEquals(false, v1.equals(Any())) assertEquals(true, v2 == v2) v1 = v2 assertEquals(true, v1 == v2) } fun testHash() { val h1 = vectorOf(1f, 4f, 3f, 7f).hashCode() val h2 = vectorOf(3f, 7f, 1f, 4f).hashCode() assertEquals(false, h1 == h2) val i = 654687 assertEquals(true, vectorOf(0, 0, i, 0).hashCode() == i.hashCode()) // exploit little endianness assertEquals(true, vectorOf(1, 0, 0, 0).hashCode() == vectorOf(0, 0, 31, 0).hashCode()) } private fun funDefaultValue(v: Vector128 = vectorOf(1.0f, 2.0f, 3.0f, 4.0f)) = v fun testDefaultValue() { assertEquals(vectorOf(1.0f, 2.0f, 3.0f, 4.0f), funDefaultValue()) } ================================================ FILE: backend.native/tests/runtime/basic/standard.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.standard import kotlin.test.* class Foo(val bar: Int) fun assertEquals(actual: T, expected: T) { if (actual != expected) throw AssertionError("Assertion failed. Expected value: $expected, actual value: $actual") } @Test fun runTest() { try { TODO() throw AssertionError("TODO() doesn't throw an exception") } catch(e: NotImplementedError) {} val foo = Foo(42) assertEquals(run { 42 }, 42) assertEquals(foo.run { bar }, 42) assertEquals(with(foo) { bar }, 42) assertEquals(foo.apply { bar }, foo) assertEquals(foo.also { it.bar }, foo) assertEquals(foo.let { it.bar }, 42) var i = 0 repeat(10) { i++ } assertEquals(i, 10) } ================================================ FILE: backend.native/tests/runtime/basic/statements0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.statements0 import kotlin.test.* fun simple() { var a = 238 a++ println(a) --a println(a) } class Foo() { val j = 2 var i = 29 fun more() { i++ } fun less() { --i } } fun fields() { val foo = Foo() foo.more() println(foo.i) foo.less() println(foo.i) } @Test fun runTest() { simple() fields() } ================================================ FILE: backend.native/tests/runtime/basic/throw0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.throw0 import kotlin.test.* @Test fun runTest() { val cond = 1 if (cond == 2) throw RuntimeException() if (cond == 3) throw NoSuchElementException("no such element") if (cond == 4) throw Error("error happens") println("Done") } ================================================ FILE: backend.native/tests/runtime/basic/tostring0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.tostring0 import kotlin.test.* @Test fun runTest() { println(127.toByte().toString()) println(255.toByte().toString()) println(239.toShort().toString()) println('A'.toString()) println('Ё'.toString()) println('ト'.toString()) println(1122334455.toString()) println(112233445566778899.toString()) // Here we differ from Java, as have no dtoa() yet. println(3.14159265358.toString()) // Here we differ from Java, as have no dtoa() yet. println(1e27.toFloat().toString()) println(1e7.toString()) println(1e-300.toDouble().toString()) println(true.toString()) println(false.toString()) } ================================================ FILE: backend.native/tests/runtime/basic/tostring1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.tostring1 import kotlin.test.* @Test fun runTest() { val hello = "Hello world" println(hello.subSequence(1, 5).toString()) } ================================================ FILE: backend.native/tests/runtime/basic/tostring2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.tostring2 import kotlin.test.* @Test fun runTest() { val hello = "Hello" val array = hello.toCharArray() for (ch in array) { print(ch) print(" ") } println() println(String(array, 0, array.size)) } ================================================ FILE: backend.native/tests/runtime/basic/tostring3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.tostring3 import kotlin.test.* fun testByte() { val values = ByteArray(2) values[0] = Byte.MIN_VALUE values[1] = Byte.MAX_VALUE for (v in values) { println(v) } } fun testShort() { val values = ShortArray(2) values[0] = Short.MIN_VALUE values[1] = Short.MAX_VALUE for (v in values) { println(v) } } fun testInt() { val values = IntArray(2) values[0] = Int.MIN_VALUE values[1] = Int.MAX_VALUE for (v in values) { println(v) } } fun testLong() { val values = LongArray(2) values[0] = Long.MIN_VALUE values[1] = Long.MAX_VALUE for (v in values) { println(v) } } fun testFloat() { val values = FloatArray(5) values[0] = Float.MIN_VALUE values[1] = Float.MAX_VALUE values[2] = Float.NEGATIVE_INFINITY values[3] = Float.POSITIVE_INFINITY values[4] = Float.NaN for (v in values) { println(v) } } fun testDouble() { val values = DoubleArray(5) values[0] = Double.MIN_VALUE values[1] = Double.MAX_VALUE values[2] = Double.NEGATIVE_INFINITY values[3] = Double.POSITIVE_INFINITY values[4] = Double.NaN for (v in values) { println(v) } } @Test fun runTest() { testByte() testShort() testInt() testLong() testFloat() testDouble() } ================================================ FILE: backend.native/tests/runtime/basic/worker_random.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.basic.worker_random import kotlin.native.concurrent.* import kotlin.collections.* import kotlin.random.* import kotlin.system.* import kotlin.test.* @Test fun testRandomWorkers() { val seed = getTimeMillis() val workers = Array(5, { _ -> Worker.start() }) val attempts = 3 val results = Array(attempts, { ArrayList() } ) for (attempt in 0 until attempts) { // Produce a list of random numbers in each worker val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { workerIndex }) { input -> Array(10, { Random.nextInt() }).toList() } }) // Now collect all results into current attempt's list val futureSet = futures.toSet() var finished = 0 while (finished < futureSet.size) { val ready = waitForMultipleFutures(futureSet, 10000) ready.forEach { results[attempt].addAll(it.result) } finished += ready.size } } workers.forEach { it.requestTermination().result } } ================================================ FILE: backend.native/tests/runtime/collections/AbstractMutableCollection.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.AbstractMutableCollection import kotlin.test.* class TestCollection(): AbstractMutableCollection() { companion object { const val SIZE = 7 } private val array = IntArray(SIZE) private var len = 0 override val size: Int get() = len override fun add(element: Int): Boolean { if (len >= SIZE) return false array[len++] = element return true } override fun iterator(): MutableIterator = object: MutableIterator { var nextIndex = 0 override fun hasNext() = nextIndex < len override fun next() = array[nextIndex++] override fun remove() { if (nextIndex == 0) throw IllegalStateException() for (i in nextIndex..len - 1) { array[i - 1] = array[i] } len-- nextIndex-- } } override fun clear() { len = 0 } } fun assertEquals(a: TestCollection, b: List) { if (a.size != b.size) { throw AssertionError() } val aIt = a.iterator() val bIt = b.iterator() while (aIt.hasNext()) { if (aIt.next() != bIt.next()) throw AssertionError("TestCollection contains wrong elements. Expected: $b, actual: $a.") } } @Test fun runTest() { val c = TestCollection() if (!c.addAll(listOf(1, 2, 3, 2, 4, 5, 4))) throw AssertionError("addAll is false when it must be true.") if (c.addAll(listOf(1, 2)) != false) throw AssertionError("addAll is true when it must be false.") c.removeAll(listOf(1, 2)) assertEquals(c, listOf(3, 4, 5, 4)) c.retainAll(listOf(4, 5)) assertEquals(c, listOf(4, 5, 4)) c.remove(4) assertEquals(c, listOf(5, 4)) c.clear() assertEquals(c, listOf()) } ================================================ FILE: backend.native/tests/runtime/collections/BitSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.BitSet import kotlin.test.* fun assertContainsOnly(bitSet: BitSet, trueBits: Set, size: Int) { for (i in 0 until size) { val expectedBit = i in trueBits if (bitSet[i] != expectedBit) { throw AssertionError() } } } fun assertNotContainsOnly(bitSet: BitSet, falseBits: Set, size: Int) { for (i in 0 until size) { val expectedBit = i !in falseBits if (bitSet[i] != expectedBit) { throw AssertionError() } } } fun assertTrue(str: String, cond: Boolean) { if (!cond) throw AssertionError(str) } fun assertFalse(str: String, cond: Boolean) { if (cond) throw AssertionError(str) } fun assertEquals(str: String, a: T, b: T) { if (a != b) throw AssertionError(str) } fun assertTrue(cond: Boolean) = assertTrue("", cond) fun assertFalse(cond: Boolean) = assertFalse("", cond) fun assertEquals(a: T, b: T) = assertEquals("", a, b) fun fail(): Unit = throw AssertionError() fun testConstructor() { var b = BitSet(12) assertContainsOnly(b, setOf(), 12) b = BitSet(12) { it == 0 || it in 5..6 || it == 11 } assertContainsOnly(b, setOf(0, 5, 6, 11), 12) } fun testSet() { var b = BitSet(0) assertEquals(b.lastTrueIndex, -1) b = BitSet(2) // Test set and clear operation for single index. assertTrue(b.isEmpty) b.set(0, true) b.set(3, true) assertEquals(b.lastTrueIndex, 3) assertFalse(b.isEmpty) assertContainsOnly(b, setOf(0, 3), 4) b.clear() assertContainsOnly(b, setOf(), 4) b.set(1) b.set(5) assertEquals(b.lastTrueIndex, 5) assertContainsOnly(b, setOf(1, 5), 6) b.set(1, false) b.set(7, false) assertEquals(b.lastTrueIndex, 5) assertContainsOnly(b, setOf(5), 8) b.clear(5) assertEquals(b.lastTrueIndex, -1) assertContainsOnly(b, setOf(), 8) b.set(70) assertEquals(b.lastTrueIndex, 70) assertContainsOnly(b, setOf(70), 71) b.clear(70) assertEquals(b.lastTrueIndex, -1) assertContainsOnly(b, setOf(), 71) // Test set and clear operations for ranges. // Set false and clear. b = BitSet(2) assertContainsOnly(b, setOf(), 2) b.set(0..70, true) assertNotContainsOnly(b, setOf(), 71) b.set(0..2, false) assertNotContainsOnly(b, setOf(0, 1, 2), 71) b.set(63..65, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 71) b.set(68..70, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70), 71) b.set(68..72, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70, 71, 72), 73) b.set(0..72, false) assertContainsOnly(b, setOf(), 73) b.set(0..72) assertNotContainsOnly(b, setOf(), 73) b.clear(0..2) assertNotContainsOnly(b, setOf(0, 1, 2), 73) b.clear(63..65) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 73) b.clear(68..70) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70), 73) b.clear(68..72) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70, 71, 72), 73) b.clear(0..72) assertContainsOnly(b, setOf(), 73) // Set true. b.set(0..2, true) assertContainsOnly(b, setOf(0, 1, 2), 73) b.set(63..65, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 73) b.set(70..72, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 70, 71, 72), 73) b.set(73..74, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 70, 71, 72, 73, 74), 75) b.set(0..74, true) assertNotContainsOnly(b, setOf(), 75) // Test set and clear for pair of indices. b = BitSet(2) assertContainsOnly(b, setOf(), 71) b.set(0, 71, true) assertNotContainsOnly(b, setOf(), 71) b.set(0, 3, false) assertNotContainsOnly(b, setOf(0, 1, 2), 71) b.set(63, 66, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 71) b.set(68, 71, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70), 71) b.set(68, 73, false) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70, 71, 72), 73) b.set(0, 73, false) assertContainsOnly(b, setOf(), 73) b.set(0, 73) assertNotContainsOnly(b, setOf(), 73) b.clear(0, 3) assertNotContainsOnly(b, setOf(0, 1, 2), 73) b.clear(63, 66) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 73) b.clear(68, 71) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70), 73) b.clear(68, 73) assertNotContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 68, 69, 70, 71, 72), 73) b.clear(0, 73) assertContainsOnly(b, setOf(), 73) // Set true. b.set(0, 3, true) assertContainsOnly(b, setOf(0, 1, 2), 73) b.set(63, 66, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65), 73) b.set(70, 73, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 70, 71, 72), 73) b.set(73, 75, true) assertContainsOnly(b, setOf(0, 1, 2, 63, 64, 65, 70, 71, 72, 73, 74), 75) b.set(0, 75, true) assertNotContainsOnly(b, setOf(), 75) // Access to negative elements must cause an exception try { b.set(-1) fail() } catch(e: IndexOutOfBoundsException) {} try { b.clear(-1) fail() } catch(e: IndexOutOfBoundsException) {} try { b.clear(-1..0) fail() } catch(e: IndexOutOfBoundsException) {} try { b.set(-1..0) fail() } catch(e: IndexOutOfBoundsException) {} try { b[-1] fail() } catch(e: IndexOutOfBoundsException) {} } fun testFlip() { val b = BitSet(2) b.set(0, true) b.set(70, true) b.set(63..65, true) assertEquals(b.lastTrueIndex, 70) // 0 element assertContainsOnly(b, setOf(0, 63, 64, 65, 70), 71) b.flip(0) assertContainsOnly(b, setOf(63, 64, 65, 70), 71) b.flip(1) assertContainsOnly(b, setOf(1, 63, 64, 65, 70), 71) b.flip(0) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 70), 71) // last element b.flip(70) assertContainsOnly(b, setOf(0, 1, 63, 64, 65), 71) b.flip(69) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69), 71) b.flip(70) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69, 70), 71) // element in the middle b.flip(64) assertContainsOnly(b, setOf(0, 1, 63, 65, 69, 70), 71) b.flip(65) assertContainsOnly(b, setOf(0, 1, 63, 69, 70), 71) b.flip(65) b.flip(64) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69, 70), 71) // range in the beginning b.flip(0..2) assertContainsOnly(b, setOf(2, 63, 64, 65, 69, 70), 71) b.flip(0, 3) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69, 70), 71) // In the end b.flip(68..70) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 68), 71) b.flip(68, 71) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69, 70), 71) // In the middle b.flip(64..66) assertContainsOnly(b, setOf(0, 1, 63, 66, 69, 70), 71) b.flip(64, 67) assertContainsOnly(b, setOf(0, 1, 63, 64, 65, 69, 70), 71) // Access to a negative element must cause an exception. try { b.flip(-1) fail() } catch(e: IndexOutOfBoundsException) {} try { b.flip(-1..0) fail() } catch(e: IndexOutOfBoundsException) {} } fun testNextBit() { val b = BitSet(71) b.set(0) b.set(65) b.set(70) assertEquals(b.nextSetBit(), 0) assertEquals(b.nextSetBit(0), 0) assertEquals(b.nextSetBit(1), 65) assertEquals(b.nextSetBit(65), 65) assertEquals(b.nextSetBit(66), 70) assertEquals(b.nextSetBit(70), 70) assertEquals(b.nextSetBit(71), -1) assertEquals(b.previousSetBit(0), 0) assertEquals(b.previousSetBit(64), 0) assertEquals(b.previousSetBit(65), 65) assertEquals(b.previousSetBit(69), 65) assertEquals(b.previousSetBit(70), 70) assertEquals(b.previousSetBit(71), 70) b.clear() assertEquals(b.nextSetBit(), -1) assertEquals(b.previousSetBit(70), -1) b.set(0..70) assertEquals(b.nextClearBit(), 71) assertEquals(b.previousClearBit(70), -1) b.clear(0) b.clear(65) b.clear(70) assertEquals(b.nextClearBit(), 0) assertEquals(b.nextClearBit(0), 0) assertEquals(b.nextClearBit(1), 65) assertEquals(b.nextClearBit(65), 65) assertEquals(b.nextClearBit(66), 70) assertEquals(b.nextClearBit(70), 70) assertEquals(b.nextClearBit(71), 71) // assume that the bitset is extended here (virtually). assertEquals(b.previousClearBit(0), 0) assertEquals(b.previousClearBit(64), 0) assertEquals(b.previousClearBit(65), 65) assertEquals(b.previousClearBit(69), 65) assertEquals(b.previousClearBit(70), 70) assertEquals(b.previousClearBit(71), 71) // See http://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html#previousClearBit-int- assertEquals(b.previousClearBit(-1), -1) assertEquals(b.previousSetBit(-1), -1) // Test behaviour on the right border of the bit vector. // We assume that the vector is infinite and have zeros after (size - 1)th bit. var a = BitSet(64) assertEquals(a.nextClearBit(63), 63) assertEquals(a.nextClearBit(64), 64) assertEquals(a.nextSetBit(63), -1) assertEquals(a.nextSetBit(64), -1) a.set(0, 64) assertEquals(a.nextClearBit(63), 64) assertEquals(a.nextClearBit(64), 64) assertEquals(a.nextSetBit(63), 63) assertEquals(a.nextSetBit(64), -1) a.clear() assertEquals(a.previousClearBit(63), 63) assertEquals(a.previousClearBit(64), 64) assertEquals(a.previousSetBit(63), -1) assertEquals(a.previousSetBit(64), -1) a.set(0, 64) assertEquals(a.previousClearBit(63), -1) assertEquals(a.previousClearBit(64), 64) assertEquals(a.previousSetBit(63), 63) assertEquals(a.previousSetBit(64), 63) a = BitSet(0) assertEquals(a.nextSetBit(0), -1) assertEquals(a.nextClearBit(0), 0) assertEquals(a.previousSetBit(0), -1) assertEquals(a.previousClearBit(0), 0) // Access to a negative element must cause an exception. try { b.previousSetBit(-2) fail() } catch(e: IndexOutOfBoundsException) {} try { b.previousClearBit(-2) fail() } catch(e: IndexOutOfBoundsException) {} try { b.nextSetBit(-1) fail() } catch(e: IndexOutOfBoundsException) {} try { b.nextClearBit(-1) fail() } catch(e: IndexOutOfBoundsException) {} } fun BitSet.setBits(vararg indices: Int, value: Boolean = true) { indices.forEach { set(it, value) } } fun testLogic() { var b2 = BitSet(76) b2.setBits(1, 3, 61, 63, 65, 67, 70, 72) // and var b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.and(b2) assertContainsOnly(b1, setOf(3, 63, 67, 72), 76) b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.set(128) b1.and(b2) assertContainsOnly(b1, setOf(3, 63, 67, 72), 129) // or b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.or(b2) assertContainsOnly(b1, setOf(1, 2, 3, 61, 62, 63, 65, 66, 67, 70, 71, 72), 76) b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.set(128) b1.or(b2) assertContainsOnly(b1, setOf(1, 2, 3, 61, 62, 63, 65, 66, 67, 70, 71, 72, 128), 129) // xor b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.xor(b2) assertContainsOnly(b1, setOf(1, 2, 61, 62, 65, 66, 70, 71), 76) b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.set(128) b1.xor(b2) assertContainsOnly(b1, setOf(1, 2, 61, 62, 65, 66, 70, 71, 128), 129) // andNot b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.andNot(b2) assertContainsOnly(b1, setOf(2, 62, 66, 71), 76) b1 = BitSet(73) b1.set(2..3); b1.set(62..63); b1.set(66..67); b1.set(71..72) b1.set(128) b1.andNot(b2) assertContainsOnly(b1, setOf(2, 62, 66, 71, 128), 129) // intersects b1 = BitSet(73) b1.set(0..1); b1.set(62..63); b1.set(64..65); b1.set(71..72) b2.clear(); b2.set(0) assertTrue(b1.intersects(b2)) b2.clear(); b2.set(62..65) assertTrue(b1.intersects(b2)) b2.clear(); b2.set(72) assertTrue(b1.intersects(b2)) b2.clear() assertFalse(b1.intersects(b2)) b2.set(128) assertFalse(b1.intersects(b2)) } // Based on Harmony tests. fun testEqualsHashCode() { // HashCode. val b = BitSet() b.set(0..7) b.clear(2) b.clear(6) assertEquals("BitSet returns wrong hash value", 1129, b.hashCode()) b.set(10) b.clear(3) assertEquals("BitSet returns wrong hash value", 97, b.hashCode()) // Equals. val b1 = BitSet() val b2 = BitSet() b1.set(0..7) b2.set(0..7) assertTrue("Same BitSet returned false", b1 == b1) assertTrue("Identical BitSet returned false", b1 == b2) b2.clear(6) assertFalse("Different BitSets returned true", b1 == b2) val b3 = BitSet() b3.set(0..7) b3.set(128) assertFalse("Different sized BitSet with higher bit set returned true", b1 == b3) b3.clear(128) assertTrue("Different sized BitSet with higher bits not set returned false", b1 == b3) } @Test fun runTest() { testConstructor() testSet() testFlip() testNextBit() testLogic() testEqualsHashCode() } ================================================ FILE: backend.native/tests/runtime/collections/SortWith.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.SortWith import kotlin.test.* val correctIncreasing = Comparator { a, b -> // correct one. when { a > b -> 1 a < b -> -1 else -> 0 } } val correctDecreasing = Comparator { a, b -> // correct one. when { a < b -> 1 a > b -> -1 else -> 0 } } fun Array.assertSorted(cmp: Comparator, message: String = "") { for (i in 1 until size) { assertTrue(cmp.compare(this[i - 1], this[i]) <= 0, message) } } fun Array.assertSorted(message: String = "") { for (i in 1 until size) { assertTrue(this[i - 1] <= this[i], message) } } data class ComparatorInfo(val name: String, val comparator: Comparator, val isCorrect: Boolean) class MyComparable (val value: Int, val comparator: Comparator): Comparable { override fun compareTo(other: MyComparable): Int = comparator.compare(value, other.value) } // Assert that the array is sorted in terms of a comparator only for correct/partially correct cases val comparators = listOf( ComparatorInfo("Correct increasing", correctIncreasing , true), ComparatorInfo("Correct decreasing", correctDecreasing , true), ComparatorInfo("Incorrect increasing", Comparator { a ,b -> if (a > b) 1 else -1 }, false), ComparatorInfo("Incorrect decreasing", Comparator { a ,b -> if (a < b) 1 else -1 }, false), ComparatorInfo("Always 1", Comparator { a ,b -> 1 }, false), ComparatorInfo("Always -1", Comparator { a ,b -> -1 }, false), ComparatorInfo("Always 0", Comparator { a ,b -> 0 }, false) ) val arrays = listOf>( arrayOf(), arrayOf(1), arrayOf(Int.MIN_VALUE, 0, Int.MAX_VALUE), arrayOf(Int.MAX_VALUE, 0, Int.MIN_VALUE), arrayOf(1, 2, 3), arrayOf(-2, -1, 99, 1, 2), arrayOf(90, 91, 0, 98, 99), arrayOf(2, 1, 99, -1, 2), arrayOf(99, 98, 0, 91, 90), arrayOf(42, 42, 42), arrayOf(99, 42, 0, 42, 50), arrayOf( 100000, 190001, 200002, 200003, 200004, 210005, 220006, 250007, 300008, 310009, 360010, 365011, 380012, 390013, 390014, 399015, 400016, 400017, 400018, 400019, 400020, 400021, 400022, 400023, 400024, 400025, 400026, 450027, 450028, 480029, 480030, 500031, 500032, 500033, 500034, 500035, 500036, 500037, 500038, 500039, 500040, 500041, 500042, 500043, 500044, 500045, 500046, 500047, 500048, 500049, 500050, 500051, 500052, 500053, 505054, 510055, 510056, 510057, 510058, 510059, 510060, 510061, 510062, 510063, 410064, 410065, 511066, 511067, 520068, 520069, 420070, 520071, 530072, 530073, 530074, 430075, 430076, 530077, 540078, 540079, 540080, 540081, 540082, 540083, 540084, 490085, 540086, 540087, 542088, 544089, 546090, 550091, 550092, 550093, 550094, 590095, 590096, 595097, 600098, 600099, 600100, 600101, 600102, 600103, 600104, 550105, 600106, 600107, 600108, 600109, 600110, 610111, 610112, 610113, 620114, 620115, 620116, 620117, 620118, 620119, 640120, 640121, 645122, 645123, 645124, 645125, 645126, 645127, 650128, 700129, 700130 ) ) @Test fun runTest() { arrays.forEach { array -> comparators.forEach { // Test with custom comparator val arrayUnderTest = array.copyOf() arrayUnderTest.sortWith(it.comparator) if (it.isCorrect) { arrayUnderTest.assertSorted(it.comparator, """ Assert sorted failed for comparator: "${it.name}" Array: ${array.joinToString()} Array after sorting: ${arrayUnderTest.joinToString()} """.trimIndent()) } // Test of a custom comparable val comparableArrayUnderTest = Array(array.size) { i -> MyComparable(array[i], it.comparator) } comparableArrayUnderTest.sort() if (it.isCorrect) { comparableArrayUnderTest.assertSorted(""" Assert sorted failed for Comparable: "${it.name}" Array: ${array.joinToString()} Array after sorting: ${comparableArrayUnderTest.joinToString()} """.trimIndent()) } } } } ================================================ FILE: backend.native/tests/runtime/collections/array0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array0 import kotlin.test.* @Test fun runTest() { // Create instances of all array types. val byteArray = ByteArray(5) println(byteArray.size.toString()) val charArray = CharArray(6) println(charArray.size.toString()) val shortArray = ShortArray(7) println(shortArray.size.toString()) val intArray = IntArray(8) println(intArray.size.toString()) val longArray = LongArray(9) println(longArray.size.toString()) val floatArray = FloatArray(10) println(floatArray.size.toString()) val doubleArray = FloatArray(11) println(doubleArray.size.toString()) val booleanArray = BooleanArray(12) println(booleanArray.size.toString()) val stringArray = Array(13, { i -> ""}) println(stringArray.size.toString()) } ================================================ FILE: backend.native/tests/runtime/collections/array1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array1 import kotlin.test.* @Test fun runTest() { val byteArray = ByteArray(5) byteArray[1] = 2 byteArray[3] = 4 println(byteArray[3].toString() + " " + byteArray[1].toString()) val shortArray = ShortArray(2) shortArray[0] = -1 shortArray[1] = 1 print(shortArray[1].toString()) print(shortArray[0].toString()) println() val intArray = IntArray(7) intArray[1] = 9 intArray[3] = 6 print(intArray[3].toString()) print(intArray[1].toString()) println() val longArray = LongArray(9) longArray[8] = 8 longArray[3] = 3 print(longArray[3].toString()) print(longArray[8].toString()) println() } ================================================ FILE: backend.native/tests/runtime/collections/array2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array2 import kotlin.test.* @Test fun runTest() { val byteArray = Array(5, { i -> (i * 2).toByte() }) byteArray.map { println(it) } val intArray = Array(5, { i -> i * 4 }) println(intArray.sum()) } ================================================ FILE: backend.native/tests/runtime/collections/array3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array3 import kotlin.test.* import kotlin.native.* @Test fun runTest() { val data = immutableBlobOf(0x1, 0x2, 0x3, 0x7, 0x8, 0x9, 0x80, 0xff) for (b in data) { print("$b ") } println() val dataClone = data.toByteArray() dataClone.map { print("$it ") } println() } ================================================ FILE: backend.native/tests/runtime/collections/array4.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array4 import kotlin.test.* @Test fun runTest() { assertFailsWith { val a = Array(-2) { "nope" } println(a) } assertFailsWith { val a = ByteArray(-2) println(a) } assertFailsWith { val a = UByteArray(-2) println(a) } assertFailsWith { val a = ShortArray(-2) println(a) } assertFailsWith { val a = UShortArray(-2) println(a) } assertFailsWith { val a = IntArray(-2) println(a) } assertFailsWith { val a = UIntArray(-2) println(a) } assertFailsWith { val a = LongArray(-2) println(a) } assertFailsWith { val a = ULongArray(-2) println(a) } assertFailsWith { val a = FloatArray(-2) println(a) } assertFailsWith { val a = DoubleArray(-2) println(a) } assertFailsWith { val a = BooleanArray(-2) println(a) } assertFailsWith { val a = CharArray(-2) println(a) } println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/array5.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array5 import kotlin.test.* import kotlinx.cinterop.* @Test fun arrayGet() { val arr = Array(10) { 0 } assertEquals(0, arr[0]) assertEquals(0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun arraySet() { val arr = Array(10) { 0 } arr[0] = 1 arr[9] = 1 assertFailsWith { arr[10] = 1 } assertFailsWith { arr[-1] = 1 } assertFailsWith { arr[Int.MAX_VALUE] = 1 } assertFailsWith { arr[Int.MIN_VALUE] = 1 } } @Test fun byteArrayGet() { val arr = ByteArray(10) { 0 } assertEquals(0, arr[0]) assertEquals(0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun byteArraySet() { val arr = ByteArray(10) { 0 } arr[0] = 1 arr[9] = 1 assertFailsWith { arr[10] = 1 } assertFailsWith { arr[-1] = 1 } assertFailsWith { arr[Int.MAX_VALUE] = 1 } assertFailsWith { arr[Int.MIN_VALUE] = 1 } } @Test fun uByteArrayGet() { val arr = UByteArray(10) { 0U } assertEquals(0U, arr[0]) assertEquals(0U, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun uByteArraySet() { val arr = UByteArray(10) { 0U } arr[0] = 1U arr[9] = 1U assertFailsWith { arr[10] = 1U } assertFailsWith { arr[-1] = 1U } assertFailsWith { arr[Int.MAX_VALUE] = 1U } assertFailsWith { arr[Int.MIN_VALUE] = 1U } } @Test fun shortArrayGet() { val arr = ShortArray(10) { 0 } assertEquals(0, arr[0]) assertEquals(0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun shortArraySet() { val arr = ShortArray(10) { 0 } arr[0] = 1 arr[9] = 1 assertFailsWith { arr[10] = 1 } assertFailsWith { arr[-1] = 1 } assertFailsWith { arr[Int.MAX_VALUE] = 1 } assertFailsWith { arr[Int.MIN_VALUE] = 1 } } @Test fun uShortArrayGet() { val arr = UShortArray(10) { 0U } assertEquals(0U, arr[0]) assertEquals(0U, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun uShortArraySet() { val arr = UShortArray(10) { 0U } arr[0] = 1U arr[9] = 1U assertFailsWith { arr[10] = 1U } assertFailsWith { arr[-1] = 1U } assertFailsWith { arr[Int.MAX_VALUE] = 1U } assertFailsWith { arr[Int.MIN_VALUE] = 1U } } @Test fun intArrayGet() { val arr = IntArray(10) { 0 } assertEquals(0, arr[0]) assertEquals(0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun intArraySet() { val arr = IntArray(10) { 0 } arr[0] = 1 arr[9] = 1 assertFailsWith { arr[10] = 1 } assertFailsWith { arr[-1] = 1 } assertFailsWith { arr[Int.MAX_VALUE] = 1 } assertFailsWith { arr[Int.MIN_VALUE] = 1 } } @Test fun uIntArrayGet() { val arr = UIntArray(10) { 0U } assertEquals(0U, arr[0]) assertEquals(0U, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun uIntArraySet() { val arr = UIntArray(10) { 0U } arr[0] = 1U arr[9] = 1U assertFailsWith { arr[10] = 1U } assertFailsWith { arr[-1] = 1U } assertFailsWith { arr[Int.MAX_VALUE] = 1U } assertFailsWith { arr[Int.MIN_VALUE] = 1U } } @Test fun longArrayGet() { val arr = LongArray(10) { 0 } assertEquals(0, arr[0]) assertEquals(0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun longArraySet() { val arr = LongArray(10) { 0 } arr[0] = 1 arr[9] = 1 assertFailsWith { arr[10] = 1 } assertFailsWith { arr[-1] = 1 } assertFailsWith { arr[Int.MAX_VALUE] = 1 } assertFailsWith { arr[Int.MIN_VALUE] = 1 } } @Test fun uLongArrayGet() { val arr = ULongArray(10) { 0U } assertEquals(0U, arr[0]) assertEquals(0U, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun uLongArraySet() { val arr = ULongArray(10) { 0U } arr[0] = 1U arr[9] = 1U assertFailsWith { arr[10] = 1U } assertFailsWith { arr[-1] = 1U } assertFailsWith { arr[Int.MAX_VALUE] = 1U } assertFailsWith { arr[Int.MIN_VALUE] = 1U } } @Test fun floatArrayGet() { val arr = FloatArray(10) { 0.0f } assertEquals(0.0f, arr[0]) assertEquals(0.0f, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun floatArraySet() { val arr = FloatArray(10) { 0.0f } arr[0] = 1.0f arr[9] = 1.0f assertFailsWith { arr[10] = 1.0f } assertFailsWith { arr[-1] = 1.0f } assertFailsWith { arr[Int.MAX_VALUE] = 1.0f } assertFailsWith { arr[Int.MIN_VALUE] = 1.0f } } @Test fun doubleArrayGet() { val arr = DoubleArray(10) { 0.0 } assertEquals(0.0, arr[0]) assertEquals(0.0, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun doubleArraySet() { val arr = DoubleArray(10) { 0.0 } arr[0] = 1.0 arr[9] = 1.0 assertFailsWith { arr[10] = 1.0 } assertFailsWith { arr[-1] = 1.0 } assertFailsWith { arr[Int.MAX_VALUE] = 1.0 } assertFailsWith { arr[Int.MIN_VALUE] = 1.0 } } @Test fun booleanArrayGet() { val arr = BooleanArray(10) { false } assertEquals(false, arr[0]) assertEquals(false, arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun booleanArraySet() { val arr = BooleanArray(10) { false } arr[0] = true arr[9] = true assertFailsWith { arr[10] = true } assertFailsWith { arr[-1] = true } assertFailsWith { arr[Int.MAX_VALUE] = true } assertFailsWith { arr[Int.MIN_VALUE] = true } } @Test fun charArrayGet() { val arr = CharArray(10) { '0' } assertEquals('0', arr[0]) assertEquals('0', arr[9]) assertFailsWith { arr[10] } assertFailsWith { arr[-1] } assertFailsWith { arr[Int.MAX_VALUE] } assertFailsWith { arr[Int.MIN_VALUE] } } @Test fun charArraySet() { val arr = CharArray(10) { '0' } arr[0] = '1' arr[9] = '1' assertFailsWith { arr[10] = '1' } assertFailsWith { arr[-1] = '1' } assertFailsWith { arr[Int.MAX_VALUE] = '1' } assertFailsWith { arr[Int.MIN_VALUE] = '1' } } @Test fun byteArrayGetUByte() { val arr = ByteArray(10) { 0 } assertEquals(0U, arr.getUByteAt(0)) assertEquals(0U, arr.getUByteAt(9)) assertFailsWith { arr.getUByteAt(10) } assertFailsWith { arr.getUByteAt(-1) } assertFailsWith { arr.getUByteAt(Int.MAX_VALUE) } assertFailsWith { arr.getUByteAt(Int.MIN_VALUE) } } @Test fun byteArraySetUByte() { val arr = ByteArray(10) { 0 } arr.setUByteAt(0, 1U) arr.setUByteAt(9, 1U) assertFailsWith { arr.setUByteAt(10, 1U) } assertFailsWith { arr.setUByteAt(-1, 1U) } assertFailsWith { arr.setUByteAt(Int.MAX_VALUE, 1U) } assertFailsWith { arr.setUByteAt(Int.MIN_VALUE, 1U) } } @Test fun byteArrayGetChar() { val arr = ByteArray(10) { 0 } assertEquals(0.toChar(), arr.getCharAt(0)) assertEquals(0.toChar(), arr.getCharAt(8)) assertFailsWith { arr.getCharAt(9) } assertFailsWith { arr.getCharAt(10) } assertFailsWith { arr.getCharAt(-1) } assertFailsWith { arr.getCharAt(Int.MAX_VALUE) } assertFailsWith { arr.getCharAt(Int.MIN_VALUE) } } @Test fun byteArraySetChar() { val arr = ByteArray(10) { 0 } arr.setCharAt(0, '1') arr.setCharAt(8, '1') assertFailsWith { arr.setCharAt(9, '1') } assertFailsWith { arr.setCharAt(10, '1') } assertFailsWith { arr.setCharAt(-1, '1') } assertFailsWith { arr.setCharAt(Int.MAX_VALUE, '1') } assertFailsWith { arr.setCharAt(Int.MIN_VALUE, '1') } } @Test fun byteArrayGetShort() { val arr = ByteArray(10) { 0 } assertEquals(0, arr.getShortAt(0)) assertEquals(0, arr.getShortAt(8)) assertFailsWith { arr.getShortAt(9) } assertFailsWith { arr.getShortAt(10) } assertFailsWith { arr.getShortAt(-1) } assertFailsWith { arr.getShortAt(Int.MAX_VALUE) } assertFailsWith { arr.getShortAt(Int.MIN_VALUE) } } @Test fun byteArraySetShort() { val arr = ByteArray(10) { 0 } arr.setShortAt(0, 0) arr.setShortAt(8, 0) assertFailsWith { arr.setShortAt(9, 1) } assertFailsWith { arr.setShortAt(10, 1) } assertFailsWith { arr.setShortAt(-1, 1) } assertFailsWith { arr.setShortAt(Int.MAX_VALUE, 1) } assertFailsWith { arr.setShortAt(Int.MIN_VALUE, 1) } } @Test fun byteArrayGetUShort() { val arr = ByteArray(10) { 0 } assertEquals(0U, arr.getUShortAt(0)) assertEquals(0U, arr.getUShortAt(8)) assertFailsWith { arr.getUShortAt(9) } assertFailsWith { arr.getUShortAt(10) } assertFailsWith { arr.getUShortAt(-1) } assertFailsWith { arr.getUShortAt(Int.MAX_VALUE) } assertFailsWith { arr.getUShortAt(Int.MIN_VALUE) } } @Test fun byteArraySetUShort() { val arr = ByteArray(10) { 0 } arr.setUShortAt(0, 0U) arr.setUShortAt(8, 0U) assertFailsWith { arr.setUShortAt(9, 1U) } assertFailsWith { arr.setUShortAt(10, 1U) } assertFailsWith { arr.setUShortAt(-1, 1U) } assertFailsWith { arr.setUShortAt(Int.MAX_VALUE, 1U) } assertFailsWith { arr.setUShortAt(Int.MIN_VALUE, 1U) } } @Test fun byteArrayGetInt() { val arr = ByteArray(10) { 0 } assertEquals(0, arr.getIntAt(0)) assertEquals(0, arr.getIntAt(6)) assertFailsWith { arr.getIntAt(7) } assertFailsWith { arr.getIntAt(10) } assertFailsWith { arr.getIntAt(-1) } assertFailsWith { arr.getIntAt(Int.MAX_VALUE) } assertFailsWith { arr.getIntAt(Int.MIN_VALUE) } } @Test fun byteArraySetInt() { val arr = ByteArray(10) { 0 } arr.setIntAt(0, 1) arr.setIntAt(6, 1) assertFailsWith { arr.setIntAt(7, 1) } assertFailsWith { arr.setIntAt(10, 1) } assertFailsWith { arr.setIntAt(-1, 1) } assertFailsWith { arr.setIntAt(Int.MAX_VALUE, 1) } assertFailsWith { arr.setIntAt(Int.MIN_VALUE, 1) } } @Test fun byteArrayGetUInt() { val arr = ByteArray(10) { 0 } assertEquals(0U, arr.getUIntAt(0)) assertEquals(0U, arr.getUIntAt(6)) assertFailsWith { arr.getUIntAt(7) } assertFailsWith { arr.getUIntAt(10) } assertFailsWith { arr.getUIntAt(-1) } assertFailsWith { arr.getUIntAt(Int.MAX_VALUE) } assertFailsWith { arr.getUIntAt(Int.MIN_VALUE) } } @Test fun byteArraySetUInt() { val arr = ByteArray(10) { 0 } arr.setUIntAt(0, 1U) arr.setUIntAt(6, 1U) assertFailsWith { arr.setUIntAt(7, 1U) } assertFailsWith { arr.setUIntAt(10, 1U) } assertFailsWith { arr.setUIntAt(-1, 1U) } assertFailsWith { arr.setUIntAt(Int.MAX_VALUE, 1U) } assertFailsWith { arr.setUIntAt(Int.MIN_VALUE, 1U) } } @Test fun byteArrayGetLong() { val arr = ByteArray(10) { 0 } assertEquals(0, arr.getLongAt(0)) assertEquals(0, arr.getLongAt(2)) assertFailsWith { arr.getLongAt(3) } assertFailsWith { arr.getLongAt(10) } assertFailsWith { arr.getLongAt(-1) } assertFailsWith { arr.getLongAt(Int.MAX_VALUE) } assertFailsWith { arr.getLongAt(Int.MIN_VALUE) } } @Test fun byteArraySetLong() { val arr = ByteArray(10) { 0 } arr.setLongAt(0, 1) arr.setLongAt(2, 1) assertFailsWith { arr.setLongAt(3, 1) } assertFailsWith { arr.setLongAt(10, 1) } assertFailsWith { arr.setLongAt(-1, 1) } assertFailsWith { arr.setLongAt(Int.MAX_VALUE, 1) } assertFailsWith { arr.setLongAt(Int.MIN_VALUE, 1) } } @Test fun byteArrayGetULong() { val arr = ByteArray(10) { 0 } assertEquals(0U, arr.getULongAt(0)) assertEquals(0U, arr.getULongAt(2)) assertFailsWith { arr.getULongAt(3) } assertFailsWith { arr.getULongAt(10) } assertFailsWith { arr.getULongAt(-1) } assertFailsWith { arr.getULongAt(Int.MAX_VALUE) } assertFailsWith { arr.getULongAt(Int.MIN_VALUE) } } @Test fun byteArraySetULong() { val arr = ByteArray(10) { 0 } arr.setULongAt(0, 1U) arr.setULongAt(2, 1U) assertFailsWith { arr.setULongAt(3, 1U) } assertFailsWith { arr.setULongAt(10, 1U) } assertFailsWith { arr.setULongAt(-1, 1U) } assertFailsWith { arr.setULongAt(Int.MAX_VALUE, 1U) } assertFailsWith { arr.setULongAt(Int.MIN_VALUE, 1U) } } @Test fun byteArrayGetFloat() { val arr = ByteArray(10) { 0 } assertEquals(0.0f, arr.getFloatAt(0)) assertEquals(0.0f, arr.getFloatAt(6)) assertFailsWith { arr.getFloatAt(7) } assertFailsWith { arr.getFloatAt(10) } assertFailsWith { arr.getFloatAt(-1) } assertFailsWith { arr.getFloatAt(Int.MAX_VALUE) } assertFailsWith { arr.getFloatAt(Int.MIN_VALUE) } } @Test fun byteArraySetFloat() { val arr = ByteArray(10) { 0 } arr.setFloatAt(0, 1.0f) arr.setFloatAt(6, 1.0f) assertFailsWith { arr.setFloatAt(7, 1.0f) } assertFailsWith { arr.setFloatAt(10, 1.0f) } assertFailsWith { arr.setFloatAt(-1, 1.0f) } assertFailsWith { arr.setFloatAt(Int.MAX_VALUE, 1.0f) } assertFailsWith { arr.setFloatAt(Int.MIN_VALUE, 1.0f) } } @Test fun byteArrayGetDouble() { val arr = ByteArray(10) { 0 } assertEquals(0.0, arr.getDoubleAt(0)) assertEquals(0.0, arr.getDoubleAt(2)) assertFailsWith { arr.getDoubleAt(3) } assertFailsWith { arr.getDoubleAt(10) } assertFailsWith { arr.getDoubleAt(-1) } assertFailsWith { arr.getDoubleAt(Int.MAX_VALUE) } assertFailsWith { arr.getDoubleAt(Int.MIN_VALUE) } } @Test fun byteArraySetDouble() { val arr = ByteArray(10) { 0 } arr.setDoubleAt(0, 1.0) arr.setDoubleAt(2, 1.0) assertFailsWith { arr.setDoubleAt(3, 1.0) } assertFailsWith { arr.setDoubleAt(10, 1.0) } assertFailsWith { arr.setDoubleAt(-1, 1.0) } assertFailsWith { arr.setDoubleAt(Int.MAX_VALUE, 1.0) } assertFailsWith { arr.setDoubleAt(Int.MIN_VALUE, 1.0) } } @Test fun immutableBlobToByteArray() { val blob = immutableBlobOf(0, 0) val arr = blob.toByteArray(0, 1) assertEquals(1, arr.size) assertEquals(0, arr[0]) assertFailsWith { blob.toByteArray(-1, 1) } assertFailsWith { blob.toByteArray(0, -1) } assertFailsWith { blob.toByteArray(0, 10) } assertFailsWith { blob.toByteArray(10, 11) } assertFailsWith { blob.toByteArray(10, 1) } } @Test fun immutableBlobToUByteArray() { val blob = immutableBlobOf(0, 0) val arr = blob.toUByteArray(0, 1) assertEquals(1, arr.size) assertEquals(0U, arr[0]) assertFailsWith { blob.toUByteArray(-1, 1) } assertFailsWith { blob.toUByteArray(0, -1) } assertFailsWith { blob.toUByteArray(0, 10) } assertFailsWith { blob.toUByteArray(10, 11) } assertFailsWith { blob.toUByteArray(10, 1) } } @Test fun immutableBlobAsCPointer() { val blob = immutableBlobOf(0, 0) assertEquals(0, blob.asCPointer(0).pointed.value) assertFailsWith { blob.asCPointer(10) } assertFailsWith { blob.asCPointer(-1) } assertFailsWith { blob.asCPointer(Int.MAX_VALUE) } assertFailsWith { blob.asCPointer(Int.MIN_VALUE) } } @Test fun immutableBlobAsUCPointer() { val blob = immutableBlobOf(0, 0) assertEquals(0U, blob.asUCPointer(0).pointed.value) assertFailsWith { blob.asUCPointer(10) } assertFailsWith { blob.asUCPointer(-1) } assertFailsWith { blob.asUCPointer(Int.MAX_VALUE) } assertFailsWith { blob.asUCPointer(Int.MIN_VALUE) } } ================================================ FILE: backend.native/tests/runtime/collections/array_list1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array_list1 import kotlin.test.* fun assertTrue(cond: Boolean) { if (!cond) println("FAIL") } fun assertFalse(cond: Boolean) { if (cond) println("FAIL") } fun assertEquals(value1: Any?, value2: Any?) { if (value1 != value2) throw Error("FAIL " + value1 + " " + value2) } fun assertEquals(value1: Int, value2: Int) { if (value1 != value2) throw Error("FAIL " + value1 + " " + value2) } fun testBasic() { val a = ArrayList() assertTrue(a.isEmpty()) assertEquals(0, a.size) assertTrue(a.add("1")) assertTrue(a.add("2")) assertTrue(a.add("3")) assertFalse(a.isEmpty()) assertEquals(3, a.size) assertEquals("1", a[0]) assertEquals("2", a[1]) assertEquals("3", a[2]) a[0] = "11" assertEquals("11", a[0]) assertEquals("11", a.removeAt(0)) assertEquals(2, a.size) assertEquals("2", a[0]) assertEquals("3", a[1]) a.add(1, "22") assertEquals(3, a.size) assertEquals("2", a[0]) assertEquals("22", a[1]) assertEquals("3", a[2]) a.clear() assertTrue(a.isEmpty()) assertEquals(0, a.size) } fun testIterator() { val a = ArrayList(listOf("1", "2", "3")) val it = a.iterator() assertTrue(it.hasNext()) assertEquals("1", it.next()) assertTrue(it.hasNext()) assertEquals("2", it.next()) assertTrue(it.hasNext()) assertEquals("3", it.next()) assertFalse(it.hasNext()) } fun testContainsAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) assertFalse(a.containsAll(listOf("6", "7", "8"))) assertFalse(a.containsAll(listOf("5", "6", "7"))) assertFalse(a.containsAll(listOf("4", "5", "6"))) assertTrue(a.containsAll(listOf("3", "4", "5"))) assertTrue(a.containsAll(listOf("2", "3", "4"))) } fun testRemove() { val a = ArrayList(listOf("1", "2", "3")) assertTrue(a.remove("2")) assertEquals(2, a.size) assertEquals("1", a[0]) assertEquals("3", a[1]) assertFalse(a.remove("2")) assertEquals(2, a.size) assertEquals("1", a[0]) assertEquals("3", a[1]) } fun testRemoveAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "1")) assertFalse(a.removeAll(listOf("6", "7", "8"))) assertEquals(listOf("1", "2", "3", "4", "5", "1"), a) assertTrue(a.removeAll(listOf("5", "3", "1"))) assertEquals(listOf("2", "4"), a) } fun testRetainAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) assertFalse(a.retainAll(listOf("1", "2", "3", "4", "5"))) assertEquals(listOf("1", "2", "3", "4", "5"), a) assertTrue(a.retainAll(listOf("5", "3", "1"))) assertEquals(listOf("1", "3", "5"), a) } fun testEquals() { val a = ArrayList(listOf("1", "2", "3")) assertTrue(a == listOf("1", "2", "3")) assertFalse(a == listOf("2", "3", "1")) // order matters assertFalse(a == listOf("1", "2", "4")) assertFalse(a == listOf("1", "2")) } fun testHashCode() { val a = ArrayList(listOf("1", "2", "3")) assertTrue(a.hashCode() == listOf("1", "2", "3").hashCode()) } fun testToString() { val a = ArrayList(listOf("1", "2", "3")) assertTrue(a.toString() == listOf("1", "2", "3").toString()) } fun testSubList() { val a0 = ArrayList(listOf("0", "1", "2", "3", "4")) val a = a0.subList(1, 4) assertEquals(3, a.size) assertEquals("1", a[0]) assertEquals("2", a[1]) assertEquals("3", a[2]) assertTrue(a == listOf("1", "2", "3")) assertTrue(a.hashCode() == listOf("1", "2", "3").hashCode()) assertTrue(a.toString() == listOf("1", "2", "3").toString()) } fun testResize() { val a = ArrayList() val n = 10000 for (i in 1..n) assertTrue(a.add(i.toString())) assertEquals(n, a.size) for (i in 1..n) assertEquals(i.toString(), a[i - 1]) a.trimToSize() assertEquals(n, a.size) for (i in 1..n) assertEquals(i.toString(), a[i - 1]) } fun testSubListContains() { val a = ArrayList(listOf("1", "2", "3", "4")) val s = a.subList(1, 3) assertTrue(a.contains("1")) assertFalse(s.contains("1")) assertTrue(a.contains("2")) assertTrue(s.contains("2")) assertTrue(a.contains("3")) assertTrue(s.contains("3")) assertTrue(a.contains("4")) assertFalse(s.contains("4")) } fun testSubListIndexOf() { val a = ArrayList(listOf("1", "2", "3", "4", "1")) val s = a.subList(1, 3) assertEquals(0, a.indexOf("1")) assertEquals(-1, s.indexOf("1")) assertEquals(1, a.indexOf("2")) assertEquals(0, s.indexOf("2")) assertEquals(2, a.indexOf("3")) assertEquals(1, s.indexOf("3")) assertEquals(3, a.indexOf("4")) assertEquals(-1, s.indexOf("4")) } fun testSubListLastIndexOf() { val a = ArrayList(listOf("1", "2", "3", "4", "1")) val s = a.subList(1, 3) assertEquals(4, a.lastIndexOf("1")) assertEquals(-1, s.lastIndexOf("1")) assertEquals(1, a.lastIndexOf("2")) assertEquals(0, s.lastIndexOf("2")) assertEquals(2, a.lastIndexOf("3")) assertEquals(1, s.lastIndexOf("3")) assertEquals(3, a.lastIndexOf("4")) assertEquals(-1, s.lastIndexOf("4")) } fun testSubListClear() { val a = ArrayList(listOf("1", "2", "3", "4")) val s = a.subList(1, 3) assertEquals(listOf("2", "3"), s) s.clear() assertEquals(listOf(), s) assertEquals(listOf("1", "4"), a) } fun testSubListSubListClear() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6")) val s = a.subList(1, 5) val q = s.subList(1, 3) assertEquals(listOf("2", "3", "4", "5"), s) assertEquals(listOf("3", "4"), q) q.clear() assertEquals(listOf(), q) assertEquals(listOf("2", "5"), s) assertEquals(listOf("1", "2", "5", "6"), a) } fun testSubListAdd() { val a = ArrayList(listOf("1", "2", "3", "4")) val s = a.subList(1, 3) assertEquals(listOf("2", "3"), s) assertTrue(s.add("5")) assertEquals(listOf("2", "3", "5"), s) assertEquals(listOf("1", "2", "3", "5", "4"), a) } fun testSubListSubListAdd() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6")) val s = a.subList(1, 5) val q = s.subList(1, 3) assertEquals(listOf("2", "3", "4", "5"), s) assertEquals(listOf("3", "4"), q) assertTrue(q.add("7")) assertEquals(listOf("3", "4", "7"), q) assertEquals(listOf("2", "3", "4", "7", "5"), s) assertEquals(listOf("1", "2", "3", "4", "7", "5", "6"), a) } fun testSubListAddAll() { val a = ArrayList(listOf("1", "2", "3", "4")) val s = a.subList(1, 3) assertEquals(listOf("2", "3"), s) assertTrue(s.addAll(listOf("5", "6"))) assertEquals(listOf("2", "3", "5", "6"), s) assertEquals(listOf("1", "2", "3", "5", "6", "4"), a) } fun testSubListSubListAddAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6")) val s = a.subList(1, 5) val q = s.subList(1, 3) assertEquals(listOf("2", "3", "4", "5"), s) assertEquals(listOf("3", "4"), q) assertTrue(q.addAll(listOf("7", "8"))) assertEquals(listOf("3", "4", "7", "8"), q) assertEquals(listOf("2", "3", "4", "7", "8", "5"), s) assertEquals(listOf("1", "2", "3", "4", "7", "8", "5", "6"), a) } fun testSubListRemoveAt() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) val s = a.subList(1, 4) assertEquals(listOf("2", "3", "4"), s) assertEquals("3", s.removeAt(1)) assertEquals(listOf("2", "4"), s) assertEquals(listOf("1", "2", "4", "5"), a) } fun testSubListSubListRemoveAt() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6", "7")) val s = a.subList(1, 6) val q = s.subList(1, 4) assertEquals(listOf("2", "3", "4", "5", "6"), s) assertEquals(listOf("3", "4", "5"), q) assertEquals("4", q.removeAt(1)) assertEquals(listOf("3", "5"), q) assertEquals(listOf("2", "3", "5", "6"), s) assertEquals(listOf("1", "2", "3", "5", "6", "7"), a) } fun testSubListRemoveAll() { val a = ArrayList(listOf("1", "2", "3", "3", "4", "5")) val s = a.subList(1, 5) assertEquals(listOf("2", "3", "3", "4"), s) assertTrue(s.removeAll(listOf("3", "5"))) assertEquals(listOf("2", "4"), s) assertEquals(listOf("1", "2", "4", "5"), a) } fun testSubListSubListRemoveAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6", "7")) val s = a.subList(1, 6) val q = s.subList(1, 4) assertEquals(listOf("2", "3", "4", "5", "6"), s) assertEquals(listOf("3", "4", "5"), q) assertTrue(q.removeAll(listOf("4", "6"))) assertEquals(listOf("3", "5"), q) assertEquals(listOf("2", "3", "5", "6"), s) assertEquals(listOf("1", "2", "3", "5", "6", "7"), a) } fun testSubListRetainAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) val s = a.subList(1, 4) assertEquals(listOf("2", "3", "4"), s) assertTrue(s.retainAll(listOf("5", "3"))) assertEquals(listOf("3"), s) assertEquals(listOf("1", "3", "5"), a) } fun testSubListSubListRetainAll() { val a = ArrayList(listOf("1", "2", "3", "4", "5", "6", "7")) val s = a.subList(1, 6) val q = s.subList(1, 4) assertEquals(listOf("2", "3", "4", "5", "6"), s) assertEquals(listOf("3", "4", "5"), q) assertTrue(q.retainAll(listOf("5", "3"))) assertEquals(listOf("3", "5"), q) assertEquals(listOf("2", "3", "5", "6"), s) assertEquals(listOf("1", "2", "3", "5", "6", "7"), a) } fun testIteratorRemove() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) val it = a.iterator() while (it.hasNext()) if (it.next()[0].toInt() % 2 == 0) it.remove() assertEquals(listOf("1", "3", "5"), a) } fun testIteratorAdd() { val a = ArrayList(listOf("1", "2", "3", "4", "5")) val it = a.listIterator() while (it.hasNext()) { val next = it.next() if (next[0].toInt() % 2 == 0) it.add("-" + next) } assertEquals(listOf("1", "2", "-2", "3", "4", "-4", "5"), a) } @Test fun runTest() { testBasic() testIterator() testRemove() testRemoveAll() testRetainAll() testEquals() testHashCode() testToString() testSubList() testResize() testSubListContains() testSubListIndexOf() testSubListLastIndexOf() testSubListClear() testSubListSubListClear() testSubListAdd() testSubListSubListAdd() testSubListAddAll() testSubListSubListAddAll() testSubListRemoveAt() testSubListSubListRemoveAt() testSubListRemoveAll() testSubListSubListRemoveAll() testSubListSubListRemoveAll() testSubListRetainAll() testSubListSubListRetainAll() testIteratorRemove() testIteratorAdd() println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/array_list2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.array_list2 import kotlin.test.* fun testIteratorNext() { val a = arrayListOf("1", "2", "3", "4", "5") val it = a.listIterator() assertFailsWith { while (true) { it.next() } } } fun testIteratorPrevious() { val a = arrayListOf("1", "2", "3", "4", "5") val it = a.listIterator() it.next() assertFailsWith { while (true) { it.previous() } } } @Test fun runTest() { testIteratorNext() testIteratorPrevious() println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/hash_map0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.hash_map0 import kotlin.test.* fun assertTrue(cond: Boolean) { if (!cond) println("FAIL") } fun assertFalse(cond: Boolean) { if (cond) println("FAIL") } fun assertEquals(value1: Any?, value2: Any?) { if (value1 != value2) println("FAIL") } fun assertNotEquals(value1: Any?, value2: Any?) { if (value1 == value2) println("FAIL") } fun assertEquals(value1: Int, value2: Int) { if (value1 != value2) println("FAIL") } fun testBasic() { val m = HashMap() assertTrue(m.isEmpty()) assertEquals(0, m.size) assertFalse(m.containsKey("1")) assertFalse(m.containsValue("a")) assertEquals(null, m.get("1")) assertEquals(null, m.put("1", "a")) assertTrue(m.containsKey("1")) assertTrue(m.containsValue("a")) assertEquals("a", m.get("1")) assertFalse(m.isEmpty()) assertEquals(1, m.size) assertFalse(m.containsKey("2")) assertFalse(m.containsValue("b")) assertEquals(null, m.get("2")) assertEquals(null, m.put("2", "b")) assertTrue(m.containsKey("1")) assertTrue(m.containsValue("a")) assertEquals("a", m.get("1")) assertTrue(m.containsKey("2")) assertTrue(m.containsValue("b")) assertEquals("b", m.get("2")) assertFalse(m.isEmpty()) assertEquals(2, m.size) assertEquals("b", m.put("2", "bb")) assertTrue(m.containsKey("1")) assertTrue(m.containsValue("a")) assertEquals("a", m.get("1")) assertTrue(m.containsKey("2")) assertTrue(m.containsValue("a")) assertTrue(m.containsValue("bb")) assertEquals("bb", m.get("2")) assertFalse(m.isEmpty()) assertEquals(2, m.size) assertEquals("a", m.remove("1")) assertFalse(m.containsKey("1")) assertFalse(m.containsValue("a")) assertEquals(null, m.get("1")) assertTrue(m.containsKey("2")) assertTrue(m.containsValue("bb")) assertEquals("bb", m.get("2")) assertFalse(m.isEmpty()) assertEquals(1, m.size) assertEquals("bb", m.remove("2")) assertFalse(m.containsKey("1")) assertFalse(m.containsValue("a")) assertEquals(null, m.get("1")) assertFalse(m.containsKey("2")) assertFalse(m.containsValue("bb")) assertEquals(null, m.get("2")) assertTrue(m.isEmpty()) assertEquals(0, m.size) } fun testEquals() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertTrue(m == expected) assertTrue(m == mapOf("b" to "2", "c" to "3", "a" to "1")) // order does not matter assertFalse(m == mapOf("a" to "1", "b" to "2", "c" to "4")) assertFalse(m == mapOf("a" to "1", "b" to "2", "c" to "5")) assertFalse(m == mapOf("a" to "1", "b" to "2")) assertEquals(m.keys, expected.keys) assertEquals(m.values.toList(), expected.values.toList()) assertEquals(m.entries, expected.entries) } fun testHashCode() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertEquals(expected.hashCode(), m.hashCode()) assertEquals(expected.entries.hashCode(), m.entries.hashCode()) assertEquals(expected.keys.hashCode(), m.keys.hashCode()) } fun testToString() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertEquals(expected.toString(), m.toString()) assertEquals(expected.entries.toString(), m.entries.toString()) assertEquals(expected.keys.toString(), m.keys.toString()) assertEquals(expected.values.toString(), m.values.toString()) } fun testPutEntry() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) val e = expected.entries.iterator().next() as MutableMap.MutableEntry assertTrue(m.entries.contains(e)) assertTrue(m.entries.remove(e)) assertTrue(mapOf("b" to "2", "c" to "3") == m) assertEquals(null, m.put(e.key, e.value)) assertTrue(expected == m) assertEquals(e.value, m.put(e.key, e.value)) assertTrue(expected == m) } fun testRemoveAllEntries() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertFalse(m.entries.removeAll(mapOf("a" to "2", "b" to "3", "c" to "4").entries)) assertEquals(expected, m) assertTrue(m.entries.removeAll(mapOf("b" to "22", "c" to "3", "d" to "4").entries)) assertNotEquals(expected, m) assertEquals(mapOf("a" to "1", "b" to "2"), m) } fun testRetainAllEntries() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertFalse(m.entries.retainAll(expected.entries)) assertEquals(expected, m) assertTrue(m.entries.retainAll(mapOf("b" to "22", "c" to "3", "d" to "4").entries)) assertEquals(mapOf("c" to "3"), m) } fun testContainsAllValues() { val m = HashMap(mapOf("a" to "1", "b" to "2", "c" to "3")) assertTrue(m.values.containsAll(listOf("1", "2"))) assertTrue(m.values.containsAll(listOf("1", "2", "3"))) assertFalse(m.values.containsAll(listOf("1", "2", "3", "4"))) assertFalse(m.values.containsAll(listOf("2", "3", "4"))) } fun testRemoveValue() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertFalse(m.values.remove("b")) assertEquals(expected, m) assertTrue(m.values.remove("2")) assertEquals(mapOf("a" to "1", "c" to "3"), m) } fun testRemoveAllValues() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertFalse(m.values.removeAll(listOf("b", "c"))) assertEquals(expected, m) assertTrue(m.values.removeAll(listOf("b", "3"))) assertEquals(mapOf("a" to "1", "b" to "2"), m) } fun testRetainAllValues() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) assertFalse(m.values.retainAll(listOf("1", "2", "3"))) assertEquals(expected, m) assertTrue(m.values.retainAll(listOf("1", "2", "c"))) assertEquals(mapOf("a" to "1", "b" to "2"), m) } fun testEntriesIteratorSet() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) val it = m.iterator() while (it.hasNext()) { val entry = it.next() entry.setValue(entry.value + "!") } assertNotEquals(expected, m) assertEquals(mapOf("a" to "1!", "b" to "2!", "c" to "3!"), m) } @Test fun runTest() { testBasic() testEquals() testHashCode() testToString() testPutEntry() testRemoveAllEntries() testRetainAllEntries() testContainsAllValues() testRemoveValue() testRemoveAllValues() testRetainAllValues() testEntriesIteratorSet() //testDegenerateKeys() println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/hash_map1.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.hash_map1 import kotlin.native.MemoryModel import kotlin.native.Platform import kotlin.native.internal.GC import kotlin.test.* fun assertTrue(cond: Boolean) { if (!cond) println("FAIL") } fun assertFalse(cond: Boolean) { if (cond) println("FAIL") } fun assertEquals(value1: Any?, value2: Any?) { if (value1 != value2) println("FAIL") } fun assertNotEquals(value1: Any?, value2: Any?) { if (value1 == value2) println("FAIL") } fun assertEquals(value1: Int, value2: Int) { if (value1 != value2) println("FAIL") } fun testRehashAndCompact() { val m = HashMap() for (repeat in 1..10) { val n = when (repeat) { 1 -> 1000 2 -> 10000 3 -> 10 else -> 100000 } for (i in 1..n) { assertFalse(m.containsKey(i.toString())) assertEquals(null, m.put(i.toString(), "val$i")) assertTrue(m.containsKey(i.toString())) assertEquals(i, m.size) } for (i in 1..n) { assertTrue(m.containsKey(i.toString())) } for (i in 1..n) { assertEquals("val$i", m.remove(i.toString())) assertFalse(m.containsKey(i.toString())) assertEquals(n - i, m.size) } assertTrue(m.isEmpty()) } } fun testClear() { val m = HashMap() for (repeat in 1..10) { val n = when (repeat) { 1 -> 1000 2 -> 10000 3 -> 10 else -> 100000 } for (i in 1..n) { assertFalse(m.containsKey(i.toString())) assertEquals(null, m.put(i.toString(), "val$i")) assertTrue(m.containsKey(i.toString())) assertEquals(i, m.size) } for (i in 1..n) { assertTrue(m.containsKey(i.toString())) } m.clear() assertEquals(0, m.size) for (i in 1..n) { assertFalse(m.containsKey(i.toString())) } } } @Test fun runTest() { // TODO: Do not manually control this. if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) { GC.threshold = 1000000 GC.thresholdAllocations = 1000000 } testRehashAndCompact() testClear() println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/hash_set0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.hash_set0 import kotlin.test.* fun assertTrue(cond: Boolean) { if (!cond) println("FAIL") } fun assertFalse(cond: Boolean) { if (cond) println("FAIL") } fun assertEquals(value1: Any?, value2: Any?) { if (value1 != value2) println("FAIL") } fun assertEquals(value1: Int, value2: Int) { if (value1 != value2) println("FAIL") } fun testBasic() { val a = HashSet() assertTrue(a.isEmpty()) assertEquals(0, a.size) assertTrue(a.add("1")) assertTrue(a.add("2")) assertTrue(a.add("3")) assertFalse(a.isEmpty()) assertEquals(3, a.size) assertTrue(a.contains("1")) assertTrue(a.contains("2")) assertTrue(a.contains("3")) assertFalse(a.contains("4")) assertTrue(a.remove("1")) assertEquals(2, a.size) assertFalse(a.contains("1")) assertTrue(a.contains("2")) assertTrue(a.contains("3")) assertFalse(a.contains("4")) assertTrue(a.add("4")) assertEquals(3, a.size) assertFalse(a.contains("1")) assertTrue(a.contains("2")) assertTrue(a.contains("3")) assertTrue(a.contains("4")) assertFalse(a.add("4")) assertEquals(3, a.size) assertFalse(a.contains("1")) assertTrue(a.contains("2")) assertTrue(a.contains("3")) assertTrue(a.contains("4")) a.clear() assertTrue(a.isEmpty()) assertEquals(0, a.size) assertFalse(a.contains("1")) assertFalse(a.contains("2")) assertFalse(a.contains("3")) assertFalse(a.contains("4")) } fun testIterator() { val s = HashSet(listOf("1", "2", "3")) val it = s.iterator() assertTrue(it.hasNext()) assertEquals("1", it.next()) assertTrue(it.hasNext()) assertEquals("2", it.next()) assertTrue(it.hasNext()) assertEquals("3", it.next()) assertFalse(it.hasNext()) } fun testEquals() { val s = HashSet(listOf("1", "2", "3")) assertTrue(s == setOf("1", "2", "3")) assertTrue(s == setOf("2", "3", "1")) // order does not matter assertFalse(s == setOf("1", "2", "4")) assertFalse(s == setOf("1", "2")) } fun testHashCode() { val s = HashSet(listOf("1", "2", "3")) assertTrue(s.hashCode() == setOf("1", "2", "3").hashCode()) } fun testToString() { val s = HashSet(listOf("1", "2", "3")) assertTrue(s.toString() == setOf("1", "2", "3").toString()) } fun testContainsAll() { val s = HashSet(listOf("1", "2", "3", "4", "5")) assertFalse(s.containsAll(listOf("6", "7", "8"))) assertFalse(s.containsAll(listOf("5", "6", "7"))) assertFalse(s.containsAll(listOf("4", "5", "6"))) assertTrue(s.containsAll(listOf("3", "4", "5"))) assertTrue(s.containsAll(listOf("2", "3", "4"))) } fun testRemoveAll() { val s = HashSet(listOf("1", "2", "3", "4", "5", "1")) assertFalse(s.removeAll(listOf("6", "7", "8"))) assertEquals(setOf("1", "2", "3", "4", "5", "1"), s) assertTrue(s.removeAll(listOf("5", "3", "1"))) assertEquals(setOf("2", "4"), s) } fun testRetainAll() { val s = HashSet(listOf("1", "2", "3", "4", "5")) assertFalse(s.retainAll(listOf("1", "2", "3", "4", "5"))) assertEquals(setOf("1", "2", "3", "4", "5"), s) assertTrue(s.retainAll(listOf("5", "3", "1"))) assertEquals(setOf("1", "3", "5"), s) } @Test fun runTest() { testBasic() testIterator() testEquals() testHashCode() testToString() testContainsAll() testRemoveAll() testRetainAll() println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/listof0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.listof0 import kotlin.test.* @Test fun runTest() { main(arrayOf("a")) } fun main(args : Array) { val nonConstStr = args[0] val list = arrayListOf(nonConstStr, "b", "c") for (element in list) print(element) println() list.add("d") println(list.toString()) val list2 = listOf("n", "s", nonConstStr) println(list2.toString()) } ================================================ FILE: backend.native/tests/runtime/collections/moderately_large_array.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.moderately_large_array import kotlin.test.* @Test fun runTest() { val a = ByteArray(1000000) var sum = 0 for (b in a) { sum += b } println(sum) } ================================================ FILE: backend.native/tests/runtime/collections/moderately_large_array1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.moderately_large_array1 import kotlin.test.* @Test fun runTest() { val a = Array(100000, { i -> i.toByte()}) var sum = 0 for (b in a) { sum += b } println(sum) } ================================================ FILE: backend.native/tests/runtime/collections/range0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.range0 import kotlin.test.* @Test fun runTest() { for (i in 1..3) print(i) println() for (i in 'a'..'d') print(i) println() } ================================================ FILE: backend.native/tests/runtime/collections/sort0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.sort0 import kotlin.test.* @Test fun runTest() { println(arrayOf("x", "a", "b").sorted().toString()) println(intArrayOf(239, 42, -1, 100500, 0).sorted().toString()); } ================================================ FILE: backend.native/tests/runtime/collections/sort1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.sort1 import kotlin.test.* @Test fun runTest() { val foo = mutableListOf("x", "a", "b") foo.sort() println(foo.toString()) var bar = mutableListOf(239, 42, -1, 100500, 0) bar.sort() println(bar.toString()) } ================================================ FILE: backend.native/tests/runtime/collections/stack_array.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.stack_array import kotlin.test.* @Test fun runTest() { val array = IntArray(2) array[0] = 1 array[1] = 2 val check = array is IntArray println(check) println(array[0] + array[1]) } ================================================ FILE: backend.native/tests/runtime/collections/typed_array0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.typed_array0 import kotlin.test.* @Test fun runTest() { // Those tests assume little endian bit ordering. val array = ByteArray(42) array.setLongAt(5, 0x1234_5678_9abc_def0) expect(0x1234_5678_9abc_def0) { array.getLongAt(5) } expect(0xdef0.toInt()) { array.getCharAt(5).toInt() } expect(0x9abc.toShort()) { array.getShortAt(7) } expect(0x1234_5678) { array.getIntAt(9) } expect(0xdef0_0000u) { array.getUIntAt(3) } expect(0xf0_00u) { array.getUShortAt(4) } expect(0xf0u) { array.getUByteAt(5) } expect(0x1234_5678_9abcuL) { array.getULongAt(7) } array.setIntAt(2, 0x40100000) expect(2.25f) { array.getFloatAt(2) } array.setLongAt(11, 0x400c_0000_0000_0000) expect(3.5) { array.getDoubleAt(11) } println("OK") } ================================================ FILE: backend.native/tests/runtime/collections/typed_array1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.collections.typed_array1 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest() { val array = ByteArray(17) val results = mutableSetOf() var counter = 0 assertFailsWith { results += array.getShortAt(16) } assertFailsWith { results += array.getCharAt(22) } assertFailsWith { results += array.getIntAt(15) } assertFailsWith { results += array.getLongAt(14) } assertFailsWith { results += array.getFloatAt(14) } assertFailsWith { results += array.getDoubleAt(13) } assertFailsWith { array.setShortAt(16, 2.toShort()) } assertFailsWith { array.setCharAt(22, 'a') } assertFailsWith { array.setIntAt(15, 1234) } assertFailsWith { array.setLongAt(14, 1.toLong()) } assertFailsWith { array.setFloatAt(14, 1.0f) } assertFailsWith { array.setDoubleAt(13, 3.0) } expect(0) { results.size } array.freeze() assertFailsWith { array.setShortAt(0, 2.toShort()) } assertFailsWith { array.setCharAt(0, 'a') } assertFailsWith { array.setIntAt(0, 2) } assertFailsWith { array.setLongAt(0, 2) } assertFailsWith { array.setFloatAt(0, 1.0f) } assertFailsWith { array.setDoubleAt(0, 1.0) } println("OK") } ================================================ FILE: backend.native/tests/runtime/concurrent/worker_bound_reference0.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.concurrent.worker_bound_reference0 import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.GC import kotlin.native.ref.WeakReference import kotlin.text.Regex class A(var a: Int) @SharedImmutable val global1: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobal() { assertEquals(3, global1.value.a) assertEquals(3, global1.valueOrNull?.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { global1 } val value = future.result assertEquals(3, value.value.a) assertEquals(3, value.valueOrNull?.a) worker.requestTermination().result } @SharedImmutable val global2: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobalDenyAccessOnWorker() { assertEquals(3, global2.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { val local = global2 assertFailsWith { local.value } assertEquals(null, local.valueOrNull) Unit } future.result worker.requestTermination().result } @SharedImmutable val global3: WorkerBoundReference = WorkerBoundReference(A(3).freeze()) @Test fun testGlobalAccessOnWorkerFrozenInitially() { assertEquals(3, global3.value.a) assertEquals(3, global3.valueOrNull?.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { global3.value.a } val value = future.result assertEquals(3, value) worker.requestTermination().result } @SharedImmutable val global4: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobalAccessOnWorkerFrozenBeforePassing() { assertEquals(3, global4.value.a) global4.value.freeze() val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { global4.value.a } val value = future.result assertEquals(3, value) worker.requestTermination().result } @SharedImmutable val global5: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobalAccessOnWorkerFrozenBeforeAccess() { val semaphore: AtomicInt = AtomicInt(0) assertEquals(3, global5.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { semaphore }) { semaphore -> semaphore.increment() while (semaphore.value < 2) { } global5.value.a } while (semaphore.value < 1) { } global5.value.freeze() semaphore.increment() val value = future.result assertEquals(3, value) worker.requestTermination().result } @SharedImmutable val global6: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobalModification() { val semaphore: AtomicInt = AtomicInt(0) assertEquals(3, global6.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { semaphore }) { semaphore -> semaphore.increment() while (semaphore.value < 2) { } global6 } while (semaphore.value < 1) { } global6.value.a = 4 semaphore.increment() val value = future.result assertEquals(4, value.value.a) assertEquals(4, value.valueOrNull?.a) worker.requestTermination().result } @SharedImmutable val global7: WorkerBoundReference = WorkerBoundReference(A(3)) @Test fun testGlobalGetWorker() { val ownerId = Worker.current.id assertEquals(ownerId, global7.worker.id) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { ownerId }) { ownerId -> assertEquals(ownerId, global7.worker.id) Unit } future.result worker.requestTermination().result } @Test fun testLocal() { val local = WorkerBoundReference(A(3)) assertEquals(3, local.value.a) assertEquals(3, local.valueOrNull?.a) } @Test fun testLocalFrozen() { val local = WorkerBoundReference(A(3)).freeze() assertEquals(3, local.value.a) assertEquals(3, local.valueOrNull?.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> local } val value = future.result assertEquals(3, value.value.a) assertEquals(3, value.valueOrNull?.a) worker.requestTermination().result } @Test fun testLocalDenyAccessOnWorkerFrozen() { val local = WorkerBoundReference(A(3)).freeze() assertEquals(3, local.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> assertFailsWith { local.value } assertEquals(null, local.valueOrNull) Unit } future.result worker.requestTermination().result } @Test fun testLocalAccessOnWorkerFrozenInitiallyFrozen() { val local = WorkerBoundReference(A(3).freeze()).freeze() assertEquals(3, local.value.a) assertEquals(3, local.valueOrNull?.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> local.value.a } val value = future.result assertEquals(3, value) worker.requestTermination().result } @Test fun testLocalAccessOnWorkerFrozenBeforePassingFrozen() { val local = WorkerBoundReference(A(3)).freeze() assertEquals(3, local.value.a) local.value.freeze() val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> local.value.a } val value = future.result assertEquals(3, value) worker.requestTermination().result } @Test fun testLocalAccessOnWorkerFrozenBeforeAccessFrozen() { val semaphore: AtomicInt = AtomicInt(0) val local = WorkerBoundReference(A(3)).freeze() assertEquals(3, local.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { Pair(local, semaphore) }) { (local, semaphore) -> semaphore.increment() while (semaphore.value < 2) { } local.value.a } while (semaphore.value < 1) { } local.value.freeze() semaphore.increment() val value = future.result assertEquals(3, value) worker.requestTermination().result } @Test fun testLocalAccessOnMainThread() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { WorkerBoundReference(A(3)) } assertEquals(3, future.result.value.a) worker.requestTermination().result } @Test fun testLocalDenyAccessOnMainThreadFrozen() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { WorkerBoundReference(A(3)).freeze() } val value = future.result assertFailsWith { value.value } assertEquals(null, value.valueOrNull) worker.requestTermination().result } @Test fun testLocalModificationFrozen() { val semaphore: AtomicInt = AtomicInt(0) val local = WorkerBoundReference(A(3)).freeze() assertEquals(3, local.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { Pair(local, semaphore) }) { (local, semaphore) -> semaphore.increment() while (semaphore.value < 2) { } local } while (semaphore.value < 1) { } local.value.a = 4 semaphore.increment() val value = future.result assertEquals(4, value.value.a) assertEquals(4, value.valueOrNull?.a) worker.requestTermination().result } @Test fun testLocalGetWorkerFrozen() { val local = WorkerBoundReference(A(3)).freeze() val ownerId = Worker.current.id assertEquals(ownerId, local.worker.id) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { Pair(local, ownerId) }) { (local, ownerId) -> assertEquals(ownerId, local.worker.id) Unit } future.result worker.requestTermination().result } @Test fun testLocalForeignGetWorker() { val worker = Worker.start() val ownerId = worker.id val future = worker.execute(TransferMode.SAFE, { ownerId }) { ownerId -> val local = WorkerBoundReference(A(3)) assertEquals(ownerId, local.worker.id) local } val value = future.result assertEquals(ownerId, value.worker.id) worker.requestTermination().result } @Test fun testLocalForeignGetWorkerFrozen() { val worker = Worker.start() val ownerId = worker.id val future = worker.execute(TransferMode.SAFE, { ownerId }) { ownerId -> val local = WorkerBoundReference(A(3)).freeze() assertEquals(ownerId, local.worker.id) local } val value = future.result assertEquals(ownerId, value.worker.id) worker.requestTermination().result } class Wrapper(val ref: WorkerBoundReference) @Test fun testLocalWithWrapperFrozen() { val local = Wrapper(WorkerBoundReference(A(3))).freeze() assertEquals(3, local.ref.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> local } val value = future.result assertEquals(3, value.ref.value.a) worker.requestTermination().result } @Test fun testLocalDenyAccessWithWrapperFrozen() { val local = Wrapper(WorkerBoundReference(A(3))).freeze() assertEquals(3, local.ref.value.a) val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { local }) { local -> assertFailsWith { local.ref.value } assertEquals(null, local.ref.valueOrNull) Unit } future.result worker.requestTermination().result } fun getOwnerAndWeaks(initial: Int): Triple?>, WeakReference>, WeakReference> { val ref = WorkerBoundReference(A(initial)) val refOwner: FreezableAtomicReference?> = FreezableAtomicReference(ref) val refWeak = WeakReference(ref) val refValueWeak = WeakReference(ref.value) return Triple(refOwner, refWeak, refValueWeak) } @Test fun testCollect() { val (refOwner, refWeak, refValueWeak) = getOwnerAndWeaks(3) refOwner.value = null GC.collect() // Last reference to WorkerBoundReference is gone, so it and it's referent are destroyed. assertNull(refWeak.value) assertNull(refValueWeak.value) } fun getOwnerAndWeaksFrozen(initial: Int): Triple?>, WeakReference>, WeakReference> { val ref = WorkerBoundReference(A(initial)).freeze() val refOwner: AtomicReference?> = AtomicReference(ref) val refWeak = WeakReference(ref) val refValueWeak = WeakReference(ref.value) return Triple(refOwner, refWeak, refValueWeak) } @Test fun testCollectFrozen() { val (refOwner, refWeak, refValueWeak) = getOwnerAndWeaksFrozen(3) refOwner.value = null GC.collect() // Last reference to WorkerBoundReference is gone, so it and it's referent are destroyed. assertNull(refWeak.value) assertNull(refValueWeak.value) } fun collectInWorkerFrozen(worker: Worker, semaphore: AtomicInt): Pair, Future> { val (refOwner, _, refValueWeak) = getOwnerAndWeaksFrozen(3) val future = worker.execute(TransferMode.SAFE, { Pair(refOwner, semaphore) }) { (refOwner, semaphore) -> semaphore.increment() while (semaphore.value < 2) { } refOwner.value = null GC.collect() } while (semaphore.value < 1) { } // At this point worker is spinning on semaphore. refOwner still contains reference to // WorkerBoundReference, so referent is kept alive. GC.collect() assertNotNull(refValueWeak.value) return Pair(refValueWeak, future) } @Test fun testCollectInWorkerFrozen() { val semaphore: AtomicInt = AtomicInt(0) val worker = Worker.start() val (refValueWeak, future) = collectInWorkerFrozen(worker, semaphore) semaphore.increment() future.result // At this point WorkerBoundReference no longer has a reference, so it's referent is destroyed. GC.collect() assertNull(refValueWeak.value) worker.requestTermination().result } fun doNotCollectInWorkerFrozen(worker: Worker, semaphore: AtomicInt): Future> { val ref = WorkerBoundReference(A(3)).freeze() return worker.execute(TransferMode.SAFE, { Pair(ref, semaphore) }) { (ref, semaphore) -> semaphore.increment() while (semaphore.value < 2) { } GC.collect() ref } } @Test fun testDoNotCollectInWorkerFrozen() { val semaphore: AtomicInt = AtomicInt(0) val worker = Worker.start() val future = doNotCollectInWorkerFrozen(worker, semaphore) while (semaphore.value < 1) { } GC.collect() semaphore.increment() val value = future.result assertEquals(3, value.value.a) worker.requestTermination().result } class B1 { lateinit var b2: WorkerBoundReference } data class B2(val b1: WorkerBoundReference) fun createCyclicGarbage(): Triple?>, WeakReference, WeakReference> { val ref1 = WorkerBoundReference(B1()) val ref1Owner: FreezableAtomicReference?> = FreezableAtomicReference(ref1) val ref1Weak = WeakReference(ref1.value) val ref2 = WorkerBoundReference(B2(ref1)) val ref2Weak = WeakReference(ref2.value) ref1.value.b2 = ref2 return Triple(ref1Owner, ref1Weak, ref2Weak) } @Test fun collectCyclicGarbage() { val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbage() ref1Owner.value = null GC.collect() assertNull(ref1Weak.value) assertNull(ref2Weak.value) } fun createCyclicGarbageFrozen(): Triple?>, WeakReference, WeakReference> { val ref1 = WorkerBoundReference(B1()).freeze() val ref1Owner: AtomicReference?> = AtomicReference(ref1) val ref1Weak = WeakReference(ref1.value) val ref2 = WorkerBoundReference(B2(ref1)).freeze() val ref2Weak = WeakReference(ref2.value) ref1.value.b2 = ref2 return Triple(ref1Owner, ref1Weak, ref2Weak) } @Test fun doesNotCollectCyclicGarbageFrozen() { val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageFrozen() ref1Owner.value = null GC.collect() // If these asserts fail, that means WorkerBoundReference managed to clean up cyclic garbage all by itself. assertNotNull(ref1Weak.value) assertNotNull(ref2Weak.value) } fun createCrossThreadCyclicGarbageFrozen( worker: Worker ): Triple?>, WeakReference, WeakReference> { val ref1 = WorkerBoundReference(B1()).freeze() val ref1Owner: AtomicReference?> = AtomicReference(ref1) val ref1Weak = WeakReference(ref1.value) val future = worker.execute(TransferMode.SAFE, { ref1 }) { ref1 -> val ref2 = WorkerBoundReference(B2(ref1)).freeze() Pair(ref2, WeakReference(ref2.value)) } val (ref2, ref2Weak) = future.result ref1.value.b2 = ref2 return Triple(ref1Owner, ref1Weak, ref2Weak) } @Test fun doesNotCollectCrossThreadCyclicGarbageFrozen() { val worker = Worker.start() val (ref1Owner, ref1Weak, ref2Weak) = createCrossThreadCyclicGarbageFrozen(worker) ref1Owner.value = null GC.collect() worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result // If these asserts fail, that means WorkerBoundReference managed to clean up cyclic garbage all by itself. assertNotNull(ref1Weak.value) assertNotNull(ref2Weak.value) worker.requestTermination().result } class C1 { lateinit var c2: AtomicReference?> fun dispose() { c2.value = null } } data class C2(val c1: AtomicReference>) fun createCyclicGarbageWithAtomicsFrozen(): Triple?>, WeakReference, WeakReference> { val ref1 = WorkerBoundReference(C1()).freeze() val ref1Weak = WeakReference(ref1.value) val ref2 = WorkerBoundReference(C2(AtomicReference(ref1))).freeze() val ref2Weak = WeakReference(ref2.value) ref1.value.c2 = AtomicReference(ref2) return Triple(AtomicReference(ref1), ref1Weak, ref2Weak) } fun dispose(refOwner: AtomicReference?>) { refOwner.value!!.value.dispose() refOwner.value = null } @Test fun doesNotCollectCyclicGarbageWithAtomicsFrozen() { val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageWithAtomicsFrozen() ref1Owner.value = null GC.collect() // If these asserts fail, that means AtomicReference managed to clean up cyclic garbage all by itself. assertNotNull(ref1Weak.value) assertNotNull(ref2Weak.value) } @Test fun collectCyclicGarbageWithAtomicsFrozen() { val (ref1Owner, ref1Weak, ref2Weak) = createCyclicGarbageWithAtomicsFrozen() dispose(ref1Owner) GC.collect() assertNull(ref1Weak.value) assertNull(ref2Weak.value) } fun createCrossThreadCyclicGarbageWithAtomicsFrozen( worker: Worker ): Triple?>, WeakReference, WeakReference> { val ref1 = WorkerBoundReference(C1()).freeze() val ref1Weak = WeakReference(ref1.value) val future = worker.execute(TransferMode.SAFE, { ref1 }) { ref1 -> val ref2 = WorkerBoundReference(C2(AtomicReference(ref1))).freeze() Pair(ref2, WeakReference(ref2.value)) } val (ref2, ref2Weak) = future.result ref1.value.c2 = AtomicReference(ref2) return Triple(AtomicReference(ref1), ref1Weak, ref2Weak) } @Test fun doesNotCollectCrossThreadCyclicGarbageWithAtomicsFrozen() { val worker = Worker.start() val (ref1Owner, ref1Weak, ref2Weak) = createCrossThreadCyclicGarbageWithAtomicsFrozen(worker) ref1Owner.value = null GC.collect() worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result // If these asserts fail, that means AtomicReference managed to clean up cyclic garbage all by itself. assertNotNull(ref1Weak.value) assertNotNull(ref2Weak.value) worker.requestTermination().result } @Test fun collectCrossThreadCyclicGarbageWithAtomicsFrozen() { val worker = Worker.start() val (ref1Owner, ref1Weak, ref2Weak) = createCrossThreadCyclicGarbageWithAtomicsFrozen(worker) dispose(ref1Owner) // This marks C2 as gone on the main thread GC.collect() // This cleans up all the references from the worker thread and destroys C2, but C1 is still alive. worker.execute(TransferMode.SAFE, {}) { GC.collect() }.result // And this finally destroys C1 GC.collect() assertNull(ref1Weak.value) assertNull(ref2Weak.value) worker.requestTermination().result } @Test fun concurrentAccessFrozen() { val workerCount = 10 val workerUnlocker = AtomicInt(0) val ref = WorkerBoundReference(A(3)).freeze() assertEquals(3, ref.value.a) val workers = Array(workerCount) { Worker.start() } val futures = Array(workers.size) { workers[it].execute(TransferMode.SAFE, { Pair(ref, workerUnlocker) }) { (ref, workerUnlocker) -> while (workerUnlocker.value < 1) { } assertFailsWith { ref.value } Unit } } workerUnlocker.increment() for (future in futures) { future.result } for (worker in workers) { worker.requestTermination().result } } @Test fun testExceptionMessageFrozen() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { WorkerBoundReference(A(3)).freeze() } val value = future.result val ownerName = worker.name val messagePattern = Regex("illegal attempt to access non-shared runtime\\.concurrent\\.worker_bound_reference0\\.A@[a-f0-9]+ bound to `$ownerName` from `${Worker.current.name}`") val exception = assertFailsWith { value.value } assertTrue(messagePattern matches exception.message!!) worker.requestTermination().result } @Test fun testDoubleFreeze() { val ref = WorkerBoundReference(A(3)) val wrapper = Wrapper(ref) ref.freeze() ref.freeze() wrapper.freeze() } @Test fun testDoubleFreezeWithFreezeBlocker() { val ref = WorkerBoundReference(A(3)) val wrapper = Wrapper(ref) wrapper.ensureNeverFrozen() assertFailsWith { wrapper.freeze() } ref.freeze() } ================================================ FILE: backend.native/tests/runtime/exceptions/catch1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.catch1 import kotlin.test.* @Test fun runTest() { try { println("Before") foo() println("After") } catch (e: Throwable) { println("Caught Throwable") } println("Done") } fun foo() { throw Error("Error happens") println("After in foo()") } ================================================ FILE: backend.native/tests/runtime/exceptions/catch2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.catch2 import kotlin.test.* @Test fun runTest() { try { println("Before") foo() println("After") } catch (e: Exception) { println("Caught Exception") } catch (e: Error) { println("Caught Error") } catch (e: Throwable) { println("Caught Throwable") } println("Done") } fun foo() { throw Error("Error happens") println("After in foo()") } ================================================ FILE: backend.native/tests/runtime/exceptions/catch7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.catch7 import kotlin.test.* @Test fun runTest() { try { foo() } catch (e: Throwable) { val message = e.message if (message != null) { println(message) } } } fun foo() { throw Error("Error happens") } ================================================ FILE: backend.native/tests/runtime/exceptions/check_stacktrace_format.kt ================================================ // Checks that on Apple targets first two lines of exception stacktrace of symbolized executable looks like // "\tat 1 main.kexe\t\t 0x000000010d7cdb4c kfun:package.function(kotlin.Int) + 108 (/path/to/file/name.kt:10:27)\n" // If test is broken, org.jetbrains.kotlin.idea.filters.KotlinExceptionFilter (in main Kotlin repo) should be updated. import kotlin.test.* import kotlin.text.Regex val EXTENSION = ".kt:" val LOCATION_PATTERN = Regex("\\d+:\\d+") fun checkStringFormat(s: String) { val trimmed = s.trim() assertTrue(trimmed.endsWith(')'), "Line is not ended with ')'") assertNotEquals(trimmed.indexOf('('), -1, "No '(' before filename") val fileName = trimmed.substring(trimmed.lastIndexOf('(') + 1, trimmed.lastIndex) assertNotEquals(fileName.indexOf(EXTENSION), -1, "Filename 'kt' extension is absent") val location = fileName.substring(fileName.indexOf(EXTENSION) + EXTENSION.length) assertTrue(LOCATION_PATTERN.matches(location), "Expected location of form 12:8") } fun functionA() { throw Error("an error") } fun functionB() { functionA() } const val depth = 5 fun main(args : Array) { try { functionB() } catch (e: Throwable) { val stacktrace = e.getStackTrace() assert(stacktrace.size >= depth) stacktrace.take(depth).forEach(::checkStringFormat) } } ================================================ FILE: backend.native/tests/runtime/exceptions/custom_hook.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlin.native.concurrent.* fun main(args : Array) { assertFailsWith { setUnhandledExceptionHook { _ -> println("wrong") } } val x = 42 val old = setUnhandledExceptionHook({ throwable: Throwable -> println("value $x: ${throwable::class.simpleName}") }.freeze()) assertNull(old) throw Error("an error") } ================================================ FILE: backend.native/tests/runtime/exceptions/exception_in_global_init.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* val p: Nothing = error("FAIL") fun main() { println("in kotlin main") } ================================================ FILE: backend.native/tests/runtime/exceptions/extend0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.extend0 import kotlin.test.* class C : Exception("OK") @Test fun runTest() { try { throw C() } catch (e: Throwable) { println(e.message!!) } } ================================================ FILE: backend.native/tests/runtime/exceptions/kt-37572.kt ================================================ import kotlin.text.Regex import kotlin.test.* fun main() { try { foo() } catch (tw:Throwable) { val stackTrace = tw.getStackTrace() stackTrace.take(6).forEach(::checkFrame) } } fun foo() { myRun { //platform.darwin.NSObject() throwException() } } inline fun myRun(block: () -> Unit) { block() } fun throwException() { throw Error() } internal val regex = Regex("^(\\d+)\\ +.*/(.*):(\\d+):.*$") internal val goldValues = arrayOf?>( null, null, "kt-37572.kt" to 25, "kt-37572.kt" to 16, "kt-37572.kt" to 6, "kt-37572.kt" to 4) internal fun checkFrame(value:String) { val (pos, file, line) = regex.find(value)!!.destructured goldValues[pos.toInt()]?.let{ assertEquals(it.first, file) assertEquals(it.second, line.toInt()) } } ================================================ FILE: backend.native/tests/runtime/exceptions/rethrow.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.rethtow import kotlin.test.* @Test fun runTest() { assertFailsWith("My error") { try { error("My error") } catch (e: Throwable) { throw e } } } ================================================ FILE: backend.native/tests/runtime/exceptions/stack_trace_inline.kt ================================================ import kotlin.text.Regex import kotlin.test.* fun exception() { error("FAIL!") } fun main() { try { exception() } catch (e:Exception) { val stackTrace = e.getStackTrace() stackTrace.take(6).forEach(::checkFrame) } } internal val regex = Regex("^(\\d+)\\ +.*/(.*):(\\d+):.*$") internal val goldValues = arrayOf?>( null, null, null, null, "stack_trace_inline.kt" to 5, "stack_trace_inline.kt" to 10) internal fun checkFrame(value:String) { val (pos, file, line) = regex.find(value)!!.destructured goldValues[pos.toInt()]?.let{ assertEquals(it.first, file) assertEquals(it.second, line.toInt()) } } ================================================ FILE: backend.native/tests/runtime/exceptions/throw_from_catch.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.exceptions.throw_from_catch import kotlin.test.* @Test fun runTest() { assertFailsWith("My another error") { try { error("My error") } catch (e: Throwable) { error("My another error") } } } ================================================ FILE: backend.native/tests/runtime/memory/basic0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.basic0 import kotlin.test.* class A { var field: B? = null } class B(var field: Int) @Test fun runTest() { val a = A() a.field = B(2) } ================================================ FILE: backend.native/tests/runtime/memory/cycle_collector.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.internal.GC import kotlin.native.Platform import kotlin.test.* fun test1() { val a = AtomicReference(null) val b = AtomicReference(null) a.value = b b.value = a } class Holder(var other: Any?) fun test2() { val array = arrayOf(AtomicReference(null), AtomicReference(null)) val obj1 = Holder(array).freeze() array[0].value = obj1 } fun test3() { val a1 = FreezableAtomicReference(null) val head = Holder(null) var current = head repeat(30) { val next = Holder(null) current.other = next current = next } a1.value = head current.other = a1 current.freeze() } fun makeIt(): Holder { val atomic = AtomicReference(null) val holder = Holder(atomic).freeze() atomic.value = holder return holder } fun test4() { val holder = makeIt() // To clean rc count coming from rememberNewContainer(). kotlin.native.internal.GC.collect() // Request cyclic collection. kotlin.native.internal.GC.collectCyclic() // Ensure we processed delayed release. repeat(10) { // Wait a bit and process queue. Worker.current.park(10) Worker.current.processQueue() kotlin.native.internal.GC.collect() } val value = @Suppress("UNCHECKED_CAST") (holder.other as? AtomicReference?) assertTrue(value != null) assertTrue(value.value == holder) } fun createRef(): AtomicReference { val atomic1 = AtomicReference(null) val atomic2 = AtomicReference(null) atomic1.value = atomic2 atomic2.value = atomic1 return atomic1 } class Holder2(var value: AtomicReference) { fun switch() { value = value.value as AtomicReference } } fun createHolder2() = Holder2(createRef()) fun test5() { val holder = createHolder2() kotlin.native.internal.GC.collect() kotlin.native.internal.GC.collectCyclic() Worker.current.park(100 * 1000) holder.switch() kotlin.native.internal.GC.collect() Worker.current.park(100 * 1000) withWorker { executeAfter(0L, { kotlin.native.internal.GC.collect() }.freeze()) } Worker.current.park(1000) assertTrue(holder.value.value != null) } fun test6() { val atomic = AtomicReference(null) atomic.value = Pair(atomic, Holder(atomic)).freeze() } fun createRoot(): AtomicReference { val ref1 = AtomicReference(null) val ref2 = AtomicReference(null) ref1.value = Holder(ref2).freeze() ref2.value = Any().freeze() return ref1 } fun test7() { val ref1 = createRoot() kotlin.native.internal.GC.collect() kotlin.native.internal.GC.collectCyclic() Worker.current.park(500 * 1000L) withWorker { executeAfter(0L, {}.freeze()) Worker.current.park(500 * 1000L) val node = ref1.value as Holder val ref2 = node.other as AtomicReference assertTrue(ref2.value != null) } } fun array(size: Int) = Array(size, { null }) fun test8() { val ref = AtomicReference(null) val obj1 = array(2) val obj2 = array(1) val obj3 = array(2) obj1[0] = obj2 obj1[1] = obj3 obj2[0] = obj3 obj3[0] = obj2 obj3[1] = ref ref.value = obj1.freeze() } fun createNode1(): Holder { val ref = AtomicReference(null) val node2 = Holder(ref) val node1 = Holder(node2) ref.value = node1.freeze() return node1 } fun getNode2(): Holder { val node1 = createNode1() GC.collect() return node1.other as Holder } fun test9() { withWorker { val node2 = getNode2() executeAfter(10 * 1000L, { GC.collectCyclic() }.freeze()) GC.collect() Worker.current.park(50 * 1000L) execute(TransferMode.SAFE, {}, {}).result val ref = node2.other as AtomicReference assertTrue(ref.value != null) } } fun main() { Platform.isMemoryLeakCheckerActive = true kotlin.native.internal.GC.cyclicCollectorEnabled = true test1() test2() test3() test4() repeat(10) { test5() } test6() test7() test8() test9() } ================================================ FILE: backend.native/tests/runtime/memory/cycle_collector_deadlock1.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.internal.GC import kotlin.test.* fun main() { kotlin.native.internal.GC.cyclicCollectorEnabled = true repeat(10000) { // Create atomic cyclic garbage: val ref = AtomicReference(null) ref.value = ref } // main thread will then run cycle collector termination, which involves running it and cleaning everything up. // 10000 references should hit [kGcThreshold] then. } ================================================ FILE: backend.native/tests/runtime/memory/cycle_detector.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.internal.GC import kotlin.native.Platform import kotlin.test.* class Holder(var other: Any?) class Holder2(var field1: Any?, var field2: Any?) val Array.description: String get() { val result = StringBuilder() result.append('[') for (elem in this) { result.append(elem.toString()) result.append(',') } result.append(']') return result.toString() } fun assertArrayEquals( expected: Array, actual: Array ): Unit { val lazyMessage: () -> String? = { "Expected <${expected.description}>, actual <${actual.description}>." } asserter.assertTrue(lazyMessage, expected.size == actual.size) for (i in expected.indices) { asserter.assertTrue(lazyMessage, expected[i] == actual[i]) } } @BeforeTest fun enableMemoryChecker() { Platform.isMemoryLeakCheckerActive = true } @Test fun noCycles() { val atomic1 = AtomicReference(null) val atomic2 = AtomicReference(null) try { atomic1.value = atomic2 val cycles = GC.detectCycles()!! assertEquals(0, cycles.size) assertNull(GC.findCycle(atomic1)); assertNull(GC.findCycle(atomic2)); } finally { atomic1.value = null atomic2.value = null } } @Test fun oneCycle() { val atomic = AtomicReference(null) try { atomic.value = atomic val cycles = GC.detectCycles()!! assertEquals(1, cycles.size) assertArrayEquals(arrayOf(atomic, atomic), GC.findCycle(cycles[0])!!) } finally { atomic.value = null } } @Test fun oneCycleWithHolder() { val atomic = AtomicReference(null) try { atomic.value = Holder(atomic).freeze() val cycles = GC.detectCycles()!! assertEquals(1, cycles.size) assertArrayEquals(arrayOf(atomic, atomic.value!!, atomic), GC.findCycle(cycles[0])!!) assertArrayEquals(arrayOf(atomic.value!!, atomic, atomic.value!!), GC.findCycle(atomic.value!!)!!) } finally { atomic.value = null } } @Test fun oneCycleWithArray() { val array = arrayOf(AtomicReference(null), AtomicReference(null)) try { array[0].value = Holder(array).freeze() val cycles = GC.detectCycles()!! assertEquals(1, cycles.size) assertArrayEquals(arrayOf(array[0], array[0].value!!, array, array[0]), GC.findCycle(cycles[0])!!) } finally { array[0].value = null array[1].value = null } } @Test fun oneCycleWithLongChain() { val atomic = AtomicReference(null) try { val head = Holder(null) var current = head repeat(30) { val next = Holder(null) current.other = next current = next } current.other = atomic atomic.value = head.freeze() val cycles = GC.detectCycles()!! assertEquals(1, cycles.size) val cycle = GC.findCycle(cycles[0])!! assertEquals(33, cycle.size) } finally { atomic.value = null } } @Test fun twoCycles() { val atomic1 = AtomicReference(null) val atomic2 = AtomicReference(null) try { atomic1.value = atomic2 atomic2.value = atomic1 val cycles = GC.detectCycles()!! assertEquals(2, cycles.size) assertArrayEquals(arrayOf(atomic2, atomic1, atomic2), GC.findCycle(cycles[0])!!) assertArrayEquals(arrayOf(atomic1, atomic2, atomic1), GC.findCycle(cycles[1])!!) } finally { atomic1.value = null atomic2.value = null } } @Test fun twoCyclesWithHolder() { val atomic1 = AtomicReference(null) val atomic2 = AtomicReference(null) try { atomic1.value = atomic2 atomic2.value = Holder(atomic1).freeze() val cycles = GC.detectCycles()!! assertEquals(2, cycles.size) assertArrayEquals(arrayOf(atomic2, atomic2.value!!, atomic1, atomic2), GC.findCycle(cycles[0])!!) assertArrayEquals(arrayOf(atomic1, atomic2, atomic2.value!!, atomic1), GC.findCycle(cycles[1])!!) } finally { atomic1.value = null atomic2.value = null } } @Test fun threeSeparateCycles() { val atomic1 = AtomicReference(null) val atomic2 = AtomicReference(null) val atomic3 = AtomicReference(null) try { atomic1.value = atomic1 atomic2.value = Holder2(atomic1, atomic2).freeze() atomic3.value = Holder2(atomic3, atomic1).freeze() val cycles = GC.detectCycles()!! assertEquals(3, cycles.size) assertArrayEquals(arrayOf(atomic3, atomic3.value!!, atomic3), GC.findCycle(cycles[0])!!) assertArrayEquals(arrayOf(atomic2, atomic2.value!!, atomic2), GC.findCycle(cycles[1])!!) assertArrayEquals(arrayOf(atomic1, atomic1), GC.findCycle(cycles[2])!!) } finally { atomic1.value = null atomic2.value = null atomic3.value = null } } @Test fun noCyclesWithFreezableAtomicReference() { val atomic = FreezableAtomicReference(null) try { atomic.value = atomic val cycles = GC.detectCycles()!! assertEquals(0, cycles.size) } finally { atomic.value = null } } @Test fun oneCycleWithFrozenFreezableAtomicReference() { val atomic = FreezableAtomicReference(null) try { atomic.value = atomic atomic.freeze() val cycles = GC.detectCycles()!! assertEquals(1, cycles.size) assertArrayEquals(arrayOf(atomic, atomic), GC.findCycle(cycles[0])!!) } finally { atomic.value = null } } ================================================ FILE: backend.native/tests/runtime/memory/cycles0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.cycles0 import kotlin.test.* data class Node(val data: Int, var next: Node?, var prev: Node?, val outer: Node?) fun makeCycle(len: Int, outer: Node?): Node { val start = Node(0, null, null, outer) var prev = start for (i in 1 .. len - 1) { prev = Node(i, prev, null, outer) } start.next = prev return start } fun makeDoubleCycle(len: Int): Node { val start = makeCycle(len, null) var prev = start var cur = prev.next while (cur != start) { cur!!.prev = prev prev = cur cur = cur.next } start.prev = prev return start } fun createCycles(junk: Node) { val cycle1 = makeCycle(1, junk) val cycle2 = makeCycle(2, junk) val cycle10 = makeCycle(10, junk) val cycle100 = makeCycle(100, junk) val dcycle1 = makeDoubleCycle(1) val dcycle2 = makeDoubleCycle(2) val dcycle10 = makeDoubleCycle(10) val dcycle100 = makeDoubleCycle(100) } @Test fun runTest() { // Create outer link from cyclic garbage. val outer = Node(42, null, null, null) createCycles(outer) kotlin.native.internal.GC.collect() // Ensure outer is not collected. println(outer.data) } ================================================ FILE: backend.native/tests/runtime/memory/cycles1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.cycles1 import kotlin.test.* import kotlin.native.ref.* @Test fun runTest() { // TODO: make it work in relaxed model as well. if (Platform.memoryModel == MemoryModel.RELAXED) return val weakRefToTrashCycle = createLoop() kotlin.native.internal.GC.collect() assertNull(weakRefToTrashCycle.get()) } private fun createLoop(): WeakReference { val loop = Array(1, { null }) loop[0] = loop return WeakReference(loop) } ================================================ FILE: backend.native/tests/runtime/memory/escape0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.escape0 import kotlin.test.* //fun foo1(arg: String) : String = foo0(arg) fun foo1(arg: Any) : Any = foo0(arg) fun foo0(arg: Any) : Any = Any() var global : Any = Any() fun foo0_escape(arg: Any) : Any{ global = arg return Any() } class Node(var previous: Node?) fun zoo3() : Node { var current = Node(null) for (i in 1 .. 5) { current = Node(current) } return current } fun zoo4(arg: Int) : Any { var a = Any() var b = Any() var c = Any() a = b val x = 3 a = when { x < arg -> b else -> c } return a } fun zoo5(arg: Any) : Any{ foo1(arg) return arg } fun zoo6(arg: Any) : Any { return zoo7(arg, "foo", 11) } fun zoo7(arg1: Any, arg2: Any, selector: Int) : Any { return if (selector < 2) arg1 else arg2; } @Test fun runTest() { //val z = zoo7(Any(), Any(), 1) val x = zoo5(Any()) //println(bar(foo1(foo2("")), foo2(foo1("")))) } ================================================ FILE: backend.native/tests/runtime/memory/escape1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.escape1 import kotlin.test.* class B(val s: String) class A { val b = B("zzz") } fun foo(): B { val a = A() return a.b } @Test fun runTest() { println(foo().s) } ================================================ FILE: backend.native/tests/runtime/memory/escape2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.escape2 import kotlin.test.* class A(val s: String) class B { var a: A? = null } class C(val b: B) fun foo(c: C) { c.b.a = A("zzz") } fun bar(b: B) { val c = C(b) foo(c) } @ThreadLocal val global = B() @Test fun runTest() { bar(global) println(global.a!!.s) } ================================================ FILE: backend.native/tests/runtime/memory/leak_memory.kt ================================================ import kotlinx.cinterop.* import kotlin.native.Platform fun main() { Platform.isMemoryLeakCheckerActive = true StableRef.create(Any()) } ================================================ FILE: backend.native/tests/runtime/memory/leak_memory_test_runner.kt ================================================ import kotlin.test.* import kotlinx.cinterop.* import kotlin.native.Platform @BeforeTest fun enableMemoryChecker() { Platform.isMemoryLeakCheckerActive = true } @Test fun test() { StableRef.create(Any()) } ================================================ FILE: backend.native/tests/runtime/memory/only_gc.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { kotlin.native.internal.GC.collect() } ================================================ FILE: backend.native/tests/runtime/memory/stable_ref_cross_thread_check.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.stable_ref_cross_thread_check import kotlin.test.* import kotlin.native.concurrent.* import kotlinx.cinterop.* @Test fun runTest1() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { }) { StableRef.create(Any()) } val ref = future.result assertFailsWith { val value = ref.get() println(value.toString()) } worker.requestTermination().result } @Test fun runTest2() { val worker = Worker.start() val mainThreadRef = StableRef.create(Any()) // Simulate this going through interop as raw C pointer. val pointerValue: Long = mainThreadRef.asCPointer().toLong() val future = worker.execute(TransferMode.SAFE, { pointerValue }) { val pointer: COpaquePointer = it.toCPointer()!! assertFailsWith { // Even attempting to convert a pointer to StableRef should fail. val otherThreadRef: StableRef = pointer.asStableRef() println(otherThreadRef.toString()) } Unit } future.result worker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/memory/throw_cleanup.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.throw_cleanup import kotlin.test.* @Test fun runTest() { foo(false) try { foo(true) } catch (e: Error) { println("Ok") } } fun foo(b: Boolean): Any { var result = Any() if (b) { throw Error() } return result } ================================================ FILE: backend.native/tests/runtime/memory/var1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.var1 import kotlin.test.* class Integer(val value: Int) { operator fun inc() = Integer(value + 1) } fun foo(x: Any, y: Any) { x.use() y.use() } @Test fun runTest1() { var x = Integer(0) for (i in 0..1) { val c = Integer(0) if (i == 0) x = c } // x refcount is 1. foo(x, ++x) } fun Any?.use() { var x = this } @kotlin.native.internal.CanBePrecreated object CompileTime { const val int = Int.MIN_VALUE const val byte = Byte.MIN_VALUE const val short = Short.MIN_VALUE const val long = Long.MIN_VALUE const val boolean = true const val float = 1.0f const val double = 1.0 const val char = Char.MIN_VALUE } class AClass { companion object {} } @Test fun runTest2() { assertEquals(Int.MIN_VALUE, CompileTime.int) assertEquals(Byte.MIN_VALUE, CompileTime.byte) assertEquals(Short.MIN_VALUE, CompileTime.short) assertEquals(Long.MIN_VALUE, CompileTime.long) assertEquals(true, CompileTime.boolean) assertEquals(1.0f, CompileTime.float) assertEquals(1.0, CompileTime.double) assertEquals(Char.MIN_VALUE, CompileTime.char) } ================================================ FILE: backend.native/tests/runtime/memory/var2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.var2 import kotlin.test.* @Test fun runTest() { var x = Any() for (i in 0..1) { val c = Any() if (i == 0) x = c } // x refcount is 1. val y = try { x } finally { x = Any() } y.use() } fun Any?.use() { var x = this } ================================================ FILE: backend.native/tests/runtime/memory/var3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.var3 import kotlin.test.* @Test fun runTest() { foo().use() } fun foo(): Any { var x = Any() for (i in 0..1) { val c = Any() if (i == 0) x = c } // x refcount is 1. try { return x } finally { x = Any() } } fun Any?.use() { var x = this } ================================================ FILE: backend.native/tests/runtime/memory/var4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.var4 import kotlin.test.* @Test fun runTest() { var x = Error() for (i in 0..1) { val c = Error() if (i == 0) x = c } // x refcount is 1. try { try { throw x } finally { x = Error() } } catch (e: Error) { e.use() } } fun Any?.use() { var x = this } ================================================ FILE: backend.native/tests/runtime/memory/weak0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.weak0 import kotlin.test.* import kotlin.native.ref.* data class Data(val s: String) fun localWeak(): WeakReference { val x = Data("Hello") val weak = WeakReference(x) println(weak.get()) return weak } fun multiWeak(): Array> { val x = Data("Hello") val weaks = Array(100, { WeakReference(x) } ) weaks.forEach { it -> if (it.get()?.s != "Hello") throw Error("bad reference") } return weaks } @Test fun runTest() { val weak = localWeak() kotlin.native.internal.GC.collect() val value = weak.get() println(value?.toString()) val weaks = multiWeak() kotlin.native.internal.GC.collect() weaks.forEach { it -> if (it.get()?.s != null) throw Error("not null") } println("OK") } ================================================ FILE: backend.native/tests/runtime/memory/weak1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.memory.weak1 import kotlin.test.* import kotlin.native.ref.* class Node(var next: Node?) @Test fun runTest1() { val node1 = Node(null) val node2 = Node(node1) node1.next = node2 kotlin.native.ref.WeakReference(node1) println("OK") } @Test fun runTest2() { val string = "Hello" val refString = WeakReference(string) assertEquals(string, refString.value) val zero = 0 val refZero = WeakReference(zero) assertEquals(0, refZero.value) val long = Long.MAX_VALUE val refLong = WeakReference(long) assertEquals(Long.MAX_VALUE, refLong.value) } ================================================ FILE: backend.native/tests/runtime/text/chars0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.chars0 import kotlin.test.* fun assertTrue(v: Boolean) = if (!v) throw AssertionError() else Unit fun assertFalse(v: Boolean) = if (v) throw AssertionError() else Unit fun assertEquals(a: Int, b: Int) { if (a != b) throw AssertionError() } fun testIsSupplementaryCodePoint() { assertFalse(Char.isSupplementaryCodePoint(-1)) for (c in 0..0xFFFF) { assertFalse(Char.isSupplementaryCodePoint(c.toInt())) } for (c in 0xFFFF + 1..0x10FFFF) { assertTrue(Char.isSupplementaryCodePoint(c)) } assertFalse(Char.isSupplementaryCodePoint(0x10FFFF + 1)) } fun testIsSurrogatePair() { assertFalse(Char.isSurrogatePair('\u0000', '\u0000')) assertFalse(Char.isSurrogatePair('\u0000', '\uDC00')) assertTrue( Char.isSurrogatePair('\uD800', '\uDC00')) assertTrue( Char.isSurrogatePair('\uD800', '\uDFFF')) assertTrue( Char.isSurrogatePair('\uDBFF', '\uDFFF')) assertFalse(Char.isSurrogatePair('\uDBFF', '\uF000')) } fun testToChars() { assertTrue(charArrayOf('\uD800', '\uDC00').contentEquals(Char.toChars(0x010000))) assertTrue(charArrayOf('\uD800', '\uDC01').contentEquals(Char.toChars(0x010001))) assertTrue(charArrayOf('\uD801', '\uDC01').contentEquals(Char.toChars(0x010401))) assertTrue(charArrayOf('\uDBFF', '\uDFFF').contentEquals(Char.toChars(0x10FFFF))) try { Char.toChars(Int.MAX_VALUE) throw AssertionError() } catch (e: IllegalArgumentException) {} } fun testToCodePoint() { assertEquals(0x010000, Char.toCodePoint('\uD800', '\uDC00')) assertEquals(0x010001, Char.toCodePoint('\uD800', '\uDC01')) assertEquals(0x010401, Char.toCodePoint('\uD801', '\uDC01')) assertEquals(0x10FFFF, Char.toCodePoint('\uDBFF', '\uDFFF')) } // TODO: Uncomment when such operations are supported for supplementary codepoints and the API is public. fun testCase() { /* assertEquals('A'.toInt(), Char.toUpperCase('a'.toInt())) assertEquals('A'.toInt(), Char.toUpperCase('A'.toInt())) assertEquals('1'.toInt(), Char.toUpperCase('1'.toInt())) assertEquals('a'.toInt(), Char.toLowerCase('A'.toInt())) assertEquals('a'.toInt(), Char.toLowerCase('a'.toInt())) assertEquals('1'.toInt(), Char.toLowerCase('1'.toInt())) assertEquals(0x010400, Char.toUpperCase(0x010428)) assertEquals(0x010400, Char.toUpperCase(0x010400)) assertEquals(0x10FFFF, Char.toUpperCase(0x10FFFF)) assertEquals(0x110000, Char.toUpperCase(0x110000)) assertEquals(0x010428, Char.toLowerCase(0x010400)) assertEquals(0x010428, Char.toLowerCase(0x010428)) assertEquals(0x10FFFF, Char.toLowerCase(0x10FFFF)) assertEquals(0x110000, Char.toLowerCase(0x110000)) */ } fun testCategory() { assertEquals('\n'.category.value, CharCategory.CONTROL.value) assertEquals('1'.category.value, CharCategory.DECIMAL_DIGIT_NUMBER.value) assertEquals(' '.category.value, CharCategory.SPACE_SEPARATOR.value) assertEquals('a'.category.value, CharCategory.LOWERCASE_LETTER.value) assertEquals('A'.category.value, CharCategory.UPPERCASE_LETTER.value) assertEquals('<'.category.value, CharCategory.MATH_SYMBOL.value) assertEquals(';'.category.value, CharCategory.OTHER_PUNCTUATION.value) assertEquals('_'.category.value, CharCategory.CONNECTOR_PUNCTUATION.value) assertEquals('$'.category.value, CharCategory.CURRENCY_SYMBOL.value) assertEquals('\u2029'.category.value, CharCategory.PARAGRAPH_SEPARATOR.value) assertTrue('\n' in CharCategory.CONTROL) assertTrue('1' in CharCategory.DECIMAL_DIGIT_NUMBER) assertTrue(' ' in CharCategory.SPACE_SEPARATOR) assertTrue('a' in CharCategory.LOWERCASE_LETTER) assertTrue('A' in CharCategory.UPPERCASE_LETTER) assertTrue('<' in CharCategory.MATH_SYMBOL) assertTrue(';' in CharCategory.OTHER_PUNCTUATION) assertTrue('_' in CharCategory.CONNECTOR_PUNCTUATION) assertTrue('$' in CharCategory.CURRENCY_SYMBOL) assertTrue('\u2029' in CharCategory.PARAGRAPH_SEPARATOR) try { CharCategory.valueOf(-1) throw AssertionError() } catch (e: IllegalArgumentException) {} try { CharCategory.valueOf(31) throw AssertionError() } catch (e: IllegalArgumentException) {} try { CharCategory.valueOf(17) throw AssertionError() } catch (e: IllegalArgumentException) {} } @Test fun runTest() { testIsSurrogatePair() testToChars() testToCodePoint() testIsSupplementaryCodePoint() testCase() testCategory() } ================================================ FILE: backend.native/tests/runtime/text/indexof.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.indexof import kotlin.test.* @Test fun runTest() { var str = "Hello World!!" // for indexOf String var ch = 'a' // for indexOf Char assertEquals(6, str.indexOf("World", 0)) assertEquals(6, str.indexOf("World", -1)) assertEquals(-1, str.indexOf(ch, 0)) str = "Kotlin/Native" assertEquals(-1, str.indexOf("/", str.length + 1)) assertEquals(-1, str.indexOf("/", Int.MAX_VALUE)) assertEquals(str.length, str.indexOf("", Int.MAX_VALUE)) assertEquals(1, str.indexOf("", 1)) assertEquals(8, str.indexOf(ch, 1)) assertEquals(-1, str.indexOf(ch, str.length - 1)) str = "" assertEquals(-1, str.indexOf("a", -3)) assertEquals(0, str.indexOf("", 0)) assertEquals(-1, str.indexOf(ch, -3)) assertEquals(-1, str.indexOf(ch, 10)) ch = 0.toChar() assertEquals(-1, str.indexOf(ch, -3)) assertEquals(-1, str.indexOf(ch, 10)) } ================================================ FILE: backend.native/tests/runtime/text/parse0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.parse0 import kotlin.test.* @Test fun runTest() { println("false".toBoolean()) println("true".toBoolean()) println("-1".toByte()) println("a".toByte(16)) println("aa".toShort(16)) println("11110".toInt(2)) println("ffffffff".toLong(16)) try { val x = "ffffffff".toLong(10) } catch (ne: NumberFormatException) { println("bad format") } println("0.5".toFloat()) println("2.39".toDouble()) } ================================================ FILE: backend.native/tests/runtime/text/string0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.string0 import kotlin.test.* @Test fun runTest() { val str = "hello" println(str.equals("HElLo", true)) val strI18n = "Привет" println(strI18n.equals("прИВет", true)) println(strI18n.toUpperCase()) println(strI18n.toLowerCase()) println("пока".capitalize()) println("http://jetbrains.com".startsWith("http://")) } ================================================ FILE: backend.native/tests/runtime/text/string_builder0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.string_builder0 import kotlin.test.* // Utils ==================================================================================================== fun assertTrue(cond: Boolean) { if (!cond) throw AssertionError("Condition expected to be true") } fun assertFalse(cond: Boolean) { if (cond) throw AssertionError("Condition expected to be false") } fun assertEquals(value1: String, value2: String) { if (value1 != value2) throw AssertionError("FAIL: '" + value1 + "' != '" + value2 + "'") } fun assertEquals(value1: Int, value2: Int) { if (value1 != value2) throw AssertionError("FAIL" + value1.toString() + " != " + value2.toString()) } fun assertEquals(builder: StringBuilder, content: String) = assertEquals(builder.toString(), content) // IndexOutOfBoundsException. fun assertException(body: () -> Unit) { try { body() throw AssertionError ("Test failed: no IndexOutOfBoundsException on wrong indices") } catch (e: IndexOutOfBoundsException) { } catch (e: IllegalArgumentException) {} } // Insert =================================================================================================== fun testInsertString(initial: String, index: Int, toInsert: String, expected: String) { assertEquals(StringBuilder(initial).insert(index, toInsert), expected) assertEquals(StringBuilder(initial).insert(index, toInsert.toCharArray()), expected) assertEquals(StringBuilder(initial).insert(index, toInsert as CharSequence), expected) } fun testInsertStringException(initial: String, index: Int, toInsert: String) { assertException { StringBuilder(initial).insert(index, toInsert) } assertException { StringBuilder(initial).insert(index, toInsert.toCharArray()) } assertException { StringBuilder(initial).insert(index, toInsert as CharSequence) } } fun testInsertSingle(value: Byte) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Short) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Int) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Long) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Float) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Double) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Any?) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsertSingle(value: Char) { assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd") assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString()) assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd") assertEquals(StringBuilder("").insert(0, value), value.toString()) } fun testInsert() { // String/CharSequence/CharArray. testInsertString("abcd", 0, "12", "12abcd") testInsertString("abcd", 4, "12", "abcd12") testInsertString("abcd", 2, "12", "ab12cd") testInsertString("", 0, "12", "12") testInsertStringException("a", -1, "1") testInsertStringException("a", 2, "1") // Null inserting. assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?), "nullabcd") assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?), "abcdnull") assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?), "abnullcd") assertEquals(StringBuilder("").insert(0, null as CharSequence?), "null") // Subsequence of CharSequence. // Insert in the beginning. assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 0), "abcd") // 0 symbols assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 1), "1abcd") // 1 symbol assertEquals(StringBuilder("abcd").insert(0, "1234", 1, 3), "23abcd") // 2 symbols assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?, 1, 3), "ulabcd") // 2 symbols of null // Insert in the end. assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 0), "abcd") assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 1), "abcd1") assertEquals(StringBuilder("abcd").insert(4, "1234", 1, 3), "abcd23") assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?, 1, 3), "abcdul") // Insert in the middle. assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 0), "abcd") assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 1), "ab1cd") assertEquals(StringBuilder("abcd").insert(2, "1234", 1, 3), "ab23cd") assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?, 1, 3), "abulcd") // Incorrect indices. assertException { StringBuilder("a").insert(-1, "1", 0, 0) } assertException { StringBuilder("a").insert(2, "1", 0, 0) } assertException { StringBuilder("a").insert(1, "1", -1, 0) } assertException { StringBuilder("a").insert(1, "1", 0, 2) } assertException { StringBuilder("a").insert(1, "123", 2, 0) } // Other types. testInsertSingle(true) testInsertSingle(42.toByte()) testInsertSingle(42.toShort()) testInsertSingle(42.toInt()) testInsertSingle(42.toLong()) testInsertSingle(42.2.toFloat()) testInsertSingle(42.2.toDouble()) testInsertSingle(object { override fun toString(): String { return "Object" } }) testInsertSingle('a') } // Reverse ================================================================================================== fun testReverse(original: String, reversed: String, reversedBack: String) { assertEquals(StringBuilder(original).reverse(), reversed) assertEquals(StringBuilder(reversed).reverse(), reversedBack) } fun testReverse() { var builder = StringBuilder("123456") assertTrue(builder === builder.reverse()) assertEquals(builder, "654321") builder.setLength(1) assertEquals(builder, "6") builder.setLength(0) assertEquals(builder, "") var str: String = "a" testReverse(str, str, str) str = "ab" testReverse(str, "ba", str) str = "abcdef" testReverse(str, "fedcba", str) str = "abcdefg" testReverse(str, "gfedcba", str) str = "\ud800\udc00" testReverse(str, str, str) str = "\udc00\ud800" testReverse(str, "\ud800\udc00", "\ud800\udc00") str = "a\ud800\udc00" testReverse(str, "\ud800\udc00a", str) str = "ab\ud800\udc00" testReverse(str, "\ud800\udc00ba", str) str = "abc\ud800\udc00" testReverse(str, "\ud800\udc00cba", str) str = "\ud800\udc00\udc01\ud801\ud802\udc02" testReverse(str, "\ud802\udc02\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01\ud802\udc02") str = "\ud800\udc00\ud801\udc01\ud802\udc02" testReverse(str, "\ud802\udc02\ud801\udc01\ud800\udc00", str) str = "\ud800\udc00\udc01\ud801a" testReverse(str, "a\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01a") str = "a\ud800\udc00\ud801\udc01" testReverse(str, "\ud801\udc01\ud800\udc00a", str) str = "\ud800\udc00\udc01\ud801ab" testReverse(str, "ba\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01ab") str = "ab\ud800\udc00\ud801\udc01" testReverse(str, "\ud801\udc01\ud800\udc00ba", str) str = "\ud800\udc00\ud801\udc01" testReverse(str, "\ud801\udc01\ud800\udc00", str) str = "a\ud800\udc00z\ud801\udc01" testReverse(str, "\ud801\udc01z\ud800\udc00a", str) str = "a\ud800\udc00bz\ud801\udc01" testReverse(str, "\ud801\udc01zb\ud800\udc00a", str) str = "abc\ud802\udc02\ud801\udc01\ud800\udc00" testReverse(str, "\ud800\udc00\ud801\udc01\ud802\udc02cba", str) str = "abcd\ud802\udc02\ud801\udc01\ud800\udc00" testReverse(str, "\ud800\udc00\ud801\udc01\ud802\udc02dcba", str) } // Basic ==================================================================================================== fun testBasic() { val sb = StringBuilder() assertEquals(0, sb.length) assertEquals("", sb.toString()) sb.append(1) assertEquals(1, sb.length) assertEquals("1", sb.toString()) sb.append(", ") assertEquals(3, sb.length) assertEquals("1, ", sb.toString()) sb.append(true) assertEquals(7, sb.length) assertEquals("1, true", sb.toString()) sb.append(12345678L) assertEquals(15, sb.length) assertEquals("1, true12345678", sb.toString()) sb.append(null as CharSequence?) assertEquals(19, sb.length) assertEquals("1, true12345678null", sb.toString()) sb.setLength(0) assertEquals(0, sb.length) assertEquals("", sb.toString()) } @Test fun runTest() { testBasic() testInsert() testReverse() println("OK") } ================================================ FILE: backend.native/tests/runtime/text/string_builder1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.string_builder1 import kotlin.test.* @Test fun runTest() { val a = StringBuilder() a.append("Hello").appendln("Kotlin").appendln(42).appendln(0.1).appendln(true) println(a.toString()) } ================================================ FILE: backend.native/tests/runtime/text/to_string0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.to_string0 import kotlin.test.* // Based on Apache Harmony tests. fun assertEquals(actual: String, expected: String, msg: String) { if (actual != expected) throw AssertionError("$msg. Actual: $actual. Expected: $expected") } fun testIntToStringWithRadix() { assertEquals(2147483647.toString(8), "17777777777", "Octal string") assertEquals(2147483647.toString(16), "7fffffff", "Hex string") assertEquals(2147483647.toString(2), "1111111111111111111111111111111", "Binary string") assertEquals(2147483647.toString(10), "2147483647", "Decimal string") assertEquals((-2147483647).toString(8), "-17777777777", "Octal string") assertEquals((-2147483647).toString(16), "-7fffffff", "Hex string") assertEquals((-2147483647).toString(2), "-1111111111111111111111111111111", "Binary string") assertEquals((-2147483647).toString(10), "-2147483647", "Decimal string") assertEquals((-2147483648).toString(8), "-20000000000", "Octal string") assertEquals((-2147483648).toString(16), "-80000000", "Hex string") assertEquals((-2147483648).toString(2), "-10000000000000000000000000000000", "Binary string") assertEquals((-2147483648).toString(10), "-2147483648", "Decimal string") } fun testLongToStringWithRadix() { assertEquals(100000000L.toString(10), "100000000", "Decimal string") assertEquals(68719476735L.toString(16), "fffffffff", "Hex string") assertEquals(8589934591L.toString(8), "77777777777", "Octal string") assertEquals(8796093022207L.toString(2), "1111111111111111111111111111111111111111111", "Binary string") assertEquals((-0x7fffffffffffffffL - 1).toString(10), "-9223372036854775808", "Min decimal string") assertEquals(0x7fffffffffffffffL.toString(10), "9223372036854775807", "Max decimal string") assertEquals((-0x7fffffffffffffffL - 1).toString(16), "-8000000000000000", "Min hex string") assertEquals(0x7fffffffffffffffL.toString(16), "7fffffffffffffff", "Max hex string") } @Test fun runTest() { testIntToStringWithRadix() testLongToStringWithRadix() println("OK") } ================================================ FILE: backend.native/tests/runtime/text/trim.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.trim import kotlin.test.* /** * Tests correct conversions of floats/doubles along with trimming of leading/trailing whitespaces. * String.trim() trims all whitespaces (see kotlin/text/Strings.kt) while String.toFloat() uses * the same approach as java.lang.Float.parseFloat() */ @Test fun runTest() { convertToFloatingPoint() convertWithWhitespaces() trimWhitespaces() println("OK") } private fun convertToFloatingPoint() { assertEquals(expected = 3.14F, actual = " 3.14 ".toFloat(), message = "String float should be trimmed") assertEquals(expected = 3.14, actual = " 3.14 ".toDouble(), message = "String double should be trimmed") assertEquals(expected = 7.15F, actual = "\u0019 7.15 ".toFloat(), message = "String float should be trimmed") assertEquals(expected = 42.3, actual = "\n 42.3 ".toDouble(), message = "String double should be trimmed") } private fun convertWithWhitespaces() { val s = "\u0009 \u000A 2.71 \u000D" assertEquals(expected = 2.71F, actual = s.toFloat(), message = "String should be cleared of LF, CR, TAB and converted to Float") assertEquals(expected = 2.71, actual = s.toDouble(), message = "String should be cleared of LF, CR, TAB and converted to Double") // Special symbols should not be trimmed during String to Float/Double conversion assertFailsWith { "\u202F3.14".toFloat() } assertFailsWith { "\u20293.14".toDouble() } assertFailsWith { "3.14\u200B".toDouble() } assertFailsWith { "3.14\u200B ABC".toDouble() } } private fun trimWhitespaces() { assertEquals(expected = "String", actual = " String".trim(), message = "Trim leading spaces") assertEquals(expected = "String ", actual = " String ".trimStart(), message = "Trim start") assertEquals(expected = " String", actual = " String \t ".trimEnd(), message = "Trim end") assertEquals(expected = "String", actual = "\u0020 \u202FString\u2028\u2029".trim(), message = "Trim special whitespaces") assertEquals(expected = "\u1FFFString", actual = "\u00A0 \u1FFFString".trim(), message = "Trim special whitespace but should left a unicode symbol") assertEquals(expected = "String\tSTR", actual = " \nString\tSTR ".trim(), message = "Trim newline") } ================================================ FILE: backend.native/tests/runtime/text/utf8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.text.utf8 import kotlin.test.* import kotlin.reflect.KClass import kotlinx.cinterop.toKString // -------------------------------------- Utils -------------------------------------- fun assertEquals(expected: ByteArray, actual: ByteArray, message: String) = assertTrue(expected.contentEquals(actual), message) fun checkUtf16to8(string: String, expected: IntArray, conversion: String.() -> ByteArray) { expected.forEach { assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values") } val expectedBytes = ByteArray(expected.size) { i -> expected[i].toByte() } val actual = string.conversion() assertEquals(expectedBytes, actual, """ Assert failed for string: $string Expected: ${expected.joinToString()} Actual: ${actual.joinToString()} """.trimIndent()) } // Utils for checking successful UTF-16 to UTF-8 conversion. fun checkUtf16to8Replacing(string: String, expected: IntArray) { checkUtf16to8(string, expected) { encodeToByteArray() } } fun checkUtf16to8Throwing(string: String, expected: IntArray) { checkUtf16to8(string, expected) { encodeToByteArray(throwOnInvalidSequence = true) } } fun checkValidUtf16to8(string: String, expected: IntArray) { checkUtf16to8Replacing(string, expected) checkUtf16to8Throwing(string, expected) } fun checkUtf16to8Replacing(string: String, expected: IntArray, start: Int, size: Int) { checkUtf16to8(string, expected) { encodeToByteArray(start, start + size) } } fun checkUtf16to8Throwing(string: String, expected: IntArray, start: Int, size: Int) { checkUtf16to8(string, expected) { encodeToByteArray(start, start + size, true) } } fun checkValidUtf16to8(string: String, expected: IntArray, start: Int, size: Int) { checkUtf16to8Replacing(string, expected, start, size) checkUtf16to8Throwing(string, expected, start, size) } // Utils for checking successful UTF-8 to UTF-16 conversion. fun checkUtf8to16(expected: String, array: IntArray, conversion: ByteArray.() -> String) { array.forEach { assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values") } val arrayBytes = ByteArray(array.size) { i -> array[i].toByte() } val actual = arrayBytes.conversion() assertEquals(expected, actual, """ Assert failed for string: $expected Expected: $expected Actual: $actual """.trimIndent()) } fun checkZeroTerminatedUtf8to16Replacing(expected: String, array: IntArray) { checkUtf8to16(expected, array) { toKString() } checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString() } } fun checkUtf8to16Replacing(expected: String, array: IntArray) { checkUtf8to16(expected, array) { decodeToString() } checkZeroTerminatedUtf8to16Replacing(expected, array) } fun checkZeroTerminatedUtf8to16Throwing(expected: String, array: IntArray) { checkUtf8to16(expected, array) { toKString(throwOnInvalidSequence = true) } checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(throwOnInvalidSequence = true) } } fun checkUtf8to16Throwing(expected: String, array: IntArray) { checkUtf8to16(expected, array) { decodeToString(throwOnInvalidSequence = true) } checkZeroTerminatedUtf8to16Throwing(expected, array) } fun checkValidUtf8to16(expected: String, array: IntArray) { checkUtf8to16Replacing(expected, array) checkUtf8to16Throwing(expected, array) } fun checkValidZeroTerminatedUtf8to16(expected: String, array: IntArray) { checkZeroTerminatedUtf8to16Replacing(expected, array) checkZeroTerminatedUtf8to16Throwing(expected, array) } fun checkZeroTerminatedUtf8to16Replacing(expected: String, array: IntArray, start: Int, size: Int) { checkUtf8to16(expected, array) { toKString(start, start + size) } checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(start, start + size) } } fun checkUtf8to16Replacing(expected: String, array: IntArray, start: Int, size: Int) { checkUtf8to16(expected, array) { decodeToString(start, start + size) } checkZeroTerminatedUtf8to16Replacing(expected, array, start, size) } fun checkZeroTerminatedUtf8to16Throwing(expected: String, array: IntArray, start: Int, size: Int) { checkUtf8to16(expected, array) { toKString(start, start + size, true) } checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(start, start + size, true) } } fun checkUtf8to16Throwing(expected: String, array: IntArray, start: Int, size: Int) { checkUtf8to16(expected, array) { decodeToString(start, start + size, true) } checkZeroTerminatedUtf8to16Throwing(expected, array, start, size) } fun checkValidUtf8to16(expected: String, array: IntArray, start: Int, size: Int) { checkUtf8to16Replacing(expected, array, start, size) checkUtf8to16Throwing(expected, array, start, size) } fun checkValidZeroTerminatedUtf8to16(expected: String, array: IntArray, start: Int, size: Int) { checkZeroTerminatedUtf8to16Replacing(expected, array, start, size) checkZeroTerminatedUtf8to16Throwing(expected, array, start, size) } // Utils for checking malformed UTF-16 to UTF-8 conversion. fun checkThrows(e: KClass, string: String, action: () -> Unit) { var exception: Throwable? = null try { action() } catch (e: Throwable) { exception = e } assertNotNull(exception, "No exception was thrown for string: $string") assertTrue(e.isInstance(exception),""" Wrong exception was thrown for string: $string Expected: ${e.qualifiedName} Actual: ${exception::class.qualifiedName}: $exception} """.trimIndent()) } fun checkUtf16to8Throws(string: String) { checkThrows(CharacterCodingException::class, string) { string.encodeToByteArray(throwOnInvalidSequence = true) } } fun checkUtf16to8Throws(string: String, start: Int, size: Int) { checkThrows(CharacterCodingException::class, string) { string.encodeToByteArray(start, start + size, true) } } // Utils for checking malformed UTF-8 to UTF-16 conversion. fun checkUtf8to16Throws(e: KClass, string: String, array: IntArray, conversion: ByteArray.() -> String) = checkThrows(e, string) { array.forEach { assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values") } val arrayBytes = ByteArray(array.size) { i -> array[i].toByte() } arrayBytes.conversion() } fun checkZeroTerminatedUtf8to16Throws(string: String, array: IntArray) { checkUtf8to16Throws(CharacterCodingException::class, string, array) { toKString(throwOnInvalidSequence = true) } checkUtf8to16Throws(CharacterCodingException::class, string, array.copyOf(array.size + 1)) { toKString(throwOnInvalidSequence = true) } } fun checkUtf8to16Throws(string: String, array: IntArray) { checkUtf8to16Throws(CharacterCodingException::class, string, array) { decodeToString(throwOnInvalidSequence = true) } checkZeroTerminatedUtf8to16Throws(string, array) } fun checkZeroTerminatedUtf8to16Throws(string: String, array: IntArray, start: Int, size: Int) { checkUtf8to16Throws(CharacterCodingException::class, string, array) { toKString(start, start + size, true) } checkUtf8to16Throws(CharacterCodingException::class, string, array.copyOf(array.size + 1)) { toKString(start, start + size, true) } } fun checkUtf8to16Throws(string: String, array: IntArray, start: Int, size: Int) { checkUtf8to16Throws(CharacterCodingException::class, string, array) { decodeToString(start, start + size, true) } checkZeroTerminatedUtf8to16Throws(string, array, start, size) } // Utils for checking String to floating-point number conversion. fun checkDoubleConversionThrows(string: String) = checkThrows(NumberFormatException::class, string) { string.toDouble() } fun checkFloatConversionThrows(string: String) = checkThrows(NumberFormatException::class, string) { string.toFloat() } // Utils for checking invalid-bounds-exception thrown by UTF-16 to UTF-8 conversion. fun checkOutOfBoundsUtf16to8Replacing(e: KClass, string: String, start: Int, size: Int) { checkThrows(e, string) { string.encodeToByteArray(start, start + size) } } fun checkOutOfBoundsUtf16to8Throwing(e: KClass, string: String, start: Int, size: Int) { checkThrows(e, string) { string.encodeToByteArray(start, start + size, true) } } fun checkOutOfBoundsUtf16to8(e: KClass, string: String, start: Int, size: Int) { checkOutOfBoundsUtf16to8Replacing(e, string, start, size) checkOutOfBoundsUtf16to8Throwing(e, string, start, size) } // Utils for checking invalid-bounds-exception thrown by UTF-8 to UTF-16 conversion. fun checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkThrows(e, string) { byteArray.toKString(start, start + size) } } fun checkOutOfBoundsUtf8to16Replacing(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkThrows(e, string) { byteArray.decodeToString(start, start + size) } checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e, string, byteArray, start, size) } fun checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkThrows(e, string) { byteArray.toKString(start, start + size, true) } } fun checkOutOfBoundsUtf8to16Throwing(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkThrows(e, string) { byteArray.decodeToString(start, start + size, true) } checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e, string, byteArray, start, size) } fun checkOutOfBoundsUtf8to16(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkOutOfBoundsUtf8to16Replacing(e, string, byteArray, start, size) checkOutOfBoundsUtf8to16Throwing(e, string, byteArray, start, size) } fun checkOutOfBoundsZeroTerminatedUtf8to16(e: KClass, string: String, byteArray: ByteArray, start: Int, size: Int) { checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e, string, byteArray, start, size) checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e, string, byteArray, start, size) } // Util for performing action on result of UTF-8 to UTF-16 conversion. fun convertUtf8to16(byteArray: ByteArray, action: (String) -> Unit) { byteArray.decodeToString().let { action(it) } byteArray.toKString().let { action(it) } } // ------------------------- Test UTF-16 to UTF-8 conversion ------------------------- fun test16to8() { // Valid strings. checkValidUtf16to8("Hello", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt())) checkValidUtf16to8("Привет", intArrayOf(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126)) checkValidUtf16to8("\uD800\uDC00", intArrayOf(-16, -112, -128, -128)) checkValidUtf16to8("", intArrayOf()) // Test manual conversion with replacement. // Illegal surrogate pair -> replace with default checkUtf16to8Replacing("\uDC00\uD800", intArrayOf(-17, -65, -67, -17, -65, -67)) // Different kinds of input checkUtf16to8Replacing("\uD800\uDC001\uDC00\uD800", intArrayOf(-16, -112, -128, -128, '1'.toInt(), -17, -65, -67, -17, -65, -67)) // Lone surrogate - replace with default checkUtf16to8Replacing("\uD80012", intArrayOf(-17, -65, -67, '1'.toInt(), '2'.toInt())) checkUtf16to8Replacing("\uDC0012", intArrayOf(-17, -65, -67, '1'.toInt(), '2'.toInt())) checkUtf16to8Replacing("12\uD800", intArrayOf('1'.toInt(), '2'.toInt(), -17, -65, -67)) // Test manual conversion with an exception if an input is invalid. // Illegal surrogate pair -> throw checkUtf16to8Throws("\uDC00\uD800") // Different kinds of input (including illegal one) -> throw checkUtf16to8Throws("\uD800\uDC001\uDC00\uD800") // Lone surrogate - throw checkUtf16to8Throws("\uD80012") checkUtf16to8Throws("\uDC0012") checkUtf16to8Throws("12\uD800") // Test double parsing. assertEquals(4.2, "4.2".toDouble()) // Illegal surrogate pair -> throw checkDoubleConversionThrows("\uDC00\uD800") // Different kinds of input (including illegal one) -> throw checkDoubleConversionThrows("\uD800\uDC001\uDC00\uD800") // Lone surrogate - throw checkDoubleConversionThrows("\uD80012") checkDoubleConversionThrows("\uDC0012") checkDoubleConversionThrows("12\uD800") // Test float parsing. assertEquals(4.2F, "4.2".toFloat()) // Illegal surrogate pair -> throw checkFloatConversionThrows("\uDC00\uD800") // Different kinds of input (including illegal one) -> throw checkFloatConversionThrows("\uD800\uDC001\uDC00\uD800") // Lone surrogate - throw checkFloatConversionThrows("\uD80012") checkFloatConversionThrows("\uDC0012") checkFloatConversionThrows("12\uD800") } fun test16to8CustomBorders() { // Valid strings. checkValidUtf16to8("Hello!", intArrayOf('H'.toInt(), 'e'.toInt()), 0, 2) checkValidUtf16to8("Hello!", intArrayOf('e'.toInt(), 'l'.toInt()), 1, 2) checkValidUtf16to8("Hello!", intArrayOf('o'.toInt(), '!'.toInt()), 4, 2) checkValidUtf16to8("Hello!", intArrayOf(), 0, 0) checkValidUtf16to8("Hello!", intArrayOf(), 6, 0) checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 0, 4) checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 2, 4) checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 4, 4) // Index out of bound checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", -1, 4) checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", 5, 10) checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", 2, 10) checkOutOfBoundsUtf16to8(IllegalArgumentException::class, "Hello", 3, -2) // Test manual conversion with replacement and custom borders. // Illegal surrogate pair -> replace with default checkUtf16to8Replacing("\uDC00\uD80012", intArrayOf(-17, -65, -67, -17, -65, -67, '1'.toInt()), 0, 3) checkUtf16to8Replacing("1\uDC00\uD8002", intArrayOf(-17, -65, -67, -17, -65, -67, '2'.toInt()), 1, 3) checkUtf16to8Replacing("12\uDC00\uD800", intArrayOf('2'.toInt(), -17, -65, -67, -17, -65, -67), 1, 3) // Lone surrogate - replace with default checkUtf16to8Replacing("1\uD800\uDC002", intArrayOf('1'.toInt(), -17, -65, -67), 0, 2) checkUtf16to8Replacing("1\uD800\uDC002", intArrayOf(-17, -65, -67, '2'.toInt()), 2, 2) // Test manual conversion with an exception if an input is invalid and custom borders. // Illegal surrogate pair -> throw checkUtf16to8Throws("\uDC00\uD80012", 0, 3) checkUtf16to8Throws("1\uDC00\uD8002", 1, 3) checkUtf16to8Throws("12\uDC00\uD800", 1, 3) // Lone surrogate -> throw checkUtf16to8Throws("1\uD800\uDC002", 0, 2) checkUtf16to8Throws("1\uD800\uDC002", 2, 2) } fun testPrint() { // Valid strings. println("Hello") println("Привет") println("\uD800\uDC00") println("") // Illegal surrogate pair -> default output println("\uDC00\uD800") // Lone surrogate -> default output println("\uD80012") println("\uDC0012") println("12\uD800") // https://github.com/JetBrains/kotlin-native/issues/1091 val array = byteArrayOf(0xF0.toByte(), 0x9F.toByte(), 0x98.toByte(), 0xA5.toByte()) convertUtf8to16(array) { badString -> assertEquals(2, badString.length) println(badString) } } // ------------------------- Test UTF-8 to UTF-16 conversion ------------------------- fun test8to16() { // Valid strings. checkValidUtf8to16("Hello", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt())) checkValidUtf8to16("Привет", intArrayOf(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126)) checkValidUtf8to16("\uD800\uDC00", intArrayOf(-16, -112, -128, -128)) checkValidUtf8to16("", intArrayOf()) // Test manual conversion with replacement. // Incorrect UTF-8 lead character. checkUtf8to16Replacing("\uFFFD1", intArrayOf(-1, '1'.toInt())) // Incomplete codepoint. checkUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt())) checkUtf8to16Replacing("\uFFFD1\uFFFD", intArrayOf(-16, -97, -104, '1'.toInt(), -16, -97, -104)) // Test manual conversion with exception throwing // Incorrect UTF-8 lead character -> throw. checkUtf8to16Throws("\uFFFD1", intArrayOf(-1, '1'.toInt())) // Incomplete codepoint -> throw. checkUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt())) checkUtf8to16Throws("\uFFFD1\uFFFD", intArrayOf(-16, -97, -104, '1'.toInt(), -16, -97, -104)) } fun test8to16CustomBorders() { // Valid strings. checkValidUtf8to16("He", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()),0, 2) checkValidUtf8to16("ll", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 2, 2) checkValidUtf8to16("lo", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 3, 2) checkValidUtf8to16("", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 0, 0) checkValidUtf8to16("\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 0, 8) checkValidUtf8to16("\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 4, 8) checkValidUtf8to16("\uD800\uDC00\uD800\uDC00", intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 8, 8) // Index out of bound val helloArray = byteArrayOf('H'.toByte(), 'e'.toByte(), 'l'.toByte(), 'l'.toByte(), 'o'.toByte()) checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, -1, 4) checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 5, 10) checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 2, 10) checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 10, 0) checkOutOfBoundsUtf8to16(IllegalArgumentException::class, "Hello", helloArray, 3, -2) // Test manual conversion with replacement and custom borders. // Incorrect UTF-8 lead character. checkUtf8to16Replacing("\uFFFD1", intArrayOf(-1, '1'.toInt(), '2'.toInt()), 0, 2) checkUtf8to16Replacing("\uFFFD2", intArrayOf('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 2) checkUtf8to16Replacing("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -1), 1, 2) // Incomplete codepoint. checkUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4) checkUtf8to16Replacing("\uFFFD2", intArrayOf('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 4) checkUtf8to16Replacing("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 4) // Test manual conversion with an exception if an input is invalid and custom borders. // Incorrect UTF-8 lead character. checkUtf8to16Throws("\uFFFD1", intArrayOf(-1, '1'.toInt(), '2'.toInt()), 0, 2) checkUtf8to16Throws("\uFFFD2", intArrayOf('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 2) checkUtf8to16Throws("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -1), 1, 2) // Incomplete codepoint. checkUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4) checkUtf8to16Throws("\uFFFD2", intArrayOf('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 4) checkUtf8to16Throws("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 4) } // ----------------- Test zero-terminated UTF-8 to UTF-16 conversion ----------------- fun testZeroTerminated8To16() { // Valid strings. checkValidZeroTerminatedUtf8to16("Hell", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 0, 'o'.toInt())) checkValidZeroTerminatedUtf8to16("При", intArrayOf(-48, -97, -47, -128, -48, -72, 0, -48, -78, 0, -48, -75, -47, -126)) checkValidZeroTerminatedUtf8to16("\uD800\uDC00", intArrayOf(-16, -112, -128, -128, 0, -16, -112, -128, -128)) checkValidZeroTerminatedUtf8to16("", intArrayOf(0, 'H'.toInt())) // Test manual conversion with replacement. // Incorrect UTF-8 lead character. checkZeroTerminatedUtf8to16Replacing("\uFFFD", intArrayOf(-1, 0, '1'.toInt())) // Incomplete codepoint. checkZeroTerminatedUtf8to16Replacing("\uFFFD", intArrayOf(-16, -97, -104, 0, '1'.toInt())) checkZeroTerminatedUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), 0, -16, -97, -104)) // Test manual conversion with exception throwing // Incorrect UTF-8 lead character -> throw. checkZeroTerminatedUtf8to16Throws("\uFFFD", intArrayOf(-1, 0, '1'.toInt())) // Incomplete codepoint -> throw. checkZeroTerminatedUtf8to16Throws("\uFFFD", intArrayOf(-16, -97, -104, 0, '1'.toInt())) checkZeroTerminatedUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), 0, -16, -97, -104)) } fun testZeroTerminated8To16CustomBorders() { val array = intArrayOf('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0) checkValidZeroTerminatedUtf8to16("aaa", array, 0, 5) checkValidZeroTerminatedUtf8to16("a", array, 2, 2) checkValidZeroTerminatedUtf8to16("", array, 3, 2) checkValidZeroTerminatedUtf8to16("bb", array, 4, 2) checkValidZeroTerminatedUtf8to16("bbb", array, 4, 3) checkValidZeroTerminatedUtf8to16("bbb", array, 4, 4) checkValidZeroTerminatedUtf8to16("bb", array, 5, 3) checkValidZeroTerminatedUtf8to16("b", array, 6, 2) checkValidZeroTerminatedUtf8to16("", array, 7, 1) checkValidZeroTerminatedUtf8to16("", array, 8, 0) val byteArray = ByteArray(array.size) { array[it].toByte() } checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, -1, 4) checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 8, 10) checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 2, 10) checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 10, 0) checkOutOfBoundsZeroTerminatedUtf8to16(IllegalArgumentException::class, "aaa0bbb0", byteArray, 3, -2) } // ------------------------------------ Run tests ------------------------------------ @Test fun runTest() { test16to8() test16to8CustomBorders() test8to16() test8to16CustomBorders() testZeroTerminated8To16() testZeroTerminated8To16CustomBorders() testPrint() } ================================================ FILE: backend.native/tests/runtime/workers/atomic0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.atomic0 import kotlin.test.* import kotlin.native.concurrent.* fun test1(workers: Array) { val atomic = AtomicInt(15) val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { atomic }) { input -> input.addAndGet(1) } }) futures.forEach { it.result } println(atomic.value) } fun test2(workers: Array) { val atomic = AtomicInt(1) val counter = AtomicInt(0) val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { Triple(atomic, workerIndex, counter) }) { (place, index, result) -> // Here we simulate mutex using [place] location to store tag of the current worker. // When it is negative - worker executes exclusively. val tag = index + 1 while (place.compareAndSwap(tag, -tag) != tag) {} val ok1 = result.addAndGet(1) == index + 1 // Now, let the next worker run. val ok2 = place.compareAndSwap(-tag, tag + 1) == -tag ok1 && ok2 } }) futures.forEach { assertEquals(it.result, true) } println(counter.value) } data class Data(val value: Int) fun test3(workers: Array) { val common = AtomicReference(null) val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { Pair(common, workerIndex) }) { (place, index) -> val mine = Data(index).freeze() // Try to publish our own data, until successful, in a tight loop. while (!place.compareAndSet(null, mine)) {} } }) val seen = mutableSetOf() for (i in 0 until workers.size) { do { val current = common.value if (current != null && !seen.contains(current)) { seen += current // Let others publish. assertEquals(common.compareAndSwap(current, null), current) break } } while (true) } futures.forEach { it.result } assertEquals(seen.size, workers.size) } fun test4() { assertFailsWith { AtomicReference(Data(1)) } assertFailsWith { AtomicReference(null).compareAndSwap(null, Data(2)) } } fun test5() { assertFailsWith { AtomicReference(null).value = Data(2) } val ref = AtomicReference(null) val value = Data(3).freeze() assertEquals(null, ref.value) ref.value = value assertEquals(3, ref.value!!.value) } fun test6() { val int = AtomicInt(0) int.value = 239 assertEquals(239, int.value) val long = AtomicLong(0) long.value = 239L assertEquals(239L, long.value) } fun test7() { val ref = FreezableAtomicReference(Array(1) { "hey" }) ref.value[0] = "ho" assertEquals(ref.value[0], "ho") ref.value = Array(1) { "po" } assertEquals(ref.value[0], "po") ref.freeze() assertFailsWith { ref.value = Array(1) { "no" } } assertFailsWith { ref.value[0] = "go" } ref.value = Array(1) { "so" }.freeze() assertEquals(ref.value[0], "so") } @Test fun runTest() { val COUNT = 20 val workers = Array(COUNT, { _ -> Worker.start()}) test1(workers) test2(workers) test3(workers) test4() test5() test6() test7() workers.forEach { it.requestTermination().result } println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/atomic1.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // Note: This test reproduces a race, so it'll start flaking if problem is reintroduced. import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.internal.* val thrashGC = AtomicInt(1) val canStartCreating = AtomicInt(0) val createdCount = AtomicInt(0) val canStartReading = AtomicInt(0) const val atomicsCount = 1000 const val workersCount = 10 fun main() { val gcWorker = Worker.start() val future = gcWorker.execute(TransferMode.SAFE, {}, { canStartCreating.value = 1 while (thrashGC.value != 0) { GC.collectCyclic() } GC.collect() }) while (canStartCreating.value == 0) {} val workers = Array(workersCount) { Worker.start() } val futures = workers.map { it.execute(TransferMode.SAFE, {}, { val atomics = Array(atomicsCount) { AtomicReference(Any().freeze()) } createdCount.increment() while (canStartReading.value == 0) {} GC.collect() atomics.all { it.value != null } }) } while (createdCount.value != workersCount) {} thrashGC.value = 0 future.result GC.collect() canStartReading.value = 1 assertTrue(futures.all { it.result }) for (worker in workers) { worker.requestTermination().result } gcWorker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/workers/enum_identity.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.enum_identity import kotlin.test.* import kotlin.native.concurrent.* enum class A { A, B } data class Foo(val kind: A) // Enums are shared between threads so identity should be kept. @Test fun runTest() { val result = Worker.start().execute(TransferMode.SAFE, { Foo(A.B) }, { input -> input.kind == A.B }).result println(result) } ================================================ FILE: backend.native/tests/runtime/workers/freeze0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze0 import kotlin.test.* import kotlin.native.concurrent.* data class SharedDataMember(val double: Double) data class SharedData(val string: String, val int: Int, val member: SharedDataMember) @Test fun runTest() { val worker = Worker.start() // Create immutable shared data. val immutable = SharedData("Hello", 10, SharedDataMember(0.1)).freeze() println("frozen bit is ${immutable.isFrozen}") val future = worker.execute(TransferMode.SAFE, { immutable } ) { input -> println("Worker: $input") input } future.consume { result -> println("Main: $result") } worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/freeze1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze1 import kotlin.test.* import kotlin.native.concurrent.* data class Node(var previous: Node?, var data: Int) fun makeCycle(count: Int): Node { val first = Node(null, 0) var current = first for (index in 1 .. count - 1) { current = Node(current, index) } first.previous = current return first } data class Node2(var leaf1: Node2?, var leaf2: Node2?) fun makeDiamond(): Node2 { val bottom = Node2(null, null) val mid1prime = Node2(bottom, null) val mid1 = Node2(mid1prime, null) val mid2 = Node2(bottom, null) return Node2(mid1, mid2) } @Test fun runTest() { makeCycle(10).freeze() // Must be able to freeze diamond shaped graph. val diamond = makeDiamond().freeze() val immutable = Node(null, 4).freeze() try { immutable.data = 42 } catch (e: InvalidMutabilityException) { println("OK, cannot mutate frozen") } } ================================================ FILE: backend.native/tests/runtime/workers/freeze2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze2 import kotlin.test.* import kotlin.native.concurrent.* data class Data(var int: Int) @Test fun runTest() { // Ensure that we can not mutate frozen objects and arrays. val a0 = Data(2) a0.int++ a0.freeze() assertFailsWith {a0.int++ } val a1 = ByteArray(2) a1[1]++ a1.freeze() assertFailsWith { a1[1]++ } val a2 = ShortArray(2) a2[1]++ a2.freeze() assertFailsWith { a2[1]++ } val a3 = IntArray(2) a3[1]++ a3.freeze() assertFailsWith { a3[1]++ } val a4 = LongArray(2) a4[1]++ a4.freeze() assertFailsWith { a4[1]++ } val a5 = BooleanArray(2) a5[1] = true a5.freeze() assertFailsWith { a5[1] = false } val a6 = CharArray(2) a6[1] = 'a' a6.freeze() assertFailsWith { a6[1] = 'b' } val a7 = FloatArray(2) a7[1] = 1.0f a7.freeze() assertFailsWith { a7[1] = 2.0f } val a8 = DoubleArray(2) a8[1] = 1.0 a8.freeze() assertFailsWith { a8[1] = 2.0 } // Ensure that String and integral boxes are frozen by default, by passing local to the worker. val worker = Worker.start() var data: Any = "Hello" + " " + "world" assert(data.isFrozen) worker.execute(TransferMode.SAFE, { data } ) { input -> println("Worker 1: $input") }.result data = 42 assert(data.isFrozen) worker.execute(TransferMode.SAFE, { data } ) { input -> println("Worker2: $input") }.result data = 239.0 assert(data.isFrozen) worker.execute(TransferMode.SAFE, { data } ) { input -> println("Worker3: $input") }.result data = 'a' assert(data.isFrozen) worker.execute(TransferMode.SAFE, { data } ) { input -> println("Worker4: $input") }.result worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/freeze3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze3 import kotlin.test.* import kotlin.native.concurrent.* object AnObject { var x = 1 } @ThreadLocal object Mutable { var x = 2 } val topLevelInline: ULong = 0xc3a5c85c97cb3127U @Test fun runTest1() { assertEquals(1, AnObject.x) if (Platform.memoryModel == MemoryModel.STRICT) { assertFailsWith { AnObject.x++ } assertEquals(1, AnObject.x) } else { AnObject.x++ assertEquals(2, AnObject.x) } Mutable.x++ assertEquals(3, Mutable.x) println("OK") } @Test fun runTest2() { val ok = AtomicInt(0) withWorker() { executeAfter(0, { assertEquals(0xc3a5c85c97cb3127U, topLevelInline) ok.increment() }.freeze()) } assertEquals(1, ok.value) } ================================================ FILE: backend.native/tests/runtime/workers/freeze4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze4 import kotlin.test.* import kotlin.native.concurrent.* data class Data(val x: Int, val s: String, val next: Data? = null) @Test fun runTest() { val data1 = Data(1, "") data1.freeze() assertFailsWith { data1.ensureNeverFrozen() } val dataNF = Data(42, "42") dataNF.ensureNeverFrozen() val data2 = Data(2, "2", dataNF) assertFailsWith { data2.freeze() } assert(!data2.isFrozen) println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/freeze5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze5 import kotlin.test.* object Keys { internal val myMap: Map> = mapOf( "val1" to listOf("a1", "a2", "a3"), "val2" to listOf("b1", "b2") ) fun getKey(name: String): String { for (key in myMap.keys) { if (key == name) { return key } } return "" } fun getValue(name: String): String { for (value in myMap.values) { if (value.contains(name)) { return name } } return "" } fun getEntry(name: String): String { for (entry in myMap.entries) { if (entry.key == name) { return entry.key } } return "" } } @Test fun runTest() { assertEquals("val2", Keys.getKey("val2")) assertEquals("a1", Keys.getValue("a1")) assertEquals("val1", Keys.getEntry("val1")) println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/freeze6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze6 import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.ref.* data class Hi(val s: String) data class Nested(val hi: Hi) @Test fun ensureNeverFrozenNoFreezeChild(){ val noFreeze = Hi("qwert") noFreeze.ensureNeverFrozen() val nested = Nested(noFreeze) assertFails { nested.freeze() } println("OK") } @Test fun ensureNeverFrozenFailsTarget(){ val noFreeze = Hi("qwert") noFreeze.ensureNeverFrozen() assertFalse(noFreeze.isFrozen) assertFails { noFreeze.freeze() } assertFalse(noFreeze.isFrozen) println("OK") } fun createRef1(): FreezableAtomicReference { val ref = FreezableAtomicReference(null) ref.value = ref ref.freeze() ref.value = null return ref } var global = 0 @Test fun ensureFreezableHandlesCycles1() { val ref = createRef1() kotlin.native.internal.GC.collect() val obj: Any = ref global = obj.hashCode() } class Node(var ref: Any?) /** * ref1 -> Node <- ref3 * | /\ * V | * ref2 --- */ fun createRef2(): Pair, Any> { val ref1 = FreezableAtomicReference(null) val node = Node(null) val ref3 = FreezableAtomicReference(node) val ref2 = FreezableAtomicReference(ref3) node.ref = ref2 ref1.value = node ref1.freeze() ref3.value = null assertTrue(node.isFrozen) assertTrue(ref1.isFrozen) assertTrue(ref2.isFrozen) assertTrue(ref3.isFrozen) return ref1 to ref2 } @Test fun ensureFreezableHandlesCycles2() { val (ref, obj) = createRef2() kotlin.native.internal.GC.collect() assertTrue(obj.toString().length > 0) global = ref.value!!.ref!!.hashCode() } fun createRef3(): FreezableAtomicReference { val ref = FreezableAtomicReference(null) val node = Node(ref) ref.value = node ref.freeze() assertTrue(node.isFrozen) assertTrue(ref.isFrozen) return ref } @Test fun ensureFreezableHandlesCycles3() { val ref = createRef3() ref.value = null kotlin.native.internal.GC.collect() val obj: Any = ref assertTrue(obj.toString().length > 0) global = obj.hashCode() } lateinit var weakRef: WeakReference fun createRef4(): FreezableAtomicReference { val ref = FreezableAtomicReference(null) val node = Node(ref) weakRef = WeakReference(node) ref.value = node ref.freeze() assertTrue(weakRef.get() != null) return ref } @Test fun ensureWeakRefNotLeaks1() { val ref = createRef4() ref.value = null // We cannot check weakRef.get() here, as value read will be stored in the stack slot, // and thus hold weak reference from release. kotlin.native.internal.GC.collect() assertTrue(weakRef.get() == null) } lateinit var node1: Node lateinit var weakNode2: WeakReference fun createRef5() { val ref = FreezableAtomicReference(null) node1 = Node(ref) val node2 = Node(node1) weakNode2 = WeakReference(node2) ref.value = node2 node1.freeze() assertTrue(weakNode2.get() != null) ref.value = null } @Test fun ensureWeakRefNotLeaks2() { createRef5() kotlin.native.internal.GC.collect() assertTrue(weakNode2.get() == null) } ================================================ FILE: backend.native/tests/runtime/workers/freeze_stress.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.freeze_stress import kotlin.test.* import kotlin.native.concurrent.* class Random(private var seed: Int) { fun next(): Int { seed = (1103515245 * seed + 12345) and 0x7fffffff return seed } fun next(maxExclusiveValue: Int) = if (maxExclusiveValue == 0) 0 else next() % maxExclusiveValue fun next(minInclusiveValue: Int, maxInclusiveValue: Int) = minInclusiveValue + next(maxInclusiveValue - minInclusiveValue + 1) } class Node(val id: Int) { var numberOfEdges = 0 lateinit var edge0: Node lateinit var edge1: Node lateinit var edge2: Node lateinit var edge3: Node lateinit var edge4: Node lateinit var edge5: Node lateinit var edge6: Node lateinit var edge7: Node lateinit var edge8: Node lateinit var edge9: Node fun addEdge(child: Node) { when (numberOfEdges) { 0 -> edge0 = child 1 -> edge1 = child 2 -> edge2 = child 3 -> edge3 = child 4 -> edge4 = child 5 -> edge5 = child 6 -> edge6 = child 7 -> edge7 = child 8 -> edge8 = child 9 -> edge9 = child else -> error("Too many edges") } ++numberOfEdges } fun getEdges(): List { val result = mutableListOf() if (numberOfEdges > 0) result += edge0 if (numberOfEdges > 1) result += edge1 if (numberOfEdges > 2) result += edge2 if (numberOfEdges > 3) result += edge3 if (numberOfEdges > 4) result += edge4 if (numberOfEdges > 5) result += edge5 if (numberOfEdges > 6) result += edge6 if (numberOfEdges > 7) result += edge7 if (numberOfEdges > 8) result += edge8 if (numberOfEdges > 9) result += edge9 return result } } class Graph(val nodes: List, val roots: List) fun min(x: Int, y: Int) = if (x < y) x else y fun max(x: Int, y: Int) = if (x > y) x else y @ThreadLocal val random = Random(42) fun generate(condensationSize: Int, branchingFactor: Int, swellingFactor: Int): Graph { var id = 0 val nodes = mutableListOf() fun genDAG(n: Int): Node { val node = Node(id++) nodes += node if (n == 1) return node val numberOfChildren = random.next(1, min(n - 1, branchingFactor)) val used = BooleanArray(n) val points = IntArray(numberOfChildren + 1) points[0] = 0 points[numberOfChildren] = n - 1 used[0] = true used[n - 1] = true for (i in 1 until numberOfChildren) { var p: Int do { p = random.next(1, n - 1) } while (used[p]) used[p] = true points[i] = p } points.sort() for (i in 1..numberOfChildren) { val childSize = points[i] - points[i - 1] val child = genDAG(childSize) if (random.next(2) == 0) node.addEdge(child) else child.addEdge(node) } return node } genDAG(condensationSize) val numberOfEnters = IntArray(condensationSize) for (node in nodes) for (edge in node.getEdges()) ++numberOfEnters[edge.id] val roots = nodes.filter { numberOfEnters[it.id] == 0 } for (i in 0 until condensationSize) { val node = nodes[i] val componentSize = random.next(1, swellingFactor) if (componentSize == 1 && random.next(2) == 0) continue val component = Array(componentSize) { if (it == 0) node else Node(id++).also { nodes += it } } for (j in 0 until componentSize) component[j].addEdge(component[(j - 1 + componentSize) % componentSize]) val numberOfAdditionalEdges = random.next((componentSize + 1) / 2) for (j in 0 until numberOfAdditionalEdges) component[random.next(componentSize)].addEdge(component[random.next(componentSize)]) } return Graph(nodes, roots) } fun freezeOneGraph() { val graph = generate(100, 5, 20) graph.roots.forEach { it.freeze() } for (node in graph.nodes) assert (node.isFrozen, { "All nodes should be frozen" }) } @Test fun runTest() { for (i in 0..1000) { freezeOneGraph() } println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/lazy0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.lazy0 import kotlin.test.* import kotlin.native.concurrent.* data class Data(val x: Int, val y: String) object Immutable { val x by atomicLazy { 42 } } object Immutable2 { val y by atomicLazy { Data(239, "Kotlin") } } object Immutable3 { val x by lazy { var result = 0 for (i in 1 .. 1000) result += i result } } fun testSingleData(workers: Array) { val set = mutableSetOf() for (attempt in 1 .. 3) { val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { "" }) { _ -> Immutable2.y } }) futures.forEach { set += it.result } } assertEquals(set.size, 1) assertEquals(set.single(), Immutable2.y) } fun testFrozenLazy(workers: Array) { // To make sure it is always frozen, and we don't race in relaxed mode. Immutable3.freeze() val set = mutableSetOf() for (attempt in 1 .. 3) { val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { "" }) { _ -> Immutable3.x } }) futures.forEach { set += it.result } } assertEquals(1, set.size) assertEquals(Immutable3.x, set.single()) assertEquals(1001 * 500, set.single()) } fun testLiquidLazy() { class L { val value by lazy { 17 } } val l1 = L() for (i in 1 .. 100) assertEquals(l1.value, 17) val l2 = L() l2.freeze() for (i in 1 .. 100) assertEquals(l2.value, 17) } @Test fun runTest() { assertEquals(42, Immutable.x) val COUNT = 5 val workers = Array(COUNT, { _ -> Worker.start()}) testSingleData(workers) testFrozenLazy(workers) testLiquidLazy() println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/lazy1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.lazy1 import kotlin.test.* import kotlin.native.concurrent.* class Lazy { val x = 17 val self by lazy { this } val recursion: Int by lazy { if (x < 17) 42 else recursion } val freezer: Int by lazy { freeze() 42 } val thrower: String by lazy { if (x < 100) throw IllegalArgumentException() "FAIL" } } @Test fun runTest1() { assertFailsWith { println(Lazy().recursion) } assertFailsWith { println(Lazy().freeze().recursion) } } @Test fun runTest2() { var sum = 0 for (i in 1 .. 100) { val self = Lazy().freeze() assertEquals(self, self.self) sum += self.self.hashCode() } println("OK") } @Test fun runTest3() { assertFailsWith { println(Lazy().freezer) } } @Test fun runTest4() { val self = Lazy() repeat(10) { assertFailsWith { println(self.thrower) } } } ================================================ FILE: backend.native/tests/runtime/workers/lazy2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* object Foo { val bar = Bar() } class Bar { val f by lazy { foo() } fun foo() = 123 } fun printAll() { println(Foo.bar.f) } // This test is extracted from the real problem found in kotlinx.serialization, where zeroing out // initializer field in frozen lazy object led to the crash, induced by breaking frozen objects' // invariant (initializer end up in the same container as the lazy object itself, so it was destroyed // earlier than it should when reference counter was decremented). fun main(args: Array) { printAll() kotlin.native.internal.GC.collect() println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/lazy3.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.ref.* import kotlin.test.* fun main() { test1() test2() } fun test1() { ensureGetsCollectedFrozenAndNotFrozen { LazyCapturesThis() } ensureGetsCollectedFrozenAndNotFrozen { val l = LazyCapturesThis() l.bar l } ensureGetsCollected { val l = LazyCapturesThis().freeze() l.bar l } } class LazyCapturesThis { fun foo() = 42 val bar by lazy { foo() } } fun test2() { ensureGetsCollectedFrozenAndNotFrozen { Throwable() } ensureGetsCollectedFrozenAndNotFrozen { val throwable = Throwable() throwable.getStackTrace() throwable } ensureGetsCollected { val throwable = Throwable().freeze() throwable.getStackTrace() throwable } } fun ensureGetsCollectedFrozenAndNotFrozen(create: () -> Any) { ensureGetsCollected { create().freeze() } ensureGetsCollected(create) } fun ensureGetsCollected(create: () -> Any) { val ref = makeWeakRef(create) kotlin.native.internal.GC.collect() assertNull(ref.get()) } fun makeWeakRef(create: () -> Any) = WeakReference(create()) ================================================ FILE: backend.native/tests/runtime/workers/leak_memory_with_worker_termination.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.Platform import kotlinx.cinterop.* fun main() { Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() // Make sure worker is initialized. worker.execute(TransferMode.SAFE, {}, {}).result; StableRef.create(Any()) worker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/workers/leak_worker.kt ================================================ import kotlin.native.concurrent.* import kotlin.native.Platform import kotlinx.cinterop.* fun main() { Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() // Make sure worker is initialized. worker.execute(TransferMode.SAFE, {}, {}).result; StableRef.create(Any()) } ================================================ FILE: backend.native/tests/runtime/workers/mutableData1.kt ================================================ package runtime.workers.mutableData1 import kotlin.native.concurrent.* import kotlin.test.* // See https://youtrack.jetbrains.com/issue/KT-39145 @Test fun kt39145_1() = withWorker { execute(TransferMode.SAFE, { "test" }) { val data = MutableData(1_000) val bytes = byteArrayOf(0, 10, 20, 30) data.append(bytes, 0, 4) assertEquals(4, data.size) assertContentsEquals(bytes, data) }.result } @Test fun kt39145_2() = withWorker { val externalData = MutableData(1_000) execute(TransferMode.SAFE, { externalData }) { val bytes = byteArrayOf(0, 10, 20, 30) it.append(bytes, 0, 4) assertEquals(4, it.size) assertContentsEquals(bytes, it) }.result } @Test fun kt39145_3() { val mainThreadData = MutableData(1_000) val bytes = byteArrayOf(0, 10, 20, 30) mainThreadData.append(bytes, 0, 4) assertEquals(4, mainThreadData.size) assertContentsEquals(bytes, mainThreadData) } private fun assertContentsEquals(expected: ByteArray, actual: MutableData) { assertEquals(expected.size, actual.size) expected.forEachIndexed { index, byte -> assertEquals(byte, actual.get(index)) } } ================================================ FILE: backend.native/tests/runtime/workers/worker0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker0 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { "Input" }) { input -> assertEquals(1, 1) assertFailsWith { assertEquals(1, 2) } input + " processed" } future.consume { result -> println("Got $result") } worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker1.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker1 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest() { val COUNT = 5 val workers = Array(COUNT, { _ -> Worker.start()}) for (attempt in 1 .. 3) { val futures = Array(workers.size, { i -> workers[i].execute(TransferMode.SAFE, { "$attempt: Input $i" }) { input -> input + " processed" } }) futures.forEachIndexed { index, future -> future.consume { result -> if ("$attempt: Input $index processed" != result) { println("Got unexpected $result") throw Error(result) } } } } workers.forEach { it.requestTermination().result } println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker10.kt ================================================ package runtime.workers.worker10 import kotlin.test.* import kotlin.native.concurrent.* import kotlin.native.ref.WeakReference import kotlinx.cinterop.StableRef class Data(val x: Int) val topInt = 1 val topString = "string" var topStringVar = "string" val topSharedStringWithGetter: String get() = "top" val topData = Data(42) @SharedImmutable val topSharedData = Data(43) @Test fun runTest1() { val worker = Worker.start() assertEquals(1, topInt) assertEquals("string", topString) assertEquals(42, topData.x) assertEquals(43, topSharedData.x) assertEquals("top", topSharedStringWithGetter) worker.execute(TransferMode.SAFE, { -> }, { it -> topInt == 1 }).consume { result -> assertEquals(true, result) } worker.execute(TransferMode.SAFE, { -> }, { it -> topString == "string" }).consume { result -> assertEquals(true, result) } worker.execute(TransferMode.SAFE, { -> }, { it -> try { topStringVar == "string" } catch (e: IncorrectDereferenceException) { false } }).consume { result -> assertEquals(Platform.memoryModel == MemoryModel.RELAXED, result) } worker.execute(TransferMode.SAFE, { -> }, { it -> try { topSharedStringWithGetter == "top" } catch (e: IncorrectDereferenceException) { false } }).consume { result -> assertEquals(true, result) } worker.execute(TransferMode.SAFE, { -> }, { it -> try { topData.x == 42 } catch (e: IncorrectDereferenceException) { false } }).consume { result -> assertEquals(Platform.memoryModel == MemoryModel.RELAXED, result) } worker.execute(TransferMode.SAFE, { -> }, { it -> try { topSharedData.x == 43 } catch (e: Throwable) { false } }).consume { result -> assertEquals(true, result) } worker.requestTermination().result println("OK") } val atomicRef = AtomicReference(Any().freeze()) @SharedImmutable val stableRef = StableRef.create(Any().freeze()) val semaphore = AtomicInt(0) @Test fun runTest2() { semaphore.value = 0 val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { null }) { val value = atomicRef.value semaphore.increment() while (semaphore.value != 2) {} println(value.toString() != "") } while (semaphore.value != 1) {} atomicRef.value = null kotlin.native.internal.GC.collect() semaphore.increment() future.result worker.requestTermination().result } @Test fun runTest3() { semaphore.value = 0 val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { null }) { val value = stableRef.get() semaphore.increment() while (semaphore.value != 2) {} println(value.toString() != "") } while (semaphore.value != 1) {} stableRef.dispose() kotlin.native.internal.GC.collect() semaphore.increment() future.result worker.requestTermination().result } fun ensureWeakIs(weak: WeakReference, expected: T?) { assertEquals(expected, weak.get()) } val stableHolder1 = StableRef.create(("hello" to "world").freeze()) @Test fun runTest4() { val worker = Worker.start() semaphore.value = 0 val future = worker.execute(TransferMode.SAFE, { WeakReference(stableHolder1.get()) }) { ensureWeakIs(it, "hello" to "world") semaphore.increment() while (semaphore.value != 2) {} kotlin.native.internal.GC.collect() ensureWeakIs(it, null) } while (semaphore.value != 1) {} stableHolder1.dispose() kotlin.native.internal.GC.collect() semaphore.increment() future.result worker.requestTermination().result } val stableHolder2 = StableRef.create(("hello" to "world").freeze()) @Test fun runTest5() { val worker = Worker.start() semaphore.value = 0 val future = worker.execute(TransferMode.SAFE, { WeakReference(stableHolder2.get()) }) { val value = it.get() semaphore.increment() while (semaphore.value != 2) {} kotlin.native.internal.GC.collect() assertEquals("hello" to "world", value) } while (semaphore.value != 1) {} stableHolder2.dispose() kotlin.native.internal.GC.collect() semaphore.increment() future.result worker.requestTermination().result } val atomicRef2 = AtomicReference(Any().freeze()) @Test fun runTest6() { semaphore.value = 0 val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { null }) { val value = atomicRef2.compareAndSwap(null, null) semaphore.increment() while (semaphore.value != 2) {} assertEquals(true, value.toString() != "") } while (semaphore.value != 1) {} atomicRef2.value = null kotlin.native.internal.GC.collect() semaphore.increment() future.result worker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/workers/worker11.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker11 import kotlin.test.* import kotlin.native.concurrent.* import kotlinx.cinterop.convert data class Job(val index: Int, var input: Int, var counter: Int) fun initJobs(count: Int) = Array(count) { i -> Job(i, i * 2, i)} @Test fun runTest0() { val workers = Array(100, { _ -> Worker.start() }) val jobs = initJobs(workers.size) val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { val job = jobs[workerIndex] jobs[workerIndex] = null job!! }) { job -> job.counter += job.input job } }) val futureSet = futures.toSet() var consumed = 0 while (consumed < futureSet.size) { val ready = waitForMultipleFutures(futureSet, 10000) ready.forEach { it.consume { job -> assertEquals(job.index * 3, job.counter) jobs[job.index] = job } consumed++ } } assertEquals(consumed, workers.size) workers.forEach { it.requestTermination().result } println("OK") } val COUNT = 2 @SharedImmutable val counters = Array(COUNT) { AtomicInt(0) } @Test fun runTest1() { val workers = Array(COUNT) { Worker.start() } // Ensure processQueue() can only be called on current Worker. workers.forEach { assertFailsWith { it.processQueue() } } val futures = Array(workers.size) { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { workerIndex }) { index -> assertEquals(0, counters[index].value) // Process following request. while (!Worker.current!!.processQueue()) {} // Ensure it has an effect. assertEquals(1, counters[index].value) // No more non-terminating tasks in this worker queue. assertEquals(false, Worker.current!!.processQueue()) } } val futures2 = Array(workers.size) { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { workerIndex }) { index -> assertEquals(0, counters[index].value) counters[index].increment() } } futures2.forEach { it.result } futures.forEach { it.result } workers.forEach { it.requestTermination().result } // Ensure terminated workers are no longer there. workers.forEach { assertFailsWith { it.execute(TransferMode.SAFE, { Unit }) { println("ERROR") } } } } @Test fun runTest2() { val workers = Array(COUNT) { Worker.start() } val futures = Array(workers.size) { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { null }) { // Here we processed termination request. assertEquals(false, Worker.current.processQueue()) } } workers.forEach { it.executeAfter(1000*1000*1000, { println("DELAY EXECUTED") assert(false) }.freeze()) } workers.forEach { it.requestTermination(processScheduledJobs = false).result } // Process futures, ignoring possible cancelled ones. futures.forEach { try { it.result } catch (e: IllegalStateException) {} } } ================================================ FILE: backend.native/tests/runtime/workers/worker2.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker2 import kotlin.test.* import kotlin.native.concurrent.* data class WorkerArgument(val intParam: Int, val stringParam: String) data class WorkerResult(val intResult: Int, val stringResult: String) @Test fun runTest() { val COUNT = 5 val workers = Array(COUNT, { _ -> Worker.start()}) for (attempt in 1 .. 3) { val futures = Array(workers.size, { workerIndex -> workers[workerIndex].execute(TransferMode.SAFE, { WorkerArgument(workerIndex, "attempt $attempt") }) { input -> var sum = 0 for (i in 0..input.intParam * 1000) { sum += i } WorkerResult(sum, input.stringParam + " result") } }) val futureSet = futures.toSet() var consumed = 0 while (consumed < futureSet.size) { val ready = waitForMultipleFutures(futureSet, 10000) ready.forEach { it.consume { result -> if (result.stringResult != "attempt $attempt result") throw Error("Unexpected $result") consumed++ } } } } workers.forEach { it.requestTermination().result } println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker3.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker3 import kotlin.test.* import kotlin.native.concurrent.* data class DataParam(var int: Int) data class WorkerArgument(val intParam: Int, val dataParam: DataParam) data class WorkerResult(val intResult: Int, val stringResult: String) @Test fun runTest() { main(emptyArray()) } fun main(args: Array) { val worker = Worker.start() val dataParam = DataParam(17) val future = try { worker.execute(TransferMode.SAFE, { WorkerArgument(42, dataParam) }) { input -> WorkerResult(input.intParam, input.dataParam.toString() + " result") } } catch (e: IllegalStateException) { null } if (future != null && Platform.memoryModel == MemoryModel.STRICT) println("Fail 1") if (dataParam.int != 17) println("Fail 2") worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker4.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker4 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest1() { withWorker { val future = execute(TransferMode.SAFE, { 41 }) { input -> input + 1 } future.consume { result -> println("Got $result") } } println("OK") } @Test fun runTest2() { withWorker { val counter = AtomicInt(0) executeAfter(0, { assertTrue(Worker.current.park(10_000_000, false)) assertEquals(counter.value, 0) assertTrue(Worker.current.processQueue()) assertEquals(1, counter.value) // Let main proceed. counter.increment() // counter becomes 2 here. assertTrue(Worker.current.park(10_000_000, true)) assertEquals(3, counter.value) }.freeze()) executeAfter(0, { counter.increment() }.freeze()) while (counter.value < 2) { Worker.current.park(1_000) } executeAfter(0, { counter.increment() }.freeze()) while (counter.value == 2) { Worker.current.park(1_000) } } } @Test fun runTest3() { val worker = Worker.start(name = "Lumberjack") val counter = AtomicInt(0) worker.executeAfter(0, { assertEquals("Lumberjack", Worker.current.name) counter.increment() }.freeze()) while (counter.value == 0) { Worker.current.park(1_000) } assertEquals("Lumberjack", worker.name) worker.requestTermination().result assertFailsWith { println(worker.name) } } @Test fun runTest4() { val counter = AtomicInt(0) Worker.current.executeAfter(10_000, { counter.increment() }.freeze()) assertTrue(Worker.current.park(1_000_000, process = true)) assertEquals(1, counter.value) } @Test fun runTest5() { val main = Worker.current val counter = AtomicInt(0) withWorker { executeAfter(1000, { main.executeAfter(1, { counter.increment() }.freeze()) }.freeze()) assertTrue(main.park(1000L * 1000 * 1000, process = true)) assertEquals(1, counter.value) } } @Test fun runTest6() { // Ensure zero timeout works properly. Worker.current.park(0, process = true) } @Test fun runTest7() { val counter = AtomicInt(0) withWorker { val f1 = execute(TransferMode.SAFE, { counter }) { counter -> Worker.current.park(Long.MAX_VALUE / 1000L, process = true) counter.increment() } // wait a bit Worker.current.park(10_000L) // submit a task val f2 = execute(TransferMode.SAFE, { counter }) { counter -> counter.increment() } f1.consume {} f2.consume {} assertEquals(2, counter.value) } } ================================================ FILE: backend.native/tests/runtime/workers/worker5.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest0() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { "zzz" }) { input -> input.length } future.consume { result -> println("Got $result") } worker.requestTermination().result println("OK") } var done = false @Test fun runTest1() { val worker = Worker.current done = false // Here we request execution of the operation on the current worker. worker.executeAfter(0, { done = true }.freeze()) while (!done) worker.processQueue() } // Ensure that termination of current worker on main thread doesn't lead to problems. @Test fun runTest2() { val worker = Worker.current val future = worker.requestTermination(false) worker.processQueue() assertEquals(future.state, FutureState.COMPUTED) future.consume {} // After termination request this worker is no longer addressable. assertFailsWith { worker.executeAfter(0, { println("BUG!") }.freeze()) } } fun main() { runTest0() runTest1() runTest2() } ================================================ FILE: backend.native/tests/runtime/workers/worker6.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker6 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest1() { withWorker { val future = execute(TransferMode.SAFE, { 42 }) { input -> input.toString() } future.consume { result -> println("Got $result") } } println("OK") } var int1 = 1 val int2 = 77 @Test fun runTest2() { int1++ withWorker { executeAfter(0, { assertFailsWith { int1++ } assertEquals(2, int1) assertEquals(77, int2) }.freeze()) } } ================================================ FILE: backend.native/tests/runtime/workers/worker7.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker7 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest() { val worker = Worker.start(false) val future = worker.execute(TransferMode.SAFE, { "Input" }) { input -> println(input) } future.consume { result -> println("Got $result") } assertFailsWith { println(worker.execute(TransferMode.SAFE, { null }, { _ -> throw Error("An error") }).result) } worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker8.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker8 import kotlin.test.* import kotlin.native.concurrent.* data class SharedDataMember(val double: Double) data class SharedData(val string: String, val int: Int, val member: SharedDataMember) @Test fun runTest() { val worker = Worker.start() // Here we do rather strange thing. To test object detach API we detach object graph, // pass detached graph to a worker, where we manually reattached passed value. val future = worker.execute(TransferMode.SAFE, { DetachedObjectGraph { SharedData("Hello", 10, SharedDataMember(0.1)) }.asCPointer() }) { inputDetached -> val input = DetachedObjectGraph(inputDetached).attach() println(input) } future.consume { result -> println("Got $result") } worker.requestTermination().result println("OK") } ================================================ FILE: backend.native/tests/runtime/workers/worker9.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package runtime.workers.worker9 import kotlin.test.* import kotlin.native.concurrent.* @Test fun runTest1() { withLock { println("zzz") } val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { withLock { println("42") } } future.result worker.requestTermination().result println("OK") } fun withLock(op: () -> Unit) { op() } @Test fun runTest2() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, {}) { val me = Worker.current var x = 1 me.executeAfter (20000) { println("second ${++x}") } me.executeAfter(10000) { println("first ${++x}") } } worker.requestTermination().result } @Test fun runTest3() { val worker = Worker.start() assertFailsWith { worker.executeAfter { println("shall not happen") } } assertFailsWith { worker.executeAfter(-1, { println("shall not happen") }.freeze()) } worker.executeAfter(0, { println("frozen OK") }.freeze()) worker.requestTermination().result } class Node(var node: Node?, var outher: Node?) fun makeCyclic(): Node { val inner = Node(null, null) inner.node = inner val outer = Node(null, null) inner.outher = outer return outer } @Test fun runTest4() { val worker = Worker.start() val future = worker.execute(TransferMode.SAFE, { }) { makeCyclic().also { kotlin.native.internal.GC.collect() } } assert(future.result != null) worker.requestTermination().result } ================================================ FILE: backend.native/tests/runtime/workers/worker_threadlocal_no_leak.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.native.concurrent.* import kotlin.native.Platform @ThreadLocal var x = Any() fun main() { Platform.isMemoryLeakCheckerActive = true val worker = Worker.start() worker.execute(TransferMode.SAFE, {}) { println(x) // Make sure x is initialized }.result worker.requestTermination().result } ================================================ FILE: backend.native/tests/serialization/catch.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ inline fun foo() { try { try { throw Exception("XXX") } catch (e: Throwable) { println("Gotcha1: ${e.message}") throw Exception("YYY") } } catch (e: Throwable) { println("Gotcha2: ${e.message}") } } ================================================ FILE: backend.native/tests/serialization/char_const.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ inline fun foo(x: Char = '\u042b') = x ================================================ FILE: backend.native/tests/serialization/default_args.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ inline val Int.prop get() = SomeDataClass(second = this) data class SomeDataClass(val first: Int = 17, val second: Int = 19, val third: Int = 23) ================================================ FILE: backend.native/tests/serialization/deserialize_members.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import foo.bar.* fun main(args: Array) { val c = C() val d = C.D() val e = C.D.E() c.foo() d.foo() e.foo() val c2 = C2() val d2 = C2().D2() val e2 = C2().D2().E2() c2.foo() d2.foo() e2.foo() val c3 = C3() val d3 = C3.D3() val e3 = C3.D3.E3() c3.foo(13) d3.foo("cha-cha-cha") e3.foo(1.0f) // This part doesn't work with file local inline functions. // So disabled for now. // val c4 = C4() // val d4 = C4().D4() // val e4 = C4().D4().E4() // c4.foo(13) // d4.foo("cawabunga", 17) // e4.foo(19, "raqa-taqa", 23) } ================================================ FILE: backend.native/tests/serialization/deserialized_fields.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package serialization.deserialized_fields import kotlin.test.* class CustomThrowable(val extraInfo: String): Throwable("Some message", null) @Test fun runTest() { val custom = CustomThrowable("Extra info") assertEquals(custom.extraInfo, "Extra info") assertEquals(custom.message, "Some message") assertEquals(custom.cause, null) } ================================================ FILE: backend.native/tests/serialization/deserialized_inline0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package serialization.deserialized_inline0 import kotlin.test.* fun inline_todo() { try { TODO("OK") } catch (e: Throwable) { println(e.message) } } fun inline_maxof() { println(maxOf(10, 17)) println(maxOf(17, 13)) println(maxOf(17, 17)) } fun inline_assert() { //assert(true) } @Test fun runTest() { inline_todo() inline_assert() inline_maxof() } ================================================ FILE: backend.native/tests/serialization/deserialized_listof0.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package serialization.deserialized_listof0 import kotlin.test.* fun test_arrayList() { val l = listOf(1, 2, 3) val m = listOf() val n = l + m println(n) } fun test_arrayList2(x: T, y: T, z: T) { val l = listOf(x, y, z) val m = listOf() val n = m + l println(l) } fun test_arrayList3() { val l = listOf() val m = listOf("a", "b", "c") val n = l + m println(n) } @Test fun runTest() { test_arrayList() test_arrayList2(5, 6, 7) test_arrayList2("a", "b", "c") test_arrayList3() } ================================================ FILE: backend.native/tests/serialization/do_while.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ inline fun foo() { do { var x: Int = 999 println(x) } while (x != 999) } ================================================ FILE: backend.native/tests/serialization/enum_ordinal/library.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ enum class Color { RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW } fun determineColor(code: Int): Color = when (code) { 0 -> Color.BLUE 1 -> Color.MAGENTA else -> Color.CYAN } ================================================ FILE: backend.native/tests/serialization/enum_ordinal/main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { println(Color.RED.ordinal) println(Color.GREEN.ordinal) println(Color.BLUE.ordinal) val color = when (determineColor(args.size)) { Color.RED -> println("r") Color.GREEN -> println("g") Color.BLUE -> println("b") Color.CYAN -> println("c") Color.MAGENTA -> println("m") Color.YELLOW -> println("y") } } ================================================ FILE: backend.native/tests/serialization/prop.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { println(666.prop) } ================================================ FILE: backend.native/tests/serialization/regression/no_type_map.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cinterop.* fun main(args: Array) { memScoped { val bufferLength = 100L val buffer = allocArray(bufferLength) } println("OK") } ================================================ FILE: backend.native/tests/serialization/serialize_members.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package foo.bar class R { inline fun bar(t: T) { println("just a single class: $t") } } class C { inline fun foo() { println("first level") } class D { inline fun foo() { println("second level") } class E { inline fun foo() { println("third levelxz") } } } } class C2 { inline fun foo() { println("inner first level") } inner class D2 { inline fun foo() { println("inner second level") } inner class E2 { inline fun foo() { println("inner third level") } } } } class C3 { inline fun foo(x: X) { println("types first level: $x") } class D3 { inline fun foo(x: X) { println("types second level $x") } class E3 { inline fun foo(x: X) { println("types third level $x") } } } } class C4 { inline fun foo(x: X) { println("inner types first level: $x") } inner class D4 { inline fun foo(x: X, y: Y) { println("inner types second level $x, $y") } inner class E4 { inline fun foo(x: X, y: Y, z: Z) { println("inner types third level $x, $y, $z") } } } } ================================================ FILE: backend.native/tests/serialization/use.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { foo() } ================================================ FILE: backend.native/tests/serialization/use_char_const.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun main(args: Array) { println(foo()) } ================================================ FILE: backend.native/tests/serialization/vararg.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ fun bar(vararg x: Int) { x.forEach { println(it) } println("size: ${x.size}") } inline fun foo() = bar(17, 19, 23, *intArrayOf(29, 31)) ================================================ FILE: backend.native/tests/stdlib_external/collections/KT42428Test.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package test.collections import kotlin.test.* // TODO: consider moving to common stdlib tests. class KT42428Test { private val listOfLetterIndexPairs = ('a'..'z').withIndex().map { (i, c) -> "$c" to i } private val mapOfLetterToIndex = listOfLetterIndexPairs.toMap() @Test fun testListOfPairsToMapEntriesContainsMapEntry() { testMapEntriesContainsMapEntry(listOfLetterIndexPairs.toMap(), "h", 7) } @Test fun testMapToMutableMapEntriesContainsMapEntry() { testMapEntriesContainsMapEntry(mapOfLetterToIndex.toMutableMap(), "h", 7) } @Test fun testHashMapEntriesContainsMapEntry() { testMapEntriesContainsMapEntry(HashMap(mapOfLetterToIndex), "h", 7) } @Test fun testLinkedHashMapEntriesContainsMapEntry() { testMapEntriesContainsMapEntry(LinkedHashMap(mapOfLetterToIndex), "h", 7) } // Based on https://youtrack.jetbrains.com/issue/KT-42428. private fun testMapEntriesContainsMapEntry(map: Map, key: String, value: Int) { data class SimpleEntry(override val key: K, override val value: V) : Map.Entry { override fun equals(other: Any?): Boolean = other is Map.Entry<*, *> && key == other.key && value == other.value override fun hashCode(): Int = key.hashCode() xor value.hashCode() override fun toString(): String = "$key=$value" } assertTrue(map.keys.contains(key)) // This one requires special efforts to make it work this way. // map.entries can in fact be `MutableSet`, // which [contains] method takes [MutableEntry], so the compiler may generate special bridge // returning false for values that aren't [MutableEntry] (including [SimpleEntry]). assertTrue(map.entries.contains(SimpleEntry(key, value))) assertTrue(map.entries.toSet().contains(SimpleEntry(key, value))) } } ================================================ FILE: backend.native/tests/stdlib_external/jsCollectionFactoriesActuals.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test.collections.js actual fun stringMapOf(vararg pairs: Pair): HashMap = hashMapOf(*pairs) actual fun linkedStringMapOf(vararg pairs: Pair): LinkedHashMap = linkedMapOf(*pairs) actual fun stringSetOf(vararg elements: String): HashSet = hashSetOf(*elements) actual fun linkedStringSetOf(vararg elements: String): LinkedHashSet = linkedSetOf(*elements) ================================================ FILE: backend.native/tests/stdlib_external/numbers/HarmonyMathTests.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package test.numbers.harmony_math import kotlin.math.* import kotlin.test.* class HarmonyMath { fun assertEquals(expected: Double, actual: Double, tolerance: Double? = null) = assertEquals(null, expected, actual, tolerance) fun assertEquals(expected: Float, actual: Float, tolerance: Float? = null) = assertEquals(null, expected, actual, tolerance) fun Double.Companion.isNaN(v: Double) = v.isNaN() fun Float.Companion.isNaN(v: Float) = v.isNaN() fun pow(a: Double, b: Double) = a.pow(b) fun pow(a: Float, b: Float) = a.pow(b) fun ulp(v: Double) = v.ulp fun ulp(v: Float) = v.ulp fun assertEquals(message: String?, expected: Int, actual: Int) = assertEquals(expected, actual, message) fun assertEquals(message: String?, expected: Long, actual: Long) = assertEquals(expected, actual, message) fun assertEquals(message: String?, expected: Double, actual: Double, tolerance: Double? = null) { val tolerance_ = tolerance?.let { abs(it) } ?: 0.000000000001 if (abs(expected - actual) > tolerance_) { assertEquals(expected, actual, message) } } fun assertEquals(message: String?, expected: Float, actual: Float, tolerance: Float? = null) { val tolerance_ = tolerance?.let { abs(it) } ?: 0.0000001f if (abs(expected - actual) > tolerance_) { assertEquals(expected, actual, message) } } fun assertTrue(message: String? = null, condition: Boolean) = assertTrue(condition, message) internal var HYP = sqrt(2.0) internal var OPP = 1.0 internal var ADJ = 1.0 /* Required to make previous preprocessor flags work - do not remove */ internal var unused = 0 /** * Tests kotlin.math.abs(Double) */ @Test fun absD() { // Test for abs(Double): Double assertTrue("Incorrect Double abs value", abs(-1908.8976) == 1908.8976) assertTrue("Incorrect Double abs value", abs(1908.8976) == 1908.8976) } /** * Tests kotlin.math.abs(float) */ @Test fun absF() { // Test for abs(float): float assertTrue("Incorrect float abs value", abs(-1908.8976f) == 1908.8976f) assertTrue("Incorrect float abs value", abs(1908.8976f) == 1908.8976f) } /** * Tests kotlin.math.abs(int) */ @Test fun absI() { // Test for abs(int): int assertTrue("Incorrect int abs value", abs(-1908897) == 1908897) assertTrue("Incorrect int abs value", abs(1908897) == 1908897) } /** * Tests kotlin.math.abs(long) */ @Test fun absJ() { // Test for abs(long): long assertTrue("Incorrect long abs value", abs(-19088976000089L) == 19088976000089L) assertTrue("Incorrect long abs value", abs(19088976000089L) == 19088976000089L) } /** * Tests kotlin.math.acos(Double) */ @Test fun acosD() { // Test for acos(Double): Double val r = cos(acos(ADJ / HYP)) val lr = r.toBits() val t = (ADJ / HYP).toBits() assertTrue("Returned incorrect arc cosine", lr == t || lr + 1 == t || lr - 1 == t) } /** * Tests kotlin.math.asin(Double) */ @Test fun asinD() { // Test for asin(Double): Double val r = sin(asin(OPP / HYP)) val lr = r.toBits() val t = (OPP / HYP).toBits() assertTrue("Returned incorrect arc sine", lr == t || lr + 1 == t || lr - 1 == t) } /** * Tests kotlin.math.atan(Double) */ @Test fun atanD() { // Test for atan(Double): Double val answer = tan(atan(1.0)) assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0 && answer >= 9.9999999999999983E-1) } /** * Tests kotlin.math.atan2(Double, Double) */ @Test fun atan2DD() { // Test for atan2(Double, Double): Double val answer = atan(tan(1.0)) assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0 && answer >= 9.9999999999999983E-1) } /** * Tests kotlin.math.ceil(Double) */ @Test fun ceilD() { // Test for ceil(Double): Double assertEquals("Incorrect ceiling for Double", 79.0, ceil(78.89), 0.0) assertEquals("Incorrect ceiling for Double", -78.0, ceil(-78.89), 0.0) } /** * Tests kotlin.math.withSign(Double) */ @Test fun withSign_D() { for (i in COPYSIGN_DD_CASES.indices) { val magnitude = COPYSIGN_DD_CASES[i] val absMagnitudeBits = abs(magnitude).toBits() val negMagnitudeBits = (-abs(magnitude)).toBits() assertTrue("The result should be NaN.", Double.isNaN(Double.NaN.withSign(magnitude))) for (j in COPYSIGN_DD_CASES.indices) { val sign = COPYSIGN_DD_CASES[j] val resultBits = magnitude.withSign(sign).toBits() if (sign > 0 || (+0.0).toBits() == sign.toBits() || 0.0.toBits() == sign.toBits()) { assertEquals( "If the sign is positive, the result should be positive.", absMagnitudeBits, resultBits) } if (sign < 0 || (-0.0).toBits() == sign.toBits()) { assertEquals( "If the sign is negative, the result should be negative.", negMagnitudeBits, resultBits) } } } assertTrue("The result should be NaN.", Double.isNaN(Double.NaN.withSign(Double.NaN))) } /** * Tests kotlin.math.withSign(Float) */ @Test fun withSign_F() { for (i in COPYSIGN_FF_CASES.indices) { val magnitude = COPYSIGN_FF_CASES[i] val absMagnitudeBits = abs(magnitude).toBits() val negMagnitudeBits = (-abs(magnitude)).toBits() assertTrue("The result should be NaN.", Float.isNaN(Float.NaN.withSign(magnitude))) for (j in COPYSIGN_FF_CASES.indices) { val sign = COPYSIGN_FF_CASES[j] val resultBits = magnitude.withSign(sign).toBits() if (sign > 0 || (+0.0f).toBits() == sign.toBits() || 0.0f.toBits() == sign.toBits()) { assertEquals( "If the sign is positive, the result should be positive.", absMagnitudeBits, resultBits) } if (sign < 0 || (-0.0f).toBits() == sign.toBits()) { assertEquals( "If the sign is negative, the result should be negative.", negMagnitudeBits, resultBits) } } } assertTrue("The result should be NaN.", Float.isNaN(Float.NaN.withSign(Float.NaN))) } /** * Tests kotlin.math.cos(Double) */ @Test fun cosD() { // Test for cos(Double): Double assertEquals("Incorrect answer", 1.0, cos(0.0), 0.0) assertEquals("Incorrect answer", 0.5403023058681398, cos(1.0), 0.0) } /** * Tests kotlin.math.cosh(Double) */ @Test fun cosh_D() { // Test for special situations assertTrue(Double.isNaN(cosh(Double.NaN))) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, cosh(Double.POSITIVE_INFINITY), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, cosh(Double.NEGATIVE_INFINITY), 0.0) assertEquals("Should return 1.0", 1.0, cosh(+0.0), 0.0) assertEquals("Should return 1.0", 1.0, cosh(-0.0), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, cosh(1234.56), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, cosh(-1234.56), 0.0) assertEquals("Should return 1.0000000000005", 1.0000000000005, cosh(0.000001), 0.0) assertEquals("Should return 1.0000000000005", 1.0000000000005, cosh(-0.000001), 0.0) assertEquals("Should return 5.212214351945598", 5.212214351945598, cosh(2.33482), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, cosh(Double.MAX_VALUE), 0.0) assertEquals("Should return 1.0", 1.0, cosh(Double.MIN_VALUE), 0.0) } /** * Tests kotlin.math.exp(Double) */ @Test fun expD() { // Test for exp(Double): Double assertTrue("Incorrect answer returned for simple power", abs(exp(4.0) - E * E * E * E) < 0.1) assertTrue("Incorrect answer returned for larger power", ln(abs(exp(5.5)) - 5.5) < 10.0) } /** * Tests kotlin.math.expm1(Double) */ @Test fun expm1_D() { // Test for special cases assertTrue("Should return NaN", Double.isNaN(expm1(Double.NaN))) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, expm1(Double.POSITIVE_INFINITY), 0.0) assertEquals("Should return -1.0", -1.0, expm1(Double.NEGATIVE_INFINITY), 0.0) assertEquals(0.0.toBits(), expm1(0.0).toBits()) assertEquals(+0.0.toBits(), expm1(+0.0).toBits()) assertEquals((-0.0).toBits(), expm1(-0.0).toBits()) assertEquals("Should return -9.999950000166666E-6", -9.999950000166666E-6, expm1(-0.00001)) assertEquals("Should return 1.0145103074469635E60", 1.0145103074469635E60, expm1(138.16951162), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, expm1(123456789123456789123456789.4521584223), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, expm1(Double.MAX_VALUE), 0.0) assertEquals("Should return MIN_VALUE", Double.MIN_VALUE, expm1(Double.MIN_VALUE), 0.0) } /** * Tests kotlin.math.floor(Double) */ @Test fun floorD() { assertEquals("Incorrect floor for int", 42.0, floor(42.0), 0.0) assertEquals("Incorrect floor for -int", -2.0, floor(-2.0), 0.0) assertEquals("Incorrect floor for zero", 0.0, floor(0.0), 0.0) assertEquals("Incorrect floor for +Double", 78.0, floor(78.89), 0.0) assertEquals("Incorrect floor for -Double", -79.0, floor(-78.89), 0.0) assertEquals("floor large +Double", 3.7314645675925406E19, floor(3.7314645675925406E19), 0.0) assertEquals("floor large -Double", -8.173521839218E12, floor(-8.173521839218E12), 0.0) assertEquals("floor small Double", 0.0, floor(1.11895241315E-102), 0.0) // Compare toString representations here since -0.0 = +0.0, and // NaN != NaN and we need to distinguish assertEquals(Double.NaN.toString(), floor(Double.NaN).toString(), "Floor failed for NaN") assertEquals((+0.0).toString(), floor(+0.0).toString(), "Floor failed for +0.0") assertEquals((-0.0).toString(), floor(-0.0).toString(), "Floor failed for -0.0") assertEquals(Double.POSITIVE_INFINITY.toString(), floor(Double.POSITIVE_INFINITY).toString(), "Floor failed for +infinity") assertEquals(Double.NEGATIVE_INFINITY.toString(), floor(Double.NEGATIVE_INFINITY).toString(), "Floor failed for -infinity") } /** * Tests kotlin.math.hypot(Double, Double) */ @Test fun hypot_DD() { // Test for special cases assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(Double.POSITIVE_INFINITY, 1.0), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, 123.324), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(-758.2587, Double.POSITIVE_INFINITY), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(5687.21, Double.NEGATIVE_INFINITY), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), 0.0) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), 0.0) assertTrue("Should be NaN", Double.isNaN(hypot(Double.NaN, 2342301.89843))) assertTrue("Should be NaN", Double.isNaN(hypot(-345.2680, Double.NaN))) assertEquals("Should return 2396424.905416697", 2396424.905416697, hypot(12322.12, -2396393.2258), 0.0) assertEquals("Should return 138.16958070558556", 138.16958070558556, hypot(-138.16951162, 0.13817035864), 0.0) assertEquals("Should return 1.7976931348623157E308", 1.7976931348623157E308, hypot(Double.MAX_VALUE, 211370.35), 0.0) assertEquals("Should return 5413.7185", 5413.7185, hypot( -5413.7185, Double.MIN_VALUE), 0.0) } /** * Tests kotlin.math.IEEEremainder(Double, Double) */ @Test fun IEEEremainderDD() { // Test for IEEEremainder(Double, Double): Double assertEquals("Incorrect remainder returned", 0.0, 1.0.IEEErem(1.0), 0.0) assertTrue("Incorrect remainder returned", 1.32.IEEErem(89.765) >= 1.4705063220631647E-2 || 1.32.IEEErem(89.765) >= 1.4705063220631649E-2) } /** * Tests kotlin.math.ln(Double) */ @Test fun lnD() { // Test for log(Double): Double var d = 10.0 while (d >= -10) { val answer = ln(exp(d)) assertTrue("Answer does not equal expected answer for d = " + d + " answer = " + answer, abs(answer - d) <= abs(d * 0.00000001)) d -= 0.5 } } /** * Tests kotlin.math.log10(Double) */ @Test fun log10_D() { // Test for special cases assertTrue(Double.isNaN(log10(Double.NaN))) assertTrue(Double.isNaN(log10(-2541.05745687234187532))) assertTrue(Double.isNaN(log10(-0.1))) assertEquals(Double.POSITIVE_INFINITY, log10(Double.POSITIVE_INFINITY)) assertEquals(Double.NEGATIVE_INFINITY, log10(0.0)) assertEquals(Double.NEGATIVE_INFINITY, log10(+0.0)) assertEquals(Double.NEGATIVE_INFINITY, log10(-0.0)) assertEquals(3.0, log10(1000.0)) assertEquals(14.0, log10(10.0.pow(14.0))) assertEquals(3.7389561269540406, log10(5482.2158)) assertEquals(14.661551142893833, log10(458723662312872.125782332587)) assertEquals(-0.9083828622192334, log10(0.12348583358871)) assertEquals(308.25471555991675, log10(Double.MAX_VALUE)) assertEquals(-323.3062153431158, log10(Double.MIN_VALUE)) } /** * Tests kotlin.math.ln1p(Double) */ @Test fun ln1p_D() { // Test for special cases assertTrue("Should return NaN", Double.isNaN(ln1p(Double.NaN))) assertTrue("Should return NaN", Double.isNaN(ln1p(-32.0482175))) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, ln1p(Double.POSITIVE_INFINITY), 0.0) assertEquals(0.0.toBits(), ln1p(0.0).toBits()) assertEquals(+0.0.toBits(), ln1p(+0.0).toBits()) assertEquals((-0.0).toBits(), ln1p(-0.0).toBits()) assertEquals("Should return -0.2941782295312541", -0.2941782295312541, ln1p(-0.254856327), 0.0) assertEquals("Should return 7.368050685564151", 7.368050685564151, ln1p(1583.542), 0.0) assertEquals("Should return 0.4633708685409921", 0.4633708685409921, ln1p(0.5894227), 0.0) assertEquals("Should return 709.782712893384", 709.782712893384, ln1p(Double.MAX_VALUE), 0.0) assertEquals("Should return Double.MIN_VALUE", Double.MIN_VALUE, ln1p(Double.MIN_VALUE), 0.0) } /** * Tests kotlin.math.max(Double, Double) */ @Test fun maxDD() { // Test for max(Double, Double): Double assertEquals("Incorrect Double max value", 1908897.6000089, max(-1908897.6000089, 1908897.6000089), 0.0) assertEquals("Incorrect Double max value", 1908897.6000089, max(2.0, 1908897.6000089), 0.0) assertEquals("Incorrect Double max value", -2.0, max(-2.0, -1908897.6000089), 0.0) // Compare toString representations here since -0.0 = +0.0, and // NaN != NaN and we need to distinguish assertEquals((Double.NaN).toString(), max(Double.NaN, 42.0).toString(), "Max failed for NaN") assertEquals((Double.NaN).toString(), max(42.0, Double.NaN).toString(), "Max failed for NaN") assertEquals((+0.0).toString(), max(+0.0, -0.0).toString(), "Max failed for 0.0") assertEquals((+0.0).toString(), max(-0.0, +0.0).toString(), "Max failed for 0.0") assertEquals((-0.0).toString(), max(-0.0, -0.0).toString(), "Max failed for -0.0d") assertEquals((+0.0).toString(), max(+0.0, +0.0).toString(), "Max failed for 0.0") } /** * Tests kotlin.math.max(float, float) */ @Test fun maxFF() { // Test for max(float, float): float assertTrue("Incorrect float max value", max(-1908897.600f, 1908897.600f) == 1908897.600f) assertTrue("Incorrect float max value", max(2.0f, 1908897.600f) == 1908897.600f) assertTrue("Incorrect float max value", max(-2.0f, -1908897.600f) == -2.0f) // Compare toString representations here since -0.0 = +0.0, and // NaN != NaN and we need to distinguish assertEquals(Float.NaN.toString(), max(Float.NaN, 42.0f).toString(), "Max failed for NaN") assertEquals(Float.NaN.toString(), max(42.0f, Float.NaN).toString(), "Max failed for NaN") assertEquals((+0.0f).toString(), max(+0.0f, -0.0f).toString(), "Max failed for 0.0") assertEquals((+0.0f).toString(), max(-0.0f, +0.0f).toString(), "Max failed for 0.0") assertEquals((-0.0f).toString(), max(-0.0f, -0.0f).toString(), "Max failed for -0.0f") assertEquals((+0.0f).toString(), max(+0.0f, +0.0f).toString(), "Max failed for 0.0") } /** * Tests kotlin.math.max(int, int) */ @Test fun maxII() { // Test for max(int, int): int assertEquals("Incorrect int max value", 19088976, max(-19088976, 19088976)) assertEquals("Incorrect int max value", 19088976, max(20, 19088976)) assertEquals("Incorrect int max value", -20, max(-20, -19088976)) } /** * Tests kotlin.math.max(long, long) */ @Test fun maxJJ() { // Test for max(long, long): long assertEquals("Incorrect long max value", 19088976000089L, max(-19088976000089L, 19088976000089L)) assertEquals("Incorrect long max value", 19088976000089L, max(20, 19088976000089L)) assertEquals("Incorrect long max value", -20, max(-20, -19088976000089L)) } /** * Tests kotlin.math.min(Double, Double) */ @Test fun minDD() { // Test for min(Double, Double): Double assertEquals("Incorrect Double min value", -1908897.6000089, min(-1908897.6000089, 1908897.6000089), 0.0) assertEquals("Incorrect Double min value", 2.0, min(2.0, 1908897.6000089), 0.0) assertEquals("Incorrect Double min value", -1908897.6000089, min(-2.0, -1908897.6000089), 0.0) assertEquals("Incorrect Double min value", 1.0, min(1.0, 1.0)) // Compare toString representations here since -0.0 = +0.0, and // NaN != NaN and we need to distinguish assertEquals(Double.NaN.toString(), min(Double.NaN, 42.0).toString(), "Min failed for NaN") assertEquals(Double.NaN.toString(), min(42.0, Double.NaN).toString(), "Min failed for NaN") assertEquals((-0.0).toString(), min(+0.0, -0.0).toString(), "Min failed for -0.0") assertEquals((-0.0).toString(), min(-0.0, +0.0).toString(), "Min failed for -0.0") assertEquals((-0.0).toString(), min(-0.0, -0.0).toString(), "Min failed for -0.0d") assertEquals((+0.0).toString(), min(+0.0, +0.0).toString(), "Min failed for 0.0") } /** * Tests kotlin.math.min(float, float) */ @Test fun minFF() { // Test for min(float, float): float assertTrue("Incorrect float min value", min(-1908897.600f, 1908897.600f) == -1908897.600f) assertTrue("Incorrect float min value", min(2.0f, 1908897.600f) == 2.0f) assertTrue("Incorrect float min value", min(-2.0f, -1908897.600f) == -1908897.600f) assertEquals("Incorrect float min value", 1.0f, min(1.0f, 1.0f)) // Compare toString representations here since -0.0 = +0.0, and // NaN != NaN and we need to distinguish assertEquals(Float.NaN.toString(), min(Float.NaN, 42.0f).toString(), "Min failed for NaN") assertEquals(Float.NaN.toString(), min(42.0f, Float.NaN).toString(), "Min failed for NaN") assertEquals((-0.0f).toString(), min(+0.0f, -0.0f).toString(), "Min failed for -0.0") assertEquals((-0.0f).toString(), min(-0.0f, +0.0f).toString(), "Min failed for -0.0") assertEquals((-0.0f).toString(), min(-0.0f, -0.0f).toString(), "Min failed for -0.0f") assertEquals((+0.0f).toString(), min(+0.0f, +0.0f).toString(), "Min failed for 0.0") } /** * Tests kotlin.math.min(int, int) */ @Test fun minII() { // Test for min(int, int): int assertEquals("Incorrect int min value", -19088976, min(-19088976, 19088976)) assertEquals("Incorrect int min value", 20, min(20, 19088976)) assertEquals("Incorrect int min value", -19088976, min(-20, -19088976)) } /** * @tests java.lang.Math#pow(double, double) */ fun test_powDD() { // Test for method double java.lang.Math.pow(double, double) assertTrue("pow returned incorrect value", 2.0.pow(8.0).toLong() == 256L) assertTrue("pow returned incorrect value", 2.0.pow(-8.0) == 0.00390625) assertEquals("Incorrect root returned1", 2.0, sqrt(sqrt(2.0).pow(4.0)), 0.0) } /** * Tests kotlin.math.round(Double) */ @Test fun roundD() { // Test for round(Double): Double assertEquals("Failed to round properly - up to odd", 3.0, round(2.9), 0.0) assertTrue("Failed to round properly - NaN", Double.isNaN(round(Double.NaN))) assertEquals("Failed to round properly down to even", 2.0, round(2.1), 0.0) assertTrue("Failed to round properly " + 2.5 + " to even", round(2.5) == 2.0) assertTrue("Failed to round properly " + +0.0, round(+0.0) == +0.0) assertTrue("Failed to round properly " + -0.0, round(-0.0) == -0.0) } /** * Tests kotlin.math.sign(Double) */ @Test fun sign_D() { assertTrue(Double.isNaN(sign(Double.NaN))) assertTrue(Double.isNaN(sign(Double.NaN))) assertEquals(0.0.toBits(), sign(0.0).toBits()) assertEquals(+0.0.toBits(), sign(+0.0).toBits()) assertEquals((-0.0).toBits(), sign(-0.0).toBits()) assertEquals(1.0, sign(253681.2187962), 0.0) assertEquals(-1.0, sign(-125874693.56), 0.0) assertEquals(1.0, sign(1.2587E-308), 0.0) assertEquals(-1.0, sign(-1.2587E-308), 0.0) assertEquals(1.0, sign(Double.MAX_VALUE), 0.0) assertEquals(1.0, sign(Double.MIN_VALUE), 0.0) assertEquals(-1.0, sign(-Double.MAX_VALUE), 0.0) assertEquals(-1.0, sign(-Double.MIN_VALUE), 0.0) assertEquals(1.0, sign(Double.POSITIVE_INFINITY), 0.0) assertEquals(-1.0, sign(Double.NEGATIVE_INFINITY), 0.0) } /** * Tests kotlin.math.sign(float) */ @Test fun sign_F() { assertTrue(Float.isNaN(sign(Float.NaN))) assertEquals(0.0f.toBits(), sign(0.0f).toBits()) assertEquals(+0.0f.toBits(), sign(+0.0f).toBits()) assertEquals((-0.0f).toBits(), sign(-0.0f).toBits()) assertEquals(1.0f, sign(253681.2187962f), 0f) assertEquals(-1.0f, sign(-125874693.56f), 0f) assertEquals(1.0f, sign(1.2587E-11f), 0f) assertEquals(-1.0f, sign(-1.2587E-11f), 0f) assertEquals(1.0f, sign(Float.MAX_VALUE), 0f) assertEquals(1.0f, sign(Float.MIN_VALUE), 0f) assertEquals(-1.0f, sign(-Float.MAX_VALUE), 0f) assertEquals(-1.0f, sign(-Float.MIN_VALUE), 0f) assertEquals(1.0f, sign(Float.POSITIVE_INFINITY), 0f) assertEquals(-1.0f, sign(Float.NEGATIVE_INFINITY), 0f) } /** * Tests kotlin.math.sin(Double) */ @Test fun sinD() { // Test for sin(Double): Double assertEquals("Incorrect answer", 0.0, sin(0.0), 0.0) assertEquals("Incorrect answer", 0.8414709848078965, sin(1.0), 0.0) } /** * Tests kotlin.math.sinh(Double) */ @Test fun sinh_D() { // Test for special situations assertTrue("Should return NaN", Double.isNaN(sinh(Double.NaN))) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, sinh(Double.POSITIVE_INFINITY), 0.0) assertEquals("Should return NEGATIVE_INFINITY", Double.NEGATIVE_INFINITY, sinh(Double.NEGATIVE_INFINITY), 0.0) assertEquals(0.0.toBits(), sinh(0.0).toBits()) assertEquals(+0.0.toBits(), sinh(+0.0).toBits()) assertEquals((-0.0).toBits(), sinh(-0.0).toBits()) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, sinh(1234.56), 0.0) assertEquals("Should return NEGATIVE_INFINITY", Double.NEGATIVE_INFINITY, sinh(-1234.56), 0.0) assertEquals("Should return 1.0000000000001666E-6", 1.0000000000001666E-6, sinh(0.000001), 0.0) assertEquals("Should return -1.0000000000001666E-6", -1.0000000000001666E-6, sinh(-0.000001), 0.0) assertEquals("Should return 5.115386441963859", 5.115386441963859, sinh(2.33482)) assertEquals("Should return POSITIVE_INFINITY", Double.POSITIVE_INFINITY, sinh(Double.MAX_VALUE), 0.0) assertEquals("Should return 4.9E-324", 4.9E-324, sinh(Double.MIN_VALUE), 0.0) } /** * Tests kotlin.math.sqrt(Double) */ @Test fun sqrt_D() { // Test for sqrt(Double): Double assertEquals("Incorrect root returned2", 7.0, sqrt(49.0), 0.0) } /** * Tests kotlin.math.tan(Double) */ @Test fun tan_D() { // Test for tan(Double): Double assertEquals("Incorrect answer", 0.0, tan(0.0), 0.0) assertEquals("Incorrect answer", 1.5574077246549023, tan(1.0)) } /** * Tests kotlin.math.tanh(Double) */ @Test fun tanh_D() { // Test for special situations assertTrue("Should return NaN", Double.isNaN(tanh(Double.NaN))) assertEquals("Should return +1.0", +1.0, tanh(Double.POSITIVE_INFINITY), 0.0) assertEquals("Should return -1.0", -1.0, tanh(Double.NEGATIVE_INFINITY), 0.0) assertEquals(0.0.toBits(), tanh(0.0).toBits()) assertEquals(+0.0.toBits(), tanh(+0.0).toBits()) assertEquals((-0.0).toBits(), tanh(-0.0).toBits()) assertEquals("Should return 1.0", 1.0, tanh(1234.56), 0.0) assertEquals("Should return -1.0", -1.0, tanh(-1234.56), 0.0) assertEquals("Should return 9.999999999996666E-7", 9.999999999996666E-7, tanh(0.000001), 0.0) assertEquals("Should return 0.981422884124941", 0.981422884124941, tanh(2.33482), 0.0) assertEquals("Should return 1.0", 1.0, tanh(Double.MAX_VALUE), 0.0) assertEquals("Should return 4.9E-324", 4.9E-324, tanh(Double.MIN_VALUE), 0.0) } /** * Tests kotlin.Double.ulp */ fun test_ulp_D() { // Test for special cases assertTrue("Should return NaN", Double.isNaN(ulp(Double.NaN))) assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, ulp(Double.POSITIVE_INFINITY), 0.0) assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, ulp(Double.NEGATIVE_INFINITY), 0.0) assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(0.0), 0.0) assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(+0.0), 0.0) assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(-0.0), 0.0) assertEquals("Returned incorrect value", pow(2.0, 971.0), ulp(Double.MAX_VALUE), 0.0) assertEquals("Returned incorrect value", pow(2.0, 971.0), ulp(-Double.MAX_VALUE), 0.0) assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(Double.MIN_VALUE), 0.0) assertEquals("Returned incorrect value", Double.MIN_VALUE, ulp(-Double.MIN_VALUE), 0.0) assertEquals("Returned incorrect value", 2.220446049250313E-16, ulp(1.0), 0.0) assertEquals("Returned incorrect value", 2.220446049250313E-16, ulp(-1.0), 0.0) assertEquals("Returned incorrect value", 2.2737367544323206E-13, ulp(1153.0), 0.0) } /** * Tests kotlin.Float.ulp */ fun test_ulp_f() { // Test for special cases assertTrue("Should return NaN", Float.isNaN(ulp(Float.NaN))) assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, ulp(Float.POSITIVE_INFINITY), 0f) assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, ulp(Float.NEGATIVE_INFINITY), 0f) assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(0.0f), 0f) assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(+0.0f), 0f) assertEquals("Returned incorrect value", Float.MIN_VALUE, ulp(-0.0f), 0f) assertEquals("Returned incorrect value", 2.028241E31f, ulp(Float.MAX_VALUE), 0f) assertEquals("Returned incorrect value", 2.028241E31f, ulp(-Float.MAX_VALUE), 0f) assertEquals("Returned incorrect value", 1.4E-45f, ulp(Float.MIN_VALUE), 0f) assertEquals("Returned incorrect value", 1.4E-45f, ulp(-Float.MIN_VALUE), 0f) assertEquals("Returned incorrect value", 1.1920929E-7f, ulp(1.0f), 0f) assertEquals("Returned incorrect value", 1.1920929E-7f, ulp(-1.0f), 0f) assertEquals("Returned incorrect value", 1.2207031E-4f, ulp(1153.0f), 0f) assertEquals("Returned incorrect value", 5.6E-45f, ulp(9.403954E-38f), 0f) } companion object { const val MIN_NORMAL_D: Double = 2.2250738585072014E-308 const val MIN_NORMAL_F: Float = 1.1754943508222875E-38f /** * cases for test_copySign_DD in est/Strictest */ internal val COPYSIGN_DD_CASES = doubleArrayOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, 3.4E302, 2.3, MIN_NORMAL_D, MIN_NORMAL_D / 2, Double.MIN_VALUE, +0.0, 0.0, -0.0, -Double.MIN_VALUE, -MIN_NORMAL_D / 2, -MIN_NORMAL_D, -4.5, -3.4E102, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY) /** * cases for test_copySign_FF in est/Strictest */ internal val COPYSIGN_FF_CASES = floatArrayOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE, 3.4E12f, 2.3f, MIN_NORMAL_F, MIN_NORMAL_F / 2, Float.MIN_VALUE, +0.0f, 0.0f, -0.0f, -Float.MIN_VALUE, -MIN_NORMAL_F / 2, -MIN_NORMAL_F, -4.5f, -5.6442E21f, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY) /** * start number cases for test_nextTowards_DD in est/Strictest * NEXTAFTER_DD_START_CASES[i][0] is the start number * NEXTAFTER_DD_START_CASES[i][1] is the nextUp of start number * NEXTAFTER_DD_START_CASES[i][2] is the nextDown of start number */ internal val NEXTAFTER_DD_START_CASES = arrayOf( doubleArrayOf(3.4, 3.4000000000000004, 3.3999999999999995), doubleArrayOf(-3.4, -3.3999999999999995, -3.4000000000000004), doubleArrayOf(3.4233E109, 3.4233000000000005E109, 3.4232999999999996E109), doubleArrayOf(-3.4233E109, -3.4232999999999996E109, -3.4233000000000005E109), doubleArrayOf(+0.0, Double.MIN_VALUE, -Double.MIN_VALUE), doubleArrayOf(0.0, Double.MIN_VALUE, -Double.MIN_VALUE), doubleArrayOf(-0.0, Double.MIN_VALUE, -Double.MIN_VALUE), doubleArrayOf(Double.MIN_VALUE, 1.0E-323, +0.0), doubleArrayOf(-Double.MIN_VALUE, -0.0, -1.0E-323), doubleArrayOf(MIN_NORMAL_D, 2.225073858507202E-308, 2.225073858507201E-308), doubleArrayOf(-MIN_NORMAL_D, -2.225073858507201E-308, -2.225073858507202E-308), doubleArrayOf(Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1.7976931348623155E308), doubleArrayOf(-Double.MAX_VALUE, -1.7976931348623155E308, Double.NEGATIVE_INFINITY), doubleArrayOf(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.MAX_VALUE), doubleArrayOf(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY) ) /** * direction number cases for test_nextTowards_DD/test_nextTowards_FD in * est/Strictest */ internal val NEXTAFTER_DD_FD_DIRECTION_CASES = doubleArrayOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, 8.8, 3.4, 1.4, MIN_NORMAL_D, MIN_NORMAL_D / 2, Double.MIN_VALUE, +0.0, 0.0, -0.0, -Double.MIN_VALUE, -MIN_NORMAL_D / 2, -MIN_NORMAL_D, -1.4, -3.4, -8.8, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY) /** * start number cases for test_nextTowards_FD in est/Strictest * NEXTAFTER_FD_START_CASES[i][0] is the start number * NEXTAFTER_FD_START_CASES[i][1] is the nextUp of start number * NEXTAFTER_FD_START_CASES[i][2] is the nextDown of start number */ internal val NEXTAFTER_FD_START_CASES = arrayOf(floatArrayOf(3.4f, 3.4000003f, 3.3999999f), floatArrayOf(-3.4f, -3.3999999f, -3.4000003f), floatArrayOf(3.4233E19f, 3.4233002E19f, 3.4232998E19f), floatArrayOf(-3.4233E19f, -3.4232998E19f, -3.4233002E19f), floatArrayOf(+0.0f, Float.MIN_VALUE, -Float.MIN_VALUE), floatArrayOf(0.0f, Float.MIN_VALUE, -Float.MIN_VALUE), floatArrayOf(-0.0f, Float.MIN_VALUE, -Float.MIN_VALUE), floatArrayOf(Float.MIN_VALUE, 2.8E-45f, +0.0f), floatArrayOf(-Float.MIN_VALUE, -0.0f, -2.8E-45f), floatArrayOf(MIN_NORMAL_F, 1.1754945E-38f, 1.1754942E-38f), floatArrayOf(-MIN_NORMAL_F, -1.1754942E-38f, -1.1754945E-38f), floatArrayOf(Float.MAX_VALUE, Float.POSITIVE_INFINITY, 3.4028233E38f), floatArrayOf(-Float.MAX_VALUE, -3.4028233E38f, Float.NEGATIVE_INFINITY), floatArrayOf(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.MAX_VALUE), floatArrayOf(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY)) } } ================================================ FILE: backend.native/tests/stdlib_external/numbers/MathExceptionTest.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test.numbers import kotlin.math.* import kotlin.test.* class MathExceptionTest { @Test fun exceptions() { assertFails { Double.NaN.roundToLong() } assertFails { Double.NaN.roundToInt() } assertFails { Float.NaN.roundToLong() } assertFails { Float.NaN.roundToInt() } } } ================================================ FILE: backend.native/tests/stdlib_external/numbers/MathTest.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test.numbers import kotlin.math.* import kotlin.test.* fun assertAlmostEquals(expected: Double, actual: Double, tolerance: Double? = null) { val tolerance_ = tolerance?.let { abs(it) } ?: 0.000000000001 if (abs(expected - actual) > tolerance_) { assertEquals(expected, actual) } } fun assertAlmostEquals(expected: Float, actual: Float, tolerance: Double? = null) { val tolerance_ = tolerance?.let { abs(it) } ?: 0.0000001 if (abs(expected - actual) > tolerance_) { assertEquals(expected, actual) } } class DoubleMathTest { @Test fun trigonometric() { assertEquals(0.0, sin(0.0)) assertAlmostEquals(0.0, sin(PI)) assertEquals(0.0, asin(0.0)) assertAlmostEquals(PI / 2, asin(1.0)) assertEquals(1.0, cos(0.0)) assertAlmostEquals(-1.0, cos(PI)) assertEquals(0.0, acos(1.0)) assertAlmostEquals(PI / 2, acos(0.0)) assertEquals(0.0, tan(0.0)) assertAlmostEquals(1.0, tan(PI / 4)) assertAlmostEquals(0.0, atan(0.0)) assertAlmostEquals(PI / 4, atan(1.0)) assertAlmostEquals(PI / 4, atan2(10.0, 10.0)) assertAlmostEquals(-PI / 4, atan2(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) assertAlmostEquals(0.0, atan2(0.0, 0.0)) assertAlmostEquals(0.0, atan2(0.0, 10.0)) assertAlmostEquals(PI / 2, atan2(2.0, 0.0)) for (angle in listOf(Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY)) { assertTrue(sin(angle).isNaN(), "sin($angle)") assertTrue(cos(angle).isNaN(), "cos($angle)") assertTrue(tan(angle).isNaN(), "tan($angle)") } for (value in listOf(Double.NaN, 1.2, -1.1)) { assertTrue(asin(value).isNaN()) assertTrue(acos(value).isNaN()) } assertTrue(atan(Double.NaN).isNaN()) assertTrue(atan2(Double.NaN, 0.0).isNaN()) assertTrue(atan2(0.0, Double.NaN).isNaN()) } @Test fun hyperbolic() { assertEquals(Double.POSITIVE_INFINITY, sinh(Double.POSITIVE_INFINITY)) assertEquals(Double.NEGATIVE_INFINITY, sinh(Double.NEGATIVE_INFINITY)) assertTrue(sinh(Double.MIN_VALUE) != 0.0) assertTrue(sinh(710.0).isFinite()) assertTrue(sinh(-710.0).isFinite()) assertTrue(sinh(Double.NaN).isNaN()) assertEquals(Double.POSITIVE_INFINITY, cosh(Double.POSITIVE_INFINITY)) assertEquals(Double.POSITIVE_INFINITY, cosh(Double.NEGATIVE_INFINITY)) assertTrue(cosh(710.0).isFinite()) assertTrue(cosh(-710.0).isFinite()) assertTrue(cosh(Double.NaN).isNaN()) assertAlmostEquals(1.0, tanh(Double.POSITIVE_INFINITY)) assertAlmostEquals(-1.0, tanh(Double.NEGATIVE_INFINITY)) assertTrue(tanh(Double.MIN_VALUE) != 0.0) assertTrue(tanh(Double.NaN).isNaN()) } @Test fun inverseHyperbolicSin() { for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, Double.MIN_VALUE, -Double.MIN_VALUE, 0.00001)) { assertEquals(exact, asinh(sinh(exact))) } for (approx in listOf(Double.MIN_VALUE, 0.1, 1.0, 100.0, 710.0)) { assertAlmostEquals(approx, asinh(sinh(approx))) assertAlmostEquals(-approx, asinh(sinh(-approx))) } assertTrue(asinh(Double.NaN).isNaN()) } @Test fun inverseHyperbolicCos() { for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0)) { assertEquals(abs(exact), acosh(cosh(exact))) } for (approx in listOf(Double.MIN_VALUE, 0.00001, 1.0, 100.0, 710.0)) { assertAlmostEquals(approx, acosh(cosh(approx))) assertAlmostEquals(approx, acosh(cosh(-approx))) } for (invalid in listOf(-1.0, 0.0, 0.99999, Double.NaN)) { assertTrue(acosh(invalid).isNaN()) } } @Test fun inverseHyperbolicTan() { for (exact in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, Double.MIN_VALUE, -Double.MIN_VALUE)) { assertEquals(exact, atanh(tanh(exact))) } for (approx in listOf(0.00001)) { assertAlmostEquals(approx, atanh(tanh(approx))) } for (invalid in listOf(-1.00001, 1.00001, Double.NaN, Double.MAX_VALUE, -Double.MAX_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)) { assertTrue(atanh(invalid).isNaN()) } } @Test fun powers() { assertEquals(5.0, hypot(3.0, 4.0)) assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NEGATIVE_INFINITY, Double.NaN)) assertEquals(Double.POSITIVE_INFINITY, hypot(Double.NaN, Double.POSITIVE_INFINITY)) assertTrue(hypot(Double.NaN, 0.0).isNaN()) assertEquals(1.0, Double.NaN.pow(0.0)) assertEquals(1.0, Double.POSITIVE_INFINITY.pow(0)) assertEquals(49.0, 7.0.pow(2)) assertEquals(0.25, 2.0.pow(-2)) assertTrue(0.0.pow(Double.NaN).isNaN()) assertTrue(Double.NaN.pow(-1).isNaN()) assertTrue((-7.0).pow(1/3.0).isNaN()) assertTrue(1.0.pow(Double.POSITIVE_INFINITY).isNaN()) assertTrue((-1.0).pow(Double.NEGATIVE_INFINITY).isNaN()) assertEquals(5.0, sqrt(9.0 + 16.0)) assertTrue(sqrt(-1.0).isNaN()) assertTrue(sqrt(Double.NaN).isNaN()) assertTrue(exp(Double.NaN).isNaN()) assertAlmostEquals(E, exp(1.0)) assertEquals(1.0, exp(0.0)) assertEquals(0.0, exp(Double.NEGATIVE_INFINITY)) assertEquals(Double.POSITIVE_INFINITY, exp(Double.POSITIVE_INFINITY)) assertEquals(0.0, expm1(0.0)) assertEquals(Double.MIN_VALUE, expm1(Double.MIN_VALUE)) assertEquals(0.00010000500016667084, expm1(1e-4)) assertEquals(-1.0, expm1(Double.NEGATIVE_INFINITY)) assertEquals(Double.POSITIVE_INFINITY, expm1(Double.POSITIVE_INFINITY)) } @Test fun logarithms() { assertTrue(log(1.0, Double.NaN).isNaN()) assertTrue(log(Double.NaN, 1.0).isNaN()) assertTrue(log(-1.0, 2.0).isNaN()) assertTrue(log(2.0, -1.0).isNaN()) assertTrue(log(2.0, 0.0).isNaN()) assertTrue(log(2.0, 1.0).isNaN()) assertTrue(log(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isNaN()) assertEquals(-2.0, log(0.25, 2.0)) assertEquals(-0.5, log(2.0, 0.25)) assertEquals(Double.NEGATIVE_INFINITY, log(Double.POSITIVE_INFINITY, 0.25)) assertEquals(Double.POSITIVE_INFINITY, log(Double.POSITIVE_INFINITY, 2.0)) assertEquals(Double.NEGATIVE_INFINITY, log(0.0, 2.0)) assertEquals(Double.POSITIVE_INFINITY, log(0.0, 0.25)) assertTrue(ln(Double.NaN).isNaN()) assertTrue(ln(-1.0).isNaN()) assertEquals(1.0, ln(E)) assertEquals(Double.NEGATIVE_INFINITY, ln(0.0)) assertEquals(Double.POSITIVE_INFINITY, ln(Double.POSITIVE_INFINITY)) assertEquals(1.0, log10(10.0)) assertAlmostEquals(-1.0, log10(0.1)) assertAlmostEquals(3.0, log2(8.0)) assertEquals(-1.0, log2(0.5)) assertTrue(ln1p(Double.NaN).isNaN()) assertTrue(ln1p(-1.1).isNaN()) assertEquals(0.0, ln1p(0.0)) assertEquals(9.999995000003334e-7, ln1p(1e-6)) assertEquals(Double.MIN_VALUE, ln1p(Double.MIN_VALUE)) assertEquals(Double.NEGATIVE_INFINITY, ln1p(-1.0)) } @Test fun rounding() { for (value in listOf(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0, 1.0, -10.0)) { assertEquals(value, ceil(value)) assertEquals(value, floor(value)) assertEquals(value, truncate(value)) assertEquals(value, round(value)) } assertTrue(ceil(Double.NaN).isNaN()) assertTrue(floor(Double.NaN).isNaN()) assertTrue(truncate(Double.NaN).isNaN()) assertTrue(round(Double.NaN).isNaN()) val data = arrayOf( // v floor trunc round ceil doubleArrayOf( 1.3, 1.0, 1.0, 1.0, 2.0), doubleArrayOf(-1.3, -2.0, -1.0, -1.0, -1.0), doubleArrayOf( 1.5, 1.0, 1.0, 2.0, 2.0), doubleArrayOf(-1.5, -2.0, -1.0, -2.0, -1.0), doubleArrayOf( 1.8, 1.0, 1.0, 2.0, 2.0), doubleArrayOf(-1.8, -2.0, -1.0, -2.0, -1.0), doubleArrayOf( 2.3, 2.0, 2.0, 2.0, 3.0), doubleArrayOf(-2.3, -3.0, -2.0, -2.0, -2.0), doubleArrayOf( 2.5, 2.0, 2.0, 2.0, 3.0), doubleArrayOf(-2.5, -3.0, -2.0, -2.0, -2.0), doubleArrayOf( 2.8, 2.0, 2.0, 3.0, 3.0), doubleArrayOf(-2.8, -3.0, -2.0, -3.0, -2.0) ) for ((v, f, t, r, c) in data) { assertEquals(f, floor(v), "floor($v)") assertEquals(t, truncate(v), "truncate($v)") assertEquals(r, round(v), "round($v)") assertEquals(c, ceil(v), "ceil($v)") } } @Test fun roundingConversion() { assertEquals(1L, 1.0.roundToLong()) assertEquals(1L, 1.1.roundToLong()) assertEquals(2L, 1.5.roundToLong()) assertEquals(3L, 2.5.roundToLong()) assertEquals(-2L, (-2.5).roundToLong()) assertEquals(-3L, (-2.6).roundToLong()) assertEquals(9223372036854774784, (9223372036854774800.0).roundToLong()) assertEquals(Long.MAX_VALUE, Double.MAX_VALUE.roundToLong()) assertEquals(Long.MIN_VALUE, (-Double.MAX_VALUE).roundToLong()) assertEquals(Long.MAX_VALUE, Double.POSITIVE_INFINITY.roundToLong()) assertEquals(Long.MIN_VALUE, Double.NEGATIVE_INFINITY.roundToLong()) assertEquals(1, 1.0.roundToInt()) assertEquals(1, 1.1.roundToInt()) assertEquals(2, 1.5.roundToInt()) assertEquals(3, 2.5.roundToInt()) assertEquals(-2, (-2.5).roundToInt()) assertEquals(-3, (-2.6).roundToInt()) assertEquals(2123456789, (2123456789.0).roundToInt()) assertEquals(Int.MAX_VALUE, Double.MAX_VALUE.roundToInt()) assertEquals(Int.MIN_VALUE, (-Double.MAX_VALUE).roundToInt()) assertEquals(Int.MAX_VALUE, Double.POSITIVE_INFINITY.roundToInt()) assertEquals(Int.MIN_VALUE, Double.NEGATIVE_INFINITY.roundToInt()) } @Test fun absoluteValue() { assertTrue(abs(Double.NaN).isNaN()) assertTrue(Double.NaN.absoluteValue.isNaN()) for (value in listOf(0.0, Double.MIN_VALUE, 0.1, 1.0, 1000.0, Double.MAX_VALUE, Double.POSITIVE_INFINITY)) { assertEquals(value, value.absoluteValue) assertEquals(value, (-value).absoluteValue) assertEquals(value, abs(value)) assertEquals(value, abs(-value)) } } @Test fun signs() { assertTrue(sign(Double.NaN).isNaN()) assertTrue(Double.NaN.sign.isNaN()) val negatives = listOf(Double.NEGATIVE_INFINITY, -Double.MAX_VALUE, -1.0, -Double.MIN_VALUE) for (value in negatives) { assertEquals(-1.0, sign(value)) assertEquals(-1.0, value.sign) } val zeroes = listOf(0.0, -0.0) for (value in zeroes) { assertEquals(value, sign(value)) assertEquals(value, value.sign) } val positives = listOf(Double.POSITIVE_INFINITY, Double.MAX_VALUE, 1.0, Double.MIN_VALUE) for (value in positives) { assertEquals(1.0, sign(value)) assertEquals(1.0, value.sign) } val allValues = negatives + positives for (a in allValues) { for (b in allValues) { val r = a.withSign(b) assertEquals(a.absoluteValue, r.absoluteValue) assertEquals(b.sign, r.sign, "expected $a with sign bit of $b to have sign ${b.sign}") } val rp0 = a.withSign(0.0) assertEquals(1.0, rp0.sign) assertEquals(a.absoluteValue, rp0.absoluteValue) val rm0 = a.withSign(-0.0) assertEquals(-1.0, rm0.sign) assertEquals(a.absoluteValue, rm0.absoluteValue) val ri = a.withSign(-1) assertEquals(-1.0, ri.sign) assertEquals(a.absoluteValue, ri.absoluteValue) val rn = a.withSign(Double.NaN) assertEquals(a.absoluteValue, rn.absoluteValue) } } @Test fun nextAndPrev() { for (value in listOf(0.0, -0.0, Double.MIN_VALUE, -1.0, 2.0.pow(10))) { val next = value.nextUp() if (next > 0) { assertEquals(next, value + value.ulp) } else { assertEquals(value, next - next.ulp) } val prev = value.nextDown() if (prev > 0) { assertEquals(value, prev + prev.ulp) } else { assertEquals(prev, value - value.ulp) } val toZero = value.nextTowards(0.0) if (toZero != 0.0) { assertEquals(value, toZero + toZero.ulp.withSign(toZero)) } assertEquals(Double.POSITIVE_INFINITY, Double.MAX_VALUE.nextUp()) assertEquals(Double.MAX_VALUE, Double.POSITIVE_INFINITY.nextDown()) assertEquals(Double.NEGATIVE_INFINITY, (-Double.MAX_VALUE).nextDown()) assertEquals((-Double.MAX_VALUE), Double.NEGATIVE_INFINITY.nextUp()) assertTrue(Double.NaN.ulp.isNaN()) assertTrue(Double.NaN.nextDown().isNaN()) assertTrue(Double.NaN.nextUp().isNaN()) assertTrue(Double.NaN.nextTowards(0.0).isNaN()) assertEquals(Double.MIN_VALUE, (0.0).ulp) assertEquals(Double.MIN_VALUE, (-0.0).ulp) assertEquals(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY.ulp) assertEquals(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.ulp) val maxUlp = 2.0.pow(971) assertEquals(maxUlp, Double.MAX_VALUE.ulp) assertEquals(maxUlp, (-Double.MAX_VALUE).ulp) } } @Test fun IEEEremainder() { val data = arrayOf( // a a IEEErem 2.5 doubleArrayOf(-2.0, 0.5), doubleArrayOf(-1.25, -1.25), doubleArrayOf( 0.0, 0.0), doubleArrayOf( 1.0, 1.0), doubleArrayOf( 1.25, 1.25), doubleArrayOf( 1.5, -1.0), doubleArrayOf( 2.0, -0.5), doubleArrayOf( 2.5, 0.0), doubleArrayOf( 3.5, 1.0), doubleArrayOf( 3.75, -1.25), doubleArrayOf( 4.0, -1.0) ) for ((a, r) in data) { assertEquals(r, a.IEEErem(2.5), "($a).IEEErem(2.5)") } assertTrue(Double.NaN.IEEErem(2.5).isNaN()) assertTrue(2.0.IEEErem(Double.NaN).isNaN()) assertTrue(Double.POSITIVE_INFINITY.IEEErem(2.0).isNaN()) assertTrue(2.0.IEEErem(0.0).isNaN()) assertEquals(PI, PI.IEEErem(Double.NEGATIVE_INFINITY)) } /* * Special cases: * - `atan2(0.0, 0.0)` is `0.0` * - `atan2(0.0, x)` is `0.0` for `x > 0` and `PI` for `x < 0` * - `atan2(-0.0, x)` is `-0.0` for 'x > 0` and `-PI` for `x < 0` * - `atan2(y, +Inf)` is `0.0` for `0 < y < +Inf` and `-0.0` for '-Inf < y < 0` * - `atan2(y, -Inf)` is `PI` for `0 < y < +Inf` and `-PI` for `-Inf < y < 0` * - `atan2(y, 0.0)` is `PI/2` for `y > 0` and `-PI/2` for `y < 0` * - `atan2(+Inf, x)` is `PI/2` for finite `x`y * - `atan2(-Inf, x)` is `-PI/2` for finite `x` * - `atan2(NaN, x)` and `atan2(y, NaN)` is `NaN` */ @Test fun atan2SpecialCases() { assertEquals(atan2(0.0, 0.0), 0.0) assertEquals(atan2(0.0, 1.0), 0.0) assertEquals(atan2(0.0, -1.0), PI) assertEquals(atan2(-0.0, 1.0), -0.0) assertEquals(atan2(-0.0, -1.0), -PI) assertEquals(atan2(1.0, Double.POSITIVE_INFINITY), 0.0) assertEquals(atan2(-1.0, Double.POSITIVE_INFINITY), -0.0) assertEquals(atan2(1.0, Double.NEGATIVE_INFINITY), PI) assertEquals(atan2(-1.0, Double.NEGATIVE_INFINITY), -PI) assertEquals(atan2(1.0, 0.0), PI/2) assertEquals(atan2(-1.0, 0.0), -PI/2) assertEquals(atan2(Double.POSITIVE_INFINITY, 1.0), PI/2) assertEquals(atan2(Double.NEGATIVE_INFINITY, 1.0), -PI/2) assertTrue(atan2(Double.NaN, 1.0).isNaN()) assertTrue(atan2(1.0, Double.NaN).isNaN()) } } class FloatMathTest { companion object { const val PI = kotlin.math.PI.toFloat() const val E = kotlin.math.E.toFloat() } @Test fun trigonometric() { assertEquals(0.0F, sin(0.0F)) assertAlmostEquals(0.0F, sin(PI)) assertEquals(0.0F, asin(0.0F)) assertAlmostEquals(PI / 2, asin(1.0F), 0.0000002) assertEquals(1.0F, cos(0.0F)) assertAlmostEquals(-1.0F, cos(PI)) assertEquals(0.0F, acos(1.0F)) assertAlmostEquals(PI / 2, acos(0.0F)) assertEquals(0.0F, tan(0.0F)) assertAlmostEquals(1.0F, tan(PI / 4)) assertAlmostEquals(0.0F, atan(0.0F)) assertAlmostEquals(PI / 4, atan(1.0F)) assertAlmostEquals(PI / 4, atan2(10.0F, 10.0F)) assertAlmostEquals(-PI / 4, atan2(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY)) assertAlmostEquals(0.0F, atan2(0.0F, 0.0F)) assertAlmostEquals(0.0F, atan2(0.0F, 10.0F)) assertAlmostEquals(PI / 2, atan2(2.0F, 0.0F)) for (angle in listOf(Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY)) { assertTrue(sin(angle).isNaN(), "sin($angle)") assertTrue(cos(angle).isNaN(), "cos($angle)") assertTrue(tan(angle).isNaN(), "tan($angle)") } for (value in listOf(Float.NaN, 1.2F, -1.1F)) { assertTrue(asin(value).isNaN()) assertTrue(acos(value).isNaN()) } assertTrue(atan(Float.NaN).isNaN()) assertTrue(atan2(Float.NaN, 0.0F).isNaN()) assertTrue(atan2(0.0F, Float.NaN).isNaN()) } @Test fun hyperbolic() { assertEquals(Float.POSITIVE_INFINITY, sinh(Float.POSITIVE_INFINITY)) assertEquals(Float.NEGATIVE_INFINITY, sinh(Float.NEGATIVE_INFINITY)) assertTrue(sinh(Float.MIN_VALUE) != 0.0F) assertTrue(sinh(89.0F).isFinite()) assertTrue(sinh(-89.0F).isFinite()) assertTrue(sinh(Float.NaN).isNaN()) assertEquals(Float.POSITIVE_INFINITY, cosh(Float.POSITIVE_INFINITY)) assertEquals(Float.POSITIVE_INFINITY, cosh(Float.NEGATIVE_INFINITY)) assertTrue(cosh(89.0F).isFinite()) assertTrue(cosh(-89.0F).isFinite()) assertTrue(cosh(Float.NaN).isNaN()) assertAlmostEquals(1.0F, tanh(Float.POSITIVE_INFINITY)) assertAlmostEquals(-1.0F, tanh(Float.NEGATIVE_INFINITY)) assertTrue(tanh(Float.MIN_VALUE) != 0.0F) assertTrue(tanh(Float.NaN).isNaN()) } @Test fun inverseHyperbolicSin() { for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, Float.MIN_VALUE, -Float.MIN_VALUE, 0.00001F)) { assertEquals(exact, asinh(sinh(exact))) } for (approx in listOf(Float.MIN_VALUE, 0.1F, 1.0F, 89.0F)) { assertAlmostEquals(approx, asinh(sinh(approx))) assertAlmostEquals(-approx, asinh(sinh(-approx))) } assertTrue(asinh(Float.NaN).isNaN()) } @Test fun inverseHyperbolicCos() { for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F)) { assertEquals(abs(exact), acosh(cosh(exact))) } for (approx in listOf(Float.MIN_VALUE, 0.1F, 1.0F, 89.0F)) { assertAlmostEquals(approx, acosh(cosh(approx))) assertAlmostEquals(approx, acosh(cosh(-approx))) } for (invalid in listOf(-1.0F, 0.0F, 0.99999F, Float.NaN)) { assertTrue(acosh(invalid).isNaN()) } } @Test fun inverseHyperbolicTan() { for (exact in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, Float.MIN_VALUE, -Float.MIN_VALUE)) { assertEquals(exact, atanh(tanh(exact))) } for (approx in listOf(0.00001F)) { assertAlmostEquals(approx, atanh(tanh(approx))) } for (invalid in listOf(-1.00001F, 1.00001F, Float.NaN, Float.MAX_VALUE, -Float.MAX_VALUE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY)) { assertTrue(atanh(invalid).isNaN()) } } @Test fun powers() { assertEquals(5.0F, hypot(3.0F, 4.0F)) assertEquals(Float.POSITIVE_INFINITY, hypot(Float.NEGATIVE_INFINITY, Float.NaN)) assertEquals(Float.POSITIVE_INFINITY, hypot(Float.NaN, Float.POSITIVE_INFINITY)) assertTrue(hypot(Float.NaN, 0.0F).isNaN()) assertEquals(1.0F, Float.NaN.pow(0.0F)) assertEquals(1.0F, Float.POSITIVE_INFINITY.pow(0)) assertEquals(49.0F, 7.0F.pow(2)) assertEquals(0.25F, 2.0F.pow(-2)) assertTrue(0.0F.pow(Float.NaN).isNaN()) assertTrue(Float.NaN.pow(-1).isNaN()) assertTrue((-7.0F).pow(1/3.0F).isNaN()) assertTrue(1.0F.pow(Float.POSITIVE_INFINITY).isNaN()) assertTrue((-1.0F).pow(Float.NEGATIVE_INFINITY).isNaN()) assertEquals(5.0F, sqrt(9.0F + 16.0F)) assertTrue(sqrt(-1.0F).isNaN()) assertTrue(sqrt(Float.NaN).isNaN()) assertTrue(exp(Float.NaN).isNaN()) assertAlmostEquals(E, exp(1.0F)) assertEquals(1.0F, exp(0.0F)) assertEquals(0.0F, exp(Float.NEGATIVE_INFINITY)) assertEquals(Float.POSITIVE_INFINITY, exp(Float.POSITIVE_INFINITY)) assertEquals(0.0F, expm1(0.0F)) assertEquals(-1.0F, expm1(Float.NEGATIVE_INFINITY)) assertEquals(Float.POSITIVE_INFINITY, expm1(Float.POSITIVE_INFINITY)) } @Test fun logarithms() { assertTrue(log(1.0F, Float.NaN).isNaN()) assertTrue(log(Float.NaN, 1.0F).isNaN()) assertTrue(log(-1.0F, 2.0F).isNaN()) assertTrue(log(2.0F, -1.0F).isNaN()) assertTrue(log(2.0F, 0.0F).isNaN()) assertTrue(log(2.0F, 1.0F).isNaN()) assertTrue(log(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY).isNaN()) assertEquals(-2.0F, log(0.25F, 2.0F)) assertEquals(-0.5F, log(2.0F, 0.25F)) assertEquals(Float.NEGATIVE_INFINITY, log(Float.POSITIVE_INFINITY, 0.25F)) assertEquals(Float.POSITIVE_INFINITY, log(Float.POSITIVE_INFINITY, 2.0F)) assertEquals(Float.NEGATIVE_INFINITY, log(0.0F, 2.0F)) assertEquals(Float.POSITIVE_INFINITY, log(0.0F, 0.25F)) assertTrue(ln(Float.NaN).isNaN()) assertTrue(ln(-1.0F).isNaN()) assertAlmostEquals(1.0F, ln(E)) assertEquals(Float.NEGATIVE_INFINITY, ln(0.0F)) assertEquals(Float.POSITIVE_INFINITY, ln(Float.POSITIVE_INFINITY)) assertEquals(1.0F, log10(10.0F)) assertAlmostEquals(-1.0F, log10(0.1F)) assertAlmostEquals(3.0F, log2(8.0F)) assertEquals(-1.0F, log2(0.5F)) assertTrue(ln1p(Float.NaN).isNaN()) assertTrue(ln1p(-1.1F).isNaN()) assertEquals(0.0F, ln1p(0.0F)) assertEquals(Float.NEGATIVE_INFINITY, ln1p(-1.0F)) } @Test fun rounding() { for (value in listOf(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0F, 1.0F, -10.0F)) { assertEquals(value, ceil(value)) assertEquals(value, floor(value)) assertEquals(value, truncate(value)) assertEquals(value, round(value)) } assertTrue(ceil(Float.NaN).isNaN()) assertTrue(floor(Float.NaN).isNaN()) assertTrue(truncate(Float.NaN).isNaN()) assertTrue(round(Float.NaN).isNaN()) val data = arrayOf( // v floor trunc round ceil floatArrayOf( 1.3F, 1.0F, 1.0F, 1.0F, 2.0F), floatArrayOf(-1.3F, -2.0F, -1.0F, -1.0F, -1.0F), floatArrayOf( 1.5F, 1.0F, 1.0F, 2.0F, 2.0F), floatArrayOf(-1.5F, -2.0F, -1.0F, -2.0F, -1.0F), floatArrayOf( 1.8F, 1.0F, 1.0F, 2.0F, 2.0F), floatArrayOf(-1.8F, -2.0F, -1.0F, -2.0F, -1.0F), floatArrayOf( 2.3F, 2.0F, 2.0F, 2.0F, 3.0F), floatArrayOf(-2.3F, -3.0F, -2.0F, -2.0F, -2.0F), floatArrayOf( 2.5F, 2.0F, 2.0F, 2.0F, 3.0F), floatArrayOf(-2.5F, -3.0F, -2.0F, -2.0F, -2.0F), floatArrayOf( 2.8F, 2.0F, 2.0F, 3.0F, 3.0F), floatArrayOf(-2.8F, -3.0F, -2.0F, -3.0F, -2.0F) ) for ((v, f, t, r, c) in data) { assertEquals(f, floor(v), "floor($v)") assertEquals(t, truncate(v), "truncate($v)") assertEquals(r, round(v), "round($v)") assertEquals(c, ceil(v), "ceil($v)") } } @Test fun roundingConversion() { assertEquals(1L, 1.0F.roundToLong()) assertEquals(1L, 1.1F.roundToLong()) assertEquals(2L, 1.5F.roundToLong()) assertEquals(3L, 2.5F.roundToLong()) assertEquals(-2L, (-2.5F).roundToLong()) assertEquals(-3L, (-2.6F).roundToLong()) // assertEquals(9223372036854774784, (9223372036854774800.0F).roundToLong()) // platform-specific assertEquals(Long.MAX_VALUE, Float.MAX_VALUE.roundToLong()) assertEquals(Long.MIN_VALUE, (-Float.MAX_VALUE).roundToLong()) assertEquals(Long.MAX_VALUE, Float.POSITIVE_INFINITY.roundToLong()) assertEquals(Long.MIN_VALUE, Float.NEGATIVE_INFINITY.roundToLong()) assertEquals(1, 1.0F.roundToInt()) assertEquals(1, 1.1F.roundToInt()) assertEquals(2, 1.5F.roundToInt()) assertEquals(3, 2.5F.roundToInt()) assertEquals(-2, (-2.5F).roundToInt()) assertEquals(-3, (-2.6F).roundToInt()) assertEquals(16777218, (16777218F).roundToInt()) assertEquals(Int.MAX_VALUE, Float.MAX_VALUE.roundToInt()) assertEquals(Int.MIN_VALUE, (-Float.MAX_VALUE).roundToInt()) assertEquals(Int.MAX_VALUE, Float.POSITIVE_INFINITY.roundToInt()) assertEquals(Int.MIN_VALUE, Float.NEGATIVE_INFINITY.roundToInt()) } @Test fun absoluteValue() { assertTrue(abs(Float.NaN).isNaN()) assertTrue(Float.NaN.absoluteValue.isNaN()) for (value in listOf(0.0F, Float.MIN_VALUE, 0.1F, 1.0F, 1000.0F, Float.MAX_VALUE, Float.POSITIVE_INFINITY)) { assertEquals(value, value.absoluteValue) assertEquals(value, (-value).absoluteValue) assertEquals(value, abs(value)) assertEquals(value, abs(-value)) } } @Test fun signs() { assertTrue(sign(Float.NaN).isNaN()) assertTrue(Float.NaN.sign.isNaN()) val negatives = listOf(Float.NEGATIVE_INFINITY, -Float.MAX_VALUE, -1.0F, -Float.MIN_VALUE) for (value in negatives) { assertEquals(-1.0F, sign(value)) assertEquals(-1.0F, value.sign) } val zeroes = listOf(0.0F, -0.0F) for (value in zeroes) { assertEquals(value, sign(value)) assertEquals(value, value.sign) } val positives = listOf(Float.POSITIVE_INFINITY, Float.MAX_VALUE, 1.0F, Float.MIN_VALUE) for (value in positives) { assertEquals(1.0F, sign(value)) assertEquals(1.0F, value.sign) } val allValues = negatives + positives for (a in allValues) { for (b in allValues) { val r = a.withSign(b) assertEquals(a.absoluteValue, r.absoluteValue) assertEquals(b.sign, r.sign) } val rp0 = a.withSign(0.0F) assertEquals(1.0F, rp0.sign) assertEquals(a.absoluteValue, rp0.absoluteValue) val rm0 = a.withSign(-0.0F) assertEquals(-1.0F, rm0.sign) assertEquals(a.absoluteValue, rm0.absoluteValue) val ri = a.withSign(-1) assertEquals(-1.0F, ri.sign) assertEquals(a.absoluteValue, ri.absoluteValue) } } @Test fun nextAndPrev() { for (value in listOf(0.0f, -0.0f, Float.MIN_VALUE, -1.0f, 2.0f.pow(10))) { val next = value.nextUp() if (next > 0) { assertEquals(next, value + value.ulp) } else { assertEquals(value, next - next.ulp) } val prev = value.nextDown() if (prev > 0) { assertEquals(value, prev + prev.ulp) } else { assertEquals(prev, value - value.ulp) } val toZero = value.nextTowards(0.0f) if (toZero != 0.0f) { assertEquals(value, toZero + toZero.ulp.withSign(toZero)) } assertEquals(Float.POSITIVE_INFINITY, Float.MAX_VALUE.nextUp()) assertEquals(Float.MAX_VALUE, Float.POSITIVE_INFINITY.nextDown()) assertEquals(Float.NEGATIVE_INFINITY, (-Float.MAX_VALUE).nextDown()) assertEquals((-Float.MAX_VALUE), Float.NEGATIVE_INFINITY.nextUp()) assertTrue(Float.NaN.ulp.isNaN()) assertTrue(Float.NaN.nextDown().isNaN()) assertTrue(Float.NaN.nextUp().isNaN()) assertTrue(Float.NaN.nextTowards(0.0f).isNaN()) assertEquals(Float.MIN_VALUE, (0.0f).ulp) assertEquals(Float.MIN_VALUE, (-0.0f).ulp) assertEquals(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY.ulp) assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY.ulp) val maxUlp = 2.0f.pow(104) assertEquals(maxUlp, Float.MAX_VALUE.ulp) assertEquals(maxUlp, (-Float.MAX_VALUE).ulp) } } @Test fun IEEEremainder() { val data = arrayOf( // a a IEEErem 2.5 floatArrayOf(-2.0f, 0.5f), floatArrayOf(-1.25f, -1.25f), floatArrayOf( 0.0f, 0.0f), floatArrayOf( 1.0f, 1.0f), floatArrayOf( 1.25f, 1.25f), floatArrayOf( 1.5f, -1.0f), floatArrayOf( 2.0f, -0.5f), floatArrayOf( 2.5f, 0.0f), floatArrayOf( 3.5f, 1.0f), floatArrayOf( 3.75f, -1.25f), floatArrayOf( 4.0f, -1.0f) ) for ((a, r) in data) { assertEquals(r, a.IEEErem(2.5f), "($a).IEEErem(2.5f)") } assertTrue(Float.NaN.IEEErem(2.5f).isNaN()) assertTrue(2.0f.IEEErem(Float.NaN).isNaN()) assertTrue(Float.POSITIVE_INFINITY.IEEErem(2.0f).isNaN()) assertTrue(2.0f.IEEErem(0.0f).isNaN()) assertEquals(PI.toFloat(), PI.toFloat().IEEErem(Float.NEGATIVE_INFINITY)) } } class IntegerMathTest { @Test fun intSigns() { val negatives = listOf(Int.MIN_VALUE, -65536, -1) val positives = listOf(1, 100, 256, Int.MAX_VALUE) negatives.forEach { assertEquals(-1, it.sign) } positives.forEach { assertEquals(1, it.sign) } assertEquals(0, 0.sign) (negatives - Int.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) } assertEquals(Int.MIN_VALUE, Int.MIN_VALUE.absoluteValue) positives.forEach { assertEquals(it, it.absoluteValue) } } @Test fun longSigns() { val negatives = listOf(Long.MIN_VALUE, -65536L, -1L) val positives = listOf(1L, 100L, 256L, Long.MAX_VALUE) negatives.forEach { assertEquals(-1, it.sign) } positives.forEach { assertEquals(1, it.sign) } assertEquals(0, 0L.sign) (negatives - Long.MIN_VALUE).forEach { assertEquals(-it, it.absoluteValue) } assertEquals(Long.MIN_VALUE, Long.MIN_VALUE.absoluteValue) positives.forEach { assertEquals(it, it.absoluteValue) } } } ================================================ FILE: backend.native/tests/stdlib_external/text/CharNativeTest.kt ================================================ package test.text import kotlin.test.* class CharNativeTest { @Test fun lowercaseChar() { // large mapping assertEquals('\u0239', '\u0239'.lowercaseChar()) assertEquals('\u2C65', '\u023A'.lowercaseChar()) assertEquals('\u023C', '\u023B'.lowercaseChar()) // large negative mapping assertEquals('\u2C7D', '\u2C7D'.lowercaseChar()) assertEquals('\u023F', '\u2C7E'.lowercaseChar()) assertEquals('\u0240', '\u2C7F'.lowercaseChar()) // assertEquals('\u2C81', '\u2C80'.lowercaseChar()) assertEquals('\u2C81', '\u2C81'.lowercaseChar()) assertEquals('\u2C83', '\u2C82'.lowercaseChar()) } @Test fun uppercaseChar() { // large mapping assertEquals('\u029C', '\u029C'.uppercaseChar()) assertEquals('\uA7B2', '\u029D'.uppercaseChar()) assertEquals('\uA7B0', '\u029E'.uppercaseChar()) assertEquals('\u029F', '\u029F'.uppercaseChar()) // large negative mapping assertEquals('\uAB6F', '\uAB6F'.uppercaseChar()) assertEquals('\u13A0', '\uAB70'.uppercaseChar()) assertEquals('\u13EF', '\uABBF'.uppercaseChar()) assertEquals('\uABC0', '\uABC0'.uppercaseChar()) } @Test fun titlecaseChar() { // titlecaseChar == char && uppercaseChar != char assertEquals('\u10CF'.uppercaseChar(), '\u10CF'.titlecaseChar()) for (char in '\u10D0'..'\u10FA') { assertEquals(char, char.titlecaseChar()) assertNotEquals(char, char.uppercaseChar()) } for (char in '\u10FB'..'\u10FC') { assertEquals(char, char.titlecaseChar()) assertEquals(char, char.uppercaseChar()) } for (char in '\u10FD'..'\u10FF') { assertEquals(char, char.titlecaseChar()) assertNotEquals(char, char.uppercaseChar()) } assertEquals('\u1100'.uppercaseChar(), '\u1100'.titlecaseChar()) } @Test fun lowercase() { // LATIN CAPITAL LETTER I WITH DOT ABOVE assertEquals("\u0069\u0307", '\u0130'.lowercase()) } fun titlecase() { // titlecase = titlecaseChar = char != uppercaseChar assertEquals('\u10F0'.titlecaseChar().toString(), '\u10F0'.titlecase()) assertEquals('\u10F0', '\u10F0'.titlecaseChar()) assertNotEquals('\u10F0', '\u10F0'.uppercaseChar()) } } ================================================ FILE: backend.native/tests/stdlib_external/text/StringEncodingTestNative.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test.text @SharedImmutable internal actual val surrogateCodePointDecoding: String = "\uFFFD".repeat(3) @SharedImmutable internal actual val surrogateCharEncoding: ByteArray = byteArrayOf(0xEF.toByte(), 0xBF.toByte(), 0xBD.toByte()) ================================================ FILE: backend.native/tests/stdlib_external/text/StringNativeTest.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package test.text import kotlin.test.* class StringNativeTest { @Test fun lowercase() { // Non-ASCII assertEquals("\u214E\uA7B5\u2CEF", "\u2132\uA7B4\u2CEF".lowercase()) // Surrogate pairs assertEquals("\uD801\uDC4F\uD806\uDCD0\uD81B\uDE7F", "\uD801\uDC27\uD806\uDCB0\uD81B\uDE5F".lowercase()) // Special Casing // LATIN CAPITAL LETTER I WITH DOT ABOVE assertEquals("\u0069\u0307", "\u0130".lowercase()) assertEquals("a\u0069\u0307z", "a\u0130Z".lowercase()) // Final_Sigma run { fun caseIgnorable(length: Int): String { return listOf( "\u0483", // COMBINING CYRILLIC TITLO; Mn "\u20DF", // COMBINING ENCLOSING DIAMOND; Me "\uD804\uDCBD", // 110BD; KAITHI NUMBER SIGN; Cf "\u2C7D", // MODIFIER LETTER CAPITAL V; Lm "\uD83C\uDFFD", // 1F3FD; EMOJI MODIFIER FITZPATRICK TYPE-4; Sk "\u003A", // COLON; Po; Word_Break=MidLetter "\uFF0E", // FULLWIDTH FULL STOP; Po; Word_Break=MidNumLet "\u0027" // APOSTROPHE; Po; Word_Break=Single_Quote ).shuffled().take(length).joinToString(separator = "") } fun cased(): String { return listOf( "\u0041", // LATIN CAPITAL LETTER A; Lu "\uD81B\uDE63", // 16E63; MEDEFAIDRIN SMALL LETTER W; Ll "\u01CB", // LATIN CAPITAL LETTER N WITH SMALL LETTER J; Lt "\u217A", // SMALL ROMAN NUMERAL ELEVEN; Nl; Other_Lowercase "\uD83C\uDD50" // 1F150; NEGATIVE CIRCLED LATIN CAPITAL LETTER A; So; Other_Uppercase ).random() } fun other(): String { return listOf( "\u0000", // ; Cc "\u0030", // DIGIT ZERO; Nd "\uD838\uDEC6" // 1E2C6; WANCHO LETTER YA; Lo ).random() } fun Char.hex(): String { return toInt().toString(16).padStart(4, '0') } val sigma = '\u03A3' val lowerSigma = '\u03C3' val specialLowerSigma = '\u03C2' // Build a string of the form: [cased][other](caseIgnorable*)(sigma)(caseIgnorable*)[other][cased] for (precedingCaseIgnorable in 0..5) { for (succeedingCaseIgnorable in 0..5) { val caseIgnorableBefore = caseIgnorable(precedingCaseIgnorable) val caseIgnorableAfter = caseIgnorable(succeedingCaseIgnorable) val sigmaNearby = caseIgnorableBefore + sigma + caseIgnorableAfter val lowerSigmaNearby = caseIgnorableBefore + lowerSigma + caseIgnorableAfter val specialSigmaNearby = caseIgnorableBefore + specialLowerSigma + caseIgnorableAfter for (mask in 0 until (1 shl 4)) { val casedBefore = cased().repeat((mask shr 0) and 1) val casedAfter = cased().repeat((mask shr 1) and 1) val otherBefore = other().repeat((mask shr 2) and 1) val otherAfter = other().repeat((mask shr 3) and 1) val resultSigmaNearby = if (otherBefore.isEmpty() && casedBefore.isNotEmpty() && (otherAfter.isNotEmpty() || casedAfter.isEmpty())) specialSigmaNearby else lowerSigmaNearby val actual = (casedBefore + otherBefore + sigmaNearby + otherAfter + casedAfter).lowercase() val expected = casedBefore.lowercase() + otherBefore + resultSigmaNearby + otherAfter + casedAfter.lowercase() assertEquals( expected, actual, "Expected <$expected>${expected.map { it.hex() }}, Actual <$actual>${actual.map { it.hex() }}" ) } } } } } @Test fun uppercase() { // Non-ASCII assertEquals("\u00DE\u03A9\u0403\uA779", "\u00FE\u03A9\u0453\uA77A".uppercase()) } } ================================================ FILE: backend.native/tests/stdlib_external/text/_IsCaseIgnorableTest.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package test.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // import kotlin.test.* @SharedImmutable private val caseIgnorableRanges = arrayOf( 0x0027..0x0027, 0x002e..0x002e, 0x003a..0x003a, 0x005e..0x005e, 0x0060..0x0060, 0x00a8..0x00a8, 0x00ad..0x00ad, 0x00af..0x00af, 0x00b4..0x00b4, 0x00b7..0x00b7, 0x00b8..0x00b8, 0x02b0..0x02c1, 0x02c2..0x02c5, 0x02c6..0x02d1, 0x02d2..0x02df, 0x02e0..0x02e4, 0x02e5..0x02eb, 0x02ec..0x02ec, 0x02ed..0x02ed, 0x02ee..0x02ee, 0x02ef..0x02ff, 0x0300..0x036f, 0x0374..0x0374, 0x0375..0x0375, 0x037a..0x037a, 0x0384..0x0385, 0x0387..0x0387, 0x0483..0x0487, 0x0488..0x0489, 0x0559..0x0559, 0x055f..0x055f, 0x0591..0x05bd, 0x05bf..0x05bf, 0x05c1..0x05c2, 0x05c4..0x05c5, 0x05c7..0x05c7, 0x05f4..0x05f4, 0x0600..0x0605, 0x0610..0x061a, 0x061c..0x061c, 0x0640..0x0640, 0x064b..0x065f, 0x0670..0x0670, 0x06d6..0x06dc, 0x06dd..0x06dd, 0x06df..0x06e4, 0x06e5..0x06e6, 0x06e7..0x06e8, 0x06ea..0x06ed, 0x070f..0x070f, 0x0711..0x0711, 0x0730..0x074a, 0x07a6..0x07b0, 0x07eb..0x07f3, 0x07f4..0x07f5, 0x07fa..0x07fa, 0x07fd..0x07fd, 0x0816..0x0819, 0x081a..0x081a, 0x081b..0x0823, 0x0824..0x0824, 0x0825..0x0827, 0x0828..0x0828, 0x0829..0x082d, 0x0859..0x085b, 0x08d3..0x08e1, 0x08e2..0x08e2, 0x08e3..0x0902, 0x093a..0x093a, 0x093c..0x093c, 0x0941..0x0948, 0x094d..0x094d, 0x0951..0x0957, 0x0962..0x0963, 0x0971..0x0971, 0x0981..0x0981, 0x09bc..0x09bc, 0x09c1..0x09c4, 0x09cd..0x09cd, 0x09e2..0x09e3, 0x09fe..0x09fe, 0x0a01..0x0a02, 0x0a3c..0x0a3c, 0x0a41..0x0a42, 0x0a47..0x0a48, 0x0a4b..0x0a4d, 0x0a51..0x0a51, 0x0a70..0x0a71, 0x0a75..0x0a75, 0x0a81..0x0a82, 0x0abc..0x0abc, 0x0ac1..0x0ac5, 0x0ac7..0x0ac8, 0x0acd..0x0acd, 0x0ae2..0x0ae3, 0x0afa..0x0aff, 0x0b01..0x0b01, 0x0b3c..0x0b3c, 0x0b3f..0x0b3f, 0x0b41..0x0b44, 0x0b4d..0x0b4d, 0x0b55..0x0b56, 0x0b62..0x0b63, 0x0b82..0x0b82, 0x0bc0..0x0bc0, 0x0bcd..0x0bcd, 0x0c00..0x0c00, 0x0c04..0x0c04, 0x0c3e..0x0c40, 0x0c46..0x0c48, 0x0c4a..0x0c4d, 0x0c55..0x0c56, 0x0c62..0x0c63, 0x0c81..0x0c81, 0x0cbc..0x0cbc, 0x0cbf..0x0cbf, 0x0cc6..0x0cc6, 0x0ccc..0x0ccd, 0x0ce2..0x0ce3, 0x0d00..0x0d01, 0x0d3b..0x0d3c, 0x0d41..0x0d44, 0x0d4d..0x0d4d, 0x0d62..0x0d63, 0x0d81..0x0d81, 0x0dca..0x0dca, 0x0dd2..0x0dd4, 0x0dd6..0x0dd6, 0x0e31..0x0e31, 0x0e34..0x0e3a, 0x0e46..0x0e46, 0x0e47..0x0e4e, 0x0eb1..0x0eb1, 0x0eb4..0x0ebc, 0x0ec6..0x0ec6, 0x0ec8..0x0ecd, 0x0f18..0x0f19, 0x0f35..0x0f35, 0x0f37..0x0f37, 0x0f39..0x0f39, 0x0f71..0x0f7e, 0x0f80..0x0f84, 0x0f86..0x0f87, 0x0f8d..0x0f97, 0x0f99..0x0fbc, 0x0fc6..0x0fc6, 0x102d..0x1030, 0x1032..0x1037, 0x1039..0x103a, 0x103d..0x103e, 0x1058..0x1059, 0x105e..0x1060, 0x1071..0x1074, 0x1082..0x1082, 0x1085..0x1086, 0x108d..0x108d, 0x109d..0x109d, 0x10fc..0x10fc, 0x135d..0x135f, 0x1712..0x1714, 0x1732..0x1734, 0x1752..0x1753, 0x1772..0x1773, 0x17b4..0x17b5, 0x17b7..0x17bd, 0x17c6..0x17c6, 0x17c9..0x17d3, 0x17d7..0x17d7, 0x17dd..0x17dd, 0x180b..0x180d, 0x180e..0x180e, 0x1843..0x1843, 0x1885..0x1886, 0x18a9..0x18a9, 0x1920..0x1922, 0x1927..0x1928, 0x1932..0x1932, 0x1939..0x193b, 0x1a17..0x1a18, 0x1a1b..0x1a1b, 0x1a56..0x1a56, 0x1a58..0x1a5e, 0x1a60..0x1a60, 0x1a62..0x1a62, 0x1a65..0x1a6c, 0x1a73..0x1a7c, 0x1a7f..0x1a7f, 0x1aa7..0x1aa7, 0x1ab0..0x1abd, 0x1abe..0x1abe, 0x1abf..0x1ac0, 0x1b00..0x1b03, 0x1b34..0x1b34, 0x1b36..0x1b3a, 0x1b3c..0x1b3c, 0x1b42..0x1b42, 0x1b6b..0x1b73, 0x1b80..0x1b81, 0x1ba2..0x1ba5, 0x1ba8..0x1ba9, 0x1bab..0x1bad, 0x1be6..0x1be6, 0x1be8..0x1be9, 0x1bed..0x1bed, 0x1bef..0x1bf1, 0x1c2c..0x1c33, 0x1c36..0x1c37, 0x1c78..0x1c7d, 0x1cd0..0x1cd2, 0x1cd4..0x1ce0, 0x1ce2..0x1ce8, 0x1ced..0x1ced, 0x1cf4..0x1cf4, 0x1cf8..0x1cf9, 0x1d2c..0x1d6a, 0x1d78..0x1d78, 0x1d9b..0x1dbf, 0x1dc0..0x1df9, 0x1dfb..0x1dff, 0x1fbd..0x1fbd, 0x1fbf..0x1fc1, 0x1fcd..0x1fcf, 0x1fdd..0x1fdf, 0x1fed..0x1fef, 0x1ffd..0x1ffe, 0x200b..0x200f, 0x2018..0x2018, 0x2019..0x2019, 0x2024..0x2024, 0x2027..0x2027, 0x202a..0x202e, 0x2060..0x2064, 0x2066..0x206f, 0x2071..0x2071, 0x207f..0x207f, 0x2090..0x209c, 0x20d0..0x20dc, 0x20dd..0x20e0, 0x20e1..0x20e1, 0x20e2..0x20e4, 0x20e5..0x20f0, 0x2c7c..0x2c7d, 0x2cef..0x2cf1, 0x2d6f..0x2d6f, 0x2d7f..0x2d7f, 0x2de0..0x2dff, 0x2e2f..0x2e2f, 0x3005..0x3005, 0x302a..0x302d, 0x3031..0x3035, 0x303b..0x303b, 0x3099..0x309a, 0x309b..0x309c, 0x309d..0x309e, 0x30fc..0x30fe, 0xa015..0xa015, 0xa4f8..0xa4fd, 0xa60c..0xa60c, 0xa66f..0xa66f, 0xa670..0xa672, 0xa674..0xa67d, 0xa67f..0xa67f, 0xa69c..0xa69d, 0xa69e..0xa69f, 0xa6f0..0xa6f1, 0xa700..0xa716, 0xa717..0xa71f, 0xa720..0xa721, 0xa770..0xa770, 0xa788..0xa788, 0xa789..0xa78a, 0xa7f8..0xa7f9, 0xa802..0xa802, 0xa806..0xa806, 0xa80b..0xa80b, 0xa825..0xa826, 0xa82c..0xa82c, 0xa8c4..0xa8c5, 0xa8e0..0xa8f1, 0xa8ff..0xa8ff, 0xa926..0xa92d, 0xa947..0xa951, 0xa980..0xa982, 0xa9b3..0xa9b3, 0xa9b6..0xa9b9, 0xa9bc..0xa9bd, 0xa9cf..0xa9cf, 0xa9e5..0xa9e5, 0xa9e6..0xa9e6, 0xaa29..0xaa2e, 0xaa31..0xaa32, 0xaa35..0xaa36, 0xaa43..0xaa43, 0xaa4c..0xaa4c, 0xaa70..0xaa70, 0xaa7c..0xaa7c, 0xaab0..0xaab0, 0xaab2..0xaab4, 0xaab7..0xaab8, 0xaabe..0xaabf, 0xaac1..0xaac1, 0xaadd..0xaadd, 0xaaec..0xaaed, 0xaaf3..0xaaf4, 0xaaf6..0xaaf6, 0xab5b..0xab5b, 0xab5c..0xab5f, 0xab69..0xab69, 0xab6a..0xab6b, 0xabe5..0xabe5, 0xabe8..0xabe8, 0xabed..0xabed, 0xfb1e..0xfb1e, 0xfbb2..0xfbc1, 0xfe00..0xfe0f, 0xfe13..0xfe13, 0xfe20..0xfe2f, 0xfe52..0xfe52, 0xfe55..0xfe55, 0xfeff..0xfeff, 0xff07..0xff07, 0xff0e..0xff0e, 0xff1a..0xff1a, 0xff3e..0xff3e, 0xff40..0xff40, 0xff70..0xff70, 0xff9e..0xff9f, 0xffe3..0xffe3, 0xfff9..0xfffb, 0x101fd..0x101fd, 0x102e0..0x102e0, 0x10376..0x1037a, 0x10a01..0x10a03, 0x10a05..0x10a06, 0x10a0c..0x10a0f, 0x10a38..0x10a3a, 0x10a3f..0x10a3f, 0x10ae5..0x10ae6, 0x10d24..0x10d27, 0x10eab..0x10eac, 0x10f46..0x10f50, 0x11001..0x11001, 0x11038..0x11046, 0x1107f..0x11081, 0x110b3..0x110b6, 0x110b9..0x110ba, 0x110bd..0x110bd, 0x110cd..0x110cd, 0x11100..0x11102, 0x11127..0x1112b, 0x1112d..0x11134, 0x11173..0x11173, 0x11180..0x11181, 0x111b6..0x111be, 0x111c9..0x111cc, 0x111cf..0x111cf, 0x1122f..0x11231, 0x11234..0x11234, 0x11236..0x11237, 0x1123e..0x1123e, 0x112df..0x112df, 0x112e3..0x112ea, 0x11300..0x11301, 0x1133b..0x1133c, 0x11340..0x11340, 0x11366..0x1136c, 0x11370..0x11374, 0x11438..0x1143f, 0x11442..0x11444, 0x11446..0x11446, 0x1145e..0x1145e, 0x114b3..0x114b8, 0x114ba..0x114ba, 0x114bf..0x114c0, 0x114c2..0x114c3, 0x115b2..0x115b5, 0x115bc..0x115bd, 0x115bf..0x115c0, 0x115dc..0x115dd, 0x11633..0x1163a, 0x1163d..0x1163d, 0x1163f..0x11640, 0x116ab..0x116ab, 0x116ad..0x116ad, 0x116b0..0x116b5, 0x116b7..0x116b7, 0x1171d..0x1171f, 0x11722..0x11725, 0x11727..0x1172b, 0x1182f..0x11837, 0x11839..0x1183a, 0x1193b..0x1193c, 0x1193e..0x1193e, 0x11943..0x11943, 0x119d4..0x119d7, 0x119da..0x119db, 0x119e0..0x119e0, 0x11a01..0x11a0a, 0x11a33..0x11a38, 0x11a3b..0x11a3e, 0x11a47..0x11a47, 0x11a51..0x11a56, 0x11a59..0x11a5b, 0x11a8a..0x11a96, 0x11a98..0x11a99, 0x11c30..0x11c36, 0x11c38..0x11c3d, 0x11c3f..0x11c3f, 0x11c92..0x11ca7, 0x11caa..0x11cb0, 0x11cb2..0x11cb3, 0x11cb5..0x11cb6, 0x11d31..0x11d36, 0x11d3a..0x11d3a, 0x11d3c..0x11d3d, 0x11d3f..0x11d45, 0x11d47..0x11d47, 0x11d90..0x11d91, 0x11d95..0x11d95, 0x11d97..0x11d97, 0x11ef3..0x11ef4, 0x13430..0x13438, 0x16af0..0x16af4, 0x16b30..0x16b36, 0x16b40..0x16b43, 0x16f4f..0x16f4f, 0x16f8f..0x16f92, 0x16f93..0x16f9f, 0x16fe0..0x16fe1, 0x16fe3..0x16fe3, 0x16fe4..0x16fe4, 0x1bc9d..0x1bc9e, 0x1bca0..0x1bca3, 0x1d167..0x1d169, 0x1d173..0x1d17a, 0x1d17b..0x1d182, 0x1d185..0x1d18b, 0x1d1aa..0x1d1ad, 0x1d242..0x1d244, 0x1da00..0x1da36, 0x1da3b..0x1da6c, 0x1da75..0x1da75, 0x1da84..0x1da84, 0x1da9b..0x1da9f, 0x1daa1..0x1daaf, 0x1e000..0x1e006, 0x1e008..0x1e018, 0x1e01b..0x1e021, 0x1e023..0x1e024, 0x1e026..0x1e02a, 0x1e130..0x1e136, 0x1e137..0x1e13d, 0x1e2ec..0x1e2ef, 0x1e8d0..0x1e8d6, 0x1e944..0x1e94a, 0x1e94b..0x1e94b, 0x1f3fb..0x1f3ff, 0xe0001..0xe0001, 0xe0020..0xe007f, 0xe0100..0xe01ef, ) class IsCaseIgnorableTest { @Test fun isCaseIgnorable() { var lastChecked = -1 for (range in caseIgnorableRanges) { for (codePoint in lastChecked + 1 until range.first) { assertFalse(codePoint.isCaseIgnorable()) } for (codePoint in range.first..range.last) { assertTrue(codePoint.isCaseIgnorable()) } lastChecked = range.last } for (codePoint in lastChecked + 1..0x10FFFF) { assertFalse(codePoint.isCaseIgnorable()) } } } ================================================ FILE: backend.native/tests/stdlib_external/text/_IsCasedTest.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package test.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // import kotlin.test.* @SharedImmutable private val casedRanges = arrayOf( 0x0041..0x005a, 0x0061..0x007a, 0x00aa..0x00aa, 0x00b5..0x00b5, 0x00ba..0x00ba, 0x00c0..0x00d6, 0x00d8..0x00f6, 0x00f8..0x01ba, 0x01bc..0x01bf, 0x01c4..0x0293, 0x0295..0x02af, 0x02b0..0x02b8, 0x02c0..0x02c1, 0x02e0..0x02e4, 0x0345..0x0345, 0x0370..0x0373, 0x0376..0x0377, 0x037a..0x037a, 0x037b..0x037d, 0x037f..0x037f, 0x0386..0x0386, 0x0388..0x038a, 0x038c..0x038c, 0x038e..0x03a1, 0x03a3..0x03f5, 0x03f7..0x0481, 0x048a..0x052f, 0x0531..0x0556, 0x0560..0x0588, 0x10a0..0x10c5, 0x10c7..0x10c7, 0x10cd..0x10cd, 0x10d0..0x10fa, 0x10fd..0x10ff, 0x13a0..0x13f5, 0x13f8..0x13fd, 0x1c80..0x1c88, 0x1c90..0x1cba, 0x1cbd..0x1cbf, 0x1d00..0x1d2b, 0x1d2c..0x1d6a, 0x1d6b..0x1d77, 0x1d78..0x1d78, 0x1d79..0x1d9a, 0x1d9b..0x1dbf, 0x1e00..0x1f15, 0x1f18..0x1f1d, 0x1f20..0x1f45, 0x1f48..0x1f4d, 0x1f50..0x1f57, 0x1f59..0x1f59, 0x1f5b..0x1f5b, 0x1f5d..0x1f5d, 0x1f5f..0x1f7d, 0x1f80..0x1fb4, 0x1fb6..0x1fbc, 0x1fbe..0x1fbe, 0x1fc2..0x1fc4, 0x1fc6..0x1fcc, 0x1fd0..0x1fd3, 0x1fd6..0x1fdb, 0x1fe0..0x1fec, 0x1ff2..0x1ff4, 0x1ff6..0x1ffc, 0x2071..0x2071, 0x207f..0x207f, 0x2090..0x209c, 0x2102..0x2102, 0x2107..0x2107, 0x210a..0x2113, 0x2115..0x2115, 0x2119..0x211d, 0x2124..0x2124, 0x2126..0x2126, 0x2128..0x2128, 0x212a..0x212d, 0x212f..0x2134, 0x2139..0x2139, 0x213c..0x213f, 0x2145..0x2149, 0x214e..0x214e, 0x2160..0x217f, 0x2183..0x2184, 0x24b6..0x24e9, 0x2c00..0x2c2e, 0x2c30..0x2c5e, 0x2c60..0x2c7b, 0x2c7c..0x2c7d, 0x2c7e..0x2ce4, 0x2ceb..0x2cee, 0x2cf2..0x2cf3, 0x2d00..0x2d25, 0x2d27..0x2d27, 0x2d2d..0x2d2d, 0xa640..0xa66d, 0xa680..0xa69b, 0xa69c..0xa69d, 0xa722..0xa76f, 0xa770..0xa770, 0xa771..0xa787, 0xa78b..0xa78e, 0xa790..0xa7bf, 0xa7c2..0xa7ca, 0xa7f5..0xa7f6, 0xa7f8..0xa7f9, 0xa7fa..0xa7fa, 0xab30..0xab5a, 0xab5c..0xab5f, 0xab60..0xab68, 0xab70..0xabbf, 0xfb00..0xfb06, 0xfb13..0xfb17, 0xff21..0xff3a, 0xff41..0xff5a, 0x10400..0x1044f, 0x104b0..0x104d3, 0x104d8..0x104fb, 0x10c80..0x10cb2, 0x10cc0..0x10cf2, 0x118a0..0x118df, 0x16e40..0x16e7f, 0x1d400..0x1d454, 0x1d456..0x1d49c, 0x1d49e..0x1d49f, 0x1d4a2..0x1d4a2, 0x1d4a5..0x1d4a6, 0x1d4a9..0x1d4ac, 0x1d4ae..0x1d4b9, 0x1d4bb..0x1d4bb, 0x1d4bd..0x1d4c3, 0x1d4c5..0x1d505, 0x1d507..0x1d50a, 0x1d50d..0x1d514, 0x1d516..0x1d51c, 0x1d51e..0x1d539, 0x1d53b..0x1d53e, 0x1d540..0x1d544, 0x1d546..0x1d546, 0x1d54a..0x1d550, 0x1d552..0x1d6a5, 0x1d6a8..0x1d6c0, 0x1d6c2..0x1d6da, 0x1d6dc..0x1d6fa, 0x1d6fc..0x1d714, 0x1d716..0x1d734, 0x1d736..0x1d74e, 0x1d750..0x1d76e, 0x1d770..0x1d788, 0x1d78a..0x1d7a8, 0x1d7aa..0x1d7c2, 0x1d7c4..0x1d7cb, 0x1e900..0x1e943, 0x1f130..0x1f149, 0x1f150..0x1f169, 0x1f170..0x1f189, ) class IsCasedTest { @Test fun isCased() { var lastChecked = -1 for (range in casedRanges) { for (codePoint in lastChecked + 1 until range.first) { assertFalse(codePoint.isCased()) } for (codePoint in range.first..range.last) { assertTrue(codePoint.isCased()) } lastChecked = range.last } for (codePoint in lastChecked + 1..0x10FFFF) { assertFalse(codePoint.isCased()) } } } ================================================ FILE: backend.native/tests/stdlib_external/utils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test import kotlin.test.* public actual fun assertTypeEquals(expected: Any?, actual: Any?) { if (expected != null && actual != null) { assertTrue(expected::class.isInstance(actual) || actual::class.isInstance(expected), "Expected: $expected, Actual: $actual") } else { assertTrue(expected == null && actual == null) } } internal actual fun String.removeLeadingPlusOnJava6(): String = this internal actual inline fun testOnNonJvm6And7(f: () -> Unit) { f() } actual fun testOnJvm(action: () -> Unit) {} actual fun testOnJs(action: () -> Unit) {} public actual val isFloat32RangeEnforced: Boolean get() = true public actual val supportsSuppressedExceptions: Boolean get() = true ================================================ FILE: backend.native/tests/testLibrary/kotlin/test_platform_lib.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package test.konan.platform fun produceMessage() { println("""This is a side effect of a test library linked into the binary. You should not be seeing this. """) } val x: Unit = produceMessage() ================================================ FILE: backend.native/tests/testing/annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.test.tests import kotlin.test.* import kotlin.native.internal.test.* @Ignore class IgnoredClass { @Ignore object IgnoredObject { @Test fun test() { throw AssertionError("Ignored test") } } @Test fun test() { throw AssertionError("Ignored test") } } @Ignore object IgnoredObject { @Test fun test() { throw AssertionError("Ignored test") } } class A { companion object { @BeforeTest fun before() { println("before (A.companion)") } @AfterTest fun after() { println("after (A.companion)") } @Test fun test1() { println("test1 (A.companion)") } @BeforeClass fun beforeClass() { println("beforeClass (A.companion)") } @AfterClass fun afterClass() { println("afterClass (A.companion)") } } @BeforeTest fun before() { println("before (A)") } @AfterTest fun after() { println("after (A)") } @Test fun test1() { println("test1 (A)") } @Ignore @Test fun ignoredTest() { throw AssertionError("Ignored test") } @BeforeClass fun beforeClass() { println("beforeClass (A)") } @AfterClass fun afterClass() { println("afterClass (A)") } object O { @BeforeTest fun before() { println("before (A.object)") } @AfterTest fun after() { println("after (A.object)") } @Test fun test1() { println("test1 (A.object)") } @Ignore @Test fun ignoredTest() { throw AssertionError("Ignored test") } @BeforeClass fun beforeClass() { println("beforeClass (A.object)") } @AfterClass fun afterClass() { println("afterClass (A.object)") } } } object O { @BeforeTest fun before() { println("before (object)") } @AfterTest fun after() { println("after (object)") } @Test fun test1() { println("test1 (object)") } @Ignore @Test fun ignoredTest() { throw AssertionError("Ignored test") } @BeforeClass fun beforeClass() { println("beforeClass (object)") } @AfterClass fun afterClass() { println("afterClass (object)") } } @BeforeTest fun before() { println("before (file)") } @AfterTest fun after() { println("after (file)") } @Test fun test1() { println("test1 (file)") } @Ignore @Test fun ignoredTest() { throw AssertionError("Ignored test") } @BeforeClass fun beforeClass() { println("beforeClass (file)") } @AfterClass fun afterClass() { println("afterClass (file)") } ================================================ FILE: backend.native/tests/testing/assertions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.test.tests import kotlin.test.* class BasicAssertionsTest { @Test fun testAssertEquals() { assertEquals(1, 1) } @Test fun testAssertEqualsString() { assertEquals("a", "a") } @Test fun testAssertFailsWith() { assertFailsWith { throw IllegalStateException() } assertFailsWith { throw AssertionError() } } @Test fun testAssertFailsWithFails() { withDefaultAsserter run@ { try { assertFailsWith { throw IllegalArgumentException() } } catch (e: AssertionError) { return@run } throw AssertionError("Expected to fail") } withDefaultAsserter run@ { try { assertFailsWith { } } catch (e: AssertionError) { return@run } throw AssertionError("Expected to fail") } } @Test fun testAssertFailsWithClass() { assertFailsWith { throw IllegalArgumentException("This is illegal") } } @Test fun testAssertFailsWithClassFails() { checkFailedAssertion { assertFailsWith { throw IllegalStateException() } } checkFailedAssertion { assertFailsWith { } } } @Test fun testAssertEqualsFails() { checkFailedAssertion { assertEquals(1, 2) } } @Test fun testAssertTrue() { assertTrue(true) assertTrue { true } } @Test() fun testAssertTrueFails() { checkFailedAssertion { assertTrue(false) } checkFailedAssertion { assertTrue { false } } } @Test fun testAssertFalse() { assertFalse(false) assertFalse { false } } @Test fun testAssertFalseFails() { checkFailedAssertion { assertFalse(true) } checkFailedAssertion{ assertFalse { true } } } @Test fun testAssertFails() { assertFails { throw IllegalStateException() } } @Test() fun testAssertFailsFails() { checkFailedAssertion { assertFails { } } } @Test fun testAssertNotEquals() { assertNotEquals(1, 2) } @Test() fun testAssertNotEqualsFails() { checkFailedAssertion { assertNotEquals(1, 1) } } @Test fun testAssertNotNull() { assertNotNull(true) } @Test() fun testAssertNotNullFails() { checkFailedAssertion { assertNotNull(null) } } @Test fun testAssertNotNullLambda() { assertNotNull("") { assertEquals("", it) } } @Test fun testAssertNotNullLambdaFails() { checkFailedAssertion { val value: String? = null assertNotNull(value) { it.substring(0, 0) } } } @Test fun testAssertNull() { assertNull(null) } @Test fun testAssertNullFails() { checkFailedAssertion { assertNull("") } } @Test() fun testFail() { checkFailedAssertion { fail("should fail") } } @Test fun testExpect() { expect(1) { 1 } } @Test fun testExpectFails() { checkFailedAssertion { expect(1) { 2 } } } @Test fun testContracts() { open class S class P(val str: String = "P") : S() val s: S = P() val p: Any = P("A") assertTrue(s is P) assertEquals("P", s.str) assertFalse(p !is P) assertEquals("A", p.str) val nullableT: P? = P("N") assertNotNull(nullableT) assertEquals("N", nullableT.str) } } private fun checkFailedAssertion(assertion: () -> Unit) { assertFailsWith { withDefaultAsserter(assertion) } } @Suppress("INVISIBLE_MEMBER") private fun withDefaultAsserter(block: () -> Unit) { block() } ================================================ FILE: backend.native/tests/testing/custom_main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.test.tests import kotlin.test.* import kotlin.native.internal.test.* @Test fun test() { println("test") } fun main(args: Array) { println("Custom main") testLauncherEntryPoint(args) } ================================================ FILE: backend.native/tests/testing/filtered_suites.kt ================================================ package kotlin.test.tests import kotlin.test.* private fun hook(message: String) { print("Hook: ") println(message) } class A { @Test fun foo() {} @Test fun common() {} @Ignore @Test fun ignored() {} companion object { @BeforeClass fun before() = hook("A.before") @AfterClass fun after() = hook("A.after") } } @Ignore class Ignored { @Test fun bar() {} @Test fun common() {} companion object { @BeforeClass fun before() = hook("Ignored.before") @AfterClass fun after() = hook("Ignored.after") } } @BeforeClass fun before() = hook("Filtered_suitesKt.before") @AfterClass fun after() = hook("Filtered_suitesKt.after") @Test fun baz() {} @Test fun common() {} ================================================ FILE: backend.native/tests/testing/filters.kt ================================================ package kotlin.test.tests import kotlin.test.* class A { @Test fun foo1() {} @Test fun foo2() {} @Test fun bar() {} } class B { @Test fun foo1() {} @Test fun foo2() {} @Test fun bar() {} } @Test fun foo1() {} @Test fun foo2() {} @Test fun bar() {} ================================================ FILE: backend.native/tests/testing/library.kt ================================================ package library import kotlin.test.* val output = mutableListOf() interface I1 { @Test fun foo() } interface I2 { @Test fun foo() } open class A { @BeforeTest open fun before() { output.add("A.before") } @AfterTest open fun after() { output.add("A.after") } @Test open fun test0() { output.add("A.test0") } @Test open fun test1() { output.add("A.test1") } @Test open fun test2() { output.add("A.test2") } @Test open fun test3() { output.add("A.test3") } @Ignore @Test open fun ignored0() { output.add("A.ignored0") } @Ignore @Test open fun ignored1() { output.add("A.ignored1") } @Ignore @Test open fun ignored2() { output.add("A.ignored2") } } ================================================ FILE: backend.native/tests/testing/library_user.kt ================================================ import kotlin.native.internal.test.* import kotlin.test.* import library.* open class B : A() { // Override test methods without a test annotation. // We should run these methods anyway. override fun before() { output.add("B.before") } // test0 should be executed. // Should be executed. override fun test1() { output.add("B.test1") } // Should be executed @Ignore override fun test2() { output.add("B.test2") } // Should be ignored. @Ignore @Test override fun test3() { output.add("B.test3") } // ignored0 should be ignored. // Should be ignored. override fun ignored1() { output.add("B.ignored1") } // Should be executed. @Test override fun ignored2() { output.add("B.ignored2") } } // All test methods from B should be executed for C. class C: B() {} class D: I1, I2 { // This method shouldn't be executed because its parent methods annotated // with @Test belong to an interface instead of an abstract class. override fun foo(){ output.add("D.foo") } } fun main(args: Array) { testLauncherEntryPoint(args) output.forEach(::println) assertEquals(8, output.count { it == "A.after" }) assertEquals(8, output.count { it == "B.before" }) assertEquals(2, output.count { it == "A.test0" }) assertEquals(2, output.count { it == "B.test1" }) assertEquals(2, output.count { it == "B.test2" }) assertEquals(2, output.count { it == "B.ignored2" }) assertTrue(output.none { it == "B.test3" }) assertTrue(output.none { it == "A.ignored0" }) assertTrue(output.none { it == "B.ignored1" }) assertTrue(output.none { it == "D.foo" }) } ================================================ FILE: backend.native/tests/testing/stacktrace.kt ================================================ package kotlin.test.tests import kotlin.test.* @Ignore class Ignored { @Test fun foo() {} } class Failed { @Test fun bar() { try { baz() } catch(e: Exception) { throw Exception("Bar", e) } } fun baz() { throw Exception("Baz") } } ================================================ FILE: build-tools/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import java.util.Properties plugins { // We explicitly configure versions of plugins in settings.gradle.kts. // due to https://github.com/gradle/gradle/issues/1697. id("kotlin") groovy `java-gradle-plugin` } buildscript { dependencies { classpath("com.google.code.gson:gson:2.8.6") } } val rootProperties = Properties().apply { rootDir.resolve("../gradle.properties").reader().use(::load) } val kotlinVersion: String by rootProperties val kotlinCompilerRepo: String by rootProperties val buildKotlinVersion: String by rootProperties val buildKotlinCompilerRepo: String by rootProperties val konanVersion: String by rootProperties val slackApiVersion: String by rootProperties val ktorVersion: String by rootProperties val shadowVersion: String by rootProperties val metadataVersion: String by rootProperties group = "org.jetbrains.kotlin" version = konanVersion repositories { maven(kotlinCompilerRepo) maven(buildKotlinCompilerRepo) maven("https://cache-redirector.jetbrains.com/maven-central") mavenCentral() maven("https://kotlin.bintray.com/kotlinx") maven("https://dl.bintray.com/kotlin/kotlin-dev") maven("https://cache-redirector.jetbrains.com/jcenter") jcenter() } dependencies { compileOnly(gradleApi()) implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") implementation("com.ullink.slack:simpleslackapi:$slackApiVersion") implementation("io.ktor:ktor-client-auth:$ktorVersion") implementation("io.ktor:ktor-client-core:$ktorVersion") implementation("io.ktor:ktor-client-cio:$ktorVersion") api("org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion") // Located in /shared and always provided by the composite build. api("org.jetbrains.kotlin:kotlin-native-shared:$konanVersion") implementation("com.github.jengelman.gradle.plugins:shadow:$shadowVersion") implementation("org.jetbrains.kotlinx:kotlinx-metadata-klib:$metadataVersion") } sourceSets["main"].withConvention(KotlinSourceSet::class) { kotlin.srcDir("$projectDir/../tools/benchmarks/shared/src/main/kotlin/report") } gradlePlugin { plugins { create("benchmarkPlugin") { id = "benchmarking" implementationClass = "org.jetbrains.kotlin.benchmark.KotlinNativeBenchmarkingPlugin" } create("compileBenchmarking") { id = "compile-benchmarking" implementationClass = "org.jetbrains.kotlin.benchmark.CompileBenchmarkingPlugin" } create("swiftBenchmarking") { id = "swift-benchmarking" implementationClass = "org.jetbrains.kotlin.benchmark.SwiftBenchmarkingPlugin" } create("compileToBitcode") { id = "compile-to-bitcode" implementationClass = "org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin" } create("runtimeTesting") { id = "runtime-testing" implementationClass = "org.jetbrains.kotlin.testing.native.RuntimeTestingPlugin" } } } val compileKotlin: KotlinCompile by tasks val compileGroovy: GroovyCompile by tasks // https://youtrack.jetbrains.com/issue/KT-37435 compileKotlin.apply { kotlinOptions.jvmTarget = "1.8" kotlinOptions.freeCompilerArgs += listOf("-Xno-optimized-callable-references", "-Xskip-prerelease-check") } // Add Kotlin classes to a classpath for the Groovy compiler compileGroovy.apply { classpath += project.files(compileKotlin.destinationDir) dependsOn(compileKotlin) } ================================================ FILE: build-tools/settings.gradle.kts ================================================ pluginManagement { val rootProperties = java.util.Properties().apply { rootDir.resolve("../gradle.properties").reader().use(::load) } val buildKotlinCompilerRepo: String by rootProperties val kotlinCompilerRepo: String by rootProperties val buildKotlinVersion by rootProperties repositories { maven(kotlinCompilerRepo) maven(buildKotlinCompilerRepo) maven("https://cache-redirector.jetbrains.com/maven-central") mavenCentral() } resolutionStrategy { eachPlugin { if (requested.id.id == "kotlin") { useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$buildKotlinVersion") } } } } rootProject.name = "kotlin-native-build-tools" includeBuild("../shared") ================================================ FILE: build-tools/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin import org.gradle.api.tasks.Input import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.TaskAction import org.gradle.process.ExecResult import org.jetbrains.kotlin.utils.DFS import java.nio.file.Paths import java.util.function.Function import java.util.function.UnaryOperator import java.util.regex.Pattern import java.util.stream.Collectors class RunExternalTestGroup extends JavaExec implements CompilerRunner { def platformManager = project.rootProject.platformManager def target = platformManager.targetManager(project.testTarget).target def dist = UtilsKt.getKotlinNativeDist(project) def enableKonanAssertions = true def verifyIr = true String outputDirectory = null String goldValue = null // Checks test's output against gold value and returns true if the output matches the expectation Function outputChecker = { str -> (goldValue == null || goldValue == str) } boolean printOutput = true String testData = null int expectedExitStatus = 0 List arguments = null List flags = null boolean multiRuns = false List> multiArguments = null boolean expectedFail = false boolean compilerMessages = false // Uses directory defined in $outputSourceSetName source set void createOutputDirectory() { if (outputDirectory != null) { return } def outputSourceSet = UtilsKt.getTestOutputExternal(project) outputDirectory = Paths.get(outputSourceSet, name).toString() project.file(outputDirectory).mkdirs() } RunExternalTestGroup() { // We don't build the compiler if a custom dist path is specified. UtilsKt.dependsOnDist(this) main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' } @Override void exec() { // Perhaps later we will return this exec() back but for now rest of infrastructure expects // compilation begins on runCompiler call, to emulate this behaviour we call super.exec() after // configuration part at runCompiler. } @Override void runCompiler(List filesToCompile, String output, List moreArgs) { def log = new ByteArrayOutputStream() try { classpath = project.fileTree("$dist.canonicalPath/konan/lib/") { include '*.jar' } jvmArgs "-Xmx4G" enableAssertions = true def sources = File.createTempFile(name,".lst") sources.deleteOnExit() def sourcesWriter = sources.newWriter() filesToCompile.each { f -> sourcesWriter.write(f.chars().any { Character.isWhitespace(it) } ? "\"${f.replace("\\", "\\\\")}\"\n" // escape file name : "$f\n") } sourcesWriter.close() args = ["-output", output, "@${sources.absolutePath}", *moreArgs, *project.globalTestArgs] if (project.testTarget) { args "-target", target.visibleName } if (enableKonanAssertions) { args "-ea" } if (verifyIr) { args "-Xverify-ir" } if (project.hasProperty("test_verbose")) { println("Files to compile: $filesToCompile") println(args) } standardOutput = log errorOutput = log super.exec() } finally { def logString = log.toString("UTF-8") project.file("${output}.compilation.log").write(logString) println(logString) } } // FIXME: output directory here changes and hence this is not a property String executablePath() { return "$outputDirectory/program.tr" } OutputStream out void runExecutable() { if (!enabled) { println "Test is disabled: $name" return } def program = executablePath() def suffix = target.family.exeSuffix def exe = "$program.$suffix" println "execution: $exe" def compilerMessagesText = compilerMessages ? project.file("${program}.compilation.log").getText('UTF-8') : "" out = new ByteArrayOutputStream() //TODO Add test timeout def times = multiRuns ? multiArguments.size() : 1 def exitCodeMismatch = false for (int i = 0; i < times; i++) { ExecResult execResult = project.execute { commandLine exe if (arguments != null) { args arguments } if (multiRuns && multiArguments[i] != null) { args multiArguments[i] } if (testData != null) { standardInput = new ByteArrayInputStream(testData.bytes) } standardOutput = out ignoreExitValue = true } exitCodeMismatch |= execResult.exitValue != expectedExitStatus if (exitCodeMismatch) { def message = "Expected exit status: $expectedExitStatus, actual: ${execResult.exitValue}" if (this.expectedFail) { println("Expected failure. $message") } else { throw new TestFailedException("Test failed on iteration $i. $message\n ${out.toString("UTF-8")}") } } } def result = compilerMessagesText + out.toString("UTF-8") if (printOutput) { println(result) } result = result.replace(System.lineSeparator(), "\n") def goldValueMismatch = !outputChecker.apply(result) if (goldValueMismatch) { def message if (goldValue != null) { message = "Expected output: $goldValue, actual output: $result" } else { message = "Actual output doesn't match output checker: $result" } if (this.expectedFail) { println("Expected failure. $message") } else { throw new TestFailedException("Test failed. $message") } } if (!exitCodeMismatch && !goldValueMismatch && this.expectedFail) println("Unexpected pass") } /** * If true, the test executable will be built in two stages: * 1. Build a klibrary from sources. * 2. Build a final executable from this klibrary. */ @Input public def enableTwoStageCompilation = false @Input def groupDirectory = "." String filter = project.findProperty("filter") def testGroupReporter = new KonanTestGroupReportEnvironment(project) void parseLanguageFlags(String src) { def text = project.buildDir.toPath().resolve(src).text def languageSettings = findLinesWithPrefixesRemoved(text, "// !LANGUAGE: ") if (languageSettings.size() != 0) { languageSettings.forEach { line -> line.split(" ").toList().forEach { if (it != "+NewInference") // It is on already by default, but passing it explicitly turns on a special "compatibility mode" in FE which is not desirable. flags.add("-XXLanguage:$it") } } } def experimentalSettings = findLinesWithPrefixesRemoved(text, "// !USE_EXPERIMENTAL: ") if (experimentalSettings.size() != 0) { experimentalSettings.forEach { line -> line.split(" ").toList().forEach { flags.add("-Xopt-in=$it") } } } def expectActualLinker = findLinesWithPrefixesRemoved(text, "// EXPECT_ACTUAL_LINKER") if (expectActualLinker.size() != 0) { flags.add("-Xexpect-actual-linker") } } static String markMutableObjects(String text) { def lines = text.readLines() def result = new ArrayList(lines.size()) lines.forEach { line -> // FIXME: find only those who has vars inside // Find object declarations and companion objects if (line.matches("\\s*(private|public|internal)?\\s*object [a-zA-Z_][a-zA-Z0-9_]*\\s*.*") || line.matches("\\s*(private|public|internal)?\\s*companion object.*")) { result += "@kotlin.native.ThreadLocal" } result += line } return result.join(System.lineSeparator()) } static String insertInTextAfter(String text, String insert, String after) { def begin = text.indexOf(after) if (begin != -1) { def end = text.indexOf("\n", begin) text = text.substring(0, end) + insert + text.substring(end) } else { text = insert + text } return text } List createTestFiles(String src) { def identifier = /[a-zA-Z_][a-zA-Z0-9_]/ def fullQualified = /[a-zA-Z_][a-zA-Z0-9_.]/ def importRegex = /(?m)^\s*import\s+/ def packagePattern = ~/(?m)^\s*package\s+(${fullQualified}*)/ def boxPattern = ~/(?m)fun\s+box\s*\(\s*\)/ def classPattern = ~/.*(class|object|enum|interface)\s+(${identifier}*).*/ def sourceName = "_" + normalize(project.buildDir.toPath().resolve(src).toFile().name) def packages = new LinkedHashSet() def imports = [] def classes = [] def vars = new HashSet() // variables that has the same name as a package TestModule mainModule = null def testFiles = TestDirectivesKt.buildCompileList(project.file("build/$src").toPath(), "$outputDirectory/$src") for (TestFile testFile: testFiles) { def text = testFile.text def filePath = testFile.path if (text.contains('COROUTINES_PACKAGE')) { text = text.replace('COROUTINES_PACKAGE', 'kotlin.coroutines') } def pkg if (text =~ packagePattern) { pkg = (text =~ packagePattern)[0][1] packages.add(pkg) pkg = "$sourceName.$pkg" text = text.replaceFirst(packagePattern, "package $pkg") } else { pkg = sourceName text = insertInTextAfter(text, "\npackage $pkg\n", "@file:") } if (text =~ boxPattern) { imports.add("${pkg}.*") mainModule = testFile.module } // Find mutable objects that should be marked as ThreadLocal if (filePath != "$outputDirectory/$src/helpers.kt") { text = markMutableObjects(text) } testFile.text = text } for (TestFile testFile: testFiles) { def text = testFile.text // Find if there are any imports in the file def matcher = (text =~ ~/${importRegex}(${fullQualified}*)/) if (matcher) { // Prepend package name to found imports for (int i = 0; i < matcher.count; i++) { String importStatement = matcher[i][1] def subImport = importStatement.with { int dotIdx = indexOf('.') dotIdx > 0 ? substring(0, dotIdx) : it } if (packages.contains(subImport) || classes.contains(subImport)) { // add only to those who import packages or import classes from the test files text = text.replaceFirst(~/${importRegex}${Pattern.quote(importStatement)}/, "import $sourceName.$importStatement") } else if (text =~ classPattern) { // special case for import from the local class def clsMatcher = (text =~ classPattern) for (int j = 0; j < clsMatcher.count; j++) { def cl = (text =~ classPattern)[j][2] classes.add(cl) if (subImport == cl) { text = text.replaceFirst(~/${importRegex}${Pattern.quote(importStatement)}/, "import $sourceName.$importStatement") } } } } } else if (packages.empty) { // Add import statement after package def pkg = null if (text =~ packagePattern) { pkg = 'package ' + (text =~ packagePattern)[0][1] text = text.replaceFirst(packagePattern, '') } text = insertInTextAfter(text, (pkg ? "\n$pkg\n" : "") + "import $sourceName.*\n", "@file:") } // now replace all package usages in full qualified names def res = "" // filesToCompile text.eachLine { line -> packages.each { pkg -> // line contains val or var declaration or function parameter declaration if ((line =~ ~/va(l|r) *$pkg*( *: *$fullQualified*)?( *get\(\))? *\=.*/) || (line =~ ~/fun .*\(\n?\s*$pkg:.*/)) { vars.add(pkg) } if (line.contains("$pkg.") && !(line =~ packagePattern || line =~ importRegex) && !vars.contains(pkg)) { def idx = 0 while ((idx = line.indexOf(pkg, idx)) >= 0) { if (!Character.isJavaIdentifierPart(line.charAt(idx - 1))) { line = line.substring(0, idx) + "$sourceName.$pkg" + line.substring(idx + pkg.length()) idx += sourceName.length() + pkg.length() + 1 } else { idx += pkg.length() } } } } res += "$line\n" } testFile.text = res } def launcherText = createLauncherFileText(src, imports) testFiles.add(new TestFile("_launcher.kt", "$outputDirectory/$src/_launcher.kt".toString(), launcherText, mainModule != null ? mainModule : TestModule.default)) return testFiles } String normalize(String name) { name.replace('.kt', '') .replace('-','_') .replace('.', '_') } /** * There are tests that require non-trivial 'package foo' in test launcher. */ String createLauncherFileText(String src, List imports) { StringBuilder text = new StringBuilder() def pack = normalize(project.file(src).name) text.append("package _$pack\n") for (v in imports) { text.append("import $v\n") } text.append( """ import kotlin.test.Test @Test fun runTest() { @Suppress("UNUSED_VARIABLE") val result = box() if (result != "OK") throw AssertionError("Test failed with: " + result) } """ ) return text.toString() } List findLinesWithPrefixesRemoved(String text, String prefix) { def result = [] text.eachLine { if (it.startsWith(prefix)) { result.add(it - prefix) } } return result } static def excludeList = [ "external/compiler/codegen/boxInline/multiplatform/defaultArguments/receiversAndParametersInLambda.kt", // KT-36880 "external/compiler/compileKotlinAgainstKotlin/specialBridgesInDependencies.kt", // KT-42723 "external/compiler/codegen/box/collections/kt41123.kt", // KT-42723 "external/compiler/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt", // KT-40137 "external/compiler/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt", // KT-33091 "external/compiler/codegen/box/multiplatform/multiModule/expectActualLink.kt", // KT-41901 "external/compiler/codegen/box/coroutines/multiModule/", // KT-40121 "external/compiler/codegen/box/defaultArguments/recursiveDefaultArguments.kt" // KT-42684 ] boolean isEnabledForNativeBackend(String fileName) { def text = project.buildDir.toPath().resolve(fileName).text if (excludeList.any { fileName.replace(File.separator, "/").contains(it) }) return false def languageSettings = findLinesWithPrefixesRemoved(text, '// !LANGUAGE: ') if (!languageSettings.empty) { def settings = languageSettings.first() if (settings.contains('-ProperIeee754Comparisons') || // K/N supports only proper IEEE754 comparisons settings.contains('-ReleaseCoroutines') || // only release coroutines settings.contains('-DataClassInheritance') || // old behavior is not supported settings.contains('-ProhibitAssigningSingleElementsToVarargsInNamedForm')) { // Prohibit these assignments return false } } def version = findLinesWithPrefixesRemoved(text, '// LANGUAGE_VERSION: ') if (version.size() != 0 && (!version.contains("1.3") || !version.contains("1.4"))) { // Support tests for 1.3 and exclude 1.2 return false } def apiVersion = findLinesWithPrefixesRemoved(text, '// !API_VERSION: ') if (apiVersion.size() != 0 && !apiVersion.contains("1.4")) { return false } def targetBackend = findLinesWithPrefixesRemoved(text, "// TARGET_BACKEND") if (targetBackend.size() != 0) { // There is some target backend. Check if it is NATIVE or not. for (String s : targetBackend) { if (s.contains("NATIVE")){ return true } } return false } else { // No target backend. Check if NATIVE backend is ignored. def ignoredBackends = findLinesWithPrefixesRemoved(text, "// IGNORE_BACKEND: ") for (String s : ignoredBackends) { if (s.contains("NATIVE")) { return false } } // No ignored backends. Check if test is targeted to FULL_JDK or has JVM_TARGET set if (!findLinesWithPrefixesRemoved(text, "// FULL_JDK").isEmpty()) { return false } if (!findLinesWithPrefixesRemoved(text, "// JVM_TARGET:").isEmpty()) { return false } return true } } @TaskAction void executeTest() { createOutputDirectory() // Form the test list. List ktFiles = project.buildDir.toPath().resolve(groupDirectory).toFile() .listFiles({ it.isFile() && it.name.endsWith(".kt") } as FileFilter) if (filter != null) { def pattern = ~filter ktFiles = ktFiles.findAll { it.name =~ pattern } } testGroupReporter.suite(name) { suite -> // Build tests in the group flags = (flags ?: []) + "-tr" List compileList = [] ktFiles.each { def src = project.buildDir.relativePath(it) if (isEnabledForNativeBackend(src)) { // Create separate output directory for each test in the group. project.file("$outputDirectory/${it.name}").mkdirs() parseLanguageFlags(src) compileList.addAll(createTestFiles(src)) } } compileList*.writeTextToFile() try { if (enableTwoStageCompilation) { // Two-stage compilation. def klibPath = "${executablePath()}.klib" def files = compileList.stream() .map { it.path } .collect(Collectors.toList()) if (!files.empty) { runCompiler(files, klibPath, flags + ["-p", "library"]) runCompiler([], executablePath(), flags + ["-Xinclude=$klibPath"]) } } else { // Regular compilation with modules. Map modules = compileList.stream() .map { it.module } .distinct() .collect(Collectors.toMap({ it.name }, UnaryOperator.identity() )) List orderedModules = DFS.INSTANCE.topologicalOrder(modules.values()) { module -> module.dependencies.collect { modules[it] }.findAll { it != null } } def compiler = new MultiModuleCompilerInvocations(this, outputDirectory, executablePath(), modules, flags) orderedModules.reverse().each { module -> if (!module.isDefaultModule()) { compiler.produceLibrary(module) } } compiler.produceProgram(compileList) } } catch (Exception ex) { project.logger.quiet("ERROR: Compilation failed for test suite: $name with exception", ex) project.logger.quiet("The following files were unable to compile:") ktFiles.each { project.logger.quiet(it.name) } suite.abort(ex, ktFiles.size()) throw new RuntimeException("Compilation failed", ex) } // Run the tests. arguments = (arguments ?: []) + "--ktest_logger=SILENT" ktFiles.each { file -> def src = project.buildDir.relativePath(file) def savedArgs = arguments arguments += "--ktest_filter=_${normalize(file.name)}.*" use(KonanTestSuiteReportKt) { project.logger.quiet("TEST: $file.name " + "(done: $testGroupReporter.statistics.total/${ktFiles.size()}, " + "passed: $testGroupReporter.statistics.passed, " + "skipped: $testGroupReporter.statistics.skipped)") } if (isEnabledForNativeBackend(src)) { suite.executeTest(file.name) { project.logger.quiet(src) runExecutable() } } else { suite.skipTest(file.name) } arguments = savedArgs } } } } ================================================ FILE: build-tools/src/main/groovy/org/jetbrains/kotlin/NativeInteropPlugin.groovy ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin import org.gradle.api.Named import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.Configuration import org.gradle.api.file.FileCollection import org.gradle.api.internal.AbstractNamedDomainObjectContainer import org.gradle.api.internal.CollectionCallbackActionDecorator import org.gradle.api.internal.file.AbstractFileCollection import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskDependency import org.gradle.internal.reflect.Instantiator import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.* class NamedNativeInteropConfig implements Named { private final Project project final String name private String interopStubsName private SourceSet interopStubs final JavaExec genTask private String flavor = "jvm" private String defFile private String pkg private String target private List compilerOpts = [] private List headers; private String linker List linkerOpts = [] private FileCollection linkFiles; private List linkTasks = [] Configuration configuration void flavor(String value) { flavor = value } void defFile(String value) { defFile = value genTask.inputs.file(project.file(defFile)) } void target(String value) { target = value } void pkg(String value) { pkg = value } void compilerOpts(List values) { compilerOpts.addAll(values) } void compilerOpts(String... values) { compilerOpts.addAll(values) } void headers(FileCollection files) { dependsOnFiles(files) headers = headers + files.toSet().collect { it.absolutePath } } void headers(String... values) { headers = headers + values.toList() } void linker(String value) { linker = value } void linkerOpts(String... values) { this.linkerOpts(values.toList()) } void linkerOpts(List values) { linkerOpts.addAll(values) } void dependsOn(Object... deps) { // TODO: add all files to inputs genTask.dependsOn(deps) } private void dependsOnFiles(FileCollection files) { dependsOn(files) genTask.inputs.files(files) } void link(FileCollection files) { linkFiles = linkFiles + files dependsOnFiles(files) } void linkOutputs(Task task) { linkOutputs(task.name) } void linkOutputs(String task) { linkTasks += task dependsOn(task) final Project prj; String taskName; int index = task.lastIndexOf(':') if (index != -1) { prj = project.project(task.substring(0, index)) taskName = task.substring(index + 1) } else { prj = project taskName = task } prj.tasks.matching { it.name == taskName }.all { // TODO: it is a hack this.dependsOnFiles(it.outputs.files) } } void includeDirs(String... values) { compilerOpts.addAll(values.collect {"-I$it"}) } File getNativeLibsDir() { return new File(project.buildDir, "nativelibs/$target") } File getGeneratedSrcDir() { return new File(project.buildDir, "nativeInteropStubs/$name/kotlin") } File getTemporaryFilesDir() { return new File(project.buildDir, "interopTemp") } NamedNativeInteropConfig(Project project, String name, String target = null, String flavor = 'jvm') { this.name = name this.project = project this.flavor = flavor def platformManager = project.rootProject.ext.platformManager def targetManager = platformManager.targetManager(target) this.target = targetManager.targetName this.headers = [] this.linkFiles = project.files() interopStubsName = name + "InteropStubs" genTask = project.task("gen" + interopStubsName.capitalize(), type: JavaExec) this.configure() } private void configure() { if (project.plugins.hasPlugin("kotlin")) { interopStubs = project.sourceSets.create(interopStubsName) configuration = project.configurations.create(interopStubs.name) project.tasks.getByName(interopStubs.getTaskName("compile", "Kotlin")) { dependsOn genTask kotlinOptions.freeCompilerArgs = ["-Xskip-prerelease-check"] } interopStubs.kotlin.srcDirs generatedSrcDir project.dependencies { add interopStubs.getCompileConfigurationName(), project(path: ':Interop:Runtime') } this.configuration.extendsFrom project.configurations[interopStubs.runtimeConfigurationName] project.dependencies.add(this.configuration.name, interopStubs.output) } genTask.configure { classpath = project.configurations.interopStubGenerator main = "org.jetbrains.kotlin.native.interop.gen.jvm.MainKt" jvmArgs '-ea' systemProperties "java.library.path" : project.files( new File(project.findProject(":Interop:Indexer").buildDir, "nativelibs"), new File(project.findProject(":Interop:Runtime").buildDir, "nativelibs") ).asPath // Set the konan.home property because we run the cinterop tool not from a distribution jar // so it will not be able to determine this path by itself. systemProperties "konan.home": project.rootProject.projectDir environment "LIBCLANG_DISABLE_CRASH_RECOVERY": "1" outputs.dir generatedSrcDir outputs.dir nativeLibsDir outputs.dir temporaryFilesDir // defer as much as possible doFirst { List linkerOpts = this.linkerOpts linkTasks.each { linkerOpts += project.tasks.getByPath(it).outputs.files.files } linkerOpts += linkFiles.files args '-generated', generatedSrcDir args '-natives', nativeLibsDir args '-Xtemporary-files-dir', temporaryFilesDir args '-flavor', this.flavor if (flavor == "jvm") { args '-mode', 'sourcecode' } // Uncomment to debug. // args '-verbose', 'true' if (defFile != null) { args '-def', project.file(defFile) } if (pkg != null) { args '-pkg', pkg } if (linker != null) { args '-linker', linker } if (target != null) { args '-target', target } // TODO: the interop plugin should probably be reworked to execute clang from build scripts directly environment['PATH'] = project.files(project.hostPlatform.clang.clangPaths).asPath + File.pathSeparator + environment['PATH'] args compilerOpts.collectMany { ['-compiler-option', it] } args linkerOpts.collectMany { ['-linker-option', it] } headers.each { args '-header', it } } } } } class NativeInteropExtension extends AbstractNamedDomainObjectContainer { private final Project project private String target = null private String flavor = 'jvm' protected NativeInteropExtension(Project project) { super(NamedNativeInteropConfig, project.gradle.services.get(Instantiator), project.gradle.services.get(CollectionCallbackActionDecorator)) this.project = project } @Override protected NamedNativeInteropConfig doCreate(String name) { def config = new NamedNativeInteropConfig(project, name, target, flavor) return config } public void target(String value) { this.target = value } public void flavor(String value) { this.flavor = value } } class NativeInteropPlugin implements Plugin { @Override void apply(Project prj) { prj.extensions.add("kotlinNativeInterop", new NativeInteropExtension(prj)) def runtimeNativeLibsDir = new File(prj.findProject(':Interop:Runtime').buildDir, 'nativelibs') def nativeLibsDir = new File(prj.buildDir, "nativelibs") prj.configurations { interopStubGenerator } prj.dependencies { interopStubGenerator project(path: ":Interop:StubGenerator") interopStubGenerator project(path: ":endorsedLibraries:kotlinx.cli", configuration: "jvmRuntimeElements") } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/BenchmarkRepeatingType.kt ================================================ package org.jetbrains.kotlin enum class BenchmarkRepeatingType { INTERNAL, // Let the benchmark perform warmups and repeats. EXTERNAL, // Repeat by relaunching benchmark } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/BuildRegister.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction import java.io.BufferedReader import java.io.FileInputStream import java.io.InputStreamReader import java.io.OutputStreamWriter import java.net.HttpURLConnection import java.net.URL import java.util.* /** * Task to save benchmarks results on server. * * @property bundleSize size of build * @property onlyBranch register only builds for branch * @property fileWithResult json file with benchmarks run results */ open class BuildRegister : DefaultTask() { var onlyBranch: String? = null var bundleSize: Int? = null var fileWithResult: String = "nativeReport.json" val performanceServer = "https://kotlin-native-perf-summary.labs.jb.gg" private fun sendPostRequest(url: String, body: String): String { val connection = URL(url).openConnection() as HttpURLConnection return connection.apply { setRequestProperty("Content-Type", "application/json; charset=utf-8") requestMethod = "POST" doOutput = true val outputWriter = OutputStreamWriter(outputStream) outputWriter.write(body) outputWriter.flush() }.let { if (it.responseCode == 200) it.inputStream else it.errorStream }.let { streamToRead -> BufferedReader(InputStreamReader(streamToRead)).use { val response = StringBuffer() var inputLine = it.readLine() while (inputLine != null) { response.append(inputLine) inputLine = it.readLine() } it.close() response.toString() } } } @TaskAction fun run() { // Get TeamCity properties. val teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") ?: error("Can't load teamcity config!") val buildProperties = Properties() buildProperties.load(FileInputStream(teamcityConfig)) val buildId = buildProperties.getProperty("teamcity.build.id") val teamCityUser = buildProperties.getProperty("teamcity.auth.userId") val teamCityPassword = buildProperties.getProperty("teamcity.auth.password") // Get branch. val currentBuild = getBuild("id:$buildId", teamCityUser, teamCityPassword) val branch = getBuildProperty(currentBuild, "branchName") // Send post request to register build. val requestBody = buildString { append("{\"buildId\":\"$buildId\",") append("\"teamCityUser\":\"$teamCityUser\",") append("\"teamCityPassword\":\"$teamCityPassword\",") append("\"fileWithResult\":\"$fileWithResult\",") append("\"bundleSize\": ${bundleSize?.let { "\"$bundleSize\"" } ?: bundleSize}}") } if (onlyBranch == null || onlyBranch == branch) { println(sendPostRequest("$performanceServer/register", requestBody)) } else { println("Skipping registration. Current branch $branch, need registration for $onlyBranch!") } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CacheTesting.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.Exec import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.util.visibleName class CacheTesting(val buildCacheTask: Task, val compilerArgs: List, val isDynamic: Boolean) fun configureCacheTesting(project: Project): CacheTesting? { val cacheKindString = project.findProperty("test_with_cache_kind") as String? ?: return null val isDynamic = when (cacheKindString) { "dynamic" -> true "static" -> false else -> error(cacheKindString) } val cacheKind = if (isDynamic) { CompilerOutputKind.DYNAMIC_CACHE } else { CompilerOutputKind.STATIC_CACHE } val target = project.testTarget val cacheDir = project.file("${project.buildDir}/cache") val cacheFile = "$cacheDir/stdlib-cache" val dist = project.kotlinNativeDist val stdlib = "$dist/klib/common/stdlib" val compilerArgs = listOf("-Xcached-library=$stdlib,$cacheFile") val buildCacheTask = project.tasks.create("buildStdlibCache", Exec::class.java) { it.doFirst { cacheDir.mkdirs() } if (!(project.property("useCustomDist") as Boolean)) { val tasks = listOf( "${target}CrossDist", "${target}CrossDistRuntime", "distCompiler" ).map { task -> project.rootProject.tasks.getByName(task) } it.dependsOn(tasks) } it.commandLine( "$dist/bin/konanc", "-p", cacheKind.visibleName, "-o", "$cacheDir/stdlib-cache", "-Xmake-cache=$stdlib", "-no-default-libs", "-nostdlib", "-target", target, "-g" ) } return CacheTesting(buildCacheTask, compilerArgs, isDynamic) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionDetector.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction import org.gradle.api.artifacts.Configuration import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles import java.io.File import java.util.zip.ZipFile /** * Task to find out collisions before producing fat jar. * * @property configurations added to fat jar configurations * @property resolvingRules a map containing rules to resolve conflicts. Key - conflicting file, value - a jar to copy the file from * @property resolvingRulesWithRegexes a map containing rules to resolve conflicts. Key - regular expression describing conflicting file, value - a jar to copy the file from * @property librariesWithIgnoredClassCollisions libraries which collision in class files are ignored */ open class CollisionDetector : DefaultTask() { @InputFiles var configurations = listOf() @Input val resolvingRules = mutableMapOf() @Input val resolvingRulesWithRegexes = mutableMapOf() @Input val librariesWithIgnoredClassCollisions = mutableListOf() val resolvedConflicts = mutableMapOf() // Key - filename, value - jar file containing it. private val filesInfo = mutableMapOf() @TaskAction fun run() { configurations.forEach { configuration -> configuration.files.filter { it.name.endsWith(".jar") }.forEach { processedFile -> ZipFile(processedFile).use { zip -> zip.entries().asSequence().filterNot { it.isDirectory || it.name.equals("META-INF/MANIFEST.MF", ignoreCase = true) || it.name.equals("META-INF/versions/9/module-info.class", ignoreCase = true) || it.name.startsWith("META-INF/services/", ignoreCase = true) }.forEach { val outputPath = it.name if (outputPath in filesInfo.keys) { val rule = resolvingRules.getOrElse(outputPath) { resolvingRulesWithRegexes.entries.firstOrNull { (key, _) -> key.matches(outputPath) }?.value } var ignoreJar = false if (rule != null && processedFile.name.startsWith(rule)) { resolvedConflicts[outputPath] = processedFile } else { // Skip class files from ignored libraries if version of libraries had collision are the same. val versionRegex = "\\d+\\.\\d+(\\.\\d+)?(-M\\d)?(-\\w+(-\\d+)?)?".toRegex() val currentVersion = versionRegex.find(processedFile.name)?.groupValues?.get(0) val collisionLibVersion = versionRegex.find(filesInfo.getValue(outputPath))?.groupValues?.get(0) if (outputPath.endsWith(".class") && currentVersion == collisionLibVersion) { if (processedFile.name == filesInfo[outputPath]) { ignoreJar = true } else { librariesWithIgnoredClassCollisions.forEach { if (processedFile.name.startsWith(it)) { ignoreJar = true } } } } } if (rule == null && !ignoreJar) { error("Collision is detected. File $outputPath is found in ${filesInfo[outputPath]} and ${processedFile.name}") } } else { filesInfo[outputPath] = processedFile.name } } } } } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CollisionTransformer.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext import org.gradle.api.file.FileTreeElement import shadow.org.apache.tools.zip.ZipOutputStream import java.io.File import shadow.org.apache.commons.io.IOUtils import shadow.org.apache.tools.zip.ZipEntry import shadow.org.apache.tools.zip.ZipFile class CollisionTransformer: Transformer { var resolvedConflicts = mutableMapOf() private val foundConflictsFiles = mutableSetOf() override fun canTransformResource(element: FileTreeElement): Boolean { val result = element.name in resolvedConflicts.keys if (result) { foundConflictsFiles.add(element.name) } return result } override fun transform(context: TransformerContext) {} override fun hasTransformedResource(): Boolean { return foundConflictsFiles.isNotEmpty() } override fun modifyOutputStream(jos: ZipOutputStream, preserveFileTimestamps: Boolean) { foundConflictsFiles.forEach { val entry = ZipEntry(it) entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) jos.putNextEntry(entry) val archive = ZipFile(resolvedConflicts[it]) archive.getInputStream(archive.getEntry(it)).use { IOUtils.copyLarge(it, jos) } jos.closeEntry() } foundConflictsFiles.clear() } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CompareDistributionSignatures.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.konan.target.HostManager import java.io.File import java.nio.file.Files import java.nio.file.LinkOption import java.nio.file.Path import java.nio.file.Paths /** * Compares SignatureIds of the current distribution and the given older one. * Can be used to validate that there are no unexpected breaking ABI changes. */ open class CompareDistributionSignatures : DefaultTask() { @Input lateinit var oldDistribution: String private val newDistribution: String = project.kotlinNativeDist.absolutePath enum class OnMismatchMode { FAIL, NOTIFY } private val messageBuilder = StringBuilder() @Input var onMismatchMode: OnMismatchMode = OnMismatchMode.NOTIFY sealed class Libraries { object Standard : Libraries() class Platform(val target: String) : Libraries() } @Input lateinit var libraries: Libraries private fun computeDiff(): KlibDiff = when (val libraries = libraries) { Libraries.Standard -> KlibDiff( emptyList(), emptyList(), listOf(RemainingLibrary(newDistribution.stdlib(), oldDistribution.stdlib())) ) is Libraries.Platform -> { val oldPlatformLibs = oldDistribution.platformLibs(libraries.target) val oldPlatformLibsNames = oldPlatformLibs.list().toSet() val newPlatformLibs = newDistribution.platformLibs(libraries.target) val newPlatformLibsNames = newPlatformLibs.list().toSet() KlibDiff( (newPlatformLibsNames - oldPlatformLibsNames).map(newPlatformLibs::resolve), (oldPlatformLibsNames - newPlatformLibsNames).map(oldPlatformLibs::resolve), oldPlatformLibsNames.intersect(newPlatformLibsNames).map { RemainingLibrary(newPlatformLibs.resolve(it), oldPlatformLibs.resolve(it)) } ) } } @TaskAction fun run() { check(looksLikeKotlinNativeDistribution(Paths.get(oldDistribution))) { """ `$oldDistribution` doesn't look like Kotlin/Native distribution. Make sure to provide an absolute path to it. """.trimIndent() } val platformLibsDiff = computeDiff() if (platformLibsDiff.missingLibs.isNotEmpty()) { messageBuilder.apply { appendln("Following platform libraries are missing in the new distro:") platformLibsDiff.missingLibs.forEach { appendln(it) } } } if (platformLibsDiff.newLibs.isNotEmpty()) { messageBuilder.apply { appendln("Following platform libraries were added:") platformLibsDiff.newLibs.forEach { appendln(it) } } } for ((new, old) in platformLibsDiff.remainingLibs) { val result = compareSignatures(new, old) if (result.run { newKlibOnly.isNotEmpty() || oldKlibOnly.isNotEmpty() }) { reportMismatch(result, new.name) } } if (messageBuilder.isNotEmpty()) { report(messageBuilder.toString()) } } private fun reportMismatch(compareDiff: CompareDiff, klibName: String) { messageBuilder.apply { appendln("Mismatch for $klibName:") if (compareDiff.oldKlibOnly.isNotEmpty()) { appendln("Following signatures are missing in the new version:") compareDiff.oldKlibOnly.forEach { appendln(it) } } if (compareDiff.newKlibOnly.isNotEmpty()) { appendln("Following signatures were added:") compareDiff.newKlibOnly.forEach { appendln(it) } } } } private fun report(message: String) { when (onMismatchMode) { OnMismatchMode.FAIL -> error(message) OnMismatchMode.NOTIFY -> println(message) } } private data class RemainingLibrary(val new: File, val old: File) private class KlibDiff( val newLibs: Collection, val missingLibs: Collection, val remainingLibs: Collection ) private fun String.stdlib(): File = File("$this/klib/common/stdlib").also { check(it.exists()) { """ `${it.absolutePath}` doesn't exists. If $oldDistribution has a different directory layout then it is time to update this comparator. """.trimIndent() } } private fun String.platformLibs(target: String): File = File("$this/klib/platform/$target").also { check(it.exists()) { """ `${it.absolutePath}` doesn't exists. Make sure that given distribution actually supports $target. """.trimIndent() } } private fun getKlibSignatures(klib: File): List { val tool = if (HostManager.hostIsMingw) "klib.bat" else "klib" val klibTool = File("$newDistribution/bin/$tool").absolutePath val args = listOf("signatures", klib.absolutePath) return runProcess(localExecutor(project), klibTool, args).stdOut.lines() } private class CompareDiff(val newKlibOnly: Set, val oldKlibOnly: Set) private fun compareSignatures(new: File, old: File): CompareDiff { val newKlibSignatures = getKlibSignatures(new).toSet() val oldKlibSignatures = getKlibSignatures(old).toSet() return CompareDiff( newKlibSignatures - oldKlibSignatures, oldKlibSignatures - newKlibSignatures, ) } private fun looksLikeKotlinNativeDistribution(directory: Path): Boolean { val distributionComponents = directory.run { val konanDir = resolve("konan") setOf(resolve("bin"), resolve("klib"), konanDir, konanDir.resolve("konan.properties")) } return distributionComponents.all { Files.exists(it, LinkOption.NOFOLLOW_LINKS) } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CompilationDatabase.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import java.io.File import javax.inject.Inject import org.gradle.api.GradleException import com.google.gson.annotations.Expose import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.bitcode.CompileToBitcode import java.io.FileReader import java.io.FileWriter internal data class Entry( @Expose val directory: String, @Expose val file: String, @Expose val arguments: List, @Expose val output: String ) { companion object { fun create( directory: File, file: File, args: List, outputDir: File ): Entry { return Entry( directory.absolutePath, file.absolutePath, args + listOf(file.absolutePath), File(outputDir, file.name + ".o").absolutePath ) } fun writeListTo(file: File, entries: List) = FileWriter(file).use { gson.toJson(entries, it) } fun readListFrom(file: File): Array = FileReader(file).use { gson.fromJson(it, Array::class.java) } } } open class GenerateCompilationDatabase @Inject constructor(@Input val target: String, @Input val srcRoot: File, @Input val files: Iterable, @Input val executable: String, @Input val compilerFlags: List, @Input val outputDir: File ) : DefaultTask() { @OutputFile var outputFile = File(outputDir, "compile_commands.json") @TaskAction fun run() { val plugin = project.convention.getPlugin(ExecClang::class.java) val executable = plugin.resolveExecutable(executable) val args = listOf(executable) + compilerFlags + plugin.konanArgs(target) val entries: List = files.map { Entry.create(srcRoot, it, args, outputDir) } Entry.writeListTo(outputFile, entries) } } open class MergeCompilationDatabases @Inject constructor() : DefaultTask() { @InputFiles val inputFiles = mutableListOf() @OutputFile var outputFile = File(project.buildDir, "compile_commands.json") @TaskAction fun run() { val entries = mutableListOf() for (file in inputFiles) { entries.addAll(Entry.readListFrom(file)) } Entry.writeListTo(outputFile, entries) } } fun mergeCompilationDatabases(project: Project, name: String, paths: List): Task { val subtasks: List = paths.map { val task = project.tasks.getByPath(it) if (task !is MergeCompilationDatabases) { throw GradleException("Unknown task type for compdb merging: $task") } task } return project.tasks.create(name, MergeCompilationDatabases::class.java) { task -> task.dependsOn(subtasks) task.inputFiles.addAll(subtasks.map { it.outputFile }) } } /** * Get all [CompileToBitcode] tasks in the project, group them by target, and generate * compilation database for each target. Tasks will be named [name]. Databases * will be placed in a build dir in /compile_commands.json */ fun createCompilationDatabasesFromCompileToBitcodeTasks(project: Project, name: String) { val compileTasks = project.tasks.withType(CompileToBitcode::class.java).toList() val compdbTasks = compileTasks.groupBy({ task -> task.target }) { task -> project.tasks.create("${task.name}_CompilationDatabase", GenerateCompilationDatabase::class.java, task.target, task.srcRoot, task.inputFiles, task.executable, task.compilerFlags, task.objDir) } for ((target, tasks) in compdbTasks) { project.tasks.create("${target}${name}", MergeCompilationDatabases::class.java) { task -> task.dependsOn(tasks) task.inputFiles.addAll(tasks.map { it.outputFile }) task.outputFile = File(File(project.buildDir, target), "compile_commands.json") } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CopyCommonSources.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import java.io.File open class CopyCommonSources : DefaultTask() { @Input var zipSources: Boolean = false @InputFiles var sourcePaths: ConfigurableFileCollection = project.files() @OutputDirectory var outputDir: File = project.buildDir.resolve("sources") fun zipSources(needToZip: Boolean) { zipSources = needToZip } fun outputDir(path: Any) { outputDir = project.file(path) } fun sourcePaths(paths: Any) { sourcePaths = project.files(paths) } @TaskAction fun copySources() { if (zipSources) copyAndZip() else copyPlain() } private fun copyPlain() { for (sourcePath in sourcePaths) { sourcePath.copyFilteredTo(outputDir) } } private fun copyAndZip() { for (sourcePath in sourcePaths) { val filePrefix = sourcePath.name.replace(Regex("-\\d+.*"), "") val targetFileName = "$filePrefix-sources.zip" val tempDir = project.buildDir.resolve(name).resolve(filePrefix).also { it.deleteRecursively() it.mkdirs() } sourcePath.copyFilteredTo(tempDir) project.ant.invokeMethod( "zip", mapOf( "destfile" to outputDir.resolve(targetFileName).absolutePath, "basedir" to tempDir.absolutePath ) ) } } private fun File.copyFilteredTo(destinationDir: File) { val fileTree = if (isFile) project.zipTree(this) else project.fileTree(this) project.copy { it.from(fileTree) it.includeEmptyDirs = false it.include("generated/**/*.kt") it.include("kotlin/**/*.kt") it.include("kotlin.test/*.kt") it.into(destinationDir) } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CopySamples.kt ================================================ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Task import org.gradle.api.tasks.Copy import org.gradle.api.tasks.InputDirectory import java.io.File /** * A task that copies samples and replaces direct repository URLs with ones provided by the cache-redirector service. * This task also adds kotlin compiler repository from the project's gradle.properties file. */ open class CopySamples : Copy() { @InputDirectory var samplesDir: File = project.file("samples") private fun configureReplacements() { from(samplesDir) { it.exclude("**/*.gradle.kts") it.exclude("**/*.gradle") it.exclude("**/gradle.properties") } from(samplesDir) { it.include("**/*.gradle") it.include("**/*.gradle.kts") it.filter { line -> replacements.forEach { (repo, replacement) -> if (line.contains(repo)) { return@filter line.replace(repo, replacement) } } return@filter line } } from(samplesDir) { it.include("**/gradle.properties") val kotlinVersion = project.property("kotlinVersion") as? String ?: throw IllegalArgumentException("Property kotlinVersion should be specified in the root project") val kotlinCompilerRepo = project.property("kotlinCompilerRepo") as? String ?: throw IllegalArgumentException("Property kotlinCompilerRepo should be specified in the root project") it.filter { line -> when { line.startsWith("kotlin_version") -> "kotlin_version=$kotlinVersion" line.startsWith("#kotlinCompilerRepo") || line.startsWith("kotlinCompilerRepo") -> "kotlinCompilerRepo=$kotlinCompilerRepo" else -> line } } } } override fun configure(closure: Closure): Task { super.configure(closure) configureReplacements() return this } private val replacements = listOf( "https://dl.bintray.com/kotlin/kotlin-dev" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev", "https://dl.bintray.com/kotlin/kotlin-eap" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap", "https://dl.bintray.com/kotlin/ktor" to "https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/ktor", "https://plugins.gradle.org/m2" to "https://cache-redirector.jetbrains.com/plugins.gradle.org/m2", "mavenCentral()" to "maven { setUrl(\"https://cache-redirector.jetbrains.com/maven-central\") }", "jcenter()" to "maven { setUrl(\"https://cache-redirector.jetbrains.com/jcenter\") }", ) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/CoverageTest.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.konan.target.AppleConfigurables /** * Test task for -Xcoverage and -Xlibraries-to-cover flags. Requires a binary to be built by the Konan plugin * with * konanArtifacts { * program([binaryName], targets: [testTarget]) { * ... * extraOpts "-Xcoverage"/"-Xlibrary-to-cover=...", "-Xcoverage-file=$[profrawFile]" * } * } * and a dependency set according to a pattern "run${binaryName}". * * @property numberOfCoveredFunctions Expected number of covered functions * @property numberOfCoveredLines Expected number of covered lines in all functions * @property binaryName Name of the produced binary */ open class CoverageTest : DefaultTask() { private val target = project.testTarget private val platform = project.platformManager.platform(target) private val configurables = platform.configurables // Use the same LLVM version as compiler when producing machine code: private val llvmToolsDir = if (configurables is AppleConfigurables) { "${configurables.absoluteTargetToolchain}/usr/bin" } else { "${configurables.absoluteLlvmHome}/bin" } @Input lateinit var binaryName: String // TODO: Consider better metric. @Input var numberOfCoveredFunctions: Int? = null @Input var numberOfCoveredLines: Int? = null val profrawFile: String by lazy { "${project.buildDir.absolutePath}/$binaryName.profraw" } private val profdataFile: String by lazy { "${project.buildDir.absolutePath}/$binaryName.profdata" } private val outputDir: String by lazy { project.file(project.property("testOutputCoverage")!!).absolutePath } override fun configure(closure: Closure): Task { super.configure(closure) dependsOnDist() dependsOn(project.tasks.getByName("compileKonan$binaryName")) return this } @TaskAction fun run() { val suffix = target.family.exeSuffix val pathToBinary = "$outputDir/$binaryName/$target/$binaryName.$suffix" runProcess({ project.executor.execute(it) }, pathToBinary) .ensureSuccessful(pathToBinary) exec("llvm-profdata", "merge", profrawFile, "-o", profdataFile) val llvmCovResult = exec("llvm-cov", "export", pathToBinary, "-instr-profile", profdataFile) val jsonReport = llvmCovResult.stdOut val llvmCovReport = parseLlvmCovReport(jsonReport) try { CoverageValidator(numberOfCoveredFunctions, numberOfCoveredLines).validateReport(llvmCovReport) } catch (e: TestFailedException) { // Show report in message to make debug easier. val show = exec("llvm-cov", "show", pathToBinary, "-instr-profile", profdataFile).stdOut // llvm-cov output contains '|' so another symbol is used as margin prefix. throw TestFailedException(""" >${e.message} >$show """.trimMargin(">")) } } private fun exec(llvmTool: String, vararg args: String): ProcessOutput { val executable = "$llvmToolsDir/$llvmTool" val result = runProcess(localExecutor(project), executable, args.toList()) result.ensureSuccessful(llvmTool) return result } private fun ProcessOutput.ensureSuccessful(executable: String) { if (exitCode != 0) { println(""" $executable failed. exitCode: $exitCode stdout: $stdOut stderr: $stdErr """.trimIndent()) error("$executable failed") } } } private class CoverageValidator( val numberOfCoveredFunctions: Int?, val numberOfCoveredLines: Int? ) { fun validateReport(report: LlvmCovReport) { val data = report.data if (data.isEmpty()) { failTest("Report data should not be empty!") } compareNumbers(numberOfCoveredFunctions, data[0].totals.functions.covered, "Number of covered functions") compareNumbers(numberOfCoveredLines, data[0].totals.lines.covered, "Number of covered lines") } private fun compareNumbers(expected: Int?, actual: Int, description: String) { if (expected != null && actual != expected) { failTest("$description differs from expected! Expected: $expected. Got: $actual") } } private fun failTest(message: String) { throw TestFailedException(message) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/EndorsedLibraryInfo.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.Project data class EndorsedLibraryInfo(val project: Project, val name: String) { val projectName: String get() = project.name val taskName: String by lazy { projectName.split('.').joinToString(separator = "") { it.capitalize() } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecClang.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin import org.gradle.api.Action import groovy.lang.Closure import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.process.ExecResult import org.gradle.process.ExecSpec import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.file.* class ExecClang(private val project: Project) { private val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager private fun konanArgs(target: KonanTarget): List { return platformManager.platform(target).clang.clangArgsForKonanSources.asList() } fun konanArgs(targetName: String?): List { val target = platformManager.targetManager(targetName).target return konanArgs(target) } fun resolveExecutable(executableOrNull: String?): String { val executable = executableOrNull ?: "clang" if (listOf("clang", "clang++").contains(executable)) { val llvmDir = project.findProperty("llvmDir") return "${llvmDir}/bin/$executable" } else { throw GradleException("unsupported clang executable: $executable") } } fun resolveToolchainExecutable(target: KonanTarget, executableOrNull: String?): String { val executable = executableOrNull ?: "clang" if (listOf("clang", "clang++").contains(executable)) { // TODO: This is copied from `BitcodeCompiler`. Consider sharing the code instead. val platform = platformManager.platform(target) return if (target.family.isAppleFamily) { "${platform.absoluteTargetToolchain}/usr/bin/$executable" } else { "${platform.absoluteTargetToolchain}/bin/$executable" } } else { throw GradleException("unsupported clang executable: $executable") } } // The bare ones invoke clang with system default sysroot. fun execBareClang(action: Action): ExecResult { return this.execClang(emptyList(), action) } fun execBareClang(closure: Closure): ExecResult { return this.execClang(emptyList(), closure) } // The konan ones invoke clang with konan provided sysroots. // So they require a target or assume it to be the host. // The target can be specified as KonanTarget or as a // (nullable, which means host) target name. fun execKonanClang(target: String?, action: Action): ExecResult { return this.execClang(konanArgs(target), action) } fun execKonanClang(target: KonanTarget, action: Action): ExecResult { return this.execClang(konanArgs(target), action) } fun execKonanClang(target: String?, closure: Closure): ExecResult { return this.execClang(konanArgs(target), closure) } fun execKonanClang(target: KonanTarget, closure: Closure): ExecResult { return this.execClang(konanArgs(target), closure) } // The toolchain ones execute clang from the toolchain. fun execToolchainClang(target: String?, action: Action): ExecResult { return this.execToolchainClang(platformManager.targetManager(target).target, action) } fun execToolchainClang(target: String?, closure: Closure): ExecResult { return this.execToolchainClang(platformManager.targetManager(target).target, ConfigureUtil.configureUsing(closure)) } fun execToolchainClang(target: KonanTarget, action: Action): ExecResult { val extendedAction = Action { execSpec -> action.execute(execSpec) execSpec.apply { executable = resolveToolchainExecutable(target, executable) } } return project.exec(extendedAction) } fun execToolchainClang(target: KonanTarget, closure: Closure): ExecResult { return this.execToolchainClang(target, ConfigureUtil.configureUsing(closure)) } // These ones are private, so one has to choose either Bare or Konan. private fun execClang(defaultArgs: List, closure: Closure): ExecResult { return this.execClang(defaultArgs, ConfigureUtil.configureUsing(closure)) } private fun execClang(defaultArgs: List, action: Action): ExecResult { val extendedAction = Action { execSpec -> action.execute(execSpec) execSpec.apply { executable = resolveExecutable(executable) val hostPlatform = project.findProperty("hostPlatform") as Platform environment["PATH"] = project.files(hostPlatform.clang.clangPaths).asPath + java.io.File.pathSeparator + environment["PATH"] args = args + defaultArgs } } return project.exec(extendedAction) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecLlvm.kt ================================================ ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/ExecutorService.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin import com.google.gson.annotations.Expose import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.Project import org.gradle.process.ExecResult import org.gradle.process.ExecSpec import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.konan.target.Architecture import org.jetbrains.kotlin.konan.target.ConfigurablesWithEmulator import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.Xcode import java.io.* import java.nio.file.Path import java.nio.file.Paths import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.concurrent.TimeUnit /** * A replacement of the standard `exec {}` * @see org.gradle.api.Project.exec */ interface ExecutorService { fun execute(closure: Closure): ExecResult? = execute(ConfigureUtil.configureUsing(closure)) fun execute(action: Action): ExecResult? } /** * Creates an ExecutorService depending on a test target -Ptest_target */ fun create(project: Project): ExecutorService { val platformManager = project.platformManager val testTarget = project.testTarget val platform = platformManager.platform(testTarget) val absoluteTargetToolchain = platform.absoluteTargetToolchain return if (project.hasProperty("remote")) { sshExecutor(project) } else when (testTarget) { KonanTarget.WASM32 -> object : ExecutorService { override fun execute(action: Action): ExecResult? = project.exec { execSpec -> action.execute(execSpec) with(execSpec) { val exe = executable val d8 = "$absoluteTargetToolchain/bin/d8" val launcherJs = "$executable.js" executable = d8 args = listOf("--expose-wasm", launcherJs, "--", exe) + args } } } KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32, KonanTarget.LINUX_ARM32_HFP, KonanTarget.LINUX_ARM64 -> emulatorExecutor(project, testTarget) KonanTarget.IOS_X64, KonanTarget.TVOS_X64, KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64 -> simulator(project) KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64 -> deviceLauncher(project) else -> localExecutorService(project) } } data class ProcessOutput(var stdOut: String, var stdErr: String, var exitCode: Int) /** * Runs process using a given executor. * * @param executor a method that is able to run a given executable, e.g. ExecutorService::execute * @param executable a process executable to be run * @param args arguments for a process */ fun runProcess(executor: (Action) -> ExecResult?, executable: String, args: List): ProcessOutput { val outStream = ByteArrayOutputStream() val errStream = ByteArrayOutputStream() val execResult = executor(Action { it.executable = executable it.args = args.toList() it.standardOutput = outStream it.errorOutput = errStream it.isIgnoreExitValue = true }) checkNotNull(execResult) val stdOut = outStream.toString("UTF-8") val stdErr = errStream.toString("UTF-8") return ProcessOutput(stdOut, stdErr, execResult.exitValue) } fun runProcess(executor: (Action) -> ExecResult?, executable: String, vararg args: String) = runProcess(executor, executable, args.toList()) /** * Runs process using a given executor. * * @param executor a method that is able to run a given executable, e.g. ExecutorService::execute * @param executable a process executable to be run * @param args arguments for a process * @param input an input string to be passed through the standard input stream */ fun runProcessWithInput(executor: (Action) -> ExecResult?, executable: String, args: List, input: String): ProcessOutput { val outStream = ByteArrayOutputStream() val errStream = ByteArrayOutputStream() val inStream = ByteArrayInputStream(input.toByteArray()) val execResult = executor(Action { it.executable = executable it.args = args.toList() it.standardOutput = outStream it.errorOutput = errStream it.isIgnoreExitValue = true it.standardInput = inStream }) checkNotNull(execResult) val stdOut = outStream.toString("UTF-8") val stdErr = errStream.toString("UTF-8") return ProcessOutput(stdOut, stdErr, execResult.exitValue) } /** * The [ExecutorService] being set in the given project. * @throws IllegalStateException if there are no executor in the project. */ val Project.executor: ExecutorService get() = this.convention.plugins["executor"] as? ExecutorService ?: throw IllegalStateException("Executor wasn't found") /** * Creates a new executor service with additional action [actionParameter] executed after the main one. * The following is an example how to pass an environment parameter * @code `executor.add(Action { it.environment = mapOf("JAVA_OPTS" to "-verbose:gc") })::execute` */ fun ExecutorService.add(actionParameter: Action) = object : ExecutorService { override fun execute(action: Action): ExecResult? = this@add.execute { action.execute(it) actionParameter.execute(it) } } /** * Executes the [executable] with the given [arguments] * and checks that the program finished with zero exit code. */ fun Project.executeAndCheck(executable: Path, arguments: List = emptyList()) { val (stdOut, stdErr, exitCode) = runProcess( executor = executor::execute, executable = executable.toString(), args = arguments ) println(""" |stdout: $stdOut |stderr: $stdErr """.trimMargin()) check(exitCode == 0) { "Execution failed with exit code: $exitCode" } } /** * Returns [project]'s process executor. * @see Project.exec */ fun localExecutor(project: Project) = { a: Action -> project.exec(a) } fun localExecutorService(project: Project): ExecutorService = object : ExecutorService { override fun execute(action: Action): ExecResult? = project.exec(action) } private fun emulatorExecutor(project: Project, target: KonanTarget) = object : ExecutorService { val platformManager = project.platformManager val configurables = platformManager.platform(target).configurables as? ConfigurablesWithEmulator ?: error("$target does not support emulation!") val absoluteTargetSysRoot = configurables.absoluteTargetSysRoot override fun execute(action: Action): ExecResult? = project.exec { execSpec -> action.execute(execSpec) with(execSpec) { val exe = executable // TODO: Move these to konan.properties when when it will be possible // to represent absolute path there. val qemuSpecificArguments = listOf("-L", absoluteTargetSysRoot) val targetSpecificArguments = when (target) { KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 -> { // This is to workaround an endianess issue. // See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=731082 for details. listOf("$absoluteTargetSysRoot/lib/ld.so.1", "--inhibit-cache") } else -> emptyList() } executable = configurables.absoluteEmulatorExecutable args = qemuSpecificArguments + targetSpecificArguments + exe + args } } } /** * Executes a given action with iPhone Simulator. * * The test target should be specified with -Ptest_target=ios_x64 * @see KonanTarget.IOS_X64 * @param iosDevice an optional project property used to control simulator's device type * Specify -PiosDevice=iPhone X to set it */ @Suppress("KDocUnresolvedReference") private fun simulator(project: Project): ExecutorService = object : ExecutorService { private val target = project.testTarget private val simctl by lazy { val sdk = when (target) { KonanTarget.TVOS_X64 -> Xcode.current.appletvsimulatorSdk KonanTarget.IOS_X64 -> Xcode.current.iphonesimulatorSdk KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_X86 -> Xcode.current.watchsimulatorSdk else -> error("Unexpected simulation target: $target") } val out = ByteArrayOutputStream() val result = project.exec { it.commandLine("/usr/bin/xcrun", "--find", "simctl", "--sdk", sdk) it.standardOutput = out } result.assertNormalExitValue() out.toString("UTF-8").trim() } private val device = project.findProperty("iosDevice")?.toString() ?: when (target) { KonanTarget.TVOS_X64 -> "Apple TV 4K" KonanTarget.IOS_X64 -> "iPhone 8" KonanTarget.WATCHOS_X64 -> "Apple Watch Series 6 - 40mm" KonanTarget.WATCHOS_X86 -> "Apple Watch Series 4 - 40mm" else -> error("Unexpected simulation target: $target") } private val archSpecification = when (target.architecture) { Architecture.X86 -> listOf("-a", "i386") Architecture.X64 -> listOf() // x86-64 is used by default. else -> error("${target.architecture} can't be used in simulator.") }.toTypedArray() override fun execute(action: Action): ExecResult? = project.exec { execSpec -> action.execute(execSpec) // Starting Xcode 11 `simctl spawn` requires explicit `--standalone` flag. with(execSpec) { commandLine = listOf(simctl, "spawn", "--standalone", *archSpecification, device, executable) + args } } } /** * Remote process executor. * * @param remote makes binaries be executed on a remote host * Specify it as -Premote=user@host */ @Suppress("KDocUnresolvedReference") private fun sshExecutor(project: Project): ExecutorService = object : ExecutorService { private val remote: String = project.property("remote").toString() private val sshArgs: List = System.getenv("SSH_ARGS")?.split(" ") ?: emptyList() private val sshHome = System.getenv("SSH_HOME") ?: "/usr/bin" // Unique remote dir name to be used in the target host private val remoteDir = run { val date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) Paths.get(project.findProperty("remoteRoot").toString(), "tmp", System.getProperty("user.name") + "_" + date).toString() } override fun execute(action: Action): ExecResult { var execFile: String? = null createRemoteDir() val execResult = project.exec { execSpec -> action.execute(execSpec) with(execSpec) { upload(executable) executable = "$remoteDir/${File(executable).name}" execFile = executable commandLine = arrayListOf("$sshHome/ssh") + sshArgs + remote + commandLine } } cleanup(execFile!!) return execResult } private fun createRemoteDir() { project.exec { it.commandLine = arrayListOf("$sshHome/ssh") + sshArgs + remote + "mkdir" + "-p" + remoteDir } } private fun upload(fileName: String) { project.exec { it.commandLine = arrayListOf("$sshHome/scp") + sshArgs + fileName + "$remote:$remoteDir" } } private fun cleanup(fileName: String) { project.exec { it.commandLine = arrayListOf("$sshHome/ssh") + sshArgs + remote + "rm" + fileName } } } internal data class DeviceTarget( @Expose val name: String, @Expose val udid: String, @Expose val state: String, @Expose val type: String ) private fun deviceLauncher(project: Project) = object : ExecutorService { private val xcProject = Paths.get(project.testOutputRoot, "launcher") private val idb = project.findProperty("idb_path") as? String ?: "idb" private val deviceName = project.findProperty("device_name") as? String private val bundleID = "org.jetbrains.kotlin.KonanTestLauncher" override fun execute(action: Action): ExecResult? { val result: ExecResult? try { val udid = targetUDID() println("Found device UDID: $udid") install(udid, xcProject.resolve("build/KonanTestLauncher.ipa").toString()) val commands = startDebugServer(udid) .split("\n") .filter { it.isNotBlank() } .flatMap { listOf("-o", it) } var savedOut: OutputStream? = null val out = ByteArrayOutputStream() result = project.exec { execSpec: ExecSpec -> action.execute(execSpec) execSpec.executable = "lldb" execSpec.args = commands + "-b" + "-o" + "command script import ${pythonScript()}" + "-o" + ("process launch" + (execSpec.args.takeUnless { it.isEmpty() } ?.let { " -- ${it.joinToString(" ")}" } ?: "")) + "-o" + "get_exit_code" + "-k" + "get_exit_code" + "-k" + "exit -1" // A test task that uses project.exec { } sets the stdOut to parse the result, // but the test executable is being run under debugger that has its own output mixed with the // output from the test. Save the stdOut from the test to write the parsed output to it. savedOut = execSpec.standardOutput execSpec.standardOutput = out } out.toString() .also { if (project.verboseTest) println(it) } .split("\n") .dropWhile { s -> !s.startsWith("(lldb) process launch") } .drop(1) // drop 'process launch' also .dropLastWhile { !it.matches(".*Process [0-9]* exited with status .*".toRegex()) } .joinToString("\n") { it.replace("Process [0-9]* exited with status .*".toRegex(), "") .replace("\r", "") // TODO: investigate: where does the \r comes from } .also { savedOut?.write(it.toByteArray()) } uninstall(udid) } catch (exc: Exception) { throw RuntimeException("iOS-device execution failed", exc) } finally { kill() } return result } /* * This script kills the target process in case it has been stopped, * and exists lldb with the same exit code as a target process. */ private fun pythonScript(): String = xcProject.resolve("lldb_cmd.py").toFile().run { writeText( // language=Python """ import lldb def exit_code(debugger, command, exe_ctx, result, internal_dict): process = exe_ctx.GetProcess() state = process.GetState() if state == lldb.eStateStopped: # Call flush method, otherwise some output isn't shown in the debugger debugger.HandleCommand("expression -- (int) fflush(NULL)") debugger.HandleCommand("bt all") process.Kill() code = process.GetExitStatus() debugger.HandleCommand("exit %d" % code) def __lldb_init_module(debugger, _): debugger.HandleCommand('command script add -f lldb_cmd.exit_code get_exit_code') """.trimIndent()) absolutePath } private fun kill() = project.exec { it.commandLine(idb, "kill") } private inline fun tryUntilTrue(times: Int = 3, f: () -> Boolean) { for (i in 1..times) { if (f()) break else TimeUnit.SECONDS.sleep(i.toLong()) } } private fun targetUDID(): String { val out = ByteArrayOutputStream() // idb launches idb_companion but doesn't wait for it and just exits. // So relaunch `list-targets` again. tryUntilTrue { project.exec { it.commandLine(idb, "list-targets", "--json") it.standardOutput = out }.assertNormalExitValue() out.toString().trim().isNotEmpty() } return out.toString().run { check(isNotEmpty()) split("\n") .filter { it.isNotEmpty() } .map { gson.fromJson(it, DeviceTarget::class.java) } .first { it.type == "device" && deviceName?.run { this == it.name } ?: true } .udid } } private fun install(udid: String, bundlePath: String) { val out = ByteArrayOutputStream() lateinit var result: ExecResult tryUntilTrue { result = project.exec { it.workingDir = xcProject.toFile() it.commandLine = listOf(idb, "install", "--udid", udid, bundlePath) it.standardOutput = out it.errorOutput = out it.isIgnoreExitValue = true } println(out.toString()) result.exitValue == 0 } check(result.exitValue == 0) { "Installation of $bundlePath failed: $out" } } private fun uninstall(udid: String) { val out = ByteArrayOutputStream() project.exec { it.workingDir = xcProject.toFile() it.commandLine = listOf(idb, "uninstall", "--udid", udid, bundleID) it.standardOutput = out it.errorOutput = out it.isIgnoreExitValue = true } println(out.toString()) } private fun startDebugServer(udid: String): String { val out = ByteArrayOutputStream() val result = project.exec { it.workingDir = xcProject.toFile() it.commandLine = listOf(idb, "debugserver", "start", "--udid", udid, bundleID) it.standardOutput = out it.errorOutput = out it.isIgnoreExitValue = true } check(result.exitValue == 0) { "Failed to start debug server: $out" } return out.toString() } } fun KonanTestExecutable.configureXcodeBuild() { this.doBeforeRun = Action { val signIdentity = project.findProperty("sign_identity") as? String ?: "iPhone Developer" val developmentTeam = project.findProperty("development_team") as? String requireNotNull(developmentTeam) { "Specify '-Pdevelopment_team=' with the your team id" } val xcProject = Paths.get(project.testOutputRoot, "launcher") val shellScript: String = // language=Bash mutableListOf(""" set -x # Copy executable to the build dir. COPY_TO="${"$"}TARGET_BUILD_DIR/${"$"}EXECUTABLE_PATH" cp "${project.file(executable).absolutePath}" "${"$"}COPY_TO" # copy dSYM if it exists DSYM_DIR="${project.file("$executable.dSYM").absolutePath}" if [ -d "${"$"}DSYM_DIR" ]; then cp -r "${"$"}DSYM_DIR" "${"$"}TARGET_BUILD_DIR/${"$"}EXECUTABLE_FOLDER_PATH/" fi """.trimIndent()).also { if (this is FrameworkTest) { // Create a Frameworks folder inside the build dir. it += "mkdir -p \"\$TARGET_BUILD_DIR/\$FRAMEWORKS_FOLDER_PATH\"" // Copy each framework to the Frameworks dir. it += frameworks.filter { framework -> !framework.isStatic } .map { framework -> val artifact = framework.artifact "cp -r \"$testOutput/${this.name}/${project.testTarget.name}/$artifact.framework\" " + "\"\$TARGET_BUILD_DIR/\$FRAMEWORKS_FOLDER_PATH/$artifact.framework\"" } } }.joinToString(separator = "\\n") { it.replace("\"", "\\\"") } // Copy template xcode project. project.file("iosLauncher").copyRecursively(xcProject.toFile(), overwrite = true) xcProject.resolve("KonanTestLauncher.xcodeproj/project.pbxproj") .toFile() .apply { val text = readLines().joinToString("\n") { when { it.contains("CODE_SIGN_IDENTITY") -> it.replaceAfter("= ", "\"$signIdentity\";") it.contains("DEVELOPMENT_TEAM") || it.contains("DevelopmentTeam") -> it.replaceAfter("= ", "$developmentTeam;") it.contains("shellScript = ") -> it.replaceAfter("= ", "\"$shellScript\";") else -> it } } writeText(text) } val sdk = when (project.testTarget) { KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64 -> Xcode.current.iphoneosSdk else -> error("Unsupported target: ${project.testTarget}") } fun xcodebuild(vararg elements: String) { val xcode = listOf("/usr/bin/xcrun", "-sdk", sdk, "xcodebuild") val out = ByteArrayOutputStream() val result = project.exec { it.workingDir = xcProject.toFile() it.commandLine = xcode + elements.toList() it.standardOutput = out } println(out.toString("UTF-8")) result.assertNormalExitValue() } xcodebuild("-workspace", "KonanTestLauncher.xcodeproj/project.xcworkspace", "-scheme", "KonanTestLauncher", "-allowProvisioningUpdates", "-destination", "generic/platform=iOS", "build") val archive = xcProject.resolve("build/KonanTestLauncher.xcarchive").toString() xcodebuild("-workspace", "KonanTestLauncher.xcodeproj/project.xcworkspace", "-scheme", "KonanTestLauncher", "archive", "-archivePath", archive) xcodebuild("-exportArchive", "-archivePath", archive, "-exportOptionsPlist", "KonanTestLauncher/Info.plist", "-exportPath", xcProject.resolve("build").toString()) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/ExternalReportUtils.kt ================================================ package org.jetbrains.kotlin import com.google.gson.annotations.* import com.google.gson.* import com.google.gson.stream.JsonReader import java.io.File import java.io.FileReader import java.io.PrintWriter data class ExternalTestReport(@Expose val statistics: Statistics, @Expose val groups: List) fun saveReport(reportFileName: String, statistics: Statistics, groups:List){ File(reportFileName).apply { parentFile.mkdirs() PrintWriter(this).use { it.append(gson.toJson(ExternalTestReport(statistics, groups))) } } } internal val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()!! fun loadReport(reportFileName: String) : ExternalTestReport = JsonReader(FileReader(reportFileName)).use { gson.fromJson(it, ExternalTestReport::class.java) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/FrameworkTest.kt ================================================ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.file.FileTree import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.konan.target.* import java.io.File import java.io.FileWriter import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths /** * Test task for -produce framework testing. Requires a framework to be built by the Konan plugin * with konanArtifacts { framework(frameworkName, targets: [ testTarget] ) } and a dependency set * according to a pattern "compileKonan${frameworkName}". * * @property swiftSources Swift-language test sources that use a given framework * @property frameworks names of frameworks */ open class FrameworkTest : DefaultTask(), KonanTestExecutable { @Input lateinit var swiftSources: List @Input var swiftExtraOpts: List = emptyList() @Input lateinit var frameworks: MutableList @Input var fullBitcode: Boolean = false @Input var codesign: Boolean = true val testOutput: String = project.testOutputFramework @Input @Optional var expectedExitStatus: Int? = null /** * Framework description. * * @param name is the framework name, * @param sources framework sources, * @param bitcode bitcode embedding in the framework, * @param isStatic determines that framework is static * @param artifact the name of the resulting artifact, * @param library library dependency name, * @param opts additional options for the compiler. */ class Framework( val name: String, var sources: List = emptyList(), var bitcode: Boolean = false, var isStatic: Boolean = false, var artifact: String = name, var library: String? = null, var opts: List = emptyList() ) /** * Used for the framework configuration in the task's closure. */ fun framework(name: String, closure: Closure): Framework { val f = Framework(name).apply { closure.delegate = this closure.resolveStrategy = Closure.DELEGATE_FIRST closure.call() // map to file paths sources = sources.toFiles(Language.Kotlin).map { it.path } } if (!::frameworks.isInitialized) { frameworks = mutableListOf(f) } else { frameworks.add(f) } return f } enum class Language(val extension: String) { Kotlin(".kt"), ObjC(".m"), Swift(".swift") } fun Language.filesFrom(dir: String): FileTree = project.fileTree(dir) { // include only files with the language extension it.include("*${this.extension}") } fun List.toFiles(language: Language): List = this.map { language.filesFrom(it) } .flatMap { it.files } override val executable: String get() = Paths.get(testOutput, name, "swiftTestExecutable").toString() override var doBeforeRun: Action? = null override var doBeforeBuild: Action? = null override val buildTasks: List get() = frameworks.map { project.tasks.getByName("compileKonan${it.name}") } @Suppress("UnstableApiUsage") override fun configure(config: Closure<*>): Task { super.configure(config) // set crossdist build dependency if custom konan.home wasn't set this.dependsOnDist() // Set Gradle properties for the better navigation group = LifecycleBasePlugin.VERIFICATION_GROUP description = "Kotlin/Native test infrastructure task" check(::frameworks.isInitialized) { "Frameworks should be set" } return this } private fun buildTestExecutable() { val frameworkParentDirPath = "$testOutput/$name/${project.testTarget.name}" frameworks.forEach { framework -> val frameworkArtifact = framework.artifact val frameworkPath = "$frameworkParentDirPath/$frameworkArtifact.framework" val frameworkBinaryPath = "$frameworkPath/$frameworkArtifact" validateBitcodeEmbedding(frameworkBinaryPath) if (codesign) codesign(project, frameworkPath) } // create a test provider and get main entry point val provider = Paths.get(testOutput, name, "provider.swift") FileWriter(provider.toFile()).use { writer -> val providers = swiftSources.toFiles(Language.Swift) .map { it.name.toString().removeSuffix(".swift").capitalize() } .map { "${it}Tests" } writer.write(""" |// THIS IS AUTOGENERATED FILE |// This method is invoked by the main routine to get a list of tests |func registerProviders() { | ${providers.joinToString("\n ") { "$it()" }} |} """.trimMargin()) } val testHome = project.file("framework").toPath() val swiftMain = Paths.get(testHome.toString(), "main.swift").toString() // Compile swift sources val sources = swiftSources.toFiles(Language.Swift) .map { it.path } + listOf(provider.toString(), swiftMain) val options = listOf( "-g", "-Xlinker", "-rpath", "-Xlinker", "@executable_path/Frameworks", "-Xlinker", "-rpath", "-Xlinker", frameworkParentDirPath, "-F", frameworkParentDirPath, "-Xcc", "-Werror" // To fail compilation on warnings in framework header. ) compileSwift(project, project.testTarget, sources, options + swiftExtraOpts, Paths.get(executable), fullBitcode) } @TaskAction fun run() { // Build test executable as a first action of the task before executing the test buildTestExecutable() doBeforeRun?.execute(this) runTest(executorService = project.executor, testExecutable = Paths.get(executable)) } /** * Returns path to directory that contains `libswiftCore.dylib` for the current * test target. */ private fun getSwiftLibsPathForTestTarget(): String { val target = project.testTarget val platform = project.platformManager.platform(target) val configs = platform.configurables as AppleConfigurables val swiftPlatform = when (target) { KonanTarget.IOS_X64 -> "iphonesimulator" KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64 -> "iphoneos" KonanTarget.TVOS_X64 -> "appletvsimulator" KonanTarget.TVOS_ARM64 -> "appletvos" KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64 -> "macosx" KonanTarget.WATCHOS_ARM64 -> "watchos" KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_X86 -> "watchsimulator" else -> throw IllegalStateException("Test target $target is not supported") } val simulatorPath = when (target) { KonanTarget.TVOS_X64, KonanTarget.IOS_X64, KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64 -> Xcode.current.getLatestSimulatorRuntimeFor(target, configs.osVersionMin)?.bundlePath?.let { "$it/Contents/Resources/RuntimeRoot/usr/lib/swift" } else -> null } // Use default path from toolchain if we cannot get `bundlePath` for target. // It may be the case for simulators if Xcode/macOS is old. return simulatorPath ?: configs.absoluteTargetToolchain + "/usr/lib/swift-5.0/$swiftPlatform" } private fun buildEnvironment(): Map { val target = project.testTarget // Hopefully, lexicographical comparison will work. val newMacos = System.getProperty("os.version").compareTo("10.14.4") >= 0 val dyldLibraryPathKey = when (target) { KonanTarget.IOS_X64, KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64, KonanTarget.TVOS_X64 -> "SIMCTL_CHILD_DYLD_LIBRARY_PATH" else -> "DYLD_LIBRARY_PATH" } // TODO: macos_arm64? return if (newMacos && target == KonanTarget.MACOS_X64) emptyMap() else mapOf( dyldLibraryPathKey to getSwiftLibsPathForTestTarget() ) } private fun runTest(executorService: ExecutorService, testExecutable: Path, args: List = emptyList()) { val (stdOut, stdErr, exitCode) = runProcess( executor = { executorService.add(Action { it.environment = buildEnvironment() it.workingDir = Paths.get(testOutput).toFile() }).execute(it) }, executable = testExecutable.toString(), args = args) val testExecName = testExecutable.fileName println(""" |$testExecName |stdout: $stdOut |stderr: $stdErr """.trimMargin()) check(exitCode == expectedExitStatus ?: 0) { "Execution of $testExecName failed with exit code: $exitCode " } } private fun validateBitcodeEmbedding(frameworkBinary: String) { // Check only the full bitcode embedding for now. if (!fullBitcode) { return } val testTarget = project.testTarget val configurables = project.platformManager.platform(testTarget).configurables as AppleConfigurables val bitcodeBuildTool = "${configurables.absoluteAdditionalToolsDir}/bin/bitcode-build-tool" val toolPath = "${configurables.absoluteTargetToolchain}/usr/bin/" val sdk = when (testTarget) { KonanTarget.IOS_X64, KonanTarget.TVOS_X64, KonanTarget.WATCHOS_X86, KonanTarget.WATCHOS_X64 -> return // bitcode-build-tool doesn't support simulators. KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32 -> Xcode.current.iphoneosSdk KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64 -> Xcode.current.macosxSdk KonanTarget.TVOS_ARM64 -> Xcode.current.appletvosSdk KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_ARM64 -> Xcode.current.watchosSdk else -> error("Cannot validate bitcode for test target $testTarget") } val python3 = listOf("/usr/bin/python3", "/usr/local/bin/python3") .map { Paths.get(it) }.firstOrNull { Files.exists(it) } ?: error("Can't find python3") runTest(executorService = localExecutorService(project), testExecutable = python3, args = listOf("-B", bitcodeBuildTool, "--sdk", sdk, "-v", "-t", toolPath, frameworkBinary)) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/Internals.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import org.gradle.api.NamedDomainObjectCollection import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.api.provider.Provider import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation import java.io.File /* * This file includes internal short-cuts visible only inside of the 'buildSrc' module. */ internal val hostOs by lazy { System.getProperty("os.name") } internal val userHome by lazy { System.getProperty("user.home") } internal val Project.ext: ExtraPropertiesExtension get() = extensions.getByName("ext") as ExtraPropertiesExtension internal val Project.kotlin: KotlinMultiplatformExtension get() = extensions.getByName("kotlin") as KotlinMultiplatformExtension internal val NamedDomainObjectCollection>.macosX64: KotlinTargetPreset<*> get() = getByName(::macosX64.name) as KotlinTargetPreset<*> internal val NamedDomainObjectCollection>.linuxX64: KotlinTargetPreset<*> get() = getByName(::linuxX64.name) as KotlinTargetPreset<*> internal val NamedDomainObjectCollection>.mingwX64: KotlinTargetPreset<*> get() = getByName(::mingwX64.name) as KotlinTargetPreset<*> internal val NamedDomainObjectContainer>.main: KotlinNativeCompilation get() = getByName(::main.name) as KotlinNativeCompilation internal val FileCollection.isNotEmpty: Boolean get() = !isEmpty internal fun Provider.resolve(child: String): Provider = map { it.resolve(child) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/KLibInstall.kt ================================================ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Task import org.gradle.api.provider.Provider import org.gradle.api.tasks.Exec import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputDirectory import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.HostManager import java.io.File // TODO: Implement as a part of the gradle plugin open class KlibInstall: Exec() { @Input lateinit var klib: Provider @Input var repo: File = project.rootDir val installDir: Provider @OutputDirectory get() = project.provider { val klibName = klib.get().nameWithoutExtension project.file("${repo.absolutePath}/$klibName") } @Input var target: String = HostManager.hostName override fun configure(config: Closure<*>): Task { val result = super.configure(config) val konanHome = project.kotlinNativeDist val suffix = if (HostManager.host == KonanTarget.MINGW_X64) ".bat" else "" val klibProgram = "$konanHome/bin/klib$suffix" doFirst { repo.mkdirs() commandLine(klibProgram, "install", klib.get().absolutePath, "-target", target, "-repository", repo.absolutePath ) } return result } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestExecutable.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.Action import org.gradle.api.Task /** * An interface that any test that works with ExecutorService * should implement to be run on different platforms. */ interface KonanTestExecutable : Task { /** * Test executable to be run by the service. */ val executable: String /** * Action that configures task or does some workload before the test will be executed. * Could be done as a first step in the test or just as a `doFirst` action in the test task. */ var doBeforeRun: Action? /** * Action that configures task or does some workload before the test will be built. * Depending on the test task implementation this action is done before the build task * or as its `doFirst` action. */ var doBeforeBuild: Action? /** * Build tasks that this [executable] depends on, or is built from. */ val buildTasks: List } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/KonanTestSuiteReport.kt ================================================ package org.jetbrains.kotlin import com.google.gson.annotations.Expose import java.io.PrintWriter import java.io.StringWriter import org.gradle.api.Project enum class TestStatus { PASSED, FAILED, ERROR, SKIPPED } data class Statistics( @Expose var passed: Int = 0, @Expose var failed: Int = 0, @Expose var error: Int = 0, @Expose var skipped: Int = 0) { fun pass(count: Int = 1) { passed += count } fun skip(count: Int = 1) { skipped += count } fun fail(count: Int = 1) { failed += count } fun error(count: Int = 1) { error += count } fun add(other: Statistics) { passed += other.passed failed += other.failed error += other.error skipped += other.skipped } } val Statistics.total: Int get() = passed + failed + error + skipped class TestFailedException(msg:String) : RuntimeException(msg) data class KonanTestGroupReport(@Expose val name: String, val suites: List) data class KonanTestSuiteReport(@Expose val name: String, val tests: List) data class KonanTestCaseReport(@Expose val name: String, @Expose val status: TestStatus, @Expose val comment: String? = null) class KonanTestSuiteReportEnvironment(val name: String, val project: Project, val statistics: Statistics) { private val tc = if (Tc.enabled) TeamCityTestPrinter(project) else null val tests = mutableListOf() fun executeTest(testName: String, action:() -> Unit) { var test: KonanTestCaseReport? try { tc?.startTest(testName) action() tc?.passTest(testName) statistics.pass() test = KonanTestCaseReport(testName, TestStatus.PASSED) } catch (e:TestFailedException) { tc?.failedTest(testName, e) statistics.fail() test = KonanTestCaseReport(testName, TestStatus.FAILED, "Exception: ${e.message}. Cause: ${e.cause?.message}") project.logger.quiet("test: $testName failed") } catch (e:Exception) { tc?.errorTest(testName, e) statistics.error() test = KonanTestCaseReport(testName, TestStatus.ERROR, "Exception: ${e.message}. Cause: ${e.cause?.message}") project.logger.quiet("error on test: $testName", e) } test!!.apply { tests += this if (status == TestStatus.ERROR || status == TestStatus.FAILED) { project.logger.quiet("Command to reproduce: ./gradlew $name -Pfilter=${test.name}\n") } } } fun skipTest(name: String) { tc?.skipTest(name) statistics.skip() tests += KonanTestCaseReport(name, TestStatus.SKIPPED) } fun abort(throwable: Throwable, count:Int) { statistics.error(count) project.logger.quiet("suite `$name` aborted with exception", throwable) } internal operator fun invoke(action: (KonanTestSuiteReportEnvironment) -> Unit) { tc?.suiteStart(name) action(this) tc?.suiteFinish(name) } } class KonanTestGroupReportEnvironment(val project:Project) { val statistics = Statistics() val suiteReports = mutableListOf() fun suite(suiteName:String, action:(KonanTestSuiteReportEnvironment)->Unit) { val konanTestSuiteEnvironment = KonanTestSuiteReportEnvironment(suiteName, project, statistics) konanTestSuiteEnvironment { action(it) } suiteReports += KonanTestSuiteReport(suiteName, konanTestSuiteEnvironment.tests) } } private class TeamCityTestPrinter(val project:Project) { fun suiteStart(name: String) { teamcityReport("testSuiteStarted name='$name'") } fun suiteFinish(name: String) { teamcityReport("testSuiteFinished name='$name'") } fun startTest(name: String) { teamcityReport("testStarted name='$name'") } fun passTest(testName: String) = teamcityFinish(testName) fun failedTest(testName: String, testFailedException: TestFailedException) { teamcityReport("testFailed type='comparisonFailure' name='$testName' message='${testFailedException.message.toTeamCityFormat()}'") teamcityFinish(testName) } fun errorTest(testName: String, exception: Exception) { val writer = StringWriter() exception.printStackTrace(PrintWriter(writer)) val rawString = writer.toString() teamcityReport("testFailed name='$testName' message='${exception.message.toTeamCityFormat()}' " + "details='${rawString.toTeamCityFormat()}'") teamcityFinish(testName) } fun skipTest(testName: String) { teamcityReport("testIgnored name='$testName'") teamcityFinish(testName) } private fun teamcityFinish(testName:String) { teamcityReport("testFinished name='$testName'") } /** * Teamcity require escaping some symbols in pipe manner. * https://github.com/GitTools/GitVersion/issues/94 */ private fun String?.toTeamCityFormat(): String = this?.let { it.replace("\\|", "||") .replace("\r", "|r") .replace("\n", "|n") .replace("'", "|'") .replace("\\[", "|[") .replace("]", "|]")} ?: "null" private fun teamcityReport(msg: String) { project.logger.quiet("##teamcity[$msg]") } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinBuildPusher.kt ================================================ package org.jetbrains.kotlin import io.ktor.client.HttpClient import io.ktor.client.request.get import io.ktor.client.request.header import io.ktor.client.request.post import io.ktor.content.TextContent import io.ktor.http.ContentType import kotlinx.coroutines.runBlocking import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option @Suppress("UnstableApiUsage") open class KotlinBuildPusher : DefaultTask() { @Input @Option(option = "token", description = "Teamcity Bear token") var token: String? = "" @Input @Option(option = "buildServer", description = "Teamcity server") var buildServer: String = "" @Input @Option(option = "compilerConfigurationId", description = "Teamcity configuration id") var compilerConfigurationId: String = "Kotlin_dev_Compiler" @Input @Option(option = "overrideConfigurationId", description = "Teamcity kotlin override configuration id") var overrideConfigurationId: String = "Kotlin_dev_DeployMavenArtifacts_OverrideNative" @Input @Option(option = "kotlinVersion", description = "Kotlin Compiler Version") var kotlinVersion: String = "" @Input @Option(option = "konanVersion", description = "Kotlin Native Compiler Version") var konanVersion: String = "" @TaskAction fun run() { requireNotNull(token, { "Teamcity Bear token required" }) val client = HttpClient() runBlocking { val buildId = client.get( scheme = "https", host = buildServer, path = "/app/rest/builds/buildType:(id:$compilerConfigurationId),number:$kotlinVersion/id" ) { header("Authorization", "Bearer $token") } project.logger.info("pusher: buildId: $buildId") /** * * * * * * * * * */ val content = buildString { build { buildType(overrideConfigurationId) lastChanges { change(buildId) } properties { property("system.versions.kotlin-native", konanVersion) } } } project.logger.info("pusher: content: \"$content\"") val res = client.post( scheme = "https", host = buildServer, path = "/app/rest/buildQueue" ) { header("Authorization", "Bearer $token") header("Origin", "https://$buildServer") body = TextContent(content, ContentType.Application.Xml) } project.logger.info("pusher: result: \"$res\"") } client.close() } } internal fun StringBuilder.paired(tag:String, body:StringBuilder.()->Unit) { appendln("<$tag>") body() appendln("") } internal fun StringBuilder.build(body: StringBuilder.() -> Unit) = paired("build", body) internal fun StringBuilder.buildType(id: String) = appendln("") internal fun StringBuilder.lastChanges(body: StringBuilder.() -> Unit) = paired("lastChanges", body) internal fun StringBuilder.change(build: String) = appendln("") internal fun StringBuilder.properties(body: StringBuilder.() -> Unit) = paired("properties", body) internal fun StringBuilder.property(key: String, value: String) = appendln("") ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinNativeTest.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction import org.gradle.language.base.plugins.LifecycleBasePlugin import org.gradle.process.ExecSpec import org.jetbrains.kotlin.konan.exec.Command import java.io.File import java.io.ByteArrayOutputStream import java.util.regex.Pattern import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.LinkerOutputKind abstract class KonanTest : DefaultTask(), KonanTestExecutable { enum class Logger { EMPTY, // Built without test runner GTEST, // Google test log output TEAMCITY, // TeamCity log output SIMPLE, // Prints simple messages of passed/failed tests SILENT // Prints no log of passed/failed tests } var disabled: Boolean get() = !enabled set(value) { enabled = !value } /** * Test output directory. Used to store processed sources and binary artifacts. */ abstract val outputDirectory: String /** * Test logger to be used for the test built with TestRunner (`-tr` option). */ abstract var testLogger: Logger /** * Test executable arguments. */ @Input var arguments = mutableListOf() /** * Test executable. */ abstract override val executable: String /** * Test source. */ lateinit var source: String /** * Sets test filtering to choose the exact test in the executable built with TestRunner. */ @Input var useFilter = true /** * An action to be executed before the build. * As this run task comes after the build task all actions for doFirst * should be done before the build and not run. */ @Input @Optional override var doBeforeBuild: Action? = null @Input @Optional override var doBeforeRun: Action? = null override val buildTasks: List get() = listOf(project.findKonanBuildTask(name, project.testTarget)) @Suppress("UnstableApiUsage") override fun configure(config: Closure<*>): Task { super.configure(config) // Set Gradle properties for the better navigation group = LifecycleBasePlugin.VERIFICATION_GROUP description = "Kotlin/Native test infrastructure task" if (testLogger != Logger.EMPTY) { arguments.add("--ktest_logger=$testLogger") } if (useFilter && ::source.isInitialized) { arguments.add("--ktest_filter=${source.convertToPattern()}") } this.dependsOnDist() return this } @TaskAction open fun run() = project.executeAndCheck(project.file(executable).toPath(), arguments) // Converts to runner's pattern private fun String.convertToPattern() = this.removeSuffix(".kt").replace("/", ".") + ".*" internal fun ProcessOutput.print(prepend: String = "") { if (project.verboseTest) println(prepend + """ |stdout: |$stdOut |stderr: |$stdErr |exit code: $exitCode """.trimMargin()) } } /** * Create a test task of the given type. Supports configuration with Closure passed form build.gradle file. */ fun Project.createTest(name: String, type: Class, config: Closure<*>): T = project.tasks.create(name, type).apply { // Apply closure set in build.gradle to get all parameters. this.configure(config) if (enabled) { // If run task depends on something, build tasks should also depend on this. buildTasks.forEach { buildTask -> buildTask.sameDependenciesAs(this) // Run task should depend on compile task this.dependsOn(buildTask) doBeforeBuild?.let { buildTask.doFirst(it) } buildTask.enabled = enabled } } } /** * Task to run tests compiled with TestRunner. * Runs tests with GTEST output and parses it to create statistics info */ open class KonanGTest : KonanTest() { override val outputDirectory = "${project.testOutputStdlib}/$name" // Use GTEST logger to parse test results later override var testLogger = Logger.GTEST override val executable: String get() = "$outputDirectory/${project.testTarget.name}/$name.${project.testTarget.family.exeSuffix}" var statistics = Statistics() @TaskAction override fun run() { doBeforeRun?.execute(this) runProcess( executor = {project.executor.execute(it)}, executable = executable, args = arguments ).run { parse(stdOut) println(""" |stdout: |$stdOut |stderr: |$stdErr |exit code: $exitCode """.trimMargin()) check(exitCode == 0) { "Test $executable exited with $exitCode" } } } private fun parse(output: String) = statistics.apply { Pattern.compile("\\[ PASSED ] ([0-9]*) tests\\.").matcher(output) .apply { if (find()) pass(group(1).toInt()) } Pattern.compile("\\[ FAILED ] ([0-9]*) tests.*").matcher(output) .apply { if (find()) fail(group(1).toInt()) } if (total == 0) { // No test were run. Try to find if we've tried to run something error(Pattern.compile("\\[={10}] Running ([0-9]*) tests from ([0-9]*) test cases\\..*") .matcher(output) .run { if (find()) group(1).toInt() else 1 }) } } } /** * Task to run tests built into a single predefined binary named `localTest`. * Note: this task should depend on task that builds a test binary. */ open class KonanLocalTest : KonanTest() { override val outputDirectory = project.testOutputLocal // local tests built into a single binary with the known name override val executable: String get() = "$outputDirectory/${project.testTarget.name}/localTest.${project.testTarget.family.exeSuffix}" override var testLogger = Logger.SILENT @Input @Optional var expectedExitStatus: Int? = null @Input @Optional var expectedExitStatusChecker: (Int) -> Boolean = { it == (expectedExitStatus ?: 0) } /** * Should this test fail or not. */ @Input @Optional var expectedFail = false /** * Used to validate output as a gold value. */ @Input @Optional var goldValue: String? = null /** * Checks test's output against gold value and returns true if the output matches the expectation. */ @Input @Optional var outputChecker: (String) -> Boolean = { str -> goldValue == null || goldValue == str } /** * Input test data to be passed to process' stdin. */ @Input @Optional var testData: String? = null /** * Should compiler message be read and validated with output checker or gold value. */ @Input @Optional var compilerMessages = false @Input @Optional var multiRuns = false @Input @Optional var multiArguments: List>? = null @TaskAction override fun run() { doBeforeRun?.execute(this) val times = if (multiRuns && multiArguments != null) multiArguments!!.size else 1 var output = ProcessOutput("", "", 0) for (i in 1..times) { val args = arguments + (multiArguments?.get(i - 1) ?: emptyList()) output += if (testData != null) runProcessWithInput({project.executor.execute(it)}, executable, args, testData!!) else runProcess({project.executor.execute(it)}, executable, args) } if (compilerMessages) { // TODO: as for now it captures output only in the driver task. // It should capture output from the build task using Gradle's LoggerManager and LoggerOutput val compilationLog = project.file("$executable.compilation.log").readText() // TODO: ugly hack to fix irrelevant warnings. val filteredCompilationLog = compilationLog.split('\n').filter { it != "warning: relaxed memory model is not yet fully functional" }.joinToString(separator = "\n") output.stdOut = filteredCompilationLog + output.stdOut } output.check() output.print() } private operator fun ProcessOutput.plus(other: ProcessOutput) = ProcessOutput( stdOut + other.stdOut, stdErr + other.stdErr, exitCode + other.exitCode) private fun ProcessOutput.check() { val exitCodeMismatch = !expectedExitStatusChecker(exitCode) if (exitCodeMismatch) { val message = if (expectedExitStatus != null) "Expected exit status: $expectedExitStatus, actual: $exitCode" else "Actual exit status doesn't match with exit status checker: $exitCode" check(expectedFail) { """ |Test failed. $message |stdout: |$stdOut |stderr: |$stdErr """.trimMargin() } println("Expected failure. $message") } val result = stdOut + stdErr val goldValueMismatch = !outputChecker(result.replace(System.lineSeparator(), "\n")) if (goldValueMismatch) { val message = if (goldValue != null) "Expected output: $goldValue, actual output: $result" else "Actual output doesn't match with output checker: $result" check(expectedFail) { "Test failed. $message" } println("Expected failure. $message") } check ((exitCodeMismatch || goldValueMismatch) || !expectedFail) { """ |Unexpected pass: | * exit code mismatch: $exitCodeMismatch | * gold value mismatch: $goldValueMismatch | * expected fail: $expectedFail """.trimMargin() } } } /** * Executes a standalone tests provided with either @param executable or by the tasks @param name. * The executable itself should be built by the konan plugin. */ open class KonanStandaloneTest : KonanLocalTest() { init { useFilter = false } override val outputDirectory: String get() = "${project.testOutputLocal}/$name" override var testLogger = Logger.EMPTY override val executable: String get() = "$outputDirectory/${project.testTarget.name}/$name.${project.testTarget.family.exeSuffix}" @Input @Optional var enableKonanAssertions = true @Input @Optional var verifyIr = true /** * Compiler flags used to build a test. */ var flags: List = listOf() get() { val result = field.toMutableList() if (enableKonanAssertions) result += "-ea" if (verifyIr) result += "-Xverify-ir" return result } fun getSources(): Provider> = project.provider { val sources = buildCompileList(project.file(source).toPath(), outputDirectory) sources.forEach { it.writeTextToFile() } sources.map { it.path } } } /** * This is another way to run the konanc compiler. It runs a konanc shell script. * * @note This task is not intended for regular testing as project.exec + a shell script isolate the jvm from IDEA. * @see KonanLocalTest to be used as a regular task. */ open class KonanDriverTest : KonanStandaloneTest() { override fun configure(config: Closure<*>): Task { super.configure(config) doFirst { konan() } doBeforeBuild?.let { doFirst(it) } return this } private fun konan() { val dist = project.kotlinNativeDist val konancDriver = if (HostManager.hostIsMingw) "konanc.bat" else "konanc" val konanc = File("${dist.canonicalPath}/bin/$konancDriver").absolutePath File(executable).parentFile.mkdirs() val args = mutableListOf("-output", executable).apply { if (project.testTarget != HostManager.host) { add("-target") add(project.testTarget.visibleName) } addAll(getSources().get()) addAll(flags) addAll(project.globalTestArgs) } // run konanc compiler locally runProcess(localExecutor(project), konanc, args).let { it.print("Konanc compiler execution:") project.file("$executable.compilation.log").run { writeText(it.stdOut) appendText(it.stdErr) } check(it.exitCode == 0) { "Compiler failed with exit code ${it.exitCode}" } } } } open class KonanInteropTest : KonanStandaloneTest() { /** * Name of the interop library */ @Input lateinit var interop: String } open class KonanLinkTest : KonanStandaloneTest() { @Input lateinit var lib: String } /** * Test task to check a library built by `-produce dynamic`. * C source code should contain `testlib` as a reference to a testing library. * It will be replaced then by the actual library name. */ open class KonanDynamicTest : KonanStandaloneTest() { override fun configure(config: Closure<*>): Task { super.configure(config) doFirst { clang() } return this } /** * File path to the C source. */ @Input lateinit var cSource: String @Input var clangTool = "clang" @Input var clangFlags: List = listOf() @Input @Optional var interop: String? = null // Replace testlib_api.h and all occurrences of the testlib with the actual name of the test private fun processCSource(): String { val sourceFile = File(cSource) val prefixedName = if (HostManager.hostIsMingw) name else "lib$name" val res = sourceFile.readText() .replace("#include \"testlib_api.h\"", "#include \"${prefixedName}_api.h\"") .replace("testlib", prefixedName) val newFileName = "$outputDirectory/${sourceFile.name}" println(newFileName) File(newFileName).run { createNewFile() writeText(res) } return newFileName } private fun clang() { val log = ByteArrayOutputStream() val plugin = project.convention.getPlugin(ExecClang::class.java) val artifactsDir = "$outputDirectory/${project.testTarget}" fun flagsContain(opt: String) = project.globalTestArgs.contains(opt) || flags.contains(opt) val isOpt = flagsContain("-opt") val isDebug = flagsContain("-g") val execResult = plugin.execKonanClang(project.testTarget) { it.workingDir = File(outputDirectory) it.executable = clangTool it.args = listOf(processCSource(), "-c", "-o", "$executable.o", "-I", artifactsDir ) + clangFlags it.standardOutput = log it.errorOutput = log it.isIgnoreExitValue = true } log.toString("UTF-8").also { project.file("$executable.compilation.log").writeText(it) println(it) } execResult.assertNormalExitValue() val linker = project.platformManager.platform(project.testTarget).linker val commands = linker.finalLinkCommands( objectFiles = listOf("$executable.o"), executable = executable, libraries = listOf("-l$name"), linkerArgs = listOf("-L", artifactsDir, "-rpath", artifactsDir), optimize = isOpt, debug = isDebug, kind = LinkerOutputKind.EXECUTABLE, outputDsymBundle = "", needsProfileLibrary = false, mimallocEnabled = false ) commands.map { cmd -> // Filter out linker option that defines __cxa_demangle because Konan_cxa_demangle is not defined in tests. Command(cmd.argsWithExecutable.filterNot { it.contains("--defsym") || it.contains("Konan_cxa_demangle") }) }.forEach { it.logWith { message -> project.file("$executable.compilation.log").appendText(message()) } it.execute() } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/LlvmCovReport.kt ================================================ package org.jetbrains.kotlin import com.google.gson.* import com.google.gson.annotations.* data class LlvmCovReportFunction( @Expose val name: String, @Expose val count: Int, @Expose val regions: List>, @Expose val filenames: List ) data class LlvmCovReportSummary( @Expose val lines: LlvmCovReportStatistics, @Expose val functions: LlvmCovReportStatistics, @Expose val instantiations: LlvmCovReportStatistics, @Expose val regions: LlvmCovReportStatistics ) /** * TODO: Add support for `segments` field later. * It's a bit complicated since every segment * is encoded not as dictionary, but as array of ints and bools. */ data class LlvmCovReportFile( @Expose val filename: String, @Expose val summary: LlvmCovReportSummary ) data class LlvmCovReportStatistics( @Expose val count: Int, @Expose val covered: Int, @Expose val percent: Double ) data class LlvmCovReportData( @Expose val files: List, @Expose val functions: List, @Expose val totals: LlvmCovReportSummary ) data class LlvmCovReport( @Expose val version: String, @Expose val type: String, @Expose val data: List ) fun parseLlvmCovReport(llvmCovReport: String): LlvmCovReport = gson.fromJson(llvmCovReport, LlvmCovReport::class.java) val LlvmCovReport.isValid get() = type == "llvm.coverage.json.export" ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/MPPTools.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ @file:JvmName("MPPTools") package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.TaskState import org.gradle.api.execution.TaskExecutionListener import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.report.* import org.jetbrains.report.json.* import java.nio.file.Paths import java.io.File import java.io.FileInputStream import java.io.BufferedOutputStream import java.io.BufferedInputStream import java.net.HttpURLConnection import java.net.URL import java.util.Base64 /* * This file includes short-cuts that may potentially be implemented in Kotlin MPP Gradle plugin in the future. */ // Short-cuts for mostly used paths. @get:JvmName("mingwPath") val mingwPath by lazy { System.getenv("MINGW64_DIR") ?: "c:/msys64/mingw64" } @get:JvmName("kotlinNativeDataPath") val kotlinNativeDataPath by lazy { System.getenv("KONAN_DATA_DIR") ?: Paths.get(userHome, ".konan").toString() } // A short-cut for evaluation of the default host Kotlin/Native preset. @JvmOverloads fun defaultHostPreset( subproject: Project, whitelist: List> = listOf(subproject.kotlin.presets.macosX64, subproject.kotlin.presets.linuxX64, subproject.kotlin.presets.mingwX64) ): KotlinTargetPreset<*> { if (whitelist.isEmpty()) throw Exception("Preset whitelist must not be empty in Kotlin/Native ${subproject.displayName}.") val presetCandidate = when { PlatformInfo.isMac() -> subproject.kotlin.presets.macosX64 PlatformInfo.isLinux() -> subproject.kotlin.presets.linuxX64 PlatformInfo.isWindows() -> subproject.kotlin.presets.mingwX64 else -> null } return if (presetCandidate != null && presetCandidate in whitelist) presetCandidate else throw Exception("Host OS '$hostOs' is not supported in Kotlin/Native ${subproject.displayName}.") } fun getNativeProgramExtension(): String = when { PlatformInfo.isMac() -> ".kexe" PlatformInfo.isLinux() -> ".kexe" PlatformInfo.isWindows() -> ".exe" else -> error("Unknown host") } fun getFileSize(filePath: String): Long? { val file = File(filePath) return if (file.exists()) file.length() else null } fun getCodeSizeBenchmark(programName: String, filePath: String): BenchmarkResult { val codeSize = getFileSize(filePath) return BenchmarkResult(programName, codeSize?. let { BenchmarkResult.Status.PASSED } ?: run { BenchmarkResult.Status.FAILED }, codeSize?.toDouble() ?: 0.0, BenchmarkResult.Metric.CODE_SIZE, codeSize?.toDouble() ?: 0.0, 1, 0) } fun toCodeSizeBenchmark(metricDescription: String, status: String, programName: String): BenchmarkResult { if (!metricDescription.startsWith("CODE_SIZE")) { error("Wrong metric is used as code size.") } val codeSize = metricDescription.split(' ')[1].toDouble() return BenchmarkResult(programName, if (status == "PASSED") BenchmarkResult.Status.PASSED else BenchmarkResult.Status.FAILED, codeSize, BenchmarkResult.Metric.CODE_SIZE, codeSize, 1, 0) } // Create benchmarks json report based on information get from gradle project fun createJsonReport(projectProperties: Map): String { fun getValue(key: String): String = projectProperties[key] as? String ?: "unknown" val machine = Environment.Machine(getValue("cpu"), getValue("os")) val jdk = Environment.JDKInstance(getValue("jdkVersion"), getValue("jdkVendor")) val env = Environment(machine, jdk) val flags: List = (projectProperties["flags"] as? List<*>)?.filterIsInstance() ?: emptyList() val backend = Compiler.Backend(Compiler.backendTypeFromString(getValue("type"))!! , getValue("compilerVersion"), flags) val kotlin = Compiler(backend, getValue("kotlinVersion")) val benchDesc = getValue("benchmarks") val benchmarksArray = JsonTreeParser.parse(benchDesc) val benchmarks = parseBenchmarksArray(benchmarksArray) .union((projectProperties["compileTime"] as? List<*>)?.filterIsInstance() ?: emptyList()).union( listOf(projectProperties["codeSize"] as? BenchmarkResult).filterNotNull()).toList() val report = BenchmarksReport(env, benchmarks, kotlin) return report.toJson() } fun mergeReports(reports: List): String { val reportsToMerge = reports.filter { it.exists() }.map { val json = it.inputStream().bufferedReader().use { it.readText() } val reportElement = JsonTreeParser.parse(json) BenchmarksReport.create(reportElement) } val structuredReports = mutableMapOf>() reportsToMerge.map { it.compiler.backend.flags.joinToString() to it }.forEach { structuredReports.getOrPut(it.first) { mutableListOf() }.add(it.second) } val jsons = structuredReports.map { (_, value) -> value.reduce { result, it -> result + it }.toJson() } return when(jsons.size) { 0 -> "" 1 -> jsons[0] else -> jsons.joinToString(prefix = "[", postfix = "]") } } fun getCompileOnlyBenchmarksOpts(project: Project, defaultCompilerOpts: List): List { val dist = project.file(project.findProperty("kotlin.native.home") ?: "dist") val useCache = !project.hasProperty("disableCompilerCaches") val cacheOption = "-Xcache-directory=$dist/klib/cache/${HostManager.host.name}-gSTATIC" .takeIf { useCache && !PlatformInfo.isWindows() } // TODO: remove target condition when we have cache support for other targets. return (project.findProperty("nativeBuildType") as String?)?.let { if (it.equals("RELEASE", true)) listOf("-opt") else if (it.equals("DEBUG", true)) listOfNotNull("-g", cacheOption) else listOf() } ?: defaultCompilerOpts + listOfNotNull(cacheOption?.takeIf { !defaultCompilerOpts.contains("-opt") }) } // Find file with set name in directory. fun findFile(fileName: String, directory: String): String? = File(directory).walkTopDown().filter { !it.absolutePath.contains(".dSYM") } .find { it.name == fileName }?.getAbsolutePath() fun uploadFileToArtifactory(url: String, project: String, artifactoryFilePath: String, filePath: String, password: String) { val uploadUrl = "$url/$project/$artifactoryFilePath" sendUploadRequest(uploadUrl, filePath, extraHeaders = listOf(Pair("X-JFrog-Art-Api", password))) } fun sendUploadRequest(url: String, fileName: String, username: String? = null, password: String? = null, extraHeaders: List> = emptyList()) { val uploadingFile = File(fileName) val connection = URL(url).openConnection() as HttpURLConnection connection.doOutput = true connection.doInput = true connection.requestMethod = "PUT" connection.setRequestProperty("Content-type", "text/plain") if (username != null && password != null) { val auth = Base64.getEncoder().encode((username + ":" + password).toByteArray()).toString(Charsets.UTF_8) connection.addRequestProperty("Authorization", "Basic $auth") } extraHeaders.forEach { connection.addRequestProperty(it.first, it.second) } try { connection.connect() BufferedOutputStream(connection.outputStream).use { output -> BufferedInputStream(FileInputStream(uploadingFile)).use { input -> input.copyTo(output) } } val response = connection.responseMessage println("Upload request ended with ${connection.responseCode} - $response") } catch (t: Throwable) { error("Couldn't upload file $fileName to $url") } } // A short-cut to add a Kotlin/Native run task. fun createRunTask( subproject: Project, name: String, linkTask: Task, executable: String, outputFileName: String ): Task { return subproject.tasks.create(name, RunKotlinNativeTask::class.java, linkTask, executable, outputFileName) } fun getJvmCompileTime(subproject: Project,programName: String): BenchmarkResult = TaskTimerListener.getTimerListenerOfSubproject(subproject) .getBenchmarkResult(programName, listOf("compileKotlinMetadata", "jvmJar")) @JvmOverloads fun getNativeCompileTime(subproject: Project, programName: String, tasks: List = listOf("linkBenchmarkReleaseExecutableNative")): BenchmarkResult = TaskTimerListener.getTimerListenerOfSubproject(subproject).getBenchmarkResult(programName, tasks) fun getCompileBenchmarkTime(subproject: Project, programName: String, tasksNames: Iterable, repeats: Int, exitCodes: Map) = (1..repeats).map { number -> var time = 0.0 var status = BenchmarkResult.Status.PASSED tasksNames.forEach { time += TaskTimerListener.getTimerListenerOfSubproject(subproject).getTime("$it$number") status = if (exitCodes["$it$number"] != 0) BenchmarkResult.Status.FAILED else status } BenchmarkResult(programName, status, time, BenchmarkResult.Metric.COMPILE_TIME, time, number, 0) }.toList() fun toCompileBenchmark(metricDescription: String, status: String, programName: String): BenchmarkResult { if (!metricDescription.startsWith("COMPILE_TIME")) { error("Wrong metric is used as compile time.") } val time = metricDescription.split(' ')[1].toDouble() return BenchmarkResult(programName, if (status == "PASSED") BenchmarkResult.Status.PASSED else BenchmarkResult.Status.FAILED, time, BenchmarkResult.Metric.COMPILE_TIME, time, 1, 0) } // Class time tracker for all tasks. class TaskTimerListener: TaskExecutionListener { companion object { internal val timerListeners = mutableMapOf() internal fun getTimerListenerOfSubproject(subproject: Project) = timerListeners[subproject.name] ?: error("TimeListener for project ${subproject.name} wasn't set") } val tasksTimes = mutableMapOf() fun getBenchmarkResult(programName: String, tasksNames: List): BenchmarkResult { val time = tasksNames.map { tasksTimes[it] ?: 0.0 }.sum() // TODO get this info from gradle plugin with exit code end stacktrace. val status = tasksNames.map { tasksTimes.containsKey(it) }.reduce { a, b -> a && b } return BenchmarkResult(programName, if (status) BenchmarkResult.Status.PASSED else BenchmarkResult.Status.FAILED, time, BenchmarkResult.Metric.COMPILE_TIME, time, 1, 0) } fun getTime(taskName: String) = tasksTimes[taskName] ?: 0.0 private var startTime = System.nanoTime() override fun beforeExecute(task: Task) { startTime = System.nanoTime() } override fun afterExecute(task: Task, taskState: TaskState) { tasksTimes[task.name] = (System.nanoTime() - startTime) / 1000.0 } } fun addTimeListener(subproject: Project) { val listener = TaskTimerListener() TaskTimerListener.timerListeners.put(subproject.name, listener) subproject.gradle.addListener(listener) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/MetadataComparisonTest.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.klib.metadata.CInteropComparisonConfig import org.jetbrains.kotlin.klib.metadata.MetadataCompareResult import org.jetbrains.kotlin.klib.metadata.compareKlibMetadata import org.jetbrains.kotlin.klib.metadata.expandFail import org.jetbrains.kotlin.konan.target.HostManager import java.io.File /** * Produces 2 interop libraries from the given [defFile]. * One in legacy `sourcecode` mode and another one in `metadata` mode. * Then structurally compares metadata of the produced klibs. * * * Motivation for this kind of tests: * * `sourcecode` mode generates Kotlin source file that is passes to a * regular Kotlin/Native compiler. * Thus, the produced metadata is correct (from compiler's point of view) * because it is produced by the compiler itself. * * `metadata` mode generates metadata directly from parsed Clang AST. * Since another algorithm is used, produced metadata may be incorrect. * * So we have to check that these two are more or less the same. */ open class MetadataComparisonTest : DefaultTask() { private enum class Mode { METADATA, SOURCECODE } /** * Path to a cinterop *.def file. */ @Input lateinit var defFile: String @TaskAction fun run() { val metadataLibrary = cinterop(project.file(defFile), Mode.METADATA) val sourcecodeLibrary = cinterop(project.file(defFile), Mode.SOURCECODE) compareKlibMetadata(CInteropComparisonConfig(), sourcecodeLibrary.absolutePath, metadataLibrary.absolutePath).let { result -> if (result is MetadataCompareResult.Fail) { val message = StringBuilder().also { expandFail(result, it::appendln) }.toString() throw TestFailedException(message) } } } private fun cinterop(defFile: File, mode: Mode): File { val dist = project.kotlinNativeDist val output = "${project.buildDir.absolutePath}/${defFile.nameWithoutExtension}_$mode" val tool = if (HostManager.hostIsMingw) "cinterop.bat" else "cinterop" val cinterop = File("${dist.canonicalPath}/bin/$tool").absolutePath val args = listOf( "-def", defFile.absolutePath, "-mode", mode.name.toLowerCase(), "-target", project.testTarget.visibleName, "-no-default-libs", "-no-endorsed-libs", "-o", output ) runProcess(localExecutor(project), cinterop, args).let { result -> if (result.exitCode != 0) { println(""" cinterop failed. exitCode: ${result.exitCode} stdout: ${result.stdOut} stderr: ${result.stdErr} """.trimIndent()) } } return File(output) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/MultiModule.kt ================================================ package org.jetbrains.kotlin interface CompilerRunner { fun runCompiler(filesToCompile: List, output: String, moreArgs: List) } // This class knows how to run the compiler for multi-module external tests. // // In addition it knows how to deal with multi-versioned modules. // The versioned modules are used for binary compatibility testing. // For such modules we produce two klibs: // `version1/foo.klib` and `version2/foo.klib`. // For un-versioned modules we still produce just `bar.klib` // We link all klibs against `version1/foo.klib` and `bar.klib` // We link the final executable against `version2/foo.klib` and `bar.klib`. class MultiModuleCompilerInvocations( val konanTest: CompilerRunner, val outputDirectory: String, val executablePath: String, val modules: Map, val flags: List ) { val libs = HashSet() fun moduleToKlibName(moduleName: String, version: Int): String { val module = modules[moduleName] ?: error("Could not find module $moduleName") return if (module.hasVersions) { val versionSuffix = "_version$version" "$executablePath$versionSuffix/$moduleName.klib" } else { "$executablePath.$moduleName.klib" } } private fun produceLibrary(module: TestModule, moduleVersion: Int) { val klibModulePath = moduleToKlibName(module.name, moduleVersion) libs.addAll(module.dependencies) // When producing klibs link them against version 1 of multiversioned klibs. val dependencyVersion = 1 val klibs = module.dependencies.flatMap { listOf("-l", moduleToKlibName(it, dependencyVersion)) } val repos = listOf("-r", "${executablePath}_version$dependencyVersion", "-r", outputDirectory) val friends = module.friends.flatMap { listOf("-friend-modules", "$executablePath.$it.klib") } konanTest.runCompiler(module.versionFiles(moduleVersion).map { it.path }, klibModulePath, flags + listOf("-p", "library") + repos + klibs + friends) } fun produceLibrary(module: TestModule) { if (!module.hasVersions) { produceLibrary(module, 1) } else { produceLibrary(module, 1) produceLibrary(module, 2) } } fun produceProgram(compileList: List) { val compileMain = compileList.filter { it.module.isDefaultModule() || it.module === TestModule.support } compileMain.forEach { f -> libs.addAll(f.module.dependencies) } // When producing klibs link them against version 2 of multiversioned klibs. val dependencyVersion = 2 val friends = compileMain.flatMap { it.module.friends }.toSet() val repos = listOf("-r", "${executablePath}_version$dependencyVersion", "-r", outputDirectory) if (compileMain.isNotEmpty()) { konanTest.runCompiler(compileMain.map { it.path }, executablePath, flags + repos + libs.flatMap { listOf("-l", moduleToKlibName(it, dependencyVersion)) } + friends.flatMap { listOf("-friend-modules", "${executablePath}.${it}.klib") } ) } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/PlatformInfo.kt ================================================ package org.jetbrains.kotlin import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.* import org.gradle.api.Project object PlatformInfo { @JvmStatic fun isMac() = HostManager.hostIsMac @JvmStatic fun isWindows() = HostManager.hostIsMingw @JvmStatic fun isLinux() = HostManager.hostIsLinux @JvmStatic fun isAppleTarget(project: Project): Boolean { val target = getTarget(project) return target.family.isAppleFamily } @JvmStatic fun isAppleTarget(target: KonanTarget): Boolean { return target.family.isAppleFamily } @JvmStatic fun isWindowsTarget(project: Project) = getTarget(project).family == Family.MINGW @JvmStatic fun isWasmTarget(project: Project) = getTarget(project).family == Family.WASM @JvmStatic fun getTarget(project: Project): KonanTarget { val platformManager = project.rootProject.platformManager val targetName = project.project.testTarget.name return platformManager.targetManager(targetName).target } @JvmStatic fun checkXcodeVersion(project: Project) { val properties = PropertiesProvider(project) val requiredMajorVersion = properties.xcodeMajorVersion if (!DependencyProcessor.isInternalSeverAvailable && properties.checkXcodeVersion && requiredMajorVersion != null ) { val currentXcodeVersion = Xcode.current.version val currentMajorVersion = currentXcodeVersion.splitToSequence('.').first() if (currentMajorVersion != requiredMajorVersion) { throw IllegalStateException( "Incorrect Xcode version: ${currentXcodeVersion}. Required major Xcode version is ${requiredMajorVersion}." ) } } } fun unsupportedPlatformException() = TargetSupportException() } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/PropertiesProvider.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.Project import java.util.* class PropertiesProvider(val project: Project) { private val localProperties by lazy { Properties().apply { project.file("local.properties").takeIf { it.isFile }?.inputStream()?.use { load(it) } } } fun findProperty(name: String): Any? = project.findProperty(name) ?: localProperties.getProperty(name) fun getProperty(name: String): Any = findProperty(name) ?: throw IllegalArgumentException("No such property: $name") fun hasProperty(name: String): Boolean = project.hasProperty(name) || localProperties.containsKey(name) val xcodeMajorVersion: String? get() = findProperty("xcodeMajorVersion") as String? val checkXcodeVersion: Boolean get() = findProperty("checkXcodeVersion")?.let { it == "true" } ?: true } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/RegressionsReporter.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory import org.jetbrains.report.json.* import java.io.FileInputStream import java.io.IOException import java.io.File import java.util.concurrent.TimeUnit import java.net.HttpURLConnection import java.net.URL import java.util.Base64 import java.util.Properties /** * Task to produce regressions report and send it to slack. Requires a report with current benchmarks result * and path to analyzer tool * * @property currentBenchmarksReportFile path to file with becnhmarks result * @property analyzer path to analyzer tool * @property htmlReport name of result html report * @property defaultBranch name of default branch * @property summaryFile name of file with short summary * @property bundleBuild property to show if current build is full or not */ open class RegressionsReporter : DefaultTask() { val slackUsers = mapOf( "olonho" to "nikolay.igotti", "nikolay.igotti" to "nikolay.igotti", "ilya.matveev" to "ilya.matveev", "ilmat192" to "ilya.matveev", "vasily.v.levchenko" to "minamoto", "vasily.levchenko" to "minamoto", "alexander.gorshenev" to "alexander.gorshenev", "igor.chevdar" to "igor.chevdar", "pavel.punegov" to "Pavel Punegov", "dmitriy.dolovov" to "dmitriy.dolovov", "svyatoslav.scherbina" to "svyatoslav.scherbina", "sbogolepov" to "sergey.bogolepov", "Alexey.Zubakov" to "Alexey.Zubakov", "kirill.shmakov" to "kirill.shmakov", "elena.lepilkina" to "elena.lepilkina") @Input lateinit var currentBenchmarksReportFile: String @Input lateinit var analyzer: String @Input lateinit var htmlReport: String @Input lateinit var defaultBranch: String @Input lateinit var summaryFile: String @Input var bundleBuild: Boolean = false private fun tabUrl(buildId: String, buildTypeId: String, tab: String) = "$teamCityUrl/viewLog.html?buildId=$buildId&buildTypeId=$buildTypeId&tab=$tab" private fun testReportUrl(buildId: String, buildTypeId: String) = tabUrl(buildId, buildTypeId, "testsInfo") private fun previousBuildLocator(buildTypeId: String, branchName: String) = "buildType:id:$buildTypeId,branch:name:$branchName,status:SUCCESS,state:finished,count:1" private fun changesListUrl(buildLocator: String) = "$teamCityUrl/app/rest/changes/?locator=build:$buildLocator" private fun getCommits(buildLocator: String, user: String, password: String): CommitsList { val changes = try { sendGetRequest(changesListUrl(buildLocator), user, password) } catch (t: Throwable) { error("Try to get commits! TeamCity is unreachable!") } return CommitsList(JsonTreeParser.parse(changes)) } @TaskAction fun run() { // Get TeamCity properties. val teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") ?: error("Can't load teamcity config!") val buildProperties = Properties().apply { load(FileInputStream(teamcityConfig)) } val buildId = buildProperties.getProperty("teamcity.build.id") val buildTypeId = buildProperties.getProperty("teamcity.buildType.id") val buildNumber = buildProperties.getProperty("build.number") val user = buildProperties.getProperty("teamcity.auth.userId") val password = buildProperties.getProperty("teamcity.auth.password") // Get branch. val currentBuild = getBuild("id:$buildId", user, password) val branch = getBuildProperty(currentBuild,"branchName") val testReportUrl = testReportUrl(buildId, buildTypeId) // Get previous build on branch. getBuild(previousBuildLocator(buildTypeId,branch), user, password) // Get changes description. val changesList = getCommits("id:$buildId", user, password) val changesInfo = "*Changes* in branch *$branch:*\n" + buildString { changesList.commits.forEach { append(" - Change ${it.revision} by ${it.developer} (details: ${it.webUrlWithDescription})\n") } } // File name on Artifactory is the same as current. val artifactoryFileName = currentBenchmarksReportFile.substringAfterLast("/") // Get compare to build. val compareToBuild = getBuild(previousBuildLocator(buildTypeId, defaultBranch), user, password) val compareToBuildLink = getBuildProperty(compareToBuild,"webUrl") val compareToBuildNumber = getBuildProperty(compareToBuild,"number") val target = System.getProperty("os.name").replace("\\s".toRegex(), "") // Generate comparison report. val output = arrayOf(analyzer, "-r", "html", currentBenchmarksReportFile, "artifactory:$compareToBuildNumber:$target:$artifactoryFileName", "-o", htmlReport) .runCommand() if (output.contains("Uncaught exception")) { error("Error during comparasion of $currentBenchmarksReportFile and " + "artifactory:$compareToBuildNumber:$target:$artifactoryFileName with $analyzer! " + "Please check files existance and their correctness.") } arrayOf("$analyzer", "-r", "statistics", "$currentBenchmarksReportFile", "artifactory:$compareToBuildNumber:$target:$artifactoryFileName", "-o", "$summaryFile") .runCommand() val reportLink = "https://kotlin-native-perf-summary.labs.jb.gg/?target=$target&build=$buildNumber" val detailedReportLink = "https://kotlin-native-performance.labs.jb.gg/?" + "report=artifactory:$buildNumber:$target:$artifactoryFileName&" + "compareTo=artifactory:$compareToBuildNumber:$target:$artifactoryFileName" val title = "\n*Performance report for target $target (build $buildNumber)* - $reportLink\n" + "*Detailed info - * $detailedReportLink" val header = "$title\n$changesInfo\n\nCompare to build $compareToBuildNumber: $compareToBuildLink\n\n" val footer = "*Benchmarks statistics:* $testReportUrl" val message = "$header\n$footer\n" // Send to channel or user directly. val session = SlackSessionFactory.createWebSocketSlackSession(buildProperties.getProperty("konan-reporter-token")) session.connect() if (branch == defaultBranch) { if (bundleBuild) { val channel = session.findChannelByName(buildProperties.getProperty("konan-channel-name")) session.sendMessage(channel, message) } } session.disconnect() } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/RegressionsSummaryReporter.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory import com.ullink.slack.simpleslackapi.SlackAttachment import com.ullink.slack.simpleslackapi.SlackPreparedMessage import java.io.FileInputStream import java.io.File import java.util.Properties /** * Task to produce regressions report and send it to slack. Requires a report with current benchmarks result * and path to analyzer tool * * @property targetsResultFiles map with pathes to results of each target */ open class RegressionsSummaryReporter : DefaultTask() { @Input lateinit var targetsResultFiles: Map val performanceServer = "https://kotlin-native-perf-summary.labs.jb.gg/" @TaskAction fun run() { // Get TeamCity properties. val teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") ?: error("Can't load teamcity config!") val buildProperties = Properties() buildProperties.load(FileInputStream(teamcityConfig)) val buildId = buildProperties.getProperty("teamcity.build.id") val buildTypeId = buildProperties.getProperty("teamcity.buildType.id") val buildNumber = buildProperties.getProperty("build.number") val results = mutableMapOf>() // Parse and merge results from all targets. targetsResultFiles.forEach { (key, value) -> val file = File(value) if (file.exists()) { file.forEachLine { val matchResult = "(\\w+)\\s*:\\s*(\\w+)".toRegex().find(it) val propertyName = matchResult?.groups?.get(1)?.value val propertyValue = matchResult?.groups?.get(2)?.value if (propertyName != null && propertyValue != null) { results[propertyName]?.let { it[key] = propertyValue } ?: run { results.put(propertyName, mutableMapOf(key to propertyValue)) } } } } } val message = buildString { append("*Performance summary on charts* - $performanceServer\n") results.forEach { (property, targets) -> append("$property: ${targets.map {(target, value) -> "$value ($target)"}.joinToString(" | ")}\n") } } val summaryStatus = results["status"]?.values?.fold("STABLE") {summary, element -> when { summary == "FAILED" || element == "FAILED" -> "FAILED" summary == "FIXED" || element == "FIXED" -> "FIXED" summary == "STABLE" -> element summary == element -> summary else -> "UNSTABLE" } } val attachement = SlackAttachment() with (attachement) { setTitle("Performance Summary (build $buildNumber)") setTitleLink("https://buildserver.labs.intellij.net/viewLog.html?buildId=$buildId&buildTypeId=$buildTypeId") setText(message) if (summaryStatus == "FIXED" || summaryStatus == "IMPROVED") { setColor("#36a64f") } else if (summaryStatus == "FAILED" || summaryStatus == "REGRESSED") { setColor("#ff0000") } } // Send to channel or user directly. val session = SlackSessionFactory.createWebSocketSlackSession(buildProperties.getProperty("konan-reporter-token")) session.connect() val channel = session.findChannelByName(buildProperties.getProperty("konan-channel-name")) val preparedMessage = SlackPreparedMessage.Builder() .addAttachment(attachement) .build() session.sendMessage(channel, preparedMessage) session.disconnect() } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/Reporter.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory import org.gradle.api.DefaultTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import java.io.FileInputStream import java.util.* internal object Tc { private val teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") val enabled:Boolean = (teamcityConfig != null) private val buildConfig by lazy { teamcityConfig ?: return@lazy null val properties = Properties() properties.load(FileInputStream(teamcityConfig)) properties } val buildId = buildConfig?.getProperty("teamcity.build.id") val buildTypeId = buildConfig?.getProperty("teamcity.buildType.id") val konanReporterToken = buildConfig?.getProperty("konan-reporter-token") val konanChannelName = buildConfig?.getProperty("konan-channel-name") } private fun buildLogUrlTab(buildId: String?, buildTypeId: String?): String = tabUrl(buildId, buildTypeId, "buildLog") private fun tabUrl(buildId: String?, buildTypeId: String?, tab: String?): String = "http://buildserver.labs.intellij.net/viewLog.html?buildId=$buildId&buildTypeId=$buildTypeId&tab=$tab" private fun testReportUrl(buildId: String?, buildTypeId: String?): String = tabUrl(buildId, buildTypeId, "testsInfo") private fun sendTextToSlack(report: String) { with(SlackSessionFactory.createWebSocketSlackSession(Tc.konanReporterToken)) { connect() sendMessage(findChannelByName(Tc.konanChannelName), "Hello, аборигены Котлина!\n текущий статус:\n$report") disconnect() } } private fun reportEpilogue(): String { val logUrl = buildLogUrlTab(Tc.buildId, Tc.buildTypeId) val testReportUrl = testReportUrl(Tc.buildId, Tc.buildTypeId) return "\nlog url: $logUrl\ntest report url: $testReportUrl" } private val Statistics.report get() = "total: $total\npassed: $passed\nfailed: $failed\nerror: $error\nskipped: $skipped" private val Statistics.oneLineReport get() = "(total: $total, passed: $passed, failed: $failed, error: $error, skipped: $skipped)" open class Reporter : DefaultTask() { @Input lateinit var reportHome: String @TaskAction fun report() { val reportJson = loadReport("$reportHome/external/results.json") val report: String = "${reportJson.statistics.report}\n ${reportEpilogue()}" project.logger.info(report) if (doSlackSending()) sendTextToSlack(report) } } private fun DefaultTask.doSlackSending() = !project.hasProperty("build.reporter.noSlack") || !project.property("build.reporter.noSlack").toString().toBoolean() open class NightlyReporter: DefaultTask() { @Input lateinit var externalMacosReport:String @Input lateinit var externalLinuxReport:String @Input lateinit var externalWindowsReport:String @TaskAction fun report() { val externalMacosJsonReport = loadReport("${project.rootDir.absolutePath}/$externalMacosReport") val externalLinuxJsonReport = loadReport("${project.rootDir.absolutePath}/$externalLinuxReport") val externalWindowsJsonReport = loadReport("${project.rootDir.absolutePath}/$externalWindowsReport") val report = buildString { append("Mac OS ") appendln(externalMacosJsonReport.statistics.oneLineReport) append("Linux ") appendln(externalLinuxJsonReport.statistics.oneLineReport) append("Windows ") appendln(externalWindowsJsonReport.statistics.oneLineReport) appendln(reportEpilogue()) } project.logger.info(report) if (doSlackSending()) sendTextToSlack(report) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/RunJvmTask.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option import org.gradle.api.tasks.Input import org.jetbrains.kotlin.benchmark.LogLevel import org.jetbrains.kotlin.benchmark.Logger import org.jetbrains.report.json.* import java.io.ByteArrayOutputStream import java.io.File data class ExecParameters(val warmupCount: Int, val repeatCount: Int, val filterArgs: List, val filterRegexArgs: List, val verbose: Boolean, val outputFileName: String?) open class RunJvmTask: JavaExec() { @Input @Option(option = "filter", description = "Benchmarks to run (comma-separated)") var filter: String = "" @Input @Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)") var filterRegex: String = "" @Input @Option(option = "verbose", description = "Verbose mode of running benchmarks") var verbose: Boolean = false @Input var warmupCount: Int = 0 @Input var repeatCount: Int = 0 @Input var repeatingType = BenchmarkRepeatingType.INTERNAL @Input var outputFileName: String? = null private var predefinedArgs: List = emptyList() private fun executeTask(execParameters: ExecParameters): String { // Firstly clean arguments. setArgs(emptyList()) args(predefinedArgs) args(execParameters.filterArgs) args(execParameters.filterRegexArgs) args("-w", execParameters.warmupCount) args("-r", execParameters.repeatCount) if (execParameters.verbose) { args("-v") } execParameters.outputFileName?.let { args("-o", outputFileName) } standardOutput = ByteArrayOutputStream() super.exec() return standardOutput.toString() } private fun getBenchmarksList(filterArgs: List, filterRegexArgs: List): List { // Firstly clean arguments. setArgs(emptyList()) args("list") standardOutput = ByteArrayOutputStream() super.exec() val benchmarks = standardOutput.toString().lines() val regexes = filterRegexArgs.map { it.toRegex() } return if (filterArgs.isNotEmpty() || regexes.isNotEmpty()) { benchmarks.filter { benchmark -> benchmark in filterArgs || regexes.any { it.matches(benchmark) } } } else benchmarks.filter { !it.isEmpty() } } private fun execSeparateBenchmarkRepeatedly(benchmark: String): List { // Logging with application should be done only in case it controls running benchmarks itself. // Although it's a responsibility of gradle task. val logger = if (verbose) Logger(LogLevel.DEBUG) else Logger() logger.log("Warm up iterations for benchmark $benchmark\n") for (i in 0.until(warmupCount)) { executeTask(ExecParameters(0, 1, listOf("-f", benchmark), emptyList(), false, null)) } val result = mutableListOf() logger.log("Running benchmark $benchmark ") for (i in 0.until(repeatCount)) { logger.log(".", usePrefix = false) val benchmarkReport = JsonTreeParser.parse( executeTask(ExecParameters(0, 1, listOf("-f", benchmark), emptyList(), false, null) ).removePrefix("[").removeSuffix("]") ).jsonObject val modifiedBenchmarkReport = JsonObject(HashMap(benchmarkReport.content).apply { put("repeat", JsonLiteral(i)) put("warmup", JsonLiteral(warmupCount)) }) result.add(modifiedBenchmarkReport.toString()) } logger.log("\n", usePrefix = false) return result } private fun execBenchmarksRepeatedly(filterArgs: List, filterRegexArgs: List) { val benchmarksToRun = getBenchmarksList(filterArgs, filterRegexArgs) val results = benchmarksToRun.flatMap { benchmark -> execSeparateBenchmarkRepeatedly(benchmark) } File(outputFileName).printWriter().use { out -> out.println("[${results.joinToString(",")}]") } } @TaskAction override fun exec() { assert(outputFileName != null) { "Output file name should be always set" } predefinedArgs = args ?: emptyList() val filterArgs = filter.splitCommaSeparatedOption("-f") val filterRegexArgs = filterRegex.splitCommaSeparatedOption("-fr") when (repeatingType) { BenchmarkRepeatingType.INTERNAL -> executeTask( ExecParameters(warmupCount, repeatCount, filterArgs, filterRegexArgs, verbose, outputFileName) ) BenchmarkRepeatingType.EXTERNAL -> execBenchmarksRepeatedly(filterArgs, filterRegexArgs) } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/RunKotlinNativeTask.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin import org.gradle.api.DefaultTask import org.gradle.api.Task import org.jetbrains.kotlin.benchmark.Logger import org.jetbrains.kotlin.benchmark.LogLevel import org.jetbrains.report.json.* import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option import org.gradle.api.tasks.Input import java.io.ByteArrayOutputStream import java.io.File import javax.inject.Inject import kotlin.collections.HashMap open class RunKotlinNativeTask @Inject constructor(private val linkTask: Task, private val executable: String, private val outputFileName: String ) : DefaultTask() { @Input @Option(option = "filter", description = "Benchmarks to run (comma-separated)") var filter: String = "" @Input @Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)") var filterRegex: String = "" @Input @Option(option = "verbose", description = "Verbose mode of running benchmarks") var verbose: Boolean = false @Input var warmupCount: Int = 0 @Input var repeatCount: Int = 0 @Input var repeatingType = BenchmarkRepeatingType.INTERNAL private val argumentsList = mutableListOf() init { this.dependsOn += linkTask.name this.finalizedBy("konanJsonReport") } fun depends(taskName: String) { this.dependsOn += taskName } fun args(vararg arguments: String) { argumentsList.addAll(arguments.toList()) } private fun execBenchmarkOnce(benchmark: String, warmupCount: Int, repeatCount: Int) : String { val output = ByteArrayOutputStream() val useCset = project.findProperty("useCset")?.toString()?.toBoolean() ?: false project.exec { if (useCset) { it.executable = "cset" it.args("shield", "--exec", "--", executable) } else { it.executable = executable } it.args(argumentsList) it.args("-f", benchmark) // Logging with application should be done only in case it controls running benchmarks itself. // Although it's a responsibility of gradle task. if (verbose && repeatingType == BenchmarkRepeatingType.INTERNAL) { it.args("-v") } it.args("-w", warmupCount.toString()) it.args("-r", repeatCount.toString()) it.standardOutput = output } return output.toString().substringAfter("[").removeSuffix("]") } private fun execBenchmarkRepeatedly(benchmark: String, warmupCount: Int, repeatCount: Int) : List { val logger = if (verbose) Logger(LogLevel.DEBUG) else Logger() logger.log("Warm up iterations for benchmark $benchmark\n") for (i in 0.until(warmupCount)) { execBenchmarkOnce(benchmark, 0, 1) } val result = mutableListOf() logger.log("Running benchmark $benchmark ") for (i in 0.until(repeatCount)) { logger.log(".", usePrefix = false) val benchmarkReport = JsonTreeParser.parse(execBenchmarkOnce(benchmark, 0, 1)).jsonObject val modifiedBenchmarkReport = JsonObject(HashMap(benchmarkReport.content).apply { put("repeat", JsonLiteral(i)) put("warmup", JsonLiteral(warmupCount)) }) result.add(modifiedBenchmarkReport.toString()) } logger.log("\n", usePrefix = false) return result } @TaskAction fun run() { val output = ByteArrayOutputStream() project.exec { it.executable = executable it.args("list") it.standardOutput = output } val benchmarks = output.toString().lines() val filterArgs = filter.splitCommaSeparatedOption("-f") val filterRegexArgs = filterRegex.splitCommaSeparatedOption("-fr") val regexes = filterRegexArgs.map { it.toRegex() } val benchmarksToRun = if (filterArgs.isNotEmpty() || regexes.isNotEmpty()) { benchmarks.filter { benchmark -> benchmark in filterArgs || regexes.any { it.matches(benchmark) } } } else benchmarks.filter { !it.isEmpty() } val results = benchmarksToRun.flatMap { benchmark -> when (repeatingType) { BenchmarkRepeatingType.INTERNAL -> listOf(execBenchmarkOnce(benchmark, warmupCount, repeatCount)) BenchmarkRepeatingType.EXTERNAL -> execBenchmarkRepeatedly(benchmark, warmupCount, repeatCount) } } File(outputFileName).printWriter().use { out -> out.println("[${results.joinToString(",")}]") } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/TestDirectives.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import org.jetbrains.kotlin.TestModule.Companion.default import org.jetbrains.kotlin.TestModule.Companion.support import java.nio.file.Path import java.nio.file.Paths import java.util.regex.Matcher import java.util.regex.Pattern private const val MODULE_DELIMITER = ",\\s*" // These patterns are copies from // kotlin/compiler/tests-common/tests/org/jetbrains/kotlin/test/TestFiles.java // kotlin/compiler/tests-common/tests/org/jetbrains/kotlin/test/KotlinTestUtils.java private val FILE_OR_MODULE_PATTERN: Pattern = Pattern.compile("(?://\\s*MODULE:\\s*([^()\\n]+)(?:\\(([^()]+(?:" + "$MODULE_DELIMITER[^()]+)*)\\))?\\s*(?:\\(([^()]+(?:$MODULE_DELIMITER[^()]+)*)\\))?\\s*)?//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE) private val DIRECTIVE_PATTERN = Pattern.compile("^//\\s*[!]?([A-Z_]+)(:[ \\t]*(.*))?$", Pattern.MULTILINE) /** * Creates test files from the given source file that may contain different test directives. * * @return list of test files [TestFile] to be compiled */ fun buildCompileList(source: Path, outputDirectory: String): List { val result = mutableListOf() val srcFile = source.toFile() // Remove diagnostic parameters in external tests. val srcText = srcFile.readText().replace(Regex("(.*?)")) { match -> match.groupValues[1] } if (srcText.contains("// WITH_COROUTINES")) { result.add(TestFile("helpers.kt", "$outputDirectory/helpers.kt", createTextForHelpers(true), TestModule.support)) } val matcher = FILE_OR_MODULE_PATTERN.matcher(srcText) if (!matcher.find()) { // There is only one file in the input result.add(TestFile(srcFile.name, "$outputDirectory/${srcFile.name}", srcText)) } else { // There are several files var processedChars = 0 var module: TestModule = TestModule.default var nextFileExists = true while (nextFileExists) { var moduleName = matcher.group(1) val moduleDependencies = matcher.group(2) val moduleFriends = matcher.group(3) if (moduleName != null) { moduleName = moduleName.trim { it <= ' ' } module = TestModule("${srcFile.name}.$moduleName", moduleDependencies.parseModuleList().map { if (it != "support") "${srcFile.name}.$it" else it }, moduleFriends.parseModuleList().map { "${srcFile.name}.$it" }) } val fileName = matcher.group(4) val filePath = "$outputDirectory/$fileName" val start = processedChars nextFileExists = matcher.find() val end = if (nextFileExists) matcher.start() else srcText.length val fileText = srcText.substring(start, end) processedChars = end if (fileName.endsWith(".kt")) { result.add(TestFile(fileName, filePath, fileText, module)) } } } return result } private fun String?.parseModuleList() = this ?.split(Pattern.compile(MODULE_DELIMITER), 0) ?: emptyList() /** * Test module from the test source declared by the [FILE_OR_MODULE_PATTERN]. * Module should have a [name] and could have [dependencies] on other modules and [friends]. * * There are 2 predefined modules: * - [default] that contains all sources that don't declare a module, * - [support] for a helper sources like Coroutines support. */ data class TestModule( val name: String, val dependencies: List, val friends: List ) { val files = mutableListOf() fun isDefaultModule() = this == default || name.endsWith(".main") val hasVersions get() = this.files.any { it.version != null } fun versionFiles(version: Int) = this.files.filter { it.version == null || it.version == version } companion object { val default = TestModule("default", emptyList(), emptyList()) val support = TestModule("support", emptyList(), emptyList()) } } /** * Represent a single test file that belongs to the [module]. */ data class TestFile( val name: String, val path: String, var text: String = "", val module: TestModule = TestModule.default ) { init { this.module.files.add(this) } val directives: Map by lazy { parseDirectives() } val version: Int? get() = this.directives["VERSION"]?.toInt() fun parseDirectives(): Map { val newDirectives = mutableMapOf() val directiveMatcher: Matcher = DIRECTIVE_PATTERN.matcher(text) while (directiveMatcher.find()) { val name = directiveMatcher.group(1) val value = directiveMatcher.group(3) newDirectives.put(name, value) } return newDirectives } /** * Writes [text] to the file created from the [path]. */ fun writeTextToFile() { Paths.get(path).takeUnless { text.isEmpty() }?.run { parent.toFile() .takeUnless { it.exists() } ?.mkdirs() toFile().writeText(text) } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/Utils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin import org.gradle.api.Project import org.gradle.api.Task import org.jetbrains.kotlin.konan.properties.loadProperties import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.konan.properties.saveProperties import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.library.KLIB_PROPERTY_NATIVE_TARGETS import java.io.File import java.util.concurrent.TimeUnit import java.net.HttpURLConnection import java.net.URL import java.util.Base64 import org.jetbrains.report.json.* import java.nio.file.Path import org.jetbrains.kotlin.konan.file.File as KFile //region Project properties. val Project.platformManager get() = findProperty("platformManager") as PlatformManager val Project.testTarget get() = findProperty("target") as KonanTarget val Project.verboseTest get() = hasProperty("test_verbose") val Project.testOutputRoot get() = findProperty("testOutputRoot") as String val Project.testOutputLocal get() = (findProperty("testOutputLocal") as File).toString() val Project.testOutputStdlib get() = (findProperty("testOutputStdlib") as File).toString() val Project.testOutputFramework get() = (findProperty("testOutputFramework") as File).toString() val Project.testOutputExternal get() = (findProperty("testOutputExternal") as File).toString() val Project.kotlinNativeDist get() = this.rootProject.file(this.findProperty("org.jetbrains.kotlin.native.home") ?: this.findProperty("konan.home") ?: "dist") @Suppress("UNCHECKED_CAST") val Project.globalTestArgs: List get() = with(findProperty("globalTestArgs")) { if (this is Array<*>) this.toList() as List else this as List } val Project.testTargetSupportsCodeCoverage: Boolean get() = this.testTarget.supportsCodeCoverage() //endregion /** * Ad-hoc signing of the specified path. */ fun codesign(project: Project, path: String) { check(HostManager.hostIsMac) { "Apple specific code signing" } val (stdOut, stdErr, exitCode) = runProcess(executor = localExecutor(project), executable = "/usr/bin/codesign", args = listOf("--verbose", "-s", "-", path)) check(exitCode == 0) { """ |Codesign failed with exitCode: $exitCode |stdout: $stdOut |stderr: $stdErr """.trimMargin() } } /** * Creates a list of file paths to be compiled from the given [compile] list with regard to [exclude] list. */ fun Project.getFilesToCompile(compile: List, exclude: List): List { // convert exclude list to paths val excludeFiles = exclude.map { project.file(it).absolutePath }.toList() // create list of tests to compile return compile.flatMap { f -> project.file(f) .walk() .filter { it.isFile && it.name.endsWith(".kt") && !excludeFiles.contains(it.absolutePath) } .map{ it.absolutePath } .asIterable() } } //region Task dependency. fun Project.findKonanBuildTask(artifact: String, target: KonanTarget): Task = tasks.getByName("compileKonan${artifact.capitalize()}${target.name.capitalize()}") fun Project.dependsOnDist(taskName: String) { project.tasks.getByName(taskName).dependsOnDist() } fun Task.dependsOnDist() { val rootTasks = project.rootProject.tasks // We don't build the compiler if a custom dist path is specified. if (!(project.findProperty("useCustomDist") as Boolean)) { dependsOn(rootTasks.getByName("dist")) val target = project.testTarget if (target != HostManager.host) { // if a test_target property is set then tests should depend on a crossDist // otherwise, runtime components would not be build for a target. dependsOn(rootTasks.getByName("${target.name}CrossDist")) } } } /** * Sets the same dependencies for the receiver task from the given [task] */ fun String.sameDependenciesAs(task: Task) { val t = task.project.tasks.getByName(this) t.sameDependenciesAs(task) } /** * Sets the same dependencies for the receiver task from the given [task] */ fun Task.sameDependenciesAs(task: Task) { val dependencies = task.dependsOn.toList() // save to the list, otherwise it will cause cyclic dependency. this.dependsOn(dependencies) } /** * Set dependency on [artifact] built by the Konan Plugin for the receiver task, * also make [artifact] depend on `dist` and all dependencies of the task to make [artifact] execute before the task. */ fun Task.dependsOnKonanBuildingTask(artifact: String, target: KonanTarget) { val buildTask = project.findKonanBuildTask(artifact, target) buildTask.dependsOnDist() buildTask.sameDependenciesAs(this) dependsOn(buildTask) } //endregion // Run command line from string. fun Array.runCommand(workingDir: File = File("."), timeoutAmount: Long = 60, timeoutUnit: TimeUnit = TimeUnit.SECONDS): String { return try { ProcessBuilder(*this) .directory(workingDir) .redirectOutput(ProcessBuilder.Redirect.PIPE) .redirectError(ProcessBuilder.Redirect.PIPE) .start().apply { waitFor(timeoutAmount, timeoutUnit) }.inputStream.bufferedReader().readText() } catch (e: Exception) { println("Couldn't run command ${this.joinToString(" ")}") println(e.stackTrace.joinToString("\n")) error(e.message!!) } } fun String.splitCommaSeparatedOption(optionName: String) = split("\\s*,\\s*".toRegex()).map { if (it.isNotEmpty()) listOf(optionName, it) else listOf(null) }.flatten().filterNotNull() data class Commit(val revision: String, val developer: String, val webUrlWithDescription: String) val teamCityUrl = "http://buildserver.labs.intellij.net" // List of commits. class CommitsList(data: JsonElement): ConvertedFromJson { val commits: List init { if (data !is JsonObject) { error("Commits description is expected to be a json object!") } val changesElement = data.getOptionalField("change") commits = changesElement?.let { if (changesElement !is JsonArray) { error("Change field is expected to be an array. Please, check source.") } changesElement.jsonArray.map { with(it as JsonObject) { Commit(elementToString(getRequiredField("version"), "version"), elementToString(getRequiredField("username"), "username"), elementToString(getRequiredField("webUrl"), "webUrl") ) } } } ?: listOf() } } fun buildsUrl(buildLocator: String) = "$teamCityUrl/app/rest/builds/?locator=$buildLocator" fun getBuild(buildLocator: String, user: String, password: String) = try { sendGetRequest(buildsUrl(buildLocator), user, password) } catch (t: Throwable) { error("Try to get build! TeamCity is unreachable!") } fun sendGetRequest(url: String, username: String? = null, password: String? = null) : String { val connection = URL(url).openConnection() as HttpURLConnection if (username != null && password != null) { val auth = Base64.getEncoder().encode(("$username:$password").toByteArray()).toString(Charsets.UTF_8) connection.addRequestProperty("Authorization", "Basic $auth") } connection.setRequestProperty("Accept", "application/json"); connection.connect() return connection.inputStream.use { it.reader().use { reader -> reader.readText() } } } fun getBuildProperty(buildJsonDescription: String, property: String) = with(JsonTreeParser.parse(buildJsonDescription) as JsonObject) { if (getPrimitive("count").int == 0) { error("No build information on TeamCity for $buildJsonDescription!") } (getArray("build").getObject(0).getPrimitive(property) as JsonLiteral).unquoted() } @JvmOverloads fun compileSwift(project: Project, target: KonanTarget, sources: List, options: List, output: Path, fullBitcode: Boolean = false) { val platform = project.platformManager.platform(target) assert(platform.configurables is AppleConfigurables) val configs = platform.configurables as AppleConfigurables val compiler = configs.absoluteTargetToolchain + "/usr/bin/swiftc" val swiftTarget = when (target) { KonanTarget.IOS_X64 -> "x86_64-apple-ios" + configs.osVersionMin KonanTarget.IOS_ARM32 -> "armv7-apple-ios" + configs.osVersionMin KonanTarget.IOS_ARM64 -> "arm64-apple-ios" + configs.osVersionMin KonanTarget.TVOS_X64 -> "x86_64-apple-tvos" + configs.osVersionMin KonanTarget.TVOS_ARM64 -> "arm64-apple-tvos" + configs.osVersionMin KonanTarget.MACOS_X64 -> "x86_64-apple-macosx" + configs.osVersionMin KonanTarget.MACOS_ARM64 -> "arm64-apple-macos" + configs.osVersionMin KonanTarget.WATCHOS_X86 -> "i386-apple-watchos" + configs.osVersionMin KonanTarget.WATCHOS_X64 -> "x86_64-apple-watchos" + configs.osVersionMin else -> throw IllegalStateException("Test target $target is not supported") } val args = listOf("-sdk", configs.absoluteTargetSysRoot, "-target", swiftTarget) + options + "-o" + output.toString() + sources + if (fullBitcode) listOf("-embed-bitcode", "-Xlinker", "-bitcode_verify") else listOf("-embed-bitcode-marker") val (stdOut, stdErr, exitCode) = runProcess(executor = localExecutor(project), executable = compiler, args = args) println(""" |$compiler finished with exit code: $exitCode |options: ${args.joinToString(separator = " ")} |stdout: $stdOut |stderr: $stdErr """.trimMargin()) check(exitCode == 0) { "Compilation failed" } check(output.toFile().exists()) { "Compiler swiftc hasn't produced an output file: $output" } } fun targetSupportsMimallocAllocator(targetName: String) = HostManager().targetByName(targetName).supportsMimallocAllocator() fun Project.mergeManifestsByTargets(source: File, destination: File) { logger.info("Merging manifests: $source -> $destination") val sourceFile = KFile(source.absolutePath) val sourceProperties = sourceFile.loadProperties() val destinationFile = KFile(destination.absolutePath) val destinationProperties = destinationFile.loadProperties() // check that all properties except for KLIB_PROPERTY_NATIVE_TARGETS are equivalent val mismatchedProperties = (sourceProperties.keys + destinationProperties.keys) .asSequence() .map { it.toString() } .filter { it != KLIB_PROPERTY_NATIVE_TARGETS } .sorted() .mapNotNull { propertyKey: String -> val sourceProperty: String? = sourceProperties.getProperty(propertyKey) val destinationProperty: String? = destinationProperties.getProperty(propertyKey) when { sourceProperty == null -> "\"$propertyKey\" is absent in $sourceFile" destinationProperty == null -> "\"$propertyKey\" is absent in $destinationFile" sourceProperty == destinationProperty -> { // properties match, OK null } sourceProperties.propertyList(propertyKey, escapeInQuotes = true).toSet() == destinationProperties.propertyList(propertyKey, escapeInQuotes = true).toSet() -> { // properties match, OK null } else -> "\"$propertyKey\" differ: [$sourceProperty] vs [$destinationProperty]" } } .toList() check(mismatchedProperties.isEmpty()) { buildString { appendln("Found mismatched properties while merging manifest files: $source -> $destination") mismatchedProperties.joinTo(this, "\n") } } // merge KLIB_PROPERTY_NATIVE_TARGETS property val sourceNativeTargets = sourceProperties.propertyList(KLIB_PROPERTY_NATIVE_TARGETS) val destinationNativeTargets = destinationProperties.propertyList(KLIB_PROPERTY_NATIVE_TARGETS) val mergedNativeTargets = HashSet().apply { addAll(sourceNativeTargets) addAll(destinationNativeTargets) } destinationProperties[KLIB_PROPERTY_NATIVE_TARGETS] = mergedNativeTargets.joinToString(" ") destinationFile.saveProperties(destinationProperties) } fun Project.buildStaticLibrary(cSources: Collection, output: File, objDir: File) { delete(objDir) delete(output) val platform = platformManager.platform(testTarget) objDir.mkdirs() exec { it.commandLine(platform.clang.clangC( "-c", *cSources.map { it.absolutePath }.toTypedArray() )) it.workingDir(objDir) } output.parentFile.mkdirs() exec { it.commandLine( "${platform.configurables.absoluteLlvmHome}/bin/llvm-ar", "-rc", output, *fileTree(objDir).files.toTypedArray() ) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/Wrappers.kt ================================================ package org.jetbrains.kotlin import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.wrapper.Wrapper open class CustomWrapper : Wrapper() { internal lateinit var mainWrapperTask: Wrapper val mainWrapperVersion: String @Input get() = mainWrapperTask.gradleVersion val mainWrapperDistrSha256: String? @Optional @Input get() = mainWrapperTask.distributionSha256Sum } open class WrappersExtension { var projects = mutableListOf() var distributionType = Wrapper.DistributionType.BIN } class GradleWrappers : Plugin { override fun apply(project: Project): Unit = with(project) { val mainWrapperTask = tasks.findByName("wrapper") as? Wrapper ?: return@with val wrappers = extensions.create( WrappersExtension::class.java, "wrappers", WrappersExtension::class.java ) afterEvaluate { wrappers.projects.map { file(it) }.forEach { tasks.create("${it.name}Wrapper", CustomWrapper::class.java).apply { this.mainWrapperTask = mainWrapperTask jarFile = it.resolve("gradle/wrapper/gradle-wrapper.jar") scriptFile = it.resolve("gradlew") distributionType = wrappers.distributionType mainWrapperTask.dependsOn(this) // Get these parameters from the main wrapper task to support // command line options like --gradle-version. // Gradle doesn't provide access to the values passed in command line // at the configuration phase, so we have to get these values at the execution phase. doFirst { gradleVersion = mainWrapperVersion distributionSha256Sum = mainWrapperDistrSha256 } } } } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/XcRunRuntimeUtils.kt ================================================ package org.jetbrains.kotlin import com.google.gson.annotations.Expose import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.Xcode import kotlin.math.min /** * Compares two strings assuming that both are representing numeric version strings. * Examples of numeric version strings: "12.4.1.2", "9", "0.5". */ private fun compareStringsAsVersions(version1: String, version2: String): Int { val splitVersion1 = version1.split('.').map { it.toInt() } val splitVersion2 = version2.split('.').map { it.toInt() } val minimalLength = min(splitVersion1.size, splitVersion2.size) for (index in 0 until minimalLength) { if (splitVersion1[index] < splitVersion2[index]) return -1 if (splitVersion1[index] > splitVersion2[index]) return 1 } return splitVersion1.size.compareTo(splitVersion2.size) } /** * Returns parsed output of `xcrun simctl list runtimes -j`. */ private fun Xcode.getSimulatorRuntimeDescriptors(): List = gson.fromJson(simulatorRuntimes, ListRuntimesReport::class.java).runtimes /** * Returns first available simulator runtime for [target] with at least [osMinVersion] OS version. * */ fun Xcode.getLatestSimulatorRuntimeFor(target: KonanTarget, osMinVersion: String): SimulatorRuntimeDescriptor? { val osName = when (target) { KonanTarget.IOS_X64 -> "iOS" KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_X86 -> "watchOS" KonanTarget.TVOS_X64 -> "tvOS" else -> error("Unexpected simulator target: $target") } return getSimulatorRuntimeDescriptors().firstOrNull { it.checkAvailability() && it.name.startsWith(osName) && compareStringsAsVersions(it.version, osMinVersion) >= 0 } } // Result of `xcrun simctl list runtimes -j`. data class ListRuntimesReport( @Expose val runtimes: List ) data class SimulatorRuntimeDescriptor( @Expose val version: String, // bundlePath field may not exist in the old Xcode (prior to 10.3). @Expose val bundlePath: String? = null, @Expose val isAvailable: Boolean? = null, @Expose val availability: String? = null, @Expose val name: String, @Expose val identifier: String, @Expose val buildversion: String ) { /** * Different Xcode/macOS combinations give different fields that checks * runtime availability. This method is an umbrella for these fields. */ fun checkAvailability(): Boolean { if (isAvailable == true) return true if (availability?.contains("unavailable") == true) return false return false } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkLogger.kt ================================================ package org.jetbrains.kotlin.benchmark import java.text.SimpleDateFormat import java.util.* enum class LogLevel { DEBUG, OFF } class Logger(val level: LogLevel = LogLevel.OFF) { private fun printStderr(message: String) { System.err.print(message) } private fun currentTime(): String = SimpleDateFormat("HH:mm:ss").format(Date()) fun log(message: String, messageLevel: LogLevel = LogLevel.DEBUG, usePrefix: Boolean = true) { if (messageLevel == level) { if (usePrefix) { printStderr("[$level][${currentTime()}] $message") } else { printStderr("$message") } } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/benchmark/BenchmarkingPlugin.kt ================================================ package org.jetbrains.kotlin.benchmark import groovy.lang.Closure import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.artifacts.Dependency import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.* import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.konan.target.HostManager import javax.inject.Inject import kotlin.reflect.KClass internal val NamedDomainObjectContainer.commonMain get() = maybeCreate("commonMain") internal val NamedDomainObjectContainer.nativeMain get() = maybeCreate("nativeMain") internal val Project.nativeWarmup: Int get() = (property("nativeWarmup") as String).toInt() internal val Project.attempts: Int get() = (property("attempts") as String).toInt() internal val Project.nativeBenchResults: String get() = property("nativeBenchResults") as String // Gradle property to add flags to benchmarks run from command line. internal val Project.compilerArgs: List get() = (findProperty("compilerArgs") as String?)?.split("\\s").orEmpty() internal val Project.kotlinVersion: String get() = property("kotlinVersion") as String internal val Project.konanVersion: String get() = property("konanVersion") as String internal val Project.kotlinStdlibVersion: String get() = property("kotlinStdlibVersion") as String internal val Project.kotlinStdlibRepo: String get() = property("kotlinStdlibRepo") as String internal val Project.nativeJson: String get() = project.property("nativeJson") as String internal val Project.jvmJson: String get() = project.property("jvmJson") as String internal val Project.commonBenchmarkProperties: Map get() = mapOf( "cpu" to System.getProperty("os.arch"), "os" to System.getProperty("os.name"), "jdkVersion" to System.getProperty("java.version"), "jdkVendor" to System.getProperty("java.vendor"), "kotlinVersion" to kotlinVersion ) open class BenchmarkExtension @Inject constructor(val project: Project) { var applicationName: String = project.name var commonSrcDirs: Collection = emptyList() var nativeSrcDirs: Collection = emptyList() var compileTasks: List = emptyList() var linkerOpts: Collection = emptyList() var compilerOpts: List = emptyList() var buildType: NativeBuildType = NativeBuildType.RELEASE var repeatingType: BenchmarkRepeatingType = BenchmarkRepeatingType.INTERNAL var cleanBeforeRunTask: String? = "konanRun" val dependencies: BenchmarkDependencies = BenchmarkDependencies() fun dependencies(action: BenchmarkDependencies.() -> Unit) = dependencies.action() fun dependencies(action: Closure<*>) { ConfigureUtil.configure(action, dependencies) } inner class BenchmarkDependencies { public val sourceSets: NamedDomainObjectContainer get() = project.kotlin.sourceSets fun project(path: String): Dependency = project.dependencies.project(mapOf("path" to path)) fun project(path: String, configuration: String): Dependency = project.dependencies.project(mapOf("path" to path, "configuration" to configuration)) fun common(notation: Any) = sourceSets.commonMain.dependencies { implementation(notation) } fun native(notation: Any) = sourceSets.nativeMain.dependencies { implementation(notation) } } } /** * A plugin configuring a benchmark Kotlin/Native project. */ abstract class BenchmarkingPlugin: Plugin { protected abstract val Project.nativeExecutable: String protected abstract val Project.nativeLinkTask: Task protected abstract val Project.benchmark: BenchmarkExtension protected abstract val benchmarkExtensionName: String protected abstract val benchmarkExtensionClass: KClass<*> protected val mingwPath: String = System.getenv("MINGW64_DIR") ?: "c:/msys64/mingw64" protected open fun Project.determinePreset(): AbstractKotlinNativeTargetPreset<*> = defaultHostPreset(this).also { preset -> logger.quiet("$project has been configured for ${preset.name} platform.") } as AbstractKotlinNativeTargetPreset<*> protected abstract fun NamedDomainObjectContainer.configureSources(project: Project) protected open fun NamedDomainObjectContainer.additionalConfigurations(project: Project) {} protected open fun Project.configureSourceSets(kotlinVersion: String) { with(kotlin.sourceSets) { commonMain.dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinStdlibVersion") } project.configurations.getByName(nativeMain.implementationConfigurationName).apply { // Exclude dependencies already included into K/N distribution (aka endorsed libraries). exclude(mapOf("module" to "kotlinx.cli")) } repositories.maven { it.setUrl(kotlinStdlibRepo) } additionalConfigurations(this@configureSourceSets) // Add sources specified by a user in the benchmark DSL. afterEvaluate { configureSources(project) } } } protected open fun KotlinNativeTarget.configureNativeOutput(project: Project) { binaries.executable(NATIVE_EXECUTABLE_NAME, listOf(project.benchmark.buildType)) { if (HostManager.hostIsMingw) { linkerOpts.add("-L${mingwPath}/lib") } runTask!!.apply { group = "" enabled = false } // Specify settings configured by a user in the benchmark extension. project.afterEvaluate { linkerOpts.addAll(project.benchmark.linkerOpts) freeCompilerArgs = project.benchmark.compilerOpts + project.compilerArgs } } } protected fun Project.configureNativeTarget(hostPreset: AbstractKotlinNativeTargetPreset<*>) { kotlin.targetFromPreset(hostPreset, NATIVE_TARGET_NAME) { compilations.getByName("main").kotlinOptions.freeCompilerArgs = benchmark.compilerOpts + project.compilerArgs compilations.getByName("main").enableEndorsedLibs = true configureNativeOutput(this@configureNativeTarget) } } protected open fun configureMPPExtension(project: Project) { project.configureSourceSets(project.kotlinVersion) project.configureNativeTarget(project.determinePreset()) } protected open fun Project.configureNativeTask(nativeTarget: KotlinNativeTarget): Task { val konanRun = createRunTask(this, "konanRun", nativeLinkTask, nativeExecutable, buildDir.resolve(nativeBenchResults).absolutePath).apply { group = BENCHMARKING_GROUP description = "Runs the benchmark for Kotlin/Native." } afterEvaluate { val task = konanRun as RunKotlinNativeTask task.args("-p", "${benchmark.applicationName}::") task.warmupCount = nativeWarmup task.repeatCount = attempts task.repeatingType = benchmark.repeatingType } return konanRun } protected abstract fun Project.configureJvmTask(): Task protected fun compilerFlagsFromBinary(project: Project): List { val result = mutableListOf() if (project.benchmark.buildType.optimized) { result.add("-opt") } if (project.benchmark.buildType.debuggable) { result.add("-g") } return result } protected open fun getCompilerFlags(project: Project, nativeTarget: KotlinNativeTarget) = compilerFlagsFromBinary(project) + nativeTarget.compilations.main.kotlinOptions.freeCompilerArgs.map { "\"$it\"" } protected open fun Project.collectCodeSize(applicationName: String) = getCodeSizeBenchmark(applicationName, nativeExecutable) protected open fun Project.configureKonanJsonTask(nativeTarget: KotlinNativeTarget): Task { return tasks.create("konanJsonReport") { it.group = BENCHMARKING_GROUP it.description = "Builds the benchmarking report for Kotlin/Native." it.doLast { val applicationName = benchmark.applicationName val benchContents = buildDir.resolve(nativeBenchResults).readText() val nativeCompileTime = if (benchmark.compileTasks.isEmpty()) getNativeCompileTime(project, applicationName) else getNativeCompileTime(project, applicationName, benchmark.compileTasks) val properties = commonBenchmarkProperties + mapOf( "type" to "native", "compilerVersion" to konanVersion, "flags" to getCompilerFlags(project, nativeTarget).sorted(), "benchmarks" to benchContents, "compileTime" to listOf(nativeCompileTime), "codeSize" to collectCodeSize(applicationName) ) val output = createJsonReport(properties) buildDir.resolve(nativeJson).writeText(output) } } } protected abstract fun Project.configureJvmJsonTask(jvmRun: Task): Task protected open fun Project.configureExtraTasks() {} private fun Project.configureTasks() { val nativeTarget = kotlin.targets.getByName(NATIVE_TARGET_NAME) as KotlinNativeTarget configureExtraTasks() // Native run task. configureNativeTask(nativeTarget) // JVM run task. val jvmRun = configureJvmTask() // Native report task. configureKonanJsonTask(nativeTarget) // JVM report task. configureJvmJsonTask(jvmRun) project.afterEvaluate { // Need to rebuild benchmark to collect compile time. project.benchmark.cleanBeforeRunTask?.let { tasks.getByName(it).dependsOn("clean") } } } override fun apply(target: Project) = with(target) { pluginManager.apply("kotlin-multiplatform") // Use Kotlin compiler version specified by the project property. dependencies.add("kotlinCompilerClasspath", "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlinVersion") addTimeListener(this) extensions.create(benchmarkExtensionName, benchmarkExtensionClass.java, this) configureMPPExtension(this) configureTasks() } companion object { const val NATIVE_TARGET_NAME = "native" const val NATIVE_EXECUTABLE_NAME = "benchmark" const val BENCHMARKING_GROUP = "benchmarking" } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/benchmark/CompileBenchmarkingPlugin.kt ================================================ package org.jetbrains.kotlin.benchmark import groovy.lang.Closure import org.gradle.api.* import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Exec import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.* import javax.inject.Inject class BuildStep (private val _name: String): Named { override fun getName(): String = _name lateinit var command: List fun command(vararg command: String) { this.command = command.toList() } } class BuildStepContainer(project: Project): NamedDomainObjectContainer by project.container(BuildStep::class.java) { fun step(name: String, configure: Action) = maybeCreate(name).apply { configure.execute(this) } fun step(name: String, configure: Closure) = step(name, ConfigureUtil.configureUsing(configure)) } open class CompileBenchmarkExtension @Inject constructor(val project: Project) { var applicationName = project.name var repeatNumber: Int = 1 var buildSteps: BuildStepContainer = BuildStepContainer(project) var compilerOpts: List = emptyList() fun buildSteps(configure: Action): Unit = buildSteps.let { configure.execute(it) } fun buildSteps(configure: Closure): Unit = buildSteps(ConfigureUtil.configureUsing(configure)) } open class CompileBenchmarkingPlugin : Plugin { private val exitCodes: MutableMap = mutableMapOf() private fun Project.configureUtilityTasks() { tasks.create("configureBuild") { it.doLast { mkdir(buildDir) } } tasks.create("clean", Delete::class.java) { it.delete(buildDir) } } private fun Project.configureKonanRun( benchmarkExtension: CompileBenchmarkExtension ): Unit = with(benchmarkExtension) { // Aggregate task. val konanRun = tasks.create("konanRun") { task -> task.dependsOn("configureBuild") task.group = BenchmarkingPlugin.BENCHMARKING_GROUP task.description = "Runs the compile only benchmark for Kotlin/Native." } // Compile tasks. afterEvaluate { for (number in 1..repeatNumber) { buildSteps.forEach { step -> val taskName = step.name tasks.create("$taskName$number", Exec::class.java).apply { commandLine(step.command) isIgnoreExitValue = true konanRun.dependsOn(this) doLast { exitCodes[name] = execResult!!.exitValue } } } } } // Report task. tasks.create("konanJsonReport").apply { group = BenchmarkingPlugin.BENCHMARKING_GROUP description = "Builds the benchmarking report for Kotlin/Native." doLast { val nativeCompileTime = getCompileBenchmarkTime( project, applicationName, buildSteps.names, repeatNumber, exitCodes ) val nativeExecutable = buildDir.resolve("program${getNativeProgramExtension()}") val properties = commonBenchmarkProperties + mapOf( "type" to "native", "compilerVersion" to konanVersion, "benchmarks" to "[]", "flags" to getCompilerFlags(benchmarkExtension).sorted(), "compileTime" to nativeCompileTime, "codeSize" to getCodeSizeBenchmark(applicationName, nativeExecutable.absolutePath) ) val output = createJsonReport(properties) buildDir.resolve(nativeJson).writeText(output) } konanRun.finalizedBy(this) } } private fun getCompilerFlags(benchmarkExtension: CompileBenchmarkExtension) = benchmarkExtension.compilerOpts private fun Project.configureJvmRun() { val jvmRun = tasks.create("jvmRun") { it.group = BenchmarkingPlugin.BENCHMARKING_GROUP it.description = "Runs the compile only benchmark for Kotlin/JVM." it.doLast { println("JVM run isn't supported") } } tasks.create("jvmJsonReport") { it.group = BenchmarkingPlugin.BENCHMARKING_GROUP it.description = "Builds the benchmarking report for Kotlin/Native." it.doLast { println("JVM run isn't supported") } jvmRun.finalizedBy(it) } } override fun apply(target: Project): Unit = with(target) { addTimeListener(this) val benchmarkExtension = extensions.create( COMPILE_BENCHMARK_EXTENSION_NAME, CompileBenchmarkExtension::class.java, this ) // Create tasks. configureUtilityTasks() configureKonanRun(benchmarkExtension) configureJvmRun() } companion object { const val COMPILE_BENCHMARK_EXTENSION_NAME = "compileBenchmark" } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/benchmark/KotlinNativeBenchmarkingPlugin.kt ================================================ package org.jetbrains.kotlin.benchmark import org.gradle.jvm.tasks.Jar import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.Task import org.jetbrains.kotlin.* import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.Executable import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.konan.target.HostManager import javax.inject.Inject import kotlin.reflect.KClass private val NamedDomainObjectContainer.jvmMain get() = maybeCreate("jvmMain") private val Project.jvmWarmup: Int get() = (property("jvmWarmup") as String).toInt() private val Project.jvmBenchResults: String get() = property("jvmBenchResults") as String open class KotlinNativeBenchmarkExtension @Inject constructor(project: Project) : BenchmarkExtension(project) { var jvmSrcDirs: Collection = emptyList() var mingwSrcDirs: Collection = emptyList() var posixSrcDirs: Collection = emptyList() fun BenchmarkExtension.BenchmarkDependencies.jvm(notation: Any) = sourceSets.jvmMain.dependencies { implementation(notation) } } /** * A plugin configuring a benchmark Kotlin/Native project. */ open class KotlinNativeBenchmarkingPlugin: BenchmarkingPlugin() { override fun Project.configureJvmJsonTask(jvmRun: Task): Task { return tasks.create("jvmJsonReport") { it.group = BENCHMARKING_GROUP it.description = "Builds the benchmarking report for Kotlin/JVM." it.doLast { val applicationName = benchmark.applicationName val jarPath = (tasks.getByName("jvmJar") as Jar).archiveFile.get().asFile val jvmCompileTime = getJvmCompileTime(project, applicationName) val benchContents = buildDir.resolve(jvmBenchResults).readText() val properties: Map = commonBenchmarkProperties + mapOf( "type" to "jvm", "compilerVersion" to kotlinVersion, "benchmarks" to benchContents, "compileTime" to listOf(jvmCompileTime), "codeSize" to getCodeSizeBenchmark(applicationName, jarPath.absolutePath) ) val output = createJsonReport(properties) buildDir.resolve(jvmJson).writeText(output) } jvmRun.finalizedBy(it) } } override fun Project.configureJvmTask(): Task { return tasks.create("jvmRun", RunJvmTask::class.java) { task -> task.dependsOn("jvmJar") val mainCompilation = kotlin.jvm().compilations.getByName("main") val runtimeDependencies = configurations.getByName(mainCompilation.runtimeDependencyConfigurationName) task.classpath(files(mainCompilation.output.allOutputs, runtimeDependencies)) task.main = "MainKt" task.group = BENCHMARKING_GROUP task.description = "Runs the benchmark for Kotlin/JVM." // Specify settings configured by a user in the benchmark extension. afterEvaluate { task.args("-p", "${benchmark.applicationName}::") task.warmupCount = jvmWarmup task.repeatCount = attempts task.outputFileName = buildDir.resolve(jvmBenchResults).absolutePath task.repeatingType = benchmark.repeatingType } } } override val benchmarkExtensionClass: KClass<*> get() = KotlinNativeBenchmarkExtension::class override val Project.benchmark: KotlinNativeBenchmarkExtension get() = extensions.getByName(benchmarkExtensionName) as KotlinNativeBenchmarkExtension override val benchmarkExtensionName: String = "benchmark" private val Project.nativeBinary: Executable get() = (kotlin.targets.getByName(NATIVE_TARGET_NAME) as KotlinNativeTarget) .binaries.getExecutable(NATIVE_EXECUTABLE_NAME, benchmark.buildType) override val Project.nativeExecutable: String get() = nativeBinary.outputFile.absolutePath override val Project.nativeLinkTask: Task get() = nativeBinary.linkTask override fun configureMPPExtension(project: Project) { super.configureMPPExtension(project) project.configureJVMTarget() } override fun getCompilerFlags(project: Project, nativeTarget: KotlinNativeTarget) = super.getCompilerFlags(project, nativeTarget) + project.nativeBinary.freeCompilerArgs.map { "\"$it\"" } override fun NamedDomainObjectContainer.configureSources(project: Project) { project.benchmark.let { commonMain.kotlin.srcDirs(*it.commonSrcDirs.toTypedArray()) if (HostManager.hostIsMingw) { nativeMain.kotlin.srcDirs(*(it.nativeSrcDirs + it.mingwSrcDirs).toTypedArray()) } else { nativeMain.kotlin.srcDirs(*(it.nativeSrcDirs + it.posixSrcDirs).toTypedArray()) } jvmMain.kotlin.srcDirs(*it.jvmSrcDirs.toTypedArray()) } } override fun NamedDomainObjectContainer.additionalConfigurations(project: Project) { jvmMain.dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${project.kotlinStdlibVersion}") } } private fun Project.configureJVMTarget() { kotlin.jvm { compilations.all { it.compileKotlinTask.kotlinOptions { jvmTarget = "1.8" suppressWarnings = true freeCompilerArgs = project.benchmark.compilerOpts + project.compilerArgs } } } } companion object { const val BENCHMARK_EXTENSION_NAME = "benchmark" } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/benchmark/SwiftBenchmarkingPlugin.kt ================================================ package org.jetbrains.kotlin.benchmark import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.Task import org.jetbrains.kotlin.* import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.Framework import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import java.io.File import javax.inject.Inject import java.nio.file.Paths import kotlin.reflect.KClass enum class CodeSizeEntity { FRAMEWORK, EXECUTABLE } open class SwiftBenchmarkExtension @Inject constructor(project: Project) : BenchmarkExtension(project) { var swiftSources: List = emptyList() var useCodeSize: CodeSizeEntity = CodeSizeEntity.FRAMEWORK // use as code size metric framework size or executable } /** * A plugin configuring a benchmark Kotlin/Native project. */ open class SwiftBenchmarkingPlugin : BenchmarkingPlugin() { override fun Project.configureJvmJsonTask(jvmRun: Task): Task { return tasks.create("jvmJsonReport") { logger.info("JVM run is unsupported") jvmRun.finalizedBy(it) } } override fun Project.configureJvmTask(): Task { return tasks.create("jvmRun") { task -> task.doLast { logger.info("JVM run is unsupported") } } } override val benchmarkExtensionClass: KClass<*> get() = SwiftBenchmarkExtension::class override val Project.benchmark: SwiftBenchmarkExtension get() = extensions.getByName(benchmarkExtensionName) as SwiftBenchmarkExtension override val benchmarkExtensionName: String = "swiftBenchmark" override val Project.nativeExecutable: String get() = Paths.get(buildDir.absolutePath, benchmark.applicationName).toString() override val Project.nativeLinkTask: Task get() = tasks.getByName("buildSwift") private lateinit var framework: Framework val nativeFrameworkName = "benchmark" override fun NamedDomainObjectContainer.configureSources(project: Project) { project.benchmark.let { commonMain.kotlin.srcDirs(*it.commonSrcDirs.toTypedArray()) nativeMain.kotlin.srcDirs(*(it.nativeSrcDirs).toTypedArray()) } } override fun Project.determinePreset(): AbstractKotlinNativeTargetPreset<*> = kotlin.presets.macosX64 as AbstractKotlinNativeTargetPreset<*> override fun KotlinNativeTarget.configureNativeOutput(project: Project) { binaries.framework(nativeFrameworkName, listOf(project.benchmark.buildType)) { // Specify settings configured by a user in the benchmark extension. project.afterEvaluate { linkerOpts.addAll(project.benchmark.linkerOpts) } } } override fun Project.configureExtraTasks() { val nativeTarget = kotlin.targets.getByName(NATIVE_TARGET_NAME) as KotlinNativeTarget // Build executable from swift code. framework = nativeTarget.binaries.getFramework(nativeFrameworkName, benchmark.buildType) tasks.create("buildSwift") { task -> task.dependsOn(framework.linkTaskName) task.doLast { val frameworkParentDirPath = framework.outputDirectory.absolutePath val options = listOf("-O", "-wmo", "-Xlinker", "-rpath", "-Xlinker", frameworkParentDirPath, "-F", frameworkParentDirPath) compileSwift(project, nativeTarget.konanTarget, benchmark.swiftSources, options, Paths.get(buildDir.absolutePath, benchmark.applicationName), false) } } } override fun Project.collectCodeSize(applicationName: String) = getCodeSizeBenchmark(applicationName, if (benchmark.useCodeSize == CodeSizeEntity.FRAMEWORK) File("${framework.outputFile.absolutePath}/$nativeFrameworkName").canonicalPath else nativeExecutable ) override fun getCompilerFlags(project: Project, nativeTarget: KotlinNativeTarget) = if (project.benchmark.useCodeSize == CodeSizeEntity.FRAMEWORK) { super.getCompilerFlags(project, nativeTarget) + framework.freeCompilerArgs.map { "\"$it\"" } } else { listOf("-O", "-wmo") } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcode.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.bitcode import org.gradle.api.DefaultTask import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.SanitizerKind import java.io.File import javax.inject.Inject open class CompileToBitcode @Inject constructor( val srcRoot: File, val folderName: String, val target: String, val outputGroup: String, ) : DefaultTask() { enum class Language { C, CPP } // Compiler args are part of compilerFlags so we don't register them as an input. val compilerArgs = mutableListOf() @Input val linkerArgs = mutableListOf() var excludeFiles: List = listOf( "**/*Test.cpp", "**/*TestSupport.cpp", "**/*Test.mm", "**/*TestSupport.mm", ) var includeFiles: List = listOf( "**/*.cpp", "**/*.mm" ) // Source files and headers are registered as inputs by the `inputFiles` and `headers` properties. var srcDirs: FileCollection = project.files(srcRoot.resolve("cpp")) var headersDirs: FileCollection = project.files(srcRoot.resolve("headers")) @Input var language = Language.CPP @Input @Optional var sanitizer: SanitizerKind? = null private val targetDir: File get() { val sanitizerSuffix = when (sanitizer) { null -> "" SanitizerKind.ADDRESS -> "-asan" SanitizerKind.THREAD -> "-tsan" } return project.buildDir.resolve("bitcode/$outputGroup/$target$sanitizerSuffix") } @get:Input val objDir get() = File(targetDir, folderName) private val KonanTarget.isMINGW get() = this.family == Family.MINGW val executable get() = when (language) { Language.C -> "clang" Language.CPP -> "clang++" } @get:Input val compilerFlags: List get() { val commonFlags = listOf("-c", "-emit-llvm") + headersDirs.map { "-I$it" } val sanitizerFlags = when (sanitizer) { null -> listOf() SanitizerKind.ADDRESS -> listOf("-fsanitize=address") SanitizerKind.THREAD -> listOf("-fsanitize=thread") } val languageFlags = when (language) { Language.C -> // Used flags provided by original build of allocator C code. listOf("-std=gnu11", "-O3", "-Wall", "-Wextra", "-Werror") Language.CPP -> listOfNotNull("-std=c++17", "-Werror", "-O2", "-Wall", "-Wextra", "-Wno-unused-parameter", // False positives with polymorphic functions. "-fPIC".takeIf { !HostManager().targetByName(target).isMINGW }) } return commonFlags + sanitizerFlags + languageFlags + compilerArgs } @get:SkipWhenEmpty @get:InputFiles val inputFiles: Iterable get() { return srcDirs.flatMap { srcDir -> project.fileTree(srcDir) { it.include(includeFiles) it.exclude(excludeFiles) }.files } } private fun outputFileForInputFile(file: File, extension: String) = objDir.resolve("${file.nameWithoutExtension}.${extension}") private fun bitcodeFileForInputFile(file: File) = outputFileForInputFile(file, "bc") @get:InputFiles protected val headers: Iterable get() { // Not using clang's -M* flags because there's a problem with our current include system: // We allow includes relative to the current directory and also pass -I for each imported module // Given file tree: // a: // header.hpp // b: // impl.cpp // Assume module b adds a to its include path. // If b/impl.cpp has #include "header.hpp", it'll be included from a/header.hpp. If we add another file // header.hpp into b/, the next compilation of b/impl.cpp will include b/header.hpp. -M flags, however, // won't generate a dependency on b/header.hpp, so incremental compilation will be broken. // TODO: Apart from dependency generation this also makes it awkward to have two files with // the same name (e.g. Utils.h) in directories a/ and b/: For the b/impl.cpp to include a/header.hpp // it needs to have #include "../a/header.hpp" val dirs = mutableSetOf() // First add dirs with sources, as clang by default adds directory with the source to the include path. inputFiles.forEach { dirs.add(it.parentFile) } // Now add manually given header dirs. dirs.addAll(headersDirs.files) return dirs.flatMap { dir -> project.fileTree(dir) { val includePatterns = when (language) { Language.C -> arrayOf("**/.h") Language.CPP -> arrayOf("**/*.h", "**/*.hpp") } it.include(*includePatterns) }.files } } @get:OutputFile val outFile: File get() = File(targetDir, "${folderName}.bc") @TaskAction fun compile() { objDir.mkdirs() val plugin = project.convention.getPlugin(ExecClang::class.java) plugin.execKonanClang(target) { it.workingDir = objDir it.executable = executable it.args = compilerFlags + inputFiles.map { it.absolutePath } } project.exec { val llvmDir = project.findProperty("llvmDir") it.executable = "$llvmDir/bin/llvm-link" it.args = listOf("-o", outFile.absolutePath) + linkerArgs + inputFiles.map { bitcodeFileForInputFile(it).absolutePath } } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/bitcode/CompileToBitcodePlugin.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.bitcode import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.BasePlugin import org.jetbrains.kotlin.createCompilationDatabasesFromCompileToBitcodeTasks import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.target.SanitizerKind import org.jetbrains.kotlin.konan.target.supportedSanitizers import java.io.File import javax.inject.Inject /** * A plugin creating extensions to compile */ open class CompileToBitcodePlugin: Plugin { override fun apply(target: Project) = with(target) { extensions.create(EXTENSION_NAME, CompileToBitcodeExtension::class.java, target) afterEvaluate { // TODO: Support providers (https://docs.gradle.org/current/userguide/lazy_configuration.html) // in database tasks and create them along with corresponding compile tasks (not in afterEvaluate). createCompilationDatabasesFromCompileToBitcodeTasks(project, COMPILATION_DATABASE_TASK_NAME) } } companion object { const val EXTENSION_NAME = "bitcode" const val COMPILATION_DATABASE_TASK_NAME = "CompilationDatabase" } } open class CompileToBitcodeExtension @Inject constructor(val project: Project) { private val targetList = with(project) { provider { (rootProject.property("targetList") as? List<*>)?.filterIsInstance() ?: emptyList() } // TODO: Can we make it better? } fun create( name: String, srcDir: File = project.file("src/$name"), outputGroup: String = "main", configurationBlock: CompileToBitcode.() -> Unit = {} ) { targetList.get().forEach { targetName -> val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager val target = platformManager.targetByName(targetName) val sanitizers: List = target.supportedSanitizers() + listOf(null) sanitizers.forEach { sanitizer -> project.tasks.register( "${targetName}${name.snakeCaseToCamelCase().capitalize()}${suffixForSanitizer(sanitizer)}", CompileToBitcode::class.java, srcDir, name, targetName, outputGroup ).configure { it.sanitizer = sanitizer it.group = BasePlugin.BUILD_GROUP val sanitizerDescription = when (sanitizer) { null -> "" SanitizerKind.ADDRESS -> " with ASAN" SanitizerKind.THREAD -> " with TSAN" } it.description = "Compiles '$name' to bitcode for $targetName$sanitizerDescription" it.configurationBlock() } } } } companion object { private fun String.snakeCaseToCamelCase() = split('_').joinToString(separator = "") { it.capitalize() } fun suffixForSanitizer(sanitizer: SanitizerKind?) = when (sanitizer) { null -> "" SanitizerKind.ADDRESS -> "_ASAN" SanitizerKind.THREAD -> "_TSAN" } } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/coroutineTestUtil.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin // This is almost a full copy of kotlin/compiler/tests-common/tests/org/jetbrains/kotlin/coroutineTestUtil.kt // TODO: get it automatically as a dependency fun createTextForHelpers(isReleaseCoroutines: Boolean): String { val coroutinesPackage = "kotlin.coroutines" val emptyContinuationBody = if (isReleaseCoroutines) """ |override fun resumeWith(result: Result) { | result.getOrThrow() |} """.trimMargin() else """ |override fun resume(data: Any?) {} |override fun resumeWithException(exception: Throwable) { throw exception } """.trimMargin() val handleResultContinuationBody = if (isReleaseCoroutines) """ |override fun resumeWith(result: Result) { | x(result.getOrThrow()) |} """.trimMargin() else """ |override fun resumeWithException(exception: Throwable) { | throw exception |} | |override fun resume(data: T) = x(data) """.trimMargin() val handleExceptionContinuationBody = if (isReleaseCoroutines) """ |override fun resumeWith(result: Result) { | result.exceptionOrNull()?.let(x) |} """.trimMargin() else """ |override fun resumeWithException(exception: Throwable) { | x(exception) |} | |override fun resume(data: Any?) {} """.trimMargin() val continuationAdapterBody = if (isReleaseCoroutines) """ |override fun resumeWith(result: Result) { | if (result.isSuccess) { | resume(result.getOrThrow()) | } else { | resumeWithException(result.exceptionOrNull()!!) | } |} | |abstract fun resumeWithException(exception: Throwable) |abstract fun resume(value: T) """.trimMargin() else "" return """ |package helpers |import $coroutinesPackage.* | |fun handleResultContinuation(x: (T) -> Unit): Continuation = object: Continuation { | override val context = EmptyCoroutineContext | $handleResultContinuationBody |} | | |fun handleExceptionContinuation(x: (Throwable) -> Unit): Continuation = object: Continuation { | override val context = EmptyCoroutineContext | $handleExceptionContinuationBody |} | |open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation { | companion object : EmptyContinuation() | $emptyContinuationBody |} | |abstract class ContinuationAdapter : Continuation { | override val context: CoroutineContext = EmptyCoroutineContext | $continuationAdapterBody |} |class StateMachineCheckerClass { | private var counter = 0 | var finished = false | | var proceed: () -> Unit = {} | | fun reset() { | counter = 0 | finished = false | proceed = {} | } | | suspend fun suspendHere() = suspendCoroutine { c -> | counter++ | proceed = { c.resume(Unit) } | } | | fun check(numberOfSuspensions: Int, checkFinished: Boolean = true) { | for (i in 1..numberOfSuspensions) { | if (counter != i) error("Wrong state-machine generated: suspendHere called should be called exactly once in one state. Expected " + i + ", got " + counter) | proceed() | } | if (counter != numberOfSuspensions) | error("Wrong state-machine generated: suspendHere called should be called exactly once in one state. Expected " + numberOfSuspensions + ", got " + counter) | if (finished) error("Wrong state-machine generated: it is finished early") | proceed() | if (checkFinished && !finished) error("Wrong state-machine generated: it is not finished yet") | } |} |val StateMachineChecker = StateMachineCheckerClass() |object CheckStateMachineContinuation: ContinuationAdapter() { | override val context: CoroutineContext | get() = EmptyCoroutineContext | | override fun resume(value: Unit) { | StateMachineChecker.proceed = { | StateMachineChecker.finished = true | } | } | | override fun resumeWithException(exception: Throwable) { | throw exception | } |} """.trimMargin() } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/genTestKT39548.kt ================================================ package org.jetbrains.kotlin import java.io.File fun genTestKT39548(file: File) { val longName = StringBuilder().apply { repeat(10_000_000) { append('a') } } val text = """ import kotlin.test.* fun $longName(): Int = 42 fun same(value: T): T = value val globalInt1: Int = same(1) val globalStringA: String = same("a") @ThreadLocal val threadLocalInt2: Int = same(2) @ThreadLocal val threadLocalStringB: String = same("b") fun main() { // Ensure function don't get DCEd: val resultOfFunctionWithLongName = $longName() assertEquals(42, resultOfFunctionWithLongName) // Check that top-level initializers did run as expected: assertEquals(1, globalInt1) assertEquals("a", globalStringA) assertEquals(2, threadLocalInt2) assertEquals("b", threadLocalStringB) } """.trimIndent() file.parentFile.mkdirs() file.writeText(text) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/klib/metadata/KmComparator.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.klib.metadata import kotlinx.metadata.* import kotlinx.metadata.klib.* /** * Structural comparison of Km* metadata. * [configuration] allows to tune comparison process. * */ internal class KmComparator(private val configuration: ComparisonConfig) { fun compare(kmClass1: KmClass, kmClass2: KmClass): MetadataCompareResult = serialComparator( compare(KmClass::name, ::compare) to "Different names: ${kmClass1.name}, ${kmClass2.name}", ::compareClassFlags to "Different flags for ${kmClass1.name}", compare(KmClass::constructors, compareLists(::compare)) to "Constructors mismatch for ${kmClass1.name}", compare(KmClass::properties, compareLists(::compare, KmProperty::mangle)) to "Properties mismatch for ${kmClass1.name}", compare(KmClass::functions, compareLists(::compare, KmFunction::mangle)) to "Functions mismatch for ${kmClass1.name}", )(kmClass1, kmClass2) fun compare(typealias1: KmTypeAlias, typealias2: KmTypeAlias): MetadataCompareResult = serialComparator( compare(KmTypeAlias::name, ::compare) to "Different names", compare(KmTypeAlias::underlyingType, ::compareTypes) to "Underlying types mismatch", compare(KmTypeAlias::expandedType, ::compareTypes) to "Expanded types mismatch", compare(KmTypeAlias::typeParameters, compareLists(::compare)) to "Type parameters mismatch" )(typealias1, typealias2) fun compare(function1: KmFunction, function2: KmFunction): MetadataCompareResult = serialComparator( compare(KmFunction::name, ::compare) to "Different names", compare(KmFunction::returnType, ::compareTypes) to "Return type mismatch", compare(KmFunction::valueParameters, compareLists(::compare)) to "Value parameters mismatch", ::compareFunctionFlags to "Flags mismatch" )(function1, function2) fun compare(property1: KmProperty, property2: KmProperty): MetadataCompareResult = serialComparator( compare(KmProperty::name, ::compare) to "Different names", compare(KmProperty::returnType, ::compareTypes) to "Return type mismatch", ::comparePropertyFlags to "Flags mismatch", (compare(KmProperty::getterFlags, ::comparePropertyAccessorFlags) to "Getter flags mismatch") .takeIf { Flag.Property.HAS_GETTER(property1.flags) && Flag.Property.HAS_GETTER(property2.flags) }, (compare(KmProperty::setterFlags, ::comparePropertyAccessorFlags) to "Setter flags mismatch") .takeIf { Flag.Property.HAS_SETTER(property1.flags) && Flag.Property.HAS_SETTER(property2.flags) } )(property1, property2) private fun compare(entry1: KlibEnumEntry, entry2: KlibEnumEntry): MetadataCompareResult = serialComparator( compare(KlibEnumEntry::annotations, compareLists(::compare)) to "Different annotations", compare(KlibEnumEntry::name, ::compare) to "Different names", compare(KlibEnumEntry::ordinal, compareNullable(::compare)) to "Different ordinals" )(entry1, entry2) private fun checkFlag(flag: Flag, flagName: String? = null): (Flags, Flags) -> MetadataCompareResult = { f1, f2 -> when { flag(f1) != flag(f2) -> Fail("Flags mismatch: ${flag(f1)}, ${flag(f2)} for $flagName") else -> Ok } } private fun compare(value1: Int, value2: Int): MetadataCompareResult = when { value1 == value2 -> Ok else -> Fail("$value1 != $value2") } private fun compare(string1: String, string2: String): MetadataCompareResult = when { string1 == string2 -> Ok else -> Fail("$string1 != $string2") } private fun compareFunctionFlags(function1: KmFunction, function2: KmFunction): MetadataCompareResult = serialComparator( checkFlag(Flag.Function.IS_EXTERNAL, "IS_EXTERNAL"), checkFlag(Flag.Function.IS_DECLARATION, "IS_DECLARATION"), ::compareVisibilityFlags, ::compareModalityFlags )(function1.flags, function2.flags) private fun comparePropertyFlags(property1: KmProperty, property2: KmProperty): MetadataCompareResult = serialComparator( checkFlag(Flag.Property.IS_CONST, "IS_CONST"), checkFlag(Flag.Property.HAS_SETTER, "HAS_SETTER"), checkFlag(Flag.Property.HAS_GETTER, "HAS_GETTER"), checkFlag(Flag.Property.IS_VAR, "IS_VAR"), checkFlag(Flag.Property.HAS_CONSTANT, "HAS_CONSTANT"), checkFlag(Flag.Property.IS_DECLARATION, "IS_DECLARATION"), checkFlag(Flag.Property.IS_EXTERNAL, "IS_EXTERNAL") )(property1.flags, property2.flags) private fun comparePropertyAccessorFlags(flags1: Flags, flags2: Flags): MetadataCompareResult = serialComparator( checkFlag(Flag.PropertyAccessor.IS_NOT_DEFAULT, "IS_NOT_DEFAULT"), checkFlag(Flag.PropertyAccessor.IS_INLINE, "IS_INLINE"), checkFlag(Flag.PropertyAccessor.IS_EXTERNAL, "IS_EXTERNAL"), ::compareVisibilityFlags, ::compareModalityFlags )(flags1, flags2) private fun compareClassFlags(class1: KmClass, class2: KmClass): MetadataCompareResult = serialComparator( checkFlag(Flag.Class.IS_CLASS, "IS_CLASS"), checkFlag(Flag.Class.IS_COMPANION_OBJECT, "IS_COMPANION_OBJECT"), checkFlag(Flag.Class.IS_ENUM_CLASS, "IS_ENUM_CLASS"), checkFlag(Flag.Class.IS_ENUM_ENTRY, "IS_ENUM_ENTRY"), checkFlag(Flag.Class.IS_OBJECT, "IS_OBJECT"), checkFlag(Flag.IS_FINAL, "IS_FINAL"), checkFlag(Flag.IS_OPEN, "IS_OPEN"), checkFlag(Flag.HAS_ANNOTATIONS, "HAS_ANNOTATIONS"), ::compareVisibilityFlags, ::compareModalityFlags )(class1.flags, class2.flags) private fun compareVisibilityFlags(flags1: Flags, flags2: Flags): MetadataCompareResult = serialComparator( checkFlag(Flag.IS_PUBLIC, "IS_PUBLIC"), checkFlag(Flag.IS_PRIVATE_TO_THIS, "IS_PRIVATE_TO_THIS"), checkFlag(Flag.IS_PRIVATE, "IS_PRIVATE"), checkFlag(Flag.IS_PROTECTED, "IS_PROTECTED"), checkFlag(Flag.IS_INTERNAL, "IS_INTERNAL") )(flags1, flags2) private fun compareModalityFlags(flags1: Flags, flags2: Flags): MetadataCompareResult = serialComparator( checkFlag(Flag.IS_FINAL, "IS_FINAL"), checkFlag(Flag.IS_ABSTRACT, "IS_ABSTRACT"), checkFlag(Flag.IS_OPEN, "IS_OPEN"), checkFlag(Flag.IS_SEALED, "IS_SEALED") )(flags1, flags2) private fun compare(annotation1: KmAnnotation, annotation2: KmAnnotation): MetadataCompareResult = when { annotation1.className != annotation2.className -> Fail("${annotation1.className} != ${annotation2.className}") // TODO: compare values else -> Ok } private fun compare(p1: KmValueParameter, p2: KmValueParameter): MetadataCompareResult = serialComparator( compare(KmValueParameter::name, ::compare) to "Different names", compare(KmValueParameter::type, compareNullable(::compareTypes)) to "Type mismatch", compare(KmValueParameter::annotations, compareLists(::compare)) to "Annotations mismatch" )(p1, p2) private fun compareTypeFlags(flags1: Flags, flags2: Flags): MetadataCompareResult = serialComparator( checkFlag(Flag.Type.IS_NULLABLE) to "Nullable flag mismatch", checkFlag(Flag.Type.IS_SUSPEND) to "Suspend flag mismatch" )(flags1, flags2) private fun compareConstructorFlags(flags1: Flags, flags2: Flags): MetadataCompareResult = serialComparator( checkFlag(Flag.Constructor.IS_SECONDARY) to "IS_SECONDARY mismatch" )(flags1, flags2) private fun compare(constructor1: KmConstructor, constructor2: KmConstructor): MetadataCompareResult = serialComparator( ::compareVisibilityFlags, ::compareConstructorFlags )(constructor1.flags, constructor2.flags) private fun compare(typeArgument1: KmTypeProjection, typeArgument2: KmTypeProjection): MetadataCompareResult = serialComparator( compare(KmTypeProjection::type, compareNullable(::compareTypes)) )(typeArgument1, typeArgument2) private fun compare(typeParameter1: KmTypeParameter, typeParameter2: KmTypeParameter): MetadataCompareResult = when { typeParameter1.variance != typeParameter2.variance -> Fail("Different variance") typeParameter1.name != typeParameter2.name -> Fail("${typeParameter1.name}, ${typeParameter2.name}") else -> Ok } private fun compareTypes(type1: KmType, type2: KmType): MetadataCompareResult = serialComparator( compare(KmType::classifier, ::compare) to "Classifiers mismatch", compare(KmType::arguments, compareLists(::compare)) to "Type arguments mismatch", compare(KmType::flags, ::compareTypeFlags) to "Type flags mismatch for", compare(KmType::abbreviatedType, compareNullable(::compareTypes)) to "Abbreviated types mismatch" )(type1, type2) private fun compare(class1: KmClassifier, class2: KmClassifier): MetadataCompareResult = when { class1 is KmClassifier.TypeAlias && class2 is KmClassifier.TypeAlias -> { if (class1.name == class2.name) Ok else Fail("Different type aliases: ${class1.name}, ${class2.name}") } class1 is KmClassifier.Class && class2 is KmClassifier.Class -> { when (class1.name) { class2.name -> Ok else -> Fail("Different classes: ${class1.name}, ${class2.name}") } } class1 is KmClassifier.TypeParameter && class2 is KmClassifier.TypeParameter -> { // TODO: How to correctly compare type ids? Ok } else -> Fail("class1 is $class1 and class2 is $class2") } private fun compare( property: T.() -> R, comparator: (R, R) -> MetadataCompareResult ): (T, T) -> MetadataCompareResult = { o1, o2 -> if (configuration.shouldCheck(property)) comparator(o1.property(), o2.property()) else Ok } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/klib/metadata/KmComparatorUtils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.klib.metadata import kotlinx.metadata.* private fun render(element: Any?): String = when (element) { is KmTypeAlias -> "typealias ${element.name}" is KmFunction -> "function ${element.name}" is KmProperty -> "property ${element.name}" is KmClass -> "class ${element.name}" is KmType -> "`type ${element.classifier}`" else -> element.toString() } internal fun serialComparator( vararg comparators: Pair<(T, T) -> MetadataCompareResult, String>? ): (T, T) -> MetadataCompareResult = { o1, o2 -> comparators.filterNotNull().map { (comparator, message) -> comparator(o1, o2).let { result -> if (result is Fail) Fail(message, result) else result } }.wrap() } internal fun serialComparator( vararg comparators: (T, T) -> MetadataCompareResult ): (T, T) -> MetadataCompareResult = { o1, o2 -> comparators .map { comparator -> comparator(o1, o2) } .wrap() } internal fun Collection.wrap(): MetadataCompareResult = filterIsInstance().let { fails -> when (fails.size) { 0 -> Ok else -> Fail(fails) } } internal fun compareNullable( comparator: (T, T) -> MetadataCompareResult ): (T?, T?) -> MetadataCompareResult = { a, b -> when { a != null && b != null -> comparator(a, b) a == null && b == null -> Ok else -> Fail("${render(a)} ${render(b)}") } } internal fun compareLists(elementComparator: (T, T) -> MetadataCompareResult, sortBy: T.() -> String? = { null }) = { list1: List, list2: List -> compareLists(list1.sortedBy(sortBy), list2.sortedBy(sortBy), elementComparator) } private fun compareLists(l1: List, l2: List, comparator: (T, T) -> MetadataCompareResult) = when { l1.size != l2.size -> Fail("${l1.size} != ${l2.size}") else -> l1.zip(l2).map { comparator(it.first, it.second) }.wrap() } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/klib/metadata/SortedMergeStrategy.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.klib.metadata import kotlinx.metadata.* import kotlinx.metadata.klib.KlibModuleFragmentReadStrategy import kotlinx.metadata.klib.fqName /** * Output klib declarations in predictable sorted order. */ internal class SortedMergeStrategy : KlibModuleFragmentReadStrategy { override fun processModuleParts(parts: List): List = parts.fold(KmModuleFragment(), ::joinFragments).let(::listOf) } /** * We need a stable order for overloaded functions. */ internal fun KmFunction.mangle(): String { val typeParameters = typeParameters.joinToString(prefix = "<", postfix = ">", transform = KmTypeParameter::name) val valueParameters = valueParameters.joinToString(prefix = "(", postfix = ")", transform = KmValueParameter::name) val receiver = receiverParameterType?.classifier return "$receiver.${name}.$typeParameters.$valueParameters" } internal fun KmProperty.mangle(): String { val receiver = receiverParameterType?.classifier return "$receiver.$name" } private fun joinAndSortPackages(pkg1: KmPackage, pkg2: KmPackage) = KmPackage().apply { functions += (pkg1.functions + pkg2.functions).sortedBy(KmFunction::mangle) properties += (pkg1.properties + pkg2.properties).sortedBy(KmProperty::name) typeAliases += (pkg1.typeAliases + pkg2.typeAliases).sortedBy(KmTypeAlias::name) } /** * Merges two fragments of a single module into one. */ internal fun joinFragments(fragment1: KmModuleFragment, fragment2: KmModuleFragment) = KmModuleFragment().apply { assert(fragment1.fqName == fragment2.fqName) pkg = when { fragment1.pkg != null && fragment2.pkg != null -> joinAndSortPackages(fragment1.pkg!!, fragment2.pkg!!) fragment1.pkg != null -> joinAndSortPackages(fragment1.pkg!!, KmPackage()) fragment2.pkg != null -> joinAndSortPackages(KmPackage(), fragment2.pkg!!) else -> null } fqName = fragment1.fqName classes += fragment1.classes.sortedBy(KmClass::name) + fragment2.classes.sortedBy(KmClass::name) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/klib/metadata/TrivialLibraryProvider.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.klib.metadata import kotlinx.metadata.klib.KlibModuleMetadata import org.jetbrains.kotlin.library.MetadataLibrary /** * Provides access to metadata using default compiler's routine. */ internal class TrivialLibraryProvider( private val library: MetadataLibrary ) : KlibModuleMetadata.MetadataLibraryProvider { override val moduleHeaderData: ByteArray get() = library.moduleHeaderData override fun packageMetadata(fqName: String, partName: String): ByteArray = library.packageMetadata(fqName, partName) override fun packageMetadataParts(fqName: String): Set = library.packageMetadataParts(fqName) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/klib/metadata/comparison.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.klib.metadata import kotlinx.metadata.* import kotlinx.metadata.klib.KlibModuleMetadata import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.library.CompilerSingleFileKlibResolveAllowingIrProvidersStrategy import org.jetbrains.kotlin.library.resolveSingleFileKlib private inline fun compareElements( comparisonConfig: ComparisonConfig, elements: Map>, crossinline comparator: (T, T) -> MetadataCompareResult ): MetadataCompareResult = elements .entries .asSequence() .filter { comparisonConfig.shouldCheckDeclaration(it.key) } .map { comparator(it.value.first, it.value.second).messageIfFail("${it.key} mismatch") } .toList() .wrap() private class JoinedFragments( val classes: JoinResult, val functions: JoinResult, val properties: JoinResult, val typeAliases: JoinResult, ) private fun processMissing(comparisonConfig: ComparisonConfig, joinResult: JoinResult<*>): MetadataCompareResult { val missingInFirst = joinResult.missingInFirst .filter(comparisonConfig::shouldCheckDeclaration) .map { Fail("$it missing in first fragment") } val missingInSecond = joinResult.missingInSecond .filter(comparisonConfig::shouldCheckDeclaration) .map { Fail("$it missing in second fragment") } return (missingInFirst + missingInSecond).let { if (it.isEmpty()) Ok else Fail(it) } } private fun MetadataCompareResult.messageIfFail(message: String): MetadataCompareResult = if (this is Fail) Fail(message, this) else this private fun processMissing( comparisonConfig: ComparisonConfig, joinedFragments: JoinedFragments ): MetadataCompareResult = listOf( processMissing(comparisonConfig, joinedFragments.classes) .messageIfFail("Missing classes"), processMissing(comparisonConfig, joinedFragments.functions) .messageIfFail("Missing functions"), processMissing(comparisonConfig, joinedFragments.typeAliases) .messageIfFail("Missing type aliases"), processMissing(comparisonConfig, joinedFragments.properties) .messageIfFail("Missing properties"), ).wrap() private data class JoinResult( val joined: Map>, val missingInFirst: List, val missingInSecond: List ) private fun buildJoined(e1: List, e2: List, key: T.() -> String): JoinResult { val m1 = e1.associateBy { it.key() } val m2 = e2.associateBy { it.key() } val joinedKeys = e1.map(key).filter { it in m2 }.toSet() val joined = m1 .filterKeys(joinedKeys::contains) .mapValues { (key, value) -> value to m2.getValue(key) } return JoinResult( joined, (m1 - joinedKeys).keys.toList(), (m2 - joinedKeys).keys.toList() ) } /** * Wrapper around direct access to [fragment] that allows * to uniformly process all its components. */ private fun processFragment( fragment: KmModuleFragment, action: (List, List, List, List) -> T ): T { val classes = fragment.classes val pkg = fragment.pkg return when { pkg != null -> action(classes, pkg.functions, pkg.properties, pkg.typeAliases) else -> action(classes, emptyList(), emptyList(), emptyList()) } } private fun compareMetadata( comparisonConfig: ComparisonConfig, metadataModuleA: KlibModuleMetadata, metadataModuleB: KlibModuleMetadata ): MetadataCompareResult { val fragmentA = metadataModuleA.fragments.fold(KmModuleFragment(), ::joinFragments) val fragmentB = metadataModuleB.fragments.fold(KmModuleFragment(), ::joinFragments) val joinedFragments = processFragment(fragmentA) { classesA, functionsA, propertiesA, typeAliasesA -> processFragment(fragmentB) { classesB, functionsB, propertiesB, typeAliasesB -> JoinedFragments( buildJoined(classesA, classesB, KmClass::name), buildJoined(functionsA, functionsB, KmFunction::name), buildJoined(propertiesA, propertiesB, KmProperty::name), buildJoined(typeAliasesA, typeAliasesB, KmTypeAlias::name) ) } } val comparator = KmComparator(comparisonConfig) return joinedFragments.run { listOf( compareElements(comparisonConfig, classes.joined, comparator::compare), compareElements(comparisonConfig, functions.joined, comparator::compare), compareElements(comparisonConfig, properties.joined, comparator::compare), compareElements(comparisonConfig, typeAliases.joined, comparator::compare), processMissing(comparisonConfig, this) ) }.wrap() } sealed class MetadataCompareResult { class Fail( val children: Collection, val message: String? = null ) : MetadataCompareResult() { constructor(message: String, child: Fail? = null) : this(listOfNotNull(child), message) } object Ok : MetadataCompareResult() } // A neat way to have short names internally without polluting client's namespace. internal typealias Fail = MetadataCompareResult.Fail internal typealias Ok = MetadataCompareResult.Ok fun expandFail(fail: Fail, output: (String) -> Unit, padding: String = "") { fail.message?.let { output("$padding$it") } fail.children.forEach { expandFail(it, output, "$padding ") } } /** * Configure what should be tested and what shouldn't. * * TODO: Add a way to conditionally disable property comparison. * E.g. "If class name is Companion do not compare flags". */ interface ComparisonConfig { /** * Should the declaration be compared at all. */ fun shouldCheckDeclaration(element: String): Boolean /** * Should we check property of declaration. */ fun shouldCheck(property: T.() -> R): Boolean } /** * Configuration for comparing `metadata` and `sourcecode` cinterop modes. */ class CInteropComparisonConfig : ComparisonConfig { override fun shouldCheck(property: T.() -> R): Boolean = when (property) { // Kotlin compiler may incorrectly omit abbreviatedType in some cases. KmType::abbreviatedType -> false else -> true } override fun shouldCheckDeclaration(element: String): Boolean = when { // kniBridge is generated only in sourcecode mode. element.startsWith("kniBridge") -> false else -> true } } /** * Structurally compares metadata of given libraries. */ fun compareKlibMetadata( comparisonConfig: ComparisonConfig, pathToFirstLibrary: String, pathToSecondLibrary: String ): MetadataCompareResult { val resolveStrategy = CompilerSingleFileKlibResolveAllowingIrProvidersStrategy( knownIrProviders = listOf("kotlin.native.cinterop") ) val klib1 = resolveSingleFileKlib(File(pathToFirstLibrary), strategy = resolveStrategy) val klib2 = resolveSingleFileKlib(File(pathToSecondLibrary), strategy = resolveStrategy) val metadata1 = KlibModuleMetadata.read(TrivialLibraryProvider(klib1), SortedMergeStrategy()) val metadata2 = KlibModuleMetadata.read(TrivialLibraryProvider(klib2), SortedMergeStrategy()) return compareMetadata(comparisonConfig, metadata1, metadata2) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/testing/native/GitDownloadTask.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.testing.native import org.gradle.api.DefaultTask import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option import org.gradle.process.ExecResult import org.gradle.process.ExecSpec import org.jetbrains.kotlin.isNotEmpty import java.io.File import java.net.URL import java.util.* import javax.inject.Inject /** * Clones the given revision of the given Git repository to the given directory. */ @Suppress("UnstableApiUsage") open class GitDownloadTask @Inject constructor( val repositoryProvider: Provider, val revisionProvider: Provider, val outputDirectoryProvider: Provider ) : DefaultTask() { private val repository: URL get() = repositoryProvider.get() private val revision: String get() = revisionProvider.get() private val outputDirectory: File get() = outputDirectoryProvider.get() @Option(option = "refresh", description = "Fetch and checkout the revision even if the output directory already contains it. " + "All changes in the output directory will be overwritten") val refresh: Property = project.objects.property(Boolean::class.java).apply { set(false) } private val upToDateChecker = UpToDateChecker() init { outputs.upToDateWhen { upToDateChecker.isUpToDate() } } private fun git( vararg args: String, ignoreExitValue: Boolean = false, execConfiguration: ExecSpec.() -> Unit = {} ): ExecResult = project.exec { it.executable = "git" it.args(*args) it.isIgnoreExitValue = ignoreExitValue it.execConfiguration() } private fun tryCloneBranch(): Boolean { val execResult = git( "clone", repository.toString(), outputDirectory.absolutePath, "--depth", "1", "--branch", revision, ignoreExitValue = true ) return execResult.exitValue == 0 } private fun fetchByHash() { git("init", outputDirectory.absolutePath) git("fetch", repository.toString(), "--depth", "1", revision) { workingDir(outputDirectory) } git("reset", "--hard", revision) { workingDir(outputDirectory) } } @TaskAction fun clone() { // Gradle ignores outputs.upToDateWhen { ... } and reruns a task if the classpath of the task was changed // So we have to perform the up-to-date check manually one more time in the task action. if (upToDateChecker.isUpToDate()) { logger.info("Skip cloning to avoid rewriting possible debug changes in ${outputDirectory.absolutePath}.") return } project.delete { it.delete(outputDirectory) } if (!tryCloneBranch()) { logger.info("Cannot use the revision '$revision' to clone the repository. Trying to use init && fetch instead.") fetchByHash() } // Store info about used revision for the manual up-to-date check. upToDateChecker.storeRevisionInfo() // Delete the .git directory of the cloned repo to avoid adding it to IDEA's VCS roots. outputDirectory.resolve(".git").deleteRecursively() } /** * This class performs manual UP-TO-DATE checking. * * We want to be able to edit downloaded sources for debug purposes. Thus this task should not rewrite changes in * the output directory. * * Gradle does allow us to provide a custom logic to determine if task outputs are UP-TO-DATE or not (see * Task.outputs.upToDateWhen). But Gradle still reruns a task if its classpath was changed. This may lead * to rewriting our manual debug changes in downloaded sources if there are some changes in the * `build-tools` project. * * So we have to manually check up-to-dateness in upToDateWhen and as a first step of the task action. */ private inner class UpToDateChecker() { private val revisionInfoFile: File get() = outputDirectory.resolve(".revision") /** * The download task should be executed in the following cases: * * - The output directory doesn't exist or is empty; * - Repository or revision was changed since the last execution; * - A user forced rerunning this tasks manually (see [GitDownloadTask.refresh]). * * In all other cases we consider the task UP-TO-DATE. */ fun isUpToDate(): Boolean { return !refresh.get() && outputDirectory.let { it.exists() && project.fileTree(it).isNotEmpty } && noRevisionChanges() } private fun noRevisionChanges(): Boolean = revisionInfoFile.exists() && loadRevisionInfo() == RevisionInfo(repository, revision) fun storeRevisionInfo() { val properties = Properties() properties["repository"] = repository.toString() properties["revision"] = revision revisionInfoFile.bufferedWriter().use { properties.store(it, null) } } private fun loadRevisionInfo(): RevisionInfo? { return try { val properties = Properties() revisionInfoFile.bufferedReader().use { properties.load(it) } RevisionInfo(properties.getProperty("repository"), properties.getProperty("revision")) } catch (_ : Exception) { null } } } private data class RevisionInfo(val repository: String, val revision: String) { constructor(repository: URL, revision: String): this(repository.toString(), revision) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/testing/native/NativeTest.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.testing.native import groovy.lang.Closure import java.io.File import javax.inject.Inject import org.gradle.api.* import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.tasks.* import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.bitcode.CompileToBitcode import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension import org.jetbrains.kotlin.konan.target.* open class CompileNativeTest @Inject constructor( @InputFile val inputFile: File, @Input val target: KonanTarget, ) : DefaultTask() { @OutputFile var outputFile = project.buildDir.resolve("bin/test/${target.name}/${inputFile.nameWithoutExtension}.o") @Input val clangArgs = mutableListOf() @Input @Optional var sanitizer: SanitizerKind? = null @Input private val sanitizerFlags = when (sanitizer) { null -> listOf() SanitizerKind.ADDRESS -> listOf("-fsanitize=address") SanitizerKind.THREAD -> listOf("-fsanitize=thread") } @TaskAction fun compile() { val plugin = project.convention.getPlugin(ExecClang::class.java) val args = clangArgs + sanitizerFlags + listOf(inputFile.absolutePath, "-o", outputFile.absolutePath) if (target.family.isAppleFamily) { plugin.execToolchainClang(target) { it.executable = "clang++" it.args = args } } else { plugin.execBareClang { it.executable = "clang++" it.args = args } } } } open class LlvmLinkNativeTest @Inject constructor( val baseName: String, @Input val target: String, @InputFile val mainFile: File ) : DefaultTask() { @SkipWhenEmpty @InputFiles var inputFiles: ConfigurableFileCollection = project.files() @OutputFile var outputFile: File = project.buildDir.resolve("bitcode/test/$target/$baseName.bc") @TaskAction fun llvmLink() { val llvmDir = project.property("llvmDir") val tmpOutput = File.createTempFile("runtimeTests", ".bc").apply { deleteOnExit() } // The runtime provides our implementations for some standard functions (see StdCppStubs.cpp). // We need to internalize these symbols to avoid clashes with symbols provided by the C++ stdlib. // But llvm-link -internalize is kinda broken: it links modules one by one and can't see usages // of a symbol in subsequent modules. So it will mangle such symbols causing "unresolved symbol" // errors at the link stage. So we have to run llvm-link twice: the first one links all modules // except the one containing the entry point to a single *.bc without internalization. The second // run internalizes this big module and links it with a module containing the entry point. project.exec { it.executable = "$llvmDir/bin/llvm-link" it.args = listOf("-o", tmpOutput.absolutePath) + inputFiles.map { it.absolutePath } } project.exec { it.executable = "$llvmDir/bin/llvm-link" it.args = listOf( "-o", outputFile.absolutePath, mainFile.absolutePath, tmpOutput.absolutePath, "-internalize" ) } } } open class LinkNativeTest @Inject constructor( @InputFiles val inputFiles: List, @OutputFile val outputFile: File, @Internal val target: String, @Internal val linkerArgs: List, private val platformManager: PlatformManager, private val mimallocEnabled: Boolean, ) : DefaultTask () { companion object { fun create( project: Project, platformManager: PlatformManager, taskName: String, inputFiles: List, target: String, outputFile: File, linkerArgs: List, mimallocEnabled: Boolean, ): LinkNativeTest = project.tasks.create( taskName, LinkNativeTest::class.java, inputFiles, outputFile, target, linkerArgs, platformManager, mimallocEnabled) fun create( project: Project, platformManager: PlatformManager, taskName: String, inputFiles: List, target: String, executableName: String, mimallocEnabled: Boolean, linkerArgs: List = listOf() ): LinkNativeTest = create( project, platformManager, taskName, inputFiles, target, project.buildDir.resolve("bin/test/$target/$executableName"), linkerArgs, mimallocEnabled) } @Input @Optional var sanitizer: SanitizerKind? = null @get:Input val commands: List> get() { // Getting link commands requires presence of a target toolchain. // Thus we cannot get them at the configuration stage because the toolchain may be not downloaded yet. val linker = platformManager.platform(platformManager.targetByName(target)).linker return linker.finalLinkCommands( inputFiles.map { it.absolutePath }, outputFile.absolutePath, listOf(), linkerArgs, optimize = false, debug = false, kind = LinkerOutputKind.EXECUTABLE, outputDsymBundle = "", needsProfileLibrary = false, mimallocEnabled = mimallocEnabled, sanitizer = sanitizer, ).map { it.argsWithExecutable } } @TaskAction fun link() { for (command in commands) { project.exec { it.commandLine(command) } } } } private fun createTestTask( project: Project, testName: String, testedTaskNames: List, sanitizer: SanitizerKind?, configureCompileToBitcode: CompileToBitcode.() -> Unit = {}, ): Task { val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager val googleTestExtension = project.extensions.getByName(RuntimeTestingPlugin.GOOGLE_TEST_EXTENSION_NAME) as GoogleTestExtension val testedTasks = testedTaskNames.map { project.tasks.getByName(it) as CompileToBitcode } val target = testedTasks.map { it.target }.distinct().single() val konanTarget = platformManager.targetByName(target) val compileToBitcodeTasks = testedTasks.mapNotNull { val name = "${it.name}TestBitcode" val task = project.tasks.findByName(name) as? CompileToBitcode ?: project.tasks.create(name, CompileToBitcode::class.java, it.srcRoot, "${it.folderName}Tests", target, "test" ).apply { this.sanitizer = sanitizer excludeFiles = emptyList() includeFiles = listOf("**/*Test.cpp", "**/*TestSupport.cpp", "**/*Test.mm", "**/*TestSupport.mm") dependsOn(it) dependsOn("downloadGoogleTest") compilerArgs.addAll(it.compilerArgs) headersDirs += googleTestExtension.headersDirs this.configureCompileToBitcode() } if (task.inputFiles.count() == 0) null else task } // TODO: Consider using sanitized versions. val testFrameworkTasks = listOf( project.tasks.getByName("${target}Googletest") as CompileToBitcode, project.tasks.getByName("${target}Googlemock") as CompileToBitcode ) val testSupportTask = project.tasks.getByName("${target}TestSupport${CompileToBitcodeExtension.suffixForSanitizer(sanitizer)}") as CompileToBitcode // TODO: It may make sense to merge llvm-link, compile and link to a single task. val llvmLinkTask = project.tasks.create( "${testName}LlvmLink", LlvmLinkNativeTest::class.java, testName, target, testSupportTask.outFile ).apply { val tasksToLink = (compileToBitcodeTasks + testedTasks + testFrameworkTasks) inputFiles = project.files(tasksToLink.map { it.outFile }) dependsOn(testSupportTask) dependsOn(tasksToLink) } val clangFlags = platformManager.platform(konanTarget).configurables as ClangFlags val compileTask = project.tasks.create( "${testName}Compile", CompileNativeTest::class.java, llvmLinkTask.outputFile, konanTarget, ).apply { this.sanitizer = sanitizer dependsOn(llvmLinkTask) clangArgs.addAll(clangFlags.clangFlags) clangArgs.addAll(clangFlags.clangNooptFlags) } val mimallocEnabled = testedTaskNames.any { it.contains("mimalloc", ignoreCase = true) } val linkTask = LinkNativeTest.create( project, platformManager, "${testName}Link${CompileToBitcodeExtension.suffixForSanitizer(sanitizer)}", listOf(compileTask.outputFile), target, testName, mimallocEnabled, ).apply { this.sanitizer = sanitizer dependsOn(compileTask) } return project.tasks.create(testName, Exec::class.java).apply { dependsOn(linkTask) workingDir = project.buildDir.resolve("testReports/$testName") val xmlReport = workingDir.resolve("report.xml") executable(linkTask.outputFile) args("--gtest_output=xml:${xmlReport.absoluteFile}") when (sanitizer) { SanitizerKind.THREAD -> { val file = project.file("tsan_suppressions.txt") inputs.file(file) environment("TSAN_OPTIONS", "suppressions=${file.absolutePath}") } else -> {} // no action required } doFirst { workingDir.mkdirs() } doLast { // TODO: Better to use proper XML parsing. var contents = xmlReport.readText() contents = contents.replace(", configureCompileToBitcode: CompileToBitcode.() -> Unit = {}, ): List { val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager val target = platformManager.targetByName(targetName) val sanitizers: List = target.supportedSanitizers() + listOf(null) return sanitizers.map { sanitizer -> val suffix = CompileToBitcodeExtension.suffixForSanitizer(sanitizer) val name = testTaskName + suffix val testedNames = testedTaskNames.map { it + suffix } createTestTask(project, name, testedNames, sanitizer, configureCompileToBitcode) } } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/testing/native/RuntimeTestingPlugin.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.testing.native import org.gradle.api.InvalidUserDataException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension import org.jetbrains.kotlin.bitcode.CompileToBitcodePlugin import org.jetbrains.kotlin.resolve import java.io.File import java.net.URL import javax.inject.Inject @Suppress("UnstableApiUsage") open class RuntimeTestingPlugin : Plugin { override fun apply(target: Project): Unit = with(target) { val extension = extensions.create(GOOGLE_TEST_EXTENSION_NAME, GoogleTestExtension::class.java, target) val downloadTask = registerDownloadTask(extension) val googleTestRoot = project.provider { extension.sourceDirectory } createBitcodeTasks(googleTestRoot, listOf(downloadTask)) } private fun Project.registerDownloadTask(extension: GoogleTestExtension): TaskProvider { val task = tasks.register( "downloadGoogleTest", GitDownloadTask::class.java, provider { URL(extension.repository) }, provider { extension.revision }, provider { extension.fetchDirectory } ) task.configure { it.refresh.set(provider { extension.refresh }) it.onlyIf { extension.localSourceRoot == null } it.description = "Retrieves GoogleTest from the given repository" it.group = "Google Test" } return task } private fun Project.createBitcodeTasks( googleTestRoot: Provider, dependencies: Iterable> ) { pluginManager.withPlugin("compile-to-bitcode") { val bitcodeExtension = project.extensions.getByName(CompileToBitcodePlugin.EXTENSION_NAME) as CompileToBitcodeExtension bitcodeExtension.create("googletest", outputGroup = "test") { srcDirs = project.files( googleTestRoot.resolve("googletest/src") ) headersDirs = project.files( googleTestRoot.resolve("googletest/include"), googleTestRoot.resolve("googletest") ) includeFiles = listOf("*.cc") excludeFiles = listOf("gtest-all.cc", "gtest_main.cc") // Original GTest sources contain an unused variable on Windows (kAlternatePathSeparatorString). compilerArgs.add("-Wno-unused") dependsOn(dependencies) } bitcodeExtension.create("googlemock", outputGroup = "test") { srcDirs = project.files( googleTestRoot.resolve("googlemock/src") ) headersDirs = project.files( googleTestRoot.resolve("googlemock"), googleTestRoot.resolve("googlemock/include"), googleTestRoot.resolve("googletest/include") ) includeFiles = listOf("*.cc") excludeFiles = listOf("gmock-all.cc", "gmock_main.cc") dependsOn(dependencies) } } } companion object { internal const val GOOGLE_TEST_EXTENSION_NAME = "googletest" } } /** * A project extension to configure from where we get the GoogleTest framework. */ open class GoogleTestExtension @Inject constructor(private val project: Project) { /** * A repository to fetch GoogleTest from. */ var repository: String = "https://github.com/google/googletest.git" private var _revision: String? = null /** * A particular revision in the [repository] to be fetched. It can be a branch, a tag or a commit hash. */ var revision: String get() = _revision ?: throw InvalidUserDataException( "No value provided for property '${RuntimeTestingPlugin.GOOGLE_TEST_EXTENSION_NAME}.revision'. " + "Please specify it in the buildscript." ) set(value) { _revision = value } /** * Fetch the [revision] even if the [fetchDirectory] already contains it. Overwrite all changes manually made in the output directory. */ var refresh: Boolean = false /** * A directory to fetch the [revision] to. */ var fetchDirectory: File = project.file("googletest") internal var localSourceRoot: File? = null /** * Use a local [directory] with GoogleTest instead of the fetched one. If set, the download task will not be executed. */ fun useLocalSources(directory: File) { localSourceRoot = directory } /** * Use a local [directory] with GoogleTest instead of the fetched one. If set, the download task will not be executed. */ fun useLocalSources(directory: String) { localSourceRoot = project.file(directory) } /** * A getter for directory that contains the GTest sources. * Returns a local source directory if it's specified (see [useLocalSources]) or [fetchDirectory] otherwise. */ val sourceDirectory: File get() = localSourceRoot ?: fetchDirectory /** * A file collection with header directories for GoogleTest and GoogleMock. * Useful to configure compilation against GTest. */ val headersDirs: FileCollection = project.files( project.provider { sourceDirectory.resolve("googletest/include") }, project.provider { sourceDirectory.resolve("googlemock/include") } ) } ================================================ FILE: build-tools/src/main/kotlin/org/jetbrains/kotlin/utils/DFS.kt ================================================ package org.jetbrains.kotlin.utils import java.util.* // Copied from Kotlin org.jetbrains.kotlin.utils.DFS class @Suppress("MemberVisibilityCanBePrivate", "MemberVisibilityCanBePrivate", "unused") object DFS { fun dfs(nodes: Collection, neighbors: Neighbors, visited: Visited, handler: NodeHandler): R { for (node in nodes) { doDfs(node, neighbors, visited, handler) } return handler.result() } fun dfs( nodes: Collection, neighbors: Neighbors, handler: NodeHandler ): R { return dfs(nodes, neighbors, VisitedWithSet(), handler) } fun ifAny( nodes: Collection, neighbors: Neighbors, predicate: Function1 ): Boolean { val result = BooleanArray(1) return dfs(nodes, neighbors, object : AbstractNodeHandler() { override fun beforeChildren(current: N): Boolean { if (predicate.invoke(current)) { result[0] = true } return !result[0] } override fun result(): Boolean { return result[0] } })!! } fun dfsFromNode(node: N, neighbors: Neighbors, visited: Visited, handler: NodeHandler): R { doDfs(node, neighbors, visited, handler) return handler.result() } fun dfsFromNode( node: N, neighbors: Neighbors, visited: Visited ) { dfsFromNode(node, neighbors, visited, object : AbstractNodeHandler() { override fun result(): Void? { return null } }) } fun topologicalOrder(nodes: Iterable, neighbors: Neighbors, visited: Visited): List { val handler = TopologicalOrder() for (node in nodes) { doDfs(node, neighbors, visited, handler) } return handler.result() } fun topologicalOrder(nodes: Iterable, neighbors: Neighbors): List { return topologicalOrder(nodes, neighbors, VisitedWithSet()) } fun doDfs(current: N, neighbors: Neighbors, visited: Visited, handler: NodeHandler) { if (!visited.checkAndMarkVisited(current)) return if (!handler.beforeChildren(current)) return for (neighbor in neighbors.getNeighbors(current)) { doDfs(neighbor, neighbors, visited, handler) } handler.afterChildren(current) } interface NodeHandler { fun beforeChildren(current: N): Boolean fun afterChildren(current: N) fun result(): R } interface Neighbors { fun getNeighbors(current: N): Iterable } interface Visited { fun checkAndMarkVisited(current: N): Boolean } abstract class AbstractNodeHandler : NodeHandler { override fun beforeChildren(current: N): Boolean { return true } override fun afterChildren(current: N) {} } class VisitedWithSet @JvmOverloads constructor(private val visited: MutableSet = HashSet()) : Visited { override fun checkAndMarkVisited(current: N): Boolean { return visited.add(current) } } abstract class CollectingNodeHandler> protected constructor(protected val result: C) : AbstractNodeHandler() { override fun result(): C { return result } } abstract class NodeHandlerWithListResult protected constructor() : CollectingNodeHandler>(LinkedList()) class TopologicalOrder : NodeHandlerWithListResult() { override fun afterChildren(current: N) { result.addFirst(current) } } } ================================================ FILE: build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import kotlin.text.Regex import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.* import org.jetbrains.kotlin.CopySamples import org.jetbrains.kotlin.CopyCommonSources import org.jetbrains.kotlin.PlatformInfo import org.jetbrains.kotlin.KotlinBuildPusher import org.jetbrains.kotlin.CollisionDetector import org.jetbrains.kotlin.CollisionTransformer import org.jetbrains.kotlin.CompilationDatabaseKt import org.jetbrains.kotlin.CompareDistributionSignatures import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.UtilsKt buildscript { apply from: "gradle/kotlinGradlePlugin.gradle" repositories { maven { url kotlinCompilerRepo } maven { url "https://kotlin.bintray.com/kotlinx" } maven { url "https://cache-redirector.jetbrains.com/maven-central" } mavenCentral() maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } maven { url "https://cache-redirector.jetbrains.com/jcenter" } jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" classpath "org.jetbrains.kotlin:kotlin-native-build-tools:$konanVersion" classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0' } } import org.jetbrains.kotlin.konan.* // Allows generating wrappers for the root build and all the samples during execution of the default 'wrapper' task. // Run './gradlew wrapper --gradle-version ' to update all the wrappers. apply plugin: org.jetbrains.kotlin.GradleWrappers wrappers.projects = ['samples', 'samples/calculator', 'samples/androidNativeActivity', 'samples/cocoapods/kotlin-library'] wrapper.distributionType = Wrapper.DistributionType.ALL // FIXME: Remove until IDEA-231214 is fixed. //defaultTasks 'clean', 'dist' convention.plugins.platformInfo = PlatformInfo if (isMac()) { checkXcodeVersion(project) } ext { distDir = file('dist') dependenciesDir = DependencyProcessor.defaultDependenciesRoot experimentalEnabled = project.hasProperty("org.jetbrains.kotlin.native.experimentalTargets") platformManager = new PlatformManager(DistributionKt.buildDistribution(projectDir.absolutePath), ext.experimentalEnabled) cacheableTargetNames = platformManager.hostPlatform.cacheableTargets cacheableTargets = cacheableTargetNames.collect { platformManager.targetByName(it) } // Some targets miss zlib in their sysroots. // We skip these targets when generate a corresponding platform library. // See also: the :distDef task, targetDefFiles in the :platformLibs project. targetsWithoutZlib = [ KonanTarget.LINUX_MIPS32.INSTANCE, KonanTarget.LINUX_MIPSEL32.INSTANCE ] kotlinCompilerModule="org.jetbrains.kotlin:kotlin-compiler:${kotlinVersion}" kotlinStdLibModule="org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}" kotlinCommonStdlibModule="org.jetbrains.kotlin:kotlin-stdlib-common:${kotlinStdlibVersion}:sources" kotlinTestCommonModule="org.jetbrains.kotlin:kotlin-test-common:${kotlinStdlibVersion}:sources" kotlinTestAnnotationsCommonModule="org.jetbrains.kotlin:kotlin-test-annotations-common:${kotlinStdlibVersion}:sources" kotlinReflectModule="org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}" kotlinScriptRuntimeModule="org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}" kotlinUtilKliMetadatabModule="org.jetbrains.kotlin:kotlin-util-klib-metadata:${kotlinVersion}" konanVersionFull = CompilerVersionGeneratedKt.getCurrentCompilerVersion() gradlePluginVersion = konanVersionFull } allprojects { buildscript { repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } } } if (path != ":dependencies") { evaluationDependsOn(":dependencies") } repositories { maven { url 'https://cache-redirector.jetbrains.com/maven-central' } mavenCentral() maven { url kotlinStdlibRepo } maven { url kotlinCompilerRepo } maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } } if (findProperty("kotlin.build.useIR") == "true") { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { useIR = true freeCompilerArgs += ["-Xir-binary-with-stable-abi"] } } } setupHostAndTarget() loadCommandLineProperties() loadLocalProperties() setupClang(project) } void setupHostAndTarget() { ext.hostName = platformManager.hostName ext.targetList = platformManager.enabled.collect { it.visibleName } as List ext.konanTargetList = platformManager.enabled as List } void setupClang(Project project) { project.convention.plugins.platformManager = project.rootProject.ext.platformManager project.convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project) project.plugins.withType(NativeComponentPlugin) { project.model { if (isWindows()) { platforms { host { architecture 'x86_64' } } components { withType(NativeComponentSpec) { targetPlatform 'host' } } toolChains { gcc(Gcc) { path "$llvmDir/bin" } } } else { toolChains { clang(Clang) { hostPlatform.clang.clangPaths.each { path it } eachPlatform { // TODO: will not work when cross-compiling [cCompiler, cppCompiler, linker].each { it.withArguments { it.addAll(project.hostPlatform.clang.clangArgs) } } } } } } } } } void loadLocalProperties() { if (new File("$project.rootDir/local.properties").exists()) { Properties props = new Properties() props.load(new FileInputStream("$project.rootDir/local.properties")) props.each { prop -> project.ext.set(prop.key, prop.value) } } } void loadCommandLineProperties() { if (project.hasProperty("konanc_flags")) { throw new Error("Specify either -Ptest_flags or -Pbuild_flags.") } ext.globalBuildArgs = project.hasProperty("build_flags") ? ext.build_flags.split() : [] ext.globalTestArgs = project.hasProperty("test_flags") ? ext.test_flags.split() : [] ext.testTarget = project.hasProperty("test_target") ? ext.test_target : null } configurations { ftpAntTask kotlinCommonSources distPack } dependencies { ftpAntTask 'org.apache.ant:ant-commons-net:1.9.9' [kotlinCommonStdlibModule, kotlinTestCommonModule, kotlinTestAnnotationsCommonModule].each { kotlinCommonSources(it) { transitive = false } } distPack project(':Interop:Runtime') distPack project(':Interop:Indexer') distPack project(':Interop:StubGenerator') distPack project(':backend.native') distPack project(':utilities:cli-runner') distPack project(':utilities:basic-utils') distPack project(':klib') distPack project(path: ':endorsedLibraries:kotlinx.cli', configuration: "jvmRuntimeElements") distPack "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } task sharedJar { dependsOn gradle.includedBuild('shared').task(':jar') } task gradlePluginJar { dependsOn gradle.includedBuild('kotlin-native-gradle-plugin').task(':shadowJar') } task gradlePluginCheck { dependsOn gradle.includedBuild('kotlin-native-gradle-plugin').task(':check') } task dist_compiler(dependsOn: "distCompiler") task dist_runtime(dependsOn: "distRuntime") task cross_dist(dependsOn: "crossDist") task list_dist(dependsOn: "listDist") task build { dependsOn ':dist', ':distPlatformLibs' } task distCommonSources(type: CopyCommonSources) { outputDir "$distDir/sources" sourcePaths configurations.kotlinCommonSources.files zipSources true } task distNativeSources(type: Zip) { destinationDirectory = file("$distDir/sources") archiveFileName = "kotlin-stdlib-native-sources.zip" includeEmptyDirs = false include('**/*.kt') from(project(':runtime').file('src/main/kotlin')) from(project(':Interop:Runtime').file('src/main/kotlin')) from(project(':Interop:Runtime').file('src/native/kotlin')) from(project(':Interop:JsRuntime').file('src/main/kotlin')) { into('kotlinx/wasm/jsinterop') } } task distEndorsedSources { dependsOn(':endorsedLibraries:endorsedLibsSources') } task distSources { dependsOn(distCommonSources) dependsOn(distNativeSources) dependsOn(distEndorsedSources) } task detectJarCollision(type: CollisionDetector) { configurations = [project.configurations.distPack] resolvingRules["META-INF/kotlin-util-klib.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/kotlin-util-io.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/descriptors.jvm.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/descriptors.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/descriptors.runtime.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/deserialization.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/metadata.jvm.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/metadata.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/type-system.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/util.runtime.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/kotlin-native-utils.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/compiler.common.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/compiler.common.jvm.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/deserialization.common.jvm.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/deserialization.common.kotlin_module"] = "kotlin-compiler" // These collisions are introduced by kotlinx-metadata-klib. resolvingRules["META-INF/serialization.kotlin_module"] = "kotlin-compiler" resolvingRules["META-INF/kotlin-util-klib-metadata.kotlin_module"] = "kotlin-compiler" resolvingRules["kotlin/annotation/annotation.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/collections/collections.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/coroutines/coroutines.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/internal/internal.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/kotlin.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/ranges/ranges.kotlin_builtins"] = "kotlin-compiler" resolvingRules["kotlin/reflect/reflect.kotlin_builtins"] = "kotlin-compiler" resolvingRules["META-INF/maven/com.google.protobuf/protobuf-java/pom.properties"] = "kotlin-compiler" resolvingRules["META-INF/maven/com.google.protobuf/protobuf-java/pom.xml"] = "kotlin-compiler" resolvingRules["org/jetbrains/kotlin/builtins/konan/KonanBuiltIns.class"] = "kotlin-compiler" resolvingRules["org/jetbrains/kotlin/resolve/konan/platform/NativeInliningRule.class"] = "kotlin-compiler" resolvingRules["org/jetbrains/kotlin/resolve/konan/platform/NativePlatformAnalyzerServices.class"] = "kotlin-compiler" resolvingRules["org/jetbrains/annotations/Nls.class"] = "kotlin-compiler" resolvingRules["META-INF/extensions/core.xml"] = "kotlin-compiler" librariesWithIgnoredClassCollisions.addAll(["kotlin-util-klib", "kotlin-util-io", "kotlinx-metadata-klib", "kotlin-native-utils"]) if (project.hasProperty('kotlinProjectPath')) { resolvingRulesWithRegexes[new Regex("META-INF/.+\\.kotlin_module")] = "kotlin-compiler" resolvingRules["META-INF/extensions/compiler.xml"] = "kotlin-compiler" resolvingRules["META-INF/compiler.version"] = "kotlin-compiler" resolvingRules["kotlinManifest.properties"] = "kotlin-compiler" librariesWithIgnoredClassCollisions.addAll(["util", "container", "resolution.common", "resolution", "serialization", "psi", "deserialization.common", "deserialization.common.jvm", "compiler.backend.common.jvm", "frontend", "config", "config.jvm", "js.config", "javac-wrapper", "frontend.common", "frontend.java", "cli-common", "ir.tree", "ir.tree.impl", "ir.tree.persisting", "ir.psi2ir", "ir.backend.common", "backend.jvm", "backend.js", "backend.wasm", "ir.serialization.common", "ir.serialization.js", "ir.serialization.jvm", "ir.interpreter", "jvm", "compiler.version", "backend-common", "backend", "plugin-api", "light-classes", "cli", "cli-js", "incremental-compilation-impl", "js.ast", "js.serializer", "js.parser", "js.frontend", "js.translator", "js.dce", "metadata", "metadata.jvm", "descriptors", "descriptors.jvm", "descriptors.runtime", "deserialization", "util.runtime", "compiler.common", "type-system", "cones", "resolve", "tree", "psi2fir", "fir2ir", "java", "kotlin-build-common", "lightTree", "jvm", "checkers", "raw-fir.common", "light-tree2fir", "cfg", "fir-serialization", "fir-deserialization", "entrypoint", "wasm.ir"]) } } task shadowJar(type: ShadowJar) { dependsOn ':detectJarCollision' mergeServiceFiles() destinationDirectory.set(file("$distDir/konan/lib")) archiveBaseName.set("kotlin-native") // Exclude trove4j because of license agreement. exclude "*trove4j*" exclude("META-INF/versions/9/module-info.class") configurations = [project.configurations.distPack] archiveClassifier.set(null) transform(CollisionTransformer.class) { resolvedConflicts = detectJarCollision.resolvedConflicts } } task distCompiler(type: Copy) { dependsOn ':shadowJar' destinationDir distDir from(project(':backend.native').file("build/nativelibs/$hostName")) { into('konan/nativelib') } from(project(':backend.native').file('build/external_jars/trove4j.jar')) { into('konan/lib') } from(project(':Interop').file('Indexer/build/nativelibs')) { into('konan/nativelib') } from(project(':Interop').file('Runtime/build/nativelibs')) { into('konan/nativelib') } from(project(':llvmCoverageMappingC').file('build/libs/coverageMapping/shared')) { into('konan/nativelib') } from(project(':llvmDebugInfoC').file('build/libs/debugInfo/shared')) { into('konan/nativelib') } from(project(':llvmDebugInfoC').file('src/scripts/konan_lldb.py')) { into('tools') } from(project(':utilities').file('env_blacklist')) { into('tools') } from(file('cmd')) { fileMode(0755) into('bin') if (!PlatformInfo.isWindows()) { exclude('**/*.bat') } } from(project.file('konan')) { into('konan') exclude('**/*.properties') } from(project.file('konan')) { into('konan') include('**/*.properties') filter(ReplaceTokens, tokens: [compilerVersion: konanVersionFull.toString()]) } if (experimentalEnabled) { file('konan/experimentalTargetsEnabled').text = "" } else { delete('konan/experimentalTargetsEnabled') } } task distDef(type: Copy) { destinationDir distDir platformManager.targetValues.each { target -> from(project("platformLibs").file("src/platform/${target.family.name().toLowerCase()}")) { into("konan/platformDef/${target.visibleName}") include '**/*.def' if (target in targetsWithoutZlib) { exclude '**/zlib.def' } } } } task listDist(type: Exec) { commandLine 'find', distDir } task distRuntime(type: Copy) { dependsOn "${hostName}CrossDistRuntime" } task distEndorsedLibraries { dependsOn "${hostName}CrossDistEndorsedLibraries" } task distStdlibCache { if (hostName in cacheableTargetNames) { dependsOn("${hostName}StdlibCache") } } task distEndorsedCache { if (hostName in cacheableTargetNames) { dependsOn("${hostName}EndorsedCache") } } def stdlib = 'klib/common/stdlib' def stdlibDefaultComponent = "$stdlib/default" def endorsedLibs = 'klib/common/endorsedLibraries' def endorsedLibsBase = 'klib/common' task crossDistRuntime(type: Copy) { dependsOn.addAll(targetList.collect { "${it}CrossDistRuntime" }) } task crossDistEndorsedLibraries(type: Copy) { dependsOn.addAll(targetList.collect { "${it}CrossDistEndorsedLibraries" }) } task crossDistPlatformLibs { dependsOn.addAll(targetList.collect { "${it}PlatformLibs" }) } task crossDistStdlibCache { dependsOn.addAll(targetList.findAll { it in cacheableTargetNames }.collect { "${it}StdlibCache" }) } task crossDistEndorsedCache { dependsOn.addAll(targetList.findAll { it in cacheableTargetNames }.collect { "${it}EndorsedCache" }) } targetList.each { target -> task("${target}CrossDistRuntime", type: Copy) { dependsOn ":runtime:${target}Runtime" dependsOn ":backend.native:${target}Stdlib" destinationDir distDir from(project(':runtime').file("build/${target}Stdlib")) { include('**') into(stdlib) eachFile { if (name == 'manifest') { def existingManifest = file("$destinationDir/$path") if (existingManifest.exists()) { UtilsKt.mergeManifestsByTargets(project, file, existingManifest) exclude() } } } } from(project(':runtime').file("build/bitcode/main/$target")) { include("runtime.bc") into("$stdlibDefaultComponent/targets/$target/native") } from(project(':runtime').file("build/bitcode/main/$target")) { include("*.bc") exclude("runtime.bc") into("konan/targets/$target/native") } if (target == 'wasm32') { into("$stdlibDefaultComponent/targets/wasm32/included") { from(project(':runtime').file('src/main/js')) from(project(':runtime').file('src/launcher/js')) from(project(':Interop:JsRuntime').file('src/main/js')) } } } task("${target}PlatformLibs") { dependsOn ":platformLibs:${target}Install" if (target in cacheableTargetNames) { dependsOn(":platformLibs:${target}Cache") } } if (target in cacheableTargetNames) { task "${target}StdlibCache" { dependsOn ":platformLibs:${target}StdlibCache" } task "${target}EndorsedCache" { dependsOn ":endorsedLibraries:${target}Cache" } } task("${target}CrossDist") { dependsOn "${target}CrossDistRuntime", "distCompiler", "${target}CrossDistEndorsedLibraries" if (target in cacheableTargetNames) { dependsOn "${target}StdlibCache", "${target}EndorsedCache" } } task("${target}CrossDistEndorsedLibraries", type: Copy) { dependsOn ":endorsedLibraries:${target}EndorsedLibraries" destinationDir distDir from(project(':endorsedLibraries').file("build")) { include('**') into("$endorsedLibsBase") } } } task distPlatformLibs { dependsOn ':platformLibs:hostInstall' dependsOn ':platformLibs:hostCache' } task dist { dependsOn "distCompiler", "distRuntime", "distEndorsedLibraries", "distDef", "distStdlibCache", "distEndorsedCache" } task crossDist { dependsOn "distCompiler", "crossDistRuntime", "crossDistEndorsedLibraries", "distDef", "crossDistStdlibCache", "crossDistEndorsedCache" } task bundle { dependsOn 'bundleRegular', 'bundlePrebuilt' } task bundleRegular(type: (isWindows()) ? Zip : Tar) { def simpleOsName = HostManager.simpleOsName() archiveBaseName.set("kotlin-native-$simpleOsName-$konanVersionFull") from("$project.rootDir/dist") { include '**' exclude 'dependencies' exclude 'klib/testLibrary' // Don't include platform libraries into the bundle (generate them at the user side instead). exclude 'klib/platform' // Exclude platform libraries caches too. Keep caches for stdlib and endorsed libs. exclude 'klib/cache/*/org.jetbrains.kotlin.native.platform.*/**' into archiveBaseName } from(project.rootDir) { include 'licenses/**' exclude '**/xcode_license.pdf' into archiveBaseName } } task bundlePrebuilt(type: (isWindows()) ? Zip : Tar) { dependsOn("crossDistPlatformLibs") def simpleOsName = HostManager.simpleOsName() archiveBaseName.set("kotlin-native-prebuilt-$simpleOsName-$konanVersionFull") from("$project.rootDir/dist") { include '**' exclude 'dependencies' exclude 'klib/testLibrary' into archiveBaseName } from(project.rootDir) { include 'licenses/**' into archiveBaseName } } configure([bundleRegular, bundlePrebuilt]) { dependsOn("crossDist") dependsOn("crossDistStdlibCache") dependsOn("crossDistEndorsedCache") dependsOn("distSources") dependsOn("distDef") from(project.rootDir) { include 'DISTRO_README.md' rename { return "README.md" } into baseName } from(project.rootDir) { include 'RELEASE_NOTES.md' into baseName } destinationDirectory.set(file('.')) if (isWindows()) { zip64 true } else { archiveExtension.set('tar.gz') compression = Compression.GZIP } } task 'tc-dist'(type: (isWindows()) ? Zip : Tar) { dependsOn('distPlatformLibs') dependsOn('dist') dependsOn('distSources') def simpleOsName = HostManager.simpleOsName() archiveBaseName.set("kotlin-native-dist-$simpleOsName-$konanVersionFull") from("$project.rootDir/dist") { include '**' exclude 'dependencies' into archiveBaseName } destinationDirectory.set(file('.')) if (isWindows()) { zip64 true } else { archiveExtension.set('tar.gz') compression = Compression.GZIP } } task samples { dependsOn 'samplesZip', 'samplesTar' } task samplesZip(type: Zip) task samplesTar(type: Tar) { extension = 'tar.gz' compression = Compression.GZIP } configure([samplesZip, samplesTar]) { baseName "kotlin-native-samples-$konanVersionFull" destinationDir = projectDir into(baseName) from(file('samples')) { // Process properties files separately. exclude '**/gradle.properties' } from(project.rootDir) { include 'licenses/**' } from(file('samples')) { include '**/gradle.properties' filter { it.startsWith('org.jetbrains.kotlin.native.home=') || it.startsWith('# Use custom Kotlin/Native home:') ? null : it } } // Exclude build artifacts. exclude '**/build' exclude '**/.gradle' exclude '**/.idea' exclude '**/*.kt.bc-build/' } project.tasks.register("copy_samples") { dependsOn 'copySamples' } project.tasks.register("copySamples", CopySamples) { destinationDir file('build/samples-under-test') } task uploadBundle { dependsOn ':bundle' if (isMac()) { dependsOn ':bundleRestricted' } doLast { def kind = (konanVersionFull.meta == MetaVersion.DEV) ? "dev" : "releases" def ftpSettings = [ server: project.findProperty("cdnUrl") ?: System.getenv("CDN_URL"), userid: project.findProperty("cdnUser") ?: System.getenv("CDN_USER"), password: project.findProperty("cdnPass") ?: System.getenv("CDN_PASS"), remoteDir: "/builds/$kind/$konanVersion/${HostManager.simpleOsName()}" ] ant { taskdef(name: 'ftp', classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP', classpath: configurations.ftpAntTask.asPath) ftp([action: "mkdir"] + ftpSettings) ftp(ftpSettings) { fileset(file: bundle.archivePath) } if (isMac()) { ftp(ftpSettings) { fileset(file: bundleRestricted.archivePath) } } } } } task teamcityCompilerVersion { doLast { println("##teamcity[setParameter name='kotlin.native.version.base' value='$konanVersion']") println("##teamcity[setParameter name='kotlin.native.version.full' value='$konanVersionFull']") println("##teamcity[setParameter name='kotlin.native.version.meta' value='${konanVersionFull.meta.toString().toLowerCase()}']") println("##teamcity[buildNumber '${konanVersionFull.toString(true, true)}']") } } task clean { dependsOn subprojects.collect { it.tasks.matching { it.name == "clean" } } doLast { delete distDir delete bundle.outputs.files delete "${projectDir}/compile_commands.json" } } task pusher(type: KotlinBuildPusher){ kotlinVersion = project.kotlinVersion konanVersion = CompilerVersionGeneratedKt.getCurrentCompilerVersion() buildServer = "buildserver.labs.intellij.net" compilerConfigurationId = System.getenv("TEAMCITY_COMPILER_ID") ?: "Kotlin_KotlinDev_Compiler" overrideConfigurationId = System.getenv("TEAMCITY_OVERRIDE_NATIVE_ID") ?: "Kotlin_KotlinDev_DeployMavenArtifacts_OverrideNative" token = project.findProperty("teamcityBearToken") ?: System.getenv("TEAMCITY_BEAR_TOKEN") } targetList.each { target -> CompilationDatabaseKt.mergeCompilationDatabases(project, "${target}CompilationDatabase".toString(), [ ":common:${target}CompilationDatabase".toString(), ":runtime:${target}CompilationDatabase".toString() ]).configure { outputFile = file("$buildDir/${target}/compile_commands.json") } } task compdb(type: Copy) { dependsOn "${hostName}CompilationDatabase" from "$buildDir/${hostName}/compile_commands.json" into "$projectDir" } targetList.each { targetName -> task "${targetName}CheckPlatformAbiCompatibility"(type: CompareDistributionSignatures) { dependsOn "${targetName}PlatformLibs" libraries = new CompareDistributionSignatures.Libraries.Platform(targetName) if (project.hasProperty("anotherDistro")) { oldDistribution = project.findProperty("anotherDistro") } onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL } } task "checkStdlibAbiCompatibility"(type: CompareDistributionSignatures) { dependsOn "distRuntime" libraries = CompareDistributionSignatures.Libraries.Standard.INSTANCE if (project.hasProperty("anotherDistro")) { oldDistribution = project.findProperty("anotherDistro") } onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL } ================================================ FILE: cmd/cinterop ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan cinterop "$@" ================================================ FILE: cmd/cinterop.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat cinterop %* ================================================ FILE: cmd/generate-platform ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan generatePlatformLibraries "$@" ================================================ FILE: cmd/generate-platform.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat generatePlatformLibraries %* ================================================ FILE: cmd/jsinterop ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan jsinterop "$@" ================================================ FILE: cmd/jsinterop.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat jsinterop %* ================================================ FILE: cmd/klib ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan klib "$@" ================================================ FILE: cmd/klib.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat klib %* ================================================ FILE: cmd/konan-lldb ================================================ #!/usr/bin/env bash # # Copyright 2010-2018 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DISTDIR=$(dirname $0)/.. exec lldb -o "command script import $DISTDIR/tools/konan_lldb.py" $* ================================================ FILE: cmd/konanc ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan konanc "$@" ================================================ FILE: cmd/konanc.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat konanc %* ================================================ FILE: cmd/kotlinc ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan kotlinc "$@" ================================================ FILE: cmd/kotlinc-native ================================================ #!/usr/bin/env bash # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. DIR="${BASH_SOURCE[0]%/*}" : ${DIR:="."} "${DIR}"/run_konan konanc "$@" ================================================ FILE: cmd/kotlinc-native.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat konanc %* ================================================ FILE: cmd/kotlinc.bat ================================================ @echo off rem Copyright 2010-2017 JetBrains s.r.o. rem rem Licensed under the Apache License, Version 2.0 (the "License"); rem you may not use this file except in compliance with the License. rem You may obtain a copy of the License at rem rem http://www.apache.org/licenses/LICENSE-2.0 rem rem Unless required by applicable law or agreed to in writing, software rem distributed under the License is distributed on an "AS IS" BASIS, rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. rem See the License for the specific language governing permissions and rem limitations under the License. call %~dps0run_konan.bat kotlinc %* ================================================ FILE: cmd/run_konan ================================================ #!/usr/bin/env bash # # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. TOOL_NAME="$1" shift if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then JAVACMD="$JAVA_HOME/bin/java" else JAVACMD=java fi [ -n "$JAVACMD" ] || JAVACMD=java declare -a java_args declare -a java_opts declare -a konan_args while [ $# -gt 0 ]; do case "$1" in -D*) java_args=("${java_args[@]}" "$1") shift ;; -J*) java_args=("${java_args[@]}" "${1:2}") shift ;; --time) konan_args=("${konan_args[@]}" --time) java_args=("${java_args[@]}" -Dkonan.profile=true) TIMECMD=time shift ;; *) konan_args[${#konan_args[@]}]=$1 shift ;; esac done findHome() { local source="${BASH_SOURCE[0]}" while [ -h "$source" ] ; do local linked="$(readlink "$source")" local dir="$(cd -P $(dirname "$source") && cd -P $(dirname "$linked") && pwd)" source="$dir/$(basename "$linked")" done (cd -P "$(dirname "$source")/.." && pwd) } KONAN_HOME="$(findHome)" java_opts=(-ea \ -Xmx3G \ -XX:TieredStopAtLevel=1 \ -Dfile.encoding=UTF-8 \ ${JAVA_OPTS}) # Unset some environment variables which are set by XCode and may potentially affect the tool executed. while IFS=$'\r' read -r line || [[ -n "$line" ]]; do unset $line done < "${KONAN_HOME}/tools/env_blacklist" KONAN_JAR="${KONAN_HOME}/konan/lib/kotlin-native.jar" TROVE_JAR="${KONAN_HOME}/konan/lib/trove4j.jar" KONAN_CLASSPATH="$KONAN_JAR:$TROVE_JAR" TOOL_CLASS=org.jetbrains.kotlin.cli.utilities.MainKt LIBCLANG_DISABLE_CRASH_RECOVERY=1 \ $TIMECMD "$JAVACMD" "${java_opts[@]}" "${java_args[@]}" -cp "$KONAN_CLASSPATH" "$TOOL_CLASS" "$TOOL_NAME" "${konan_args[@]}" ================================================ FILE: cmd/run_konan.bat ================================================ @echo off rem based on scalac.bat from the Scala distribution rem ########################################################################## rem # Copyright 2002-2011, LAMP/EPFL rem # Copyright 2011-2017, JetBrains rem # rem # This is free software; see the distribution for copying conditions. rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A rem # PARTICULAR PURPOSE. rem ########################################################################## setlocal enabledelayedexpansion call :set_home call :set_path set "TOOL_NAME=%1" shift if "%_TOOL_CLASS%"=="" set _TOOL_CLASS=org.jetbrains.kotlin.cli.utilities.MainKt if not "%JAVA_HOME%"=="" ( if exist "%JAVA_HOME%\bin\java.exe" set "_JAVACMD=%JAVA_HOME%\bin\java.exe" ) if "%_JAVACMD%"=="" set _JAVACMD=java set JAVA_ARGS= set KONAN_ARGS= :again set "ARG=%1" if not "!ARG!" == "" ( if "!ARG:~0,2!" == "-D" ( set "JAVA_ARGS=%JAVA_ARGS% %ARG%" goto next ) if "!ARG:~0,2!" == "-J" ( set "JAVA_ARGS=%JAVA_ARGS% !ARG:~2!" goto next ) if "!ARG!" == "--time" ( set "KONAN_ARGS=%KONAN_ARGS% --time" set "JAVA_ARGS=%JAVA_ARGS% -Dkonan.profile=true" goto next ) set "KONAN_ARGS=%KONAN_ARGS% %ARG%" :next shift goto again ) set "KONAN_LIB=%_KONAN_HOME%\konan\lib" set "KONAN_JAR=%KONAN_LIB%\kotlin-native.jar" set TROVE_JAR="%KONAN_LIB%\trove4j.jar" set "KONAN_CLASSPATH=%KONAN_JAR%;%TROVE_JAR%" set JAVA_OPTS=-ea ^ -Xmx3G ^ -XX:TieredStopAtLevel=1 ^ -Dfile.encoding=UTF-8 ^ %JAVA_OPTS% set LIBCLANG_DISABLE_CRASH_RECOVERY=1 "%_JAVACMD%" %JAVA_OPTS% %JAVA_ARGS% -cp "%KONAN_CLASSPATH%" %_TOOL_CLASS% %TOOL_NAME% %KONAN_ARGS% exit /b %ERRORLEVEL% goto end rem ########################################################################## rem # subroutines :set_home set _BIN_DIR= for %%i in (%~sf0) do set _BIN_DIR=%_BIN_DIR%%%~dpsi set _KONAN_HOME=%_BIN_DIR%.. goto :eof :set_path rem libclang.dll is dynamically linked and thus requires correct PATH to be loaded. rem TODO: remove this hack. if "%KONAN_DATA_DIR%"=="" (set KONAN_DATA_DIR=%USERPROFILE%\.konan) set "PATH=%KONAN_DATA_DIR%\dependencies\msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1\bin;%PATH%" goto :eof :end endlocal ================================================ FILE: codestyle/cpp/CLionFormat.xml ================================================ ================================================ FILE: codestyle/cpp/README.md ================================================ # Code style for C++ **TODO**: Expand beyond naming and formatting ## Headers * Headers should live in the same folder with it's implementation counterpart (if there's one) **TODO**: This does not work with multiple implementations of a single header. * Headers should use header guards * Headers that are designed to be included into both `.cpp`/`.mm` and `.c`/`.m` should have extension `.h` * Headers that are designed to be included into `.cpp`/`.mm` only should have extension `.hpp` ## Namespace usage * Do not use namespace blocks inside implementation files (`*.c`, `*.cpp`, `*.m`, `*.mm`). Use fully qualified names for definitions. * Do not use `extern "C"` blocks inside implementation files. ### Runtime-specific * Put main module inside `namespace kotlin` * Put other modules under `namespace kotlin` in a nested `namespace [module_name]` * Put implementation details inside `.h`/`.hpp` into a nested `namespace internal` (e.g. implementation details of module `mm` go into `namespace kotlin { namespace mm { namespace internal { ... } } }`) * Put implementation details inside `.cpp`/`.mm` into a global anonymous `namespace` * For `extern "C"` declarations emulate namespaces with `Kotlin_[module_name]_` prefixes. * To mark type as move-only, privately inherit from `kotlin::MoveOnly` * To mark type unmovable and uncopyable, privately inherit from `kotlin::Pinned` * All heap-allocated classes should publicly inherit from `KonanAllocatorAware` * Use `KStd*` containers and smart pointers instead of `std::*` ones. ## Naming * Types should use `PascalCase` * Local variables and function parameters should use `camelCase` * Global variables should use `camelCase` * Constants should use `kPascalCase` (with prefix `k`) * Private functions (not visible outside a compilation unit) should use `camelCase` * Exported functions (declared in headers or shared with Kotlin) should use `PascalCase` * Member fields should use `camelCase`. Private member fields should add `_` suffix: `camelCase_` * Member functions should use `camelCase` * Macros should use `SCREAMING_SNAKE_CASE` * namespaces should use `snake_case` * `enum` and `enum class` members should use `kPascalCase` If API is designed to mimic C++ stdlib (e.g. stubbing `` for platforms that do not support it), its allowed to follow stdlib naming conventions. ## Formatting For automated formatting you can use [config for CLion](codestyle/cpp/CLionFormat.xml) or `clang-format` (see [config](.clang-format) at the repo's root). Note, that CLion uses `clang-format` by default; this can be turned off if you prefer to use rules from `CLionFormat.xml`. Formatting rules are designed to closely mirror [Kotlin rules](https://kotlinlang.org/docs/reference/coding-conventions.html). * Use spaces instead of tabs. Indentation width is 4 spaces. Continuation width is 8 spaces * Do not indent namespaces * Visibility modifiers are placed without indentation * All operators should be wrapped with a space or a line break * In pointer and reference definitions `*` and `&` should be placed on a type instead of a variable * In pointer to functions prefer not to use `*` at all. * Add a space between `template` and `<` ================================================ FILE: common/build.gradle.kts ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ plugins { id("compile-to-bitcode") } bitcode { create("hash") create("files") } val hostName: String by project val build by tasks.registering { dependsOn("${hostName}Hash") dependsOn("${hostName}Files") } val clean by tasks.registering { doLast { delete(buildDir) } } ================================================ FILE: common/src/files/cpp/Files.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Files.h" #include #ifdef __APPLE__ bool renameAtomic(const char* from, const char* to, bool replaceExisting) { return renamex_np(from, to, replaceExisting ? 0 : RENAME_EXCL) == 0; } #elif _WIN32 #include bool renameAtomic(const char* from, const char* to, bool replaceExisting) { return MoveFileExA(from, to, replaceExisting ? MOVEFILE_REPLACE_EXISTING : 0) != 0; } #else #include #include #include bool renameAtomic(const char* from, const char* to, bool replaceExisting) { return syscall(SYS_renameat2, 0, from, 0, to, replaceExisting ? 0 : RENAME_NOREPLACE) == 0; } #endif ================================================ FILE: common/src/files/headers/Files.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef COMMON_FILES_H #define COMMON_FILES_H #include #ifdef __cplusplus extern "C" { #endif bool renameAtomic(const char* from, const char* to, bool replaceExisting); #ifdef __cplusplus } #endif #endif // COMMON_FILES_H ================================================ FILE: common/src/hash/cpp/Base64.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "Base64.h" namespace { // From https://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64 // with minor tweaks. #define WHITESPACE 64 #define EQUALS 65 #define INVALID 66 const char kAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const unsigned char kDecode[] = { 66,66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53, 54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28, 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, 66,66,66,66,66,66 }; } // namespace #ifdef __cplusplus extern "C" { #endif int EncodeBase64( const void* dataBuf, uint32_t dataLength, void* resultBuf, uint32_t resultSize) { char *result = reinterpret_cast(resultBuf); const uint8_t *data = reinterpret_cast(dataBuf); size_t resultIndex = 0; size_t x; uint32_t n = 0; int padCount = dataLength % 3; uint8_t n0, n1, n2, n3; /* increment over the length of the string, three characters at a time */ for (x = 0; x < dataLength; x += 3) { /* these three 8-bit (ASCII) characters become one 24-bit number */ n = ((uint32_t)data[x]) << 16; if ((x+1) < dataLength) n += ((uint32_t)data[x+1]) << 8; if ((x+2) < dataLength) n += data[x+2]; /* this 24-bit number gets separated into four 6-bit numbers */ n0 = (uint8_t)(n >> 18) & 63; n1 = (uint8_t)(n >> 12) & 63; n2 = (uint8_t)(n >> 6) & 63; n3 = (uint8_t)n & 63; /* * if we have one byte available, then its encoding is spread * out over two characters */ if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex++] = kAlphabet[n0]; if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex++] = kAlphabet[n1]; /* * if we have only two bytes available, then their encoding is * spread out over three chars */ if ((x+1) < dataLength) { if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex++] = kAlphabet[n2]; } /* * if we have all three bytes available, then their encoding is spread * out over four characters */ if ((x+2) < dataLength) { if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex++] = kAlphabet[n3]; } } /* * create and add padding that is required if we did not have a multiple of 3 * number of characters available */ if (padCount > 0) { for (; padCount < 3; padCount++) { if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex++] = '='; } } if (resultIndex >= resultSize) return 1; /* indicate failure: buffer too small */ result[resultIndex] = 0; return 0; /* indicate success */ } int DecodeBase64( const char *in, uint32_t inLen, void* outBuf, uint32_t* outLen) { uint8_t* out = reinterpret_cast(outBuf); const char* end = in + inLen; char iter = 0; size_t buf = 0, len = 0; while (in < end) { // char may be a signed type. Explicitly convert it to an unsigned byte, // so that indexing into kDecode array is safe. The latter has exactly // 256 elements, so any unsigned byte value is valid. uint8_t index = *in++; unsigned char c = kDecode[index]; switch (c) { case WHITESPACE: continue; /* skip whitespace */ case INVALID: return 1; /* invalid input, return error */ case EQUALS: /* pad character, end of data */ in = end; continue; default: buf = buf << 6 | c; iter++; // increment the number of iteration /* If the buffer is full, split it into bytes */ if (iter == 4) { if ((len += 3) > *outLen) return 1; /* buffer overflow */ *(out++) = (buf >> 16) & 255; *(out++) = (buf >> 8) & 255; *(out++) = buf & 255; buf = 0; iter = 0; } } } if (iter == 3) { if ((len += 2) > *outLen) return 1; /* buffer overflow */ *(out++) = (buf >> 10) & 255; *(out++) = (buf >> 2) & 255; } else if (iter == 2) { if (++len > *outLen) return 1; /* buffer overflow */ *(out++) = (buf >> 4) & 255; } *outLen = len; /* modify to reflect the actual output size */ return 0; } #ifdef __cplusplus } #endif ================================================ FILE: common/src/hash/cpp/City.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "City.h" #include #include namespace { // Some primes between 2^63 and 2^64 for various uses. static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; static const uint64_t k1 = 0xb492b66fbe98f273ULL; static const uint64_t k2 = 0x9ae16a3b2f90404fULL; uint64_t UNALIGNED_LOAD64(const char *p) { uint64_t result; memcpy(&result, p, sizeof(result)); return result; } uint32_t UNALIGNED_LOAD32(const char *p) { uint32_t result; memcpy(&result, p, sizeof(result)); return result; } #define bswap32(x) __builtin_bswap32(x) #define bswap64(x) __builtin_bswap64(x) #ifdef WORDS_BIGENDIAN #define uint32_in_expected_order(x) (bswap32(x)) #define uint64_in_expected_order(x) (bswap64(x)) #else #define uint32_in_expected_order(x) (x) #define uint64_in_expected_order(x) (x) #endif uint64_t Fetch64(const char *p) { return uint64_in_expected_order(UNALIGNED_LOAD64(p)); } uint32_t Fetch32(const char *p) { return uint32_in_expected_order(UNALIGNED_LOAD32(p)); } // Bitwise right rotate. Normally this will compile to a single // instruction, especially if the shift is a manifest constant. uint64_t Rotate(uint64_t val, int shift) { // Avoid shifting by 64: doing so yields an undefined result. return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); } uint64_t ShiftMix(uint64_t val) { return val ^ (val >> 47); } uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) { // Murmur-inspired hashing. uint64_t a = (u ^ v) * mul; a ^= (a >> 47); uint64_t b = (v ^ a) * mul; b ^= (b >> 47); b *= mul; return b; } typedef std::pair uint128_t; uint64_t Hash128to64(const uint128_t& x) { // Murmur-inspired hashing. const uint64_t kMul = 0x9ddfea08eb382d69ULL; uint64_t a = (x.first ^ x.second) * kMul; a ^= (a >> 47); uint64_t b = (x.second ^ a) * kMul; b ^= (b >> 47); b *= kMul; return b; } uint64_t HashLen16(uint64_t u, uint64_t v) { return Hash128to64(uint128_t(u, v)); } uint64_t HashLen0to16(const char *s, size_t len) { if (len >= 8) { uint64_t mul = k2 + len * 2; uint64_t a = Fetch64(s) + k2; uint64_t b = Fetch64(s + len - 8); uint64_t c = Rotate(b, 37) * mul + a; uint64_t d = (Rotate(a, 25) + b) * mul; return HashLen16(c, d, mul); } if (len >= 4) { uint64_t mul = k2 + len * 2; uint64_t a = Fetch32(s); return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul); } if (len > 0) { uint8_t a = s[0]; uint8_t b = s[len >> 1]; uint8_t c = s[len - 1]; uint32_t y = static_cast(a) + (static_cast(b) << 8); uint32_t z = len + (static_cast(c) << 2); return ShiftMix(y * k2 ^ z * k0) * k2; } return k2; } // This probably works well for 16-byte strings as well, but it may be overkill // in that case. static uint64_t HashLen17to32(const char *s, size_t len) { uint64_t mul = k2 + len * 2; uint64_t a = Fetch64(s) * k1; uint64_t b = Fetch64(s + 8); uint64_t c = Fetch64(s + len - 8) * mul; uint64_t d = Fetch64(s + len - 16) * k2; return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d, a + Rotate(b + k2, 18) + c, mul); } // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. std::pair WeakHashLen32WithSeeds( uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; b = Rotate(b + a + z, 21); uint64_t c = a; a += x; a += y; b += Rotate(a, 44); return std::make_pair(a + z, b + c); } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. std::pair WeakHashLen32WithSeeds( const char* s, uint64_t a, uint64_t b) { return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), Fetch64(s + 24), a, b); } // Return an 8-byte hash for 33 to 64 bytes. uint64_t HashLen33to64(const char *s, size_t len) { uint64_t mul = k2 + len * 2; uint64_t a = Fetch64(s) * k2; uint64_t b = Fetch64(s + 8); uint64_t c = Fetch64(s + len - 24); uint64_t d = Fetch64(s + len - 32); uint64_t e = Fetch64(s + 16) * k2; uint64_t f = Fetch64(s + 24) * 9; uint64_t g = Fetch64(s + len - 8); uint64_t h = Fetch64(s + len - 16) * mul; uint64_t u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; uint64_t v = ((a + g) ^ d) + f + 1; uint64_t w = bswap64((u + v) * mul) + h; uint64_t x = Rotate(e + f, 42) + c; uint64_t y = (bswap64((v + w) * mul) + g) * mul; uint64_t z = e + f + c; a = bswap64((x + z) * mul + y) + b; b = ShiftMix((z + a) * mul + d + h) * mul; return b + x; } } // namespace extern "C" { uint64_t CityHash64(const void* data, size_t len) { const char* s = reinterpret_cast(data); if (len <= 32) { if (len <= 16) { return HashLen0to16(s, len); } else { return HashLen17to32(s, len); } } else if (len <= 64) { return HashLen33to64(s, len); } // For strings over 64 bytes we hash the end first, and then as we // loop we keep 56 bytes of state: v, w, x, y, and z. uint64_t x = Fetch64(s + len - 40); uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); std::pair v = WeakHashLen32WithSeeds(s + len - 64, len, z); std::pair w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. len = (len - 1) & ~static_cast(63); do { x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1; y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1; x ^= w.second; y += v.first + Fetch64(s + 40); z = Rotate(z + w.first, 33) * k1; v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first); w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16)); std::swap(z, x); s += 64; len -= 64; } while (len != 0); return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z, HashLen16(v.second, w.second) + x); } } // extern "C" ================================================ FILE: common/src/hash/cpp/Names.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "Names.h" #include "Base64.h" #include "City.h" #include "Sha1.h" namespace { constexpr uint32_t PrintableBase64Size(uint32_t input_length) { return ((input_length + 2) / 3 * 4) + 1; } void PrintableBase64(const uint8_t* data, uint32_t data_length, char* base64) { int rv = EncodeBase64(data, data_length, base64, PrintableBase64Size(data_length)); assert(rv == 0); } } // namespace extern "C" { // Make local hash out of arbitrary data. void MakeLocalHash(const void* data, uint32_t size, LocalHash* hash) { *hash = CityHash64(data, size); } // Make global hash out of arbitrary data. void MakeGlobalHash(const void* data, uint32_t size, GlobalHash* hash) { SHA1_CTX ctx; SHA1Init(&ctx); SHA1Update(&ctx, reinterpret_cast(data), size); SHA1Final(&hash->bits[0], &ctx); } // Make printable C string out of local hash. void PrintableLocalHash(const LocalHash* hash, char* buffer, uint32_t size) { if (size < PrintableBase64Size(sizeof(*hash))) { assert(false); return; } PrintableBase64(reinterpret_cast(&hash), sizeof(*hash), buffer); } // Make printable C string out of global hash. void PrintableGlobalHash(const GlobalHash* hash, char* buffer, uint32_t size) { if (size < PrintableBase64Size(sizeof(*hash))) { assert(false); return; } PrintableBase64(hash->bits, sizeof(*hash), buffer); } } // extern "C" ================================================ FILE: common/src/hash/cpp/Sha1.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* SHA-1 in C By Steve Reid 100% Public Domain Test Vectors (from FIPS PUB 180-1) "abc" A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 A million repetitions of "a" 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ /* #define SHA1HANDSOFF * Copies data before messing with it. */ #define SHA1HANDSOFF #include #include #include #include "Sha1.h" #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #if BYTE_ORDER == LITTLE_ENDIAN #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |(rol(block->l[i],8)&0x00FF00FF)) #elif BYTE_ORDER == BIG_ENDIAN #define blk0(i) block->l[i] #else #error "Endianness not defined!" #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); /* Hash a single 512-bit block. This is the core of the algorithm. */ static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) { uint32_t a, b, c, d, e; typedef union { unsigned char c[64]; uint32_t l[16]; } CHAR64LONG16; #ifdef SHA1HANDSOFF CHAR64LONG16 block[1]; /* use array to appear as a pointer */ memcpy(block, buffer, 64); #else /* The following had better never be used because it causes the * pointer-to-const buffer to be cast into a pointer to non-const. * And the result is written through. I threw a "const" in, hoping * this will cause a diagnostic. */ CHAR64LONG16* block = (const CHAR64LONG16*)buffer; #endif /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; #ifdef SHA1HANDSOFF memset(block, '\0', sizeof(block)); #endif } #ifdef __cplusplus extern "C" { #endif /* SHA1Init - Initialize new context */ void SHA1Init(SHA1_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) { uint32_t i, j; j = context->count[0]; if ((context->count[0] += len << 3) < j) context->count[1]++; context->count[1] += (len>>29); j = (j >> 3) & 63; if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); SHA1Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1Transform(context->state, &data[i]); } j = 0; } else i = 0; memcpy(&context->buffer[j], &data[i], len - i); } /* Add padding and return the message digest. */ void SHA1Final(unsigned char digest[20], SHA1_CTX* context) { unsigned i; unsigned char finalcount[8]; unsigned char c; for (i = 0; i < 8; i++) { finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } c = 0200; SHA1Update(context, &c, 1); while ((context->count[0] & 504) != 448) { c = 0000; SHA1Update(context, &c, 1); } SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ for (i = 0; i < 20; i++) { digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ memset(context, '\0', sizeof(*context)); memset(&finalcount, '\0', sizeof(finalcount)); } #ifdef __cplusplus } #endif ================================================ FILE: common/src/hash/headers/Base64.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COMMON_BASE64_H #define COMMON_BASE64_H #include #ifdef __cplusplus extern "C" { #endif int EncodeBase64( const void* input, uint32_t inputLen, void* output, uint32_t outputLen); int DecodeBase64( const char* input, uint32_t inputLen, void* output, uint32_t* outputLen); #ifdef __cplusplus } #endif #endif // COMMON_BASE64_H ================================================ FILE: common/src/hash/headers/City.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COMMON_CITY_H #define COMMON_CITY_H // CityHash, by Geoff Pike and Jyrki Alakuijala. #include #include #ifdef __cplusplus extern "C" { #endif // Hash function for a byte array. uint64_t CityHash64(const void* buf, size_t len); #ifdef __cplusplus } #endif #endif // COMMON_CITY_H ================================================ FILE: common/src/hash/headers/Names.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COMMON_NAMES_H #define COMMON_NAMES_H #include // All names in system are stored as hashes (or maybe, for debug builds, // as pointers to uniqued C strings containing names?). // There are two types of hashes: // - local hash, must be unique per class/scope (CityHash64 is being used) // - global hash, must be unique globally (SHA1 is being used) // Generic guideline is that global hash is being used in global persistent // context, while local hashes are more local in scope. // Local hash. typedef int64_t LocalHash; // Hash of field name. typedef LocalHash FieldNameHash; // Hash of open method name. typedef LocalHash MethodNameHash; // Global hash. typedef struct { uint8_t bits[20]; } GlobalHash; // Hash of function name. typedef GlobalHash FunctionNameHash; // Hash of class name. typedef GlobalHash ClassNameHash; #ifdef __cplusplus extern "C" { #endif // Make local hash out of arbitrary data. void MakeLocalHash(const void* data, uint32_t size, LocalHash* hash); // Make global hash out of arbitrary data. void MakeGlobalHash(const void* data, uint32_t size, GlobalHash* hash); // Make printable C string out of local hash. void PrintableLocalHash(const LocalHash* hash, char* buffer, uint32_t size); // Make printable C string out of global hash. void PrintableGlobalHash(const GlobalHash* hash, char* buffer, uint32_t size); #ifdef __cplusplus } // extern "C" #endif #endif // COMMON_NAMES_H ================================================ FILE: common/src/hash/headers/Sha1.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef COMMON_SHA1_H #define COMMON_SHA1_H #include /* SHA-1 in C By Steve Reid 100% Public Domain */ #ifdef __cplusplus extern "C" { #endif typedef struct SHA1_CTX { uint32_t state[5]; uint32_t count[2]; unsigned char buffer[64]; } SHA1_CTX; void SHA1Init(SHA1_CTX* context); void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); void SHA1Final(unsigned char digest[20], SHA1_CTX* context); #ifdef __cplusplus } #endif #endif // COMMON_SHA1_H ================================================ FILE: dependencies/build.gradle ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import groovy.transform.stc.ClosureParams import groovy.transform.stc.FromString import org.jetbrains.kotlin.konan.target.* import static org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.util.Named import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader import org.jetbrains.kotlin.konan.util.ArchiveType import org.jetbrains.kotlin.konan.util.DependencyProcessor import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.getVisibleName buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" repositories { maven { url = 'https://cache-redirector.jetbrains.com/jcenter' } } } /** * Downloads dependencies from the given URL into the given directory. * The set of dependencies is determined by konanPropertiesLoader. */ class NativeDep extends DefaultTask { static final String baseUrl = "https://cache-redirector.jetbrains.com/download.jetbrains.com/kotlin/native" KonanPropertiesLoader konanPropertiesLoader = null final File getBaseOutDir() { final File res = project.rootProject.ext.dependenciesDir res.mkdirs() return res } @TaskAction void downloadAndExtract() { def downloader = new DependencyProcessor(baseOutDir, konanPropertiesLoader, baseUrl, false, ArchiveType.systemDefault) downloader.showInfo = false downloader.run() } } enum DependencyKind { LLVM( "llvm", { it.llvmHome }, { "llvmDir" } ), LIBFFI( "libffi", { it.libffiDir } ) DependencyKind(String name, @ClosureParams(value = FromString.class, options = "KonanPropertiesLoader") Closure dirGetter, @ClosureParams(value = FromString.class, options = "KonanTarget") Closure propertyNameGetter = {target -> "${target.visibleName}${name.capitalize()}Dir"}) { this.name = name this.dirGetter = dirGetter this.propertyNameGetter = propertyNameGetter } private String name private Closure dirGetter // KonanProperties -> String private Closure propertyNameGetter // KonanTarget -> String String getDirectory(KonanPropertiesLoader properties) { return dirGetter(properties) } String getPropertyName(KonanTarget target) { return propertyNameGetter(target) } String toString() { return name } } def platformManager = rootProject.ext.platformManager platformManager.enabled.each { target -> def loader = platformManager.loader(target) task "${target}Dependencies"(type: NativeDep) { konanPropertiesLoader = loader } // Also resolves all dependencies: final DependencyProcessor dependencyProcessor = new DependencyProcessor( project.rootProject.ext.dependenciesDir, loader.properties, loader.dependencies, NativeDep.baseUrl, false, ArchiveType.systemDefault ) DependencyKind.values().each { kind -> def dir = kind.getDirectory(loader) if (dir != null) { String path = dependencyProcessor.resolve(dir).canonicalPath rootProject.ext.set(kind.getPropertyName(target), path) } } } task update(type: Copy) { dependsOn tasks.withType(NativeDep) } task rmDotKonan(type: Delete) { def dir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan" delete dir } ================================================ FILE: dependencyPacker/build.gradle.kts ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader import org.jetbrains.kotlin.konan.util.DependencyProcessor import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.presetName /** * Creates an archive with LLVM distribution without files * that are not required for Kotlin/Native. * * For example, it excludes binaries that are part of LLVM testing infrastructure. */ inline fun createLlvmPackingTask( host: KonanTarget, whitelist: File?, blacklist: File?, crossinline additionalConfiguration: T.() -> Unit ) { val distribution = Distribution(rootProject.projectDir.absolutePath) val reducedLlvmAppendix = distribution.properties .getProperty("reducedLlvmAppendix") val propertiesLoader = object : KonanPropertiesLoader( host = host, target = host, properties = distribution.properties, baseDir = DependencyProcessor.defaultDependenciesRoot.absolutePath ) {} val hostName = host.presetName.capitalize() val downloadTaskName = "downloadLlvmFor$hostName" tasks.create(downloadTaskName) { doFirst { propertiesLoader.downloadDependencies() } } tasks.create("packLlvmFor$hostName") { dependsOn(downloadTaskName) additionalConfiguration() description = "Packs LLVM dependency for $hostName into archive" group = "Distribution packing" // > When both inclusion and exclusion are used, // > only files/directories that match at least one of the include patterns // > and don't match any of the exclude patterns are used. // // See: https://ant.apache.org/manual/dirtasks.html whitelist?.let { it.readLines() .filter { !it.startsWith("#") && it.isNotBlank() } .forEach(this::include) } blacklist?.let { it.readLines() .filter { !it.startsWith("#") && it.isNotBlank() } .forEach(this::exclude) } from(propertiesLoader.absoluteLlvmHome) destinationDirectory.set(buildDir.resolve("artifacts")) archiveBaseName.set(propertiesLoader.llvmHome) archiveAppendix.set(reducedLlvmAppendix) } } createLlvmPackingTask( KonanTarget.MACOS_X64, whitelist = file("macos_llvm_whitelist"), blacklist = null ) { compression = Compression.GZIP } createLlvmPackingTask( KonanTarget.LINUX_X64, whitelist = file("linux_llvm_whitelist"), blacklist = file("linux_llvm_blacklist") ) { compression = Compression.GZIP } createLlvmPackingTask( KonanTarget.MINGW_X64, whitelist = file("mingw_llvm_whitelist"), blacklist = file("mingw_llvm_blacklist") ) {} ================================================ FILE: dependencyPacker/linux_llvm_blacklist ================================================ # Unused large files lib/liblldb.so lib/liblldb.so.8 lib/libLTO.so lib/libLTO.so.8 lib/python2.7/site-packages/lldb/_lldb.so ================================================ FILE: dependencyPacker/linux_llvm_whitelist ================================================ # Compilation process bin/clang bin/clang++ bin/clang-8 # Linkage bin/dsymutil bin/lld bin/ld.lld bin/wasm-ld bin/llvm-ar # Useful utility bin/llvm-dis bin/c-index-test bin/llvm-config # Coverage support bin/llvm-cov bin/llvm-profdata # Used to link runtime files bin/llvm-link include/** lib/** libexec/** share/** ================================================ FILE: dependencyPacker/macos_llvm_whitelist ================================================ # Compilation process bin/clang bin/clang++ bin/clang-8 # Linkage bin/dsymutil bin/lld bin/ld.lld bin/wasm-ld bin/llvm-ar # Useful utility bin/llvm-dis bin/c-index-test bin/llvm-config # Coverage support bin/llvm-cov bin/llvm-profdata # Used to link runtime files bin/llvm-link include/** lib/** libexec/** local/** share/** ================================================ FILE: dependencyPacker/mingw_llvm_blacklist ================================================ lib/gcc/x86_64-w64-mingw32/9.2.0/cc1plus.exe lib/gcc/x86_64-w64-mingw32/9.2.0/plugin/cc1.exe.a lib/gcc/x86_64-w64-mingw32/9.2.0/plugin/cc1plus.exe.a lib/gcc/x86_64-w64-mingw32/9.2.0/lto1.exe lib/gcc/x86_64-w64-mingw32/9.2.0/cc1.exe ================================================ FILE: dependencyPacker/mingw_llvm_whitelist ================================================ # Compilation process bin/clang.exe bin/clang++.exe bin/clang-8.exe # Linkage bin/lld.exe bin/ld.lld.exe bin/wasm-ld.exe bin/llvm-ar.exe # Useful utility bin/llvm-dis.exe bin/llvm-config.exe # Coverage support bin/llvm-cov.exe bin/llvm-profdata.exe # Used to link runtime files bin/llvm-link.exe # Used for samples bin/windres.exe # Used by other binaries bin/zlib1.dll bin/libwinpthread-1.dll bin/libgcc_s_seh-1.dll bin/libstdc++-6.dll bin/libz3.dll include/** lib/** etc/** local/** share/** x86_64-w64-mingw32/** libclang.dll ================================================ FILE: endorsedLibraries/build.gradle ================================================ import org.jetbrains.kotlin.UtilsKt import org.jetbrains.kotlin.gradle.plugin.konan.tasks.KonanCacheTask import org.jetbrains.kotlin.EndorsedLibraryInfo buildscript { repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:$gradlePluginVersion" } } ext { endorsedLibraries = [ new EndorsedLibraryInfo(project('kotlinx.cli'), "org.jetbrains.kotlinx.kotlinx-cli") ].collectEntries { [it.project, it] } } Collection endorsedLibrariesList = ext.endorsedLibraries.values() task clean { doLast { delete buildDir } } task jvmJar { endorsedLibrariesList.each { library -> dependsOn "$library.projectName:jvmJar" } } // Build all default libraries. targetList.each { target -> task("${target}EndorsedLibraries", type: Copy) { endorsedLibrariesList.each { library -> dependsOn "$library.projectName:${target}${library.taskName}" } destinationDir project.buildDir endorsedLibrariesList.each { library -> from(library.project.file("build/${target}${library.taskName}")) { include('**') into(library.name) eachFile { if (name == 'manifest') { def existingManifest = file("$destinationDir/$path") if (existingManifest.exists()) { UtilsKt.mergeManifestsByTargets(project, file, existingManifest) exclude() } } } } } } if (target in cacheableTargetNames) { def cacheTask = task("${target}Cache") endorsedLibrariesList.each { library -> def dist = rootProject.file("dist") task("${target}${library.taskName}Cache", type: KonanCacheTask) { it.target = target originalKlib = file("${project.buildDir}/${library.name}") cacheRoot = file("$dist/klib/cache") compilerDistributionPath.set(distDir) dependsOn "${target}EndorsedLibraries" dependsOn ":${target}CrossDistRuntime" dependsOn ":${target}StdlibCache" cacheTask.dependsOn it } } } } endorsedLibrariesList.each { library -> task("${library.taskName}CommonSources", type: Zip) { destinationDirectory = file("${rootProject.projectDir}/dist/sources") archiveFileName = "${library.name}-common-sources.zip" includeEmptyDirs = false include('**/*.kt') from(library.project.file('src/main/kotlin')) } task("${library.taskName}NativeSources", type: Zip) { destinationDirectory = file("${rootProject.projectDir}/dist/sources") archiveFileName = "${library.name}-native-sources.zip" includeEmptyDirs = false include('**/*.kt') from(library.project.file('src/main/kotlin-native')) } } task endorsedLibsSources { endorsedLibrariesList.each { library -> dependsOn "${library.taskName}CommonSources" dependsOn "${library.taskName}NativeSources" } } ================================================ FILE: endorsedLibraries/kotlinx.cli/build.gradle ================================================ import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.util.PlatformLibsInfo buildscript { repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } apply plugin: 'kotlin-multiplatform' repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } maven { url buildKotlinCompilerRepo } } kotlin { sourceSets { commonMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" } kotlin.srcDir 'src/main/kotlin' } commonTest { dependencies { implementation "org.jetbrains.kotlin:kotlin-test-common:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlinVersion" } kotlin.srcDir 'src/tests' } jvm().compilations.main.defaultSourceSet { dependencies { implementation kotlin('stdlib-jdk8') } kotlin.srcDir 'src/main/kotlin-jvm' } // JVM-specific tests and their dependencies: jvm().compilations.test.defaultSourceSet { dependencies { implementation kotlin('test-junit') } } jvm().compilations.all { kotlinOptions { freeCompilerArgs = ["-Xopt-in=kotlinx.cli.ExperimentalCli", "-Xopt-in=kotlin.RequiresOptIn"] suppressWarnings = true } } } } def commonSrc = new File("$projectDir/src/main/kotlin") def nativeSrc = new File("$projectDir/src/main/kotlin-native") targetList.each { target -> def konanJvmArgs = [*HostManager.regularJvmArgs] def defaultArgs = ['-nopack', '-no-default-libs', '-no-endorsed-libs'] if (target != "wasm32") defaultArgs += '-g' def konanArgs = [*defaultArgs, '-target', target, "-Xruntime=${project(':runtime').file('build/bitcode/main/' + target + '/runtime.bc')}", *project.globalBuildArgs] task("${target}KotlinxCli", type: JavaExec) { def outputFile = project.file("build/${target}KotlinxCli") // See :endorsedLibraries.ext for full endorsedLibraries list. def moduleName = endorsedLibraries[project].name dependsOn ":distCompiler" dependsOn ":${target}CrossDistRuntime" main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' // This task depends on distCompiler, so the compiler jar is already in the dist directory. classpath = fileTree("${rootProject.projectDir}/dist/konan/lib") { include "*.jar" } jvmArgs = konanJvmArgs args = [*konanArgs, '-output', outputFile, '-produce', 'library', '-module-name', moduleName, '-Xmulti-platform', '-Xopt-in=kotlinx.cli.ExperimentalCli', '-Xopt-in=kotlin.ExperimentalMultiplatform', '-Xallow-result-return-type', '-Werror', '-Xopt-in=kotlin.RequiresOptIn', commonSrc.absolutePath, "-Xcommon-sources=${commonSrc.absolutePath}", nativeSrc] inputs.dir(nativeSrc) inputs.dir(commonSrc) outputs.dir(outputFile) } } ================================================ FILE: endorsedLibraries/kotlinx.cli/gradle.properties ================================================ org.jetbrains.kotlin.native.home=../../dist org.jetbrains.kotlin.native.jvmArgs=-Xmx6G ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/ArgParser.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli import kotlin.reflect.KProperty internal expect fun exitProcess(status: Int): Nothing /** * Queue of arguments descriptors. * Arguments can have several values, so one descriptor can be returned several times. */ internal class ArgumentsQueue(argumentsDescriptors: List>) { /** * Map of arguments descriptors and their current usage number. */ private val argumentsUsageNumber = linkedMapOf(*argumentsDescriptors.map { it to 0 }.toTypedArray()) /** * Get next descriptor from queue. */ fun pop(): String? { if (argumentsUsageNumber.isEmpty()) return null val (currentDescriptor, usageNumber) = argumentsUsageNumber.iterator().next() currentDescriptor.number?.let { // Parse all arguments for current argument description. if (usageNumber + 1 >= currentDescriptor.number) { // All needed arguments were provided. argumentsUsageNumber.remove(currentDescriptor) } else { argumentsUsageNumber[currentDescriptor] = usageNumber + 1 } } return currentDescriptor.fullName } } /** * A property delegate that provides access to the argument/option value. */ interface ArgumentValueDelegate { /** * The value of an option or argument parsed from command line. * * Accessing this value before [ArgParser.parse] method is called will result in an exception. * * @see CLIEntity.value */ var value: T /** Provides the value for the delegated property getter. Returns the [value] property. * @throws IllegalStateException in case of accessing the value before [ArgParser.parse] method is called. */ operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value /** Sets the [value] to the [ArgumentValueDelegate.value] property from the delegated property setter. * This operation is possible only after command line arguments were parsed with [ArgParser.parse] * @throws IllegalStateException in case of resetting value before command line arguments are parsed. */ operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { this.value = value } } /** * Abstract base class for subcommands. */ @ExperimentalCli abstract class Subcommand(val name: String, val actionDescription: String): ArgParser(name) { /** * Execute action if subcommand was provided. */ abstract fun execute() val helpMessage: String get() = " $name - $actionDescription\n" } /** * Argument parsing result. * Contains name of subcommand which was called. * * @property commandName name of command which was called. */ class ArgParserResult(val commandName: String) /** * Arguments parser. * * @property programName the name of the current program. * @property useDefaultHelpShortName specifies whether to register "-h" option for printing the usage information. * @property prefixStyle the style of option prefixing. * @property skipExtraArguments specifies whether the extra unmatched arguments in a command line string * can be skipped without producing an error message. */ open class ArgParser( val programName: String, var useDefaultHelpShortName: Boolean = true, var prefixStyle: OptionPrefixStyle = OptionPrefixStyle.LINUX, var skipExtraArguments: Boolean = false ) { /** * Map of options: key - full name of option, value - pair of descriptor and parsed values. */ private val options = mutableMapOf>() /** * Map of arguments: key - full name of argument, value - pair of descriptor and parsed values. */ private val arguments = mutableMapOf>() /** * Map with declared options. */ private val declaredOptions = mutableListOf() /** * Map with declared arguments. */ private val declaredArguments = mutableListOf() /** * State of parser. Stores last parsing result or null. */ private var parsingState: ArgParserResult? = null /** * Map of subcommands. */ @OptIn(ExperimentalCli::class) protected val subcommands = mutableMapOf() /** * Mapping for short options names for quick search. */ private val shortNames = mutableMapOf>() /** * Used prefix form for full option form. */ protected val optionFullFormPrefix = if (prefixStyle == OptionPrefixStyle.JVM) "-" else "--" /** * Used prefix form for short option form. */ protected val optionShortFromPrefix = "-" /** * Name with all commands that should be executed. */ protected val fullCommandName = mutableListOf(programName) /** * Flag to recognize if CLI entities can be treated as options. */ protected var treatAsOption = true /** * Arguments which should be parsed with subcommands. */ private val subcommandsArguments = mutableListOf() /** * Options which should be parsed with subcommands. */ private val subcommandsOptions = mutableListOf() /** * Subcommand used in commmand line arguments. */ private var usedSubcommand: Subcommand? = null /** * The way an option/argument has got its value. */ enum class ValueOrigin { /* The value was parsed from command line arguments. */ SET_BY_USER, /* The value was missing in command line, therefore the default value was used. */ SET_DEFAULT_VALUE, /* The value is not initialized by command line values or by default values. */ UNSET, /* The value was redefined after parsing manually (usually with the property setter). */ REDEFINED, /* The value is undefined, because parsing wasn't called. */ UNDEFINED } /** * The style of option prefixing. */ enum class OptionPrefixStyle { /* Linux style: the full name of an option is prefixed with two hyphens "--" and the short name — with one "-". */ LINUX, /* JVM style: both full and short names are prefixed with one hyphen "-". */ JVM, /* GNU style: the full name of an option is prefixed with two hyphens "--" and "=" between options and value and the short name — with one "-". Detailed information https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html */ GNU } @Deprecated("OPTION_PREFIX_STYLE is deprecated. Please, use OptionPrefixStyle.", ReplaceWith("OptionPrefixStyle", "kotlinx.cli.OptionPrefixStyle")) @Suppress("TOPLEVEL_TYPEALIASES_ONLY") typealias OPTION_PREFIX_STYLE = OptionPrefixStyle /** * Declares a named option and returns an object which can be used to access the option value * after all arguments are parsed or to delegate a property for accessing the option value to. * * By default, the option supports only a single value, is optional, and has no default value, * therefore its value's type is `T?`. * * You can alter the option properties by chaining extensions for the option type on the returned object: * - [AbstractSingleOption.default] to provide a default value that is used when the option is not specified; * - [SingleNullableOption.required] to make the option non-optional; * - [AbstractSingleOption.delimiter] to allow specifying multiple values in one command line argument with a delimiter; * - [AbstractSingleOption.multiple] to allow specifying the option several times. * * @param type The type describing how to parse an option value from a string, * an instance of [ArgType], e.g. [ArgType.String] or [ArgType.Choice]. * @param fullName the full name of the option, can be omitted if the option name is inferred * from the name of a property delegated to this option. * @param shortName the short name of the option, `null` if the option cannot be specified in a short form. * @param description the description of the option used when rendering the usage information. * @param deprecatedWarning the deprecation message for the option. * Specifying anything except `null` makes this option deprecated. The message is rendered in a help message and * issued as a warning when the option is encountered when parsing command line arguments. */ fun option( type: ArgType, fullName: String? = null, shortName: String ? = null, description: String? = null, deprecatedWarning: String? = null ): SingleNullableOption { if (prefixStyle == OptionPrefixStyle.GNU && shortName != null) require(shortName.length == 1) { """ GNU standart for options allow to use short form which consists of one character. For more information, please, see https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html """.trimIndent() } val option = SingleNullableOption(OptionDescriptor(optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, deprecatedWarning = deprecatedWarning), CLIEntityWrapper()) option.owner.entity = option declaredOptions.add(option.owner) return option } /** * Check usage of required property for arguments. * Make sense only for several last arguments. */ private fun inspectRequiredAndDefaultUsage() { var previousArgument: ParsingValue<*, *>? = null arguments.forEach { (_, currentArgument) -> previousArgument?.let { previous -> // Previous argument has default value. if (previous.descriptor.defaultValueSet) { if (!currentArgument.descriptor.defaultValueSet && currentArgument.descriptor.required) { error("Default value of argument ${previous.descriptor.fullName} will be unused, " + "because next argument ${currentArgument.descriptor.fullName} is always required and has no default value.") } } // Previous argument is optional. if (!previous.descriptor.required) { if (!currentArgument.descriptor.defaultValueSet && currentArgument.descriptor.required) { error("Argument ${previous.descriptor.fullName} will be always required, " + "because next argument ${currentArgument.descriptor.fullName} is always required.") } } } previousArgument = currentArgument } } /** * Declares an argument and returns an object which can be used to access the argument value * after all arguments are parsed or to delegate a property for accessing the argument value to. * * By default, the argument supports only a single value, is required, and has no default value, * therefore its value's type is `T`. * * You can alter the argument properties by chaining extensions for the argument type on the returned object: * - [AbstractSingleArgument.default] to provide a default value that is used when the argument is not specified; * - [SingleArgument.optional] to allow omitting the argument; * - [AbstractSingleArgument.multiple] to require the argument to have exactly the number of values specified; * - [AbstractSingleArgument.vararg] to allow specifying an unlimited number of values for the _last_ argument. * * @param type The type describing how to parse an option value from a string, * an instance of [ArgType], e.g. [ArgType.String] or [ArgType.Choice]. * @param fullName the full name of the argument, can be omitted if the argument name is inferred * from the name of a property delegated to this argument. * @param description the description of the argument used when rendering the usage information. * @param deprecatedWarning the deprecation message for the argument. * Specifying anything except `null` makes this argument deprecated. The message is rendered in a help message and * issued as a warning when the argument is encountered when parsing command line arguments. */ fun argument( type: ArgType, fullName: String? = null, description: String? = null, deprecatedWarning: String? = null ) : SingleArgument { val argument = SingleArgument(ArgDescriptor(type, fullName, 1, description, deprecatedWarning = deprecatedWarning), CLIEntityWrapper()) argument.owner.entity = argument declaredArguments.add(argument.owner) return argument } /** * Registers one or more subcommands. * * @param subcommandsList subcommands to add. */ @ExperimentalCli fun subcommands(vararg subcommandsList: Subcommand) { subcommandsList.forEach { if (it.name in subcommands) { error("Subcommand with name ${it.name} was already defined.") } // Set same settings as main parser. it.prefixStyle = prefixStyle it.useDefaultHelpShortName = useDefaultHelpShortName fullCommandName.forEachIndexed { index, namePart -> it.fullCommandName.add(index, namePart) } subcommands[it.name] = it } } /** * Outputs an error message adding the usage information after it. * * @param message error message. */ fun printError(message: String): Nothing { error("$message\n${makeUsage()}") } /** * Save value as argument value. * * @param arg string with argument value. * @param argumentsQueue queue with active argument descriptors. */ private fun saveAsArg(arg: String, argumentsQueue: ArgumentsQueue): Boolean { // Find next uninitialized arguments. val name = argumentsQueue.pop() name?.let { val argumentValue = arguments[name]!! argumentValue.descriptor.deprecatedWarning?.let { printWarning(it) } argumentValue.addValue(arg) return true } return false } /** * Treat value as argument value. * * @param arg string with argument value. * @param argumentsQueue queue with active argument descriptors. */ private fun treatAsArgument(arg: String, argumentsQueue: ArgumentsQueue) { if (!saveAsArg(arg, argumentsQueue)) { usedSubcommand?.let { (if (treatAsOption) subcommandsOptions else subcommandsArguments).add(arg) } ?: printError("Too many arguments! Couldn't process argument $arg!") } } /** * Save value as option value. */ private fun saveAsOption(parsingValue: ParsingValue, value: String) { parsingValue.addValue(value) } /** * Try to recognize and save command line element as full form of option. * * @param candidate string with candidate in options. * @param argIterator iterator over command line arguments. */ private fun recognizeAndSaveOptionFullForm(candidate: String, argIterator: Iterator): Boolean { if (prefixStyle == OptionPrefixStyle.GNU && candidate == optionFullFormPrefix) { // All other arguments after `--` are treated as non-option arguments. treatAsOption = false return false } if (!candidate.startsWith(optionFullFormPrefix)) return false val optionString = candidate.substring(optionFullFormPrefix.length) val argValue = if (prefixStyle == OptionPrefixStyle.GNU) null else options[optionString] if (argValue != null) { saveStandardOptionForm(argValue, argIterator) return true } else { // Check GNU style of options. if (prefixStyle == OptionPrefixStyle.GNU) { // Option without a parameter. if (options[optionString]?.descriptor?.type?.hasParameter == false) { saveOptionWithoutParameter(options[optionString]!!) return true } // Option with parameters. val optionParts = optionString.split('=', limit = 2) if (optionParts.size != 2) return false if (options[optionParts[0]] != null) { saveAsOption(options[optionParts[0]]!!, optionParts[1]) return true } } } return false } /** * Save option without parameter. * * @param argValue argument value with all information about option. */ internal fun saveOptionWithoutParameter(argValue: ParsingValue<*, *>) { // Boolean flags. if (argValue.descriptor.fullName == "help") { usedSubcommand?.let { it.parse(listOf("${it.optionFullFormPrefix}${argValue.descriptor.fullName}")) } println(makeUsage()) exitProcess(0) } saveAsOption(argValue, "true") } /** * Save option described with standard separated form `--name value`. * * @param argValue argument value with all information about option. * @param argIterator iterator over command line arguments. */ private fun saveStandardOptionForm(argValue: ParsingValue<*, *>, argIterator: Iterator) { if (argValue.descriptor.type.hasParameter) { if (argIterator.hasNext()) { saveAsOption(argValue, argIterator.next()) } else { // An error, option with value without value. printError("No value for ${argValue.descriptor.textDescription}") } } else { saveOptionWithoutParameter(argValue) } } /** * Try to recognize and save command line element as short form of option. * * @param candidate string with candidate in options. * @param argIterator iterator over command line arguments. */ private fun recognizeAndSaveOptionShortForm(candidate: String, argIterator: Iterator): Boolean { if (!candidate.startsWith(optionShortFromPrefix) || optionFullFormPrefix != optionShortFromPrefix && candidate.startsWith(optionFullFormPrefix)) return false // Try to find exact match. val option = candidate.substring(optionShortFromPrefix.length) val argValue = shortNames[option] if (argValue != null) { saveStandardOptionForm(argValue, argIterator) } else { if (prefixStyle != OptionPrefixStyle.GNU || option.isEmpty()) return false // Try to find collapsed form. val firstOption = shortNames["${option[0]}"] ?: return false // Form with value after short form without separator. if (firstOption.descriptor.type.hasParameter) { saveAsOption(firstOption, option.substring(1)) } else { // Form with several short forms as one string. val otherBooleanOptions = option.substring(1) saveOptionWithoutParameter(firstOption) for (opt in otherBooleanOptions) { shortNames["$opt"]?.let { if (it.descriptor.type.hasParameter) { printError( "Option $optionShortFromPrefix$opt can't be used in option combination $candidate, " + "because parameter value of type ${it.descriptor.type.description} should be " + "provided for current option." ) } }?: printError("Unknown option $optionShortFromPrefix$opt in option combination $candidate.") saveOptionWithoutParameter(shortNames["$opt"]!!) } } } return true } /** * Parses the provided array of command line arguments. * After a successful parsing, the options and arguments declared in this parser get their values and can be accessed * with the properties delegated to them. * * @param args the array with command line arguments. * * @return an [ArgParserResult] if all arguments were parsed successfully. * Otherwise, prints the usage information and terminates the program execution. * @throws IllegalStateException in case of attempt of calling parsing several times. */ fun parse(args: Array): ArgParserResult = parse(args.asList()) protected fun parse(args: List): ArgParserResult { check(parsingState == null) { "Parsing of command line options can be called only once." } // Add help option. val helpDescriptor = if (useDefaultHelpShortName) OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, ArgType.Boolean, "help", "h", "Usage info" ) else OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, ArgType.Boolean, "help", description = "Usage info" ) val helpOption = SingleNullableOption(helpDescriptor, CLIEntityWrapper()) helpOption.owner.entity = helpOption declaredOptions.add(helpOption.owner) // Add default list with arguments if there can be extra free arguments. if (skipExtraArguments) { argument(ArgType.String, "").vararg() } // Clean options and arguments maps. options.clear() arguments.clear() // Map declared options and arguments to maps. declaredOptions.forEachIndexed { index, option -> val value = option.entity?.delegate as ParsingValue<*, *> value.descriptor.fullName?.let { // Add option. if (options.containsKey(it)) { error("Option with full name $it was already added.") } with(value.descriptor as OptionDescriptor) { if (shortName != null && shortNames.containsKey(shortName)) { error("Option with short name ${shortName} was already added.") } shortName?.let { shortNames[it] = value } } options[it] = value } ?: error("Option was added, but unnamed. Added option under №${index + 1}") } declaredArguments.forEachIndexed { index, argument -> val value = argument.entity?.delegate as ParsingValue<*, *> value.descriptor.fullName?.let { // Add option. if (arguments.containsKey(it)) { error("Argument with full name $it was already added.") } arguments[it] = value } ?: error("Argument was added, but unnamed. Added argument under №${index + 1}") } // Make inspections for arguments. inspectRequiredAndDefaultUsage() listOf(arguments, options).forEach { it.forEach { (_, value) -> value.valueOrigin = ValueOrigin.UNSET } } val argumentsQueue = ArgumentsQueue(arguments.map { it.value.descriptor as ArgDescriptor<*, *> }) usedSubcommand = null subcommandsOptions.clear() subcommandsArguments.clear() val argIterator = args.listIterator() try { while (argIterator.hasNext()) { val arg = argIterator.next() // Check for subcommands. if (arg !in subcommands) { // Parse arguments from command line. if (treatAsOption && arg.startsWith('-')) { // Candidate in being option. // Option is found. if (!(recognizeAndSaveOptionShortForm(arg, argIterator) || recognizeAndSaveOptionFullForm(arg, argIterator)) ) { // State is changed so next options are arguments. if (!treatAsOption) { // Argument is found. treatAsArgument(argIterator.next(), argumentsQueue) } else { usedSubcommand?.let { subcommandsOptions.add(arg) } ?: run { // Try save as argument. if (!saveAsArg(arg, argumentsQueue)) { printError("Unknown option $arg") } } } } } else { // Argument is found. treatAsArgument(arg, argumentsQueue) } } else { usedSubcommand = subcommands[arg] } } // Postprocess results of parsing. options.values.union(arguments.values).forEach { value -> // Not inited, append default value if needed. if (value.isEmpty()) { value.addDefaultValue() } if (value.valueOrigin != ValueOrigin.SET_BY_USER && value.descriptor.required) { printError("Value for ${value.descriptor.textDescription} should be always provided in command line.") } } // Parse arguments for subcommand. usedSubcommand?.let { it.parse(subcommandsOptions + listOfNotNull("--".takeUnless { treatAsOption }) + subcommandsArguments) it.execute() parsingState = ArgParserResult(it.name) return parsingState!! } } catch (exception: ParsingException) { printError(exception.message!!) } parsingState = ArgParserResult(programName) return parsingState!! } /** * Creates a message with the usage information. */ internal fun makeUsage(): String { val result = StringBuilder() result.append("Usage: ${fullCommandName.joinToString(" ")} options_list\n") if (subcommands.isNotEmpty()) { result.append("Subcommands: \n") subcommands.forEach { (_, subcommand) -> result.append(subcommand.helpMessage) } result.append("\n") } if (arguments.isNotEmpty()) { result.append("Arguments: \n") arguments.forEach { result.append(it.value.descriptor.helpMessage) } } if (options.isNotEmpty()) { result.append("Options: \n") options.forEach { result.append(it.value.descriptor.helpMessage) } } return result.toString() } } /** * Output warning. * * @param message warning message. */ internal fun printWarning(message: String) { println("WARNING $message") } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/ArgType.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli /** * Possible types of arguments. * * Inheritors describe type of argument value. New types can be added by user. * In case of options type can have parameter or not. */ abstract class ArgType(val hasParameter: kotlin.Boolean) { /** * Text description of type for helpMessage. */ abstract val description: kotlin.String /** * Function to convert string argument value to its type. * In case of error during conversion also provides help message. * * @param value value */ abstract fun convert(value: kotlin.String, name: kotlin.String): T /** * Argument type for flags that can be only set/unset. */ object Boolean : ArgType(false) { override val description: kotlin.String get() = "" override fun convert(value: kotlin.String, name: kotlin.String): kotlin.Boolean = value != "false" } /** * Argument type for string values. */ object String : ArgType(true) { override val description: kotlin.String get() = "{ String }" override fun convert(value: kotlin.String, name: kotlin.String): kotlin.String = value } /** * Argument type for integer values. */ object Int : ArgType(true) { override val description: kotlin.String get() = "{ Int }" override fun convert(value: kotlin.String, name: kotlin.String): kotlin.Int = value.toIntOrNull() ?: throw ParsingException("Option $name is expected to be integer number. $value is provided.") } /** * Argument type for double values. */ object Double : ArgType(true) { override val description: kotlin.String get() = "{ Double }" override fun convert(value: kotlin.String, name: kotlin.String): kotlin.Double = value.toDoubleOrNull() ?: throw ParsingException("Option $name is expected to be double number. $value is provided.") } companion object { /** * Helper for arguments that have limited set of possible values represented as enumeration constants. */ inline fun > Choice( noinline toVariant: (kotlin.String) -> T = { enumValues().find { e -> e.toString().equals(it, ignoreCase = true) } ?: throw IllegalArgumentException("No enum constant $it") }, noinline toString: (T) -> kotlin.String = { it.toString().toLowerCase() }): Choice { return Choice(enumValues().toList(), toVariant, toString) } } /** * Type for arguments that have limited set of possible values. */ class Choice(choices: List, val toVariant: (kotlin.String) -> T, val variantToString: (T) -> kotlin.String = { it.toString() }): ArgType(true) { private val choicesMap: Map = choices.associateBy { variantToString(it) } init { require(choicesMap.size == choices.size) { "Command line representations of enum choices are not distinct" } } override val description: kotlin.String get() { return "{ Value should be one of ${choicesMap.keys} }" } override fun convert(value: kotlin.String, name: kotlin.String) = try { toVariant(value) } catch (e: Exception) { throw ParsingException("Option $name is expected to be one of ${choicesMap.keys}. $value is provided.") } } } internal class ParsingException(message: String) : Exception(message) ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/ArgumentValues.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli /** * Parsing value of option/argument. */ internal abstract class ParsingValue(val descriptor: Descriptor) { /** * Values of arguments. */ protected lateinit var parsedValue: TResult /** * Value origin. */ var valueOrigin = ArgParser.ValueOrigin.UNDEFINED internal set /** * Check if values of argument are empty. */ abstract fun isEmpty(): Boolean /** * Check if value of argument was initialized. */ protected fun valueIsInitialized() = ::parsedValue.isInitialized /** * Sace value from command line. * * @param stringValue value from command line. */ protected abstract fun saveValue(stringValue: String) /** * Set value of delegated property. */ fun setDelegatedValue(providedValue: TResult) { parsedValue = providedValue valueOrigin = ArgParser.ValueOrigin.REDEFINED } /** * Add parsed value from command line. * * @param stringValue value from command line. */ internal fun addValue(stringValue: String) { // Check of possibility to set several values to one option/argument. if (descriptor is OptionDescriptor<*, *> && !descriptor.multiple && !isEmpty() && descriptor.delimiter == null) { throw ParsingException("Try to provide more than one value for ${descriptor.fullName}.") } // Show deprecated warning only first time of using option/argument. descriptor.deprecatedWarning?.let { if (isEmpty()) println ("Warning: $it") } // Split value if needed. if (descriptor is OptionDescriptor<*, *> && descriptor.delimiter != null) { stringValue.split(descriptor.delimiter).forEach { saveValue(it) } } else { saveValue(stringValue) } } /** * Set default value to option. */ fun addDefaultValue() { if (descriptor.defaultValueSet) { parsedValue = descriptor.defaultValue!! valueOrigin = ArgParser.ValueOrigin.SET_DEFAULT_VALUE } } /** * Provide name for CLI entity. * * @param name name for CLI entity. */ fun provideName(name: String) { descriptor.fullName ?: run { descriptor.fullName = name } } } /** * Single argument value. * * @property descriptor descriptor of option/argument. */ internal abstract class AbstractArgumentSingleValue(descriptor: Descriptor): ParsingValue(descriptor) { override fun saveValue(stringValue: String) { if (!valueIsInitialized()) { parsedValue = descriptor.type.convert(stringValue, descriptor.fullName!!) valueOrigin = ArgParser.ValueOrigin.SET_BY_USER } else { throw ParsingException("Try to provide more than one value $parsedValue and $stringValue for ${descriptor.fullName}.") } } override fun isEmpty(): Boolean = !valueIsInitialized() } /** * Single argument value. * * @property descriptor descriptor of option/argument. */ internal class ArgumentSingleValue(descriptor: Descriptor): AbstractArgumentSingleValue(descriptor), ArgumentValueDelegate { override var value: T get() = if (!isEmpty()) parsedValue else error("Value for argument ${descriptor.fullName} isn't set. " + "ArgParser.parse(...) method should be called before.") set(value) = setDelegatedValue(value) } /** * Single nullable argument value. * * @property descriptor descriptor of option/argument. */ internal class ArgumentSingleNullableValue(descriptor: Descriptor): AbstractArgumentSingleValue(descriptor), ArgumentValueDelegate { private var setToNull = false override var value: T? get() = if (!isEmpty() && !setToNull) parsedValue else null set(providedValue) = providedValue?.let { setDelegatedValue(it) setToNull = false } ?: run { setToNull = true valueOrigin = ArgParser.ValueOrigin.REDEFINED } } /** * Multiple argument values. * * @property descriptor descriptor of option/argument. */ internal class ArgumentMultipleValues(descriptor: Descriptor>): ParsingValue>(descriptor), ArgumentValueDelegate> { private val addedValue = mutableListOf() init { parsedValue = addedValue } override var value: List get() = parsedValue set(value) = setDelegatedValue(value) override fun saveValue(stringValue: String) { addedValue.add(descriptor.type.convert(stringValue, descriptor.fullName!!)) valueOrigin = ArgParser.ValueOrigin.SET_BY_USER } override fun isEmpty() = parsedValue.isEmpty() } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/Arguments.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli import kotlin.reflect.KProperty internal data class CLIEntityWrapper(var entity: CLIEntity<*>? = null) /** * Base interface for all possible types of entities with default and required values. * Provides limitations for API that is accessible for different options/arguments types. * Allows to save the reason why option/argument can(or can't) be omitted in command line. * * @see [SingleOption], [MultipleOption], [SingleArgument], [MultipleArgument]. */ interface DefaultRequiredType { /** * Type of an entity with default value. */ class Default : DefaultRequiredType /** * Type of an entity which value should always be provided in command line. */ class Required : DefaultRequiredType /** * Type of entity which is optional and has no default value. */ class None : DefaultRequiredType } /** * The base class for a command line argument or an option. */ abstract class CLIEntity internal constructor(val delegate: ArgumentValueDelegate, internal val owner: CLIEntityWrapper) { /** * The value of the option or argument parsed from command line. * * Accessing this property before it gets its value will result in an exception. * You can use [valueOrigin] property to find out whether the property has been already set. * * @see ArgumentValueDelegate.value */ var value: TResult get() = delegate.value set(value) { check((delegate as ParsingValue<*, *>).valueOrigin != ArgParser.ValueOrigin.UNDEFINED) { "Resetting value of option/argument is only possible after parsing command line arguments." + " ArgParser.parse(...) method should be called before" } delegate.value = value } /** * The origin of the option/argument value. */ val valueOrigin: ArgParser.ValueOrigin get() = (delegate as ParsingValue<*, *>).valueOrigin private var delegateProvided = false /** * Returns the delegate object for property delegation and initializes it with the name of the delegated property. * * This operator makes it possible to delegate a property to this instance. It returns [delegate] object * to be used as an actual delegate and uses the name of the delegated property to initialize the full name * of the option/argument if it wasn't done during construction of that option/argument. * * @throws IllegalStateException in case of trying to use same delegate several times. */ operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ArgumentValueDelegate { check(!delegateProvided) { "There is already used delegate for ${(delegate as ParsingValue<*, *>).descriptor.fullName}." } (delegate as ParsingValue<*, *>).provideName(prop.name) delegateProvided = true return delegate } } /** * The base class for command line arguments. * * You can use [ArgParser.argument] function to declare an argument. */ abstract class Argument internal constructor(delegate: ArgumentValueDelegate, owner: CLIEntityWrapper): CLIEntity(delegate, owner) /** * The base class of an argument with a single value. * * A non-optional argument or an optional argument with a default value is represented with the [SingleArgument] inheritor. * An optional argument having nullable value is represented with the [SingleNullableArgument] inheritor. */ // TODO: investigate if we can collapse two inheritors into the single base class and specialize extensions by TResult upper bound abstract class AbstractSingleArgument internal constructor( delegate: ArgumentValueDelegate, owner: CLIEntityWrapper): Argument(delegate, owner) { /** * Check descriptor for this kind of argument. */ internal fun checkDescriptor(descriptor: ArgDescriptor<*, *>) { if (descriptor.number == null || descriptor.number > 1) { failAssertion("Argument with single value can't be initialized with descriptor for multiple values.") } } } /** * A non-optional argument or an optional argument with a default value. * * The [value] of such argument is non-null. */ class SingleArgument internal constructor(descriptor: ArgDescriptor, owner: CLIEntityWrapper): AbstractSingleArgument(ArgumentSingleValue(descriptor), owner) { init { checkDescriptor(descriptor) } } /** * An optional argument with nullable [value]. */ class SingleNullableArgument internal constructor(descriptor: ArgDescriptor, owner: CLIEntityWrapper): AbstractSingleArgument(ArgumentSingleNullableValue(descriptor), owner) { init { checkDescriptor(descriptor) } } /** * An argument that allows several values to be provided in command line string. * * The [value] property of such argument has type `List`. */ class MultipleArgument internal constructor( descriptor: ArgDescriptor>, owner: CLIEntityWrapper): Argument>(ArgumentMultipleValues(descriptor), owner) { init { if (descriptor.number != null && descriptor.number < 2) { failAssertion("Argument with multiple values can't be initialized with descriptor for single one.") } } } /** * Allows the argument to have several values specified in command line string. * * @param number the exact number of values expected for this argument, but at least 2. * * @throws IllegalArgumentException if number of values expected for this argument less than 2. */ fun AbstractSingleArgument.multiple(number: Int): MultipleArgument { require(number >= 2) { "multiple() modifier with value less than 2 is unavailable. It's already set to 1." } val newArgument = with((delegate.cast>()).descriptor as ArgDescriptor) { MultipleArgument(ArgDescriptor(type, fullName, number, description, listOfNotNull(defaultValue), required, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } /** * Allows the last argument to take all the trailing values in command line string. */ fun AbstractSingleArgument.vararg(): MultipleArgument { val newArgument = with((delegate.cast>()).descriptor as ArgDescriptor) { MultipleArgument(ArgDescriptor(type, fullName, null, description, listOfNotNull(defaultValue), required, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } /** * Specifies the default value for the argument, that will be used when no value is provided for the argument * in command line string. * * Argument becomes optional, because value for it is set even if it isn't provided in command line. * * @param value the default value. */ fun SingleNullableArgument.default(value: T): SingleArgument { val newArgument = with((delegate.cast>()).descriptor as ArgDescriptor) { SingleArgument(ArgDescriptor(type, fullName, number, description, value, false, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } /** * Specifies the default value for the argument with multiple values, that will be used when no values are provided * for the argument in command line string. * * Argument becomes optional, because value for it is set even if it isn't provided in command line. * * @param value the default value, must be a non-empty collection. */ fun MultipleArgument.default(value: Collection): MultipleArgument { require (value.isNotEmpty()) { "Default value for argument can't be empty collection." } val newArgument = with((delegate.cast>>()).descriptor as ArgDescriptor) { MultipleArgument(ArgDescriptor(type, fullName, number, description, value.toList(), required, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } /** * Allows the argument to have no value specified in command line string. * * The value of the argument is `null` in case if no value was specified in command line string. * * Note that only trailing arguments can be optional, i.e. no required arguments can follow optional ones. */ fun SingleArgument.optional(): SingleNullableArgument { val newArgument = with((delegate.cast>()).descriptor as ArgDescriptor) { SingleNullableArgument(ArgDescriptor(type, fullName, number, description, defaultValue, false, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } /** * Allows the argument with multiple values to have no values specified in command line string. * * The value of the argument is an empty list in case if no value was specified in command line string. * * Note that only trailing arguments can be optional: no required arguments can follow the optional ones. */ fun MultipleArgument.optional(): MultipleArgument { val newArgument = with((delegate.cast>>()).descriptor as ArgDescriptor) { MultipleArgument(ArgDescriptor(type, fullName, number, description, defaultValue?.toList() ?: listOf(), false, deprecatedWarning), owner) } owner.entity = newArgument return newArgument } internal fun failAssertion(message: String): Nothing = throw AssertionError(message) internal inline fun Any?.cast(): T = this as T ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/Descriptors.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli /** * Common descriptor both for options and positional arguments. * * @property type option/argument type, one of [ArgType]. * @property fullName option/argument full name. * @property description text description of option/argument. * @property defaultValue default value for option/argument. * @property required if option/argument is required or not. If it's required and not provided in command line, error will be generated. * @property deprecatedWarning text message with information in case if option is deprecated. */ internal abstract class Descriptor(val type: ArgType, var fullName: String? = null, val description: String? = null, val defaultValue: TResult? = null, val required: Boolean = false, val deprecatedWarning: String? = null) { /** * Text description for help message. */ abstract val textDescription: String /** * Help message for descriptor. */ abstract val helpMessage: String /** * Provide text description of value. * * @param value value got getting text description for. */ fun valueDescription(value: TResult?) = value?.let { if (it is List<*> && it.isNotEmpty()) " [${it.joinToString()}]" else if (it !is List<*>) " [$it]" else null } /** * Flag to check if descriptor has set default value for option/argument. */ val defaultValueSet by lazy { defaultValue != null && (defaultValue is List<*> && defaultValue.isNotEmpty() || defaultValue !is List<*>) } } /** * Option descriptor. * * Command line entity started with some prefix (-/--) and can have value as next entity in command line string. * * @property optionFullFormPrefix prefix used before full form of option. * @property optionShortFromPrefix prefix used before short form of option. * @property type option type, one of [ArgType]. * @property fullName option full name. * @property shortName option short name. * @property description text description of option. * @property defaultValue default value for option. * @property required if option is required or not. If it's required and not provided in command line, error will be generated. * @property multiple if option can be repeated several times in command line with different values. All values are stored. * @property delimiter delimiter that separate option provided as one string to several values. * @property deprecatedWarning text message with information in case if option is deprecated. */ internal class OptionDescriptor( val optionFullFormPrefix: String, val optionShortFromPrefix: String, type: ArgType, fullName: String? = null, val shortName: String ? = null, description: String? = null, defaultValue: TResult? = null, required: Boolean = false, val multiple: Boolean = false, val delimiter: String? = null, deprecatedWarning: String? = null) : Descriptor(type, fullName, description, defaultValue, required, deprecatedWarning) { override val textDescription: String get() = "option $optionFullFormPrefix$fullName" override val helpMessage: String get() { val result = StringBuilder() result.append(" $optionFullFormPrefix$fullName") shortName?.let { result.append(", $optionShortFromPrefix$it") } valueDescription(defaultValue)?.let { result.append(it) } description?.let {result.append(" -> $it")} if (required) result.append(" (always required)") result.append(" ${type.description}") deprecatedWarning?.let { result.append(" Warning: $it") } result.append("\n") return result.toString() } } /** * Argument descriptor. * * Command line entity which role is connected only with its position. * * @property type argument type, one of [ArgType]. * @property fullName argument full name. * @property number expected number of values. Null means any possible number of values. * @property description text description of argument. * @property defaultValue default value for argument. * @property required if argument is required or not. If it's required and not provided in command line and have no default value, error will be generated. * @property deprecatedWarning text message with information in case if argument is deprecated. */ internal class ArgDescriptor( type: ArgType, fullName: String?, val number: Int? = null, description: String? = null, defaultValue: TResult? = null, required: Boolean = true, deprecatedWarning: String? = null) : Descriptor(type, fullName, description, defaultValue, required, deprecatedWarning) { init { // Check arguments number correctness. number?.let { if (it < 1) error("Number of arguments for argument description $fullName should be greater than zero.") } } override val textDescription: String get() = "argument $fullName" override val helpMessage: String get() { val result = StringBuilder() result.append(" ${fullName}") valueDescription(defaultValue)?.let { result.append(it) } description?.let { result.append(" -> $it") } if (!required) result.append(" (optional)") result.append(" ${type.description}") deprecatedWarning?.let { result.append(" Warning: $it") } result.append("\n") return result.toString() } } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/ExperimentalCli.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli import kotlin.annotation.AnnotationTarget.* /** * This annotation marks the experimental API for working with command line arguments. * * > Beware using the annotated API especially if you're developing a library, since your library might become binary incompatible * with the future versions of the CLI library. * * Any usage of a declaration annotated with `@ExperimentalCli` must be accepted either by * annotating that usage with the [UseExperimental] annotation, e.g. `@UseExperimental(ExperimentalCli::class)`, * or by using the compiler argument `-Xuse-experimental=kotlinx.cli.ExperimentalCli`. */ @RequiresOptIn("This API is experimental. It may be changed in the future without notice.", RequiresOptIn.Level.WARNING) @Retention(AnnotationRetention.BINARY) @Target( CLASS, ANNOTATION_CLASS, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS ) public annotation class ExperimentalCli ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin/kotlinx/cli/Options.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli /** * Base interface for all possible types of options with multiple values. * Provides limitations for API that is accessible for options with several values. * Allows to save the way of providing several values in command line. * * @see [MultipleOption] */ interface MultipleOptionType { /** * Type of an option with multiple values allowed to be provided several times in command line. */ class Repeated : MultipleOptionType /** * Type of an option with multiple values allowed to be provided using delimiter in one command line value. */ class Delimited : MultipleOptionType /** * Type of an option with multiple values allowed to be provided several times in command line * both with specifying several values and with delimiter. */ class RepeatedDelimited : MultipleOptionType } /** * The base class for command line options. * * You can use [ArgParser.option] function to declare an option. */ abstract class Option internal constructor(delegate: ArgumentValueDelegate, owner: CLIEntityWrapper) : CLIEntity(delegate, owner) /** * The base class of an option with a single value. * * A required option or an option with a default value is represented with the [SingleOption] inheritor. * An option having nullable value is represented with the [SingleNullableOption] inheritor. */ abstract class AbstractSingleOption internal constructor( delegate: ArgumentValueDelegate, owner: CLIEntityWrapper) : Option(delegate, owner) { /** * Check descriptor for this kind of option. */ internal fun checkDescriptor(descriptor: OptionDescriptor<*, *>) { if (descriptor.multiple || descriptor.delimiter != null) { failAssertion("Option with single value can't be initialized with descriptor for multiple values.") } } } /** * A required option or an option with a default value. * * The [value] of such option is non-null. */ class SingleOption internal constructor(descriptor: OptionDescriptor, owner: CLIEntityWrapper) : AbstractSingleOption(ArgumentSingleValue(descriptor), owner) { init { checkDescriptor(descriptor) } } /** * An option with nullable [value]. */ class SingleNullableOption internal constructor(descriptor: OptionDescriptor, owner: CLIEntityWrapper) : AbstractSingleOption(ArgumentSingleNullableValue(descriptor), owner) { init { checkDescriptor(descriptor) } } /** * An option that allows several values to be provided in command line string. * * The [value] property of such option has type `List`. */ class MultipleOption internal constructor( descriptor: OptionDescriptor>, owner: CLIEntityWrapper ) : Option>( ArgumentMultipleValues(descriptor), owner) { init { if (!descriptor.multiple && descriptor.delimiter == null) { failAssertion("Option with multiple values can't be initialized with descriptor for single one.") } } } /** * Allows the option to have several values specified in command line string. * Number of values is unlimited. */ fun AbstractSingleOption.multiple(): MultipleOption { val newOption = with((delegate.cast>()).descriptor as OptionDescriptor) { MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, listOfNotNull(defaultValue), required, true, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Allows the option to have several values specified in command line string. * Number of values is unlimited. */ fun MultipleOption.multiple(): MultipleOption { val newOption = with((delegate.cast>>()).descriptor as OptionDescriptor) { if (multiple) { error("Try to use modifier multiple() twice on option ${fullName ?: ""}") } MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, defaultValue?.toList() ?: listOf(), required, true, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Specifies the default value for the option, that will be used when no value is provided for it * in command line string. * * @param value the default value. */ fun SingleNullableOption.default(value: T): SingleOption { val newOption = with((delegate.cast>()).descriptor as OptionDescriptor) { SingleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, value, required, multiple, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Specifies the default value for the option with multiple values, that will be used when no values are provided * for it in command line string. * * @param value the default value, must be a non-empty collection. * @throws IllegalArgumentException if provided default value is empty collection. */ fun MultipleOption.default(value: Collection): MultipleOption { val newOption = with((delegate.cast>>()).descriptor as OptionDescriptor) { require(value.isNotEmpty()) { "Default value for option can't be empty collection." } MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, value.toList(), required, multiple, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Requires the option to be always provided in command line. */ fun SingleNullableOption.required(): SingleOption { val newOption = with((delegate.cast>()).descriptor as OptionDescriptor) { SingleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, defaultValue, true, multiple, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Requires the option to be always provided in command line. */ fun MultipleOption.required(): MultipleOption { val newOption = with((delegate.cast>>()).descriptor as OptionDescriptor) { MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, defaultValue?.toList() ?: listOf(), true, multiple, delimiter, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Allows the option to have several values joined with [delimiter] specified in command line string. * Number of values is unlimited. * * The value of the argument is an empty list in case if no value was specified in command line string. * * @param delimiterValue delimiter used to separate string value to option values list. */ fun AbstractSingleOption.delimiter( delimiterValue: String): MultipleOption { val newOption = with((delegate.cast>()).descriptor as OptionDescriptor) { MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, listOfNotNull(defaultValue), required, multiple, delimiterValue, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } /** * Allows the option to have several values joined with [delimiter] specified in command line string. * Number of values is unlimited. * * The value of the argument is an empty list in case if no value was specified in command line string. * * @param delimiterValue delimiter used to separate string value to option values list. */ fun MultipleOption.delimiter( delimiterValue: String): MultipleOption { val newOption = with((delegate.cast>>()).descriptor as OptionDescriptor) { MultipleOption( OptionDescriptor( optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName, description, defaultValue?.toList() ?: listOf(), required, multiple, delimiterValue, deprecatedWarning ), owner ) } owner.entity = newOption return newOption } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin-js/kotlinx.cli/Utils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli internal actual fun exitProcess(status: Int): Nothing { error("Not implemented for JS!") } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin-jvm/kotlinx/cli/nonStdlibUtils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli internal actual fun exitProcess(status: Int): Nothing { kotlin.system.exitProcess(0) } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/main/kotlin-native/kotlinx/cli/Utils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlinx.cli internal actual fun exitProcess(status: Int): Nothing { kotlin.system.exitProcess(0) } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/ArgumentsTests.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED_VARIABLE") package kotlinx.cli import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlin.test.* class ArgumentsTests { @Test fun testPositionalArguments() { val argParser = ArgParser("testParser") val debugMode by argParser.option(ArgType.Boolean, "debug", "d", "Debug mode") val input by argParser.argument(ArgType.String, "input", "Input file") val output by argParser.argument(ArgType.String, "output", "Output file") argParser.parse(arrayOf("-d", "input.txt", "out.txt")) assertEquals(true, debugMode) assertEquals("out.txt", output) assertEquals("input.txt", input) } @Test fun testArgumetsWithAnyNumberOfValues() { val argParser = ArgParser("testParser") val output by argParser.argument(ArgType.String, "output", "Output file") val inputs by argParser.argument(ArgType.String, description = "Input files").vararg() argParser.parse(arrayOf("out.txt", "input1.txt", "input2.txt", "input3.txt", "input4.txt")) assertEquals("out.txt", output) assertEquals(4, inputs.size) } @Test fun testArgumetsWithSeveralValues() { val argParser = ArgParser("testParser") val addendums by argParser.argument(ArgType.Int, "addendums", description = "Addendums").multiple(2) val output by argParser.argument(ArgType.String, "output", "Output file") val debugMode by argParser.option(ArgType.Boolean, "debug", "d", "Debug mode") argParser.parse(arrayOf("2", "-d", "3", "out.txt")) assertEquals("out.txt", output) val (first, second) = addendums assertEquals(2, addendums.size) assertEquals(2, first) assertEquals(3, second) } @Test fun testSkippingExtraArguments() { val argParser = ArgParser("testParser", skipExtraArguments = true) val addendums by argParser.argument(ArgType.Int, "addendums", description = "Addendums").multiple(2) val output by argParser.argument(ArgType.String, "output", "Output file") val debugMode by argParser.option(ArgType.Boolean, "debug", "d", "Debug mode") argParser.parse(arrayOf("2", "-d", "3", "out.txt", "something", "else", "in", "string")) assertEquals("out.txt", output) } } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/DataSourceEnum.kt ================================================ package kotlinx.cli enum class DataSourceEnum { LOCAL, STAGING, PRODUCTION; override fun toString(): String = name.toLowerCase() } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/ErrorTests.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED_VARIABLE") package kotlinx.cli import kotlin.test.* class ErrorTests { @Test fun testExtraArguments() { val argParser = ArgParser("testParser") val addendums by argParser.argument(ArgType.Int, "addendums", description = "Addendums").multiple(2) val output by argParser.argument(ArgType.String, "output", "Output file") val debugMode by argParser.option(ArgType.Boolean, "debug", "d", "Debug mode") val exception = assertFailsWith { argParser.parse( arrayOf("2", "-d", "3", "out.txt", "something", "else", "in", "string")) } assertTrue("Too many arguments! Couldn't process argument something" in exception.message!!) } @Test fun testUnknownOption() { val argParser = ArgParser("testParser") val output by argParser.option(ArgType.String, "output", "o", "Output file") val input by argParser.option(ArgType.String, "input", "i", "Input file") val exception = assertFailsWith { argParser.parse(arrayOf("-o", "out.txt", "-d", "-i", "input.txt")) } assertTrue("Unknown option -d" in exception.message!!) } @Test fun testWrongFormat() { val argParser = ArgParser("testParser") val number by argParser.option(ArgType.Int, "number", description = "Integer number") val exception = assertFailsWith { argParser.parse(arrayOf("--number", "out.txt")) } assertTrue("Option number is expected to be integer number. out.txt is provided." in exception.message!!) } enum class RenderEnum { TEXT, HTML; } @Test fun testWrongChoice() { val argParser = ArgParser("testParser") val useShortForm by argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) val renders by argParser.option(ArgType.Choice(), "renders", "r", "Renders for showing information").multiple().default(listOf(RenderEnum.TEXT)) val exception = assertFailsWith { argParser.parse(arrayOf("-r", "xml")) } assertTrue("Option renders is expected to be one of [text, html]. xml is provided." in exception.message!!) } @Test fun testWrongEnumChoice() { val argParser = ArgParser("testParser") val sources by argParser.option(ArgType.Choice(), "sources", "s", "Data sources").multiple().default(listOf(DataSourceEnum.PRODUCTION)) val exception = assertFailsWith { argParser.parse(arrayOf("-s", "debug")) } assertTrue("Option sources is expected to be one of [local, staging, production]. debug is provided." in exception.message!!) } } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/HelpTests.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalCli::class) @file:Suppress("UNUSED_VARIABLE") package kotlinx.cli import kotlin.test.* class HelpTests { enum class Renders { TEXT, HTML, TEAMCITY, STATISTICS, METRICS } @Test fun testHelpMessage() { val argParser = ArgParser("test") val mainReport by argParser.argument(ArgType.String, description = "Main report for analysis") val compareToReport by argParser.argument(ArgType.String, description = "Report to compare to").optional() val output by argParser.option(ArgType.String, shortName = "o", description = "Output file") val epsValue by argParser.option(ArgType.Double, "eps", "e", "Meaningful performance changes").default(1.0) val useShortForm by argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) val renders by argParser.option(ArgType.Choice(listOf("text", "html", "teamcity", "statistics", "metrics"), { it }), shortName = "r", description = "Renders for showing information").multiple().default(listOf("text")) val sources by argParser.option(ArgType.Choice(), "sources", "ds", "Data sources").multiple().default(listOf(DataSourceEnum.PRODUCTION)) val user by argParser.option(ArgType.String, shortName = "u", description = "User access information for authorization") argParser.parse(arrayOf("main.txt")) val helpOutput = argParser.makeUsage().trimIndent() @Suppress("CanBeVal") // can't be val in order to build expectedOutput only in run time. var epsDefault = 1.0 val expectedOutput = """ Usage: test options_list Arguments: mainReport -> Main report for analysis { String } compareToReport -> Report to compare to (optional) { String } Options: --output, -o -> Output file { String } --eps, -e [$epsDefault] -> Meaningful performance changes { Double } --short, -s [false] -> Show short version of report --renders, -r [text] -> Renders for showing information { Value should be one of [text, html, teamcity, statistics, metrics] } --sources, -ds [production] -> Data sources { Value should be one of [local, staging, production] } --user, -u -> User access information for authorization { String } --help, -h -> Usage info """.trimIndent() assertEquals(expectedOutput, helpOutput) } enum class MetricType { SAMPLES, GEOMEAN; override fun toString() = name.toLowerCase() } @Test fun testHelpForSubcommands() { class Summary: Subcommand("summary", "Get summary information") { val exec by option(ArgType.Choice(), description = "Execution time way of calculation").default(MetricType.GEOMEAN) val execSamples by option(ArgType.String, "exec-samples", description = "Samples used for execution time metric (value 'all' allows use all samples)").delimiter(",") val execNormalize by option(ArgType.String, "exec-normalize", description = "File with golden results which should be used for normalization") val compile by option(ArgType.Choice(), description = "Compile time way of calculation").default(MetricType.GEOMEAN) val compileSamples by option(ArgType.String, "compile-samples", description = "Samples used for compile time metric (value 'all' allows use all samples)").delimiter(",") val compileNormalize by option(ArgType.String, "compile-normalize", description = "File with golden results which should be used for normalization") val codesize by option(ArgType.Choice(), description = "Code size way of calculation").default(MetricType.GEOMEAN) val codesizeSamples by option(ArgType.String, "codesize-samples", description = "Samples used for code size metric (value 'all' allows use all samples)").delimiter(",") val codesizeNormalize by option(ArgType.String, "codesize-normalize", description = "File with golden results which should be used for normalization") val source by option(ArgType.Choice(), description = "Data source").default(DataSourceEnum.PRODUCTION) val sourceSamples by option(ArgType.String, "source-samples", description = "Samples used for code size metric (value 'all' allows use all samples)").delimiter(",") val sourceNormalize by option(ArgType.String, "source-normalize", description = "File with golden results which should be used for normalization") val user by option(ArgType.String, shortName = "u", description = "User access information for authorization") val mainReport by argument(ArgType.String, description = "Main report for analysis") override fun execute() { println("Do some important things!") } } val action = Summary() // Parse args. val argParser = ArgParser("test") argParser.subcommands(action) argParser.parse(arrayOf("summary", "out.txt")) val helpOutput = action.makeUsage().trimIndent() val expectedOutput = """ Usage: test summary options_list Arguments: mainReport -> Main report for analysis { String } Options: --exec [geomean] -> Execution time way of calculation { Value should be one of [samples, geomean] } --exec-samples -> Samples used for execution time metric (value 'all' allows use all samples) { String } --exec-normalize -> File with golden results which should be used for normalization { String } --compile [geomean] -> Compile time way of calculation { Value should be one of [samples, geomean] } --compile-samples -> Samples used for compile time metric (value 'all' allows use all samples) { String } --compile-normalize -> File with golden results which should be used for normalization { String } --codesize [geomean] -> Code size way of calculation { Value should be one of [samples, geomean] } --codesize-samples -> Samples used for code size metric (value 'all' allows use all samples) { String } --codesize-normalize -> File with golden results which should be used for normalization { String } --source [production] -> Data source { Value should be one of [local, staging, production] } --source-samples -> Samples used for code size metric (value 'all' allows use all samples) { String } --source-normalize -> File with golden results which should be used for normalization { String } --user, -u -> User access information for authorization { String } --help, -h -> Usage info """.trimIndent() assertEquals(expectedOutput, helpOutput) } @Test fun testHelpMessageWithSubcommands() { abstract class CommonOptions(name: String, actionDescription: String): Subcommand(name, actionDescription) { val numbers by argument(ArgType.Int, "numbers", description = "Numbers").vararg() } class Summary: CommonOptions("summary", "Calculate summary") { val invert by option(ArgType.Boolean, "invert", "i", "Invert results") var result: Int = 0 override fun execute() { result = numbers.sum() result = invert?.let { -1 * result } ?: result } } class Subtraction : CommonOptions("sub", "Calculate subtraction") { var result: Int = 0 override fun execute() { result = numbers.map { -it }.sum() } } val summaryAction = Summary() val subtractionAction = Subtraction() val argParser = ArgParser("testParser") argParser.subcommands(summaryAction, subtractionAction) argParser.parse(emptyArray()) val helpOutput = argParser.makeUsage().trimIndent() println(helpOutput) val expectedOutput = """ Usage: testParser options_list Subcommands: summary - Calculate summary sub - Calculate subtraction Options: --help, -h -> Usage info """.trimIndent() assertEquals(expectedOutput, helpOutput) } } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/OptionsTests.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("UNUSED_VARIABLE") package kotlinx.cli import kotlin.test.* class OptionsTests { @Test fun testShortForm() { val argParser = ArgParser("testParser") val output by argParser.option(ArgType.String, "output", "o", "Output file") val input by argParser.option(ArgType.String, "input", "i", "Input file") argParser.parse(arrayOf("-o", "out.txt", "-i", "input.txt")) assertEquals("out.txt", output) assertEquals("input.txt", input) } @Test fun testFullForm() { val argParser = ArgParser("testParser") val output by argParser.option(ArgType.String, shortName = "o", description = "Output file") val input by argParser.option(ArgType.String, shortName = "i", description = "Input file") argParser.parse(arrayOf("--output", "out.txt", "--input", "input.txt")) assertEquals("out.txt", output) assertEquals("input.txt", input) } @Test fun testJavaPrefix() { val argParser = ArgParser("testParser", prefixStyle = ArgParser.OptionPrefixStyle.JVM) val output by argParser.option(ArgType.String, "output", "o", "Output file") val input by argParser.option(ArgType.String, "input", "i", "Input file") argParser.parse(arrayOf("-output", "out.txt", "-i", "input.txt")) assertEquals("out.txt", output) assertEquals("input.txt", input) } enum class Renders { TEXT, HTML, XML, JSON } @Test fun testGNUPrefix() { val argParser = ArgParser("testParser", prefixStyle = ArgParser.OptionPrefixStyle.GNU) val output by argParser.option(ArgType.String, "output", "o", "Output file") val input by argParser.option(ArgType.String, "input", "i", "Input file") val verbose by argParser.option(ArgType.Boolean, "verbose", "v", "Verbose print") val shortForm by argParser.option(ArgType.Boolean, "short", "s", "Short output form") val text by argParser.option(ArgType.Boolean, "text", "t", "Use text format") argParser.parse(arrayOf("-oout.txt", "--input=input.txt", "-vst")) assertEquals("out.txt", output) assertEquals("input.txt", input) assertEquals(verbose, true) assertEquals(shortForm, true) assertEquals(text, true) } @Test fun testGNUArguments() { val argParser = ArgParser("testParser", prefixStyle = ArgParser.OptionPrefixStyle.GNU) val output by argParser.argument(ArgType.String, "output", "Output file") val input by argParser.argument(ArgType.String, "input", "Input file") val verbose by argParser.option(ArgType.Boolean, "verbose", "v", "Verbose print") val shortForm by argParser.option(ArgType.Boolean, "short", "s", "Short output form").default(false) val text by argParser.option(ArgType.Boolean, "text", "t", "Use text format").default(false) argParser.parse(arrayOf("--verbose", "--", "out.txt", "--input.txt")) assertEquals("out.txt", output) assertEquals("--input.txt", input) assertEquals(verbose, true) assertEquals(shortForm, false) assertEquals(text, false) } @Test fun testMultipleOptions() { val argParser = ArgParser("testParser") val useShortForm by argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) val renders by argParser.option(ArgType.Choice(), "renders", "r", "Renders for showing information").multiple().default(listOf(Renders.TEXT)) val sources by argParser.option(ArgType.Choice(), "sources", "ds", "Data sources").multiple().default(listOf(DataSourceEnum.PRODUCTION)) argParser.parse(arrayOf("-s", "-r", "text", "-r", "json", "-ds", "local", "-ds", "production")) assertEquals(true, useShortForm) assertEquals(2, renders.size) val (firstRender, secondRender) = renders assertEquals(Renders.TEXT, firstRender) assertEquals(Renders.JSON, secondRender) assertEquals(2, sources.size) val (firstSource, secondSource) = sources assertEquals(DataSourceEnum.LOCAL, firstSource) assertEquals(DataSourceEnum.PRODUCTION, secondSource) } @Test fun testDefaultOptions() { val argParser = ArgParser("testParser") val useShortForm by argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) val renders by argParser.option(ArgType.Choice(), "renders", "r", "Renders for showing information").multiple().default(listOf(Renders.TEXT)) val sources by argParser.option(ArgType.Choice(), "sources", "ds", "Data sources").multiple().default(listOf(DataSourceEnum.PRODUCTION)) val output by argParser.option(ArgType.String, "output", "o", "Output file") argParser.parse(arrayOf("-o", "out.txt")) assertEquals(false, useShortForm) assertEquals(Renders.TEXT, renders[0]) assertEquals(DataSourceEnum.PRODUCTION, sources[0]) } @Test fun testResetOptionsValues() { val argParser = ArgParser("testParser") val useShortFormOption = argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) var useShortForm by useShortFormOption val rendersOption = argParser.option(ArgType.Choice(), "renders", "r", "Renders for showing information").multiple().default(listOf(Renders.TEXT)) var renders by rendersOption val sourcesOption = argParser.option(ArgType.Choice(), "sources", "ds", "Data sources").multiple().default(listOf(DataSourceEnum.PRODUCTION)) var sources by sourcesOption val outputOption = argParser.option(ArgType.String, "output", "o", "Output file") var output by outputOption argParser.parse(arrayOf("-o", "out.txt")) output = null useShortForm = true renders = listOf() sources = listOf() assertEquals(true, useShortForm) assertEquals(null, output) assertEquals(0, renders.size) assertEquals(0, sources.size) assertEquals(ArgParser.ValueOrigin.REDEFINED, outputOption.valueOrigin) assertEquals(ArgParser.ValueOrigin.REDEFINED, useShortFormOption.valueOrigin) assertEquals(ArgParser.ValueOrigin.REDEFINED, rendersOption.valueOrigin) assertEquals(ArgParser.ValueOrigin.REDEFINED, sourcesOption.valueOrigin) } } ================================================ FILE: endorsedLibraries/kotlinx.cli/src/tests/SubcommandsTests.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalCli::class) package kotlinx.cli import kotlinx.cli.ArgParser import kotlinx.cli.ArgType import kotlinx.cli.ExperimentalCli import kotlinx.cli.Subcommand import kotlin.test.* class SubcommandsTests { @Test fun testSubcommand() { val argParser = ArgParser("testParser") val output by argParser.option(ArgType.String, "output", "o", "Output file") class Summary: Subcommand("summary", "Calculate summary") { val invert by option(ArgType.Boolean, "invert", "i", "Invert results") val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg() var result: Int = 0 override fun execute() { result = addendums.sum() result = if (invert!!) -1 * result else result } } val action = Summary() argParser.subcommands(action) argParser.parse(arrayOf("summary", "-o", "out.txt", "-i", "2", "3", "5")) assertEquals("out.txt", output) assertEquals(-10, action.result) } @Test fun testCommonOptions() { abstract class CommonOptions(name: String, actionDescription: String): Subcommand(name, actionDescription) { val numbers by argument(ArgType.Int, "numbers", description = "Numbers").vararg() } class Summary: CommonOptions("summary", "Calculate summary") { val invert by option(ArgType.Boolean, "invert", "i", "Invert results") var result: Int = 0 override fun execute() { result = numbers.sum() result = invert?.let { -1 * result } ?: result } } class Subtraction : CommonOptions("sub", "Calculate subtraction") { var result: Int = 0 override fun execute() { result = numbers.map { -it }.sum() } } val summaryAction = Summary() val subtractionAction = Subtraction() val argParser = ArgParser("testParser") argParser.subcommands(summaryAction, subtractionAction) argParser.parse(arrayOf("summary", "2", "3", "5")) assertEquals(10, summaryAction.result) val argParserSubtraction = ArgParser("testParser") argParserSubtraction.subcommands(summaryAction, subtractionAction) argParserSubtraction.parse(arrayOf("sub", "8", "-2", "3")) assertEquals(-9, subtractionAction.result) } @Test fun testRecursiveSubcommands() { val argParser = ArgParser("testParser") class Summary: Subcommand("summary", "Calculate summary") { val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg() var result: Int = 0 override fun execute() { result = addendums.sum() } } class Calculation: Subcommand("calc", "Execute calculation") { init { subcommands(Summary()) } val invert by option(ArgType.Boolean, "invert", "i", "Invert results") var result: Int = 0 override fun execute() { result = (subcommands["summary"] as Summary).result result = if (invert!!) -1 * result else result } } val action = Calculation() argParser.subcommands(action) argParser.parse(arrayOf("calc", "-i", "summary", "2", "3", "5")) assertEquals(-10, action.result) } @Test fun testCommonDefaultInSubcommand() { val parser = ArgParser("testParser") val output by parser.option(ArgType.String, "output", "o", "Output file") .default("any_file") class Summary: Subcommand("summary", "Calculate summary") { val invert by option(ArgType.Boolean, "invert", "i", "Invert results").default(false) val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg() var result: Int = 0 override fun execute() { result = addendums.sum() result = if (invert) -1 * result else result println("result is: $result and will output to $output") } } class Multiply: Subcommand("mul", "Multiply") { val numbers by argument(ArgType.Int, description = "Addendums").vararg() var result: Int = 0 override fun execute() { result = numbers.reduce{ acc, it -> acc * it } } } val summary = Summary() val multiple = Multiply() parser.subcommands(summary, multiple) parser.parse(arrayOf("summary", "1", "2", "4")) assertEquals("any_file", output) assertEquals(7, summary.result) } } ================================================ FILE: gradle/kotlinGradlePlugin.gradle ================================================ def properties = ['buildKotlinVersion', 'buildKotlinCompilerRepo', 'kotlinVersion', 'kotlinCompilerRepo'] for (prop in properties) { if (!hasProperty(prop)) { throw new GradleException("Please ensure the '$prop' property is defined before applying this script.") } } project.buildscript.repositories { maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } maven { url 'https://cache-redirector.jetbrains.com/maven-central' } mavenCentral() } project.buildscript.dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } configurations { kotlinCompilerClasspath } project.repositories { maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } } project.dependencies { kotlinCompilerClasspath("org.jetbrains.kotlin:kotlin-compiler-embeddable:$buildKotlinVersion") } ================================================ FILE: gradle/loadRootProperties.gradle ================================================ if (!project.hasProperty("rootBuildDirectory")) { throw new GradleException('Please ensure the "rootBuildDirectory" property is defined before applying this script.') } ext.distDir = file("$rootBuildDirectory/dist") def rootProperties = new Properties() def rootDir = file(rootBuildDirectory).absolutePath file("$rootDir/gradle.properties").withReader { rootProperties.load(it) } rootProperties.each { k, v -> if (!project.hasProperty(k)) { ext.set(k, v) } } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: gradle.properties ================================================ # # Copyright 2010-2019 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # A version of the Kotlin compiler that is used to build Kotlin/Native. buildKotlinVersion=1.5.20-dev-372 buildKotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-372,branch:default:any,pinned:true/artifacts/content/maven remoteRoot=konan_tests kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-1393,branch:default:any,pinned:true/artifacts/content/maven kotlinVersion=1.5.20-dev-1393 kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-1508,branch:default:any,pinned:true/artifacts/content/maven kotlinStdlibVersion=1.5.20-dev-1508 kotlinStdlibTestsVersion=1.5.20-dev-1508 testKotlinCompilerVersion=1.5.20-dev-1508 konanVersion=1.5.20 # A version of Xcode required to build the Kotlin/Native compiler. xcodeMajorVersion=12 # A GTest revision used to test the runtime. # The latest release GTest (1.10.0) doesn't properly register skipped tests in an XML-report. # Therefore we use a fixed commit form the master branch where this problem is already fixed. # https://github.com/google/googletest/commit/07f4869221012b16b7f9ee685d94856e1fc9f361 gtestRevision=07f4869221012b16b7f9ee685d94856e1fc9f361 org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.workers.max=4 slackApiVersion=1.2.0 ktorVersion=1.2.1 shadowVersion=5.1.0 metadataVersion=0.0.1-dev-10 # Uncomment to compile Kotlin/Native backend modules with JVM IR backend. # kotlin.build.useIR=true kotlin.internal.mpp12x.deprecation.suppress=true kotlin.mpp.stability.nowarn=true # Uncomment to enable composite build #kotlinProjectPath= ================================================ FILE: gradlew ================================================ #!/usr/bin/env sh # # Copyright 2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn () { echo "$*" } die () { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin or MSYS, switch paths to Windows format before running java if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=`expr $i + 1` done case $i in 0) set -- ;; 1) set -- "$args0" ;; 2) set -- "$args0" "$args1" ;; 3) set -- "$args0" "$args1" "$args2" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Escape application args save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" exec "$JAVACMD" "$@" ================================================ FILE: gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: klib/build.gradle ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:$gradlePluginVersion" } ext.useCustomDist = project.hasProperty("org.jetbrains.kotlin.native.home") || project.hasProperty("konan.home") if (!useCustomDist) { ext.setProperty("org.jetbrains.kotlin.native.home", distDir.absolutePath) } if (project.hasProperty("konan.home")) { ext.setProperty("org.jetbrains.kotlin.native.home", project.getProperty("konan.home")) } } apply plugin: 'kotlin' apply plugin: 'konan' konanArtifacts { def testFiles = fileTree('src/test/testData') { include "*.kt" } testFiles.files.each { file -> def name = file.name library(name.take(name.lastIndexOf('.'))) { srcFiles file.absolutePath // Build the compiler before building the test unless a custom path to the distribution is specified. if (!useCustomDist) { dependsOn ':dist' } } } } compileKotlin { kotlinOptions.freeCompilerArgs += ['-Xskip-prerelease-check'] } repositories { maven { url buildKotlinCompilerRepo } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation project(path: ':backend.native', configuration: 'cli_bc') implementation project(":utilities:basic-utils") testImplementation "junit:junit:4.12" testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$buildKotlinVersion" testImplementation "org.jetbrains.kotlin:kotlin-test:$buildKotlinVersion" } test { dependsOn 'cleanTest' // Specify a path to the distribution that is used in the tests. systemProperty('konan.home', getProperty("org.jetbrains.kotlin.native.home")) dependsOn konanArtifacts.collect { it.getByTarget('host') } if (useCustomDist) { // Use the klib utility from the distribution def distClasspath = fileTree("${project.getProperty("org.jetbrains.kotlin.native.home")}/konan/lib") { include "**/*.jar" } classpath = distClasspath + sourceSets.test.runtimeClasspath - sourceSets.main.runtimeClasspath } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/DeclarationHeaderRenderer.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.descriptors.DeclarationDescriptor interface DeclarationHeaderRenderer { fun render(descriptor: DeclarationDescriptor): String } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/DeclarationPrinter.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.utils.Printer class DeclarationPrinter( out: Appendable, private val headerRenderer: DeclarationHeaderRenderer, private val signatureRenderer: IdSignatureRenderer ) { private val printer = Printer(out, 1, " ") private val DeclarationDescriptorWithVisibility.isPublicOrProtected: Boolean get() = visibility == DescriptorVisibilities.PUBLIC || visibility == DescriptorVisibilities.PROTECTED private val CallableMemberDescriptor.isFakeOverride: Boolean get() = kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE private val DeclarationDescriptor.shouldBePrinted: Boolean get() = this is ClassifierDescriptorWithTypeParameters && isPublicOrProtected || this is CallableMemberDescriptor && isPublicOrProtected && !isFakeOverride fun print(module: ModuleDescriptor) { module.accept(PrinterVisitor(), Unit) } private fun Printer.printWithBody(header: String, signature: String? = null, body: () -> Unit) { println() printPlain(header, signature, suffix = " {") pushIndent() body() popIndent() println("}") println() } private fun Printer.printPlain(header: String, signature: String? = null, suffix: String? = null) { if (signature != null) println(signature) println(if (suffix != null ) header + suffix else header) } private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies() { override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) { descriptor.getPackageFragments().forEach { it.accept(this, data) } } override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) { val children = descriptor.getMemberScope().getContributedDescriptors() .filter { it.shouldBePrinted } .sortedBy { it.name } if (children.isNotEmpty()) { printer.printWithBody(header = headerRenderer.render(descriptor)) { children.forEach { it.accept(this, data) } } } } override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) { val header = headerRenderer.render(descriptor) val signature = signatureRenderer.render(descriptor) val children = descriptor.unsubstitutedMemberScope.getContributedDescriptors().filter { it.shouldBePrinted } val constructors = descriptor.constructors.filter { !it.isPrimary && it.shouldBePrinted } if (children.isNotEmpty() || constructors.isNotEmpty()) { printer.printWithBody(header, signature) { constructors.forEach { it.accept(this, data) } children.forEach { it.accept(this, data) } } } else { printer.printPlain(header, signature) } } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) { printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor)) } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) { printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor)) descriptor.getter?.takeIf { !it.annotations.isEmpty() }?.let { getter -> printer.pushIndent() printer.printPlain(header = headerRenderer.render(getter), signature = signatureRenderer.render(getter)) printer.popIndent() } descriptor.setter?.takeIf { !it.annotations.isEmpty() || it.visibility != descriptor.visibility }?.let { setter -> printer.pushIndent() printer.printPlain(header = headerRenderer.render(setter), signature = signatureRenderer.render(setter)) printer.popIndent() } } override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) { printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor)) } override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) { printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor)) } } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/DefaultDeclarationHeaderRenderer.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererModifier import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy object DefaultDeclarationHeaderRenderer : DeclarationHeaderRenderer { override fun render(descriptor: DeclarationDescriptor): String = when (descriptor) { is PackageFragmentDescriptor -> render(descriptor) is ClassifierDescriptorWithTypeParameters -> render(descriptor) is PropertyAccessorDescriptor -> render(descriptor) is CallableMemberDescriptor -> render(descriptor) else -> throw AssertionError("Unknown declaration descriptor type: $descriptor") } private fun render(descriptor: PackageFragmentDescriptor): String { val packageName = descriptor.fqName.let { if (it.isRoot) "" else it.asString() } return "package $packageName" } private fun render(descriptor: ClassifierDescriptorWithTypeParameters): String { val renderer = when (descriptor.modality) { // Don't render 'final' modality Modality.FINAL -> Renderers.WITHOUT_MODALITY else -> Renderers.DEFAULT } return renderer.render(descriptor) } private fun render(descriptor: CallableMemberDescriptor): String { val containingDeclaration = descriptor.containingDeclaration val renderer = when { // Don't render modality for non-override final methods and interface methods. containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.INTERFACE || descriptor.modality == Modality.FINAL && descriptor.overriddenDescriptors.isEmpty() -> Renderers.WITHOUT_MODALITY else -> Renderers.DEFAULT } return renderer.render(descriptor) } private fun render(descriptor: PropertyAccessorDescriptor) = buildString { descriptor.annotations.forEach { append(Renderers.DEFAULT.renderAnnotation(it)).append(" ") } if (descriptor.visibility != DescriptorVisibilities.DEFAULT_VISIBILITY) { append(descriptor.visibility.internalDisplayName).append(" ") } when (descriptor) { is PropertyGetterDescriptor -> append("get") is PropertySetterDescriptor -> append("set") else -> throw AssertionError("Unknown accessor descriptor type: $descriptor") } } private object Renderers { val DEFAULT = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions { modifiers = DescriptorRendererModifier.ALL overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY excludedAnnotationClasses += StandardNames.FqNames.suppress classWithPrimaryConstructor = true renderConstructorKeyword = true includePropertyConstant = true unitReturnType = false withDefinedIn = false renderDefaultVisibility = false secondaryConstructorsAsPrimary = false } val WITHOUT_MODALITY = DEFAULT.withOptions { modifiers -= DescriptorRendererModifier.MODALITY } } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/DefaultIdSignatureRenderer.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DeclarationDescriptor class DefaultIdSignatureRenderer(private val prefix: String? = null) : IdSignatureRenderer { private val idSignaturer = KonanIdSignaturer(KonanManglerDesc) override fun render(descriptor: DeclarationDescriptor): String? { val idSignature = if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) { idSignaturer.composeEnumEntrySignature(descriptor) } else { idSignaturer.composeSignature(descriptor) } ?: return null return if (prefix != null) prefix + idSignature.render() else idSignature.render() } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/IdSignatureRenderer.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.descriptors.DeclarationDescriptor interface IdSignatureRenderer { fun render(descriptor: DeclarationDescriptor): String? companion object { val NO_SIGNATURE = object : IdSignatureRenderer { override fun render(descriptor: DeclarationDescriptor): String? = null } } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/SignaturePrinter.kt ================================================ package org.jetbrains.kotlin.cli.klib import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.utils.Printer class SignaturePrinter( out: Appendable, private val signatureRenderer: IdSignatureRenderer ) { private val printer = Printer(out) fun print(module: ModuleDescriptor) { module.accept(PrinterVisitor(), Unit) } private fun Printer.printlnIfNotNull(line: String?) { if (line != null) println(line) } private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies() { override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) { descriptor.getPackageFragments().forEach { it.accept(this, data) } } override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) { descriptor.getMemberScope().getContributedDescriptors().forEach { it.accept(this, data) } } override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) { printer.printlnIfNotNull(signatureRenderer.render(descriptor)) descriptor.constructors.forEach { it.accept(this, data) } descriptor.unsubstitutedMemberScope.getContributedDescriptors().forEach { it.accept(this, data) } } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) { printer.printlnIfNotNull(signatureRenderer.render(descriptor)) } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) { printer.printlnIfNotNull(signatureRenderer.render(descriptor)) descriptor.getter?.let { printer.printlnIfNotNull(signatureRenderer.render(it)) } descriptor.setter?.let { printer.printlnIfNotNull(signatureRenderer.render(it)) } } override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) { printer.printlnIfNotNull(signatureRenderer.render(descriptor)) } override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) { printer.printlnIfNotNull(signatureRenderer.render(descriptor)) } } } ================================================ FILE: klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.klib // TODO: Extract `library` package as a shared jar? import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.util.DependencyProcessor import org.jetbrains.kotlin.library.unpackZippedKonanLibraryTo import org.jetbrains.kotlin.konan.util.KlibMetadataFactories import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.library.resolverByName import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION_WITH_DOT import org.jetbrains.kotlin.library.metadata.parseModuleHeader import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.util.removeSuffixIfPresent import kotlin.system.exitProcess internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None) fun printUsage() { println("Usage: klib ") println("where the commands are:") println("\tinfo\tgeneral information about the library") println("\tinstall\tinstall the library to the local repository") println("\tcontents\tlist contents of the library") println("\tsignatures\tlist of ID signatures in the library") println("\tremove\tremove the library from the local repository") println("and the options are:") println("\t-repository \twork with the specified repository") println("\t-target \tinspect specifics of the given target") println("\t-print-signatures [true|false]\tprint ID signature for every declaration (only for \"contents\" command)") } private fun parseArgs(args: Array): Map> { val commandLine = mutableMapOf>() for (index in args.indices step 2) { val key = args[index] if (key[0] != '-') { throw IllegalArgumentException("Expected a flag with initial dash: $key") } if (index + 1 == args.size) { throw IllegalArgumentException("Expected an value after $key") } val value = listOf(args[index + 1]) commandLine[key]?.addAll(value) ?: commandLine.put(key, value.toMutableList()) } return commandLine } class Command(args: Array) { init { if (args.size < 2) { printUsage() exitProcess(0) } } val verb = args[0] val library = args[1] val options = parseArgs(args.drop(2).toTypedArray()) } fun warn(text: String) { println("warning: $text") } fun error(text: String): Nothing { kotlin.error("error: $text") } object KlibToolLogger : Logger { override fun warning(message: String) = org.jetbrains.kotlin.cli.klib.warn(message) override fun error(message: String) = org.jetbrains.kotlin.cli.klib.warn(message) override fun fatal(message: String) = org.jetbrains.kotlin.cli.klib.error(message) override fun log(message: String) = println(message) } val defaultRepository = File(DependencyProcessor.localKonanDir.resolve("klib").absolutePath) open class ModuleDeserializer(val library: ByteArray) { protected val moduleHeader: KlibMetadataProtoBuf.Header get() = parseModuleHeader(library) val moduleName: String get() = moduleHeader.moduleName val packageFragmentNameList: List get() = moduleHeader.packageFragmentNameList } class Library(val libraryNameOrPath: String, val requestedRepository: String?, val target: String) { val repository = requestedRepository?.File() ?: defaultRepository fun info() { val library = libraryInRepoOrCurrentDir(repository, libraryNameOrPath) val headerAbiVersion = library.versions.abiVersion val headerCompilerVersion = library.versions.compilerVersion val headerLibraryVersion = library.versions.libraryVersion val headerMetadataVersion = library.versions.metadataVersion val headerIrVersion = library.versions.irVersion val moduleName = ModuleDeserializer(library.moduleHeaderData).moduleName println("") println("Resolved to: ${library.libraryName.File().absolutePath}") println("Module name: $moduleName") println("ABI version: $headerAbiVersion") println("Compiler version: ${headerCompilerVersion}") println("Library version: $headerLibraryVersion") println("Metadata version: $headerMetadataVersion") println("IR version: $headerIrVersion") if (library is KonanLibrary) { val targets = library.targetList.joinToString(", ") print("Available targets: $targets\n") } } fun install() { if (!repository.exists) { warn("Repository does not exist: $repository. Creating.") repository.mkdirs() } val libraryTrueName = File(libraryNameOrPath).name.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT) val library = libraryInCurrentDir(libraryNameOrPath) val installLibDir = File(repository, libraryTrueName) if (installLibDir.exists) installLibDir.deleteRecursively() library.libraryFile.unpackZippedKonanLibraryTo(installLibDir) } fun remove(blind: Boolean = false) { if (!repository.exists) error("Repository does not exist: $repository") val library = try { val library = libraryInRepo(repository, libraryNameOrPath) if (blind) warn("Removing The previously installed $libraryNameOrPath from $repository.") library } catch (e: Throwable) { if (!blind) println(e.message) null } library?.libraryFile?.deleteRecursively() } fun contents(output: Appendable, printSignatures: Boolean) { val module = loadModule() val signatureRenderer = if (printSignatures) DefaultIdSignatureRenderer("// ID signature: ") else IdSignatureRenderer.NO_SIGNATURE val printer = DeclarationPrinter(output, DefaultDeclarationHeaderRenderer, signatureRenderer) printer.print(module) } fun signatures(output: Appendable) { val module = loadModule() val printer = SignaturePrinter(output, DefaultIdSignatureRenderer()) printer.print(module) } private fun loadModule(): ModuleDescriptor { val storageManager = LockBasedStorageManager("klib") val library = libraryInRepoOrCurrentDir(repository, libraryNameOrPath) val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion) val module = KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, versionSpec, storageManager, null) val defaultModules = mutableListOf() if (!module.isNativeStdlib()) { val resolver = resolverByName( emptyList(), distributionKlib = Distribution(KonanHomeProvider.determineKonanHome()).klib, skipCurrentDir = true, logger = KlibToolLogger ) resolver.defaultLinks(false, true, true).mapTo(defaultModules) { KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(it, versionSpec, storageManager, module.builtIns, null) } } (defaultModules + module).let { allModules -> allModules.forEach { it.setDependencies(allModules) } } return module } } val currentLanguageVersion = LanguageVersion.LATEST_STABLE val currentApiVersion = ApiVersion.LATEST_STABLE fun libraryInRepo(repository: File, name: String) = resolverByName(listOf(repository.absolutePath), skipCurrentDir = true, logger = KlibToolLogger).resolve(name) fun libraryInCurrentDir(name: String) = resolverByName(emptyList(), logger = KlibToolLogger).resolve(name) fun libraryInRepoOrCurrentDir(repository: File, name: String) = resolverByName(listOf(repository.absolutePath), logger = KlibToolLogger).resolve(name) fun main(args: Array) { val command = Command(args) val targetManager = PlatformManager(KonanHomeProvider.determineKonanHome()) .targetManager(command.options["-target"]?.last()) val target = targetManager.targetName val repository = command.options["-repository"]?.last() val printSignatures = command.options["-print-signatures"]?.last()?.toBoolean() == true val library = Library(command.library, repository, target) when (command.verb) { "contents" -> library.contents(System.out, printSignatures) "signatures" -> library.signatures(System.out) "info" -> library.info() "install" -> library.install() "remove" -> library.remove() else -> error("Unknown command ${command.verb}.") } } ================================================ FILE: klib/src/test/kotlin/org/jetbrains/kotlin/cli/klib/test/ContentsTest.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.klib.test import com.intellij.openapi.util.text.StringUtil import kotlin.test.* import org.jetbrains.kotlin.cli.klib.* import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.HostManager import java.nio.file.Paths class ContentsTest { private fun testLibrary(name: String) = LIBRARY_DIRECTORY.resolve("$name.klib").toFile().absolutePath private fun klibContents(library: String, printOutput: Boolean = false, expected: () -> String) { val output = StringBuilder() val lib = Library(library, null, "host") lib.contents(output, false) if (printOutput) { println(output.trim().toString()) } assertEquals( StringUtil.convertLineSeparators(expected()), StringUtil.convertLineSeparators(output.trim().toString()), "klib contents test failed for library: $library" ) } @Test fun `Stdlib content should be printed without exceptions`() { val output = StringBuilder() val distributionPath = System.getProperty("konan.home") Library(Distribution(distributionPath).stdlib, null, "host").contents(output, false) } @Test fun topLevelFunctions() = klibContents(testLibrary("TopLevelFunctions")) { """ package { annotation class A constructor() : Annotation annotation class B constructor() : Annotation class Foo constructor() } package { @A @B fun a() fun Foo.e() fun f1(x: Foo) fun f2(x: Foo, y: Foo): Int inline fun i1(block: () -> Foo) inline fun i2(noinline block: () -> Foo) inline fun i3(crossinline block: () -> Foo) fun i4(block: (Foo) -> Int) fun i5(block: (Foo, Foo) -> Int) fun i6(block: Foo.() -> Int) fun i7(block: Foo.(Foo) -> Int) fun t1(x: Foo) fun t2(x: T) fun t3(x: T, y: F) inline fun t4(x: T) fun t5(x: T) } """.trimIndent() } @Test fun constructors() = klibContents(testLibrary("Constructors")) { """ package { annotation class A constructor() : Annotation class Bar @A constructor(x: Int) class Baz private constructor(x: Int) class Foo constructor(x: Int) { constructor() constructor(x: Double) constructor(x: Double, y: Int) protected constructor(x: String) @A constructor(x: Foo) } class Qux protected constructor(x: Int) class Typed constructor(x: Int) { constructor() constructor(x: Double) constructor(x: Double, y: Int) protected constructor(x: String) @A constructor(x: Foo) } } """.trimIndent() } @Test fun objects() = klibContents(testLibrary("Objects")) { """ package { object A { fun a() } class B constructor() { object C { fun c() } companion object { fun b() } } class D constructor() { companion object E { fun e() } } } """.trimIndent() } @Test fun classes() = klibContents(testLibrary("Classes")) { """ package { class A constructor() { val aVal: Int = 0 var aVar: String fun aFun() inner class B constructor() { val bVal: Int = 0 var bVar: String fun bFun() inner class C constructor() { val cVal: Int = 0 var cVar: String fun cFun() } } class E constructor() { val eVal: Int = 0 var eVar: String fun eFun() } } data class F constructor(fVal: Int, fVar: String) { val fVal: Int var fVar: String operator fun component1(): Int operator fun component2(): String fun copy(fVal: Int = ..., fVar: String = ...): F override fun equals(other: Any?): Boolean fun fFun() override fun hashCode(): Int override fun toString(): String } class FinalImpl constructor() : OpenImpl { override val iVal: Int = 0 override var iVar: String override fun iFun() } interface Interface { val iVal: Int var iVar: String fun iFun() } open class OpenImpl constructor() : Interface { override val iVal: Int = 0 override var iVar: String override fun iFun() } } """.trimIndent() } @Test fun methodModality() = klibContents(testLibrary("MethodModality")) { """ package { abstract class AbstractClass constructor() : Interface { abstract fun abstractFun() override fun interfaceFun() } class FinalClass constructor() : OpenClass { override fun openFun1() final override fun openFun2() } interface Interface { fun interfaceFun() } open class OpenClass constructor() : AbstractClass { override fun abstractFun() fun finalFun() open fun openFun1() open fun openFun2() } } """.trimIndent() } @Test fun functionModifiers() = klibContents(testLibrary("FunctionModifiers")) { """ package { class Foo constructor() { fun f1() infix fun f2(x: Int) suspend fun f3() tailrec fun f4() fun f5(vararg x: Int) operator fun plus(x: Int) } } """.trimIndent() } @Test // TODO: Support enum entry methods in serialization/deserialization. fun enum() = klibContents(testLibrary("Enum")) { """ package { enum class E private constructor(x: Int = ...) : Enum { enum entry A enum entry B enum entry C val enumVal: Int = 0 var enumVar: String val x: Int open fun enumFun(): Int } } """.trimIndent() } @Test // TODO: Support getter/setter annotations in serialization/deserialization. fun accessors() = klibContents(testLibrary("Accessors")) { """ package custom.pkg { annotation class A constructor() : Annotation class Foo constructor() { @A val annotated: Int = 0 var annotatedAccessors: Int @A get @A set val annotatedGetter: Int = 0 @A get var annotatedSetter: Int @A set var privateSetter: Int private set protected val protectedSimple: Int = 0 val simple: Int = 0 } } """.trimIndent() } @Test fun topLevelPropertiesCustomPackage() = klibContents(testLibrary("TopLevelPropertiesCustomPackage")) { """ package custom.pkg { typealias MyTransformer = (String) -> Int } package custom.pkg { val v1: Int = 1 val v2: String = "hello" val v3: (String) -> Int val v4: MyTransformer /* = (String) -> Int */ } """.trimIndent() } @Test fun topLevelPropertiesRootPackage() = klibContents(testLibrary("TopLevelPropertiesRootPackage")) { """ package { typealias MyTransformer = (String) -> Int } package { val v1: Int = 1 val v2: String = "hello" val v3: (String) -> Int val v4: MyTransformer /* = (String) -> Int */ } """.trimIndent() } @Test fun topLevelPropertiesWithClassesCustomPackage() = klibContents(testLibrary("TopLevelPropertiesWithClassesCustomPackage")) { """ package custom.pkg { object Bar class Foo constructor() typealias MyTransformer = (String) -> Int } package custom.pkg { val v1: Int = 1 val v2: String = "hello" val v3: (String) -> Int val v4: MyTransformer /* = (String) -> Int */ } """.trimIndent() } @Test fun topLevelPropertiesWithClassesRootPackage() = klibContents(testLibrary("TopLevelPropertiesWithClassesRootPackage")) { """ package { object Bar class Foo constructor() typealias MyTransformer = (String) -> Int } package { val v1: Int = 1 val v2: String = "hello" val v3: (String) -> Int val v4: MyTransformer /* = (String) -> Int */ } """.trimIndent() } companion object { val LIBRARY_DIRECTORY = Paths.get("build/konan/libs").resolve(HostManager.hostName) } } ================================================ FILE: klib/src/test/testData/Accessors.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package custom.pkg annotation class A class Foo { val simple = 0 private val privateSimple = 0 protected val protectedSimple = 0 var privateSetter = 0 private set @A val annotated = 0 val annotatedGetter = 0 @A get var annotatedSetter = 0 @A set var annotatedAccessors = 0 @A set @A get } ================================================ FILE: klib/src/test/testData/Classes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class A { fun aFun() {} val aVal = 0 var aVar = "" inner class B { fun bFun() {} val bVal = 0 var bVar = "" inner class C { fun cFun() {} val cVal = 0 var cVar = "" } private inner class D { fun dFun() {} val dVal = 0 var dVar = "" } } class E { fun eFun() {} val eVal = 0 var eVar = "" } } data class F(val fVal: Int, var fVar: String) { fun fFun() {} } interface Interface { fun iFun() val iVal: Int var iVar: String } open class OpenImpl: Interface { override fun iFun() {} override val iVal = 0 override var iVar = "" } class FinalImpl: OpenImpl() { override fun iFun() {} override val iVal = 0 override var iVar = "" } ================================================ FILE: klib/src/test/testData/Constructors.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") annotation class A class Foo(x: Int) { constructor(): this(0) constructor(x: Double): this(x.toInt()) constructor(x: Double, y: Int): this(y) private constructor(x: Long): this(0) protected constructor(x: String): this(0) @A constructor(x: Foo) : this(0) } class Bar @A constructor(x: Int) class Baz private constructor(x: Int) class Qux protected constructor(x: Int) class Typed(x: Int) { constructor(): this(0) constructor(x: Double): this(x.toInt()) constructor(x: Double, y: Int): this(y) private constructor(x: Long): this(0) protected constructor(x: String): this(0) @A constructor(x: Foo) : this(0) } ================================================ FILE: klib/src/test/testData/Enum.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ enum class E(val x: Int = 0) { A, B, C(1) { override fun enumFun() = 42 }; open fun enumFun(): Int = 0 val enumVal = 0 var enumVar = "" } ================================================ FILE: klib/src/test/testData/FunctionModifiers.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ class Foo { fun f1() {} infix fun f2(x: Int) {} suspend fun f3() {} operator fun plus(x: Int) {} tailrec fun f4() {} fun f5(vararg x: Int) {} } ================================================ FILE: klib/src/test/testData/MethodModality.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ interface Interface { fun interfaceFun() } abstract class AbstractClass: Interface { override fun interfaceFun() {} abstract fun abstractFun() } open class OpenClass: AbstractClass() { override fun abstractFun() {} open fun openFun1() {} open fun openFun2() {} fun finalFun() {} } class FinalClass: OpenClass() { override fun openFun1() {} final override fun openFun2() {} } ================================================ FILE: klib/src/test/testData/Objects.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ object A { fun a() {} } class B { companion object { fun b() {} } object C { fun c() {} } } class D { companion object E { fun e() {} } } ================================================ FILE: klib/src/test/testData/TopLevelFunctions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") annotation class A annotation class B class Foo fun f1(x: Foo): Unit {} fun f2(x: Foo, y: Foo) = 0 // inline inline fun i1(block: () -> Foo) {} inline fun i2(noinline block: () -> Foo) {} inline fun i3(crossinline block: () -> Foo) {} // callable args fun i4(block: (Foo) -> Int) {} fun i5(block: (Foo, Foo) -> Int) {} fun i6(block: Foo.() -> Int) {} fun i7(block: Foo.(Foo) -> Int) {} // type parameters fun t1(x: Foo) {} fun t2(x: T) {} fun t3(x: T, y: F) {} inline fun t4(x: T) {} fun t5(x: T) {} // extension fun Foo.e() {} // annotations @A @B fun a() {} ================================================ FILE: klib/src/test/testData/TopLevelPropertiesCustomPackage.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") package custom.pkg typealias MyTransformer = (String) -> Int // top-level properties val v1 = 1 val v2 = "hello" val v3: (String) -> Int = { it.length } val v4: MyTransformer = v3 ================================================ FILE: klib/src/test/testData/TopLevelPropertiesRootPackage.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") typealias MyTransformer = (String) -> Int // top-level properties val v1 = 1 val v2 = "hello" val v3: (String) -> Int = { it.length } val v4: MyTransformer = v3 ================================================ FILE: klib/src/test/testData/TopLevelPropertiesWithClassesCustomPackage.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") package custom.pkg class Foo typealias MyTransformer = (String) -> Int // top-level properties val v1 = 1 val v2 = "hello" val v3: (String) -> Int = { it.length } val v4: MyTransformer = v3 object Bar ================================================ FILE: klib/src/test/testData/TopLevelPropertiesWithClassesRootPackage.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNUSED_PARAMETER") class Foo typealias MyTransformer = (String) -> Int // top-level properties val v1 = 1 val v2 = "hello" val v3: (String) -> Int = { it.length } val v4: MyTransformer = v3 object Bar ================================================ FILE: konan/konan.properties ================================================ # # Copyright 2010-2018 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # TODO: Do we need a $variable substitution mechanism here? dependenciesUrl = https://download.jetbrains.com/kotlin/native # In order of preference: dependencyProfiles = default alt # Don't check dependencies on a server. # If true, dependency downloader will throw an exception if a dependency isn't found in $KONAN_DATA_DIR/dependencies airplaneMode = false # if true, ignores Xcode version check. ignoreXcodeVersionCheck = false minimalXcodeVersion=11.0 downloadingAttempts = 10 downloadingAttemptIntervalMs = 3000 homeDependencyCache = .konan/cache # Appendix that is used for smaller version of LLVM distributions. reducedLlvmAppendix = compact predefinedLlvmDistributions = \ clang-llvm-8.0.0-linux-x86-64 \ msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 \ clang-llvm-apple-8.0.0-darwin-macos llvm.linux_x64.dev = clang-llvm-8.0.0-linux-x86-64 llvm.linux_x64.user = clang-llvm-8.0.0-linux-x86-64 llvm.mingw_x64.dev = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 llvm.mingw_x64.user = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 llvm.macos_x64.dev = clang-llvm-apple-8.0.0-darwin-macos llvm.macos_x64.user = clang-llvm-apple-8.0.0-darwin-macos # By default LLVM uses 250 for -03 builds. # We use a smaller value since default value leads to # unreasonably bloated runtime code without any measurable # performance benefits. # This value still has to be tuned for different targets, though. llvmInlineThreshold = 100 clangDebugFlags = -O0 linkerGccFlags = -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed llvmVersion.linux_x64 = 8.0.0 llvmVersion.mingw_x64 = 8.0.1 llvmVersion.macos_x64 = 8.0.0 cacheableTargets.macos_x64 = \ macos_x64 \ ios_x64 \ ios_arm64 cacheableTargets.linux_x64 = \ linux_x64 cacheableTargets.mingw_x64 = # Mac OS X. # Can be an absolute path instead of predefined value. llvmHome.macos_x64 = $llvm.macos_x64.dev targetToolchain.macos_x64 = target-toolchain-xcode_12_2-macos_x64 libffiDir.macos_x64 = libffi-3.2.1-3-darwin-macos additionalToolsDir.macos_x64 = xcode-addon-xcode_12_2-macos_x64 arch.macos_x64 = x86_64 targetSysRoot.macos_x64 = target-sysroot-xcode_12_2-macos_x64 targetCpu.macos_x64 = core2 clangFlags.macos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.macos_x64 = -O1 clangOptFlags.macos_x64 = -O3 clangDebugFlags.macos_x64 = -O0 linkerKonanFlags.macos_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 10.15.6 linkerOptimizationFlags.macos_x64 = -dead_strip linkerNoDebugFlags.macos_x64 = -S stripFlags.macos_x64 = -S linkerDynamicFlags.macos_x64 = -dylib osVersionMinFlagLd.macos_x64 = -macosx_version_min osVersionMinFlagClang.macos_x64 = -mmacosx-version-min osVersionMin.macos_x64 = 10.11 runtimeDefinitions.macos_x64 = KONAN_OSX=1 KONAN_MACOSX=1 KONAN_X64=1 KONAN_OBJC_INTEROP=1 \ KONAN_CORE_SYMBOLICATION=1 dependencies.macos_x64 = \ libffi-3.2.1-3-darwin-macos \ lldb-3-macos target-sysroot-xcode_12_2-macos_x64.default = \ remote:internal target-toolchain-xcode_12_2-macos_x64.default = \ remote:internal xcode-addon-xcode_12_2-macos_x64.default = \ remote:internal # macOS Apple Silicon targetToolchain.macos_x64-macos_arm64 = target-toolchain-xcode_12_2-macos_x64 arch.macos_arm64 = arm64 targetSysRoot.macos_arm64 = target-sysroot-xcode_12_2-macos_x64 # TODO: Check Clang behaviour. targetCpu.macos_arm64 = cyclone clangFlags.macos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.macos_arm64 = -O1 clangOptFlags.macos_arm64 = -O3 # See clangDebugFlags.ios_arm64 # TODO: Is it still necessary? clangDebugFlags.macos_arm64 = -O0 -mllvm -fast-isel=false -mllvm -global-isel=false linkerKonanFlags.macos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 11.0.1 linkerOptimizationFlags.macos_arm64 = -dead_strip linkerNoDebugFlags.macos_arm64 = -S stripFlags.macos_arm64 = -S linkerDynamicFlags.macos_arm64 = -dylib osVersionMinFlagLd.macos_arm64 = -macosx_version_min osVersionMinFlagClang.macos_arm64 = -mmacosx-version-min osVersionMin.macos_arm64 = 11.0 runtimeDefinitions.macos_arm64 = KONAN_OSX=1 KONAN_MACOSX=1 KONAN_ARM64=1 KONAN_OBJC_INTEROP=1 \ KONAN_CORE_SYMBOLICATION=1 dependencies.macos_x64-macos_arm64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-macos_arm64.default = \ remote:internal # Apple's 32-bit iOS. targetToolchain.macos_x64-ios_arm32 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-ios_arm32 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-ios_arm32.default = \ remote:internal arch.ios_arm32 = armv7 # Shared with 64-bit version. targetSysRoot.ios_arm32 = target-sysroot-xcode_12_2-ios_arm64 targetCpu.ios_arm32 = generic clangFlags.ios_arm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.ios_arm32 = -O1 clangOptFlags.ios_arm32 = -O3 clangDebugFlags.ios_arm32 = -O0 linkerNoDebugFlags.ios_arm32 = -S stripFlags.ios_arm32 = -S linkerDynamicFlags.ios_arm32 = -dylib linkerKonanFlags.ios_arm32 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 14.0 linkerOptimizationFlags.ios_arm32 = -dead_strip osVersionMinFlagLd.ios_arm32 = -iphoneos_version_min osVersionMinFlagClang.ios_arm32 = -miphoneos-version-min osVersionMin.ios_arm32 = 9.0 # Regarding KONAN_NO_64BIT_ATOMIC: # While not 100% correct here, using atomic ops on iOS armv7 requires 8 byte alignment, # and general ABI requires 4-byte alignment on 64-bit long fields as mentioned in # https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html#//apple_ref/doc/uid/TP40009021-SW1 # See https://github.com/ktorio/ktor/issues/941 for the context. runtimeDefinitions.ios_arm32 = KONAN_OBJC_INTEROP=1 KONAN_IOS KONAN_ARM32=1 \ KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1 MACHSIZE=32 \ KONAN_NO_64BIT_ATOMIC=1 KONAN_NO_UNALIGNED_ACCESS=1 # Apple's 64-bit iOS. targetToolchain.macos_x64-ios_arm64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-ios_arm64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-ios_arm64.default = \ remote:internal arch.ios_arm64 = arm64 targetSysRoot.ios_arm64 = target-sysroot-xcode_12_2-ios_arm64 targetCpu.ios_arm64 = cyclone clangFlags.ios_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.ios_arm64 = -O1 clangOptFlags.ios_arm64 = -O3 # We force LLVM to use SelectionDAG because fast isel may miscompile sign extension. # Related: # https://github.com/JetBrains/kotlin-native/issues/3290 clangDebugFlags.ios_arm64 = -O0 -mllvm -fast-isel=false -mllvm -global-isel=false linkerNoDebugFlags.ios_arm64 = -S stripFlags.ios_arm64 = -S linkerDynamicFlags.ios_arm64 = -dylib linkerKonanFlags.ios_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 14.0 linkerOptimizationFlags.ios_arm64 = -dead_strip osVersionMinFlagLd.ios_arm64 = -iphoneos_version_min osVersionMinFlagClang.ios_arm64 = -miphoneos-version-min osVersionMin.ios_arm64 = 9.0 runtimeDefinitions.ios_arm64 = KONAN_OBJC_INTEROP=1 KONAN_IOS=1 KONAN_ARM64=1 \ KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1 MACHSIZE=64 additionalCacheFlags.ios_arm64 = -Xembed-bitcode-marker # Apple's iOS simulator. targetToolchain.macos_x64-ios_x64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-ios_x64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-ios_x64.default = \ remote:internal arch.ios_x64 = x86_64 targetSysRoot.ios_x64 = target-sysroot-xcode_12_2-ios_x64 targetCpu.ios_x64 = core2 clangFlags.ios_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.ios_x64 = -O1 clangOptFlags.ios_x64 = -O3 clangDebugFlags.ios_x64 = -O0 linkerKonanFlags.ios_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 14.0 linkerOptimizationFlags.ios_x64 = -dead_strip linkerNoDebugFlags.ios_x64 = -S stripFlags.ios_x64 = -S linkerDynamicFlags.ios_x64 = -dylib osVersionMinFlagLd.ios_x64 = -ios_simulator_version_min osVersionMinFlagClang.ios_x64 = -mios-simulator-version-min osVersionMin.ios_x64 = 9.0 runtimeDefinitions.ios_x64 = KONAN_OBJC_INTEROP=1 KONAN_IOS=1 KONAN_X64=1 \ KONAN_CORE_SYMBOLICATION=1 # Apple's tvOS simulator. targetToolchain.macos_x64-tvos_x64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-tvos_x64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-tvos_x64.default = \ remote:internal arch.tvos_x64 = x86_64 targetSysRoot.tvos_x64 = target-sysroot-xcode_12_2-tvos_x64 targetCpu.tvos_x64 = core2 clangFlags.tvos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.tvos_x64 = -O1 clangOptFlags.tvos_x64 = -O3 clangDebugFlags.tvos_x64 = -O0 linkerKonanFlags.tvos_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 14.0 linkerOptimizationFlags.tvos_x64 = -dead_strip linkerNoDebugFlags.tvos_x64 = -S stripFlags.tvos_x64 = -S linkerDynamicFlags.tvos_x64 = -dylib osVersionMinFlagLd.tvos_x64 = -tvos_simulator_version_min osVersionMinFlagClang.tvos_x64 = -mtvos-simulator-version-min osVersionMin.tvos_x64 = 9.0 runtimeDefinitions.tvos_x64 = KONAN_OBJC_INTEROP=1 KONAN_TVOS=1 KONAN_X64=1 \ KONAN_CORE_SYMBOLICATION=1 # Apple's 64-bit tvOS. targetToolchain.macos_x64-tvos_arm64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-tvos_arm64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-tvos_arm64.default = \ remote:internal arch.tvos_arm64 = arm64 targetSysRoot.tvos_arm64 = target-sysroot-xcode_12_2-tvos_arm64 targetCpu.tvos_arm64 = cyclone clangFlags.tvos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.tvos_arm64 = -O1 clangOptFlags.tvos_arm64 = -O3 clangDebugFlags.tvos_arm64 = -O0 -mllvm -fast-isel=false -mllvm -global-isel=false linkerNoDebugFlags.tvos_arm64 = -S stripFlags.tvos_arm64 = -S linkerDynamicFlags.tvos_arm64 = -dylib linkerKonanFlags.tvos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 14.0 linkerOptimizationFlags.tvos_arm64 = -dead_strip osVersionMinFlagLd.tvos_arm64 = -tvos_version_min osVersionMinFlagClang.tvos_arm64 = -mtvos-version-min osVersionMin.tvos_arm64 = 9.0 runtimeDefinitions.tvos_arm64 = KONAN_OBJC_INTEROP=1 KONAN_TVOS=1 KONAN_ARM64=1 \ KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1 MACHSIZE=64 # watchOS armv7k targetToolchain.macos_x64-watchos_arm32 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-watchos_arm32 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-watchos_arm32.default = \ remote:internal arch.watchos_arm32 = armv7k targetSysRoot.watchos_arm32 = target-sysroot-xcode_12_2-watchos_arm32 targetCpu.watchos_arm32 = cortex-a7 clangFlags.watchos_arm32 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.watchos_arm32 = -O1 clangOptFlags.watchos_arm32 = -O3 clangDebugFlags.watchos_arm32 = -O0 linkerKonanFlags.watchos_arm32 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 7.0 linkerOptimizationFlags.watchos_arm32 = -dead_strip linkerNoDebugFlags.watchos_arm32 = -S stripFlags.watchos_arm32 = -S linkerDynamicFlags.watchos_arm32 = -dylib osVersionMinFlagLd.watchos_arm32 = -watchos_version_min osVersionMinFlagClang.watchos_arm32 = -mwatchos-version-min osVersionMin.watchos_arm32 = 5.0 # Regarding KONAN_NO_64BIT_ATOMIC=1: see explanation for ios_arm32 above. runtimeDefinitions.watchos_arm32 = KONAN_OBJC_INTEROP=1 KONAN_WATCHOS KONAN_ARM32=1 \ KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1 \ MACHSIZE=32 KONAN_NO_64BIT_ATOMIC=1 KONAN_NO_UNALIGNED_ACCESS=1 # watchOS arm64_32 targetToolchain.macos_x64-watchos_arm64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-watchos_arm64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-watchos_arm64.default = \ remote:internal arch.watchos_arm64 = arm64_32 targetSysRoot.watchos_arm64 = target-sysroot-xcode_12_2-watchos_arm32 targetCpu.watchos_arm64 = cortex-a7 clangFlags.watchos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir -mllvm -aarch64-watch-bitcode-compatibility \ -mllvm -arm-bitcode-compatibility -mllvm -fast-isel=false -mllvm -global-isel=false clangNooptFlags.watchos_arm64 = -O1 clangOptFlags.watchos_arm64 = -O3 clangDebugFlags.watchos_arm64 = -O0 linkerKonanFlags.watchos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 7.0 linkerOptimizationFlags.watchos_arm64 = -dead_strip linkerNoDebugFlags.watchos_arm64 = -S stripFlags.watchos_arm64 = -S linkerDynamicFlags.watchos_arm64 = -dylib osVersionMinFlagLd.watchos_arm64 = -watchos_version_min osVersionMinFlagClang.watchos_arm64 = -mwatchos-version-min osVersionMin.watchos_arm64 = 5.0 # Regarding KONAN_NO_64BIT_ATOMIC=1: see explanation for ios_arm32 above. runtimeDefinitions.watchos_arm64 = KONAN_OBJC_INTEROP=1 KONAN_WATCHOS KONAN_ARM32=1 \ KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1 \ MACHSIZE=32 KONAN_NO_64BIT_ATOMIC=1 KONAN_NO_UNALIGNED_ACCESS=1 # Apple's watchOS i386 simulator. targetToolchain.macos_x64-watchos_x86 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-watchos_x86 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-watchos_x86.default = \ remote:internal arch.watchos_x86 = i386 targetSysRoot.watchos_x86 = target-sysroot-xcode_12_2-watchos_x86 # -target-cpu pentium4 makes sure that code-generator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can remove this flag. targetCpu.watchos_x86 = pentium4 clangFlags.watchos_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu $targetCpu.watchos_x86 clangNooptFlags.watchos_x86 = -O1 clangOptFlags.watchos_x86 = -O3 clangDebugFlags.watchos_x86 = -O0 linkerKonanFlags.watchos_x86 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 7.0 linkerOptimizationFlags.watchos_x86 = -dead_strip linkerNoDebugFlags.watchos_x86 = -S stripFlags.watchos_x86 = -S linkerDynamicFlags.watchos_x86 = -dylib osVersionMinFlagLd.watchos_x86 = -watchos_simulator_version_min osVersionMinFlagClang.watchos_x86 = -mwatchos-simulator-version-min osVersionMin.watchos_x86 = 5.0 runtimeDefinitions.watchos_x86 = KONAN_OBJC_INTEROP=1 KONAN_WATCHOS=1 KONAN_NO_64BIT_ATOMIC=1 \ KONAN_X86=1 KONAN_CORE_SYMBOLICATION=1 # watchOS x86_64 simulator. targetToolchain.macos_x64-watchos_x64 = target-toolchain-xcode_12_2-macos_x64 dependencies.macos_x64-watchos_x64 = \ libffi-3.2.1-3-darwin-macos target-sysroot-xcode_12_2-watchos_x64.default = \ remote:internal arch.watchos_x64 = x86_64 targetSysRoot.watchos_x64 = target-sysroot-xcode_12_2-watchos_x86 targetCpu.watchos_x64 = core2 clangFlags.watchos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu $targetCpu.watchos_x64 clangNooptFlags.watchos_x64 = -O1 clangOptFlags.watchos_x64 = -O3 clangDebugFlags.watchos_x64 = -O0 linkerKonanFlags.watchos_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 7.0 linkerOptimizationFlags.watchos_x64 = -dead_strip linkerNoDebugFlags.watchos_x64 = -S stripFlags.watchos_x64 = -S linkerDynamicFlags.watchos_x64 = -dylib osVersionMinFlagLd.watchos_x64 = -watchos_simulator_version_min osVersionMinFlagClang.watchos_x64 = -mwatchos-simulator-version-min osVersionMin.watchos_x64 = 7.0 runtimeDefinitions.watchos_x64 = KONAN_OBJC_INTEROP=1 KONAN_WATCHOS=1 \ KONAN_X64=1 KONAN_CORE_SYMBOLICATION=1 # Linux x86-64. llvmHome.linux_x64 = $llvm.linux_x64.dev libffiDir.linux_x64 = libffi-3.2.1-2-linux-x86-64 gccToolchain.linux_x64 = x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 targetToolchain.linux_x64 = $gccToolchain.linux_x64/x86_64-unknown-linux-gnu dependencies.linux_x64 = \ x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-2-linux-x86-64 \ lldb-3-linux targetToolchain.mingw_x64-linux_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 dependencies.mingw_x64-linux_x64 = \ libffi-3.2.1-mingw-w64-x86-64 \ x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 targetToolchain.macos_x64-linux_x64 = $llvmHome.macos_x64 dependencies.macos_x64-linux_x64 = \ libffi-3.2.1-3-darwin-macos \ x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 quadruple.linux_x64 = x86_64-unknown-linux-gnu targetSysRoot.linux_x64 = $gccToolchain.linux_x64/x86_64-unknown-linux-gnu/sysroot # targetSysroot-relative. libGcc.linux_x64 = ../../lib/gcc/x86_64-unknown-linux-gnu/8.3.0 targetCpu.linux_x64 = x86-64 clangFlags.linux_x64 = -cc1 -target-cpu $targetCpu.linux_x64 -emit-obj -disable-llvm-optzns -x ir \ -ffunction-sections -fdata-sections clangNooptFlags.linux_x64 = -O1 clangOptFlags.linux_x64 = -O3 clangDebugFlags.linux_x64 = -O0 dynamicLibraryRelocationMode.linux_x64 = pic staticLibraryRelocationMode.linux_x64 = pic linkerKonanFlags.linux_x64 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle --gc-sections linkerOptimizationFlags.linux_x64 = linkerNoDebugFlags.linux_x64 = -S linkerDynamicFlags.linux_x64 = -shared linker.linux_x64 = $targetToolchain.linux_x64/bin/ld.gold linkerHostSpecificFlags.linux_x64-linux_x64 = linker.mingw_x64-linux_x64 = $targetToolchain.mingw_x64-linux_x64/bin/ld.gold linkerHostSpecificFlags.mingw_x64-linux_x64 = linker.macos_x64-linux_x64 = $targetToolchain.macos_x64-linux_x64/bin/ld.lld linkerHostSpecificFlags.macos_x64-linux_x64 = --no-threads dynamicLinker.linux_x64 = /lib64/ld-linux-x86-64.so.2 # targetSysRoot relative abiSpecificLibraries.linux_x64 = lib usr/lib ../lib64 lib64 usr/lib64 # targetSysRoot relative crtFilesLocation.linux_x64 = usr/lib runtimeDefinitions.linux_x64 = USE_GCC_UNWIND=1 KONAN_LINUX=1 KONAN_X64=1 \ USE_ELF_SYMBOLS=1 ELFSIZE=64 # Raspberry Pi gccToolchain.linux_arm32_hfp = arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2 targetToolchain.linux_x64-linux_arm32_hfp = $gccToolchain.linux_arm32_hfp/arm-unknown-linux-gnueabihf targetToolchain.mingw_x64-linux_arm32_hfp = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 targetToolchain.macos_x64-linux_arm32_hfp = $llvmHome.macos_x64 # TODO: We might use docker on Windows or macOS. emulatorDependency.linux_x64-linux_arm32_hfp = qemu-arm-static-5.1.0-linux-2 emulatorExecutable.linux_x64-linux_arm32_hfp = qemu-arm-static-5.1.0-linux-2/qemu-arm dependencies.linux_x64-linux_arm32_hfp = \ arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-2-linux-x86-64 dependencies.mingw_x64-linux_arm32_hfp = \ arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-mingw-w64-x86-64 dependencies.macos_x64-linux_arm32_hfp = \ arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-3-darwin-macos quadruple.linux_arm32_hfp = arm-unknown-linux-gnueabihf linkerNoDebugFlags.linux_arm32_hfp = -S linkerDynamicFlags.linux_arm32_hfp = -shared linkerOptimizationFlags.linux_arm32_hfp = --gc-sections targetSysRoot.linux_arm32_hfp = $gccToolchain.linux_arm32_hfp/arm-unknown-linux-gnueabihf/sysroot # We could reuse host toolchain here. linkerKonanFlags.linux_arm32_hfp = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle # targetSysroot-relative. libGcc.linux_arm32_hfp = ../../lib/gcc/arm-unknown-linux-gnueabihf/8.3.0 targetCpu.linux_arm32_hfp = arm1136jf-s targetCpuFeatures.linux_arm32_hfp = +dsp,+strict-align,+vfp2,-crypto,-d16,-fp-armv8,-fp-only-sp,-fp16,-neon,-thumb-mode,-vfp3,-vfp4 clangFlags.linux_arm32_hfp = -cc1 -target-cpu $targetCpu.linux_arm32_hfp -mfloat-abi hard -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.linux_arm32_hfp = -O1 clangOptFlags.linux_arm32_hfp = -O3 -ffunction-sections clangDebugFlags.linux_arm32_hfp = -O0 dynamicLibraryRelocationMode.linux_arm32_hfp = pic staticLibraryRelocationMode.linux_arm32_hfp = pic linker.linux_x64-linux_arm32_hfp = $targetToolchain.linux_x64-linux_arm32_hfp/bin/ld linkerHostSpecificFlags.linux_x64-linux_arm32_hfp = linker.mingw_x64-linux_arm32_hfp = $targetToolchain.mingw_x64-linux_arm32_hfp/bin/ld.gold linkerHostSpecificFlags.mingw_x64-linux_arm32_hfp = linker.macos_x64-linux_arm32_hfp = $targetToolchain.macos_x64-linux_arm32_hfp/bin/ld.lld linkerHostSpecificFlags.macos_x64-linux_arm32_hfp = --no-threads dynamicLinker.linux_arm32_hfp = /lib/ld-linux-armhf.so.3 # targetSysRoot relative abiSpecificLibraries.linux_arm32_hfp = lib usr/lib # targetSysRoot relative crtFilesLocation.linux_arm32_hfp = usr/lib runtimeDefinitions.linux_arm32_hfp = USE_GCC_UNWIND=1 KONAN_LINUX=1 \ KONAN_ARM32=1 USE_ELF_SYMBOLS=1 ELFSIZE=32 KONAN_NO_UNALIGNED_ACCESS=1 # Linux arm64 gccToolchain.linux_arm64 = aarch64-unknown-linux-gnu-gcc-8.3.0-glibc-2.25-kernel-4.9-2 targetToolchain.linux_x64-linux_arm64 = $gccToolchain.linux_arm64/aarch64-unknown-linux-gnu targetToolchain.mingw_x64-linux_arm64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 targetToolchain.macos_x64-linux_arm64 = $llvmHome.macos_x64 emulatorDependency.linux_x64-linux_arm64 = qemu-aarch64-static-5.1.0-linux-2 emulatorExecutable.linux_x64-linux_arm64 = qemu-aarch64-static-5.1.0-linux-2/qemu-aarch64 dependencies.linux_x64-linux_arm64 = \ aarch64-unknown-linux-gnu-gcc-8.3.0-glibc-2.25-kernel-4.9-2 \ libffi-3.2.1-2-linux-x86-64 dependencies.mingw_x64-linux_arm64 = \ aarch64-unknown-linux-gnu-gcc-8.3.0-glibc-2.25-kernel-4.9-2 \ libffi-3.2.1-mingw-w64-x86-64 dependencies.macos_x64-linux_arm64 = \ aarch64-unknown-linux-gnu-gcc-8.3.0-glibc-2.25-kernel-4.9-2 \ libffi-3.2.1-3-darwin-macos quadruple.linux_arm64 = aarch64-unknown-linux-gnu linkerNoDebugFlags.linux_arm64 = -S linkerDynamicFlags.linux_arm64 = -shared linkerOptimizationFlags.linux_arm64 = --gc-sections targetSysRoot.linux_arm64 = $gccToolchain.linux_arm64/aarch64-unknown-linux-gnu/sysroot # We could reuse host toolchain here. linkerKonanFlags.linux_arm64 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle # targetSysroot-relative. libGcc.linux_arm64 = ../../lib/gcc/aarch64-unknown-linux-gnu/8.3.0 targetCpu.linux_arm64 = generic clangFlags.linux_arm64 = -cc1 -target-cpu cortex-a57 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.linux_arm64 = -O1 clangOptFlags.linux_arm64 = -O3 -ffunction-sections clangDebugFlags.linux_arm64 = -O0 dynamicLibraryRelocationMode.linux_arm64 = pic staticLibraryRelocationMode.linux_arm64 = pic linker.linux_x64-linux_arm64 = $targetToolchain.linux_x64-linux_arm64/bin/ld.gold linkerHostSpecificFlags.linux_x64-linux_arm64 = linker.mingw_x64-linux_arm64 = $targetToolchain.mingw_x64-linux_arm64/bin/ld.gold linkerHostSpecificFlags.mingw_x64-linux_arm64 = linker.macos_x64-linux_arm64 = $targetToolchain.macos_x64-linux_arm64/bin/ld.lld linkerHostSpecificFlags.macos_x64-linux_arm64 = --no-threads dynamicLinker.linux_arm64 = /lib/ld-linux-aarch64.so.1 # targetSysRoot relative abiSpecificLibraries.linux_arm64 = lib usr/lib # targetSysRoot relative crtFilesLocation.linux_arm64 = usr/lib runtimeDefinitions.linux_arm64 = USE_GCC_UNWIND=1 KONAN_LINUX=1 KONAN_ARM64=1 \ USE_ELF_SYMBOLS=1 ELFSIZE=64 # MIPS gccToolchain.linux_mips32 = mips-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 targetToolchain.linux_x64-linux_mips32 = $gccToolchain.linux_mips32/mips-unknown-linux-gnu emulatorDependency.linux_x64-linux_mips32 = qemu-mips-static-5.1.0-linux-2 emulatorExecutable.linux_x64-linux_mips32 = qemu-mips-static-5.1.0-linux-2/qemu-mips dependencies.linux_x64-linux_mips32 = \ mips-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-2-linux-x86-64 quadruple.linux_mips32 = mips-unknown-linux-gnu linkerOptimizationFlags.linux_mips32 = --gc-sections linkerDynamicFlags.linux_mips32 = -shared targetSysRoot.linux_mips32 = $gccToolchain.linux_mips32/mips-unknown-linux-gnu/sysroot # We could reuse host toolchain here. linkerKonanFlags.linux_mips32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle -z notext # targetSysroot-relative. libGcc.linux_mips32 = ../../lib/gcc/mips-unknown-linux-gnu/8.3.0 targetCpu.linux_mips32 = mips32r2 # We generate a single binary with a big GOT. It causes problems for MIPS. # See https://gcc.gnu.org/onlinedocs/gcc/MIPS-Options.html about mxgot. clangFlags.linux_mips32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mips32 -mllvm -mxgot clangNooptFlags.linux_mips32 = -O1 clangOptFlags.linux_mips32 = -O3 -ffunction-sections clangDebugFlags.linux_mips32 = -O0 dynamicLibraryRelocationMode.linux_mips32 = pic staticLibraryRelocationMode.linux_mips32 = pic executableRelocationMode.linux_mips32 = static linker.linux_x64-linux_mips32 = $targetToolchain.linux_x64-linux_mips32/bin/ld linkerHostSpecificFlags.linux_x64-linux_mips32 = dynamicLinker.linux_mips32 = /lib/ld.so.1 # targetSysRoot relative abiSpecificLibraries.linux_mips32 = lib usr/lib # targetSysRoot relative crtFilesLocation.linux_mips32 = usr/lib # TODO: reconsider KONAN_NO_64BIT_ATOMIC, once target MIPS can do proper 64-bit load/store/CAS. runtimeDefinitions.linux_mips32 = USE_GCC_UNWIND=1 KONAN_LINUX=1 KONAN_MIPS32=1 \ USE_ELF_SYMBOLS=1 ELFSIZE=32 KONAN_NO_64BIT_ATOMIC=1 KONAN_NO_UNALIGNED_ACCESS=1 # MIPSel gccToolchain.linux_mipsel32 = mipsel-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 targetToolchain.linux_x64-linux_mipsel32 = $gccToolchain.linux_mipsel32/mipsel-unknown-linux-gnu emulatorDependency.linux_x64-linux_mipsel32 = qemu-mipsel-static-5.1.0-linux-2 emulatorExecutable.linux_x64-linux_mipsel32 = qemu-mipsel-static-5.1.0-linux-2/qemu-mipsel dependencies.linux_x64-linux_mipsel32 = \ mipsel-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 \ libffi-3.2.1-2-linux-x86-64 quadruple.linux_mipsel32 = mipsel-unknown-linux-gnu linkerOptimizationFlags.linux_mipsel32 = --gc-sections linkerDynamicFlags.linux_mipsel32 = -shared targetSysRoot.linux_mipsel32 = $gccToolchain.linux_mipsel32/mipsel-unknown-linux-gnu/sysroot # We could reuse host toolchain here. linkerKonanFlags.linux_mipsel32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle -z notext # targetSysroot-relative. libGcc.linux_mipsel32 = ../../lib/gcc/mipsel-unknown-linux-gnu/8.3.0 targetCpu.linux_mipsel32 = mips32r2 clangFlags.linux_mipsel32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mipsel32 -mllvm -mxgot clangNooptFlags.linux_mipsel32 = -O1 clangOptFlags.linux_mipsel32 = -O3 -ffunction-sections clangDebugFlags.linux_mipsel32 = -O0 dynamicLibraryRelocationMode.linux_mipsel32 = pic staticLibraryRelocationMode.linux_mipsel32 = pic linker.linux_x64-linux_mipsel32 = $targetToolchain.linux_x64-linux_mipsel32/bin/ld linkerHostSpecificFlags.linux_x64-linux_mipsel32 = dynamicLinker.linux_mipsel32 = /lib/ld.so.1 # targetSysRoot relative abiSpecificLibraries.linux_mipsel32 = lib usr/lib # targetSysRoot relative crtFilesLocation.linux_mipsel32 = usr/lib # TODO: reconsider KONAN_NO_64BIT_ATOMIC, once target MIPS can do proper 64-bit load/store/CAS. runtimeDefinitions.linux_mipsel32 = USE_GCC_UNWIND=1 KONAN_LINUX=1 \ KONAN_MIPSEL32=1 USE_ELF_SYMBOLS=1 ELFSIZE=32 KONAN_NO_64BIT_ATOMIC=1 KONAN_NO_UNALIGNED_ACCESS=1 # Android ARM32, based on NDK for android-21. targetToolchain.macos_x64-android_arm32 = target-toolchain-2-osx-android_ndk dependencies.macos_x64-android_arm32 = \ target-sysroot-1-android_ndk \ target-toolchain-2-osx-android_ndk \ libffi-3.2.1-3-darwin-macos targetToolchain.linux_x64-android_arm32 = target-toolchain-2-linux-android_ndk dependencies.linux_x64-android_arm32 = \ target-sysroot-1-android_ndk \ target-toolchain-2-linux-android_ndk \ libffi-3.2.1-2-linux-x86-64 targetToolchain.mingw_x64-android_arm32 = target-toolchain-2-windows-android_ndk dependencies.mingw_x64-android_arm32 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_arm32 = arm-linux-androideabi targetCpu.android_arm32 = arm7tdmi targetCpuFeatures.android_arm32 = +soft-float,+strict-align,-crypto,-neon,-thumb-mode clangFlags.android_arm32 = -cc1 -target-cpu $targetCpu.android_arm32 -emit-obj -disable-llvm-optzns -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_arm32 = -O3 -ffunction-sections linkerNoDebugFlags.android_arm32 = -Wl,-S clangNooptFlags.android_arm32 = -O1 targetSysRoot.android_arm32 = target-sysroot-1-android_ndk linkerKonanFlags.android_arm32 = -lm -lc++_static -lc++abi -landroid -llog -latomic runtimeDefinitions.android_arm32 = __ANDROID__ USE_GCC_UNWIND=1 USE_ELF_SYMBOLS=1 ELFSIZE=32 \ KONAN_ANDROID=1 KONAN_ARM32=1 KONAN_NO_UNALIGNED_ACCESS=1 # Android ARM64, based on NDK. targetToolchain.macos_x64-android_arm64 = target-toolchain-2-osx-android_ndk dependencies.macos_x64-android_arm64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-osx-android_ndk \ libffi-3.2.1-3-darwin-macos targetToolchain.linux_x64-android_arm64 = target-toolchain-2-linux-android_ndk dependencies.linux_x64-android_arm64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-linux-android_ndk \ libffi-3.2.1-2-linux-x86-64 targetToolchain.mingw_x64-android_arm64 = target-toolchain-2-windows-android_ndk dependencies.mingw_x64-android_arm64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_arm64 = aarch64-linux-android targetCpu.android_arm64 = cortex-a57 clangFlags.android_arm64 = -cc1 -target-cpu $targetCpu.android_arm64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_arm64 = -O3 -ffunction-sections clangNooptFlags.android_arm64 = -O1 targetSysRoot.android_arm64 = target-sysroot-1-android_ndk linkerKonanFlags.android_arm64 = -lm -lc++_static -lc++abi -landroid -llog -latomic linkerNoDebugFlags.android_arm64 = -Wl,-S runtimeDefinitions.android_arm64 = __ANDROID__ USE_GCC_UNWIND=1 USE_ELF_SYMBOLS=1 \ ELFSIZE=64 KONAN_ANDROID=1 KONAN_ARM64=1 # Android X86, based on NDK. targetToolchain.macos_x64-android_x86 = target-toolchain-2-osx-android_ndk dependencies.macos_x64-android_x86 = \ target-sysroot-1-android_ndk \ target-toolchain-2-osx-android_ndk \ libffi-3.2.1-3-darwin-macos targetToolchain.linux_x64-android_x86 = target-toolchain-2-linux-android_ndk dependencies.linux_x64-android_x86 = \ target-sysroot-1-android_ndk \ target-toolchain-2-linux-android_ndk \ libffi-3.2.1-2-linux-x86-64 targetToolchain.mingw_x64-android_x86 = target-toolchain-2-windows-android_ndk dependencies.mingw_x64-android_x86 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_x86 = i686-linux-android # -target-cpu pentium4 makes sure that cogenerator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can set target CPU to i686. targetCpu.android_x86 = pentium4 clangFlags.android_x86 = -cc1 -target-cpu $targetCpu.android_x86 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_x86 = -O3 -ffunction-sections clangNooptFlags.android_x86 = -O1 targetSysRoot.android_x86 = target-sysroot-1-android_ndk linkerKonanFlags.android_x86 = -lm -lc++_static -lc++abi -landroid -llog -latomic linkerNoDebugFlags.android_x86 = -Wl,-S runtimeDefinitions.android_x86 = __ANDROID__ USE_GCC_UNWIND=1 USE_ELF_SYMBOLS=1 \ ELFSIZE=32 KONAN_ANDROID=1 KONAN_X86=1 # Android X64, based on NDK. targetToolchain.macos_x64-android_x64 = target-toolchain-2-osx-android_ndk dependencies.macos_x64-android_x64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-osx-android_ndk \ libffi-3.2.1-3-darwin-macos targetToolchain.linux_x64-android_x64 = target-toolchain-2-linux-android_ndk dependencies.linux_x64-android_x64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-linux-android_ndk \ libffi-3.2.1-2-linux-x86-64 targetToolchain.mingw_x64-android_x64 = target-toolchain-2-windows-android_ndk dependencies.mingw_x64-android_x64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_x64 = x86_64-linux-android targetCpu.android_x64 = x86-64 clangFlags.android_x64 = -cc1 -target-cpu $targetCpu.android_x64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_x64 = -O3 -ffunction-sections clangNooptFlags.android_x64 = -O1 targetSysRoot.android_x64 = target-sysroot-1-android_ndk linkerKonanFlags.android_x64 = -lm -lc++_static -lc++abi -landroid -llog -latomic linkerNoDebugFlags.android_x64 = -Wl,-S runtimeDefinitions.android_x64 = __ANDROID__ USE_GCC_UNWIND=1 USE_ELF_SYMBOLS=1 \ ELFSIZE=64 KONAN_ANDROID=1 KONAN_X64=1 # Windows x86-64, based on mingw-w64. llvmHome.mingw_x64 = $llvm.mingw_x64.dev targetToolchain.mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 libffiDir.mingw_x64 = libffi-3.2.1-mingw-w64-x86-64 targetToolchain.linux_x64-mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 targetToolchain.macos_x64-mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 # for Windows we are currently using LLDB 9 dependencies.mingw_x64 = \ libffi-3.2.1-mingw-w64-x86-64 \ lldb-2-windows dependencies.linux_x64-mingw_x64 = \ libffi-3.2.1-2-linux-x86-64 dependencies.macos_x64-mingw_x64 = \ libffi-3.2.1-3-darwin-macos quadruple.mingw_x64 = x86_64-w64-mingw32 targetSysRoot.mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 targetCpu.mingw_x64 = x86-64 # For using with Universal Windows Platform (UWP) we need to use this slower option. # See https://youtrack.jetbrains.com/issue/KT-27654. # TODO: remove, once fixed in mingw, check with the bug testcase. clangFlags.mingw_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu $targetCpu.mingw_x64 clangOptFlags.mingw_x64 = -O3 -ffunction-sections clangNooptFlags.mingw_x64 = -O1 linkerNoDebugFlags.mingw_x64 = -Wl,-S linkerDynamicFlags.mingw_x64 = -shared linkerKonanFlags.mingw_x64 =-static-libgcc -static-libstdc++ \ -Wl,--dynamicbase \ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \ -Wl,--defsym,__cxa_demangle=Konan_cxa_demangle linkerOptimizationFlags.mingw_x64 = -Wl,--gc-sections mimallocLinkerDependencies.mingw_x64 = -lbcrypt runtimeDefinitions.mingw_x64 = USE_GCC_UNWIND=1 USE_PE_COFF_SYMBOLS=1 KONAN_WINDOWS=1 \ UNICODE KONAN_X64=1 KONAN_NO_MEMMEM=1 # Windows i686, based on mingw-w64. targetToolchain.mingw_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 dependencies.mingw_x64-mingw_x86 = \ msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 \ libffi-3.2.1-mingw-w64-x86-64 targetToolchain.linux_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 targetToolchain.macos_x64-mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 dependencies.linux_x64-mingw_x86 = \ msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 \ libffi-3.2.1-2-linux-x86-64 dependencies.macos_x64-mingw_x86 = \ msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 \ libffi-3.2.1-3-darwin-macos quadruple.mingw_x86 = i686-w64-mingw32 targetSysRoot.mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 # For using with Universal Windows Platform (UWP) we need to use slower -emulated-tls option. # See https://youtrack.jetbrains.com/issue/KT-27654. # TODO: remove, once fixed in mingw, check with the bug testcase. # -target-cpu pentium4 makes sure that code-generator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed in coprocessor registers # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can remove this flag. targetCpu.mingw_x86 = pentium4 clangFlags.mingw_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu $targetCpu.mingw_x86 clangOptFlags.mingw_x86 = -O3 -ffunction-sections clangNooptFlags.mingw_x86 = -O1 linkerNoDebugFlags.mingw_x86 = -Wl,-S linkerDynamicFlags.mingw_x86 = -shared linkerKonanFlags.mingw_x86 = -static-libgcc -static-libstdc++ \ -Wl,--dynamicbase \ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \ -Wl,--defsym,___cxa_demangle=_Konan_cxa_demangle mimallocLinkerDependencies.mingw_x86 = -lbcrypt linkerOptimizationFlags.mingw_x86 = -Wl,--gc-sections runtimeDefinitions.mingw_x86 = USE_GCC_UNWIND=1 USE_PE_COFF_SYMBOLS=1 KONAN_WINDOWS=1 \ UNICODE KONAN_X86=1 KONAN_NO_MEMMEM=1 # WebAssembly 32-bit. targetToolchain.macos_x64-wasm32 = target-toolchain-3-macos-wasm dependencies.macos_x64-wasm32 = \ libffi-3.2.1-3-darwin-macos \ target-sysroot-4-embedded \ target-toolchain-3-macos-wasm targetToolchain.linux_x64-wasm32 = target-toolchain-2-linux-wasm dependencies.linux_x64-wasm32 = \ libffi-3.2.1-2-linux-x86-64 \ target-sysroot-4-embedded \ target-toolchain-2-linux-wasm targetToolchain.mingw_x64-wasm32 = target-toolchain-2-mingw-wasm dependencies.mingw_x64-wasm32 = \ libffi-3.2.1-mingw-w64-x86-64 \ target-sysroot-4-embedded \ target-toolchain-2-mingw-wasm quadruple.wasm32 = wasm32-unknown-unknown targetSysRoot.wasm32 = target-sysroot-4-embedded targetCpu.wasm32 = generic clangFlags.wasm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.wasm32 = -O1 clangOptFlags.wasm32 = -O3 clangDebugFlags.wasm32 = -O0 # TODO: make explicit list of external symbols lld.wasm32 = --allow-undefined --no-entry --global-base=0 --no-threads --export-dynamic runtimeDefinitions.wasm32 = KONAN_WASM=1 KONAN_NO_FFI=1 KONAN_NO_THREADS=1 \ KONAN_NO_EXCEPTIONS=1 KONAN_INTERNAL_DLMALLOC=1 KONAN_INTERNAL_SNPRINTF=1 \ KONAN_INTERNAL_NOW=1 KONAN_NO_MEMMEM KONAN_NO_CTORS_SECTION=1 # The version of Kotlin/Native compiler compilerVersion=1.5-dev ================================================ FILE: konan/platforms/zephyr/stm32f4_disco ================================================ # # Copyright 2010-2018 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Zephyr RTOS. # STM32 F4 Discovery quadruple.zephyr_stm32f4_disco = armv7m-none-eabi targetSysRoot.zephyr_stm32f4_disco = target-sysroot-4-embedded boardSpecificClangFlags.zephyr_stm32f4_disco = -mthumb targetCpu.zephyr_stm32f4_disco = cortex-m4 targetAbi.zephyr_stm32f4_disco = aapcs clangFlags = -Os runtimeDefinitions.zephyr_stm32f4_disco = KONAN_ZEPHYR=1 KONAN_NO_FFI=1 \ KONAN_NO_THREADS=1 KONAN_NO_EXCEPTIONS=1 KONAN_NO_MATH=1 \ KONAN_INTERNAL_SNPRINTF=1 KONAN_INTERNAL_NOW=1 KONAN_NO_MEMMEM=1 \ KONAN_NO_CTORS_SECTION=1 KONAN_NO_UNALIGNED_ACCESS=1 targetToolchain.linux_x64-zephyr_stm32f4_disco = gcc-arm-none-eabi-7-2017-q4-major-linux/arm-none-eabi dependencies.linux_x64-zephyr_stm32f4_disco = \ libffi-3.2.1-2-linux-x86-64 \ clang-llvm-8.0.0-linux-x86-64 \ gcc-arm-none-eabi-7-2017-q4-major-linux \ target-sysroot-4-embedded targetToolchain.macos_x64-zephyr_stm32f4_disco = gcc-arm-none-eabi-7-2017-q4-major-mac/arm-none-eabi dependencies.macos_x64-zephyr_stm32f4_disco = \ gcc-arm-none-eabi-7-2017-q4-major-mac \ libffi-3.2.1-3-darwin-macos \ clang-llvm-apple-8.0.0-darwin-macos \ target-sysroot-4-embedded targetToolchain.mingw_x64-zephyr_stm32f4_disco = gcc-arm-none-eabi-7-2017-q4-major-win32/arm-none-eabi dependencies.mingw_x64-zephyr_stm32f4_disco = \ libffi-3.2.1-mingw-w64-x86-64 \ msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 \ gcc-arm-none-eabi-7-2017-q4-major-win32 \ target-sysroot-4-embedded ================================================ FILE: libclangext/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ apply plugin: "cpp" apply plugin: "c" buildscript { ext.rootBuildDirectory = file('..') apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } import org.jetbrains.kotlin.konan.target.ClangArgs import org.jetbrains.kotlin.PlatformInfo ext.isEnabled = PlatformInfo.isMac() model { components { clangext(NativeLibrarySpec) { sources { cpp { source.srcDirs "src/main/cpp" exportedHeaders.srcDirs "src/main/include" } } binaries.withType(StaticLibraryBinarySpec) { binary -> if (!project.parent.convention.plugins.platformInfo.isWindows()) cppCompiler.args "-fPIC" cppCompiler.args "--std=c++17", "-g", "-I${llvmDir}/include" if (isEnabled) { cppCompiler.args '-DLIBCLANGEXT_ENABLE=1' } } binaries.withType(SharedLibraryBinarySpec) { binary -> buildable = false } } } toolChains { clang(Clang) { eachPlatform { cppCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) } } } } ================================================ FILE: libclangext/src/main/cpp/ClangExt.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "clang-c/ext.h" using namespace clang; #if LIBCLANGEXT_ENABLE static CXCursor makeObjCProtocolDeclCXCursor(const ObjCProtocolDecl* decl, CXTranslationUnit translationUnit) { auto kind = CXCursor_ObjCProtocolDecl; CXCursor result = { kind, 0, { decl, (void*)(intptr_t) 1, translationUnit } }; return result; } static const Attr* getCursorAttr(CXCursor cursor) { return static_cast(cursor.data[1]); } static const Decl *getCursorDecl(CXCursor Cursor) { return static_cast(Cursor.data[0]); } static const QualType unwrapCXType(CXType type) { return QualType::getFromOpaquePtr(type.data[0]); } static CXTranslationUnit getTranslationUnit(CXType type) { return static_cast(type.data[1]); } static ASTUnit* getASTUnit(CXTranslationUnit translationUnit) { return reinterpret_cast(translationUnit)[1]; } // The functions above are totally libclang-implementation-specific and thus version-dependent. static CXTypeAttributes makeCXTypeAttributes(QualType qualType) { CXTypeAttributes result = { qualType.getAsOpaquePtr() }; return result; } static QualType unwrapCXTypeAttributes(CXTypeAttributes attributes) { return QualType::getFromOpaquePtr(attributes.typeOpaquePtr); } #else // LIBCLANGEXT_ENABLE static CXTypeAttributes makeCXTypeAttributes() { CXTypeAttributes result = { nullptr }; return result; } #endif // LIBCLANGEXT_ENABLE extern "C" { const char* clang_Cursor_getAttributeSpelling(CXCursor cursor) { #if LIBCLANGEXT_ENABLE if (clang_isAttribute(cursor.kind) == 0) { return nullptr; } return getCursorAttr(cursor)->getSpelling(); #else return ""; #endif } CXTypeAttributes clang_getDeclTypeAttributes(CXCursor cursor) { #if LIBCLANGEXT_ENABLE CXType cxType = clang_getCursorType(cursor); if (clang_isDeclaration(cursor.kind)) { const Decl *D = getCursorDecl(cursor); if (D) { if (const DeclaratorDecl *DD = dyn_cast(D)) return makeCXTypeAttributes(DD->getType()); } } return makeCXTypeAttributes(QualType()); #else return makeCXTypeAttributes(); #endif } CXTypeAttributes clang_getResultTypeAttributes(CXTypeAttributes typeAttributes) { #if LIBCLANGEXT_ENABLE QualType qualType = unwrapCXTypeAttributes(typeAttributes); if (qualType.isNull()) return makeCXTypeAttributes(qualType); if (const FunctionType *functionType = qualType->getAs()) return makeCXTypeAttributes(functionType->getReturnType()); return makeCXTypeAttributes(QualType()); #else return makeCXTypeAttributes(); #endif } CXTypeAttributes clang_getCursorResultTypeAttributes(CXCursor cursor) { #if LIBCLANGEXT_ENABLE if (clang_isDeclaration(cursor.kind)) { const Decl *decl = getCursorDecl(cursor); if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null(decl)) return makeCXTypeAttributes(methodDecl->getReturnType()); return clang_getResultTypeAttributes(clang_getDeclTypeAttributes(cursor)); } return makeCXTypeAttributes(QualType()); #else return makeCXTypeAttributes(); #endif } enum CXNullabilityKind clang_Type_getNullabilityKind(CXType type, CXTypeAttributes attributes) { #if LIBCLANGEXT_ENABLE CXTranslationUnit translationUnit = getTranslationUnit(type); ASTContext& astContext = getASTUnit(translationUnit)->getASTContext(); QualType qualType = unwrapCXTypeAttributes(attributes); auto kind = qualType->getNullability(astContext); if (!kind.hasValue()) { return CXNullabilityKind_Unspecified; } switch (*kind) { case NullabilityKind::NonNull: return CXNullabilityKind_NonNull; case NullabilityKind::Nullable: return CXNullabilityKind_Nullable; case NullabilityKind::Unspecified: return CXNullabilityKind_Unspecified; default: assert(false); } #else return CXNullabilityKind_Unspecified; #endif } unsigned clang_Type_getNumProtocols(CXType type) { #if LIBCLANGEXT_ENABLE QualType qualType = unwrapCXType(type); if (auto objCObjectPointerType = qualType->getAs()) { return objCObjectPointerType->getObjectType()->getNumProtocols(); } #endif return 0; } CXCursor clang_Type_getProtocol(CXType type, unsigned index) { #if LIBCLANGEXT_ENABLE QualType qualType = unwrapCXType(type); if (auto objCObjectPointerType = qualType->getAs()) { auto objectType = objCObjectPointerType->getObjectType(); unsigned n = objectType->getNumProtocols(); if (index < n) { auto protocolDecl = objectType->getProtocol(index); auto kind = CXCursor_ObjCProtocolDecl; return makeObjCProtocolDeclCXCursor(protocolDecl, getTranslationUnit(type)); } } #endif return clang_getNullCursor(); } unsigned clang_Cursor_isObjCInitMethod(CXCursor cursor) { #if LIBCLANGEXT_ENABLE if (cursor.kind == CXCursor_ObjCInstanceMethodDecl) { const Decl *decl = getCursorDecl(cursor); if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null(decl)) { return methodDecl->getMethodFamily() == OMF_init; } } #endif return 0; } unsigned clang_Cursor_isObjCReturningRetainedMethod(CXCursor cursor) { #if LIBCLANGEXT_ENABLE if (cursor.kind == CXCursor_ObjCInstanceMethodDecl) { const Decl *decl = getCursorDecl(cursor); if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null(decl)) { return methodDecl->hasAttr(); } } #endif return 0; } unsigned clang_Cursor_isObjCConsumingSelfMethod(CXCursor cursor) { #if LIBCLANGEXT_ENABLE if (cursor.kind == CXCursor_ObjCInstanceMethodDecl) { const Decl *decl = getCursorDecl(cursor); if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null(decl)) { return methodDecl->hasAttr(); } } #endif return 0; } } ================================================ FILE: libclangext/src/main/cpp/ExtVector.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include using namespace clang; static inline QualType GetQualType(CXType CT) { return QualType::getFromOpaquePtr(CT.data[0]); } extern "C" int clang_isExtVectorType(CXType CT) { static_assert(CINDEX_VERSION < 59, "Use CXType_ExtVector for this libclang version"); QualType T = GetQualType(CT); const clang::Type *TP = T.getTypePtrOrNull(); return TP && TP->isExtVectorType(); } ================================================ FILE: libclangext/src/main/include/clang-c/ExtVector.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #ifdef __cplusplus extern "C" { #endif int clang_isExtVectorType(CXType type); #ifdef __cplusplus } #endif ================================================ FILE: libclangext/src/main/include/clang-c/ext.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include // TODO: the API declared below should eventually be refined and contributed to libclang. // libclang doesn't include the type attributes when constructing `CXType`, // so attributes have to be represented separately: typedef struct { const void* typeOpaquePtr; } CXTypeAttributes; enum CXNullabilityKind { CXNullabilityKind_Nullable, CXNullabilityKind_NonNull, CXNullabilityKind_Unspecified }; #ifdef __cplusplus extern "C" { #endif const char* clang_Cursor_getAttributeSpelling(CXCursor cursor); CXTypeAttributes clang_getDeclTypeAttributes(CXCursor cursor); CXTypeAttributes clang_getResultTypeAttributes(CXTypeAttributes typeAttributes); CXTypeAttributes clang_getCursorResultTypeAttributes(CXCursor cursor); enum CXNullabilityKind clang_Type_getNullabilityKind(CXType type, CXTypeAttributes attributes); unsigned clang_Type_getNumProtocols(CXType type); CXCursor clang_Type_getProtocol(CXType type, unsigned index); unsigned clang_Cursor_isObjCInitMethod(CXCursor cursor); unsigned clang_Cursor_isObjCReturningRetainedMethod(CXCursor cursor); unsigned clang_Cursor_isObjCConsumingSelfMethod(CXCursor cursor); #ifdef __cplusplus } #endif ================================================ FILE: licenses/LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2000-2020 JetBrains s.r.o. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: licenses/NOTICE.txt ================================================ ========================================================================= == NOTICE file corresponding to the section 4 d of == == the Apache License, Version 2.0, == == in this case for the Kotlin Compiler distribution. == ========================================================================= Kotlin Compiler Copyright 2010-2017 JetBrains s.r.o and respective authors and developers ================================================ FILE: licenses/third_party/args4j_LICENSE.txt ================================================ The MIT License Copyright (c) 2003, Kohsuke Kawaguchi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/asm_license.txt ================================================ ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: licenses/third_party/boost_LICENSE.txt ================================================ Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/closure-compiler_LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: licenses/third_party/dart_LICENSE.txt ================================================ This license applies to all parts of Dart that are not externally maintained libraries. The external maintained libraries used by Dart are: 7-Zip - in third_party/7zip JSCRE - in runtime/third_party/jscre Ant - in third_party/apache_ant args4j - in third_party/args4j bzip2 - in third_party/bzip2 dromaeo - in samples/third_party/dromaeo Eclipse - in third_party/eclipse gsutil = in third_party/gsutil Guava - in third_party/guava hamcrest - in third_party/hamcrest Httplib2 - in samples/third_party/httplib2 JSON - in third_party/json JUnit - in third_party/junit Oauth - in samples/third_party/oauth2client Rhino - in third_party/rhino weberknecht - in third_party/weberknecht The libraries may have their own licenses; we recommend you read them, as their terms may differ from the terms below. Copyright 2012, the Dart project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: licenses/third_party/glibc_license.txt ================================================ GCC RUNTIME LIBRARY EXCEPTION Version 3.1, 31 March 2009 Copyright (C) 2009 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception. When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception. 0. Definitions. A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library. "GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF. "GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC. "Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation. The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors. A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process. 1. Grant of Additional Permission. You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules. 2. No Weakening of GCC Copyleft. The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC. Hopefully that text is self-explanatory. If it isn't, you need to speak to your lawyer, or the Free Software Foundation. ================================================ FILE: licenses/third_party/harmony_LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================================================ ================================================================================ APACHE HARMONY SUBCOMPONENTS: Apache Harmony includes a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following licenses. License Notice for ICU4C version 3.4 ==================================== ICU License - ICU 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Copyright (c) 1995-2005 International Business Machines Corporation and others All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. -------------------------------------------------------------------------------- All trademarks and registered trademarks mentioned herein are the property of their respective owners. ================================================================================ ================================================================================ License Notice for ICU4J version 4.2.1 ====================================== ICU4J license - ICU4J 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Copyright (c) 1995-2009 International Business Machines Corporation and others All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. -------------------------------------------------------------------------------- All trademarks and registered trademarks mentioned herein are the property of their respective owners. ================================================================================ ================================================================================ License Notice for FDLIBM version 5.2 ===================================== Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. Developed at SunSoft, a Sun Microsystems, Inc. business. Permission to use, copy, modify, and distribute this software is freely granted, provided that this notice is preserved. ================================================================================ ================================================================================ License Notice for ZLIB version 1.2.3 ===================================== (C) 1995-2004 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu ================================================================================ ================================================================================ Visual C++ Runtime Files ======================== The file msvcr71.dll is the Microsoft(R) C Runtime Library. The file msvcp71.dll is the Microsoft Multithreaded Standard C++ Library. These files are redistributed from Microsoft(R) Visual Studio 7.1 as described in the file "redist.txt" available with that product. ================================================================================ ================================================================================ License Notice for Bouncy Castle version 1.45 ============================================= Copyright (c) 2000 - 2009 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================== =============================================================================== License Notice for MX4J 3.0.2. ============================== The MX4J License, Version 1.0 Copyright (c) 2001-2004 by the MX4J contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the MX4J project (http://mx4j.sourceforge.net)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The name "MX4J" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact biorn_steedom [at] users [dot] sourceforge [dot] net 5. Products derived from this software may not be called "MX4J", nor may "MX4J" appear in their name, without prior written permission of Simone Bordet. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE MX4J CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================== This software consists of voluntary contributions made by many individuals on behalf of the MX4J project. For more information on MX4J, please see the MX4J website (http://mx4j.sourceforge.net/). =============================================================================== =============================================================================== Notice for The Independent JPEG Group's JPEG software ===================================================== This distribution may contain software that is based in part on the work of the Independent JPEG Group for which the following notice applies: The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided "AS IS", and you, its user, assume the entire risk as to its quality and accuracy. This software is copyright (C) 1991-1998, Thomas G. Lane. All Rights Reserved except as specified below. Permission is hereby granted to use, copy, modify, and distribute this software (or portions thereof) for any purpose, without fee, subject to these conditions: (1) If any part of the source code for this software is distributed, then this README file must be included, with this copyright and no-warranty notice unaltered; and any additions, deletions, or changes to the original files must be clearly indicated in accompanying documentation. (2) If only executable code is distributed, then the accompanying documentation must state that "this software is based in part on the work of the Independent JPEG Group". (3) Permission for use of this software is granted only if the user accepts full responsibility for any undesirable consequences; the authors accept NO LIABILITY for damages of any kind. These conditions apply to any software derived from or based on the IJG code, not just to the unmodified library. If you use our work, you ought to acknowledge us. Permission is NOT granted for the use of any IJG author's name or company name in advertising or publicity relating to this software or products derived from it. This software may be referred to only as "the Independent JPEG Group's software". We specifically permit and encourage the use of this software as the basis of commercial products, provided that all warranty or liability claims are assumed by the product vendor. =============================================================================== =============================================================================== Notice for Little CMS ===================== This distribution may contain software that is based in part on Little cms for which the following notice applies: Copyright (c) 1998-2007 Marti Maria Saguer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================== =============================================================================== Notice for libpng ================= This distribution may contain software that is based in part on libpng v1.2.38 for which the following notice applies: libpng versions 1.2.6, August 15, 2004, through 1.2.38, July 16, 2009, are Copyright (c) 2004, 2006-2009 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors: Cosmin Truta libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: Simon-Pierre Cadieux Eric S. Raymond Gilles Vollant and with the following additions to the disclaimer: There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996, 1997 Andreas Dilger Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. =============================================================================== =============================================================================== Notice for Unicode Character Database ===================================== Copyright (c) 1991-2005 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. =============================================================================== =============================================================================== Notice for IETF RFCs prior to 2005 ================================== This distribution may contain software that is based in part on the work of the following IETF RFCs. Portions of the IETF RFC specifications may be included in source code comments for reference, and in accordance with the licensing terms, the licenses are reproduced here: RFC 1779 - A String Representation of Distinguished Names RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies RFC 2251 - Lightweight Directory Access Protocol (v3) Copyright (C) The Internet Society (1997). All Rights Reserved. RFC 2253 - Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names Copyright (C) The Internet Society (1997). All Rights Reserved. RFC 2313 - PKCS #1: RSA Encryption Copyright (C) The Internet Society (1998). All Rights Reserved. RFC 2315 - PKCS #7: Cryptographic Message Syntax Copyright (C) The Internet Society (1998). All Rights Reserved. RFC 2459 - Internet X.509 Public Key Infrastructure Certificate and CRL Profile Copyright (C) The Internet Society (1999). All Rights Reserved. RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1 Copyright (C) The Internet Society (1999). All Rights Reserved. RFC 2781 - UTF-16, an encoding of ISO 10646 Copyright (C) The Internet Society (2000). All Rights Reserved. RFC 2891 - LDAP Control Extension for Server Side Sorting of Search Results Copyright (C) The Internet Society (2000). All Rights Reserved. RFC 2985 - PKCS #9: Selected Object Classes and Attribute Types Copyright (C) The Internet Society (2000). All Rights Reserved. RFC 3161 - Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP) Copyright (C) The Internet Society (2001). All Rights Reserved. RFC 3280 - Internet X.509 Public Key Infrastructure, Certificate and Certificate Revocation List (CRL) Profile Copyright (C) The Internet Society (2002). All Rights Reserved. INTERNET-DRAFT - Persistent Search: A Simple LDAP Change Notification Mechanism Copyright (C) The Internet Society (1997-2000). All Rights Reserved. The following statement applies to each RFC: This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Notice for IETF RFCs from 2005 onwards ====================================== This distribution may contain software that is based in part on the work of the following IETF RFCs. Portions of the IETF RFC specifications may be included in source code comments for reference, and in accordance with the licensing terms, the licenses are reproduced here: RFC 4122 - A Universally Unique Identifier (UUID) URN Namespace Copyright (C) The Internet Society (2005). The following statement applies to this RFC: Copyright (C) The Internet Society (2005). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. =============================================================================== =============================================================================== Notice for RSA Public-Key Cryptography Standards ================================================ Portions of Apache Harmony reference RSA Public-Key Cryptography Standards: PKCS#7, PKCS#8 and PKSC#10. Portions of these standards are included in Harmony Javadoc for reference, and in accordance with the licensing terms for PKCS#7, PKCS#8 and PKSC#10, the full copyright statement is here: Copyright 1991-1993 RSA Laboratories, a division of RSA Data Security, Inc. License to copy this document is granted provided that it is identified as "RSA Data Security, Inc. Public-Key Cryptography Standards (PKCS)" in all material mentioning or referencing this document. =============================================================================== =============================================================================== Notice for Apache Yoko ====================== This distribution may contain software that is based in part on Apache Yoko for which the following notice applies: Apache Yoko is an effort undergoing incubation at the Apache Software Foundation (ASF). Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF. http://incubator.apache.org/yoko/ =============================================================================== =============================================================================== Notice for the Eclipse JDT Core Batch Compiler ============================================== The license terms for the Eclipse JDT Core Batch Compiler are available at http://www.eclipse.org/legal/epl-v10.html Source code for the Eclipse JDT Core Batch Compiler can be found at: http://download.eclipse.org/eclipse/downloads/ Navigate to the version of ECJ used in this distribution, and the source is provided in a ZIP file in the section titled "JDT Core Batch Compiler". =============================================================================== =============================================================================== License notice for the DejaVu fonts package ============================================== Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. Glyphs imported from Arev fonts are (c) Tavmjung Bah (see below) Bitstream Vera Fonts Copyright ------------------------------ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Arev Fonts Copyright ------------------------------ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the modifications to the Bitstream Vera Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Tavmjong Bah" or the word "Arev". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Tavmjong Bah Arev" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the name of Tavmjong Bah shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from Tavmjong Bah. For further information, contact: tavmjong @ free . fr. =============================================================================== =============================================================================== License notice for ASM ======================= ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== =============================================================================== License notice for Junit ======================== This distribution may contain a jar file based on Junit 4.2.1 for which the following notice applies: Copyright 2001-2009 Kent Beck Copyright 2000-2009 Erich Gamma Copyright 2006-2009 David Saff Common Public License - v 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. =============================================================================== =============================================================================== The Apache Harmony DRLVM uses the Apache Portable Runtime which includes a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following licenses. From strings/apr_fnmatch.c, include/apr_fnmatch.h, misc/unix/getopt.c, file_io/unix/mktemp.c, strings/apr_strings.c: /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. From network_io/unix/inet_ntop.c, network_io/unix/inet_pton.c: /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. From dso/aix/dso.c: * Based on libdl (dlfcn.c/dlfcn.h) which is * Copyright (c) 1992,1993,1995,1996,1997,1988 * Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany. * * Not derived from licensed software. * * Permission is granted to freely use, copy, modify, and redistribute * this software, provided that the author is not construed to be liable * for any results of using the software, alterations are clearly marked * as such, and this notice is not modified. From strings/apr_strnatcmp.c, include/apr_strings.h: strnatcmp.c -- Perform 'natural order' comparisons of strings in C. Copyright (C) 2000 by Martin Pool This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. From strings/apr_snprintf.c: * * cvt - IEEE floating point formatting routines. * Derived from UNIX V7, Copyright(C) Caldera International Inc. * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code and documentation must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed or owned by Caldera International, Inc. Neither the name of Caldera International, Inc. nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== =============================================================================== License notice for Hamcrest =========================== BSD License Copyright (c) 2000-2006, www.hamcrest.org All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Hamcrest nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== =============================================================================== ================================================ FILE: licenses/third_party/jshashtable_license.txt ================================================ /** * Copyright 2010 Tim Down. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ ================================================ FILE: licenses/third_party/json_LICENSE.txt ================================================ JSON Copyright (c) 2002 JSON.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Software shall be used for Good, not Evil. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/libffi_license.txt ================================================ libffi - Copyright (c) 1996-2014 Anthony Green, Red Hat, Inc and others. See source files for details. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/llvm_license.txt ================================================ ============================================================================== libc++ License ============================================================================== The libc++ library is dual licensed under both the University of Illinois "BSD-Like" license and the MIT license. As a user of this code you may choose to use it under either license. As a contributor, you agree to allow your code to be used under both. Full text of the relevant licenses is included below. ============================================================================== University of Illinois/NCSA Open Source License Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ============================================================================== Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/maven_LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: licenses/third_party/mimalloc_LICENSE.txt ================================================ MIT License Copyright (c) 2019 Microsoft Corporation, Daan Leijen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/pcollections_LICENSE.txt ================================================ Copyright (c) 2008 Harold Cooper Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/prototype_license.txt ================================================ Copyright (c) 2005-2010 Sam Stephenson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: licenses/third_party/rhino_LICENSE.txt ================================================ The majority of Rhino is MPL 1.1 / GPL 2.0 dual licensed: The Mozilla Public License (http://www.mozilla.org/MPL/MPL-1.1.txt): ============================================================================ MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is ______________________________________. The Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] ============================================================================ ============================================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ============================================================================ Additionally, some files (currently the contents of toolsrc/org/mozilla/javascript/tools/debugger/treetable/) are available only under the following license: ============================================================================ * Copyright 1997, 1998 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================================ ================================================ FILE: licenses/third_party/scala_license.txt ================================================ SCALA LICENSE Copyright (c) 2002-2012 EPFL, Lausanne, unless otherwise specified. All rights reserved. This software was developed by the Programming Methods Laboratory of the Swiss Federal Institute of Technology (EPFL), Lausanne, Switzerland. Permission to use, copy, modify, and distribute this software in source or binary form for any purpose with or without fee is hereby granted, provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the EPFL nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: licenses/third_party/sdl_license.txt ================================================ SDL 2.0 and newer are available under the zlib license : This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ================================================ FILE: licenses/third_party/trove_license.txt ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: licenses/third_party/trove_readme_license.txt ================================================ The Trove library is licensed under the Lesser GNU Public License, which is included with the distribution in a file called trove_license.txt. The PrimeFinder and HashFunctions classes in Trove are subject to the following license restrictions: Copyright (c) 1999 CERN - European Organization for Nuclear Research. Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. CERN makes no representations about the suitability of this software for any purpose. It is provided "as is" without expressed or implied warranty. ================================================ FILE: licenses/third_party/unicode_LICENSE.txt ================================================ Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. COPYRIGHT AND PERMISSION NOTICE Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. 2. Additional terms from the Database: Copyright © 1995-1999 Unicode, Inc. All Rights reserved. Disclaimer The Unicode Character Database is provided as is by Unicode, Inc. No claims are made as to fitness for any particular purpose. No warranties of any kind are expressed or implied. The recipient agrees to determine applicability of information provided. If this file has been purchased on magnetic or optical media from Unicode, Inc., the sole remedy for any claim will be exchange of defective media within 90 days of receipt. This disclaimer is applicable for all other data files accompanying the Unicode Character Database, some of which have been compiled by the Unicode Consortium, and some of which have been supplied by other sources. Limitations on Rights to Redistribute This Data Recipient is granted the right to make copies in any form for internal distribution and to freely use the information supplied in the creation of products supporting the UnicodeTM Standard. The files in the Unicode Character Database can be redistributed to third parties or other organizations (whether for profit or not) as long as this notice and the disclaimer notice are retained. Information can be extracted from these files and used in documentation or programs, as long as there is an accompanying notice indicating the source. ================================================ FILE: licenses/third_party/zephyr_LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: licenses/third_party/zlib_license.txt ================================================ zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.11, January 15th, 2017 Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu ================================================ FILE: llvmCoverageMappingC/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ apply plugin: "cpp" apply plugin: "c" buildscript { ext.rootBuildDirectory = file('..') apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } import org.jetbrains.kotlin.konan.target.ClangArgs model { components { coverageMapping(NativeLibrarySpec) { sources.cpp.source.srcDirs "src/main/cpp" binaries.withType(StaticLibraryBinarySpec) { binary -> if (!project.parent.convention.plugins.platformInfo.isWindows()) cppCompiler.args "-fPIC" cppCompiler.args "--std=c++17", "-I${llvmDir}/include", "-I${projectDir}/src/main/include" if (isMac()) { cppCompiler.args "-DKONAN_MACOS=1" } else if (isWindows()) { cppCompiler.args "-DKONAN_WINDOWS=1" } else if (isLinux()) { cppCompiler.args "-DKONAN_LINUX=1", "-D_GLIBCXX_USE_CXX11_ABI=0" } else { throw new Error("Unsupported host OS.") } linker.args "-L${llvmDir}/lib", "-lLLVMCore", "-lLLVMSupport" } binaries.withType(SharedLibraryBinarySpec) { binary -> buildable = false } } } toolChains { clang(Clang) { eachPlatform { cppCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) } } } } ================================================ FILE: llvmCoverageMappingC/src/main/cpp/CoverageMappingC.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "CoverageMappingC.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace llvm; using namespace llvm::coverage; namespace llvm { DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetLibraryInfoImpl, LLVMTargetLibraryInfoRef) } struct LLVMFunctionCoverage { explicit LLVMFunctionCoverage(std::string coverageData) : coverageData(std::move(coverageData)) {} std::string coverageData; }; static coverage::CounterMappingRegion::RegionKind determineRegionKind(const struct LLVMCoverageRegion& region) { switch (region.kind) { case LLVMCoverageRegionKind::CODE: return coverage::CounterMappingRegion::RegionKind::CodeRegion; case LLVMCoverageRegionKind::GAP: return coverage::CounterMappingRegion::RegionKind::GapRegion; case LLVMCoverageRegionKind::EXPANSION: return coverage::CounterMappingRegion::RegionKind::ExpansionRegion; } } static coverage::CounterMappingRegion createCounterMappingRegion(struct LLVMCoverageRegion& region) { auto regionKind = determineRegionKind(region); int expandedFileId = 0; if (regionKind == coverage::CounterMappingRegion::RegionKind::ExpansionRegion) { expandedFileId = region.expandedFileId; } const Counter &counter = coverage::Counter::getCounter(region.counterId); return coverage::CounterMappingRegion(counter, region.fileId, expandedFileId, region.lineStart, region.columnStart, region.lineEnd, region.columnEnd, regionKind); } LLVMFunctionCoverage* LLVMWriteCoverageRegionMapping(unsigned int *fileIdMapping, size_t fileIdMappingSize, struct LLVMCoverageRegion **mappingRegions, size_t mappingRegionsSize) { std::vector counterMappingRegions; for (size_t i = 0; i < mappingRegionsSize; ++i) { struct LLVMCoverageRegion region = *mappingRegions[i]; counterMappingRegions.emplace_back(createCounterMappingRegion(region)); } CoverageMappingWriter writer(ArrayRef(fileIdMapping, fileIdMappingSize), None, counterMappingRegions); std::string CoverageMapping; raw_string_ostream OS(CoverageMapping); writer.write(OS); OS.flush(); // Should be disposed with `LLVMFunctionCoverageDispose`. return new LLVMFunctionCoverage(CoverageMapping); } void LLVMFunctionCoverageDispose(struct LLVMFunctionCoverage* functionCoverage) { delete functionCoverage; } static StructType *getFunctionRecordTy(LLVMContext &Ctx) { #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType, Type *FunctionRecordTypes[] = { #include "llvm/ProfileData/InstrProfData.inc" }; StructType *FunctionRecordTy = StructType::get(Ctx, makeArrayRef(FunctionRecordTypes), true); return FunctionRecordTy; } static llvm::Constant *addFunctionMappingRecord(llvm::LLVMContext &Ctx, StringRef NameValue, uint64_t FuncHash, const std::string &CoverageMapping) { llvm::StructType *FunctionRecordTy = getFunctionRecordTy(Ctx); #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init, llvm::Constant *FunctionRecordVals[] = { #include "llvm/ProfileData/InstrProfData.inc" }; return llvm::ConstantStruct::get(FunctionRecordTy, makeArrayRef(FunctionRecordVals)); } // See https://github.com/llvm/llvm-project/blob/fa8fa044ec46b94e64971efa8852df0d58114062/clang/lib/CodeGen/CoverageMappingGen.cpp#L1284. LLVMValueRef LLVMAddFunctionMappingRecord(LLVMContextRef context, const char *name, uint64_t hash, struct LLVMFunctionCoverage *coverageMapping) { return llvm::wrap(addFunctionMappingRecord(*llvm::unwrap(context), name, hash, coverageMapping->coverageData)); } // See https://github.com/llvm/llvm-project/blob/fa8fa044ec46b94e64971efa8852df0d58114062/clang/lib/CodeGen/CoverageMappingGen.cpp#L1335. // Please note that llvm/ProfileData/InstrProfData.inc refers to variable names of the function that includes it. So be careful with renaming. static llvm::GlobalVariable* emitCoverageGlobal( llvm::LLVMContext &Ctx, llvm::Module &module, std::vector &FunctionRecords, const llvm::SmallVector &FilenameRefs, const std::string &RawCoverageMappings) { auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); std::string FilenamesAndCoverageMappings; llvm::raw_string_ostream outputStream(FilenamesAndCoverageMappings); CoverageFilenamesSectionWriter(FilenameRefs).write(outputStream); outputStream << RawCoverageMappings; size_t CoverageMappingSize = RawCoverageMappings.size(); size_t FilenamesSize = outputStream.str().size() - CoverageMappingSize; // See https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation // // > Coverage mapping data which is an array of bytes. Zero paddings are added at the end to force 8 byte alignment. // if (size_t rem = outputStream.str().size() % 8) { CoverageMappingSize += 8 - rem; for (size_t i = 0; i < 8 - rem; ++i) { outputStream << '\0'; } } StructType *functionRecordTy = getFunctionRecordTy(Ctx); // Create the deferred function records array auto functionRecordsTy = llvm::ArrayType::get(functionRecordTy, FunctionRecords.size()); auto functionRecordsVal = llvm::ConstantArray::get(functionRecordsTy, FunctionRecords); llvm::Type *CovDataHeaderTypes[] = { #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType, #include "llvm/ProfileData/InstrProfData.inc" }; auto CovDataHeaderTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes)); llvm::Constant *CovDataHeaderVals[] = { #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init, #include "llvm/ProfileData/InstrProfData.inc" }; auto covDataHeaderVal = llvm::ConstantStruct::get(CovDataHeaderTy, makeArrayRef(CovDataHeaderVals)); auto *filenamesAndMappingsVal = llvm::ConstantDataArray::getString(Ctx, outputStream.str(), false); // Create the coverage data record llvm::Type *covDataTypes[] = {CovDataHeaderTy, functionRecordsTy, filenamesAndMappingsVal->getType()}; auto covDataTy = llvm::StructType::get(Ctx, makeArrayRef(covDataTypes)); llvm::Constant *TUDataVals[] = {covDataHeaderVal, functionRecordsVal, filenamesAndMappingsVal}; auto covDataVal = llvm::ConstantStruct::get(covDataTy, makeArrayRef(TUDataVals)); // Will be deleted when module is disposed. return new llvm::GlobalVariable(module, covDataTy, true, llvm::GlobalValue::InternalLinkage, covDataVal, llvm::getCoverageMappingVarName()); } static std::string createRawCoverageMapping(struct LLVMFunctionCoverage **functionCoverages, size_t functionCoveragesSize) { std::vector coverageMappings; for (size_t i = 0; i < functionCoveragesSize; ++i) { coverageMappings.emplace_back(functionCoverages[i]->coverageData); } return llvm::join(coverageMappings.begin(), coverageMappings.end(), ""); } LLVMValueRef LLVMCoverageEmit(LLVMModuleRef moduleRef, LLVMValueRef *records, size_t recordsSize, const char **filenames, int *filenamesIndices, size_t filenamesSize, struct LLVMFunctionCoverage **functionCoverages, size_t functionCoveragesSize) { LLVMContext &ctx = *unwrap(LLVMGetModuleContext(moduleRef)); Module &module = *unwrap(moduleRef); std::vector functionRecords; for (size_t i = 0; i < recordsSize; ++i) { functionRecords.push_back(dyn_cast(unwrap(records[i]))); } llvm::SmallVector filenameRefs; filenameRefs.resize(filenamesSize); for (size_t i = 0; i < filenamesSize; ++i) { if (sys::path::is_absolute(filenames[i])) { filenameRefs[filenamesIndices[i]] = filenames[i]; } else { SmallString<256> path(filenames[i]); sys::fs::make_absolute(path); sys::path::remove_dots(path, true); filenameRefs[filenamesIndices[i]] = path; } } const std::string &rawCoverageMappings = createRawCoverageMapping(functionCoverages, functionCoveragesSize); GlobalVariable *coverageGlobal = emitCoverageGlobal(ctx, module, functionRecords, filenameRefs, rawCoverageMappings); const std::string §ion = getInstrProfSectionName(IPSK_covmap, Triple(module.getTargetTriple()).getObjectFormat()); coverageGlobal->setSection(section); coverageGlobal->setAlignment(8); return wrap(coverageGlobal); } LLVMValueRef LLVMInstrProfIncrement(LLVMModuleRef moduleRef) { Module &module = *unwrap(moduleRef); return wrap(Intrinsic::getDeclaration(&module, Intrinsic::instrprof_increment, None)); } LLVMValueRef LLVMCreatePGOFunctionNameVar(LLVMValueRef llvmFunction, const char *pgoFunctionName) { auto *fnPtr = cast(unwrap(llvmFunction)); return wrap(createPGOFuncNameVar(*fnPtr, pgoFunctionName)); } void LLVMAddInstrProfPass(LLVMPassManagerRef passManagerRef, const char* outputFileName) { legacy::PassManagerBase *passManager = unwrap(passManagerRef); InstrProfOptions options; options.InstrProfileOutput = outputFileName; passManager->add(createInstrProfilingLegacyPass(options)); } void LLVMKotlinAddTargetLibraryInfoWrapperPass(LLVMPassManagerRef passManagerRef, const char* targetTriple) { legacy::PassManagerBase *passManager = unwrap(passManagerRef); passManager->add(new TargetLibraryInfoWrapperPass(Triple(targetTriple))); } void LLVMKotlinInitializeTargets() { #define INIT_LLVM_TARGET(TargetName) \ LLVMInitialize##TargetName##TargetInfo();\ LLVMInitialize##TargetName##Target();\ LLVMInitialize##TargetName##TargetMC(); #if KONAN_MACOS INIT_LLVM_TARGET(AArch64) INIT_LLVM_TARGET(ARM) INIT_LLVM_TARGET(Mips) INIT_LLVM_TARGET(X86) INIT_LLVM_TARGET(WebAssembly) #elif KONAN_LINUX INIT_LLVM_TARGET(AArch64) INIT_LLVM_TARGET(ARM) INIT_LLVM_TARGET(Mips) INIT_LLVM_TARGET(X86) INIT_LLVM_TARGET(WebAssembly) #elif KONAN_WINDOWS INIT_LLVM_TARGET(AArch64) INIT_LLVM_TARGET(ARM) INIT_LLVM_TARGET(X86) INIT_LLVM_TARGET(WebAssembly) #endif #undef INIT_LLVM_TARGET } ================================================ FILE: llvmCoverageMappingC/src/main/include/CoverageMappingC.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef __COVERAGE_MAPPING_C_H__ # define __COVERAGE_MAPPING_C_H__ #include #include # ifdef __cplusplus extern "C" { # endif /** * See org.jetbrains.kotlin.backend.konan.llvm.coverage.RegionKind. */ enum LLVMCoverageRegionKind { CODE, GAP, EXPANSION }; /** * See org.jetbrains.kotlin.backend.konan.llvm.coverage.Region. */ struct LLVMCoverageRegion { int fileId; int lineStart; int columnStart; int lineEnd; int columnEnd; int counterId; int expandedFileId; enum LLVMCoverageRegionKind kind; }; struct LLVMFunctionCoverage; /** * Add record in the following format: https://llvm.org/docs/CoverageMappingFormat.html#function-record. */ LLVMValueRef LLVMAddFunctionMappingRecord(LLVMContextRef context, const char *name, uint64_t hash, struct LLVMFunctionCoverage* coverageMapping); /** * Wraps creation of coverage::CoverageMappingWriter and call to coverage::CoverageMappingWriter::write. */ struct LLVMFunctionCoverage* LLVMWriteCoverageRegionMapping(unsigned int *fileIdMapping, size_t fileIdMappingSize, struct LLVMCoverageRegion **mappingRegions, size_t mappingRegionsSize); void LLVMFunctionCoverageDispose(struct LLVMFunctionCoverage* functionCoverage); /** * Create __llvm_coverage_mapping global. */ LLVMValueRef LLVMCoverageEmit(LLVMModuleRef moduleRef, LLVMValueRef *records, size_t recordsSize, const char **filenames, int *filenamesIndices, size_t filenamesSize, struct LLVMFunctionCoverage** functionCoverages, size_t functionCoveragesSize); /** * Wrapper for `llvm.instrprof.increment` declaration. */ LLVMValueRef LLVMInstrProfIncrement(LLVMModuleRef moduleRef); /** * Wrapper for llvm::createPGOFuncNameVar. */ LLVMValueRef LLVMCreatePGOFunctionNameVar(LLVMValueRef llvmFunction, const char *pgoFunctionName); void LLVMAddInstrProfPass(LLVMPassManagerRef passManagerRef, const char* outputFileName); void LLVMKotlinAddTargetLibraryInfoWrapperPass(LLVMPassManagerRef passManagerRef, const char* targetTriple); void LLVMKotlinInitializeTargets(); # ifdef __cplusplus } # endif #endif ================================================ FILE: llvmDebugInfoC/build.gradle ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ apply plugin: "cpp" apply plugin: "c" buildscript { ext.rootBuildDirectory = file('..') apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" dependencies { classpath "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } import org.jetbrains.kotlin.konan.target.ClangArgs model { components { debugInfo(NativeLibrarySpec) { sources.cpp.source.srcDirs "src/main/cpp" binaries.withType(StaticLibraryBinarySpec) { binary -> if (!project.parent.convention.plugins.platformInfo.isWindows()) cppCompiler.args "-fPIC" cppCompiler.args "--std=c++17", "-I${llvmDir}/include", "-I${projectDir}/src/main/include" linker.args "-L${llvmDir}/lib", "-lLLVMCore", "-lLLVMSupport" } binaries.withType(SharedLibraryBinarySpec) { binary -> buildable = false } } } toolChains { clang(Clang) { eachPlatform { cppCompiler.withArguments(ClangArgs.&filterGradleNativeSoftwareFlags) } } } } ================================================ FILE: llvmDebugInfoC/src/dwarf/include/dwarf_util.kt.pp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.backend.konan.llvm /** * This code was generated with following command: * $ clang -xc -E -Idist/dependencies/clang-llvm-3.9.0-darwin-macos/include/ llvmDebugInfoC/src/dwarf/include/dwarf_util.kt.pp -Wp,-P -Wp,-CC -o - | sed -e '/^$/d' -e '/^\ *\/\/.*$/d' > backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Dwarf.kt * */ internal enum class DwarfTag(val value:Int) { #define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME(ID), #include "llvm/Support/Dwarf.def" #undef HANDLE_DW_TAG } internal enum class DwarfTypeKind(val value:Byte) { #define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME(ID), #include "llvm/Support/Dwarf.def" #undef HANDLE_DW_ATE } internal enum class DwarfOp(val value:Long) { #define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME(ID), #include "llvm/Support/Dwarf.def" #undef HANDLE_DW_OP } internal enum class DwarfLanguage(val value:Int) { #define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME(ID), #include "llvm/Support/Dwarf.def" #undef HANDLE_DW_LANG DW_LANG_Kotlin(0x0001) /* manually added, should be changed someday. */ } ================================================ FILE: llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "DebugInfoC.h" /** * c++ --std=c++17 llvmDebugInfoC/src/DebugInfoC.cpp -IllvmDebugInfoC/include/ -Idependencies/all/clang+llvm-3.9.0-darwin-macos/include -Ldependencies/all/clang+llvm-3.9.0-darwin-macos/lib -lLLVMCore -lLLVMSupport -lncurses -shared -o libLLVMDebugInfoC.dylib */ namespace llvm { //DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, DIBuilderRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompileUnit, DICompileUnitRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIFile, DIFileRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBasicType, DIBasicTypeRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompositeType, DICompositeTypeRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIType, DITypeOpaqueRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIDerivedType, DIDerivedTypeRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIModule, DIModuleRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIScope, DIScopeOpaqueRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubroutineType, DISubroutineTypeRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubprogram, DISubprogramRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocation, DILocationRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocalVariable, DILocalVariableRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIExpression, DIExpressionRef) // from Module.cpp //DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef) } /** * see [DIFlags::FlagFwdDecl]. */ #define DI_FORWARD_DECLARAION (4) extern "C" { void DIFinalize(DIBuilderRef builder) { auto diBuilder = llvm::unwrap(builder); diBuilder->finalize(); } DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang, const char *file, const char* dir, const char * producer, int isOptimized, const char * flags, unsigned int rv) { llvm::DIBuilder *D = llvm::unwrap(builder); return llvm::wrap(llvm::unwrap(builder)->createCompileUnit(lang, D->createFile(file, dir), producer, isOptimized, flags, rv)); } DIFileRef DICreateFile(DIBuilderRef builder, const char *filename, const char *directory) { return llvm::wrap(llvm::unwrap(builder)->createFile(filename, directory)); } DIBasicTypeRef DICreateBasicType(DIBuilderRef builder, const char* name, uint64_t sizeInBits, uint64_t alignment, unsigned encoding) { return llvm::wrap(llvm::unwrap(builder)->createBasicType(name, sizeInBits, encoding)); } DIModuleRef DICreateModule(DIBuilderRef builder, DIScopeOpaqueRef scope, const char* name, const char* configurationMacro, const char* includePath, const char *iSysRoot) { return llvm::wrap(llvm::unwrap(builder)->createModule(llvm::unwrap(scope), name, configurationMacro, includePath, iSysRoot)); } DISubprogramRef DICreateFunction(DIBuilderRef builderRef, DIScopeOpaqueRef scope, const char* name, const char *linkageName, DIFileRef file, unsigned lineNo, DISubroutineTypeRef type, int isLocal, int isDefinition, unsigned scopeLine) { auto builder = llvm::unwrap(builderRef); auto subprogram = builder->createFunction(llvm::unwrap(scope), name, linkageName, llvm::unwrap(file), lineNo, llvm::unwrap(type), scopeLine, llvm::DINode::DIFlags::FlagZero, llvm::DISubprogram::toSPFlags(false, true, false)); auto tmp = subprogram->getRetainedNodes().get(); if (!tmp && tmp->isTemporary()) llvm::MDTuple::deleteTemporary(tmp); builder->finalizeSubprogram(subprogram); return llvm::wrap(subprogram); } DIScopeOpaqueRef DICreateLexicalBlockFile(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef) { return llvm::wrap(llvm::unwrap(builderRef)->createLexicalBlockFile(llvm::unwrap(scopeRef), llvm::unwrap(fileRef))); } DIScopeOpaqueRef DICreateLexicalBlock(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef, int line, int column) { return llvm::wrap(llvm::unwrap(builderRef)->createLexicalBlock(llvm::unwrap(scopeRef), llvm::unwrap(fileRef), line, column)); } DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned lineNumber, uint64_t sizeInBits, uint64_t alignInBits, unsigned flags, DITypeOpaqueRef derivedFrom, DIDerivedTypeRef *elements, uint64_t elementsCount, DICompositeTypeRef refPlace) { auto builder = llvm::unwrap(refBuilder); if ((flags & DI_FORWARD_DECLARAION) != 0) { auto tmp = builder->createReplaceableCompositeType( llvm::dwarf::DW_TAG_structure_type, name, llvm::unwrap(scope), llvm::unwrap(file), lineNumber, 0, sizeInBits, alignInBits, (llvm::DINode::DIFlags)flags); builder->replaceTemporary(llvm::TempDIType(tmp), tmp); builder->retainType(tmp); return llvm::wrap(tmp); } assert(false); return nullptr; } DICompositeTypeRef DICreateArrayType(DIBuilderRef refBuilder, uint64_t size, uint64_t alignInBits, DITypeOpaqueRef refType, uint64_t elementsCount) { auto builder = llvm::unwrap(refBuilder); auto range = std::vector({llvm::dyn_cast(builder->getOrCreateSubrange(0, size))}); auto type = builder->createArrayType(size, alignInBits, llvm::unwrap(refType), builder->getOrCreateArray(range)); builder->retainType(type); return llvm::wrap(type); } DIDerivedTypeRef DICreateMemberType(DIBuilderRef refBuilder, DIScopeOpaqueRef refScope, const char *name, DIFileRef file, unsigned lineNum, uint64_t sizeInBits, uint64_t alignInBits, uint64_t offsetInBits, unsigned flags, DITypeOpaqueRef type) { return llvm::wrap(llvm::unwrap(refBuilder)->createMemberType( llvm::unwrap(refScope), name, llvm::unwrap(file), lineNum, sizeInBits, alignInBits, offsetInBits, (llvm::DINode::DIFlags)flags, llvm::unwrap(type))); } DICompositeTypeRef DICreateReplaceableCompositeType(DIBuilderRef refBuilder, int tag, const char *name, DIScopeOpaqueRef refScope, DIFileRef refFile, unsigned line) { auto builder = llvm::unwrap(refBuilder); auto type = builder->createReplaceableCompositeType( tag, name, llvm::unwrap(refScope), llvm::unwrap(refFile), line); builder->retainType(type); return llvm::wrap(type); } DIDerivedTypeRef DICreateReferenceType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) { auto builder = llvm::unwrap(refBuilder); auto type = builder->createReferenceType( llvm::dwarf::DW_TAG_reference_type, llvm::unwrap(refType)); builder->retainType(type); return llvm::wrap(type); } DIDerivedTypeRef DICreatePointerType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) { auto builder = llvm::unwrap(refBuilder); auto type = builder->createReferenceType( llvm::dwarf::DW_TAG_pointer_type, llvm::unwrap(refType)); builder->retainType(type); return llvm::wrap(type); } DISubroutineTypeRef DICreateSubroutineType(DIBuilderRef builder, DITypeOpaqueRef* types, unsigned typesCount) { std::vector parameterTypes; for (int i = 0; i != typesCount; ++i) { parameterTypes.push_back(llvm::unwrap(types[i])); } llvm::DIBuilder *b = llvm::unwrap(builder); llvm::DITypeRefArray typeArray = b->getOrCreateTypeArray(parameterTypes); auto type = b->createSubroutineType(typeArray); b->retainType(type); return llvm::wrap(type); } void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp) { auto f = llvm::cast(llvm::unwrap(fn)); auto dsp = llvm::cast(llvm::unwrap(sp)); f->setSubprogram(dsp); if (!dsp->describes(f)) { fprintf(stderr, "error!!! f:%s, sp:%s\n", f->getName().str().c_str(), dsp->getLinkageName().str().c_str()); } } DILocalVariableRef DICreateAutoVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned line, DITypeOpaqueRef type) { return llvm::wrap(llvm::unwrap(builder)->createAutoVariable( llvm::unwrap(scope), name, llvm::unwrap(file), line, llvm::unwrap(type))); } DILocalVariableRef DICreateParameterVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, unsigned argNo, DIFileRef file, unsigned line, DITypeOpaqueRef type) { return llvm::wrap(llvm::unwrap(builder)->createParameterVariable( llvm::unwrap(scope), name, argNo, llvm::unwrap(file), line, llvm::unwrap(type))); } DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder) { return llvm::wrap(llvm::unwrap(builder)->createExpression()); } void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount) { auto di_builder = llvm::unwrap(builder); std::vector expression; for (uint64_t i = 0; i < exprCount; ++i) expression.push_back(expr[i]); di_builder->insertDeclare(llvm::unwrap(value), llvm::unwrap(localVariable), di_builder->createExpression(expression), llvm::unwrap(location), llvm::unwrap(bb)); } DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope) { auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), nullptr); return llvm::wrap(location); } DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocationInlinedAt) { auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), llvm::unwrap(refLocationInlinedAt)); return llvm::wrap(location); } void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation) { llvm::unwrap(builder)->SetCurrentDebugLocation(llvm::unwrap(refLocation)); } void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder) { llvm::unwrap(builder)->SetCurrentDebugLocation(nullptr); } LLVMValueRef LLVMBuilderGetCurrentFunction(LLVMBuilderRef builder) { return llvm::wrap(llvm::unwrap(builder)->GetInsertBlock()->getParent()); } const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder) { return llvm::unwrap(builder)->GetInsertBlock()->getName().str().c_str(); } const char *DIGetSubprogramLinkName(DISubprogramRef sp) { return llvm::unwrap(sp)->getLinkageName().str().c_str(); } int DISubprogramDescribesFunction(DISubprogramRef sp, LLVMValueRef fn) { return llvm::unwrap(sp)->describes(llvm::cast(llvm::unwrap(fn))); } } /* extern "C" */ ================================================ FILE: llvmDebugInfoC/src/main/include/DebugInfoC.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __DEBUG_INFO_C_H__ # define __DEBUG_INFO_C_H__ #include # ifdef __cplusplus extern "C" { # endif typedef struct LLVMOpaqueDIBuilder *DIBuilderRef; //typedef struct DIBuilder *DIBuilderRef; typedef struct DICompileUnit *DICompileUnitRef; typedef struct DIFile *DIFileRef; typedef struct DIBasicType *DIBasicTypeRef; typedef struct DICompositeType *DICompositeTypeRef; typedef struct DIDerivedType *DIDerivedTypeRef; typedef struct DIType *DITypeOpaqueRef; typedef struct DISubprogram *DISubprogramRef; typedef struct DIModule *DIModuleRef; typedef struct DIScope *DIScopeOpaqueRef; typedef struct DISubroutineType *DISubroutineTypeRef; //typedef struct DISubprogram *DISubprogramRef; typedef struct DILocation *DILocationRef; typedef struct DILocalVariable *DILocalVariableRef; typedef struct DIExpression *DIExpressionRef; void DIFinalize(DIBuilderRef builder); DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang, const char *File, const char* dir, const char * producer, int isOptimized, const char * flags, unsigned int rv); DIFileRef DICreateFile(DIBuilderRef builder, const char *filename, const char *directory); DIBasicTypeRef DICreateBasicType(DIBuilderRef builder, const char* name, uint64_t sizeInBits, uint64_t alignment, unsigned encoding); DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned lineNumber, uint64_t sizeInBits, uint64_t alignInBits, unsigned flags, DITypeOpaqueRef derivedFrom, DIDerivedTypeRef *elements, uint64_t elementsCount, DICompositeTypeRef refPlace); DICompositeTypeRef DICreateArrayType(DIBuilderRef refBuilder, uint64_t size, uint64_t alignInBits, DITypeOpaqueRef type, uint64_t elementsCount); DIDerivedTypeRef DICreateReferenceType(DIBuilderRef refBuilder, DITypeOpaqueRef refType); DIDerivedTypeRef DICreatePointerType(DIBuilderRef refBuilder, DITypeOpaqueRef refType); DICompositeTypeRef DICreateReplaceableCompositeType(DIBuilderRef refBuilder, int tag, const char *name, DIScopeOpaqueRef refScope, DIFileRef refFile, unsigned line); DIDerivedTypeRef DICreateMemberType(DIBuilderRef refBuilder, DIScopeOpaqueRef refScope, const char *name, DIFileRef file, unsigned lineNum, uint64_t sizeInBits, uint64_t alignInBits, uint64_t offsetInBits, unsigned flags, DITypeOpaqueRef type); DIModuleRef DICreateModule(DIBuilderRef builder, DIScopeOpaqueRef scope, const char* name, const char* configurationMacro, const char* includePath, const char *iSysRoot); DIScopeOpaqueRef DICreateLexicalBlockFile(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef); DIScopeOpaqueRef DICreateLexicalBlock(DIBuilderRef builderRef, DIScopeOpaqueRef scopeRef, DIFileRef fileRef, int line, int column); DISubprogramRef DICreateFunction(DIBuilderRef builder, DIScopeOpaqueRef scope, const char* name, const char *linkageName, DIFileRef file, unsigned lineNo, DISubroutineTypeRef type, int isLocal, int isDefinition, unsigned scopeLine); DISubroutineTypeRef DICreateSubroutineType(DIBuilderRef builder, DITypeOpaqueRef* types, unsigned typesCount); DILocalVariableRef DICreateAutoVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned line, DITypeOpaqueRef type); DILocalVariableRef DICreateParameterVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, unsigned argNo, DIFileRef file, unsigned line, DITypeOpaqueRef type); void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount); DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder); void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp); DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope); DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocation); void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation); void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder); const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder); const char *DIGetSubprogramLinkName(DISubprogramRef sp); LLVMValueRef LLVMBuilderGetCurrentFunction(LLVMBuilderRef builder); int DISubprogramDescribesFunction(DISubprogramRef sp, LLVMValueRef fn); # ifdef __cplusplus } # endif #endif ================================================ FILE: llvmDebugInfoC/src/scripts/konan_lldb.py ================================================ #!/usr/bin/python ## # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # (lldb) command script import llvmDebugInfoC/src/scripts/konan_lldb.py # (lldb) p kotlin_variable # import lldb import struct import re import sys import os import time import io import traceback NULL = 'null' logging=False exe_logging=False bench_logging=False def log(msg): if logging: sys.stderr.write(msg()) sys.stderr.write('\n') exelog(msg) def exelog(stmt): if exe_logging: f = open(os.getenv('HOME', '') + "/lldbexelog.txt", "a") f.write(stmt()) f.write("\n") f.close() def bench(start, msg): if bench_logging: print("{}: {}".format(msg(), time.monotonic() - start)) def evaluate(expr): result = lldb.debugger.GetSelectedTarget().EvaluateExpression(expr) log(lambda : "evaluate: {} => {}".format(expr, result)) return result class DebuggerException(Exception): pass _OUTPUT_MAX_CHILDREN = re.compile(r"target.max-children-count \(int\) = (.*)\n") def _max_children_count(): result = lldb.SBCommandReturnObject() lldb.debugger.GetCommandInterpreter().HandleCommand("settings show target.max-children-count", result, False) if not result.Succeeded(): raise DebuggerException() v = _OUTPUT_MAX_CHILDREN.search(result.GetOutput()).group(1) return int(v) def _symbol_loaded_address(name, debugger = lldb.debugger): target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() candidates = list(filter(lambda x: x.name == name, frame.module.symbols)) # take first for candidate in candidates: address = candidate.GetStartAddress().GetLoadAddress(target) log(lambda: "_symbol_loaded_address:{} {:#x}".format(name, address)) return address def _type_info_by_address(address, debugger = lldb.debugger): target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() candidates = list(filter(lambda x: x.GetStartAddress().GetLoadAddress(target) == address, frame.module.symbols)) return candidates def is_instance_of(addr, typeinfo): return evaluate("(bool)IsInstance({:#x}, {:#x})".format(addr, typeinfo)).GetValue() == "true" def is_string_or_array(value): start = time.monotonic() soa = evaluate("(int)IsInstance({0:#x}, {1:#x}) ? 1 : ((int)Konan_DebugIsArray({0:#x})) ? 2 : 0)" .format(value.unsigned, _symbol_loaded_address('kclass:kotlin.String'))).unsigned log(lambda: "is_string_or_array:{:#x}:{}".format(value.unsigned, soa)) bench(start, lambda: "is_string_or_array({:#x}) = {}".format(value.unsigned, soa)) return soa def type_info(value): """This method checks self-referencing of pointer of first member of TypeInfo including case when object has an meta-object pointed by TypeInfo. Two lower bits are reserved for memory management needs see runtime/src/main/cpp/Memory.h.""" log(lambda: "type_info({:#x}: {})".format(value.unsigned, value.GetTypeName())) if value.GetTypeName() != "ObjHeader *": return None expr = "*(void **)((uintptr_t)(*(void**){0:#x}) & ~0x3) == **(void***)((uintptr_t)(*(void**){0:#x}) & ~0x3) " \ "? *(void **)((uintptr_t)(*(void**){0:#x}) & ~0x3) : (void *)0".format(value.unsigned) result = evaluate(expr) return result.unsigned if result.IsValid() and result.unsigned != 0 else None __FACTORY = {} # Cache type info pointer to [ChildMetaInfo] SYNTHETIC_OBJECT_LAYOUT_CACHE = {} TO_STRING_DEPTH = 2 ARRAY_TO_STRING_LIMIT = 10 _TYPE_CONVERSION = [ lambda obj, value, address, name: value.CreateValueFromExpression(name, "(void *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromAddress(name, address, value.type), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(int8_t *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(int16_t *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(int32_t *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(int64_t *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(float *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(double *){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(void **){:#x}".format(address)), lambda obj, value, address, name: value.CreateValueFromExpression(name, "(bool *){:#x}".format(address)), lambda obj, value, address, name: None] _TYPES = [ lambda x: x.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType(), lambda x: x.GetType(), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeChar), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeShort), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeInt), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeLongLong), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeFloat), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeDouble), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType(), lambda x: x.GetType().GetBasicType(lldb.eBasicTypeBool) ] def kotlin_object_type_summary(lldb_val, internal_dict = {}): """Hook that is run by lldb to display a Kotlin object.""" start = time.monotonic() log(lambda: "kotlin_object_type_summary({:#x}: {})".format(lldb_val.unsigned, lldb_val.type.name)) fallback = lldb_val.GetValue() if lldb_val.GetTypeName() != "ObjHeader *": if lldb_val.GetValue() is None: bench(start, lambda: "kotlin_object_type_summary:({:#x}) = NULL".format(lldb_val.unsigned)) return NULL bench(start, lambda: "kotlin_object_type_summary:({:#x}) = {}".format(lldb_val.unsigned, lldb_val.signed)) return lldb_val.value if lldb_val.unsigned == 0: bench(start, lambda: "kotlin_object_type_summary:({:#x}) = NULL".format(lldb_val.unsigned)) return NULL tip = internal_dict["type_info"] if "type_info" in internal_dict.keys() else type_info(lldb_val) if not tip: bench(start, lambda: "kotlin_object_type_summary:({0:#x}) = falback:{0:#x}".format(lldb_val.unsigned)) return fallback value = select_provider(lldb_val, tip, internal_dict) bench(start, lambda: "kotlin_object_type_summary:({:#x}) = value:{:#x}".format(lldb_val.unsigned, value._valobj.unsigned)) start = time.monotonic() str0 = value.to_short_string() bench(start, lambda: "kotlin_object_type_summary:({:#x}) = str:'{}...'".format(lldb_val.unsigned, str0[:3])) return str0 def select_provider(lldb_val, tip, internal_dict): start = time.monotonic() log(lambda : "select_provider: {:#x} name:{} tip:{:#x}".format(lldb_val.unsigned, lldb_val.name, tip)) soa = is_string_or_array(lldb_val) log(lambda : "select_provider: {:#x} : soa: {}".format(lldb_val.unsigned, soa)) ret = __FACTORY['string'](lldb_val, tip, internal_dict) if soa == 1 \ else __FACTORY['array'](lldb_val, tip, internal_dict) if soa == 2 \ else __FACTORY['object'](lldb_val, tip, internal_dict) log(lambda: "select_provider({:#x}) = {}".format(lldb_val.unsigned, ret)) bench(start, lambda: "select_provider({:#x})".format(lldb_val.unsigned)) return ret class KonanHelperProvider(lldb.SBSyntheticValueProvider): def __init__(self, valobj, amString, internal_dict = {}): self._target = lldb.debugger.GetSelectedTarget() self._process = self._target.GetProcess() self._valobj = valobj self._internal_dict = internal_dict.copy() if amString: return if self._children_count == 0: children_count = evaluate("(int)Konan_DebugGetFieldCount({:#x})".format(self._valobj.unsigned)).signed log(lambda: "(int)[{}].Konan_DebugGetFieldCount({:#x}) = {}".format(self._valobj.name, self._valobj.unsigned, children_count)) self._children_count = children_count def _read_string(self, expr, error): return self._process.ReadCStringFromMemory(evaluate(expr).unsigned, 0x1000, error) def _read_value(self, index): value_type = self._field_type(index) address = self._field_address(index) log(lambda: "_read_value: [{}, type:{}, address:{:#x}]".format(index, value_type, address)) return _TYPE_CONVERSION[int(value_type)](self, self._valobj, address, str(self._field_name(index))) def _read_type(self, index): type = _TYPES[self._field_type(index)](self._valobj) log(lambda: "type:{0} of {1:#x} of {2:#x}".format(type, self._valobj.unsigned, self._valobj.unsigned + self._children[index].offset())) return type def _deref_or_obj_summary(self, index, internal_dict = {}): value = self._read_value(index) if not value: log(lambda : "_deref_or_obj_summary: value none, index:{}, type:{}".format(index, self._children[index].type())) return None return value.value if type_info(value) else value.deref.value def _field_address(self, index): return evaluate("(void *)Konan_DebugGetFieldAddress({:#x}, {})".format(self._valobj.unsigned, index)).unsigned def _field_type(self, index): return evaluate("(int)Konan_DebugGetFieldType({:#x}, {})".format(self._valobj.unsigned, index)).unsigned def to_string(self, representation): writer = io.StringIO() max_children_count=_max_children_count() limit = min(self._children_count, max_children_count) for i in range(limit): writer.write(representation(i)) if (i != limit - 1): writer.write(", ") if max_children_count < self._children_count: writer.write(', ...') return "[{}]".format(writer.getvalue()) class KonanStringSyntheticProvider(KonanHelperProvider): def __init__(self, valobj): log(lambda: "KonanStringSyntheticProvider:{:#x} name:{}".format(valobj.unsigned, valobj.name)) self._children_count = 0 super(KonanStringSyntheticProvider, self).__init__(valobj, True) fallback = valobj.GetValue() buff_addr = evaluate("(void *)Konan_DebugBuffer()").unsigned buff_len = evaluate( '(int)Konan_DebugObjectToUtf8Array({:#x}, (void *){:#x}, (int)Konan_DebugBufferSize());'.format( self._valobj.unsigned, buff_addr) ).signed if not buff_len: self._representation = fallback return error = lldb.SBError() s = self._process.ReadCStringFromMemory(int(buff_addr), int(buff_len), error) if not error.Success(): raise DebuggerException() self._representation = s if error.Success() else fallback self._logger = lldb.formatters.Logger.Logger() def update(self): pass def num_children(self): return 0 def has_children(self): return False def get_child_index(self, _): return None def get_child_at_index(self, _): return None def to_short_string(self): return self._representation def to_string(self): return self._representation class KonanObjectSyntheticProvider(KonanHelperProvider): def __init__(self, valobj, tip, internal_dict): # Save an extra call into the process log(lambda: "KonanObjectSyntheticProvider({:#x})".format(valobj.unsigned)) self._children_count = 0 super(KonanObjectSyntheticProvider, self).__init__(valobj, False, internal_dict) self._children = [self._field_name(i) for i in range(self._children_count)] log(lambda: "KonanObjectSyntheticProvider::__init__({:#x}) _children:{}".format(self._valobj.unsigned, self._children)) def _field_name(self, index): log(lambda: "KonanObjectSyntheticProvider::_field_name({:#x}, {})".format(self._valobj.unsigned, index)) error = lldb.SBError() name = self._read_string("(char *)Konan_DebugGetFieldName({:#x}, (int){})".format(self._valobj.unsigned, index), error) if not error.Success(): raise DebuggerException() log(lambda: "KonanObjectSyntheticProvider::_field_name({:#x}, {}) = {}".format(self._valobj.unsigned, index, name)) return name def num_children(self): log(lambda: "KonanObjectSyntheticProvider::num_children({:#x}) = {}".format(self._valobj.unsigned, self._children_count)) return self._children_count def has_children(self): log(lambda: "KonanObjectSyntheticProvider::has_children({:#x}) = {}".format(self._valobj.unsigned, self._children_count > 0)) return self._children_count > 0 def get_child_index(self, name): log(lambda: "KonanObjectSyntheticProvider::get_child_index({:#x}, {})".format(self._valobj.unsigned, name)) index = self._children.index(name) log(lambda: "KonanObjectSyntheticProvider::get_child_index({:#x}) index={}".format(self._valobj.unsigned, index)) return index def get_child_at_index(self, index): log(lambda: "KonanObjectSyntheticProvider::get_child_at_index({:#x}, {})".format(self._valobj.unsigned, index)) return self._read_value(index) def to_short_string(self): log(lambda: "to_short_string:{:#x}".format(self._valobj.unsigned)) return super().to_string(lambda index: "{}: ...".format(self._field_name(index))) def to_string(self): log(lambda: "to_string:{:#x}".format(self._valobj.unsigned)) return super().to_string(lambda index: "{}: {}".format(self._field_name(index), self._deref_or_obj_summary(index))) class KonanArraySyntheticProvider(KonanHelperProvider): def __init__(self, valobj, internal_dict): self._children_count = 0 super(KonanArraySyntheticProvider, self).__init__(valobj, False, internal_dict) log(lambda: "KonanArraySyntheticProvider: valobj:{:#x}".format(valobj.unsigned)) if self._valobj is None: return valobj.SetSyntheticChildrenGenerated(True) type = self._field_type(0) def num_children(self): log(lambda: "KonanArraySyntheticProvider::num_children({:#x}) = {}".format(self._valobj.unsigned, self._children_count)) return self._children_count def has_children(self): log(lambda: "KonanArraySyntheticProvider::has_children({:#x}) = {}".format(self._valobj.unsigned, self._children_count> 0)) return self._children_count > 0 def get_child_index(self, name): log(lambda: "KonanArraySyntheticProvider::get_child_index({:#x}, {})".format(self._valobj.unsigned, name)) index = int(name) return index if (0 <= index < self._children_count) else -1 def get_child_at_index(self, index): log(lambda: "KonanArraySyntheticProvider::get_child_at_index({:#x}, {})".format(self._valobj.unsigned, index)) return self._read_value(index) def _field_name(self, index): log(lambda: "KonanArraySyntheticProvider::_field_name({:#x}, {})".format(self._valobj.unsigned, index)) return str(index) def to_short_string(self): log(lambda: "to_short_string:{:#x}".format(self._valobj.unsigned)) return super().to_string(lambda index: "...") def to_string(self): log(lambda: "to_string:{self._valobj.unsigned:#x}") return super().to_string(lambda index: "{}".format(self._deref_or_obj_summary(index))) class KonanZerroSyntheticProvider(lldb.SBSyntheticValueProvider): def __init__(self, valobj): log(lambda: "KonanZerroSyntheticProvider::__init__ {}".format(valobj.name)) def num_children(self): log(lambda: "KonanZerroSyntheticProvider::num_children") return 0 def has_children(self): log(lambda: "KonanZerroSyntheticProvider::has_children") return False def get_child_index(self, name): log(lambda: "KonanZerroSyntheticProvider::get_child_index") return 0 def get_child_at_index(self, index): log(lambda: "KonanZerroSyntheticProvider::get_child_at_index") return None def to_string(self): log(lambda: "KonanZerroSyntheticProvider::to_string") return NULL def to_short_string(self): log(lambda: "KonanZerroSyntheticProvider::to_short_string") return NULL def __getattr__(self, item): pass class KonanNullSyntheticProvider(KonanZerroSyntheticProvider): def __init__(self, valobj): super(KonanNullSyntheticProvider, self).__init__(valobj) class KonanNotInitializedObjectSyntheticProvider(KonanZerroSyntheticProvider): def __init__(self, valobj): super(KonanNotInitializedObjectSyntheticProvider, self).__init__(valobj) class KonanProxyTypeProvider: def __init__(self, valobj, internal_dict): start = time.monotonic() log(lambda : "KonanProxyTypeProvider:{:#x}, name: {}".format(valobj.unsigned, valobj.name)) if valobj.unsigned == 0: log(lambda : "KonanProxyTypeProvider:{:#x}, name: {} NULL syntectic {}".format(valobj.unsigned, valobj.name, valobj.IsValid())) bench(start, lambda: "KonanProxyTypeProvider({:#x})".format(valobj.unsigned)) self._proxy = KonanNullSyntheticProvider(valobj) return tip = type_info(valobj) if not tip: log(lambda : "KonanProxyTypeProvider:{:#x}, name: {} not initialized syntectic {}".format(valobj.unsigned, valobj.name, valobj.IsValid())) bench(start, lambda: "KonanProxyTypeProvider({:#x})".format(valobj.unsigned)) self._proxy = KonanNotInitializedObjectSyntheticProvider(valobj) return log(lambda : "KonanProxyTypeProvider:{:#x} tip: {:#x}".format(valobj.unsigned, tip)) self._proxy = select_provider(valobj, tip, internal_dict) bench(start, lambda: "KonanProxyTypeProvider({:#x})".format(valobj.unsigned)) log(lambda: "KonanProxyTypeProvider:{:#x} _proxy: {}".format(valobj.unsigned, self._proxy.__class__.__name__)) def __getattr__(self, item): return getattr(self._proxy, item) def type_name_command(debugger, command, result, internal_dict): result.AppendMessage(evaluate('(char *)Konan_DebugGetTypeName({})'.format(command)).summary) __KONAN_VARIABLE = re.compile('kvar:(.*)#internal') __KONAN_VARIABLE_TYPE = re.compile('^kfun:\\(\\)(.*)$') __TYPES_KONAN_TO_C = { 'kotlin.Byte': ('int8_t', lambda v: v.signed), 'kotlin.Short': ('short', lambda v: v.signed), 'kotlin.Int': ('int', lambda v: v.signed), 'kotlin.Long': ('long', lambda v: v.signed), 'kotlin.UByte': ('int8_t', lambda v: v.unsigned), 'kotlin.UShort': ('short', lambda v: v.unsigned), 'kotlin.UInt': ('int', lambda v: v.unsigned), 'kotlin.ULong': ('long', lambda v: v.unsigned), 'kotlin.Char': ('short', lambda v: v.signed), 'kotlin.Boolean': ('bool', lambda v: v.signed), 'kotlin.Float': ('float', lambda v: v.value), 'kotlin.Double': ('double', lambda v: v.value) } def type_by_address_command(debugger, command, result, internal_dict): result.AppendMessage("DEBUG: {}".format(command)) tokens = command.split() target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() types = _type_info_by_address(tokens[0]) result.AppendMessage("DEBUG: {}".format(types)) for t in types: result.AppendMessage("{}: {:#x}".format(t.name, t.GetStartAddress().GetLoadAddress(target))) def symbol_by_name_command(debugger, command, result, internal_dict): target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() tokens = command.split() mask = re.compile(tokens[0]) symbols = list(filter(lambda v: mask.match(v.name), frame.GetModule().symbols)) visited = list() for symbol in symbols: name = symbol.name if name in visited: continue visited.append(name) result.AppendMessage("{}: {:#x}".format(name, symbol.GetStartAddress().GetLoadAddress(target))) def konan_globals_command(debugger, command, result, internal_dict): target = debugger.GetSelectedTarget() process = target.GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() konan_variable_symbols = list(filter(lambda v: __KONAN_VARIABLE.match(v.name), frame.GetModule().symbols)) visited = list() for symbol in konan_variable_symbols: name = __KONAN_VARIABLE.search(symbol.name).group(1) if name in visited: continue visited.append(name) getters = list(filter(lambda v: re.match('^kfun:\\(\\).*$'.format(name), v.name), frame.module.symbols)) if not getters: result.AppendMessage("storage not found for name:{}".format(name)) continue getter_functions = frame.module.FindFunctions(getters[0].name) if not getter_functions: continue address = getter_functions[0].function.GetStartAddress().GetLoadAddress(target) type = __KONAN_VARIABLE_TYPE.search(getters[0].name).group(2) (c_type, extractor) = __TYPES_KONAN_TO_C[type] if type in __TYPES_KONAN_TO_C.keys() else ('ObjHeader *', lambda v: kotlin_object_type_summary(v)) value = evaluate('(({0} (*)()){1:#x})()'.format(c_type, address)) str_value = extractor(value) result.AppendMessage('{} {}: {}'.format(type, name, str_value)) def __lldb_init_module(debugger, _): log(lambda: "init start") __FACTORY['object'] = lambda x, y, z: KonanObjectSyntheticProvider(x, y, z) __FACTORY['array'] = lambda x, y, z: KonanArraySyntheticProvider(x, z) __FACTORY['string'] = lambda x, y, _: KonanStringSyntheticProvider(x) debugger.HandleCommand('\ type summary add \ --no-value \ --expand \ --python-function konan_lldb.kotlin_object_type_summary \ "ObjHeader *" \ --category Kotlin\ ') debugger.HandleCommand('\ type synthetic add \ --python-class konan_lldb.KonanProxyTypeProvider \ "ObjHeader *" \ --category Kotlin\ ') debugger.HandleCommand('type category enable Kotlin') debugger.HandleCommand('command script add -f {}.type_name_command type_name'.format(__name__)) debugger.HandleCommand('command script add -f {}.type_by_address_command type_by_address'.format(__name__)) debugger.HandleCommand('command script add -f {}.symbol_by_name_command symbol_by_name'.format(__name__)) log(lambda: "init end") ================================================ FILE: performance/KotlinVsSwift/build.gradle ================================================ buildscript { apply from: "$rootProject.projectDir/../gradle/kotlinGradlePlugin.gradle" repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() } } def rootBuildDirectory = rootProject.projectDir task konanRun { subprojects.each { dependsOn it.getTasksByName('konanRun', true)[0] } } task jvmRun { subprojects.each { dependsOn it.getTasksByName('jvmRun', true)[0] } } task clean { subprojects.each { dependsOn it.getTasksByName('clean', true)[0] } doLast { delete "${buildDir.absolutePath}" } } defaultTasks 'konanRun' task mergeNativeReports { doLast { mergeReports(nativeJson) uploadBenchmarkResultToArtifactory(nativeJson) } } task mergeJvmReports { doLast { mergeReports(jvmJson) uploadBenchmarkResultToArtifactory(jvmJson) } } subprojects.each { it.getTasksByName('jvmJsonReport', true)[0].finalizedBy mergeJvmReports it.getTasksByName('konanJsonReport', true)[0].finalizedBy mergeNativeReports } task ring { dependsOn 'clean' dependsOn 'ring:konanRun' } ================================================ FILE: performance/KotlinVsSwift/ring/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.benchmark.CodeSizeEntity plugins { id("swift-benchmarking") } val toolsPath = "../../../tools" swiftBenchmark { applicationName = "Ring" commonSrcDirs = listOf("$toolsPath/benchmarks/shared/src/main/kotlin", "../../shared/src/main/kotlin") nativeSrcDirs = listOf("../../shared/src/main/kotlin-native/common", "../../shared/src/main/kotlin-native/posix") swiftSources = File("$projectDir/src").list().map { "$projectDir/src/$it" }.toList() compileTasks = listOf("buildSwift") useCodeSize = CodeSizeEntity.EXECUTABLE } ================================================ FILE: performance/KotlinVsSwift/ring/gradle.properties ================================================ kotlin.native.home=../../../dist ================================================ FILE: performance/KotlinVsSwift/ring/src/AbstractMethodBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class AbstractMethodBenchmark { private let arr: [String] = zdf_win private let sequence = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" private var sequenceMap: [Character: Int] = [:] init() { var i = 0 for ch in sequence { sequenceMap[ch] = i i += 1 } } func sortStrings() -> Set { var size = arr.count if (Constants.BENCHMARK_SIZE < size) { size = Constants.BENCHMARK_SIZE } let res = Set(arr[0.. Set { var res = Set() var size = Constants.BENCHMARK_SIZE < arr.count ? Constants.BENCHMARK_SIZE : arr.count arr[0.. Int } protocol E { func foo() -> Any } extension I { func foo1() -> Int { return 1 } func foo2() -> Int { return 2 } func foo3() -> Int { return 3 } func foo4() -> Int { return 4 } func foo5() -> Int { return 5 } func foo6() -> Int { return 6 } func foo7() -> Int { return 7 } func foo8() -> Int { return 8 } func foo9() -> Int { return 9 } func foo10() -> Int { return 10 } func foo11() -> Int { return 11 } func foo12() -> Int { return 12 } func foo13() -> Int { return 13 } func foo14() -> Int { return 14 } func foo15() -> Int { return 15 } func foo16() -> Int { return 16 } func foo17() -> Int { return 17 } func foo18() -> Int { return 18 } func foo19() -> Int { return 19 } func foo20() -> Int { return 20 } func foo21() -> Int { return 21 } func foo22() -> Int { return 22 } func foo23() -> Int { return 23 } func foo24() -> Int { return 24 } func foo25() -> Int { return 25 } func foo26() -> Int { return 26 } func foo27() -> Int { return 27 } func foo28() -> Int { return 28 } func foo29() -> Int { return 29 } func foo30() -> Int { return 30 } func foo31() -> Int { return 31 } func foo32() -> Int { return 32 } func foo33() -> Int { return 33 } func foo34() -> Int { return 34 } func foo35() -> Int { return 35 } func foo36() -> Int { return 36 } func foo37() -> Int { return 37 } func foo38() -> Int { return 38 } func foo39() -> Int { return 39 } func foo40() -> Int { return 40 } func foo41() -> Int { return 41 } func foo42() -> Int { return 42 } func foo43() -> Int { return 43 } func foo44() -> Int { return 44 } func foo45() -> Int { return 45 } func foo46() -> Int { return 46 } func foo47() -> Int { return 47 } func foo48() -> Int { return 48 } func foo49() -> Int { return 49 } func foo50() -> Int { return 50 } func foo51() -> Int { return 51 } func foo52() -> Int { return 52 } func foo53() -> Int { return 53 } func foo54() -> Int { return 54 } func foo55() -> Int { return 55 } func foo56() -> Int { return 56 } func foo57() -> Int { return 57 } func foo58() -> Int { return 58 } func foo59() -> Int { return 59 } func foo60() -> Int { return 60 } func foo61() -> Int { return 31 } func foo62() -> Int { return 62 } func foo63() -> Int { return 63 } func foo64() -> Int { return 64 } func foo65() -> Int { return 65 } func foo66() -> Int { return 66 } func foo67() -> Int { return 67 } func foo68() -> Int { return 68 } func foo69() -> Int { return 69 } func foo70() -> Int { return 70 } func foo71() -> Int { return 71 } func foo72() -> Int { return 72 } func foo73() -> Int { return 73 } func foo74() -> Int { return 74 } func foo75() -> Int { return 75 } func foo76() -> Int { return 76 } func foo77() -> Int { return 77 } func foo78() -> Int { return 78 } func foo79() -> Int { return 79 } func foo80() -> Int { return 80 } func foo81() -> Int { return 81 } func foo82() -> Int { return 82 } func foo83() -> Int { return 83 } func foo84() -> Int { return 84 } func foo85() -> Int { return 85 } func foo86() -> Int { return 86 } func foo87() -> Int { return 87 } func foo88() -> Int { return 88 } func foo89() -> Int { return 89 } func foo90() -> Int { return 90 } func foo91() -> Int { return 91 } func foo92() -> Int { return 92 } func foo93() -> Int { return 93 } func foo94() -> Int { return 94 } func foo95() -> Int { return 95 } func foo96() -> Int { return 96 } func foo97() -> Int { return 97 } func foo98() -> Int { return 98 } func foo99() -> Int { return 99 } } protocol A : I {} class CallsBenchmarks { class B : A { func foo() -> Int { return 42 } } class C : A { func foo() -> Int { return 117 } } class D : A { func foo() -> Int { return 314 } } class X : A { func foo() -> Int { return 456456 } } class Y : A { func foo() -> Int { return -398473 } } class Z : A { func foo() -> Int { return 8298734 } } let d = D() let a1: A = B() let a2: A = C() lazy var a3: A = d lazy var i1: I = a1 lazy var i2: I = a2 lazy var i3: I = d let i4: I = X() let i5: I = Y() let i6: I = Z() func finalMethodCall() -> Int { var x = 0 let d = self.d for _ in 0.. Int { var x = 0 let a1 = self.a1 for _ in 0.. Int { var x = 0 let a1 = self.a1 let a2 = self.a2 for i in 0.. Int { var x = 0 let a1 = self.a1 let a2 = self.a2 let a3 = self.a3 for i in 0.. Int { var x = 0 let i1 = self.i1 for _ in 0.. Int { var x = 0 let i1 = self.i1 let i2 = self.i2 for i in 0.. Int { var x = 0 let i1 = self.i1 let i2 = self.i2 let i3 = self.i3 for i in 0.. Int { var x = 0 let i1 = self.i1 let i2 = self.i2 let i3 = self.i3 let i4 = self.i4 let i5 = self.i5 let i6 = self.i6 for i in 0.. Any { return 42 } } let e: E = F() func returnBoxUnboxFolding() -> Int { var x = 0 let e = self.e for _ in 0.. Int { var x = x if (c is C0) { x = x &+ i } if (c is C1) { x = x ^ i } if (c is C2) { x = x &+ i } if (c is C3) { x = x ^ i } if (c is C4) { x = x &+ i } if (c is C5) { x = x ^ i } if (c is C6) { x = x &+ i } if (c is C7) { x = x ^ i } if (c is C8) { x = x &+ i } if (c is C9) { x = x ^ i } return x } private func foo_iface(_ c: Any, _ x: Int, _ i: Int) -> Int { var x = x if (c is I0) { x = x &+ i } if (c is I1) { x = x ^ i } if (c is I2) { x = x &+ i } if (c is I3) { x = x ^ i } if (c is I4) { x = x &+ i } if (c is I5) { x = x ^ i } if (c is I6) { x = x &+ i } if (c is I7) { x = x ^ i } if (c is I8) { x = x &+ i } if (c is I9) { x = x ^ i } return x } func classCast() -> Int { let c0: Any = C0() let c1: Any = C1() let c2: Any = C2() let c3: Any = C3() let c4: Any = C4() let c5: Any = C5() let c6: Any = C6() let c7: Any = C7() let c8: Any = C8() let c9: Any = C9() var x = 0 for i in 0.. Int { let c0: Any = C0() let c1: Any = C1() let c2: Any = C2() let c3: Any = C3() let c4: Any = C4() let c5: Any = C5() let c6: Any = C6() let c7: Any = C7() let c8: Any = C8() let c9: Any = C9() var x = 0 for i in 0.. [Value] { return Array(data) } func copyManual() -> [Value] { var list: [Value] = [] for item in data { list.append(item) } return list } func filterAndCount() -> Int { return data.filter { filterLoad($0) }.count } func filterAndMap() -> [String] { return data.filter { filterLoad($0) }.map { mapLoad($0) } } func filterAndMapManual() -> [String] { var list: [String] = [] for it in data { if (filterLoad(it)) { let value = mapLoad(it) list.append(value) } } return list } func filter() -> [Value] { return data.filter { filterLoad($0) } } func filterManual() -> [Value] { var list: [Value] = [] for it in data { if (filterLoad(it)) { list.append(it) } } return list } func countFilteredManual() -> Int { var count = 0 for it in data { if (filterLoad(it)) { count += 1 } } return count } func countFiltered() -> Int { return data.count { filterLoad($0) } } func countFilteredLocal() -> Int { return data.cnt { filterLoad($0) } } } extension Collection { func count(where test: (Element) throws -> Bool) rethrows -> Int { return try self.filter(test).count } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ClassBaselineBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class ClassBaselineBenchmark { func consume() { for item in 1...Constants.BENCHMARK_SIZE { Blackhole.consume(Value(item)) } } func consumeField() { let value = Value(0) for item in 1...Constants.BENCHMARK_SIZE { value.value = item Blackhole.consume(value) } } func allocateList() -> [Value] { let list = [Value](repeating: Value(0), count: Constants.BENCHMARK_SIZE) return list } func allocateArray() -> [Value?] { let list = [Value?](repeating: nil, count: Constants.BENCHMARK_SIZE) return list } func allocateListAndFill() -> [Value] { var list: [Value] = [] for item in 1...Constants.BENCHMARK_SIZE { list.append(Value(item)) } return list } func allocateListAndWrite() -> [Value] { let value = Value(0) var list: [Value] = [] for _ in 1...Constants.BENCHMARK_SIZE { list.append(value) } return list } func allocateArrayAndFill() -> [Value?] { var list = [Value?](repeating: nil, count: Constants.BENCHMARK_SIZE) var index = 0 for item in 1...Constants.BENCHMARK_SIZE { list[index] = Value(item) index += 1 } return list } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ClassListBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class ClassListBenchmark { private var _data: [Value]? = nil var data: [Value] { return _data! } init() { var list: [Value] = [] for n in classValues(Constants.BENCHMARK_SIZE) { list.append(n) } _data = list } func filterAndCountWithLambda() -> Int { return data.filter { $0.value % 2 == 0 }.count } func filterWithLambda() -> [Value] { return data.filter { $0.value % 2 == 0 } } func mapWithLambda() -> [String] { return data.map { String($0.value) } } func countWithLambda() -> Int { return data.count { $0.value % 2 == 0 } } func filterAndMapWithLambda() -> [String] { return data.filter { $0.value % 2 == 0 }.map { String($0.value) } } func filterAndMapWithLambdaAsSequence() -> [String] { return data.lazy.filter { $0.value % 2 == 0 }.map { String($0.value) } } func reduce() -> Int { return data.reduce(0) { if (filterLoad($1)) { return $0 + 1 } else { return $0 }} } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ClassStreamBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class ClassStreamBenchmark { private var _data: AnySequence? = nil var data: AnySequence { return _data! } init() { _data = AnySequence(classValues(Constants.BENCHMARK_SIZE)) } func copy() -> [Value] { return Array(data) } func copyManual() -> [Value] { var list: [Value] = [] for item in data.lazy { list.append(item) } return list } func filterAndCount() -> Int { return data.lazy.filter { filterLoad($0) }.count } func filterAndMap() { for item in (data.lazy.filter { filterLoad($0) }.map { mapLoad($0) }) { Blackhole.consume(item) } } func filterAndMapManual() { for it in data.lazy { if (filterLoad(it)) { let item = mapLoad(it) Blackhole.consume(item) } } } func filter() { for item in (data.lazy.filter { filterLoad($0) }) { Blackhole.consume(item) } } func filterManual() { for it in data.lazy { if (filterLoad(it)) { Blackhole.consume(it) } } } func countFilteredManual() -> Int { var count = 0 for it in data.lazy { if (filterLoad(it)) { count += 1 } } return count } func reduce() -> Int { return data.lazy.reduce(0) {if (filterLoad($1)) { return $0 + 1 } else { return $0 }} } } ================================================ FILE: performance/KotlinVsSwift/ring/src/CompanionObjectBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class CompanionObjectBenchmark { func invokeRegularFunction() { CompanionObjectBenchmark.regularCompanionObjectFunction("") } static func regularCompanionObjectFunction(_ o: Any) -> Any { return o } } ================================================ FILE: performance/KotlinVsSwift/ring/src/CoordinatesSolver.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class CoordinatesSolverBenchmark { let solver: Solver init() { let inputValue = """ 12 5 3 25 3 9 3 9 1 3 13 3 12 6 10 10 12 2 10 10 9 2 9 5 6 12 5 0 2 10 10 14 12 5 3 9 5 2 10 10 8 1 3 9 4 0 3 14 10 10 12 0 4 6 9 6 12 5 6 10 11 12 3 9 6 9 5 3 9 6 8 5 6 8 3 12 7 10 10 11 12 3 13 6 12 3 9 6 12 2 13 4 5 5 5 6 12 5 5 2 1 """ let input = CoordinatesSolverBenchmark.readTillParsed(inputValue) solver = Solver(input!) } struct Coordinate: Equatable { let x: Int let y: Int } struct Field { let x: Int let y: Int let value: Int8 func northWall() -> Bool { return value & 1 != 0 } func eastWall() -> Bool { return value & 2 != 0 } func southWall() -> Bool { return value & 4 != 0 } func westWall() -> Bool { return value & 8 != 0 } func hasObject() -> Bool { return value & 16 != 0 } } struct Input { let labyrinth: Labyrinth let nObjects: Int } class Labyrinth { let width: Int let height: Int let fields: [Field] init(_ width: Int, _ height: Int, _ fields: Array) { self.width = width self.height = height self.fields = fields } func getField(_ x: Int, _ y: Int) -> Field { return fields[x + y * width] } } struct Output { let steps: [Coordinate?] } class InputParser { private var rows : [[Field]] = [] private var numObjects: Int = 0 private var input: Input { get { let width = rows[0].count var fields = [Field?](repeating: nil, count: width * rows.count) for y in rows.indices { let row = rows[y] for p in (y*width)..<(y*width + width) { fields[p] = row[p-y*width] } } let labyrinth = Labyrinth(width, rows.count, fields.filter { $0 != nil } as! Array) return Input(labyrinth: labyrinth, nObjects: numObjects) } } func feedLine(line: String) -> Input? { let items = line.split(separator: " ").filter { $0 != "" } if (items.count == 1) { numObjects = Int(items[0]) ?? 0 return input } else if (items.count > 0) { let rowNum = rows.count var row = [Field?](repeating: nil, count: items.count) for col in items.indices { row[col] = Field(x: rowNum, y: col, value: Int8(items[col]) ?? 0) } rows.append(row as! [CoordinatesSolverBenchmark.Field]) } return nil } } class Solver { private let input: Input init(_ input: Input) { self.input = input objects = [] for f in input.labyrinth.fields { if (f.hasObject()) { objects.append(Coordinate(x: f.x, y: f.y)) } } width = input.labyrinth.width height = input.labyrinth.height maze_end = Coordinate(x: width - 1, y: height - 1) } private var objects: [Coordinate] private let width: Int private let height: Int private let maze_end: Coordinate private var counter: Int64 = 0 func solve() -> Output { var steps = [Coordinate]() for o in objects.indices { var limit = input.labyrinth.width + input.labyrinth.height - 2 var ss: [Coordinate]? = nil while (ss == nil) { if (o == 0) { ss = solveWithLimit(limit, Solver.MAZE_START) { $0[$0.count - 1] == objects[0] } } else { ss = solveWithLimit(limit, objects[o - 1]) { $0[$0.count - 1] == objects[o] } } if (ss != nil) { steps.append(contentsOf: ss!) } limit += 1 } } var limit = input.labyrinth.width + input.labyrinth.height - 2 var ss: [Coordinate]? = nil while (ss == nil) { ss = solveWithLimit(limit, objects[objects.count - 1]) { $0[$0.count - 1] == maze_end } if (ss != nil) { steps.append(contentsOf: ss!) } limit += 1 } return createOutput(steps: steps) } private func createOutput(steps: [Coordinate]) -> Output { var objects : [Coordinate] = self.objects var outSteps : [Coordinate?] = [] for step in steps { outSteps.append(step) if (objects.contains(step)) { outSteps.append(nil) objects = objects.filter { $0 != step } } } return Output(steps: outSteps) } private func isValid(steps: [Coordinate]) -> Bool { counter += 1 let coords = steps[steps.count - 1] let x = coords.x let y = coords.y return (!(x == input.labyrinth.width - 1 && y == input.labyrinth.height - 1)) ? false : objects.filter{ steps.contains($0) == false }.count == 0 } private func getPossibleSteps(_ now: Coordinate, _ previous: Coordinate?) -> [Coordinate] { let field = input.labyrinth.getField(now.x, now.y) var possibleSteps: [Coordinate] = [] if (now.x != width - 1 && !field.eastWall()) { possibleSteps.append(Coordinate(x: now.x + 1, y: now.y)) } if (now.x != 0 && !field.westWall()) { possibleSteps.append(Coordinate(x: now.x - 1, y: now.y)) } if (now.y != 0 && !field.northWall()) { possibleSteps.append(Coordinate(x: now.x, y: now.y - 1)) } if (now.y != height - 1 && !field.southWall()) { possibleSteps.append(Coordinate(x: now.x, y: now.y + 1)) } if (!field.hasObject() && previous != nil) { possibleSteps = possibleSteps.filter { $0 != previous } } return possibleSteps } private func solveWithLimit(_ limit: Int, _ start: Coordinate, _ validFn: ([Coordinate]) -> Bool) -> [Coordinate]? { var steps: [Coordinate]? = findFirstLegitSteps(nil, start, limit) while (steps != nil && !validFn(steps!)) { steps = alter(start, nil, &steps!) } return steps } private func findFirstLegitSteps(_ startPrev: Coordinate?, _ start: Coordinate, _ num: Int) -> [Coordinate]? { var steps: [Coordinate]? = [] var i = 0 while (i < num) { let prev: Coordinate? let state: Coordinate if (i == 0) { state = start prev = startPrev } else if (i == 1) { state = steps![i - 1] prev = startPrev } else { state = steps![i - 1] prev = steps![i - 2] } let possibleSteps = getPossibleSteps(state, prev) if (possibleSteps.count == 0) { if (steps!.count == 0) { return nil } steps = alter(start, startPrev, &steps!) if (steps == nil) { return nil } i -= 1 i += 1 continue } let newStep = possibleSteps[0] steps!.append(newStep) i += 1 } return steps } private func alter(_ start: Coordinate, _ startPrev: Coordinate?, _ steps: inout [Coordinate]) -> [Coordinate]? { let size = steps.count var i = size - 1 while (i >= 0) { let current = steps[i] let prev = i == 0 ? start : steps[i - 1] let prevprev: Coordinate? if (i > 1) { prevprev = steps[i - 2] } else if (i == 1) { prevprev = start } else { prevprev = startPrev } let alternatives = getPossibleSteps(prev, prevprev) let index = alternatives.firstIndex(of: current) if (index != nil && index != alternatives.count - 1) { let newItem = alternatives[index! + 1] steps[i] = newItem let remainder = findFirstLegitSteps(prev, newItem, size - i - 1) if (remainder == nil) { i += 1 i -= 1 continue } Solver.removeAfterIndexExclusive(&steps, i) steps.append(contentsOf: remainder ?? []) return steps } else { if (i == 0) { return nil } } i -= 1 } return steps } private static let MAZE_START = Coordinate(x: 0, y: 0) private static func removeAfterIndexExclusive(_ list: inout [Coordinate], _ index: Int) { let rnum = list.count - 1 - index for _ in 0.. Input? { let parser = InputParser() var input: Input? = nil inputValue.split(separator: "\n").forEach { line in input = parser.feedLine(line: String(line)) } return input } func solve() { let output = solver.solve() for c in output.steps { let value = (c == nil) ? "felvesz" : "${c.x} ${c.y}" } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/Data.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation public class Value: Hashable { public func hash(into hasher: inout Hasher) { return value.hash(into: &hasher) } public static func == (lhs: Value, rhs: Value) -> Bool { return lhs.value == rhs.value } public var hashValue: Int { return value.hashValue } var value: Int init(_ value: Int) { self.value = value } lazy var text = String(String(value).reversed()) } public func intValues(_ size: Int) -> [Int] { return Array(1...size) } public func classValues(_ size: Int) -> [Value] { return intValues(size).map { Value($0) } } public func stringValues(_ size: Int) -> [String] { return intValues(size).map { String($0) } } public func filterLoad(_ v: Value) -> Bool { return v.text.contains(String(v.value)) } public func mapLoad(_ v: Value) -> String { return String(v.text.reversed()) } public func filterLoad(_ v: Int) -> Bool { return "0123456789".contains(String(v)) } public func mapLoad(_ v: Int) -> String { return String(v) } public func filterSome(_ v: Int) -> Bool { return v % 7 == 0 || v % 11 == 0 } public func filterPrime(_ v: Int) -> Bool { if (v <= 1) { return false } if (v <= 3) { return true } if (v % 2 == 0) { return false } var i = 3 while (i*i <= v) { if (v % i == 0) { return false } i += 2 } return true } extension Array where Element: Value { @inlinable func cnt(predicate: (Value) -> Bool) -> Int { var count = 0 for element in self { if (predicate(element)) { count += 1 } } return count } } extension Array where Element == Int { @inlinable func cnt(predicate: (Int) -> Bool) -> Int { var count = 0 for element in self { if (predicate(element)) { count += 1 } } return count } } extension Sequence where Element == Int { @inlinable func cnt(predicate: (Int) -> Bool) -> Int { var count = 0 for element in self { if (predicate(element)) { count += 1 } } return count } } ================================================ FILE: performance/KotlinVsSwift/ring/src/DefaultArgumentBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class DefaultArgumentBenchmark { private var arg = 0 init() { arg = Int.random(in: 0...100) } func sumTwo(_ first: Int, _ second: Int = 0) -> Int { return first + second } func sumFour(_ first: Int, _ second: Int = 0, _ third: Int = 1, _ fourth: Int = 1) -> Int { return first + second + third + fourth } func sumEight(_ first: Int, _ second: Int = 0, _ third: Int = 1, _ fourth: Int = 1, _ fifth: Int = 1, _ sixth: Int = 1, _ seventh: Int = 1, _ eighth: Int = 1) -> Int { return first + second + third + fourth + fifth + sixth + seventh + eighth } func testOneOfTwo() { sumTwo(arg) } func testTwoOfTwo() { sumTwo(arg, arg) } func testOneOfFour() { sumFour(arg) } func testFourOfFour() { sumFour(arg, arg, arg, arg) } func testOneOfEight() { sumEight(arg) } func testEightOfEight() { sumEight(arg, arg, arg, arg, arg, arg, arg, arg) } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ElvisBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class ElvisBenchmark { class Value { var value: Int init(_ value: Int) { self.value = value } } var array : [Value?] = [] init() { array = (0 ..< Constants.BENCHMARK_SIZE).map { _ in if (Int.random(in: 0...Constants.BENCHMARK_SIZE) < Constants.BENCHMARK_SIZE / 10) { return nil } else { return Value(Int.random(in: 0...100)) } } } func testElvis() { for obj in array { Blackhole.consume(obj?.value ?? 0) } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/EulerBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation struct FibonacciGenerator: Sequence, IteratorProtocol { var a = 0 var b = 1 var current = 1 mutating func next() -> Int? { defer { current = a + b a = b b = current } return current } } extension Int64 { func isPalindrome() -> Bool { return String(self) == String(String(self).reversed()) } } extension Range where Bound == Int { @inlinable func sum(_ predicate: (Int) -> Bool) -> Int { var sum = 0 for i in self { if (predicate(i)) { sum += i } } return sum } } extension Sequence where Element == Int { @inlinable func sum(_ predicate: (Int) -> Bool) -> Int { var sum = 0 for i in self { if (predicate(i)) { sum += i } } return sum } } extension Sequence { func takeWhile(condition: (Element) -> Bool) -> [Element] { var result: [Element] = [] for x in self { guard condition(x) else { break } result.append(x) } return result } } class EulerBenchmark { func problem1bySequence() -> Int { return AnySequence(1...Constants.BENCHMARK_SIZE).lazy.sum( { $0 % 3 == 0 || $0 % 5 == 0} ) } func problem1() -> Int { return (1...Constants.BENCHMARK_SIZE).sum( { $0 % 3 == 0 || $0 % 5 == 0} ) } func problem2() -> Int { return FibonacciGenerator().takeWhile { $0 < Constants.BENCHMARK_SIZE }.sum { $0 % 2 == 0 } } func problem4() -> Int64 { let s: Int64 = Int64(Constants.BENCHMARK_SIZE) let maxLimit = (s-1)*(s-1) let minLimit = (s/10)*(s/10) let maxDiv = Constants.BENCHMARK_SIZE-1 let minDiv = Constants.BENCHMARK_SIZE/10 for i in stride(from: maxLimit, through: minLimit, by: -1) { if (!i.isPalindrome()) { continue } for j in minDiv...maxDiv { if (i % Int64(j) == 0) { let res = i / Int64(j) if ((Int64(minDiv)...Int64(maxDiv)).contains(res)) { return i } } } } return -1 } private let veryLongNumber = """ 73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 62229893423380308135336276614282806444486645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 82166370484403199890008895243450658541227588666881 16427171479924442928230863465674813919123162824586 17866458359124566529476545682848912883142607690042 24219022671055626321111109370544217506941658960408 07198403850962455444362981230987879927244284909188 84580156166097919133875499200524063689912560717606 05886116467109405077541002256983155200055935729725 71636269561882670428252483600823257530420752963450 """ func problem8() -> Int64 { var productSize = 13 if ((1...10).contains(Constants.BENCHMARK_SIZE)) { productSize = 4 } else if ((11...1000).contains(Constants.BENCHMARK_SIZE)) { productSize = 8 } var digits: [Int] = [] for digit in veryLongNumber { if (("0"..."9").contains(digit)) { if let number = Int(String(digit)) { if let secNumber = Int(String("0")) { digits.append(number - secNumber) } } } } var largest: Int64 = 0 for i in 0...digits.count - productSize - 1 { var product: Int64 = 1 for j in 0...productSize-1 { product *= Int64(digits[i+j]) } if (product > largest) { largest = product } } return largest } func problem9() -> Int64 { for c in Constants.BENCHMARK_SIZE/3...Constants.BENCHMARK_SIZE-3 { let c2 = Int64(c) * Int64(c) for b in (Constants.BENCHMARK_SIZE-c)/2..= Constants.BENCHMARK_SIZE) { break } let a = Constants.BENCHMARK_SIZE - b - c if (a >= b) { continue } let b2 = Int64(b) * Int64(b) let a2 = Int64(a) * Int64(a) if (c2 == b2 + a2) { return Int64(a) * Int64(b) * Int64(c) } } } return -1 } class Children { let left: Int let right: Int init(_ left: Int, _ right: Int) { self.left = left self.right = right } } func problem14() -> [Int] { // Build a tree // index is produced from first & second let tree = (0..4 && (i+2) % 6 == 0) ? (i-1)/3 : 0)} // Find longest chain by DFS func dfs(_ begin: Int) -> [Int] { if (begin == 0 || begin >= Constants.BENCHMARK_SIZE) { return [] } let left = dfs(tree[begin].left) let right = dfs(tree[begin].right) return [begin] + ((left.count > right.count) ? left : right) } return dfs(1) } class Way { let length: Int let next: Int init(_ length: Int, _ next: Int) { self.length = length self.next = next } } func problem14full() -> [Int] { var map: [Int: Way] = [:] // Starting point map[1] = Way(0, 0) // Check all other numbers var bestNum = 0 var bestLen = 0 func go(_ begin: Int) -> Way { let res = map[begin] if (res != nil) { return res! } let next = (begin % 2 == 0) ? begin/2 : 3*begin+1 let childRes = go(next) let myRes = Way(childRes.length + 1, next) map[begin] = myRes return myRes } for i in 2...Constants.BENCHMARK_SIZE-1 { let res = go(i) if (res.length > bestLen) { bestLen = res.length bestNum = i } } func unroll(_ begin: Int) -> [Int] { if (begin == 0) { return [] } let next = map[begin]?.next ?? 0 return [begin] + unroll(next) } return unroll(bestNum) } } ================================================ FILE: performance/KotlinVsSwift/ring/src/FibonacciBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class FibonacciBenchmark { func calcClassic() -> Int64 { var a: Int64 = 1 var b: Int64 = 2 let size = Constants.BENCHMARK_SIZE for _ in 0...size-1 { let next = a &+ b a = b b = next } return b } func calc() -> Int64 { var a: Int64 = 1 var b: Int64 = 2 for _ in stride(from: Constants.BENCHMARK_SIZE, through: 1, by: -1) { let next = a &+ b a = b b = next } return b } func calcWithProgression() -> Int64 { var a: Int64 = 1 var b: Int64 = 2 for _ in stride(from: 1, through: 2*Constants.BENCHMARK_SIZE-1, by: 2) { let next = a &+ b a = b b = next } return b } func calcSquare() -> Int64 { var a: Int64 = 1 var b: Int64 = 2 let s = Int64(Constants.BENCHMARK_SIZE) let limit = s*s for _ in stride(from: limit, through: 1, by: -1) { let next = a &+ b a = b b = next } return b } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ForLoopsBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class ForLoopsBenchmark { private let array: [Int] = (1...Constants.BENCHMARK_SIZE).map { $0 } private let charArray: [Character] = (1...Constants.BENCHMARK_SIZE).map { Character(UnicodeScalar($0) ?? "0") } private lazy var string: String = String(charArray) private let floatArray: [Float] = (1...Constants.BENCHMARK_SIZE).map { Float($0) } func arrayLoop() -> Int64 { var sum: Int64 = 0 for e in array { sum += Int64(e) } return sum } func charArrayLoop() -> Int64 { var sum : Int64 = 0 for e in charArray { sum += Int64(String(e)) ?? 0 } return sum } func stringLoop() -> Int64 { var sum: Int64 = 0 for e in string { sum = sum &+ (Int64(String(e)) ?? 0) } return sum } func floatArrayLoop() -> Double { var sum = 0.0 for e in floatArray { sum += Double(e) } return sum } func arrayIndicesLoop() -> Int64 { var sum = 0 for i in array.indices { sum += array[i] } return Int64(sum) } func charArrayIndicesLoop() -> Int64 { var sum: Int64 = 0 for i in charArray.indices { sum += Int64(String(charArray[i])) ?? 0 } return sum } func stringIndicesLoop() -> Int64 { var sum: Int64 = 0 for i in string.indices { sum = sum &+ Int64(string[i].hashValue) } return sum } func floatArrayIndicesLoop() -> Double { var sum = 0.0 for i in floatArray.indices { sum += Double(floatArray[i]) } return sum } } ================================================ FILE: performance/KotlinVsSwift/ring/src/GraphSolverBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation private class Graph { var nodes: [Node] = [] var size: Int { get { return nodes.count } } func first() -> Node { nodes.first! } subscript(nodeId: Int) -> Node { get { if (!nodes.indices.contains(nodeId)) { nodes.insert(Node(nodeId), at: nodeId) } return nodes[nodeId] } } } private class Node: Hashable { static func == (lhs: Node, rhs: Node) -> Bool { return lhs.id == rhs.id } let id: Int var neighbors: [Node:Int] = [:] init(_ id: Int) { self.id = id } public func hash(into hasher: inout Hasher) { return id.hash(into: &hasher) } public var hashValue: Int { var hasher = Hasher() self.hash(into: &hasher) return hasher.finalize() } } extension String { func blank() -> Bool { let trimmed = self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) return trimmed.isEmpty } } private func addNeighbors(_ line: String, _ graph: Graph, _ lineNumber: Int) -> Node { let node = graph[lineNumber] for (index, value) in line.split(separator: ",").enumerated() { node.neighbors[graph[index]] = Int(value.trimmingCharacters(in: .whitespacesAndNewlines)) } return node } private func parseData(_ content: [String]) -> Graph { let graph = Graph() for (lineNumber, line) in (content.filter { !$0.blank() }).enumerated() { addNeighbors(line, graph, lineNumber) } return graph } private struct ClosestNode { let node: Node let distance: Int } class Greedy { private let graph: Graph private var visitedNodes = Set() fileprivate init(_ graph: Graph) { self.graph = graph } private func getClosest(_ node: Node) -> ClosestNode? { let nodes = node.neighbors.filter { $0.value != 0 && !visitedNodes.contains($0.key)} let closest = nodes.min { a,b in a.value < b.value }! return ClosestNode(node: closest.key, distance: closest.value) } func solve() { var previousNode = graph.first() visitedNodes.insert(graph.first()) var cost = 0 while (visitedNodes.count != graph.size) { let closest = getClosest(previousNode)! visitedNodes.insert(closest.node) cost += closest.distance previousNode = closest.node } cost += (Array(visitedNodes).last?.neighbors[graph.first()]!)! } } class GraphSolverBenchmark { let content = [ "0,604,802,57,278,84,33,758,908,420,610,484,195,474,254,969,172,463,130,335,704,507,358,852,356,444,396,95,446,86,397,893,56,812,967,40,229,33,112,913,548,902,793,563,318,311,579,58,145,304,133,440,159,219,300,855,443,385,157,770,29,97,229,734,829,324,917,380,817,597,461,386,536,942,533,774,71,996,752,6,741,644,701,782,870,947,159,464,412,807,765,174,334,77,930,536,885,533,202,191,825,342,578,76,394,432,786,313,693,587,659,55,491,467,33,955,883,353,452,60,588,87,109,473,66,965,973,950,952,492,624,810,87,62,218,435,559,283,562,798,349,201,383,249,69,263,415,961,56,755,616,27,186,63,247,800,503,767,869,13,252,746,6,436,793,189,926,442,465,225,573,379,875,620,294,452,832,739,354,781,348,264,790,110,369,393,678,873,8,708,268,177,722,49,448,849,381,720,166,208,178,634,557,595,969,968,384,682,558,298,726,899,444,420,481,714,524,633,897,279,760,755,101,37,769,460,252,869,700,182,507,389,263,88,291,885,106,638,375,661,375,941,487,58,890,700,121,852,700,888,814,546,374,771,683,730,478,446,456,447,369,727,258,307,794,669,438,604,549,921,848,918,694,512,390,913,118,776,441,438,488,187,813,668,373,522,411,772,943,183,6,84,984,619,453,729,744,166,880,800,860,869,805,873,296,706,901,155,111,286,958,119,652,2,140,248,809,475,752,368,924,108,276,472,469,704,92,680,374,473,372,607,251,454,718,228,252,116,812,561,49,248,826,682,598,900,239,652,367,293,196,868,18,555,746,142,170,75,788,675,661,697,632,185,283,838,509,843,222,690,783,963,550,621,211,276,133,303,695,211,957,685,686,98,902,725,707,758,194,461,411,177,912,818,92,512,480,795,586,161,962,546,891,223,476,937,669,938,516,247,668,751,195,678,848,764,888,40,291,456,710,685,129,637,876,293,194,102,153,903,414,766,368,31,561,537,962,873,902,529,362,225,936,743,782,307,217,300,921,699,664,638,862,170,916,806,721,100,395,800,244,50,746,500,962,753,547,889,199,743,611,357,952,781,899,548,507,875,434,702,109,32,835,788,108,469,171,993,886,130,871,752,217,896,446,66,223,648,352,497,782,182,463,557,20,849,685,956,834,676,28,533,256,904,606,334,472,206,942,166,38,203,953,201,566,409,64,833,958,784,852,817,835,829,911,254,917,706,681,35,456,795,615,349,597,198,643,18,955,531,431,49,80,699,35,345,830,687,406,605,872,293,697,348,296,472,951,117,464,843,96,359,945,388,226,338,41,429,367,940,474,477,978,867,975,632,388,319,999,409,145,748,136,226,853,21,620,89,319,557,602,206,759,638,977,499,723,381,223,299,298,981,642,100,95,828,794,689,778,983,201,195,905,670,313,555,762,962,212,311,572,852,657,622,461,101,771,644,925,761,286,275,297,246,904,24,327,474,455,395,148,330,919,710,485,709,341,871,669,27,5,643,840,999,940,489,803,164,806,187,989,178,257,835,516,172,594,661,77,28,961,222,953,604,611,111,296,784,967,175,448,130,611,998,669,350,234,272,149,714,942,501,378,192,28,891,694,37,788,495,961,770,736,207,903,664,21,345,480,604,451,271,99,81,131,902,314,436,979,634,63,164,849,736,283,210,5,131,117,978,379,488,392,649,951,927,757,835,567,472,530,589,959,213,74,904,270,677,787,884,287,569,182,11,604,384,440,914,286,110,760,639,284,3,523,275,968,342,759,765,907,624,468,674,891,81,205,226,907,158,473,622,67,981,858,790,268,176,998,811,987,130,307,735,414,822,625,147,210,875,778,175,388,671,762,352,550,496,82,985,340,915,946,803,441,822,142,297,409,773,356,890,170,201,815,931,486,626,223,290,722,178,39,873,601,741,88,690,295,272,189,397,631,546,178,718,124,397,234,251,503,64,990,295,733,948,449,540,728,801,351,2,553,75,595,907,299,469,258,40,524,845,281,892,64,50,994,630,380,785,60,341,278,468,828,213,711,17,190,952,370,464,291,918,454,239,399,914,451,281,720,215,62,962,8,208,617,285,391,544,521,254,215,559,184,805,737,774,661,784,206,345,994,238,979,394,685,131,822,717,397,715,607,502,400,937,653,653,352,619,733,275,753,257,766,839,814,308,402,528,912,260,754,367,8,301,917,351,988,696,570,416,444,784,581,829,870,378,368,224,956,237,86,648,448,10,856,196,146,484,229,344,870,673,738,250,949,264,995,873", "604,0,40,254,413,440,450,189,382,388,460,802,266,415,70,10,137,344,215,456,530,796,664,686,149,440,863,46,325,418,304,904,295,948,626,722,167,27,396,183,396,822,81,117,114,950,786,101,888,750,550,293,584,254,732,694,278,971,813,730,589,978,214,629,781,358,941,962,144,609,629,25,779,492,412,778,302,220,159,617,673,703,602,256,997,805,922,332,116,639,333,384,526,980,764,929,183,987,806,519,293,758,992,261,587,366,154,544,480,983,148,855,372,746,876,207,833,719,607,546,124,719,555,154,264,486,643,437,828,729,571,950,71,908,63,125,560,335,612,16,296,884,446,530,622,121,742,378,816,616,307,115,492,646,831,308,254,860,338,739,614,918,21,493,370,512,817,584,872,221,184,321,218,878,919,841,327,320,949,838,138,537,868,329,759,923,496,960,488,452,407,844,390,619,477,822,968,17,632,471,639,273,142,763,708,694,395,53,976,778,842,967,875,668,980,367,48,424,692,958,223,374,929,828,450,465,411,75,199,145,705,227,66,620,982,33,317,925,780,598,712,29,191,650,287,301,735,765,117,501,324,264,10,538,808,114,389,563,375,421,267,265,554,862,609,244,662,714,194,853,788,359,355,944,781,907,520,52,669,597,292,269,463,378,64,452,672,474,660,455,32,871,305,571,646,477,890,624,850,69,155,897,498,813,295,719,696,381,341,877,30,213,227,394,332,421,924,385,405,407,486,681,293,515,590,497,657,130,680,535,881,478,474,541,522,135,163,180,442,380,478,682,218,350,355,533,870,515,757,740,73,837,600,762,337,555,950,316,235,236,786,502,476,804,44,717,793,688,246,854,85,476,243,513,895,569,29,561,528,525,333,986,829,680,587,336,182,909,196,614,118,198,700,94,100,29,381,933,46,32,920,646,46,482,479,588,596,263,550,902,261,326,272,780,568,295,597,704,46,768,76,731,369,25,421,622,846,756,686,176,583,435,364,415,614,571,145,888,999,235,727,913,128,904,57,300,25,764,822,924,415,526,689,858,224,381,526,607,119,646,544,202,365,277,556,681,668,350,496,113,14,914,813,974,528,389,490,491,550,983,812,652,170,618,665,439,966,386,512,521,589,218,481,288,995,791,791,674,582,593,29,787,687,878,640,11,883,827,723,884,670,129,831,500,422,196,936,719,10,736,641,227,538,609,954,84,304,961,667,781,137,842,79,937,810,56,179,335,760,197,991,995,876,5,342,379,132,231,783,59,459,932,907,612,40,138,857,958,614,164,338,5,467,894,513,352,630,460,511,179,419,826,155,584,448,16,82,909,104,608,900,971,763,98,464,955,314,12,618,150,252,880,429,309,539,687,681,883,888,13,931,804,158,451,768,954,695,751,230,61,834,940,156,410,734,599,444,399,956,210,290,117,878,725,758,453,652,41,207,144,162,46,689,775,318,311,247,748,318,828,500,276,191,218,503,751,994,171,530,884,538,653,69,728,14,905,147,88,291,192,669,742,260,206,152,419,84,814,656,236,262,476,806,589,155,935,197,623,546,492,794,179,487,555,710,215,94,707,326,469,456,186,82,830,22,865,589,375,312,626,550,221,670,295,353,690,167,99,370,833,642,437,746,565,23,956,830,266,866,792,56,337,424,136,669,2,568,584,294,362,421,304,621,582,439,825,45,208,249,63,468,764,594,90,745,7,24,252,528,973,117,290,548,202,264,831,235,162,683,648,530,873,286,333,221,223,95,665,884,235,8,839,225,756,840,748,901,385,514,720,113,972,196,509,601,160,133,350,444,846,464,507,733,303,597,568,640,328,932,520,288,663,519,741,115,152,722,948,318,60,973,239,488,813,322,616,336,241,957,892,196,691,424,249,932,603,677,122,731,939,960,571,430,280,976,144,894,356,855,794,830,721,988,887,318,723,560,688,644,44,946,988,512,979,431,640,688,805,386,809,863,329,152,131,603,77,781,325,321,501,876,240,152,734,13,707,607,375,159,446,415,422,808,798,299,683,47,260,871,344,638,799,881,997,342,572,487,984,96,757,77,843,367,32,840,777,640,38,541,59,160,765,92,32,56,662,451,449,517,476,672,902,22,352,970,140,513,198,595,85,601,341,719,608,663,861,509,621,813,37,195,915,662,284,749,33,812,480,949,133,947,204,246,782,244,810,48,661,585,135,99,321,450,513,70,896,564,677,490,703,977,243,630,613,262,721,100,807,17,24,534,892,626,618,59,640,908,996,874,212,342,778,657,755,777,470,233,547,913,804", "802,40,0,321,721,986,467,509,781,544,43,803,544,354,937,252,687,373,142,628,327,167,769,538,459,857,820,971,750,652,904,223,132,909,607,679,461,628,781,698,361,121,216,819,304,475,74,324,59,349,120,555,62,299,840,451,353,402,539,565,562,424,973,187,553,859,381,51,696,343,79,63,286,499,302,842,682,896,576,942,68,454,786,497,517,255,417,518,417,523,896,784,55,673,417,665,893,870,4,795,396,418,483,566,132,985,566,605,837,448,985,334,36,409,227,428,625,275,207,176,190,881,447,530,458,382,466,65,16,85,21,223,921,353,134,593,511,430,516,646,640,294,623,203,717,762,715,496,442,11,113,751,888,803,934,210,870,900,656,780,679,147,201,135,932,785,923,240,390,636,534,846,415,993,977,910,132,949,7,624,684,720,651,556,534,661,852,457,259,348,990,365,284,260,652,788,918,689,104,967,837,653,656,465,154,321,722,553,402,768,262,257,941,118,51,170,229,865,45,982,109,575,320,879,331,990,887,921,368,294,743,78,415,23,434,618,22,574,692,953,154,656,121,543,160,848,724,366,765,598,880,5,389,660,481,221,771,398,304,816,918,372,353,586,487,698,386,823,849,784,78,850,855,107,868,269,162,197,338,314,996,294,133,874,638,314,711,534,132,564,482,430,564,128,996,185,345,714,848,217,648,244,67,94,26,492,982,336,300,246,275,61,888,197,978,191,448,747,975,182,972,469,986,770,12,700,977,216,324,839,723,259,101,875,823,242,809,249,681,417,257,492,881,511,86,105,262,641,977,257,182,126,672,693,864,252,424,351,634,190,90,507,122,398,763,207,252,209,561,354,206,829,537,510,279,277,316,143,32,948,772,901,538,930,299,181,886,162,473,446,210,8,431,161,747,529,206,568,758,752,346,738,131,601,827,22,448,216,892,617,622,39,447,898,759,749,103,341,435,900,113,994,760,96,410,175,731,591,318,731,431,338,476,193,735,106,716,479,344,571,294,498,719,921,571,881,136,929,603,541,608,192,118,36,921,715,831,958,774,933,473,588,207,107,864,34,556,490,890,874,642,256,945,701,214,45,937,929,415,221,6,666,263,1,314,643,299,857,539,210,559,670,477,766,400,17,869,915,361,882,934,471,397,92,714,569,886,133,47,370,801,455,849,326,32,329,750,458,445,665,420,613,596,755,870,406,727,935,530,366,822,203,704,449,665,158,322,293,927,98,165,409,238,94,442,877,445,266,706,312,712,321,65,914,962,71,172,795,973,430,355,969,510,610,957,696,505,533,884,754,968,998,994,214,388,509,980,622,353,233,496,178,988,344,445,890,50,376,620,766,552,98,392,700,723,753,83,245,967,253,563,736,880,519,76,3,624,102,254,8,574,804,798,832,883,137,694,608,28,318,326,928,330,987,173,553,181,402,156,163,331,587,771,204,607,979,404,137,688,572,967,206,595,5,895,787,47,844,458,451,269,716,260,849,592,462,850,840,359,296,830,724,101,730,795,997,795,415,475,851,274,953,899,29,442,830,374,754,622,73,622,190,271,412,275,427,398,206,953,138,198,947,234,745,669,47,270,799,300,67,102,566,502,796,11,186,127,426,656,576,398,723,266,895,899,439,509,1000,517,991,77,617,659,695,334,797,375,721,220,739,464,67,62,396,530,888,346,67,264,744,772,726,838,590,964,760,201,16,9,160,868,124,267,460,928,316,325,173,52,820,394,410,759,46,246,275,400,664,787,817,860,333,452,897,618,760,943,24,834,426,894,126,413,484,412,769,301,349,973,720,343,210,915,640,221,94,937,576,995,751,235,914,855,548,434,415,280,83,405,104,197,213,852,907,357,4,99,969,116,474,421,86,950,62,216,409,559,488,511,618,766,232,239,591,556,351,839,689,387,944,336,262,156,978,879,623,634,258,805,64,603,919,87,809,605,36,197,183,639,333,991,644,570,761,180,673,802,137,78,680,825,283,630,661,843,964,443,945,868,455,470,458,710,493,378,467,194,984,178,44,765,755,523,121,834,711,136,668,888,467,799,429,25,817,322,339,141,662,560,647,840,462,761,410,764,177,39,138,974,919,138,965,727,270,191,780,59,213,694,381,534,970,20,39,952,195,784,683,218,146,915,520,335,561,873,916,478,11,470,583,601,973,266,88,141,299,916,97,951,306,220,434,419,183,307,287,216,258,162,249,210,135,677,290,752,535,984,861,840,436,14,529,762,746,944,873,838,795,296,199,149,675,941,533,422,227,581,470,328,976", "57,254,321,0,726,976,877,679,555,918,259,522,153,491,650,419,377,449,295,813,575,548,550,571,135,708,85,803,595,15,973,375,674,439,832,866,244,950,993,821,818,906,58,492,863,955,503,775,396,520,652,572,404,747,304,949,222,7,383,658,89,188,122,919,600,45,473,37,105,517,619,545,30,163,866,785,54,219,573,636,635,557,930,80,595,94,675,781,143,384,363,838,109,41,294,160,950,754,224,659,377,26,517,74,503,784,953,482,526,469,13,183,732,180,775,752,408,597,866,425,684,790,475,48,839,592,379,950,990,980,716,332,189,908,819,65,555,158,438,681,78,447,931,721,183,377,333,839,570,636,296,301,947,552,920,443,592,793,781,277,326,971,673,208,83,916,373,413,642,157,212,366,680,482,876,431,961,307,10,286,188,982,970,237,614,274,50,808,973,66,918,456,370,723,118,301,412,789,988,80,886,457,333,603,737,985,546,479,222,881,247,954,128,478,249,511,378,363,108,577,932,170,241,733,500,357,200,713,503,588,513,833,440,189,241,10,210,56,331,982,572,675,525,801,546,827,99,741,130,337,869,743,702,585,401,725,478,889,796,244,310,251,484,862,94,179,486,991,626,301,855,974,793,135,183,768,746,162,3,73,810,559,822,836,74,250,739,982,336,284,604,411,974,808,349,808,688,280,743,824,396,664,467,751,156,576,183,930,471,667,564,731,900,938,249,300,542,745,24,119,41,486,869,298,149,310,350,146,568,159,209,243,164,575,305,881,528,618,755,484,103,720,541,355,467,478,787,937,241,812,835,148,453,881,774,126,782,884,518,356,981,248,862,177,472,490,194,179,788,663,855,673,728,479,937,890,328,961,91,311,494,25,587,780,924,897,532,749,460,8,857,632,316,271,872,797,99,729,76,585,832,837,838,4,777,300,30,78,656,867,583,57,407,584,442,766,895,420,238,492,552,379,572,399,353,828,763,588,735,331,837,551,855,570,15,700,400,897,800,53,800,860,105,1,616,56,840,279,360,881,322,51,34,810,143,908,482,932,521,535,174,560,208,277,693,95,928,461,747,762,718,635,225,458,617,128,272,463,260,74,531,726,822,622,831,442,410,74,411,459,89,577,969,74,672,930,663,387,973,674,275,791,723,360,238,270,588,401,704,258,575,407,823,406,50,451,566,20,547,237,307,430,331,176,121,682,696,25,379,450,458,28,899,169,627,879,97,84,702,720,820,766,328,198,794,41,970,978,175,847,324,706,885,931,724,124,423,731,15,553,949,79,979,134,926,103,578,97,905,866,443,885,11,984,698,613,689,931,623,390,532,752,456,497,438,363,701,198,900,928,344,688,842,506,946,19,933,650,97,166,439,746,837,697,444,208,346,711,674,198,784,184,159,845,876,87,817,726,301,895,295,810,239,528,531,733,988,941,654,334,9,294,441,194,902,117,969,201,451,589,106,322,482,542,746,391,529,74,858,355,46,530,200,344,955,789,221,131,555,217,275,964,137,204,388,96,121,329,156,488,645,398,23,214,709,875,129,491,668,139,276,678,673,94,764,731,778,196,10,87,3,644,914,500,643,579,508,878,52,830,363,921,839,113,129,710,623,992,97,807,906,592,985,349,872,383,83,351,431,323,391,359,930,967,986,306,796,625,65,379,201,693,135,814,498,358,847,895,906,570,936,826,397,333,62,296,431,960,424,916,47,52,69,164,479,380,496,455,615,750,957,397,293,645,50,469,67,923,552,198,698,698,741,676,831,92,846,775,142,839,268,538,803,695,765,125,263,627,877,119,195,596,480,138,858,596,439,930,922,316,917,751,203,557,26,735,95,549,702,424,479,674,86,978,189,763,34,950,927,895,947,759,83,330,348,651,773,914,494,387,644,66,219,333,87,427,163,279,443,445,189,148,665,866,855,267,417,553,94,423,992,97,737,177,97,858,890,591,23,84,945,621,755,459,536,719,128,992,591,861,91,261,411,717,702,901,488,350,620,526,733,350,364,31,590,971,381,803,419,488,319,131,741,671,756,970,751,675,855,933,133,489,195,268,776,634,871,454,976,605,380,868,472,410,549,277,392,907,893,987,408,739,799,175,752,288,861,39,40,346,963,861,481,800,907,122,455,8,770,153,338,773,13,374,709,839,956,600,429,600,92,276,650,489,804,157,259,655,193,882,169,220,309,887,270,963,648,658,221,396,15,324,725,825,479,418,240,353,110,219,78,229,348,141,223,37,50,312,367,307,885,215,565,658,738,191,136,994,706,299", "278,413,721,726,0,584,44,514,846,58,260,489,486,66,420,805,805,115,978,230,125,277,219,921,253,211,368,206,811,700,708,271,620,26,885,289,859,190,731,963,186,586,52,700,83,981,733,396,915,102,122,905,891,296,198,736,352,527,836,911,443,87,176,376,531,656,959,381,929,609,312,81,1000,453,659,936,930,252,904,894,70,352,793,354,862,234,644,180,361,702,792,312,448,312,410,924,337,720,907,222,319,153,584,855,512,917,630,916,484,362,926,942,653,37,484,416,381,553,441,433,689,677,393,767,8,904,387,965,540,463,362,112,154,430,25,850,374,206,544,833,198,844,658,692,135,85,377,546,260,736,21,40,309,74,164,250,183,886,464,540,586,85,769,967,781,41,271,412,854,961,528,724,947,269,7,530,363,253,495,230,683,634,851,906,983,610,966,563,165,217,116,528,285,413,431,736,366,235,90,514,739,357,806,963,754,213,427,819,981,661,158,123,21,946,140,526,149,85,254,710,100,317,239,471,217,966,557,263,433,940,597,706,38,330,856,790,509,460,143,434,493,332,536,989,647,96,247,695,888,276,684,916,343,55,767,754,289,190,185,906,463,10,235,374,696,742,176,98,799,394,334,620,956,45,119,527,444,102,62,169,396,806,906,889,931,706,303,468,620,208,428,374,89,572,288,456,506,667,725,392,37,641,545,137,495,653,317,90,734,473,599,566,508,383,727,957,237,607,595,683,954,325,619,544,66,607,614,236,324,201,96,373,275,738,567,516,698,89,387,14,354,780,507,305,462,897,623,397,247,241,442,888,513,754,614,277,764,716,100,162,636,592,792,827,181,620,758,118,311,525,676,765,933,298,257,668,939,971,661,4,853,257,935,245,552,766,465,922,650,824,706,553,75,185,901,342,892,859,356,312,803,982,221,565,799,161,557,185,453,164,931,35,304,724,451,305,491,572,297,716,348,606,789,268,887,224,574,308,86,348,942,839,86,52,523,396,839,841,707,919,348,140,44,526,636,479,5,507,903,582,708,988,190,983,55,243,621,141,25,64,537,171,714,685,820,43,323,800,535,249,92,178,146,125,77,374,432,388,758,158,121,868,961,959,641,370,164,925,454,333,458,739,15,856,35,467,465,404,29,956,215,265,533,307,424,501,166,501,87,268,363,134,415,175,483,103,983,327,45,527,311,248,973,862,683,951,91,681,381,923,869,307,21,469,992,196,617,598,60,70,57,62,893,315,76,635,477,538,938,757,911,414,700,648,266,682,578,597,447,734,570,236,559,417,419,971,269,858,28,151,504,236,19,941,499,760,963,163,332,910,877,116,41,128,146,582,11,573,432,919,207,846,584,704,118,44,731,780,416,806,885,332,663,999,915,174,549,545,430,738,797,127,576,100,980,867,204,620,287,178,803,153,696,80,791,526,923,824,658,602,86,332,104,689,959,217,466,184,313,774,735,829,644,115,935,807,283,48,38,796,924,559,160,206,490,866,432,511,231,445,841,657,468,723,124,940,212,387,855,65,382,504,586,70,704,459,831,492,220,308,770,832,239,828,764,273,149,191,607,382,895,187,513,554,997,630,52,938,264,872,260,187,911,918,541,328,517,743,975,485,967,608,24,647,760,861,226,362,600,681,528,416,971,781,46,230,837,541,235,391,594,274,263,372,648,593,792,626,755,535,235,739,8,808,65,759,13,59,364,50,485,393,960,972,970,967,711,876,786,423,412,254,107,395,785,784,220,876,21,6,904,304,305,809,359,276,533,921,150,496,606,147,111,541,85,646,710,749,708,357,354,33,80,28,356,181,864,889,143,916,455,731,655,620,704,544,462,593,295,507,389,530,650,938,349,42,308,910,587,124,492,893,574,341,652,447,701,258,565,510,804,90,290,221,926,273,147,725,871,507,777,462,209,996,989,491,232,39,221,962,152,667,200,311,195,652,81,95,307,739,685,403,955,525,289,474,172,634,987,30,171,900,638,276,703,265,664,944,563,128,263,453,400,748,515,777,114,893,20,299,530,472,598,381,288,224,610,115,941,795,565,101,837,655,613,991,940,305,438,9,902,863,58,951,266,135,131,44,133,411,77,961,778,84,857,877,378,987,612,313,8,855,543,461,724,511,154,900,464,356,42,972,42,463,353,417,733,999,854,307,510,421,702,158,19,960,930,522,360,459,142,19,826,580,833,483,779,982,61,449,490,271,884,416,9,14,178,92,142,576,113,56,15,400,212,935,668,332,465,78,957,826,559,501,195,588,558,952,887,90", "84,440,986,976,584,0,109,366,390,794,546,750,18,671,300,198,220,770,609,610,544,818,439,158,84,27,534,980,462,713,488,755,518,552,134,652,299,852,156,676,904,251,841,175,504,116,242,248,794,281,805,595,59,924,109,36,87,931,779,556,782,393,576,675,456,939,788,887,922,858,606,22,943,781,129,203,381,316,445,851,976,223,902,231,910,48,531,336,936,64,421,685,890,581,899,792,947,188,981,373,819,114,983,410,313,752,402,350,142,295,285,2,25,319,458,666,716,671,842,659,288,987,558,590,853,878,812,337,210,805,262,360,209,461,756,97,523,220,821,140,285,367,287,922,213,359,961,319,674,229,245,848,181,394,165,388,319,497,690,797,985,796,96,484,873,694,607,736,713,371,559,476,446,7,431,981,181,64,237,962,445,63,561,882,980,211,458,409,222,559,641,570,185,33,389,435,961,606,170,962,72,777,127,261,532,979,344,263,451,602,48,408,122,297,161,685,422,83,288,284,866,289,828,859,732,853,816,481,776,586,175,168,591,206,784,533,541,381,423,522,148,569,995,386,382,119,123,876,440,695,838,940,338,791,594,427,825,688,535,185,420,307,834,229,508,748,502,745,643,656,122,190,543,340,552,360,441,988,911,846,39,154,10,577,874,447,240,332,512,112,357,714,536,203,95,570,861,815,978,287,31,875,428,246,888,903,710,205,946,117,457,713,368,959,930,361,614,446,575,234,875,264,620,608,952,510,256,966,191,610,786,661,45,108,333,399,371,971,354,102,382,937,739,149,732,597,236,703,633,191,512,569,328,903,32,657,890,789,873,258,187,634,205,397,870,895,344,448,910,415,595,81,977,659,648,742,463,7,65,572,807,967,221,16,131,72,635,394,389,609,382,805,632,55,538,92,696,452,703,891,218,502,645,815,611,696,310,328,129,186,275,164,28,379,136,194,322,483,572,630,357,673,216,738,994,171,174,216,51,175,878,821,883,356,825,69,512,984,694,394,477,145,115,292,971,911,75,372,893,645,46,588,209,681,247,154,105,619,319,272,501,367,219,524,797,253,589,699,340,421,192,999,53,339,250,510,284,43,354,49,389,606,522,695,531,805,144,140,433,396,516,367,764,935,892,78,8,306,72,130,215,210,312,635,595,79,226,990,395,307,630,279,938,203,728,848,258,574,425,63,396,478,171,348,37,64,461,50,753,587,751,573,947,221,624,363,693,442,41,858,767,632,994,759,462,559,678,625,692,897,51,425,119,567,895,664,536,207,162,841,227,760,143,956,426,241,20,569,828,373,843,870,284,246,152,87,106,801,876,249,802,529,722,154,263,891,703,650,872,155,196,749,154,16,648,11,383,482,235,373,648,206,249,417,712,517,492,251,137,559,974,70,306,933,457,864,437,910,834,181,348,372,213,48,903,74,969,145,406,485,253,210,338,36,277,533,632,420,213,53,823,430,75,619,463,196,760,490,338,757,161,64,626,395,717,79,839,274,903,630,282,966,337,290,656,166,637,967,735,177,766,349,119,493,957,388,574,422,513,339,453,676,262,313,924,444,115,895,53,405,463,422,575,2,386,120,896,422,569,189,414,596,996,4,697,939,246,41,657,801,12,28,206,396,835,161,359,70,493,509,365,595,142,234,819,305,924,312,678,123,445,105,454,944,221,249,131,967,433,694,240,856,553,22,91,684,191,882,530,691,712,446,837,726,790,197,263,511,936,938,427,718,186,141,274,981,777,558,152,635,279,862,988,779,683,555,710,68,186,640,200,301,599,320,466,344,123,342,449,638,124,667,105,180,965,56,446,9,568,837,211,865,280,10,144,488,270,187,147,263,664,695,592,990,950,790,235,528,992,108,543,239,161,592,124,348,117,779,827,951,762,679,837,892,640,722,154,730,412,269,81,203,201,59,764,616,170,292,254,306,43,547,950,8,63,73,889,91,873,829,512,3,769,862,225,147,221,373,886,830,290,344,379,174,273,988,561,899,397,739,169,137,866,383,219,304,546,576,342,500,682,873,424,61,156,632,802,549,15,535,981,21,921,188,345,152,612,888,224,529,445,486,727,165,94,23,53,415,16,109,392,569,650,117,589,546,981,572,213,572,239,522,559,932,672,394,734,883,703,758,609,942,128,811,998,103,821,190,73,647,715,315,877,162,417,608,215,671,160,235,332,30,472,905,503,385,772,467,9,739,23,814,719,862,674,138,258,562,714,67,423,220,485,699,427,752,873,174,771,921,89,607,196,535,191,89,761,182,869,282", "33,450,467,877,44,109,0,352,21,21,261,739,777,16,839,512,876,59,263,709,919,213,354,765,858,223,556,268,898,611,385,74,864,503,490,891,805,551,77,475,499,367,648,899,319,175,223,988,808,296,3,216,197,192,807,627,976,46,264,139,974,339,715,810,819,945,897,607,144,862,835,899,562,391,157,933,691,918,516,169,380,484,378,977,227,914,681,70,970,789,910,187,914,381,999,749,341,828,857,735,438,782,840,517,151,305,449,120,631,278,314,880,642,84,408,693,358,960,799,544,434,865,975,997,6,484,873,206,860,36,171,814,737,834,185,148,472,479,969,463,751,379,202,58,855,233,826,245,408,345,736,303,16,576,212,586,909,532,443,1000,180,352,740,341,215,940,618,140,760,427,228,771,698,371,882,533,728,996,572,242,143,962,133,390,664,786,580,895,212,873,589,171,625,558,770,356,535,784,930,214,210,51,932,163,617,662,588,139,152,417,852,326,445,917,924,798,425,323,297,389,483,151,569,529,292,298,569,270,942,671,785,569,805,232,328,315,966,65,852,726,788,349,169,870,783,324,281,584,278,219,120,909,935,557,541,706,587,419,755,576,642,363,387,228,385,632,2,815,899,790,587,494,813,65,477,543,874,356,33,518,998,110,306,25,965,769,226,909,535,597,878,101,87,32,404,194,555,544,597,886,282,890,215,973,211,751,527,769,887,873,704,803,864,296,609,396,229,670,895,222,739,438,40,256,939,377,256,512,335,850,182,404,680,529,297,362,801,53,607,385,80,880,586,930,860,162,509,899,464,917,31,743,275,381,874,906,921,596,405,75,522,322,838,198,354,885,657,580,519,588,224,156,745,834,34,768,258,68,722,727,255,819,521,605,886,353,937,657,340,105,332,240,945,437,260,398,945,948,762,39,474,897,604,11,965,945,709,705,151,240,772,682,688,692,676,177,308,504,586,118,109,445,610,344,751,510,120,104,959,131,925,680,736,812,763,985,268,815,64,714,482,886,439,496,496,11,736,304,833,818,393,83,161,51,62,419,496,372,810,953,368,171,439,698,939,370,711,482,106,925,562,341,529,829,260,941,279,925,327,901,56,528,113,289,780,181,460,640,557,566,9,235,410,959,527,370,646,257,43,710,408,205,74,150,496,805,363,333,577,154,471,906,921,504,752,302,415,329,592,628,305,919,521,285,545,342,934,653,696,267,167,699,775,723,274,910,535,893,644,818,917,306,400,694,43,679,826,866,837,311,263,568,957,63,260,523,834,747,627,863,691,192,189,555,88,41,663,150,13,367,747,765,810,952,697,811,909,895,375,608,664,496,128,100,210,631,702,553,779,629,532,989,160,198,455,258,144,518,979,486,159,89,91,168,178,429,621,286,95,574,949,493,175,153,273,73,276,353,224,468,914,910,885,11,85,168,3,38,823,572,915,41,817,812,61,730,597,543,601,31,163,389,26,543,593,847,648,138,134,430,266,439,858,20,186,967,710,264,802,265,317,325,453,549,104,412,156,54,103,668,113,700,736,399,458,984,689,85,738,357,148,343,992,903,916,982,428,271,947,383,605,606,553,287,511,891,537,243,101,532,262,223,948,859,463,91,700,195,364,942,891,411,202,954,444,548,581,988,562,116,400,21,111,369,898,20,653,498,915,933,398,893,140,264,674,221,426,628,639,467,614,480,89,777,903,861,457,133,711,487,708,677,428,159,468,675,927,897,216,734,162,769,996,168,859,901,93,630,989,343,85,575,415,907,24,35,537,311,783,799,657,11,792,52,935,669,542,311,687,757,47,551,106,87,70,111,628,694,514,117,617,239,425,839,960,52,415,810,85,178,937,760,98,193,574,301,863,431,611,1,193,832,447,18,333,493,773,40,129,638,642,914,908,880,163,240,558,485,621,217,825,76,898,172,816,165,36,51,509,123,198,645,880,628,331,591,964,91,823,41,843,605,449,123,361,833,977,39,382,466,605,22,574,750,443,385,172,167,470,539,881,2,760,855,126,747,839,402,158,193,933,445,478,20,311,54,448,144,272,144,895,336,630,716,119,529,869,350,462,867,382,686,65,561,989,337,754,901,348,599,209,545,229,847,542,484,350,678,98,302,503,792,528,681,137,733,843,101,754,678,573,221,962,393,64,522,277,372,660,484,5,758,35,707,982,780,937,125,775,48,912,516,36,409,138,140,70,5,354,319,351,811,989,151,615,276,357,364,656,256,629,151,36,31,529,864,676,620,901,788,450,981,210,594,198,834,984,953,356,615", "758,189,509,679,514,366,352,0,16,948,324,345,508,350,958,671,191,112,473,406,520,758,86,333,694,407,370,771,674,426,505,434,727,207,989,692,965,677,716,680,907,936,958,437,991,17,26,520,62,551,559,991,725,857,542,434,948,381,285,492,768,785,292,660,971,74,410,654,894,494,772,171,721,50,30,345,332,991,807,406,79,962,361,385,671,639,703,192,930,605,515,398,40,15,193,759,461,212,870,888,208,809,105,879,722,693,840,129,647,159,759,668,390,542,938,186,921,931,876,323,98,161,612,366,943,400,117,683,948,673,784,636,61,936,794,170,167,509,986,13,375,779,478,393,292,552,119,960,292,334,973,949,25,417,447,821,398,782,166,274,576,392,929,16,621,938,983,853,129,116,868,436,86,47,806,981,197,160,320,323,721,619,998,763,152,4,591,731,795,633,419,666,491,146,905,454,658,97,210,591,875,959,158,278,218,106,749,847,63,667,580,959,648,234,62,275,765,225,714,273,324,532,228,819,588,784,99,727,574,839,948,234,389,326,594,396,467,750,366,713,4,265,870,415,442,696,720,732,153,578,286,636,400,68,607,755,853,301,494,359,193,11,664,49,972,444,933,753,543,631,801,419,164,442,419,916,736,57,504,204,868,692,404,680,681,544,553,215,835,276,581,167,624,183,953,552,245,760,305,58,657,230,43,759,770,252,321,126,333,939,937,281,864,383,720,204,137,198,413,911,21,306,600,683,155,219,280,959,67,655,926,355,280,663,80,404,474,647,558,732,377,821,462,46,327,46,1000,936,412,585,804,956,239,61,384,489,226,356,638,990,527,670,763,73,270,807,180,821,786,832,877,433,468,532,438,276,544,53,47,372,257,43,765,652,81,518,314,145,923,466,908,757,846,365,626,919,875,274,927,242,716,829,145,68,911,884,352,766,704,419,589,351,5,560,146,226,139,8,984,354,384,369,149,993,511,918,356,447,999,173,125,654,494,491,878,548,653,600,912,977,584,199,75,817,60,55,644,75,828,940,472,291,410,912,479,684,837,639,560,723,704,300,499,717,614,535,190,302,770,874,740,459,430,217,242,923,541,619,92,105,976,429,685,303,453,302,219,812,514,256,41,821,398,717,885,940,801,971,791,181,38,460,713,75,367,249,36,64,734,534,8,291,254,471,879,91,435,325,501,301,586,186,747,745,731,715,762,349,608,775,367,320,980,478,217,344,820,636,555,611,932,505,746,334,864,711,840,680,945,8,478,40,823,823,141,401,352,426,905,647,757,950,351,926,400,169,612,600,322,451,321,604,201,733,147,459,106,271,562,518,443,953,990,485,380,723,618,987,457,97,926,439,14,653,477,548,290,458,762,361,102,840,516,904,344,158,27,158,786,24,876,311,54,227,577,339,537,115,226,983,481,672,120,18,750,538,756,455,860,98,431,416,524,629,405,827,836,795,122,296,953,103,928,855,883,117,45,955,882,877,718,174,536,461,461,776,643,762,383,575,503,143,421,152,508,839,769,581,627,340,686,690,248,880,878,492,914,889,901,657,257,545,813,949,616,465,710,828,209,539,227,662,925,69,78,795,821,888,297,479,612,716,409,362,543,452,994,374,961,932,299,864,24,646,476,717,856,871,194,530,145,879,578,52,733,158,218,976,574,134,895,452,801,450,650,953,13,720,726,657,950,637,591,669,814,827,582,892,200,473,946,765,598,555,503,111,45,553,782,755,233,493,939,716,583,922,471,365,919,736,251,655,422,606,133,710,763,302,548,843,55,568,560,640,778,249,485,294,495,598,224,178,939,526,442,371,532,871,618,852,992,84,430,937,566,711,801,425,70,50,711,828,727,395,233,692,640,934,642,14,455,254,998,1,755,565,161,400,423,114,114,875,963,88,645,482,717,975,320,42,761,595,12,256,972,462,173,377,969,277,295,103,708,292,231,356,780,5,718,752,608,417,928,129,191,462,625,216,200,968,875,425,519,939,924,447,356,988,725,461,17,361,52,857,637,424,587,424,820,616,400,126,331,229,968,225,537,182,852,159,225,774,929,482,146,103,346,260,114,131,981,380,927,238,594,5,9,877,943,539,538,76,257,554,170,815,886,334,878,421,543,234,231,687,732,578,132,379,23,637,106,478,763,842,479,185,97,907,373,969,19,346,504,455,941,844,857,9,792,736,13,397,207,848,49,962,893,761,467,112,70,763,222,757,970,825,24,737,670,493,191,806,119,118,591,153,787,944,919,638,579,758,75,191,543,926,692,111,754,299", "908,382,781,555,846,390,21,16,0,495,554,294,295,629,687,230,555,311,18,358,529,427,183,32,412,279,915,63,722,811,624,517,195,57,654,14,815,500,464,742,842,641,923,117,654,955,690,491,962,786,155,695,926,374,383,406,957,187,738,930,945,404,533,218,244,681,924,640,849,880,78,395,920,72,272,622,583,278,571,10,211,329,173,393,793,509,839,152,287,549,202,741,557,931,904,155,418,527,881,546,216,551,185,918,485,259,73,953,402,701,729,299,354,681,251,359,99,179,420,502,390,842,589,332,80,446,572,19,331,830,440,585,514,601,150,845,943,520,438,947,309,441,43,680,725,146,201,407,364,388,855,747,933,882,213,828,769,181,777,96,443,927,478,364,290,121,831,447,54,76,45,195,375,94,57,589,889,119,143,613,371,209,57,89,326,539,207,631,658,639,993,433,715,489,956,860,812,165,634,688,682,306,567,447,804,698,943,273,255,287,147,195,163,166,594,671,903,873,660,948,695,589,81,54,718,408,135,697,926,581,527,309,884,887,512,715,381,960,181,236,39,358,579,427,377,734,814,621,370,279,218,107,442,525,533,416,212,222,225,349,213,352,213,784,397,824,381,38,642,764,616,286,278,43,471,258,732,57,651,810,559,307,586,80,625,815,379,492,101,148,593,329,630,646,343,509,647,892,134,194,988,370,770,145,941,910,526,70,937,608,253,730,227,983,527,889,952,220,890,762,86,788,359,82,499,954,120,843,213,731,440,107,909,448,105,167,971,462,604,806,910,349,365,911,363,539,768,415,102,508,501,509,624,812,288,262,73,464,930,953,798,736,960,740,835,891,268,438,611,174,520,824,452,884,179,255,894,19,553,936,616,104,673,92,234,454,653,442,939,476,470,249,130,772,156,414,695,314,152,662,621,132,970,341,732,562,314,607,845,84,235,645,375,135,284,242,533,184,334,573,70,659,922,577,634,401,917,341,552,404,197,67,713,260,556,943,617,164,336,723,740,579,975,13,488,468,882,55,957,676,962,686,734,491,108,990,355,658,204,597,733,88,994,188,879,432,637,23,527,699,195,214,941,756,230,726,559,17,113,670,354,685,345,20,78,248,12,455,171,23,770,940,972,368,53,785,928,700,666,684,803,738,861,263,3,893,121,402,932,644,444,352,652,525,215,90,757,863,604,762,915,527,478,960,288,649,899,269,961,876,862,100,417,548,423,462,298,834,146,935,674,536,660,640,843,880,180,466,994,894,12,388,51,106,569,90,572,66,622,101,335,319,528,878,751,825,756,957,821,500,192,755,582,653,834,552,272,661,312,470,488,109,516,770,281,224,746,734,822,298,854,620,471,312,524,830,339,453,510,86,936,575,882,18,572,901,252,131,135,146,616,445,725,318,562,571,801,724,916,513,758,766,894,541,793,542,433,208,479,441,256,947,998,357,184,771,130,663,498,536,855,230,680,931,594,105,617,359,169,649,80,20,285,548,725,454,985,321,248,40,661,717,626,203,709,679,367,492,964,544,852,961,608,115,242,783,664,917,134,698,672,173,629,359,506,410,86,648,22,560,793,857,260,703,849,295,308,739,534,559,298,623,816,200,793,514,228,687,745,575,547,772,980,640,105,778,623,946,247,967,406,206,370,568,80,790,262,773,330,839,508,660,484,209,615,649,202,330,118,847,346,913,649,780,750,454,705,780,998,761,392,96,468,305,384,698,777,635,548,783,382,713,672,75,73,597,599,951,499,649,928,252,127,872,913,713,304,195,235,708,176,495,552,809,188,428,171,804,703,346,613,160,124,98,222,934,211,423,177,423,250,523,750,186,537,209,209,175,10,997,640,328,917,698,909,565,837,908,967,83,800,125,901,958,632,998,959,632,45,673,814,924,838,324,994,837,758,915,236,970,350,420,309,790,497,496,291,830,948,226,136,903,924,464,66,249,132,882,320,215,351,191,265,690,28,363,463,671,973,836,330,595,127,270,968,972,718,188,214,425,585,437,249,164,304,867,500,212,69,839,938,689,883,837,411,608,866,638,464,297,72,375,203,869,838,115,343,492,122,14,815,258,606,127,39,868,750,36,308,603,933,296,878,683,909,928,555,662,809,410,121,478,514,791,436,918,397,907,156,422,988,279,705,775,980,820,673,505,679,351,31,667,103,362,311,27,906,601,928,266,228,148,260,199,11,219,609,973,647,418,155,998,535,751,757,991,418,474,396,202,326,726,45,190,658,609,912,157,875,272,354,480,128,192,279,878,552,249,407,823", "420,388,544,918,58,794,21,948,495,0,906,650,437,53,933,817,60,131,55,582,893,880,829,213,669,73,736,131,573,120,403,566,346,932,878,9,187,198,621,731,396,65,529,612,196,130,591,875,15,187,802,769,214,671,331,611,474,305,521,745,991,195,227,791,853,739,158,898,390,180,403,79,812,252,187,260,706,2,142,852,582,265,22,190,134,824,608,952,465,637,875,648,756,91,38,732,141,802,664,824,107,364,957,216,205,78,98,510,295,359,166,476,23,533,618,951,242,228,42,758,301,431,961,245,778,830,396,406,618,552,777,542,287,627,859,457,90,342,314,568,326,952,541,216,593,909,164,816,460,891,999,294,884,228,991,978,487,168,649,868,100,979,942,304,625,552,300,340,275,986,223,626,801,650,714,197,186,558,811,755,44,622,15,820,55,960,518,850,870,876,109,984,273,167,528,279,578,338,938,996,663,465,603,70,140,509,83,122,85,655,328,177,197,911,890,562,659,736,183,903,747,944,880,324,820,773,395,676,435,637,505,729,232,145,282,353,322,285,771,498,64,112,157,333,211,631,751,496,404,917,846,328,238,740,853,596,377,188,313,234,928,472,832,69,551,786,359,763,50,85,365,77,821,660,782,662,468,724,52,110,936,392,778,750,872,407,562,867,951,404,277,454,202,514,458,514,958,770,505,709,114,212,20,463,105,113,674,566,6,540,134,164,106,200,639,839,382,227,91,934,918,362,35,509,326,231,284,753,833,627,620,407,116,261,421,775,292,441,923,764,249,734,52,37,886,981,178,845,796,670,917,277,905,449,777,206,819,542,236,609,518,117,1,202,725,710,812,678,179,352,713,136,383,896,582,749,340,979,70,588,389,826,430,288,898,467,637,462,179,299,471,503,301,433,701,553,759,861,224,387,451,624,833,83,911,305,280,247,796,112,742,398,55,211,326,388,669,331,536,181,330,645,935,158,519,881,517,629,451,427,619,771,557,523,353,20,368,699,795,229,873,787,984,501,554,308,765,21,90,896,523,627,549,854,544,896,12,168,159,342,133,800,164,413,634,517,524,198,33,193,514,909,285,608,755,137,931,425,410,805,829,990,72,191,607,492,910,410,432,339,627,935,499,73,507,421,693,258,899,381,276,995,86,969,802,410,411,77,203,991,625,843,538,103,736,200,601,453,834,216,490,821,323,760,607,431,439,767,210,165,664,770,60,884,394,127,512,403,270,641,497,654,658,987,812,875,528,948,782,713,878,184,588,193,129,681,980,786,667,71,666,663,909,411,221,23,829,125,549,323,190,433,957,530,270,933,601,243,429,208,877,786,323,11,234,71,861,757,141,25,239,670,315,445,578,607,104,109,824,523,462,792,39,937,991,103,134,271,408,120,672,327,455,770,134,842,329,994,902,899,116,90,543,821,211,649,562,588,773,349,388,245,748,385,339,940,8,126,996,242,984,718,795,346,773,259,546,564,265,928,365,612,390,795,687,931,179,767,518,997,477,624,616,270,448,468,496,102,330,547,550,336,70,555,305,595,628,115,522,184,166,873,566,122,490,64,682,794,925,557,305,609,812,675,201,556,970,541,530,354,509,949,266,468,392,393,567,383,978,81,927,817,162,598,792,79,736,77,212,598,555,805,173,312,377,278,78,33,570,440,609,216,533,183,313,400,726,851,599,931,269,213,940,984,133,838,320,835,760,288,775,52,170,422,830,998,692,788,113,410,24,303,616,926,951,760,904,408,508,516,547,458,473,702,850,807,79,891,683,448,559,195,184,424,857,108,226,359,900,558,474,496,244,437,596,295,730,969,926,313,755,791,579,967,855,424,872,918,643,808,577,723,31,871,427,86,145,468,338,593,796,498,512,923,500,865,303,486,87,321,859,363,180,204,535,931,77,981,545,875,941,959,367,842,474,385,76,171,494,751,248,596,509,678,420,213,168,606,39,836,27,625,777,4,392,337,711,157,976,138,658,146,177,817,204,801,600,145,904,365,76,895,886,907,254,354,219,744,842,205,307,277,245,495,265,251,849,29,632,823,196,477,122,35,504,698,724,445,628,746,987,528,315,531,374,428,942,806,533,646,167,626,436,213,460,34,753,14,142,362,412,882,727,698,390,713,588,773,621,626,560,90,954,781,841,49,876,372,873,354,78,52,980,212,943,275,307,559,378,854,294,998,990,145,654,829,815,627,578,142,921,255,946,86,61,457,18,142,18,54,808,306,550,691,122,143,837,306,561,793,838,805,229,418,373,295,501,346,12,509", "610,460,43,259,260,546,261,324,554,906,0,354,773,953,227,795,438,900,794,598,528,234,86,872,523,742,913,352,841,518,392,982,264,47,325,816,178,620,786,202,218,529,921,751,224,543,129,72,529,848,167,509,840,471,851,544,945,328,797,300,43,899,845,307,420,634,460,995,662,779,939,880,64,655,936,602,814,436,545,729,248,617,917,301,305,250,368,491,354,760,119,984,940,302,476,19,145,863,675,876,400,435,56,906,480,543,342,408,906,639,211,571,731,354,484,964,466,734,815,262,678,553,703,270,455,894,302,697,499,126,746,585,828,929,102,782,766,478,295,512,484,542,210,58,727,292,704,596,371,828,238,415,730,183,660,372,459,530,857,541,450,302,879,922,274,836,203,712,257,866,581,518,280,188,924,223,425,619,149,349,797,664,629,295,188,39,786,204,897,506,84,563,739,84,710,906,691,848,873,689,547,480,769,287,418,185,62,9,606,582,451,450,475,717,851,373,989,311,731,911,300,882,402,442,805,102,764,89,91,847,808,110,311,977,927,702,260,517,71,656,487,158,191,280,797,416,64,286,23,26,751,700,179,956,955,732,322,865,592,89,131,242,656,763,26,494,927,990,85,958,282,810,146,859,375,634,189,387,557,56,324,285,579,696,111,693,55,214,439,339,329,789,270,472,485,373,67,4,98,868,871,926,70,757,489,240,180,719,210,32,484,403,29,679,450,658,80,891,54,654,653,725,385,85,119,952,38,817,466,633,222,661,480,560,181,364,52,213,503,431,117,206,295,637,815,756,216,965,396,748,843,896,953,608,7,311,690,903,664,116,340,956,819,17,26,846,453,259,905,635,185,368,174,505,573,423,922,923,425,339,481,426,487,26,374,839,319,795,63,663,21,433,777,702,414,112,381,396,791,10,780,563,851,835,224,150,552,634,864,437,954,164,398,629,624,388,530,579,497,945,746,770,922,945,364,507,932,164,869,183,839,943,467,271,948,753,334,585,97,238,555,486,813,567,603,219,116,700,81,797,552,261,428,759,522,373,608,847,401,199,675,723,134,382,672,915,721,762,488,497,103,69,325,282,550,907,718,851,888,424,482,735,637,656,43,281,529,839,90,670,442,842,65,520,320,513,663,396,949,767,15,366,975,497,685,160,766,906,475,725,906,948,145,128,281,19,434,451,809,35,439,684,251,242,84,503,513,511,728,502,794,618,915,205,675,682,134,82,307,695,390,385,848,126,265,341,492,686,760,525,118,32,35,990,752,752,690,13,746,626,492,320,526,666,551,158,72,20,631,751,43,417,60,954,53,106,133,261,812,379,808,600,452,899,75,474,766,606,792,879,499,599,627,991,450,83,236,868,375,52,19,495,503,458,400,841,679,147,416,610,890,648,28,474,394,51,926,197,56,960,330,228,556,994,211,800,573,260,853,513,520,746,711,548,552,964,395,132,444,154,203,567,907,724,602,150,442,336,278,813,709,766,238,895,704,728,335,867,393,99,942,926,591,929,344,523,601,363,284,636,445,850,798,516,465,159,259,551,656,849,903,467,175,883,697,274,306,415,728,344,806,398,342,750,525,24,147,834,174,439,238,478,142,983,25,864,757,810,295,91,113,812,506,526,282,817,237,607,367,984,399,973,458,931,500,355,119,801,781,571,800,623,681,54,818,365,675,20,981,762,557,244,362,998,915,243,509,381,237,662,818,814,156,923,657,900,533,32,46,190,617,775,959,627,376,440,289,173,646,976,201,856,567,104,40,914,983,394,939,358,665,474,512,946,936,313,897,450,881,979,117,506,954,861,94,395,893,280,764,231,276,637,655,275,789,636,585,570,294,174,692,54,25,298,54,905,895,926,348,189,611,442,995,338,133,900,990,133,261,770,834,318,217,435,235,185,571,798,510,469,926,77,100,214,518,657,476,484,39,39,172,880,209,135,762,351,375,856,300,833,588,591,563,882,661,74,875,788,86,753,760,749,549,657,207,400,129,268,58,512,281,953,539,603,697,982,271,78,908,673,214,78,727,962,605,789,421,430,856,663,139,334,548,278,401,840,641,195,596,242,530,557,196,480,301,528,438,492,381,352,737,160,374,154,921,531,412,878,387,444,129,307,921,414,131,509,360,626,436,947,928,717,749,468,259,366,427,458,908,297,67,492,983,411,6,276,275,818,268,916,845,821,164,599,798,484,124,467,240,778,232,867,289,135,410,958,52,975,168,642,60,578,705,41,560,54,774,940,501,457,773,153,171,405,94,105,113,50,632,738", "484,802,803,522,489,750,739,345,294,650,354,0,879,269,568,43,905,661,885,938,831,68,641,935,878,424,774,63,352,484,122,756,55,875,305,105,785,232,574,24,310,982,609,630,633,802,420,952,8,600,243,323,748,412,46,140,483,755,879,204,434,514,32,906,660,831,705,293,929,793,341,215,442,575,543,913,296,33,61,1,675,259,733,932,89,250,531,728,444,924,356,253,864,245,829,293,562,126,657,764,376,26,326,613,405,70,267,388,239,405,991,507,952,270,279,784,547,601,9,771,828,645,421,60,617,643,832,489,455,24,754,444,321,709,110,178,788,787,271,923,880,858,213,818,463,238,241,242,389,35,682,165,872,22,102,508,436,251,254,252,363,874,2,925,635,866,371,982,618,354,97,473,293,594,643,262,253,479,868,250,430,681,359,356,818,66,626,323,817,498,670,61,545,837,327,532,772,557,269,374,38,735,954,340,158,99,414,601,618,473,248,789,754,567,381,793,563,852,151,66,537,192,881,421,920,487,354,240,58,859,61,174,385,73,644,570,154,570,199,136,920,70,917,712,603,907,475,901,368,40,288,313,235,770,101,496,492,7,867,627,968,424,60,541,306,792,486,824,923,926,644,497,194,335,471,855,326,189,369,357,598,119,848,553,387,339,136,543,111,352,659,347,542,180,502,606,996,320,414,974,388,625,396,256,863,479,711,522,356,627,729,668,458,74,245,311,369,780,68,689,124,95,512,100,672,142,650,243,104,153,296,149,680,654,304,88,529,72,214,49,866,885,244,411,123,105,565,701,256,382,804,444,503,406,877,729,542,11,212,86,766,903,311,204,340,354,518,180,854,131,904,615,956,834,153,54,142,423,861,961,231,126,765,160,710,299,41,656,592,432,82,387,69,699,697,143,935,143,736,872,11,716,975,987,366,742,145,838,686,651,383,400,185,859,801,740,171,975,7,124,402,916,231,750,195,347,194,552,823,598,251,666,440,747,400,724,922,24,760,925,511,448,858,429,305,249,866,917,643,376,830,70,754,951,305,431,209,352,947,541,28,442,306,207,631,274,337,130,265,246,287,983,457,568,370,266,152,738,824,383,670,201,572,667,809,265,732,313,38,963,361,431,537,418,275,295,836,466,365,567,396,949,529,181,303,627,738,486,281,897,858,566,569,834,860,576,244,613,746,887,759,772,712,463,781,529,397,242,302,445,175,155,588,718,803,615,292,686,184,896,213,558,157,171,583,437,629,184,445,787,697,248,440,908,327,558,310,806,334,809,494,601,503,797,247,352,651,104,462,920,821,839,926,871,482,172,571,164,85,333,983,343,591,287,3,652,167,283,156,374,976,598,920,966,35,52,324,884,702,264,995,898,149,493,454,50,697,117,151,868,292,618,642,566,973,932,51,782,355,771,275,409,723,183,481,579,966,600,165,876,667,42,450,643,538,230,391,306,929,350,778,677,102,220,511,303,585,5,109,189,859,250,387,921,982,251,547,555,617,146,817,541,32,541,397,839,568,900,639,80,617,774,145,633,261,825,625,821,166,802,766,320,330,449,197,832,226,377,350,273,446,272,335,883,706,231,75,580,380,835,735,161,453,545,345,438,308,381,80,395,927,41,683,528,505,867,235,284,172,379,571,461,19,506,892,978,606,285,534,717,737,217,264,74,141,954,99,559,36,988,550,603,81,497,495,342,392,329,404,424,309,3,330,828,434,537,392,273,789,263,151,513,605,336,329,6,28,906,258,75,806,145,735,959,754,481,890,916,648,678,152,116,432,497,580,301,105,922,128,194,728,440,897,278,3,84,166,566,850,713,735,63,627,516,19,975,336,147,654,895,748,3,638,648,498,718,101,546,786,801,156,10,413,132,164,923,252,132,857,122,400,608,818,644,319,198,81,473,56,306,981,500,394,805,824,490,40,236,571,662,880,304,279,701,113,834,394,319,251,534,247,725,882,884,828,378,531,869,884,873,211,401,280,705,815,644,923,221,642,128,162,500,830,294,348,910,203,898,456,327,138,492,723,592,401,786,357,428,883,66,282,832,563,204,155,662,450,248,775,649,51,205,640,87,729,538,295,166,363,996,788,301,947,6,945,40,611,907,214,218,853,895,692,351,771,494,19,454,916,655,317,992,874,73,547,295,776,975,291,52,57,991,281,359,819,288,43,808,69,693,208,488,705,406,56,663,598,72,349,515,869,299,293,167,960,56,78,930,685,562,654,736,739,978,526,481,88,493,422,604,806,624,840,598,59,286,889,744,711,437", "195,266,544,153,486,18,777,508,295,437,773,879,0,171,471,291,787,106,859,102,784,760,146,473,131,720,555,110,194,684,590,158,346,780,667,911,951,198,340,54,504,549,491,280,220,347,268,486,9,299,597,386,352,938,893,767,400,262,637,281,979,87,554,476,847,195,19,3,745,892,732,862,901,991,990,135,976,17,242,402,856,4,260,205,751,300,780,861,242,36,508,58,527,966,612,88,946,542,398,439,223,254,44,520,883,533,793,287,467,423,118,227,758,547,842,612,906,609,671,520,52,952,506,658,506,736,465,73,739,56,52,258,590,651,441,968,711,451,283,906,890,172,416,632,677,774,433,108,677,398,220,984,888,47,459,716,683,93,360,919,697,416,372,851,248,911,958,927,471,818,648,640,460,869,473,588,539,484,126,75,351,749,262,897,271,671,168,21,927,892,512,908,721,508,346,279,119,263,7,105,905,122,454,331,189,635,672,219,199,360,362,368,711,736,232,33,812,149,232,900,183,916,943,257,953,108,750,326,454,652,382,618,136,870,184,920,194,204,774,47,642,203,113,199,514,789,31,26,708,46,854,492,577,582,701,357,398,928,755,604,890,723,30,404,154,321,978,583,520,677,503,325,244,18,482,447,694,887,529,930,618,981,790,196,925,714,441,208,772,568,673,629,299,960,54,528,520,413,911,314,543,205,128,227,287,795,386,817,471,779,151,867,632,514,667,356,151,152,320,631,943,801,687,314,692,872,406,647,143,726,114,183,905,195,554,923,626,181,558,300,429,354,760,809,272,102,948,52,325,171,426,986,253,884,52,651,725,460,707,654,316,922,996,342,585,843,895,8,291,654,58,99,536,353,44,999,944,470,197,564,525,137,683,450,148,161,608,698,61,758,209,726,580,698,668,37,820,215,276,651,161,914,587,155,479,670,998,468,167,486,40,974,795,968,514,310,426,439,872,339,781,979,282,376,438,168,75,439,314,507,184,117,90,153,956,392,710,193,713,359,76,713,275,946,214,615,806,995,342,454,80,419,980,771,985,972,855,710,948,213,896,515,692,364,527,415,155,801,586,939,529,88,612,731,246,649,829,917,937,302,998,954,290,304,473,492,733,921,274,280,796,541,402,456,110,256,983,678,392,730,542,569,286,795,596,11,713,601,402,589,23,810,440,126,430,20,858,964,379,2,471,786,759,810,104,222,127,521,897,426,222,366,49,177,177,907,649,653,881,894,930,890,128,196,55,870,167,669,509,715,482,891,536,934,483,749,466,521,745,358,538,815,396,147,807,230,875,996,189,557,149,112,359,521,701,214,503,807,865,752,386,397,293,268,339,351,891,977,536,253,610,620,748,379,66,570,141,53,681,855,506,410,781,464,463,979,729,968,492,669,538,190,97,262,598,657,916,147,669,256,318,105,214,174,381,730,542,115,406,813,47,270,677,964,549,884,412,750,109,136,21,896,200,46,535,366,258,858,980,761,407,951,425,622,532,50,64,974,735,311,448,227,920,685,194,467,603,838,672,776,937,989,62,850,262,788,364,290,783,528,473,497,432,853,146,909,192,965,357,529,630,68,436,958,242,54,873,539,740,864,938,301,983,294,118,223,174,333,213,338,419,732,897,416,890,754,151,616,581,561,259,653,951,485,469,195,814,112,512,280,94,470,748,787,839,117,404,231,260,465,128,517,464,783,577,739,675,748,729,364,625,568,575,473,671,924,279,950,482,725,747,700,732,1,511,369,346,444,695,742,365,121,332,343,245,609,918,317,355,222,572,437,188,745,371,737,506,32,54,73,780,712,560,532,510,773,695,695,391,891,325,714,929,520,219,296,231,919,943,860,999,258,119,88,845,319,63,235,23,648,965,903,155,799,844,513,388,187,724,928,953,555,453,604,205,397,864,356,718,444,102,396,154,855,947,907,725,980,23,955,200,875,95,449,806,349,129,921,428,881,201,718,895,656,742,29,921,30,4,724,250,425,192,926,488,301,306,145,527,132,952,584,433,735,348,497,743,258,797,644,52,94,398,708,364,646,258,15,791,33,461,487,94,376,402,68,678,199,26,560,946,370,722,527,133,821,546,213,957,708,726,74,441,833,296,69,896,595,33,880,3,625,933,433,430,876,921,391,252,588,244,160,152,358,759,727,755,850,676,4,250,921,413,590,278,862,529,983,315,457,644,403,974,667,413,189,503,755,875,903,779,213,598,981,11,937,993,523,679,479,753,19,248,616,758,112,687,903,380,224,259,908,843,909,500,311,890,142,346,999", "474,415,354,491,66,671,16,350,629,53,953,269,171,0,370,567,309,812,670,925,317,695,660,548,423,717,659,520,184,281,506,575,658,880,711,541,122,654,833,38,195,850,264,354,217,256,39,184,807,183,471,522,274,155,496,90,624,931,714,44,118,891,255,22,446,569,488,980,299,928,550,209,256,703,953,165,935,415,478,737,450,369,683,385,492,491,299,906,31,551,157,957,995,608,806,928,415,414,584,674,887,262,776,668,872,272,736,764,135,252,749,734,961,373,784,490,33,703,725,50,816,160,609,225,428,208,796,654,70,363,657,29,630,903,90,529,456,379,560,32,748,629,629,795,890,766,557,208,680,979,556,753,93,468,788,141,686,944,305,220,724,198,262,741,86,238,844,624,344,283,813,60,483,650,935,200,613,321,737,389,657,292,152,794,800,60,22,392,784,791,25,517,115,576,414,831,724,381,143,143,498,710,458,409,623,637,56,732,322,616,476,823,651,177,177,963,532,708,58,356,615,888,120,815,324,718,333,44,996,809,145,441,106,40,451,445,450,204,698,356,912,827,438,785,49,268,600,613,827,643,647,267,626,616,561,860,764,38,459,285,35,225,932,474,511,864,284,321,385,469,244,767,950,123,635,871,405,57,596,930,517,297,949,388,28,235,526,902,135,336,105,708,119,844,440,306,102,914,858,564,738,819,886,318,218,173,317,512,504,111,840,105,424,424,340,847,438,403,74,124,609,54,846,348,389,134,686,913,262,21,141,764,28,221,963,203,50,354,646,924,388,955,933,773,856,796,209,839,188,679,662,768,161,566,554,647,267,532,122,992,263,149,387,670,554,98,736,617,550,693,1000,768,159,673,292,163,117,157,893,890,558,844,217,152,464,967,55,64,537,840,224,791,530,709,18,274,298,227,504,799,684,824,204,114,723,863,320,934,53,455,505,933,643,159,360,731,251,782,210,339,645,921,179,314,363,959,641,231,604,131,973,433,927,515,741,195,680,902,547,98,616,616,622,750,982,754,830,347,307,907,272,5,844,213,812,192,958,659,136,665,156,522,97,160,951,395,629,62,957,688,78,299,668,803,426,934,877,743,344,918,895,12,409,851,271,295,650,790,368,859,246,106,15,694,233,331,590,181,694,329,414,959,801,128,170,390,227,191,157,208,708,670,742,219,755,156,252,403,367,968,97,18,933,516,203,475,112,211,518,484,331,633,920,226,766,981,422,821,494,408,776,625,24,845,930,893,992,331,267,642,104,444,89,46,416,589,278,230,113,281,107,962,560,815,936,460,313,990,157,398,678,602,814,881,427,237,741,270,825,790,74,222,12,29,505,311,333,503,347,230,480,188,347,631,44,521,785,376,694,912,179,624,802,145,808,991,427,645,400,702,111,132,856,149,449,658,151,542,523,243,382,144,975,109,919,467,435,826,730,142,796,991,32,413,552,785,121,952,932,600,147,945,380,128,334,866,16,356,25,366,431,587,677,11,138,258,135,354,388,167,186,929,55,408,256,194,869,16,734,12,131,794,153,315,454,770,441,791,347,6,958,627,293,17,672,771,159,788,111,342,820,704,353,995,512,82,226,686,79,511,76,183,115,514,844,964,230,914,592,671,196,794,297,911,208,496,483,695,399,6,127,936,767,509,459,894,986,87,578,674,972,675,589,526,831,542,226,561,954,499,269,969,163,133,937,939,488,37,929,259,598,775,991,797,321,247,332,302,927,556,960,264,756,769,472,270,248,216,402,197,460,468,144,404,77,729,585,36,546,154,983,58,329,522,833,822,184,255,433,301,573,341,731,379,997,865,153,161,43,573,924,692,17,737,563,943,830,587,55,334,762,122,419,574,719,479,422,194,395,369,591,510,564,542,66,18,62,904,989,475,495,47,885,878,650,296,490,435,620,841,921,297,155,590,925,870,788,161,549,951,204,545,205,199,95,833,448,773,327,973,853,399,179,252,271,181,589,671,295,600,152,838,929,369,942,140,231,550,846,582,279,830,942,927,767,138,775,731,616,459,752,168,978,489,891,601,525,991,862,112,577,958,338,19,132,554,279,710,565,339,286,429,350,486,594,73,25,987,161,99,680,773,809,901,116,93,356,155,936,168,191,450,467,490,32,609,968,247,891,331,897,939,414,548,918,936,159,70,312,721,883,62,997,28,187,817,778,28,694,819,677,115,499,498,969,38,709,409,327,974,977,568,402,983,478,510,68,490,140,441,314,698,339,19,152,925,76,681,694,119,340,936,567,700,346,353,938,415,732,899", "254,70,937,650,420,300,839,958,687,933,227,568,471,370,0,417,780,847,487,857,293,818,622,123,96,762,744,354,512,654,425,493,763,12,396,149,785,594,312,273,841,941,480,554,262,675,654,65,908,547,131,166,475,995,10,529,720,343,818,8,865,416,795,542,26,225,147,801,708,703,382,440,35,368,104,866,595,94,458,87,637,278,164,524,254,56,414,615,330,50,373,616,659,986,328,671,395,473,566,432,162,751,708,574,481,253,616,700,446,405,557,269,708,132,895,182,994,518,499,509,225,150,547,619,820,705,884,841,302,64,47,376,399,926,732,112,225,176,258,702,647,849,288,149,199,493,908,733,864,180,164,932,363,9,638,989,563,182,88,858,205,171,21,76,518,828,597,754,817,721,957,126,819,14,573,342,789,880,88,572,621,310,501,485,382,890,360,890,774,460,506,905,286,538,744,307,855,148,235,378,944,1,554,368,718,69,96,452,398,354,191,385,742,801,431,971,906,415,345,560,932,630,189,160,393,933,371,856,909,844,423,998,301,201,319,39,14,815,505,893,233,930,42,306,780,455,635,671,116,194,90,292,11,418,360,293,966,373,489,668,285,671,95,87,420,807,702,590,591,36,377,705,380,105,479,291,745,326,698,649,794,94,923,798,491,571,786,498,357,129,412,268,816,118,890,642,197,471,557,835,712,386,144,198,266,452,915,822,348,437,343,172,388,94,319,56,869,596,183,333,734,948,47,133,333,914,393,496,894,901,147,755,232,433,258,77,772,142,970,621,307,621,903,917,606,585,913,78,516,365,918,323,623,901,566,953,59,252,599,719,473,21,919,603,781,454,173,660,431,924,737,425,428,33,60,264,699,919,369,763,863,479,163,73,322,2,176,939,292,526,890,449,596,241,922,314,195,576,857,608,80,300,880,65,203,902,949,389,567,438,268,946,672,968,366,739,986,160,245,339,215,43,347,579,318,85,86,951,627,479,628,302,938,320,643,859,995,705,319,903,79,72,214,260,770,616,285,53,328,586,148,573,76,600,438,195,819,685,852,231,608,585,293,351,888,129,948,469,477,650,898,983,178,465,947,918,768,422,274,489,283,610,876,567,960,254,230,324,176,738,720,472,523,221,609,45,958,411,265,96,573,82,493,323,461,942,589,453,269,158,463,987,353,581,448,850,215,832,968,425,507,900,227,126,9,488,335,839,724,907,442,618,311,106,321,849,156,307,666,315,434,966,203,313,835,948,182,395,213,237,773,29,876,195,86,826,335,679,233,344,808,105,482,603,189,487,510,380,658,387,774,581,252,192,531,838,762,913,128,642,36,61,494,38,176,278,763,610,342,572,664,450,226,67,419,514,377,364,212,820,530,428,632,408,16,826,788,766,788,280,362,754,691,790,115,921,508,841,665,632,771,541,746,729,590,757,63,180,546,734,233,552,886,200,91,87,785,657,786,151,141,107,685,297,353,357,159,158,702,42,715,917,832,59,11,977,227,879,797,9,567,514,412,979,872,579,630,201,903,576,577,245,53,764,828,902,88,631,525,376,504,888,435,612,155,147,401,993,473,157,655,280,769,828,297,931,819,147,123,723,693,781,501,35,240,783,638,103,343,632,901,548,874,784,298,874,39,483,118,625,875,209,762,182,504,185,327,232,742,702,373,982,78,871,815,48,809,303,293,187,894,446,463,364,395,791,222,877,786,614,348,7,772,229,78,409,538,924,89,600,101,773,834,891,714,123,955,852,209,946,392,151,357,927,847,290,718,777,714,154,628,885,360,705,656,72,26,186,107,581,430,722,773,253,527,798,733,798,253,327,947,595,4,886,288,525,488,357,280,137,829,280,511,436,749,218,697,401,525,19,732,265,261,398,160,828,382,929,255,88,356,153,785,402,488,137,781,30,908,898,504,931,648,19,194,587,318,379,463,416,586,130,797,958,824,664,782,243,161,238,325,824,653,595,180,608,937,121,278,785,358,170,436,487,968,898,623,637,833,726,423,743,995,283,517,905,6,730,328,777,290,708,925,189,493,875,287,371,740,904,100,25,77,458,31,211,694,881,220,215,335,229,822,23,914,968,13,814,218,303,976,578,449,136,685,148,789,974,534,697,963,782,218,317,931,159,800,606,593,416,553,604,46,266,676,615,956,822,879,10,351,188,125,869,910,619,946,777,900,261,620,973,202,798,280,742,940,912,48,769,467,284,157,52,856,437,287,253,601,902,950,568,105,707,976,93,172,471,11,477,810,282,609,956,414,349,545,824,765,501", "969,10,252,419,805,198,512,671,230,817,795,43,291,567,417,0,669,407,187,539,62,456,304,977,900,967,804,163,336,640,427,233,478,804,284,994,373,134,567,694,759,761,88,361,216,196,886,340,312,440,30,811,652,51,758,529,324,113,509,431,992,697,80,283,626,159,963,640,734,917,633,332,458,82,736,793,446,626,233,69,310,933,325,244,45,196,69,374,264,613,748,66,299,484,672,515,531,836,420,883,621,429,297,175,171,239,897,489,48,262,455,486,490,358,491,917,621,68,359,325,958,922,438,864,471,318,771,14,724,71,932,259,356,383,296,389,651,275,178,549,624,102,291,911,218,471,841,909,306,185,587,609,154,477,303,657,544,821,302,270,303,546,429,549,515,122,199,867,262,296,754,34,214,761,210,141,746,334,404,32,807,695,306,393,134,310,137,511,494,786,913,467,697,889,413,105,49,631,639,959,939,628,169,732,275,248,427,593,256,150,117,205,323,794,59,600,32,445,436,272,209,371,361,625,559,62,193,825,813,83,955,814,429,679,570,439,716,83,493,864,879,374,159,429,730,78,782,852,374,237,901,587,499,225,998,418,113,211,156,283,224,672,408,665,343,858,85,890,339,371,674,685,664,738,867,168,819,811,819,817,882,715,941,429,410,653,937,428,188,822,501,96,964,18,315,523,954,520,502,992,290,659,91,113,885,624,310,512,751,453,873,930,748,432,905,132,849,674,454,874,793,50,454,780,958,343,247,313,567,850,609,254,788,711,811,438,183,294,950,273,254,976,671,937,89,567,348,251,360,823,160,509,618,345,147,788,767,506,486,833,365,206,471,271,831,279,297,116,335,507,778,646,887,364,977,784,836,656,129,558,169,931,228,133,632,785,648,519,330,413,286,932,351,476,455,481,608,152,674,53,567,217,375,929,469,709,335,187,460,52,500,895,602,94,252,165,947,205,187,787,463,994,443,71,760,65,523,667,99,818,974,661,774,29,45,711,372,518,700,104,741,120,558,335,835,795,476,438,863,968,418,596,620,669,157,331,781,552,628,693,639,350,713,400,112,318,692,181,95,30,620,46,124,840,961,822,321,576,598,797,292,816,757,995,525,728,907,334,722,565,18,895,851,479,225,102,368,492,405,536,839,180,677,462,2,494,456,835,454,190,697,473,499,987,704,618,420,879,746,517,86,426,169,861,106,57,412,535,479,928,227,802,604,479,222,758,618,20,385,207,402,862,935,250,621,260,655,196,941,112,815,79,973,423,852,983,101,62,49,336,613,505,617,348,339,469,458,602,340,538,551,351,450,417,108,863,226,67,386,654,78,181,231,587,892,95,604,387,518,277,467,788,297,7,126,65,339,430,420,553,219,722,125,239,953,777,569,394,324,784,23,116,738,505,463,857,663,202,665,70,843,314,103,308,67,913,96,326,854,224,542,859,351,914,725,144,44,919,60,467,384,475,122,722,690,676,805,149,491,613,56,281,49,419,962,152,866,508,937,226,226,943,745,85,239,422,607,799,400,724,628,969,509,761,278,940,591,482,571,362,908,292,860,577,532,685,844,409,482,860,143,128,649,239,795,536,76,20,447,182,367,39,144,135,150,544,40,411,766,20,687,867,920,155,763,843,472,498,518,382,471,984,876,446,32,556,752,39,247,742,931,51,616,870,371,140,900,490,456,753,896,874,504,445,969,529,623,351,773,635,906,910,521,365,356,389,748,268,585,119,907,598,879,821,316,835,275,625,484,251,450,982,547,253,425,538,733,775,857,98,12,11,688,482,43,583,935,601,797,113,41,416,209,25,804,569,553,726,341,378,690,231,168,568,683,906,121,716,168,708,933,669,338,236,216,679,913,311,307,651,499,901,787,251,197,337,179,465,196,127,906,654,850,426,710,33,556,174,795,326,536,748,925,835,61,343,9,526,377,305,356,404,774,260,39,121,707,487,572,524,689,289,220,44,789,186,946,114,382,657,442,611,45,519,755,587,2,265,28,969,453,430,379,442,516,330,652,752,60,402,719,75,173,270,218,221,931,769,886,647,196,838,211,867,370,318,460,593,874,253,924,360,119,417,946,660,446,484,41,893,401,187,757,294,968,252,581,759,997,495,21,887,366,252,86,256,672,967,195,93,523,400,7,763,869,740,15,227,741,790,5,759,122,168,139,602,131,241,390,286,112,676,560,539,693,885,809,652,326,924,995,699,540,176,520,4,774,92,945,139,221,825,104,518,534,59,404,795,700,100,803,313,202,319,137,796,278,7,696,303", "172,137,687,377,805,220,876,191,555,60,438,905,787,309,780,669,0,676,334,535,110,499,368,115,167,93,409,442,485,233,729,548,200,876,622,439,257,847,921,91,385,914,469,58,706,858,307,636,277,311,413,744,988,697,463,635,601,20,450,955,448,809,805,954,160,645,63,139,986,676,831,656,920,827,776,465,599,199,149,553,204,956,86,616,803,55,462,526,701,599,883,75,572,571,325,666,847,750,26,949,367,617,394,710,982,566,351,51,430,142,705,697,255,436,82,706,910,302,52,414,824,800,383,176,913,630,806,788,267,26,608,719,532,365,687,980,278,191,139,92,852,34,768,784,627,691,447,74,46,598,475,183,584,339,356,226,73,709,953,913,369,331,737,283,21,749,500,570,703,271,59,350,252,457,638,43,989,427,63,355,4,959,680,858,500,813,281,67,235,220,452,676,32,838,494,375,622,135,585,695,691,642,220,671,755,236,832,486,206,10,776,648,169,636,65,532,116,110,549,370,315,775,99,423,812,864,837,582,44,641,812,895,853,725,276,463,212,295,64,892,770,693,848,362,535,674,31,193,605,18,604,928,56,626,433,382,179,458,978,771,671,749,109,205,93,232,159,598,110,594,946,969,862,566,224,416,385,108,118,752,353,225,557,522,644,985,171,649,495,555,148,566,163,552,643,513,918,666,503,778,486,59,46,714,636,214,122,674,647,684,625,398,34,74,248,555,429,577,64,650,671,435,583,252,809,321,931,473,881,905,668,984,673,348,917,419,322,258,872,781,695,520,351,158,24,649,587,172,110,252,938,812,137,790,77,499,26,72,631,587,67,26,498,988,772,250,858,282,594,854,769,6,896,140,296,221,669,276,262,509,66,358,670,409,287,352,482,85,328,705,581,906,680,526,835,782,611,777,594,410,245,675,884,783,723,540,989,954,20,481,303,625,132,704,669,805,695,592,950,914,649,394,559,456,689,189,414,558,490,601,424,500,890,574,787,667,220,960,613,681,992,219,594,736,275,889,782,111,513,612,587,75,509,178,542,836,193,569,923,664,93,977,978,439,471,389,221,301,623,159,423,780,892,408,656,234,454,79,553,182,827,290,790,736,740,896,329,929,462,104,230,358,485,190,164,810,583,943,399,454,365,105,605,96,81,746,828,962,63,61,342,837,586,807,190,765,575,97,725,257,6,150,771,923,602,350,810,873,81,755,33,447,575,33,422,915,215,331,340,503,207,705,568,307,922,537,349,556,739,366,199,642,366,166,547,941,176,338,558,718,53,407,250,925,411,920,674,411,169,633,900,320,953,777,204,382,478,870,742,907,84,154,436,516,229,525,262,171,539,457,947,73,992,980,442,186,871,218,939,80,64,193,554,572,690,417,762,572,996,427,109,755,18,454,227,897,626,720,392,231,512,340,132,703,350,254,832,994,708,841,734,387,456,467,631,783,960,911,835,213,302,382,496,983,238,182,303,380,734,349,254,965,224,237,712,333,39,86,205,616,689,686,759,401,837,417,468,183,138,844,56,336,354,963,915,880,802,672,879,84,342,438,351,217,942,273,315,128,611,416,45,763,220,745,871,13,933,436,464,457,870,176,265,545,909,457,762,448,146,785,768,533,954,551,11,660,257,421,208,607,406,527,815,100,632,964,52,828,162,171,234,213,130,853,720,811,519,496,62,151,841,880,375,881,578,545,244,911,723,714,940,659,217,923,877,951,248,481,978,408,276,404,892,873,520,500,220,182,63,931,212,507,818,745,614,298,792,616,755,650,655,430,514,388,797,834,703,127,949,248,438,631,966,630,133,305,998,437,614,602,270,470,190,831,538,302,53,385,191,718,833,537,936,56,501,143,540,971,45,925,625,131,79,608,806,862,869,8,30,319,605,631,613,605,893,652,658,292,888,941,386,506,782,206,208,965,497,663,816,411,939,687,228,396,628,845,855,416,881,196,801,835,895,798,393,843,794,940,210,952,116,453,566,510,80,216,722,378,383,567,642,41,464,252,154,221,177,375,905,72,284,758,765,727,591,635,229,59,747,729,716,825,237,555,873,723,962,365,273,890,535,261,9,613,516,597,626,974,950,343,953,880,231,600,36,528,284,785,581,481,783,68,600,876,349,736,742,338,119,235,654,715,94,447,732,413,501,421,75,103,473,23,954,94,759,880,522,562,578,874,610,232,255,977,249,416,690,522,800,955,789,974,104,552,499,352,189,676,625,742,465,941,522,417,298,714,112,508,417,523,684,301,33,895,529,570,443,314,937,758", "463,344,373,449,115,770,59,112,311,131,900,661,106,812,847,407,676,0,40,23,996,231,587,141,284,596,718,189,487,11,264,597,427,921,151,214,109,947,617,842,393,142,840,240,51,446,53,749,512,341,949,115,55,309,951,611,910,245,274,827,124,507,726,978,615,539,989,338,870,1,883,789,220,534,777,976,672,700,106,711,306,160,359,687,576,905,598,694,529,391,686,503,55,934,24,774,331,257,348,383,315,442,239,828,341,228,829,684,218,38,943,866,564,80,686,965,898,820,698,4,113,969,362,489,124,794,684,376,808,848,527,102,939,359,344,226,613,390,189,327,413,267,669,63,543,301,230,373,437,17,381,273,792,586,494,596,997,68,843,946,55,174,651,469,430,871,815,958,754,652,816,936,572,906,641,438,940,267,449,284,739,370,539,909,249,310,235,493,166,574,972,223,418,517,407,721,677,76,534,959,726,319,11,963,27,20,694,15,137,457,66,239,552,777,226,687,799,490,316,72,102,762,762,16,11,639,957,36,326,603,107,428,845,444,836,578,744,769,237,688,796,70,910,357,685,665,519,584,16,574,502,38,975,705,388,729,701,76,538,956,56,207,950,623,31,584,751,272,818,480,390,257,661,934,137,990,647,710,786,629,702,650,685,460,982,231,600,617,994,915,672,468,206,222,748,787,30,146,664,249,610,727,197,610,501,682,327,862,285,694,497,177,359,192,336,568,63,293,73,776,317,127,6,260,476,86,503,831,271,203,679,271,356,340,756,652,323,849,49,539,976,420,244,243,847,36,477,578,211,681,279,34,303,268,165,867,503,318,75,296,866,245,490,768,948,718,541,112,619,276,988,324,596,822,397,586,381,438,67,776,289,111,329,895,621,944,125,324,370,208,149,966,437,910,113,345,63,259,757,86,357,325,149,884,459,802,915,917,191,113,208,488,579,420,545,219,237,325,390,4,28,597,484,268,562,740,571,176,631,377,683,280,988,889,589,718,338,350,753,457,942,343,322,257,564,20,282,239,124,132,854,215,617,730,98,61,831,264,702,416,678,830,635,441,927,38,809,540,66,72,236,558,893,515,978,280,746,663,999,39,629,427,306,848,669,223,323,842,920,200,735,751,438,435,788,290,714,782,725,167,718,890,116,664,303,521,848,809,334,87,579,245,2,243,306,466,455,116,189,281,989,455,791,37,968,551,392,28,34,857,853,663,936,943,410,480,407,296,118,985,68,42,497,97,430,780,207,142,574,680,518,382,873,826,157,915,51,582,79,432,84,182,444,530,614,208,823,908,547,116,922,556,811,866,321,130,867,937,667,311,218,88,18,880,154,335,718,720,988,429,26,677,525,852,421,493,425,713,923,568,946,776,602,832,73,659,425,254,712,563,111,482,264,429,200,835,815,874,389,619,125,732,902,704,344,935,736,895,59,258,216,48,619,588,653,159,621,909,474,376,66,369,967,253,717,587,582,774,382,154,261,897,383,639,777,451,497,329,780,515,313,218,127,269,238,508,661,13,101,146,208,962,513,566,770,64,314,836,24,242,552,778,487,22,288,773,870,339,916,56,861,207,234,994,367,473,960,562,393,705,816,133,774,347,762,381,350,170,126,647,114,986,774,826,42,856,505,368,73,33,899,101,790,551,769,38,771,890,432,513,368,587,190,15,531,971,729,121,769,307,964,473,790,746,751,484,128,566,761,637,251,734,798,929,729,348,231,842,926,261,440,145,354,500,551,933,376,235,593,560,60,281,808,676,741,169,701,869,274,120,37,958,970,195,1000,130,68,503,72,185,288,448,103,558,448,374,987,402,637,698,566,702,848,664,121,314,756,116,121,779,768,898,821,443,653,884,768,58,40,629,804,741,427,555,755,953,242,484,237,29,119,598,340,402,346,914,663,616,794,320,70,316,941,875,304,954,870,573,555,551,429,47,724,777,477,93,188,26,244,138,246,379,251,173,197,80,186,560,123,732,948,710,589,446,476,28,524,270,951,462,331,872,22,503,668,536,751,588,545,184,782,995,223,606,630,574,208,577,807,902,742,823,25,826,920,445,927,381,970,907,411,568,412,489,191,27,888,55,485,492,275,799,159,678,227,626,255,159,979,364,280,378,682,346,26,394,682,699,399,932,961,199,51,136,251,645,466,690,188,849,285,452,81,303,303,457,379,397,887,129,751,383,288,651,600,814,680,916,515,334,632,220,959,304,989,658,236,740,371,303,668,47,770,83,697,787,46,735,558,492,267,368,548,544,755,250,44,258,478,899", "130,215,142,295,978,609,263,473,18,55,794,885,859,670,487,187,334,40,0,961,451,126,268,474,960,830,869,969,534,5,142,574,324,240,649,478,379,779,978,288,265,48,517,758,431,775,101,841,59,565,609,600,483,562,234,912,588,224,640,155,46,208,705,846,944,668,919,230,828,211,293,675,498,622,456,910,498,713,451,566,903,793,250,285,666,433,188,760,297,268,318,403,663,268,45,149,105,440,737,112,30,34,631,609,949,101,804,103,980,490,400,985,795,955,738,549,602,81,464,431,306,133,576,436,121,85,1000,477,79,861,968,54,330,872,148,631,773,247,854,632,999,466,589,948,295,626,680,535,14,267,211,999,598,403,838,616,282,315,903,701,734,430,311,6,40,969,578,562,77,279,84,595,910,152,289,681,342,269,390,14,386,356,822,356,314,690,752,244,920,199,6,186,808,652,82,808,587,370,105,14,935,1,695,414,904,912,820,662,780,29,348,175,724,245,246,913,731,902,406,635,370,657,138,795,520,629,133,864,237,731,806,973,478,166,932,15,569,160,803,867,207,650,268,340,942,455,325,869,3,35,23,211,983,45,108,421,254,540,947,513,27,487,75,635,335,198,317,426,692,305,556,259,827,64,367,789,280,473,895,85,264,616,786,207,162,227,445,971,409,769,834,971,438,492,387,574,573,939,850,923,956,814,562,254,902,773,280,489,392,547,349,574,739,42,738,126,940,601,425,112,244,862,733,905,315,942,371,961,881,976,908,415,33,265,542,60,148,427,825,27,441,441,25,579,272,366,28,650,613,770,956,745,353,303,182,874,824,565,184,139,148,84,45,327,479,81,550,542,340,210,878,857,72,454,491,649,580,293,805,24,69,447,152,629,771,586,353,309,421,846,380,39,82,287,249,337,433,36,589,71,940,54,626,712,646,59,401,499,879,893,101,434,46,695,471,700,892,140,501,586,783,982,973,579,852,98,81,971,50,457,708,450,337,621,301,823,717,387,276,904,260,990,447,206,878,601,181,67,392,420,237,683,27,591,242,469,630,347,749,650,793,925,298,923,476,953,666,549,104,629,185,153,355,701,403,234,829,203,235,319,385,527,599,301,980,911,81,319,741,516,940,520,758,257,316,813,569,722,314,843,650,896,722,22,237,768,34,401,475,511,519,644,443,803,359,783,698,824,266,659,752,313,159,505,545,333,286,359,467,568,13,201,581,520,811,100,152,797,321,884,830,556,257,302,546,736,619,894,229,388,105,594,4,840,736,105,10,207,158,283,238,872,8,111,454,476,201,110,299,913,395,645,329,580,774,987,96,200,459,665,526,639,101,935,891,925,714,617,665,820,388,90,185,179,111,440,137,894,405,87,5,888,630,135,813,389,990,98,318,358,351,446,834,515,820,395,281,100,25,147,349,606,865,835,885,158,895,453,707,658,120,427,102,476,244,145,808,55,477,829,640,747,489,720,504,350,154,681,564,143,881,130,67,239,111,149,537,554,191,952,248,383,926,617,69,939,235,663,853,543,491,791,738,757,903,58,86,591,709,281,454,332,660,947,296,17,926,182,898,144,445,314,939,95,907,368,563,816,949,501,467,83,328,592,952,109,269,5,767,37,839,482,353,830,722,891,847,961,801,496,634,531,252,553,591,746,734,87,355,260,989,829,725,669,420,896,948,93,572,527,742,953,672,625,463,353,432,629,494,555,354,631,217,888,303,738,935,85,377,766,114,966,575,987,152,629,58,31,951,76,470,44,439,587,789,210,827,471,946,997,228,312,12,699,631,578,583,210,49,624,408,297,274,302,884,941,338,749,93,809,60,509,593,824,938,389,774,744,208,113,196,357,404,530,120,110,640,514,720,173,466,325,81,330,868,345,441,468,862,205,448,107,317,485,816,31,744,648,475,769,569,953,947,916,659,462,61,219,764,890,769,997,927,946,233,866,178,192,325,521,32,573,352,171,259,890,761,747,134,810,808,998,663,254,253,14,475,609,148,709,566,364,932,209,768,668,183,869,755,598,770,218,434,172,752,329,898,123,795,531,255,235,634,454,374,737,322,285,75,415,158,616,90,767,97,263,552,870,984,520,76,963,785,740,137,249,484,89,91,170,299,174,696,298,336,22,197,690,624,347,462,583,667,713,268,108,425,820,626,391,927,55,854,483,105,631,270,60,861,625,247,222,239,272,712,857,769,101,273,753,838,638,683,139,815,806,81,362,109,377,319,296,830,846,53,514,779,353,386,707,798,648,992,935,59,847,425,998,201,69", "335,456,628,813,230,610,709,406,358,582,598,938,102,925,857,539,535,23,961,0,564,541,18,691,671,992,980,200,957,281,761,131,916,499,866,525,447,991,102,120,116,344,457,957,671,801,139,906,787,718,463,818,851,42,296,9,4,335,558,419,182,611,5,695,103,414,217,81,545,573,987,608,545,100,559,274,257,452,785,833,387,649,451,627,727,694,916,473,544,67,930,143,551,906,222,144,697,334,527,215,677,180,299,982,127,552,921,74,629,258,512,679,852,100,210,700,642,531,578,329,172,337,815,560,18,175,173,602,66,193,368,223,775,357,305,854,682,582,549,693,373,326,337,706,361,85,130,39,581,475,889,658,193,73,80,97,446,415,668,284,208,499,376,498,299,111,476,811,985,132,844,395,73,166,162,661,414,234,473,509,500,98,256,952,626,722,544,862,238,666,842,448,591,822,228,692,835,867,440,485,352,407,319,955,808,426,552,722,389,252,153,299,914,703,564,48,939,849,414,573,193,871,940,468,404,567,675,711,464,42,905,689,580,213,387,684,704,814,223,366,284,118,126,721,741,663,19,32,475,4,193,288,265,37,444,108,696,496,664,960,531,80,420,642,507,711,837,52,15,664,798,220,379,419,846,269,463,25,785,620,293,112,807,637,913,600,820,998,126,760,172,100,318,874,152,667,380,796,628,94,2,968,870,940,270,36,594,595,685,321,732,387,601,750,10,410,432,792,493,43,51,654,700,57,255,775,735,355,200,527,490,123,766,537,109,504,947,537,775,572,527,193,962,295,794,1,396,118,371,114,856,463,70,707,533,213,964,350,480,877,284,421,485,657,180,953,889,249,772,28,361,139,31,494,86,739,838,182,684,460,166,550,841,386,440,750,517,242,716,532,605,532,825,732,399,897,261,660,805,283,238,32,710,603,914,629,698,252,635,852,137,352,812,100,153,431,882,246,920,407,127,4,752,995,210,52,831,492,514,213,777,265,848,874,445,503,944,837,139,350,39,764,721,410,100,184,760,948,417,32,105,936,276,696,482,292,325,93,623,278,289,401,34,932,152,822,406,720,785,98,476,542,830,807,146,430,907,207,495,629,331,877,737,577,184,214,119,277,717,845,197,513,892,527,20,410,938,793,992,262,931,344,805,778,701,373,377,837,362,468,704,59,136,190,843,623,580,747,412,426,127,725,339,922,900,127,435,957,681,354,604,166,286,724,206,173,169,759,735,694,199,604,829,468,174,289,854,691,903,562,116,241,284,430,271,119,206,64,116,937,663,149,612,297,273,733,132,468,710,80,408,313,768,384,383,360,536,586,393,51,65,280,341,691,733,290,78,775,556,797,144,632,973,558,287,703,276,686,588,71,402,836,374,416,332,741,797,650,736,152,986,757,50,857,325,227,254,59,820,502,594,278,793,702,357,689,959,138,231,585,754,622,141,126,459,112,620,474,9,770,149,237,289,836,116,171,757,111,272,479,695,7,550,860,253,96,744,875,816,12,249,545,823,994,570,767,916,754,291,31,805,537,766,543,61,622,366,820,265,821,566,988,460,84,859,345,117,890,236,166,939,943,515,688,860,341,742,318,71,675,11,843,184,611,707,256,148,906,882,459,186,408,342,254,405,72,423,732,286,234,505,920,668,324,959,410,851,471,629,352,873,895,277,112,52,805,200,937,568,523,945,941,932,612,88,599,273,398,280,265,785,678,158,509,186,762,565,457,961,107,822,19,773,62,756,270,601,71,117,220,756,333,791,715,433,860,994,143,741,320,625,567,574,55,133,861,485,631,292,685,612,725,476,860,810,238,279,799,870,420,652,678,119,323,360,400,792,899,372,925,721,496,820,173,352,605,513,804,463,83,459,282,596,35,961,343,395,356,439,286,341,563,338,65,381,971,797,886,834,388,224,923,763,152,854,424,248,888,804,174,148,103,548,155,88,371,424,563,334,992,908,948,421,350,474,862,405,924,29,312,78,830,91,74,292,105,690,887,907,212,802,519,99,392,633,124,632,702,190,206,920,421,718,24,365,665,489,734,858,653,921,868,796,469,602,735,178,595,41,76,895,311,531,617,537,737,877,823,379,804,994,642,374,593,445,470,920,356,843,110,647,753,381,31,566,578,995,352,396,772,241,879,362,464,590,828,182,291,143,8,866,611,620,643,793,455,631,569,284,638,124,296,381,607,440,765,937,969,606,655,653,934,547,934,976,425,715,104,803,933,838,562,506,802,515,512,798,349,396,9,485,43,934,861,212,148,11,943,838,148", "704,530,327,575,125,544,919,520,529,893,528,831,784,317,293,62,110,996,451,564,0,818,652,964,387,318,521,261,165,483,239,417,828,995,62,168,179,42,224,832,281,356,885,459,93,317,449,469,118,909,631,847,359,805,622,712,925,802,585,207,301,445,390,678,550,584,783,111,805,122,112,989,711,106,168,343,853,231,7,109,501,733,883,707,20,726,39,590,303,516,457,206,368,152,612,452,229,709,470,799,404,973,124,446,955,614,524,435,668,159,125,840,410,238,114,416,680,41,630,967,818,424,474,34,894,637,605,184,616,844,769,503,763,630,380,23,671,17,708,154,427,964,446,436,56,554,746,643,333,448,739,558,711,219,235,163,554,574,166,95,895,323,257,323,140,264,48,38,335,333,148,608,777,620,336,460,952,111,13,262,131,952,753,416,386,865,459,176,926,793,482,762,885,147,945,86,376,730,732,290,88,866,181,887,163,771,574,903,146,461,369,23,535,362,18,398,648,854,501,436,102,12,683,878,655,324,242,660,72,119,418,212,132,783,266,505,225,670,928,923,217,784,914,516,712,322,859,241,515,312,731,939,51,219,103,57,882,461,591,370,74,225,832,337,542,304,829,832,357,568,406,494,343,206,323,882,945,564,220,93,6,946,890,448,102,545,569,463,137,29,859,960,467,744,84,259,197,385,671,899,754,251,59,63,676,153,761,224,530,997,694,957,661,446,218,143,15,421,541,640,306,439,39,63,299,865,147,696,917,56,705,64,451,425,115,384,932,751,211,251,364,15,874,138,439,552,488,346,451,666,10,126,341,793,422,994,782,34,248,726,895,403,963,857,630,75,250,118,325,948,503,863,525,619,717,642,632,480,9,685,609,194,973,865,313,270,570,671,352,651,148,885,996,794,771,992,471,458,1000,273,784,982,153,933,356,460,483,509,61,969,992,315,455,260,997,245,368,792,772,50,53,381,288,243,347,157,767,88,316,639,341,445,608,363,933,267,474,42,84,271,142,766,715,160,759,557,90,236,31,662,587,896,571,647,653,620,746,728,673,865,853,320,435,144,404,987,606,591,322,985,74,387,939,660,84,252,665,329,479,684,394,966,887,605,298,197,995,408,118,931,894,293,65,706,99,577,355,79,293,420,334,883,200,478,663,469,426,838,928,57,460,408,403,748,715,545,504,928,192,597,886,251,211,101,277,492,552,689,951,537,567,632,690,213,675,76,9,169,886,274,147,656,891,616,664,267,653,628,209,656,910,701,618,126,561,466,650,141,910,235,548,512,707,329,597,724,591,157,445,470,648,505,820,454,796,277,332,172,134,905,896,906,747,130,141,852,329,685,567,600,524,726,678,743,404,830,856,201,401,356,546,127,483,55,898,529,166,98,493,305,438,741,697,642,631,728,294,861,684,190,688,735,517,850,457,879,614,570,631,197,974,618,656,536,870,96,200,422,355,759,936,358,741,460,348,520,947,474,371,60,291,60,809,822,12,450,485,872,100,147,414,315,823,591,571,391,846,264,556,952,693,847,663,171,576,825,111,908,587,49,696,710,250,303,396,40,10,933,92,405,865,31,860,673,552,471,726,619,730,263,242,862,640,25,181,737,397,970,523,155,562,814,736,18,597,210,443,473,873,960,62,246,3,986,749,66,552,351,802,515,580,556,593,767,678,268,834,860,70,466,267,523,233,760,456,652,567,264,477,608,772,522,506,359,954,63,216,103,460,335,784,440,390,525,609,734,337,213,37,393,691,438,954,309,294,957,279,714,886,892,9,911,423,489,773,399,648,940,959,129,401,660,755,101,675,875,35,865,50,127,356,400,376,627,383,142,262,782,112,316,36,148,319,266,461,32,2,235,128,896,102,493,609,611,396,437,23,978,884,587,494,71,176,748,618,787,555,440,720,765,594,47,65,469,69,363,19,65,986,56,562,276,153,132,201,932,660,843,232,134,654,308,458,899,808,931,734,609,841,927,87,804,522,281,60,719,263,54,54,789,667,869,986,572,347,642,393,987,368,400,243,788,177,204,492,574,693,846,196,534,839,524,781,282,632,431,100,825,988,928,171,173,841,69,963,552,649,203,792,416,581,285,476,714,724,721,543,342,15,430,254,232,886,449,269,765,591,554,246,541,351,252,167,781,737,587,62,487,328,908,772,813,174,709,796,248,49,216,161,101,127,508,102,694,98,530,562,1000,88,413,780,120,309,119,727,447,523,861,140,229,568,412,449,525,904,313,219,650,157,426,416,60,676,299,313,317,400,54,888,774", "507,796,167,548,277,818,213,758,427,880,234,68,760,695,818,456,499,231,126,541,818,0,253,24,452,95,64,826,727,77,988,67,57,877,89,355,338,517,755,736,371,820,301,912,686,86,206,212,1,443,810,940,799,698,861,924,335,630,434,265,90,699,838,363,740,377,333,222,86,171,794,984,907,268,979,16,26,111,298,878,277,858,826,659,272,260,606,627,532,654,119,843,918,462,552,310,954,895,890,622,179,331,414,32,683,795,420,210,161,62,833,199,351,334,92,657,106,126,249,429,978,814,474,243,653,979,263,732,864,214,950,763,61,276,848,868,499,396,871,87,15,366,261,986,992,650,515,2,397,983,215,159,491,289,799,952,668,60,676,676,566,918,86,951,934,716,990,924,530,124,358,928,739,599,903,259,842,515,932,947,918,333,279,153,918,394,37,590,598,622,648,440,791,620,963,244,582,319,536,912,419,73,73,53,50,140,490,319,836,328,843,948,441,685,479,100,797,614,294,137,108,551,411,678,37,51,808,828,19,424,178,638,438,332,149,13,665,3,195,341,472,993,371,12,636,621,985,962,316,226,67,381,510,554,881,75,432,219,443,575,559,892,880,425,374,49,602,24,923,444,39,970,803,54,340,746,187,292,102,418,228,334,962,968,161,308,532,659,323,208,942,342,223,991,389,329,957,554,279,596,664,741,502,924,115,378,745,98,827,996,101,984,715,456,974,452,902,862,267,214,44,637,422,334,296,980,238,467,290,974,362,48,93,861,158,562,223,443,87,8,969,946,29,147,449,396,146,584,740,449,562,383,940,506,583,362,837,81,998,472,418,220,725,491,982,506,288,586,546,798,622,180,132,741,453,857,684,436,214,309,774,34,349,945,265,95,235,216,447,777,709,757,665,788,420,820,47,960,87,163,299,948,654,264,884,225,529,154,97,880,129,543,842,911,886,498,721,572,584,523,411,226,441,645,489,219,409,80,519,904,597,486,789,569,502,558,395,605,413,935,914,814,413,443,263,107,810,726,401,701,386,504,103,281,230,803,994,9,457,973,572,462,854,197,925,338,777,366,624,299,708,523,754,986,346,908,264,308,124,293,418,839,427,602,819,391,810,814,550,72,76,829,69,311,31,66,298,973,440,391,233,157,336,778,712,450,229,728,922,360,584,107,425,45,243,254,905,322,499,583,61,578,979,660,28,65,230,600,825,864,347,937,378,754,475,130,76,148,341,385,734,306,312,7,966,73,245,607,959,143,335,436,931,885,532,295,774,634,218,358,387,407,298,161,306,831,386,128,163,471,525,559,730,179,274,196,531,787,859,307,357,164,406,964,408,43,433,146,706,160,752,76,815,707,965,141,247,352,118,203,364,424,151,709,888,267,429,157,911,944,810,722,530,277,660,23,756,697,357,456,121,222,964,431,503,518,651,699,779,531,588,550,560,114,414,201,562,813,602,978,273,877,967,903,770,491,579,350,880,406,991,568,158,141,327,226,517,806,584,825,624,504,630,866,846,347,824,633,946,837,725,391,38,712,21,443,872,988,14,702,745,309,975,6,275,706,165,461,644,560,204,34,260,719,53,480,686,904,266,979,607,601,898,808,121,721,539,685,380,533,285,947,521,400,913,816,502,176,251,342,449,121,160,488,494,126,142,598,420,614,302,228,869,555,613,712,531,333,938,631,967,989,416,700,352,193,620,401,775,954,167,63,3,572,222,471,468,968,719,352,895,859,733,323,530,981,543,671,420,904,182,196,381,711,152,580,406,149,731,308,71,206,995,956,808,645,526,828,141,754,902,775,853,976,314,915,660,355,350,805,507,200,507,45,362,470,254,261,507,265,475,246,879,306,104,424,186,240,278,648,692,804,932,568,3,811,216,137,950,957,397,43,313,902,367,537,310,717,867,387,102,148,638,454,968,220,606,752,6,144,601,392,546,631,852,790,426,95,772,433,84,700,435,516,521,909,170,786,995,892,437,480,516,516,863,965,660,450,131,771,281,339,360,381,327,290,321,571,635,331,846,186,398,98,134,398,806,901,302,326,922,371,177,510,718,347,235,322,874,775,928,284,366,436,622,998,763,257,305,384,640,329,504,75,306,69,466,719,323,401,657,386,40,173,11,767,787,64,856,476,391,540,692,699,20,313,273,219,212,47,932,586,14,309,643,367,945,853,582,572,745,866,104,532,265,554,200,3,86,246,443,432,257,597,209,55,451,316,935,971,693,16,745,623,62,357,476,133,689,824,227,858,549,415,53,366,208,865,341,947", "358,664,769,550,219,439,354,86,183,829,86,641,146,660,622,304,368,587,268,18,652,253,0,873,213,93,216,408,976,798,427,620,229,638,875,168,304,548,176,848,393,716,954,364,180,31,116,597,499,229,688,965,829,632,71,116,674,382,836,308,277,187,821,18,426,800,223,405,95,286,638,630,998,569,967,425,319,599,101,383,380,246,138,664,836,680,607,124,624,19,911,747,889,747,704,317,309,578,799,893,894,585,961,592,173,370,116,513,706,498,523,688,103,128,686,789,343,46,735,217,305,918,288,22,68,526,533,934,201,466,52,814,48,463,97,340,976,652,122,182,203,535,808,108,19,356,898,23,769,409,399,616,160,32,764,311,244,595,84,554,436,483,95,209,909,473,713,662,326,509,370,814,427,285,808,288,695,177,771,849,512,961,512,499,803,834,395,481,421,25,297,433,486,417,202,606,223,189,662,310,670,459,242,382,273,883,412,132,35,773,880,962,339,54,810,852,368,395,654,756,643,745,668,113,29,129,382,424,858,327,110,912,592,511,65,77,645,292,855,71,431,759,156,604,537,557,909,379,949,444,113,117,960,45,412,406,156,899,873,657,179,933,804,389,484,126,726,619,789,565,177,903,808,631,988,940,326,844,314,623,114,228,538,491,528,772,39,853,280,336,412,587,722,869,300,70,718,141,152,935,716,634,270,568,477,411,114,314,20,261,561,903,27,65,751,393,735,572,419,742,6,459,245,147,72,51,538,737,674,471,474,742,943,372,17,58,611,142,434,94,996,801,267,775,739,345,528,380,628,853,429,192,291,428,804,561,797,825,497,493,1,414,626,873,221,686,168,11,349,73,988,86,144,336,627,149,701,143,352,684,373,835,523,826,582,816,981,518,548,906,822,330,350,879,962,778,390,868,386,326,188,496,653,803,352,38,886,295,430,155,826,594,125,477,457,844,58,905,368,4,594,862,783,386,969,829,420,295,115,490,22,507,602,267,975,245,190,680,260,154,733,754,385,447,31,376,337,941,164,970,893,714,880,498,424,219,9,3,89,583,57,932,746,422,584,70,926,544,319,265,498,326,449,507,291,854,591,170,475,269,184,332,945,930,430,650,637,301,562,898,669,697,560,28,841,790,909,836,664,697,149,965,751,439,286,223,125,669,870,674,711,976,507,32,339,68,753,938,450,856,33,118,398,228,348,470,676,423,812,567,134,460,857,130,818,230,476,79,982,437,679,185,900,751,96,460,185,84,916,529,346,645,215,830,999,839,131,90,389,929,211,534,568,685,473,48,891,652,412,144,371,340,384,759,312,415,921,516,519,705,294,935,486,733,268,731,198,55,670,270,165,849,357,211,708,710,39,584,174,529,855,990,665,746,629,843,279,728,249,131,935,566,104,518,609,27,674,675,315,927,325,8,209,346,848,301,624,388,87,480,798,487,49,225,170,324,610,921,469,550,306,511,370,798,518,659,195,752,670,763,144,884,764,427,101,113,507,598,421,486,917,535,740,337,290,452,132,198,973,952,16,265,351,308,22,706,327,49,787,560,494,530,348,120,322,961,269,437,372,307,334,132,797,650,483,169,383,654,496,620,492,118,702,4,457,50,529,374,169,710,888,763,527,978,126,548,252,680,922,100,619,36,645,728,472,468,303,907,175,258,568,258,673,888,120,282,341,627,168,981,7,14,820,596,569,104,281,402,486,745,49,787,363,18,526,696,896,732,6,66,194,639,16,135,997,20,882,713,438,770,281,447,866,34,459,159,796,499,448,354,566,103,986,925,765,423,85,604,561,869,950,226,302,214,552,948,465,662,160,733,435,460,638,123,335,919,733,880,21,483,187,653,38,33,338,436,336,603,555,711,983,574,786,596,39,325,688,714,159,565,779,451,644,360,940,678,342,662,255,532,407,366,580,724,166,340,677,237,202,920,193,917,748,955,767,876,336,642,638,451,847,480,348,313,643,153,616,132,361,421,680,131,285,27,640,342,777,479,20,506,491,47,180,197,690,732,966,255,94,71,22,863,767,269,961,686,415,498,81,660,719,154,586,967,120,260,162,550,493,388,852,721,870,208,128,56,64,274,160,306,962,181,881,851,892,923,662,956,725,849,521,449,798,353,984,775,504,319,499,582,735,211,214,147,769,452,513,883,975,290,153,414,393,556,621,760,708,152,392,201,384,613,883,674,231,945,549,860,263,828,716,470,634,242,93,845,767,75,320,931,572,647,779,564,303,10,245,904,801,291,723,723,881,696,138,632,795,664,490,127", "852,686,538,571,921,158,765,333,32,213,872,935,473,548,123,977,115,141,474,691,964,24,873,0,8,930,962,128,274,555,24,852,567,553,386,709,481,436,99,42,651,318,186,953,242,868,322,603,543,476,937,625,980,128,910,71,368,12,513,915,810,455,175,3,589,602,871,700,319,567,456,140,54,679,382,793,213,730,283,920,779,726,107,369,208,116,113,877,36,63,136,148,977,282,753,58,490,62,174,879,995,452,956,528,23,778,609,878,237,651,935,523,846,732,84,937,118,925,814,228,708,664,236,756,535,434,794,929,188,760,676,505,949,981,609,19,147,647,6,2,568,709,661,704,54,775,311,963,388,678,497,446,71,675,468,462,233,29,798,779,555,662,992,172,122,388,677,157,318,482,881,164,395,114,98,131,921,93,823,385,789,82,631,112,82,320,959,237,653,41,151,685,240,260,169,823,62,171,504,950,750,577,281,887,713,454,760,113,141,72,774,525,400,15,344,845,779,755,564,36,162,224,805,381,34,873,417,500,482,831,537,226,159,489,219,211,732,328,651,275,976,432,472,972,812,483,217,171,78,440,452,939,483,679,563,544,981,381,809,543,455,305,935,766,596,417,48,97,336,381,834,729,820,333,304,352,445,444,963,145,873,557,27,583,843,142,817,457,577,406,648,230,927,74,395,558,264,490,650,814,270,745,453,584,911,973,510,612,270,278,646,26,391,83,194,310,299,164,541,328,277,228,688,665,145,746,991,984,629,65,2,123,973,465,916,141,534,376,825,296,978,102,151,264,224,627,538,151,169,783,754,731,63,423,816,616,963,90,137,660,926,864,880,921,448,990,895,449,703,640,907,155,247,549,118,15,156,338,818,49,85,165,314,695,13,785,294,734,579,908,461,736,307,792,509,567,241,563,798,176,841,32,949,567,643,87,133,811,412,330,525,137,51,459,631,72,37,800,213,707,88,9,968,338,931,610,825,864,69,283,837,852,966,48,238,562,898,597,170,337,176,750,749,86,969,54,190,765,333,29,140,194,802,274,811,687,601,804,403,686,112,509,554,764,914,372,842,654,824,427,625,808,231,168,792,158,875,661,720,976,822,942,816,84,901,609,883,274,111,661,778,222,674,328,499,811,618,703,420,295,632,263,770,148,99,702,681,995,343,66,125,131,263,228,148,299,239,303,396,792,523,842,385,418,317,93,724,122,869,8,244,960,367,870,755,146,727,867,587,835,303,288,782,750,964,881,654,379,187,646,792,66,290,933,270,559,293,19,232,353,796,554,170,784,238,248,108,228,498,337,609,561,604,176,639,268,583,479,671,203,764,883,690,606,247,555,499,216,508,77,81,198,184,304,339,856,275,981,403,470,250,869,161,989,597,583,30,587,306,484,503,607,837,197,691,201,192,893,247,728,420,15,594,457,678,445,206,503,360,989,695,127,403,11,522,595,268,296,976,145,925,364,323,753,805,614,138,576,778,897,621,796,791,617,834,475,710,291,364,632,56,846,518,300,559,421,736,786,918,589,389,591,714,825,471,477,304,448,276,291,32,980,667,485,377,884,40,896,359,528,173,813,863,20,88,333,966,588,174,506,425,737,349,200,79,728,823,582,666,464,97,982,665,655,237,656,53,943,390,893,141,911,652,681,910,822,387,959,983,278,129,694,70,903,169,849,217,418,665,824,759,65,316,262,605,541,765,876,919,583,692,171,139,110,574,792,100,992,431,787,528,321,122,731,643,138,393,130,112,185,644,997,213,225,70,877,882,172,942,934,288,446,848,314,409,169,754,894,152,860,577,771,874,936,653,276,203,638,152,515,799,359,134,254,20,83,823,29,744,68,444,575,442,25,706,515,126,46,489,881,636,14,951,497,918,391,52,940,383,248,742,203,828,72,32,949,174,961,739,809,154,107,490,815,509,969,74,485,810,831,146,744,538,263,34,332,62,826,456,643,675,894,462,764,984,188,482,304,244,317,438,348,41,171,665,969,106,950,497,837,548,776,322,61,746,802,352,152,843,306,793,161,109,353,407,380,791,541,382,775,504,787,367,950,128,990,209,857,427,649,330,392,655,213,636,51,212,605,337,490,393,837,52,307,353,110,187,617,668,570,69,977,818,717,68,883,516,934,109,490,444,592,790,42,310,149,5,692,752,644,612,34,831,516,959,4,948,621,300,559,845,41,744,411,593,314,470,428,77,137,4,203,587,574,613,5,592,591,815,330,478,889,900,231,136,995,668,843,366,931,664,51,467,952,259,852,559,243,17,83", "356,149,459,135,253,84,858,694,412,669,523,878,131,423,96,900,167,284,960,671,387,452,213,8,0,135,511,388,733,119,454,770,527,977,384,286,345,139,774,3,896,861,342,433,219,528,849,703,763,327,234,107,613,928,57,591,91,323,727,210,537,641,54,493,515,412,568,605,121,540,805,771,506,967,376,534,779,19,8,495,936,27,229,799,819,946,537,504,789,534,434,818,323,600,182,193,719,736,367,835,176,517,84,236,831,126,565,864,898,985,975,186,91,450,315,995,974,872,463,308,855,342,277,978,960,916,283,517,545,291,856,770,160,811,270,899,145,116,410,246,271,696,231,914,436,140,805,679,173,582,29,752,740,130,624,667,115,69,303,349,284,384,126,456,103,371,936,329,666,348,667,346,848,341,194,702,168,29,316,395,869,855,391,87,92,690,874,361,395,182,810,423,345,389,604,306,727,668,367,900,215,240,561,30,661,119,906,202,830,862,140,681,790,155,263,22,715,792,177,732,551,995,604,640,771,232,766,649,596,519,26,948,255,430,80,960,514,462,88,753,597,557,985,61,60,184,783,787,861,768,820,732,91,471,868,790,220,395,550,580,625,11,229,740,251,439,745,200,514,197,993,280,880,859,749,532,433,763,844,410,978,814,686,329,611,663,5,57,794,946,351,13,704,290,732,718,496,906,200,850,739,759,294,16,357,37,544,56,88,44,165,120,204,315,881,333,577,663,840,574,941,564,626,76,40,338,251,501,410,200,510,348,923,437,939,335,672,379,563,764,857,880,333,905,985,62,971,214,530,717,558,764,955,940,735,337,205,157,218,594,254,264,501,781,168,893,866,40,89,218,624,239,8,802,824,688,329,157,250,762,789,919,304,919,373,326,845,422,864,699,946,743,841,422,109,454,953,397,48,791,507,766,85,402,262,535,412,31,684,982,673,78,211,747,396,835,216,882,734,419,699,384,210,673,584,803,205,110,506,419,679,253,635,378,995,983,831,986,674,68,130,311,437,172,266,117,569,848,29,912,235,107,968,266,17,420,108,286,410,995,510,260,59,912,629,209,943,654,154,52,351,411,660,642,739,892,10,390,819,950,899,374,841,140,303,867,625,776,350,165,393,431,915,840,351,424,951,739,504,522,364,977,108,337,92,80,819,639,455,413,218,132,13,178,815,739,375,222,36,247,612,77,461,459,911,4,487,793,994,900,677,503,399,296,255,806,411,991,371,578,768,436,444,457,592,427,446,462,991,666,920,509,57,595,823,487,308,453,201,176,27,962,981,265,223,598,249,949,436,759,498,687,749,51,626,564,236,400,802,577,910,762,318,115,786,401,410,538,951,734,53,439,61,532,667,623,651,635,385,680,128,34,806,148,243,714,788,634,274,265,983,358,716,920,922,286,982,699,593,978,655,245,919,338,270,997,186,719,170,593,500,701,155,846,177,883,559,525,60,706,852,120,330,999,576,938,56,459,822,817,165,798,116,718,51,735,168,712,903,668,910,621,184,692,714,624,66,746,648,409,108,285,472,470,730,368,195,679,15,295,95,820,90,68,112,246,731,598,769,969,979,807,346,820,886,630,358,905,463,948,586,816,523,122,876,235,68,23,784,900,479,592,690,240,512,335,84,222,70,847,333,932,359,508,786,982,463,380,168,1000,658,418,241,507,577,112,343,613,827,19,37,222,735,199,106,17,928,910,754,496,257,638,328,461,681,569,49,31,828,438,395,484,641,306,97,115,951,937,422,97,429,148,368,576,256,992,258,448,66,102,100,864,696,336,78,755,986,251,328,279,646,658,811,20,294,742,67,786,35,265,75,926,927,854,338,930,45,373,16,645,934,330,796,250,306,788,313,161,252,925,463,390,942,214,7,928,5,653,77,644,394,352,443,669,793,217,100,476,574,354,615,492,987,667,385,912,778,183,24,219,836,480,291,931,190,319,679,121,856,763,68,682,923,435,164,35,628,76,805,797,899,104,566,646,922,402,776,735,559,724,92,558,162,312,82,888,886,523,591,129,863,712,986,412,383,333,557,966,242,14,378,135,767,483,612,372,827,224,967,151,459,675,319,342,988,434,857,569,531,983,270,103,401,740,332,17,707,675,569,589,501,854,667,803,118,355,806,404,415,841,265,815,155,946,692,457,543,276,414,859,743,364,554,874,623,614,553,308,59,343,539,294,412,101,976,387,238,354,94,494,13,204,468,599,84,629,133,734,560,684,39,730,563,97,218,512,525,915,52,172,689,511,394,472,79,412,556,623,78,684", "444,440,857,708,211,27,223,407,279,73,742,424,720,717,762,967,93,596,830,992,318,95,93,930,135,0,392,530,608,328,271,341,90,140,472,212,167,781,718,147,197,993,337,764,233,377,70,102,425,306,970,951,945,636,924,752,167,867,901,265,581,739,891,25,734,46,598,521,348,95,142,667,357,879,30,609,946,53,263,766,314,539,625,877,111,59,637,929,336,844,653,503,732,866,832,657,829,413,245,973,781,739,187,50,40,589,140,390,967,787,800,551,817,906,388,381,582,245,543,981,2,372,612,111,950,837,566,659,23,679,344,654,850,491,870,237,203,850,107,327,586,731,452,550,810,451,167,72,907,497,670,26,554,396,308,720,307,199,654,721,418,409,826,962,787,729,702,906,600,679,643,976,756,804,197,361,504,450,758,133,998,168,881,753,17,798,608,441,296,783,735,702,991,787,460,720,392,433,678,824,238,91,982,872,56,832,729,903,445,113,486,578,287,474,338,133,933,400,619,809,694,670,818,30,184,136,955,632,996,141,434,292,69,542,565,883,925,46,207,663,611,381,394,875,119,517,327,416,460,766,296,287,571,461,265,655,752,716,377,244,938,404,47,952,460,338,771,787,815,733,453,111,895,484,523,582,692,390,219,526,830,227,893,881,246,236,167,68,566,194,687,866,439,767,373,513,85,303,665,58,885,796,209,188,54,839,363,554,585,238,769,424,271,195,687,854,255,490,906,524,669,865,231,988,607,930,36,384,247,965,283,422,542,124,88,406,255,926,407,586,87,906,390,971,359,313,318,155,102,517,98,238,888,284,628,212,860,206,461,598,320,147,383,90,516,660,2,934,640,238,315,187,586,603,642,511,85,794,58,958,520,936,712,345,763,234,345,798,194,447,194,323,920,932,988,26,122,923,856,128,908,793,394,593,536,591,182,682,562,769,886,953,798,464,492,840,344,838,450,499,475,874,874,231,285,874,90,359,560,382,907,266,918,93,70,854,406,70,277,635,294,313,363,313,846,943,782,4,9,250,699,235,357,954,275,797,5,933,542,117,687,790,854,895,686,482,794,835,999,120,18,160,274,855,119,84,519,800,573,207,481,68,789,927,670,741,803,47,279,216,493,222,238,140,447,447,995,200,253,188,964,296,598,924,849,303,846,943,845,701,542,670,765,545,716,807,434,707,247,326,772,49,679,785,893,685,261,373,960,156,325,215,958,101,385,530,164,236,696,178,634,12,466,918,606,280,887,148,189,416,142,418,748,619,638,907,911,366,288,658,528,939,243,450,766,23,793,838,862,322,454,516,90,960,743,797,841,407,370,468,9,176,160,568,809,752,471,968,735,158,368,695,703,570,420,957,512,854,819,167,894,215,527,374,337,283,539,52,133,715,821,661,384,187,914,386,484,738,995,869,166,604,662,483,416,198,971,719,311,972,166,428,115,931,431,339,55,839,933,191,378,693,673,67,25,618,81,673,297,243,678,272,330,958,617,289,912,775,550,526,187,915,106,983,604,768,750,633,136,389,887,301,689,586,705,317,729,656,611,845,454,294,12,393,562,117,90,258,392,96,114,403,222,3,428,621,353,150,496,940,59,730,576,45,981,546,332,110,471,998,623,187,487,296,26,683,280,474,983,125,455,566,966,371,502,835,19,706,454,835,588,201,324,586,504,173,426,579,620,481,969,526,65,958,14,582,145,282,343,744,570,299,529,989,449,709,245,807,665,279,830,450,319,46,428,840,695,710,496,445,129,343,749,926,31,484,676,432,961,205,547,314,171,109,189,766,969,851,952,492,373,843,163,493,370,341,461,210,862,332,941,613,200,409,973,902,51,541,100,147,307,10,494,651,825,399,93,124,450,417,165,866,108,190,189,808,394,23,399,883,87,883,189,432,74,703,634,512,156,799,1,1,131,725,697,738,984,166,24,520,562,21,535,878,40,86,554,255,233,932,478,758,448,21,152,665,734,509,499,963,373,626,801,74,688,836,185,803,185,884,788,88,17,710,111,92,518,172,798,28,474,983,458,207,890,541,252,319,710,151,140,522,601,241,74,426,295,371,474,674,130,691,29,180,156,875,778,247,771,358,569,742,638,112,511,979,819,569,869,719,344,531,783,752,430,843,360,89,852,475,223,907,521,133,77,229,548,279,961,680,612,221,782,715,904,7,620,850,639,244,136,448,186,747,885,560,414,906,228,667,510,228,197,563,650,833,672,333,763,548,872,400,699,948,917,61,814,222,49,558,944,67,664,857,71,722,894,213,9,438", "396,863,820,85,368,534,556,370,915,736,913,774,555,659,744,804,409,718,869,980,521,64,216,962,511,392,0,900,77,745,968,52,97,341,18,418,53,305,301,718,621,641,566,324,468,154,792,470,65,824,547,889,90,460,677,734,40,640,368,168,156,661,579,260,273,700,600,204,844,449,907,905,134,58,955,818,578,195,675,417,236,192,418,659,238,928,360,824,133,127,584,722,992,108,382,987,160,340,478,396,849,486,533,802,608,827,71,385,471,370,912,284,30,306,928,144,773,328,959,458,356,211,153,743,702,658,432,64,251,741,105,54,36,969,972,388,874,833,433,970,263,582,365,131,300,222,15,167,315,733,156,181,757,221,494,933,32,537,61,53,293,784,234,365,155,388,439,16,15,217,974,171,282,547,884,937,902,652,173,597,564,569,493,735,47,144,474,291,454,24,619,846,257,878,116,512,131,299,776,783,783,307,225,187,724,827,310,341,21,852,941,864,447,417,410,152,194,575,265,747,529,788,563,913,614,94,80,148,629,93,72,289,694,813,811,150,393,13,467,993,102,885,908,184,688,615,357,145,102,64,361,316,468,408,862,975,211,117,918,847,34,210,776,431,121,598,541,364,928,668,483,327,704,527,337,57,400,3,868,725,537,687,969,355,141,434,198,301,843,918,288,405,275,264,674,468,166,327,900,83,614,861,534,166,528,914,528,334,515,753,812,684,275,526,677,279,248,853,877,341,419,651,363,705,170,792,887,621,743,119,701,275,52,517,618,729,777,228,495,751,616,786,920,129,966,949,560,98,81,883,815,103,493,53,764,188,935,859,758,539,659,38,220,825,865,466,212,892,322,992,334,648,727,828,481,556,54,259,461,276,273,708,517,69,224,193,625,951,54,204,476,743,687,55,507,567,222,155,372,298,592,352,767,383,351,102,679,635,841,199,677,882,262,530,412,428,664,233,391,490,620,626,354,625,997,105,326,479,811,465,92,526,601,79,249,399,11,505,886,573,919,564,295,911,852,934,587,181,150,108,327,810,440,692,178,707,908,999,69,39,340,662,45,64,526,967,446,564,530,4,552,170,169,408,482,71,641,988,276,463,460,428,958,86,100,220,915,797,447,827,681,707,923,745,897,663,645,538,208,70,124,715,535,95,408,578,985,557,689,219,977,765,189,480,811,682,579,611,200,450,144,762,238,125,861,232,753,930,35,504,572,440,733,812,832,11,913,675,306,101,848,978,263,157,693,829,505,492,301,633,362,810,857,272,764,392,741,18,591,618,809,270,950,881,789,820,165,14,198,405,968,908,921,869,509,33,793,384,899,810,238,77,612,223,176,442,33,703,119,591,255,67,997,154,129,409,492,252,300,205,729,341,663,368,606,572,807,801,518,135,646,154,767,572,64,297,346,238,997,940,369,351,655,8,21,981,280,888,266,338,320,585,635,990,571,944,378,448,768,616,77,337,287,838,695,521,479,623,694,716,14,607,185,675,491,480,809,942,228,322,67,65,266,323,530,38,889,703,859,178,491,439,347,168,876,362,751,831,296,73,994,485,859,654,312,414,386,226,544,462,644,667,704,346,875,741,167,813,184,549,628,714,589,785,270,778,212,606,495,886,500,63,224,736,940,197,650,339,922,964,160,480,824,347,158,643,632,528,287,892,133,501,264,641,961,187,836,427,287,694,390,810,111,781,677,867,14,56,431,599,115,341,786,990,884,630,896,20,201,295,655,253,281,370,281,988,567,629,648,430,591,624,613,117,479,587,876,554,219,607,348,761,396,963,682,184,108,742,890,634,231,954,418,138,19,290,481,460,485,107,564,719,932,463,890,331,622,241,155,105,789,319,144,690,217,271,180,732,786,886,879,575,375,502,953,937,593,782,38,665,927,110,375,422,698,291,279,27,779,411,350,603,895,811,894,434,234,597,850,784,722,913,518,495,862,942,451,44,246,22,526,121,854,836,954,749,678,195,972,201,976,794,660,691,203,642,301,457,923,453,826,233,701,734,331,862,923,164,189,316,844,214,499,867,822,856,489,768,723,55,776,767,928,609,543,175,265,754,856,883,110,489,352,266,747,11,293,273,286,757,820,592,563,534,304,416,810,471,547,572,932,837,427,859,18,626,766,859,809,655,639,109,15,57,592,991,176,745,930,929,320,756,634,807,115,738,847,748,29,941,712,723,31,88,214,64,274,716,392,486,948,419,575,482,861,467,149,106,468,562,566,798,31,373,325,492,30,338,519,296,755,175,875,740,570,945,753,250,919,756", "95,46,971,803,206,980,268,771,63,131,352,63,110,520,354,163,442,189,969,200,261,826,408,128,388,530,900,0,492,882,490,660,480,216,925,575,165,974,995,391,559,338,861,311,617,37,53,659,525,153,516,88,746,365,255,772,67,175,677,690,544,857,607,617,767,644,882,454,293,696,937,892,183,611,575,839,23,150,472,123,987,735,918,18,369,51,589,281,357,637,359,294,996,953,117,664,39,792,786,627,720,259,522,994,337,159,302,746,35,642,305,488,191,534,177,709,7,718,443,21,734,858,543,945,661,111,486,209,496,426,686,140,549,197,736,551,308,368,133,666,48,113,317,917,496,11,736,489,173,399,499,643,448,62,673,496,205,352,949,209,555,154,958,761,314,477,278,213,435,600,339,173,84,322,623,22,708,240,570,381,892,397,127,687,584,674,259,204,785,203,529,807,618,869,230,337,705,647,484,289,555,867,940,676,333,552,727,17,424,79,377,13,374,75,873,358,152,631,587,875,691,446,764,388,396,712,211,23,187,582,774,730,916,623,721,784,787,705,880,493,544,768,619,755,299,299,833,76,906,372,596,289,59,627,265,909,552,131,62,540,978,697,958,102,875,71,377,344,237,672,953,551,983,122,382,77,573,473,626,768,462,32,419,639,417,809,203,647,945,716,292,634,646,628,631,97,774,556,581,204,742,479,448,944,514,288,385,399,787,179,611,258,481,368,756,381,364,425,546,885,894,869,959,473,499,683,729,884,902,523,494,482,241,552,410,42,645,10,736,7,921,939,248,141,909,754,830,708,795,862,698,602,616,514,528,624,480,988,433,250,540,804,185,223,884,42,294,104,983,979,69,32,907,237,890,613,203,25,463,166,48,860,297,714,799,871,621,451,937,556,761,381,206,338,939,912,675,659,989,312,106,979,125,399,541,887,802,77,322,601,550,81,474,310,345,120,156,917,37,238,933,108,485,351,985,113,804,109,599,901,844,540,883,807,934,193,515,741,515,2,624,781,138,883,355,373,63,426,759,41,484,671,616,187,969,408,160,790,356,29,650,525,52,529,7,196,461,174,612,561,1,415,182,129,876,583,697,194,610,346,764,14,935,692,867,513,710,726,610,520,78,530,684,515,761,378,859,19,856,589,143,306,733,419,348,39,635,824,383,234,450,382,684,309,622,671,68,859,39,41,348,971,251,57,109,956,127,985,560,773,651,444,748,881,704,951,940,30,765,88,588,720,310,242,896,607,367,894,887,569,440,333,239,825,794,211,569,774,986,818,262,832,466,910,144,655,415,601,118,119,470,559,500,161,967,259,34,141,594,903,379,529,277,407,604,198,594,561,129,455,809,887,939,705,998,915,839,794,280,819,927,343,172,191,881,68,578,850,966,399,302,194,815,534,968,956,607,134,557,383,979,105,522,814,551,699,979,252,737,42,395,798,587,554,71,529,797,761,684,66,520,996,302,87,762,501,892,149,11,2,200,266,868,568,497,407,387,95,954,625,620,340,151,704,671,724,237,463,600,503,627,851,258,496,856,143,625,414,749,504,320,229,335,234,1,850,518,286,730,803,2,40,458,457,638,78,670,404,461,242,881,20,345,199,777,834,284,863,420,531,163,985,197,414,58,850,897,837,462,893,713,120,516,454,284,721,715,137,119,448,193,349,544,162,501,501,511,827,837,350,347,427,400,230,451,678,279,716,821,879,908,773,30,268,855,754,596,701,557,713,952,932,386,11,682,919,178,535,102,827,908,988,138,203,267,766,994,547,699,702,266,424,206,263,785,316,782,335,834,521,898,442,371,437,163,509,638,858,895,463,55,813,913,645,887,860,897,275,370,990,775,824,239,775,726,979,914,890,822,883,616,135,524,613,241,370,519,876,662,192,123,841,483,165,478,945,711,146,16,372,508,878,427,758,932,537,627,331,246,575,262,496,471,201,503,824,756,350,958,540,146,422,175,775,634,789,969,944,847,261,358,806,629,666,96,982,270,63,939,758,515,653,840,520,440,999,584,768,26,34,767,601,623,570,995,8,888,211,775,147,437,691,633,49,407,716,49,387,220,855,789,258,821,148,684,797,444,629,63,776,894,255,445,887,51,819,129,476,890,540,732,357,526,670,463,42,624,137,727,269,646,300,945,168,122,28,826,477,523,11,800,448,181,764,871,178,758,49,901,233,96,213,878,306,2,537,899,393,861,533,572,504,923,713,393,113,420,767,832,181,5,833,995,657,845,565,615,398,787,288,659,179,626,723,142,972,722,844,469,264", "446,325,750,595,811,462,898,674,722,573,841,352,194,184,512,336,485,487,534,957,165,727,976,274,733,608,77,492,0,383,129,57,115,794,896,829,523,476,567,959,492,596,239,16,265,809,732,470,156,464,66,480,332,55,412,873,600,123,658,25,157,550,202,615,371,574,461,425,659,412,548,161,161,287,160,969,617,516,450,605,718,571,725,322,222,250,787,600,606,51,898,594,843,917,789,174,486,914,698,218,315,589,757,961,663,875,573,665,556,212,323,736,456,566,37,723,662,953,613,751,162,227,431,233,863,595,353,53,908,645,710,241,28,681,337,661,356,348,815,438,444,860,570,20,33,638,322,717,812,351,276,920,717,746,603,79,274,43,3,201,210,758,436,141,899,708,979,627,280,645,784,743,492,285,95,268,990,740,721,465,292,738,621,329,389,437,837,223,178,899,708,708,511,295,101,580,504,562,168,815,471,841,151,337,879,442,650,949,271,211,593,522,37,229,765,675,26,313,895,293,458,235,414,405,501,528,377,257,952,887,908,769,206,239,883,974,383,497,907,824,384,966,477,630,958,57,62,87,274,550,963,993,71,970,655,724,769,247,628,541,48,275,357,831,135,797,827,426,334,291,621,78,635,411,988,590,445,392,431,364,987,338,468,173,237,125,557,769,291,231,866,20,808,473,726,177,556,349,801,770,712,611,274,353,560,550,98,240,177,362,209,682,305,461,495,921,581,61,427,770,238,243,719,619,597,3,330,825,232,424,107,799,332,867,424,907,274,805,929,534,631,159,841,762,688,780,131,725,798,287,766,115,46,664,509,882,310,55,670,512,464,951,4,409,320,742,843,919,13,896,646,958,260,256,341,772,61,846,186,528,391,983,291,16,776,805,49,715,639,965,310,344,358,732,190,185,75,798,907,697,577,924,460,446,130,107,874,360,912,84,286,33,726,102,919,910,306,815,860,942,789,710,545,369,34,659,893,797,879,517,967,13,946,361,652,296,738,975,512,394,88,192,61,655,382,885,355,856,482,935,310,228,455,288,92,721,14,329,587,928,78,162,9,117,948,526,348,979,107,932,406,107,59,861,793,165,811,539,344,377,394,439,812,441,992,969,160,562,24,386,911,550,299,547,189,499,412,351,921,282,497,357,173,548,815,778,657,720,956,57,526,264,925,647,612,882,470,248,628,239,133,729,281,530,143,388,433,628,768,294,724,213,945,145,885,239,150,305,315,932,644,726,97,671,381,431,354,17,278,940,498,460,56,919,455,491,1000,744,32,349,529,121,238,690,184,611,386,817,209,114,104,750,810,599,631,394,774,44,240,351,380,493,806,897,197,708,325,597,474,279,924,319,871,57,773,296,888,438,760,860,264,889,384,675,286,282,783,781,33,237,827,125,660,28,539,843,415,282,834,826,660,621,577,39,283,439,380,511,756,856,374,616,368,496,888,884,584,80,610,221,899,604,25,416,476,775,613,505,133,40,758,363,632,109,2,292,431,754,994,885,65,794,328,787,960,780,892,834,209,677,431,359,374,694,352,559,9,246,780,33,119,444,710,610,28,366,156,391,251,259,18,901,114,83,85,383,960,90,577,910,441,575,255,901,991,254,247,577,97,563,76,854,554,976,863,769,157,954,104,553,485,842,334,808,371,726,625,465,30,674,538,774,872,391,950,53,127,407,734,258,913,817,117,969,761,935,685,398,111,566,172,873,591,407,814,980,469,239,10,635,339,245,892,900,654,313,910,602,511,483,326,778,487,623,448,160,229,898,343,94,474,734,916,155,372,978,840,684,257,295,141,964,712,26,872,851,829,553,363,572,801,972,203,124,247,993,781,536,759,538,994,249,653,353,485,575,367,268,620,777,647,851,802,378,970,830,753,731,622,228,321,579,761,637,854,928,627,722,270,784,693,50,607,34,757,899,232,415,784,796,299,80,193,627,478,402,982,990,95,308,149,461,576,434,609,146,687,2,308,209,958,440,61,808,141,687,385,290,735,564,629,840,852,698,981,739,230,195,953,456,81,637,275,714,951,67,764,445,783,143,972,428,120,599,789,271,626,253,170,551,699,608,152,430,693,509,188,319,198,847,536,337,575,803,375,944,722,101,228,161,746,235,123,652,971,857,247,971,947,742,142,598,248,958,679,254,77,723,999,176,589,429,523,748,398,618,914,814,749,114,539,955,564,511,994,59,859,441,546,549,342,401,475,836,151,182,360,999,676,750,297,154,374,558,206,425,315,817,474,999,375,765,354,615,824,510,200,475,860,851", "86,418,652,15,700,713,611,426,811,120,518,484,684,281,654,640,233,11,5,281,483,77,798,555,119,328,745,882,383,0,806,714,266,69,179,807,425,846,564,334,148,810,112,360,273,168,723,779,511,273,761,417,813,184,955,183,592,912,48,14,777,968,274,799,314,56,563,488,650,887,162,697,487,726,431,332,510,412,92,215,347,858,459,169,208,899,615,522,322,9,663,351,174,547,524,774,66,935,563,511,532,816,238,297,570,455,180,596,541,629,180,169,986,749,471,423,564,10,117,149,858,617,681,82,534,286,183,396,404,986,517,112,147,874,64,542,323,661,149,88,520,814,621,134,855,29,429,127,938,920,758,980,985,236,44,748,730,783,915,654,30,800,768,27,407,184,641,90,637,653,291,579,372,187,731,514,201,526,254,418,458,601,31,30,194,582,539,345,759,95,563,765,416,849,512,864,221,351,194,91,375,228,424,983,388,807,279,521,318,697,625,710,937,959,58,686,387,750,582,532,433,342,269,592,612,84,80,683,745,654,253,855,427,841,527,573,818,1,122,276,141,377,225,911,804,568,952,355,844,937,441,678,129,128,813,688,697,438,601,187,154,819,718,366,604,189,44,912,956,30,661,152,346,431,420,275,670,708,977,86,375,749,344,544,452,75,394,977,705,329,881,856,495,955,744,462,172,34,12,296,139,189,92,336,531,951,485,362,436,356,513,420,285,890,268,947,852,555,176,593,793,777,636,815,936,427,309,218,149,695,874,585,731,441,458,924,606,592,763,653,504,318,313,438,859,956,904,258,917,192,118,809,524,157,912,268,627,79,49,449,840,727,781,514,349,25,282,764,971,740,351,307,315,782,236,742,138,362,516,306,588,40,996,835,153,746,713,705,855,624,34,877,251,350,261,816,486,686,657,940,466,222,255,419,823,944,226,74,916,916,343,118,692,965,501,533,737,32,156,671,220,666,551,984,613,308,306,308,873,274,321,532,919,266,311,596,171,68,757,949,483,22,446,251,860,519,992,431,249,153,479,16,948,542,301,326,166,685,132,858,635,789,789,112,884,340,637,958,394,433,184,443,901,821,699,174,596,648,487,977,845,781,865,32,343,177,823,115,461,780,548,268,83,458,468,349,591,705,689,713,603,37,764,913,18,698,282,10,557,932,44,763,326,892,557,42,863,136,680,592,292,232,65,788,146,283,331,512,291,640,613,593,845,729,272,870,953,298,223,351,493,762,841,306,925,16,753,271,323,13,435,622,392,477,835,367,20,293,912,857,761,294,302,35,706,520,574,896,259,367,527,423,781,387,233,260,727,224,255,422,655,126,666,465,617,554,420,53,670,178,210,186,597,186,983,772,474,690,583,802,290,49,558,232,260,962,195,615,885,799,575,582,190,581,556,703,52,758,967,416,386,742,801,307,936,49,33,20,842,935,570,14,420,572,254,307,99,730,561,220,204,814,793,234,293,377,643,148,207,415,471,398,400,963,484,288,4,295,477,330,160,403,776,537,813,569,762,77,985,586,341,884,371,381,300,351,510,902,829,183,374,364,527,80,503,938,970,149,977,453,576,432,414,756,543,424,217,275,460,280,122,227,140,64,691,835,478,117,943,286,600,458,491,904,843,480,893,922,44,55,516,356,307,463,196,364,36,291,965,457,22,479,248,229,742,79,351,396,522,335,716,509,712,648,912,428,601,710,210,531,2,992,289,246,230,759,98,438,59,113,778,760,622,298,308,996,302,17,899,541,618,43,675,83,191,949,946,365,756,599,479,931,682,667,366,644,543,858,362,487,569,935,620,692,486,703,322,566,458,470,938,748,35,25,874,654,983,489,168,602,462,732,656,401,204,93,466,14,59,339,542,108,439,839,525,775,737,366,40,827,629,435,257,140,176,426,224,378,330,440,760,931,75,584,806,382,769,534,155,38,185,49,970,13,683,918,328,343,891,219,92,822,179,553,554,431,249,405,888,284,490,901,388,963,838,655,618,439,282,95,206,749,276,761,876,92,32,604,543,498,63,887,907,415,534,587,896,714,884,837,215,975,848,159,298,662,273,314,909,767,885,314,347,442,72,959,793,316,160,735,735,302,838,618,43,619,562,961,578,225,948,743,235,874,4,952,463,240,532,577,128,276,66,328,68,351,768,810,970,917,157,670,385,290,920,446,614,928,532,80,789,604,952,584,94,449,683,470,582,84,81,603,62,940,967,256,36,965,204,487,667,842,431,552,601,768,332,27,563,642,996,198,319,425,99,541,396,347,216,423", "397,304,904,973,708,488,385,505,624,403,392,122,590,506,425,427,729,264,142,761,239,988,427,24,454,271,968,490,129,806,0,500,19,949,953,345,971,962,839,732,325,290,11,445,78,904,992,30,398,35,59,817,89,224,157,955,876,736,232,567,492,30,241,888,678,871,753,546,449,666,408,803,937,332,314,213,694,594,295,294,765,436,143,496,495,683,463,49,574,516,610,266,751,672,385,367,781,267,425,123,737,548,957,24,705,750,685,267,550,933,173,285,953,269,406,218,625,702,726,258,854,738,383,193,523,879,350,895,550,279,448,194,89,391,527,118,51,644,296,715,523,535,731,861,878,356,171,899,782,944,520,879,739,626,23,656,643,121,318,457,92,152,794,422,424,712,858,906,65,813,283,773,790,542,531,670,555,125,76,297,277,112,630,676,411,281,869,973,548,108,549,226,185,560,344,760,491,433,776,630,574,287,447,674,903,381,747,187,811,185,985,302,70,765,261,838,133,993,275,286,461,694,562,430,632,848,334,163,262,156,146,764,631,153,146,554,860,110,128,941,660,109,676,609,187,217,796,455,115,707,514,199,383,769,488,440,440,5,680,79,338,161,809,153,940,125,290,841,505,220,913,299,349,416,545,5,3,494,628,469,948,741,860,170,126,792,383,897,27,497,152,572,86,36,631,342,905,536,217,474,603,597,371,777,399,997,70,813,869,680,408,454,58,481,810,735,377,813,644,760,275,212,943,673,167,417,936,424,391,169,502,230,727,813,745,855,109,563,711,33,555,651,599,866,879,586,61,269,926,260,468,713,845,394,651,806,552,948,899,307,698,718,595,312,807,849,124,860,788,911,742,703,828,607,200,870,662,955,93,194,559,271,332,303,320,323,813,550,234,961,331,56,594,260,658,232,856,806,898,31,394,445,462,491,705,113,857,518,862,349,328,550,841,860,618,330,998,414,400,939,353,994,123,992,983,906,631,971,188,875,34,717,77,693,559,790,725,225,499,34,400,662,845,734,752,537,269,534,749,690,798,523,877,712,568,635,197,789,294,809,710,752,404,784,461,443,894,53,696,550,835,310,291,704,560,895,36,98,569,542,92,399,986,379,596,586,114,946,758,613,303,879,753,437,631,702,779,788,712,537,997,917,716,684,159,748,176,151,496,90,700,437,723,272,943,188,670,239,294,195,410,105,784,402,149,737,29,904,593,240,679,428,335,862,126,921,511,293,556,191,526,215,769,255,421,337,521,368,526,496,81,747,457,488,912,557,597,277,234,600,390,994,438,872,960,168,349,230,946,945,874,999,22,914,194,503,808,755,761,543,384,530,247,225,685,674,321,593,175,481,556,451,955,570,264,747,98,470,56,829,957,678,76,648,627,82,654,721,171,46,133,702,955,816,294,734,952,584,106,564,221,915,760,635,35,148,672,95,851,807,579,833,648,14,541,58,665,80,636,613,115,517,48,146,524,794,185,695,220,391,157,808,322,717,734,701,893,740,834,906,48,619,56,279,556,161,426,81,90,909,816,802,29,514,883,476,391,233,329,597,3,721,279,397,262,438,181,218,914,4,275,123,384,950,97,762,198,98,557,284,927,205,87,432,981,924,137,14,33,623,844,471,271,482,749,701,464,225,859,538,750,417,963,459,643,104,183,459,563,397,452,800,574,16,647,611,125,759,656,204,433,823,183,237,143,530,799,241,584,952,591,989,148,955,36,259,831,896,981,436,858,117,941,209,31,904,388,782,982,365,254,394,936,381,581,179,105,101,270,582,995,180,44,249,439,833,307,495,434,812,253,868,546,429,965,613,399,411,240,646,850,586,173,503,686,150,443,83,749,424,905,532,507,174,679,699,592,630,255,722,397,200,343,968,553,751,558,859,495,848,607,402,700,615,126,825,336,422,486,708,838,43,66,287,84,766,138,840,339,184,638,366,885,705,599,782,950,618,666,542,873,437,215,450,566,87,155,710,676,644,820,535,678,43,583,786,337,94,32,148,777,958,409,157,412,138,668,773,812,522,98,732,265,902,937,204,777,21,874,829,171,609,331,828,325,635,567,611,988,661,453,93,708,603,629,904,964,759,278,252,832,809,776,632,860,822,995,173,817,952,519,352,764,852,516,481,691,429,471,684,968,767,384,207,286,208,950,537,133,371,573,704,585,146,745,949,959,598,345,702,747,32,955,55,544,25,422,102,287,842,554,108,807,905,163,706,804,144,76,463,641,642,591,980,922,764,875,968,154,768,925,205,156,984,474,227,499,518,946,653", "893,904,223,375,271,755,74,434,517,566,982,756,158,575,493,233,548,597,574,131,417,67,620,852,770,341,52,660,57,714,500,0,126,276,671,125,556,179,628,311,665,594,340,115,195,834,240,860,740,164,145,473,502,670,332,922,645,981,296,286,786,838,389,175,673,803,246,587,725,687,82,935,486,615,778,216,402,237,530,570,759,474,338,513,217,949,914,682,736,813,467,541,248,29,14,794,895,66,34,549,523,545,32,3,669,157,824,271,192,210,283,324,375,724,339,96,833,252,15,311,587,663,328,258,236,328,991,407,19,514,730,871,415,631,167,986,812,450,235,902,804,563,620,192,481,528,470,403,605,897,850,649,213,694,683,350,630,385,311,220,486,31,477,535,398,285,688,98,407,710,949,305,879,395,559,648,780,797,323,524,261,853,233,312,896,960,693,450,144,74,739,614,318,663,82,781,452,648,304,701,798,610,89,347,821,538,182,102,544,857,634,983,967,53,108,983,512,284,795,128,880,443,334,37,172,197,561,663,26,196,911,121,768,930,856,379,87,866,831,517,489,332,301,291,340,474,355,541,59,974,164,991,851,599,230,285,992,158,858,32,248,793,91,559,294,126,893,791,74,972,379,812,328,682,815,995,484,538,292,334,681,381,938,460,728,373,547,395,134,300,560,997,110,932,611,464,675,117,396,171,176,320,52,40,854,144,792,410,122,247,91,289,824,921,579,532,971,379,729,941,48,115,548,905,568,768,651,582,808,505,641,205,399,607,439,138,354,836,276,6,914,995,468,721,97,884,853,603,295,519,958,344,625,252,297,619,412,211,532,287,829,847,452,612,50,729,683,995,875,365,882,886,919,93,23,141,94,345,428,741,530,619,490,12,545,165,42,174,67,232,249,203,33,936,489,596,139,435,677,83,612,186,188,450,533,194,711,371,341,715,927,767,217,566,750,46,632,113,729,983,283,559,192,28,674,955,315,285,919,980,398,518,159,894,358,595,539,967,828,329,980,831,117,945,789,194,17,71,346,433,920,377,243,644,26,38,538,546,601,682,986,643,700,396,510,524,601,48,269,598,445,496,37,279,210,15,446,698,133,4,745,457,31,462,146,459,425,962,251,452,910,986,451,919,429,387,151,655,323,106,833,276,145,251,950,884,156,25,798,302,432,640,914,458,172,671,459,682,767,144,217,440,397,185,581,733,15,204,253,552,543,773,718,918,713,122,936,35,406,931,614,884,774,195,94,854,607,840,22,834,396,917,315,536,371,943,43,496,967,71,971,101,271,55,126,426,82,616,61,263,498,640,987,630,145,162,811,472,101,365,688,931,91,195,442,994,219,319,202,524,141,161,45,862,162,977,999,941,153,420,203,192,820,505,792,698,548,17,616,647,477,696,168,709,949,679,681,948,248,585,895,238,743,590,822,394,644,154,348,454,173,635,992,876,91,676,951,880,617,399,763,653,848,460,527,641,529,585,963,347,474,747,577,501,376,70,787,383,675,874,131,402,865,480,919,258,951,136,729,557,550,127,415,282,501,526,907,466,108,897,731,206,148,448,849,507,26,656,219,115,673,119,814,693,726,290,653,419,58,823,593,241,36,293,724,690,77,438,283,353,746,70,485,625,825,241,968,123,962,854,146,80,200,55,978,830,794,143,402,518,451,96,689,541,834,978,520,223,554,858,632,484,794,152,392,80,389,578,397,119,397,490,514,535,556,569,826,208,741,276,790,291,78,793,606,72,445,200,158,997,623,249,992,491,967,223,994,909,303,833,868,381,336,230,186,289,918,304,288,847,444,7,264,228,397,309,473,394,911,780,468,887,787,286,658,537,881,956,980,380,845,988,406,494,170,556,479,482,437,773,252,901,490,890,415,697,760,652,101,219,108,773,705,283,946,813,974,631,995,901,267,734,44,173,962,479,398,967,669,543,115,871,114,434,357,797,28,549,258,558,223,139,155,787,641,820,594,429,678,97,272,861,648,264,829,845,696,837,715,58,981,607,807,4,812,622,355,856,651,512,659,291,766,450,474,745,994,638,853,829,803,482,86,523,26,856,8,819,995,463,305,510,625,111,306,331,75,851,143,346,704,640,129,968,489,998,757,573,673,339,137,110,667,939,115,653,248,2,666,78,787,541,236,364,85,793,266,182,156,738,581,445,523,969,587,647,493,346,214,793,675,447,782,431,105,351,363,571,456,832,496,509,736,440,982,292,960,319,444,772,16,922,851,405,502,940,149,252,529,402,960,323,739,542,466,972,390,668,38,22", "56,295,132,674,620,518,864,727,195,346,264,55,346,658,763,478,200,427,324,916,828,57,229,567,527,90,97,480,115,266,19,126,0,897,271,659,573,383,611,885,405,848,699,379,648,93,218,473,398,771,379,679,342,853,453,121,443,371,767,882,808,573,42,862,473,453,891,955,227,958,102,81,139,887,666,6,782,837,780,548,663,337,610,557,69,129,488,336,920,66,463,93,195,681,866,349,259,754,100,334,815,969,537,934,528,28,721,574,947,459,657,232,663,672,221,44,226,805,953,195,672,191,493,975,262,485,958,683,395,507,85,477,188,455,579,602,732,388,620,822,788,93,593,277,721,878,758,237,217,361,815,825,378,109,243,874,804,190,232,467,561,715,234,339,185,150,739,861,406,895,234,275,341,559,265,618,189,70,857,294,457,427,921,629,460,704,621,794,186,78,331,572,794,123,941,728,555,335,474,234,409,339,81,620,450,674,217,751,90,609,888,437,440,994,817,971,261,676,25,251,985,956,366,830,679,913,478,410,878,313,532,132,142,96,359,410,593,747,716,268,932,303,727,851,891,422,139,674,911,312,502,898,551,629,994,328,708,347,324,160,462,870,910,491,994,372,999,286,529,234,26,32,47,483,958,302,12,580,956,370,809,329,835,167,227,396,419,999,552,202,474,260,975,809,852,540,737,561,573,989,23,506,676,237,246,23,62,104,774,893,180,808,96,395,261,602,508,643,909,185,854,944,532,121,406,922,77,571,113,530,624,868,520,285,478,980,276,447,439,918,247,131,690,564,334,511,416,825,150,551,554,205,891,258,140,545,402,334,556,171,330,222,781,926,112,473,547,816,166,341,746,495,168,403,816,395,441,411,122,71,955,796,490,912,744,391,248,535,864,612,358,178,613,651,646,435,479,798,597,6,638,941,559,775,933,469,391,388,950,924,763,283,930,39,847,898,416,37,802,971,346,896,662,68,425,714,855,698,946,564,763,435,102,386,94,475,586,20,660,310,985,637,470,124,127,534,111,140,94,763,234,412,319,61,622,516,212,393,663,305,113,168,797,420,358,764,23,404,17,872,874,459,499,624,718,238,994,353,194,454,142,6,716,114,710,947,6,215,791,151,428,919,539,207,910,184,366,818,445,123,640,486,369,684,601,394,636,807,633,189,813,588,842,580,332,117,169,773,477,244,476,961,866,768,510,121,701,218,405,686,573,583,657,485,886,271,884,669,423,756,749,38,900,163,268,741,795,236,772,489,536,216,596,810,941,945,122,662,55,800,918,179,611,854,791,102,504,718,392,651,838,406,764,28,204,364,614,430,904,895,795,753,956,643,393,904,795,544,836,163,892,240,870,803,533,528,811,122,635,617,274,742,306,242,319,474,404,746,381,853,964,223,154,474,480,411,356,544,562,899,117,354,626,4,898,109,943,940,707,610,780,89,110,14,953,126,136,940,3,181,536,654,42,784,753,583,438,48,512,186,455,980,972,756,737,513,8,331,137,866,979,449,273,817,509,219,174,844,76,974,566,636,22,345,828,577,731,164,602,632,597,654,128,820,185,737,273,726,213,286,138,571,125,195,459,171,27,193,6,603,179,198,360,909,631,478,646,604,826,747,932,156,728,289,743,838,193,758,80,359,967,283,699,962,664,684,782,598,671,878,777,524,15,207,323,137,127,722,63,532,139,989,34,862,489,777,855,737,494,895,63,833,438,985,321,307,491,1000,369,419,280,522,496,930,923,144,496,365,130,878,812,261,709,687,766,3,777,711,382,671,344,845,529,443,211,249,699,772,577,656,417,192,514,633,244,641,121,434,429,144,357,441,273,723,201,817,535,913,910,801,296,166,188,178,237,722,895,15,954,397,24,932,191,254,391,804,905,75,194,356,594,220,600,153,194,892,540,445,220,428,159,781,930,895,176,167,189,700,670,941,488,14,760,793,628,186,736,124,356,80,109,312,978,105,623,314,596,936,856,427,896,627,125,813,585,60,133,702,921,621,532,212,849,945,631,758,263,895,989,513,203,840,726,72,272,226,539,268,557,256,870,340,461,947,165,49,298,731,970,533,253,680,816,224,690,659,596,217,874,58,410,930,272,59,142,909,247,527,78,151,766,337,805,748,708,154,408,991,996,298,908,514,973,994,107,989,630,537,958,437,409,854,564,992,421,90,945,116,585,798,514,854,774,256,151,402,104,400,677,434,884,181,35,623,708,392,797,981,671,944,571,703,630,802,539,529,313,635,315,969,182,143,404,646,542,102,929,488,507,979", "812,948,909,439,26,552,503,207,57,932,47,875,780,880,12,804,876,921,240,499,995,877,638,553,977,140,341,216,794,69,949,276,897,0,406,545,822,554,704,814,512,285,329,674,956,121,655,534,857,147,130,932,814,413,613,609,533,574,517,993,519,46,217,328,427,435,133,32,973,925,796,521,262,915,817,572,427,768,632,986,9,979,986,351,4,264,190,12,482,571,183,857,739,527,56,326,970,857,851,762,200,813,694,950,52,199,140,882,539,825,457,959,687,168,838,505,78,651,860,995,598,567,167,307,42,810,306,720,862,97,952,543,915,349,328,260,888,448,75,824,971,592,958,582,430,383,770,18,751,115,540,947,373,96,307,40,324,99,655,68,883,489,571,954,172,58,523,476,507,247,765,617,360,750,390,580,999,220,503,944,673,521,927,883,108,658,895,336,935,994,680,386,325,247,744,880,404,736,279,931,757,677,95,139,758,125,471,719,153,411,955,886,476,712,687,240,348,753,664,919,163,903,775,804,697,603,107,962,218,140,59,109,473,528,990,515,108,188,410,911,601,722,542,256,423,259,140,355,918,41,463,354,283,634,215,675,934,700,572,571,374,382,15,29,615,839,873,873,451,515,515,747,394,334,660,601,775,21,33,691,437,111,989,314,447,361,126,660,930,782,98,341,209,266,911,589,670,163,146,714,786,541,674,607,478,411,889,774,414,81,225,473,947,316,587,191,139,512,728,112,608,201,205,716,371,448,893,117,704,411,212,199,337,741,942,10,63,613,229,445,164,317,653,137,952,697,641,955,221,760,90,678,421,426,471,996,570,502,912,16,899,404,663,509,589,684,600,975,62,465,780,881,407,864,162,8,680,639,350,961,597,694,421,100,196,561,36,928,462,345,929,670,627,787,918,246,765,792,497,951,110,712,312,276,593,616,264,7,105,844,959,106,258,184,763,869,341,793,262,912,869,817,816,801,443,909,601,538,462,42,192,64,288,941,736,266,124,523,187,905,237,254,207,278,134,83,776,666,238,476,108,940,181,651,858,330,418,882,256,491,466,401,183,178,897,885,803,772,334,154,355,42,231,463,912,600,439,411,150,565,153,76,796,807,287,65,722,403,420,204,795,296,447,948,562,238,121,461,40,726,368,828,944,256,604,438,552,296,302,690,570,927,586,202,28,798,346,962,602,177,814,935,621,123,735,108,333,269,602,887,586,4,130,454,403,260,980,7,102,398,218,323,826,295,341,980,541,378,905,532,535,877,839,849,1000,677,920,946,491,34,73,680,618,78,936,480,436,932,323,306,117,771,400,187,485,762,900,182,335,468,811,991,825,438,554,298,770,878,347,230,28,77,182,54,871,676,647,50,762,312,233,777,858,434,337,34,635,577,545,469,949,357,401,215,850,881,942,937,865,315,861,456,816,577,934,703,220,63,955,91,610,751,355,109,203,272,73,466,395,572,701,829,823,127,524,892,536,484,235,460,708,991,69,633,71,983,657,685,973,116,802,539,127,943,577,53,21,738,327,352,703,250,261,93,538,48,304,6,929,462,462,354,741,621,481,902,942,941,177,36,972,727,575,893,970,326,459,734,215,936,510,724,233,307,885,698,85,577,40,543,594,779,369,671,446,254,222,665,137,608,388,923,958,280,608,763,336,376,415,982,218,381,400,146,410,727,359,218,920,378,716,527,566,387,218,935,315,253,741,378,411,765,862,474,606,340,256,907,767,644,760,238,278,68,388,156,383,529,114,439,561,673,342,211,989,540,985,379,248,3,824,731,685,407,187,622,425,269,774,379,364,937,820,770,330,312,991,895,391,716,736,661,710,45,229,625,459,301,533,612,695,962,34,566,205,44,402,828,502,165,20,996,57,89,404,492,694,136,369,827,740,119,646,155,543,817,557,699,512,542,190,666,878,988,138,135,727,734,68,370,2,720,492,456,38,432,848,244,457,796,877,67,78,854,645,926,370,177,339,752,286,593,61,55,90,787,739,313,411,502,434,129,499,719,655,830,29,183,599,297,903,537,579,531,393,112,177,257,503,710,435,24,394,935,321,742,978,880,663,33,257,873,42,293,337,377,708,49,706,691,143,228,979,972,809,818,657,471,780,137,805,418,987,365,193,755,136,24,624,686,866,302,947,395,93,897,84,676,324,519,375,137,58,94,996,785,880,99,923,489,468,802,711,836,571,762,760,593,534,681,187,190,842,686,941,191,51,679,751,157,260,232,952,60,612,590,607,646,92,752,103,914,842,553,30,317,756,635,69,697", "967,626,607,832,885,134,490,989,654,878,325,305,667,711,396,284,622,151,649,866,62,89,875,386,384,472,18,925,896,179,953,671,271,406,0,352,114,710,187,521,922,379,983,956,176,705,159,602,29,494,890,905,937,977,346,35,73,12,633,805,541,909,534,304,818,730,355,644,826,153,261,98,855,894,863,419,717,379,257,814,582,557,870,364,557,881,950,382,499,578,939,193,433,187,997,673,217,108,396,427,46,8,926,627,366,462,601,621,455,269,878,474,183,315,709,942,767,277,967,502,698,262,332,135,385,23,718,503,671,562,45,712,745,470,95,706,550,386,798,286,634,580,584,596,589,421,815,548,727,276,442,868,760,993,937,296,929,126,256,275,847,6,247,85,180,320,545,200,90,84,161,275,425,553,718,317,700,461,339,554,759,15,972,424,693,571,53,362,988,98,130,926,766,817,865,148,418,993,309,190,382,445,750,295,760,32,915,148,367,862,658,824,364,235,446,384,118,813,456,993,347,536,61,685,558,930,793,500,269,715,327,10,649,618,597,410,785,703,433,832,943,281,518,129,707,744,391,927,489,711,761,698,98,798,263,843,124,800,41,973,341,396,189,146,460,324,176,707,985,410,358,385,237,141,939,658,145,803,781,811,495,613,837,713,981,4,987,645,121,584,164,261,356,423,247,643,234,150,519,627,800,612,998,124,505,640,974,360,675,998,396,516,118,918,546,511,493,64,917,442,979,240,860,632,620,52,827,569,388,514,238,678,977,989,499,574,336,78,199,673,325,728,466,684,48,929,662,425,96,953,768,50,600,806,449,974,935,895,105,568,894,613,653,396,334,226,308,364,240,107,331,696,44,561,153,757,905,382,908,983,488,808,496,215,446,204,532,127,642,182,721,834,31,300,590,974,107,297,976,478,346,809,368,320,29,921,721,470,810,240,944,232,517,351,754,450,900,519,407,847,610,755,710,559,502,796,846,708,589,582,225,864,681,624,8,177,770,924,524,52,190,303,787,78,93,119,559,730,577,305,271,3,842,960,873,171,618,981,177,344,361,963,800,255,569,360,467,194,798,769,957,986,759,257,31,595,52,145,289,391,795,891,686,365,206,223,921,540,689,87,933,764,262,436,585,30,37,711,347,442,608,80,3,919,35,161,375,253,510,732,489,298,120,885,481,831,283,78,575,290,47,287,829,332,559,637,308,413,585,567,324,943,239,976,121,263,217,283,269,471,654,658,559,393,600,558,466,825,413,150,355,575,33,599,909,440,753,400,468,759,824,491,926,499,831,942,994,702,441,811,71,596,95,586,173,47,945,996,901,560,496,682,853,622,672,660,928,841,77,407,878,751,696,236,423,927,398,710,28,540,812,589,532,540,914,260,21,177,99,811,630,229,83,624,684,661,912,429,830,552,875,947,272,329,571,169,894,386,921,16,469,187,321,922,161,335,358,306,209,499,285,55,602,298,499,188,831,457,598,440,62,621,857,915,536,989,868,506,323,875,484,175,297,409,364,10,764,953,888,32,502,334,990,382,293,144,243,411,840,953,176,73,13,74,31,911,893,521,828,306,648,37,722,471,496,323,797,447,149,846,83,586,643,476,978,213,744,342,435,596,643,789,82,196,167,882,900,840,106,334,354,273,37,382,632,365,365,70,627,865,949,567,325,433,848,737,276,284,809,674,690,392,519,654,697,978,96,725,232,551,387,221,331,559,466,249,280,759,843,142,504,265,397,671,319,925,688,141,94,829,49,630,657,953,417,788,630,446,319,555,31,517,717,894,734,757,705,835,858,604,264,694,77,218,303,857,80,878,14,728,922,881,149,455,772,762,324,819,845,435,483,302,754,82,989,574,1,811,933,326,310,742,995,141,418,688,623,187,786,496,470,629,150,582,345,915,708,43,690,871,707,462,521,490,474,749,743,603,264,834,555,480,586,412,44,269,461,912,293,545,982,986,328,484,182,112,546,495,377,661,496,173,667,486,447,117,997,841,753,276,943,82,714,596,436,344,718,609,336,535,915,694,278,504,685,818,719,476,769,513,854,331,41,401,98,707,844,215,909,639,839,883,876,1000,263,137,436,112,827,798,48,304,333,103,997,263,508,134,309,853,134,569,656,70,570,584,42,910,458,253,607,201,48,332,204,342,417,958,583,40,630,417,786,221,798,286,899,553,8,695,854,554,829,41,764,287,353,725,674,751,844,234,669,671,763,100,443,843,556,66,639,242,640,844,382,898,284,968,873,260,105,699,899,381,407,947,739,102,937,938", "40,722,679,866,289,652,891,692,14,9,816,105,911,541,149,994,439,214,478,525,168,355,168,709,286,212,418,575,829,807,345,125,659,545,352,0,310,336,656,507,41,260,375,99,406,593,307,816,240,12,690,244,765,408,961,959,699,532,274,333,241,510,709,631,550,340,107,628,666,492,999,435,386,337,618,992,376,845,652,713,979,824,679,210,388,107,151,436,977,379,701,759,568,457,440,516,479,236,520,525,221,683,254,436,348,60,833,140,116,243,943,938,773,370,564,869,318,236,340,946,633,363,712,745,39,94,701,698,464,121,611,694,872,815,948,577,110,168,382,121,790,590,779,492,871,51,506,48,218,753,295,134,349,94,682,100,707,856,993,481,498,351,245,383,326,46,522,660,303,37,222,413,70,667,818,330,349,643,400,967,963,289,201,245,748,22,177,191,699,726,296,313,526,674,299,123,133,183,321,573,301,709,258,469,762,976,309,719,195,828,762,327,783,926,230,220,474,528,833,292,546,877,742,305,86,445,870,917,75,430,796,204,165,767,745,839,513,495,204,801,823,969,666,255,978,347,578,644,951,918,584,75,702,125,561,408,916,843,515,923,773,262,683,873,162,14,29,340,835,709,59,364,850,643,463,66,584,612,37,496,687,319,736,337,87,656,262,376,186,64,708,836,877,501,101,36,980,733,606,332,140,457,484,998,182,716,479,279,719,751,548,869,911,886,72,497,764,572,907,124,971,598,352,309,1,638,190,449,534,81,9,506,810,628,304,816,563,957,424,408,691,302,990,253,950,167,122,302,487,797,307,634,310,558,64,621,113,664,804,348,518,842,327,119,226,971,623,173,11,423,61,428,402,15,546,569,780,232,425,465,387,2,459,88,943,291,774,639,914,785,659,465,519,393,763,641,893,447,73,615,484,922,41,962,48,447,918,786,928,451,630,483,387,285,280,76,319,769,902,47,631,969,35,68,894,669,527,248,281,199,251,344,457,65,439,888,801,478,293,622,447,929,855,54,440,136,573,551,512,121,319,114,682,131,84,880,872,85,623,859,882,929,135,394,333,397,963,370,311,254,271,885,520,301,240,697,162,920,105,14,113,25,345,466,803,571,931,104,202,946,168,940,466,648,199,6,878,887,219,433,242,693,131,938,278,511,661,246,642,527,296,886,414,44,649,562,614,652,291,583,792,61,960,102,516,947,991,161,560,858,923,219,118,641,852,753,808,303,272,836,830,479,769,557,331,832,256,255,228,668,871,417,370,441,161,32,892,672,294,746,106,524,246,578,783,511,699,267,596,914,227,977,995,513,464,540,274,595,482,685,697,873,89,742,490,511,663,347,110,659,108,99,536,757,180,876,245,310,696,405,359,871,853,994,737,650,431,243,903,964,273,22,505,114,314,676,247,761,759,372,58,511,302,895,104,814,50,435,781,30,831,824,930,716,762,462,358,755,29,420,411,884,573,921,914,813,408,647,646,687,834,968,110,531,46,668,810,866,234,190,602,633,287,437,347,958,183,776,464,914,928,931,772,932,339,822,865,206,633,828,895,7,57,957,203,321,944,720,362,974,381,199,34,825,75,854,792,153,103,827,151,544,580,395,777,3,245,723,911,935,540,219,956,610,264,410,607,253,896,534,64,456,533,112,823,833,423,779,136,593,385,794,855,464,697,626,268,814,595,500,594,40,189,182,813,239,928,684,490,896,128,287,16,233,858,298,532,824,88,252,142,327,132,959,220,758,649,68,480,953,87,846,589,399,430,76,785,223,305,893,44,840,324,399,742,891,256,424,384,225,136,936,763,166,746,705,222,258,406,884,729,486,177,78,622,282,96,605,440,597,961,959,625,706,963,969,827,488,450,701,882,807,782,242,876,277,521,443,395,814,293,419,936,599,5,283,112,2,937,131,544,34,304,318,873,633,107,664,107,977,294,604,751,987,520,906,767,631,520,744,494,753,187,645,934,553,777,872,850,314,264,188,214,466,967,22,9,303,24,369,671,229,255,250,558,306,953,913,75,59,843,523,374,902,739,414,547,597,529,646,370,432,743,805,973,796,224,527,343,621,573,498,975,660,204,194,245,854,974,44,633,380,834,395,655,90,854,307,94,758,246,17,790,630,137,552,487,653,763,929,29,172,482,986,318,224,503,942,580,444,827,369,17,186,373,839,57,954,200,157,377,554,730,795,770,981,128,861,839,917,493,952,295,87,611,880,951,50,908,162,989,851,474,304,986,525,211,353,128,824,599,220,164,802,441,142,826,696,229,476", "229,167,461,244,859,299,805,965,815,187,178,785,951,122,785,373,257,109,379,447,179,338,304,481,345,167,53,165,523,425,971,556,573,822,114,310,0,153,876,804,859,472,364,502,573,351,181,496,790,304,743,367,765,359,16,450,964,328,948,617,440,43,730,703,481,131,94,972,304,414,269,165,66,350,577,165,199,649,204,865,998,953,996,244,239,866,203,723,649,281,749,77,990,905,16,751,620,756,142,673,532,525,582,944,376,463,88,253,161,507,87,681,920,83,256,359,904,330,606,681,744,702,713,805,780,289,988,740,714,88,928,493,668,600,672,907,841,819,521,40,941,558,137,9,327,309,302,913,697,22,793,154,909,879,341,581,955,732,584,8,420,183,193,955,391,79,970,229,928,217,238,856,491,154,195,193,128,842,303,353,94,104,138,267,313,59,702,604,372,487,231,663,525,258,305,723,824,215,248,630,949,831,315,331,65,978,568,978,626,526,935,662,790,843,547,708,607,714,685,983,651,374,258,903,620,565,614,43,408,616,60,201,510,826,23,832,710,36,916,465,853,24,623,646,481,191,343,584,782,737,37,992,12,427,905,986,865,737,268,717,245,712,221,51,907,687,40,541,679,464,242,719,89,992,881,300,474,717,492,73,601,136,122,261,203,267,445,708,866,339,807,906,956,674,721,244,510,400,535,668,949,24,499,274,325,573,112,511,733,10,496,403,661,223,363,519,84,579,785,889,362,948,130,493,443,155,863,116,966,870,620,533,914,414,989,670,149,404,44,923,966,365,645,337,161,741,79,642,227,918,879,816,210,804,360,986,177,222,746,740,587,989,21,610,344,127,476,9,586,892,830,689,866,25,972,822,15,193,366,829,85,666,102,160,8,833,792,834,503,912,35,650,764,380,44,714,831,428,94,956,759,35,270,509,112,347,174,799,930,62,963,558,790,299,654,955,715,521,196,924,822,245,220,538,171,76,567,917,745,305,202,999,414,830,723,906,477,34,256,674,880,813,403,780,280,315,45,946,498,696,882,50,969,282,608,339,501,875,805,108,584,241,446,249,448,744,985,335,303,997,173,520,10,881,488,16,297,88,665,628,720,850,983,505,753,952,501,602,364,564,26,84,576,301,786,361,68,561,850,416,56,719,990,101,697,699,248,45,681,575,314,405,478,365,291,969,748,374,217,260,343,198,768,905,960,29,283,866,863,137,860,501,839,585,125,170,46,277,209,346,128,234,357,355,24,451,908,182,508,877,430,195,96,368,373,279,614,260,326,192,551,61,933,128,670,546,646,742,320,410,70,555,689,298,769,237,703,608,585,923,899,282,924,853,677,978,938,110,726,677,329,913,466,878,884,698,86,862,962,254,846,92,542,600,95,463,516,373,140,103,385,258,226,932,384,195,343,499,127,465,705,152,511,758,395,360,437,39,426,89,53,368,419,914,826,149,695,727,206,681,568,163,891,798,167,723,205,130,769,321,437,985,527,289,450,496,556,567,973,540,545,244,559,182,390,357,130,668,905,546,792,68,105,912,88,854,256,46,336,826,320,219,765,28,502,260,446,518,430,156,721,169,291,384,564,423,386,885,591,98,542,692,618,880,400,777,885,59,589,624,626,621,517,63,547,424,523,493,608,676,584,181,623,675,722,525,238,629,649,968,860,647,926,333,659,78,41,878,497,966,869,301,28,483,801,869,160,724,411,411,351,575,388,232,60,342,818,362,742,102,387,855,712,306,944,486,887,735,696,318,691,258,614,269,133,706,65,652,693,438,44,232,30,483,492,979,954,837,915,112,349,97,447,500,371,403,800,123,505,258,437,330,79,207,297,91,430,452,651,708,274,821,780,673,499,159,309,701,394,998,877,743,333,852,765,710,502,450,193,875,629,731,475,633,284,514,690,295,273,344,921,818,935,689,419,391,468,785,80,530,376,194,259,224,298,555,355,473,961,306,987,200,639,443,812,481,685,293,794,253,41,163,481,6,166,419,654,298,939,808,637,12,403,853,405,438,838,950,654,243,870,925,901,897,619,436,303,112,897,420,109,217,404,639,306,202,801,835,942,369,507,105,676,335,356,510,879,217,951,63,947,550,939,551,224,440,209,44,853,96,243,58,960,162,249,458,506,453,787,511,667,145,666,41,484,712,389,925,415,988,545,403,320,95,477,383,345,127,614,921,69,173,419,538,947,278,877,618,2,98,358,384,641,81,27,663,47,522,773,995,976,190,777,264,655,748,424,83,88,690,645,31,60,872,996,250,984,757,512,835", "33,27,628,950,190,852,551,677,500,198,620,232,198,654,594,134,847,947,779,991,42,517,548,436,139,781,305,974,476,846,962,179,383,554,710,336,153,0,636,824,690,230,321,896,269,479,951,740,713,401,891,908,530,467,603,945,713,693,486,424,981,809,67,431,167,780,782,171,630,686,553,631,529,221,534,823,274,171,891,556,815,211,629,863,411,924,11,314,622,566,267,49,538,922,572,198,25,996,101,4,709,793,475,259,993,442,605,516,305,513,77,733,808,155,501,836,573,553,460,908,702,707,778,893,600,15,228,458,223,735,211,401,958,285,322,850,236,91,809,63,12,129,170,51,416,486,27,919,494,798,244,93,879,520,994,997,507,324,867,274,897,852,965,614,129,719,958,315,57,675,583,153,511,70,350,320,730,965,498,993,232,544,915,394,226,323,943,210,974,650,309,539,615,992,825,645,251,49,769,381,678,640,927,612,933,908,489,341,153,435,877,349,573,388,530,125,784,871,603,334,853,195,440,692,68,268,496,947,373,907,826,270,771,292,219,935,158,992,418,345,42,884,1,331,944,318,903,757,249,797,847,74,408,107,397,120,151,254,307,418,832,407,533,549,560,418,525,393,280,101,842,108,366,91,974,265,982,857,234,926,560,188,850,770,777,827,609,240,25,740,167,622,655,658,241,419,147,441,83,229,352,645,83,919,474,696,668,278,882,662,475,123,326,151,595,620,305,241,322,4,917,295,791,105,674,189,971,434,930,896,850,358,927,934,105,218,673,794,874,580,507,211,284,759,737,241,86,482,99,505,816,212,143,949,549,42,611,385,303,779,930,105,329,376,98,29,258,248,600,901,109,510,351,601,313,49,874,910,39,881,576,475,451,130,314,923,657,839,580,286,516,329,688,352,606,10,358,913,564,463,574,154,977,833,977,973,255,786,425,946,432,169,782,678,383,177,868,988,270,776,486,848,110,79,279,221,83,848,590,3,546,972,871,697,387,190,819,684,864,867,15,161,927,222,973,851,618,170,822,343,784,44,664,491,418,37,207,932,881,812,274,727,735,600,288,708,606,387,200,244,484,923,732,80,613,176,458,50,278,198,209,949,966,534,198,21,849,161,343,474,373,807,225,685,310,117,701,77,950,555,973,990,639,185,490,990,886,377,228,255,489,42,709,648,267,39,706,265,988,788,791,149,613,690,224,701,954,22,795,443,741,369,188,978,576,577,433,906,848,81,226,19,564,38,9,726,881,152,201,219,187,337,250,854,948,990,181,622,753,756,267,603,892,731,658,875,259,629,757,78,873,97,37,817,938,718,840,464,638,666,772,299,650,349,282,743,808,130,236,472,881,973,130,565,232,887,452,667,389,980,84,799,406,183,297,444,380,404,141,330,268,379,374,963,204,58,486,292,337,530,748,737,44,812,65,849,196,233,107,810,690,35,855,921,951,821,483,893,768,187,350,985,52,657,507,274,686,955,823,903,883,63,234,398,43,281,819,756,992,353,263,36,599,155,646,865,452,797,680,561,649,500,318,667,269,513,742,963,729,852,169,385,398,120,595,408,619,471,301,862,846,900,930,242,574,216,425,110,112,144,851,180,377,300,132,595,497,955,758,991,164,649,354,869,309,461,629,743,652,35,22,75,809,199,307,298,386,479,265,511,911,890,393,857,991,155,770,405,690,842,49,599,339,674,805,810,716,621,329,974,130,257,598,807,857,629,835,118,972,277,654,904,497,707,377,434,844,886,548,495,352,754,990,567,696,267,522,254,874,612,228,775,364,101,213,241,799,938,284,669,922,988,361,992,469,342,435,515,394,795,508,599,740,924,437,601,4,407,468,304,399,650,889,228,325,44,917,416,690,652,761,400,502,801,797,140,582,799,153,679,664,38,260,597,595,664,947,784,830,323,929,35,112,992,527,265,640,944,926,118,317,662,333,40,953,731,833,273,834,872,927,465,908,668,611,310,461,274,36,509,701,36,381,76,945,605,813,924,170,923,52,767,773,893,700,730,156,401,439,581,874,871,579,894,857,9,739,980,757,543,811,348,389,291,730,999,767,201,872,857,469,307,773,111,556,999,128,667,208,543,319,602,266,312,103,294,759,721,936,940,495,214,258,531,221,2,179,460,949,512,599,539,790,487,635,770,650,92,512,655,754,228,441,728,259,468,105,447,432,674,171,267,686,745,947,541,615,411,306,251,506,798,165,817,302,145,652,351,260,790,493,261,774,830,60,787,359,121,885,237,91,440,95,355,215,188,750,537,763,349", "112,396,781,993,731,156,77,716,464,621,786,574,340,833,312,567,921,617,978,102,224,755,176,99,774,718,301,995,567,564,839,628,611,704,187,656,876,636,0,634,880,367,291,800,380,358,7,279,299,800,601,318,951,884,884,930,921,2,719,23,701,861,760,289,366,519,158,114,203,857,217,823,727,126,677,667,568,882,584,996,892,952,870,490,564,739,891,50,532,857,342,273,13,282,684,878,505,999,515,939,392,996,894,603,942,959,141,716,709,821,324,813,409,745,552,623,742,854,256,787,946,953,811,33,260,577,802,76,176,417,725,730,148,393,776,273,776,773,177,610,671,35,338,150,725,834,274,600,583,59,274,801,337,696,65,755,931,548,808,266,345,654,507,723,479,467,222,179,227,619,442,22,728,918,31,479,524,902,26,987,938,346,4,855,911,287,35,147,787,89,348,107,810,944,750,898,106,996,347,652,43,378,825,968,484,7,720,551,635,356,768,298,564,212,122,442,221,349,99,539,146,830,766,352,131,394,547,387,885,885,976,694,59,898,823,39,786,396,81,217,511,149,64,674,959,934,459,354,510,399,98,571,984,342,902,443,541,65,240,253,367,778,432,880,468,561,626,309,423,12,420,643,860,885,414,364,649,151,827,477,129,41,359,957,177,485,390,134,890,966,33,219,317,609,924,208,952,34,150,438,479,711,698,22,383,202,523,946,900,583,17,492,511,500,413,983,739,188,665,438,223,228,724,288,632,960,732,626,379,392,514,114,895,574,15,785,373,489,592,802,821,351,914,592,894,67,429,260,989,846,956,750,138,327,39,756,643,153,316,118,617,54,524,676,88,912,741,884,340,288,406,695,728,500,259,85,586,755,261,408,250,248,268,915,37,592,510,201,432,790,629,823,67,594,109,316,71,675,558,522,693,200,591,750,748,211,678,625,291,819,892,797,304,444,433,699,911,311,905,934,285,522,543,33,447,785,204,490,757,59,9,848,631,997,673,431,929,197,453,554,16,845,156,885,490,915,233,310,207,709,536,635,64,620,763,28,243,433,609,159,839,903,403,246,122,387,368,481,4,185,535,625,827,837,232,886,591,948,547,671,348,779,442,431,423,349,215,311,182,896,523,460,422,874,523,139,19,322,585,917,229,236,149,413,996,42,468,610,665,188,238,395,152,61,97,608,945,291,31,781,322,598,146,748,585,219,225,107,464,251,79,5,711,819,411,893,762,885,177,334,545,982,416,71,822,673,450,618,462,399,944,884,373,129,248,385,986,786,191,330,398,298,495,811,908,116,852,167,859,439,736,234,936,457,719,515,208,291,194,666,236,800,656,440,535,817,167,33,463,506,929,550,765,984,307,320,677,307,630,469,404,240,844,308,522,408,371,870,669,629,580,948,134,348,992,312,556,140,420,153,405,540,266,643,486,612,617,496,50,959,232,485,414,371,773,696,998,160,512,846,358,450,705,691,55,899,999,97,395,197,779,293,213,970,715,669,928,721,563,6,107,535,823,782,375,486,582,328,365,117,289,822,861,12,589,750,524,234,670,541,136,509,700,375,441,622,508,146,106,828,502,670,246,569,203,571,238,902,148,211,514,328,359,798,733,993,427,7,97,252,706,129,753,633,510,257,742,183,436,927,398,364,605,96,722,121,676,440,147,364,381,81,423,406,797,514,441,168,51,667,173,711,945,113,425,599,915,959,329,972,399,643,112,709,204,783,833,297,564,533,37,980,448,157,490,442,209,86,751,806,879,222,680,107,192,837,729,121,584,84,444,41,439,236,206,506,560,452,41,27,687,754,637,659,261,886,144,246,945,636,62,138,930,588,528,153,58,674,97,187,648,646,856,555,669,269,158,933,451,249,872,973,648,403,783,406,698,582,36,909,696,569,450,682,194,977,447,445,445,501,681,922,117,99,648,855,664,767,859,583,251,192,960,427,629,911,805,257,184,428,558,78,404,172,913,981,722,357,859,668,582,608,784,704,327,492,428,484,982,646,356,367,117,922,985,52,784,468,540,250,245,359,616,727,350,647,152,711,498,416,328,491,275,719,281,556,222,805,994,123,320,534,772,839,914,570,403,371,81,340,242,856,707,569,71,46,396,556,251,619,544,251,265,516,754,751,507,665,154,297,115,407,749,671,814,859,885,220,468,294,657,268,847,175,172,388,305,161,352,190,707,422,369,324,824,505,301,175,303,679,816,225,141,718,479,392,887,723,773,920,516,553,916,379,334,157,847,783,198,322,847,250,318,779,257,342,915,995,985,915", "913,183,698,821,963,676,475,680,742,731,202,24,54,38,273,694,91,842,288,120,832,736,848,42,3,147,718,391,959,334,732,311,885,814,521,507,804,824,634,0,825,126,977,599,271,612,352,534,649,208,203,99,308,108,1,202,765,370,611,451,992,42,846,387,568,305,771,189,985,806,458,44,833,585,442,455,143,507,274,717,127,365,655,510,463,481,928,350,52,800,134,649,619,981,365,151,906,251,184,675,609,74,208,997,359,620,706,473,770,871,918,164,952,170,969,549,341,1,695,160,119,462,297,646,396,812,944,339,6,665,240,906,994,598,714,433,448,652,864,113,383,317,977,628,332,611,740,167,875,997,60,217,332,319,501,609,557,665,68,53,600,486,656,772,336,431,27,552,865,545,106,766,862,266,806,575,285,560,899,512,614,280,499,888,820,875,224,866,540,461,815,613,391,678,88,782,656,607,300,996,520,831,400,749,815,615,93,382,778,406,231,761,30,582,168,732,608,655,539,264,286,42,645,706,207,58,506,606,177,501,176,421,539,636,35,968,200,91,27,890,359,658,974,842,33,910,526,122,487,237,501,742,576,322,503,444,165,695,466,683,473,104,920,30,265,624,864,135,181,248,141,170,962,10,85,5,531,850,301,200,296,590,358,713,898,103,844,66,519,272,229,948,315,943,39,13,602,338,14,919,208,52,311,653,622,71,392,939,593,889,826,197,89,746,125,365,958,4,252,362,627,158,363,263,399,776,951,324,775,212,427,480,528,584,79,338,425,874,430,342,861,441,731,87,886,421,254,77,631,331,535,364,285,598,120,612,782,593,834,29,287,71,255,345,973,98,15,82,4,963,931,818,616,960,441,303,642,211,91,77,320,862,975,238,397,47,422,735,51,489,170,340,623,94,652,683,901,414,244,196,292,611,735,939,365,474,677,730,108,639,944,833,101,916,326,754,777,431,61,223,337,91,66,553,123,325,7,603,143,434,378,740,668,780,347,680,845,451,193,517,743,716,105,129,321,88,411,666,622,516,927,196,441,735,660,169,96,792,898,118,53,479,778,872,178,641,577,525,846,293,37,19,351,7,229,390,397,857,898,210,184,272,551,792,276,288,578,913,392,608,320,978,695,44,130,283,524,844,415,30,500,781,137,973,422,338,36,406,597,48,61,925,839,641,108,198,271,578,863,40,135,222,962,807,500,544,390,40,391,303,620,129,459,516,879,752,776,647,932,764,254,918,709,190,241,827,818,366,170,847,20,26,831,820,351,116,143,459,645,824,562,229,301,194,746,14,236,380,892,395,785,622,200,19,260,970,841,482,389,767,576,318,396,421,31,31,44,913,882,331,742,856,208,466,456,818,14,873,371,319,348,421,398,13,235,330,402,561,237,608,332,385,342,557,693,517,287,377,79,208,236,6,811,282,893,427,297,309,292,552,986,373,450,81,88,755,520,21,208,914,617,550,517,907,830,79,529,386,768,739,999,214,905,576,351,863,234,616,952,925,91,356,656,131,194,848,243,828,175,772,786,528,82,576,959,588,325,740,986,516,381,373,702,551,60,167,20,279,483,245,219,103,865,950,584,914,118,481,210,664,151,158,538,986,920,462,201,496,638,306,806,638,950,826,690,489,283,569,662,81,555,571,45,244,245,208,958,111,802,80,415,476,535,585,637,767,41,595,837,799,931,997,304,693,687,802,671,33,963,768,610,228,932,762,727,844,285,731,449,470,578,644,799,133,300,159,767,954,540,446,970,902,349,185,615,362,43,635,150,266,398,405,371,669,192,50,841,27,25,45,301,361,216,335,58,712,768,722,253,116,346,217,523,500,702,808,991,13,110,740,440,991,448,584,173,437,533,180,951,695,266,494,740,393,637,437,898,117,778,779,363,635,720,222,817,637,63,315,583,245,925,549,294,765,884,768,983,854,170,119,292,915,505,158,792,725,178,581,895,915,534,393,971,922,229,612,307,634,859,619,37,11,955,6,663,288,879,560,137,570,82,605,103,781,648,202,869,124,139,916,811,556,553,297,344,387,85,998,581,821,440,952,885,110,188,661,388,650,197,453,999,515,145,507,765,815,832,248,128,192,668,126,210,737,217,211,544,382,568,409,502,162,16,184,248,822,343,19,620,625,828,298,599,35,813,55,435,579,369,89,438,845,578,643,217,522,991,335,987,80,9,979,415,565,531,201,336,98,870,809,810,234,619,95,197,308,731,204,17,367,260,903,317,302,318,912,792,338,801,523,585,388,179,511,281,220,154,887,587,966", "548,396,361,818,186,904,499,907,842,396,218,310,504,195,841,759,385,393,265,116,281,371,393,651,896,197,621,559,492,148,325,665,405,512,922,41,859,690,880,825,0,208,684,473,706,130,446,885,211,143,367,99,258,196,77,706,32,895,875,793,422,661,77,655,499,786,700,126,53,775,324,233,156,651,39,229,893,487,98,771,439,972,401,737,425,70,901,151,837,763,490,232,140,518,706,934,198,959,106,367,958,414,627,484,431,462,407,368,129,251,454,698,627,101,420,364,350,759,154,443,210,805,254,580,759,791,370,965,916,684,499,760,120,584,852,104,556,536,995,770,834,303,239,335,915,776,781,703,436,557,48,252,480,451,388,290,354,259,936,47,347,750,858,901,702,412,187,114,433,472,868,402,445,154,769,95,858,683,342,779,77,797,641,377,304,634,237,610,235,262,500,581,253,592,167,122,347,834,892,499,342,628,922,211,673,46,837,822,877,873,748,556,314,713,762,27,949,253,468,502,269,4,172,641,497,365,168,648,778,637,53,884,157,618,477,555,641,500,160,745,798,892,289,862,659,244,34,127,545,346,116,761,826,202,478,521,174,217,732,267,988,502,509,703,586,23,333,889,666,321,590,210,910,505,274,283,271,236,96,383,881,293,798,889,703,96,779,575,309,23,938,756,586,604,634,613,379,21,248,676,642,40,275,392,110,270,266,415,270,204,496,995,427,357,598,855,556,395,561,897,330,305,939,598,56,559,916,737,484,620,937,229,74,827,35,789,581,358,252,947,154,96,924,965,563,968,900,938,774,56,892,960,807,262,663,172,888,922,835,834,879,92,415,309,290,862,464,525,232,804,893,755,320,442,496,979,576,982,591,856,537,185,70,584,812,282,510,389,663,46,289,583,851,181,804,999,988,833,975,337,755,660,62,17,569,741,710,158,969,863,979,315,701,351,296,446,569,475,652,49,738,275,709,181,849,306,608,561,106,315,317,734,306,891,530,629,16,531,139,677,932,640,295,527,504,180,579,823,552,797,640,771,42,432,829,855,569,432,988,8,924,538,801,243,198,262,632,714,824,679,898,166,705,380,664,134,959,224,577,157,428,453,468,96,801,192,409,321,334,55,247,134,618,180,603,503,960,394,165,574,207,133,504,76,983,851,819,904,221,728,187,297,979,662,460,86,693,114,205,284,300,401,72,222,357,101,265,527,715,388,354,462,268,485,875,650,101,224,406,467,708,947,874,932,630,81,126,217,764,44,965,138,506,717,862,967,172,390,485,244,743,134,931,241,639,300,164,580,92,412,187,562,509,790,628,716,276,323,807,270,624,547,419,361,498,177,224,54,662,827,504,81,462,12,449,292,959,991,253,865,877,898,162,886,214,966,641,902,828,446,419,895,480,255,793,620,490,682,149,750,874,412,967,200,797,824,631,406,182,202,135,478,378,770,661,229,847,448,95,818,398,889,496,67,520,163,352,230,157,492,302,440,256,204,564,794,755,650,548,580,532,128,194,408,924,710,830,721,914,897,884,389,573,772,335,15,790,597,935,894,592,404,582,471,201,786,918,951,647,217,91,344,717,640,820,193,48,801,172,885,928,973,739,963,365,828,81,484,888,322,359,331,544,95,847,274,369,668,853,373,306,622,514,313,235,202,468,821,954,935,813,420,190,890,159,191,254,706,415,987,587,578,402,944,428,926,993,863,81,603,746,269,723,697,278,697,114,57,353,629,273,993,456,103,696,987,843,893,650,731,460,900,180,670,665,465,359,233,895,22,248,237,226,101,612,884,424,611,610,216,534,108,92,506,567,321,912,668,543,307,510,334,685,63,182,563,245,930,169,230,649,381,796,56,814,832,468,196,519,923,578,541,98,68,233,441,864,87,807,219,440,673,369,582,356,733,732,869,776,92,859,461,870,105,143,958,775,82,592,634,820,617,303,437,492,40,122,166,517,95,964,381,727,216,333,496,934,979,962,880,604,78,969,368,201,352,654,604,232,719,151,352,62,508,795,333,775,590,875,93,89,584,417,556,186,391,502,208,101,88,619,557,87,413,52,542,991,352,91,746,302,562,92,264,588,507,924,148,360,836,931,64,844,90,668,406,779,7,892,828,103,529,335,90,593,941,448,200,406,550,885,788,105,887,943,990,833,868,898,141,293,759,470,508,289,698,248,754,756,867,526,550,308,263,858,648,475,593,111,662,420,719,298,482,300,233,750,110,309,433,769,527,819,727,826,754,540,50,888,21,935,369,617,137,359,14,45,687,111,543", "902,822,121,906,586,251,367,936,641,65,529,982,549,850,941,761,914,142,48,344,356,820,716,318,861,993,641,338,596,810,290,594,848,285,379,260,472,230,367,126,208,0,641,88,268,757,539,283,405,356,594,265,179,605,753,735,959,145,736,685,678,902,215,835,136,218,592,401,512,660,310,625,936,828,67,433,37,868,126,352,51,923,546,496,508,709,892,44,666,464,693,191,79,536,635,232,248,99,996,562,90,971,393,687,743,951,744,70,989,380,456,44,219,607,604,7,362,876,613,569,155,380,962,718,84,406,524,90,82,832,16,679,527,474,46,422,122,735,105,411,810,444,357,720,536,495,546,589,468,965,937,975,150,609,880,862,813,554,642,556,693,362,889,247,961,61,195,6,895,414,687,987,847,627,323,243,986,523,495,36,515,480,256,490,731,879,192,813,356,780,266,472,345,339,742,463,639,232,418,656,991,99,735,228,384,443,668,337,33,842,437,319,535,264,930,119,61,395,576,639,403,58,632,873,865,112,499,835,491,314,629,246,74,315,464,540,832,907,515,58,561,790,423,855,127,717,71,408,410,144,14,464,73,191,728,570,883,699,746,116,177,647,121,611,326,743,94,933,207,216,860,295,748,556,305,673,961,952,913,697,491,397,376,702,256,13,788,386,467,299,699,794,796,964,361,597,763,173,105,757,802,42,773,968,619,796,485,291,259,26,106,53,289,585,811,219,968,572,22,275,873,128,57,739,201,995,176,752,863,354,981,954,188,488,144,303,599,328,128,192,194,149,920,741,864,414,829,384,535,149,112,790,466,975,898,855,179,785,150,412,84,461,96,960,682,936,278,326,932,561,136,628,823,898,354,564,399,693,678,512,509,992,105,250,78,375,811,706,200,69,968,49,559,731,110,526,472,824,38,596,103,933,219,648,321,415,95,210,303,552,215,991,562,775,991,722,998,361,902,495,539,766,798,754,986,556,715,911,88,953,981,769,487,993,44,315,765,701,478,819,595,114,568,874,485,460,646,646,736,920,528,84,867,598,775,950,389,936,565,891,382,799,217,27,248,521,254,144,88,586,544,609,552,938,205,97,579,796,158,576,967,68,611,64,938,769,658,410,187,28,156,573,746,346,42,343,800,597,94,998,347,573,56,121,283,795,212,25,581,678,179,858,362,168,504,503,127,643,329,791,743,749,417,609,59,694,637,365,973,685,509,24,929,890,335,472,775,455,721,908,530,438,27,120,603,397,528,615,848,576,752,353,145,41,201,754,366,233,190,133,704,154,839,993,81,670,918,152,955,464,108,32,60,243,793,608,162,377,238,957,7,986,286,862,280,791,146,670,857,569,525,780,753,772,117,575,576,398,429,34,661,756,890,90,540,922,132,731,181,142,688,884,225,254,106,215,718,257,403,710,210,206,182,140,422,626,937,465,273,127,136,816,717,648,662,650,284,30,410,689,147,714,914,775,347,855,130,141,684,149,56,808,930,24,19,745,409,625,326,335,779,522,144,554,405,551,454,698,408,79,654,73,317,478,519,829,887,441,670,212,24,157,969,20,993,29,690,553,664,989,634,360,547,500,373,860,616,734,949,944,717,64,977,642,616,119,449,655,490,619,396,737,585,304,446,45,489,644,595,785,712,854,661,428,625,218,540,891,252,988,244,76,563,391,456,582,644,25,626,858,392,253,759,512,258,333,590,279,507,427,830,883,10,138,779,917,441,412,809,611,601,720,401,84,525,994,54,977,709,347,701,765,765,217,798,331,895,585,877,818,663,727,719,386,367,913,2,326,50,682,167,404,226,723,95,760,504,935,632,663,733,768,531,392,274,490,377,217,76,385,559,789,673,377,957,517,866,544,749,783,215,36,163,14,508,374,519,932,866,181,294,752,121,143,348,546,135,536,320,669,141,986,947,587,886,959,213,41,180,585,959,239,413,424,293,509,825,886,66,312,580,621,963,737,992,814,521,297,169,451,892,156,581,694,527,714,307,341,344,120,486,623,298,687,809,488,66,413,295,109,889,545,624,199,40,59,12,243,884,681,786,649,804,565,470,130,94,611,746,558,885,40,365,655,471,755,518,466,489,27,766,529,912,139,560,603,663,380,568,23,589,470,52,934,597,19,785,693,706,603,812,986,104,713,600,912,328,52,46,960,55,967,143,802,530,591,613,369,584,115,651,887,600,677,655,705,823,414,643,758,369,530,975,451,665,298,232,592,216,707,451,754,634,224,302,356,205,159,665,688,517,235,805,526,420,151,476,415,224,921", "793,81,216,58,52,841,648,958,923,529,921,609,491,264,480,88,469,840,517,457,885,301,954,186,342,337,566,861,239,112,11,340,699,329,983,375,364,321,291,977,684,641,0,438,867,729,43,24,58,214,419,195,449,860,328,109,866,403,359,786,574,682,838,848,727,170,867,525,171,636,152,930,705,571,804,990,447,128,857,950,239,389,956,670,67,640,751,59,810,1000,851,592,670,790,230,549,991,369,500,465,173,35,596,698,308,651,823,119,288,453,856,318,902,452,726,929,920,15,6,886,947,37,423,766,88,400,867,422,458,686,588,502,536,635,927,12,252,241,448,926,884,965,307,455,197,511,132,303,647,83,686,152,979,611,650,642,609,75,834,721,980,235,694,456,901,677,505,281,109,478,337,629,322,600,4,364,117,989,904,902,532,790,490,441,876,128,761,219,220,214,636,560,410,288,828,733,576,928,454,107,106,424,160,158,355,273,835,850,824,852,53,4,701,166,777,119,801,238,284,687,345,309,125,643,413,320,278,208,20,165,356,221,339,812,817,525,439,265,795,646,172,696,572,108,177,557,317,428,310,509,232,672,3,349,767,589,829,671,994,453,876,312,481,565,270,28,863,710,861,779,944,106,322,853,120,648,675,346,779,179,388,934,904,754,499,527,603,775,644,335,934,937,726,68,723,156,794,32,388,63,458,300,228,720,566,979,770,351,696,292,589,104,136,10,843,833,118,679,32,212,789,501,326,374,934,678,84,943,38,311,59,190,78,224,544,179,984,988,625,953,31,987,876,239,244,111,103,281,858,659,426,331,234,693,218,873,341,559,913,494,923,213,280,241,636,308,693,417,653,837,685,18,16,723,623,74,891,62,614,630,300,735,638,883,917,144,515,948,643,730,535,790,308,632,114,897,148,355,198,476,148,445,483,273,693,331,486,615,490,508,607,254,260,930,169,462,545,711,889,291,244,104,790,824,38,663,464,676,3,91,93,263,263,895,335,960,35,326,877,98,494,574,801,713,285,332,652,723,774,525,275,310,23,322,346,194,41,635,190,968,597,10,132,406,116,220,845,217,729,181,825,315,937,518,539,130,436,38,583,428,430,173,865,208,967,169,321,814,262,266,33,667,89,934,864,29,870,801,96,197,407,577,919,865,455,185,864,747,434,923,155,642,153,614,316,925,266,626,12,600,644,441,198,37,268,662,779,618,537,110,77,297,889,830,980,191,263,42,498,21,120,148,273,316,427,725,830,937,127,241,966,96,153,509,951,171,268,188,386,223,150,318,747,838,638,790,164,560,476,69,121,756,53,385,207,830,533,250,992,478,210,947,516,808,392,911,139,911,157,972,274,191,185,265,387,182,151,531,290,424,700,116,410,162,42,622,557,979,74,705,891,791,978,108,728,145,795,389,602,21,748,25,410,306,600,419,919,445,905,900,526,100,606,970,860,918,709,928,105,526,138,361,181,843,11,927,22,26,972,326,268,10,34,262,963,173,312,422,521,477,888,787,973,265,382,519,820,656,765,353,214,91,983,739,990,520,55,543,829,418,323,677,96,516,856,46,416,335,881,911,814,247,82,128,110,704,954,43,846,709,228,792,227,337,373,756,7,605,311,622,649,863,789,131,756,500,988,26,985,944,154,344,94,586,917,522,588,498,791,928,550,664,354,345,668,734,718,176,800,233,610,313,777,332,358,650,109,609,257,607,48,557,520,54,85,153,345,170,350,908,304,874,699,849,929,223,998,896,725,101,392,887,661,737,740,391,764,190,75,266,720,258,916,395,634,347,403,504,297,517,939,569,244,813,655,831,303,81,496,202,320,522,131,242,57,919,885,56,231,693,565,974,852,603,87,573,419,750,797,624,421,364,301,530,120,729,804,787,836,417,535,278,346,445,222,613,864,784,309,403,439,986,643,854,944,2,522,274,717,834,215,821,936,860,553,845,606,556,891,167,10,208,924,153,839,346,884,361,201,476,271,37,992,942,918,140,895,502,306,137,983,527,553,639,672,515,628,652,903,63,896,150,313,620,603,616,312,289,343,840,986,399,161,615,795,640,821,985,465,232,397,698,544,350,426,972,644,3,850,506,293,60,684,21,463,598,217,782,640,138,295,387,690,209,81,937,321,706,556,54,824,220,838,328,432,910,628,164,98,986,239,110,1,386,501,829,622,722,195,955,9,154,776,111,819,857,395,766,976,655,25,224,83,735,689,461,587,180,840,197,636,537,653,361,796,225,415,27,427,97,866,650,824,478,142,20,675,715,595,590", "563,117,819,492,700,175,899,437,117,612,751,630,280,354,554,361,58,240,758,957,459,912,364,953,433,764,324,311,16,360,445,115,379,674,956,99,502,896,800,599,473,88,438,0,752,566,320,297,213,597,810,563,743,121,71,497,4,551,788,167,73,421,90,402,435,989,509,423,285,285,698,648,871,1000,896,534,492,148,342,385,816,986,443,449,219,69,990,606,903,788,753,132,756,582,918,980,205,220,484,395,473,318,27,914,783,912,51,620,538,16,579,327,626,946,406,223,898,412,360,848,981,544,83,625,335,423,636,969,945,865,187,890,794,538,57,90,255,919,455,310,539,738,787,954,994,851,803,469,285,307,790,998,121,535,249,38,180,235,899,757,636,955,498,757,535,215,330,428,608,139,653,119,126,830,688,377,479,262,138,243,536,853,73,139,711,431,760,357,900,742,761,540,240,852,239,91,821,351,558,85,74,195,682,873,597,107,172,561,908,721,865,87,193,946,977,32,375,605,205,739,714,179,339,818,714,334,678,294,320,638,901,430,331,852,4,493,743,435,390,237,298,202,941,215,422,883,444,173,456,828,248,750,343,810,538,273,442,502,130,458,568,779,188,502,920,786,224,370,469,619,603,780,73,897,528,406,579,400,871,756,354,412,728,608,484,824,606,292,902,47,463,433,526,348,563,88,714,465,462,91,435,135,565,232,769,320,913,80,196,642,796,247,176,21,446,610,156,8,22,654,28,225,632,259,478,189,240,705,768,958,9,929,172,99,163,411,619,28,492,818,327,342,303,241,205,440,614,55,713,517,262,398,974,607,928,755,628,308,396,408,723,264,883,84,699,231,684,975,765,110,513,53,399,395,535,712,386,27,977,203,694,629,286,772,740,899,676,382,495,300,870,554,734,919,98,669,457,539,609,416,62,236,627,168,188,246,791,697,283,945,285,472,95,749,97,423,665,321,446,497,692,893,428,728,613,490,75,627,23,991,267,474,83,75,637,390,130,512,133,846,223,72,448,84,957,401,497,954,711,560,608,849,432,352,271,916,682,810,805,761,330,912,313,456,894,583,725,875,878,412,54,145,826,114,574,338,389,712,913,208,840,159,346,359,892,476,689,264,537,986,249,947,947,17,634,974,225,540,441,289,202,519,356,974,643,253,989,422,141,621,362,707,940,356,929,499,193,751,506,427,255,792,283,414,319,82,446,302,671,293,346,881,557,386,961,933,292,22,619,313,819,231,293,710,47,311,453,678,459,935,191,230,220,464,354,753,987,689,362,632,867,174,919,355,702,499,140,405,273,426,337,661,551,794,218,658,973,800,185,105,592,708,625,201,198,600,19,3,940,856,311,288,895,749,30,68,83,404,604,359,699,603,991,841,613,415,671,841,970,851,846,516,694,602,454,538,534,279,433,446,285,405,898,257,846,776,535,602,567,306,551,406,216,198,972,643,591,549,242,978,82,516,679,543,849,121,300,520,33,19,343,964,876,503,283,494,768,742,876,21,284,882,872,639,460,527,219,84,600,640,592,200,345,35,174,912,517,298,996,370,740,662,706,736,312,728,967,567,767,855,946,178,266,518,30,742,217,877,535,270,566,739,428,113,418,183,341,123,232,449,508,859,255,803,813,94,815,443,297,602,913,106,941,268,440,680,14,982,215,560,649,489,230,136,837,970,738,896,559,460,140,549,346,762,735,165,361,495,130,756,876,508,980,765,382,146,249,968,936,821,657,492,436,746,641,418,38,168,977,575,271,288,20,261,526,801,364,228,229,104,132,680,833,457,918,939,335,342,709,609,743,370,15,601,50,710,685,267,399,332,779,594,844,26,756,878,122,10,297,62,255,747,425,824,611,14,309,961,572,226,526,745,59,172,850,286,934,769,858,809,988,861,763,982,616,919,847,988,897,764,404,743,75,531,951,739,303,493,89,416,583,336,155,599,103,455,242,55,840,881,326,717,839,600,785,121,947,211,28,993,366,715,513,7,476,362,108,742,906,595,810,154,512,889,683,428,932,930,996,41,661,711,67,562,851,269,692,400,613,337,524,858,378,27,765,702,96,696,801,917,761,814,286,416,742,690,498,840,487,911,92,225,484,452,895,244,689,370,817,260,175,183,845,167,133,58,316,855,926,95,303,426,151,862,493,87,845,155,876,980,350,314,667,798,899,973,82,948,833,288,811,491,288,198,727,141,973,384,270,793,379,9,59,286,252,744,450,231,313,674,374,308,253,974,56,568,602,79,1,5,141,815,371,459,23,997,387,259,91,967", "318,114,304,863,83,504,319,991,654,196,224,633,220,217,262,216,706,51,431,671,93,686,180,242,219,233,468,617,265,273,78,195,648,956,176,406,573,269,380,271,706,268,867,752,0,959,664,268,830,946,536,541,953,851,468,50,828,534,94,452,300,576,642,695,641,548,157,42,105,384,508,566,880,729,329,454,522,408,426,831,42,622,65,313,472,942,656,175,217,421,684,642,336,912,475,987,684,399,958,719,73,115,525,35,488,511,122,228,764,343,509,211,266,645,199,735,219,290,502,515,497,80,938,995,168,764,656,54,18,108,515,153,743,974,670,776,316,274,53,948,669,772,43,730,583,614,853,584,924,581,589,775,168,642,427,461,176,515,136,809,725,984,818,357,269,433,177,910,110,848,188,661,929,533,116,307,671,111,255,8,587,945,438,397,840,935,140,230,181,299,603,714,486,954,737,747,923,794,828,343,141,429,953,311,264,146,938,416,351,239,510,4,298,242,1,602,813,577,738,626,251,950,811,275,476,945,447,702,53,927,442,252,681,213,403,245,344,789,735,331,672,470,510,396,269,717,282,145,884,561,715,248,498,439,673,59,776,307,379,603,501,552,977,34,551,304,222,84,561,586,79,944,243,261,548,661,801,277,663,393,291,472,52,707,244,869,327,130,569,302,920,349,220,517,586,966,907,225,519,921,608,531,25,482,557,465,97,680,64,837,758,33,396,551,218,715,718,547,741,70,552,866,472,33,715,1000,899,816,371,490,251,208,34,327,176,212,578,242,211,100,44,562,236,635,55,703,600,533,699,791,952,800,945,377,615,740,849,476,444,750,445,425,66,2,878,495,665,638,383,402,73,420,451,153,280,489,892,842,973,579,625,204,228,170,611,683,510,364,637,890,607,502,3,767,646,161,260,909,403,641,342,303,641,63,765,167,790,488,276,414,873,389,500,227,746,74,166,966,541,331,686,447,207,69,152,396,958,3,190,17,386,205,744,746,517,132,381,750,412,908,183,945,813,902,34,357,341,915,969,325,606,24,257,858,721,145,776,449,35,513,65,34,261,453,571,922,1,828,775,464,68,332,874,174,474,273,18,835,218,562,993,267,329,294,940,976,875,499,783,101,809,497,703,437,539,554,605,879,992,124,978,553,679,66,338,463,321,494,190,209,841,413,269,769,158,50,825,458,281,507,207,610,504,120,975,448,193,826,978,134,687,283,740,768,835,810,531,652,380,383,172,171,818,676,578,207,447,469,787,326,649,348,138,116,591,271,564,397,416,882,938,798,491,609,869,21,483,175,944,591,765,301,737,252,541,226,442,286,932,425,570,575,188,493,112,806,869,637,968,335,874,691,377,610,134,91,784,830,45,714,563,664,277,429,89,322,207,605,405,307,162,77,452,411,995,181,386,648,983,896,684,670,559,375,156,986,463,642,143,433,13,883,475,67,384,932,96,36,884,308,929,402,889,211,474,579,910,285,499,419,445,996,286,897,910,804,90,764,962,724,31,131,134,741,701,291,864,372,662,585,625,70,224,24,693,83,555,878,303,475,827,613,825,564,193,60,601,644,592,796,830,601,969,960,571,470,507,917,631,613,234,814,666,174,704,456,198,162,196,187,311,984,778,627,245,309,346,636,439,484,188,541,655,444,568,935,696,464,849,446,408,27,571,305,801,96,546,911,474,592,32,840,716,427,302,472,600,908,619,846,420,77,68,430,280,591,108,46,76,993,272,107,868,188,675,704,894,291,117,485,781,145,781,124,287,505,981,928,29,949,835,5,16,598,706,735,234,205,48,794,346,7,283,217,783,358,559,289,584,472,182,139,333,764,74,993,633,764,96,478,980,92,493,262,128,635,429,517,299,924,120,822,317,730,907,120,33,873,982,137,834,544,128,550,59,567,481,140,499,972,297,922,415,392,355,922,318,381,753,763,371,334,506,3,154,805,34,826,92,109,503,618,315,24,388,175,628,772,988,790,237,131,679,122,274,491,134,51,812,213,887,894,841,231,384,350,779,181,355,325,386,130,864,870,954,983,919,937,474,191,156,344,82,625,489,173,351,244,445,895,84,580,856,256,805,436,915,703,873,447,41,345,386,100,703,603,376,121,657,701,383,165,716,527,532,693,187,379,883,187,22,742,565,385,823,379,35,654,338,702,831,283,814,914,520,2,352,394,299,542,487,282,921,587,94,907,134,336,453,755,488,731,909,77,387,756,974,803,259,715,72,43,65,399,404,226,342,146,191,576,723,305,125,831,447,465,811,474,714,536", "311,950,475,955,981,116,175,17,955,130,543,802,347,256,675,196,858,446,775,801,317,86,31,868,528,377,154,37,809,168,904,834,93,121,705,593,351,479,358,612,130,757,729,566,959,0,6,724,543,988,115,77,57,895,461,937,927,240,577,446,911,730,121,10,666,706,829,350,574,223,597,242,84,744,143,320,905,56,970,226,730,847,430,181,909,747,484,314,293,88,145,787,829,321,109,713,80,751,677,343,149,465,147,230,414,359,135,152,210,493,857,226,756,687,951,319,492,302,645,746,643,244,891,93,65,314,731,612,946,72,363,993,738,322,149,146,57,563,271,613,419,245,753,322,614,785,24,180,286,790,673,665,709,70,434,178,251,435,978,154,381,586,216,602,24,14,203,459,250,873,932,820,282,884,361,649,824,783,740,139,210,637,573,876,580,531,725,977,958,190,547,14,329,885,23,282,627,863,816,542,764,504,221,711,465,898,568,459,392,282,952,85,994,832,846,627,951,725,172,456,241,270,277,755,743,73,551,300,755,858,909,418,729,676,529,840,799,718,130,363,119,937,484,974,572,548,895,771,477,444,416,548,839,866,944,507,960,391,601,922,828,419,384,92,976,986,914,793,277,790,936,846,947,26,911,872,39,137,827,227,82,664,862,470,578,452,784,89,205,896,911,88,506,62,626,653,887,498,963,44,929,638,867,301,268,150,723,928,922,333,41,687,161,336,672,688,647,973,201,692,176,825,270,716,643,71,241,974,881,835,551,747,718,705,917,824,908,286,391,905,854,697,123,46,506,470,522,883,70,615,972,501,869,404,331,689,719,306,861,678,27,942,66,603,514,645,533,337,44,185,681,156,292,251,534,834,388,763,890,530,617,827,800,151,226,335,884,395,86,101,871,366,23,359,757,174,811,828,361,53,21,988,910,802,529,834,831,833,108,560,317,917,453,305,148,917,733,36,260,498,913,757,319,87,203,304,311,955,708,388,739,641,126,124,16,706,582,60,24,904,846,820,606,823,932,6,935,715,705,142,41,143,419,373,992,13,617,518,148,624,292,293,459,640,59,644,23,176,109,381,43,142,36,542,61,990,153,414,969,190,255,554,767,523,74,259,501,118,735,874,261,643,629,478,483,32,2,729,440,431,258,669,708,679,559,336,384,487,400,510,910,700,704,346,686,953,944,617,935,448,263,935,77,915,74,441,870,110,28,878,962,180,203,776,773,609,6,405,235,168,80,848,211,782,282,716,656,956,360,886,94,469,941,188,673,968,298,843,892,363,710,400,378,477,71,656,610,427,635,946,521,363,873,144,176,939,11,58,150,564,31,717,480,300,58,722,848,176,89,760,589,428,232,345,89,114,487,655,584,174,802,543,178,778,811,925,457,322,19,358,8,664,192,674,381,107,947,911,338,804,908,510,710,190,16,581,804,747,615,408,32,570,261,523,998,181,725,396,920,18,541,661,670,407,124,243,513,419,336,935,965,684,691,299,142,711,209,33,826,788,798,818,765,900,730,261,6,907,751,630,334,473,346,846,184,432,276,921,908,553,781,771,148,295,613,967,801,39,375,36,836,386,601,486,26,153,699,768,631,653,471,537,758,747,652,476,768,612,259,861,398,548,157,35,332,27,896,514,736,453,561,463,958,21,598,333,843,906,837,250,916,81,325,891,145,790,621,70,577,219,858,240,911,675,450,774,538,126,126,14,258,50,909,486,560,706,254,906,653,320,758,310,195,663,85,801,444,861,193,108,288,307,959,796,215,4,731,332,14,895,604,178,401,389,38,787,684,902,638,104,562,570,942,864,352,878,5,251,824,828,8,801,595,321,232,454,41,435,898,904,233,121,130,333,713,483,452,663,449,671,832,207,86,72,305,743,46,953,542,458,196,204,795,714,772,417,72,29,191,553,423,285,461,937,404,92,690,979,994,65,671,146,97,767,510,451,768,73,385,740,738,750,618,518,815,40,402,955,619,107,643,608,126,628,431,727,993,807,985,651,724,361,772,444,159,782,965,407,517,721,815,159,157,169,280,577,838,249,328,600,859,980,975,975,686,920,434,538,465,727,125,671,646,368,712,625,630,921,607,760,481,863,288,260,848,850,384,303,219,337,58,895,806,116,307,505,770,484,881,135,325,893,365,675,255,958,552,614,389,352,225,533,683,581,444,260,786,5,542,582,5,308,25,327,226,693,452,890,620,926,850,669,825,259,254,163,989,707,164,332,649,514,424,719,447,257,246,252,400,820,497,172,307,4,326,542,846,547,733,647", "579,786,74,503,733,242,223,26,690,591,129,420,268,39,654,886,307,53,101,139,449,206,116,322,849,70,792,53,732,723,992,240,218,655,159,307,181,951,7,352,446,539,43,320,664,6,0,878,543,871,960,864,898,314,371,263,859,100,427,343,591,541,42,786,982,982,776,774,430,83,332,530,357,385,245,895,887,445,716,433,990,542,205,931,693,618,140,524,813,808,204,704,685,599,528,963,262,337,700,766,965,673,34,159,145,681,634,789,656,554,669,349,760,823,766,99,71,353,800,267,616,256,134,286,153,300,546,78,996,117,304,54,884,808,617,47,932,767,571,391,768,694,86,639,392,76,397,674,603,216,723,812,155,343,514,993,596,976,120,306,190,680,666,3,435,541,678,888,803,649,94,961,20,760,979,643,888,384,917,802,35,346,274,146,663,913,105,838,348,152,543,956,811,419,879,481,197,514,765,525,665,134,514,295,493,686,731,354,987,857,485,475,966,706,21,841,382,665,533,184,432,345,677,493,111,129,89,920,917,515,346,711,552,85,390,375,715,829,995,600,237,803,558,395,736,861,198,477,843,470,255,945,964,888,883,977,64,326,999,979,499,268,457,551,482,113,23,556,759,87,524,100,114,793,221,555,525,846,442,998,160,841,322,986,807,877,398,542,815,244,300,747,49,110,11,703,193,537,161,655,223,437,928,978,494,199,340,31,45,592,92,899,330,962,889,10,409,517,48,994,932,850,507,244,356,695,70,62,397,723,40,977,731,652,768,698,485,725,92,317,532,165,133,481,807,137,592,103,263,820,618,84,799,557,194,527,872,459,100,968,916,110,209,18,793,777,503,242,297,588,671,948,464,638,590,629,577,494,680,560,681,393,182,551,57,125,933,753,268,456,126,557,891,444,401,659,158,24,392,551,523,437,550,796,244,289,355,556,906,173,208,782,801,563,173,254,515,57,487,603,234,524,196,770,505,716,240,974,827,309,678,598,165,188,60,389,180,167,842,111,310,631,451,231,969,164,150,917,757,801,354,808,319,590,560,27,349,676,314,960,774,562,790,139,564,939,992,803,684,149,474,404,159,63,228,43,879,334,771,82,970,595,872,870,932,481,165,100,426,482,383,579,803,147,310,193,881,372,840,159,820,472,2,18,810,762,624,731,287,293,642,366,485,718,836,135,584,154,729,142,987,601,281,54,42,891,614,815,3,144,31,700,75,618,281,424,450,624,602,829,752,235,428,331,660,512,841,376,789,999,979,452,767,733,243,742,479,149,598,694,774,13,582,325,570,976,19,950,172,454,831,487,146,646,625,869,909,378,772,806,807,815,923,903,511,361,295,363,888,546,645,428,270,618,386,128,185,287,223,21,652,174,69,770,119,642,467,381,430,551,513,367,956,989,594,106,559,257,170,794,808,328,691,889,775,781,90,283,322,78,315,228,539,503,195,117,525,670,203,576,967,886,454,51,35,348,832,965,291,942,969,78,222,42,565,503,400,516,517,283,564,813,840,677,259,273,930,958,691,129,964,957,349,243,783,862,360,453,996,844,882,319,639,635,568,911,520,260,964,959,729,160,900,104,649,779,908,159,389,887,959,857,352,560,490,354,584,848,749,292,442,852,85,329,875,435,893,135,364,259,886,710,152,452,562,755,664,654,635,100,575,610,44,723,451,593,853,904,580,555,141,299,21,616,686,292,503,932,779,807,317,4,27,837,437,95,446,811,86,935,125,111,763,561,924,336,540,715,133,596,806,884,950,51,598,617,332,684,736,970,699,867,428,175,377,309,161,257,84,818,607,460,482,198,70,936,548,846,17,818,373,318,192,893,13,79,821,455,624,106,901,432,793,302,933,787,807,627,998,668,175,860,130,918,729,529,216,280,148,142,445,143,686,437,40,885,938,414,544,558,381,286,977,671,754,957,687,776,272,957,480,732,150,847,238,233,902,301,897,728,238,493,999,171,810,826,840,815,623,183,950,109,15,322,552,861,432,713,615,319,281,543,175,606,388,863,98,886,20,253,996,449,890,800,700,52,193,714,409,756,726,980,331,4,429,773,30,157,996,717,37,317,600,754,933,927,62,185,561,215,845,974,24,591,875,381,445,508,617,632,217,801,471,373,315,314,905,71,969,92,425,985,481,242,904,422,589,243,527,29,882,491,930,853,797,628,225,942,214,269,326,816,272,249,174,440,396,9,6,834,82,945,820,333,749,124,866,606,866,493,244,743,888,469,988,976,342,508,320,339,746,317,426,878,748,885,942,9,126,303", "58,101,324,775,396,248,988,520,491,875,72,952,486,184,65,340,636,749,841,906,469,212,597,603,703,102,470,659,470,779,30,860,473,534,602,816,496,740,279,534,885,283,24,297,268,724,878,0,954,597,947,566,935,507,285,939,574,729,932,68,722,984,385,833,142,311,526,407,612,932,686,867,36,634,818,58,877,334,932,151,520,315,194,554,915,579,450,146,852,833,731,701,168,826,204,450,367,998,372,548,419,242,148,83,378,378,656,215,764,816,245,342,684,289,397,792,411,968,855,884,684,279,183,459,105,226,422,140,800,934,827,590,63,814,438,398,407,4,420,889,479,727,952,261,61,826,742,536,995,996,737,952,156,899,126,664,732,947,223,986,931,385,412,749,734,237,299,512,992,876,89,160,518,446,556,430,775,431,407,672,150,882,260,972,854,416,83,692,305,396,578,85,196,939,384,506,310,381,901,980,350,10,368,520,98,518,761,690,462,476,982,979,752,821,358,712,791,998,415,221,26,613,23,1000,725,531,400,954,365,585,107,853,92,395,825,543,949,569,110,542,982,566,611,466,716,348,873,542,602,502,972,305,354,116,149,421,917,464,233,256,264,888,304,608,895,950,443,431,381,144,817,604,239,817,797,299,534,334,810,917,815,858,861,671,474,845,305,773,808,902,596,330,38,826,777,804,651,592,521,556,942,75,137,93,416,651,277,53,340,217,862,466,497,470,178,612,451,304,114,277,435,96,955,947,5,303,832,622,944,670,415,497,426,319,736,684,599,569,248,991,899,702,611,825,310,224,630,215,725,233,84,84,18,252,399,304,524,987,237,262,982,679,360,377,99,478,999,919,5,674,936,326,426,361,76,232,250,560,350,983,338,66,992,149,237,16,183,475,41,974,886,424,647,864,203,437,361,608,123,834,137,925,273,100,6,815,282,175,30,839,512,806,845,375,303,197,354,339,544,949,34,917,361,179,605,55,644,475,550,632,618,768,203,116,111,148,622,261,173,190,695,771,287,429,45,489,758,882,410,610,677,631,367,803,94,898,894,472,374,950,308,795,799,177,218,194,523,432,823,138,370,868,806,193,943,39,212,975,87,423,579,189,440,516,983,690,568,740,717,177,430,624,494,611,494,771,651,894,642,685,668,974,877,904,590,979,478,469,255,635,552,525,221,963,45,915,476,326,962,298,177,935,537,909,928,651,221,251,367,393,652,750,105,48,863,611,883,706,620,545,790,138,374,162,47,23,787,999,458,561,675,454,994,5,11,939,559,773,703,448,180,205,23,653,183,749,672,185,586,411,661,408,93,62,795,16,794,867,319,682,266,181,931,752,398,53,724,602,922,847,683,586,370,57,86,634,88,86,906,908,151,19,480,807,142,825,71,83,24,50,153,540,603,848,459,654,870,986,248,3,870,598,727,325,353,153,19,45,669,281,493,761,579,390,632,128,72,667,344,525,661,164,832,790,549,340,690,805,572,490,184,516,196,62,242,784,939,893,687,968,782,109,971,506,544,790,865,242,847,235,954,802,595,289,654,576,788,539,785,916,287,490,991,100,229,83,814,844,161,237,114,406,333,982,756,164,112,885,303,545,157,618,726,994,271,660,444,826,970,746,584,443,120,254,780,726,684,36,988,671,904,318,555,714,295,484,553,386,666,424,590,782,864,341,461,186,149,792,489,376,808,452,379,469,554,292,597,348,210,759,283,993,56,152,937,675,46,966,590,374,247,293,556,625,877,525,300,664,152,737,165,410,689,643,665,817,701,928,981,421,44,256,369,741,427,397,978,543,564,144,656,693,30,207,511,340,365,268,258,940,235,127,676,31,439,886,563,929,472,646,866,15,355,568,42,723,171,750,666,46,866,769,194,530,933,828,91,436,665,196,504,250,429,948,233,337,794,355,879,286,605,791,404,906,297,773,23,599,76,912,384,747,575,642,444,937,771,404,658,485,165,363,161,234,310,721,630,955,935,571,884,685,136,893,469,380,13,236,244,337,798,67,73,231,534,98,389,558,603,774,781,870,89,105,679,945,313,494,937,703,44,524,125,828,78,541,982,949,618,381,404,66,507,169,402,761,250,975,789,611,764,928,624,285,742,740,917,630,970,14,863,932,745,536,32,783,419,798,174,153,436,786,424,865,423,447,520,821,867,776,885,886,124,924,959,304,184,451,339,638,986,798,592,849,144,719,328,693,193,955,678,663,214,380,599,842,61,486,979,21,820,944,498,370,192,352,388,78,165,133,590,927,905,281,352,941,920,953,292,665", "145,888,59,396,915,794,808,62,962,15,529,8,9,807,908,312,277,512,59,787,118,1,499,543,763,425,65,525,156,511,398,740,398,857,29,240,790,713,299,649,211,405,58,213,830,543,543,954,0,120,144,121,842,607,660,504,730,305,31,626,434,987,994,786,590,488,994,505,801,246,509,266,241,253,644,804,462,110,628,505,939,917,615,522,916,142,64,692,7,564,438,636,305,23,157,310,414,264,472,536,140,26,562,135,169,18,185,569,721,704,898,581,825,663,58,9,535,55,964,816,134,606,246,403,87,782,754,184,906,604,751,336,486,51,707,915,94,202,505,370,381,289,748,509,34,584,372,906,718,155,204,894,159,771,714,320,299,540,518,93,458,639,715,140,556,79,558,551,220,544,269,290,976,111,624,591,566,760,742,832,63,553,889,431,831,258,557,70,150,803,700,571,636,126,294,112,88,141,825,321,789,272,838,926,308,400,825,180,751,665,81,165,100,602,429,488,853,977,133,732,598,203,826,753,878,940,763,989,427,656,660,44,230,999,754,928,751,504,772,613,176,893,745,410,886,589,86,285,384,257,129,242,495,412,988,699,378,991,360,767,492,160,396,227,996,350,984,165,560,329,957,790,458,140,571,730,568,628,259,978,126,421,240,713,818,649,800,443,993,594,601,841,134,705,564,154,849,331,417,3,266,592,920,340,124,989,707,840,288,104,737,945,843,605,352,239,469,269,609,449,107,817,568,439,440,509,196,224,229,189,424,448,27,308,242,409,212,109,462,954,453,670,253,152,159,629,630,912,989,578,349,299,65,976,58,69,262,641,999,484,981,255,424,745,432,161,823,965,843,987,577,133,498,203,730,555,170,266,137,937,278,303,359,116,657,231,618,343,645,923,469,63,701,83,197,379,140,656,599,368,109,14,46,453,825,69,892,414,112,815,101,837,15,52,955,935,885,534,404,659,909,748,131,756,494,836,448,474,459,46,332,522,813,827,38,719,990,699,97,89,88,369,926,530,618,268,900,283,575,250,256,346,46,875,177,132,31,898,478,849,469,259,207,770,705,782,581,702,250,521,6,784,18,893,249,653,95,464,34,287,128,531,379,160,579,408,51,598,52,535,251,748,71,910,669,586,401,353,182,912,47,759,296,208,212,414,739,835,713,23,407,73,529,101,852,655,786,49,838,352,257,148,887,105,10,346,286,162,305,440,989,564,392,447,100,626,777,874,280,185,508,193,659,245,212,723,397,735,475,558,742,432,768,196,557,435,801,139,630,217,608,993,825,73,243,429,827,481,319,43,561,835,672,109,661,344,307,437,839,61,618,739,215,792,836,108,894,634,793,402,653,756,44,683,696,346,82,233,73,510,378,917,67,257,733,359,110,269,803,854,801,967,880,225,847,355,182,662,84,407,338,789,269,830,30,755,875,828,697,22,723,403,73,729,888,60,556,347,316,173,667,145,94,650,491,307,674,941,760,510,255,716,754,518,228,416,781,643,844,447,709,942,590,691,53,513,109,658,802,847,409,782,262,741,797,826,525,863,431,75,441,703,669,318,917,762,502,887,171,422,888,572,76,304,796,607,718,784,852,341,251,580,233,390,833,976,521,411,667,618,237,796,521,494,23,618,479,343,751,778,299,382,393,458,390,368,83,200,467,363,302,356,309,839,276,804,111,870,734,670,143,455,899,13,974,30,726,706,68,455,962,738,768,149,131,206,616,729,533,686,323,489,454,381,221,386,991,256,595,683,767,10,318,772,789,354,655,491,574,179,870,70,952,32,435,798,213,87,742,291,555,154,773,428,201,621,398,769,412,398,827,534,359,729,142,202,852,783,624,543,261,333,215,871,782,448,860,191,783,380,7,453,608,729,477,60,284,642,28,13,384,472,176,414,496,360,166,816,667,305,864,851,244,592,982,120,278,365,860,646,843,39,576,825,843,207,325,317,489,655,365,450,724,496,959,655,513,659,214,721,865,827,369,282,13,441,115,514,622,204,746,867,896,416,799,631,868,329,923,828,503,428,572,33,160,631,952,909,793,763,387,463,940,388,590,360,736,877,542,431,406,126,660,399,770,355,132,608,492,387,836,656,834,112,50,937,516,30,186,965,893,699,137,400,331,144,439,102,309,246,591,239,705,2,973,454,320,62,348,690,332,183,121,469,676,104,318,960,332,500,476,636,293,804,660,657,642,763,273,712,16,489,139,103,547,703,217,953,192,522,152,7,779,96,191,695,413,562,641,722,642,717,325,382,535,137,924,388,888,776", "304,750,349,520,102,281,296,551,786,187,848,600,299,183,547,440,311,341,565,718,909,443,229,476,327,306,824,153,464,273,35,164,771,147,494,12,304,401,800,208,143,356,214,597,946,988,871,597,120,0,676,502,739,122,757,469,633,597,41,405,468,844,833,882,61,303,311,633,845,962,279,929,861,321,730,239,620,591,602,637,908,466,279,737,671,976,754,190,725,576,536,503,441,352,670,428,548,302,619,309,10,575,299,458,834,823,101,191,568,444,920,335,545,426,436,481,814,122,73,153,324,801,623,257,410,506,310,232,569,213,115,760,311,452,267,585,247,765,765,436,775,745,639,254,760,726,697,517,785,256,652,395,425,136,977,476,578,360,284,576,977,693,578,37,529,316,369,319,3,254,767,798,511,921,902,641,84,477,72,985,107,594,931,776,219,570,402,912,86,371,138,484,350,953,500,393,719,414,481,903,234,983,665,641,354,314,461,384,678,319,658,566,896,539,551,545,464,928,908,964,81,527,250,529,739,648,126,785,787,483,607,22,896,764,778,574,188,453,589,4,445,477,536,686,14,709,858,624,656,28,661,59,456,376,917,643,524,6,219,789,485,813,513,120,622,994,11,538,477,303,877,192,686,505,385,606,983,160,773,506,796,884,883,297,984,298,131,557,58,991,133,298,236,369,73,367,980,391,937,87,155,677,719,276,513,495,732,614,960,988,185,3,105,677,718,699,87,721,999,948,427,170,5,253,268,328,151,349,164,43,246,111,753,969,566,774,757,762,441,330,262,625,702,419,168,311,198,724,516,774,36,444,272,943,157,391,454,109,107,251,936,801,796,547,295,456,200,992,40,768,948,877,942,706,327,424,856,22,21,807,80,575,927,770,619,671,733,304,623,340,282,725,375,71,441,631,891,157,309,783,267,952,396,963,806,553,247,724,14,59,549,942,110,880,558,165,415,626,222,91,943,507,397,427,856,183,238,392,330,766,552,68,766,558,211,994,491,755,494,583,848,805,124,379,487,369,879,180,385,757,762,958,347,124,477,706,673,710,142,131,146,260,921,918,457,55,657,810,269,104,533,883,851,944,671,296,821,648,625,648,530,673,465,474,693,38,887,508,395,940,197,678,443,755,363,672,740,683,307,607,152,472,691,793,167,994,352,575,693,153,526,444,954,287,358,206,204,151,209,972,687,246,262,29,737,508,894,813,244,731,960,127,194,899,943,924,599,490,542,646,27,691,165,950,802,675,390,680,827,631,981,301,656,778,299,902,65,307,131,106,249,53,544,319,228,527,964,731,251,893,671,283,241,719,608,497,244,256,268,661,462,639,846,112,337,195,563,707,592,712,935,631,11,559,509,502,363,230,211,56,966,319,35,463,489,3,227,837,186,939,418,312,432,995,268,116,871,344,922,996,430,999,737,827,866,986,452,818,646,432,519,411,747,603,228,424,570,749,837,607,335,929,205,12,628,580,921,177,998,359,22,565,718,842,563,748,353,631,772,273,376,806,561,538,218,8,756,93,322,964,304,874,790,495,918,831,615,380,428,353,467,1000,352,309,698,359,766,260,480,545,97,358,115,623,249,907,868,809,1000,409,26,968,687,876,495,233,21,552,429,254,473,927,853,967,976,665,306,923,34,884,724,416,296,899,681,543,708,657,572,249,99,117,784,352,564,804,718,890,781,835,316,563,897,312,274,436,953,677,611,191,463,485,814,143,628,54,801,735,307,302,808,720,190,751,484,8,984,773,960,966,579,515,797,897,376,106,321,985,2,376,167,212,317,28,670,400,180,567,548,542,21,951,435,937,954,155,906,244,86,319,151,357,470,538,670,747,607,349,867,59,665,491,544,428,813,582,653,926,53,29,575,970,253,886,899,813,649,899,500,940,922,184,222,425,445,285,593,409,591,773,601,918,39,757,521,935,513,549,466,346,148,493,622,312,644,990,680,769,612,73,86,979,608,431,988,850,905,597,779,67,657,82,107,77,186,941,706,61,156,241,674,195,493,115,41,836,974,342,432,275,251,394,572,873,983,146,641,312,404,407,74,951,898,857,831,30,847,776,340,528,337,9,755,469,985,444,711,340,966,811,750,791,858,531,595,813,677,718,389,273,272,288,338,251,904,200,98,28,854,565,705,292,46,140,776,701,943,153,760,187,238,750,247,701,849,896,228,963,625,320,112,376,124,592,207,550,674,930,269,791,897,19,694,326,430,852,912,594,321,611,629,954,332,602,139,566,402,164,995,963,961,568,305,390,22,101,101,970,958,407", "133,550,120,652,122,805,3,559,155,802,167,243,597,471,131,30,413,949,609,463,631,810,688,937,234,970,547,516,66,761,59,145,379,130,890,690,743,891,601,203,367,594,419,810,536,115,960,947,144,676,0,62,384,383,596,12,461,343,664,102,343,365,762,658,710,988,143,26,323,707,419,205,413,312,821,385,819,908,427,461,358,398,746,348,821,91,491,707,481,765,919,488,5,641,215,755,240,300,833,932,391,724,911,519,703,768,78,257,926,504,237,979,530,521,793,444,684,486,812,16,956,229,834,673,1000,519,894,195,648,694,439,448,916,436,870,954,182,595,385,203,827,294,940,692,671,807,19,112,328,276,290,835,365,933,889,536,435,444,670,872,934,231,941,402,650,790,718,948,194,636,354,817,614,390,967,624,459,756,521,339,160,248,53,564,413,965,148,499,851,521,930,284,251,487,706,61,650,211,89,255,786,500,858,630,214,953,471,53,603,737,598,729,135,990,208,624,489,393,311,375,584,134,240,84,825,531,411,204,406,819,214,236,569,638,904,55,349,555,950,540,823,844,862,844,498,532,564,831,228,753,327,564,782,212,826,229,566,543,373,198,825,709,706,848,361,355,506,875,787,604,584,373,83,258,512,936,197,639,22,753,104,298,491,507,337,626,475,809,641,18,876,734,530,398,668,921,840,243,365,219,487,594,767,398,157,384,344,338,546,89,683,42,419,100,854,202,457,218,412,680,200,102,123,112,161,395,126,584,800,453,434,411,513,847,332,677,105,413,912,641,376,379,434,458,937,179,258,429,692,192,446,894,527,182,691,728,752,826,328,773,481,106,792,128,89,505,7,842,223,58,592,372,287,962,454,654,185,710,580,926,274,656,93,383,121,318,980,832,441,435,236,987,548,723,535,713,554,435,557,277,957,498,709,154,550,824,166,89,983,431,911,522,208,389,912,341,120,192,611,16,50,678,119,131,847,571,673,422,576,681,437,710,320,583,826,539,54,888,191,97,83,989,327,372,613,710,184,734,656,368,38,996,268,444,67,647,598,22,323,441,161,223,742,200,303,956,564,698,819,794,698,173,583,358,133,128,254,161,737,942,424,221,65,625,46,148,218,744,703,802,739,60,695,421,561,684,276,570,324,919,943,728,38,639,341,104,597,696,338,686,474,232,439,790,658,458,9,561,88,976,244,278,45,993,939,700,968,57,573,740,756,948,524,452,575,917,606,54,246,652,744,343,334,439,649,950,920,962,800,985,885,189,400,5,608,85,814,221,198,395,725,877,864,271,768,666,986,947,272,697,125,863,889,439,396,699,999,454,191,686,109,998,403,618,511,278,345,603,171,647,157,975,251,252,2,203,523,425,431,661,854,961,639,471,837,991,289,665,235,777,461,691,595,212,642,710,769,719,587,357,563,830,500,928,18,765,130,224,371,420,3,54,858,233,713,333,196,216,675,778,150,613,530,755,484,624,49,30,204,523,176,165,580,897,352,972,259,938,311,305,73,610,518,95,444,494,918,825,795,862,910,438,505,516,450,214,125,184,607,526,945,476,977,741,629,2,366,623,956,503,685,306,959,362,398,32,804,568,482,999,945,782,67,504,598,377,837,357,542,110,309,186,45,536,913,200,427,322,682,356,915,283,195,431,87,801,545,784,452,932,143,856,745,267,250,421,733,40,854,186,123,106,933,809,383,264,588,234,82,557,451,218,721,873,646,738,205,343,975,175,904,80,749,257,199,338,244,554,513,615,312,784,360,739,599,367,849,380,786,229,80,204,341,820,624,806,44,482,494,304,419,477,648,697,750,317,615,507,495,631,703,837,637,313,952,700,498,946,295,780,378,898,23,128,946,296,526,540,248,501,945,829,478,564,595,940,363,723,226,594,403,811,565,435,783,418,5,873,363,20,571,281,705,952,260,161,149,510,588,690,967,467,795,272,276,452,234,963,474,515,874,142,851,81,758,624,547,966,455,604,2,157,615,758,638,846,966,339,954,187,605,530,102,802,91,684,571,586,624,706,405,859,406,930,261,430,19,653,33,473,987,357,820,205,431,717,949,449,713,703,151,392,264,183,477,11,968,893,337,172,151,541,586,641,27,432,587,178,670,348,729,829,964,845,620,91,789,467,807,728,196,11,764,633,598,718,374,792,639,532,562,219,273,420,895,408,706,731,446,579,517,700,477,26,286,433,386,20,856,449,674,383,836,720,700,584,947,560,582,321,45,600,916,199,838,964,298,784,714,418,892,972,553,534,845,378,960,213,273,861", "440,293,555,572,905,595,216,991,695,769,509,323,386,522,166,811,744,115,600,818,847,940,965,625,107,951,889,88,480,417,817,473,679,932,905,244,367,908,318,99,99,265,195,563,541,77,864,566,121,502,62,0,442,871,933,416,80,303,135,927,358,213,286,258,314,313,386,345,142,532,224,538,322,841,542,253,292,85,628,878,200,769,758,255,889,867,25,982,191,359,8,707,712,178,607,46,647,932,91,135,844,952,158,516,993,183,812,275,606,919,118,822,187,124,274,333,454,82,494,372,879,364,363,408,547,884,164,152,363,644,879,307,114,915,520,470,281,476,915,780,651,321,426,268,180,415,712,408,429,201,238,389,936,144,993,833,150,150,846,518,566,714,633,221,763,42,622,555,125,298,460,24,192,11,352,743,369,864,227,716,241,107,384,700,748,36,192,145,908,207,718,845,694,909,240,897,104,989,25,822,584,219,629,899,11,135,564,899,496,23,609,724,675,602,97,251,182,324,932,262,770,835,29,73,557,600,240,944,84,570,871,137,840,465,621,171,559,741,253,831,777,447,825,961,978,88,952,530,159,50,932,16,213,113,496,252,496,48,426,435,159,670,752,2,245,553,371,238,718,896,713,412,38,581,109,370,753,538,950,710,32,880,367,920,758,311,291,63,503,296,260,588,494,647,42,254,629,800,52,531,879,869,797,687,759,347,113,144,352,842,711,150,807,959,53,426,45,819,844,83,523,892,217,748,466,10,654,932,73,790,543,88,751,233,515,798,633,887,50,67,590,315,191,611,599,495,52,655,52,774,997,469,134,92,666,516,470,589,680,906,32,522,704,133,238,531,394,327,198,477,320,980,635,11,506,481,954,822,212,215,828,333,636,344,782,119,80,491,360,651,183,270,103,869,485,622,545,594,561,599,830,143,976,120,844,326,720,365,529,93,900,601,413,611,203,158,782,969,782,838,173,162,549,89,118,683,468,946,427,110,672,336,130,135,466,814,864,259,996,579,420,855,902,481,497,562,331,422,773,240,606,95,594,208,290,742,364,122,338,266,127,816,721,31,778,340,463,689,748,587,899,816,666,986,709,285,397,528,936,408,190,122,977,822,379,289,145,99,682,833,729,113,346,499,577,488,402,290,305,356,651,530,56,373,125,673,499,737,985,394,65,287,417,814,928,334,505,811,515,656,600,876,112,730,11,895,830,711,400,749,160,685,529,121,339,876,789,558,127,331,820,114,827,150,832,559,149,47,322,272,606,921,884,195,985,617,513,431,788,609,769,537,768,214,42,415,293,641,390,830,161,517,319,753,115,675,186,53,350,648,583,194,180,307,283,920,605,130,467,436,781,948,94,605,592,78,285,759,873,839,321,619,294,462,97,296,121,815,190,642,220,989,113,314,39,965,771,103,836,31,976,443,425,846,306,47,406,589,67,579,232,266,393,322,799,767,968,768,472,703,533,567,232,778,387,742,111,6,453,733,559,930,560,860,596,385,430,454,143,577,374,241,582,505,537,58,262,731,806,323,964,747,653,835,2,908,791,619,904,906,447,129,734,411,178,7,554,774,461,650,208,517,837,868,770,152,568,238,143,457,931,464,363,29,601,915,674,485,409,185,721,630,438,251,31,138,165,850,573,317,931,75,249,1000,693,811,400,982,674,139,261,752,148,178,211,878,120,681,47,741,284,389,23,997,646,869,280,651,524,380,377,638,647,958,134,591,165,629,420,472,355,915,417,281,756,615,408,249,360,919,131,852,75,743,428,629,915,242,397,955,495,533,853,322,30,696,46,301,57,501,331,33,205,871,220,727,522,633,660,544,598,292,292,916,232,914,982,548,934,52,300,277,135,737,78,691,249,291,639,495,992,462,747,337,911,907,257,282,440,620,870,430,906,166,85,373,143,96,986,207,391,712,576,887,673,537,11,448,633,781,838,603,639,456,758,451,882,347,928,375,641,77,912,614,329,961,48,754,120,920,443,205,873,366,146,264,568,826,159,945,736,132,373,444,302,402,486,274,547,556,249,120,638,355,579,437,410,173,700,133,990,724,575,189,74,6,899,292,679,267,176,898,216,688,781,920,63,455,660,205,987,614,352,484,366,935,551,872,127,307,342,301,494,913,980,595,960,391,563,775,358,894,809,694,416,627,675,119,32,362,49,200,822,550,692,271,4,721,481,568,140,676,817,711,296,362,169,794,815,579,632,435,313,129,875,888,292,443,104,941,339,624,115,899,179,894,972,122,56,12,778,566,91,124,87,84,738,30,799,136", "159,584,62,404,891,59,197,725,926,214,840,748,352,274,475,652,988,55,483,851,359,799,829,980,613,945,90,746,332,813,89,502,342,814,937,765,765,530,951,308,258,179,449,743,953,57,898,935,842,739,384,442,0,805,491,400,320,458,926,37,841,201,449,112,87,780,969,761,667,22,215,841,437,264,337,332,611,854,102,911,569,467,657,663,370,524,753,228,668,354,939,477,394,828,808,285,999,993,305,439,222,138,98,421,19,816,28,657,449,717,880,445,896,366,534,247,565,334,375,372,734,723,188,809,72,896,447,560,117,172,75,350,945,334,738,495,44,115,538,12,953,45,613,321,790,295,762,274,309,541,51,993,438,683,949,169,414,981,438,385,851,284,904,981,344,92,547,68,413,952,730,897,592,480,212,407,758,996,166,423,337,865,421,229,167,580,653,349,405,622,650,337,361,352,784,846,14,996,23,234,269,328,994,622,697,77,134,364,993,859,922,713,939,786,952,392,882,176,426,295,37,103,969,86,251,247,492,815,802,825,88,447,726,566,270,493,77,45,690,709,514,405,66,737,522,247,692,265,633,504,386,81,65,606,733,278,395,453,781,804,854,66,762,734,317,393,90,213,735,305,179,820,764,338,775,74,496,623,906,405,329,792,76,900,634,67,180,569,240,612,329,657,148,513,51,794,743,850,484,388,49,141,81,513,998,567,269,485,710,695,538,491,205,325,151,542,983,674,589,760,476,569,860,972,882,725,778,997,339,694,658,392,420,354,58,896,336,224,297,714,894,959,56,233,658,67,113,562,154,708,696,743,44,898,414,87,412,492,356,19,614,215,843,734,804,105,479,94,445,726,552,367,44,99,667,530,95,392,611,163,785,212,334,808,798,723,456,114,153,966,788,436,786,236,802,749,950,79,879,936,294,934,803,963,887,849,127,288,565,456,92,112,757,642,533,139,522,669,128,647,905,633,491,797,149,106,429,560,416,252,199,135,996,691,34,576,960,39,719,953,524,311,287,460,714,335,173,57,969,753,370,632,939,784,88,274,429,187,737,974,687,576,968,528,375,119,895,635,371,165,7,31,805,51,587,65,657,732,620,267,604,797,894,877,717,937,528,728,796,450,968,814,538,980,506,526,337,631,63,961,743,890,697,62,290,834,821,390,122,148,540,217,655,462,187,911,980,510,641,904,256,247,831,645,966,55,234,656,363,350,64,790,760,999,736,258,943,713,134,529,227,773,151,2,352,801,676,236,421,904,128,930,829,681,658,991,773,785,207,458,747,77,939,663,173,425,887,64,57,76,201,303,488,794,151,483,416,685,818,380,487,794,12,377,436,522,173,222,576,219,262,371,8,542,193,771,169,749,31,115,510,802,761,36,942,40,427,511,554,305,226,522,503,380,832,811,993,211,377,647,305,405,450,644,171,322,808,147,708,802,8,638,152,458,953,568,685,265,189,568,545,121,371,109,603,475,4,750,840,31,840,928,536,719,261,365,336,199,72,308,312,286,964,583,351,404,453,437,543,566,786,907,560,361,33,48,907,165,868,290,483,491,795,912,244,520,949,247,192,308,124,767,428,628,100,579,874,177,988,677,412,531,45,606,659,776,742,347,714,186,160,646,159,137,62,787,545,978,531,95,176,598,569,142,325,463,404,409,908,376,30,684,817,631,814,712,704,870,738,563,903,47,292,368,582,509,12,626,993,683,238,756,135,67,655,475,150,389,540,678,180,181,717,966,868,245,96,243,819,414,713,875,513,915,277,192,16,900,473,709,368,538,205,473,159,110,589,603,1,896,884,501,291,575,527,744,187,624,823,751,90,541,29,761,902,877,762,220,170,222,446,318,940,956,662,729,324,528,804,756,506,475,475,63,287,836,857,913,776,477,358,741,593,656,840,642,127,798,660,322,89,214,538,336,252,592,870,511,481,8,469,683,98,340,67,682,2,352,649,159,258,756,193,392,335,980,972,824,660,920,538,52,659,874,511,894,197,771,683,813,184,36,140,231,663,470,839,60,115,402,12,515,482,275,242,892,487,532,884,847,659,69,12,995,371,783,527,846,52,50,42,361,973,80,702,569,832,794,355,864,506,538,218,724,154,774,497,736,570,834,364,800,776,363,567,812,660,384,331,734,882,778,25,407,94,809,662,487,592,954,533,347,914,516,250,158,962,433,470,940,642,521,418,123,654,397,582,126,295,605,363,168,235,755,42,313,244,829,205,918,941,766,117,635,686,460,958,237,13,529,652,711,109,889,90,635,992,279,287,956", "219,254,299,747,296,924,192,857,374,671,471,412,938,155,995,51,697,309,562,42,805,698,632,128,928,636,460,365,55,184,224,670,853,413,977,408,359,467,884,108,196,605,860,121,851,895,314,507,607,122,383,871,805,0,163,331,865,503,804,944,606,503,596,459,776,297,349,623,522,408,110,605,863,62,433,646,421,750,220,541,746,185,989,259,256,280,732,46,377,620,978,557,766,803,629,444,916,625,52,511,181,689,100,703,894,812,741,741,15,551,426,500,432,35,24,912,323,144,814,918,173,825,940,300,552,167,83,102,234,572,23,285,771,529,386,469,539,672,892,398,978,343,171,585,413,276,425,432,548,741,799,695,227,197,291,36,747,523,340,172,476,688,964,976,693,794,11,869,107,94,525,732,226,811,34,78,222,381,923,707,62,263,603,346,559,956,558,11,60,390,521,144,941,899,572,266,757,944,127,541,288,420,479,519,851,362,735,333,82,101,683,697,2,696,486,578,241,201,89,146,616,67,482,468,251,873,266,671,650,348,21,180,635,40,431,813,807,383,728,290,3,660,642,958,280,73,337,244,431,5,651,214,644,421,472,538,861,918,703,355,222,708,650,29,867,90,203,767,243,434,434,534,811,378,511,91,477,34,697,726,534,495,987,650,320,581,218,586,964,841,929,207,178,973,71,318,972,818,539,971,524,708,201,465,312,865,230,646,31,693,581,551,52,865,224,114,224,62,586,674,363,171,808,202,77,543,889,934,419,887,541,391,736,346,887,511,340,513,904,800,452,2,417,114,338,276,466,968,91,283,827,445,324,676,274,885,448,746,685,220,709,627,587,697,39,667,521,560,603,208,224,8,578,519,930,647,919,153,723,989,648,819,132,183,550,843,888,928,237,596,59,921,993,880,472,860,107,560,408,359,464,104,410,562,301,679,840,271,18,386,559,861,532,891,565,879,755,389,382,474,465,783,530,728,164,457,420,712,769,54,74,206,2,812,936,388,220,558,779,813,552,602,35,306,451,366,617,742,763,653,669,563,247,14,303,393,453,188,404,190,505,566,477,688,31,62,137,835,178,106,618,901,515,890,934,320,883,484,857,657,597,648,995,849,898,143,832,165,663,538,972,830,514,363,390,34,324,795,733,911,572,272,3,292,474,990,769,183,854,123,537,549,913,97,763,496,236,939,643,412,148,508,200,930,365,930,435,108,545,399,219,63,732,698,465,566,360,68,63,164,351,855,209,646,480,256,55,283,737,978,935,979,377,574,546,196,833,272,6,508,203,524,288,658,984,944,179,611,565,208,303,644,461,985,271,684,477,196,209,149,127,353,176,618,710,817,743,564,850,829,874,105,606,845,387,914,137,181,690,964,928,824,262,3,862,528,135,559,547,451,607,367,614,826,436,539,649,106,139,178,868,306,909,982,633,266,881,288,560,338,452,947,111,259,304,761,238,894,528,869,821,853,878,851,582,732,431,922,434,46,805,196,72,13,321,693,876,899,678,754,149,420,451,626,34,397,563,678,645,727,914,919,88,612,299,54,223,532,84,628,469,94,566,821,919,875,588,825,189,462,530,956,16,864,820,315,134,942,127,810,937,744,47,894,267,377,729,40,482,391,529,918,807,224,181,977,802,970,19,60,961,332,363,36,246,757,886,506,249,267,69,582,630,409,410,971,501,952,780,162,850,244,622,974,958,122,380,508,971,172,933,59,777,169,689,222,643,220,35,453,106,923,180,294,867,669,802,72,866,804,845,249,761,766,435,492,415,384,303,80,401,842,306,595,817,127,329,85,528,479,866,611,515,179,875,535,842,592,313,335,811,873,270,472,674,152,641,521,958,491,669,351,833,353,979,205,731,245,44,316,510,407,123,590,268,801,807,355,354,136,250,656,562,184,456,342,686,853,565,413,931,710,713,800,975,615,217,380,496,492,777,20,357,446,149,12,546,796,768,611,461,454,416,968,54,42,94,91,596,944,512,92,86,970,664,326,515,417,223,316,799,421,408,728,345,266,176,835,679,467,926,38,521,808,433,987,563,6,618,773,825,252,871,809,451,877,925,523,27,703,793,259,848,784,259,391,669,254,997,8,7,385,751,855,682,113,78,967,225,51,923,911,37,957,334,50,83,120,941,566,960,351,191,850,205,777,846,355,787,632,764,239,360,649,170,370,696,88,870,66,735,568,821,285,515,967,832,169,951,799,607,671,829,279,418,799,679,869,153,748,905,112,612,957,469,613,770,972,265,308,295,595,459,524,763,790,218,177,816,895", "300,732,840,304,198,109,807,542,383,331,851,46,893,496,10,758,463,951,234,296,622,861,71,910,57,924,677,255,412,955,157,332,453,613,346,961,16,603,884,1,77,753,328,71,468,461,371,285,660,757,596,933,491,163,0,150,664,288,651,186,9,900,286,411,567,180,129,469,148,152,858,30,862,57,327,264,807,795,478,700,724,145,811,360,138,870,301,672,109,702,864,175,15,782,801,999,828,740,342,527,334,931,775,504,897,339,744,323,703,988,920,807,743,674,780,295,983,25,575,424,496,669,414,71,50,652,776,781,804,494,628,856,664,315,163,399,551,16,105,936,178,778,287,305,412,222,4,602,637,568,820,754,257,474,817,618,573,563,11,771,78,587,430,987,392,602,14,829,554,981,945,545,569,437,385,431,134,941,39,985,247,402,735,473,505,278,266,668,186,263,520,417,898,267,715,126,730,585,972,732,232,115,996,636,379,285,278,892,932,116,617,739,98,581,17,81,243,190,405,995,787,399,566,291,216,792,673,503,385,205,185,491,535,191,43,370,628,544,83,915,726,42,392,241,934,907,739,888,720,429,512,872,954,188,619,632,51,851,765,535,379,432,170,444,161,463,525,623,4,4,316,414,423,120,498,766,630,605,499,108,953,255,494,853,283,403,568,162,261,888,918,416,2,90,990,963,84,399,915,272,117,762,979,304,63,19,618,833,670,438,373,333,956,3,138,644,295,442,130,310,539,568,925,176,110,957,377,521,506,688,462,690,786,897,55,993,650,174,993,402,543,422,930,263,482,316,182,234,262,138,86,760,528,744,443,565,845,939,176,289,532,883,476,424,321,976,688,935,76,644,670,102,51,498,691,290,132,167,970,130,627,532,194,732,101,385,425,564,511,413,689,466,681,426,474,271,793,794,420,934,922,382,345,970,320,771,342,961,300,954,709,213,727,824,434,431,47,63,281,217,146,578,943,401,412,326,416,758,809,971,898,385,155,958,831,393,618,833,405,737,340,917,563,903,859,688,541,431,160,559,92,648,146,652,533,407,859,17,260,628,59,580,804,504,612,524,417,664,53,597,606,624,549,645,753,387,638,116,777,831,366,163,840,10,700,997,825,688,631,427,171,403,201,101,406,487,751,155,769,400,122,956,171,834,176,119,682,552,508,913,615,3,955,124,281,273,895,647,325,832,432,886,693,857,192,362,629,773,355,320,459,232,476,563,740,645,766,794,704,160,523,246,267,265,345,674,584,51,274,91,112,894,946,231,760,908,163,201,924,121,976,43,354,876,809,597,117,393,858,628,363,413,654,781,720,494,432,50,243,752,426,801,624,641,521,803,262,81,406,325,389,884,789,416,803,643,275,111,520,688,275,588,223,311,307,3,261,914,106,975,758,847,946,621,961,503,703,120,879,192,321,466,532,652,822,265,840,681,287,388,83,166,969,452,160,389,263,337,479,331,108,240,56,921,210,211,410,127,808,380,670,404,130,274,509,564,687,76,288,371,584,20,129,629,271,902,245,19,824,220,834,40,60,515,930,206,878,729,11,498,253,403,46,390,230,979,881,260,23,19,989,169,408,974,187,993,919,912,220,324,762,461,573,420,779,688,193,658,873,845,730,834,224,738,860,17,183,863,797,133,170,603,659,26,719,681,929,324,896,565,851,345,869,16,935,682,753,853,680,428,963,641,479,684,719,108,561,643,592,562,522,431,839,462,389,939,700,136,664,351,164,308,325,466,172,114,238,789,166,266,334,120,701,972,132,438,642,590,61,729,837,664,552,304,104,14,838,41,812,714,70,856,982,822,970,702,664,141,430,306,719,474,145,359,303,420,343,163,67,285,868,402,896,506,414,61,48,202,817,37,813,614,473,943,597,434,96,486,707,844,942,138,648,850,494,541,801,361,81,686,310,585,897,663,706,670,724,144,920,201,582,512,327,706,686,118,686,173,275,880,778,604,112,726,603,704,351,753,653,966,71,687,714,17,826,791,200,846,779,263,52,543,941,315,662,838,165,319,490,735,491,664,235,703,385,921,733,203,846,261,691,825,439,599,691,127,146,414,862,355,315,444,469,804,652,509,817,547,198,857,18,853,358,809,196,598,508,972,376,116,745,477,84,365,927,232,869,411,747,544,735,887,298,169,408,178,102,526,443,393,74,2,508,916,355,101,382,482,639,66,55,425,472,861,204,344,208,546,165,395,296,804,857,798,635,424,78,982,815,394,700,630,313,336,154,119,859,628,382,539,161,423,636,259,143,62,791,574,199,714", "855,694,451,949,736,36,627,434,406,611,544,140,767,90,529,529,635,611,912,9,712,924,116,71,591,752,734,772,873,183,955,922,121,609,35,959,450,945,930,202,706,735,109,497,50,937,263,939,504,469,12,416,400,331,150,0,645,237,340,118,864,315,648,709,634,385,641,168,699,3,683,300,596,454,693,514,294,442,14,178,55,462,110,910,160,374,113,768,315,491,228,697,168,431,511,321,34,878,703,858,635,320,913,668,439,904,625,105,99,31,570,868,628,182,513,231,699,199,348,438,318,999,24,584,245,895,739,641,503,469,160,448,214,846,391,894,550,629,26,351,426,935,519,426,551,602,129,131,817,634,212,145,381,957,726,789,470,880,752,8,962,831,300,411,72,419,857,28,198,297,203,109,795,960,305,689,842,760,658,103,810,317,494,859,828,176,9,88,288,419,617,24,500,68,502,852,211,78,912,539,640,857,372,153,545,59,71,29,398,614,767,681,338,731,309,755,181,256,837,750,299,864,136,904,358,982,867,437,681,764,299,248,57,538,65,441,803,644,756,978,606,812,319,308,163,774,496,945,715,468,335,353,765,423,463,167,632,144,871,698,423,509,133,251,86,177,295,551,644,24,611,644,642,786,284,190,90,974,14,276,147,353,413,252,730,111,742,833,657,67,356,965,854,295,502,97,926,775,403,681,128,518,522,844,48,914,204,127,98,994,660,434,844,58,744,620,381,715,365,116,438,332,158,37,918,397,712,651,306,342,72,932,267,563,795,917,702,965,885,223,170,10,667,729,142,361,850,716,516,129,930,624,77,113,768,254,550,770,641,591,178,934,391,944,756,916,250,781,786,704,464,16,575,434,35,317,279,845,764,925,210,61,797,272,519,38,509,110,845,960,858,254,798,760,164,613,130,594,161,865,829,696,660,590,61,196,722,718,572,116,665,216,186,901,911,256,483,36,349,711,520,114,773,848,355,550,43,174,257,847,518,298,80,615,106,213,60,407,55,597,559,410,8,228,462,880,350,167,230,370,11,147,620,757,795,938,9,754,60,931,422,730,991,96,713,286,498,142,794,979,653,273,978,806,931,258,127,722,814,508,533,846,961,851,560,716,321,951,572,233,35,874,472,568,987,94,26,258,18,68,79,715,665,183,513,671,307,923,20,16,655,213,851,193,724,305,195,139,115,971,58,481,920,980,231,910,593,928,698,724,922,973,173,998,206,603,195,823,714,593,92,327,410,1000,112,417,816,688,379,155,774,552,474,256,916,299,37,224,948,8,470,661,559,140,558,54,463,574,967,869,640,370,273,633,77,966,540,162,831,567,67,679,167,965,942,225,79,860,757,7,14,755,520,636,762,485,458,253,31,340,918,415,381,315,378,234,97,880,412,168,179,283,498,887,153,145,358,536,190,747,558,285,70,76,658,711,348,941,951,204,778,906,884,395,312,480,439,603,580,440,104,463,818,125,126,268,894,203,106,729,109,412,258,906,15,869,413,233,219,865,385,991,979,479,931,960,442,317,336,305,36,70,543,97,413,445,421,344,626,353,853,173,555,399,105,989,450,231,409,69,771,157,564,672,482,4,662,83,254,100,312,266,848,606,640,364,135,276,161,477,700,727,9,239,734,663,198,504,585,745,428,878,672,588,125,448,349,139,39,953,953,320,120,907,857,686,994,10,527,247,412,524,268,517,293,291,141,483,325,972,844,532,658,670,443,896,208,353,6,901,503,769,309,501,310,882,262,773,405,907,376,460,511,356,888,186,308,234,6,93,456,444,187,10,607,709,847,288,769,189,871,287,183,206,618,756,835,458,989,729,87,190,161,21,648,24,517,250,469,846,557,672,428,77,288,294,818,626,907,595,706,182,676,863,734,193,276,376,363,959,821,442,183,535,835,694,684,192,497,90,622,458,595,230,293,377,796,682,359,538,707,741,947,683,570,403,857,832,536,522,98,359,224,431,509,446,665,583,391,657,343,516,829,414,618,727,260,315,429,814,727,421,86,791,71,639,579,737,72,837,244,847,42,118,241,471,267,97,843,667,498,33,63,138,831,625,275,49,11,253,595,812,261,270,721,26,1,229,770,268,966,938,858,592,605,209,380,82,228,146,902,722,715,23,686,266,379,624,59,841,895,772,345,47,314,830,504,360,889,614,488,939,16,376,887,664,594,327,608,722,495,225,493,229,58,234,743,166,885,61,648,229,200,911,679,472,751,78,421,83,59,435,407,229,9,426,530,51,222,367,306,715,686,504,997,869,336,152,415,816", "443,278,353,222,352,87,976,948,957,474,945,483,400,624,720,324,601,910,588,4,925,335,674,368,91,167,40,67,600,592,876,645,443,533,73,699,964,713,921,765,32,959,866,4,828,927,859,574,730,633,461,80,320,865,664,645,0,389,702,97,475,182,555,966,340,865,99,86,926,35,777,555,161,257,28,43,681,25,204,407,577,467,146,514,568,390,177,4,636,26,780,462,759,33,295,625,361,83,653,508,76,220,603,451,277,358,292,857,580,134,886,291,236,354,361,932,290,403,920,85,919,591,32,778,886,204,484,677,123,15,6,986,741,529,421,975,9,187,918,40,362,377,173,47,735,883,418,93,293,501,496,73,657,924,144,870,545,219,462,201,26,319,296,617,331,33,897,838,457,177,686,933,504,114,179,342,640,608,362,182,763,231,768,465,654,392,531,685,534,234,114,333,200,953,489,921,641,381,570,452,852,308,752,187,321,647,721,677,93,878,991,235,664,927,396,998,359,120,443,112,34,379,29,127,14,207,241,775,982,796,548,148,56,453,810,361,631,265,803,936,187,880,168,371,89,89,116,215,625,32,828,195,597,208,638,600,383,865,487,936,915,584,136,720,978,309,775,87,347,169,947,658,120,642,534,179,362,401,266,550,426,616,126,724,905,951,416,990,43,260,466,385,406,464,963,747,630,687,460,351,28,675,690,755,328,90,994,87,526,926,138,291,477,280,796,947,87,432,801,403,831,802,221,313,133,806,492,522,543,644,627,117,391,870,938,546,99,11,540,68,164,359,919,357,816,329,303,151,744,260,118,100,929,643,639,428,726,403,989,181,129,287,727,617,287,549,331,757,742,929,978,895,52,79,627,665,408,621,290,568,761,372,785,999,536,702,871,560,13,994,995,784,751,356,22,192,643,554,454,115,553,96,594,166,104,28,692,365,398,943,116,103,962,970,553,446,952,635,615,183,324,911,806,831,647,185,867,457,399,810,17,925,532,117,730,409,405,359,548,483,975,43,337,685,884,920,645,439,144,684,776,768,612,871,896,790,37,6,941,874,45,681,335,224,527,780,451,952,945,620,158,654,749,643,425,937,827,44,227,333,277,648,429,940,716,345,347,157,296,109,230,641,371,358,800,569,909,92,843,154,991,731,653,928,491,244,247,974,884,790,407,294,750,488,989,524,240,442,778,849,865,374,102,205,177,847,278,329,685,454,623,290,150,798,468,342,493,407,198,479,549,809,928,537,672,795,265,194,880,51,146,136,915,897,88,388,657,313,350,137,242,513,557,153,768,254,228,793,756,341,83,427,172,137,159,308,280,503,570,30,32,812,253,341,24,556,480,987,31,279,26,245,27,70,580,965,261,968,53,836,172,376,808,187,910,804,544,304,209,421,462,736,792,68,613,698,591,420,515,203,948,105,290,787,741,489,27,637,94,416,308,343,68,788,743,449,713,457,180,824,404,50,697,511,459,899,58,868,43,696,895,31,869,602,696,355,322,142,539,460,273,526,927,832,443,274,494,953,915,310,297,703,145,680,476,196,672,399,989,425,824,258,317,71,458,914,327,24,714,330,154,659,543,274,404,20,210,286,435,694,395,237,233,936,516,150,786,235,225,647,684,296,913,452,365,805,467,276,328,659,826,846,746,910,407,473,550,958,253,225,521,511,262,41,853,246,510,524,219,167,179,337,106,347,232,846,371,134,371,708,600,75,160,952,748,335,116,716,93,440,546,630,973,105,197,701,365,855,705,140,939,847,483,395,621,450,123,242,107,139,639,658,609,414,150,222,359,741,192,628,426,693,789,271,102,193,529,241,717,108,985,352,550,98,366,601,119,977,286,211,694,765,346,819,346,442,36,62,234,100,261,782,694,677,220,690,858,753,156,287,984,562,590,279,775,775,750,31,130,783,66,248,891,858,379,780,663,868,891,842,299,619,788,904,395,757,447,764,682,154,572,287,292,573,672,757,573,266,822,490,961,63,794,15,829,794,240,733,391,86,980,469,711,169,388,302,291,575,658,70,334,304,936,987,643,547,924,504,862,326,528,985,687,138,708,365,455,912,461,30,616,643,719,585,222,770,498,360,247,529,736,751,85,234,259,605,858,410,591,829,700,611,586,484,657,359,474,523,404,58,691,984,655,895,689,988,583,280,358,667,112,303,734,520,966,546,395,32,648,75,565,817,24,482,813,821,319,762,307,253,651,254,856,87,684,137,503,663,806,860,992,293,593,435,603,655,705,541,242,659,976,702,474,245,62,741,734,255,216,95", "385,971,402,7,527,931,46,381,187,305,328,755,262,931,343,113,20,245,224,335,802,630,382,12,323,867,640,175,123,912,736,981,371,574,12,532,328,693,2,370,895,145,403,551,534,240,100,729,305,597,343,303,458,503,288,237,389,0,785,532,196,233,290,69,745,181,16,761,876,976,558,752,870,715,742,412,660,396,401,161,814,690,303,193,580,100,968,782,520,223,241,438,148,434,612,319,5,970,559,14,338,577,801,775,119,537,537,940,698,918,231,4,369,465,278,114,41,630,266,460,845,710,947,883,194,737,680,289,655,466,716,767,50,353,158,529,927,231,74,912,29,546,949,826,282,424,201,63,28,360,937,218,699,972,478,1000,307,956,988,982,251,114,969,563,977,939,435,850,323,102,762,987,653,104,14,310,711,565,201,144,570,386,319,237,197,544,755,652,992,187,478,541,39,464,976,774,805,421,374,385,29,244,420,734,297,451,422,453,327,941,864,641,673,726,928,910,411,97,571,229,482,349,565,222,366,126,166,515,403,795,319,307,39,261,680,175,420,318,186,991,586,835,800,152,346,276,314,40,11,495,183,886,536,5,232,4,731,706,868,432,881,587,141,262,258,336,788,378,975,375,756,277,940,320,768,459,812,837,269,760,55,654,683,812,510,443,841,381,891,575,451,689,563,218,588,39,477,60,728,664,489,501,532,560,321,206,523,773,541,787,970,271,770,530,225,1000,697,714,579,625,167,716,775,63,717,951,480,279,425,222,189,191,832,121,295,666,161,365,804,502,904,299,502,872,854,918,32,905,754,963,418,291,75,940,845,524,865,161,479,342,27,324,777,206,844,883,915,270,208,392,119,496,450,465,513,952,722,889,576,34,741,703,282,48,846,627,141,327,833,951,640,80,931,628,901,519,86,481,72,63,582,592,389,835,428,127,183,186,716,645,96,693,413,167,19,804,690,473,694,434,598,488,433,710,18,740,124,207,726,180,980,952,659,930,624,151,269,600,101,205,659,151,95,616,330,696,377,225,254,640,527,917,662,703,117,927,951,625,770,189,445,721,368,417,345,946,346,459,87,379,404,787,650,334,551,964,361,11,680,737,360,866,882,165,845,96,385,273,702,164,676,940,191,690,37,265,362,607,812,589,832,277,535,661,573,625,170,24,917,139,592,908,855,152,481,615,773,582,103,512,145,371,594,129,446,615,533,194,660,694,446,907,330,282,681,508,720,802,401,987,27,40,875,177,717,99,541,739,691,513,887,771,327,500,300,761,569,469,872,259,86,17,449,734,342,887,348,968,767,675,667,468,215,503,304,996,6,289,417,526,923,665,181,160,411,912,735,779,620,856,919,978,580,394,430,220,436,167,474,801,902,233,145,109,229,607,852,891,942,723,66,38,723,806,218,623,722,508,264,399,806,112,285,582,881,460,208,405,103,617,388,303,238,442,259,480,442,182,874,996,36,963,517,601,574,325,210,671,18,541,384,927,49,70,788,193,723,441,434,262,842,685,765,407,305,217,442,967,134,651,829,976,651,300,924,772,120,433,985,842,410,447,598,387,257,322,653,433,357,40,468,183,542,617,869,824,635,380,4,581,592,213,658,974,92,605,740,702,686,432,581,549,848,814,272,512,202,36,691,94,623,71,73,845,425,462,667,210,877,613,709,588,474,520,463,928,177,526,300,647,745,295,703,408,890,855,481,513,364,863,505,104,268,793,819,74,21,772,14,555,365,695,965,905,7,972,128,924,641,832,918,688,17,297,643,599,957,961,465,710,495,959,415,176,156,825,413,428,367,598,636,64,726,269,364,844,242,711,120,959,317,139,538,584,791,801,550,870,816,767,749,381,250,444,675,397,816,245,323,594,207,765,731,678,348,172,343,517,148,904,530,590,156,890,357,390,624,373,498,798,804,21,360,561,883,942,484,724,457,659,16,669,3,730,841,632,273,872,424,123,117,24,637,133,690,150,112,833,901,752,111,462,319,849,329,836,377,703,863,919,282,274,852,131,916,644,532,269,135,683,815,379,129,582,377,985,765,470,427,339,412,235,244,180,270,163,20,363,166,833,284,800,71,61,656,596,357,362,13,904,902,712,561,22,976,238,963,745,912,961,978,643,956,746,531,725,459,531,144,741,532,230,605,944,79,459,531,542,348,271,405,960,322,295,825,825,893,866,921,234,371,109,889,583,171,361,522,74,726,495,176,703,618,741,455,998,765,671,777,923,325,874,938,876,981,268,677,83,988,484,289,896,32,950,867,743,280,501,923,248", "157,813,539,383,836,779,264,285,738,521,797,879,637,714,818,509,450,274,640,558,585,434,836,513,727,901,368,677,658,48,232,296,767,517,633,274,948,486,719,611,875,736,359,788,94,577,427,932,31,41,664,135,926,804,651,340,702,785,0,143,458,78,679,687,713,746,498,680,280,15,985,569,53,289,244,846,563,150,528,69,31,618,387,557,799,67,926,332,918,585,473,673,690,673,873,632,310,31,326,811,128,758,878,279,608,676,90,920,35,667,980,345,523,166,903,746,456,369,438,949,202,442,676,163,157,722,949,623,425,479,669,902,277,866,356,214,996,704,649,933,669,605,814,492,403,37,985,213,796,699,547,279,897,451,613,305,914,744,681,30,451,633,358,173,1000,824,160,187,770,720,510,373,629,818,486,526,803,556,424,880,303,925,880,353,166,948,910,6,627,541,797,308,103,708,910,423,208,46,606,399,671,864,233,218,812,753,765,815,516,521,779,843,640,515,157,43,564,251,732,151,641,271,816,689,352,964,229,172,579,894,756,763,25,18,241,621,344,899,391,412,770,860,543,209,185,116,377,703,702,403,387,845,285,113,349,41,380,48,779,558,678,266,987,139,953,255,564,850,29,103,319,807,180,57,256,935,71,830,766,360,81,890,44,48,988,19,951,209,925,815,465,680,463,171,443,413,909,940,135,698,759,82,96,884,447,638,773,337,618,978,964,502,947,143,526,805,615,315,701,146,610,806,511,147,485,6,699,213,343,28,184,827,692,415,608,673,978,725,104,107,821,169,120,432,147,101,373,688,848,697,993,106,502,332,399,699,258,208,464,710,499,983,986,683,547,17,486,41,544,812,903,212,286,999,608,905,135,59,652,650,118,177,524,580,441,682,165,378,882,517,961,94,388,844,68,179,780,412,50,21,872,430,109,948,505,973,918,437,14,982,566,196,697,749,857,669,49,470,132,456,920,319,153,740,940,404,363,193,493,11,198,950,505,367,534,464,130,736,145,487,270,248,323,77,11,827,62,749,428,828,547,878,169,28,221,384,652,32,469,966,677,952,656,548,140,441,808,420,558,18,415,906,194,365,883,94,674,721,956,354,92,126,707,154,986,301,238,961,463,303,946,492,716,681,276,383,99,24,3,682,469,569,587,221,856,527,379,905,998,971,71,909,803,527,721,952,239,70,339,230,933,450,142,788,937,571,14,91,571,794,164,425,311,34,726,876,938,896,653,94,336,331,376,517,46,983,699,93,290,52,127,872,552,874,720,311,913,912,393,921,94,550,397,536,364,227,1,777,442,527,334,106,361,895,876,101,78,337,531,255,679,67,107,27,135,272,208,941,150,296,951,821,13,855,347,348,475,515,617,187,453,484,838,822,112,75,786,152,955,918,765,404,948,912,874,392,771,162,740,566,704,71,923,852,305,397,407,928,608,150,289,947,786,918,302,814,308,417,379,878,166,625,560,17,846,259,342,551,137,452,295,137,315,291,888,680,761,726,723,960,632,860,993,236,86,831,676,359,899,406,477,983,89,386,929,295,713,473,640,220,670,726,826,716,320,419,136,436,867,357,557,512,887,843,441,130,81,672,711,609,754,387,162,494,958,475,651,502,537,814,202,499,299,393,590,961,773,483,27,28,10,716,313,653,514,569,701,16,893,855,213,342,499,280,833,59,920,182,554,195,836,125,956,730,354,36,166,64,240,701,271,66,555,322,861,724,10,831,305,797,550,782,941,807,257,804,645,643,460,156,368,233,44,49,68,4,372,476,134,470,423,280,610,255,382,825,328,722,91,338,766,777,286,968,952,175,265,926,877,152,15,832,645,823,587,431,881,830,380,987,234,955,33,825,88,400,502,645,940,994,400,932,10,466,811,696,312,235,348,342,34,592,288,637,49,275,243,295,210,324,114,562,472,920,227,966,409,78,135,146,462,128,482,480,91,266,658,287,278,706,789,925,81,234,868,851,719,124,238,787,926,135,974,980,758,734,120,869,30,551,974,484,827,482,111,611,918,379,676,660,511,458,563,914,364,611,253,307,288,986,133,830,932,640,916,303,536,914,953,452,908,724,810,354,549,917,529,18,318,806,722,977,233,157,624,597,958,20,775,331,43,276,612,791,134,749,203,657,660,884,1,462,508,606,851,858,124,969,13,500,334,224,172,850,605,927,469,70,489,292,839,759,956,405,424,30,151,757,820,626,83,601,683,789,202,789,726,48,834,220,116,2,54,465,842,240,251,866,319,340,869,566,604,518,645,344,942,898,67,232", "770,730,565,658,911,556,139,492,930,745,300,204,281,44,8,431,955,827,155,419,207,265,308,915,210,265,168,690,25,14,567,286,882,993,805,333,617,424,23,451,793,685,786,167,452,446,343,68,626,405,102,927,37,944,186,118,97,532,143,0,474,892,778,882,708,395,346,463,227,841,694,961,10,49,672,399,236,928,71,180,473,892,306,831,264,29,999,763,361,632,201,213,153,805,974,866,539,707,391,398,151,192,917,7,480,743,833,550,700,76,330,951,566,957,872,530,749,306,570,98,706,85,929,659,440,155,281,849,927,539,547,255,419,187,494,54,144,326,924,665,858,450,500,945,652,65,639,161,24,853,336,434,858,166,199,835,978,404,247,17,708,443,595,916,410,122,444,446,408,586,901,837,837,345,101,284,373,148,382,192,489,690,979,340,702,940,449,585,550,879,770,639,867,840,264,376,6,235,726,376,32,470,633,269,996,550,587,183,730,856,18,149,361,11,718,303,840,219,20,933,653,790,541,869,197,544,58,305,79,289,223,576,572,944,536,478,594,922,233,344,512,724,78,639,170,540,884,84,778,79,743,144,453,898,690,241,409,738,836,389,549,893,216,675,498,452,438,919,594,886,711,391,831,884,18,407,585,236,688,215,299,652,25,739,890,939,66,742,720,541,513,735,782,370,170,511,54,683,771,313,861,67,1,81,293,507,515,683,133,148,497,599,688,950,561,194,587,297,526,847,506,452,104,132,972,934,438,501,628,694,744,366,299,12,306,770,507,679,860,349,525,895,677,47,158,61,91,261,674,175,629,166,459,459,580,621,990,31,665,645,920,240,297,166,610,219,784,882,184,6,993,640,18,294,126,442,286,169,597,458,935,440,156,34,650,205,982,338,947,679,348,251,642,100,658,725,286,775,645,46,677,473,186,569,98,590,143,912,198,15,382,543,125,994,166,95,206,887,823,373,321,455,571,759,265,161,507,476,448,655,145,956,634,92,636,303,461,723,689,43,836,28,443,921,286,664,68,429,398,218,907,171,22,292,367,48,706,293,861,618,679,503,309,443,788,639,720,866,62,748,583,505,851,376,266,621,542,590,629,389,957,101,666,724,61,666,437,685,833,44,738,728,83,930,28,550,622,657,135,26,335,570,985,702,69,854,395,709,202,841,260,606,442,290,536,589,310,494,617,837,986,914,282,679,391,80,125,699,935,406,408,574,313,848,227,949,587,986,597,409,626,789,174,124,390,808,373,177,158,979,631,530,264,253,567,880,804,911,544,649,288,59,454,228,641,738,592,964,861,445,806,951,880,819,526,150,539,448,245,669,111,490,925,52,65,797,608,396,247,37,839,525,579,409,739,962,766,409,355,200,462,947,678,954,833,605,531,537,227,440,706,108,395,555,881,556,747,28,263,536,652,867,231,120,658,333,517,336,906,272,318,904,127,651,256,108,453,951,745,980,486,246,138,770,701,614,14,686,593,503,410,994,304,984,535,648,84,50,703,528,639,155,400,378,864,862,836,654,891,997,112,21,541,360,701,239,749,170,74,327,171,672,374,711,640,776,875,832,918,418,903,209,503,930,274,569,300,422,684,244,165,505,901,102,998,72,547,504,309,67,157,964,822,184,879,513,596,769,728,38,739,162,782,575,777,159,73,226,408,527,717,731,112,32,137,199,129,522,978,505,159,496,366,795,442,369,750,57,382,271,197,777,223,749,672,133,411,151,682,843,675,514,163,676,872,988,236,751,244,703,998,765,736,613,561,100,817,81,34,35,469,819,953,62,865,888,833,73,245,31,381,428,173,599,698,633,202,658,244,551,779,98,425,368,16,861,818,688,914,898,937,908,473,571,59,205,401,940,866,620,518,510,65,828,691,941,802,66,985,475,792,833,49,993,892,630,369,234,987,896,546,733,236,374,873,473,388,439,963,967,835,420,728,898,81,304,148,924,607,848,700,314,965,228,351,837,974,672,351,509,248,932,497,659,22,690,504,437,491,956,145,110,995,50,265,720,391,158,662,131,520,431,691,307,170,859,402,420,614,621,845,237,148,943,207,656,748,329,189,61,29,841,369,265,358,645,948,138,498,555,588,311,936,253,293,352,928,111,343,887,250,814,440,194,285,770,268,213,498,327,348,22,916,820,110,330,821,361,723,16,743,338,776,319,132,482,779,879,891,184,798,256,256,184,109,562,986,385,781,216,828,895,374,174,91,570,830,490,15,951,154,121,508,769,97,795,583,799,502,649,530,360,652,332,788,288,468,55,571,469", "29,589,562,89,443,782,974,768,945,991,43,434,979,118,865,992,448,124,46,182,301,90,277,810,537,581,156,544,157,777,492,786,808,519,541,241,440,981,701,992,422,678,574,73,300,911,591,722,434,468,343,358,841,606,9,864,475,196,458,474,0,791,289,974,149,803,336,442,841,606,101,621,223,780,507,550,948,226,847,820,671,305,898,191,253,860,864,652,188,85,573,33,521,341,275,682,697,830,840,928,603,740,311,26,8,40,154,952,387,712,211,645,321,749,128,313,142,513,590,839,453,376,659,954,989,346,859,269,978,470,738,815,818,264,490,418,411,939,842,240,849,430,735,475,377,300,149,830,710,577,574,535,923,772,253,902,306,657,561,137,842,603,358,40,282,102,813,684,227,268,595,387,453,75,798,379,404,226,268,525,553,79,92,153,310,797,36,523,495,88,353,521,370,545,778,318,504,946,428,707,711,612,85,81,571,91,818,344,916,724,356,520,863,77,633,446,606,867,312,884,805,358,243,22,888,986,405,332,989,912,80,274,441,727,416,7,783,925,398,65,885,763,419,660,373,769,768,452,887,414,301,202,34,240,984,800,192,44,178,743,112,576,988,924,597,684,681,146,778,612,342,667,336,842,797,943,943,191,739,897,815,269,166,4,108,87,992,781,186,279,121,534,291,10,942,855,140,347,280,316,908,826,125,374,308,116,899,527,913,524,25,965,164,702,362,778,159,859,728,494,473,893,400,916,668,409,57,437,426,570,914,894,468,66,673,391,297,913,149,158,118,514,866,280,105,495,594,718,732,849,99,398,393,240,575,14,447,94,513,359,615,602,633,578,152,828,19,965,623,212,301,199,849,257,306,786,241,434,982,311,795,947,249,764,4,835,48,563,574,611,951,370,769,877,750,87,181,601,638,703,474,905,808,116,450,676,873,258,575,687,404,277,693,924,187,725,334,854,210,579,339,884,282,336,653,432,627,906,13,791,542,494,688,298,887,132,103,611,905,246,406,254,696,418,921,310,395,674,978,776,777,374,982,395,523,149,933,657,400,559,842,29,525,162,867,872,383,738,32,37,814,833,489,788,15,927,979,932,170,249,323,994,46,208,376,890,322,241,181,874,855,475,97,246,816,99,407,996,759,477,293,264,428,438,904,16,260,600,944,452,330,68,645,180,151,93,115,811,962,375,113,456,634,320,119,679,3,327,678,589,410,347,477,17,138,351,108,240,770,65,327,704,126,552,470,887,304,505,885,850,250,400,354,464,500,150,647,971,496,98,289,450,182,167,76,604,434,225,875,790,192,457,896,932,558,250,893,982,941,47,738,512,300,745,684,634,264,265,632,676,730,880,187,142,704,383,255,101,195,363,900,235,549,524,259,835,961,983,97,771,253,50,662,880,309,582,308,493,216,166,194,889,610,899,799,735,506,482,103,373,711,71,503,744,765,229,9,74,154,304,130,563,271,938,449,669,431,569,957,53,541,879,446,351,283,531,752,578,332,527,513,593,996,137,637,603,308,839,341,850,797,43,803,96,635,111,549,481,108,865,649,878,191,707,352,214,43,883,430,917,316,230,580,944,65,875,503,358,665,92,528,29,731,252,87,586,462,730,475,484,208,91,552,144,528,272,364,328,440,848,909,163,329,681,259,122,34,291,311,570,860,521,187,685,566,201,882,761,293,722,434,883,597,538,173,369,725,760,604,350,552,944,464,8,280,188,59,182,308,345,675,284,891,54,368,938,166,600,15,968,389,364,718,286,946,223,307,183,387,571,996,448,183,411,263,497,405,784,196,576,211,526,853,657,287,115,262,114,785,860,254,674,95,245,494,134,390,748,430,830,941,768,590,118,477,278,896,500,737,490,303,528,968,648,415,624,552,79,143,241,591,746,681,455,361,759,197,15,59,336,663,515,736,407,964,503,854,549,863,693,323,798,648,948,479,51,740,384,917,685,955,953,560,385,787,443,790,623,366,120,911,598,181,919,42,147,6,691,915,874,669,110,499,632,271,464,717,672,945,320,937,631,20,645,8,546,957,392,269,73,986,98,49,843,84,181,401,567,338,959,860,860,459,731,392,333,546,307,413,458,784,859,735,924,567,415,786,779,985,406,966,17,830,358,102,527,831,892,353,711,834,557,534,654,465,78,101,619,888,662,802,609,605,431,92,525,662,841,461,744,619,516,824,268,959,560,511,286,960,489,991,341,850,307,181,915,545,831,104,881,536,930,317,579,250,923,301,296,574,979,576,931,440,165,448,186,299,796,128,342", "97,978,424,188,87,393,339,785,404,195,899,514,87,891,416,697,809,507,208,611,445,699,187,455,641,739,661,857,550,968,30,838,573,46,909,510,43,809,861,42,661,902,682,421,576,730,541,984,987,844,365,213,201,503,900,315,182,233,78,892,791,0,234,465,805,969,292,980,982,742,792,352,781,175,682,857,549,758,270,740,76,280,471,374,415,259,524,635,97,241,677,866,824,905,667,952,341,224,66,229,902,333,837,99,49,565,893,817,58,819,769,1000,273,136,478,373,948,908,807,788,722,477,588,432,56,8,245,347,926,80,734,78,553,238,860,248,653,229,852,873,110,123,267,781,621,949,368,667,36,339,692,374,513,388,14,383,918,908,462,80,877,144,111,306,692,334,357,239,873,901,691,97,783,815,688,208,842,25,583,574,92,284,724,62,836,946,834,400,761,37,119,272,647,442,814,679,765,712,348,756,299,758,110,968,570,518,504,998,682,297,339,487,53,107,629,562,856,450,122,64,48,768,190,332,131,562,450,484,834,318,63,245,745,884,963,714,688,83,901,181,848,957,894,561,253,119,113,105,498,262,223,787,191,971,153,9,534,112,247,964,702,542,694,997,11,575,896,230,345,76,341,714,375,104,341,201,914,653,155,71,709,604,658,575,739,382,359,582,538,691,547,468,588,300,106,519,775,277,517,160,480,118,945,363,249,989,539,997,132,264,515,605,741,578,213,675,202,63,868,998,534,143,229,55,340,687,460,410,468,251,804,124,93,529,491,667,69,174,48,671,58,878,182,848,720,671,327,606,453,832,768,926,196,928,889,463,558,248,92,338,243,13,626,990,482,456,621,772,863,476,245,19,645,843,92,614,99,959,904,51,763,753,864,159,412,322,543,812,990,336,822,626,69,654,63,513,806,575,613,350,368,349,133,352,184,583,543,936,145,71,698,966,271,212,638,544,84,406,349,532,348,898,687,382,954,926,477,5,34,313,460,119,112,563,554,458,329,371,247,316,938,668,102,690,46,363,258,600,159,38,219,167,282,159,13,393,304,590,770,375,958,977,284,921,576,406,209,734,727,987,425,846,131,253,393,682,609,838,450,312,795,385,865,73,714,256,464,280,469,181,824,323,729,405,494,667,451,168,323,743,305,439,593,21,886,702,820,764,806,469,993,584,124,294,408,59,290,267,451,530,589,753,613,497,631,652,832,648,645,33,476,665,715,613,446,548,57,746,326,118,903,358,377,44,105,165,24,779,660,609,691,635,265,87,304,373,60,256,437,134,199,349,704,890,710,534,985,602,870,305,846,423,771,603,893,252,596,339,566,348,712,518,842,759,11,947,437,250,510,410,823,552,181,357,911,546,366,225,179,669,268,479,230,24,700,426,887,536,990,935,816,471,908,681,304,915,793,220,837,654,588,721,248,801,571,258,853,772,164,322,474,314,80,750,264,945,884,485,428,29,920,889,826,322,512,735,90,834,5,206,723,526,592,921,903,531,809,636,441,726,640,507,656,138,305,58,152,410,454,423,4,429,86,669,151,181,746,888,293,969,983,977,696,643,155,992,721,994,557,291,71,791,638,304,366,518,687,929,530,656,86,863,314,383,713,134,720,110,90,594,276,421,908,819,607,431,300,547,340,904,273,799,426,70,911,951,365,171,644,576,210,370,214,143,408,892,555,35,921,76,367,900,72,998,602,821,952,410,503,63,856,47,902,70,671,74,546,869,891,577,508,358,817,827,37,298,542,372,237,80,761,329,420,590,87,132,23,36,314,800,290,296,271,316,553,2,445,256,918,873,877,954,746,473,980,346,47,976,350,441,186,526,26,171,730,208,645,380,550,7,348,277,247,384,375,931,270,608,592,860,901,505,388,353,41,539,848,804,559,990,32,818,191,181,578,350,692,23,88,277,802,417,269,121,743,625,924,513,953,564,76,464,601,892,679,805,266,850,4,689,70,277,779,92,645,848,11,81,676,527,634,713,538,4,105,840,814,82,906,499,165,372,858,816,695,876,407,651,912,866,158,323,248,898,524,574,190,38,956,208,427,745,984,899,138,876,427,22,488,777,260,149,976,555,765,561,399,25,35,476,965,745,924,982,513,900,493,424,967,194,881,293,341,246,566,469,338,635,353,565,725,222,401,382,367,322,188,320,593,633,953,940,347,786,613,42,175,976,976,374,414,905,652,332,688,353,857,366,226,579,212,754,298,6,962,789,75,138,20,7,435,148,899,795,644,755,85,2,378,423,68,616,992,164,721,948,766,82,111,863", "229,214,973,122,176,576,715,292,533,227,845,32,554,255,795,80,805,726,705,5,390,838,821,175,54,891,579,607,202,274,241,389,42,217,534,709,730,67,760,846,77,215,838,90,642,121,42,385,994,833,762,286,449,596,286,648,555,290,679,778,289,234,0,712,545,46,26,566,549,393,476,824,79,281,471,847,614,977,742,537,463,94,242,423,60,657,177,566,584,830,849,879,659,451,334,493,529,234,837,970,913,312,195,637,18,156,11,913,15,907,844,825,672,180,969,879,609,894,246,662,317,630,920,798,343,492,957,707,194,475,680,990,450,338,374,768,96,649,610,597,612,898,859,502,420,39,144,290,302,797,837,442,90,54,514,250,932,951,500,882,13,497,994,568,194,252,687,298,174,552,78,419,117,431,227,306,399,139,538,694,598,816,877,166,953,738,334,381,613,428,794,415,381,401,743,645,904,468,427,141,16,995,878,439,707,944,721,880,906,771,682,864,136,648,674,27,817,901,892,501,797,267,34,964,589,289,842,359,60,980,671,881,330,882,916,688,807,613,83,444,24,325,969,230,853,747,350,758,724,664,287,900,474,91,235,879,557,499,601,891,494,387,977,513,122,78,725,800,52,266,621,87,527,37,375,635,333,268,656,727,262,708,642,611,600,136,600,408,658,962,627,992,660,158,987,90,493,234,737,866,61,193,847,916,813,145,697,458,924,968,331,872,174,330,485,403,856,130,397,245,894,808,629,270,660,884,365,718,304,176,996,657,156,611,586,862,813,484,226,629,508,870,450,454,117,138,468,691,264,155,895,593,464,747,414,481,389,880,833,46,305,496,858,834,561,127,158,95,636,183,776,553,858,548,635,957,653,123,352,824,545,252,58,460,996,697,329,250,906,632,606,844,337,277,399,488,726,456,81,316,139,377,99,549,864,838,69,104,830,409,376,681,991,582,347,422,380,928,307,268,231,980,490,886,453,300,454,273,403,634,697,504,221,668,576,644,43,556,275,696,46,848,366,357,416,504,122,282,580,714,893,108,776,799,734,807,998,319,18,748,544,812,557,409,141,984,209,434,234,955,788,916,137,739,596,642,597,147,55,266,198,253,295,427,134,369,196,867,470,179,705,173,874,199,692,380,575,307,44,925,286,134,997,111,80,759,819,218,857,805,196,644,442,55,877,386,329,770,377,986,39,385,320,162,695,87,102,343,483,905,280,24,646,516,460,744,244,399,78,781,202,818,216,148,421,229,29,926,22,633,801,942,970,510,890,182,103,490,559,46,719,442,773,767,804,194,297,81,760,490,953,522,614,843,68,416,286,150,687,719,361,746,23,967,86,150,25,709,304,522,559,946,821,526,548,640,763,206,833,542,467,278,231,544,536,746,258,750,122,840,622,471,18,481,657,925,297,111,263,501,688,129,980,990,824,564,339,12,232,828,649,86,9,317,890,566,944,543,84,517,322,73,329,50,504,942,594,227,14,658,284,51,738,391,717,893,870,217,616,583,759,581,46,302,71,149,271,992,446,726,327,471,417,291,432,102,726,937,646,602,847,873,564,75,414,289,759,930,913,91,136,220,946,641,751,345,256,349,564,887,761,653,42,422,260,819,583,790,756,884,464,687,505,442,562,776,634,399,491,147,561,844,219,905,294,345,283,383,533,929,456,62,950,225,86,821,435,895,426,599,563,712,926,22,640,812,266,589,529,69,552,857,580,894,132,859,495,418,189,324,356,269,901,842,499,565,818,77,575,563,38,87,602,66,36,96,581,204,28,582,538,120,322,884,760,933,211,549,144,61,802,470,867,873,755,715,419,9,509,351,731,44,134,448,754,829,402,255,137,284,638,816,399,256,314,62,609,621,608,491,35,450,137,23,413,354,519,304,25,213,175,952,774,972,115,846,356,637,295,236,546,109,240,545,205,636,501,122,688,601,979,861,27,530,927,560,701,737,760,379,806,211,673,991,932,870,528,710,369,856,953,999,61,742,695,158,552,856,163,936,382,505,955,974,99,872,480,551,832,951,496,736,909,592,912,256,594,122,884,298,425,312,34,819,785,960,205,127,600,54,566,142,70,567,690,165,51,69,984,988,331,338,101,658,270,327,596,375,747,220,434,758,613,269,940,552,828,967,929,84,342,475,171,418,457,768,705,131,728,835,397,670,777,606,692,770,153,576,603,349,857,419,799,486,132,704,309,193,174,369,881,567,647,475,82,151,218,64,610,386,111,92,521,615,530,961,748,826,171,625,692,331,638,118,382,20,923,53,273,439", "734,629,187,919,376,675,810,660,218,791,307,906,476,22,542,283,954,978,846,695,678,363,18,3,493,25,260,617,615,799,888,175,862,328,304,631,703,431,289,387,655,835,848,402,695,10,786,833,786,882,658,258,112,459,411,709,966,69,687,882,974,465,712,0,739,89,31,583,342,766,330,753,614,371,646,418,50,260,811,127,182,446,71,913,538,225,789,357,728,51,758,732,22,89,820,376,600,610,91,6,163,365,546,569,448,195,574,259,557,91,44,2,916,523,369,321,783,24,670,699,985,414,959,751,196,538,556,593,310,321,361,985,620,479,283,681,436,8,585,383,948,417,492,906,218,533,332,878,185,603,400,543,798,232,325,45,391,833,27,314,471,276,403,659,87,496,644,697,154,878,141,711,822,924,27,944,106,620,809,530,92,899,632,955,22,856,599,254,38,98,787,58,132,737,374,310,612,550,802,240,121,314,682,618,473,911,395,733,139,599,424,986,358,308,593,969,167,560,82,322,386,513,9,696,923,549,992,827,670,756,439,203,312,566,170,848,911,387,238,484,707,553,554,457,860,981,452,597,299,262,587,796,114,553,808,530,171,204,914,333,462,440,569,742,825,170,860,593,318,784,386,918,649,145,327,279,97,478,528,510,819,78,563,151,724,143,549,67,646,323,700,87,139,460,716,123,926,801,638,652,955,129,143,542,327,336,196,464,432,952,556,129,199,137,555,499,612,612,846,316,665,64,825,118,448,106,945,864,32,753,155,5,810,449,761,374,925,712,578,314,339,612,296,878,861,213,260,419,369,75,304,460,952,273,519,290,311,429,733,202,875,867,918,236,483,345,38,572,272,864,425,486,186,938,295,579,574,866,356,169,897,809,167,289,383,68,236,96,552,701,710,97,461,8,402,866,880,642,920,707,889,208,260,749,563,590,361,142,601,256,811,567,679,58,404,981,23,659,28,815,386,855,131,261,787,197,254,827,572,666,575,365,305,361,280,440,659,732,615,66,511,494,120,248,678,504,476,956,910,924,742,90,49,890,434,537,327,90,579,886,228,377,606,18,136,798,138,747,857,925,683,465,529,739,32,334,487,241,904,6,744,700,851,5,874,865,515,45,186,154,326,206,214,668,354,732,468,563,862,512,182,272,787,90,726,891,637,875,959,388,691,318,541,191,888,23,602,624,929,866,300,426,638,415,379,826,226,671,794,980,624,459,900,495,42,844,359,543,109,137,100,429,480,928,545,858,369,707,526,809,700,968,149,853,778,425,345,938,581,889,330,484,377,86,671,970,728,726,548,558,97,798,34,834,934,787,890,557,680,12,773,489,878,384,614,623,333,152,675,746,776,3,417,751,803,531,684,45,196,537,295,641,425,570,677,194,658,449,351,241,660,893,631,91,92,330,296,488,754,713,989,144,247,34,673,277,386,415,310,787,930,592,450,652,486,664,970,701,317,230,704,397,162,496,579,460,133,348,826,980,112,993,69,387,328,28,972,67,469,970,242,29,62,959,269,378,606,967,443,329,607,357,947,486,201,653,305,445,461,887,630,462,944,118,211,337,587,333,736,913,505,340,781,163,658,547,146,702,243,688,19,196,587,719,241,77,66,582,30,669,853,382,962,255,348,351,890,310,201,897,346,169,595,596,281,80,67,65,441,319,450,282,695,422,620,610,181,602,927,947,450,388,949,223,357,605,182,250,440,102,790,472,123,516,174,159,317,366,596,81,855,11,861,61,14,512,340,986,842,676,900,112,22,847,574,645,329,593,503,899,149,130,173,109,312,262,863,88,593,915,857,778,647,987,130,85,138,422,755,199,934,894,149,686,63,250,635,670,135,479,846,724,732,75,11,743,254,350,498,240,543,712,245,652,565,862,48,185,643,561,667,100,812,961,753,984,945,667,910,147,410,165,116,245,297,236,937,615,421,183,983,380,957,179,711,50,228,609,190,828,336,990,259,913,289,214,303,943,445,868,261,29,265,705,568,865,330,679,904,686,575,618,868,473,643,110,815,970,558,877,332,882,191,11,615,66,664,446,15,585,252,172,665,728,64,719,576,663,364,399,328,495,437,898,495,318,672,895,152,669,707,632,976,311,101,882,825,117,906,271,365,65,190,399,367,235,434,402,881,901,879,638,517,500,747,410,783,4,953,372,367,821,245,79,568,642,59,522,235,140,201,279,797,169,879,643,716,874,329,86,124,748,378,134,486,345,399,102,715,491,863,925,985,83,64,279,762,551,181,998,724,337,782,546,13,190,272,163,607,446", "829,781,553,600,531,456,819,971,244,853,420,660,847,446,26,626,160,615,944,103,550,740,426,589,515,734,273,767,371,314,678,673,473,427,818,550,481,167,366,568,499,136,727,435,641,666,982,142,590,61,710,314,87,776,567,634,340,745,713,708,149,805,545,739,0,808,797,627,19,445,180,328,617,876,310,901,870,922,11,738,770,914,728,195,986,869,457,253,698,536,710,600,594,966,967,381,729,5,209,745,93,86,155,492,143,117,864,902,479,842,215,399,249,326,697,410,58,578,467,450,275,955,520,18,365,803,861,240,133,74,51,872,617,317,385,231,996,279,751,857,635,994,255,386,83,124,545,585,979,27,122,245,84,376,727,389,169,939,26,9,113,917,1,27,132,472,939,246,334,184,928,343,179,406,330,844,574,798,373,9,777,505,355,907,641,714,13,397,742,600,190,941,820,336,19,319,607,576,349,254,923,947,590,175,551,106,509,440,69,131,297,569,198,601,680,191,209,371,41,847,104,945,329,971,872,467,374,37,760,197,114,343,404,101,814,223,505,7,419,792,954,971,779,759,331,24,579,251,713,321,972,583,690,706,373,937,1000,678,413,242,4,941,625,204,884,372,985,696,4,15,983,551,984,632,352,745,122,667,957,13,769,35,539,288,396,707,7,775,365,410,2,351,127,998,415,108,954,693,523,877,640,63,383,354,71,772,772,607,120,398,765,82,590,170,650,441,238,995,993,717,610,564,350,246,850,815,181,230,554,392,685,450,180,129,92,86,914,91,298,352,462,111,182,116,802,59,139,68,62,504,603,8,931,549,663,886,730,789,818,938,556,301,83,208,692,896,331,46,553,722,687,756,990,504,723,6,906,879,877,32,772,154,39,321,111,227,67,366,462,212,29,986,741,976,209,115,992,136,478,637,757,930,57,505,784,213,735,707,910,915,163,896,710,7,651,870,637,151,967,712,248,791,47,364,453,359,865,303,979,450,901,884,759,10,863,260,235,119,454,134,681,771,520,369,580,770,163,516,58,44,194,842,923,987,425,306,210,114,387,345,283,632,406,769,676,143,457,75,890,192,73,548,574,815,612,365,717,779,191,984,747,313,709,55,917,409,852,858,210,78,904,757,943,278,488,386,930,926,472,3,528,157,245,766,754,326,747,907,35,624,841,188,345,251,911,901,799,618,955,437,382,233,9,679,129,519,859,348,350,625,415,175,6,6,330,468,163,618,555,327,971,498,494,948,320,239,745,278,103,509,945,773,828,313,309,984,845,128,764,506,625,255,865,797,323,196,995,390,36,308,24,258,690,542,759,461,719,170,347,253,590,79,349,783,249,693,589,222,802,679,23,90,704,361,450,118,194,391,27,517,375,461,527,562,50,783,792,286,23,406,183,386,980,908,379,558,415,764,950,580,692,330,325,83,461,66,655,509,129,818,571,439,598,269,344,848,275,456,332,402,228,853,769,354,73,381,915,774,133,360,783,670,101,411,794,951,149,280,113,555,507,515,193,39,447,488,787,980,589,643,703,383,106,803,969,401,982,773,848,768,865,683,939,793,155,743,673,970,168,533,106,70,743,641,348,665,389,585,70,583,469,104,129,117,991,843,834,310,235,66,597,300,82,809,322,662,233,857,441,466,70,625,20,177,418,380,919,856,65,269,554,495,808,584,724,631,952,407,870,773,388,706,809,374,846,502,769,356,802,720,579,52,910,918,58,468,575,85,806,868,199,848,879,767,76,451,681,476,176,146,606,942,441,233,548,536,68,352,445,908,234,244,906,948,624,284,399,218,442,441,104,572,526,138,397,344,501,604,168,166,579,213,808,139,227,238,813,755,297,363,18,37,142,207,554,930,262,601,812,654,621,637,699,825,972,137,811,576,962,40,428,569,725,481,596,476,394,555,887,188,623,433,851,323,310,467,467,417,946,445,294,612,8,704,537,554,727,985,263,158,362,114,181,564,339,190,753,103,794,11,11,993,507,31,253,764,235,199,965,638,483,96,637,933,382,896,92,764,127,295,843,82,649,384,302,687,694,783,382,744,571,527,954,113,409,209,219,920,375,973,306,344,303,297,217,243,193,259,988,916,404,851,547,205,408,326,819,490,590,363,263,831,973,982,474,176,484,98,886,380,921,120,591,221,573,240,522,569,822,280,952,383,710,813,111,860,450,828,687,157,920,923,280,146,931,891,737,538,915,718,571,277,632,377,845,609,77,6,773,213,17,522,473,770,803,376,396,559,826,487,239,482,130,258,219,554,335,355,584,5", "324,358,859,45,656,939,945,74,681,739,634,831,195,569,225,159,645,539,668,414,584,377,800,602,412,46,700,644,574,56,871,803,453,435,730,340,131,780,519,305,786,218,170,989,548,706,982,311,488,303,988,313,780,297,180,385,865,181,746,395,803,969,46,89,808,0,405,196,872,53,810,342,341,40,31,677,390,974,42,361,27,624,334,893,32,603,38,414,588,33,126,437,142,337,40,161,737,188,374,215,817,33,532,37,221,738,37,77,498,519,129,809,396,904,92,642,819,199,920,900,47,848,2,564,416,123,103,955,907,745,929,297,902,920,694,47,703,285,905,226,977,449,73,28,173,403,620,459,175,227,52,173,37,67,190,54,751,944,813,23,128,458,988,340,853,317,456,55,538,541,309,465,466,107,16,847,675,551,109,906,119,971,551,615,943,450,617,175,900,639,549,386,39,350,197,552,322,14,383,904,173,889,443,312,163,53,129,636,289,395,362,485,934,96,135,393,50,827,660,460,414,88,253,796,501,437,67,662,968,482,479,285,954,587,479,312,983,667,366,38,291,333,818,158,201,658,546,915,427,737,744,612,694,482,303,540,84,740,442,330,812,979,976,12,574,887,934,135,526,349,149,957,399,891,429,496,178,488,619,91,965,669,294,561,267,13,414,419,551,784,315,767,34,591,284,263,489,228,619,684,729,697,97,324,696,715,386,271,251,17,29,186,249,642,241,320,836,624,809,629,538,552,731,675,693,76,831,734,680,821,468,916,307,743,142,465,551,784,80,302,546,665,408,804,738,134,350,429,600,988,527,827,279,197,543,7,223,548,828,714,251,567,578,413,272,600,901,333,993,429,995,750,936,341,261,546,66,726,995,682,755,225,422,306,106,600,603,199,808,329,961,187,403,725,300,329,635,825,676,133,545,938,295,438,652,458,891,900,38,702,895,748,758,719,769,248,32,216,498,972,701,783,610,753,757,734,426,707,475,568,119,869,525,455,652,695,228,381,409,878,218,895,427,363,825,791,655,454,874,790,791,84,711,391,242,294,921,650,549,908,774,846,56,69,633,334,787,22,610,814,682,504,312,581,16,988,318,331,571,909,124,650,880,201,554,297,439,285,978,550,723,636,692,188,617,949,742,594,49,826,354,616,365,662,862,488,241,895,857,436,268,813,55,751,89,415,446,579,626,871,787,862,625,162,54,324,141,211,420,728,104,695,182,865,9,871,645,439,561,321,752,452,103,269,836,1000,644,307,625,403,747,434,725,6,608,744,568,895,505,856,917,300,166,280,978,393,153,556,769,254,125,842,62,333,171,455,282,422,750,274,218,130,170,900,989,917,154,308,104,279,816,606,597,430,41,598,642,483,190,827,224,273,897,862,769,772,198,55,989,974,129,747,491,822,822,80,833,604,152,127,870,33,783,237,822,678,523,444,653,53,317,630,756,955,378,1,492,655,22,30,247,649,906,257,516,128,723,574,480,546,406,429,529,896,894,221,151,494,998,482,655,86,366,536,644,222,904,767,186,436,80,756,129,436,536,405,94,479,513,753,302,486,396,453,649,444,324,613,395,663,293,775,679,340,693,69,476,638,382,274,947,948,221,998,214,148,451,64,186,620,441,29,778,246,94,894,41,417,519,845,734,302,703,375,906,390,871,733,313,967,606,832,656,71,752,692,873,596,468,529,708,893,365,170,171,705,520,187,920,715,395,569,763,148,621,321,323,49,783,797,442,541,403,590,589,589,171,595,971,999,964,708,198,282,296,280,158,428,210,393,996,127,336,805,723,842,656,380,597,164,372,308,770,901,50,221,117,728,466,150,294,533,515,823,719,755,306,788,249,888,83,369,662,79,710,102,823,577,921,91,298,352,234,919,297,263,789,626,855,964,941,649,774,353,817,92,847,794,527,591,115,420,860,536,651,979,328,567,973,525,725,226,396,452,818,606,120,808,206,259,985,362,990,851,102,666,523,691,486,530,251,607,142,122,31,38,250,101,272,449,929,871,993,786,646,50,996,199,836,357,210,430,390,825,149,752,507,877,442,162,967,111,241,324,922,453,150,56,821,740,224,699,998,954,342,904,771,426,588,77,434,233,801,290,396,194,422,459,411,425,939,850,290,20,733,429,830,363,958,156,259,819,44,25,923,232,545,829,212,58,893,528,129,289,758,289,478,2,408,299,170,123,838,233,47,508,603,552,244,2,249,287,213,157,526,828,555,178,653,347,344,106,57,16,670,204,235,654,296,48,912,710,911,552,522,873,872,22,903,597", "917,941,381,473,959,788,897,410,924,158,460,705,19,488,147,963,63,989,919,217,783,333,223,871,568,598,600,882,461,563,753,246,891,133,355,107,94,782,158,771,700,592,867,509,157,829,776,526,994,311,143,386,969,349,129,641,99,16,498,346,336,292,26,31,797,405,0,901,681,982,797,778,461,609,445,24,668,1000,786,31,410,833,203,120,723,521,677,28,567,924,439,754,263,437,888,956,152,439,258,274,845,682,987,559,160,779,729,819,155,609,967,641,706,669,285,115,458,522,55,249,966,667,122,267,518,546,563,401,291,993,535,876,294,254,691,616,284,114,706,585,921,743,739,139,732,215,276,420,388,226,346,586,186,560,598,54,648,802,956,273,165,350,929,391,109,121,570,560,745,388,323,461,635,561,989,519,69,349,22,348,725,181,447,115,579,854,818,700,972,305,445,253,163,243,904,595,850,814,174,379,627,401,552,42,171,766,664,132,853,426,633,258,933,225,101,686,715,984,257,343,987,755,704,732,392,271,513,777,275,501,852,93,32,652,873,314,247,212,690,439,786,89,297,502,375,534,722,826,224,764,302,198,660,726,805,186,589,801,158,89,564,432,437,624,589,181,916,11,601,415,692,290,893,347,810,607,917,529,344,531,879,443,606,676,252,993,244,994,971,843,22,946,801,157,658,899,731,416,340,802,742,278,606,241,428,846,110,584,269,921,470,125,203,849,406,957,663,995,980,112,342,783,828,448,605,956,439,564,439,976,32,198,109,310,648,985,627,995,572,574,560,385,166,239,671,481,431,193,95,684,546,507,116,370,301,831,780,847,747,651,410,904,184,193,861,661,921,761,828,821,676,61,980,917,729,324,42,952,516,321,8,600,941,245,376,663,186,320,318,886,723,291,986,480,126,492,77,198,787,820,672,95,353,967,792,456,924,364,951,619,973,205,434,194,131,228,114,965,57,33,876,259,965,674,806,876,461,191,880,405,20,747,453,13,415,946,919,496,946,357,982,507,392,697,558,913,442,254,109,973,7,495,657,675,846,578,447,726,954,711,652,815,444,187,890,744,165,660,112,910,713,96,832,409,417,312,222,832,227,57,364,751,43,194,680,120,712,703,655,597,930,259,755,478,829,373,294,548,490,765,376,122,167,328,363,863,351,502,801,627,100,779,498,939,590,486,185,407,260,315,723,871,108,593,290,373,253,826,791,355,409,143,957,806,381,866,246,563,49,847,606,201,957,502,976,128,463,223,797,203,785,446,444,627,731,379,892,119,727,423,877,426,968,767,854,365,125,138,593,635,436,503,318,618,38,421,988,852,294,864,311,624,724,281,310,262,9,908,193,633,630,467,20,523,100,520,896,149,120,576,791,392,81,640,90,722,9,400,875,561,508,98,968,106,76,980,979,720,788,634,77,314,107,231,601,479,872,478,316,54,893,984,219,143,196,323,641,382,992,134,47,940,604,800,488,498,98,431,787,335,339,233,898,251,953,321,78,696,617,770,393,8,3,42,160,982,142,264,257,263,908,894,299,963,778,244,565,523,693,652,395,740,788,3,986,597,565,422,418,887,569,842,421,587,324,4,781,922,523,411,73,380,968,232,869,675,108,239,456,650,678,694,151,388,431,286,880,264,646,701,867,214,220,602,746,782,325,484,756,426,927,14,456,958,152,967,890,248,564,814,706,312,516,775,269,309,798,777,528,555,976,419,29,397,591,556,415,810,514,847,915,295,364,45,481,484,173,208,761,621,675,246,217,629,332,666,526,951,348,152,505,166,310,167,11,603,426,694,379,918,623,485,111,654,361,725,88,756,272,491,699,365,538,515,73,937,588,685,331,926,418,57,760,825,471,308,868,317,481,75,327,73,633,496,299,175,195,537,305,341,820,209,424,743,25,755,889,789,472,340,105,943,855,252,478,191,431,732,600,416,233,801,16,322,381,776,873,528,88,76,758,419,350,105,767,538,432,21,819,713,226,975,894,239,301,491,900,316,516,793,387,642,942,193,59,140,364,940,510,453,269,90,848,772,660,230,992,336,878,784,481,603,54,878,77,198,779,978,229,98,755,214,89,199,716,45,145,961,80,75,779,917,661,657,531,531,742,593,347,365,660,79,182,574,727,777,530,248,374,663,369,496,405,43,176,193,900,679,857,742,659,859,196,237,229,529,317,22,193,40,864,854,391,735,282,519,766,761,17,147,61,754,801,871,314,294,143,123,82,563,686,781,224,901,570,316,910,753,139,65,389,624,517,1,597,717,207,795,919,578", "380,962,51,37,381,887,607,654,640,898,995,293,3,980,801,640,139,338,230,81,111,222,405,700,605,521,204,454,425,488,546,587,955,32,644,628,972,171,114,189,126,401,525,423,42,350,774,407,505,633,26,345,761,623,469,168,86,761,680,463,442,980,566,583,627,196,901,0,99,973,768,99,49,130,285,432,649,634,199,608,892,124,598,771,776,991,346,21,817,628,631,866,240,494,698,524,84,656,669,941,532,383,606,291,487,676,276,622,680,360,192,60,296,860,907,891,980,683,410,870,635,749,279,427,186,250,216,397,365,393,108,219,223,446,794,78,197,723,490,374,139,234,850,634,662,85,882,951,22,596,268,18,999,466,681,165,172,212,507,740,123,109,302,141,28,201,973,885,993,241,813,322,290,181,111,738,68,426,727,147,411,881,9,551,109,370,873,168,576,551,91,423,241,605,399,321,110,14,691,849,588,917,350,115,605,282,137,950,314,872,955,958,463,467,306,686,25,824,150,24,875,858,251,128,789,637,171,521,763,165,52,556,847,362,586,730,447,690,595,195,264,896,802,257,955,378,152,551,448,594,422,753,177,500,916,379,49,780,904,397,52,836,432,857,960,793,362,881,975,144,27,736,848,248,819,554,537,36,258,15,33,876,745,301,29,207,824,803,717,782,285,579,830,71,512,815,667,637,415,805,90,852,569,440,114,466,878,897,912,932,636,416,568,702,174,640,533,189,317,702,883,126,45,927,977,525,240,499,145,44,99,746,266,662,669,372,790,939,701,497,209,697,569,86,350,794,614,848,166,206,866,403,805,638,753,983,800,513,288,229,346,548,854,771,434,87,948,641,870,564,356,600,307,329,175,214,652,548,900,231,428,657,537,165,809,7,599,872,453,760,354,785,483,245,591,489,242,209,48,582,476,718,462,626,947,942,785,921,147,932,621,596,641,171,302,879,308,803,94,504,147,461,347,279,450,491,321,160,116,181,798,13,796,325,356,732,458,106,71,479,995,267,961,177,205,599,546,228,461,448,611,970,204,628,522,468,957,437,741,476,760,720,995,78,725,939,228,23,82,379,685,637,264,57,726,585,860,848,544,594,812,901,187,600,855,884,153,334,288,483,745,29,949,103,550,637,552,828,181,438,115,259,88,539,425,868,77,636,415,91,714,58,822,440,889,600,917,634,843,668,122,759,449,271,531,84,965,701,816,572,917,93,154,695,580,49,236,216,411,69,296,494,884,983,45,422,586,418,205,718,546,591,90,70,445,275,354,520,804,962,567,378,398,681,889,83,50,201,948,884,477,847,886,607,740,869,441,954,738,801,417,604,202,758,215,959,261,176,700,625,670,920,636,440,549,131,939,277,834,526,238,568,629,701,274,373,818,119,326,51,360,745,135,143,368,393,849,63,288,986,40,717,367,258,14,711,870,954,309,712,216,677,653,53,53,819,460,905,222,766,255,531,343,350,223,708,499,692,851,415,810,878,753,852,158,628,284,897,88,224,400,148,948,914,27,853,627,543,706,492,299,241,794,165,216,445,674,600,354,120,251,396,742,137,397,909,545,760,483,196,823,492,980,700,691,139,497,958,239,740,141,2,208,217,721,745,830,123,181,36,186,922,48,232,704,206,744,807,327,157,440,603,999,156,6,440,409,888,70,485,548,184,933,545,597,205,247,656,583,650,519,343,847,893,410,591,968,710,98,287,446,604,392,834,768,328,72,567,480,977,642,510,390,826,226,399,126,565,7,618,369,677,337,156,69,986,65,664,848,540,530,413,955,705,845,232,659,202,827,474,504,777,156,232,247,740,596,333,553,759,635,263,165,655,136,980,740,253,290,216,882,566,600,21,953,933,613,108,847,615,130,250,428,201,616,418,736,706,171,43,973,912,869,149,576,673,319,394,31,762,917,918,760,405,42,929,290,387,354,736,598,316,283,448,677,837,561,822,916,933,101,355,963,509,549,872,591,854,501,421,242,783,32,981,426,415,662,385,455,499,291,104,168,128,165,344,544,305,547,705,647,387,692,699,871,70,960,642,929,713,942,827,859,631,942,484,970,904,325,148,456,851,139,420,10,439,756,308,885,960,679,171,817,534,774,156,761,131,524,787,239,630,609,301,293,872,661,36,522,206,852,443,715,33,831,176,706,646,761,890,981,808,541,771,93,878,158,11,423,86,983,861,566,501,687,829,730,810,864,876,981,809,261,441,827,66,397,813,211,624,745,921,762,168,605,64,878,523,946,351,922,154,527,818,35,245,232,514,272,554", "817,144,696,105,929,922,144,894,849,390,662,929,745,299,708,734,986,870,828,545,805,86,95,319,121,348,844,293,659,650,449,725,227,973,826,666,304,630,203,985,53,512,171,285,105,574,430,612,801,845,323,142,667,522,148,699,926,876,280,227,841,982,549,342,19,872,681,99,0,748,373,915,594,615,822,710,140,285,686,590,99,311,556,166,61,351,269,859,142,860,475,325,86,393,89,160,515,331,154,529,216,379,314,6,458,323,227,961,113,624,392,583,254,411,107,182,991,492,793,382,239,354,602,803,676,250,62,252,832,979,322,16,276,681,575,624,191,399,823,47,126,63,886,575,347,855,181,534,44,845,679,64,540,917,551,815,207,765,238,88,852,849,793,161,827,437,427,17,8,11,488,851,841,172,628,747,645,461,346,664,734,849,567,117,71,591,278,193,20,811,760,408,875,396,401,303,664,843,868,296,992,648,104,948,829,37,15,544,44,854,58,147,945,50,990,969,734,258,776,616,881,240,355,196,661,554,267,621,570,924,843,478,413,971,743,688,317,699,676,236,301,171,614,845,679,790,473,458,677,628,755,38,657,309,647,855,973,826,221,299,458,745,910,171,258,640,854,424,170,739,426,31,129,377,399,138,205,196,64,957,172,375,689,343,234,631,196,658,402,883,919,497,872,701,499,835,694,469,775,326,194,995,866,840,369,95,189,709,848,449,462,320,316,314,881,675,226,92,390,585,189,897,747,697,928,553,834,822,28,144,762,325,40,244,773,335,919,27,243,897,856,367,732,820,565,513,875,206,837,322,264,400,498,500,558,218,221,440,963,472,218,888,377,999,615,93,438,726,382,7,103,998,411,503,99,857,41,594,531,835,900,694,44,139,585,217,750,179,799,934,886,980,255,299,722,716,848,694,167,542,440,439,291,444,835,364,447,719,305,833,59,620,432,126,445,979,138,879,45,585,737,331,172,97,818,898,798,198,248,390,83,263,343,118,106,990,379,906,795,462,226,219,282,831,197,640,318,278,248,68,529,32,106,698,302,23,757,828,69,720,299,571,658,835,680,407,351,763,650,177,282,413,516,159,487,175,800,909,16,975,347,239,744,763,729,189,880,935,750,785,420,986,838,572,511,410,658,84,954,627,541,435,957,384,633,74,250,258,442,901,726,891,325,155,300,187,456,893,926,778,559,181,646,446,309,792,304,457,26,767,150,460,543,224,300,371,921,377,677,149,550,955,653,812,394,961,523,478,802,323,571,579,909,526,888,998,219,901,238,725,264,759,577,509,94,281,17,525,911,686,386,557,730,788,879,325,701,970,379,740,401,507,974,366,843,68,113,733,954,633,191,10,713,343,447,655,715,38,525,145,955,43,783,844,928,201,794,832,803,706,561,885,782,900,743,249,596,74,408,561,874,482,609,791,27,618,378,715,889,415,276,841,1000,220,146,513,83,131,991,101,20,808,276,270,335,800,720,715,291,523,833,972,267,937,743,767,629,77,737,380,767,762,84,813,549,538,815,238,219,118,965,122,866,672,34,564,275,922,829,54,976,89,949,55,276,197,79,717,77,206,494,221,16,729,299,497,418,567,432,722,154,851,572,703,498,865,308,729,966,790,336,653,46,970,744,509,602,569,350,201,786,749,356,249,551,918,474,306,126,720,142,245,160,283,390,126,630,9,321,268,981,167,928,219,634,547,485,537,390,796,338,538,800,834,830,984,223,978,512,822,71,729,902,603,928,391,975,205,504,402,427,471,105,955,653,686,778,352,58,448,591,923,453,237,254,454,348,995,806,647,873,788,96,779,583,982,926,41,138,168,252,496,293,550,847,571,94,2,523,284,207,392,545,961,353,889,599,557,533,521,521,178,247,786,561,50,171,140,136,655,219,40,179,228,623,893,651,325,308,146,502,253,53,970,87,821,304,16,879,891,764,494,996,217,767,931,48,72,595,823,302,743,791,89,357,550,745,632,162,587,931,137,697,909,712,301,204,61,797,520,386,470,395,845,388,862,612,800,593,963,831,70,807,100,822,310,164,367,772,946,106,464,145,209,686,779,86,795,375,649,723,367,752,499,400,38,877,935,822,7,358,905,386,296,795,746,103,664,102,92,635,86,25,261,413,730,788,894,195,788,201,717,566,629,337,424,554,701,959,780,143,147,485,918,125,382,313,45,793,69,725,31,156,992,878,873,869,309,781,925,928,52,603,459,824,709,975,876,441,275,400,390,980,118,122,473,129,214,268,496,179,481,171,467,601,586,131,661,67,817", "597,609,343,517,609,858,862,494,880,180,779,793,892,928,703,917,676,1,211,573,122,171,286,567,540,95,449,696,412,887,666,687,958,925,153,492,414,686,857,806,775,660,636,285,384,223,83,932,246,962,707,532,22,408,152,3,35,976,15,841,606,742,393,766,445,53,982,973,748,0,625,620,237,89,87,711,953,431,764,479,692,108,145,651,190,146,838,706,813,169,118,565,684,374,720,519,68,546,941,459,408,419,979,660,413,225,390,777,563,281,770,140,716,977,68,721,712,100,627,219,810,794,526,213,423,669,994,947,977,485,883,825,487,612,593,900,267,142,461,712,176,825,123,684,392,250,245,321,769,251,204,226,48,510,978,754,890,282,992,726,699,344,344,603,785,659,409,697,441,513,308,343,659,339,349,780,947,357,786,318,222,89,606,327,208,388,747,153,490,288,762,497,844,760,53,218,32,759,516,870,816,571,915,712,820,361,2,182,425,252,598,750,172,856,478,590,120,954,283,182,663,956,749,284,824,850,180,73,962,152,783,449,532,977,741,678,842,45,621,548,245,595,516,963,362,742,726,704,441,112,236,964,301,678,640,240,428,808,645,516,48,410,896,401,590,723,14,829,358,656,902,75,899,240,650,894,757,565,196,172,217,477,138,528,863,195,913,91,466,792,174,426,711,788,71,119,830,221,258,47,252,812,119,904,484,331,169,650,260,45,91,391,308,832,223,96,530,187,104,74,95,940,859,382,802,818,50,65,101,240,227,67,751,20,625,966,91,973,241,2,20,317,348,178,34,493,810,608,668,359,739,857,965,886,335,912,247,702,359,585,718,81,804,225,89,587,659,726,230,765,686,418,397,902,889,146,537,24,780,822,816,560,81,248,438,172,787,27,903,332,594,50,221,499,506,899,175,228,137,437,28,26,690,827,401,236,251,691,886,987,497,993,727,813,581,920,537,252,228,747,348,815,35,911,855,90,838,100,322,559,599,673,918,152,311,818,831,809,887,786,304,51,983,437,702,957,156,895,40,6,898,587,294,982,592,697,105,128,515,40,958,705,780,440,616,438,920,841,317,717,464,184,808,290,50,591,328,357,276,2,906,872,611,869,272,555,749,896,926,410,873,962,864,613,70,406,546,144,910,813,463,555,712,649,506,467,115,70,460,907,667,311,338,37,153,985,505,985,938,426,311,579,683,710,198,157,500,704,528,338,943,829,378,384,265,415,166,128,912,54,152,940,960,683,603,947,1,872,48,686,362,157,847,155,86,443,322,265,688,868,526,899,466,459,328,716,557,443,175,237,899,95,601,289,381,289,465,845,350,603,856,543,809,751,748,126,789,354,227,736,510,412,776,335,632,820,468,433,765,447,267,203,404,468,327,509,951,9,107,777,71,897,57,196,356,143,137,486,256,571,7,979,822,250,190,66,484,191,980,902,552,988,414,275,171,754,258,113,929,997,505,138,710,145,854,953,314,271,548,799,323,722,405,608,644,31,70,697,672,332,293,234,175,64,495,269,199,570,567,13,837,813,566,409,182,8,877,782,940,87,949,934,365,316,601,709,920,650,512,876,971,423,996,12,697,93,113,304,248,587,908,843,265,240,414,792,292,426,26,780,426,123,623,959,450,301,436,952,46,134,925,426,357,336,158,421,650,890,80,299,895,54,748,228,104,816,247,227,579,756,453,240,56,350,229,299,566,156,733,478,482,135,498,491,665,400,5,204,186,744,497,621,726,123,263,15,668,311,819,391,965,244,250,302,345,726,307,481,979,718,508,601,53,353,996,680,356,182,437,151,500,550,552,387,710,721,587,984,894,602,22,183,566,590,224,940,321,827,15,95,638,77,764,443,164,658,142,252,336,398,693,303,892,88,612,18,897,264,823,305,467,998,294,607,824,569,895,610,675,960,242,391,421,801,744,472,324,821,359,395,381,558,196,696,216,555,254,77,834,265,396,288,214,916,350,156,814,131,268,775,504,611,838,929,997,732,58,155,499,13,129,541,834,518,404,525,106,185,311,278,298,230,242,23,269,463,587,330,414,454,989,854,788,509,904,207,592,499,885,121,718,524,644,488,191,636,913,812,974,115,815,205,919,975,852,210,708,967,858,119,975,183,836,445,621,960,523,616,112,295,307,886,825,562,991,130,910,337,65,820,605,692,97,8,858,283,149,561,659,648,910,681,600,793,573,3,253,258,155,333,447,898,36,932,572,969,932,506,636,347,83,569,547,372,881,36,225,173,927,483,158,537,953,474,900,998,86,537,610,694", "461,629,79,619,312,606,835,772,78,403,939,341,732,550,382,633,831,883,293,987,112,794,638,456,805,142,907,937,548,162,408,82,102,796,261,999,269,553,217,458,324,310,152,698,508,597,332,686,509,279,419,224,215,110,858,683,777,558,985,694,101,792,476,330,180,810,797,768,373,625,0,189,957,393,629,141,569,908,187,922,20,449,125,277,949,957,658,827,116,78,577,901,428,540,851,310,89,651,102,488,979,680,364,780,938,197,182,970,670,965,184,287,939,778,731,597,105,481,569,10,958,238,811,705,670,228,714,442,13,590,889,931,338,940,575,473,400,350,679,564,17,197,81,709,60,449,729,921,834,698,735,555,51,223,567,261,791,264,231,762,817,74,702,967,248,448,423,172,923,94,129,625,414,766,300,587,537,767,38,133,247,424,574,848,156,281,389,266,2,101,140,557,367,893,823,448,82,106,297,706,751,44,500,176,751,546,452,340,996,129,564,342,68,628,453,995,274,288,689,356,288,586,713,676,938,30,357,832,760,4,245,459,958,371,493,978,948,190,201,219,335,916,546,748,963,464,914,871,381,203,698,161,481,657,927,677,207,385,110,651,807,986,989,67,537,519,840,730,511,603,131,55,785,57,335,2,395,636,216,180,884,53,276,6,400,704,433,888,288,698,552,699,253,352,172,522,991,278,665,793,102,582,520,676,707,698,995,47,283,537,481,568,487,576,224,881,34,492,912,741,936,971,911,955,107,59,728,760,986,940,736,43,220,232,534,749,855,756,564,458,119,923,995,571,4,342,90,527,364,518,226,626,682,864,737,31,682,845,639,424,664,911,924,659,228,509,509,458,499,633,232,930,597,311,804,967,508,466,992,266,548,160,964,728,687,948,205,208,745,374,102,734,653,848,687,638,815,930,42,955,843,192,476,315,116,273,22,876,264,492,690,525,702,528,217,263,801,527,275,59,1000,747,519,136,526,431,148,12,151,777,678,489,97,253,706,870,658,536,367,458,329,229,965,989,718,468,971,911,401,454,813,453,932,185,977,5,196,534,897,898,82,193,153,857,976,714,131,756,148,793,621,753,921,100,247,359,491,320,676,139,821,217,640,918,431,482,182,875,385,664,708,604,659,65,138,920,182,448,186,999,666,903,791,647,323,984,166,311,34,961,274,8,552,214,952,834,50,216,395,78,568,348,565,280,965,570,529,10,588,175,380,624,880,532,354,353,172,466,29,404,598,967,508,43,680,282,521,224,47,805,108,533,201,197,908,856,104,833,772,492,232,651,646,345,382,115,575,271,312,501,827,935,144,569,284,389,555,377,805,331,254,136,501,441,903,735,771,295,276,669,18,301,485,255,673,7,683,24,334,396,946,798,667,797,754,596,320,726,719,536,313,418,753,685,998,610,242,428,638,552,289,253,88,606,137,776,621,182,240,924,250,536,554,925,748,906,892,973,624,846,59,190,356,727,35,271,639,951,329,618,93,173,863,564,145,170,62,627,452,82,870,241,398,918,501,690,86,560,107,41,990,752,104,781,695,739,697,849,49,931,901,165,40,969,166,258,837,597,355,470,564,560,175,26,743,252,359,610,917,421,622,936,632,145,669,387,330,955,679,153,734,704,319,365,380,490,229,845,34,451,978,183,79,693,679,144,697,373,475,940,846,515,616,170,242,693,349,529,744,88,300,280,119,617,245,144,2,157,551,590,862,69,419,339,67,888,201,771,152,544,381,345,917,479,31,749,161,120,454,725,655,946,623,334,294,476,862,648,312,831,17,408,962,683,408,461,17,961,693,541,734,142,706,349,720,87,154,521,858,50,879,748,416,407,157,639,882,426,24,510,536,530,445,875,407,292,892,709,176,255,809,630,329,393,892,678,375,901,273,714,286,879,510,731,303,700,809,139,250,150,994,403,984,596,866,511,617,859,672,477,994,180,632,690,306,402,344,614,892,292,833,925,402,430,332,980,90,434,921,187,844,295,971,358,205,257,670,232,982,940,407,209,452,475,253,9,397,599,82,480,950,926,939,669,211,514,445,574,492,144,908,690,820,820,278,804,886,706,783,814,443,989,621,944,455,221,636,130,979,338,540,464,754,907,530,561,488,119,901,363,423,345,892,833,18,500,855,6,699,475,457,928,278,468,937,59,779,386,253,882,856,984,246,518,616,656,546,978,394,913,34,686,986,239,379,452,670,111,371,60,479,864,884,553,575,110,905,263,134,811,398,218,250,250,32,148,736,887,706,327,766,122,924,206,223,285,177,48,989,280", "386,25,63,545,81,22,899,171,395,79,880,215,862,209,440,332,656,789,675,608,989,984,630,140,771,667,905,892,161,697,803,935,81,521,98,435,165,631,823,44,233,625,930,648,566,242,530,867,266,929,205,538,841,605,30,300,555,752,569,961,621,352,824,753,328,342,778,99,915,620,189,0,229,571,325,263,461,650,96,642,619,352,729,871,940,605,502,310,203,332,39,767,137,432,284,274,560,549,908,3,471,55,162,499,440,221,702,518,713,407,62,649,410,272,768,106,373,924,600,111,154,596,911,854,126,476,11,181,115,749,811,482,754,512,371,580,835,796,327,583,524,799,367,8,643,346,56,795,6,286,766,47,120,418,367,730,937,150,625,915,850,906,478,736,15,746,790,90,345,252,969,326,761,986,823,492,643,179,13,371,195,351,538,380,110,637,258,731,610,198,845,467,840,335,860,846,961,165,774,813,416,301,538,962,518,710,545,536,963,450,830,655,934,155,727,393,618,85,295,796,455,197,200,180,865,524,498,666,425,572,846,78,644,441,27,482,751,746,390,79,448,713,116,400,624,247,627,368,594,573,516,138,424,4,353,92,766,114,333,596,670,985,680,582,210,59,391,773,912,238,904,941,842,626,775,753,318,88,971,162,583,836,803,961,424,588,764,678,457,166,926,348,676,431,782,902,940,241,913,301,505,615,661,57,5,19,305,406,445,10,627,405,845,306,767,994,321,6,600,110,174,812,278,93,258,439,645,806,12,845,488,748,862,483,639,265,673,918,650,131,660,926,651,295,620,572,386,760,456,532,689,773,450,627,302,991,857,29,160,849,929,189,680,413,918,78,545,622,372,239,586,305,907,527,404,289,960,41,507,70,759,755,539,705,691,328,670,720,460,626,648,782,954,133,790,700,662,870,354,660,942,724,844,504,488,817,336,959,5,10,892,351,356,89,70,932,280,20,137,839,879,592,161,715,161,61,334,388,12,192,579,310,246,922,570,491,652,49,778,176,550,83,910,312,823,581,768,770,537,413,596,224,401,196,467,20,56,100,943,252,319,675,655,52,435,219,71,195,995,455,153,77,288,447,349,510,622,679,171,791,192,648,566,123,528,158,724,698,889,418,475,249,665,232,194,494,646,994,673,679,782,883,577,660,793,798,282,480,438,771,971,569,983,112,498,729,712,40,812,900,78,381,726,125,633,215,735,312,667,431,464,224,476,52,917,157,787,660,19,451,325,27,492,996,494,410,425,398,366,544,997,578,507,37,538,882,636,520,423,661,344,494,613,207,132,980,222,453,209,346,288,208,688,881,222,467,741,312,22,754,949,434,684,525,258,860,126,967,762,41,608,473,194,384,13,752,709,931,599,81,514,920,708,157,546,841,805,911,677,13,547,257,637,368,62,145,416,951,435,692,619,840,77,36,376,517,10,89,425,938,431,228,339,821,284,84,611,596,944,37,780,629,642,686,742,622,587,408,235,19,575,199,285,153,516,516,63,958,885,541,790,61,960,138,976,289,390,684,885,288,66,964,40,974,252,420,264,885,852,868,807,409,529,934,251,645,749,97,688,863,518,319,738,816,2,49,963,653,996,324,211,518,513,820,956,781,857,300,100,150,132,503,81,934,950,858,2,424,443,549,349,180,463,959,562,96,209,873,540,484,997,485,711,800,418,425,599,645,744,593,240,199,806,185,69,546,933,714,106,953,411,753,473,297,316,508,354,894,368,5,15,65,385,583,410,293,189,1000,962,77,370,532,124,185,773,721,2,79,544,918,436,786,608,180,165,278,824,120,818,257,378,900,778,482,748,150,164,689,226,841,193,651,642,831,42,664,690,705,785,354,211,63,870,217,461,111,868,422,581,818,814,618,875,754,806,521,48,638,378,25,90,44,610,747,348,610,762,412,288,183,47,30,561,782,546,754,382,532,364,564,230,599,580,593,342,400,235,805,521,716,735,431,993,442,410,712,917,586,780,626,204,379,577,5,873,434,979,710,516,446,396,849,562,242,816,697,676,68,24,97,345,244,546,790,654,777,462,45,814,604,26,570,599,566,240,572,847,321,708,335,372,366,258,570,84,63,582,347,900,320,476,512,760,563,839,841,653,356,570,616,691,653,321,367,744,980,832,820,566,84,386,516,121,6,391,316,82,470,258,710,875,479,78,262,790,503,846,964,175,444,613,32,186,931,523,291,476,886,234,49,919,717,700,785,82,135,832,102,791,366,323,150,676,896,948,250,84,158,756,297,762,749,6,222,15,945,61,403,582,785", "536,779,286,30,1000,943,562,721,920,812,64,442,901,256,35,458,920,220,498,545,711,907,998,54,506,357,134,183,161,487,937,486,139,262,855,386,66,529,727,833,156,936,705,871,880,84,357,36,241,861,413,322,437,863,862,596,161,870,53,10,223,781,79,614,617,341,461,49,594,237,957,229,0,797,260,378,75,345,635,745,625,589,222,699,202,107,479,392,570,575,530,3,128,717,293,742,923,351,79,902,417,755,571,303,878,680,687,692,678,610,611,574,336,34,921,66,325,3,38,975,135,330,507,471,831,242,905,866,736,810,667,822,176,375,282,556,289,828,992,278,744,63,637,62,673,275,957,745,29,202,592,464,668,705,665,617,147,197,711,885,337,87,749,692,911,270,265,755,497,463,683,7,43,328,504,69,197,862,55,677,445,269,352,529,786,331,239,492,596,739,646,602,532,436,285,251,415,753,528,426,127,636,170,244,821,569,557,965,977,754,371,499,40,500,182,135,485,207,650,345,49,8,587,631,796,725,472,30,833,700,988,665,537,77,114,794,938,150,242,238,365,914,160,427,267,38,912,288,599,745,858,416,227,149,231,977,151,201,209,720,72,892,553,819,323,641,564,258,248,28,78,618,512,280,592,149,431,972,33,639,937,374,503,358,446,939,531,77,789,9,237,838,367,818,104,57,279,139,979,590,895,935,78,972,350,85,561,272,512,580,777,872,283,699,514,269,414,894,250,457,44,987,674,165,767,44,544,126,200,829,3,911,829,932,921,768,67,764,703,783,814,303,380,966,56,979,849,169,117,35,736,702,841,111,114,302,102,650,726,277,146,998,887,940,63,313,47,870,570,104,903,113,202,348,561,836,93,294,605,394,213,861,602,596,664,295,555,729,258,673,923,233,356,600,828,530,698,950,545,272,883,493,334,81,67,462,615,869,763,597,408,99,535,379,454,93,480,446,928,903,594,929,655,227,570,754,756,78,614,199,169,751,179,66,533,710,739,61,330,233,718,964,453,703,685,860,553,986,828,355,786,34,792,213,70,914,126,729,176,798,314,195,726,9,917,378,817,653,805,273,585,650,53,604,51,716,372,510,860,661,4,241,720,469,683,619,65,486,633,651,593,392,169,487,428,729,78,224,348,243,631,964,404,373,154,888,570,872,782,729,828,33,294,368,286,764,89,151,805,888,163,906,436,112,760,173,151,515,702,329,551,580,180,560,177,920,514,21,519,140,87,764,747,522,395,907,783,727,858,663,399,741,441,752,644,374,831,578,631,654,145,603,457,28,851,99,393,69,913,999,261,677,991,868,340,690,727,670,725,294,413,921,576,123,611,493,730,904,862,143,882,808,50,771,663,981,531,39,101,270,425,710,826,627,12,332,199,682,370,994,722,720,805,771,544,775,843,250,834,579,524,949,271,97,278,676,645,246,710,912,981,160,963,280,573,561,555,718,445,720,679,666,198,45,832,325,834,768,335,30,975,640,520,98,365,195,556,303,20,911,648,965,126,358,197,855,526,558,710,973,68,480,67,974,272,237,172,66,691,624,315,891,363,971,697,817,52,690,394,62,573,408,415,289,962,459,926,907,937,130,979,627,354,85,701,788,612,376,393,384,405,318,306,134,605,724,116,901,196,997,377,81,147,837,850,511,438,713,620,233,879,86,220,837,336,308,63,422,107,913,376,948,672,886,631,975,643,546,215,314,259,734,327,353,424,658,635,824,161,252,173,170,932,733,848,143,318,975,24,506,595,35,995,649,845,53,347,866,322,85,233,165,855,770,431,170,191,116,917,976,479,569,232,500,128,391,721,110,39,785,6,83,932,996,361,99,692,752,773,276,317,629,483,338,232,837,59,566,455,380,785,264,183,697,780,762,35,515,397,84,554,326,826,456,71,138,911,36,866,552,636,372,258,580,247,374,335,891,758,231,300,830,734,348,98,20,187,86,717,914,73,424,327,595,49,862,135,822,398,770,712,406,542,529,344,980,897,702,935,80,196,978,386,579,156,146,559,88,918,688,947,943,909,398,761,616,169,570,448,711,93,209,665,314,868,225,916,736,283,3,777,611,235,664,821,278,316,179,634,733,610,49,775,719,99,824,991,835,191,807,937,397,744,549,601,695,678,238,378,394,191,908,526,103,42,426,552,327,449,373,16,524,55,724,232,76,394,661,52,970,233,722,535,963,665,872,314,782,12,742,535,888,574,640,283,54,828,338,875,681,22,782,57,922,69,821,318,765,512,959,256,624,611,851,117,667,676,583,765,433", "942,492,499,163,453,781,391,50,72,252,655,575,991,703,368,82,827,534,622,100,106,268,569,679,967,879,58,611,287,726,332,615,887,915,894,337,350,221,126,585,651,828,571,1000,729,744,385,634,253,321,312,841,264,62,57,454,257,715,289,49,780,175,281,371,876,40,609,130,615,89,393,571,797,0,236,370,876,626,717,36,212,608,694,400,760,67,752,403,455,793,63,950,911,677,315,894,258,74,42,826,740,211,968,448,444,726,251,21,763,460,293,541,437,642,877,960,589,602,805,500,752,158,390,648,131,809,519,209,440,874,521,937,629,871,504,561,900,754,630,159,759,444,606,11,292,183,612,818,109,680,765,737,440,406,19,3,133,943,783,431,36,831,880,896,285,643,160,735,289,840,682,339,198,117,497,247,202,572,325,490,865,211,43,503,170,869,879,489,499,278,102,937,279,620,913,96,35,551,759,17,547,437,346,274,686,217,911,86,309,268,559,564,346,411,7,81,889,533,585,673,576,975,434,550,349,197,597,817,738,778,711,814,29,204,417,189,280,53,327,72,90,524,234,262,604,490,261,944,13,20,609,126,270,86,925,511,514,739,99,787,452,47,853,138,438,313,341,16,849,365,465,535,544,695,85,553,351,31,356,203,638,643,84,366,995,646,579,815,262,91,953,211,156,648,82,918,826,822,10,776,651,126,511,396,58,942,993,481,815,98,458,183,925,925,842,695,161,274,917,421,318,688,215,841,233,744,289,442,721,55,900,367,858,370,851,265,298,736,247,60,248,25,245,385,788,374,98,587,758,709,1000,402,586,598,831,895,976,493,409,610,290,604,486,950,169,273,487,231,756,150,327,722,113,791,189,559,630,497,10,51,249,247,427,192,820,272,771,396,246,275,109,974,268,231,457,761,642,801,400,317,481,578,781,990,638,607,458,322,824,862,727,373,874,942,23,239,674,605,828,598,398,736,551,340,485,780,157,830,481,57,99,326,222,663,520,698,29,37,320,1,166,151,883,121,884,670,750,744,406,511,242,971,377,76,930,612,545,969,719,484,91,495,234,623,866,409,971,517,157,808,399,58,910,741,369,76,990,591,731,749,274,98,335,352,518,803,986,126,985,751,330,853,399,496,25,929,274,370,506,56,751,189,15,244,42,173,934,446,67,82,630,501,665,848,860,794,476,574,314,880,753,264,251,692,62,883,322,66,304,144,939,330,984,752,374,989,128,253,262,960,932,627,902,126,551,410,260,280,923,21,814,605,690,722,411,386,597,932,837,940,994,397,32,88,825,366,804,127,875,280,495,4,869,228,433,368,460,399,974,8,893,598,824,514,608,638,391,21,868,890,764,218,237,393,87,149,692,687,678,452,591,174,890,845,316,639,811,388,100,901,403,640,882,184,413,99,106,51,321,824,67,350,79,267,145,975,128,793,817,614,380,88,271,223,844,264,732,528,119,772,370,114,547,276,753,301,52,330,975,467,242,457,288,226,243,771,966,786,116,926,211,901,474,842,937,558,361,490,72,604,30,844,634,163,507,683,377,900,687,388,123,128,207,994,150,161,783,405,435,773,244,537,711,250,756,38,311,57,432,93,126,53,273,87,485,162,795,530,416,483,811,592,466,940,712,285,152,255,543,428,596,215,202,351,725,26,472,783,446,49,616,656,404,822,658,165,437,245,377,783,279,724,900,255,310,46,598,86,55,567,399,128,932,761,556,753,669,958,132,889,758,204,516,539,733,713,63,469,712,920,992,225,909,75,47,748,863,929,146,541,265,442,503,355,737,771,625,760,156,908,286,261,211,262,55,790,604,176,216,815,832,483,672,198,395,154,43,148,619,200,683,944,394,418,201,855,549,452,191,479,298,717,424,562,75,353,561,150,942,199,253,247,528,498,923,842,157,402,355,803,468,299,494,817,295,713,955,161,365,234,727,688,239,267,657,205,497,433,268,113,30,722,457,879,751,299,633,265,778,601,469,566,961,622,111,457,100,444,799,355,584,415,488,717,537,782,941,291,158,249,502,680,115,160,165,287,966,744,237,132,539,169,704,720,20,196,756,175,856,991,861,825,943,201,136,106,297,98,161,875,873,302,897,746,376,418,790,800,645,21,430,490,194,58,721,54,415,957,470,927,123,226,662,835,254,329,118,961,704,402,541,28,304,316,733,688,60,999,655,35,983,63,186,442,319,693,585,128,408,83,483,315,855,790,522,277,415,522,525,328,491,450,939,729,255,381,938,939,489,880,586,703,456,729,521,705,756,234,601,895", "533,412,302,866,659,129,157,30,272,187,936,543,990,953,104,736,776,777,456,559,168,979,967,382,376,30,955,575,160,431,314,778,666,817,863,618,577,534,677,442,39,67,804,896,329,143,245,818,644,730,821,542,337,433,327,693,28,742,244,672,507,682,471,646,310,31,445,285,822,87,629,325,260,236,0,465,641,299,197,778,426,24,692,716,22,1000,783,283,753,638,813,38,171,438,266,354,284,79,230,379,366,136,133,393,253,757,357,65,324,708,711,356,585,424,107,171,813,203,666,937,857,429,295,427,140,718,152,763,75,227,912,275,435,18,184,5,807,889,409,223,854,175,787,165,654,719,518,691,837,800,928,104,933,564,713,801,142,43,158,306,266,496,234,186,821,167,658,419,910,599,29,999,634,231,39,226,130,2,751,28,237,535,216,466,820,190,846,928,660,428,924,117,222,948,778,195,493,584,608,766,635,457,436,641,551,643,164,320,233,899,277,580,535,365,767,456,389,796,637,814,328,200,626,558,626,489,876,728,132,539,652,579,783,133,986,527,895,572,960,564,490,9,284,197,806,737,774,461,315,419,250,654,856,60,19,957,308,651,254,538,368,469,743,326,429,503,326,171,752,298,538,425,875,221,130,660,517,139,53,283,511,531,107,709,570,814,10,449,389,218,216,856,464,272,916,251,592,428,299,82,36,720,862,540,462,798,390,156,676,700,949,925,480,786,599,728,98,992,978,456,837,687,202,162,132,861,54,957,215,660,135,417,576,744,389,991,379,161,674,513,630,726,511,454,869,973,947,818,517,620,756,526,446,16,421,346,150,466,685,201,819,270,859,754,505,827,811,690,293,592,968,693,803,931,915,560,129,990,381,411,96,603,643,185,105,295,870,68,600,395,187,773,891,616,719,240,496,941,780,674,653,861,622,977,809,99,323,678,106,609,895,119,608,806,869,271,975,30,554,820,351,666,168,729,831,410,773,931,383,657,184,507,188,914,379,243,438,215,561,252,813,717,19,964,641,716,337,274,440,584,437,183,701,630,551,175,870,64,827,908,74,905,202,154,859,582,925,681,481,530,75,277,767,19,835,918,249,232,453,387,839,331,967,13,198,689,802,605,258,203,341,882,31,658,689,98,371,356,127,856,864,882,443,926,526,343,366,849,699,564,381,999,628,188,165,88,568,698,719,828,977,443,804,482,209,428,310,485,368,467,238,520,593,688,651,801,449,746,77,691,281,859,240,395,28,346,556,586,790,216,714,255,344,114,723,898,530,519,464,252,208,159,102,262,586,247,369,961,125,260,953,32,581,322,818,23,898,541,443,505,534,458,78,323,659,729,779,938,955,526,163,628,910,161,629,870,602,742,683,776,528,349,622,402,719,425,806,238,833,598,161,487,908,402,384,102,377,725,569,862,690,862,307,895,401,985,263,720,190,773,518,862,487,328,292,926,261,551,956,312,241,896,460,73,212,802,263,944,130,836,671,736,534,664,791,822,130,280,792,519,788,360,877,864,611,470,169,382,297,208,179,451,52,552,419,739,549,687,134,268,334,951,48,962,781,140,265,681,208,314,347,119,16,578,447,558,720,70,375,738,57,634,163,923,666,296,620,20,444,247,521,557,941,672,824,292,183,350,661,288,408,645,437,719,868,623,855,693,834,260,759,546,444,981,490,946,875,216,767,306,610,114,594,443,119,953,378,801,147,792,332,822,263,535,491,580,992,470,423,644,889,800,480,235,537,181,885,471,629,218,302,514,772,854,166,272,948,95,542,165,446,715,442,740,159,718,206,63,740,837,282,495,400,309,860,465,185,611,137,693,887,770,357,897,591,146,268,893,877,40,747,454,362,366,249,376,933,51,208,972,994,51,514,710,950,778,183,378,141,724,383,800,358,813,368,953,348,620,215,585,90,729,766,902,456,524,326,21,260,118,864,753,827,898,227,603,572,371,721,306,736,926,610,325,261,439,281,14,398,846,474,468,338,314,433,916,267,992,943,868,449,860,660,679,261,914,956,323,962,779,308,958,169,493,822,858,254,539,132,118,339,778,686,441,716,788,967,373,776,718,699,902,567,9,283,185,83,897,869,4,573,991,945,418,51,975,757,572,617,295,824,717,479,797,917,682,71,500,921,560,613,77,340,297,348,590,683,297,268,130,191,863,659,441,349,497,699,24,43,560,710,895,5,829,759,364,293,357,751,939,887,424,141,58,505,551,951,35,258,389,506,167,281,959,325,412,404,267,239,990,953,757,252,76,662,93,88,720,367,943", "774,778,842,785,936,203,933,345,622,260,602,913,135,165,866,793,465,976,910,274,343,16,425,793,534,609,818,839,969,332,213,216,6,572,419,992,165,823,667,455,229,433,990,534,454,320,895,58,804,239,385,253,332,646,264,514,43,412,846,399,550,857,847,418,901,677,24,432,710,711,141,263,378,370,465,0,587,908,169,38,629,538,271,824,624,405,65,622,827,786,978,835,338,595,929,545,804,517,119,485,480,953,299,416,368,411,175,399,470,348,425,61,99,506,953,507,11,774,82,422,966,637,573,314,101,900,104,888,790,456,590,945,588,303,588,99,413,712,78,443,196,739,231,27,873,7,902,211,16,12,544,311,794,113,835,67,416,30,980,293,875,203,283,398,152,339,659,698,763,836,196,333,664,396,258,778,852,274,238,50,243,292,579,901,264,202,964,752,555,237,709,268,638,894,235,291,705,434,140,340,213,973,748,715,540,163,874,35,434,328,161,742,355,911,814,7,187,745,185,477,508,112,561,634,182,371,280,901,103,140,819,318,739,676,354,400,162,933,749,745,583,352,560,510,511,589,967,103,719,993,533,605,652,750,397,565,626,798,155,864,635,525,148,913,153,744,20,876,504,684,339,396,62,68,556,110,82,93,192,431,982,156,882,118,309,344,506,726,659,620,872,690,926,712,999,976,4,848,51,404,21,277,628,527,965,842,509,344,853,222,57,532,135,835,343,678,646,130,292,403,163,195,81,135,133,111,175,930,329,485,499,579,612,529,731,400,485,522,292,685,33,399,813,677,536,131,277,639,529,815,852,552,946,487,368,440,707,734,166,377,968,706,187,726,875,491,154,727,404,961,131,171,717,722,697,459,891,95,838,323,83,723,663,476,944,858,611,169,871,782,687,354,800,190,392,308,272,754,823,467,580,719,971,42,650,994,26,374,752,2,447,452,904,388,915,776,315,678,271,76,589,107,73,269,728,202,935,437,339,66,716,650,501,940,181,642,127,878,360,362,878,417,457,43,902,258,677,931,718,170,94,861,581,819,729,722,328,59,559,209,362,353,748,685,260,387,273,658,745,353,632,196,729,903,891,135,675,498,80,615,507,713,22,358,647,893,650,313,715,835,765,397,681,512,657,275,62,130,59,869,724,231,770,298,598,367,488,280,473,398,576,510,117,417,289,865,94,385,601,540,893,811,392,627,566,275,515,120,177,936,615,930,570,787,210,886,478,666,399,954,163,51,789,726,894,291,89,111,168,200,22,985,8,670,649,32,67,529,926,437,949,153,515,75,596,200,497,704,905,135,429,117,684,634,285,849,56,920,365,463,712,285,866,601,618,495,271,320,681,921,805,487,437,465,936,218,675,187,89,838,581,512,941,17,290,220,558,678,868,55,870,631,800,417,491,838,824,795,549,183,738,159,412,944,590,500,323,867,176,758,27,687,615,594,608,776,296,705,614,986,62,62,537,42,25,885,831,168,4,972,989,552,566,161,332,629,372,211,892,71,137,48,171,95,394,289,237,363,691,819,542,271,418,579,857,37,914,584,651,178,906,439,32,389,691,152,347,737,543,981,21,288,461,670,782,676,210,629,31,589,628,821,993,106,497,515,211,446,847,39,473,981,625,733,381,410,486,431,388,439,854,939,209,557,466,991,500,446,777,947,916,151,816,305,229,92,426,839,625,418,689,670,755,423,770,162,982,715,624,881,727,530,727,692,914,926,448,178,453,696,455,406,170,15,160,840,378,860,554,429,780,309,840,868,261,327,665,500,606,491,20,948,670,236,830,217,492,66,635,702,723,394,593,564,705,668,816,871,799,630,245,209,470,627,637,958,449,584,478,550,872,212,245,615,279,662,190,819,29,545,186,931,224,891,35,33,389,238,531,187,30,878,716,780,337,163,604,601,240,301,655,257,342,756,136,912,904,466,280,540,10,879,163,654,648,596,309,958,634,318,588,865,866,646,24,404,4,60,245,93,918,893,453,46,94,802,224,468,978,734,783,579,735,706,748,474,653,670,142,259,916,874,692,353,890,454,124,146,357,518,523,637,567,644,842,659,275,31,889,167,571,655,366,151,816,98,589,720,452,451,995,625,458,920,611,836,45,8,485,465,93,454,621,612,15,38,833,278,571,712,437,45,905,415,533,793,931,591,816,375,853,615,917,684,960,27,151,619,191,974,302,179,221,790,238,61,188,195,729,87,641,867,171,562,474,985,586,888,729,671,719,214,752,916,808,393,885,341,308,43,745,798,525,129,740,784,202,348,376,111", "71,302,682,54,930,381,691,332,583,706,814,296,976,935,595,446,599,672,498,257,853,26,319,213,779,946,578,23,617,510,694,402,782,427,717,376,199,274,568,143,893,37,447,492,522,905,887,877,462,620,819,292,611,421,807,294,681,660,563,236,948,549,614,50,870,390,668,649,140,953,569,461,75,876,641,587,0,439,88,841,930,402,918,735,185,215,159,60,716,475,886,664,422,425,744,926,310,881,325,361,149,379,323,86,927,564,878,480,839,14,160,771,635,793,834,695,693,121,988,832,931,887,399,544,122,653,990,302,450,827,832,159,293,198,685,417,133,114,666,882,835,743,865,801,123,755,882,336,656,927,933,610,245,696,460,869,31,187,636,693,602,665,97,544,313,157,900,602,903,845,693,622,630,504,753,430,666,325,101,89,954,729,905,724,335,347,158,488,260,824,324,954,791,715,552,233,616,578,487,461,613,30,679,853,630,785,908,566,262,55,915,556,742,919,438,210,963,496,613,234,88,288,682,817,608,437,354,800,812,209,876,303,924,184,761,837,258,46,776,94,268,314,34,230,318,246,994,187,752,812,46,414,247,8,630,521,66,991,42,952,684,392,460,16,233,698,124,451,37,490,205,278,187,335,951,165,141,442,573,288,412,582,929,38,573,16,108,476,882,972,731,238,630,548,463,706,133,651,167,990,568,465,700,463,376,302,50,454,591,462,659,507,283,367,985,137,842,473,879,518,240,508,660,31,597,656,955,746,853,253,783,987,732,618,220,136,129,826,877,587,185,465,891,208,288,427,212,485,904,689,931,886,462,752,492,268,945,837,813,724,188,99,186,297,451,751,704,236,266,594,494,928,371,513,127,462,786,68,366,799,14,269,812,912,601,417,787,436,7,53,353,110,93,668,251,422,778,827,483,348,924,195,827,806,374,645,343,812,551,613,48,161,325,205,585,846,29,893,988,153,659,835,563,512,805,961,287,84,767,834,81,112,344,582,77,524,897,880,433,60,148,16,506,811,342,307,719,216,404,667,436,403,287,816,521,168,404,663,981,317,611,968,869,632,667,489,46,830,321,212,796,808,797,308,747,558,418,14,287,578,300,394,538,30,138,573,345,69,545,809,829,887,648,870,882,854,169,852,546,666,159,721,271,894,555,571,689,451,742,456,702,730,743,229,64,843,842,881,451,937,410,442,230,483,589,223,713,222,70,441,799,27,843,636,832,766,44,104,382,881,443,199,532,903,514,652,287,263,500,922,238,632,408,846,723,870,894,577,596,148,16,98,432,76,274,908,567,186,947,970,38,609,467,602,557,346,962,560,78,536,355,826,655,66,288,407,364,840,925,596,76,948,843,249,389,726,486,58,33,67,856,558,30,297,87,419,687,13,599,785,832,850,88,768,154,699,803,564,250,695,780,539,603,978,702,180,90,522,795,627,921,333,950,528,872,576,845,499,290,610,955,144,659,756,358,473,535,960,566,986,108,335,146,625,631,651,655,137,231,743,405,400,890,337,85,979,528,10,824,535,77,274,365,66,64,71,198,412,820,449,589,795,608,916,113,321,992,919,981,234,617,53,827,11,797,550,857,520,152,946,121,875,451,479,111,593,953,551,792,602,420,859,435,70,115,970,67,362,260,538,897,563,757,794,960,907,506,509,581,747,237,801,689,102,862,779,814,560,666,886,143,964,676,732,625,492,568,566,342,26,351,590,733,984,221,387,412,37,162,80,833,14,340,193,443,903,811,732,226,537,873,508,304,588,627,584,231,836,426,60,131,561,520,315,861,803,710,298,127,421,354,109,781,757,849,380,705,573,900,844,12,432,605,213,646,513,697,562,109,707,11,547,272,401,410,11,275,299,685,68,397,303,517,379,629,63,329,504,3,984,561,931,703,616,890,469,574,318,463,475,689,411,765,473,21,333,231,244,175,479,818,153,563,34,10,610,818,962,887,662,33,138,375,953,354,166,142,730,845,931,295,955,986,513,758,194,538,70,307,230,742,227,349,756,356,762,350,861,959,632,958,755,789,932,574,26,499,651,201,790,381,229,231,303,445,526,118,632,277,600,365,500,828,64,972,572,250,507,345,345,962,764,913,352,111,135,497,770,716,843,19,903,471,985,398,315,474,501,35,458,109,771,24,463,742,41,457,550,838,700,682,529,542,830,371,825,816,386,610,960,887,876,654,135,434,328,188,335,64,468,282,186,927,325,873,656,349,159,707,253,440,29,320,731,707,545,575,532,699,665,550,271,984,129,929,83,904,402,10,838", "996,220,896,219,252,316,918,991,278,2,436,33,17,415,94,626,199,700,713,452,231,111,599,730,19,53,195,150,516,412,594,237,837,768,379,845,649,171,882,507,487,868,128,148,408,56,445,334,110,591,908,85,854,750,795,442,25,396,150,928,226,758,977,260,922,974,1000,634,285,431,908,650,345,626,299,908,439,0,663,93,765,747,893,926,934,768,303,683,174,686,133,486,78,892,504,527,668,587,817,859,969,191,795,525,180,886,735,650,607,241,510,53,305,639,865,681,351,265,84,924,55,218,37,66,929,995,123,185,976,19,405,169,775,772,741,670,390,700,602,560,38,791,751,947,354,620,651,664,802,575,681,567,865,644,862,59,833,559,854,468,731,199,864,971,370,90,787,383,820,60,437,423,552,707,847,782,742,574,89,992,311,25,43,424,808,728,356,640,123,34,727,104,483,21,261,957,308,622,104,743,938,813,874,800,641,794,530,595,950,744,298,564,397,72,448,81,927,995,944,959,27,949,257,235,8,127,193,398,154,254,434,672,209,580,652,314,887,387,43,25,349,345,249,826,408,176,472,59,877,647,61,121,3,503,140,346,434,902,424,43,812,107,325,960,413,568,335,185,68,684,367,480,559,931,528,282,675,940,825,920,927,946,487,71,228,885,94,150,795,386,594,305,310,327,155,137,189,442,459,807,900,944,84,292,725,686,299,791,595,897,709,397,704,608,417,521,8,605,711,519,48,58,190,905,676,946,779,540,977,681,928,86,38,858,73,625,924,873,768,407,894,23,247,667,697,834,385,297,929,998,79,824,442,912,322,283,459,514,66,311,988,477,997,62,137,475,543,561,193,827,819,931,246,696,262,493,733,283,510,898,150,472,599,453,236,231,801,921,159,741,627,377,174,305,807,679,845,402,415,692,88,826,861,576,718,375,149,773,555,44,965,665,439,355,144,113,857,78,633,238,579,670,200,952,780,246,698,203,196,271,288,144,524,45,611,313,801,431,715,571,626,956,583,138,781,94,985,312,269,365,22,372,600,533,707,257,25,791,205,283,55,573,710,620,34,540,875,260,217,304,549,224,467,864,153,822,561,702,124,29,696,710,206,999,580,716,855,777,93,74,872,207,841,44,723,145,45,595,487,679,411,418,188,123,773,333,33,508,676,435,410,612,173,504,560,952,19,700,626,350,372,595,753,213,962,171,22,921,82,831,465,328,988,967,714,190,674,272,539,305,175,618,251,645,753,858,933,697,391,169,34,18,146,947,46,900,125,877,360,351,459,517,948,732,439,635,278,345,380,781,239,336,192,559,229,175,281,231,264,838,128,818,147,670,307,508,537,764,247,274,932,854,64,42,691,553,184,23,420,358,877,513,219,783,495,440,679,601,468,414,629,914,718,934,485,138,378,966,302,543,211,904,256,880,881,999,300,611,654,49,643,393,558,778,54,24,278,138,439,22,211,422,775,909,407,927,30,107,495,127,838,699,35,277,496,832,851,968,620,893,886,271,966,892,647,791,979,645,986,79,849,559,174,35,385,521,597,970,925,93,159,31,552,697,553,454,943,243,432,889,989,467,159,921,527,628,316,914,551,1000,143,718,86,993,127,652,205,276,654,706,712,823,154,765,546,394,565,697,240,267,45,583,58,891,321,747,182,216,113,656,341,969,962,39,814,639,882,826,146,691,318,671,3,965,129,311,95,279,275,576,615,680,798,26,673,188,602,977,75,529,168,695,266,885,30,726,656,770,704,205,360,728,460,902,66,485,810,369,513,24,782,139,402,336,74,172,204,708,752,497,469,336,419,339,886,804,708,50,217,833,604,701,353,459,273,277,538,521,369,691,267,999,330,340,94,342,717,557,911,180,713,339,3,412,930,501,479,242,523,359,988,59,914,485,370,843,740,928,371,765,572,17,49,186,21,795,63,551,301,446,725,379,326,269,702,835,314,545,461,731,478,619,817,349,562,524,524,974,556,804,30,106,445,683,435,571,74,622,330,951,178,842,952,820,796,528,14,35,130,457,797,428,803,944,204,620,793,615,452,310,975,822,384,525,173,461,593,891,698,700,692,887,826,55,705,910,101,344,335,715,760,393,273,839,352,960,610,314,752,997,115,334,561,205,493,570,5,351,526,842,65,714,818,115,224,312,615,461,165,300,304,63,507,769,617,215,587,825,144,511,666,422,203,39,234,694,929,106,646,753,204,662,572,299,772,169,846,581,727,269,227,28,361,387,643,638,77,770,708,176,944,235,514,16,788,722,14,869,68,776", "752,159,576,573,904,445,516,807,571,142,545,61,242,478,458,233,149,106,451,785,7,298,101,283,8,263,675,472,450,92,295,530,780,632,257,652,204,891,584,274,98,126,857,342,426,970,716,932,628,602,427,628,102,220,478,14,204,401,528,71,847,270,742,811,11,42,786,199,686,764,187,96,635,717,197,169,88,663,0,13,628,963,947,870,529,561,911,739,137,529,353,40,435,322,780,494,10,753,960,518,587,324,852,670,353,690,46,848,904,487,233,683,519,613,978,944,558,441,854,547,784,202,637,276,389,409,570,620,522,321,197,755,263,396,747,650,956,361,618,160,570,772,963,919,952,519,618,697,227,238,738,910,690,474,698,71,825,320,982,645,416,734,79,521,297,166,957,652,88,120,920,123,876,969,514,764,541,654,710,877,190,206,648,798,680,537,416,997,695,788,620,432,565,725,746,317,507,929,55,669,117,114,217,427,127,25,589,809,614,325,94,265,500,591,368,857,643,721,660,650,155,332,138,336,57,871,386,141,963,131,794,668,561,651,132,193,652,116,676,791,830,180,840,537,587,421,327,380,953,723,977,289,139,576,292,2,842,65,363,651,838,669,760,900,862,141,209,940,413,269,690,871,164,639,920,567,92,606,851,919,862,547,293,544,254,327,995,759,749,905,464,9,421,51,269,123,23,892,626,555,982,145,420,141,539,540,727,64,869,104,681,56,2,126,513,728,689,816,874,110,11,507,437,262,762,682,82,777,548,120,34,933,657,562,945,48,366,935,973,628,631,657,709,295,456,615,223,784,458,148,487,990,641,50,391,349,640,385,368,315,116,180,648,500,146,353,653,28,605,197,89,552,695,856,309,886,901,913,716,417,176,932,729,475,89,568,599,539,855,734,650,939,360,243,739,550,816,402,519,520,404,936,996,595,349,119,762,671,232,54,411,234,630,937,778,772,466,639,213,548,669,391,693,914,567,818,330,140,513,677,632,387,302,753,10,920,349,267,893,381,343,201,151,313,546,361,430,533,791,337,97,577,534,330,923,271,462,852,504,347,754,24,634,522,550,85,154,215,317,143,523,816,395,802,580,236,767,670,460,208,191,493,731,340,584,921,43,727,635,871,858,239,734,754,443,21,88,657,287,712,64,277,749,189,687,276,744,446,734,851,611,709,696,125,494,528,789,682,732,431,948,379,501,991,677,262,982,889,65,179,942,771,168,738,740,992,711,239,701,851,51,856,749,822,525,964,854,123,100,830,965,489,267,934,314,172,49,511,762,685,795,548,432,509,560,326,525,99,69,57,370,956,952,153,209,588,283,931,204,689,484,723,383,753,558,622,165,673,115,190,909,165,230,373,283,673,889,409,824,62,418,352,669,971,49,378,554,747,777,874,758,95,639,418,804,886,313,407,458,21,578,953,55,811,894,777,563,264,770,310,863,641,725,824,668,265,767,974,833,451,904,467,220,274,153,892,138,425,879,49,201,394,528,660,59,879,42,283,628,430,850,653,451,729,168,845,662,565,990,24,897,629,343,7,32,909,717,118,553,989,7,443,184,416,783,199,94,632,209,976,795,531,121,343,830,39,260,655,306,761,792,660,377,215,309,975,686,769,371,613,697,817,324,155,743,357,846,692,844,267,255,664,110,882,704,172,450,276,773,701,221,350,813,491,238,63,147,56,230,818,113,606,292,800,158,175,416,888,749,666,67,95,716,936,530,96,140,634,178,506,795,735,274,575,999,471,786,503,624,369,129,491,829,228,253,362,918,399,510,841,318,851,304,965,623,561,293,643,342,885,650,221,711,698,263,606,842,946,469,827,275,150,388,166,944,527,63,497,624,423,150,156,144,435,820,123,819,356,466,827,164,824,901,850,876,987,464,38,166,218,926,769,142,15,21,981,719,107,862,56,919,474,754,868,343,66,786,842,762,25,97,305,999,449,582,993,68,991,189,11,142,914,255,878,585,250,933,58,774,390,329,97,260,161,35,774,619,175,939,267,568,594,120,810,831,285,858,267,506,47,122,708,339,135,204,69,653,347,954,559,84,626,152,591,940,462,57,47,163,112,90,50,743,547,435,141,761,727,934,456,414,51,462,852,943,695,750,968,59,194,376,760,889,343,944,236,624,525,484,342,82,945,150,206,12,799,112,140,744,814,640,136,707,651,442,795,742,695,903,443,227,714,682,220,124,961,287,921,210,631,711,214,907,432,997,625,987,35,972,350,54,415,417,823,135,696,113,223,630,48,252,294,922,885,418,517,638,343,857,945", "6,617,942,636,894,851,169,406,10,852,729,1,402,737,87,69,553,711,566,833,109,878,383,920,495,766,417,123,605,215,294,570,548,986,814,713,865,556,996,717,771,352,950,385,831,226,433,151,505,637,461,878,911,541,700,178,407,161,69,180,820,740,537,127,738,361,31,608,590,479,922,642,745,36,778,38,841,93,13,0,898,967,850,312,20,836,922,975,359,111,299,743,767,422,839,718,779,636,138,965,983,741,979,911,725,443,822,520,24,803,100,999,195,851,149,94,901,179,486,950,685,330,703,857,106,277,883,39,510,238,516,839,783,605,77,660,655,200,168,42,321,794,870,157,260,540,357,706,542,899,424,164,153,177,320,541,109,486,227,811,467,192,24,974,442,594,654,795,548,316,496,292,342,717,345,14,542,753,30,938,179,198,93,873,516,494,542,63,942,565,639,202,426,142,197,562,898,855,984,946,20,214,704,585,466,731,443,356,852,78,278,480,409,666,317,779,268,865,367,357,349,337,198,658,953,270,29,316,449,458,516,274,776,258,591,789,36,282,94,950,473,473,547,763,840,228,294,131,451,424,284,427,124,479,212,615,217,788,932,767,859,641,780,419,489,964,27,830,646,606,620,421,85,245,934,694,231,306,904,865,920,493,510,169,890,829,635,765,52,195,972,922,140,966,864,727,564,120,601,119,73,771,549,180,74,680,367,3,204,815,210,736,229,623,444,63,889,835,658,462,369,618,561,132,430,717,447,104,126,29,439,356,934,335,901,115,41,771,500,427,642,197,466,268,797,989,770,330,264,406,66,562,451,806,500,84,225,282,624,375,188,604,655,528,683,195,429,156,675,269,695,631,324,524,258,742,117,171,414,882,808,826,619,957,787,984,413,977,459,390,305,533,887,908,962,987,936,709,30,348,127,654,356,714,543,116,193,390,121,219,207,635,829,522,5,851,448,627,86,71,877,277,502,790,764,196,718,310,820,566,362,568,780,706,116,943,575,153,534,27,843,756,822,218,378,224,253,160,923,836,374,108,868,494,977,960,129,676,338,327,858,604,323,722,412,264,902,370,902,69,533,653,454,655,96,110,407,624,191,441,442,107,77,58,460,418,42,994,206,476,162,965,568,527,717,104,316,763,902,339,953,18,559,756,129,832,830,555,330,896,382,118,630,907,28,486,247,364,991,301,677,258,263,906,718,133,977,175,723,958,558,87,24,882,770,557,136,898,750,29,305,51,783,523,705,210,81,238,384,233,609,722,995,942,624,765,647,545,984,660,674,200,271,807,792,704,857,375,506,400,522,218,841,759,686,359,370,247,64,687,726,108,837,438,810,122,301,521,5,307,599,142,991,594,563,696,419,502,408,822,359,471,950,746,484,784,499,268,841,499,131,518,822,270,434,712,615,878,692,783,550,525,277,605,825,486,313,68,416,667,727,166,160,665,237,108,180,309,27,175,583,84,97,438,24,375,579,942,513,227,155,654,174,93,879,571,110,168,738,888,811,981,437,545,316,340,769,942,488,259,999,197,737,684,360,495,707,992,644,396,553,557,237,962,867,868,136,584,407,35,51,871,883,521,439,54,300,232,419,242,364,774,899,334,666,942,964,921,216,466,688,889,6,247,582,371,943,87,605,924,372,250,299,651,74,896,511,594,149,103,369,935,953,274,604,921,862,330,462,208,768,234,953,841,826,533,724,403,751,209,585,207,229,807,522,22,129,781,336,559,973,263,503,61,416,480,324,641,576,844,230,511,120,793,948,14,139,665,799,487,708,908,672,564,879,526,845,622,372,130,75,697,796,324,685,968,433,950,359,171,249,683,610,580,584,521,670,669,106,212,58,204,829,23,589,206,321,872,183,689,860,694,315,893,922,438,509,488,904,816,285,575,804,346,205,233,16,317,886,452,228,568,362,870,477,32,557,901,854,898,922,373,119,906,51,668,569,41,629,734,493,821,428,819,447,729,378,80,166,320,106,88,233,217,561,648,685,597,161,506,653,847,739,432,442,483,142,777,311,605,839,973,129,216,590,181,576,932,45,326,826,340,780,106,213,170,320,345,962,692,5,431,370,448,409,386,696,643,953,946,251,250,190,441,360,784,205,89,167,240,205,174,110,104,339,847,119,332,142,942,970,330,576,288,780,858,317,639,923,726,918,275,953,436,475,377,674,940,54,351,734,345,255,680,513,136,51,441,21,698,437,368,676,125,584,406,31,894,235,600,965,666,17,341,608,927,355,583,494,709,579,785,932,762,496,416,775,81,259,718", "741,673,68,635,70,976,380,79,211,582,248,675,856,450,637,310,204,306,903,387,501,277,380,779,936,314,236,987,718,347,765,759,663,9,582,979,998,815,892,127,439,51,239,816,42,730,990,520,939,908,358,200,569,746,724,55,577,814,31,473,671,76,463,182,770,27,410,892,99,692,20,619,625,212,426,629,930,765,628,898,0,230,448,214,436,205,404,69,52,140,293,818,174,54,57,223,373,970,450,853,38,515,587,435,154,407,435,472,945,592,934,763,968,250,311,317,685,633,732,178,980,278,645,722,326,65,37,686,906,973,31,31,337,138,638,162,446,652,508,976,636,758,716,69,206,319,609,975,313,667,904,919,297,126,29,554,473,787,930,700,112,922,787,77,59,501,981,917,647,614,41,903,831,335,842,920,557,174,962,871,920,924,287,268,836,430,549,540,215,992,360,387,131,500,813,397,395,421,229,601,646,267,163,832,590,520,609,251,628,387,629,695,118,685,117,11,836,655,266,525,858,814,465,564,435,395,760,173,307,762,524,701,331,796,76,623,285,228,12,213,877,320,142,920,643,237,816,662,606,316,641,101,974,865,926,616,807,26,138,154,429,155,929,213,232,856,723,377,221,360,808,890,371,268,462,916,992,34,597,552,617,530,487,205,785,725,586,416,405,471,267,340,424,299,55,3,69,448,912,922,287,442,676,454,316,28,680,824,988,437,568,863,78,226,307,516,272,556,753,486,727,877,454,606,181,215,914,158,133,402,601,854,490,439,491,88,712,907,946,518,1000,6,59,1000,899,828,381,892,889,120,897,711,718,843,633,424,566,485,35,169,586,391,97,432,861,544,416,137,717,359,96,454,598,159,709,366,78,937,916,776,473,623,626,623,265,23,318,797,61,380,798,594,374,950,545,212,439,861,407,138,94,667,546,686,63,899,803,730,729,47,351,842,145,369,304,915,374,600,210,105,138,860,490,476,335,469,53,634,849,676,867,51,637,789,941,180,869,478,808,997,535,251,159,676,583,413,450,684,446,247,900,536,588,301,267,780,432,150,252,725,564,219,893,229,33,553,619,37,872,846,282,971,7,309,113,374,556,336,979,624,563,349,916,761,379,556,785,786,311,908,497,923,257,913,993,242,977,827,350,935,648,667,766,754,578,985,143,578,876,190,546,941,578,274,604,505,785,269,613,434,161,395,294,625,519,19,822,97,421,85,169,792,832,888,390,296,122,258,999,144,672,931,687,106,700,254,603,752,578,989,64,276,651,288,207,225,302,862,927,23,596,630,719,666,858,866,440,798,226,299,736,675,715,677,472,340,684,214,932,237,383,570,767,739,800,957,716,124,747,992,763,861,624,788,420,882,624,201,850,739,570,873,302,726,400,490,918,316,358,385,879,280,538,78,872,881,778,224,599,410,176,804,656,445,157,939,399,106,439,774,768,322,586,137,66,730,56,743,689,606,143,861,716,713,525,733,38,20,597,296,515,170,70,229,781,453,140,985,108,500,23,574,210,412,242,662,448,608,396,144,462,823,634,309,310,177,58,854,202,672,425,279,530,502,210,231,620,215,223,426,335,597,868,630,434,499,118,473,862,519,410,713,987,760,814,680,919,897,858,320,591,181,812,104,401,884,289,687,599,608,60,963,216,697,594,627,116,865,550,476,131,218,806,641,410,762,834,612,828,245,55,730,52,714,955,99,2,384,818,229,743,699,940,700,281,777,514,470,430,570,822,60,371,306,471,354,114,138,86,878,303,858,445,624,710,253,456,669,804,859,637,409,360,63,165,494,458,998,231,343,107,350,720,64,486,953,328,187,759,598,338,855,669,197,203,88,737,489,73,766,199,532,249,855,314,780,451,994,537,762,594,658,652,88,280,888,77,398,384,497,64,883,835,177,981,735,688,463,978,140,966,694,348,409,284,907,890,939,184,646,912,69,777,414,716,429,63,620,611,456,994,16,740,366,802,832,699,688,126,845,540,649,1,426,953,561,75,592,271,444,326,811,852,400,675,813,221,623,36,523,68,891,930,158,219,948,564,947,190,97,453,784,704,713,188,78,370,2,608,494,595,53,519,274,858,402,862,300,932,423,214,662,607,175,829,319,919,161,688,537,41,885,894,608,130,831,35,272,718,896,591,470,457,55,676,965,26,445,869,166,512,172,395,665,171,966,821,807,762,146,876,102,85,282,242,761,399,671,897,484,46,637,304,316,571,541,770,876,683,675,878,368,66,27,926,973,110,193,129,797,170,92,641,379,710,469,216,279,993,38", "644,703,454,557,352,223,484,962,329,265,617,259,4,369,278,933,956,160,793,649,733,858,246,726,27,539,192,735,571,858,436,474,337,979,557,824,953,211,952,365,972,923,389,986,622,847,542,315,917,466,398,769,467,185,145,462,467,690,618,892,305,280,94,446,914,624,833,124,311,108,449,352,589,608,24,538,402,747,963,967,230,0,339,598,207,37,779,627,70,531,607,536,148,572,148,317,651,421,194,436,892,602,229,654,510,833,609,549,789,481,378,204,337,396,989,361,103,237,125,501,810,715,225,58,399,499,384,883,551,601,706,37,152,79,574,497,538,492,266,455,260,555,910,686,440,736,276,860,918,520,380,659,122,674,457,423,917,354,24,175,21,969,975,880,902,773,715,198,361,816,373,132,691,25,38,545,161,504,491,180,389,812,751,557,711,143,353,974,953,625,564,210,187,110,517,182,460,910,310,969,484,963,339,950,9,560,829,352,903,851,778,998,454,588,650,818,887,311,829,88,868,673,511,640,587,92,868,858,5,613,934,121,228,664,180,782,163,403,696,881,528,770,736,920,65,265,68,363,442,846,919,616,649,907,797,674,507,269,275,840,424,591,616,984,902,291,511,979,483,767,6,348,485,37,499,921,422,53,289,732,435,194,511,188,300,121,188,310,574,803,932,370,687,566,483,566,968,372,263,632,212,640,306,305,279,540,235,287,787,215,727,891,508,995,979,444,994,31,620,75,386,7,659,281,650,112,462,4,111,947,812,298,346,254,527,145,176,186,355,830,247,615,707,626,230,492,299,496,962,47,974,728,201,522,268,550,576,344,185,570,903,405,627,165,137,759,949,614,362,861,868,529,531,507,320,738,410,852,712,680,150,788,995,277,933,43,942,862,754,634,294,363,153,123,666,464,845,205,71,409,546,745,912,422,379,318,396,442,899,696,39,9,875,638,424,24,353,302,768,929,522,182,913,799,162,230,719,462,686,296,401,690,167,769,642,366,824,317,433,506,207,830,565,794,281,350,631,581,715,467,691,248,362,339,862,306,489,624,736,170,705,818,245,922,192,718,169,944,852,786,92,33,861,85,313,354,792,337,444,877,139,958,499,723,22,939,799,783,162,461,629,117,616,563,122,310,627,111,70,296,467,105,675,228,103,972,652,473,290,266,232,554,909,877,136,584,914,264,221,141,259,952,597,658,29,824,268,154,449,606,764,475,593,681,799,161,850,194,122,24,633,153,112,861,702,354,183,119,697,944,631,248,126,287,885,189,243,818,476,478,895,188,917,315,450,790,759,273,222,830,495,455,884,620,951,656,331,14,27,898,484,523,291,170,131,827,314,630,333,112,248,878,443,884,998,671,2,738,333,770,623,951,677,887,346,493,735,783,933,528,332,483,899,471,595,631,355,461,424,12,555,355,414,566,959,617,788,695,253,48,706,277,559,119,577,657,751,869,582,232,43,430,1,349,688,814,566,120,184,351,768,257,811,985,863,580,912,29,32,219,148,351,306,11,477,603,117,434,196,643,774,66,929,906,973,759,448,161,796,694,416,36,239,173,156,178,307,405,157,133,582,308,936,532,478,762,366,377,607,425,247,645,558,317,604,913,226,127,508,119,98,358,2,486,854,80,672,326,592,288,938,487,326,351,90,179,907,667,366,894,252,882,324,204,727,565,908,101,783,876,922,280,219,111,13,701,410,113,632,797,843,725,900,266,908,587,502,451,473,613,730,107,892,357,7,328,469,628,201,854,943,809,490,218,613,371,530,232,243,276,501,91,256,740,264,861,785,546,474,777,338,650,691,194,343,989,69,626,143,649,172,1,411,370,73,961,546,189,767,161,164,571,463,572,990,833,365,714,717,583,872,359,5,920,929,397,68,438,652,484,335,571,29,557,454,164,642,335,88,907,948,490,310,685,820,625,11,879,550,720,18,391,338,623,227,870,426,679,534,809,247,998,888,494,279,961,874,900,251,842,141,356,12,220,850,415,698,20,880,293,498,705,197,903,246,990,487,222,350,771,230,585,715,174,110,913,380,226,754,358,955,66,872,628,688,973,299,121,50,505,489,433,953,227,653,906,239,333,58,895,891,283,25,35,936,9,442,713,632,152,62,513,510,971,819,701,782,253,714,334,931,614,93,60,297,314,68,283,342,75,180,858,844,494,824,864,626,255,762,593,58,24,167,809,119,852,83,792,697,45,457,26,77,261,356,174,252,252,789,337,914,747,725,272,141,477,833,505,278,963,962,901,362,68,172,393,815,604,469,592", "701,602,786,930,793,902,378,361,173,22,917,733,260,683,164,325,86,359,250,451,883,826,138,107,229,625,418,918,725,459,143,338,610,986,870,679,996,629,870,655,401,546,956,443,65,430,205,194,615,279,746,758,657,989,811,110,146,303,387,306,898,471,242,71,728,334,203,598,556,145,125,729,222,694,692,271,918,893,947,850,448,339,0,487,742,764,983,413,296,375,897,564,693,134,263,198,246,269,4,692,966,259,992,408,547,162,521,954,46,199,415,591,79,575,719,549,453,243,542,107,414,204,484,251,413,999,953,372,757,982,354,706,492,409,245,820,780,812,55,474,611,589,679,643,929,404,269,780,824,109,720,457,216,414,341,312,413,318,668,523,806,887,268,19,434,447,870,973,550,144,260,255,889,698,886,101,288,805,568,698,849,983,632,539,888,850,691,745,534,667,138,121,791,821,27,352,374,630,321,568,928,438,15,818,94,8,526,802,404,573,42,935,45,80,884,798,282,540,871,180,621,217,310,33,788,107,663,805,983,4,991,908,176,411,387,890,828,605,188,545,552,687,203,937,238,715,305,338,480,116,385,306,430,98,522,603,649,652,875,966,442,530,665,953,366,236,899,211,514,276,798,267,168,852,923,270,920,565,102,481,539,484,240,869,82,534,297,443,414,152,496,181,685,476,398,257,238,48,329,679,610,551,519,506,593,165,141,631,49,311,508,879,165,616,651,402,181,47,259,143,638,821,581,684,451,273,989,63,649,484,443,301,595,329,263,430,671,990,556,749,966,212,651,641,305,583,559,589,309,909,43,643,66,561,789,550,873,12,327,522,65,187,751,178,137,719,965,932,921,931,608,539,580,523,175,242,683,833,604,685,503,593,428,207,887,292,401,88,258,923,475,660,440,734,20,832,972,300,705,886,317,317,14,43,209,859,502,220,89,634,210,698,665,897,56,678,43,921,552,646,48,769,455,685,491,721,990,557,325,29,808,923,290,137,216,530,614,831,178,588,283,597,60,328,67,889,67,676,376,308,82,964,243,144,484,23,874,876,430,986,158,484,99,418,501,924,220,980,219,983,895,137,173,470,684,771,984,23,826,482,387,458,923,591,182,545,28,738,994,645,620,885,169,21,942,723,58,315,531,287,27,856,310,166,742,591,537,486,792,400,607,970,45,488,178,808,149,241,215,153,412,861,94,372,111,809,119,302,809,402,735,463,692,643,307,102,648,549,897,201,897,209,390,483,606,66,445,348,145,975,672,164,644,840,527,602,683,139,26,883,723,680,124,281,57,281,812,915,376,612,684,504,419,406,310,709,292,780,992,28,197,613,300,432,76,475,618,511,526,460,914,894,74,756,836,338,555,337,293,317,413,658,273,876,777,37,957,947,804,86,731,644,10,604,110,989,780,649,507,54,69,772,281,346,685,754,694,619,729,829,518,642,248,586,994,863,962,747,108,777,246,773,516,138,222,166,490,600,484,111,72,55,566,250,476,749,177,239,623,627,857,479,969,303,660,316,659,415,710,175,33,907,723,304,644,512,264,854,633,244,304,803,472,63,84,5,181,98,433,645,750,319,797,132,340,601,43,610,815,836,387,539,191,963,862,327,683,244,232,532,956,250,278,60,377,33,756,736,647,325,897,100,604,352,992,52,207,925,530,446,712,762,855,490,64,427,504,524,124,969,406,152,698,211,410,675,279,939,273,353,607,216,252,330,892,960,898,2,748,829,30,952,959,743,255,26,876,98,461,29,429,906,757,88,512,351,520,259,409,944,928,597,116,297,342,896,825,836,467,337,212,240,657,445,179,806,294,494,53,250,202,948,66,351,742,546,196,61,123,908,346,798,89,854,947,877,985,268,457,763,324,363,209,536,460,454,87,765,554,260,214,705,673,697,560,517,576,548,251,154,560,185,820,51,486,222,117,699,832,387,491,134,308,300,931,435,581,505,367,757,374,257,916,62,893,607,146,609,437,393,299,398,895,462,431,120,86,470,80,835,627,753,777,307,595,485,717,552,17,489,811,311,780,508,112,984,627,656,5,992,453,133,754,806,396,398,998,238,627,688,230,53,27,287,925,269,314,27,934,573,177,398,856,241,905,297,157,197,951,916,778,437,747,465,37,917,321,945,432,547,691,630,573,727,654,671,847,853,982,629,77,39,677,362,501,293,802,443,548,909,467,884,818,644,647,992,882,632,772,166,383,615,27,801,284,744,296,22,262,582,939,500,614,884,716,77,95,623,294,410,148,485,995,978,348,839,956,911,334,387", "782,256,497,80,354,231,977,385,393,190,301,932,205,385,524,244,616,687,285,627,707,659,664,369,799,877,659,18,322,169,496,513,557,351,364,210,244,863,490,510,737,496,670,449,313,181,931,554,522,737,348,255,663,259,360,910,514,193,557,831,191,374,423,913,195,893,120,771,166,651,277,871,699,400,716,824,735,926,870,312,214,598,487,0,814,347,391,248,410,804,476,679,394,518,637,471,786,664,574,413,591,524,910,156,244,18,389,925,21,641,157,652,281,758,607,664,289,395,807,193,722,420,84,185,704,221,429,307,677,593,506,372,403,115,408,392,778,11,378,796,515,973,314,703,377,830,50,767,426,8,225,12,123,68,208,385,9,136,575,398,527,425,956,649,765,781,118,549,370,725,396,173,354,749,744,793,834,57,468,740,433,668,537,871,123,164,373,384,869,184,219,833,781,911,509,147,959,223,821,381,649,233,998,413,873,214,656,518,792,998,803,851,423,121,24,387,290,512,681,131,134,480,726,188,778,379,804,391,102,351,737,996,942,872,865,422,116,302,942,619,114,129,407,390,288,611,876,654,340,86,18,767,873,152,812,135,646,857,744,401,178,522,41,860,650,839,687,819,754,213,462,550,772,785,857,897,470,65,988,871,824,706,466,373,986,559,629,360,822,171,294,908,992,277,232,247,783,174,387,658,560,330,748,951,130,486,434,692,849,42,498,667,976,764,383,521,683,79,853,40,900,310,775,680,192,972,40,551,718,169,666,147,186,664,527,29,924,426,634,580,530,343,469,194,858,409,160,369,710,863,966,12,838,493,89,369,360,379,942,174,486,316,49,783,96,793,991,853,442,810,114,609,540,281,7,9,638,363,368,763,191,341,546,552,452,60,63,29,540,694,273,816,609,618,830,81,568,712,648,153,213,778,961,920,147,537,804,842,280,646,502,982,225,54,124,429,834,635,600,803,814,149,324,353,578,279,919,160,527,295,419,707,820,594,958,9,566,564,909,64,243,851,497,786,46,200,893,314,104,205,953,590,184,326,562,618,91,930,934,3,30,353,104,83,941,575,342,821,687,809,522,143,422,726,23,809,800,983,987,719,52,413,640,687,683,189,505,382,535,555,500,431,361,939,838,230,545,236,587,271,192,459,857,149,84,524,348,775,754,661,204,730,881,464,800,714,818,458,415,340,793,432,335,801,204,213,989,419,372,960,200,688,179,383,410,985,164,288,230,679,732,989,99,10,738,285,91,671,39,279,611,414,43,212,661,271,740,24,973,478,976,256,919,465,190,173,667,422,449,248,224,820,1000,638,67,6,117,17,387,712,833,254,794,872,345,546,155,210,404,336,456,999,631,764,613,818,72,735,938,818,46,321,574,143,268,646,243,109,936,988,17,153,642,351,299,518,979,430,643,522,9,663,858,477,397,360,787,391,178,454,328,682,138,490,790,874,621,620,834,330,636,259,123,798,787,491,895,154,135,568,15,488,579,387,232,598,145,335,495,805,862,285,580,2,240,119,142,749,21,585,284,598,3,974,206,267,518,838,844,308,739,792,925,263,312,938,367,98,143,23,660,103,509,133,999,592,399,774,673,846,961,544,947,290,437,458,16,360,539,956,348,780,229,87,6,69,819,654,987,360,804,651,239,572,225,940,179,25,987,911,953,410,215,54,598,225,235,422,754,689,293,382,334,461,18,269,967,511,662,165,895,240,119,328,125,688,691,450,811,979,391,197,799,189,56,512,575,76,491,636,355,532,972,432,492,1,131,664,666,929,527,136,988,16,891,342,632,486,428,628,474,804,707,256,207,621,15,494,649,78,53,614,463,510,643,695,972,745,627,147,3,362,422,401,281,739,928,70,601,504,485,927,798,633,421,45,576,626,437,565,916,856,804,721,260,25,163,291,491,911,389,707,312,97,143,678,367,816,267,902,462,963,434,949,673,464,548,172,673,522,770,36,871,114,484,736,473,26,808,940,625,104,935,705,218,963,247,269,286,703,75,825,259,709,459,96,883,38,316,895,99,419,46,9,169,968,988,993,449,888,139,325,179,510,302,545,3,567,625,813,377,70,490,333,457,126,174,894,878,768,850,399,535,419,704,280,598,840,897,291,566,66,79,688,768,124,982,51,837,7,554,590,694,566,621,405,462,573,22,515,451,441,321,829,222,277,256,680,899,759,918,187,669,979,900,858,604,408,919,104,982,570,231,611,132,33,691,764,875,780,722,516,560,829,559,608,189,920,949,826,644,952,575,944,710,98,995,848,191,416", "870,997,517,595,862,910,227,671,793,134,305,89,751,492,254,45,803,576,666,727,20,272,836,208,819,111,238,369,222,208,495,217,69,4,557,388,239,411,564,463,425,508,67,219,472,909,693,915,916,671,821,889,370,256,138,160,568,580,799,264,253,415,60,538,986,32,723,776,61,190,949,940,202,760,22,624,185,934,529,20,436,207,742,814,0,557,41,734,603,383,164,529,579,951,610,703,153,651,264,727,585,487,127,223,634,205,293,725,464,241,225,809,461,968,992,639,31,686,155,147,447,276,306,952,53,490,554,460,187,840,849,356,270,386,380,309,12,582,616,847,271,493,953,28,446,520,630,114,343,309,366,305,489,724,736,317,488,107,219,94,34,500,625,333,628,951,436,494,317,457,813,536,320,540,729,849,654,889,210,56,275,677,997,620,403,612,363,813,942,620,434,762,361,974,828,695,873,253,827,493,227,404,637,237,53,7,478,69,276,284,886,635,171,672,783,396,582,303,486,506,928,612,875,334,513,313,649,510,742,368,337,948,576,329,691,238,511,686,673,370,366,992,432,810,133,524,20,741,150,275,937,380,78,876,692,509,277,367,779,454,797,775,439,965,715,534,748,390,801,540,549,53,350,480,183,4,893,404,84,689,582,930,19,980,433,740,666,104,56,472,610,992,340,756,962,8,53,58,351,518,698,511,912,696,85,411,174,645,374,733,97,539,29,994,702,879,754,789,387,80,303,165,927,770,413,147,900,320,831,254,166,692,258,499,459,778,416,694,24,611,477,143,68,16,225,474,871,933,687,347,611,118,894,830,122,459,865,267,560,628,986,947,700,110,686,636,367,501,420,635,581,228,954,624,694,329,240,741,807,549,619,74,93,125,435,358,456,815,985,589,390,760,371,142,308,531,453,216,754,912,736,696,746,517,191,271,388,689,370,1000,998,597,78,209,972,833,997,874,825,856,64,730,800,937,53,268,881,880,268,135,98,752,324,846,521,591,538,533,714,892,450,839,740,256,241,360,23,338,420,650,671,88,359,399,217,571,756,569,438,88,350,852,560,91,864,650,105,475,355,566,369,51,427,71,730,354,846,168,948,240,392,555,391,308,30,266,293,516,517,681,508,358,105,475,140,720,327,953,926,830,181,867,695,123,811,497,850,915,275,794,306,151,267,100,827,519,78,138,676,842,522,960,941,73,162,682,382,372,63,345,591,78,39,722,805,997,504,92,937,77,610,976,65,88,287,359,53,777,796,987,987,292,733,414,346,442,901,161,714,310,554,667,547,384,316,202,594,788,135,453,317,509,182,585,50,223,955,25,624,500,700,824,801,889,826,731,327,90,876,253,181,51,987,481,322,656,700,868,104,336,930,925,571,518,335,227,178,777,761,851,216,689,294,910,661,305,24,514,653,338,412,624,844,456,670,70,179,805,134,581,295,131,677,262,647,107,515,751,949,395,868,479,187,122,950,179,771,452,685,110,313,342,431,21,173,490,267,754,694,57,460,121,261,571,807,166,648,236,356,4,233,297,545,626,815,720,519,463,514,259,198,510,294,601,64,582,893,7,378,79,273,548,986,625,646,128,586,920,184,439,431,753,552,701,522,896,806,677,760,743,327,150,746,114,392,937,309,626,260,912,468,587,420,532,87,274,564,433,194,509,295,816,765,630,605,360,437,754,668,396,845,716,66,632,41,809,522,725,340,127,467,280,610,797,306,781,87,604,553,546,78,425,488,621,16,932,997,240,550,793,175,806,912,372,1,330,967,424,80,256,83,28,535,140,929,924,34,14,562,702,751,19,143,394,100,976,586,991,861,90,321,991,215,775,328,438,351,835,908,58,189,129,559,704,149,279,882,430,484,475,275,727,909,252,158,702,541,227,184,160,976,119,276,693,953,391,680,593,965,865,970,747,185,620,978,876,167,705,997,699,792,961,223,61,563,442,282,485,487,176,369,884,319,589,180,440,498,342,563,603,931,597,636,755,953,814,967,68,858,49,578,101,288,326,959,228,104,635,486,25,365,727,905,628,557,273,314,302,51,452,766,344,633,454,819,376,449,935,4,751,786,720,137,112,363,256,349,261,103,118,489,399,72,30,16,101,85,572,929,583,32,437,853,300,146,41,489,526,122,267,146,213,485,47,860,424,752,396,770,634,614,30,696,894,394,806,402,387,782,200,855,177,373,761,254,416,973,49,556,856,696,345,990,638,611,949,602,237,83,510,397,850,934,3,922,952,833,903,301,83,601,115,547,648,636,431,444,89,419,150", "947,805,255,94,234,48,914,639,509,824,250,250,300,491,56,196,55,905,433,694,726,260,680,116,946,59,928,51,250,899,683,949,129,264,881,107,866,924,739,481,70,709,640,69,942,747,618,579,142,976,91,867,524,280,870,374,390,100,67,29,860,259,657,225,869,603,521,991,351,146,957,605,107,67,1000,405,215,768,561,836,205,37,764,347,557,0,746,13,869,856,879,815,324,563,728,771,503,888,338,275,133,422,436,385,586,533,188,959,762,684,174,234,348,109,7,327,315,801,718,25,312,9,853,623,171,317,12,502,355,690,561,125,990,936,689,226,377,380,77,936,609,597,356,715,890,961,831,91,344,685,913,515,485,125,390,706,85,246,604,99,938,800,85,692,737,208,988,445,54,307,806,277,761,218,97,300,8,194,254,494,753,902,734,945,16,450,642,528,39,998,181,19,271,401,808,762,123,802,70,675,497,409,285,194,707,518,490,156,777,885,438,136,852,277,732,106,854,573,990,578,481,628,672,479,971,388,273,238,84,972,358,310,413,70,260,861,622,805,317,808,47,5,637,715,730,347,36,183,231,759,911,195,149,232,881,75,429,101,664,266,51,275,324,324,666,414,743,376,518,347,562,634,19,25,707,467,833,928,661,310,260,681,833,868,809,563,23,206,748,299,544,511,783,444,103,400,519,410,229,416,559,732,910,685,463,710,871,519,888,260,158,958,889,686,239,368,517,804,792,650,590,837,594,478,423,628,485,85,290,301,159,429,247,215,786,696,380,271,656,518,730,430,79,543,19,531,233,262,805,280,843,179,702,869,951,204,171,732,20,729,776,313,369,550,650,744,667,925,4,992,356,850,590,886,353,859,258,607,279,121,607,113,852,66,358,831,600,392,793,800,834,686,281,396,233,104,582,579,952,874,913,168,393,722,434,693,149,103,455,328,149,596,821,842,231,494,375,174,122,533,858,754,107,921,637,20,315,741,162,969,309,793,373,986,390,404,77,161,25,578,146,8,361,253,234,279,15,883,486,460,172,52,917,240,554,725,484,278,546,935,666,914,889,201,686,738,29,575,601,65,447,604,513,300,279,372,230,620,705,817,869,694,668,956,612,832,444,77,730,750,875,605,568,173,463,62,431,967,560,85,671,685,225,509,234,474,301,316,171,756,942,51,829,715,940,53,289,924,115,503,678,913,171,488,992,102,394,544,174,186,585,913,6,776,479,225,65,586,900,985,326,2,150,712,822,697,968,448,188,970,594,927,257,915,548,622,115,846,352,959,256,828,854,880,551,899,542,715,146,17,373,231,523,947,560,693,595,330,683,345,488,942,289,587,380,730,347,818,871,168,984,515,752,142,572,304,30,213,361,427,991,583,831,993,84,70,235,678,373,497,960,268,669,131,785,204,958,654,271,965,467,509,371,923,690,751,477,233,396,380,453,701,25,182,618,737,204,415,451,922,110,387,227,825,838,817,221,404,22,642,142,427,959,829,445,492,735,619,684,435,33,73,482,925,756,735,687,71,189,971,110,218,744,247,483,881,477,552,548,26,812,264,708,406,998,418,968,859,70,744,807,903,593,98,632,462,474,754,552,859,658,207,533,460,691,295,603,534,118,341,822,57,217,547,726,704,988,800,528,933,316,916,64,764,211,619,594,939,467,818,441,815,545,926,962,810,724,960,933,818,444,79,816,323,414,536,933,795,820,31,790,672,183,357,782,208,643,350,198,904,750,925,612,152,860,846,951,148,188,612,259,237,777,859,244,351,447,834,615,685,572,661,250,282,109,840,872,453,151,644,349,117,658,355,937,545,741,28,630,804,170,389,293,169,722,720,634,507,813,270,457,788,734,187,957,229,457,721,749,161,667,663,262,960,141,36,21,801,585,631,661,446,364,72,395,613,167,25,280,490,845,488,567,172,745,109,27,361,995,474,378,32,117,234,941,636,643,110,493,583,55,411,619,590,83,713,695,52,28,866,383,421,162,494,674,119,684,601,799,637,382,440,106,46,169,993,630,479,845,273,687,589,955,865,393,347,735,433,283,879,483,125,951,899,60,729,85,31,79,790,414,263,21,125,758,915,566,893,982,895,369,823,844,992,597,610,951,631,756,242,523,562,638,74,171,410,456,114,494,842,434,572,769,430,527,884,940,975,473,358,548,250,917,237,924,396,706,225,513,655,289,887,993,25,816,303,258,589,8,130,892,865,792,990,763,559,146,507,392,287,932,407,906,351,376,89,984,657,179,763,572,405,978,537,329,186,896,999,993,191", "159,922,417,675,644,531,681,703,839,608,368,531,780,299,414,69,462,598,188,916,39,606,607,113,537,637,360,589,787,615,463,914,488,190,950,151,203,11,891,928,901,892,751,990,656,484,140,450,64,754,491,25,753,732,301,113,177,968,926,999,864,524,177,789,457,38,677,346,269,838,658,502,479,752,783,65,159,303,911,922,404,779,983,391,41,746,0,1000,640,445,26,335,454,850,944,211,283,244,609,194,655,887,828,551,279,622,111,852,340,964,322,579,779,725,948,409,498,832,706,134,612,181,94,721,570,928,195,712,471,697,55,926,110,169,628,681,495,608,35,191,497,600,658,194,349,512,813,908,911,978,870,556,733,655,310,799,786,671,6,525,891,612,597,214,344,102,791,603,693,949,118,283,425,262,900,834,376,665,708,316,259,215,426,890,466,665,141,140,782,311,974,65,499,257,615,311,487,991,248,734,751,694,756,811,606,398,925,280,424,465,314,678,785,28,586,607,757,783,988,128,523,468,568,41,978,440,685,804,862,682,739,61,842,23,675,722,34,316,831,444,967,919,240,190,677,775,423,175,693,676,319,890,798,429,374,502,486,241,997,760,9,739,880,338,754,928,204,724,572,440,355,70,148,523,747,439,749,623,642,883,940,910,322,957,29,915,350,413,249,118,802,529,851,710,299,775,885,94,236,79,242,954,472,354,248,163,212,815,930,396,347,59,120,121,57,561,389,599,618,970,49,172,730,951,456,274,784,905,915,28,570,197,732,258,946,706,925,16,77,865,48,428,519,278,671,282,740,714,68,246,732,330,339,241,93,700,733,938,840,559,770,801,81,634,514,758,628,318,103,524,815,484,186,493,444,102,380,473,650,178,641,662,898,737,577,22,378,848,110,766,261,454,532,655,634,667,482,582,485,959,659,44,791,2,528,738,197,438,457,350,178,663,105,973,878,702,668,402,317,234,37,874,73,749,582,357,938,584,741,887,977,172,892,844,58,598,396,506,507,530,446,291,467,370,539,839,899,956,77,974,451,308,162,438,819,738,652,901,414,398,587,210,654,794,323,619,486,441,105,164,64,99,652,745,19,520,68,283,161,431,367,107,380,258,969,395,196,98,175,252,224,852,627,367,963,978,732,556,979,702,826,394,475,851,925,142,800,75,324,45,686,819,999,742,948,250,180,382,40,758,571,832,766,567,754,655,537,767,399,68,975,212,40,599,898,345,878,3,538,883,56,31,742,999,600,243,888,206,738,150,109,687,294,114,707,990,218,819,277,535,187,289,305,857,784,149,221,834,737,799,328,752,99,947,576,332,672,899,59,411,443,104,299,17,336,401,222,320,170,166,528,957,449,99,106,230,878,356,515,990,589,22,318,199,816,91,591,777,155,698,4,699,644,384,621,893,334,673,489,919,675,493,886,886,173,33,538,316,116,446,32,90,48,601,60,687,939,216,635,423,984,688,490,622,657,918,394,432,85,545,700,884,877,149,55,246,761,543,19,307,427,62,433,419,130,501,367,330,627,902,714,821,682,929,731,479,213,642,618,87,879,325,724,271,905,512,885,812,316,830,927,148,685,991,59,706,533,168,31,420,24,311,803,836,857,946,363,521,929,587,741,770,568,442,636,103,440,831,416,34,890,402,252,137,524,778,502,65,621,263,381,993,385,220,413,909,200,630,466,964,613,516,227,619,893,688,183,407,586,903,32,747,16,738,684,72,520,204,863,89,878,886,368,614,346,557,65,318,292,214,153,691,473,443,846,875,726,561,483,466,179,894,909,450,781,374,293,841,23,870,915,593,813,53,80,377,452,797,321,928,772,434,309,742,810,231,839,200,578,686,141,80,996,615,38,463,183,166,433,663,26,656,970,59,726,423,974,9,568,707,633,488,209,213,159,246,233,114,810,250,632,593,658,209,490,508,488,462,551,88,321,424,527,811,931,216,250,82,281,3,902,722,870,804,650,560,757,883,266,724,488,141,339,701,669,518,545,448,92,908,194,580,411,617,454,677,492,86,697,709,950,29,456,920,33,433,522,582,667,683,25,808,804,146,321,254,349,644,797,32,649,735,686,244,569,454,188,813,505,899,978,17,435,68,424,75,152,199,584,19,682,527,322,9,525,387,630,139,419,517,440,272,934,201,627,71,52,717,888,622,406,616,512,933,932,797,300,23,985,581,341,120,680,417,752,674,563,112,178,460,336,654,6,48,800,149,84,830,656,800,943,28,88,638,532,761,79,873,298,573,172,708,333,582,774,767,28,996,880,159", "464,332,518,781,180,336,70,192,152,952,491,728,861,906,615,374,526,694,760,473,590,627,124,877,504,929,824,281,600,522,49,682,336,12,382,436,723,314,50,350,151,44,59,606,175,314,524,146,692,190,707,982,228,46,672,768,4,782,332,763,652,635,566,357,253,414,28,21,859,706,827,310,392,403,283,622,60,683,739,975,69,627,413,248,734,13,1000,0,865,273,347,460,77,449,519,11,291,187,46,455,742,425,387,426,912,666,274,793,580,830,847,214,342,769,820,661,156,321,473,79,25,995,376,585,491,481,95,255,202,438,433,642,501,295,217,810,834,466,380,490,658,706,242,241,891,391,7,947,405,461,225,927,37,385,126,54,643,546,280,611,681,160,191,480,682,520,436,293,321,431,646,962,40,18,32,155,471,867,129,117,46,60,326,585,627,752,368,436,965,379,620,896,118,40,974,908,963,389,800,952,939,515,864,895,667,669,559,187,458,953,19,581,264,983,984,349,959,805,353,613,64,291,283,18,632,257,859,595,600,678,274,570,331,147,825,627,218,704,478,851,686,345,42,398,134,80,230,680,382,515,904,584,844,821,723,890,147,802,239,668,680,255,34,562,148,147,521,435,611,355,775,683,708,140,535,934,778,699,274,722,638,622,683,274,622,850,203,94,344,946,334,542,714,887,451,356,513,787,78,442,667,373,333,480,944,848,640,471,632,228,48,348,480,585,418,768,892,278,380,856,580,360,928,893,342,994,718,861,3,913,33,617,355,722,692,262,749,390,11,510,78,869,171,327,867,238,344,260,853,548,573,288,886,184,105,321,206,675,742,630,944,378,796,799,402,867,771,546,625,119,110,315,3,914,654,880,742,999,866,75,899,357,645,680,108,47,534,678,531,173,76,602,372,978,444,112,802,242,768,321,361,287,105,737,445,459,314,824,357,291,130,11,900,237,929,465,926,119,123,735,954,449,756,290,595,112,421,160,792,887,396,285,811,24,494,470,387,56,200,585,422,893,974,432,692,287,879,343,33,1,212,204,975,94,353,806,903,625,289,2,974,366,139,870,586,880,625,874,835,597,717,198,480,324,664,21,616,388,307,85,862,917,807,958,168,844,836,817,441,291,714,594,972,293,516,919,137,205,652,601,742,798,691,784,864,3,850,219,767,326,568,784,718,856,213,280,167,639,817,136,734,355,34,736,380,915,915,508,749,40,252,489,670,954,458,148,592,581,795,676,211,410,481,850,538,242,407,950,944,938,539,365,476,706,447,775,681,853,728,618,280,634,792,515,112,624,389,55,782,602,73,74,343,699,389,326,575,550,776,94,149,829,949,173,648,682,956,27,603,797,352,147,850,82,980,44,977,248,343,879,558,989,263,105,189,752,190,550,901,999,496,80,340,867,999,215,617,969,47,672,709,654,99,822,721,527,548,766,326,988,376,853,422,526,950,812,74,739,804,262,328,131,866,751,325,33,878,736,314,942,562,386,585,59,640,151,981,177,469,81,308,660,187,647,190,49,936,984,91,208,155,892,103,351,387,494,823,508,408,590,531,696,261,647,364,579,662,619,419,516,422,697,960,700,547,466,644,931,910,295,961,447,510,76,109,513,9,20,678,476,863,574,829,740,135,510,599,650,448,562,727,840,559,470,470,350,934,692,896,499,926,528,280,996,736,507,707,510,113,150,68,207,288,444,626,239,572,574,72,972,327,126,541,722,724,501,948,352,26,881,739,837,698,674,716,920,365,930,413,124,752,857,249,945,928,543,267,913,287,958,860,824,46,672,109,921,79,526,827,696,762,832,326,130,472,802,72,342,980,616,621,261,114,710,347,6,957,724,234,62,139,150,973,975,207,733,765,843,223,369,351,685,797,729,847,501,971,661,13,880,916,974,758,728,761,107,922,943,546,35,283,588,14,777,144,664,369,483,94,464,214,182,257,446,34,16,809,20,281,812,737,505,500,47,347,504,237,687,903,1,559,541,748,552,21,6,673,399,515,610,43,207,726,934,502,276,808,630,587,691,132,429,424,984,581,865,748,812,270,838,208,662,855,443,545,85,406,197,799,997,681,575,525,717,832,914,689,744,164,92,440,785,553,888,373,16,483,847,88,628,177,259,134,581,347,151,630,453,427,110,42,41,296,92,718,715,613,696,278,920,461,533,333,474,454,655,784,760,783,20,180,345,15,465,758,293,822,716,4,487,898,83,339,398,565,740,265,119,802,442,203,731,767,395,680,774,32,253,786,974,664,650,783,251,183,250,593,112,459,679", "412,116,417,143,361,936,970,930,287,465,354,444,242,31,330,264,701,529,297,544,303,532,624,36,789,336,133,357,606,322,574,736,920,482,499,977,649,622,532,52,837,666,810,903,217,293,813,852,7,725,481,191,668,377,109,315,636,520,918,361,188,97,584,728,698,588,567,817,142,813,116,203,570,455,753,827,716,174,137,359,52,70,296,410,603,869,640,865,0,67,85,37,385,208,26,633,138,113,817,670,650,808,663,434,194,448,614,770,258,273,209,807,214,345,767,773,167,876,887,790,317,432,456,387,43,974,629,652,105,532,479,197,101,126,989,324,523,180,588,644,202,666,102,156,536,833,246,618,58,490,216,719,673,841,974,981,77,874,306,390,840,189,696,535,84,341,723,849,142,957,270,509,404,699,395,309,587,218,520,857,173,744,99,23,415,648,232,904,455,204,922,329,919,631,917,474,881,575,150,843,102,544,154,927,98,893,92,684,738,589,766,680,422,137,277,192,362,51,249,212,909,272,843,44,539,944,93,832,740,933,483,501,316,10,863,380,798,641,925,354,298,181,533,566,366,333,290,448,590,287,650,545,685,198,252,555,952,175,622,704,379,623,86,179,356,783,284,123,177,829,666,396,814,775,611,544,913,550,775,191,1,96,322,956,334,469,906,465,85,659,119,333,673,31,27,959,590,505,171,663,319,306,764,9,84,647,760,33,392,359,942,790,42,640,622,99,897,919,197,384,996,181,20,351,429,554,925,348,514,149,540,393,786,221,969,157,533,711,380,48,665,765,48,468,166,352,506,204,730,383,35,575,326,123,576,318,174,544,901,619,32,3,948,890,206,520,319,902,278,733,155,895,392,904,847,276,740,127,333,157,624,154,273,865,76,837,689,796,74,869,16,436,792,584,486,278,563,888,683,804,856,717,993,509,736,50,783,562,81,921,743,636,116,781,19,905,328,600,420,414,255,226,165,106,495,36,831,560,414,837,710,729,798,229,580,62,169,538,934,40,201,718,977,741,142,990,423,394,162,634,205,31,755,478,885,110,580,642,61,165,234,755,370,587,843,993,49,387,708,626,146,30,89,617,771,122,38,692,388,881,621,70,212,189,272,977,510,625,485,768,806,832,894,781,354,277,277,913,768,230,798,758,213,885,523,459,511,985,665,427,88,972,751,279,786,277,55,461,798,103,916,989,420,926,999,859,631,843,450,519,774,460,479,538,277,541,214,266,173,388,337,701,864,868,544,886,272,629,683,288,787,863,354,560,72,968,943,962,1000,326,375,246,96,385,423,14,178,39,811,409,329,496,319,482,529,503,375,48,488,41,591,516,778,628,571,563,50,726,280,633,413,878,59,30,891,753,975,442,645,914,939,562,700,273,124,269,2,730,494,727,261,167,202,403,510,148,263,55,334,813,346,588,154,562,720,935,668,107,535,965,19,682,417,280,298,17,721,384,826,479,239,770,76,120,412,138,306,99,262,244,529,184,78,783,250,836,734,178,939,582,618,223,15,178,606,836,506,653,392,519,388,912,400,714,694,649,343,228,210,298,366,343,554,868,925,324,480,352,592,203,688,519,116,57,607,279,364,556,420,187,734,413,168,560,190,260,134,517,453,495,195,483,496,475,99,151,615,460,127,150,679,466,983,349,135,498,180,61,13,836,907,552,399,908,777,708,142,353,390,500,409,358,556,441,710,923,839,363,484,68,788,766,442,875,77,334,347,372,156,738,903,957,151,37,385,170,292,31,297,488,328,161,356,827,511,980,997,910,815,895,385,345,216,942,709,950,424,726,683,214,868,813,799,729,86,852,110,115,436,50,500,617,371,345,254,487,800,590,628,723,302,118,865,37,200,913,377,119,935,846,670,819,976,206,214,721,374,979,775,746,217,685,757,180,453,662,546,623,749,299,159,320,52,533,956,848,927,467,283,758,286,803,725,588,715,336,564,567,926,109,457,495,93,508,133,392,970,769,546,339,468,241,109,824,439,855,996,32,853,33,164,191,904,881,157,742,714,922,733,233,553,94,173,490,853,364,567,199,120,599,36,461,341,877,834,353,384,546,279,25,885,141,369,586,892,825,737,343,632,84,630,803,488,503,313,596,977,54,509,596,977,426,752,109,136,649,478,693,940,290,471,654,598,878,515,51,744,5,211,948,248,327,185,446,393,291,449,169,492,732,846,621,717,241,814,320,864,616,766,597,708,874,573,516,530,276,221,50,913,285,322,496,192,182,64,673,594,319,745,933,901,715,537,522,729,226,416,218,284,468", "807,639,523,384,702,64,789,605,549,637,760,924,36,551,50,613,599,391,268,67,516,654,19,63,534,844,127,637,51,9,516,813,66,571,578,379,281,566,857,800,763,464,1000,788,421,88,808,833,564,576,765,359,354,620,702,491,26,223,585,632,85,241,830,51,536,33,924,628,860,169,78,332,575,793,638,786,475,686,529,111,140,531,375,804,383,856,445,273,67,0,442,147,977,649,230,187,505,727,302,991,432,986,946,397,83,839,598,202,723,824,448,88,490,375,9,4,804,6,914,77,465,983,909,333,830,101,987,999,79,324,44,38,56,473,966,221,374,909,682,734,681,739,985,249,418,224,440,217,274,977,287,830,977,352,372,293,662,30,735,479,234,113,933,712,689,147,709,515,194,925,961,725,271,227,231,834,157,684,795,812,328,943,911,114,303,641,893,740,539,508,700,526,805,459,696,827,987,470,647,141,985,609,644,455,372,540,148,732,38,300,76,647,758,713,977,984,482,809,664,495,423,653,644,935,939,889,228,991,835,688,679,345,124,205,803,81,262,921,642,997,168,427,717,110,99,12,12,481,64,10,417,345,840,50,186,627,18,667,628,245,424,898,894,606,767,823,804,980,551,936,29,110,60,187,985,818,727,206,496,926,615,515,41,261,616,273,374,916,994,124,151,635,285,749,733,487,639,654,591,294,232,204,379,639,427,135,23,251,719,185,840,691,686,693,504,387,253,933,997,842,157,943,66,140,644,824,744,102,750,438,431,362,503,806,663,706,783,577,813,703,921,511,714,414,156,393,84,430,520,610,238,67,752,958,633,9,178,425,993,711,719,970,513,858,721,390,133,180,908,52,782,815,343,328,17,412,922,806,614,157,855,779,474,88,65,385,387,696,191,737,997,758,848,441,942,579,525,333,778,325,101,339,106,197,673,413,69,149,327,745,710,152,987,854,214,200,942,186,866,959,776,339,499,782,284,121,107,107,591,68,28,385,483,766,245,539,590,180,768,811,779,699,909,295,727,31,31,272,424,28,281,59,730,763,642,838,152,845,874,476,216,339,640,94,579,356,576,315,686,679,841,819,758,568,25,766,595,882,802,421,18,939,719,939,485,705,133,463,574,650,503,719,514,767,859,973,214,416,319,922,285,516,557,410,657,867,233,839,859,638,735,492,851,583,103,182,604,417,615,758,871,622,898,278,303,171,713,209,255,594,320,55,258,512,814,80,282,603,977,320,147,372,629,639,607,15,75,901,35,861,813,718,343,850,400,207,848,665,110,677,326,700,192,546,998,678,418,596,337,944,584,159,68,580,642,925,545,998,565,289,503,202,589,853,669,556,728,880,631,851,295,974,997,857,51,918,390,200,214,653,931,520,222,554,39,357,704,275,149,435,851,696,305,86,789,238,372,306,287,408,260,986,879,336,157,754,968,601,636,579,850,971,72,239,43,649,412,588,365,818,459,911,409,267,910,690,657,793,980,349,577,792,257,449,825,154,943,901,18,745,367,57,738,933,768,67,383,723,282,66,71,687,342,208,251,548,401,107,147,582,901,115,128,829,908,207,688,518,385,732,684,742,847,218,480,875,929,190,254,389,365,763,222,23,243,115,669,782,192,317,96,828,258,47,227,386,257,256,523,66,997,108,923,860,447,217,750,433,629,461,59,248,140,314,734,801,513,111,217,326,486,428,90,923,776,379,997,481,24,192,351,950,374,982,232,153,199,118,983,418,69,360,881,374,697,856,358,365,608,223,504,683,723,578,81,823,318,490,183,954,565,319,468,951,565,855,429,887,629,718,581,106,480,717,394,898,358,419,297,542,729,998,16,648,17,747,967,65,575,376,695,836,669,602,682,570,834,198,134,37,712,953,180,413,75,399,535,756,690,191,501,784,105,671,439,827,511,35,637,994,635,612,836,664,750,14,897,170,949,878,79,621,594,280,329,350,778,202,637,518,375,301,341,728,896,876,271,762,758,760,486,519,730,106,350,974,790,761,728,864,659,846,983,434,732,340,976,686,157,221,781,219,96,287,381,748,841,519,338,557,748,989,240,129,781,239,861,146,97,598,313,294,437,962,809,971,538,582,683,445,804,630,491,722,76,871,808,509,728,670,441,274,812,891,498,440,143,511,97,350,644,887,937,821,523,217,30,208,34,358,619,346,411,282,188,195,114,451,938,555,987,347,908,836,227,954,193,298,479,813,766,109,313,490,39,877,732,454,738,391,124,599,364,641,269,443,323,787,868,972,288,207,241,798,276,420,727,40,628,640", "765,333,896,363,792,421,910,515,202,875,119,356,508,157,373,748,883,686,318,930,457,119,911,136,434,653,584,359,898,663,610,467,463,183,939,701,749,267,342,134,490,693,851,753,684,145,204,731,438,536,919,8,939,978,864,228,780,241,473,201,573,677,849,758,710,126,439,631,475,118,577,39,530,63,813,978,886,133,353,299,293,607,897,476,164,879,26,347,85,442,0,929,376,392,925,13,438,150,507,742,513,151,798,81,984,197,578,445,393,945,658,896,841,904,145,64,179,211,351,665,704,643,147,560,761,639,63,46,981,298,463,24,374,567,135,903,831,485,662,711,686,194,809,979,301,87,500,673,719,660,177,498,469,718,124,987,138,322,780,663,664,743,968,663,954,654,704,367,905,883,106,915,953,990,589,641,289,479,58,248,592,267,239,469,390,769,769,288,825,550,674,352,246,237,218,989,897,991,500,95,840,886,142,781,976,486,666,308,622,48,3,77,479,881,779,409,707,462,886,806,261,216,166,295,257,883,402,301,204,17,157,369,162,905,457,115,70,891,563,905,767,235,226,639,381,188,961,886,335,911,289,963,240,611,152,593,178,32,634,253,281,97,47,611,407,634,340,63,29,349,318,832,704,456,573,806,507,732,917,670,249,376,813,824,378,998,74,956,578,981,403,983,466,553,34,190,458,92,631,366,908,703,703,200,925,814,81,500,873,549,935,792,134,336,207,865,314,866,842,843,868,328,551,462,702,206,28,133,859,697,447,391,504,835,729,374,689,86,114,366,214,492,561,733,599,981,248,728,190,334,504,504,934,991,780,934,667,972,291,522,73,215,807,837,464,684,285,961,808,771,249,36,607,861,465,43,7,523,404,840,948,978,169,306,873,304,96,81,463,104,168,549,498,847,406,888,39,969,338,277,883,530,723,394,100,152,610,132,517,428,588,770,650,88,29,491,306,611,448,616,456,636,282,691,470,947,116,813,384,209,396,434,618,29,271,240,71,108,577,300,231,372,853,8,416,831,120,564,412,829,734,44,602,655,842,664,125,754,944,56,96,235,226,121,439,410,663,456,175,112,934,977,717,844,341,158,589,275,75,89,540,976,677,184,188,256,460,728,480,964,408,215,178,309,631,977,208,24,69,821,125,715,924,968,347,829,505,581,129,290,177,852,440,388,140,440,738,354,6,42,882,706,2,393,348,128,706,721,620,912,518,839,938,650,689,853,33,468,436,568,53,787,648,427,897,319,506,728,826,242,131,246,51,454,305,982,383,356,155,699,394,707,198,468,546,114,673,798,858,34,244,486,70,696,455,258,444,451,27,715,33,397,698,108,734,15,565,345,512,134,637,947,271,238,265,249,42,294,9,90,827,388,567,490,559,481,280,422,938,370,803,732,140,763,300,659,927,766,524,497,970,823,109,350,967,490,224,378,85,913,295,282,981,320,588,968,40,513,699,788,886,359,529,39,585,202,978,163,504,61,226,578,945,926,732,140,572,487,679,398,233,346,540,415,618,523,254,373,721,907,91,507,861,511,796,539,117,793,576,926,74,963,622,302,716,295,530,270,221,76,372,567,848,138,872,5,771,732,593,910,501,947,637,524,239,636,408,205,27,383,252,431,37,311,628,433,28,624,943,119,722,968,166,106,954,656,393,655,939,946,691,602,971,845,846,92,118,137,967,995,589,542,973,165,982,877,68,398,497,908,149,204,408,652,61,700,713,13,984,330,557,445,123,398,620,594,54,730,948,902,831,429,831,196,325,159,984,287,142,58,84,155,342,998,836,737,476,962,612,921,402,377,807,543,806,731,328,993,100,733,549,413,930,108,889,323,902,322,774,838,539,131,408,653,114,324,60,815,758,60,815,550,857,638,602,464,704,614,302,821,76,357,587,919,855,60,577,706,460,79,429,724,940,634,344,599,613,582,802,80,327,465,913,128,373,998,866,428,360,814,152,691,426,79,285,308,9,567,609,901,549,136,546,330,242,842,964,560,875,397,367,289,459,91,826,230,638,217,515,903,142,543,821,731,844,64,417,410,59,641,842,378,977,19,401,144,327,932,17,255,464,770,88,487,121,140,2,312,945,54,204,738,861,466,467,803,419,402,361,902,300,48,734,656,295,158,876,959,404,788,339,158,113,175,175,564,297,721,666,356,130,393,118,229,484,744,574,484,734,169,668,323,484,709,356,938,33,746,509,71,479,310,626,854,129,328,398,311,244,90,436,712,347,857,370,751,509,51,119,7,37,115,459,426,214,880,506,711,498,82", "174,384,784,838,312,685,187,398,741,648,984,253,58,957,616,66,75,503,403,143,206,843,747,148,818,503,722,294,594,351,266,541,93,857,193,759,77,49,273,649,232,191,592,132,642,787,704,701,636,503,488,707,477,557,175,697,462,438,673,213,33,866,879,732,600,437,754,866,325,565,901,767,3,950,38,835,664,486,40,743,818,536,564,679,529,815,335,460,37,147,929,0,457,538,364,395,890,820,290,466,187,17,448,822,359,638,867,266,606,175,88,392,655,899,659,516,503,959,560,697,835,697,760,916,841,691,315,676,17,830,722,918,683,610,298,560,609,924,647,556,932,528,923,472,66,739,87,363,794,210,586,706,560,315,605,9,144,13,44,328,492,546,334,57,601,670,468,252,234,918,816,680,363,365,636,376,175,979,432,906,273,525,197,933,675,506,149,770,636,905,908,259,818,820,750,270,343,547,380,621,574,304,472,709,287,521,380,870,756,969,679,460,999,133,234,169,975,211,762,851,326,770,413,770,308,751,423,196,881,810,394,571,495,930,780,499,216,648,124,209,702,216,433,276,330,765,944,68,598,763,248,839,596,627,249,311,519,367,966,471,284,228,619,313,713,741,334,586,654,886,712,276,467,763,628,191,600,53,61,582,397,653,615,638,591,408,463,539,13,335,918,11,895,448,486,134,382,123,183,976,658,59,573,509,963,362,292,164,581,39,207,791,741,308,144,157,705,770,261,646,113,82,555,163,600,198,802,137,661,947,927,799,976,310,664,162,243,281,948,362,569,403,887,402,705,43,357,223,278,683,609,814,608,256,815,496,545,612,369,526,791,804,256,888,119,936,157,133,829,11,201,872,378,381,716,561,393,270,531,51,813,711,946,940,458,241,131,148,164,521,980,892,319,492,591,65,797,582,293,659,501,63,75,752,355,70,713,902,417,147,520,556,547,898,830,370,525,735,85,382,827,215,616,268,822,206,702,573,500,686,360,607,258,323,708,914,207,857,595,95,417,787,277,726,367,56,323,678,658,282,777,428,45,889,353,262,699,680,685,858,186,394,769,156,457,883,578,161,148,196,93,971,524,805,687,539,575,828,809,797,430,408,122,614,635,57,336,315,545,169,346,780,45,391,521,902,442,475,307,111,300,688,4,646,164,935,763,583,372,914,143,939,616,880,390,488,401,158,601,860,116,795,508,337,308,850,329,551,322,162,410,824,255,395,299,368,838,172,47,191,426,127,159,205,329,481,181,130,354,815,298,174,175,962,410,116,286,398,463,540,294,646,470,224,934,312,884,509,456,32,713,574,820,676,907,553,716,866,901,297,945,642,882,245,303,567,559,247,159,690,939,23,219,975,641,703,587,618,84,728,304,230,995,549,613,324,346,877,364,135,487,230,155,83,206,480,787,499,716,559,936,64,798,117,63,199,113,914,863,296,254,616,67,266,194,737,619,135,192,429,38,801,462,553,216,693,388,627,84,760,473,492,552,100,384,830,675,448,488,956,690,117,796,35,510,428,978,193,765,640,441,780,52,528,282,563,62,377,400,85,776,12,85,69,222,525,762,74,371,462,929,724,915,83,552,828,903,36,824,555,472,84,439,766,404,30,23,774,947,945,598,8,477,840,489,573,769,832,791,679,977,381,711,367,124,16,284,162,51,362,404,378,894,587,690,844,555,7,7,30,873,768,501,572,802,715,496,325,169,418,534,131,919,915,866,719,154,101,124,652,746,138,595,663,573,947,727,281,30,859,159,862,878,503,668,553,225,710,758,410,301,785,236,601,329,274,758,325,795,63,317,635,502,326,813,333,21,46,58,109,303,270,130,708,460,291,900,803,770,349,1000,477,48,754,527,336,74,217,637,126,879,414,939,366,476,204,824,200,969,248,720,439,46,771,647,426,56,954,126,716,311,308,306,592,640,437,294,194,288,67,983,299,409,199,448,713,59,302,594,546,139,326,515,693,323,211,175,254,169,859,352,767,299,222,334,177,758,356,703,656,450,194,882,935,410,504,686,305,766,688,716,639,225,311,919,800,256,655,400,573,986,457,534,943,734,111,624,311,947,223,496,549,622,506,778,112,825,615,67,620,736,478,197,972,848,66,211,923,578,754,322,776,708,159,399,359,890,313,848,19,177,501,565,23,589,654,42,67,490,125,639,264,474,141,455,57,98,869,349,544,352,435,78,489,606,768,135,106,7,808,701,877,100,849,780,744,546,272,410,124,68,45,626,370,546,560,598,426,132,29,414,239,623,849,755,47,929,800,131,205", "334,526,55,109,448,890,914,40,557,756,940,864,527,995,659,299,572,55,663,551,368,918,889,977,323,732,992,996,843,174,751,248,195,739,433,568,990,538,13,619,140,79,670,756,336,829,685,168,305,441,5,712,394,766,15,168,759,148,690,153,521,824,659,22,594,142,263,240,86,684,428,137,128,911,171,338,422,78,435,767,174,148,693,394,579,324,454,77,385,977,376,457,0,693,190,634,39,976,180,34,605,814,358,905,154,120,907,631,663,201,729,514,224,750,265,447,995,366,420,993,193,878,528,800,336,635,871,241,462,731,636,777,63,918,841,433,559,352,698,474,774,159,911,323,607,427,670,801,832,487,893,679,538,31,557,739,658,147,995,555,985,15,701,250,226,548,861,677,300,215,64,505,759,541,220,321,786,112,48,696,8,199,442,159,809,964,535,212,464,972,708,136,986,390,683,112,939,2,947,942,654,329,542,316,998,240,48,907,32,542,175,391,37,267,965,918,179,806,417,754,725,478,679,43,866,664,404,219,862,233,988,548,200,18,917,787,918,825,650,235,865,842,215,479,13,72,503,595,687,927,114,302,559,597,849,842,356,690,160,755,545,154,192,799,258,532,675,604,174,293,983,397,56,299,134,499,893,661,998,287,201,557,894,558,603,438,216,512,79,607,63,478,948,767,746,724,445,471,474,514,139,737,215,125,507,923,787,250,681,177,108,556,606,218,945,961,621,30,736,278,882,448,186,242,526,790,50,267,215,714,415,609,705,269,282,551,818,298,839,857,516,949,703,112,358,763,380,160,959,110,951,736,456,948,851,433,756,157,285,706,839,294,159,313,556,470,732,715,785,146,49,913,218,721,318,594,384,144,571,422,136,966,733,594,204,714,187,993,755,340,989,541,430,465,890,561,210,383,214,738,740,508,404,990,155,144,900,225,301,894,642,328,424,889,970,95,47,256,408,716,348,295,310,183,17,995,283,106,603,890,695,178,358,365,434,244,579,688,379,698,877,977,145,470,31,337,938,747,232,164,198,868,909,960,941,313,901,895,790,429,507,518,290,354,77,530,706,89,992,813,852,18,976,336,722,276,897,728,867,973,77,643,300,682,615,749,175,982,111,437,17,587,165,645,668,86,507,992,524,473,317,999,466,607,749,475,522,186,560,383,442,443,325,571,89,438,137,533,426,57,357,434,697,95,859,488,184,885,889,486,52,900,730,232,502,995,994,628,431,515,946,290,540,919,195,929,966,921,143,181,118,427,817,277,694,680,801,463,889,94,412,760,335,104,56,905,614,822,376,460,668,937,761,751,450,908,361,341,415,929,503,994,391,196,11,44,467,574,568,256,405,878,876,518,309,562,488,428,409,993,281,747,713,531,277,169,137,903,618,206,806,837,955,796,200,826,328,475,89,814,110,542,773,145,318,541,224,261,225,922,506,876,2,355,831,482,156,252,696,442,993,933,652,670,896,314,131,11,758,91,704,607,60,836,86,482,18,131,555,557,226,47,582,986,874,814,660,502,605,497,214,114,472,472,207,256,673,876,60,973,683,677,159,456,94,657,486,449,478,587,363,471,303,370,827,811,108,878,589,440,420,22,263,116,301,25,379,594,427,178,579,739,972,540,934,51,117,756,980,419,939,65,4,424,552,123,49,381,280,434,351,425,671,679,867,217,337,691,326,922,559,976,742,341,952,712,307,637,689,109,487,620,898,46,707,58,388,69,779,570,318,328,898,691,888,538,583,478,207,428,959,823,777,771,657,565,891,366,891,959,615,804,243,627,626,178,184,226,735,3,543,391,704,750,54,569,303,88,58,689,831,141,91,569,278,648,94,530,19,118,632,931,921,908,16,995,664,27,555,989,559,765,161,856,388,280,543,95,303,644,54,266,196,353,571,764,549,332,902,241,436,172,93,568,733,558,324,549,157,49,630,857,93,947,771,991,634,94,518,771,340,701,757,428,608,846,694,459,880,275,760,853,709,671,592,874,985,452,268,187,944,520,419,578,123,277,294,965,771,732,671,757,169,700,142,922,852,406,486,874,956,729,570,788,392,116,165,90,856,653,605,843,800,234,646,2,148,400,372,733,813,654,499,53,771,259,443,969,638,575,878,5,274,81,264,483,3,557,447,991,113,388,232,172,313,217,575,90,346,124,511,902,264,394,445,892,843,395,602,274,360,923,619,225,27,183,90,803,169,348,514,519,485,993,175,106,317,436,869,797,926,81,692,800,196,815,884,522,888,964,181,585,819,969,886,101,569,8,204,520", "77,980,673,41,312,581,381,15,931,91,302,245,966,608,986,484,571,934,268,906,152,462,747,282,600,866,108,953,917,547,672,29,681,527,187,457,905,922,282,981,518,536,790,582,912,321,599,826,23,352,641,178,828,803,782,431,33,434,673,805,341,905,451,89,966,337,437,494,393,374,540,432,717,677,438,595,425,892,322,422,54,572,134,518,951,563,850,449,208,649,392,538,693,0,197,186,781,479,786,953,220,763,356,880,847,695,518,473,803,202,120,692,461,701,957,39,311,31,597,366,127,331,880,761,183,238,600,919,682,254,11,112,965,294,586,541,94,627,988,992,868,195,574,996,175,949,867,287,76,976,773,269,507,986,420,508,756,869,275,499,562,344,62,353,124,285,440,304,455,573,674,52,64,692,373,340,766,198,764,574,525,785,648,688,453,551,265,665,739,832,915,715,281,278,804,472,822,45,176,431,717,314,276,3,984,173,449,741,890,368,324,901,458,345,462,919,513,575,496,827,526,413,382,378,971,392,16,79,194,246,214,256,217,89,965,124,57,717,215,63,225,261,307,487,953,414,715,206,667,526,803,366,212,539,177,607,297,944,29,78,641,895,193,917,825,824,264,902,292,839,379,624,872,949,487,253,838,411,938,722,109,242,613,63,313,739,526,341,236,851,428,534,562,124,537,369,650,313,165,152,873,684,27,984,367,695,233,562,185,307,540,938,945,32,201,482,948,67,352,896,395,667,809,125,22,572,794,711,71,678,291,469,939,262,125,147,773,527,263,649,743,2,576,125,173,830,241,912,948,95,208,652,86,227,552,685,299,216,732,678,789,219,973,379,123,457,40,488,387,307,222,430,253,503,68,605,141,862,311,701,740,163,982,325,911,257,198,537,416,12,815,193,921,736,273,173,551,76,129,844,793,291,811,70,123,16,630,503,474,698,851,19,76,96,977,222,461,181,249,291,379,153,423,360,265,762,424,596,862,710,109,404,858,410,666,486,670,75,529,167,556,349,562,150,274,907,365,612,555,666,936,134,282,955,504,570,26,679,200,845,668,512,580,270,958,32,399,124,383,986,412,959,930,220,669,510,237,456,764,363,173,180,280,248,271,385,271,336,948,454,842,372,332,45,163,265,706,941,706,526,462,522,7,363,802,791,615,477,352,641,816,120,397,55,846,374,426,747,935,822,431,658,75,236,122,846,844,669,29,813,627,320,387,55,350,487,721,938,427,706,147,932,775,34,418,12,963,97,277,905,435,337,775,956,760,700,358,230,169,547,368,276,845,576,560,311,978,688,965,337,806,385,415,615,994,867,526,635,698,446,197,743,566,382,789,533,653,817,638,805,413,236,66,73,531,322,337,967,304,130,413,400,836,248,462,818,491,514,266,323,916,445,355,665,686,464,28,643,110,641,727,640,8,409,572,797,791,995,329,233,119,531,908,836,34,784,343,108,928,864,954,802,138,636,436,823,834,333,812,568,616,41,329,419,371,439,47,804,336,88,929,101,288,218,914,434,274,192,445,761,108,107,856,856,498,243,444,463,84,798,704,757,565,771,859,578,286,138,784,590,917,822,498,919,61,844,944,729,934,894,731,433,956,814,228,117,656,114,514,528,573,226,195,378,86,746,565,83,432,801,879,344,492,18,223,163,995,315,124,498,25,433,710,736,477,500,558,628,981,263,797,962,76,788,944,531,842,316,431,531,324,345,750,25,500,425,360,889,479,495,76,912,205,660,514,558,123,506,968,455,869,512,950,793,691,243,518,142,932,748,100,161,845,708,885,826,338,683,932,31,563,697,269,726,527,693,706,662,15,808,927,295,970,777,865,339,352,548,567,151,288,507,443,996,748,843,54,591,326,79,275,614,328,754,128,854,136,782,726,18,184,590,44,998,793,275,669,235,17,308,782,237,300,219,917,962,546,566,550,862,110,443,115,365,219,698,181,710,103,166,385,221,834,218,101,411,824,69,120,951,870,591,834,131,863,62,676,16,560,474,957,106,727,200,462,77,149,711,975,591,825,258,959,152,244,32,908,703,447,566,310,577,568,248,415,860,656,865,402,686,407,591,860,624,435,316,724,191,675,674,12,176,743,413,725,665,565,760,80,209,583,236,693,213,756,434,449,884,298,932,677,406,770,151,433,432,416,634,40,629,570,13,600,300,58,985,879,109,629,320,174,444,284,176,168,540,386,387,66,660,573,61,440,438,835,974,724,444,875,760,881,861,28,110,922,631,822,424,655,381,806,65,212,148,295,936,239,533,29,91", "930,764,417,294,410,899,999,193,904,38,476,829,612,806,328,672,325,24,45,222,612,552,704,753,182,832,382,117,789,524,385,14,866,56,997,440,16,572,684,365,706,635,230,918,475,109,528,204,157,670,215,607,808,629,801,511,295,612,873,974,275,667,334,820,967,40,888,698,89,720,851,284,293,315,266,929,744,504,780,839,57,148,263,637,610,728,944,519,26,230,925,364,190,197,0,421,934,583,210,353,616,31,760,879,525,329,272,499,416,569,94,224,253,512,102,264,865,705,837,607,591,828,100,516,323,166,448,137,130,777,403,14,450,143,61,550,235,818,26,745,742,115,443,4,697,703,369,109,733,707,527,868,632,724,443,662,311,277,413,398,195,232,988,646,687,834,749,593,680,592,556,510,381,855,322,424,728,147,3,394,669,788,491,345,360,729,677,258,677,431,624,847,821,514,150,915,881,541,597,7,124,839,197,17,856,98,256,66,563,647,593,835,840,598,167,546,99,244,936,464,769,640,126,205,82,869,16,987,318,787,671,572,286,994,322,30,444,158,598,142,135,575,391,548,470,767,118,195,564,656,661,587,4,253,219,753,976,49,584,742,155,463,48,573,201,981,416,322,343,252,114,393,64,86,175,997,95,16,974,330,797,740,307,544,312,844,259,316,197,81,464,38,170,909,53,666,633,19,832,654,168,355,154,952,130,233,742,834,248,85,888,488,615,305,464,486,146,129,70,133,487,621,842,828,966,553,268,308,311,300,120,924,384,697,514,191,798,720,202,761,813,68,891,784,695,15,552,363,789,516,554,669,369,787,407,161,241,272,606,385,883,773,883,821,370,94,290,374,659,10,292,273,701,863,784,820,100,370,409,709,110,248,393,135,536,473,117,78,361,78,504,636,599,417,852,960,890,714,897,539,879,17,46,313,892,140,614,466,138,576,883,520,120,582,772,106,706,326,782,595,502,79,659,289,202,36,303,519,719,125,645,697,811,224,998,533,926,462,887,324,497,958,706,976,666,12,390,838,570,692,301,791,860,747,925,370,77,776,13,200,16,108,13,150,714,687,688,356,720,281,692,747,947,37,296,886,339,466,74,417,738,797,573,389,349,614,200,691,140,890,693,376,886,778,329,768,6,840,387,590,460,698,854,351,842,970,493,647,447,770,798,253,790,719,608,171,327,421,771,399,604,265,328,856,706,941,503,358,825,612,505,450,524,17,289,5,816,136,648,186,840,864,192,29,45,168,383,103,772,639,359,981,430,24,217,238,381,244,393,460,976,953,690,987,499,625,841,838,62,639,511,303,641,778,862,662,253,607,678,361,59,190,387,120,907,224,818,140,895,115,660,208,815,781,480,434,584,981,46,709,441,843,565,394,197,929,455,205,619,458,58,489,991,365,973,522,204,195,71,954,855,693,549,561,608,93,559,897,406,774,757,580,810,611,670,475,841,829,951,400,769,271,366,895,225,659,57,507,938,362,351,300,700,229,498,890,470,27,631,278,223,236,478,804,121,910,125,776,273,108,854,454,376,539,781,804,669,166,522,604,619,785,985,402,41,278,132,8,607,925,388,453,786,457,699,961,968,877,884,975,686,324,976,883,353,919,935,668,362,326,310,786,82,206,329,62,53,998,906,760,680,484,599,795,243,622,489,424,88,103,468,160,77,476,977,554,418,355,3,514,347,827,333,56,176,851,477,683,598,599,859,473,457,140,233,966,422,82,129,523,343,558,913,410,298,164,516,338,726,302,810,668,184,904,580,51,378,266,775,214,712,599,2,554,15,585,335,222,206,321,419,920,249,225,919,422,240,861,571,306,230,689,846,975,83,868,587,670,779,99,747,115,870,169,505,246,610,216,831,862,534,371,79,866,19,650,231,24,95,296,377,382,693,661,35,790,446,576,863,75,496,432,37,739,79,402,505,539,529,373,557,428,646,8,736,420,812,697,685,274,662,357,748,726,378,378,782,919,767,990,374,712,818,984,46,382,850,946,561,427,946,364,856,757,560,860,175,352,268,698,504,588,243,933,812,168,252,459,683,238,802,296,558,314,869,277,190,95,169,856,498,857,977,911,981,624,651,737,366,218,684,877,752,946,402,968,853,36,838,579,83,410,410,517,541,357,535,454,645,418,814,112,416,386,362,834,989,320,61,235,158,299,359,172,868,560,54,143,648,616,917,277,222,656,462,983,317,172,868,667,47,36,956,883,341,750,707,796,217,439,266,317,317,633,284,295,890,722,507,820,479,701,700,499,327,131,509,268,936,777", "536,929,665,160,924,792,749,759,155,732,19,293,88,928,671,515,666,774,149,144,452,310,317,58,193,657,987,664,174,774,367,794,349,326,673,516,751,198,878,151,934,232,549,980,987,713,963,450,310,428,755,46,285,444,999,321,625,319,632,866,682,952,493,376,381,161,956,524,160,519,310,274,742,894,354,545,926,527,494,718,223,317,198,471,703,771,211,11,633,187,13,395,634,186,421,0,508,44,737,836,718,50,584,397,145,27,249,965,637,668,699,624,631,614,983,135,428,352,184,668,91,656,370,845,911,475,459,487,885,690,564,841,910,522,432,671,626,663,193,536,317,421,321,859,879,628,310,944,157,712,315,84,839,487,916,237,606,569,248,995,90,905,151,160,847,483,978,20,973,291,34,517,652,671,255,726,6,372,829,872,638,387,978,837,414,164,746,120,430,474,640,893,57,234,427,571,969,389,178,290,756,641,976,532,230,306,547,501,696,299,341,526,40,213,268,538,732,95,922,923,123,5,280,354,789,553,144,42,657,121,69,851,952,316,521,276,55,681,736,982,24,137,797,114,279,628,752,426,530,142,798,546,192,196,201,12,645,236,637,363,653,683,973,182,418,178,249,265,81,236,539,146,647,341,263,229,48,777,321,260,469,238,322,221,105,31,846,294,146,329,303,201,634,556,89,295,994,274,864,526,773,894,15,615,33,173,755,13,639,288,437,617,459,642,234,434,889,944,456,653,757,440,725,438,753,496,952,440,414,975,207,459,217,588,565,826,60,457,603,646,827,993,901,620,368,893,345,316,668,946,698,481,520,43,531,311,666,156,454,971,126,899,533,34,600,729,306,931,175,373,156,58,148,518,120,120,284,718,538,570,917,250,357,603,738,812,198,735,759,838,740,877,140,366,88,965,643,174,175,30,824,894,61,163,676,839,37,989,643,779,728,881,3,101,961,90,336,185,807,851,536,121,529,55,834,413,967,168,920,220,626,877,333,368,871,827,77,277,59,960,147,443,255,76,980,468,185,779,893,643,434,904,178,378,68,70,755,48,510,948,425,12,901,18,351,522,796,397,510,823,36,207,223,971,397,896,817,68,244,123,603,966,996,736,329,371,758,616,606,829,525,781,227,49,695,245,206,856,909,661,686,105,146,798,204,762,84,409,951,773,901,394,345,281,746,835,287,245,252,88,360,636,769,498,253,19,392,5,187,744,493,217,278,169,186,946,346,557,748,722,620,940,422,69,47,258,400,732,644,483,92,999,513,623,228,975,876,785,119,218,360,436,433,14,343,615,909,125,166,527,75,261,877,366,890,718,794,130,780,841,644,469,572,207,467,808,619,786,53,823,250,184,19,187,490,759,695,364,874,848,81,338,245,692,147,993,533,17,375,857,699,720,793,258,668,916,893,991,197,161,926,50,653,23,46,155,525,717,12,769,128,842,43,61,548,330,521,809,346,754,29,21,57,809,554,956,95,484,374,980,545,937,61,932,755,164,994,464,464,908,497,748,747,816,509,760,391,230,598,578,550,879,261,525,121,710,766,210,280,748,192,413,55,64,565,795,985,808,180,939,298,923,667,564,462,751,356,562,991,561,119,866,633,135,69,4,600,59,212,780,1,84,300,409,641,458,517,564,337,290,774,571,981,666,242,618,323,241,329,126,705,853,792,618,553,93,879,290,627,474,831,402,849,649,107,161,794,739,981,928,573,501,617,347,897,334,23,910,539,634,580,340,898,85,815,206,868,691,586,866,388,103,472,412,482,997,958,665,749,618,425,669,405,753,832,275,844,542,769,668,588,734,773,326,156,876,371,561,7,762,826,870,184,169,381,310,98,689,794,101,483,29,473,291,370,108,411,567,691,938,903,831,194,638,986,286,43,487,561,649,129,677,944,328,535,214,410,837,973,892,514,114,804,576,84,832,583,445,324,75,824,855,381,31,229,674,511,93,259,358,916,528,422,360,26,131,197,148,577,174,971,710,474,537,965,142,283,910,316,797,96,526,224,370,83,612,284,426,447,509,57,123,159,149,486,839,232,759,720,794,963,698,845,163,665,503,941,763,957,987,969,157,194,583,363,958,357,756,817,917,256,827,739,397,288,437,165,194,598,310,917,328,338,831,743,893,201,687,429,54,260,850,666,540,965,311,979,635,851,274,510,250,898,507,632,189,814,395,236,580,53,357,958,253,947,513,321,278,425,375,105,367,443,634,495,993,27,135,926,883,22,770,867,307,801,503,523,830,527,548,42,951,637,142,547,309,22,649,430,692", "885,183,893,950,337,947,341,461,418,141,145,562,946,415,395,531,847,331,105,697,229,954,309,490,719,829,160,39,486,66,781,895,259,970,217,479,620,25,505,906,198,248,991,205,684,80,262,367,414,548,240,647,999,916,828,34,361,5,310,539,697,341,529,600,729,737,152,84,515,68,89,560,923,258,284,804,310,668,10,779,373,651,246,786,153,503,283,291,138,505,438,890,39,781,934,508,0,577,911,843,570,583,560,856,498,383,91,218,213,238,396,83,109,172,284,72,470,50,670,32,76,62,624,864,10,438,780,2,571,268,41,91,828,811,144,569,678,377,244,727,918,296,404,890,590,924,407,125,221,149,642,465,261,49,494,910,525,252,614,629,485,665,857,143,948,607,681,45,971,849,437,250,923,612,610,378,897,390,337,196,195,80,408,640,7,267,207,443,727,266,934,870,837,807,972,802,437,435,824,545,76,385,444,324,711,83,292,125,92,981,481,499,705,961,177,892,992,101,298,460,213,929,671,560,882,689,94,445,42,429,199,317,741,608,429,305,13,219,152,230,851,381,376,664,935,749,891,622,819,359,891,570,66,656,171,977,786,654,127,90,162,506,637,775,959,226,415,316,441,318,469,963,6,114,76,448,995,873,954,389,94,876,439,320,489,120,708,328,559,729,431,642,211,468,46,19,13,583,686,567,269,994,117,932,205,124,400,57,684,175,778,288,264,985,361,692,315,887,935,375,337,76,555,348,44,933,55,108,125,369,949,105,540,43,277,313,128,341,216,305,96,853,214,435,172,476,163,594,292,261,484,391,883,775,654,827,606,461,753,839,890,634,809,475,127,977,363,241,298,178,455,827,974,290,239,530,900,230,603,776,180,169,132,212,423,300,307,623,287,386,632,222,299,135,221,889,635,657,899,887,301,330,254,113,474,14,67,326,69,334,218,157,835,111,196,103,292,390,278,277,181,261,473,384,906,868,74,903,696,966,87,906,136,249,1,799,545,323,123,481,888,176,574,515,655,99,245,167,257,982,530,495,720,219,799,963,841,682,498,617,701,465,369,617,31,49,34,440,325,377,651,530,174,162,137,771,979,655,788,480,731,893,27,996,499,511,451,554,401,432,720,19,938,350,200,166,184,997,361,68,554,908,530,511,222,295,5,272,208,597,690,792,628,326,480,853,268,786,499,312,95,144,125,636,695,112,576,79,28,210,210,590,496,874,92,675,701,280,643,916,454,961,449,960,88,700,992,366,744,248,765,7,386,33,623,48,457,339,602,96,293,670,311,173,705,867,613,991,525,700,868,602,563,875,532,858,423,916,117,447,1,676,822,896,966,125,761,101,255,930,215,886,205,7,54,345,64,301,67,270,220,475,495,515,640,400,931,100,138,819,379,809,581,930,200,106,446,556,461,732,293,775,247,958,277,157,20,761,60,375,124,980,101,576,71,919,301,5,547,372,235,98,283,721,74,815,478,205,235,632,724,327,444,559,938,286,990,617,599,522,400,312,420,502,507,180,413,596,901,143,339,849,298,273,182,90,279,191,556,558,935,872,160,956,94,865,827,183,239,435,631,384,683,400,579,53,881,395,460,884,679,246,685,651,883,548,446,555,160,102,193,43,222,477,30,311,707,141,125,228,120,914,91,668,865,607,639,530,412,608,885,699,987,414,744,910,474,777,813,609,585,619,246,800,336,888,383,445,847,988,649,338,808,794,621,390,949,629,124,852,983,442,359,616,142,77,835,545,875,870,919,254,569,937,683,840,472,409,79,471,356,449,659,421,832,767,500,210,278,362,56,372,214,602,611,491,274,325,292,655,760,725,340,235,79,391,59,612,655,139,552,384,941,742,380,584,523,822,145,741,480,781,603,152,521,266,968,968,825,436,684,795,318,707,860,195,324,910,935,319,357,301,878,410,797,87,695,724,712,910,565,856,746,326,879,980,20,672,162,960,158,326,25,770,777,864,170,722,507,754,354,107,209,606,361,326,153,550,474,243,116,367,658,287,307,121,784,849,71,790,607,522,101,480,884,951,556,172,179,365,30,328,264,388,694,836,173,448,492,915,807,721,122,587,266,535,711,727,500,918,578,587,995,316,239,815,96,174,852,584,688,415,693,576,812,360,638,281,187,1000,785,516,427,599,458,851,14,644,97,989,940,883,612,641,737,938,430,170,162,813,970,903,772,444,351,965,407,524,344,581,177,306,38,109,533,86,965,452,326,943,914,654,961,859,436,917,299,117,883,969,457,31,801,910,621,778,316,313,52,275", "533,987,870,754,720,188,828,212,527,802,863,126,542,414,473,836,750,257,440,334,709,895,578,62,736,413,340,792,914,935,267,66,754,857,108,236,756,996,999,251,959,99,369,220,399,751,337,998,264,302,300,932,993,625,740,878,83,970,31,707,830,224,234,610,5,188,439,656,331,546,651,549,351,74,79,517,881,587,753,636,970,421,269,664,651,888,244,187,113,727,150,820,976,479,583,44,577,0,993,710,382,712,174,507,466,271,779,54,912,942,366,637,829,240,993,577,450,486,356,812,48,528,589,534,466,224,599,96,830,866,233,594,573,102,621,468,44,469,242,577,686,202,767,507,311,772,867,584,973,464,554,781,236,610,403,634,875,543,215,980,484,599,133,290,15,287,716,449,725,119,917,430,578,755,914,469,87,507,399,279,468,787,24,639,998,391,74,967,166,430,535,401,429,72,836,859,425,654,256,486,682,277,134,694,488,671,677,85,736,27,391,62,557,465,516,833,323,505,477,237,474,581,451,235,472,34,691,191,260,362,637,43,117,692,579,729,755,439,887,997,93,892,317,251,236,294,116,882,641,515,540,18,821,713,946,550,112,459,303,120,188,473,152,832,896,531,254,306,397,16,202,479,133,7,737,469,697,626,72,830,470,141,279,455,282,704,865,763,358,499,777,219,970,715,916,298,328,920,495,632,66,255,19,708,890,856,967,575,28,829,361,173,410,114,917,555,678,358,355,70,623,433,407,219,408,658,815,229,76,635,754,54,50,925,651,829,302,719,13,113,378,252,943,901,897,218,732,117,538,423,563,261,877,910,908,349,263,459,196,196,235,922,961,802,790,348,718,998,166,957,432,878,453,486,904,605,258,477,955,830,588,267,459,166,993,648,109,442,5,619,214,402,235,798,469,69,187,356,286,409,995,181,660,300,39,572,71,43,603,322,970,653,334,950,564,84,37,865,318,925,31,175,956,921,222,956,491,284,27,382,976,144,684,477,607,14,965,590,307,458,159,289,369,606,707,294,924,421,679,339,890,602,947,942,402,545,875,533,313,789,260,515,667,978,322,998,952,667,269,429,86,214,52,805,368,156,301,526,77,336,497,328,147,114,763,519,726,171,288,893,615,253,588,538,457,139,523,340,950,439,689,299,225,433,252,120,706,439,316,356,128,529,573,263,361,337,484,450,259,66,561,730,395,152,493,760,686,386,539,292,478,206,228,268,325,578,81,896,304,752,900,881,265,782,431,463,661,1,148,991,336,522,144,486,79,55,870,533,545,834,119,869,271,253,47,145,839,311,598,106,267,773,667,731,658,613,509,687,883,457,924,707,835,343,625,206,625,920,68,539,684,351,475,104,849,598,82,419,389,38,118,776,442,699,856,146,558,531,872,119,61,468,529,933,293,782,276,639,838,940,66,597,128,955,218,866,509,604,24,89,614,515,632,946,308,337,167,209,116,477,810,958,43,684,846,736,796,619,475,408,257,300,255,463,767,219,889,619,981,3,601,552,18,413,201,752,645,424,703,173,740,87,115,891,640,933,702,286,889,247,422,607,931,18,93,112,939,66,792,450,309,882,177,679,501,653,343,838,131,974,890,521,837,723,240,490,984,787,606,25,912,133,690,755,358,103,374,91,703,128,154,274,724,152,378,630,257,348,177,628,547,380,927,374,90,71,321,714,130,478,452,559,306,833,719,574,459,341,727,873,433,19,829,206,669,875,216,926,201,251,205,434,69,918,489,962,652,432,716,260,935,503,104,106,872,507,106,833,374,281,115,697,952,147,76,406,374,412,896,133,245,907,821,845,906,682,70,227,607,8,552,840,545,139,286,829,257,275,995,30,387,552,991,551,983,694,923,805,185,982,320,761,281,518,657,145,821,402,988,479,331,448,343,226,533,820,679,175,251,941,588,392,407,305,692,749,59,325,543,718,284,261,576,308,224,36,983,816,829,761,246,653,467,29,737,428,90,518,603,528,186,709,897,880,13,673,537,902,37,761,109,757,669,859,791,563,338,989,987,406,997,382,584,793,463,163,191,200,385,163,236,368,241,168,400,905,330,372,177,428,423,619,271,660,382,946,717,579,261,794,283,680,782,189,966,731,725,755,929,482,41,171,948,499,117,786,385,861,773,521,617,961,985,87,884,534,623,456,790,591,531,938,924,439,946,908,767,830,676,774,817,445,976,746,330,108,175,65,170,735,816,64,963,792,50,739,304,30,694,177,125,941,946,730,380,190,598,337,79,845,250,6,99,96,867,419,324,229,569,944", "202,806,4,224,907,981,857,870,881,664,675,657,398,584,566,420,26,348,737,527,470,890,799,174,367,245,478,786,698,563,425,34,100,851,396,520,142,101,515,184,106,996,500,484,958,677,700,372,472,619,833,91,305,52,342,703,653,559,326,391,840,66,837,91,209,374,258,669,154,941,102,908,79,42,230,119,325,817,960,138,450,194,4,574,264,338,609,46,817,302,507,290,180,786,210,737,911,993,0,701,224,422,111,754,310,509,908,865,478,422,924,147,32,972,500,125,921,4,316,624,452,246,758,650,335,626,62,874,638,383,431,294,921,770,42,847,888,671,803,278,369,860,71,564,66,486,475,521,128,244,885,968,408,640,151,289,701,538,279,240,321,162,299,885,463,531,15,526,177,68,716,360,732,973,439,983,834,170,723,867,393,854,214,457,716,798,612,652,850,77,788,637,491,319,384,116,18,676,629,595,593,250,522,718,163,286,571,473,56,620,585,971,354,289,512,12,305,195,335,453,364,596,245,457,302,82,460,431,934,528,877,306,748,623,659,539,666,59,824,763,777,938,878,120,328,665,24,810,2,561,272,881,872,428,72,337,142,618,862,985,496,423,978,608,939,409,487,23,795,355,276,362,723,15,850,255,542,56,437,189,726,627,923,914,974,286,87,31,426,927,741,806,211,124,533,95,598,443,149,129,114,739,246,224,305,406,194,2,172,652,393,464,64,437,338,413,289,377,139,197,743,171,882,945,427,231,988,564,813,799,465,899,273,158,747,986,216,819,694,645,889,929,824,886,142,84,387,280,598,964,265,234,963,557,202,815,83,165,598,292,294,433,61,844,661,773,793,264,255,160,858,950,534,128,965,120,298,963,102,797,518,144,654,60,805,673,335,545,448,46,471,51,466,230,741,3,322,812,569,611,929,63,157,263,550,522,542,545,149,598,108,827,186,557,347,322,860,98,609,528,365,178,30,322,574,652,795,753,384,925,985,888,215,388,223,794,838,220,585,502,916,363,590,14,836,551,863,722,695,710,383,255,600,217,833,532,449,82,507,658,237,396,134,148,31,433,109,947,251,629,558,521,94,219,331,157,516,269,165,288,473,811,235,363,567,585,359,401,814,596,168,523,898,725,350,410,293,289,837,864,583,383,265,448,368,65,861,76,967,247,219,668,355,371,987,504,871,813,302,584,317,635,358,211,641,303,986,315,789,34,517,855,963,746,511,353,805,838,518,453,790,63,556,667,414,193,533,143,942,825,595,618,763,545,945,968,829,391,145,298,173,545,896,159,124,595,914,294,624,924,681,81,686,842,943,88,552,822,329,786,750,141,759,974,925,89,871,611,113,437,184,841,357,210,653,193,439,392,920,357,681,199,821,528,917,393,206,151,329,812,115,315,999,476,186,710,397,651,660,659,274,859,590,463,808,439,372,736,966,763,365,410,199,988,955,321,860,682,599,825,65,136,671,519,165,485,621,847,639,302,432,338,909,922,232,919,677,157,976,450,266,81,841,881,674,138,231,952,498,498,230,129,782,988,900,212,429,884,24,844,595,824,499,282,131,288,932,862,57,972,297,955,760,240,802,635,381,35,919,772,846,543,482,231,463,167,710,394,937,630,754,764,58,421,395,519,431,630,486,116,342,138,149,676,423,382,892,330,803,10,572,343,107,532,422,749,790,832,94,116,77,241,817,795,975,778,937,518,676,265,335,515,749,302,950,978,983,743,375,416,338,209,565,287,877,943,179,463,488,799,649,489,520,61,31,180,784,725,333,676,611,399,414,514,859,327,420,232,26,58,306,766,186,984,43,905,495,514,249,821,749,645,278,801,995,840,243,592,92,293,122,674,651,697,837,823,355,835,424,594,767,996,562,284,79,75,706,816,98,123,355,79,527,758,413,73,129,660,860,982,820,994,914,950,163,334,207,824,740,508,190,465,962,700,465,829,229,453,709,691,553,793,648,611,611,321,426,850,315,413,665,356,11,756,676,796,958,275,327,207,614,541,746,66,663,297,953,276,891,363,646,832,394,819,109,527,248,261,549,788,786,136,194,748,185,19,804,550,25,342,650,726,149,209,4,67,69,653,518,117,606,44,174,676,867,982,149,602,200,276,799,910,429,315,659,380,11,278,53,140,457,556,342,442,60,565,311,922,115,115,737,937,647,804,45,581,840,349,93,653,642,276,732,19,388,535,116,60,557,909,681,330,381,748,662,252,814,272,654,778,246,821,773,129,772,576,768,701,739,284,32,968,217,452,519,293,490,520,559,185", "191,519,795,659,222,373,735,888,546,824,876,764,439,674,432,883,949,383,112,215,799,622,893,879,835,973,396,627,218,511,123,549,334,762,427,525,673,4,939,675,367,562,465,395,719,343,766,548,536,309,932,135,439,511,527,858,508,14,811,398,928,229,970,6,745,215,274,941,529,459,488,3,902,826,379,485,361,859,518,965,853,436,692,413,727,275,194,455,670,991,742,466,34,953,353,836,843,710,701,0,887,566,273,185,811,311,502,841,5,179,459,929,203,991,358,869,573,671,895,684,340,257,896,774,637,763,547,976,338,595,170,57,361,675,483,656,285,832,96,447,108,508,330,842,886,127,545,189,28,556,849,834,54,187,523,197,317,646,372,562,675,865,928,556,921,188,57,966,153,708,346,127,813,633,553,509,629,714,302,690,133,453,786,485,727,61,968,312,846,286,250,838,455,214,982,757,423,473,199,714,51,998,635,266,891,831,237,280,247,572,156,32,459,647,700,987,739,456,256,503,478,848,44,297,138,747,64,268,450,161,549,898,643,245,759,946,252,360,479,894,729,875,782,835,392,124,628,776,405,435,413,236,120,230,288,101,537,51,103,519,240,360,841,914,513,910,535,790,484,322,441,708,537,81,595,123,491,414,878,429,802,447,281,792,39,674,159,460,3,350,817,689,180,751,795,411,8,364,470,8,93,318,64,443,235,650,545,168,311,983,113,762,335,388,905,746,929,93,528,129,907,100,698,669,417,314,70,839,429,503,926,423,879,803,302,506,440,966,330,572,892,498,756,435,42,831,389,47,963,304,320,284,343,966,219,311,409,628,184,253,832,368,92,354,197,43,439,262,616,350,896,865,220,133,971,307,497,771,946,909,737,755,58,299,380,580,822,656,917,885,974,263,699,662,407,292,539,824,245,736,623,25,33,592,789,394,326,160,151,214,879,546,49,60,459,573,40,252,934,493,887,190,942,698,809,620,686,767,926,274,134,862,178,308,940,767,633,839,366,828,602,92,60,406,241,551,4,401,199,760,341,735,405,739,314,96,8,307,835,193,76,805,231,266,953,54,947,888,758,100,37,282,149,220,978,557,256,828,176,41,659,294,397,907,654,791,340,531,392,567,283,977,276,758,70,672,543,218,590,9,899,433,576,367,948,303,585,92,126,91,700,461,698,114,994,11,760,171,428,575,605,148,597,123,218,518,225,277,694,958,650,977,45,470,709,812,411,772,413,420,673,864,308,366,389,171,200,214,441,314,218,626,376,433,733,217,933,729,978,835,593,36,955,583,8,420,808,712,404,793,504,209,420,617,406,848,958,441,793,616,319,343,789,287,542,59,554,287,336,370,892,234,848,67,848,335,297,166,781,232,801,991,992,491,547,660,132,352,3,108,304,341,943,72,242,980,908,733,289,642,108,462,83,272,140,145,433,164,407,839,12,389,659,942,269,972,439,5,685,81,666,936,864,596,775,710,819,418,332,396,255,338,561,480,244,932,464,372,67,819,17,945,727,810,254,475,640,280,761,672,134,885,718,339,439,142,629,964,512,25,887,415,303,650,366,807,368,19,752,903,195,461,107,799,559,6,51,450,377,104,395,858,465,633,239,33,369,274,235,58,676,375,798,370,768,654,562,633,29,742,475,311,386,580,943,711,665,363,103,560,104,149,495,591,951,499,982,370,883,914,602,644,810,954,80,905,65,480,197,826,579,181,654,611,485,621,308,352,862,272,258,864,55,977,274,128,112,943,59,246,142,312,264,21,876,618,63,102,799,976,206,189,663,673,624,973,939,926,251,869,759,493,796,248,577,90,508,60,909,453,462,212,927,385,801,66,701,515,767,361,34,232,568,35,615,284,654,94,979,872,93,556,45,939,489,163,708,375,649,941,74,943,491,258,14,171,976,398,736,872,238,25,3,569,74,429,34,262,45,552,403,453,386,383,819,95,863,336,250,599,957,513,41,486,633,73,877,949,53,926,160,137,138,698,568,608,697,557,712,44,933,303,618,366,765,553,561,589,798,569,326,923,607,53,410,684,526,20,221,908,282,893,412,779,187,38,605,657,945,403,286,760,766,536,623,708,1,733,644,222,575,912,149,837,990,251,486,167,135,301,105,782,267,898,446,323,526,790,92,52,521,294,33,785,116,120,380,611,798,51,170,168,617,632,180,607,57,45,978,593,482,774,200,605,195,326,484,349,372,962,766,61,464,432,55,230,570,109,701,900,967,283,941,943,125,860,837,263,521,993,607,435,740,84,949,421,533,160,3,906", "825,293,396,377,319,819,438,208,216,107,400,376,223,887,162,621,367,315,30,677,404,179,894,995,176,781,849,720,315,532,737,523,815,200,46,221,532,709,392,609,958,90,173,473,73,149,965,419,140,10,391,844,222,181,334,635,76,338,128,151,603,902,913,163,93,817,845,532,216,408,979,471,417,740,366,480,149,969,587,983,38,892,966,591,585,133,655,742,650,432,513,187,605,220,616,718,570,382,224,887,0,245,334,398,718,57,632,534,465,827,989,513,226,895,73,893,204,347,983,826,904,208,302,533,745,66,746,527,775,389,528,165,771,138,303,675,645,250,78,221,562,589,736,308,638,481,326,481,880,198,630,994,112,894,678,224,487,911,104,18,159,890,945,498,76,76,432,317,151,962,87,964,171,232,860,800,687,972,844,721,31,581,471,42,103,836,728,755,537,921,975,1,52,30,338,672,437,995,724,848,734,387,209,460,214,640,339,985,673,378,311,316,929,981,2,438,978,851,732,285,609,365,287,889,807,132,114,178,623,246,447,572,867,78,26,866,946,383,751,998,419,752,911,244,668,105,659,371,690,186,453,782,406,552,160,174,551,205,710,192,61,974,565,579,551,166,550,957,904,3,424,237,135,93,823,425,535,409,789,443,887,306,424,402,376,348,866,827,774,930,84,854,506,90,435,148,309,695,663,571,266,867,81,388,801,131,32,577,442,960,606,521,723,958,416,706,361,768,100,591,206,113,319,578,811,507,663,818,16,714,393,571,645,764,498,392,919,535,697,672,163,242,946,657,526,871,838,184,636,898,218,81,446,956,897,443,160,711,280,197,526,834,166,748,903,628,94,361,260,34,342,113,172,238,422,87,755,300,328,843,566,947,407,928,551,827,849,596,430,590,439,718,449,771,482,724,677,391,453,2,835,857,319,995,193,554,829,95,165,296,968,102,192,521,421,666,229,228,290,654,768,604,148,982,723,140,108,297,541,465,45,382,147,992,327,155,637,485,743,64,814,895,925,150,840,165,836,206,404,31,743,289,768,667,946,473,317,687,247,49,588,366,882,347,185,155,886,366,930,417,631,424,185,240,886,449,704,957,218,844,204,63,765,398,548,892,111,161,935,629,740,806,125,136,513,878,758,409,17,622,829,348,792,247,584,281,235,595,117,615,107,553,315,193,920,363,232,815,463,493,954,485,775,102,575,884,158,938,666,820,308,697,380,193,842,384,286,37,753,449,443,718,312,948,377,172,155,139,810,87,439,527,760,562,739,22,303,444,635,622,560,885,120,648,547,342,413,164,678,877,644,598,658,668,29,673,418,820,952,400,434,272,430,98,649,607,875,218,69,855,352,212,669,411,339,170,237,690,454,320,939,281,954,854,456,200,506,139,696,964,841,294,324,328,392,939,474,521,394,448,32,883,783,943,103,863,186,788,94,392,172,265,556,98,73,901,860,607,745,23,284,573,13,36,551,252,707,881,947,7,591,988,98,280,235,757,886,975,825,137,273,311,900,245,519,704,443,162,377,157,336,484,831,558,429,38,572,217,99,52,848,893,112,190,57,597,718,97,26,216,428,147,900,468,108,283,727,250,854,138,949,301,309,833,863,251,58,522,616,673,53,891,14,245,814,839,63,338,335,910,890,862,112,357,622,106,565,225,291,888,593,905,290,739,848,455,635,140,971,235,7,382,87,504,815,643,141,986,428,198,979,351,607,307,687,798,463,988,273,236,383,365,356,18,778,252,886,493,470,914,65,498,928,177,67,875,625,767,222,122,739,505,650,86,706,527,715,52,531,36,449,9,350,822,923,834,609,490,358,924,514,231,446,594,998,388,550,495,844,347,2,667,631,379,901,974,747,721,873,809,427,693,639,379,196,160,430,378,770,624,285,576,850,270,113,497,91,881,394,542,456,544,28,719,84,669,600,300,50,263,10,567,966,855,640,692,95,867,791,206,339,575,408,235,580,808,13,277,1,314,612,178,658,873,659,588,554,492,467,292,763,719,567,115,955,853,99,21,927,259,642,749,781,996,91,548,276,662,668,375,625,298,500,886,608,964,97,772,462,478,39,557,47,533,584,780,330,704,264,24,492,516,884,450,787,437,979,531,957,894,794,887,616,498,52,309,865,275,25,905,812,911,740,917,180,106,275,222,110,399,538,276,675,321,741,516,697,88,970,395,19,582,421,699,384,989,448,55,889,517,616,607,595,466,600,363,439,985,231,444,820,415,821,929,139,158,824,873,407,613,741,630,60,494,246,543,941,914,860,451", "342,758,418,26,153,114,782,809,551,364,435,26,254,262,751,429,617,442,34,180,973,331,585,452,517,739,486,259,589,816,548,545,969,813,8,683,525,793,996,74,414,971,35,318,115,465,673,242,26,575,724,952,138,689,931,320,220,577,758,192,740,333,312,365,86,33,682,383,379,419,680,55,755,211,136,953,379,191,324,741,515,602,259,524,487,422,887,425,808,986,151,17,814,763,31,50,583,712,422,566,245,0,628,271,783,867,605,919,650,657,864,802,711,26,893,945,559,916,630,417,38,274,383,66,553,423,42,539,797,358,469,925,916,277,836,211,18,594,763,712,610,146,809,388,316,668,204,839,915,125,365,38,128,978,923,192,812,787,564,543,994,745,706,643,946,682,417,757,437,659,301,8,996,602,776,655,536,414,329,18,69,215,876,64,284,75,325,177,848,563,657,642,476,742,187,454,324,547,687,589,990,996,501,490,591,676,294,143,53,162,838,967,837,33,855,650,83,648,760,457,944,564,539,175,116,243,419,756,706,17,859,706,473,764,112,580,456,131,150,616,884,613,998,580,111,589,348,866,768,476,792,166,352,949,886,49,947,991,404,49,460,494,973,982,79,332,612,523,812,215,324,937,393,466,293,958,235,842,207,572,28,227,784,2,640,13,468,66,942,786,885,933,682,506,868,126,371,739,578,439,947,828,887,802,80,733,754,20,590,790,177,484,64,643,923,401,741,220,806,558,23,589,358,227,788,150,292,887,572,665,964,577,255,311,603,413,953,644,509,355,548,203,136,289,457,680,545,652,581,346,428,210,846,878,940,457,76,866,820,84,731,696,259,871,602,155,498,981,578,524,195,676,15,912,295,970,826,409,936,152,975,285,808,477,466,93,157,634,619,44,87,421,15,916,746,383,604,414,301,333,394,354,346,311,404,268,564,638,751,141,226,672,688,790,298,426,720,861,594,698,134,250,550,157,735,850,309,807,805,75,916,999,804,907,184,602,340,331,388,40,29,587,325,121,501,431,117,927,426,777,494,746,913,596,190,749,267,658,547,483,696,912,477,821,982,280,578,857,321,239,503,885,651,336,453,847,877,49,816,333,653,111,887,985,874,368,51,344,448,978,490,970,296,260,568,733,88,719,428,614,1000,746,873,878,285,270,408,51,221,111,27,11,657,171,906,940,104,882,302,743,622,255,556,215,108,750,963,358,117,909,515,669,210,796,167,390,792,394,316,568,785,803,6,307,248,474,272,942,322,134,914,204,159,752,903,16,177,842,991,249,436,888,614,175,126,675,430,970,265,895,152,519,802,373,703,484,585,465,171,674,350,798,892,846,241,663,963,241,549,279,715,886,474,670,471,680,795,309,996,518,643,498,73,287,709,935,308,780,663,727,426,248,294,100,193,316,735,354,573,465,334,902,44,836,238,255,576,306,430,306,499,565,531,545,134,417,71,474,23,264,191,345,439,212,762,47,753,530,619,94,767,367,82,332,453,339,148,686,544,969,647,499,907,382,642,756,16,63,957,371,685,988,202,990,961,815,798,407,489,646,601,154,667,757,499,697,70,208,731,749,297,981,999,597,642,409,203,995,270,988,840,210,953,199,620,710,430,755,554,530,478,980,970,871,747,522,494,302,190,49,126,12,9,351,670,755,205,309,428,248,712,168,789,713,11,928,506,878,108,288,786,241,504,897,453,304,944,15,829,513,979,845,478,102,196,966,634,725,433,400,651,175,225,696,795,437,40,30,246,811,602,214,831,482,35,605,889,701,535,283,683,668,388,252,796,651,712,744,733,829,15,777,725,206,217,646,873,678,372,289,64,573,763,667,296,616,334,141,431,484,166,292,417,964,460,353,262,59,668,500,258,976,30,209,189,62,743,912,551,966,543,398,133,866,710,444,691,767,358,3,923,790,242,987,571,839,801,11,684,229,291,878,577,396,774,976,66,29,368,323,571,208,484,514,579,70,102,336,515,15,938,699,944,464,305,999,314,327,114,676,373,429,158,159,554,691,680,731,422,214,245,874,346,223,770,636,955,419,300,362,695,312,943,168,487,576,796,730,967,440,528,356,840,233,285,282,532,586,627,385,838,5,998,71,276,656,403,248,91,257,503,695,495,765,777,537,197,487,829,608,104,494,391,947,343,74,251,568,24,285,693,498,77,415,681,189,494,13,850,5,548,292,302,359,792,613,229,110,327,350,651,374,393,520,251,775,86,56,635,273,188,257,952,308,265,876,33,793,625,639,40,321,629,703,280,934,70,448,360,254", "578,992,483,517,584,983,840,105,185,957,56,326,44,776,708,297,394,239,631,299,124,414,961,956,84,187,533,522,757,238,957,32,537,694,926,254,582,475,894,208,627,393,596,27,525,147,34,148,562,299,911,158,98,100,775,913,603,801,878,917,311,837,195,546,155,532,987,606,314,979,364,162,571,968,133,299,323,795,852,979,587,229,992,910,127,436,828,387,663,946,798,448,358,356,760,584,560,174,111,273,334,628,0,656,370,912,110,602,245,666,524,459,77,584,709,706,490,438,358,742,16,448,74,761,258,206,455,809,448,598,238,507,77,449,669,782,821,656,921,4,755,428,39,522,764,223,78,822,880,237,124,668,38,97,296,968,227,650,204,664,387,897,858,141,979,528,205,685,112,117,119,669,321,97,803,322,38,852,70,416,308,79,750,280,293,782,74,622,147,425,495,133,488,894,325,209,785,185,803,331,781,535,336,19,4,449,567,711,913,370,210,913,32,811,756,141,83,346,158,342,294,914,565,822,877,226,230,511,876,716,641,444,375,603,418,419,333,368,520,930,898,127,586,345,178,27,912,561,297,686,572,31,23,872,887,906,56,463,813,145,978,815,41,268,966,660,821,362,305,659,780,887,922,346,799,929,136,919,759,902,211,947,651,190,797,416,58,111,315,490,138,531,849,788,705,409,677,894,315,815,919,68,485,6,981,22,394,963,835,896,738,36,247,387,784,684,819,541,9,779,255,287,903,913,19,23,39,537,676,160,801,774,362,780,856,29,513,759,11,661,890,696,23,630,688,438,419,347,143,429,445,19,915,28,83,417,657,636,518,829,226,592,397,588,240,442,941,76,508,316,739,501,743,697,451,13,146,837,430,724,796,243,134,776,387,74,419,180,204,526,941,522,931,351,100,404,597,126,738,708,549,880,421,402,515,30,261,279,407,876,740,626,333,805,771,776,184,409,638,463,729,167,469,154,245,622,228,561,519,766,972,71,392,867,713,925,83,44,922,993,365,735,91,446,408,2,711,860,923,38,803,215,126,387,369,516,696,26,728,868,728,550,173,589,816,938,448,832,767,606,641,415,679,449,9,204,579,600,886,56,126,816,416,549,187,526,743,564,370,99,439,724,954,746,593,170,400,441,915,354,603,624,885,63,459,445,57,96,615,580,743,487,970,528,690,729,158,844,772,415,314,391,987,477,240,812,882,611,450,659,936,290,512,32,794,100,547,268,309,744,693,606,226,694,60,699,117,229,648,538,260,519,622,316,265,431,752,486,115,650,889,929,7,136,606,137,37,163,612,524,309,756,457,805,108,877,478,379,920,187,320,909,812,210,794,849,814,911,869,949,645,766,538,880,694,741,272,530,414,798,288,965,987,124,912,555,237,310,880,228,711,544,740,245,498,668,70,985,872,100,749,681,780,653,670,734,303,354,993,937,135,853,12,23,161,326,754,790,554,465,775,832,692,899,733,80,459,70,438,962,26,106,291,75,202,315,379,397,703,375,806,124,586,365,312,256,853,378,300,982,599,507,205,441,851,270,263,313,749,70,837,297,539,208,363,714,115,974,224,864,848,863,980,941,668,514,524,836,134,656,785,584,867,691,468,353,924,697,877,990,821,465,595,907,955,131,984,26,382,418,352,550,146,296,953,354,947,894,994,626,595,41,164,240,297,612,488,804,326,119,461,457,789,500,302,321,727,528,436,725,906,130,485,556,629,680,630,143,578,782,148,800,430,328,989,514,596,90,371,635,10,502,795,508,90,385,520,569,802,832,887,516,124,645,151,383,528,887,854,289,866,302,322,557,73,619,313,315,17,197,522,343,760,261,303,292,64,621,461,792,872,786,67,6,302,491,951,77,321,94,384,361,141,214,99,773,104,887,801,699,115,636,304,171,759,451,568,255,214,743,429,816,719,421,680,693,64,376,901,804,328,225,910,213,133,989,242,76,648,153,233,86,122,789,844,46,447,40,360,185,881,437,773,454,304,549,862,756,359,242,359,112,615,495,361,39,810,139,25,616,643,459,546,813,151,394,119,210,4,285,920,643,372,703,359,321,852,124,427,200,38,91,470,798,377,508,691,456,599,388,478,392,219,250,694,846,407,43,67,587,860,156,155,173,710,783,191,789,428,598,683,130,836,872,444,737,931,956,573,510,756,452,683,866,673,621,473,911,404,141,238,979,379,434,240,902,732,855,278,326,479,188,613,994,519,807,636,680,414,211,914,45,255,335,361,669,572,287,403,528,449,87,625,81,78,230,24,983,715,461", "76,261,566,74,855,410,517,879,918,216,906,613,520,668,574,175,710,828,609,982,446,32,592,528,236,50,802,994,961,297,24,3,934,950,627,436,944,259,603,997,484,687,698,914,35,230,159,83,135,458,519,516,421,703,504,668,451,775,279,7,26,99,637,569,492,37,559,291,6,660,780,499,303,448,393,416,86,525,670,911,435,654,408,156,223,385,551,426,434,397,81,822,905,880,879,397,856,507,754,185,398,271,656,0,247,880,501,218,154,799,619,900,78,579,533,480,248,184,733,219,739,888,61,31,824,327,195,171,986,36,744,724,58,575,292,922,614,899,805,157,15,234,864,356,640,999,413,858,248,423,9,705,743,252,393,433,372,292,480,390,984,286,352,323,385,303,911,124,501,232,360,195,536,464,6,220,501,931,551,667,280,508,696,324,775,892,46,645,576,560,765,756,732,905,397,290,751,816,885,887,312,107,377,903,624,31,480,928,209,470,366,342,723,655,838,594,733,516,763,554,528,671,992,91,290,23,34,826,701,804,912,353,999,905,117,644,524,664,977,451,362,918,583,336,486,159,276,907,721,564,313,810,876,129,757,270,743,46,8,732,876,220,820,796,70,960,204,720,394,904,389,573,645,180,201,609,725,316,836,317,605,615,235,562,482,212,556,494,162,163,614,998,235,393,952,836,427,62,193,436,827,220,486,548,534,205,517,288,598,466,522,894,522,731,510,855,693,405,901,954,625,2,751,911,204,493,606,178,134,645,799,44,848,5,498,575,664,157,554,875,765,144,633,611,251,2,503,431,506,263,210,81,43,214,364,183,51,473,505,478,260,395,926,75,458,67,267,410,167,692,242,94,464,109,596,762,982,683,903,75,810,471,879,291,487,767,252,950,856,730,679,184,810,399,49,76,539,701,31,585,426,461,187,438,100,627,280,361,970,989,875,119,835,733,65,52,980,693,793,415,654,151,390,842,381,739,993,751,624,705,23,154,888,243,800,866,406,410,878,100,896,589,558,376,340,276,627,687,573,903,199,569,398,165,192,550,941,452,974,324,517,663,978,120,939,907,455,493,97,515,801,236,474,5,773,985,57,726,934,490,460,994,568,735,580,607,835,752,338,303,961,658,726,665,564,807,875,23,269,181,275,692,34,240,76,459,158,951,461,495,781,380,585,879,62,507,988,28,996,2,167,346,575,469,688,756,825,150,158,398,996,228,263,94,341,904,252,884,251,885,64,501,937,89,553,591,87,247,821,260,29,308,198,961,232,756,992,636,428,626,358,511,551,876,846,661,654,902,903,396,948,13,143,290,395,141,44,23,740,769,632,381,634,789,917,709,390,477,917,134,471,196,948,475,290,117,216,58,195,483,51,886,642,108,869,308,777,338,865,20,928,513,178,112,910,169,579,434,703,412,27,480,51,157,900,475,711,934,957,417,622,181,515,288,149,300,599,195,251,501,41,728,918,866,159,732,411,759,236,347,199,678,824,138,296,529,691,900,20,934,269,903,622,670,98,720,9,64,725,223,830,350,531,774,122,988,395,369,895,21,505,712,737,154,552,16,190,834,196,842,41,823,262,29,607,371,908,590,899,990,518,118,45,847,85,668,686,692,272,224,912,120,984,341,258,190,94,225,844,330,986,836,548,33,681,595,723,798,975,50,326,750,494,667,70,106,712,652,600,966,5,719,895,983,164,662,894,158,602,202,140,648,989,761,319,343,178,26,659,521,824,182,65,279,53,681,873,471,171,236,369,762,376,436,494,131,611,257,234,27,505,137,592,814,322,579,675,270,656,206,340,47,111,849,226,571,305,474,512,655,142,643,807,959,225,196,633,600,443,729,26,46,938,688,288,212,356,147,396,268,281,271,501,486,828,437,864,457,485,244,304,569,914,404,355,991,183,888,836,531,662,923,759,746,254,676,324,963,643,784,695,359,113,501,77,209,167,371,986,409,871,781,411,2,175,339,130,517,84,963,703,157,180,491,549,409,94,580,812,132,671,395,988,871,626,55,988,495,414,437,841,445,839,575,644,512,548,285,435,749,809,220,744,268,131,32,849,733,655,280,387,33,794,42,998,403,431,707,258,379,502,881,331,708,961,146,82,708,275,700,561,796,538,264,208,64,452,704,845,950,259,7,286,892,837,2,237,304,625,868,560,370,589,650,389,648,825,314,844,601,34,325,501,837,812,973,783,912,635,821,736,138,426,516,241,138,988,111,46,361,386,621,155,633,566,229,484,735,145,515,117,731,963,632,471,778,996,454,124,770", "394,587,132,503,512,313,151,722,485,205,480,405,883,872,481,171,982,341,949,127,955,683,173,23,831,40,608,337,663,570,705,669,528,52,366,348,376,993,942,359,431,743,308,783,488,414,145,378,169,834,703,993,19,894,897,439,277,119,608,480,8,49,18,448,143,221,160,487,458,413,938,440,878,444,253,368,927,180,353,725,154,510,547,244,634,586,279,912,194,83,984,359,154,847,525,145,498,466,310,811,718,783,370,247,0,358,576,342,814,284,213,550,526,175,346,721,353,374,409,547,745,739,311,236,698,452,747,342,375,839,784,641,273,962,571,227,806,289,310,843,518,43,846,195,536,71,787,324,116,796,371,997,633,600,17,144,202,388,28,792,313,324,883,38,389,882,215,398,309,755,575,454,811,739,893,866,504,658,804,839,625,98,62,216,899,343,972,384,791,929,723,87,261,489,20,452,867,368,209,78,966,307,561,325,189,441,37,995,445,582,856,476,82,111,837,890,802,74,740,635,684,951,416,662,993,334,74,840,902,507,462,579,396,107,302,259,646,614,657,444,131,473,253,914,902,710,224,575,198,150,103,802,872,843,73,124,647,83,404,813,948,235,151,455,607,509,693,532,263,348,696,877,339,757,861,276,639,966,55,829,326,381,10,320,638,735,710,300,192,129,774,32,929,46,882,379,916,232,115,681,339,795,833,604,641,291,18,715,40,86,664,180,791,361,933,700,478,631,399,935,339,300,326,394,6,418,316,655,660,757,13,321,450,258,828,748,68,494,473,682,110,344,469,700,375,609,10,669,686,956,849,939,765,202,171,68,856,776,904,717,114,482,473,43,351,411,640,775,993,250,42,655,636,628,691,928,904,895,903,584,255,766,131,671,899,776,84,450,183,951,980,514,240,42,10,958,978,507,905,319,280,20,189,838,63,523,594,44,923,30,277,363,787,751,903,39,946,638,262,83,218,243,624,466,56,308,678,885,593,96,455,52,146,342,700,617,287,300,930,890,490,847,236,352,150,368,558,74,592,132,945,326,41,642,206,19,864,932,987,321,558,315,143,558,724,267,567,70,31,829,710,144,341,198,954,947,471,231,232,956,740,514,772,962,297,226,637,828,877,475,790,871,697,850,912,445,522,994,164,746,389,593,185,660,9,568,268,934,67,207,468,895,36,141,502,796,287,515,986,538,995,127,754,110,561,793,624,304,47,893,725,755,9,254,925,585,113,480,486,550,629,587,516,963,113,900,73,638,303,802,148,945,599,770,681,809,808,139,650,454,984,476,214,353,8,689,515,436,991,386,716,483,783,508,627,621,734,949,651,202,337,299,83,816,881,440,339,839,884,384,85,712,695,249,975,867,889,346,550,652,517,141,850,228,446,407,936,966,4,363,97,39,810,780,763,996,371,281,757,248,813,67,835,216,572,801,288,148,201,910,397,38,926,555,831,69,183,394,17,817,933,654,239,768,748,559,701,622,4,583,753,449,685,480,854,608,47,396,115,569,933,336,646,604,465,1,659,266,788,866,114,278,552,96,251,49,72,250,266,115,819,377,477,985,426,796,643,457,171,481,778,678,220,631,845,48,469,908,388,943,858,770,673,983,27,373,761,281,708,413,457,408,43,57,718,668,906,829,913,773,647,625,196,276,83,119,492,267,867,339,82,943,681,766,174,126,205,480,572,623,942,495,954,249,143,316,933,959,109,59,684,687,760,950,80,25,468,614,156,954,31,434,722,129,465,654,571,489,470,266,197,86,686,233,903,793,146,863,903,633,298,901,465,693,534,948,396,215,789,209,840,337,287,884,319,981,827,711,251,252,866,839,661,994,983,808,578,555,615,538,934,684,129,294,490,545,96,567,40,890,950,897,669,7,430,476,734,749,674,124,722,663,583,873,757,479,50,889,901,112,761,339,497,7,551,825,345,155,326,933,535,693,936,13,653,208,244,540,319,202,670,455,843,646,68,930,661,485,202,741,599,586,293,569,232,311,266,579,363,885,628,118,858,245,512,812,354,496,707,915,164,504,156,507,823,780,768,221,148,646,905,699,147,337,564,186,299,409,959,781,164,722,135,226,123,19,898,420,659,468,4,953,808,699,422,83,109,922,14,847,216,838,571,550,186,576,146,717,876,712,533,767,369,598,524,977,140,313,104,144,77,749,745,479,333,876,468,665,846,345,985,219,613,388,683,61,240,407,940,816,991,494,722,481,989,544,395,451,787,673,939,433,53,546,454,693,733,236,219,684,964,216,17,164,251,934,798,947,93,778", "432,366,985,784,917,752,305,693,259,78,543,70,533,272,253,239,566,228,101,552,614,795,370,778,126,589,827,159,875,455,750,157,28,199,462,60,463,442,959,620,462,951,651,912,511,359,681,378,18,823,768,183,816,812,339,904,358,537,676,743,40,565,156,195,117,738,779,676,323,225,197,221,680,726,757,411,564,886,690,443,407,833,162,18,205,533,622,666,448,839,197,638,120,695,329,27,383,271,509,311,57,867,912,880,358,0,625,924,453,69,537,112,830,548,136,943,863,861,137,928,831,670,682,316,251,846,960,979,189,62,819,128,884,245,504,513,567,650,247,472,928,457,308,738,210,954,374,449,792,616,253,658,538,550,129,998,659,648,9,547,537,931,590,296,732,4,536,922,37,919,791,348,481,449,16,695,73,257,94,72,439,376,506,370,277,43,789,913,658,856,853,700,897,808,513,110,618,258,315,294,563,4,441,854,726,47,802,509,856,965,786,13,195,166,245,646,453,335,646,966,884,335,427,513,45,679,937,859,178,466,270,378,262,784,780,766,460,550,107,480,211,303,712,753,830,776,174,619,192,713,678,976,617,488,200,500,312,296,133,673,215,21,795,533,814,260,776,483,395,16,888,787,619,905,345,685,380,645,304,868,206,211,47,608,995,198,270,545,390,817,113,288,921,586,252,511,737,715,354,388,407,377,701,271,214,379,580,703,676,685,534,632,39,630,715,103,113,281,155,439,222,302,228,199,967,677,328,621,931,204,445,729,148,692,311,978,938,660,232,964,795,855,465,944,410,889,989,216,779,363,463,72,427,211,871,483,62,645,163,733,639,115,2,168,764,656,820,915,608,306,195,205,352,738,275,218,24,257,181,57,964,346,768,36,957,279,406,857,57,517,549,187,991,394,76,444,921,34,402,805,729,832,132,993,401,322,279,376,166,589,431,545,794,248,529,101,619,416,107,679,330,112,586,923,117,821,351,497,383,52,388,547,287,689,785,155,815,365,345,760,525,37,662,629,782,16,43,54,589,707,468,223,16,881,539,203,873,954,437,658,778,606,772,134,998,964,936,703,468,807,491,411,840,269,613,3,341,236,679,992,414,786,720,283,514,754,656,598,134,411,80,768,90,203,175,414,11,289,512,936,887,600,451,380,567,951,840,302,616,999,18,433,150,292,197,22,733,435,755,533,283,592,764,384,227,10,198,669,678,414,672,641,372,806,438,560,949,383,851,821,94,823,986,519,694,919,776,656,604,447,806,488,865,84,754,315,968,154,736,957,372,164,552,629,157,963,181,554,966,496,126,77,416,837,150,110,538,31,491,799,335,373,769,518,152,315,619,428,174,607,447,265,922,368,107,451,821,85,162,33,269,473,309,559,940,658,830,417,724,178,448,942,326,88,737,611,224,108,284,758,242,468,991,427,191,378,668,955,100,153,347,476,80,93,258,190,423,17,445,374,275,636,297,972,806,459,51,438,721,68,819,548,359,847,933,299,914,421,452,616,694,665,773,255,946,152,571,419,790,563,233,317,776,321,122,131,705,164,337,801,358,837,232,851,818,683,65,510,368,623,793,752,340,78,128,520,972,889,316,383,191,244,367,825,171,306,698,194,211,991,840,326,655,259,282,17,754,971,834,637,118,464,458,698,690,223,594,860,445,45,361,681,477,132,375,357,292,410,819,463,202,729,476,845,884,765,211,941,245,980,738,742,974,14,514,526,490,854,682,829,513,815,596,594,109,344,874,913,175,185,565,576,917,233,468,911,664,98,152,725,713,765,437,729,903,388,808,692,774,742,761,971,753,403,200,585,749,602,27,206,957,142,305,946,960,902,806,577,263,68,649,312,991,752,856,532,39,321,848,599,663,143,75,7,20,269,109,692,435,595,799,180,353,891,67,992,945,878,820,667,422,102,668,218,516,894,574,884,615,751,378,832,375,374,244,760,699,854,956,160,679,130,595,244,982,661,145,840,592,59,710,216,19,539,364,480,93,748,121,471,844,404,975,656,434,500,993,32,769,611,401,331,164,869,433,993,700,285,17,523,619,666,516,569,54,996,685,383,142,993,638,365,100,684,162,729,582,716,454,860,432,372,957,124,179,100,94,310,499,572,131,837,514,421,472,29,83,255,230,255,475,260,755,308,572,345,720,386,838,795,386,279,55,65,638,73,769,677,692,165,276,614,801,613,992,723,827,908,504,143,637,952,96,732,685,866,386,810,570,295,588,622,129,568,14,89,684,321,668,732,723,72,87,941,215,638,835,191,846,253", "786,154,566,953,630,402,449,840,73,98,342,267,793,736,616,897,351,829,804,921,524,420,116,609,565,140,71,302,573,180,685,824,721,140,601,833,88,605,141,706,407,744,823,51,122,135,634,656,185,101,78,812,28,741,744,625,292,537,90,833,154,893,11,574,864,37,729,276,227,390,182,702,687,251,357,175,878,735,46,822,435,609,521,389,293,188,111,274,614,598,578,867,907,518,272,249,91,779,908,502,632,605,110,501,576,625,0,568,574,410,589,852,919,700,547,889,519,697,308,863,901,346,17,599,718,962,884,850,403,279,379,730,69,411,554,693,443,780,623,197,511,410,483,10,197,535,883,553,125,445,826,672,609,887,898,661,405,689,391,381,392,479,619,623,523,334,132,137,330,283,581,615,196,921,304,46,451,515,503,174,260,690,410,462,181,487,252,532,653,240,601,624,215,785,433,32,146,190,392,244,549,459,275,598,291,90,717,323,892,670,916,20,148,556,535,484,956,862,14,93,520,777,990,477,335,292,896,765,122,569,423,398,357,266,751,568,893,487,232,483,357,708,497,417,145,205,17,877,743,61,747,643,72,746,340,782,935,932,792,898,907,183,21,225,163,817,476,125,891,280,369,27,136,692,451,256,93,237,284,760,627,171,597,386,512,737,612,508,257,718,504,896,83,443,895,150,347,181,157,917,998,983,617,983,755,571,340,758,982,110,414,672,306,219,881,150,287,927,667,241,256,576,994,417,478,843,880,905,728,464,37,225,13,591,856,671,473,260,553,640,70,969,889,787,480,318,362,697,680,619,673,550,266,115,781,366,105,116,696,992,509,465,441,763,375,882,477,72,298,636,902,15,350,180,164,514,335,150,353,906,233,442,493,573,857,6,536,958,902,808,578,641,460,939,416,759,685,389,718,458,218,751,527,628,935,292,927,430,5,793,517,698,471,327,618,274,131,675,988,336,850,84,668,853,721,951,487,182,204,277,931,12,529,350,801,275,566,42,297,582,122,200,483,395,779,49,760,728,705,572,165,377,409,481,8,57,491,864,72,78,199,394,981,925,772,887,789,319,648,372,371,345,468,373,347,576,731,484,945,575,767,406,212,706,560,724,907,35,975,278,425,35,175,26,762,53,977,761,453,434,663,539,688,785,784,482,569,679,16,419,953,501,725,7,220,132,589,4,358,319,320,651,698,88,335,227,622,350,936,234,663,303,970,604,163,339,488,245,259,882,556,264,725,407,725,314,850,804,801,518,826,788,777,746,288,952,736,804,291,550,8,214,814,509,226,235,522,215,304,793,709,794,924,92,584,956,816,180,383,600,133,388,77,398,852,619,598,799,222,96,603,16,889,563,665,299,69,513,47,898,965,310,918,681,670,212,590,409,33,694,518,786,722,823,737,849,568,680,615,920,918,929,962,986,67,13,665,433,629,635,630,398,665,402,436,820,138,955,129,941,911,813,908,164,716,240,98,522,947,751,689,388,893,318,513,791,973,683,121,281,321,202,833,505,143,595,407,6,744,536,901,414,666,441,342,289,709,283,760,522,789,759,853,932,871,950,533,622,789,63,276,59,821,815,399,770,247,2,764,242,291,115,329,113,356,806,409,543,399,670,404,855,444,49,779,400,257,317,375,179,405,904,802,485,598,703,918,679,269,900,692,404,137,693,816,110,486,229,249,881,666,296,21,123,977,46,802,865,715,555,129,358,869,976,450,211,702,323,853,16,840,692,198,705,173,912,804,971,74,125,224,410,868,977,246,755,385,144,836,22,14,433,788,100,78,758,521,274,334,295,816,520,693,705,546,81,298,395,54,773,259,656,877,911,417,404,540,71,927,986,506,789,832,795,923,455,781,360,788,270,816,718,169,159,727,371,688,973,49,727,760,623,682,824,69,482,128,869,630,7,279,18,84,696,124,958,757,461,821,392,822,159,682,99,709,539,143,315,533,233,190,990,148,568,583,996,938,147,661,382,147,582,816,805,423,341,850,296,476,841,985,437,479,30,157,771,984,476,335,974,324,309,393,126,751,845,985,586,603,508,237,379,253,948,675,63,389,734,299,832,389,248,914,423,727,596,528,970,247,659,460,56,803,531,359,54,143,29,119,125,171,758,516,630,977,188,45,661,4,800,258,656,858,154,517,587,397,128,440,818,224,678,393,249,394,200,541,532,714,45,992,440,191,958,111,254,29,827,871,312,390,165,326,69,629,418,495,758,757,817,352,309,322,773,104,274,787,782,593,797,420,722,64,407,46,70,913,611,211,469", "313,544,605,482,916,350,120,129,953,510,408,388,287,764,700,489,51,684,103,74,435,210,513,878,864,390,385,746,665,596,267,271,574,882,621,140,253,516,716,473,368,70,119,620,228,152,789,215,569,191,257,275,657,741,323,105,857,940,920,550,952,817,913,259,902,77,819,622,961,777,970,518,692,21,65,399,480,650,848,520,472,549,954,925,725,959,852,793,770,202,445,266,631,473,499,965,218,54,865,841,534,919,602,218,342,924,568,0,598,15,965,81,22,997,580,389,417,558,67,124,461,641,290,651,990,579,564,710,252,37,835,334,186,994,877,255,866,805,763,656,16,989,266,713,402,394,870,357,174,453,657,843,427,909,87,772,981,674,236,204,998,584,856,332,798,808,327,769,987,433,936,61,309,996,474,901,811,524,257,677,404,969,427,451,765,76,312,702,994,658,8,732,768,957,239,927,209,328,742,844,912,840,125,671,38,406,328,606,402,830,518,635,792,433,497,124,17,652,315,474,699,294,966,4,837,437,82,551,724,569,553,820,359,947,403,715,317,31,878,280,621,117,820,556,365,692,9,915,204,347,241,616,732,781,619,684,953,738,815,113,193,544,396,135,774,35,707,611,596,27,815,271,76,645,980,965,989,961,937,326,781,846,507,271,719,360,70,264,696,13,21,223,738,976,569,786,873,228,953,847,363,469,503,782,646,763,493,313,533,746,740,338,321,57,470,583,225,58,605,708,500,48,156,100,911,617,953,494,483,913,738,525,964,229,699,48,504,420,735,314,180,120,608,878,43,199,320,691,419,659,762,190,17,6,772,849,903,577,597,146,411,674,656,18,501,670,40,678,705,514,997,514,33,152,822,672,173,450,475,986,826,519,349,342,75,207,136,802,813,826,972,463,644,986,703,602,81,816,594,51,573,245,837,798,926,851,446,7,615,546,509,469,620,441,554,540,573,770,527,231,318,873,518,405,518,38,329,540,68,415,48,197,500,554,578,460,200,246,267,434,651,925,267,591,588,165,68,933,431,233,655,431,708,376,871,517,116,627,305,210,511,915,128,82,248,350,261,141,702,184,611,701,876,190,320,429,3,120,795,946,756,520,540,894,469,19,806,675,978,816,517,412,368,259,270,125,696,745,50,913,442,408,565,61,23,397,207,971,596,301,40,791,206,22,813,786,246,926,686,318,42,900,875,748,23,864,1,330,6,207,144,437,537,293,114,607,547,808,845,135,577,819,86,158,329,691,451,441,79,270,884,963,800,861,847,577,648,692,403,421,66,192,934,428,468,274,447,828,912,253,628,547,529,239,627,14,708,931,14,707,592,998,202,893,342,84,183,414,339,484,225,982,812,565,848,49,893,60,473,181,56,996,792,395,470,22,533,584,562,844,644,109,246,354,863,459,39,866,383,117,73,462,36,806,881,968,571,876,720,216,895,187,205,166,959,69,370,350,241,28,692,303,166,885,875,497,406,885,729,681,538,223,737,77,1,597,453,927,303,135,238,598,850,524,285,480,602,84,404,127,843,969,722,893,679,337,629,379,671,634,621,666,363,875,721,548,70,997,722,220,970,778,898,541,185,326,661,690,62,730,944,346,143,861,843,505,867,179,351,718,671,761,501,748,698,516,488,760,57,977,622,589,564,949,756,341,55,873,306,839,774,321,117,745,300,603,212,628,125,661,357,123,441,770,385,423,498,202,91,342,309,973,981,219,824,499,410,313,106,539,257,468,422,105,26,650,753,578,349,953,436,324,986,362,730,1000,793,656,334,770,394,767,449,291,163,100,66,423,402,839,171,254,672,674,30,876,973,724,410,972,236,760,983,712,385,251,104,946,386,538,65,471,621,947,232,210,718,586,489,654,881,124,635,159,50,221,547,848,342,235,689,292,221,707,197,609,463,744,287,852,710,905,194,123,999,501,924,779,35,81,175,815,318,742,45,388,905,710,217,659,115,211,49,786,845,444,955,23,820,386,83,746,473,12,153,799,702,562,687,794,856,96,505,216,935,642,598,125,191,689,94,876,781,55,74,241,152,971,948,453,107,70,456,464,497,701,817,440,582,171,321,809,899,747,414,174,433,975,154,947,488,695,810,950,850,496,565,364,893,30,353,367,910,738,886,772,524,579,962,732,414,382,430,725,892,563,150,648,263,78,398,856,954,324,672,666,552,271,280,892,242,474,754,465,772,114,595,289,452,302,988,272,89,215,155,836,667,351,268,767,541,217,21,436,835,816,755,485,660,591,843,155,673,105,984,103,329,54,291,419", "693,480,837,526,484,142,631,647,402,295,906,239,467,135,446,48,430,218,980,629,668,161,706,237,898,967,471,35,556,541,550,192,947,539,455,116,161,305,709,770,129,989,288,538,764,210,656,764,721,568,926,606,449,15,703,99,580,698,35,700,387,58,15,557,479,498,155,680,113,563,670,713,678,763,324,470,839,607,904,24,945,789,46,21,464,762,340,580,258,723,393,606,663,803,416,637,213,912,478,5,465,650,245,154,814,453,574,598,0,792,176,44,491,467,855,18,726,457,887,925,242,201,502,352,386,906,612,573,908,36,801,153,136,972,815,181,934,439,757,117,692,317,935,103,719,698,475,444,413,771,597,954,511,467,308,910,461,562,915,22,354,919,72,555,158,922,453,191,417,378,32,217,812,523,151,880,72,881,200,56,44,335,491,488,40,314,406,508,730,500,152,82,992,1000,651,785,802,32,184,813,900,286,295,703,923,793,517,676,510,250,728,932,753,225,603,133,794,237,407,505,61,53,94,604,89,482,989,20,378,715,138,695,283,964,541,331,214,459,397,677,252,86,918,238,505,63,122,27,818,616,458,127,724,281,301,570,366,354,589,797,694,206,127,307,206,26,839,912,426,174,910,818,816,823,717,304,601,996,29,133,739,243,676,10,404,628,124,338,831,803,215,132,945,196,388,738,772,263,255,24,93,555,488,904,846,402,490,13,129,785,386,75,798,285,588,389,679,598,782,360,634,27,307,69,792,960,665,632,426,250,317,828,16,794,306,285,653,623,981,4,971,206,564,422,802,759,705,394,242,393,30,614,309,701,999,862,71,454,429,153,832,985,787,873,910,398,635,948,231,616,788,215,600,871,356,449,199,770,707,586,842,429,437,883,719,51,660,915,795,436,47,24,525,222,573,619,408,153,224,650,570,152,368,328,259,932,364,381,572,522,906,274,78,911,966,578,926,978,762,47,654,146,114,533,697,258,453,773,660,616,74,295,963,572,660,47,528,300,649,706,459,617,288,324,118,40,692,72,678,623,365,751,177,880,232,318,986,26,858,976,489,121,531,857,168,301,30,681,858,513,290,785,814,547,835,419,16,827,954,34,163,717,984,680,787,229,807,239,201,515,260,40,531,466,956,369,52,702,307,72,853,123,373,652,589,525,876,433,633,39,639,690,814,597,19,348,262,413,860,497,690,803,672,677,343,970,658,417,777,181,998,287,9,638,326,623,225,824,17,340,822,544,225,908,745,80,739,258,381,711,206,11,460,748,813,821,798,37,83,357,958,599,692,311,194,528,834,497,137,518,117,133,57,203,406,481,663,96,305,957,162,142,957,973,780,913,996,203,391,815,892,175,322,673,168,125,203,105,72,540,372,105,286,276,169,787,584,887,914,8,903,266,92,881,367,969,600,737,139,377,494,781,995,518,499,475,195,473,140,487,596,985,115,371,665,259,995,668,869,647,632,460,3,902,938,645,157,963,714,239,488,518,457,218,106,556,357,760,667,290,71,809,720,366,365,671,195,684,764,510,356,79,246,801,569,815,490,601,136,345,683,612,530,536,557,35,621,609,877,702,675,657,331,161,288,84,546,733,84,979,174,94,410,503,36,645,673,280,771,246,835,230,839,822,128,668,29,476,623,862,20,536,708,64,376,984,18,733,987,766,170,823,345,583,600,587,33,182,918,323,569,773,996,468,745,11,600,308,607,337,531,100,12,962,829,138,735,915,970,967,177,156,818,977,531,850,778,587,515,460,924,791,457,997,54,137,356,997,948,102,341,275,793,604,230,997,716,601,322,952,996,601,376,752,997,903,678,564,854,975,912,589,80,879,559,408,732,804,225,431,788,835,225,831,795,846,105,106,827,670,81,872,434,126,333,90,708,25,748,353,569,234,135,572,386,2,842,752,873,780,579,607,297,925,145,146,399,585,716,697,657,530,373,803,499,726,436,705,582,675,677,142,480,741,959,373,248,581,493,115,905,893,535,183,257,344,219,466,753,275,775,856,355,988,362,989,624,600,610,714,82,574,897,600,369,303,312,798,101,473,111,607,827,395,665,821,436,679,101,461,482,341,437,789,241,314,143,880,432,483,691,36,833,450,848,928,415,949,775,106,60,927,350,881,519,21,202,429,38,467,956,698,196,337,720,751,977,638,642,306,951,455,296,606,982,594,982,743,664,487,620,265,294,261,245,526,38,960,476,121,38,371,133,136,24,466,713,613,847,418,23,376,304,192,475,751,228,434,769,14,641,367,440,545,185,444,61,193,989,250", "587,983,448,469,362,295,278,159,701,359,639,405,423,252,405,262,142,38,490,258,159,62,498,651,985,787,370,642,212,629,933,210,459,825,269,243,507,513,821,871,251,380,453,16,343,493,554,816,704,444,504,919,717,551,988,31,134,918,667,76,712,819,907,91,842,519,609,360,624,281,965,407,610,460,708,348,14,241,487,803,592,481,199,641,241,684,964,830,273,824,945,175,201,202,569,668,238,942,422,179,827,657,666,799,284,69,410,15,792,0,565,760,261,134,90,559,562,183,927,753,166,827,862,772,128,882,161,345,527,975,659,568,952,706,307,204,389,46,525,202,927,780,919,468,678,265,651,653,514,236,332,602,74,349,623,746,818,564,184,966,521,608,449,725,262,777,569,788,548,718,462,940,930,834,211,535,600,102,396,728,203,532,242,225,695,28,737,556,849,620,868,294,375,558,292,335,421,520,693,49,188,972,683,510,132,975,184,95,96,513,580,234,482,395,825,545,620,989,884,325,5,251,838,800,622,895,74,335,456,952,94,797,94,900,254,523,390,963,320,277,902,301,511,269,375,417,659,391,7,508,228,712,146,359,846,274,271,602,170,596,898,268,11,851,719,677,560,217,266,297,52,167,171,450,239,90,951,92,549,273,819,534,821,648,410,662,971,687,425,384,68,531,350,95,403,671,408,810,120,254,783,767,999,202,982,867,937,589,941,592,143,896,37,520,683,474,697,131,904,321,156,352,625,706,490,502,930,776,524,846,311,45,231,603,994,157,551,264,759,119,610,224,504,149,966,640,310,426,40,713,873,185,636,349,76,234,903,476,898,164,881,705,503,402,187,911,408,923,334,477,11,548,667,318,330,120,798,786,710,948,976,664,26,617,140,590,770,266,320,90,15,53,399,348,113,691,391,677,558,325,695,680,391,398,358,95,636,815,366,659,508,110,98,800,832,858,223,697,762,573,685,629,321,747,112,572,167,613,865,731,970,103,384,714,743,746,132,971,979,980,996,541,111,52,997,377,887,30,279,982,454,96,857,384,669,702,417,527,929,425,891,941,642,472,981,743,38,241,177,554,613,370,674,322,480,721,89,932,949,738,947,997,843,821,4,380,939,966,335,64,477,307,206,362,284,938,813,108,561,922,784,415,339,146,156,755,810,338,403,622,667,476,76,201,991,774,886,267,675,500,71,616,292,347,790,647,307,336,426,329,697,211,166,912,59,530,910,332,888,582,21,749,344,94,325,813,689,398,942,655,100,27,984,182,354,737,798,362,254,148,946,7,190,965,80,816,13,802,87,49,928,638,92,843,708,257,655,761,526,970,16,664,740,861,96,816,493,330,924,583,445,315,201,66,895,435,735,533,852,256,861,555,299,437,69,893,970,309,237,903,252,863,1,444,172,209,315,559,368,507,860,783,681,852,460,244,137,469,782,115,413,529,294,62,425,32,126,592,974,519,650,686,648,61,424,243,554,595,30,956,178,328,504,806,331,742,809,973,767,164,680,690,808,254,18,535,228,603,846,568,678,245,200,68,496,866,665,100,382,400,305,328,276,984,648,160,110,208,148,189,635,978,166,513,799,104,432,799,444,642,693,923,59,82,472,735,451,166,246,628,26,52,494,606,841,900,491,642,878,805,886,366,797,773,725,987,735,145,708,47,179,891,745,664,829,562,459,859,991,536,136,521,242,50,305,706,732,317,989,587,193,595,494,626,147,129,607,939,211,776,347,471,801,538,188,784,873,728,293,924,799,4,500,689,653,128,898,379,334,446,859,289,814,404,888,536,534,894,757,371,60,637,157,530,308,748,588,448,61,581,285,507,812,772,8,863,594,760,509,723,150,986,974,952,192,869,81,630,94,901,344,894,523,707,731,174,141,363,290,844,703,230,665,690,258,97,486,636,961,610,232,374,341,592,685,204,635,129,885,856,577,499,858,164,146,519,339,546,146,785,757,95,31,715,734,733,45,405,556,679,231,867,152,194,566,41,829,698,606,287,715,988,333,273,701,275,765,695,825,590,874,368,688,724,864,455,160,146,478,505,605,151,530,380,696,195,874,409,570,321,6,966,966,149,312,615,206,617,589,462,75,570,922,53,951,231,93,727,161,509,357,801,264,587,848,803,238,398,683,568,333,181,23,780,189,721,212,12,893,623,501,383,309,327,480,504,194,3,964,255,528,287,290,447,857,37,417,352,804,291,118,214,656,983,110,315,983,250,23,439,457,104,554,974,127,381,13,440,138,211,228,517,710,502,925,879,271,378,560,439", "659,148,985,13,926,285,314,759,729,166,211,991,118,749,557,455,705,943,400,512,125,833,523,935,975,800,912,305,323,180,173,283,657,457,878,943,87,77,324,918,454,456,856,579,509,857,669,245,898,920,237,118,880,426,920,570,886,231,980,330,211,769,844,44,215,129,967,192,392,770,184,62,611,293,711,425,160,510,233,100,934,378,415,157,225,174,322,847,209,448,658,88,729,120,94,699,396,366,924,459,989,864,524,619,213,537,589,965,176,565,0,161,186,563,798,336,970,379,551,52,182,973,956,741,474,423,392,501,610,286,866,775,636,440,51,517,529,710,81,174,202,973,683,378,102,866,591,719,252,973,199,687,688,180,830,364,755,255,452,26,452,389,982,746,894,962,379,931,373,570,160,245,297,117,937,274,522,346,517,334,103,433,695,20,985,737,475,269,354,199,989,622,213,583,332,242,934,957,253,430,391,211,210,811,432,532,284,562,686,145,677,17,910,917,258,275,284,279,40,727,865,271,349,908,77,21,203,324,599,899,860,775,408,858,919,688,578,232,491,61,695,413,637,554,443,956,89,927,865,397,481,12,121,129,698,273,889,436,91,206,191,377,460,1000,703,483,757,605,565,9,570,367,659,787,139,582,466,604,863,987,309,999,643,622,249,4,206,269,749,620,78,958,285,434,792,142,412,692,432,211,955,817,758,898,344,310,864,137,880,19,84,501,664,735,449,523,809,178,159,948,358,375,493,118,857,99,122,63,652,375,899,693,450,201,882,532,101,461,802,21,82,204,303,855,64,976,122,336,731,244,800,433,387,658,717,8,227,110,182,343,172,36,512,101,553,163,205,752,147,560,873,166,768,506,222,215,575,990,694,546,696,890,91,409,287,413,190,925,59,337,416,926,821,153,323,904,878,193,614,88,583,859,489,5,886,775,471,226,363,609,558,919,881,860,157,366,300,154,662,626,505,693,632,672,316,513,278,840,572,774,782,856,528,621,800,282,31,404,513,292,610,427,767,37,111,18,725,75,975,20,630,211,43,81,931,537,971,907,30,324,995,930,256,123,803,13,817,993,496,635,373,939,83,845,248,574,362,629,549,954,289,610,749,847,514,433,254,774,402,648,642,36,531,461,161,451,982,205,120,774,126,815,785,329,650,989,824,321,928,983,623,756,721,122,470,671,715,151,437,94,230,401,722,914,671,433,30,71,315,909,226,265,996,107,923,549,418,557,206,234,408,753,386,870,222,494,308,850,297,88,80,673,695,318,332,575,901,693,483,688,887,717,446,617,858,289,828,889,337,326,806,485,455,854,493,655,784,284,133,268,951,46,715,848,499,281,899,401,912,134,929,106,241,862,836,491,801,783,990,707,329,249,54,298,754,529,44,538,318,548,412,864,318,256,657,651,349,819,262,322,885,5,75,261,146,411,452,573,470,136,726,91,393,25,355,862,513,377,465,637,766,402,731,874,95,655,465,801,314,838,528,910,809,475,309,660,964,63,337,896,826,631,16,113,32,381,500,726,465,496,132,331,459,894,80,538,77,150,664,402,671,647,421,802,389,220,309,403,997,760,961,575,187,697,903,349,323,957,748,381,137,144,499,850,660,380,773,756,836,647,922,405,159,528,214,726,188,989,871,402,661,827,455,228,291,836,253,826,237,69,878,984,900,622,950,490,996,125,440,105,921,726,852,283,420,13,876,202,435,798,948,976,198,945,750,2,469,549,729,936,963,892,692,642,569,923,516,151,346,697,335,788,203,817,758,259,498,779,326,581,616,17,642,603,23,743,807,662,160,248,399,493,46,487,522,982,645,689,609,445,880,88,818,425,768,452,767,106,693,947,89,399,161,550,426,948,827,434,118,360,402,25,405,511,665,166,655,258,198,20,935,140,93,117,671,378,800,922,376,460,872,585,359,543,414,285,648,557,75,38,218,145,235,431,560,327,59,418,415,200,127,695,711,82,875,886,28,328,898,701,19,247,927,482,793,828,910,203,72,512,952,833,133,302,263,220,870,797,103,126,916,305,577,214,662,257,145,80,302,586,255,252,129,561,52,302,716,578,120,61,346,534,608,903,535,37,679,567,957,21,137,652,96,540,781,213,41,65,370,623,847,370,89,958,136,167,236,698,395,828,549,898,63,328,70,124,827,530,789,386,524,478,409,708,456,664,911,926,172,890,403,547,62,423,687,753,246,279,969,217,593,173,486,901,409,514,235,167,746,138,346,684,458,756,266,141,348,154,151,777,765,195,69,297,46,369,527,32,309,573", "55,855,334,183,942,2,880,668,299,476,571,507,227,734,269,486,697,866,985,679,840,199,688,523,186,551,284,488,736,169,285,324,232,959,474,938,681,733,813,164,698,44,318,327,211,226,349,342,581,335,979,822,445,500,807,868,291,4,345,951,645,1000,825,2,399,809,641,60,583,140,287,649,574,541,356,61,771,53,683,999,763,204,591,652,809,234,579,214,807,88,896,392,514,692,224,624,83,637,147,929,513,802,459,900,550,112,852,81,44,760,161,0,252,200,751,959,901,473,351,332,92,357,574,269,106,82,916,476,556,793,697,565,822,782,267,875,521,860,686,273,268,582,24,878,339,791,330,115,607,169,884,305,69,965,877,945,120,694,490,750,659,211,21,859,925,702,323,321,573,353,547,659,853,485,675,373,242,662,952,979,283,223,473,992,84,196,227,358,575,175,666,368,726,819,733,331,775,180,161,385,960,708,810,120,6,527,268,230,54,823,481,237,804,423,929,729,278,962,408,18,368,907,165,692,764,680,952,273,276,108,697,94,925,184,821,782,257,372,798,846,140,454,311,384,694,357,338,844,206,387,669,891,542,747,255,257,850,56,22,832,874,420,444,199,373,414,654,471,205,462,231,774,142,473,255,800,288,139,166,463,483,291,468,429,534,548,750,601,40,341,662,289,194,754,670,334,109,644,408,450,697,384,445,572,489,690,719,177,417,559,349,708,540,19,15,978,699,928,821,390,867,541,146,519,168,273,287,287,216,196,652,164,77,952,155,732,802,920,323,296,519,27,944,304,633,842,586,320,740,234,742,504,555,780,509,677,386,524,72,866,457,853,363,311,362,397,624,779,639,420,356,703,158,269,369,185,845,454,348,125,2,856,11,615,86,761,126,920,184,835,504,34,15,613,73,73,749,318,91,177,331,204,51,647,703,376,348,898,700,755,358,735,69,125,44,766,790,796,458,123,630,996,133,960,532,886,886,213,809,94,848,651,238,35,148,970,314,984,351,739,921,90,461,615,809,756,786,738,466,314,443,259,498,845,65,468,989,668,611,251,616,9,292,70,740,243,491,507,354,935,75,993,993,719,789,479,239,563,730,681,862,330,897,408,664,893,873,612,902,412,483,257,982,357,408,16,884,692,937,626,575,152,644,348,464,510,967,620,317,403,301,640,23,614,199,759,215,886,850,870,975,670,607,882,153,885,293,830,534,823,971,127,593,631,956,176,365,752,934,870,803,273,856,349,528,81,48,531,492,86,413,563,385,687,546,584,581,796,312,807,590,304,641,874,79,610,274,787,35,701,707,765,385,299,66,480,323,915,482,811,674,493,212,54,278,442,888,613,411,110,643,671,528,164,351,826,107,471,614,758,156,600,765,777,312,926,984,214,469,319,200,127,428,809,503,965,730,152,275,503,348,483,303,591,503,912,384,12,27,427,461,621,251,283,900,953,703,871,915,113,472,918,380,41,578,655,998,423,700,995,778,543,385,658,294,648,95,696,539,762,970,313,3,178,921,347,486,382,383,371,715,339,805,730,984,691,699,230,119,731,144,246,482,879,846,555,899,966,399,705,383,468,983,324,260,943,483,49,366,502,732,32,245,750,361,663,367,73,314,716,135,431,658,812,76,912,217,668,340,696,797,952,318,169,901,43,833,548,56,171,74,481,117,552,409,829,454,392,943,832,357,395,649,64,36,776,770,527,84,736,255,380,464,328,662,530,893,164,402,974,59,148,661,960,373,872,90,236,14,678,761,602,741,959,593,447,57,207,520,30,756,210,83,573,186,72,908,543,350,867,951,785,686,303,553,377,685,570,612,19,948,430,815,480,878,249,175,890,488,232,881,724,405,352,260,561,296,908,956,885,208,443,389,182,867,328,51,574,543,615,898,534,535,936,273,102,999,319,470,688,444,15,754,730,72,986,207,107,837,817,780,755,301,344,974,624,885,876,368,287,723,757,224,415,696,907,900,192,180,78,559,716,127,8,98,615,830,809,726,583,164,682,854,369,212,901,865,472,388,143,396,88,274,501,477,249,359,670,732,258,529,519,98,894,591,681,795,295,171,908,848,373,287,687,98,521,579,242,935,119,111,130,975,604,707,169,957,969,374,86,437,438,243,972,191,391,564,255,198,478,911,827,186,608,847,680,936,918,794,80,503,334,22,725,237,865,624,215,843,292,82,637,47,708,129,130,718,657,222,226,625,622,781,378,131,867,618,581,640,4,286,560,784,349,2,946,203,239,592,757,290,14,50,755,354,151,147,256,730,600", "491,372,36,732,653,25,642,390,354,23,731,952,758,961,708,490,255,564,795,852,410,351,103,846,91,817,30,191,456,986,953,375,663,687,183,773,920,808,409,952,627,219,902,626,266,756,760,684,825,545,530,187,896,432,743,628,236,369,523,566,321,273,672,916,249,396,706,296,254,716,939,410,336,437,585,99,635,305,519,195,968,337,79,281,461,348,779,342,214,490,841,655,224,461,253,631,109,829,32,203,226,711,77,78,526,830,919,22,491,261,186,252,0,7,816,506,181,193,957,399,236,695,841,854,30,983,56,244,560,164,300,750,374,201,798,141,287,237,205,326,784,504,899,2,82,132,790,328,326,935,810,37,723,929,542,323,600,252,14,898,514,857,365,157,684,119,71,72,848,524,275,910,687,665,639,851,904,377,231,24,811,175,837,611,299,900,477,738,717,853,248,33,150,524,206,759,597,945,948,98,261,468,708,992,376,881,90,115,337,165,954,185,489,526,15,902,993,218,368,997,413,443,13,570,435,527,727,757,507,109,531,439,857,530,69,961,900,792,198,219,623,438,578,355,269,459,681,127,21,327,155,295,674,930,191,9,557,761,547,562,169,971,393,616,889,676,502,364,12,593,869,851,836,561,420,666,111,358,717,555,699,77,34,801,155,905,767,881,545,502,5,114,120,695,924,797,86,579,389,140,350,552,298,687,782,319,306,838,880,167,906,25,76,533,671,487,291,773,573,952,338,987,97,910,124,979,130,785,758,474,850,612,322,335,312,237,639,833,939,727,926,346,952,459,269,86,174,578,286,180,339,751,153,456,878,389,927,934,9,599,66,157,430,725,78,720,551,798,584,291,177,778,203,212,511,451,385,420,710,975,968,910,109,343,618,728,623,87,941,509,525,384,822,859,821,211,326,514,459,118,375,61,155,621,358,188,331,61,403,318,460,680,872,504,790,277,337,436,105,716,389,526,996,552,809,906,631,59,378,906,687,590,646,878,498,663,818,603,65,339,320,354,952,902,392,516,99,25,527,29,3,32,20,873,429,400,151,860,314,931,52,624,235,321,150,547,543,109,834,9,11,660,763,156,428,403,168,717,4,686,340,896,814,190,393,805,607,173,351,298,536,2,648,921,790,186,639,423,43,86,729,519,678,891,401,147,989,738,861,174,468,959,283,203,370,147,874,777,144,625,19,669,429,900,328,837,875,376,53,936,431,372,710,385,447,155,621,481,216,242,727,46,124,767,481,972,545,15,678,124,339,464,232,181,395,134,178,364,929,486,200,234,944,618,264,821,507,710,746,905,678,97,440,933,455,215,431,83,781,426,821,136,649,600,966,853,427,715,436,170,765,723,694,145,780,405,702,304,888,454,588,556,346,540,350,626,225,298,622,56,821,25,52,974,961,164,642,384,581,95,613,34,458,101,219,291,431,107,661,964,164,970,300,456,411,91,931,123,975,419,627,830,188,201,374,895,637,647,772,720,696,906,374,10,362,396,147,994,287,531,914,782,972,754,44,325,909,948,69,225,39,883,209,623,440,826,541,952,549,807,896,943,830,631,246,700,863,612,845,829,958,177,89,705,653,547,108,798,489,410,364,869,479,185,586,899,365,753,612,731,753,370,849,810,129,685,965,676,893,644,847,127,802,572,855,848,441,48,283,140,412,939,971,556,944,930,264,799,270,932,41,309,714,911,749,436,564,87,980,388,153,180,141,284,71,222,384,632,480,823,152,168,892,665,109,324,9,761,986,334,518,98,509,300,676,794,350,144,122,113,801,89,111,623,135,534,202,691,316,430,258,159,277,545,844,13,316,20,397,618,542,881,86,946,40,146,518,409,555,287,433,376,644,374,311,919,93,783,564,187,919,440,609,822,600,763,754,276,351,207,709,995,301,641,778,537,695,42,18,686,711,29,931,583,725,146,344,533,953,746,154,420,980,579,452,188,773,604,639,570,335,947,764,381,12,646,557,293,424,752,60,822,985,75,361,325,849,430,178,874,714,395,209,789,699,201,330,768,153,191,462,468,578,581,887,790,279,618,299,869,247,814,242,637,686,965,562,813,507,878,455,873,891,253,423,336,532,689,903,636,513,525,434,810,588,218,139,340,565,581,421,349,651,443,267,189,661,113,646,413,42,542,522,849,507,849,557,832,197,736,78,818,594,568,61,31,265,235,733,881,484,282,78,394,520,972,378,792,237,350,115,28,477,960,30,736,732,597,869,551,900,772,381,594,685,60,999,772,234,718,602,246,956,13,679,898,180,498,223,15", "467,746,409,180,37,319,84,542,681,533,354,270,547,373,132,358,436,80,955,100,238,334,128,732,450,906,306,534,566,749,269,724,672,168,315,370,83,155,745,170,101,607,452,946,645,687,823,289,663,426,521,124,366,35,674,182,354,465,166,957,749,136,180,523,326,904,669,860,411,977,778,272,34,642,424,506,793,639,613,851,250,396,575,758,968,109,725,769,345,375,904,899,750,701,512,614,172,240,972,991,895,26,584,579,175,548,700,997,467,134,563,200,7,0,734,714,754,525,439,820,122,158,840,487,72,499,655,605,493,691,106,661,357,336,702,583,201,684,56,576,710,783,420,794,716,86,978,540,645,975,238,567,399,613,851,387,276,193,814,554,70,266,58,265,880,176,305,399,155,32,945,326,777,510,856,173,412,943,711,872,23,222,774,966,498,384,856,784,804,873,714,37,764,81,800,690,161,550,708,763,361,616,966,389,134,533,535,472,345,78,581,681,586,923,943,1,734,833,954,11,223,220,852,66,391,673,810,137,920,590,404,747,6,618,55,118,725,855,226,110,458,37,105,536,936,981,912,471,63,73,982,116,216,303,722,180,810,181,40,381,514,43,413,907,197,671,283,997,859,945,590,45,560,961,755,346,677,495,542,546,962,19,930,109,917,198,465,612,427,530,307,359,946,235,354,150,797,156,673,241,162,134,316,743,662,132,696,822,99,839,477,408,58,868,750,12,75,91,521,455,747,695,826,600,545,170,372,783,985,467,926,568,643,972,341,782,497,284,542,280,724,980,609,308,783,630,805,884,60,206,311,606,889,967,712,906,55,533,351,758,545,633,858,87,752,400,438,228,374,54,632,812,522,570,566,512,370,399,587,430,723,228,574,637,798,662,218,277,355,935,894,16,911,693,547,373,44,310,213,422,374,119,366,269,872,635,591,929,347,628,139,92,411,193,186,796,495,301,345,602,109,400,312,60,184,887,701,881,132,753,492,10,527,669,505,662,806,382,508,196,975,266,373,456,592,983,37,585,968,710,484,64,403,972,91,134,897,123,398,598,208,512,885,45,605,772,525,456,102,946,950,794,76,917,248,395,173,359,542,636,501,87,219,70,86,714,3,778,612,994,455,548,549,593,518,457,784,800,96,28,142,476,913,243,892,488,902,972,422,927,529,134,188,446,186,400,285,756,20,245,116,247,88,312,181,668,531,371,451,895,691,410,573,568,169,835,501,701,622,276,439,639,872,5,264,17,984,840,566,124,955,94,308,697,665,433,574,998,547,795,611,386,857,138,165,415,465,75,152,129,733,815,199,547,403,202,381,274,731,773,912,475,122,168,954,902,218,335,639,622,858,478,48,646,965,474,916,843,220,952,227,518,183,965,557,772,773,982,844,388,362,271,65,259,540,478,831,940,988,541,164,401,170,106,769,470,700,147,518,830,872,234,738,102,474,785,188,510,854,812,14,500,283,531,41,212,381,404,736,631,920,8,26,174,119,935,764,489,8,730,917,228,511,362,919,796,759,937,688,83,693,84,937,764,269,326,366,114,246,180,911,694,362,561,365,357,639,981,200,144,757,919,274,202,202,779,783,698,42,876,429,745,9,134,483,641,223,482,394,501,382,183,26,725,416,64,438,476,729,964,82,585,589,709,891,252,682,531,379,512,908,496,26,771,27,542,75,382,651,169,104,405,909,145,491,768,122,879,687,868,472,363,415,554,860,842,865,763,506,264,504,249,136,98,281,417,426,259,285,541,727,108,569,700,573,544,939,226,604,424,100,928,781,141,758,932,763,3,608,482,368,380,517,364,154,772,562,104,853,127,783,718,790,276,928,722,322,68,810,349,717,44,957,268,763,109,960,374,209,145,19,353,729,100,255,621,607,271,822,147,438,715,578,372,737,594,511,441,139,170,696,460,570,18,4,577,773,977,520,399,223,785,902,524,3,959,921,73,454,753,846,567,68,580,609,863,527,941,9,997,273,75,780,358,174,839,574,333,698,662,400,695,878,804,580,266,362,928,279,530,293,560,93,877,799,444,177,577,662,467,581,558,524,63,985,170,312,965,439,296,279,530,262,914,746,115,480,969,343,845,776,732,427,235,827,39,270,578,982,408,669,751,295,657,853,890,281,847,338,534,353,463,309,304,221,553,854,52,167,961,635,831,440,71,810,956,381,780,425,625,711,94,257,599,478,526,633,320,747,52,25,514,772,884,767,556,392,29,117,708,622,414,412,381,637,418,246,502,238,508,963,917,682,538,883,307,925,193,294,197", "33,876,227,775,484,458,408,938,251,618,484,279,842,784,895,491,82,686,738,210,114,92,686,84,315,388,928,177,37,471,406,339,221,838,709,564,256,501,552,969,420,604,726,406,199,951,766,397,58,436,793,274,534,24,780,513,361,278,903,872,128,478,969,369,697,92,285,907,107,68,731,768,921,877,107,953,834,865,978,149,311,989,719,607,992,7,948,820,767,9,145,659,265,957,102,983,284,993,500,358,73,893,709,533,346,136,547,580,855,90,798,751,816,734,0,680,950,959,533,686,870,199,372,646,206,769,275,364,912,771,859,85,364,783,580,899,639,5,575,483,866,113,885,193,268,544,686,581,970,535,195,122,107,455,570,614,774,744,131,820,246,770,608,515,784,930,245,458,547,872,53,987,543,495,660,280,781,63,720,597,799,966,938,465,981,794,888,640,187,668,818,932,440,11,256,585,672,865,598,569,827,84,753,530,68,403,940,296,836,973,633,271,787,776,195,229,347,85,103,866,697,740,779,464,407,899,443,408,79,506,739,898,27,174,223,751,584,6,448,203,481,739,503,267,80,157,435,139,805,493,304,52,146,435,880,372,971,987,702,695,668,974,145,231,994,587,163,234,275,123,986,459,939,780,593,523,537,177,226,260,65,705,586,64,302,990,196,44,639,354,617,383,421,802,588,111,231,267,107,558,103,54,9,642,356,993,566,556,934,789,562,540,336,91,56,661,435,874,849,766,619,314,626,27,664,545,227,6,456,513,825,122,984,586,644,513,45,953,539,987,199,206,95,818,997,400,459,125,976,702,631,947,847,188,45,206,718,880,968,52,753,47,986,333,275,988,883,966,629,960,596,677,760,638,47,802,845,694,937,326,895,915,692,819,588,75,917,611,819,304,517,744,847,967,743,118,831,568,285,744,532,973,743,264,609,144,579,396,97,238,324,920,987,20,172,100,79,865,950,55,323,77,933,366,19,901,131,462,612,296,648,548,446,270,622,732,21,3,485,854,591,114,349,33,545,585,133,53,257,396,644,84,654,325,901,542,920,457,548,22,709,737,636,716,824,430,434,224,97,570,86,150,976,300,337,709,439,791,994,782,378,963,99,625,884,577,924,580,373,197,119,864,484,579,155,52,614,299,823,139,912,524,898,93,379,28,68,831,175,718,47,351,489,75,362,704,594,11,862,440,269,971,150,439,6,151,689,868,266,169,285,857,785,913,413,530,256,401,28,939,783,797,673,702,342,415,257,786,580,716,5,258,176,731,343,973,512,351,653,588,803,898,661,880,323,364,743,553,969,153,648,4,630,205,21,531,17,376,227,283,670,933,510,591,168,874,32,934,493,483,297,390,676,385,846,404,717,783,255,467,993,461,23,957,859,697,613,75,196,112,424,166,850,978,408,449,286,764,897,248,290,474,177,691,51,744,643,943,144,316,867,924,245,274,203,779,561,594,269,341,782,387,811,26,371,199,175,982,790,9,5,204,294,283,315,478,820,989,135,701,943,561,301,329,19,375,690,45,146,423,734,510,406,216,335,624,917,278,996,270,745,426,662,87,333,464,139,516,693,303,117,284,811,514,678,548,470,293,572,767,389,30,431,455,771,935,382,406,524,184,733,995,706,291,487,108,576,542,873,908,515,770,775,790,720,954,931,528,440,755,546,831,357,555,474,507,803,997,277,715,6,228,857,143,566,583,330,364,144,406,836,739,446,896,414,883,44,124,476,677,959,992,832,295,798,144,756,665,83,404,31,594,52,322,106,922,831,845,376,347,855,455,434,473,488,289,967,144,769,992,788,583,890,351,558,506,456,107,256,499,47,970,942,741,297,763,235,809,420,941,911,88,925,630,882,997,27,594,169,640,262,11,984,614,145,330,885,924,907,306,210,356,264,889,508,38,80,880,360,212,475,664,461,734,236,708,56,174,661,381,106,71,729,395,431,623,627,854,349,147,563,544,427,530,630,386,492,914,867,671,784,356,567,397,470,924,36,147,577,412,839,167,511,228,849,737,590,758,659,543,623,34,963,476,748,552,427,956,597,718,416,161,500,664,412,353,324,50,591,118,255,551,371,30,489,201,208,210,520,546,491,392,272,570,747,664,122,66,817,913,51,754,571,975,199,130,802,217,525,766,386,529,891,513,336,238,310,849,726,76,488,612,389,156,360,327,343,776,285,362,980,532,136,710,873,447,577,750,499,784,255,276,118,546,903,213,832,512,483,243,154,250,702,275,2,820,355,291,532,425,258,243,592,100,914,331,358,893,241,465", "955,207,428,752,416,666,693,186,359,951,964,784,612,490,182,917,706,965,549,700,416,657,789,937,995,381,144,709,723,423,218,96,44,505,942,869,359,836,623,549,364,7,929,223,735,319,99,792,9,481,444,333,247,912,295,231,932,114,746,530,313,373,879,321,410,642,115,891,182,721,597,106,66,960,171,507,695,681,944,94,317,361,549,664,639,327,409,661,773,4,64,516,447,39,264,135,72,577,125,869,893,945,706,480,721,943,889,389,18,559,336,959,506,714,680,0,359,219,153,117,569,584,600,387,533,868,299,377,929,278,591,566,756,79,577,38,682,125,857,746,811,464,261,904,913,923,845,832,411,368,89,940,971,920,581,319,223,800,268,593,646,249,992,758,431,637,591,76,35,893,857,859,667,324,347,824,115,202,853,20,955,750,2,969,132,928,808,898,306,826,42,612,722,711,841,564,366,786,831,209,71,739,916,26,229,872,236,191,635,419,222,522,689,1,499,998,978,707,523,410,667,57,460,936,899,752,682,502,100,21,775,530,681,130,265,541,586,936,872,126,503,174,604,257,314,34,728,614,812,218,187,163,949,100,997,977,832,310,15,847,370,878,278,721,127,345,4,815,483,167,631,198,939,201,457,278,291,662,585,159,217,605,989,661,537,347,94,74,702,974,226,245,140,58,540,789,624,918,25,132,904,308,211,398,856,193,986,317,288,581,122,866,919,315,528,759,524,940,637,55,989,642,827,994,738,301,733,204,887,671,351,196,651,595,890,544,655,129,845,991,905,547,202,956,369,561,502,132,121,480,410,296,596,336,917,816,919,852,787,895,569,307,810,382,732,226,920,339,368,503,529,983,203,793,283,569,554,123,725,134,231,310,361,812,925,855,126,840,43,299,301,515,516,161,837,364,694,431,602,70,304,636,871,907,237,554,33,126,262,762,405,979,678,246,570,371,438,846,577,361,654,536,423,359,47,299,656,520,53,992,574,229,249,61,773,164,252,277,75,666,207,563,853,502,96,556,911,352,189,526,179,307,612,884,797,125,87,65,137,214,150,85,786,864,950,402,122,563,668,465,890,176,289,554,836,812,781,929,235,854,489,74,278,184,877,805,320,784,949,655,33,173,176,694,845,306,463,86,867,93,758,612,180,831,999,636,781,519,32,401,548,72,517,486,80,188,140,487,742,523,774,350,192,182,728,39,314,174,375,351,117,971,36,193,631,323,68,222,291,176,182,316,747,765,639,689,412,482,365,496,117,406,943,53,311,505,739,43,872,411,787,56,21,194,499,90,7,626,207,675,164,24,771,767,743,668,977,868,484,455,975,523,305,735,516,78,727,910,775,867,846,902,694,650,685,177,159,459,989,252,700,590,746,625,308,934,689,357,909,844,599,587,266,265,752,686,964,325,686,884,924,422,793,851,590,209,444,600,517,995,444,974,22,568,939,154,542,670,270,346,328,718,467,457,297,968,428,449,93,767,100,155,417,959,909,712,308,153,954,218,555,316,906,805,680,861,292,611,472,550,217,716,728,20,308,442,647,748,323,918,852,345,599,234,577,931,685,56,343,540,725,23,801,595,610,936,522,761,773,135,7,243,805,407,527,835,669,729,39,253,474,910,119,212,79,338,50,662,649,346,240,647,556,161,327,747,360,222,887,575,449,168,173,182,369,862,211,455,204,556,707,508,323,11,637,598,369,28,683,780,84,126,799,421,100,50,515,90,979,523,519,182,965,548,155,615,75,29,596,300,420,800,630,303,848,117,503,768,253,485,265,205,62,261,802,86,785,893,732,429,665,115,819,58,370,997,62,543,470,904,598,317,237,982,73,65,918,649,866,205,70,892,557,661,865,527,749,154,787,690,154,19,245,412,100,321,562,283,116,312,864,888,855,256,147,521,834,161,258,765,494,430,204,276,752,266,783,252,954,630,969,787,96,28,799,297,990,676,325,422,208,201,516,732,948,239,837,381,173,612,918,643,71,480,684,3,449,527,713,409,719,48,814,164,949,503,424,649,181,258,438,809,513,445,626,911,685,806,607,448,892,662,86,949,29,25,107,863,958,288,713,989,947,347,46,977,920,427,49,559,58,674,46,774,856,391,669,467,619,556,597,757,429,620,447,64,735,498,809,343,607,635,253,779,568,691,592,894,953,796,405,517,770,711,283,853,187,571,402,73,603,923,380,345,578,551,686,453,111,53,565,610,497,223,632,407,53,212,12,158,883,10,703,325,487,343,309,500,711,34,248,964,407,595,344,370,711,945,827,187", "883,833,625,408,381,716,358,921,99,242,466,547,906,33,994,621,910,898,602,642,680,106,343,118,974,582,773,7,662,564,625,833,226,78,767,318,904,573,742,341,350,362,920,898,219,492,71,411,535,814,684,454,565,323,983,699,290,41,456,749,142,948,609,783,58,819,458,980,991,712,105,373,325,589,813,11,693,351,558,901,685,103,453,289,31,315,498,156,167,804,179,503,995,311,865,428,470,450,921,573,204,559,490,248,353,863,519,417,726,562,970,901,181,754,950,359,0,787,956,232,426,379,408,185,693,517,181,863,170,443,486,90,660,840,405,432,148,888,950,899,67,423,847,913,923,832,457,561,236,544,400,734,744,26,91,582,887,654,693,449,423,117,510,326,794,742,502,193,452,107,473,839,561,159,890,947,371,802,756,218,291,188,686,71,504,450,776,719,290,16,819,795,892,67,82,374,318,614,410,980,391,635,911,197,75,250,177,960,604,837,677,793,8,252,169,411,92,535,452,860,520,95,24,290,59,416,829,119,49,734,96,367,301,872,360,347,101,681,167,886,29,156,123,148,840,132,357,12,719,828,963,618,76,680,350,69,975,581,147,249,744,340,442,900,857,334,110,378,394,850,636,207,718,554,298,722,827,692,837,852,840,786,603,896,153,850,314,10,60,80,671,226,507,713,822,673,646,278,268,641,234,145,518,819,100,428,96,338,810,659,61,423,711,96,190,964,96,757,862,321,426,518,220,428,786,898,984,179,221,992,23,811,713,519,869,775,959,693,728,62,60,452,820,735,579,878,443,598,387,938,486,619,269,674,505,256,705,6,619,395,836,515,192,5,591,640,724,490,502,821,742,630,802,476,150,446,725,270,812,99,7,653,247,186,326,896,45,386,439,566,743,261,177,633,431,250,1000,721,218,235,432,298,502,633,377,342,151,547,120,253,760,860,358,393,340,593,803,61,806,815,981,949,614,543,444,607,870,64,961,860,971,575,263,861,698,372,634,868,338,591,30,908,481,998,165,411,813,375,67,338,322,49,586,122,16,921,432,328,344,730,232,36,595,268,799,225,97,650,957,125,735,411,810,115,687,5,956,630,284,237,747,728,395,673,359,913,175,105,668,121,641,255,405,330,319,158,143,986,881,299,761,931,359,553,521,429,677,40,883,427,895,912,142,254,717,562,185,994,356,333,405,963,960,489,1,187,6,94,706,296,47,943,121,921,832,294,274,984,510,136,825,354,549,624,966,901,253,699,819,32,912,658,622,370,287,464,608,193,747,381,310,723,166,127,389,79,504,52,66,674,735,455,494,351,891,425,847,946,943,845,549,21,82,840,910,703,781,556,902,181,306,891,838,461,333,908,817,675,665,529,755,623,824,834,633,362,431,851,587,99,977,213,608,41,423,651,775,708,175,299,15,165,582,959,567,492,713,284,294,163,219,493,994,212,94,704,883,54,579,554,335,593,513,597,36,423,43,43,845,891,221,740,587,61,639,432,299,320,891,729,702,761,37,629,159,66,609,605,622,180,510,151,632,816,465,550,378,814,485,585,250,97,553,530,81,410,619,822,533,436,416,607,766,663,984,530,952,292,225,103,945,908,623,167,83,474,658,251,474,224,577,525,148,532,534,648,989,646,297,941,738,124,562,646,857,209,705,170,684,63,261,322,102,285,582,138,781,435,473,547,987,781,404,78,9,734,172,195,549,183,840,575,774,250,581,866,541,442,159,466,515,875,173,951,784,723,972,623,49,358,189,960,730,362,869,768,858,728,937,910,351,696,209,445,894,662,657,985,935,200,399,673,977,955,378,466,785,598,114,922,398,274,174,707,33,296,272,948,385,597,336,639,40,308,138,909,323,278,339,842,907,358,850,314,987,141,947,979,490,253,342,361,498,127,735,892,493,137,367,676,92,353,398,344,360,618,58,424,273,377,694,988,476,751,200,478,699,687,484,861,397,305,126,595,760,7,615,456,429,725,763,786,3,536,713,549,499,519,884,793,719,659,415,871,513,749,249,698,760,48,336,18,163,6,997,833,767,46,342,56,833,238,653,338,264,867,699,358,259,12,924,437,348,77,274,129,982,80,45,647,697,81,684,790,321,15,608,444,733,694,549,33,173,52,599,203,315,997,439,72,870,461,186,72,730,636,162,751,529,571,433,170,898,156,643,371,906,990,913,367,966,347,655,87,471,784,489,759,355,3,927,420,574,214,375,971,853,738,913,101,329,129,327,725,135,272,440,32,893,385,690,216,476,27,958,450,81,200,912,269", "353,719,275,597,553,671,960,931,179,228,734,601,609,703,518,68,302,820,81,531,41,126,46,925,872,245,328,718,953,10,702,252,805,651,277,236,330,553,854,1,759,876,15,412,290,302,353,968,55,122,486,82,334,144,25,199,403,630,369,306,513,908,894,24,578,199,522,683,492,100,481,924,3,602,203,774,121,265,441,179,633,237,243,395,686,801,832,321,876,6,211,959,366,31,705,352,50,486,4,671,347,916,438,184,374,861,697,558,457,183,379,473,193,525,959,219,787,0,183,781,719,562,779,743,353,546,274,952,546,371,160,283,630,698,5,277,682,368,973,705,276,377,533,644,688,70,844,952,171,278,988,919,695,119,909,26,844,993,184,177,712,651,289,131,184,364,773,255,411,215,512,31,580,906,791,956,508,770,757,838,776,417,138,482,341,333,101,30,805,389,488,758,437,161,731,392,694,183,46,395,244,766,806,228,680,79,380,316,845,649,272,597,622,449,758,765,447,355,663,210,868,49,262,475,237,832,812,266,500,465,530,447,919,776,426,323,38,816,726,514,577,267,143,765,741,240,123,781,402,793,298,977,432,19,33,947,937,699,725,976,216,693,56,346,853,113,275,863,7,494,273,962,61,497,170,666,541,234,867,687,449,1,275,752,895,547,263,37,979,417,149,263,381,41,702,697,89,16,647,214,281,542,712,194,149,760,976,14,604,75,581,200,268,586,62,274,249,948,146,946,856,837,124,810,416,450,133,317,71,135,553,712,762,118,198,828,311,830,602,294,515,242,801,296,243,894,193,383,994,494,888,899,954,856,18,293,476,663,909,234,574,182,881,359,3,175,508,75,259,994,110,36,515,260,556,416,536,449,541,924,376,116,268,917,900,690,217,360,37,307,665,314,708,909,341,504,52,990,254,41,979,463,624,969,678,750,867,357,80,32,209,57,49,474,392,12,374,841,789,132,500,966,824,363,127,137,373,664,273,659,923,932,902,158,52,469,606,640,587,6,675,138,321,795,315,324,735,804,175,660,231,908,53,979,646,508,688,222,169,454,49,482,826,307,472,787,749,131,372,794,189,47,93,760,698,651,734,222,312,119,722,566,522,288,486,311,614,713,637,793,547,679,420,478,754,714,139,501,5,83,375,186,258,544,917,119,220,939,268,833,560,800,131,503,855,998,273,48,313,969,845,928,169,330,990,291,838,387,635,712,181,857,224,271,256,235,189,599,84,841,182,675,227,375,266,947,261,471,614,928,584,88,940,118,567,193,856,15,507,198,7,239,659,773,628,71,529,233,562,124,209,142,446,525,238,301,477,821,604,924,719,288,873,959,426,957,61,770,768,856,423,568,521,145,258,136,776,726,138,512,274,807,470,52,469,651,674,494,657,991,615,939,617,643,425,362,636,530,284,446,441,966,557,348,656,655,251,242,916,449,414,833,675,659,320,787,60,914,891,989,402,295,956,740,807,414,160,925,186,78,754,35,392,520,214,220,263,233,72,655,480,645,208,700,265,618,426,563,422,69,275,667,521,91,4,970,452,154,548,972,314,374,199,719,520,901,549,141,863,309,11,682,169,803,544,541,99,956,266,356,864,59,331,34,394,197,789,953,671,901,60,874,153,668,909,865,574,248,180,385,934,589,584,215,468,989,982,326,461,64,621,880,683,920,385,723,159,461,875,908,63,315,133,458,182,440,254,289,852,714,504,617,995,581,76,598,562,141,340,427,582,284,88,129,397,552,657,313,473,241,980,89,728,31,985,322,440,911,360,157,950,960,981,714,603,960,410,18,857,726,911,405,590,333,480,782,644,880,601,353,992,335,108,93,179,832,844,410,177,564,336,546,385,5,454,679,283,542,309,934,225,381,928,373,132,566,740,185,37,380,795,401,347,293,354,782,316,613,499,697,989,158,949,420,347,779,858,191,116,381,499,394,487,76,620,759,278,729,481,23,717,196,767,979,225,471,838,634,23,634,362,298,592,229,892,537,892,425,861,698,244,161,607,220,660,998,478,323,775,461,501,336,92,636,588,381,656,855,992,603,755,738,958,994,219,260,991,14,412,339,380,3,226,12,589,649,623,689,806,851,670,649,445,151,196,815,752,913,311,388,225,888,577,366,111,498,334,911,893,67,169,428,808,859,916,285,760,591,693,12,986,210,551,141,959,662,899,264,851,485,754,524,794,238,62,380,655,490,480,219,390,756,944,926,63,596,408,529,980,70,189,14,750,229,540,605,503,604,501,340,581,313,627,81,402,307,619,289,23,872", "452,607,207,866,441,842,799,876,420,42,815,9,671,725,499,359,52,698,464,578,630,249,735,814,463,543,959,443,613,117,726,15,953,860,967,340,606,460,256,695,154,613,6,360,502,645,800,855,964,73,812,494,375,814,575,348,920,266,438,570,590,807,246,670,467,920,55,410,793,627,569,600,38,805,666,82,988,84,854,486,732,125,542,807,155,718,706,473,887,914,351,560,420,597,837,184,670,356,316,895,983,630,358,733,409,137,308,67,887,927,551,351,957,439,533,153,956,183,0,667,459,600,223,840,142,263,315,93,953,535,498,515,813,481,538,374,153,376,220,128,756,144,629,718,111,977,688,179,291,489,634,494,535,330,561,355,651,511,951,827,209,83,701,729,893,974,339,657,459,21,234,238,482,490,619,566,721,820,534,359,272,579,849,315,467,947,560,290,646,931,752,34,578,810,388,56,468,136,905,389,281,507,713,507,998,747,944,313,380,445,916,222,918,509,320,46,87,62,603,158,567,70,407,289,55,379,16,81,89,459,395,937,250,282,537,242,988,412,320,808,609,966,978,530,184,647,427,6,136,866,107,593,850,231,425,424,166,96,288,867,584,77,523,612,844,256,892,58,837,970,42,550,885,240,568,258,364,802,733,45,245,735,586,698,505,535,333,476,876,723,171,955,796,778,536,948,974,500,18,972,424,513,84,687,107,518,358,796,477,111,98,790,72,138,600,645,987,662,178,885,953,662,326,300,770,250,506,939,872,344,816,505,185,347,220,542,559,413,295,111,135,318,246,636,372,68,317,278,775,676,542,666,75,60,260,962,910,593,146,43,689,875,84,656,157,593,165,139,944,519,921,484,598,391,730,314,203,918,795,86,523,436,232,251,35,654,340,378,614,333,390,117,975,808,8,231,394,412,784,127,373,526,428,193,848,935,770,566,716,410,273,84,888,1,816,627,408,556,144,600,289,183,640,728,233,184,106,569,355,502,772,200,543,118,100,648,452,580,536,200,233,137,602,913,365,642,612,9,931,509,536,997,133,85,34,457,910,504,11,674,385,624,276,449,175,445,537,460,328,703,55,36,515,115,548,924,472,442,133,219,882,343,439,778,62,822,412,418,138,381,779,309,216,429,490,111,115,482,736,36,200,534,31,643,214,352,554,807,930,476,762,725,130,886,123,517,913,73,16,114,538,450,434,806,503,210,510,883,624,800,346,302,128,328,177,884,989,189,774,931,299,127,605,748,638,165,124,750,84,824,492,830,754,755,816,103,695,772,935,985,391,623,971,565,56,372,670,985,744,349,628,428,355,794,581,61,69,344,195,700,488,18,104,241,833,148,952,515,224,283,698,137,944,12,657,153,86,612,157,741,335,959,126,697,873,622,153,856,708,355,826,101,45,471,173,28,220,142,442,629,327,268,509,192,73,312,454,613,908,180,499,356,131,398,2,49,546,665,829,896,798,848,815,553,937,181,117,96,491,57,756,818,323,302,211,152,986,3,987,885,65,403,342,556,18,823,673,518,221,277,662,762,886,384,430,333,124,569,441,669,641,295,354,997,518,55,218,583,168,688,565,134,428,329,720,926,460,715,217,214,514,187,476,966,877,330,442,974,514,819,503,70,973,950,363,593,170,692,969,999,570,181,481,518,764,830,800,121,585,918,707,652,469,721,297,82,164,972,746,167,287,756,353,507,549,838,600,62,299,999,421,179,870,740,256,348,556,815,971,24,949,820,623,397,51,35,597,898,349,180,784,616,913,489,690,870,247,941,140,290,32,720,920,367,677,760,909,22,117,23,419,572,866,325,41,548,27,191,992,838,543,664,138,939,711,796,170,785,947,666,645,833,277,7,676,114,493,234,743,360,912,592,711,552,560,623,258,443,291,516,755,409,358,803,283,875,628,141,360,194,275,523,75,964,852,441,924,586,334,356,325,999,62,295,302,965,236,86,399,206,612,391,952,2,909,677,531,594,239,818,22,855,448,875,490,150,681,737,211,425,439,823,856,919,326,948,964,22,711,89,974,70,371,679,989,5,532,631,329,713,941,12,50,680,639,605,109,862,463,338,199,972,230,85,525,681,842,322,298,595,601,892,937,624,264,719,434,441,745,937,56,884,447,24,147,655,293,937,411,876,358,635,523,14,75,434,756,579,648,645,768,245,208,69,649,98,111,647,984,802,780,975,591,76,109,896,334,83,788,354,896,735,612,920,669,244,387,660,90,299,709,559,109,881,849,351,683,585,491,383,54,708,31,757,788,391,444,98,183,433", "60,546,176,425,433,659,544,323,502,758,262,771,520,50,509,325,414,4,431,329,967,429,217,228,308,981,458,21,751,149,258,311,195,995,502,946,681,908,787,160,443,569,886,848,515,746,267,884,816,153,16,372,372,918,424,438,85,460,949,98,839,788,662,699,450,900,249,870,382,219,10,111,975,500,937,422,832,924,547,950,178,501,107,193,147,25,134,79,790,77,665,697,993,366,607,668,32,812,624,684,826,417,742,219,547,928,863,124,925,753,52,332,399,820,686,117,232,781,667,0,312,597,977,269,38,42,77,513,358,508,510,497,482,390,911,58,245,336,933,175,585,986,509,648,83,254,332,271,223,400,457,387,570,38,327,560,237,489,426,98,43,584,389,573,111,257,642,859,933,630,384,283,771,431,281,360,764,240,112,976,466,404,89,20,316,923,876,808,554,596,461,533,393,710,885,684,55,597,717,961,786,545,521,966,386,901,996,783,226,169,905,366,768,460,531,969,477,284,603,396,994,520,375,667,473,601,329,94,674,802,972,314,976,437,170,631,501,614,973,830,845,579,120,448,746,928,21,318,361,522,48,853,899,545,660,91,12,374,905,67,682,834,273,233,493,143,834,293,169,133,708,201,694,565,939,257,401,45,624,136,367,566,296,957,34,890,259,311,301,927,387,786,610,571,104,597,463,517,104,557,693,577,387,691,686,395,722,550,620,130,726,415,469,371,934,695,958,867,84,937,393,829,994,869,939,62,464,186,465,558,796,262,802,29,518,15,785,805,838,813,484,995,893,195,513,608,362,843,267,102,680,197,674,46,662,249,166,360,873,247,272,106,842,197,916,479,338,87,19,576,477,481,338,99,67,917,548,652,249,613,686,660,335,382,124,408,889,265,123,815,475,613,32,783,316,950,338,547,399,485,675,696,488,393,903,731,547,564,821,292,226,925,256,51,536,637,582,191,968,352,997,961,324,458,915,575,422,880,57,636,36,927,536,757,665,682,917,367,658,753,658,332,158,516,608,186,884,735,822,273,559,356,393,581,735,13,234,138,860,750,507,120,456,141,790,682,843,343,603,810,116,535,412,438,697,342,264,555,758,24,693,472,62,801,19,830,292,948,810,798,42,325,621,520,240,541,246,638,332,906,102,384,811,380,462,215,455,945,666,511,662,254,730,801,950,86,155,906,238,589,503,471,493,392,482,324,64,58,352,39,37,44,623,987,251,65,168,714,431,165,668,973,987,796,500,731,485,90,159,210,478,840,623,541,726,310,846,545,670,973,641,58,391,525,285,154,107,557,391,937,340,398,751,135,161,161,56,79,68,289,899,494,665,611,474,542,436,997,326,457,952,553,622,152,418,17,545,847,220,996,74,283,78,697,116,533,142,765,553,340,903,850,736,667,543,893,642,420,193,619,592,342,451,579,496,508,19,327,687,659,191,221,993,683,47,316,91,814,980,542,873,127,443,748,363,838,409,112,591,56,248,200,847,73,561,263,180,912,320,651,327,194,427,308,331,741,658,918,985,571,213,34,984,198,392,806,329,547,299,158,728,773,10,262,625,687,260,187,706,537,679,777,69,63,914,784,845,531,171,831,372,297,383,925,722,117,793,657,364,455,120,344,907,299,225,326,299,886,908,277,99,712,895,684,261,644,854,151,566,652,620,3,758,555,454,867,69,66,384,214,252,288,812,703,745,929,599,420,431,839,324,784,576,673,398,208,425,477,285,500,565,941,929,890,783,969,621,150,940,256,554,752,440,379,636,597,838,134,269,770,307,162,263,466,617,291,378,148,323,889,357,779,153,919,197,871,908,746,124,405,205,162,209,3,84,509,626,463,254,444,272,323,580,26,213,895,37,77,240,216,350,835,179,341,577,787,219,810,304,993,575,712,978,528,21,768,322,746,48,979,553,798,183,946,545,767,719,931,977,930,904,344,487,690,845,666,151,875,873,237,232,409,743,944,24,788,155,55,332,928,250,682,9,833,482,140,314,71,11,146,480,682,376,317,37,428,384,811,846,524,29,47,980,797,430,455,322,845,446,911,683,998,547,982,99,627,745,228,97,809,979,648,35,548,217,103,264,991,172,272,819,638,351,898,187,357,393,534,948,64,319,677,830,927,319,74,720,397,496,732,763,671,72,664,652,937,36,3,763,106,197,453,601,35,923,617,694,230,500,379,62,661,343,875,924,678,46,41,135,156,806,426,26,197,205,775,285,475,692,293,125,237,253,905,281,93,448,289,973,341,705,261,980,617,421,324,362,307,403,387", "588,124,190,684,689,288,434,98,390,301,678,828,52,816,225,958,824,113,306,172,818,978,305,708,855,2,356,734,162,858,854,587,672,598,698,633,744,702,946,119,210,155,947,981,497,643,616,684,134,324,956,879,734,173,496,318,919,845,202,706,453,722,317,985,275,47,966,635,239,810,958,154,135,752,857,966,931,55,784,685,980,810,414,722,447,312,612,25,317,465,704,835,193,127,591,91,76,48,452,340,904,38,16,739,745,831,901,461,242,166,182,92,236,122,870,569,426,719,459,312,0,723,393,838,654,968,431,402,678,605,56,110,64,492,615,27,187,135,42,207,8,848,785,751,838,49,179,504,884,110,481,559,697,740,69,146,130,54,469,978,282,845,96,847,216,844,30,398,196,35,576,494,833,368,541,463,585,480,636,243,925,821,452,663,618,973,320,446,900,198,290,56,379,363,901,928,604,741,633,982,691,968,410,997,381,160,85,882,521,603,630,860,381,2,233,885,242,352,518,315,688,992,604,590,5,859,493,328,467,596,815,274,265,326,154,360,675,577,727,661,471,176,775,952,142,597,885,576,492,517,424,218,694,110,439,565,791,212,856,654,710,793,38,533,959,716,483,478,235,123,21,668,200,636,134,300,756,929,884,185,701,903,60,626,803,811,841,280,382,621,399,5,922,866,725,880,712,22,108,424,221,412,591,59,857,792,885,858,629,318,488,706,426,29,105,273,665,691,259,413,37,969,333,958,946,370,394,2,448,781,709,871,179,195,356,859,293,348,448,323,325,259,645,545,255,716,746,631,216,304,947,727,304,869,263,63,671,238,259,133,589,268,964,831,822,189,479,913,935,2,537,29,708,783,628,140,23,426,924,885,350,816,380,52,60,566,765,626,405,135,211,453,659,853,654,431,607,679,597,770,828,760,626,861,77,659,667,41,194,14,905,932,856,997,677,37,140,922,677,890,171,636,475,757,596,156,33,950,617,349,227,338,2,278,89,916,931,728,51,532,741,87,856,893,850,993,924,3,993,860,743,440,225,462,431,369,155,846,651,246,614,435,148,929,176,951,366,176,572,504,747,132,354,359,794,52,897,339,921,566,735,47,72,336,14,178,358,805,576,188,48,188,928,861,973,579,727,183,834,815,954,236,200,298,873,198,587,750,11,973,209,553,848,565,609,858,210,823,578,636,247,123,213,911,629,21,275,890,214,19,217,555,672,123,752,107,138,426,934,696,584,56,220,568,868,283,739,154,430,343,337,964,998,111,889,305,901,694,446,509,207,574,758,389,415,503,403,377,681,849,826,864,637,936,642,559,79,632,819,400,722,733,612,716,274,608,359,240,389,392,410,700,82,662,255,745,99,492,70,612,645,585,270,255,769,870,520,139,259,808,656,663,699,915,524,252,899,479,400,556,982,499,303,199,548,645,887,655,508,483,103,590,693,66,30,255,716,774,677,190,519,419,180,3,740,342,79,695,315,203,866,685,348,998,637,704,462,425,56,441,461,873,803,449,633,826,757,156,208,588,781,528,683,40,699,153,483,446,378,370,779,641,718,636,936,424,103,925,336,608,754,682,936,142,770,722,227,701,479,363,44,811,799,256,391,346,493,55,364,991,680,700,418,844,737,676,981,771,28,786,745,732,16,86,900,936,998,507,493,221,927,409,725,870,659,611,111,891,161,352,227,706,157,181,716,26,551,576,865,888,331,839,185,698,138,505,125,895,171,185,7,426,108,78,766,834,109,242,944,88,514,25,489,4,794,336,286,420,467,88,303,117,985,717,159,503,402,975,473,800,354,376,389,617,363,642,917,571,631,899,445,373,887,166,96,820,50,263,185,433,277,616,651,159,222,910,928,185,121,356,253,631,619,592,917,453,609,194,846,550,821,305,206,215,292,968,503,985,638,989,63,161,965,816,411,476,584,596,77,418,891,918,890,502,226,740,571,210,827,707,101,828,166,992,467,353,658,493,872,822,979,152,579,966,323,341,196,140,235,718,210,135,384,8,846,584,164,375,446,312,207,317,546,382,85,202,827,142,667,864,899,639,809,129,714,103,699,332,730,732,152,179,770,956,134,828,526,285,768,409,80,572,306,621,260,158,111,549,400,467,127,672,353,754,827,24,397,60,405,126,941,226,39,889,687,276,680,477,46,820,842,924,255,964,469,777,616,692,380,122,537,709,638,721,50,474,202,327,250,919,598,748,812,523,286,785,774,463,371,133,417,251,951,24,216,735,707,639,517,251,447,906,940,869,300,23,163,74,517,560", "87,719,881,790,677,987,865,161,842,431,553,645,952,160,150,922,800,969,133,337,424,814,918,664,342,372,211,858,227,617,738,663,191,567,262,363,702,707,953,462,805,380,37,544,80,244,256,279,606,801,229,364,723,825,669,999,591,710,442,85,376,477,630,414,955,848,667,749,354,794,238,596,330,158,429,637,887,218,202,330,278,715,204,420,276,9,181,995,432,983,643,697,878,331,828,656,62,528,246,257,208,274,448,888,739,670,346,641,201,827,973,357,695,158,199,584,379,562,600,597,723,0,297,730,890,770,180,605,699,195,299,301,38,756,516,733,610,432,590,883,318,471,770,820,952,545,418,663,525,399,490,972,261,605,106,913,457,675,97,236,594,116,700,208,959,178,144,167,393,638,964,890,248,915,746,971,441,876,11,218,770,410,850,386,502,938,263,92,413,271,179,252,656,230,650,913,609,136,618,970,904,792,80,622,722,257,906,434,625,858,71,363,615,437,461,953,941,119,618,70,139,64,844,537,729,538,852,14,531,489,518,635,179,941,5,217,150,250,819,957,693,333,423,209,385,375,820,310,770,851,409,102,743,535,611,958,330,59,75,99,614,547,660,225,577,487,247,820,372,682,687,207,583,378,44,744,287,78,543,983,170,138,265,486,381,485,107,324,655,589,744,294,163,689,910,919,338,387,21,613,926,297,412,116,516,481,947,220,78,619,226,56,693,555,570,673,158,350,568,775,154,476,789,946,437,204,465,329,706,334,100,930,488,223,534,204,843,31,888,789,691,455,721,895,741,248,546,307,88,572,69,336,951,638,432,773,299,664,146,204,104,405,243,652,866,350,466,416,590,317,652,646,288,422,84,780,609,237,177,992,583,959,416,994,630,112,657,807,894,945,76,362,600,787,842,847,793,816,940,890,278,625,811,64,450,279,936,223,229,201,7,305,674,765,791,42,945,439,466,346,733,285,310,232,959,270,260,392,863,206,754,991,468,157,828,546,370,801,635,82,50,735,411,133,653,412,931,814,447,991,87,907,41,132,503,45,836,691,439,528,796,750,702,844,853,36,253,699,367,483,316,655,647,764,882,933,768,775,776,975,721,863,141,677,484,725,470,127,471,773,531,512,546,587,699,561,195,845,261,594,617,85,105,592,948,723,948,643,13,313,362,656,107,35,58,975,87,872,101,344,38,346,98,589,34,917,450,837,334,166,461,80,357,948,611,930,778,116,484,984,737,776,567,22,525,237,102,210,370,521,169,504,141,932,327,194,49,94,164,833,529,810,822,983,95,727,304,707,146,167,48,733,411,48,863,438,802,315,657,6,243,430,556,644,285,184,813,438,17,561,491,832,983,898,947,862,947,404,592,339,787,526,854,836,11,621,405,61,301,151,531,355,328,153,465,466,684,847,261,453,531,572,110,546,932,497,682,381,689,990,359,67,381,665,668,970,793,937,884,780,542,445,222,175,547,509,130,693,394,845,411,555,565,936,590,857,981,999,377,365,814,202,244,507,289,668,372,927,809,571,301,106,742,691,785,629,370,39,100,413,816,685,318,642,237,294,434,384,66,742,185,256,510,934,178,390,177,317,639,24,731,537,733,845,923,714,228,111,103,843,529,986,13,278,384,171,177,89,284,70,720,253,282,466,652,434,422,359,128,813,286,664,150,175,687,992,661,300,609,497,161,826,538,336,522,62,510,695,523,589,342,585,636,610,602,742,240,100,61,814,472,541,394,65,833,214,764,793,302,868,131,478,973,331,611,29,850,296,894,92,157,718,617,975,913,473,881,102,916,67,880,138,390,625,237,634,935,334,827,298,403,516,812,157,582,829,650,881,402,595,844,64,2,623,68,783,699,160,154,203,484,598,634,423,811,661,202,125,865,368,886,663,9,466,250,958,132,889,242,726,323,296,346,666,327,50,134,567,470,282,717,908,115,716,383,679,645,773,54,768,158,345,524,145,381,494,739,905,967,870,874,394,960,947,543,272,849,553,86,333,674,324,43,269,846,266,840,231,6,41,19,82,490,160,851,253,890,304,182,133,216,158,41,430,397,678,235,950,675,8,226,338,408,212,238,271,77,650,392,394,89,914,433,235,807,944,789,382,442,969,933,859,724,244,505,562,71,48,670,129,78,892,748,834,242,957,273,424,368,777,709,318,61,443,337,764,187,32,370,565,475,823,557,630,822,864,132,879,662,798,11,322,285,479,839,270,10,483,28,173,430,336,485,443,252,177,73,365,490,791,55,648,175,528,198,644,139,141,838,262", "109,555,447,475,393,558,975,612,589,961,703,421,506,609,547,438,383,362,576,815,474,474,288,236,277,612,153,543,431,681,383,328,493,167,332,712,713,778,811,297,254,962,423,83,938,891,134,183,246,623,834,363,188,940,414,24,32,947,676,929,659,588,920,959,520,2,122,279,602,526,811,911,507,390,295,573,399,37,637,703,645,225,484,84,306,853,94,376,456,909,147,760,528,880,100,370,624,589,758,896,302,383,74,61,311,682,17,290,502,862,956,574,841,840,372,600,408,779,223,977,393,297,0,984,986,109,878,308,384,926,192,425,187,55,993,393,374,862,550,241,372,922,641,301,468,440,844,72,577,847,938,547,10,406,868,329,223,919,991,90,733,16,694,119,651,436,817,257,639,173,831,885,51,938,303,626,936,942,233,522,425,327,491,916,238,671,977,976,785,274,451,785,240,691,939,501,905,101,698,96,402,359,730,291,622,392,783,189,27,771,12,528,681,115,726,728,936,841,476,41,339,143,464,619,699,604,359,878,370,406,211,287,661,521,553,463,363,326,128,895,200,68,347,164,947,379,784,23,857,712,395,579,720,340,514,214,23,880,645,261,333,707,64,175,234,325,20,927,82,164,266,564,851,54,681,2,535,468,573,861,709,709,981,794,123,781,704,869,240,893,687,447,897,120,893,419,168,280,582,749,519,880,382,670,618,347,933,275,342,840,544,425,687,958,804,182,176,366,787,747,76,903,934,31,737,56,208,398,618,961,926,394,911,876,851,772,684,504,690,972,996,633,736,991,491,780,654,259,161,456,345,369,700,608,694,829,165,538,665,515,618,853,333,399,665,108,399,964,989,108,469,793,454,256,483,635,185,577,1,780,314,333,738,691,424,821,537,263,414,556,860,347,517,769,375,500,845,694,293,871,531,191,382,176,746,801,105,716,163,820,291,360,334,778,890,716,141,584,745,996,831,48,387,678,670,232,455,700,668,303,227,728,16,927,68,599,551,996,858,468,713,917,983,999,686,264,249,105,87,361,914,494,554,802,931,634,84,581,160,896,103,293,16,113,250,277,980,550,462,823,86,840,799,714,669,890,636,366,702,440,50,951,807,8,830,751,793,816,681,44,335,640,919,579,944,765,89,224,764,322,346,566,216,538,100,835,118,167,303,657,670,975,805,540,104,422,893,844,32,464,105,257,192,137,471,663,708,496,803,187,581,49,265,966,73,406,535,502,136,429,899,394,700,677,982,840,156,769,216,216,725,389,474,693,100,417,970,731,272,107,476,756,21,35,784,189,446,316,970,135,779,104,647,443,813,624,552,779,985,264,17,831,318,283,169,99,334,136,322,970,980,146,827,94,337,202,343,955,254,212,470,28,73,356,533,331,785,479,689,524,366,511,27,555,285,708,400,459,796,631,627,60,392,666,364,862,914,529,32,559,774,712,435,584,917,965,97,713,674,938,969,972,894,829,77,724,517,436,337,541,356,126,166,540,351,578,810,896,214,567,362,200,636,356,7,512,421,213,91,704,890,99,475,640,999,201,492,743,830,328,134,955,854,70,220,329,45,481,917,389,674,465,426,492,530,313,857,133,912,846,680,417,872,499,811,390,674,497,952,951,78,746,501,300,168,358,345,386,893,631,413,740,15,655,534,21,92,164,887,903,933,892,550,608,730,30,928,54,923,855,244,278,662,609,318,236,111,118,706,829,275,395,562,809,497,51,82,278,104,49,796,334,751,616,495,793,96,473,522,355,340,620,183,494,873,585,927,882,446,269,195,683,698,802,78,961,531,426,623,778,400,616,789,711,840,948,256,477,496,980,89,806,32,777,717,322,660,640,487,628,791,633,133,965,811,947,107,496,23,334,133,62,416,568,681,103,282,822,921,616,355,33,60,205,657,993,934,289,181,352,135,302,674,566,787,212,126,821,752,480,313,248,28,181,168,173,159,117,738,433,96,92,606,894,12,197,993,203,765,793,926,159,492,575,132,687,648,169,183,100,165,950,352,55,900,910,301,425,527,797,805,384,256,295,893,430,793,747,252,483,458,468,349,385,61,628,801,146,874,230,961,686,701,22,583,30,148,995,80,120,573,842,368,679,81,538,290,737,446,100,80,184,36,141,733,472,606,170,296,679,689,921,791,5,732,991,321,165,512,710,920,481,770,292,278,650,918,996,894,596,632,121,723,210,399,429,26,118,250,919,827,282,758,491,630,542,93,229,943,360,519,683,586,929,662,252,282,33,55,226,553,172,649,723,993,404,353,583,643,280", "473,154,530,48,767,590,997,366,332,245,270,60,658,225,619,864,176,489,436,560,34,243,22,756,978,111,743,945,233,82,193,258,975,307,135,745,805,893,33,646,580,718,766,625,995,93,286,459,403,257,673,408,809,300,71,584,778,883,163,659,954,432,798,751,18,564,267,427,803,213,705,854,471,648,427,314,544,66,276,857,722,58,251,185,952,623,721,585,387,333,560,916,800,761,516,845,864,534,650,774,533,66,761,31,236,316,599,651,352,772,741,269,854,487,646,387,185,743,840,269,838,730,984,0,820,71,615,595,871,917,404,610,181,698,794,213,924,499,125,967,222,858,255,284,569,88,423,611,237,35,622,210,741,204,564,677,514,945,65,949,687,108,926,184,889,458,617,596,812,187,606,992,903,95,511,926,151,854,834,288,732,770,810,400,110,583,777,133,502,752,715,494,435,492,237,25,910,736,420,7,802,145,788,97,965,75,559,886,348,159,836,802,626,146,650,55,593,727,148,623,12,156,518,753,958,489,7,819,31,836,642,499,768,368,703,185,6,457,382,648,954,921,379,818,846,206,469,283,868,424,778,397,240,765,830,865,168,319,311,245,348,548,478,447,813,631,629,412,887,494,408,618,338,246,584,118,258,657,749,259,489,281,991,146,488,931,316,353,28,671,727,58,414,620,238,662,560,955,351,874,344,579,121,26,413,697,723,676,676,169,940,549,907,416,567,207,917,294,18,510,719,424,32,676,256,453,993,230,800,787,209,377,36,241,926,609,579,623,108,322,601,524,854,872,466,579,950,192,405,915,579,282,100,350,543,140,835,205,479,188,614,443,927,19,760,988,217,92,23,432,361,284,668,126,643,716,967,667,655,612,328,936,606,63,386,49,50,238,609,577,521,938,921,982,973,674,483,566,58,973,587,396,111,556,237,403,545,765,649,172,240,569,592,968,955,481,869,375,774,790,620,795,658,941,805,41,425,541,317,893,735,843,603,869,920,884,912,633,308,52,460,894,731,718,738,571,146,182,866,160,748,708,119,14,644,306,99,264,98,973,175,690,968,7,39,906,921,316,227,413,184,799,550,311,491,23,667,469,227,910,128,861,413,907,827,701,733,558,162,729,69,66,516,974,362,937,8,779,312,898,622,594,188,430,158,159,140,681,952,948,953,159,640,244,808,490,673,506,351,565,6,566,142,972,640,876,471,541,876,471,687,680,766,895,896,684,21,936,204,443,53,115,411,771,996,340,423,216,806,29,76,565,37,688,731,361,224,594,290,531,776,370,533,705,772,927,873,963,458,118,122,939,691,613,537,668,841,483,593,639,231,335,796,816,367,324,928,85,950,168,655,416,837,898,187,782,980,724,167,619,44,676,202,484,751,10,508,952,683,633,904,56,675,923,858,599,70,297,961,109,865,569,979,989,347,987,451,955,749,855,450,367,44,934,37,741,518,238,9,355,415,557,264,829,193,78,984,360,442,903,593,967,230,713,620,38,856,809,837,643,660,391,765,762,427,962,32,621,897,973,382,749,290,997,833,448,823,643,321,290,906,919,584,963,247,507,309,365,517,712,520,579,640,258,816,599,488,43,683,296,294,796,774,917,525,781,110,172,753,533,240,939,753,766,979,329,125,618,642,334,718,469,295,381,342,798,750,665,536,433,633,681,56,361,626,478,931,459,276,203,994,316,171,793,203,733,556,517,674,508,170,960,677,314,155,378,189,394,946,339,245,420,590,355,982,961,786,836,451,779,976,16,754,171,865,207,327,348,673,756,458,769,908,226,205,674,473,275,726,684,451,3,310,449,968,245,583,106,439,818,149,825,336,927,168,195,415,340,406,772,751,525,892,938,289,944,342,450,207,355,155,334,915,121,298,599,284,726,984,224,281,495,879,270,810,882,459,557,231,766,469,668,265,818,51,29,920,823,845,373,273,221,518,452,262,825,389,954,180,647,46,987,184,852,805,884,37,470,885,44,587,643,783,500,279,418,716,50,863,239,792,989,158,983,26,721,186,545,222,668,262,471,974,638,571,233,993,63,39,956,767,585,593,404,285,429,795,38,605,347,866,113,333,245,732,283,398,783,33,601,635,210,467,282,960,611,79,161,391,608,708,721,767,765,386,730,686,559,856,457,590,976,183,278,101,64,594,253,938,122,236,608,201,999,297,332,550,785,251,357,739,363,150,694,878,973,144,444,264,337,253,645,711,875,307,933,816,102,392,335,133,381,168,297,915,135,519,640,649,129,400,302,561,55,886,937,925,483,101,665", "66,264,458,839,8,853,6,943,80,778,455,617,506,428,820,471,913,124,121,18,894,653,68,535,960,950,702,661,863,534,523,236,262,42,385,39,780,600,260,396,759,84,88,335,168,65,153,105,87,410,1000,547,72,552,50,245,886,194,157,440,989,56,343,196,365,416,518,186,676,423,670,126,831,131,140,101,122,929,389,106,326,399,413,704,53,171,570,491,43,830,761,841,336,183,323,911,10,466,335,637,745,553,258,824,698,251,718,990,386,128,474,106,30,72,206,533,693,353,142,38,654,890,986,820,0,496,923,457,750,587,494,552,415,281,131,76,601,27,584,308,641,686,563,504,331,570,807,108,902,239,444,302,582,713,297,771,254,358,844,752,708,262,425,661,158,630,313,868,382,594,472,226,718,533,557,27,515,68,455,513,461,431,741,761,283,477,841,235,475,478,700,89,273,595,257,879,181,598,379,927,12,577,718,78,275,950,983,18,246,553,966,612,237,105,639,926,901,480,740,697,18,985,627,934,971,339,672,768,104,388,179,155,437,784,362,384,502,764,762,316,786,982,142,162,41,258,233,468,300,326,208,893,74,815,536,562,452,876,626,853,188,98,924,923,981,187,247,403,408,933,780,706,532,628,48,66,368,982,745,154,512,346,907,120,577,436,806,765,71,100,526,540,50,757,752,410,570,820,61,21,498,766,773,386,514,32,728,4,67,3,743,103,268,132,714,554,48,856,120,422,509,483,843,763,68,957,735,545,153,820,257,769,774,693,41,863,261,57,956,641,892,722,106,878,484,948,594,132,177,832,109,37,312,402,480,696,858,958,559,515,673,422,77,22,541,24,407,226,902,498,628,630,308,365,925,668,643,870,383,745,477,146,754,97,641,751,199,675,491,277,515,94,214,119,648,291,647,308,573,461,904,724,959,608,450,973,7,300,998,959,281,610,348,272,534,918,385,350,618,976,333,303,941,160,418,241,857,877,258,428,626,859,795,681,700,247,108,223,822,943,831,667,915,102,425,756,480,981,522,275,73,861,195,434,911,415,194,24,816,875,145,309,148,292,270,33,744,234,437,184,759,555,573,628,575,237,73,697,42,220,565,397,215,40,270,922,367,737,430,848,486,528,941,739,726,864,271,246,417,315,307,230,783,48,589,844,294,592,540,954,566,163,190,416,860,181,969,588,678,675,95,289,866,686,193,265,763,669,885,859,305,319,553,991,59,544,492,117,665,107,356,833,211,956,472,635,132,579,934,944,689,972,633,84,16,489,808,950,951,429,699,497,36,708,35,323,549,640,730,251,497,208,994,753,689,103,5,247,751,291,602,493,477,586,822,415,29,972,651,150,989,528,967,761,789,174,972,421,165,485,269,114,751,2,625,495,725,870,685,581,553,182,110,565,140,992,566,738,880,213,946,578,343,502,538,578,380,401,244,387,765,771,993,681,37,914,80,1000,548,730,766,940,362,9,20,362,166,652,706,72,362,671,792,499,260,406,589,522,658,407,475,9,338,546,759,519,60,935,312,48,721,329,896,671,324,111,557,341,651,596,693,383,181,735,232,942,23,491,420,269,367,272,596,559,698,737,131,506,71,771,131,890,557,472,196,609,974,582,748,155,710,69,956,972,840,962,325,748,781,244,451,941,329,856,519,694,363,427,356,331,200,710,870,895,473,671,107,449,955,88,837,542,591,504,817,762,188,614,381,377,809,270,503,807,332,933,764,513,926,435,845,373,566,13,522,649,883,686,42,464,98,118,913,598,704,890,924,838,887,766,340,524,542,755,940,142,432,695,733,588,924,827,477,171,625,313,861,832,988,378,617,529,108,254,440,609,624,24,956,526,589,85,554,442,62,14,271,440,548,774,481,91,143,177,271,614,758,844,129,296,107,539,258,570,246,173,908,111,742,309,601,120,379,57,883,346,565,870,283,359,603,844,168,871,819,471,315,315,317,857,369,230,711,779,414,164,650,201,357,378,654,472,712,493,365,910,330,594,329,194,675,336,537,214,748,794,636,698,982,766,931,227,872,528,682,30,669,428,141,699,682,711,488,499,246,741,919,702,518,421,470,708,234,881,500,918,833,939,486,182,187,602,905,915,90,706,280,614,274,41,617,232,608,650,529,832,314,945,660,244,982,824,49,839,34,135,246,810,619,472,428,729,511,393,963,521,16,378,197,327,937,759,501,695,635,215,257,523,907,827,515,372,652,910,373,162,443,23,540,565,673,796,329,104,849,579,267,232,686,593,370,848,260,626,753,959,634,925,383,741", "965,486,382,592,904,878,484,400,446,830,894,643,736,208,705,318,630,794,85,175,637,979,526,434,916,837,658,111,595,286,879,328,485,810,23,94,289,15,577,812,791,406,400,423,764,314,300,226,782,506,519,884,896,167,652,895,204,737,722,155,346,8,492,538,803,123,546,250,250,669,228,476,242,809,718,900,653,995,409,277,65,499,999,221,490,317,928,481,974,101,639,691,635,238,166,475,438,224,626,763,66,423,206,327,452,846,962,579,906,882,423,82,983,499,769,868,517,546,263,42,968,770,109,71,496,0,188,882,148,202,857,516,659,943,349,928,944,876,69,211,210,949,64,127,117,701,289,364,164,257,423,309,899,608,525,462,571,892,909,153,933,50,639,518,299,564,957,511,775,769,915,10,230,810,227,358,5,289,670,590,171,301,885,50,794,639,505,956,980,212,932,628,64,876,270,111,733,58,27,854,781,532,994,727,984,641,953,826,7,391,331,221,908,230,515,100,159,443,207,745,535,747,415,467,186,940,799,234,667,947,154,400,891,664,266,717,631,490,826,423,814,298,115,181,804,149,251,938,92,25,41,897,795,945,919,789,283,484,568,848,446,431,723,812,150,646,673,589,760,248,200,653,690,958,131,404,406,113,327,204,472,847,668,503,992,682,609,349,432,665,649,18,17,68,936,778,164,633,384,851,743,937,263,356,228,668,900,55,757,881,419,422,789,408,344,328,330,577,896,850,774,423,927,644,201,946,436,328,305,627,664,721,855,143,819,720,469,808,673,773,864,90,170,485,241,10,528,735,72,330,87,560,812,345,334,889,831,396,972,211,933,813,530,168,741,646,296,260,160,107,187,707,67,390,265,458,310,384,183,137,670,246,658,663,602,83,120,367,324,686,145,994,336,653,412,376,51,860,410,540,54,172,368,661,634,590,820,453,344,160,646,402,144,950,899,627,91,263,686,893,665,6,261,19,312,428,703,803,666,546,312,490,368,591,577,458,129,598,127,846,977,55,684,687,47,917,450,141,430,365,402,424,288,739,579,517,162,987,559,199,780,582,783,480,951,642,884,626,624,449,690,289,895,707,320,74,646,540,736,645,50,76,155,646,6,976,635,962,787,717,669,308,933,451,212,764,110,350,605,759,927,507,148,706,267,790,189,618,307,644,604,788,3,518,149,799,358,855,765,867,909,557,115,730,559,804,372,650,478,287,547,297,360,491,910,916,439,630,699,99,664,487,88,273,241,692,798,416,604,518,865,193,202,852,883,442,885,823,799,371,442,626,289,286,182,522,209,235,778,281,852,425,980,848,734,323,411,444,11,661,613,411,926,147,987,206,805,698,807,60,545,599,921,469,530,955,616,545,284,10,602,820,894,921,947,510,948,341,886,556,803,882,366,774,164,174,405,663,966,263,263,139,930,200,21,339,87,95,444,84,835,626,155,671,840,963,300,849,943,59,617,863,594,369,319,506,294,383,401,277,265,680,911,913,556,168,348,39,282,647,496,318,225,475,63,840,764,156,783,167,89,749,925,945,75,16,653,622,791,723,949,445,960,34,168,822,231,42,54,163,413,780,77,358,486,486,391,606,420,623,379,735,920,153,587,826,523,404,802,32,685,515,727,656,21,398,613,232,623,56,22,903,231,618,147,499,144,136,842,181,637,35,304,918,890,75,184,728,683,754,512,997,920,96,855,75,962,885,730,812,817,798,290,400,920,589,213,11,384,116,395,210,154,735,758,781,705,3,219,590,102,761,543,474,922,172,702,661,569,179,167,363,402,28,191,864,80,491,888,963,925,683,569,713,843,944,382,205,173,553,112,915,905,688,620,949,980,814,563,888,538,57,99,592,412,519,120,706,217,371,366,237,631,296,665,696,939,769,346,524,225,899,230,83,945,354,918,614,246,959,952,670,501,721,652,643,683,8,838,419,950,247,653,852,388,385,108,250,347,500,550,366,576,937,733,856,95,352,506,152,44,194,131,129,434,992,689,357,460,171,8,214,229,231,510,842,984,163,468,960,395,556,468,606,978,316,509,634,27,803,988,369,672,350,358,623,339,490,99,56,727,959,666,124,451,352,823,984,998,844,653,426,395,614,397,114,319,633,903,721,313,295,922,545,129,506,262,199,497,707,831,553,598,357,538,260,256,448,389,513,330,435,835,65,38,149,124,238,173,192,128,466,796,581,74,537,61,384,577,552,916,707,491,610,437,758,881,625,152,602,195,966,257,16,797,299,379,830,906,41,483,204,569,340,654,779,237,978,292,90", "973,643,466,379,387,812,873,117,572,396,302,832,465,796,884,771,806,684,1000,173,605,263,533,794,283,566,432,486,353,183,350,991,958,306,718,701,988,228,802,944,370,524,867,636,656,731,546,422,754,310,894,164,447,83,776,739,484,680,949,281,859,245,957,556,861,103,563,216,62,994,714,11,905,519,152,104,990,123,570,883,37,384,953,429,554,12,195,95,629,987,63,315,871,600,448,459,780,599,62,547,746,42,455,195,747,960,884,564,612,161,392,916,56,655,275,299,181,274,315,77,431,180,878,615,923,188,0,673,46,622,240,176,919,904,570,481,732,645,523,543,208,104,978,565,903,847,288,641,129,580,47,781,15,577,98,421,229,464,942,612,229,784,319,992,163,242,874,248,193,242,810,247,578,795,214,789,426,946,186,616,651,605,524,796,285,61,44,138,229,636,897,574,794,178,560,574,89,114,629,494,927,823,314,48,746,717,843,604,737,489,96,674,940,979,913,839,631,248,939,220,146,569,936,849,139,252,912,645,449,856,750,801,356,761,487,411,178,897,263,884,954,430,868,237,254,43,150,189,893,676,426,657,997,601,63,523,575,438,445,429,142,421,904,865,54,772,767,38,838,977,328,812,139,108,284,803,469,589,132,675,324,501,152,911,707,567,286,531,833,805,155,117,259,459,624,166,671,3,106,35,88,89,277,97,505,286,480,181,338,469,738,145,356,438,267,811,989,612,888,933,716,996,117,867,822,816,609,67,52,122,839,880,8,707,471,723,174,373,232,666,597,532,152,838,881,875,289,86,521,923,145,599,200,275,743,270,833,58,496,790,483,814,741,216,62,755,918,207,600,616,771,867,307,130,830,441,377,177,765,781,473,167,935,503,953,470,166,316,510,304,549,965,267,684,93,44,432,545,57,228,193,830,48,893,252,76,134,255,463,175,203,816,701,398,728,754,243,52,569,764,81,291,714,24,51,786,496,228,708,50,32,8,157,278,720,377,378,169,859,619,905,214,166,479,61,995,865,166,624,11,334,154,295,45,152,158,1000,671,263,478,452,13,797,876,308,542,672,601,152,853,953,403,63,451,217,897,100,612,810,192,250,290,187,793,505,288,9,975,715,700,268,310,80,209,990,783,598,232,422,96,19,575,829,283,174,214,297,662,712,957,904,936,338,345,238,450,583,647,44,160,165,542,54,138,950,342,838,839,952,925,62,291,539,980,399,433,785,983,208,45,360,742,32,500,474,932,354,20,924,167,813,109,353,120,101,900,430,485,177,430,50,672,636,781,469,858,582,796,869,818,912,803,626,417,156,734,860,305,783,111,929,652,844,922,46,795,248,413,719,114,892,471,107,709,81,906,440,417,595,998,496,275,802,756,213,375,437,699,123,929,821,740,738,237,412,411,752,422,114,361,499,64,541,618,409,159,990,37,780,349,418,173,282,581,412,429,296,373,873,757,911,778,705,173,228,156,931,269,359,303,94,12,853,690,948,870,361,220,400,62,658,732,7,504,330,354,176,811,53,821,447,315,841,980,329,163,986,101,509,167,94,898,237,353,541,985,691,803,480,154,41,841,813,121,619,690,901,327,652,802,69,158,863,929,431,439,953,375,856,790,432,889,51,281,743,272,592,532,266,879,285,431,654,819,984,782,389,319,173,336,383,72,334,657,598,182,997,673,458,50,528,112,945,971,232,75,383,367,754,270,716,294,73,104,631,406,68,196,779,286,228,372,585,288,122,164,826,328,793,66,530,469,491,2,658,737,693,664,156,443,336,143,502,18,13,554,809,237,929,667,920,873,44,535,509,119,143,121,364,288,127,524,810,232,668,878,290,522,224,642,200,230,420,658,570,980,152,314,455,395,123,876,500,985,781,754,419,72,231,493,364,599,83,298,536,212,25,415,167,412,151,726,601,425,252,988,139,718,638,308,339,919,929,868,245,746,988,747,806,520,37,820,219,823,53,654,502,832,453,158,593,726,822,117,496,706,29,418,104,882,82,550,90,436,94,545,914,982,537,240,773,125,281,790,906,793,440,167,866,596,279,683,281,80,14,739,47,296,530,298,928,304,156,3,22,536,228,983,937,497,853,387,686,629,675,859,236,252,509,164,9,389,166,645,219,325,868,662,259,500,747,852,666,121,304,697,918,255,797,750,387,244,577,387,423,183,613,567,893,103,761,867,654,709,925,576,414,42,983,842,505,666,965,105,105,976,287,725,662,155,501,530,722,598,424,159,829,45,937,957,302,39,794,441,613,101,730,311,366,735", "950,437,65,950,965,337,206,683,19,406,697,489,73,654,841,14,788,376,477,602,184,732,934,929,517,659,64,209,53,396,895,407,683,720,503,698,740,458,76,339,965,90,422,969,54,612,78,140,184,232,195,152,560,102,781,641,677,289,623,849,269,347,707,593,240,955,401,397,252,947,442,181,866,209,763,888,302,185,620,39,686,883,372,307,460,502,712,255,652,999,46,676,241,919,137,487,2,96,874,976,527,539,809,171,342,979,850,710,573,345,501,476,244,605,364,377,863,952,93,513,402,605,308,595,457,882,673,0,668,449,456,198,853,327,505,808,227,164,468,273,931,342,625,285,616,668,9,595,209,470,701,915,234,747,74,649,839,414,913,814,331,518,162,931,854,853,7,661,6,199,269,628,269,174,481,429,962,549,821,916,309,857,341,305,937,231,948,276,84,161,309,620,94,129,725,161,419,210,787,753,609,681,691,199,186,220,466,544,242,256,709,220,676,416,905,47,62,72,838,724,743,434,930,355,584,553,277,95,738,828,322,977,552,285,495,815,987,586,606,751,635,115,822,915,791,984,713,469,72,269,740,611,588,724,19,798,251,641,219,170,17,130,467,797,497,909,70,262,139,976,767,833,744,778,894,496,870,393,826,324,824,623,666,18,393,100,459,198,103,620,765,891,799,419,456,566,602,664,334,611,82,450,583,312,497,719,602,462,480,714,767,135,596,23,109,255,2,893,113,294,500,967,640,867,470,101,439,947,604,27,998,356,941,129,14,259,68,444,656,241,829,919,679,382,34,904,934,332,117,275,837,249,534,51,109,208,572,454,298,576,293,413,492,500,210,762,782,460,67,485,337,977,426,442,385,5,833,834,119,102,408,124,28,948,601,158,711,382,853,802,259,433,368,478,287,933,109,450,438,636,159,461,554,703,813,819,533,670,716,145,467,406,927,889,641,230,817,355,110,901,871,193,346,5,716,856,107,55,83,941,344,438,148,59,282,366,130,983,906,182,799,729,15,880,650,106,396,179,185,829,126,708,437,397,151,151,664,847,220,96,913,267,949,9,59,790,482,193,104,72,456,796,152,872,712,280,685,194,911,418,699,535,309,36,536,250,77,521,263,85,671,458,949,945,914,219,662,274,340,851,18,429,950,26,533,295,712,527,559,138,636,768,508,642,760,60,194,912,135,104,662,613,935,793,21,563,325,996,38,413,15,624,788,598,58,971,50,792,942,463,700,945,987,628,324,7,202,63,457,173,563,939,459,561,263,155,803,338,715,10,627,771,11,846,377,235,501,689,16,522,249,10,902,172,836,874,613,273,662,38,950,168,942,329,340,321,47,513,15,673,216,767,293,64,212,27,312,260,348,978,944,718,599,779,334,330,272,513,651,251,605,282,781,960,181,978,129,435,568,436,886,958,60,268,304,560,202,532,151,97,962,539,320,866,673,346,43,488,115,177,896,598,196,902,719,261,642,580,52,168,762,807,362,103,442,547,47,543,472,423,492,298,610,429,122,463,360,749,887,910,33,314,927,404,873,4,905,965,945,401,336,229,337,181,259,329,65,59,977,728,334,58,123,883,409,847,462,343,453,128,892,19,483,718,470,60,936,414,543,509,898,70,284,345,395,280,923,901,339,323,338,875,972,736,974,41,757,275,761,884,136,473,427,620,340,565,815,502,325,113,387,342,519,460,481,30,2,151,89,929,597,86,449,455,274,26,399,785,303,182,703,99,131,784,332,108,62,140,467,883,161,222,902,574,83,332,834,427,241,222,513,559,871,351,526,430,562,615,713,364,856,981,778,115,407,145,690,759,892,559,916,469,101,875,253,952,444,327,407,669,313,361,954,706,429,680,88,124,467,498,629,183,809,270,699,60,478,17,874,33,73,689,25,973,168,127,199,193,729,365,651,220,6,487,63,909,720,222,224,944,143,247,432,457,700,147,412,682,466,548,622,947,302,419,24,299,641,922,733,714,175,327,806,662,63,68,119,367,143,861,915,367,73,162,316,782,534,509,743,631,993,207,843,440,536,473,120,925,720,684,486,691,627,239,899,353,138,475,96,694,691,354,874,542,609,180,777,100,192,909,105,674,266,635,745,189,555,259,151,389,965,126,911,560,326,862,457,109,728,866,578,361,458,794,872,69,428,856,393,479,865,61,589,989,170,153,523,544,233,761,35,227,464,788,717,273,591,159,810,220,4,835,965,514,268,590,220,938,279,994,304,11,72,963,609,633,669,884,607,139,171,54,619,833,919,215,135,473,712,233", "952,828,16,990,540,210,860,948,331,618,499,455,739,70,302,724,267,808,79,66,616,864,201,188,545,23,251,496,908,404,550,19,395,862,671,464,714,223,176,6,916,82,458,945,18,946,996,800,906,569,648,363,117,234,804,503,123,655,425,927,978,926,194,310,133,907,291,365,832,977,13,115,736,440,75,790,450,976,522,510,906,551,757,677,187,355,471,202,105,79,981,17,462,682,130,885,571,830,638,338,775,797,448,986,375,189,403,252,908,527,610,556,560,493,912,929,170,546,953,358,678,699,384,871,750,148,46,668,0,158,337,173,601,624,124,539,513,133,320,77,748,916,520,56,465,905,124,842,97,221,369,151,316,4,371,616,765,236,376,559,115,508,925,135,774,885,266,644,648,299,977,805,454,553,243,671,25,892,862,757,817,629,932,248,62,206,265,800,233,996,765,140,301,90,950,246,88,112,836,883,128,709,699,787,244,92,41,624,536,359,244,440,893,562,857,708,20,459,290,153,642,533,223,951,795,464,817,345,25,952,894,295,811,662,333,819,76,543,95,741,844,845,163,123,662,448,457,439,226,188,267,339,227,379,18,232,886,940,814,433,847,225,812,896,353,881,755,482,483,278,273,350,180,311,206,536,765,181,371,820,961,168,770,571,204,707,396,146,26,364,546,642,291,590,629,390,77,452,656,267,572,682,262,48,839,288,920,536,284,107,757,582,115,661,638,924,591,432,629,277,237,590,181,948,603,851,57,547,866,492,990,591,371,230,768,399,212,319,369,934,954,859,948,371,824,922,527,382,218,401,425,751,953,673,36,659,30,779,357,104,930,278,246,200,423,413,681,583,689,18,776,176,891,664,449,782,193,741,251,655,345,52,102,881,606,344,901,741,297,778,555,822,246,9,970,446,614,778,750,503,87,246,467,242,644,543,686,341,480,983,51,840,628,956,845,510,257,915,22,640,255,279,749,248,712,90,711,514,174,237,259,774,923,38,687,25,213,619,652,701,973,126,714,995,54,328,815,6,714,851,382,266,430,221,737,75,942,398,658,993,261,388,579,798,557,934,73,26,937,38,9,214,360,55,443,801,558,875,702,483,716,350,684,800,370,348,601,219,386,393,12,196,542,655,503,84,657,634,731,675,547,568,260,171,12,72,967,935,788,528,755,724,274,677,49,859,516,611,758,604,836,811,601,728,954,606,121,412,375,629,82,782,533,97,708,32,345,758,697,310,686,746,361,98,139,85,527,655,212,160,609,227,889,541,657,678,316,413,501,282,660,566,942,864,868,834,272,211,152,945,402,102,221,249,477,659,415,82,455,48,217,531,962,403,650,689,685,475,287,662,171,421,899,474,633,373,545,317,994,484,554,12,821,651,569,288,262,255,577,550,387,795,970,189,512,739,747,352,721,459,8,413,372,292,90,180,969,677,371,973,636,421,385,188,501,104,531,979,111,319,115,379,833,754,910,500,621,228,615,175,204,176,914,377,727,628,952,507,3,404,461,55,72,836,946,939,732,367,151,456,375,600,701,829,63,901,856,244,831,65,761,750,802,239,772,913,279,605,718,768,999,483,875,569,664,260,387,552,293,501,306,681,738,956,978,451,697,617,898,495,584,258,664,292,389,358,766,742,189,345,20,207,67,894,633,735,494,150,383,588,359,776,814,947,747,148,996,665,398,276,287,270,173,881,908,165,876,283,421,216,541,95,575,113,309,902,995,124,891,223,426,600,989,205,804,491,193,48,466,11,977,82,458,253,240,935,966,316,675,643,949,48,307,853,171,397,141,609,730,617,222,135,569,240,560,662,366,54,290,912,997,101,84,359,991,576,341,971,534,876,72,517,84,272,824,947,879,477,548,548,604,746,515,489,629,129,519,562,441,954,962,632,86,311,674,682,426,916,194,919,329,877,652,133,612,181,654,943,527,833,31,698,273,655,689,635,313,560,519,677,374,519,703,416,119,176,954,728,498,338,122,475,25,559,387,342,432,883,842,74,450,79,312,629,306,262,415,22,763,529,356,517,944,718,162,310,978,829,671,323,909,99,458,896,572,665,713,119,436,421,976,411,258,663,880,813,68,706,555,591,136,950,456,920,685,499,637,562,962,836,142,870,476,165,401,854,908,158,309,258,800,554,214,856,918,247,531,960,258,688,967,316,77,774,655,396,604,148,766,484,180,928,81,958,476,584,326,311,100,945,384,611,418,448,107,75,149,43,961,288,202,866,86,585,7,16,155,649,107,687,377,412,67,64,959,49,509,959,313,103", "492,729,85,980,463,805,36,673,830,552,126,24,56,363,64,71,26,848,861,193,844,214,466,760,291,679,741,426,645,986,279,514,507,97,562,121,88,735,417,665,684,832,686,865,108,72,117,934,604,213,694,644,172,572,494,469,15,466,479,539,470,80,475,321,74,745,993,393,979,485,590,749,810,874,227,456,827,19,321,238,973,601,982,593,840,690,697,438,532,324,298,830,731,254,777,690,268,866,383,595,389,358,598,36,839,62,279,37,36,975,286,793,164,691,771,278,443,371,535,508,605,195,926,917,587,202,622,449,158,0,13,146,288,260,842,352,144,636,590,893,654,669,967,99,851,342,578,178,628,81,484,353,972,451,695,557,250,962,228,222,161,115,812,288,467,414,65,815,470,739,834,894,627,929,588,74,559,881,227,739,163,849,609,825,343,733,585,489,916,101,344,899,159,210,976,482,574,233,865,149,330,257,659,510,262,222,203,594,96,776,100,405,397,861,480,342,41,177,995,42,676,68,413,856,814,522,745,835,394,416,986,685,753,828,375,991,153,776,972,424,512,247,642,277,341,116,24,789,240,963,319,273,560,942,502,181,568,189,5,815,430,192,224,182,617,204,10,560,885,758,833,848,774,885,15,76,630,92,963,850,356,100,939,506,699,426,304,167,907,213,650,23,969,757,330,434,596,830,389,173,27,482,394,684,363,875,835,326,113,855,840,692,2,844,299,640,532,834,296,54,106,906,899,434,429,521,374,810,474,239,226,574,463,892,844,743,251,927,592,660,883,560,115,926,943,748,925,922,508,26,413,389,867,12,536,561,29,266,605,656,941,842,751,264,500,820,106,325,959,9,706,432,16,583,795,827,575,561,351,467,5,121,477,355,635,540,326,340,865,809,530,480,743,490,383,600,447,984,604,129,717,243,695,14,889,392,804,663,795,156,877,675,777,649,98,460,418,305,83,686,238,647,679,664,226,869,839,159,419,585,812,525,221,141,186,230,288,304,784,751,322,810,679,27,952,368,336,764,768,66,413,191,501,390,757,132,895,914,941,130,737,123,112,648,629,817,191,458,378,110,98,255,452,744,364,153,598,93,353,184,677,397,845,891,581,169,647,646,173,238,282,331,740,310,22,453,826,35,51,583,32,622,684,155,372,699,42,150,795,556,206,935,317,879,935,640,188,44,49,205,113,266,957,63,32,444,928,17,286,845,980,788,239,325,134,331,702,144,198,134,410,690,104,641,533,354,46,614,81,756,254,208,771,44,949,532,235,228,700,853,721,698,468,150,477,19,249,730,734,744,271,266,754,568,121,896,435,121,446,283,833,599,448,273,375,343,233,807,317,33,350,90,222,731,265,900,852,140,937,842,629,826,151,642,940,479,912,801,444,838,779,829,721,678,897,631,60,217,823,253,716,519,178,180,325,388,33,915,359,793,899,204,398,222,306,948,229,81,753,61,423,401,748,43,194,389,530,702,28,90,330,537,285,570,783,119,546,547,758,844,547,604,470,274,434,967,744,86,155,783,635,111,847,386,12,186,646,183,190,888,784,38,696,303,940,513,589,791,681,916,154,955,308,751,192,834,282,622,993,967,152,14,919,184,165,303,521,170,617,175,500,93,67,405,603,417,49,692,140,75,403,878,950,555,399,466,699,532,859,991,474,893,819,203,844,40,661,114,444,321,898,1000,544,234,131,478,119,524,600,584,94,639,354,161,657,16,933,899,426,958,349,358,512,40,984,652,673,785,572,696,49,993,531,925,570,679,632,384,338,606,809,519,69,844,778,672,316,729,634,901,807,42,139,715,788,380,857,781,455,853,316,812,695,515,122,179,757,338,241,494,342,349,476,584,156,446,142,798,667,830,286,430,725,920,767,369,790,633,270,589,496,195,306,989,881,242,271,361,459,946,963,503,985,429,19,916,974,929,497,333,97,982,319,493,424,75,988,905,594,808,774,720,247,3,813,137,908,652,699,714,393,757,701,44,554,534,962,330,402,598,115,208,561,16,870,614,174,417,882,623,853,925,767,467,415,232,799,720,279,478,58,960,142,942,59,451,708,329,589,303,688,53,771,168,482,622,510,892,792,999,206,740,125,366,571,763,252,582,192,521,935,929,725,154,119,136,520,731,300,746,382,572,965,68,622,372,940,760,365,392,369,679,193,84,399,708,332,958,785,738,255,485,687,6,559,597,366,356,866,726,577,185,996,570,951,555,475,182,156,912,408,187,638,531,31,768,885,871,753,345,638,586,856,892,307,487,612,530,805,641", "624,571,21,716,362,262,171,784,440,777,746,754,52,657,47,932,608,527,968,368,769,950,52,676,856,344,105,686,710,517,448,730,85,952,45,611,928,211,725,240,499,16,588,187,515,363,304,827,751,115,439,879,75,23,628,160,6,716,669,547,738,734,680,361,51,929,535,108,322,883,889,811,667,521,912,590,832,405,197,516,31,706,354,506,849,561,55,433,479,44,463,722,636,11,403,564,41,233,431,170,528,469,238,744,784,819,379,835,801,659,866,697,300,106,859,591,486,160,498,510,56,299,192,404,494,857,240,456,337,13,0,980,246,430,524,61,345,710,992,762,667,181,65,117,239,768,964,297,649,838,340,572,122,939,84,232,807,368,162,602,512,336,37,422,585,896,410,562,153,696,205,341,827,15,690,698,189,419,65,210,704,677,102,655,909,187,128,438,255,569,929,928,93,965,543,262,587,331,814,365,607,110,80,271,182,723,845,635,62,25,853,997,710,73,114,701,779,360,149,839,613,298,386,425,369,67,475,739,794,330,627,49,173,780,726,654,688,157,969,150,833,804,556,851,202,709,521,639,866,556,616,835,70,282,609,988,44,207,201,126,519,874,116,947,78,999,367,985,733,432,102,170,303,36,899,328,633,374,427,89,686,224,315,215,944,269,818,384,19,179,236,750,938,102,569,304,185,31,290,275,260,345,906,368,983,784,629,318,937,976,449,649,605,110,869,369,513,591,290,889,640,512,759,946,211,92,329,216,148,886,862,87,353,456,599,621,220,705,161,403,782,238,178,950,610,144,797,980,384,406,470,299,115,857,770,758,31,511,775,152,294,219,579,872,981,91,27,899,923,118,87,259,355,824,994,360,235,997,824,377,65,374,755,486,731,213,511,522,913,118,966,138,573,246,747,504,899,164,270,241,100,624,296,307,942,106,552,513,753,910,100,810,584,987,885,88,87,301,479,818,78,551,978,318,435,401,959,535,129,419,640,80,981,810,665,215,330,457,86,609,549,491,677,271,725,937,279,709,55,377,416,738,345,919,390,37,929,26,209,229,435,292,50,929,694,418,11,664,699,651,805,720,787,846,279,82,595,197,688,766,864,294,946,436,978,503,223,504,819,202,376,285,136,880,145,703,518,1,74,5,150,343,234,613,964,819,528,376,584,387,444,56,593,216,660,890,845,605,513,915,4,308,916,787,246,976,2,201,359,259,961,378,436,836,247,461,580,455,59,116,864,138,275,159,325,705,594,698,364,385,142,799,349,263,457,827,501,48,501,221,383,581,853,197,872,395,653,838,806,190,322,406,169,578,346,343,340,503,348,672,64,296,818,340,961,630,547,922,725,722,966,92,329,545,239,46,775,774,998,238,822,943,602,500,821,493,245,263,462,471,971,295,335,548,779,920,11,467,262,170,23,26,302,821,142,792,284,510,447,903,928,790,918,761,376,592,325,967,856,778,616,172,421,900,48,691,903,219,498,334,213,921,628,592,257,739,781,226,508,460,849,933,234,326,922,588,666,228,433,905,357,1,927,724,960,281,280,834,644,24,417,48,455,407,221,419,74,547,921,391,939,326,640,736,453,976,941,406,814,290,186,171,282,617,833,810,215,481,369,104,59,924,823,601,491,405,246,320,156,301,55,583,6,480,563,288,773,862,160,369,364,851,269,254,549,744,438,948,986,979,505,609,930,427,841,472,442,168,835,43,316,859,520,150,838,92,37,805,314,592,734,357,610,339,410,284,624,904,85,263,644,792,478,832,981,799,305,6,671,860,655,991,774,695,889,180,362,230,239,831,809,572,344,771,297,951,381,377,215,361,852,892,389,477,494,304,781,757,432,442,134,296,320,501,983,304,768,551,856,450,664,99,785,748,3,725,483,555,347,176,90,584,973,840,701,913,260,761,907,404,968,382,461,498,780,570,97,788,421,136,329,839,468,645,945,473,244,895,746,660,941,446,867,997,263,512,468,588,808,835,435,233,308,984,854,791,496,76,662,137,637,882,520,968,425,482,616,713,248,858,318,712,411,829,432,801,748,814,684,150,394,994,268,530,980,268,194,158,411,343,272,459,693,808,400,956,685,239,189,885,759,995,410,907,90,891,947,349,516,562,598,90,689,233,610,593,913,125,688,784,957,296,952,951,140,721,340,341,889,855,881,418,741,772,765,990,293,548,758,667,390,481,679,100,435,144,643,552,487,235,89,816,178,241,569,570,635,691,861,879,23,603,111,444,509,867,951,635,511,950,564,14,632,230,533,296,86,404,495,808", "810,950,223,332,112,360,814,636,585,542,585,444,258,29,376,259,719,102,54,223,503,763,814,505,770,654,54,140,241,112,194,871,477,543,712,694,493,401,730,906,760,679,502,890,153,993,54,590,336,760,448,307,350,285,856,448,986,767,902,255,815,78,990,985,872,297,876,219,16,825,931,482,822,937,275,945,159,169,755,839,31,37,706,372,356,125,926,642,197,38,24,918,777,112,14,841,91,594,294,57,165,925,507,724,641,128,730,334,153,568,775,565,750,661,85,566,90,283,515,497,110,301,425,610,552,516,176,198,173,146,980,0,600,714,530,944,641,687,502,725,140,31,842,557,928,211,112,379,169,714,459,803,919,840,240,945,894,972,668,579,28,233,889,151,412,207,470,216,105,31,972,755,823,82,34,816,536,896,395,844,955,154,42,432,318,759,240,411,132,197,821,255,172,736,192,145,212,796,457,336,772,678,620,556,50,621,883,595,816,396,176,935,993,138,880,613,331,197,582,798,165,737,607,778,686,730,972,719,258,10,893,417,136,841,505,397,918,270,381,425,63,217,260,838,925,923,439,435,538,72,858,379,461,351,522,905,719,967,773,821,839,598,144,981,425,815,93,740,297,876,608,160,331,971,657,247,362,889,416,393,742,356,256,351,921,965,100,769,969,71,373,696,632,825,163,163,204,398,325,105,187,905,432,713,488,793,611,173,336,380,542,147,33,417,886,997,556,209,322,363,986,466,729,953,596,269,45,656,590,192,464,39,175,809,836,296,490,434,426,687,142,270,651,975,148,420,749,572,845,34,492,550,950,355,944,554,92,687,907,249,468,363,592,983,378,552,460,25,349,405,448,824,806,261,326,87,18,263,270,946,233,749,829,474,297,320,339,59,467,260,328,937,201,355,725,724,870,880,555,180,759,202,762,441,855,389,867,874,349,923,405,808,660,21,185,805,755,12,909,630,209,631,791,326,187,532,900,631,965,578,188,341,315,65,606,811,290,561,450,222,595,14,364,837,118,634,860,321,250,454,766,478,932,617,264,477,277,692,254,256,249,682,654,106,515,380,12,395,984,323,850,479,847,621,865,688,145,148,35,406,806,409,842,177,18,151,730,243,189,437,27,141,763,988,420,171,438,763,239,706,52,295,248,872,281,426,174,201,952,703,137,95,810,694,739,127,845,995,727,48,498,609,365,615,327,133,463,632,129,603,25,415,3,514,724,931,920,436,751,294,418,417,280,779,336,330,567,499,880,293,384,456,740,838,45,457,964,908,95,815,670,661,460,907,993,798,145,601,353,327,132,529,990,717,985,730,189,189,226,666,440,850,439,996,868,127,296,753,334,462,40,239,928,751,562,536,329,619,743,312,981,642,676,457,443,95,107,438,545,521,905,675,32,91,248,283,423,52,873,723,208,712,274,886,67,962,105,634,690,417,863,135,577,442,773,305,562,72,643,599,461,157,960,19,318,926,902,574,196,193,75,896,702,323,885,621,642,513,520,624,860,272,691,760,445,114,740,763,758,413,280,603,478,997,856,479,827,441,370,322,125,752,415,349,583,689,774,952,286,799,42,561,562,775,899,735,146,566,637,348,694,848,926,909,119,590,203,6,213,624,690,547,455,284,494,71,833,336,11,679,870,86,877,328,181,504,548,99,490,157,918,442,688,224,569,107,48,17,196,943,188,140,447,72,485,919,888,20,695,550,833,981,444,92,846,889,377,507,842,629,569,888,163,31,745,107,505,874,543,314,894,612,203,825,360,21,785,433,38,163,656,378,110,264,288,167,813,494,391,7,53,726,150,287,354,595,102,488,576,837,738,369,552,844,970,705,319,608,4,891,951,853,577,516,267,647,292,89,106,484,381,160,737,847,154,282,531,442,278,745,144,782,741,274,64,976,221,770,188,498,924,53,997,727,561,264,60,837,438,528,785,99,989,488,142,629,410,320,849,863,419,771,958,648,795,725,639,605,465,157,934,739,599,325,625,499,951,419,402,402,857,787,479,926,474,621,98,570,482,395,711,844,785,36,855,679,725,264,123,509,656,495,637,626,154,66,673,52,934,269,721,631,193,358,650,421,425,517,433,945,240,695,258,698,805,335,734,500,619,812,449,592,909,881,197,522,492,370,747,537,390,784,869,656,727,354,776,326,604,590,98,975,317,769,418,161,466,685,907,691,869,389,514,632,17,101,333,866,372,153,246,105,657,852,64,980,649,792,987,363,414,307,644,491,850,149,43,75,695,758,487,849,515,316,462,629,269,970,936,457", "87,71,921,189,154,209,737,61,514,287,828,321,590,630,399,356,532,939,330,775,763,61,48,949,160,850,36,549,28,147,89,415,188,915,745,872,668,958,148,994,120,527,536,794,743,738,884,63,486,311,916,114,945,771,664,214,741,50,277,419,818,553,450,620,617,902,294,223,276,487,338,754,176,629,435,588,293,775,263,783,337,152,492,403,270,990,110,501,101,56,374,683,63,965,450,910,828,573,921,361,771,916,77,58,273,884,69,186,136,952,636,822,374,357,364,756,660,630,813,482,64,38,187,181,415,659,919,853,601,288,246,600,0,929,65,734,786,629,769,732,319,334,464,874,977,491,832,411,961,574,551,988,255,101,56,869,938,696,444,266,186,442,479,586,989,718,967,764,277,836,310,892,114,40,554,443,73,770,487,105,485,414,103,583,511,333,415,582,397,900,625,73,745,713,983,661,754,70,779,713,545,723,381,968,965,409,564,135,849,899,191,776,805,715,19,968,92,607,937,231,291,221,963,334,981,612,994,292,630,321,656,861,284,131,282,384,904,627,644,1000,124,841,668,586,10,282,582,151,489,702,304,182,584,173,548,819,781,592,997,311,332,226,29,872,334,118,451,5,265,19,618,673,518,107,440,492,784,73,494,77,492,979,723,409,598,512,238,926,81,686,513,490,309,142,235,146,752,224,630,2,847,46,116,718,779,656,547,929,956,902,420,852,337,793,271,289,380,600,824,758,976,25,717,204,960,329,366,509,124,317,528,604,745,379,199,286,692,588,469,273,634,919,726,12,57,144,809,849,802,621,868,399,359,698,346,155,847,509,911,297,845,667,122,575,84,149,852,163,906,666,564,175,846,906,96,426,632,459,955,83,139,341,980,411,782,368,862,979,104,685,615,458,895,623,468,531,565,332,764,798,256,181,854,490,258,15,142,840,974,211,782,135,367,637,167,743,821,195,94,966,289,265,269,698,725,579,635,670,640,844,309,879,267,979,247,122,842,141,361,155,275,195,686,532,407,994,699,576,978,104,222,624,261,126,684,913,343,865,687,995,559,850,881,127,350,495,808,762,661,177,241,963,480,211,820,9,419,167,649,720,385,409,541,163,628,435,794,472,511,664,671,127,209,709,313,833,355,927,560,691,493,374,716,757,117,614,723,481,619,823,280,269,809,840,241,115,52,162,846,71,152,375,903,166,684,874,906,673,845,325,939,567,895,12,780,232,117,332,209,815,573,799,302,323,528,985,453,997,104,345,274,134,665,136,17,975,536,938,456,634,409,480,619,593,727,875,990,764,748,431,129,929,399,885,91,789,162,538,782,350,799,463,163,298,262,950,731,56,545,789,592,448,354,324,984,365,640,150,395,712,116,572,127,384,636,275,369,748,580,52,891,614,571,185,551,802,58,219,589,118,217,181,187,257,966,693,46,484,429,641,278,496,351,108,904,178,758,279,700,416,607,867,649,474,444,644,608,281,874,926,323,376,964,860,260,960,182,850,376,283,517,93,598,298,467,729,382,204,12,817,712,439,28,584,743,741,708,678,323,480,948,346,639,223,482,387,161,720,170,478,724,7,609,591,495,940,154,113,551,744,92,344,390,981,198,76,513,451,309,565,246,447,844,306,417,764,773,971,196,546,254,34,713,610,262,271,79,150,512,997,831,290,17,475,502,357,64,28,25,734,844,272,763,376,698,678,543,726,392,865,775,535,323,67,631,436,221,121,563,221,415,667,834,204,771,138,950,192,88,968,325,481,620,876,877,686,335,531,365,931,770,974,929,976,348,831,531,328,807,629,848,233,647,496,425,871,361,516,671,987,1000,118,565,435,574,603,771,197,104,769,786,262,259,947,785,614,11,978,375,213,64,194,786,764,891,778,593,406,689,845,572,775,241,72,703,128,736,508,336,775,936,99,537,335,100,980,205,9,7,88,817,1,294,30,355,706,947,687,781,650,522,669,275,858,389,22,622,360,181,380,551,55,536,354,978,799,523,150,479,376,650,816,140,43,558,386,522,288,207,368,285,928,692,582,760,189,600,167,769,943,827,862,923,786,628,987,24,860,327,923,484,197,425,502,620,742,522,238,926,629,938,157,930,34,595,454,897,746,563,433,4,836,125,989,652,800,746,952,11,634,793,283,485,879,454,759,122,933,513,577,292,239,781,884,849,816,345,592,149,468,534,408,279,704,690,112,767,675,82,415,239,429,794,591,720,423,509,740,313,122,710,608,72,156,965,656,302,663,367,865,495,576,275,607,902,172,794,237,516,944", "62,908,353,908,430,461,834,936,601,627,929,709,651,903,926,383,365,359,872,357,630,276,463,981,811,491,969,197,681,874,391,631,455,349,470,815,600,285,393,598,584,474,635,538,974,322,808,814,51,452,436,915,334,529,315,846,529,353,866,187,264,238,338,479,317,920,254,446,681,612,940,512,375,871,18,303,198,772,396,605,138,79,409,115,386,936,169,295,126,473,567,610,918,294,143,522,811,102,770,675,138,277,449,575,962,245,411,994,972,706,440,782,201,336,783,79,840,698,481,390,492,756,55,698,281,943,904,327,624,260,430,714,929,0,215,503,244,422,354,230,943,706,431,135,997,814,814,108,402,165,866,195,798,151,541,445,495,661,298,921,606,537,555,880,356,528,99,312,18,554,874,720,557,159,733,101,497,965,900,910,777,879,277,924,29,593,849,183,295,23,87,354,201,487,189,937,636,89,515,356,641,587,831,309,567,495,298,838,507,57,736,546,787,330,438,982,632,23,353,248,775,785,754,593,612,21,852,22,562,862,64,276,824,313,740,314,156,856,486,181,979,352,106,512,264,706,235,238,69,702,474,923,176,474,637,738,425,317,178,349,349,835,84,745,379,336,933,541,799,272,979,404,431,438,162,754,116,269,167,814,465,329,981,266,596,657,214,411,444,931,660,19,615,735,101,128,742,570,593,982,889,647,278,147,473,47,54,945,871,710,518,867,568,519,457,532,737,144,907,120,192,510,211,731,368,413,303,70,591,72,746,171,655,980,539,918,490,680,781,604,823,884,438,862,934,682,702,393,653,365,719,777,157,898,217,346,381,926,776,973,207,782,814,960,383,86,897,564,754,352,203,331,128,585,719,771,539,994,304,960,287,147,367,37,658,207,230,108,976,725,775,893,339,734,799,719,213,367,50,576,896,360,983,373,94,197,337,566,644,470,741,362,731,498,966,594,391,450,799,959,976,239,638,494,704,269,180,370,620,824,157,950,345,225,855,440,315,232,40,822,385,513,2,528,609,954,983,880,610,66,251,188,467,885,795,260,729,899,769,904,486,733,648,367,881,400,498,59,189,700,914,217,544,869,215,522,428,877,175,298,281,522,19,11,551,860,345,305,110,889,854,771,516,232,739,776,188,212,153,434,542,642,816,303,457,280,580,593,879,771,323,439,695,664,656,103,617,752,223,979,953,952,25,435,464,572,820,478,45,80,631,365,231,924,498,392,581,277,360,99,548,49,265,221,557,199,105,131,422,564,290,527,923,684,9,286,873,23,963,367,240,894,272,215,46,206,860,96,570,477,898,439,332,40,750,417,756,49,622,876,991,231,367,513,58,497,478,427,331,575,100,558,143,988,48,813,978,150,199,830,474,446,598,687,972,864,889,970,459,856,707,539,404,15,43,994,296,204,11,342,83,753,191,737,282,36,360,273,705,829,989,968,771,179,775,599,272,336,781,313,789,205,135,692,213,105,372,626,478,535,156,972,286,919,962,309,825,821,114,7,71,809,29,207,470,306,676,344,489,259,819,986,831,362,562,756,784,445,242,722,218,642,588,6,497,781,261,641,589,728,361,311,942,257,994,577,363,584,777,327,962,962,179,398,234,236,10,245,416,141,579,778,860,716,787,770,747,378,696,505,553,808,688,479,193,589,540,802,941,364,761,130,287,357,432,840,569,630,337,928,509,888,736,63,905,323,224,365,214,878,476,844,771,973,276,898,658,107,394,914,944,319,689,329,450,483,638,304,518,484,69,568,874,893,23,376,848,298,92,808,447,83,662,752,199,998,705,281,854,787,147,627,452,832,158,318,492,315,697,701,659,955,345,946,626,642,768,621,94,166,978,416,501,738,162,207,12,984,806,424,578,937,774,649,790,455,512,920,828,619,366,645,957,745,274,594,505,803,224,916,597,884,46,327,973,231,719,544,856,369,766,306,366,483,463,721,150,204,740,662,132,567,646,708,592,785,476,787,698,269,69,778,362,535,359,798,848,995,170,157,959,146,411,119,519,695,635,692,282,314,114,408,347,766,567,444,924,580,582,702,813,98,725,213,789,978,437,107,468,711,884,681,377,587,192,119,874,76,864,295,234,586,207,494,714,624,656,32,442,79,419,325,584,696,23,124,570,600,549,97,79,736,217,978,24,326,370,849,14,865,471,933,521,610,894,22,672,625,167,296,186,370,133,706,123,765,431,830,804,390,516,752,18,350,926,98,196,566,146,284,449,13,235,999,927,145,304,414,906,409,180,444,686,422,157,185,684,456,674,853", "218,63,134,819,25,756,185,794,150,859,102,110,441,90,732,296,687,344,148,305,380,848,97,609,270,870,972,736,337,64,527,167,579,328,95,948,672,322,776,714,852,46,927,57,670,149,617,438,707,267,870,520,738,386,163,391,421,158,356,494,490,860,374,283,385,694,691,794,575,593,575,371,282,504,184,588,685,741,747,77,638,574,245,408,380,689,628,217,989,966,135,298,841,586,61,432,144,621,42,483,303,836,669,292,571,504,554,877,815,307,51,267,798,702,580,577,405,5,538,911,615,516,993,794,131,349,570,505,124,842,524,530,65,215,0,931,351,515,330,549,44,913,645,370,954,741,328,342,958,951,631,134,278,865,556,728,408,493,205,690,960,84,491,751,766,855,468,555,954,703,598,30,179,880,804,293,659,713,555,521,314,580,812,375,901,153,980,103,440,206,570,687,396,412,164,175,246,581,642,219,718,519,596,223,894,34,398,747,816,679,222,116,297,538,689,649,112,238,501,726,810,212,396,531,824,532,354,818,191,423,667,460,147,165,550,41,994,986,793,555,929,290,631,259,935,998,102,53,806,880,970,912,868,152,276,849,599,158,618,150,483,587,950,614,173,297,866,816,880,210,314,268,511,321,407,390,558,221,785,219,426,663,928,410,523,686,443,23,500,707,549,194,125,623,67,820,324,793,523,928,505,879,566,28,850,764,656,778,419,899,378,261,335,396,984,143,348,264,373,291,166,367,687,355,246,140,340,337,157,576,59,522,252,562,610,820,656,897,424,796,699,529,371,807,417,861,764,209,831,117,921,33,137,613,706,584,111,575,421,605,198,207,189,518,89,93,232,66,949,534,110,345,771,326,155,62,579,243,550,744,57,343,690,483,927,225,757,479,682,988,63,828,428,267,918,172,363,333,381,292,278,407,892,899,653,632,728,758,855,778,311,181,912,733,515,313,151,886,825,961,195,328,160,529,582,305,697,427,827,62,771,138,705,165,351,85,59,466,191,180,14,192,585,279,816,204,124,761,916,457,829,92,927,978,779,324,324,641,998,515,820,672,409,850,923,108,159,759,107,964,123,579,277,104,624,738,775,195,692,203,267,328,825,664,327,789,966,876,794,649,346,437,496,861,541,350,77,609,722,258,11,32,645,471,936,264,125,55,351,44,799,250,788,546,943,115,405,989,659,469,760,273,845,601,268,810,596,684,505,735,86,26,544,809,657,169,764,897,948,674,408,843,576,363,967,392,750,348,801,822,481,934,311,469,93,506,212,169,643,809,642,28,560,657,616,902,887,753,775,334,68,245,66,650,501,382,584,887,736,432,81,633,9,422,626,884,905,338,70,725,691,76,985,23,461,414,918,246,698,804,966,948,341,426,542,903,551,118,823,766,885,312,234,26,237,207,596,380,519,802,268,563,304,127,776,336,250,992,813,646,175,769,206,952,18,828,226,225,194,475,468,631,603,611,382,743,770,240,869,588,34,593,655,866,69,756,553,85,198,156,575,506,102,455,675,584,560,743,644,585,214,413,19,173,823,995,484,319,201,943,860,27,42,249,657,968,846,437,72,675,582,2,229,441,450,298,449,128,725,117,246,443,190,153,894,337,530,310,348,193,627,971,2,903,673,534,805,331,11,150,184,21,584,792,483,672,967,61,431,985,949,664,890,415,425,713,518,538,22,903,85,621,275,100,979,271,982,323,37,209,161,945,926,826,433,223,937,23,647,10,113,563,186,273,233,953,175,850,976,832,594,110,294,402,750,1000,926,39,640,977,208,631,840,318,621,748,366,225,174,455,636,984,822,289,237,274,427,527,100,386,571,880,15,99,376,194,864,928,564,496,570,864,176,776,143,713,101,86,412,210,190,909,478,645,120,335,207,872,459,451,521,123,563,658,727,527,312,270,411,380,51,911,943,437,132,227,126,59,453,716,786,837,316,218,512,657,821,672,711,876,987,509,566,318,814,452,546,594,991,880,614,82,787,739,470,469,911,948,453,98,11,14,109,634,282,844,898,935,967,732,810,616,436,376,349,773,566,726,887,84,461,135,413,451,46,535,787,172,475,514,313,398,581,591,19,164,649,575,472,727,296,95,847,803,549,736,144,877,996,424,323,169,52,516,841,766,976,689,974,988,363,715,497,847,240,969,126,276,342,334,727,474,755,894,289,330,61,449,183,951,975,572,855,453,92,302,671,948,329,33,234,499,866,555,24,16,689,255,302,992,840,941,58,317,464,6,928,483,297,66,893,811,762,23,829,197,138,835,383,496", "435,125,593,65,850,97,148,170,845,457,782,178,968,529,112,389,980,226,631,854,23,868,340,19,899,237,388,551,661,542,118,986,602,260,706,577,907,850,273,433,104,422,12,90,776,146,47,398,915,585,954,470,495,469,399,894,975,529,214,54,418,248,768,681,231,47,616,78,624,900,473,580,556,561,5,99,417,670,650,660,162,497,820,392,309,226,681,810,324,221,903,560,433,541,550,671,569,468,847,656,675,211,782,922,227,513,693,255,181,204,517,875,141,583,899,38,432,277,374,58,27,733,393,213,76,928,481,808,539,352,61,944,734,503,931,0,290,797,581,57,306,783,69,761,741,173,731,570,221,121,834,29,658,994,987,6,974,858,663,447,67,280,327,536,769,125,405,859,437,871,230,967,990,8,107,620,132,761,877,610,358,2,569,171,23,217,199,180,602,38,452,235,820,538,174,110,151,111,653,603,8,255,417,922,128,532,903,983,91,699,796,462,55,838,118,229,143,221,696,426,4,256,479,258,940,299,170,889,287,479,418,909,549,424,739,701,780,920,733,124,637,496,914,84,143,542,448,20,686,964,436,802,516,765,330,365,982,432,445,921,718,23,845,243,598,332,223,473,980,746,859,23,728,350,253,590,414,202,442,549,537,850,600,252,385,865,660,349,339,631,373,899,523,902,171,86,64,338,7,882,467,434,815,901,335,459,292,507,730,900,955,175,957,255,462,303,481,824,284,232,273,953,498,225,254,320,968,254,79,834,698,102,660,479,246,40,268,511,276,730,899,633,731,301,709,90,36,524,213,864,636,131,602,702,517,256,444,683,957,668,540,385,147,322,778,802,731,249,576,320,818,917,68,93,312,160,968,794,837,75,423,826,671,467,117,609,777,509,341,302,122,563,371,24,880,283,590,37,413,776,999,846,382,618,870,566,904,378,54,934,762,368,619,715,981,238,467,560,737,307,24,688,741,388,548,290,559,62,219,889,42,959,440,394,506,441,296,661,404,577,354,652,216,661,365,861,881,975,663,803,574,244,25,80,776,742,718,842,712,311,448,116,846,443,805,518,992,476,919,172,299,434,374,397,508,41,758,527,426,423,632,684,462,750,765,405,896,18,141,298,847,317,794,3,846,892,119,917,172,882,876,939,789,652,67,104,269,498,915,824,704,390,971,172,3,713,853,183,21,841,608,445,162,419,538,897,490,559,885,163,885,166,921,899,257,185,765,611,110,409,437,762,124,432,781,738,274,409,309,608,782,695,146,193,217,463,901,885,228,272,584,730,317,21,221,257,731,641,925,479,815,94,541,312,799,111,825,45,426,417,515,567,61,386,259,494,752,58,200,269,137,751,600,576,188,444,585,716,34,953,80,300,847,452,403,159,908,719,114,937,333,617,806,895,458,615,462,734,703,4,864,192,361,679,951,697,247,553,812,575,939,22,255,618,367,876,41,906,247,839,114,821,803,917,202,441,443,973,476,115,484,304,51,431,144,947,476,777,476,814,194,893,441,340,919,550,837,310,567,613,108,99,359,774,33,19,224,450,960,94,147,958,72,174,420,635,556,468,292,864,562,413,731,108,4,594,975,201,852,95,841,982,932,155,702,632,521,809,292,684,482,472,120,573,319,70,42,918,995,822,24,215,762,450,166,790,277,207,1,148,52,82,792,67,533,818,452,68,663,30,249,216,879,784,497,712,372,117,217,517,506,686,747,533,296,166,923,516,438,126,343,309,944,234,792,890,408,153,71,457,803,511,219,453,96,544,863,722,807,666,166,380,45,952,877,668,235,225,793,853,126,566,489,323,717,895,652,185,435,137,203,155,878,971,849,396,998,673,663,935,504,41,308,625,158,714,804,897,392,825,289,188,341,376,168,60,709,660,501,273,546,797,143,120,272,120,597,630,499,352,904,186,672,889,32,40,911,108,170,115,998,871,117,658,838,638,733,323,398,656,295,683,293,175,445,14,140,858,845,354,694,407,642,791,669,838,610,846,800,27,879,79,178,855,136,335,231,28,221,304,354,808,242,647,807,245,152,163,487,680,318,500,397,627,140,858,599,51,755,983,672,998,175,580,734,571,128,258,558,126,922,381,502,686,219,8,12,907,410,161,397,485,745,523,551,148,788,174,626,685,126,560,92,264,476,482,384,443,448,918,194,862,416,142,684,900,464,373,604,70,136,173,940,791,715,257,523,180,829,442,720,683,146,391,690,420,256,598,939,98,212,153,40,282,539,894,870,331,804,63,403,985,155,386,563,129,753,201,564,38", "559,560,511,555,374,523,472,167,943,90,766,788,711,456,225,651,278,613,773,682,671,499,976,147,145,203,874,308,356,323,51,812,732,888,550,110,841,236,776,448,556,122,252,255,316,57,932,407,94,247,182,281,44,539,551,550,9,927,996,144,411,653,96,436,996,703,284,197,191,267,400,835,289,900,807,413,133,390,956,655,446,538,780,778,12,377,495,834,523,374,831,609,559,94,235,626,678,44,888,285,645,18,821,614,806,567,443,866,934,389,529,521,287,201,639,682,148,682,153,245,187,610,374,924,601,944,732,227,513,144,345,641,786,244,351,290,0,176,575,629,986,230,976,364,720,474,837,698,508,369,431,734,504,626,141,85,861,569,301,319,670,817,32,156,619,998,893,255,156,938,209,272,328,968,561,640,388,765,457,359,181,210,331,412,510,300,795,399,298,881,620,702,872,326,317,126,262,219,110,143,562,814,290,10,353,222,619,743,857,364,701,733,954,543,802,493,20,816,13,49,348,405,123,876,237,731,60,552,832,564,121,274,99,309,631,912,23,444,994,7,333,241,38,896,146,504,614,378,953,685,104,111,135,790,758,240,763,429,565,178,321,12,283,36,711,399,679,330,801,36,709,799,123,773,786,192,960,983,122,779,152,131,987,440,191,637,292,946,936,106,204,664,355,275,566,375,328,444,264,212,617,550,691,880,573,229,677,652,71,309,693,727,947,249,652,654,152,32,980,593,24,366,489,994,588,403,624,73,718,814,138,288,420,204,745,258,193,746,940,502,740,563,889,765,360,712,908,551,488,713,722,443,477,615,129,912,281,533,994,687,133,768,465,928,63,755,537,86,170,248,125,301,436,652,863,883,552,282,418,470,633,158,970,840,336,182,547,380,240,345,516,867,854,190,75,662,930,987,330,53,757,143,281,158,779,119,407,51,616,959,34,912,406,511,592,567,750,633,128,910,584,365,607,705,984,168,900,756,719,324,46,164,908,229,852,410,717,672,193,600,622,14,138,311,536,820,346,651,666,131,455,345,503,20,495,625,536,658,407,199,630,351,951,389,835,327,202,273,818,60,403,106,962,892,625,733,710,682,280,283,425,615,903,527,712,89,611,757,400,152,120,264,525,551,694,521,516,96,975,226,809,361,278,473,157,201,877,631,60,376,777,355,352,448,352,114,390,235,137,921,532,740,360,713,963,361,350,444,668,22,366,104,452,151,833,114,53,624,1000,741,200,884,788,541,204,706,988,567,78,634,351,200,431,548,939,463,416,701,360,450,682,248,50,536,24,357,510,8,933,842,793,533,279,589,337,540,660,53,919,58,455,795,12,753,634,215,89,560,849,168,739,560,911,487,295,128,493,161,517,357,925,700,58,790,175,466,762,690,324,823,958,428,677,517,620,536,782,195,590,423,282,964,725,3,896,94,36,243,483,393,190,534,848,763,85,927,200,347,771,130,722,905,217,463,365,843,780,752,851,303,633,511,530,817,564,382,288,101,427,548,579,805,175,559,758,971,919,295,825,33,322,990,693,935,462,861,338,36,455,151,279,832,856,21,555,513,707,925,891,855,335,808,658,383,115,414,814,779,521,302,250,23,648,82,145,546,301,496,549,476,185,283,345,941,152,778,295,879,72,939,343,30,967,765,70,574,199,963,810,680,220,351,693,185,781,771,399,166,851,139,617,258,887,127,569,821,106,552,445,402,578,546,92,112,605,597,373,216,588,742,42,317,788,392,310,213,252,309,93,532,388,558,658,782,734,472,824,422,706,395,579,567,856,40,452,242,718,310,405,895,735,623,614,112,143,616,244,314,661,495,743,262,434,954,853,655,517,851,451,205,312,504,920,498,416,440,101,976,934,200,849,923,388,522,695,737,402,575,57,560,420,161,437,24,16,691,906,165,279,476,801,324,955,669,613,778,144,437,236,743,320,169,112,245,619,783,341,775,921,763,950,849,381,909,151,211,389,962,287,298,564,493,396,273,12,686,440,273,427,911,724,733,949,561,772,408,425,743,221,584,903,665,521,302,820,776,160,648,118,560,174,926,919,245,750,970,134,856,671,882,102,608,253,349,222,604,24,948,843,456,252,145,400,747,607,926,520,621,497,550,696,833,123,203,719,76,858,860,485,226,517,525,705,28,819,361,675,364,781,658,164,724,335,421,61,803,234,337,865,809,47,725,276,981,256,349,802,434,255,72,252,575,861,133,323,671,133,316,293,888,687,600,303,195,622,588,874,676,19,303,485,295,867,6,973,293,514,826,974,190", "283,335,430,158,206,220,479,509,520,342,478,787,451,379,176,275,191,390,247,582,17,396,652,647,116,850,833,368,348,661,644,450,388,448,386,168,819,91,773,652,536,735,241,919,274,563,767,4,202,765,595,476,115,672,16,629,187,231,704,326,939,229,649,8,279,285,114,723,399,142,350,796,828,754,889,712,114,700,361,200,652,492,812,11,582,380,608,466,180,909,485,924,352,627,818,663,377,469,671,832,250,594,656,899,289,650,780,805,439,46,710,860,237,684,5,125,888,368,376,336,135,432,862,499,27,876,645,164,133,636,710,687,629,422,515,797,176,0,160,435,672,292,756,320,383,674,250,210,786,444,447,977,479,258,403,868,102,245,475,615,791,701,60,986,862,958,915,52,164,208,26,734,929,54,935,756,539,989,394,683,743,672,503,105,304,896,27,850,142,425,148,499,482,922,87,184,920,834,855,125,271,439,546,928,610,527,963,437,728,340,827,165,368,169,539,890,73,19,455,819,564,275,978,946,657,708,415,982,131,271,75,995,976,569,50,938,863,845,975,495,463,591,629,602,544,190,200,521,352,694,542,209,625,44,392,682,297,312,236,956,18,260,256,976,399,29,398,843,632,442,898,845,912,779,248,8,965,142,232,599,49,60,740,529,147,122,362,192,294,586,815,616,607,410,35,52,395,53,846,968,969,744,921,618,429,27,489,545,951,828,726,568,208,777,230,113,703,553,933,257,515,895,725,682,303,215,207,597,180,844,523,141,198,286,970,515,869,49,376,258,905,536,468,587,259,22,505,636,795,224,672,443,992,615,6,107,523,476,281,880,836,289,487,975,817,559,216,427,893,363,459,457,476,961,145,256,685,691,154,156,766,484,727,942,669,977,746,756,149,331,613,913,281,670,540,752,967,941,736,148,621,4,987,324,854,118,896,600,613,55,146,415,617,949,58,43,822,717,584,818,316,80,115,783,606,821,651,756,232,824,369,363,338,514,589,642,918,718,946,83,41,768,680,597,955,806,42,225,979,91,754,757,439,900,71,998,880,245,764,456,54,749,960,559,593,685,193,806,40,143,719,956,71,359,437,382,102,418,160,988,939,813,409,699,678,247,491,352,70,485,398,562,714,760,742,663,806,554,796,395,123,345,882,629,533,204,866,952,395,265,889,99,797,803,128,576,460,736,219,219,576,70,113,88,527,506,508,39,369,971,360,555,728,577,160,913,227,394,752,922,504,941,902,331,361,800,132,409,192,860,481,750,956,877,562,478,570,557,590,291,323,521,584,526,553,20,830,366,36,311,645,222,6,976,553,229,962,328,552,955,282,136,24,520,215,157,819,663,924,836,986,168,694,443,332,377,356,105,344,469,264,310,339,997,379,823,536,989,750,12,602,918,712,235,233,344,507,388,902,25,617,44,137,435,367,957,262,863,247,40,570,626,56,877,659,29,606,926,25,266,593,193,627,950,296,296,855,739,788,895,607,610,847,924,823,892,779,977,841,536,159,304,534,226,148,749,708,502,733,784,594,829,451,822,198,204,527,986,822,920,228,346,412,803,67,53,927,213,858,590,81,38,571,347,98,933,148,979,448,743,463,725,355,928,397,955,865,136,305,447,443,826,488,16,556,614,639,85,398,977,180,329,315,76,361,583,150,468,714,982,881,308,119,693,56,945,280,574,572,19,344,700,227,832,629,712,661,336,823,558,675,209,413,378,196,446,474,295,795,160,304,967,722,491,859,578,11,850,3,805,254,258,332,603,543,597,300,324,899,700,682,643,288,368,881,621,690,179,702,384,304,447,426,586,173,300,458,199,156,3,99,492,454,7,454,319,273,185,35,469,382,16,990,931,192,724,659,322,70,763,256,586,411,621,322,554,807,72,144,468,806,463,983,201,506,926,329,267,94,515,785,61,443,445,884,659,34,528,976,657,864,798,555,389,28,903,81,112,258,110,127,327,97,219,472,51,793,602,794,909,623,980,426,619,959,337,559,969,350,564,104,742,823,506,731,976,124,267,890,767,524,203,728,765,130,746,940,116,884,343,85,497,398,850,795,901,869,423,838,161,993,650,204,735,557,902,460,268,443,274,773,899,268,26,547,404,964,458,850,805,129,344,740,61,479,637,316,846,900,203,320,137,999,883,767,567,320,560,33,106,402,720,661,80,647,93,141,396,367,691,33,360,366,188,531,103,213,930,914,61,686,882,927,535,766,874,904,336,687,457,120,458,40,456,94,679,349,100,605,838,742,72,85,881,894,449,937,919,658,623", "562,612,516,438,544,821,969,986,438,314,295,271,283,560,258,178,139,189,854,549,708,871,122,6,410,107,433,133,815,149,296,235,620,75,798,382,521,809,177,864,995,105,448,455,53,271,571,420,505,765,385,915,538,892,105,26,918,74,649,924,842,852,610,585,751,905,706,490,823,461,679,327,992,630,409,78,666,602,618,168,508,266,55,378,616,77,35,380,588,682,662,647,698,988,26,193,244,242,803,96,78,763,921,805,310,247,623,763,757,525,81,686,205,56,575,857,950,973,220,933,42,590,550,125,584,69,523,468,320,590,992,502,769,354,330,581,575,160,0,317,140,590,46,38,784,651,461,70,834,674,322,907,358,748,1,654,571,313,592,410,527,571,638,391,585,308,279,616,556,759,164,716,584,916,381,598,716,36,957,973,629,867,407,696,554,505,144,881,290,586,866,471,884,270,629,895,649,697,143,58,540,150,403,487,540,62,816,747,41,926,509,938,412,17,907,618,227,163,434,774,884,884,881,978,67,116,210,791,902,636,377,730,744,700,713,726,303,885,455,803,400,749,881,982,887,280,337,788,207,997,644,822,132,934,332,753,47,265,236,589,995,428,265,770,23,937,544,208,728,952,834,295,272,23,98,825,705,751,25,903,883,768,879,85,563,314,272,895,71,298,250,207,259,293,71,289,289,372,23,371,166,885,750,144,433,53,671,12,11,964,295,529,116,253,707,683,653,929,729,894,479,749,94,855,114,458,993,988,350,843,752,735,409,242,857,790,339,627,341,943,816,399,278,321,778,559,52,807,863,315,814,200,799,643,769,392,879,448,207,65,847,200,45,122,30,608,800,574,656,220,263,677,854,568,950,716,556,806,523,497,130,702,278,663,222,298,997,51,608,656,862,481,549,510,129,177,791,983,472,371,582,807,156,126,171,732,342,245,467,381,874,632,87,950,74,52,755,265,911,872,281,845,66,986,707,878,565,627,710,550,865,78,880,601,307,661,1,881,948,473,335,600,428,208,408,109,27,67,745,443,57,314,672,345,486,415,731,106,846,203,224,986,344,913,812,182,806,470,824,244,282,661,583,372,612,422,398,876,59,961,126,462,11,611,874,166,100,545,39,717,96,362,987,455,877,753,225,136,428,555,781,119,568,258,291,597,79,306,62,718,102,334,208,709,323,860,796,439,297,714,730,910,743,39,447,887,962,451,104,791,999,811,213,703,190,457,334,888,962,85,332,335,180,372,801,921,774,803,382,834,46,85,458,218,265,872,937,383,855,393,19,44,963,655,570,568,267,342,164,239,403,669,874,781,229,729,572,858,613,235,31,606,769,809,125,319,474,181,770,412,268,215,944,540,273,681,864,284,182,345,723,856,479,872,283,443,183,74,57,477,446,704,592,633,683,204,505,823,790,677,523,622,385,800,949,21,508,748,955,216,347,382,42,662,672,999,661,561,814,721,274,85,156,966,290,384,925,412,395,273,585,571,823,954,372,228,395,746,411,47,784,649,481,247,922,592,933,311,455,374,787,162,279,110,834,803,185,226,859,919,402,631,662,612,40,362,281,697,636,970,371,822,52,534,17,273,193,461,274,707,207,821,411,740,959,144,319,256,562,623,595,314,944,155,413,559,690,119,314,122,843,251,217,262,428,337,373,844,949,438,265,435,783,457,515,170,514,954,260,561,432,795,138,698,755,636,761,865,463,397,675,371,621,455,582,358,48,745,789,83,8,925,609,835,488,900,81,458,701,792,315,977,121,92,383,236,945,846,419,67,333,718,692,543,56,562,103,436,183,965,831,391,281,467,492,322,157,189,619,101,53,280,742,800,545,566,192,581,491,158,995,776,392,762,343,910,890,501,439,707,131,470,696,829,237,327,556,624,275,873,616,519,181,241,148,540,649,229,147,192,748,845,481,795,486,651,976,645,997,77,543,837,451,586,404,415,391,901,222,36,699,818,969,710,629,102,999,206,149,560,314,556,943,870,83,269,402,905,306,981,118,639,665,868,397,949,880,334,85,537,3,518,519,118,516,716,521,721,142,654,754,22,690,52,278,969,980,693,112,895,953,11,665,72,802,859,978,384,573,219,993,341,762,288,994,380,369,541,702,805,206,591,600,18,998,35,960,281,214,901,658,458,723,327,399,610,409,694,364,222,202,955,2,936,970,271,392,248,784,499,533,639,198,91,320,740,311,392,733,224,133,788,490,408,1000,830,144,352,126,372,396,742,527,808,62,324,967,995,402,441,103,427,940,311,188,901,161,551,339,124", "798,16,646,681,833,140,463,13,947,568,512,923,906,32,702,549,92,327,632,693,154,87,182,2,246,327,970,666,438,88,715,902,822,824,286,121,40,63,610,113,770,411,926,310,948,613,391,889,370,436,203,780,12,398,936,351,40,912,933,665,240,873,597,383,857,226,585,374,47,712,564,583,278,159,223,443,882,560,160,42,976,455,474,796,847,936,191,490,644,734,711,556,474,992,745,536,727,577,278,447,221,712,4,157,843,472,197,656,117,202,174,273,326,576,483,746,899,705,128,175,207,883,241,967,308,211,543,273,77,893,762,725,732,230,549,57,629,435,317,0,251,532,19,465,810,839,90,742,567,459,333,780,36,397,781,763,780,818,769,728,391,641,230,32,999,699,843,476,985,734,829,350,86,65,481,673,325,649,623,710,328,331,450,158,288,605,519,890,809,122,198,16,225,849,886,667,496,800,75,692,794,347,864,528,947,734,35,143,568,912,94,302,599,270,256,942,251,797,189,89,668,232,429,663,50,511,293,19,762,588,305,889,158,886,12,701,326,993,892,704,301,392,292,306,68,405,6,545,803,352,489,330,127,7,898,624,995,73,814,508,40,777,414,561,352,898,401,282,867,960,959,688,437,515,548,520,279,994,88,296,121,878,734,722,678,754,225,764,940,511,192,12,105,192,568,912,785,700,242,98,292,84,848,149,53,946,820,60,284,301,138,579,347,302,500,237,294,564,715,437,424,775,833,536,265,54,687,200,972,775,992,438,801,363,713,476,602,524,172,488,593,722,746,130,751,352,161,944,506,213,35,909,556,174,873,743,277,842,243,220,349,264,884,25,792,803,239,568,352,856,368,251,660,740,790,816,836,843,304,516,741,218,631,660,142,442,161,575,27,480,54,547,18,981,346,402,738,322,858,294,702,812,652,807,652,624,118,686,44,816,847,732,549,562,323,775,869,422,805,651,845,249,209,956,9,633,765,582,6,98,59,429,334,887,879,174,826,236,531,703,669,872,518,255,326,313,585,668,212,307,77,998,946,575,530,250,631,926,219,6,496,15,520,25,325,809,528,480,264,251,729,787,733,484,517,825,226,960,872,921,596,622,128,929,317,41,209,303,345,104,19,19,831,954,248,61,979,848,886,965,126,395,379,842,201,698,595,337,597,378,951,554,746,88,23,103,564,715,459,130,584,645,563,746,645,890,89,905,718,59,700,513,540,668,739,703,630,93,630,686,766,173,961,437,418,58,726,865,429,236,130,187,237,507,545,604,371,448,70,861,914,392,117,352,150,481,334,843,557,462,127,206,745,395,181,136,552,486,451,900,451,358,413,695,621,401,826,108,586,251,833,691,774,676,437,12,763,431,640,956,403,656,413,523,653,872,977,21,638,948,433,492,519,704,832,245,643,563,456,518,718,694,924,301,98,686,927,265,644,407,295,703,619,132,796,966,247,853,693,63,446,895,716,556,872,331,832,130,736,199,196,631,827,783,832,863,658,184,87,821,476,228,745,929,446,868,881,513,347,851,788,428,987,739,73,592,530,702,52,291,880,992,350,897,232,213,64,762,696,543,608,501,280,140,118,860,398,223,547,256,166,567,226,760,68,833,728,989,677,334,503,906,129,682,199,574,583,177,638,53,407,794,152,690,39,522,738,491,781,427,684,340,276,513,184,575,94,903,172,469,127,695,858,15,427,473,563,106,296,894,168,480,55,435,419,443,156,980,786,249,278,266,483,884,763,958,581,299,237,551,694,141,93,301,454,198,82,544,197,553,98,4,278,601,981,409,296,311,431,506,601,707,562,306,635,179,974,620,34,956,13,234,852,314,599,491,665,78,217,23,243,318,256,346,518,879,461,854,138,605,681,212,307,791,28,441,95,418,713,601,706,81,355,35,395,644,192,871,279,182,571,228,600,953,115,5,685,907,92,717,216,992,710,374,662,366,337,912,856,840,389,730,348,504,878,401,863,106,648,258,462,950,445,925,103,879,861,159,411,304,419,811,505,356,287,65,191,993,458,88,249,412,919,519,264,474,589,823,346,853,945,961,909,116,234,682,892,884,193,823,112,596,579,45,984,442,334,544,455,808,883,244,332,270,353,866,874,902,317,997,792,653,185,689,317,776,891,903,506,128,955,854,594,778,971,254,894,36,767,13,514,575,555,265,639,19,77,145,234,794,668,37,742,872,72,191,121,254,836,828,86,949,413,653,620,442,863,970,881,487,513,806,81,66,744,78,448,837,774,836,58,508,220,322,498,919,716,890,935,160", "349,296,640,78,198,285,751,375,309,326,484,880,890,748,647,624,852,413,999,373,427,15,203,568,271,586,263,48,444,520,523,804,788,971,634,790,941,12,671,383,834,810,884,539,669,419,768,479,381,775,827,651,953,978,178,426,362,29,669,858,849,110,612,948,635,977,921,139,126,176,17,524,744,759,854,196,835,38,570,321,636,260,611,515,271,609,497,658,202,681,686,932,774,868,742,317,918,686,369,108,562,610,755,15,518,928,511,16,692,927,202,268,784,710,866,811,67,276,756,585,8,318,372,222,641,210,208,931,748,654,667,140,319,943,44,306,986,672,140,251,0,63,630,532,985,622,807,872,708,650,242,242,119,813,133,869,692,178,439,756,728,444,711,274,855,130,897,882,922,10,341,450,974,359,230,587,332,547,771,499,157,985,167,397,72,398,31,491,153,860,257,976,432,764,582,764,712,807,76,617,581,947,631,250,184,115,95,518,669,43,232,58,101,582,534,363,834,720,527,849,679,574,679,482,968,838,807,449,4,886,932,457,760,194,148,80,675,292,333,945,605,353,209,549,576,772,907,122,170,221,216,464,703,278,114,985,120,578,238,432,392,339,153,939,342,695,684,358,115,592,321,26,614,604,896,202,306,639,287,287,5,937,214,159,83,87,368,118,975,165,876,577,765,118,550,223,100,624,37,486,26,584,273,246,79,370,758,376,159,662,248,261,17,228,345,502,90,547,530,189,115,535,524,217,981,679,11,499,694,651,352,875,612,766,431,655,936,894,368,204,73,615,540,390,29,774,538,417,104,344,313,249,107,946,598,509,656,161,422,714,478,4,240,664,678,462,448,586,344,177,724,225,350,472,18,922,162,852,474,171,928,213,253,767,485,447,975,910,243,684,351,748,699,451,467,726,961,846,389,555,807,368,258,467,309,89,786,906,227,157,652,898,797,217,732,625,371,685,542,608,458,183,899,480,374,861,460,937,817,614,124,248,556,437,598,560,452,182,61,453,965,491,357,89,744,59,171,158,100,387,699,945,575,293,442,465,844,602,974,32,890,552,832,494,645,254,428,592,191,883,692,856,72,952,686,198,885,863,947,701,35,54,961,257,777,817,112,901,256,949,804,709,989,366,420,413,616,812,853,865,681,656,453,75,706,641,708,621,271,484,761,470,384,896,586,391,44,580,159,670,253,551,986,572,666,635,899,843,416,888,998,330,145,991,548,697,596,481,735,652,518,39,633,946,113,416,775,609,942,964,359,604,129,43,393,693,294,457,245,782,915,601,979,105,118,429,322,429,714,175,871,392,760,648,891,627,446,450,882,244,241,989,192,617,988,288,630,809,385,514,285,593,549,981,766,825,634,380,61,438,717,897,985,687,725,22,483,824,178,479,157,556,725,870,275,118,198,621,79,275,341,632,169,753,589,26,704,980,883,889,457,950,180,950,318,300,747,235,227,732,629,574,180,747,125,230,963,50,438,20,518,426,290,345,73,471,514,384,439,599,808,837,250,249,632,86,433,743,71,744,789,223,831,50,83,17,900,496,678,656,528,124,883,672,984,672,71,362,173,482,871,437,155,444,218,450,141,637,528,302,181,71,874,819,877,278,887,922,434,797,929,932,402,545,284,768,979,510,653,157,323,927,707,149,211,583,358,623,757,648,951,49,55,234,208,581,585,691,535,611,421,5,780,192,747,507,171,860,466,305,522,546,910,23,295,618,898,267,812,127,505,913,486,880,957,94,705,825,366,547,289,330,319,84,510,499,262,666,860,122,750,74,591,301,638,803,191,813,919,498,298,709,361,630,21,724,195,882,705,379,1,252,646,225,743,347,684,378,292,162,882,202,549,554,145,606,785,399,769,801,841,48,152,845,406,261,595,592,916,342,652,480,319,319,48,815,753,656,315,998,946,319,50,368,894,70,420,435,671,417,129,124,367,365,671,124,644,951,895,933,467,908,122,448,150,36,881,982,983,83,15,815,942,60,843,541,539,190,880,883,562,709,634,861,104,271,856,619,244,997,620,759,667,31,592,141,965,402,345,473,934,944,885,778,668,943,141,109,83,340,238,49,762,3,267,139,473,469,374,401,669,244,33,986,488,182,581,482,918,335,817,615,839,552,870,508,920,210,974,838,539,412,954,36,949,662,171,782,157,807,9,720,70,279,28,764,156,296,699,442,870,288,76,720,605,249,374,902,495,374,271,189,995,798,274,832,955,324,692,389,706,881,974,803,91,487,779,465,560,46,710,825,786,273,223,33,171,168,153,152", "201,884,294,447,844,367,379,779,441,952,542,858,172,629,849,102,34,267,466,326,964,366,535,709,696,731,582,113,860,814,535,563,93,592,580,590,558,129,35,317,303,444,965,738,772,245,694,727,289,745,294,321,45,343,778,935,377,546,605,450,430,123,898,417,994,449,743,234,63,825,197,799,63,444,175,739,743,791,772,794,758,555,589,973,493,597,600,706,666,739,194,528,159,195,115,421,296,202,860,508,589,146,428,234,43,457,410,989,317,780,973,582,504,783,113,464,423,377,144,986,848,471,922,858,686,949,104,342,916,669,181,31,334,706,913,783,230,292,590,532,63,0,856,39,725,224,18,943,809,208,35,528,659,158,264,408,951,665,958,42,641,782,53,177,952,184,147,488,272,324,57,474,369,747,643,448,612,623,683,628,936,373,997,298,217,770,666,540,247,665,62,105,425,14,449,93,252,169,546,188,702,505,497,551,379,115,224,217,871,173,176,36,571,942,576,503,388,210,808,22,802,585,512,787,500,604,638,404,163,171,652,639,105,818,381,459,421,118,731,391,178,772,144,210,907,254,744,376,182,58,60,891,809,482,495,129,37,260,192,682,732,10,413,101,224,433,940,425,536,967,891,206,870,768,263,389,640,100,833,643,999,560,212,311,96,359,720,846,852,198,581,319,508,53,707,288,888,387,788,505,489,459,212,149,664,963,361,713,340,516,459,234,852,112,755,157,949,317,919,943,437,876,291,28,533,715,393,456,129,323,388,478,799,83,935,953,422,410,604,754,481,11,408,173,21,74,739,229,418,254,456,989,46,966,600,74,376,281,841,510,232,872,980,580,303,337,684,208,144,418,338,183,308,249,121,632,17,168,299,177,836,103,834,459,973,865,524,604,795,993,770,554,126,626,472,825,364,657,200,292,326,357,462,428,788,912,570,545,935,304,245,951,546,434,848,172,339,40,791,890,397,713,205,309,179,910,308,386,9,403,286,173,734,740,971,97,451,834,829,84,176,179,703,611,108,321,621,288,234,409,711,543,563,64,296,313,161,532,724,902,618,213,102,100,945,386,305,907,606,108,945,991,881,934,458,523,414,201,659,199,546,971,422,582,647,720,964,740,386,172,772,110,605,590,754,491,701,139,674,277,583,192,519,259,617,442,424,736,184,49,260,355,652,627,856,128,856,670,129,862,990,125,679,113,468,299,393,688,202,67,610,924,694,602,347,171,797,447,568,439,713,404,532,945,754,112,279,492,794,786,320,477,43,448,350,467,702,529,529,463,135,171,323,761,693,631,580,465,870,299,831,412,865,467,945,664,577,339,729,101,429,723,169,121,624,593,944,458,588,796,55,642,381,402,973,259,759,869,259,628,644,57,110,476,841,25,44,158,300,597,610,409,145,954,557,17,967,377,289,20,522,487,285,711,323,401,914,390,784,437,386,797,198,433,486,436,56,438,280,717,279,96,723,132,644,750,396,312,607,726,629,57,168,664,589,107,358,402,28,406,393,788,379,953,565,41,357,485,868,901,437,132,69,97,312,196,110,549,880,804,300,491,929,150,762,100,73,337,681,135,593,918,633,43,449,497,406,429,863,446,316,245,691,547,351,535,770,604,103,523,25,299,621,674,955,849,587,449,578,222,48,268,180,21,287,687,642,863,392,996,737,657,835,359,305,584,154,357,830,388,718,120,481,472,462,759,739,995,305,894,736,81,911,534,221,200,922,181,156,335,427,519,926,181,101,847,493,923,564,81,32,987,363,853,189,37,238,881,785,770,47,645,405,644,846,106,744,147,279,769,935,973,991,538,603,318,200,254,709,996,348,320,734,523,872,640,204,910,454,154,430,474,58,144,572,21,426,448,581,315,23,102,361,545,678,567,770,287,480,685,212,410,996,305,433,512,129,910,198,939,727,203,43,620,91,951,701,825,403,283,482,139,871,919,650,798,908,448,494,504,625,131,407,897,26,778,842,909,642,100,134,51,741,735,721,855,685,290,206,463,961,784,37,607,696,496,531,234,138,16,219,696,884,966,962,545,584,568,380,580,654,96,983,336,711,580,432,716,242,42,369,471,502,929,767,521,359,347,220,376,835,157,246,515,310,672,592,791,623,331,400,665,753,88,497,134,239,509,926,186,358,706,220,474,984,856,449,179,673,568,381,722,404,62,628,570,917,692,968,448,166,234,344,118,173,468,775,370,235,886,859,32,471,664,963,474,277,905,985,513,25,102,85,906,421,813,139,729,683,250,605,774,397,359,51,880,627,461,458,872", "383,446,623,931,658,287,202,478,43,541,210,213,416,629,288,291,768,669,589,337,446,261,808,661,231,452,365,317,570,621,731,620,593,958,584,779,137,170,338,977,239,357,307,787,43,753,86,952,748,639,940,426,613,171,287,519,173,949,814,500,735,267,859,492,255,73,739,850,886,123,81,367,637,606,787,231,865,751,963,870,716,910,679,314,953,356,658,242,102,985,809,923,911,574,443,321,404,767,71,330,736,809,39,864,846,308,483,266,935,919,683,24,899,420,885,261,847,533,629,509,785,770,641,255,563,64,978,625,520,967,65,842,464,431,645,69,976,756,46,19,630,856,0,667,592,355,429,3,166,141,25,659,435,371,389,179,540,711,358,381,803,46,795,467,587,740,523,41,381,831,641,815,301,225,476,690,578,162,264,390,518,134,218,552,248,720,940,486,453,578,15,517,702,507,499,868,785,245,261,495,85,391,133,434,892,986,384,125,914,148,176,274,444,718,597,865,252,246,728,607,275,877,379,123,420,958,787,85,593,829,336,822,142,256,233,135,412,461,372,571,771,641,102,174,757,90,450,313,65,660,500,875,349,825,121,926,670,898,844,87,794,368,425,888,842,567,868,662,250,234,829,475,536,613,294,165,367,974,99,297,911,866,531,197,653,852,285,353,31,52,997,361,980,433,961,957,241,766,604,323,337,933,270,73,251,374,67,877,511,718,182,742,829,188,41,650,345,422,140,15,324,358,730,374,255,9,144,206,148,539,896,132,967,512,835,811,97,254,83,77,846,716,593,394,412,889,291,334,321,531,453,234,861,90,375,729,578,5,423,635,313,620,983,863,956,786,438,348,284,917,801,382,759,703,867,82,570,375,717,362,463,743,896,194,793,314,708,803,558,771,765,27,481,149,33,115,622,460,248,819,907,658,948,303,824,816,202,701,495,530,705,495,20,224,812,362,429,747,472,877,975,985,941,423,798,932,994,197,632,207,942,205,445,166,590,699,970,111,90,616,105,543,932,876,552,201,120,187,311,13,790,604,597,394,89,744,558,38,464,492,19,528,998,809,739,853,740,784,290,527,506,451,974,87,944,645,27,841,31,399,826,415,859,520,689,100,839,714,744,379,964,944,696,517,534,910,426,185,201,618,246,346,289,404,7,342,458,459,476,618,336,699,675,605,898,799,576,214,501,984,117,673,807,783,540,584,457,839,14,855,507,646,63,905,766,296,993,883,398,462,958,118,338,156,217,676,948,154,55,149,298,755,908,254,656,320,13,318,568,380,937,783,35,645,220,400,276,810,39,560,923,153,244,583,8,463,425,905,497,572,599,802,961,317,580,58,920,945,345,280,551,250,13,249,251,321,412,545,826,83,880,70,828,905,348,995,324,838,642,575,206,388,109,987,547,348,154,42,504,923,80,272,501,614,277,341,266,632,450,844,412,23,318,58,739,199,69,278,40,443,105,452,124,21,37,348,936,212,260,787,6,915,171,518,541,800,52,590,8,186,510,82,239,384,488,914,841,616,660,837,502,813,598,849,832,487,499,852,759,366,200,977,767,554,47,464,508,570,414,695,787,384,50,965,174,766,986,180,532,372,71,507,840,952,575,670,515,985,238,887,731,875,435,846,846,413,307,712,973,470,390,380,415,469,20,523,124,989,905,356,936,642,878,939,766,771,486,848,853,925,190,995,481,167,878,334,710,913,778,549,251,815,103,105,97,826,347,773,425,460,651,919,835,962,202,898,909,454,963,125,674,57,909,17,462,936,718,941,691,723,55,86,210,794,292,876,678,430,91,366,630,549,311,643,800,969,506,465,471,508,454,419,839,53,638,872,26,120,879,752,505,807,486,713,386,221,312,886,763,303,585,677,407,886,539,208,270,49,272,405,247,143,948,287,979,308,359,491,892,72,563,820,22,37,234,908,449,488,230,476,635,880,526,989,92,482,249,447,255,699,439,88,981,669,819,753,660,388,955,498,698,318,124,928,811,545,713,733,554,460,980,683,411,808,697,877,689,695,338,326,892,259,52,582,838,452,386,396,906,947,189,831,898,368,28,833,32,526,175,260,33,154,710,233,748,523,242,492,494,920,424,5,609,71,100,362,877,180,187,444,828,342,823,862,878,498,211,816,472,735,217,294,737,185,613,207,445,820,500,470,573,999,693,602,552,768,735,442,351,783,795,901,441,519,80,602,855,251,350,339,890,84,213,69,222,98,46,476,105,919,519,603,154,155,619,153,40,305,367,181,146,157,935,430,691,574,145,932,595,214", "249,530,203,721,692,922,58,393,680,216,58,818,632,795,149,911,784,63,948,706,436,986,108,704,914,550,131,917,20,134,861,192,277,582,596,492,9,51,150,628,335,720,455,954,730,322,639,261,509,254,692,268,321,585,305,426,47,826,492,945,475,781,502,906,386,28,139,634,575,684,709,8,62,11,165,27,801,947,919,157,69,686,643,703,28,715,194,241,156,249,979,472,323,996,4,859,890,507,564,842,308,388,522,356,195,738,10,713,103,468,378,878,2,794,193,904,913,644,718,648,751,820,301,284,504,127,565,285,56,99,117,557,874,135,370,761,364,320,38,465,532,39,667,0,192,766,458,641,400,831,864,772,332,761,540,735,643,978,580,409,489,299,746,720,982,241,336,979,566,331,809,437,979,917,320,112,970,359,613,338,448,841,518,710,318,50,168,452,496,950,385,205,707,150,516,533,205,790,966,250,529,893,679,20,559,500,13,93,448,935,339,795,967,127,184,74,966,262,74,318,174,528,354,810,813,575,641,1000,786,299,774,400,989,577,111,875,890,467,118,488,697,838,497,127,233,464,22,935,93,960,837,49,503,559,75,930,601,977,726,498,458,739,807,363,827,810,917,468,516,756,425,811,393,404,293,448,828,550,766,571,410,210,313,445,985,115,124,606,748,152,619,724,635,485,683,285,917,673,970,203,795,43,144,144,748,131,246,351,606,520,200,174,877,617,794,548,610,43,907,485,546,325,205,514,720,840,614,165,466,621,278,705,803,263,753,59,453,657,960,620,646,832,98,768,257,967,346,39,694,600,328,38,122,634,634,828,344,184,13,868,728,644,723,129,223,207,644,421,22,754,713,423,921,196,961,837,195,664,478,76,768,684,316,616,697,182,305,535,287,437,789,667,807,909,461,294,511,531,54,413,398,901,814,426,120,530,172,64,707,256,980,631,186,116,759,641,535,559,702,419,985,489,692,30,520,564,583,930,583,876,610,861,521,894,279,382,331,637,121,119,447,546,289,203,558,992,417,876,684,830,460,333,270,465,703,985,60,72,294,958,618,265,497,973,366,345,7,588,734,408,631,395,888,615,518,995,746,60,280,547,241,445,151,401,899,341,577,654,379,991,844,999,364,826,644,215,154,340,775,463,989,669,825,795,798,615,637,39,879,977,538,687,603,62,407,147,254,408,441,869,371,60,144,962,292,451,567,19,99,934,573,831,462,921,209,269,927,175,177,359,43,781,25,646,61,899,259,522,526,804,589,800,438,582,387,896,98,442,19,569,161,491,923,697,770,831,200,57,505,958,133,447,123,647,39,116,547,517,620,718,580,20,484,492,439,821,936,658,587,459,764,513,945,992,707,123,335,788,721,35,606,103,62,746,241,127,157,807,535,546,449,804,699,910,306,776,495,490,10,769,434,813,207,153,685,949,679,580,949,761,26,233,38,428,416,699,9,160,461,665,993,751,473,352,598,663,292,352,856,203,447,625,594,122,974,107,405,711,977,653,254,164,909,163,90,7,4,885,682,943,505,201,319,680,964,885,414,871,535,979,254,374,610,250,136,248,710,709,941,176,125,53,231,421,976,617,648,205,361,176,309,332,642,986,978,603,661,192,342,191,49,227,518,856,789,201,689,238,218,633,875,33,8,474,787,70,284,723,569,363,653,399,266,49,209,424,236,943,463,368,15,81,677,674,632,136,367,935,539,151,562,165,919,996,883,179,18,962,447,222,479,205,738,326,252,410,428,955,945,767,732,639,445,511,906,982,565,657,533,337,625,692,595,450,573,909,434,566,171,225,974,261,177,759,230,585,193,7,420,286,303,340,293,720,671,459,257,501,497,255,803,843,266,496,22,416,920,457,918,941,117,82,994,296,251,233,778,808,320,754,479,549,596,593,475,238,850,992,861,736,698,592,633,238,216,854,392,94,832,711,55,826,61,325,696,410,707,777,421,838,547,407,156,734,141,942,851,274,108,625,792,906,227,376,134,160,534,325,925,977,677,564,153,789,434,459,510,456,837,678,925,855,513,478,459,984,610,574,737,957,331,842,596,900,433,338,997,178,614,848,18,186,653,192,450,52,835,985,711,402,623,514,579,490,656,304,751,710,169,462,427,817,503,655,24,931,338,576,307,987,858,438,429,816,640,196,778,503,9,131,433,646,293,577,857,550,40,699,183,898,180,149,618,262,438,878,143,832,939,211,498,584,139,227,724,543,222,516,105,542,965,183,893,141,773,276,826,796,116,910,628,183,594,950,864,552,124,877,275,844", "69,622,717,183,135,213,855,292,725,593,727,463,677,890,199,218,627,543,295,361,56,992,19,54,436,810,300,496,33,855,878,481,721,430,589,871,327,416,725,332,915,536,197,994,583,614,392,61,34,760,671,180,790,413,412,551,735,282,403,652,377,621,420,218,83,173,732,662,347,392,60,643,673,292,654,873,123,354,952,260,206,440,929,377,446,890,349,891,536,418,301,66,607,175,697,879,590,311,66,886,638,316,764,640,536,210,197,402,719,678,102,339,82,716,268,913,923,688,111,83,838,952,468,569,331,117,903,616,465,851,239,928,977,997,954,741,720,383,784,810,985,725,592,192,0,280,349,302,448,648,272,151,764,487,946,675,765,581,765,455,987,180,685,753,774,333,990,896,65,35,733,562,859,614,875,665,834,294,533,117,450,885,455,695,637,60,97,714,737,576,651,839,626,688,829,133,850,801,748,411,410,388,695,107,207,481,276,919,915,389,202,390,234,653,994,578,558,120,852,514,45,692,464,860,48,801,557,857,671,804,603,61,445,141,862,6,897,990,910,294,96,786,713,765,722,977,258,823,968,348,393,581,151,876,443,94,746,111,615,794,914,151,791,709,271,442,877,4,683,982,191,173,725,995,964,597,491,975,887,169,525,8,100,912,547,498,129,484,282,178,386,961,209,852,73,931,529,183,43,211,38,145,306,999,859,668,933,631,476,672,470,419,211,191,755,111,164,662,506,20,565,882,947,978,93,883,25,375,441,800,683,673,191,353,984,221,228,159,13,395,740,663,659,941,114,414,511,580,998,857,537,343,681,826,544,176,696,328,214,157,804,385,950,99,71,744,654,576,230,106,815,891,489,412,587,579,605,299,718,505,458,167,154,899,886,721,986,206,47,987,798,326,981,445,482,277,644,615,414,136,815,69,447,730,284,440,849,529,547,712,414,96,32,587,164,705,738,893,661,270,316,71,392,488,92,371,697,447,993,242,17,54,169,642,81,10,292,591,312,574,631,548,856,912,650,888,318,838,383,203,465,625,418,7,863,8,536,299,94,810,487,944,738,773,528,327,479,965,207,815,415,656,991,732,285,125,858,7,232,5,706,595,513,413,222,26,37,587,26,336,214,678,915,260,950,24,925,870,780,184,930,630,84,615,626,44,349,436,527,89,336,273,524,697,584,50,130,842,561,267,592,487,237,493,383,762,75,917,386,132,233,487,107,258,975,730,300,399,741,650,393,237,935,530,801,755,141,593,614,20,503,271,886,553,333,522,188,635,836,752,731,412,42,946,585,333,126,758,645,719,473,201,957,801,423,567,852,840,765,564,389,186,517,11,550,354,214,161,20,832,388,987,434,625,326,544,631,76,91,651,29,21,801,726,400,27,39,272,230,912,466,46,499,642,545,141,818,378,422,152,614,714,362,634,597,651,778,148,387,208,142,796,853,363,374,721,689,796,263,52,463,925,162,558,921,946,959,646,728,750,822,183,334,581,458,791,912,73,202,788,851,647,454,577,921,567,945,383,374,497,593,932,576,152,676,378,376,13,653,166,139,918,594,448,24,863,365,666,926,749,141,184,605,92,693,80,738,246,414,480,82,721,875,906,636,421,589,502,165,641,211,705,48,982,830,270,933,827,901,810,663,614,356,488,499,435,898,456,966,815,848,247,677,442,125,417,70,604,619,633,252,774,799,44,8,157,24,866,297,382,203,866,851,477,740,52,317,247,518,753,87,121,152,904,841,899,445,570,864,460,361,126,307,720,613,493,726,781,583,90,156,860,222,829,53,972,70,214,367,970,742,451,469,137,619,929,19,394,836,904,657,102,808,870,771,525,238,285,41,634,33,700,63,439,413,564,441,514,10,527,500,315,711,635,418,126,187,105,324,406,554,240,217,832,324,31,299,643,867,252,921,824,638,245,942,736,467,262,70,789,406,656,118,321,711,632,945,282,315,89,203,131,663,753,380,837,10,867,309,35,623,666,755,166,969,204,292,921,866,215,749,579,971,960,225,275,83,702,990,403,955,648,505,340,217,518,857,566,648,618,955,790,938,557,442,603,351,691,685,40,389,224,612,166,613,51,9,969,202,160,834,651,852,849,476,436,193,836,572,966,848,507,948,868,820,434,398,828,151,334,700,346,708,873,729,218,640,131,300,964,491,615,812,551,19,167,979,748,258,436,638,805,502,332,45,335,410,591,937,195,202,985,671,415,294,635,25,624,463,540,997,622,448,758,870,120,233,960,793,213,949,965,536,596,257,118,767,700,286,868", "263,121,762,377,85,359,233,552,146,909,292,238,774,766,493,471,691,301,626,85,554,650,356,775,140,451,222,11,638,29,356,528,878,383,421,51,309,486,834,611,776,495,511,851,614,785,76,826,584,726,807,415,295,276,222,602,883,424,37,65,300,949,39,533,124,403,215,85,855,250,449,346,275,183,719,7,755,620,519,540,319,736,404,830,520,961,512,391,833,224,87,739,427,949,703,628,924,772,486,127,481,668,223,999,71,954,535,394,698,265,866,791,132,86,544,923,832,70,977,254,49,545,440,88,570,701,847,668,905,342,768,211,491,814,741,173,474,674,651,839,622,224,355,766,280,0,895,884,467,577,178,929,230,93,436,301,576,353,539,912,254,239,264,398,220,704,278,942,233,621,649,220,447,809,874,910,638,903,706,14,994,170,385,135,330,308,99,242,555,434,477,766,635,815,193,166,268,854,266,749,837,302,925,484,683,789,987,762,704,850,582,316,195,938,170,801,553,6,370,9,183,341,99,133,207,460,444,551,722,645,181,920,906,716,311,440,383,846,350,487,661,396,489,836,951,115,992,442,717,927,647,604,58,63,575,849,722,524,630,657,306,389,496,619,787,254,46,213,621,380,788,436,424,883,472,212,188,811,777,582,540,224,262,570,779,348,662,238,452,839,335,833,565,561,867,678,391,365,457,698,858,930,905,732,130,996,904,571,751,897,790,86,760,476,956,141,769,872,420,343,221,224,304,451,27,295,332,918,303,45,287,695,694,179,843,375,688,764,354,655,667,272,651,559,328,357,305,990,968,821,771,268,554,510,311,117,349,161,913,298,368,830,752,776,951,320,189,485,24,94,708,154,501,215,455,367,189,7,853,286,749,298,21,509,233,148,997,56,598,542,838,149,32,815,917,755,71,878,459,656,991,591,801,157,971,130,410,141,1000,99,661,960,782,1000,892,1000,247,636,507,338,890,346,132,658,713,126,503,523,40,363,633,988,985,759,869,534,399,227,162,377,322,203,404,51,676,657,64,942,358,442,53,196,927,962,90,215,790,696,144,292,747,840,222,992,798,368,261,367,80,385,725,305,554,123,677,838,785,521,894,647,401,975,12,484,466,909,282,341,752,737,730,291,99,350,732,664,834,641,393,335,473,904,625,287,110,66,930,58,865,760,46,992,620,942,252,530,800,354,703,768,569,636,946,402,369,903,273,375,633,807,362,622,392,225,549,599,774,929,427,959,386,380,401,884,814,513,318,380,671,776,754,552,381,652,268,671,606,524,748,627,585,802,616,926,413,404,405,298,661,253,452,90,775,563,947,856,367,206,695,638,633,992,588,706,669,21,247,760,437,5,720,932,952,589,911,22,597,296,453,56,727,87,622,928,179,260,805,510,994,90,233,821,654,18,910,177,194,674,78,83,96,377,643,536,755,462,676,966,895,329,545,106,504,575,916,689,825,179,981,850,69,136,788,484,56,735,853,879,137,515,725,86,725,59,698,94,506,446,986,787,466,637,754,179,203,176,63,890,897,980,888,530,923,738,718,831,830,166,779,351,906,310,994,503,409,232,78,738,230,747,668,108,129,240,841,416,403,376,841,10,450,67,182,112,346,898,667,695,484,314,9,994,616,54,662,902,260,565,360,809,122,430,196,782,472,99,491,952,247,23,344,22,57,856,917,905,513,769,12,989,418,284,430,78,641,903,514,356,392,713,463,641,266,33,405,369,979,157,592,404,790,740,267,669,739,666,303,194,506,875,483,323,33,774,356,207,7,563,652,756,237,487,91,470,607,244,833,314,905,238,372,704,414,409,878,107,576,166,739,325,161,310,776,37,624,719,508,690,72,891,229,231,359,305,716,673,121,645,846,546,305,407,297,750,921,999,433,372,744,543,630,183,604,790,643,973,388,472,333,446,237,715,625,267,165,713,524,250,503,763,664,735,645,444,441,500,92,673,295,474,167,474,618,111,865,37,638,412,247,960,320,662,752,11,663,164,208,712,950,399,700,893,672,564,175,511,156,969,563,632,594,128,46,467,493,305,987,681,752,140,80,922,117,34,402,845,573,557,236,122,158,173,627,220,816,889,398,140,199,939,2,719,60,355,430,319,877,705,256,858,130,703,812,469,114,503,858,858,320,698,413,372,934,661,444,990,224,571,117,221,171,431,561,294,728,377,290,323,948,983,801,826,624,230,879,162,337,482,906,339,32,87,583,263,365,488,494,275,944,538,250,832,541,59,992,936,20,641,662,534,930,136,765,117,984,150,282,832,97,835", "415,742,715,333,377,961,826,119,201,164,704,241,433,557,908,841,447,230,680,130,746,515,898,311,805,167,15,736,322,429,171,470,758,770,815,506,302,27,274,740,781,546,132,803,853,24,397,742,372,697,19,712,762,425,4,129,418,201,985,639,149,368,144,332,545,620,276,882,181,245,729,56,957,612,518,902,882,651,618,357,609,276,269,50,630,831,813,7,246,440,500,87,670,867,369,310,407,867,475,545,326,204,78,413,787,374,883,870,475,651,591,330,790,978,686,845,457,844,688,332,179,418,844,423,807,289,288,9,124,578,964,112,832,814,328,731,837,250,461,90,807,18,429,458,349,895,0,175,750,29,983,188,116,316,807,870,591,444,992,889,661,255,328,437,612,137,461,95,195,892,296,960,917,928,256,942,355,680,931,409,881,424,797,629,172,589,384,29,33,28,207,577,731,486,669,485,986,158,798,649,540,132,806,574,337,485,951,837,243,988,346,370,128,938,959,895,135,717,502,930,666,430,389,446,488,316,804,822,133,303,515,646,512,786,67,260,50,479,873,466,517,478,21,177,502,870,462,105,609,802,749,79,843,209,133,538,174,907,179,890,317,81,315,914,757,251,618,849,425,497,179,442,632,155,514,4,921,516,773,403,765,847,855,386,300,342,248,301,304,199,172,906,541,430,652,609,273,319,227,18,722,301,757,362,544,214,421,212,373,876,181,375,992,549,844,361,699,388,70,412,150,965,543,387,975,127,264,106,853,470,549,285,687,278,278,604,944,741,718,900,683,382,708,60,976,901,505,369,680,962,879,594,528,295,389,889,272,299,327,886,130,990,995,752,918,467,658,74,495,966,566,45,750,548,175,95,948,835,910,931,57,529,341,512,286,929,592,745,968,287,723,74,168,468,379,694,742,358,567,755,443,142,807,677,126,536,538,530,222,141,688,80,76,760,50,640,786,325,125,26,335,651,258,167,899,160,760,264,290,630,365,880,204,292,290,685,546,434,965,826,472,564,148,860,69,418,123,782,515,86,650,82,191,625,550,609,139,242,330,4,215,789,413,491,611,112,58,818,711,658,922,351,477,422,409,640,940,817,884,150,410,270,372,77,123,626,862,20,710,317,487,613,296,62,52,271,18,539,43,563,752,44,63,325,904,915,898,481,163,76,653,728,962,539,769,510,257,10,788,985,774,888,576,760,675,9,670,9,842,691,467,153,825,903,696,73,159,405,177,215,749,5,99,881,771,322,4,859,606,624,29,948,992,796,348,357,320,170,60,136,408,142,741,500,838,79,334,305,301,190,175,17,893,696,564,420,468,677,16,918,889,618,238,484,862,690,349,488,132,975,454,706,54,246,205,817,400,426,230,981,561,157,343,929,551,869,375,811,82,98,81,477,588,215,824,16,387,891,812,595,56,952,909,292,613,453,561,983,991,516,43,766,727,659,625,724,934,934,582,542,979,713,569,33,797,816,466,112,361,534,764,654,864,186,512,687,290,700,726,348,959,227,142,785,197,320,376,521,81,745,573,570,813,414,906,986,538,498,628,400,414,693,294,146,711,384,951,335,564,714,583,236,418,864,775,551,541,112,190,994,406,772,138,667,207,994,204,570,419,410,209,80,252,718,519,59,933,432,123,639,762,702,125,498,742,212,570,230,767,796,427,296,680,488,978,200,445,663,152,395,661,998,116,470,204,113,866,533,119,310,872,477,991,852,735,250,84,730,890,899,305,864,779,368,570,814,984,587,820,868,912,805,241,930,510,647,951,144,595,121,610,609,22,961,538,625,71,854,779,838,443,580,329,76,769,458,337,642,614,185,397,327,762,373,901,362,180,283,875,286,591,378,98,49,557,95,114,851,819,873,664,738,506,369,683,241,329,28,216,378,257,468,719,445,406,748,76,195,167,398,115,142,93,358,162,163,175,64,926,693,227,336,42,424,43,579,631,366,458,10,240,688,978,557,862,580,58,95,248,529,347,701,191,104,243,828,591,344,85,221,537,496,818,453,850,36,730,62,695,945,475,366,642,493,332,615,759,440,228,205,507,948,277,304,364,317,775,175,208,242,196,177,382,239,384,977,49,861,163,83,881,263,45,847,993,811,98,599,38,372,922,109,524,255,362,958,404,1,667,933,585,855,682,913,324,509,577,167,893,570,433,727,636,557,400,396,277,449,404,118,334,393,881,860,652,199,188,771,627,264,759,395,676,339,664,529,424,372,35,587,609,32,503,353,768,909,920,187,792,794,312,478,348,206,732,7,629,111,126,99", "961,378,496,839,546,319,245,960,407,816,596,242,108,208,733,909,74,373,535,39,643,2,23,963,679,72,167,489,717,127,899,403,237,18,548,48,913,919,600,167,703,589,303,469,584,180,674,536,906,517,112,408,274,432,602,131,93,63,213,161,830,667,290,878,585,459,420,951,534,321,921,795,745,818,691,211,336,664,697,706,975,860,780,767,114,91,908,947,618,217,673,363,801,287,109,944,125,584,521,189,481,839,822,858,324,449,553,357,444,653,719,115,328,540,581,832,561,952,179,271,504,663,72,611,108,364,641,595,842,178,297,379,411,108,342,570,698,210,70,742,872,943,3,641,302,884,175,0,394,34,634,173,564,256,603,255,767,381,672,971,116,994,782,715,168,710,459,29,719,469,894,808,590,477,140,281,477,452,327,602,228,927,942,746,922,815,928,695,394,57,670,103,610,282,228,503,263,961,738,443,814,234,556,544,86,390,40,734,394,635,624,888,966,967,203,67,473,795,901,888,695,525,949,677,257,21,387,322,446,753,727,249,43,699,886,33,916,179,210,416,521,390,708,916,194,106,379,361,146,943,226,302,280,188,212,729,613,170,697,328,230,266,411,288,607,17,230,613,350,357,988,666,49,958,940,157,330,772,782,900,535,462,460,214,418,993,961,932,707,427,757,326,232,26,639,275,567,586,301,221,918,573,809,316,928,421,832,223,871,860,620,297,285,652,817,194,631,9,810,197,865,495,172,107,274,250,143,357,361,36,332,495,347,63,94,409,244,64,759,55,420,728,451,333,855,216,253,346,955,730,19,833,865,635,380,501,488,691,759,910,702,355,277,105,281,382,932,710,821,901,343,936,381,898,515,394,448,736,448,818,30,59,53,86,423,425,820,469,494,342,206,841,6,269,257,291,240,471,808,391,91,612,206,893,217,399,976,391,159,619,394,17,303,337,931,697,948,870,648,136,238,126,36,153,625,985,205,893,227,265,332,952,158,696,835,83,919,920,214,291,79,441,697,502,414,45,892,207,156,778,145,142,187,640,529,541,293,210,715,698,673,840,187,15,658,802,313,729,261,830,838,278,230,4,227,870,605,889,581,347,390,749,136,530,38,630,195,115,691,279,971,767,759,910,894,582,903,571,866,279,478,290,537,944,667,466,432,528,571,436,119,68,987,107,844,307,17,598,658,909,884,10,981,159,883,139,994,462,401,103,102,136,616,520,505,483,150,969,979,736,742,40,225,80,807,922,38,982,523,780,833,95,77,900,617,813,995,865,551,698,317,657,181,680,213,821,341,314,591,738,582,565,787,157,337,615,933,409,620,553,648,867,491,679,814,575,706,358,789,694,194,190,744,257,347,676,855,392,450,90,491,438,260,959,483,107,792,459,46,739,291,115,948,915,553,305,614,663,978,414,776,467,661,788,902,774,887,854,975,54,964,937,291,286,84,41,669,151,717,199,688,989,221,662,280,85,249,203,639,429,137,206,66,536,143,438,761,633,697,16,705,279,313,799,326,157,961,988,527,540,274,967,900,615,613,945,665,97,62,404,454,578,436,675,88,474,354,291,722,933,20,186,853,717,906,883,177,146,676,532,94,846,933,910,529,634,431,1000,29,941,368,896,633,115,863,787,309,916,7,156,359,619,977,831,568,842,203,324,302,263,369,118,639,186,428,976,359,628,140,827,707,122,568,490,709,655,436,819,683,518,339,448,197,676,917,65,572,531,88,991,597,553,493,845,840,269,619,626,405,505,852,702,580,164,348,118,123,599,359,439,263,987,341,777,190,699,263,905,44,548,560,458,280,979,296,353,760,891,674,596,93,297,998,913,12,336,466,235,346,157,390,493,607,561,796,455,633,788,77,628,156,73,633,114,278,17,113,730,70,738,759,574,104,706,942,693,174,219,831,785,264,71,229,860,469,700,971,395,826,142,228,150,229,681,997,433,485,954,618,61,725,352,5,565,295,119,443,387,641,567,251,375,753,932,870,639,942,783,457,771,507,721,261,522,356,15,578,674,352,231,145,690,800,534,910,343,807,780,233,504,367,49,302,521,130,804,98,629,599,22,800,766,248,766,810,559,262,878,252,183,120,284,594,281,570,420,118,67,608,515,372,361,778,390,646,213,915,928,991,72,129,172,488,268,324,365,896,983,26,698,185,146,751,931,271,343,256,217,169,756,577,957,421,292,719,538,741,970,992,731,933,563,54,762,606,353,744,344,735,789,631,346,976,925,25,820,515,898,264,325,725,938,942,696,580,265,449,917,172,147", "56,816,442,570,260,674,408,292,364,460,371,389,677,680,864,306,46,437,14,581,333,397,769,388,173,907,315,173,812,938,782,605,217,751,727,218,697,494,583,875,436,468,647,285,924,286,603,995,718,785,328,429,309,548,637,817,293,28,796,24,710,36,302,185,979,175,388,22,44,769,834,6,29,109,837,16,656,802,227,542,313,918,824,426,343,344,911,405,58,274,719,794,832,76,733,157,221,973,128,28,880,915,880,248,116,792,125,174,413,514,252,607,326,645,970,411,236,171,291,223,884,525,577,237,902,164,129,209,97,628,649,169,961,402,958,221,508,786,834,567,708,809,166,400,448,467,750,394,0,58,373,558,146,141,899,379,805,868,404,349,749,813,976,903,799,301,741,994,915,33,743,909,423,786,362,897,587,768,937,271,421,88,878,260,218,665,514,118,847,333,418,617,962,571,537,168,719,941,103,432,886,724,929,713,74,376,732,561,81,31,741,143,266,799,953,605,967,39,888,478,767,511,150,337,92,656,446,469,266,657,798,788,922,942,772,596,637,110,143,741,914,508,737,642,396,945,91,637,684,468,800,974,767,789,969,794,349,102,387,366,816,632,763,767,381,331,152,246,74,111,948,200,495,748,867,411,900,617,138,243,822,733,933,100,737,968,795,76,648,657,989,892,639,451,714,583,31,874,343,596,918,450,749,458,390,198,255,774,105,182,458,729,747,661,990,606,936,182,770,24,694,24,781,776,407,609,677,544,275,885,657,19,146,62,779,929,289,161,986,41,617,693,997,452,168,921,131,760,867,189,171,872,675,164,293,33,115,682,327,566,592,332,760,923,249,372,906,787,196,320,856,875,280,727,806,550,974,360,108,92,178,332,420,548,217,137,955,605,697,968,999,732,442,693,515,950,933,919,412,451,69,248,453,667,737,294,241,54,799,816,736,767,34,256,414,71,941,756,773,329,201,124,654,903,349,14,315,102,386,807,483,280,839,348,705,130,6,518,776,123,265,637,736,987,203,42,175,707,949,935,827,375,858,996,426,192,162,278,943,241,676,763,916,979,532,616,291,813,854,918,200,631,4,437,236,677,490,297,233,442,978,822,158,108,74,72,411,25,373,463,100,619,826,103,714,424,420,930,503,347,251,595,157,640,985,630,804,675,934,900,781,770,874,422,787,550,210,537,604,306,229,598,385,635,672,131,800,382,285,994,710,30,368,240,553,320,809,956,734,833,517,176,974,97,491,956,9,669,313,632,923,37,511,441,453,131,91,779,164,299,506,5,786,993,775,768,169,588,738,930,83,82,129,399,126,665,274,739,540,979,584,110,552,826,103,205,137,927,758,771,656,872,745,504,649,968,395,679,447,775,572,616,301,223,764,253,986,415,109,46,595,548,675,679,74,949,457,308,457,36,439,231,897,793,968,894,528,63,900,406,920,994,815,155,916,296,416,91,937,325,240,465,180,315,606,869,442,818,725,889,157,569,974,8,860,21,670,503,94,147,527,565,960,968,284,660,678,438,524,720,862,5,754,811,991,655,323,184,637,401,349,644,367,14,50,885,87,285,299,684,685,107,830,283,179,530,662,390,712,696,975,505,373,69,601,74,912,286,52,160,272,364,813,302,68,758,168,77,611,399,958,271,409,454,539,377,765,503,927,840,45,35,195,303,514,232,810,700,367,248,592,592,162,302,227,95,584,958,468,615,375,234,105,542,530,842,640,128,553,307,778,95,605,18,527,133,623,806,890,622,764,949,95,65,652,901,680,231,549,948,902,143,763,207,299,941,690,770,416,206,288,266,843,624,222,360,256,202,780,788,261,823,55,67,600,792,167,649,772,380,373,954,38,635,772,609,798,58,231,469,311,928,159,641,2,630,764,567,256,217,8,447,887,908,746,444,463,549,504,672,387,762,353,413,499,56,926,980,766,94,660,903,479,92,305,990,567,291,596,508,115,939,615,300,538,50,54,675,337,371,91,923,269,634,450,288,401,184,943,420,897,839,335,613,655,936,199,82,122,407,496,550,909,683,45,671,245,385,158,245,791,779,281,52,202,599,629,236,678,69,388,552,158,149,161,694,336,721,196,908,673,220,84,259,399,233,488,833,178,761,375,260,443,247,815,988,843,701,887,989,375,128,997,516,337,566,498,909,822,815,264,59,243,947,222,921,325,471,454,434,170,417,725,308,639,147,705,105,993,795,610,476,841,733,367,431,458,810,325,161,13,906,549,476,841,509,345,549,983,880,141,91,474,957,905,711,276,351,170,224", "755,616,11,636,736,229,345,334,388,891,828,35,398,979,180,185,598,17,267,475,448,983,409,678,582,497,733,399,351,920,944,897,361,115,276,753,22,798,59,997,557,965,83,307,581,790,216,996,155,256,276,201,541,741,568,634,501,360,699,853,577,339,797,603,27,227,226,596,845,251,698,286,202,680,800,12,927,575,238,899,667,520,109,8,309,685,978,461,490,977,660,210,487,976,707,712,149,464,244,556,198,125,237,423,796,616,445,453,771,236,973,169,935,975,535,368,544,278,489,400,110,399,847,35,239,257,580,470,221,81,838,714,574,165,951,121,369,444,674,459,650,208,141,831,648,577,29,34,58,0,570,306,342,369,497,748,914,766,767,883,184,458,652,530,497,156,820,900,545,348,527,180,164,684,541,841,434,56,512,407,853,999,745,246,634,19,571,627,691,541,814,419,950,360,457,448,965,50,757,113,836,76,324,660,516,346,239,363,354,51,895,607,891,325,113,258,668,92,910,498,136,196,17,521,497,544,864,572,235,251,808,928,41,547,483,575,558,542,891,163,555,687,995,139,897,146,695,940,679,881,208,98,732,495,891,129,796,289,682,388,901,521,719,153,114,404,59,690,509,855,419,496,12,444,39,228,410,366,443,205,4,523,367,867,747,79,534,172,603,235,934,396,487,208,968,619,148,241,110,148,821,836,176,249,397,429,30,834,865,54,143,523,368,26,31,568,374,607,617,44,319,288,441,319,81,486,906,217,469,439,195,922,799,965,80,232,126,120,12,388,334,304,930,748,545,647,329,170,664,374,173,880,616,693,48,882,610,573,586,981,342,261,928,330,729,855,17,813,865,829,894,932,467,402,802,952,712,962,847,548,379,824,955,376,840,740,489,296,807,513,973,50,138,629,973,793,431,183,798,598,950,332,583,536,444,220,891,393,720,111,823,113,676,955,870,708,539,77,266,350,970,451,300,821,250,684,538,562,268,150,244,898,426,336,712,764,303,86,267,663,299,227,261,591,827,290,699,784,185,101,621,677,779,427,591,202,221,565,615,367,536,809,672,968,524,207,738,576,374,21,610,439,590,983,522,254,665,507,995,62,882,214,605,266,241,862,32,879,589,993,382,454,240,987,924,695,735,100,871,63,630,764,895,839,285,142,161,900,775,226,28,134,909,485,503,192,568,895,407,650,406,371,105,848,759,441,426,365,446,220,607,954,279,290,947,379,828,811,227,992,645,425,852,640,525,112,35,107,970,654,429,649,582,957,797,478,194,120,878,477,167,587,237,2,427,604,743,814,564,84,473,195,967,688,700,17,258,962,182,198,276,342,219,770,44,163,266,397,625,386,675,444,123,264,56,646,907,351,737,185,340,152,913,390,75,165,315,14,903,645,232,465,606,280,880,615,192,464,497,305,493,487,255,450,569,874,366,735,841,64,80,300,671,556,262,46,484,420,929,836,573,632,287,749,629,782,86,682,777,399,25,498,715,146,932,560,629,379,163,779,707,31,535,101,225,266,780,142,309,717,180,17,271,435,453,969,338,228,16,467,831,47,802,394,396,666,71,267,771,949,413,312,314,856,368,790,81,370,144,896,923,42,316,242,223,121,860,497,398,809,2,723,322,968,312,437,657,508,273,293,938,581,879,110,807,468,808,946,85,679,317,231,517,103,319,292,782,550,28,447,12,967,27,520,232,24,125,728,314,804,178,345,376,901,254,792,227,517,358,959,243,886,264,910,86,781,620,87,251,462,405,45,422,388,387,413,586,491,784,796,178,508,806,48,908,425,643,562,748,512,140,633,901,437,361,741,525,698,122,183,72,993,151,38,56,447,324,518,710,156,475,616,604,905,502,621,735,671,392,750,525,282,64,136,261,333,839,674,221,420,327,497,100,136,680,84,227,367,967,588,966,4,716,496,27,830,377,768,234,197,624,609,810,586,160,261,848,581,184,796,244,939,892,834,861,403,215,23,102,800,953,401,570,174,790,363,451,145,832,779,89,455,822,809,779,303,920,901,581,171,995,555,258,173,69,419,743,325,443,638,917,73,414,975,558,823,464,623,299,7,743,993,49,950,119,139,608,48,456,954,395,761,951,477,916,4,145,535,168,7,324,880,138,527,137,638,641,124,99,128,243,801,926,263,254,163,510,980,615,573,563,480,362,35,105,441,602,601,616,197,853,211,71,12,744,294,248,172,252,574,831,849,299,605,274,599,896,210,273,156,10,705,76,729,559,31,415,111,826,222,748,925,178,641,999,93,524,509,503,600", "616,307,113,296,21,245,736,973,855,999,238,682,220,556,164,587,475,381,211,889,739,215,399,497,29,670,156,499,276,758,520,850,815,540,442,295,793,244,274,60,48,937,686,790,589,673,723,737,204,652,290,238,51,799,820,212,496,937,547,336,574,692,837,400,122,52,346,268,679,204,735,766,592,765,928,544,933,681,738,424,904,380,720,225,366,913,870,225,216,287,177,586,893,773,527,315,642,554,885,849,630,365,124,9,371,253,826,657,597,332,199,884,810,238,195,89,400,988,634,457,481,490,938,622,444,423,47,701,369,484,340,459,551,866,631,834,431,447,322,333,242,35,25,864,272,178,983,634,373,570,0,383,751,268,898,485,281,371,874,492,739,512,372,100,918,266,184,422,710,796,183,578,107,21,290,868,934,987,978,305,366,629,305,615,791,949,79,988,215,727,245,574,373,544,95,651,32,83,355,42,200,538,527,493,222,325,560,159,33,850,283,464,865,364,734,502,275,643,251,482,639,759,663,539,85,71,875,490,969,81,875,731,246,598,548,958,879,132,994,145,452,404,991,939,50,144,500,162,527,957,384,268,647,106,810,257,740,527,624,860,115,320,95,951,56,849,589,690,557,696,684,579,607,747,510,810,375,272,627,378,20,978,953,240,178,691,199,534,408,767,265,642,339,638,620,341,747,349,682,72,441,313,236,478,698,347,969,770,220,18,509,992,515,688,372,103,336,683,856,312,3,851,570,684,874,998,948,597,240,944,542,886,248,67,707,638,273,848,261,952,405,346,983,272,339,848,621,933,288,945,515,806,423,343,460,147,76,400,505,138,953,903,734,559,351,685,730,340,122,207,851,953,661,803,620,743,990,601,165,236,360,253,668,691,851,53,174,66,719,611,217,245,455,171,898,318,300,983,873,797,207,931,155,588,738,674,876,678,845,548,256,388,106,279,295,417,703,740,259,530,995,154,628,867,265,941,967,51,322,842,824,845,842,100,218,426,469,592,600,560,129,221,907,78,979,52,739,193,398,87,919,621,226,45,399,763,604,408,719,684,902,563,862,423,753,995,516,360,713,947,257,228,402,633,866,685,264,44,600,327,712,176,872,356,425,104,636,545,204,236,286,537,307,941,156,923,397,214,948,492,488,869,503,791,293,219,859,895,129,145,79,990,272,892,624,466,892,686,968,716,766,156,355,477,740,150,243,932,900,804,502,136,165,466,212,147,123,276,715,619,764,862,339,757,127,836,546,329,351,389,231,148,385,634,492,611,94,338,637,966,14,326,362,810,471,68,720,186,154,75,895,477,28,723,841,907,197,367,410,184,17,527,660,715,166,251,962,459,303,807,893,984,391,59,208,58,216,458,87,441,570,78,592,840,600,616,269,20,763,313,110,642,485,674,121,370,598,937,498,262,303,126,971,799,31,902,575,43,550,366,462,945,324,232,852,819,304,101,653,237,859,287,667,140,498,455,255,646,173,545,389,923,213,393,69,475,949,288,375,285,945,622,625,580,904,77,422,198,907,780,85,879,857,965,762,590,381,551,65,213,958,732,248,120,196,930,409,983,674,92,282,838,570,61,20,318,47,927,138,456,393,14,883,79,469,196,98,647,81,762,455,857,203,496,359,172,636,425,727,781,33,594,231,787,594,855,59,287,151,747,279,132,486,705,113,294,355,469,996,498,648,30,731,577,266,57,834,923,647,680,540,203,803,860,623,625,295,230,223,229,742,369,181,690,815,941,190,756,599,102,563,205,351,678,13,734,322,964,829,853,103,851,539,498,864,765,610,872,40,144,325,949,493,457,574,522,544,714,342,648,319,9,802,184,939,814,867,942,800,479,427,153,727,136,132,914,659,871,407,400,733,569,469,707,276,252,943,76,420,845,259,490,617,292,71,862,47,530,523,22,821,487,295,236,792,661,126,686,510,522,917,76,40,877,699,558,455,211,884,781,227,515,519,642,988,178,620,463,134,364,854,280,162,745,803,395,565,984,335,523,68,460,722,347,898,18,874,727,592,568,226,189,904,974,472,838,587,903,768,247,610,890,33,261,388,433,284,937,633,81,311,947,947,774,575,143,654,606,744,284,997,863,53,485,199,172,982,411,98,833,402,986,81,946,103,171,646,195,19,811,18,189,599,722,312,429,808,228,173,622,65,187,114,418,53,809,191,765,418,62,444,709,706,671,706,52,778,522,2,152,926,594,824,957,485,476,468,641,528,605,235,687,882,103,219,770,476,170,936,341,618,768,655,806,835,59,665,136,486,328", "27,115,751,301,40,848,303,949,747,294,415,165,984,753,932,609,183,273,999,658,558,159,616,446,752,26,181,643,920,980,879,649,825,947,868,134,154,93,801,217,252,975,152,998,775,665,812,952,894,395,835,389,993,695,754,145,73,218,279,434,535,374,442,543,245,173,586,18,64,226,555,47,464,737,104,311,610,567,910,164,919,659,457,12,305,515,556,927,719,830,498,706,679,269,868,84,465,781,968,834,994,38,668,705,997,658,672,843,954,602,687,305,37,567,122,940,734,919,494,387,559,972,547,210,302,309,781,915,151,353,572,803,988,195,134,29,734,977,907,780,242,528,659,772,151,929,188,173,558,306,383,0,516,490,109,547,469,445,852,514,696,87,305,780,471,514,219,823,918,345,968,771,782,333,269,754,934,301,101,866,110,18,988,780,136,364,207,816,478,465,183,760,912,964,85,738,79,903,662,751,232,736,422,714,836,610,77,144,864,17,891,63,944,293,412,437,487,862,842,300,116,534,726,895,371,617,961,440,149,838,84,570,706,4,756,557,785,121,6,861,378,502,686,616,507,356,715,983,1,997,667,99,869,109,402,846,978,437,954,302,337,898,301,76,695,626,70,162,635,300,164,303,755,310,62,426,298,232,643,300,419,254,200,305,862,628,946,862,787,471,924,752,296,718,366,856,675,145,283,282,563,966,765,409,768,927,863,673,621,58,910,355,323,246,368,774,610,766,850,981,769,465,776,461,433,794,466,798,922,62,170,681,649,933,210,558,171,887,421,231,663,799,490,867,55,915,958,646,849,97,130,836,697,733,619,126,207,224,438,738,272,724,442,244,45,82,426,61,729,370,570,434,936,537,519,357,906,367,805,814,557,229,660,968,70,530,184,845,473,78,559,839,71,637,500,173,506,824,399,969,764,551,654,679,109,847,257,366,392,159,267,110,46,662,571,833,786,475,758,353,696,424,696,615,61,878,328,685,255,529,58,94,804,785,96,53,747,409,41,284,330,391,187,24,843,359,593,862,377,988,348,968,818,571,455,57,894,439,262,65,194,407,538,344,186,593,93,737,234,299,97,608,947,182,204,504,603,394,911,614,137,977,666,975,768,146,438,412,774,203,499,640,862,585,228,636,938,892,607,337,721,353,998,186,20,639,51,446,641,747,425,819,574,228,801,889,888,145,270,217,381,247,844,176,323,249,494,516,431,969,324,173,50,302,826,99,603,633,352,585,394,535,410,377,562,13,212,669,948,33,85,131,758,619,249,375,153,351,260,348,26,290,288,437,64,718,283,548,435,190,989,104,388,895,749,961,490,97,927,656,830,204,854,165,489,810,510,530,269,142,765,34,70,400,409,878,949,65,1000,290,747,921,59,555,339,974,739,765,159,811,227,141,500,431,336,779,145,224,888,621,954,254,188,603,555,903,180,70,551,482,559,500,843,520,866,791,66,330,743,909,232,34,116,227,132,832,549,698,676,368,194,526,830,171,16,613,983,92,410,607,316,962,7,129,454,918,602,551,504,99,702,634,899,788,549,450,732,801,463,737,326,211,331,300,565,370,383,205,819,925,145,851,34,410,280,432,319,827,229,970,102,567,700,853,683,82,608,101,392,351,862,628,133,95,877,822,252,334,240,312,627,103,298,996,344,693,152,218,228,784,760,967,54,891,57,392,318,51,736,219,573,890,88,974,137,983,542,433,606,728,745,187,84,977,239,67,71,124,246,106,219,871,868,529,817,186,121,654,922,602,989,33,643,721,35,158,543,483,717,744,113,86,604,490,615,9,4,632,281,96,467,354,302,785,37,55,158,705,921,29,861,433,776,531,17,675,278,394,157,262,389,170,227,505,794,743,679,195,48,447,996,136,438,14,858,683,235,862,385,320,418,915,161,401,77,763,294,998,757,342,199,308,980,482,247,9,859,191,735,933,732,756,31,477,520,374,288,400,772,63,243,208,777,856,680,166,626,326,344,342,68,454,652,742,867,964,620,75,163,366,720,876,840,885,103,324,201,139,378,313,794,986,728,893,485,487,290,251,647,504,490,494,180,328,280,37,699,985,952,778,901,285,575,337,752,426,702,486,969,169,232,151,558,886,40,296,887,733,182,600,715,753,972,560,895,272,592,412,863,194,678,164,95,409,246,21,333,408,209,140,859,384,612,716,714,827,848,989,299,935,748,894,994,239,542,805,490,588,839,207,888,165,417,473,13,92,792,614,659,39,438,673,379,669,977,125,853,250,941,51,311,605,940,620,868,941,65,950,665,457", "186,492,888,947,309,181,16,25,933,884,730,872,888,93,363,154,584,792,598,193,711,491,160,71,740,554,757,448,717,985,739,213,378,373,760,349,909,879,337,332,480,150,979,121,168,709,155,156,159,425,365,936,438,227,257,381,657,699,897,858,923,513,90,798,84,37,186,999,540,48,51,120,668,440,933,794,245,865,690,153,297,122,216,123,489,485,733,37,673,977,469,560,538,507,632,839,261,236,408,54,112,128,38,743,633,538,609,427,511,74,688,69,723,399,107,971,744,695,535,570,697,261,10,741,582,899,15,234,316,972,122,919,255,798,278,658,504,479,358,36,119,659,435,332,764,230,116,564,146,342,751,516,0,110,771,723,429,472,584,883,934,724,997,793,527,939,577,482,995,318,888,110,188,75,493,537,679,365,902,42,957,987,153,835,218,772,291,565,568,294,331,696,461,31,231,491,220,518,602,656,740,594,222,355,484,637,66,535,867,891,615,701,267,478,218,309,218,942,269,592,294,137,268,277,903,123,906,278,193,759,834,243,136,903,44,485,888,418,170,736,197,958,171,475,729,43,162,292,917,127,382,335,170,740,836,196,787,840,994,241,486,23,93,687,183,673,208,328,224,63,122,490,516,51,627,105,290,46,861,295,399,456,179,153,810,921,408,554,876,512,461,10,289,521,427,94,837,506,385,693,583,850,60,175,512,865,59,791,229,724,151,163,991,685,826,1000,992,541,244,361,952,165,875,207,386,639,972,759,246,355,714,92,191,917,104,244,921,834,91,496,764,429,850,711,672,551,252,819,786,46,410,605,791,590,696,326,302,700,130,699,55,174,477,401,53,731,551,285,869,31,201,359,666,419,126,553,955,189,535,476,435,558,931,103,300,586,837,138,109,553,594,494,312,764,226,31,27,453,444,225,135,413,796,185,20,750,656,235,186,380,777,868,960,614,342,534,896,766,454,172,565,648,757,796,986,361,871,692,582,467,663,521,232,429,477,679,273,454,903,219,812,559,848,117,865,963,899,238,644,769,777,113,739,45,95,692,461,713,867,930,263,47,62,524,784,86,495,998,571,144,44,611,907,815,993,89,370,205,70,731,310,659,556,128,676,215,381,62,983,418,937,82,521,124,654,677,713,149,184,6,540,176,728,993,591,897,318,7,918,524,657,768,772,176,626,123,79,295,502,811,739,552,281,338,664,728,345,579,671,975,95,245,559,920,90,187,358,330,272,883,927,532,506,797,2,758,786,210,46,343,137,967,989,484,190,825,627,428,524,476,498,455,71,946,546,428,966,292,649,973,953,220,635,669,257,764,404,243,577,960,807,511,883,333,623,51,89,673,314,446,23,367,361,784,102,893,358,888,905,886,912,881,87,133,288,479,972,259,700,756,576,262,963,945,886,901,505,786,666,915,699,430,38,965,499,284,86,45,980,330,652,366,474,978,402,975,196,365,768,825,584,147,31,355,196,369,119,122,142,419,884,283,357,744,477,542,686,492,529,188,457,665,134,592,413,492,675,5,39,76,173,842,791,532,451,840,329,860,394,9,537,128,836,327,727,677,912,714,656,273,80,513,53,690,614,123,267,756,802,998,47,890,907,196,750,739,491,610,469,100,520,405,719,384,9,208,360,139,810,133,314,766,132,786,97,58,580,183,973,455,428,4,884,325,944,331,729,573,965,394,629,129,455,861,320,626,261,854,943,508,462,717,686,37,38,150,860,768,382,437,170,813,263,399,693,585,584,221,116,857,670,711,388,281,341,827,674,46,223,156,170,685,8,517,880,237,48,504,57,485,530,620,758,239,499,371,811,910,150,731,15,104,52,731,364,205,681,608,474,469,354,202,770,667,348,728,901,492,69,147,194,428,92,135,853,111,325,505,69,557,664,935,356,145,511,269,831,444,882,842,888,955,222,872,526,148,398,407,835,150,146,653,967,382,396,600,369,661,530,166,440,210,21,11,558,909,114,694,235,125,271,257,774,416,612,182,595,251,298,689,868,529,382,774,183,808,775,440,135,952,42,994,456,604,823,49,856,546,388,107,199,26,585,632,772,349,232,807,508,289,477,611,927,477,332,199,706,187,964,229,11,508,159,609,772,692,123,35,877,714,900,751,63,985,493,406,854,915,776,669,42,541,595,365,291,448,28,447,659,259,445,570,127,182,272,650,646,783,878,380,871,477,133,165,643,409,734,898,604,770,331,217,168,591,422,958,232,779,64,650,214,996,68,296,892,556,317,326,701,786,955,893,601,77,694,353,866,205,578,211", "63,646,803,552,74,394,576,417,882,228,183,22,47,468,9,477,339,586,403,73,219,289,32,675,130,396,221,62,746,236,626,694,109,96,993,94,879,520,696,319,451,609,611,535,642,70,343,899,771,136,933,144,683,197,474,957,924,972,451,166,772,388,54,232,376,67,560,466,917,510,223,418,705,406,564,113,696,644,474,177,126,674,414,68,724,125,655,385,841,352,718,315,31,986,724,487,49,610,640,187,894,978,97,252,600,550,887,909,467,349,180,965,929,613,455,920,26,119,330,38,740,605,406,204,713,608,577,747,4,451,939,840,101,151,865,994,626,258,748,397,813,158,371,761,487,93,316,256,141,369,268,490,110,0,473,618,329,340,703,856,217,716,692,697,104,182,422,927,706,320,542,412,786,536,657,428,875,810,759,253,145,88,244,960,928,247,867,134,819,842,113,196,482,10,682,84,877,48,203,245,77,973,840,425,357,844,100,605,838,175,722,680,206,873,979,972,166,152,593,271,538,108,451,991,267,232,590,608,152,171,528,39,442,657,251,404,864,694,756,635,170,337,610,684,758,382,367,19,72,824,701,55,922,293,820,494,308,351,234,755,494,640,240,513,417,856,597,423,408,955,48,475,444,223,727,382,464,667,830,363,805,439,949,208,973,574,326,670,116,150,373,577,772,457,426,79,514,554,482,494,727,274,412,648,481,111,630,869,681,17,992,233,763,752,8,424,839,477,866,943,569,954,126,209,364,48,859,474,205,637,911,907,939,962,502,36,51,305,347,623,116,144,996,705,582,379,132,843,98,23,540,468,420,797,107,847,105,702,92,990,544,767,979,775,674,716,852,493,382,823,298,539,16,57,284,317,11,67,824,680,562,483,594,932,388,297,892,127,915,584,589,993,527,128,712,570,630,353,448,96,131,388,872,138,214,725,454,169,693,607,355,772,560,508,90,903,60,546,69,470,74,912,579,157,587,480,36,34,839,796,695,355,12,446,387,804,756,747,633,971,967,687,866,947,376,756,522,411,92,163,903,7,657,877,544,209,35,86,327,456,209,353,271,789,255,712,561,323,248,987,593,765,536,489,942,619,954,644,756,891,64,395,917,757,350,90,249,219,51,265,353,462,940,416,378,381,931,245,212,590,547,798,542,258,739,259,115,910,304,280,667,652,22,730,785,134,922,709,588,65,408,30,581,864,721,895,880,934,77,811,640,846,94,859,92,190,729,188,676,94,848,506,283,380,542,752,510,937,6,14,46,283,366,540,861,234,605,696,133,199,198,134,326,198,968,363,922,84,888,202,963,608,413,553,41,234,838,473,455,414,492,619,793,290,521,793,35,3,359,257,679,224,281,639,23,541,864,215,19,150,366,222,918,543,958,492,899,672,389,742,783,448,203,198,800,888,773,808,3,680,400,196,888,428,626,26,613,674,513,102,604,811,763,833,941,598,942,464,737,482,36,270,98,680,800,604,492,989,649,642,244,907,995,24,259,412,224,825,853,971,189,126,167,875,486,11,537,227,227,493,831,267,428,238,299,661,616,823,405,752,822,636,727,44,609,727,246,177,376,740,614,131,707,281,138,919,571,42,328,411,792,311,787,803,765,598,388,208,468,352,122,600,602,190,855,417,19,371,275,819,644,619,361,194,915,16,543,818,453,400,758,475,263,860,774,410,782,561,134,918,860,365,73,550,22,337,569,454,273,583,90,643,680,659,987,167,724,357,122,918,253,631,216,626,749,894,674,954,508,837,159,892,448,790,559,956,460,161,908,183,412,158,371,774,570,640,533,811,926,487,283,225,855,269,958,559,136,42,611,473,270,760,459,943,408,795,801,992,840,356,517,724,250,704,373,953,931,871,275,290,522,23,437,236,825,755,305,712,243,552,11,150,601,564,238,349,848,959,56,735,55,867,196,229,466,162,844,925,23,713,690,420,38,243,995,5,41,733,441,768,731,664,488,982,491,788,899,763,518,3,826,346,59,126,522,729,89,611,505,16,994,918,23,317,720,723,256,355,277,33,712,174,313,740,122,929,497,86,279,109,384,179,632,421,194,629,892,544,584,701,782,763,604,512,358,939,583,460,914,227,42,869,361,229,895,82,227,988,68,37,73,196,562,927,622,854,640,902,496,662,800,728,843,646,353,866,874,661,92,865,752,454,334,998,746,104,327,882,40,281,908,897,154,446,829,633,774,592,243,735,919,577,805,606,961,309,398,949,286,490,886,292,224,119,475,450,681,397,871,304,838,115,370,914,629,387,47,564,917,453", "247,831,934,920,164,165,212,447,213,991,660,102,459,788,638,303,356,494,838,80,235,799,764,468,624,308,494,673,603,44,23,683,243,307,937,682,341,994,65,501,388,880,650,249,427,434,514,126,714,977,889,993,949,291,817,726,144,478,613,199,253,14,514,325,727,190,598,681,551,978,567,367,665,19,713,835,460,862,698,320,29,457,341,208,736,390,310,126,974,372,124,605,557,420,443,916,494,403,151,523,678,923,296,393,17,129,898,87,308,623,830,877,542,851,570,581,91,909,561,327,69,106,868,564,297,525,98,74,371,695,84,240,56,541,556,987,141,403,1,781,133,264,389,540,946,436,807,603,899,497,898,109,771,473,0,302,599,779,287,837,470,117,732,655,447,728,951,630,957,815,939,334,339,716,558,882,524,697,49,163,257,584,100,28,700,975,535,512,649,622,314,89,291,859,185,118,19,701,299,804,25,475,586,744,241,11,6,342,32,728,56,649,60,833,429,350,846,607,392,198,602,166,541,588,210,710,597,920,5,300,809,265,674,347,162,443,575,791,65,746,666,540,829,39,716,136,605,246,386,924,763,822,295,592,751,51,169,168,405,722,357,411,3,226,355,424,233,61,980,671,753,321,986,904,203,124,524,904,518,244,86,781,894,29,502,128,932,717,683,26,24,100,191,140,264,949,133,804,861,925,967,745,435,988,286,67,670,614,86,986,545,730,268,881,195,385,880,120,879,857,182,801,943,795,720,205,155,774,925,895,505,789,465,382,842,243,609,255,163,779,184,860,612,944,110,158,638,102,512,878,617,745,967,332,110,704,801,722,870,803,78,204,930,172,742,239,746,829,655,146,946,836,139,441,928,156,252,36,660,9,992,964,890,565,826,946,967,328,585,437,961,714,354,360,311,811,283,272,298,657,267,815,651,688,951,555,881,120,6,796,505,724,313,123,913,362,179,488,706,300,448,468,80,575,190,507,558,36,281,787,51,455,947,837,980,401,337,206,947,714,511,496,228,500,664,262,536,412,970,185,944,825,55,883,60,753,74,311,86,398,430,653,897,97,791,121,349,500,798,524,370,672,502,870,380,942,891,970,307,808,611,879,554,880,196,843,521,982,347,89,613,499,74,501,720,614,258,993,957,901,315,17,824,331,141,771,507,792,524,577,524,898,461,544,738,804,143,376,727,300,311,457,64,618,899,802,853,501,769,829,793,181,361,157,211,508,891,835,479,103,326,644,216,663,722,11,307,533,21,857,969,619,254,793,456,945,530,267,547,866,926,673,610,15,96,882,943,848,240,743,68,77,400,121,50,194,987,512,13,524,741,703,285,245,260,222,844,100,977,996,528,669,577,739,960,290,489,27,552,362,502,487,242,930,388,406,399,119,889,999,135,893,907,773,182,461,984,568,530,445,165,589,762,776,70,744,316,367,490,340,971,854,623,120,580,100,506,760,648,311,858,372,938,116,461,154,110,121,970,530,345,864,395,674,797,495,172,239,580,674,60,334,643,526,617,981,627,835,869,89,620,502,862,673,556,486,82,666,151,571,744,570,553,799,2,171,714,581,93,7,104,491,481,169,722,49,674,149,573,150,148,162,693,559,436,84,97,869,129,213,128,526,650,84,352,874,825,333,552,540,306,179,342,673,736,47,171,834,261,233,705,516,399,833,415,579,929,659,648,900,793,474,223,157,399,416,554,341,685,926,226,867,284,547,115,720,298,873,230,271,181,772,774,998,668,424,341,248,298,187,143,916,337,31,415,164,196,164,317,991,374,908,103,222,147,911,921,346,762,652,244,365,439,84,43,990,432,114,405,803,332,690,790,897,405,937,935,836,398,688,709,723,931,508,115,266,434,627,777,481,376,459,934,775,456,348,257,532,657,556,128,899,502,577,383,526,301,954,163,667,245,396,742,288,347,669,957,691,7,918,899,104,581,969,381,10,541,45,303,752,83,939,639,934,751,801,888,919,124,159,90,27,328,322,679,388,306,515,227,207,940,623,474,171,380,626,865,596,757,996,701,642,911,248,9,696,29,389,718,458,327,478,828,942,502,668,868,113,550,493,836,934,898,530,290,69,654,657,257,404,798,525,408,518,734,663,590,488,2,760,607,227,287,305,619,350,647,681,289,154,24,171,62,60,261,944,772,808,328,137,76,810,657,841,674,198,524,727,278,221,265,224,406,864,471,451,803,531,911,54,161,352,219,924,954,392,149,894,846,107,776,715,798,850,973,480,962,90,915,536,911,65,320,322,574,950,953,284,648,287", "800,308,210,443,250,388,586,821,828,978,372,508,716,141,989,657,226,596,616,97,163,952,311,462,667,720,933,496,79,748,656,350,874,40,296,100,581,997,755,609,290,862,642,38,461,178,993,664,320,476,536,833,169,36,618,789,870,1000,305,835,902,383,250,45,389,54,54,165,815,754,261,730,617,3,801,67,869,59,71,541,554,423,312,385,317,706,799,54,981,293,987,9,739,508,662,237,910,634,289,197,224,192,968,433,144,998,661,772,910,746,364,945,323,387,614,319,582,26,355,560,146,913,329,677,771,462,421,649,616,557,232,945,869,445,728,6,85,868,654,763,869,408,179,735,675,301,870,255,379,748,485,547,723,618,302,0,430,246,653,638,447,638,33,636,750,172,207,292,758,825,767,590,292,457,650,989,357,91,306,686,486,501,326,737,896,792,884,356,238,669,768,383,705,304,731,980,258,567,556,45,716,98,922,456,843,200,856,538,43,603,866,854,314,713,345,704,467,174,496,403,927,234,229,383,487,919,637,160,384,857,182,985,563,307,749,863,355,768,167,718,773,984,99,640,777,614,738,993,343,649,746,986,302,168,235,1000,502,560,98,794,56,144,473,171,114,341,743,135,774,460,208,96,260,865,286,220,207,462,195,493,16,760,609,818,415,863,73,799,964,552,680,433,652,676,615,151,642,283,241,781,225,991,804,3,349,581,35,455,518,606,626,288,740,156,624,770,241,212,271,526,588,97,286,1000,593,776,484,605,298,890,312,553,862,70,607,147,835,872,363,496,583,215,970,554,735,669,56,383,375,554,723,214,834,959,6,765,947,364,768,751,160,674,370,591,294,115,670,196,313,985,573,575,251,248,59,327,50,282,966,533,5,417,881,448,381,755,246,598,523,980,894,607,692,325,830,959,321,629,102,48,400,232,424,977,343,877,609,358,475,895,17,398,425,863,578,29,485,457,303,963,863,312,308,40,832,768,849,635,550,480,880,526,582,124,657,231,503,710,918,766,340,584,69,876,625,748,896,387,206,150,756,461,457,677,9,940,958,987,638,777,746,876,914,555,289,264,875,585,200,331,849,969,257,776,330,326,640,387,384,316,123,432,58,612,961,454,7,223,360,862,686,838,725,364,703,100,249,397,695,546,827,945,239,878,618,764,80,751,546,667,820,732,964,828,529,214,622,846,493,640,862,491,579,327,340,521,442,982,420,822,656,740,50,391,24,347,560,438,807,618,391,742,174,307,215,770,700,491,481,763,482,136,115,210,416,838,973,584,389,386,820,845,673,918,61,477,582,729,553,493,994,703,116,915,319,916,541,202,608,310,669,93,856,466,188,213,995,299,824,89,465,311,367,870,606,161,524,843,8,880,943,246,739,665,431,934,188,540,744,669,952,138,606,791,326,921,891,746,148,769,574,491,378,600,240,911,408,668,907,661,961,380,638,567,45,435,435,446,883,432,753,181,810,512,436,43,614,950,723,320,106,43,56,472,860,886,770,517,832,307,541,860,912,373,954,599,249,93,75,895,739,383,929,490,637,242,124,78,554,989,607,848,638,840,579,360,470,554,381,201,8,220,449,739,798,159,716,551,597,543,775,690,955,410,231,915,394,227,230,844,360,899,100,583,820,586,568,616,849,766,367,948,259,985,740,841,170,825,251,777,820,625,907,602,779,678,969,969,952,700,542,732,404,30,620,181,940,299,53,958,806,382,467,969,564,683,687,417,145,982,219,865,761,569,516,304,772,149,791,468,93,232,849,408,122,397,944,71,543,62,292,491,295,606,265,260,85,540,248,521,231,691,14,347,193,675,849,106,815,527,608,24,644,392,993,194,510,926,804,417,72,229,893,635,783,713,344,901,958,457,400,646,878,986,95,74,764,565,794,872,148,543,705,28,899,142,203,688,755,906,138,470,219,877,964,256,634,715,544,476,801,497,197,342,738,31,11,974,927,373,113,453,673,373,377,135,164,808,562,560,28,846,666,692,71,848,351,747,57,580,837,414,718,963,866,537,767,961,730,865,646,448,881,323,303,97,15,710,454,879,748,25,819,379,22,210,522,363,954,837,654,38,600,975,993,477,881,966,533,713,518,775,696,730,564,714,974,493,10,299,563,796,511,807,866,597,533,467,909,567,181,175,880,807,274,815,283,885,98,232,742,453,721,572,406,194,516,818,589,988,668,615,951,165,465,308,907,497,484,12,229,700,682,716,293,388,492,660,307,955,604,227,687,889,745,239,381,642,167,672,520,213,735,669,96,269,512,101,123,716", "503,254,870,592,183,319,909,398,769,487,459,436,683,686,563,544,73,997,282,446,554,668,244,233,115,307,32,205,274,730,643,630,804,324,929,707,955,507,931,557,354,813,609,180,176,251,596,732,299,578,435,150,414,747,573,470,545,307,914,978,306,918,932,391,169,751,648,172,207,890,791,937,147,133,142,416,31,833,825,109,473,917,413,9,488,85,786,643,77,662,138,144,658,756,311,606,525,875,701,317,487,812,227,372,202,659,405,981,461,818,755,120,600,276,774,223,887,844,651,237,130,457,223,514,254,571,229,839,765,250,807,894,938,495,408,974,861,102,571,780,692,951,540,643,765,576,591,767,805,914,281,469,429,329,599,430,0,986,519,970,36,608,406,929,997,46,186,643,123,282,914,507,972,81,3,740,39,207,769,157,751,641,243,264,63,965,949,217,655,290,488,429,915,332,416,598,355,304,790,630,679,227,728,20,698,899,214,220,278,108,581,182,424,890,194,225,65,567,432,430,72,367,699,798,538,351,184,445,43,377,542,266,489,281,113,583,658,989,301,653,144,949,716,456,496,811,336,937,885,588,382,234,139,343,994,642,147,313,11,858,850,41,494,572,556,471,392,362,594,902,355,812,755,387,412,959,182,550,396,463,573,16,867,15,514,450,407,136,52,820,399,642,302,77,924,902,651,281,261,862,597,343,194,289,351,172,110,906,992,202,689,19,478,702,616,935,220,310,922,336,604,290,864,786,168,13,85,785,767,301,554,453,17,610,904,147,699,151,342,794,657,112,212,753,226,684,732,985,808,260,221,523,827,528,478,736,322,429,313,853,102,191,52,804,557,329,253,377,54,806,422,834,836,998,372,516,742,882,197,481,94,705,983,161,875,922,492,783,458,711,486,426,531,955,255,858,879,940,688,112,702,203,682,587,22,689,62,699,463,978,482,977,88,333,446,363,570,426,86,314,228,936,277,985,405,142,902,902,199,945,729,263,962,549,729,310,232,393,220,749,465,167,295,696,841,792,824,167,285,28,700,27,745,48,849,713,832,850,70,675,509,694,394,548,969,487,466,842,151,439,2,242,904,180,325,512,843,470,877,923,122,620,411,966,926,404,946,303,309,438,424,128,56,855,861,529,315,430,406,987,597,752,380,936,944,624,941,854,235,303,97,518,133,646,706,695,39,799,985,234,416,908,512,447,866,294,806,242,361,305,412,155,227,742,458,533,457,144,881,515,104,573,844,638,379,338,558,856,54,385,398,177,192,676,739,770,460,63,910,177,38,915,540,667,526,720,190,540,289,599,893,441,908,758,953,511,597,251,226,448,102,780,811,343,515,245,981,732,812,46,388,774,986,990,446,285,684,640,752,768,977,56,845,187,452,32,546,563,259,412,41,880,619,224,666,650,276,465,33,920,680,270,28,488,634,892,351,443,884,91,137,937,623,898,405,417,711,590,500,204,641,983,333,56,565,263,557,791,746,243,909,595,658,9,486,495,859,980,710,384,720,965,904,781,916,237,67,208,465,298,582,544,603,536,625,338,634,562,113,216,175,262,844,76,661,379,187,893,711,736,337,152,436,247,123,118,169,595,238,542,78,704,17,620,497,171,956,950,504,833,687,331,237,800,751,520,66,38,278,912,957,965,910,167,701,45,538,780,885,268,639,111,229,470,539,395,919,826,624,591,734,555,760,320,300,264,338,543,486,64,241,82,746,353,165,263,306,360,60,920,720,529,160,557,810,994,759,328,823,625,80,528,698,7,591,530,459,250,372,999,505,744,737,981,251,985,661,558,245,294,890,420,306,614,857,895,552,128,851,432,274,835,622,921,405,756,774,975,682,553,610,52,153,455,36,364,258,109,524,76,446,316,716,715,388,129,34,92,221,109,865,969,720,341,390,247,919,893,512,731,432,975,892,461,828,537,916,710,861,556,925,381,879,75,170,79,885,191,280,189,683,502,286,893,865,732,196,857,498,823,917,826,625,28,842,228,280,117,925,202,371,829,45,145,130,12,902,525,308,806,583,642,768,220,926,588,69,360,931,540,37,585,943,672,144,827,533,807,148,349,318,427,40,481,824,753,784,742,898,241,585,940,588,691,613,332,704,559,592,713,521,240,442,251,269,423,381,112,103,357,589,946,803,639,186,539,983,521,788,278,300,821,828,623,518,605,446,86,355,213,444,686,577,314,112,621,323,785,342,817,51,581,411,877,777,619,904,462,532,963,930,793,46,679,790,832,282,810,349,896,130,787,769,252,129,389,761,787,589,216", "767,860,900,793,886,497,532,782,181,168,530,251,93,944,182,821,709,68,315,415,574,60,595,29,69,199,537,352,43,783,121,385,190,99,126,856,732,324,548,665,259,554,75,235,515,435,976,947,540,360,444,150,981,523,563,880,219,956,744,404,657,908,951,833,939,944,802,212,765,282,264,150,197,943,43,30,187,559,320,486,787,354,318,136,107,246,671,546,874,30,322,13,147,869,277,569,252,543,538,646,911,787,650,292,388,648,689,674,562,564,255,694,252,193,744,800,654,993,511,489,54,675,919,945,358,892,464,414,236,962,368,972,696,661,493,858,569,245,313,818,178,665,711,978,581,353,444,381,868,766,371,445,472,340,779,246,986,0,660,672,169,523,8,989,516,631,811,243,572,668,371,541,301,163,9,868,591,224,437,338,869,778,726,440,615,39,965,954,964,494,60,58,680,644,55,291,123,892,326,936,251,706,989,941,828,347,384,734,226,192,440,26,334,375,104,606,502,80,833,262,71,985,703,45,937,298,935,221,706,484,886,761,931,32,322,559,305,107,172,73,827,850,135,890,432,19,978,843,953,479,879,928,619,942,424,874,722,580,691,612,894,280,296,500,247,757,953,600,796,965,387,655,474,268,86,975,948,871,220,36,787,922,910,687,629,428,901,541,24,398,924,189,216,737,621,360,538,921,482,602,930,59,791,652,29,35,697,771,36,171,264,176,986,555,402,305,869,685,658,770,528,788,517,860,284,679,960,430,2,81,297,4,697,989,613,612,638,531,716,798,561,355,49,342,447,678,619,148,26,905,579,739,370,543,64,224,479,852,88,730,121,824,424,246,670,701,350,484,748,436,437,241,440,774,971,700,59,600,938,913,33,656,578,857,405,536,344,110,883,517,482,405,367,270,523,845,653,54,432,124,335,533,379,288,501,178,352,112,82,385,152,503,862,68,971,584,647,752,421,586,945,871,826,634,758,700,655,94,382,604,405,696,160,860,629,419,539,661,966,245,1,74,520,685,925,162,783,431,415,828,688,908,411,567,933,599,617,109,385,249,410,680,656,63,622,807,448,889,735,959,956,886,117,897,584,925,858,585,950,211,68,410,68,679,32,143,781,703,368,725,179,282,620,516,8,268,35,561,828,666,802,398,145,284,470,29,132,222,272,161,219,599,296,772,951,401,102,854,631,33,500,738,460,752,921,770,82,517,317,930,543,728,17,103,717,35,31,870,650,438,746,733,527,790,134,583,387,302,721,135,351,966,961,212,346,767,204,180,937,458,3,676,620,721,451,34,155,809,635,326,919,21,993,152,482,259,390,897,779,168,107,711,28,248,495,332,546,838,311,16,381,106,171,18,926,182,969,54,352,34,384,705,478,600,382,430,441,476,362,826,372,454,23,341,336,126,737,414,577,9,254,424,421,345,920,794,716,559,651,265,969,981,418,756,716,340,295,534,109,688,43,487,512,691,552,778,263,670,173,732,821,632,886,498,188,578,60,3,919,189,347,524,503,388,890,33,991,110,378,533,46,457,294,68,467,655,120,42,351,810,716,599,370,342,855,199,733,569,752,702,92,294,263,126,891,799,963,250,637,384,563,961,423,67,598,356,711,653,721,643,739,185,465,14,916,32,518,885,589,198,400,673,617,923,396,472,692,626,87,216,317,674,18,680,458,617,988,964,302,461,440,763,759,107,482,560,287,338,912,250,582,876,883,289,446,311,970,745,225,993,513,985,958,384,808,916,518,156,328,907,827,621,123,360,977,878,952,255,315,24,306,618,343,535,7,52,397,312,273,790,401,580,98,287,258,985,860,293,494,333,470,71,974,391,262,475,810,648,57,442,838,922,900,215,392,962,877,564,924,925,723,60,302,772,139,514,188,313,139,920,198,330,727,421,977,511,836,663,827,755,899,372,209,419,612,644,873,430,610,374,326,108,183,220,977,545,581,31,920,459,20,498,939,673,298,194,856,343,503,93,787,777,221,346,291,887,590,810,604,689,769,517,344,290,852,564,274,168,373,989,281,964,538,368,657,219,220,168,541,712,432,316,640,943,155,245,975,893,411,653,180,105,938,367,826,284,299,170,314,634,637,899,350,538,39,969,375,519,424,726,66,257,322,775,745,841,873,288,951,614,566,242,248,782,373,484,287,396,553,458,158,658,714,211,740,899,858,931,658,789,342,381,438,372,407,343,450,281,209,160,986,371,454,602,47,128,345,478,906,14,869,636,158,747,140,811,686,912,299,197,131,372,804,481,213,943,384,308,861,642", "869,338,656,781,464,690,443,166,777,649,857,254,360,305,88,302,953,843,903,668,166,676,84,798,303,654,61,949,3,915,318,311,232,655,256,993,584,867,808,68,936,642,834,899,136,978,120,223,518,284,670,846,438,340,11,752,462,988,681,247,561,462,500,27,26,813,956,507,238,992,231,625,711,783,158,980,636,854,982,227,930,24,668,575,219,604,6,280,306,735,780,44,995,275,413,248,614,215,279,372,104,564,204,480,28,9,391,236,915,184,452,490,14,814,131,268,693,184,951,426,469,97,991,65,844,909,942,913,376,228,162,668,444,298,205,663,301,475,592,769,439,958,358,580,765,539,992,672,404,767,874,852,584,703,287,653,519,660,0,760,391,188,157,221,86,893,928,185,128,907,435,536,526,919,479,103,613,45,340,58,394,453,654,825,718,297,598,25,2,156,522,986,628,16,675,14,719,188,764,429,195,421,930,67,227,129,52,475,599,956,798,628,500,787,856,785,641,35,467,647,992,984,792,553,200,238,346,391,554,471,895,843,41,591,474,452,196,223,608,24,235,407,851,884,111,468,245,14,507,514,812,921,940,553,12,899,568,461,564,645,866,158,886,759,489,105,460,757,640,948,359,269,14,954,377,982,818,324,376,166,482,526,704,144,173,96,789,47,908,195,104,641,339,276,745,504,210,857,877,145,400,313,866,142,904,209,65,949,340,500,59,678,762,949,876,406,357,622,298,890,552,278,78,907,332,975,251,218,669,771,810,151,779,378,490,784,134,390,449,196,153,221,882,197,266,228,220,284,289,408,757,377,102,885,211,642,696,280,444,439,956,398,653,828,623,592,593,579,121,496,455,595,669,134,716,585,158,264,941,112,201,134,302,401,99,303,189,428,583,135,681,142,29,803,43,501,271,116,841,854,452,536,285,582,548,564,862,461,950,71,657,552,117,895,488,463,387,707,218,509,228,6,974,330,828,421,104,243,466,440,961,57,768,444,67,51,372,16,509,359,944,282,794,941,331,280,189,572,508,873,78,595,888,472,873,703,303,354,156,693,678,534,762,677,268,99,257,122,738,832,350,161,665,600,597,324,877,36,518,927,76,465,212,393,383,514,566,445,83,272,998,515,402,389,18,931,635,175,483,108,349,966,353,485,839,174,765,298,833,35,547,360,162,781,895,3,206,505,587,120,136,986,587,18,189,157,95,186,760,896,860,380,853,594,364,901,766,245,810,736,934,766,58,596,376,749,83,341,216,607,495,492,174,930,695,33,267,713,348,295,439,510,66,238,935,737,619,94,707,950,839,362,93,839,555,487,930,433,343,958,412,186,521,434,446,714,729,38,265,820,850,405,387,847,575,541,237,976,163,509,917,539,448,324,964,225,961,769,142,116,646,476,869,357,454,171,332,693,26,715,93,804,555,784,741,957,313,294,275,689,401,692,858,802,862,250,585,902,870,106,493,324,205,591,643,841,371,848,146,815,535,725,225,153,97,339,372,314,538,132,623,396,258,936,108,683,907,76,494,903,993,34,74,843,577,734,723,333,96,810,275,646,783,654,889,177,85,345,667,946,982,744,766,211,329,994,279,123,665,188,835,722,356,137,919,43,938,768,787,343,755,147,588,308,755,676,270,721,786,580,653,720,255,608,478,207,476,830,207,856,317,674,44,619,767,986,326,160,467,433,190,286,11,358,917,76,928,175,552,271,991,171,475,990,116,773,960,744,731,756,79,63,543,461,702,349,435,923,741,955,656,86,733,550,801,837,800,94,613,325,215,533,843,383,125,204,434,712,839,606,404,925,521,585,267,123,809,355,551,146,484,242,394,473,775,298,968,314,347,566,673,915,335,293,907,896,592,104,150,651,648,481,800,87,673,890,380,207,346,120,246,377,443,396,499,451,737,42,290,558,350,322,585,416,810,838,893,880,908,717,677,645,49,345,750,626,119,295,714,461,765,22,321,794,376,534,635,126,770,991,397,543,108,264,28,737,54,625,486,750,660,656,436,746,648,856,553,406,100,110,308,772,330,638,794,119,416,899,194,928,735,134,416,150,563,930,913,906,869,517,162,270,191,22,826,891,394,73,362,102,771,868,295,135,28,845,231,972,862,330,958,288,608,773,447,874,888,196,419,688,53,323,635,959,59,427,132,226,643,152,701,602,801,395,290,984,290,245,342,34,47,21,544,433,473,537,307,730,736,534,496,819,50,125,768,706,298,324,296,318,45,562,250,539,762,437,210,907,417,201,969,642,726,364,89,656,272,782,968,327", "13,739,780,277,540,797,1000,274,96,868,541,252,919,220,858,270,913,946,701,284,95,676,554,779,349,721,53,209,201,654,457,220,467,68,275,481,8,274,266,53,47,556,721,757,809,154,306,986,93,576,872,518,385,172,771,8,201,982,30,17,137,80,882,314,9,23,273,740,88,726,762,915,885,431,306,293,693,468,645,811,700,175,523,398,94,99,525,611,390,479,663,328,555,499,398,995,629,980,240,562,18,543,664,390,792,547,381,204,22,966,26,750,898,554,820,593,449,177,827,98,978,236,90,949,752,153,612,814,559,222,602,579,266,921,690,447,319,615,410,728,756,42,381,409,455,912,889,971,349,883,492,514,883,856,837,638,970,672,760,0,102,533,624,509,277,227,849,445,304,402,264,488,940,858,679,724,846,14,777,431,376,661,671,42,54,767,421,659,462,334,589,655,876,874,823,960,118,617,644,236,876,400,200,395,370,898,467,100,665,656,943,475,675,320,295,130,228,84,735,394,743,486,841,975,999,119,174,306,897,333,311,261,923,296,337,429,460,294,623,989,55,828,5,63,39,594,718,475,853,425,172,239,699,996,723,233,285,562,567,837,113,495,968,313,720,284,704,490,560,53,828,569,352,693,318,804,310,85,758,11,710,532,67,716,766,209,711,500,996,584,322,941,616,475,641,355,663,237,418,382,925,634,483,172,327,506,884,38,976,379,57,237,387,310,721,510,347,871,252,161,265,595,473,822,930,662,105,616,469,275,425,689,532,711,954,637,198,40,974,777,897,712,369,27,874,113,450,682,97,263,629,927,332,260,382,190,120,272,943,954,813,866,211,816,970,102,482,24,428,160,271,540,999,554,484,339,154,262,781,649,796,641,874,237,171,786,920,263,256,222,759,684,530,434,478,3,141,910,323,455,249,35,94,113,839,149,508,763,462,379,518,656,591,905,623,283,964,836,850,395,947,715,31,685,386,132,842,147,814,450,108,665,478,755,64,906,111,193,680,146,569,812,496,710,320,196,478,397,643,909,472,648,622,915,908,259,608,582,375,776,592,431,825,585,487,752,710,854,684,878,201,122,847,960,448,531,460,288,859,691,438,51,166,65,589,401,976,73,371,418,272,426,655,503,915,880,3,446,307,630,475,5,11,599,436,293,46,629,47,913,796,978,161,751,63,15,874,194,402,502,711,663,690,68,200,646,691,374,679,203,453,233,140,92,446,730,756,830,110,70,148,229,344,782,333,300,500,179,172,948,492,436,729,465,702,825,685,103,634,12,393,26,310,389,613,179,306,139,453,558,930,657,732,830,679,782,512,495,389,516,442,932,236,473,435,481,819,637,112,54,380,313,240,536,390,512,411,464,890,377,923,823,616,342,266,852,422,446,857,318,527,11,420,649,628,289,545,415,731,744,48,378,3,532,613,86,229,140,798,241,678,189,681,571,854,335,438,415,31,287,567,922,442,162,419,293,886,680,150,320,951,710,117,279,248,436,85,252,847,328,752,908,433,162,131,338,215,321,885,852,625,284,565,115,21,155,60,960,697,951,600,878,60,383,475,511,206,98,942,183,291,153,592,697,262,593,666,646,568,243,564,575,457,195,175,398,203,31,809,346,859,419,818,811,824,708,887,457,415,5,542,579,199,768,747,499,816,773,290,790,612,63,765,343,796,994,469,85,476,524,710,569,612,526,910,826,17,163,950,620,978,686,769,767,65,883,656,133,796,358,729,678,880,188,585,960,40,748,500,799,145,972,726,766,410,819,880,525,767,428,390,230,577,597,782,939,39,24,96,978,571,64,606,87,667,440,575,874,778,20,640,236,657,523,583,805,462,526,236,7,720,956,924,880,758,840,61,224,194,88,995,933,627,930,159,490,285,409,338,726,543,751,30,623,954,172,433,84,382,809,715,781,921,661,241,534,476,562,795,537,609,103,502,268,259,206,649,794,252,103,292,738,701,672,949,444,233,611,593,367,926,227,27,636,715,328,930,533,122,837,98,806,238,811,595,681,625,106,543,777,654,150,886,872,980,615,684,101,570,314,649,198,815,722,513,148,780,366,512,451,657,465,693,573,604,960,42,225,868,84,550,682,190,503,89,461,920,546,665,895,332,735,258,466,124,595,56,623,650,850,65,469,712,367,8,755,128,666,79,619,974,9,901,796,507,512,180,448,910,451,931,377,487,210,945,521,459,569,125,863,855,202,78,865,945,996,851,461,292,543,80,481,335,292,560,301,173,506,373,692,294,679,118,694,981,182,511,166,742,47", "252,614,679,326,586,985,180,576,443,100,450,363,697,724,205,303,369,55,734,208,895,566,436,555,284,418,293,555,210,30,92,486,561,883,847,498,420,897,345,600,347,693,980,636,725,381,190,931,458,977,934,566,851,476,78,962,26,251,451,708,842,877,13,471,113,128,165,123,852,699,817,850,337,36,266,875,602,731,416,467,112,21,806,527,34,938,891,681,840,234,664,492,985,562,195,90,485,484,321,675,159,994,387,984,313,537,392,998,354,521,452,659,514,70,246,646,423,712,209,43,282,594,733,687,708,933,229,331,115,161,512,28,186,606,960,67,670,791,527,391,728,641,803,489,987,254,661,116,749,184,739,696,934,217,470,447,36,169,391,102,0,34,635,310,15,380,402,85,475,646,818,171,542,993,272,9,163,64,128,160,295,658,75,300,918,126,960,339,916,300,504,415,33,512,244,521,72,247,121,423,211,677,578,314,177,511,486,45,262,548,878,244,978,828,301,333,336,856,267,447,599,682,686,64,825,187,339,710,919,554,898,777,868,699,770,547,975,204,623,864,869,74,862,333,668,908,855,198,325,181,908,361,751,613,231,136,615,705,872,365,380,32,898,905,158,673,275,912,914,3,742,609,371,667,386,799,453,561,252,262,1000,526,167,376,971,949,821,602,398,729,514,39,930,69,34,36,731,970,343,852,500,996,754,531,35,521,139,890,978,575,766,436,642,193,356,760,618,260,909,41,65,223,683,945,4,338,444,927,284,813,977,842,346,493,904,152,218,995,130,828,980,746,701,51,643,118,143,524,334,460,991,251,54,636,973,655,309,36,108,938,578,705,333,92,976,929,217,131,111,211,122,165,41,324,946,771,674,721,3,314,624,931,502,791,567,919,173,309,531,992,466,424,783,398,626,248,793,429,991,739,724,760,376,986,968,428,664,79,898,979,991,996,809,524,643,278,156,420,24,211,200,107,545,60,587,646,721,960,147,668,744,755,679,515,264,150,517,470,833,515,399,405,81,71,262,885,443,998,480,700,686,348,398,565,223,702,951,898,662,534,998,97,593,955,69,560,625,427,23,290,47,621,41,592,775,886,629,22,92,94,941,999,323,803,779,178,607,681,235,17,168,725,268,240,281,643,502,618,993,305,356,505,784,7,584,327,57,208,676,675,133,504,81,743,476,983,944,142,329,170,578,316,990,624,212,550,533,321,485,630,332,524,56,805,368,748,297,105,625,468,132,43,399,987,360,171,753,659,971,667,760,725,235,474,835,570,161,120,713,852,49,522,779,659,512,449,650,38,978,969,963,329,355,628,325,378,115,366,877,532,607,366,248,157,999,779,560,401,420,691,193,784,474,576,352,437,143,767,861,91,551,5,829,114,405,904,561,390,164,820,158,50,150,771,488,435,330,175,271,288,174,484,857,934,251,469,598,472,239,491,573,393,939,490,615,556,189,467,824,763,815,621,54,373,937,894,14,440,653,613,989,92,210,237,923,216,975,351,141,486,227,271,667,474,332,631,552,826,786,403,811,268,824,991,17,897,576,150,839,72,938,485,624,719,139,246,14,513,216,841,14,104,276,62,183,109,461,954,304,785,209,855,511,180,223,165,219,782,813,895,159,557,29,834,756,217,48,674,605,413,580,113,293,840,197,847,15,387,589,768,188,5,183,449,670,541,545,182,628,860,137,302,485,992,61,858,436,634,57,862,547,900,125,972,835,424,775,279,344,681,48,942,630,993,438,578,871,509,403,672,223,872,958,925,446,856,841,555,459,58,529,309,141,895,306,900,889,712,961,407,78,339,162,981,786,534,573,625,948,594,346,569,831,334,224,499,740,875,854,186,189,353,359,182,704,272,446,964,757,679,613,747,927,590,747,127,756,637,162,920,832,12,684,396,989,943,68,62,365,10,554,738,816,466,82,31,733,683,410,577,21,836,362,841,929,524,44,407,599,79,33,529,279,728,122,52,919,417,318,124,6,78,849,793,471,633,280,563,575,905,442,66,878,279,742,633,859,551,393,531,182,247,887,311,52,733,139,694,433,692,365,858,492,136,111,426,33,12,614,453,928,918,766,943,747,771,97,746,499,375,472,605,368,939,712,884,152,799,464,26,514,965,284,622,594,979,181,896,543,107,177,13,888,941,682,500,66,973,542,653,259,397,886,210,701,63,482,105,475,382,676,828,683,500,268,882,340,246,488,143,666,236,98,702,969,974,91,784,151,31,592,376,459,563,700,772,23,497,498,548,776,980,46,13,929,698,744,115,283,738", "746,918,147,971,85,796,352,392,927,979,302,874,416,198,171,546,331,174,430,499,323,918,483,662,384,409,784,154,758,800,152,31,715,489,6,351,183,852,654,486,750,362,235,955,984,586,680,385,639,693,231,714,284,688,587,831,319,114,633,443,603,144,497,276,917,458,350,109,849,344,74,906,87,831,496,203,665,199,734,192,922,969,887,425,500,800,612,160,189,113,743,546,15,344,232,905,665,599,162,865,890,745,897,286,324,931,479,584,919,608,389,211,857,266,770,249,117,651,83,584,845,116,16,108,262,50,784,518,508,115,336,233,442,537,84,280,817,701,571,641,444,782,46,299,180,239,255,994,813,458,512,87,724,716,117,638,608,523,188,533,34,0,302,3,519,341,267,34,787,923,527,155,245,340,768,390,30,670,290,743,524,607,682,903,696,5,594,810,640,292,650,522,628,333,530,849,288,662,527,426,923,185,27,530,543,794,647,727,22,408,112,52,417,956,825,477,589,398,868,270,707,285,798,761,320,959,274,406,353,772,464,574,394,385,224,292,295,937,256,561,6,439,190,654,241,646,423,380,944,515,495,847,719,480,756,611,669,65,140,198,431,347,450,958,438,349,378,971,136,909,750,296,7,753,660,719,189,57,347,350,394,763,398,585,177,21,606,104,552,904,861,641,266,197,46,464,957,827,761,715,770,694,988,999,802,23,372,357,278,510,576,224,72,421,18,443,926,879,748,775,760,768,304,104,86,314,195,589,133,213,421,949,655,948,277,823,5,279,473,630,279,681,7,25,718,192,261,147,275,446,134,785,213,532,55,660,745,454,321,622,835,128,515,29,646,126,485,973,896,246,530,964,421,429,791,546,557,566,731,50,17,823,229,25,709,768,266,700,590,560,944,569,182,372,24,802,200,19,94,59,427,713,400,167,175,595,622,450,755,816,753,343,644,581,596,299,267,634,344,624,608,706,459,127,224,152,232,787,690,775,804,267,43,118,732,670,98,101,453,588,914,410,787,374,349,176,113,918,35,480,816,482,553,280,841,409,413,794,358,458,335,786,163,962,812,874,328,850,469,594,693,674,532,549,913,957,624,511,548,391,783,620,923,874,816,848,937,67,722,150,852,123,546,676,539,791,366,223,252,409,813,487,617,222,515,718,339,506,62,756,211,729,941,603,296,560,757,605,20,951,771,558,761,106,124,901,140,608,286,366,578,17,660,906,216,159,221,265,432,298,714,237,993,906,328,308,502,855,633,259,606,799,15,74,640,786,320,755,923,965,205,39,283,756,853,719,459,236,758,407,114,515,636,320,170,365,765,202,164,359,839,216,239,593,956,135,35,536,915,562,980,267,668,617,835,282,780,419,860,892,715,159,655,63,480,246,174,189,246,731,939,740,242,194,322,986,289,481,500,739,875,599,867,5,457,413,692,244,552,358,671,751,668,550,501,124,268,654,173,429,551,958,551,721,243,920,442,622,940,27,415,782,783,212,234,513,390,783,923,279,894,451,878,201,822,64,8,383,80,709,595,698,484,672,383,334,324,763,429,278,878,657,253,905,767,174,529,177,863,265,838,226,673,503,986,580,872,996,130,510,518,470,887,177,980,41,444,201,978,722,173,292,797,999,867,587,343,907,392,969,480,732,503,778,720,796,811,937,383,141,702,986,237,269,701,925,914,928,958,904,864,470,917,897,869,232,115,607,123,794,851,873,909,884,818,726,965,191,266,974,327,21,327,53,877,921,94,56,662,901,809,764,165,830,150,38,485,16,894,99,800,215,273,983,481,809,442,446,489,112,782,901,930,537,284,427,722,289,766,382,614,421,240,674,240,808,510,750,833,339,331,580,493,958,815,200,226,471,56,55,823,485,326,812,241,987,135,196,505,921,806,304,120,139,70,328,732,74,197,346,263,416,106,965,711,49,545,819,624,837,93,819,746,888,135,167,410,181,706,790,292,146,131,224,968,375,808,736,615,495,998,144,484,531,358,547,128,721,12,140,284,269,656,491,425,22,831,856,252,768,889,532,650,998,128,895,415,624,944,65,97,937,644,889,850,468,348,442,33,302,569,528,276,493,978,509,3,20,170,830,728,573,901,891,768,971,5,927,865,149,948,700,841,978,52,758,448,679,386,218,497,735,399,639,803,782,82,93,66,162,444,628,335,804,179,138,917,256,244,286,850,178,652,247,485,145,161,424,733,502,744,740,324,952,154,727,19,946,183,975,180,976,244,534,558,464,583,953,296,748,47,61,670,534,304,124,491,134,460,983", "6,21,201,673,769,96,740,929,478,942,879,2,372,262,21,429,737,651,311,376,257,86,95,992,126,826,234,958,436,768,794,477,234,571,247,245,193,965,507,656,858,889,694,498,818,216,666,412,715,578,941,633,904,964,430,300,296,969,358,595,358,111,994,403,1,988,929,302,793,344,702,478,749,880,234,283,97,864,79,24,787,975,268,956,625,85,597,191,696,933,968,334,701,62,988,151,857,133,299,928,945,706,858,352,883,590,619,856,72,449,982,21,365,58,608,992,510,289,701,389,96,700,694,926,425,639,319,162,925,812,37,889,479,555,491,327,32,60,638,230,711,53,795,746,685,264,328,782,976,652,372,305,997,692,732,33,406,8,157,624,635,302,0,682,559,170,179,793,801,913,629,503,538,884,480,439,249,700,769,644,517,31,358,480,272,87,45,384,945,264,68,806,395,974,922,984,640,451,124,382,199,886,612,79,145,748,999,963,28,564,900,279,199,587,829,989,897,358,528,299,551,637,413,382,174,175,146,876,602,426,892,385,4,918,237,649,401,37,286,698,37,91,325,314,230,956,795,374,948,150,488,986,408,724,609,353,727,536,676,100,547,666,641,650,51,755,874,259,206,718,723,810,883,635,963,407,150,247,137,222,862,494,922,372,240,528,768,970,79,292,600,459,451,914,725,615,102,140,145,263,858,271,190,331,901,209,646,856,822,601,123,998,107,413,453,772,817,608,215,261,716,499,775,263,144,864,271,468,732,729,821,715,450,206,953,913,811,892,687,772,920,442,447,626,645,930,614,44,781,81,922,419,277,736,289,456,734,959,310,727,218,522,104,627,354,406,169,787,171,70,315,280,738,562,864,323,638,507,374,162,540,275,19,192,762,862,763,945,658,499,262,40,17,385,163,676,512,890,131,902,526,825,987,489,350,745,270,659,384,410,631,943,92,397,570,571,220,509,923,374,563,865,337,188,941,452,485,562,675,926,163,104,763,813,938,968,178,805,941,999,864,710,829,817,586,668,271,103,746,757,354,107,360,588,320,957,76,294,332,748,358,27,533,561,943,501,979,958,553,180,805,299,65,25,770,653,52,580,471,953,358,640,991,18,883,871,835,816,523,872,359,910,471,148,68,501,596,608,96,369,167,87,553,5,792,541,517,779,726,427,564,874,5,987,674,135,580,665,38,494,711,382,172,481,406,847,612,405,754,922,587,224,899,581,789,365,730,343,340,519,715,428,177,719,123,657,512,78,103,934,767,356,448,881,434,17,798,598,670,469,953,989,862,1000,330,650,119,404,174,707,451,156,904,700,15,223,457,136,91,627,339,163,523,67,674,967,281,695,94,815,50,390,548,4,343,886,346,558,984,66,407,754,345,750,508,90,839,693,705,255,444,207,428,15,4,105,580,459,959,963,727,201,104,665,758,985,838,617,572,14,22,133,191,663,85,180,372,203,765,649,922,885,78,701,65,465,986,243,74,657,725,534,59,748,680,51,343,418,143,456,9,632,980,93,330,13,118,763,454,293,395,14,6,187,942,640,106,950,480,671,370,878,507,231,537,514,395,795,743,139,880,722,735,211,439,371,125,930,232,388,156,763,303,536,914,114,434,597,341,791,510,382,828,593,536,364,208,273,836,979,100,909,976,540,351,120,364,506,980,943,379,208,5,956,641,403,402,7,535,452,237,245,974,341,820,267,239,184,824,26,959,911,676,108,621,916,312,947,924,345,720,328,281,223,278,353,401,311,782,273,430,956,869,295,907,787,111,95,813,919,217,715,612,995,849,845,949,707,84,683,701,90,903,664,752,286,98,167,625,817,777,535,59,93,257,330,110,164,578,664,562,352,570,707,170,859,289,582,28,621,9,353,54,436,618,556,759,743,144,611,270,806,117,280,756,599,607,871,237,441,235,38,787,359,477,451,409,711,54,382,438,855,771,565,570,748,52,994,811,799,462,754,459,803,136,507,376,259,963,972,992,324,845,459,749,583,855,756,356,43,512,850,736,707,361,878,531,551,797,514,746,144,43,852,759,796,229,422,380,575,363,212,979,717,925,818,615,130,435,825,386,736,751,991,641,191,596,341,632,655,539,826,303,656,435,183,287,273,115,630,469,680,237,583,3,711,434,660,49,967,553,475,361,377,976,452,357,28,339,792,945,549,703,205,767,935,303,338,411,528,697,426,911,310,784,975,187,988,47,306,85,650,373,904,923,70,616,161,460,742,685,138,686,614,613,420,170,397,555,789,477,697,961,202,250,904,66,48,64,570", "436,493,135,208,967,484,341,16,364,304,922,925,851,741,76,549,283,469,6,498,323,951,209,172,456,962,365,761,141,27,422,535,339,954,85,383,955,614,723,772,901,247,456,757,357,602,3,749,140,37,402,221,981,976,987,411,617,563,173,916,40,306,568,659,27,340,391,141,161,603,967,736,692,896,186,398,544,971,521,974,77,880,19,649,333,692,214,480,535,712,663,57,250,353,646,160,143,290,885,556,498,643,141,323,38,296,623,332,555,725,746,859,157,265,515,758,326,131,729,573,847,208,119,184,661,518,992,931,135,288,422,151,586,880,751,536,156,986,391,32,274,177,467,720,753,398,437,715,903,530,100,780,793,697,655,636,929,989,221,509,310,3,682,0,900,967,760,768,517,819,224,238,489,864,363,496,368,675,357,661,971,157,642,47,474,973,966,222,917,157,193,29,995,725,737,930,611,226,868,20,949,910,190,501,825,874,366,177,698,573,825,59,701,453,173,337,869,247,955,783,189,441,896,692,49,751,834,750,611,506,889,903,142,225,653,486,49,87,426,452,111,35,913,918,875,795,526,127,447,303,618,67,650,726,737,321,705,379,106,886,37,994,314,950,487,498,885,990,197,518,863,95,430,898,491,395,183,128,150,446,610,488,689,422,173,860,132,468,496,387,941,708,798,940,870,534,347,684,557,352,521,319,188,417,444,35,572,460,506,931,318,931,471,806,317,382,105,736,943,78,147,276,914,718,120,398,40,108,326,677,579,595,380,29,911,553,787,201,359,126,269,528,649,883,262,849,121,661,696,960,274,203,441,164,293,492,794,965,353,739,673,450,849,584,999,203,682,430,221,878,279,991,153,923,776,102,92,190,986,427,120,791,563,173,796,411,17,152,878,580,833,381,549,130,145,159,74,979,640,622,125,53,409,59,592,303,737,362,419,14,416,946,1,446,100,355,996,108,246,280,501,821,172,848,808,219,706,56,671,326,900,680,896,689,110,212,628,866,793,315,815,615,136,196,631,605,728,962,160,165,856,105,813,21,786,870,104,969,152,438,836,682,302,234,214,622,235,67,467,934,478,604,557,111,508,924,230,270,134,772,674,845,622,577,575,800,758,928,420,408,653,501,697,657,687,202,580,582,434,880,791,11,609,683,487,303,634,709,69,145,687,898,839,209,139,534,87,674,290,828,643,41,658,105,689,601,758,239,895,851,694,9,522,787,142,759,973,131,355,369,823,815,3,748,466,474,422,313,964,628,965,720,817,552,143,264,240,114,531,531,156,980,303,310,604,745,404,587,775,918,506,344,35,56,326,270,367,875,608,700,45,947,739,563,683,698,29,382,139,284,260,848,908,866,564,488,395,19,615,246,20,423,282,130,819,655,684,65,158,880,562,898,488,595,841,735,597,283,907,93,930,984,892,994,902,649,123,530,269,472,920,666,931,832,281,384,344,613,624,173,722,373,398,974,466,75,578,858,497,693,656,65,861,168,886,571,110,340,925,145,654,432,772,436,486,607,851,70,446,57,494,685,792,458,772,107,34,241,278,37,354,6,391,783,796,354,840,823,294,773,308,974,219,251,525,934,598,65,342,273,913,186,770,548,247,453,441,532,28,788,505,732,531,81,827,609,842,279,745,520,446,418,808,619,623,862,208,283,256,649,527,298,998,948,459,960,488,295,59,822,71,578,201,335,438,853,75,249,608,268,491,897,991,554,484,690,922,457,784,741,127,68,852,420,375,42,246,495,995,635,421,90,940,850,399,535,561,753,628,774,668,761,270,682,148,762,476,805,910,905,238,648,639,182,449,135,361,888,613,366,506,636,979,703,649,697,55,290,307,854,152,641,150,946,460,147,549,221,255,266,918,911,553,65,466,976,659,283,567,9,353,958,89,803,688,993,700,813,348,710,841,454,430,412,412,704,839,885,499,915,30,789,882,851,215,958,828,454,509,961,801,602,420,832,514,824,837,182,928,28,14,984,35,853,754,57,689,775,510,170,346,700,825,681,733,905,932,657,783,365,515,906,22,229,681,430,87,445,636,845,997,787,304,68,928,439,227,456,398,281,682,308,457,151,631,558,334,483,199,232,739,202,408,678,881,311,472,13,35,129,968,532,827,969,706,762,825,706,444,695,8,344,225,187,368,244,57,197,749,45,94,453,993,875,875,603,320,61,340,165,614,472,630,749,649,961,386,578,609,977,225,676,694,415,601,96,656,277,819,891,533,430,656,388,739,614,298,624,974,718,669,278,119,276,637,112,400,570,596,503", "793,370,932,83,781,873,215,621,290,625,274,635,248,86,518,515,21,430,40,299,140,934,909,122,103,787,155,314,899,407,424,398,185,172,180,326,391,129,479,336,702,961,901,535,269,24,435,734,556,529,650,763,344,693,392,72,331,977,1000,410,282,692,194,87,132,853,109,28,827,785,248,15,911,285,821,152,313,370,297,442,59,902,434,765,628,737,344,682,84,689,954,601,226,124,687,847,948,15,463,921,76,946,979,385,389,732,523,798,158,262,894,925,684,880,784,431,794,184,893,111,216,959,651,889,158,299,163,854,774,467,585,412,989,356,766,769,619,862,585,999,855,952,587,982,774,220,612,168,799,497,918,471,527,104,447,750,997,516,86,277,15,519,559,900,0,920,614,201,389,800,48,367,610,540,845,948,891,237,721,11,563,543,668,942,938,669,157,391,591,194,660,899,49,409,87,623,831,588,420,613,406,157,750,392,999,352,23,363,738,953,772,686,763,776,800,199,587,670,731,398,769,46,621,701,445,423,253,248,914,284,891,837,810,467,412,600,446,57,944,607,250,21,786,338,530,276,960,228,262,981,788,443,477,179,391,668,302,543,691,485,525,494,214,297,497,682,908,894,289,376,89,900,8,973,232,260,723,130,262,475,297,276,209,957,416,722,170,249,81,731,728,55,249,607,821,992,571,259,789,511,637,907,516,818,112,26,899,158,173,787,801,486,675,807,783,740,226,616,383,367,761,965,80,913,512,231,684,354,489,213,272,261,584,274,656,30,380,341,629,566,975,475,372,818,423,722,191,269,409,830,936,634,27,677,565,982,963,529,978,449,537,1000,739,140,983,278,128,225,225,200,894,716,950,97,408,200,631,132,64,801,234,7,145,166,502,980,485,360,469,509,74,322,355,846,110,163,686,213,468,401,634,104,435,517,299,304,861,254,569,436,915,371,467,579,370,724,702,315,174,271,425,912,364,720,338,326,178,518,690,905,743,236,445,212,648,552,994,206,711,967,890,683,203,202,74,578,130,533,113,147,938,667,708,258,951,778,860,587,879,820,245,141,919,859,844,597,559,154,584,760,856,811,963,227,963,860,652,204,508,877,669,542,750,904,650,967,269,116,633,499,272,386,985,975,506,371,763,889,759,556,164,185,222,472,93,88,666,32,406,620,121,573,355,256,125,318,610,505,733,736,379,91,290,877,151,955,320,320,882,227,833,235,760,529,340,604,863,522,211,446,979,987,135,240,58,945,575,548,945,616,525,448,182,587,265,126,878,123,51,508,959,167,372,859,42,810,404,756,272,68,325,751,44,460,944,95,119,2,181,321,711,253,618,237,519,9,88,145,324,526,128,644,810,869,515,473,879,330,629,947,54,56,785,655,463,391,696,287,303,156,878,742,511,812,746,479,368,415,560,817,515,861,12,779,630,889,937,999,320,491,67,833,447,656,560,705,829,224,922,408,879,427,242,424,968,129,210,323,264,298,920,704,846,213,60,130,952,489,141,652,284,985,947,145,626,955,583,628,719,875,455,372,987,573,827,233,559,290,197,404,25,248,683,308,876,54,104,87,397,737,60,465,791,20,484,830,912,249,265,710,756,529,135,367,624,278,55,712,192,63,519,471,701,367,763,322,273,643,882,62,986,666,772,77,336,752,9,591,831,652,891,514,979,688,114,609,551,7,290,919,922,456,738,845,258,676,153,243,209,856,943,720,294,166,450,918,15,661,118,447,746,881,927,690,358,347,951,466,810,484,899,252,420,217,55,472,158,142,265,582,531,556,691,979,841,22,373,950,627,518,259,290,102,389,264,700,875,501,505,355,214,958,139,130,313,413,687,949,647,192,610,357,873,87,293,886,932,467,540,209,672,393,372,649,475,26,530,43,970,398,36,443,453,77,298,839,938,769,111,724,55,288,253,860,147,101,429,597,408,980,481,364,679,469,724,644,831,592,517,109,818,956,524,776,407,353,483,242,46,704,311,840,425,192,795,490,407,820,273,54,135,505,259,881,197,369,564,277,196,752,845,145,956,154,571,661,224,859,507,456,408,172,546,684,622,868,194,333,545,77,764,865,150,33,487,672,649,621,408,979,278,558,545,454,499,85,625,90,542,853,141,709,246,119,446,848,194,57,467,364,279,925,673,183,596,373,20,526,755,816,418,459,976,992,243,555,457,957,779,271,917,467,135,531,659,31,933,701,392,651,902,588,151,109,416,861,966,402,827,706,872,143,770,567,387,669,547,318,632,752,808,1000,349,897,705,601,857,838,789,554", "189,512,785,916,41,694,940,938,121,552,836,866,911,238,828,122,749,871,969,111,264,716,473,388,371,729,388,477,708,184,712,285,150,58,320,46,79,719,467,431,412,61,677,215,433,14,541,237,79,316,790,42,92,794,602,419,33,939,824,122,102,334,252,496,472,317,121,201,437,659,448,746,270,643,167,339,157,90,166,594,501,773,447,781,951,208,102,520,341,147,654,670,548,285,834,483,607,287,531,188,76,682,528,303,882,4,334,808,922,777,962,702,119,176,930,637,742,364,974,257,844,178,436,458,630,564,242,853,885,414,896,207,718,528,855,125,998,958,308,699,130,184,740,241,333,704,137,710,301,156,266,514,939,182,728,172,46,631,893,227,380,341,170,967,920,0,566,463,969,959,505,25,843,751,884,228,681,395,365,984,64,530,538,355,762,602,357,739,601,93,133,676,364,625,218,891,269,627,145,256,638,990,297,210,841,255,42,144,58,531,642,127,813,162,690,152,516,342,457,396,647,564,99,325,332,501,143,546,429,79,280,592,819,675,246,943,368,558,148,85,416,876,142,489,878,752,127,18,463,16,333,60,763,936,892,407,239,605,460,448,936,110,522,107,85,276,779,968,773,128,639,887,680,619,173,678,620,899,565,168,39,670,573,110,44,806,27,878,790,387,6,750,403,629,323,570,432,664,323,6,424,687,720,600,992,657,435,695,957,585,513,94,14,70,119,104,934,810,35,721,97,685,587,820,995,287,399,956,350,639,310,675,824,780,268,591,369,641,374,141,971,984,570,193,748,663,373,993,469,603,890,804,434,351,575,398,839,929,510,724,773,859,863,617,689,355,585,306,756,193,706,580,197,780,678,937,716,837,457,459,61,639,828,687,766,760,691,135,135,250,828,831,736,898,896,534,898,100,54,664,44,142,848,250,659,775,931,79,865,287,295,800,333,911,920,619,152,415,851,152,382,735,110,671,941,437,104,13,80,379,720,701,755,221,103,742,473,836,644,896,428,948,393,6,627,247,218,124,171,979,185,188,521,385,46,201,482,689,166,150,195,499,258,968,353,60,277,658,190,755,821,353,328,679,710,633,690,601,138,592,461,102,420,624,542,931,386,117,115,588,220,661,242,114,153,939,163,439,11,629,980,498,571,760,532,898,432,465,646,696,343,661,578,979,665,194,190,199,919,801,16,158,689,337,788,567,385,188,709,825,43,69,115,430,322,698,533,578,45,567,66,439,57,470,949,525,768,893,246,121,53,152,659,807,206,241,522,12,613,150,464,823,275,815,103,478,365,402,573,601,957,505,125,67,382,981,91,839,704,736,856,870,271,611,533,673,160,640,896,606,968,882,377,233,62,773,405,247,156,387,817,708,804,780,547,287,137,256,498,387,717,837,416,312,295,353,469,903,938,29,942,337,441,346,692,445,590,832,394,226,410,948,664,737,308,954,714,215,391,563,831,365,523,445,995,624,884,600,135,179,279,339,189,318,540,521,4,271,243,17,231,222,953,619,510,750,933,780,145,237,306,399,810,603,823,766,522,110,107,544,837,19,33,478,225,763,508,233,811,106,234,941,465,893,14,401,723,689,49,382,385,795,679,70,627,239,658,944,673,881,218,459,615,166,586,851,551,47,944,256,806,978,336,569,668,394,748,797,805,705,66,952,281,133,910,171,777,533,533,174,560,251,835,145,276,837,773,411,334,547,474,770,570,106,407,454,260,23,252,63,897,613,148,440,767,177,692,552,877,177,601,316,184,158,530,732,280,689,771,43,513,268,71,514,457,795,581,538,743,243,377,148,727,50,81,709,764,843,570,738,782,470,69,378,118,410,370,833,648,772,613,207,279,144,930,27,808,52,395,430,507,142,718,855,180,193,541,531,999,751,562,177,297,253,730,68,65,306,837,824,471,95,155,397,664,393,454,392,883,513,648,535,716,33,579,375,752,984,983,123,700,635,996,604,915,687,50,543,216,663,70,891,370,768,797,174,955,473,44,808,78,410,163,685,525,75,119,224,688,257,662,210,127,215,834,629,829,143,390,108,994,368,83,177,848,156,588,757,363,46,543,747,77,825,280,418,460,851,175,258,962,161,444,491,105,5,422,142,138,683,925,295,607,205,550,56,356,785,599,72,403,217,796,710,691,305,266,174,511,548,128,875,363,443,885,248,153,577,574,143,311,33,517,258,242,479,152,288,941,130,8,331,305,356,515,726,430,103,742,460,606,737,435,492,810,772,811,423,355,272,856,37,234,273,467,927,366,544,116,235", "926,817,923,373,271,607,618,983,831,300,203,371,958,844,597,199,500,815,578,476,48,990,713,677,936,702,439,278,979,641,858,688,739,523,545,522,970,958,222,27,187,195,505,330,177,203,678,299,558,369,718,622,547,11,14,857,897,435,160,444,813,357,687,644,939,456,570,973,427,409,423,790,265,160,658,659,900,787,957,654,981,715,870,118,436,988,791,436,723,709,704,468,861,440,749,978,681,716,15,57,432,417,205,911,215,536,132,327,453,569,379,323,71,305,245,591,502,773,339,642,30,144,817,617,313,957,874,7,266,65,410,470,967,99,468,405,893,915,279,843,897,147,523,336,990,278,461,459,741,820,184,219,577,422,951,207,186,811,928,849,402,267,179,760,614,566,0,576,135,254,969,926,409,386,329,276,349,849,756,294,801,691,618,48,993,177,619,347,526,303,188,150,944,494,436,916,586,389,112,326,358,943,107,342,770,993,679,472,767,629,163,564,729,977,33,127,745,922,628,76,204,370,111,126,129,424,187,285,102,891,129,782,318,493,595,217,690,885,648,243,137,890,731,327,7,397,200,569,580,159,481,201,874,520,280,562,756,329,8,18,655,777,453,944,661,997,493,618,793,341,773,214,578,882,623,832,515,113,143,204,542,948,197,446,76,264,682,339,155,733,225,140,927,701,136,566,903,972,697,905,627,769,622,820,49,269,432,80,496,246,659,449,450,904,402,992,772,993,345,73,887,419,270,27,788,106,848,23,352,418,19,206,147,326,57,237,774,979,558,356,282,593,146,425,717,630,958,476,940,460,603,681,24,695,696,124,799,458,250,254,115,777,337,593,547,752,773,820,873,404,843,636,512,985,244,989,683,671,529,938,91,929,461,201,281,936,967,620,693,62,171,331,749,118,167,46,438,474,819,423,685,91,263,12,496,57,498,739,705,261,732,438,510,233,339,175,936,30,160,854,345,452,482,578,660,914,588,786,336,482,357,46,271,934,854,691,759,69,732,578,421,934,179,945,437,915,382,691,663,989,894,696,225,271,571,405,46,739,300,866,299,267,796,559,434,16,238,977,637,861,40,667,434,92,166,326,642,242,417,905,432,702,423,263,915,689,511,659,320,985,461,214,379,459,628,780,849,296,605,389,688,811,462,171,774,182,657,850,179,782,64,818,257,763,831,884,555,132,792,302,449,45,150,577,869,809,765,126,464,969,488,634,805,944,697,2,769,662,9,874,879,487,525,67,474,340,954,793,138,956,204,55,185,730,311,117,510,732,536,594,254,783,275,877,722,349,656,610,703,71,988,400,56,712,542,785,102,366,673,270,836,787,160,190,118,984,554,654,337,199,302,942,259,237,241,328,12,968,684,933,427,845,619,822,859,147,328,658,741,324,509,221,126,269,259,783,61,72,524,328,757,913,938,804,948,216,141,194,712,582,979,154,20,655,875,578,99,583,532,515,330,998,745,408,84,162,638,324,689,507,987,685,467,166,145,790,233,287,591,892,985,743,107,550,857,753,798,71,870,651,764,280,935,535,712,182,927,170,947,528,48,839,138,506,629,760,419,246,478,183,201,329,909,773,65,663,588,752,844,141,663,194,756,262,53,897,640,944,73,758,481,368,597,990,95,584,632,173,516,81,792,387,985,3,983,461,758,947,671,564,89,945,470,696,589,732,213,31,296,748,785,324,474,110,135,769,221,851,330,170,150,553,187,344,775,907,475,185,963,548,653,83,775,514,729,654,299,897,575,775,41,449,298,708,774,327,171,898,257,634,459,891,584,831,714,36,87,561,262,928,572,563,11,50,235,137,591,788,524,279,361,858,640,787,61,72,180,848,203,926,382,671,806,855,536,232,943,850,488,196,698,655,164,79,860,270,666,694,388,783,963,669,578,543,530,155,667,550,387,427,238,54,455,309,689,322,405,422,627,848,951,882,454,659,326,66,88,624,849,268,883,232,176,218,244,398,604,474,929,288,479,16,437,673,324,339,484,244,728,691,883,479,14,770,12,878,630,364,20,598,509,720,737,956,663,490,284,836,38,586,143,185,874,569,424,401,943,223,363,462,487,802,703,332,37,380,109,93,879,447,690,647,292,964,620,491,476,116,202,913,184,1,546,202,843,61,599,354,759,79,527,928,519,68,274,829,842,780,198,136,604,182,484,852,616,396,662,55,790,71,428,212,13,29,437,62,624,226,530,799,969,539,779,486,745,902,387,650,691,729,643,657,39,833,850,528,616,461,722,605,894,482,47,717,821,83,981,42,173,52", "442,584,240,413,412,736,140,853,447,340,712,982,927,624,754,867,570,958,562,811,38,924,662,157,329,906,16,213,627,90,906,98,861,476,200,660,229,315,179,552,114,6,281,428,910,459,888,512,551,319,948,555,68,869,829,28,838,850,187,446,684,239,298,697,246,55,560,885,17,697,172,90,755,735,419,698,602,383,652,795,917,198,973,549,494,445,603,293,849,515,367,252,677,304,593,20,45,449,526,966,317,757,685,124,398,922,137,769,191,788,931,321,72,399,458,76,193,255,657,859,398,167,257,596,868,511,248,661,644,815,562,216,764,312,555,859,255,52,616,476,882,488,41,979,896,942,95,29,994,900,422,823,482,927,630,292,643,243,185,445,85,34,793,768,201,463,576,0,198,972,269,468,73,915,300,856,200,559,529,524,205,598,208,347,178,66,750,579,729,763,307,223,351,860,945,340,831,765,218,519,570,316,762,428,531,74,877,915,781,290,891,237,538,854,688,545,777,796,548,88,812,410,533,751,473,589,908,719,188,79,179,827,398,330,7,597,400,231,683,422,517,307,512,778,743,148,22,233,749,795,917,754,693,854,933,3,443,809,623,627,581,532,93,674,722,872,476,368,913,265,45,162,946,541,238,972,405,356,701,176,915,278,912,644,301,374,821,147,820,241,856,926,517,477,162,258,200,832,975,388,926,861,702,818,97,330,628,617,462,131,247,576,457,460,229,145,949,411,406,340,215,803,177,253,821,544,827,81,878,917,121,923,187,913,510,627,209,8,300,193,51,673,828,823,873,190,118,341,770,16,932,464,62,754,254,521,501,602,424,587,116,572,889,350,213,799,590,868,580,470,489,465,807,260,700,772,518,207,572,424,298,4,670,998,466,911,976,777,498,958,791,524,13,566,953,483,282,383,775,291,927,383,12,845,678,887,161,586,502,695,29,624,540,768,162,739,438,913,28,407,161,183,60,120,413,872,874,314,164,530,599,852,7,626,833,101,635,230,322,800,936,945,116,351,365,43,652,149,287,286,927,461,921,265,553,240,908,328,640,417,993,317,136,698,926,195,810,381,363,158,502,682,725,203,657,73,168,320,343,885,881,326,604,184,873,291,825,235,114,810,666,952,713,13,752,131,64,36,145,224,872,408,120,953,699,611,661,105,152,505,93,430,69,950,832,677,515,891,747,922,297,356,1000,230,319,463,881,68,546,47,496,562,922,302,324,623,418,867,336,368,192,615,299,127,115,931,733,860,347,209,874,220,440,87,219,380,179,972,948,746,257,969,390,123,917,443,462,89,284,907,572,143,81,25,37,432,876,291,521,142,554,254,515,21,388,618,842,664,830,818,930,631,358,30,447,746,202,200,323,675,37,917,462,76,2,454,476,875,569,196,794,626,678,383,894,898,685,958,260,355,55,637,710,402,626,231,491,437,960,108,148,253,366,365,737,104,536,124,718,793,319,680,533,631,831,570,594,3,351,14,851,752,297,91,868,948,265,787,645,742,795,686,8,303,869,915,887,449,438,440,289,775,796,116,787,558,886,160,321,325,464,795,381,48,13,808,583,998,399,862,734,823,753,156,169,427,820,137,506,975,382,702,918,943,155,175,266,269,125,144,656,593,474,722,442,680,970,899,421,854,845,419,458,270,566,682,40,247,279,255,764,533,18,620,995,127,304,471,593,730,513,931,916,947,937,155,50,314,755,262,451,742,928,487,71,696,75,567,259,686,220,563,59,101,973,466,772,577,433,342,336,982,389,784,930,719,661,331,496,953,354,302,473,124,56,356,14,946,815,351,650,444,275,767,690,414,209,762,757,671,235,74,324,290,363,177,521,801,673,273,939,144,880,515,737,206,731,694,999,966,292,86,695,969,742,307,526,929,984,18,22,655,315,570,398,954,968,591,481,170,801,392,492,48,674,255,777,237,595,725,376,411,275,543,161,496,428,924,918,193,718,80,81,176,173,483,505,730,803,507,189,214,175,798,453,974,92,608,408,733,389,808,932,99,485,864,637,123,211,544,133,944,163,410,919,771,242,421,820,610,731,741,826,965,898,823,127,983,170,585,76,395,879,264,38,659,865,880,157,598,886,367,988,532,434,598,718,920,505,930,168,897,438,672,244,837,683,228,801,860,229,606,221,524,93,738,878,178,696,281,990,813,845,593,312,523,397,464,286,290,693,56,968,192,325,717,195,26,834,753,934,66,644,200,127,149,292,848,308,638,263,715,953,432,420,952,257,583,936,938,191,22,1000,445,975,866,58,831,392,392", "465,872,390,642,854,713,760,129,54,275,257,618,471,344,817,262,703,754,77,985,335,530,326,318,666,600,15,435,280,637,65,407,406,507,90,303,928,57,227,865,433,895,109,608,110,250,803,992,220,3,194,125,413,107,554,198,457,323,770,408,227,873,174,154,334,538,745,993,8,441,923,345,497,289,910,763,903,820,88,548,647,361,550,370,317,54,693,321,142,194,905,234,300,455,680,973,971,725,177,153,151,437,112,501,309,37,330,987,417,548,373,573,848,155,547,35,452,411,459,933,196,393,639,812,382,775,193,6,648,470,153,105,277,18,954,437,156,164,556,985,922,272,381,566,65,233,195,719,915,545,710,918,995,706,957,758,123,572,128,304,475,787,801,517,389,969,135,198,0,64,153,270,883,818,408,696,590,317,834,745,465,29,91,346,233,87,47,641,88,890,730,292,536,840,421,646,362,133,50,341,346,470,304,989,60,55,924,859,528,341,237,530,106,495,358,598,370,722,813,710,594,179,805,50,540,372,622,797,296,306,544,62,920,823,783,895,149,815,211,783,27,499,777,951,826,848,161,738,722,501,354,685,700,34,561,764,273,313,301,26,651,364,121,624,480,607,972,199,282,955,778,358,583,891,385,319,548,854,90,533,800,480,701,49,431,76,622,15,11,786,966,227,905,701,113,110,474,67,978,397,642,507,789,139,533,546,76,507,899,707,906,447,638,12,812,618,752,639,740,262,133,158,374,798,532,555,542,80,494,616,18,627,396,454,913,473,952,655,159,211,928,925,294,215,748,991,320,562,608,869,656,270,216,793,14,366,576,456,303,990,19,97,476,454,554,499,601,635,317,430,683,18,88,484,558,773,658,282,483,82,272,794,986,99,40,30,121,922,276,833,638,99,459,274,148,983,758,5,937,687,399,750,281,100,982,106,637,894,344,221,179,528,766,347,629,244,490,572,453,629,921,761,293,619,702,636,573,33,501,995,220,698,114,423,964,151,387,432,14,161,109,471,670,910,79,654,323,880,993,17,670,62,695,349,591,908,635,850,798,239,634,704,874,699,122,546,380,906,709,984,461,296,822,595,778,531,395,680,64,356,115,335,377,502,674,206,901,638,556,393,622,674,552,432,781,693,963,704,117,156,692,280,420,149,408,694,838,386,893,683,186,509,484,636,840,580,811,458,152,156,411,863,12,870,507,506,823,645,305,290,448,542,175,769,291,504,530,10,737,875,720,960,156,820,980,80,244,100,726,286,634,224,809,752,581,280,973,461,761,586,696,839,109,417,995,424,307,913,412,142,236,447,537,164,395,818,552,709,493,450,903,211,788,56,499,344,121,790,436,223,430,873,1000,352,637,883,134,408,544,466,76,364,23,895,104,106,719,226,88,984,920,920,235,149,934,344,793,370,887,580,263,8,328,295,885,767,453,949,233,547,544,663,474,973,656,450,845,150,897,366,496,132,429,747,265,258,22,899,786,242,190,357,458,582,58,63,634,957,831,59,523,564,287,390,889,277,145,616,45,443,131,393,622,913,942,355,348,687,501,139,318,347,830,203,505,163,182,585,275,608,260,281,924,304,880,146,977,694,72,895,642,794,216,298,855,156,351,118,683,458,175,281,187,855,126,614,645,394,300,254,69,74,340,955,423,204,457,694,448,345,400,688,90,972,18,967,800,884,638,562,229,230,615,279,180,24,994,485,372,636,999,825,320,253,482,868,216,410,423,770,551,723,899,962,545,971,43,630,520,425,207,865,641,888,790,26,479,857,808,516,130,870,500,103,631,98,33,535,698,737,807,904,531,180,630,440,5,573,282,14,355,564,83,264,186,828,907,842,970,491,273,403,950,394,263,896,889,312,985,275,825,250,508,298,878,938,927,219,727,971,916,964,111,618,111,257,789,715,600,324,351,448,477,67,103,997,490,45,630,552,662,742,812,179,353,458,61,339,798,678,505,109,447,785,661,124,286,66,318,253,84,120,977,605,628,428,146,850,153,476,740,320,230,236,146,225,551,558,107,850,538,589,215,246,23,804,575,337,864,445,956,728,245,744,495,745,396,527,105,443,206,250,176,6,299,519,997,82,177,15,998,318,590,226,610,471,405,632,258,701,916,926,321,545,441,14,633,871,448,286,423,279,881,463,173,833,958,673,98,512,245,155,633,850,602,917,920,367,248,335,448,869,345,117,253,918,331,407,498,514,920,656,368,99,820,218,443,653,847,443,634,484,733,338,882,880,387,400,622,588,684,226,939,804,635,577,643,983,788,409", "225,221,636,157,961,371,427,116,76,986,866,354,818,283,721,296,271,652,279,132,333,124,509,482,348,679,217,600,645,653,813,710,895,247,84,37,217,675,619,545,472,414,478,139,848,873,649,876,544,254,636,298,952,94,981,297,177,102,720,586,268,901,552,878,184,541,388,241,11,513,94,252,463,840,599,836,845,60,120,316,614,816,144,725,457,307,949,431,957,925,883,918,215,573,592,291,849,119,68,708,962,659,117,232,755,919,283,433,378,718,570,353,524,32,872,893,107,215,21,630,35,638,173,187,594,769,242,199,299,739,696,31,836,554,703,871,938,208,759,734,10,324,831,331,35,621,892,469,33,348,796,345,318,320,815,825,282,668,907,402,646,923,913,819,800,959,254,972,64,0,327,944,277,707,5,885,775,158,501,181,734,532,787,186,528,83,696,875,230,690,318,45,349,650,211,844,735,173,482,811,370,538,724,17,86,333,116,12,677,847,220,261,373,912,931,506,910,999,621,17,124,729,557,186,224,234,532,427,901,747,138,897,730,129,933,419,741,352,176,202,641,416,259,668,162,377,606,573,87,824,530,282,835,635,654,146,309,218,340,314,522,998,65,2,399,348,437,969,461,839,700,499,247,480,865,771,899,99,885,560,260,893,535,14,622,535,638,909,430,487,662,371,849,27,349,361,151,620,97,732,419,162,95,352,792,434,96,689,542,392,653,774,292,527,10,86,982,331,302,158,383,260,762,253,612,30,875,535,214,296,474,178,973,582,637,817,227,474,730,361,781,428,100,825,523,844,802,60,832,790,51,19,325,995,811,772,13,624,176,269,941,454,967,272,927,863,879,799,230,852,222,233,484,646,341,215,53,707,657,372,255,381,855,900,157,725,690,313,836,937,621,337,961,75,152,797,583,420,931,855,800,685,997,47,598,863,548,72,44,60,903,103,422,212,605,294,591,280,251,21,105,499,730,433,509,579,567,769,144,800,642,889,481,944,636,523,302,670,964,340,501,599,129,86,738,694,775,770,436,886,37,421,138,998,33,385,136,200,981,625,528,857,852,486,321,171,207,62,949,81,515,893,239,708,169,176,26,571,563,796,636,625,7,738,335,700,393,515,445,253,714,722,180,153,32,198,639,200,670,127,245,952,779,289,858,994,303,552,173,839,76,560,702,77,202,188,81,656,938,926,635,575,539,546,807,176,434,9,87,535,644,121,840,690,381,133,697,757,34,710,547,704,25,327,537,653,635,12,708,577,978,494,813,698,149,54,518,514,153,899,527,907,998,577,763,563,902,183,558,966,741,36,449,510,293,527,148,871,64,931,296,280,601,913,964,194,785,666,417,758,134,32,382,914,740,850,879,710,694,114,241,243,321,958,16,126,450,733,973,199,15,327,152,111,636,79,443,498,18,334,623,632,837,562,35,473,26,354,343,526,667,691,685,101,115,171,609,641,194,187,968,157,427,510,23,444,693,388,348,71,935,253,247,377,900,660,811,717,567,884,844,175,238,610,615,605,838,134,680,589,504,998,762,580,796,194,388,278,54,198,491,470,902,729,235,788,491,478,579,161,175,443,162,177,368,344,508,949,968,647,266,338,141,69,144,670,45,932,455,124,678,712,380,145,179,966,928,211,856,170,760,846,513,322,789,978,10,47,965,759,802,551,977,841,23,980,926,210,64,215,182,150,989,789,668,85,379,869,775,383,646,569,340,358,528,762,575,903,180,482,573,568,368,350,533,165,66,494,129,493,610,41,599,410,200,252,58,681,530,599,578,255,611,56,519,571,610,379,391,493,989,664,216,342,580,220,632,299,919,943,272,877,393,729,378,684,903,70,32,79,972,756,761,664,793,405,196,763,534,587,40,317,131,675,747,985,699,57,526,665,138,55,648,250,466,932,658,28,333,242,145,662,576,887,121,325,384,115,171,3,928,816,493,553,615,74,331,412,941,848,442,741,21,275,327,166,523,892,793,265,711,555,788,697,678,96,939,604,144,892,643,152,713,989,572,827,316,799,681,635,6,623,537,272,265,781,474,67,159,449,810,178,880,99,84,982,739,893,144,433,160,727,760,533,10,362,170,335,977,74,100,538,536,109,401,874,950,946,425,913,164,698,234,500,14,35,700,422,120,606,460,959,171,506,201,90,961,556,73,153,467,563,239,534,328,724,104,815,13,662,910,760,519,354,46,441,36,252,504,374,907,989,450,804,234,548,325,366,828,453,777,30,106,929,526,301,871,676,483,183,846,11,915,79,793,679,401,525,907,532", "573,184,534,212,528,559,228,868,45,223,581,97,648,813,957,754,59,816,84,844,148,358,370,881,667,643,974,339,784,291,283,949,234,765,161,222,238,583,442,106,868,687,337,653,188,932,94,89,269,767,354,460,730,525,945,203,686,762,510,901,595,691,78,141,928,309,323,813,488,308,129,969,683,682,29,196,693,437,920,496,41,373,260,396,813,806,118,646,270,961,106,816,64,674,556,34,437,917,716,346,87,301,119,360,575,791,581,936,32,462,160,547,275,945,53,857,473,512,234,384,576,964,831,606,472,915,810,269,977,834,205,972,310,874,598,230,209,26,164,829,341,57,641,809,733,649,296,894,743,527,183,968,888,542,939,767,914,371,435,264,818,527,629,224,48,505,969,269,153,327,0,66,476,45,857,582,690,849,521,462,606,892,259,528,798,798,616,896,539,468,777,173,756,839,328,633,276,50,788,441,277,215,288,947,849,443,643,360,867,305,348,239,527,508,548,553,399,319,719,805,20,766,835,536,395,55,101,776,98,926,23,64,704,624,350,265,659,546,608,975,181,255,461,775,549,694,427,65,475,162,844,666,802,468,793,214,449,119,588,174,562,835,158,660,688,73,187,489,114,216,832,184,637,195,706,989,987,61,60,204,666,201,589,273,592,569,598,570,57,680,891,618,324,993,972,574,689,200,762,143,859,552,456,53,168,258,677,28,884,716,157,716,350,708,539,68,683,561,476,576,146,427,617,722,572,873,155,892,464,328,33,162,700,591,967,872,554,830,776,168,655,350,88,84,941,869,825,803,56,757,656,364,132,229,345,764,155,57,76,635,95,744,676,290,166,18,527,938,405,702,140,522,818,679,34,342,354,539,377,13,443,201,582,883,865,736,729,638,930,791,109,447,227,580,134,807,555,272,264,95,968,294,697,426,224,344,376,31,349,371,568,590,375,713,197,486,827,393,748,82,500,431,58,922,240,706,78,856,903,50,630,102,987,132,744,418,528,718,381,99,12,398,750,357,274,484,376,101,431,498,215,155,933,700,517,785,9,792,536,124,761,722,173,904,194,805,438,495,695,176,617,783,141,334,493,850,901,798,953,817,44,831,782,492,430,319,878,61,529,390,457,186,34,659,989,290,123,828,425,729,521,348,989,512,953,566,151,701,727,505,417,787,526,515,453,325,788,756,586,58,773,843,339,100,248,489,914,589,190,715,64,707,334,612,958,856,134,398,651,962,658,332,723,631,605,10,896,66,826,410,177,791,244,746,766,265,945,686,449,362,503,450,939,117,592,32,88,320,498,461,523,588,26,789,648,518,279,655,965,243,641,537,153,935,151,48,529,798,446,219,968,195,609,702,569,74,542,627,1000,979,604,227,547,240,998,330,617,298,91,937,101,3,278,169,403,208,833,409,740,901,330,165,692,149,950,991,546,476,416,136,869,513,221,150,287,231,319,90,788,447,223,190,574,972,380,574,664,170,212,204,938,67,184,817,336,75,964,689,296,853,503,516,60,995,28,416,629,610,802,369,424,453,583,230,781,209,222,614,76,365,719,823,110,106,437,569,982,916,275,603,841,127,910,359,321,367,898,788,662,513,705,910,335,765,337,579,592,250,604,942,55,905,920,117,44,487,99,950,173,691,598,697,508,603,836,750,648,652,202,966,963,860,701,752,187,540,826,184,623,439,733,853,472,559,142,204,102,435,32,721,448,274,727,698,297,459,613,142,317,274,416,615,298,819,463,910,362,333,805,673,572,915,81,952,586,374,196,773,7,984,198,237,857,823,844,857,319,202,429,319,324,286,57,493,554,77,372,231,341,635,359,616,543,748,999,773,291,285,737,660,502,697,899,781,736,166,266,222,767,974,445,800,680,835,263,352,606,976,826,978,19,444,643,207,820,873,708,519,127,72,804,13,486,790,947,349,785,700,919,99,694,784,801,22,69,556,226,358,415,617,745,992,578,299,780,441,822,438,590,251,128,984,908,58,7,929,97,482,744,352,632,981,572,494,117,390,708,607,79,379,992,521,586,343,549,447,565,925,867,527,968,301,213,249,768,646,860,503,195,378,161,45,107,941,318,826,701,864,175,416,882,426,186,846,83,966,150,70,817,537,651,68,659,378,751,67,851,212,336,727,636,771,54,804,63,175,602,276,615,114,848,597,192,581,326,62,742,139,85,34,949,377,216,848,924,888,145,935,96,53,925,192,447,949,351,826,572,386,7,908,142,695,427,134,193,24,274,277,88,262,401,788,851,502,581,831,595,201,330,155", "379,321,846,366,724,476,771,436,195,626,518,473,640,60,126,34,350,936,595,395,608,928,814,164,346,976,171,173,743,579,773,305,275,617,275,413,856,153,22,766,402,987,629,119,661,820,961,160,290,798,817,24,897,732,545,109,933,987,373,837,387,97,419,711,343,465,461,322,851,343,625,326,7,339,999,333,622,423,123,292,903,132,255,173,536,277,283,962,509,725,915,680,505,52,510,517,250,430,360,127,964,8,669,195,454,348,615,61,217,940,245,659,910,326,987,859,839,31,238,283,494,890,885,992,226,10,247,628,805,894,341,755,892,720,30,967,272,734,716,350,450,474,815,437,562,220,960,808,909,180,578,771,110,412,334,590,507,541,536,488,171,155,503,238,367,25,926,468,270,944,66,0,868,730,795,927,8,596,499,172,956,394,154,879,320,684,928,300,392,588,431,717,342,392,317,217,540,79,953,285,552,834,662,402,705,317,563,923,428,441,817,474,838,927,401,513,938,845,500,833,559,785,675,783,964,446,456,283,960,615,507,463,157,694,255,514,393,708,764,771,541,873,89,154,649,345,892,38,745,20,730,433,928,455,390,212,151,57,237,739,614,369,200,186,255,549,186,481,93,83,831,48,888,95,330,286,326,288,10,134,489,813,454,52,132,544,551,164,507,326,678,964,114,816,214,345,856,205,281,368,536,643,416,366,692,427,679,199,521,348,503,243,936,572,432,586,497,712,10,724,169,426,3,183,374,169,74,75,559,941,580,375,66,377,166,954,190,954,82,918,167,640,893,232,604,95,737,751,695,143,29,841,298,309,355,84,264,386,748,764,281,310,112,58,134,252,30,275,328,198,449,113,995,821,266,272,419,754,899,815,59,911,502,595,79,392,139,933,730,627,780,375,233,760,3,263,772,891,628,346,658,695,542,993,656,385,844,880,642,601,115,945,701,494,467,41,760,663,980,627,509,923,440,593,492,485,731,317,34,739,993,573,408,302,80,46,304,229,156,638,462,282,308,943,300,831,162,720,142,937,603,985,462,871,144,759,134,815,103,819,867,52,590,87,727,437,226,476,479,83,956,366,684,474,207,255,211,986,889,811,692,621,667,505,358,370,859,772,192,531,76,406,781,404,824,849,59,645,8,327,776,926,417,912,373,754,318,401,887,615,26,799,193,782,253,553,839,991,158,504,861,419,198,427,359,909,118,833,496,857,59,176,699,112,293,187,572,752,813,925,579,949,816,882,42,831,720,994,319,325,797,713,605,13,868,360,575,481,176,750,506,661,973,108,984,287,778,615,168,391,412,683,848,594,902,68,392,606,419,705,554,279,739,515,916,720,531,86,426,568,161,295,77,960,840,417,722,239,670,863,55,812,317,626,174,382,249,910,518,488,299,778,523,982,142,416,999,879,418,406,186,211,97,670,492,987,879,373,261,181,435,849,129,870,778,60,221,641,3,914,930,308,679,234,827,760,886,203,348,676,896,848,82,586,894,386,327,704,846,897,266,900,43,221,172,386,134,250,713,234,522,223,671,696,109,559,506,554,180,189,494,233,622,578,725,781,594,754,79,531,87,25,118,251,463,592,541,916,589,715,333,88,981,692,46,121,529,620,759,746,57,199,831,44,711,35,587,853,68,556,131,206,770,780,276,500,15,202,843,603,343,429,852,236,244,638,705,430,573,537,561,985,433,899,425,913,136,619,589,401,558,374,777,10,483,937,21,58,223,505,719,758,964,640,449,946,432,344,285,566,626,424,102,881,211,427,191,29,970,23,688,200,28,402,900,351,932,678,397,855,618,268,385,883,41,854,151,930,907,186,900,611,248,757,723,487,181,844,445,883,695,826,30,217,486,307,396,556,293,18,36,114,306,302,727,896,778,271,232,379,918,154,545,392,759,799,861,177,998,105,424,471,835,898,303,306,205,363,925,211,195,826,900,681,247,764,819,313,885,47,677,929,163,649,433,304,482,74,540,955,654,187,911,883,452,764,244,349,924,874,612,910,423,929,740,996,336,632,588,227,902,813,178,571,800,184,279,658,335,945,421,346,400,345,939,563,870,904,112,558,312,596,673,154,943,970,248,334,945,766,65,760,871,328,319,597,21,43,816,896,267,356,846,392,215,105,453,743,160,12,61,189,849,207,56,399,179,430,597,332,397,294,580,845,715,629,235,909,789,406,947,272,788,856,209,43,657,384,87,348,373,367,89,111,393,593,122,359,845,273,685,241,186,408,387,915,66,387,812,510,386,113,103,370,775,163,188,678,667,563", "875,218,415,680,947,446,698,86,375,801,280,293,460,483,819,214,252,572,910,73,777,739,427,395,848,756,282,84,492,372,790,879,341,360,425,70,491,511,728,862,445,847,322,126,929,282,20,518,976,511,614,192,592,226,569,795,504,653,629,837,453,783,117,822,179,466,635,290,841,659,414,761,43,198,634,664,630,552,876,342,831,691,889,354,320,761,425,40,404,271,953,363,759,64,381,652,923,578,732,813,171,996,321,536,811,481,196,309,812,930,297,853,687,777,543,667,561,580,482,771,833,248,51,903,718,230,578,269,454,627,827,823,114,557,179,990,328,929,584,86,974,369,301,979,859,447,917,590,423,164,107,782,188,786,339,292,972,301,526,940,542,245,538,489,610,843,409,73,883,277,476,868,0,108,957,740,669,187,756,453,31,960,430,395,450,904,544,449,798,124,387,703,670,50,540,395,935,518,948,253,683,608,231,950,586,650,16,962,82,59,757,586,11,842,119,91,160,599,566,758,904,401,264,220,809,626,801,414,195,272,993,968,226,784,53,325,337,846,969,783,994,160,484,430,40,9,924,487,633,732,796,512,929,44,76,146,436,190,356,691,466,339,602,946,126,279,146,228,455,374,170,165,159,220,429,115,276,449,528,978,508,529,309,188,90,208,846,352,586,997,931,410,258,624,170,123,205,518,212,977,632,171,864,603,66,382,762,111,532,609,535,741,602,635,866,500,544,14,201,284,832,656,669,397,268,977,679,273,756,695,460,335,62,578,987,337,254,605,277,550,625,449,266,592,58,73,696,75,228,710,772,445,365,993,733,85,240,318,337,149,589,376,115,593,109,285,890,297,457,38,636,766,202,579,447,125,466,498,101,336,239,367,192,219,300,163,643,379,774,370,107,786,17,258,35,87,760,595,719,319,506,691,570,14,358,930,117,2,304,853,432,373,192,241,219,307,515,37,176,237,68,860,795,886,577,103,563,3,773,326,870,138,973,355,724,627,4,939,784,645,89,66,40,181,249,671,941,972,850,73,496,849,296,585,811,486,297,875,26,101,389,678,669,416,139,660,347,767,687,561,11,363,223,489,624,639,817,705,59,189,174,43,358,611,860,652,870,681,45,884,515,7,471,14,810,319,95,616,291,385,448,798,406,538,981,785,692,842,676,662,94,365,494,508,695,449,640,718,630,81,798,39,80,453,334,953,252,532,525,902,563,54,857,671,722,511,594,861,83,467,88,324,268,79,278,764,295,68,20,14,396,260,2,936,244,76,349,953,947,340,589,98,800,53,45,724,865,611,697,660,754,646,357,499,230,95,850,258,335,268,205,331,35,764,963,179,39,98,885,456,622,217,254,160,222,447,976,968,965,240,634,422,320,822,882,783,133,467,642,561,266,278,440,326,371,963,374,314,376,23,803,636,695,917,912,612,67,527,351,926,524,370,321,106,275,851,604,886,957,229,427,766,638,825,655,298,35,749,268,381,455,816,841,603,327,737,974,5,901,855,135,213,998,137,371,665,571,762,253,967,401,432,532,752,92,375,226,103,748,496,560,862,263,304,15,861,815,876,622,782,428,441,627,737,792,669,198,994,402,47,723,76,534,440,22,931,446,916,649,913,458,735,942,151,303,856,191,619,22,705,175,838,971,723,274,100,301,709,355,514,383,681,551,469,499,760,251,485,862,903,352,31,14,485,235,359,544,863,130,651,102,501,745,201,35,901,804,405,776,222,156,15,882,131,762,299,498,698,418,176,590,769,329,491,276,723,947,651,893,440,160,95,884,921,515,172,531,574,939,410,930,998,177,603,105,244,994,214,864,368,590,248,356,376,98,887,656,564,185,215,286,431,36,307,348,805,594,947,714,44,251,848,329,450,216,644,846,28,993,320,103,575,326,146,563,705,984,753,378,557,592,124,542,508,100,857,127,137,244,634,113,443,387,182,332,664,954,805,431,352,945,993,780,187,104,56,84,213,247,724,28,695,575,636,721,529,280,652,504,181,763,234,621,52,895,534,158,619,983,340,422,765,77,38,114,766,904,124,994,596,369,302,56,180,655,65,382,864,556,870,643,698,79,950,246,794,317,60,799,165,492,73,791,235,656,87,537,644,837,744,167,319,466,632,416,296,855,961,956,398,110,417,864,741,44,90,897,136,173,534,244,154,599,464,972,870,120,443,577,991,704,517,20,743,163,688,505,751,356,486,774,485,646,496,496,11,784,439,392,346,650,523,802,894,900,191,19,414,274,551,608,226,648,571,535,374,530,385,726,142", "620,878,993,482,269,7,371,47,94,650,188,594,869,650,14,761,457,906,152,166,620,599,285,114,341,804,547,322,285,187,542,395,559,750,553,667,154,70,918,266,154,627,600,830,533,884,760,446,111,921,390,11,480,811,437,960,114,104,818,345,75,815,431,924,406,107,561,181,172,339,766,986,328,117,231,396,504,707,969,717,335,25,698,749,540,218,262,18,699,227,990,365,541,692,855,671,612,755,973,633,232,602,97,464,739,449,921,996,523,834,117,485,665,510,495,324,159,906,490,431,368,915,938,95,533,810,795,174,553,929,15,82,40,159,880,8,968,54,916,65,359,747,225,917,614,809,928,477,786,684,21,333,75,536,716,457,81,163,919,858,993,340,884,864,540,751,386,915,818,707,45,730,108,0,606,86,267,114,287,422,638,408,943,716,720,780,503,332,618,67,726,134,612,462,671,213,702,996,636,963,75,131,666,455,255,600,753,663,332,306,912,768,979,444,446,948,818,119,158,186,400,301,354,196,146,12,697,178,154,681,937,261,296,179,372,522,643,597,67,246,529,775,727,180,760,958,57,486,103,986,64,930,650,277,824,609,731,62,675,273,274,791,750,710,431,721,572,791,865,14,963,481,349,271,139,752,974,737,385,254,422,227,40,969,140,592,374,28,259,656,857,428,202,112,423,441,127,756,38,944,722,7,98,468,716,643,262,567,991,810,739,339,773,980,150,557,677,208,62,253,168,724,361,356,195,536,897,191,931,41,321,702,764,851,804,870,823,408,82,451,689,957,779,114,929,917,559,192,404,734,472,35,521,79,938,254,974,302,454,683,682,468,546,760,423,186,248,401,155,857,987,47,161,527,773,164,700,323,550,829,107,925,521,7,603,530,204,467,994,509,566,979,159,34,684,493,922,154,636,570,712,784,105,779,223,44,945,528,205,921,94,867,113,491,185,697,554,376,712,826,136,13,940,143,52,267,34,321,565,729,173,800,406,956,697,786,155,894,841,381,446,536,791,713,842,805,311,671,953,418,780,720,901,79,64,177,253,140,251,739,89,89,344,96,334,828,625,839,725,43,65,438,229,147,291,928,465,33,212,794,623,969,812,908,15,28,904,931,891,13,384,470,751,223,431,33,833,745,347,153,313,292,321,975,548,996,192,513,123,633,986,506,67,560,865,832,723,240,350,739,654,285,661,204,216,155,37,884,210,671,576,636,503,69,815,377,739,866,625,998,578,965,875,831,871,139,352,499,373,671,301,973,546,168,323,445,417,65,769,570,324,204,696,388,845,418,878,608,672,29,410,776,524,491,570,359,258,333,618,635,825,477,472,75,505,599,306,97,923,331,465,556,448,400,508,515,100,888,110,876,15,682,428,961,572,901,894,589,390,438,212,4,878,746,52,399,192,777,434,59,815,708,210,417,783,733,443,661,989,244,938,847,944,647,908,665,236,534,370,871,943,222,941,340,994,109,903,60,903,639,386,280,417,838,684,527,210,956,534,339,428,934,432,394,710,509,51,708,893,62,882,564,668,57,571,653,566,249,146,536,251,142,98,234,128,443,766,448,389,383,481,594,983,308,524,107,703,147,308,369,97,150,152,382,739,724,249,177,232,445,590,951,514,786,688,8,415,419,283,798,885,678,736,849,485,474,494,825,271,163,534,874,547,181,822,155,929,238,622,243,295,567,329,185,615,380,751,973,633,385,279,316,510,818,987,483,60,322,376,152,977,528,582,579,100,146,148,426,864,23,659,239,301,479,528,470,503,417,479,745,721,432,744,880,809,604,594,628,21,548,149,991,234,984,129,208,578,568,214,998,72,394,610,78,476,57,688,261,984,438,525,423,807,773,390,123,107,779,1,734,639,669,402,652,893,705,342,154,261,667,737,708,371,355,509,753,291,262,165,613,201,186,284,857,976,588,786,623,431,386,157,128,625,474,763,212,168,73,246,132,506,828,293,627,401,634,42,49,622,206,934,698,918,894,20,620,60,565,384,624,746,225,601,524,616,395,613,307,360,842,891,189,112,697,622,142,594,974,354,282,793,959,816,894,23,988,24,353,981,391,391,556,309,196,80,700,414,136,547,794,446,565,469,625,409,94,749,112,183,956,121,126,25,503,809,309,961,747,599,909,853,854,653,255,196,981,168,584,694,319,542,421,922,654,255,514,969,432,439,551,312,983,487,14,276,820,954,2,185,104,767,892,460,479,914,852,97,234,854,509,753,460,337,385,816,900,329,295,40,683,684,980,129,275,306,228,273,599,302,996", "294,919,977,876,7,431,882,806,57,714,924,643,473,935,573,210,638,641,289,162,336,903,808,98,194,197,884,623,95,731,531,559,265,390,718,818,195,350,31,806,769,323,4,688,116,361,979,556,624,902,967,352,212,34,385,305,179,14,486,101,798,688,227,27,330,16,989,111,628,349,300,823,504,497,39,258,753,847,514,345,842,38,886,744,729,97,900,32,395,231,589,636,220,373,322,255,610,914,439,553,860,776,803,6,893,16,304,474,151,211,937,675,639,856,660,347,890,791,619,281,541,746,303,511,557,227,214,481,243,588,690,34,554,733,804,107,561,935,381,481,230,643,476,320,875,874,256,140,362,541,290,269,493,657,558,650,3,9,479,679,272,768,480,363,845,884,329,300,408,5,857,795,957,606,0,963,612,518,99,450,661,446,272,803,836,863,715,373,354,651,541,911,200,50,139,219,949,793,659,849,760,444,78,424,966,877,47,244,459,626,612,551,655,357,329,308,835,520,527,865,604,588,980,659,375,143,38,315,363,251,182,364,835,187,673,148,753,370,926,653,809,374,361,754,210,876,265,697,788,713,303,138,207,744,88,347,700,583,448,996,999,739,747,907,610,350,317,50,930,241,374,583,602,915,409,15,744,143,818,523,98,383,472,518,304,578,5,363,102,648,892,832,734,707,496,218,995,625,395,986,930,128,328,543,106,979,621,843,464,276,938,632,906,266,422,204,378,172,535,622,919,20,432,960,678,41,438,217,266,925,53,962,486,986,654,88,191,696,209,590,899,680,518,502,579,317,105,322,320,79,195,269,62,65,786,559,633,633,65,630,704,971,165,439,460,617,538,39,140,577,96,101,330,581,516,2,958,242,846,264,129,179,129,728,306,956,604,93,42,929,443,124,529,443,273,54,291,121,168,190,28,191,539,950,523,960,372,777,410,703,194,409,282,950,96,636,115,336,616,280,697,705,135,909,922,815,814,135,952,403,27,310,98,316,524,299,97,254,711,229,271,764,860,786,564,796,315,259,897,151,510,494,892,981,822,295,381,670,822,73,349,378,146,923,138,216,197,615,205,863,862,95,744,552,148,371,147,252,361,369,960,723,94,636,341,431,25,855,884,799,634,820,29,333,358,547,784,925,489,873,872,394,697,805,522,334,802,422,419,547,337,621,968,448,396,514,572,409,92,123,737,930,84,753,108,975,157,293,370,713,737,135,827,328,378,885,930,788,811,721,960,551,792,253,397,911,67,992,55,771,922,450,543,364,602,33,566,157,526,41,764,586,24,167,756,966,296,622,517,135,226,567,23,2,922,597,523,394,21,47,390,54,802,507,584,933,873,830,725,448,637,244,145,918,774,412,616,164,913,119,584,887,321,15,54,342,482,302,415,543,122,439,322,45,142,473,415,596,2,468,366,626,903,967,47,69,917,120,148,299,15,645,739,9,223,743,619,818,432,642,615,221,901,398,364,976,859,164,82,580,62,29,967,360,509,408,144,611,772,435,235,143,335,491,631,170,401,747,399,792,293,570,274,523,662,433,686,314,955,756,919,692,409,983,5,794,880,847,52,118,92,948,344,538,88,515,590,291,623,112,964,431,665,290,952,990,950,818,338,315,546,408,104,153,788,579,117,71,250,218,561,191,730,464,997,121,335,253,485,194,565,676,103,940,590,198,759,647,866,647,696,956,343,893,231,112,171,103,535,252,323,885,437,714,644,904,853,655,308,707,894,344,258,44,643,803,927,275,858,381,114,595,313,673,34,45,82,74,257,465,724,814,773,254,485,601,30,88,60,239,135,857,943,45,129,752,752,497,280,94,897,990,10,599,439,896,880,122,306,353,149,695,834,541,757,121,572,518,310,737,488,512,355,639,164,406,765,397,882,881,221,634,421,346,881,416,91,264,808,962,38,273,819,839,644,141,479,223,236,505,506,495,84,850,427,778,122,269,586,464,361,565,349,811,594,886,205,772,468,204,758,263,62,428,523,697,152,809,297,557,872,931,337,583,861,411,859,501,797,650,111,398,839,362,375,281,132,52,289,294,883,198,179,659,951,871,759,715,220,129,654,195,762,269,369,102,295,868,827,503,293,657,450,201,948,219,218,64,704,639,426,292,643,396,60,366,986,146,839,7,572,551,532,679,835,7,328,535,550,131,737,716,861,359,404,560,939,183,630,850,653,120,652,215,266,760,106,404,408,397,848,515,613,295,10,890,231,113,719,658,419,888,202,746,318,40,98,68,868,30,73,320,637,272,167,891,380,755,554,683", "452,841,910,431,530,981,533,981,589,197,223,262,588,200,342,141,43,438,681,661,460,259,288,131,702,361,937,22,268,514,670,648,618,580,317,330,193,320,479,575,95,243,364,377,307,649,643,430,591,641,624,743,407,78,431,689,342,310,526,284,379,208,306,944,844,847,519,738,747,780,587,492,69,247,226,778,430,782,764,14,920,545,101,793,849,300,834,155,309,834,641,376,321,340,424,726,378,469,983,509,800,655,322,220,866,695,46,901,880,535,274,373,851,173,280,824,947,956,566,360,463,971,626,926,27,358,789,429,671,74,698,816,443,101,293,620,640,756,598,673,587,448,690,112,665,910,942,281,897,841,868,754,537,428,882,989,740,868,103,724,9,390,439,496,948,228,276,856,696,885,582,927,740,86,963,0,961,630,883,31,969,86,135,935,702,387,391,546,350,216,393,539,77,940,899,825,922,791,339,39,323,829,548,333,79,690,366,906,537,783,386,530,169,910,178,615,199,658,645,118,881,422,912,614,60,341,899,518,992,625,195,514,887,275,85,704,749,58,67,555,734,650,44,674,768,145,993,287,886,261,671,649,793,356,726,890,73,358,693,431,45,635,631,422,188,544,597,189,250,615,755,734,623,538,947,244,279,330,164,359,71,845,338,39,846,300,611,639,712,2,477,328,989,145,95,370,250,95,984,804,952,83,415,960,683,917,729,63,284,586,427,517,606,303,106,251,409,935,721,170,520,868,472,250,867,776,664,107,581,415,572,622,981,891,714,314,826,916,801,967,34,145,362,677,448,617,68,882,738,384,145,403,992,347,96,571,775,215,182,655,349,639,379,371,496,779,65,405,402,448,678,59,728,777,657,122,203,728,711,597,884,874,471,975,964,171,776,929,636,319,246,963,507,65,606,198,718,228,352,672,11,645,348,695,660,846,88,702,715,777,900,829,849,117,636,160,943,704,92,30,25,812,591,798,636,184,486,184,479,900,47,635,770,606,377,105,824,181,696,560,332,901,716,507,540,98,110,36,373,150,674,498,397,669,650,477,748,175,573,949,203,823,752,363,239,193,229,581,271,860,208,856,530,170,756,604,485,25,262,818,303,550,918,172,484,838,263,126,993,596,77,713,805,150,256,341,36,508,640,865,886,950,481,514,431,866,552,552,729,662,771,641,821,811,206,479,650,136,123,660,848,470,661,323,148,442,207,152,391,100,402,186,322,268,54,158,734,571,206,588,196,388,461,690,678,994,753,940,890,928,300,311,31,863,800,39,388,615,747,99,938,133,754,101,544,583,248,939,643,607,767,294,156,118,233,580,870,221,420,113,472,424,782,384,393,903,914,527,350,998,986,684,943,173,294,783,640,725,133,711,174,423,861,635,859,757,667,625,4,253,354,31,363,696,467,289,195,882,512,979,603,674,860,198,204,645,668,985,90,384,671,73,78,13,865,485,928,71,414,36,563,932,662,521,256,658,223,89,271,526,585,685,113,675,222,571,201,61,852,866,358,274,122,229,471,869,546,578,340,394,432,377,334,317,371,606,830,84,218,565,886,842,496,920,400,417,842,334,655,587,395,969,345,415,70,442,752,84,533,612,817,83,992,925,756,722,369,769,363,817,807,850,866,288,520,943,498,180,496,726,96,149,606,180,401,49,98,740,218,646,338,85,183,232,815,209,705,145,923,529,953,401,324,804,698,438,412,870,202,498,131,737,791,622,680,461,744,704,791,44,193,56,301,258,612,272,338,632,85,93,508,978,359,184,486,787,524,957,446,136,86,639,818,898,751,630,269,855,92,616,906,878,741,495,339,32,151,577,10,792,246,962,237,226,550,932,436,873,934,811,958,116,147,565,909,661,245,128,708,467,297,71,458,298,409,201,915,76,918,762,669,129,667,749,196,753,332,296,538,938,357,541,29,623,299,782,993,67,408,695,608,771,415,278,931,323,351,535,894,225,110,944,897,147,771,746,764,274,966,154,853,177,595,39,748,505,99,74,655,322,906,445,178,135,800,988,182,627,115,276,857,719,250,240,774,214,139,584,221,866,806,596,543,909,541,260,622,413,759,76,975,66,505,813,593,42,743,743,798,860,800,704,599,611,241,747,176,67,152,211,847,416,346,964,686,717,866,230,896,634,729,490,864,957,38,769,785,616,21,804,24,479,839,25,788,696,546,741,210,456,750,637,302,908,280,768,172,233,515,120,973,284,60,393,325,454,572,790,515,73,423,23,370,741,959,278,409,844,629,741,960,27,71,441,152,63,603,155,92,596", "832,327,132,961,363,181,728,197,889,186,425,253,539,613,789,746,989,940,342,414,952,842,695,921,168,504,902,708,990,201,555,780,189,999,700,349,128,730,524,285,858,986,117,479,671,824,888,775,566,84,459,369,758,222,134,842,640,711,803,373,404,842,399,106,574,675,69,68,645,947,537,643,197,202,130,852,666,742,541,542,557,161,288,834,654,8,376,471,587,157,289,175,786,766,728,6,897,87,834,629,687,536,38,501,504,73,451,811,72,600,522,242,904,412,781,115,371,508,721,764,585,441,936,151,515,5,426,962,25,559,189,536,73,497,659,132,388,539,716,325,332,612,578,970,834,638,355,477,587,434,934,934,679,875,524,357,39,591,613,846,163,30,249,368,891,681,349,200,590,775,690,8,669,267,612,961,0,364,178,759,124,142,113,577,614,291,132,400,508,552,142,221,353,203,431,656,326,901,414,239,985,355,58,512,219,542,159,461,856,107,759,326,117,339,968,627,229,832,912,476,704,316,704,51,345,90,859,369,399,739,477,887,881,728,430,548,125,224,766,931,604,367,448,230,646,980,668,939,83,574,619,652,920,742,29,981,282,915,493,82,368,974,545,769,547,600,814,455,552,848,367,772,90,754,825,196,812,700,964,683,326,202,234,75,771,831,297,328,466,266,347,900,444,88,319,810,618,946,51,469,467,727,370,108,55,511,556,584,542,482,568,139,371,729,29,150,525,285,693,892,208,437,450,444,647,5,988,958,244,864,102,302,190,671,331,569,457,609,669,728,859,548,818,535,134,654,645,288,439,526,792,290,674,259,167,432,616,956,580,143,580,595,357,600,256,708,885,914,430,551,634,214,726,34,118,549,977,363,663,549,71,424,218,439,422,466,784,417,454,273,321,864,781,596,340,733,818,181,137,302,744,702,316,517,332,957,943,732,388,398,310,728,741,660,397,483,441,749,293,141,689,116,655,986,454,305,42,995,638,576,515,389,46,136,773,307,232,884,834,28,457,349,356,809,475,932,800,465,886,658,919,309,677,288,684,979,52,477,410,693,878,563,998,768,560,206,627,386,811,395,486,624,217,303,747,838,65,681,44,955,949,780,68,36,865,257,866,32,12,866,220,39,314,479,621,203,754,589,880,360,156,736,724,888,670,709,297,149,21,220,138,431,11,911,623,662,233,562,955,466,372,817,9,751,432,263,784,736,534,215,539,491,206,497,834,476,760,497,878,67,47,125,127,748,800,476,65,547,388,663,184,275,283,12,651,326,129,235,292,879,286,682,309,208,730,304,706,100,123,671,188,698,468,956,837,537,927,507,12,602,374,636,619,839,663,766,565,370,516,591,179,908,762,660,16,270,379,724,610,381,699,592,681,37,655,84,387,745,177,125,41,163,296,456,557,447,144,40,635,877,9,384,584,768,355,933,88,558,975,459,105,77,766,940,408,215,930,239,670,679,144,359,851,727,113,763,467,705,53,817,475,35,580,546,691,128,887,965,9,476,403,162,303,831,934,690,92,765,393,670,143,943,477,427,868,337,406,557,453,407,361,513,737,737,76,792,23,245,786,759,818,967,298,838,410,364,480,825,220,721,702,363,942,687,100,206,311,357,679,130,310,32,356,862,595,643,326,465,299,941,920,621,731,3,409,841,990,845,402,575,438,352,271,88,928,709,610,169,82,809,463,669,74,413,747,835,523,168,462,928,547,812,865,930,176,77,494,798,564,394,461,357,306,418,716,215,375,263,472,513,357,605,453,151,707,479,432,760,986,44,925,113,28,456,486,38,226,875,959,729,968,274,293,933,646,582,463,393,3,235,263,919,276,822,647,980,729,142,302,123,896,604,355,853,706,826,221,453,764,257,595,371,866,889,799,845,198,629,169,553,240,971,297,254,400,669,762,247,67,640,272,2,427,956,522,31,134,195,98,234,549,575,541,556,598,738,451,212,57,58,334,73,426,743,914,606,663,993,140,213,483,849,448,751,996,909,46,365,874,90,942,394,900,43,993,456,26,854,326,205,879,161,8,369,729,796,416,116,30,203,969,179,621,763,272,151,958,455,136,224,177,238,841,593,775,726,222,942,616,642,273,597,779,852,786,780,63,544,876,579,610,738,347,93,542,686,861,556,791,764,821,665,473,315,137,837,95,564,89,33,595,986,634,239,453,469,181,260,700,720,511,960,539,265,906,915,505,195,966,909,570,657,677,608,262,506,557,890,703,710,966,631,706,325,297,684,512,966,177,202,370,744,352,913,401,274,716,859,234,14", "739,320,949,307,253,64,996,160,119,558,619,479,484,321,880,334,427,267,269,234,111,515,177,93,29,450,652,240,740,526,125,797,70,220,461,643,842,965,902,560,683,523,989,262,111,783,384,431,760,477,756,864,996,381,941,760,608,565,556,148,226,25,139,620,798,551,349,426,461,357,767,179,862,572,2,274,325,574,654,753,174,504,805,57,889,194,665,867,218,684,479,979,112,198,147,372,390,507,170,714,972,414,852,931,658,257,515,524,881,102,346,662,377,943,63,202,802,770,820,240,480,876,942,854,68,289,946,549,892,881,419,896,770,965,713,761,765,989,36,649,547,623,162,359,294,903,680,452,768,56,987,301,365,810,697,91,207,224,45,14,64,670,700,675,237,395,849,559,317,158,849,596,187,114,518,630,364,0,303,988,558,36,348,464,798,298,772,692,284,625,615,545,523,889,279,255,61,805,213,250,364,123,756,719,884,476,820,225,192,944,229,126,46,210,895,124,781,163,868,967,161,28,639,371,53,551,187,658,666,953,167,53,984,724,22,856,916,573,997,187,373,525,984,745,680,509,165,408,362,542,643,433,292,612,452,292,665,491,762,919,265,777,250,690,740,855,399,349,593,170,380,142,861,836,676,492,40,42,167,338,176,427,298,627,598,805,635,699,109,153,260,209,53,586,400,917,23,280,130,841,3,332,768,232,290,688,679,388,573,382,465,118,445,786,108,210,297,303,227,55,833,275,452,104,400,824,372,934,482,367,82,41,29,587,617,748,661,719,130,220,946,237,174,120,485,837,541,510,994,407,863,16,567,582,92,728,905,626,813,138,680,930,5,279,565,968,99,162,152,204,210,840,852,342,780,283,39,866,125,641,306,583,674,584,602,715,260,540,576,131,436,515,211,44,539,410,750,883,911,753,92,244,9,263,860,670,701,133,953,565,228,810,805,636,540,488,590,589,475,963,915,430,845,574,325,554,8,782,5,84,760,746,510,675,555,286,730,428,361,581,453,971,917,545,901,930,103,239,995,955,66,327,165,241,730,609,834,753,91,772,85,479,883,910,84,801,827,12,714,832,855,42,379,663,44,580,603,911,454,340,995,996,812,749,684,882,130,131,536,515,862,495,294,684,914,524,942,34,543,68,667,421,815,625,696,62,232,156,177,126,178,716,10,474,664,889,595,432,408,511,256,446,469,573,157,574,235,528,201,608,766,911,948,203,210,593,156,507,433,406,150,737,593,372,894,689,735,459,621,315,243,313,903,913,874,980,961,575,826,308,600,467,380,242,704,42,665,264,301,989,532,678,339,158,719,30,357,575,496,406,839,808,274,560,639,87,393,762,657,638,464,599,890,102,598,154,947,132,246,678,309,357,74,72,555,559,25,569,521,557,259,551,76,176,281,142,195,828,208,401,240,716,5,300,739,754,233,202,307,471,550,93,764,914,381,989,413,624,987,437,96,611,371,601,479,70,884,129,427,402,605,61,656,750,98,35,442,550,325,341,445,408,32,944,798,170,780,707,245,234,721,629,822,347,282,853,625,543,672,125,213,587,928,223,105,452,412,937,90,54,49,411,835,247,365,823,842,394,313,985,386,824,278,331,806,774,659,730,176,421,956,857,460,410,646,324,857,650,931,881,699,517,255,323,849,758,948,345,839,172,766,430,64,992,234,239,173,584,958,577,229,797,175,800,38,94,832,970,224,47,179,722,384,227,355,627,544,105,977,98,789,663,602,612,580,374,696,962,288,879,580,725,816,801,979,320,671,905,851,307,425,966,853,532,516,679,107,277,637,776,722,325,485,592,87,458,69,174,661,651,380,302,8,441,428,305,774,650,410,370,794,500,369,841,632,50,357,82,420,40,268,936,512,2,598,364,890,79,355,15,117,297,837,684,868,88,50,491,357,472,208,104,445,400,169,948,230,312,315,205,509,749,230,686,426,103,28,60,612,147,42,405,206,831,554,84,406,511,307,512,396,495,924,145,384,155,767,26,180,921,413,327,907,650,785,890,268,72,275,877,754,445,76,420,11,474,911,296,357,893,927,760,846,298,973,828,481,595,114,721,59,477,659,92,485,101,475,425,13,589,91,974,130,308,436,906,427,392,376,509,691,986,792,328,636,135,102,141,489,164,959,813,575,317,720,49,827,275,892,32,161,774,631,737,427,607,119,210,837,196,661,645,806,367,882,144,127,8,401,341,422,398,671,765,682,854,315,401,82,781,413,166,408,269,205,165,266,883,234,742,525,89,386,313,918,211,651,179,553,351", "354,949,7,10,495,237,572,320,143,811,149,868,126,737,88,404,63,449,390,473,13,932,771,823,316,758,173,570,721,254,76,323,857,503,339,400,303,498,26,899,342,495,904,138,255,740,917,407,742,72,521,227,166,923,39,658,362,201,424,382,268,583,538,809,373,109,22,727,346,786,38,13,55,325,751,238,101,89,710,30,962,491,568,468,210,254,708,129,520,795,58,432,48,764,3,829,337,399,723,302,844,329,70,551,804,94,503,257,200,396,517,952,231,711,720,853,756,757,534,112,636,11,233,834,455,670,186,821,862,227,65,395,487,900,555,877,457,394,957,623,771,683,264,613,533,706,931,327,937,512,978,101,902,759,49,306,769,437,340,777,128,290,769,357,721,365,756,529,834,501,521,499,756,287,99,883,178,303,0,912,598,682,64,985,494,741,660,691,380,67,613,191,415,173,68,138,744,329,649,482,596,249,296,226,667,780,713,140,22,683,280,140,723,331,799,702,180,751,672,720,448,93,15,711,456,453,20,253,361,442,470,110,464,571,159,255,497,477,133,59,169,212,935,628,521,710,308,576,903,106,282,484,494,772,204,567,876,132,540,740,106,912,645,42,714,193,671,765,34,467,329,56,577,646,836,541,58,688,99,268,989,93,75,85,597,738,89,450,670,520,893,756,131,104,364,290,44,666,708,200,457,214,263,771,750,197,115,272,280,818,504,522,113,359,26,229,845,389,450,529,830,770,425,251,726,498,187,876,745,857,837,370,362,753,654,232,688,206,849,757,784,864,326,886,431,938,898,943,386,156,595,109,46,396,750,388,446,57,266,2,913,56,886,44,807,750,709,259,902,714,589,578,414,55,131,701,209,570,976,808,237,897,603,392,115,73,824,967,922,852,407,111,35,229,258,876,349,534,802,74,685,500,147,45,837,659,882,814,462,34,695,87,597,440,609,315,452,732,310,374,815,945,788,999,242,317,886,107,510,729,992,180,458,645,876,131,430,903,205,817,863,113,925,697,922,963,757,320,138,741,54,875,78,456,677,740,149,129,48,707,60,451,9,542,287,602,127,52,965,663,298,521,742,378,412,549,836,700,570,980,162,170,190,907,60,481,649,514,234,971,232,292,302,301,260,425,482,754,817,629,944,100,340,225,100,811,633,125,4,952,746,643,75,800,378,802,715,537,445,31,350,792,377,110,891,368,278,197,369,345,963,258,380,925,381,45,192,660,742,367,488,222,240,388,438,978,877,352,134,267,116,164,938,755,128,401,562,678,229,360,648,668,351,752,102,765,165,246,118,488,417,754,52,736,312,735,802,723,854,84,5,112,650,905,674,577,75,146,416,960,76,642,262,571,901,44,964,361,410,339,943,365,938,500,194,484,65,142,161,268,26,397,750,786,233,888,570,210,439,435,224,574,880,623,970,75,805,205,395,735,999,207,515,314,240,136,429,385,341,80,761,667,530,836,764,820,381,155,282,118,714,733,282,937,460,670,838,630,296,645,826,90,410,681,366,261,418,753,667,928,759,833,724,378,715,874,612,963,40,577,690,417,732,749,307,708,523,108,560,478,513,800,40,91,206,773,718,120,301,753,262,463,460,989,302,540,920,34,593,60,960,55,124,231,87,546,33,931,894,499,585,905,509,782,645,651,390,341,405,228,748,91,880,613,471,374,845,409,194,514,575,77,354,264,698,319,94,520,69,633,898,451,43,901,379,733,812,325,982,299,692,220,395,495,866,423,157,403,535,732,642,647,739,295,902,957,746,790,7,94,53,181,503,614,280,661,446,177,276,319,817,906,822,841,201,786,675,496,242,643,908,537,973,598,470,364,830,309,17,398,523,601,495,395,284,426,861,881,299,903,320,555,155,551,126,16,539,118,666,228,699,920,360,208,477,529,652,50,943,570,55,737,958,907,381,411,410,838,484,157,140,471,276,333,438,707,217,396,227,845,832,626,949,925,41,744,439,83,422,234,763,338,394,534,306,334,71,491,597,752,906,932,455,639,34,354,325,632,596,557,457,201,58,445,739,937,433,957,55,131,334,67,922,702,409,29,611,714,984,929,669,427,60,504,33,16,812,260,6,25,997,451,819,73,182,974,51,451,319,959,768,25,770,67,986,405,747,71,914,485,39,982,273,643,46,302,519,317,692,346,111,376,293,413,852,21,375,552,78,143,529,213,92,65,762,974,192,307,765,959,472,684,383,437,363,316,423,573,704,284,86,903,695,217,380,65,443,133,333,87,235,775,710,120,882,332,15,792,108,778", "781,838,624,286,230,962,242,323,613,755,349,250,75,389,572,32,355,284,14,509,262,947,849,385,395,133,597,381,465,418,297,524,294,944,554,967,353,993,987,512,779,36,902,243,8,139,802,672,832,985,339,716,423,707,985,103,182,144,880,192,525,574,694,530,9,906,348,147,664,318,133,371,677,490,28,50,89,992,877,938,871,180,698,740,56,494,316,117,857,812,248,906,696,574,394,872,196,279,867,690,721,18,416,667,839,72,174,677,56,728,334,979,24,872,597,20,218,838,359,976,243,218,522,288,513,590,616,916,757,739,210,844,105,910,521,610,359,683,973,710,499,628,390,338,117,14,409,602,271,407,305,866,42,253,163,686,157,338,58,431,160,743,644,661,11,984,294,524,745,181,462,172,453,422,450,31,759,988,912,0,106,562,127,217,657,146,14,522,270,969,432,851,424,743,145,844,944,421,79,399,506,216,259,799,739,540,260,630,585,563,679,614,757,545,128,285,301,43,414,501,767,353,883,698,652,653,511,150,137,527,288,479,367,810,116,678,634,673,48,84,651,236,516,722,771,824,745,998,45,82,681,787,876,949,311,719,451,902,22,586,744,58,37,954,604,645,32,919,96,367,152,116,228,624,221,369,504,166,615,737,473,857,816,345,370,761,543,916,64,392,225,553,631,773,998,298,722,523,267,32,957,499,961,20,239,39,942,925,14,481,129,914,139,262,260,920,433,376,456,622,79,465,15,55,543,214,647,408,128,692,746,234,475,347,409,727,65,455,765,713,863,100,580,897,855,925,971,866,322,316,372,586,761,908,127,262,603,19,310,139,599,148,681,338,967,612,594,92,728,826,919,822,376,396,613,617,74,805,338,245,344,621,742,725,51,627,583,416,97,575,810,299,135,667,507,807,274,409,897,295,796,836,1000,85,155,144,339,833,147,189,43,666,425,88,600,294,71,63,44,720,632,325,192,390,33,428,19,880,512,217,143,785,305,766,125,332,200,844,839,470,31,441,68,805,301,379,954,468,704,128,759,399,174,393,337,203,114,641,290,783,902,703,192,192,523,210,24,86,688,808,601,851,133,615,974,237,278,732,160,687,104,938,38,757,803,377,139,338,229,160,980,184,41,414,264,673,866,838,127,802,614,994,432,800,466,783,220,549,933,25,29,204,462,384,396,460,338,751,289,406,297,53,281,185,544,715,122,392,42,533,366,962,230,484,943,148,598,342,212,449,469,374,618,554,561,907,530,24,80,273,200,382,585,251,754,150,616,136,685,287,282,873,593,816,353,380,226,186,525,495,279,984,176,474,492,970,334,412,237,834,324,609,158,195,328,621,398,548,246,779,320,649,185,517,54,640,799,372,119,798,457,867,672,380,757,941,373,311,188,485,232,150,667,886,358,688,880,257,155,613,432,200,703,904,335,577,446,727,826,469,587,701,416,88,427,902,760,908,821,291,868,187,206,591,870,188,519,583,899,650,388,536,527,836,878,287,945,175,628,649,215,620,539,122,844,885,292,685,463,531,906,685,595,796,183,786,145,190,836,244,594,758,625,714,352,565,648,497,150,453,55,669,391,793,105,165,809,371,10,929,195,913,586,613,512,248,554,789,152,878,933,2,585,766,200,358,715,77,925,756,3,20,12,373,286,308,272,688,390,635,484,15,590,183,678,447,459,217,945,309,29,361,426,78,401,210,932,455,886,682,681,71,703,182,82,381,958,329,11,886,764,297,393,611,525,324,207,840,944,666,910,240,165,509,488,807,734,582,700,981,673,783,174,530,894,9,465,521,296,892,352,532,728,770,816,65,786,659,612,526,278,707,582,817,836,815,407,423,477,74,262,790,860,302,805,522,937,725,951,72,274,317,293,314,456,863,435,998,294,418,781,28,856,196,658,444,220,681,542,464,459,854,863,372,827,782,491,161,582,420,342,293,460,306,209,39,611,90,876,715,553,634,871,859,810,451,658,572,856,181,717,861,828,213,834,636,322,87,811,533,116,752,851,307,353,654,686,119,741,631,177,182,547,316,423,954,932,721,26,100,173,306,571,452,981,996,123,382,422,651,518,813,966,688,299,360,43,552,912,475,499,786,739,208,453,383,259,730,445,699,129,143,812,784,59,829,914,902,740,773,161,79,574,775,3,452,648,852,11,413,190,341,84,104,859,42,146,698,637,927,355,229,721,307,479,473,936,226,334,35,509,603,651,126,651,952,146,527,326,692,668,248,184,561,759,314,678,322,15,558,882,104,594,764,695,786,106,437,110,821", "348,138,684,188,683,445,143,721,371,44,797,430,351,657,621,807,4,739,386,500,131,918,512,789,869,998,564,892,292,458,277,261,457,673,759,963,94,232,938,614,77,515,532,536,587,210,35,150,63,107,160,241,337,62,247,810,763,570,303,489,553,92,598,92,777,119,725,411,734,222,247,195,445,865,237,243,954,311,190,179,920,389,849,433,275,753,259,46,173,328,592,273,8,525,669,638,195,468,393,133,31,69,308,280,625,439,260,404,44,203,103,283,811,23,799,955,291,776,272,466,925,770,425,732,461,171,651,309,817,163,704,955,485,777,314,358,181,743,629,328,157,936,518,448,450,994,881,228,421,853,366,110,957,145,257,486,751,869,394,376,295,524,517,971,563,64,801,205,465,734,606,956,31,638,661,969,124,558,598,106,0,5,861,288,818,753,486,750,353,196,39,471,428,85,877,502,609,986,413,746,32,18,925,483,750,382,760,305,764,578,593,852,54,934,642,715,287,958,684,165,161,601,222,607,823,132,484,656,378,31,848,43,42,300,466,259,953,595,775,337,169,355,651,826,77,430,663,293,392,952,525,450,560,595,664,872,495,833,667,130,111,936,869,403,402,771,431,7,481,76,894,691,712,226,533,58,793,447,193,227,229,514,879,659,357,770,45,100,500,311,745,804,507,793,721,162,779,663,186,162,981,642,289,445,227,617,634,106,409,651,150,87,193,961,138,352,227,542,958,855,382,606,29,502,709,619,530,66,350,172,965,580,187,708,459,745,680,74,482,770,442,590,992,873,767,950,116,140,562,773,750,700,746,746,280,300,986,707,732,115,392,408,276,535,292,218,388,331,273,923,570,69,299,122,511,583,491,919,46,47,814,66,94,357,319,261,140,498,3,655,44,829,461,208,426,380,749,270,220,386,687,88,34,762,170,389,481,394,234,633,275,8,793,519,85,502,810,549,20,448,47,300,945,652,34,790,211,610,763,437,572,779,268,608,422,594,56,66,940,951,955,377,873,443,762,824,768,429,62,621,308,411,414,380,307,144,611,681,638,904,725,516,503,590,354,94,140,434,790,528,917,212,304,12,319,328,557,28,377,622,620,648,605,106,146,1000,842,555,52,955,937,244,405,19,398,253,341,344,156,613,461,486,333,80,982,262,464,458,671,707,412,779,67,81,361,481,286,650,691,145,455,394,40,183,544,898,377,452,706,756,385,152,997,879,719,109,261,794,788,378,909,952,700,90,889,943,617,145,773,370,714,3,628,552,272,266,433,877,168,475,248,379,590,967,647,206,932,238,289,435,754,964,634,15,486,786,752,36,733,191,226,722,922,540,350,591,384,375,13,911,850,340,184,80,745,518,889,280,462,773,179,755,997,187,962,725,488,463,990,14,631,623,366,211,936,717,839,983,432,680,758,886,385,517,371,401,853,152,292,227,683,184,144,704,532,215,177,420,673,819,858,938,607,410,359,245,43,801,911,646,822,179,699,805,409,54,301,959,188,657,655,114,959,845,873,125,371,68,723,516,23,405,438,762,132,818,57,397,488,135,112,729,596,303,836,741,562,220,929,823,740,296,933,50,517,195,963,15,109,62,944,110,889,786,428,753,94,258,417,92,529,89,541,48,160,997,410,400,455,764,198,726,406,776,157,95,842,9,894,563,675,779,100,633,379,262,18,706,138,668,2,80,308,841,964,420,11,4,479,967,534,571,198,864,169,575,142,645,744,597,936,15,555,604,578,928,295,396,368,332,195,746,908,294,538,613,350,976,863,553,679,109,869,308,196,862,345,137,646,352,843,76,331,848,503,384,614,162,31,305,574,779,695,672,845,136,232,477,761,977,998,323,444,899,657,224,928,780,833,172,391,677,454,213,409,52,376,936,175,563,565,40,787,339,821,851,829,482,191,553,210,19,3,524,728,84,271,474,98,565,161,302,256,986,996,398,765,864,957,360,633,460,918,765,556,665,263,742,403,96,732,77,694,770,186,789,252,419,582,422,783,154,283,564,503,930,482,594,101,785,5,17,854,353,479,391,32,181,681,125,975,823,828,49,337,195,76,991,640,458,468,283,882,978,788,689,48,24,458,928,718,971,373,532,608,384,88,181,803,828,776,447,152,229,142,181,875,366,144,627,518,84,191,353,426,312,570,917,988,629,502,325,616,924,841,571,297,297,643,43,763,342,982,763,504,776,316,997,349,604,532,633,271,900,777,397,894,938,509,767,872,226,798,477,519,694,52,973,433,62,157,681,542,306,150,401,81,348,963,564", "264,537,720,982,634,63,962,619,209,622,664,681,749,292,310,695,959,370,356,98,952,333,961,82,855,168,569,397,738,601,112,853,427,521,15,289,104,544,346,280,797,480,790,853,945,637,346,882,553,594,248,107,865,263,402,317,231,386,925,690,79,284,816,899,505,971,181,881,849,89,424,351,269,211,535,292,729,25,206,198,924,812,983,668,677,902,215,60,744,943,267,525,199,785,788,387,80,787,854,453,581,215,79,508,98,376,690,969,335,532,433,223,175,222,966,750,188,417,579,404,821,410,327,770,431,301,605,857,629,849,677,154,414,879,580,2,210,672,867,331,985,373,134,841,885,170,424,927,88,999,629,18,987,88,584,501,641,778,453,661,658,607,31,157,543,530,691,598,29,532,892,394,960,408,446,86,142,36,682,562,5,0,538,268,402,686,635,959,180,317,426,496,519,111,239,939,455,273,396,95,178,835,436,228,788,549,655,404,116,486,953,306,301,286,948,954,486,678,584,602,446,338,379,560,402,301,224,831,196,57,686,511,436,511,523,22,268,115,243,928,610,440,488,999,192,639,600,836,283,291,10,913,161,232,864,155,284,680,810,873,676,949,578,129,628,131,726,950,309,693,992,646,936,346,41,617,808,26,559,750,205,292,15,459,938,89,133,965,946,395,726,503,789,628,829,316,661,334,201,507,533,344,690,405,943,846,18,779,105,307,298,408,710,790,247,93,261,392,984,533,171,259,583,781,236,338,327,806,903,169,376,514,690,193,589,784,345,57,522,265,888,763,828,686,209,135,428,922,481,957,939,913,711,3,842,965,975,357,769,597,388,294,492,944,834,465,658,861,928,698,175,145,94,538,433,277,850,246,271,35,26,838,442,272,884,322,404,894,845,267,592,471,795,438,60,248,326,263,769,658,241,872,808,219,339,985,240,335,812,552,383,501,182,460,321,680,725,693,850,438,458,768,732,608,626,693,930,510,22,858,444,979,567,786,125,898,506,258,688,149,412,336,631,746,906,855,228,987,312,515,562,369,623,859,172,351,747,379,263,152,594,643,116,816,840,806,320,328,254,497,600,501,379,589,774,343,319,733,595,125,120,483,980,797,997,713,125,744,574,255,766,598,226,926,244,705,704,790,406,905,761,380,340,850,654,880,309,972,965,166,748,883,347,616,547,60,980,760,304,748,364,541,581,445,339,475,756,32,140,989,733,185,352,600,10,574,565,858,225,40,542,448,114,565,846,997,329,76,555,418,561,916,754,139,577,823,55,261,518,176,698,67,596,583,623,356,232,816,539,926,922,449,999,59,814,356,316,792,397,830,717,969,482,48,906,284,289,169,261,776,878,223,354,893,719,90,401,350,13,32,700,521,421,161,817,869,496,101,649,395,71,723,874,29,573,995,304,704,201,475,745,678,688,138,771,37,440,341,522,438,152,682,903,707,266,907,924,866,94,352,464,643,773,65,43,608,189,487,632,24,530,888,142,220,579,38,128,839,405,256,810,729,211,332,246,952,969,318,762,647,923,34,11,55,4,978,638,317,224,555,443,933,56,757,825,735,192,872,404,199,405,429,689,510,694,83,85,21,676,498,1,17,987,354,474,503,588,298,648,747,546,553,593,571,531,949,788,303,322,361,658,186,647,597,430,750,163,212,453,249,593,35,555,569,588,609,891,530,481,819,460,564,883,806,792,561,554,54,786,779,246,594,493,628,306,287,281,497,696,845,442,164,90,206,879,733,377,670,688,429,282,499,485,279,42,498,184,112,563,977,201,905,597,306,594,62,738,919,192,265,358,430,835,620,845,21,671,945,357,850,349,812,412,306,494,789,977,291,710,947,310,381,74,202,944,300,259,885,617,149,69,277,874,762,160,265,576,24,590,233,318,574,551,866,658,206,378,685,515,432,907,740,870,87,16,148,820,958,12,818,912,991,5,482,357,408,555,908,590,424,129,392,587,822,575,116,366,133,605,221,770,78,292,879,96,821,558,893,854,804,285,41,540,450,226,38,591,386,945,808,946,959,132,767,57,310,489,774,855,88,673,477,455,231,854,713,353,510,991,469,313,161,990,425,97,612,743,159,52,685,839,288,501,564,785,381,475,199,452,437,173,382,53,279,961,373,873,35,389,482,720,549,105,13,690,830,352,801,307,195,611,395,969,891,191,966,497,236,131,605,964,837,430,401,607,985,641,921,913,788,258,828,615,113,364,501,966,302,415,548,601,883,61,924,646,982,918,87,142,258,520,547,865,317,87,157,365,816,129,492", "790,868,651,970,851,561,133,998,57,15,629,359,262,152,501,306,680,539,822,256,753,279,512,631,391,881,493,127,621,31,630,233,921,927,972,201,138,915,4,499,641,256,490,73,438,573,274,260,889,931,53,384,421,603,735,494,768,319,880,979,92,724,877,632,355,551,447,9,567,606,574,538,352,43,216,579,905,43,648,93,287,751,632,537,997,734,426,326,99,911,239,197,442,648,491,978,408,24,214,786,471,876,750,696,62,506,410,427,491,242,695,473,837,774,938,2,686,138,849,89,452,850,491,810,741,885,524,341,932,609,102,42,103,277,812,569,331,503,407,450,167,997,218,518,455,385,797,942,878,745,305,988,153,244,100,326,243,726,654,671,75,682,358,642,668,538,618,208,91,787,259,154,430,943,272,135,113,348,64,127,861,538,0,558,215,949,756,139,242,491,941,745,315,424,370,260,34,466,693,562,920,490,707,239,94,565,245,730,369,414,810,334,418,189,194,199,709,818,299,731,701,799,806,741,3,224,629,65,220,203,756,260,688,461,508,319,641,88,819,922,98,52,763,108,883,819,906,626,803,263,13,795,596,438,491,432,377,121,131,516,328,324,294,753,679,490,366,874,742,977,185,51,212,739,36,660,718,387,459,845,780,306,555,278,585,452,129,442,935,157,329,783,499,249,600,514,322,62,214,462,712,719,464,376,758,825,46,783,675,334,494,983,409,498,983,507,824,326,170,235,194,576,742,983,197,177,645,776,625,704,107,374,170,341,575,887,384,248,181,601,808,109,790,671,791,404,178,750,409,517,429,158,444,129,194,308,579,49,704,274,712,209,251,93,518,57,597,847,820,580,290,473,712,78,119,595,13,139,920,770,894,158,671,143,601,668,199,619,295,533,757,218,585,328,969,772,469,871,384,341,32,620,903,793,975,696,568,658,75,634,263,854,493,956,348,566,835,529,977,366,13,972,504,842,379,634,475,29,657,760,480,316,508,409,897,36,378,934,216,90,648,194,899,787,852,170,479,554,546,689,495,765,31,963,702,745,689,37,674,580,532,170,43,62,573,659,916,36,121,53,619,154,692,564,151,932,962,226,904,79,312,678,659,286,47,511,256,467,898,141,347,30,611,386,527,988,575,875,602,937,644,649,298,529,888,329,512,861,629,370,181,774,244,514,886,605,828,694,139,414,327,770,120,282,80,408,219,706,819,180,849,252,131,319,528,158,64,288,217,168,552,474,190,646,270,990,883,754,131,246,458,368,772,190,906,504,209,525,478,863,451,691,679,595,929,173,840,984,900,496,994,536,647,952,971,410,25,812,874,471,599,559,344,741,640,88,845,45,266,528,721,791,417,451,623,560,330,958,716,28,565,363,712,95,647,199,866,908,318,345,227,774,949,781,366,70,908,561,741,995,834,360,911,242,843,540,127,333,819,611,15,328,616,756,498,551,227,448,123,677,672,881,160,220,916,462,204,395,470,189,775,298,179,957,834,49,993,74,68,327,429,82,200,937,479,344,270,69,421,361,111,339,5,428,404,910,36,806,321,827,362,424,341,853,209,200,205,132,431,828,573,860,256,738,917,970,986,586,304,983,608,57,388,32,38,130,758,475,587,74,258,870,2,719,306,463,41,904,746,801,299,375,62,897,935,889,668,415,528,609,302,321,846,677,805,203,799,99,378,479,597,723,519,265,360,474,293,875,694,893,291,577,154,520,990,744,495,699,319,509,31,849,933,767,417,908,668,401,440,552,615,123,940,658,742,635,817,97,405,424,667,829,861,423,312,852,903,902,258,835,6,329,25,769,938,998,133,168,41,238,347,438,834,940,953,549,633,715,880,214,306,820,304,633,311,698,16,989,259,393,913,547,453,129,438,876,503,263,664,76,783,447,589,340,198,392,328,150,139,957,365,251,341,619,804,941,263,298,224,332,282,567,205,109,532,8,20,837,106,733,731,456,852,961,302,780,858,242,15,119,727,666,375,690,380,791,304,376,675,217,835,188,370,889,683,749,625,271,141,971,297,998,781,246,336,884,139,828,851,22,140,852,402,119,776,982,314,864,841,231,863,201,951,26,448,980,312,483,951,823,280,348,29,499,953,928,757,719,630,300,794,238,977,410,477,715,246,237,294,502,619,982,541,352,944,127,339,576,980,569,481,951,936,880,809,671,855,788,638,307,795,764,556,163,423,329,828,647,864,849,38,5,384,446,204,752,571,521,682,748,653,874,695,561,2,95,612,275,669,189,741,65,301,310,618,81,559,561,796,48", "110,329,556,237,906,882,390,763,89,820,295,356,897,794,485,393,858,909,356,952,416,153,499,112,87,753,735,687,329,30,676,312,629,883,424,245,267,394,855,888,377,490,441,139,397,876,146,972,431,776,564,700,229,346,473,859,465,237,353,340,153,62,166,955,907,615,115,551,117,327,848,380,529,503,466,901,724,424,798,873,268,557,539,871,620,945,890,585,23,114,469,933,159,688,345,837,640,639,457,485,42,64,280,324,216,370,462,451,488,225,20,992,611,966,465,969,71,482,315,20,663,386,916,400,761,50,796,305,248,825,655,432,583,924,375,171,412,105,696,158,397,298,552,710,695,135,629,746,260,246,615,780,835,960,28,737,264,440,825,42,300,903,480,47,942,355,48,347,346,186,528,879,395,716,803,935,577,464,985,217,288,268,558,0,562,271,962,559,52,410,774,598,786,929,25,953,543,779,920,983,91,859,615,317,308,839,491,758,67,527,464,700,994,865,935,448,875,625,777,88,369,559,213,771,229,947,837,303,229,161,440,665,755,114,433,752,146,395,902,468,969,967,166,428,747,303,223,648,155,681,150,598,252,541,395,758,394,770,659,561,617,958,127,228,96,732,881,48,63,975,862,938,643,379,24,617,814,285,657,909,757,566,77,528,888,849,126,225,522,101,732,946,514,126,653,921,388,704,820,887,366,567,226,690,81,270,894,732,130,589,482,931,431,661,930,692,205,520,367,397,35,984,972,99,589,706,65,894,7,53,455,171,819,488,478,875,825,648,65,664,526,943,118,666,133,255,495,175,611,430,279,333,318,286,410,138,912,773,744,434,555,862,579,112,163,438,426,13,778,598,727,459,263,687,345,152,592,550,666,551,996,694,802,551,616,477,305,537,681,790,354,793,718,58,457,312,192,919,890,327,840,770,842,826,959,282,44,963,931,845,192,792,479,891,286,32,506,486,565,832,32,161,590,388,854,67,220,535,254,721,968,514,961,893,886,598,4,795,34,665,243,866,457,517,70,630,651,281,868,237,628,46,209,324,976,400,213,833,496,942,80,340,26,550,566,834,782,502,99,629,75,402,69,156,837,575,600,648,778,349,430,981,80,129,176,490,337,870,556,956,725,675,307,549,334,877,470,307,740,281,252,494,175,31,434,507,191,139,633,56,367,257,398,940,35,169,953,399,305,937,919,132,379,890,720,310,711,465,932,34,407,992,576,13,689,18,596,784,89,214,704,377,553,53,159,573,945,123,159,10,929,190,300,554,984,893,30,803,279,908,604,391,691,577,594,438,849,121,375,539,315,395,848,979,715,490,96,828,876,80,475,102,432,900,224,719,309,538,52,11,304,459,279,62,101,323,740,470,369,951,585,61,852,707,355,601,752,249,418,26,467,855,725,872,342,716,785,997,897,508,471,359,736,660,923,354,355,779,275,332,144,390,430,285,798,720,609,646,456,597,366,939,944,58,387,870,124,50,367,495,296,262,495,738,262,621,109,697,563,48,12,319,110,147,389,281,392,988,386,490,219,237,6,70,80,951,181,390,999,401,522,842,261,957,488,802,721,827,106,289,160,192,710,388,465,744,918,908,31,167,393,775,531,820,428,238,477,819,999,147,967,171,898,566,537,259,981,610,837,351,434,6,436,914,729,518,983,505,581,844,191,397,168,20,345,813,567,416,260,287,235,634,882,977,392,268,416,87,445,271,221,655,321,156,814,177,356,762,114,443,417,63,73,14,183,397,958,776,236,175,361,920,972,378,193,259,242,125,982,900,952,798,155,9,269,539,677,609,456,586,715,396,581,70,799,931,164,317,406,8,879,681,682,157,32,784,220,974,758,60,390,553,286,341,361,121,727,920,460,662,266,756,769,326,961,678,584,477,44,623,814,725,587,976,198,935,393,6,553,454,33,941,751,385,202,95,954,49,752,106,550,390,835,387,923,677,224,524,826,899,39,430,397,486,814,139,887,736,145,966,746,581,661,107,267,536,443,127,958,245,856,689,778,549,616,45,13,248,658,760,386,625,98,551,71,78,327,46,193,402,493,981,662,579,556,935,149,158,86,896,313,572,263,13,446,869,654,98,119,874,54,965,366,979,334,494,887,932,33,686,310,291,378,426,144,281,233,692,473,966,44,878,765,254,344,487,990,560,28,386,514,566,91,613,299,940,790,761,382,524,891,615,832,825,485,923,398,989,429,880,460,696,843,664,749,303,980,466,26,836,131,783,901,49,182,676,444,431,864,715,599,188,517,445,580,181,667,885,201,344", "369,759,534,614,983,980,664,152,326,55,188,818,271,800,382,134,500,249,314,626,386,918,803,82,92,17,47,584,389,194,411,896,460,108,693,748,313,226,911,820,304,731,876,711,840,580,663,854,831,219,413,748,167,559,505,828,654,197,166,702,310,836,953,22,641,943,579,109,71,208,156,110,786,170,820,264,335,808,680,516,836,711,888,123,403,16,466,627,415,303,390,675,809,453,360,414,7,998,716,727,103,284,293,775,899,277,181,765,40,695,985,84,299,498,981,132,504,341,467,316,618,502,238,110,283,794,285,937,62,343,909,318,511,29,901,23,510,304,554,288,72,217,248,318,637,330,172,922,218,634,791,136,218,928,700,896,63,615,718,54,918,696,272,474,938,762,993,178,233,528,798,320,450,720,836,702,614,798,494,657,818,402,215,562,0,535,598,471,828,895,121,62,944,171,388,87,996,263,755,459,175,987,144,911,536,876,58,208,549,372,840,188,912,729,160,986,904,70,632,345,393,549,911,224,7,830,704,437,609,489,221,120,24,355,92,482,177,82,544,7,396,692,732,686,96,963,85,104,228,720,55,519,34,891,887,213,822,804,494,137,786,768,292,639,27,42,261,295,772,195,183,991,951,486,792,392,957,397,253,448,239,859,915,176,5,177,766,404,551,337,455,86,201,986,948,631,63,934,631,940,408,467,986,565,726,622,633,737,107,91,783,236,166,632,28,899,965,710,198,638,67,144,686,58,631,584,821,805,147,114,400,471,338,430,536,122,868,491,332,298,234,231,193,769,514,462,352,28,550,675,216,776,763,795,982,762,637,677,890,29,380,813,820,470,89,988,296,61,719,750,288,920,426,53,270,213,604,335,978,760,918,187,523,19,269,817,556,716,640,834,952,931,498,200,258,146,674,49,839,181,130,894,944,942,200,490,282,791,447,594,143,219,270,562,337,821,794,618,902,828,117,899,212,858,530,664,766,96,440,810,521,828,167,787,434,12,420,538,99,952,437,468,991,391,206,346,917,3,724,22,475,195,31,602,423,51,846,249,333,447,779,332,625,372,33,168,189,932,383,782,523,728,517,774,274,529,540,636,861,87,121,73,59,864,19,758,307,385,903,845,360,228,14,262,450,332,945,921,527,406,895,379,641,711,403,741,500,716,422,800,619,207,411,602,823,814,960,579,239,709,515,198,947,218,447,350,585,700,516,734,967,100,558,437,410,989,120,322,968,902,406,553,644,400,842,19,274,77,539,104,430,327,831,313,203,131,733,604,124,433,866,131,499,318,629,746,595,271,602,14,963,759,481,270,708,657,766,142,701,764,379,81,39,348,155,2,23,494,663,673,377,597,175,42,89,543,69,537,609,146,462,788,591,224,909,37,482,606,199,816,129,542,907,716,166,790,19,584,504,793,938,797,298,475,309,762,988,688,752,317,180,377,952,100,692,89,549,261,370,309,926,721,908,271,842,571,780,853,785,263,55,624,334,205,819,419,365,363,135,487,799,200,908,658,840,483,540,433,56,22,698,93,925,477,354,180,295,197,668,788,988,966,140,759,932,539,843,124,258,863,195,459,592,950,752,137,805,699,678,307,730,304,119,955,682,455,971,239,898,276,947,447,726,818,922,27,42,918,588,415,359,267,576,827,968,889,849,609,778,926,290,139,681,494,544,198,385,775,331,740,12,257,217,242,635,984,162,304,63,594,848,154,803,579,708,102,133,858,737,87,365,856,157,220,317,129,884,672,931,863,243,858,144,887,954,585,40,669,521,520,289,447,292,137,122,337,308,492,256,923,43,395,827,85,995,762,288,649,681,252,798,264,186,95,394,54,536,203,397,144,326,64,421,15,196,772,709,171,477,590,675,764,112,334,215,843,927,608,538,901,199,752,413,99,236,55,277,319,930,953,571,755,69,56,249,71,311,712,789,549,78,66,655,797,816,219,789,895,272,900,736,284,265,93,595,969,589,860,68,29,626,886,357,315,698,198,445,602,307,414,322,67,455,860,317,681,318,931,367,768,132,697,430,632,91,651,606,189,97,460,242,335,397,83,413,279,719,44,404,801,678,266,966,175,243,989,889,604,554,91,889,117,357,298,76,691,175,304,882,257,677,217,461,472,769,867,447,520,411,738,602,457,831,167,173,67,77,839,272,229,607,441,470,568,443,896,840,791,706,663,48,214,245,829,918,391,913,18,211,154,495,187,829,510,615,671,572,476,721,984,113,818,665,327,268,684,761,619,98,402,884,883,53,446,271,338,912,412,576,967", "393,923,661,274,610,211,786,4,539,960,39,66,671,60,890,310,813,310,690,722,865,394,834,320,690,798,144,674,437,582,281,960,704,658,571,22,59,323,287,875,634,879,128,431,935,531,913,416,258,570,965,36,580,956,278,176,392,544,948,940,797,946,738,856,714,450,854,370,591,388,281,637,331,869,190,202,347,728,537,494,430,143,850,164,612,450,665,752,648,641,769,506,964,551,729,164,267,391,798,61,836,75,782,892,343,43,487,76,314,28,737,196,900,384,794,928,450,333,947,923,973,938,671,583,477,639,61,231,206,733,187,759,333,593,153,217,300,896,505,605,398,770,720,50,60,308,589,815,665,19,949,364,772,247,975,792,965,39,297,767,126,5,87,973,669,602,177,66,87,83,798,684,904,780,863,387,291,298,741,146,753,686,949,271,535,0,791,830,20,696,707,593,965,160,184,742,185,631,448,31,489,497,602,669,466,677,276,558,294,991,311,642,395,662,210,841,499,428,406,852,359,908,485,731,917,767,219,874,571,156,595,134,284,897,905,787,800,592,358,405,219,410,308,135,149,389,340,143,240,377,202,31,163,123,214,732,427,777,547,271,851,269,802,358,192,8,528,270,401,791,722,277,81,371,987,667,836,385,976,883,431,972,708,51,95,516,389,998,821,238,461,967,494,743,761,335,606,98,664,639,543,561,725,751,832,720,87,104,150,52,750,609,122,474,983,482,840,908,483,632,444,895,495,637,402,329,958,917,918,710,896,443,265,912,770,381,767,250,906,854,79,64,417,6,216,662,885,144,480,497,542,222,288,246,406,855,758,835,688,81,377,951,445,782,538,260,130,751,818,753,727,971,994,533,696,852,385,600,156,224,402,941,467,508,950,660,254,929,882,275,38,259,137,832,14,651,119,715,934,881,213,939,286,398,446,294,351,383,55,637,263,331,966,860,475,581,610,668,510,336,602,49,153,196,812,914,180,817,217,672,918,76,644,26,440,533,805,358,82,472,917,641,903,522,768,914,402,843,431,85,694,996,684,915,8,991,395,220,345,293,379,375,876,389,998,803,99,515,873,317,848,358,741,391,231,324,102,398,816,955,433,776,68,750,245,557,160,296,308,755,321,656,225,914,376,430,687,576,560,15,823,846,893,269,99,355,613,149,682,175,840,479,231,64,59,764,856,773,609,181,948,895,251,33,541,409,968,391,617,990,70,188,702,20,142,348,157,500,992,473,411,294,4,611,718,791,668,315,578,950,896,635,767,232,152,780,769,170,542,351,491,628,247,220,196,688,524,365,833,244,338,370,359,651,759,696,851,337,590,944,807,39,470,791,528,948,574,327,160,628,891,669,411,839,329,885,151,6,194,286,604,150,400,44,983,860,454,207,636,551,22,754,555,525,437,886,95,202,204,73,902,439,955,285,294,372,237,77,692,798,90,229,194,513,829,367,495,424,320,175,236,231,65,712,120,710,746,185,875,953,939,7,277,693,471,47,549,524,599,351,326,939,928,852,755,488,325,244,194,647,342,226,757,672,699,229,117,702,503,599,527,974,767,73,21,696,221,616,91,243,135,644,534,572,894,758,300,336,678,912,588,486,930,131,608,708,422,585,761,393,286,694,705,56,101,834,436,681,229,181,44,141,125,424,32,656,806,305,516,765,153,194,712,146,501,337,757,671,372,136,271,116,906,250,520,75,537,711,121,207,675,309,437,943,727,300,229,320,809,172,726,186,995,32,656,327,548,586,845,972,452,300,629,356,843,335,466,934,874,191,939,715,464,200,770,953,434,808,486,642,281,975,137,581,25,455,290,10,815,207,557,213,782,445,63,607,782,642,431,281,840,3,937,529,256,54,647,627,696,630,913,205,276,359,591,743,745,878,108,95,137,321,562,492,216,911,809,94,385,594,728,660,737,412,919,372,487,191,139,918,857,357,560,353,331,70,961,903,269,488,106,307,729,639,60,49,152,571,499,636,671,383,839,371,748,431,176,996,125,271,657,66,552,250,506,810,261,327,200,263,982,257,737,267,820,264,19,903,615,855,201,534,148,310,426,628,170,5,239,645,612,788,982,133,759,799,322,720,239,80,446,354,316,196,523,503,150,44,747,824,143,782,246,492,655,93,489,648,411,149,638,56,645,943,919,631,856,623,896,7,987,684,705,701,975,867,68,586,146,770,446,880,903,283,715,519,909,50,832,519,951,409,261,337,240,704,314,323,70,517,161,792,666,236,229,644,165,605,841,498,625,345,265,457,573,444,38,907,647,595", "678,496,852,50,966,458,580,591,207,518,786,626,168,22,360,137,281,235,752,544,459,37,395,959,874,608,474,259,837,539,869,693,621,895,53,177,702,943,35,224,237,192,761,760,140,725,105,83,557,402,148,192,653,558,266,9,531,755,910,449,36,834,334,599,13,617,818,873,278,747,389,258,239,879,846,964,158,356,416,542,549,353,691,373,363,642,141,368,232,893,769,149,535,265,677,746,207,74,612,968,728,325,74,46,972,789,252,312,406,737,475,227,477,856,888,808,776,101,560,876,320,263,977,777,841,505,44,948,265,585,128,240,415,849,980,199,795,27,144,519,31,666,940,168,97,99,384,928,514,571,79,207,291,867,535,884,949,965,598,421,960,594,45,966,157,357,619,750,47,696,616,928,544,503,715,391,132,772,660,14,486,635,756,962,598,791,0,74,66,682,746,305,516,405,275,97,495,480,826,275,463,685,977,451,945,325,727,548,233,730,840,157,195,447,412,864,517,577,35,802,751,258,572,853,706,693,609,649,853,480,786,945,625,461,587,743,771,362,722,920,36,654,29,775,705,283,510,895,785,776,448,683,188,164,816,788,335,485,216,864,839,185,857,892,809,9,465,745,58,942,483,598,180,372,177,724,579,990,573,121,986,479,617,309,406,643,646,287,61,685,962,813,476,222,628,543,802,370,276,598,111,857,218,442,605,126,40,249,399,153,80,382,667,749,841,990,251,187,319,85,57,887,597,924,469,213,329,99,151,581,172,682,305,996,373,592,160,222,939,950,408,398,235,117,446,279,563,704,73,424,493,103,989,146,5,281,159,155,963,150,298,588,431,189,743,211,121,762,356,722,283,619,347,484,257,634,666,247,632,368,329,860,818,438,209,899,999,324,799,407,515,100,121,896,85,683,758,428,910,816,424,796,756,819,578,219,311,98,360,434,375,578,490,589,558,902,231,893,540,190,895,294,25,375,537,503,788,691,285,859,621,825,391,404,338,452,630,361,493,78,535,37,461,503,412,274,126,751,187,248,365,46,60,825,961,262,846,15,430,408,453,471,11,955,344,26,447,930,482,612,148,842,902,937,657,681,179,339,629,618,405,295,964,38,245,799,950,57,952,122,560,757,649,342,387,68,84,914,446,710,51,991,113,29,635,334,492,217,141,610,841,213,425,29,556,591,660,710,866,756,52,969,763,694,511,190,13,867,978,22,436,507,351,402,123,749,108,743,839,155,133,164,539,522,827,380,43,712,769,634,242,267,296,959,736,900,437,80,285,3,44,885,737,32,202,122,50,326,935,77,229,698,664,39,684,795,322,634,955,230,421,243,248,196,257,758,383,593,964,45,839,541,388,794,475,478,550,902,202,467,121,316,333,854,597,165,473,947,513,652,821,883,290,34,273,861,501,678,484,397,515,633,857,339,592,957,607,92,794,580,450,277,992,108,964,542,773,247,79,993,953,626,865,502,71,607,121,452,282,844,40,933,360,921,733,125,360,514,29,32,886,692,805,720,19,817,749,626,516,951,873,4,43,432,994,91,28,606,550,806,760,551,431,941,302,409,741,648,69,353,419,12,619,262,720,922,946,639,93,733,918,110,387,716,717,282,835,329,770,672,130,529,507,290,715,5,132,344,99,416,304,462,425,767,694,223,744,988,574,889,13,316,866,475,301,683,949,811,680,460,853,851,761,151,647,46,423,511,377,326,689,298,800,832,718,696,581,530,137,688,311,292,44,28,267,161,272,215,599,990,436,671,917,190,642,420,917,223,794,539,168,606,872,501,104,791,796,202,11,758,976,397,157,183,722,966,222,763,412,811,340,79,469,278,186,401,70,896,761,661,994,894,585,325,149,281,677,230,614,947,205,628,806,461,941,717,951,130,429,782,52,623,249,919,120,571,906,634,695,783,506,163,501,584,831,724,951,26,802,541,656,582,927,72,406,527,819,135,64,771,257,431,173,170,538,594,780,402,195,573,164,661,428,446,875,262,89,87,593,750,906,905,469,198,395,933,546,834,967,377,633,278,3,474,911,806,975,382,865,361,237,931,594,351,7,879,981,964,557,23,289,393,765,538,891,620,99,932,929,434,759,45,47,332,606,52,569,461,646,415,971,329,623,847,143,650,820,109,252,707,841,251,185,733,319,629,259,99,668,4,332,264,25,283,742,949,943,701,286,189,214,657,780,825,328,719,328,839,348,224,755,280,788,405,905,320,769,816,391,399,393,867,596,510,289,986,308,644,695,37,57,244,774,527,825,458,738,799,751,861", "873,960,457,808,563,409,895,731,631,850,204,323,21,392,890,511,67,493,244,862,176,590,481,237,361,441,291,204,223,345,973,450,794,336,362,191,604,210,147,866,610,813,219,357,230,977,838,692,70,912,499,145,349,11,668,88,685,652,6,585,523,400,381,254,397,175,700,168,193,153,266,731,492,489,928,752,488,640,997,63,540,974,745,384,813,528,140,436,904,740,288,770,212,665,258,120,443,967,652,312,755,177,622,645,384,913,532,702,508,556,269,358,738,784,640,898,719,30,290,808,446,92,976,133,235,956,138,276,800,489,438,411,582,183,103,180,399,850,881,890,491,540,486,452,714,242,29,695,118,627,988,816,565,134,512,356,217,954,25,659,339,810,384,222,391,739,347,579,641,875,896,300,449,332,373,546,400,692,691,522,750,959,139,559,471,830,74,0,802,974,933,601,728,774,807,532,5,335,476,642,373,556,958,405,332,305,433,957,305,832,598,94,626,303,81,779,778,437,793,709,756,973,486,817,400,349,621,123,85,296,213,788,811,105,506,682,857,974,998,99,636,266,828,971,605,204,563,801,824,799,912,423,447,55,188,112,51,70,32,963,386,826,907,734,274,723,951,584,359,722,777,453,218,738,428,299,489,720,22,671,976,549,661,487,652,734,218,759,315,649,282,944,344,322,769,953,227,516,560,752,904,543,479,61,153,172,180,426,338,634,460,42,151,240,228,964,209,920,8,502,326,548,957,777,375,657,794,794,751,66,44,779,545,870,177,97,458,174,434,953,93,859,269,421,308,894,536,504,62,710,269,726,536,119,406,408,644,10,240,58,731,528,433,103,344,98,459,212,35,837,751,738,820,491,766,702,292,60,641,9,123,676,617,762,878,390,670,451,859,155,654,600,321,947,688,994,38,256,106,990,983,868,794,459,287,328,449,789,743,377,957,412,152,693,494,816,987,136,486,613,903,473,43,234,615,409,483,443,336,206,405,645,25,178,126,921,162,307,318,87,508,819,626,633,446,181,709,315,581,666,747,250,137,834,239,533,940,219,948,176,263,54,349,937,991,345,724,580,563,668,982,256,282,460,701,339,567,195,382,927,449,497,125,81,129,82,947,786,657,556,148,124,157,585,278,480,716,46,537,175,475,136,247,978,261,506,777,757,750,738,264,247,373,961,34,798,294,534,567,547,817,21,523,391,672,137,811,644,532,913,23,540,741,208,715,808,688,798,980,255,115,492,434,96,583,399,814,114,74,881,818,930,7,343,953,446,925,708,97,925,126,886,785,980,908,674,735,139,268,740,30,526,402,288,579,836,118,403,597,9,131,698,193,86,479,594,442,705,844,366,699,644,336,708,693,809,822,34,910,230,182,928,636,716,219,836,76,796,62,480,930,868,993,68,380,819,693,776,212,657,96,127,865,763,631,80,445,659,112,223,947,792,515,439,70,560,766,661,896,172,835,872,935,44,942,831,570,550,906,586,952,170,842,548,255,464,665,594,467,341,878,897,451,408,423,780,755,923,380,327,968,542,8,7,307,604,347,720,105,641,853,5,377,272,926,680,176,772,862,855,708,292,939,691,841,206,545,565,764,488,887,847,947,565,226,366,934,146,673,695,84,354,751,192,309,603,316,387,160,134,307,905,820,767,465,251,464,483,755,243,686,175,31,145,764,10,687,23,594,749,680,896,792,75,762,399,715,757,223,597,570,868,921,257,103,290,245,60,843,899,325,115,168,93,338,97,970,832,407,561,933,66,776,172,675,871,478,612,699,881,877,564,241,538,243,941,81,759,628,64,381,657,994,500,679,181,100,386,616,622,971,879,650,895,827,580,975,458,64,99,780,575,702,250,579,222,387,246,211,62,638,261,799,570,336,12,792,196,29,598,820,432,223,825,152,202,996,94,871,742,39,744,947,713,869,415,751,938,421,386,268,114,284,424,846,885,26,691,479,302,876,571,888,312,329,961,25,330,261,870,222,342,290,985,746,669,432,798,307,82,234,361,407,191,551,418,812,217,894,626,57,860,338,141,395,779,867,523,864,562,14,454,267,640,561,984,285,669,105,844,133,795,415,527,489,664,331,413,979,373,690,32,330,358,886,917,608,725,417,122,337,476,737,746,895,946,732,888,390,333,839,384,182,295,278,301,205,921,231,486,196,894,250,162,442,845,417,646,853,679,961,139,210,388,895,982,848,698,142,591,965,938,222,450,668,181,411,661,321,230,187,751,144,707,191,972,112,147,478,615,128,749,530,570,518,3,605,538,28,884", "8,488,259,973,165,222,212,795,658,870,897,817,927,784,774,494,235,166,920,238,926,598,421,653,395,296,454,785,178,759,548,144,186,935,988,699,372,974,787,540,235,356,220,900,181,958,348,305,150,86,851,908,405,60,186,288,534,992,627,550,495,761,613,38,742,900,972,576,20,490,2,610,596,499,660,555,260,123,695,942,215,953,534,869,942,39,782,965,455,539,825,636,464,739,677,430,727,166,850,846,537,848,147,576,791,658,653,994,730,849,354,575,717,804,187,306,290,805,646,554,900,413,785,502,475,980,229,84,233,916,255,132,397,295,440,602,298,142,290,809,153,247,453,496,737,555,33,394,847,691,215,478,568,819,649,238,655,964,2,462,916,640,945,917,591,601,526,729,88,230,539,392,798,618,354,350,508,284,380,270,353,180,242,52,828,20,66,802,0,458,815,870,397,298,404,829,650,961,811,926,795,629,425,313,930,96,875,555,514,747,465,73,744,364,458,565,76,572,207,607,969,379,791,180,825,684,429,423,132,638,404,550,237,761,597,520,648,326,860,391,617,865,614,93,51,454,525,396,310,471,349,385,318,576,591,132,197,38,162,456,830,891,47,632,108,968,297,163,792,717,344,118,746,500,24,389,529,644,313,861,251,916,753,576,365,729,133,773,28,948,789,998,137,66,642,778,351,174,672,265,329,225,987,540,751,318,94,258,870,726,394,988,572,510,106,24,195,859,236,795,977,599,122,857,48,95,336,39,280,538,703,989,196,522,284,681,962,285,281,851,955,462,481,747,661,110,165,979,288,147,538,891,498,742,232,288,900,625,842,56,812,654,967,462,935,826,493,955,399,775,287,686,96,42,860,256,425,561,785,823,191,965,963,604,718,814,290,934,656,25,755,435,35,59,434,617,346,111,597,968,455,417,472,157,30,829,788,226,55,580,575,327,135,94,893,757,226,295,801,934,992,588,45,791,948,949,810,229,498,852,191,709,372,606,762,80,192,634,869,358,926,162,201,470,238,686,748,341,702,278,745,835,950,257,809,357,756,870,931,448,186,464,554,829,359,95,913,661,410,529,586,767,468,438,215,736,582,943,324,286,43,534,907,36,975,258,86,618,670,878,135,978,920,802,281,552,622,303,386,351,332,781,73,438,314,311,72,517,3,499,548,672,285,992,759,859,116,88,868,324,520,614,812,352,777,615,724,477,833,945,587,360,54,582,20,446,967,604,731,390,407,851,205,186,988,8,576,314,520,273,641,285,887,453,793,326,754,69,491,825,120,210,950,469,986,784,762,685,17,373,184,875,839,367,300,661,894,483,873,121,774,655,902,450,938,337,991,380,974,349,547,265,108,184,206,246,230,483,182,22,198,292,841,712,213,884,748,142,474,604,555,484,835,917,672,637,377,626,395,153,162,82,830,879,84,473,97,811,131,272,120,247,583,702,309,950,863,704,803,255,133,154,540,587,133,167,23,854,711,186,341,290,980,60,581,163,494,45,817,571,566,403,529,46,904,941,453,865,632,312,275,326,451,233,737,520,586,820,150,614,759,427,993,521,387,204,9,640,420,158,398,616,649,355,536,311,41,720,24,642,877,136,599,2,978,594,46,949,328,763,19,933,177,10,97,733,139,63,155,881,277,298,981,57,242,307,257,583,151,647,504,620,744,603,927,512,328,404,2,172,974,821,849,736,414,126,767,56,343,264,182,455,423,530,450,875,31,142,234,56,206,707,227,175,191,413,140,937,520,39,505,979,661,699,787,413,220,858,575,998,605,559,484,692,501,737,938,959,299,930,17,279,867,125,754,571,38,484,268,550,797,440,882,756,121,476,56,275,328,12,417,788,14,123,958,405,553,837,116,393,55,134,747,588,890,609,551,426,553,539,751,322,747,44,963,28,551,32,67,689,889,139,474,487,178,959,200,670,968,45,709,778,500,927,256,511,141,853,365,631,759,143,118,877,828,557,64,849,778,644,296,317,662,734,387,851,468,264,351,936,922,623,83,199,621,588,562,872,366,530,494,856,835,250,607,800,821,756,473,521,697,601,847,857,416,4,338,587,240,569,869,97,93,120,54,308,372,661,932,378,271,234,819,399,30,124,36,145,854,527,271,486,655,378,783,874,92,816,351,397,968,219,278,186,29,427,915,822,613,495,701,156,657,459,38,284,485,62,237,593,153,105,906,35,201,647,6,996,613,353,620,735,856,739,114,537,698,420,887,561,802,573,274,834,571,267,886,251,158,212,549,437,420,205,600,743,559,621,892,472", "708,452,348,66,217,559,873,633,639,876,506,498,892,791,460,786,220,574,199,666,793,622,25,41,182,783,24,203,899,95,108,74,78,994,98,726,487,650,89,461,262,780,214,742,299,190,152,396,803,371,521,207,622,390,263,419,234,187,541,879,88,37,428,98,600,639,305,551,811,288,101,198,739,278,428,237,824,34,788,565,992,625,667,184,620,998,311,379,204,508,550,905,972,832,431,474,266,430,77,286,921,563,425,560,929,856,240,658,500,620,199,175,853,873,668,826,16,389,931,596,198,271,274,752,478,212,636,161,996,101,569,197,900,23,206,38,881,425,586,122,860,665,578,950,576,434,28,57,333,541,727,465,294,842,622,669,290,494,156,334,300,292,264,157,194,93,303,763,890,690,468,588,124,67,651,216,552,625,67,969,196,317,491,410,895,696,682,974,458,0,985,781,86,383,638,451,374,60,904,401,587,877,814,928,813,15,229,932,949,914,910,362,225,837,567,145,859,343,69,849,474,503,703,763,671,492,980,399,668,410,429,874,426,826,16,471,567,390,258,663,192,902,949,281,473,492,174,993,72,899,381,908,191,558,607,110,998,191,431,843,974,701,346,995,34,764,671,197,773,801,742,782,70,649,412,704,525,286,700,477,413,741,969,876,647,417,336,152,982,574,965,710,544,662,781,93,985,213,880,207,881,427,751,141,458,993,46,420,936,382,785,392,594,129,708,766,5,309,346,293,77,115,595,65,676,175,545,501,374,152,435,473,234,912,446,399,676,705,818,429,768,503,993,977,440,685,890,521,976,961,146,668,644,796,929,109,84,694,950,15,573,161,248,606,9,13,321,207,265,449,189,13,13,280,576,847,463,561,227,109,1,620,597,369,528,326,798,385,258,182,817,980,36,305,927,588,178,184,679,685,718,665,406,260,851,684,405,366,708,874,777,218,649,231,301,815,841,483,650,959,934,9,87,365,516,391,918,487,263,296,79,450,92,409,671,730,85,176,349,948,456,470,746,926,687,781,230,202,721,144,280,548,453,452,432,213,642,164,423,540,817,445,923,137,346,779,411,753,216,497,426,681,23,380,203,293,97,311,222,706,177,526,89,68,636,604,943,991,752,701,193,191,340,208,574,886,3,424,78,867,97,566,150,66,967,711,510,796,675,165,318,685,225,874,263,744,148,986,491,678,182,250,815,72,218,90,968,337,79,44,332,749,381,570,909,273,955,626,948,589,636,165,568,121,526,67,640,871,723,183,837,162,216,432,96,286,586,808,113,88,903,393,134,795,594,208,796,708,670,221,993,867,696,96,314,904,636,179,240,144,211,21,937,563,934,402,440,185,671,831,169,73,42,71,967,563,999,200,786,931,862,51,46,330,431,276,566,145,489,164,993,608,479,801,242,404,279,750,18,341,206,710,356,605,198,705,795,648,768,872,981,568,811,796,522,234,312,219,915,371,945,687,286,531,920,916,116,532,828,769,227,554,371,576,740,660,126,926,981,63,324,409,391,204,595,960,967,635,869,802,404,899,977,453,709,966,450,378,422,165,630,332,979,505,651,520,965,572,44,121,783,241,145,8,130,659,563,883,501,504,500,996,634,791,193,363,576,564,592,890,201,703,941,604,777,452,775,894,71,981,154,256,231,24,109,878,158,915,426,462,572,919,23,534,464,91,936,828,344,175,426,998,616,931,983,561,930,896,494,188,150,180,199,904,419,756,260,330,278,917,97,489,401,214,931,698,944,516,632,729,207,475,59,703,93,381,287,92,825,401,711,355,530,976,283,355,730,994,499,686,269,320,925,286,317,213,901,506,127,332,887,51,52,186,623,203,69,585,267,316,787,152,784,891,435,766,757,62,925,833,516,525,806,860,794,925,634,411,416,123,565,737,193,839,977,234,580,490,444,362,963,909,455,797,846,570,3,838,336,458,629,877,114,746,568,577,245,74,956,579,820,212,840,341,78,527,852,790,297,869,625,742,815,96,41,388,216,786,240,444,912,681,493,262,344,783,260,736,260,570,654,706,474,50,281,384,831,361,801,260,365,601,590,133,417,47,567,123,374,612,53,590,328,844,237,287,752,958,45,569,91,910,402,54,574,241,666,547,212,504,412,836,643,287,326,814,297,148,821,401,515,886,987,394,993,470,491,736,589,662,802,639,817,676,555,320,922,348,770,9,929,77,206,153,154,420,971,688,662,643,82,539,550,458,476,728,866,198,682,367,970,478,787,195,579,525,433,347,738,530,83,904,565,847,161,147,16,294,476,531", "268,407,990,918,116,641,589,419,993,109,84,670,512,25,506,913,452,972,6,842,482,648,297,151,810,735,619,529,708,563,549,739,331,680,130,296,231,309,348,815,500,266,636,761,603,547,543,578,700,138,930,718,650,521,520,617,114,478,797,770,353,119,794,787,190,549,445,91,760,762,140,845,646,102,924,709,324,727,620,639,360,564,138,219,434,181,974,620,922,700,674,908,708,915,624,640,934,535,788,250,975,657,495,765,723,853,601,8,152,868,989,666,248,714,818,42,819,488,752,461,290,179,451,715,700,932,897,309,765,344,929,821,625,87,570,452,620,148,866,198,257,62,15,385,651,477,207,670,418,814,245,183,331,113,314,768,488,60,522,589,504,650,68,193,660,133,188,307,730,318,777,431,387,726,541,393,142,615,613,432,39,426,941,774,121,707,746,933,815,985,0,626,305,965,764,631,227,597,297,114,869,367,709,588,607,842,222,858,36,48,484,940,654,759,220,359,173,52,580,773,638,749,348,952,510,597,123,188,879,773,397,310,815,395,288,799,322,442,827,48,895,911,837,280,195,664,682,720,750,464,292,410,632,369,550,916,838,909,348,730,141,82,601,588,50,860,757,532,206,680,751,821,949,8,629,840,617,155,330,80,519,284,63,466,171,203,804,815,57,367,515,461,687,838,255,546,205,201,281,451,180,737,708,935,883,25,735,62,888,239,238,662,713,586,134,877,639,910,631,521,131,379,803,712,443,106,23,452,804,857,41,618,776,422,313,555,106,975,905,449,984,204,649,82,517,142,604,503,193,650,874,609,432,288,621,601,716,150,535,486,411,743,539,640,290,871,948,774,135,650,285,984,514,935,291,164,959,346,633,750,980,786,763,263,723,358,210,92,747,21,405,263,760,653,203,558,405,102,616,234,535,488,218,701,51,308,68,341,840,605,271,841,646,259,482,370,906,405,515,715,872,401,791,533,856,60,866,553,369,605,276,946,135,593,245,62,230,863,172,895,562,169,462,835,53,518,900,447,867,930,758,757,600,419,759,55,598,741,138,298,910,735,228,691,938,365,407,493,171,45,944,513,807,803,434,420,194,370,702,504,557,671,597,839,302,156,819,295,427,92,248,907,46,621,64,798,819,593,394,706,719,677,959,211,394,671,668,510,282,27,406,375,387,931,832,594,512,511,844,123,501,778,789,576,937,370,182,207,427,629,894,778,171,485,411,239,745,452,163,205,168,473,43,267,403,265,779,859,114,466,793,294,932,273,79,392,768,308,477,912,367,582,671,857,650,996,66,76,110,359,274,338,913,687,982,250,441,350,146,683,920,627,111,390,853,502,111,359,409,803,708,667,161,826,815,368,247,504,548,791,674,199,515,928,455,266,916,676,358,830,562,926,928,612,873,637,934,970,668,740,925,224,480,704,913,874,951,685,905,677,691,422,740,409,278,503,784,354,816,344,846,304,860,502,28,300,696,457,631,922,842,551,739,619,699,728,559,448,926,367,691,357,314,194,889,651,271,123,579,669,395,337,357,999,183,948,971,85,692,621,414,822,735,419,775,130,953,667,766,912,42,466,588,291,255,286,168,309,437,500,428,946,848,286,639,316,128,352,991,681,28,660,873,760,195,640,302,886,95,530,117,592,60,461,717,299,405,295,568,585,521,480,919,315,545,304,74,320,505,962,906,89,811,806,160,83,191,159,919,385,764,777,70,187,711,930,55,231,204,326,417,611,339,652,338,687,39,8,511,832,770,555,72,396,163,990,18,87,130,764,314,362,142,104,609,220,130,685,594,701,888,864,190,279,901,635,67,385,266,486,284,901,483,575,819,26,639,954,630,53,295,998,15,355,362,793,130,853,820,890,43,384,571,200,887,476,727,527,904,434,215,166,830,887,718,206,733,526,675,916,14,316,55,517,979,232,859,81,761,366,221,278,278,265,622,217,169,178,705,861,101,29,943,572,657,548,769,542,975,938,540,549,435,323,891,120,571,187,916,938,285,220,386,841,34,121,842,323,320,649,588,42,170,144,866,454,352,547,741,86,314,973,57,552,245,924,31,861,476,516,24,698,708,614,753,893,338,195,185,605,594,339,262,722,175,781,595,113,884,312,968,264,915,151,691,416,871,946,246,421,594,243,683,733,300,171,597,421,867,518,579,96,426,548,666,127,190,388,668,132,391,141,680,859,687,784,228,742,374,760,574,662,503,143,638,884,74,791,788,917,546,246,593,409,293,465,424,344,672,299,200,385,708,651,165,392,360,298,749,503", "177,844,365,456,528,570,171,666,433,984,563,61,908,517,905,467,676,223,186,448,762,440,433,685,423,702,846,807,708,765,226,614,572,386,926,313,663,539,107,613,581,472,560,540,714,14,956,85,571,484,284,845,337,144,417,24,333,541,308,639,521,272,415,58,941,386,253,423,408,497,557,467,602,937,117,268,954,104,432,202,387,210,121,833,762,19,65,896,329,526,352,259,136,715,847,893,870,401,637,838,1,642,133,756,87,700,624,732,82,294,622,368,33,37,932,612,795,758,34,533,56,252,785,494,89,628,574,620,140,899,928,255,73,354,687,235,702,499,471,16,976,105,517,205,839,766,577,103,617,419,574,760,696,196,89,383,429,58,986,655,415,522,806,29,899,676,150,223,292,45,173,717,703,134,911,539,221,545,191,851,471,496,745,598,62,593,305,601,870,781,626,0,144,701,517,577,190,386,432,528,664,914,369,11,544,674,34,687,757,223,574,264,537,501,208,679,618,700,259,981,480,351,904,648,15,985,530,759,231,428,341,457,10,629,222,303,186,845,191,54,822,176,613,690,966,542,221,81,436,757,313,288,413,244,522,700,420,258,856,351,925,350,532,984,451,335,551,341,683,577,412,391,498,478,432,340,115,822,962,253,930,456,213,80,232,544,455,625,549,10,485,869,697,605,444,677,153,681,359,775,715,73,685,679,887,132,331,176,229,973,894,110,897,171,801,954,116,656,834,41,411,175,972,603,346,20,839,5,695,841,186,271,248,337,946,246,323,749,874,960,483,725,258,684,298,992,279,568,366,279,810,650,939,583,186,49,696,718,305,22,489,983,135,262,97,612,65,818,672,276,213,450,93,884,777,259,485,61,134,392,381,882,886,66,144,356,334,806,560,317,355,822,133,721,71,608,221,465,857,601,646,910,627,867,646,134,151,98,352,38,359,812,235,326,122,876,117,990,788,22,308,952,599,213,509,577,829,803,663,620,987,271,579,479,465,732,51,947,839,784,181,215,779,909,58,706,908,984,665,607,976,638,948,556,165,874,873,582,182,488,629,295,415,524,441,687,512,662,53,953,965,370,171,65,875,340,298,457,339,77,287,443,632,897,408,26,533,732,175,334,814,639,458,508,748,849,100,263,93,428,762,336,184,145,596,631,480,947,450,885,30,931,668,147,229,796,393,642,486,830,316,85,57,232,831,877,381,826,249,609,874,795,558,325,553,939,426,872,294,183,121,756,832,529,85,781,882,233,538,91,229,14,711,725,760,718,21,685,818,76,531,547,491,327,628,568,600,434,504,286,96,886,39,321,811,832,453,389,95,343,452,713,434,588,352,209,571,331,987,486,357,634,852,886,663,483,20,407,462,960,69,22,443,585,900,770,607,721,219,457,692,686,149,304,70,961,23,875,577,65,926,451,782,303,290,944,171,663,247,194,66,724,385,809,508,629,55,94,72,785,286,219,475,915,512,778,174,668,774,887,852,307,172,768,3,743,341,227,454,464,15,730,503,437,835,250,306,964,382,489,866,150,834,351,613,209,303,535,465,843,210,476,109,195,185,96,859,613,600,416,395,791,287,852,108,993,329,468,61,33,908,618,524,18,961,312,463,184,14,568,340,728,753,807,739,97,72,599,53,420,990,576,918,271,507,244,836,326,105,740,437,679,510,98,252,100,708,551,881,296,936,767,548,14,193,215,78,298,522,680,621,167,480,157,389,359,240,853,445,289,430,441,284,954,474,33,839,47,822,247,99,95,928,706,276,834,207,74,923,203,292,444,777,242,105,814,974,546,745,961,694,315,353,293,150,178,76,968,921,849,23,881,922,508,302,202,979,943,586,9,51,717,241,570,66,381,9,50,403,484,317,520,474,78,700,375,295,247,701,640,274,761,120,157,162,43,329,33,424,502,838,334,507,755,143,746,893,270,817,994,75,520,596,91,40,799,893,151,399,813,164,373,640,61,500,719,224,241,868,452,140,251,607,284,7,26,458,44,136,420,827,498,619,998,975,398,828,354,624,780,852,754,730,798,804,654,40,931,538,339,395,367,421,782,439,437,278,701,838,766,48,117,844,327,809,119,899,153,365,768,849,716,375,47,525,846,997,429,376,781,513,553,65,486,363,796,404,552,379,969,435,551,750,433,947,537,584,764,344,210,853,12,29,847,722,172,449,972,500,464,95,638,671,674,584,295,519,675,123,824,180,958,334,206,533,389,988,468,355,667,679,97,724,480,898,347,877,769,200,552,492,154,422,812,395,638,207,456,409,973", "722,390,284,370,285,185,625,491,715,273,739,545,721,115,286,697,32,418,808,591,885,791,486,240,345,991,257,618,511,416,185,318,794,325,766,526,525,615,810,391,253,345,410,240,486,329,811,196,636,350,251,694,361,941,898,500,200,39,103,867,370,647,381,132,820,39,163,241,875,844,367,840,532,279,222,638,791,483,565,426,131,187,791,781,361,271,499,118,919,805,246,818,986,281,821,57,837,429,491,455,52,476,488,732,261,897,215,768,992,375,213,726,150,764,440,722,892,437,578,393,379,656,240,435,273,64,794,94,301,159,93,172,745,201,396,820,872,482,884,225,432,425,702,707,626,635,731,610,962,950,373,912,461,482,291,705,915,680,628,876,33,628,395,995,49,364,944,351,536,349,756,342,670,612,200,77,353,523,415,424,428,519,315,786,944,965,516,728,397,86,305,144,0,641,310,951,324,847,137,484,150,320,951,695,93,881,62,315,213,63,665,426,119,470,781,585,866,727,636,640,387,959,617,89,339,269,10,327,468,766,409,713,447,493,146,361,332,910,491,928,685,537,242,700,651,469,154,195,216,668,785,340,708,67,930,149,278,427,113,536,225,306,872,343,67,61,50,569,219,438,818,813,268,263,893,678,99,620,855,516,93,22,762,414,863,301,924,161,129,246,969,776,494,319,57,191,169,953,982,355,263,429,588,69,964,12,399,150,688,55,412,511,431,574,873,329,501,69,487,228,149,377,491,900,404,687,443,154,292,818,814,959,377,605,151,623,412,882,34,689,66,109,915,435,568,446,603,151,244,309,29,845,954,760,707,879,287,791,622,868,290,675,979,453,173,499,559,649,367,708,99,456,783,20,205,72,780,483,677,692,473,196,137,880,23,827,76,305,468,646,898,459,465,487,19,104,222,667,402,574,520,812,845,319,74,998,771,590,951,967,99,548,523,753,983,203,73,430,704,349,674,888,522,41,68,287,478,512,238,667,578,981,950,341,135,430,769,346,320,607,408,144,372,50,781,964,438,469,428,5,42,345,809,482,507,227,727,605,207,488,970,562,34,546,319,841,263,315,224,932,19,136,972,816,499,808,628,182,744,476,549,420,6,29,644,542,348,873,921,617,153,845,328,691,489,39,488,520,758,821,246,633,951,395,322,650,259,427,741,838,517,595,40,714,731,499,547,306,870,539,289,812,709,918,591,800,173,376,948,320,797,599,375,944,69,442,193,663,847,149,637,561,778,153,372,511,338,374,321,387,225,528,622,98,150,434,783,284,37,550,384,571,634,65,187,893,599,631,8,584,38,541,967,272,246,445,769,943,333,658,864,586,346,226,74,871,505,972,769,229,547,331,82,863,408,137,256,313,756,221,915,392,658,613,609,885,358,226,352,413,240,339,278,654,883,441,824,779,754,493,982,389,792,175,158,225,528,419,59,717,59,757,510,317,362,174,344,88,726,930,805,754,443,631,962,799,166,956,25,862,23,80,851,508,836,434,334,729,389,383,775,275,255,796,187,891,166,397,334,578,490,805,176,809,46,214,901,414,868,272,773,752,784,720,57,369,108,315,256,947,78,679,414,603,357,459,573,388,670,592,94,154,194,691,112,418,939,554,489,851,300,97,497,767,926,706,488,928,674,42,883,266,495,88,7,184,690,446,695,962,109,779,482,985,661,52,394,539,926,987,51,713,105,210,983,334,522,36,514,346,901,602,286,723,926,385,877,122,322,220,302,274,94,585,759,644,778,106,266,811,862,481,214,680,386,628,902,729,352,15,578,704,231,968,852,551,888,767,211,414,392,551,921,384,971,678,401,250,35,509,390,89,934,384,567,526,598,224,969,812,646,394,114,368,521,954,400,807,736,689,441,785,634,334,552,909,708,448,390,641,128,678,874,257,149,516,920,671,94,490,980,964,88,58,228,175,130,157,503,105,238,597,405,73,782,205,242,544,893,638,403,658,251,547,771,42,55,224,847,731,732,461,874,471,848,348,253,59,714,513,635,230,872,94,840,626,862,256,445,409,370,505,251,542,205,964,679,64,583,394,341,98,681,678,879,742,73,615,240,53,702,553,262,22,118,744,122,166,316,764,508,775,523,599,476,18,397,697,318,831,598,439,102,383,505,876,614,536,769,966,854,110,378,502,78,599,578,856,313,406,277,143,974,763,43,897,273,679,267,332,429,677,149,171,805,136,543,626,366,403,72,346,114,54,264,438,192,537,20,588,151,698,11,368,946,191,421,631,406,923,653,565,779,48,637,777,421,253,944,116", "49,619,260,723,413,33,558,146,489,167,84,837,508,576,538,889,838,517,652,822,147,620,417,260,389,787,878,869,295,849,560,663,123,247,817,674,258,992,944,678,592,339,288,852,954,885,419,939,126,953,487,909,352,899,267,68,953,464,708,840,545,442,401,737,336,350,243,605,396,760,893,335,436,620,948,894,715,21,725,142,500,110,821,911,974,401,257,40,631,459,237,820,390,278,514,234,807,72,319,214,30,742,894,905,489,808,785,957,1000,558,583,819,524,81,11,711,67,161,810,710,363,230,691,492,595,876,178,129,90,210,965,736,713,487,412,538,326,922,270,849,764,14,507,150,688,815,486,282,571,360,544,964,31,10,859,304,332,644,16,874,512,333,974,725,409,625,494,860,840,650,839,392,50,462,50,940,203,889,173,743,85,111,424,929,171,160,405,774,298,383,965,701,641,0,834,959,886,542,142,240,469,722,959,583,773,447,624,340,352,853,222,488,680,131,191,90,344,307,448,899,640,40,760,188,880,466,606,138,835,155,179,372,348,842,334,930,313,186,189,690,346,548,464,532,709,7,543,989,925,660,425,82,700,395,695,517,269,705,528,784,561,833,51,498,958,378,61,549,389,226,415,573,876,658,903,160,586,903,897,476,202,808,376,744,473,888,75,785,98,660,527,588,611,946,488,18,932,891,623,625,498,132,547,196,773,787,165,535,734,777,362,290,273,102,563,513,579,916,317,799,740,717,884,198,207,262,209,866,82,331,494,800,685,950,908,411,988,878,698,748,931,810,404,747,611,286,334,925,495,467,969,506,811,61,799,240,144,459,413,378,229,807,871,273,626,80,533,806,760,82,416,148,954,211,734,475,666,581,516,76,47,359,515,962,99,760,358,647,913,956,178,621,508,926,838,937,414,725,358,497,312,103,416,190,783,506,155,779,123,854,198,860,897,79,54,170,831,219,258,694,890,56,233,89,800,434,398,436,590,182,515,421,266,476,652,824,491,235,868,217,714,857,16,111,752,195,520,770,52,83,425,266,626,269,93,494,901,618,68,612,927,987,666,739,578,181,278,711,374,95,883,409,151,210,300,391,220,363,984,252,489,641,283,173,827,494,107,993,226,364,430,136,981,493,553,938,313,703,534,471,665,678,99,944,468,329,532,840,947,262,24,353,992,837,987,464,871,465,874,94,856,907,133,492,20,884,729,738,164,629,770,536,240,707,294,685,397,535,617,62,402,730,402,313,288,597,254,780,810,211,665,163,260,658,868,672,150,317,684,797,646,47,644,4,822,865,516,655,459,54,414,96,514,225,380,909,706,637,713,499,555,519,862,604,196,968,992,943,24,624,257,908,267,126,351,816,637,638,19,842,948,904,345,459,895,102,766,926,670,186,919,994,412,609,852,100,384,695,352,189,903,343,286,953,364,194,561,962,36,126,100,737,891,589,899,16,583,731,293,44,38,707,692,905,772,22,796,175,766,193,896,304,418,474,356,752,781,320,935,68,725,594,797,341,119,325,452,416,190,755,119,117,692,803,731,568,871,482,512,724,761,15,570,153,514,388,721,92,810,675,576,253,217,922,808,106,911,247,411,558,401,186,920,887,396,337,541,727,8,925,353,552,880,624,540,371,289,983,59,80,511,782,952,345,864,714,416,670,159,399,199,215,341,279,606,595,959,80,107,371,848,294,333,36,516,262,819,327,874,73,485,748,865,440,679,944,375,868,180,642,550,493,261,484,629,789,905,905,127,936,332,61,944,887,746,249,718,150,659,385,403,501,737,548,396,657,48,587,118,509,784,765,139,823,791,16,331,600,933,722,449,221,848,928,194,72,212,735,878,610,154,718,871,915,996,857,974,454,87,9,390,794,855,430,99,32,297,846,384,853,480,432,333,32,772,192,442,927,115,910,974,611,354,541,660,699,745,835,950,839,592,353,933,713,740,78,463,139,760,883,202,714,986,883,29,499,993,111,35,254,661,447,200,825,855,289,693,598,268,902,334,640,487,438,649,15,409,85,156,939,957,679,19,112,87,95,829,456,240,784,730,935,326,506,683,863,894,877,680,121,243,471,608,560,531,71,247,974,738,985,476,687,787,369,438,125,713,218,248,541,909,156,220,121,815,427,873,338,264,933,49,780,86,198,104,683,800,412,399,661,908,976,266,751,328,75,284,827,522,543,953,207,967,342,713,300,794,859,668,574,612,525,572,97,651,242,897,641,175,682,193,159,566,329,913,605,266,787,822,206,720,121,30,102,937,959,314,486,541,849", "448,477,652,118,431,389,770,905,956,528,710,327,346,414,744,413,494,407,82,228,945,963,202,169,604,460,116,230,101,512,344,82,941,744,865,299,305,825,750,88,167,742,828,239,737,23,879,384,294,500,706,240,784,572,715,502,489,976,910,264,778,814,743,374,19,197,904,399,401,53,823,860,285,913,778,235,552,261,746,197,813,517,27,509,828,808,615,974,917,696,218,750,683,804,150,427,972,836,384,982,338,187,325,397,20,513,433,239,651,292,332,733,206,800,256,841,82,731,388,885,901,650,939,237,257,270,560,725,950,976,543,192,983,189,164,174,317,87,629,886,582,449,499,516,829,193,669,228,537,457,95,85,231,682,185,731,416,55,675,823,244,530,922,737,87,218,436,945,421,211,328,317,540,671,139,899,431,279,68,145,877,239,370,25,388,184,275,807,404,638,764,517,310,834,0,255,610,623,78,329,197,729,83,868,549,921,141,431,496,976,933,700,510,358,512,413,930,750,517,371,283,276,751,492,624,786,400,829,571,387,267,836,837,742,19,697,18,765,439,728,990,269,354,375,396,376,439,544,438,342,236,462,648,32,598,911,956,521,859,488,805,473,338,401,585,600,629,227,169,321,232,743,519,849,698,627,78,512,868,886,901,457,206,692,126,773,991,231,430,368,508,804,471,335,119,794,401,38,66,853,366,421,467,613,704,135,668,39,662,815,248,541,523,541,366,272,580,123,607,839,167,835,271,185,716,114,813,8,839,14,610,765,554,102,230,44,354,304,431,731,300,794,183,802,174,76,554,223,865,283,382,827,356,750,512,155,971,258,876,391,320,120,394,73,865,472,373,559,875,37,872,16,826,193,966,577,820,513,335,500,779,507,944,869,204,84,377,782,898,75,385,650,728,658,920,287,730,24,634,958,363,275,903,55,12,459,493,678,267,613,654,21,547,97,555,373,751,513,190,887,887,590,304,325,347,627,565,549,513,940,883,722,194,706,602,258,17,977,128,70,266,53,455,532,141,419,840,813,183,658,838,882,914,109,17,108,399,880,742,796,855,552,162,122,593,650,914,833,790,271,343,356,346,269,169,820,546,250,595,731,366,797,625,576,629,877,876,699,755,665,671,915,337,747,861,284,254,129,644,972,172,280,996,109,996,831,805,747,655,197,273,376,896,737,885,410,150,973,39,491,284,741,749,536,142,677,898,43,741,690,766,960,843,273,203,809,554,277,311,472,740,130,857,213,595,91,786,651,431,228,692,711,420,269,324,275,750,279,761,633,348,282,645,966,454,670,408,608,395,24,845,28,895,171,435,10,176,317,945,2,55,810,858,349,378,629,277,431,731,32,504,366,119,814,392,397,593,771,497,511,197,544,766,758,429,295,400,101,444,848,459,680,907,254,986,113,538,891,57,325,627,343,798,16,290,108,883,55,896,830,417,9,78,152,455,432,807,555,753,793,38,678,640,813,928,981,360,43,585,182,79,387,272,246,542,245,801,887,248,471,420,486,512,883,326,362,909,27,159,922,67,302,699,903,235,75,100,778,336,525,490,224,823,787,491,370,40,683,677,607,115,595,771,172,947,230,479,981,964,592,762,763,321,997,569,527,535,274,721,979,423,249,662,885,513,5,758,86,732,447,805,941,882,71,216,500,480,270,753,676,205,104,6,444,64,322,462,608,525,308,557,682,490,485,151,152,920,364,261,433,550,161,671,466,380,767,422,361,204,270,312,15,291,333,609,957,277,912,608,175,27,694,459,727,266,800,973,591,843,74,572,737,748,603,567,312,47,640,569,660,546,128,201,355,577,287,193,880,751,26,830,815,630,345,692,944,532,539,814,999,127,355,326,979,646,650,862,8,609,863,538,970,243,927,554,812,692,843,461,715,651,531,859,773,958,346,506,82,397,941,728,118,546,975,378,647,485,916,17,145,671,534,597,2,745,631,890,340,811,95,69,508,150,791,734,261,855,802,536,820,221,627,67,727,957,230,72,582,54,121,696,779,727,535,992,933,386,865,127,682,831,833,156,655,459,5,456,562,890,564,342,511,560,174,494,485,551,806,81,177,632,809,516,231,914,236,836,79,19,680,41,437,237,188,461,485,238,861,558,844,233,845,984,504,328,34,665,349,414,744,238,496,779,198,401,825,715,247,31,4,291,306,226,146,361,860,852,613,956,856,46,421,356,465,898,637,866,704,383,821,493,400,508,123,493,125,326,939,411,397,351,704,704,723,741,431,173,209,679,8,539,859,780,459,187,398,222,332,637,500", "849,822,788,301,736,435,356,454,860,279,906,532,279,831,307,105,375,721,808,692,86,244,606,823,306,720,512,337,580,864,760,781,728,880,148,123,723,645,898,782,122,463,733,91,747,282,481,506,112,393,61,897,846,266,126,852,921,774,423,376,318,679,645,310,319,552,595,321,303,218,448,846,251,96,195,291,233,957,317,562,397,182,352,147,695,762,311,908,474,827,989,270,112,472,915,571,802,859,116,757,672,454,209,290,452,110,32,927,785,335,242,331,759,690,585,564,374,392,56,684,928,913,501,25,879,111,574,161,246,482,262,145,661,937,175,110,126,184,895,667,764,93,868,533,133,166,485,503,168,448,651,738,491,84,118,980,598,291,14,960,521,849,984,930,623,891,916,340,646,844,633,217,395,213,219,825,656,255,138,844,502,939,260,953,87,742,97,532,829,451,631,577,951,959,255,0,852,654,988,722,437,98,881,954,366,958,448,123,908,81,799,183,792,697,500,719,878,658,299,605,13,352,458,324,722,937,286,913,932,782,36,969,528,803,65,649,489,119,561,533,813,697,439,480,679,685,291,965,184,804,132,348,325,5,763,366,952,197,407,100,846,950,169,145,517,671,464,118,755,350,58,541,979,502,800,925,922,591,82,181,540,211,92,793,657,288,263,855,530,793,386,467,658,188,263,48,60,540,881,823,929,919,579,684,699,66,869,645,411,991,99,236,327,251,508,384,126,498,992,598,120,743,290,840,548,14,664,928,643,716,438,912,900,157,54,711,166,897,397,756,805,899,84,73,374,36,761,501,84,817,280,578,984,458,682,93,280,490,644,154,45,569,449,563,83,250,743,525,763,334,212,18,677,560,904,246,846,406,719,416,360,807,620,769,998,385,725,493,207,648,735,806,262,601,780,904,767,193,200,288,101,364,730,825,444,367,634,187,157,324,947,2,506,127,89,964,985,266,429,868,804,518,64,328,9,635,257,17,936,526,954,698,313,385,537,749,419,662,326,121,771,509,178,490,737,52,261,689,953,31,666,825,85,264,726,290,500,807,609,749,334,459,295,884,170,523,790,844,882,886,782,304,154,740,118,420,284,204,559,582,202,92,533,410,639,905,291,17,165,421,641,896,891,408,418,3,731,418,91,540,981,489,815,631,463,403,974,83,24,798,150,376,945,146,514,112,251,629,208,59,35,670,798,930,857,620,949,24,219,267,78,64,554,179,996,832,770,421,882,393,932,386,767,227,378,634,555,969,298,65,54,849,512,34,443,728,217,647,60,18,121,164,911,84,513,768,439,337,183,919,434,630,925,837,199,555,834,618,23,663,337,967,645,243,533,912,359,281,961,285,71,116,210,636,754,793,641,202,711,168,766,823,510,111,701,654,603,390,591,642,764,266,128,393,720,290,703,96,768,69,227,940,131,744,511,857,209,308,901,105,229,497,280,89,778,916,47,337,744,424,759,927,776,709,996,375,222,872,591,67,986,24,888,707,966,705,330,275,829,738,29,332,797,167,80,548,139,965,403,898,496,35,934,257,312,109,340,173,500,420,481,66,892,886,841,217,32,940,596,545,98,367,637,132,419,287,421,612,713,530,585,881,436,498,789,533,104,291,343,981,309,659,20,231,624,112,323,467,279,214,901,138,647,323,219,956,16,919,874,444,442,608,862,679,763,512,599,125,209,808,327,358,484,221,450,902,487,191,493,351,561,754,421,798,345,712,722,111,67,664,640,452,288,853,992,676,952,398,585,728,660,530,163,672,890,583,954,511,711,603,412,876,820,141,790,326,122,516,405,248,716,767,116,359,431,761,411,770,708,668,725,676,351,206,501,787,766,745,648,190,471,887,919,585,713,656,283,971,800,448,547,668,182,534,338,231,269,578,44,90,12,320,347,548,619,18,454,787,264,877,476,606,139,44,881,825,896,633,243,251,289,984,846,863,473,990,165,840,937,860,684,928,935,25,282,202,972,59,450,419,309,673,685,622,845,227,443,369,578,956,760,472,125,381,698,515,331,736,73,126,1,370,942,910,26,413,60,361,820,498,600,608,595,873,806,879,594,497,724,57,776,835,245,843,997,254,171,372,505,74,474,867,530,213,592,941,130,924,519,893,746,473,407,331,485,627,636,829,271,888,650,466,291,61,90,254,475,450,421,157,40,406,197,787,124,642,577,666,73,575,679,231,723,221,620,976,788,170,603,300,235,594,603,883,708,361,357,783,985,531,804,652,954,773,298,546,278,307,723,159,332,411,143,115,588,537,673,942,291,944", "381,968,918,412,366,961,535,658,812,578,691,772,119,724,855,49,622,677,587,835,376,582,223,62,727,392,131,705,504,221,491,452,555,404,418,133,824,251,106,656,347,639,576,821,923,627,197,310,88,719,650,104,14,757,730,211,641,805,208,6,504,765,904,612,607,322,850,110,664,32,82,961,415,35,493,705,616,308,507,898,395,460,374,959,873,123,487,963,881,987,897,343,939,822,881,969,437,425,18,423,437,324,785,751,867,618,146,209,802,421,934,775,597,161,672,366,318,694,468,55,604,609,905,910,181,733,89,419,88,574,587,212,754,636,246,151,262,920,649,496,712,252,785,205,850,268,986,263,719,965,32,79,220,877,19,258,355,123,719,118,72,288,640,611,831,269,586,831,362,735,276,540,935,702,949,922,326,61,744,944,609,455,34,543,996,185,495,5,650,374,227,190,324,886,610,852,0,614,537,417,146,915,864,435,269,742,489,323,986,529,498,985,216,566,743,727,416,608,289,897,889,90,858,134,190,924,824,894,528,251,637,171,154,358,348,366,432,585,691,693,540,100,79,335,660,439,755,828,485,883,647,457,992,762,334,598,565,546,988,392,245,621,157,316,296,900,915,241,46,520,215,89,525,321,503,806,906,437,800,347,751,797,44,143,302,479,43,953,819,713,267,342,892,91,757,934,393,600,716,203,793,298,416,280,196,822,513,131,846,482,435,813,212,640,85,540,625,462,278,354,707,311,201,675,137,540,121,682,107,966,163,678,902,782,874,522,54,313,119,380,517,973,547,138,130,479,829,271,686,693,944,979,75,306,728,901,826,523,988,92,660,214,902,245,192,922,665,32,799,516,519,848,32,72,583,652,410,330,571,998,795,620,340,9,54,933,178,90,117,615,491,748,947,182,790,741,751,527,817,578,491,952,38,170,102,486,76,733,570,135,261,452,734,902,987,421,453,115,84,514,738,609,443,594,922,717,427,403,170,210,815,79,35,246,917,191,136,609,845,358,386,125,60,838,593,934,5,819,542,405,940,881,111,699,921,774,432,97,992,93,841,540,277,422,228,24,667,109,426,198,218,194,349,101,200,670,911,60,652,673,761,885,831,139,125,278,231,904,699,861,917,803,717,805,558,745,957,741,730,322,318,416,340,758,726,109,876,725,455,834,664,555,227,688,920,82,194,836,730,514,915,278,972,733,347,396,356,678,319,33,227,532,955,107,295,760,73,374,461,118,220,577,908,905,105,193,678,19,415,777,81,15,584,481,933,641,497,962,497,862,784,610,41,164,234,50,737,981,391,365,788,103,88,455,136,796,784,196,753,910,1000,566,81,723,280,212,691,216,65,385,137,970,48,429,942,60,951,961,341,581,84,266,417,617,273,572,962,267,94,687,529,342,538,687,574,459,428,437,380,610,628,457,487,542,10,107,552,932,367,939,203,11,140,949,658,517,541,954,679,703,412,254,711,317,583,530,704,501,635,822,148,969,172,815,592,754,699,119,239,47,33,514,259,25,822,873,861,695,686,863,174,854,869,643,995,974,829,803,613,391,941,345,279,536,986,775,7,756,790,474,580,443,715,370,960,116,64,779,330,336,334,89,987,453,579,908,715,790,559,280,31,206,462,232,368,868,844,458,608,643,31,827,327,149,661,731,28,293,407,658,575,538,85,197,506,699,379,301,787,607,857,952,105,463,222,941,260,223,19,677,993,842,438,352,347,849,497,171,512,695,427,541,54,893,448,365,658,338,766,890,478,437,782,728,450,424,324,278,204,119,642,315,67,482,667,546,214,94,916,801,831,446,412,290,638,887,866,509,642,426,348,254,773,540,211,789,847,247,546,964,974,565,621,331,936,433,601,514,56,157,851,680,700,920,535,313,699,87,718,888,779,944,761,397,562,711,778,507,297,455,217,819,929,767,818,708,248,664,598,90,721,845,116,314,995,866,956,24,818,625,696,249,960,158,358,905,564,67,54,323,745,310,141,696,243,953,992,540,820,143,148,942,198,482,5,256,513,881,556,333,298,675,576,961,861,607,219,716,302,690,854,973,514,814,700,48,456,257,370,938,852,20,803,820,33,426,176,710,883,755,984,290,963,541,650,429,210,897,255,421,169,531,974,356,773,73,36,120,383,62,244,929,161,313,901,348,923,765,459,200,980,757,695,9,295,166,80,585,882,370,736,522,633,319,993,125,830,40,112,388,70,901,835,447,380,469,581,508,692,157,148,445,257,161,436,459,684,536,467,577,903,837,421,979,500,864,31,885,973,757", "720,17,689,789,235,606,784,97,165,338,848,557,263,381,148,631,135,76,370,867,730,319,189,171,668,433,299,647,562,351,433,648,335,736,993,183,215,49,996,607,834,232,928,351,794,863,514,381,141,414,211,989,996,944,585,78,381,421,46,235,946,712,468,550,576,14,814,14,843,759,106,165,753,551,584,434,578,622,929,855,421,910,630,223,253,802,991,389,575,470,991,547,2,45,541,389,435,654,676,473,995,547,185,816,368,258,190,328,32,520,957,180,945,550,865,786,614,183,136,597,741,136,101,736,598,58,114,210,112,233,331,796,70,89,581,111,219,834,697,800,807,169,245,790,801,854,158,961,941,50,83,903,518,48,701,567,304,892,188,617,247,662,451,226,588,627,389,765,133,173,50,79,518,996,793,791,901,805,329,421,986,273,466,779,263,631,480,335,961,60,597,386,847,542,623,654,614,0,450,296,852,392,13,790,893,12,236,290,447,569,755,869,996,202,385,536,309,597,173,525,653,178,292,719,110,703,981,722,482,965,113,923,269,471,431,390,932,836,668,232,119,294,647,13,985,785,299,603,531,500,840,614,8,717,110,488,143,730,446,291,172,558,601,872,794,240,594,160,179,782,329,865,336,215,59,728,847,957,847,751,341,370,755,343,557,599,798,792,661,775,847,723,684,491,274,771,179,545,307,942,95,632,91,965,604,149,86,634,252,221,491,892,343,453,143,148,175,753,72,570,988,396,557,677,700,148,426,401,85,921,176,210,162,869,741,225,386,663,331,337,99,759,603,878,885,885,321,417,116,101,768,661,843,119,669,352,748,135,837,568,40,429,527,650,212,393,159,968,917,108,986,909,520,213,615,745,890,707,672,697,918,943,332,951,808,831,946,589,768,71,153,185,251,398,992,616,484,247,947,954,906,796,796,29,243,268,983,500,50,704,36,300,234,237,716,112,477,408,481,163,400,958,447,205,382,192,86,99,256,631,721,857,491,664,594,496,208,570,539,214,959,549,646,648,979,33,112,280,273,568,481,265,452,59,891,667,389,951,889,137,130,656,66,210,178,400,94,513,670,326,898,590,791,618,70,496,562,440,39,790,457,983,226,731,697,186,345,634,264,421,217,207,257,696,38,90,897,109,396,970,771,215,929,180,620,66,258,551,771,347,941,79,752,846,9,616,567,903,371,409,85,382,701,331,504,375,359,614,891,887,115,721,279,623,874,839,628,901,817,546,718,168,925,71,208,8,284,345,709,931,627,195,188,97,823,495,143,459,249,216,5,979,942,472,493,971,157,483,30,542,140,656,26,491,443,627,840,912,652,630,674,674,724,363,415,825,953,757,444,959,691,656,881,546,860,293,236,980,923,534,649,135,770,872,775,98,819,105,432,547,600,228,479,25,41,735,724,507,860,894,611,322,929,69,426,230,411,12,739,171,989,893,900,176,975,854,972,44,602,528,396,33,152,38,580,714,243,920,345,846,819,45,325,85,368,241,705,349,682,649,560,17,466,857,861,190,44,662,148,468,225,280,426,568,813,771,34,404,469,524,408,212,451,472,131,77,262,447,905,532,475,144,821,998,658,132,961,715,966,851,678,683,116,157,459,671,479,736,636,940,176,897,727,944,570,499,686,982,165,320,957,963,266,576,382,830,927,48,244,293,269,16,796,66,340,749,485,567,648,758,170,191,232,938,323,208,631,750,295,371,190,934,786,365,882,158,525,697,760,742,199,732,255,507,585,214,894,818,46,697,212,430,334,155,742,935,154,128,685,271,797,155,364,979,641,289,879,452,647,285,161,376,273,770,677,933,789,804,226,208,749,273,393,924,218,508,891,298,181,369,714,410,243,801,105,219,534,963,110,440,787,937,219,591,869,843,777,495,961,888,438,855,917,884,138,586,334,572,579,244,695,518,478,654,171,341,605,736,479,19,962,881,460,91,20,649,695,604,166,167,368,389,868,603,110,113,927,870,794,536,314,313,676,88,407,217,292,711,326,814,915,815,244,518,815,534,627,977,687,278,37,662,151,364,699,703,622,469,465,758,813,760,588,381,7,890,781,366,567,855,809,348,966,250,764,382,96,27,503,649,632,36,793,847,669,479,614,3,431,889,678,769,899,130,828,741,189,930,111,575,925,210,987,216,751,253,234,867,439,572,351,619,101,961,828,871,27,321,607,417,658,934,981,504,394,263,554,718,896,67,722,966,315,365,565,184,291,303,750,407,551,57,826,662,669,133,402,632,300,666,49,231,14,616,439,42,507,736,771,127", "166,632,104,988,90,170,930,210,634,938,873,269,7,143,235,639,585,534,105,440,732,536,662,504,367,678,776,484,168,194,776,304,474,279,309,321,248,769,347,300,892,418,454,558,828,816,765,901,825,481,89,25,23,127,972,912,570,374,606,726,428,348,427,802,349,383,174,691,868,516,297,774,528,759,608,140,487,104,55,984,229,310,321,821,827,70,248,800,150,647,500,380,947,176,597,178,824,256,629,199,724,687,803,885,209,315,392,742,184,693,253,161,948,708,598,831,410,46,905,717,633,618,698,420,379,27,629,787,836,865,814,457,779,515,642,653,110,855,143,75,76,546,261,966,748,266,798,738,103,757,355,662,602,203,299,556,790,326,764,644,121,527,124,868,420,145,112,218,50,482,788,953,948,636,659,339,414,213,649,79,413,396,693,920,755,448,826,476,811,904,297,432,137,142,78,988,537,450,0,788,577,789,894,950,944,738,32,866,979,815,416,87,982,435,714,953,344,31,765,959,770,720,636,773,318,826,483,393,731,518,137,377,792,996,553,424,613,751,229,548,337,589,784,505,252,702,28,53,405,420,325,545,792,681,965,502,602,969,489,739,965,575,588,644,441,993,593,647,534,247,551,148,584,462,808,663,276,486,77,859,991,560,36,869,199,79,666,45,865,293,53,139,372,194,117,904,471,603,63,109,694,317,437,614,177,722,356,31,480,390,217,440,682,114,882,438,380,626,479,772,785,106,73,571,449,995,653,472,810,9,761,923,498,263,753,824,604,597,556,45,647,893,718,718,598,139,486,959,889,852,473,531,198,822,788,370,224,136,461,799,251,928,9,120,57,2,272,73,701,41,477,696,743,726,392,120,388,421,91,634,108,850,36,42,409,330,915,843,317,778,591,282,926,373,374,458,571,411,314,182,874,450,459,401,225,495,603,310,895,627,204,239,18,13,567,661,908,175,123,543,776,83,203,550,697,392,313,816,327,422,69,526,200,443,383,265,166,140,73,669,420,723,941,962,83,740,42,910,394,280,606,504,568,761,863,321,324,887,871,189,471,876,501,928,182,778,21,414,187,151,163,73,964,449,254,121,825,899,254,845,689,769,775,445,3,92,403,20,493,28,177,94,741,860,722,147,160,410,580,720,735,806,319,798,297,49,778,876,588,745,247,83,189,585,12,590,540,368,449,940,187,523,612,401,498,834,423,594,886,529,793,818,293,440,532,734,660,778,469,931,724,200,950,588,436,465,545,163,184,690,488,100,108,530,899,227,886,896,474,882,854,192,255,58,130,147,631,485,960,493,498,796,25,126,418,910,453,540,776,393,416,738,106,100,745,999,42,882,4,874,607,831,576,91,598,797,693,854,59,497,112,397,415,481,825,210,677,269,322,57,433,707,402,510,781,755,694,700,466,414,731,712,224,156,975,941,511,758,451,306,801,997,478,732,189,472,835,531,536,788,574,664,325,379,606,759,680,897,939,397,735,652,139,831,354,675,768,857,707,43,937,712,972,371,502,97,138,888,755,117,304,800,603,447,232,43,72,607,35,284,993,429,520,571,165,934,636,899,417,890,960,727,664,810,660,566,633,826,729,491,581,834,843,887,874,212,880,718,193,144,432,896,377,299,197,98,804,891,560,540,832,465,358,659,247,436,338,430,750,803,854,753,423,636,661,677,677,945,848,242,908,326,199,10,469,464,387,728,498,744,453,42,325,514,41,87,143,917,329,830,731,527,416,642,8,641,843,362,732,794,93,384,304,79,823,728,831,598,48,500,356,683,37,998,578,313,959,284,179,972,703,356,778,249,68,915,259,250,363,570,48,493,88,92,900,593,35,416,410,182,756,387,968,166,483,224,636,40,943,522,676,830,271,678,137,174,111,712,255,68,481,371,639,969,278,426,241,740,486,87,972,720,940,567,498,425,949,253,546,694,991,646,389,508,812,387,807,797,512,41,440,245,615,894,606,591,15,535,837,255,721,565,139,90,241,141,948,128,57,245,774,18,352,569,27,804,669,443,376,34,35,500,345,836,274,462,777,864,565,152,414,418,557,38,217,471,713,789,365,265,553,484,198,739,125,925,777,475,888,506,706,384,450,855,996,345,52,451,742,146,529,253,795,248,451,79,557,441,140,497,622,249,427,455,853,130,464,960,493,958,920,151,456,868,326,69,931,472,827,214,298,950,297,866,726,81,39,551,756,35,746,394,713,504,400,530,208,871,280,206,940,209,581,674,14,863,770,125,472,621,105,526,320,830,298,568,173,304,386,67", "208,471,967,80,514,962,214,591,688,996,689,374,105,143,378,959,695,959,14,485,290,912,310,950,900,824,783,289,815,91,630,701,234,931,190,573,630,381,652,996,499,656,107,85,343,542,525,980,321,903,255,822,234,541,732,539,452,385,399,376,707,756,141,240,254,904,379,849,296,870,706,813,426,17,766,340,461,743,669,946,601,969,568,381,493,675,734,952,843,141,95,621,942,431,7,290,545,486,595,714,848,589,331,887,78,294,244,844,813,49,430,385,98,763,569,209,980,395,389,961,982,970,96,7,927,854,494,753,883,149,365,336,713,356,219,603,143,125,58,692,617,188,495,250,411,749,649,443,432,113,42,751,656,245,804,45,630,936,429,236,423,426,382,20,613,256,326,519,341,811,441,285,253,963,849,39,239,250,482,399,746,95,562,983,459,31,275,642,926,401,114,528,484,240,329,722,417,296,788,0,360,55,873,613,163,82,374,55,176,315,436,579,87,745,476,924,42,359,140,4,352,891,13,406,89,721,187,863,705,122,66,470,775,94,150,919,266,159,622,102,617,131,61,936,994,376,895,868,264,641,865,815,421,80,255,743,895,207,932,46,929,47,153,226,642,483,245,813,928,506,582,957,199,66,502,859,147,98,728,968,33,920,655,300,680,853,328,940,282,346,393,72,946,326,516,75,154,178,669,376,748,283,185,460,286,524,314,181,904,546,911,595,640,853,825,209,161,277,316,89,860,826,697,566,794,554,426,830,135,628,641,345,129,418,846,99,165,646,815,884,501,436,676,13,948,48,551,99,315,90,30,839,653,420,646,19,846,61,65,165,687,922,612,836,723,828,768,686,579,824,732,98,806,801,615,241,405,761,160,925,679,25,225,184,956,372,59,158,273,732,103,754,43,79,830,90,248,527,875,849,485,152,13,730,515,516,840,561,271,430,499,771,467,818,457,439,750,104,184,291,79,442,431,421,59,669,686,224,221,795,336,634,641,698,51,769,887,946,774,880,330,646,214,128,300,207,437,870,483,260,958,519,983,656,223,221,2,539,436,370,725,767,553,373,190,214,672,504,104,119,774,941,182,305,611,280,471,305,540,755,28,701,62,212,178,637,632,214,815,221,459,604,417,676,861,706,630,133,986,563,521,855,249,380,767,271,996,654,538,379,286,62,492,825,966,583,108,813,259,860,546,753,144,227,610,574,954,650,380,306,166,141,817,416,235,98,755,724,100,897,997,531,537,529,699,948,601,604,804,242,526,666,888,472,796,969,474,76,604,672,892,349,141,748,598,728,115,136,257,517,215,354,450,542,191,517,182,209,736,683,721,199,577,160,59,164,193,276,541,21,936,695,528,897,185,441,669,915,925,256,850,721,164,633,5,770,46,880,795,888,107,616,227,451,16,448,294,247,908,413,722,52,576,354,894,776,640,201,332,552,994,850,415,750,663,871,12,170,103,658,104,420,686,825,952,772,544,406,631,221,113,700,588,106,959,213,23,827,369,19,559,310,793,64,628,77,802,236,757,217,278,603,180,277,34,281,209,950,78,498,841,294,805,298,601,564,333,692,217,827,965,741,227,502,889,147,545,994,139,37,666,170,577,89,250,29,677,209,425,545,854,394,236,544,447,270,805,901,655,292,581,73,932,112,362,25,784,647,854,716,780,8,446,75,37,865,532,818,473,279,510,422,512,198,227,485,243,668,491,996,306,331,240,672,754,973,350,271,350,335,724,323,566,200,353,657,14,444,696,434,392,294,534,135,443,64,642,384,116,153,954,808,16,817,959,645,701,657,29,623,313,576,479,273,675,424,378,365,90,120,754,80,624,47,986,509,296,330,289,754,124,77,680,321,624,697,97,72,324,318,488,388,403,222,960,895,657,247,785,970,804,219,230,714,741,9,132,427,199,205,598,861,837,560,686,562,985,899,545,954,422,838,8,297,127,463,78,740,953,282,609,643,406,703,518,931,190,818,617,637,709,148,640,613,131,470,427,330,739,143,77,209,994,20,132,480,48,865,666,120,974,275,813,294,725,57,357,727,542,248,792,922,865,256,34,948,866,913,484,367,940,916,861,656,19,893,633,199,39,888,683,350,933,925,400,201,282,731,47,588,241,909,333,807,603,124,165,802,634,6,987,559,480,444,304,119,422,216,756,380,377,155,619,305,168,79,505,913,369,159,883,620,743,261,581,155,112,496,65,221,608,1000,639,970,767,553,953,901,332,636,712,760,396,290,838,256,498,239,156,286,389,471,249,765,451,222,483,438,561,48", "178,639,837,886,739,72,210,875,682,663,547,38,905,498,944,939,691,726,935,352,88,419,670,750,215,238,783,555,471,375,574,798,409,757,382,301,949,678,43,520,342,991,106,74,141,764,665,350,789,234,786,584,269,288,232,640,852,29,671,32,711,299,16,121,923,173,627,588,992,816,751,416,127,547,635,213,613,938,117,20,646,484,928,649,227,497,751,939,102,985,840,574,654,717,124,756,76,682,593,51,734,990,781,312,966,563,549,912,900,188,391,960,261,361,827,71,391,244,281,786,691,904,402,802,12,781,927,609,128,330,607,772,545,641,718,8,562,271,540,794,581,702,85,529,410,837,540,814,886,836,200,232,740,77,25,716,679,251,195,876,211,923,199,949,406,638,358,570,346,370,277,552,683,75,760,323,985,364,596,506,32,178,920,91,175,489,463,373,795,587,869,664,150,469,197,437,146,852,577,360,0,661,950,862,414,559,859,161,219,401,377,569,233,315,459,834,494,137,404,365,768,154,629,496,538,207,504,494,271,67,608,26,895,539,110,738,57,41,803,652,250,717,930,214,348,338,341,238,78,217,561,116,331,589,850,9,683,941,965,527,446,800,874,140,297,287,59,969,988,506,692,199,128,859,992,212,923,618,125,754,511,577,836,300,195,169,75,108,914,821,692,479,522,502,594,252,432,13,653,510,641,530,610,87,372,597,742,373,66,911,440,383,434,147,698,799,614,899,728,444,602,98,949,650,661,830,45,441,983,324,177,325,764,106,787,431,463,390,835,478,668,895,146,51,147,872,954,492,172,179,562,304,501,845,456,643,941,53,135,423,181,974,766,110,568,332,663,487,999,385,356,887,572,332,635,874,667,988,493,406,886,346,706,44,727,477,631,453,558,643,781,991,230,657,240,732,854,343,580,595,438,636,614,63,68,963,329,45,968,92,288,487,660,413,647,699,342,228,429,214,338,149,184,399,933,403,436,377,523,542,836,604,618,387,751,86,291,140,853,979,587,783,158,160,157,613,294,752,722,46,134,862,846,686,648,942,542,574,788,880,169,89,351,306,402,217,448,497,767,255,48,741,349,839,805,34,390,862,585,481,825,703,779,19,477,507,522,470,528,663,734,562,422,151,85,479,997,193,999,226,38,106,120,420,37,508,984,877,475,977,774,196,856,916,616,897,14,952,788,360,105,803,897,463,470,240,520,592,606,282,429,663,176,202,44,286,539,394,753,178,127,356,580,547,855,593,837,921,328,769,925,323,828,691,104,336,115,247,519,148,804,946,841,864,886,920,627,699,294,768,323,194,383,498,185,575,225,545,765,705,716,516,703,790,139,309,854,577,985,309,664,747,97,338,334,871,915,869,221,536,399,416,366,23,238,665,464,182,622,769,438,412,273,881,248,130,263,559,884,319,943,604,217,412,294,798,495,428,226,872,198,144,216,713,518,130,838,4,558,4,434,775,800,533,936,750,516,630,124,742,676,404,413,978,201,227,557,209,607,699,311,548,940,377,470,240,554,255,948,350,632,139,709,339,179,268,525,395,40,311,621,911,604,565,968,489,799,347,994,230,285,382,635,881,853,348,314,748,68,531,824,835,187,159,336,37,783,761,954,967,554,601,794,815,864,84,203,467,511,770,257,87,493,306,436,455,584,965,867,993,904,630,892,642,448,892,155,705,151,360,293,808,398,558,457,655,324,583,612,453,636,348,278,617,985,811,283,994,208,71,999,278,28,301,550,937,132,860,782,328,141,616,753,693,728,467,590,111,313,113,810,574,343,753,47,178,906,450,116,123,568,668,630,485,868,813,248,568,857,416,565,783,111,615,652,167,541,907,879,247,86,554,995,859,803,664,692,897,116,405,948,254,980,684,336,557,364,713,670,670,867,595,887,402,423,921,296,731,295,784,77,907,369,845,880,837,676,961,79,416,652,606,324,413,732,992,359,522,457,979,960,790,177,348,227,308,591,875,494,335,943,488,772,804,539,505,765,671,894,372,211,19,980,273,798,534,604,5,678,916,133,791,130,493,229,948,352,838,724,77,785,253,10,571,980,823,854,853,20,663,221,932,479,192,45,817,319,350,897,780,137,53,543,269,543,702,946,584,238,131,661,313,542,541,253,166,81,586,509,515,874,116,318,710,459,136,812,324,532,753,599,14,7,630,538,292,549,389,656,164,788,249,590,214,939,754,12,776,656,909,648,866,335,697,234,577,691,328,679,469,919,162,31,997,882,341,931,981,858,880,488,24,157,173,903,175,215,492,792,216", "634,273,653,457,357,777,51,959,306,465,480,735,122,710,1,628,642,319,1,407,866,73,459,577,240,91,307,867,841,228,287,610,339,677,445,709,831,640,378,831,628,99,424,195,429,504,134,10,272,983,500,219,328,420,115,857,308,244,864,470,612,758,995,314,947,889,401,917,648,571,44,301,636,437,457,973,30,813,114,214,267,963,438,233,404,409,694,515,544,609,886,304,329,314,839,641,385,277,250,998,387,996,535,107,307,4,459,840,286,972,211,708,468,616,84,739,635,766,507,545,968,792,359,145,577,532,823,681,709,257,110,678,723,587,519,255,814,439,150,347,947,505,391,893,388,302,132,234,724,76,538,736,594,973,475,98,227,706,421,400,677,185,886,910,157,990,943,316,470,538,215,834,608,131,444,829,355,123,249,216,18,835,490,859,987,497,685,556,629,877,367,914,320,722,729,98,915,392,789,55,661,0,973,386,208,432,20,809,860,287,431,921,941,842,689,956,69,856,373,968,131,174,179,160,340,966,636,592,28,410,150,580,40,109,130,181,844,1,46,617,379,212,862,29,42,823,553,399,452,567,797,950,797,832,352,393,745,230,830,866,759,472,470,53,643,454,166,833,701,318,928,617,996,615,624,739,214,403,559,892,817,27,65,301,423,70,173,416,793,5,576,225,17,881,721,644,616,77,434,290,643,944,769,152,448,243,744,292,440,774,545,105,406,205,685,709,148,157,755,682,268,238,268,377,845,202,99,852,900,94,792,400,395,481,10,916,650,578,656,427,707,809,6,100,844,126,747,517,527,76,751,477,301,925,262,772,941,158,542,602,117,715,199,654,56,172,379,120,346,857,348,466,572,123,722,3,152,126,472,466,419,649,503,846,417,540,431,237,347,434,209,55,364,620,342,925,577,558,161,542,143,905,729,873,859,423,726,831,183,54,318,624,14,392,189,112,482,672,890,165,520,517,255,247,960,873,304,545,858,839,464,212,785,735,205,208,985,843,184,567,75,159,629,665,596,937,64,359,252,646,610,520,173,612,646,362,53,456,246,279,84,216,401,573,754,860,329,416,168,623,77,775,101,727,202,73,659,313,935,799,396,454,451,881,333,620,976,667,455,818,626,891,131,203,844,728,710,398,861,577,181,798,852,369,644,888,805,575,398,523,310,464,420,349,577,732,896,168,212,450,91,547,776,977,543,287,583,435,246,880,464,993,83,966,975,350,327,197,945,820,146,263,634,794,418,345,603,529,884,605,478,763,337,100,273,108,989,691,222,920,488,434,280,246,832,867,475,745,480,709,579,57,937,668,567,268,680,131,482,487,278,639,62,187,852,829,490,956,859,253,843,524,949,74,414,914,818,707,870,441,506,777,113,192,798,641,510,544,528,886,136,773,558,284,480,460,620,721,146,219,360,647,957,754,906,99,311,990,995,967,582,462,131,550,118,361,731,780,725,370,34,221,840,457,714,80,769,5,811,319,223,388,428,589,602,813,566,104,155,262,24,948,196,696,293,406,379,451,291,400,598,830,137,719,676,314,184,127,867,823,293,528,749,451,442,141,840,50,741,72,590,970,322,402,565,223,59,795,238,587,809,721,549,835,6,132,866,337,823,929,967,685,369,808,14,362,894,836,551,976,183,671,159,321,981,699,685,475,308,611,657,717,647,276,729,229,986,268,123,652,783,846,569,710,420,845,371,298,735,667,217,500,986,433,338,602,73,969,954,231,444,304,141,439,390,212,272,952,779,539,482,350,837,392,244,182,610,155,189,232,409,186,273,292,611,578,336,841,252,550,291,963,806,221,341,641,798,70,121,697,623,525,281,888,447,345,26,976,815,677,79,185,578,478,9,213,33,679,512,488,723,708,809,538,640,539,704,241,344,471,755,680,765,591,551,78,427,559,883,894,289,617,643,400,663,51,808,392,501,193,347,117,981,457,813,792,593,19,987,785,505,645,105,895,159,776,737,712,706,919,786,395,747,540,702,771,315,101,357,512,420,52,190,341,445,946,352,709,508,346,408,415,235,341,340,287,840,784,664,246,44,720,707,490,284,311,610,307,372,480,338,238,194,424,522,390,539,435,155,966,360,643,817,865,748,35,768,749,355,227,133,85,462,14,40,674,664,684,921,78,339,817,149,556,705,657,385,225,676,166,401,625,895,457,572,578,227,553,645,137,847,173,38,683,374,930,299,52,487,138,683,862,137,332,718,519,735,448,641,252,429,329,574,194,304,240,668,98,463,813,233,392,103,882,883,279,203,602,270,361", "557,142,656,333,806,127,932,158,567,603,769,954,454,458,554,169,220,11,695,319,181,73,242,281,561,982,225,940,151,424,447,89,81,95,750,258,315,927,825,400,922,735,160,682,953,221,514,368,838,665,858,629,994,479,996,372,752,420,233,633,85,110,878,682,590,443,552,350,104,915,500,538,170,346,436,748,679,874,217,704,163,339,15,998,637,285,756,864,154,644,142,472,542,276,197,976,444,134,522,635,209,501,336,377,561,441,275,125,295,683,210,810,708,966,753,916,911,806,713,521,410,80,730,788,718,994,314,691,699,659,80,620,381,831,596,417,290,546,403,864,631,497,133,679,695,925,806,556,929,324,527,422,222,840,586,922,728,989,930,200,578,27,612,190,750,297,107,762,304,724,288,662,231,666,78,548,58,756,296,259,925,436,707,615,144,602,977,958,425,814,709,369,951,959,83,881,864,13,894,873,950,973,0,385,396,95,847,119,938,339,315,893,101,117,107,512,914,910,597,842,787,396,164,169,712,150,373,106,636,305,94,11,478,191,694,262,6,94,578,831,942,270,678,736,849,419,387,662,582,585,371,963,144,570,147,847,614,312,567,258,856,908,706,711,124,787,163,790,166,806,454,93,300,222,557,40,341,872,879,733,939,927,233,634,851,438,212,988,406,516,205,816,743,619,613,156,330,37,506,660,212,661,970,902,87,680,690,482,955,588,918,444,863,315,925,75,157,195,978,286,186,771,650,79,324,713,857,792,348,449,814,909,905,207,287,701,275,612,21,592,718,440,771,711,953,78,883,564,840,56,764,303,418,505,59,206,867,980,591,146,50,428,406,768,363,900,481,989,491,415,21,746,5,106,876,20,479,301,626,352,439,871,235,484,243,318,496,727,346,622,586,803,95,984,286,307,414,701,691,286,425,218,383,346,852,375,589,390,239,744,336,212,368,121,103,584,819,713,653,970,177,669,910,151,681,798,279,23,480,815,483,951,948,545,490,255,862,89,920,436,570,572,623,691,50,260,504,512,205,644,155,834,415,279,908,806,377,244,935,823,709,759,128,908,844,548,313,357,70,6,965,854,562,20,949,570,793,417,569,749,905,106,50,107,841,107,764,847,458,263,479,283,100,346,754,792,650,499,300,446,318,224,771,925,171,380,71,626,41,772,670,946,917,387,247,330,781,446,828,434,866,474,72,690,8,763,917,328,422,122,773,820,704,768,546,851,631,212,130,581,637,73,73,646,106,925,926,795,958,277,977,235,146,722,282,900,442,782,713,612,603,704,595,421,978,347,316,654,381,807,262,390,436,796,691,392,961,653,73,837,416,83,289,481,191,627,487,524,522,549,749,821,118,668,227,296,494,224,701,80,70,618,633,839,952,703,30,57,322,209,791,11,130,199,150,299,505,519,492,80,466,858,719,784,639,818,258,180,733,33,119,522,626,554,5,897,688,145,941,959,443,825,658,345,287,189,93,105,718,190,498,936,951,555,406,677,483,303,328,967,680,243,179,492,775,577,673,562,594,979,816,558,167,945,297,102,463,969,163,508,132,531,349,87,83,976,410,457,441,44,633,86,19,664,211,43,284,937,883,18,549,793,608,878,114,133,931,261,386,946,465,287,375,344,61,377,234,639,30,289,179,532,411,586,808,677,147,200,445,118,897,461,629,256,533,199,411,666,843,999,999,450,635,198,554,256,660,398,884,136,264,474,106,364,276,226,793,600,885,538,783,458,195,95,937,503,872,210,944,968,810,195,378,520,820,717,258,908,59,403,41,460,6,48,894,996,631,247,66,475,882,547,861,739,30,192,501,640,462,690,605,66,476,234,362,978,845,357,113,111,860,956,395,878,77,294,338,31,735,941,621,406,710,132,892,886,747,10,882,558,757,531,252,504,189,504,163,527,396,732,143,109,674,417,641,167,952,421,336,679,7,74,597,43,713,923,596,619,846,49,675,770,568,456,465,530,757,110,753,682,441,671,289,846,862,164,922,910,719,587,965,990,714,500,758,951,933,256,28,313,334,600,765,568,710,110,667,135,541,178,798,477,346,69,529,233,543,533,494,241,111,928,328,758,670,334,584,909,459,658,503,719,438,992,819,279,915,395,956,244,305,749,305,628,495,294,347,867,891,298,433,779,130,828,907,898,534,25,577,102,812,902,126,388,845,513,243,249,611,238,410,447,706,988,250,209,158,386,640,224,755,407,294,16,199,610,371,65,933,514,161,525,427,174,966,6,791,542,739,394,496,637,690,871,910,246,398,639,453,224", "595,763,465,603,963,261,163,278,447,70,287,340,331,409,368,732,671,963,414,955,887,53,382,887,30,872,187,676,337,983,674,347,620,139,295,469,331,612,968,749,211,228,158,873,311,711,295,520,926,641,630,899,622,519,636,153,187,734,218,269,81,968,439,618,175,312,42,115,948,712,176,962,244,274,641,715,853,800,427,585,832,950,818,413,237,194,811,895,927,455,781,709,316,3,17,532,324,694,718,266,460,490,19,903,325,854,598,671,703,510,811,120,992,389,530,26,197,228,507,966,997,622,291,97,78,727,48,199,787,510,271,556,968,309,223,922,10,928,487,528,250,551,434,20,107,484,574,544,713,660,493,714,355,425,744,456,20,941,67,395,314,530,79,501,392,210,342,428,989,17,947,402,950,455,424,333,512,719,226,799,483,228,239,317,911,669,451,405,313,928,588,11,695,583,868,954,435,790,950,613,862,386,385,0,545,543,777,614,564,616,341,976,426,969,700,157,892,165,269,147,975,821,253,602,583,112,981,823,956,218,122,450,126,143,446,439,891,462,366,68,717,215,899,420,555,197,11,602,371,856,345,375,988,289,321,527,82,815,845,985,323,98,36,875,89,108,365,502,490,98,169,981,830,873,945,9,334,382,707,383,429,991,368,651,860,810,243,43,808,239,702,68,470,105,746,561,445,401,9,309,608,764,744,962,600,541,547,780,391,156,503,721,15,607,916,131,842,383,645,462,677,546,128,685,65,675,977,985,93,910,185,996,474,591,810,299,257,319,264,906,899,696,497,355,11,464,666,405,837,906,216,348,887,14,164,83,171,79,74,439,666,345,712,665,126,194,860,986,264,181,402,73,138,920,373,138,507,732,204,747,779,751,795,3,517,988,427,300,612,634,842,36,94,210,409,847,85,715,709,447,872,179,467,20,644,682,95,993,417,300,577,433,552,84,211,16,383,195,205,992,981,141,165,429,475,769,646,850,105,142,707,325,778,759,291,124,720,563,872,515,652,927,226,304,302,974,303,84,232,734,226,463,678,419,705,445,797,771,124,903,423,108,87,530,823,649,295,177,778,398,916,105,287,710,770,952,395,237,223,60,345,433,585,894,669,702,233,780,400,93,649,683,985,124,846,299,439,814,786,850,745,979,200,253,530,924,223,439,742,905,703,268,420,981,226,18,154,767,437,19,917,534,74,75,434,111,277,594,504,591,744,974,183,250,992,765,261,332,540,887,460,884,606,80,488,178,662,762,461,820,676,875,408,347,950,203,148,357,824,591,256,915,207,390,696,196,237,800,685,134,55,135,770,703,124,715,824,942,383,957,78,687,728,75,335,467,552,641,655,208,787,693,707,890,508,278,212,471,526,57,110,940,922,259,743,926,875,487,487,47,399,372,10,9,466,736,871,66,879,537,880,933,977,402,284,368,670,288,799,199,841,423,252,336,401,102,359,833,93,91,894,484,11,90,149,998,275,539,979,174,640,935,446,792,162,734,139,970,529,522,356,573,257,431,858,215,319,577,268,299,866,95,226,480,67,457,994,865,549,234,167,742,494,788,94,835,205,981,100,252,827,532,572,34,816,357,74,438,522,713,62,590,956,985,2,16,719,984,8,733,559,937,380,455,350,792,962,677,34,391,718,121,988,668,116,573,160,729,428,264,624,544,787,731,465,684,362,396,691,57,269,851,455,484,712,54,501,436,819,916,289,754,257,531,595,958,171,557,526,716,147,358,605,508,656,591,32,959,331,205,421,114,655,63,353,96,451,957,222,291,463,517,979,201,30,981,959,51,420,713,290,182,371,253,179,434,78,971,26,54,76,109,429,289,592,371,757,118,747,48,570,299,780,266,128,169,779,208,679,42,142,889,677,631,607,883,776,146,750,745,356,222,842,400,433,271,580,131,951,342,832,814,763,453,405,778,363,211,731,160,751,623,248,188,861,467,679,490,727,926,530,459,890,180,355,562,768,445,304,987,728,839,305,488,851,118,580,422,733,59,35,627,695,946,500,449,965,75,992,955,631,107,691,631,25,519,761,143,507,929,454,480,834,852,283,781,883,416,942,673,618,832,532,531,597,401,640,27,450,195,606,875,924,750,297,872,386,707,815,599,843,144,381,497,224,632,325,145,710,657,686,308,828,333,368,323,533,978,883,882,214,708,422,523,758,41,506,78,603,552,947,377,840,996,126,56,299,582,5,927,336,260,70,68,337,355,413,629,804,334,560,270,656,914,19,862,979,972,929,168,792,537,975,913,43,476,516,682,691,444", "969,708,154,737,754,532,617,218,804,140,418,158,189,623,718,275,755,27,904,808,163,50,273,713,661,56,724,333,879,388,903,821,450,758,760,762,65,933,484,815,673,384,355,597,264,465,493,98,308,354,214,11,697,851,379,545,321,297,812,996,571,570,707,473,551,163,171,605,829,820,751,518,821,686,551,540,630,641,127,466,590,9,94,873,53,707,606,667,98,372,976,287,998,984,856,230,711,488,163,891,214,591,4,624,189,726,291,38,923,132,432,6,376,134,68,229,75,680,998,386,381,722,622,965,275,984,746,186,244,262,182,50,965,567,894,128,353,610,540,947,184,379,892,559,207,683,337,86,74,516,222,836,484,357,241,843,698,828,227,370,177,543,145,825,999,841,770,531,60,86,849,705,586,255,966,79,219,884,667,739,750,788,94,308,536,466,945,332,930,813,607,544,93,773,549,366,269,893,944,163,414,208,396,545,0,437,431,269,511,253,246,956,560,974,635,221,766,816,36,952,958,987,740,583,199,121,5,126,736,792,413,671,576,596,347,235,635,957,746,735,706,158,164,760,144,649,907,138,736,313,293,478,223,675,855,295,385,521,392,764,173,94,736,959,986,645,937,73,32,274,262,897,637,751,721,943,561,420,992,663,285,47,22,890,258,885,339,556,309,412,345,343,312,801,55,67,72,996,265,271,624,237,856,822,868,861,243,838,225,776,957,187,844,572,859,773,119,625,499,959,694,951,543,732,237,907,802,456,847,870,535,600,350,78,328,359,249,350,374,933,800,90,816,516,206,847,528,180,314,737,268,664,123,586,483,476,94,50,940,593,928,193,491,889,777,461,850,320,898,89,632,563,121,386,577,957,407,626,859,157,390,387,557,785,107,869,377,205,392,806,973,99,231,467,2,769,392,813,246,363,54,923,896,889,631,860,78,693,159,873,882,847,651,853,230,302,184,842,922,831,243,310,241,655,783,210,672,707,511,537,507,144,887,392,251,586,806,886,929,207,517,708,253,563,733,518,662,385,636,503,704,494,761,835,857,875,515,235,541,905,709,286,126,115,417,920,522,243,632,387,725,174,267,102,874,363,892,438,805,285,411,153,699,334,654,732,57,846,840,336,225,250,182,53,586,216,471,995,712,763,605,859,841,101,78,697,556,134,931,914,416,420,195,29,928,530,167,693,981,929,341,301,377,445,403,415,337,71,754,715,565,547,96,156,598,594,141,678,531,253,830,311,132,446,524,952,330,796,61,723,214,41,515,495,394,33,477,589,438,849,573,837,975,24,398,221,386,202,362,752,936,679,198,366,570,800,171,316,130,358,562,154,7,50,439,359,130,486,466,650,151,800,780,978,201,40,777,456,763,160,650,598,919,724,927,525,555,453,901,108,416,486,714,811,239,606,933,741,537,774,365,635,933,930,771,626,514,871,343,823,699,686,153,942,76,533,574,636,643,969,193,46,609,937,516,249,630,52,51,261,792,877,589,841,301,712,495,769,744,459,452,919,354,674,20,339,311,799,102,299,634,875,733,527,388,669,105,467,959,173,365,436,787,189,947,962,71,520,382,467,499,248,281,804,182,557,862,376,70,422,396,403,103,243,613,835,574,274,29,342,38,996,684,529,453,820,99,39,773,251,915,459,45,943,691,126,82,238,927,30,48,665,167,192,78,587,46,407,166,720,296,624,648,512,715,312,899,740,526,41,518,364,464,552,881,668,868,403,69,839,353,911,774,478,7,380,59,561,190,292,58,857,5,608,697,930,254,181,35,876,238,753,2,512,212,803,283,503,246,119,538,136,215,951,753,967,578,224,651,362,890,591,159,293,277,273,658,376,424,424,721,484,174,764,815,754,244,847,457,463,470,552,38,975,264,15,653,346,986,205,949,104,300,183,862,561,557,665,679,329,545,567,413,170,455,788,106,762,735,451,147,273,771,192,210,901,112,384,574,415,925,372,372,200,189,647,254,407,963,504,242,146,926,759,799,28,602,170,929,364,867,12,371,580,220,338,220,231,879,755,172,742,17,913,965,230,680,343,417,24,436,206,330,654,235,525,968,556,448,825,725,476,647,253,889,926,304,542,296,25,92,989,375,23,470,178,437,536,561,609,193,502,159,216,851,692,958,195,431,399,92,341,697,313,300,214,86,195,646,824,486,107,747,770,199,16,202,564,520,912,316,108,296,509,425,690,782,542,381,489,165,8,856,855,739,208,331,405,227,905,541,540,959,45,688,556,118,349,764,161,808,417,112,68,860,543,220,147,807,479", "968,694,321,985,213,979,662,106,698,509,185,99,635,637,69,248,236,20,912,426,771,140,883,454,119,832,827,552,442,807,381,538,674,125,32,976,978,908,7,615,46,443,273,107,146,898,686,518,400,314,953,135,77,362,285,59,647,451,753,550,91,518,944,911,106,53,766,282,37,361,546,710,569,217,643,163,785,794,25,731,520,560,8,214,7,518,398,669,893,540,486,521,240,173,98,306,83,671,286,831,640,676,449,31,441,47,90,406,793,975,532,527,881,533,403,872,250,79,747,901,160,257,392,75,950,641,717,220,92,222,723,621,409,495,34,532,222,527,62,734,115,115,986,500,481,789,485,390,376,346,325,610,637,844,11,200,899,347,129,898,511,794,748,874,352,255,993,74,55,333,443,317,650,600,877,690,542,476,780,540,382,549,565,839,876,677,325,305,96,15,842,674,881,447,921,958,742,12,738,82,559,432,95,543,437,0,491,269,650,228,111,175,380,157,12,322,280,462,838,991,457,500,812,600,434,812,525,773,450,75,76,885,857,901,848,435,947,313,703,207,824,967,379,845,86,312,812,278,940,421,196,547,845,765,578,414,606,7,808,128,499,546,666,57,201,915,401,212,164,732,65,910,574,723,135,948,356,210,493,504,195,446,494,740,233,37,401,392,928,637,739,402,815,577,340,5,220,282,93,475,837,687,488,508,584,337,319,96,877,45,659,647,157,254,558,501,372,825,34,768,28,527,667,703,520,737,525,841,689,371,174,566,363,363,402,812,340,493,12,536,958,460,240,691,54,198,240,685,875,730,318,690,736,827,783,958,887,88,289,644,774,804,209,283,34,532,476,994,260,972,279,12,14,862,859,611,622,588,279,964,305,16,278,722,490,823,485,830,126,516,951,891,942,352,880,558,772,432,510,25,624,694,773,665,346,821,489,145,817,901,68,437,805,5,532,266,18,603,622,855,507,418,349,795,832,495,912,415,267,167,620,912,355,276,937,714,378,15,954,630,478,267,267,516,550,98,384,197,906,268,249,43,899,428,332,713,839,889,775,210,942,421,278,608,523,402,559,212,134,164,654,358,977,440,730,330,86,653,298,18,147,410,197,611,250,66,739,659,493,354,73,48,650,784,794,155,524,608,423,581,704,74,548,944,643,791,61,799,734,179,499,913,960,529,961,861,982,397,519,601,669,980,55,403,333,281,204,457,271,198,131,480,572,997,416,920,8,496,705,184,979,548,890,389,734,279,115,672,672,281,587,444,26,482,428,36,414,728,673,474,966,974,843,582,426,293,316,663,920,126,936,634,51,367,833,340,828,307,163,297,819,270,423,450,833,310,835,18,905,963,795,772,769,9,181,116,148,990,224,911,774,73,609,191,457,127,158,962,390,508,452,737,337,213,426,903,356,834,777,663,660,268,887,116,691,475,559,130,815,907,478,269,278,92,582,243,611,173,716,817,409,782,65,138,195,905,187,52,985,129,586,19,636,75,906,334,954,71,501,48,172,354,271,421,333,890,770,758,716,820,901,712,499,591,859,704,364,413,356,764,985,857,197,954,935,207,913,32,545,642,268,261,807,10,913,822,781,219,145,48,619,152,898,826,557,169,111,819,898,130,170,516,793,946,685,830,481,346,245,826,360,308,829,914,456,160,990,317,892,183,744,595,63,886,3,664,377,408,173,491,740,372,915,443,605,775,561,426,910,211,226,217,982,330,182,251,494,124,563,313,834,72,504,448,647,520,928,471,671,89,350,609,970,971,237,108,626,790,213,29,730,43,25,136,390,19,321,258,237,172,788,796,213,102,704,649,181,742,233,515,133,886,311,666,958,393,759,7,28,129,555,41,770,861,596,755,812,402,227,144,753,216,921,683,215,150,709,124,979,967,876,665,859,793,385,914,841,171,696,97,69,419,520,542,241,793,230,870,649,758,380,285,796,500,852,595,987,186,888,236,978,377,28,872,922,379,150,482,119,65,736,749,734,182,213,937,91,324,939,966,893,83,346,732,513,914,597,810,487,932,245,5,608,204,965,902,100,401,308,982,685,798,398,565,733,15,584,425,279,324,859,619,469,598,149,141,96,493,553,481,901,858,676,593,510,888,520,10,957,943,560,589,389,590,820,188,828,353,528,359,707,346,316,799,624,166,152,232,240,702,251,473,736,704,566,636,240,402,769,784,567,98,445,286,799,76,532,898,127,461,950,981,134,869,457,586,422,172,637,823,663,788,389,954,289,466,508,879,768,755,848,844,796,9,291,955,68,672,808,733", "384,395,722,546,427,344,588,749,943,83,62,414,672,56,96,427,832,694,820,552,574,490,412,760,906,729,310,727,650,279,747,182,217,471,915,309,568,489,720,93,837,668,835,172,938,568,731,761,825,461,471,564,134,735,278,71,721,422,765,587,818,504,721,395,509,129,664,137,15,2,452,545,557,911,164,874,908,530,589,443,609,829,526,656,478,490,925,559,92,148,666,380,48,449,256,547,292,677,571,237,339,294,567,480,37,802,717,328,517,184,284,268,90,535,940,236,177,380,944,996,85,906,783,559,983,953,843,466,41,203,845,883,564,298,398,903,619,963,816,35,95,224,384,13,276,987,951,40,732,239,560,77,66,100,6,856,214,384,52,467,486,647,999,366,23,42,679,877,924,116,643,563,16,753,47,366,159,820,713,260,760,655,245,491,58,276,727,433,875,229,222,34,62,624,141,448,489,236,32,374,859,20,847,777,431,491,0,697,160,124,526,624,607,369,103,534,916,332,50,294,895,140,285,186,375,83,646,469,170,505,444,247,587,424,773,267,457,245,653,62,828,795,918,822,585,257,920,552,735,582,84,308,910,150,237,188,714,208,989,646,193,977,902,172,428,536,55,961,597,102,137,299,151,11,399,852,582,839,393,365,789,907,184,528,166,224,940,150,574,257,495,842,896,263,216,871,909,297,660,500,290,459,344,858,643,375,139,370,953,30,924,818,4,947,286,710,271,735,44,895,534,423,372,813,831,452,569,666,148,779,477,382,968,769,256,705,454,653,393,125,612,11,770,674,85,162,829,778,810,830,397,123,478,265,143,190,414,733,950,412,4,536,795,559,150,139,40,631,856,828,623,883,650,196,994,812,859,562,200,344,411,132,793,675,916,230,724,288,560,960,788,498,995,151,981,212,532,590,615,964,667,744,480,607,15,78,367,790,767,902,263,979,917,596,651,600,269,811,520,881,49,766,353,288,783,635,548,434,277,732,418,804,813,327,462,859,961,596,145,944,161,124,237,394,423,692,564,335,56,491,510,650,440,668,117,277,889,167,113,75,505,142,784,635,594,147,461,455,13,960,717,576,966,376,970,825,637,206,730,644,83,350,47,376,71,854,206,948,564,111,361,175,955,870,564,902,725,507,60,728,596,264,128,956,485,317,959,257,801,86,36,409,430,641,812,521,780,714,502,383,191,502,657,338,931,111,208,957,587,749,397,116,693,642,85,278,480,700,666,910,511,578,791,274,568,661,572,870,209,170,265,978,27,816,265,98,386,282,420,80,222,156,14,141,779,497,229,960,184,595,759,957,954,217,450,809,419,205,805,730,550,539,241,318,292,102,169,137,471,435,814,866,740,69,540,732,470,451,43,361,638,142,910,959,744,459,693,446,985,62,477,799,589,768,342,372,64,718,477,392,414,884,186,650,98,155,654,764,258,338,654,370,11,147,750,312,333,268,170,189,840,542,866,413,722,887,406,55,840,149,58,720,150,369,237,208,445,872,81,684,692,338,428,975,430,479,770,416,992,227,414,460,670,840,49,914,963,12,745,99,444,77,858,852,762,845,807,773,248,415,529,528,340,230,760,323,165,943,874,759,503,887,815,501,719,595,553,660,531,577,383,227,723,901,710,150,332,398,62,482,358,165,348,29,73,260,414,218,338,825,691,52,835,707,272,103,173,86,751,983,248,858,76,644,252,264,255,201,488,847,38,335,437,109,138,135,104,917,982,527,386,959,221,90,121,318,446,751,42,255,945,990,179,640,360,99,851,322,371,906,681,128,971,769,14,560,823,370,61,789,208,614,839,540,182,730,61,906,221,217,681,731,582,546,398,99,643,743,707,158,604,863,783,583,248,425,832,549,24,815,107,139,699,478,377,819,759,621,44,564,597,418,794,153,104,247,363,727,438,465,970,273,174,406,599,765,616,546,245,426,24,64,826,231,998,657,666,405,365,579,27,756,649,134,397,108,185,986,234,317,576,698,497,133,555,976,886,277,776,974,966,635,422,33,810,425,453,180,5,217,260,521,758,87,98,391,53,362,4,459,956,941,826,417,269,369,957,903,218,543,620,402,263,231,730,155,569,214,694,864,39,546,521,647,864,496,988,988,727,891,138,112,570,38,231,110,221,844,640,775,460,16,610,628,998,847,89,239,354,907,654,362,951,720,860,508,861,137,737,220,324,465,587,573,380,643,422,854,226,334,916,167,728,613,959,84,721,755,427,339,549,597,580,700,636,13,256,912,365,262,608,771,132,773,224,887,389,253,246,503", "682,53,553,479,819,263,139,847,273,122,9,601,219,732,452,593,486,15,662,722,903,319,132,113,202,903,341,17,949,521,187,102,751,719,148,719,978,341,551,382,822,337,850,561,416,459,354,690,180,384,53,899,364,333,892,29,677,453,815,183,344,998,880,733,440,636,132,950,544,182,340,536,965,86,320,35,566,595,809,356,251,352,802,518,69,156,280,187,684,732,308,870,907,741,66,501,125,85,473,280,985,143,711,928,995,509,323,606,676,95,562,230,115,472,296,191,960,316,313,783,882,434,189,886,18,826,604,544,624,594,635,595,135,838,747,983,743,437,747,143,518,217,125,93,919,762,837,734,561,363,159,144,535,605,342,538,220,734,475,100,45,727,963,177,363,144,472,915,859,12,360,923,962,663,244,906,461,225,140,630,305,404,730,758,208,558,548,957,555,932,858,687,315,340,431,123,323,290,866,55,161,809,119,614,269,269,697,0,328,415,304,305,870,745,836,77,393,364,899,890,90,613,634,242,925,41,604,462,461,811,948,373,330,225,343,105,441,941,308,791,285,576,481,636,219,142,120,322,289,221,867,913,386,838,529,6,887,676,736,76,653,282,298,110,445,12,244,521,59,153,225,470,599,245,186,776,627,901,989,551,870,523,421,950,554,469,155,557,219,543,832,798,106,873,105,734,553,280,445,598,938,948,353,174,582,69,58,620,140,153,456,824,95,756,233,101,431,695,82,599,255,132,100,623,840,245,825,604,497,388,733,354,800,185,718,250,752,229,826,414,512,205,222,66,556,250,420,684,455,802,809,555,111,416,902,408,596,996,363,967,779,736,688,275,582,934,990,480,539,676,894,859,963,293,25,407,682,669,545,378,650,957,233,597,856,444,400,322,274,968,325,584,166,396,169,411,137,669,15,286,308,645,833,59,899,623,456,527,897,215,954,635,516,540,19,616,956,269,812,764,183,971,607,803,347,272,306,530,881,754,231,826,473,627,100,339,509,16,686,714,138,605,86,186,288,357,292,24,882,104,979,345,97,418,533,577,771,959,44,733,458,834,483,786,492,885,194,512,302,221,359,34,396,957,336,314,582,714,57,565,27,865,584,699,933,410,356,403,21,500,763,56,97,656,99,843,943,921,22,742,575,938,859,494,113,26,130,367,585,954,362,78,594,921,426,166,609,433,287,812,563,643,301,585,102,345,707,320,457,981,998,303,478,761,682,327,562,846,624,487,95,872,740,523,402,745,388,189,720,52,801,813,830,718,234,940,416,349,957,496,283,636,319,491,575,992,696,437,8,100,235,907,109,89,630,562,787,514,601,920,651,51,801,709,768,521,968,480,278,844,379,618,217,298,592,522,863,562,485,992,792,778,152,884,939,821,213,834,785,8,601,395,550,849,735,861,257,512,825,23,118,660,727,600,242,937,735,117,1000,536,801,521,22,634,873,47,708,602,910,955,190,788,364,738,261,386,834,184,89,675,617,438,10,809,684,892,688,801,572,2,105,164,553,782,72,431,841,924,668,855,588,621,610,370,55,448,558,891,138,63,352,585,530,305,368,570,883,41,7,690,555,70,171,151,510,79,889,529,945,740,206,617,121,337,365,722,271,175,312,848,82,192,559,942,979,513,478,423,712,117,272,780,250,272,968,163,950,186,39,466,988,80,37,147,662,250,4,769,799,55,312,358,599,768,815,651,127,104,760,728,286,843,374,328,981,938,244,576,267,222,265,895,318,125,872,373,534,630,531,503,723,254,953,613,376,687,697,565,49,813,146,463,52,189,912,152,288,180,785,296,232,387,789,781,766,926,128,887,487,791,272,172,713,442,572,849,800,60,51,991,271,628,222,701,234,11,348,372,644,112,267,291,742,623,606,452,50,444,191,757,376,862,457,494,748,546,22,200,638,427,943,872,125,296,355,517,950,304,274,816,335,156,577,435,96,668,302,108,879,498,365,336,39,670,736,363,108,845,643,50,718,633,179,205,989,631,20,917,237,812,133,294,220,527,84,234,812,185,226,191,968,387,115,20,933,741,808,518,226,686,969,666,967,129,732,404,499,506,210,324,280,155,332,766,184,593,610,267,934,163,357,534,928,445,324,986,639,329,480,883,320,292,891,500,174,722,42,297,348,133,365,89,229,539,903,263,315,631,992,75,80,807,784,524,177,708,176,677,426,299,732,960,815,33,540,186,859,340,834,361,719,500,773,304,955,569,680,778,837,924,436,794,875,889,413,919,849,339,771,118,816,746,139,339,54,859,557,428,877,356", "558,976,402,222,981,451,152,63,255,85,606,618,199,322,398,256,206,137,780,389,146,836,35,141,830,445,21,424,271,318,811,544,90,153,367,195,626,153,635,778,877,33,824,908,351,392,987,462,751,678,603,496,993,82,932,398,93,327,516,730,916,682,906,139,69,289,853,314,44,425,996,963,977,309,233,434,262,950,614,852,628,903,404,792,276,777,424,458,738,38,622,756,32,890,563,696,92,736,56,247,673,53,913,209,445,856,892,402,510,96,686,54,337,345,836,635,604,845,380,226,521,625,27,348,246,7,737,242,536,96,62,816,849,507,816,91,857,728,41,568,669,871,914,448,915,704,243,394,81,354,33,864,867,838,32,43,278,226,599,665,262,22,28,698,738,58,767,781,528,677,867,428,82,332,459,537,856,192,22,585,764,116,369,67,549,294,233,305,514,949,36,757,213,352,496,908,986,447,979,176,219,860,938,564,511,650,160,328,0,381,665,153,486,30,330,560,124,216,809,86,593,867,596,948,589,167,40,906,51,134,600,78,404,570,597,577,750,782,488,145,69,925,271,581,344,884,817,765,988,285,928,129,310,777,337,889,116,786,831,708,111,75,523,305,778,468,334,437,392,214,830,772,837,829,160,881,188,118,472,914,816,336,404,311,56,194,615,84,747,897,823,15,92,431,218,999,103,135,266,249,97,922,121,647,548,277,381,565,181,646,843,906,475,709,251,940,797,941,330,246,970,822,806,75,352,173,549,142,60,292,110,376,532,11,351,956,53,377,871,815,464,548,243,502,751,462,675,372,659,877,723,298,842,669,710,635,905,253,279,162,644,38,911,108,629,69,83,701,269,811,102,130,183,302,574,884,259,320,537,621,283,716,583,594,531,298,118,55,288,382,293,550,570,31,950,28,337,776,566,855,611,763,533,606,328,642,994,831,631,688,597,35,492,553,572,250,363,786,62,290,339,93,66,617,962,507,559,907,789,702,361,570,73,357,488,248,5,150,973,354,301,925,429,971,533,175,401,641,736,247,348,461,299,42,777,147,947,705,78,361,749,668,528,873,258,732,933,975,932,446,466,165,693,279,471,265,682,941,158,61,403,530,419,883,270,42,334,51,230,150,505,447,59,682,340,895,686,234,833,40,253,890,554,866,585,950,745,232,398,520,607,309,977,772,577,870,594,946,528,164,919,381,732,983,343,249,975,666,65,336,590,516,569,58,703,257,371,619,875,978,156,963,305,724,807,595,359,250,150,638,510,732,441,63,54,94,643,376,593,36,254,773,329,794,294,350,206,172,646,867,698,368,64,871,536,837,542,2,617,403,32,851,935,407,804,650,917,4,840,311,794,937,644,719,850,589,305,993,100,624,260,317,493,552,814,787,645,225,354,625,88,775,682,718,421,894,332,478,103,330,839,849,365,702,502,617,601,815,802,895,479,539,300,435,293,235,174,18,796,23,718,349,240,759,211,248,421,47,959,250,879,759,792,479,424,796,71,219,21,692,851,245,447,174,408,516,734,75,581,776,647,503,691,619,506,236,804,790,807,841,159,903,988,803,536,508,734,12,75,554,52,313,530,220,88,818,205,246,835,858,541,979,228,572,885,83,642,104,568,890,800,815,202,317,244,44,638,683,529,493,123,173,150,73,592,137,324,685,201,131,468,862,610,220,330,647,826,200,131,552,776,582,560,420,731,843,446,668,175,571,248,372,613,327,564,55,851,450,479,75,436,673,48,299,283,384,576,267,880,883,220,883,166,460,846,753,143,227,183,759,247,706,140,183,611,80,150,180,312,616,583,465,238,970,385,497,534,409,454,270,775,693,180,453,81,232,822,611,309,519,865,409,657,786,508,860,373,554,949,795,509,285,257,80,828,104,418,211,655,992,328,606,761,40,698,400,47,978,355,424,711,898,224,254,88,162,18,326,433,682,739,310,613,348,204,214,731,311,870,195,193,499,173,713,342,105,149,298,406,918,107,961,348,413,139,542,191,276,251,899,168,538,78,767,444,328,430,483,241,379,640,621,518,670,797,607,764,450,648,794,20,871,209,327,585,381,36,324,650,405,963,163,403,192,240,927,590,970,999,197,293,317,695,626,383,194,57,366,437,503,257,791,183,920,457,347,470,938,346,962,587,252,992,515,85,261,671,763,822,17,691,350,309,385,537,295,69,792,958,628,569,906,815,512,535,933,730,922,37,14,628,285,931,391,908,805,712,559,172,837,389,949,307,674,581,285,663,620,567,118,638,935,318,591,340,979,768,529,448,159", "298,778,768,881,661,602,417,667,287,655,582,473,360,616,354,150,10,457,29,252,461,328,773,72,862,113,852,79,211,697,185,857,609,411,862,828,526,435,356,406,873,842,852,721,239,282,857,476,665,319,737,23,859,101,116,614,878,941,521,856,724,297,771,599,131,395,426,872,854,252,129,450,754,268,899,328,55,744,325,78,387,851,573,998,284,885,465,953,589,300,48,969,542,368,647,299,981,27,620,572,378,162,370,470,582,965,670,830,250,513,145,823,165,78,973,419,837,649,445,169,603,858,771,159,553,391,489,256,359,776,25,396,899,57,679,699,364,340,926,912,43,173,148,935,389,850,988,635,31,51,850,17,891,175,728,603,108,192,956,656,548,408,564,573,953,531,629,290,341,847,305,441,59,306,626,783,107,944,683,563,578,486,414,527,372,991,730,832,747,914,48,223,63,853,976,81,529,569,815,315,401,287,339,616,253,228,124,415,381,0,267,529,681,825,418,357,754,208,528,678,465,272,232,203,462,43,797,320,436,575,355,414,736,249,849,669,633,858,799,876,771,203,394,630,911,376,557,253,357,733,913,381,59,371,217,565,820,565,515,526,885,383,944,214,861,99,555,466,604,677,588,891,67,380,811,190,9,179,396,670,324,319,575,37,300,498,21,688,539,119,993,448,358,495,101,530,743,775,184,903,394,732,510,11,530,352,737,404,805,153,404,845,341,357,599,922,4,289,51,734,628,38,465,613,522,825,555,499,538,512,440,378,516,143,507,947,815,522,488,949,881,985,763,297,748,581,330,471,374,493,596,851,218,649,711,180,22,754,933,518,475,694,431,848,507,213,415,5,100,48,579,23,532,273,980,200,106,234,511,4,276,889,263,748,281,192,152,203,848,791,142,848,147,411,896,86,108,309,553,916,946,663,744,574,812,670,964,71,293,247,524,553,860,453,666,197,553,658,173,666,397,452,887,777,195,82,216,44,331,746,355,388,469,104,413,834,570,805,870,769,510,924,477,989,628,459,387,36,158,574,450,900,466,264,329,96,238,330,617,371,925,204,231,581,535,952,745,260,170,113,685,744,804,154,980,389,834,958,334,965,29,118,864,687,26,398,626,939,100,109,463,542,512,576,966,248,324,381,675,732,33,99,301,636,129,13,863,969,387,499,293,638,883,360,969,760,699,117,430,937,210,542,169,654,796,505,849,474,549,610,827,377,264,586,225,337,172,261,695,989,832,143,940,117,583,151,220,445,863,222,11,815,364,242,408,849,933,55,327,399,802,121,855,65,713,633,423,259,510,289,64,431,400,96,781,866,563,75,179,936,485,453,288,641,201,680,352,20,543,418,826,80,366,303,641,889,31,803,688,176,186,565,448,566,725,833,452,979,802,244,427,447,236,943,511,826,742,132,749,48,517,105,917,29,403,900,505,222,815,593,88,405,887,903,869,89,282,719,926,515,350,442,971,455,207,629,336,101,903,912,671,829,502,739,602,486,834,981,31,111,366,657,644,216,124,410,800,219,508,677,328,363,371,903,576,206,95,73,647,335,386,225,216,19,178,594,612,179,559,803,362,183,784,903,319,841,59,87,931,990,691,697,638,973,646,773,184,772,438,316,935,403,292,785,259,204,85,137,300,410,29,735,912,637,443,850,202,410,612,371,86,691,277,832,353,899,990,669,503,6,216,693,18,77,974,94,954,991,844,675,387,966,627,654,262,5,734,420,462,823,552,75,213,369,628,100,185,237,165,680,212,62,903,71,346,101,693,512,488,385,663,392,431,846,443,954,725,574,452,915,464,232,409,216,303,534,260,317,15,5,192,425,225,509,976,545,507,887,506,681,57,14,215,848,434,419,844,993,824,918,649,940,938,165,566,223,451,632,403,888,725,812,726,706,887,897,551,485,155,910,172,704,222,667,862,104,996,59,379,609,714,703,255,565,714,492,8,581,666,696,320,163,201,513,457,644,366,874,473,236,990,899,626,811,116,196,189,633,278,761,866,706,829,525,249,324,394,435,572,197,447,542,53,848,156,260,405,340,954,812,238,478,200,55,111,582,295,219,594,156,597,952,710,19,820,473,934,751,4,852,477,170,550,214,146,298,251,837,98,524,41,916,249,572,630,34,409,497,553,153,236,790,582,278,763,372,464,596,555,505,140,896,57,112,192,233,457,738,372,513,743,178,806,799,821,697,678,250,500,692,351,767,846,378,507,502,206,219,819,290,458,444,658,25,256,235,907,545,820,617,980,9,221,674,388,699,884,987,576,802", "726,842,262,247,158,48,852,580,147,328,451,248,362,476,191,117,776,66,348,153,369,843,880,774,140,486,941,377,593,625,985,634,888,955,658,762,935,877,768,231,748,437,53,865,510,952,485,982,81,658,598,609,922,683,617,767,991,864,779,18,356,339,682,424,297,362,633,955,58,598,564,830,371,559,277,161,915,298,94,278,629,778,42,803,886,438,314,19,766,76,3,679,175,324,593,341,481,391,585,156,311,838,210,366,856,786,916,518,728,580,677,481,954,581,633,222,677,272,916,905,630,71,12,836,966,331,96,709,244,100,853,176,191,736,222,796,701,827,509,94,232,176,176,339,202,582,346,624,741,895,283,891,615,722,56,866,581,440,798,943,878,112,900,825,772,642,163,891,237,220,348,817,757,912,612,386,759,229,280,679,593,953,810,464,840,311,840,598,465,910,484,574,665,222,933,799,498,755,416,436,377,431,315,341,246,111,526,304,665,267,0,621,692,913,633,514,557,54,267,517,710,544,951,101,432,401,24,108,202,84,452,819,134,588,751,922,159,7,411,796,554,619,171,181,56,540,354,277,737,745,79,873,257,4,175,697,326,266,79,40,970,112,516,208,476,817,793,991,166,71,885,79,264,926,771,635,235,566,975,98,636,447,570,148,165,301,389,73,801,165,541,581,148,545,252,220,236,740,456,656,56,474,797,556,28,895,591,12,379,361,5,166,361,495,640,745,248,140,643,215,544,22,884,959,534,608,459,250,359,440,914,697,604,973,735,73,360,43,290,204,252,686,689,488,314,368,184,175,846,771,869,232,877,134,404,510,447,953,494,859,868,962,800,832,894,790,913,440,46,443,954,879,777,833,526,517,34,150,372,861,618,725,385,257,659,640,149,524,799,101,448,859,927,304,642,256,368,446,967,885,409,516,416,745,82,368,155,202,212,155,415,487,169,668,271,172,448,619,462,827,140,922,789,471,605,220,76,38,712,437,994,367,49,334,691,194,160,694,336,951,334,262,688,109,817,909,879,122,485,128,509,984,141,714,270,394,378,187,14,314,913,177,564,666,492,92,886,720,866,67,635,532,109,590,587,708,203,595,575,405,540,386,198,427,4,459,552,824,892,588,550,146,228,91,965,560,451,825,286,623,870,903,317,739,506,669,365,740,939,883,261,514,720,417,384,143,378,876,588,783,303,65,52,644,250,341,76,92,613,346,398,197,998,274,529,83,776,922,573,428,312,196,639,443,283,446,678,258,197,409,870,349,93,762,362,208,60,400,242,159,642,774,363,366,859,498,595,678,101,278,216,990,281,363,36,339,938,213,636,377,403,749,462,928,219,215,561,711,886,270,806,275,541,904,747,749,967,39,635,333,693,85,566,14,912,712,631,536,383,749,922,190,337,979,576,673,833,483,745,248,962,209,184,563,82,268,455,291,608,300,591,699,722,539,213,735,578,707,412,94,230,564,825,338,271,396,752,850,546,90,794,945,884,386,923,903,653,186,967,498,630,668,679,387,232,712,541,288,680,666,349,95,89,52,830,504,403,670,829,771,97,147,902,353,312,417,703,21,669,41,665,454,216,300,297,335,442,709,383,947,61,605,644,991,870,12,310,312,622,303,18,433,818,244,439,796,674,424,90,206,469,315,78,147,84,373,831,471,725,919,641,545,467,320,452,123,638,753,267,41,144,254,861,789,831,559,643,552,375,192,85,54,76,642,261,390,762,52,240,596,202,329,170,428,534,656,363,527,45,524,485,966,747,588,495,225,436,925,336,638,183,762,965,993,116,981,784,933,88,117,5,232,999,249,752,942,542,287,760,115,757,485,229,329,14,416,646,745,580,793,410,458,613,562,196,788,648,813,378,812,481,563,269,163,823,201,993,241,695,410,887,258,213,184,473,747,216,972,24,62,104,701,320,645,414,765,165,672,203,909,100,222,687,841,742,21,629,397,249,774,489,251,19,329,878,313,384,565,987,547,143,872,590,206,840,248,653,717,422,161,890,681,453,612,326,278,531,409,492,541,355,731,891,258,894,679,816,772,340,329,335,3,113,822,152,60,204,873,983,473,513,959,731,324,703,383,40,214,286,495,987,87,247,636,97,40,432,391,387,648,332,707,775,799,474,598,464,105,344,499,754,273,847,75,598,903,995,929,251,20,308,855,20,407,378,126,839,913,923,814,643,251,169,778,163,507,934,759,833,637,762,912,30,566,60,723,908,126,477,750,87,997,831,400,939,685,930,201,593,525,904,451,844,209,477,109,623,334,190,964", "899,967,257,954,123,408,326,959,195,177,450,789,368,823,385,205,648,239,175,299,23,948,962,525,681,578,864,13,522,710,302,983,437,886,824,327,662,349,298,761,556,319,4,87,4,85,475,979,165,566,729,724,713,697,739,681,235,641,843,149,520,487,864,986,569,485,258,958,147,750,342,655,499,564,580,742,556,564,265,480,695,998,935,851,635,136,678,581,680,647,77,460,391,901,835,526,499,62,971,32,316,967,913,342,476,13,20,635,932,234,17,237,185,681,271,522,793,597,222,366,860,363,528,802,612,221,674,220,440,405,997,935,776,546,116,462,733,165,938,302,58,36,274,795,390,316,370,888,143,607,464,63,701,680,649,854,182,26,628,475,244,52,279,59,686,127,564,237,530,261,239,474,586,768,551,530,326,126,140,614,852,306,334,700,188,642,157,94,73,362,940,264,426,488,700,183,985,869,87,579,569,921,893,976,956,175,624,305,153,529,621,0,449,747,788,697,323,184,343,925,539,620,353,267,137,628,925,487,627,725,414,218,303,894,332,460,319,461,212,448,674,678,50,446,479,731,548,556,572,768,136,878,15,601,105,515,544,751,196,371,434,852,650,792,764,648,31,443,242,796,634,439,202,297,539,685,851,107,766,193,198,134,950,920,321,293,84,394,197,221,513,751,942,234,459,614,64,190,450,828,683,709,219,292,920,557,597,271,330,838,432,808,131,152,647,354,297,421,657,984,169,396,355,293,827,185,900,322,779,666,496,141,778,75,887,799,781,912,173,932,355,340,792,66,793,609,24,93,626,441,301,98,282,767,768,972,909,493,192,743,405,258,203,949,420,330,204,698,367,769,351,437,624,68,709,597,274,873,778,726,944,815,138,975,350,474,158,166,345,588,497,359,42,916,350,302,870,626,914,476,739,630,278,232,676,273,193,173,372,705,489,799,911,234,411,144,892,570,177,845,115,340,219,624,543,334,721,688,580,547,516,270,422,875,71,163,974,168,622,649,55,389,1000,519,254,433,50,969,132,834,633,55,18,499,820,512,167,371,617,336,596,249,957,362,277,596,814,402,993,123,287,298,216,782,665,815,797,500,644,188,724,879,359,305,482,216,448,223,543,158,51,413,150,397,954,820,377,190,537,285,792,848,904,98,44,595,932,839,462,699,807,827,280,539,342,761,449,746,479,582,951,723,621,419,320,3,753,650,232,160,546,332,900,197,801,861,32,592,647,650,757,205,866,152,592,570,611,968,750,572,217,533,960,307,258,879,340,548,464,872,372,29,620,374,912,339,554,357,973,632,813,207,830,551,625,820,354,753,163,285,369,539,451,163,224,65,927,888,118,880,222,966,691,651,621,606,932,575,500,603,920,445,136,51,924,635,927,152,371,860,690,444,763,780,18,192,272,680,353,6,703,485,416,42,219,532,52,387,950,149,362,918,5,814,654,610,741,844,480,21,742,89,641,53,767,61,288,367,366,946,621,443,647,973,650,653,986,722,703,310,216,531,905,439,164,193,236,999,718,124,551,122,730,221,265,342,512,868,377,48,950,517,958,834,957,945,162,823,579,713,404,181,717,129,998,908,342,182,978,546,556,774,149,974,287,327,860,65,908,769,293,515,919,717,467,795,906,326,416,568,887,901,367,278,192,337,805,419,824,312,555,939,648,28,364,553,499,862,264,795,991,278,660,788,24,75,829,860,901,27,346,284,544,579,247,183,208,554,51,329,602,819,667,856,13,404,918,378,837,632,741,751,574,919,330,748,666,800,343,809,642,181,724,927,813,99,732,661,662,379,167,81,224,460,88,856,519,679,422,364,95,140,9,878,389,439,176,635,381,184,381,751,573,493,338,661,527,444,227,765,850,818,976,976,796,912,686,890,297,79,767,666,331,570,262,3,860,949,554,526,232,1000,520,801,972,722,174,386,563,484,141,435,494,970,28,407,414,679,82,105,109,760,340,585,976,86,583,405,329,185,694,352,366,271,19,887,373,382,375,783,659,566,924,178,268,615,382,845,194,254,778,42,95,238,781,950,436,935,447,681,759,378,681,168,762,600,670,696,180,562,135,904,800,581,979,97,47,492,436,267,318,431,767,500,136,962,924,663,896,501,626,880,187,446,326,525,116,894,610,907,513,901,891,119,17,410,826,134,18,569,712,389,207,759,281,890,462,129,594,670,748,217,764,346,99,935,52,149,284,146,944,536,197,232,781,178,517,685,924,261,988,875,307,730,93,326,668,102,374,810,692,517,256,733,339,845,203,807,267,185", "444,875,941,128,21,122,445,648,163,197,475,754,711,651,742,323,169,552,724,914,535,441,339,400,790,287,447,374,37,937,70,967,440,476,364,783,790,573,564,30,314,535,701,193,298,994,966,752,100,896,135,675,939,2,98,338,664,673,640,361,863,53,136,358,198,934,933,463,945,172,68,934,40,346,535,355,742,397,500,409,118,454,45,423,171,852,785,264,422,758,479,999,37,458,840,40,705,557,354,459,929,837,32,723,82,195,148,792,753,482,910,804,489,586,787,689,8,622,918,768,381,615,681,626,237,908,940,676,893,397,710,993,805,787,297,55,954,368,412,599,101,571,444,967,234,195,128,966,266,891,865,944,267,206,60,314,424,334,500,675,978,417,199,701,763,813,729,538,106,373,527,838,11,979,655,169,117,46,723,757,54,301,418,994,912,395,195,626,744,225,654,537,119,680,510,792,216,996,982,87,233,941,101,426,560,380,607,870,486,681,692,449,0,205,914,184,337,391,685,429,467,846,649,720,85,802,878,665,20,260,718,970,205,307,32,75,597,127,844,996,305,366,976,706,65,82,903,462,341,779,582,496,201,105,58,733,66,856,575,365,917,187,6,839,448,770,340,954,26,483,382,963,207,5,32,707,815,112,581,216,63,480,571,894,293,353,90,54,435,667,981,680,44,835,954,710,818,729,378,537,495,354,75,237,833,473,685,779,468,59,880,584,369,413,695,644,327,608,121,212,986,471,361,90,219,223,382,928,452,16,411,359,780,897,962,694,735,696,187,351,889,970,341,932,170,527,160,649,972,186,965,31,918,243,393,590,597,480,585,921,615,5,649,915,825,888,789,621,189,281,427,780,573,731,438,592,589,405,584,882,118,277,812,970,626,440,587,756,775,135,273,922,966,410,286,351,291,869,934,363,16,310,990,576,455,511,862,708,49,551,629,409,471,727,502,252,155,104,510,906,155,376,916,135,677,708,300,937,481,330,606,844,88,993,862,148,422,978,755,527,248,784,451,730,209,700,146,287,717,493,432,500,371,160,742,95,207,49,755,155,831,651,347,655,164,862,857,946,186,395,164,220,183,332,266,203,21,70,360,303,57,369,465,653,191,439,89,644,541,361,299,592,927,6,175,222,814,198,400,508,59,978,187,55,595,80,569,116,375,280,352,283,928,679,824,664,348,724,31,850,8,904,246,620,408,127,531,671,465,196,234,455,546,105,817,265,773,586,673,882,624,190,885,559,57,901,758,760,131,741,305,410,659,584,452,695,445,568,282,376,717,954,622,650,989,610,234,635,17,314,107,770,758,911,395,179,389,548,827,400,223,928,997,894,932,247,755,916,236,610,765,209,355,119,286,747,7,413,414,924,377,979,618,178,852,798,89,587,970,641,340,518,947,598,172,941,157,734,19,260,999,899,559,778,299,902,487,869,487,622,462,467,464,493,410,539,924,369,21,974,619,237,17,706,436,149,110,583,389,402,438,922,626,475,780,717,251,520,462,708,549,509,280,849,883,376,712,598,859,878,332,73,387,798,40,563,622,471,869,192,870,430,907,394,531,604,62,832,9,967,930,698,866,290,968,631,79,983,315,25,73,716,958,400,289,407,236,916,511,647,165,186,727,264,26,557,310,143,292,165,608,458,209,823,97,39,523,645,362,406,394,436,852,270,266,942,590,255,417,82,419,349,3,7,728,826,598,275,754,684,758,456,498,579,200,381,147,919,822,478,967,142,632,878,697,599,543,858,105,626,886,327,677,590,989,879,16,403,852,547,738,568,813,124,9,28,618,560,837,279,71,379,600,956,302,68,366,470,944,314,267,216,880,501,824,43,651,69,273,646,336,377,244,825,321,777,712,722,128,340,229,218,884,309,392,45,595,311,595,862,58,729,808,924,384,732,614,942,770,972,835,955,171,517,243,553,269,34,781,517,631,427,66,857,264,83,855,666,749,494,324,613,296,651,303,672,834,367,831,812,932,293,502,180,387,968,25,283,170,861,307,463,912,701,951,648,294,110,141,827,304,275,180,784,65,168,827,224,572,716,74,612,931,977,658,648,53,734,654,303,453,718,788,311,596,944,828,66,228,319,861,126,282,569,111,352,311,258,682,739,647,136,834,816,925,307,615,299,318,134,786,936,103,800,443,475,235,178,319,299,623,11,898,883,988,173,660,160,580,640,543,414,71,877,811,962,916,289,229,853,315,62,951,160,292,626,633,321,888,140,472,532,309,615,555,149,479,140,954,339,619,492,122,717,645,189,627,543,691,200", "420,668,118,478,946,297,917,234,166,911,717,567,736,177,801,794,636,777,245,703,362,685,54,15,155,474,417,75,229,959,765,53,994,712,235,926,843,388,212,582,713,264,166,946,242,832,706,821,602,539,990,602,786,696,581,731,927,726,515,11,77,107,648,308,601,96,225,467,50,856,628,155,500,411,365,911,919,72,591,666,685,588,80,121,672,277,28,983,137,713,881,133,267,345,598,213,961,465,289,647,981,33,811,655,111,166,556,433,225,395,917,423,526,923,776,1,252,449,509,460,2,437,115,146,105,230,979,416,562,861,73,138,715,330,538,838,543,169,17,270,582,942,718,127,653,938,938,967,799,325,364,293,478,873,833,713,890,375,787,320,828,956,587,453,776,162,977,854,495,912,508,927,842,444,357,910,339,210,331,545,934,286,189,865,729,662,447,303,364,837,759,501,470,131,358,697,566,202,435,745,315,842,117,969,974,157,369,745,30,825,913,747,205,0,862,60,571,602,313,681,645,13,422,357,842,336,644,807,985,273,663,954,56,970,320,934,290,921,214,668,88,659,748,559,657,209,505,292,731,717,659,991,644,660,14,295,118,534,528,987,846,698,611,725,848,554,935,550,170,624,185,30,674,941,183,751,906,406,861,878,914,646,760,887,265,611,843,405,499,766,724,597,253,748,290,335,24,341,620,246,495,383,893,26,929,439,524,486,366,716,895,723,162,608,605,688,525,728,228,865,540,19,377,701,77,746,343,142,931,683,876,419,77,27,81,245,873,796,609,297,766,860,257,924,137,448,495,50,262,448,94,280,556,976,526,896,937,472,945,360,450,129,584,201,775,428,241,891,560,133,549,661,781,701,104,888,813,288,701,215,191,378,756,69,570,231,123,596,61,119,906,378,527,375,159,499,925,47,367,411,438,893,158,815,496,337,916,132,661,631,491,105,338,966,576,847,642,687,434,503,115,709,653,931,537,289,238,562,603,950,545,716,222,893,214,852,945,402,659,904,187,141,261,349,555,67,594,905,268,478,864,833,123,785,142,500,986,184,868,377,987,503,476,17,737,426,775,677,146,283,990,984,183,784,534,382,857,653,378,466,567,797,219,159,92,425,67,292,80,951,638,776,114,296,184,615,607,35,975,101,677,40,161,69,212,101,86,676,704,584,137,326,740,830,208,784,293,408,86,923,938,58,403,929,900,944,419,177,101,337,867,480,877,941,375,948,708,100,368,812,730,341,958,936,158,307,19,689,960,767,317,553,923,38,684,556,33,902,682,359,596,870,906,352,595,893,511,74,664,606,810,942,792,143,217,613,493,588,893,623,141,130,25,626,494,889,645,511,929,504,939,921,876,282,700,480,394,595,913,48,476,233,623,619,10,122,458,997,429,436,905,19,997,320,395,680,214,244,124,343,364,463,729,752,631,364,47,942,869,692,466,719,6,31,750,459,174,775,834,893,880,114,4,978,646,300,129,470,285,223,476,89,553,113,517,601,769,933,201,544,61,456,889,907,714,63,526,739,244,76,246,297,828,382,190,658,164,886,544,610,365,697,598,70,542,712,672,127,262,326,102,467,227,789,499,77,504,879,267,542,965,337,901,135,68,975,44,744,70,857,774,840,882,280,862,262,342,124,53,546,919,790,593,398,598,165,459,546,162,853,872,137,103,174,637,779,27,481,719,827,668,394,188,595,617,681,568,164,887,243,577,372,977,624,587,895,396,737,91,25,510,689,939,443,818,144,661,372,474,745,291,115,30,667,66,832,677,267,636,541,422,106,152,866,544,32,452,637,233,724,283,744,457,166,345,113,243,253,256,197,103,703,172,733,607,480,995,758,262,524,372,442,395,902,421,69,289,448,456,262,789,731,547,755,573,623,898,970,855,1,276,454,786,565,264,304,172,199,733,856,795,410,936,717,410,271,704,245,627,345,256,540,753,157,461,293,424,586,266,16,628,960,952,650,859,310,131,347,841,909,316,185,993,893,15,507,129,34,980,810,527,977,140,148,886,688,981,611,431,234,203,220,716,228,497,794,264,205,490,437,135,856,270,671,839,491,155,977,408,538,264,602,330,84,542,718,275,191,993,753,55,142,133,240,720,105,437,645,834,268,697,740,109,602,240,640,981,470,807,770,215,258,439,611,610,846,400,244,618,696,533,556,944,606,767,633,263,164,142,253,836,368,491,317,530,584,703,787,628,704,298,367,211,511,684,780,972,640,978,323,292,554,604,871,933,7,354,35,489,886,746,455,204,691,242,659,963,657,153,690", "481,980,51,249,140,161,924,62,594,890,851,381,232,177,431,59,65,226,246,564,18,479,810,344,263,338,410,873,765,58,261,108,817,687,446,230,547,530,122,168,762,930,777,977,1,846,21,358,429,551,208,97,952,486,17,309,396,928,157,718,633,629,674,593,680,135,101,306,990,478,453,727,182,7,767,814,438,448,368,317,117,650,884,24,783,732,586,984,277,977,779,234,965,462,167,268,177,516,512,700,2,855,756,838,837,245,535,497,603,825,258,929,15,943,195,499,169,758,320,531,233,461,726,650,639,515,913,905,857,480,114,880,19,438,689,118,802,539,907,256,534,576,597,184,994,170,959,203,953,113,734,412,218,979,429,345,194,104,856,295,301,825,829,173,800,690,33,688,358,931,548,401,119,446,329,178,968,895,799,128,642,948,194,935,160,210,412,81,458,567,220,208,781,191,512,500,743,385,714,476,459,689,107,700,635,12,103,836,330,418,633,788,914,862,0,205,734,427,730,989,314,513,586,962,837,65,55,101,374,463,355,370,303,598,771,990,794,835,293,624,968,242,692,791,698,660,38,823,681,372,916,831,808,292,413,70,485,297,949,584,585,791,265,765,985,683,808,472,980,521,490,143,739,412,256,606,848,360,903,926,617,737,299,667,116,219,747,963,365,815,458,697,981,534,502,55,350,76,166,10,774,279,722,602,426,32,131,108,771,539,125,817,484,355,182,888,415,769,196,890,7,617,775,328,863,714,718,713,654,799,481,539,304,163,406,125,859,30,196,579,998,914,63,178,312,533,331,519,350,158,31,461,900,643,828,183,455,460,603,164,110,12,831,75,972,516,12,78,661,503,738,885,472,170,255,59,596,614,651,906,223,844,990,376,884,565,854,726,377,885,856,845,323,854,840,173,210,355,570,984,707,467,851,708,47,78,577,437,207,295,432,868,346,645,204,822,326,407,787,480,809,745,634,357,158,281,428,672,427,410,309,196,849,633,911,828,81,885,650,950,890,830,575,848,736,391,878,854,354,57,465,615,475,864,742,824,974,696,403,412,81,497,598,836,431,333,625,821,29,25,412,586,319,519,970,557,935,944,763,701,708,762,175,32,45,609,946,727,136,968,717,998,890,93,900,69,185,786,945,293,762,176,772,848,42,764,688,403,9,540,85,623,95,937,333,590,604,521,158,178,127,126,907,379,384,737,190,541,482,391,920,217,37,752,412,326,745,724,248,430,435,634,657,629,511,313,880,365,449,784,221,780,821,29,106,21,327,936,500,971,954,377,997,147,333,948,963,541,4,40,177,791,225,953,170,836,578,954,545,728,557,676,780,15,413,572,868,157,448,236,421,698,722,138,388,523,648,691,365,526,511,843,933,197,871,730,228,628,262,667,282,557,453,646,513,761,406,948,321,859,922,894,817,909,930,462,635,741,821,873,594,58,909,845,450,17,582,27,87,826,190,953,499,933,525,724,80,559,468,601,131,476,642,843,680,968,16,821,452,750,821,300,734,283,706,106,107,698,358,203,548,269,823,260,43,395,2,884,756,925,743,99,120,142,667,111,622,915,655,144,239,737,834,145,585,548,496,583,780,999,831,561,216,540,208,964,325,720,859,968,118,88,26,644,905,11,834,445,274,709,676,256,459,404,532,620,590,192,727,272,355,220,381,629,931,540,419,206,597,559,764,569,16,118,262,905,680,86,578,17,730,348,570,395,112,450,728,703,718,86,341,642,692,526,422,95,402,206,291,143,205,843,68,147,601,297,324,572,161,786,119,659,252,82,553,129,548,38,593,174,690,294,240,484,253,479,606,930,526,71,917,883,710,654,274,9,22,987,488,264,612,910,800,922,299,151,544,817,831,199,371,140,875,558,309,174,182,897,685,863,678,855,676,417,9,696,458,413,296,167,145,49,880,635,400,839,948,634,667,276,264,163,326,193,172,103,635,690,432,434,716,301,891,256,576,208,914,943,476,627,404,212,712,502,924,757,780,94,343,284,350,813,360,275,535,999,522,906,635,179,700,366,739,583,770,179,228,776,692,432,484,116,277,853,585,416,481,758,867,951,40,611,383,929,412,643,38,599,409,877,436,222,222,269,905,141,944,105,141,60,678,220,293,33,926,690,875,643,986,116,395,306,828,541,62,57,155,714,643,198,264,589,724,111,798,101,770,183,403,730,650,71,928,600,255,395,893,910,524,679,728,65,861,522,637,59,718,693,557,139,175,440,317,445,598,9,20,779,107,482,586,753,60,154,221,72,188,413,592,456", "714,367,170,511,526,685,798,275,671,562,373,793,33,963,971,600,532,687,913,48,398,100,852,845,22,133,152,358,675,686,838,983,971,240,384,220,708,125,442,732,27,119,119,32,602,627,841,712,488,545,624,251,392,578,81,755,998,910,43,303,446,562,27,969,191,393,686,686,969,590,995,393,135,81,456,7,210,81,857,779,11,818,798,387,396,106,607,349,192,984,409,169,918,919,546,538,892,833,12,987,438,650,141,594,890,646,484,124,133,545,275,729,902,1,229,998,411,765,46,969,885,953,728,55,926,100,839,47,708,342,701,613,968,982,649,229,493,890,618,942,363,503,865,74,578,801,895,67,605,258,502,437,309,972,350,704,225,606,785,130,333,477,989,337,199,152,127,545,598,506,553,513,91,948,308,615,627,124,702,285,715,954,199,448,986,841,864,779,565,145,359,679,585,90,413,719,727,536,953,924,834,956,512,157,221,322,534,77,560,357,514,697,184,60,205,0,867,369,43,763,268,850,74,202,374,837,830,796,511,866,339,735,19,739,535,843,479,385,689,613,433,810,595,719,33,7,6,413,48,563,962,333,136,216,941,149,604,416,466,415,171,925,92,802,43,384,577,738,297,197,496,248,739,905,319,504,55,829,31,101,566,531,230,257,944,267,573,767,114,115,909,420,380,408,793,155,681,434,580,177,417,721,26,365,155,883,898,733,613,11,838,205,580,828,773,797,703,970,199,821,794,480,436,423,266,934,546,582,88,566,763,654,141,224,851,386,722,276,325,735,563,437,652,681,342,291,78,786,58,527,931,31,608,843,175,458,416,390,447,896,738,339,328,101,519,4,308,439,115,996,458,126,188,368,254,610,486,397,127,460,947,505,11,607,728,506,585,420,761,658,772,251,372,736,771,516,208,179,538,26,74,753,95,880,667,998,59,694,730,530,574,295,384,274,174,866,918,351,844,634,402,879,217,982,208,903,856,681,832,317,833,685,978,658,577,34,777,144,825,144,551,162,837,376,88,631,898,926,216,738,64,714,813,669,842,48,956,583,666,834,825,831,198,276,209,395,322,210,770,152,783,116,515,467,250,853,645,810,73,627,695,889,128,62,807,310,194,597,20,964,24,940,476,824,305,726,62,328,822,380,434,644,593,588,876,451,893,110,610,352,219,842,323,812,537,321,123,708,456,656,803,906,765,633,231,490,571,155,113,92,222,942,915,779,710,777,779,716,896,384,919,508,264,799,999,430,134,393,523,539,528,405,172,133,193,753,946,267,701,19,245,417,902,896,183,334,893,921,841,548,953,234,860,706,252,132,539,397,427,576,473,562,757,204,605,709,617,227,394,715,580,970,934,288,691,984,104,654,467,352,432,266,541,156,167,243,994,457,893,473,769,561,852,420,363,194,237,698,175,89,491,477,615,19,349,964,837,821,354,718,742,274,492,846,928,153,441,602,255,90,834,751,848,649,671,928,74,233,483,807,587,474,945,569,227,710,921,977,709,778,390,953,60,719,968,905,42,323,335,871,494,478,575,720,834,304,630,251,748,623,563,679,573,451,313,430,976,214,95,643,583,167,647,693,783,794,248,210,573,132,573,311,552,819,464,985,280,965,267,947,457,380,405,181,451,867,157,377,297,256,101,742,259,723,854,365,218,484,421,983,197,789,108,138,97,828,958,917,264,540,286,460,938,392,84,393,971,310,598,544,724,334,957,170,588,21,105,906,373,283,723,459,421,251,242,363,500,754,543,786,726,40,977,597,919,984,767,981,221,920,938,70,202,92,207,773,225,514,249,573,66,486,41,846,193,397,125,551,516,206,726,537,813,633,902,834,83,191,433,765,255,329,937,574,874,482,941,725,866,139,194,421,945,250,772,798,859,462,504,316,530,591,619,52,329,989,188,948,331,249,997,794,760,8,84,35,544,66,67,78,393,753,673,183,12,188,387,210,531,58,754,84,927,293,692,460,795,769,538,340,407,937,266,833,576,76,477,309,289,274,387,387,569,82,551,793,624,352,459,130,122,893,625,677,213,321,129,620,173,605,392,396,808,702,906,945,546,88,437,794,149,374,783,993,807,956,175,313,173,722,667,236,831,576,701,607,982,611,785,734,187,111,966,618,378,491,976,437,221,534,8,898,998,520,975,111,952,67,782,585,444,306,374,399,403,822,190,972,815,601,995,926,254,376,821,946,352,745,132,422,865,481,414,752,430,511,310,86,927,775,984,580,609,825,898,900,541,187,291,543,84,979,376,640,561,716,294,938,44,444", "524,48,229,378,149,422,425,765,903,659,989,563,812,532,906,32,116,799,731,939,648,797,368,779,715,933,194,152,26,387,133,512,261,348,118,474,607,784,221,608,949,61,801,375,813,951,382,791,853,464,489,182,882,241,243,181,359,411,564,840,606,856,817,167,209,50,715,25,734,120,274,618,485,889,389,187,963,927,643,268,836,887,282,290,582,854,757,959,362,482,707,975,179,513,99,732,992,323,305,739,978,83,83,733,802,453,956,17,794,620,284,278,993,734,347,978,92,447,87,477,242,941,936,593,901,159,631,62,20,41,779,331,92,632,112,143,20,73,227,251,834,388,252,966,558,553,135,473,967,668,275,487,218,166,846,467,65,502,641,228,336,589,897,869,587,516,745,777,370,910,399,938,160,818,835,199,229,781,180,301,287,486,709,875,904,499,517,778,76,859,173,618,866,344,930,878,416,309,344,42,494,69,914,892,766,280,916,393,124,754,557,323,337,571,734,867,0,865,443,276,817,299,525,474,593,570,383,136,727,19,602,256,601,504,160,744,185,886,388,71,202,554,557,992,131,285,205,657,258,664,209,111,176,916,24,511,8,710,944,255,104,127,128,167,848,460,9,430,762,21,787,558,308,921,729,544,570,685,166,267,775,794,619,395,677,975,319,517,847,117,91,161,356,864,157,520,555,591,172,907,422,100,569,645,739,924,725,961,302,800,617,448,636,964,898,863,353,928,826,614,514,661,258,942,164,6,115,476,10,795,758,588,959,753,511,818,384,21,146,640,605,713,658,344,619,170,921,746,661,542,475,387,874,6,672,536,226,248,134,487,748,567,48,461,321,695,636,641,808,672,374,760,224,997,213,236,610,193,220,107,70,990,222,785,137,676,260,808,526,244,247,875,614,873,442,750,222,647,740,756,273,351,886,476,441,262,578,417,318,443,520,43,499,265,282,568,215,726,683,745,242,331,379,88,737,73,332,239,333,50,318,467,955,928,219,681,225,738,484,647,154,762,693,860,649,114,92,39,258,48,415,945,826,618,385,166,189,904,778,725,198,559,205,224,988,803,155,667,283,523,913,670,361,256,920,30,496,761,209,465,940,816,821,748,363,670,873,241,623,900,114,594,592,617,815,929,914,878,186,861,138,950,98,328,313,206,835,218,549,928,559,394,449,536,112,271,944,879,78,994,610,806,844,575,777,689,161,656,510,863,844,775,725,439,98,743,548,361,405,50,529,744,678,808,560,426,439,767,904,442,647,478,319,140,822,791,760,315,615,404,111,4,790,268,30,849,789,313,751,730,720,132,698,293,16,63,283,94,939,204,563,817,749,375,610,372,836,358,848,483,491,960,21,611,85,627,343,787,911,549,820,846,53,300,323,48,274,76,394,634,763,60,88,966,200,225,861,55,318,24,417,458,690,390,660,804,463,156,43,784,653,555,620,147,731,64,421,127,745,873,464,989,784,808,194,359,909,470,117,613,967,685,773,283,739,679,442,642,172,899,509,189,71,251,640,707,97,318,291,917,278,443,284,777,264,499,630,137,498,880,972,810,294,863,989,111,593,383,619,179,235,305,79,254,506,131,42,840,136,854,877,291,900,995,368,716,475,434,909,248,972,699,994,82,304,461,964,827,988,876,866,82,872,821,852,924,534,487,475,21,959,384,542,203,119,840,28,252,809,655,602,158,889,885,140,20,178,284,880,544,664,114,666,711,972,659,377,88,235,866,342,917,168,380,872,228,607,144,804,591,142,870,237,413,916,20,92,435,623,200,308,556,31,171,687,451,590,742,137,492,409,527,690,891,399,623,129,803,102,19,336,536,878,759,783,283,70,701,965,323,661,713,77,49,107,954,878,90,624,741,518,878,528,304,144,646,624,41,351,725,414,132,972,973,207,786,850,41,803,509,520,280,570,914,335,467,561,169,104,172,238,847,3,69,502,870,13,295,379,841,698,906,216,209,606,925,24,370,903,845,16,47,141,758,244,906,22,354,225,67,153,399,508,699,561,722,800,867,838,29,699,952,964,260,32,322,333,380,437,640,800,565,141,246,428,259,951,758,424,662,493,793,984,443,600,785,987,686,983,57,937,791,232,750,607,751,446,762,6,987,430,336,499,936,306,912,360,703,419,111,779,404,839,605,956,138,410,763,1,990,865,580,290,162,894,171,864,766,504,105,617,261,972,774,979,604,441,741,699,922,618,962,532,98,504,410,373,133,480,609,119,700,613,80,922,298,27,90,509,315,488,503,860,256,662,698,230,142,969,447", "633,424,865,363,85,83,323,225,873,736,311,852,149,708,415,445,110,490,902,849,854,614,395,755,792,400,575,631,313,750,993,284,676,753,813,528,714,871,349,655,253,395,238,605,577,725,665,998,977,928,393,324,176,201,190,256,120,97,251,219,867,450,901,560,371,827,984,824,258,954,288,85,207,533,796,745,496,995,721,865,655,311,540,512,303,573,783,805,51,809,462,211,806,575,244,95,101,505,195,456,851,648,346,516,74,335,862,652,237,989,279,962,218,833,85,707,535,355,62,284,352,119,841,727,480,443,248,72,459,177,360,197,607,23,238,221,816,19,163,797,720,210,246,262,120,6,717,795,39,92,643,862,942,152,607,174,567,80,35,84,856,398,358,247,670,342,922,796,722,999,319,845,599,119,520,658,832,163,751,43,958,678,818,625,70,428,577,437,572,343,52,700,727,307,750,658,608,597,31,359,137,856,910,165,816,462,332,364,216,208,54,184,391,602,427,369,865,0,759,683,519,246,845,963,392,360,750,773,194,439,579,427,587,592,1,803,966,68,369,325,231,763,969,813,552,969,490,348,983,958,740,850,148,84,642,460,643,316,723,528,966,784,664,782,129,269,264,262,634,99,322,955,389,70,428,526,420,667,531,371,320,254,283,429,873,812,507,136,89,841,339,949,326,812,453,579,1,437,857,504,57,409,602,416,465,260,448,315,694,798,961,285,594,486,943,317,868,445,645,594,824,746,95,490,75,522,380,997,895,240,959,332,359,866,483,191,751,439,554,229,954,821,202,963,390,784,672,143,769,917,284,906,331,325,244,934,942,972,733,766,124,450,19,871,735,967,133,765,402,639,476,604,335,598,512,365,581,294,206,412,827,736,26,650,142,338,552,103,123,244,420,440,262,222,609,44,285,820,858,883,962,836,565,38,718,954,614,480,746,753,471,190,505,244,474,37,53,390,408,880,945,915,859,229,137,482,689,123,632,78,415,515,128,73,929,882,738,749,407,298,693,559,232,652,759,343,94,85,15,55,922,233,408,106,598,329,702,494,795,50,917,154,544,495,840,878,55,112,114,786,225,755,618,401,691,558,729,684,838,535,769,119,840,462,935,397,162,916,443,980,415,794,866,225,76,404,162,175,475,759,376,495,33,255,72,53,480,725,238,12,569,884,112,495,820,332,473,375,162,983,152,415,870,484,486,421,323,190,376,522,375,835,741,799,313,659,349,257,734,721,120,795,639,674,676,319,816,111,350,803,527,896,508,393,88,152,304,852,744,214,750,125,617,611,207,41,505,881,123,350,139,56,50,247,421,752,199,938,121,188,803,775,31,937,512,82,417,64,195,55,387,570,967,909,17,383,279,775,12,228,613,332,170,43,736,329,430,176,431,693,341,49,5,214,681,757,717,769,263,507,949,572,721,52,479,382,262,450,52,983,267,412,283,763,59,740,555,23,207,264,950,205,693,219,355,650,937,663,897,36,964,90,829,407,383,866,411,739,427,926,42,372,944,159,875,477,995,951,234,416,705,46,746,459,18,372,254,88,306,392,394,426,744,943,549,709,830,315,98,110,705,717,684,364,512,739,971,261,755,762,968,580,529,854,673,873,228,997,451,695,1000,656,819,418,202,430,135,8,903,86,429,536,663,634,68,798,236,433,937,12,767,672,213,674,379,28,693,627,644,386,262,770,329,718,825,626,538,850,740,363,211,156,311,686,947,708,754,36,517,252,654,510,929,499,619,956,922,283,963,725,693,405,281,706,610,209,185,122,719,616,852,708,191,470,679,471,244,885,561,319,56,329,651,827,311,64,962,366,446,608,175,737,720,872,537,643,476,815,256,290,580,116,139,150,343,195,55,728,86,108,957,590,706,522,461,633,792,350,958,246,529,136,188,614,871,475,685,256,76,466,533,881,637,633,366,963,93,998,843,585,955,539,594,953,300,380,844,782,396,634,62,420,786,547,55,148,312,808,965,351,685,164,428,937,825,399,156,274,986,395,986,206,497,682,898,857,840,576,396,976,46,433,20,430,366,837,800,831,934,909,775,638,247,994,914,670,828,381,183,895,334,481,627,448,840,564,664,108,236,548,809,392,316,300,501,747,893,35,66,850,429,881,809,566,427,310,643,327,550,896,170,370,510,405,454,390,513,944,998,557,453,140,474,257,204,29,760,804,608,4,428,240,440,160,993,506,16,255,831,660,141,378,62,520,885,849,373,791,277,196,587,558,388,91,535,351,738,522,469,501,535,347,514,41,102,367,866,543,980,123", "897,692,45,108,254,288,297,714,660,183,731,151,232,58,345,436,549,316,406,414,501,294,654,564,177,619,265,587,895,582,275,795,25,664,456,833,685,603,99,539,468,576,284,205,738,172,533,415,133,908,311,932,426,89,405,837,443,571,732,20,312,122,892,82,41,660,257,150,776,283,689,295,650,585,637,185,613,944,660,367,266,829,871,681,486,990,988,353,249,664,886,762,417,496,936,922,298,477,335,256,732,760,158,763,740,646,14,315,407,884,40,408,368,954,103,523,452,663,603,603,518,618,476,148,740,207,939,838,290,995,149,582,937,353,501,696,13,455,434,189,527,808,728,74,852,370,502,901,888,910,251,842,269,593,392,496,432,833,467,735,267,868,528,955,731,457,628,548,813,621,719,500,566,158,527,645,912,868,672,414,684,584,299,777,632,406,35,793,207,69,580,259,636,448,517,299,289,173,765,140,404,373,597,269,36,838,50,899,809,528,267,343,685,313,730,43,443,759,0,103,322,699,699,192,907,670,733,520,891,463,479,200,111,886,438,926,147,228,488,438,639,686,40,327,795,939,613,852,212,647,859,82,890,35,968,806,165,340,911,780,125,50,870,131,435,887,224,814,301,395,790,671,459,555,846,332,873,716,10,578,214,525,421,302,520,187,360,928,703,977,665,907,636,971,8,63,462,550,512,468,332,784,577,387,235,258,462,488,532,697,654,145,117,68,365,270,902,944,643,101,477,216,49,745,443,681,410,561,803,188,851,753,578,197,500,863,304,25,887,498,831,100,536,765,649,942,181,953,471,83,579,535,783,796,440,875,983,752,253,760,369,726,898,884,49,944,972,723,802,209,671,241,478,378,323,999,489,133,852,911,588,303,178,559,19,943,668,932,674,934,353,719,450,682,844,354,256,291,570,321,112,226,337,143,242,50,798,229,879,536,882,616,173,44,811,270,625,423,854,529,289,55,471,486,54,225,664,207,516,463,671,255,371,422,620,233,862,286,15,348,763,893,145,553,300,292,270,401,965,372,866,763,985,704,978,350,139,267,373,344,968,385,78,599,63,558,660,354,946,799,147,268,782,643,357,87,681,354,655,494,128,769,192,680,968,615,712,47,51,141,164,175,281,560,427,682,336,82,45,59,894,827,456,214,979,873,815,781,854,632,169,238,58,664,42,805,776,89,733,232,280,711,664,509,273,180,280,433,313,335,328,914,274,427,508,410,693,791,15,555,58,569,968,843,868,330,162,679,611,548,170,639,596,322,643,696,75,202,281,39,198,508,688,719,368,630,786,782,558,569,923,665,941,457,159,443,86,556,270,213,518,836,718,477,258,702,677,265,121,133,833,634,811,612,760,87,413,323,660,154,791,817,86,743,904,44,37,732,730,886,797,42,790,711,732,253,818,36,780,691,759,109,336,120,722,192,287,486,391,37,458,985,551,388,27,895,808,958,913,956,898,960,774,170,626,801,894,429,744,166,619,665,900,132,626,962,995,696,231,84,463,808,154,87,600,299,481,168,943,141,953,625,52,419,744,473,403,638,209,500,768,853,701,2,712,599,290,121,566,115,881,18,901,574,522,708,277,592,22,711,724,718,603,867,164,287,221,873,613,14,443,316,539,488,590,916,810,459,599,234,793,550,778,602,388,78,881,545,541,251,749,516,33,828,27,695,821,562,361,440,463,712,811,884,291,988,749,77,756,855,101,821,568,158,831,771,948,56,903,23,796,699,259,179,149,221,679,509,884,654,147,987,95,51,825,747,884,929,887,461,42,468,780,27,427,510,117,118,183,801,37,86,543,763,711,926,709,358,523,430,10,458,474,425,907,248,864,492,784,757,517,21,144,11,171,754,340,460,763,440,575,364,796,503,201,673,81,786,354,245,410,766,213,354,58,797,235,780,754,562,15,17,763,457,346,162,548,276,365,90,55,329,528,764,327,139,441,456,238,143,396,642,9,182,84,659,360,22,664,541,458,964,418,220,149,795,875,60,984,914,513,972,692,380,52,481,279,187,711,186,51,949,164,5,978,103,950,765,82,862,863,387,152,957,78,466,743,175,641,312,512,783,581,692,636,893,794,192,12,85,882,619,800,289,348,985,758,956,538,869,359,707,898,131,784,653,181,343,456,679,599,938,664,983,776,139,983,578,871,114,318,575,686,914,787,103,995,452,574,921,191,785,454,414,319,209,53,197,402,549,282,712,390,550,33,705,470,909,310,505,986,683,161,99,70,801,60,700,76,452,918,79,175,526,622,743,768,934,869,819", "279,958,982,577,710,284,389,273,948,903,911,66,900,356,560,272,370,72,635,573,436,137,756,36,732,809,747,875,293,532,286,128,251,919,993,292,983,334,539,264,502,639,687,739,626,456,184,221,732,964,375,262,295,146,995,750,112,229,151,933,884,64,501,322,847,460,343,24,616,182,356,796,345,673,814,477,234,959,650,357,525,88,180,131,506,578,128,613,212,495,806,851,754,827,464,923,460,237,453,503,285,457,342,554,635,966,93,474,505,325,727,18,997,11,866,410,860,210,158,396,315,70,41,623,697,745,220,724,153,42,839,798,231,248,726,426,49,819,774,89,849,22,607,318,514,9,930,888,478,498,482,300,592,271,198,403,430,262,647,394,447,270,299,783,398,396,76,88,710,17,805,833,758,186,865,118,476,967,720,501,165,602,731,88,345,852,802,709,607,849,773,981,640,899,371,605,897,525,959,4,365,968,842,147,952,991,294,890,86,678,517,925,429,681,989,763,276,683,103,0,5,491,538,443,848,849,402,411,348,806,950,199,914,187,86,343,770,846,893,5,987,623,603,854,62,430,203,359,504,342,693,773,252,583,541,432,823,157,231,610,72,282,75,823,887,412,858,479,253,203,347,371,315,900,926,982,537,15,971,25,744,234,203,610,896,276,829,18,477,45,211,538,910,454,748,116,401,477,231,402,334,543,241,775,840,235,846,750,876,40,336,133,921,440,766,251,736,26,409,774,140,351,983,15,816,877,556,953,379,631,812,907,474,708,878,88,322,957,945,699,91,773,210,186,962,601,52,861,684,652,956,355,68,760,410,939,356,268,902,609,134,200,356,744,475,625,682,6,20,781,334,116,660,131,6,365,140,882,949,128,997,78,268,649,331,442,733,856,325,443,458,94,893,275,142,732,900,129,45,211,973,310,793,729,706,836,646,4,132,520,302,936,713,552,463,894,229,485,864,626,27,315,31,570,584,478,372,12,856,355,78,121,629,158,621,129,293,231,76,959,955,414,445,928,706,501,212,410,314,429,356,852,741,872,590,903,470,273,140,335,815,253,241,360,316,107,233,809,776,461,939,800,828,671,959,267,837,440,568,178,178,804,112,386,610,354,631,252,674,242,799,472,187,100,758,631,759,967,246,282,865,915,776,772,3,655,722,787,338,285,983,565,933,211,584,806,474,457,998,450,429,343,917,95,960,750,691,930,309,602,344,481,400,645,494,382,866,303,498,273,487,748,187,425,242,277,27,173,942,881,46,816,671,821,478,808,663,392,213,359,936,117,728,827,459,403,712,767,460,780,903,164,957,670,411,80,496,744,955,446,382,765,106,74,648,765,987,540,334,177,623,619,583,894,860,718,801,787,968,213,16,399,204,460,422,581,461,873,178,533,436,645,929,163,901,437,517,783,910,247,983,330,54,308,124,415,251,855,174,741,810,49,561,427,138,213,292,384,789,131,629,189,235,585,217,247,145,894,215,64,545,100,159,863,764,900,213,190,404,765,2,498,750,228,664,938,929,163,667,232,119,71,642,614,246,656,543,438,689,598,671,99,640,358,686,299,462,661,344,718,124,920,607,697,604,796,611,71,445,801,594,921,532,188,852,171,658,661,96,505,515,650,794,388,53,77,603,208,842,836,762,628,362,399,622,146,268,173,771,666,265,61,344,703,560,509,551,585,66,462,34,805,336,341,398,375,576,835,298,705,770,406,96,198,805,620,398,911,2,734,219,798,636,56,480,898,934,491,764,744,483,989,895,566,418,718,741,283,207,185,150,518,186,605,695,338,587,757,779,53,663,790,311,589,358,345,499,304,98,316,475,612,139,521,910,609,398,300,913,866,845,777,756,552,66,155,314,716,203,758,974,541,118,607,573,467,58,945,320,579,593,205,421,257,251,295,688,672,273,558,17,469,62,259,742,349,275,969,360,541,95,227,540,689,991,450,51,12,343,380,121,379,948,510,443,710,716,136,426,689,513,639,220,814,894,299,366,636,581,495,145,156,245,811,391,443,347,120,943,109,206,854,926,74,716,358,641,930,538,990,764,209,894,802,660,372,612,951,121,994,82,15,247,488,709,986,116,329,549,532,985,623,359,993,739,696,627,646,643,516,251,229,672,114,834,144,139,638,970,232,339,431,819,258,778,722,987,52,489,554,899,530,642,545,521,771,151,283,293,218,329,319,988,867,971,759,809,273,156,986,872,771,886,485,764,976,363,149,290,798,922,13,392,754,117,726,884,926,567,603,630,582,537,58,33,614,170,805,99,784", "760,223,109,932,100,866,483,324,695,747,300,537,183,615,932,209,315,102,370,193,102,108,643,162,551,694,529,691,458,433,461,880,985,163,347,546,651,853,146,286,269,403,345,714,251,241,432,26,598,81,584,770,37,616,787,299,34,482,641,653,805,48,797,386,104,414,987,875,881,663,288,455,49,576,328,508,88,27,155,349,858,868,621,134,928,481,523,64,909,423,261,326,725,526,769,123,213,474,364,478,609,944,294,528,684,884,520,699,61,5,865,368,413,223,697,667,520,868,567,994,688,139,339,12,18,535,146,743,642,676,613,165,291,775,810,4,348,564,884,668,679,802,275,174,45,183,666,695,767,136,639,116,294,538,602,927,72,71,992,743,599,707,551,189,769,647,204,812,594,124,20,559,904,400,604,881,704,161,448,767,161,446,701,369,393,359,751,756,969,474,638,480,387,640,283,13,889,653,770,352,768,131,787,975,958,457,895,90,593,465,710,539,467,645,314,268,817,519,322,5,0,897,313,104,322,65,378,243,688,959,947,365,398,783,164,617,630,229,680,232,475,778,388,546,242,606,990,168,951,473,939,611,312,42,658,586,384,998,774,89,365,108,656,596,897,348,419,402,593,864,172,838,934,386,390,723,580,596,146,81,23,357,896,576,81,458,199,773,114,242,148,641,536,951,666,268,822,364,224,814,968,370,124,151,997,133,669,379,138,723,865,92,559,589,248,109,215,142,533,779,648,224,131,581,248,440,57,666,698,288,773,660,806,912,433,679,920,465,793,689,1000,679,841,341,307,848,738,892,456,711,817,990,685,185,789,729,331,801,441,157,588,217,829,803,89,503,842,200,550,798,841,339,937,923,961,881,810,444,587,581,106,675,258,480,633,546,692,580,757,212,531,435,504,12,935,771,104,552,14,232,946,182,834,252,16,164,729,454,650,538,432,937,957,547,797,261,727,998,351,4,25,852,755,520,17,916,2,297,350,355,152,923,474,925,147,710,744,729,278,514,15,586,91,290,24,922,576,653,776,853,534,444,898,428,841,931,14,511,816,157,469,506,947,277,616,370,433,637,953,418,979,797,139,374,83,762,212,897,891,311,413,855,714,942,338,929,364,579,165,944,362,943,233,71,242,768,677,981,896,959,114,419,686,372,76,466,513,434,16,649,937,359,332,760,259,482,506,945,61,428,442,524,203,888,949,684,655,595,964,633,558,938,557,24,1,518,153,744,742,457,273,127,582,51,113,766,723,117,673,877,382,525,105,298,547,160,456,479,315,356,663,35,588,735,111,556,749,469,433,879,102,343,956,250,589,3,236,474,918,616,436,97,76,771,386,283,828,633,921,341,561,323,95,347,549,635,829,392,57,342,427,306,379,617,692,438,667,371,90,42,527,675,610,567,762,769,569,457,605,619,775,641,588,511,421,298,510,596,489,677,450,876,79,931,162,825,65,649,671,543,168,722,106,108,780,13,557,32,769,612,585,451,610,319,650,304,556,863,258,929,381,121,859,509,628,369,214,188,94,647,753,98,985,880,669,179,542,335,919,423,775,762,47,819,529,341,644,236,738,171,510,823,803,997,356,751,458,584,93,79,493,471,700,742,806,8,389,222,730,799,470,420,403,716,26,849,518,794,470,340,424,704,688,193,760,575,107,412,243,256,594,633,565,588,221,652,866,591,915,384,566,942,481,700,937,727,355,360,714,318,63,526,909,148,452,275,313,275,684,773,177,652,373,193,765,893,336,651,885,781,617,428,428,661,937,147,928,573,987,877,71,323,12,277,905,835,49,857,131,428,577,733,389,503,644,380,774,979,725,464,927,855,592,862,504,465,778,360,842,983,580,357,255,852,39,262,256,598,80,4,978,397,435,727,820,279,647,388,349,489,350,915,685,55,279,407,641,72,616,389,601,515,185,651,494,109,215,732,946,536,297,594,375,262,189,381,827,498,3,680,542,3,608,433,941,578,122,481,290,719,409,790,291,346,268,902,332,813,970,819,553,323,733,260,284,544,495,674,722,39,415,991,186,566,94,977,833,647,816,761,911,232,918,225,537,188,83,159,445,705,71,179,198,324,514,250,926,539,208,369,202,895,350,347,290,321,12,127,422,393,663,320,992,609,106,475,816,218,971,721,540,498,918,83,332,219,703,365,938,507,521,756,68,91,151,332,344,769,586,158,28,224,278,322,72,22,474,168,768,26,377,305,401,506,56,714,161,936,709,626,642,312,295,589,51,720,514,860,160,174,380,846,662,809,116,312,326,708,283,461", "755,374,575,170,317,289,151,532,589,944,882,192,916,888,630,371,775,762,657,871,12,551,745,224,995,670,788,446,235,342,694,443,956,903,536,877,374,195,830,42,4,58,309,179,950,270,345,613,203,527,134,835,103,67,399,864,379,349,271,790,358,768,267,513,945,88,755,858,240,956,586,197,8,975,200,112,288,949,332,337,814,673,217,480,612,628,468,291,272,653,216,770,478,413,640,5,929,581,596,848,365,564,914,671,951,335,777,294,53,251,271,907,443,220,740,57,95,49,70,520,992,64,143,156,985,747,569,434,533,68,298,737,221,785,212,256,405,275,884,232,574,585,877,528,692,341,430,525,511,196,759,534,137,108,166,234,367,985,984,486,682,285,637,441,46,564,370,410,179,729,766,785,401,301,588,422,316,28,93,353,601,338,799,559,549,908,258,973,379,503,749,351,959,40,276,352,90,178,720,891,154,174,396,821,987,500,140,613,867,272,544,620,846,13,513,850,299,246,699,491,897,0,249,817,561,545,138,248,37,681,836,496,198,333,99,652,252,282,864,505,430,266,417,576,528,304,674,44,734,507,313,146,285,900,371,605,530,303,451,609,246,847,369,966,924,137,320,121,35,390,330,354,234,879,426,849,248,354,811,54,946,138,559,315,894,759,698,267,237,151,696,928,802,278,741,65,890,764,243,563,393,74,905,509,760,556,965,950,196,354,939,727,118,616,652,840,881,380,819,110,658,996,851,229,992,755,360,946,866,140,406,392,238,510,959,484,897,358,953,892,140,715,813,699,550,103,608,846,440,686,471,846,296,720,877,468,666,204,807,160,254,62,783,148,800,256,886,152,457,382,263,541,943,935,685,31,999,54,856,228,407,89,297,158,149,143,227,419,80,933,610,259,448,322,643,73,720,793,359,238,239,871,795,932,170,882,469,208,734,682,82,593,124,421,749,337,650,214,513,116,252,275,285,983,570,954,606,997,396,959,50,394,893,950,540,403,468,75,848,531,289,546,919,405,580,677,424,560,613,10,173,113,685,675,358,192,301,712,245,444,854,778,396,306,594,866,591,851,824,844,582,550,149,898,470,470,800,141,363,636,402,291,871,814,593,599,13,992,727,437,35,59,876,766,132,925,655,192,146,621,230,218,204,769,36,255,149,26,262,319,351,690,166,569,938,297,477,294,78,791,153,985,734,200,405,575,639,563,323,624,807,897,793,894,499,639,650,729,890,926,673,720,551,128,399,867,227,548,190,796,331,767,752,738,743,723,706,43,491,312,484,207,556,184,398,869,207,873,606,756,125,182,861,637,615,465,539,509,573,96,120,580,618,937,694,238,34,424,566,473,653,363,695,371,228,688,941,129,617,981,818,505,768,791,615,856,658,989,256,518,983,783,41,244,943,940,962,798,888,269,434,52,616,26,282,461,541,295,43,466,315,234,99,858,294,951,507,207,710,248,563,700,420,128,135,284,948,140,873,212,6,912,980,52,176,296,207,392,883,91,833,377,368,420,518,884,464,806,580,504,712,808,70,826,988,791,626,319,649,530,501,148,515,367,521,445,697,480,455,751,584,422,128,51,677,380,348,931,630,873,91,277,207,25,357,879,347,149,61,420,273,22,31,960,685,13,363,255,338,780,793,114,199,309,537,203,467,437,980,9,150,850,408,613,276,945,528,342,959,75,39,274,631,559,999,959,980,537,38,949,612,597,765,307,634,779,373,286,840,692,608,866,510,368,446,894,640,575,12,894,961,2,193,554,577,731,49,205,426,396,213,262,436,717,3,692,592,63,8,529,46,530,30,94,810,857,89,791,816,825,796,104,234,697,601,742,190,858,548,639,217,250,275,305,176,650,866,990,921,506,13,423,35,123,447,721,222,704,15,650,179,450,281,395,139,508,66,845,239,734,576,145,887,41,3,665,925,531,282,558,22,659,204,540,483,352,698,212,800,987,429,147,37,927,613,944,569,589,85,778,176,485,779,780,355,218,166,651,711,14,502,72,865,835,266,153,390,567,805,286,436,415,456,953,716,826,906,463,89,430,317,455,992,97,913,187,407,819,581,560,29,859,243,459,444,924,896,747,933,578,694,129,245,15,795,701,630,860,839,620,268,691,288,345,838,936,662,701,450,402,736,840,914,369,791,121,681,163,13,956,434,868,10,413,738,899,198,229,460,353,97,241,739,736,724,481,17,956,736,1,483,741,234,468,431,289,506,515,710,484,971,369,114,274,258,590,177,784,618,518,608,614,603,379,605,914,277,983,385,196", "101,929,320,241,239,828,569,228,81,880,402,881,943,120,189,361,99,762,138,940,683,411,668,805,604,818,563,764,414,269,562,334,366,775,61,742,258,440,766,645,172,632,125,339,811,277,677,23,826,250,240,29,969,482,566,136,29,565,816,541,243,190,34,9,329,253,704,251,355,749,713,200,587,434,626,561,682,257,138,198,465,511,310,726,875,672,568,283,843,644,166,413,679,382,126,280,671,451,245,44,287,539,565,992,416,427,990,966,94,838,349,165,13,852,779,460,24,262,407,375,604,844,464,518,627,415,936,930,223,413,386,607,963,754,396,479,123,978,881,429,679,512,379,354,464,99,389,949,150,17,663,726,268,451,541,229,699,703,792,841,686,798,413,896,621,99,111,533,805,557,835,675,264,354,980,912,704,639,15,883,222,379,806,213,911,485,572,486,791,703,348,904,617,760,751,458,858,292,636,13,629,179,164,253,740,812,285,634,596,232,951,353,649,422,586,74,525,845,699,538,313,249,0,232,372,60,78,417,703,400,789,454,930,798,727,451,474,169,984,417,772,33,806,72,860,154,821,473,644,316,242,767,963,858,734,85,960,311,288,327,967,650,862,332,138,121,234,160,758,851,909,10,793,377,174,433,654,407,51,704,573,941,12,744,853,404,831,654,392,650,986,946,156,505,537,86,901,992,541,204,84,402,273,973,850,8,136,506,912,154,574,639,430,794,395,26,13,41,265,103,880,592,232,97,62,635,237,149,833,784,197,695,11,802,225,399,486,828,716,862,628,93,320,515,25,442,724,268,190,631,499,858,290,690,252,160,705,787,360,539,324,422,988,968,489,133,848,121,789,362,974,789,512,92,423,853,205,243,584,971,315,39,458,292,176,398,780,321,922,804,225,197,202,390,465,73,188,508,232,274,911,52,332,688,112,996,862,910,610,404,702,227,701,779,484,75,818,584,629,273,478,630,607,571,318,713,928,355,946,922,53,881,760,287,126,612,504,792,683,419,647,998,533,102,969,476,758,611,684,542,958,54,871,877,363,985,434,449,820,272,434,922,799,231,519,774,73,139,677,70,312,254,878,390,700,854,52,73,830,582,786,55,184,500,459,365,611,181,268,224,809,999,31,989,477,865,348,226,370,902,237,412,550,993,60,595,681,225,121,984,588,624,706,112,413,839,932,415,243,522,40,216,990,259,54,809,292,327,142,555,471,196,534,260,563,516,93,511,997,877,81,592,622,405,265,682,366,495,270,941,881,934,497,745,377,513,636,961,198,907,887,212,594,138,259,624,786,22,706,377,456,388,152,257,542,801,483,997,370,679,250,663,554,5,993,998,510,108,355,909,414,447,191,231,51,294,578,983,572,31,106,287,869,476,964,591,573,297,270,511,898,159,962,366,650,419,969,846,120,987,955,699,618,806,725,376,293,344,126,973,608,540,141,933,158,542,701,231,882,127,243,106,574,811,538,20,385,102,143,536,403,508,161,187,768,188,337,484,362,425,512,161,129,315,46,682,664,859,7,438,990,263,321,715,617,821,889,233,216,386,436,564,870,690,454,63,109,623,655,611,43,193,189,650,779,340,37,892,163,926,562,41,195,101,810,841,541,932,972,937,823,128,474,881,43,55,551,380,476,829,849,732,436,974,592,752,241,449,377,607,445,791,379,810,216,300,172,560,252,231,384,667,325,911,964,573,122,214,320,257,361,432,791,499,347,424,671,860,354,579,179,772,102,790,182,896,726,875,347,795,94,41,517,139,606,799,653,818,510,675,988,914,442,891,572,303,484,882,32,94,799,468,30,172,662,332,227,656,975,578,740,439,101,930,429,410,50,617,404,924,770,634,686,957,460,267,835,874,491,538,135,159,639,927,850,564,10,250,458,81,962,191,220,211,477,169,672,54,894,522,259,206,320,963,971,70,277,455,550,543,239,15,351,174,288,73,689,596,613,911,312,535,876,229,635,348,271,963,934,227,758,269,827,333,704,337,525,517,332,907,785,653,643,500,705,566,213,705,946,384,668,540,394,345,673,851,650,328,50,938,414,960,122,278,918,839,463,658,464,819,69,638,812,743,804,995,233,996,919,336,874,809,765,263,300,910,89,236,160,584,658,519,603,694,188,558,606,838,659,955,234,974,606,205,98,177,631,175,565,590,589,276,889,458,49,432,46,101,956,659,630,462,194,200,620,106,794,101,652,38,991,991,512,600,315,242,393,316,863,643,123,49,938,77,154,288,894,529,761,609,424,332,638,667,108,685,197,6,917,430", "37,828,879,733,471,859,529,819,54,324,442,421,257,815,160,625,423,16,795,468,878,678,113,381,640,30,913,388,405,592,430,37,830,804,685,305,903,692,352,706,641,873,643,818,275,755,493,1000,753,529,84,73,86,468,291,904,127,222,689,869,22,332,964,696,971,796,732,128,196,284,676,180,631,550,558,634,817,235,336,658,564,640,33,188,334,479,41,18,44,935,295,770,43,378,205,354,560,235,457,297,889,175,822,91,662,513,477,4,604,800,908,692,570,66,464,936,290,475,289,667,590,537,619,753,934,467,849,355,951,856,425,778,334,593,531,258,876,946,978,663,482,787,123,810,860,133,446,677,337,521,539,895,277,991,588,383,798,45,553,975,64,761,382,692,701,325,126,751,50,186,536,783,220,196,659,614,51,371,711,698,607,560,741,771,224,731,853,817,180,763,952,648,89,188,492,324,134,719,773,406,496,160,169,602,583,600,186,242,948,203,101,267,720,357,962,202,474,963,192,443,104,817,232,0,420,462,801,385,335,176,146,668,367,652,931,650,645,740,430,702,308,186,453,492,326,721,20,264,473,663,882,778,416,357,244,800,936,98,221,677,145,994,598,599,4,107,413,887,127,711,80,599,898,181,704,77,549,667,867,734,639,779,388,575,878,431,181,443,949,939,236,33,878,13,176,627,259,188,722,216,951,263,704,258,911,41,347,814,272,255,678,770,851,396,774,838,667,631,994,906,628,819,354,432,414,334,795,169,229,972,985,814,305,406,586,117,576,598,888,476,118,208,477,375,306,672,18,490,748,41,2,26,934,407,409,869,135,384,396,235,986,326,920,492,80,376,328,543,767,399,546,750,296,912,639,157,59,166,48,549,104,303,960,367,583,373,888,560,505,382,177,109,956,794,354,465,73,339,941,82,783,353,300,314,853,987,677,958,653,931,439,542,125,723,91,964,309,896,875,712,767,747,729,538,944,688,197,519,580,159,482,210,109,954,869,657,487,319,482,785,852,63,853,35,679,589,505,126,521,222,264,767,864,265,593,617,714,298,762,87,309,773,334,574,877,178,272,69,678,215,996,307,469,26,175,224,656,869,527,338,509,878,653,898,369,75,498,887,644,97,161,925,585,567,224,252,417,482,309,303,696,636,898,454,880,76,979,330,403,201,298,807,479,114,127,74,907,880,634,196,277,477,177,670,218,840,994,121,560,884,840,240,96,383,859,65,233,249,536,694,366,103,850,315,110,770,782,269,338,860,246,496,806,394,142,331,887,373,412,36,776,415,420,912,798,129,316,209,399,261,276,820,130,607,194,169,22,120,766,964,828,517,725,919,752,412,456,755,657,825,857,253,990,235,322,771,816,876,427,84,239,481,527,491,497,829,449,524,72,819,750,273,4,712,303,969,322,88,627,677,67,599,303,346,899,190,372,811,884,304,640,492,347,395,15,134,263,577,718,929,830,130,666,139,882,126,945,550,797,894,902,737,165,349,432,990,836,24,394,595,191,390,461,642,796,430,721,234,524,77,817,163,118,636,265,723,220,33,820,61,190,217,174,231,727,662,29,352,701,466,892,153,589,400,419,294,71,25,872,660,731,792,695,77,421,205,309,783,6,847,968,160,414,80,202,719,577,339,816,437,56,977,994,769,863,848,278,970,434,231,368,790,821,448,894,461,907,579,383,471,411,774,677,659,271,932,509,234,52,777,649,692,501,502,902,530,807,573,18,628,994,865,962,762,763,291,687,756,17,851,515,151,832,736,273,509,818,185,397,749,159,804,919,62,342,221,834,539,591,142,599,321,729,673,27,21,505,544,129,99,885,822,817,269,624,216,104,568,643,123,79,237,965,370,232,222,650,700,847,876,271,122,603,670,383,434,619,485,969,180,755,122,924,982,241,724,892,168,867,289,365,333,459,235,618,515,296,711,242,294,249,162,689,571,130,236,148,556,977,858,196,772,863,367,555,120,113,829,622,479,627,114,32,864,347,896,550,373,559,301,61,665,382,973,405,582,578,8,502,759,331,457,718,879,638,508,619,67,452,308,367,35,205,232,99,610,322,338,723,40,362,302,712,217,553,475,1000,450,373,372,385,460,410,14,810,881,828,555,587,249,725,205,305,759,114,44,522,989,783,322,691,720,427,93,309,43,118,145,142,180,131,413,326,879,853,559,419,35,958,259,474,889,728,997,308,439,488,93,814,189,438,585,631,605,564,659,261,53,392,984,350,86,601,489,193,198,334,455,42,888,7,359,284,832,80,404,813,52,101,627", "769,450,331,500,217,732,292,588,718,820,805,920,953,324,393,559,812,11,520,404,655,37,29,34,771,184,614,396,501,612,632,172,679,697,558,86,620,68,131,207,497,865,413,714,476,743,111,725,878,739,825,557,251,251,216,358,14,366,352,197,888,131,589,923,872,501,392,789,661,824,938,865,796,349,626,182,608,8,57,953,435,587,788,778,513,971,978,632,539,939,257,308,866,971,82,789,882,472,302,138,807,116,877,290,993,45,335,837,89,622,77,764,435,391,407,899,59,237,55,473,5,729,699,958,971,186,139,584,795,814,369,686,981,612,824,940,237,657,67,50,968,500,420,813,48,207,488,257,92,497,85,371,903,267,210,487,538,937,200,999,825,320,174,49,445,332,129,473,540,224,395,964,809,146,375,60,345,53,456,652,823,402,3,229,7,917,706,400,825,671,510,15,339,880,624,722,190,110,318,89,538,340,712,583,199,434,375,925,589,462,432,137,85,842,837,374,593,392,907,848,322,561,372,420,0,94,513,348,251,634,236,367,384,337,467,259,499,140,813,40,751,887,781,191,17,703,386,476,586,690,36,570,603,917,223,749,467,91,310,864,694,985,424,516,952,991,571,241,349,520,731,280,992,313,907,959,26,918,246,471,683,932,136,590,518,251,426,559,454,699,364,646,8,675,495,730,59,390,147,469,436,32,349,361,277,475,649,456,599,53,805,33,937,314,741,651,851,300,955,617,404,24,825,825,734,500,615,1,659,114,454,264,619,9,708,872,125,265,26,465,833,6,114,569,661,316,405,595,184,798,26,229,910,461,525,187,686,777,512,554,883,874,969,345,511,383,50,556,6,670,934,543,213,767,626,201,483,838,386,465,788,109,539,664,753,493,278,613,894,80,104,908,349,191,183,829,7,330,691,121,574,691,176,115,195,601,204,611,84,111,400,465,202,740,393,81,895,8,693,16,588,227,778,707,924,894,282,4,828,139,151,308,193,948,993,418,953,245,42,798,708,572,193,868,610,235,991,761,846,86,373,692,524,361,41,49,757,970,654,291,740,687,167,434,925,130,830,944,425,636,755,154,186,754,256,610,280,958,865,908,301,795,922,131,701,527,493,100,325,184,578,705,839,389,34,438,888,628,529,25,843,806,920,148,148,33,817,837,236,199,346,967,244,160,924,114,638,696,564,122,584,336,614,186,75,278,859,4,682,580,529,1000,335,125,782,225,871,610,319,359,361,976,255,715,229,529,961,11,495,409,164,830,320,781,168,635,655,781,109,550,481,351,370,971,383,579,271,278,549,930,438,477,99,314,69,376,715,295,861,665,251,811,493,532,260,63,508,585,120,982,696,653,769,274,689,165,99,289,382,846,339,787,356,931,487,453,119,936,65,79,418,362,321,660,598,773,143,665,743,979,779,2,759,852,747,602,898,451,341,868,801,610,17,108,815,640,158,478,684,604,343,541,622,754,267,338,191,835,257,445,714,527,348,214,792,141,636,768,570,472,361,652,290,483,809,308,254,235,448,623,121,655,30,842,790,690,847,118,259,452,928,166,732,555,831,518,364,18,138,317,997,616,61,456,247,125,946,406,252,415,368,328,407,289,746,294,323,713,88,734,884,186,306,204,829,643,228,181,289,125,265,755,867,233,697,381,580,489,621,987,109,581,516,406,96,149,497,314,433,776,165,986,549,291,386,676,307,533,390,337,864,175,88,354,533,865,653,155,510,398,851,337,336,911,650,420,174,715,55,452,454,128,134,520,394,86,26,698,765,585,303,687,969,786,109,759,138,97,760,43,100,80,289,997,111,179,499,229,273,841,65,549,374,567,247,859,800,390,16,707,112,908,400,698,312,170,973,592,396,879,149,929,386,114,656,771,551,957,811,744,478,404,220,669,734,391,836,107,565,995,258,427,594,818,215,903,891,361,278,469,44,307,106,249,635,583,879,883,995,824,304,908,804,440,960,674,552,345,965,859,842,777,452,798,381,999,344,503,274,278,130,448,109,514,589,904,738,387,322,761,523,810,503,943,623,836,245,908,777,210,980,528,615,284,775,837,466,722,171,925,354,834,741,193,432,100,287,265,954,564,240,331,193,667,458,592,605,232,468,837,506,420,819,602,930,754,115,295,455,825,188,477,158,808,428,591,153,117,61,377,952,190,151,886,985,815,708,207,65,482,673,830,126,521,898,227,322,223,324,835,512,997,669,865,288,19,358,763,247,305,807,64,948,640,424,174,740,666,607,502,129,617,883,682,987,755,845,532,20,883", "460,465,990,357,966,853,298,784,408,773,102,487,108,718,933,62,864,639,629,567,324,51,129,873,232,136,94,712,528,84,848,197,913,603,930,445,565,268,394,58,365,112,320,334,945,73,129,531,940,648,531,600,247,873,792,982,207,126,964,544,986,562,289,549,467,437,271,637,554,850,30,524,725,197,489,371,437,127,871,270,395,92,107,379,313,388,440,257,944,889,883,751,664,392,869,553,689,34,82,747,132,243,226,23,334,679,292,437,482,895,21,680,527,673,899,752,416,832,379,601,859,538,604,489,339,940,252,553,464,522,67,730,612,21,532,299,731,708,116,511,838,604,958,575,801,460,316,21,656,544,71,617,123,232,710,919,351,298,238,119,187,959,175,751,423,501,424,589,372,234,55,446,626,12,143,341,90,551,453,653,132,301,224,947,830,767,693,349,684,492,597,985,269,466,786,937,924,703,826,721,207,966,150,112,121,812,83,41,167,43,401,628,802,336,65,837,570,360,670,849,65,545,60,462,94,0,641,918,470,870,352,375,458,867,675,303,270,407,350,578,746,530,678,198,588,349,334,122,532,325,340,724,729,705,994,157,211,45,980,466,26,992,538,120,710,319,585,108,919,539,158,23,948,904,627,165,306,102,774,493,706,679,871,73,769,563,586,934,188,616,508,924,675,424,761,195,957,329,619,965,208,425,894,50,2,438,508,882,137,404,35,264,473,126,37,151,212,758,108,575,706,563,727,735,360,439,161,291,969,619,104,123,849,144,816,283,24,241,901,848,612,466,975,883,784,164,530,590,282,253,508,815,875,868,7,18,626,18,716,739,910,352,314,9,409,292,219,428,230,671,287,3,818,840,246,162,270,720,594,132,656,231,139,854,975,400,501,210,30,279,259,982,814,189,349,191,972,268,397,528,955,420,248,214,786,720,788,685,33,276,358,229,195,100,151,982,281,95,111,591,841,747,855,133,481,258,893,627,671,437,639,412,214,264,477,377,490,963,343,834,97,391,63,917,225,936,248,617,893,361,784,509,884,733,532,277,110,304,184,704,207,453,381,230,324,888,20,670,110,827,636,316,529,187,29,490,215,711,341,9,591,177,550,35,818,444,988,898,141,305,503,218,481,259,923,772,244,131,240,362,583,672,469,788,32,138,995,881,499,732,601,529,442,889,863,748,760,89,530,38,274,134,275,505,123,767,393,934,29,947,821,441,464,141,272,237,691,359,115,42,186,907,139,640,374,475,639,840,548,45,984,59,743,973,820,246,674,919,137,57,824,30,272,857,303,484,316,205,193,296,505,205,42,33,241,208,706,231,772,989,910,524,416,674,659,898,447,674,205,474,219,18,455,647,31,985,198,7,61,406,566,543,281,791,529,634,850,751,625,730,544,77,124,44,185,272,758,761,165,463,893,266,636,236,296,531,772,377,238,705,204,247,975,978,285,397,582,106,748,627,785,25,703,408,159,83,761,24,170,232,535,959,602,29,393,723,689,965,434,645,468,444,525,452,320,389,145,18,672,641,820,808,849,135,586,630,637,717,866,216,603,557,167,701,313,64,753,569,142,898,816,191,485,861,834,8,232,620,479,825,797,599,991,89,887,949,198,147,683,947,191,789,57,802,220,245,693,615,567,77,138,405,352,90,434,743,496,329,324,609,384,328,441,311,336,703,889,210,540,740,915,2,801,365,543,743,833,950,711,642,412,798,140,838,766,185,369,750,312,664,847,199,941,272,793,896,787,844,43,871,375,992,32,543,100,309,441,85,59,287,867,51,871,946,966,590,97,565,491,10,677,12,498,727,273,699,785,53,331,217,829,592,160,430,561,765,97,847,554,263,874,846,41,308,785,921,733,154,581,282,635,365,549,778,581,32,627,574,237,933,366,207,528,614,682,390,248,468,84,263,222,302,124,261,754,536,96,699,551,744,824,126,218,704,908,337,552,969,86,948,122,739,454,370,670,223,525,289,502,209,388,804,103,104,523,968,822,54,365,319,156,302,203,72,215,653,18,851,783,838,860,524,568,844,109,981,791,930,464,991,926,846,549,670,39,24,983,672,224,688,934,937,586,953,865,431,587,679,869,134,424,787,369,134,388,4,37,922,219,252,988,977,821,338,349,871,544,984,204,429,103,120,259,160,900,907,527,777,778,208,890,94,692,43,27,958,160,618,93,786,124,290,501,980,526,583,860,131,801,668,511,562,52,151,435,32,944,973,384,423,22,825,728,887,957,246,219,278,195,133,79,48,426,128,71,958,36,867,954,260", "252,411,887,200,557,816,569,99,135,395,764,354,750,333,371,193,837,957,133,675,242,808,382,417,766,955,80,211,377,80,334,561,478,107,793,870,614,496,547,506,168,499,278,678,447,551,89,400,763,126,411,240,492,266,673,867,241,166,229,58,405,450,842,992,374,67,513,171,267,180,357,498,472,597,876,280,354,193,386,29,760,868,663,804,649,273,685,859,93,228,402,423,404,16,16,144,94,691,460,64,114,419,230,34,74,937,896,82,989,74,203,952,727,810,443,682,829,812,16,329,493,852,359,7,672,799,912,277,817,745,475,972,994,852,354,170,60,415,210,293,807,638,787,641,557,444,804,387,446,864,875,961,906,590,597,637,184,935,346,174,339,274,146,834,253,143,187,908,622,532,101,456,801,697,38,899,859,187,20,511,484,224,629,837,704,219,609,621,429,980,123,530,10,606,400,286,824,981,483,187,504,636,373,981,5,525,646,604,40,797,24,925,878,644,55,830,383,750,733,402,378,138,78,801,513,641,0,624,250,997,676,415,49,673,123,168,613,760,17,579,965,139,670,312,777,985,380,105,898,268,695,627,520,794,724,209,523,92,111,415,140,434,990,152,167,593,990,351,790,956,650,703,712,31,528,640,424,273,946,871,22,402,611,299,452,990,168,489,156,160,970,952,83,431,578,65,137,846,121,357,419,663,277,80,209,57,927,827,665,447,152,760,341,926,460,536,712,761,873,998,757,844,232,716,744,352,60,81,944,712,91,313,44,404,585,365,51,647,363,157,295,761,690,939,959,595,8,70,4,27,147,215,879,797,210,823,746,811,182,171,572,670,940,382,297,881,56,50,478,96,559,224,99,443,193,161,406,910,631,415,520,41,459,56,855,658,130,998,373,882,52,768,292,64,15,762,130,61,767,451,256,961,472,57,853,501,659,829,215,498,109,713,705,73,489,537,824,996,523,360,422,432,734,458,149,909,677,983,380,430,858,271,122,258,907,555,606,218,300,218,267,270,917,878,834,734,550,792,125,158,253,645,76,532,210,479,206,356,954,730,583,383,951,743,803,600,517,833,475,949,4,990,718,861,922,570,347,881,178,439,878,83,518,421,143,784,184,349,149,423,957,990,971,715,994,346,314,326,31,20,420,475,767,224,113,892,286,173,134,277,413,920,197,337,268,259,102,287,815,529,658,509,513,237,169,114,677,695,331,183,991,606,226,787,876,608,901,634,598,162,744,946,220,772,367,44,253,666,761,858,915,770,665,683,240,557,727,491,875,512,147,639,228,676,294,774,454,675,595,709,722,570,714,220,206,875,409,133,468,381,132,507,406,966,38,332,233,939,601,328,947,164,240,80,20,383,161,407,407,3,70,647,194,9,278,923,965,584,715,847,948,802,850,826,452,794,88,144,91,461,808,518,291,25,170,348,476,177,516,298,622,400,530,806,917,353,183,546,325,342,644,220,753,338,474,136,798,860,509,251,931,551,178,417,811,53,701,978,289,71,695,992,476,889,445,156,255,388,578,290,497,438,175,858,343,442,700,757,782,306,681,444,710,20,14,369,466,273,335,393,722,578,88,892,608,198,756,545,149,694,911,767,951,276,387,861,780,536,83,17,893,118,280,206,726,470,96,716,203,347,676,86,785,745,231,181,540,536,762,468,784,972,232,991,501,999,857,399,757,31,132,198,90,694,322,778,992,91,547,839,10,165,956,762,808,716,878,73,333,263,9,523,870,158,738,255,101,552,39,506,186,903,779,825,537,11,333,640,651,312,297,333,459,624,293,452,321,143,21,612,609,701,639,368,998,425,400,544,962,150,486,344,546,283,922,225,811,245,692,554,190,191,666,907,538,805,939,378,26,95,670,40,771,541,542,899,502,580,594,731,190,819,997,78,189,270,879,987,92,419,825,267,577,755,669,709,319,800,52,74,794,131,326,99,157,514,969,697,55,554,356,622,717,471,37,21,882,174,603,198,890,352,598,980,462,112,300,19,915,782,809,435,260,738,653,953,496,486,692,109,950,252,87,19,372,46,878,851,38,149,959,8,438,705,286,21,604,144,175,183,666,69,913,319,587,867,373,77,200,389,415,678,175,680,331,984,828,671,516,242,199,702,625,411,188,159,794,332,972,961,274,120,697,594,910,144,260,91,323,413,858,851,811,589,653,289,794,903,80,879,16,737,553,225,644,382,860,519,515,486,226,392,430,264,660,841,156,75,581,583,424,555,679,659,128,704,156,987,186,3,607,262,487,493,718,108,588,198,126,956", "869,75,921,713,263,481,270,727,697,676,89,240,326,44,856,825,582,36,864,711,660,828,424,500,649,632,148,23,257,683,163,663,410,962,500,917,43,947,387,606,648,835,208,294,702,300,920,954,989,785,204,944,815,671,503,437,775,515,172,305,332,484,359,827,37,662,777,521,621,73,832,666,30,817,728,901,800,398,141,316,173,858,805,391,510,238,804,595,832,991,301,196,219,79,987,42,445,191,431,268,178,756,511,826,840,859,765,551,20,335,324,273,757,137,408,502,119,266,81,94,328,14,878,819,768,234,645,95,345,835,739,719,292,22,818,889,552,982,791,19,449,404,85,1000,857,551,822,322,469,572,490,440,278,608,920,160,445,221,391,306,710,406,876,750,248,546,285,719,797,427,776,283,414,178,315,518,369,658,253,150,656,831,65,303,437,874,649,123,423,399,188,759,327,138,829,913,894,722,393,863,494,592,106,823,126,773,469,462,906,320,108,487,665,807,101,796,136,773,520,411,243,248,417,385,348,918,624,0,731,129,493,586,38,903,682,357,654,277,575,659,932,231,267,26,877,83,241,137,305,999,156,407,316,53,116,898,166,608,664,592,900,95,875,847,174,983,833,485,308,947,500,748,625,135,498,832,115,30,143,227,856,232,648,817,849,796,229,247,52,602,750,380,677,467,650,708,731,728,306,230,863,237,984,516,820,281,480,608,407,453,165,601,295,748,479,812,825,441,874,129,356,990,21,99,956,404,648,579,352,432,722,464,66,316,504,823,2,958,794,681,586,607,325,35,116,21,336,361,539,748,893,887,688,863,690,296,453,771,433,71,855,73,86,680,12,551,283,590,678,222,492,940,476,265,496,772,530,364,505,335,347,671,624,175,773,818,434,354,284,939,629,911,313,376,824,414,702,798,801,197,315,481,786,148,842,863,917,805,859,124,335,811,436,519,801,98,108,229,695,153,842,701,492,891,788,48,846,300,607,375,25,821,757,195,229,889,710,882,866,263,570,75,783,98,640,491,598,199,585,301,152,883,521,900,721,340,989,693,962,2,640,384,349,956,913,773,937,983,979,255,700,291,831,738,869,900,424,302,379,847,317,296,729,369,854,825,242,810,615,589,349,313,63,198,509,34,310,890,344,813,19,13,27,583,921,392,218,533,606,379,28,66,510,117,227,688,579,179,700,761,105,147,668,22,162,411,613,678,954,475,878,375,886,229,413,255,85,535,430,798,421,984,65,339,620,597,695,441,672,525,785,390,919,732,557,515,554,731,545,189,696,273,694,151,440,263,208,490,609,971,204,895,699,709,56,645,813,63,844,493,965,908,642,89,651,846,241,219,59,501,428,946,384,354,623,839,485,518,160,457,861,592,11,499,907,298,24,707,699,780,888,71,166,182,706,503,690,690,770,830,214,303,970,720,506,918,832,123,791,321,645,4,19,404,841,318,351,361,707,124,528,230,319,854,442,629,766,364,573,921,696,488,38,833,436,503,504,130,730,181,379,891,995,906,728,993,398,275,12,484,934,465,683,891,737,691,526,997,720,420,417,828,292,48,218,933,126,355,748,642,322,720,316,209,701,650,887,119,730,92,577,257,682,633,309,545,273,214,75,132,57,351,829,118,837,307,998,421,417,523,772,898,494,371,768,758,739,831,367,722,852,157,14,608,964,741,576,132,959,537,21,544,388,890,877,49,375,788,406,502,251,918,231,693,248,551,398,448,948,655,153,739,930,318,507,142,18,376,233,711,51,395,2,477,8,320,312,368,938,50,12,987,438,241,308,487,11,400,583,546,53,515,810,100,167,932,873,861,338,374,506,253,179,451,356,722,181,637,110,192,696,162,104,430,111,993,265,987,119,6,192,100,706,238,214,436,879,400,754,526,104,758,24,236,117,104,119,787,525,150,676,332,885,710,613,938,574,894,326,219,722,996,426,169,889,253,931,490,746,10,857,660,630,652,842,395,445,236,364,156,536,715,846,873,24,770,797,414,595,985,786,809,262,426,861,583,97,207,915,854,992,483,990,788,285,196,3,432,194,975,501,721,341,490,607,593,395,290,978,400,328,493,860,100,400,214,679,67,429,63,817,19,31,558,712,601,347,261,83,865,213,346,827,230,686,804,252,601,297,53,727,567,570,48,868,998,300,98,41,836,340,838,853,484,81,353,854,330,784,746,382,101,931,434,963,509,589,250,548,496,397,527,834,8,711,577,519,13,767,434,112,368,960,504,605,740,834,392,495,674,124,746,239,724,524,144,138,506,402,882", "700,199,368,503,433,776,942,574,926,435,91,58,454,996,909,813,44,326,237,464,72,19,858,482,596,996,629,187,952,745,262,26,878,218,269,75,408,373,885,177,778,491,20,320,53,755,917,365,427,787,406,84,802,650,385,681,982,403,579,79,989,834,60,670,760,968,275,763,570,962,760,425,833,738,132,103,812,154,963,449,307,5,983,102,742,84,862,600,740,835,204,881,862,194,318,657,42,260,934,450,623,706,876,701,902,178,122,724,378,456,599,276,507,920,79,100,49,500,89,674,467,531,370,31,104,667,449,738,25,394,794,258,630,562,191,287,832,131,902,762,4,163,593,786,671,722,133,446,266,235,969,149,193,152,5,384,43,706,554,897,919,353,602,611,914,429,102,188,296,901,98,960,195,154,363,992,399,666,361,137,378,196,220,229,609,571,853,85,132,668,879,231,468,835,571,932,528,482,731,705,271,28,636,956,736,450,170,461,51,436,202,627,20,985,374,511,727,194,891,348,688,37,703,335,251,470,250,731,0,210,33,138,699,281,980,750,801,782,87,452,700,407,619,947,307,662,90,46,694,644,474,149,963,336,195,639,80,737,432,364,267,664,513,406,825,202,151,881,593,530,712,485,328,58,245,952,614,692,467,650,840,666,986,592,780,186,417,287,979,786,884,776,755,308,206,961,947,102,519,796,741,739,743,653,791,32,343,128,215,502,950,960,325,61,285,838,28,193,508,583,977,697,486,838,854,114,25,228,176,96,743,822,597,389,49,853,940,77,26,96,580,594,282,529,222,306,478,260,721,313,884,230,415,316,580,646,781,605,196,132,268,180,668,521,111,174,501,994,118,552,906,932,474,457,852,7,555,193,984,364,231,856,577,218,280,805,882,299,730,380,975,340,915,71,395,489,889,818,628,342,715,402,759,646,539,640,891,287,41,372,361,968,94,226,816,217,937,739,643,660,401,714,162,290,660,911,404,512,456,585,285,640,35,452,994,11,960,613,396,467,86,55,44,295,43,372,633,894,50,167,565,27,376,387,149,285,522,285,490,792,303,431,569,78,846,731,557,980,203,917,379,568,385,388,330,989,831,918,847,901,83,191,109,839,699,796,493,937,100,767,604,577,866,628,813,555,963,422,335,152,378,458,17,959,756,760,947,774,429,720,457,642,779,993,877,440,528,568,771,342,844,588,818,151,455,961,833,538,364,108,776,689,25,244,639,842,90,676,321,964,740,496,766,931,332,858,151,632,583,885,784,871,223,968,616,632,417,902,929,41,551,188,569,125,286,605,563,101,291,707,19,83,101,910,165,224,302,597,495,993,388,266,780,223,543,4,223,233,316,255,885,118,120,632,549,797,757,184,268,971,232,67,773,951,72,979,765,94,796,773,979,582,960,680,254,349,497,166,574,797,393,697,175,72,949,538,332,675,494,976,927,508,130,867,250,481,869,371,889,386,700,758,216,307,234,230,827,970,485,695,808,16,665,761,890,36,265,985,308,392,54,683,9,702,592,615,936,850,835,22,213,464,392,400,949,722,866,329,760,368,559,860,63,884,902,153,288,713,685,884,724,434,157,565,497,909,445,361,802,634,241,653,921,115,219,876,481,706,222,711,497,550,265,782,992,725,623,594,252,252,65,993,251,125,813,71,973,360,226,772,685,124,840,259,516,397,892,978,738,407,209,124,993,135,126,651,810,112,729,855,385,870,766,695,100,443,547,920,259,739,394,558,149,940,667,925,470,199,756,217,834,591,830,475,499,130,440,222,597,408,741,501,366,342,668,862,598,64,108,409,886,151,715,363,330,601,747,394,132,158,876,163,883,606,298,597,171,658,289,701,555,344,433,207,469,294,156,639,108,924,372,490,13,427,394,376,300,411,556,535,608,941,973,756,835,377,869,460,170,730,260,987,336,346,293,945,62,290,961,285,238,526,540,860,686,198,492,969,452,763,422,837,727,306,86,265,378,703,709,443,125,491,91,710,406,831,183,546,91,52,211,377,362,727,685,603,988,815,167,511,426,490,969,92,506,67,480,995,946,431,713,722,700,285,559,637,182,670,874,109,581,741,210,511,809,957,315,998,107,804,42,539,947,87,582,370,509,908,789,947,743,562,772,426,507,32,974,862,768,838,751,902,797,64,6,528,954,716,299,494,841,897,192,868,164,339,711,311,317,974,112,676,330,42,629,236,33,404,885,415,372,794,295,517,405,967,421,876,147,865,88,867,696,369,12,681,261,269,94,917,313,94,359,553,58,828,978,817,141,747", "182,145,294,588,940,586,671,839,581,637,847,859,652,809,844,83,641,603,731,42,119,424,327,831,519,141,93,582,887,654,156,196,313,140,715,430,616,907,885,501,637,314,165,638,927,858,515,585,656,483,819,570,825,348,205,764,796,795,894,289,912,318,980,756,197,482,501,165,924,152,4,572,700,778,539,140,209,254,131,458,762,613,4,351,368,972,682,678,933,688,17,810,233,246,787,121,429,362,528,161,246,17,716,804,507,466,569,569,715,952,899,108,109,590,506,21,734,465,459,802,596,489,406,836,388,947,856,828,952,416,330,10,321,862,423,479,564,271,636,588,886,171,829,299,804,645,303,753,657,251,81,838,759,171,300,857,377,484,471,333,554,772,426,506,284,79,891,79,306,747,926,615,272,681,251,625,739,953,442,527,31,57,203,161,489,156,480,296,638,410,773,428,766,155,387,782,251,965,518,122,67,410,305,218,792,75,505,811,134,575,84,725,260,273,463,866,19,439,463,806,959,681,400,176,634,870,997,129,210,0,381,797,620,202,74,840,171,743,138,427,545,660,660,148,885,966,433,768,902,975,823,801,866,305,376,866,642,973,39,603,510,748,352,691,689,90,70,240,817,442,293,526,553,451,340,729,932,723,112,311,780,871,523,924,603,847,274,883,92,932,715,909,863,642,692,276,39,42,761,180,241,793,836,628,262,390,16,89,916,173,1000,786,5,898,538,27,1,818,660,785,639,99,711,601,694,631,717,234,289,275,296,647,26,624,430,999,145,591,794,575,73,631,559,999,468,640,570,495,608,999,754,274,936,950,370,901,140,257,599,15,969,302,468,19,833,276,4,819,678,719,94,363,357,138,998,180,269,375,707,350,9,304,671,647,599,239,693,851,428,758,478,388,468,27,664,45,978,685,951,587,212,295,730,572,532,291,779,848,880,897,828,190,392,269,778,104,563,89,158,763,648,64,742,917,694,120,434,435,210,531,938,86,767,814,473,89,677,585,253,220,530,637,276,884,541,208,13,145,895,434,478,161,135,397,399,328,236,81,485,225,57,325,887,228,935,578,815,122,961,322,577,201,550,162,576,774,139,849,642,581,734,808,618,311,912,580,224,491,835,713,521,467,450,249,727,724,754,607,246,860,246,439,177,868,296,224,513,364,217,784,149,713,386,231,82,480,178,792,314,122,722,230,108,891,267,662,352,600,163,972,768,639,419,386,725,324,998,491,740,513,538,445,322,897,791,335,568,816,306,931,69,463,1000,308,916,947,930,847,216,152,405,57,594,882,645,948,484,313,449,566,394,315,319,416,760,226,402,98,300,97,629,908,211,688,137,961,289,879,427,652,432,663,466,964,191,640,569,622,821,833,2,66,446,816,905,97,825,164,679,714,814,869,225,726,783,686,271,269,181,308,511,369,581,888,94,195,320,784,94,969,370,393,621,5,144,403,510,588,708,187,629,360,304,348,147,750,153,257,292,648,531,129,433,565,842,146,970,428,110,562,417,106,369,246,439,985,234,370,292,675,813,83,545,912,737,472,963,461,121,732,226,115,665,250,780,571,840,689,230,215,47,216,994,442,396,568,559,874,222,209,635,437,317,326,959,864,471,81,870,184,742,413,579,119,518,275,273,250,933,571,955,622,801,347,54,487,506,23,598,172,83,890,404,154,986,537,182,283,968,615,776,886,479,545,357,636,840,54,827,256,955,977,146,548,439,332,717,818,303,967,499,718,433,987,438,648,736,659,324,30,962,783,459,898,501,418,36,636,303,69,877,273,734,13,612,622,184,415,71,354,20,488,253,863,807,65,244,523,220,726,287,587,889,871,552,492,614,376,950,833,475,306,970,429,650,13,16,66,204,657,962,400,62,383,237,755,481,42,583,313,177,913,975,916,790,830,854,841,223,736,933,633,140,476,10,835,368,793,309,285,121,36,114,837,520,160,834,641,743,581,575,448,912,46,173,503,672,7,901,506,338,932,395,265,499,895,868,892,57,214,824,623,740,479,706,712,653,827,503,930,13,899,272,417,202,728,963,202,616,522,462,444,396,854,850,296,802,744,495,647,543,59,901,165,669,914,571,373,104,989,202,22,846,821,454,714,524,275,682,393,230,218,743,708,238,189,176,998,461,940,126,142,899,904,547,730,849,472,479,738,247,106,204,759,714,476,203,248,928,331,434,867,622,216,212,905,765,857,918,985,929,497,622,345,610,357,602,873,74,389,708,534,7,686,739,4,615,401,593,661,717,833,601,207,399,76,874,813,573,861", "507,705,743,513,597,175,785,948,527,505,808,61,382,145,423,955,812,107,806,905,418,178,110,537,26,434,72,774,908,253,146,911,532,59,327,796,60,826,976,176,53,629,356,901,442,909,346,107,660,607,214,871,88,21,185,299,548,319,756,223,80,63,671,439,114,479,852,52,843,783,245,846,988,711,652,819,876,434,794,516,524,934,991,737,337,358,739,274,483,679,157,394,988,214,671,69,199,637,877,549,447,859,641,912,462,270,423,553,138,94,860,697,531,404,739,775,96,530,395,972,815,518,211,642,179,154,750,322,894,986,627,893,656,64,667,418,121,75,377,305,932,652,336,774,603,181,515,727,798,808,875,84,834,528,809,182,542,886,895,311,898,464,892,889,891,280,129,179,544,138,23,507,993,937,182,195,477,167,470,288,848,686,756,440,221,595,786,213,404,429,397,341,409,179,267,36,637,113,137,66,608,150,94,122,413,76,444,948,600,355,452,414,718,663,355,339,602,579,479,950,947,836,789,146,236,352,676,493,33,381,0,139,23,833,745,359,455,482,615,745,849,766,486,237,399,786,956,528,637,660,914,318,397,204,711,576,658,845,215,634,839,285,615,142,210,504,963,140,191,432,299,21,923,74,701,711,796,40,826,775,27,991,22,886,268,817,674,89,183,166,566,176,1,140,798,320,159,238,464,248,734,47,72,805,594,708,447,644,959,688,294,968,204,950,685,792,875,46,415,470,823,947,742,778,108,716,153,66,143,563,366,996,227,655,57,371,926,703,850,279,202,750,609,273,812,569,734,394,905,676,71,40,423,73,563,176,538,926,400,414,953,980,390,60,280,841,103,939,657,751,399,139,618,932,438,137,232,821,876,931,887,4,362,451,225,529,771,665,438,406,759,94,72,681,393,771,810,112,796,390,586,206,653,436,984,273,873,334,889,611,865,626,411,579,795,296,860,456,222,170,961,801,37,961,889,989,118,33,303,111,225,437,722,755,381,190,32,744,976,561,64,721,939,774,408,174,32,149,962,341,340,627,579,183,894,706,10,7,8,110,416,881,237,627,257,981,852,911,699,629,844,336,516,935,510,108,73,984,733,81,498,268,473,508,882,253,794,201,724,195,497,772,418,33,284,121,858,728,891,830,921,473,27,287,898,758,161,493,587,4,638,799,741,364,350,154,766,97,806,914,685,777,452,559,370,988,57,784,712,8,339,534,101,168,214,717,149,155,21,857,510,109,937,241,297,551,866,17,350,759,973,131,685,223,712,334,980,327,112,420,639,613,55,452,53,510,270,966,152,432,287,528,810,783,456,943,194,628,656,853,33,998,127,667,65,554,26,135,208,940,614,178,463,385,497,282,764,87,304,84,203,936,869,209,654,302,578,602,349,952,968,314,764,882,233,561,231,751,711,859,329,954,545,904,596,869,29,77,989,705,164,371,405,471,117,337,598,29,893,910,34,695,521,260,315,887,873,245,157,884,686,480,5,286,525,453,556,877,868,876,944,163,390,359,989,684,333,872,785,119,442,195,63,533,342,924,285,822,527,56,253,641,978,938,410,623,325,785,869,829,689,66,219,234,243,817,38,345,853,79,55,36,575,87,267,7,389,707,507,545,684,14,779,223,851,50,172,416,31,291,59,712,175,2,895,983,952,176,37,401,190,540,724,378,940,632,759,389,848,173,948,370,900,614,685,646,654,305,884,472,717,833,325,91,463,568,6,159,904,377,262,365,141,93,781,167,639,258,256,318,901,51,789,830,977,353,348,384,867,890,416,681,485,468,931,543,757,252,930,871,93,43,618,879,486,677,227,261,404,978,84,28,79,963,691,816,299,971,81,74,663,446,383,970,744,536,75,381,940,80,36,811,811,176,500,383,893,872,481,25,629,22,347,931,991,392,395,153,430,477,994,667,348,679,491,810,934,243,771,617,50,758,310,55,848,935,932,632,812,680,926,327,612,22,858,378,135,562,174,412,421,599,834,734,551,976,277,364,834,886,429,4,955,797,111,355,814,97,147,12,905,351,758,670,526,829,218,629,923,594,321,146,130,795,120,637,583,755,542,896,2,500,765,851,71,280,776,634,174,619,716,789,153,785,683,761,829,940,832,572,912,835,696,718,523,495,335,815,485,455,811,528,983,29,164,689,547,517,678,311,251,736,859,952,223,757,34,357,546,179,127,790,540,668,329,734,170,637,110,647,978,845,831,451,806,18,839,922,6,113,358,827,398,474,277,435,673,617,524,549,112,932,657,349,946,237,913,378,919,452", "389,227,78,833,706,168,569,234,309,729,110,174,618,441,998,814,895,428,973,689,212,638,912,226,948,292,289,730,769,855,764,121,132,109,10,204,201,270,694,421,884,246,221,430,252,418,711,853,44,22,236,137,447,180,491,248,148,307,763,576,274,245,881,203,343,285,93,556,478,449,459,78,665,814,579,318,303,672,668,274,701,121,908,996,948,310,61,570,501,345,369,571,548,256,572,851,317,43,306,898,572,706,444,353,579,378,398,820,695,797,775,94,439,747,898,530,367,447,937,314,274,635,287,499,155,400,801,977,295,685,49,417,861,276,460,909,274,995,730,889,457,639,822,400,61,920,646,249,788,928,731,570,243,39,265,985,266,761,843,261,777,574,385,903,837,592,782,827,62,897,64,463,968,261,364,514,887,53,110,479,43,511,260,665,120,134,945,788,550,874,310,457,713,372,836,969,171,923,377,470,26,580,11,450,671,885,247,373,78,414,819,218,970,954,370,735,256,427,200,199,365,496,454,668,367,375,415,586,138,797,139,0,441,962,243,585,134,265,319,745,730,239,493,933,711,963,92,854,401,982,71,711,422,42,887,885,392,570,806,293,763,573,639,874,975,16,753,971,141,149,585,291,59,514,698,666,897,806,657,309,552,94,13,547,155,614,150,378,316,818,830,991,283,810,628,884,576,849,705,417,756,721,836,149,431,795,489,348,818,598,175,280,709,353,776,491,168,602,348,783,488,635,259,872,704,260,25,976,400,75,559,855,915,731,775,201,893,385,105,143,485,699,266,716,476,738,457,700,898,171,212,551,83,65,153,86,67,244,540,457,541,103,307,864,533,425,597,411,995,615,908,236,867,176,355,877,645,564,42,436,376,671,126,532,635,590,560,663,157,749,838,219,752,985,9,567,515,260,31,308,988,410,335,933,91,204,615,372,783,180,833,458,679,35,21,222,472,916,216,979,859,32,715,122,77,781,520,188,124,485,550,85,88,441,484,901,57,417,854,359,175,958,861,341,480,965,541,207,350,559,335,142,342,753,657,906,350,881,109,167,873,308,257,152,132,967,771,613,817,959,106,170,551,10,54,582,622,455,784,264,632,3,390,680,414,473,84,390,560,227,401,29,661,540,867,188,65,391,724,303,677,913,315,273,502,99,585,748,855,10,716,63,187,448,808,123,643,505,399,104,737,326,102,134,323,84,718,815,550,549,821,676,16,263,794,599,150,504,859,465,990,867,498,109,990,736,607,617,168,409,512,999,154,965,793,792,495,181,687,637,49,174,923,998,60,221,139,226,836,964,254,766,77,182,546,323,976,405,657,127,890,711,173,159,8,741,580,676,812,856,645,856,795,377,763,241,199,209,763,572,89,15,491,773,969,691,626,468,878,698,488,322,637,497,573,932,363,497,38,796,427,858,767,88,870,668,347,417,267,840,534,972,956,985,913,813,715,69,321,817,636,246,414,160,175,865,513,114,289,762,654,409,856,671,756,955,251,457,832,123,788,36,536,479,917,841,838,21,760,952,938,302,951,756,253,537,155,121,716,22,891,535,179,636,434,155,481,93,864,274,183,724,624,588,789,879,287,231,437,214,452,611,726,452,144,996,777,87,28,558,961,765,760,605,91,655,234,438,44,620,224,478,814,112,161,720,584,805,24,187,891,285,397,94,85,616,452,145,836,911,18,935,795,882,639,507,988,40,638,58,208,176,159,636,366,275,772,716,73,903,199,986,812,289,746,955,275,272,900,883,863,116,737,530,255,334,360,267,278,886,37,855,252,890,201,63,768,827,254,939,875,819,662,139,522,11,119,15,986,593,399,978,729,297,286,616,495,175,136,188,170,121,41,692,400,697,539,599,832,688,562,491,385,601,867,993,628,889,646,202,751,28,281,93,122,747,825,319,6,299,784,684,770,776,535,498,696,37,405,828,60,936,906,807,405,415,533,5,622,279,692,884,482,779,535,369,985,512,186,667,428,877,268,657,374,56,725,76,494,470,586,968,151,819,588,859,565,627,955,769,467,349,960,316,671,845,805,955,550,626,332,976,765,803,801,372,938,7,555,253,299,103,473,375,756,132,517,651,660,225,511,418,476,496,331,675,803,940,658,773,929,239,64,790,22,61,720,999,823,730,26,919,742,504,661,265,471,807,718,655,789,299,774,691,47,167,859,459,260,519,372,411,734,367,176,501,953,740,552,751,629,380,970,311,97,749,852,541,250,135,394,173,710,900,518,937,39,167,242,760,92,865,205,325,348,369,810,542,549,255", "263,66,415,440,38,591,805,389,884,232,311,385,136,106,301,429,853,845,478,580,132,438,592,159,255,69,694,916,206,427,631,768,142,473,649,165,510,771,59,539,157,74,339,331,681,729,552,92,230,896,569,840,726,635,535,57,56,39,25,572,441,745,330,312,404,954,32,847,413,532,958,644,537,29,783,739,924,209,561,776,331,228,176,942,576,413,842,331,316,124,162,495,200,217,286,952,741,117,748,643,867,473,375,999,396,262,357,359,283,94,408,925,857,6,27,681,301,919,250,976,265,179,661,768,437,891,356,552,811,753,173,136,284,824,147,549,99,976,744,158,760,105,142,989,445,906,512,43,922,41,246,706,136,442,674,563,489,931,41,923,868,394,4,142,810,819,318,398,920,730,704,157,226,296,835,887,881,984,464,367,42,436,688,755,24,284,625,811,237,426,815,10,447,348,837,528,154,269,792,775,895,40,478,126,576,857,587,330,404,736,134,303,205,56,303,19,601,587,111,914,398,198,930,367,384,458,49,38,699,620,23,441,0,842,620,236,927,994,102,53,801,579,238,433,344,854,7,429,891,736,841,996,330,461,579,999,902,854,996,71,464,599,289,178,93,502,300,956,8,153,320,451,968,609,623,875,637,826,149,317,598,30,794,861,176,607,29,280,739,745,710,169,598,216,513,245,848,839,454,142,41,673,76,525,246,851,602,510,542,458,915,847,692,418,968,234,422,284,483,650,573,522,249,315,668,575,587,696,295,833,684,634,393,825,749,512,98,995,724,596,504,928,489,779,685,291,304,314,587,716,555,675,359,153,890,858,225,221,925,277,238,148,178,580,244,695,212,789,763,334,913,243,120,399,71,21,248,74,752,432,662,533,311,3,845,963,978,109,344,631,700,688,149,592,837,796,574,611,145,885,124,945,148,625,894,481,162,819,796,619,858,868,347,597,84,64,225,444,179,898,25,115,19,123,583,197,854,52,416,95,432,574,987,21,322,646,863,870,312,351,558,71,816,374,343,995,379,29,23,352,740,478,839,105,943,569,259,175,104,917,122,655,195,266,54,412,152,449,19,897,32,98,891,939,406,851,308,222,288,735,419,113,902,385,295,491,759,178,877,648,449,558,801,783,575,497,729,505,338,934,803,381,902,349,54,819,134,339,100,263,909,695,613,697,494,653,436,317,229,490,518,881,640,289,21,402,302,111,268,256,456,483,226,13,385,3,66,850,970,426,192,638,762,21,446,785,568,554,359,399,929,319,47,404,272,97,582,433,622,6,122,364,950,61,971,108,985,258,760,536,263,113,822,501,923,581,19,815,415,999,510,272,375,140,769,4,844,630,967,522,712,244,63,200,134,628,880,541,507,885,83,282,197,239,625,173,727,414,604,925,610,803,842,132,666,387,347,599,831,627,164,91,145,642,173,917,527,612,314,439,13,592,221,782,547,406,447,339,673,611,727,296,47,763,199,590,256,949,583,123,703,507,804,133,994,684,157,871,568,537,947,935,309,187,249,523,669,151,78,591,723,347,498,579,665,359,288,63,181,559,72,460,228,946,464,203,292,475,916,840,819,674,536,891,538,597,287,90,545,72,23,546,769,301,22,440,250,397,418,93,209,627,329,314,443,515,414,33,371,891,113,798,842,518,230,126,145,261,940,88,620,823,492,265,97,340,493,775,855,744,949,406,941,199,141,940,870,839,910,117,923,948,164,945,132,181,259,230,652,623,805,563,607,409,691,850,848,637,830,889,198,664,289,485,965,378,727,953,516,898,54,535,662,457,146,101,62,955,460,356,69,234,729,405,669,340,369,945,626,64,723,844,515,347,131,469,940,27,894,767,489,15,543,393,803,713,390,890,110,132,89,422,786,826,39,758,516,859,994,979,837,172,89,293,46,238,659,981,246,152,538,766,906,428,666,378,754,42,762,498,203,869,600,902,376,267,511,905,455,345,555,949,666,420,942,146,336,586,71,261,405,470,73,952,882,826,131,651,383,662,569,995,985,763,668,889,761,136,266,492,169,954,87,216,152,610,44,39,795,826,912,583,830,837,338,301,87,852,251,317,74,4,478,694,285,475,5,322,540,528,83,249,407,484,18,539,353,532,376,394,888,49,959,209,106,632,942,73,748,902,413,993,580,597,780,518,263,217,73,916,155,104,577,640,551,613,997,519,363,760,990,899,872,457,423,487,463,160,653,196,138,452,599,445,351,295,913,157,90,359,62,342,406,312,737,95,994,669,727,897,432,342,44,842,508,429,544,626,482,324", "88,620,23,189,330,206,232,326,887,145,977,73,870,40,201,679,725,444,166,213,783,332,511,489,430,542,813,623,239,841,153,930,96,528,618,767,826,292,898,636,618,315,812,852,213,676,85,395,999,764,638,465,566,40,191,538,453,261,18,944,727,884,882,566,101,587,652,362,971,977,371,441,77,204,133,676,184,580,651,258,796,664,411,872,329,70,23,147,10,205,905,930,18,89,994,316,608,692,623,245,78,764,603,905,107,784,266,947,964,900,858,184,530,618,174,130,872,776,282,437,326,941,521,368,784,664,761,285,662,828,780,841,131,313,165,424,309,569,700,886,194,818,256,577,141,716,786,699,942,547,598,4,903,657,347,307,281,32,591,296,699,385,918,225,467,675,493,330,823,129,624,694,784,179,187,275,728,724,571,810,300,511,461,114,355,897,461,105,761,826,395,629,493,842,742,803,358,471,996,94,539,109,191,143,596,901,424,225,570,249,588,894,307,970,598,739,504,592,886,187,783,333,798,652,337,867,673,903,281,202,833,962,842,0,582,496,953,101,350,965,573,778,43,179,634,594,142,578,640,496,837,687,945,837,6,307,544,113,784,138,145,548,588,33,854,858,42,893,47,256,417,495,282,936,172,523,40,286,165,920,896,957,208,744,443,663,759,541,175,424,399,387,650,766,235,370,406,662,576,690,860,361,406,282,880,48,747,164,982,500,154,760,85,780,216,369,631,518,861,4,512,288,752,53,447,360,629,19,341,238,105,829,666,348,630,841,909,717,815,328,406,923,732,315,580,64,144,891,195,179,854,642,213,507,151,340,675,660,36,369,713,560,40,606,825,639,441,954,569,173,173,395,868,453,805,561,399,990,640,14,296,40,337,250,860,639,768,511,779,862,52,508,908,711,377,309,828,70,76,583,190,210,339,740,329,15,329,458,385,204,788,594,476,861,683,659,671,639,784,42,253,707,109,87,527,458,215,898,74,433,169,75,497,156,461,934,297,299,554,180,531,129,823,23,426,109,242,713,995,603,456,947,308,859,678,954,657,835,949,599,825,870,586,787,619,246,915,722,848,424,47,33,219,601,56,97,227,24,861,319,851,810,624,947,502,824,858,27,411,40,872,209,519,756,204,714,439,198,477,896,364,352,896,145,106,971,61,40,223,463,45,377,883,332,424,346,573,296,92,626,143,900,339,742,617,816,999,584,547,492,992,749,213,129,199,744,852,508,544,972,645,73,335,528,834,620,439,632,213,341,941,473,972,289,827,78,698,213,862,300,836,104,566,826,512,910,302,18,948,131,398,200,511,651,750,948,60,944,392,909,794,996,16,121,577,282,300,343,137,703,449,322,687,324,596,666,930,135,372,835,302,909,886,926,771,514,814,679,150,137,275,576,203,435,18,180,200,894,138,611,45,840,853,326,212,323,368,188,619,448,677,222,714,73,370,606,365,76,178,907,486,743,250,433,254,862,517,804,280,238,592,417,895,380,234,758,543,335,398,220,414,997,463,887,880,356,628,125,72,185,720,142,130,717,761,716,8,25,396,675,526,745,184,389,659,554,700,379,433,706,292,263,274,534,659,767,717,506,848,227,292,100,138,543,826,225,348,710,993,639,833,231,734,935,698,266,851,193,575,608,612,923,88,278,663,591,255,245,295,350,72,729,483,591,11,588,913,569,86,267,589,3,874,354,16,663,100,624,354,607,290,861,796,871,736,89,403,926,24,827,479,317,406,366,844,22,116,896,90,99,811,908,806,438,142,665,944,73,383,824,987,650,538,33,599,89,506,40,849,612,70,419,316,951,328,385,555,575,813,718,474,810,561,118,341,622,70,985,182,388,713,319,402,990,307,298,412,382,974,249,670,276,404,37,337,899,539,139,427,180,956,596,302,680,874,324,546,937,537,238,164,830,758,586,78,706,750,114,341,828,880,859,98,462,916,928,112,790,173,897,171,280,440,319,454,69,17,897,118,57,726,324,231,240,295,300,677,864,315,34,102,426,168,726,242,42,566,654,278,74,704,391,613,515,516,848,955,339,275,815,946,366,687,675,837,491,336,568,819,623,852,517,644,754,793,670,121,947,684,807,364,181,719,520,130,897,578,700,388,773,498,76,726,851,847,573,4,727,446,618,999,526,459,719,913,450,570,612,541,709,773,778,628,3,693,253,812,216,135,514,292,448,664,951,4,138,628,394,808,819,822,740,49,370,160,471,129,11,616,680,686,581,847,389,757,333,737,695,134,402,228,549,990,188,744,855,669,914,438,627", "291,982,434,241,856,784,328,594,512,282,927,644,184,451,319,570,276,836,932,387,266,149,65,219,80,565,811,721,883,527,146,856,359,990,597,745,23,219,823,35,477,464,817,4,403,529,390,825,754,778,904,621,270,431,43,65,810,680,241,536,416,963,916,170,814,479,873,586,743,741,493,27,114,417,986,354,761,652,132,591,76,180,387,865,691,260,675,825,863,803,457,780,917,965,322,521,429,579,659,759,26,112,418,117,302,780,751,403,541,254,919,821,69,55,223,265,360,426,537,170,154,5,553,703,362,266,487,495,333,375,726,505,282,740,550,739,631,50,713,12,148,381,233,111,862,311,67,886,772,483,548,756,44,251,162,749,113,322,474,337,770,224,237,653,412,246,595,7,783,933,350,255,53,372,673,85,430,22,159,116,466,523,508,433,92,905,587,506,597,16,288,222,146,334,19,65,348,431,553,150,110,130,694,446,347,848,773,343,597,849,751,332,32,320,771,535,160,1,438,86,164,99,727,931,467,675,123,682,980,74,745,243,620,582,0,490,99,101,331,138,681,223,977,56,967,747,895,699,319,673,992,217,745,320,643,296,904,528,400,35,619,482,10,473,594,531,895,450,457,122,424,829,370,778,562,475,925,62,799,292,947,786,53,868,390,223,679,529,571,694,749,400,477,592,678,977,568,771,145,888,687,761,72,521,209,683,606,616,380,600,235,586,220,492,56,929,975,646,999,862,823,619,84,708,386,179,168,959,558,866,468,742,853,636,971,567,697,211,802,438,523,872,814,280,379,886,148,461,267,712,281,279,157,615,536,266,331,838,614,151,7,258,25,698,4,219,532,835,498,425,341,249,393,640,293,41,67,111,945,27,142,299,961,873,561,745,312,53,937,406,595,89,102,595,508,183,672,477,828,700,188,846,994,645,11,16,385,649,218,419,648,245,376,13,718,295,130,309,872,376,174,343,176,843,503,403,414,975,152,828,982,653,960,913,297,561,396,441,967,55,233,225,190,461,809,624,386,102,4,743,175,897,650,447,921,563,444,208,629,181,174,562,112,746,643,702,919,745,561,955,741,825,414,271,108,852,882,171,529,311,303,918,433,20,123,895,918,54,293,420,373,61,392,357,883,464,523,992,519,320,449,862,657,703,651,282,647,269,80,740,779,658,813,930,806,729,105,428,308,554,148,345,784,466,729,544,152,461,644,928,216,926,917,651,731,999,679,448,53,597,873,392,579,857,439,577,885,54,341,788,53,357,373,35,785,131,106,377,63,844,779,637,902,762,453,877,308,909,383,967,317,917,594,241,221,951,225,115,916,94,535,278,852,763,420,607,492,785,985,824,717,260,76,325,783,90,985,36,876,893,162,176,867,102,449,507,65,708,238,859,32,13,398,762,711,839,378,78,924,779,744,191,974,199,634,58,58,503,910,82,894,65,725,930,43,804,728,524,378,719,503,537,903,432,120,659,802,734,185,431,233,34,581,651,923,957,154,419,803,432,215,999,792,198,538,944,671,865,565,481,695,645,144,505,715,343,924,807,160,314,488,901,266,449,611,92,525,667,339,266,806,330,992,16,879,970,933,18,262,454,42,720,438,329,794,217,572,824,133,489,946,192,30,221,153,383,799,992,751,651,496,197,883,420,336,3,57,426,785,853,8,599,973,932,862,730,727,487,874,186,15,780,271,485,397,829,903,702,237,470,737,831,719,665,3,993,709,76,566,529,210,569,361,970,852,653,350,581,471,656,582,304,432,139,785,301,949,643,825,308,384,892,775,126,956,651,763,749,35,124,83,319,789,874,108,885,216,702,999,651,559,729,652,846,296,103,645,44,837,951,319,937,228,384,395,317,877,857,369,657,720,812,419,861,536,463,106,777,714,628,328,213,516,785,575,787,305,575,634,979,643,480,44,165,260,627,434,37,165,192,535,261,44,796,408,756,100,990,411,622,80,916,323,878,67,768,811,8,132,551,462,29,504,615,160,307,382,376,434,198,15,875,165,353,374,554,254,566,15,67,709,16,15,329,308,311,144,313,261,82,363,401,453,543,122,830,670,216,623,141,369,358,790,533,138,332,394,793,244,686,636,37,158,347,74,12,493,904,850,314,906,999,862,83,81,157,417,682,998,872,24,488,30,58,692,456,34,731,767,345,748,49,449,39,141,487,437,579,475,643,656,432,5,968,11,342,184,357,242,855,731,167,118,143,869,925,304,94,889,10,95,385,488,687,156,760,597,572,293,396,703,746,259,986,866,901,617,30,657,644", "885,33,618,10,790,533,315,396,715,353,702,570,920,445,39,439,463,578,15,684,505,13,77,211,960,883,150,784,974,573,554,379,410,515,410,839,832,935,39,968,555,540,525,493,245,840,375,543,928,574,55,171,493,813,370,441,361,175,621,478,7,714,688,848,223,312,314,730,688,678,978,482,794,189,527,400,837,314,193,789,623,782,890,422,238,861,722,627,380,81,115,499,787,124,30,276,305,729,539,946,866,580,419,644,259,766,568,715,331,523,688,782,961,118,751,541,347,323,242,631,360,217,463,185,384,717,411,815,819,991,654,397,384,314,41,701,912,938,726,701,80,459,135,875,6,440,260,33,596,575,958,557,485,404,443,863,583,559,452,429,547,292,649,486,600,943,217,597,895,419,265,514,325,522,148,704,548,856,255,678,259,22,319,752,482,787,743,682,520,471,799,303,361,930,697,649,366,390,424,919,738,181,262,439,235,435,267,105,577,669,922,460,75,934,990,843,744,803,926,343,617,652,451,650,259,303,168,357,750,840,359,585,236,496,490,0,588,141,853,283,718,955,864,663,996,32,304,459,857,235,304,416,552,18,685,840,138,448,919,482,778,976,973,674,11,755,927,328,967,97,283,70,43,851,106,637,812,980,523,66,708,425,994,544,831,961,681,473,378,563,256,584,191,92,171,148,513,379,508,689,401,785,545,885,940,262,943,107,804,725,639,643,801,130,729,6,62,982,31,518,697,249,741,968,332,516,555,674,968,671,596,985,692,797,973,57,303,996,50,864,604,866,425,386,575,22,66,84,187,346,492,39,33,784,727,130,112,55,362,855,207,319,742,182,99,384,762,632,331,682,410,532,502,213,861,519,738,92,911,62,67,798,970,38,592,776,724,478,78,302,251,192,500,663,830,580,199,654,545,169,309,750,955,168,541,790,982,678,747,239,205,696,972,337,216,127,966,318,494,429,79,308,27,280,57,189,893,628,688,889,154,482,145,630,513,605,779,13,697,69,381,200,905,83,386,383,989,689,87,881,701,631,813,210,805,775,306,123,759,900,27,442,655,466,438,111,534,582,916,508,790,452,331,654,926,981,611,9,403,997,451,171,370,889,945,745,713,439,741,700,718,643,786,179,739,369,70,87,230,628,121,93,465,469,962,880,115,153,670,999,359,211,733,447,421,347,521,866,549,53,662,506,386,846,585,779,175,21,406,934,356,981,338,303,779,104,635,891,157,987,612,989,274,965,833,507,244,512,489,341,568,762,929,904,49,548,978,14,237,831,882,190,362,703,744,630,685,866,894,234,478,65,165,584,269,444,565,124,270,327,925,124,388,105,695,30,4,536,673,685,713,742,589,69,254,628,470,538,913,16,939,38,18,789,947,982,778,225,47,462,671,748,922,572,728,426,45,17,511,615,259,615,440,528,268,129,681,947,79,651,998,441,662,687,769,495,115,378,51,576,523,679,554,552,953,931,276,176,85,475,237,558,813,187,145,868,721,686,555,767,808,4,621,577,390,240,120,337,411,507,148,256,398,817,664,855,29,110,652,395,1,155,209,439,638,584,646,768,989,534,442,277,972,797,749,432,935,99,986,683,664,354,206,935,301,1,784,89,325,647,613,119,752,736,225,205,326,207,892,20,943,737,1000,102,520,374,831,85,669,641,87,620,946,549,862,798,521,297,287,273,94,913,348,199,100,293,567,661,112,314,607,103,787,932,422,732,913,986,907,824,80,744,828,303,791,907,434,84,282,535,79,143,430,699,227,169,885,304,665,343,94,666,109,507,848,851,917,372,204,501,683,138,861,9,348,132,687,392,812,163,473,188,694,103,772,179,863,760,533,192,869,253,466,88,726,208,208,826,134,172,249,371,130,498,927,682,279,266,381,378,909,722,47,232,731,778,986,257,373,745,703,678,845,74,625,505,512,255,881,381,403,283,19,67,439,440,628,685,312,886,349,980,252,11,155,516,887,680,211,881,469,372,444,435,927,206,176,421,619,666,415,128,723,939,104,845,156,792,787,186,250,635,471,642,808,672,743,834,253,595,113,16,557,10,289,461,731,768,848,977,574,486,270,795,269,827,242,365,641,786,586,306,586,911,764,452,496,769,704,476,815,794,121,507,330,405,305,653,39,154,78,767,676,150,677,286,287,160,874,204,698,873,367,274,381,13,382,490,949,254,224,75,785,761,258,911,839,87,304,956,737,940,500,784,630,605,775,592,738,512,402,571,676,31,643,59,911,275,411,326,487,605,528,835,233,365,746,563,267,642", "106,317,22,210,509,541,966,467,381,322,260,154,194,450,14,716,212,744,569,704,225,665,645,732,514,925,393,787,383,818,860,87,593,108,785,513,710,158,786,200,641,832,439,743,344,799,715,949,751,188,349,559,77,807,628,803,631,420,344,594,783,688,807,911,505,983,247,447,317,842,948,751,938,280,895,162,258,887,652,36,285,163,828,116,511,622,34,218,798,262,70,216,918,57,444,55,13,755,666,252,946,456,333,524,646,460,893,317,214,390,578,257,900,725,584,586,101,38,988,501,675,150,363,6,502,631,178,987,76,153,688,918,904,156,994,780,23,863,303,326,675,421,412,890,897,383,50,916,637,558,879,785,888,864,575,355,658,305,196,460,975,295,401,49,446,368,690,400,149,741,659,393,337,643,753,749,125,916,497,634,953,268,641,146,177,800,771,857,648,567,322,186,332,313,18,489,432,932,613,266,57,844,6,891,635,947,457,441,750,633,159,319,597,290,794,479,185,966,147,770,630,252,474,645,499,270,613,654,801,171,455,134,927,953,99,588,0,652,314,888,488,69,750,445,988,902,322,126,581,453,244,236,546,645,430,549,904,574,938,866,745,156,605,444,878,246,543,117,860,654,787,337,635,156,391,918,228,307,9,85,47,101,13,848,318,602,710,510,440,282,280,317,516,370,567,519,521,664,442,784,422,712,330,685,120,415,599,338,781,153,469,332,868,133,355,301,563,805,113,265,72,99,220,560,837,516,684,5,733,189,762,171,738,856,626,900,488,940,14,731,352,554,8,453,584,168,199,429,116,759,777,79,559,902,610,747,831,344,689,325,267,299,519,907,172,532,142,720,443,575,867,331,221,827,296,96,756,261,662,797,564,772,216,668,319,343,220,738,19,841,375,881,208,557,817,394,946,128,695,433,838,393,318,916,935,33,608,25,594,680,984,133,101,260,216,385,715,863,836,303,530,748,531,408,498,327,718,89,443,971,735,277,139,458,785,193,925,155,646,798,474,805,886,731,580,607,308,517,879,545,821,884,358,149,683,363,105,709,284,667,761,375,361,327,740,115,265,857,195,12,578,461,4,870,373,192,637,35,201,157,279,224,888,469,91,476,937,81,744,519,140,682,674,46,907,995,307,296,277,617,666,815,389,240,818,275,125,271,771,145,412,562,634,688,283,925,863,87,651,939,93,51,375,589,58,257,231,403,99,422,594,500,378,391,297,956,43,971,237,55,204,573,220,223,595,677,576,27,449,937,72,680,68,955,374,636,643,462,581,727,326,495,723,225,261,295,789,841,429,301,863,889,600,233,856,187,129,547,78,49,660,233,782,388,979,315,627,912,908,527,504,314,630,233,171,577,867,580,188,870,549,253,260,132,976,404,703,141,275,812,335,647,333,329,630,206,36,188,244,704,641,277,986,300,481,192,755,423,147,373,42,583,989,787,677,907,862,967,673,504,384,549,279,294,178,16,462,208,3,362,143,966,185,992,596,685,451,393,770,3,108,683,379,593,508,803,834,590,690,548,18,902,829,288,258,487,894,251,663,950,801,751,99,323,38,473,320,63,732,272,621,88,817,906,132,288,324,239,885,767,146,56,590,89,397,790,955,94,707,810,836,657,640,2,299,376,403,298,473,418,163,600,713,319,357,805,134,730,818,327,209,720,219,343,367,870,707,903,580,585,5,289,737,197,744,768,785,596,796,511,635,651,192,720,494,126,394,150,854,550,475,462,159,547,422,509,401,457,600,792,595,152,764,864,409,170,475,39,470,217,131,114,721,906,691,667,690,227,720,900,367,594,548,936,935,713,386,12,563,184,616,884,234,543,808,814,558,655,692,407,70,580,505,314,148,190,303,902,673,511,94,907,105,513,808,389,820,249,374,182,74,622,390,791,258,340,320,527,702,410,523,465,728,99,604,161,293,356,27,430,689,88,473,664,443,451,756,300,648,468,25,87,374,932,545,883,419,761,40,841,464,314,17,760,145,998,899,597,791,719,119,463,863,480,62,888,88,386,196,756,454,318,400,456,539,910,80,83,1,661,587,453,718,821,779,483,347,134,76,303,771,114,200,513,310,185,156,319,853,975,874,999,131,142,241,356,561,822,821,46,604,956,259,456,76,244,538,65,313,504,569,192,947,856,582,581,159,704,513,848,829,167,264,695,158,596,845,880,153,875,110,200,211,753,705,962,199,49,642,621,49,631,697,528,903,736,880,425,205,370,420,981,582,973,723,613,77,412,166,171,918,160,474,446,787,977,392,644,914,181", "638,925,574,56,460,381,65,750,960,285,517,570,204,204,815,83,295,769,160,814,670,3,292,328,462,46,13,705,497,1,110,866,747,188,703,495,36,992,396,91,500,907,265,435,789,718,829,569,504,453,555,741,45,383,544,644,265,318,899,922,925,83,613,387,7,667,212,690,699,45,190,746,150,53,572,933,46,387,116,282,228,403,605,302,686,805,316,704,641,921,891,648,825,717,158,681,219,439,59,360,383,131,368,664,614,550,487,31,459,963,232,372,792,855,6,936,681,816,412,614,577,250,326,457,764,490,897,586,543,776,157,270,627,856,986,920,444,845,885,993,292,118,461,467,990,846,479,179,110,542,132,121,418,694,791,768,989,107,223,294,204,937,37,87,57,558,885,231,815,352,546,708,846,597,370,58,224,573,477,673,595,115,88,395,82,592,362,974,326,390,442,845,910,186,765,119,585,836,751,159,41,1,94,462,957,313,245,941,782,858,7,461,127,921,835,385,886,68,228,846,229,282,169,740,140,407,760,277,782,743,482,265,994,101,101,141,652,0,810,578,14,257,582,40,696,14,172,574,968,681,459,564,728,244,851,62,583,511,486,158,301,52,12,318,850,21,302,387,929,798,717,351,241,971,803,208,199,745,728,473,443,988,970,226,856,295,600,620,697,739,425,235,204,568,181,733,730,155,291,714,314,22,999,527,128,300,866,76,644,440,693,426,744,34,829,162,679,701,866,294,211,347,723,68,894,236,606,762,337,97,792,261,954,61,83,826,520,384,280,765,486,696,657,106,98,220,984,710,619,351,169,928,94,958,211,456,243,350,714,75,588,141,221,616,193,702,797,6,603,353,555,26,308,28,903,21,256,590,796,586,320,87,377,564,512,666,669,591,228,652,156,909,289,863,678,588,921,62,578,352,928,420,164,234,27,535,913,751,484,666,866,343,65,164,173,745,359,314,26,994,22,198,157,230,469,819,870,807,480,95,571,579,668,702,192,171,112,284,474,731,34,554,568,287,508,363,630,534,230,525,902,770,546,110,577,877,626,34,78,999,217,58,627,838,517,959,125,77,984,107,966,380,434,806,396,947,747,132,805,887,238,331,620,708,190,153,476,634,162,30,577,70,167,65,989,342,514,389,313,248,92,361,454,516,473,606,577,713,214,851,650,407,120,916,723,63,137,943,632,630,909,757,809,265,812,695,844,301,839,310,255,427,714,702,872,230,100,249,780,269,368,326,133,971,835,693,243,34,663,537,578,590,185,988,944,626,733,771,334,776,773,109,925,292,211,45,78,234,549,79,119,887,505,817,316,955,905,826,202,29,684,868,439,436,807,233,552,827,614,127,927,528,325,59,198,109,825,411,507,180,243,45,52,247,879,805,663,159,887,81,141,637,760,671,515,181,396,355,16,788,415,960,829,486,979,387,955,823,79,903,764,351,605,603,797,139,851,401,501,696,407,103,670,442,934,78,298,118,289,942,612,80,15,311,288,714,604,908,266,470,328,411,467,533,543,509,613,509,832,402,271,975,674,729,159,951,586,583,737,880,323,876,640,70,101,4,94,70,153,780,472,418,69,974,242,963,380,437,443,127,406,449,25,423,504,595,453,42,103,293,565,644,593,803,427,433,150,389,203,655,417,101,86,454,793,445,242,989,11,525,935,253,434,365,562,579,828,668,601,771,908,655,4,921,297,55,510,929,456,161,983,569,751,97,721,436,649,338,120,204,263,44,865,332,458,486,993,181,107,279,594,185,556,623,945,473,853,319,935,739,443,885,66,847,937,552,259,824,455,542,781,790,967,325,332,131,724,611,897,934,966,131,959,932,471,590,772,962,479,863,10,729,385,286,689,172,438,681,8,81,317,624,881,931,412,580,218,128,864,699,139,845,434,145,859,691,724,187,719,649,855,311,695,357,562,852,145,949,409,510,515,286,809,618,270,376,412,521,867,214,625,962,501,457,462,261,18,970,252,989,338,32,274,279,837,304,670,535,586,836,279,85,925,25,521,637,250,371,11,857,152,561,992,102,645,303,227,53,534,754,408,907,90,142,441,264,698,909,444,111,758,426,509,278,184,469,941,482,176,447,821,702,87,457,245,447,707,126,971,172,177,659,397,47,479,50,604,98,435,921,241,360,979,746,402,157,1000,767,385,294,757,275,146,474,747,931,436,562,531,429,242,25,514,204,96,983,314,687,240,459,79,64,819,825,674,844,42,547,183,553,576,500,312,47,224,495,797,72,592,228,623,991,389,840,1,491,227,454,816,823", "375,780,692,331,143,423,852,366,181,771,71,199,774,698,505,493,64,237,803,223,928,195,855,651,88,207,467,880,907,122,128,831,716,410,433,204,916,418,81,27,160,515,795,390,735,130,995,110,772,589,950,253,690,728,83,756,803,186,391,233,398,901,83,238,419,366,690,595,676,621,201,390,242,327,960,749,776,43,676,94,12,696,188,942,673,317,831,478,925,642,563,124,650,215,598,736,152,887,824,479,751,150,520,977,657,107,232,878,397,320,491,798,198,226,448,872,167,726,320,973,727,819,128,382,762,826,263,606,95,972,969,381,644,486,793,733,994,975,455,892,333,731,372,118,910,350,873,210,143,891,994,6,170,756,65,167,301,172,608,623,623,256,286,426,944,148,648,683,211,176,608,764,969,67,926,67,766,997,133,48,775,243,819,902,544,358,722,998,860,258,827,191,491,189,439,561,691,668,229,622,803,46,578,366,746,703,653,308,488,799,411,212,844,214,293,689,388,369,488,893,680,864,984,430,813,350,17,575,87,138,615,319,102,350,331,853,314,810,0,134,366,741,749,164,507,209,881,257,112,803,764,759,935,531,259,222,717,38,518,296,321,677,335,687,542,491,292,589,336,208,489,393,570,453,490,700,329,464,352,875,538,634,298,219,864,372,647,226,810,368,77,651,178,209,730,329,923,730,702,52,612,808,32,684,214,665,961,746,414,8,367,118,539,213,296,426,283,34,480,129,955,274,717,658,715,966,537,551,975,284,253,29,808,217,517,698,292,291,379,830,887,331,922,753,356,904,657,392,648,204,868,574,106,249,857,537,585,837,19,943,861,768,696,806,95,172,432,687,157,787,78,41,810,481,319,380,89,896,817,944,217,90,258,874,355,6,847,177,241,709,767,998,79,249,869,544,952,676,134,24,358,647,634,565,241,420,347,518,888,473,814,508,763,568,111,289,695,117,507,464,782,37,821,113,698,662,256,538,624,371,583,154,685,94,195,796,901,360,292,782,848,763,990,222,869,56,942,585,447,768,351,609,393,44,590,131,43,944,571,516,76,870,31,389,927,84,977,877,509,523,251,481,909,301,686,961,681,102,683,163,935,48,475,788,650,137,433,966,557,945,515,798,588,923,694,983,236,302,656,383,423,58,946,101,214,306,159,52,252,883,253,667,908,762,874,507,645,738,190,159,647,116,787,862,420,665,966,836,532,249,322,554,302,538,578,284,402,155,237,522,346,256,668,790,120,976,716,511,891,7,28,417,268,52,253,815,712,59,629,742,799,74,742,10,711,729,512,791,473,987,91,217,7,708,649,134,649,665,354,909,677,474,756,856,511,538,629,815,10,791,662,638,701,198,604,45,937,153,211,675,323,631,880,519,249,579,484,938,308,873,831,18,35,442,479,443,333,736,632,247,593,24,785,824,746,169,754,128,213,128,48,753,181,138,930,608,757,611,598,418,82,477,5,382,295,271,571,161,960,195,216,417,566,577,701,697,155,278,376,824,991,820,458,98,816,577,823,518,632,954,261,706,421,787,944,308,345,326,183,340,213,437,679,428,371,87,587,951,785,54,995,736,290,645,443,803,669,771,559,499,510,120,878,577,245,442,385,545,800,194,997,128,622,652,561,955,169,175,980,277,467,186,513,28,985,960,96,111,566,364,773,307,215,131,810,830,572,327,526,20,204,145,459,920,22,966,738,943,766,470,149,370,560,918,393,136,109,49,621,233,334,69,787,128,573,347,104,450,284,166,85,634,17,11,582,637,295,715,457,307,941,218,233,361,154,631,165,243,823,181,35,656,65,979,948,561,531,801,453,558,463,359,575,692,338,928,216,669,921,127,555,399,365,313,396,742,157,237,718,613,238,76,249,783,223,103,81,175,130,367,729,886,543,384,833,51,941,320,349,638,333,914,482,784,848,837,883,787,344,69,86,459,892,234,965,260,61,245,559,686,151,670,184,644,436,800,822,307,354,743,970,145,233,144,316,759,326,208,495,196,413,589,529,496,471,307,28,497,515,437,779,405,346,910,511,391,875,191,998,601,454,339,372,60,525,896,160,478,110,388,33,739,777,428,538,77,393,714,269,498,649,890,976,615,844,234,715,115,385,439,159,856,276,156,797,943,361,486,843,445,243,664,465,194,795,60,610,985,173,307,812,63,905,597,443,783,165,733,897,423,660,725,261,479,409,410,537,782,801,496,314,925,950,653,26,562,154,894,75,108,974,148,832,55,410,864,628,217,110,415,124,133,10,606,824,759,860,290,551,801", "661,598,953,982,434,522,726,713,236,498,656,136,47,356,893,864,892,688,867,366,923,341,71,275,753,663,993,493,824,276,941,517,268,911,832,801,465,345,217,890,745,58,646,237,331,363,600,542,613,4,540,831,709,290,915,978,936,991,412,344,65,181,444,484,792,38,439,195,236,548,219,79,238,72,564,745,94,25,791,950,213,881,545,619,370,808,444,851,354,997,905,209,235,63,142,982,230,997,763,894,998,616,930,451,444,480,483,280,677,277,61,846,219,110,203,126,886,514,808,830,661,957,895,648,316,423,884,751,741,424,150,425,1000,181,555,124,7,495,803,704,945,391,571,488,294,487,466,416,741,163,145,861,736,635,746,718,653,73,24,989,864,561,698,452,607,85,243,422,783,202,975,771,783,246,653,555,931,187,59,84,337,928,922,468,7,405,920,99,391,663,48,54,928,690,728,533,693,232,548,102,652,617,831,68,735,207,62,791,145,876,796,448,996,668,624,613,71,325,438,5,232,505,417,702,40,578,579,659,452,427,745,745,53,965,138,283,888,578,134,0,144,180,22,805,671,861,413,634,238,523,184,688,977,168,283,81,3,487,657,208,82,167,621,760,890,486,508,139,165,601,655,430,149,491,500,47,729,319,719,488,474,73,892,992,371,217,496,244,909,802,208,683,17,981,932,333,14,38,301,247,325,282,170,675,215,282,280,584,966,775,235,178,676,478,607,350,258,485,618,520,743,230,210,900,224,452,531,771,587,861,186,213,437,441,156,423,800,463,225,30,805,217,596,22,391,258,892,482,231,420,542,96,95,54,690,228,274,610,62,899,891,495,226,508,42,646,629,222,557,949,262,210,842,731,246,225,686,136,570,135,194,679,663,751,155,118,159,637,818,685,312,191,185,968,56,623,73,900,910,400,36,405,272,471,295,679,899,586,932,744,133,410,506,842,179,209,662,295,484,665,238,382,972,90,48,812,661,237,124,861,430,560,365,853,205,356,765,418,407,183,534,472,783,481,586,309,150,227,670,760,891,51,474,153,11,64,477,102,440,559,704,782,670,84,380,863,916,796,627,396,61,943,160,865,557,369,590,74,430,975,108,530,409,575,792,623,994,405,297,464,292,375,2,922,31,742,830,23,710,785,673,610,603,708,936,238,354,517,608,962,800,874,685,526,270,239,165,616,537,46,195,466,243,707,104,123,208,605,324,948,28,493,225,370,382,398,95,81,80,313,361,797,236,677,904,519,828,484,66,957,718,612,501,726,714,369,39,654,71,449,745,878,19,892,910,957,490,575,580,506,195,283,773,814,397,159,582,434,690,864,548,594,465,382,177,180,91,184,805,670,217,25,546,783,228,350,591,161,406,885,134,707,209,607,207,88,382,534,246,348,803,795,109,603,946,585,250,813,845,486,927,129,667,240,378,909,721,511,706,152,146,373,630,334,628,299,963,197,266,159,845,98,553,916,403,944,353,844,39,566,284,839,18,391,265,959,830,37,305,27,497,421,836,6,466,624,149,392,906,21,922,130,839,290,991,529,624,127,354,123,808,178,167,583,834,732,860,922,6,53,254,956,593,191,981,143,581,908,735,112,264,666,475,11,657,652,613,207,629,389,656,769,548,734,497,95,492,413,452,582,986,217,376,908,562,545,283,912,371,431,270,889,611,656,377,250,54,28,499,126,448,146,91,212,368,57,309,602,387,218,544,527,933,123,972,457,141,663,394,584,659,494,801,534,108,846,370,869,573,449,914,884,291,346,250,435,893,975,240,499,216,137,318,548,605,452,846,448,818,460,932,274,862,905,110,245,775,416,439,794,966,655,641,157,977,63,333,598,396,871,717,50,804,693,451,213,175,111,634,126,128,386,586,924,566,922,593,623,32,407,895,648,248,634,19,443,395,738,71,892,972,944,351,513,588,125,473,166,295,450,610,21,79,26,335,215,191,887,497,535,527,652,685,908,38,540,257,306,435,984,721,882,250,59,344,865,510,659,339,863,110,41,42,49,485,937,368,189,534,743,897,33,836,275,435,940,990,69,410,544,271,488,509,693,314,2,60,885,640,477,197,852,431,21,575,363,696,257,593,79,407,770,181,338,125,152,842,992,483,708,578,626,874,762,85,763,962,880,683,419,723,961,241,781,726,196,793,701,399,49,894,671,731,68,60,640,569,855,700,855,597,995,924,725,560,275,118,951,299,330,660,242,517,859,572,758,105,597,565,126,241,544,337,803,919,797,861,132,682,355,548,48,842,161,183,485,514,535,321,167", "375,712,154,572,493,148,788,4,39,64,487,920,642,912,233,879,770,796,207,284,217,472,431,976,597,611,102,544,384,141,660,489,932,601,943,823,853,42,511,359,798,561,172,298,672,119,237,982,176,445,823,777,514,3,726,606,187,586,770,512,885,848,24,707,954,291,786,264,301,245,335,448,365,90,490,583,268,349,830,473,877,528,552,114,366,47,967,686,298,168,767,702,865,225,135,24,851,93,777,729,419,884,898,362,131,211,357,621,252,902,695,140,623,458,481,503,29,577,609,845,471,693,200,954,786,814,954,635,844,512,833,63,124,979,929,637,333,463,400,301,605,178,771,697,96,661,517,521,914,555,452,378,197,170,666,773,144,827,235,55,869,6,37,111,250,416,137,517,27,641,181,541,994,529,809,734,604,373,169,651,169,610,98,969,396,219,36,636,617,192,895,822,685,346,990,813,540,119,337,617,250,379,942,717,706,824,828,285,69,771,554,674,305,88,968,433,202,231,639,987,475,430,772,308,751,746,965,932,700,545,849,730,801,573,681,718,488,14,366,144,0,84,863,965,871,786,401,473,56,340,416,173,70,175,524,650,509,23,680,20,883,283,549,314,30,238,357,123,9,842,584,52,562,907,681,697,836,581,568,60,849,996,100,813,980,854,233,268,235,328,125,238,867,194,599,388,177,931,18,93,796,34,522,29,93,122,503,573,90,236,674,760,475,486,965,510,313,287,535,167,640,451,529,982,491,244,143,960,438,939,919,801,317,564,895,960,940,985,124,997,349,184,565,476,274,889,572,744,911,219,681,682,307,175,247,903,875,394,63,236,273,686,678,417,911,676,869,171,368,11,447,901,843,710,640,334,441,421,846,620,626,786,388,451,910,265,562,206,169,330,781,62,798,340,235,994,140,953,881,777,75,902,80,877,51,399,648,884,28,998,970,43,10,158,350,119,835,847,499,947,589,895,43,676,582,654,124,660,585,505,708,171,909,650,139,231,832,338,835,99,864,798,143,595,893,686,930,657,562,758,964,32,605,452,951,471,725,282,725,265,666,9,545,509,826,866,631,502,359,543,63,947,426,207,140,579,869,412,253,787,588,970,391,100,315,799,409,330,719,294,741,514,97,81,353,167,594,642,436,263,845,921,406,349,775,849,584,710,22,876,583,681,952,779,526,178,856,362,425,700,576,822,219,387,576,256,326,699,56,704,725,736,490,892,617,265,777,306,770,89,950,466,578,249,876,189,396,93,98,826,98,135,82,107,441,159,563,307,456,776,71,52,272,585,444,602,233,223,122,920,373,874,886,65,327,712,255,345,640,782,241,17,152,663,957,246,112,622,530,618,317,650,65,550,929,109,276,897,932,777,770,700,118,648,102,294,812,579,148,655,708,756,177,397,973,920,13,108,61,797,865,870,178,61,671,100,755,321,72,168,568,572,236,446,528,115,383,989,582,564,671,61,721,154,505,189,357,212,334,659,131,245,201,690,36,498,724,691,917,139,734,75,829,386,667,896,198,606,330,375,306,164,857,42,2,834,998,36,466,409,210,926,903,543,653,493,245,929,992,130,737,449,776,451,251,846,209,595,356,113,887,930,686,59,243,315,570,442,680,826,959,137,405,641,427,320,634,898,73,598,726,456,959,115,250,608,490,19,928,383,595,668,137,175,198,726,159,984,779,127,852,371,186,660,376,287,774,216,873,406,352,288,938,196,692,274,850,824,264,52,130,97,852,387,256,940,544,697,465,882,438,551,457,685,491,720,279,486,80,913,730,86,602,133,688,296,87,782,792,607,633,557,909,847,384,998,354,58,485,616,464,731,68,778,808,98,649,433,401,734,945,229,673,356,631,210,743,774,870,395,58,229,690,964,920,269,437,407,392,617,651,343,779,892,758,48,610,546,461,977,773,974,586,288,176,426,270,890,403,380,350,638,317,698,49,524,689,622,522,799,462,422,80,375,532,415,883,653,957,599,593,671,534,679,101,424,580,596,78,482,363,321,156,812,228,148,207,333,200,927,363,984,503,604,22,451,406,642,250,333,600,457,372,98,884,475,925,214,382,458,784,772,926,831,422,535,85,424,569,536,33,19,590,845,77,575,882,989,893,114,885,775,940,110,722,593,269,479,634,599,247,529,352,746,486,214,198,233,433,286,924,80,659,513,872,451,367,604,730,251,954,657,618,444,646,476,525,658,428,30,12,655,938,32,466,531,309,102,376,104,348,277,632,477,854,869,653,644,776,962,853,737,124,505,63,71,395,687,637,366", "941,29,656,675,332,569,349,265,358,112,158,70,203,827,930,374,693,70,650,118,784,993,759,432,557,381,885,768,966,377,109,332,303,722,281,969,24,884,149,658,892,790,696,202,470,937,803,566,893,477,844,447,405,660,42,812,880,835,860,724,763,957,325,553,971,333,89,896,171,595,916,713,914,524,9,352,314,345,180,473,320,770,687,129,992,5,919,345,181,427,235,216,842,261,575,137,381,892,938,875,752,613,127,918,473,303,708,117,86,301,413,454,438,37,739,174,156,267,966,579,176,333,68,921,982,298,430,115,845,247,804,217,841,352,290,496,241,591,749,392,353,772,641,838,786,396,478,390,508,687,404,502,958,337,540,984,949,850,407,828,74,439,91,35,21,876,890,307,499,416,255,873,160,775,374,650,367,525,212,236,355,440,52,967,692,410,654,266,865,902,911,176,537,548,269,697,100,294,589,131,717,212,270,215,158,967,795,576,925,203,619,678,366,659,242,810,554,763,686,623,778,266,33,186,887,530,139,231,407,660,766,239,579,778,223,955,69,257,741,180,84,0,58,952,424,534,493,747,463,699,431,247,888,286,972,916,182,49,1000,651,401,225,606,360,289,472,365,575,366,376,423,71,777,62,738,430,553,93,387,150,201,336,85,938,125,582,561,939,885,573,325,836,857,82,231,914,546,684,11,12,479,672,243,877,100,525,794,353,151,666,799,402,328,8,931,692,289,7,309,643,112,716,934,446,741,55,360,965,211,433,89,87,434,107,960,540,915,401,664,240,482,959,196,467,180,696,702,579,52,596,284,508,176,436,770,270,537,519,237,110,675,945,724,429,12,789,312,435,923,497,94,908,355,676,379,260,246,629,214,752,688,578,315,376,455,105,699,645,390,654,463,436,659,359,472,284,848,726,705,177,416,110,102,890,629,359,629,543,852,578,204,105,333,378,525,992,159,505,980,925,245,409,454,348,877,857,157,949,295,264,909,767,386,471,953,958,7,719,902,466,126,220,498,69,941,613,471,581,576,616,897,960,925,493,648,796,44,74,822,933,834,565,65,342,615,119,460,766,552,384,617,971,49,133,477,961,615,583,221,473,69,936,272,827,973,797,614,83,637,95,622,261,328,556,210,775,253,888,723,540,221,853,333,950,705,305,994,684,815,845,371,18,622,404,461,956,355,662,538,655,109,80,641,112,974,438,812,53,262,525,635,177,2,589,359,781,543,537,70,41,352,176,347,232,942,587,120,230,256,808,929,310,705,731,820,47,257,501,594,607,694,664,559,960,152,914,717,189,293,401,447,6,613,790,271,221,461,761,785,380,306,231,777,456,887,984,902,462,986,556,975,346,875,966,490,262,438,17,470,502,659,21,141,715,457,318,326,565,651,403,735,518,31,399,466,351,881,40,416,354,147,711,550,903,788,538,403,603,106,66,575,558,421,416,262,298,488,667,244,158,152,625,194,580,595,681,259,337,255,488,987,20,822,186,329,525,474,264,49,44,370,380,275,544,499,255,577,559,621,977,788,245,278,698,867,630,81,735,127,812,183,883,304,235,241,638,252,497,810,772,467,702,26,678,173,417,724,720,658,218,315,948,924,158,772,521,914,187,942,43,907,147,319,252,48,119,170,525,101,355,39,132,694,649,779,156,233,193,568,110,822,607,115,109,998,959,429,986,378,529,193,485,93,703,13,375,591,889,485,639,265,2,10,233,97,211,89,317,634,184,771,231,376,140,911,571,770,355,553,384,623,201,87,74,218,765,674,474,300,184,663,26,764,566,526,69,115,422,766,554,5,187,15,233,344,283,546,35,244,303,379,916,465,742,244,96,539,702,109,473,442,145,266,2,930,966,947,70,164,70,56,267,3,865,48,537,505,763,112,484,623,844,13,675,89,813,998,538,394,974,355,166,394,520,316,274,831,576,167,231,684,120,247,139,545,124,781,172,333,179,193,725,639,246,818,476,256,849,740,433,190,832,721,137,200,768,18,684,934,923,258,884,817,192,64,759,398,437,924,544,975,56,550,307,526,968,159,194,646,922,343,629,469,264,219,439,784,819,803,302,258,883,318,343,277,369,246,76,943,904,38,393,800,758,826,134,405,591,585,559,687,326,953,527,377,467,249,523,821,438,582,222,503,300,292,980,458,158,338,62,757,589,401,821,1,10,113,350,196,619,550,40,663,287,371,712,644,397,366,629,730,582,131,198,304,611,950,756,884,671,43,230,341,185,558,433,597,981,449,576,857,738,194,161,878,572,264,480,504,878", "487,191,121,525,536,995,169,870,579,157,191,917,113,438,42,159,848,910,268,126,914,371,156,472,985,394,908,619,477,225,676,301,727,542,518,666,623,1,64,974,289,423,572,941,510,484,558,611,745,536,862,825,66,642,392,319,168,800,543,78,419,894,969,554,779,818,297,802,614,516,546,116,160,234,284,560,34,249,840,547,142,736,203,407,432,637,240,42,533,717,226,433,215,307,391,797,376,317,878,782,911,998,586,583,253,712,497,820,918,511,637,311,578,105,503,604,123,143,978,120,775,423,347,379,142,115,868,822,163,642,556,260,668,106,631,914,38,629,881,292,209,144,102,497,713,489,21,708,737,995,991,686,171,610,829,99,716,135,851,5,862,190,325,913,786,142,731,512,777,259,461,89,484,727,361,44,448,984,935,516,651,488,763,166,732,308,29,828,614,949,837,613,242,464,354,439,79,647,784,61,930,862,678,899,164,379,918,481,271,394,171,50,976,748,692,595,557,969,40,603,388,417,806,453,781,678,670,267,619,660,486,493,238,43,977,864,750,582,749,22,863,58,0,575,502,372,103,386,511,440,806,122,343,301,498,706,798,902,730,452,72,271,996,876,157,760,833,472,23,905,430,829,760,578,618,934,249,768,789,570,846,477,233,505,816,133,140,298,662,26,833,684,755,111,239,896,662,657,144,201,593,235,564,509,507,556,630,297,189,504,200,881,442,456,328,791,8,651,166,60,282,938,39,142,364,871,33,539,260,624,332,700,734,590,102,842,702,818,220,292,341,829,382,427,37,339,280,335,616,468,518,292,739,327,459,654,749,491,244,309,160,877,430,67,101,246,217,913,352,22,428,3,210,173,753,459,17,302,127,751,54,953,568,742,899,685,783,260,567,945,296,211,441,782,649,586,269,259,522,627,209,242,639,697,165,966,459,646,551,613,952,539,957,452,990,400,18,368,392,368,465,164,109,265,761,573,727,921,498,605,834,994,552,422,867,609,943,977,66,345,258,607,281,13,447,309,546,487,344,27,440,584,630,171,94,222,859,568,917,550,154,547,739,19,203,250,718,902,966,53,552,633,365,913,839,27,820,371,747,983,314,82,626,126,452,408,257,523,713,749,516,460,538,824,297,367,90,825,315,209,304,431,626,950,62,348,867,550,737,759,222,715,88,376,69,664,979,262,781,777,246,876,56,142,540,290,902,427,803,531,554,3,621,766,401,502,700,308,995,921,742,148,662,718,880,311,700,605,226,648,795,775,546,195,709,190,907,183,841,155,993,985,336,260,243,461,968,954,305,244,145,31,511,668,158,384,880,545,858,803,336,660,127,786,591,491,731,543,78,534,905,532,84,390,307,662,145,572,444,872,9,392,374,652,866,86,346,313,380,622,22,501,590,595,431,885,790,72,969,120,936,765,652,147,75,936,428,173,764,899,98,759,507,437,797,417,894,796,325,251,49,743,365,656,422,110,756,12,355,947,795,328,277,378,213,777,514,332,459,353,609,512,135,817,174,703,610,477,31,31,204,795,566,830,491,336,10,236,430,671,820,909,545,399,131,622,610,436,354,182,732,445,133,549,24,436,908,438,928,615,932,94,983,488,272,472,456,359,308,104,449,738,283,91,333,226,809,565,386,576,817,883,789,775,973,999,935,948,338,893,221,991,527,507,316,222,617,421,829,519,985,516,20,692,403,180,770,553,508,716,508,989,327,153,877,349,362,755,605,516,488,201,786,614,835,208,427,856,688,360,563,70,81,969,705,493,687,155,170,390,548,387,811,502,193,243,664,286,349,944,232,471,648,764,715,130,54,375,336,689,758,554,100,750,532,151,179,884,315,390,271,491,772,889,282,285,412,253,415,421,377,366,75,918,949,967,819,733,46,382,491,321,453,218,98,112,416,566,571,130,687,895,127,266,439,839,964,595,258,261,876,628,733,679,77,195,82,387,943,635,203,131,832,154,603,461,138,786,126,98,878,729,141,126,422,138,264,857,542,19,205,545,15,835,514,285,533,82,359,405,259,290,204,164,583,712,86,966,221,726,228,338,679,982,947,502,604,385,829,454,56,855,732,808,943,254,396,977,956,930,387,797,941,381,192,892,91,541,300,5,249,464,672,537,753,323,29,366,128,779,91,119,573,402,492,205,788,212,107,883,667,757,530,149,783,508,126,459,879,193,686,863,819,427,157,476,214,740,726,792,560,820,408,407,680,705,66,673,162,197,524,560,84,394,169,158,935,777,89,60,252,754,590,638,586,325,606,7,172,369", "58,650,543,801,989,386,870,415,427,333,280,712,199,785,306,429,362,357,340,721,516,12,604,972,61,875,184,755,630,911,609,291,851,256,129,255,646,331,674,842,862,855,108,215,396,974,395,466,410,686,844,961,737,958,241,308,371,152,209,639,660,561,230,457,759,158,502,257,845,963,748,400,427,262,197,510,230,826,537,763,920,920,937,390,810,715,190,398,566,110,639,276,479,487,548,114,664,251,120,835,244,580,345,336,914,753,417,556,238,269,554,384,355,536,267,257,148,765,530,448,952,209,164,818,162,181,237,915,123,277,851,838,586,512,259,84,896,602,982,306,549,210,174,127,765,836,177,916,642,139,939,616,475,684,39,640,456,890,884,63,333,654,314,918,338,489,327,778,951,668,775,154,430,180,754,674,230,745,628,722,826,999,108,428,686,135,775,971,93,281,280,690,700,532,375,480,335,13,505,936,214,29,736,420,760,845,822,636,581,630,181,446,706,559,791,719,992,813,327,854,546,576,72,492,191,198,312,26,947,148,237,933,433,179,56,663,445,40,164,805,965,952,575,0,84,980,269,762,969,736,845,667,632,740,989,569,925,674,465,772,803,861,293,169,68,407,132,958,979,819,85,609,814,673,373,445,497,66,621,180,741,150,851,650,832,179,187,810,411,936,289,858,870,466,829,266,496,328,193,633,251,284,831,183,554,44,150,66,178,441,273,120,452,879,362,82,766,882,345,135,798,747,940,186,357,739,635,328,903,277,934,92,36,43,281,517,590,576,234,496,256,587,887,800,899,549,944,913,428,856,380,720,930,819,584,917,624,46,289,220,856,70,391,454,554,172,853,916,86,491,843,422,797,188,819,772,803,131,476,167,568,887,69,651,551,696,303,664,535,811,727,375,314,446,741,245,806,391,315,801,980,254,612,678,640,346,834,810,461,713,949,183,216,180,726,500,409,732,151,835,575,287,551,461,190,412,258,344,78,56,639,108,317,607,200,57,768,133,274,24,556,166,842,895,857,892,521,596,485,476,991,799,186,606,38,780,426,557,521,354,836,444,677,988,436,150,887,884,697,21,320,30,824,5,985,199,379,29,95,480,161,505,374,670,925,957,337,409,329,307,450,951,161,572,887,712,843,1,633,979,217,980,598,333,228,248,547,14,565,865,719,391,223,34,812,203,515,619,549,369,746,476,332,759,243,73,323,642,872,182,88,986,497,726,645,574,42,591,781,902,589,619,755,1,331,223,908,671,823,635,445,44,813,799,523,395,78,943,787,119,946,347,936,29,708,870,160,37,232,718,206,710,41,913,142,408,998,844,846,355,87,309,922,899,87,460,67,13,823,119,52,909,623,68,85,583,172,565,776,497,235,776,233,748,55,63,729,563,330,556,218,515,24,793,784,416,950,833,417,710,729,893,773,151,959,600,809,737,54,965,447,91,574,370,496,152,322,328,659,362,287,488,193,274,53,904,815,672,302,369,371,707,855,892,45,850,225,685,793,926,834,681,232,335,915,423,847,145,278,989,117,835,2,81,998,889,489,82,772,39,356,530,200,606,600,134,212,894,143,582,664,404,322,141,607,418,555,944,14,358,675,28,260,638,617,323,928,171,734,3,950,827,355,356,414,584,5,370,452,902,748,571,968,297,770,475,307,635,762,989,219,262,300,827,829,237,940,950,886,671,3,77,312,599,3,312,136,583,459,947,794,762,962,159,110,165,413,356,270,527,903,919,65,705,519,171,727,363,823,811,566,831,273,926,803,845,226,957,992,495,270,638,66,659,834,95,17,691,124,248,4,555,88,115,224,556,803,865,68,585,193,651,766,380,572,824,1000,144,653,621,463,367,614,808,299,801,929,697,322,71,148,369,760,540,396,926,324,154,286,697,316,452,367,585,965,134,864,122,428,62,53,702,953,780,726,292,786,575,263,352,704,94,919,505,938,429,186,558,8,737,853,545,159,240,175,71,112,732,332,416,97,754,761,805,829,440,160,769,171,930,15,746,799,286,248,839,244,518,457,351,19,238,954,745,426,309,254,571,680,442,994,362,785,476,860,299,798,137,810,187,388,829,663,325,489,248,566,372,929,160,76,504,478,677,273,421,297,201,410,523,67,93,544,596,95,843,111,421,456,164,747,66,114,374,947,475,854,175,113,662,956,595,793,21,517,621,366,759,237,937,703,324,169,823,647,716,832,874,714,532,110,55,400,633,305,171,704,94,262,529,173,513,448,433,754,16,627,608,866,767,718,669,609,17,991,341,260,588,716,792", "890,287,160,546,647,382,783,442,377,211,797,603,514,49,780,730,535,685,942,741,712,636,537,812,60,119,688,299,958,804,187,340,891,423,707,978,481,944,959,33,659,127,177,422,269,572,736,716,886,14,498,978,522,280,934,163,89,346,185,170,373,253,853,860,331,201,375,955,679,362,963,624,267,604,806,511,318,408,587,840,643,65,238,288,133,730,677,134,366,99,381,330,13,953,470,279,935,236,328,392,668,111,178,486,902,830,145,365,505,375,443,694,269,936,80,314,840,741,184,746,142,385,947,846,41,804,254,791,662,341,202,925,10,264,935,143,146,544,887,68,576,907,757,233,722,951,502,194,396,897,50,507,729,758,716,777,496,432,111,39,668,241,230,875,530,878,7,743,826,162,549,649,40,760,210,768,646,680,521,771,77,192,883,747,96,149,705,605,51,473,195,966,651,709,396,679,660,985,252,994,348,42,849,555,144,86,585,219,344,911,56,479,65,657,698,33,131,552,795,62,242,528,860,326,17,588,777,877,307,885,399,711,344,634,967,996,988,696,507,671,871,424,502,84,0,514,180,485,437,259,232,106,789,503,148,245,334,288,640,298,762,874,775,900,484,530,690,780,26,411,951,676,432,406,670,653,930,314,449,922,453,877,212,182,478,537,595,240,944,910,73,336,353,514,541,113,187,463,590,30,129,227,819,695,409,794,389,137,222,897,434,442,257,160,511,455,426,768,659,615,430,539,255,262,906,278,111,229,710,309,295,769,466,946,403,366,654,1000,313,156,511,419,214,964,457,687,687,119,993,754,469,355,908,399,86,875,490,673,447,147,949,801,317,374,668,469,809,143,487,241,595,609,476,246,860,955,582,675,500,328,632,107,970,948,271,371,178,451,238,375,573,681,145,839,666,648,691,909,968,27,883,875,717,453,374,921,855,606,896,590,878,407,58,371,306,638,730,953,373,775,885,963,541,3,625,167,64,96,585,399,966,119,132,206,934,609,831,952,734,92,28,697,473,914,473,406,606,107,771,771,822,595,70,349,886,861,121,681,193,273,56,980,363,411,217,320,48,57,338,728,219,550,892,854,535,764,903,63,172,673,82,590,747,67,935,91,183,916,841,246,129,541,506,11,505,993,416,512,644,60,974,733,279,97,511,986,848,621,422,451,190,807,61,674,485,108,415,269,346,743,785,911,243,784,656,753,723,52,442,919,93,512,3,49,500,668,179,344,966,902,662,840,820,779,506,119,484,731,349,728,575,528,834,806,1,940,840,631,274,547,168,182,935,561,987,369,708,632,883,75,659,735,481,727,667,854,320,509,597,909,455,246,781,950,182,516,252,688,324,556,292,799,304,146,188,78,898,420,290,280,313,882,579,186,815,361,597,556,635,120,886,9,222,755,419,434,244,169,168,957,734,166,719,951,896,819,251,937,904,924,626,809,388,234,170,756,185,433,121,93,419,372,470,888,65,65,390,814,514,566,779,128,927,720,173,859,351,702,191,47,495,190,589,175,931,407,200,348,600,693,544,441,161,899,450,696,496,558,874,889,799,34,586,248,349,143,996,637,159,698,326,104,822,854,65,122,986,707,530,656,427,387,10,741,580,609,312,614,530,909,420,192,538,890,153,714,864,10,426,726,608,221,585,290,740,678,420,647,796,148,342,940,124,662,833,310,794,223,187,701,263,905,208,535,810,299,889,370,867,668,354,467,741,765,3,555,284,109,436,86,439,435,794,420,833,940,55,613,184,188,994,172,3,987,637,92,927,857,744,658,181,525,816,816,251,259,155,279,477,849,905,882,624,446,713,142,279,49,446,4,179,70,603,317,21,20,633,361,767,748,108,991,274,327,834,731,489,358,583,618,845,122,433,46,851,879,344,302,903,463,279,497,805,90,814,778,30,174,207,219,973,780,542,818,531,694,582,901,972,276,808,670,700,248,665,786,878,822,189,671,367,311,592,957,853,548,380,826,988,563,232,710,946,724,560,383,600,606,25,880,660,669,82,853,848,735,544,669,76,139,970,785,633,631,874,322,723,603,87,286,112,945,511,579,134,464,80,577,359,34,264,602,17,641,677,378,678,44,832,694,166,827,570,777,663,852,278,66,209,275,805,200,425,24,612,579,466,698,453,541,866,582,585,99,360,984,832,537,926,152,706,234,62,413,559,64,449,420,500,56,657,842,374,715,859,823,720,24,281,408,830,364,534,241,335,60,208,471,600,193,232,669,954,940,814,343,530,603,324,40,610,48,318,295,831,624,416,510,111,451", "700,301,848,827,96,119,324,696,734,631,416,907,789,268,455,78,674,665,455,663,322,621,557,483,184,517,615,299,57,568,217,474,422,259,744,347,191,318,934,910,244,717,557,883,717,548,861,348,589,709,532,88,247,73,907,774,89,276,116,540,769,119,747,981,24,658,534,378,790,742,464,247,38,490,737,589,246,176,421,228,237,265,715,611,524,347,775,80,333,12,188,765,72,414,767,628,749,294,665,124,105,589,27,159,710,776,205,692,63,417,956,357,459,981,157,34,132,240,647,928,597,375,379,206,258,149,43,984,448,116,709,923,282,706,998,542,504,190,280,405,772,254,90,464,977,115,870,106,945,146,144,356,43,382,136,614,811,19,468,594,908,646,956,795,276,752,397,148,848,377,694,345,9,958,876,145,980,509,710,824,430,639,819,303,963,389,283,204,454,492,664,542,469,7,376,685,439,785,702,376,338,823,419,197,649,312,257,142,884,376,540,731,82,209,660,7,285,969,939,430,606,304,154,721,703,349,985,83,662,966,786,963,854,594,747,32,902,14,209,861,786,534,372,980,514,0,610,322,827,802,249,60,206,680,738,418,151,469,571,11,564,219,622,604,906,34,871,935,366,831,157,325,574,181,952,951,241,675,489,901,368,947,609,54,530,596,407,376,279,481,876,562,906,355,21,92,134,303,600,759,365,734,16,672,982,133,176,954,77,392,41,921,273,819,653,764,638,814,626,308,74,723,64,414,20,674,515,481,488,825,910,763,745,535,915,398,211,725,394,21,5,125,757,970,705,815,208,904,692,48,225,208,467,247,917,422,236,655,582,646,870,606,707,381,519,216,459,695,978,710,433,479,978,454,432,394,281,600,4,386,366,590,154,195,607,779,91,993,94,957,579,989,831,36,460,615,886,676,810,90,892,342,636,697,472,866,673,194,251,739,352,949,69,187,111,573,308,138,492,559,39,866,713,637,274,377,61,754,46,558,373,981,413,655,330,523,446,825,33,345,930,664,76,916,115,863,696,262,234,948,646,549,666,376,387,287,190,970,724,627,36,72,388,604,57,19,8,401,613,317,77,917,622,42,837,632,649,466,335,112,99,282,1000,117,621,700,299,431,844,93,527,827,939,41,846,468,822,745,4,465,815,127,178,506,365,978,288,280,879,922,445,515,476,622,945,695,632,98,259,52,48,875,838,267,632,786,955,899,459,123,676,767,4,743,900,258,208,216,714,433,334,956,311,674,726,630,275,338,312,164,59,576,262,57,936,613,774,560,285,803,636,332,856,517,8,848,724,565,679,645,689,127,316,63,577,60,267,734,830,512,831,860,146,47,439,914,566,548,552,959,533,490,407,926,409,6,202,932,649,308,676,200,707,533,709,573,354,118,987,348,981,454,754,556,194,849,70,185,709,878,31,119,472,600,238,869,370,113,875,89,948,852,290,369,364,276,934,980,100,861,542,9,38,301,637,119,486,965,766,539,312,91,656,463,483,971,72,464,583,733,364,408,111,57,254,183,117,352,200,451,281,806,455,4,37,407,215,153,854,761,79,666,377,337,697,10,503,87,737,683,175,557,695,743,751,97,483,897,140,644,340,70,291,160,720,895,516,985,945,698,593,254,471,383,927,939,409,788,46,448,728,289,262,227,112,302,951,542,827,493,320,116,845,285,231,422,412,273,166,64,995,663,378,90,442,437,131,209,345,76,879,196,637,251,47,608,815,643,177,923,466,365,250,164,322,997,157,655,101,696,891,523,623,704,701,144,752,247,988,245,91,245,62,712,787,334,638,922,763,959,741,204,261,103,623,31,373,27,328,536,140,395,200,60,388,253,356,671,46,960,345,641,589,397,865,264,627,399,624,695,119,568,882,943,947,999,348,278,727,505,72,288,978,381,8,767,279,279,591,594,498,974,310,379,859,529,929,685,155,520,5,696,444,871,916,489,335,158,338,521,254,321,755,282,607,655,465,775,270,306,614,460,337,405,26,959,56,345,455,255,349,221,990,764,255,273,568,811,950,566,8,767,708,984,302,990,813,359,714,184,207,157,805,656,600,889,316,232,186,67,937,691,991,969,165,885,471,962,350,120,559,357,818,495,748,449,412,49,516,847,208,104,878,997,58,958,800,399,804,601,166,527,402,367,805,914,759,289,920,96,455,965,577,442,215,62,184,620,701,386,585,559,672,274,608,82,441,208,902,545,473,343,313,144,936,994,86,567,347,267,841,433,811,739,803,486,531,244,353,424,11,769,308,106,125,401,184,197,322,561", "121,735,724,99,247,123,281,720,814,751,64,475,31,600,635,782,31,519,325,19,859,985,909,217,783,327,357,833,62,952,796,355,139,140,391,578,343,903,459,526,34,71,317,444,282,895,198,873,86,858,564,952,692,337,739,496,116,314,377,884,768,113,350,452,579,546,722,152,473,726,914,627,912,261,774,967,994,472,327,294,816,68,305,876,20,36,423,230,290,12,961,944,503,715,118,752,891,116,24,628,659,348,912,276,224,174,17,9,122,659,89,338,681,912,435,728,357,123,427,21,885,820,784,469,233,251,150,713,457,24,521,439,582,235,102,448,614,200,337,6,907,744,450,22,258,992,462,379,91,695,500,715,162,367,605,738,336,978,245,718,855,423,795,526,960,127,200,22,161,606,427,892,924,57,265,993,668,165,308,745,663,600,906,223,85,340,510,563,525,174,682,221,154,543,439,291,755,299,28,895,341,553,387,11,907,812,920,120,817,557,354,548,903,505,38,6,205,490,613,203,990,674,821,20,386,334,380,241,90,433,956,92,7,142,895,304,322,172,881,413,401,493,103,269,180,610,0,515,379,601,665,136,929,878,157,401,179,409,99,85,364,369,725,214,180,115,548,846,860,614,992,621,433,966,859,255,211,61,659,952,874,381,568,640,921,96,127,599,656,280,740,925,493,198,83,139,194,719,819,323,563,852,68,579,791,714,996,485,300,25,429,573,505,506,733,416,975,886,375,292,450,439,89,883,820,455,725,53,103,527,494,613,688,670,358,754,352,995,125,506,140,617,420,586,924,629,616,770,275,276,427,144,728,228,604,206,941,593,272,412,967,228,35,573,394,731,798,339,496,997,208,951,185,870,725,830,877,998,618,252,999,9,69,680,533,417,16,192,666,679,710,954,631,143,132,611,718,110,304,412,671,753,140,673,896,777,616,729,167,875,37,428,84,620,444,990,589,271,508,990,618,570,626,278,497,190,420,114,172,642,661,351,838,575,733,200,466,985,959,149,85,842,529,622,672,461,470,58,387,222,548,893,203,919,139,684,901,930,725,398,518,699,649,401,274,185,59,329,770,33,996,556,237,557,31,277,533,585,189,670,398,101,862,815,6,931,406,35,646,621,482,891,429,882,50,102,318,985,999,460,375,151,927,889,802,555,917,18,673,366,915,94,326,690,282,717,96,871,10,21,214,868,240,808,26,279,596,95,278,125,950,255,856,797,916,249,908,697,288,131,977,90,150,566,165,584,196,22,183,867,94,205,371,327,175,706,281,680,673,965,963,184,844,194,787,112,342,191,927,365,170,621,437,924,184,512,374,62,825,949,935,965,286,596,344,404,410,270,755,722,816,476,365,435,561,707,926,295,773,428,245,91,928,452,276,758,128,420,186,196,920,853,341,310,929,495,913,412,559,221,425,455,993,841,601,705,276,690,717,718,202,725,696,277,130,485,865,385,303,141,545,520,122,633,903,842,639,796,468,430,176,963,815,102,512,738,301,400,156,291,100,48,627,673,834,817,111,661,521,615,276,982,809,363,640,1000,216,366,441,280,384,121,394,67,336,137,506,492,874,619,562,818,666,507,900,514,290,628,606,642,811,646,609,218,448,750,185,910,615,706,109,831,979,288,27,513,797,38,562,498,439,376,79,912,725,803,333,984,371,752,339,810,254,631,996,703,767,665,420,456,756,443,911,329,389,81,237,961,11,595,669,808,988,246,858,328,252,711,875,201,78,318,386,589,456,902,345,257,729,300,22,455,643,461,528,401,19,168,836,752,27,892,968,841,183,921,48,720,911,895,823,157,614,315,643,629,504,410,225,309,524,765,657,439,671,688,263,793,66,261,883,89,827,454,679,701,969,470,473,719,273,644,166,226,363,224,727,629,196,765,562,551,973,971,924,67,721,733,833,47,878,559,165,211,151,298,276,106,834,184,101,578,756,844,50,134,895,796,202,110,368,695,382,848,156,270,812,45,628,559,618,820,517,662,44,452,392,79,165,673,738,621,193,932,236,670,212,36,196,547,241,5,88,189,664,490,226,226,332,343,946,172,832,441,177,123,376,547,82,516,677,325,729,903,388,326,447,453,709,963,83,115,843,569,315,296,418,619,552,724,771,821,492,985,956,543,890,223,579,259,116,429,162,222,962,78,633,581,931,16,188,406,597,94,240,396,281,758,620,324,67,95,844,862,643,888,862,359,874,948,654,367,318,460,546,269,790,307,489,5,471,834,872,465,185,376,427,415,177,365,705,734,53,732,914,466,565,999,764,244", "852,765,366,741,695,876,584,732,621,496,286,901,26,613,671,852,193,584,869,32,241,962,379,171,787,416,145,76,87,355,455,541,674,355,927,644,584,757,354,122,127,408,428,173,145,771,477,542,285,624,831,530,265,244,888,945,215,40,703,84,452,105,758,597,251,915,826,551,458,704,871,368,288,944,461,103,187,59,380,131,662,363,338,654,741,183,175,680,448,481,886,68,595,206,195,426,622,882,810,776,371,866,561,907,575,619,877,915,27,391,927,844,127,471,139,614,12,781,6,318,576,310,23,283,468,938,189,469,439,789,639,435,151,238,53,20,378,521,788,545,122,376,313,935,823,442,105,361,637,940,162,983,292,19,246,993,937,843,14,475,198,380,374,127,228,18,569,233,738,573,65,38,487,486,697,287,939,408,576,998,293,836,626,648,104,143,895,801,396,993,720,81,195,989,544,965,828,603,53,868,238,399,662,602,138,278,552,322,765,253,277,556,462,292,823,413,657,348,852,359,168,44,473,264,476,122,105,137,46,768,528,854,429,578,699,459,126,574,257,634,473,747,386,762,485,322,515,0,959,833,845,136,304,805,583,59,47,854,75,693,203,693,462,858,82,509,287,765,322,390,124,977,468,180,50,741,508,621,816,240,917,703,811,956,429,933,818,288,495,572,789,312,2,418,322,887,230,544,539,436,347,888,189,517,174,691,930,840,710,713,186,194,759,707,124,1,307,259,309,150,406,730,455,499,506,793,91,598,654,20,522,163,614,117,47,649,489,127,656,355,326,227,287,396,456,403,415,430,797,924,576,183,224,208,402,900,274,938,631,939,227,942,585,780,791,941,838,227,536,569,828,548,758,413,463,333,955,156,987,186,573,448,644,604,312,470,909,393,459,11,634,998,999,191,973,862,186,301,618,622,60,485,768,979,870,761,21,352,536,374,44,780,577,480,733,912,409,171,604,42,515,180,47,256,469,636,546,358,275,214,670,504,958,488,531,275,162,869,623,665,218,563,408,322,273,582,111,707,999,898,983,571,171,911,548,455,410,192,520,556,93,719,162,592,969,744,925,604,509,266,736,750,405,160,658,63,284,548,485,546,839,55,636,138,43,431,708,657,455,535,999,520,614,15,954,826,488,711,438,89,479,932,2,154,6,690,912,989,599,602,577,33,283,605,806,276,786,390,293,374,61,51,450,668,484,609,457,336,549,816,92,639,815,80,898,366,513,448,378,192,636,280,549,638,69,724,890,892,115,498,819,861,444,980,819,817,339,351,836,659,994,609,410,369,612,763,622,813,151,633,710,294,729,896,229,21,950,328,522,758,461,609,615,590,571,479,567,929,336,206,830,644,111,603,393,151,300,624,979,752,708,392,102,572,566,888,580,894,141,578,499,80,676,846,870,257,319,222,975,523,720,274,34,770,824,3,125,22,447,212,402,330,860,671,927,164,281,795,117,159,101,256,407,608,651,324,12,26,113,557,438,806,961,805,222,346,902,993,837,61,633,756,700,780,277,812,653,21,568,462,740,983,124,333,852,869,101,706,885,509,350,827,481,681,769,317,297,609,479,250,452,57,411,394,30,269,489,184,696,789,106,444,740,943,293,657,672,193,137,130,267,579,181,591,136,606,397,419,609,843,913,871,834,119,174,894,575,980,999,188,754,210,908,978,104,826,541,714,186,685,399,165,783,375,897,95,584,921,772,503,849,83,400,900,885,67,71,309,425,67,144,768,660,841,643,141,406,90,3,873,328,854,268,409,726,225,982,14,511,253,408,138,608,378,840,832,994,827,149,67,794,820,895,620,895,387,341,249,427,342,918,306,920,750,493,15,189,427,96,354,53,890,508,359,607,887,341,341,999,850,233,419,462,887,622,967,922,52,206,622,147,619,239,583,941,522,127,700,484,18,796,452,839,747,152,227,75,222,271,114,289,656,106,311,699,580,621,218,396,736,436,386,267,506,840,501,980,26,299,734,340,168,838,695,656,678,499,359,828,601,343,575,140,868,899,836,537,15,795,978,793,326,418,432,779,920,711,572,246,188,183,67,312,354,322,324,486,877,441,611,114,947,993,860,653,684,365,190,920,277,17,225,936,739,789,725,392,710,759,960,709,516,658,113,768,110,917,268,354,171,342,48,690,906,72,303,280,773,776,293,245,332,755,662,592,11,988,537,345,264,483,448,277,215,934,866,210,504,404,792,9,588,727,237,349,350,838,963,271,207,2,32,581,431,92,514,569,232,292,122,677,887,454,180,720,750,23,185,636,825", "700,117,765,130,888,440,278,153,370,404,23,368,708,827,116,374,605,16,3,475,515,316,949,78,861,460,102,906,274,844,115,59,911,918,489,951,782,249,510,487,545,410,310,456,884,477,843,602,384,656,228,159,633,431,720,715,625,11,702,778,887,498,724,299,713,427,224,448,677,441,381,594,599,13,315,719,752,877,953,451,606,442,480,340,150,231,693,382,590,64,335,598,687,667,564,530,819,641,2,405,690,768,297,721,198,192,743,204,818,7,865,206,21,63,805,812,719,402,136,361,492,770,857,868,300,92,893,72,226,240,866,538,489,69,806,686,953,352,207,803,170,182,65,93,968,717,609,146,684,679,527,1,917,72,386,343,885,953,507,853,325,944,948,447,262,463,580,749,722,87,475,745,633,103,788,886,83,362,903,45,392,283,803,155,228,240,785,824,310,72,750,436,216,925,438,184,485,531,405,264,78,452,582,371,736,940,735,289,988,357,737,572,341,731,681,48,258,983,212,504,951,734,644,473,586,532,898,305,694,902,637,401,891,640,319,857,581,968,112,238,56,463,511,969,437,827,379,959,0,427,33,146,383,567,38,851,99,175,744,540,382,682,675,348,434,807,1000,257,85,313,5,863,941,381,953,840,685,130,42,66,384,568,128,971,513,191,451,562,352,251,840,498,433,473,770,482,966,212,485,627,596,902,997,624,649,402,903,6,28,862,174,544,188,498,237,305,144,456,739,66,955,456,344,816,895,14,911,17,641,746,608,982,140,926,235,400,275,580,301,682,123,156,759,47,481,755,453,496,177,985,472,93,868,352,354,308,387,2,780,223,974,154,472,808,961,683,756,311,785,217,693,615,143,850,28,944,110,473,240,667,249,823,83,436,764,452,897,770,819,567,792,264,865,847,356,811,728,70,469,534,891,132,810,911,278,504,887,65,525,653,627,500,548,884,867,61,418,598,142,517,264,44,323,477,281,336,824,531,932,929,345,249,774,313,804,655,131,199,726,798,173,522,185,270,447,967,488,52,191,904,161,75,541,207,646,104,591,615,723,695,784,612,509,398,5,55,589,499,330,658,532,239,980,633,126,449,818,643,301,664,332,577,814,447,112,543,509,955,214,949,393,588,80,223,289,558,415,813,280,695,760,213,370,953,191,447,836,783,181,474,640,142,852,382,770,408,323,983,918,981,356,938,498,89,891,299,949,811,772,861,144,384,401,117,252,206,241,956,853,661,825,515,43,705,592,335,519,651,413,90,161,979,96,937,167,710,918,410,29,754,733,477,187,256,779,422,13,674,194,383,506,82,938,21,753,168,553,755,78,816,341,123,451,618,906,941,482,188,208,721,660,375,946,976,364,493,294,703,730,145,162,807,104,466,803,712,589,97,286,728,259,349,787,62,364,261,261,47,37,87,373,925,152,746,372,525,485,679,580,502,299,976,208,930,323,264,581,986,600,838,806,611,521,57,533,737,237,228,623,611,547,517,613,310,760,487,43,55,971,796,131,288,991,359,939,321,91,832,407,499,614,635,583,751,524,119,779,119,650,570,871,666,907,713,90,37,581,222,108,39,424,888,195,714,270,881,614,481,823,877,413,868,902,411,604,237,520,282,389,53,143,570,855,150,448,900,473,435,880,416,644,643,128,307,17,452,832,3,234,268,638,364,598,718,563,698,24,368,228,887,303,156,349,507,487,523,25,120,200,152,985,791,614,202,147,18,698,55,304,427,508,968,112,243,696,444,181,386,738,330,852,170,115,126,730,434,354,859,960,808,951,206,316,188,404,155,43,117,96,508,59,431,633,320,850,6,9,426,150,631,188,403,394,389,540,903,246,258,430,786,957,368,991,933,927,539,136,171,685,405,998,42,990,743,113,252,697,723,131,455,573,566,777,932,100,694,409,210,674,818,677,997,662,540,108,914,391,825,746,531,610,611,104,683,439,410,610,640,435,561,522,757,855,497,715,4,388,249,89,720,537,156,426,298,395,45,129,409,582,297,603,922,102,540,296,570,371,484,411,27,305,315,387,301,442,179,264,908,365,699,222,239,224,651,186,368,717,535,746,38,631,139,510,162,616,181,756,841,815,504,779,300,998,123,761,586,408,859,184,376,868,86,100,251,190,338,724,30,117,562,767,53,973,502,47,450,469,878,14,713,89,629,837,30,853,955,873,693,906,405,241,361,681,124,356,583,978,22,721,816,364,742,959,185,398,742,467,914,429,712,815,430,689,623,478,844,736,13,277,92,336,404,709,623,860,549,649,731,539,81", "888,501,598,337,276,695,219,578,279,917,26,40,46,643,194,237,18,574,35,4,312,226,444,440,768,766,64,372,550,937,707,974,312,41,711,918,737,797,399,237,346,144,509,828,561,444,470,502,257,28,753,50,504,5,429,468,32,495,403,79,414,262,664,262,321,737,764,594,628,112,203,573,745,20,419,993,812,647,723,424,316,846,116,86,275,759,676,515,287,10,911,763,927,526,656,142,359,515,561,435,186,476,686,564,150,713,61,347,616,508,397,387,327,73,493,218,828,793,866,522,517,851,712,424,326,25,676,269,188,963,556,72,702,702,880,964,685,694,997,352,221,58,660,960,348,927,802,943,468,881,957,997,127,824,924,649,588,479,514,425,181,515,150,303,981,16,159,795,501,824,162,20,732,986,713,261,574,542,106,82,952,291,263,681,720,377,776,799,471,899,464,757,668,660,342,804,883,500,420,641,217,567,585,856,313,421,582,221,285,733,745,768,779,717,372,563,664,958,647,342,473,507,316,663,690,325,268,999,644,975,660,982,736,496,673,235,453,681,803,523,340,699,440,736,259,802,601,833,427,0,252,343,286,849,186,310,234,689,140,797,599,484,667,316,331,246,933,590,590,610,385,979,260,924,245,260,809,175,921,669,838,456,849,766,957,684,304,386,514,936,270,437,813,624,904,1,184,726,405,830,222,703,904,507,798,643,51,654,891,325,114,242,285,189,449,908,548,745,940,545,408,677,988,177,342,912,837,291,671,496,790,9,933,773,789,902,806,859,930,855,185,86,152,428,658,915,861,787,634,438,985,586,375,761,812,746,450,595,711,478,396,180,4,708,278,211,781,338,450,553,870,780,670,396,131,403,364,939,804,751,331,453,530,216,725,292,545,534,263,203,7,49,605,414,67,26,997,961,739,903,189,697,757,916,841,60,530,807,719,999,670,450,884,519,161,756,81,355,60,549,452,144,782,590,191,800,593,720,76,315,507,832,584,402,847,466,249,713,780,540,702,387,442,387,102,492,141,588,884,61,975,345,78,681,430,157,946,939,448,903,917,200,526,762,113,735,110,944,910,277,51,545,419,185,314,782,327,972,161,208,46,642,123,338,821,371,95,148,366,977,885,424,954,498,795,32,805,281,30,962,265,747,388,745,474,701,694,4,492,590,102,445,524,924,193,358,657,883,254,176,798,414,449,989,370,970,920,841,149,700,271,556,681,671,261,390,622,582,602,376,204,173,894,20,133,789,704,169,143,910,448,59,709,742,899,734,600,485,386,123,908,149,945,590,497,176,177,59,966,404,319,814,935,413,248,297,909,810,260,70,141,635,105,667,1,10,456,676,181,657,304,67,519,150,20,381,907,242,312,433,965,792,95,80,532,329,159,104,155,938,654,233,423,724,110,322,975,842,681,667,391,491,355,884,711,240,970,995,880,920,602,761,481,46,908,58,926,322,265,119,762,383,69,770,342,562,739,85,544,849,902,897,883,861,454,424,284,483,327,854,589,488,187,87,146,923,7,816,956,771,940,511,949,254,499,341,455,443,523,3,222,137,692,319,184,316,34,177,807,806,13,443,336,69,910,42,204,684,496,394,537,763,402,663,772,139,854,730,948,535,149,399,226,752,202,554,131,678,896,442,117,733,190,904,27,330,637,683,892,514,411,904,856,94,48,443,828,325,664,397,789,479,790,649,619,600,577,305,298,256,568,884,119,974,60,649,999,380,167,404,701,22,254,956,132,836,285,538,946,291,986,39,827,606,282,17,564,317,953,477,978,76,134,26,474,981,803,661,690,426,357,478,289,191,882,443,708,582,184,720,769,213,940,565,449,432,925,852,441,805,654,599,66,174,372,904,543,164,901,398,198,328,596,71,921,343,194,685,185,792,369,857,950,256,898,94,285,169,398,490,255,918,671,672,936,193,498,301,730,874,81,591,346,736,317,436,280,205,794,197,646,698,271,388,795,558,84,576,338,835,9,635,182,380,602,19,919,671,507,89,591,511,406,649,672,180,685,576,153,375,96,192,580,477,69,351,667,823,167,333,858,990,389,457,589,272,664,465,487,157,137,829,32,973,423,17,387,814,339,40,508,841,815,255,581,308,611,332,490,689,304,6,212,346,918,97,202,225,897,305,703,3,300,281,100,383,663,360,982,453,440,157,843,262,383,322,827,92,919,61,875,714,16,857,934,155,682,448,111,694,642,491,929,658,648,718,981,894,762,476,89,532,664,637,769,526,366,678,487,610,306,662,373,903,158,910,606,210,185,905", "814,324,880,869,684,838,120,286,218,846,751,288,854,647,90,901,604,502,23,193,731,67,113,452,820,296,361,596,963,441,514,164,502,463,761,584,37,847,98,501,116,14,232,248,715,416,255,972,129,661,327,932,386,651,512,335,828,183,387,743,301,223,287,587,972,744,302,422,755,236,698,516,858,609,250,533,46,61,977,284,641,919,385,18,937,911,319,904,650,417,289,248,114,803,661,798,891,540,272,413,453,792,572,313,103,678,747,241,458,228,481,669,155,982,304,187,963,298,107,48,424,409,395,778,208,41,426,740,267,319,616,858,304,474,970,436,104,542,644,489,216,60,500,837,393,647,749,226,800,208,384,667,382,701,763,746,382,879,812,172,908,495,488,618,788,333,481,917,354,530,844,730,796,64,303,671,619,643,282,681,525,10,13,150,55,202,448,912,349,381,292,313,785,425,236,132,647,840,325,865,561,797,371,345,293,196,84,867,928,913,79,136,582,659,916,962,209,740,859,693,939,313,242,882,36,340,695,156,474,823,914,71,841,837,992,304,244,459,764,184,416,431,806,845,232,249,665,845,33,252,0,138,796,155,588,131,724,556,793,351,295,831,210,821,27,398,215,782,96,499,784,131,721,128,410,305,566,157,750,263,30,92,40,228,618,747,188,171,5,160,861,990,311,605,402,391,966,870,575,459,949,260,564,667,513,264,700,523,252,394,495,329,976,489,990,344,445,807,483,505,521,852,818,688,404,466,698,228,17,278,701,456,631,658,575,86,921,827,643,179,867,952,565,682,344,373,910,805,813,488,618,415,742,563,785,487,48,968,345,933,232,743,798,305,928,431,74,274,336,95,574,347,32,40,463,9,858,90,946,869,635,650,888,41,863,49,332,484,243,274,948,278,26,303,365,564,27,720,593,913,176,327,152,334,875,427,905,504,418,264,133,289,596,703,30,923,296,266,198,120,591,982,412,751,369,178,803,63,608,680,510,140,427,852,607,983,741,396,699,164,384,694,915,738,648,539,484,514,735,582,633,713,549,375,330,124,935,684,295,299,583,407,500,642,575,61,152,496,639,423,687,309,317,380,872,128,148,332,498,925,324,27,258,756,716,659,275,417,805,433,608,827,955,616,569,823,690,473,615,187,74,421,963,960,551,645,282,715,372,790,601,859,783,566,100,640,936,590,492,943,676,891,842,955,713,352,358,391,617,842,171,380,137,875,608,436,62,822,106,365,14,828,855,254,335,752,535,440,435,849,547,210,216,894,17,16,19,676,723,560,835,579,927,356,577,576,544,97,850,695,153,541,834,147,577,234,685,354,24,900,414,639,166,648,400,320,883,641,279,231,286,825,670,925,921,732,947,791,454,862,854,997,184,206,763,545,678,644,714,969,625,232,46,305,861,42,112,870,344,726,781,6,62,699,977,352,593,763,350,653,350,489,222,885,951,188,266,828,37,1,518,334,825,17,712,827,599,830,87,454,676,985,814,612,953,222,903,649,221,288,187,591,446,201,506,797,3,699,122,402,599,963,180,539,59,925,197,737,345,816,241,735,966,867,709,286,959,724,619,744,968,559,92,375,953,134,364,220,751,306,998,317,242,282,648,625,323,301,84,939,471,797,346,34,447,436,95,347,191,736,950,558,193,798,733,114,11,820,598,890,301,900,700,411,312,414,448,66,180,97,696,548,493,575,509,238,307,785,692,314,621,644,136,929,844,786,240,164,387,685,439,741,884,429,541,499,417,970,357,62,412,731,820,558,793,293,339,683,653,480,11,709,596,420,508,387,149,898,420,525,433,830,724,573,34,597,955,631,338,753,798,329,348,9,742,573,674,708,361,746,468,817,120,216,327,908,256,141,110,682,149,645,660,742,547,35,603,612,66,584,413,606,268,432,474,712,647,129,262,524,32,428,68,920,589,906,806,189,620,591,82,877,437,327,62,842,789,809,402,207,399,896,875,672,512,430,307,25,778,865,483,980,943,778,363,706,854,624,466,306,367,740,936,866,833,852,434,258,68,628,373,81,157,711,512,556,354,243,618,228,542,528,210,465,194,755,64,911,983,489,214,86,395,104,229,225,231,604,773,548,230,287,42,559,638,631,556,168,729,741,720,155,802,422,550,534,535,773,370,862,920,698,239,5,840,213,506,265,975,769,327,853,317,938,703,908,558,844,432,699,852,238,988,94,656,758,239,203,187,327,317,743,837,833,558,382,630,978,895,866,306,465,913,364,461,190,413,296,639,824,350,688,425,727,826,309,474,2,167,894", "546,264,5,743,916,940,909,636,107,328,700,313,492,267,292,587,928,38,211,288,939,381,117,939,732,287,316,289,993,678,199,991,898,354,698,75,992,74,571,742,761,464,672,750,248,548,945,305,242,59,564,16,81,214,872,353,195,886,845,144,202,787,900,796,583,612,198,753,38,964,161,138,416,126,654,605,414,121,289,427,101,616,306,767,380,195,890,584,545,345,963,839,302,366,587,546,570,18,881,236,782,166,31,810,802,976,643,616,127,712,12,891,295,116,52,163,618,977,593,853,218,102,579,397,893,897,657,611,339,273,835,379,182,923,912,802,111,209,822,330,464,891,875,49,581,604,79,302,974,98,268,99,335,55,822,986,234,928,921,239,361,847,986,67,443,60,201,754,685,282,666,433,512,930,138,649,652,433,484,787,450,913,795,598,519,31,683,423,385,908,410,288,340,82,462,348,457,614,545,815,116,950,963,375,478,547,308,913,129,381,873,878,496,991,831,333,111,850,82,773,611,146,767,778,570,724,627,407,149,801,318,711,996,687,217,416,236,564,759,688,173,247,122,667,106,60,136,136,146,343,138,0,375,145,248,372,887,401,463,791,409,194,289,200,223,259,937,496,353,153,234,239,838,951,582,346,871,497,858,840,887,323,558,248,522,997,604,35,787,61,937,509,630,276,690,808,335,564,448,988,564,540,811,280,426,319,548,621,863,131,682,880,516,261,881,319,348,92,708,666,521,267,268,119,224,520,782,560,580,383,177,466,794,258,460,595,955,366,771,835,881,529,565,252,868,952,240,456,239,164,252,493,248,343,15,58,829,556,736,677,444,922,450,457,310,290,956,838,149,674,893,89,395,791,590,323,797,986,308,12,756,394,389,335,496,595,467,351,154,204,476,76,569,639,343,604,769,873,624,556,133,891,646,730,774,884,662,457,560,433,958,304,602,527,671,694,284,334,698,574,509,280,610,38,435,813,630,891,397,35,11,359,879,622,368,934,58,270,685,16,501,441,99,170,147,308,270,975,982,967,641,223,506,584,790,482,494,320,128,97,587,308,399,868,542,808,130,780,552,432,840,23,514,483,830,75,928,47,159,839,71,314,327,217,122,826,370,931,917,960,610,55,34,879,501,409,852,932,82,236,797,62,435,994,802,391,917,996,27,679,969,37,169,747,828,513,49,519,976,148,667,731,125,801,361,12,612,395,156,531,753,511,817,73,922,252,786,830,568,224,812,955,675,823,511,69,621,363,174,861,783,183,34,920,311,638,363,624,11,699,418,576,170,368,898,98,125,284,690,822,10,263,133,911,495,311,552,615,603,544,758,437,131,206,172,672,85,364,963,173,645,660,497,854,341,259,573,301,49,818,524,55,381,557,752,589,396,74,920,835,617,860,690,697,39,276,104,273,575,554,483,465,484,819,806,647,596,968,892,955,642,144,704,12,387,739,494,873,843,966,599,300,435,287,9,613,794,19,295,777,166,357,304,891,829,221,465,443,490,968,669,696,79,169,331,964,18,690,596,828,146,580,551,137,954,300,24,54,882,188,518,964,107,589,555,794,759,682,706,462,117,545,416,403,138,783,216,440,604,346,159,979,234,691,645,201,423,416,742,388,277,13,716,223,132,635,398,639,428,45,423,268,52,239,471,76,507,209,753,982,392,985,615,452,526,432,659,153,748,312,110,299,989,673,920,989,246,47,864,723,743,300,255,356,983,705,94,758,470,869,791,223,406,290,938,123,234,235,128,795,918,613,623,88,883,33,689,199,322,496,928,583,547,112,173,966,231,292,98,70,809,568,15,380,679,13,642,650,689,593,844,874,634,860,582,789,960,15,94,694,927,599,319,621,4,844,703,927,733,193,376,71,274,33,827,91,641,790,7,329,685,114,462,388,718,259,367,585,212,958,545,544,640,359,655,256,313,57,65,750,397,482,916,635,143,614,765,162,556,551,38,610,499,576,454,407,836,782,639,296,806,751,230,480,288,633,439,704,707,645,309,766,540,965,136,935,889,236,908,645,444,138,917,559,607,580,719,16,521,688,515,993,436,235,623,619,552,112,271,747,853,98,851,303,783,324,57,434,619,535,281,469,363,99,884,235,85,639,332,355,301,209,187,736,831,921,866,798,835,204,11,595,356,9,947,480,36,206,666,678,410,458,635,598,542,667,279,135,42,820,749,605,741,430,683,140,895,430,489,720,753,822,445,542,646,671,865,593,950,214,142,354,263,974,805,633,738,445,178,966,766,260,34,489,310,971,293,565,474,612", "374,10,389,702,343,338,935,400,442,238,179,235,577,626,11,499,56,975,983,265,51,510,960,483,91,571,468,59,71,129,383,851,551,283,98,702,12,408,984,576,826,73,3,343,498,839,964,354,495,456,782,213,65,644,954,765,597,536,285,453,34,191,474,114,690,694,660,177,657,301,481,424,227,270,856,652,247,3,139,124,974,649,430,873,78,149,798,844,685,840,240,596,559,212,4,192,66,821,872,120,406,352,23,876,872,617,72,732,724,146,121,542,674,216,146,949,76,432,850,899,694,743,720,240,74,795,997,588,227,560,70,461,584,176,868,516,135,625,132,127,703,809,349,503,151,58,843,280,767,732,647,869,170,922,295,302,139,619,940,699,751,719,408,650,477,763,874,693,700,835,802,928,929,650,207,793,920,292,494,876,560,161,596,252,34,163,188,447,318,191,632,413,708,700,648,325,992,8,792,421,331,797,144,988,223,845,910,386,310,59,257,15,201,644,808,136,176,148,890,252,312,285,963,416,603,729,520,316,963,866,397,422,330,945,745,552,546,728,935,977,70,888,343,632,789,206,929,304,383,286,796,375,0,558,137,689,748,837,530,13,273,810,660,773,242,72,2,438,264,31,333,960,223,985,721,458,59,376,730,198,968,861,320,281,38,448,825,872,63,317,320,598,625,218,326,491,176,356,788,17,76,999,129,895,162,149,986,337,379,569,866,64,670,75,296,235,338,400,206,177,737,832,845,453,661,578,897,47,437,299,160,932,290,197,842,243,201,121,249,483,480,383,845,361,877,835,865,561,239,309,832,581,668,326,654,180,46,440,367,92,107,492,584,399,57,683,358,623,949,805,195,902,845,106,965,567,908,869,923,655,900,82,944,292,711,429,913,887,55,485,962,976,514,541,721,748,951,568,390,872,721,230,857,57,20,149,894,806,143,867,787,771,523,625,672,235,892,210,701,570,594,656,747,151,665,697,909,479,251,848,942,151,400,914,20,871,328,426,761,717,383,177,752,325,946,135,724,678,859,579,813,458,778,782,306,488,594,19,27,699,386,544,986,745,571,83,455,774,693,791,150,778,645,768,548,528,666,810,708,907,56,441,447,58,811,479,324,635,226,828,401,691,81,976,922,679,260,135,496,746,361,274,303,322,869,579,877,446,282,862,184,962,154,997,949,57,530,328,802,131,307,760,933,689,497,301,603,897,414,171,909,601,247,237,711,269,699,239,287,838,579,896,662,221,211,718,730,2,20,366,570,1,688,290,87,669,474,811,685,850,720,968,221,887,373,688,101,743,933,944,381,310,966,129,232,138,749,209,290,385,196,439,306,138,840,745,408,375,812,131,347,501,213,655,967,99,455,31,384,149,572,4,853,697,199,296,31,155,547,447,134,995,989,674,390,134,156,49,401,88,231,864,340,519,642,651,229,48,636,199,9,663,836,490,931,80,902,290,550,82,613,527,159,226,68,643,905,171,342,264,220,660,802,110,379,99,439,788,749,998,509,376,560,652,103,61,828,955,987,443,268,916,228,991,198,787,607,949,759,406,662,195,210,458,480,188,393,888,562,863,517,210,306,811,286,188,701,371,29,867,809,509,438,144,23,911,66,124,118,436,949,923,520,845,331,177,741,882,613,609,17,602,205,779,678,655,331,620,614,112,975,900,465,775,387,484,692,373,842,811,738,418,791,819,850,512,497,240,616,673,12,8,280,608,381,595,556,666,539,502,786,857,197,372,560,777,757,471,537,637,856,150,926,512,564,313,313,318,421,342,1,224,352,966,797,109,172,955,463,281,609,561,522,627,38,930,388,489,864,905,297,952,847,739,562,344,660,120,358,567,304,875,627,825,291,500,26,366,768,522,113,24,708,871,850,209,807,555,338,55,942,873,731,48,490,165,819,288,855,355,566,785,766,127,714,734,468,527,590,523,164,916,298,71,955,57,626,895,600,738,458,97,47,204,886,470,521,720,793,6,255,583,300,558,96,43,178,645,560,545,825,468,301,400,887,18,880,611,297,240,291,759,121,861,196,673,307,779,160,466,88,964,550,341,606,700,931,925,892,637,304,478,990,491,106,319,977,469,888,205,917,303,920,888,614,161,833,854,68,608,785,888,71,550,390,988,199,867,752,184,617,140,732,841,781,383,755,852,180,93,249,340,386,63,338,463,377,389,247,335,187,637,664,758,217,460,212,575,148,487,522,663,650,279,305,334,776,464,145,767,906,714,981,581,340,475,946,339,833,625,123,951,728,245,296,766,407,251,224,576", "771,538,660,585,55,791,557,68,525,740,956,770,582,616,418,225,626,705,45,37,219,554,45,679,471,461,408,627,970,128,769,599,629,634,798,125,427,107,342,322,202,191,349,810,439,866,888,116,412,376,212,113,606,421,188,423,208,5,113,898,240,971,91,553,706,482,726,500,309,678,657,4,149,86,60,750,8,503,576,479,865,907,98,152,876,232,429,821,198,50,611,627,597,539,253,196,656,713,428,230,552,949,872,129,843,488,746,781,281,359,129,747,930,303,435,100,680,19,231,545,110,535,340,765,815,945,601,724,379,942,282,351,173,474,152,765,790,44,934,7,278,482,825,559,876,63,209,188,789,495,106,109,740,293,592,168,343,942,553,996,613,480,724,726,179,936,520,854,34,635,468,455,44,277,744,356,742,612,772,949,595,232,438,541,891,123,164,55,576,558,369,244,67,395,32,5,762,717,681,80,589,832,570,289,675,765,150,838,777,371,4,601,105,660,292,216,916,84,35,583,42,900,858,357,917,705,794,53,336,305,204,42,461,837,320,18,645,244,531,168,175,286,301,740,503,680,878,805,567,849,155,145,558,0,262,561,162,196,123,45,205,876,263,162,342,258,47,748,279,620,875,132,133,443,21,155,975,649,988,72,369,382,567,429,718,418,161,191,484,237,754,190,322,43,993,783,581,224,566,296,496,574,231,440,79,381,125,892,531,17,338,983,423,382,102,670,746,14,322,541,386,239,752,545,797,824,332,960,229,693,340,355,939,278,809,816,152,512,604,190,670,742,943,427,527,234,786,194,816,103,225,985,863,207,860,308,229,145,80,698,735,685,263,425,956,213,16,912,653,172,783,72,714,276,355,511,642,570,331,382,982,887,846,431,472,248,43,142,921,635,936,327,94,87,585,296,249,866,984,604,687,732,786,705,30,456,596,704,371,963,648,986,150,762,102,971,594,204,767,277,924,932,836,722,986,22,963,541,696,681,273,671,628,442,420,964,559,848,494,169,244,49,490,166,725,535,806,421,651,104,193,208,88,629,937,894,642,682,371,256,233,563,562,373,176,473,759,204,302,377,332,370,44,18,233,686,235,421,115,678,753,213,520,949,795,783,128,414,404,986,865,161,209,310,532,126,429,171,781,612,672,205,868,861,364,777,891,489,733,532,239,359,241,47,75,236,272,300,947,835,820,523,649,766,644,719,790,794,791,462,337,781,415,69,933,314,393,823,315,712,319,950,40,312,486,740,18,111,902,60,508,50,896,434,884,344,564,760,680,321,657,572,876,423,882,860,398,416,228,861,596,409,604,215,242,44,746,418,853,670,999,426,93,221,613,656,272,902,996,617,956,324,980,943,766,292,461,699,284,216,981,944,944,20,820,421,861,23,484,773,969,221,939,181,279,425,75,902,258,231,642,658,356,57,444,909,365,629,390,563,165,291,100,282,267,911,6,382,435,520,546,136,675,530,378,535,679,591,987,918,75,454,587,609,304,876,358,150,174,234,686,388,914,489,653,503,657,122,986,780,448,10,520,722,927,497,869,696,337,957,528,646,375,568,369,408,47,887,16,371,114,404,253,146,483,737,955,627,372,807,903,565,704,105,970,379,828,897,538,595,35,320,791,162,913,11,778,934,431,672,124,363,537,972,775,893,42,229,318,220,809,766,852,408,325,337,167,595,335,502,33,566,423,426,428,305,48,263,707,897,62,400,720,591,489,892,187,50,105,487,860,768,160,911,430,472,693,812,735,59,932,363,6,150,762,750,384,464,28,110,200,940,987,134,928,973,835,193,11,453,386,891,190,413,708,937,192,260,554,418,32,585,751,747,83,3,187,371,446,544,255,252,226,230,932,110,996,737,770,231,660,104,585,370,361,472,483,446,476,793,827,264,235,217,646,609,486,33,357,56,75,840,569,162,612,993,291,189,899,892,161,884,529,161,239,678,138,241,618,583,139,590,945,194,693,634,810,548,153,223,16,94,413,799,196,40,94,367,647,996,416,77,177,47,241,53,875,952,542,758,303,331,719,333,818,71,968,680,791,380,300,609,389,751,147,173,538,61,723,599,950,190,764,971,978,314,915,768,108,735,36,892,43,433,442,796,787,544,906,145,559,943,974,416,90,636,717,740,710,121,588,895,247,785,643,499,888,649,57,690,825,410,8,377,110,297,212,130,127,945,392,247,972,533,167,330,95,102,604,594,947,297,476,791,167,435,572,674,339,627,155,238,528,414,102,293,83,629,887,910,338,80,922,740,691,507,568,509,707,432", "683,808,481,401,767,594,541,607,533,853,955,101,701,561,360,998,433,388,108,444,103,881,412,563,868,265,862,265,655,813,488,230,994,215,263,561,905,397,902,503,478,728,767,538,673,944,883,149,988,917,826,496,733,472,619,463,638,232,349,690,984,153,235,808,373,303,805,916,647,640,927,353,231,925,19,397,630,140,292,212,926,797,522,812,692,881,374,723,252,186,152,249,849,177,219,201,171,946,72,288,160,886,887,757,73,200,340,619,301,846,698,255,191,722,880,997,350,33,425,660,439,611,514,830,536,919,63,19,18,502,609,522,548,637,276,330,758,392,332,898,114,495,121,75,443,575,133,212,969,891,810,402,836,820,751,235,994,424,12,723,231,756,609,737,391,892,280,933,561,654,793,390,76,824,88,726,29,452,204,311,664,864,491,395,887,214,816,188,591,607,550,522,930,695,598,763,334,110,965,255,850,352,147,321,855,578,237,529,337,217,175,105,58,14,413,941,24,642,968,541,658,371,734,244,223,994,724,116,195,376,711,887,579,6,643,685,430,851,259,283,524,972,498,989,148,738,157,583,38,186,588,248,137,262,0,733,827,26,758,389,468,648,45,181,702,24,274,539,578,589,792,642,883,841,920,875,73,976,973,323,751,735,32,393,512,300,736,770,788,621,363,225,794,194,431,55,989,212,880,905,729,849,273,344,643,465,394,125,951,343,892,872,849,653,447,711,555,932,646,203,528,801,941,278,401,180,866,610,301,217,903,585,140,156,569,557,271,718,103,857,436,577,5,641,886,128,615,993,830,491,759,82,439,175,549,650,568,963,132,152,756,67,778,104,939,160,964,629,306,688,118,272,920,461,573,172,395,355,147,529,944,33,402,99,466,76,470,981,798,556,948,745,79,146,88,319,846,715,264,994,685,37,594,144,852,326,656,704,356,544,390,699,325,73,999,468,412,732,487,162,864,90,38,811,87,974,273,564,404,444,245,432,974,270,362,13,599,929,691,312,892,678,237,16,340,652,347,823,659,997,684,163,803,216,848,518,309,675,169,128,634,842,954,994,820,127,131,802,535,768,990,887,430,523,623,646,106,384,633,386,16,423,428,33,943,727,433,846,45,672,240,101,171,721,60,524,582,520,159,288,592,323,670,465,405,306,183,58,368,120,472,565,475,903,126,960,761,335,219,587,708,639,459,921,776,507,569,96,470,54,837,874,824,187,601,74,915,287,999,520,285,385,420,355,111,12,770,47,617,39,259,313,682,302,820,121,502,356,560,450,445,97,626,832,89,25,286,547,286,910,418,346,506,69,184,447,32,295,8,824,703,774,990,6,211,828,242,383,569,619,418,509,288,868,997,538,449,564,269,438,55,653,702,8,334,602,108,391,835,71,301,553,751,265,331,684,295,675,957,216,12,189,324,588,560,159,484,594,801,990,828,179,641,979,97,44,40,374,998,794,274,811,442,339,77,171,782,716,157,77,61,743,398,330,178,359,133,441,463,971,89,860,124,312,365,190,255,670,431,223,481,147,836,897,272,911,856,214,512,294,264,885,594,334,726,226,933,46,417,380,412,899,471,208,25,369,345,860,157,112,617,905,525,757,217,554,41,966,465,598,286,841,545,110,228,218,222,45,906,155,211,99,168,668,638,780,938,742,939,920,289,293,118,843,900,992,856,546,962,475,65,826,953,834,492,518,802,824,632,117,107,820,368,864,730,412,483,840,720,866,728,440,39,548,829,424,111,739,21,693,13,182,72,501,304,547,129,465,6,534,221,235,24,616,624,525,828,125,85,36,699,789,18,672,263,695,435,51,866,110,246,949,443,906,143,602,987,153,701,612,813,658,754,217,752,970,874,409,570,890,644,697,841,54,904,228,440,57,312,494,671,488,839,970,7,693,289,782,964,166,359,822,159,932,474,124,387,560,213,12,778,140,996,330,921,882,352,809,659,211,888,271,431,129,918,755,980,141,446,667,211,898,925,192,388,24,464,889,406,312,700,381,251,50,689,79,446,617,81,578,460,923,994,500,645,869,243,550,559,915,541,956,341,178,321,466,267,663,126,271,804,913,719,976,514,85,931,48,168,309,385,733,280,287,517,455,388,50,617,526,879,626,463,833,605,554,852,847,651,66,116,318,363,85,490,279,946,862,399,645,615,735,284,404,800,352,826,163,752,99,678,155,653,176,766,534,322,593,301,329,262,237,828,765,66,795,531,593,717,793,361,365,365,164,246,436,101,991,266,349,492,712,907,79,301,841,151,923,913,169", "730,114,221,725,754,427,706,755,416,596,732,496,357,860,293,418,382,729,421,108,57,75,406,544,790,655,975,909,724,688,440,285,328,675,843,408,986,120,443,444,521,570,589,273,59,507,977,421,699,643,229,252,278,538,632,167,600,4,41,241,800,9,879,530,937,540,186,379,855,240,677,92,977,511,957,565,521,346,2,615,616,674,603,135,509,75,502,890,555,627,593,311,842,607,753,12,977,550,337,101,174,49,906,270,124,500,782,684,570,274,273,257,9,180,372,977,69,947,424,91,565,958,214,865,562,789,523,798,232,181,988,905,819,738,849,365,240,682,753,624,985,129,926,930,94,849,538,729,794,129,257,846,196,494,51,1000,642,874,899,233,136,611,353,321,668,407,562,3,764,146,214,212,146,609,347,890,981,292,567,719,872,155,432,758,213,732,788,112,132,110,916,700,149,517,911,366,598,488,502,743,9,393,847,527,295,414,188,6,889,565,697,515,733,295,70,149,511,460,806,432,586,605,85,800,749,157,209,898,639,866,576,885,999,307,296,840,549,62,222,81,650,916,706,569,245,418,401,59,851,310,131,372,689,561,733,0,821,14,913,311,651,687,503,737,156,442,799,55,513,401,204,313,395,393,332,721,117,200,578,261,259,761,418,396,691,287,240,270,818,752,443,710,90,867,112,803,630,257,918,749,33,284,416,164,443,862,994,734,139,150,971,591,457,43,560,939,880,745,191,518,576,893,143,367,298,313,484,74,844,679,42,317,494,764,967,626,916,217,109,422,816,186,541,153,579,837,282,573,132,991,204,139,996,406,231,154,125,565,674,478,552,884,737,161,376,930,581,346,193,506,142,541,726,249,483,581,28,936,48,865,552,145,331,324,102,189,218,679,239,638,942,510,635,956,529,903,278,824,632,535,502,72,157,792,560,777,675,558,185,876,475,880,676,81,920,152,943,927,264,401,508,689,769,573,749,148,781,401,859,411,53,428,667,119,753,440,534,965,653,74,620,992,796,638,51,919,614,55,819,510,900,190,696,70,603,646,961,396,763,528,980,859,937,651,474,633,595,837,446,657,887,266,172,952,320,119,276,323,408,136,31,480,621,927,901,384,6,170,293,217,979,592,161,381,542,789,610,957,144,619,260,11,276,713,390,607,995,802,490,702,371,368,87,825,90,455,523,915,414,894,939,672,49,693,223,852,735,501,85,341,554,502,872,788,640,394,18,958,190,920,964,972,313,313,474,568,630,341,581,919,243,315,914,699,298,848,355,188,986,346,409,419,358,705,97,596,440,784,833,406,623,498,432,630,296,725,570,529,645,473,805,191,132,94,818,33,673,184,218,637,751,734,813,506,361,398,314,689,160,693,196,491,751,53,969,330,497,713,542,810,136,351,185,960,940,670,956,694,204,368,261,121,9,472,450,914,151,717,338,237,837,27,269,587,443,279,521,708,770,796,328,640,361,15,625,186,180,206,480,925,190,440,871,600,268,818,44,981,134,440,449,644,329,639,919,275,790,780,146,482,155,680,699,330,153,971,895,201,389,93,838,883,277,589,39,937,161,492,669,978,261,349,387,640,988,300,596,84,649,571,452,122,904,743,218,661,903,770,431,424,247,937,123,630,944,614,553,414,425,197,57,2,252,710,457,924,321,425,621,890,402,459,142,818,350,425,212,101,497,513,653,744,211,895,401,241,658,896,715,587,34,705,8,966,413,137,293,998,61,54,756,274,759,722,178,155,268,978,340,33,828,996,830,162,504,576,386,304,693,362,650,584,821,555,519,725,279,204,938,842,806,963,645,624,275,431,711,523,217,332,913,968,992,15,328,875,377,893,322,347,122,75,337,892,28,677,35,70,308,121,925,974,39,903,321,368,495,450,294,19,842,270,264,636,79,977,125,853,823,311,786,224,932,147,409,977,600,296,216,84,458,602,408,61,582,641,512,880,993,510,424,370,486,888,163,701,605,789,89,157,971,68,60,347,447,609,713,542,240,342,642,874,676,34,535,478,807,35,108,541,611,670,988,323,53,470,997,827,70,365,82,941,736,916,464,842,443,699,955,441,782,234,404,954,890,891,308,803,89,290,205,180,665,144,816,235,631,479,708,743,201,533,649,964,721,247,419,529,231,337,374,560,389,424,802,463,643,898,375,3,462,648,424,84,589,609,188,656,754,77,625,268,779,942,19,715,381,311,80,550,407,874,980,930,795,846,821,620,18,577,29,435,912,193,780,281,257,511,256,144,903,187,909,995,217,937,577,923,407,776", "478,389,771,478,289,825,587,853,212,377,322,492,398,764,966,113,179,701,254,696,882,432,156,981,220,752,211,552,769,697,440,992,708,934,124,916,865,151,541,165,174,883,829,442,776,960,64,917,378,524,566,496,395,861,51,632,383,731,380,409,192,534,557,171,1000,84,589,49,973,428,207,766,151,514,308,626,66,434,842,217,807,507,649,646,277,429,486,147,952,18,178,519,356,297,976,645,786,112,142,537,551,947,56,743,647,312,935,953,366,271,889,850,557,810,971,832,975,937,166,12,791,330,23,168,452,283,575,251,886,568,44,719,781,425,599,982,763,297,47,995,120,37,670,601,746,722,174,613,349,796,740,978,787,308,169,502,147,722,568,285,615,669,727,705,302,239,756,443,273,309,449,151,436,731,700,73,282,665,876,451,495,284,377,394,822,427,335,51,197,998,838,420,278,269,956,952,565,143,602,895,683,745,614,82,385,606,714,887,116,820,326,544,66,118,485,604,8,643,165,823,384,530,960,936,467,211,523,166,80,642,658,392,902,544,904,138,904,583,717,3,509,182,798,925,334,151,179,47,99,234,724,887,748,162,827,821,0,200,760,986,329,255,239,178,241,427,567,944,233,108,831,787,463,639,86,888,487,638,154,422,608,355,118,108,290,864,990,331,713,234,559,285,697,179,497,579,919,729,749,520,874,759,696,578,264,540,239,447,252,946,244,4,269,760,341,812,979,902,524,317,83,206,344,821,545,744,357,295,161,558,270,189,902,500,189,973,822,590,551,919,512,808,848,214,469,993,483,360,464,523,680,500,418,956,970,20,701,341,639,927,295,906,714,707,62,82,481,492,982,169,89,930,472,333,171,111,367,453,349,831,72,875,105,923,980,965,174,208,301,62,54,225,450,309,643,262,325,721,378,224,790,480,782,338,678,230,951,607,405,241,200,230,425,376,960,621,948,314,622,558,604,901,654,464,869,371,289,129,393,759,936,251,112,300,753,67,897,311,325,829,382,602,45,815,959,297,248,255,134,969,117,660,765,207,94,227,708,796,361,471,130,103,807,732,84,404,184,827,712,889,912,125,906,156,9,762,830,349,933,61,650,895,226,812,312,566,617,304,350,376,854,184,911,306,408,576,748,261,352,349,320,658,754,285,616,601,576,14,676,848,710,9,720,493,222,171,892,385,883,300,347,711,157,602,745,508,347,122,758,757,95,547,768,42,575,704,395,741,748,30,491,632,348,845,540,697,209,280,50,817,741,94,809,206,590,657,17,556,452,674,962,194,54,933,584,14,411,150,873,535,200,220,233,961,798,813,496,788,109,739,213,775,611,134,283,744,687,775,676,318,684,52,685,811,648,717,629,326,234,389,686,628,680,949,78,678,486,325,994,16,190,866,372,205,908,577,588,86,5,9,405,749,831,373,607,96,927,210,768,477,813,350,358,989,99,968,756,378,10,647,879,954,105,568,215,16,961,142,243,581,429,225,207,762,409,505,74,976,324,130,735,379,493,508,404,85,852,28,816,655,128,171,896,530,886,998,129,818,572,19,627,562,501,473,618,132,164,531,846,347,364,282,205,213,321,801,869,146,660,450,841,87,269,347,503,250,652,252,201,421,214,633,121,543,45,236,197,352,86,248,287,372,188,396,143,110,108,858,179,618,572,741,874,582,258,260,724,112,291,543,961,473,362,808,250,355,35,841,507,512,525,149,201,908,235,711,273,720,418,956,39,48,168,271,31,461,80,867,311,564,871,142,707,546,757,476,827,907,593,811,814,750,943,43,570,996,592,197,493,536,59,516,349,707,841,908,721,261,250,236,982,366,234,285,936,401,188,932,125,827,236,927,989,458,216,644,306,286,746,315,810,196,815,55,151,39,103,778,129,281,306,472,110,526,616,332,30,348,674,482,182,217,965,67,668,278,657,152,946,856,786,197,990,577,469,3,730,542,786,661,603,405,781,79,573,884,837,624,623,682,51,271,347,43,520,23,917,720,609,880,383,547,141,811,709,740,294,502,327,868,384,131,23,653,916,642,999,641,406,228,61,666,58,982,221,503,311,81,531,199,811,637,570,74,531,58,411,286,67,771,396,894,931,432,720,742,295,635,475,558,22,420,574,517,988,474,314,65,912,279,952,440,204,545,69,748,549,387,372,771,56,995,27,465,315,755,124,544,835,190,801,192,766,724,49,231,36,434,469,999,669,814,384,737,301,60,924,757,753,886,416,734,599,67,700,949,737,10,657,349,169,235,947,590,967,514,58,992,561,105", "446,563,398,889,190,688,419,301,222,188,865,7,928,38,373,211,458,76,540,496,461,219,899,381,395,716,117,131,247,438,5,158,347,700,800,843,737,254,65,695,217,699,671,502,307,391,326,464,991,6,543,48,453,918,851,144,865,706,48,738,44,112,499,204,678,740,801,780,826,808,385,114,201,739,651,798,991,902,65,788,26,269,652,857,367,101,241,802,175,667,32,367,690,944,49,236,654,459,618,51,205,991,463,46,83,296,932,738,354,602,436,56,761,181,987,310,581,699,96,374,212,59,880,319,876,484,438,641,940,189,207,967,592,317,158,432,429,312,265,73,578,260,898,977,111,524,907,170,102,289,527,437,840,351,168,560,313,580,461,562,705,65,536,379,543,605,329,809,313,218,119,57,190,62,583,358,915,491,132,902,833,680,121,770,804,777,485,70,38,191,909,258,427,705,521,197,546,730,969,207,941,230,312,815,521,7,208,676,786,565,266,751,856,534,297,416,710,316,340,157,998,303,311,98,91,45,92,608,737,973,845,570,854,113,528,448,574,511,38,487,23,49,902,674,288,469,409,854,175,689,556,401,837,196,26,14,200,0,927,900,446,980,911,143,822,336,526,99,129,885,446,621,432,317,196,175,672,124,301,539,523,977,924,118,171,341,448,187,81,87,798,541,947,398,872,754,758,414,761,842,985,920,141,542,351,388,657,284,503,968,436,87,76,651,10,573,617,656,268,512,761,850,55,748,799,376,74,771,144,189,265,544,84,772,862,438,544,387,435,647,770,182,245,732,564,758,824,264,416,420,9,484,457,894,923,90,787,571,624,388,233,637,995,150,435,581,565,180,642,990,835,1,532,265,464,411,722,654,606,880,207,406,962,27,877,601,956,807,546,57,879,139,897,443,883,390,936,160,724,387,112,651,722,469,623,345,519,324,988,39,416,981,188,782,230,124,645,497,391,37,816,559,742,368,788,74,323,107,378,110,17,205,103,456,352,628,983,244,712,577,325,502,181,829,624,288,541,751,893,40,430,963,903,601,391,609,932,989,353,803,203,313,135,159,95,999,353,97,843,940,998,505,857,197,144,90,309,947,485,469,721,388,895,651,834,49,847,40,808,379,280,841,656,6,709,990,782,189,572,641,905,429,86,921,130,561,40,965,251,197,377,650,192,407,842,118,825,226,156,228,451,409,356,862,711,54,861,922,120,589,339,824,832,660,703,772,391,981,991,100,466,129,497,185,629,996,321,884,983,64,675,833,14,542,286,770,865,905,657,675,577,569,11,836,426,448,354,820,949,288,32,270,180,11,741,319,535,152,648,33,696,807,233,492,151,458,308,479,291,614,666,608,109,560,692,101,242,437,687,194,203,411,529,508,352,689,83,592,191,394,379,319,768,281,636,857,447,425,773,853,429,575,291,902,787,553,538,641,465,143,928,140,339,633,702,836,616,757,850,700,384,569,551,946,638,830,9,760,376,768,680,25,252,210,967,691,231,849,104,967,675,730,138,216,663,652,642,607,300,236,266,243,78,295,22,964,709,249,719,569,689,228,959,247,285,555,246,665,132,346,87,665,905,588,253,554,702,752,239,203,404,972,541,557,17,711,182,525,43,438,134,229,740,486,80,137,27,120,418,120,667,1,912,742,64,298,226,273,811,427,547,456,960,822,630,646,793,319,48,125,382,189,629,888,919,739,514,115,78,317,654,724,106,882,936,832,941,142,112,550,609,331,708,832,473,698,363,273,612,259,107,486,604,277,98,72,898,660,974,279,297,65,173,597,879,958,152,461,87,231,947,95,99,838,919,702,735,359,88,661,168,401,796,905,791,296,817,367,773,164,603,845,350,113,112,234,908,879,67,464,456,668,617,909,353,910,40,896,534,315,72,878,476,746,468,47,276,988,605,340,679,241,929,511,785,594,908,764,286,708,742,962,311,167,565,903,588,471,10,569,442,471,475,981,105,616,791,273,728,407,268,908,108,822,385,934,426,358,26,472,934,26,846,953,681,559,388,403,26,507,823,792,460,278,809,78,739,242,362,982,946,728,806,841,67,685,648,66,400,452,38,647,681,3,705,29,853,346,824,627,607,635,105,960,17,715,96,960,397,119,868,505,376,216,87,456,161,911,676,326,875,787,810,687,716,751,181,463,982,601,390,922,513,339,892,424,809,615,526,35,379,688,854,576,819,287,958,129,979,907,866,243,226,256,474,889,359,776,852,579,783,139,460,893,987,243,553,644,416,832,746,418,167,566,435,730,463,919,413,184", "456,375,304,796,185,535,755,494,225,313,592,867,755,459,489,156,978,538,947,664,591,443,873,809,550,377,918,62,628,601,680,858,324,572,41,515,268,307,240,466,732,746,994,130,379,601,999,233,360,219,373,426,781,703,765,871,487,868,779,836,178,247,601,914,413,442,158,904,221,645,110,333,209,99,254,155,42,424,363,932,138,275,875,744,779,664,997,239,622,628,634,966,160,29,584,637,127,303,862,103,710,404,813,8,404,133,792,815,589,170,91,22,547,40,702,15,147,725,288,905,856,75,645,311,626,568,445,219,814,5,201,773,997,178,618,445,565,236,236,814,238,192,844,726,615,630,179,697,387,682,624,954,994,234,405,98,11,691,564,567,872,140,676,106,691,460,8,623,301,340,588,237,356,675,448,693,493,762,540,22,667,810,131,659,494,547,216,32,162,431,348,856,113,528,859,407,988,446,489,932,965,830,567,845,392,808,989,736,831,515,79,196,575,528,949,466,944,723,911,231,774,451,288,221,310,980,111,664,432,39,215,806,996,784,400,919,938,486,518,657,680,1000,730,465,640,571,99,75,744,140,793,463,530,123,758,913,760,927,0,757,414,540,762,48,408,602,628,891,110,82,27,463,573,521,644,255,721,972,95,13,261,383,893,279,378,213,27,296,241,807,363,240,532,447,56,7,782,367,504,930,70,340,520,974,712,164,386,462,262,672,930,491,774,604,150,984,541,234,144,296,951,953,513,680,556,7,622,936,433,871,946,537,698,78,408,690,751,178,743,981,628,627,986,756,926,935,551,80,883,89,453,906,64,505,544,425,148,996,413,2,67,66,553,274,149,890,482,660,29,391,512,725,244,644,536,348,384,903,316,702,865,997,473,276,809,275,818,677,911,871,932,32,600,546,215,569,424,621,880,290,745,258,505,6,456,897,868,450,367,342,767,280,525,980,421,593,925,135,753,791,336,290,951,124,140,877,167,918,995,420,403,280,801,401,602,731,25,3,760,19,627,27,248,404,827,900,297,540,705,465,170,916,350,793,157,637,638,768,834,835,507,323,18,865,882,391,907,646,201,500,312,93,94,596,739,762,877,21,853,999,476,804,776,687,81,441,15,345,916,561,160,172,986,682,322,326,951,347,640,602,383,714,418,785,982,15,282,275,54,764,518,652,743,341,512,218,748,39,264,443,972,679,788,794,227,256,921,827,777,701,604,386,735,44,954,42,897,273,704,178,298,217,982,438,971,32,271,56,300,807,106,214,707,528,502,864,976,797,145,312,798,23,115,697,988,545,856,866,72,328,862,959,890,525,401,865,712,257,505,909,767,555,403,514,624,673,594,172,240,826,532,819,463,238,76,792,685,392,408,227,831,451,622,359,93,92,522,473,235,169,715,611,690,87,276,521,31,231,198,526,959,808,342,452,212,474,859,133,860,916,487,859,235,725,562,260,893,223,442,699,604,909,664,108,909,55,566,867,718,888,68,154,504,953,873,450,553,2,969,959,419,165,499,358,911,603,653,326,108,299,674,286,949,784,691,848,975,17,101,2,756,216,447,492,993,374,226,22,455,634,210,482,519,278,888,460,142,858,312,992,141,362,992,180,850,972,243,380,287,202,417,345,678,260,513,14,342,256,233,699,102,566,539,51,107,947,866,40,253,925,632,990,937,401,162,710,814,527,270,242,301,766,376,184,898,659,167,240,68,554,619,999,795,223,14,739,543,674,419,25,32,634,859,481,939,720,663,409,856,876,982,784,343,893,173,264,144,243,613,581,414,134,317,780,170,34,523,18,67,453,311,669,767,620,187,241,90,804,311,347,591,717,744,739,642,482,239,349,805,920,929,433,57,113,889,858,763,305,246,198,509,587,713,660,816,986,227,29,710,168,684,204,847,1,348,369,997,238,875,921,511,55,191,385,751,322,128,208,214,641,79,159,802,752,567,862,537,239,816,515,6,917,111,263,942,518,428,765,129,814,39,202,107,278,77,925,112,662,234,283,388,246,400,117,89,699,146,924,285,52,230,228,641,776,847,543,524,946,681,603,833,521,342,766,424,353,593,772,461,288,981,585,168,78,138,749,354,511,949,746,716,898,505,934,597,712,78,413,307,206,600,173,836,777,239,724,733,165,944,579,526,643,997,186,62,325,349,457,167,77,784,219,477,381,595,445,446,658,497,608,821,358,782,453,643,159,414,626,314,246,453,487,280,444,450,360,771,236,410,446,502,175,191,963,785,198,804,559,937,950,274,364,414,613,750,26,818,679,185,181", "447,421,816,244,906,185,576,359,349,234,89,627,604,285,668,283,771,956,513,960,370,575,657,543,580,244,847,540,541,187,79,32,160,571,973,923,717,418,253,683,267,116,453,458,603,922,979,256,767,789,198,435,804,355,535,698,936,432,558,389,743,964,891,333,242,330,89,397,299,516,651,596,720,787,538,864,952,43,651,767,154,840,966,401,454,266,760,668,704,245,253,471,755,78,742,363,90,120,985,519,192,49,145,732,813,673,898,113,797,596,206,832,562,381,695,847,249,976,867,67,654,99,261,245,853,848,429,170,433,815,126,821,311,349,150,921,178,956,589,508,432,682,87,498,794,657,890,328,366,388,860,302,241,755,722,794,858,612,645,837,365,198,100,886,485,448,18,627,26,314,174,739,691,273,996,431,82,919,740,586,130,873,516,561,137,271,864,963,456,843,730,351,536,784,488,100,392,291,739,46,527,866,258,985,764,128,646,76,708,526,40,371,365,987,584,415,255,528,780,610,89,609,327,677,864,466,415,592,364,603,634,293,71,138,35,482,866,158,296,208,20,651,452,772,298,11,85,693,540,797,351,791,13,45,389,311,986,900,757,0,993,796,945,995,728,747,543,417,41,802,378,694,362,63,134,732,296,640,740,458,189,45,947,823,262,335,198,65,819,682,795,734,763,80,64,619,329,779,37,774,556,381,72,532,576,640,647,124,23,784,552,776,344,505,522,381,176,907,304,188,325,317,590,413,574,688,257,737,603,450,670,77,232,730,105,772,60,927,518,246,172,264,929,84,521,260,123,356,327,736,343,954,312,884,482,266,131,376,717,611,223,143,115,875,321,807,995,898,403,1000,374,29,109,31,788,29,676,655,542,35,885,906,102,795,848,240,338,845,952,412,102,947,363,827,464,328,898,55,219,943,459,270,783,395,858,719,885,863,319,594,893,610,457,808,520,192,97,379,800,75,944,857,396,978,463,799,870,56,61,400,301,689,19,793,286,444,467,620,316,867,591,548,319,393,862,882,684,607,97,736,278,869,348,463,378,98,916,868,190,499,527,898,386,689,112,614,896,686,361,438,80,323,699,312,385,341,497,223,16,155,101,995,615,566,852,97,166,884,318,20,902,50,73,626,264,120,565,653,346,77,888,303,323,799,471,904,460,146,146,407,230,440,267,414,700,379,952,905,103,707,584,949,15,179,123,409,452,885,474,878,846,642,463,964,378,629,235,690,909,885,69,613,365,137,547,685,725,182,7,963,339,501,238,140,208,217,934,68,959,148,420,963,908,890,567,265,207,680,95,701,868,79,597,274,101,100,276,914,231,994,849,532,389,425,601,666,402,260,299,263,971,315,878,62,211,164,266,539,594,659,657,458,217,545,648,390,26,365,916,914,855,527,555,124,627,29,260,959,790,394,796,515,957,447,642,89,754,322,137,318,819,809,909,206,652,656,314,489,889,108,637,930,107,382,732,2,308,33,463,681,776,230,507,94,847,380,733,713,99,945,945,889,581,524,464,390,976,796,145,944,208,925,207,48,201,391,708,244,275,722,616,874,747,686,627,903,269,164,741,450,546,652,925,114,313,352,747,731,273,669,49,233,887,614,144,926,423,189,317,186,336,519,837,794,208,345,258,39,374,149,703,945,697,739,733,172,995,549,670,630,853,104,614,462,363,990,362,36,932,96,449,286,286,874,30,137,147,591,127,943,974,691,835,982,509,809,262,372,922,206,792,696,383,522,465,180,730,419,887,391,116,802,8,380,896,334,801,888,261,810,746,580,946,207,907,331,509,522,950,892,978,89,366,406,252,631,679,559,562,985,415,489,322,242,876,437,194,31,312,499,106,200,430,97,484,598,641,386,781,851,72,507,182,916,54,916,192,170,345,91,999,19,630,274,148,550,341,348,866,820,679,367,388,256,546,374,507,872,814,297,579,568,34,144,64,745,865,696,283,439,221,571,527,984,570,573,959,416,386,903,265,765,715,853,984,252,700,603,107,940,454,220,502,125,859,431,174,310,918,65,386,679,476,775,349,76,673,383,669,145,235,80,494,120,259,838,112,804,650,857,164,827,943,968,990,517,980,907,879,131,202,438,716,573,277,228,42,370,907,261,90,662,137,288,227,201,454,396,356,292,472,182,454,868,962,133,126,563,499,445,879,930,318,50,717,866,994,900,365,493,390,303,144,308,950,557,729,992,556,309,393,928,314,538,654,336,452,908,303,685,129,343,580,359,22,556,585,989,880,1,464,260,336,564,744,856,547,448,297,572", "369,267,918,310,463,420,642,193,213,928,131,968,890,35,285,224,671,56,27,531,74,559,179,455,625,938,34,978,48,154,338,248,462,374,341,773,245,832,367,473,988,177,876,568,501,828,499,264,492,485,825,159,854,222,379,423,915,881,678,549,112,702,494,462,4,812,564,52,458,48,807,670,72,452,368,635,684,812,838,859,429,424,442,178,797,51,9,680,379,424,281,284,545,641,155,653,162,188,496,240,61,460,978,876,948,215,907,193,694,898,191,874,169,514,668,370,744,216,584,682,710,614,333,348,188,446,142,17,847,430,519,839,332,349,483,718,321,18,995,40,392,732,794,458,914,306,317,230,816,901,115,337,486,494,357,56,850,894,866,113,380,431,547,37,525,936,655,581,651,522,562,614,466,274,999,45,368,265,106,744,111,676,328,617,786,851,839,386,830,974,141,925,225,561,805,846,245,172,965,929,446,759,856,323,173,499,193,653,111,885,970,434,917,846,585,171,104,966,125,72,365,246,967,145,694,26,140,900,267,510,839,763,464,145,619,778,745,301,321,82,883,401,72,803,762,564,364,203,382,599,295,409,273,205,468,651,329,446,414,993,0,64,942,323,599,683,840,432,789,447,237,293,529,378,353,886,859,847,23,363,562,860,643,292,484,244,628,689,687,752,356,833,545,162,752,577,56,383,470,417,964,308,310,351,778,756,85,7,700,511,524,407,338,614,626,874,677,878,687,303,252,191,284,965,535,7,151,856,757,986,857,169,760,657,281,927,799,541,147,825,581,245,406,54,690,95,88,448,267,714,657,821,940,767,554,864,609,823,242,68,951,818,757,104,167,535,626,538,518,446,59,298,525,486,793,971,199,193,334,55,313,936,117,155,826,42,595,248,271,333,305,992,70,402,674,31,572,759,459,836,340,954,167,793,248,354,691,956,847,828,286,548,979,491,301,213,651,325,461,629,166,774,364,880,666,303,943,788,785,273,506,67,145,800,794,706,136,30,524,961,597,836,18,833,659,344,789,924,909,524,187,877,202,913,101,291,178,912,595,777,272,141,999,32,227,107,186,323,915,705,741,74,199,550,489,53,355,604,227,344,692,79,163,30,424,774,115,572,923,284,308,293,952,879,87,352,761,358,560,833,27,979,646,229,274,733,391,906,316,993,104,798,487,543,807,279,17,690,702,976,698,711,889,407,523,445,458,513,615,644,518,167,979,322,99,392,869,112,765,69,579,566,611,67,262,889,77,859,816,939,684,258,81,177,945,85,672,134,825,834,776,938,835,338,224,496,251,64,418,178,527,727,673,392,299,46,351,591,969,102,481,40,619,780,237,189,487,729,865,715,925,595,741,400,151,410,493,542,183,800,870,10,71,542,211,829,180,202,268,3,696,84,537,324,776,983,493,607,907,234,889,547,962,858,984,151,73,714,804,809,637,596,146,812,566,730,780,261,364,940,167,318,436,241,988,269,442,562,884,505,942,185,783,735,87,68,86,596,486,287,48,440,397,113,750,876,297,95,339,453,21,411,924,47,788,400,431,721,424,869,935,310,708,571,15,682,855,214,527,442,839,245,935,722,473,895,787,507,943,201,545,411,310,477,802,25,984,171,324,597,988,194,140,253,498,631,654,517,393,125,671,543,176,449,845,248,944,867,263,192,830,273,782,263,767,782,62,737,702,628,86,51,105,314,803,735,304,450,10,954,521,199,445,542,569,125,172,472,785,238,928,71,367,818,42,450,924,575,712,391,603,677,775,206,980,250,201,15,87,592,898,668,984,213,818,695,500,847,805,92,661,565,301,727,380,393,780,426,570,166,732,987,551,545,295,168,535,834,1,886,303,655,335,439,516,487,785,607,298,655,969,873,636,854,396,325,667,94,390,218,159,659,482,557,777,965,284,22,999,712,604,789,242,936,355,80,323,447,188,287,99,642,451,83,780,600,334,812,725,3,879,976,566,329,173,694,863,466,344,766,429,333,581,3,725,443,793,324,885,121,174,840,581,436,768,418,944,95,384,903,69,219,739,83,869,717,986,337,867,774,50,599,753,706,540,348,873,538,634,431,826,413,904,833,20,830,881,261,383,775,814,564,430,898,130,375,864,262,264,944,991,423,24,743,37,701,697,856,579,251,36,323,846,598,298,993,999,891,661,875,745,740,128,566,866,563,399,768,960,607,175,127,545,612,713,835,315,746,635,611,145,87,91,433,381,242,35,398,346,179,337,138,344,417,526,89,6,730,472,308,620,670,280,448,148,607,623,650,85,598", "727,265,372,251,10,307,363,11,352,472,242,424,723,225,671,672,749,207,487,80,225,892,933,305,11,404,210,697,275,819,161,793,870,382,396,262,712,407,778,104,502,647,312,779,552,419,268,888,160,813,709,670,66,708,432,509,584,587,266,893,576,542,387,440,941,979,432,836,745,410,986,985,892,47,469,525,392,107,669,641,155,591,530,522,775,275,739,255,623,898,97,228,154,895,463,683,506,473,423,360,974,494,815,220,235,21,183,544,206,268,377,420,971,43,974,878,340,693,77,834,793,547,707,548,98,431,421,130,225,192,874,598,226,835,587,23,12,260,428,777,339,10,368,739,151,389,81,266,632,521,320,898,23,640,411,144,41,280,158,495,32,347,666,994,494,110,777,532,364,998,835,369,339,791,739,635,974,777,912,58,936,949,324,958,768,269,185,826,891,701,82,350,306,833,473,950,621,558,575,47,800,472,908,98,94,546,977,282,75,383,112,852,187,698,791,925,127,784,50,282,108,847,650,994,985,992,434,95,664,748,285,573,599,548,482,976,156,52,677,167,283,225,271,861,874,219,369,693,682,484,831,194,810,876,648,687,255,980,540,796,64,0,65,338,847,373,913,767,231,340,237,251,387,735,693,981,356,809,780,741,999,33,463,765,267,160,87,734,549,781,257,130,94,20,950,393,983,4,630,555,893,701,124,970,208,175,561,925,908,621,898,796,635,42,194,197,639,386,667,665,520,447,457,137,315,10,811,804,705,570,562,764,470,513,908,206,659,306,735,966,500,173,401,952,434,886,776,444,226,595,740,11,580,340,472,482,793,293,805,873,869,342,453,190,313,518,738,550,369,705,585,908,620,37,54,143,458,430,317,160,294,683,411,59,970,925,691,738,482,542,92,38,556,115,897,741,617,489,900,933,221,827,520,983,899,649,468,172,110,543,177,669,529,541,782,418,660,938,246,54,186,464,724,73,164,995,539,132,884,125,419,257,799,989,99,755,113,822,637,787,125,671,835,71,240,988,403,97,40,590,640,594,959,419,651,780,468,904,180,520,525,363,789,772,114,883,102,929,726,509,715,319,800,251,259,952,652,340,556,854,557,28,81,603,631,174,370,636,941,878,555,904,717,738,442,781,210,105,132,969,810,7,704,16,901,896,406,79,133,304,895,258,99,611,245,283,778,796,280,88,497,990,97,670,306,659,721,428,962,379,226,70,509,783,941,384,310,110,96,715,851,911,217,395,925,933,585,274,271,446,278,52,344,32,902,13,724,162,128,413,42,683,350,831,219,628,815,414,327,588,926,950,574,137,837,967,77,155,300,398,929,6,929,560,128,508,630,792,294,430,870,517,228,220,171,976,669,286,343,452,147,391,960,587,652,227,869,520,676,698,405,463,404,973,103,247,406,797,228,193,428,54,678,246,737,597,812,982,388,795,773,986,875,575,542,746,256,68,695,178,438,764,45,440,83,732,61,292,881,416,342,862,624,607,677,127,298,530,916,151,448,707,652,709,278,896,57,962,290,179,398,300,746,500,926,103,538,714,675,919,417,903,677,826,681,951,964,278,517,221,628,395,346,56,528,312,672,646,916,33,982,719,560,536,13,788,938,421,517,966,889,825,783,638,439,600,509,279,353,832,96,400,304,196,985,847,174,148,193,848,433,880,933,50,275,620,830,821,667,303,909,195,173,32,195,985,848,933,450,1,960,443,572,420,528,879,816,157,15,860,286,990,180,995,470,198,893,784,166,394,262,928,48,750,771,985,877,487,996,668,919,716,69,378,486,129,874,661,27,473,151,33,48,314,848,254,924,405,542,19,127,819,859,692,15,269,448,871,275,858,931,511,329,298,739,801,501,622,928,510,287,832,171,413,333,79,968,279,767,237,521,13,459,615,785,728,252,238,577,254,908,475,285,546,513,843,802,735,325,833,593,941,271,451,931,174,191,283,176,241,384,776,890,341,765,808,527,557,572,256,566,351,599,536,351,993,786,906,164,665,224,783,697,366,449,527,986,169,804,341,953,481,755,29,56,778,279,603,576,40,31,93,729,844,805,358,256,637,435,817,163,608,519,89,502,585,93,105,305,61,395,862,142,328,546,952,973,272,557,562,119,40,942,995,756,574,573,984,923,256,78,469,148,269,64,153,75,900,188,549,731,726,621,890,360,353,888,464,506,1000,974,454,901,927,891,518,877,786,10,333,680,237,382,700,713,144,920,989,96,22,917,566,395,690,365,917,338,699,787,202,558,96,860,13,902,649,140,136,549,807", "258,554,353,484,235,834,387,664,213,832,656,60,30,932,95,408,109,950,75,420,832,880,804,935,229,47,776,958,357,718,809,91,910,15,189,683,221,533,432,920,509,121,481,188,977,384,457,304,396,513,706,752,762,650,170,133,136,141,987,216,988,694,977,569,625,976,437,432,910,896,989,680,553,853,743,148,460,325,760,780,929,616,665,41,439,324,880,34,86,894,47,619,192,193,48,973,637,152,978,841,565,973,41,820,151,795,21,396,127,11,460,444,393,413,145,278,442,56,523,273,38,660,64,478,924,723,904,467,812,224,116,144,29,84,950,845,283,256,265,414,153,413,425,807,791,496,315,411,763,719,95,301,93,240,3,473,494,296,886,968,898,450,641,314,214,522,453,93,121,65,158,200,602,750,747,631,545,250,645,37,869,578,294,127,292,802,857,907,47,346,601,532,872,51,338,169,157,601,588,153,874,470,706,36,736,666,902,298,523,944,516,650,6,611,265,92,128,664,870,75,656,369,862,598,424,538,990,875,513,352,615,639,289,588,10,973,605,12,335,621,549,606,996,293,775,622,725,462,675,667,210,289,660,263,45,503,239,911,762,945,942,65,0,641,92,113,625,707,625,702,632,490,65,167,472,293,825,550,45,59,339,238,456,874,722,115,922,372,414,898,374,374,76,797,787,841,80,182,687,908,138,334,127,361,592,859,721,267,21,185,557,823,969,669,97,556,418,553,29,160,351,883,564,760,22,609,817,813,593,135,425,485,859,624,789,670,652,484,514,236,187,208,959,447,220,435,467,783,202,747,992,449,583,773,760,64,571,606,657,955,202,224,869,103,187,939,371,634,640,935,79,389,986,642,550,42,635,931,463,675,433,129,194,566,262,643,860,346,595,181,633,951,77,756,601,750,813,797,307,629,568,844,665,198,748,15,164,984,777,631,809,248,903,158,671,619,614,65,719,971,221,385,320,412,774,808,374,529,236,303,127,515,926,76,887,675,453,293,162,959,563,852,20,303,299,495,933,647,168,752,346,243,893,985,692,660,464,140,859,69,194,613,409,62,577,796,360,823,737,77,729,448,407,152,662,448,198,861,389,702,849,487,79,943,166,837,678,896,558,117,906,666,273,524,925,924,890,550,333,457,11,541,909,972,957,926,183,251,285,945,84,701,113,141,887,375,855,715,744,453,338,680,171,102,600,837,91,839,883,626,100,668,503,424,453,756,796,882,238,939,333,830,795,919,468,795,203,722,43,652,72,816,29,685,718,50,880,394,140,536,668,111,271,93,845,53,158,10,308,687,345,859,468,314,920,749,522,751,393,723,38,167,472,248,309,674,284,904,344,176,38,654,435,782,40,597,647,800,422,873,172,420,65,143,766,31,197,33,495,125,169,823,75,639,840,387,864,19,495,343,654,745,763,384,262,644,494,129,322,880,816,664,308,71,432,829,772,934,133,648,995,228,992,603,485,130,230,335,184,233,647,110,736,849,128,413,621,494,919,349,320,237,661,697,763,557,438,301,301,947,932,861,772,291,25,860,613,118,969,120,95,91,390,495,382,914,81,360,872,689,61,765,199,683,309,354,698,410,77,936,344,361,22,645,623,413,217,646,786,165,272,210,404,532,56,953,77,547,576,757,947,204,307,13,874,364,189,701,185,495,680,212,983,47,723,33,171,38,307,658,235,684,411,202,221,622,410,465,135,672,233,458,344,340,195,242,376,199,613,645,924,958,249,724,222,401,710,847,207,878,331,366,84,232,560,187,738,661,1,654,151,244,319,498,165,811,446,736,271,629,429,181,504,663,569,369,212,957,380,146,10,64,28,656,697,592,606,630,566,135,835,393,795,44,640,949,837,58,879,186,933,608,460,656,92,582,40,414,520,235,134,396,215,865,12,275,132,24,328,178,932,348,11,232,408,773,656,770,100,145,381,9,876,52,991,508,190,397,404,432,645,215,700,669,997,305,401,867,992,213,949,827,784,970,417,126,171,510,971,91,672,784,439,223,547,407,819,847,934,270,54,749,533,154,740,420,403,588,758,672,663,99,497,64,91,193,711,611,485,534,920,697,441,740,189,295,601,335,236,985,810,771,75,345,144,390,970,138,450,950,358,306,967,527,7,172,232,107,644,158,895,216,217,183,780,530,795,427,505,401,897,86,422,612,395,800,894,171,912,164,555,528,756,887,705,421,54,42,115,84,819,601,928,685,979,696,399,674,766,751,91,169,834,422,121,949,526,356,316,985,932,42,494,67,783,397,493,492,951,415", "307,862,586,862,374,229,228,49,784,69,763,541,404,474,87,665,205,623,635,642,337,425,389,766,740,952,431,102,831,366,153,559,491,29,146,873,51,549,880,30,703,611,565,502,34,92,551,608,227,120,848,2,734,29,444,251,720,262,139,675,924,997,513,742,204,12,624,857,171,401,67,582,819,138,326,913,16,960,900,419,213,984,953,860,965,324,338,562,179,606,611,313,799,917,573,182,775,832,608,914,579,982,268,796,455,533,225,135,307,851,1000,199,616,907,231,721,900,346,612,233,533,225,175,447,923,812,865,797,896,182,947,981,872,745,614,243,36,976,770,561,939,101,888,363,709,619,914,288,767,153,951,76,687,513,226,171,572,500,759,313,905,958,650,950,297,107,944,674,624,2,660,186,946,710,907,422,769,690,42,954,403,129,753,228,639,358,892,734,632,995,588,984,343,498,401,145,316,872,644,226,140,53,711,875,959,57,172,110,305,214,208,792,839,725,765,802,167,782,131,823,596,966,332,599,516,120,152,847,406,691,142,874,178,33,473,674,444,318,687,760,314,360,876,169,900,604,214,858,348,316,821,200,773,162,181,737,178,143,48,995,323,338,641,0,301,240,369,681,332,486,608,817,744,871,759,721,45,234,579,975,118,284,70,856,143,323,525,367,647,136,789,999,267,893,782,217,628,512,663,85,485,289,74,987,393,307,540,171,105,967,601,579,28,22,999,675,389,822,556,650,392,280,967,236,915,792,289,458,542,116,177,840,693,30,967,31,308,211,501,270,182,329,491,149,101,669,314,521,832,765,916,526,566,934,858,147,991,595,655,149,604,712,764,991,292,194,847,979,276,237,506,495,718,267,198,693,83,892,570,662,303,304,815,374,325,575,278,29,319,692,282,656,626,64,33,243,697,133,349,175,7,451,778,595,954,454,997,280,938,198,477,436,186,250,73,872,77,852,968,586,964,765,46,15,975,214,553,903,225,243,726,242,458,212,192,465,706,672,592,31,877,457,413,554,268,811,439,472,436,467,686,248,627,875,259,918,168,835,188,140,510,146,746,1,689,487,687,254,868,801,126,726,525,494,53,114,919,101,42,710,744,164,525,871,359,544,873,824,880,341,662,640,97,535,801,818,833,325,377,656,287,943,658,96,471,343,581,104,395,236,30,689,261,67,469,694,529,627,680,34,15,745,601,901,826,224,1000,149,218,386,213,968,620,4,766,687,578,668,336,528,240,905,53,326,981,423,379,893,791,921,999,258,928,92,11,926,272,524,610,355,934,943,335,968,461,364,538,686,196,321,936,304,100,558,682,571,363,585,463,572,67,236,637,34,901,731,495,267,402,806,653,367,615,922,882,693,416,484,572,175,971,894,506,76,733,151,936,890,58,234,536,111,271,2,908,12,443,315,683,405,294,894,117,987,202,573,967,165,291,388,543,117,425,120,461,166,600,230,266,669,874,704,188,751,834,885,645,617,93,383,782,820,404,202,96,350,514,591,301,419,359,301,718,875,980,926,760,610,915,880,331,814,412,945,709,560,332,383,84,888,696,812,94,605,445,959,220,216,493,112,794,604,136,488,91,157,412,410,157,182,567,428,867,650,208,874,672,860,543,932,12,219,284,337,317,265,883,611,397,500,314,59,896,66,276,288,84,447,801,160,899,925,838,329,266,676,885,306,31,577,710,495,351,606,838,871,253,115,56,860,297,697,31,219,53,468,446,245,146,558,348,469,215,700,828,871,618,288,535,102,157,30,879,779,148,68,911,584,175,711,969,263,878,59,963,226,629,117,779,655,231,466,667,790,722,158,877,483,621,258,430,112,195,374,592,603,488,811,314,398,61,657,189,919,481,907,450,71,90,541,930,421,299,472,274,427,576,964,301,914,384,710,202,95,978,250,601,525,278,394,238,812,572,730,620,737,302,691,69,904,141,102,193,298,267,36,11,445,518,982,217,877,895,237,782,947,541,607,974,75,225,33,503,677,2,437,777,76,358,397,250,580,33,945,856,746,643,394,457,907,928,89,517,807,225,156,629,670,633,259,547,595,940,743,575,561,791,916,645,992,67,369,497,570,928,898,979,948,974,54,156,867,568,738,115,847,87,168,569,500,864,120,503,386,973,32,52,415,661,189,693,737,402,505,104,459,151,106,134,620,640,631,83,477,256,305,800,413,280,914,664,313,3,132,511,401,390,463,779,148,9,411,849,739,56,75,212,642,627,295,185,382,317,744,168,271,979,592,751,38,821,883,437,298,452,474,535,868,137,777", "794,609,487,94,696,508,385,972,397,551,26,306,154,511,420,343,93,31,335,507,542,374,484,596,251,460,121,875,135,604,940,294,994,615,460,162,907,560,468,265,586,326,270,920,551,976,482,895,996,622,361,245,317,867,161,86,978,258,953,498,597,11,122,825,884,574,589,960,258,590,537,210,323,438,429,153,233,413,862,489,232,902,366,650,715,666,754,148,356,767,407,713,258,825,201,418,959,896,939,513,551,79,966,70,607,814,163,774,206,719,703,373,889,197,994,127,857,853,844,493,959,577,234,813,981,150,54,497,353,617,78,425,334,379,173,598,711,399,23,352,342,224,842,827,271,787,757,607,381,114,56,695,183,417,355,114,556,247,489,720,158,438,51,487,497,85,661,722,480,399,688,255,126,431,610,188,547,740,714,604,402,628,679,96,27,192,809,274,108,34,50,451,67,958,585,517,296,794,441,642,297,643,124,89,986,201,428,445,778,861,476,764,448,848,985,43,848,129,435,887,897,924,138,4,952,710,167,174,825,689,210,975,93,854,594,11,878,850,542,890,30,289,157,68,484,906,180,82,434,331,27,223,242,342,702,156,241,822,408,728,599,847,92,301,0,611,458,503,343,972,201,118,964,194,339,48,403,775,739,717,499,899,455,950,584,868,835,883,194,889,271,27,71,586,853,586,366,666,964,49,394,950,105,29,139,259,156,691,300,266,352,959,507,132,815,784,853,42,981,822,639,854,205,465,399,157,682,141,16,33,819,901,205,754,920,626,844,756,795,331,513,36,670,811,752,121,497,631,734,988,152,380,138,796,979,796,681,702,988,598,1000,262,164,304,185,294,50,371,675,243,960,92,561,468,832,680,868,906,486,688,632,428,375,50,906,963,191,311,124,190,520,897,88,400,975,470,330,551,30,284,59,346,682,540,618,288,151,840,745,519,964,8,281,86,617,757,808,894,629,597,243,105,712,536,740,589,417,995,250,97,398,42,503,146,693,126,558,503,142,4,44,246,90,704,667,656,209,60,916,450,793,205,396,723,787,525,123,815,711,662,147,407,506,619,469,65,948,770,708,225,388,480,363,77,312,766,148,137,170,127,340,708,274,981,360,833,467,661,948,800,135,35,787,275,604,575,640,852,839,719,488,585,10,680,436,112,364,220,834,2,112,342,935,670,23,223,975,93,704,476,342,928,878,393,450,15,576,989,96,327,333,100,977,340,916,212,825,339,703,672,109,100,7,917,183,818,620,137,247,960,209,22,116,483,351,422,937,965,263,355,137,874,300,778,244,60,319,518,811,643,526,634,20,916,908,907,208,507,742,588,977,710,953,959,434,976,505,980,558,670,47,636,98,204,207,745,985,488,835,656,187,595,899,848,712,547,277,587,5,22,180,171,183,108,397,323,228,305,477,425,545,78,814,652,932,908,963,811,243,972,491,766,461,830,732,706,453,612,486,591,247,426,313,908,108,609,787,654,575,277,829,444,715,88,322,974,121,432,342,365,86,156,38,907,93,466,503,419,224,816,617,298,191,912,264,850,305,266,229,698,384,955,556,155,657,581,128,317,633,377,486,2,357,74,485,734,149,284,933,13,163,509,469,238,196,753,450,104,504,345,28,83,194,541,21,684,693,667,622,531,634,437,830,952,701,470,967,285,25,995,342,387,793,535,455,588,283,632,254,959,649,137,44,878,999,909,584,554,466,682,262,928,838,922,376,538,694,10,433,341,531,528,801,596,946,488,855,13,326,129,339,506,845,808,668,69,331,334,124,808,347,201,93,681,706,999,807,484,702,191,380,898,587,534,910,140,167,536,393,279,162,381,117,256,963,541,599,109,456,164,119,202,560,47,289,967,203,368,371,179,564,92,616,602,359,216,660,429,719,529,357,174,66,626,808,103,9,24,5,276,747,578,734,884,840,458,628,668,790,669,900,308,268,693,956,236,419,83,651,409,446,391,489,568,990,85,214,512,783,245,39,857,972,320,239,359,447,420,950,317,388,586,165,685,260,30,245,839,935,389,260,129,766,636,158,235,210,144,645,370,595,468,990,334,606,500,62,190,161,73,776,552,932,603,362,598,607,190,282,768,511,706,189,467,725,253,362,794,968,361,357,698,391,886,243,536,490,482,721,292,819,848,899,99,729,330,807,212,408,54,230,758,568,847,816,52,32,846,675,231,850,566,84,290,657,434,365,682,115,108,377,270,416,248,292,336,674,134,781,498,14,719,292,819,295,239,704,935,256,107,597,709,730,351,690,557,978,493,614,188", "669,244,698,179,742,748,632,444,824,786,494,792,321,864,807,858,232,584,198,711,304,49,126,417,439,338,598,71,797,189,125,126,372,839,324,14,687,418,561,624,23,743,28,786,304,986,113,950,350,994,355,553,393,90,463,177,309,336,255,452,684,575,78,170,372,887,181,793,640,723,519,59,641,313,503,744,698,568,141,964,856,291,236,839,534,414,928,147,783,823,634,741,532,824,981,178,226,531,409,910,166,332,660,960,509,260,817,35,26,677,483,414,676,671,587,345,334,113,256,143,716,487,325,631,187,646,772,909,881,204,999,815,118,336,297,332,399,29,937,898,695,433,567,810,442,254,251,17,331,404,849,626,673,856,424,341,471,757,105,284,673,349,755,498,682,276,997,872,607,348,73,549,279,721,350,544,600,855,193,645,771,131,490,732,42,8,9,723,968,764,860,335,61,378,600,671,900,240,993,483,287,454,787,108,645,915,536,12,468,99,817,648,770,554,683,384,460,269,887,412,348,137,121,107,991,319,593,983,202,90,504,16,502,858,531,755,246,21,491,486,238,472,760,407,530,34,115,509,807,246,398,259,72,258,24,442,427,336,602,747,683,373,113,240,611,0,755,265,373,309,695,268,625,348,496,787,882,105,362,904,996,457,279,811,651,809,913,221,904,158,125,921,341,230,866,47,651,86,937,513,244,341,498,277,417,967,489,860,379,867,169,778,116,894,114,772,796,299,6,197,873,730,149,466,541,850,227,408,94,298,333,376,133,186,481,693,913,216,888,340,143,561,687,86,938,722,764,871,266,55,192,785,866,344,102,856,506,427,878,32,706,406,244,286,382,438,974,494,551,545,530,923,192,936,549,840,954,188,587,567,305,979,87,324,186,554,194,13,492,436,90,965,523,312,994,914,361,87,674,789,673,189,877,553,943,421,522,80,335,592,435,227,259,256,599,45,829,61,649,224,72,661,705,250,685,116,550,986,294,184,365,791,66,262,496,490,42,878,346,630,593,164,275,836,624,169,337,464,186,535,612,969,323,119,598,829,694,323,45,990,154,207,153,607,75,557,623,170,715,771,930,265,585,722,936,995,9,752,83,687,579,565,428,935,370,738,761,979,103,622,365,516,683,796,475,306,238,485,950,14,137,815,135,368,528,862,247,598,249,923,94,239,667,848,826,223,407,381,531,188,504,348,119,394,998,198,315,596,694,872,64,768,471,427,564,936,705,570,29,307,99,314,955,718,149,195,736,304,857,544,25,559,936,329,769,427,375,928,377,985,491,580,770,605,844,617,310,275,334,781,5,566,870,213,744,57,294,588,241,601,89,928,987,781,203,523,864,480,365,760,266,207,642,901,232,835,636,236,840,814,234,915,702,599,642,113,30,490,823,326,417,830,818,635,152,143,400,169,798,938,863,403,17,654,875,569,323,788,564,958,75,809,680,697,305,608,98,467,74,832,187,100,883,175,751,728,899,450,439,272,641,771,866,825,840,813,516,197,411,532,332,463,858,675,875,496,117,335,568,852,694,588,113,360,198,53,730,636,138,613,292,411,299,467,822,403,569,526,837,836,689,397,810,294,912,451,736,540,29,406,167,331,296,253,942,9,773,529,135,587,117,585,719,796,796,188,165,966,684,63,656,292,840,375,72,970,181,994,969,551,344,200,492,462,224,364,876,444,19,855,636,609,503,352,431,874,333,482,180,809,22,977,120,943,669,228,63,405,507,867,404,23,925,153,381,385,445,278,847,607,849,218,358,266,799,855,762,25,752,673,799,802,547,943,428,426,263,161,474,940,453,15,740,985,859,762,464,841,848,129,916,675,479,318,244,475,653,930,136,175,225,282,813,933,966,155,190,519,7,905,683,755,386,951,337,775,320,352,705,706,752,188,868,968,25,348,801,454,565,2,787,435,455,752,493,881,855,603,986,341,310,227,632,707,603,682,798,364,376,314,970,102,543,118,179,206,344,506,105,248,889,744,263,230,843,304,305,79,163,122,639,493,966,32,148,364,751,716,730,469,433,163,983,196,332,514,806,473,475,153,431,716,328,979,754,686,439,408,959,531,912,129,563,761,148,132,650,137,444,88,412,995,78,574,378,733,531,707,89,662,409,673,157,452,719,95,88,771,734,192,654,710,407,716,640,345,629,549,912,871,261,786,47,460,717,74,598,593,181,343,711,314,948,83,879,547,841,373,854,711,611,517,36,733,81,470,465,956,794,424,452,820,402,696,991,680,700,219,151,794,943,446,98,340,531,470,619,351,769,358", "438,662,386,486,176,502,2,933,381,359,927,486,978,284,702,85,159,751,317,837,829,602,726,48,745,771,541,377,827,44,290,893,999,873,176,29,40,525,626,864,333,94,863,224,222,914,23,443,984,11,506,371,90,203,525,295,775,788,564,438,681,896,725,860,985,934,916,362,854,14,840,391,564,341,326,20,124,335,209,27,723,511,899,687,748,743,204,521,284,804,340,334,675,264,416,249,415,254,487,535,550,612,821,204,693,776,476,707,839,560,757,654,502,283,163,4,110,275,892,834,483,247,20,629,247,673,767,70,755,10,367,93,451,933,866,223,679,398,544,401,684,940,868,917,877,46,618,230,152,59,589,70,208,597,233,743,392,953,460,704,275,378,874,885,908,779,493,476,972,437,187,186,146,572,317,597,814,399,671,32,431,726,366,881,261,528,465,951,297,671,757,551,50,61,629,464,915,594,593,245,59,166,163,365,937,401,55,244,334,555,793,31,340,935,808,577,9,264,224,858,419,320,234,413,571,585,990,833,151,70,963,753,300,42,895,927,543,302,292,508,357,365,833,132,690,871,548,287,1000,933,215,937,2,47,274,799,567,526,628,543,840,913,625,369,458,755,0,142,430,734,631,731,373,180,766,211,597,62,996,142,766,633,242,251,218,29,648,626,12,59,338,70,674,141,742,393,733,144,262,632,199,583,155,806,927,466,175,877,953,450,589,853,508,111,901,37,253,727,934,203,178,974,77,112,390,632,617,655,72,911,932,134,501,438,253,8,784,996,204,137,846,304,988,682,211,840,348,36,823,952,990,466,206,830,663,410,871,173,774,40,974,803,933,292,940,462,871,70,155,34,723,100,582,102,740,252,712,471,622,519,607,198,25,961,460,771,418,782,876,340,842,879,12,822,81,575,485,65,334,922,66,954,20,768,957,609,26,240,607,326,941,553,563,573,188,748,918,742,208,731,732,633,542,992,851,118,438,796,369,665,989,982,864,217,490,267,549,953,655,227,471,937,152,359,226,324,767,556,878,106,365,652,717,205,550,336,311,46,823,460,398,124,497,577,410,937,791,60,981,100,815,332,409,63,843,123,442,710,907,89,30,377,507,127,905,789,836,10,881,929,354,63,571,11,236,511,763,869,906,206,470,687,497,447,303,613,713,990,519,127,211,120,864,856,775,642,758,982,272,134,602,742,367,545,306,94,244,384,750,769,687,372,333,686,474,439,395,532,704,102,572,841,30,458,935,182,896,588,153,965,124,254,781,754,545,356,84,810,288,676,380,526,897,574,532,828,893,308,394,787,985,43,176,540,273,108,55,836,407,21,302,666,65,513,90,542,549,42,972,592,517,754,641,169,418,284,428,621,84,481,570,335,751,768,902,712,36,496,611,677,420,371,976,48,681,940,227,602,667,284,368,819,311,965,581,168,205,26,607,251,917,426,239,204,783,354,125,66,574,9,198,693,951,259,194,579,676,734,743,469,790,639,217,761,96,415,301,744,684,675,812,998,945,475,22,877,281,28,63,411,649,379,723,788,82,99,61,674,685,530,684,443,560,643,864,850,804,763,902,751,66,735,261,224,112,982,199,83,952,910,730,646,266,666,83,566,979,708,781,665,879,635,893,306,152,719,787,25,21,708,977,735,885,354,890,285,396,533,127,151,556,563,185,935,343,192,209,885,920,665,742,989,436,814,895,601,399,933,615,358,507,811,475,941,726,40,501,189,866,736,22,171,467,418,260,551,245,10,829,493,432,746,602,991,602,528,533,886,46,299,877,906,964,220,851,460,18,63,884,421,678,425,30,59,381,884,524,949,531,692,79,246,536,662,293,792,836,974,892,531,484,586,204,546,523,716,955,831,582,208,451,345,270,98,265,880,632,259,580,313,679,393,236,710,837,89,425,518,51,121,779,176,145,512,377,39,954,586,441,450,599,488,638,645,134,149,612,413,537,296,524,829,980,216,54,326,106,942,126,309,696,37,518,186,281,930,83,938,63,264,521,705,344,422,35,552,980,294,517,305,286,468,21,69,635,553,939,154,464,821,218,494,614,747,822,407,69,86,866,825,363,852,426,766,664,135,293,424,405,820,571,485,655,492,154,644,372,118,604,818,540,611,443,173,862,899,773,99,534,765,214,21,261,978,256,949,865,530,992,320,978,70,562,579,68,587,377,406,414,381,941,157,927,471,87,155,274,100,323,414,992,909,189,295,733,437,394,661,151,19,903,21,984,232,974,323,487,912,874,406,289,25,543,375,267,925,966,477,888,587", "604,714,823,991,98,745,815,753,38,763,990,824,583,321,590,890,598,272,426,52,832,24,619,97,200,787,364,344,426,912,841,791,286,873,707,340,541,393,309,135,889,933,710,370,84,793,556,431,165,538,875,238,213,767,623,551,87,378,850,919,146,230,800,593,696,135,11,881,424,829,730,773,258,16,171,876,451,185,940,830,377,979,211,819,390,376,724,435,123,980,63,586,604,902,322,265,316,306,23,790,957,523,362,720,532,483,125,611,912,217,605,471,364,997,234,815,378,863,58,293,478,820,927,412,403,589,38,262,482,560,985,740,5,541,816,473,330,843,208,282,358,425,662,468,4,213,849,613,246,690,690,162,328,423,61,135,362,600,757,490,912,971,259,990,894,968,618,368,199,969,489,481,228,791,50,189,455,349,765,919,7,950,874,48,295,270,745,584,163,197,532,341,569,549,227,118,241,160,647,813,969,833,790,502,73,212,961,521,437,466,991,443,954,550,472,738,430,262,814,479,402,121,160,887,241,108,351,485,881,240,140,971,956,893,450,328,117,387,589,139,123,575,472,958,780,935,846,765,257,590,782,496,438,748,539,55,944,99,891,417,432,767,707,681,503,265,142,0,617,259,123,138,137,853,470,909,242,50,733,591,724,472,895,843,727,51,585,552,124,239,482,127,593,778,15,148,49,119,650,458,423,230,367,62,38,151,797,903,24,342,368,669,318,933,897,101,918,880,528,757,221,4,867,95,919,709,809,347,673,119,753,100,735,248,542,749,915,411,55,203,546,916,253,379,580,206,915,242,538,654,952,708,685,893,689,678,597,803,883,785,418,773,341,452,339,616,504,239,363,826,410,435,924,849,996,646,245,268,142,952,713,401,940,183,962,417,319,420,58,584,214,922,970,936,912,287,61,56,581,821,282,525,433,642,681,74,785,924,184,968,328,934,434,242,177,201,736,262,232,31,592,308,66,44,584,358,410,111,414,458,283,904,196,300,497,60,723,922,720,334,973,662,713,253,669,141,420,661,27,520,435,443,64,759,967,705,833,504,890,875,997,614,638,560,940,597,677,332,43,664,626,645,595,999,104,976,716,355,404,837,354,799,962,733,303,351,17,490,140,849,841,631,233,553,920,529,923,756,755,309,359,764,850,619,949,416,771,951,535,496,946,518,967,817,452,767,745,482,762,656,93,297,959,658,829,915,525,206,558,733,203,511,716,838,653,418,315,51,172,628,158,304,158,903,334,800,880,640,460,815,13,829,892,823,767,961,967,743,448,885,907,353,449,155,650,980,654,676,608,634,433,181,878,512,542,867,849,763,611,936,888,723,917,379,799,722,340,598,877,51,960,171,175,869,621,669,351,114,465,911,302,32,800,801,690,993,293,549,751,451,407,146,540,105,94,595,694,576,36,909,645,843,398,221,743,965,609,283,969,677,353,449,100,647,117,680,906,156,544,667,582,234,308,796,299,957,380,863,492,246,497,923,994,175,938,922,789,269,378,85,177,340,806,990,743,662,475,876,612,434,719,795,98,974,503,648,868,754,762,154,715,68,713,478,606,173,35,325,506,952,157,160,836,991,639,510,894,664,974,897,390,796,964,900,852,945,141,499,289,180,723,104,41,729,550,509,65,548,931,220,392,419,380,465,809,725,636,291,597,761,54,617,181,389,315,820,738,980,155,279,103,978,581,367,70,734,551,347,530,537,170,823,538,964,797,402,573,415,610,49,412,975,827,876,83,752,392,285,842,95,183,629,770,280,341,182,515,912,634,154,423,94,285,227,228,920,55,594,564,147,818,107,773,287,649,308,338,422,806,391,509,314,742,974,329,333,821,233,584,862,37,299,389,968,766,670,533,515,363,181,811,452,309,710,456,112,211,236,926,452,783,886,200,67,949,702,697,95,788,290,108,231,528,759,256,988,965,22,703,586,264,487,933,327,350,741,41,785,776,992,88,380,877,354,92,71,153,832,586,360,60,825,974,538,185,607,982,284,571,628,619,618,532,459,697,484,980,515,373,277,298,403,248,821,101,494,197,921,3,87,852,472,654,254,556,44,501,432,714,973,939,989,798,492,364,816,17,917,492,255,280,364,935,449,925,847,729,666,928,518,738,82,277,984,540,578,335,527,496,153,599,693,93,506,93,379,358,176,129,435,502,70,359,362,137,224,644,528,762,600,59,682,452,232,630,813,452,96,777,281,320,302,638,170,744,736,124,799,57,941,5,277,448,431,119,903,134,106,242,58,29,305,802,91,265,2,269,11,350,921", "549,194,849,626,799,643,899,543,642,50,85,923,520,385,591,339,110,818,692,15,357,923,789,336,514,815,928,237,334,956,505,74,529,451,985,835,679,280,423,181,666,207,861,469,561,277,759,381,560,477,787,718,735,243,4,644,347,975,29,594,778,345,52,318,4,526,601,975,170,358,511,912,248,849,752,504,37,68,413,646,221,483,514,754,801,518,572,611,177,551,29,654,174,292,343,81,441,397,795,484,904,812,305,394,263,395,891,596,426,266,565,205,12,859,275,483,394,7,837,169,235,372,82,887,408,760,838,139,483,885,733,297,265,799,880,980,801,632,728,867,115,536,250,516,683,621,425,350,74,509,557,635,224,408,980,774,594,796,640,560,914,136,206,197,289,773,793,913,282,461,114,93,455,865,930,250,552,593,34,96,481,309,742,63,772,401,58,359,792,773,206,683,219,389,169,755,46,179,534,928,988,701,166,490,32,164,597,59,392,604,166,242,26,170,980,297,762,634,301,253,593,35,758,127,349,919,790,308,593,817,191,141,8,47,457,967,860,929,336,165,9,366,23,979,26,366,860,322,85,590,96,353,264,279,578,513,233,129,110,41,789,231,625,332,343,373,430,617,0,671,286,997,861,816,600,15,782,339,135,134,838,518,307,624,971,311,749,993,743,108,982,270,924,929,73,73,175,167,149,833,474,591,291,174,40,850,402,11,727,452,694,555,232,875,649,727,924,724,637,736,872,15,826,928,801,232,318,725,587,662,275,471,473,125,866,335,339,150,727,369,622,129,749,871,162,420,194,674,910,758,765,428,188,824,133,992,483,626,503,199,351,162,218,809,300,237,759,798,613,647,799,353,110,279,107,873,594,198,520,458,210,983,980,696,447,882,204,344,314,68,495,509,582,925,353,473,65,409,734,813,878,663,349,352,500,736,892,220,991,69,232,499,762,739,251,785,968,939,601,840,153,550,985,995,39,880,657,81,826,888,271,634,840,448,634,610,106,546,955,857,370,704,323,434,882,652,525,765,188,380,326,496,579,656,917,51,688,85,336,123,255,658,803,420,981,506,284,118,721,540,970,602,941,944,80,321,962,866,792,941,774,14,112,943,214,880,859,201,344,309,315,26,310,573,316,876,156,481,900,3,66,453,396,428,944,152,801,284,906,413,224,433,845,784,937,332,551,451,319,420,874,236,99,412,124,922,624,288,224,40,300,681,580,184,768,744,950,970,142,280,453,678,258,610,354,224,469,231,834,70,551,771,456,461,582,739,315,10,224,599,339,753,188,722,724,26,893,568,775,804,43,184,150,522,811,174,979,652,905,284,177,960,956,185,592,309,585,549,678,770,180,621,534,546,154,249,859,313,920,863,383,577,730,139,224,651,377,420,260,452,125,963,296,92,756,926,47,549,88,392,996,196,336,632,511,613,632,92,879,136,264,635,685,671,84,304,807,787,564,158,323,956,150,653,897,839,881,152,433,880,584,430,635,334,526,9,171,502,784,210,349,254,495,292,928,891,379,748,303,763,206,27,338,43,287,354,632,366,70,692,56,479,374,810,870,766,247,397,638,359,670,551,749,123,953,467,180,837,272,830,983,481,3,254,322,742,600,688,442,438,968,349,423,391,441,925,822,186,919,275,414,530,754,632,626,558,471,409,604,678,900,341,151,796,183,671,707,292,540,640,927,314,800,143,365,462,844,811,356,205,979,356,900,353,930,640,370,174,286,150,248,35,489,192,832,582,409,918,527,145,60,953,747,580,475,27,176,754,747,605,579,848,657,510,965,13,324,907,109,151,977,755,226,835,95,519,706,417,288,442,192,154,102,479,142,957,669,329,577,618,274,788,359,838,194,114,125,730,616,831,203,602,685,928,521,933,358,415,581,382,158,866,606,166,555,5,307,26,204,413,825,397,118,671,367,716,168,11,286,348,610,308,514,964,179,199,235,602,812,221,508,450,632,915,507,470,341,142,531,717,957,154,393,479,827,15,512,787,678,312,356,623,734,671,767,59,149,810,223,413,379,795,62,549,747,38,332,762,571,255,656,214,555,955,66,878,728,39,681,519,837,559,982,525,45,162,680,613,27,962,770,636,290,381,57,656,712,892,623,59,523,332,463,403,119,21,259,896,18,814,892,157,494,849,406,717,385,789,486,542,390,359,397,994,830,939,654,989,974,272,681,350,455,685,482,722,525,34,247,428,148,155,481,387,725,430,907,960,726,350,686,924,712,499,602,788,715,590,445,472,833,716,60,844,474,309,831,704,938,402", "921,853,784,301,394,656,790,631,764,85,958,926,677,469,36,371,594,480,305,664,568,444,565,381,197,733,668,672,291,30,220,972,234,515,410,709,464,101,12,248,321,216,779,619,586,790,87,144,329,303,604,896,305,434,4,24,169,375,103,886,612,76,266,784,15,349,415,144,739,656,603,238,28,365,298,684,490,684,269,606,360,767,276,213,540,347,440,355,829,936,349,886,293,839,252,236,318,16,355,322,3,215,659,904,348,16,280,27,174,297,9,462,593,945,123,167,850,494,970,133,123,682,164,494,933,248,977,976,278,758,432,876,19,272,210,746,36,442,952,960,592,967,234,756,982,380,497,357,111,855,696,300,63,955,671,460,902,965,948,53,3,909,718,518,376,128,341,265,955,839,216,83,374,14,241,615,848,170,467,367,76,693,977,975,195,791,942,722,717,801,680,577,438,226,321,350,520,782,247,506,506,318,806,98,274,732,102,153,214,677,71,796,483,624,521,197,21,99,395,203,864,390,851,711,520,539,956,947,530,442,432,149,153,256,122,97,654,798,208,601,842,376,905,819,411,831,614,390,313,610,499,153,31,620,589,401,108,885,82,802,447,340,702,486,972,309,734,259,671,0,143,352,503,466,926,447,609,281,10,104,693,605,450,177,184,914,260,787,440,926,608,250,985,683,978,731,850,363,767,873,180,401,456,32,529,237,817,331,426,814,161,795,293,631,702,576,968,360,87,366,164,882,441,949,375,8,240,441,932,31,882,791,127,961,494,453,269,382,626,959,463,986,450,608,156,616,979,495,712,184,111,56,769,88,378,775,10,89,274,874,902,20,651,108,263,773,731,470,3,150,33,114,220,511,386,488,72,646,594,496,778,181,987,227,857,743,884,719,724,557,88,941,494,708,779,155,885,134,162,256,743,90,6,118,57,124,727,909,404,825,103,746,450,896,863,257,795,80,651,723,484,407,591,923,668,584,587,502,691,370,310,78,530,774,140,174,749,861,829,905,625,738,421,413,972,2,386,895,997,786,433,937,72,535,777,573,689,887,860,370,941,606,831,444,193,400,275,103,4,370,815,475,572,615,286,827,819,950,605,74,790,204,837,653,200,565,18,980,236,895,516,337,121,760,421,675,575,910,195,808,828,666,558,286,821,875,54,757,471,738,458,709,616,816,818,966,490,355,450,238,337,891,236,309,573,275,515,983,691,429,91,230,505,921,6,213,161,375,922,942,566,340,822,166,7,128,904,123,404,704,965,355,64,494,400,795,924,709,899,289,870,50,850,645,287,398,470,641,240,202,430,904,607,673,796,645,610,776,949,685,782,136,971,639,333,575,397,592,827,520,623,40,729,48,627,585,581,976,64,601,848,280,653,267,339,952,242,881,692,881,31,535,17,234,130,591,844,96,523,858,885,719,933,747,398,469,820,134,102,13,781,714,420,754,549,748,310,242,903,779,777,630,764,360,877,532,420,596,944,744,92,595,368,328,519,629,250,315,776,241,514,492,465,274,148,551,896,137,89,173,626,771,297,721,187,468,386,187,299,799,249,974,638,723,101,69,585,576,803,165,250,939,144,271,864,846,46,27,710,170,78,483,487,472,209,847,795,63,867,440,793,219,720,231,437,62,49,959,42,421,664,195,905,669,558,835,287,301,951,636,898,112,477,902,930,585,542,809,729,271,884,343,80,462,115,687,800,729,47,194,573,832,565,728,85,196,499,831,182,88,779,626,43,377,58,250,780,670,159,363,726,840,332,956,458,101,872,685,209,77,861,91,735,517,671,972,282,752,638,275,724,127,886,349,941,109,553,923,121,832,959,448,656,92,774,447,395,389,979,330,19,709,947,487,404,117,913,666,471,751,214,64,167,260,271,897,380,723,274,645,479,339,99,323,635,137,273,328,535,373,158,797,296,783,920,480,644,295,892,977,196,328,835,968,666,869,251,48,532,828,257,326,999,988,64,252,933,979,660,775,215,743,987,174,436,407,105,960,883,968,285,715,583,316,49,463,427,658,478,585,118,606,247,641,894,576,399,347,530,730,550,98,743,852,655,504,579,657,554,276,665,958,287,21,488,7,616,1,841,359,11,734,622,718,19,565,830,845,508,597,583,160,687,663,68,982,576,92,223,601,867,990,264,96,965,476,990,67,219,784,292,491,137,719,900,340,170,636,226,52,743,718,510,401,762,173,610,39,626,40,417,889,298,463,450,21,231,867,113,407,930,103,313,9,584,963,163,932,854,924,780,711,274,795,392,277,173,676,606,84", "848,788,78,855,334,122,587,801,616,365,282,644,503,244,377,674,946,390,556,798,406,39,177,834,993,453,483,953,621,661,913,379,26,515,358,59,242,842,420,141,590,860,944,603,79,936,524,817,957,877,584,713,179,434,316,611,947,756,319,711,342,341,621,386,983,149,692,27,426,902,131,904,78,465,538,339,205,367,690,620,808,6,798,462,549,562,355,775,666,29,318,712,983,379,114,539,469,202,276,441,424,324,780,389,696,888,369,815,910,52,570,231,869,590,986,631,636,273,42,708,21,687,266,408,780,200,328,767,273,833,102,608,618,979,314,859,709,898,834,959,321,891,829,425,191,788,179,988,948,419,684,164,122,48,753,208,355,387,359,828,742,750,723,863,89,639,773,45,778,700,832,831,170,963,374,755,367,380,329,152,894,992,185,862,183,722,483,777,344,742,751,412,818,415,232,58,215,329,551,582,692,928,454,169,262,65,137,225,830,588,885,634,382,185,490,496,787,322,790,347,172,330,909,80,731,158,650,500,712,293,299,585,320,417,424,283,787,717,489,655,584,423,430,85,951,157,992,124,5,385,784,234,333,875,792,204,831,446,27,378,237,237,632,608,201,695,631,123,286,143,0,547,596,409,514,971,283,449,371,731,669,44,7,712,380,965,824,804,628,984,890,215,820,702,724,435,539,189,653,346,509,835,332,167,654,277,748,512,265,575,546,784,568,840,693,601,774,79,665,30,774,676,562,538,651,477,184,12,86,170,556,109,396,388,496,449,701,163,735,400,241,386,620,146,310,472,994,493,954,930,641,230,190,643,263,930,577,967,656,50,565,928,231,118,882,848,39,157,471,925,18,325,325,383,632,68,599,227,558,663,703,288,510,746,680,36,728,982,723,27,540,902,563,364,489,543,892,613,869,739,863,750,881,463,570,803,903,922,218,490,427,282,671,159,743,921,994,979,265,111,718,753,840,790,212,375,249,425,214,852,464,657,318,584,40,583,699,759,79,69,87,431,457,80,301,989,474,689,529,399,989,228,309,764,983,848,388,687,702,251,246,86,794,428,564,204,581,847,630,844,416,435,406,626,93,857,998,437,440,433,403,914,160,990,915,236,428,148,378,291,338,80,478,136,211,823,935,564,148,951,923,479,159,254,66,779,429,263,828,58,965,256,42,863,289,21,599,468,398,22,400,101,907,650,155,599,774,240,255,284,319,909,330,579,503,306,962,555,930,799,785,231,598,415,296,388,693,138,589,7,284,570,822,271,826,277,189,880,822,484,468,834,969,901,801,520,308,545,493,13,171,758,505,105,412,579,857,16,507,663,564,602,443,607,837,993,378,523,111,386,763,804,292,55,912,764,37,648,966,579,825,257,603,890,610,549,106,51,246,556,818,22,110,487,533,126,87,550,702,178,260,478,669,678,211,79,82,41,403,181,689,525,758,293,888,248,5,197,445,536,261,277,663,398,103,861,805,573,515,401,931,865,499,319,149,643,921,612,123,308,64,437,355,826,311,402,685,70,634,603,294,22,63,271,61,542,988,298,736,952,730,953,605,17,623,7,247,623,369,145,567,447,271,201,576,424,898,479,160,568,153,931,438,336,538,813,770,772,537,166,730,4,75,962,163,23,371,380,677,620,10,281,710,681,859,234,311,379,879,341,183,907,778,959,279,469,964,715,816,718,954,613,742,175,172,600,553,389,906,377,757,208,888,461,55,875,147,738,988,164,868,119,864,459,338,263,150,679,485,645,797,704,388,953,701,681,620,477,523,382,977,568,82,892,333,606,889,963,689,741,646,915,118,10,655,907,173,929,881,831,684,943,811,419,909,385,574,353,492,408,518,914,300,550,722,932,341,288,681,847,263,302,294,409,116,402,735,341,934,718,235,786,928,912,16,69,320,350,245,198,602,774,402,672,329,469,266,767,220,352,546,335,302,357,204,367,85,799,902,227,563,346,221,227,86,325,702,794,632,159,272,395,320,796,20,533,66,121,116,850,473,324,8,159,943,161,426,762,553,847,751,809,643,23,246,384,151,177,867,450,22,969,807,395,150,419,290,259,884,544,546,723,63,578,256,633,632,280,306,111,127,919,384,656,939,834,43,386,564,260,891,162,196,603,62,142,734,177,914,186,424,686,416,958,395,296,655,21,38,873,980,326,81,823,989,545,40,478,63,162,405,282,662,597,266,564,803,401,352,197,335,998,649,700,433,875,737,276,34,666,940,269,239,350,704,418,329,419,599,440,944,334,662,575,104,364,712,637,550,784", "918,359,850,974,620,190,494,419,286,77,810,497,325,767,705,685,969,257,259,220,494,970,903,729,280,111,327,551,78,152,299,812,32,747,385,364,719,108,643,170,210,295,106,780,944,846,100,604,790,192,373,412,820,534,414,644,658,277,807,391,667,714,87,918,551,957,290,736,31,75,55,941,618,535,425,396,278,480,871,421,890,348,267,550,53,634,70,683,396,110,832,276,397,624,393,146,963,479,362,708,237,937,887,573,877,787,27,271,818,167,367,774,851,45,459,198,207,962,550,201,668,207,564,618,706,653,812,833,350,848,170,160,673,404,268,23,799,845,295,688,26,206,475,811,173,436,442,666,200,496,579,303,490,475,321,96,812,655,269,569,609,296,810,95,900,887,214,162,358,499,184,48,165,481,583,734,772,142,56,116,691,646,51,938,991,277,598,453,118,782,821,391,813,573,743,541,89,865,148,957,199,617,93,981,897,910,299,470,772,891,79,439,963,30,143,248,558,955,671,371,838,354,10,599,280,23,703,748,485,526,21,291,451,495,829,70,337,351,393,430,52,71,829,609,676,325,621,977,863,979,131,239,960,132,642,313,787,621,463,694,293,251,490,817,118,268,731,138,997,352,547,0,599,538,771,176,780,864,870,15,843,743,391,965,578,742,951,523,210,294,745,38,643,399,783,534,970,730,451,812,328,346,407,309,271,478,252,448,35,525,898,403,368,693,515,842,32,166,200,259,649,556,928,120,86,779,996,94,701,542,190,774,652,844,635,727,911,351,790,651,973,100,428,212,226,935,135,651,853,214,648,431,793,384,841,952,235,489,291,565,235,616,671,304,65,796,84,974,420,281,652,549,108,917,897,25,927,724,51,388,743,939,917,388,390,820,977,455,934,133,983,362,988,17,366,2,886,639,871,908,792,44,974,498,753,203,171,688,243,609,234,777,738,800,751,339,45,252,144,879,348,164,212,851,446,553,143,857,531,748,746,646,219,838,548,443,33,170,377,677,3,958,263,747,799,363,988,188,526,949,186,966,143,7,416,281,297,67,43,584,240,454,362,397,562,206,904,385,251,455,518,849,269,627,519,880,386,776,788,478,527,524,625,503,533,166,600,805,545,468,46,917,881,352,633,133,196,606,178,261,687,435,741,195,879,554,677,421,689,60,128,546,333,684,110,646,997,71,722,132,653,260,681,256,408,818,975,536,535,759,672,726,69,237,511,230,940,814,973,962,404,762,122,855,297,813,851,213,326,693,297,369,35,480,276,762,379,720,534,902,746,454,234,585,759,964,586,940,457,465,378,804,959,868,3,251,583,540,389,876,126,137,282,576,778,884,998,550,279,989,746,176,931,469,452,307,957,529,289,698,776,66,807,632,657,914,648,721,202,839,199,730,725,456,918,622,923,526,110,284,56,896,543,834,626,802,721,318,700,994,275,779,676,523,624,526,409,204,375,392,305,327,994,813,869,355,634,627,655,953,400,597,611,557,331,223,934,948,524,888,697,913,278,571,371,881,373,147,329,874,771,303,516,909,307,657,273,141,774,78,552,224,778,18,413,191,649,461,18,344,91,545,725,824,276,641,727,34,512,535,502,566,94,136,539,398,135,22,580,173,470,931,136,324,209,466,284,15,395,149,960,509,223,736,850,53,442,296,239,129,316,437,438,806,86,55,664,113,522,565,603,117,775,605,230,838,833,38,623,90,189,898,975,6,852,21,79,703,543,494,767,689,585,763,286,593,591,602,375,387,383,475,611,658,98,750,246,32,319,4,690,477,33,891,826,875,102,74,343,540,465,902,501,709,343,245,766,178,597,618,687,553,413,278,286,813,458,443,469,319,706,727,328,216,862,759,50,446,47,611,239,74,488,107,286,53,352,872,745,515,551,385,225,512,190,317,120,638,433,663,48,159,14,994,40,273,613,488,484,487,482,399,777,511,95,635,198,383,613,275,94,489,135,702,187,774,844,649,172,394,391,572,371,164,260,896,228,320,154,777,241,142,471,370,529,112,930,988,686,235,850,503,351,425,573,722,691,183,605,838,969,985,488,238,615,351,421,843,207,508,713,984,603,187,889,469,604,310,395,6,486,193,194,356,60,579,141,252,371,160,198,650,781,771,97,548,28,611,731,609,732,269,89,403,815,290,202,735,920,620,276,956,953,32,74,822,799,28,476,438,220,419,318,270,881,564,916,299,737,305,357,816,604,738,826,983,145,653,484,31,993,789,33,830,351,439,913,696,831,879,697,442,662,980,707,633,62,140,343,180", "694,355,855,793,956,543,813,164,278,821,146,194,244,950,380,664,862,661,827,379,343,803,808,820,880,895,704,983,635,346,349,328,47,394,237,850,89,366,860,962,910,748,322,73,243,947,114,239,458,686,83,38,764,811,423,642,120,940,180,831,336,375,527,649,984,399,893,848,129,899,785,842,512,544,875,62,187,559,164,85,371,485,168,772,350,19,148,708,814,60,704,467,56,872,64,647,6,133,723,537,135,393,922,645,339,619,136,76,816,171,659,142,836,560,939,939,718,61,885,694,200,583,851,338,532,690,139,744,180,774,303,331,518,431,511,728,123,912,272,437,614,870,536,393,725,424,632,49,495,12,607,755,516,444,986,260,755,474,14,352,371,7,883,430,8,680,578,946,583,247,637,888,159,349,602,623,90,861,577,228,712,936,212,643,951,81,180,218,746,70,949,498,268,876,519,979,525,336,584,199,128,996,300,830,637,574,151,599,837,67,264,202,207,674,739,739,308,389,459,315,934,234,793,898,992,948,712,625,328,553,923,59,968,282,370,43,635,241,570,149,562,777,760,814,432,574,433,468,941,260,721,838,223,133,883,395,463,432,573,362,529,387,65,744,964,625,373,137,861,503,596,599,0,101,816,66,689,747,211,322,993,932,157,247,626,364,920,294,763,439,512,594,443,204,135,769,689,249,881,589,50,798,246,420,734,943,141,2,219,626,68,742,370,596,528,817,475,365,727,442,706,989,203,118,287,866,705,644,561,588,807,677,885,195,970,615,453,782,432,313,281,857,522,960,865,75,379,732,926,795,352,633,100,197,882,87,666,543,734,980,531,618,4,116,395,686,202,68,554,228,627,513,473,314,226,735,100,408,108,128,614,409,502,727,989,6,978,50,833,774,16,5,595,720,729,603,352,663,934,164,215,857,588,243,599,292,9,542,505,501,683,857,334,884,610,896,599,124,303,172,864,946,919,114,36,563,968,202,956,982,587,368,827,912,319,224,385,794,614,101,394,207,701,334,563,909,47,202,113,657,355,400,677,1000,101,901,400,898,466,36,671,499,96,908,736,353,860,197,28,2,401,183,162,233,409,989,286,543,633,131,849,638,715,381,396,847,840,107,973,704,238,514,243,32,634,26,447,882,523,962,899,836,159,36,705,217,238,765,906,38,593,160,105,722,665,339,549,790,174,70,169,481,390,56,31,430,473,769,204,782,728,287,799,225,698,633,234,640,645,747,984,452,712,376,51,740,14,847,99,904,340,281,520,803,62,849,937,668,714,479,75,505,816,384,824,36,68,581,164,749,802,310,206,946,337,555,303,447,647,399,359,165,447,672,988,814,644,427,310,291,382,863,535,381,787,865,399,864,492,140,678,722,343,554,168,121,448,879,353,601,521,132,83,825,800,714,604,325,962,673,990,899,834,998,584,186,776,451,9,123,931,735,168,250,524,723,418,886,79,333,545,433,835,943,631,24,818,270,607,604,364,353,881,162,587,872,406,405,411,24,848,141,602,709,667,843,675,404,324,808,448,999,140,966,781,846,751,849,817,193,970,829,423,606,927,784,497,501,403,715,78,282,317,592,339,202,203,622,161,186,504,224,385,941,943,633,706,388,569,2,868,636,654,393,467,471,971,915,827,954,98,295,651,365,237,346,285,964,608,548,569,775,592,619,41,557,150,500,14,266,882,220,526,932,346,874,990,218,887,679,51,209,639,908,637,189,652,544,938,78,418,369,244,255,925,640,349,782,835,311,553,179,208,213,326,907,842,546,823,233,724,788,45,548,163,462,169,798,315,55,215,775,812,106,441,218,745,104,122,611,807,720,421,721,515,605,303,66,857,783,886,232,338,676,438,79,681,424,819,860,759,19,841,35,345,400,846,352,942,841,644,239,622,579,811,320,844,587,870,276,189,581,249,272,31,128,925,251,608,180,301,366,989,717,850,648,585,966,463,113,991,953,965,211,184,397,798,709,990,455,12,871,614,705,983,118,924,314,173,38,939,461,849,404,701,515,634,986,712,703,731,515,107,878,642,502,382,897,312,811,198,729,799,70,37,632,297,643,106,594,442,366,601,13,521,316,562,926,237,644,397,306,327,992,375,650,497,637,127,855,154,694,47,56,883,161,45,123,278,909,8,868,909,382,844,1000,716,802,297,305,880,209,554,853,121,690,410,834,856,257,142,646,656,516,654,128,150,160,248,80,446,307,827,680,652,541,564,764,892,772,939,856,408,665,127,872,11,917,634,914,275,683,694,940,141,827,794,758,154,491", "512,944,107,135,45,340,65,442,43,660,859,335,18,123,105,738,566,934,64,419,206,54,631,333,859,484,527,122,411,431,416,682,483,334,141,643,992,91,885,10,505,556,853,897,261,26,793,817,140,505,258,581,338,378,120,786,642,320,57,884,842,104,37,145,632,891,347,248,377,240,57,626,280,695,221,68,335,931,639,245,268,37,852,785,480,25,523,140,775,187,456,763,299,949,86,341,114,7,15,81,93,466,346,180,757,905,692,645,823,450,787,473,561,961,780,201,554,497,240,565,636,378,54,246,628,958,108,778,311,885,36,971,107,438,321,350,773,779,23,515,604,768,613,404,995,883,155,958,748,444,747,310,51,223,904,865,387,268,954,693,667,753,635,898,973,619,882,541,891,480,195,95,220,271,915,538,754,836,646,624,226,346,739,379,486,371,372,738,500,649,8,478,263,658,849,502,321,215,462,66,859,615,222,873,751,723,11,245,829,380,926,297,5,941,412,905,921,70,555,900,386,879,377,181,313,904,31,135,58,451,74,514,609,936,778,851,156,971,453,491,907,62,578,673,406,181,966,180,381,924,128,951,985,443,841,393,639,317,521,63,378,735,167,871,194,348,180,853,816,466,409,538,101,0,799,916,693,649,316,477,464,835,767,994,676,868,304,800,756,700,127,618,96,870,370,376,50,830,542,6,575,215,774,853,515,179,344,391,891,795,614,881,134,752,849,534,89,676,837,998,100,631,42,842,948,81,600,666,190,447,515,483,205,213,930,380,634,102,872,283,995,926,450,674,807,628,707,920,192,27,193,667,474,511,144,164,558,945,528,485,610,308,431,504,606,640,535,498,60,359,696,669,59,55,307,562,880,706,623,663,3,342,765,157,869,985,686,694,345,587,482,601,159,169,177,713,848,256,451,767,302,327,275,162,2,280,894,833,845,601,272,847,719,622,539,973,425,275,514,151,375,441,469,899,754,374,585,231,194,778,509,833,166,834,914,130,882,915,230,664,344,876,423,494,435,761,198,901,502,739,137,932,588,630,362,932,127,470,335,505,302,168,596,458,827,392,321,192,897,263,135,244,619,811,301,446,750,738,396,357,846,674,592,879,182,956,608,415,112,201,389,225,33,471,266,399,140,747,775,845,594,545,236,182,254,625,964,416,683,464,634,826,505,139,274,816,745,87,628,636,69,3,392,296,758,83,666,937,692,354,900,607,514,26,91,201,975,531,567,672,918,347,302,881,466,924,7,655,434,60,314,513,583,481,211,525,977,432,849,465,546,902,733,857,814,654,896,526,619,422,531,722,151,115,43,29,388,783,406,812,628,79,507,655,289,157,609,1000,827,956,580,133,578,369,934,529,585,864,470,957,912,39,359,533,530,461,204,399,190,184,879,276,931,485,396,557,557,910,140,557,936,651,817,199,726,97,672,883,62,963,602,347,933,305,793,176,632,9,809,895,138,558,629,769,727,24,117,932,569,607,498,942,911,119,815,755,809,297,632,278,98,960,924,98,862,342,758,533,739,708,431,184,304,783,868,486,682,608,535,797,280,634,549,962,948,175,216,91,624,320,309,295,435,172,156,38,593,842,142,584,995,107,983,755,785,447,301,382,287,786,510,304,976,526,2,621,847,635,853,510,416,455,105,854,768,305,318,115,430,898,645,627,115,484,365,668,338,378,229,874,787,545,776,598,721,524,69,961,28,525,909,909,476,977,176,831,745,405,529,602,85,830,745,397,451,357,366,316,807,814,607,482,173,308,820,119,708,912,17,862,679,496,741,427,76,860,354,98,180,818,755,852,272,782,635,503,414,771,711,633,634,108,802,482,93,792,418,885,930,136,251,72,174,354,952,574,139,276,949,279,527,908,215,538,343,685,616,901,729,680,388,680,262,65,38,830,987,440,829,466,650,676,867,486,847,748,55,52,631,376,13,187,265,9,637,713,265,648,664,289,787,479,560,124,868,791,175,182,430,996,451,102,734,191,644,348,701,159,724,546,860,154,829,545,570,331,832,793,650,90,123,918,549,400,17,238,286,44,194,769,480,535,70,900,191,12,128,955,271,6,896,695,765,82,866,135,793,478,396,754,377,899,548,264,516,468,762,409,270,483,350,873,144,847,143,510,763,566,798,186,916,675,493,590,201,178,894,112,64,324,481,238,162,684,708,793,574,546,302,132,814,214,874,532,577,589,228,163,801,699,664,330,762,848,584,287,90,982,110,760,438,971,44,700,418,132,962,741,916,822,829,812,242,693,696,95,537,856,840,220", "390,781,868,183,119,552,477,419,471,782,375,471,482,635,479,867,224,137,367,846,323,340,988,304,749,523,337,382,988,420,545,815,958,660,939,463,881,974,414,85,274,305,120,528,548,911,221,797,571,385,512,109,775,511,498,284,534,768,256,18,797,341,375,327,352,429,810,819,399,650,335,775,592,85,130,556,951,528,920,934,462,499,923,857,183,707,747,535,611,985,573,628,134,487,175,263,76,737,850,595,823,293,799,201,861,345,451,980,717,239,139,255,420,755,593,457,298,170,568,939,134,44,681,584,48,131,284,894,206,15,899,657,440,162,407,253,786,248,98,548,896,263,294,293,964,472,514,940,867,39,510,62,627,727,203,286,412,86,377,318,386,660,963,491,232,173,623,238,385,865,706,330,429,139,409,947,825,676,836,221,533,41,36,24,792,987,177,428,24,412,629,432,893,903,698,800,503,59,808,502,992,624,557,945,721,135,399,186,160,811,771,539,32,183,256,319,729,428,846,926,390,426,174,704,907,627,528,498,245,340,701,698,623,172,562,106,391,803,490,500,681,738,618,373,670,952,859,50,953,245,410,582,721,21,920,332,86,196,644,134,353,693,472,759,339,496,766,470,600,926,514,771,816,799,0,551,561,65,793,333,190,292,90,76,737,555,55,397,628,196,53,701,248,738,202,575,903,733,988,220,815,122,163,881,838,419,158,172,32,673,431,742,20,978,258,692,459,873,681,166,937,193,182,499,909,147,737,484,643,812,118,598,982,88,4,944,212,36,378,460,59,988,360,144,823,799,874,96,878,707,490,576,812,58,562,866,831,611,552,266,931,82,753,770,120,866,615,469,934,397,668,925,713,198,905,195,759,857,907,238,494,359,139,171,435,806,338,282,2,700,925,925,750,166,975,198,145,458,772,375,779,461,661,582,476,563,565,97,941,991,807,412,914,532,479,691,406,95,138,231,578,373,987,762,431,891,143,847,410,119,302,98,80,615,552,397,710,22,56,291,833,752,670,314,317,291,953,111,778,36,815,922,721,721,138,489,841,532,819,746,26,412,213,63,232,158,65,835,647,505,546,224,792,189,223,64,889,586,155,15,298,339,997,910,713,879,639,459,30,331,922,654,237,800,226,517,62,886,793,184,328,817,462,788,934,850,848,526,483,218,204,960,492,107,915,240,697,792,738,54,960,645,880,399,210,981,766,28,898,479,697,876,137,520,742,368,791,286,617,312,663,706,674,493,582,295,341,996,657,327,697,168,996,442,371,983,987,367,289,46,166,901,297,520,697,47,312,419,673,216,467,249,547,398,14,896,308,729,225,802,747,281,123,336,358,213,939,606,745,367,559,859,652,371,160,445,822,79,870,316,452,221,126,575,986,99,90,777,836,506,409,915,895,979,843,356,557,691,498,283,721,187,585,324,512,470,74,976,63,581,213,840,824,31,327,545,383,889,852,346,848,626,120,123,627,497,316,657,583,586,911,143,768,259,742,386,438,133,874,442,486,424,412,630,600,926,817,858,945,987,475,1,518,847,282,665,586,344,306,726,47,325,940,693,203,772,489,3,279,409,655,274,796,185,320,165,388,92,496,458,778,491,180,841,561,465,208,268,229,102,567,105,221,882,781,327,150,92,130,792,468,872,341,370,548,291,410,317,81,214,512,933,220,12,872,164,59,570,1000,105,876,228,576,181,425,992,722,194,919,170,480,36,286,96,720,547,562,454,164,343,374,661,277,284,601,378,522,37,446,751,419,749,886,508,812,331,210,878,909,114,384,500,697,425,389,243,69,532,382,6,491,69,406,374,816,487,118,285,301,641,306,945,916,860,804,111,574,588,183,76,750,610,208,385,892,770,284,678,345,660,722,923,509,743,147,825,812,64,108,214,161,72,902,267,263,707,465,677,925,904,613,996,109,518,358,835,400,653,951,525,478,648,200,149,935,569,316,121,871,959,419,532,514,203,827,606,992,903,21,738,816,801,608,425,123,407,962,116,268,36,317,514,217,941,22,885,767,71,303,302,945,786,229,272,138,716,856,261,809,940,847,672,167,721,926,76,614,158,757,445,642,980,805,700,250,44,549,16,199,740,789,762,181,112,187,640,486,646,150,203,354,168,96,744,986,704,692,222,62,728,355,893,930,482,468,557,498,144,5,797,555,778,719,402,696,276,980,440,987,453,453,140,991,734,925,525,936,749,898,51,520,121,662,86,687,536,510,626,929,240,941,46,161,687,215,411,681,123,297,570,834,212,198,73,653,269,590,888,652,957", "913,907,269,768,527,360,543,916,258,662,634,855,447,871,291,168,416,990,789,269,882,746,940,352,532,582,57,77,590,275,5,995,302,601,658,66,300,265,364,5,283,673,648,406,661,872,555,299,730,606,936,370,74,91,766,190,179,459,935,407,943,201,635,279,745,496,607,554,138,894,2,753,149,553,660,110,165,282,567,694,916,921,270,897,4,467,439,934,544,818,806,191,499,253,997,229,448,469,255,123,425,958,929,609,276,685,256,965,304,90,582,800,666,346,523,278,722,666,258,257,300,744,2,118,66,404,803,496,536,76,328,247,492,754,390,590,192,8,825,520,202,389,165,448,597,212,4,157,411,228,810,426,105,382,124,220,959,975,982,804,799,719,407,395,260,678,832,972,319,771,989,286,115,752,15,244,196,492,541,369,58,617,660,617,392,667,724,299,389,704,840,340,678,160,627,925,806,728,663,859,212,739,40,9,943,948,852,776,881,190,635,685,707,751,606,504,544,526,332,982,723,849,433,77,959,165,640,832,952,729,711,666,875,523,475,637,918,208,700,47,697,430,934,445,653,951,255,741,840,260,305,346,458,155,875,721,888,175,255,732,886,981,293,721,48,787,211,909,15,447,971,176,66,916,551,0,737,544,136,250,200,669,30,511,325,94,138,710,705,324,862,457,811,790,981,684,976,248,732,886,420,4,274,808,469,721,291,546,869,317,185,788,278,239,692,212,468,443,116,790,710,795,215,962,156,530,220,323,9,649,681,25,61,449,883,866,327,323,434,975,314,672,208,156,976,676,329,617,27,693,156,705,579,646,673,183,293,432,840,266,122,184,410,617,66,458,721,599,841,610,617,582,572,491,292,70,445,577,735,209,779,465,794,369,886,286,847,835,41,69,386,231,178,812,443,155,5,143,573,498,293,699,362,654,603,974,523,161,76,824,279,427,866,827,970,705,702,446,753,422,786,788,388,853,462,840,921,307,638,199,943,383,596,676,825,281,48,365,763,458,562,728,999,835,14,125,123,59,230,1,223,771,485,74,466,137,318,837,782,33,347,749,90,293,641,440,188,517,551,900,560,511,442,702,118,207,773,804,839,481,543,379,303,673,177,809,603,552,895,948,657,976,677,346,183,115,549,72,292,424,435,597,192,228,727,286,742,869,11,662,517,322,173,548,600,484,725,465,199,351,594,777,376,265,991,411,773,562,18,748,865,624,259,94,807,689,40,138,371,821,816,84,271,590,984,283,254,683,558,670,969,320,530,499,898,869,939,498,838,770,604,952,753,667,566,603,51,774,53,357,426,450,692,922,763,355,655,438,838,54,791,715,207,256,79,427,754,605,416,455,946,223,219,764,724,565,796,24,835,274,337,856,118,718,133,481,360,240,38,916,58,778,967,116,832,376,592,98,164,190,949,537,225,919,932,194,9,211,814,127,217,329,558,886,818,989,966,227,982,296,114,52,537,49,975,871,332,738,833,736,840,848,489,255,257,585,105,427,545,557,664,624,48,78,473,549,337,336,406,549,516,301,299,937,126,682,977,355,959,829,106,392,95,201,53,756,733,382,383,365,270,533,37,375,529,401,810,70,766,892,589,934,209,255,930,927,597,929,397,857,515,918,111,725,795,265,40,79,887,229,529,74,226,473,586,730,221,375,704,903,201,479,778,193,807,854,36,379,186,990,182,147,374,855,60,617,385,631,877,449,871,660,388,823,552,660,29,803,268,808,288,108,600,671,475,568,265,383,357,493,590,263,578,207,904,105,420,489,974,168,378,584,864,78,599,748,267,580,764,574,460,598,360,375,198,457,705,866,506,505,782,41,561,105,589,634,884,192,117,646,376,809,496,934,32,435,274,663,246,970,479,15,713,757,224,967,967,627,938,416,545,379,208,273,526,38,275,454,680,807,796,975,1,735,875,602,511,546,327,380,659,472,895,139,40,393,649,305,307,126,636,10,437,927,787,925,290,772,94,167,266,966,186,275,873,701,656,189,571,450,120,919,333,73,107,313,553,503,916,476,692,935,639,936,810,140,926,178,414,728,298,680,822,601,661,369,8,259,443,976,167,475,56,740,472,405,437,728,911,98,225,385,726,184,555,963,628,690,163,641,273,804,118,779,93,614,862,305,307,125,894,371,848,774,393,534,801,323,346,674,478,101,387,498,549,819,214,436,455,563,172,253,732,476,435,594,399,134,504,331,307,136,723,879,375,785,8,180,343,973,901,511,500,774,600,42,57,746,72,34,562,905,942,638,265,732,981,880,99,260", "118,520,162,746,444,441,874,736,732,468,189,326,694,405,745,819,385,647,280,463,945,187,326,445,433,692,400,573,445,670,3,484,12,775,145,584,474,982,649,531,271,961,675,579,801,39,525,534,568,983,197,753,496,477,630,90,362,812,71,585,943,914,333,97,122,178,917,537,205,757,395,318,431,351,517,82,141,675,92,231,992,422,920,470,893,833,749,778,913,727,507,600,893,838,95,48,995,697,542,491,535,235,136,725,639,380,93,989,601,951,466,288,111,677,537,291,827,541,364,401,756,287,535,258,368,406,469,870,765,630,633,362,784,116,558,414,960,965,705,279,306,640,367,828,491,188,921,330,900,410,375,298,290,464,524,207,182,948,818,310,453,189,150,183,723,620,515,405,548,899,987,326,276,974,744,279,812,40,58,504,793,808,718,814,957,836,579,489,529,525,617,115,99,586,78,922,906,847,276,147,923,214,341,334,561,356,582,627,188,9,235,851,815,906,848,55,570,420,873,537,580,248,654,549,26,306,424,115,614,932,796,897,637,40,925,812,228,199,329,729,836,553,249,497,930,241,211,508,685,809,566,871,59,975,73,117,487,672,721,296,859,356,825,45,403,882,597,242,782,609,283,780,689,693,561,737,0,220,994,17,903,207,123,755,357,28,630,134,977,592,584,556,478,873,382,156,626,599,480,958,354,760,517,331,239,735,803,412,556,237,391,768,296,343,994,971,804,527,582,573,905,620,919,79,563,882,508,506,168,533,904,649,192,765,751,498,986,827,937,220,645,624,618,308,353,733,749,542,648,155,323,377,212,57,562,778,708,913,403,876,449,234,494,922,749,453,810,561,988,377,615,407,701,84,37,296,998,483,508,846,236,376,620,388,415,210,808,345,344,732,270,853,917,927,121,117,971,74,693,14,341,192,587,925,919,645,853,110,817,837,169,556,889,235,647,735,277,230,550,460,254,56,956,942,143,28,281,588,150,407,83,212,577,132,707,376,468,486,637,609,664,123,772,371,541,343,672,309,588,122,596,212,478,29,161,394,447,835,43,855,549,213,995,980,412,650,613,484,604,320,988,564,621,831,99,419,278,897,57,491,242,233,869,815,714,983,890,243,559,403,31,798,628,37,694,680,622,328,770,397,909,434,908,326,329,421,804,162,631,306,712,865,625,915,114,735,444,716,719,462,261,57,779,194,142,500,751,970,239,858,736,581,31,179,189,75,938,34,560,748,588,403,18,260,937,35,550,690,248,467,879,496,263,795,895,977,326,445,682,974,139,806,161,382,502,771,919,438,404,604,208,25,801,914,713,618,26,134,403,370,287,706,805,282,43,49,222,550,105,566,753,611,608,149,215,536,710,163,765,917,766,318,326,822,360,492,122,589,425,200,964,565,310,405,918,916,75,736,237,37,187,786,207,359,379,129,192,262,630,743,509,140,846,402,62,899,548,686,619,166,190,324,850,174,657,42,63,562,305,242,118,900,454,218,629,901,290,464,59,720,442,656,624,545,106,164,347,786,605,836,905,662,360,104,204,401,440,444,297,101,878,165,218,635,955,523,721,266,98,128,149,921,613,665,593,149,125,685,254,982,759,491,587,90,932,115,971,892,784,484,206,562,746,948,147,244,471,426,525,782,687,670,758,51,357,96,774,976,3,884,172,724,475,364,953,377,968,998,990,856,657,973,82,197,779,796,192,549,976,780,756,912,996,363,650,791,624,641,450,342,297,910,77,849,381,169,712,200,106,261,117,345,835,866,72,358,730,504,773,919,683,241,143,698,341,221,116,750,799,143,641,274,405,714,514,81,602,739,587,571,246,682,485,273,961,25,837,147,132,942,335,206,228,705,738,50,149,878,917,342,754,630,634,793,303,66,325,370,534,840,456,286,159,990,515,776,242,180,763,690,876,707,979,473,179,923,4,675,23,897,408,992,284,546,181,832,73,922,728,56,953,877,43,633,348,502,802,127,282,946,708,4,343,590,836,469,710,608,297,640,581,419,400,962,278,736,170,968,636,624,360,532,98,827,609,993,496,653,995,724,454,918,649,121,580,643,949,562,152,503,519,511,796,455,412,85,163,280,824,871,597,341,281,35,62,110,270,434,310,808,185,513,244,482,752,813,219,519,410,103,222,130,338,649,253,796,633,812,742,231,441,950,382,329,730,564,704,806,316,473,772,52,838,876,231,25,979,926,91,842,856,642,633,563,269,359,433,540,411,181,806,405,330,775,433,989,561,242,370,33,116,421,473,16,884,502,904,669,133,207", "776,52,197,162,102,988,356,57,57,724,387,189,887,57,326,811,108,710,473,25,564,292,844,444,763,390,3,473,392,708,494,538,580,21,803,612,717,857,151,850,236,952,346,400,277,137,846,334,628,160,639,538,623,34,605,974,401,837,830,236,191,653,268,478,667,488,529,36,196,565,636,88,972,31,139,93,442,940,606,306,34,53,565,65,404,928,623,699,550,206,732,53,661,411,16,777,873,626,56,414,409,842,919,316,966,645,237,961,996,92,604,139,358,495,177,662,692,234,802,45,929,78,468,657,982,113,589,393,181,92,374,889,73,269,221,202,983,142,751,994,639,100,974,550,975,811,516,772,617,366,272,232,46,667,904,462,550,871,324,85,561,57,247,128,130,899,113,356,854,99,61,288,449,737,143,330,700,42,688,166,447,26,387,285,397,385,990,720,644,286,155,822,620,903,512,591,437,957,486,98,618,403,872,382,420,210,839,901,118,179,566,107,112,406,360,829,685,667,716,15,596,354,407,667,918,102,273,30,692,723,40,806,826,286,62,980,307,745,464,319,581,93,768,66,314,675,61,621,130,175,157,497,376,649,976,200,638,124,972,640,847,809,550,234,775,105,62,50,339,281,449,864,747,649,65,544,220,0,297,593,326,107,822,262,399,451,818,974,597,221,991,476,839,724,25,218,605,925,101,572,148,477,920,210,786,572,75,463,2,251,755,347,938,31,187,891,13,786,556,723,919,538,45,712,223,853,359,410,657,837,927,849,468,414,188,2,39,390,281,671,209,309,83,718,72,497,81,787,840,134,313,177,13,390,149,232,181,271,52,108,449,182,2,366,343,748,105,581,162,16,653,137,881,482,260,465,535,109,70,27,328,505,652,262,288,224,504,906,124,645,89,535,103,614,594,872,47,704,298,98,172,654,5,873,434,247,978,795,355,454,209,362,11,603,282,245,668,368,199,961,378,123,442,386,641,561,612,770,378,480,755,849,271,230,378,867,581,253,883,596,88,874,209,671,230,236,223,508,209,861,671,721,563,936,490,749,49,641,675,800,144,191,14,7,468,826,97,447,74,883,796,125,772,166,305,51,910,114,342,856,480,439,16,664,984,994,993,515,738,540,33,126,804,84,973,91,937,996,379,666,581,30,674,241,779,821,666,671,896,749,288,16,191,979,905,632,65,978,755,417,31,870,240,297,776,536,620,643,330,15,349,847,995,735,144,970,684,242,609,553,329,320,403,956,94,298,714,468,427,858,339,795,769,248,436,515,833,565,347,776,874,526,5,807,738,186,97,530,917,753,506,644,325,39,913,776,728,553,966,697,850,421,232,863,203,600,682,222,539,783,637,902,333,774,889,571,576,630,625,304,618,13,157,584,958,806,274,743,137,347,290,820,433,618,115,825,423,764,433,879,287,394,355,973,96,374,289,998,737,515,226,121,190,25,491,272,506,321,436,923,934,566,631,29,329,488,961,635,657,318,715,384,133,617,13,729,988,832,195,385,587,730,46,341,583,701,459,461,965,710,436,469,279,889,983,68,811,824,753,108,740,407,33,902,400,932,675,504,999,686,426,276,769,795,626,254,817,735,605,125,725,323,379,794,856,723,514,125,370,162,837,405,865,467,591,965,899,884,588,810,254,722,359,5,453,562,558,638,746,944,546,252,127,953,839,820,621,271,866,148,270,966,642,142,905,908,694,489,62,290,281,746,506,774,974,150,797,721,769,265,409,869,80,44,474,608,864,142,243,679,740,11,154,685,176,390,434,197,345,76,846,694,19,966,427,191,890,606,734,13,912,118,741,113,858,108,909,640,996,431,760,924,432,909,612,440,149,895,750,191,475,513,709,409,260,863,863,369,670,743,798,664,484,402,485,285,739,811,956,727,783,328,604,297,226,451,725,252,725,678,142,6,335,647,820,155,570,559,920,344,845,835,30,310,600,669,44,619,313,38,756,357,3,870,769,418,363,539,274,354,969,930,785,104,17,383,640,247,121,729,439,898,439,421,852,330,517,24,555,90,875,62,566,140,682,609,935,437,313,158,86,133,889,362,965,709,840,784,258,648,895,683,281,16,83,514,560,63,660,276,538,311,956,580,570,120,187,589,781,310,445,835,367,936,429,51,261,307,499,188,352,14,583,699,131,711,115,622,490,722,943,866,278,339,425,842,560,520,871,720,916,364,765,495,665,363,735,102,548,666,140,169,957,667,458,162,648,547,122,560,512,430,335,932,801,856,986,31,626,857,427,421,218,394,346,650,529,63,126,259", "441,669,338,3,62,911,33,504,651,52,557,369,529,596,698,819,118,786,895,785,220,102,314,963,844,219,868,626,431,977,628,292,956,33,781,37,492,234,827,301,96,913,779,871,663,827,442,810,259,773,22,950,906,697,499,14,266,269,766,688,739,155,656,528,957,619,344,258,64,196,216,971,33,356,53,192,573,825,851,904,597,289,102,988,84,661,642,274,775,496,917,61,998,938,974,321,954,72,437,878,789,207,759,836,55,304,284,937,29,549,863,166,717,542,226,585,837,867,733,624,884,543,573,749,745,327,132,826,371,963,427,416,494,167,785,442,122,232,25,88,287,833,99,766,887,777,773,782,138,443,627,643,861,830,518,195,396,220,376,758,252,347,137,150,262,565,143,701,90,885,60,10,528,385,818,164,964,167,99,615,193,559,459,657,253,976,573,22,313,700,330,962,855,897,868,82,800,847,77,728,125,559,879,707,992,493,393,989,472,396,975,766,581,861,903,31,166,531,10,971,146,811,51,867,246,774,946,143,467,112,826,657,149,165,799,523,9,728,352,719,568,387,789,621,449,489,659,816,42,921,750,858,730,988,973,578,154,301,95,740,23,780,45,579,739,362,996,733,135,10,371,870,211,316,793,136,994,297,0,45,911,816,531,948,127,569,709,377,345,873,978,580,101,769,250,96,709,863,991,496,797,664,464,776,32,432,141,315,44,38,418,824,875,127,192,424,122,534,895,654,148,216,261,280,392,899,901,105,393,538,392,150,875,994,68,523,876,410,153,200,774,821,374,505,747,796,504,754,415,171,689,684,429,423,541,398,856,274,767,6,930,913,475,191,530,825,544,564,313,972,223,717,48,595,855,492,780,771,489,927,956,950,980,954,683,669,874,443,599,906,60,380,869,187,452,367,53,505,597,79,358,234,88,292,461,520,396,298,166,458,172,823,51,627,349,702,191,534,244,451,781,678,345,274,793,493,428,338,766,935,730,399,494,331,941,387,806,479,53,810,142,852,923,377,279,277,541,93,296,154,948,873,549,737,447,463,798,372,424,640,451,162,262,423,520,414,573,634,118,583,614,263,715,264,672,904,288,313,919,450,336,141,483,49,878,696,777,955,636,386,128,675,120,68,194,350,97,192,995,393,494,413,919,197,487,140,159,464,596,864,812,852,753,102,763,54,858,114,330,764,78,152,308,218,729,621,627,953,951,89,378,784,600,771,219,634,528,776,116,810,756,54,570,127,701,623,264,616,23,447,191,158,193,933,183,186,371,925,396,30,738,211,952,101,107,591,790,24,233,331,178,995,526,472,58,612,470,490,821,860,474,174,606,976,322,109,664,350,851,368,320,217,172,754,908,731,933,762,698,204,306,370,158,70,333,810,156,195,170,308,175,737,654,849,290,480,460,660,726,35,989,344,720,466,110,355,881,90,345,740,877,257,142,527,178,624,688,112,892,350,178,628,839,59,155,76,260,606,223,966,956,658,405,583,465,304,132,332,262,649,293,28,259,364,879,54,545,665,417,2,247,393,123,943,333,104,532,93,941,263,304,71,932,811,713,216,292,349,96,774,827,17,528,692,960,348,878,401,981,85,718,60,666,412,926,30,557,438,475,247,24,668,542,227,510,298,291,360,2,816,355,205,214,920,566,704,974,413,913,447,508,135,249,382,6,40,266,345,533,96,469,298,155,417,962,59,491,596,491,814,202,727,475,325,433,172,161,248,925,583,613,915,33,11,732,186,144,419,62,45,126,248,833,837,309,719,120,637,283,232,151,234,722,61,998,94,262,817,948,933,941,489,480,222,20,848,675,751,964,606,937,389,544,374,990,256,300,2,255,959,504,818,22,112,110,547,350,787,445,134,995,989,361,468,925,586,835,177,59,673,510,430,881,808,24,491,846,491,639,48,657,339,346,914,389,76,355,777,275,750,651,3,461,922,320,490,661,998,664,24,328,311,316,415,947,28,722,307,710,269,145,889,50,315,409,481,784,20,504,940,164,155,281,438,562,31,752,259,955,716,267,512,567,528,225,637,459,248,225,519,107,361,362,443,800,630,796,311,761,87,754,433,937,748,840,449,884,449,378,705,266,489,299,537,908,6,512,395,430,589,754,237,793,922,292,103,78,919,118,27,579,898,534,376,592,704,117,833,641,739,446,356,707,728,313,815,897,424,252,282,800,294,619,887,573,389,762,144,730,306,679,731,762,127,783,37,358,740,306,359,309,534,530,829,965,307,87,991,845,481,924,363,296,435,703,209,452,224,68,3", "438,597,314,73,169,846,518,204,810,110,56,357,930,930,649,817,752,629,85,620,93,418,623,145,410,526,725,768,364,86,469,334,370,691,811,496,73,926,477,200,383,697,179,756,393,227,998,917,978,506,753,710,405,726,108,276,550,760,360,215,897,71,727,510,13,91,531,15,957,172,180,162,639,203,283,431,288,920,919,865,552,732,481,871,689,310,883,722,191,926,670,582,287,722,330,260,389,830,189,429,443,572,902,317,829,868,760,326,133,273,987,463,555,546,260,159,852,687,45,136,185,983,861,259,154,204,675,324,820,850,89,393,77,814,219,549,779,599,903,296,287,643,297,571,169,582,403,900,243,205,378,300,295,363,244,493,463,36,166,11,262,350,222,446,475,168,204,176,533,560,204,134,978,254,523,359,683,338,268,737,227,750,845,909,448,883,121,671,861,477,80,253,516,476,886,181,347,751,859,968,754,892,733,383,663,504,365,551,914,670,98,193,216,878,926,101,267,371,578,25,81,54,704,734,471,493,871,227,650,311,775,309,317,920,292,66,85,473,875,488,60,150,570,180,922,901,952,240,66,669,263,840,198,72,323,261,422,539,13,458,363,741,59,975,717,904,142,591,134,104,731,15,322,477,333,250,17,593,45,0,682,770,810,251,109,575,6,188,15,993,630,974,936,985,725,231,569,298,346,757,965,625,448,874,75,326,116,412,849,221,584,442,510,994,133,200,316,458,325,50,187,656,388,664,211,794,154,685,435,963,703,628,972,729,203,247,889,999,116,924,495,614,394,295,950,90,223,74,462,534,833,240,226,222,431,179,254,800,449,722,373,700,385,419,530,377,726,492,89,212,166,889,891,543,762,361,357,110,308,566,589,527,784,202,183,25,516,484,487,119,46,376,658,321,125,655,531,820,847,649,451,336,471,675,142,478,188,708,308,318,315,102,329,558,793,132,80,385,961,656,894,707,460,873,695,27,623,371,335,889,398,75,539,647,429,11,40,9,975,700,513,769,508,79,458,325,866,930,287,295,294,751,477,192,270,748,66,149,373,381,936,519,958,309,867,960,878,343,504,320,323,582,740,737,473,65,196,203,358,596,65,137,892,563,173,857,642,681,246,503,863,140,921,834,959,601,470,734,605,320,787,383,846,173,671,392,64,830,314,805,983,946,62,563,957,886,331,324,258,89,388,522,567,864,592,886,668,301,832,34,909,627,572,186,211,886,289,894,530,110,266,781,847,786,370,829,213,317,632,580,381,875,629,102,977,544,997,633,363,653,121,36,324,922,842,61,567,68,46,693,916,145,971,177,183,23,895,734,311,868,157,523,157,715,944,774,947,359,193,46,749,321,778,155,365,808,930,803,856,710,572,717,114,969,550,308,667,613,388,314,706,518,790,33,728,744,413,815,972,755,74,134,519,345,792,372,583,571,967,516,846,497,865,221,258,777,605,195,828,274,619,319,846,2,986,586,211,112,998,552,504,807,645,870,457,76,380,651,129,573,621,341,17,697,194,938,725,526,303,512,617,911,371,817,565,462,685,866,596,46,974,771,565,358,410,877,193,459,829,99,273,301,972,916,901,143,970,509,182,38,685,112,11,554,950,729,272,689,459,534,468,261,991,795,972,240,184,678,993,958,182,315,649,515,247,408,908,271,389,632,791,564,153,355,438,179,716,46,390,234,769,978,448,782,572,921,138,119,218,154,889,702,711,353,578,499,610,577,38,534,467,55,198,835,251,476,941,577,93,758,856,933,19,694,284,26,867,530,285,151,9,746,458,807,241,691,267,924,128,639,953,209,941,658,250,906,745,480,96,56,185,767,87,261,739,939,341,939,872,323,202,369,580,52,254,731,422,247,887,675,709,107,194,445,983,27,222,688,880,222,195,703,588,22,915,306,838,134,770,600,91,44,774,664,509,339,444,979,597,668,568,913,74,411,98,481,424,59,308,730,983,715,35,186,928,726,601,531,713,485,124,116,861,318,288,776,682,929,659,977,342,566,579,820,507,729,825,433,70,295,918,375,114,823,806,552,59,60,357,297,715,895,666,999,13,390,849,681,113,44,889,874,286,982,808,682,34,38,711,75,985,602,828,504,637,243,337,551,555,579,403,432,516,364,885,349,920,584,127,371,611,194,391,698,759,166,430,457,367,311,38,736,89,883,674,652,37,856,197,996,553,174,848,112,654,868,253,187,570,506,625,555,536,452,881,238,710,11,981,502,241,657,517,210,326,334,396,62,822,306,432,745,429,520,295,463,711,39,281,875", "488,292,996,810,396,39,998,868,559,936,324,598,618,517,794,882,353,702,264,293,6,228,114,873,978,830,537,462,987,375,948,681,809,437,495,687,601,560,129,296,881,491,388,354,291,82,160,815,126,796,104,32,329,534,953,147,426,55,81,299,815,709,262,819,769,965,879,33,172,217,884,583,937,638,511,982,412,927,862,920,617,435,539,824,582,260,940,638,1,615,249,397,201,109,797,469,94,470,726,802,887,28,211,605,326,206,627,781,739,819,309,483,699,962,65,217,840,449,245,367,701,170,709,489,512,472,324,824,961,356,686,742,492,465,426,537,152,49,883,121,5,999,911,410,525,540,765,535,822,4,20,419,399,805,86,16,573,787,482,710,1000,394,862,610,297,39,542,915,800,260,666,489,508,422,98,71,326,176,989,473,229,205,780,757,239,431,986,976,251,413,519,930,93,202,901,540,751,341,991,33,511,817,939,429,285,195,789,870,816,324,636,198,63,914,617,566,775,320,214,744,23,946,573,639,683,706,22,856,840,780,27,552,598,896,947,708,47,443,538,474,849,201,846,741,453,368,874,917,384,838,30,887,968,369,751,259,608,523,261,189,562,999,339,118,499,996,766,724,838,693,669,843,993,464,190,200,903,326,911,682,0,406,283,870,599,348,147,541,683,694,935,25,500,264,305,632,464,993,379,342,450,476,655,974,965,87,511,457,31,800,904,883,673,713,490,865,554,969,987,133,149,259,604,641,643,260,830,264,549,928,423,612,521,64,327,766,25,943,98,632,343,638,695,30,193,494,266,493,238,173,804,159,553,593,46,242,38,357,140,789,155,60,380,100,462,775,26,703,122,616,973,490,801,166,521,199,970,467,557,885,607,869,794,62,895,730,679,75,500,246,457,714,52,132,532,287,685,517,368,499,126,416,479,800,91,771,393,912,552,151,698,338,47,711,264,658,105,509,252,104,281,671,429,754,514,674,858,320,484,739,983,103,79,703,108,435,238,529,820,474,798,178,846,737,898,420,677,880,169,305,621,745,172,52,67,783,449,629,318,323,7,992,867,463,583,742,801,552,458,500,413,965,805,828,16,454,927,914,23,61,13,727,548,915,888,353,388,443,599,615,157,240,666,926,818,652,855,592,137,618,931,737,3,828,559,11,749,569,990,929,583,581,761,247,150,787,394,921,297,167,948,415,806,530,447,599,222,119,73,81,358,405,398,21,984,688,594,178,63,684,788,302,150,859,256,944,263,299,778,258,800,254,120,203,881,644,524,928,14,966,287,290,120,313,642,752,557,873,711,358,627,405,792,889,545,372,294,139,333,12,742,491,96,365,632,398,26,582,843,146,528,742,894,622,965,665,424,869,440,637,825,477,691,508,982,412,937,790,726,949,465,923,722,812,124,559,115,58,436,245,464,702,407,416,953,319,809,876,697,510,326,69,700,664,687,48,441,222,903,62,247,335,884,434,396,508,208,305,923,767,121,135,190,244,592,434,954,623,204,488,874,803,314,976,274,502,802,608,938,692,77,456,496,539,323,716,547,302,84,37,369,355,975,440,930,514,340,491,724,464,324,43,738,466,422,596,291,337,662,920,916,241,84,976,591,192,39,831,232,966,710,358,12,690,877,943,889,41,50,716,187,884,637,325,863,597,266,768,384,268,389,209,799,327,709,863,767,195,85,101,790,225,894,794,334,19,846,850,90,240,413,88,708,635,830,620,338,552,799,521,901,137,42,521,354,32,174,786,129,121,526,446,565,769,843,39,273,885,60,332,999,266,265,270,462,87,618,304,771,708,71,504,58,33,214,927,119,932,616,139,938,575,501,660,438,298,791,954,551,480,287,973,488,394,727,82,87,161,919,390,491,819,959,384,215,164,712,733,960,419,78,890,998,61,190,430,577,771,516,700,496,500,123,856,584,546,580,760,182,381,265,219,953,470,752,112,807,445,449,292,298,487,443,579,966,479,78,744,637,613,293,541,968,450,756,934,963,155,371,320,480,951,530,18,390,5,360,535,901,256,743,951,893,153,705,438,684,957,97,672,699,594,740,629,377,928,16,518,751,743,616,864,4,815,554,566,27,828,282,480,846,933,602,394,484,34,696,872,26,804,96,721,202,762,346,398,189,576,359,812,725,948,423,317,843,298,724,168,77,921,201,145,186,157,364,207,83,156,340,851,517,474,367,362,807,870,954,833,454,757,690,425,204,677,391,671,912,321,545,375,674,719,309,917,340,410,201,613,874,552,437,282,764,572,586,771,641,411,383,895", "187,269,294,559,806,154,110,692,307,392,285,119,981,297,94,715,225,650,616,112,946,334,228,557,814,227,687,32,338,749,741,381,329,111,613,319,136,188,41,590,293,397,934,412,472,664,841,858,421,884,298,880,792,495,255,353,616,654,890,652,269,604,708,78,35,669,443,876,375,477,53,836,374,643,531,156,582,946,547,493,530,194,484,706,930,681,910,622,96,515,376,653,557,242,740,238,876,141,627,447,306,227,947,615,381,211,171,846,243,534,999,291,77,19,705,605,786,1,735,566,903,138,709,281,346,847,501,623,168,100,224,356,979,329,663,850,131,60,768,878,937,560,866,210,8,224,847,462,733,523,978,254,456,439,781,760,16,922,526,532,526,763,494,488,276,670,948,278,480,893,201,813,529,227,383,845,202,427,93,857,514,292,306,566,859,972,479,549,916,741,284,456,22,808,457,211,797,370,560,920,577,27,927,991,47,446,907,523,336,319,447,134,480,646,737,531,794,254,525,234,357,138,941,779,932,679,402,232,666,871,991,94,30,957,786,425,101,988,634,73,996,336,477,150,877,947,381,703,568,456,92,323,861,382,735,761,355,977,383,45,860,33,238,284,899,457,633,472,518,605,44,743,932,835,292,669,207,107,816,770,406,0,98,44,299,473,19,134,524,823,192,565,195,659,885,772,682,85,565,141,944,725,973,216,570,753,922,487,479,146,241,785,522,130,773,631,484,437,273,270,414,32,37,293,348,724,273,224,136,479,575,504,153,863,516,661,295,127,696,219,98,254,76,639,873,574,164,312,694,829,721,606,395,767,215,398,402,683,590,517,836,842,738,719,348,1000,723,354,510,932,14,9,261,926,329,6,679,296,217,282,960,616,80,261,389,972,144,452,17,265,151,593,8,52,732,681,28,761,866,722,756,873,28,747,593,966,300,133,942,221,990,672,239,937,521,59,703,223,352,770,273,435,667,275,333,570,480,877,582,620,420,945,55,426,869,473,454,161,867,472,461,647,338,969,299,440,19,896,836,650,784,770,540,907,510,896,618,986,541,294,209,430,285,840,547,201,156,256,992,566,616,911,469,445,256,16,760,865,672,305,700,876,633,215,512,104,247,450,696,21,156,394,641,681,228,740,52,855,315,620,783,307,189,484,939,541,880,647,903,243,933,729,544,286,173,787,356,62,825,250,163,894,54,939,129,895,733,400,472,672,568,304,978,989,630,647,253,174,660,870,743,61,232,81,241,791,278,263,210,908,919,1000,483,921,747,933,185,918,131,185,840,343,467,714,757,59,297,160,35,288,74,183,299,12,316,56,542,22,925,853,672,907,244,434,835,75,512,349,882,57,291,907,694,463,352,5,974,132,185,762,335,575,551,384,218,873,871,552,705,790,132,117,399,269,486,691,598,95,280,790,567,936,968,81,609,155,792,736,89,712,744,546,980,354,631,856,149,760,978,177,228,522,720,2,487,24,69,529,70,683,498,359,824,588,656,324,24,971,336,781,673,917,376,348,169,956,631,401,971,839,468,972,613,150,909,591,759,676,53,346,134,398,221,901,549,216,873,841,420,834,643,514,109,162,796,966,738,845,811,564,222,82,365,671,496,891,28,477,840,19,635,584,915,717,638,148,266,736,792,80,861,410,785,281,541,944,714,176,658,165,587,181,215,935,649,49,712,742,119,426,474,578,113,819,50,522,687,612,159,30,812,876,23,286,442,749,215,536,770,799,262,881,253,373,47,562,790,237,572,432,2,749,481,718,148,612,414,72,839,940,64,806,110,730,813,707,957,660,556,847,47,185,329,627,144,241,191,575,621,789,365,809,762,385,299,362,74,130,309,975,71,559,173,535,65,465,696,594,377,870,865,944,685,166,433,665,156,123,774,494,499,813,187,277,257,815,912,623,663,784,993,666,374,449,999,837,191,909,309,110,175,615,307,758,112,273,328,655,509,408,315,821,246,778,794,815,607,29,383,47,757,123,368,175,718,771,683,125,686,183,912,821,817,565,235,294,248,374,232,862,174,371,589,430,720,999,659,911,778,99,505,486,146,161,153,215,833,309,6,803,350,499,930,869,226,985,735,865,298,771,929,90,873,744,728,590,818,616,935,356,262,20,771,444,961,387,705,941,708,348,857,92,932,86,985,295,559,389,127,303,509,374,593,58,978,687,372,78,163,915,680,401,142,236,597,56,526,585,56,479,298,91,472,452,647,607,528,167,644,862,859,847,419,952,661,378,475,469,444,818,183,448,345,747,595,111,273,507,211,910", "813,463,133,822,906,10,306,404,586,778,579,848,790,949,923,941,557,685,786,807,890,962,538,27,686,893,969,419,468,344,860,938,835,989,837,736,122,850,359,358,798,376,904,728,52,862,322,861,240,883,491,367,76,987,494,413,126,683,44,25,166,658,642,563,539,294,606,745,689,138,276,803,503,84,107,882,929,487,293,510,487,511,240,466,19,833,322,683,322,41,813,615,894,613,307,322,439,279,923,281,424,784,651,235,10,47,597,507,676,821,643,468,34,930,586,989,603,275,586,296,60,265,981,991,907,668,152,666,770,939,315,256,723,981,928,600,987,740,879,734,214,212,531,313,100,262,855,460,933,367,953,200,179,949,894,609,867,910,704,67,167,398,922,689,209,573,197,912,701,535,589,454,309,40,472,338,234,298,75,816,879,15,555,77,915,708,617,661,753,969,63,213,762,376,206,92,44,755,36,655,836,65,233,368,22,494,184,421,404,575,570,950,571,760,299,230,619,283,421,203,896,559,12,388,136,871,611,648,986,523,22,13,794,208,53,994,13,970,298,892,100,85,233,851,212,609,568,811,128,849,40,558,320,567,32,418,118,924,893,947,643,463,456,70,455,279,242,895,307,450,7,391,157,767,90,30,123,822,531,810,283,98,0,529,432,506,274,139,547,795,952,26,414,287,521,260,111,832,803,405,215,757,457,29,293,231,504,135,24,781,12,84,401,262,487,512,811,231,502,940,446,551,827,832,593,297,733,946,23,865,917,64,987,714,237,549,780,386,77,814,681,570,558,859,578,546,788,719,181,466,190,891,938,213,667,409,310,294,928,291,157,610,485,386,453,827,918,365,341,25,413,348,7,363,437,565,458,670,186,63,454,406,393,105,880,199,761,654,520,894,731,104,346,714,68,240,888,560,412,420,992,723,764,565,510,993,6,304,422,550,210,447,814,779,532,650,799,113,435,517,492,92,371,72,478,338,370,31,995,879,973,611,496,480,384,730,147,73,987,492,298,255,269,486,380,142,16,113,940,51,843,674,713,979,584,495,890,807,223,622,998,845,603,512,251,554,975,152,270,310,248,313,51,745,363,107,265,759,423,511,210,411,661,848,780,769,550,299,678,919,136,590,722,208,734,619,279,948,419,678,547,836,980,743,252,8,889,328,455,954,341,735,854,176,937,347,433,221,545,496,303,335,456,681,745,831,828,252,965,954,613,756,771,126,626,831,145,30,950,952,275,325,411,672,571,284,6,399,936,706,67,943,932,74,829,748,111,481,815,157,569,20,538,381,614,446,39,907,646,869,220,452,130,332,490,914,861,773,666,142,459,158,139,327,27,386,718,366,995,341,978,905,588,960,682,884,626,487,795,843,829,189,180,583,993,699,349,471,864,100,376,332,349,72,944,45,771,123,513,805,279,814,788,375,324,34,420,865,523,186,408,753,908,848,267,751,343,117,55,243,900,451,809,872,270,732,311,383,432,526,113,884,385,270,683,879,436,180,707,781,905,51,291,494,158,713,631,213,442,152,792,701,585,943,665,821,552,353,206,768,868,21,797,954,761,958,881,307,154,34,168,361,885,976,276,857,416,764,257,613,290,550,68,902,107,58,211,844,604,247,387,751,936,12,826,37,367,548,561,358,522,316,338,706,960,341,903,721,736,633,272,126,202,109,791,770,174,28,663,490,264,778,914,361,567,515,130,887,525,703,372,86,379,739,503,342,455,981,276,459,100,43,90,820,109,465,162,894,406,412,275,435,508,949,577,728,728,824,334,928,772,987,826,55,277,243,316,439,841,912,235,636,271,19,406,764,657,839,274,78,974,715,135,565,349,234,571,390,697,197,822,532,891,671,504,610,283,437,626,616,718,464,929,546,101,736,299,227,369,258,872,460,967,153,870,155,908,302,230,450,907,971,166,233,829,133,943,620,406,305,170,636,417,831,794,483,783,526,969,550,693,907,703,871,316,560,862,998,935,259,591,465,865,7,497,178,332,276,703,963,404,608,818,828,710,377,51,564,468,71,81,147,97,979,518,18,791,595,193,848,89,601,100,76,993,700,790,67,426,811,279,343,939,71,58,947,847,875,663,810,788,307,6,395,345,340,490,976,545,762,556,240,218,464,397,833,686,902,998,597,633,47,904,793,783,999,944,328,460,813,486,440,514,80,468,34,35,730,504,452,686,60,251,99,581,414,625,265,234,604,956,383,83,671,179,149,190,879,192,305,994,773,827,348,697,327,899,582,734,711,849,589,603,634,216,134,200,314,481,605", "668,378,874,836,889,577,25,680,80,750,696,553,196,388,798,429,522,460,207,637,448,968,491,583,329,881,355,639,173,544,170,460,167,314,713,337,261,770,957,713,889,702,754,608,707,470,986,671,713,297,507,920,900,650,853,252,724,812,48,739,4,575,611,151,288,561,676,301,343,528,6,961,358,366,709,118,38,71,544,169,205,188,869,373,980,868,957,274,956,261,824,638,558,63,544,221,320,455,914,792,402,2,190,562,320,608,386,271,10,648,622,429,801,109,64,661,896,752,698,957,626,486,794,146,120,503,911,18,571,506,215,351,409,266,410,252,440,529,85,722,159,311,197,445,912,570,386,214,100,867,240,305,153,208,29,818,15,687,144,716,376,585,372,422,957,110,446,644,49,14,273,52,188,969,518,39,75,627,85,345,659,459,278,528,176,51,309,487,576,876,466,80,414,744,692,793,143,343,869,300,300,301,634,651,890,740,528,950,311,37,148,920,894,887,667,257,395,429,302,610,576,315,744,575,590,73,299,817,592,924,886,547,861,744,868,544,848,226,219,992,813,938,505,650,182,54,640,956,971,766,228,248,281,429,393,396,108,118,279,823,292,765,874,856,950,811,251,843,624,177,712,965,247,994,76,511,755,262,948,251,870,44,529,0,337,752,259,452,332,840,825,467,700,795,123,411,996,818,99,839,482,560,170,329,359,510,602,861,388,359,771,297,131,804,981,859,581,124,789,368,145,561,178,192,844,518,868,446,62,410,409,410,682,381,319,339,943,636,636,424,156,234,152,956,1000,162,988,433,475,779,544,666,496,469,616,488,376,930,259,970,148,560,924,643,567,571,482,77,37,372,147,447,202,68,472,208,483,234,829,751,703,588,550,110,773,558,991,487,862,889,637,10,807,485,545,537,666,413,970,701,116,948,223,320,573,37,381,630,729,987,494,858,46,537,282,899,412,805,389,198,17,47,408,705,433,432,216,116,309,946,152,807,793,454,200,652,720,778,715,723,276,13,76,37,180,26,911,70,499,591,516,464,388,441,290,978,533,870,7,656,9,314,424,752,339,33,371,754,700,980,377,825,174,845,509,713,346,948,413,341,762,985,18,74,400,447,159,575,71,977,826,970,157,564,584,318,960,567,714,575,460,446,454,487,954,813,487,905,85,27,355,714,642,720,124,712,449,985,483,74,746,673,737,539,550,558,471,181,599,716,113,719,741,111,819,171,769,271,27,390,73,476,911,912,72,65,796,903,788,171,52,198,332,359,524,178,13,53,329,711,927,629,70,714,487,202,652,408,455,352,452,641,746,863,658,943,2,255,211,459,138,384,188,474,887,585,415,34,823,602,996,261,79,784,278,964,741,880,519,309,133,687,502,686,213,717,185,96,809,134,850,834,542,340,132,998,868,18,153,625,808,385,473,247,538,998,153,360,762,384,826,61,311,827,352,781,742,292,182,761,873,379,832,829,854,202,67,959,758,70,780,21,202,98,349,265,219,44,742,927,605,230,382,945,866,172,367,887,40,484,55,769,48,469,935,782,12,494,448,45,134,535,915,531,649,352,643,941,99,789,52,959,928,7,220,662,820,118,961,258,208,107,992,113,22,636,500,115,866,203,464,40,330,697,733,530,701,348,920,849,793,328,544,26,203,946,981,177,9,50,454,529,814,353,788,675,832,434,174,411,642,883,978,74,372,14,970,357,854,662,241,245,730,586,22,63,836,769,144,368,392,384,745,490,438,997,844,947,861,673,152,694,898,285,884,937,462,297,393,372,673,468,587,186,489,972,498,143,429,630,688,55,851,126,314,825,782,619,349,102,246,259,686,756,188,708,509,166,169,90,610,426,815,89,336,386,525,677,771,901,251,818,451,650,774,652,342,673,715,408,428,674,32,164,994,807,28,69,328,135,186,679,699,788,820,86,903,201,840,95,280,391,983,592,162,657,461,645,297,565,352,395,884,188,780,935,160,694,368,51,984,1,282,160,942,470,747,364,283,156,562,222,777,99,763,186,658,648,372,292,307,6,679,95,915,446,270,247,722,543,403,599,384,950,625,355,175,720,821,296,248,204,29,594,224,786,150,505,8,594,73,96,250,986,873,2,653,224,727,437,746,22,878,780,428,34,744,823,451,426,794,859,369,658,878,187,534,629,104,17,779,804,525,921,438,128,368,113,129,370,654,238,275,132,192,2,112,100,716,801,638,891,663,226,288,227,286,571,614,778,320,946,433,816,869,247,709,532,366,238,821,7,363,819,218,533,565,517,278,976", "373,64,638,74,931,874,965,681,625,872,111,387,925,28,491,410,644,982,162,913,102,161,528,843,611,246,141,417,237,452,126,728,227,447,981,87,203,777,177,898,703,256,499,484,244,578,807,474,818,984,337,758,634,320,283,730,905,510,988,890,108,739,600,724,396,267,252,29,234,863,400,424,446,995,570,309,573,228,254,890,785,300,82,986,433,809,29,622,334,616,378,591,603,313,312,105,489,282,974,39,376,640,797,482,638,995,512,719,404,410,249,534,155,917,302,537,153,895,505,34,803,381,123,488,577,992,707,393,204,699,944,921,598,596,523,385,191,147,563,678,83,96,653,985,547,779,300,418,737,747,178,862,810,973,502,415,514,629,173,766,971,177,240,173,416,44,76,301,431,622,592,132,90,140,304,846,771,598,597,370,357,938,585,888,5,95,406,652,365,647,171,232,863,473,126,657,302,557,199,680,195,423,851,860,258,233,166,554,56,300,165,321,293,265,116,944,677,873,520,896,81,894,853,878,518,769,452,849,780,603,268,155,176,443,390,831,318,856,864,371,980,125,816,832,478,530,921,429,513,957,618,522,38,718,512,691,290,171,378,262,484,267,722,143,584,651,218,727,971,184,380,578,626,676,737,325,357,399,127,109,599,299,432,337,0,902,311,12,856,483,592,539,782,941,725,141,512,329,101,222,391,342,353,453,82,824,242,948,425,98,791,73,425,350,435,683,715,593,373,2,824,99,503,604,627,244,982,964,298,967,170,656,531,55,732,986,898,857,533,525,657,649,138,19,953,759,445,487,633,47,782,931,431,420,474,103,537,867,823,33,460,422,512,629,365,549,232,122,31,199,326,407,200,892,1,136,488,380,693,717,304,427,465,341,260,502,779,57,316,845,606,150,448,68,136,108,77,446,673,139,177,288,892,606,269,630,374,230,306,558,177,335,329,498,21,644,564,632,17,236,489,421,280,144,561,740,101,279,364,53,84,807,348,541,733,938,478,736,109,536,837,215,771,792,365,856,302,747,911,306,344,890,826,765,812,452,474,411,366,380,498,411,140,782,667,104,385,385,98,594,923,502,397,122,489,70,993,922,930,638,463,532,801,291,105,510,858,330,173,823,936,213,528,839,888,417,222,319,367,805,164,90,963,193,517,397,262,499,975,15,267,595,997,665,406,723,911,363,848,540,746,227,957,707,25,252,583,927,66,319,814,667,391,303,195,418,737,124,147,334,347,748,942,231,764,312,517,123,925,339,373,830,386,119,1000,356,62,261,431,794,650,17,778,134,394,220,686,926,683,44,285,243,543,843,55,654,313,804,68,172,414,753,342,384,818,891,981,340,989,809,17,886,716,458,126,33,203,634,62,93,542,50,305,801,558,57,312,354,419,11,307,725,238,81,75,328,248,357,875,638,549,144,816,883,9,928,137,939,719,951,446,26,226,241,341,226,205,911,124,387,680,510,353,692,595,756,996,39,960,937,137,496,716,89,314,645,589,413,261,764,47,986,592,852,143,48,924,342,336,973,643,660,96,554,550,495,722,858,137,286,242,692,574,964,451,308,587,491,481,158,275,346,173,328,328,79,449,647,681,163,903,158,659,740,706,80,876,385,370,635,114,414,780,301,153,690,249,642,758,975,381,192,613,546,435,573,770,954,493,35,182,431,838,840,561,428,56,715,613,491,636,273,240,54,266,607,258,589,974,287,158,451,762,408,537,452,510,770,750,161,605,570,675,140,8,499,507,595,641,825,92,247,612,583,122,435,452,393,214,743,585,82,462,407,53,990,718,782,719,847,52,265,3,767,802,304,904,161,41,147,693,366,58,706,634,654,578,790,136,954,759,199,34,300,671,850,747,462,133,860,487,938,464,953,244,932,874,400,784,498,111,774,778,206,882,637,502,510,427,374,546,661,714,287,392,766,90,82,650,884,323,367,370,558,604,645,478,333,820,164,169,869,307,655,957,804,896,809,450,845,562,503,508,1000,618,68,880,626,192,195,598,829,126,30,375,274,575,243,54,675,369,76,239,872,806,396,183,731,598,870,582,518,288,993,492,891,944,356,473,70,907,108,667,477,964,507,473,178,220,473,877,825,184,866,483,393,404,518,561,794,256,164,381,577,579,86,590,135,680,539,840,349,891,734,898,267,641,172,395,698,776,192,59,683,378,914,297,315,3,442,387,124,648,987,749,739,843,253,875,108,40,170,997,912,857,875,432,843,459,550,550,335,838,221,414,759,911,723,287,913,629,230,479,142,538,955,681,346,628,72", "522,452,314,250,706,447,769,544,815,407,693,339,714,235,571,653,985,231,227,600,545,308,772,142,663,236,434,809,125,75,792,373,396,361,4,656,267,827,485,103,96,13,527,824,869,452,877,845,649,298,626,311,67,581,403,111,951,443,19,939,87,382,136,143,707,13,993,207,631,195,704,588,939,646,814,344,16,885,327,829,725,121,534,559,740,563,915,850,469,273,998,408,438,739,844,31,120,704,286,674,348,13,416,212,735,198,737,360,628,662,4,548,905,198,990,347,850,547,535,890,811,485,781,931,436,682,567,100,707,426,269,965,512,657,686,865,637,122,314,754,87,359,852,115,498,348,342,993,968,79,691,628,921,574,128,863,450,428,96,209,949,21,528,860,722,806,264,374,76,535,569,544,208,592,578,300,831,805,738,761,770,89,452,849,177,516,643,734,729,417,203,544,301,888,773,288,479,599,79,853,169,70,438,810,885,37,224,469,194,498,301,293,353,611,219,267,975,812,187,276,458,759,404,431,251,563,990,796,186,847,817,614,607,663,223,961,602,295,372,217,854,582,133,179,537,596,96,933,191,684,747,997,448,418,300,287,864,341,213,335,244,160,115,323,868,809,29,51,311,914,965,742,364,868,555,94,28,451,569,575,348,473,506,752,902,0,704,88,35,138,299,470,245,328,401,303,988,823,944,855,757,273,394,777,522,985,584,14,556,42,732,340,627,258,264,274,724,405,817,175,170,546,957,881,345,573,576,199,605,514,766,69,538,297,812,431,72,231,561,659,939,986,35,510,502,629,82,624,649,817,404,534,497,698,770,34,439,224,212,682,583,17,467,648,27,543,449,483,157,462,645,616,815,214,609,403,894,836,452,11,694,820,703,715,748,224,868,882,294,401,283,17,86,288,87,835,171,430,606,400,200,933,206,123,398,478,281,699,427,409,168,269,961,876,521,194,414,405,218,178,783,707,546,102,619,989,3,481,858,902,446,909,612,527,413,18,357,806,646,105,358,501,204,840,300,33,904,743,67,367,989,911,659,894,490,161,33,734,383,160,804,78,720,994,319,194,817,179,465,410,393,473,665,382,126,86,290,417,218,131,48,290,32,359,592,717,565,728,324,470,254,700,139,861,697,747,205,956,367,875,733,648,879,876,188,535,152,439,117,895,781,799,855,444,71,78,637,590,584,232,725,965,119,150,186,964,625,671,175,756,341,492,113,292,365,546,841,137,342,273,994,554,378,143,881,237,630,32,801,840,528,817,309,833,22,71,650,654,547,728,198,623,175,771,255,233,900,998,996,212,808,458,708,943,405,452,126,704,412,650,906,337,302,460,146,554,986,938,800,751,763,78,413,563,49,670,284,782,119,15,226,148,63,358,13,858,369,773,812,950,133,653,342,936,921,565,648,891,117,128,188,637,272,942,546,313,757,656,742,393,26,900,321,431,604,259,179,464,859,124,391,50,299,687,646,38,378,763,190,824,589,209,560,696,906,566,148,532,50,201,665,869,648,18,754,462,221,852,545,921,215,763,896,521,90,688,84,674,245,951,679,621,749,850,956,101,387,713,786,176,601,893,704,525,120,418,447,384,221,971,890,190,459,570,24,263,62,236,669,841,576,172,671,810,739,273,473,758,681,540,543,70,387,321,281,976,335,639,13,458,616,565,634,575,896,461,654,262,992,578,851,43,778,356,220,532,969,217,722,863,519,450,880,257,177,375,512,450,518,489,339,382,761,268,457,937,196,580,213,965,568,655,485,246,518,910,538,313,207,499,787,265,70,884,569,527,988,97,947,795,373,509,892,199,47,369,404,852,374,587,958,683,718,637,492,112,37,530,350,29,862,115,735,955,905,862,749,372,161,871,612,955,520,440,38,345,364,364,389,541,366,769,631,921,244,959,698,829,595,774,888,489,906,304,312,412,499,664,893,147,934,170,285,381,254,829,461,239,63,77,687,669,941,492,218,575,325,461,166,248,197,647,872,207,777,299,713,222,988,276,838,719,883,731,541,655,315,121,684,329,706,844,1,304,135,972,201,546,536,153,645,711,493,964,13,776,586,492,150,343,479,626,995,609,299,25,742,6,651,684,268,316,430,434,889,808,869,126,689,137,18,830,974,495,829,230,726,993,527,6,710,507,270,58,511,657,656,218,535,938,776,300,56,192,423,946,695,499,347,71,534,394,832,252,911,713,307,405,427,828,46,207,712,846,77,156,372,631,689,150,820,867,761,422,544,769,884,450,80,240,904,589,154,380,739,614,379,921,654,786", "411,672,711,739,303,240,226,553,379,562,55,136,441,526,786,937,171,600,445,820,569,532,39,817,5,167,198,203,557,394,383,547,419,126,987,262,445,609,390,844,779,788,603,606,327,784,398,305,800,131,475,291,180,218,568,742,416,841,951,66,992,359,600,549,7,414,244,824,196,913,433,764,531,579,10,506,108,94,995,635,586,188,297,629,666,23,350,203,906,374,74,463,216,526,259,846,708,865,87,159,866,468,58,556,710,270,612,70,124,971,206,750,767,465,196,94,314,263,333,259,841,107,704,316,806,609,286,459,396,304,818,100,238,214,443,660,292,362,272,225,368,720,285,124,129,662,248,961,795,534,199,946,408,326,932,73,407,901,789,711,821,606,768,132,170,27,682,821,622,638,598,551,846,374,5,611,297,635,89,543,45,133,129,126,766,389,646,218,133,336,804,455,924,75,991,263,43,798,666,328,75,173,212,243,339,401,940,155,615,21,389,84,90,843,747,573,319,507,360,829,199,698,831,181,426,586,168,229,417,274,674,150,29,759,679,681,710,600,647,496,233,561,140,187,595,407,127,818,451,304,188,604,825,161,736,240,990,448,27,198,628,87,922,525,835,913,648,585,749,260,824,951,920,304,55,138,630,818,709,6,147,19,274,259,311,704,0,197,168,700,374,652,738,483,689,581,873,737,928,26,604,120,128,326,569,41,356,858,476,813,651,145,210,653,517,570,927,295,437,422,492,750,258,178,479,237,401,322,8,286,708,212,224,580,420,663,267,797,819,538,968,61,793,295,993,750,502,115,983,978,771,341,309,506,238,324,114,774,260,495,989,909,919,768,845,285,507,240,919,480,534,563,2,216,58,925,784,441,273,214,684,259,222,960,946,474,874,860,719,644,34,700,246,965,688,34,338,519,773,638,671,407,93,699,521,662,760,298,898,499,97,306,604,652,835,351,341,66,306,672,444,601,219,507,638,698,143,339,278,601,346,812,246,960,996,470,656,712,949,669,58,711,25,841,702,656,852,610,741,179,193,442,827,679,854,839,612,38,340,13,822,851,184,107,563,638,692,136,847,164,918,972,347,955,542,16,625,811,6,231,806,58,780,326,60,934,974,365,288,452,868,265,801,469,660,398,823,664,776,893,413,232,84,119,308,145,548,501,985,627,638,432,556,957,87,140,461,383,777,612,470,54,338,318,818,987,324,944,957,794,407,991,53,6,778,618,493,642,50,449,867,107,308,990,392,554,863,866,855,536,839,511,886,52,523,564,845,806,581,765,344,804,625,209,485,72,797,450,842,407,28,709,765,455,37,785,754,9,340,254,890,412,617,442,483,892,531,587,854,922,883,184,615,454,397,701,893,443,9,382,802,631,70,33,939,268,738,185,146,763,724,251,136,64,576,430,759,24,727,342,692,949,190,346,303,500,757,246,583,360,198,368,803,882,585,501,958,805,495,42,711,565,127,26,86,565,84,103,938,315,578,554,612,320,403,316,744,180,221,63,509,60,689,658,272,575,111,452,302,934,760,114,667,877,285,290,952,51,212,654,56,410,50,454,219,931,880,143,391,915,894,936,971,864,847,266,488,658,674,457,281,510,936,185,922,260,733,426,314,894,285,537,167,521,90,844,656,497,140,649,28,729,264,795,582,497,424,65,817,404,690,601,867,226,82,501,108,432,715,897,569,561,268,173,552,849,436,104,785,56,65,503,192,162,817,917,35,915,135,671,474,388,776,88,185,231,585,686,777,433,184,654,112,174,277,611,479,476,963,583,959,797,540,358,166,982,580,510,627,900,822,715,498,400,305,852,449,683,889,114,240,598,835,494,143,451,234,951,258,97,613,324,602,770,958,725,505,263,626,534,771,542,721,701,819,409,367,453,219,311,791,464,437,930,58,797,344,292,206,947,904,902,428,132,303,306,292,73,283,216,583,693,358,462,546,355,889,273,494,866,342,410,606,325,870,182,215,664,73,995,635,669,335,908,147,265,869,395,388,260,23,923,97,298,809,708,368,489,510,912,953,999,791,455,120,287,590,696,263,923,770,399,468,607,896,826,322,601,651,551,690,647,985,934,606,879,909,387,766,638,279,12,687,573,338,916,28,973,201,381,159,53,209,968,561,227,196,141,347,735,93,184,73,743,681,764,119,962,185,676,174,810,443,362,63,835,640,164,239,133,833,733,423,510,295,804,136,85,498,726,776,638,228,409,500,212,451,512,33,116,615,673,723,889,418,131,526,735,671,334,931,103,200,569,877,787,736,542,973,275", "772,474,534,982,468,332,909,215,492,867,214,543,208,902,498,428,649,617,971,998,463,659,853,457,57,68,301,647,769,977,897,395,999,660,645,376,708,240,134,66,575,386,775,292,130,89,542,773,443,557,809,63,569,586,162,833,990,381,209,742,781,582,408,67,775,419,994,803,658,91,888,678,77,815,449,726,476,150,759,765,416,310,443,360,104,206,413,94,465,916,956,539,512,341,316,294,328,763,31,460,827,66,111,494,300,545,508,264,338,687,269,601,881,612,44,74,10,37,476,311,280,324,869,353,765,349,531,198,146,167,384,769,926,411,23,349,946,192,895,764,118,846,353,606,484,238,301,932,76,172,534,862,554,670,717,799,136,541,47,500,602,104,970,468,249,878,339,147,15,909,570,164,352,28,363,639,328,699,450,916,100,965,442,225,404,998,287,759,773,152,815,625,161,785,231,855,953,792,45,940,108,416,988,43,556,392,150,557,84,688,73,394,54,405,963,767,517,136,928,18,773,267,654,443,559,934,489,247,287,883,89,378,280,541,529,473,510,620,226,244,268,939,298,810,240,376,599,288,562,386,171,35,872,191,770,270,331,187,296,65,689,734,372,367,883,221,626,552,993,787,804,523,294,800,397,710,134,974,377,188,541,134,139,452,12,88,197,0,813,895,768,765,691,534,406,967,270,877,556,507,982,855,342,921,405,462,595,746,767,903,553,306,499,574,251,808,319,568,438,380,163,8,931,770,688,787,341,975,427,378,83,922,634,412,171,991,477,188,722,164,200,382,264,723,574,948,892,949,778,937,269,525,442,579,849,399,74,111,616,13,29,885,510,516,406,798,989,828,797,887,830,203,460,657,687,458,266,389,627,624,650,719,71,476,694,726,249,319,1,216,172,637,169,14,658,629,347,931,795,28,210,242,240,60,548,995,87,650,70,48,517,309,978,158,277,504,6,100,945,376,166,658,642,604,808,291,810,166,108,806,690,523,695,272,519,977,996,341,394,879,809,274,786,882,672,347,89,776,893,184,126,784,350,242,523,584,28,965,11,404,455,623,771,939,569,772,70,342,592,903,92,353,291,824,90,13,889,920,73,102,53,879,543,968,951,556,936,82,702,523,117,997,632,444,668,706,726,882,293,246,924,387,137,416,191,749,361,49,667,796,134,68,533,503,235,642,40,812,424,361,420,990,698,620,404,481,10,206,268,458,791,44,435,373,79,610,770,480,628,214,488,123,599,26,409,162,802,966,892,527,903,428,580,667,398,661,957,780,589,798,60,824,371,506,368,321,140,208,743,283,403,471,885,94,125,317,739,39,238,423,58,777,808,6,875,261,723,266,573,692,188,212,407,171,265,704,764,433,265,52,647,545,227,607,915,384,54,260,419,300,890,691,949,398,369,595,336,548,702,424,596,27,319,909,993,258,904,217,864,119,292,506,971,199,369,756,131,394,835,678,947,692,191,757,419,389,132,410,930,578,725,450,440,740,411,759,635,136,905,225,716,703,960,515,126,406,303,138,362,635,467,328,971,935,359,948,890,811,770,531,948,781,1000,443,993,281,508,641,893,56,945,918,723,871,464,822,355,532,202,300,953,230,722,690,429,983,688,294,375,57,457,38,239,411,195,955,599,147,98,445,274,385,264,495,703,967,155,125,965,467,967,402,904,288,958,919,927,80,829,224,732,932,219,930,756,816,585,185,461,463,467,705,79,706,735,314,456,905,573,388,173,934,596,508,85,866,844,897,328,949,206,24,465,101,911,584,470,712,430,488,536,995,45,968,436,494,30,881,511,360,115,950,11,123,309,558,186,520,30,264,843,385,979,874,543,252,832,484,732,51,855,621,630,844,108,739,99,923,969,292,41,714,461,833,863,652,650,263,754,838,360,482,587,732,387,610,577,334,711,375,202,280,31,807,489,166,442,646,170,598,505,155,468,430,700,926,160,505,176,830,942,990,911,734,390,331,618,203,208,104,643,479,179,313,447,498,148,606,139,743,534,67,669,41,165,373,606,237,370,542,63,336,738,768,771,134,36,585,196,45,310,325,725,954,736,269,436,229,961,243,394,64,998,808,442,176,671,691,225,772,385,260,578,187,887,668,423,175,110,697,88,909,463,412,235,866,53,300,182,742,790,677,563,99,192,610,660,35,980,105,155,490,582,168,557,635,535,993,443,156,864,521,26,825,245,330,351,930,584,149,766,517,981,250,437,314,815,29,562,21,125,521,276,678,644,999,186,767,557,831,63,982,285,873,70,805,532,953,779,350", "943,660,132,336,620,512,535,835,101,951,439,111,772,135,357,188,495,994,409,126,137,323,280,577,794,566,843,945,291,705,27,134,552,930,121,186,866,25,890,519,309,467,644,902,569,205,815,808,993,58,641,503,240,964,261,657,43,891,925,720,186,538,658,646,365,551,971,717,402,466,288,457,789,262,389,659,882,795,749,52,405,574,414,822,56,748,249,344,85,994,578,13,79,236,197,146,559,358,426,3,774,942,315,162,192,390,257,696,831,425,749,40,545,427,639,702,60,979,876,301,382,655,240,28,71,432,833,103,26,907,19,969,81,444,500,339,936,294,71,940,975,852,31,748,282,452,304,707,648,603,408,787,876,116,683,964,52,24,908,996,398,552,79,496,81,790,155,820,11,430,57,507,586,259,102,712,466,109,670,64,500,946,935,522,551,821,61,315,28,982,57,549,129,98,430,530,819,661,865,282,914,793,406,808,309,928,574,219,747,539,801,197,435,499,365,114,847,89,703,477,114,237,392,949,454,188,156,52,979,92,183,316,739,175,571,378,440,697,810,909,235,885,662,411,944,279,656,495,352,514,5,787,63,484,788,818,713,81,241,819,687,549,414,647,194,904,12,124,743,440,628,210,763,756,628,705,977,597,345,15,683,524,547,332,856,35,168,813,0,222,755,956,879,777,58,817,325,835,926,864,521,677,565,456,680,245,775,96,820,218,224,772,101,59,726,448,592,754,538,923,518,37,257,231,45,402,364,318,952,616,479,790,442,97,832,680,753,152,448,342,995,659,278,790,978,321,978,259,332,972,441,213,638,299,68,836,722,673,412,20,446,667,555,585,256,144,498,308,647,432,696,344,604,867,58,851,925,845,101,342,439,831,358,17,577,75,207,612,838,534,935,405,873,935,37,31,159,100,184,290,994,563,756,54,514,91,225,812,614,323,266,697,100,472,776,472,992,979,359,362,285,508,20,656,111,52,749,306,490,768,358,136,587,292,616,846,141,311,506,213,149,627,281,95,321,616,445,551,962,959,268,716,727,522,531,38,134,325,159,798,315,854,438,157,229,94,663,913,898,304,271,839,185,272,725,557,10,124,542,575,413,274,566,341,476,803,317,201,326,671,956,563,647,59,960,608,947,924,890,372,799,256,8,346,513,197,743,280,846,592,942,150,75,491,63,51,139,833,89,22,754,832,560,910,19,525,566,758,81,655,359,772,985,947,389,539,595,105,816,998,565,49,74,29,621,859,240,823,558,600,235,515,188,868,843,366,596,466,920,765,612,878,606,316,182,801,508,671,249,558,266,972,114,989,209,869,48,147,558,221,415,236,418,579,47,595,537,977,345,229,290,597,772,111,383,200,355,30,592,339,559,748,243,573,645,739,813,993,174,665,511,589,197,574,247,580,579,404,492,941,297,282,157,508,574,652,524,822,7,356,210,151,144,452,916,488,224,470,938,625,853,387,618,154,799,929,318,643,858,877,991,585,601,141,352,656,297,869,750,361,119,339,847,243,780,288,948,927,930,702,613,524,349,71,591,997,115,850,826,604,224,555,426,429,16,900,785,249,704,312,19,331,355,139,222,359,884,136,702,125,56,205,359,794,719,366,501,797,766,866,860,178,412,685,13,142,827,597,98,640,8,469,569,628,682,424,275,462,63,743,345,165,172,754,247,261,966,886,545,723,834,321,921,230,38,8,82,361,642,624,783,93,512,268,253,544,664,329,169,90,476,817,983,471,593,320,680,232,210,263,948,634,508,620,204,360,113,739,327,9,221,8,102,826,924,112,760,765,284,257,916,563,198,732,783,780,990,645,245,653,566,103,349,616,202,906,239,323,577,661,510,382,503,488,45,440,341,778,707,860,820,313,308,701,249,224,872,967,288,597,195,565,77,850,984,943,512,107,668,327,536,930,887,195,4,244,677,7,342,300,286,246,239,909,311,328,150,262,399,762,915,549,37,448,86,25,476,798,272,891,792,524,199,24,443,78,956,232,678,946,652,568,219,215,522,256,266,786,777,687,22,872,103,685,968,644,597,992,205,182,797,707,828,830,678,92,767,720,418,352,773,943,147,868,852,157,293,122,749,337,903,983,242,203,410,971,107,833,398,942,362,984,789,553,672,375,983,376,728,217,88,431,168,499,277,157,500,3,363,345,408,963,862,557,229,354,361,793,810,398,783,709,732,996,103,467,870,455,889,193,661,43,323,718,268,25,348,789,975,912,89,601,501,603,311,139,232,280,23,933,948,765,807,806,162,464,38,732,591,858", "183,455,564,284,208,112,597,276,148,404,339,352,568,336,129,822,555,915,769,760,29,208,336,406,946,194,918,716,231,329,497,300,202,782,584,64,339,740,966,272,23,299,335,47,302,896,244,902,594,991,18,296,612,841,888,67,260,575,815,541,279,691,962,323,410,784,843,782,883,792,698,166,9,91,218,620,972,386,905,195,471,803,152,171,472,299,118,946,659,124,981,335,607,851,81,329,729,499,927,350,930,786,490,163,129,817,718,13,803,384,620,341,502,530,354,974,80,417,723,927,621,589,893,671,100,665,805,620,364,213,179,71,686,931,707,631,106,586,298,511,165,198,52,152,178,839,199,427,657,235,767,471,512,150,26,552,820,398,195,584,729,904,292,387,731,387,733,241,786,487,680,326,997,656,648,2,266,153,520,392,311,395,157,101,337,238,685,649,948,574,367,10,246,660,368,793,713,775,293,346,821,5,516,239,412,637,257,543,897,119,165,221,667,766,815,115,117,841,977,45,242,151,650,939,699,616,160,602,786,932,166,818,745,424,694,563,282,739,368,802,328,573,26,936,910,481,280,572,251,936,160,61,317,237,621,752,234,87,807,682,752,781,898,136,889,158,59,239,108,926,984,294,439,700,196,324,592,221,873,993,694,823,795,840,483,138,700,895,222,0,864,522,319,559,518,92,683,267,205,311,610,593,259,837,679,874,828,972,58,932,261,779,297,18,586,449,404,296,5,185,622,787,789,871,943,37,403,537,893,659,931,767,129,43,132,182,166,594,626,881,311,426,703,955,453,946,365,454,1000,897,291,669,857,357,604,769,68,467,555,580,336,792,451,309,931,119,131,783,471,838,498,585,934,652,473,723,767,481,703,459,726,642,538,79,800,596,494,41,47,586,153,485,207,780,777,417,487,410,691,717,519,62,882,586,776,293,813,93,104,149,298,964,956,976,501,374,374,842,940,465,872,406,895,531,696,259,593,670,182,578,832,333,623,249,113,996,88,41,593,393,844,630,982,205,33,368,860,305,686,133,355,241,705,360,973,752,424,941,619,3,254,710,826,991,772,372,272,486,227,698,135,581,527,335,945,937,717,580,636,535,236,483,468,854,198,179,967,576,557,200,108,49,384,248,555,204,216,68,112,416,947,12,752,256,951,491,568,280,917,361,100,921,263,430,855,782,497,910,835,712,953,414,992,280,111,967,955,619,972,459,77,67,660,550,599,348,816,846,724,75,337,67,495,313,983,994,869,594,751,730,823,983,592,63,328,544,707,623,476,359,435,123,271,538,608,31,120,875,215,792,962,794,753,532,449,680,150,102,389,331,617,765,424,352,905,623,865,370,988,815,881,814,952,900,338,795,56,358,489,779,283,321,520,899,297,292,332,501,979,982,989,606,245,101,411,573,365,956,674,924,140,54,829,31,902,589,613,643,9,478,869,642,549,159,536,555,686,289,474,168,320,653,808,983,440,340,139,345,712,517,938,633,363,970,748,794,572,964,251,833,293,751,211,701,602,565,259,642,74,192,443,627,231,369,200,10,150,716,11,722,751,744,442,762,887,899,606,141,498,638,919,507,242,126,579,124,342,738,416,63,203,331,375,727,619,923,438,300,381,470,838,251,150,66,55,525,672,689,951,473,887,640,776,745,165,856,494,589,621,12,947,826,848,406,987,980,814,558,115,581,64,965,263,610,463,677,695,226,667,201,308,886,898,87,728,900,72,205,330,424,856,35,798,867,512,843,250,780,649,375,680,556,894,718,765,206,191,190,6,319,655,803,321,468,630,728,8,791,425,215,548,781,755,848,113,425,670,563,958,465,882,756,301,782,662,354,915,645,207,36,634,50,631,33,984,601,503,224,928,653,449,707,188,979,829,932,847,85,987,139,973,557,657,628,259,541,591,804,593,823,155,709,138,795,437,973,487,425,826,92,265,106,24,885,406,384,954,159,949,897,638,36,173,249,290,939,331,947,148,712,730,866,559,807,810,826,658,488,471,706,692,371,225,747,382,599,7,617,463,422,743,922,994,146,216,198,951,900,414,210,415,913,297,334,867,438,196,667,37,118,784,422,684,730,416,617,253,31,395,576,194,575,771,750,71,693,57,965,281,175,754,202,596,681,477,95,645,887,50,910,591,25,215,641,522,385,505,155,858,300,777,765,925,508,126,519,10,195,883,347,899,950,45,372,976,921,790,307,569,277,504,818,178,901,262,36,609,192,571,522,671,96,932,921,912,61,278,511,498,682,301,908,72,52,663,690,515,262,280,464", "6,32,482,604,428,357,878,581,593,277,329,659,673,105,412,501,148,672,834,172,859,942,412,648,351,687,288,292,866,881,152,560,474,98,164,708,807,167,33,229,938,699,934,463,920,911,300,596,601,133,876,260,329,929,918,356,466,451,465,513,121,547,627,700,2,315,22,285,919,174,552,926,237,953,216,872,731,594,464,972,267,932,496,294,610,544,802,334,119,151,403,918,63,428,464,303,431,777,741,817,84,885,138,614,774,113,504,21,215,68,78,662,5,307,617,226,671,149,171,387,399,744,687,727,526,649,155,765,546,650,236,373,513,660,549,373,204,815,250,192,876,581,997,619,386,335,172,757,989,934,265,924,461,373,24,680,399,924,104,322,514,861,600,941,728,6,225,856,966,662,891,678,931,857,892,477,347,260,893,225,745,726,329,732,455,461,962,282,789,965,515,485,969,527,508,386,267,847,53,393,692,576,205,702,345,739,495,832,823,993,541,513,981,724,458,909,91,339,665,211,148,696,986,236,364,508,970,750,884,715,566,830,710,399,749,256,280,425,77,208,125,325,833,289,73,876,740,789,840,270,861,937,320,754,363,443,559,798,363,795,356,257,374,789,271,125,338,482,982,608,890,745,512,127,53,862,584,991,978,630,935,192,952,825,592,299,374,768,755,864,0,388,260,904,904,234,851,565,750,553,375,776,48,960,363,329,242,52,854,535,110,875,92,363,679,616,843,321,734,233,532,100,565,688,955,803,871,503,826,161,253,416,292,981,961,809,581,658,595,533,655,579,663,453,582,56,236,43,458,523,295,367,254,690,666,264,998,191,247,937,316,381,998,154,124,831,31,748,502,33,276,469,294,798,490,188,602,693,374,476,820,132,509,143,771,897,404,586,399,367,36,974,685,997,304,571,991,275,293,240,796,121,367,124,94,492,404,332,226,814,110,713,857,546,588,386,983,526,124,110,437,26,820,371,227,475,352,256,712,228,244,938,778,167,787,858,807,987,794,272,636,654,359,798,236,455,946,323,546,652,486,894,320,768,165,47,481,816,649,671,488,712,175,35,287,167,712,633,41,670,701,938,929,75,637,686,692,109,683,658,493,484,517,137,457,550,842,992,912,411,351,334,532,349,113,122,639,745,634,290,164,3,218,628,390,592,952,539,256,311,705,749,990,151,927,127,542,345,427,803,724,369,100,875,776,464,504,655,212,131,237,425,472,228,204,808,649,63,192,707,613,426,117,787,11,988,746,889,962,909,865,918,859,497,663,968,459,122,245,951,653,108,898,113,248,993,500,362,700,846,693,52,871,826,865,402,728,67,51,522,134,207,895,612,913,208,877,517,269,493,766,783,875,778,431,588,797,743,364,724,405,814,362,623,57,694,156,534,447,12,576,542,893,824,22,361,262,198,582,133,813,290,669,563,881,891,425,25,759,992,740,217,997,285,274,919,596,932,83,900,43,307,360,872,721,224,223,99,267,173,855,28,96,842,28,964,714,519,222,355,323,456,373,504,800,98,208,663,918,989,661,469,272,933,458,320,222,733,461,895,754,332,901,483,78,661,928,348,256,55,390,368,205,202,509,989,276,502,170,333,806,819,833,767,265,777,991,376,561,580,128,399,379,81,509,40,755,101,47,550,253,129,773,671,187,339,512,827,112,357,143,70,126,810,534,767,109,671,124,555,708,112,14,183,190,247,146,378,166,164,41,564,197,724,446,773,637,153,627,823,57,163,785,834,625,989,384,708,420,729,690,746,939,232,735,608,766,393,89,500,690,551,333,137,683,704,291,764,27,961,364,749,611,121,687,775,386,149,529,599,585,771,166,448,804,805,196,76,419,961,758,471,669,461,606,646,117,342,842,435,876,501,681,958,641,685,244,56,574,846,950,30,900,521,627,667,27,749,455,247,490,905,980,627,329,682,516,407,696,414,65,500,205,416,294,405,48,246,281,24,684,882,947,169,11,525,887,484,737,915,980,808,512,938,661,481,301,120,605,201,532,105,920,193,755,284,671,528,88,473,735,783,898,82,284,319,748,225,278,999,317,601,297,407,884,159,902,332,466,123,736,692,97,212,718,634,780,445,311,102,403,524,515,690,485,270,916,468,544,746,245,352,288,758,78,85,549,310,252,933,354,461,253,381,37,222,314,383,572,144,601,689,675,167,726,92,776,562,459,591,897,678,667,111,834,924,657,496,732,396,856,347,405,383,470,694,972,647,265,989,338,742,579,801,684,353,441,141,100,89,413,962,733,936,839,701,958,825,608,655", "84,871,430,411,374,714,101,167,329,454,789,347,629,708,268,96,566,468,971,100,960,342,587,230,13,866,405,634,20,856,572,997,260,341,261,836,906,622,219,948,756,794,937,433,349,88,747,330,841,298,734,588,657,207,416,965,385,689,680,735,534,468,992,87,351,767,946,579,497,426,699,348,838,211,856,690,238,305,9,922,340,370,181,908,992,511,529,542,333,635,983,11,478,534,38,201,642,219,806,689,854,933,531,998,32,288,896,223,132,531,958,289,114,359,383,245,226,263,955,786,5,294,447,58,540,18,117,891,642,23,750,696,490,19,194,899,664,616,207,12,577,319,361,724,961,833,906,326,892,396,642,752,10,577,100,433,642,189,641,941,39,641,459,708,55,750,140,926,227,371,618,964,410,428,832,328,900,209,756,553,804,503,783,946,86,967,813,944,998,710,461,869,776,588,804,467,342,723,139,72,479,225,816,68,343,402,842,798,15,448,581,751,680,597,697,420,161,949,907,538,641,928,946,33,646,924,952,380,776,909,176,991,169,387,400,584,317,235,651,683,238,836,684,858,336,562,925,312,498,437,990,509,598,190,225,710,285,541,240,734,833,130,374,999,27,921,70,127,270,250,215,38,594,618,701,457,556,476,580,974,25,565,26,467,539,470,652,765,956,522,388,0,126,458,901,864,434,400,473,925,650,793,408,122,832,158,38,801,512,359,156,560,97,292,568,876,231,983,674,705,869,763,940,939,997,198,492,369,156,396,7,584,372,234,416,895,689,860,664,6,738,690,758,692,813,589,141,89,157,96,695,817,352,938,112,297,549,32,705,701,570,665,260,280,924,285,739,246,543,464,27,795,202,365,548,119,503,470,705,296,942,333,1,73,700,342,851,348,712,781,408,466,713,805,364,227,927,453,749,246,727,296,396,409,407,356,968,316,875,543,28,632,827,269,756,87,684,737,369,271,977,563,549,521,430,726,107,413,233,735,96,120,340,723,287,567,136,659,654,16,745,656,992,896,344,509,719,480,124,136,317,21,221,211,549,341,19,362,977,316,515,626,981,110,164,794,772,218,915,943,186,419,974,326,335,737,925,191,152,762,646,186,746,46,38,888,821,385,949,761,873,7,332,723,944,46,58,590,755,910,827,337,895,545,937,288,768,506,417,33,908,849,682,158,947,755,506,985,919,751,181,579,831,613,74,93,738,334,339,734,615,502,664,718,330,464,866,888,197,452,796,729,486,55,359,567,378,603,649,281,665,734,411,904,85,366,604,838,395,559,380,652,603,290,169,52,484,213,576,173,271,128,339,429,795,64,358,272,29,900,727,56,623,439,141,184,30,493,17,51,744,709,100,79,924,989,34,170,199,443,165,778,45,345,766,349,869,258,677,168,440,620,75,440,867,309,487,896,958,131,336,638,26,408,380,344,938,319,149,781,101,738,613,676,232,84,499,418,609,207,641,778,394,873,82,185,338,228,98,98,586,124,791,854,381,376,171,822,848,633,593,348,506,181,413,236,650,557,174,564,217,941,707,730,796,973,99,598,592,666,779,920,466,4,497,961,12,205,959,909,766,263,43,171,543,97,697,776,329,892,517,904,915,3,30,582,864,517,326,150,902,294,257,594,891,253,500,799,501,562,464,401,685,634,822,80,114,555,667,391,162,810,98,109,289,99,479,608,486,549,746,927,723,372,836,416,822,780,643,524,111,990,21,815,737,814,732,479,342,747,292,393,842,373,84,843,707,114,36,732,769,823,609,574,986,961,226,255,291,545,563,823,510,934,193,651,292,343,712,867,715,79,228,993,138,913,618,769,758,749,304,195,819,540,578,32,737,62,637,929,191,60,385,814,284,41,871,648,184,823,398,166,366,392,498,501,721,53,853,362,402,151,98,940,735,746,93,13,651,318,174,607,925,586,275,775,587,533,212,804,327,944,797,15,958,309,325,760,886,233,349,684,885,123,682,864,800,184,650,845,894,385,219,591,44,597,917,444,547,338,609,515,175,541,378,49,765,83,218,734,463,844,160,953,429,237,71,109,976,875,198,773,707,845,753,374,53,368,994,101,496,402,338,621,665,687,258,235,996,350,175,91,95,78,462,349,844,185,660,968,744,914,243,594,231,863,832,838,146,250,748,578,739,949,708,755,18,688,804,617,257,142,924,121,287,331,418,864,185,30,69,276,119,227,727,477,979,682,662,657,431,390,525,71,59,348,405,935,298,639,356,84,432,556,662,431,230,54,764,128,187,67,938,634,692,16,934,524,567,829", "984,305,564,974,89,536,87,624,630,202,270,542,299,119,816,964,163,206,438,318,467,223,722,927,704,439,275,646,808,495,86,110,975,209,356,877,956,655,317,315,586,796,726,526,220,506,49,38,134,236,530,494,148,178,2,854,406,563,463,782,291,588,660,139,127,34,801,830,872,711,253,676,367,156,464,926,630,310,421,140,424,687,685,992,340,783,851,714,673,285,466,895,948,562,170,634,211,970,211,180,506,682,849,235,929,921,83,738,945,350,285,194,120,946,421,140,507,381,796,610,922,163,897,414,50,17,259,799,291,969,938,632,309,615,125,523,355,607,259,105,765,508,980,635,209,565,541,232,639,487,339,296,289,772,191,652,302,216,339,616,930,266,451,798,249,403,927,517,905,849,324,114,258,202,734,989,444,53,131,631,507,789,499,514,201,494,476,344,137,544,687,697,494,611,471,658,892,684,372,946,522,17,743,470,312,815,896,106,92,358,148,942,44,253,981,380,356,326,636,910,536,802,156,878,8,675,83,677,755,863,1,283,598,650,477,191,516,204,178,17,867,857,755,870,353,906,493,2,433,813,311,630,625,322,794,90,697,947,532,763,545,94,76,267,71,341,674,593,924,985,820,643,443,96,248,811,478,839,101,936,500,195,414,700,782,245,738,691,879,319,260,126,0,363,203,79,400,606,810,276,780,201,808,785,598,860,703,193,915,370,420,448,246,259,148,817,97,358,951,163,76,863,905,898,412,36,394,613,128,5,515,713,431,209,291,227,402,633,283,867,526,249,327,385,34,842,885,407,190,45,873,239,887,25,128,331,755,306,629,953,891,454,398,88,112,581,835,446,995,147,591,646,967,231,928,984,801,604,537,579,801,174,913,948,905,975,456,609,47,624,655,682,932,410,922,361,580,717,667,797,62,581,480,255,59,142,500,716,376,265,501,445,696,676,634,835,506,48,70,91,22,525,836,475,195,888,590,950,382,506,265,639,334,795,48,646,327,455,763,271,898,881,920,473,108,702,665,312,211,368,39,563,829,690,975,722,365,61,493,199,337,903,177,824,615,438,132,767,651,464,428,993,769,77,240,504,663,500,503,190,638,331,232,757,338,63,260,650,970,432,275,155,484,361,239,846,295,122,973,771,388,99,140,303,726,931,322,121,6,677,644,902,421,431,797,431,72,173,131,954,308,514,716,314,264,298,917,612,928,730,903,223,637,384,907,579,407,365,941,111,57,636,614,618,261,991,628,747,637,500,716,223,226,320,224,389,399,106,814,180,182,712,749,355,164,356,854,832,580,36,256,935,106,28,174,595,697,23,798,560,371,247,662,612,672,152,437,362,406,471,569,54,920,387,92,607,725,288,604,38,615,61,113,226,500,186,85,835,908,207,666,879,116,455,787,167,73,393,259,814,1,517,716,94,828,986,806,639,972,615,174,107,986,834,624,23,914,588,377,349,587,789,329,587,581,564,64,76,83,804,341,613,910,942,175,845,771,195,495,505,638,809,617,913,738,857,639,274,767,223,430,989,558,55,769,500,431,505,14,608,459,552,14,384,931,714,480,879,779,215,188,385,838,195,960,419,160,47,629,784,950,967,896,799,272,545,658,454,999,455,686,191,296,212,41,183,656,630,738,651,7,250,65,716,953,437,591,688,987,239,643,856,865,748,415,975,804,628,383,182,532,671,67,46,697,377,655,166,252,928,679,171,970,981,748,996,68,100,339,967,621,76,816,271,255,959,223,586,213,860,285,976,534,123,153,390,167,248,161,866,846,519,208,374,86,565,174,214,360,872,36,429,242,857,268,961,573,427,515,473,759,554,629,822,440,276,451,338,243,902,712,796,140,440,914,704,344,857,916,651,328,909,492,920,305,8,797,252,423,722,448,974,842,80,948,271,78,694,796,342,647,693,835,514,338,54,814,557,962,470,434,967,940,579,37,44,80,914,345,118,204,586,727,155,69,735,134,914,287,10,29,382,206,892,275,38,803,13,854,612,451,802,279,82,537,300,846,329,534,518,367,880,127,252,112,485,344,432,694,688,787,129,77,791,975,918,721,291,885,744,988,49,883,235,366,67,261,36,143,846,625,977,884,101,109,304,491,908,613,652,267,777,570,844,101,362,16,201,296,406,724,492,452,43,885,552,573,753,141,58,879,939,461,592,889,403,298,817,356,359,893,855,312,251,600,92,37,805,148,335,270,760,483,511,264,436,509,178,908,110,953,176,919,53,732,406,876,895,45,153,115,688,55,45,409,646,116,301,706,145", "619,571,128,808,572,203,32,183,646,514,472,180,960,844,118,18,552,222,492,874,744,991,869,74,290,767,264,628,473,955,36,932,809,266,423,501,674,658,609,943,604,964,68,348,517,62,110,826,705,369,398,647,513,973,90,295,464,218,171,370,10,300,158,460,998,591,157,71,701,788,352,431,818,648,272,712,548,327,51,966,299,566,476,277,756,444,710,887,31,749,553,448,767,124,909,556,468,715,124,751,90,506,788,393,46,586,443,976,196,95,434,754,695,235,802,58,713,41,778,571,866,689,120,620,757,68,459,419,590,757,102,825,142,735,623,902,275,410,293,192,118,53,433,485,852,561,430,26,451,208,638,718,521,457,140,676,77,737,276,475,69,197,914,940,607,629,701,477,701,27,993,816,624,112,707,145,88,586,104,773,793,628,249,126,986,743,222,322,66,662,838,605,319,946,335,188,91,491,194,326,502,881,619,105,801,577,263,873,431,495,545,234,835,748,534,408,864,812,971,454,951,278,505,13,675,424,431,467,308,642,140,810,216,766,592,92,370,568,209,981,194,82,111,466,514,355,198,418,473,624,605,276,218,43,194,867,179,398,447,80,162,20,797,893,586,230,141,778,929,683,702,399,204,870,738,790,873,724,769,985,264,659,287,795,941,328,483,534,777,559,904,458,363,0,745,298,359,831,932,93,688,627,508,623,984,923,494,390,255,783,345,130,514,946,524,650,342,887,560,347,30,60,561,675,129,106,303,140,551,721,331,428,241,98,205,533,883,6,684,338,471,477,672,754,472,477,816,684,374,328,164,73,253,141,873,503,238,586,369,573,853,183,552,305,964,323,752,158,68,998,825,365,425,833,464,816,600,70,500,8,818,700,28,999,140,453,491,248,80,82,242,691,312,549,207,896,336,926,438,428,338,193,715,943,603,311,404,786,65,90,764,928,635,751,618,38,108,926,68,885,550,265,687,337,537,152,171,539,964,153,258,371,76,774,495,823,607,82,81,267,169,305,487,388,67,673,700,865,973,381,677,298,476,130,705,756,855,475,781,803,581,548,732,379,859,292,711,762,415,787,270,536,631,44,356,36,990,122,866,519,661,544,235,651,72,594,468,894,593,921,574,876,96,992,111,294,20,748,912,416,178,310,631,195,427,81,688,787,404,372,690,520,640,745,994,256,157,97,902,818,752,107,529,713,774,958,546,35,666,192,424,63,727,863,622,936,244,563,64,123,386,954,489,652,606,664,968,846,666,963,530,154,86,853,243,866,470,100,262,694,18,332,821,950,836,32,928,410,570,562,10,953,868,391,369,202,414,692,772,642,45,869,114,977,49,729,404,276,646,478,105,154,470,485,36,13,350,672,441,577,48,647,754,215,246,93,791,555,154,225,574,52,638,399,800,251,247,122,776,466,993,564,969,927,682,293,589,461,78,752,770,130,945,786,433,975,184,761,500,569,5,599,511,44,798,703,362,925,433,820,981,896,560,547,727,307,610,866,527,773,61,865,983,65,57,800,310,153,133,840,403,398,492,575,99,616,22,48,716,327,767,681,844,751,507,845,789,174,367,931,253,23,188,850,288,373,521,80,953,94,193,718,960,128,253,12,585,378,319,861,947,75,488,181,685,888,688,890,486,806,327,148,846,987,165,802,672,315,696,730,725,385,202,9,118,827,912,183,974,600,255,493,886,569,523,168,895,658,565,42,484,728,105,361,178,187,36,727,865,485,96,533,22,149,444,481,217,13,751,814,497,301,171,965,176,464,309,438,563,234,183,643,935,280,487,269,74,765,900,897,619,783,964,389,5,316,953,647,199,450,434,939,913,298,540,15,859,362,365,843,486,135,899,749,692,401,854,12,148,313,841,665,289,853,113,346,818,980,391,774,877,679,47,194,489,396,414,991,125,139,904,791,300,511,279,268,939,537,57,562,467,250,80,394,162,582,569,181,803,351,608,833,484,135,439,873,176,989,974,449,973,277,982,939,92,41,798,184,587,232,288,14,494,726,945,268,267,266,947,283,893,924,826,78,683,472,91,449,900,146,319,343,361,529,148,578,250,340,120,530,728,695,490,814,837,385,967,450,307,651,539,719,855,84,634,136,842,671,575,307,798,983,92,699,454,163,257,551,247,811,214,724,151,410,192,606,354,486,754,820,785,825,779,770,376,733,389,493,836,915,833,738,578,48,768,444,862,254,706,150,24,937,98,711,368,427,822,190,822,395,785,875,686,81,672,890,517,241,984,515,503,556,946,760,689,931,925,2,150,769", "453,646,996,349,288,95,404,953,343,458,485,502,54,440,890,315,643,748,387,152,84,389,300,395,732,373,674,631,726,744,631,611,852,911,247,101,721,241,924,39,634,361,723,563,586,626,11,777,564,73,668,42,51,71,990,502,963,588,443,170,942,106,987,716,415,284,658,512,499,71,172,782,104,82,916,999,463,155,269,864,55,483,398,232,962,103,299,451,27,733,34,486,746,537,53,89,46,916,533,795,435,868,705,952,882,252,895,569,388,403,792,670,924,354,588,540,822,702,536,104,725,910,893,238,752,936,624,456,629,330,569,163,235,101,67,171,566,35,71,568,550,707,961,683,73,867,652,639,714,968,620,366,427,426,264,615,924,621,745,641,34,46,725,870,821,323,136,162,113,349,972,214,170,423,496,95,319,400,364,998,721,829,600,653,948,761,628,769,642,781,255,444,57,488,119,263,757,274,117,516,594,721,613,746,55,340,216,105,218,101,252,459,954,290,502,793,157,453,8,748,666,741,537,176,495,761,578,650,206,692,798,628,513,235,678,171,567,181,730,932,599,231,239,829,541,21,83,322,770,904,402,690,326,993,431,112,497,872,56,64,752,950,787,782,853,866,742,15,73,978,724,783,135,370,202,981,382,25,250,725,305,885,521,123,725,401,689,406,58,518,904,901,203,745,0,804,804,632,856,888,882,684,947,361,982,693,585,550,283,824,803,709,2,165,529,71,580,195,347,724,79,316,486,263,35,251,346,498,151,170,709,34,547,805,885,394,171,776,379,93,83,937,296,60,985,308,238,584,240,97,522,55,585,751,955,4,936,81,896,549,563,329,45,319,43,857,332,611,237,853,702,457,704,613,650,224,839,960,379,802,630,188,135,375,956,184,172,947,583,16,290,316,944,345,793,646,407,560,993,6,193,134,515,720,360,220,23,770,104,746,764,830,852,552,726,931,475,295,424,603,434,79,128,153,850,161,671,761,640,892,814,840,383,278,846,403,818,592,116,268,764,191,470,855,683,955,1,897,220,501,121,919,46,513,319,981,185,465,128,317,176,171,934,170,772,241,99,430,476,839,746,731,169,519,450,499,487,12,772,588,416,903,86,276,413,331,355,958,522,441,510,115,899,366,73,447,219,820,350,502,367,922,941,845,268,734,736,856,265,674,132,172,401,743,913,237,53,259,734,411,575,140,870,59,391,902,125,675,782,610,82,307,813,267,394,477,36,808,146,280,973,158,703,127,905,769,500,467,609,232,785,548,291,258,132,228,574,201,797,168,360,666,665,64,218,664,159,250,661,907,780,285,531,960,972,125,568,526,589,297,31,946,982,211,211,388,779,557,802,217,732,400,405,158,270,531,3,818,576,258,508,741,796,553,410,629,701,568,545,822,224,360,745,217,60,109,863,733,702,232,746,478,422,10,589,385,615,773,80,174,454,324,249,949,637,62,414,568,509,559,382,619,695,156,506,998,967,385,503,527,509,669,368,796,218,16,405,548,636,318,328,514,405,934,797,279,614,943,213,581,896,338,716,611,561,52,361,645,524,318,929,717,214,997,793,340,102,593,821,570,741,160,653,316,6,80,408,906,749,325,623,391,133,774,94,954,938,172,90,5,657,676,850,645,982,769,154,43,251,83,53,769,476,213,821,466,349,502,227,991,958,325,996,104,578,504,659,431,257,129,407,441,277,67,827,813,363,748,984,99,87,39,604,532,244,270,410,83,911,743,490,793,452,807,295,199,397,994,217,201,784,129,308,582,627,909,661,240,265,153,362,558,190,193,467,783,450,281,230,283,513,143,324,245,428,864,542,375,723,143,832,261,417,365,570,64,554,490,786,589,750,791,650,699,907,735,642,505,382,526,769,606,103,878,699,799,96,630,733,405,715,974,738,456,187,616,76,480,623,411,764,61,18,419,390,383,613,600,901,338,672,937,153,145,627,207,666,124,165,616,390,288,85,538,451,963,478,41,861,979,605,908,735,440,592,205,379,201,924,470,55,635,554,358,992,190,441,643,18,50,212,181,618,136,767,417,201,483,205,8,574,950,81,954,75,19,285,249,950,979,555,70,24,338,802,925,181,552,895,394,311,574,785,342,975,702,880,16,171,232,511,753,215,720,285,823,527,135,593,626,664,235,187,499,980,554,1,721,594,466,560,984,515,618,102,260,304,574,271,200,893,932,818,102,19,404,97,132,279,571,488,312,918,387,986,369,44,33,769,691,516,951,806,218,977,153,417,187,293,809,691,420,607,617,75,32,851,713,310,725", "729,477,185,808,456,570,194,552,509,514,373,606,528,306,642,523,513,787,574,667,259,329,70,558,718,513,468,97,177,462,342,464,540,589,643,36,244,419,208,13,613,597,156,88,966,653,703,804,154,367,921,254,794,318,963,97,747,39,413,511,855,519,90,123,108,263,899,815,835,119,522,902,57,918,251,976,706,137,123,727,3,566,257,247,8,400,775,356,959,487,190,134,724,369,666,295,19,298,95,411,148,126,409,836,379,511,150,786,738,671,142,334,797,150,111,789,673,697,948,597,880,919,419,662,410,778,166,566,390,434,304,163,146,128,820,86,375,52,289,912,223,288,957,285,931,678,609,275,583,619,341,856,94,79,949,151,902,360,504,355,36,464,615,534,992,570,566,258,110,361,574,345,123,441,218,370,810,917,290,298,162,316,514,921,631,335,543,953,778,93,546,677,191,18,794,48,934,771,904,75,252,644,156,561,67,5,871,734,999,530,220,614,710,335,55,155,520,579,63,116,268,65,86,627,730,195,65,708,961,276,320,884,245,370,977,148,519,733,329,333,388,914,896,266,113,92,139,887,482,1,391,808,491,783,55,803,579,754,7,619,577,393,841,217,586,47,393,148,73,731,435,534,769,376,575,684,156,218,96,231,632,772,260,411,141,303,581,967,817,92,234,864,79,298,804,0,827,289,551,391,761,550,689,530,148,46,540,811,728,468,478,619,244,596,662,347,416,281,725,548,566,625,47,391,76,982,17,533,275,164,151,144,750,845,851,799,986,874,683,547,677,827,49,182,50,894,962,967,465,575,359,54,494,49,524,736,765,226,499,567,249,180,487,858,882,851,507,722,280,315,61,118,471,961,84,527,265,101,72,347,748,585,77,282,872,270,253,18,815,402,945,283,796,863,362,577,531,674,907,910,438,363,139,79,910,330,29,625,949,909,104,79,128,327,558,629,250,393,803,444,807,749,479,738,505,125,259,207,381,551,757,739,112,103,917,31,202,310,419,22,619,903,992,140,101,996,660,71,993,465,223,139,56,557,9,829,157,312,307,703,183,689,523,686,796,473,983,917,583,198,979,807,614,924,868,225,672,884,979,199,668,400,451,660,330,453,454,946,744,527,146,954,185,102,149,980,792,7,456,541,118,387,80,492,336,904,78,789,981,442,835,554,666,832,939,583,561,977,958,887,858,368,729,964,531,718,871,956,68,451,871,204,829,557,805,402,453,976,371,724,688,410,377,714,309,483,401,242,655,678,629,481,211,893,566,237,780,714,272,126,518,418,737,676,430,514,136,82,282,866,350,95,629,225,656,659,906,879,899,665,213,471,442,87,393,149,370,861,549,425,52,814,480,469,405,982,626,578,424,178,851,417,403,777,895,254,151,653,856,957,930,193,71,705,121,841,702,962,66,260,697,124,820,962,621,60,64,674,800,938,551,172,841,665,870,8,798,464,78,955,513,834,687,601,132,743,43,614,343,265,820,901,189,745,347,199,470,599,275,118,259,231,7,836,243,387,686,577,235,957,838,382,300,147,9,931,975,727,944,687,576,425,772,266,974,895,481,433,958,326,847,848,268,819,375,271,723,198,948,846,233,975,100,361,957,373,498,708,371,965,963,305,941,369,415,27,763,157,604,948,246,143,817,622,660,887,135,338,32,340,435,112,25,96,772,427,860,811,643,769,988,255,67,872,237,586,930,275,217,288,790,838,728,967,560,661,506,879,564,328,366,914,665,589,84,149,764,818,516,704,143,560,18,762,185,634,568,184,538,225,272,32,739,59,719,920,725,877,115,963,94,383,721,68,948,716,994,131,521,849,62,833,348,760,386,198,140,261,811,88,561,802,350,841,683,887,98,65,494,866,221,664,197,722,709,215,585,906,915,228,367,398,543,974,245,458,591,847,118,295,844,555,977,432,292,678,599,421,769,186,482,620,237,440,25,321,987,417,757,524,992,200,667,47,480,203,397,500,6,820,654,25,54,694,936,674,39,684,867,583,876,474,871,996,297,614,344,867,866,567,125,6,825,520,375,907,1000,460,576,804,123,990,569,211,894,594,594,257,661,573,439,919,838,59,685,143,311,909,286,876,864,964,162,291,221,890,539,318,916,597,320,446,874,714,692,946,769,501,452,308,379,535,791,450,84,307,295,209,964,873,994,799,522,19,630,930,856,265,51,313,372,468,278,793,249,298,614,551,178,867,574,6,124,671,965,482,577,301,360,431,720,894,407,561,514,357,348,589,895,264,640,118,503,459,799,333,500,801,682,362", "744,890,345,688,506,861,555,245,647,958,67,996,520,102,197,954,918,30,573,380,197,957,718,264,496,85,166,774,556,172,905,675,737,670,234,980,510,147,952,602,379,763,794,714,907,887,193,651,849,980,840,629,743,972,84,926,630,477,909,54,140,775,493,926,954,489,731,667,694,830,991,940,279,826,592,4,133,189,23,564,69,968,238,783,53,519,885,513,590,639,458,382,445,650,633,994,13,328,598,8,309,371,677,427,916,737,347,873,772,408,412,109,86,797,231,624,646,89,974,463,712,338,168,560,570,164,671,602,77,596,185,204,752,742,324,64,328,395,289,785,100,888,241,917,529,391,273,567,31,148,747,675,837,514,133,642,651,538,210,663,731,957,102,347,571,432,903,200,474,151,689,856,205,127,995,250,618,23,44,722,779,661,322,388,63,606,802,227,351,985,205,153,169,932,401,60,393,179,471,154,432,616,330,445,72,220,909,553,103,743,236,64,818,24,350,681,555,1,462,401,822,890,901,259,59,957,137,731,947,39,159,576,848,406,568,513,521,730,923,14,177,546,662,496,187,134,194,230,966,184,966,335,176,581,989,630,919,758,782,329,56,983,80,628,366,651,733,49,175,850,539,970,689,50,903,976,626,605,709,569,464,682,111,996,512,988,873,270,325,683,851,434,400,359,804,827,0,172,932,869,948,661,650,639,5,608,391,121,882,832,914,644,684,697,635,657,254,539,295,204,321,952,714,649,929,376,218,759,66,443,660,905,127,994,148,555,891,338,498,101,341,869,592,555,978,716,93,369,545,537,453,566,190,930,969,400,896,108,470,784,501,122,364,840,905,430,557,244,465,761,238,19,450,566,416,682,282,937,303,857,966,153,471,468,341,437,646,179,208,272,735,987,880,21,373,140,764,210,853,813,279,49,798,646,797,331,81,205,753,626,755,246,542,964,240,450,953,839,900,820,994,203,732,597,56,621,585,215,488,586,907,365,289,840,21,547,823,42,932,461,270,56,582,36,429,924,715,693,607,270,970,948,125,664,82,166,881,316,740,534,396,427,499,211,932,478,80,923,658,268,871,366,249,995,679,877,320,485,626,942,807,288,977,978,151,807,962,410,461,981,840,33,423,492,428,261,249,28,402,316,925,371,586,181,332,513,474,684,175,676,579,697,735,122,759,25,785,485,556,98,203,817,24,865,60,626,247,759,800,438,561,396,958,916,393,916,20,160,406,757,316,279,382,96,419,898,840,304,883,599,67,949,991,176,925,449,892,543,468,278,6,392,324,880,154,388,883,177,255,240,435,903,121,100,205,7,203,289,525,731,175,196,173,152,232,870,234,643,586,503,869,673,10,974,329,509,227,457,468,323,885,571,892,53,485,983,804,463,285,738,846,372,218,549,120,386,924,507,580,58,362,885,902,656,740,921,116,398,956,133,808,759,375,891,285,628,44,667,30,722,722,411,136,226,884,523,943,609,472,246,969,525,698,381,245,312,501,129,202,16,475,514,386,403,927,512,761,885,371,251,796,675,73,742,114,196,616,492,741,882,941,860,13,631,95,386,260,3,7,508,195,886,815,657,700,425,849,629,264,948,780,431,695,191,142,960,865,945,925,852,500,138,163,652,962,336,237,897,75,44,374,847,650,435,404,251,162,257,150,500,639,55,334,723,542,585,155,81,95,729,290,767,802,371,673,523,396,101,202,445,239,347,850,972,328,789,856,737,827,657,104,334,580,446,295,541,463,134,580,126,769,912,45,463,798,487,625,70,264,191,343,962,759,102,881,472,57,480,639,839,559,841,235,825,18,884,925,973,630,507,36,613,541,848,537,356,511,562,405,579,876,148,534,944,220,785,663,59,442,896,791,782,682,457,995,38,84,781,82,81,665,820,805,343,901,960,141,217,378,758,446,303,629,184,929,113,590,302,949,379,913,438,727,648,72,446,762,306,704,824,739,629,177,62,338,987,738,684,508,777,548,46,909,379,587,42,232,363,816,684,31,86,872,212,629,917,188,677,831,641,442,528,378,907,475,726,231,523,181,524,574,192,144,486,715,672,750,185,570,45,716,953,669,563,69,359,963,409,42,574,838,640,23,633,700,140,691,387,246,768,237,917,576,930,78,852,227,805,978,908,712,418,569,950,22,390,300,107,114,504,787,216,344,205,708,614,382,243,210,237,207,168,114,310,449,910,647,915,346,340,130,382,32,968,449,723,98,808,414,740,566,861,483,719,71,682,80,387,279,60,291,963,677,485,41,464,600,76,740,719", "166,624,714,280,667,815,544,760,892,770,4,320,413,914,471,520,666,146,939,796,385,554,141,490,906,303,327,556,349,34,536,117,561,163,150,733,400,441,34,338,21,173,32,465,225,498,537,592,331,391,243,800,850,818,399,775,687,60,940,683,347,277,234,801,693,228,416,637,469,221,278,241,139,822,428,848,651,442,892,120,448,372,48,174,58,410,94,787,505,654,92,123,471,313,19,274,583,920,443,364,695,739,894,62,232,715,181,228,263,810,692,644,579,156,267,918,278,16,500,517,22,387,280,955,820,633,3,664,452,830,31,398,224,570,793,338,444,53,372,700,624,387,766,673,183,365,319,586,874,241,349,145,506,554,804,283,281,921,857,237,970,827,140,684,259,664,972,832,67,620,200,205,518,756,625,95,946,280,666,523,663,334,62,704,934,98,370,516,174,213,201,681,953,891,38,540,600,545,603,178,13,77,37,401,996,282,297,280,135,775,740,190,729,341,76,434,591,437,550,477,364,764,992,188,390,329,846,728,102,42,238,849,839,662,771,379,664,155,730,38,931,684,657,328,463,303,719,544,212,726,870,564,356,224,212,257,729,414,367,779,383,4,182,512,666,86,144,119,167,363,189,730,249,830,733,248,599,925,863,298,993,85,832,818,329,823,737,877,835,267,565,400,606,831,632,289,172,0,687,121,424,12,961,830,90,915,508,479,351,502,463,969,774,426,927,647,170,50,342,809,926,26,836,179,837,375,669,20,442,764,635,110,929,853,863,240,186,417,798,980,839,917,635,257,229,298,152,26,856,211,462,875,712,676,558,960,637,462,393,159,433,61,109,889,3,90,367,148,803,660,321,503,866,325,311,129,194,392,992,691,514,36,386,225,140,672,188,641,227,464,484,503,131,52,884,976,746,740,224,833,8,723,814,897,177,597,361,299,167,936,214,912,410,123,338,86,589,596,201,146,852,284,866,276,125,207,609,465,473,903,709,379,822,110,484,618,659,675,316,355,484,249,684,328,379,152,867,421,422,174,372,380,385,887,835,499,23,475,471,771,310,873,842,281,135,563,672,660,209,906,950,3,826,689,988,464,638,824,981,379,623,28,435,360,136,918,783,860,606,845,943,574,511,963,383,27,772,124,151,23,300,271,74,559,927,264,566,539,655,276,299,711,552,786,806,414,284,787,423,120,884,527,583,207,783,89,441,425,190,596,56,646,177,284,711,110,98,409,816,651,52,712,146,369,58,981,221,412,641,91,839,823,129,388,483,130,303,976,959,20,417,904,18,98,779,589,226,599,234,250,114,863,132,933,324,358,998,261,142,724,755,373,680,844,974,581,419,345,588,735,997,894,866,856,749,278,809,451,736,862,570,865,425,913,668,523,320,195,642,776,979,20,371,542,677,274,203,881,834,33,874,536,857,818,728,359,878,630,480,428,599,404,809,720,309,144,103,725,704,91,401,239,748,964,778,292,217,742,757,919,911,924,166,43,990,184,814,756,353,672,132,686,713,369,118,425,964,581,657,57,535,100,892,400,915,755,503,25,465,627,194,27,122,312,853,868,786,836,196,32,635,415,819,819,694,993,984,955,992,772,613,971,504,370,155,194,900,59,919,10,997,856,389,795,377,95,721,427,195,400,990,301,41,272,166,331,179,222,165,922,917,703,883,224,129,397,839,840,271,817,216,872,412,348,505,13,803,277,99,255,82,969,901,792,513,812,726,845,456,520,657,21,625,807,799,902,20,812,48,720,564,354,444,176,780,534,280,316,759,424,661,934,73,204,583,768,256,832,332,56,871,257,167,241,641,445,747,810,593,185,766,193,677,750,128,834,680,906,766,655,808,228,815,186,834,333,136,187,895,922,522,170,862,406,963,979,32,516,315,386,456,897,166,655,610,143,900,549,97,727,239,272,619,609,516,845,98,206,71,117,108,749,837,612,902,105,203,503,485,768,80,896,331,52,963,165,170,724,560,16,456,386,720,55,212,870,577,197,127,61,481,362,515,90,953,803,749,558,189,813,770,810,359,141,244,110,862,204,6,39,106,894,819,746,201,180,788,510,509,202,922,893,533,811,638,93,866,855,19,678,707,663,746,366,390,619,71,267,254,93,880,894,616,359,816,583,126,900,744,52,18,347,277,749,473,119,525,16,516,708,759,629,846,402,906,287,369,948,164,722,329,574,486,74,87,168,752,331,910,134,917,570,218,36,877,356,106,97,451,317,295,423,197,481,269,437,989,346,635,14,896,10,128,639,495,277,614,841,618,880", "880,850,848,743,725,978,597,305,134,505,98,414,911,858,557,502,503,664,850,628,671,279,152,650,200,665,900,581,801,12,217,396,573,146,519,606,535,83,150,14,248,105,388,462,519,963,161,521,417,937,365,52,484,539,915,403,460,728,135,771,280,517,737,638,523,619,340,415,775,258,665,913,979,10,299,51,167,459,626,601,912,263,329,387,351,229,236,78,171,591,631,183,474,165,832,864,686,495,149,470,663,578,315,193,115,354,157,953,255,120,432,408,389,673,107,25,268,647,18,104,108,21,582,351,61,384,106,334,656,389,290,325,630,593,523,7,264,846,23,242,37,788,604,970,43,457,227,301,343,110,682,283,385,482,861,241,261,482,877,418,343,761,145,557,789,323,697,975,978,97,762,281,212,38,395,984,51,130,708,267,186,201,214,820,631,664,276,560,672,880,281,359,982,623,66,881,716,307,63,669,653,434,506,9,265,93,660,445,266,184,456,450,378,620,166,580,172,857,512,231,224,243,541,722,147,619,121,306,519,761,464,705,454,576,145,508,442,291,702,301,18,11,144,193,590,600,819,539,485,405,575,448,788,566,880,918,749,761,504,37,470,630,687,663,964,937,262,650,149,767,653,451,881,542,988,732,480,101,991,346,379,565,803,99,101,944,928,556,926,205,750,473,810,932,856,551,932,687,0,838,275,521,323,968,802,624,465,12,665,698,838,123,36,158,188,404,904,944,410,885,859,622,511,857,73,283,358,752,938,113,611,342,377,724,806,539,222,268,908,25,983,241,877,944,320,871,587,214,44,583,67,700,856,115,268,323,807,807,703,210,5,76,417,848,466,242,948,631,591,821,13,286,406,96,525,426,927,694,458,528,6,739,306,618,127,185,365,502,361,697,731,514,432,388,443,102,135,456,822,473,63,4,289,854,585,760,660,494,698,22,465,419,374,410,312,572,17,644,553,863,280,890,882,924,976,299,813,537,857,704,26,754,831,40,820,153,3,639,69,721,755,277,679,373,467,977,998,798,36,342,796,989,365,401,142,796,634,928,20,91,529,526,639,760,738,664,763,75,830,391,635,339,98,324,829,811,376,461,90,199,198,940,651,64,762,986,558,828,596,735,812,619,704,2,59,323,626,558,867,247,832,736,591,856,759,462,288,891,324,588,254,984,513,174,203,210,65,641,335,664,216,406,645,312,991,246,24,251,101,290,694,471,600,660,791,694,648,416,199,31,220,933,475,239,362,498,452,475,707,730,250,333,922,435,653,148,987,560,458,800,120,914,482,106,738,138,97,334,443,115,234,8,704,122,631,686,581,30,292,709,366,727,771,175,155,527,255,178,672,661,302,431,75,914,446,263,917,327,757,95,177,691,904,485,704,823,321,824,243,114,584,784,756,915,520,133,105,738,998,764,757,112,886,680,165,65,910,183,519,299,309,667,462,552,850,666,331,192,105,379,844,935,850,791,534,33,364,574,415,374,405,332,45,978,434,287,704,856,27,822,952,309,994,500,106,220,746,590,955,858,297,934,81,790,548,57,790,56,7,266,207,601,307,461,171,865,690,521,86,773,290,617,2,183,993,152,921,66,750,869,869,945,82,67,921,45,845,151,97,829,695,824,62,130,557,395,592,495,746,991,578,413,365,129,79,496,257,77,501,548,754,747,782,321,483,346,986,252,687,551,632,114,755,599,230,797,223,813,386,14,357,733,189,699,974,546,142,771,747,160,421,697,767,813,667,538,200,370,690,670,568,181,819,916,915,938,188,324,461,427,813,970,371,854,660,944,607,315,560,223,789,720,280,39,669,807,481,446,290,745,406,308,565,222,973,98,232,521,760,425,269,814,494,263,448,703,103,921,935,85,615,355,256,310,411,436,533,379,935,108,612,487,749,162,899,26,292,199,325,232,278,595,268,111,329,864,255,705,248,225,419,154,809,850,751,282,990,473,643,483,116,750,498,918,570,554,63,930,247,465,632,697,819,345,411,663,57,271,60,546,760,982,244,918,802,625,851,190,8,490,739,117,470,45,960,97,575,166,456,570,785,943,22,821,408,960,662,767,384,613,2,359,579,844,114,272,670,397,499,468,969,529,432,154,549,784,153,546,537,776,100,852,157,737,565,91,934,843,781,464,360,30,537,612,169,733,368,109,232,405,35,60,461,105,359,955,511,551,634,441,39,202,670,428,363,824,153,904,344,278,49,846,561,411,188,868,511,58,760,271,874,631,816,161,875,297,740,428,917,179,435,305,480,427,660,168,147,347,198,941", "800,69,217,824,392,287,886,58,194,709,868,974,314,564,835,992,778,249,923,94,899,596,935,814,850,58,83,204,770,296,474,171,989,714,627,332,668,229,438,919,676,757,63,91,921,44,655,556,3,87,219,531,388,971,272,681,351,664,698,313,316,160,866,652,877,684,802,805,326,47,793,301,590,776,82,404,990,807,555,119,922,632,679,658,518,416,79,442,663,294,366,976,514,152,654,526,567,632,129,8,571,439,815,436,681,388,917,847,24,254,211,450,140,241,558,132,641,214,972,557,424,613,749,874,21,851,35,611,267,173,275,105,2,982,928,882,212,968,371,98,486,505,323,203,211,698,18,221,596,148,72,282,693,494,925,781,862,602,145,382,852,715,263,352,511,6,905,388,397,732,143,368,977,944,986,804,469,841,200,32,162,507,462,887,940,639,598,752,265,207,451,775,355,625,853,823,203,942,109,376,510,290,660,309,271,475,500,598,249,903,656,828,537,246,10,177,907,504,468,402,814,563,204,216,469,965,357,230,796,180,248,417,142,690,888,689,784,714,52,247,93,12,201,633,30,759,323,436,627,830,459,988,17,296,905,749,520,842,930,774,417,555,908,85,49,513,632,458,833,873,346,812,589,6,220,886,958,572,496,757,342,141,405,839,222,855,26,507,864,311,553,925,276,93,888,391,869,121,838,0,109,141,119,717,566,881,564,920,378,444,231,278,924,950,197,908,135,101,482,98,262,961,696,939,962,118,740,257,958,63,203,691,286,579,724,541,133,301,745,275,230,503,975,228,298,180,81,685,560,509,16,87,773,593,345,497,662,865,223,29,650,770,336,335,373,701,677,286,677,417,474,264,361,62,925,394,214,607,768,307,136,246,392,937,847,79,858,726,529,930,102,233,35,202,396,444,858,530,241,384,827,803,314,751,470,352,83,38,917,12,805,201,991,843,328,739,626,886,671,557,796,904,547,783,322,672,74,489,965,584,482,528,114,565,147,176,863,875,168,699,737,538,958,41,902,286,344,928,254,615,442,576,319,478,177,529,692,948,587,926,250,18,734,385,569,921,953,468,727,949,395,5,613,758,55,793,271,174,251,997,17,337,78,672,124,30,614,574,440,644,509,814,61,112,147,280,804,519,107,944,663,499,953,453,63,401,272,753,893,390,318,229,952,455,189,887,536,623,614,133,826,410,69,864,592,636,149,466,111,967,545,943,431,374,722,159,851,986,368,831,896,97,279,651,300,871,780,557,992,665,27,755,975,307,607,789,145,15,293,214,915,212,780,679,201,427,519,461,892,623,727,523,668,812,230,738,137,207,582,993,241,999,128,245,80,946,643,632,739,133,240,525,312,820,284,642,914,79,218,638,493,556,542,100,41,471,739,530,257,151,131,664,237,154,172,447,859,912,869,481,771,39,109,239,159,30,363,591,373,741,146,634,17,577,31,230,624,143,65,21,224,574,933,901,940,952,194,241,730,983,978,693,759,955,715,788,312,630,976,124,163,579,850,756,37,45,440,939,716,742,150,31,657,879,840,306,920,920,549,722,629,537,621,677,749,451,606,629,213,268,960,769,805,211,222,904,940,553,823,921,742,73,365,197,766,198,582,813,594,662,696,132,182,781,195,586,650,86,620,963,856,323,912,150,829,265,851,471,912,418,340,553,251,307,967,183,332,6,485,484,163,609,635,275,863,280,827,789,623,565,727,462,881,284,412,366,310,440,361,991,565,586,415,435,801,242,629,805,794,614,855,499,518,941,466,238,653,262,66,491,110,670,443,431,29,851,386,529,162,841,74,228,101,127,52,242,945,586,184,937,610,329,326,511,355,201,398,455,153,694,379,76,261,701,884,46,135,850,343,265,341,983,495,28,223,446,52,754,987,589,242,465,354,355,413,207,491,365,670,729,438,275,233,920,901,272,829,3,451,13,777,46,386,685,277,20,74,796,933,455,873,588,330,418,556,807,937,400,957,688,436,590,768,877,875,596,349,796,873,856,824,996,752,525,734,331,153,33,107,851,159,587,957,146,625,202,116,229,377,145,519,846,196,490,950,374,315,682,327,766,870,554,870,418,787,783,301,847,611,948,365,97,641,590,932,417,790,485,756,681,290,153,454,109,890,678,483,769,493,767,509,659,853,590,236,101,250,503,838,93,912,614,997,783,962,603,368,391,503,131,409,99,378,18,298,444,444,707,280,363,11,47,890,867,27,514,800,49,755,879,96,205,403,249,62,337,193,144,458,763,755,467,152,717,45,518,817,17,845,521", "860,155,648,396,37,31,282,657,988,114,871,388,543,738,712,290,486,610,956,2,754,664,716,270,739,885,614,742,712,139,603,176,23,786,800,140,949,352,479,208,642,802,458,435,608,929,223,942,266,155,487,879,49,524,117,128,28,489,759,861,908,480,61,955,640,729,742,90,194,252,102,505,895,651,36,21,568,900,982,73,287,212,610,560,698,559,242,667,319,232,908,658,139,873,168,773,269,66,114,93,266,947,919,827,339,407,998,363,93,783,955,697,350,162,103,904,234,281,424,693,221,926,519,344,498,743,88,82,572,27,260,187,847,889,505,467,617,969,166,292,26,489,337,795,38,858,722,918,918,821,441,563,583,727,967,225,597,930,400,925,500,770,858,521,637,424,627,926,642,419,859,536,632,722,930,952,467,3,457,957,981,533,712,366,408,543,111,904,329,881,180,715,263,498,366,929,793,95,694,748,641,643,212,608,624,837,290,938,97,394,56,683,495,495,774,417,422,57,332,334,968,393,84,951,436,208,419,863,741,241,734,756,41,860,687,401,422,314,612,325,796,479,593,251,129,365,563,347,596,222,949,564,76,496,729,33,874,985,70,556,964,893,138,485,394,244,199,423,474,180,509,328,50,575,815,420,354,148,797,965,450,944,215,482,391,757,604,982,521,610,375,650,780,688,882,761,948,424,275,109,0,34,607,626,447,824,752,509,244,895,107,172,516,83,480,289,5,691,368,628,315,274,397,878,853,300,370,635,341,45,800,87,835,825,328,61,381,139,955,652,861,565,320,909,952,221,64,832,883,429,512,891,194,182,357,325,619,344,994,841,711,985,279,910,81,858,588,634,834,998,234,705,370,391,788,288,526,457,871,978,199,94,921,517,570,894,882,887,427,748,735,287,107,910,959,819,518,278,420,911,99,498,877,704,140,96,861,740,41,960,716,942,954,784,591,93,264,339,375,809,468,649,821,289,254,21,888,558,12,669,477,614,545,158,5,919,847,475,481,896,559,326,38,303,721,22,707,184,809,233,76,181,187,305,34,519,394,583,197,90,677,1000,459,907,990,780,806,546,280,853,973,642,222,336,405,373,302,205,67,538,398,699,138,635,590,705,615,770,850,784,31,354,592,401,513,195,879,590,364,327,320,926,159,269,832,719,564,839,812,116,462,459,582,372,80,297,893,293,63,480,373,935,438,864,849,246,15,7,580,41,250,884,99,56,124,776,745,269,494,196,725,962,41,95,262,725,364,779,951,209,416,817,609,575,736,762,893,367,933,447,531,98,113,877,439,266,625,150,230,534,955,392,959,663,269,511,993,756,181,698,286,749,759,438,641,779,795,251,136,230,227,544,438,263,443,711,590,281,801,258,872,381,982,892,128,929,686,733,505,205,53,646,381,416,809,415,814,997,103,297,816,231,594,597,456,232,512,612,133,980,525,135,857,38,754,348,168,904,62,748,154,134,299,505,809,712,762,115,497,397,26,478,885,998,876,891,685,982,874,104,524,601,338,865,139,289,64,325,121,337,761,194,94,756,785,910,386,585,614,77,704,746,12,181,416,687,112,225,841,980,26,618,828,391,942,929,768,214,414,28,649,871,738,242,570,586,880,98,405,406,651,581,393,55,481,295,679,692,736,440,681,960,21,653,266,439,795,946,850,691,522,819,362,928,12,526,913,954,80,446,707,221,512,601,145,111,343,854,946,466,722,976,461,488,961,649,539,822,543,947,223,757,585,515,249,137,646,615,628,59,206,816,736,23,783,430,981,293,402,890,845,675,972,452,136,871,377,133,565,161,484,334,305,976,906,866,646,295,53,54,683,818,957,569,988,681,483,177,160,315,20,725,565,285,487,816,464,161,387,670,416,225,540,539,156,594,518,216,454,306,41,534,874,989,726,521,748,400,318,299,729,136,414,180,175,27,687,55,34,854,107,539,142,719,274,910,907,461,316,963,181,658,530,541,168,543,586,44,37,880,764,669,220,918,574,669,984,486,844,901,959,369,892,844,430,524,276,211,188,649,401,919,427,296,22,127,513,406,811,936,703,196,684,965,425,885,771,451,532,580,795,470,140,426,108,716,617,844,423,37,547,880,811,369,905,802,461,944,773,9,541,435,434,151,492,65,949,313,198,496,615,793,493,202,907,126,84,168,9,837,884,442,152,156,789,99,508,109,505,923,970,234,9,168,731,231,63,799,930,734,601,405,796,483,401,802,810,579,873,761,663,675,862,39,949,38,871,379,486,993,649,862,335,573,907,299,846,831,481,595", "869,897,244,664,641,875,890,230,370,212,926,625,205,819,386,659,59,727,814,968,251,741,634,745,759,796,861,479,611,189,597,320,506,541,612,457,24,645,711,52,40,42,300,135,531,638,437,75,592,677,594,869,141,708,762,518,675,501,82,67,826,118,193,129,63,697,278,852,995,812,582,615,935,126,720,277,465,944,145,771,442,640,551,330,511,732,954,373,306,204,703,59,737,684,355,894,994,255,739,318,867,828,68,220,795,377,983,469,555,767,817,384,552,134,54,308,145,542,513,577,412,297,880,579,766,937,89,450,682,482,345,905,46,647,879,434,550,744,885,84,584,459,933,43,145,930,301,573,450,836,313,966,850,274,745,991,343,59,313,634,996,694,271,319,907,687,769,861,507,162,552,643,171,7,128,83,727,332,214,499,642,344,719,567,467,561,857,543,225,427,737,73,429,132,421,919,298,632,317,283,530,944,661,764,237,687,459,948,922,732,474,709,354,383,279,721,100,409,784,543,370,74,402,263,32,425,663,237,739,793,47,721,673,361,761,785,712,22,808,282,34,672,235,284,227,734,852,888,902,703,260,540,999,574,849,284,759,920,340,381,308,701,334,289,950,341,583,230,591,401,835,346,798,215,122,4,760,477,664,625,476,725,757,560,342,273,120,855,677,593,776,793,201,627,684,550,661,12,521,141,34,0,783,970,63,986,729,841,909,289,701,254,764,458,471,340,678,448,100,210,107,578,648,442,402,757,702,557,37,853,321,480,997,377,184,728,955,846,940,841,638,569,696,462,274,710,877,25,484,418,903,994,413,950,12,285,839,656,228,844,339,302,862,675,471,942,557,707,462,332,297,590,914,131,385,518,998,526,462,783,160,213,186,33,440,301,581,422,506,448,989,841,104,422,416,601,934,446,781,512,253,247,819,386,322,497,113,713,852,897,173,423,482,432,557,725,139,900,628,642,119,307,706,739,806,927,565,579,449,845,945,611,8,88,827,484,113,907,665,471,619,970,751,959,198,647,224,939,506,224,810,348,436,410,664,612,276,216,871,535,552,583,281,650,111,82,816,268,778,143,884,823,336,103,241,282,858,113,310,267,408,901,800,231,427,177,617,5,79,549,852,385,964,727,358,148,519,339,946,312,272,713,416,298,951,258,58,60,291,181,918,161,871,64,760,647,501,292,37,147,719,46,453,714,798,80,308,761,724,291,800,167,516,400,265,206,278,716,421,438,16,859,496,98,469,658,940,226,368,58,183,777,53,675,613,996,184,846,217,521,951,519,583,876,365,368,746,329,129,618,871,696,92,874,32,660,512,813,949,117,532,65,501,75,42,379,899,726,825,564,665,993,164,393,998,933,165,562,271,412,205,393,927,336,220,122,45,338,270,425,250,389,209,310,270,474,428,359,765,661,832,258,2,177,156,753,422,492,556,600,273,669,907,180,791,89,21,658,14,778,514,239,397,12,634,851,814,274,270,926,227,93,358,318,969,220,789,243,194,935,675,782,248,849,327,363,995,734,187,444,581,243,948,430,88,845,136,701,664,389,42,837,867,160,701,841,329,396,363,127,994,234,226,789,952,411,504,905,757,461,252,620,424,716,263,589,460,298,800,603,896,925,585,520,56,959,212,68,705,950,230,857,878,7,849,50,765,422,448,261,37,970,497,247,426,367,18,393,655,37,378,192,754,104,493,522,598,349,954,868,764,345,490,100,262,508,463,438,853,650,915,436,174,820,919,454,168,670,96,801,500,30,107,553,306,295,441,464,371,536,790,514,216,302,379,969,981,904,468,78,217,679,775,632,52,619,452,517,242,416,726,62,132,909,523,683,742,358,504,793,75,924,816,173,805,642,885,242,243,275,911,13,566,552,677,119,266,109,956,56,312,749,231,928,303,967,390,993,225,325,955,473,417,543,790,725,574,339,630,765,369,972,656,684,236,213,221,729,860,61,384,964,967,24,366,435,772,724,237,802,918,195,958,572,644,568,945,414,579,170,451,181,61,100,299,774,131,892,521,995,854,914,221,882,330,30,190,337,95,330,8,888,794,202,193,820,214,92,11,331,420,42,925,203,587,904,509,429,123,254,365,487,509,382,132,584,483,825,253,822,594,635,537,448,349,436,766,130,567,745,729,427,124,54,392,598,832,272,311,667,313,689,990,103,377,808,932,967,677,875,657,802,248,979,842,452,759,344,165,569,235,351,471,468,456,3,130,896,863,311,735,123,326,683,845,769,911,845,206,600,494,247,519,690,288,727,215,62,280,754", "805,498,67,467,545,428,215,43,770,20,70,396,128,886,144,91,46,197,562,870,59,502,270,453,294,209,534,448,274,92,371,52,676,674,998,484,499,83,698,311,275,773,228,565,25,867,928,137,920,719,767,797,81,201,979,522,690,532,96,1,125,945,847,143,383,97,606,569,866,119,520,661,78,511,862,628,700,84,420,549,676,306,519,748,912,910,472,333,764,379,703,573,215,27,154,15,117,19,246,64,81,887,485,486,833,701,617,503,488,999,758,445,298,316,9,211,518,712,84,387,591,412,382,121,773,263,277,583,262,394,906,432,116,278,566,815,691,921,750,848,273,212,270,144,306,905,757,809,749,176,236,765,60,412,435,804,194,791,866,483,754,988,190,188,516,720,622,702,789,95,456,416,864,98,328,415,370,768,263,961,289,690,464,226,986,725,218,479,987,751,708,685,588,547,467,579,416,91,437,185,610,769,970,744,856,488,344,353,121,510,797,219,75,893,722,26,569,602,577,241,124,905,273,704,349,894,277,984,743,836,72,836,76,406,72,545,330,999,32,170,522,243,564,831,819,16,68,189,997,904,564,811,129,231,273,416,696,141,520,72,310,124,127,74,105,498,155,367,291,456,332,407,246,774,163,274,517,920,464,448,655,973,457,170,353,394,128,342,565,259,48,408,808,508,947,689,650,961,323,119,607,783,0,770,997,410,187,398,749,258,461,552,402,134,413,833,52,467,884,264,528,392,863,120,6,379,783,987,494,915,679,862,616,487,708,23,353,804,71,234,311,154,280,654,314,679,626,655,862,495,154,433,325,429,805,239,829,344,498,666,669,830,515,333,579,547,918,932,584,647,548,866,965,319,788,37,681,452,724,474,69,369,635,892,419,754,361,965,261,971,542,873,48,742,929,671,128,313,804,922,691,492,504,269,209,992,531,494,306,4,873,54,114,117,766,99,663,350,433,773,580,859,514,287,976,918,261,842,786,851,20,306,119,366,809,789,259,172,790,602,797,553,857,56,854,504,694,556,907,596,548,102,450,992,383,995,443,308,356,972,230,696,47,206,223,649,754,513,492,540,296,436,121,773,548,319,984,549,485,63,164,366,947,425,694,493,741,871,615,35,827,131,618,223,672,109,902,646,433,467,627,733,928,511,367,310,674,205,790,906,370,347,334,439,67,718,50,688,481,373,343,675,705,453,86,939,375,258,432,385,924,484,23,393,185,343,563,433,56,735,797,981,630,85,147,928,247,857,870,2,733,107,791,68,879,296,887,380,88,822,19,798,706,647,967,348,93,591,972,160,761,843,934,585,810,472,248,615,269,602,905,249,744,342,264,584,949,753,308,584,395,557,100,885,791,696,41,768,295,924,574,317,281,717,336,991,602,102,271,797,551,469,16,315,125,93,481,535,999,911,79,669,155,216,313,478,416,634,301,370,663,223,495,408,546,597,84,661,430,338,616,630,677,586,50,590,555,267,63,112,786,505,73,505,352,118,775,531,491,912,751,336,567,402,738,857,750,178,730,21,490,781,494,441,204,349,681,333,805,296,184,343,75,293,236,276,17,340,517,681,287,865,969,467,836,718,920,898,427,542,679,853,601,709,855,319,665,882,787,301,666,309,908,443,904,576,853,38,52,144,525,516,332,383,908,954,587,312,305,580,740,229,421,198,833,628,593,378,288,333,956,947,436,89,848,451,790,685,477,47,200,978,809,2,296,609,508,542,608,330,472,712,357,912,218,828,26,619,428,544,359,977,863,773,519,72,323,656,53,990,511,307,811,685,248,605,877,131,941,385,39,733,985,103,515,460,520,760,672,325,887,96,280,819,904,940,393,229,487,525,629,891,622,155,38,270,410,706,459,830,361,449,28,238,499,609,452,281,715,797,573,739,42,249,405,489,136,45,955,312,335,506,682,990,328,660,995,22,472,51,535,242,833,281,558,927,499,940,890,974,143,634,281,97,214,117,180,809,831,762,556,584,750,505,161,63,354,111,57,767,725,499,786,556,234,106,735,872,906,246,374,546,64,664,725,774,829,668,786,962,937,947,721,78,431,951,249,36,572,734,323,841,608,683,355,559,854,472,54,952,766,262,202,62,427,858,853,395,148,542,713,401,202,399,3,215,241,777,236,275,284,116,273,540,314,631,669,579,94,903,990,412,489,658,881,117,302,69,648,546,202,412,683,296,333,879,94,506,340,164,815,535,927,943,27,210,529,438,878,741,462,484,279,189,673,865,170,985,183,210,152,169,181,464,607,177,381,921,671,565", "873,813,94,751,137,246,973,759,145,463,757,256,227,318,198,113,714,610,254,940,63,924,568,584,16,188,166,944,353,336,777,40,237,607,124,998,274,919,22,653,392,968,720,232,482,301,978,93,340,276,398,687,513,465,304,844,755,560,884,81,374,363,916,542,354,324,241,440,840,904,676,57,972,396,540,527,463,292,141,180,454,305,506,951,696,685,354,480,9,639,200,509,125,984,952,615,932,708,224,443,388,802,6,548,604,271,983,782,904,202,898,572,687,743,642,398,819,194,687,691,59,116,670,26,386,356,97,312,48,684,368,713,718,147,28,901,880,618,144,149,246,149,73,144,999,732,362,316,458,249,478,409,175,648,988,3,289,652,142,172,531,999,331,417,818,600,820,818,139,352,53,366,603,468,543,960,108,232,771,20,445,405,376,690,565,751,442,61,540,141,935,679,69,196,613,684,280,965,614,460,87,152,902,962,822,508,858,174,647,11,556,292,237,26,602,365,645,416,387,775,151,509,973,258,361,50,80,516,653,628,805,149,525,282,521,885,685,527,684,675,29,877,509,183,695,672,579,517,624,507,667,280,895,440,344,164,578,542,974,532,351,970,361,987,29,277,806,62,174,32,167,309,420,853,881,808,331,210,776,874,974,216,29,329,453,777,326,921,456,837,960,122,785,623,361,530,639,830,968,717,626,970,770,0,472,499,391,991,89,178,705,133,736,771,588,730,269,969,543,90,212,495,738,101,853,13,251,466,233,112,171,318,86,194,573,126,206,192,424,735,85,925,374,889,510,737,593,827,880,145,764,357,971,700,155,816,110,73,948,836,925,735,811,739,309,548,404,237,293,549,842,759,326,929,764,504,659,248,59,874,751,714,182,395,544,386,979,808,466,729,160,118,812,624,296,882,980,983,875,641,879,881,652,835,551,437,561,487,37,502,292,915,696,482,996,411,342,450,234,24,952,913,171,231,904,851,455,974,947,457,703,41,131,347,805,401,567,856,54,755,662,447,105,573,195,103,791,251,670,553,128,836,314,236,641,111,716,160,882,460,941,861,910,888,236,706,675,937,924,18,816,550,572,592,355,16,765,429,764,845,465,777,675,327,914,736,573,347,540,31,20,588,84,20,284,219,326,535,637,405,398,954,560,734,658,943,994,415,197,498,498,884,958,952,718,580,56,812,966,583,839,401,337,468,482,86,598,625,856,259,569,746,576,320,140,729,731,726,169,390,633,889,555,801,673,48,316,54,169,261,688,119,617,214,579,301,797,438,321,725,724,806,538,314,225,157,214,420,620,567,869,209,965,209,146,620,839,260,99,367,371,697,291,197,219,657,971,386,551,737,129,691,273,825,51,792,460,611,98,955,514,617,122,325,104,259,436,540,716,723,963,503,295,924,254,144,208,558,535,426,302,599,96,747,109,125,812,495,180,570,27,563,410,248,885,507,450,285,242,97,473,649,23,385,808,274,926,436,108,853,357,391,81,998,85,998,260,688,496,312,495,945,432,552,729,404,227,208,76,237,318,356,89,375,334,882,326,243,786,950,494,884,343,384,431,200,259,683,666,857,662,941,667,980,24,805,904,564,507,850,54,982,36,313,286,247,31,269,795,88,158,912,592,355,486,715,569,550,479,944,448,427,592,796,365,982,882,555,173,482,791,536,196,799,853,19,119,540,289,315,745,460,963,268,365,9,42,731,644,270,551,152,179,830,956,29,758,575,57,83,237,719,188,931,223,708,86,583,582,541,484,288,377,516,938,263,567,943,598,49,638,913,41,352,431,279,963,450,267,372,416,323,777,280,625,746,185,782,966,910,582,616,838,363,18,713,167,978,714,47,243,521,488,441,577,266,209,458,719,854,522,165,244,36,137,423,414,607,430,467,721,61,744,879,544,559,205,727,694,644,340,136,420,459,189,817,962,697,106,975,687,818,140,316,529,553,495,502,991,682,980,926,994,187,215,3,317,54,564,296,801,98,201,826,564,555,546,287,383,844,650,939,27,756,636,926,639,174,12,865,963,767,353,552,196,130,627,633,431,151,506,833,673,754,139,847,885,383,313,55,677,922,908,534,115,69,641,685,111,752,959,865,479,323,445,752,390,329,855,290,327,447,693,397,867,438,763,123,428,396,793,5,134,130,951,894,224,306,855,939,47,913,804,909,899,316,498,759,844,217,652,42,518,531,79,93,13,256,161,463,466,208,35,456,932,340,171,141,248,248,249,66,91,53,664,418,523,182,600,405,791,996,707,802,58,592,149,950,164,605", "296,295,26,156,495,888,211,770,941,105,489,863,287,218,266,885,636,501,902,270,676,115,477,911,357,54,528,514,560,531,399,854,246,478,505,182,325,474,383,622,110,619,566,769,557,268,494,416,124,513,157,759,998,312,63,48,328,321,447,293,308,249,813,327,71,696,428,114,369,484,707,5,350,58,462,965,376,725,539,74,316,279,593,130,85,463,248,944,84,427,925,963,507,367,130,33,205,890,305,235,801,80,981,534,641,214,755,646,846,982,344,489,782,662,356,856,100,149,107,686,857,516,618,413,514,228,505,497,839,363,983,488,779,473,850,335,573,429,433,53,79,664,251,748,859,130,544,928,390,397,698,768,512,481,286,349,351,29,904,327,35,802,901,444,112,992,49,97,533,792,168,692,66,716,106,683,55,290,750,239,227,943,758,81,726,832,605,153,751,458,883,887,964,773,704,699,196,604,177,286,372,448,87,600,868,584,643,582,548,530,28,920,833,929,426,155,739,465,235,840,997,760,850,911,277,2,209,820,791,262,594,431,246,880,209,940,120,128,214,215,93,100,507,554,409,982,791,174,649,798,513,426,162,79,643,443,264,351,712,576,778,208,592,393,139,417,927,38,40,529,654,271,734,515,838,469,239,786,32,75,965,570,293,359,82,522,569,405,680,679,363,832,598,984,982,148,5,90,802,566,447,63,997,472,0,102,701,399,901,415,722,597,740,115,783,644,820,907,246,244,837,509,976,656,813,826,166,886,960,961,186,114,914,474,809,930,811,824,165,909,152,368,626,614,240,765,666,232,698,998,802,207,916,203,284,393,213,96,592,751,634,159,884,656,644,493,962,519,402,728,220,500,437,602,775,488,96,175,860,482,730,804,959,114,753,888,798,618,2,503,262,778,370,526,707,577,766,83,593,401,503,349,706,721,245,596,3,647,158,800,733,802,917,361,260,30,126,223,13,112,811,873,556,35,310,823,229,368,849,767,228,696,784,633,781,220,503,399,15,32,40,429,90,969,31,998,746,150,5,884,803,918,398,139,658,303,850,427,311,114,801,759,108,963,143,238,502,415,610,15,361,549,782,214,666,872,518,718,197,658,400,353,486,764,118,439,859,448,652,697,106,388,693,36,357,912,821,336,805,767,474,134,891,504,57,385,212,629,925,186,600,277,9,792,563,399,932,548,442,569,114,708,204,526,15,98,919,136,294,578,180,22,94,892,920,895,191,444,122,373,70,181,143,3,439,683,254,40,226,525,856,109,350,195,463,84,835,816,606,299,889,235,260,651,477,113,157,569,930,922,681,793,776,795,93,340,310,853,200,149,263,402,564,779,321,9,690,433,966,222,988,635,294,993,871,696,289,644,574,677,523,672,857,148,109,797,995,71,622,905,927,386,41,982,549,543,205,6,519,965,337,376,968,397,565,621,321,355,163,370,965,929,204,173,131,56,609,116,933,669,97,482,706,797,233,781,594,642,858,417,18,636,120,735,75,94,401,37,808,892,227,732,492,450,477,589,589,718,385,84,509,937,939,894,645,216,936,364,398,582,729,623,85,811,374,944,789,139,144,919,147,262,360,290,96,450,209,967,748,695,792,905,118,319,388,42,359,678,823,505,918,712,572,856,603,783,724,485,228,486,886,452,539,654,710,311,342,215,679,200,121,35,490,672,94,486,36,998,103,818,19,268,525,468,443,253,754,83,114,67,665,764,504,699,940,275,677,379,349,73,859,475,568,968,948,32,676,425,155,735,271,264,970,945,288,586,440,180,603,923,535,876,739,100,265,663,92,846,96,461,255,653,402,434,407,491,715,917,241,849,662,379,530,71,592,860,965,497,244,962,228,337,909,132,798,914,277,239,691,348,335,117,168,262,477,115,101,646,242,90,766,733,440,338,769,94,549,492,426,823,895,841,891,491,608,817,874,214,856,73,198,917,926,388,401,39,215,882,276,585,699,851,448,325,781,304,637,112,17,599,216,540,428,533,358,48,207,249,161,396,289,433,345,892,644,830,303,432,590,347,808,280,509,204,859,860,251,524,70,545,626,434,519,632,824,642,256,706,671,293,410,711,774,810,665,884,261,832,494,802,166,326,107,545,361,208,592,472,630,449,979,754,782,309,619,218,308,987,271,416,262,327,301,702,91,104,423,105,583,853,242,368,345,485,240,543,586,392,140,982,234,711,425,879,322,790,450,142,652,142,125,859,694,167,610,591,671,133,494,379,677,272,627,201,903,735,736,816,382,523,495,118,523,23,194,940,471,151,958,371", "706,719,492,576,653,903,751,252,910,113,240,479,795,173,452,624,214,682,773,36,153,378,411,973,37,839,914,288,550,951,997,144,23,411,640,716,573,696,202,71,270,796,979,320,465,150,199,651,989,495,384,347,567,865,19,914,90,206,638,507,116,989,145,336,772,715,846,466,95,331,698,19,85,942,798,842,302,686,540,680,28,540,165,486,411,710,163,848,647,135,814,362,923,695,233,173,124,856,406,650,131,733,22,205,291,379,571,763,402,867,310,690,319,132,993,193,428,760,518,395,792,481,347,697,32,668,286,719,288,875,784,793,656,47,764,459,229,27,53,946,370,963,374,131,668,996,214,421,198,429,347,927,865,111,67,581,172,35,209,506,521,23,209,35,26,657,269,330,546,434,258,427,382,643,979,917,511,688,197,39,617,846,825,270,622,720,126,172,318,993,25,132,12,787,135,66,822,149,722,524,597,243,680,541,861,337,375,69,277,352,895,557,473,439,32,883,924,260,258,235,133,556,8,41,475,438,57,281,32,390,708,795,851,48,683,262,415,300,665,282,122,525,556,44,794,133,714,691,402,643,264,319,149,381,465,862,540,388,164,640,756,175,859,307,259,967,466,151,850,237,277,478,943,179,419,721,735,572,432,326,87,753,231,510,824,985,41,462,245,874,329,158,860,923,693,46,608,915,624,881,824,986,410,499,102,0,738,375,923,236,179,81,93,615,259,183,938,69,101,558,759,559,936,728,18,327,660,683,21,315,349,483,321,229,248,213,265,126,895,638,967,962,326,216,594,663,575,302,416,947,883,653,526,768,551,343,896,859,919,642,574,355,131,52,886,278,280,516,741,446,407,107,83,589,845,635,796,173,248,292,747,609,289,217,498,743,536,986,401,219,510,463,192,134,96,130,911,447,726,41,342,63,396,78,874,60,145,255,265,483,114,576,764,140,837,682,62,466,613,538,403,865,786,439,237,948,674,27,55,817,655,54,252,946,8,945,183,829,245,567,440,583,475,695,676,655,963,964,631,92,385,156,571,8,632,541,712,744,394,251,834,714,663,758,803,754,985,297,118,478,165,781,738,596,250,300,448,58,824,478,135,92,44,85,269,539,192,457,159,428,891,790,252,389,11,278,703,253,32,948,915,13,998,162,327,695,536,468,907,542,923,612,742,705,294,211,672,523,252,295,9,313,418,273,891,862,141,8,463,835,518,404,472,963,573,10,764,627,921,993,486,796,411,336,610,946,832,690,750,68,43,229,632,634,17,886,646,461,64,981,260,131,347,591,824,904,913,370,120,255,278,935,260,546,727,602,544,510,623,942,569,462,350,442,162,875,853,930,771,106,349,369,958,851,844,622,658,411,180,690,395,256,436,428,925,29,612,175,391,432,881,614,88,700,210,459,560,309,641,591,45,522,145,570,306,280,476,767,536,263,491,976,803,166,269,815,174,882,8,858,458,146,188,994,300,531,244,979,976,17,657,65,457,825,150,652,500,698,94,849,238,743,662,244,623,917,457,750,734,289,528,855,238,58,459,731,732,790,952,444,101,626,715,965,48,522,342,219,248,140,509,528,417,68,185,976,795,662,439,810,350,257,407,748,712,481,87,452,304,335,938,413,819,359,752,440,710,67,574,237,746,771,531,267,468,111,870,679,210,527,36,715,868,867,404,664,173,547,647,767,633,113,638,307,380,321,544,908,847,232,625,102,470,43,334,994,710,821,674,521,774,43,402,64,974,192,421,192,630,639,490,567,756,978,326,87,486,742,421,907,35,155,760,846,23,891,617,798,596,390,746,485,815,83,602,777,151,687,20,707,896,294,339,710,699,197,565,352,889,322,219,190,228,851,744,973,811,959,229,113,854,311,377,802,235,882,717,369,296,48,579,823,165,393,68,159,17,931,535,570,11,289,127,846,604,138,940,65,632,391,740,382,247,958,923,8,412,423,716,381,570,791,139,776,508,951,554,353,497,382,351,243,461,796,320,554,428,511,789,267,573,921,415,954,733,34,558,545,997,905,224,181,130,838,470,822,27,778,344,949,674,204,192,953,495,780,837,278,450,630,779,469,816,30,41,167,116,237,962,917,355,718,721,236,950,540,563,766,645,672,716,778,463,566,780,483,105,765,197,169,635,183,683,521,87,153,105,866,202,802,528,928,208,990,378,395,266,829,940,592,148,896,257,634,329,375,295,336,616,701,26,182,639,123,258,310,658,834,385,96,494,770,894,934,766,97,718,550,125,42,827,636,306,211,716,566,119,557,983,403", "901,696,982,183,317,710,527,321,526,674,180,711,386,317,915,310,122,327,280,594,761,745,114,510,544,363,528,385,98,485,70,792,62,889,974,479,112,668,523,392,266,485,770,913,97,723,340,277,707,732,344,113,269,230,618,204,994,523,773,515,899,539,697,196,772,386,110,878,189,169,995,305,561,993,390,509,50,299,727,367,680,235,141,434,174,871,212,640,760,23,81,292,787,233,742,755,400,967,194,545,32,754,394,517,18,580,340,493,490,937,864,719,306,696,566,986,96,976,358,722,885,947,933,723,728,900,480,602,920,835,629,611,547,54,656,292,677,489,671,820,758,361,67,246,933,904,421,832,255,30,969,863,59,630,670,35,110,697,65,884,139,372,646,572,899,435,432,628,76,96,677,679,762,262,621,729,556,679,115,942,634,18,46,894,633,87,40,180,94,46,735,331,399,165,668,869,513,86,356,314,742,744,690,547,243,319,139,58,381,737,591,597,685,524,131,898,725,448,462,846,669,965,136,347,649,508,927,480,343,16,447,489,602,747,606,943,599,866,961,280,503,794,630,150,389,176,996,930,903,51,700,548,986,125,394,994,239,657,386,647,85,561,721,540,156,489,175,797,402,817,748,252,141,344,158,291,803,75,141,116,511,922,504,602,242,584,356,595,775,828,242,38,703,494,585,540,391,508,465,564,752,729,187,391,701,738,0,119,368,631,553,26,999,552,551,986,381,40,308,70,374,648,508,770,11,800,43,28,741,690,97,294,76,298,683,27,540,737,200,154,671,305,943,511,678,176,552,40,246,339,673,879,822,339,487,161,41,117,648,841,606,135,105,191,747,424,374,728,535,672,718,178,250,308,219,778,832,696,123,260,473,317,595,469,837,645,474,683,445,755,123,817,983,421,332,99,279,708,486,698,441,114,607,748,412,653,283,269,198,104,320,668,726,204,187,811,619,964,267,248,335,138,665,707,888,399,506,272,489,900,562,69,469,892,793,218,943,799,414,106,976,66,903,204,809,6,799,948,14,322,939,740,724,206,23,658,529,866,955,173,120,989,168,379,718,513,343,970,998,631,214,61,198,838,366,851,971,13,931,572,324,758,605,146,936,270,205,15,276,211,241,542,171,895,520,430,949,465,246,391,695,170,222,207,938,913,729,389,431,559,703,618,883,641,341,365,947,773,474,841,997,894,114,875,413,863,202,641,52,31,105,714,38,217,344,356,623,12,270,778,141,937,372,53,106,533,634,272,832,326,628,676,569,665,801,61,424,409,683,186,94,211,605,23,490,666,726,858,119,978,828,973,124,474,680,63,338,887,218,480,247,391,643,538,402,598,577,699,280,65,247,264,107,373,523,183,766,849,394,395,150,517,823,548,264,96,781,435,334,656,977,890,65,334,408,790,502,228,329,950,20,789,154,496,310,471,688,303,177,358,120,882,568,432,796,519,672,329,522,173,281,656,870,236,854,70,108,859,449,917,499,51,622,855,299,476,790,975,506,894,903,585,73,247,6,261,688,345,672,845,278,364,794,958,531,495,354,233,412,879,267,589,95,214,144,784,302,909,916,987,948,670,778,370,30,589,989,246,614,242,101,156,769,144,288,415,670,295,21,918,551,42,235,337,192,858,262,749,471,789,297,606,479,519,275,770,11,886,727,130,332,402,714,690,780,919,699,387,256,214,811,591,186,245,890,979,41,940,501,868,602,84,762,532,533,69,816,13,842,344,245,734,651,12,732,949,220,502,348,230,513,588,628,262,416,729,353,477,400,684,911,128,703,862,984,861,469,70,250,112,400,504,595,226,988,441,157,545,95,307,551,876,951,490,684,83,503,528,752,513,727,315,362,882,119,330,20,256,596,596,714,516,426,142,496,867,750,761,590,539,194,371,808,70,840,67,483,790,325,516,603,652,293,930,469,759,597,857,496,808,889,251,828,304,345,613,806,723,128,651,643,119,846,474,712,685,580,597,592,988,76,780,330,343,194,101,86,275,942,217,638,255,286,484,482,91,392,52,390,698,485,800,103,369,532,618,239,115,547,851,34,415,105,844,368,146,850,138,754,527,166,305,573,185,442,460,323,38,726,747,702,367,394,909,315,112,266,352,287,138,46,756,949,203,413,310,59,751,706,665,662,171,50,39,151,250,708,750,968,384,907,698,464,1,423,566,4,65,690,151,775,474,161,917,664,743,235,626,194,241,275,567,112,151,469,689,504,990,439,803,66,634,589,555,122,659,327,279,232,359,639,838,395,682,636,527,230,476,73,459", "155,381,336,930,90,205,769,126,70,566,719,522,817,512,822,512,674,862,489,595,224,98,314,612,56,554,334,399,240,362,813,410,104,774,360,279,511,278,946,939,415,291,351,80,680,928,31,53,840,614,338,144,485,646,833,127,87,773,337,683,527,997,458,464,607,271,584,897,709,650,47,406,272,481,156,344,454,791,64,3,824,287,631,692,645,519,815,471,33,251,500,164,250,562,834,13,57,575,2,168,577,20,963,288,715,703,758,313,13,589,137,177,838,822,556,317,338,14,796,550,858,220,275,676,4,55,181,462,536,326,318,173,929,945,778,507,652,545,12,60,376,713,877,351,631,571,212,223,774,834,770,673,791,869,614,455,906,771,949,38,890,357,856,460,158,695,80,617,507,689,28,199,111,567,843,63,584,388,272,925,106,779,783,732,737,104,249,426,258,420,62,176,150,535,39,645,131,634,31,181,373,292,482,780,838,96,370,620,565,404,12,271,779,486,108,733,961,315,488,750,379,950,506,814,456,882,827,608,128,89,644,348,510,164,616,107,338,76,746,584,573,353,297,66,137,954,485,840,6,654,523,621,337,892,125,734,447,284,462,124,7,925,267,171,691,860,877,903,11,331,512,448,2,391,172,546,412,463,315,412,457,487,135,861,948,14,858,746,96,972,52,801,193,390,550,811,121,479,12,920,509,841,398,991,399,375,119,0,141,781,492,839,969,794,339,867,539,664,225,562,517,166,138,469,874,42,851,286,351,272,517,152,891,403,484,770,508,297,101,286,719,33,773,113,672,712,101,819,32,338,797,445,563,496,294,873,648,115,190,628,871,659,635,340,631,324,225,828,935,889,325,472,979,15,209,817,750,220,62,304,696,33,497,664,404,105,699,683,783,18,926,282,420,434,943,45,609,518,92,531,81,338,522,768,276,959,181,877,830,96,804,87,74,990,100,844,480,147,18,438,431,528,380,533,284,296,120,916,629,378,595,745,839,297,483,886,887,150,214,30,571,973,57,34,312,305,192,246,772,550,231,13,703,244,466,125,183,88,577,338,973,45,103,181,726,908,435,309,72,502,513,851,863,38,964,776,131,18,495,985,837,326,580,223,553,203,669,993,377,849,382,800,833,595,235,908,437,13,671,114,533,96,411,983,697,54,238,187,479,824,76,9,101,902,920,346,425,239,30,160,215,704,160,825,686,190,398,676,503,708,378,852,532,59,811,856,302,549,589,575,586,426,762,79,120,724,276,997,302,886,918,494,470,891,196,508,396,241,695,637,652,684,469,632,692,341,67,866,283,666,70,381,295,936,24,217,919,627,925,607,120,128,67,431,230,581,195,698,93,123,315,270,281,328,749,358,823,330,272,392,272,821,316,932,417,700,747,642,955,672,346,457,363,541,607,916,351,260,464,472,129,573,48,737,352,876,893,854,154,876,189,653,610,867,991,995,158,897,453,480,851,491,590,990,302,443,501,284,125,866,624,201,829,342,284,988,123,774,813,458,787,434,430,489,73,350,645,297,910,296,552,736,771,992,712,760,583,758,463,841,258,484,485,278,642,41,172,324,956,428,283,840,617,286,851,426,69,566,671,291,350,966,463,39,976,817,435,76,617,469,775,584,851,164,92,269,344,367,628,917,186,831,700,279,753,506,51,119,299,540,45,380,422,545,376,81,186,52,88,705,615,296,866,789,895,253,677,784,9,989,122,231,996,145,290,905,827,676,592,409,977,900,244,508,529,306,521,394,70,957,641,817,179,946,549,575,11,841,830,336,625,501,905,372,593,240,227,743,296,891,22,534,888,637,408,736,211,156,492,206,642,662,123,494,382,501,772,670,907,401,452,268,141,643,623,749,799,211,71,145,918,420,220,253,513,507,917,45,307,924,197,636,623,511,127,894,548,501,919,180,419,764,951,162,961,959,254,623,721,554,535,185,543,66,950,678,831,485,628,617,303,947,534,268,889,806,151,591,705,728,414,153,691,448,584,169,716,871,501,70,870,351,295,718,804,998,700,38,14,104,709,15,711,762,307,882,640,92,70,775,388,336,113,364,663,259,981,582,597,244,753,378,220,64,646,959,50,868,985,202,950,861,764,381,305,70,602,481,442,150,314,393,699,369,608,252,183,430,403,994,642,38,558,73,35,207,231,924,743,669,109,808,752,513,184,182,298,886,723,683,223,223,456,938,830,955,244,206,214,15,706,198,934,487,306,894,566,480,44,75,688,62,611,847,425,24,973,858,621,956,660,512,989,742,192,333,832,401,654,394", "111,341,300,471,734,946,887,333,937,6,210,356,471,504,348,751,647,285,392,685,530,827,20,270,88,585,515,787,177,436,869,122,774,414,675,719,733,882,900,593,270,259,696,196,64,922,45,340,288,960,546,352,710,31,670,98,526,541,618,133,913,132,924,432,120,251,269,912,848,260,283,445,512,815,676,853,591,595,869,204,988,787,49,849,374,888,930,632,392,719,873,581,681,185,248,639,684,28,172,311,442,590,835,598,40,676,982,533,129,941,880,417,880,99,934,288,810,604,477,620,629,78,342,676,67,757,338,480,284,113,937,336,956,871,419,730,71,951,11,284,159,340,511,606,476,751,373,871,105,865,220,621,229,681,86,518,992,36,340,976,978,278,822,506,173,957,496,462,899,542,884,521,532,991,464,284,542,573,280,14,409,105,675,130,107,150,399,338,870,936,888,229,688,734,662,411,846,252,480,904,66,440,955,391,225,877,953,140,181,805,379,330,468,366,771,613,302,694,532,876,138,196,912,272,599,137,665,407,215,916,959,818,542,982,380,804,781,644,414,966,90,151,189,178,222,77,300,710,28,891,252,863,379,531,951,139,252,503,262,23,700,908,21,105,300,379,953,24,727,426,265,35,219,891,32,869,556,2,44,849,31,479,24,388,425,556,476,767,820,58,854,512,915,255,283,728,882,351,665,378,244,909,749,89,901,923,368,141,0,390,426,727,617,300,854,470,2,212,939,415,752,436,104,922,247,582,785,229,418,724,985,942,441,433,232,461,763,165,534,813,632,536,791,510,478,944,179,656,102,117,520,875,248,355,439,772,830,96,630,258,459,784,803,164,935,148,624,669,234,77,621,958,159,110,941,167,963,961,911,484,605,484,901,924,703,458,806,16,616,263,788,739,353,964,939,555,140,300,450,487,534,154,536,280,929,476,761,205,798,513,849,674,402,384,897,754,795,556,965,952,161,945,120,460,374,364,612,318,268,949,957,506,82,60,889,650,558,92,403,235,556,777,97,346,23,414,687,697,27,872,89,420,267,92,113,473,824,134,833,746,927,653,971,368,439,471,965,792,227,914,82,299,56,589,265,221,296,684,778,438,15,23,42,149,552,681,689,947,15,522,30,738,470,993,795,194,869,464,87,41,869,671,779,898,135,277,375,979,410,42,155,970,756,707,656,667,919,776,755,877,336,309,568,575,574,644,894,659,227,775,576,448,78,121,920,247,374,868,843,329,844,706,263,53,494,425,731,938,281,631,291,623,776,330,311,47,123,648,385,654,132,180,353,856,824,972,6,814,682,547,862,308,997,388,518,427,866,127,936,18,477,818,795,233,951,461,359,564,755,889,599,153,388,544,282,374,861,405,147,66,799,646,20,800,50,507,758,717,854,612,226,236,158,34,749,506,196,75,391,232,550,291,867,393,159,292,276,131,521,711,336,334,14,856,33,500,201,748,198,252,499,446,250,231,689,952,903,773,590,71,467,268,937,584,472,641,618,991,931,273,312,471,953,874,859,501,125,447,716,244,519,377,433,881,729,211,61,83,971,376,622,126,841,714,156,498,266,931,934,423,180,30,214,671,993,902,14,805,215,651,672,499,436,386,150,107,510,456,923,51,177,731,466,330,744,282,586,223,831,420,37,253,426,202,449,376,434,773,814,806,698,891,857,646,233,203,854,372,431,224,107,306,634,988,505,239,155,720,944,670,602,961,81,663,243,231,668,753,758,905,406,855,953,155,508,202,276,680,120,241,993,142,142,614,779,201,607,792,857,682,720,262,293,244,424,82,460,952,695,161,54,702,87,370,143,773,754,223,511,306,815,100,467,267,77,25,882,459,266,919,230,236,841,259,323,964,978,876,622,824,400,483,337,859,475,591,482,273,179,126,812,596,390,49,939,76,365,500,126,612,643,425,950,971,743,301,602,921,154,836,160,881,558,85,903,693,820,873,743,202,4,637,270,711,275,165,720,126,67,763,719,45,55,473,650,957,639,592,391,961,266,333,937,808,887,558,574,821,162,880,800,900,345,377,190,353,928,137,264,290,416,688,308,939,89,198,134,975,845,611,938,207,507,864,317,362,241,41,746,239,33,250,737,121,465,707,158,725,58,891,50,786,935,540,386,763,669,406,598,695,933,959,72,969,315,154,224,562,431,455,876,49,169,136,965,966,79,352,775,142,744,441,514,725,446,891,898,2,938,180,388,86,616,440,597,124,854,188,419,689,510,42,893,491,675,861,227,468,962,327,874,141,586,648,354,274,282,590,40,33", "286,877,246,667,473,117,873,939,608,540,32,627,779,111,437,453,684,694,547,321,997,996,261,278,44,238,753,179,362,356,680,247,893,81,998,751,10,662,583,889,204,26,292,642,837,333,592,217,104,988,89,842,695,693,438,994,926,787,978,148,524,264,968,952,398,17,921,932,449,45,537,10,580,98,700,222,462,897,104,815,437,215,311,42,733,260,396,228,359,185,549,39,177,307,85,288,175,829,652,983,960,790,896,466,86,685,110,746,785,592,19,559,167,839,789,581,659,75,111,130,318,619,840,169,3,881,469,714,107,855,976,380,902,710,899,900,309,828,964,301,662,516,718,520,672,897,876,860,182,54,18,58,724,17,986,606,202,171,500,379,575,510,601,931,787,585,246,131,707,392,716,348,609,810,276,586,482,382,818,481,651,307,334,589,91,52,153,634,726,382,239,973,55,777,815,991,482,221,390,546,911,774,588,156,776,45,30,153,646,153,361,838,59,716,539,11,800,798,697,40,723,354,154,255,53,404,447,453,502,173,688,598,458,500,600,725,153,440,8,775,236,666,504,441,897,392,25,713,862,325,394,131,569,17,343,150,946,968,672,784,511,621,185,967,266,867,450,342,452,814,575,525,626,795,673,317,237,251,38,221,800,146,781,359,98,42,813,903,218,932,535,359,370,783,824,468,832,502,698,444,895,289,258,178,415,236,631,781,390,0,510,942,943,423,831,497,685,990,639,286,372,378,181,176,608,949,452,234,668,613,988,226,213,474,843,93,1000,333,862,174,392,674,783,539,896,961,110,9,908,959,714,128,531,844,214,589,948,320,755,246,811,836,938,633,95,187,808,570,832,393,527,310,908,747,718,142,406,813,283,877,7,331,644,362,110,69,727,611,906,161,471,973,361,252,329,163,23,365,594,724,389,525,448,539,144,926,518,159,581,449,451,71,220,915,544,950,510,809,404,250,279,281,849,931,705,575,923,746,178,879,72,441,240,28,276,10,155,670,102,936,880,530,17,977,875,675,716,228,518,990,744,92,875,852,930,541,125,407,486,459,478,939,15,407,40,797,426,555,29,699,924,239,295,601,236,255,896,494,711,955,578,355,189,58,372,612,662,3,866,664,421,373,490,517,149,689,708,321,943,356,253,235,745,335,39,214,297,323,590,474,18,747,206,758,335,678,233,388,373,102,690,826,840,801,438,817,803,701,405,602,582,498,629,572,31,665,110,716,560,897,938,355,19,342,500,824,418,789,625,473,430,564,121,214,99,875,785,436,687,663,722,843,689,906,428,827,753,848,325,252,942,576,342,299,871,528,306,947,835,623,862,230,136,172,718,541,935,499,37,956,31,327,812,430,778,372,418,845,176,32,800,45,998,27,294,326,847,357,859,621,794,922,832,188,754,594,654,51,272,413,834,31,67,110,541,854,964,998,115,69,712,976,287,630,712,710,93,535,307,952,3,54,171,17,381,319,613,340,473,952,703,926,820,345,832,482,399,191,883,487,15,788,932,227,559,609,51,812,942,756,740,850,633,695,505,388,606,147,537,769,246,803,134,749,250,914,612,723,569,394,446,132,668,180,833,512,947,413,438,449,354,372,672,3,379,144,357,953,859,625,163,81,637,918,587,819,377,221,356,237,139,765,240,870,403,363,616,463,975,183,183,244,624,856,542,253,709,639,420,487,321,975,149,878,79,260,592,938,334,291,80,942,831,845,66,668,792,239,97,511,742,919,358,719,135,621,404,464,966,400,260,316,316,395,819,594,223,902,546,712,604,522,817,856,79,135,134,929,109,864,291,645,603,742,493,135,242,925,530,214,800,148,465,926,268,622,296,160,302,221,191,597,629,796,120,210,166,437,765,865,983,704,902,67,257,777,593,148,703,164,19,168,733,410,72,244,762,41,126,355,226,493,734,255,944,981,500,762,955,102,134,231,16,677,434,826,171,896,13,330,861,464,85,54,43,581,926,609,250,348,941,358,647,820,812,836,987,84,425,768,617,423,220,923,808,454,799,404,16,813,793,903,564,852,269,276,129,708,99,857,776,647,555,914,952,560,723,171,292,323,170,204,292,941,524,529,943,371,60,575,729,640,617,260,503,181,888,868,777,15,458,996,23,498,137,44,407,305,285,576,791,358,443,184,644,746,508,438,669,391,724,908,579,635,430,284,76,202,904,515,617,782,819,880,248,458,945,774,607,545,46,64,58,662,344,879,407,97,907,332,594,600,838,699,248,932,217,658,113,412,130,211,273,392,132,715,398,59,998,763", "958,30,275,564,599,457,704,937,253,134,484,729,151,840,343,873,625,497,349,732,694,101,561,646,165,769,812,611,209,513,408,91,180,225,396,548,496,475,17,826,496,106,589,796,758,41,92,862,737,185,683,711,538,581,373,660,138,970,964,497,25,515,331,556,765,29,470,636,462,91,481,627,777,458,949,57,659,709,681,210,568,727,508,498,97,158,347,48,942,840,935,207,108,540,888,437,778,361,393,113,606,177,738,522,664,534,414,740,386,143,84,349,906,477,562,122,61,581,98,726,488,226,544,940,743,419,738,767,757,840,449,542,420,518,378,955,693,726,295,138,248,459,182,200,470,790,181,620,458,143,509,910,151,992,545,626,689,264,59,57,766,576,123,318,801,513,659,247,906,653,157,503,535,739,938,427,568,465,504,129,150,298,494,482,783,750,80,460,394,785,238,894,412,362,248,99,435,491,217,911,440,545,918,503,957,659,924,456,843,404,5,432,880,895,125,838,617,961,654,336,865,939,574,678,805,35,152,165,950,1000,294,175,915,154,235,639,469,693,367,235,674,799,200,273,434,41,429,186,174,114,495,682,866,338,892,971,244,436,930,552,524,898,557,601,352,169,589,368,694,161,546,898,68,614,431,185,391,755,418,584,904,241,12,771,791,732,651,553,224,261,110,156,420,345,803,478,914,463,838,231,107,701,461,705,722,179,553,492,426,510,0,453,351,569,885,519,963,699,557,835,349,46,943,649,390,379,897,926,380,271,30,753,445,823,111,130,880,668,720,830,843,267,775,933,564,583,30,96,291,463,311,750,698,334,907,218,216,292,447,564,688,116,750,965,385,153,817,383,557,132,363,985,684,982,637,302,462,597,876,434,32,991,316,506,271,465,712,356,197,477,166,310,918,465,162,153,32,937,406,8,339,865,530,389,462,583,572,811,804,594,309,696,620,768,433,11,899,343,998,803,150,477,827,429,892,986,155,279,941,712,569,595,77,216,496,650,436,436,408,62,337,580,621,693,927,320,534,165,215,988,697,607,610,328,64,744,540,574,701,364,536,688,359,201,252,172,787,499,284,601,64,128,918,283,478,677,345,223,740,846,975,113,821,91,755,929,581,418,387,504,963,315,815,152,534,849,877,98,279,432,200,496,387,143,655,835,957,522,84,776,892,724,307,661,704,545,511,650,344,914,254,577,590,89,408,282,238,643,24,945,543,904,668,898,262,777,542,665,12,665,82,506,768,119,668,242,283,854,618,148,488,884,105,13,842,950,100,437,231,586,786,524,417,276,864,737,913,989,468,944,30,253,823,988,614,56,792,264,806,677,559,812,261,990,687,920,551,189,265,856,206,541,635,86,144,553,327,306,719,636,503,701,561,631,327,445,839,508,454,842,880,949,529,918,867,82,723,18,937,891,745,600,147,457,675,926,906,393,131,126,98,766,312,174,736,166,276,994,430,607,985,805,228,51,702,98,630,312,905,393,78,719,344,874,732,90,208,32,175,55,324,820,586,954,419,787,54,916,202,73,127,66,924,862,517,493,158,196,680,127,883,947,870,724,418,145,215,732,663,969,671,264,399,245,394,664,861,598,249,351,37,40,423,74,931,432,451,263,595,323,869,35,876,588,957,490,146,612,950,440,852,795,831,851,683,831,476,370,254,110,25,170,709,44,881,639,660,259,834,359,818,487,188,440,338,157,882,601,331,805,136,530,185,844,287,629,254,572,753,818,391,404,768,735,959,991,985,712,949,348,551,960,934,606,539,199,175,495,240,238,31,755,222,156,734,71,671,572,758,169,203,59,72,627,335,74,561,176,366,716,122,318,900,138,756,815,925,925,86,447,747,503,161,551,802,525,148,532,461,309,741,90,323,497,232,133,910,349,653,179,702,599,831,120,283,367,643,732,468,866,791,164,259,810,968,730,368,357,542,48,660,345,604,376,711,149,767,895,378,107,90,562,678,21,284,626,147,105,688,618,726,548,289,455,967,722,776,667,387,449,678,538,771,988,459,672,70,64,893,672,123,951,29,888,475,521,787,316,654,735,350,910,289,210,987,597,555,952,256,732,222,122,316,244,288,208,366,901,416,462,266,584,573,548,126,161,341,344,853,946,265,597,135,730,723,101,922,396,782,551,639,541,337,161,520,572,318,562,467,132,432,424,556,501,676,172,843,558,322,902,358,62,821,153,484,783,27,701,746,881,88,426,436,52,355,201,244,619,45,987,421,766,766,887,943,510,423,935,40,125,114,413,572,393,922,350,315,566,362,856", "119,213,61,731,566,713,803,281,730,164,403,668,867,105,172,930,398,177,574,387,957,984,903,26,120,424,684,258,682,420,454,289,808,473,516,869,403,123,492,197,995,53,104,247,33,687,899,466,945,3,42,150,491,551,333,434,291,271,502,599,965,605,872,129,82,186,125,416,320,391,568,405,872,183,925,532,507,397,56,736,863,891,879,667,539,958,59,348,790,691,792,791,556,938,488,617,288,173,464,762,521,484,36,894,180,632,672,338,75,896,501,708,25,408,540,866,423,200,790,415,706,56,425,549,103,422,145,135,582,692,649,147,852,867,261,175,727,568,529,579,261,234,742,174,419,86,375,297,729,523,992,355,163,233,730,288,19,176,678,237,436,224,998,931,486,94,449,576,447,774,716,243,741,339,632,517,139,118,522,914,87,408,983,931,236,609,382,42,988,392,662,110,511,290,541,236,813,892,440,595,383,105,444,721,187,647,818,824,906,845,166,808,584,723,817,205,448,285,145,133,92,727,639,770,33,264,760,601,960,786,968,280,847,760,586,643,332,426,118,178,760,402,881,120,442,921,573,194,544,242,329,880,64,983,872,591,4,87,491,776,407,796,823,579,959,778,853,669,555,795,784,403,742,881,742,788,768,347,824,442,883,785,84,297,73,340,145,306,772,779,875,560,448,130,709,619,644,969,123,278,172,254,552,133,597,81,26,839,727,942,453,0,20,954,247,461,592,249,274,172,48,727,302,779,164,991,886,847,488,510,398,945,581,712,136,700,127,533,983,884,408,739,231,102,677,911,557,906,321,701,332,968,78,675,598,354,569,911,994,403,846,871,187,42,806,895,843,678,329,759,23,30,347,38,675,769,183,434,420,198,773,842,245,88,286,825,193,602,477,371,180,795,206,78,664,377,23,965,192,713,710,178,717,673,433,713,772,509,112,701,352,300,551,976,868,768,364,52,813,116,231,155,776,19,92,414,713,89,406,11,391,413,955,331,625,883,230,15,431,663,953,648,8,141,471,971,864,515,13,482,914,666,364,714,750,149,526,392,281,657,52,344,343,108,938,567,694,451,344,992,873,81,80,496,407,407,740,361,236,14,454,64,562,860,704,511,148,231,592,703,996,899,100,621,427,760,892,304,834,416,809,462,50,774,32,563,576,525,641,464,250,516,477,796,477,581,184,852,767,657,515,745,871,786,918,631,91,990,760,395,374,637,427,659,587,586,897,673,406,299,497,497,666,938,168,364,668,958,230,557,101,277,282,482,833,905,881,674,59,2,233,742,694,452,388,376,613,111,2,544,886,256,539,827,951,489,470,216,553,652,190,396,84,712,973,323,103,37,922,754,378,867,570,804,864,959,81,421,391,161,132,520,263,408,805,86,723,706,371,250,192,237,939,951,810,187,453,463,119,637,494,945,425,382,940,635,907,231,829,892,344,214,523,588,939,36,966,745,275,694,691,171,612,410,839,958,410,821,969,501,93,610,252,790,486,871,336,498,492,714,172,654,276,169,346,87,594,541,50,560,594,973,27,421,519,27,817,582,544,511,122,142,953,483,735,353,658,635,165,4,830,819,593,796,395,716,632,195,898,151,892,717,833,543,102,442,861,852,140,282,878,266,82,522,148,236,564,458,514,331,995,500,297,504,917,792,648,83,380,409,948,621,293,766,912,548,533,646,150,347,847,836,110,599,567,769,363,240,391,626,44,728,151,675,867,538,792,624,270,153,102,738,826,332,43,732,690,375,762,322,605,59,42,41,477,170,122,468,339,374,233,39,962,956,125,813,919,976,842,74,465,501,487,884,692,367,87,717,550,698,968,862,176,353,921,537,957,442,800,445,86,42,353,14,837,771,66,1,538,875,467,530,571,850,733,316,96,65,867,266,415,338,117,397,213,640,626,397,671,613,671,177,3,313,155,331,50,192,602,485,958,551,950,357,926,327,438,392,512,54,97,103,748,941,867,764,616,762,842,721,76,552,432,989,115,264,493,549,894,457,39,584,89,778,859,377,852,388,954,231,678,624,580,974,994,117,471,5,462,34,805,266,576,441,766,428,171,450,90,764,386,296,627,292,202,851,514,388,636,990,996,686,2,421,760,343,740,907,563,510,431,835,641,771,697,113,493,393,26,374,354,700,997,20,529,813,458,834,842,783,905,131,395,136,882,956,14,988,255,101,390,550,322,592,201,642,692,880,721,893,871,275,385,903,676,37,504,792,724,146,307,997,905,536,168,681,961,349,838,15,536,485,210,319,250,770,626,446,979,793", "652,227,888,900,508,368,864,864,227,106,29,458,632,424,388,748,34,359,739,601,661,715,27,391,204,271,275,481,305,285,58,824,96,947,118,911,661,326,511,89,427,289,136,176,396,161,330,497,843,105,419,807,205,52,956,844,477,770,947,688,164,741,174,199,590,249,203,568,316,308,487,845,283,925,480,135,283,704,2,229,78,508,165,976,29,889,120,480,42,686,134,741,606,945,615,459,264,410,64,335,723,64,247,522,791,39,306,321,798,37,664,540,76,58,336,919,711,268,72,469,426,693,687,907,268,789,356,596,115,2,605,33,337,568,335,957,947,208,116,347,17,852,829,877,211,760,992,285,747,368,515,323,991,763,268,740,478,986,762,387,642,72,107,471,675,14,450,457,638,292,350,936,602,773,906,606,371,445,113,139,193,710,409,431,166,122,667,151,572,594,713,897,431,273,523,327,212,343,682,640,434,406,863,15,844,157,4,95,475,341,361,131,369,162,484,580,636,594,117,921,559,118,430,851,937,473,341,295,325,5,204,709,692,85,220,801,868,744,539,676,475,328,442,452,257,273,505,759,188,285,976,516,670,423,849,457,269,76,774,344,338,635,969,28,507,116,508,318,232,293,568,368,370,134,20,278,296,938,875,510,673,522,401,131,425,627,210,499,101,297,92,97,246,514,2,244,684,774,36,924,516,764,402,736,740,93,999,969,617,943,351,20,0,543,863,474,565,995,723,895,128,736,985,430,396,89,58,574,858,134,497,309,400,214,814,309,751,103,441,361,23,692,502,252,148,631,851,106,969,400,888,275,753,106,165,437,304,141,874,979,45,664,137,999,73,528,866,802,82,424,225,152,256,193,404,805,828,876,475,418,187,978,766,859,78,133,394,726,838,800,19,103,729,538,523,574,538,286,72,12,190,569,506,68,974,189,182,320,527,395,151,680,50,374,233,419,298,610,8,989,31,574,670,770,237,233,492,926,61,21,467,943,923,602,996,525,904,912,7,899,916,920,658,75,587,151,286,317,488,727,950,81,144,990,788,464,913,740,25,716,551,943,886,868,839,89,567,603,253,4,71,293,845,245,261,938,620,809,204,491,878,874,460,500,761,283,106,632,999,212,414,306,308,777,437,393,200,719,618,369,724,247,126,36,210,325,404,897,309,690,22,836,849,149,901,266,355,819,540,121,862,279,777,619,303,619,853,630,867,499,565,806,803,329,211,659,547,505,898,437,445,635,66,764,400,647,574,910,665,426,73,742,957,102,23,808,830,955,732,678,144,797,523,988,543,920,282,401,652,123,747,981,896,117,643,242,857,173,274,167,392,142,89,556,596,993,302,573,347,582,682,895,273,517,449,183,10,856,458,159,678,598,597,347,606,732,947,395,685,446,296,4,88,35,639,10,654,726,805,893,908,430,325,125,259,400,620,570,316,267,260,511,228,674,527,213,816,366,645,157,57,182,385,246,384,664,562,151,16,631,6,244,138,461,45,740,955,963,4,755,863,979,160,390,256,479,395,631,888,984,812,927,494,354,540,565,197,244,959,409,119,704,80,552,24,537,809,736,545,690,110,305,244,125,526,643,384,305,810,917,920,275,543,916,251,817,479,239,68,823,776,980,445,834,182,392,395,318,192,798,207,966,43,256,609,936,63,142,287,284,264,793,861,382,925,185,530,587,956,644,177,195,537,324,940,391,590,425,996,385,502,620,449,695,811,22,32,152,535,861,211,377,707,736,307,89,647,541,625,230,463,603,78,844,337,414,743,546,565,332,810,310,95,822,674,666,235,364,594,353,135,827,427,26,895,150,124,281,17,823,708,716,507,82,89,54,869,292,300,979,53,379,844,996,823,421,508,148,707,682,797,117,568,758,44,668,675,609,940,749,319,248,462,509,815,20,121,78,733,456,816,853,783,273,878,264,909,539,689,650,164,925,468,973,571,236,866,103,497,295,493,131,414,204,145,578,940,298,750,245,266,954,345,407,349,799,342,787,259,89,703,218,169,654,555,187,338,1,969,160,612,954,742,656,636,355,559,988,802,330,895,826,278,557,150,994,427,775,500,883,326,481,521,715,484,297,607,560,598,736,929,166,444,208,562,653,435,862,807,620,782,792,816,178,266,968,118,451,360,913,823,753,809,741,214,207,728,263,404,456,38,126,456,488,343,935,14,479,793,506,902,516,873,775,806,307,392,289,581,987,498,887,111,695,846,616,192,135,29,540,312,460,444,28,173,518,553,850,107,310,257,724,266,896,319,206,913,489,690,356", "2,394,197,938,383,959,296,383,983,200,679,74,514,424,94,432,74,192,42,750,446,456,65,83,315,195,526,368,461,890,481,921,395,316,918,886,223,151,500,746,357,585,10,21,551,336,962,470,605,677,100,959,325,865,3,58,280,530,143,950,702,578,330,137,170,642,849,702,314,832,576,306,699,925,786,835,367,608,126,623,226,995,616,764,994,686,121,585,640,693,336,308,218,32,305,642,985,114,437,388,958,643,387,731,361,630,219,57,285,520,735,19,533,868,91,315,96,586,138,371,29,555,958,416,132,408,438,23,661,844,110,417,793,519,396,255,249,777,253,302,228,112,188,617,191,476,549,652,661,26,688,246,685,752,881,156,702,555,949,310,193,421,413,806,807,70,904,460,12,527,708,572,635,980,266,303,729,786,359,262,961,790,498,661,632,474,749,240,510,129,586,171,574,102,541,251,640,453,114,853,147,205,315,607,572,254,947,756,709,357,495,152,413,608,355,828,964,486,68,440,589,616,794,396,314,126,926,748,61,898,950,353,418,780,492,130,133,34,213,478,486,8,456,879,160,819,506,707,498,189,489,261,75,382,653,43,760,651,604,505,614,42,669,22,132,894,111,933,875,631,840,693,596,752,978,239,343,31,127,994,713,130,262,804,350,258,653,574,59,18,363,292,259,946,165,596,697,426,158,950,83,458,134,771,115,615,552,794,300,423,569,954,543,0,580,493,677,539,299,221,438,80,976,361,764,518,842,335,915,248,631,832,956,479,335,436,705,578,459,830,211,937,759,689,487,910,526,240,370,164,738,136,908,140,181,481,28,272,420,309,158,131,808,652,144,935,518,870,181,636,471,364,637,241,846,811,725,244,165,604,118,470,127,185,686,29,49,833,948,839,888,633,669,886,858,449,959,941,12,204,804,493,768,565,315,818,135,496,724,27,635,342,797,562,641,951,352,544,748,24,902,343,85,82,382,529,356,179,206,947,208,421,490,494,160,740,308,392,966,347,605,436,373,649,179,510,620,116,925,720,418,758,349,592,13,528,903,203,297,37,686,837,482,92,370,918,365,163,739,949,258,74,384,312,637,940,336,27,263,750,100,738,964,271,267,445,501,870,480,251,772,53,803,745,893,297,50,139,13,424,322,924,742,992,75,988,918,2,284,819,564,218,473,40,772,941,778,996,360,993,606,191,666,376,729,230,72,8,698,578,329,528,268,466,24,541,185,329,30,372,603,218,888,750,534,740,337,840,370,225,701,365,932,638,167,84,594,225,991,275,513,917,413,80,680,365,757,424,374,153,528,587,760,282,964,689,522,242,103,514,989,109,74,591,365,758,636,396,118,470,613,83,302,915,812,37,789,457,330,234,715,456,961,549,750,513,482,895,301,655,555,847,272,872,726,45,781,384,896,556,30,540,143,940,357,79,107,147,859,599,599,941,643,50,885,167,370,467,100,6,882,247,637,623,282,1,920,93,879,9,949,116,603,120,840,747,615,220,4,762,818,53,334,949,736,166,528,113,138,834,61,397,371,321,297,647,880,989,196,298,419,474,582,749,739,423,382,971,295,176,827,33,923,596,609,834,366,356,757,957,391,641,332,202,986,692,59,259,790,858,115,719,242,530,280,97,495,639,726,843,721,726,534,225,724,988,61,715,554,940,778,423,781,817,283,190,751,164,36,485,260,461,798,898,902,703,806,957,854,679,84,625,103,584,138,609,648,244,837,645,802,123,412,800,483,371,19,694,35,583,142,224,448,449,26,62,423,273,812,959,805,962,713,155,786,151,369,855,200,935,408,154,566,970,32,672,244,418,599,24,23,90,675,384,387,605,771,492,394,348,457,613,122,422,101,115,403,431,815,787,859,380,560,567,773,80,574,873,934,595,619,533,556,983,960,721,114,991,811,835,687,745,636,506,714,444,67,901,772,358,108,462,452,448,886,320,305,929,911,5,810,708,100,848,81,330,697,387,182,126,677,667,686,258,345,387,973,560,740,347,984,872,174,930,510,909,657,902,648,283,628,625,108,353,368,880,9,571,925,597,884,511,462,718,413,269,988,227,226,753,900,662,793,951,283,107,690,710,724,196,946,705,518,824,142,953,44,9,276,442,861,65,456,749,527,261,332,977,585,422,866,623,649,701,14,211,713,182,566,464,885,264,429,20,782,855,869,977,99,351,275,990,480,675,536,113,622,794,567,378,981,364,257,747,494,296,9,122,245,649,41,792,243,430,172,246,278,835,301,462,305,451,924,48,590,162,964,327,970,481", "140,332,978,249,727,930,609,720,527,639,450,245,667,340,319,905,248,336,738,10,218,974,751,194,881,687,677,756,495,268,810,579,261,587,546,72,363,595,413,125,598,811,843,446,218,672,889,178,352,718,854,53,151,224,138,744,796,225,526,561,362,213,485,555,650,241,406,174,881,223,224,767,514,842,599,343,985,417,513,444,307,979,651,383,702,239,57,418,622,504,207,144,945,201,464,234,361,917,338,905,416,923,784,510,933,715,881,470,588,683,449,15,671,750,56,528,190,62,600,934,105,570,804,567,714,344,267,109,638,299,869,886,271,457,984,462,652,230,707,500,345,755,41,794,755,956,844,817,990,31,372,368,826,8,195,624,616,402,876,721,356,18,453,317,783,119,402,229,812,10,539,432,866,150,422,106,29,108,26,260,138,247,983,930,28,983,841,228,106,708,134,801,873,563,366,508,85,143,882,825,698,685,925,916,859,558,286,233,251,599,640,647,695,605,182,773,898,943,365,766,248,652,395,774,741,37,460,479,285,538,685,776,968,216,56,729,355,829,296,607,965,931,328,362,511,653,733,124,237,449,990,881,296,102,447,560,341,10,150,522,626,194,97,999,815,114,901,897,649,702,693,515,528,849,258,692,994,187,192,133,490,773,487,981,435,264,517,251,726,586,679,568,148,524,529,662,635,927,188,197,480,471,413,588,783,259,551,339,854,831,885,247,863,580,0,30,452,26,312,660,224,41,760,299,388,299,928,759,932,716,683,398,744,687,964,942,857,772,151,227,407,685,702,296,451,971,364,417,657,356,502,852,313,711,293,105,510,344,391,27,51,691,3,231,44,798,891,293,677,445,691,137,166,269,388,355,503,866,373,383,303,175,851,368,470,462,803,684,186,578,433,419,200,697,892,967,495,464,183,473,418,647,945,761,66,459,470,688,219,532,131,802,3,810,769,414,325,165,603,787,346,325,458,228,425,896,498,812,450,216,17,574,539,963,850,109,872,495,39,222,654,427,993,39,478,900,472,207,135,796,639,492,190,449,574,525,345,271,666,904,67,641,950,943,92,483,32,976,784,423,881,763,237,142,640,119,304,108,898,557,540,107,386,879,948,549,18,417,701,128,739,181,965,561,620,61,905,949,47,866,294,124,905,700,763,994,45,124,941,41,462,878,373,333,226,524,919,506,865,344,711,106,841,181,800,706,658,670,611,515,823,669,679,600,778,203,725,469,158,160,438,585,716,376,77,280,991,365,986,569,101,950,106,950,93,915,116,405,492,307,30,924,779,166,921,231,483,811,313,259,225,939,346,140,750,356,479,693,30,82,49,625,818,652,70,833,701,675,632,532,527,987,898,341,99,19,224,173,900,602,500,911,723,24,99,64,772,609,327,576,399,385,934,220,236,312,41,171,513,690,435,454,865,118,371,262,203,371,844,753,827,873,595,335,60,478,463,221,140,39,688,223,249,196,546,229,606,739,149,600,760,120,873,731,868,50,59,910,320,944,925,205,33,523,877,808,412,680,4,721,92,714,802,830,975,787,76,950,471,610,355,306,353,670,483,341,252,814,220,430,660,592,365,942,391,13,749,150,352,392,291,436,277,722,812,433,894,923,150,834,482,218,517,266,983,917,37,820,878,513,810,783,371,803,615,415,532,740,281,475,36,82,962,594,759,71,87,924,346,793,486,878,364,334,848,199,283,877,543,192,608,853,700,506,51,457,468,57,544,685,780,750,215,93,41,256,812,538,607,906,274,509,836,396,486,870,427,200,889,633,489,106,52,909,913,272,574,888,440,872,524,696,183,253,365,867,40,923,35,314,933,218,200,644,405,445,976,201,670,382,469,352,379,276,376,408,880,442,482,136,437,577,849,872,973,315,837,856,495,309,895,100,691,825,299,557,593,379,767,727,208,99,7,2,706,252,915,583,105,987,33,872,810,971,234,684,488,985,157,37,926,748,396,809,306,762,435,62,734,658,245,478,433,99,773,708,958,933,458,372,179,786,856,236,166,437,849,856,633,146,815,136,606,102,614,721,628,497,902,635,814,972,816,178,158,974,63,949,588,434,76,329,349,193,879,763,143,851,409,792,241,248,285,359,573,113,514,174,653,83,776,125,998,518,966,921,587,747,468,634,112,687,180,730,298,570,355,55,279,875,141,618,906,597,926,14,110,782,758,316,566,84,103,94,545,847,589,1000,451,382,953,886,960,176,995,939,166,357,677,991,605,470,736,862,621,45,449,735,680,405,76,637,170,526,4,495,633,386,857,16", "248,421,191,300,957,361,396,204,889,839,658,311,356,847,56,132,555,568,126,410,143,452,393,310,333,854,279,381,921,947,735,532,602,191,511,497,519,620,983,365,855,219,833,610,715,688,10,612,239,699,202,426,542,114,644,620,947,1000,805,194,778,675,403,499,441,320,957,640,675,96,881,994,269,695,728,678,137,521,728,63,516,444,402,521,879,368,561,768,99,387,865,157,961,482,486,434,692,555,413,746,706,401,684,855,700,103,150,583,389,474,523,978,487,12,661,759,964,274,645,695,273,673,182,207,554,328,811,255,924,640,369,997,289,532,143,303,654,113,683,237,502,157,650,548,111,141,361,194,606,568,103,774,1000,424,385,770,935,305,406,510,760,443,772,382,740,104,992,145,618,86,68,586,500,557,204,251,150,210,229,920,352,93,507,692,899,482,990,964,24,766,877,954,329,513,272,384,540,148,438,209,799,709,75,131,773,501,710,101,940,922,745,354,644,688,888,797,863,317,270,251,109,840,26,838,651,151,536,812,838,27,792,491,234,369,929,6,301,162,426,350,510,692,791,82,455,764,416,1,305,908,344,319,235,670,711,939,812,573,984,381,874,197,556,675,784,772,37,101,727,576,601,842,817,534,692,212,971,891,424,200,865,631,512,859,683,274,570,808,448,449,616,876,817,650,71,347,657,647,404,908,289,340,833,730,644,183,986,867,470,497,519,461,474,493,30,0,360,510,992,816,192,293,77,336,691,481,495,522,54,154,371,851,415,448,629,200,87,270,596,756,353,867,178,96,368,837,537,84,692,744,99,849,791,681,365,436,982,173,290,946,243,35,711,312,341,358,683,494,655,578,68,804,421,393,102,348,234,805,243,578,64,320,391,742,563,409,726,507,835,698,596,807,131,276,683,278,964,235,598,24,773,824,456,696,95,878,558,866,949,745,94,622,577,835,563,795,450,650,294,702,275,815,767,639,79,488,278,733,595,857,925,649,29,999,802,513,278,227,638,270,967,989,694,862,333,284,790,764,989,610,298,457,819,811,491,107,433,864,767,935,761,936,521,882,984,430,19,621,827,275,231,190,409,417,874,683,657,205,114,719,243,483,866,785,944,686,535,177,946,130,525,194,103,803,648,991,671,603,353,392,381,215,850,39,637,203,282,984,115,221,511,969,137,527,503,240,190,441,357,938,834,212,714,227,851,60,858,509,511,727,545,80,663,558,993,117,249,677,945,312,930,237,715,815,725,688,943,676,234,486,786,94,479,267,858,568,301,122,940,480,381,12,494,574,658,476,665,368,740,943,276,745,381,850,446,99,15,561,937,830,85,574,484,906,130,599,85,632,729,343,590,988,724,374,59,126,810,441,802,80,850,941,28,664,939,103,654,979,811,611,515,312,656,175,384,992,578,741,788,425,405,640,333,636,348,889,231,733,436,846,102,75,98,630,636,306,169,887,826,759,935,579,122,326,562,15,41,897,191,782,24,539,907,299,130,919,996,462,460,24,541,658,775,953,602,419,976,722,785,800,88,959,621,450,344,431,477,662,724,980,299,319,645,354,235,628,916,346,839,312,604,98,726,929,461,289,283,107,948,223,229,577,334,967,663,994,95,657,162,621,506,582,202,285,450,678,562,251,975,534,395,679,575,582,770,674,561,712,402,991,272,844,511,308,921,850,817,533,405,238,952,454,528,379,543,597,590,887,36,171,113,539,57,550,45,891,85,528,768,628,234,600,144,481,949,345,348,50,534,186,921,846,73,916,543,416,56,823,934,476,568,167,636,802,126,712,902,304,89,941,240,366,319,18,414,405,323,431,732,128,561,817,681,542,394,513,704,9,433,575,747,782,921,529,936,166,828,587,904,150,134,732,172,668,179,569,856,863,49,852,409,379,711,457,922,908,37,215,32,268,571,447,626,856,234,270,71,950,634,787,316,509,866,339,99,767,597,747,649,779,191,495,359,81,319,45,654,707,593,1,950,956,623,611,176,446,299,340,34,351,633,322,423,298,72,709,437,893,668,371,893,729,34,86,431,132,113,75,790,487,380,487,344,65,224,438,806,379,756,523,313,473,364,481,617,104,331,488,947,508,313,455,293,329,368,339,664,966,102,869,233,558,847,270,912,572,512,813,925,956,445,154,719,789,986,639,736,63,803,508,231,400,170,460,484,49,142,321,495,801,763,699,693,239,958,297,766,857,500,702,957,849,655,300,56,808,429,756,604,766,46,774,115,277,384,678,734,466,401,731,456,836,807,61,119,820,732,103,821,297", "809,924,448,542,237,614,229,137,952,382,80,369,151,438,869,849,429,63,940,432,15,902,735,299,577,255,248,364,581,852,377,971,508,139,493,764,84,305,739,958,556,968,118,156,718,647,409,451,469,87,457,45,983,224,295,381,87,697,615,587,159,202,856,612,238,836,663,533,226,530,34,321,414,161,98,646,842,8,689,889,272,994,181,683,754,517,389,892,897,253,314,705,621,948,146,889,315,678,289,929,361,741,819,693,478,113,287,225,679,697,809,699,291,75,435,524,96,249,987,958,665,158,176,917,48,330,989,2,591,532,513,556,380,737,348,481,152,703,653,294,90,949,345,610,164,769,699,631,936,374,336,610,992,839,880,241,220,869,357,347,618,926,817,105,226,934,772,949,752,982,683,497,544,677,378,409,525,297,845,433,227,261,824,205,965,840,251,209,195,5,639,116,501,579,580,126,625,175,380,161,614,148,157,842,119,372,271,431,797,4,248,297,327,525,415,703,353,868,902,736,215,881,13,667,851,212,712,825,28,1,875,168,422,631,975,62,563,679,283,258,313,289,8,766,426,638,975,307,144,548,445,348,338,746,555,880,979,617,541,176,677,639,418,389,853,796,253,918,924,968,774,32,475,89,459,468,804,13,122,316,554,484,811,581,715,724,927,319,592,404,843,231,97,342,580,416,254,170,904,135,5,678,52,269,820,938,381,539,2,685,963,592,565,677,452,360,0,848,993,981,996,405,309,967,172,393,914,30,581,828,953,788,387,929,615,477,611,851,248,194,942,674,291,371,314,828,371,225,97,193,176,365,383,751,172,144,32,167,236,853,201,905,398,538,577,563,61,397,552,928,215,674,118,767,949,157,874,653,54,917,781,16,74,918,862,87,505,812,582,380,59,294,375,413,872,808,618,39,400,373,14,305,139,495,362,527,187,730,65,805,269,381,665,612,351,938,445,906,467,758,454,261,801,473,457,469,225,655,914,562,813,349,935,244,58,509,315,850,475,845,422,922,661,150,909,538,648,845,532,798,677,452,374,109,590,152,356,247,741,569,40,132,702,246,307,602,170,764,748,755,289,530,925,735,743,995,77,627,971,883,18,862,595,834,269,861,730,586,610,393,121,737,726,981,871,662,744,316,262,781,215,648,306,635,344,771,405,141,189,440,538,155,185,174,585,846,470,270,710,322,269,758,169,840,561,915,584,74,587,966,411,475,704,572,923,55,424,775,116,883,392,540,840,43,884,820,980,137,363,17,813,486,60,357,681,939,215,2,63,653,448,58,907,333,523,370,782,96,92,259,343,676,670,399,537,24,32,236,479,922,471,811,662,5,767,290,423,291,693,483,356,693,665,584,524,90,112,62,927,386,999,515,513,649,345,792,215,403,742,715,510,495,816,584,796,383,246,18,514,200,406,114,731,470,906,326,966,46,14,49,468,55,529,664,725,732,295,150,234,822,6,642,554,880,455,407,75,868,870,607,431,50,791,662,889,93,739,151,340,542,641,413,541,662,555,521,142,191,665,226,979,847,169,950,230,379,815,728,871,734,852,420,366,545,990,597,643,517,553,996,45,615,223,989,467,749,30,886,471,842,638,512,93,862,125,23,381,937,784,321,477,394,787,400,921,68,707,586,117,325,96,201,456,43,125,619,400,991,232,682,931,166,682,734,284,941,856,896,781,660,44,519,534,577,288,12,263,37,232,957,220,714,87,800,305,313,637,968,997,450,784,978,225,158,46,855,657,8,703,179,831,135,169,107,647,584,554,629,912,608,227,63,741,328,142,203,835,440,431,474,874,744,222,814,279,597,818,601,281,384,942,738,276,704,853,880,634,996,741,759,130,436,548,95,230,982,123,253,27,433,22,665,547,410,141,417,849,762,731,699,998,773,738,940,929,113,836,63,549,37,286,173,111,73,446,487,690,701,318,658,198,44,246,1,127,869,605,697,120,325,414,82,209,465,210,389,955,193,247,360,495,191,221,282,365,129,380,394,895,632,792,186,77,806,258,451,534,867,582,28,693,801,153,32,64,498,20,560,586,738,557,678,542,542,996,540,112,222,388,51,395,59,163,93,620,834,477,149,104,732,626,235,837,742,78,999,366,235,38,197,208,310,828,533,267,518,670,138,782,558,314,583,363,304,676,380,844,436,88,833,111,515,714,245,225,164,213,955,496,626,534,898,524,542,418,594,721,61,250,985,789,830,926,326,670,827,207,105,443,544,330,108,669,977,410,435,102,110,274,404,446,363,793,402,971,894,166,531,605,974", "475,385,747,745,607,446,670,198,220,227,891,780,152,403,596,674,577,293,601,792,421,862,572,164,663,490,853,425,61,555,813,379,643,512,64,572,579,241,188,4,395,572,679,8,547,973,517,304,269,721,218,819,674,62,442,715,432,714,315,297,859,63,130,612,995,624,995,189,92,187,492,6,894,274,992,130,473,605,816,835,556,31,47,79,789,804,599,278,919,933,866,770,30,67,129,944,887,358,377,93,768,220,541,405,631,281,927,58,598,131,178,928,773,91,874,940,757,948,662,867,691,350,366,294,856,577,612,893,432,834,591,209,600,144,264,824,32,553,929,564,547,317,422,43,662,872,388,9,182,607,683,766,541,477,120,212,310,685,622,871,260,879,608,736,616,810,993,411,639,331,561,712,14,208,172,935,285,303,389,376,542,392,326,520,710,908,187,920,859,309,910,656,69,916,123,498,462,753,626,277,899,157,195,383,625,825,735,695,941,289,140,421,608,728,769,970,928,445,944,26,142,380,41,631,300,758,761,441,193,818,46,602,284,518,646,982,805,701,34,485,287,7,651,882,768,814,886,259,456,745,807,92,400,14,932,745,902,656,234,907,878,386,553,822,42,299,727,880,724,360,79,166,365,676,873,443,527,786,534,458,969,437,231,124,593,405,295,568,754,296,321,983,358,887,195,281,539,50,944,101,691,448,467,969,907,69,40,664,212,990,699,249,995,539,26,510,848,0,700,333,670,44,430,69,869,645,455,667,707,883,246,307,778,585,192,885,316,40,501,212,744,383,135,386,44,9,348,139,686,741,326,45,628,395,278,566,406,514,953,674,56,437,434,200,804,94,572,669,483,355,898,656,390,792,134,598,134,920,83,415,418,563,448,635,74,726,301,205,554,141,462,735,567,750,99,110,456,103,104,530,481,336,364,546,853,189,980,601,642,986,701,569,975,489,387,598,360,153,739,493,997,493,51,723,67,313,973,988,852,338,500,20,237,462,389,162,476,653,219,700,15,127,804,128,772,929,102,692,83,19,436,370,447,406,433,409,574,610,1,314,690,712,562,353,732,219,889,117,271,719,354,885,432,726,542,52,873,543,345,937,223,96,676,455,228,42,210,333,225,896,753,788,923,997,50,256,560,926,619,78,594,331,870,218,298,285,987,394,336,860,914,53,707,194,426,244,12,887,876,988,734,975,29,554,49,892,129,503,751,247,297,159,618,208,504,450,944,24,444,715,281,174,854,971,150,385,834,263,461,615,864,545,936,581,785,162,46,426,368,554,684,713,999,927,821,384,765,894,332,336,592,748,85,147,579,946,966,286,734,497,576,85,424,589,716,364,86,36,809,901,571,631,28,850,157,936,212,181,388,649,741,281,194,88,108,44,321,358,188,505,96,820,108,529,427,401,841,870,480,508,84,801,124,991,699,660,424,284,359,667,700,282,282,101,230,321,109,465,950,933,290,245,410,676,477,3,530,828,664,486,59,104,919,695,271,669,406,749,32,855,491,94,591,226,864,318,142,603,875,514,659,449,417,306,961,886,229,433,994,88,908,395,803,885,407,372,323,721,225,383,735,839,497,999,489,47,405,230,365,364,868,151,407,217,30,913,717,873,393,939,492,575,982,625,835,415,103,308,239,927,368,178,676,298,204,618,622,852,374,852,424,321,955,835,197,753,543,254,119,245,420,159,847,517,236,232,540,876,45,117,623,488,449,800,802,242,453,352,949,875,708,45,476,692,68,277,419,181,763,77,154,296,980,337,878,61,718,200,328,707,129,608,539,698,414,190,113,350,705,603,578,444,34,259,308,981,418,932,462,478,139,687,984,946,658,694,306,351,541,877,229,138,935,794,788,478,996,849,226,451,913,516,345,627,313,811,333,393,970,129,337,218,395,350,713,712,226,989,534,493,591,372,550,950,419,366,993,81,241,287,348,25,786,858,422,508,591,707,67,943,852,316,103,444,23,191,259,190,464,317,778,951,558,732,676,848,29,209,436,695,753,228,307,906,831,541,130,669,722,732,241,611,49,463,841,691,303,515,315,847,599,231,876,828,606,673,36,881,464,252,491,199,737,456,999,757,98,913,393,374,543,368,846,414,840,86,484,657,234,69,195,441,169,187,267,180,856,140,969,164,409,782,891,537,676,122,902,80,472,95,715,411,589,823,382,136,278,141,387,911,850,374,969,856,312,620,59,238,602,169,933,812,867,499,219,20,37,221,800,254,757,517,578,914,739,824,140,41,206,185,966,162,718,961,652,842,155,976,623,188", "752,405,975,24,595,575,895,413,890,91,54,68,320,74,183,454,64,73,425,493,541,267,419,541,840,906,877,546,427,176,644,729,909,728,917,907,785,322,665,252,561,22,32,22,741,201,48,114,609,999,412,844,589,586,130,365,801,579,701,526,728,868,397,846,993,809,980,317,390,104,912,600,250,917,978,292,879,711,874,658,753,620,259,853,387,792,618,380,197,997,842,261,736,352,70,456,935,355,139,528,100,806,9,901,399,155,667,605,782,904,159,821,573,521,849,637,862,146,178,84,259,568,787,18,120,896,888,113,629,296,290,322,824,907,373,284,980,933,729,715,530,919,140,907,506,420,70,810,770,617,856,850,244,866,879,271,922,658,298,252,909,748,215,943,383,35,345,406,740,302,476,10,201,62,535,721,693,227,450,456,958,984,170,367,198,483,319,8,236,346,631,834,487,317,607,992,278,72,479,316,728,755,978,645,499,34,44,82,330,51,643,657,121,228,196,199,826,645,643,409,533,819,265,994,955,108,873,874,508,660,415,348,483,861,999,31,113,866,480,618,535,309,166,345,659,626,375,309,739,940,483,708,206,322,646,191,524,268,144,304,687,667,29,556,981,6,934,528,637,87,665,200,727,837,681,116,582,556,895,325,987,273,502,789,373,817,437,438,538,5,734,674,951,560,347,725,295,342,410,482,368,100,884,543,246,101,308,225,939,639,557,274,723,299,312,992,993,700,0,608,768,526,530,858,157,502,450,319,152,750,752,722,163,822,105,970,824,766,650,894,860,580,439,798,648,781,145,234,109,281,564,817,157,70,899,217,690,57,218,564,713,974,986,533,407,82,617,911,623,237,706,118,862,722,579,796,484,380,382,247,479,170,246,481,519,613,719,283,945,720,571,7,968,104,725,725,666,162,902,670,982,842,484,457,398,513,992,562,140,334,825,999,865,791,123,240,188,910,610,529,760,339,182,103,687,792,651,660,116,962,539,860,190,858,452,863,231,539,615,446,477,740,323,622,160,931,770,317,895,67,881,555,137,489,75,427,737,556,609,879,482,877,22,760,75,733,633,634,227,248,648,907,253,508,382,933,522,435,27,3,369,440,538,888,272,515,102,623,39,605,398,651,664,893,319,742,878,59,126,421,146,818,416,985,368,999,434,128,658,837,632,64,968,589,959,6,397,185,768,294,492,320,997,297,165,270,914,868,632,100,415,156,22,2,337,411,930,919,119,987,953,743,565,463,348,676,184,33,401,394,856,518,716,803,245,21,138,700,943,148,368,354,409,704,604,892,620,802,708,24,75,204,236,365,465,728,189,260,133,133,411,479,516,332,699,818,797,589,75,94,271,800,29,909,807,715,582,244,634,894,268,269,122,244,327,351,317,503,667,824,543,741,573,691,594,421,681,775,714,194,589,714,311,299,688,770,135,230,810,181,358,995,593,19,150,613,192,173,72,413,566,44,767,716,385,333,120,849,877,283,815,670,244,157,599,776,788,779,903,477,93,815,555,979,322,709,809,485,390,465,693,231,173,762,456,576,732,245,558,685,108,388,317,180,46,863,979,353,32,286,203,559,33,346,375,578,623,75,916,975,677,680,890,410,890,685,571,231,776,752,64,973,513,580,167,915,317,304,30,189,937,644,143,871,32,676,200,504,467,364,825,809,57,48,518,113,545,642,119,250,581,481,919,82,902,693,225,771,790,778,834,760,523,982,153,58,524,565,41,331,696,359,994,914,12,243,902,285,478,375,909,299,561,95,88,393,11,891,110,647,649,334,83,811,659,624,242,487,843,406,554,61,860,518,356,155,348,858,45,425,868,600,482,512,325,413,427,465,621,380,614,237,855,25,852,301,98,511,172,131,421,112,227,835,59,29,616,878,9,986,581,910,768,894,792,626,624,873,216,81,337,468,528,987,90,308,462,877,831,139,507,902,878,725,265,544,34,454,584,745,65,880,246,502,343,138,140,185,790,855,86,775,753,584,173,791,694,211,420,881,650,362,740,641,617,433,955,304,312,421,284,461,345,810,981,821,194,674,891,765,342,691,590,260,47,244,462,168,446,943,53,533,32,239,461,159,502,181,961,949,436,660,555,532,473,600,995,562,761,813,289,836,179,72,251,614,803,890,134,411,905,728,393,90,65,275,420,647,392,723,884,843,37,78,133,37,337,539,496,595,714,169,508,938,346,28,833,529,995,918,257,202,290,523,70,75,970,276,951,341,707,710,5,586,614,6,846,286,101,485,138,276,114,891,752,455,932,817,890,248", "368,407,182,119,683,234,222,911,762,934,654,689,631,124,333,874,650,776,112,43,640,214,742,328,574,524,341,885,770,593,760,941,185,112,442,124,889,4,438,362,897,275,212,654,70,692,994,277,449,948,680,83,760,674,310,116,403,625,146,847,494,998,245,316,717,629,112,702,585,74,741,110,457,421,456,403,518,519,110,462,486,75,143,40,80,650,970,856,384,842,843,646,278,896,133,653,375,70,197,129,591,558,779,954,935,439,241,708,360,321,948,390,952,455,766,55,321,946,885,937,413,775,747,510,422,850,933,294,277,54,889,363,758,120,291,232,593,257,894,437,189,943,15,485,20,343,412,197,24,44,312,981,361,943,857,526,336,770,890,161,41,775,261,78,367,721,73,340,262,158,576,724,284,253,622,170,892,55,529,622,855,533,235,397,638,632,85,502,795,293,521,41,228,799,839,598,354,570,772,89,444,682,286,462,959,768,895,599,246,734,215,984,212,865,890,821,614,594,101,774,779,110,103,906,617,575,998,129,583,785,470,783,650,4,862,518,265,294,129,520,167,643,60,135,615,308,292,150,66,545,505,666,177,541,203,518,317,512,296,188,303,665,160,650,822,197,203,757,736,366,30,259,442,998,166,790,573,723,654,50,133,270,940,368,2,175,422,380,923,185,233,705,163,347,724,548,204,809,885,98,628,210,264,90,244,558,70,562,415,286,835,172,895,221,660,816,981,333,608,0,982,708,138,74,628,102,716,398,601,704,12,118,693,38,835,52,855,811,958,698,392,397,443,705,539,806,782,236,579,652,565,770,569,615,700,972,473,358,364,964,303,326,828,712,799,384,964,255,355,645,65,468,623,317,403,982,802,807,725,16,635,140,143,107,111,216,14,493,549,24,840,608,120,720,92,641,57,894,519,958,86,46,733,375,904,436,567,427,99,341,534,838,238,200,998,296,425,868,880,217,307,941,612,465,551,123,920,707,854,172,662,480,76,993,842,467,793,855,686,633,322,409,936,879,675,788,224,987,416,304,356,810,745,74,126,591,319,891,956,865,729,163,7,326,519,901,547,385,722,59,235,535,518,802,976,553,929,427,143,176,664,732,663,573,133,837,423,656,453,108,980,672,166,183,247,270,104,842,929,958,774,411,624,281,81,268,690,221,370,902,306,614,147,298,936,193,572,305,326,934,579,902,722,721,136,294,725,863,281,150,488,558,1,890,778,33,577,589,732,210,127,464,56,846,211,615,174,628,172,348,820,52,77,63,865,44,901,798,183,560,426,414,753,457,678,311,113,333,702,527,750,500,543,832,122,626,795,498,819,574,611,639,517,508,361,949,370,810,890,939,468,513,612,721,568,93,422,366,927,788,90,602,48,538,800,577,62,228,222,106,561,7,682,426,831,374,824,587,194,625,319,706,481,664,273,35,103,585,675,960,75,471,287,943,880,174,786,708,249,670,840,314,311,505,58,985,233,531,497,752,202,655,547,474,501,806,190,353,266,398,817,87,814,268,725,146,806,253,592,626,262,621,507,521,327,622,367,208,475,722,613,767,582,591,65,837,472,486,518,559,575,321,185,229,358,537,569,144,211,32,571,68,555,992,346,666,87,754,980,978,162,938,417,852,450,642,795,22,7,113,497,197,199,290,233,484,378,401,451,159,875,261,10,491,97,938,353,696,693,171,561,311,535,289,152,501,696,904,802,149,818,741,324,265,430,102,243,953,208,80,963,703,485,577,523,216,968,628,355,763,28,900,467,523,129,141,108,130,158,743,185,719,386,861,451,492,764,502,685,80,92,483,780,207,758,547,557,671,208,975,321,725,266,875,377,542,876,200,474,342,691,575,258,933,291,945,703,769,695,916,280,545,749,122,109,858,951,116,193,757,747,101,456,443,433,592,146,433,310,187,418,597,788,350,612,701,800,996,863,295,560,50,867,264,529,971,645,687,404,71,199,40,464,350,852,6,458,564,574,864,11,516,935,568,519,554,444,586,454,25,314,447,241,482,699,328,880,37,520,758,832,401,110,309,104,7,983,755,563,584,166,249,760,260,888,736,813,893,656,590,525,984,390,821,730,218,632,797,918,712,794,114,203,430,482,223,292,55,859,763,984,963,734,462,650,566,428,677,36,932,390,723,559,573,932,781,498,255,705,190,442,489,918,209,245,901,339,529,740,309,600,69,785,693,819,247,440,149,966,308,494,297,143,68,165,174,54,540,709,272,294,336,466,760,925,235,812,18,484,778,739,213,504,67,646,904,449,21,90,960", "924,486,972,41,954,875,739,21,86,918,653,124,943,609,734,793,671,317,244,51,306,44,6,277,941,669,419,894,238,793,275,48,854,608,979,971,362,917,223,627,330,873,789,28,552,176,932,435,107,427,200,523,476,363,539,438,831,167,610,506,473,534,894,665,610,538,342,883,189,95,936,174,44,318,837,163,240,48,11,369,727,386,638,900,303,590,49,580,996,157,868,113,882,395,487,757,337,623,743,907,206,23,255,625,339,222,256,500,634,156,358,867,338,747,619,989,426,856,953,393,37,154,76,719,509,774,716,500,237,106,640,986,976,192,166,273,24,515,479,424,115,437,324,546,565,221,150,865,694,319,3,769,952,569,182,588,604,528,552,265,65,760,716,147,761,97,887,215,133,383,146,169,832,168,919,520,208,833,830,79,382,171,194,35,67,444,57,326,977,77,131,411,149,740,167,120,707,988,785,860,602,268,186,677,694,28,534,255,970,628,544,169,986,540,7,794,514,824,477,140,648,658,880,628,404,706,757,356,977,639,823,488,573,512,823,697,72,211,955,743,640,112,282,798,430,74,450,406,955,408,521,521,737,386,528,576,83,761,951,325,252,520,351,392,639,873,178,221,872,164,774,649,706,100,937,710,905,919,148,187,149,414,446,145,824,170,492,163,518,622,532,869,76,30,79,566,321,926,859,262,315,107,528,212,837,759,374,517,752,372,349,48,128,438,224,192,996,670,768,982,0,888,15,47,336,318,450,436,350,937,6,202,93,100,871,795,675,766,86,855,969,152,291,927,904,246,465,592,157,381,574,561,254,325,31,324,760,917,5,224,378,162,232,51,323,354,277,10,935,338,44,281,395,534,591,526,753,217,748,137,727,405,434,689,609,541,928,647,562,122,658,197,823,726,828,475,595,863,207,998,66,540,535,599,154,101,69,93,82,213,236,213,396,809,771,748,580,39,243,542,962,894,144,31,269,925,120,513,168,167,397,622,611,60,167,492,310,568,320,66,20,114,448,782,16,784,232,468,558,829,696,582,467,777,749,608,802,299,716,975,162,758,133,756,576,612,404,144,681,618,971,381,121,859,445,837,588,505,686,808,382,799,991,274,389,86,47,186,61,861,386,803,189,3,379,226,535,723,550,89,624,382,52,572,653,399,985,425,63,169,185,273,890,37,410,765,207,731,17,516,773,475,854,259,214,255,2,437,932,289,360,88,562,539,821,179,643,843,202,387,206,879,184,714,49,295,560,975,186,212,970,835,849,211,861,995,104,855,930,933,126,768,310,641,508,854,175,332,56,509,474,34,447,723,256,66,111,39,468,578,964,369,375,117,152,581,15,943,215,779,363,165,504,915,828,669,839,322,535,328,19,334,795,422,894,997,257,614,489,923,763,670,989,979,764,348,39,20,784,319,931,512,206,630,706,148,405,530,395,999,323,929,519,355,73,913,839,160,628,485,530,176,524,743,158,117,93,301,595,938,140,282,272,724,546,428,553,946,298,929,916,36,639,211,853,611,420,83,470,928,714,421,126,491,933,310,261,282,980,439,87,785,883,478,560,754,200,656,339,669,224,234,184,974,435,354,935,118,214,277,513,196,36,810,630,973,505,483,803,576,354,581,269,672,587,614,727,638,493,292,221,348,887,88,717,717,196,758,5,665,776,925,113,819,59,127,853,22,375,43,313,579,384,657,322,793,346,961,972,743,371,869,767,948,627,577,977,523,295,448,2,648,531,929,59,38,246,298,924,540,33,453,740,452,125,592,389,450,231,246,858,54,210,193,654,792,339,930,559,232,991,756,395,199,168,891,828,456,315,562,621,553,297,168,541,362,382,742,763,194,574,393,688,854,307,236,229,441,925,781,798,725,56,872,784,997,847,73,175,297,32,498,286,913,452,597,428,589,579,369,795,541,719,524,777,734,929,35,914,815,928,523,80,476,827,685,332,404,407,861,573,801,592,453,808,718,917,532,293,795,443,175,574,360,346,370,777,818,693,195,972,609,867,9,497,479,238,323,919,961,448,249,515,583,957,23,41,971,119,42,327,4,597,200,398,755,293,962,65,372,811,13,933,254,161,820,484,107,23,314,915,214,599,686,355,578,382,802,396,516,132,834,251,246,824,541,518,345,92,862,721,243,238,711,359,349,440,669,277,661,965,122,72,410,495,428,870,176,541,9,744,669,716,520,223,584,886,278,262,720,367,581,871,403,972,414,645,340,317,922,686,893,894,116,841,29,830,62,323,892,257,1000,482,942,308,111,774,819,537,639", "108,681,469,486,325,264,438,306,788,362,725,95,801,54,948,50,435,127,862,654,439,637,459,228,564,865,651,869,243,777,212,115,944,201,240,598,948,295,228,158,305,128,501,225,866,825,850,96,817,170,102,892,569,171,568,332,802,716,806,452,893,143,808,64,564,552,783,126,897,940,971,812,987,688,687,195,508,58,507,618,877,7,821,310,165,837,172,360,181,943,328,82,448,667,621,440,76,433,171,100,113,589,287,2,300,302,576,48,27,352,375,541,987,695,314,642,518,837,662,829,969,476,903,424,483,423,996,967,590,906,512,466,25,510,367,953,366,895,749,775,535,876,358,325,882,224,965,495,24,288,851,465,165,954,801,97,290,788,278,595,223,768,499,276,965,685,419,803,158,260,427,426,656,724,20,868,437,275,770,465,606,259,576,984,144,895,887,548,599,115,379,175,377,717,835,743,311,396,106,826,98,238,771,546,951,527,423,132,822,38,22,396,471,19,617,480,661,746,216,351,224,996,592,819,24,563,844,990,697,99,947,635,522,288,619,249,99,347,274,230,451,716,938,747,539,723,439,730,456,677,852,267,832,239,801,893,206,850,953,317,191,447,883,280,854,730,974,4,15,882,676,556,989,631,193,795,620,538,216,656,259,32,551,561,99,546,750,8,37,787,100,763,863,60,316,625,952,26,622,961,274,578,392,495,509,559,648,166,436,378,46,727,736,80,41,293,405,44,526,708,888,0,939,186,442,295,385,675,285,723,439,183,491,230,216,972,941,185,41,263,265,583,483,825,618,227,858,329,430,946,515,130,952,404,332,30,219,58,988,18,897,638,364,789,979,934,570,952,241,930,460,502,593,731,992,974,811,400,611,538,610,928,110,108,143,694,278,917,333,7,798,337,481,582,617,497,992,372,960,712,749,248,656,997,707,898,30,692,603,866,424,118,786,361,20,988,135,311,757,513,417,839,326,716,741,951,201,564,562,5,319,101,186,500,391,183,620,557,134,54,905,830,777,571,706,322,949,46,234,773,702,516,64,442,294,340,507,706,755,190,621,357,44,971,709,766,481,208,591,545,612,536,168,153,603,210,522,343,300,104,919,276,885,695,664,796,298,77,662,22,155,198,692,199,746,810,790,537,66,570,736,27,682,491,735,550,135,253,668,178,988,974,664,796,538,492,996,540,662,801,592,975,137,404,354,875,446,900,947,234,18,646,290,982,223,548,594,946,806,17,937,220,259,549,196,449,491,12,387,965,504,928,232,901,692,459,589,48,812,769,397,654,586,499,528,621,973,508,270,169,774,515,548,254,115,900,48,656,501,180,815,313,149,503,32,413,160,468,582,179,189,402,971,158,811,373,562,445,138,611,147,138,740,440,725,122,463,948,531,108,978,921,58,941,445,579,430,666,65,954,114,998,120,617,777,655,878,274,559,628,883,45,287,514,415,181,73,620,507,93,880,559,435,605,30,899,936,306,629,52,17,524,294,378,531,163,491,733,139,275,91,94,557,182,703,35,588,78,372,357,727,29,197,593,470,736,272,990,378,106,145,526,300,789,791,167,686,635,482,858,13,334,71,572,416,5,66,894,784,679,201,710,738,425,905,29,801,194,146,33,968,94,81,403,457,723,730,769,558,172,336,292,359,825,313,359,530,248,21,476,732,25,196,12,539,609,202,486,691,947,78,989,20,323,617,516,718,601,348,286,166,644,696,22,464,186,548,759,653,125,408,91,2,169,701,548,741,304,262,792,724,553,210,18,696,442,913,488,590,136,355,979,705,864,348,181,973,959,240,499,355,637,462,824,447,365,653,367,253,117,537,363,377,2,746,627,459,394,822,530,507,322,278,507,936,343,759,520,93,711,418,791,456,764,575,597,428,988,86,731,867,840,895,321,727,184,193,820,149,88,968,980,412,854,727,349,584,272,895,555,90,860,436,398,868,199,434,879,681,756,811,872,55,950,723,816,837,448,870,693,472,259,367,459,341,119,384,768,991,117,817,652,169,513,393,432,342,360,133,906,548,712,116,435,422,576,509,415,20,651,306,835,537,737,674,35,16,970,45,19,747,193,367,683,832,101,947,357,427,967,125,421,937,12,500,14,361,555,162,208,735,198,977,449,946,530,461,370,134,824,591,344,437,781,95,760,767,214,298,966,801,445,248,419,387,683,851,488,278,751,680,566,730,606,725,73,104,644,52,439,436,648,951,190,694,764,353,834,440,895,397,419,497,206,197,264,141,442,101,612,664,911,808,437,820,114,294,519,414,524", "276,293,986,869,619,620,40,600,359,35,385,512,687,846,47,454,583,6,733,700,39,422,245,688,626,231,363,959,719,636,943,548,532,205,860,352,130,791,724,363,939,57,326,632,472,270,507,955,568,5,123,217,860,808,925,158,221,775,511,104,400,229,629,825,350,731,828,45,747,859,911,278,674,215,202,81,660,190,437,561,454,659,581,775,927,594,730,928,20,66,551,555,186,809,842,725,555,407,882,698,319,358,903,751,326,228,994,156,307,625,493,146,97,826,626,827,220,124,326,994,333,789,934,32,843,927,117,640,181,899,759,729,717,211,687,498,489,725,94,833,524,291,730,205,947,304,543,172,781,441,570,776,875,126,943,286,864,517,78,473,683,304,775,914,80,587,270,177,374,762,617,3,669,361,432,472,450,452,425,15,29,583,742,972,686,495,597,957,122,595,803,972,491,884,271,290,201,557,73,697,949,268,650,128,543,667,372,100,806,465,884,355,361,377,775,436,258,95,49,983,131,851,232,354,825,727,232,21,486,711,742,259,249,752,84,741,220,723,717,210,529,934,39,940,255,64,89,455,344,988,818,268,845,752,941,143,344,55,513,590,284,457,564,967,205,149,77,867,826,441,562,928,203,42,182,215,919,45,261,388,604,37,827,178,503,957,258,931,257,789,565,940,905,561,486,47,714,836,511,696,397,648,863,738,976,936,508,138,104,181,943,302,985,976,760,77,309,430,530,138,15,939,0,193,327,808,279,821,160,356,455,465,489,63,773,525,836,960,19,546,142,626,28,935,927,665,75,244,81,574,225,307,221,689,527,678,44,740,259,268,630,336,382,350,619,234,838,299,807,82,6,428,474,485,132,104,958,327,863,839,595,82,206,20,594,296,428,583,686,224,792,752,892,857,647,535,466,619,985,292,214,179,405,154,216,446,895,259,199,131,597,615,764,831,985,370,388,625,697,968,920,341,544,508,849,255,614,550,410,12,583,641,137,980,269,440,577,846,82,512,721,876,946,405,95,653,260,220,989,565,927,46,822,9,576,123,448,811,943,425,701,583,639,870,672,582,871,81,190,418,142,976,545,963,664,954,510,385,717,403,862,67,847,908,75,93,821,533,771,608,575,442,598,108,716,52,407,532,87,35,558,447,359,441,643,219,452,682,548,687,887,391,412,12,968,567,878,886,916,633,810,723,847,75,216,685,946,4,88,530,482,733,418,164,925,656,480,400,551,494,103,13,626,993,626,685,931,606,63,472,589,176,558,502,871,870,236,940,492,462,825,729,731,234,173,716,922,612,721,304,396,930,388,621,692,335,627,699,757,811,920,766,127,415,919,235,121,385,660,308,739,848,243,174,496,297,405,555,465,65,321,90,799,81,686,944,437,833,877,79,581,891,636,317,182,520,921,315,562,945,938,268,132,251,194,940,917,914,146,317,241,799,52,780,609,281,838,465,136,738,249,722,339,192,481,870,211,193,979,623,427,962,417,602,251,422,574,585,962,968,487,340,721,610,150,809,33,413,90,388,402,554,371,840,565,971,714,241,894,301,220,76,877,639,289,60,894,248,147,645,224,528,906,476,830,972,59,14,648,871,643,664,875,829,545,634,830,490,344,501,623,213,112,327,943,402,397,545,595,959,410,91,138,654,67,409,173,852,982,472,665,368,887,786,698,502,824,393,528,505,797,510,370,721,206,160,318,693,594,321,174,857,413,746,253,690,992,355,209,776,741,34,965,775,897,655,294,646,3,129,672,370,774,87,266,933,998,839,482,659,925,118,896,218,737,949,566,27,891,935,235,201,557,172,236,620,951,692,723,198,217,813,291,281,433,489,425,632,540,158,400,52,21,951,18,783,329,359,666,382,40,623,683,701,680,206,472,127,865,435,354,238,523,209,651,475,925,45,840,297,479,62,305,891,884,979,867,931,836,947,715,331,713,456,934,745,975,77,382,369,805,679,687,173,544,538,68,774,254,13,244,903,477,204,419,66,577,409,733,417,741,805,940,696,675,763,191,958,325,492,515,10,917,535,543,77,346,378,343,883,122,462,971,308,2,339,222,555,637,562,92,134,747,9,486,50,312,904,572,54,425,668,526,516,231,127,142,105,8,380,392,185,766,616,807,747,375,827,102,716,177,72,293,562,851,809,579,805,376,966,693,606,587,639,456,691,965,355,843,599,916,671,653,664,780,143,741,418,111,322,352,908,553,283,796,14,500,322,960,580,601,833,655,886,118,145,114,772,390,581,271,645,195,556,376,529,900,784,512,876", "472,515,770,298,544,608,256,683,82,509,85,100,314,348,133,780,252,260,905,57,63,334,147,665,76,988,705,473,619,815,673,905,121,716,632,309,493,105,288,263,598,739,374,259,33,716,244,947,439,253,112,748,972,202,176,37,313,63,147,132,916,55,270,118,246,675,448,927,697,382,955,93,165,841,162,135,31,905,262,132,606,281,684,680,770,478,951,893,351,140,462,163,242,125,828,438,348,219,945,669,578,227,913,911,394,199,417,100,69,706,118,519,910,600,27,994,428,810,300,869,958,946,31,676,763,644,867,867,948,434,946,953,204,731,355,225,994,682,855,536,217,28,374,514,978,451,387,107,776,319,684,461,207,209,795,1000,786,860,907,822,945,104,263,718,913,820,27,253,798,253,722,183,397,356,960,250,444,104,251,55,502,781,983,99,58,637,924,777,857,65,712,603,900,198,185,840,675,677,571,566,650,377,79,685,732,703,813,623,75,613,959,293,90,701,328,423,942,490,745,15,581,229,97,432,825,735,716,99,838,601,778,872,315,53,708,968,560,68,658,900,982,446,142,186,262,414,883,499,816,177,688,119,453,545,278,367,821,748,680,413,965,137,760,236,465,466,112,95,928,949,538,120,118,842,499,962,79,712,280,664,641,293,832,192,604,881,178,770,231,871,688,939,898,675,263,391,649,179,857,939,878,442,120,101,656,728,770,469,922,176,649,779,430,361,299,336,967,69,858,74,47,186,193,0,63,796,469,753,449,934,549,720,558,272,428,253,212,380,808,304,560,678,978,668,777,386,678,465,890,242,624,629,328,562,459,952,203,695,621,482,771,230,84,361,255,598,926,864,159,122,21,278,639,970,153,180,854,255,813,44,843,951,81,536,364,727,854,203,92,702,653,683,828,950,547,771,892,947,693,668,95,688,218,994,17,302,226,207,996,941,184,131,637,958,793,159,154,187,351,228,978,356,231,145,166,269,754,122,219,709,620,473,856,976,820,407,628,221,350,126,436,612,529,822,848,83,781,147,257,734,77,11,373,544,355,114,599,379,273,155,56,440,601,373,164,304,301,174,240,198,634,543,74,319,112,821,550,963,638,851,42,220,43,516,843,659,795,260,485,882,857,594,887,339,801,979,221,108,353,139,7,371,447,308,195,319,57,215,978,318,165,859,284,866,524,551,171,428,918,190,640,470,811,279,316,204,685,958,826,565,205,658,432,751,939,275,961,889,447,71,401,18,270,713,160,668,727,883,878,228,881,825,660,622,782,698,440,786,987,815,271,491,449,386,567,591,843,278,463,515,864,402,921,821,825,7,832,739,362,201,651,794,20,352,609,998,198,358,156,422,854,953,563,254,457,537,337,349,785,683,754,716,229,439,815,740,106,228,952,476,357,79,79,790,776,791,76,768,370,369,101,243,153,593,842,351,903,112,160,78,92,96,364,3,530,442,237,512,351,65,83,588,393,739,81,567,896,977,230,709,568,827,445,917,326,773,189,735,157,310,786,782,236,3,326,490,848,905,231,535,9,170,31,679,481,22,278,175,46,278,619,138,39,466,102,280,231,890,160,325,138,501,939,424,751,946,182,410,337,348,249,849,127,17,393,285,715,638,285,306,321,366,221,464,629,452,914,661,674,191,342,849,979,318,733,436,732,941,310,379,68,8,189,989,23,899,280,862,590,721,692,298,403,126,466,499,674,163,514,652,556,685,870,460,801,545,369,209,212,517,20,450,582,669,186,470,77,218,328,199,276,445,85,716,565,702,615,628,415,312,624,498,535,186,383,116,285,456,938,155,239,603,321,385,34,60,609,516,864,564,779,611,638,394,702,491,934,549,354,108,269,230,371,123,430,574,896,637,192,332,840,157,265,297,236,677,994,16,980,449,98,721,714,556,374,89,866,558,510,975,631,394,322,138,386,504,550,45,406,2,979,134,852,528,640,424,294,562,608,588,960,551,376,419,901,409,618,969,525,187,978,635,309,54,700,975,480,359,26,676,18,93,319,673,561,87,690,69,449,922,880,615,1000,683,94,566,67,903,16,299,940,429,825,992,516,453,914,918,772,359,69,354,270,973,355,490,814,847,981,34,364,495,316,181,773,300,117,869,473,811,398,163,545,851,952,603,361,71,908,982,219,700,787,446,138,65,711,27,904,487,496,875,264,742,536,392,723,551,952,662,933,520,18,187,991,442,187,438,660,91,6,203,20,495,956,820,494,740,989,342,827,146,92,65,847,496,440,339,270,974,617,540,789,327,118,692,265,311,869,993", "469,590,12,149,66,952,939,155,499,326,119,672,692,389,333,958,809,476,315,255,299,296,72,145,40,607,170,499,597,936,167,568,406,371,620,1,443,674,632,399,56,201,934,478,715,643,356,5,440,268,161,466,882,77,110,918,133,717,485,972,668,340,660,448,850,693,605,977,928,802,107,258,767,233,132,133,597,676,762,430,181,650,451,192,413,423,456,342,429,644,702,600,526,22,966,753,44,408,427,417,811,788,19,204,6,967,478,911,792,490,857,168,124,545,664,738,786,416,770,939,946,437,737,256,68,201,822,470,603,429,211,596,960,368,246,254,588,303,114,265,981,533,255,720,93,27,975,274,407,81,874,433,386,364,720,593,168,284,332,930,4,86,144,120,512,995,788,821,532,612,572,374,268,195,678,867,647,400,726,543,709,236,197,589,631,402,469,375,48,676,443,346,404,207,716,548,137,700,449,794,661,845,324,65,237,520,831,840,352,522,534,827,219,77,863,266,164,75,443,816,248,992,62,414,734,360,744,956,854,694,108,704,668,447,386,332,837,894,715,224,491,741,364,357,906,20,820,506,895,342,404,224,661,797,401,298,545,799,556,574,535,315,22,915,399,541,390,919,801,375,651,86,287,948,909,156,563,223,392,211,643,348,593,844,627,345,479,688,45,943,955,997,412,129,35,76,929,837,73,962,853,402,6,853,813,18,11,874,247,608,390,164,396,764,388,691,172,869,157,628,336,442,327,63,0,975,825,652,194,391,773,609,595,744,127,204,663,944,917,486,376,549,740,295,832,414,163,842,13,399,960,868,558,61,600,803,542,512,177,864,330,214,421,514,501,780,859,761,357,548,476,299,248,691,100,26,260,125,800,47,919,803,137,520,139,97,454,533,837,755,957,784,81,779,465,494,937,28,290,985,292,405,630,362,245,797,527,673,85,546,702,505,696,103,605,802,430,149,422,220,498,654,803,764,926,969,577,762,766,478,123,872,569,559,6,817,126,623,994,85,295,135,544,845,754,230,984,101,632,114,718,906,21,307,491,553,288,444,842,124,962,424,743,512,322,374,359,955,284,194,383,257,418,164,955,868,496,826,919,893,855,55,454,713,274,86,972,601,227,55,369,490,886,490,266,756,559,65,886,727,61,700,147,87,915,783,795,295,831,123,208,981,423,26,550,921,804,92,904,14,527,920,413,676,855,423,972,452,675,566,961,991,554,26,758,799,93,739,736,881,824,393,334,957,873,453,647,356,157,220,112,519,316,972,884,38,849,30,266,267,228,278,681,919,511,451,210,794,445,262,900,664,801,863,386,416,162,623,171,856,812,36,864,710,151,924,508,234,795,496,497,814,503,195,347,792,11,681,698,330,715,962,285,249,222,279,302,551,914,160,495,579,102,868,29,462,148,456,254,727,13,65,521,697,114,736,163,645,444,316,17,438,299,775,567,77,218,911,614,287,107,431,266,908,574,714,408,215,118,938,177,448,733,634,555,945,718,909,349,436,120,673,263,36,773,541,30,519,683,376,670,443,490,433,944,154,62,915,437,735,678,974,86,333,487,188,508,567,179,520,681,500,448,382,791,303,728,717,320,432,642,309,251,410,154,936,541,228,968,594,845,306,288,722,259,152,549,842,341,157,514,923,559,343,901,456,72,599,85,853,769,558,416,467,318,703,568,409,313,706,982,259,279,71,333,513,708,593,508,503,40,159,15,858,978,394,655,955,154,631,407,708,706,506,280,84,893,584,809,443,65,666,387,807,924,677,485,789,94,39,322,60,880,70,527,229,988,354,761,601,71,692,461,264,911,648,887,986,962,816,396,153,959,915,131,121,862,319,486,682,44,155,138,605,444,832,342,222,965,781,841,573,842,750,546,624,699,890,751,977,181,668,958,981,445,770,907,170,599,20,409,826,543,154,151,567,285,571,5,349,580,474,384,771,557,579,128,985,527,223,73,331,470,965,911,23,723,681,599,671,994,153,844,721,456,820,384,694,704,195,210,642,544,963,245,537,378,241,805,203,867,405,1,215,337,939,596,414,758,747,754,461,780,597,961,273,483,354,905,500,253,890,65,38,355,82,542,160,268,348,408,886,825,648,782,229,561,722,56,790,845,763,748,293,342,425,96,821,54,393,147,112,873,814,597,840,139,958,789,181,646,657,388,366,502,568,139,888,668,702,723,647,620,989,62,836,62,850,332,908,520,269,480,18,800,190,891,835,763,81,539,930,983,408,363,707,236,478,5,307,537,394,200,755,563,635,423,678,974,791", "704,497,700,310,607,510,377,219,954,231,952,142,872,134,914,343,321,86,942,775,865,980,51,746,338,930,792,683,3,427,417,768,922,448,52,638,155,189,960,776,559,995,678,189,1000,71,695,303,509,328,395,10,725,543,957,397,806,951,6,934,409,687,884,106,815,76,956,525,553,818,59,439,44,744,861,111,656,946,682,717,215,112,273,972,147,628,274,994,554,824,206,198,790,572,553,496,933,658,231,314,507,150,23,493,418,677,843,617,960,502,99,273,979,170,545,301,898,450,250,62,370,204,56,453,957,946,816,101,851,521,92,269,329,413,140,320,403,215,458,54,679,715,9,840,883,295,127,250,609,486,998,794,639,48,205,776,13,679,975,662,338,314,864,398,231,287,106,544,555,30,873,169,977,536,41,776,5,824,498,214,619,338,177,706,584,329,213,657,95,175,106,20,687,262,114,14,540,148,995,554,830,202,713,675,907,737,452,245,173,825,608,185,223,746,714,934,6,522,681,877,440,755,635,334,500,439,352,404,114,631,716,260,575,360,179,516,516,236,966,452,244,55,871,739,278,674,455,793,14,912,466,520,578,824,180,313,744,376,7,688,7,10,609,792,157,850,632,709,232,8,477,779,866,81,147,530,882,853,899,794,260,724,297,518,244,573,237,787,402,37,803,198,36,106,251,982,376,375,283,118,300,757,379,13,826,327,800,42,582,949,379,991,89,518,299,481,393,645,502,102,318,295,808,796,975,0,70,172,92,519,640,398,759,674,133,701,729,781,413,792,280,334,710,451,87,734,130,203,719,30,393,107,147,936,822,754,857,187,701,377,244,742,274,697,294,324,442,561,404,950,232,420,841,107,479,572,888,328,824,920,850,824,338,349,869,273,607,78,823,607,553,642,601,494,253,766,215,623,251,240,336,908,258,818,618,894,647,977,239,719,528,791,752,903,56,88,427,918,318,89,626,34,992,357,740,491,214,210,78,480,420,447,666,26,25,729,425,893,368,624,463,530,411,707,962,879,532,242,874,347,303,681,353,352,871,51,914,658,35,674,487,235,391,21,939,867,773,400,244,186,391,582,727,746,737,309,52,883,588,414,16,950,359,962,212,198,481,963,983,876,284,21,321,322,486,412,15,383,525,756,228,577,533,411,669,859,144,750,440,583,587,47,919,645,53,448,171,572,826,608,167,144,473,352,426,793,912,995,958,88,15,404,694,64,349,494,535,246,570,839,497,889,104,162,942,197,431,896,951,242,630,869,599,155,192,380,647,341,887,155,158,200,498,517,696,916,718,472,39,596,933,378,955,952,562,966,48,252,978,170,327,946,77,323,105,174,755,473,400,98,211,571,622,663,216,603,516,610,985,613,630,418,375,300,586,246,990,22,200,434,266,41,535,763,410,30,104,930,269,877,811,676,821,687,661,826,550,939,646,804,738,101,705,973,273,21,731,188,742,674,515,4,38,482,371,167,280,243,214,891,788,943,72,389,222,59,344,769,490,330,768,403,5,989,459,551,352,808,956,284,886,323,185,423,933,601,135,45,483,368,742,276,739,40,560,360,258,242,383,457,370,605,368,829,852,495,953,723,886,689,743,285,698,278,247,330,894,749,55,191,774,866,128,600,87,509,327,203,808,661,368,840,789,956,470,502,187,486,950,563,332,703,499,980,894,517,845,565,977,730,36,662,257,101,980,545,751,99,483,323,143,1,338,681,546,83,418,502,327,154,778,986,727,843,392,542,281,975,400,871,48,881,379,758,392,974,971,267,189,473,440,213,168,290,493,63,329,954,314,271,964,899,996,368,285,57,258,96,687,230,609,969,512,542,558,920,66,438,128,709,149,578,5,456,72,43,286,979,566,814,214,557,735,934,713,881,818,440,428,81,794,873,877,541,176,947,226,702,760,641,654,55,112,897,226,635,924,880,975,735,117,61,366,878,904,262,919,781,597,930,977,457,449,2,651,932,852,286,232,15,759,938,611,318,583,820,51,774,91,928,426,3,308,63,978,178,406,329,586,689,744,377,55,617,951,446,294,436,56,238,16,525,69,237,905,78,777,559,247,351,226,960,453,826,25,216,658,308,288,964,722,516,148,290,942,969,901,748,123,397,863,770,304,781,348,337,800,793,360,871,174,467,59,325,305,838,423,131,418,502,340,334,882,822,181,39,999,441,853,366,571,118,659,489,843,142,353,555,914,460,291,345,269,10,454,111,502,417,201,784,955,39,767,412,706,112,922,621,729,725,98,504,516,46,817,236,541,536,956,460", "92,657,977,350,614,256,256,280,120,284,38,650,406,686,393,247,931,503,371,735,147,238,538,991,251,36,887,729,330,309,936,651,77,893,827,190,863,971,732,951,916,176,84,240,899,241,70,832,196,151,126,654,778,889,377,712,492,480,699,438,57,460,365,945,181,831,439,240,834,50,728,645,544,289,54,175,955,779,82,447,914,462,989,40,900,485,784,718,925,744,28,802,50,794,268,952,55,815,988,70,663,292,39,606,316,328,880,953,665,930,122,287,130,372,227,733,984,133,506,464,394,465,208,993,735,436,609,439,57,374,329,45,366,303,340,968,624,207,993,687,11,393,144,614,25,332,264,143,677,906,948,466,972,859,155,484,85,960,251,105,444,195,271,40,684,399,848,827,542,875,155,74,679,897,438,664,988,372,187,647,530,327,645,65,821,958,329,794,336,545,23,839,443,209,813,664,121,426,653,426,45,99,857,977,802,525,569,825,549,555,459,900,382,343,718,546,115,380,410,556,57,360,237,795,615,161,60,648,25,717,153,25,587,629,168,555,684,606,537,531,143,360,33,635,111,515,725,91,911,837,698,782,897,332,866,484,357,74,622,257,151,811,817,289,682,227,617,809,318,240,184,996,705,600,737,220,508,359,901,154,830,273,733,868,982,576,401,341,364,403,871,492,394,303,346,17,218,669,358,740,370,702,783,251,166,660,43,851,785,452,897,886,58,842,928,495,914,455,450,716,450,385,279,469,825,70,0,846,801,49,241,47,28,320,274,641,715,457,900,588,795,488,827,409,410,400,176,778,142,471,899,819,505,625,597,548,121,452,148,237,664,646,267,3,108,167,433,367,442,358,974,753,97,778,375,846,984,847,978,307,569,751,603,85,728,322,58,649,365,798,570,868,763,61,947,811,460,942,493,344,487,438,36,749,915,948,856,252,579,293,113,23,799,473,979,603,972,38,63,959,171,230,189,686,917,578,97,619,428,109,111,303,949,508,861,162,249,799,939,361,799,600,358,161,723,537,378,257,23,836,56,768,67,62,814,787,940,933,590,188,842,951,22,242,903,995,910,76,674,124,562,679,304,503,98,978,805,417,651,977,629,526,56,979,923,719,900,180,262,447,54,769,659,355,668,71,648,920,262,398,767,669,982,262,955,574,334,502,256,572,890,782,632,74,301,760,111,193,372,76,138,847,443,884,284,550,348,842,169,1,542,544,723,73,779,214,989,982,787,129,272,257,829,760,349,190,362,468,47,940,341,492,533,288,794,236,755,820,591,892,69,523,626,113,439,162,187,193,761,909,859,198,394,256,555,622,364,988,194,792,348,326,750,642,22,378,482,970,253,70,809,819,244,571,348,821,778,830,400,524,676,718,636,497,571,165,48,538,163,575,655,650,186,784,133,635,275,884,8,826,28,86,898,576,657,904,106,364,143,4,467,862,581,881,837,863,411,131,176,704,586,489,117,965,517,188,776,620,223,110,426,975,638,417,850,97,487,720,939,75,232,853,189,508,646,675,370,171,171,922,498,848,881,478,201,366,309,395,394,21,65,412,241,986,950,388,663,460,76,776,692,241,318,782,919,352,942,183,892,567,200,578,426,526,723,498,488,597,167,1000,889,297,381,819,642,412,199,820,325,75,203,472,376,630,58,846,381,297,342,411,721,222,629,42,767,381,157,556,605,436,307,611,132,889,93,153,89,201,767,662,289,531,233,894,456,969,778,625,873,187,950,639,729,516,324,693,646,917,846,688,32,109,455,375,932,396,895,280,854,183,153,419,7,739,807,242,566,905,690,999,833,121,853,771,920,808,242,33,788,828,482,702,228,240,402,161,30,190,751,129,159,611,587,296,842,744,138,278,677,823,61,728,375,551,29,415,121,256,872,849,303,89,470,214,811,437,430,298,291,221,101,12,202,21,981,927,922,613,100,15,480,348,662,935,188,576,851,96,202,682,206,288,514,834,564,180,439,658,480,622,800,525,760,491,220,707,508,701,150,215,315,678,912,5,992,328,372,922,614,710,827,940,974,70,459,101,416,302,491,886,74,942,429,38,331,522,730,919,489,870,411,388,706,839,776,86,186,692,955,881,488,917,721,869,129,808,482,975,365,646,562,875,178,307,188,339,721,53,253,46,761,267,54,412,461,636,112,132,243,386,933,341,178,399,376,977,706,896,869,865,140,360,145,637,6,934,803,271,430,48,841,260,16,503,287,276,907,245,33,917,798,15,867,261,632,766,420,499,674,992,999,63,625,465,698,761,204,79,719,136", "680,130,216,146,236,966,512,959,843,753,817,243,647,913,496,313,473,831,961,355,696,467,737,984,501,384,621,884,825,218,424,582,571,117,569,449,116,434,626,324,737,752,943,705,816,974,62,622,224,349,584,932,997,934,521,651,522,279,213,501,437,410,718,864,230,734,564,499,822,65,760,806,126,442,957,930,746,540,777,104,158,4,63,551,320,85,905,861,348,102,133,137,267,711,308,440,108,229,564,839,818,887,537,178,655,621,905,494,632,776,63,287,785,783,6,204,179,317,939,186,2,329,398,230,545,328,67,947,547,810,216,656,509,70,337,254,73,597,988,200,499,456,206,165,375,918,106,357,544,217,597,798,759,474,774,605,785,430,218,616,927,589,468,108,354,956,23,81,80,535,892,75,273,191,217,107,958,934,876,408,66,806,776,894,805,917,99,794,39,501,452,5,154,866,8,928,682,401,472,830,441,852,792,985,456,841,666,604,142,499,250,322,928,142,713,582,476,997,561,953,666,946,149,169,1,291,81,579,228,234,66,976,696,19,959,674,5,762,551,771,960,965,539,328,229,481,53,598,17,291,228,560,47,960,610,74,295,771,936,737,856,804,813,458,141,408,655,347,725,441,12,94,644,666,484,323,506,410,105,685,264,224,946,446,964,199,322,975,318,537,503,369,613,140,498,533,759,20,752,257,635,557,987,466,886,683,28,286,229,234,926,847,574,335,759,522,30,667,319,398,436,675,821,753,652,172,846,0,463,42,186,57,601,795,622,651,6,88,977,505,983,305,596,982,728,228,597,475,878,348,930,559,592,484,653,525,667,670,198,301,791,639,103,508,434,420,368,839,701,492,375,884,391,366,899,882,559,670,756,260,113,111,816,879,667,280,643,980,289,339,26,680,455,56,456,47,639,205,610,893,278,80,510,294,899,253,661,132,653,41,869,96,522,402,554,968,429,731,571,917,625,359,233,39,921,568,265,89,970,708,789,809,741,14,253,584,872,366,454,544,59,914,349,217,994,85,672,33,573,964,179,462,585,968,260,804,404,504,103,214,313,741,944,572,87,134,295,851,626,628,432,688,162,400,377,219,986,553,140,759,495,181,954,753,90,788,253,291,627,641,957,265,282,676,814,445,657,801,173,616,784,834,447,213,441,1,70,599,970,995,71,851,152,623,987,876,536,70,694,469,47,834,284,114,505,392,639,80,658,523,60,497,806,124,194,348,787,908,91,518,783,188,235,159,128,160,935,603,739,230,526,754,729,96,427,860,303,667,240,97,49,387,162,663,360,600,441,760,125,454,672,958,188,643,461,5,476,241,371,412,892,654,931,543,897,970,756,174,821,203,117,348,781,665,40,799,585,908,956,571,269,82,561,106,263,370,456,426,320,539,90,448,45,912,50,671,541,636,771,956,596,891,127,899,576,690,955,974,567,107,187,401,950,718,161,769,579,86,802,809,226,823,932,83,618,806,919,829,578,403,181,40,508,803,256,521,56,125,379,370,914,769,777,214,207,214,150,885,38,681,318,557,868,701,898,83,844,176,545,475,800,315,454,971,589,916,736,874,297,840,178,944,379,755,498,371,178,959,618,705,626,136,427,886,864,635,85,672,241,754,312,66,48,632,415,274,59,730,192,266,488,546,370,228,128,153,203,627,55,88,866,70,863,142,403,174,866,462,962,321,412,945,653,377,653,241,486,243,158,16,738,419,306,653,894,265,143,65,705,737,403,590,935,188,987,902,222,241,420,897,944,276,492,451,944,532,433,78,781,747,734,521,518,234,15,636,607,112,240,316,303,503,600,973,393,460,334,913,256,793,419,399,581,987,425,953,888,168,356,113,908,606,426,607,353,266,150,319,93,708,77,64,568,429,378,403,851,47,691,520,565,99,624,552,874,132,741,189,150,742,932,915,236,618,134,360,146,831,842,116,378,52,494,815,262,169,505,336,254,387,382,227,419,428,777,51,720,921,35,96,881,852,154,719,322,918,787,30,204,186,879,841,755,235,415,783,891,190,71,361,770,501,682,924,758,133,985,890,957,179,372,792,698,280,365,350,896,849,190,149,355,904,24,428,807,272,28,108,255,727,435,757,767,55,751,31,727,234,982,587,762,371,495,89,721,904,891,381,244,23,118,665,518,78,906,38,558,536,661,281,396,250,569,694,944,213,379,639,221,270,928,730,921,185,618,237,935,135,292,367,40,579,846,759,638,361,427,890,975,377,792,438,202,917,434,484,284,835,205,239,635,750,468,411,340,25,50,250,282,83", "374,680,324,568,324,191,335,67,213,833,466,104,143,262,894,567,881,271,881,200,917,290,674,629,410,247,743,902,232,149,391,808,113,704,388,534,966,930,379,775,484,863,38,768,371,881,397,944,229,164,800,73,339,419,506,306,543,425,343,628,426,468,304,32,554,680,439,145,28,101,986,12,200,721,215,329,853,977,548,126,133,111,649,718,831,290,915,3,514,750,859,661,215,71,311,414,125,76,813,429,16,572,676,134,660,931,728,483,426,524,652,216,758,985,456,887,221,71,872,465,448,706,618,800,153,305,52,604,866,474,148,590,124,591,157,79,718,180,350,972,694,129,148,466,441,303,853,361,275,469,240,922,246,205,925,298,767,2,669,469,284,133,732,326,489,350,352,878,494,214,464,559,756,931,266,581,244,482,745,128,350,903,625,7,147,918,151,751,280,374,804,695,292,82,839,643,107,85,810,135,983,900,348,93,847,689,148,497,60,538,359,779,452,931,654,88,10,895,803,379,698,866,833,229,659,969,944,352,176,289,143,400,295,341,558,968,733,337,975,587,438,211,260,903,710,488,103,654,641,671,17,580,437,229,301,844,161,144,433,603,757,705,593,542,16,94,72,673,587,932,86,701,561,190,643,9,168,657,393,435,549,136,23,62,298,605,8,427,952,893,826,156,128,551,151,275,66,442,938,958,341,37,494,233,960,21,741,351,418,668,380,488,858,915,932,54,581,707,152,601,350,285,160,449,194,92,801,463,0,893,782,197,133,26,969,803,636,13,927,975,112,802,801,9,435,832,845,267,158,535,766,600,649,392,528,428,857,697,290,244,609,752,346,100,348,986,712,367,152,824,327,767,191,895,858,705,388,520,688,122,999,934,137,535,373,166,52,457,779,904,776,202,866,979,199,115,998,836,309,633,341,814,917,664,549,548,662,492,157,32,633,152,4,928,90,594,294,597,688,656,774,650,123,738,803,884,129,801,819,233,480,462,694,441,292,497,44,451,419,790,742,147,421,595,671,137,934,686,308,6,112,537,242,30,437,710,986,974,789,784,566,875,873,44,824,444,121,966,369,896,916,640,245,451,734,514,636,632,467,291,194,376,859,925,271,274,915,185,84,395,465,67,191,837,332,622,152,438,601,932,348,744,252,20,106,39,769,3,255,340,616,643,828,142,297,268,602,241,295,670,525,919,58,135,920,377,521,621,333,987,446,503,988,222,504,178,371,69,956,601,611,637,938,391,660,427,936,387,246,393,824,91,811,72,837,20,406,787,620,116,690,150,236,945,880,84,349,239,846,746,647,839,582,584,333,647,681,659,644,598,178,401,428,277,966,719,156,485,821,635,404,584,542,640,996,46,907,498,940,458,223,530,654,337,924,943,930,3,727,984,136,104,10,535,124,761,955,869,566,403,844,664,809,877,651,441,738,648,588,850,255,981,639,564,593,43,339,803,877,167,873,424,391,440,710,908,253,630,952,575,921,143,775,584,451,206,571,967,117,291,417,24,589,246,931,463,457,920,542,930,716,844,581,868,266,659,939,157,58,17,312,551,840,817,321,510,469,117,677,899,890,147,151,250,670,131,708,203,23,326,620,829,55,858,570,889,554,888,358,727,703,350,964,164,679,337,23,151,717,146,159,618,223,325,859,912,529,330,483,588,692,660,392,413,355,870,301,553,160,469,221,431,310,521,141,728,494,165,834,360,11,236,478,81,448,662,400,332,358,755,834,259,76,619,697,223,611,474,943,693,546,128,100,822,874,808,95,423,634,995,1,841,410,178,155,353,462,617,406,763,948,14,135,270,686,238,967,684,623,124,787,345,677,465,600,335,879,646,872,304,528,920,232,474,897,910,458,493,343,567,276,943,212,353,680,490,224,889,691,828,616,987,89,170,662,804,162,453,11,778,467,485,295,65,452,198,435,331,298,192,55,528,909,10,343,481,881,219,32,419,776,134,992,117,969,971,550,574,555,784,377,360,146,828,987,558,561,576,985,523,516,981,642,705,835,167,881,109,860,483,482,933,727,651,785,282,530,17,758,889,180,467,813,691,412,161,727,218,486,852,561,138,438,135,524,737,9,168,995,93,835,310,893,244,226,696,985,761,580,987,75,943,887,134,337,325,800,894,232,943,208,81,751,359,22,930,643,362,866,415,82,940,734,965,960,207,203,906,652,324,65,851,926,778,615,67,301,737,388,101,357,857,139,659,575,195,438,681,990,565,641,805,951,173,566,491,540,56,730,34,559,796,780,934,66,229,465,628,308,783", "473,535,839,159,201,610,850,655,731,627,633,153,726,21,901,850,905,203,976,527,56,974,471,65,200,965,119,523,424,695,169,505,530,411,514,81,870,896,392,212,620,354,311,958,490,835,723,670,189,43,453,790,694,887,688,342,644,222,28,694,570,251,176,753,392,821,976,44,144,240,940,845,829,55,660,485,253,681,120,29,402,947,484,169,254,301,28,913,149,438,697,947,714,678,300,975,369,635,799,503,714,665,160,645,757,204,464,913,250,846,375,196,474,467,513,671,992,135,344,558,781,334,961,787,820,627,122,27,492,239,886,192,317,72,576,834,814,844,843,775,651,323,539,621,800,45,470,36,885,439,944,62,355,637,895,890,301,81,771,275,813,213,729,677,213,639,418,917,616,296,328,941,695,41,925,415,864,367,857,692,172,169,704,53,114,710,581,66,538,152,857,841,818,331,14,716,966,921,9,628,324,94,449,910,870,371,779,388,292,512,440,666,16,683,799,566,795,240,188,631,288,140,784,972,114,619,712,432,96,275,563,75,833,238,866,671,189,97,284,861,939,433,624,277,309,825,527,20,746,496,278,383,299,693,217,679,558,189,871,450,986,570,135,116,33,298,911,119,662,31,170,542,588,447,812,649,533,837,538,963,928,479,865,410,967,514,286,378,616,659,161,396,5,721,170,164,443,764,113,63,45,853,915,112,961,315,690,272,724,613,271,510,134,248,716,154,828,883,750,704,937,723,356,934,391,519,49,42,893,0,72,221,765,129,588,846,190,246,991,445,171,836,411,320,770,999,704,778,401,897,678,325,196,915,978,56,839,915,53,167,974,592,929,294,896,69,746,879,964,396,260,39,963,239,977,603,914,759,331,481,472,136,356,237,779,693,371,852,620,389,799,956,524,559,725,976,824,447,297,289,995,984,191,405,426,778,168,373,721,485,438,21,664,359,315,884,487,689,287,911,135,120,180,674,58,842,855,484,146,485,315,674,439,543,733,451,367,805,318,214,550,452,172,696,646,793,949,304,593,246,197,849,302,452,272,2,50,583,149,976,520,843,849,500,242,79,38,345,178,530,933,815,425,454,410,189,580,941,995,774,653,48,433,739,105,787,946,515,263,449,724,309,601,860,341,683,282,358,634,695,669,522,822,234,833,126,813,681,716,467,514,64,730,947,419,812,821,10,599,971,964,552,676,84,551,475,376,872,740,297,945,351,162,794,396,715,936,912,23,70,279,880,32,868,330,33,668,936,358,65,738,545,787,945,660,498,490,464,137,594,897,842,833,538,672,428,458,655,509,187,166,885,110,441,930,724,838,753,132,532,634,627,135,524,751,498,929,77,502,446,488,279,107,758,13,797,684,304,129,350,658,442,941,576,3,718,530,334,923,753,979,29,933,561,67,949,872,571,176,37,588,223,658,598,747,94,751,228,655,946,391,789,537,712,937,753,377,100,706,972,415,217,282,950,756,177,349,110,707,376,877,676,610,322,935,81,945,578,335,50,560,666,574,258,211,910,737,995,863,554,90,895,404,569,407,236,270,682,970,798,776,54,867,891,63,710,3,659,946,629,946,612,286,515,942,966,471,881,880,859,853,148,654,480,209,856,837,310,464,511,473,639,416,273,965,667,997,150,369,481,33,527,16,450,400,213,172,400,449,79,28,447,309,875,498,225,760,618,868,999,619,632,12,281,294,789,320,936,622,611,814,7,534,854,830,53,211,964,754,757,883,114,5,321,190,128,212,13,363,657,808,129,816,232,343,360,896,765,101,81,441,664,328,63,622,374,459,733,604,693,714,518,6,139,590,872,495,539,318,267,246,811,762,962,465,361,355,579,559,936,931,130,547,812,223,178,909,17,483,535,537,184,372,138,803,85,490,336,843,778,309,502,776,215,676,374,305,801,8,37,29,121,286,603,748,776,897,827,821,630,926,62,830,276,228,937,103,569,676,377,244,452,575,51,905,569,353,847,779,56,823,250,385,271,502,159,858,401,718,492,648,957,842,961,10,549,350,980,170,37,355,859,729,283,708,242,62,738,865,494,268,39,392,248,238,834,963,847,497,871,729,178,663,919,393,842,664,84,775,465,707,606,610,58,957,473,952,187,45,323,604,120,803,9,624,572,456,319,13,502,372,222,691,467,721,406,342,720,48,994,215,792,514,812,781,414,492,987,195,104,43,12,12,105,885,72,806,251,721,204,205,202,879,595,396,420,195,416,521,782,1000,492,963,458,494,435,765,731,760,992,725,374,5,68,717,152,554,171,835,834", "372,881,723,209,96,786,182,926,440,620,222,296,114,141,147,609,668,679,908,490,705,362,474,2,510,283,701,494,107,874,502,641,624,212,238,9,620,850,514,427,937,981,59,9,251,551,40,415,424,246,434,543,658,541,462,72,627,189,184,744,914,804,996,155,685,468,32,99,762,227,736,488,3,900,135,499,783,928,34,439,601,812,443,666,166,159,570,33,540,431,447,927,415,291,120,207,949,754,465,926,393,964,801,799,13,445,37,738,317,311,899,652,850,926,825,351,23,553,816,796,709,100,926,209,257,664,839,998,990,226,862,464,528,746,59,698,138,523,752,992,352,388,896,278,683,287,549,332,657,195,542,170,714,911,505,312,554,297,810,425,977,421,821,579,272,310,19,121,18,474,33,580,460,321,53,572,102,82,837,746,965,376,107,455,400,896,172,44,703,435,41,186,814,494,610,438,163,176,761,641,177,792,814,185,535,174,477,733,110,440,914,496,411,876,481,763,758,959,851,812,773,406,197,985,454,104,91,722,743,296,366,559,684,105,468,596,762,792,253,186,919,89,332,934,295,910,494,522,608,790,701,177,160,340,903,42,270,265,946,670,857,562,425,177,819,333,932,753,275,882,556,190,807,515,118,681,904,927,392,703,423,575,917,409,170,766,708,83,479,931,253,7,515,331,709,151,660,635,611,203,800,321,679,171,186,349,97,517,985,988,30,398,497,631,683,371,953,246,752,12,6,439,455,549,773,640,241,186,782,72,0,388,790,942,738,147,656,294,314,839,107,128,924,781,864,529,123,45,435,593,572,284,942,461,319,767,257,646,565,214,640,272,877,658,511,879,285,217,30,398,106,102,710,633,454,96,749,713,152,66,193,227,86,960,984,396,689,744,115,415,389,67,935,131,585,111,519,238,200,146,992,702,57,642,712,588,14,862,997,19,324,738,32,444,234,385,414,647,822,780,850,453,449,225,975,565,68,309,694,264,841,705,673,134,840,705,709,997,513,68,107,337,943,719,356,431,748,489,377,609,915,601,752,166,866,390,939,279,277,836,369,235,498,153,718,989,376,268,864,320,698,996,213,684,794,312,918,151,393,329,322,957,963,635,548,260,132,177,501,250,467,892,314,669,380,320,585,105,776,872,912,852,359,653,184,907,3,693,475,122,597,670,627,637,906,848,842,823,660,344,558,4,172,339,147,917,341,612,153,710,569,216,133,178,552,553,893,498,661,129,286,600,351,359,628,357,483,873,569,446,304,714,236,491,663,33,81,593,797,399,133,826,650,521,81,584,894,98,336,432,208,965,236,783,71,588,316,637,826,141,287,275,651,378,709,903,803,751,131,530,205,905,525,394,103,490,672,685,99,423,711,754,760,556,817,858,295,225,599,622,743,478,75,976,676,353,480,564,726,688,675,537,154,470,905,603,811,376,319,352,536,134,146,564,808,992,95,656,947,72,462,757,809,331,372,114,325,604,670,376,741,874,236,374,901,986,970,229,168,443,440,926,304,537,982,669,508,447,927,297,478,145,602,557,825,797,92,517,5,437,38,622,907,391,375,252,794,322,492,491,443,401,18,443,579,301,87,566,717,785,239,274,139,906,273,885,251,657,470,989,478,867,446,161,326,589,684,571,488,294,188,172,97,374,562,565,423,710,810,30,260,882,108,704,650,404,100,763,90,845,649,263,543,940,641,737,76,718,973,794,275,793,616,668,434,246,168,429,589,730,989,350,795,617,839,929,463,711,667,343,502,205,538,522,438,864,661,934,216,994,279,161,971,987,181,981,867,283,76,573,736,629,380,712,534,973,40,343,607,226,42,972,165,931,657,425,612,20,561,6,214,156,5,710,145,951,32,555,287,18,352,105,494,134,701,192,748,235,205,181,459,693,602,117,294,364,53,509,747,399,260,60,228,204,94,986,105,142,177,368,584,785,12,5,279,128,57,121,237,911,250,250,373,675,706,940,176,45,67,729,686,406,464,574,964,507,879,930,201,877,221,364,250,830,734,393,529,578,39,107,864,32,213,973,273,943,497,38,116,635,766,150,871,145,115,348,471,441,797,525,77,432,623,296,549,445,989,970,552,918,305,467,817,604,151,205,136,659,131,589,3,873,154,507,370,442,956,796,347,668,655,438,998,87,774,797,854,210,270,865,709,383,805,490,56,170,318,454,482,596,239,690,379,224,629,678,936,471,146,484,813,831,938,623,629,253,650,34,49,532,785,207,180,954,853,829,484,182,66,38,329,242,464,504,484,189,581,43,705,165", "607,478,259,243,373,661,404,355,107,407,661,149,183,764,755,254,984,271,415,123,64,48,742,123,348,422,275,482,799,585,230,205,868,199,678,506,533,358,114,480,229,954,190,929,208,747,977,497,448,111,411,88,392,391,690,932,117,191,827,366,894,124,657,5,450,916,198,746,325,67,43,748,911,367,417,579,987,86,933,356,854,298,301,147,692,429,197,617,393,362,391,799,609,469,924,459,105,54,899,423,571,577,774,44,321,729,225,525,828,45,693,164,612,568,122,196,811,712,505,262,871,930,394,377,769,721,880,356,591,574,87,39,604,171,522,102,288,141,735,438,875,478,132,705,673,695,285,495,19,922,886,681,92,907,789,553,453,4,151,689,842,949,715,595,261,675,206,923,627,178,162,375,335,702,962,622,302,41,370,234,580,514,374,171,471,443,682,779,989,473,618,271,959,800,765,912,678,210,923,345,325,400,909,996,600,566,382,354,376,378,697,141,359,419,539,654,588,332,753,907,660,392,695,814,264,123,313,464,822,647,996,855,634,829,742,985,171,261,29,213,801,87,700,92,769,763,613,163,982,9,456,466,932,355,585,317,189,544,537,77,169,764,485,840,901,376,134,100,471,791,109,774,677,483,598,25,649,849,150,628,612,504,64,410,656,69,212,922,790,767,416,584,713,428,34,144,905,110,342,691,87,480,862,318,114,483,294,152,942,226,753,945,309,832,398,851,788,307,722,118,202,183,465,720,609,398,47,57,197,221,388,0,544,916,714,431,471,936,479,774,291,560,954,907,709,577,110,682,132,798,713,335,479,304,321,57,889,58,730,708,332,506,826,799,795,423,193,882,381,797,246,579,692,696,115,706,413,509,201,645,40,409,431,5,537,734,184,96,981,173,130,299,891,666,58,177,596,123,119,450,730,548,257,531,227,235,287,56,312,487,155,27,364,389,810,400,509,725,925,915,719,919,56,107,355,884,729,673,525,885,786,675,633,569,366,570,772,920,732,849,160,100,299,106,562,291,504,946,66,293,790,347,793,896,696,170,945,503,400,833,197,630,311,224,589,935,662,331,592,888,157,343,28,942,906,600,798,78,195,704,452,691,259,141,570,995,372,51,641,323,899,688,190,309,122,238,611,67,949,311,953,396,40,254,527,870,399,343,721,387,989,539,143,642,214,99,353,7,22,833,963,744,753,11,886,930,498,570,696,169,235,604,523,806,171,117,522,529,823,679,285,766,234,232,377,671,502,78,832,825,861,170,468,450,184,630,803,205,182,28,175,821,275,876,266,26,814,809,302,293,236,675,488,270,449,802,745,395,389,937,126,410,110,117,823,936,554,697,81,365,295,498,866,750,702,156,184,803,99,736,594,512,962,984,147,34,789,684,943,651,560,887,357,593,714,282,701,31,938,252,695,255,278,73,342,729,864,757,749,816,926,197,19,499,232,795,110,996,796,516,314,273,408,97,412,33,278,298,328,859,747,352,447,864,855,209,486,192,307,277,526,883,929,877,767,297,969,581,51,187,688,335,242,2,871,652,667,973,871,860,461,69,954,4,357,175,527,690,51,182,453,274,617,6,326,815,407,992,235,317,264,493,681,788,637,520,906,234,235,323,415,641,433,397,397,449,189,129,957,891,612,210,742,699,858,178,101,293,147,875,142,615,801,349,244,443,790,511,865,353,393,787,154,846,677,756,198,123,596,647,40,830,328,194,154,76,584,224,973,203,590,876,278,678,629,429,223,533,616,802,105,165,303,430,288,767,427,532,585,301,277,828,761,207,685,653,653,897,129,322,333,300,505,722,257,526,203,448,465,541,289,215,698,622,236,68,202,314,239,868,246,818,98,473,815,655,419,93,645,514,166,898,603,433,209,437,548,930,797,474,466,994,285,77,598,751,273,722,619,187,562,200,519,44,587,277,810,800,222,253,339,764,352,499,795,617,151,503,793,527,683,501,23,392,709,490,383,360,944,835,964,131,236,337,454,715,225,180,262,956,376,666,779,920,687,898,472,406,921,762,75,807,614,335,671,206,875,643,746,951,723,276,207,482,530,854,106,829,555,187,471,62,675,446,390,688,37,239,218,473,792,356,451,793,205,675,239,42,908,951,638,275,468,197,262,760,606,286,464,542,662,612,75,717,410,492,344,643,523,645,231,959,293,605,881,405,445,615,498,132,792,439,163,483,249,373,343,889,575,530,702,834,721,486,402,280,627,628,875,286,869,245,994,773,353,812,726,405,352,319,216,591,274,458,385,585,210,838,715,358", "251,474,101,164,275,45,680,280,909,116,480,680,905,28,232,788,673,356,33,766,451,93,943,973,923,542,52,241,332,731,727,399,520,337,977,810,914,927,895,528,74,188,78,172,34,718,731,426,27,753,513,751,420,736,786,267,391,832,692,299,468,93,156,810,180,307,109,266,40,751,220,862,829,858,576,612,732,38,657,934,490,346,595,186,258,247,732,355,786,503,504,976,705,939,384,217,540,50,273,879,645,255,362,848,450,148,13,964,16,231,450,77,322,643,984,651,713,762,185,802,179,488,911,36,774,855,8,941,371,463,353,175,745,655,252,660,420,198,409,801,612,799,967,803,191,694,687,347,146,799,248,649,191,939,465,862,17,697,779,532,346,655,450,380,584,824,147,187,396,973,700,66,62,764,486,981,190,29,362,475,187,690,170,819,338,265,305,545,196,234,776,248,377,685,554,900,902,162,498,129,764,395,905,474,350,363,968,800,532,516,604,778,780,77,304,141,959,359,578,474,806,238,11,305,619,849,44,66,597,26,227,915,393,666,853,692,738,954,808,437,317,434,734,36,466,745,688,614,140,933,631,794,290,939,140,494,902,84,698,232,760,470,859,693,205,133,501,735,473,127,396,652,885,205,982,61,192,468,875,972,521,153,987,682,531,538,224,634,442,129,292,372,431,241,547,750,127,929,377,286,835,997,616,86,914,321,76,891,441,213,445,581,400,956,744,415,387,778,163,693,93,491,489,558,595,759,28,601,133,765,790,544,0,290,625,425,799,385,699,747,563,577,731,905,666,53,927,218,653,727,365,545,472,715,405,611,839,147,199,209,290,270,736,594,264,771,853,139,771,71,833,633,256,430,136,992,996,927,938,169,615,379,348,754,735,434,440,853,886,325,569,876,887,542,701,321,41,669,41,466,717,243,566,481,159,113,850,986,759,769,297,31,394,804,856,446,793,290,758,641,403,576,919,401,780,383,971,851,39,579,873,180,367,115,247,789,268,138,237,835,316,575,340,408,172,175,21,872,153,654,175,261,171,69,620,241,623,120,614,572,51,100,635,73,95,971,793,378,62,579,659,76,48,552,59,251,5,716,779,594,898,119,469,439,469,60,782,935,706,834,724,412,384,840,636,377,994,587,744,444,324,981,16,539,303,416,120,861,722,680,182,953,81,895,962,381,225,887,83,668,543,576,197,563,94,815,731,848,14,72,949,269,979,864,175,43,998,1,295,449,922,713,985,319,191,396,248,628,509,313,890,184,673,723,985,994,995,638,581,133,402,102,224,366,620,554,344,740,109,886,440,591,108,978,95,950,476,493,975,443,612,389,922,58,868,451,541,760,628,227,925,437,595,746,941,147,229,995,405,977,974,680,851,599,884,320,722,594,53,707,419,402,431,464,363,114,465,327,951,485,778,341,598,882,985,287,816,331,648,35,905,594,85,385,226,149,789,440,300,764,227,527,143,80,491,274,695,4,730,602,533,44,411,888,73,458,328,253,560,912,590,939,504,967,824,694,683,14,49,411,677,329,316,197,97,771,952,900,223,947,712,217,770,600,913,236,261,270,978,1000,770,131,993,312,281,731,959,434,189,129,75,519,456,295,689,739,268,365,93,460,381,375,68,277,401,24,585,531,270,156,248,463,377,450,29,165,57,758,875,730,283,830,487,675,388,25,463,957,57,557,306,61,803,398,797,654,465,216,504,946,767,136,823,748,481,213,689,959,148,197,606,680,51,483,552,528,857,637,731,279,480,717,109,657,979,839,570,8,706,17,951,642,729,380,395,655,175,647,838,175,51,276,830,671,560,477,466,677,396,442,395,31,973,671,870,696,763,567,609,162,39,401,944,988,524,683,658,291,504,249,381,858,394,737,275,846,550,639,658,920,947,181,626,883,875,57,237,817,34,481,571,856,578,390,671,736,698,700,390,189,701,582,113,794,564,741,285,718,520,560,273,221,575,374,537,534,145,661,441,815,763,622,829,735,176,73,482,690,687,847,199,358,25,675,324,667,818,688,786,138,3,166,429,661,737,620,644,150,653,685,116,282,606,325,212,211,722,895,400,837,860,881,626,578,647,649,544,514,921,604,776,872,478,62,586,825,151,832,702,561,288,44,249,303,26,84,51,580,615,428,424,605,436,287,592,601,299,217,387,591,9,528,484,305,988,789,214,136,259,548,207,857,749,334,611,855,189,800,154,344,171,803,571,343,556,666,16,65,335,53,764,881,409,15,191,836,894,763,891,82,628,637,358,65,551,512,928,461,736,377", "454,541,875,575,738,108,529,663,448,261,560,654,195,221,433,711,348,340,265,537,425,861,372,465,437,124,517,552,867,441,813,607,285,741,989,628,414,934,574,584,827,488,224,99,327,705,652,319,308,969,847,233,354,346,897,563,870,121,415,12,66,529,611,449,129,743,310,662,244,20,232,483,932,370,744,529,618,858,562,335,439,254,329,664,499,215,258,722,221,806,835,310,269,262,697,588,43,925,158,803,764,311,780,5,258,692,591,229,794,603,201,952,335,972,586,595,519,118,347,29,195,223,876,241,693,143,707,129,230,892,456,809,379,980,562,479,204,286,242,363,766,83,512,263,353,179,278,63,62,965,67,933,917,962,382,70,610,989,378,711,493,948,206,29,274,780,326,913,454,582,591,377,578,851,986,891,671,587,753,347,708,193,341,488,430,912,996,870,522,912,422,337,605,950,102,157,782,869,263,418,106,481,207,591,78,363,769,185,11,143,973,75,897,27,163,224,753,866,197,708,912,510,802,406,9,144,404,316,389,624,655,731,825,348,636,797,856,61,217,441,564,107,590,43,946,535,670,117,926,773,658,258,197,278,156,764,500,772,78,730,657,513,624,30,754,186,438,248,125,961,388,844,195,213,88,449,765,414,994,729,64,863,714,381,55,297,580,412,97,43,981,234,209,98,805,845,994,853,724,579,825,377,487,194,474,229,298,403,433,474,823,712,214,479,687,448,929,585,822,38,100,230,63,272,744,674,320,795,26,129,942,916,290,0,546,725,584,310,287,154,330,648,648,494,703,6,172,391,855,389,909,127,561,204,451,54,203,303,904,837,488,654,703,782,254,525,428,692,180,547,62,598,516,168,544,80,740,241,836,701,264,529,28,639,137,9,510,374,599,380,32,506,758,533,273,623,855,726,715,738,10,208,288,966,753,962,296,987,558,239,671,439,80,352,629,211,725,228,685,53,172,95,301,48,490,182,508,357,816,851,76,429,731,508,931,80,538,621,92,80,466,124,608,416,23,312,530,185,207,775,550,460,647,487,640,913,950,686,872,402,4,557,3,458,469,234,605,876,833,583,678,678,388,607,251,176,500,569,997,376,790,845,255,573,960,774,546,191,230,763,698,943,425,667,212,562,982,501,147,426,771,81,238,957,763,504,672,61,349,221,737,610,344,647,495,442,256,439,258,797,835,871,114,6,703,341,971,674,361,884,673,695,873,923,236,417,917,277,391,56,600,216,169,759,147,159,584,31,387,115,547,506,879,817,948,61,951,562,910,649,185,401,625,232,775,509,531,766,938,822,264,598,684,125,963,756,770,298,743,618,129,690,358,834,616,757,917,508,584,819,92,346,886,521,665,833,252,449,18,890,671,665,655,529,784,773,700,446,774,337,75,540,575,510,857,860,154,228,134,408,106,403,201,266,60,255,644,67,930,134,835,695,393,659,299,17,27,72,730,601,144,74,838,159,743,434,536,596,897,981,387,625,674,648,158,481,41,771,421,652,323,931,915,52,805,524,901,955,181,964,516,274,31,383,354,115,615,446,323,780,455,390,102,311,768,130,560,21,163,355,968,736,113,253,248,389,8,477,363,197,625,643,41,265,38,63,72,986,519,30,838,979,651,661,636,670,644,660,993,89,55,111,985,620,158,803,478,978,691,786,574,662,407,433,679,675,492,948,618,435,206,737,762,202,78,921,582,18,923,539,173,185,649,54,505,972,136,631,65,851,595,92,862,602,906,695,490,36,84,322,34,267,602,463,447,206,547,265,966,583,520,94,779,930,867,512,985,273,528,717,41,375,953,455,470,499,277,273,927,157,594,611,586,638,126,928,709,913,834,602,531,290,959,149,121,650,370,72,389,560,533,230,537,809,477,624,972,159,386,719,588,823,314,338,750,121,238,941,90,870,500,688,310,525,219,956,366,707,624,13,677,658,701,470,959,682,874,510,513,416,948,683,251,500,392,984,753,77,726,383,661,918,601,672,198,243,937,442,115,753,848,500,901,766,479,74,212,325,937,657,662,814,975,59,680,48,83,781,158,572,66,469,504,788,252,33,489,816,235,413,874,681,256,255,901,607,748,880,596,123,233,542,333,838,976,956,55,236,766,459,648,346,250,28,380,17,685,703,361,162,262,4,8,658,320,693,799,723,470,561,63,856,939,635,565,583,863,305,967,241,701,105,419,821,224,367,418,815,352,852,927,29,930,849,635,835,913,16,571,685,579,384,105,935,699,311,82,711,569,749,300,588,906,804,55,249,754,889,792,195", "718,522,823,305,567,333,297,80,105,421,181,304,554,963,258,811,917,756,542,109,115,158,17,916,939,88,618,410,424,458,745,439,478,942,499,304,989,105,15,79,35,144,544,163,176,917,768,736,242,566,332,515,58,887,55,795,938,295,608,306,673,491,586,761,92,142,648,669,773,625,534,639,921,851,389,731,220,73,945,901,491,527,263,527,459,786,946,692,969,663,729,664,282,125,514,565,277,651,747,302,498,603,856,498,828,311,856,699,306,994,882,155,312,341,644,890,869,198,220,518,356,534,851,926,41,819,471,14,768,844,599,836,199,539,610,246,745,970,857,713,431,935,835,753,984,843,278,94,779,80,707,210,104,502,842,607,904,613,490,954,904,277,953,911,656,268,57,510,913,637,967,166,987,804,654,714,331,617,654,409,459,589,575,478,536,770,373,177,284,446,313,946,151,908,230,54,874,741,753,846,787,10,287,810,328,402,256,718,351,507,735,887,962,81,406,851,511,483,500,878,433,959,225,586,708,816,585,504,49,430,57,775,749,630,971,973,626,83,517,156,895,960,102,281,403,915,358,47,235,789,575,460,842,809,569,967,189,862,408,105,281,908,789,967,920,481,253,542,866,494,496,635,970,930,4,883,751,188,68,203,327,516,237,319,732,812,420,171,832,132,961,416,291,205,885,851,148,863,806,724,328,184,708,573,809,248,683,484,232,843,111,136,814,335,964,629,615,192,105,835,871,216,773,428,127,133,274,622,969,588,738,714,625,546,0,359,86,334,27,808,551,387,715,509,200,695,948,270,561,23,215,210,16,865,133,815,544,791,190,623,146,616,897,373,401,111,810,699,11,733,706,410,831,499,518,725,39,577,534,831,537,244,455,618,313,632,641,136,280,641,573,968,473,323,963,843,211,331,421,456,488,717,482,483,696,826,942,357,869,633,563,781,64,32,711,957,688,52,690,185,914,661,83,936,251,148,215,300,989,664,661,747,547,215,121,566,599,303,154,188,546,76,587,888,485,244,526,624,399,501,359,950,206,591,216,109,313,713,72,521,384,636,903,399,981,841,786,394,834,187,438,36,629,722,365,249,212,333,160,45,656,526,266,490,783,590,887,324,667,67,947,754,74,223,296,779,305,169,562,194,111,566,502,987,831,870,347,824,313,784,26,630,356,70,847,23,264,178,886,728,472,636,176,532,576,138,420,693,142,805,870,291,997,74,459,434,975,841,3,702,669,158,397,542,792,293,400,779,400,925,835,863,691,143,249,814,290,580,100,955,473,239,474,955,531,917,453,448,192,547,858,43,326,595,225,758,732,437,115,844,510,592,33,791,537,699,269,874,752,909,399,368,692,95,557,244,690,722,638,390,855,666,306,946,123,749,295,70,216,155,365,314,289,960,480,494,364,18,754,227,316,161,749,288,65,112,361,290,25,456,605,249,657,557,592,936,448,212,533,441,215,550,591,276,658,252,908,788,795,470,534,947,473,109,637,870,714,870,788,916,585,885,475,374,954,594,50,868,259,373,127,256,491,181,643,435,931,204,587,144,283,716,739,427,124,792,457,280,731,317,765,728,806,903,187,323,61,539,574,805,668,847,64,384,580,634,479,681,596,716,417,132,871,662,682,218,273,879,431,725,786,237,610,511,205,351,303,298,89,67,846,464,877,612,222,147,755,944,508,182,72,116,944,420,688,863,411,364,851,613,970,270,379,352,10,386,865,136,710,972,842,326,409,609,810,477,439,624,584,984,998,256,821,940,357,336,843,829,88,63,346,779,92,408,321,144,901,844,676,67,969,478,838,864,271,809,566,446,111,343,447,470,829,489,480,772,964,819,739,353,659,3,231,46,40,662,464,75,559,345,769,148,934,861,92,179,193,310,390,63,24,59,801,534,326,687,784,457,654,938,268,691,974,215,242,537,784,884,244,7,262,696,688,82,877,2,74,80,477,814,584,411,410,88,707,543,882,285,457,536,633,73,452,988,704,837,733,9,314,469,14,298,59,883,328,353,750,439,845,556,514,675,244,231,398,132,499,302,274,704,147,314,474,522,513,676,135,512,561,701,431,360,627,819,662,970,608,329,654,452,470,357,632,439,165,885,544,637,617,69,316,749,926,343,904,953,91,485,807,110,146,176,662,124,158,924,692,239,631,398,904,715,296,415,355,599,530,934,76,749,496,640,468,436,193,487,927,273,520,491,850,60,774,768,393,192,248,209,244,927,452,308,871,943,775,855,339,626,57,824,599,92,6,577,364,382,766,161,758,873", "228,135,242,881,516,399,362,404,167,775,364,88,923,203,77,438,419,652,60,504,384,562,58,141,335,406,729,42,907,924,855,138,980,10,574,816,670,218,785,338,789,303,179,411,212,824,698,684,409,774,677,798,896,511,993,917,546,666,673,770,391,667,862,374,86,465,985,372,335,966,749,265,768,265,991,400,136,625,48,115,88,145,430,29,778,696,706,262,157,706,374,162,551,147,191,826,313,829,986,506,392,413,29,575,748,978,671,48,285,157,532,732,237,782,513,544,775,828,542,15,859,204,772,609,863,720,723,259,399,743,621,296,286,918,820,40,258,515,790,476,655,953,811,59,221,375,604,409,929,232,638,558,244,36,243,147,147,612,784,637,152,823,913,553,30,591,237,627,473,817,872,954,337,870,88,314,569,748,232,727,745,784,887,875,122,381,592,97,681,399,555,246,623,411,44,711,522,225,824,99,431,916,701,299,359,812,705,250,956,947,73,799,694,245,125,386,818,191,863,88,679,484,399,117,872,283,365,823,853,999,371,201,512,841,567,57,900,826,698,423,960,540,842,517,366,398,754,649,400,902,86,595,243,816,557,626,973,438,690,772,927,206,670,31,626,693,8,749,335,453,449,727,615,380,944,866,498,2,523,247,766,661,549,339,986,431,663,991,680,182,809,895,227,533,394,799,555,240,539,541,61,728,23,126,930,213,27,770,461,93,130,700,309,436,942,200,477,885,970,52,795,972,525,253,204,701,641,651,803,846,147,431,425,725,359,0,207,108,220,673,881,749,439,212,662,658,609,362,922,857,62,587,571,798,580,192,497,46,870,715,137,511,661,622,887,472,179,440,767,213,378,644,208,686,149,317,734,73,984,892,828,132,416,196,36,358,138,676,875,317,802,729,654,707,969,871,742,247,894,603,129,871,511,650,592,819,700,830,556,888,85,133,730,86,433,666,291,107,355,338,135,649,843,107,262,57,917,245,327,442,230,4,993,88,919,498,339,475,220,833,901,733,311,336,794,83,318,220,562,869,672,138,538,492,545,404,617,87,181,489,40,308,289,922,407,206,268,25,385,683,509,913,763,608,914,757,736,171,71,152,583,346,598,245,809,126,907,867,209,267,500,185,125,585,67,260,865,527,59,801,992,125,623,62,551,213,82,931,773,401,206,509,381,956,866,849,268,275,311,797,316,502,927,789,442,914,476,820,219,485,520,296,209,280,43,870,170,190,907,58,883,296,489,408,925,388,63,251,792,487,133,37,107,239,201,825,357,147,524,997,747,126,115,805,226,532,396,975,437,874,913,605,812,491,89,178,278,908,807,788,493,92,854,20,606,554,736,665,848,385,974,387,361,946,478,414,727,153,265,513,851,125,457,367,45,613,944,153,409,579,540,750,720,440,128,460,974,855,852,622,595,458,593,769,197,101,514,186,931,350,827,266,923,290,74,122,906,134,515,485,45,902,983,16,942,488,292,455,801,920,946,544,869,756,38,418,780,273,877,603,666,747,272,905,994,182,671,380,228,718,819,711,161,878,168,597,806,897,99,704,739,699,415,983,760,948,262,343,644,463,295,405,703,326,265,633,143,173,504,738,103,737,847,786,928,492,377,130,798,423,945,528,386,643,503,415,74,589,409,910,92,742,818,177,862,861,855,142,605,240,334,261,92,30,499,676,736,449,566,727,550,912,61,166,637,11,233,208,316,883,819,698,380,499,714,998,149,169,510,737,972,757,324,727,573,114,634,102,711,224,597,554,142,615,769,27,988,995,453,459,492,3,204,627,63,911,302,122,293,782,833,523,510,711,333,863,449,425,160,516,69,607,851,496,327,794,190,69,338,649,975,763,336,162,47,821,325,22,315,141,278,228,708,933,597,940,377,166,657,888,976,899,196,992,356,756,935,19,437,418,753,524,722,932,444,635,25,393,49,296,915,762,589,528,849,606,598,271,522,766,33,705,171,793,255,923,633,348,45,813,855,639,552,222,404,649,215,230,905,605,461,166,761,674,573,879,82,85,280,953,172,931,123,258,317,20,479,71,583,661,244,462,99,745,189,962,159,483,834,689,848,891,665,417,903,491,853,942,21,520,548,614,880,667,416,469,499,178,275,517,573,784,443,195,414,640,324,508,369,654,498,61,136,132,445,23,656,630,724,873,918,222,954,577,56,909,139,763,739,309,300,417,296,265,952,881,15,112,2,184,434,967,389,855,352,905,299,539,808,421,237,724,774,901,12,197,109,123,330,734,371,392,255,935,502,865,488,147,663,773", "252,163,809,528,698,371,801,474,971,292,52,529,626,50,772,183,322,323,148,947,932,223,611,534,672,255,777,645,274,606,109,354,276,63,336,563,149,673,373,425,581,599,984,619,578,908,485,599,212,757,105,633,336,340,650,702,99,161,978,507,297,69,813,925,914,551,627,790,919,91,855,673,67,298,379,485,129,924,366,41,712,176,671,924,416,380,925,749,533,783,689,243,818,773,798,60,128,302,216,440,919,953,513,664,68,938,473,504,653,551,101,802,639,497,45,655,959,311,559,785,293,843,684,579,261,469,174,68,212,251,220,490,692,490,656,268,193,869,339,602,936,422,97,453,228,688,944,244,289,126,273,171,921,51,609,835,699,638,134,198,218,5,811,787,380,369,774,209,952,227,554,190,254,823,191,826,457,661,688,65,680,345,384,825,868,767,160,458,962,676,106,323,412,988,354,166,54,386,604,165,463,650,275,257,249,340,454,752,53,815,360,781,735,873,859,722,384,751,304,322,920,897,486,576,125,24,51,2,940,145,926,893,98,909,697,303,488,520,292,800,940,915,702,590,654,211,352,489,275,806,921,955,201,152,271,916,822,544,751,60,799,659,652,308,844,913,784,915,339,269,701,911,453,634,212,327,986,39,876,889,25,295,780,943,898,72,267,477,753,166,581,689,402,883,171,986,891,186,222,133,381,955,353,206,811,265,540,508,763,1000,880,127,751,705,857,87,611,316,824,855,675,941,836,212,663,729,715,6,636,190,656,471,799,584,86,207,0,152,532,843,213,448,714,348,126,50,251,715,287,593,200,313,32,171,859,216,429,837,587,991,641,755,271,281,680,582,6,118,692,632,671,231,626,416,577,360,851,985,490,265,925,721,308,927,259,216,825,741,796,95,226,783,721,423,186,338,478,137,72,150,707,275,38,301,80,956,889,552,747,294,248,866,69,15,661,224,641,140,181,316,1000,673,985,935,639,606,750,238,552,96,484,717,135,333,102,244,23,875,204,110,901,331,712,558,40,808,264,566,455,355,99,243,714,433,413,14,131,191,861,243,72,179,49,545,884,775,973,751,79,923,157,951,189,700,344,289,341,534,592,480,459,145,886,241,809,964,555,76,556,141,658,626,672,826,791,457,597,155,760,418,748,141,605,621,973,909,370,955,292,275,867,905,173,116,266,698,112,347,60,395,9,791,939,627,982,6,486,243,561,905,505,54,661,443,98,675,899,638,135,31,208,730,781,730,996,438,143,767,105,948,350,802,688,557,291,252,36,698,180,204,793,232,911,903,933,397,419,949,3,350,450,865,823,193,453,947,916,808,155,949,79,845,861,858,253,278,810,599,625,751,31,854,399,248,944,658,886,730,374,312,856,378,753,431,703,757,735,850,103,882,202,204,336,759,724,696,444,899,940,630,565,861,246,901,429,786,860,713,637,451,785,890,130,360,721,760,658,976,466,395,559,217,278,40,937,169,183,208,595,528,474,383,14,969,768,459,647,883,318,906,960,425,283,428,603,933,924,566,741,629,811,204,499,558,349,833,675,557,244,350,335,699,923,195,166,348,139,517,302,632,57,517,470,788,932,637,930,595,538,504,992,843,857,5,360,830,260,457,4,327,188,211,246,147,172,652,74,947,41,808,269,61,154,633,488,967,868,250,510,741,787,242,232,485,205,438,143,671,800,277,937,207,257,731,554,723,785,460,192,482,871,809,882,43,603,29,781,334,206,21,817,645,137,32,513,678,199,41,347,374,27,886,325,193,905,867,46,396,881,252,784,246,862,682,423,466,788,877,315,280,433,800,908,45,460,681,68,542,801,171,879,597,502,586,480,500,320,147,325,877,567,604,29,189,957,526,475,921,453,875,27,358,511,210,11,707,899,936,177,299,20,604,511,113,304,204,921,534,660,16,156,154,34,411,768,539,160,290,74,446,700,308,677,44,681,863,238,150,685,265,636,695,867,756,695,443,993,624,71,258,31,920,862,892,444,969,997,932,260,816,41,367,966,35,82,350,717,724,665,347,885,493,169,503,712,987,852,649,229,476,355,381,799,63,697,888,40,855,18,80,571,983,372,361,482,484,499,588,509,750,22,491,176,310,730,488,327,636,739,989,18,855,495,377,493,297,519,941,161,187,435,511,392,354,738,470,758,728,639,674,910,320,16,868,111,187,37,140,174,488,6,128,470,166,17,586,520,510,466,35,201,958,142,747,752,907,486,362,137,354,622,794,60,683,180,673,891,255,86,602,237,329,602,257,436,117,241,714,613,242", "116,180,249,618,89,971,53,647,462,441,213,72,181,354,142,294,258,849,427,537,751,443,142,376,379,926,228,10,805,592,563,836,447,613,78,957,404,794,489,874,358,328,988,28,242,286,725,569,109,762,413,887,224,513,174,965,11,365,725,679,913,174,484,712,91,784,995,939,27,973,756,918,764,736,161,522,826,873,935,771,907,186,990,426,694,271,16,390,711,577,86,281,298,527,720,457,341,719,819,966,535,644,759,157,494,660,260,420,623,264,461,920,833,284,953,129,693,830,413,805,348,31,504,623,57,808,373,444,319,927,705,434,588,680,897,511,746,49,627,524,894,410,254,657,159,764,741,64,161,120,848,887,834,305,255,872,151,531,390,40,995,279,892,201,341,641,979,8,655,474,830,954,605,408,696,916,609,719,206,455,74,57,248,648,491,250,222,174,285,705,975,749,882,878,304,897,313,663,597,646,390,578,612,319,350,493,653,229,377,522,43,912,696,796,30,276,21,439,25,957,465,358,828,598,265,241,647,958,77,591,703,385,995,717,211,996,940,384,291,463,985,401,818,576,1000,725,995,127,580,859,827,366,121,512,718,217,590,387,178,927,541,306,484,211,756,216,996,411,150,382,163,351,782,102,36,323,827,390,410,999,943,127,386,636,857,231,797,188,152,594,658,860,633,6,776,874,338,417,268,301,139,846,804,192,824,126,737,297,165,333,668,533,103,578,772,270,851,40,766,811,766,185,960,380,944,781,457,88,13,246,294,936,385,310,334,108,152,0,223,33,721,860,662,819,522,63,641,875,789,600,472,636,533,361,984,642,857,352,457,477,169,371,145,348,435,899,179,291,858,437,681,477,825,75,450,443,366,694,139,435,861,854,114,333,524,742,850,449,829,827,739,314,917,773,90,682,315,529,344,601,404,815,77,212,364,901,117,498,92,667,237,749,741,745,77,906,34,274,257,421,260,966,424,291,133,923,452,970,904,152,893,825,518,714,163,255,538,2,411,886,417,891,579,770,563,131,274,19,89,8,107,889,227,604,853,224,963,716,286,247,497,683,435,487,230,961,372,403,954,874,409,56,858,68,303,57,83,670,834,997,974,885,625,775,613,340,39,725,770,648,410,374,796,391,45,590,28,479,452,107,24,755,594,292,298,484,568,629,313,583,346,930,768,990,786,542,317,621,179,236,155,68,917,61,379,594,794,48,910,652,45,638,604,676,522,702,324,891,910,902,987,433,4,534,407,100,548,120,900,28,832,466,29,825,197,859,536,713,654,875,166,375,127,962,944,812,766,445,103,352,750,222,456,733,740,415,532,596,106,831,107,356,370,326,616,358,844,363,466,872,861,296,606,770,189,157,551,612,354,31,419,21,890,447,771,535,742,189,198,55,594,100,380,304,77,24,483,5,705,372,358,916,101,711,641,180,392,428,126,813,278,935,754,835,825,168,382,641,797,905,506,51,613,662,83,483,219,160,130,927,717,85,171,707,282,716,194,104,233,900,737,913,408,101,877,778,799,791,40,618,392,562,321,766,146,161,669,992,322,456,739,324,7,660,794,382,229,640,836,361,65,125,724,959,269,589,139,741,512,541,866,704,18,70,650,128,174,410,771,903,684,486,58,460,427,678,307,314,86,76,861,483,443,70,138,921,547,746,379,210,39,316,483,946,149,230,879,32,614,440,662,539,948,869,218,288,984,730,128,39,742,31,838,786,636,301,78,354,601,995,860,329,548,616,847,90,26,80,465,550,769,446,4,453,72,379,800,34,341,558,949,958,82,255,993,180,433,954,723,388,546,19,802,518,881,85,765,729,912,622,828,352,879,730,455,335,928,989,805,669,854,21,170,209,927,939,644,525,970,607,700,764,824,137,889,304,174,766,402,88,521,537,624,467,78,72,994,734,360,179,216,837,271,355,450,419,158,946,26,734,821,287,562,986,592,776,735,18,136,861,906,345,429,917,34,785,874,356,316,104,613,406,387,436,528,551,818,19,318,614,449,809,398,622,491,706,822,940,812,591,737,603,818,843,634,747,619,268,476,2,996,112,686,576,452,248,601,590,749,779,953,551,159,375,423,237,899,204,954,310,212,415,585,284,903,22,38,754,483,84,838,537,105,965,268,441,377,752,503,657,974,248,75,536,49,204,941,567,438,116,496,623,813,964,592,940,158,826,265,133,781,645,547,903,498,169,523,997,162,162,826,413,474,318,95,429,674,111,984,380,230,151,119,498,646,992,982,730,500,152,302,701,606,45,845,826,977,685,964,297", "812,442,681,755,387,354,607,558,604,923,503,214,558,646,970,950,872,49,825,775,211,87,434,825,563,407,495,736,929,763,711,276,439,229,199,424,44,874,592,430,252,128,625,492,211,391,92,248,462,441,912,50,297,904,993,885,540,804,104,860,149,48,226,578,298,80,572,701,243,241,564,650,703,247,674,292,877,768,973,500,946,355,556,634,24,656,77,11,380,813,114,948,839,263,202,603,216,13,694,330,697,509,11,554,473,232,553,735,981,759,802,323,939,542,539,845,728,602,295,838,448,888,690,108,956,673,232,656,369,592,161,426,469,781,424,276,940,376,341,172,368,604,83,960,13,354,718,759,986,12,261,421,91,347,163,363,342,716,449,974,130,473,687,359,629,374,558,300,159,730,776,82,277,82,209,801,669,130,849,765,482,522,181,65,332,906,939,434,281,818,905,874,34,698,431,397,119,331,556,815,835,656,21,264,374,12,393,826,871,488,290,173,187,609,196,325,146,554,887,945,793,953,716,888,26,901,363,794,26,794,850,105,724,815,802,50,14,280,379,225,124,664,220,234,313,394,125,656,301,930,643,771,249,604,103,109,551,435,743,518,147,735,514,501,795,888,204,55,727,626,735,790,432,872,378,434,937,281,153,116,98,696,77,636,533,561,819,722,448,626,595,664,283,684,379,683,498,798,908,745,955,940,71,424,165,895,200,101,534,862,720,983,441,459,151,596,248,501,650,958,86,41,19,808,917,413,900,977,927,991,314,479,699,287,27,220,532,223,0,311,402,756,440,279,175,727,187,156,840,582,108,951,944,709,280,492,21,861,770,983,644,264,808,985,833,695,649,893,303,605,441,910,565,763,475,198,425,835,216,803,617,541,142,315,137,852,234,120,404,607,866,447,709,292,940,80,628,976,765,386,389,891,790,495,201,817,10,823,114,986,728,349,992,112,828,276,379,436,561,849,654,961,958,719,32,321,10,523,225,384,559,477,926,576,312,525,701,984,595,963,702,573,113,785,760,959,130,746,22,466,958,719,349,700,654,336,325,703,92,72,427,616,220,965,32,408,72,801,850,543,949,353,496,512,974,786,956,406,812,286,252,355,878,412,765,197,364,614,442,342,926,770,476,699,468,54,445,521,343,518,910,990,747,655,667,78,320,603,3,491,375,596,270,37,363,884,237,297,723,264,565,990,914,809,946,216,871,872,605,451,184,783,594,930,21,373,808,187,626,785,994,938,465,927,886,515,234,214,300,257,130,800,324,820,601,745,955,699,805,549,394,865,634,617,497,942,526,579,291,899,221,150,798,947,606,813,566,230,264,988,760,148,934,368,306,930,638,947,293,570,609,456,118,94,396,358,114,74,154,91,677,596,963,33,61,552,242,267,584,878,141,915,895,960,38,939,444,534,614,881,418,340,448,343,264,728,828,206,318,781,187,317,871,700,881,131,836,507,552,761,528,783,876,119,279,544,543,256,295,17,782,766,187,461,659,438,67,671,339,158,685,312,22,416,385,526,30,238,594,216,571,95,768,85,713,34,696,724,290,956,578,757,993,242,632,431,167,395,770,245,407,793,659,643,635,884,741,564,596,277,39,276,669,250,417,761,695,205,153,710,885,716,725,547,259,352,405,23,159,429,999,604,982,995,97,681,912,92,744,90,271,749,91,17,262,237,819,144,556,748,209,210,188,687,439,347,388,915,412,161,729,533,298,648,123,595,651,957,233,828,47,428,620,234,513,806,750,301,747,39,529,684,857,556,632,985,518,710,430,179,23,694,158,992,244,225,591,104,874,342,482,447,656,605,89,644,751,314,727,916,504,892,439,482,251,594,772,369,344,300,18,668,538,145,549,646,938,655,954,462,291,347,556,233,548,908,90,609,835,55,832,664,915,513,330,858,548,144,418,712,727,844,634,402,45,867,689,881,119,604,805,164,313,546,615,870,191,848,239,934,691,610,877,717,158,549,484,159,220,372,854,297,448,435,180,586,870,361,457,529,956,465,236,306,852,469,306,306,157,539,450,704,802,817,870,688,911,158,211,6,242,476,685,628,922,492,579,226,189,599,451,429,536,474,36,309,746,135,725,661,114,975,288,358,608,33,29,805,979,535,711,86,802,292,664,751,987,303,797,114,906,238,599,760,593,692,399,33,583,190,719,928,392,781,262,905,608,50,224,303,235,397,694,331,689,505,419,280,304,98,482,388,157,577,7,457,158,174,260,540,302,522,584,251,519,244,973,395,938,271,619,266,218,581,967,744,401,410,469,711", "561,380,417,484,14,102,385,732,806,764,431,49,300,924,621,273,781,539,27,572,251,8,94,296,764,586,751,7,534,653,33,6,918,445,673,408,923,580,802,342,947,192,953,818,100,905,317,991,954,330,641,67,714,800,402,223,68,502,107,349,158,671,629,314,352,302,574,497,897,2,458,131,783,60,513,685,587,407,628,427,518,830,749,580,611,518,865,510,48,703,366,362,857,649,761,646,305,113,645,572,672,355,661,875,682,964,640,314,4,119,21,296,727,280,987,991,62,294,111,813,323,789,972,322,641,773,666,241,934,660,403,687,273,604,796,730,502,258,943,488,204,754,77,620,395,655,900,55,41,388,952,231,496,623,779,496,794,798,196,777,828,630,772,126,566,141,356,193,211,361,168,918,550,451,590,967,728,220,757,713,770,265,601,664,298,854,950,953,851,429,449,960,689,748,731,756,380,337,45,884,478,427,592,906,933,536,125,414,815,949,204,932,351,297,579,735,640,229,498,699,689,892,862,476,465,848,157,681,96,575,279,143,596,328,438,864,731,765,830,30,997,240,292,496,156,21,506,355,682,855,179,835,483,190,857,422,919,647,981,246,825,966,236,270,331,340,137,203,369,959,400,651,313,283,460,975,220,671,200,924,632,219,814,424,525,659,538,164,342,881,533,6,867,338,93,547,101,980,25,275,652,841,234,735,909,638,154,286,813,174,830,884,361,830,227,756,194,212,894,698,855,263,546,304,486,792,588,505,975,445,839,774,747,154,808,673,843,33,311,0,117,713,969,430,196,204,940,494,578,948,616,608,802,10,244,630,954,720,564,946,649,709,724,361,941,261,48,107,670,95,345,115,640,685,795,139,629,742,241,821,101,736,626,790,984,908,590,629,739,673,140,394,721,268,396,107,262,886,469,513,942,708,471,202,118,586,585,607,612,416,724,762,833,188,284,82,225,961,233,820,652,365,701,139,741,999,692,933,212,691,309,136,50,515,580,961,706,205,410,251,298,909,376,119,799,100,10,286,133,551,454,596,42,627,184,505,631,769,640,742,456,623,708,414,428,216,304,198,263,164,740,118,553,79,32,117,769,889,771,760,827,641,365,394,243,867,599,160,545,411,691,21,414,130,369,526,484,440,466,126,958,178,131,456,694,716,696,58,422,754,749,342,114,308,559,840,621,114,283,646,483,389,288,972,14,570,115,699,941,650,522,612,665,901,332,190,420,338,326,965,967,470,739,30,847,492,142,237,37,314,747,551,537,368,378,446,626,893,980,184,178,442,839,702,975,130,645,778,946,564,514,744,709,945,878,222,980,715,618,442,347,817,314,528,301,254,417,980,238,529,992,363,309,26,997,274,986,297,187,8,587,348,228,76,641,60,883,627,804,551,872,901,828,970,949,764,288,892,898,256,518,597,563,342,805,392,5,422,836,48,380,658,330,865,109,533,628,445,182,15,17,757,35,701,261,919,636,183,889,729,856,511,791,321,895,107,680,619,914,655,775,670,966,568,650,674,500,462,946,348,560,334,236,852,210,53,284,611,666,979,847,611,516,194,654,895,471,539,557,126,312,479,400,182,135,582,332,870,637,190,944,158,738,228,309,867,318,423,14,744,599,220,386,400,559,112,945,241,320,534,402,223,42,172,204,268,253,694,781,330,466,173,268,821,634,434,940,797,329,926,187,789,504,34,886,979,488,36,888,242,544,187,483,149,269,549,86,250,141,914,64,298,284,196,430,551,964,633,171,794,163,831,656,549,320,577,620,783,702,280,640,137,647,155,162,751,386,866,776,360,850,576,45,171,12,947,338,914,611,447,279,187,744,76,719,494,404,284,610,625,441,558,274,637,504,666,479,315,396,726,904,392,954,723,449,610,114,783,935,258,971,208,531,861,91,858,798,233,913,733,564,379,270,217,969,980,628,997,882,354,509,406,674,116,47,413,757,257,420,864,886,812,661,795,740,426,534,520,189,170,132,372,370,489,813,79,486,811,902,226,492,985,213,556,645,762,408,910,457,831,269,817,548,802,158,377,315,700,439,221,812,544,314,133,716,932,65,596,767,581,344,897,33,897,17,425,590,8,723,558,87,27,359,643,143,600,957,859,452,919,968,9,375,770,407,997,458,604,672,601,323,398,900,456,60,248,795,233,908,540,440,701,929,670,577,812,665,971,278,557,349,171,433,336,196,39,529,445,194,478,666,91,759,467,87,276,821,416,155,995,182,840,114,821,989,620,414,23,790,416,921,758,467,763,949,801,655,720,911,232", "49,478,257,103,354,382,80,377,910,249,117,866,429,388,307,254,695,976,441,527,364,969,996,978,857,87,616,921,631,504,555,914,247,164,325,691,966,507,821,861,154,194,31,327,44,854,532,899,453,262,376,590,894,452,543,170,164,904,821,525,118,58,508,339,462,546,560,209,856,20,119,660,814,248,630,33,185,894,631,642,1000,247,966,530,477,730,48,78,665,921,214,569,516,743,813,827,96,378,889,892,163,548,890,765,110,795,70,180,971,610,82,519,926,724,199,905,60,515,135,484,325,691,996,601,892,864,597,829,954,883,782,142,634,823,699,899,740,905,816,593,73,481,846,646,740,667,683,420,617,334,405,663,764,116,184,583,657,561,153,897,980,279,920,269,975,971,282,51,928,781,655,167,625,689,899,34,859,946,784,863,442,888,808,526,234,79,408,93,955,768,984,483,66,931,300,805,517,99,647,501,668,707,718,899,800,958,612,512,464,881,252,355,889,766,998,563,605,954,831,91,1000,140,628,118,833,612,295,586,580,73,202,485,504,406,523,604,352,486,887,805,349,482,341,256,511,5,140,326,123,185,867,881,480,670,436,816,512,770,628,172,581,500,187,182,513,143,846,546,622,463,241,973,281,995,59,314,645,209,774,495,343,98,681,156,657,939,968,200,995,311,655,738,526,471,83,677,341,839,983,230,861,638,311,85,152,967,671,719,632,392,843,408,23,211,407,353,942,744,860,392,969,265,142,560,376,280,795,983,112,171,107,291,563,330,551,881,213,721,402,117,0,803,293,796,132,734,294,873,327,831,442,466,961,242,860,59,628,609,749,4,762,523,709,134,777,18,761,209,104,741,495,716,409,235,173,114,480,496,549,996,728,341,159,698,23,774,897,595,682,365,621,680,736,496,685,329,109,706,172,90,961,265,844,837,806,362,999,796,809,672,887,512,78,454,685,465,289,251,868,26,777,260,115,117,488,4,696,95,985,833,377,533,64,551,566,909,475,950,658,602,671,155,165,590,615,876,187,721,932,64,178,140,856,910,62,605,890,141,523,884,651,47,618,186,911,353,854,967,483,362,937,47,22,341,767,155,543,43,151,765,838,851,529,463,619,751,874,461,93,344,336,215,974,603,276,551,946,421,845,157,579,483,409,892,581,424,891,379,367,980,905,485,679,528,804,650,863,941,712,433,22,485,809,888,230,93,801,576,545,110,409,290,380,131,130,841,52,646,513,709,222,199,318,492,20,269,753,333,966,401,574,167,339,335,343,812,448,59,727,368,624,157,129,859,448,432,600,833,97,663,901,230,743,343,885,963,728,216,845,84,430,75,136,325,858,178,160,136,281,954,706,785,860,691,592,449,514,937,349,548,319,97,123,185,314,151,498,362,579,96,830,561,813,718,352,381,534,903,593,612,31,915,937,119,331,525,914,534,795,801,352,433,624,995,545,874,966,803,247,443,238,86,298,72,184,738,218,283,823,872,889,407,908,746,633,675,245,48,132,103,513,525,198,453,826,135,866,184,137,354,335,684,739,192,132,847,313,403,897,672,792,704,663,226,936,99,568,38,612,709,805,217,335,661,308,426,873,165,754,970,902,491,87,563,753,948,228,556,658,570,753,435,812,550,173,236,703,234,191,415,576,314,791,971,577,845,334,67,210,852,939,91,582,714,97,713,967,800,163,278,489,493,336,336,172,612,588,697,439,258,150,150,375,268,541,77,969,595,744,692,705,78,38,592,767,754,340,725,66,804,653,50,750,506,905,549,208,670,151,862,957,547,744,787,450,782,752,839,454,167,936,671,185,823,102,715,21,164,156,424,27,562,626,384,46,970,821,857,482,270,151,547,236,669,959,633,690,590,66,968,800,430,893,413,565,302,747,594,985,548,645,816,486,198,6,871,696,479,793,386,928,708,242,448,826,485,526,411,696,302,230,300,417,960,868,958,286,968,829,275,556,907,340,305,297,926,860,55,448,636,341,616,235,737,725,857,564,44,820,100,63,692,537,84,57,74,271,454,162,696,737,593,622,274,581,493,718,122,224,410,183,297,858,733,49,70,733,933,993,970,384,709,767,340,624,233,829,287,593,812,704,375,451,273,880,332,190,280,326,265,157,274,464,416,363,116,757,67,504,262,859,916,331,392,959,888,349,36,464,369,886,521,887,351,180,955,147,704,886,672,336,747,426,872,575,764,997,775,185,214,777,693,478,412,809,557,323,26,415,661,381,257,202,444,142,961,826,248,843,937,340,833,689,352,228,438,488,826,107,711", "248,682,492,720,780,937,880,821,349,734,206,885,354,955,621,976,520,420,441,193,15,946,801,102,880,906,786,939,159,318,651,995,131,317,728,302,365,211,351,441,96,149,987,342,562,697,165,702,670,625,379,315,959,2,422,10,359,299,169,895,514,878,870,612,111,665,385,697,367,317,923,926,303,25,726,399,465,23,657,197,6,615,212,343,143,430,428,869,765,511,492,403,949,2,68,993,853,252,929,498,242,203,696,144,344,855,969,120,206,224,204,27,346,980,206,547,452,242,318,995,259,455,633,524,722,90,532,919,859,560,238,270,919,884,529,633,563,536,399,722,615,11,716,832,663,272,382,728,693,304,346,799,429,144,860,215,112,355,221,712,746,681,442,528,475,984,593,673,925,428,350,640,449,957,680,145,548,237,864,100,590,763,109,943,231,64,398,859,462,503,204,725,109,810,794,899,973,759,893,436,895,809,440,696,90,460,11,205,548,985,686,340,970,860,914,437,713,821,100,773,679,715,93,208,6,466,761,607,594,631,750,699,928,923,872,866,554,696,331,217,184,959,829,587,419,125,617,227,156,86,952,529,383,742,577,186,808,182,627,264,245,173,208,329,36,561,304,916,129,986,386,100,857,926,988,672,624,309,821,614,638,254,570,234,649,986,61,382,659,426,579,690,249,477,937,827,869,917,241,503,565,569,154,925,368,962,305,33,536,674,267,739,692,937,685,867,674,383,580,397,152,583,626,678,549,334,488,305,802,836,128,560,577,648,387,749,448,860,756,713,803,0,333,936,619,544,877,927,734,309,927,157,124,428,942,6,277,799,239,802,218,774,109,786,152,566,742,317,476,227,190,122,557,408,458,949,908,368,454,197,62,342,11,471,553,983,543,726,952,142,417,110,590,380,737,629,832,437,289,297,656,502,620,278,819,990,795,491,577,178,215,597,221,728,399,288,508,863,863,747,228,387,562,711,71,205,19,933,776,352,561,779,660,409,828,734,216,45,774,626,361,910,125,387,844,73,206,516,866,103,78,407,96,916,588,719,978,651,346,648,603,815,350,162,528,279,920,743,260,878,128,442,720,821,665,341,113,800,386,156,307,85,403,645,438,670,685,147,194,433,563,507,876,212,724,282,425,804,176,995,914,248,260,646,536,33,764,427,219,256,208,301,989,719,822,84,449,736,794,39,574,934,982,532,571,963,694,238,38,953,585,581,522,147,255,20,92,951,890,500,533,678,361,687,624,741,763,384,697,362,474,424,278,668,697,620,305,897,339,167,185,205,152,983,364,12,787,106,86,105,466,817,658,700,731,459,340,381,458,542,522,970,829,740,231,856,316,844,908,972,199,517,263,828,168,543,143,689,547,372,110,772,31,249,218,940,978,262,726,973,536,123,137,309,608,466,769,798,933,343,43,923,177,198,884,705,762,786,459,110,825,9,720,857,499,875,855,171,429,114,353,741,404,924,753,203,112,918,711,570,535,541,41,402,729,465,560,680,686,237,567,319,686,285,908,687,958,52,77,706,412,651,803,415,560,802,613,483,538,967,698,46,326,262,678,59,998,424,168,39,345,126,582,784,889,99,123,79,371,177,346,972,329,470,751,153,792,140,942,507,808,164,429,876,986,117,647,827,469,528,863,865,943,704,485,965,502,659,870,956,468,191,890,662,300,446,858,538,328,497,870,366,408,506,246,470,326,968,109,75,300,295,436,162,542,727,617,678,306,381,888,914,202,193,284,491,624,319,503,901,881,945,44,942,653,664,778,604,738,213,944,52,874,309,375,938,975,994,627,727,334,770,674,467,151,290,226,147,111,296,889,341,198,200,698,111,564,895,231,44,315,629,20,402,316,820,290,329,146,115,927,935,691,121,908,676,968,973,199,298,307,567,614,938,247,426,467,205,478,846,698,147,923,426,423,473,335,208,653,875,659,772,587,780,193,671,988,402,223,17,645,545,230,150,940,955,72,80,861,551,802,531,34,728,612,672,148,946,810,818,485,194,441,243,925,570,831,947,759,563,905,152,216,391,389,483,810,902,801,775,677,808,129,498,847,868,72,199,153,916,706,169,289,985,234,817,96,235,963,30,7,945,939,336,730,4,728,800,468,409,432,682,436,551,57,10,892,850,922,450,697,166,703,972,603,44,164,929,249,227,706,697,945,996,76,362,977,823,376,491,965,617,411,715,960,739,500,86,629,595,197,596,685,2,489,615,378,699,35,63,616,27,320,354,623,853,163,816,420,700,917,527,456,846,653,349,342,360,653,208", "826,218,881,541,507,739,586,462,365,52,295,244,760,933,903,671,351,244,25,962,874,29,267,151,333,390,920,248,841,313,599,468,690,653,466,990,645,284,914,731,924,920,876,303,236,123,133,611,253,702,434,191,56,417,930,667,919,502,120,677,866,182,450,296,182,408,166,569,732,348,995,651,380,245,511,813,891,247,709,466,59,707,651,469,68,79,519,171,48,714,561,887,703,576,891,901,214,943,824,756,946,136,23,633,469,465,889,608,564,504,303,944,952,609,95,202,820,801,246,893,645,721,736,854,106,170,152,679,948,115,178,651,726,438,371,731,889,468,278,746,540,408,593,98,659,651,708,451,997,930,983,490,850,996,612,970,212,49,882,369,701,7,447,649,372,570,146,828,294,100,88,893,266,779,518,362,818,174,326,580,992,828,790,118,193,417,235,269,481,993,649,258,915,404,183,84,547,603,718,676,146,6,771,497,816,240,770,222,243,763,689,792,341,257,63,652,658,202,536,210,841,813,320,477,114,975,690,325,282,559,609,266,489,732,814,425,8,657,922,596,565,196,382,887,214,757,420,287,759,152,565,565,845,943,5,541,848,245,986,929,406,401,959,491,670,687,988,253,749,450,620,428,522,450,360,208,618,83,374,394,695,76,558,152,138,35,793,264,278,703,663,758,327,672,296,49,592,635,877,975,320,696,280,374,626,326,943,773,791,783,775,231,502,759,702,178,291,135,439,443,291,483,28,978,740,710,827,596,801,411,924,954,731,648,715,439,714,662,440,969,293,333,0,16,801,658,763,9,983,913,740,506,919,236,922,630,591,878,823,877,816,684,137,9,569,409,173,143,919,710,140,993,133,340,505,325,511,831,453,409,420,663,379,54,635,276,73,878,215,305,28,871,75,826,409,172,243,698,628,190,296,662,534,119,188,595,663,414,484,653,497,388,314,60,664,891,367,886,434,573,886,655,811,729,963,262,152,757,579,527,558,773,206,469,518,428,817,465,996,319,834,179,533,866,900,476,566,432,301,530,443,681,184,912,273,173,356,390,513,247,881,294,690,195,790,533,511,931,536,689,264,84,605,327,699,320,146,203,257,989,124,849,213,919,108,92,471,197,194,236,181,577,158,138,76,37,624,645,145,101,221,371,762,430,551,862,357,557,723,508,24,798,431,422,89,155,974,585,321,351,328,349,166,231,388,162,300,472,144,759,710,399,151,281,16,509,688,675,55,304,904,305,16,405,289,611,626,313,600,133,938,299,498,740,243,792,722,156,641,450,801,609,253,190,723,816,711,932,793,708,445,287,430,804,763,805,627,452,343,898,480,981,267,412,38,638,138,105,396,913,310,674,419,304,781,967,63,913,927,81,21,350,761,185,288,152,532,480,958,35,242,190,254,880,623,328,512,552,474,485,794,462,416,652,805,705,751,506,189,878,586,18,603,205,423,200,741,747,247,822,135,552,862,210,857,191,583,249,944,626,23,820,493,484,451,662,282,705,855,540,417,533,894,405,523,120,53,234,827,100,920,438,994,67,529,778,641,629,815,645,193,596,418,42,618,434,610,144,111,376,680,504,546,829,92,945,655,624,795,502,635,109,961,832,911,256,473,456,84,19,767,689,282,297,776,213,255,509,900,83,687,829,326,291,778,719,482,653,973,896,480,757,454,803,973,764,886,886,949,777,609,139,18,295,889,776,156,665,990,58,988,643,61,719,833,501,238,364,468,918,334,845,762,245,118,166,377,782,594,80,356,216,844,847,180,73,939,742,313,158,392,549,415,252,288,563,964,734,237,998,596,552,275,510,44,771,453,783,529,5,408,308,650,681,267,806,852,719,135,346,378,342,830,641,36,561,56,23,134,498,574,826,208,313,596,883,296,343,623,151,468,965,923,55,363,20,570,853,204,674,149,501,575,589,311,563,972,37,237,365,659,313,682,358,883,894,33,778,865,62,358,404,412,806,765,146,646,984,542,182,996,271,112,227,79,672,924,56,533,851,349,520,633,576,456,198,54,338,658,200,528,219,723,173,541,169,652,929,386,101,871,952,370,871,243,545,30,387,880,2,490,999,884,104,738,955,876,786,907,398,295,221,447,345,34,492,573,422,99,737,630,161,887,393,519,996,110,531,108,46,382,586,193,218,734,355,724,343,732,23,274,612,748,344,736,736,231,702,197,826,682,878,425,849,269,837,388,356,567,385,986,711,447,16,457,11,523,446,144,398,459,102,862,350,256,400,616,179,162,808,318,785,271,798,963,164,473,776,508,201", "682,350,511,355,305,149,930,46,911,37,637,411,809,773,917,937,158,243,579,295,138,147,775,264,905,971,129,141,762,438,866,721,564,137,684,253,337,759,592,87,965,741,239,241,635,46,481,825,152,419,458,611,233,114,263,729,357,872,432,47,280,848,454,878,116,804,239,86,820,178,571,295,966,385,454,677,208,667,295,268,1000,626,641,194,16,543,278,327,468,414,733,402,112,125,784,620,435,901,886,435,657,289,630,611,700,944,787,878,422,149,855,304,459,308,818,956,735,296,636,195,545,895,991,872,878,485,838,382,371,926,950,975,12,862,807,301,765,587,321,130,390,173,394,768,941,559,60,333,452,748,272,867,711,705,944,554,753,342,197,27,51,25,626,883,818,193,425,823,215,825,84,232,592,114,502,677,535,120,886,897,873,686,671,666,769,6,117,421,747,977,82,684,435,747,802,73,138,878,718,13,51,100,711,355,516,691,674,66,502,297,488,66,932,924,178,681,344,963,765,186,341,699,515,375,569,883,939,35,529,999,273,716,779,315,280,386,453,106,753,22,476,467,427,800,964,970,586,396,47,428,682,252,361,427,641,153,214,732,756,84,54,952,447,149,811,86,682,379,871,608,146,212,960,674,144,156,308,718,505,295,30,639,859,956,19,510,295,723,790,955,453,692,385,754,60,182,555,257,944,228,909,462,654,889,614,216,511,113,510,539,933,102,252,689,296,96,371,386,798,705,927,825,935,668,295,451,409,982,9,320,781,907,905,494,509,212,348,819,279,430,796,936,16,0,947,743,742,67,593,605,623,635,454,577,921,595,637,946,765,268,483,719,588,570,838,646,552,53,298,786,412,135,230,826,782,796,73,373,766,126,745,687,287,916,404,298,255,946,580,965,600,31,96,188,5,726,219,749,645,928,134,113,597,128,672,455,375,929,537,863,889,123,969,787,36,733,747,127,587,800,989,203,165,774,332,143,787,64,194,885,505,224,298,480,319,635,487,623,317,609,675,735,234,72,670,448,223,59,665,923,836,71,863,238,621,931,358,256,440,455,330,392,118,283,232,242,100,838,761,17,138,715,224,814,496,931,847,742,319,198,998,88,414,547,598,776,919,396,74,946,330,378,152,357,840,302,570,125,376,998,659,872,806,235,330,331,705,599,766,227,453,68,170,920,413,365,599,26,40,609,364,91,724,70,104,365,715,359,42,10,424,466,638,369,287,154,922,126,465,997,127,811,331,996,977,441,261,816,79,704,402,170,185,941,355,478,795,382,307,719,567,70,925,545,298,832,709,395,645,402,413,665,977,429,321,899,977,882,416,666,941,259,931,244,276,461,712,703,948,612,630,197,25,595,68,151,679,556,596,755,197,391,676,998,735,792,730,565,175,307,773,412,342,327,209,429,784,725,828,714,851,873,246,619,598,363,615,912,637,579,940,138,119,552,262,89,779,296,73,453,622,742,599,725,848,448,308,175,859,40,761,163,235,702,643,189,930,847,187,44,66,952,95,625,7,936,232,552,915,838,284,344,915,76,614,540,154,258,723,541,343,486,248,182,12,317,102,996,945,713,102,165,89,944,482,508,418,495,662,110,442,604,732,426,145,400,230,940,907,125,212,196,627,821,550,920,672,952,491,833,151,272,208,101,228,769,812,154,225,36,22,357,236,470,333,273,681,221,220,613,900,266,483,743,741,611,516,545,323,985,800,888,189,654,736,739,619,878,681,476,345,26,170,1000,58,259,660,512,205,902,213,491,220,764,668,293,237,332,284,235,388,614,560,184,626,608,236,813,419,221,566,656,148,758,622,570,74,287,302,259,729,387,530,499,241,619,81,885,763,48,772,658,542,736,90,41,218,339,425,501,867,943,915,940,497,30,725,730,548,747,442,989,390,893,586,851,448,858,564,667,272,71,157,102,846,443,878,89,654,480,156,23,688,240,241,327,526,391,472,783,648,293,482,138,403,11,268,686,243,978,776,363,954,899,53,371,102,393,562,282,559,173,722,315,965,548,874,782,276,723,585,237,776,631,368,838,612,510,443,72,112,367,238,956,148,309,89,816,164,293,175,714,391,451,735,349,922,6,163,912,490,811,744,971,5,934,530,652,553,875,229,959,995,561,651,640,800,539,121,818,826,649,294,106,200,127,479,629,774,243,195,18,624,749,284,678,15,195,390,961,24,452,842,921,690,117,212,366,210,685,850,660,889,128,368,341,700,274,244,742,477,118,963,179,557,306,849,953,504,776,681,131,305,799,267,942,371,963,680,18", "598,355,86,467,462,732,860,327,363,886,815,123,272,856,606,89,24,847,272,794,439,449,739,224,985,359,966,909,688,859,879,97,334,952,48,950,161,737,894,886,563,864,244,205,55,506,807,310,159,168,937,599,658,338,482,142,816,854,147,158,105,720,117,861,802,738,671,350,565,34,4,620,56,788,869,536,288,697,456,797,899,230,305,858,225,19,671,867,166,156,599,705,358,173,695,368,172,897,142,42,526,457,688,251,375,410,480,43,802,966,64,633,269,783,997,369,579,243,372,513,255,741,491,466,484,241,881,34,824,943,610,148,57,934,417,709,360,259,778,751,29,21,412,257,114,328,976,855,168,545,339,55,672,582,110,735,226,447,266,874,643,718,645,262,423,748,717,873,748,523,941,604,58,929,579,448,134,485,431,855,767,209,791,133,514,216,446,308,661,440,517,298,568,611,174,374,130,885,598,948,147,844,953,11,206,54,85,556,751,748,314,793,170,137,312,342,619,390,649,962,307,550,25,306,661,784,959,116,222,468,812,476,685,580,379,575,584,98,356,391,274,180,37,899,457,705,924,456,481,658,344,868,877,527,886,579,469,564,926,521,690,434,220,101,752,938,211,580,162,156,310,226,865,807,823,976,353,72,747,950,193,873,578,1000,953,502,993,574,978,453,582,813,34,472,985,50,978,229,320,298,952,274,314,510,240,594,678,672,478,896,564,677,148,487,451,368,314,44,648,539,904,618,927,777,832,87,410,728,435,770,864,709,666,703,200,662,126,522,175,196,132,619,801,947,0,620,111,197,137,359,422,53,34,690,138,856,998,458,70,99,142,75,672,175,711,991,890,767,26,640,216,988,550,611,688,739,531,217,788,311,214,630,220,427,352,745,225,151,504,84,812,687,505,689,225,223,955,889,963,205,259,673,398,608,636,256,544,194,895,900,793,349,595,412,566,268,902,144,815,515,174,41,310,485,71,879,209,68,984,732,537,166,625,383,586,715,172,885,323,964,888,305,936,346,640,52,129,886,645,222,415,506,17,298,486,352,125,279,465,156,640,269,179,934,570,775,442,803,716,963,793,32,623,991,112,797,84,620,296,76,115,737,372,788,150,862,610,38,382,823,725,400,989,462,746,372,334,226,347,72,678,331,407,5,630,933,415,729,68,287,883,90,963,751,828,72,718,257,300,839,513,386,846,350,977,467,708,435,267,448,812,856,833,716,754,961,786,766,726,444,528,449,927,844,946,573,915,654,262,823,19,608,499,895,683,501,445,190,257,512,639,256,447,591,86,868,658,945,351,902,190,882,12,299,543,30,91,454,370,311,921,527,602,153,363,924,71,434,738,750,177,646,395,94,399,379,176,13,405,129,19,326,920,653,6,115,168,727,458,850,980,198,448,4,737,771,112,596,496,533,468,93,559,222,753,968,899,857,150,913,295,169,105,899,616,438,134,688,679,460,595,256,979,622,159,373,617,866,486,295,2,284,524,720,384,244,195,194,872,569,955,659,887,617,400,660,207,674,769,38,52,280,237,755,50,915,297,763,588,954,381,912,493,347,650,742,471,927,439,73,67,128,694,645,796,647,227,620,636,433,213,507,167,28,318,533,962,944,150,536,945,840,375,278,966,330,111,127,984,138,205,697,33,965,398,636,399,726,546,618,447,205,949,605,619,263,945,354,125,412,776,675,944,825,125,682,126,269,169,668,240,169,843,272,177,405,110,832,702,788,910,152,150,609,436,126,946,296,375,605,266,505,553,426,228,114,315,914,517,938,960,104,551,373,225,876,775,749,879,374,521,412,318,410,671,306,937,532,341,258,222,533,489,571,749,111,837,901,218,697,150,535,547,258,30,975,367,265,718,719,292,609,911,422,284,615,295,28,479,158,410,496,948,251,959,569,407,141,543,209,336,326,205,527,797,891,625,928,292,290,820,888,211,198,475,908,677,804,731,823,316,992,320,185,198,98,487,894,334,58,633,41,501,771,708,609,297,534,869,18,716,527,594,768,588,21,242,857,76,135,257,278,149,602,324,219,505,125,350,604,879,248,677,987,19,556,683,928,32,203,505,264,816,491,33,451,861,87,328,845,146,385,852,452,424,10,867,356,579,593,550,614,141,382,438,269,376,173,707,784,444,599,743,157,640,515,903,618,800,310,829,424,827,884,926,207,482,895,957,666,465,640,975,784,301,319,691,54,524,177,256,671,584,758,932,941,410,729,679,913,616,478,943,276,351,318,212,57,36,22,917,285,567,343,430,421,751,653,591,154", "900,533,105,478,897,597,162,46,539,981,756,105,102,796,585,567,649,36,366,1,552,396,345,627,62,313,949,754,780,956,586,884,511,697,929,167,741,241,67,421,968,414,111,440,703,470,137,224,629,311,179,495,67,276,316,361,329,918,101,61,495,671,138,213,59,134,481,794,513,493,342,572,979,374,973,131,427,834,615,989,828,492,583,409,474,531,282,238,352,393,981,43,763,830,15,893,476,218,84,831,871,680,438,2,609,889,318,199,759,640,976,842,86,630,400,561,878,894,68,608,716,248,780,579,948,10,875,904,922,748,144,420,144,682,861,90,712,22,559,352,774,74,889,967,414,357,901,216,921,647,848,915,551,379,158,669,684,678,228,113,118,192,930,849,722,663,630,190,991,844,869,95,73,917,317,617,654,837,938,925,950,135,404,255,462,662,279,894,110,685,142,992,446,286,76,36,479,885,139,48,872,126,78,464,847,198,162,250,462,581,368,609,527,448,533,291,170,784,942,601,848,103,442,672,316,164,595,21,306,640,569,738,291,64,886,22,168,220,904,258,889,696,339,549,687,815,629,403,755,915,373,952,835,234,128,837,993,758,935,260,95,886,435,669,121,722,840,206,420,616,472,935,75,628,799,676,733,497,796,90,494,574,546,162,759,629,750,948,321,946,56,589,842,477,308,894,716,298,871,180,221,710,679,737,765,663,176,712,944,961,583,911,631,910,971,837,828,9,781,806,246,227,665,386,414,734,400,228,832,999,529,577,53,6,695,658,50,63,727,204,734,544,658,743,620,0,894,397,422,705,954,921,322,307,520,654,619,161,594,769,712,590,918,825,945,787,505,486,839,87,427,112,405,997,191,142,450,736,317,632,177,913,819,9,218,78,942,468,858,163,707,567,806,650,367,383,577,496,941,375,543,822,528,182,772,685,356,815,87,608,671,313,815,712,924,975,421,852,766,745,257,590,459,233,770,621,259,65,70,788,813,740,911,893,433,873,390,393,327,353,158,986,72,789,363,182,17,859,795,978,803,41,14,171,361,452,546,24,113,671,526,894,785,564,636,890,233,98,631,768,397,732,107,575,332,485,216,511,563,213,300,973,234,771,899,178,186,356,399,962,299,332,789,527,627,790,399,955,108,915,77,201,618,615,854,212,119,883,704,305,122,716,518,35,757,229,842,231,11,237,864,567,600,553,970,680,547,330,865,767,443,257,467,310,644,97,479,135,577,965,978,935,618,904,231,514,244,716,125,192,679,113,826,493,290,703,761,287,109,248,752,895,713,968,62,979,795,725,854,513,991,436,602,860,624,444,430,715,240,308,804,766,612,672,963,488,619,427,235,192,635,201,602,42,944,96,464,108,119,631,69,708,101,30,423,108,113,356,529,962,746,66,928,127,570,513,714,595,260,577,420,628,958,473,800,317,618,262,984,289,668,713,246,69,394,190,803,466,128,593,361,900,45,680,304,618,945,568,42,522,575,618,832,551,771,286,629,379,797,116,891,243,340,123,314,956,859,127,355,140,565,549,229,348,735,824,665,523,941,246,206,63,242,103,693,487,225,836,606,545,557,184,303,732,409,359,870,231,485,594,998,129,855,583,785,312,56,480,192,893,513,992,937,67,954,854,782,700,514,911,156,643,209,828,414,340,877,140,98,905,266,722,146,22,758,111,278,678,690,798,773,441,254,566,498,500,622,501,78,587,141,605,301,906,580,954,599,995,289,379,833,532,206,557,222,212,598,832,858,435,361,500,884,401,339,495,461,595,344,815,107,895,980,514,243,369,997,541,498,585,957,420,736,200,102,216,611,969,992,278,156,989,584,416,416,640,473,435,272,156,506,626,193,863,112,381,664,518,806,205,383,269,707,663,304,585,279,72,200,668,807,733,655,47,944,781,327,49,575,995,137,670,868,112,90,145,85,758,285,308,743,816,856,713,542,984,263,821,71,140,511,161,156,359,399,505,869,250,770,7,110,602,890,897,924,108,596,341,896,251,361,73,125,376,976,411,49,995,195,881,518,421,753,523,36,612,88,298,217,892,481,213,790,847,54,982,513,25,782,162,42,968,429,331,377,708,511,97,334,422,756,889,627,254,144,768,890,780,734,564,517,714,667,237,456,87,376,178,299,470,625,65,363,115,749,599,407,803,554,311,821,270,790,693,780,201,414,938,369,64,66,146,219,336,993,715,643,578,937,271,589,452,431,417,297,641,975,441,191,3,843,532,532,205,831,371,966,289,524,828,803,975,35,987,393,932,767,796,76,88", "239,870,262,787,623,236,509,1000,768,178,216,565,948,209,913,348,587,477,28,396,488,146,528,538,971,318,560,830,131,904,61,853,416,641,662,122,79,86,429,254,900,829,103,614,600,522,592,630,630,198,258,52,113,466,182,850,303,32,373,91,594,327,468,260,139,350,431,614,875,810,90,386,849,98,947,277,212,385,223,770,381,299,559,160,871,233,740,344,506,84,248,357,380,241,552,345,163,732,387,389,838,545,419,503,10,989,362,320,705,310,122,586,174,805,459,502,443,193,317,362,746,546,654,950,594,528,289,934,527,925,797,749,809,702,764,36,908,505,52,161,538,739,291,346,511,305,505,253,131,329,621,958,252,132,638,56,732,619,220,450,143,261,614,121,191,373,958,118,320,802,825,737,696,559,105,68,645,541,898,971,116,428,178,495,352,885,563,536,165,890,604,279,603,334,554,761,829,321,486,551,954,747,883,666,528,240,829,420,675,330,184,24,160,495,331,78,921,672,181,52,738,608,724,18,405,530,8,336,478,570,734,457,304,144,148,66,199,984,657,892,572,702,280,944,687,208,616,415,453,861,910,240,865,786,615,282,483,824,551,123,88,776,467,314,497,764,348,915,194,979,994,135,379,707,874,329,749,81,504,223,266,164,788,988,445,82,502,892,978,365,236,141,885,816,238,962,93,152,587,81,64,877,626,593,666,575,552,101,179,110,30,557,851,526,364,537,371,348,145,782,465,858,75,678,163,130,176,597,845,704,123,110,927,172,948,609,251,641,187,940,294,877,763,742,111,894,0,664,816,189,659,335,599,61,630,115,869,990,699,686,142,301,564,995,711,378,583,615,175,785,537,352,341,418,784,111,782,415,880,295,731,908,890,488,335,479,129,979,208,487,266,581,380,842,115,974,750,933,277,961,63,969,925,599,271,816,393,302,31,271,522,856,126,251,314,316,347,961,392,252,666,336,588,681,755,777,508,724,172,485,984,154,988,944,619,475,791,719,483,76,26,523,751,966,594,893,308,128,246,128,763,554,376,632,443,482,741,299,218,917,190,400,801,66,481,446,246,622,826,655,847,304,468,324,680,698,587,705,568,845,678,431,942,493,112,757,897,184,220,520,255,915,348,745,967,26,252,73,654,720,616,76,106,320,616,394,596,696,664,341,643,299,236,86,46,945,474,175,721,150,884,431,398,859,152,370,361,434,171,192,423,589,769,778,300,922,298,908,148,31,957,960,301,809,256,543,244,359,540,788,767,671,849,316,105,258,915,535,621,881,651,259,311,323,911,61,101,752,909,241,992,14,676,371,76,486,142,267,924,902,355,804,538,212,35,704,658,552,484,722,541,259,231,70,507,735,884,81,939,651,577,634,951,834,35,577,255,351,895,781,680,841,68,217,882,256,287,36,39,379,788,969,437,224,235,902,639,107,297,500,808,80,449,149,424,191,369,955,794,499,661,348,440,484,404,232,226,855,912,466,490,978,601,122,130,339,286,339,190,307,680,935,358,835,840,593,891,571,638,543,680,274,715,109,835,89,362,299,724,34,661,812,465,284,545,953,662,617,158,517,210,189,412,35,950,592,538,623,291,469,573,610,550,688,577,316,20,193,73,962,265,609,634,620,867,318,951,276,764,208,798,536,40,937,718,14,21,191,236,117,190,582,681,497,74,360,955,173,725,773,430,890,387,899,546,130,829,532,268,105,93,144,803,63,482,685,780,792,946,492,952,464,774,945,423,354,257,564,372,280,629,273,623,987,59,602,810,172,795,468,419,262,879,34,366,830,325,882,250,315,581,587,565,714,21,97,798,373,875,702,23,541,183,144,54,871,965,48,94,700,963,152,661,874,54,240,479,251,621,192,896,266,517,90,20,671,807,969,611,721,770,775,233,325,580,293,954,556,39,262,505,244,430,755,855,648,327,544,458,256,584,278,368,703,28,268,119,491,312,244,853,741,865,6,17,728,389,324,636,961,858,859,518,845,436,205,707,671,630,50,813,58,863,837,303,4,423,500,39,866,774,915,732,504,278,983,48,595,284,740,579,36,980,580,556,995,454,60,147,926,436,815,344,438,791,34,509,173,642,3,560,465,426,41,56,288,359,605,328,243,829,771,511,259,99,263,501,663,432,786,760,950,257,489,400,807,258,671,413,427,42,848,489,989,722,28,762,420,818,890,826,485,654,767,904,185,978,490,695,194,217,416,218,845,52,908,512,147,987,762,3,306,591,473,942,58,188,315,231,808,399,322,262,977,388,163,711,466,429,983", "652,515,641,937,397,703,899,936,415,845,965,701,52,839,78,251,172,578,650,118,346,584,380,151,214,155,98,708,725,258,269,603,825,955,425,302,642,482,260,77,938,384,281,55,533,883,103,215,912,724,429,655,562,968,234,716,151,905,688,261,718,606,691,419,68,429,193,848,206,608,527,760,169,587,818,639,485,297,784,330,892,496,589,369,933,262,714,260,204,430,728,223,160,912,363,316,594,117,280,47,184,652,347,431,669,216,697,691,394,426,336,320,578,884,125,132,598,383,278,843,631,307,259,192,132,735,86,332,382,922,980,572,849,393,209,524,551,636,807,944,417,229,334,39,580,990,369,346,760,170,933,646,819,843,102,383,985,148,284,682,524,147,44,661,269,993,476,341,562,60,803,751,75,192,322,882,288,510,943,866,140,922,750,175,28,144,704,504,979,521,503,568,151,925,223,501,271,417,959,99,492,517,564,405,180,685,778,684,372,471,175,93,649,50,519,786,746,143,953,861,892,846,268,490,595,590,70,361,260,495,394,700,314,891,461,84,429,710,392,482,744,579,335,913,119,904,770,430,496,787,805,456,561,194,993,573,360,264,80,356,448,444,783,521,631,871,36,242,674,495,493,651,732,920,96,617,542,787,754,74,493,312,719,433,487,624,115,949,259,454,43,89,407,684,584,967,369,26,214,685,832,25,655,827,232,302,40,819,656,9,96,906,106,240,417,84,225,139,234,236,592,329,244,465,842,203,778,475,267,778,45,682,218,391,270,362,715,875,156,494,873,927,9,67,197,397,664,0,267,905,469,660,50,750,618,323,615,696,528,158,615,545,398,128,484,98,879,959,944,619,529,931,637,416,578,320,793,135,89,538,930,440,560,969,344,778,862,566,346,493,341,233,631,789,224,100,560,997,342,335,83,898,220,175,435,375,116,529,789,500,946,892,307,36,578,460,159,713,690,755,600,938,172,382,354,1000,807,6,528,943,611,17,408,226,762,184,394,930,971,570,224,179,259,665,689,43,67,680,914,124,686,993,403,651,561,519,336,23,572,199,439,51,9,603,669,574,334,12,847,383,906,604,875,854,776,778,693,172,405,586,917,129,790,962,879,861,764,375,369,66,841,686,975,513,745,767,304,97,111,865,75,31,150,510,956,265,64,216,607,506,910,40,513,867,181,4,109,973,194,368,98,139,244,825,324,482,577,788,809,953,425,155,585,39,892,92,748,914,675,505,992,405,546,702,732,820,584,794,734,517,61,306,820,140,470,983,59,697,728,802,151,829,666,818,204,515,513,54,231,583,706,651,899,959,913,395,58,808,867,55,787,598,496,158,480,246,984,182,468,696,400,100,649,15,940,159,23,283,221,489,262,122,372,526,682,842,499,750,96,974,488,729,368,2,802,10,361,866,464,704,372,343,902,873,536,77,562,434,625,301,573,25,721,792,453,18,190,500,398,840,220,996,218,163,856,297,554,816,493,328,809,374,139,890,409,455,154,158,896,838,70,397,465,645,693,236,311,268,292,322,697,772,827,871,183,586,156,800,588,48,126,153,991,288,19,789,301,594,128,550,902,591,76,608,499,450,207,641,29,214,6,55,240,256,777,939,185,294,33,781,735,894,531,879,496,653,448,42,637,99,827,229,64,360,303,255,555,853,95,334,501,17,942,67,65,956,919,115,450,403,197,20,65,197,427,849,488,188,555,948,228,115,768,780,796,918,618,5,726,111,415,248,270,398,228,754,854,906,771,821,884,72,474,689,27,317,922,191,166,653,987,651,352,684,82,851,959,508,964,921,86,71,597,404,155,618,198,429,917,147,938,760,926,386,896,351,551,912,160,912,581,512,667,672,362,211,93,826,160,849,225,556,709,182,183,194,179,856,344,200,347,991,72,47,985,506,869,316,934,399,591,331,937,627,945,958,812,687,277,138,452,98,5,963,430,812,486,263,243,54,973,845,727,17,618,807,372,194,747,585,150,258,464,263,329,773,166,245,833,371,228,113,143,552,934,432,773,27,20,358,218,532,953,472,361,311,707,234,400,183,105,894,221,922,806,985,385,240,616,309,99,739,518,961,738,959,753,24,923,661,288,570,119,148,891,607,532,157,234,902,610,23,44,652,36,7,981,537,323,115,502,395,226,422,418,128,306,631,797,378,613,323,31,846,54,768,440,196,200,71,500,235,812,258,728,398,76,333,315,352,72,989,134,181,708,555,975,382,564,642,835,438,977,370,203,621,347,282,937,350,726,599,355,723,235,329,367,295,766,592", "367,757,977,241,247,633,464,412,102,796,396,256,325,188,516,360,110,211,613,371,451,740,628,169,530,102,81,795,798,917,926,295,150,221,96,487,227,99,989,631,774,535,858,713,699,70,263,725,989,516,692,52,154,91,262,516,744,754,848,674,732,453,264,369,62,600,95,166,837,668,364,456,117,758,517,529,904,929,458,264,889,962,309,710,687,805,68,853,730,520,190,278,959,948,789,668,292,538,598,963,636,581,143,506,686,779,680,419,242,40,731,740,286,60,976,121,387,994,775,267,216,88,161,405,177,72,521,117,218,508,384,845,802,653,831,213,488,795,863,506,104,418,321,694,998,968,680,955,867,664,288,849,786,98,512,375,808,26,289,97,334,275,781,696,409,469,940,770,608,832,56,695,228,404,320,738,439,994,386,322,562,481,409,611,550,480,73,62,288,976,193,366,244,495,865,84,686,116,889,315,172,527,840,837,314,875,810,455,659,374,846,626,972,262,350,58,661,769,471,684,456,440,190,748,184,282,4,539,721,608,905,898,587,195,267,187,116,619,648,231,911,52,616,428,993,692,275,797,177,634,813,239,239,816,830,132,464,416,883,327,267,226,202,832,734,266,823,538,910,712,954,853,926,192,878,27,648,840,415,462,238,694,181,475,633,649,983,778,332,1000,458,157,190,374,240,465,545,856,44,560,883,484,862,880,698,416,246,32,102,908,291,321,969,370,657,692,97,686,109,579,157,430,81,890,13,719,142,878,158,401,435,132,653,855,561,922,287,789,840,578,327,734,983,593,137,422,816,267,0,742,473,134,98,486,126,685,948,331,260,412,990,80,177,192,661,794,929,735,94,631,555,311,42,594,651,153,510,466,189,767,622,873,800,949,369,911,396,161,737,270,540,238,8,477,662,669,449,525,76,809,623,924,568,558,688,108,828,112,801,793,40,218,987,62,288,120,905,483,388,578,153,716,948,385,775,290,596,861,103,476,409,126,696,104,634,887,509,463,653,634,978,456,553,194,332,111,242,463,890,574,541,660,924,789,620,690,829,509,347,101,386,989,768,999,743,399,75,113,209,762,595,123,49,150,889,157,957,195,711,851,532,402,32,578,783,819,971,781,988,38,645,733,18,766,657,67,903,614,610,254,748,817,704,23,846,904,669,584,237,760,143,595,758,734,524,474,111,360,935,737,489,529,403,840,292,215,61,846,74,971,89,67,640,961,38,670,766,461,641,556,743,428,626,773,885,560,778,503,914,194,794,439,287,327,156,24,321,712,834,932,803,105,423,495,450,705,887,781,923,927,182,985,260,831,177,925,824,954,584,605,151,833,549,213,3,354,87,854,328,613,710,72,112,882,536,274,974,433,861,987,196,899,85,658,106,964,1000,2,481,210,433,32,789,239,129,907,214,921,499,118,74,788,686,794,172,974,566,478,61,373,113,986,486,192,561,684,577,219,486,542,195,664,814,502,357,296,850,805,9,781,661,148,888,540,592,374,706,21,946,146,597,608,515,252,735,968,199,254,466,197,243,872,793,136,296,678,658,987,519,48,713,112,748,55,680,100,333,448,653,897,984,261,504,520,102,905,638,628,825,135,221,617,628,678,720,166,217,286,775,378,386,26,655,530,727,864,349,851,89,657,77,871,724,458,907,449,674,870,998,644,576,24,803,181,673,512,89,519,570,87,13,393,562,472,436,970,974,788,534,650,380,56,132,431,460,914,13,379,487,545,893,598,957,749,411,628,613,445,544,150,227,817,720,145,659,324,123,473,850,996,500,294,502,987,451,305,322,792,233,847,635,473,496,93,425,986,171,657,348,769,434,980,890,623,533,60,308,159,491,56,898,653,681,750,762,369,260,162,25,749,509,858,349,645,444,426,545,209,87,430,355,229,332,465,930,41,993,477,992,653,826,960,462,206,403,546,591,414,333,906,258,949,407,598,130,183,163,522,523,837,998,273,817,560,920,18,11,718,320,25,882,325,622,175,953,506,626,596,212,119,952,89,244,506,486,947,865,189,333,727,1000,956,206,463,947,339,878,619,535,794,954,690,513,416,725,501,735,33,275,52,723,696,35,578,274,662,314,681,80,244,230,355,14,350,280,587,730,233,458,573,42,278,550,666,268,986,436,467,575,73,761,807,37,289,955,770,409,936,856,674,815,371,985,874,600,662,164,256,922,134,508,686,505,748,654,460,499,824,707,583,319,65,278,895,644,983,763,290,713,746,607,908,384,30,694,387,576,657,626,52,987,427,439,561,881,970,15,365,673,35", "293,740,257,812,241,191,917,585,508,670,748,382,171,679,365,823,252,681,770,114,666,449,853,783,717,517,883,862,287,192,260,519,551,760,953,797,918,505,846,331,56,149,659,517,791,615,820,233,578,774,192,774,708,283,138,129,260,963,697,175,849,832,155,75,504,988,684,206,322,359,518,532,35,709,620,815,689,998,148,406,120,47,909,863,347,280,246,548,383,610,334,683,110,95,516,946,261,423,964,304,898,346,429,263,956,363,619,659,393,713,244,234,180,206,702,480,938,494,676,102,304,572,456,915,832,330,923,275,401,26,406,34,621,365,117,864,713,224,315,213,344,254,531,600,857,821,962,730,189,374,945,97,46,23,878,554,260,905,408,263,460,446,81,960,830,603,460,16,869,790,757,143,710,734,79,384,526,407,156,316,773,957,517,430,675,497,424,710,147,961,650,279,309,467,283,817,693,101,852,90,179,76,56,906,737,730,830,802,877,493,771,441,186,448,158,527,542,917,83,652,711,686,631,41,798,253,27,748,313,999,676,171,716,179,712,346,759,351,204,420,219,596,468,856,754,48,276,924,985,438,488,164,309,103,491,991,523,420,89,736,714,595,747,765,988,55,952,654,758,184,930,214,795,27,707,693,155,134,171,534,173,829,466,779,47,817,978,937,972,897,523,96,45,328,97,575,537,211,583,509,429,418,495,145,998,947,339,338,117,959,463,701,400,164,356,744,193,741,281,652,381,946,574,242,399,30,471,348,535,897,593,798,727,389,23,857,593,600,582,948,831,309,913,605,359,705,189,905,742,0,993,910,915,842,554,65,106,500,341,848,490,599,612,116,140,739,923,890,213,602,405,182,559,164,336,739,104,266,873,483,164,964,15,180,427,707,594,710,118,462,566,417,535,583,811,44,66,807,654,601,390,622,228,841,802,857,106,810,825,111,547,395,229,81,320,184,43,85,41,837,385,60,143,718,798,380,276,600,150,650,879,454,348,205,226,339,275,929,184,479,636,303,718,429,903,668,839,192,848,1000,964,293,564,288,841,28,262,827,899,577,451,750,285,975,213,283,103,275,888,283,567,785,732,56,859,535,813,331,740,324,594,949,998,891,617,893,571,748,206,992,737,205,43,919,8,216,580,210,969,90,585,70,41,417,266,756,88,915,422,817,1000,429,569,810,147,590,450,961,803,520,620,754,232,505,859,616,978,894,634,251,879,821,167,215,462,95,878,621,320,534,363,730,574,251,490,646,985,588,945,885,913,448,357,575,79,771,144,512,761,118,244,624,100,804,292,542,274,887,439,722,137,972,110,78,247,555,128,340,658,320,664,308,511,793,200,35,602,301,880,997,865,619,464,681,835,116,283,655,4,362,349,277,704,337,924,773,58,4,147,84,488,214,128,463,924,640,476,229,237,169,607,935,372,628,795,89,137,139,210,665,992,443,506,928,913,60,295,116,746,99,149,231,996,564,529,37,382,140,785,18,777,679,648,436,820,615,562,619,625,162,854,937,171,527,542,585,698,410,265,695,259,271,230,387,632,478,424,892,943,708,946,199,337,78,12,943,129,974,814,113,726,594,524,926,32,583,226,778,226,380,318,26,597,9,836,54,251,694,896,447,656,861,266,832,292,501,982,419,340,675,391,91,179,230,281,533,759,799,524,687,148,191,775,859,286,471,310,979,442,864,300,870,419,724,8,321,141,883,717,644,722,12,738,32,824,118,355,95,782,201,802,510,212,53,614,823,203,27,467,576,580,443,290,921,752,682,690,809,265,593,818,656,583,21,250,629,574,235,83,468,102,367,568,433,177,393,837,439,852,375,271,714,612,736,68,876,884,546,110,55,575,294,686,380,140,430,812,812,455,747,138,75,335,901,455,614,380,868,601,558,459,786,766,391,799,152,263,658,804,12,898,384,645,558,977,45,540,679,920,501,847,920,614,975,192,339,381,703,700,151,728,110,55,313,116,392,110,432,170,106,188,624,155,575,187,734,379,238,969,465,299,632,794,438,108,102,860,437,566,74,739,392,123,910,211,528,864,929,20,42,118,549,180,562,687,998,250,822,994,805,317,344,618,751,218,430,192,545,450,972,853,383,444,220,472,806,252,861,520,77,157,898,379,359,607,619,437,197,740,709,758,849,618,97,951,606,863,191,118,452,588,656,135,54,17,107,924,91,660,912,365,630,936,651,161,293,697,288,596,528,834,715,655,119,510,912,454,549,405,306,206,39,489,334,228,466,533,8,585,949,873,697,599,732,633,108,181,997,630,102", "196,73,182,835,442,512,31,804,501,917,843,804,426,662,918,160,938,279,956,856,10,562,429,754,558,98,815,698,766,118,468,958,554,90,768,307,879,816,956,535,892,112,426,262,952,972,618,84,349,36,446,997,696,827,86,930,118,418,993,629,99,768,895,304,603,527,546,866,264,739,226,689,736,1000,756,852,931,79,487,66,897,974,43,966,611,843,732,573,35,238,504,609,951,208,554,698,484,563,265,320,218,428,445,210,849,463,673,762,30,873,800,742,339,311,631,410,486,888,542,680,947,69,345,579,109,87,145,837,425,413,470,492,868,719,921,636,722,672,814,35,313,456,453,328,537,771,879,19,171,173,515,130,410,540,617,723,221,579,757,629,991,134,922,274,936,890,603,932,656,51,656,29,772,472,195,145,792,863,595,372,750,939,429,279,216,542,493,269,538,146,874,810,29,969,382,280,944,768,473,30,562,751,764,216,268,318,397,809,723,596,869,301,965,94,31,931,475,284,579,956,817,471,499,2,26,508,147,893,884,754,71,212,555,854,281,492,777,169,868,542,681,284,518,380,469,225,427,576,472,985,618,252,832,225,759,204,680,9,453,343,657,740,992,916,152,192,990,952,765,111,641,648,352,193,490,156,323,313,689,833,804,721,190,544,782,404,771,269,441,291,295,695,873,164,522,359,453,462,67,16,512,903,154,764,802,883,673,797,520,714,311,332,888,738,502,99,176,326,564,565,574,515,225,624,960,393,899,930,766,678,572,713,365,909,215,62,200,472,108,616,442,927,740,623,422,954,659,469,473,993,0,841,306,390,97,777,25,255,121,30,230,808,668,881,969,909,889,65,441,367,362,745,804,715,929,255,346,379,126,650,498,53,986,153,207,876,875,751,101,326,860,730,241,966,558,799,256,691,511,563,989,844,802,248,642,265,44,266,598,517,256,22,398,716,245,990,34,282,822,742,891,42,606,260,14,222,895,33,578,144,983,981,979,951,751,747,21,157,35,286,699,855,783,935,404,875,578,301,943,940,841,714,914,806,274,46,693,79,787,189,41,461,154,885,479,788,126,492,845,223,262,453,594,217,837,729,597,2,108,435,885,251,654,235,919,569,129,699,831,341,101,895,642,612,327,231,22,269,684,399,476,279,14,956,829,325,661,443,747,852,529,849,423,626,813,85,804,738,393,365,889,750,268,444,909,17,427,800,779,319,44,852,340,582,696,715,996,370,916,721,882,718,176,889,398,781,776,425,499,226,646,52,523,21,587,622,263,40,644,574,558,102,977,806,930,473,256,121,986,456,526,653,218,636,728,383,236,72,419,911,688,970,731,368,375,874,864,910,216,766,938,514,845,167,272,219,255,327,464,616,867,425,56,532,964,707,763,44,866,590,453,515,962,43,442,541,811,370,272,896,232,832,65,705,905,279,490,330,417,447,412,500,530,579,387,788,811,343,875,886,237,759,703,606,205,50,959,761,408,716,292,315,952,995,62,563,29,594,236,878,306,432,798,311,548,621,921,951,677,202,628,709,803,979,438,652,951,613,563,772,9,49,310,860,895,510,103,11,872,698,233,972,530,87,439,29,618,297,973,614,855,135,445,469,966,855,806,914,644,27,689,725,531,679,877,311,893,431,660,323,18,731,764,518,380,5,88,217,793,717,275,629,934,678,251,967,952,857,230,372,939,958,560,90,21,32,636,832,488,731,472,662,60,386,86,345,973,927,617,960,30,742,328,770,862,421,876,201,874,720,547,435,230,972,518,117,317,624,235,783,55,898,738,62,326,761,797,829,141,158,93,523,859,510,340,439,96,862,448,527,791,91,103,260,798,884,390,645,94,861,565,793,297,719,558,766,562,727,978,288,691,594,101,680,944,443,83,244,113,464,891,245,715,382,774,550,378,123,356,4,68,315,525,833,62,529,689,602,560,545,365,502,61,282,540,960,667,74,191,536,146,30,840,168,893,601,319,582,414,484,631,32,667,280,10,641,40,816,192,941,351,579,439,198,6,749,317,677,457,438,875,360,110,162,979,606,638,95,424,32,518,509,966,412,980,999,305,650,942,108,72,733,671,263,409,598,488,531,299,758,181,887,511,626,157,346,57,326,103,482,961,974,839,870,980,720,966,32,181,49,943,790,915,283,355,747,982,831,176,608,473,437,560,371,497,296,874,851,327,502,563,329,169,774,835,789,596,307,393,570,373,615,236,150,57,287,770,276,361,265,230,815,778,889,947,393,296,612,440,246,629,616,276,187,312,412,276,585,599,83", "868,837,126,148,888,569,743,956,509,277,896,444,986,768,323,509,812,34,745,463,126,383,192,731,764,238,103,602,115,809,713,344,205,678,50,634,816,212,750,364,960,790,331,398,800,501,84,84,299,444,894,469,743,445,760,624,100,291,106,166,398,926,593,460,8,827,507,403,400,857,626,773,702,402,526,552,886,824,990,562,711,728,643,12,118,179,330,288,575,67,504,814,736,652,669,481,391,261,234,284,81,210,19,81,939,72,550,190,614,185,433,504,751,606,947,296,619,899,666,197,727,336,369,282,37,560,599,249,751,389,299,550,399,777,33,131,443,443,200,909,249,989,234,38,343,268,594,833,872,880,806,836,605,468,745,214,523,739,377,927,251,785,419,203,634,804,681,464,270,19,364,841,445,35,269,403,290,16,109,586,700,913,158,333,776,222,103,726,891,668,609,650,845,506,827,578,979,661,531,839,304,477,303,348,664,690,123,555,298,851,232,98,31,280,461,31,387,906,535,355,990,846,858,26,229,815,215,887,230,274,40,551,675,642,279,39,79,928,574,96,682,508,292,720,355,208,144,183,93,586,415,493,581,985,82,139,500,484,906,954,821,11,449,526,380,785,466,708,428,56,230,431,633,667,576,705,377,177,684,240,159,606,891,666,931,534,341,525,213,669,367,817,239,73,55,54,566,875,700,87,891,994,433,357,207,653,879,445,875,128,750,968,275,136,852,849,365,45,817,770,561,130,307,629,868,107,819,559,600,325,284,335,545,127,210,587,313,636,951,608,466,157,506,635,53,921,335,660,134,910,841,0,414,749,343,307,867,366,246,784,260,2,740,480,988,42,113,494,569,474,643,791,820,873,605,771,673,253,96,604,879,777,702,148,63,498,810,215,884,791,574,371,888,27,402,338,646,151,996,101,490,302,685,440,64,831,418,838,293,306,177,881,939,321,304,656,530,470,291,138,269,314,832,338,344,762,529,116,261,438,339,750,842,352,263,130,434,807,439,765,212,552,220,789,768,370,481,687,633,469,955,453,292,819,357,376,930,749,465,232,972,839,871,886,84,135,812,672,281,704,236,237,823,507,638,311,876,189,588,802,374,105,88,817,754,786,467,516,756,432,792,750,927,844,702,421,460,387,116,537,373,19,510,791,329,917,914,807,160,811,234,978,401,211,292,620,576,41,207,447,441,93,964,409,105,66,906,224,826,391,788,237,515,10,456,811,664,430,955,739,141,292,313,380,58,123,627,639,648,292,203,782,689,154,53,48,938,231,404,411,982,685,598,803,408,200,272,51,910,956,646,105,739,700,205,113,8,958,995,418,534,235,267,201,829,309,143,806,237,899,90,732,456,950,671,819,33,356,839,105,208,293,647,519,886,774,85,237,968,527,230,935,451,728,405,854,440,791,40,738,103,679,295,725,327,206,836,619,851,327,941,931,542,970,399,281,990,217,517,470,705,220,976,200,854,886,700,881,105,610,997,114,744,546,806,848,658,684,1000,755,730,467,397,1000,212,268,926,268,657,381,177,338,51,138,107,498,20,495,535,925,283,463,133,542,878,993,974,595,951,971,743,128,314,73,494,207,465,751,22,819,173,886,882,238,891,305,162,932,182,604,773,65,932,682,670,265,966,926,495,489,917,98,2,361,707,837,624,868,88,849,144,823,92,313,242,672,623,889,260,967,263,672,200,106,719,848,88,83,915,7,202,801,44,102,194,508,230,558,718,739,451,780,182,480,908,969,144,236,703,203,80,171,436,175,360,729,891,527,768,830,653,152,124,691,804,222,920,483,322,983,841,13,742,898,189,201,288,573,148,378,214,673,714,221,789,477,962,545,429,610,555,958,237,987,936,221,744,103,159,669,279,934,613,482,527,198,783,786,335,611,78,554,508,562,429,129,363,408,873,216,648,405,460,665,789,20,569,301,858,593,536,493,675,999,828,692,374,360,584,117,333,831,238,879,903,889,65,494,659,526,532,493,484,457,318,166,947,843,542,627,694,91,398,188,295,51,598,214,149,636,819,610,608,699,609,160,412,890,777,189,15,642,366,370,673,595,481,834,934,850,839,371,888,703,656,631,249,530,553,46,869,114,258,796,549,601,946,137,800,478,432,52,451,33,332,974,146,452,406,814,373,736,500,851,764,463,3,76,269,426,75,374,758,533,971,185,485,621,281,715,639,629,542,673,409,633,691,689,885,669,897,142,604,591,688,877,508,873,335,856,818,271,666,462,216,805,747,256,103,850,999,971,42,301,873,428,501,180,740,696", "18,600,672,453,513,328,275,239,624,905,953,503,253,161,623,618,137,303,353,70,341,940,291,63,955,888,493,616,46,524,845,625,891,421,600,310,210,143,138,285,807,466,234,974,945,869,799,18,65,272,527,134,44,324,528,77,929,75,502,459,393,196,464,952,931,279,116,805,498,965,682,450,841,586,446,946,462,442,641,451,718,201,66,838,894,702,339,886,326,752,934,608,456,86,369,520,883,877,963,343,446,846,915,43,765,427,266,17,309,636,387,555,153,889,847,596,269,954,75,674,304,951,700,100,312,812,200,534,953,867,115,950,359,157,137,602,477,992,799,556,107,46,861,122,681,554,528,865,675,616,423,697,791,420,967,834,827,370,102,332,54,213,277,441,27,434,24,62,216,325,132,298,365,521,62,992,674,567,46,761,746,711,444,318,763,288,989,536,498,644,432,939,954,811,356,984,75,843,198,653,501,301,418,887,123,736,478,111,842,218,877,282,918,556,900,608,874,331,783,68,685,296,290,934,910,875,879,688,415,936,423,83,359,213,157,33,559,94,106,95,307,176,739,930,908,467,728,224,868,375,742,248,668,863,439,996,418,457,64,312,940,580,583,566,138,866,206,685,188,769,190,793,100,474,812,579,212,13,429,226,553,395,938,496,431,497,309,442,638,857,254,352,887,253,585,494,190,712,856,773,194,413,325,971,916,526,822,563,248,531,698,78,753,908,313,791,383,628,157,569,254,952,221,328,558,147,505,592,649,196,942,479,472,561,16,571,32,533,944,802,961,124,919,454,34,322,599,50,98,915,306,414,0,631,157,172,955,710,109,159,480,652,266,151,664,155,940,750,627,228,937,287,52,107,184,311,443,240,631,245,81,327,81,492,81,706,19,477,702,715,167,545,93,910,933,469,569,273,510,757,200,862,671,546,320,36,938,459,559,613,442,618,839,919,153,232,492,904,964,900,633,13,871,74,573,550,209,57,117,394,153,553,995,105,177,752,860,630,772,735,860,948,242,239,641,382,404,542,126,222,160,479,436,665,194,632,261,460,562,264,69,801,183,454,351,876,634,740,78,6,652,605,964,258,480,952,190,986,914,186,865,922,475,108,191,249,355,873,619,439,999,961,431,216,865,326,24,849,101,575,749,126,648,456,949,848,106,190,332,673,625,293,26,995,158,989,59,347,928,468,262,7,428,426,721,70,886,126,515,659,272,862,480,91,497,10,834,780,218,801,696,266,688,29,734,586,32,351,343,671,778,739,753,870,278,178,588,915,343,985,905,36,180,917,706,571,864,902,181,326,486,977,928,941,48,84,847,800,236,211,139,22,411,946,732,794,785,32,675,685,942,687,851,161,225,243,421,766,78,13,768,885,382,549,608,332,550,602,842,135,569,760,122,736,627,285,427,690,316,482,513,10,780,282,784,668,354,66,557,363,905,726,576,981,98,179,186,316,282,733,591,241,834,165,421,16,234,868,995,458,37,172,404,436,936,480,659,945,448,869,148,392,103,461,228,160,884,130,378,401,464,251,659,657,961,638,441,396,626,453,784,280,512,915,137,546,325,330,611,632,419,299,508,959,98,902,312,177,869,134,391,879,673,817,715,594,904,171,208,924,838,83,276,709,413,621,925,581,242,934,782,465,653,634,323,205,694,112,916,978,192,678,915,422,812,377,236,632,403,492,698,516,770,233,919,640,509,890,562,82,548,322,882,472,661,736,100,549,559,700,447,473,523,958,891,962,751,9,655,339,675,240,480,544,980,644,190,831,290,252,290,467,281,622,305,305,469,559,136,13,390,497,539,878,466,499,648,415,989,346,751,92,581,284,610,768,486,964,846,272,636,177,504,463,495,928,925,41,795,33,475,373,847,633,870,949,735,953,66,402,751,806,637,746,575,714,32,183,251,116,404,838,807,748,964,357,437,381,660,650,283,117,515,878,991,671,294,509,677,719,455,841,794,607,667,396,544,371,581,507,118,223,484,367,442,763,982,189,856,560,548,358,842,346,629,426,384,538,791,208,812,917,122,480,634,573,966,848,500,519,149,868,892,901,359,122,579,440,754,877,148,655,905,668,308,301,719,530,312,269,114,918,584,572,482,609,649,67,265,685,255,393,188,18,661,414,696,907,3,820,147,799,525,424,365,477,352,472,453,752,976,526,968,394,802,351,125,900,680,514,928,634,867,537,484,35,180,67,784,670,65,61,448,861,709,767,58,436,518,352,359,538,838,101,276,866,393,541,116,304,449,505,833,280,633,467,411,712,244,522", "555,762,693,881,754,903,381,61,812,449,608,406,884,566,901,345,790,268,303,707,793,506,428,423,940,284,53,514,664,157,394,252,258,426,806,558,804,949,327,598,262,975,693,607,377,404,557,252,976,943,182,92,898,676,744,113,643,940,332,459,240,928,747,273,549,197,370,638,500,886,864,627,111,598,16,487,752,912,50,806,843,522,561,493,830,869,241,184,123,958,991,256,948,227,787,43,775,910,557,966,956,878,28,214,202,211,115,6,701,349,658,780,456,967,188,336,674,856,60,46,869,638,608,350,402,345,275,51,673,12,857,355,698,898,613,702,615,615,643,174,946,966,90,634,826,510,295,635,164,693,343,733,590,797,332,959,528,543,885,260,636,532,736,164,677,351,695,754,793,995,229,309,993,79,65,347,259,582,396,908,746,3,129,286,795,246,146,119,742,796,288,583,760,61,750,458,306,119,822,420,845,925,505,14,586,827,265,416,669,649,134,767,243,976,643,843,6,325,796,760,185,720,690,407,461,868,797,863,316,950,73,65,153,507,615,784,902,958,249,54,175,436,327,819,399,247,228,208,352,761,563,343,326,207,175,406,956,894,505,884,767,340,773,934,796,344,830,893,824,88,643,384,197,511,58,646,57,390,423,222,593,767,213,469,420,698,506,579,299,357,690,938,25,141,751,49,930,676,115,593,182,950,429,700,203,768,339,496,355,844,334,675,106,140,711,681,751,395,70,615,325,404,689,562,61,936,625,484,392,915,461,304,715,204,865,798,171,361,709,10,242,428,236,577,690,307,61,750,486,842,390,749,631,0,73,574,388,291,90,718,210,74,448,922,648,588,549,702,876,485,742,844,737,907,828,123,864,894,46,940,926,827,500,380,437,937,436,249,508,356,264,416,164,684,506,357,319,255,725,151,909,62,756,512,169,471,762,294,595,181,713,964,578,393,976,924,403,470,859,665,837,300,128,674,77,848,906,749,729,756,330,156,494,330,755,829,595,962,186,76,940,789,792,646,373,265,32,479,433,45,903,720,349,872,561,565,189,116,998,294,291,482,42,127,117,347,969,181,897,851,635,990,551,559,24,337,760,766,790,512,148,388,87,219,533,726,946,193,851,453,208,691,945,649,970,508,225,808,290,171,921,733,415,886,580,244,697,259,17,313,784,414,305,309,542,965,340,651,659,431,90,71,81,752,262,840,300,503,492,966,692,695,705,401,597,766,254,983,114,767,406,862,980,120,59,549,541,696,247,437,190,640,536,732,626,689,200,28,53,549,50,648,293,409,774,571,134,525,446,549,944,646,825,569,834,345,534,16,535,785,153,967,531,767,964,487,271,958,981,788,384,778,754,616,512,842,498,828,439,549,347,227,964,991,858,915,9,866,758,602,921,301,76,239,367,905,446,183,329,563,657,541,886,192,837,518,491,881,802,707,621,826,592,3,963,278,361,247,794,950,583,53,406,20,754,786,763,536,312,115,877,276,771,517,222,214,130,156,664,594,7,738,660,778,205,398,204,645,650,899,519,573,309,400,175,44,986,826,149,146,723,232,440,622,524,55,857,103,545,903,709,977,502,605,344,71,706,542,774,936,660,729,231,276,695,293,1000,609,408,948,104,642,433,15,972,62,729,256,744,46,6,17,157,675,992,25,552,337,527,905,267,86,833,541,837,622,97,166,335,443,869,784,76,535,137,151,182,860,595,106,887,97,338,10,435,886,643,847,980,547,735,270,757,115,611,943,175,658,581,780,917,300,519,664,73,168,236,521,262,263,881,58,109,883,112,442,4,954,80,661,181,546,118,685,183,81,671,339,718,382,347,882,738,642,929,35,923,249,553,743,96,835,887,644,304,892,206,36,427,241,26,292,717,703,488,938,770,799,745,641,268,638,508,998,69,158,92,613,970,145,868,939,924,71,981,177,273,676,725,392,624,918,48,422,508,684,449,674,173,563,465,734,979,811,731,431,49,155,57,661,936,100,587,982,309,670,420,832,343,64,449,538,423,278,398,913,15,878,50,877,411,636,483,972,284,550,142,746,959,640,759,895,421,611,949,108,446,994,671,687,606,646,238,444,348,831,304,511,610,133,123,620,432,398,498,631,388,192,547,157,652,32,91,664,689,191,540,209,900,617,255,268,947,177,31,964,616,132,956,188,762,823,17,998,807,849,798,906,99,73,267,245,740,229,594,739,424,615,145,560,474,860,252,311,675,458,175,711,845,251,899,542,632,619,655,407,879,692,852,644,144,93,989,196,713,397,597,547,645,215", "746,337,864,774,614,32,874,384,288,777,7,877,52,554,566,147,77,165,182,533,422,583,804,816,735,628,764,528,509,912,651,297,140,471,449,64,360,549,39,120,663,898,218,928,615,331,194,399,58,157,691,666,414,274,443,768,639,845,399,580,575,889,414,519,663,543,301,753,558,335,737,302,114,831,421,368,492,322,391,500,633,268,789,89,122,951,93,105,576,633,780,815,851,552,407,531,654,908,202,219,897,940,83,364,171,871,781,772,999,76,717,509,878,712,45,917,505,18,260,662,263,432,694,543,480,334,743,109,36,536,770,944,346,217,706,517,129,6,769,873,598,600,375,634,544,311,389,380,293,48,460,619,696,107,110,6,478,64,211,382,973,55,289,293,565,575,696,254,14,811,345,355,733,938,786,96,167,92,750,127,280,842,194,410,982,406,5,406,232,929,621,186,707,799,512,682,728,669,788,646,456,262,59,164,483,783,143,902,710,711,404,768,393,526,828,175,672,244,440,410,789,877,252,409,525,7,210,690,580,370,563,153,890,151,536,727,610,211,857,690,247,770,459,584,86,917,604,402,354,812,785,15,654,860,549,231,970,923,544,482,554,472,760,858,979,102,663,689,133,378,263,841,882,144,562,673,562,149,541,431,46,215,667,616,474,770,238,849,68,604,666,112,128,873,955,524,969,558,268,345,357,12,805,155,284,551,487,294,439,214,907,598,165,181,293,365,172,278,899,700,31,332,527,459,600,822,597,653,528,978,319,321,405,451,133,580,859,984,280,244,860,942,922,921,138,520,630,618,126,554,97,343,157,73,0,33,849,675,66,952,204,733,315,618,953,925,414,317,927,977,124,302,690,933,169,91,975,408,671,457,437,145,908,626,869,690,891,80,761,944,938,4,186,851,231,797,70,119,394,646,765,994,557,124,681,667,684,737,939,589,242,130,808,218,329,273,839,703,863,235,279,738,976,422,736,928,379,702,120,694,802,41,247,38,197,920,264,241,566,410,153,784,295,239,43,970,765,279,535,942,354,410,693,991,934,94,952,996,671,586,788,489,654,40,659,4,448,622,568,176,386,232,816,267,765,925,14,517,269,198,410,876,259,72,861,521,506,204,513,564,608,508,230,468,581,205,257,69,234,351,255,588,362,953,78,31,996,265,944,330,721,353,575,349,86,655,400,587,502,678,420,664,243,127,984,832,166,528,205,120,993,538,815,800,519,188,983,646,370,102,324,646,82,448,64,279,404,148,447,15,859,741,323,490,279,194,427,597,819,365,389,284,400,953,105,703,720,333,682,627,51,350,311,117,71,893,278,568,842,773,715,515,996,813,960,520,648,532,948,458,222,103,840,854,766,255,779,744,772,97,911,149,54,500,456,759,636,24,129,521,728,991,858,727,494,525,968,981,422,602,126,717,743,88,767,318,441,590,420,467,541,86,336,277,567,527,462,609,620,304,114,882,363,970,532,831,247,198,191,353,302,553,598,311,836,343,933,491,382,504,177,749,630,617,596,351,668,74,159,801,789,552,200,180,840,950,648,287,508,218,684,858,791,23,942,413,127,635,310,819,870,473,823,792,133,306,863,912,948,588,874,850,255,971,996,936,83,43,825,10,111,454,717,710,381,402,669,597,332,724,320,13,706,193,699,232,855,21,406,660,379,851,86,952,566,776,766,125,238,386,414,547,474,894,703,589,802,932,367,970,949,413,269,86,824,451,672,473,393,97,97,192,574,69,512,405,735,338,154,213,890,402,695,978,359,461,300,47,652,277,5,219,776,138,578,127,945,102,954,659,369,893,268,907,582,952,926,743,725,544,472,310,873,194,57,761,463,908,52,166,550,736,186,124,672,960,602,786,290,742,674,74,718,690,198,91,66,63,937,886,507,601,897,367,170,747,655,199,52,504,973,727,547,481,552,404,457,389,572,448,332,457,958,144,899,240,20,273,455,850,487,249,161,388,90,153,140,907,232,394,525,52,612,360,707,987,483,232,491,652,934,94,174,42,419,289,214,573,148,180,524,224,454,41,981,809,998,912,625,705,679,117,870,427,191,355,416,183,49,936,898,538,856,158,414,859,577,140,915,320,259,570,635,423,48,116,419,955,146,896,988,495,915,213,227,855,581,785,994,542,324,599,421,718,863,62,609,578,60,744,480,778,161,884,646,995,70,534,761,783,889,433,982,110,896,902,867,428,466,610,958,511,626,689,710,502,505,193,867,576,672,423,156,295,615,33,89,457,244,846,948,836,404,588,112,953,864,455,16,404", "142,555,252,126,277,657,906,489,262,206,311,729,651,647,953,788,499,867,874,213,994,362,561,616,337,212,188,624,882,268,806,619,545,996,974,621,986,42,756,612,172,855,873,755,740,689,527,304,69,391,728,516,87,885,565,254,428,524,699,621,14,463,481,290,886,7,831,983,218,912,31,991,302,895,346,440,268,283,349,84,424,550,550,369,459,204,700,321,318,9,934,496,433,685,161,311,827,349,815,311,443,457,417,183,68,483,366,849,862,234,8,677,389,906,206,816,256,293,962,249,63,773,829,140,696,889,270,208,659,561,758,554,155,346,584,256,912,107,392,743,509,74,729,828,176,117,889,501,33,882,147,126,326,847,704,765,736,224,642,190,655,660,456,492,982,398,124,521,366,772,764,84,85,254,559,571,432,728,388,262,300,965,308,138,762,855,281,408,288,109,601,49,879,240,155,93,901,352,370,19,643,772,206,83,476,958,190,408,635,180,510,972,590,896,183,458,536,934,875,939,729,468,160,869,187,18,823,296,646,901,176,86,858,340,266,130,747,456,537,228,903,270,654,917,875,422,206,900,308,746,487,58,180,308,650,154,20,90,425,266,864,482,64,147,796,856,410,678,992,775,930,952,87,164,866,183,778,232,398,179,242,398,409,488,103,34,324,399,836,769,264,297,331,503,4,736,400,960,323,497,325,285,239,816,393,343,161,873,772,589,218,354,437,481,105,436,144,566,217,972,324,30,678,952,803,754,548,525,428,56,767,57,611,54,815,192,216,642,492,630,59,6,630,595,856,654,115,323,685,65,777,307,172,574,33,0,494,168,816,590,708,379,714,560,630,662,473,743,120,357,770,959,156,693,545,489,67,452,787,796,116,96,336,141,915,190,525,73,404,472,280,741,728,460,53,938,764,563,803,600,514,206,312,471,959,886,50,849,14,985,872,584,131,619,620,464,492,827,524,524,199,38,60,441,695,341,975,686,706,588,576,693,896,314,883,916,772,814,73,208,352,886,894,889,766,702,410,505,457,987,256,635,762,574,273,493,818,450,762,447,790,618,916,792,339,203,489,205,999,39,416,397,492,649,398,284,245,250,592,261,516,272,873,919,472,223,567,390,420,571,196,140,981,789,177,177,419,106,409,929,286,444,109,298,814,566,496,870,813,976,546,486,442,680,60,924,532,988,809,326,187,787,649,50,296,344,920,703,476,647,789,780,153,135,104,708,905,655,605,344,217,581,679,633,950,657,124,812,531,123,899,585,348,232,38,562,86,701,225,106,942,217,330,727,891,283,315,216,762,522,642,282,62,477,59,240,894,994,128,928,8,404,309,661,718,323,716,784,125,468,213,796,859,117,935,835,687,583,623,398,640,155,633,405,213,129,639,813,215,64,940,145,151,934,403,560,790,570,3,613,973,138,71,331,921,240,151,429,439,529,265,846,502,722,412,146,416,509,969,309,938,400,821,343,790,843,719,53,57,883,396,917,573,428,998,704,989,662,144,148,730,561,855,562,672,70,68,457,464,179,244,71,262,474,251,373,114,917,327,709,505,180,257,454,963,67,18,11,586,386,97,224,440,524,632,633,793,693,454,721,68,88,242,906,344,94,567,318,459,703,631,382,297,146,261,662,629,244,733,561,842,329,622,91,457,544,591,898,362,191,261,417,675,301,209,651,533,382,976,909,685,563,69,690,524,307,169,918,286,293,338,793,427,628,902,263,52,259,970,37,794,137,664,174,504,88,617,131,723,354,989,21,615,67,729,462,322,232,733,607,963,628,270,551,644,344,860,979,753,726,175,640,906,573,334,284,65,35,863,14,749,114,149,210,727,686,220,469,763,120,165,375,373,231,808,122,264,867,859,877,551,348,995,653,944,42,42,282,62,588,184,625,555,820,276,982,900,146,849,758,897,609,975,6,210,930,928,438,710,364,876,832,10,184,558,737,843,148,6,144,809,306,524,536,998,527,137,384,231,152,405,703,96,981,162,113,852,750,360,816,243,166,957,584,667,163,629,960,704,819,664,482,481,958,556,932,303,35,172,254,458,63,921,277,65,697,824,569,478,241,343,787,711,489,719,47,496,185,632,932,359,289,728,698,331,149,773,828,92,24,1,206,408,882,553,971,166,181,889,537,701,789,203,184,872,502,49,754,690,413,987,35,952,533,295,891,428,661,633,538,884,913,996,527,551,557,167,659,906,804,635,290,972,338,149,673,208,392,902,35,568,729,579,877,625,764,450,172,872,1000,993,807,400,569,201,664,874,419,146,315", "170,950,424,782,764,890,921,226,73,819,690,542,725,267,59,767,26,503,824,964,782,837,797,963,205,860,935,480,310,627,552,412,402,570,935,113,177,611,643,782,888,179,341,628,849,719,872,524,262,454,752,470,412,448,845,550,726,865,258,990,447,558,389,311,730,223,780,800,221,247,682,857,102,976,150,707,945,459,640,225,566,576,873,360,865,171,733,206,174,178,667,545,756,299,241,666,606,263,83,409,160,76,657,51,856,62,105,903,71,903,227,386,927,55,718,919,705,476,910,166,671,299,165,835,858,831,833,572,30,29,31,92,847,381,111,444,281,523,879,277,656,376,578,344,696,349,272,488,115,610,76,207,302,105,801,947,322,479,696,120,309,745,734,794,963,839,799,501,576,13,155,264,240,974,633,775,616,905,446,603,986,975,579,912,637,758,159,644,900,84,716,696,287,144,971,280,826,748,224,846,941,941,867,171,94,887,414,596,905,22,447,909,597,937,455,416,226,942,983,356,331,666,705,135,686,626,746,453,781,140,538,67,225,675,331,112,831,243,585,274,875,537,749,624,490,236,941,274,387,450,48,829,46,229,568,125,701,787,148,131,609,793,571,991,681,506,871,597,483,10,577,235,666,558,831,293,708,181,856,254,38,402,310,376,537,439,114,74,722,68,998,549,755,238,936,765,896,637,807,662,619,839,829,110,213,896,41,648,830,948,216,569,304,28,510,982,32,406,690,473,760,219,44,203,542,857,121,667,857,839,257,889,839,203,544,497,429,857,21,954,628,277,591,637,998,619,869,615,948,106,25,867,955,388,849,494,0,937,585,495,201,557,920,347,213,476,756,489,171,853,933,839,739,750,898,766,916,702,656,685,83,872,562,582,35,822,26,684,673,529,623,273,358,7,60,167,133,502,458,222,284,565,791,587,288,549,400,124,117,712,895,549,975,58,904,428,354,733,315,925,909,598,831,279,145,232,154,360,181,447,611,748,208,731,829,534,498,845,613,864,606,799,179,796,744,595,205,206,549,695,976,698,710,628,187,946,847,94,719,80,658,527,720,655,80,759,165,17,372,609,465,559,134,122,505,457,258,247,406,902,170,748,110,93,121,292,999,500,991,416,592,216,530,871,826,277,39,460,206,945,107,926,911,100,26,242,247,982,76,864,679,377,969,666,307,592,66,356,251,167,446,966,128,265,285,362,694,445,768,417,991,57,154,633,112,937,427,551,131,386,157,619,348,258,386,303,498,309,855,259,545,156,169,94,185,400,461,60,349,931,405,161,499,804,361,593,24,876,663,391,992,768,960,522,445,185,840,460,619,248,96,43,926,625,643,926,640,610,545,909,773,812,632,583,380,756,399,443,326,477,147,126,861,678,856,373,397,531,209,80,632,648,636,221,14,276,820,594,606,284,63,527,966,80,525,281,984,862,114,70,240,232,453,397,933,132,345,331,441,508,197,487,522,157,956,181,698,792,280,531,976,377,827,570,911,429,232,255,385,407,43,349,524,829,934,928,29,91,728,320,853,498,561,929,319,128,709,304,804,462,35,637,929,860,533,377,429,633,943,701,211,816,223,791,576,52,714,409,259,569,101,324,815,679,779,136,358,710,822,540,861,998,714,15,463,552,212,763,408,128,565,563,71,620,269,306,454,163,165,801,538,5,627,816,959,644,449,746,181,195,218,422,456,27,363,361,992,988,182,338,337,14,971,12,303,883,414,367,514,821,312,151,301,847,654,115,847,457,212,616,265,547,665,227,170,610,662,117,684,381,447,665,362,816,914,230,4,819,681,384,699,636,696,122,961,402,783,36,499,286,73,689,845,986,815,254,897,190,570,120,153,698,717,517,746,675,772,445,447,281,334,281,500,833,117,96,225,421,257,90,690,912,427,916,110,856,480,554,237,838,806,276,987,911,660,295,578,283,431,341,885,701,630,934,974,544,507,997,391,645,794,285,452,935,958,490,535,935,362,480,524,385,488,644,64,995,747,801,757,558,864,357,534,688,650,213,352,851,485,957,580,657,833,189,228,211,861,522,912,448,182,452,364,59,522,223,207,857,784,436,201,589,301,234,97,626,509,302,881,626,182,101,39,124,173,48,901,167,222,230,560,581,923,870,421,659,725,235,37,980,196,616,42,945,628,532,403,269,962,205,675,733,678,365,43,233,899,21,602,299,62,407,105,161,2,27,48,184,435,810,658,557,817,454,376,782,880,786,63,49,904,768,586,665,141,333,148,82,2,74,43,64,105,606,242,78,883,200,45,66", "75,316,351,884,716,789,596,356,464,542,903,11,460,532,252,506,72,318,565,350,34,81,825,90,157,206,859,988,55,79,948,211,334,502,895,664,222,385,153,593,922,785,559,308,476,306,459,987,641,109,826,589,492,746,939,770,403,161,208,31,94,248,880,429,789,548,847,513,440,702,845,29,650,493,466,734,837,514,385,282,485,344,12,379,267,732,938,675,544,425,972,612,157,216,272,156,461,459,165,628,711,866,636,473,776,645,116,577,454,476,110,524,934,533,880,852,6,663,593,360,238,664,538,205,958,396,58,454,779,266,511,687,509,926,575,683,533,476,448,842,161,281,5,184,328,161,299,691,682,573,400,224,700,702,722,364,429,852,280,272,36,454,959,965,529,929,458,602,456,624,57,386,318,302,633,215,956,626,57,19,707,357,49,773,677,835,155,10,625,694,150,718,791,459,258,490,523,135,136,61,53,158,980,79,50,88,733,996,253,754,953,493,480,472,460,390,248,972,752,268,801,204,787,384,777,18,811,771,605,257,926,244,221,660,838,55,344,350,837,610,394,519,491,46,673,655,593,938,2,595,968,556,440,145,963,565,341,571,996,376,823,293,606,595,702,427,173,803,626,89,967,489,543,945,611,432,913,271,274,800,357,683,294,930,867,224,774,111,673,467,191,32,306,586,81,226,108,462,807,865,344,656,344,73,96,859,117,115,96,320,292,911,141,272,344,173,167,514,57,358,917,58,740,695,512,187,452,670,697,915,646,58,147,303,791,46,837,352,861,720,609,799,878,946,458,161,990,696,331,500,255,366,710,291,675,168,937,0,549,562,735,518,523,452,833,284,619,798,505,354,51,867,270,659,600,386,155,501,934,161,261,324,190,576,307,165,205,355,446,331,456,458,354,144,155,174,723,955,938,772,549,979,547,940,607,122,693,776,368,921,404,8,179,491,632,46,935,88,368,309,904,787,664,823,947,229,904,263,555,385,988,780,552,559,967,602,283,437,829,737,585,277,116,391,376,148,664,134,569,297,993,496,304,787,810,931,83,557,297,124,55,744,552,348,418,103,338,55,271,797,915,66,546,585,851,201,248,830,681,341,920,645,906,866,718,470,818,858,749,496,732,523,79,767,423,419,814,500,275,432,984,549,592,267,702,916,31,908,538,497,747,474,323,792,257,148,268,590,48,246,436,972,530,510,370,56,215,192,700,240,83,621,224,108,355,250,462,639,149,840,19,658,592,836,45,889,361,953,409,11,766,553,682,165,610,91,564,245,3,156,688,493,462,466,936,774,883,894,822,465,922,86,732,206,382,622,332,341,152,430,548,206,705,998,436,934,593,23,930,230,456,582,516,327,782,690,285,987,25,827,616,685,238,577,784,517,134,179,77,760,386,331,130,891,955,325,698,443,224,635,641,613,19,461,48,275,521,218,262,179,577,321,319,612,445,417,295,563,760,79,779,723,466,800,778,388,870,473,263,219,692,428,169,711,915,672,708,684,935,364,83,300,753,577,587,197,255,682,644,129,609,746,638,251,127,486,564,443,192,542,837,425,611,275,972,977,949,715,295,838,539,936,754,333,202,252,316,663,594,606,344,832,807,741,399,616,231,107,787,508,188,601,975,943,555,599,447,347,522,522,994,53,833,401,95,444,455,711,762,972,593,826,401,291,747,253,862,345,874,568,474,189,752,265,270,400,854,216,988,657,135,341,559,653,537,648,667,140,723,12,162,287,805,77,179,423,828,152,125,558,151,249,695,712,451,18,510,452,602,439,727,137,860,41,193,354,896,777,797,210,757,549,928,53,441,298,814,195,502,747,229,764,318,156,245,570,430,385,374,250,112,322,755,245,364,570,681,550,355,275,492,986,689,64,978,816,395,86,692,723,184,875,187,483,707,583,894,577,198,569,623,531,425,12,128,7,728,781,69,330,829,674,731,738,375,712,210,955,949,956,213,38,726,999,61,781,182,496,870,130,80,767,456,412,687,227,768,691,96,990,976,598,535,530,235,935,43,192,747,363,257,660,980,550,810,530,232,773,68,990,770,873,8,81,653,138,837,510,865,635,325,437,893,874,791,407,14,874,689,224,227,32,743,487,81,982,400,466,113,408,45,962,270,389,673,987,857,240,646,159,460,785,857,326,151,727,676,322,320,209,854,411,839,590,537,504,797,247,489,504,987,208,830,121,220,145,468,760,4,773,968,203,770,452,333,90,76,650,688,728,482,699,876,92,976,878,931,917,5,648,15,293,998,286,642,747,126,838,216,673", "788,235,634,518,100,873,405,638,930,236,664,212,707,122,599,486,631,75,184,480,248,998,497,137,218,461,758,433,670,49,899,532,556,912,105,804,746,303,316,834,835,150,913,396,444,861,100,237,999,107,328,680,356,685,176,641,989,479,464,665,513,92,833,733,818,828,747,288,963,359,639,160,726,409,685,166,813,66,368,624,35,185,327,942,560,20,840,742,901,993,291,369,285,732,606,454,753,196,598,184,280,820,518,505,904,163,696,597,429,898,182,72,9,351,968,787,619,909,146,873,259,146,665,479,559,972,496,298,357,605,775,907,911,776,421,957,994,281,207,243,422,841,423,13,214,913,327,759,327,586,505,438,130,92,870,768,313,88,444,943,108,321,310,353,978,510,250,424,303,176,76,748,337,454,65,182,580,813,266,310,732,769,704,744,890,688,963,240,842,950,535,305,622,413,876,644,988,837,461,65,135,542,591,74,940,289,950,363,279,933,494,192,585,945,603,447,134,733,253,902,441,807,360,396,512,716,182,433,196,599,400,540,925,36,614,362,689,714,19,62,63,237,244,289,447,582,272,631,780,711,345,736,367,80,132,674,639,624,413,717,242,805,657,655,988,878,774,883,503,274,656,291,734,528,552,840,403,52,767,449,140,590,928,259,823,212,260,616,412,555,247,705,629,369,896,499,470,393,703,223,994,228,498,948,592,919,648,190,630,755,447,994,874,420,391,290,236,953,218,364,5,988,259,621,177,701,148,198,290,53,565,730,199,904,190,870,587,457,770,564,749,239,823,765,70,594,699,528,260,341,121,246,109,90,66,816,585,549,0,740,432,444,270,385,241,553,924,244,964,142,365,537,6,224,243,201,663,303,569,717,88,221,87,266,657,540,765,656,910,134,514,923,947,361,602,570,602,779,343,622,214,469,385,952,79,966,446,484,829,938,714,618,115,227,893,445,686,837,244,528,733,601,246,491,378,333,801,161,532,21,928,112,88,448,374,613,643,109,891,209,659,791,685,282,736,629,612,345,687,387,204,71,377,267,311,784,695,258,842,146,749,796,174,747,434,560,829,654,835,81,608,772,330,732,225,857,977,440,94,372,60,764,822,488,683,347,476,616,560,416,587,415,233,480,525,928,533,7,867,654,932,844,864,353,318,63,378,318,858,947,280,716,563,346,555,862,504,206,223,354,570,914,657,213,149,148,32,883,773,891,118,505,949,565,96,370,467,887,528,98,600,678,66,378,817,499,994,529,852,461,999,740,421,540,802,986,404,703,417,507,271,45,748,874,828,645,927,4,719,870,690,166,720,616,30,109,975,522,423,365,34,657,1,820,458,258,861,924,732,54,452,240,82,189,35,557,636,729,7,976,73,573,657,84,516,261,241,288,355,985,524,990,188,269,700,206,449,49,645,251,393,600,423,26,958,785,229,62,290,429,915,497,706,333,680,859,254,955,301,984,843,996,559,903,225,177,353,56,604,776,593,390,437,421,171,739,628,494,408,368,149,445,491,926,298,339,943,828,284,971,116,25,59,442,767,473,416,372,820,901,551,583,16,781,681,435,15,951,542,341,196,388,493,392,59,411,26,287,427,984,742,66,584,569,567,581,316,969,199,658,406,102,134,430,226,918,948,975,797,694,237,427,871,916,399,300,255,606,943,216,742,333,10,70,999,210,817,581,584,5,137,699,569,844,948,970,628,866,236,115,151,899,639,436,474,495,975,771,561,543,515,687,280,729,859,173,597,427,707,101,674,254,972,363,311,964,977,223,666,887,871,447,735,838,6,502,857,587,72,896,627,381,877,554,417,628,593,464,460,751,893,374,973,700,555,307,754,207,719,343,110,926,478,137,527,378,256,103,692,373,876,775,913,104,602,802,420,587,85,285,365,81,243,671,993,355,498,448,880,22,312,422,210,902,877,846,521,92,517,324,656,729,278,182,30,900,321,55,829,660,130,208,681,945,825,51,284,256,928,132,247,488,666,764,854,306,331,36,411,527,397,730,520,208,658,969,50,584,359,988,384,192,514,991,987,123,598,372,677,527,231,178,236,338,905,131,847,758,506,148,600,156,743,628,651,910,794,479,135,592,735,28,266,504,839,941,323,174,328,480,665,704,319,202,148,146,781,653,959,352,254,799,918,272,62,457,167,947,322,759,450,184,792,941,722,777,301,248,76,155,125,751,838,580,905,854,588,653,345,771,309,516,402,232,107,805,595,49,339,302,607,838,152,599,808,494,297,640,654,467,239,583,996,229,514,831,652,26,641,651", "675,236,190,356,162,258,75,990,953,609,116,86,654,992,719,833,587,296,139,877,726,472,493,660,594,598,539,250,512,449,307,287,171,16,568,348,740,779,118,29,834,412,494,408,750,678,968,262,484,251,773,906,19,220,289,591,181,342,710,645,359,338,46,202,938,714,651,229,472,585,424,849,277,610,201,377,724,311,315,375,169,570,522,174,628,729,559,630,619,711,522,526,706,678,385,971,839,196,292,253,197,84,829,478,717,733,992,146,153,164,343,866,599,758,52,895,395,234,43,247,133,204,515,188,515,211,790,576,104,656,152,249,297,973,605,668,687,880,65,220,714,510,635,868,157,298,886,910,566,981,138,738,699,990,803,751,853,730,439,954,938,622,727,739,449,724,254,587,990,269,635,764,149,683,630,655,143,138,2,139,115,597,274,434,29,81,150,58,56,15,486,22,868,378,391,154,92,568,799,165,423,602,146,439,593,644,412,967,162,518,859,743,921,360,164,896,487,766,760,609,157,160,539,235,554,739,171,71,132,15,414,457,277,369,151,855,325,75,943,899,236,110,309,220,147,646,412,939,223,478,933,677,92,698,152,478,927,388,2,611,68,873,955,149,598,32,40,785,199,874,50,565,980,485,266,266,876,108,6,722,789,517,291,970,33,682,495,13,20,580,937,701,953,573,549,567,784,159,210,29,841,844,666,836,751,642,841,628,258,246,564,403,979,309,27,946,853,674,564,964,224,18,268,482,864,377,237,301,244,167,214,708,209,837,623,715,991,477,983,946,4,802,877,268,99,769,686,158,412,848,30,784,159,718,952,590,495,562,740,0,951,586,612,126,601,705,340,51,767,787,237,28,940,370,663,561,364,204,910,718,196,477,613,694,20,442,693,348,802,645,453,260,977,441,228,713,822,857,755,792,715,610,158,940,957,550,202,304,497,130,723,149,102,56,981,418,278,962,232,528,521,753,460,805,775,347,607,346,338,720,532,955,779,407,882,253,347,53,813,996,825,462,70,181,791,870,518,621,479,348,131,772,856,412,425,419,696,579,57,546,156,833,650,703,43,518,379,279,614,513,93,613,161,607,337,924,842,884,562,599,316,521,148,554,282,310,964,911,74,174,725,544,308,214,763,948,703,548,778,795,100,698,556,653,89,971,708,436,90,969,98,386,123,928,631,868,513,291,466,818,703,152,56,174,367,159,648,297,542,925,730,272,422,102,68,857,550,438,877,901,399,133,88,340,459,417,112,555,345,372,411,823,228,186,739,451,31,46,977,408,931,224,382,383,452,616,499,86,777,261,933,996,736,217,350,493,562,29,875,65,810,391,74,282,82,765,237,759,618,753,641,568,10,467,178,781,995,36,296,762,513,746,484,111,949,196,200,844,392,999,19,788,587,535,572,307,927,271,862,424,105,347,697,469,934,440,580,328,862,379,483,948,763,950,115,812,512,748,871,793,559,5,385,560,622,402,838,260,609,374,36,134,756,364,749,553,426,285,617,974,357,988,637,826,342,556,927,228,272,583,56,280,844,778,36,140,610,457,481,138,785,199,186,691,598,864,901,960,327,599,908,417,516,698,690,673,51,637,107,509,224,27,908,819,355,142,698,876,257,575,264,628,539,464,168,654,352,675,104,314,94,982,506,401,854,516,173,159,294,441,60,674,925,572,76,248,275,996,740,222,836,133,253,500,756,478,271,392,316,904,372,63,770,683,182,688,895,320,38,326,870,254,44,86,584,246,285,125,800,57,241,9,299,48,33,291,627,705,21,481,65,389,783,98,673,948,37,264,51,915,715,484,156,119,363,924,526,466,755,244,971,399,988,128,601,872,755,992,987,174,152,154,277,42,899,600,418,177,411,648,641,436,701,197,162,206,408,87,871,304,827,296,655,183,692,964,918,441,333,596,1,896,308,973,974,819,154,670,318,337,28,51,88,373,712,36,174,827,630,796,811,804,815,428,235,260,658,843,333,237,213,201,864,321,343,617,756,256,204,174,116,266,451,162,429,280,452,76,764,625,254,742,687,55,575,800,575,107,842,738,303,437,189,719,806,517,984,376,36,568,460,31,42,119,104,681,684,573,666,184,868,623,277,667,939,522,958,787,812,604,562,263,444,536,880,358,606,809,62,889,984,792,962,185,105,496,774,555,548,984,872,38,720,297,747,879,263,740,585,115,699,875,664,913,31,409,627,535,697,545,63,538,484,931,227,374,480,298,110,531,389,699,513,585,81,90,337,408,71,873,339,737,845,23,257,983,39,89,931,235", "661,786,90,981,636,187,522,527,798,518,340,766,316,263,473,365,67,866,148,284,895,418,1,926,254,320,659,540,464,840,698,829,330,899,894,518,587,930,617,287,879,84,923,723,445,27,916,982,981,936,481,32,614,709,532,178,129,27,499,920,615,243,305,875,556,251,410,346,218,718,664,929,146,290,819,968,188,988,116,188,586,903,65,486,986,776,770,944,32,719,73,791,839,789,883,126,890,235,294,832,526,731,226,260,114,639,509,411,832,881,172,457,66,545,753,569,836,574,689,272,589,104,618,614,673,933,483,293,930,941,294,468,845,207,198,540,133,836,847,349,478,232,313,728,804,368,130,702,592,342,953,272,55,544,78,160,102,121,956,813,578,835,218,673,537,773,115,116,19,941,95,281,589,682,704,349,580,680,913,599,392,388,712,555,380,377,298,731,812,573,411,489,290,229,320,45,660,40,251,687,181,117,50,666,928,774,4,779,644,475,868,405,615,450,110,738,748,124,369,134,588,254,324,986,883,910,572,855,268,969,953,541,238,713,7,207,267,588,861,891,273,675,160,856,949,870,967,227,974,396,232,444,107,735,756,552,295,233,67,223,951,869,202,604,1000,706,974,418,351,902,565,235,531,610,931,122,449,449,930,373,155,836,157,148,460,583,989,29,446,336,316,570,891,853,563,249,501,433,5,650,711,339,669,925,634,574,606,871,459,811,688,846,45,158,51,243,201,56,713,303,378,897,630,771,330,244,664,791,609,974,640,332,290,488,146,137,641,169,644,649,762,218,816,483,142,712,142,615,990,490,230,260,480,210,204,708,201,735,432,951,0,100,389,748,728,290,352,501,563,88,962,516,822,323,65,99,841,671,258,576,236,247,127,994,231,676,640,235,209,768,813,156,216,999,642,650,27,676,901,881,559,83,834,652,167,695,622,348,377,421,205,27,188,919,850,843,449,562,744,613,731,775,975,172,199,110,749,708,201,793,890,873,885,779,726,528,608,697,433,883,696,766,489,292,157,475,539,947,59,184,359,825,627,362,560,113,238,839,899,760,583,420,984,965,302,180,201,401,985,326,277,304,509,332,303,133,192,904,491,244,267,677,718,168,64,105,939,375,957,332,402,223,776,947,908,246,765,324,949,237,901,947,691,3,981,146,871,120,378,451,137,342,411,446,684,523,327,641,737,239,28,981,504,434,732,674,593,519,715,353,464,548,87,699,624,63,86,57,792,158,700,360,362,161,513,160,841,849,850,977,130,179,358,923,25,58,289,814,667,802,596,803,276,170,847,915,923,694,702,567,110,551,847,550,812,749,337,104,276,303,300,198,24,340,790,867,853,130,252,322,735,298,907,252,270,619,109,419,202,889,429,235,323,953,476,268,592,180,313,626,627,181,616,999,354,599,236,396,170,631,237,306,845,284,319,737,950,882,306,821,796,234,606,37,676,336,170,662,156,336,221,660,318,705,534,618,675,604,316,884,964,292,443,191,495,297,555,388,316,264,775,995,228,61,878,452,57,161,894,316,618,879,112,559,829,967,168,730,25,465,838,591,584,37,407,806,298,542,975,170,728,165,44,781,774,507,832,383,413,418,461,997,218,562,59,873,607,821,422,961,3,922,368,496,201,646,164,561,897,281,558,428,921,50,864,412,150,945,451,832,980,871,619,427,999,816,598,63,35,42,244,42,90,617,582,876,659,324,38,855,468,696,13,290,988,590,599,391,389,172,138,472,92,71,174,15,557,249,695,250,836,280,556,476,3,340,49,37,263,546,65,296,297,169,435,300,170,231,328,261,30,718,834,862,304,736,862,56,53,447,672,661,136,373,751,595,852,245,878,592,397,166,168,431,115,667,555,995,665,802,557,715,929,529,212,295,360,335,239,175,751,476,808,166,447,493,986,829,212,555,469,24,209,87,737,730,833,477,436,55,137,111,465,554,367,870,244,488,693,247,359,691,556,435,74,391,853,164,862,811,163,49,351,38,197,840,949,731,59,823,116,292,634,692,319,729,578,65,601,452,624,849,107,592,606,645,832,602,728,502,915,418,627,972,320,895,399,638,107,357,537,311,915,493,489,719,679,363,192,46,312,800,840,952,595,759,416,698,999,832,730,182,662,46,823,136,911,461,60,68,790,26,59,839,827,488,225,766,59,685,225,995,85,981,407,714,187,722,484,903,185,319,373,877,702,37,934,845,732,907,277,907,334,114,189,256,787,810,509,740,827,750,855,183,329,280,201,654,212,280,514,482,560,845,300,713,353,515,925,397", "697,502,507,248,592,634,322,670,736,117,956,903,922,149,21,206,26,245,84,421,403,220,414,864,264,147,38,804,951,727,718,847,222,404,613,842,989,105,54,71,92,461,213,264,425,942,110,679,255,801,106,522,215,627,883,934,287,324,983,240,602,13,496,867,301,567,904,548,888,81,911,189,998,604,270,706,99,477,180,604,391,405,187,316,947,313,801,378,3,970,215,804,294,219,773,899,634,922,433,368,834,696,592,395,482,115,465,674,985,705,36,853,157,633,47,307,515,182,875,106,268,405,853,443,422,813,814,413,278,842,219,363,667,782,207,385,768,289,200,264,4,872,620,644,385,830,990,355,332,261,903,724,174,767,204,674,191,824,398,866,705,128,522,450,1000,859,777,572,97,454,744,310,376,468,971,639,595,930,56,148,408,294,209,862,813,951,588,528,654,161,743,983,675,807,120,569,214,429,928,922,974,715,428,345,193,804,536,736,38,694,962,258,5,129,12,339,567,450,726,200,217,62,422,326,874,352,670,73,180,302,980,103,148,560,258,319,299,141,768,495,686,945,877,70,801,606,228,942,154,180,743,922,492,685,67,884,906,637,66,143,818,342,224,712,262,406,803,773,162,20,928,616,618,308,82,184,234,182,913,700,60,842,610,560,422,17,909,885,667,792,381,665,454,183,329,180,122,61,76,770,985,302,830,735,159,355,135,659,784,836,116,871,664,131,691,35,905,437,974,326,162,638,336,230,214,742,646,639,752,592,272,506,270,654,616,511,755,371,264,709,523,774,684,719,75,590,301,545,80,599,808,2,652,74,733,379,557,518,444,586,100,0,794,627,898,388,172,88,171,879,904,284,558,476,274,169,617,250,690,814,330,555,652,402,628,151,655,88,228,747,266,366,661,5,986,627,204,231,226,893,387,302,999,15,798,602,196,994,296,42,91,799,436,440,975,226,890,624,360,724,720,674,191,813,225,925,989,847,98,827,160,256,670,711,480,364,17,957,286,436,251,610,225,304,597,114,413,345,198,537,94,873,561,273,325,937,323,132,833,613,37,168,156,265,527,211,325,646,177,460,835,440,996,339,120,711,286,283,407,228,758,579,467,450,343,573,946,747,951,648,173,618,391,339,916,852,812,879,786,783,984,412,83,702,178,550,778,330,911,294,529,94,235,972,289,123,214,138,15,199,183,475,107,12,284,422,794,558,707,206,950,627,99,874,130,845,244,321,293,453,835,389,622,50,233,253,52,953,832,539,655,541,941,493,541,614,46,349,963,609,287,432,885,836,556,212,941,144,311,161,759,189,613,111,850,602,711,149,888,447,519,517,520,769,343,563,271,769,199,708,417,368,224,245,94,219,664,287,238,410,18,772,681,577,251,404,64,425,201,881,828,569,358,184,88,395,271,673,781,372,895,507,704,504,864,129,963,461,594,919,391,815,994,55,215,750,975,331,858,786,437,492,953,689,118,57,965,945,209,655,545,244,171,660,598,120,674,99,977,807,828,92,769,576,446,183,462,938,647,476,619,416,304,991,66,124,805,677,715,178,904,76,744,638,415,577,933,59,55,218,317,672,829,724,45,861,75,91,299,164,494,922,639,489,791,419,498,14,854,203,555,440,375,569,454,124,340,706,529,286,707,875,988,703,943,335,669,411,81,332,954,140,498,692,730,383,874,698,201,92,633,60,14,119,461,668,318,518,913,146,712,526,119,960,353,298,426,365,861,455,968,908,955,524,618,472,263,474,990,623,258,210,42,969,823,613,43,124,351,844,868,899,351,925,403,87,505,382,23,998,414,489,256,140,401,169,51,348,497,373,400,984,649,643,601,998,430,262,709,312,605,300,734,677,93,967,90,31,613,964,484,778,694,610,720,139,538,133,176,780,224,877,578,633,373,732,949,753,647,889,161,684,778,285,679,577,574,438,26,701,720,159,185,11,370,213,222,714,100,657,172,8,577,186,208,645,952,37,35,869,66,351,988,523,854,203,318,654,597,79,527,578,582,748,793,788,601,997,142,618,561,178,814,99,382,993,140,471,58,719,632,450,264,591,153,469,465,183,552,370,928,112,508,955,672,198,82,541,646,916,86,113,214,258,289,26,500,677,86,471,94,649,925,275,702,820,736,197,750,754,389,442,390,590,736,41,622,859,817,71,437,899,168,298,805,163,89,105,703,216,169,865,120,576,419,179,717,228,577,134,917,968,755,15,65,349,656,193,913,588,587,68,443,61,122,234,28,554,822,237,186,290,139,965,853,476,947,416,912,271", "632,476,122,862,792,205,838,763,960,1,819,311,996,387,919,471,498,490,45,485,963,725,626,880,501,383,220,185,4,781,595,452,781,663,653,327,21,329,524,255,415,96,280,883,66,66,209,360,424,796,792,704,843,587,476,391,727,777,986,297,633,626,858,918,83,578,184,854,377,804,924,680,887,486,859,187,186,997,648,655,97,627,751,49,700,369,81,796,948,513,807,256,159,973,883,533,809,961,61,92,166,259,397,926,473,2,441,656,787,503,512,363,430,858,986,810,192,881,84,842,964,243,333,927,77,530,741,492,246,751,579,592,122,814,189,147,465,487,45,884,240,980,983,723,950,752,995,277,760,928,734,442,477,979,930,370,52,424,653,211,333,515,104,849,739,863,337,889,476,967,676,112,115,546,165,379,357,5,886,681,276,492,251,579,820,445,431,433,967,248,539,135,979,871,394,449,902,527,9,612,766,199,406,712,491,209,795,688,911,431,800,203,649,584,831,328,48,19,898,356,829,783,988,920,969,314,940,86,668,468,390,307,178,40,25,742,519,221,696,226,678,724,430,391,317,707,35,585,472,4,798,450,584,263,778,737,714,995,553,115,757,453,869,764,164,244,933,341,218,651,231,671,4,431,753,410,494,2,475,385,380,738,485,924,512,467,919,510,555,451,998,260,398,552,45,487,364,109,417,336,279,862,515,811,884,131,105,635,803,938,750,187,137,808,3,711,398,434,986,828,232,364,382,84,421,274,267,103,346,929,877,826,736,703,897,661,271,145,808,724,709,109,137,588,672,918,564,398,177,612,668,740,266,448,315,714,920,523,270,612,389,794,0,333,256,616,150,165,822,748,720,735,920,161,430,475,536,553,824,408,524,250,947,279,743,499,99,249,242,679,870,150,886,328,421,906,7,331,929,168,143,211,952,912,535,644,90,510,244,890,940,76,903,138,550,170,601,721,323,334,71,843,392,96,283,161,621,227,39,701,887,87,464,199,458,312,560,583,152,916,358,277,633,237,874,192,889,204,721,265,499,314,96,534,438,268,899,755,443,636,400,340,150,495,22,712,473,246,247,106,138,35,310,40,86,227,304,35,992,249,520,141,371,879,947,952,638,817,886,876,239,173,482,372,668,796,257,872,499,491,494,237,922,353,926,487,763,15,453,294,197,550,747,156,829,503,158,485,400,91,697,71,348,287,421,235,249,884,401,87,407,378,339,203,600,798,714,488,410,118,95,159,5,809,26,398,744,98,250,275,835,202,39,817,381,946,167,621,653,536,391,923,242,186,125,550,176,639,323,481,376,83,745,294,805,613,338,543,309,421,475,189,839,500,639,340,77,274,974,573,124,322,274,168,224,164,356,643,910,526,640,659,221,94,642,494,136,517,162,750,1000,2,184,259,604,826,778,931,168,781,224,245,969,185,342,940,90,802,532,493,509,156,905,829,183,959,987,913,905,119,377,321,74,542,233,240,638,141,770,935,465,881,86,95,899,727,272,465,605,311,858,860,153,687,526,324,443,830,739,950,278,147,386,935,99,173,573,178,737,488,33,991,126,160,815,741,604,742,701,390,425,498,605,169,184,195,992,878,240,740,521,333,15,868,64,271,266,365,94,467,664,327,712,806,275,89,167,950,680,531,247,894,1000,716,915,310,399,164,2,930,840,889,668,327,902,755,128,72,670,361,122,359,941,875,223,520,52,518,847,548,463,749,455,71,563,699,219,565,101,787,328,981,471,480,677,430,474,125,907,179,647,519,485,135,256,540,315,877,712,115,358,392,54,887,510,873,29,852,148,993,162,280,468,126,68,150,211,621,886,706,734,418,458,529,170,698,155,882,752,959,975,647,40,693,946,393,811,693,570,666,507,204,115,595,798,991,860,640,455,874,298,333,426,247,784,133,747,814,48,646,817,913,406,925,623,873,555,43,89,65,293,353,320,841,796,906,804,893,384,379,273,189,968,881,915,495,725,240,547,479,97,126,888,454,858,77,772,412,153,691,259,85,923,965,417,714,706,345,373,39,941,474,954,895,480,263,181,665,956,324,843,794,62,128,264,937,264,617,575,58,672,947,651,590,185,936,65,921,312,633,445,705,85,348,860,819,571,611,707,877,126,112,926,980,182,329,918,386,145,81,49,471,532,564,471,241,484,35,34,732,73,759,886,291,595,63,850,478,179,472,245,568,275,206,664,183,104,158,218,377,535,652,441,73,154,732,819,712,350,970,383,661,525,44,517,161,646,737,706,552,403,404,635,684,996,736,586,370,384,588", "185,804,398,177,827,397,198,73,740,202,17,204,342,670,603,271,988,768,327,657,857,491,873,921,781,90,825,223,409,514,312,612,926,509,396,119,610,376,676,345,309,960,241,84,2,603,18,377,745,547,128,133,734,697,424,944,617,206,683,166,578,990,834,236,208,413,193,771,999,225,659,413,940,950,754,726,297,62,500,528,432,165,178,783,110,550,634,799,890,858,837,888,313,379,821,34,475,802,844,354,748,871,588,75,43,168,763,18,873,402,101,311,725,87,333,382,5,359,656,197,831,652,399,19,22,168,216,500,200,264,872,983,575,960,518,322,928,975,122,25,664,580,863,129,99,776,752,105,923,330,559,244,401,775,172,591,804,246,828,816,92,29,627,584,140,617,593,350,454,272,290,58,593,760,439,371,600,279,44,338,535,944,93,112,470,782,189,103,462,606,640,262,453,273,73,563,245,650,120,836,110,654,768,665,889,283,559,275,108,848,832,949,915,201,75,101,461,871,884,744,803,148,968,492,345,9,382,680,521,19,60,864,580,606,698,182,907,616,806,508,417,429,67,454,374,381,573,780,808,708,305,457,399,425,104,161,707,150,274,875,104,190,103,991,304,286,292,452,809,108,118,304,116,504,770,617,922,366,191,419,100,719,386,643,629,648,768,516,585,309,154,280,88,305,319,858,840,889,848,335,910,675,333,739,656,52,191,340,164,633,965,42,999,652,231,312,538,200,533,712,51,789,350,361,514,697,3,508,100,294,658,799,594,782,373,622,281,348,985,361,134,786,9,570,175,825,995,128,192,116,881,480,151,922,618,560,347,452,385,126,748,627,333,0,41,291,632,201,719,34,357,396,980,166,3,467,509,257,805,353,901,294,612,203,17,28,131,134,775,489,16,61,562,650,209,976,991,213,407,998,960,582,586,964,518,701,581,774,136,335,322,257,406,44,964,488,449,76,766,299,343,946,254,236,879,660,902,196,486,426,867,286,85,966,415,431,647,605,556,395,98,922,438,239,975,268,26,765,103,752,280,101,725,698,595,697,388,334,523,589,302,83,182,951,58,503,857,643,252,723,699,348,548,413,598,183,563,92,563,840,406,680,984,12,662,657,982,479,659,402,366,621,153,177,342,990,6,924,202,275,855,532,440,527,129,894,296,148,98,928,555,84,445,509,518,927,980,165,567,86,283,429,258,290,476,569,93,749,870,618,425,782,721,542,356,52,761,543,447,995,154,602,732,10,949,317,721,970,168,833,328,485,183,660,341,954,768,508,81,833,235,667,730,195,300,884,371,158,122,242,892,687,704,595,443,640,38,151,388,586,726,228,108,440,969,958,327,839,413,804,942,739,909,533,860,412,548,149,451,408,443,703,330,420,860,60,865,198,436,143,573,340,732,72,355,256,491,837,961,472,173,135,226,25,300,485,200,649,740,744,884,97,524,153,611,774,379,757,413,719,520,827,335,674,301,534,329,849,350,702,847,727,514,424,198,24,913,796,284,901,409,254,308,821,454,121,685,737,660,512,481,952,845,360,574,789,979,161,273,854,773,8,149,379,100,232,890,780,314,387,577,832,77,598,913,591,729,608,230,721,30,701,897,633,529,4,515,621,459,598,475,219,299,41,323,74,577,691,810,164,994,324,672,619,686,338,80,161,688,652,201,202,961,549,65,462,301,885,47,581,781,944,737,1000,894,33,16,26,1,476,342,153,214,830,871,165,23,986,324,779,297,921,494,632,942,3,761,335,362,190,95,629,705,112,947,302,877,183,879,964,55,247,95,480,449,42,983,624,18,833,606,292,516,159,896,146,536,627,412,132,262,152,187,897,33,449,883,93,192,93,939,741,433,370,23,427,853,879,928,440,374,539,38,46,148,745,44,818,879,415,611,386,556,98,954,226,724,748,312,751,698,380,610,966,869,409,680,62,440,300,570,839,222,8,833,616,109,219,435,604,188,224,898,271,674,699,641,677,873,377,807,500,430,667,117,96,764,702,628,497,46,104,122,824,528,296,702,255,709,306,701,897,382,806,788,509,962,476,828,142,973,183,826,446,531,758,568,254,381,946,405,725,297,574,860,527,628,465,430,903,139,587,264,905,343,34,235,180,407,336,746,919,509,302,710,107,48,135,147,424,260,647,329,735,559,391,98,53,4,521,81,230,517,746,224,102,303,687,710,767,897,118,798,265,76,681,591,414,331,857,35,424,373,904,897,231,78,625,818,280,609,129,989,168,833,951,113,91,618,667,5,574,1,878,436,73,65,574,863,54", "283,44,763,472,181,870,354,270,835,725,26,340,585,554,781,831,772,948,479,180,630,982,221,448,168,516,865,884,320,349,807,50,112,589,334,226,344,98,88,973,290,682,636,699,878,514,793,99,432,295,89,238,804,39,321,756,287,844,547,610,152,482,561,483,692,272,861,434,615,89,228,918,63,169,505,875,451,137,146,683,861,137,137,96,686,650,514,402,206,721,464,119,556,123,370,600,127,790,661,197,903,602,240,458,351,764,375,501,910,187,553,362,78,752,275,732,591,3,157,916,822,866,665,760,541,741,62,210,423,500,981,378,84,383,89,778,63,817,30,792,678,303,956,223,71,951,918,281,249,729,351,45,53,674,742,294,557,670,623,970,976,646,354,999,983,689,547,213,554,927,166,134,109,423,460,496,256,565,807,967,292,834,518,163,89,538,743,344,935,9,290,97,173,626,865,83,192,212,57,723,568,56,363,126,777,34,150,582,629,507,894,420,825,775,972,519,321,735,49,475,89,800,489,80,511,409,297,12,111,833,280,533,244,825,4,99,172,193,95,42,911,12,101,554,668,519,394,791,961,278,928,310,57,956,939,376,62,435,149,321,167,313,187,292,185,382,940,339,300,263,882,65,395,606,120,66,749,343,530,530,462,348,453,567,365,27,845,406,256,931,124,924,112,964,43,882,905,3,466,373,81,471,579,309,644,886,747,631,935,95,385,806,73,144,44,341,577,804,407,799,323,979,619,255,501,294,108,434,348,896,511,795,264,254,401,887,680,435,833,941,777,152,569,838,711,945,711,484,661,140,969,988,664,648,953,630,213,833,241,601,728,898,256,41,0,655,565,838,551,9,248,955,803,937,279,29,260,346,602,426,82,479,47,231,736,277,369,18,806,155,899,827,892,142,778,798,978,251,755,406,281,298,915,801,864,226,85,94,895,480,561,178,129,157,722,349,599,21,383,300,861,18,963,251,230,724,464,249,807,25,587,187,4,107,217,354,480,586,958,642,909,948,498,886,866,749,214,230,649,146,372,837,935,719,303,452,3,787,295,178,865,870,930,924,171,254,376,580,701,345,348,834,480,615,92,663,803,220,979,583,999,485,95,868,79,482,933,639,53,543,775,857,927,480,139,4,17,843,202,723,333,300,129,825,841,701,680,461,636,831,269,39,648,499,196,937,820,53,942,346,897,721,415,444,804,623,106,861,194,762,173,245,864,394,690,442,10,408,806,170,807,907,439,574,54,94,277,729,261,680,534,265,986,274,874,914,181,923,64,923,336,375,159,746,700,994,956,898,598,766,74,755,76,572,178,274,744,978,927,600,379,578,440,32,355,642,659,985,673,323,232,924,962,241,254,369,856,88,884,534,504,573,447,183,852,285,224,667,923,776,508,435,875,312,87,56,75,94,911,554,995,238,389,155,336,59,692,916,32,355,265,855,404,573,736,55,301,791,796,13,313,163,696,130,180,159,913,244,59,73,590,330,322,434,619,994,359,669,895,255,621,541,350,586,483,59,548,528,583,519,311,632,238,606,856,893,738,715,670,356,423,17,254,35,691,191,743,614,114,558,656,602,894,537,255,15,810,167,368,249,375,47,641,41,265,737,324,906,720,284,86,801,721,474,14,288,761,679,76,729,924,227,150,773,349,180,853,827,880,894,252,430,531,786,863,216,70,18,750,648,240,609,318,214,949,737,688,929,266,221,510,780,792,737,704,863,632,338,470,651,736,869,102,438,284,866,436,410,958,63,175,827,510,167,278,635,932,434,105,344,940,635,590,81,575,93,358,138,817,26,390,657,598,692,498,375,407,111,295,280,954,225,26,400,876,639,269,914,682,29,854,437,96,429,568,578,768,633,953,16,476,530,953,76,681,394,426,759,659,134,913,233,591,948,458,235,514,243,315,231,330,87,169,996,830,705,637,267,126,18,188,65,547,351,268,440,321,479,19,185,768,315,611,52,613,972,417,434,88,584,450,284,13,126,703,483,925,52,983,945,848,842,331,974,529,662,718,727,500,559,645,736,41,578,152,387,161,119,207,202,256,731,339,869,581,443,136,265,302,129,912,180,825,432,613,938,922,532,501,865,434,247,255,967,308,564,529,200,241,927,486,824,27,770,271,830,889,89,517,612,27,51,742,47,960,625,531,269,702,566,334,589,592,379,359,916,752,364,995,92,241,977,282,271,316,11,746,356,818,286,58,131,135,105,483,405,551,813,2,198,788,228,705,477,947,224,727,724,170,612,838,28,878,814,695,329,945,583,152,143", "838,717,207,490,620,895,885,807,891,710,846,354,843,98,454,279,250,718,81,953,75,506,686,990,893,660,466,42,742,25,849,729,473,684,226,971,127,29,912,98,862,936,308,231,495,645,777,478,161,456,505,531,105,667,976,916,549,883,17,219,828,456,127,345,896,600,661,87,93,587,509,78,313,273,827,491,751,475,353,195,544,759,719,793,636,744,758,867,520,390,684,936,470,457,94,729,977,348,773,43,628,155,442,67,411,656,882,670,398,911,163,397,720,400,988,226,640,175,593,479,189,350,108,988,24,646,755,762,413,820,91,552,149,86,93,802,755,559,608,803,462,337,786,207,744,320,467,382,372,855,685,82,731,716,239,115,329,701,592,102,929,126,406,203,278,355,752,799,499,863,18,252,285,186,617,779,708,968,750,612,218,465,57,438,988,260,211,98,826,13,871,612,499,80,472,250,922,393,2,828,332,172,900,194,461,532,139,934,69,213,790,330,888,428,516,4,695,967,944,625,503,256,133,376,383,292,881,551,174,276,841,425,695,639,219,384,532,702,172,646,676,789,246,172,469,216,731,941,683,211,431,290,683,213,160,930,82,581,890,807,535,518,939,194,294,438,462,616,237,773,848,796,686,640,866,458,453,748,825,377,775,1000,827,571,549,543,285,798,144,119,831,285,581,323,857,851,430,90,242,701,858,942,547,548,493,278,424,324,148,187,153,895,528,935,798,358,563,94,82,384,354,934,234,598,780,324,167,420,986,69,879,423,771,525,111,472,582,899,695,261,18,566,409,646,991,787,378,98,794,739,909,42,155,588,925,662,476,284,553,705,290,388,616,291,655,0,72,94,768,947,706,141,139,546,224,88,636,864,760,194,177,272,227,857,112,459,811,395,625,164,332,853,164,668,932,169,587,30,107,899,55,840,505,654,449,100,870,259,519,577,524,388,372,59,964,596,58,47,761,191,180,623,272,233,738,904,814,355,401,798,278,376,304,922,577,403,85,626,733,107,562,374,951,452,194,239,307,831,432,889,940,100,539,834,545,399,805,173,708,324,79,180,354,698,737,853,574,181,844,233,666,666,319,455,170,378,424,364,665,656,532,204,325,84,644,205,535,500,628,775,831,739,201,585,564,287,824,855,514,946,520,541,334,96,716,41,543,62,166,5,640,684,73,61,302,674,779,235,49,940,461,814,40,804,713,293,119,922,781,601,25,599,325,43,321,595,423,553,890,917,571,618,170,212,525,452,377,552,848,907,345,589,574,202,519,828,217,745,761,498,271,32,958,968,969,794,752,180,265,575,968,693,540,461,145,475,826,668,297,17,527,739,474,341,318,106,218,197,399,37,358,214,689,497,731,787,229,146,266,143,145,883,166,667,300,623,957,526,395,627,714,587,492,810,127,39,558,607,435,508,829,178,908,402,912,351,285,611,913,612,936,1000,79,379,20,954,102,531,724,373,782,527,242,384,911,835,271,546,946,92,484,882,493,190,384,950,785,413,463,83,426,252,168,819,354,138,26,727,366,702,671,748,432,289,13,920,531,936,599,945,58,327,681,134,24,244,71,484,364,110,630,52,766,954,649,153,794,953,296,361,161,450,22,471,340,529,554,112,522,166,742,227,633,627,267,509,443,907,746,10,265,505,611,431,751,145,537,389,330,678,689,659,457,543,374,209,106,962,775,755,352,818,412,54,249,867,652,767,365,143,875,462,626,757,826,193,979,222,584,174,423,213,382,402,661,766,844,512,926,976,18,615,238,964,602,187,804,380,612,301,423,970,120,693,310,397,592,73,326,671,335,997,30,33,347,203,24,793,79,525,776,904,522,772,826,84,137,953,650,486,473,50,934,270,725,432,966,407,305,645,315,303,649,905,531,160,20,853,342,861,147,96,165,337,736,493,581,62,908,718,924,289,252,970,983,343,697,103,175,831,191,456,907,646,804,644,268,167,238,143,782,325,764,810,471,366,611,261,934,830,180,814,942,483,77,870,259,171,232,303,73,91,648,911,135,204,740,843,728,580,939,155,34,378,389,409,177,157,824,235,623,387,607,499,522,664,665,365,774,314,952,314,720,839,426,382,218,212,967,183,695,470,68,432,614,973,631,158,660,329,731,400,610,400,883,483,559,769,780,54,763,657,823,529,667,693,365,337,611,326,676,78,99,742,230,226,766,816,272,784,673,738,671,589,653,642,143,896,793,926,159,862,896,584,780,915,60,639,731,647,781,162,782,893,813,193,866,169,960,387,143,789,826,106,105,821,22,764,457,940", "509,793,252,194,758,344,657,180,268,812,453,518,895,736,173,297,858,541,550,889,250,288,168,895,866,2,212,294,843,282,124,683,547,600,308,623,476,258,741,15,464,278,693,684,665,533,503,999,823,200,7,394,479,521,688,250,331,915,486,784,19,621,158,38,331,901,921,948,438,659,509,545,47,487,811,154,704,543,653,429,416,949,965,991,367,667,628,771,319,133,285,157,732,40,290,306,363,718,793,439,94,498,941,267,640,820,477,40,635,408,205,624,551,438,883,920,724,508,165,338,479,466,399,217,407,296,918,782,681,106,27,460,852,897,232,731,537,216,800,239,448,684,438,644,654,189,658,932,906,17,730,426,551,852,746,670,253,350,593,482,217,485,169,682,128,585,773,590,601,879,527,30,890,248,538,65,885,99,709,594,388,658,597,426,296,130,121,459,493,321,948,65,559,533,373,743,665,159,272,768,663,379,481,860,850,476,40,990,83,415,913,204,789,241,12,308,636,133,972,682,842,886,848,328,50,219,56,283,501,4,103,597,212,441,532,762,142,797,432,629,869,312,217,853,809,459,798,838,756,781,74,956,358,16,964,581,481,565,482,995,626,738,371,847,50,974,871,504,759,731,39,84,202,535,615,721,810,105,544,726,26,723,918,482,232,449,507,989,498,131,31,739,835,752,332,507,557,367,948,677,588,557,918,404,962,280,374,225,624,808,817,843,866,518,891,683,61,572,617,964,277,570,838,926,859,442,433,368,712,746,285,193,853,428,810,179,6,179,649,48,761,742,173,552,890,505,583,879,929,923,889,113,940,549,414,473,756,619,924,340,352,172,150,632,565,72,0,621,462,269,492,150,381,596,118,212,931,655,661,892,925,463,751,339,685,915,214,600,457,801,443,908,770,322,580,502,861,882,132,52,954,904,710,165,713,371,648,871,268,452,234,983,242,949,425,785,726,374,330,175,342,600,950,5,535,288,857,461,797,322,528,586,291,367,877,610,21,891,952,687,911,514,661,283,723,846,327,857,183,358,912,273,22,862,405,978,878,985,911,482,681,674,984,584,306,290,81,984,579,946,380,934,126,811,78,431,572,928,179,258,28,150,384,901,97,752,561,26,840,549,652,188,757,697,102,73,44,230,224,298,630,570,631,590,402,163,116,208,165,756,893,422,674,166,777,392,867,592,423,275,249,676,458,426,146,887,774,206,668,138,997,970,248,582,740,885,928,338,656,932,997,904,642,923,253,482,831,237,517,874,330,925,315,227,170,668,800,697,908,234,840,293,568,384,612,167,221,804,457,868,814,343,749,597,818,929,855,186,837,826,398,101,627,373,9,73,917,291,374,129,277,943,725,103,464,397,740,923,79,724,559,534,534,928,913,404,841,102,391,719,577,853,278,943,270,548,766,872,597,122,742,877,2,427,51,710,207,687,664,899,381,200,761,663,831,599,131,786,702,217,113,455,22,837,495,651,669,114,847,574,758,767,502,141,103,658,85,495,584,791,316,419,887,146,512,921,58,253,120,658,662,92,405,341,307,148,740,487,589,965,28,141,655,241,910,652,591,881,54,225,755,399,478,45,876,73,980,515,275,260,678,203,763,539,802,21,692,89,33,955,18,749,540,937,612,460,525,196,915,350,778,158,149,24,621,59,378,883,582,458,270,896,931,268,214,10,998,559,961,70,183,155,196,990,349,770,72,962,892,382,266,833,632,173,266,45,916,805,270,514,295,604,603,769,619,387,146,203,51,220,215,886,261,197,509,649,339,846,266,865,796,428,135,125,722,677,291,2,723,670,942,861,563,814,644,85,204,568,436,728,942,549,346,746,247,54,287,115,703,845,734,984,708,26,69,276,658,619,368,676,929,506,434,297,631,234,299,450,827,224,746,377,653,145,601,242,75,866,729,513,632,649,862,60,94,983,742,141,74,896,415,518,552,122,813,791,846,246,267,712,177,553,635,897,37,692,876,724,413,147,311,644,963,335,817,76,470,586,304,26,590,581,512,844,633,72,466,374,38,727,254,78,174,109,908,63,205,102,11,159,999,291,192,739,340,709,801,657,327,976,856,263,920,966,550,731,304,527,914,226,933,7,847,717,561,788,131,790,773,83,827,224,326,46,344,119,519,254,861,181,899,184,342,419,838,582,434,641,621,707,110,26,418,847,762,148,11,245,45,960,452,513,840,184,521,215,893,879,410,58,878,682,248,971,844,936,420,214,421,75,188,338,23,806,509,153,568,91,243,269,785,561,282,880,392,113,668,580,20,689", "843,688,209,179,118,448,580,821,438,678,259,180,8,617,660,116,282,112,542,249,118,586,11,449,40,934,892,104,919,764,860,995,816,975,364,173,9,248,884,82,525,326,417,975,638,337,242,919,965,992,842,327,94,560,935,781,757,270,41,882,965,772,95,572,46,333,761,641,726,726,458,622,870,231,690,727,236,561,28,156,137,614,932,853,501,925,318,546,902,180,961,133,715,488,374,931,241,998,264,262,361,981,76,410,775,915,72,678,948,923,752,779,798,228,966,339,490,75,139,87,913,416,964,92,226,260,207,460,583,325,899,25,163,564,66,249,86,427,574,568,586,208,348,421,576,485,74,710,787,813,340,61,285,493,829,196,377,484,579,24,131,973,787,430,225,306,820,868,635,799,938,275,297,401,39,405,914,162,259,92,331,861,847,13,61,751,762,212,955,207,774,818,649,806,559,525,32,968,73,686,487,120,989,986,320,994,631,480,701,5,440,698,621,891,78,439,641,765,723,6,200,152,121,543,556,428,50,590,994,819,939,411,789,954,835,632,720,6,687,222,171,435,913,916,143,695,339,227,311,338,274,838,623,912,629,346,492,180,660,898,538,550,634,979,371,494,70,239,798,470,157,974,68,498,469,599,561,581,564,492,703,354,365,77,122,483,240,828,308,783,748,246,446,158,611,722,244,148,631,286,634,707,932,237,519,516,728,828,669,570,383,678,802,870,293,494,397,669,911,255,10,952,299,864,761,561,367,839,367,879,217,882,139,692,699,440,118,291,893,107,209,317,143,53,767,486,615,959,735,890,65,494,750,702,317,743,489,798,244,51,501,88,165,201,838,94,621,0,137,687,716,740,48,780,271,847,816,333,958,501,531,295,928,663,24,364,366,41,829,311,79,676,667,471,975,244,755,265,114,123,988,166,964,932,255,791,618,991,631,844,715,723,689,774,827,915,890,875,316,779,303,180,500,163,759,387,994,830,575,80,214,75,933,954,855,216,122,88,172,414,106,254,591,621,411,102,236,253,514,563,824,173,374,542,7,701,405,654,315,575,921,74,657,347,794,996,963,818,634,735,893,315,585,992,202,97,21,111,66,80,143,148,404,868,731,183,903,170,523,268,148,175,734,543,428,259,175,832,453,762,517,305,119,58,378,686,156,739,701,708,887,143,359,301,1000,215,379,735,347,664,210,767,848,226,223,92,340,559,677,487,529,55,339,187,227,560,830,548,613,815,361,59,334,285,170,819,569,135,815,197,578,87,824,142,726,425,943,979,633,606,453,990,902,434,601,805,992,167,129,718,763,190,276,779,370,424,965,385,60,186,718,922,47,192,776,742,159,869,704,291,528,387,777,736,14,890,328,544,992,251,126,190,861,502,488,227,528,495,651,207,816,483,245,630,753,706,580,276,549,52,880,9,302,737,895,8,38,898,46,307,747,797,512,683,737,614,773,297,881,339,437,674,819,974,661,121,928,857,22,984,437,801,450,315,21,416,982,432,126,341,863,177,983,930,242,755,722,713,953,234,162,277,231,887,552,158,552,381,143,154,646,23,752,325,718,596,74,741,960,77,16,505,498,863,528,396,716,555,262,652,773,924,248,120,971,106,419,980,96,891,129,968,368,894,253,727,861,575,60,253,366,987,602,73,236,163,179,772,892,328,835,662,887,304,460,831,631,943,758,89,239,872,803,322,880,442,410,944,802,747,57,244,973,144,616,432,704,758,896,240,152,483,958,147,409,207,160,908,124,770,433,541,386,154,56,564,912,309,373,304,995,236,715,894,714,831,966,952,818,637,261,187,663,13,998,571,52,737,671,958,25,781,161,253,257,309,777,214,571,53,856,140,626,153,545,612,250,763,708,179,659,507,586,990,230,410,478,290,243,388,932,613,564,489,284,302,475,10,142,579,510,838,89,954,38,329,586,866,367,651,72,365,617,374,240,955,848,498,384,670,116,492,833,904,994,777,973,442,391,651,983,662,492,343,60,144,904,720,817,33,199,887,854,12,677,261,758,486,435,364,695,509,195,945,837,998,843,19,898,106,524,340,645,364,422,698,836,890,69,497,576,668,385,264,721,480,918,138,846,376,297,246,245,371,671,60,850,663,665,808,685,733,156,185,794,10,934,156,356,38,64,661,246,61,954,349,432,560,417,109,991,554,432,120,795,366,460,362,904,119,374,968,188,223,116,437,254,902,313,277,949,40,219,756,813,812,607,616,330,516,897,279,700,569,811,618,154,771,40,752,923,945,109,406,456,232,199,157,479,584", "222,246,561,788,311,910,519,786,611,179,905,854,291,550,431,335,594,619,340,772,325,546,349,703,89,640,322,983,13,971,788,875,166,62,240,11,586,600,340,4,232,932,653,765,383,44,297,5,843,40,223,198,445,603,76,786,742,208,544,184,623,863,636,272,553,993,828,870,382,230,499,372,570,756,293,404,266,193,605,675,717,362,921,442,420,4,103,625,278,908,808,829,785,387,659,175,298,166,255,616,260,578,508,167,993,608,298,705,231,334,147,639,584,374,629,368,502,259,944,19,935,590,989,23,902,160,600,67,689,959,923,349,906,754,949,576,170,893,656,352,344,144,284,22,230,24,495,821,196,865,122,729,869,382,655,313,54,748,121,428,111,896,171,221,225,756,873,580,317,230,405,328,457,155,140,402,430,152,902,728,273,928,820,778,719,818,356,35,399,265,135,672,367,760,875,763,799,917,701,579,999,346,491,264,898,260,856,539,269,100,46,367,189,560,661,115,808,402,802,20,550,457,789,767,6,230,478,678,118,678,657,995,763,569,498,331,443,603,157,557,368,923,352,86,487,978,496,536,785,450,336,149,949,653,306,193,982,642,29,403,518,369,640,276,675,551,155,363,613,3,471,420,554,60,934,841,988,162,313,89,122,510,341,37,31,157,919,797,647,471,502,543,995,68,237,280,465,803,591,677,834,462,584,293,402,741,535,935,234,832,557,329,82,181,677,655,552,483,623,355,935,241,807,159,357,404,442,701,152,964,30,381,771,180,11,767,692,858,303,670,104,476,919,298,26,839,175,944,94,213,441,569,627,876,927,120,171,505,964,767,563,171,822,719,551,768,462,137,0,183,166,526,222,63,867,175,773,698,360,405,855,401,306,566,526,996,13,168,520,103,637,66,103,125,218,255,481,770,672,625,101,816,50,259,370,441,744,671,44,822,856,946,329,163,861,786,863,891,185,94,885,894,586,77,811,708,506,20,919,797,170,878,23,130,197,272,458,331,734,767,962,284,447,12,791,721,756,501,837,527,847,979,803,552,8,312,227,127,427,460,828,381,284,246,855,829,260,24,970,534,85,765,391,468,801,823,151,817,232,958,276,614,626,551,707,290,288,686,536,707,388,531,41,422,811,123,481,286,793,607,946,676,172,348,816,383,716,190,638,755,383,925,992,158,630,93,510,588,876,700,511,420,446,447,538,29,86,993,808,38,997,8,421,868,903,28,965,876,850,876,948,150,32,699,473,400,56,651,560,528,873,830,72,57,956,403,742,784,635,727,743,411,884,952,519,365,573,268,256,642,940,76,518,739,666,765,2,253,798,400,461,857,870,755,608,652,926,932,861,36,415,759,181,939,710,200,385,996,319,271,123,964,276,884,285,701,43,951,472,652,986,133,958,747,749,489,288,659,167,929,458,828,665,282,167,284,776,88,942,440,431,953,306,719,296,301,934,106,999,52,141,82,454,855,553,296,531,866,32,368,407,463,111,620,905,824,216,215,39,284,281,996,287,328,877,22,681,508,649,781,697,333,468,846,613,910,369,489,570,803,880,870,699,233,351,858,263,87,858,873,889,205,634,26,210,662,259,667,194,170,983,642,610,631,628,443,257,481,247,229,576,761,419,221,974,483,604,941,909,479,752,615,793,329,418,139,273,631,961,971,400,321,272,172,947,341,694,679,774,701,537,89,677,47,654,178,271,622,415,828,130,753,443,681,968,903,151,867,594,793,275,647,358,4,546,748,624,559,39,546,819,717,133,477,206,555,953,187,792,429,755,296,117,372,149,919,897,216,486,281,53,296,362,693,323,349,654,347,504,18,159,580,915,49,564,94,960,597,811,55,291,615,480,68,158,811,173,723,49,344,755,777,87,887,986,557,84,270,823,867,39,42,5,287,66,660,337,480,676,841,317,480,15,368,737,16,399,988,6,200,249,990,790,928,105,708,167,745,979,898,352,765,188,931,393,992,884,503,334,62,588,263,104,967,619,247,499,634,811,317,985,346,460,105,932,369,522,104,613,997,226,466,31,39,721,579,715,120,192,133,959,748,454,595,607,930,122,717,742,279,22,684,536,959,751,898,776,839,995,173,215,546,650,535,131,584,168,165,587,643,90,232,508,589,293,487,695,730,609,153,536,430,886,62,101,526,50,458,657,999,726,410,709,524,59,33,126,809,290,720,2,936,450,212,634,141,722,450,184,852,153,749,933,166,994,59,503,103,401,679,364,482,880,68,820,144,503,396,413,110,951,395,161,238,973,676,600,337,980,573", "690,854,354,663,525,415,588,832,174,352,635,131,654,693,924,507,854,276,210,28,948,798,73,640,218,238,992,979,896,740,911,365,341,465,107,423,892,901,288,963,804,561,837,110,402,185,588,674,987,768,58,477,726,208,644,704,929,392,812,6,212,476,183,864,722,429,821,564,7,765,633,239,104,150,592,961,594,827,197,269,359,861,931,810,635,992,524,119,733,52,771,11,146,307,10,373,178,957,160,350,34,524,316,692,250,306,636,514,616,477,560,420,291,54,960,503,821,994,519,576,2,317,108,432,498,107,616,485,18,9,118,405,666,352,534,320,248,363,220,856,177,418,917,754,106,94,966,901,320,829,207,370,31,823,146,985,806,436,496,160,211,246,70,878,200,193,404,470,430,852,702,198,38,857,577,448,551,204,714,826,923,698,580,598,750,753,722,837,775,449,650,276,708,82,37,334,516,108,41,824,385,857,415,181,89,972,828,676,811,48,443,769,281,133,503,996,672,639,209,781,798,382,362,399,670,671,96,222,552,719,751,615,334,173,425,682,575,353,787,949,11,497,22,491,241,710,997,569,217,553,95,674,805,172,688,506,169,990,391,1000,446,705,935,237,243,545,34,826,647,150,925,281,228,359,397,610,377,16,972,212,616,932,25,372,199,462,480,887,432,838,33,464,147,998,853,315,761,660,821,417,998,332,647,549,728,446,672,889,77,393,132,759,424,636,445,578,928,355,237,645,338,930,82,122,548,950,358,492,824,396,398,797,71,547,733,213,632,437,605,95,741,227,710,786,640,87,785,619,631,602,367,474,228,485,977,357,853,354,142,787,88,879,748,34,9,947,269,687,183,0,590,223,139,39,728,693,568,923,34,732,965,33,337,297,894,200,511,204,502,697,295,453,6,432,47,471,105,278,800,192,174,912,615,831,156,594,25,553,852,677,236,11,109,914,109,313,531,893,186,966,894,57,126,39,558,329,263,52,139,426,289,815,492,808,538,941,763,389,357,255,13,398,591,927,297,234,631,117,799,778,267,678,193,900,495,674,547,358,240,944,981,770,921,396,545,437,430,366,384,428,604,870,365,944,647,493,592,462,672,460,180,786,870,564,47,146,239,482,334,974,337,404,698,844,116,995,436,171,666,887,767,538,244,179,130,414,362,256,124,65,342,22,623,680,951,177,195,911,82,451,87,215,793,970,673,496,214,355,817,152,394,865,281,391,510,340,846,498,429,172,273,457,141,204,83,234,558,429,53,8,101,906,402,74,700,326,948,835,394,971,879,234,569,694,474,803,393,744,994,807,305,270,199,568,440,952,875,762,92,904,371,539,574,250,251,192,947,499,47,778,439,63,349,9,985,67,680,654,99,895,162,274,794,841,276,390,405,756,128,616,3,123,32,730,632,166,516,256,965,857,632,185,942,438,66,32,984,107,989,160,669,890,861,583,171,776,389,128,59,196,941,820,812,103,607,656,994,425,148,415,958,588,216,331,820,822,27,878,610,147,104,705,298,58,831,473,250,521,219,925,883,894,341,590,550,537,287,914,257,160,798,965,999,5,771,187,966,616,831,333,20,339,877,888,576,594,382,835,596,245,580,130,601,295,796,158,24,767,80,369,883,634,380,124,130,234,362,785,756,474,97,545,615,390,902,129,964,725,96,159,674,762,837,465,619,744,693,516,88,597,983,355,450,683,287,73,432,363,506,221,200,533,252,41,934,69,565,573,921,518,820,964,674,697,628,613,127,475,57,71,206,335,457,430,175,417,813,101,902,792,850,807,618,65,162,461,346,179,140,855,918,393,947,507,247,890,339,874,371,438,337,840,733,431,782,263,160,511,219,767,395,636,477,133,913,591,169,937,4,781,359,385,197,189,25,309,10,722,441,241,18,216,84,604,633,986,161,152,753,489,809,214,483,120,959,675,666,450,432,470,743,206,3,833,355,976,301,722,908,531,311,786,173,623,870,84,801,599,976,279,420,238,630,809,761,555,455,919,981,655,977,894,912,852,694,644,251,911,698,195,124,46,830,457,850,961,305,714,873,156,670,358,255,165,686,126,560,824,498,779,218,925,599,950,134,548,749,943,792,228,145,343,572,121,949,50,875,256,121,393,688,855,924,217,876,561,122,280,243,221,595,770,166,877,749,224,635,586,645,869,142,842,898,751,724,68,265,944,283,487,571,980,686,240,478,444,822,419,88,855,59,505,755,44,519,31,504,666,559,311,471,699,856,319,641,347,530,412,123,867,899,737,507,897,953,721,899,771,836,505", "783,85,206,855,676,595,224,877,520,713,185,904,58,1000,737,778,769,988,878,361,503,622,988,907,624,315,334,69,646,351,742,882,746,780,331,61,830,109,406,931,893,136,685,513,73,681,671,936,577,948,592,320,552,224,670,464,978,119,903,993,301,245,776,425,687,995,676,356,103,686,232,586,903,327,968,131,494,819,89,695,96,868,608,114,581,356,815,110,155,782,249,201,49,222,292,156,455,432,858,896,342,195,739,242,42,195,902,997,788,11,873,356,177,632,596,529,742,110,921,477,537,652,469,361,628,187,771,337,776,706,87,448,564,203,110,818,125,459,263,368,724,338,801,713,815,708,566,343,856,894,851,570,201,298,946,573,422,437,455,271,122,530,315,279,894,706,843,489,683,222,140,449,636,987,96,678,634,210,589,919,570,175,290,727,288,727,283,751,287,189,285,213,99,416,872,212,519,986,477,732,356,348,21,402,632,279,623,894,102,579,954,351,427,549,738,458,374,476,671,334,841,263,974,546,934,287,559,492,906,94,399,908,913,173,341,410,867,555,78,262,447,94,428,843,595,433,208,828,693,870,574,893,195,783,118,142,89,835,512,374,59,585,79,506,960,530,723,410,799,33,18,652,627,696,668,617,615,653,223,166,973,14,413,147,326,645,534,830,696,498,276,27,591,825,702,61,238,321,13,474,234,297,548,842,220,407,718,325,621,527,363,23,225,471,691,68,215,898,706,65,44,460,6,21,476,232,974,375,327,260,106,246,833,62,706,378,671,681,441,345,495,190,140,412,216,427,537,529,555,405,362,643,937,742,124,770,933,51,365,237,962,904,720,357,248,706,492,716,166,590,0,429,432,34,99,503,861,33,69,45,947,631,542,410,55,171,135,311,865,799,278,147,528,804,157,144,964,380,595,204,679,862,242,297,75,66,746,730,363,291,86,883,674,182,302,459,591,576,450,476,801,846,967,866,466,81,47,11,371,220,799,841,256,796,943,75,571,658,573,472,318,575,992,204,956,864,675,353,900,845,532,241,962,407,646,336,652,780,989,24,608,455,150,594,571,991,578,510,57,868,921,568,893,114,704,654,652,782,831,980,250,176,457,945,339,672,408,888,114,561,765,765,677,759,573,473,413,16,152,256,784,185,576,106,925,912,236,704,216,654,484,296,739,546,675,614,391,212,402,259,705,74,202,948,279,751,54,216,136,757,253,405,269,715,324,136,630,923,459,846,76,746,258,493,134,967,346,240,17,151,459,2,185,595,438,316,377,385,667,865,169,544,215,908,762,791,508,533,472,289,966,800,777,50,889,1000,300,723,656,307,103,443,273,27,863,210,821,474,790,212,686,397,478,28,943,109,713,765,530,858,730,29,99,388,92,544,259,66,413,996,747,603,517,711,161,420,809,573,299,239,904,766,103,602,51,786,217,313,932,36,499,592,294,118,749,561,724,477,272,226,95,109,447,855,553,669,410,206,629,611,410,323,259,352,996,637,518,532,660,575,618,657,163,450,548,71,851,11,748,426,968,890,398,673,493,126,301,584,121,710,937,295,656,440,703,421,974,655,87,569,762,393,77,571,258,640,834,830,28,754,576,71,754,545,359,624,854,796,895,681,8,35,895,168,359,169,569,220,792,314,495,631,982,335,637,535,100,894,438,87,811,680,495,349,771,545,555,317,389,469,877,7,507,29,669,19,804,8,142,63,461,134,823,286,491,321,722,546,509,720,235,347,245,421,833,111,909,555,423,744,994,423,457,734,732,261,751,614,586,391,499,147,16,719,165,980,856,813,208,227,855,42,802,542,955,66,635,877,861,306,869,240,92,234,881,490,620,667,158,197,421,437,563,897,265,843,300,185,180,299,879,575,448,546,256,78,620,501,696,429,306,731,839,485,885,688,170,648,722,951,533,446,474,962,52,272,438,993,758,547,849,954,917,59,187,485,982,475,76,154,519,415,53,94,303,551,325,488,414,679,396,517,984,200,405,830,159,705,621,406,183,748,892,594,144,950,218,222,203,323,488,192,329,354,802,994,662,834,237,57,473,830,9,552,257,801,920,736,309,183,289,812,26,959,342,446,300,825,339,355,429,571,697,828,625,151,203,460,941,112,461,389,235,144,437,746,863,652,98,533,330,696,685,816,779,979,669,605,655,30,682,493,942,738,330,905,576,375,427,678,95,977,888,839,150,624,128,245,772,534,389,567,670,83,156,764,770,330,756,916,631,133,698,585,131,680,613,996,121,276,470,676,272,638,492,552,517,877,165,210", "963,476,829,673,765,81,156,433,824,136,368,615,99,768,425,646,6,324,857,139,863,180,86,155,239,187,648,32,958,307,703,886,495,881,696,428,689,510,695,818,755,628,18,53,420,156,948,326,133,877,372,980,367,8,102,16,895,496,212,640,199,19,553,486,756,750,61,600,998,418,930,305,113,722,693,171,928,931,552,631,454,529,539,609,228,850,484,315,895,815,36,872,913,430,273,58,827,878,950,865,113,676,501,94,655,205,15,514,215,548,166,703,778,812,677,983,630,36,484,481,29,646,793,284,630,707,867,977,176,432,259,824,175,331,345,917,301,457,677,251,225,183,382,423,891,154,45,936,875,932,953,434,359,539,836,575,834,241,595,540,165,964,280,991,716,580,636,465,18,233,522,113,766,47,101,59,214,840,578,822,69,145,473,459,920,971,619,738,686,13,984,450,456,148,16,18,848,909,696,98,887,466,746,73,563,12,883,859,130,23,879,437,780,661,885,126,760,604,241,116,339,541,789,750,543,3,224,940,932,363,139,236,243,395,249,532,331,26,41,210,901,908,3,422,609,479,951,548,615,780,347,89,902,72,272,541,930,1,725,29,298,908,389,495,92,923,100,435,353,114,325,549,513,669,925,582,407,137,717,889,490,9,348,447,407,616,563,203,344,585,469,795,646,365,457,118,19,503,286,264,705,590,866,759,500,107,178,472,958,310,985,30,152,364,137,804,674,656,118,468,281,502,428,278,299,420,753,884,767,39,102,579,633,598,410,644,231,477,910,115,716,122,993,135,988,112,352,931,311,182,745,791,287,844,302,959,839,867,537,28,516,284,735,396,955,141,150,740,526,223,429,0,553,859,464,269,76,176,164,743,161,112,630,224,382,558,235,747,805,821,803,194,864,670,376,445,629,222,538,338,209,832,459,748,117,280,280,848,751,787,726,237,504,115,417,397,727,91,925,974,197,636,889,216,996,983,361,640,717,122,360,170,185,899,36,193,887,212,494,852,1000,595,319,85,397,988,188,653,26,931,634,787,807,176,267,694,574,591,569,637,631,395,870,225,430,681,599,763,725,524,419,249,23,20,689,500,691,111,709,316,941,516,470,475,861,509,851,903,971,938,820,383,825,720,856,322,801,998,773,286,169,542,202,719,71,275,191,176,860,984,798,747,118,328,984,984,836,578,196,307,832,339,706,77,594,540,886,301,684,728,404,714,28,429,683,907,454,736,918,202,26,42,554,767,315,223,459,685,938,288,273,865,554,931,135,189,806,896,155,764,902,420,35,433,49,701,842,484,167,897,895,332,273,941,350,488,828,138,203,785,629,223,91,15,712,758,537,414,81,883,904,195,600,195,901,260,730,497,583,20,80,634,65,885,999,279,149,92,706,117,70,955,645,780,516,666,663,830,55,290,578,762,280,333,240,516,226,768,484,740,65,57,260,73,878,448,496,485,954,301,909,968,853,219,699,75,764,655,396,638,345,827,135,256,857,186,289,147,764,279,532,34,856,784,415,96,408,320,480,834,126,721,283,181,863,805,978,403,497,898,467,206,98,766,583,549,800,467,548,696,870,796,820,575,400,927,178,471,636,489,663,832,254,49,370,228,794,773,302,123,559,569,819,847,157,576,276,309,45,153,631,898,336,38,289,974,430,213,8,813,808,691,533,980,960,562,643,490,7,46,945,888,991,445,761,415,744,67,508,263,748,162,599,173,399,851,467,932,135,374,28,277,675,23,545,855,595,695,854,953,366,566,767,662,568,238,583,411,407,129,659,690,641,446,442,325,55,730,716,806,199,904,816,999,597,787,795,429,648,480,489,470,674,973,991,819,378,315,542,144,403,271,167,187,625,504,823,189,95,683,168,202,848,751,667,881,965,423,238,223,785,886,459,656,114,637,947,876,466,995,455,447,184,301,937,29,333,519,299,282,754,504,167,698,258,866,2,420,729,816,339,855,198,790,701,168,924,237,123,752,584,880,873,82,246,582,423,533,60,158,655,945,393,692,909,795,959,916,747,972,542,961,959,993,243,965,261,595,276,111,346,157,321,560,706,571,857,878,96,140,884,547,397,32,414,339,178,761,563,268,252,514,404,185,543,660,779,584,99,41,748,15,671,429,851,639,719,630,609,157,927,165,367,695,860,692,800,103,675,997,892,629,473,140,452,371,201,2,60,42,19,993,120,680,242,272,302,231,526,419,520,398,988,137,184,340,609,832,331,659,453,695,506,439,161,589,556,27,745,256,764,31,499,331,882,326,999,360,443,293", "550,243,537,728,933,977,745,468,452,383,174,956,536,159,428,887,896,596,72,31,525,132,144,247,8,586,727,907,260,315,828,919,168,407,44,402,866,351,728,616,320,823,16,399,451,292,464,426,498,942,287,635,44,578,51,575,52,450,286,18,849,645,858,186,990,936,980,307,411,397,597,907,202,113,803,717,371,246,695,324,598,531,580,540,954,590,186,3,392,343,607,378,218,253,701,148,974,453,534,220,172,15,743,464,636,352,350,33,600,667,768,158,203,522,760,203,802,515,598,338,708,288,454,668,308,67,307,426,891,16,355,806,846,128,771,68,436,476,854,660,350,308,759,921,489,501,750,381,280,467,661,936,666,16,139,251,836,440,669,999,41,421,738,153,950,197,512,807,88,484,818,995,202,161,330,728,726,852,414,376,299,94,712,263,426,994,347,820,96,13,514,93,783,954,826,677,32,520,743,806,572,572,5,138,121,14,650,963,183,532,777,624,573,781,472,188,224,335,478,660,937,943,512,296,213,818,99,476,474,357,618,867,120,868,393,502,221,308,810,842,843,355,210,797,476,978,185,758,143,670,32,395,845,714,920,726,472,532,244,109,525,620,986,718,561,192,582,924,110,220,325,108,473,59,713,572,701,881,48,891,801,261,7,202,200,815,2,460,604,934,294,202,967,425,704,471,450,866,406,361,370,914,965,326,437,83,250,979,159,908,684,347,256,637,166,421,118,390,862,623,395,593,474,639,248,841,97,391,191,963,710,692,256,516,831,208,626,825,565,640,409,557,133,230,550,405,341,637,42,559,804,820,52,737,690,156,739,270,6,940,822,558,920,980,803,139,381,48,222,139,432,553,0,189,779,510,327,598,116,383,91,433,4,642,430,817,567,978,688,176,253,823,69,185,994,337,235,421,488,871,172,685,923,98,458,579,619,813,417,999,71,285,917,439,255,54,158,816,919,610,263,345,595,762,612,799,247,181,80,495,456,750,469,961,198,319,878,863,967,640,2,936,83,637,595,355,569,43,291,268,906,630,525,275,643,168,946,588,47,799,317,632,449,785,953,259,48,836,395,974,979,375,550,559,336,758,855,636,130,762,959,468,808,330,765,466,600,404,372,403,564,625,40,10,876,126,597,924,766,392,818,910,562,295,73,870,384,865,896,838,636,770,888,844,225,993,479,518,528,56,18,182,664,363,245,912,895,666,661,498,520,556,711,700,628,884,118,556,421,60,47,204,875,866,145,532,340,616,885,885,77,634,848,46,748,336,736,996,455,338,98,393,457,725,703,140,10,857,876,620,227,44,402,883,570,93,453,896,308,398,533,348,861,944,53,580,147,912,321,195,764,114,797,648,525,870,763,725,115,749,913,480,277,313,812,154,162,132,727,553,758,101,924,367,138,706,659,533,817,684,807,999,574,956,845,473,498,26,167,880,301,307,591,372,76,759,943,83,626,782,270,479,533,858,360,617,573,373,925,707,913,208,871,997,274,793,992,318,668,383,507,339,73,204,927,549,698,394,981,13,441,61,765,70,944,564,891,260,235,746,142,486,25,517,398,249,151,264,638,340,492,937,243,715,560,9,811,353,138,856,62,853,243,333,334,556,670,936,728,49,959,585,946,308,152,608,324,709,464,527,243,812,153,268,993,320,849,789,33,25,706,759,409,342,804,886,243,213,862,717,712,586,425,711,757,812,299,585,61,28,129,216,546,315,483,341,995,973,101,562,967,733,824,457,831,79,947,943,257,617,396,835,246,957,14,494,245,352,802,704,109,581,891,17,51,481,967,622,645,588,682,643,290,466,836,360,278,128,795,183,355,423,944,47,774,538,896,637,820,580,394,748,575,391,545,725,792,301,747,686,865,47,910,876,61,46,454,336,6,201,731,178,467,841,123,848,153,272,278,642,908,734,126,235,162,575,648,177,144,145,636,499,85,489,980,698,44,961,688,43,186,998,988,348,161,964,777,778,743,258,70,938,559,885,690,411,486,269,630,500,945,906,124,398,644,210,646,997,114,48,733,312,606,730,526,965,707,685,890,170,943,367,816,44,76,930,432,666,956,415,930,20,341,654,527,643,957,401,495,410,718,299,591,793,600,873,926,652,623,730,989,311,506,618,170,666,609,783,453,761,347,308,800,790,903,479,672,101,804,17,703,873,778,347,418,927,369,684,937,316,639,437,129,283,510,448,678,60,463,127,266,172,108,935,84,885,912,607,352,686,370,796,806,77,482,601,769,129,980,121,446,835,824,200,925,459,860,579,212,418", "621,513,510,479,298,659,834,532,884,896,505,834,353,673,33,364,140,822,454,494,619,741,336,549,802,603,828,237,256,782,607,93,403,864,561,15,25,601,500,960,442,898,723,395,153,251,638,361,203,706,962,11,99,519,498,434,79,465,999,294,257,843,548,938,504,341,917,329,503,902,311,527,348,791,931,722,513,696,856,524,159,507,523,281,624,886,493,914,904,328,861,381,721,503,863,518,290,486,128,133,238,912,697,109,628,738,180,152,871,318,506,269,212,570,638,793,476,260,391,99,783,422,256,126,365,390,130,442,664,583,824,261,906,585,326,93,652,961,568,740,472,249,703,196,412,215,548,898,727,402,803,537,419,57,441,248,998,774,134,554,324,429,562,923,97,780,985,260,484,646,679,821,579,527,581,777,34,342,55,396,122,538,78,687,53,533,484,491,42,280,935,884,20,211,193,560,72,213,726,801,332,123,106,920,386,862,196,293,302,273,833,68,731,701,170,368,997,598,378,131,923,935,92,912,767,840,443,265,457,138,932,176,399,453,640,213,827,28,481,731,710,676,173,188,246,454,870,413,850,396,40,791,106,276,461,249,333,265,644,31,486,37,642,267,468,936,102,849,279,511,383,917,314,55,198,491,84,482,595,543,166,926,363,68,892,214,216,657,867,652,798,365,231,833,613,961,566,325,96,62,391,131,319,929,602,589,308,15,110,747,982,38,193,241,269,393,767,792,722,317,534,731,485,970,691,107,778,366,895,239,633,696,430,168,499,686,416,75,763,685,235,408,340,826,611,997,418,416,594,164,715,873,107,907,933,693,750,659,224,370,323,476,161,166,937,546,596,780,63,39,34,859,189,0,528,254,892,796,935,694,127,11,209,199,326,888,865,985,468,88,704,47,589,156,285,262,980,555,208,537,709,212,2,59,563,886,50,368,92,168,171,246,681,596,648,426,335,419,367,572,871,759,385,218,807,24,93,227,329,887,195,414,532,283,898,985,160,689,22,15,760,777,311,935,51,221,790,928,481,504,171,660,603,829,317,611,915,386,650,955,661,775,332,423,795,505,106,993,438,214,280,11,74,845,564,452,186,817,39,89,891,775,356,625,805,701,40,737,486,6,807,285,683,919,546,769,904,871,646,978,380,480,374,470,268,714,24,845,243,511,447,690,84,770,494,593,550,535,872,536,209,187,705,203,386,615,712,441,88,630,228,339,300,274,11,254,740,187,364,816,357,935,763,830,964,350,631,328,478,409,533,253,26,982,256,685,164,943,16,582,752,229,965,17,788,204,499,673,843,965,107,172,289,522,876,786,561,272,74,78,336,772,633,941,13,513,561,14,453,218,718,610,49,781,481,998,818,950,156,857,510,137,196,692,516,751,959,37,994,30,343,701,121,470,814,965,282,936,550,969,515,153,223,83,161,528,109,540,508,732,536,945,551,398,462,533,131,431,4,511,321,944,672,7,403,544,887,344,975,296,72,549,575,901,188,938,883,405,125,710,983,647,562,257,426,635,117,905,282,255,852,979,644,962,377,114,108,326,265,935,126,94,235,272,511,99,603,417,8,511,371,815,176,969,947,431,575,709,756,639,481,119,246,776,187,493,119,434,176,447,318,13,302,724,102,266,349,421,810,667,777,686,802,284,676,84,353,191,357,296,856,156,316,203,699,964,174,480,175,413,680,134,414,435,877,110,982,587,668,336,603,698,26,713,787,531,234,482,806,495,47,1000,57,438,70,676,288,420,932,761,844,258,776,128,336,920,791,727,541,88,448,289,702,655,357,577,465,261,926,310,425,930,327,484,438,338,237,861,358,955,761,587,690,887,649,486,960,925,929,288,788,634,573,355,224,485,353,583,683,121,83,468,978,65,212,619,713,984,398,209,112,850,425,17,910,828,114,979,838,210,331,355,171,454,42,253,620,954,59,876,185,393,197,156,920,754,346,349,175,347,997,874,26,340,877,403,185,813,468,439,711,553,461,41,301,28,472,773,346,181,150,472,526,519,679,185,689,55,311,262,496,662,596,322,10,437,786,670,276,497,289,157,719,689,440,654,337,519,923,365,931,514,267,98,679,33,305,855,523,999,953,614,421,8,44,610,403,137,359,600,15,183,782,199,31,545,124,160,796,808,861,503,212,505,171,463,145,718,862,146,210,595,18,502,604,249,71,877,538,130,529,844,25,168,242,127,602,84,548,514,553,926,855,315,345,776,472,973,737,337,749,955,279,223,291,848,386,128,201,281,941,667,989,942,718,187,720,381,346,471", "211,895,279,937,257,648,34,438,179,582,573,153,44,292,60,977,296,397,491,86,717,453,627,118,824,642,481,890,341,236,200,23,816,162,153,546,972,313,259,441,496,354,623,535,280,534,590,76,730,327,454,506,667,930,691,35,627,513,608,126,306,92,635,295,723,261,729,175,99,889,804,404,561,189,915,697,127,262,309,258,709,320,175,7,694,353,444,654,847,17,465,716,318,68,784,120,239,904,965,971,422,295,451,596,691,275,164,822,356,330,222,369,511,566,47,283,150,556,730,67,628,84,483,643,925,265,830,385,449,795,994,326,96,719,155,312,863,145,950,790,18,121,867,961,587,455,175,515,806,802,620,519,126,284,928,59,372,971,716,484,946,791,864,776,408,678,244,700,558,341,34,266,447,773,516,657,118,780,131,613,511,433,119,345,270,696,257,766,860,576,291,777,205,734,966,904,583,615,392,615,635,722,876,373,577,859,994,25,574,980,526,709,438,104,255,254,213,512,323,6,961,685,423,639,626,246,193,496,852,998,438,355,71,805,293,861,296,903,319,246,640,379,753,819,860,432,725,463,28,131,463,590,965,355,573,483,171,464,536,788,793,54,550,198,832,549,740,996,107,386,632,897,226,307,905,292,37,260,855,762,521,329,437,472,1,609,58,687,58,473,490,548,928,464,650,84,416,311,525,925,788,385,788,764,775,845,219,209,941,718,637,675,404,846,388,102,949,134,579,403,591,992,132,153,100,479,375,899,858,977,454,115,136,544,518,149,577,450,475,795,173,458,505,782,688,191,784,578,651,336,929,605,184,828,169,545,898,600,243,663,65,274,430,3,279,224,118,271,867,728,99,464,779,528,0,147,672,70,877,609,198,131,189,703,18,392,579,107,913,951,911,916,269,60,540,364,969,537,956,813,380,672,909,986,950,72,913,519,582,960,291,827,33,401,338,91,972,127,122,571,965,557,454,247,642,641,222,87,642,971,893,77,287,58,308,846,490,891,500,362,513,422,53,619,799,298,952,521,398,924,448,540,562,942,875,62,649,866,217,830,813,862,281,962,404,498,819,118,276,829,25,562,685,592,910,198,595,195,864,167,93,399,704,101,891,187,495,962,777,618,741,61,651,584,610,287,622,896,379,872,957,545,630,571,51,767,959,799,415,24,732,132,585,715,65,883,452,481,19,674,894,403,316,415,738,595,822,854,860,431,861,870,124,368,689,121,134,331,670,935,364,226,780,925,388,996,801,260,548,988,123,721,54,363,76,560,471,297,661,201,524,476,17,564,228,530,607,20,164,759,625,404,161,863,787,733,858,342,88,621,141,637,7,864,924,48,62,197,893,30,308,817,305,769,879,551,412,286,106,531,222,639,897,748,189,685,50,361,19,191,864,597,793,574,948,149,93,867,243,82,938,868,513,667,54,126,241,809,128,18,104,191,964,837,793,872,742,255,761,712,589,230,909,283,361,672,193,970,101,7,740,262,76,485,372,700,502,900,781,976,667,384,880,392,832,227,434,764,918,229,797,968,750,748,98,363,202,755,388,692,412,239,847,865,212,858,496,774,378,586,775,209,514,550,349,42,591,480,190,579,290,165,896,194,425,34,292,106,263,768,792,880,522,988,877,614,590,816,756,917,861,124,842,463,317,774,789,512,808,935,849,735,161,258,765,994,434,395,648,609,216,865,182,995,124,540,213,897,944,201,884,145,698,778,128,457,996,788,983,949,315,439,797,684,484,175,915,105,729,10,119,648,774,527,883,945,65,231,401,733,968,674,879,468,325,496,749,438,348,377,537,233,764,394,644,152,832,61,659,641,608,846,291,669,674,75,894,829,634,173,587,191,875,416,270,385,811,554,578,767,473,969,473,464,431,764,592,339,227,851,775,365,578,431,601,248,64,205,238,398,867,240,654,344,76,624,312,799,892,761,231,131,708,244,442,775,486,680,188,655,276,828,874,525,543,868,24,120,227,651,562,829,353,995,963,523,245,895,347,175,731,520,958,8,53,208,165,294,985,452,528,801,436,615,246,326,88,149,891,357,203,974,951,389,305,861,156,215,882,34,476,816,568,678,991,124,119,349,899,5,175,338,30,824,797,145,464,851,598,957,335,672,357,787,415,383,220,45,956,265,241,260,414,386,532,757,214,798,39,829,287,363,40,881,747,958,635,944,187,979,374,348,4,83,869,557,350,891,841,216,210,331,679,976,567,638,548,216,378,318,562,202,347,661,411,263,302,581,264,447,460,57,815,773,336,517,71,451,377,887", "276,569,277,890,668,742,768,276,255,749,423,54,999,163,264,784,221,586,649,739,642,857,149,15,688,511,556,613,772,742,870,141,395,8,757,569,822,49,85,303,979,564,74,712,489,834,629,232,555,424,654,481,530,647,290,317,665,952,905,442,786,614,957,579,6,546,324,214,857,146,967,289,836,559,560,459,462,493,886,742,366,738,242,9,329,859,102,880,276,412,43,561,594,605,820,120,530,605,120,307,87,970,13,762,928,218,514,672,449,120,215,185,451,512,802,569,446,416,314,917,140,780,635,716,668,458,441,5,782,827,360,87,426,771,62,160,883,256,716,816,922,632,82,837,579,367,95,394,550,952,743,357,553,317,156,327,516,700,585,339,771,546,323,102,200,937,989,772,773,215,342,272,125,164,2,122,549,283,701,617,583,277,595,152,213,852,634,702,256,847,164,259,72,475,577,246,652,745,120,241,874,3,20,138,957,611,812,407,884,200,517,597,592,888,59,610,236,365,999,365,881,31,853,157,201,162,161,772,7,180,137,877,21,561,41,519,96,21,380,225,334,260,459,772,955,394,830,333,944,403,9,323,567,511,172,581,111,411,348,29,971,143,42,693,680,840,252,646,873,488,68,25,735,562,195,70,296,465,492,361,199,6,565,208,136,403,925,458,851,723,188,119,984,816,224,527,682,129,426,394,288,518,37,504,488,635,778,817,167,142,302,769,805,811,355,348,157,598,796,982,526,974,104,180,26,572,846,882,705,603,96,706,992,80,725,317,360,443,198,139,114,949,325,796,739,142,111,320,153,739,255,771,311,123,91,489,766,386,201,561,99,169,475,467,29,88,212,847,175,693,503,269,510,254,147,0,364,277,672,212,814,167,685,806,36,695,319,747,687,775,366,592,684,968,891,446,462,874,485,556,602,449,611,686,955,993,594,571,245,705,9,217,382,795,975,149,579,871,892,224,259,210,440,834,973,479,935,139,887,890,693,230,639,201,379,320,417,677,153,775,766,754,776,190,222,234,533,176,603,753,958,571,975,90,745,701,459,554,294,419,158,517,712,614,218,406,64,829,216,245,267,738,772,248,405,638,676,665,507,997,638,666,469,134,837,327,315,45,783,873,464,707,13,367,729,84,405,764,969,132,104,267,100,184,142,229,407,685,116,461,592,239,345,717,43,382,90,247,181,52,489,811,337,185,705,928,767,221,813,731,905,17,28,613,825,698,986,143,446,761,224,933,618,522,382,6,259,763,817,867,673,965,846,210,180,829,314,148,44,64,173,274,944,687,721,115,952,498,181,351,119,123,66,496,718,169,427,65,483,782,487,792,526,114,477,94,993,898,324,794,225,600,761,900,788,141,387,274,290,246,162,799,580,62,521,169,428,80,706,645,851,624,640,685,655,76,115,917,201,921,861,244,715,406,97,776,919,477,914,567,594,910,97,730,495,783,864,960,712,575,784,668,757,273,18,123,301,917,579,38,240,659,241,496,204,27,111,901,164,181,869,774,272,447,391,63,162,459,865,456,211,288,214,348,806,64,719,944,499,478,49,444,242,5,297,293,257,98,576,258,299,899,573,3,534,203,194,386,327,524,137,644,743,563,97,255,484,322,870,128,873,928,74,639,325,644,978,648,785,483,198,620,211,788,79,574,767,436,683,483,223,669,392,56,79,22,487,159,68,77,45,13,195,625,809,749,162,213,814,512,26,264,785,958,604,521,273,493,971,929,795,624,84,665,656,300,730,294,547,798,450,378,359,744,364,814,894,377,873,542,64,31,245,913,455,68,724,884,697,163,473,534,887,572,678,183,759,569,425,768,782,63,262,828,832,387,228,592,301,489,369,223,801,637,907,672,190,32,763,612,358,948,331,869,156,40,196,383,181,102,388,515,690,394,284,512,672,856,869,125,579,664,689,942,374,635,614,642,370,804,99,166,850,916,867,929,159,901,639,125,866,458,702,23,685,59,841,317,29,210,113,212,881,675,69,210,807,327,15,723,893,608,749,447,555,511,140,523,625,598,594,358,18,186,294,492,527,238,576,882,559,853,296,745,995,694,146,963,490,83,737,682,412,482,861,274,907,826,87,702,816,419,193,232,611,781,437,197,645,221,341,168,446,210,775,237,849,42,143,144,638,466,259,714,247,476,708,2,83,363,98,760,419,798,390,535,946,537,475,887,530,879,77,481,801,39,269,927,763,415,997,65,429,200,371,101,128,314,143,855,245,877,696,988,196,792,593,272,358,760,872,512,198,185,737,833,917,868,494,961", "133,29,316,328,939,463,258,544,894,340,922,142,944,117,699,836,669,381,580,838,632,684,701,156,329,85,54,203,61,138,662,94,441,680,905,780,15,874,586,642,576,399,891,386,892,388,577,250,170,856,185,954,95,919,132,279,408,722,135,286,241,99,653,574,906,66,42,652,41,537,508,960,93,630,129,891,786,733,901,117,78,410,683,638,240,258,380,742,740,922,7,393,384,141,100,284,900,258,298,497,755,826,146,982,904,24,335,173,199,798,575,845,385,370,845,554,725,536,203,548,23,609,185,967,643,310,377,833,193,575,235,18,632,539,579,968,552,685,556,836,162,17,570,195,605,189,948,448,974,712,990,906,955,11,252,50,742,59,158,154,674,557,638,92,631,716,683,518,658,53,354,419,466,700,958,203,977,39,209,74,491,850,13,592,604,385,666,292,425,463,959,485,780,666,820,846,410,890,388,405,667,152,479,507,407,622,859,682,259,106,34,274,589,813,596,486,610,581,489,140,810,999,205,59,483,270,406,530,555,269,232,645,248,399,67,738,756,256,89,686,441,246,17,803,582,281,877,955,110,364,858,797,908,642,395,28,367,722,384,676,199,458,635,83,868,954,712,245,594,72,599,927,100,880,759,445,998,535,780,357,970,679,458,483,488,894,784,266,925,767,602,503,801,600,839,265,282,194,927,214,526,998,681,659,96,796,832,750,963,406,462,183,828,725,503,234,874,134,484,802,753,811,958,854,260,888,984,559,388,914,749,413,996,740,39,734,851,366,425,629,480,908,511,73,531,450,782,793,510,104,346,673,443,864,975,67,916,155,663,364,841,617,536,509,260,636,931,816,773,568,861,76,327,892,672,364,0,137,428,278,315,376,954,315,273,399,241,559,830,665,817,491,308,952,839,244,14,13,280,749,922,360,105,111,423,605,527,837,132,435,582,774,727,695,569,27,150,533,294,535,385,343,985,794,226,908,903,888,607,185,413,419,322,870,596,609,869,786,963,182,669,134,979,578,497,852,170,309,726,487,356,462,95,201,324,166,496,917,733,983,748,503,334,701,658,477,95,636,419,359,408,628,343,301,248,983,176,624,266,2,611,538,814,412,720,703,97,488,699,300,871,325,898,440,557,494,10,480,581,301,787,566,797,830,593,158,100,873,972,391,471,310,124,552,889,30,856,396,682,91,685,837,47,503,914,625,696,232,29,44,125,627,518,892,718,248,632,301,219,876,31,911,988,108,942,494,183,593,141,411,125,371,630,46,992,3,376,256,85,19,94,446,28,274,570,978,422,618,191,715,685,699,568,871,453,144,227,921,205,994,82,726,804,321,409,966,978,632,276,101,408,206,808,161,41,878,48,307,912,288,401,748,448,971,74,363,860,488,940,654,736,652,907,405,714,486,785,268,747,29,851,858,519,90,124,82,747,953,872,654,943,572,204,496,402,479,170,391,33,319,80,946,714,507,339,997,377,383,217,510,35,602,819,639,968,164,16,771,244,709,843,867,923,117,435,743,659,671,413,957,181,18,708,725,753,712,453,172,988,472,100,520,522,103,597,426,133,987,227,656,616,705,772,423,696,228,670,382,530,245,370,330,685,461,633,475,312,47,529,646,57,371,501,213,532,399,301,482,568,946,661,310,142,686,831,18,786,825,902,85,874,42,675,876,111,857,530,572,342,511,457,506,476,958,58,940,170,470,355,409,251,601,913,738,523,976,936,243,785,833,222,394,540,63,338,297,234,880,616,22,13,118,829,889,600,746,193,834,105,809,654,426,968,206,922,890,801,496,833,981,472,183,808,158,632,64,709,756,532,501,118,906,344,206,876,312,396,3,29,781,428,476,782,682,934,411,41,42,750,865,719,913,28,455,693,175,599,886,478,933,24,567,246,661,901,461,186,75,905,377,449,600,188,693,678,467,743,349,811,498,591,423,79,407,696,631,657,732,134,508,112,576,373,113,391,545,591,160,728,873,608,377,831,643,183,275,426,855,494,520,487,532,541,85,99,127,931,114,909,580,203,194,803,505,703,327,419,223,450,822,880,546,498,913,438,267,143,892,199,819,135,34,26,872,716,435,287,329,755,7,92,750,942,87,399,40,701,301,850,1000,882,713,509,821,896,719,661,530,369,519,893,846,622,933,567,566,713,691,762,802,678,740,302,459,374,446,516,89,435,911,867,618,320,715,140,568,633,512,891,948,469,107,440,789,74,396,526,530,477,338,820,435,655,789,703,7,195,714,325,232,796,160,729,406,47,952,614,715,57,185", "303,561,143,961,971,7,68,53,19,979,923,423,470,157,919,656,276,438,293,182,480,436,143,338,157,794,259,25,846,362,955,345,411,639,382,232,193,910,755,211,982,693,62,27,842,763,494,560,266,22,710,822,392,153,167,845,621,889,59,169,434,959,123,866,879,726,952,548,594,24,466,41,294,497,990,95,68,283,913,171,937,852,833,363,741,607,473,999,127,806,523,270,144,862,370,718,230,477,963,771,300,409,837,683,895,257,150,450,770,786,990,454,420,399,694,123,270,449,918,652,426,237,577,667,870,384,177,834,741,561,997,263,459,994,243,794,282,691,806,843,852,168,375,664,299,7,835,736,360,962,601,367,189,67,36,282,882,600,264,262,721,566,507,190,132,837,671,207,282,707,539,754,498,323,242,728,363,866,570,805,919,246,139,550,335,600,247,60,561,561,346,61,483,581,513,406,330,707,421,761,988,126,301,732,626,588,562,669,320,234,150,873,405,288,614,397,193,294,133,882,444,54,243,166,838,720,910,364,193,375,821,564,74,990,111,92,261,590,896,136,421,629,302,131,675,600,998,156,473,939,90,986,869,570,355,936,453,654,903,655,193,430,931,892,906,188,471,268,198,646,227,724,408,706,857,577,483,109,771,110,467,296,670,234,380,836,441,389,845,481,693,470,604,70,960,101,937,392,694,607,457,526,452,248,175,173,696,220,961,813,597,434,876,244,866,805,653,920,380,807,217,400,327,255,125,328,847,670,520,759,713,509,927,241,577,73,985,694,835,742,496,368,831,373,217,736,415,135,466,266,379,253,240,894,408,452,702,501,303,204,671,250,553,257,346,864,655,333,698,923,33,176,598,796,70,277,137,0,478,437,353,627,952,879,947,298,509,135,10,75,416,352,680,757,370,682,586,282,444,174,482,555,224,481,599,359,630,395,402,185,25,858,322,355,235,107,241,580,456,957,941,555,4,807,895,265,466,507,314,58,406,410,326,154,932,853,91,269,696,605,149,890,655,891,883,370,33,750,839,985,155,138,385,926,655,538,126,625,90,551,777,662,510,750,427,323,453,775,354,566,247,941,427,392,744,360,721,511,865,466,552,675,524,96,313,138,470,252,979,868,445,320,232,22,596,250,133,334,957,737,526,729,864,345,523,311,449,113,261,452,123,767,476,338,560,658,150,455,198,143,909,200,335,151,328,109,102,258,323,563,919,748,701,165,352,998,48,190,64,626,594,281,19,367,729,364,809,51,262,918,628,665,254,806,743,338,228,59,885,621,910,655,931,274,359,906,481,865,317,311,867,33,479,615,900,248,893,510,722,21,16,209,413,898,943,319,865,589,849,343,378,512,584,279,165,789,299,334,101,522,735,35,276,508,674,478,439,934,489,472,423,139,325,419,836,136,575,516,229,265,695,693,621,370,955,6,950,374,649,351,830,492,372,703,264,761,106,448,417,329,326,12,818,331,243,596,268,366,867,336,261,413,657,167,704,260,221,944,63,84,610,529,364,635,881,355,930,730,597,908,36,448,226,687,459,510,193,149,57,206,573,744,745,525,916,457,349,254,566,640,763,139,947,482,248,905,820,11,478,700,89,191,892,560,316,700,229,600,646,888,707,366,321,199,287,139,63,340,145,611,619,294,321,645,259,69,181,669,336,27,37,295,106,330,499,460,690,174,461,908,165,383,799,567,565,448,611,714,886,658,27,882,167,51,275,428,134,590,814,902,453,239,555,973,10,107,782,400,140,574,552,409,718,522,532,625,812,955,566,427,429,280,497,382,752,501,84,280,475,207,180,325,794,946,669,32,517,932,201,359,410,723,896,198,429,516,796,892,558,335,103,891,259,400,454,485,654,685,4,834,647,370,446,18,50,290,867,413,95,808,223,397,281,644,982,508,616,679,454,291,817,228,109,284,539,857,418,44,735,634,761,711,342,130,475,928,937,223,692,262,766,511,862,762,212,825,745,547,683,694,473,637,7,602,112,594,83,171,823,430,458,932,601,129,81,287,284,573,292,620,235,713,112,771,40,899,476,639,673,270,113,303,42,431,605,879,447,496,784,349,875,762,567,589,601,52,69,853,934,68,452,281,752,75,60,82,512,644,728,698,380,996,703,533,608,524,582,149,910,332,935,346,555,202,496,281,738,891,173,4,533,43,116,116,597,907,877,641,644,432,923,615,257,504,369,964,937,111,635,693,353,33,617,858,560,42,327,194,799,282,435,23,29,680,88,464,658,868,485,121,545,861,739,908,574,896,864,255,970,724", "695,528,32,91,661,65,722,47,553,70,425,861,197,893,369,129,262,67,805,684,9,214,352,818,250,58,461,463,186,516,93,428,122,350,908,425,366,39,261,91,591,678,614,977,973,890,680,350,137,21,580,212,611,723,970,764,290,576,652,597,982,904,352,356,877,995,516,900,531,780,992,507,605,10,381,838,366,510,716,414,916,712,604,368,807,279,650,866,333,614,404,531,571,311,409,538,603,955,102,946,328,936,430,903,903,181,353,475,707,710,694,348,710,587,937,725,812,541,795,249,924,177,1,655,383,183,765,119,251,351,824,270,955,304,550,837,418,154,523,304,474,299,717,478,718,853,910,448,108,847,165,805,535,824,660,966,197,938,941,781,3,731,374,986,64,457,529,572,483,657,377,899,101,550,846,711,663,125,976,338,46,271,920,666,978,156,632,641,785,227,633,134,677,516,335,719,571,672,91,160,493,472,626,204,859,279,200,545,537,511,372,778,584,701,651,127,220,206,852,949,587,856,584,48,386,594,631,505,984,707,876,42,752,640,945,911,662,796,817,570,846,214,127,476,500,4,618,987,240,804,946,308,923,331,147,48,349,606,316,542,334,317,463,570,486,587,622,142,520,594,558,51,108,623,907,735,508,70,489,308,557,217,186,829,693,452,273,627,101,703,374,705,537,500,379,72,303,992,458,768,871,462,724,59,860,248,123,62,911,283,876,420,475,165,373,243,54,83,382,725,748,611,863,813,800,824,978,756,688,331,152,201,938,836,534,984,490,139,216,241,549,454,453,766,788,317,880,89,189,873,126,96,631,46,671,787,656,934,569,910,258,690,824,805,602,760,661,958,360,34,69,164,116,935,877,672,428,478,0,991,832,802,225,667,552,577,913,497,564,945,318,877,832,140,785,431,802,162,735,559,176,483,824,211,131,250,303,719,617,843,59,693,176,973,184,701,610,349,379,464,340,281,212,317,71,331,683,914,100,784,735,200,177,459,18,556,819,247,866,627,54,303,8,400,788,179,254,572,220,668,406,101,920,661,708,58,800,769,850,706,364,4,844,873,377,747,125,975,722,705,168,505,767,58,448,456,633,570,860,187,767,50,919,509,693,54,68,682,603,233,414,828,523,490,499,249,132,653,417,454,592,134,38,605,926,591,857,945,642,476,888,949,376,205,867,958,389,703,518,356,678,93,615,576,473,479,577,634,847,598,714,231,712,813,672,702,997,582,266,446,268,85,869,405,308,547,970,180,477,572,722,694,254,369,289,966,891,599,956,69,196,143,467,872,834,440,116,930,135,563,363,341,774,140,619,242,637,10,275,700,405,669,66,776,486,571,331,228,597,706,431,639,538,501,526,27,284,543,370,72,726,278,153,97,348,665,67,185,793,688,33,611,984,415,528,758,251,801,646,53,983,784,945,690,103,566,895,185,366,115,174,393,903,726,953,106,909,373,99,832,546,691,667,938,625,287,304,189,431,990,204,80,780,418,417,474,822,493,248,800,629,774,675,91,563,889,750,777,936,472,163,967,833,572,656,535,556,118,571,337,782,512,914,896,636,172,677,403,18,5,121,85,121,931,467,259,404,815,476,514,299,692,834,368,324,674,63,321,10,896,90,128,433,174,579,232,714,522,291,730,184,146,737,77,593,591,98,763,403,601,992,889,516,408,108,959,198,697,13,977,814,540,289,175,418,837,353,165,358,26,489,25,313,592,692,836,604,339,531,780,288,807,238,271,694,448,754,818,233,420,148,997,464,575,374,290,663,371,819,834,397,683,948,381,260,802,413,775,45,238,815,992,981,162,775,442,516,103,247,675,514,512,351,300,977,396,531,523,637,150,44,43,171,479,588,914,185,20,850,436,961,150,78,335,254,15,486,432,231,564,949,63,623,515,419,315,487,66,843,774,495,345,170,546,317,862,974,710,668,550,827,90,179,960,744,5,741,13,215,990,110,809,802,85,94,957,87,717,239,225,737,25,380,878,991,268,666,292,886,271,833,490,522,790,570,45,831,615,554,554,673,654,451,559,373,324,936,316,107,480,443,299,104,851,995,760,33,509,558,309,720,336,184,857,644,540,957,523,199,457,979,278,868,75,649,315,783,857,775,7,663,383,148,271,450,384,991,601,764,875,9,872,71,373,243,450,634,739,351,599,224,921,53,81,57,658,562,340,181,29,620,623,376,157,598,537,548,303,318,503,358,718,768,392,576,173,600,710,476,5,990,246,723,719,107,963,102,421,670,31,805,206,336,316,924,900,863,940,323,361", "211,525,948,311,4,572,727,372,936,588,339,961,564,890,763,558,509,776,24,460,685,309,684,49,762,958,276,166,528,306,194,741,71,961,983,465,829,881,408,77,856,512,630,203,579,530,560,983,937,807,926,215,163,989,130,925,568,34,650,458,311,51,824,169,32,682,321,231,835,822,266,70,394,51,411,323,799,898,417,882,776,680,685,763,549,121,178,75,157,157,840,51,422,701,709,570,776,830,797,909,843,152,724,75,584,57,906,986,586,948,546,125,975,430,326,134,99,924,86,613,885,992,780,612,745,137,781,102,655,467,377,946,83,960,744,75,470,156,497,516,171,177,362,76,505,286,931,818,92,548,236,814,476,680,9,533,481,913,112,649,314,50,162,427,801,459,938,424,82,372,13,815,336,829,264,597,549,641,808,245,47,35,770,551,760,224,368,9,823,109,750,392,692,76,500,416,998,697,634,925,406,466,352,747,157,964,344,378,621,4,861,726,882,215,906,460,107,412,911,128,581,228,971,549,465,132,415,335,364,350,931,436,432,14,27,62,797,586,944,135,620,752,751,167,328,386,252,186,667,751,869,12,655,382,529,865,831,880,702,35,55,160,675,662,688,567,519,952,458,496,663,388,128,663,238,209,846,27,927,566,885,282,63,751,717,11,214,624,342,459,476,296,579,8,802,347,857,691,528,307,978,783,474,874,482,292,260,304,484,877,434,198,418,604,383,578,917,415,247,16,137,538,839,44,47,920,307,260,122,481,66,645,169,701,831,892,265,435,803,821,996,197,409,126,311,632,295,538,767,483,650,604,245,940,457,796,685,161,717,718,576,814,408,353,426,194,892,501,405,732,45,743,383,694,609,212,278,437,991,0,808,114,207,395,95,82,47,332,462,367,210,426,193,201,630,770,756,511,690,74,828,866,245,262,992,163,316,174,253,341,164,374,650,510,766,618,185,249,908,801,60,56,310,475,16,904,199,721,114,290,582,298,873,688,226,4,395,785,438,873,445,955,491,119,832,246,234,529,83,909,496,311,278,374,425,425,875,443,644,498,532,786,930,877,526,36,257,167,621,407,979,489,998,348,435,391,741,992,232,72,748,627,137,673,148,940,618,930,952,89,961,345,469,104,332,556,548,48,968,814,495,317,851,745,835,749,685,106,897,962,127,303,436,214,40,94,992,224,847,79,85,824,775,392,927,599,901,611,724,793,121,226,801,905,976,968,682,580,440,353,660,100,226,87,407,863,257,719,36,598,678,736,411,917,750,502,423,780,205,923,587,30,174,702,179,138,167,992,399,756,143,332,524,741,296,679,564,355,413,317,505,464,335,683,558,72,890,387,66,600,971,237,726,811,160,613,942,5,178,346,510,460,665,419,110,673,889,579,877,368,674,720,975,818,663,206,935,443,22,907,203,853,312,886,750,883,426,460,973,50,192,486,230,645,738,619,489,177,993,972,346,790,315,434,923,719,76,12,673,355,941,964,437,845,123,34,657,404,58,431,712,400,441,531,695,648,149,826,59,161,364,427,801,243,569,814,445,645,110,577,674,180,514,182,917,34,79,783,820,938,54,66,277,108,817,210,243,299,954,451,766,856,472,401,655,686,858,605,328,635,322,70,492,555,976,481,490,320,227,864,531,101,530,825,829,380,8,827,99,211,681,795,426,646,170,419,899,611,340,622,424,234,64,826,289,770,125,63,481,540,807,389,243,271,911,986,277,863,4,945,733,282,621,236,912,989,946,568,558,431,75,18,539,690,299,650,574,563,463,446,992,70,164,762,336,581,317,115,336,340,136,782,999,995,800,753,875,15,406,291,254,749,308,153,117,176,392,950,647,137,978,286,221,423,28,175,574,695,811,917,311,140,478,164,572,996,313,53,862,728,610,860,829,643,706,210,592,100,245,677,758,838,248,236,408,94,730,814,957,498,405,649,139,248,832,317,815,159,141,505,922,397,197,200,768,594,302,600,679,417,366,426,47,84,962,422,594,880,817,691,989,418,185,62,778,831,161,918,617,48,106,67,114,185,130,729,203,439,647,925,150,707,391,257,260,525,689,950,933,419,857,935,486,919,936,298,54,847,227,506,378,871,467,706,349,464,385,62,606,512,526,378,663,410,299,861,229,344,83,16,861,114,153,378,141,989,93,936,458,848,920,605,35,442,672,95,361,95,504,156,532,310,681,431,639,15,428,105,370,258,955,334,694,984,849,94,224,224,574,806,413,241,115,812,167,181,507,969,456,671,941,389,484,305,449,460,325,641,660,77", "957,333,772,494,853,807,255,257,616,389,481,231,525,558,863,169,66,289,69,166,609,774,373,85,789,520,273,48,391,588,559,530,955,597,488,387,85,576,250,320,537,509,300,694,625,617,681,338,278,80,274,828,785,648,627,210,761,741,118,935,795,763,545,897,772,755,8,428,900,816,548,759,213,249,96,83,14,150,176,808,473,150,503,191,619,607,641,899,624,855,948,813,136,740,110,917,180,588,518,737,566,975,796,810,255,964,233,826,842,976,696,2,968,723,895,231,7,376,523,686,350,583,314,328,477,670,473,408,345,5,65,233,139,287,57,423,633,766,130,741,928,836,463,768,458,749,57,30,178,379,360,557,435,562,992,5,94,33,201,796,624,17,540,120,234,61,91,298,272,255,443,59,239,107,129,884,71,306,237,344,814,26,894,996,918,402,329,123,191,1,980,381,473,47,779,360,795,918,108,679,886,419,439,779,390,305,411,650,283,276,618,944,118,191,223,947,70,827,588,997,106,407,315,104,788,656,520,347,231,9,887,376,662,296,142,67,564,320,217,194,626,688,54,568,632,366,999,573,249,331,635,756,900,982,944,552,72,207,865,885,313,294,433,303,632,305,607,713,210,778,703,743,614,3,494,779,236,328,956,589,607,960,454,703,304,694,684,650,439,726,820,942,801,818,630,748,966,514,6,136,199,160,69,751,730,747,473,696,605,7,32,773,187,118,303,64,781,418,479,635,727,610,595,843,919,850,569,113,999,472,193,40,615,264,537,828,925,861,617,101,728,62,420,745,214,177,731,930,622,164,498,879,81,926,437,116,83,261,88,196,236,330,524,901,82,177,925,531,855,965,947,161,91,127,198,814,315,353,832,808,0,708,164,420,409,99,253,631,750,630,177,22,740,669,288,277,915,804,817,980,278,625,49,374,777,572,488,667,108,224,142,871,111,332,741,801,16,574,412,48,704,382,33,951,789,584,576,226,172,933,525,341,638,694,167,280,606,888,529,916,915,576,126,609,335,226,50,828,166,105,670,116,657,839,822,921,628,84,540,705,611,242,754,486,896,796,515,590,30,647,333,711,259,219,804,465,206,162,668,739,152,197,863,784,727,194,719,211,99,955,339,551,312,136,654,706,725,120,272,828,236,404,412,821,321,600,374,687,469,769,99,672,352,725,256,168,653,376,963,342,423,533,948,139,497,702,345,750,285,282,332,667,514,960,854,254,23,840,766,787,634,223,216,892,47,166,200,728,997,187,800,548,121,718,527,10,613,976,975,212,877,862,485,650,727,175,427,11,373,527,147,438,490,383,441,296,397,620,485,636,2,681,387,401,241,734,761,545,555,782,591,729,34,663,616,263,636,382,295,394,20,672,402,53,762,366,299,364,468,430,78,551,785,510,788,52,424,128,931,637,592,896,573,25,888,271,90,220,598,670,937,929,583,646,655,475,920,431,701,136,981,68,822,708,816,668,693,220,561,297,352,402,739,613,35,604,35,154,738,229,443,404,821,163,506,956,611,207,798,450,873,93,829,347,860,752,190,595,978,339,557,496,973,113,889,381,624,292,262,884,191,678,828,187,93,362,829,592,203,885,542,376,4,942,836,724,190,21,776,409,24,9,223,935,252,634,653,532,170,908,869,940,856,11,135,690,742,897,742,754,726,48,837,222,133,782,599,287,4,857,346,998,331,30,318,128,824,857,24,262,204,976,915,932,304,26,956,414,622,288,123,114,314,294,539,516,342,642,280,68,569,710,685,203,449,856,508,794,709,661,378,317,469,778,547,34,788,235,659,392,706,485,61,728,296,417,797,108,759,96,424,82,861,648,443,903,53,411,664,266,553,835,380,845,684,482,649,992,493,568,431,403,770,874,373,926,402,530,568,999,549,660,171,319,973,505,274,60,36,691,183,420,807,294,24,630,44,956,33,447,392,916,611,209,431,484,334,574,224,935,158,705,101,981,225,357,660,767,844,301,975,204,211,222,525,42,114,443,2,117,6,159,134,636,365,455,591,164,275,95,126,234,885,798,95,860,610,389,640,237,729,433,699,617,515,368,22,456,821,959,657,899,914,683,447,270,318,203,461,795,721,571,410,556,100,957,9,404,666,105,421,842,297,291,398,858,683,458,571,824,359,959,446,249,742,519,710,923,401,661,217,280,493,119,876,630,609,258,395,931,29,443,846,263,848,738,452,373,821,337,829,156,985,948,833,275,783,560,512,931,129,988,715,607,194,857,214,774,253,748,87,283,686,840,888,908,886,110,444,587", "685,986,901,25,257,967,819,43,104,826,426,126,137,844,479,931,358,111,447,550,194,34,835,165,919,936,708,860,983,40,271,619,796,694,808,2,666,475,248,862,185,992,735,629,204,827,393,66,303,575,656,333,212,819,532,61,372,703,177,440,947,753,252,809,154,225,600,657,694,560,160,755,861,247,603,723,269,472,932,826,623,788,593,341,74,113,662,357,154,779,978,711,966,163,248,250,169,267,144,755,947,285,243,471,766,346,442,519,429,664,890,856,910,228,915,310,653,116,436,660,816,959,333,936,146,246,167,124,52,121,374,749,341,147,343,826,158,484,702,218,213,103,743,684,167,298,529,59,332,824,253,229,558,483,964,417,705,656,134,641,931,823,275,791,7,639,929,4,794,381,201,911,367,925,179,874,424,583,897,621,66,838,158,694,187,941,860,676,965,620,786,882,196,359,507,807,620,943,850,25,346,649,871,751,387,16,132,957,716,889,725,815,277,378,844,505,990,736,303,78,675,89,39,303,109,231,41,671,856,304,4,671,533,40,299,798,772,87,90,679,786,578,953,887,107,590,9,448,823,453,650,394,82,887,33,145,875,406,997,906,936,683,129,304,428,979,198,401,983,181,288,939,409,342,359,465,376,505,950,527,869,616,406,588,427,820,259,719,831,642,132,333,174,700,188,585,153,36,739,246,94,213,369,714,804,609,317,33,484,331,991,842,978,470,175,320,16,563,170,140,405,928,82,951,803,824,751,111,934,136,227,409,379,529,244,132,721,854,541,736,341,342,663,687,630,913,908,440,873,964,53,777,327,827,145,96,872,324,221,477,247,555,250,294,479,272,463,295,401,33,631,112,433,11,131,167,376,627,802,114,708,0,749,561,681,455,970,836,584,84,272,456,738,40,181,765,899,246,142,49,721,214,313,810,93,854,87,74,760,225,463,320,108,590,685,711,257,256,405,51,566,198,180,568,740,544,683,836,231,914,85,548,623,881,435,314,383,361,625,767,870,207,390,340,332,900,214,514,287,898,42,965,849,65,525,435,647,523,862,238,411,298,472,657,824,508,771,912,681,894,250,249,815,191,935,579,948,948,569,338,265,238,94,97,724,878,444,509,876,994,835,920,293,758,603,361,841,790,432,544,57,734,225,574,44,884,205,171,459,912,287,136,836,857,9,969,941,789,405,609,549,585,706,213,369,9,703,627,800,702,486,399,492,499,985,274,402,744,964,658,487,896,685,970,1000,163,536,53,438,376,587,531,807,915,446,747,721,894,20,157,125,719,20,199,237,620,568,503,235,707,631,71,490,42,965,907,552,328,484,530,653,333,409,260,855,243,37,562,153,277,297,938,340,467,89,718,561,81,469,586,168,773,211,676,285,6,703,523,903,427,251,430,379,469,213,829,540,479,53,793,82,675,338,308,674,92,768,636,50,551,539,802,285,600,697,867,162,462,91,376,258,734,674,432,348,550,154,994,432,759,523,490,206,634,460,790,674,149,13,392,52,409,591,85,113,623,198,278,141,571,271,933,709,399,124,69,137,169,296,999,645,147,16,484,527,259,754,356,775,787,60,989,968,762,530,912,717,126,204,609,230,546,734,645,449,878,922,643,682,660,768,266,531,370,268,75,440,335,498,303,511,77,428,369,568,190,591,863,448,464,771,559,939,290,86,237,775,771,153,571,541,531,907,722,13,511,613,836,787,220,744,583,361,328,928,197,226,550,810,195,316,738,773,416,372,529,805,453,17,286,84,796,989,869,624,359,98,650,651,773,467,762,657,942,628,505,363,986,41,814,608,453,509,968,404,352,594,903,442,953,34,112,545,12,653,475,837,166,216,688,243,452,20,751,609,390,14,941,312,315,165,197,775,553,625,707,248,654,495,101,522,208,996,531,156,812,505,408,832,814,459,52,112,887,460,735,248,606,694,229,644,494,95,173,601,91,581,770,360,53,796,194,847,450,302,601,298,83,503,385,191,67,952,511,589,536,374,427,278,322,994,666,890,751,303,301,245,652,23,434,724,438,447,5,685,654,25,92,785,37,20,823,656,676,180,789,50,450,562,609,729,278,462,196,36,171,193,995,13,279,826,841,422,508,195,526,159,971,704,621,772,454,463,452,695,583,108,84,987,418,312,962,684,781,494,157,449,240,806,972,987,223,286,54,534,255,417,36,360,572,816,88,5,706,576,672,326,345,897,357,290,116,757,713,736,690,590,305,925,468,201,615,139,424,375,851,646,614,87,345,20,580,631,796,237,561,223,935,78,699", "686,829,538,587,935,221,521,765,673,430,487,765,683,217,163,228,670,329,152,841,973,349,523,314,304,712,517,297,291,996,332,490,490,421,496,459,102,451,268,975,70,105,638,286,228,800,182,992,359,927,93,636,334,132,194,797,785,282,524,156,249,864,58,167,39,422,941,537,44,81,964,539,602,427,643,663,812,599,729,619,626,995,428,546,93,852,898,645,273,474,169,946,733,982,393,357,132,459,654,58,407,808,134,879,131,768,493,349,437,26,91,11,109,574,692,361,247,268,232,335,380,416,738,606,754,658,935,28,102,477,755,829,980,367,690,671,970,727,278,631,253,834,896,316,154,21,341,53,420,955,668,660,931,594,890,881,983,578,302,874,502,229,19,563,145,828,461,670,986,855,582,502,192,521,129,471,218,674,603,742,94,442,671,802,523,467,818,617,963,597,763,886,137,515,944,620,340,332,36,225,706,503,235,795,557,278,793,233,583,263,385,138,812,756,990,11,222,26,178,268,258,297,458,960,539,139,459,624,577,671,362,126,311,337,961,970,216,377,258,663,388,315,568,69,970,154,69,644,83,530,888,389,944,846,402,331,105,962,473,102,117,411,194,815,375,87,25,940,980,987,510,917,502,765,139,794,620,652,980,784,794,80,393,550,465,703,222,71,358,538,509,1,913,28,135,77,471,386,306,392,921,186,635,182,959,289,595,497,901,644,316,245,766,127,851,391,74,448,246,143,434,110,206,81,137,338,603,816,137,356,86,431,348,28,455,416,308,114,142,626,159,11,379,287,220,819,890,560,800,15,986,702,81,500,908,336,562,190,87,613,127,652,947,612,47,227,751,928,306,337,542,630,4,209,189,685,954,952,225,207,164,749,0,170,1,423,712,470,17,453,330,924,552,950,349,119,950,169,728,902,586,545,995,344,230,374,228,132,49,730,461,117,728,818,905,84,767,805,562,703,574,55,53,731,657,990,345,335,871,214,229,997,467,980,592,969,902,247,523,811,738,193,411,909,992,930,24,28,913,720,28,354,190,992,819,68,473,509,651,513,469,12,963,782,264,90,280,51,749,778,920,84,409,584,730,841,270,140,349,865,462,42,674,727,494,581,303,52,359,157,453,955,493,738,602,445,117,799,925,248,689,447,978,258,115,211,499,349,139,366,742,151,343,141,183,226,818,458,968,379,455,29,440,274,725,198,22,675,441,626,216,521,25,606,901,907,942,729,583,418,142,800,469,42,945,197,581,848,137,366,656,914,471,397,736,545,257,648,815,942,941,883,436,74,640,113,855,259,523,140,911,415,991,399,421,13,158,598,777,475,977,440,886,459,199,966,46,889,681,987,137,150,692,168,317,195,250,846,619,660,597,603,513,442,121,701,915,792,283,611,846,85,795,642,699,544,871,487,269,186,166,122,710,603,8,326,890,996,941,139,53,659,814,537,93,463,502,157,822,346,596,424,696,459,854,741,823,479,4,585,428,775,212,216,368,492,838,6,191,482,633,439,257,519,91,175,212,606,429,382,539,431,254,96,213,874,708,14,467,94,953,704,333,347,532,899,615,137,473,367,734,814,243,970,112,801,808,830,8,979,25,271,128,941,916,352,396,382,599,459,380,317,774,12,995,694,169,249,926,237,174,363,707,418,840,69,402,242,637,136,413,375,761,454,170,248,714,729,778,278,127,585,760,358,62,887,269,245,580,976,722,232,14,977,919,47,442,687,267,846,472,895,713,912,170,822,7,424,170,218,231,370,405,335,807,106,176,576,365,395,771,824,457,468,680,476,892,721,722,309,762,351,455,965,829,762,231,525,723,211,507,91,608,874,767,720,966,90,572,353,497,173,38,661,677,417,631,294,53,855,46,441,171,336,237,462,806,250,601,800,175,329,308,949,895,4,770,119,805,872,813,998,187,918,680,933,808,958,578,661,623,150,958,83,328,764,679,988,80,434,279,234,561,650,672,326,188,330,715,172,736,792,352,217,78,737,442,583,345,724,898,797,949,129,765,190,69,976,478,822,41,746,746,400,462,527,537,727,358,47,49,763,846,684,896,687,801,270,91,457,638,85,948,105,744,185,599,368,618,962,396,937,546,450,122,202,51,677,296,638,600,338,972,998,404,692,468,966,578,74,775,452,370,316,74,362,245,478,363,251,252,252,664,790,983,576,901,293,509,371,524,672,528,704,488,222,374,30,764,273,577,974,340,606,905,251,134,538,11,85,869,348,450,703,788,573,968,96,459,485,106,336,940,751,368,538,529,23,999,702", "98,680,930,780,245,16,605,652,92,288,26,160,450,152,73,133,409,895,629,386,865,945,826,695,919,345,69,714,16,835,303,12,912,100,215,88,160,130,915,238,584,250,883,772,170,151,551,149,116,770,383,344,808,183,732,272,999,48,580,34,764,159,460,289,321,306,245,165,139,248,728,705,596,192,185,476,912,453,475,957,623,277,207,552,125,66,737,680,865,88,306,940,594,325,135,603,212,166,60,299,928,477,776,291,671,36,573,342,883,617,409,615,343,637,819,812,186,917,251,382,52,994,691,63,97,663,503,948,881,355,486,474,411,37,483,467,840,942,663,660,767,459,194,616,899,509,512,86,548,376,691,968,103,932,565,448,161,857,401,237,791,25,192,173,166,687,201,998,99,900,883,595,219,7,728,975,439,584,392,725,357,272,143,551,19,508,438,762,604,369,263,66,880,962,869,769,9,951,42,184,44,846,484,3,785,722,675,597,594,748,257,975,970,69,376,607,785,650,559,649,480,158,292,367,664,854,56,175,218,647,451,532,3,250,873,38,668,564,874,751,451,376,742,651,948,195,680,604,436,216,41,335,292,431,99,324,923,27,276,795,155,59,566,374,50,324,961,183,696,227,746,388,727,157,171,369,388,262,954,202,62,261,105,110,341,715,960,476,17,79,143,73,948,999,375,282,468,225,618,937,517,33,892,395,114,217,469,664,924,362,506,88,859,185,368,742,918,635,481,107,689,108,20,536,520,349,85,879,535,237,960,5,754,639,618,196,927,333,315,790,698,471,54,916,427,9,488,969,949,180,153,148,492,380,626,141,582,576,266,694,994,402,279,203,231,857,339,663,566,297,410,224,642,199,703,806,315,879,667,395,420,561,170,0,695,201,204,129,339,659,329,857,417,996,830,713,219,31,939,853,348,941,93,782,303,293,333,79,921,41,228,486,78,673,643,366,308,682,497,574,954,788,617,532,273,701,269,900,860,871,340,128,20,347,22,137,419,412,919,493,46,786,263,21,313,352,38,23,638,562,565,748,685,310,952,932,869,251,352,475,918,739,213,868,523,18,997,920,949,150,333,236,84,41,952,479,630,266,607,638,89,297,367,268,815,928,655,342,809,338,620,743,888,82,407,880,525,403,396,958,997,792,850,881,299,905,331,969,970,487,197,494,367,23,248,562,105,61,617,308,745,218,212,514,8,763,196,438,280,49,411,782,829,848,727,839,976,16,277,824,793,685,578,772,647,953,45,25,113,3,533,898,7,902,909,392,488,399,640,249,443,117,601,505,126,653,784,169,613,229,1000,36,724,56,446,725,258,623,445,189,591,798,118,418,56,781,151,411,59,103,241,701,389,802,210,173,777,48,606,146,3,731,798,94,456,78,288,22,254,539,649,92,470,828,29,454,647,558,942,661,401,907,60,34,372,903,299,495,514,472,808,729,313,208,913,191,577,736,953,634,494,285,119,422,455,317,622,935,930,509,267,638,931,780,880,982,448,91,994,737,153,995,158,507,2,521,904,887,977,201,671,844,484,806,942,753,354,304,95,926,647,52,330,824,509,928,886,932,704,400,550,54,716,261,45,541,486,260,523,855,482,839,158,834,968,851,413,955,401,412,173,791,189,842,657,17,844,341,762,595,127,197,351,425,602,182,277,419,846,805,663,509,974,164,602,91,424,656,168,954,920,486,235,876,221,57,226,465,745,818,64,237,613,493,163,164,449,883,136,293,431,821,980,158,853,281,98,387,953,539,942,29,868,188,785,980,944,531,490,650,246,758,19,791,795,663,220,194,886,563,103,875,616,707,506,479,871,696,246,460,740,564,811,674,957,515,140,381,778,545,264,876,223,170,785,457,441,940,233,314,563,626,712,56,867,464,411,366,914,682,955,863,72,640,289,404,144,591,578,771,556,2,98,254,95,740,34,92,475,667,437,338,901,470,575,527,815,203,948,85,669,6,619,826,770,44,211,345,368,67,21,384,114,994,889,739,848,419,460,571,148,743,284,55,692,203,402,374,907,603,92,715,371,483,777,678,50,657,571,433,760,627,530,101,15,682,46,845,554,534,703,456,731,135,816,159,105,341,263,62,546,946,38,993,626,559,289,183,78,658,470,360,414,37,237,816,80,570,895,636,894,676,647,783,552,378,210,739,278,888,486,355,901,17,925,680,235,504,699,812,918,508,895,433,542,724,359,820,599,711,909,160,799,192,632,971,158,74,424,551,815,624,441,639,645,216,791,282,546,586,825,64,260,604,133,650,70,726,256,220", "902,587,299,924,552,131,886,81,234,898,374,710,148,464,322,632,287,621,771,440,313,265,582,13,373,763,224,799,776,153,320,545,744,196,446,943,8,314,37,397,812,78,917,740,611,226,57,237,657,619,121,782,798,550,101,519,536,846,441,650,4,412,996,383,111,106,376,809,585,438,687,691,664,820,105,944,601,236,89,787,265,933,887,452,435,358,577,108,76,65,873,458,204,911,536,738,423,993,805,380,551,466,387,487,899,957,857,75,719,140,287,86,618,798,588,925,326,900,35,124,60,630,424,386,641,602,953,601,606,635,731,297,782,658,927,117,336,669,222,142,485,973,793,697,886,233,286,423,217,840,851,70,300,388,826,381,875,405,99,171,567,709,762,796,502,766,281,466,40,157,865,79,300,603,306,964,422,602,115,51,319,884,601,616,269,950,209,878,718,528,723,144,23,99,204,998,54,808,409,956,727,417,243,517,107,490,916,856,531,281,659,350,626,570,884,728,137,142,19,331,633,149,176,583,753,975,855,773,280,599,225,635,845,860,561,592,319,512,355,155,910,455,899,551,271,607,533,312,764,725,863,496,711,472,466,102,980,877,809,848,826,970,262,325,906,186,460,962,447,857,680,390,989,869,435,886,415,288,683,183,895,389,880,773,260,748,946,694,577,800,771,700,905,140,956,872,341,140,127,847,570,440,419,544,753,498,837,404,703,110,271,286,78,686,470,563,862,74,519,111,609,143,594,364,139,869,728,667,373,779,984,537,735,137,313,36,259,524,137,984,23,553,635,404,352,218,335,344,369,427,207,63,81,437,869,915,35,307,657,20,231,628,743,17,736,112,685,24,526,894,55,382,430,326,18,36,273,947,552,95,409,681,1,695,0,490,706,683,184,435,357,267,60,471,612,324,612,627,842,459,594,610,381,362,20,672,547,573,642,473,31,572,432,474,260,827,54,398,487,766,437,836,819,215,599,964,90,685,750,833,698,850,302,831,168,668,974,198,363,538,694,225,320,36,698,500,614,972,115,659,545,127,664,653,595,504,829,221,378,82,956,202,241,249,858,979,237,726,90,497,755,351,358,902,329,992,813,486,432,784,162,899,493,432,842,566,872,347,630,126,375,627,803,465,898,405,352,699,254,838,663,413,906,959,922,821,646,566,79,241,909,531,268,941,863,772,653,243,901,609,134,97,61,906,681,426,344,97,158,43,775,311,397,801,561,757,795,413,719,444,484,947,59,455,405,309,830,347,909,259,994,235,526,358,97,400,40,711,789,485,540,315,148,826,682,748,47,418,679,619,911,687,524,64,406,903,896,868,810,574,971,745,920,162,226,495,18,228,695,423,337,779,102,816,519,610,29,835,503,200,743,51,878,892,112,166,355,465,174,413,106,671,236,874,64,736,322,661,620,612,98,394,611,244,686,240,47,895,859,971,342,824,378,865,893,219,725,253,845,256,385,953,590,46,629,25,852,810,30,116,125,83,792,54,91,957,702,813,447,208,283,851,643,262,200,551,963,861,293,475,262,208,741,644,543,709,138,513,967,372,437,244,280,595,787,550,507,83,570,545,960,862,499,391,20,277,131,396,254,116,254,616,313,838,946,101,403,474,863,714,14,428,391,26,354,367,267,639,553,95,337,872,308,445,799,983,795,935,591,541,58,693,927,232,684,159,125,252,82,511,990,704,633,682,350,919,471,797,592,605,692,111,222,730,975,864,766,199,959,395,193,197,565,739,824,441,195,682,286,142,348,915,396,478,831,263,519,204,451,530,28,865,817,869,400,757,507,818,406,787,460,320,44,466,184,465,274,405,936,804,850,833,263,681,499,56,912,237,347,392,933,795,392,925,349,682,5,446,629,832,755,845,384,157,472,126,343,382,214,763,973,841,875,89,767,164,3,217,531,801,329,409,813,161,729,827,186,304,387,940,771,838,345,977,972,130,556,845,208,478,268,684,188,154,430,103,789,499,313,967,976,487,80,968,888,970,499,363,27,605,238,648,735,748,435,519,917,137,691,833,832,334,964,621,768,429,347,544,30,115,88,266,851,156,232,405,774,686,871,881,408,666,156,494,448,582,378,755,40,157,75,566,897,544,918,135,698,941,799,652,602,279,545,656,78,315,342,814,574,680,914,394,333,737,850,927,538,182,400,915,667,340,379,798,110,517,792,517,936,609,557,651,506,779,27,157,98,686,278,176,315,92,18,492,457,981,719,727,775,576,851,157,756,49,369,218,442,423,816,927,683,140,323,859,853,817,302,393,696,394", "725,336,181,897,766,72,353,518,454,467,839,299,161,967,2,785,352,944,586,750,270,95,816,785,326,234,193,871,805,746,323,165,391,561,204,291,833,923,592,47,282,375,144,899,683,335,125,16,231,671,318,119,723,843,385,38,702,627,682,205,835,322,697,68,227,600,663,7,217,172,948,328,295,272,295,858,417,231,568,984,23,43,292,60,358,831,22,47,837,385,304,241,714,257,473,812,300,648,673,580,827,93,74,767,776,279,6,207,51,590,413,761,728,662,75,855,896,690,654,408,566,112,821,49,751,83,470,158,344,540,213,320,368,207,225,609,182,977,298,442,447,865,314,182,721,148,929,425,137,740,53,530,586,297,946,755,922,536,303,786,919,768,862,411,980,760,936,911,30,725,736,392,163,530,956,171,466,715,73,627,261,322,668,477,817,660,899,390,814,326,358,356,827,760,84,385,933,831,330,372,477,540,318,988,869,823,230,444,298,192,640,474,440,231,565,506,676,338,943,442,546,143,398,373,493,400,658,818,805,239,529,590,963,639,745,776,343,666,6,118,265,105,685,696,371,779,417,470,452,292,49,595,429,248,76,189,965,601,275,240,42,925,643,575,963,554,771,417,882,743,36,820,6,985,806,286,210,224,669,25,730,972,199,558,502,224,474,726,75,596,897,342,975,453,184,270,437,672,185,79,894,301,754,386,888,743,645,105,458,69,465,825,133,29,462,409,87,726,613,216,541,694,296,727,97,273,322,280,166,693,396,734,434,9,632,358,216,742,852,908,774,983,276,298,745,78,479,778,911,707,876,498,706,937,690,190,822,165,540,442,676,151,499,28,277,459,915,364,996,200,171,558,817,888,392,695,399,298,577,82,99,455,423,201,490,0,737,551,584,320,98,120,322,575,858,700,161,817,754,255,483,705,668,555,962,370,587,851,263,294,276,685,928,670,56,239,922,410,942,833,186,589,544,39,131,184,963,341,204,426,251,748,842,592,433,515,504,475,946,290,459,195,324,165,592,534,277,890,443,601,748,890,411,602,489,152,5,799,739,87,279,973,844,358,129,697,825,117,124,361,950,883,529,240,577,775,681,81,61,39,305,796,113,641,236,409,673,175,250,597,596,592,942,259,522,5,798,199,945,831,144,39,485,85,227,558,684,609,585,913,971,689,103,661,89,162,410,205,792,511,608,564,536,130,73,762,18,955,354,629,440,273,62,754,816,304,175,360,734,733,256,158,19,244,193,812,754,757,515,78,713,25,557,643,531,206,638,400,677,159,101,929,688,923,268,802,245,19,675,533,619,665,270,146,508,551,24,798,510,626,677,173,291,654,623,250,840,863,185,70,777,20,61,542,917,97,257,101,995,37,507,389,71,985,254,396,88,180,625,220,312,958,358,607,750,769,352,780,688,31,700,326,348,212,195,853,338,861,727,966,823,864,780,951,334,266,204,307,151,921,465,156,390,8,912,937,551,45,362,156,722,797,430,212,957,420,136,660,556,36,552,346,936,527,953,441,654,399,230,988,333,63,528,241,989,824,288,784,100,34,624,74,471,559,450,684,185,138,563,613,649,596,933,209,499,641,60,170,489,567,111,253,615,286,872,161,275,488,890,358,739,367,673,823,301,759,553,226,821,968,922,550,429,936,889,243,663,65,557,518,635,473,752,778,89,236,941,237,305,4,410,361,137,250,456,227,81,23,194,29,266,810,607,217,878,317,497,335,778,60,241,679,543,9,705,230,934,803,943,139,774,155,893,703,273,521,195,456,449,483,694,737,453,351,831,616,486,769,166,731,498,495,192,239,471,17,287,817,561,524,423,415,433,454,398,77,978,166,239,62,883,72,115,682,800,934,854,173,758,519,889,320,385,512,453,520,186,373,264,834,109,868,775,367,216,871,251,827,469,628,369,501,192,749,441,32,262,879,66,991,896,23,257,943,353,898,5,426,188,452,136,14,914,43,256,330,634,287,803,654,94,533,128,156,348,991,242,357,521,732,608,481,642,670,648,694,992,364,177,79,894,872,670,838,841,406,595,555,878,458,528,376,824,636,811,108,914,966,373,14,280,436,58,7,618,275,534,935,380,517,992,492,139,910,631,809,970,861,478,6,357,442,685,796,416,824,967,249,859,235,389,781,839,790,450,839,359,198,324,874,494,893,313,885,183,73,602,308,497,195,798,398,202,772,252,900,400,89,269,117,202,689,474,516,168,569,927,36,498,364,688,605,600,199,642,729,212,309,427,270,38,379,42,671,493,210,86,850,482,838", "707,182,886,532,465,635,937,314,653,637,319,41,608,55,176,648,482,125,353,517,570,235,981,294,845,345,625,621,49,713,813,42,248,36,532,774,792,657,510,422,510,811,515,676,510,884,933,183,618,733,980,80,456,888,425,509,871,141,165,982,48,543,329,236,67,603,186,599,750,787,205,670,555,771,870,611,787,801,599,413,318,942,401,63,456,600,378,534,689,387,96,131,187,198,117,198,307,109,335,822,849,157,419,252,84,406,536,136,660,770,190,126,623,218,917,126,45,217,340,889,765,657,537,50,199,120,166,711,901,326,511,339,862,230,757,777,547,746,997,161,975,524,708,305,986,997,592,820,955,489,174,184,837,892,967,246,492,344,189,920,173,266,763,17,485,691,967,976,121,690,729,139,643,204,604,776,784,260,824,583,140,404,199,305,556,254,999,670,290,798,210,334,76,358,377,725,178,946,915,59,631,431,496,427,377,485,724,400,118,152,149,158,587,123,854,585,260,552,668,733,692,227,780,888,278,501,130,434,882,693,771,560,978,768,312,724,220,669,847,159,562,699,783,303,178,91,16,909,897,545,332,467,913,43,470,218,174,956,818,338,595,691,860,278,191,194,418,319,204,884,728,977,978,686,338,847,808,504,874,516,679,144,761,991,779,868,874,249,207,494,404,851,456,491,172,253,646,188,365,858,882,581,361,979,798,536,474,699,806,727,712,193,394,49,803,726,505,301,719,14,928,278,428,854,454,607,58,643,52,371,689,184,440,510,641,138,825,850,234,590,897,543,73,255,225,942,129,862,396,594,875,810,19,436,891,525,26,205,765,693,640,655,99,131,369,811,214,366,13,511,135,235,567,865,579,319,241,509,913,47,253,970,712,204,706,737,0,960,852,701,593,538,927,491,27,396,951,111,406,870,806,929,937,16,161,151,82,339,671,657,350,617,243,910,863,741,129,293,395,33,460,291,387,620,226,350,284,605,534,617,656,422,419,467,830,993,866,39,321,727,130,725,776,140,8,654,828,67,650,42,936,96,570,976,461,926,18,376,303,469,130,166,17,45,883,719,711,525,317,928,203,641,855,498,957,578,269,690,113,858,306,707,301,281,516,690,910,320,424,791,452,290,910,931,572,327,785,689,581,557,554,779,366,600,692,760,916,587,733,113,737,123,894,977,442,389,993,249,457,557,29,800,416,612,571,467,50,269,309,686,31,573,558,918,185,351,43,140,846,333,67,656,38,161,924,407,535,955,185,154,408,855,853,836,278,490,296,760,9,419,809,786,439,303,101,117,449,16,310,841,678,858,47,645,925,620,812,565,454,64,659,122,142,495,597,963,483,518,462,880,222,201,671,502,510,237,602,665,392,309,621,199,647,800,996,772,594,56,675,611,641,284,197,754,203,827,354,64,334,424,273,417,429,327,330,540,750,819,731,232,831,970,192,445,551,564,951,861,347,238,227,487,510,989,313,258,414,9,181,296,364,641,950,566,73,967,28,940,124,935,745,939,895,34,421,80,228,414,293,112,113,748,2,284,709,998,677,470,430,866,814,855,519,666,365,568,964,400,158,24,314,906,581,220,711,111,401,928,661,972,775,618,504,534,105,966,617,483,144,492,787,266,557,11,978,221,551,666,773,454,889,363,706,997,617,813,921,677,726,214,121,865,110,675,94,672,824,122,791,289,253,902,400,490,109,170,123,490,298,993,197,139,445,22,586,982,678,77,847,390,614,118,30,858,42,902,24,980,220,398,867,728,402,926,391,88,912,106,2,528,874,981,865,949,618,634,934,228,500,4,413,680,474,537,771,769,732,732,231,681,167,265,487,685,508,867,687,352,564,53,241,956,624,786,596,935,530,85,17,942,736,353,11,467,433,692,954,473,259,258,949,92,993,203,609,943,109,779,635,95,697,311,658,853,899,928,91,407,851,451,505,613,649,152,436,392,285,81,181,859,201,728,515,907,270,254,989,324,6,333,749,660,94,311,568,616,275,546,18,700,672,938,28,739,60,182,217,644,947,817,948,893,832,959,49,789,296,48,247,146,847,91,773,465,664,916,56,72,282,292,716,180,352,808,623,753,563,727,798,731,583,753,858,888,158,982,859,683,768,308,595,484,457,37,883,561,636,898,501,693,514,659,707,605,572,800,928,675,83,28,755,270,63,852,223,498,9,420,400,586,576,743,514,569,816,31,927,709,938,837,508,731,738,978,827,549,844,313,218,700,498,947,849,87,478,397,853,58,383,760,597,666,839,844,773,7,356,342,607,526", "758,909,162,749,922,394,657,145,442,462,795,656,698,64,939,519,85,324,309,242,671,216,518,734,422,798,951,451,715,705,550,174,535,928,127,639,834,839,201,735,389,706,948,382,364,395,753,475,343,304,832,491,114,928,564,110,560,327,378,338,563,812,250,96,366,199,320,872,179,27,208,720,729,396,68,169,436,921,539,977,797,862,88,29,815,392,848,678,796,696,81,148,993,537,78,735,623,442,545,656,596,634,180,950,450,857,958,802,915,266,925,920,87,277,611,840,386,360,378,265,626,807,263,238,675,367,316,382,741,340,522,59,979,108,479,509,380,756,51,575,910,604,803,535,206,56,745,469,605,296,66,845,138,127,328,598,783,110,428,263,309,700,945,152,360,135,620,777,922,313,638,933,379,467,93,929,417,540,967,416,498,894,619,537,716,929,324,451,934,385,92,806,305,647,782,493,90,589,843,158,453,237,727,300,205,830,288,322,55,203,524,166,756,596,726,420,808,103,932,856,580,419,321,560,613,210,998,354,299,851,665,663,109,511,53,478,738,591,177,637,206,645,260,664,451,993,192,393,770,534,484,351,887,142,981,679,208,807,677,845,248,738,346,29,311,13,782,420,344,719,982,455,50,694,282,835,345,906,443,484,75,452,654,487,57,882,860,319,612,41,586,348,609,248,947,18,179,641,502,726,887,422,965,808,618,986,683,683,16,611,356,602,726,833,684,507,812,205,283,493,647,917,583,203,533,78,649,980,457,852,744,96,853,374,136,676,741,449,120,629,595,726,878,946,151,468,979,566,161,710,751,215,477,249,80,73,684,355,656,348,235,88,249,134,18,395,600,41,168,204,311,747,978,985,107,747,559,135,497,332,631,836,470,129,683,551,960,0,915,359,895,973,553,126,20,82,966,929,129,745,922,585,841,437,823,430,215,272,501,433,789,222,403,471,706,314,251,67,589,852,955,461,630,24,138,282,278,802,832,873,196,932,235,904,115,528,924,807,517,244,181,484,965,123,193,420,252,128,254,87,329,29,268,434,137,214,965,77,686,357,74,414,692,143,246,252,838,191,401,238,623,884,600,75,612,798,660,413,631,208,147,667,366,935,255,596,92,482,309,648,22,11,344,880,381,281,891,501,385,208,699,119,904,873,976,825,640,276,847,144,782,247,666,535,444,41,410,503,140,929,626,73,282,528,64,520,2,240,750,496,363,860,412,564,749,974,479,538,618,495,289,285,692,792,190,900,892,728,693,177,355,810,245,282,294,952,794,222,68,531,353,843,150,104,972,958,695,529,346,681,272,936,7,964,242,72,865,443,194,610,936,407,182,223,309,735,442,610,605,165,608,399,949,81,974,331,530,106,716,387,526,685,609,926,371,262,80,671,836,343,214,231,502,642,328,97,380,667,210,311,476,764,579,279,617,224,365,198,291,313,322,65,352,675,193,928,664,804,239,711,755,183,247,659,696,919,663,949,908,131,715,775,514,448,7,578,876,59,760,751,864,894,908,40,305,417,884,244,498,998,404,574,401,619,195,231,750,814,124,914,566,717,322,624,956,855,588,5,80,953,689,471,312,86,923,597,48,525,281,484,257,613,358,112,494,595,11,158,813,889,325,615,37,937,711,850,323,233,163,816,285,106,498,138,819,527,923,113,270,233,573,393,419,461,811,308,802,25,497,804,835,333,819,263,105,2,362,626,336,72,732,783,493,423,440,881,1,843,423,692,916,575,770,110,265,117,572,776,278,91,37,140,899,878,371,638,472,187,688,49,546,972,272,101,429,115,394,613,743,499,276,11,933,146,978,196,204,549,437,460,557,862,517,669,145,641,524,818,932,949,91,16,601,223,957,76,535,812,721,808,624,159,260,634,934,136,826,79,19,683,510,450,845,154,22,680,218,759,521,707,435,92,539,264,892,337,35,892,142,382,188,786,26,910,881,549,199,645,368,822,974,652,251,395,783,139,226,476,199,266,490,740,37,456,641,963,28,36,121,904,731,344,931,636,475,935,15,327,660,894,554,386,384,695,702,821,302,17,529,732,362,38,102,588,322,964,886,332,725,200,131,656,268,943,182,657,372,914,132,997,171,740,968,658,363,389,434,104,746,604,30,290,744,305,658,198,976,446,113,403,503,83,407,131,261,354,662,428,277,782,165,333,782,328,83,255,477,408,75,654,575,624,83,228,550,63,904,177,975,101,195,391,10,746,6,556,508,743,146,856,356,874,827,332,677,369,674,189,598,575,581,794,202,834,589,948,749,893,86,560", "194,196,473,460,650,389,340,923,939,179,63,592,61,537,292,330,328,370,421,716,352,447,548,579,864,194,54,937,639,855,234,67,864,462,642,914,503,580,432,51,663,200,643,495,637,86,268,41,645,623,441,360,153,237,511,845,13,833,882,947,574,990,906,552,462,808,318,453,799,903,745,460,258,246,600,871,7,159,855,459,61,754,258,540,985,793,110,531,74,191,463,164,755,416,361,759,287,5,448,917,430,619,204,856,183,57,902,813,795,320,59,184,941,355,819,43,439,37,614,123,405,894,414,609,491,324,510,853,297,865,913,467,104,976,682,341,240,149,608,27,243,795,558,287,47,598,968,494,697,807,719,473,109,915,585,523,458,883,583,256,531,590,658,878,469,135,693,498,276,836,930,730,774,994,42,636,454,576,922,97,3,845,295,681,640,882,799,859,656,258,747,560,468,913,898,207,117,768,317,273,558,347,346,612,392,126,560,274,288,848,799,345,775,61,377,761,526,123,674,325,757,80,922,505,894,30,373,284,730,428,438,157,344,779,937,78,19,228,241,818,169,390,567,535,238,94,666,459,819,263,243,154,55,921,798,239,301,546,911,952,271,482,595,319,124,492,876,58,314,724,723,934,833,345,2,41,344,124,599,487,500,17,520,862,316,294,719,1,838,47,399,712,47,80,583,815,208,227,361,529,427,506,261,466,2,401,445,783,616,906,197,477,838,948,186,835,582,554,945,549,562,333,686,92,837,823,365,289,779,620,115,981,886,599,280,875,796,829,404,739,682,952,215,580,504,858,208,346,737,118,101,884,702,508,761,404,673,446,910,802,209,228,242,775,806,625,457,829,520,502,865,805,688,468,913,687,830,10,564,462,750,584,17,339,184,584,852,915,0,965,819,308,25,120,838,40,182,317,258,686,767,103,897,400,229,291,899,630,40,133,590,546,459,405,735,574,645,241,507,873,50,449,390,54,307,701,763,251,931,447,125,512,403,646,288,886,902,208,370,944,60,750,42,723,370,835,635,123,144,983,659,743,132,179,636,659,789,148,833,557,968,77,124,441,766,784,276,74,320,655,436,113,785,2,169,490,641,160,383,867,924,618,333,804,933,165,346,274,741,953,177,240,949,167,62,878,377,974,89,818,677,256,860,354,772,155,740,849,244,565,389,473,841,870,112,570,129,537,830,862,669,397,335,374,923,155,350,853,432,249,482,126,678,597,816,758,687,851,815,397,760,943,8,110,575,752,338,902,547,346,808,853,428,343,74,460,275,466,53,333,377,25,710,14,769,538,816,166,503,145,90,276,735,517,999,137,333,743,108,684,568,779,104,425,219,561,462,719,483,784,274,646,950,163,22,490,502,35,782,787,844,949,390,64,894,460,827,771,298,11,741,380,262,624,171,905,669,341,411,797,208,891,583,109,297,483,11,880,705,728,836,336,87,832,248,229,827,490,527,539,838,203,20,603,739,864,863,135,551,77,608,402,538,249,954,249,235,57,68,610,31,847,791,615,448,847,874,415,117,321,521,596,782,527,586,197,146,138,531,821,689,636,856,389,560,757,855,481,227,386,174,334,279,283,123,737,668,46,506,896,460,281,442,627,494,680,325,597,637,46,273,673,551,200,307,57,401,763,170,609,506,881,242,150,690,399,380,418,802,796,542,235,420,171,539,4,442,163,105,919,79,252,855,199,289,847,231,986,797,713,437,755,363,442,933,223,62,102,769,909,379,688,718,838,683,818,574,537,40,446,959,14,89,229,856,342,564,582,235,112,100,787,750,17,251,28,412,75,794,119,559,868,844,131,720,343,598,424,902,567,352,867,175,893,973,560,736,902,317,786,176,671,812,569,152,12,331,223,103,914,65,778,727,20,473,97,628,403,193,192,796,701,378,29,769,46,518,548,53,402,374,810,961,660,664,689,189,106,152,231,542,783,222,857,794,728,420,570,295,27,193,800,646,112,631,584,523,442,162,491,267,863,53,233,176,747,990,8,412,388,80,984,41,699,685,935,620,93,903,381,69,989,219,405,600,228,812,443,650,503,984,368,845,144,822,488,567,2,355,405,144,157,81,866,689,66,166,99,385,107,498,224,994,232,296,924,480,125,326,172,206,935,765,412,354,951,626,563,342,561,328,399,704,13,770,390,172,899,406,821,590,663,481,449,319,420,335,717,385,398,254,224,871,375,581,926,527,530,854,646,942,151,465,942,413,297,980,129,75,307,677,711,331,470,856,165,633,879,571,7,784,4,440,688,220,379,943,148,351,286", "461,614,446,8,824,609,105,466,476,299,663,432,758,840,526,413,705,208,846,532,651,777,906,908,699,447,204,556,965,624,961,232,612,345,182,785,912,286,790,489,46,69,730,300,890,101,456,974,923,340,435,651,966,596,413,960,994,951,517,679,611,336,632,701,212,329,886,760,934,332,374,626,673,275,395,782,53,741,734,390,380,634,923,694,589,800,766,173,869,737,104,521,340,12,78,838,386,619,46,885,590,44,526,730,951,517,808,826,436,90,337,835,509,935,304,299,566,307,333,815,135,945,556,577,277,686,304,802,778,809,118,260,685,725,988,302,345,331,656,480,684,993,771,437,987,542,287,342,968,513,611,78,553,584,437,980,711,517,135,222,992,560,499,580,509,250,62,958,833,937,791,627,370,509,929,319,273,131,852,575,655,267,533,790,834,275,407,155,25,182,21,317,646,956,75,648,615,71,778,732,643,434,622,634,806,516,960,968,382,791,101,588,135,119,885,658,244,244,934,443,212,933,804,382,80,279,882,939,380,758,406,749,631,862,406,302,841,652,709,685,330,654,945,811,375,957,679,11,567,203,274,204,485,635,556,638,62,57,871,412,333,542,181,692,190,436,340,584,68,557,27,133,774,587,700,69,732,645,906,119,246,265,894,889,845,401,644,216,534,586,367,781,624,82,16,402,272,464,697,930,748,448,971,729,503,219,755,18,263,161,477,371,800,839,578,698,380,141,720,24,122,7,224,702,755,607,798,339,904,389,415,173,325,380,641,317,95,827,607,673,365,142,305,965,84,163,487,493,270,462,326,791,715,356,944,472,529,331,134,645,768,747,679,489,155,164,801,311,103,697,799,821,176,88,951,775,665,75,945,367,630,84,453,659,435,320,701,359,965,0,678,182,459,606,97,970,987,779,657,202,554,331,912,664,488,604,871,878,187,732,27,719,99,221,481,137,790,497,534,448,716,871,152,296,651,685,884,764,772,893,486,927,665,956,149,285,394,166,70,734,791,255,836,737,787,803,667,140,763,818,698,72,354,322,370,471,469,845,564,506,536,118,464,896,251,386,644,48,289,211,528,273,999,344,500,953,229,268,298,832,521,561,685,595,496,80,869,875,707,202,887,309,997,29,815,231,588,765,87,703,708,110,254,491,68,385,262,549,82,854,431,91,331,283,809,951,917,611,518,156,614,458,883,31,195,312,5,579,38,4,967,607,27,320,753,25,869,332,591,896,749,16,237,305,808,691,38,316,210,912,522,974,121,632,66,964,728,575,699,720,952,800,607,105,206,470,380,26,781,309,315,695,55,632,895,190,353,445,416,541,45,51,221,71,873,839,804,752,216,740,572,678,414,878,299,64,145,204,675,39,392,188,268,750,107,89,77,146,149,710,174,317,785,727,525,331,282,788,693,761,706,848,949,208,971,705,150,47,229,986,124,651,441,542,278,845,902,600,531,1000,284,751,381,111,596,576,49,197,807,143,9,209,226,845,151,241,490,927,474,483,13,777,192,253,727,29,949,159,964,577,583,130,153,988,925,322,471,152,920,333,782,607,364,321,28,372,511,76,928,651,108,687,146,90,230,712,569,599,527,615,411,711,190,510,608,54,886,393,158,617,48,822,18,47,34,713,279,357,751,151,980,164,975,470,414,669,591,820,412,992,510,891,984,466,248,711,970,123,80,55,483,498,425,263,229,829,136,412,264,418,566,245,971,663,836,772,707,619,802,193,703,97,218,997,178,265,755,365,696,712,220,757,305,698,94,819,611,278,321,99,262,380,194,722,176,358,58,709,414,60,900,63,340,294,270,475,110,707,914,520,971,236,898,647,379,209,37,279,733,846,98,896,8,765,611,655,63,36,874,822,588,188,586,883,776,818,263,531,414,491,237,89,364,11,914,574,143,661,618,384,357,311,476,821,720,676,594,594,948,885,950,45,254,223,264,52,503,234,376,858,353,861,476,525,378,75,301,64,140,504,476,713,159,671,463,373,580,553,489,311,726,4,496,341,986,571,33,118,983,890,426,792,418,687,724,478,722,17,391,471,990,247,899,627,453,409,62,636,974,152,477,745,327,297,536,517,143,155,662,144,426,589,215,630,48,441,196,515,546,35,425,749,499,180,821,333,328,889,734,964,613,153,264,173,827,674,782,341,935,152,428,813,30,821,170,813,638,958,21,755,387,479,118,445,607,243,925,56,644,430,929,448,551,102,476,423,240,351,371,459,802,200,968,509,804,254,889,722,951,408,285,211,886,444,803,567,940,399,145,325", "411,118,210,857,706,382,332,908,470,471,21,82,209,224,890,286,581,149,380,605,148,709,822,461,946,194,476,761,310,34,331,249,358,929,721,659,35,516,629,170,289,968,535,870,607,871,126,886,469,282,236,183,788,59,689,858,995,640,961,348,951,822,606,710,29,961,723,354,886,594,102,648,923,109,187,687,353,627,650,305,798,294,475,273,390,834,261,76,16,997,168,980,989,815,504,740,632,214,471,974,439,87,941,679,980,549,578,972,47,15,416,504,525,894,517,301,743,665,390,475,211,76,860,521,515,145,549,259,555,530,966,328,615,775,63,122,516,613,862,54,351,770,765,789,798,838,723,206,999,973,217,559,594,589,961,894,486,482,681,759,466,944,262,833,74,828,171,791,638,621,109,780,107,566,443,246,321,436,407,810,44,592,757,354,952,38,515,654,755,817,405,355,898,178,385,735,491,153,591,103,781,209,586,842,973,951,788,325,293,142,448,497,273,906,856,772,247,420,353,458,531,610,225,177,104,259,52,629,975,478,759,838,700,52,595,251,375,156,767,312,781,463,296,727,573,579,710,634,792,7,948,476,962,936,948,942,54,879,932,102,305,92,633,282,520,90,842,214,495,88,540,983,16,482,925,386,270,89,60,46,457,151,731,637,606,283,34,172,935,153,36,408,655,242,290,945,735,484,731,102,735,989,542,160,262,510,123,926,788,471,166,180,19,888,433,596,59,462,571,840,658,798,792,653,957,553,570,26,776,799,389,130,569,32,573,802,226,739,866,140,621,417,28,600,812,707,266,341,540,566,860,574,167,264,938,280,623,456,514,453,813,266,870,16,899,332,443,79,637,295,278,803,253,704,911,366,817,416,318,210,177,272,330,329,357,98,593,895,819,678,0,910,411,381,776,248,302,108,39,398,61,87,117,25,786,773,225,169,366,562,237,873,26,814,782,462,309,542,207,51,967,432,646,571,268,96,818,79,80,26,54,888,276,943,841,7,383,16,771,55,881,869,257,422,495,421,537,491,955,239,606,750,10,385,512,382,262,293,266,885,593,434,242,707,968,595,950,397,592,875,84,578,444,760,865,166,458,796,25,946,589,489,12,260,560,883,533,157,288,540,390,558,582,181,306,925,390,857,504,684,613,398,591,536,331,449,292,76,112,74,262,8,74,726,931,186,941,67,450,720,226,370,851,736,389,289,240,268,135,526,965,745,801,531,710,65,921,245,200,261,995,517,691,1000,684,439,222,70,247,388,205,242,231,787,830,97,444,561,814,810,689,224,851,728,772,310,602,73,806,444,980,518,402,793,861,921,115,471,942,178,3,805,322,735,451,357,771,260,93,271,971,470,332,836,724,617,529,103,165,53,856,26,347,81,111,265,482,197,707,54,878,417,751,727,588,787,309,339,845,606,775,340,126,789,833,708,481,561,38,640,372,477,400,627,385,186,890,623,563,490,671,509,504,595,54,15,541,329,567,617,942,609,475,163,965,486,895,405,999,78,411,467,971,207,914,279,767,697,784,942,350,435,635,752,978,605,755,162,148,938,831,853,222,758,30,310,715,999,823,473,370,18,72,175,429,329,298,377,54,609,940,330,389,818,586,153,20,369,421,60,454,353,589,59,208,600,967,41,402,898,277,823,417,257,695,542,622,9,808,496,995,853,818,6,891,582,69,794,672,452,264,825,140,636,391,523,358,498,853,299,814,278,923,401,884,196,485,17,489,399,996,772,943,683,581,367,760,370,291,856,142,775,574,41,727,302,5,498,611,566,900,794,755,149,115,920,277,395,788,500,217,719,705,265,195,97,721,420,501,905,28,131,239,347,710,276,521,837,296,302,715,185,448,939,548,910,860,478,190,717,957,371,227,413,512,534,637,326,358,721,598,6,581,512,945,967,689,18,609,309,16,657,607,83,95,295,273,812,621,420,478,97,40,619,485,743,926,588,70,63,979,7,197,986,51,359,132,510,220,269,16,322,541,176,398,368,513,355,101,647,894,339,680,692,307,902,987,658,262,288,393,649,696,51,562,708,169,376,739,54,397,586,310,746,323,400,413,901,785,554,240,529,320,813,657,902,554,897,181,898,457,407,915,243,674,289,293,158,223,297,799,906,81,451,181,693,610,291,670,306,498,972,845,706,53,599,929,75,688,603,88,20,788,515,454,309,704,985,40,318,596,435,780,303,464,597,198,909,38,454,535,189,367,192,249,154,566,431,406,419,489,960,561,980,82,37,330,86,90,899,122,836,542,112,950,274,864,657,471,612", "177,198,8,632,553,805,240,757,249,503,433,387,726,791,449,932,906,966,39,532,885,757,330,736,743,323,743,381,344,877,56,203,178,670,834,465,650,329,823,340,583,49,790,554,502,366,557,424,63,725,987,270,436,921,466,254,784,80,94,251,370,626,844,97,986,187,291,785,980,50,734,782,233,974,773,354,110,377,939,533,594,363,660,816,760,686,454,602,436,758,549,892,541,193,636,877,222,402,51,263,718,421,522,184,514,187,641,463,24,53,926,34,384,16,744,515,261,314,117,613,453,362,347,938,94,994,965,433,822,480,138,937,458,893,828,563,867,913,481,547,748,554,27,667,326,149,74,841,732,50,245,839,494,993,714,607,426,405,142,684,424,569,40,381,322,831,331,524,99,337,447,375,786,979,124,963,864,515,111,299,829,471,218,793,931,259,100,600,435,980,263,822,459,621,650,806,748,185,282,754,991,55,803,36,99,891,498,584,550,848,859,359,922,378,845,251,875,440,719,94,435,259,197,109,908,982,768,911,340,388,94,219,688,508,89,192,881,909,998,191,62,436,211,375,681,989,954,998,264,49,278,76,976,327,745,510,225,139,32,947,992,38,951,656,897,965,879,922,509,941,902,362,5,601,925,231,853,535,380,376,714,593,104,10,150,17,700,637,405,485,974,466,682,691,316,283,987,503,514,233,287,841,873,118,778,463,817,282,739,973,310,795,103,633,419,807,294,735,7,608,197,337,752,683,784,642,868,680,202,956,67,299,876,506,968,729,783,314,447,394,680,110,871,31,687,567,581,233,238,417,730,371,545,416,4,741,273,458,923,260,156,366,150,61,827,853,908,676,66,453,147,194,823,47,916,592,491,352,877,426,22,456,924,857,267,120,538,973,308,182,910,0,226,340,491,414,747,655,357,89,60,646,316,340,963,288,897,732,743,397,807,865,830,649,893,916,480,852,326,636,104,893,885,315,57,477,514,579,817,826,908,59,441,923,445,688,251,848,962,820,443,518,320,445,166,756,966,737,991,102,151,292,624,304,740,90,614,834,135,288,519,907,55,206,854,814,14,986,311,822,764,962,169,499,217,323,244,961,972,461,355,772,182,716,846,470,548,285,132,598,474,558,202,228,354,645,301,29,76,707,744,850,676,153,963,436,99,151,846,355,579,556,838,421,562,400,797,527,453,991,854,844,299,228,628,447,482,565,709,455,118,698,814,402,808,178,126,355,155,991,721,348,63,796,424,182,424,509,745,190,425,335,195,325,337,535,84,453,654,327,939,808,566,478,864,947,414,667,111,890,318,793,554,839,273,875,919,41,13,91,929,616,247,444,487,74,808,853,107,968,579,588,784,658,509,151,656,384,669,933,285,603,457,670,865,549,381,650,367,307,404,681,499,273,227,855,265,372,262,532,777,131,697,43,662,341,368,683,101,562,148,22,487,323,411,498,269,291,940,633,436,248,743,315,242,942,550,194,166,97,163,57,867,316,913,654,184,127,552,543,469,839,521,110,908,251,106,325,617,304,943,573,441,975,651,551,491,315,802,305,794,403,21,196,683,871,575,603,933,349,387,36,797,748,648,51,941,536,845,326,533,627,345,55,426,585,712,760,198,401,513,543,418,10,115,369,281,695,746,856,338,704,258,269,563,358,522,547,650,796,485,168,56,840,821,615,485,851,401,954,156,86,453,206,760,84,976,911,971,64,894,86,401,469,559,584,248,939,896,21,351,917,701,842,26,897,700,675,252,195,789,622,614,120,948,573,401,185,95,122,450,314,515,439,367,836,11,498,554,648,183,316,426,952,296,792,644,619,372,249,406,956,312,552,408,58,960,656,94,759,157,822,415,657,272,175,974,718,670,612,541,715,485,457,658,33,468,826,36,43,47,727,752,81,158,285,17,276,525,866,859,275,97,425,155,173,165,753,156,544,988,52,860,166,103,667,584,793,702,826,108,126,488,541,352,589,625,123,304,443,714,258,860,849,393,462,927,472,272,463,124,46,735,207,789,25,868,753,893,107,483,476,81,665,799,459,666,530,548,427,627,123,447,356,372,503,193,914,719,153,439,282,439,791,318,820,590,326,59,218,90,4,120,318,458,953,236,709,521,115,417,95,170,488,370,48,644,886,353,363,58,517,920,654,973,300,740,896,688,418,756,79,236,320,580,811,586,104,923,918,7,942,972,81,109,314,75,399,604,724,662,819,212,184,909,200,430,338,499,729,414,699,965,90,570,691,618,336,967,275,80,919,480,149,653,719,682,235,424,826", "912,700,431,316,75,632,945,846,130,301,777,69,580,530,596,351,680,437,82,825,996,665,350,307,841,920,687,206,358,251,594,33,613,627,31,519,764,688,67,623,851,559,308,734,3,23,891,647,701,375,548,103,786,993,681,798,751,931,388,642,769,69,337,461,741,403,986,483,255,221,653,954,356,268,891,800,93,174,360,887,374,153,440,609,371,281,532,372,792,848,498,319,430,921,599,140,299,235,466,699,449,15,931,810,240,991,460,644,525,399,821,15,822,911,847,516,177,708,975,32,659,600,517,921,214,336,267,368,246,743,573,201,895,339,428,371,854,281,549,18,699,126,481,807,981,32,168,6,442,138,455,71,312,527,354,692,531,367,29,530,783,182,17,549,355,736,749,13,459,961,227,233,17,159,529,507,781,211,35,135,461,795,585,718,498,137,121,321,35,36,760,133,465,508,728,262,947,251,926,43,230,364,95,94,231,942,995,166,570,147,927,42,966,527,323,372,614,262,450,893,504,448,202,956,349,814,292,313,915,468,72,752,149,908,102,500,208,289,79,185,798,659,441,314,145,831,631,999,865,605,26,569,514,94,79,635,450,897,600,363,70,556,77,626,88,523,12,970,582,494,563,988,595,159,750,178,917,103,869,658,52,8,346,807,448,86,246,169,873,207,685,713,932,312,944,796,880,131,432,35,107,104,48,812,370,192,983,420,353,361,918,206,729,669,200,131,375,567,968,120,823,481,892,828,81,601,763,455,866,524,935,891,887,758,473,654,721,917,709,721,736,590,75,96,505,806,380,631,8,535,241,888,93,164,186,728,358,354,947,977,216,661,886,562,892,164,770,667,103,6,528,864,69,589,269,684,308,680,832,193,740,738,552,417,60,322,927,553,25,459,411,226,0,294,879,726,251,952,687,630,536,750,226,364,692,299,33,227,730,867,733,977,958,524,662,25,338,47,585,757,531,67,611,578,12,87,967,524,734,428,949,32,794,195,355,508,14,579,215,657,577,863,557,865,197,927,18,921,459,321,285,542,841,654,291,520,937,875,939,257,72,977,566,466,968,632,349,342,508,647,45,210,388,217,187,109,862,531,277,582,270,826,233,138,556,281,999,802,863,491,866,420,522,188,939,468,193,760,358,667,496,847,906,849,575,163,724,625,912,831,226,301,797,172,87,718,875,59,306,315,685,329,936,844,694,946,461,730,142,649,268,766,441,447,255,467,773,713,215,759,69,415,616,57,614,182,358,382,133,605,253,384,987,319,514,161,920,3,418,359,461,996,667,392,924,266,863,455,669,415,763,113,30,491,75,872,772,425,407,188,391,160,642,92,960,960,756,398,830,163,197,687,906,423,790,560,329,985,499,276,747,4,390,222,533,629,37,269,279,866,912,994,49,625,273,444,637,127,443,215,273,773,399,455,741,748,549,850,387,995,840,389,678,767,753,376,513,85,129,280,435,64,172,492,589,25,966,332,959,185,785,871,988,638,990,629,520,747,405,628,590,938,639,984,820,52,477,203,493,925,20,126,434,777,431,444,63,585,242,696,379,742,616,161,677,1,587,732,302,994,216,921,604,61,689,37,431,347,557,209,662,53,330,295,305,35,803,865,770,415,333,586,169,455,30,973,110,426,804,654,400,186,546,918,59,964,13,860,509,247,134,898,961,363,769,646,918,877,493,750,200,254,236,985,16,55,865,175,2,560,863,178,580,482,823,991,83,870,313,515,937,836,978,114,414,771,547,608,245,688,504,471,64,88,58,617,135,802,359,461,355,750,972,99,16,271,184,42,611,887,673,806,981,172,340,485,610,768,792,308,187,953,822,70,99,333,345,576,547,342,526,679,776,770,209,208,11,947,724,317,566,751,437,702,576,18,985,479,111,21,423,183,798,356,935,244,574,587,221,947,856,639,440,551,329,945,984,30,130,710,609,905,247,686,750,450,697,53,767,667,796,658,246,603,519,896,946,388,172,565,798,824,819,31,199,441,106,895,970,136,70,472,153,517,936,523,803,552,89,792,776,771,62,740,58,856,966,642,157,747,329,387,606,445,371,39,64,36,202,739,806,463,942,146,380,991,288,916,965,911,864,189,687,386,477,158,187,163,960,47,162,226,721,730,906,195,809,270,270,436,804,278,411,605,42,827,366,322,9,157,594,939,923,585,678,39,294,51,274,527,224,373,877,160,81,789,409,604,896,868,245,625,992,80,64,797,384,493,311,391,762,640,35,15,942,31,116,188,525,717,310,359,253,636,782,897,756,774,245,280", "818,94,161,271,185,55,437,365,772,433,702,699,698,709,241,476,526,910,287,732,794,788,879,792,422,932,55,338,732,350,260,936,651,787,300,393,380,352,594,94,181,731,632,919,767,359,444,864,83,71,723,869,236,880,426,760,356,628,844,100,877,654,277,8,976,725,480,245,299,499,848,133,600,231,616,190,668,305,243,908,950,123,734,618,142,396,655,978,584,441,847,492,465,736,417,366,135,798,230,662,771,916,351,399,42,394,939,986,222,348,153,613,859,693,967,161,633,909,808,783,853,787,769,982,119,653,684,478,9,490,246,355,623,734,267,24,190,670,510,981,451,626,149,909,445,815,468,269,693,629,171,637,764,128,360,325,955,270,803,434,398,372,385,130,846,898,118,566,274,75,580,760,258,34,443,65,596,44,229,667,208,438,328,58,200,832,896,947,59,305,653,721,487,926,658,601,182,398,373,79,657,620,984,210,467,352,151,396,31,411,304,916,410,375,854,736,873,222,682,275,12,322,390,794,191,189,64,376,71,27,681,985,592,711,595,663,557,863,249,968,340,359,782,446,839,36,143,191,847,414,303,639,541,87,146,956,309,443,546,827,402,115,756,64,400,312,822,936,925,708,364,17,720,169,166,812,927,614,187,321,132,52,714,485,68,288,965,14,935,780,997,805,410,549,345,863,21,52,388,202,910,422,742,624,526,134,421,434,964,252,465,78,538,886,697,276,413,750,104,720,726,582,857,950,779,494,61,56,979,559,131,666,542,533,323,707,423,773,292,268,496,380,826,188,689,650,842,789,477,583,966,27,910,684,851,460,7,144,361,441,999,5,328,650,142,668,322,471,125,432,804,670,185,156,60,968,952,757,140,201,669,40,950,996,471,575,491,126,120,606,381,340,294,0,31,585,857,493,636,613,310,848,191,514,457,746,815,797,627,662,204,835,142,140,685,211,15,595,286,859,957,673,226,951,181,132,394,601,647,466,51,241,789,876,352,672,708,554,104,930,154,294,752,129,30,181,970,318,468,560,65,357,768,81,609,522,60,396,985,129,316,694,893,852,504,479,131,640,190,455,924,524,521,612,237,409,322,739,730,79,896,786,367,134,519,207,892,674,749,347,224,557,649,889,713,500,953,44,200,733,350,500,247,927,108,13,807,86,618,281,332,418,829,658,559,121,119,302,723,87,71,52,814,819,550,46,439,125,796,868,996,932,53,795,189,939,244,939,737,387,920,480,607,559,656,545,436,760,11,370,66,693,338,236,339,887,462,808,292,707,623,353,473,663,858,47,255,15,551,72,421,625,9,303,672,5,812,212,194,97,248,914,801,776,788,849,701,129,468,854,384,584,776,626,264,695,503,584,966,101,981,944,593,305,871,992,54,744,647,580,236,237,211,117,301,81,632,395,872,603,419,622,846,562,303,335,56,760,331,677,152,448,285,424,114,824,990,323,489,828,151,42,532,164,506,544,648,501,906,695,912,604,519,425,433,74,413,576,259,192,381,628,403,279,341,515,460,461,601,968,91,183,842,61,810,882,235,747,995,118,838,184,482,785,5,679,734,254,890,71,907,175,398,771,144,246,150,425,185,24,987,963,497,653,336,738,795,455,268,401,698,231,147,732,682,682,954,664,897,315,421,736,9,809,33,152,900,145,222,686,597,444,94,659,861,475,316,980,910,878,258,603,572,785,182,380,237,68,606,720,715,673,25,779,272,625,270,484,531,26,997,80,120,983,566,279,660,455,902,977,762,103,717,767,312,707,33,539,331,33,140,152,949,14,202,192,937,280,399,788,225,130,585,334,603,803,368,251,18,559,788,48,185,882,706,23,711,590,277,25,174,306,956,606,430,112,110,811,478,678,131,612,741,447,482,27,718,584,441,347,721,100,172,638,455,704,516,240,619,223,188,138,158,562,683,129,891,912,505,165,239,718,861,902,128,446,9,825,37,117,419,726,925,448,420,736,240,160,70,407,15,890,302,290,766,270,710,767,4,620,314,172,824,633,462,424,334,259,836,703,23,403,497,865,12,850,563,877,888,10,176,123,791,772,684,759,658,424,225,792,67,598,930,694,329,487,742,429,531,209,15,346,342,204,23,836,9,215,830,922,991,756,902,666,38,620,473,760,733,723,289,175,743,875,266,276,54,105,758,105,841,540,875,150,767,725,720,680,655,29,883,332,657,774,655,249,417,326,138,909,278,128,689,742,372,697,546,487,447,624,316,496,590,274,730,530,264,663,446,211,645,315,278,648,781,566,710,685,973,881", "92,100,747,872,901,538,260,626,156,701,414,697,668,18,922,455,835,113,249,399,771,420,962,509,109,988,507,939,190,261,658,489,646,918,590,763,44,606,109,652,804,110,114,98,646,757,401,203,197,441,535,485,802,472,474,164,22,901,68,658,750,63,399,402,209,300,126,591,722,506,687,790,828,457,719,392,251,807,739,962,545,666,20,830,308,233,634,444,486,942,406,591,890,273,852,88,221,469,741,407,482,746,100,49,10,76,416,703,573,113,323,73,821,547,743,837,431,341,8,316,654,842,375,973,648,412,93,287,970,383,747,725,468,799,918,880,75,540,129,346,467,472,33,461,482,917,379,257,515,973,898,500,226,712,311,830,255,523,43,478,626,24,163,145,110,896,167,953,148,152,134,3,35,684,273,606,340,539,258,507,426,60,969,457,258,14,85,688,434,927,203,71,19,838,920,780,790,992,374,830,240,342,286,409,2,880,981,169,950,896,642,350,286,159,840,771,442,609,844,142,935,643,465,354,183,349,15,824,395,664,393,9,837,377,508,830,817,678,869,56,235,472,649,741,666,460,132,973,356,67,365,343,721,585,88,529,643,883,215,464,674,897,601,33,975,994,81,912,353,779,489,366,729,177,975,443,121,594,452,125,532,732,68,545,136,87,688,658,37,777,304,364,922,207,793,362,373,884,443,396,959,416,929,296,707,96,332,943,939,329,162,664,523,858,892,683,872,99,725,92,828,617,647,547,465,253,947,456,199,725,585,58,701,273,963,969,186,90,940,396,685,737,409,5,225,367,115,224,662,811,558,402,933,506,231,53,60,155,602,228,642,986,421,209,778,932,580,975,218,47,157,376,994,285,540,891,839,370,785,630,288,181,349,830,612,858,27,20,838,97,776,491,879,31,0,888,33,730,656,521,745,155,894,941,174,842,982,631,576,617,837,575,926,273,175,911,525,437,838,572,415,967,652,830,13,700,99,625,302,522,160,858,631,787,564,896,763,628,953,813,406,256,591,104,282,109,612,591,671,593,497,917,876,70,773,76,714,898,309,677,514,608,821,694,555,526,540,226,965,300,53,554,721,652,760,805,657,826,751,382,691,996,304,389,304,329,87,109,716,495,510,420,32,883,799,913,157,721,717,818,241,72,862,598,846,707,498,350,223,393,410,183,921,178,295,935,133,747,964,807,982,423,855,72,115,538,371,367,274,820,415,541,148,584,66,911,241,784,126,738,945,642,285,574,730,352,92,311,379,534,142,472,880,23,372,566,690,552,322,525,293,706,246,884,942,464,827,782,227,952,193,449,476,370,973,865,17,375,122,870,472,499,776,616,742,901,288,338,744,177,486,782,41,367,994,2,657,16,360,438,718,828,129,221,623,852,478,812,975,252,983,515,57,135,965,417,917,152,592,469,519,44,580,441,35,486,554,346,129,392,416,848,28,988,336,805,936,210,480,230,241,448,199,750,867,411,369,647,474,951,647,620,913,596,13,721,675,282,837,463,748,392,936,501,442,271,647,186,129,199,289,802,159,553,540,213,698,594,13,45,971,452,539,54,412,353,487,246,625,27,606,882,296,107,969,385,923,33,384,621,312,910,257,797,621,549,953,269,578,158,36,666,519,51,267,911,451,134,339,640,375,390,301,977,626,753,803,462,104,873,419,94,392,797,421,843,315,997,533,303,341,835,101,720,564,334,311,435,865,629,443,498,273,299,919,286,633,589,791,229,55,553,283,52,977,643,461,229,829,647,499,718,261,751,513,370,933,484,443,309,7,339,683,735,219,609,285,40,465,658,954,68,194,258,214,382,870,762,97,953,994,373,345,21,907,848,17,612,18,689,80,232,158,735,220,763,634,687,432,680,333,662,678,764,234,595,383,670,917,550,195,927,225,920,770,852,140,253,523,697,918,678,94,180,9,288,432,43,508,952,319,105,152,177,730,814,818,179,219,839,234,640,661,987,619,344,522,6,944,310,751,344,606,407,805,189,289,881,398,224,585,653,874,348,761,809,114,840,630,753,581,76,870,167,205,924,340,553,578,279,624,733,997,668,631,29,878,510,968,487,529,110,654,951,220,706,178,231,413,246,183,702,270,100,205,327,439,764,490,505,72,332,347,728,898,741,169,917,418,313,443,936,303,248,237,56,456,786,605,130,494,10,521,656,670,357,374,634,380,274,957,107,768,585,968,361,257,3,1,250,607,132,592,131,995,594,420,319,197,950,653,879,809,289,844,573,989,831,953,953,16,526,158,651,827,103,122,899,853,80", "512,29,529,797,342,92,398,919,414,553,112,143,37,274,314,481,782,345,337,897,992,820,778,567,454,26,567,912,185,816,232,596,435,246,974,641,714,10,316,683,999,526,897,669,161,174,659,437,379,631,713,622,749,860,271,613,192,519,179,725,87,513,488,866,115,329,492,489,716,899,638,700,530,761,240,308,422,679,550,987,212,464,832,81,531,104,667,112,278,579,888,65,561,173,960,965,889,69,3,292,724,383,404,76,958,444,759,602,619,691,904,73,211,373,118,364,250,504,231,950,431,847,500,674,291,376,44,933,446,600,504,724,531,719,172,283,662,752,177,402,726,825,115,294,277,755,694,291,950,793,318,173,31,570,811,959,858,845,501,3,248,802,676,159,163,534,46,483,983,797,807,263,87,493,54,198,733,410,876,807,380,248,772,312,146,651,683,994,617,588,558,608,104,937,287,904,741,616,458,90,732,925,307,847,769,558,212,411,28,86,256,302,351,499,173,516,750,44,354,732,771,73,73,465,829,191,762,414,489,45,771,567,796,309,183,580,394,588,544,623,994,284,586,245,648,615,611,862,811,26,564,604,748,296,319,903,262,390,569,328,31,741,750,243,470,914,575,287,473,155,543,2,603,713,198,155,117,872,367,655,287,681,240,537,108,835,34,629,31,417,571,227,361,896,646,577,140,976,102,444,819,601,671,882,577,130,99,45,555,163,153,377,574,449,967,278,808,110,725,641,475,497,535,771,494,766,811,47,115,976,111,177,321,623,843,871,338,682,80,107,329,629,172,726,223,383,974,100,669,44,799,338,469,357,797,938,167,174,570,713,650,627,906,976,798,169,502,244,255,471,144,445,337,262,364,446,244,682,431,770,277,765,119,713,324,700,396,82,40,970,248,414,726,585,888,0,797,337,846,94,502,438,860,319,892,280,4,336,62,45,723,163,570,869,114,101,312,55,391,109,425,795,419,960,221,155,952,179,743,904,57,78,521,854,716,210,21,36,605,800,914,597,770,405,737,383,982,538,694,220,84,507,301,101,921,515,726,183,570,40,370,437,232,198,916,935,92,927,2,821,800,188,935,406,742,344,511,677,380,326,94,801,864,893,953,707,863,106,429,499,663,137,368,97,240,671,801,197,518,198,947,740,607,398,648,7,254,83,88,44,921,698,508,519,932,512,637,626,137,328,120,527,439,363,288,859,457,95,147,907,594,90,779,643,562,224,997,837,746,948,523,27,526,661,510,227,66,351,365,304,276,823,829,976,925,485,792,926,214,347,851,210,365,53,249,273,190,279,49,660,731,875,711,907,480,203,349,35,808,868,233,354,408,867,413,344,853,539,65,778,17,998,134,490,984,209,356,291,101,664,330,271,381,298,702,54,537,211,420,271,260,222,927,164,735,534,935,244,681,359,660,252,577,415,364,54,282,196,613,131,667,727,547,509,30,831,525,652,648,546,993,378,266,560,156,558,368,587,966,519,732,556,83,183,292,599,932,753,755,227,481,812,176,927,7,680,723,759,888,489,705,518,673,491,558,635,349,749,163,897,797,931,740,69,842,99,746,411,213,928,763,264,950,85,452,205,287,573,599,126,427,101,531,101,835,39,826,708,584,268,371,552,803,11,284,366,125,418,260,987,685,974,74,457,79,80,46,593,335,164,101,131,708,457,285,227,132,294,205,241,57,333,925,177,405,14,202,695,658,316,196,528,359,701,897,664,76,283,927,435,393,404,798,11,942,140,203,297,965,27,839,645,514,973,7,155,919,466,667,367,252,473,452,903,538,433,482,344,320,73,327,519,592,542,250,892,787,844,580,310,974,286,40,500,993,728,652,450,53,860,654,962,372,48,66,645,247,18,780,306,301,205,719,317,764,654,125,556,687,726,16,198,113,935,531,479,933,887,516,29,629,953,988,886,314,864,687,874,790,244,923,881,45,756,223,786,887,2,534,38,292,569,528,398,103,264,37,589,289,362,130,988,175,931,241,177,480,959,785,284,117,429,91,752,40,375,226,47,426,590,277,859,359,825,651,693,582,348,394,856,21,485,316,343,616,153,257,465,615,118,246,31,182,980,205,538,920,224,370,361,988,288,534,126,257,690,160,556,165,441,136,576,770,66,552,168,500,9,164,782,85,814,538,893,792,124,974,178,94,885,646,130,5,598,206,717,617,258,323,948,517,138,314,398,280,352,804,431,45,188,517,523,75,908,703,350,758,444,99,764,262,88,140,628,364,834,90,161,624,151,812,970,206,297,43,138,15,491,114,804", "480,381,206,99,892,696,945,875,695,759,381,935,820,298,195,608,611,63,433,261,471,47,390,241,953,122,222,675,75,486,856,139,479,765,107,893,831,358,71,901,988,472,148,457,260,811,158,361,140,891,554,545,950,107,793,130,643,86,780,286,181,806,726,880,992,635,77,242,848,175,815,662,698,642,496,272,778,845,816,936,439,845,972,568,453,582,482,802,563,525,39,797,210,551,890,643,635,187,322,539,677,604,597,539,978,921,685,81,408,391,878,749,326,44,831,694,1000,52,394,338,607,793,845,483,647,51,432,109,614,447,899,870,565,213,363,590,930,967,791,738,961,364,622,511,644,71,742,240,933,431,300,506,27,630,283,321,879,653,271,141,793,200,512,74,686,898,438,282,758,583,555,772,760,922,291,718,818,750,349,274,749,326,469,192,674,119,758,38,346,178,405,221,222,414,730,767,751,484,571,248,854,577,414,85,392,772,532,137,337,108,368,870,291,925,210,208,222,285,256,900,104,720,188,73,7,972,130,702,889,978,810,515,574,828,672,199,946,921,952,73,140,848,269,806,691,886,718,186,728,997,27,769,951,249,846,278,325,936,424,898,572,617,813,697,330,361,485,61,65,885,892,886,352,848,145,5,971,47,53,531,685,28,888,666,77,171,338,347,159,487,991,927,580,336,407,531,764,746,135,858,518,934,128,980,766,911,279,609,140,23,32,23,538,959,495,964,618,456,666,57,595,992,466,892,937,215,460,639,998,824,519,596,41,855,211,742,478,315,628,262,109,832,243,219,955,577,750,560,449,66,256,646,569,319,70,764,133,723,602,822,27,204,7,991,978,587,861,755,481,105,964,629,235,980,969,462,14,586,802,756,915,899,950,219,612,161,951,966,182,987,302,747,251,857,33,797,0,23,711,590,691,22,557,468,403,991,646,753,658,670,742,478,254,202,924,738,87,308,938,876,710,10,406,478,69,294,370,80,404,271,249,830,160,915,511,57,171,685,198,359,718,157,442,985,948,533,891,592,665,714,309,826,207,528,316,611,515,495,854,134,73,232,725,559,41,314,440,540,987,105,97,640,465,630,455,243,788,466,869,767,156,686,226,370,845,183,387,9,696,98,797,916,717,681,87,591,753,269,898,309,482,354,743,221,686,160,37,604,466,958,428,542,210,666,680,779,392,487,94,907,520,934,677,637,489,996,66,853,146,605,608,79,713,818,681,981,578,233,815,917,40,68,986,119,905,262,623,485,186,526,114,822,826,256,522,410,981,434,480,121,422,318,499,543,788,230,943,12,4,663,660,726,84,888,367,718,126,438,840,405,155,651,784,75,473,686,997,248,170,91,424,350,292,527,126,103,20,212,381,672,666,454,255,440,96,912,187,337,125,259,519,185,650,422,331,225,210,797,544,959,36,20,756,473,739,176,811,97,648,364,803,606,481,672,314,137,899,709,942,211,261,64,786,701,924,579,948,632,884,417,736,675,579,114,527,410,239,841,117,155,581,780,510,299,813,488,118,292,722,495,873,992,93,467,540,442,952,167,24,518,981,798,658,537,867,474,982,492,732,428,726,930,265,509,621,464,186,750,686,129,796,29,232,405,654,338,892,951,524,502,249,60,69,346,500,188,967,30,279,928,582,221,799,60,421,476,632,943,655,672,584,243,453,386,673,649,994,766,218,584,135,191,52,542,563,238,138,233,89,491,551,298,6,189,710,991,494,63,356,663,599,348,958,997,809,914,447,256,735,560,539,998,535,658,168,743,49,4,264,291,693,906,206,112,405,235,262,909,456,390,322,580,88,167,921,412,804,47,776,668,1000,120,351,972,705,616,141,422,468,571,597,234,219,792,212,397,902,952,655,532,750,368,875,190,506,382,767,112,955,809,516,949,301,107,938,916,985,120,314,507,170,302,41,567,127,397,310,49,39,61,914,719,453,337,487,676,110,654,182,836,618,939,139,243,203,163,942,133,796,872,678,462,571,177,361,862,102,860,217,725,226,528,907,693,847,740,391,450,548,993,756,573,509,399,796,329,7,942,902,840,225,872,894,801,414,483,725,701,892,225,518,448,342,479,775,967,863,240,246,169,566,108,469,719,887,175,669,108,491,963,893,889,316,887,757,27,335,265,731,685,46,750,720,988,781,947,878,532,469,102,638,949,239,991,43,416,168,740,746,303,95,28,454,28,150,775,460,359,204,110,409,190,758,493,34,528,138,133,44,511,967,900,636,318,989,697,483,994,608,961,515,791,782,187,4,571,685,103,260,184", "795,933,568,729,859,452,948,274,314,861,396,143,215,227,576,152,777,259,36,660,458,960,868,563,397,923,155,659,798,686,806,435,798,792,297,447,428,913,675,414,833,824,355,539,909,828,24,608,656,157,435,594,79,560,794,594,554,481,412,775,601,575,456,642,136,825,198,209,694,228,930,870,950,801,941,754,827,402,402,709,861,205,300,712,216,579,582,242,888,333,969,582,383,76,714,174,657,356,812,824,391,414,126,701,507,34,389,816,153,677,193,318,514,310,568,431,721,990,412,547,679,816,694,566,308,860,545,450,778,984,164,880,332,367,333,37,987,941,983,322,846,657,460,531,615,878,358,471,919,183,983,824,453,353,272,629,940,54,116,910,429,19,890,979,213,100,474,383,5,420,272,891,595,154,121,228,181,883,534,409,270,263,871,919,49,715,428,256,111,184,102,465,667,725,24,193,527,247,411,527,343,558,701,715,813,432,590,669,776,309,446,626,869,47,355,179,647,820,291,129,552,793,508,339,330,268,61,798,818,685,112,260,611,70,477,654,128,62,676,900,953,726,259,391,909,676,110,301,70,961,720,873,568,866,715,824,721,160,621,55,759,489,797,133,551,87,65,56,409,134,613,639,663,256,458,143,74,704,505,820,517,761,560,413,446,430,519,931,100,410,275,453,717,926,560,674,210,740,456,530,278,446,313,983,83,447,708,518,300,365,937,965,286,941,464,235,39,103,162,894,863,372,619,947,28,623,942,205,836,447,238,123,669,726,331,247,137,529,976,886,706,437,698,749,889,496,933,997,525,807,691,151,273,255,119,563,502,955,779,857,676,231,331,213,251,30,882,265,770,278,380,222,421,555,537,874,13,282,162,511,804,246,169,31,627,817,111,929,317,779,108,655,952,493,730,337,23,0,492,211,868,133,992,252,68,771,698,370,323,352,864,569,929,188,368,890,224,888,600,193,842,719,825,808,320,496,594,879,723,670,506,683,829,682,193,28,706,531,267,533,966,894,908,9,509,390,708,716,861,312,495,334,700,663,25,764,839,170,906,50,859,463,793,923,98,579,955,25,845,68,171,696,90,9,101,386,789,456,285,712,302,761,243,755,270,880,446,913,757,97,441,855,877,914,940,352,605,516,612,368,881,10,602,33,796,295,225,816,304,590,215,37,461,365,354,587,796,604,454,36,946,859,850,599,522,832,612,495,832,603,849,745,254,236,628,313,905,602,935,732,501,706,534,433,387,489,688,874,961,776,221,294,913,90,844,990,954,877,719,163,22,902,281,293,19,746,432,22,909,199,214,839,852,87,408,29,816,115,119,22,155,403,173,232,289,138,734,645,197,750,933,550,217,738,695,882,863,575,403,448,316,715,945,236,331,860,587,312,478,270,143,225,371,763,947,588,799,676,131,467,218,186,792,315,992,873,761,238,133,846,12,836,458,860,722,245,451,948,945,98,17,751,333,593,717,728,586,14,715,809,885,921,469,297,974,848,123,949,159,209,528,783,315,920,462,414,26,517,888,852,667,154,772,780,893,217,476,159,117,655,40,592,740,322,432,118,833,264,946,737,800,41,230,817,147,227,834,149,509,928,759,850,703,740,571,896,825,261,663,196,200,254,411,10,983,150,606,112,675,970,33,645,901,223,507,358,955,216,596,778,163,759,994,173,98,122,717,858,787,804,368,916,955,326,263,114,467,410,31,112,234,41,561,424,70,65,214,450,377,480,574,294,510,985,427,49,515,489,994,167,706,314,449,333,914,760,177,384,170,448,641,384,432,523,871,597,798,547,919,805,649,462,958,677,661,224,948,357,565,208,773,275,376,746,407,654,61,909,567,635,655,506,124,995,385,199,549,712,53,75,322,978,610,596,329,591,125,761,885,236,366,188,627,304,552,230,406,679,775,374,364,608,380,381,650,30,518,920,856,616,545,538,163,281,64,118,895,644,885,641,859,850,921,84,564,874,610,497,227,508,272,235,533,483,416,2,369,299,152,409,209,127,268,463,958,83,302,767,924,779,296,248,672,485,486,697,803,657,148,478,454,328,333,84,197,366,184,210,600,783,635,549,911,277,206,88,999,616,176,518,436,688,370,96,210,571,725,172,651,989,23,151,699,29,282,364,665,435,784,321,306,335,928,418,479,780,266,263,550,73,865,618,470,165,282,414,865,498,220,654,329,794,791,500,810,879,735,990,646,770,643,749,510,580,920,400,26,192,163,526,253,829,473,655,746,697,427,780,794,90,961,624,245,164,843,845,740,992,836,866", "586,46,758,76,356,703,762,927,152,224,791,736,276,504,857,674,594,757,589,805,1000,87,386,798,48,856,372,989,907,657,898,677,597,497,976,73,94,564,558,244,975,38,198,609,403,361,392,123,599,309,557,561,879,408,420,161,454,72,50,645,638,613,81,920,478,676,787,48,167,137,42,354,545,400,780,823,483,415,519,30,407,71,705,648,754,952,485,768,683,778,338,293,214,129,897,175,899,286,569,245,453,301,738,31,905,402,718,594,224,558,614,91,459,213,285,602,218,254,784,399,597,940,293,58,573,410,57,438,750,604,270,555,764,50,381,413,330,736,472,858,389,200,248,54,414,459,567,808,412,798,873,399,444,448,298,102,688,432,841,323,991,94,131,640,468,54,819,775,937,931,264,628,719,636,168,352,137,911,802,897,220,769,384,890,839,934,910,106,597,679,616,857,402,358,634,200,817,947,314,875,580,161,691,709,246,510,615,15,566,553,967,914,934,367,570,538,740,858,570,45,14,359,232,941,691,397,767,801,628,951,796,31,145,76,828,545,695,578,134,910,881,705,522,315,968,810,304,618,469,739,593,624,390,984,264,632,378,724,880,219,459,900,307,349,30,674,334,581,734,162,869,871,934,451,772,573,693,298,597,847,368,866,412,970,673,606,773,795,184,691,293,749,667,438,993,907,853,224,822,241,420,781,804,875,593,726,486,92,450,594,406,192,72,12,183,598,400,104,902,519,207,960,985,693,290,251,493,610,309,297,200,119,41,715,421,894,72,344,765,469,172,289,628,645,963,941,277,342,76,654,511,996,510,725,394,803,458,938,343,755,901,226,929,407,755,107,132,114,672,800,595,538,488,208,956,485,280,444,735,690,817,142,728,939,842,754,406,129,258,657,39,357,687,636,656,846,711,492,0,751,705,565,273,418,734,243,239,419,610,925,325,222,135,472,126,513,759,439,615,438,340,886,738,273,497,32,738,796,899,881,622,389,315,636,192,480,894,449,563,520,811,470,68,62,740,643,3,894,718,728,657,662,347,938,503,185,363,130,879,365,971,545,506,253,278,774,800,424,772,745,212,856,217,114,742,892,324,202,293,227,421,956,453,171,149,204,808,641,392,887,326,79,716,643,690,387,852,891,959,194,335,470,602,19,178,285,391,195,649,739,612,453,707,285,105,818,868,29,77,585,234,297,974,659,874,965,999,486,233,136,428,769,250,950,650,517,440,500,199,757,874,553,216,517,302,15,247,641,288,787,308,639,149,1000,23,211,874,791,637,315,148,71,683,517,351,630,233,973,201,810,715,299,280,515,483,649,927,631,96,380,953,522,234,99,878,806,747,892,456,744,976,240,491,694,270,261,286,986,6,599,859,424,814,862,29,8,918,886,516,633,994,279,34,487,676,445,162,763,726,142,695,942,678,973,278,946,78,15,119,303,711,841,951,701,503,540,677,108,160,336,295,4,289,713,839,327,830,735,314,34,783,922,984,375,892,584,718,993,981,457,778,58,187,538,422,727,124,282,97,991,488,586,157,919,71,916,675,142,954,798,735,502,89,905,723,717,680,29,638,194,30,326,128,893,600,85,408,980,934,788,363,592,137,939,481,139,724,925,231,782,556,469,6,358,266,633,567,394,404,135,559,247,64,984,609,743,418,58,185,475,505,434,328,691,718,225,192,487,189,817,849,989,429,600,86,212,68,311,49,596,954,387,345,860,233,454,561,485,64,174,211,110,977,149,825,971,259,12,549,912,737,47,280,620,80,648,528,409,117,642,92,931,85,268,560,498,137,777,516,403,934,636,844,184,161,336,748,190,569,121,553,590,120,353,451,86,482,239,854,855,763,978,979,389,793,168,51,859,472,424,177,547,904,172,568,931,81,737,773,364,248,675,396,988,146,601,980,225,748,13,807,747,228,357,821,118,254,527,96,126,527,398,982,328,672,766,756,437,36,557,661,105,846,842,323,349,464,874,288,586,902,184,382,817,98,162,550,558,23,458,397,604,216,811,804,820,549,877,48,926,189,736,578,647,328,428,859,702,789,566,775,236,320,5,470,605,911,837,850,26,139,663,935,1,362,817,238,960,939,560,433,816,208,355,480,569,569,70,115,674,435,157,922,832,842,572,699,382,974,253,91,142,253,537,656,526,106,327,796,181,524,668,894,955,942,240,271,333,581,327,255,946,575,209,944,979,276,488,696,832,502,5,517,756,82,367,734,564,267,80,37,25,897,173,365,945,786,12,499,740,75,759,502,453,210,407,489,792,115,403", "161,32,752,585,312,891,39,242,662,387,10,872,651,799,608,53,410,86,71,283,273,163,326,176,791,128,298,312,697,940,31,83,6,951,478,615,956,463,522,196,337,596,476,416,641,53,551,834,368,783,277,599,936,359,934,865,115,63,21,46,703,350,316,707,637,133,820,582,542,437,955,660,272,317,674,467,348,692,520,348,138,409,886,153,912,874,959,321,804,325,277,659,738,844,539,30,887,409,611,736,2,333,708,585,319,805,458,51,650,325,88,177,118,422,744,70,235,41,127,485,770,890,871,973,461,540,228,636,503,129,241,180,798,576,292,776,53,148,371,294,555,292,819,413,136,656,755,391,451,598,797,969,225,96,657,48,112,124,854,455,739,59,902,622,401,664,423,291,687,855,95,346,319,570,190,672,302,753,74,295,386,658,341,327,181,881,816,990,968,685,234,601,574,497,958,288,578,954,182,849,595,542,286,447,363,25,964,286,855,916,885,476,363,411,984,26,756,883,321,211,232,238,274,82,121,528,451,197,342,587,390,308,885,583,700,169,433,352,24,400,777,177,627,801,27,90,412,622,534,903,913,556,872,604,994,535,224,387,290,943,836,933,629,175,284,789,922,821,813,256,739,908,164,767,375,498,14,98,79,649,499,722,420,701,139,400,638,28,290,717,240,246,797,428,6,910,813,833,473,384,911,512,922,641,401,41,698,531,487,724,8,713,12,204,473,24,373,530,670,958,998,712,292,668,985,240,344,893,633,289,146,450,466,738,456,603,150,601,386,513,90,297,190,928,205,375,961,335,809,601,563,101,757,151,646,600,222,772,622,792,881,893,168,998,406,899,52,123,625,192,204,338,871,537,813,556,749,174,559,74,980,49,902,853,459,255,870,745,686,202,398,89,630,613,521,94,590,211,751,0,947,219,98,717,10,807,619,476,967,19,690,779,807,126,8,833,113,787,615,601,563,102,309,278,999,534,693,500,793,707,121,807,721,777,901,641,665,534,770,845,890,597,866,981,255,816,829,559,550,82,912,428,343,614,206,924,998,907,136,567,534,942,549,209,667,874,35,507,323,999,23,598,947,279,16,596,841,472,939,547,207,847,504,584,376,207,859,533,170,913,675,684,255,841,826,64,186,817,857,85,740,606,71,250,979,517,260,827,447,188,579,131,507,431,642,742,102,516,41,495,356,545,529,775,815,464,514,520,480,32,343,81,101,990,102,614,565,547,805,646,649,102,819,246,279,205,754,572,627,551,384,690,813,628,999,157,774,681,512,699,227,402,259,668,104,194,402,636,181,258,137,312,5,405,152,490,261,72,514,116,200,871,269,120,919,273,709,800,611,921,625,604,386,225,99,468,740,273,444,131,681,558,920,184,621,436,98,940,285,840,506,635,787,738,456,283,481,721,977,771,441,384,736,639,607,904,740,230,273,265,807,173,565,339,377,150,182,549,223,947,745,295,862,184,549,421,893,340,529,570,997,523,865,736,422,376,602,703,809,422,87,26,958,50,31,75,423,252,704,435,799,589,612,433,511,879,321,371,925,290,140,258,959,950,978,297,808,485,513,39,471,938,140,547,708,803,935,996,548,842,919,734,173,876,682,28,579,697,466,338,263,862,54,833,959,360,890,399,304,693,832,623,979,330,300,118,237,207,554,606,146,302,304,366,118,659,608,673,89,154,266,488,517,822,200,652,237,634,352,386,55,951,893,605,808,547,866,530,54,372,460,584,562,897,487,527,992,504,784,531,739,136,869,327,277,423,819,883,122,465,236,192,852,435,373,587,699,95,252,202,952,307,975,261,515,945,646,295,793,712,557,546,35,285,388,678,501,431,980,671,199,723,785,905,674,195,118,943,12,800,818,343,50,915,364,808,905,580,122,93,940,78,157,350,634,651,839,201,623,867,534,162,73,700,473,674,753,721,891,250,820,424,255,144,518,823,917,583,775,900,918,369,797,559,857,934,168,317,132,173,337,462,310,933,223,722,801,668,412,977,898,972,979,905,185,975,69,684,629,876,795,557,284,797,646,882,863,818,468,17,810,206,521,379,635,229,896,387,780,883,243,506,219,968,436,995,464,456,856,950,251,463,190,717,460,609,328,14,577,717,150,800,185,975,323,29,53,304,61,340,717,468,556,650,882,381,300,172,679,693,380,70,471,612,444,314,135,237,713,298,175,27,880,569,755,674,65,648,746,607,776,764,641,288,577,601,179,92,151,134,956,347,645,642,594,379,318,78,805,763,846,639,678,768,706,292,418,272,246,404", "962,920,346,832,803,218,474,716,621,451,780,11,161,684,80,567,245,357,940,238,784,299,188,841,507,908,592,106,577,466,394,612,638,110,346,484,759,574,693,292,755,103,148,62,342,21,523,137,109,267,957,830,294,464,922,829,553,582,872,677,474,368,139,889,757,545,672,476,440,28,843,942,883,481,653,580,924,88,404,127,94,546,317,213,736,913,659,361,856,101,883,501,740,793,879,824,301,995,929,623,835,394,549,426,280,729,218,573,570,695,583,331,375,374,532,304,432,979,373,675,828,278,531,587,904,54,193,159,87,717,100,759,256,896,278,999,757,621,582,702,807,326,907,398,815,991,443,91,69,950,207,764,135,131,267,400,702,335,452,249,724,427,526,125,634,44,685,927,399,800,968,658,506,712,28,11,744,92,685,796,687,241,32,840,130,213,424,983,455,718,535,646,520,312,363,101,491,906,874,485,438,143,425,872,54,624,667,308,611,946,409,739,16,438,707,74,273,962,112,973,946,239,911,783,574,955,256,315,715,212,586,988,124,190,188,309,838,928,358,36,75,416,209,980,883,892,671,60,891,189,176,133,721,687,685,502,790,112,745,459,340,221,568,7,59,673,66,282,878,743,863,792,215,302,779,293,341,172,358,451,126,756,992,116,177,200,671,210,994,519,796,727,62,338,193,438,279,8,63,827,99,253,691,879,503,342,441,81,534,389,339,710,190,804,418,773,14,481,982,86,66,749,214,95,292,336,487,278,341,995,992,730,717,10,488,129,707,404,389,942,961,656,296,134,259,543,63,83,623,390,989,490,200,909,765,514,284,549,214,715,559,387,143,960,281,55,954,988,101,174,679,209,172,709,380,602,922,482,176,828,278,721,586,348,594,483,806,922,767,554,61,60,536,310,745,502,691,868,705,947,0,113,154,48,186,457,305,71,888,299,637,877,904,663,503,522,47,497,109,626,14,890,793,412,774,229,82,718,380,108,574,86,803,10,539,535,907,270,568,574,467,764,570,926,652,866,808,115,781,23,322,876,890,628,723,247,625,418,635,540,956,29,822,983,551,120,290,938,421,226,487,959,293,679,837,507,313,586,107,582,257,875,132,345,932,399,395,129,289,740,512,825,364,219,817,221,646,657,265,658,16,927,940,756,306,975,143,943,971,586,561,990,380,511,386,705,390,196,590,318,410,224,970,541,589,617,600,389,889,486,35,953,506,567,933,29,495,2,652,854,860,512,547,47,369,381,606,770,553,991,444,826,979,209,546,766,321,429,151,982,643,667,67,391,515,585,37,102,611,616,45,222,656,172,283,514,201,394,583,41,551,697,841,163,443,192,868,826,886,719,947,680,597,967,761,838,955,672,553,661,159,504,950,321,193,769,235,264,941,172,996,433,799,8,762,948,33,845,127,746,837,574,372,773,28,248,149,261,711,144,231,762,309,70,919,718,901,581,279,43,113,306,731,145,733,294,351,924,530,886,339,287,189,707,618,297,854,965,51,285,718,223,807,711,123,260,616,602,252,698,196,685,566,949,422,896,988,55,568,901,536,186,144,696,550,599,682,104,743,921,218,955,194,900,579,416,70,957,387,919,306,231,585,666,680,231,560,807,141,338,799,112,183,544,178,381,369,70,629,916,456,129,447,975,350,46,609,256,88,883,846,650,322,215,108,775,775,986,406,842,8,931,999,926,493,764,707,226,717,36,751,792,81,675,628,744,657,643,393,850,628,568,874,292,280,543,430,866,106,692,705,668,763,918,160,946,782,965,659,693,564,904,547,80,401,761,481,245,871,169,216,230,935,194,694,812,116,576,460,333,203,666,203,279,750,629,893,867,457,924,618,93,248,923,47,177,991,238,977,285,467,970,84,634,526,394,226,363,775,746,28,884,850,593,95,304,503,577,663,652,707,332,146,430,597,310,961,383,570,306,175,206,796,484,534,945,707,408,713,614,787,923,609,969,859,168,684,356,238,271,236,712,614,279,434,192,450,877,587,793,863,963,986,358,39,773,271,408,633,914,387,526,461,214,580,29,77,978,169,82,426,638,244,884,193,203,274,877,237,38,482,909,622,797,759,960,897,881,476,471,277,913,990,348,168,539,502,615,178,126,75,89,437,587,26,203,113,470,824,890,647,956,913,403,944,604,335,925,644,692,461,56,634,466,23,766,714,96,124,947,243,336,459,315,992,350,498,758,459,673,975,59,941,490,772,829,684,315,695,918,386,495,809,766,795,548,644,708,634,640,194,427,273,972,49,497,331,872,213,250", "546,646,738,837,982,502,897,829,132,624,563,716,914,824,300,217,675,325,54,32,982,948,496,32,766,793,352,979,924,222,445,186,941,712,809,922,35,154,200,611,660,933,445,236,303,988,437,925,14,952,498,143,934,104,382,696,96,592,430,473,905,349,377,208,930,938,95,718,439,26,192,724,493,578,861,719,195,826,936,654,667,745,317,778,696,168,44,287,717,339,530,63,508,291,17,894,330,181,63,25,857,354,880,461,20,832,751,245,152,680,859,204,61,119,973,636,298,463,526,696,760,625,191,396,724,172,830,461,246,243,624,202,181,360,407,846,143,4,807,812,368,357,658,901,69,591,142,612,248,332,931,551,413,388,815,232,203,533,536,35,760,713,825,53,104,142,91,383,750,685,294,695,691,784,191,645,702,244,500,836,88,872,620,770,894,939,796,868,417,665,488,910,812,103,275,364,952,796,450,152,636,905,218,179,923,694,744,645,763,663,516,630,310,893,467,753,351,836,226,310,182,871,52,353,691,420,961,481,402,295,206,410,945,210,846,750,393,420,647,405,902,110,242,254,875,342,753,485,132,697,327,891,230,732,37,72,480,651,258,270,954,827,844,451,346,189,954,525,663,90,750,44,857,327,461,699,192,654,234,336,416,873,723,948,288,933,407,242,563,62,121,296,581,193,134,363,49,723,4,803,498,247,492,881,349,63,114,338,154,525,865,178,569,493,647,824,305,336,842,46,540,248,179,688,405,908,438,80,814,984,702,548,243,208,717,871,275,815,891,708,265,502,662,113,673,822,969,898,924,622,844,302,862,62,994,206,565,979,469,610,83,302,211,582,298,840,904,166,816,912,862,832,685,212,672,449,360,555,483,866,625,214,545,941,610,705,929,585,103,331,87,646,750,848,155,438,22,133,565,219,113,0,868,971,864,425,483,979,260,76,245,122,772,940,796,381,255,117,371,731,935,875,835,795,448,350,505,440,771,712,764,613,518,948,508,670,5,357,257,272,422,390,313,14,707,946,187,894,879,153,459,249,544,39,44,169,546,664,898,489,73,970,73,506,419,689,791,258,21,568,260,232,546,164,931,449,547,767,95,575,698,106,781,963,519,437,522,360,760,744,407,2,396,83,87,113,185,371,731,517,200,208,925,392,32,816,851,174,131,971,47,371,104,802,225,918,545,840,351,401,820,453,587,499,21,850,22,473,287,955,441,92,730,975,553,906,958,801,47,973,673,383,872,115,916,73,564,847,528,92,195,24,428,727,318,968,376,959,282,234,617,435,113,179,850,573,618,438,871,723,526,99,335,493,532,566,716,962,210,527,758,39,741,985,608,9,475,550,943,484,115,353,45,737,902,512,609,375,655,692,225,742,107,63,154,708,528,509,92,929,631,824,938,343,735,970,388,932,385,860,561,240,258,553,168,688,690,515,349,414,854,444,329,602,309,959,584,806,116,303,623,517,859,175,380,972,735,22,958,827,260,876,628,491,799,487,900,286,164,438,128,266,531,333,553,777,561,691,825,780,220,827,3,70,509,361,196,914,279,795,682,187,516,352,228,942,897,839,23,297,935,117,697,205,843,759,311,613,264,716,200,823,258,770,325,526,370,65,543,411,763,613,716,273,751,438,249,384,8,604,176,690,831,772,90,717,310,849,773,905,559,116,866,116,134,217,729,990,625,104,390,909,125,130,62,955,745,928,805,830,246,721,44,194,414,815,377,155,25,304,559,570,91,456,834,421,915,893,51,540,844,519,709,487,7,512,236,525,217,214,68,270,168,134,611,161,437,346,122,418,843,25,329,176,474,414,948,263,489,726,186,439,686,97,280,514,959,743,166,769,956,270,620,319,795,263,141,483,711,970,140,930,316,942,927,838,669,193,680,273,901,379,598,984,533,32,11,120,581,353,112,242,611,621,327,11,611,785,323,548,716,857,592,100,295,511,560,133,581,593,691,994,155,899,522,569,655,891,423,53,531,182,259,172,340,329,270,30,969,449,280,912,626,776,546,824,174,753,990,12,895,342,328,209,423,346,593,916,449,325,24,889,64,625,465,893,895,688,26,426,439,599,792,488,849,170,251,505,705,848,14,286,671,38,658,709,732,972,449,396,955,215,173,366,343,173,130,352,168,710,943,888,480,11,583,404,41,427,655,774,708,282,943,590,288,402,748,455,305,311,94,828,699,16,422,838,494,121,567,589,969,84,495,633,868,47,561,370,327,689,618,138,339,271,43,700,784,308,6,402,124,722,44,34,213,588,505,626,442,682", "891,46,131,838,221,645,604,145,970,833,851,975,587,204,880,375,884,149,626,710,153,654,653,949,85,394,767,125,460,255,462,188,559,312,368,41,270,977,591,735,62,219,483,627,641,910,550,273,46,396,709,976,803,410,345,660,594,389,109,186,808,133,99,260,57,295,353,462,291,690,476,844,334,781,622,971,827,861,996,356,546,912,14,961,746,393,791,105,993,106,723,75,404,811,46,61,254,660,157,33,319,346,421,187,189,132,527,837,368,391,489,51,155,366,743,871,502,624,428,488,626,811,382,111,959,368,48,554,467,695,296,762,854,983,892,382,281,987,156,652,258,462,948,814,447,801,807,206,453,583,155,654,796,872,651,424,682,379,285,94,376,400,987,409,435,848,263,12,281,997,697,542,570,105,539,348,316,9,147,1000,34,808,903,842,944,286,756,794,472,406,218,627,845,416,903,730,38,796,459,13,614,729,383,467,896,773,480,833,533,744,416,278,990,158,851,95,886,565,337,793,834,795,332,300,176,248,472,786,759,730,653,335,148,339,994,955,318,164,634,272,80,102,639,612,717,636,140,768,810,757,152,646,857,786,594,157,782,722,505,783,167,520,665,778,682,877,20,433,349,6,881,974,588,275,661,362,587,5,88,471,479,28,764,223,892,206,93,240,756,882,367,396,480,715,515,139,798,814,289,314,877,819,504,652,706,396,607,522,536,448,530,717,506,768,945,456,139,364,484,733,535,656,405,218,630,258,36,510,917,191,57,257,566,288,482,511,38,77,790,471,844,620,534,597,398,528,925,220,568,228,802,685,671,756,557,312,791,547,385,158,834,999,952,586,915,505,710,964,50,615,242,459,923,2,909,611,105,224,824,245,49,313,995,93,381,668,937,841,897,912,117,316,226,191,894,860,557,992,273,98,154,868,0,358,78,103,531,641,594,614,386,651,881,156,241,680,568,379,710,140,743,79,208,613,438,955,425,108,488,701,852,134,708,546,463,536,943,992,480,904,226,106,207,950,130,668,896,65,612,569,183,498,404,805,674,510,642,962,878,882,263,581,186,777,578,65,408,975,56,424,106,87,223,875,916,617,305,359,643,203,213,307,973,519,98,503,673,239,638,169,613,240,484,636,643,698,706,90,88,164,903,18,945,40,733,589,842,193,324,172,94,210,866,46,330,991,793,440,494,19,775,509,854,442,874,654,196,949,467,725,833,22,231,710,103,215,165,627,848,906,670,442,793,145,170,127,292,558,403,646,601,180,775,137,816,575,589,586,617,133,432,507,51,325,457,641,359,469,359,538,989,720,79,663,941,861,712,316,323,231,652,41,396,389,639,414,574,352,430,57,891,842,351,328,873,84,323,801,404,41,63,208,754,335,785,878,233,774,361,866,615,417,662,726,106,217,1,832,962,284,927,909,407,214,520,848,756,924,774,128,143,231,390,752,338,118,402,511,103,422,594,308,869,738,355,462,67,132,581,277,115,675,988,510,974,626,548,153,825,395,637,376,642,910,946,357,788,902,97,852,513,761,623,951,256,901,989,140,648,600,392,132,519,82,229,208,996,130,320,411,187,335,894,299,447,424,187,135,751,410,802,50,904,336,732,9,203,31,192,815,71,465,547,679,660,770,919,666,634,81,206,719,90,288,729,575,905,389,388,530,777,746,336,11,505,178,638,428,717,607,329,711,724,79,977,937,696,994,440,896,113,17,210,435,163,575,470,168,726,638,651,777,669,547,748,594,278,346,388,408,641,207,589,971,434,573,925,767,905,680,76,245,996,743,877,271,291,651,226,911,8,895,974,298,804,3,336,468,633,373,916,597,356,69,47,676,913,138,246,479,997,881,497,21,201,111,150,111,33,532,899,5,150,824,31,662,437,11,78,127,626,345,481,493,744,272,381,13,833,141,456,882,296,434,542,517,931,214,929,918,127,692,451,854,756,840,886,14,177,466,659,516,615,615,381,443,906,406,597,116,470,615,861,4,661,896,772,623,934,634,678,955,919,80,209,889,894,968,530,64,263,404,618,290,257,306,87,444,952,77,687,104,267,153,765,791,44,682,805,949,972,667,711,209,366,828,983,485,201,632,955,467,620,926,938,885,840,117,712,737,138,960,2,551,463,253,960,862,78,675,951,32,993,165,740,14,328,354,23,878,98,111,918,842,410,181,644,384,871,48,565,904,394,127,696,416,41,615,548,902,797,659,98,618,432,44,454,691,950,423,167,132,671,81,700,691,580,263,758,32,173,147,648,497,394,115,386,598,959,522", "223,482,601,4,565,815,11,68,341,83,835,987,155,114,65,929,783,884,712,603,933,264,803,567,402,593,383,399,446,419,491,450,775,276,320,962,509,833,750,939,17,648,273,168,63,802,796,100,453,963,154,120,963,562,970,590,166,835,948,569,116,352,549,749,505,438,967,626,444,827,315,504,81,990,977,42,806,576,595,714,686,422,43,920,517,722,2,737,509,197,394,752,990,70,313,163,113,300,263,592,995,311,402,438,838,993,628,798,328,398,5,647,621,269,264,907,633,969,193,393,861,64,176,556,608,661,893,703,242,14,307,441,490,373,899,618,158,324,126,807,467,428,303,426,730,157,677,893,667,536,588,679,185,138,688,977,587,288,582,113,986,167,489,59,517,250,12,845,100,47,426,993,14,779,950,695,517,263,45,85,762,219,793,826,942,398,819,459,157,260,701,867,319,190,55,825,170,29,401,730,63,873,346,20,889,665,607,59,606,574,745,232,576,815,708,880,476,38,143,729,252,932,688,314,115,214,57,148,646,572,436,933,625,740,645,168,916,234,565,471,877,890,697,678,453,697,673,979,911,916,334,730,57,705,144,792,338,469,6,395,793,983,198,595,540,553,768,642,352,118,463,498,243,162,582,654,925,873,292,675,800,747,565,320,606,123,699,60,54,586,124,409,255,943,720,79,646,897,854,751,704,386,269,835,721,78,748,768,280,539,389,673,68,565,761,696,495,546,457,375,599,997,154,994,362,818,749,294,664,405,642,531,481,966,483,650,301,212,495,202,837,278,119,128,608,182,599,175,558,841,248,440,546,512,124,471,587,940,952,940,652,15,912,964,801,654,165,932,259,831,297,748,98,59,986,686,111,481,211,262,374,810,344,782,362,555,16,437,400,664,25,340,364,514,941,319,468,252,418,717,48,971,358,0,457,60,891,658,957,358,743,474,913,296,690,870,795,995,416,920,592,298,774,592,907,344,911,324,201,914,828,490,636,557,567,509,107,492,144,630,88,375,576,785,508,302,359,855,682,917,8,989,303,857,838,758,148,674,827,104,950,535,664,768,672,113,900,338,72,444,964,655,40,637,424,339,55,957,733,345,354,624,982,845,552,99,274,225,348,67,793,460,304,309,622,845,984,119,173,668,727,90,936,935,3,676,162,79,517,932,505,575,312,809,78,859,668,647,594,249,298,720,186,6,639,267,452,904,637,276,533,95,596,785,881,602,141,496,16,220,663,629,595,608,223,725,201,149,120,22,711,262,336,178,334,103,342,415,469,602,348,419,272,296,314,561,558,871,189,98,6,890,777,897,242,878,736,271,50,736,877,63,511,649,504,38,122,83,777,286,333,809,14,962,204,438,926,594,726,481,917,785,855,373,108,751,336,571,503,257,377,870,117,4,783,450,529,211,233,369,902,885,677,878,627,784,363,215,362,481,638,846,474,153,50,221,827,591,611,316,251,418,917,813,727,932,532,155,206,67,338,148,344,357,53,261,848,459,800,224,570,470,780,719,92,723,594,10,546,701,308,519,668,841,615,645,71,926,76,377,558,579,37,138,588,207,840,294,939,25,809,961,964,552,69,384,520,893,169,680,430,426,655,898,707,935,89,527,303,955,994,112,940,17,60,960,467,520,602,905,483,387,202,208,7,663,3,838,309,879,140,591,442,937,467,530,888,299,88,158,29,238,32,750,344,37,598,691,775,833,398,213,180,866,51,914,228,323,135,643,629,960,185,97,936,210,544,600,346,850,911,245,64,566,444,209,839,20,727,400,808,927,471,521,262,975,983,905,252,418,727,853,297,304,251,595,650,311,407,241,988,324,825,717,60,727,78,796,826,821,667,67,815,301,636,38,46,939,82,259,135,469,973,811,927,188,946,8,617,348,221,423,928,613,598,690,110,604,757,204,195,730,785,701,985,195,250,141,823,194,587,83,975,628,742,257,484,731,972,491,842,579,450,41,631,66,51,227,277,290,353,690,236,371,259,789,750,107,283,467,237,62,66,246,650,327,950,339,180,75,841,769,909,51,102,654,470,242,484,98,526,82,347,101,118,311,478,153,196,200,280,789,924,847,690,519,872,728,902,266,929,895,586,948,984,538,967,759,340,562,352,659,741,880,551,669,825,196,923,988,12,160,6,120,493,152,884,956,959,301,529,187,128,524,675,811,386,331,762,471,667,300,245,680,773,245,173,401,262,171,120,923,880,488,379,810,233,651,874,649,492,986,798,231,750,801,248,225,214,818,753,427,11,982,964,77,246,403,593,953", "476,479,827,777,799,611,965,911,732,911,224,366,479,723,203,469,723,459,646,914,356,884,352,643,262,536,351,541,130,823,705,533,933,593,29,48,112,977,748,365,569,321,693,188,765,529,244,6,825,806,550,844,887,301,320,61,104,428,505,98,450,184,864,563,784,652,792,947,835,401,116,488,67,638,809,650,374,718,349,543,63,379,209,147,191,434,528,445,736,673,100,355,155,123,892,676,474,39,550,789,193,404,515,100,63,401,935,926,259,358,886,703,358,872,609,237,377,678,848,903,77,450,746,237,450,634,252,813,644,889,942,855,258,94,653,870,779,854,171,652,309,788,824,120,284,971,126,217,737,444,738,109,20,214,951,343,22,501,548,839,968,175,350,592,299,659,496,678,982,598,224,656,358,223,523,660,332,860,837,155,170,339,975,959,200,446,578,287,30,851,51,646,74,783,12,444,102,243,225,515,68,859,852,644,631,346,15,899,328,812,82,676,455,496,47,667,441,718,242,706,16,170,112,853,195,786,853,842,539,532,984,91,894,329,11,541,935,27,241,295,51,629,165,640,374,472,896,870,278,841,875,774,20,30,852,560,678,623,456,858,248,899,748,954,618,943,957,681,500,57,570,753,599,2,476,603,919,434,461,142,91,593,510,573,269,398,521,548,514,776,94,407,59,603,360,910,797,177,585,470,140,322,209,551,245,874,412,276,929,144,462,433,974,315,66,95,362,853,398,904,154,707,216,17,245,618,915,899,549,426,712,227,159,753,696,592,80,364,201,118,806,819,188,672,636,772,271,435,688,802,642,64,320,169,681,959,288,607,79,957,167,798,535,518,864,449,713,255,370,156,75,117,458,563,950,955,423,599,131,992,777,93,230,303,20,962,161,823,229,488,786,963,692,457,174,892,403,68,734,10,186,864,78,457,0,524,653,992,330,570,992,356,125,866,360,692,121,912,924,372,476,540,780,454,207,66,819,590,714,921,337,475,190,559,290,641,273,223,390,263,42,865,385,133,878,649,694,397,600,803,428,580,529,150,959,845,385,69,803,858,897,88,495,904,479,393,792,746,348,734,107,377,971,305,353,831,571,292,882,927,797,400,591,865,227,463,297,454,586,52,272,652,704,38,611,698,263,567,673,29,618,732,114,975,520,641,827,786,66,996,515,59,424,617,693,690,658,294,817,646,369,897,698,442,74,17,756,647,536,727,486,786,596,515,889,65,486,453,541,594,79,429,861,810,44,591,114,233,899,686,15,153,930,590,763,218,513,458,748,393,687,978,504,786,938,970,644,639,13,438,881,638,361,304,714,538,535,908,853,75,140,791,753,117,450,796,480,272,867,915,567,721,312,944,775,799,358,296,135,761,928,970,537,400,667,179,741,865,3,967,392,144,739,515,583,660,76,810,259,850,974,753,182,421,267,782,288,226,364,354,719,477,40,371,199,428,556,524,565,602,426,608,212,460,960,740,176,564,479,287,794,353,994,569,459,88,60,178,352,178,703,266,556,291,720,328,708,826,782,638,861,945,986,63,113,287,839,846,992,10,217,531,530,474,823,42,165,733,276,164,585,458,189,790,363,890,758,286,535,325,89,257,184,23,254,705,265,317,61,819,925,207,468,184,459,143,85,287,696,348,876,192,849,632,846,565,272,658,819,704,514,653,334,287,118,808,683,515,956,286,195,469,435,827,551,212,563,895,579,789,442,408,1,93,595,614,482,892,141,621,959,117,942,700,8,931,248,469,740,666,503,719,784,936,906,504,418,588,655,784,786,594,317,844,157,415,246,614,641,824,367,875,488,638,467,84,999,683,16,629,60,625,818,19,942,275,451,466,777,229,732,298,269,864,87,979,902,395,317,218,264,839,596,907,966,721,881,679,955,629,904,962,299,440,452,803,409,518,60,370,123,731,30,888,111,287,820,701,981,66,505,587,300,655,305,110,947,61,780,809,211,472,657,833,296,162,191,390,213,183,734,429,164,468,205,630,401,549,332,632,922,75,99,755,175,851,455,558,428,712,465,907,190,248,434,123,227,27,471,272,978,432,959,590,330,851,187,417,367,686,171,712,130,185,194,955,734,860,769,53,157,929,677,330,926,881,291,394,438,42,124,121,848,916,773,216,574,481,887,295,327,136,205,385,180,27,498,773,195,621,588,726,31,597,952,705,61,564,699,514,38,216,415,142,737,102,812,161,463,696,518,262,637,100,22,141,391,253,71,658,650,784,321,548,464,685,223,198,805,515,709,267,76,753,73,15,682,685,136,408", "937,588,22,300,161,696,945,884,562,305,150,742,670,863,902,709,540,802,59,629,460,225,38,87,535,591,102,887,107,944,113,194,469,616,921,447,347,973,211,474,741,415,331,246,167,834,289,815,69,553,824,326,849,679,771,196,28,127,973,590,676,583,838,590,213,458,456,942,364,236,273,817,462,607,99,994,645,375,119,116,899,318,859,537,271,693,738,459,50,413,152,70,144,16,140,839,14,572,522,394,554,268,30,627,523,322,292,851,932,95,775,376,188,635,144,554,342,750,935,731,659,279,801,403,973,590,76,819,543,392,106,389,15,197,632,566,119,118,732,624,89,912,816,530,440,130,536,399,294,220,674,847,750,725,555,877,689,178,564,149,428,595,745,303,304,775,57,887,106,863,344,385,930,44,960,846,957,670,659,144,389,985,696,282,490,294,219,328,829,684,308,134,998,506,459,367,486,268,495,516,963,423,375,682,860,821,78,623,642,670,368,273,511,337,78,998,262,954,50,836,164,882,996,987,601,720,501,863,640,291,273,204,481,15,16,790,33,535,420,679,399,359,966,346,921,866,777,761,504,60,427,884,149,456,326,777,230,345,897,719,354,649,15,454,288,421,609,74,736,124,803,203,292,280,563,974,645,247,520,478,771,966,993,37,630,478,662,995,91,293,492,356,142,311,220,330,331,597,760,352,96,497,992,437,596,60,653,959,476,926,583,713,189,818,459,878,527,189,513,436,101,898,446,302,797,894,948,253,548,778,588,235,113,962,826,819,956,901,817,586,362,990,595,455,256,685,816,375,108,857,265,831,36,471,667,886,549,122,966,550,695,602,644,701,226,100,371,791,441,594,66,280,579,886,72,993,605,359,250,163,572,854,374,293,672,370,151,430,291,604,773,288,299,746,842,280,991,771,243,807,457,425,103,60,524,0,486,199,405,424,571,9,128,198,124,346,421,795,859,395,248,462,247,889,805,790,263,401,38,326,824,450,910,78,273,16,594,846,583,709,802,542,485,201,950,802,862,642,428,772,648,626,850,306,427,779,102,961,608,559,320,237,298,974,113,454,280,533,109,419,524,947,644,279,286,197,22,349,497,649,512,20,984,247,331,698,850,205,714,192,691,148,652,706,250,650,361,927,285,540,742,201,93,418,790,726,876,469,618,416,312,276,778,261,410,441,137,854,965,624,736,73,110,656,604,857,652,999,858,908,997,367,890,806,828,605,228,521,460,297,486,961,65,276,662,520,214,555,737,929,611,638,44,699,509,124,65,801,419,298,808,889,368,175,956,58,357,728,927,295,790,639,803,996,196,640,569,109,381,37,279,70,732,44,612,15,703,107,876,357,772,10,300,905,547,977,123,288,7,552,799,611,41,655,133,509,40,414,939,152,809,534,743,138,931,646,988,392,829,245,883,907,254,170,482,861,749,889,316,812,538,405,195,620,859,177,216,34,950,471,409,579,319,516,55,377,182,356,798,203,191,236,494,863,473,790,111,816,486,988,849,106,968,391,478,1,480,294,577,960,655,695,581,255,674,185,319,214,147,157,526,687,66,104,957,108,266,853,152,583,832,808,647,823,89,227,324,660,667,297,44,292,724,177,518,786,896,486,542,736,57,474,286,871,939,609,475,680,526,536,914,566,510,776,205,930,726,422,418,501,397,184,189,548,901,539,446,571,762,98,966,439,706,826,630,149,108,993,993,323,616,455,835,803,465,103,683,295,183,337,642,48,671,39,274,294,270,487,164,690,206,461,390,660,238,69,944,15,685,249,710,404,755,865,17,392,486,598,110,199,767,630,676,899,397,336,491,69,198,797,81,528,494,253,196,461,628,317,527,590,753,411,551,305,921,695,428,590,880,239,169,188,741,182,476,824,137,967,541,339,319,974,957,666,573,638,230,106,23,8,717,362,248,960,278,145,133,854,968,271,934,597,281,985,409,567,82,481,110,18,416,244,417,286,514,858,811,608,5,301,260,5,384,784,21,296,453,676,323,149,770,871,353,164,600,47,429,388,99,366,466,850,371,651,314,415,464,883,210,173,988,550,327,819,726,411,918,191,336,968,341,909,133,975,267,125,682,514,900,514,938,921,778,765,608,799,385,668,971,396,859,356,207,985,450,994,508,114,594,986,138,815,132,924,780,877,359,274,81,654,321,828,809,52,754,575,513,133,763,899,78,810,868,862,18,309,936,103,763,700,110,467,392,981,292,565,130,79,586,604,428,989,987,148,742,617,677,475,918,422,656,28,387,578,16,302,439,295,896,199", "669,596,448,30,557,310,709,352,314,280,552,145,998,320,949,335,989,915,401,698,483,529,886,133,412,182,679,802,874,226,857,711,391,264,721,918,174,255,678,677,710,95,486,791,790,831,355,282,892,247,166,720,127,840,342,722,692,183,918,143,873,543,69,361,735,891,924,785,447,251,22,336,615,458,323,26,343,149,762,193,803,396,502,804,388,149,197,314,783,69,610,713,900,630,614,37,67,71,542,326,829,564,261,280,594,279,927,446,364,636,471,348,331,591,579,33,151,867,770,547,667,936,105,545,7,820,134,533,686,804,552,867,142,337,728,904,407,896,342,118,786,570,202,172,849,410,538,976,241,891,876,257,656,454,881,609,62,352,862,508,664,622,270,737,861,931,498,161,637,548,376,844,117,945,372,88,943,701,882,339,481,240,568,44,282,351,311,449,788,405,68,151,771,155,493,634,76,983,603,840,329,726,589,95,78,489,367,456,994,964,155,193,862,916,577,59,578,614,798,646,729,469,862,677,204,788,659,917,891,779,873,615,162,329,385,982,608,913,347,899,648,629,459,834,855,673,616,21,887,530,905,662,894,596,656,675,951,519,868,885,691,468,164,997,151,522,26,785,892,727,903,171,9,894,565,523,853,978,396,188,393,300,6,381,374,281,760,87,225,813,404,968,500,404,23,29,81,361,660,83,861,113,531,561,3,145,283,181,761,518,572,772,182,135,470,558,187,980,992,567,69,30,895,226,527,647,856,661,662,168,14,287,850,296,942,700,889,117,10,585,999,795,663,375,544,356,393,116,828,106,44,418,938,762,684,50,400,693,446,202,622,196,90,581,85,870,648,618,744,25,746,280,619,50,913,594,527,630,303,316,488,87,228,333,547,587,82,215,899,871,225,897,33,815,982,4,646,698,239,619,305,483,531,891,653,486,0,171,653,234,671,931,399,665,408,872,854,888,67,347,963,345,424,169,949,17,234,788,971,368,669,995,2,273,782,31,614,757,189,454,416,522,295,538,285,124,126,918,199,432,808,914,241,506,33,278,269,299,388,838,214,289,877,312,520,784,955,827,701,721,821,311,788,23,306,521,59,397,399,183,911,98,903,754,951,284,97,314,834,742,701,160,218,850,365,389,705,824,2,114,931,916,737,3,931,327,46,509,673,275,99,998,309,575,973,162,310,122,737,138,512,886,120,285,926,418,642,535,238,447,655,235,505,961,942,472,884,973,418,756,729,302,122,593,562,894,734,60,583,165,948,12,293,111,491,807,666,960,212,342,995,95,258,746,324,63,705,899,663,81,665,179,918,246,924,236,33,921,774,748,509,817,908,726,701,259,992,802,639,191,249,125,834,298,134,812,883,530,689,251,107,313,632,986,198,941,306,562,438,632,779,114,522,625,879,952,936,669,598,924,278,298,620,871,867,225,703,926,937,263,881,337,857,247,398,65,919,772,396,756,683,846,529,360,956,33,771,286,147,436,390,48,692,507,28,915,395,141,66,302,404,716,75,443,666,675,598,947,145,504,527,944,887,891,927,46,121,407,214,634,50,278,371,708,69,42,195,680,98,591,577,810,872,545,378,507,955,446,160,60,337,951,616,658,645,582,153,358,929,407,318,336,988,22,872,507,506,498,830,72,899,437,305,929,672,464,668,350,85,259,545,78,60,731,472,733,84,952,83,785,185,643,281,403,343,149,520,759,905,513,553,757,471,138,420,540,62,830,808,737,467,822,793,628,27,91,628,867,424,480,962,288,597,152,612,449,720,697,992,97,145,363,967,663,4,223,273,941,569,401,673,35,498,640,387,730,42,665,789,497,21,881,450,89,944,964,353,310,665,578,64,981,335,981,65,425,518,373,126,607,439,433,706,790,72,918,539,867,264,220,33,563,694,366,838,603,382,341,801,756,387,836,242,945,921,336,362,353,827,161,123,574,234,576,227,498,369,41,304,448,494,966,272,742,791,842,244,556,482,496,989,569,465,109,685,301,197,542,706,506,402,66,476,488,973,31,444,461,584,555,818,776,876,418,973,497,751,615,559,513,454,674,991,781,395,267,844,7,980,765,30,589,1000,500,732,196,895,873,884,842,487,936,851,661,808,83,899,100,752,221,195,148,537,948,360,918,408,742,967,888,906,268,186,309,965,805,657,139,992,82,40,191,702,294,27,864,790,896,681,111,508,484,793,163,901,192,537,499,280,223,787,701,939,980,956,252,76,811,320,179,230,447,436,405,302,447,735,56,423,581,241,813,279,931,681,895,365,234,326,189", "938,263,216,78,185,328,705,766,607,247,634,838,468,934,389,187,954,917,499,252,509,154,295,811,31,682,635,77,360,74,518,371,388,7,470,786,799,786,625,730,158,210,615,697,488,833,556,175,414,724,89,365,288,271,961,718,365,186,437,912,258,936,104,142,707,900,364,921,719,691,876,959,869,322,678,374,812,773,671,390,730,442,220,842,689,103,438,824,562,149,132,902,225,503,466,989,326,43,545,160,95,638,279,361,44,376,430,7,381,815,226,898,61,929,396,126,547,357,566,564,41,223,716,765,300,453,255,670,341,663,513,874,840,566,758,378,51,600,245,686,906,545,701,64,529,141,530,391,54,393,678,366,235,169,120,358,699,112,461,763,79,450,659,362,254,79,739,586,894,72,31,880,2,528,777,702,732,133,814,833,394,335,658,963,791,383,98,789,226,366,341,98,590,779,678,187,733,500,310,561,45,831,390,993,693,145,790,527,831,71,202,173,708,132,437,694,417,480,229,4,454,208,910,958,611,685,829,805,287,848,334,372,819,458,649,678,25,751,518,586,884,543,646,810,606,194,729,352,65,807,504,457,806,704,704,558,607,324,450,863,956,172,984,280,840,80,240,924,220,909,922,688,542,833,97,161,110,795,298,708,912,133,304,630,230,699,298,650,812,93,332,316,716,786,770,625,205,299,494,38,740,713,494,487,647,255,269,877,205,159,811,509,320,496,688,866,730,601,562,427,93,692,259,207,673,977,252,132,492,373,862,56,986,987,357,830,552,498,823,607,796,491,414,929,194,815,302,529,112,810,266,838,459,294,737,849,124,776,484,304,348,994,510,774,94,259,871,991,671,553,730,848,813,368,519,571,837,395,719,174,667,74,132,79,573,851,339,272,630,878,169,732,227,797,631,336,753,370,419,476,71,979,641,658,992,199,171,0,598,862,731,485,429,131,745,216,928,407,15,219,720,96,281,265,627,513,854,973,826,309,65,276,558,472,211,131,129,330,60,883,796,606,314,614,49,488,39,284,640,921,366,116,379,800,631,407,292,335,100,320,187,549,641,891,379,562,186,86,37,674,462,3,30,553,128,621,528,908,655,977,837,968,21,793,583,282,207,289,968,516,509,207,459,1,609,94,627,593,432,126,439,362,114,534,590,419,536,820,511,824,773,307,984,807,381,186,426,877,403,626,791,825,629,425,457,993,69,498,907,451,826,193,831,699,782,127,416,990,283,815,740,248,778,454,949,647,303,442,736,781,563,226,879,441,771,832,491,434,442,391,167,122,680,387,891,772,125,490,503,320,924,433,736,351,740,184,52,454,217,160,914,164,24,121,351,12,625,149,312,21,227,75,494,834,682,477,397,672,17,125,821,169,531,293,881,371,982,857,818,182,749,477,634,161,57,122,274,619,385,946,957,200,501,856,23,749,711,206,155,875,992,897,375,552,647,334,631,817,489,216,531,492,176,551,52,879,863,206,369,747,428,721,616,521,542,11,831,334,437,12,849,678,763,54,678,158,76,927,166,388,275,156,253,553,960,916,940,893,250,45,691,929,116,495,155,762,293,353,884,120,188,606,169,264,514,595,602,455,789,452,814,348,428,59,523,82,313,288,6,570,532,137,523,179,369,46,756,864,37,411,783,891,999,4,211,304,190,961,160,819,277,30,331,789,78,454,985,758,964,890,882,369,798,974,274,518,369,688,404,213,554,532,184,524,376,653,993,802,772,218,346,257,603,829,742,334,904,371,554,745,210,327,242,158,664,754,223,14,180,312,807,950,651,338,419,322,841,789,484,178,482,89,35,632,379,432,656,351,470,855,773,966,446,813,760,74,850,178,915,783,407,548,560,157,425,171,226,807,984,860,516,18,535,854,230,631,878,114,956,940,282,591,192,331,385,412,126,424,562,994,744,477,239,329,762,190,895,334,150,244,729,767,683,966,712,78,500,883,148,198,396,344,144,698,583,943,349,243,740,522,994,310,351,490,71,264,49,713,917,673,770,381,708,440,492,111,724,980,453,820,460,859,293,933,427,678,658,275,864,688,312,225,639,524,689,304,862,251,837,154,253,746,574,686,785,202,615,440,905,626,927,9,418,346,531,402,71,192,103,924,505,330,146,613,594,393,51,622,133,53,689,114,307,195,580,76,854,820,389,573,112,205,655,753,717,966,328,383,734,952,80,30,4,247,477,520,607,495,504,746,646,153,404,444,126,750,134,864,30,449,281,99,898,79,835,908,627,82,488,843,757,937,798,666,708,856,950,591,873,127", "516,550,892,656,453,129,151,704,845,796,864,686,167,53,567,460,20,191,879,635,61,97,430,412,684,562,841,322,912,916,862,341,950,105,810,928,930,425,291,108,969,303,490,283,276,108,906,30,112,14,983,529,565,18,300,572,398,716,14,198,575,145,830,601,910,38,951,147,305,886,264,5,763,824,106,752,551,555,232,121,729,899,89,280,370,455,457,357,81,327,517,417,301,474,138,643,69,603,149,151,165,751,407,970,923,166,5,615,572,366,363,700,403,347,97,262,120,80,716,821,194,229,163,649,998,344,463,716,480,795,753,349,974,644,855,54,616,613,467,44,227,935,495,707,547,1000,222,159,799,720,845,392,186,693,6,475,463,82,950,462,898,755,384,419,569,865,705,502,344,44,349,642,304,205,410,715,388,953,462,147,234,812,75,931,447,55,360,743,55,708,840,352,951,123,267,157,570,50,895,271,968,183,239,417,159,817,767,897,631,293,212,372,49,661,207,730,318,746,879,132,650,734,610,653,84,33,215,859,41,880,889,783,796,385,218,747,594,484,888,932,28,852,551,461,896,251,167,536,525,719,418,560,143,371,356,185,405,988,367,319,847,110,777,938,745,335,607,184,991,404,218,243,505,845,941,76,817,355,166,308,552,942,422,729,306,427,898,70,614,104,226,875,376,65,104,949,753,167,698,917,41,852,306,37,158,265,198,830,798,581,804,112,527,724,219,949,65,642,140,99,82,603,199,996,85,239,579,653,157,721,997,312,759,558,869,556,747,92,114,612,809,577,484,537,895,87,31,789,801,825,598,293,559,595,939,14,117,368,829,497,377,296,244,136,895,519,268,631,44,852,363,751,417,92,582,245,132,402,617,253,108,760,49,921,642,263,671,501,40,187,366,743,730,627,576,62,658,323,610,967,888,260,594,957,330,405,653,598,0,154,543,493,439,173,32,159,173,536,445,517,764,951,463,258,822,80,623,566,235,217,767,202,761,172,893,685,503,316,4,38,609,662,116,531,474,389,51,350,352,951,400,436,308,473,279,648,199,989,226,303,251,353,887,169,77,488,374,949,1000,739,636,170,739,476,478,540,556,820,67,709,289,434,968,11,773,454,105,966,432,386,857,277,212,414,28,109,273,872,564,894,950,528,852,457,185,165,764,112,839,473,502,99,118,848,349,50,864,536,309,848,153,731,535,125,514,756,969,977,419,893,924,986,282,120,363,202,272,907,879,265,589,399,199,243,950,990,62,298,1000,412,228,904,950,558,137,454,969,792,678,741,505,125,59,644,154,355,96,365,925,799,887,682,702,646,176,173,907,830,696,997,393,542,149,115,438,415,157,748,438,251,616,417,642,460,135,927,822,397,806,89,477,175,311,973,168,142,654,920,924,833,372,347,967,319,258,765,532,259,12,390,364,958,917,224,333,642,814,234,56,988,864,409,822,666,744,333,890,780,542,515,978,573,670,354,386,887,523,77,917,105,712,29,949,725,174,563,253,105,779,309,11,707,515,82,805,526,243,910,37,353,797,751,167,159,149,285,838,982,915,608,518,358,728,238,641,210,850,678,648,485,859,920,231,533,201,438,273,240,590,669,146,86,478,157,959,855,175,422,280,162,551,489,818,321,526,294,200,105,867,980,919,86,888,622,931,949,760,298,124,664,770,524,329,432,776,487,773,571,416,230,557,884,278,144,257,137,95,320,749,991,871,442,770,428,437,790,956,114,246,143,976,670,621,102,211,472,788,249,823,304,241,43,868,996,651,506,207,67,204,87,543,15,194,156,438,622,284,369,408,941,963,740,907,179,706,591,105,331,966,873,3,362,247,862,255,677,308,787,997,341,820,232,830,214,322,977,635,926,572,592,509,777,853,589,81,53,152,257,841,374,113,186,958,879,100,843,758,351,438,163,809,24,193,213,628,441,879,507,593,875,386,278,966,48,422,597,822,442,272,437,391,824,238,454,811,198,200,237,821,765,696,951,946,14,175,857,263,346,981,678,286,532,982,600,571,475,745,767,91,897,24,478,716,801,688,730,606,475,421,34,681,818,445,732,785,652,133,582,948,257,540,235,820,509,973,519,177,774,197,240,233,396,114,449,129,145,670,390,526,985,695,3,472,404,437,978,712,280,253,914,181,98,608,592,659,584,60,126,255,700,584,59,917,719,494,858,688,239,793,413,579,492,393,315,34,981,637,793,316,67,820,970,237,977,67,880,240,295,70,526,949,437,930,96,425,313,557,440,439,422,365,764,155,341,279,85,536,32,51,477", "247,902,617,867,164,186,240,419,84,112,437,651,486,455,438,52,481,113,893,852,969,880,155,330,982,769,199,601,84,916,349,715,924,844,240,451,62,946,819,639,863,552,508,945,414,560,173,839,815,59,431,93,456,386,954,116,943,645,982,15,687,71,409,256,915,702,619,932,833,987,492,10,597,862,609,2,613,44,54,219,47,696,634,646,1000,328,350,291,921,745,428,147,894,698,576,779,334,322,598,214,296,141,876,989,30,589,793,546,522,659,609,755,318,628,238,762,253,32,410,292,14,201,820,172,959,160,175,145,983,156,910,923,211,470,778,934,959,55,381,816,157,304,530,256,712,99,141,619,816,111,548,159,380,607,796,895,978,385,71,379,979,816,410,14,436,287,261,695,221,60,371,601,853,921,703,777,398,565,34,189,633,552,634,845,594,637,434,377,580,874,605,38,967,854,613,324,135,704,627,430,92,54,744,300,873,901,902,215,688,247,155,705,551,631,295,530,443,753,536,520,538,682,404,931,111,276,498,124,372,897,611,180,619,204,419,239,680,666,473,744,998,578,613,713,590,739,875,374,653,999,264,433,867,963,544,876,241,39,342,594,828,543,631,198,519,592,326,968,69,825,490,609,501,601,991,824,837,454,458,318,151,221,550,987,558,409,499,48,323,149,814,543,265,90,746,909,626,936,22,12,960,897,4,502,800,483,104,96,513,449,594,701,395,27,532,745,805,986,334,341,213,866,131,941,546,719,293,41,32,485,19,487,769,239,633,888,294,667,986,416,672,178,653,863,900,608,271,500,793,111,517,306,613,181,589,985,712,921,938,130,421,42,890,335,480,577,452,844,822,677,291,787,999,168,960,705,435,185,843,341,224,225,730,41,473,294,657,433,133,732,562,397,867,662,617,45,670,352,925,19,299,76,614,358,570,424,234,862,154,0,722,465,357,853,853,191,145,519,32,295,726,459,205,454,8,122,650,796,574,837,849,967,696,558,136,336,76,477,773,878,284,397,6,984,881,116,66,202,920,971,786,956,210,904,631,536,681,8,194,161,725,298,354,11,980,280,936,275,851,707,790,844,878,246,384,944,939,160,559,642,679,579,802,560,241,611,526,448,786,636,47,31,20,95,747,816,253,368,811,722,986,303,938,101,294,627,95,511,240,784,507,63,930,262,756,90,39,435,281,984,72,399,769,83,934,825,81,397,685,481,864,612,474,726,80,186,54,336,136,181,124,85,194,472,318,664,243,136,42,850,842,838,328,941,635,297,680,534,806,198,110,612,606,179,10,815,686,667,834,907,480,794,240,262,266,269,34,194,123,98,413,935,187,992,262,837,552,939,687,396,292,491,427,591,522,495,714,312,270,85,111,837,182,941,136,568,377,542,85,364,868,697,251,783,840,287,385,175,850,797,962,681,586,591,314,879,585,467,360,433,523,321,75,280,590,282,500,108,708,322,258,667,586,524,590,477,339,305,316,290,495,44,918,959,279,222,275,448,581,545,698,276,176,859,845,991,664,708,556,790,199,482,151,338,543,465,955,640,541,24,599,693,524,75,245,387,46,489,728,167,777,301,435,370,544,734,829,557,643,633,936,511,859,155,296,350,54,881,4,613,6,463,56,293,332,493,648,321,337,100,503,85,184,64,193,542,648,886,480,505,441,903,552,958,287,820,32,980,856,693,156,27,299,993,461,761,787,739,751,623,39,206,550,389,652,351,827,686,163,723,272,94,335,861,192,488,331,598,19,675,148,489,766,904,509,100,264,29,114,592,217,394,254,141,976,470,525,739,153,443,605,992,135,647,578,559,206,806,830,165,275,537,568,78,731,74,627,125,236,761,430,791,558,66,681,157,246,106,117,441,701,32,261,272,668,156,626,770,425,873,155,866,214,796,515,294,19,805,179,896,669,961,400,939,780,888,925,141,40,392,367,238,631,329,951,519,654,407,238,282,263,399,272,2,263,329,151,464,197,3,372,293,809,602,904,147,922,512,870,209,708,14,189,227,369,101,530,771,336,47,735,55,624,819,339,133,488,515,421,800,727,976,602,51,454,583,70,296,382,182,14,410,70,852,919,204,913,198,817,10,861,531,793,45,49,393,684,220,492,164,217,106,396,473,294,964,97,224,741,21,335,915,623,313,582,652,658,703,717,151,261,4,782,632,211,791,534,560,565,456,291,106,826,552,292,14,461,761,435,328,135,485,906,997,759,435,154,742,808,748,667,248,601,84,435,851,170,682,959,834,777,613,904,303,58,679,877,890,413,132", "668,261,622,583,931,275,772,589,235,742,954,383,40,505,268,500,303,208,101,137,992,129,826,525,673,886,677,550,286,343,328,927,763,959,944,630,963,432,892,944,979,215,607,285,873,317,208,512,101,549,911,900,92,559,709,665,116,96,566,382,404,698,376,811,163,895,973,621,59,497,690,892,408,727,895,447,48,965,411,207,351,39,210,502,998,149,178,130,743,710,588,520,642,851,883,728,218,970,108,879,968,226,740,875,277,431,517,509,906,508,558,358,460,139,324,405,760,209,273,226,905,7,291,240,281,646,203,467,51,877,100,405,782,741,311,762,34,146,874,847,652,245,705,980,414,661,688,394,736,823,256,267,777,355,505,17,482,152,657,518,991,753,631,416,915,295,732,29,179,903,568,115,432,94,194,900,310,228,695,43,275,383,263,192,143,263,375,957,575,777,271,359,99,198,654,947,261,36,204,499,288,318,336,577,882,68,263,954,597,524,415,489,629,491,432,574,520,471,882,302,432,82,702,439,400,358,109,335,361,828,865,833,858,788,648,205,984,866,814,133,970,204,952,949,878,352,37,44,627,670,133,958,787,648,390,475,200,416,767,893,286,177,809,477,964,435,941,328,232,103,427,234,683,272,807,279,169,209,172,315,698,990,210,494,177,168,97,517,266,298,110,28,501,764,764,104,755,214,465,805,716,173,873,292,733,114,320,804,849,451,309,352,151,635,131,94,269,701,825,534,236,424,597,184,702,528,113,869,633,438,324,155,297,671,563,85,248,237,728,724,887,215,497,889,793,671,522,946,40,547,256,177,442,713,242,872,895,404,714,723,205,91,940,322,561,524,234,715,856,236,86,726,71,171,291,9,582,25,59,164,142,463,461,228,31,276,350,789,590,27,237,807,733,204,837,723,742,864,325,690,637,245,386,743,992,571,671,731,543,722,0,928,65,615,117,52,798,82,413,389,722,301,771,363,880,118,393,342,993,49,400,232,978,199,387,156,886,12,186,291,908,371,830,951,729,741,32,617,213,461,585,818,474,237,26,136,145,639,589,420,363,94,527,629,879,894,326,646,642,491,112,599,733,108,58,86,919,215,410,788,306,942,461,494,867,90,680,770,197,420,258,799,61,840,982,942,432,689,430,373,918,704,898,357,425,376,67,788,365,501,359,95,382,196,175,439,802,249,477,78,621,921,635,216,372,465,113,884,400,889,123,858,51,512,278,920,832,2,538,786,143,634,460,900,97,606,608,551,909,624,238,853,637,116,824,619,785,711,256,946,758,706,774,487,190,638,299,692,625,384,261,946,155,927,1000,280,760,723,645,593,593,33,496,468,934,993,231,805,77,71,317,360,626,857,372,362,248,236,749,589,21,767,354,7,523,317,47,112,878,485,321,875,26,153,624,194,63,689,10,538,53,514,110,416,618,560,426,415,973,749,970,173,858,433,349,17,308,809,294,753,356,449,514,207,561,558,17,971,822,28,607,40,651,942,414,76,814,309,458,721,817,471,287,283,661,285,850,686,943,511,193,424,354,215,165,600,296,857,506,531,928,985,783,606,904,154,599,542,488,805,327,796,996,421,354,898,650,756,878,767,307,620,795,302,79,54,227,580,794,513,878,809,692,287,991,36,456,62,442,460,999,152,667,126,626,648,839,871,966,835,116,848,712,535,526,11,728,709,601,132,430,604,275,95,422,404,383,976,587,710,799,750,310,874,652,798,51,477,987,909,679,617,219,124,781,892,52,230,710,403,160,308,240,691,476,733,525,276,367,708,4,686,364,228,289,148,40,438,895,269,274,418,807,455,106,816,39,861,709,537,343,681,508,557,407,162,650,950,334,163,442,866,36,522,539,445,66,127,22,239,125,802,52,406,418,715,656,211,583,136,178,225,47,678,602,485,162,745,72,497,195,859,818,143,741,118,806,798,817,988,893,470,223,616,778,552,527,427,692,632,263,623,606,699,911,590,177,607,272,696,77,473,337,51,463,995,22,530,698,70,18,462,590,757,791,555,796,159,125,653,257,232,689,4,790,906,559,470,623,563,963,226,838,514,510,39,754,222,963,999,472,819,711,348,143,355,770,616,434,298,508,879,664,744,577,965,303,5,538,149,406,552,29,361,168,846,716,882,243,110,358,323,402,868,214,665,999,534,104,91,678,44,541,178,409,752,563,351,189,688,410,802,653,907,399,310,604,707,936,785,569,947,479,334,134,804,737,489,465,312,985,681,348,380,29,940,838,505,668,181,131,849,985,873,80,371,457,283,536,386", "751,326,39,57,35,164,682,351,645,398,164,400,974,933,946,895,625,488,434,352,315,543,594,137,78,953,882,81,33,118,550,767,283,106,232,483,558,169,797,833,315,991,254,472,389,917,782,806,837,942,522,601,112,861,213,216,103,693,196,543,277,966,681,567,896,748,205,596,620,993,525,351,99,373,119,452,161,665,234,635,842,9,698,982,597,596,663,11,636,152,770,556,328,19,520,881,157,653,827,546,102,672,626,119,363,545,698,469,274,110,919,735,680,92,920,979,860,57,84,925,932,305,360,569,610,402,816,406,840,675,810,808,135,362,181,368,912,415,632,732,898,951,495,631,96,960,80,17,767,113,388,110,868,772,724,398,977,503,552,656,996,343,943,946,371,800,438,624,528,103,590,945,373,867,409,829,728,810,87,666,8,501,854,792,219,331,578,412,327,218,841,812,548,860,21,2,452,300,239,771,487,624,212,433,847,437,979,635,35,553,487,799,409,105,868,295,43,190,616,936,937,593,227,542,465,229,713,811,968,190,626,458,868,594,245,696,133,343,508,410,43,105,539,183,407,949,428,780,500,450,289,304,771,986,699,880,230,981,280,610,548,669,248,436,8,227,553,934,499,746,282,777,857,847,412,427,556,362,823,102,338,672,447,858,335,269,306,309,697,964,713,632,445,928,830,79,246,912,419,201,942,423,54,915,802,576,668,87,674,71,696,300,680,342,802,622,381,569,999,838,213,118,615,131,505,791,23,96,152,21,738,27,31,439,781,133,866,749,349,762,512,597,388,123,349,313,856,892,218,395,22,881,618,964,130,584,549,8,618,149,27,799,76,257,178,388,983,723,946,11,883,237,285,246,827,217,774,858,693,374,871,320,117,486,572,685,617,222,546,719,873,865,977,835,575,163,478,569,222,779,877,122,651,474,356,9,931,485,493,465,928,0,917,662,304,900,677,307,183,742,570,952,284,63,7,885,830,474,550,768,662,802,451,505,865,853,961,210,242,775,831,820,366,762,952,445,600,152,551,365,239,385,302,431,456,604,222,543,273,222,236,80,75,672,177,591,484,913,633,715,659,804,950,194,889,318,523,543,842,276,424,882,41,256,765,703,146,801,627,993,883,132,554,460,318,346,524,723,479,90,431,831,892,851,993,392,937,631,314,571,471,173,403,584,322,41,388,132,543,180,547,825,12,999,622,270,786,693,192,49,889,234,120,741,51,997,86,522,390,444,73,717,740,704,992,616,981,217,240,160,106,877,691,153,424,323,371,392,544,696,319,141,723,670,464,87,673,256,972,997,346,159,630,688,486,90,765,95,222,277,724,732,959,362,630,468,246,61,775,959,743,404,43,242,882,215,731,741,469,591,805,52,160,828,266,310,656,497,128,997,619,248,655,402,454,73,928,798,338,274,917,334,173,320,281,360,160,905,360,382,279,739,813,553,809,284,508,833,374,507,24,458,145,980,466,481,95,63,807,403,427,928,220,573,512,448,810,478,949,137,313,71,788,226,170,110,232,227,868,693,347,28,724,308,144,39,9,994,882,504,718,462,781,781,876,858,35,583,869,897,794,371,128,161,259,167,76,335,973,239,717,442,710,517,302,894,980,267,261,383,912,446,725,131,438,222,251,547,368,452,932,116,465,203,178,892,124,930,244,531,799,464,989,577,467,721,744,988,717,309,145,65,829,466,135,271,217,457,950,893,360,473,332,838,512,557,331,743,676,24,667,475,505,637,665,486,791,372,820,203,214,718,922,708,141,817,124,220,468,63,117,760,762,740,891,455,104,395,41,828,752,866,211,125,790,694,602,445,347,729,676,114,342,640,593,132,326,560,415,218,739,705,357,574,680,565,192,103,816,610,651,331,893,378,842,839,766,758,151,815,722,220,907,602,458,65,501,98,145,362,391,534,224,807,641,672,989,469,933,951,755,593,965,236,473,268,650,999,790,462,313,516,59,841,933,886,758,271,704,508,106,429,843,264,525,322,408,69,190,287,852,879,81,250,988,888,823,265,546,64,426,840,915,105,119,461,75,595,898,246,399,458,191,963,706,996,729,69,621,106,638,868,580,484,533,608,714,186,136,538,134,594,571,647,205,722,602,804,362,677,612,472,636,879,806,847,73,911,688,259,212,485,520,832,340,404,322,169,63,13,283,968,931,934,596,303,265,859,428,913,987,52,846,204,927,12,640,260,677,448,176,485,822,525,295,538,340,135,334,471,536,798,506,460,664,120,263,794,426,325,254,391,418,939,638,308,885,734,781,648", "195,272,447,407,304,28,688,5,375,55,398,185,795,643,672,602,132,579,46,812,455,842,125,51,211,798,262,474,726,692,841,217,930,258,517,387,790,782,304,101,701,562,260,95,500,453,801,845,15,110,208,413,757,532,727,186,962,413,697,125,693,271,991,679,710,758,434,641,432,727,702,356,535,874,608,904,325,439,630,829,145,875,665,225,78,821,105,900,116,987,650,547,424,76,120,3,835,334,186,49,192,688,333,835,787,794,471,620,78,98,881,69,872,411,987,678,358,49,888,256,856,674,334,592,348,144,701,927,628,777,584,660,367,731,912,619,406,617,87,549,797,546,20,186,32,782,76,303,34,676,106,46,960,560,313,425,88,862,117,591,809,644,92,1,467,333,510,540,766,422,375,701,192,113,282,849,741,805,597,425,793,182,493,479,270,966,490,152,135,649,646,235,523,897,547,506,734,234,18,467,660,14,368,552,651,805,917,516,492,860,169,911,471,338,346,384,499,505,173,713,957,124,701,125,202,195,705,436,94,392,411,679,347,476,376,972,101,65,763,506,10,333,957,216,58,69,84,577,548,884,596,602,523,150,325,676,425,188,525,457,979,529,903,186,281,259,563,434,762,450,671,738,334,719,914,866,889,11,51,329,47,239,814,46,329,961,604,978,100,956,857,827,696,635,852,128,542,410,374,991,954,482,114,696,917,764,726,74,402,220,620,551,50,797,3,577,665,975,865,238,396,786,764,637,696,752,799,522,4,664,32,364,394,80,64,730,69,741,992,833,78,221,314,969,595,815,126,307,987,229,398,939,839,578,808,131,975,179,115,102,188,436,903,406,129,372,242,689,329,109,674,504,917,681,33,382,727,322,176,650,111,108,728,78,432,928,243,403,459,99,26,830,958,142,926,570,254,929,135,807,904,772,881,913,125,128,399,429,439,357,65,917,0,825,139,994,370,739,3,19,742,140,346,559,919,698,949,891,186,737,722,189,472,724,903,130,469,787,593,529,86,523,334,715,181,436,349,916,220,751,784,196,834,86,953,991,161,482,585,647,157,959,104,473,222,946,41,230,457,472,637,429,874,814,782,44,702,455,457,761,466,35,382,597,839,308,276,454,712,376,748,959,620,715,136,780,607,689,461,154,473,343,385,481,885,49,773,529,541,784,674,316,705,319,38,489,841,429,662,185,237,650,723,641,62,42,429,880,359,338,604,595,6,321,198,624,577,889,15,641,612,107,855,749,941,518,176,391,4,740,291,928,675,941,962,672,252,98,208,53,427,724,749,427,948,441,531,667,870,94,191,838,681,878,644,787,784,346,646,593,107,545,14,382,930,496,10,973,188,633,83,340,573,104,216,861,375,470,578,136,357,776,272,439,860,160,368,442,369,833,308,261,930,564,22,455,755,11,108,652,827,930,941,42,111,910,842,440,185,312,632,556,37,756,974,691,950,428,745,901,66,451,222,953,242,856,917,618,182,245,890,585,718,291,733,895,318,459,298,705,920,374,85,992,951,330,897,152,117,645,521,124,386,677,583,948,745,453,495,119,443,211,34,631,723,765,790,212,789,552,490,691,677,332,570,243,21,699,581,355,529,110,51,386,235,330,906,920,8,695,478,746,206,784,920,955,337,677,77,214,707,55,947,754,994,647,505,677,375,52,94,850,359,330,415,236,660,403,111,343,496,681,419,117,592,81,945,861,767,32,73,367,122,381,687,1000,506,767,970,343,733,751,697,376,826,539,55,37,465,30,982,483,339,413,745,421,768,664,136,163,322,687,674,993,910,470,624,333,612,384,487,410,27,308,775,611,54,710,676,541,857,328,637,408,384,546,889,73,216,550,285,26,71,777,111,808,454,170,523,749,279,580,618,443,594,342,939,68,778,463,174,329,582,105,589,816,448,303,997,961,995,171,739,239,207,847,765,261,773,115,730,635,950,992,190,176,636,152,830,770,909,445,264,119,722,469,472,61,396,597,781,308,43,7,692,819,63,768,462,194,3,457,376,198,49,576,427,113,237,441,641,754,549,782,182,49,460,561,526,758,488,307,606,280,227,627,953,567,916,192,616,98,729,614,150,861,955,835,988,545,724,961,976,960,743,429,470,529,164,825,43,764,823,780,911,316,920,171,506,201,795,384,995,926,764,208,345,483,856,518,595,493,745,813,428,816,618,40,49,771,525,500,451,55,911,926,235,773,121,120,301,107,993,372,591,859,89,750,505,210,164,118,614,774,505,328,207,102,197,185,451,918,991,197,780,286,830,586,398,404", "678,780,898,584,724,379,692,560,135,211,629,859,968,159,968,94,704,420,695,100,260,911,477,459,747,464,530,310,102,965,860,566,39,184,351,285,299,678,444,916,351,775,930,749,227,305,563,375,52,880,389,611,642,891,824,901,970,167,749,994,924,212,582,58,7,719,194,171,126,813,528,89,379,942,806,388,205,355,937,522,369,638,897,54,209,842,973,237,781,854,88,898,889,96,582,101,111,950,557,60,521,790,805,733,751,248,327,441,911,800,860,125,504,193,20,246,393,474,1,51,997,765,778,968,272,950,398,889,956,649,987,21,637,498,733,715,511,949,950,562,217,434,224,116,587,1000,760,337,256,955,279,662,614,508,123,863,333,68,895,905,524,581,397,446,579,911,233,768,347,212,713,494,241,491,950,117,660,636,440,88,519,460,956,891,562,860,589,693,94,231,259,326,753,79,97,127,902,237,13,818,413,392,121,84,853,5,596,540,553,453,668,234,727,966,645,274,265,244,44,552,547,421,779,723,740,100,73,519,226,269,579,35,597,861,13,337,260,164,568,842,158,378,452,180,371,187,620,480,884,519,703,527,625,762,73,81,376,782,980,808,491,541,158,250,86,256,573,242,739,896,159,800,884,622,532,827,235,603,627,558,711,937,779,537,498,876,652,158,472,976,546,269,676,751,552,327,964,123,410,843,784,432,117,482,361,140,204,990,384,915,768,976,374,562,810,835,612,489,791,200,809,361,831,958,103,903,473,402,928,359,444,389,804,352,32,86,15,745,112,188,454,728,60,787,412,712,251,36,62,81,716,321,919,393,218,619,58,491,227,56,919,440,138,44,157,59,949,774,163,914,182,115,439,596,401,795,695,355,973,510,332,590,818,673,474,670,910,471,405,221,814,649,524,140,273,869,202,188,472,126,663,940,156,296,866,198,665,131,173,853,615,662,825,0,241,803,64,363,199,60,650,868,480,70,207,37,348,690,595,601,276,864,267,616,458,555,9,16,401,910,275,585,744,265,593,672,404,653,183,426,89,727,500,814,468,397,243,576,87,938,509,794,486,958,251,497,2,668,69,137,323,807,178,847,887,402,632,289,58,789,794,70,265,268,705,190,735,446,769,573,395,807,749,957,559,780,906,458,811,313,203,524,938,235,600,205,371,648,209,700,291,374,196,901,741,122,795,858,499,709,224,853,142,976,477,506,20,188,463,138,405,597,763,641,294,923,869,560,137,698,681,99,39,884,813,680,824,269,766,624,270,723,118,608,859,156,311,423,887,877,587,927,395,255,35,613,679,445,443,958,362,181,606,855,252,956,236,860,150,790,225,210,862,171,709,976,462,688,31,786,525,541,616,973,632,899,89,190,593,138,457,359,261,724,391,428,89,563,505,221,598,27,385,398,494,688,505,118,702,879,231,996,388,752,913,740,209,190,877,779,899,888,860,478,250,554,185,144,174,491,330,925,656,165,395,273,901,749,402,658,363,96,621,343,646,252,671,719,315,920,285,657,578,478,824,977,531,95,421,323,924,632,953,170,836,172,272,741,896,342,720,632,729,260,345,677,529,568,462,46,690,836,95,961,724,462,653,717,79,508,806,932,464,922,647,457,424,868,707,48,967,474,579,737,601,112,346,533,720,393,703,249,527,311,743,338,200,459,434,980,506,786,380,492,373,409,775,186,624,256,841,266,691,12,77,538,929,931,194,146,492,525,811,128,359,667,256,895,621,718,548,537,522,521,198,828,196,59,873,216,602,807,83,349,10,657,121,189,291,883,427,137,918,877,292,700,596,342,377,460,598,421,223,837,243,800,57,628,565,620,716,257,332,511,668,437,555,353,60,714,861,552,111,231,782,448,274,19,117,215,953,173,322,157,85,598,377,188,654,856,465,576,453,755,450,244,150,888,879,113,161,206,297,264,365,318,924,13,593,990,921,245,597,461,71,517,148,481,347,180,64,723,506,966,373,585,205,98,655,333,75,191,915,103,353,590,652,888,657,43,99,198,106,968,101,558,669,244,167,894,387,979,119,716,24,457,662,163,368,174,119,133,692,73,930,536,289,559,224,434,376,867,756,945,673,340,361,436,221,721,509,972,239,118,896,744,874,313,37,76,485,875,223,336,926,117,34,886,328,946,819,306,637,943,724,93,220,865,143,493,450,561,863,251,967,601,480,955,146,274,92,405,705,781,586,332,349,42,171,761,682,755,950,476,593,253,433,772,960,1000,964,705,884,384,453,804,738,926,954,520,687,974,413,561,128,999,528,779,859,585", "848,568,759,442,451,136,676,146,284,326,624,801,514,360,366,252,669,545,471,153,997,886,457,631,396,492,412,345,919,501,618,750,847,763,754,280,654,383,433,326,296,991,169,97,746,148,173,303,955,558,912,203,533,565,434,911,553,19,857,166,187,638,347,404,651,769,131,302,445,581,217,70,454,23,869,915,585,144,778,5,304,424,56,124,972,231,878,929,19,214,29,830,970,977,772,961,196,564,347,459,421,298,771,65,903,529,618,554,966,832,157,44,790,186,172,570,340,392,816,536,677,791,890,955,534,899,728,641,845,98,885,185,167,966,515,981,592,58,74,323,732,848,812,759,164,892,50,931,414,870,295,571,342,90,913,578,446,971,488,623,643,596,570,100,370,920,339,162,629,605,197,467,219,185,96,636,397,540,609,600,85,321,348,286,337,475,558,494,893,301,482,122,983,54,555,89,987,716,567,457,647,189,103,211,230,532,651,19,572,666,271,411,502,576,204,174,282,474,811,463,797,749,484,91,393,151,489,801,816,778,795,21,84,683,718,216,216,173,111,179,350,525,990,726,306,111,444,733,867,161,30,671,672,102,999,920,960,230,421,520,301,782,671,73,617,599,188,177,251,863,743,751,610,539,479,970,647,282,349,793,264,521,532,282,21,521,835,277,776,501,588,756,634,618,726,558,240,338,312,328,591,557,766,996,260,837,187,100,897,544,433,868,233,641,769,563,351,387,123,998,771,20,985,793,605,56,979,554,90,315,234,810,856,629,711,433,661,77,828,284,685,399,664,36,566,924,314,578,288,320,245,304,153,976,329,620,904,632,893,981,850,975,550,964,722,964,425,827,861,109,302,417,255,648,338,975,569,235,184,766,741,685,905,643,260,56,863,706,735,481,782,893,662,685,175,114,924,368,126,8,503,796,241,690,360,124,408,745,32,853,117,304,139,241,0,495,316,761,389,297,22,454,851,316,241,594,645,579,716,8,922,398,919,444,545,356,682,27,952,525,185,278,901,822,818,266,148,297,509,485,272,197,681,703,335,163,153,869,107,725,859,972,282,329,702,527,88,196,423,34,613,537,46,683,288,147,560,755,607,966,653,403,786,792,456,511,315,933,114,589,309,697,80,402,903,360,754,991,184,993,793,541,968,180,200,12,756,539,427,630,420,836,739,757,60,909,86,129,864,36,220,764,598,658,202,796,951,938,837,862,718,163,387,32,742,709,498,48,282,979,394,707,440,755,496,777,139,516,859,358,161,773,897,212,588,145,741,28,597,261,636,340,110,896,590,382,170,121,199,13,757,729,841,363,375,776,66,342,800,182,219,753,122,803,575,590,951,124,36,103,968,162,497,644,691,786,890,741,292,364,840,201,402,991,659,695,89,371,959,604,369,360,907,192,568,357,787,320,451,87,628,446,735,944,409,751,371,650,766,266,655,50,745,397,441,881,901,975,907,535,627,66,777,330,638,595,575,414,726,533,35,676,439,713,557,312,975,839,48,740,148,146,104,94,92,286,81,316,582,173,745,850,402,282,614,811,670,710,7,68,23,101,915,267,140,455,850,419,265,195,182,61,99,660,446,539,71,718,500,553,633,375,170,85,989,83,697,197,379,524,502,582,806,948,647,441,479,167,244,722,388,603,336,7,15,636,80,748,776,161,826,224,708,664,68,169,83,797,442,674,804,492,637,575,192,504,651,518,411,673,396,485,467,80,696,955,661,143,320,664,360,806,816,950,739,498,197,555,63,845,898,718,520,947,266,91,870,423,976,595,819,656,533,251,68,169,87,533,975,823,162,428,631,788,922,726,785,14,333,616,850,82,722,797,274,854,189,244,659,236,182,127,902,40,12,283,57,215,833,772,272,465,935,301,542,172,573,724,112,278,608,210,5,459,233,963,553,884,194,883,356,405,254,845,141,765,734,846,297,658,478,246,714,784,331,408,277,936,157,871,440,467,265,865,100,183,268,827,53,14,386,557,302,869,439,102,952,12,241,990,725,622,461,483,726,233,40,24,514,664,770,550,843,986,897,735,587,579,359,522,342,592,425,104,116,879,190,863,441,60,882,466,181,814,992,474,19,373,976,384,667,6,856,896,152,605,337,148,746,352,311,204,740,913,771,951,455,312,625,301,158,509,128,942,857,675,936,765,950,607,365,400,291,249,394,833,148,292,538,467,65,190,213,595,414,524,965,786,127,74,420,857,720,2,45,60,622,269,797,121,530,67,231,392,399,958,978,151,477,618,904,715,735,517,926,595,872,242,606,177", "764,295,749,766,305,194,177,226,242,388,388,740,310,731,739,165,805,219,700,431,245,498,844,72,835,840,428,120,910,533,330,46,898,869,450,76,955,177,699,754,446,722,462,423,74,917,254,197,935,165,341,158,139,879,431,256,446,804,669,95,725,544,422,981,870,248,228,879,979,920,263,932,93,239,271,776,846,113,772,851,915,24,678,429,833,494,702,465,905,200,491,370,95,222,106,90,103,84,322,573,666,426,776,52,39,101,274,540,578,858,366,766,277,796,100,371,593,12,627,637,37,42,716,481,918,627,754,230,510,460,88,805,743,594,313,238,567,43,52,775,625,172,362,641,705,1000,640,697,71,708,417,833,534,903,362,29,363,584,463,283,278,299,571,355,724,619,175,739,244,294,486,41,307,697,636,160,483,488,315,294,502,680,566,32,821,581,902,816,757,815,370,876,203,170,373,964,421,112,661,439,699,112,584,16,302,266,600,616,250,197,172,144,252,847,822,866,568,37,270,894,261,337,75,964,81,982,537,98,217,104,296,222,64,659,295,127,385,745,289,209,119,992,400,500,638,573,990,912,61,756,923,694,235,971,468,152,621,124,593,192,213,418,619,872,757,45,748,201,785,257,921,339,896,973,691,705,735,245,702,132,658,59,650,899,644,194,351,504,472,374,386,87,835,38,931,629,450,86,572,739,93,725,99,411,30,682,811,844,754,950,11,768,419,951,414,795,938,598,240,296,748,988,370,159,802,88,603,968,594,884,385,400,446,211,957,666,224,906,276,82,465,288,891,733,268,975,316,460,120,184,990,656,232,924,273,464,428,46,445,418,843,226,170,488,349,596,785,915,786,313,459,397,54,426,91,149,27,107,701,618,801,711,84,366,827,239,741,314,574,137,462,916,25,211,911,101,738,890,513,833,522,381,680,870,692,346,872,216,159,191,52,900,994,803,495,0,740,412,815,242,8,838,861,942,545,349,195,888,683,216,934,851,16,650,178,280,562,396,261,627,538,550,559,102,21,551,526,757,433,436,142,241,558,866,300,86,628,503,529,432,483,542,261,443,174,869,845,195,794,268,778,625,471,504,792,639,860,362,961,300,143,540,163,729,252,147,655,394,630,503,95,249,549,939,129,135,592,52,760,292,584,642,345,517,130,896,835,679,640,565,827,892,325,666,991,698,94,767,798,443,829,706,62,22,146,836,484,952,791,112,392,227,377,389,620,835,703,896,681,53,223,833,926,419,284,338,154,390,847,794,346,174,557,201,732,824,450,702,128,204,468,651,483,863,458,859,69,728,606,164,483,452,301,450,146,782,753,751,781,284,635,910,112,266,732,850,317,626,804,281,789,194,750,523,214,35,556,701,536,824,697,754,859,724,470,765,550,478,820,276,658,702,22,664,728,286,236,575,315,239,569,57,988,718,881,868,768,221,244,70,120,618,581,783,336,556,864,216,873,283,194,694,492,111,584,745,582,799,771,716,751,228,614,934,979,539,383,678,891,275,785,897,251,11,378,48,620,19,171,914,191,687,445,644,539,47,518,663,860,997,171,651,994,448,855,685,671,450,66,512,778,863,627,751,719,609,61,63,346,786,720,520,95,17,221,284,385,696,817,447,895,107,350,729,222,366,738,701,543,643,565,527,52,547,23,722,394,744,82,845,305,88,731,865,416,452,690,618,938,798,523,449,594,625,303,495,926,599,54,710,637,315,533,82,434,42,722,817,106,16,105,523,43,359,915,127,727,11,60,320,861,923,384,665,842,948,837,404,200,810,234,503,811,782,229,9,653,958,955,60,30,365,491,626,822,813,793,48,46,359,909,67,480,850,303,737,822,794,743,920,719,959,172,840,715,664,41,868,918,934,214,437,237,244,770,930,562,882,74,148,382,1,519,127,236,996,341,873,222,778,140,218,126,938,480,47,821,914,849,459,562,98,283,149,404,999,486,422,462,883,714,72,70,38,610,104,943,64,956,204,623,612,928,282,928,924,823,695,113,123,748,968,232,442,829,467,905,247,16,510,117,246,255,173,225,701,688,796,562,399,827,661,657,324,524,904,227,198,335,973,856,507,8,493,757,244,196,206,36,240,760,672,932,118,182,535,238,996,450,531,51,81,886,233,146,892,106,938,402,600,256,431,732,478,748,550,915,674,764,648,507,166,764,717,182,997,782,473,244,678,550,171,251,431,907,473,650,63,316,90,636,554,236,983,738,852,731,656,195,553,414,515,55,203,27,452,700,806,149,650,511,202,211,598,873,513,128,660,532,356", "888,597,103,895,491,322,308,139,533,669,530,171,426,251,986,947,695,237,892,882,368,721,58,37,216,344,664,156,306,737,998,632,416,341,900,319,715,868,911,777,569,998,545,665,166,733,515,354,885,415,120,782,522,755,47,483,952,690,49,206,334,84,380,23,637,32,114,308,138,537,801,280,480,674,975,315,29,857,466,448,374,353,43,834,997,375,668,926,328,942,306,525,47,461,706,336,292,37,860,40,229,720,184,980,946,619,131,573,926,223,300,790,337,495,79,438,803,374,408,582,140,945,141,869,385,91,243,817,257,418,87,755,821,391,151,467,750,822,755,869,371,339,429,535,738,247,786,948,941,539,703,786,896,60,179,485,570,647,387,964,156,267,220,996,702,152,936,438,490,591,827,760,515,554,115,943,441,590,452,71,810,725,835,506,794,610,231,987,226,841,906,117,73,831,751,985,453,477,908,750,342,482,819,383,184,18,269,956,363,553,448,892,155,642,326,918,215,53,625,229,727,650,818,309,895,281,824,108,937,563,860,472,225,671,130,966,715,359,695,662,835,159,18,409,730,308,589,409,418,81,296,284,892,594,412,943,948,645,925,97,651,660,614,77,808,829,918,736,968,795,994,45,599,425,406,702,277,668,191,80,105,703,799,412,564,414,341,6,992,374,983,684,506,108,475,250,953,589,17,626,264,139,663,342,126,62,619,480,795,510,899,364,298,352,325,450,445,360,188,425,580,135,388,154,430,427,972,429,294,487,414,509,793,725,688,291,641,34,379,225,289,508,367,747,902,421,347,159,905,43,34,530,492,403,839,492,354,935,686,278,449,890,601,449,599,58,726,890,863,531,591,727,158,335,972,579,150,241,610,185,16,257,767,308,54,922,129,251,645,790,309,480,338,15,525,312,87,224,759,113,47,255,568,795,121,421,854,928,173,145,798,677,370,64,316,740,0,66,355,711,156,891,555,817,477,517,413,927,712,427,50,409,355,682,32,685,412,888,291,456,483,744,47,281,745,331,630,941,583,88,814,757,40,465,660,6,409,2,59,178,611,349,998,821,261,536,506,993,342,786,418,911,178,653,283,972,357,987,185,567,700,564,413,149,642,475,216,370,488,900,301,537,375,549,539,560,162,841,689,970,788,548,949,805,314,253,733,862,713,46,848,758,494,697,927,27,199,348,958,500,231,691,759,467,142,828,322,23,719,92,977,45,944,223,25,323,874,28,535,36,953,152,522,45,876,967,207,118,313,994,62,213,463,290,48,931,105,522,41,267,504,994,231,211,883,528,261,341,568,874,504,385,84,36,927,784,5,239,313,717,145,773,182,474,90,284,956,523,558,349,230,753,829,546,865,957,564,747,874,42,167,145,975,317,83,620,230,549,268,874,142,982,563,349,763,686,87,434,102,287,836,322,245,592,652,903,538,929,7,94,525,560,44,137,836,527,521,431,774,247,759,799,805,51,195,252,249,927,279,882,447,969,383,756,708,139,513,824,606,975,309,77,59,268,364,111,464,321,198,521,249,942,778,901,807,472,756,342,718,173,222,478,831,391,456,912,994,227,345,851,234,2,815,484,749,109,703,32,653,178,898,220,498,283,914,740,422,585,106,50,590,567,876,974,457,57,55,589,951,574,127,555,646,470,44,26,48,303,233,939,456,96,859,324,998,95,79,46,358,43,229,937,886,216,537,17,7,41,78,910,835,786,531,303,271,84,616,586,207,792,571,262,585,379,326,661,706,642,445,405,952,863,862,419,932,773,838,844,714,597,100,836,836,610,158,446,588,829,835,677,242,833,114,427,464,413,83,167,868,150,108,545,386,295,577,934,454,907,814,125,719,972,876,610,608,73,148,774,942,785,926,635,243,492,973,808,154,169,934,430,276,708,552,258,417,267,90,391,190,631,130,343,579,464,541,577,38,939,126,333,168,851,411,916,518,498,430,63,74,473,495,732,197,489,392,825,992,323,158,931,350,504,421,282,506,992,698,574,683,542,241,458,651,497,223,111,589,977,414,764,204,633,450,512,62,678,27,486,637,800,587,510,473,808,906,656,944,99,743,436,630,627,264,41,38,623,235,888,938,921,129,599,722,768,123,239,585,283,898,80,758,390,249,990,200,960,658,841,651,698,413,739,840,86,315,387,242,299,33,15,45,487,692,21,60,912,445,32,337,642,597,920,588,207,774,989,365,317,81,499,771,750,871,415,697,821,465,831,976,50,743,659,807,426,983,380,985,92,480,37,828,80,679,549,984,406,738,630,515,603", "40,704,341,420,572,483,504,8,184,331,579,975,439,782,160,205,592,325,140,246,792,572,905,800,882,838,233,917,815,32,414,113,37,793,519,769,521,988,311,431,475,361,711,321,966,36,57,339,534,626,192,969,669,389,63,36,635,473,470,887,854,406,928,659,151,216,965,803,879,252,527,20,446,605,30,678,893,78,639,627,600,302,921,635,874,174,402,119,600,186,611,735,256,181,326,185,390,865,98,252,228,861,409,693,638,416,675,770,978,697,154,796,436,301,865,846,61,841,556,191,922,439,584,375,350,263,52,355,915,305,301,12,195,450,886,560,633,717,265,422,685,40,747,559,893,636,325,870,756,77,740,475,766,546,488,457,426,752,707,836,420,634,509,108,315,415,30,913,572,280,393,663,37,376,336,704,749,589,732,63,549,693,529,486,618,668,893,136,295,483,405,990,430,219,513,266,115,408,175,104,228,672,713,195,842,603,811,269,786,658,619,570,104,687,407,351,726,390,423,485,998,214,584,896,8,95,996,229,739,89,456,916,444,639,309,318,863,314,117,295,847,505,368,732,953,138,271,171,598,355,266,334,210,204,732,927,314,497,135,379,325,938,65,852,894,61,742,262,939,80,979,252,124,275,95,446,230,368,534,385,509,223,113,805,632,405,66,100,979,842,526,737,48,926,295,393,839,596,644,886,339,900,350,450,223,466,964,147,556,809,343,52,610,544,165,650,906,153,910,868,39,311,625,187,149,918,38,731,597,689,647,725,290,228,52,107,140,274,436,961,251,863,886,127,144,852,961,713,483,85,282,470,904,470,703,827,733,88,837,962,562,624,721,76,21,47,374,875,891,893,576,91,816,419,127,871,533,580,349,249,574,256,805,682,398,410,293,67,241,497,542,852,47,595,437,55,308,888,439,787,497,117,379,995,912,795,888,407,536,519,82,307,739,363,761,412,66,0,748,693,712,258,425,617,923,505,490,846,516,626,182,778,601,251,417,126,360,432,80,725,672,373,377,121,539,542,256,309,795,826,372,9,661,317,68,216,73,202,616,854,500,402,321,457,534,856,283,804,261,379,332,545,881,533,816,574,465,284,145,727,816,958,710,930,851,967,127,205,521,606,451,162,3,280,722,400,440,696,349,85,220,869,826,561,44,603,532,751,998,233,714,792,965,891,277,479,545,82,652,412,935,518,406,922,863,404,357,532,257,969,162,170,862,625,362,726,907,899,728,734,458,864,123,248,997,899,509,307,829,82,181,784,930,264,244,858,564,647,845,980,707,612,236,799,576,963,961,563,834,557,349,550,346,311,334,568,369,733,957,420,395,701,288,959,154,41,30,867,559,355,123,588,217,938,937,443,119,908,463,718,403,704,102,468,735,614,41,692,828,895,884,692,623,516,511,954,520,12,792,454,342,426,754,932,15,985,973,481,166,718,200,884,167,968,872,536,661,735,835,592,322,672,623,768,747,135,952,695,817,88,223,121,598,429,98,406,102,128,943,153,952,604,237,758,360,971,151,996,448,686,163,517,407,456,613,201,271,855,189,494,964,460,312,36,970,795,635,665,805,458,591,465,743,267,740,384,480,204,404,389,190,85,728,629,167,344,543,762,884,521,515,516,92,91,539,747,327,418,352,68,410,927,852,843,113,812,46,637,489,918,718,146,238,118,492,976,651,190,367,357,131,471,264,104,112,456,423,619,152,963,178,695,902,375,112,125,402,876,472,106,845,219,773,439,470,455,498,47,43,587,742,558,836,535,892,526,371,267,513,121,280,336,91,124,460,449,994,262,421,788,341,535,315,67,53,257,487,463,934,635,487,321,960,123,606,530,56,269,512,747,587,552,66,242,846,833,208,22,658,287,902,238,258,467,140,414,773,273,740,62,731,135,870,476,339,36,427,671,995,562,505,221,845,652,379,789,80,398,875,656,284,986,272,31,972,955,332,520,549,143,587,609,735,759,678,378,798,657,539,915,985,479,800,202,635,200,845,191,174,10,16,564,949,784,922,242,739,120,894,965,242,230,789,53,419,476,584,116,146,846,165,85,533,415,335,778,867,262,477,209,276,845,207,698,912,804,291,319,493,442,74,171,857,611,235,429,530,457,527,147,399,291,236,671,680,589,499,462,973,398,238,871,492,508,514,140,674,606,575,503,869,630,994,875,36,197,541,503,588,990,294,817,31,258,532,859,420,636,531,727,298,56,826,845,27,423,635,514,939,382,143,55,782,321,939,507,817,350,623,360,231,230,458,207,492,465,716,87,551,523", "291,46,435,238,297,572,586,984,334,536,497,7,872,210,245,187,950,390,501,920,772,584,368,213,734,450,391,37,860,156,400,729,802,262,407,902,196,270,905,61,652,902,889,446,541,260,487,544,404,222,611,782,128,382,281,349,615,694,132,823,210,349,307,28,967,498,57,94,45,228,275,137,928,828,554,271,988,633,213,86,210,768,552,600,825,122,317,123,420,866,448,85,408,249,782,807,278,318,609,934,290,594,638,793,262,107,988,527,762,762,662,458,105,345,950,577,806,789,144,968,677,466,745,774,618,686,569,110,22,83,479,909,94,799,825,737,128,584,911,805,542,791,472,702,661,507,125,648,773,266,259,758,454,69,706,303,86,421,218,850,24,344,923,246,174,851,160,28,453,251,748,980,176,712,616,92,293,475,310,44,20,850,977,565,902,510,540,486,801,650,515,788,704,258,190,429,84,481,123,184,429,890,653,205,922,622,520,812,62,173,462,177,510,434,787,844,683,408,854,864,351,513,629,875,693,111,523,695,643,158,222,216,179,784,872,494,836,26,507,484,499,980,392,151,373,492,508,604,142,60,198,698,701,767,487,264,622,391,753,800,461,246,719,968,629,649,208,232,601,651,265,144,303,514,138,753,550,199,244,961,252,352,435,389,17,218,306,945,359,940,124,369,70,68,424,803,900,201,553,671,375,628,433,234,13,613,267,18,965,404,998,813,8,748,603,294,467,739,610,880,243,757,697,351,422,318,63,571,688,287,822,925,758,685,690,355,181,257,561,233,868,863,434,587,815,766,392,690,388,41,822,291,964,859,863,524,315,368,244,232,744,360,323,766,383,761,330,316,185,186,450,925,919,367,122,892,294,456,379,908,412,405,562,497,487,942,395,589,507,534,207,326,585,286,838,391,938,600,615,615,109,371,710,416,924,859,67,15,445,32,413,183,3,199,389,815,355,748,0,338,411,82,158,835,457,840,752,348,670,7,715,880,217,460,252,393,81,237,607,548,885,424,740,418,247,872,952,43,676,165,7,887,461,236,847,417,290,316,17,948,654,120,222,172,426,474,221,243,52,706,388,693,825,222,579,690,202,106,720,566,182,440,337,716,396,750,440,914,14,273,365,213,114,370,779,680,100,514,370,951,433,837,379,314,55,584,162,701,872,306,541,673,931,282,349,735,451,355,820,288,303,225,853,200,583,572,142,841,698,797,722,85,743,338,983,771,257,546,95,587,811,623,85,749,88,373,952,175,631,857,805,169,790,805,2,107,449,555,342,325,469,604,22,431,786,384,451,402,204,975,94,27,647,380,44,888,55,633,33,591,888,195,272,870,210,200,145,565,812,338,929,101,502,113,566,602,475,127,825,655,89,496,623,925,639,726,451,831,657,401,112,200,950,33,973,945,33,172,710,836,981,318,908,3,735,567,57,266,893,990,450,393,395,849,412,416,896,182,595,233,352,104,549,367,963,937,72,694,429,934,458,943,43,398,187,235,564,779,747,689,376,339,933,760,303,309,577,387,489,674,420,332,808,399,272,395,599,149,300,303,840,508,318,39,96,86,242,666,518,531,140,539,653,851,409,435,178,422,135,863,378,147,698,440,494,616,641,735,711,114,417,845,513,652,575,305,687,125,742,253,373,148,228,807,489,979,95,918,471,605,501,172,16,927,788,493,875,670,25,389,930,690,892,308,699,836,742,624,578,485,980,755,501,388,270,466,119,872,842,251,380,299,418,93,752,639,985,173,168,668,409,870,734,184,800,97,344,773,888,235,986,206,660,47,520,859,253,910,311,830,281,307,499,709,974,404,979,957,620,962,678,318,906,999,638,636,196,877,650,317,546,855,550,456,347,745,745,205,277,872,58,629,832,419,959,297,597,458,622,296,115,234,638,323,742,397,154,873,86,630,287,70,353,106,341,955,245,249,942,454,115,50,256,141,39,352,866,626,485,341,180,286,483,51,135,514,118,242,289,956,841,802,907,990,999,898,987,841,891,893,704,688,857,233,980,869,229,435,108,927,694,387,901,863,173,846,455,311,676,520,694,26,688,957,389,594,959,447,996,543,650,991,359,337,733,302,169,370,79,65,8,884,917,7,764,290,801,638,974,767,751,763,171,423,128,845,617,215,607,779,194,323,410,934,91,784,418,105,870,209,820,718,684,412,927,413,318,166,261,164,657,687,988,603,997,801,314,388,215,254,262,816,920,389,797,438,78,856,536,356,795,469,887,158,335,187,377,431,192,338,8,298,277,896,47,259,340,32,36,370", "456,768,900,492,716,630,118,354,573,181,945,124,339,339,339,787,914,4,586,407,50,523,4,707,419,499,490,238,942,671,939,983,971,912,847,47,924,776,934,223,49,495,291,497,331,498,603,949,659,91,16,838,647,474,217,711,183,434,456,373,579,532,268,815,712,972,33,504,585,747,59,839,903,598,820,76,153,238,548,71,105,929,646,803,856,533,234,735,414,959,616,382,716,291,595,851,277,925,528,493,654,698,463,415,83,679,336,231,47,573,626,123,716,602,55,361,815,132,600,352,890,346,996,790,976,893,764,901,640,686,818,630,966,959,961,307,910,818,872,651,608,890,877,419,270,338,26,136,329,350,530,353,172,470,300,963,314,586,509,395,211,624,374,280,271,152,854,407,629,21,82,627,237,826,280,30,141,963,374,720,448,438,366,832,828,336,190,613,934,959,715,22,349,694,887,868,514,163,543,291,214,165,970,992,831,855,881,764,290,666,827,845,906,503,480,634,745,880,529,626,4,116,273,712,16,591,360,153,660,763,170,979,898,42,376,429,303,994,464,665,947,925,368,835,775,559,990,42,517,549,120,574,570,277,162,401,558,37,791,75,629,54,971,586,597,224,731,31,840,723,111,879,172,151,231,422,460,961,451,656,104,770,517,198,236,178,672,376,362,465,110,271,91,885,603,444,820,146,863,557,809,642,773,24,112,538,248,438,952,250,803,116,989,24,787,702,758,493,529,217,542,513,968,228,220,89,959,917,656,911,780,915,641,53,185,338,316,421,849,820,26,747,573,800,515,745,252,755,578,837,742,138,900,665,235,524,925,309,528,528,613,724,334,299,300,191,175,779,94,966,476,974,610,572,571,224,535,957,464,801,48,51,703,574,766,833,33,852,873,448,51,636,757,859,572,109,876,193,438,601,626,731,140,920,372,395,347,219,517,295,389,742,19,60,297,242,711,693,338,0,360,767,467,582,599,92,678,916,373,940,784,561,36,329,193,643,40,63,341,813,679,319,646,191,164,706,585,613,25,984,314,994,562,195,416,318,458,348,13,778,476,369,819,119,861,657,719,264,733,148,732,447,943,837,626,204,959,704,10,487,694,886,872,450,324,381,260,834,594,981,366,617,619,302,85,855,280,29,92,925,71,408,892,11,607,17,177,799,148,740,219,113,952,230,726,498,947,619,728,396,273,211,368,850,177,2,890,837,852,485,836,849,638,316,974,167,697,358,444,478,80,173,944,35,196,86,94,906,712,312,390,547,950,399,780,276,967,512,918,509,78,877,292,414,443,824,127,215,672,517,995,813,42,810,620,884,441,481,37,746,581,366,142,537,12,683,418,922,856,476,101,192,425,533,961,268,244,823,735,61,825,242,45,686,822,938,266,764,314,6,829,385,504,381,902,581,127,174,971,427,20,998,639,934,515,256,898,770,296,405,945,59,123,439,875,565,132,153,544,210,650,205,920,246,2,717,721,573,248,428,86,621,539,86,866,626,176,170,979,741,198,886,689,474,951,390,742,353,303,90,947,517,334,421,456,60,45,396,423,381,620,409,781,97,5,78,991,860,977,159,560,621,113,760,574,761,421,750,851,446,747,915,752,282,306,447,663,749,586,637,642,577,618,737,521,972,266,207,629,651,702,267,316,261,996,840,2,749,1,669,492,491,7,437,939,198,313,738,318,651,219,981,629,156,382,777,301,372,46,648,231,457,717,227,310,281,434,489,198,518,314,92,185,241,880,52,950,91,382,857,178,207,994,760,742,274,694,362,696,712,132,817,729,362,835,900,804,809,903,149,805,139,513,361,320,699,431,895,469,143,452,327,346,411,996,507,207,208,500,950,865,977,168,98,155,611,406,182,648,504,569,267,477,697,898,97,492,297,463,654,47,619,818,877,580,298,998,703,890,991,187,878,714,581,581,55,627,163,710,806,724,398,555,626,950,966,733,859,132,991,874,554,786,118,775,315,633,84,427,769,450,99,356,44,514,324,36,100,817,56,920,990,207,72,781,789,154,349,928,639,29,420,337,488,239,534,601,342,690,637,958,462,916,476,585,469,155,890,247,123,179,306,246,856,910,497,491,345,51,624,260,989,828,310,234,229,465,791,605,90,406,675,483,834,384,449,679,697,865,148,361,334,359,457,955,987,9,138,458,822,719,310,217,426,213,364,97,152,502,252,820,954,231,695,654,686,142,7,56,854,147,666,30,453,263,284,967,217,840,102,835,668,366,228,276,534,447,184,110,910,546,934,435,754,724,56,644,188,424,555", "710,76,113,552,348,357,109,384,70,330,746,402,781,645,215,463,649,28,783,127,53,411,594,88,699,475,620,933,789,220,353,283,346,869,610,631,822,486,285,337,738,539,244,692,686,913,234,34,909,943,50,173,905,465,146,520,324,598,920,321,339,348,231,386,248,701,876,147,737,348,1000,879,594,398,351,589,659,579,669,877,138,522,48,814,64,858,37,954,255,776,456,827,348,379,502,536,181,31,365,887,768,134,729,654,218,330,850,318,654,685,505,630,389,109,323,654,981,500,289,997,171,733,831,620,333,665,81,871,255,238,78,209,289,976,195,24,584,316,281,845,458,397,975,985,316,890,335,238,201,970,995,696,565,74,448,863,228,945,228,947,200,608,563,501,425,382,345,161,921,105,500,509,68,136,697,25,689,915,815,632,47,458,13,32,117,602,895,903,992,934,872,308,674,890,887,804,738,400,776,79,338,520,177,981,243,507,49,183,339,397,140,115,155,115,809,402,242,945,289,27,25,252,478,767,588,841,422,842,401,648,961,859,25,253,174,79,530,22,782,238,589,245,465,575,885,39,618,515,264,452,591,509,594,924,864,508,604,816,336,944,166,186,221,964,243,72,732,592,153,484,718,348,864,375,578,786,254,378,781,894,281,273,492,17,489,783,444,166,285,872,437,977,22,550,434,807,994,852,280,796,468,119,580,952,811,403,335,431,161,279,150,231,31,902,346,275,454,997,760,307,962,417,920,978,498,626,171,625,774,135,850,719,403,172,914,135,1000,260,654,652,777,228,886,989,174,257,666,600,153,385,891,269,633,837,279,199,909,904,733,521,731,720,71,343,861,180,342,303,885,894,801,197,263,871,965,259,385,941,340,60,704,566,574,954,437,186,460,955,50,716,967,104,531,957,415,425,710,842,340,563,14,935,743,592,476,248,963,720,764,726,722,570,742,650,22,8,156,712,411,360,0,180,685,470,766,469,843,881,45,248,801,10,162,658,165,988,75,641,168,308,500,906,928,118,763,61,25,129,466,931,323,576,230,596,969,527,692,409,925,960,815,5,716,328,81,643,109,407,922,791,938,508,500,828,167,978,422,840,61,288,500,689,324,701,898,366,821,863,548,601,697,156,854,29,224,310,20,537,411,435,565,30,359,242,809,175,630,448,478,510,675,50,491,975,559,527,552,543,285,682,813,99,173,809,323,727,21,979,214,668,927,583,941,528,950,608,643,879,446,58,456,759,743,351,586,385,995,431,730,200,622,827,125,491,195,254,405,125,603,376,862,752,451,376,870,70,209,43,41,577,934,261,553,963,840,776,774,129,890,131,98,396,99,953,823,125,484,178,890,361,23,287,716,603,658,29,124,255,227,624,332,252,396,372,704,834,309,78,216,634,671,996,934,636,132,779,540,996,740,125,247,158,350,199,560,396,391,696,148,761,41,39,343,506,575,681,955,632,519,26,187,291,354,280,574,897,179,432,734,573,988,327,624,394,527,933,237,279,392,822,239,7,850,867,281,987,472,706,392,124,532,799,499,153,952,856,478,885,766,195,464,937,387,878,338,113,511,945,333,912,53,301,780,867,103,728,37,507,264,105,900,296,811,193,592,53,377,762,758,208,329,11,661,901,281,27,416,924,657,488,752,411,631,343,916,455,968,287,351,610,824,626,16,947,396,199,842,166,110,732,244,213,638,724,617,806,520,96,252,391,779,849,687,191,370,209,570,338,438,617,17,663,91,662,882,251,275,258,924,549,207,18,572,801,234,583,836,182,934,639,76,348,602,128,881,238,657,404,953,621,372,338,337,729,800,293,182,737,231,888,599,887,570,454,812,32,820,157,889,672,116,193,663,38,281,565,504,306,165,988,720,636,482,558,783,92,186,631,61,955,632,927,128,905,47,543,639,189,566,144,349,313,521,666,109,979,904,262,387,486,686,170,173,40,552,253,358,435,924,822,559,685,316,795,854,671,56,174,64,860,57,361,810,142,950,891,2,815,528,893,339,717,866,510,770,954,853,290,102,300,176,202,987,388,478,364,285,628,639,265,28,210,250,777,859,986,630,135,653,433,581,143,683,825,75,398,596,685,253,569,843,711,493,27,393,858,857,575,533,674,548,156,152,126,307,724,418,598,645,381,773,945,207,218,42,49,765,830,689,287,980,207,639,171,224,354,712,599,990,502,815,633,394,92,159,897,216,710,939,905,559,780,252,565,920,220,580,224,968,935,7,652,849,761,617,491,787,593,263,620,558,967,541,598,934,955,350,961,574,398", "685,731,994,379,606,673,445,369,659,645,770,916,979,921,43,994,394,597,982,4,381,226,862,9,384,874,626,108,710,666,994,559,896,817,755,969,245,848,522,91,275,766,104,893,447,757,524,917,748,507,678,162,633,783,578,114,911,488,319,455,884,898,980,855,791,783,259,461,331,815,747,592,929,736,666,107,835,670,391,277,860,182,769,149,730,754,874,449,226,339,636,215,295,153,79,121,261,175,178,190,604,250,167,151,243,112,84,873,146,629,693,996,526,400,77,536,949,966,183,961,636,285,48,795,303,6,291,193,279,647,551,631,265,239,328,688,365,80,845,249,183,713,985,489,71,346,651,126,124,451,154,424,648,912,468,312,936,871,6,715,107,706,865,821,912,735,452,183,761,499,431,923,860,13,705,812,116,430,945,325,300,768,972,161,899,49,294,473,588,9,401,952,888,56,590,518,609,958,83,442,149,517,669,141,310,418,766,971,93,452,922,340,376,709,745,879,331,915,55,315,852,275,630,747,227,747,432,701,714,64,801,32,115,707,343,308,748,198,37,382,895,409,164,287,963,866,570,180,44,144,982,280,656,932,90,689,901,559,290,857,774,464,385,765,105,661,633,308,550,407,753,164,946,441,373,788,56,123,678,707,671,435,92,47,421,707,601,658,508,406,26,563,525,265,79,749,203,284,890,904,649,307,859,913,873,865,138,528,945,281,477,155,574,343,325,815,261,493,339,941,894,839,341,356,654,34,230,359,650,120,453,919,576,95,661,649,673,966,961,365,260,387,655,203,41,590,336,938,716,60,42,314,13,300,738,38,598,787,601,753,775,674,843,946,18,623,600,180,894,57,846,636,345,759,557,210,343,555,281,56,382,198,55,788,836,589,291,461,449,871,432,893,67,673,967,795,10,719,886,102,890,875,79,298,540,462,345,96,951,459,301,952,140,868,454,838,891,258,82,767,180,0,644,621,350,104,76,34,380,733,309,145,535,532,516,815,85,616,369,952,246,634,639,646,849,969,548,960,36,639,117,597,629,88,831,618,952,42,799,152,152,262,410,552,356,209,238,491,410,506,845,129,898,489,711,825,935,998,596,814,525,602,490,980,582,20,641,33,738,484,296,978,864,172,189,625,680,774,695,20,906,729,134,36,959,453,179,128,464,760,967,598,973,269,821,26,37,424,673,413,960,853,848,597,268,53,358,629,329,670,508,347,45,517,539,950,984,415,725,208,355,347,941,817,481,732,211,618,326,663,604,70,790,185,266,270,533,786,202,331,768,88,841,919,419,547,780,839,539,881,85,887,958,220,283,137,555,345,577,383,183,265,746,233,709,557,50,356,506,376,943,471,828,671,920,826,92,336,277,998,744,212,173,490,349,858,665,825,234,224,577,685,568,796,818,933,145,511,535,54,423,784,781,879,737,454,172,191,195,999,156,984,374,959,61,226,228,887,29,365,531,467,263,124,456,842,113,598,845,491,558,845,864,130,751,239,973,923,592,568,83,992,47,330,376,349,945,883,214,882,551,507,190,682,351,348,907,135,762,769,650,104,517,449,223,732,561,429,982,43,165,933,749,325,907,452,369,150,897,487,889,137,797,334,113,718,509,748,654,384,792,465,711,960,309,493,436,731,289,202,89,966,80,536,837,82,81,735,138,684,728,819,236,836,33,107,728,38,559,370,881,362,945,168,363,274,471,125,488,234,304,903,147,612,684,486,619,829,472,808,676,445,247,286,850,893,876,643,301,40,936,720,688,575,296,306,729,321,114,323,632,208,860,871,275,5,841,533,54,542,788,654,220,120,411,123,509,43,751,514,20,656,907,450,865,504,109,835,999,406,677,270,271,636,801,498,116,709,263,67,346,803,185,628,495,514,743,741,551,71,34,593,109,548,928,603,744,264,841,224,872,210,16,561,780,977,619,28,544,562,798,765,831,253,139,725,615,113,666,704,449,378,398,572,492,503,963,968,724,579,756,112,33,755,209,665,619,393,657,313,649,166,871,857,340,65,614,616,111,905,873,915,270,237,698,162,417,322,811,935,48,793,535,463,790,944,458,446,51,840,140,875,476,785,862,277,10,528,210,252,581,901,959,389,700,716,889,621,625,444,502,699,779,372,203,287,813,810,441,545,796,196,396,684,80,972,5,111,669,635,327,617,128,48,683,150,330,552,554,654,493,42,697,502,868,589,90,791,652,50,92,481,594,303,770,771,554,161,111,777,159,170,318,372,44,852,555,918,487,516,268,822,874,468,140,101,954,85,558,670", "129,369,760,572,789,216,610,149,922,935,922,231,282,179,347,443,559,484,973,752,288,441,783,968,210,874,354,485,545,551,123,192,662,816,710,35,220,110,543,66,709,798,790,428,207,319,196,361,131,397,119,549,491,530,943,773,806,433,153,571,282,687,490,131,47,610,965,347,172,35,519,161,655,551,168,73,563,200,693,502,490,913,455,324,800,107,73,756,165,499,282,616,310,423,659,529,473,956,30,942,148,550,469,390,624,586,668,518,114,321,632,133,996,312,933,423,614,824,640,324,475,310,387,658,941,261,714,346,749,679,978,791,269,638,160,741,607,115,66,209,899,205,941,692,392,132,258,36,654,300,628,696,757,579,80,308,277,826,974,31,545,459,337,172,364,110,482,60,293,730,58,440,795,940,135,591,655,845,788,192,945,732,504,590,212,153,25,43,45,87,791,599,522,233,304,64,443,447,203,431,184,255,910,165,241,349,353,607,66,887,789,219,916,653,634,217,379,859,471,31,755,285,607,729,778,855,734,492,162,742,37,715,19,109,176,27,531,157,821,972,43,454,109,551,541,713,626,47,323,782,412,610,747,836,38,769,654,742,951,396,364,724,320,46,712,705,542,66,985,591,840,212,919,469,987,388,956,442,345,460,429,667,371,408,280,546,219,642,20,895,820,549,836,687,128,479,732,866,882,547,821,706,514,171,556,786,665,380,120,849,827,776,670,85,458,767,801,51,182,612,144,326,544,231,803,992,189,233,123,180,449,56,919,301,83,843,985,424,958,701,115,562,811,165,310,459,588,172,948,143,606,832,871,128,976,60,831,664,246,460,975,191,392,254,963,272,950,500,586,126,967,889,595,385,454,440,985,4,212,310,33,180,53,617,819,544,387,630,390,152,646,885,611,226,652,419,406,825,738,309,793,835,208,774,780,247,424,281,463,205,771,284,346,480,851,861,555,425,158,467,685,644,0,6,511,529,843,898,166,419,758,296,137,573,230,1,696,7,530,791,55,632,944,782,578,528,965,155,964,508,14,87,267,108,208,856,15,995,712,680,836,745,969,326,522,119,396,179,725,146,390,225,18,857,374,606,184,485,516,128,216,573,739,960,859,867,737,443,828,907,510,814,910,65,835,10,829,406,711,498,180,686,170,258,651,812,11,338,842,476,79,480,49,902,312,266,791,348,183,947,715,319,853,321,822,898,382,34,992,576,702,303,645,743,682,850,404,241,608,129,529,494,790,714,807,238,929,248,222,84,690,113,918,245,588,860,872,419,159,952,215,661,82,106,396,988,617,289,317,19,645,801,720,470,987,207,738,692,465,600,141,907,126,206,444,506,262,370,143,241,469,879,661,863,885,831,659,646,335,980,221,548,895,617,464,102,516,241,535,18,614,520,217,279,961,381,864,583,447,264,882,847,931,338,132,865,317,547,787,280,643,245,19,409,887,262,968,207,411,420,906,53,129,441,630,175,673,590,466,881,151,380,50,698,331,206,978,461,266,435,834,235,238,59,211,716,98,960,648,332,733,316,759,779,643,700,124,625,804,89,113,359,418,765,708,968,924,137,60,69,657,217,236,954,667,318,859,935,918,219,910,893,208,59,436,971,28,983,716,268,103,955,658,241,490,209,35,952,548,86,875,722,702,795,965,610,317,127,477,742,47,71,681,718,949,894,882,978,320,4,348,949,928,566,47,198,579,126,472,834,670,305,485,524,760,349,199,532,783,638,534,766,714,466,35,74,475,298,109,607,794,561,110,697,871,682,733,611,723,884,685,397,254,905,707,819,150,145,926,501,413,376,252,644,788,147,607,219,163,830,227,891,170,39,766,475,880,392,752,702,667,1000,308,657,342,61,364,560,837,623,758,711,868,9,215,380,452,920,279,967,664,541,76,931,668,703,917,28,861,903,135,874,746,396,420,517,60,975,492,251,114,797,432,566,404,431,518,237,884,618,814,152,620,857,409,474,218,371,937,781,544,959,64,48,119,400,263,464,724,226,440,232,103,181,6,222,233,568,409,712,549,466,657,472,806,511,490,858,540,105,63,683,464,296,430,200,856,123,631,497,730,614,249,214,936,271,463,74,281,140,769,754,949,668,478,134,219,425,469,517,495,105,519,202,326,595,75,178,728,636,824,50,559,146,734,556,867,986,431,451,496,213,825,716,158,634,36,121,16,785,606,902,788,644,657,964,956,211,447,919,496,134,473,242,847,631,555,613,359,956,405,304,598,219,506,955,345,761,6,331,183,606,582,480,306,780,811,954,291,832", "637,25,96,399,268,738,344,993,577,158,945,750,376,314,579,71,456,268,579,995,243,645,386,338,673,231,625,351,369,984,992,28,68,801,559,68,538,79,33,553,181,754,824,728,69,87,770,179,756,427,131,89,797,728,401,848,831,710,740,759,336,382,886,261,364,753,674,279,97,911,136,715,227,340,729,269,512,952,914,790,476,799,685,353,937,921,749,290,106,782,691,268,183,360,289,55,384,921,322,698,982,157,154,842,466,923,853,405,533,747,672,960,552,60,366,359,543,363,728,458,757,232,678,941,160,19,24,5,248,664,318,326,698,494,529,388,705,783,986,956,480,309,423,30,488,658,167,153,903,821,867,615,796,157,575,40,985,634,330,685,60,127,188,848,720,671,578,120,619,433,922,593,886,143,909,798,986,574,999,390,652,608,842,388,858,196,375,234,791,365,533,213,41,89,325,328,594,205,550,421,399,247,151,429,655,795,288,803,617,777,471,624,135,931,357,982,88,229,486,570,520,983,571,538,707,133,458,891,290,917,961,122,123,87,843,280,408,230,113,90,676,348,265,461,3,637,278,256,477,590,751,38,151,722,811,573,464,368,124,978,880,73,412,15,536,250,992,44,995,923,790,851,114,899,762,853,942,386,274,873,754,275,72,705,144,102,507,604,656,531,371,521,475,337,153,738,597,276,924,783,289,739,287,231,35,439,707,533,460,931,429,19,770,82,228,639,473,723,103,465,31,716,508,145,764,357,686,39,738,674,225,107,401,48,936,107,935,291,719,139,117,711,729,774,485,233,681,382,385,718,260,338,74,674,422,441,279,823,491,805,172,813,96,236,251,233,5,163,77,39,866,216,762,218,247,834,794,807,317,475,951,568,731,532,215,39,620,24,54,296,571,315,578,951,830,960,478,808,273,278,412,795,613,592,454,889,169,265,258,454,363,63,559,70,316,942,817,617,835,582,470,621,6,0,469,440,731,47,743,302,374,231,121,19,632,942,591,849,161,419,486,5,992,798,180,493,941,240,897,153,469,427,328,216,210,919,212,240,783,640,746,156,828,32,395,841,525,803,616,803,161,485,855,966,986,64,608,984,671,63,333,382,761,505,734,588,993,552,941,35,294,92,134,806,545,647,267,141,7,340,455,766,636,845,550,803,359,523,140,448,346,165,914,188,625,970,171,416,683,689,952,252,16,628,95,949,473,657,288,85,771,965,983,576,587,8,559,345,721,310,33,733,4,383,862,279,23,803,827,712,824,398,750,662,114,651,505,638,193,423,76,899,956,765,924,771,91,57,957,468,228,660,775,388,994,966,723,860,226,498,500,3,636,426,112,590,658,222,89,789,260,677,797,943,841,685,547,410,335,956,927,145,480,333,635,666,889,134,253,762,518,644,921,211,300,117,587,212,409,895,426,977,725,83,92,430,76,867,951,670,572,391,134,280,235,25,784,222,149,464,353,705,243,668,16,339,661,511,421,63,868,702,426,774,224,309,680,457,652,74,128,89,22,478,626,750,897,808,660,164,192,177,68,315,669,241,101,61,687,546,220,340,772,898,43,956,130,206,791,50,771,656,869,986,789,390,670,294,322,41,753,271,265,904,637,96,866,8,696,883,639,74,97,228,851,58,985,953,243,60,174,2,210,521,795,128,581,104,469,197,39,353,443,979,28,560,373,461,695,36,5,95,322,468,164,425,606,145,499,28,877,482,812,498,753,907,956,89,50,543,750,502,266,115,131,186,333,186,154,217,597,522,220,395,923,532,463,171,609,615,609,425,569,520,990,706,394,977,166,297,76,238,533,604,966,756,731,11,866,434,19,957,577,394,795,475,75,963,280,565,754,690,302,192,933,419,146,603,304,403,952,490,911,30,236,872,439,49,482,854,43,339,948,268,179,527,244,758,24,855,770,770,934,418,107,172,968,967,679,518,690,926,875,147,673,430,443,7,1,188,211,607,95,424,205,614,308,173,251,24,251,240,746,908,202,255,331,837,887,110,712,899,173,387,68,180,233,807,997,73,739,404,238,834,165,10,75,313,80,172,523,942,269,423,663,268,995,469,60,115,307,556,66,77,949,860,697,511,769,703,542,124,334,235,831,1000,542,95,81,468,151,291,199,989,901,254,393,390,196,696,473,839,174,48,182,199,795,388,959,973,254,480,522,696,223,567,134,65,116,895,685,311,218,211,821,796,315,865,684,867,381,234,797,731,370,872,40,680,160,416,533,621,772,761,151,301,133,257,24,270,367,459,735,69,632,49,480,898,493,533", "876,421,410,353,887,994,751,511,634,519,364,195,438,363,318,760,689,562,852,210,347,489,969,931,584,285,997,985,34,613,983,674,425,443,502,894,171,279,447,123,849,986,38,613,152,203,505,605,494,856,847,118,149,164,412,355,647,18,940,265,653,954,453,787,453,757,806,450,818,855,526,161,570,485,831,728,805,780,567,764,335,162,491,578,53,637,582,595,495,284,470,822,17,265,202,834,906,222,574,809,723,735,245,381,56,117,721,518,697,112,316,532,809,184,19,47,444,127,233,915,596,959,670,805,418,312,51,716,712,226,435,187,725,704,582,548,984,606,707,9,374,179,798,520,92,713,899,625,349,250,265,61,986,587,190,832,405,758,828,386,587,224,941,808,338,941,660,413,702,509,240,492,577,52,922,636,454,325,242,33,34,626,379,854,530,812,537,615,948,516,856,509,68,800,347,9,922,382,697,59,933,960,681,475,783,832,783,347,962,195,605,543,677,537,158,208,737,137,54,584,17,570,318,944,924,481,149,788,660,694,889,77,583,527,503,57,498,469,698,48,582,877,761,190,625,274,497,469,281,191,369,435,665,986,87,749,869,788,140,463,666,164,774,975,740,685,851,584,39,668,212,446,36,754,431,462,143,641,793,695,514,333,478,433,561,619,638,808,111,696,227,430,195,537,850,505,56,125,976,322,254,806,976,904,310,237,888,284,374,705,892,92,237,382,425,79,457,67,687,551,269,741,849,166,926,740,917,921,803,58,975,355,780,490,251,262,639,133,32,741,488,71,963,332,71,770,755,354,775,798,14,344,573,77,736,695,145,947,378,775,199,225,283,879,230,738,535,759,811,558,466,996,612,807,642,973,226,895,71,16,789,740,657,273,599,131,226,138,307,651,268,57,12,181,13,221,69,320,497,999,774,448,438,907,207,805,949,627,822,8,880,7,919,207,241,545,477,923,457,599,766,350,511,469,0,362,248,846,188,177,654,497,367,260,551,794,451,637,909,283,341,748,333,411,672,570,791,656,113,453,623,765,173,895,851,30,802,402,751,884,398,834,389,628,783,832,310,642,416,207,425,732,717,658,902,200,509,11,214,962,31,515,668,475,925,235,29,808,399,845,23,895,922,817,888,930,111,962,863,727,80,913,866,463,746,211,368,478,494,869,672,92,53,724,280,702,816,56,372,292,56,491,449,124,127,920,282,533,525,229,363,897,761,632,17,293,623,984,714,937,407,547,266,223,111,210,710,815,942,746,15,586,860,750,459,700,906,181,264,405,234,731,317,147,645,251,242,324,677,489,827,16,208,7,199,918,766,403,29,83,980,431,109,240,345,118,216,822,630,628,799,372,632,435,861,987,969,770,113,313,767,524,997,637,801,366,195,96,596,263,565,879,153,365,236,888,123,473,648,23,119,207,945,466,623,983,218,426,951,904,974,10,102,59,130,101,590,972,685,276,268,780,24,295,972,83,438,896,186,88,419,253,344,700,984,167,512,486,442,289,572,474,276,683,668,818,142,272,117,972,313,486,859,420,307,853,695,936,109,962,939,456,659,539,473,355,148,304,591,30,413,158,371,461,476,529,944,760,917,965,945,535,364,887,62,251,16,188,296,679,100,481,207,565,174,643,294,418,806,517,694,998,105,727,294,356,252,97,367,982,483,151,297,931,770,525,442,114,741,683,135,894,37,860,772,446,789,94,174,927,663,221,761,989,116,162,93,634,530,134,252,217,444,393,376,357,625,753,368,282,774,861,612,757,659,529,340,325,673,203,808,232,948,801,693,809,90,220,5,86,249,327,375,544,864,496,723,14,786,477,951,823,282,130,705,162,243,721,477,690,94,585,6,543,405,866,802,94,599,909,936,579,604,415,737,407,59,263,544,624,893,306,369,615,290,994,463,367,214,34,508,538,675,383,692,852,108,502,275,539,184,980,608,554,655,715,209,312,509,721,418,581,704,396,453,622,364,171,788,736,265,321,542,820,930,649,856,831,733,758,628,387,994,221,676,818,600,694,477,48,927,119,405,391,358,840,397,405,802,292,246,575,329,821,516,77,970,376,466,420,508,291,692,771,218,398,347,321,584,485,467,606,876,572,864,51,549,35,366,311,388,515,507,902,530,11,501,205,824,269,283,612,221,167,501,498,452,473,863,440,92,82,356,61,782,588,762,244,288,295,988,631,718,384,272,48,7,865,895,201,947,708,151,877,962,361,471,643,791,884,308,476,16,139,47,616,146,514,847,435,766,908,374,450,767,603,165,525,801,481", "293,622,175,828,224,171,510,918,401,881,507,347,168,959,85,65,189,740,98,52,157,219,829,610,803,874,105,113,659,308,906,955,714,909,796,669,76,221,785,325,306,556,663,490,396,304,716,55,836,183,571,683,106,457,326,550,185,740,404,161,432,926,300,197,359,734,876,491,898,90,431,61,754,780,410,202,961,246,818,196,469,230,721,279,268,20,357,112,36,121,947,206,995,762,36,413,868,956,652,620,140,850,622,739,308,821,951,38,258,572,513,886,906,887,901,299,607,137,184,575,156,270,232,41,241,428,786,856,90,869,401,532,579,269,305,290,168,821,878,633,861,910,932,564,371,126,160,985,14,684,941,878,361,480,507,768,142,700,421,132,646,152,452,219,326,437,914,872,636,579,706,485,103,267,815,184,305,554,317,428,790,693,634,67,664,914,503,409,949,391,60,577,287,434,627,635,717,192,392,669,403,873,798,769,210,495,635,272,507,82,220,334,708,289,281,903,73,482,225,478,916,954,713,688,894,258,909,48,911,120,989,781,197,458,403,189,327,819,662,812,654,857,573,412,167,377,190,636,336,800,178,813,697,22,974,148,371,74,877,799,303,995,808,214,589,116,118,358,880,584,375,553,563,374,891,840,28,561,493,27,674,570,338,432,740,989,698,291,52,259,475,726,888,152,161,125,621,207,299,672,21,927,918,851,823,948,399,296,364,575,986,414,233,529,896,488,469,313,792,123,925,951,255,269,969,491,578,568,884,842,565,884,383,182,148,57,606,923,321,999,4,205,262,143,879,621,777,1000,290,380,222,762,550,848,928,341,232,229,333,347,110,925,161,660,724,904,288,387,708,329,81,983,799,24,641,479,908,265,331,904,584,544,990,701,964,184,350,282,701,685,96,477,87,132,700,155,294,496,32,534,229,350,955,344,66,790,17,513,80,122,118,885,698,37,594,349,517,505,840,92,469,104,529,440,362,0,796,362,397,198,904,315,849,690,509,226,120,293,100,438,349,432,985,815,39,568,166,403,222,377,65,29,473,574,917,50,698,194,157,729,918,744,655,657,468,349,850,534,507,352,909,225,177,847,670,415,129,984,639,912,618,933,977,9,406,618,349,507,600,752,9,424,371,45,219,860,733,812,728,563,196,137,455,440,694,601,926,838,111,105,946,532,417,804,650,270,130,719,813,892,440,967,596,414,209,368,733,349,537,350,936,700,213,70,606,643,941,212,710,904,802,310,341,406,485,987,272,877,50,78,254,50,108,117,214,507,168,316,569,51,385,39,585,122,315,509,340,907,830,872,497,954,877,907,2,95,707,379,619,189,851,229,55,321,879,142,455,175,106,761,858,152,465,22,402,170,452,290,678,277,4,401,54,143,404,849,399,722,390,426,861,301,136,86,645,279,391,962,448,23,771,754,526,730,398,423,452,937,711,966,279,386,999,933,698,853,355,339,110,58,133,284,977,793,70,985,707,872,283,75,310,757,331,126,655,947,163,184,308,25,423,596,305,362,388,676,209,560,964,517,876,19,89,347,345,150,527,245,929,816,289,24,791,718,279,69,918,771,332,498,368,743,563,472,89,175,610,95,214,685,237,590,575,791,295,421,678,42,809,472,559,467,200,495,93,89,850,205,644,153,297,528,292,468,45,358,32,391,393,343,181,740,829,911,306,581,884,293,272,128,685,650,267,186,578,661,772,863,732,986,554,772,119,134,13,831,56,767,22,69,363,916,448,83,241,589,918,444,399,228,392,564,651,638,964,651,931,5,369,298,329,228,251,761,508,216,816,241,394,299,195,974,921,453,286,699,785,837,658,769,39,280,974,61,826,527,666,230,689,685,169,811,15,869,291,109,294,993,434,175,39,467,514,770,289,750,122,435,900,785,912,602,104,274,724,157,829,25,452,902,446,452,938,251,70,417,129,927,209,613,540,334,977,306,580,446,730,300,290,883,649,882,976,969,888,248,133,55,485,685,745,604,565,544,681,176,647,611,285,383,477,505,762,469,737,562,820,374,373,409,782,433,411,398,529,898,364,61,754,714,948,971,130,431,177,513,76,894,600,324,64,802,869,971,966,409,135,678,526,383,282,550,465,519,873,460,373,732,241,343,38,494,875,843,266,370,115,267,869,37,317,674,590,85,194,250,773,329,186,255,330,147,391,727,616,696,924,385,183,869,22,599,346,979,752,962,225,623,708,423,314,464,944,174,377,714,138,808,482,108,821,457,443,959,22,777,463,377,104,283,569,804,509,848,658,587,9,86,800,796", "194,846,731,763,574,174,120,356,917,517,932,194,75,641,86,523,414,571,81,831,767,409,420,825,205,90,326,804,893,306,631,315,855,601,846,527,567,83,204,7,608,715,464,75,958,311,240,644,448,238,673,468,429,420,416,43,867,124,363,507,627,477,454,254,865,426,461,321,798,838,148,334,756,157,773,935,287,698,330,718,53,719,990,919,881,315,938,421,831,107,116,702,283,424,303,967,74,491,795,686,108,309,228,993,678,351,487,329,453,167,278,886,631,701,131,656,870,373,106,422,33,260,455,425,857,703,496,107,711,839,959,900,635,180,697,559,900,651,565,765,460,308,994,583,697,503,760,205,315,538,967,328,871,36,558,849,902,655,104,842,721,232,485,706,178,104,588,874,573,567,78,731,563,34,814,486,42,8,886,19,211,930,475,220,766,180,788,483,810,918,866,829,478,398,565,257,427,86,313,686,436,304,279,646,672,912,548,306,559,216,76,721,300,238,428,856,332,689,664,372,2,606,928,197,282,893,677,846,404,434,118,520,854,215,414,893,718,870,256,661,124,157,727,258,64,61,420,546,824,593,803,630,909,963,273,781,289,323,167,870,943,539,374,553,417,550,438,410,657,587,249,143,968,585,143,921,281,612,428,623,858,480,370,216,101,3,143,810,749,593,352,107,590,171,671,259,585,609,813,74,888,565,261,455,229,674,506,120,612,923,155,713,492,356,498,278,225,973,651,920,120,201,614,754,577,214,97,265,129,855,68,729,971,508,215,917,750,452,10,692,696,19,152,787,209,259,508,807,596,276,895,529,209,906,379,975,154,904,801,607,749,989,621,902,464,814,857,994,506,263,47,361,247,93,222,935,903,466,683,199,576,683,345,269,90,963,284,278,763,884,818,514,967,394,99,952,370,594,738,693,82,505,425,911,819,263,234,854,623,650,393,830,949,348,645,195,413,490,752,678,843,76,843,731,248,796,0,519,118,846,874,842,487,752,700,144,661,380,15,236,215,872,742,786,943,160,739,508,535,522,720,854,94,590,852,77,535,45,76,277,218,730,863,386,962,484,259,745,914,474,565,155,196,328,395,792,888,343,404,253,916,308,602,40,738,320,246,257,456,869,279,709,254,14,631,678,220,136,890,841,450,294,743,562,662,408,685,966,967,463,44,932,678,61,507,754,299,854,79,89,410,398,28,844,109,443,132,489,686,613,874,108,157,512,537,622,615,364,200,56,819,283,697,121,605,241,205,15,126,897,269,922,858,401,373,368,560,354,33,472,357,891,7,360,209,724,599,585,221,278,182,546,540,665,748,517,814,434,540,229,431,266,26,896,49,211,62,627,90,677,708,969,756,568,488,188,983,185,667,596,257,234,269,913,303,118,679,571,516,647,11,650,214,19,937,520,40,336,233,914,352,215,588,304,406,206,274,397,781,632,432,530,796,16,611,738,31,288,431,337,390,586,521,799,236,905,694,901,765,109,68,852,569,887,396,786,506,957,811,207,938,490,395,977,59,452,937,205,694,780,239,155,102,946,657,192,106,492,272,623,618,732,677,674,290,902,248,541,940,697,875,123,468,899,892,720,958,218,755,507,454,595,714,237,549,466,734,68,626,538,441,306,879,146,922,835,554,114,40,733,524,462,545,848,3,622,709,547,357,388,529,138,331,114,62,687,747,566,731,657,23,693,294,597,401,1000,134,736,840,383,881,91,817,548,967,868,549,411,269,290,707,843,373,875,242,182,287,510,225,379,838,921,32,689,408,52,449,878,378,262,73,269,197,459,766,15,120,292,165,262,612,391,27,887,808,455,994,702,532,35,630,312,16,112,877,512,547,684,560,176,342,899,715,93,24,59,611,889,701,154,355,258,762,829,406,64,227,108,123,453,331,777,96,322,894,523,564,180,26,721,119,496,842,660,34,118,790,116,529,234,43,455,111,415,292,792,810,495,146,784,208,944,101,757,571,906,432,348,854,878,669,834,575,286,618,686,245,419,110,762,670,378,782,103,10,895,944,906,398,659,919,109,840,689,372,609,432,674,69,519,37,833,666,340,737,911,280,436,636,864,731,122,920,259,437,754,35,365,42,925,338,705,626,669,844,626,271,825,939,377,489,527,3,823,14,186,550,965,497,191,231,952,157,568,961,747,759,688,221,720,767,528,154,343,549,230,136,430,205,686,309,162,974,589,875,972,760,739,426,360,555,844,450,691,237,269,587,639,483,271,464,773,495,580,29,703,945,644,500,773,743,336,438,525,375,777,371,177,977,966", "102,756,591,588,308,216,104,447,341,629,164,552,439,231,951,667,558,176,971,492,88,80,295,864,110,359,479,109,797,308,971,285,698,538,708,248,917,848,490,603,561,911,676,627,3,955,974,475,474,392,422,946,560,712,758,174,457,207,193,476,906,5,273,827,303,707,191,160,198,100,12,388,78,830,931,437,84,203,140,310,634,462,557,160,880,741,584,160,560,107,813,573,106,596,519,168,903,284,753,767,297,807,561,751,885,497,182,540,773,613,840,213,59,881,462,520,64,664,569,880,950,392,700,541,877,803,228,55,514,159,535,631,670,370,427,62,756,756,627,582,937,386,197,930,447,523,264,893,102,562,51,685,692,34,36,635,902,94,243,147,960,787,562,56,518,13,786,314,33,769,856,317,3,321,135,184,995,782,107,880,610,510,29,535,96,817,691,443,229,487,553,803,512,436,549,17,403,99,816,224,377,545,23,850,707,415,434,530,907,44,38,688,937,562,672,681,239,123,207,12,297,997,355,519,4,627,983,300,512,435,33,188,52,898,975,628,89,807,538,237,660,949,921,344,96,754,114,358,531,720,63,891,479,541,564,401,129,107,918,56,788,132,529,903,995,986,796,111,81,502,425,857,202,231,847,307,588,770,338,371,320,877,31,116,279,481,339,166,306,670,256,413,950,539,761,207,215,465,537,489,558,579,842,974,368,27,272,916,318,746,279,89,926,179,812,733,655,988,660,707,513,564,550,122,762,210,619,89,801,484,309,673,851,357,300,245,238,970,523,933,95,933,757,64,68,65,724,6,861,600,33,116,57,749,702,686,360,263,161,346,708,847,227,196,249,355,461,830,20,52,11,640,181,227,87,139,888,507,914,721,226,836,335,900,685,341,605,802,251,764,79,579,524,601,625,179,80,879,796,500,718,440,108,324,590,401,788,973,566,796,342,474,891,690,579,888,927,846,348,916,881,34,898,47,846,362,519,0,100,50,292,828,163,884,179,374,949,357,268,812,536,797,856,357,745,984,879,482,556,91,507,492,643,878,715,565,759,729,167,623,447,56,128,856,221,367,724,527,435,217,747,26,304,224,178,900,50,758,870,620,521,944,422,766,208,60,161,105,661,748,676,617,698,498,599,674,247,519,937,497,71,436,356,684,86,923,465,189,123,780,526,707,370,672,312,309,297,368,416,924,580,45,786,629,335,543,765,165,558,387,253,22,901,395,313,688,83,558,529,530,813,929,24,216,287,254,672,554,706,319,424,159,84,486,439,744,455,714,22,378,834,294,239,674,717,730,132,597,841,438,967,806,48,345,202,800,237,690,63,527,477,844,564,285,135,42,608,771,64,389,281,308,828,603,711,555,582,500,486,122,423,912,284,669,806,718,524,65,900,866,139,615,880,628,754,420,671,68,213,732,843,751,244,75,777,729,374,633,517,462,408,109,167,842,861,826,525,16,108,405,704,593,866,807,779,746,220,402,633,386,334,65,82,470,517,330,347,841,21,846,672,777,323,453,516,449,669,494,766,391,971,331,948,363,165,557,601,239,966,49,616,41,529,508,377,956,118,657,894,965,487,316,877,851,603,542,128,764,397,54,225,640,898,464,677,845,528,573,57,411,861,206,960,794,364,817,796,619,534,563,705,88,588,779,642,812,250,369,388,21,3,197,92,881,296,682,670,595,118,730,401,779,905,644,244,948,686,232,979,420,239,56,787,206,135,513,359,334,967,519,371,84,475,692,761,927,418,967,121,470,589,116,663,6,830,368,313,574,26,757,943,115,338,296,208,790,898,402,243,106,537,383,780,511,101,375,688,401,964,891,532,794,851,229,772,940,313,297,76,450,116,423,406,137,43,100,263,130,846,570,594,126,269,116,322,991,996,531,849,612,325,621,170,32,859,721,618,586,684,176,469,21,611,9,923,681,612,925,390,887,404,48,74,306,400,628,30,604,762,634,176,366,26,122,573,667,162,216,323,615,630,468,530,574,490,891,137,176,814,122,721,809,327,946,291,248,634,109,60,242,265,252,773,705,654,326,975,519,638,292,59,651,100,532,418,248,907,863,257,505,748,218,987,714,245,511,328,886,790,945,399,275,310,40,395,854,551,306,78,199,952,237,830,991,332,254,618,393,726,167,459,682,832,82,12,705,957,779,342,499,73,254,799,513,848,829,284,666,206,492,845,734,512,423,523,997,147,517,131,124,100,855,592,924,599,860,334,287,472,498,553,150,782,256,490,211,757,35,588,444,589,214,403,350,810,313,304,455,627,30", "153,686,318,735,86,51,959,999,552,451,869,823,314,604,627,99,490,631,50,514,316,519,115,69,506,560,811,599,879,873,188,919,946,462,589,281,745,590,757,143,106,88,3,23,190,708,827,550,459,330,576,427,416,769,809,257,399,726,493,448,13,34,403,572,979,475,880,116,248,322,151,12,614,481,383,339,767,196,513,820,849,686,325,527,268,162,741,792,414,591,384,500,603,862,719,920,696,27,384,926,541,805,519,624,593,383,204,68,660,865,572,809,378,132,612,53,961,273,355,57,617,863,668,317,258,666,708,83,174,419,129,965,640,620,827,219,719,232,710,6,817,9,632,583,993,40,290,227,386,268,322,255,582,839,281,550,199,382,466,814,147,690,675,671,690,80,336,164,501,144,903,34,773,565,952,479,638,5,510,512,763,22,657,254,440,217,285,336,498,263,369,663,238,590,513,936,170,256,327,221,523,858,480,105,511,267,277,881,789,331,712,580,481,603,427,832,333,632,516,856,350,396,946,580,828,671,380,607,456,210,303,124,416,74,152,688,443,480,624,124,585,295,498,78,585,46,172,275,932,76,608,397,251,696,404,859,393,378,995,61,785,884,236,225,250,294,369,414,826,691,214,531,956,194,410,638,150,378,766,335,484,582,995,309,364,858,278,108,490,182,712,233,382,964,640,381,488,473,857,965,12,449,786,947,849,55,489,629,268,178,941,406,61,206,450,595,914,852,116,854,168,562,410,219,766,78,428,970,819,146,694,525,39,816,989,327,552,904,225,212,985,776,579,194,984,70,172,528,103,150,578,261,117,729,120,706,181,555,532,338,201,98,39,486,807,401,797,575,919,139,371,717,80,329,642,887,607,314,100,114,172,231,871,860,750,204,534,832,931,772,80,817,734,647,302,743,404,723,899,793,380,771,488,201,714,38,971,826,235,574,993,550,186,595,716,683,712,516,670,373,45,380,166,743,188,397,118,100,0,254,565,946,777,482,625,377,70,305,802,735,152,358,962,486,156,807,493,195,832,874,285,921,774,604,116,207,404,677,212,429,964,803,371,996,662,365,710,671,255,855,702,86,251,407,805,655,414,813,985,688,89,524,171,126,683,859,429,341,441,511,997,948,978,668,543,186,779,592,545,854,308,821,635,667,164,962,681,84,350,520,883,791,711,524,184,526,382,212,352,446,874,429,413,779,893,981,553,112,730,957,756,906,810,104,299,8,460,843,792,188,76,6,534,349,849,495,609,894,565,826,420,102,205,734,554,774,206,14,938,732,148,467,99,722,76,176,210,72,385,263,56,233,347,702,689,718,639,418,529,311,176,822,955,202,112,806,533,846,231,824,721,556,958,944,999,811,909,130,560,629,722,995,102,957,226,874,28,601,303,301,745,534,253,251,408,183,273,86,771,32,104,681,663,875,86,684,929,5,975,399,233,114,907,825,525,336,518,598,846,155,166,750,924,699,299,242,58,256,505,982,433,507,964,716,332,696,680,947,935,996,469,318,379,355,606,953,31,298,491,177,923,883,405,85,339,71,137,456,476,585,262,629,372,322,26,31,81,648,281,973,743,915,608,784,495,408,592,133,181,109,688,90,558,795,248,587,403,757,6,481,951,748,363,982,224,863,82,153,779,316,986,235,647,565,331,717,148,474,495,11,487,171,655,691,67,596,287,915,826,466,817,545,520,242,971,443,202,930,330,451,130,934,358,734,358,247,541,774,39,647,604,357,618,99,668,689,553,608,60,863,401,432,15,389,233,587,814,210,873,244,350,5,787,876,918,327,601,432,885,535,630,291,544,362,546,445,640,285,799,391,595,276,300,361,255,561,693,548,596,330,711,120,720,741,630,953,367,711,65,300,697,934,62,168,888,962,522,845,280,914,136,884,892,772,520,246,659,186,70,712,116,116,894,450,838,441,95,186,931,288,583,6,14,571,736,376,220,339,898,328,529,111,620,592,888,377,311,863,3,735,175,64,338,675,674,385,423,777,989,349,762,462,821,218,203,984,325,831,398,645,346,656,59,857,449,597,1,864,696,433,895,755,989,735,899,535,148,582,332,912,260,118,226,226,717,621,287,84,853,993,480,316,380,482,834,773,865,209,664,332,328,735,367,809,264,465,932,139,227,294,84,795,636,118,502,863,405,574,99,63,671,910,605,928,997,414,668,964,560,366,363,862,805,230,439,947,593,117,627,727,147,372,46,349,172,423,876,211,848,245,509,363,673,496,44,822,434,255,665,279,26,332,29,226,764,247,193,663,551,718", "903,176,731,331,348,175,131,173,404,427,183,598,507,131,479,818,601,377,457,213,639,904,490,283,419,382,465,901,517,274,875,980,564,42,582,199,305,3,59,434,315,953,91,991,17,388,309,632,46,766,681,110,252,54,971,847,810,180,11,655,791,313,634,666,450,568,405,181,390,559,777,192,199,57,657,66,834,271,677,566,676,296,29,295,135,969,887,887,837,68,209,686,890,710,125,220,966,382,925,274,465,75,766,705,96,52,277,415,616,731,774,94,906,753,296,992,860,659,502,636,349,206,303,893,428,546,50,941,237,585,419,578,844,824,62,889,324,824,550,98,614,403,207,876,242,363,630,265,807,150,842,529,467,796,787,480,945,604,440,450,668,775,926,326,905,379,482,530,995,800,50,739,326,729,403,900,576,84,729,217,437,858,760,721,810,672,859,206,852,296,605,620,667,182,940,526,210,631,422,795,542,839,815,142,537,167,732,754,702,746,437,547,330,950,410,317,50,78,463,355,355,959,922,159,139,437,430,375,585,531,111,485,95,433,828,889,971,95,371,861,505,264,605,56,399,558,642,214,929,315,680,35,848,681,444,411,759,110,420,400,273,125,303,243,97,184,665,458,888,370,852,748,982,778,119,199,407,480,935,889,739,620,879,946,53,902,601,806,768,578,228,735,506,153,892,551,586,903,704,584,669,845,851,457,767,817,900,378,949,879,712,11,21,947,216,857,562,338,962,172,167,5,12,709,478,480,109,708,233,485,264,885,579,851,664,442,96,152,384,691,833,352,527,885,732,788,485,943,476,650,144,438,394,756,694,588,447,385,21,720,793,827,701,426,25,798,322,80,797,426,220,122,495,887,971,890,185,58,784,290,933,914,214,871,833,426,617,873,447,893,26,826,428,466,522,904,271,670,881,707,108,712,701,914,921,326,368,309,217,837,49,768,737,601,8,216,427,626,7,940,248,733,419,302,177,198,846,50,254,0,123,8,27,437,594,126,14,469,462,171,792,792,990,68,816,382,535,760,929,285,509,41,33,579,452,868,664,974,652,835,788,467,39,58,900,380,85,798,162,588,712,204,409,136,81,118,831,840,132,59,539,878,431,802,44,792,200,950,92,354,263,763,634,410,938,450,416,904,595,89,313,833,60,65,479,700,868,958,836,638,165,393,368,215,652,434,893,850,22,941,563,432,327,643,488,863,59,432,210,245,930,468,733,139,521,523,283,727,428,752,224,294,251,678,251,474,200,318,773,793,291,773,828,496,845,582,759,145,339,557,33,663,137,71,422,663,835,981,826,287,96,636,819,301,949,784,814,705,458,236,834,503,545,355,409,41,903,431,786,348,981,226,220,646,417,532,631,595,308,538,428,186,513,820,380,917,700,626,648,208,670,360,995,116,601,854,890,793,379,394,166,682,374,918,411,422,789,492,218,158,881,603,451,246,112,487,241,468,814,716,703,928,602,521,664,803,280,510,906,910,174,889,782,925,849,288,476,602,201,61,968,701,867,406,791,172,545,694,47,52,238,275,588,70,427,156,121,246,253,357,763,686,21,540,652,594,392,41,251,6,880,763,237,74,101,321,750,985,864,254,30,292,741,759,32,345,45,103,732,213,929,323,519,318,945,800,336,459,409,523,949,599,332,399,864,292,758,467,415,196,500,803,367,469,288,119,854,838,328,286,305,716,661,710,262,612,273,628,701,755,556,740,327,503,443,385,714,793,820,985,210,79,942,612,703,995,646,360,309,668,605,525,512,255,591,21,592,39,764,685,926,338,922,261,271,50,972,769,104,536,312,654,113,191,637,961,453,290,474,609,805,118,318,133,146,742,678,930,365,647,116,99,478,673,923,291,342,469,749,799,810,269,841,927,311,24,498,483,792,895,919,560,881,155,392,882,501,731,691,95,883,955,128,264,380,763,947,286,830,801,24,529,147,364,458,687,499,903,293,852,854,715,933,538,426,131,213,649,58,244,707,837,574,194,144,200,199,477,866,431,344,624,422,660,647,307,796,233,183,920,996,744,830,424,449,903,674,469,462,958,817,848,121,741,780,469,221,325,147,602,561,841,759,577,911,49,595,826,635,924,839,473,841,738,858,149,623,502,728,209,422,908,510,864,287,35,546,338,48,77,711,670,570,74,519,429,443,388,15,499,60,347,921,679,475,819,5,670,112,998,617,153,617,382,26,101,978,339,3,648,512,613,941,176,157,155,901,811,293,242,420,419,849,863,807,387,899,90,128,998,601,986,531,843,268,22,398,976,409,178", "414,583,431,837,942,878,925,125,197,619,839,251,184,973,628,974,424,683,708,777,341,597,22,837,679,907,92,844,967,321,34,398,763,192,225,251,202,546,9,378,317,981,93,267,386,739,678,618,332,552,437,672,199,74,898,518,17,980,198,145,542,460,697,575,901,119,20,798,83,599,678,579,169,99,184,716,81,288,632,362,867,401,808,419,98,309,977,396,710,28,396,360,695,109,645,626,87,976,985,134,45,916,972,23,455,388,931,48,74,970,782,848,687,492,648,574,971,923,772,36,227,754,227,735,626,312,32,344,259,812,640,188,309,157,771,42,46,369,865,59,124,286,942,610,17,633,365,332,483,244,824,58,663,695,51,880,729,405,961,108,744,804,163,900,743,720,357,599,220,642,630,993,870,173,27,47,515,760,992,143,572,444,480,968,521,918,621,405,191,79,276,987,578,515,883,954,815,721,69,336,836,464,483,707,507,620,418,231,361,355,994,516,606,545,309,833,318,415,671,78,152,50,53,482,151,639,858,25,285,938,225,550,432,169,982,154,735,571,583,430,708,909,834,639,966,373,661,670,345,507,510,11,942,273,245,53,936,17,403,301,506,419,127,726,398,365,989,283,271,310,464,746,587,509,302,943,83,755,730,398,983,420,973,152,84,446,346,690,358,832,244,96,265,258,814,757,907,709,26,482,477,945,20,703,228,655,562,595,957,72,569,391,467,208,17,925,813,500,539,662,397,319,583,620,123,420,111,789,480,315,841,786,873,76,661,230,484,893,559,309,377,561,558,505,537,813,984,611,409,879,983,339,153,330,802,576,611,988,928,532,890,160,887,867,587,278,528,214,170,289,799,360,456,195,893,693,413,406,735,582,525,85,229,340,698,251,656,196,125,486,54,908,949,51,160,57,249,506,622,121,574,764,852,828,337,824,669,65,767,849,400,662,722,276,922,934,50,182,715,784,801,309,758,374,654,904,874,292,565,123,0,727,229,574,451,30,657,239,717,25,936,727,574,67,177,655,20,218,685,882,756,818,812,80,726,864,611,801,444,225,59,191,347,875,81,452,772,676,361,263,569,879,403,127,456,565,625,544,421,70,765,658,242,217,61,844,701,636,44,917,471,399,346,365,150,890,110,905,406,202,285,162,839,426,79,656,929,923,497,403,553,876,22,296,731,682,836,706,235,517,514,67,243,760,170,612,233,836,101,770,306,85,341,888,345,411,400,684,38,627,94,313,489,161,630,702,691,101,628,182,903,897,937,415,393,69,706,670,526,913,894,930,502,109,685,102,486,373,989,504,51,743,238,848,725,205,817,551,566,644,8,840,904,236,411,86,895,521,145,184,717,83,824,846,399,300,854,158,12,953,36,100,705,528,532,276,59,125,468,885,928,81,604,69,236,286,523,801,348,554,363,436,750,279,248,162,152,862,188,88,448,159,722,61,878,708,939,865,280,355,922,955,225,501,867,609,177,238,512,275,232,295,848,151,529,619,393,655,403,384,686,123,492,463,151,637,966,154,437,341,715,95,951,525,836,719,720,111,39,619,173,511,913,807,182,740,473,270,769,967,420,175,988,714,420,318,109,753,123,499,413,36,998,562,745,416,150,41,544,260,761,976,617,324,464,995,929,449,35,81,631,547,890,42,431,271,249,464,376,915,949,938,612,93,914,126,462,209,411,636,974,694,901,786,935,439,218,303,409,448,821,659,111,82,566,38,876,252,80,360,196,954,448,388,684,848,11,963,993,480,177,413,665,831,661,684,215,216,775,912,485,857,760,905,462,925,18,433,465,68,516,322,257,784,869,919,869,235,220,271,667,491,828,168,159,196,12,193,983,502,579,598,955,397,741,410,298,799,875,981,501,867,316,73,953,802,466,825,695,778,494,18,166,653,64,498,356,649,204,551,779,519,700,370,612,384,631,168,797,194,519,570,524,328,33,647,596,673,670,562,830,422,599,123,81,609,231,180,916,974,973,415,784,135,845,231,357,252,68,422,766,759,498,736,2,399,555,30,316,329,857,34,979,741,81,69,249,977,419,387,19,481,823,745,815,228,776,802,872,40,171,468,920,810,804,429,704,593,921,856,858,596,355,845,855,437,316,599,274,471,156,190,999,44,131,706,824,63,989,657,721,215,904,190,180,197,570,997,940,358,285,558,141,591,617,443,480,666,733,393,742,736,33,766,838,744,936,324,793,824,415,472,101,655,811,472,475,201,23,360,611,750,520,181,807,572,125,824,440,641,511,926,339,402,63,669,318,641,347,308", "766,435,338,551,839,821,680,654,67,771,943,666,117,433,302,661,500,280,450,265,445,486,507,852,253,266,526,540,13,532,717,518,435,64,864,344,999,972,848,740,734,769,263,474,205,641,598,768,522,68,710,336,135,206,385,298,925,952,950,956,494,119,504,365,884,869,747,13,263,673,489,310,751,326,507,650,112,144,387,568,51,690,923,707,752,793,172,285,729,385,434,607,178,404,697,877,906,144,888,862,382,999,71,154,52,547,12,197,295,103,856,651,590,10,548,229,575,932,200,927,338,991,728,843,859,490,8,438,774,525,80,341,879,950,138,959,164,363,78,429,248,173,205,861,54,988,880,952,280,898,845,94,521,355,455,526,263,696,57,665,755,267,104,680,236,701,46,852,698,889,102,573,138,800,310,635,389,746,180,785,779,979,316,514,828,76,825,645,709,450,946,271,981,421,722,698,79,857,526,634,604,212,951,325,144,912,804,826,570,388,367,270,844,716,196,685,467,515,255,121,923,394,881,210,308,412,271,821,640,86,437,85,574,75,653,482,277,579,154,560,171,767,994,108,119,981,351,504,249,832,140,359,151,671,432,428,251,205,280,689,67,257,515,242,42,791,982,904,634,78,657,646,368,833,98,383,212,849,399,75,103,945,611,807,807,909,812,523,136,333,938,120,639,371,840,739,365,379,754,528,614,611,306,41,696,54,69,745,506,441,595,413,943,421,574,649,349,20,860,480,622,101,641,473,872,447,303,809,462,674,705,675,180,429,747,4,717,825,477,136,533,779,773,224,166,740,154,17,126,454,981,750,553,156,41,693,748,780,112,955,873,256,87,286,187,376,586,75,878,815,841,170,750,414,77,230,419,410,200,298,341,548,997,128,850,748,422,932,512,927,888,59,32,241,858,78,830,683,389,807,86,613,134,490,475,450,995,276,202,967,232,802,189,864,398,851,409,778,880,561,10,145,296,231,497,315,842,828,946,8,727,0,633,718,61,454,338,50,719,432,194,675,478,89,79,115,623,283,178,397,63,706,760,219,828,289,774,948,590,614,835,660,727,286,584,969,868,564,899,893,43,455,301,735,864,550,78,14,83,362,234,764,47,50,298,908,423,819,979,830,803,937,734,375,285,971,704,149,830,261,999,860,225,480,55,279,518,870,38,654,79,292,810,3,806,599,295,185,168,615,66,910,640,796,83,771,640,607,616,816,295,158,455,676,241,490,581,962,993,421,246,186,417,589,657,215,491,348,715,290,93,413,412,180,123,538,563,492,24,494,296,685,673,356,903,961,251,941,844,903,128,635,233,736,428,720,268,516,259,648,57,558,723,785,276,57,621,885,317,706,263,849,673,493,784,42,554,755,494,769,400,596,566,954,59,915,188,126,194,856,472,568,960,830,651,632,973,69,132,59,275,445,208,455,300,924,973,783,743,837,755,80,958,214,271,347,932,273,221,416,504,546,430,754,517,354,502,693,856,935,7,738,956,168,823,585,589,136,523,408,624,571,660,285,160,612,73,23,348,932,180,186,405,363,673,817,721,957,677,442,638,46,985,257,795,277,661,383,42,230,142,63,698,184,324,15,13,250,686,106,78,348,861,1000,58,576,321,879,725,45,648,39,367,354,380,905,914,76,102,960,91,581,604,584,222,98,229,573,686,766,47,3,465,603,764,351,651,401,772,357,66,967,500,812,731,136,733,99,194,213,388,550,755,857,391,925,776,975,383,456,123,394,311,972,939,486,730,703,365,958,656,331,40,924,978,347,599,728,637,818,729,160,760,959,744,211,383,966,93,181,367,882,309,758,415,918,875,705,75,991,732,534,290,367,979,383,33,458,533,962,684,690,965,96,971,884,779,655,843,878,852,594,333,173,632,947,373,646,280,602,22,232,682,279,496,973,169,702,293,775,212,953,969,569,203,150,55,183,625,272,753,941,841,530,438,801,839,989,62,644,283,216,382,798,885,920,324,446,933,479,28,240,771,610,311,426,319,255,834,152,815,708,383,11,434,762,742,969,593,585,639,683,847,839,192,491,577,773,771,231,696,180,573,417,641,812,591,278,174,697,815,984,76,942,9,766,951,322,153,668,863,770,61,812,372,409,822,588,657,121,856,977,37,330,349,782,517,346,54,498,881,299,832,89,789,595,620,640,814,168,92,674,357,924,996,675,273,426,355,87,149,666,60,591,425,167,206,217,687,841,396,690,147,366,543,834,837,702,446,343,937,62,128,245,156,112,833,37,710,636,235,982,42,990,918,845,460,219,302,351", "368,364,476,855,86,883,736,494,713,557,467,440,90,927,938,774,890,988,337,848,608,789,602,966,635,918,601,883,946,919,77,159,102,288,681,457,414,871,631,668,306,487,263,83,744,126,165,203,813,766,320,130,996,2,155,80,532,659,505,634,688,112,221,305,759,525,453,796,343,918,97,246,179,222,188,501,344,524,302,780,637,167,290,820,324,373,892,811,798,483,618,258,358,858,811,333,136,684,215,178,147,804,392,888,146,287,529,500,963,384,528,238,646,527,446,249,263,902,543,536,2,468,16,603,795,368,157,148,923,221,981,315,267,345,705,440,908,338,880,334,556,734,445,521,169,985,204,158,839,426,842,804,232,12,947,582,962,160,768,478,679,43,763,896,445,755,271,7,114,481,987,408,973,406,98,770,46,510,458,305,268,567,508,961,167,644,391,25,372,92,135,579,950,266,194,313,35,491,200,641,618,785,948,778,887,355,813,473,73,469,49,422,88,222,849,978,955,128,371,629,474,893,760,109,193,214,122,757,35,767,722,88,987,497,960,145,139,668,685,365,909,386,552,317,132,413,838,958,774,584,427,879,400,628,974,667,112,103,801,19,145,799,926,458,503,66,864,196,840,530,318,219,827,166,80,596,577,271,494,539,79,55,496,793,348,612,246,695,587,623,778,340,334,76,383,112,289,822,831,114,545,8,119,131,784,252,469,839,82,240,77,955,923,490,539,29,935,237,190,76,611,186,137,856,569,666,949,741,694,439,673,633,367,731,547,993,135,518,926,50,64,660,206,298,625,911,988,408,696,348,979,842,995,494,247,896,208,552,88,779,885,670,464,85,4,304,291,933,23,492,256,185,469,532,287,639,322,326,177,873,638,623,467,20,302,842,419,235,403,665,276,441,794,789,631,521,160,829,315,721,803,518,708,636,190,910,2,558,761,696,978,451,472,267,919,16,355,601,217,36,162,535,137,121,367,849,487,163,777,27,229,633,0,78,28,988,169,859,996,715,462,898,609,101,425,972,5,891,250,357,593,976,459,293,486,857,714,420,962,530,487,757,453,519,785,774,510,644,921,463,373,309,80,797,462,739,584,473,113,376,847,796,414,539,680,436,210,492,967,584,143,583,387,979,79,370,994,699,817,836,845,486,597,75,205,893,895,399,481,534,548,742,733,480,95,487,41,889,6,711,248,81,548,54,999,708,936,542,848,481,489,99,379,996,657,485,348,615,614,806,318,506,995,912,233,792,585,530,205,877,110,553,284,272,661,779,62,417,587,553,976,557,764,232,999,261,232,588,246,442,311,716,582,782,838,719,956,383,444,990,184,348,909,851,540,893,646,737,978,729,457,583,528,550,467,795,153,663,264,902,590,178,680,343,565,996,658,565,711,585,95,513,269,799,697,3,223,141,966,311,123,121,562,676,131,669,826,266,975,766,922,21,530,123,902,598,138,432,915,981,412,836,454,728,429,831,240,640,596,40,736,864,801,477,855,113,952,537,398,992,363,161,564,977,120,305,884,988,419,596,996,544,78,726,959,969,215,366,799,102,259,479,614,289,156,922,44,236,206,397,25,742,757,692,660,316,717,565,531,120,291,454,30,677,71,284,224,724,796,726,97,242,639,437,989,162,733,278,646,970,944,30,452,506,50,150,584,172,231,522,966,615,795,398,755,586,112,86,220,17,945,90,32,384,558,372,888,47,818,470,565,42,932,443,752,939,470,293,936,674,151,517,130,274,580,9,453,124,533,150,593,562,993,38,453,83,375,740,908,23,475,377,539,373,555,466,745,742,570,213,579,966,180,477,78,712,761,127,146,306,504,714,488,604,986,46,614,270,847,997,102,516,551,862,565,966,827,686,336,745,955,427,927,758,288,842,981,515,20,182,606,697,4,342,805,863,981,56,887,769,918,604,137,118,50,129,250,893,145,278,139,636,199,585,655,271,319,383,182,161,587,61,211,275,543,180,690,857,988,590,469,836,354,56,976,845,757,166,38,672,675,819,759,907,673,834,985,947,180,785,886,845,591,959,668,10,878,224,744,106,290,325,189,607,910,906,695,157,831,811,897,183,102,237,249,730,609,954,744,963,628,87,356,122,451,565,716,819,848,756,763,688,828,502,895,339,409,549,838,80,288,427,908,543,527,601,421,254,439,374,685,841,854,180,183,66,621,805,905,139,582,472,637,910,685,166,676,310,117,642,284,297,35,850,151,41,315,548,809,347,649,111,433,392,277,40,406,365,649,689,7,592,809,730,283,198,351,465,905,863", "31,415,193,570,52,356,812,491,260,523,271,747,153,515,320,29,574,889,621,874,363,569,267,48,378,93,79,807,361,266,693,894,386,941,624,65,830,697,997,780,891,993,895,75,746,124,188,116,827,558,583,135,691,812,958,615,117,930,367,92,298,563,668,361,10,455,13,325,118,152,253,922,66,663,914,940,582,45,753,706,789,769,137,594,846,986,844,24,229,766,29,323,365,410,224,368,249,477,388,308,992,907,867,243,342,689,350,554,572,714,621,35,878,669,270,61,861,158,118,757,278,157,927,869,681,591,278,59,38,141,810,65,979,225,165,394,229,514,601,887,437,740,166,894,642,759,292,696,348,336,100,785,429,446,837,124,549,860,444,755,515,118,813,689,212,221,934,626,423,944,132,302,355,956,316,606,136,675,645,766,608,786,409,893,787,26,404,178,606,409,593,479,341,476,706,385,246,664,443,698,387,735,545,759,392,276,327,627,357,104,334,875,993,893,633,658,928,73,422,158,925,950,287,954,948,264,258,195,452,814,755,441,21,156,913,630,458,702,94,853,650,471,422,607,206,655,575,488,313,402,852,622,914,442,270,119,300,456,401,793,800,989,76,212,146,262,217,300,448,774,584,838,912,834,615,676,132,230,331,647,703,426,480,454,541,527,960,272,292,249,167,723,795,774,278,103,840,110,40,565,158,88,366,347,633,946,892,297,60,28,216,331,602,494,963,999,244,462,858,993,60,500,980,976,559,26,508,14,441,543,134,569,115,508,215,88,333,714,576,515,551,409,469,480,383,893,944,226,104,205,951,352,105,330,38,314,731,559,448,407,779,711,199,966,107,922,367,954,130,808,796,899,961,283,58,201,870,154,459,688,694,881,980,347,831,592,467,904,646,956,943,923,195,876,787,854,915,682,636,777,10,948,546,557,559,78,273,472,172,558,199,505,724,616,444,650,682,251,460,329,658,532,573,19,260,690,752,884,482,437,574,718,78,0,445,971,637,627,875,265,105,307,212,908,688,910,948,823,735,581,616,93,465,197,511,421,644,887,774,304,966,175,864,115,21,931,883,280,686,170,607,83,356,651,110,818,492,340,549,380,589,615,452,441,654,114,946,936,318,665,741,328,460,277,576,452,862,529,962,184,510,588,438,486,229,204,750,49,424,57,546,4,222,891,298,656,631,346,952,920,643,221,46,924,837,255,233,68,752,925,456,6,819,480,139,357,620,369,22,367,55,903,810,755,654,359,659,947,399,678,504,298,402,747,11,909,280,832,172,506,309,788,441,664,465,164,718,796,338,373,54,771,827,384,517,443,67,362,753,806,58,857,585,951,478,336,132,357,3,425,765,527,580,461,471,814,591,251,26,937,272,905,910,478,141,109,574,957,386,133,732,883,328,930,721,52,463,8,65,430,411,30,968,429,636,661,753,52,577,462,977,299,514,553,10,898,562,101,882,267,750,929,562,999,717,688,2,708,87,95,844,257,661,49,824,457,15,174,548,447,907,564,745,804,151,146,976,358,630,609,113,225,786,557,733,7,815,852,392,153,188,298,980,714,529,192,753,595,710,130,749,926,611,653,982,46,490,348,779,898,461,357,110,215,458,416,221,647,158,771,180,765,654,747,384,915,660,918,592,864,561,559,267,478,117,449,75,183,478,207,236,250,568,735,606,83,647,331,622,361,333,360,479,401,147,718,25,341,621,420,13,279,689,158,778,588,112,31,369,25,132,435,486,570,608,248,968,204,200,168,978,778,354,71,153,610,348,880,348,304,764,636,969,532,798,750,208,309,466,416,96,958,871,32,681,543,752,528,396,380,702,692,494,330,726,647,351,755,100,929,448,176,711,727,335,260,95,523,214,763,544,411,743,561,480,874,28,188,231,291,467,113,169,592,712,385,219,230,431,185,791,992,116,37,759,880,304,31,558,946,115,325,679,567,576,9,123,179,406,706,825,824,644,638,999,399,696,559,887,302,918,150,239,266,839,654,270,714,146,342,65,322,989,30,613,469,69,720,483,539,408,347,414,132,303,173,84,686,435,498,510,314,532,784,932,959,870,869,243,841,695,287,314,274,196,120,375,403,208,28,29,269,54,601,308,225,300,36,726,251,94,924,94,453,151,818,637,790,774,904,799,811,718,672,887,718,419,46,348,975,562,935,776,875,102,34,52,85,640,494,320,56,29,790,307,358,752,218,877,572,836,190,650,64,280,160,591,860,158,678,990,234,572,180,363,373,598,715,393,359,341,142,46,452,911,701,750,985,190,796", "561,614,735,15,523,825,763,878,556,353,948,400,956,741,643,45,787,589,301,445,933,502,975,238,995,70,249,934,652,311,559,358,94,736,8,439,723,387,673,347,530,44,335,637,517,16,60,111,38,211,826,466,34,936,831,106,730,624,534,636,887,554,576,280,863,652,415,356,106,311,706,570,533,520,379,181,77,611,10,116,941,642,216,958,521,390,58,494,580,245,271,708,434,666,998,871,1,607,223,940,327,184,713,800,700,785,801,578,660,743,800,148,498,505,622,773,698,52,100,665,89,828,68,920,700,577,720,282,687,186,665,606,247,855,351,506,852,589,307,879,598,971,590,279,81,869,290,835,705,712,218,96,477,387,980,657,729,629,67,64,264,732,938,110,648,103,854,833,964,636,744,80,724,697,524,377,773,555,876,125,422,125,897,886,434,440,338,126,762,671,245,465,135,652,602,537,917,594,383,51,751,205,490,291,251,937,462,100,488,413,691,71,862,214,911,577,219,929,620,621,147,540,126,869,993,477,907,229,994,473,381,484,322,461,297,513,785,192,195,205,139,953,867,200,934,330,733,531,804,847,607,368,20,420,362,753,753,352,602,286,794,99,887,192,693,496,490,497,634,140,40,548,319,914,552,825,707,378,941,429,108,869,384,200,733,413,996,519,616,113,787,287,48,495,846,917,21,484,820,147,5,827,809,805,781,8,793,483,889,276,496,625,996,160,850,802,58,389,452,842,167,391,269,820,6,25,861,253,292,733,840,366,247,931,121,919,102,163,312,580,566,828,518,319,586,433,619,762,634,226,751,263,177,755,197,883,829,967,374,882,726,480,458,415,217,577,877,855,197,538,943,36,198,898,308,379,596,932,18,226,167,435,592,22,168,433,830,115,288,149,841,445,355,352,564,716,511,193,192,901,539,508,463,567,290,273,782,211,893,136,387,865,903,458,545,178,32,417,252,193,165,516,230,632,551,509,700,179,625,594,451,61,28,445,0,869,873,714,695,82,510,566,91,289,791,994,455,220,27,96,129,348,546,638,785,807,404,274,780,604,159,660,840,327,463,849,996,624,179,42,71,418,923,217,791,369,466,913,746,476,756,837,798,544,969,87,974,790,763,969,242,605,247,219,753,767,58,23,110,945,134,327,709,69,911,831,791,79,152,973,608,622,617,281,571,58,124,602,665,50,11,698,874,815,258,790,585,953,509,734,454,843,153,129,653,160,617,494,931,440,351,691,340,950,858,442,929,648,806,503,781,254,97,922,462,655,42,636,447,988,280,576,338,161,713,716,862,777,755,101,50,579,758,780,448,245,366,106,736,768,726,463,729,881,280,666,164,806,703,936,262,459,17,98,55,184,909,925,588,146,274,604,819,685,556,522,398,844,528,92,431,911,425,153,907,689,701,71,832,16,550,255,403,4,81,914,346,207,485,369,326,403,95,145,949,179,893,616,146,581,605,718,831,503,571,639,261,226,752,988,600,753,573,821,919,508,111,134,688,986,109,250,19,429,648,146,882,506,389,525,132,253,58,739,844,989,571,938,870,162,862,285,968,894,556,26,172,940,841,952,365,463,169,172,342,471,274,129,233,268,310,701,904,142,821,733,148,764,534,152,33,104,853,996,216,334,853,894,357,215,552,881,840,625,972,191,888,782,922,780,945,33,609,595,380,381,289,151,747,43,893,206,409,168,60,204,64,815,967,957,783,705,440,207,453,459,886,950,756,911,389,57,561,715,934,167,413,523,485,431,464,886,841,855,462,95,392,894,107,229,287,50,797,458,273,770,640,770,29,924,434,38,681,21,369,121,834,266,895,931,342,736,769,616,202,678,541,791,97,392,408,809,911,934,209,640,702,752,957,141,363,234,469,365,970,782,35,845,620,662,30,879,686,709,938,938,29,594,658,256,474,209,478,417,494,592,714,719,169,174,909,180,678,584,181,949,498,984,512,777,293,387,390,92,424,941,653,222,439,458,78,631,611,523,166,73,12,656,378,112,100,177,240,462,601,669,88,162,812,587,195,562,319,671,331,910,910,765,905,816,210,448,367,845,297,503,621,596,749,127,366,177,698,41,500,626,204,657,280,636,300,870,149,894,103,409,429,613,259,994,306,358,555,141,163,890,877,440,787,980,681,402,682,132,390,309,966,270,61,40,20,520,93,296,268,636,684,15,141,834,107,853,522,36,773,284,383,338,720,400,577,714,28,4,23,863,117,65,702,520,916,175,532,774,126,976,539,958,541,489,514,570,812,491,60,318,739,989,778,188", "537,571,106,700,396,69,985,548,943,20,753,724,392,195,859,711,667,718,823,503,267,558,245,562,983,854,399,193,296,596,790,595,475,266,177,888,906,190,431,680,629,315,960,390,132,706,389,148,719,994,539,814,576,388,393,213,409,151,464,303,132,458,644,440,260,695,946,732,990,818,870,491,710,698,243,642,524,313,920,943,180,366,530,9,591,404,598,470,62,539,240,914,244,486,533,827,799,14,794,767,155,602,925,866,617,155,275,460,47,746,282,970,663,662,732,164,372,469,648,682,916,546,599,884,247,458,377,366,25,230,215,811,122,440,85,441,410,642,661,174,560,97,699,382,10,534,685,83,130,764,426,53,679,804,401,231,310,419,51,906,150,670,968,212,552,742,691,101,151,523,418,46,627,786,299,105,307,286,131,332,594,898,36,598,12,533,452,921,80,730,62,732,430,824,258,749,191,496,265,769,86,208,255,124,586,714,859,339,248,834,194,163,148,852,828,34,681,882,233,129,710,403,612,657,418,377,555,889,11,89,190,901,646,934,561,605,193,171,796,356,231,958,609,57,609,523,200,275,655,466,983,934,871,964,13,440,67,628,731,444,706,755,675,465,126,490,267,60,610,174,583,443,224,130,397,281,376,867,387,11,435,473,730,652,938,18,470,977,846,996,858,567,646,823,403,31,547,618,153,176,919,484,789,401,220,945,218,886,650,10,650,883,525,740,109,513,509,162,863,467,492,183,440,407,817,729,162,584,497,451,705,570,789,80,566,498,244,255,525,961,909,734,428,635,715,873,475,184,887,339,747,130,752,829,920,916,534,602,613,253,528,364,312,431,354,403,610,216,272,941,75,193,319,985,846,320,609,853,556,4,280,314,969,137,668,515,993,528,886,285,7,688,508,672,896,210,57,28,480,641,535,670,536,509,641,16,31,131,685,336,156,853,130,555,356,280,685,126,393,643,988,815,1,942,794,226,144,374,377,126,30,454,988,971,869,0,490,495,430,48,404,335,436,772,538,544,376,714,443,281,103,214,854,752,267,644,331,273,349,112,675,465,448,434,621,200,767,477,865,192,170,136,577,285,913,782,188,197,379,804,834,421,480,523,295,22,246,192,710,698,674,691,442,125,649,313,502,834,645,278,213,910,150,768,75,807,866,161,427,817,293,765,891,217,941,988,20,650,418,894,81,39,349,744,773,371,403,202,786,532,940,942,121,40,329,670,879,151,376,648,604,342,870,518,894,956,939,43,335,116,726,209,470,263,577,640,390,397,213,537,779,305,13,589,565,719,984,437,293,808,252,526,909,381,275,723,986,959,869,904,215,561,507,976,364,172,328,980,207,928,594,617,718,501,695,434,490,920,987,236,678,956,204,384,403,754,749,239,225,76,262,710,573,740,454,179,844,69,284,755,803,924,696,493,179,31,767,371,647,660,820,715,376,377,893,528,792,247,617,801,985,331,525,713,413,730,299,735,202,299,729,881,652,462,915,606,62,813,479,867,375,978,797,348,18,986,429,405,541,677,5,722,915,148,617,32,333,722,138,924,707,611,586,960,649,428,858,356,68,939,611,757,819,436,401,558,209,587,557,867,644,316,487,213,181,519,719,848,786,688,434,801,235,434,151,275,258,340,182,598,9,960,654,841,21,611,682,980,115,954,397,869,294,519,456,884,147,349,4,926,200,35,767,110,542,554,628,636,599,81,541,374,588,571,632,295,649,635,23,264,696,949,344,481,154,537,439,187,482,208,699,518,718,994,122,757,682,862,805,788,356,424,728,756,183,739,958,646,631,79,815,397,361,779,666,677,139,148,792,5,881,7,761,332,870,665,977,106,230,365,578,367,934,444,695,473,602,953,648,248,533,961,93,590,515,986,78,475,592,588,323,652,911,987,276,58,894,211,568,423,802,334,330,395,816,757,514,91,272,241,358,120,593,708,614,830,975,993,32,976,960,613,576,133,502,112,234,58,609,253,769,37,967,480,865,455,912,583,213,249,467,786,810,40,977,964,546,746,25,652,908,418,107,510,32,141,634,869,792,752,598,103,894,568,403,80,435,478,493,6,529,243,217,420,149,518,305,80,456,338,870,250,93,836,338,67,242,112,980,394,663,947,124,53,449,701,14,748,546,650,719,427,338,365,828,11,450,762,515,910,8,163,607,270,796,289,274,245,761,246,364,618,796,850,895,357,497,759,878,845,149,261,149,547,598,732,315,681,881,601,586,41,955,689,882,309,503,865,621,595,388,488,39,325,489,940,898,452,766,132", "962,145,716,400,839,512,268,653,617,368,334,922,710,680,995,372,220,338,717,944,474,395,190,898,831,406,11,515,738,171,725,539,586,124,770,801,477,819,929,845,16,765,35,130,381,582,180,622,990,491,54,864,960,220,618,60,405,269,130,461,103,329,43,659,235,228,919,458,379,831,658,652,739,29,438,127,897,801,349,575,869,824,614,566,538,77,396,387,169,590,71,207,579,670,926,77,545,965,838,633,637,340,83,406,287,815,566,200,528,132,31,314,818,806,21,252,634,606,452,917,931,370,551,912,108,129,378,130,213,288,330,290,842,315,59,296,717,918,1,826,452,451,970,331,292,399,546,919,6,303,469,747,273,756,337,503,232,539,372,111,517,98,178,628,994,473,759,635,387,302,528,304,4,155,97,824,232,730,430,200,56,506,378,4,420,805,630,162,192,85,230,51,769,491,17,419,136,208,166,887,291,985,862,720,806,378,961,509,5,570,160,974,422,945,81,777,225,738,862,293,744,468,504,487,953,490,606,710,960,677,32,57,863,297,396,779,925,112,901,765,832,7,943,768,831,446,466,162,131,249,741,58,328,559,599,534,897,983,25,467,136,113,453,706,558,42,549,723,106,749,699,33,385,882,710,48,468,581,806,40,238,454,147,720,478,357,656,996,141,88,807,136,327,607,818,202,823,659,3,863,847,113,259,567,503,183,943,887,558,155,436,230,904,308,872,278,315,476,231,793,310,620,577,628,126,425,249,872,44,367,709,772,268,538,599,339,23,538,701,706,475,216,817,487,172,390,791,394,509,275,21,434,860,595,264,772,498,283,643,347,608,17,560,647,480,85,21,122,458,763,571,887,878,160,490,417,869,91,819,395,606,383,902,419,974,504,866,924,902,394,383,251,14,708,763,21,171,706,894,665,907,5,943,107,273,594,614,129,503,76,886,961,469,9,682,562,412,360,81,40,75,85,696,591,451,120,661,949,70,14,657,338,169,637,873,490,0,343,898,655,389,556,98,607,926,415,216,665,68,275,478,925,149,10,907,783,734,963,155,290,836,75,245,708,676,341,608,541,181,471,662,925,131,705,526,811,84,564,134,786,309,273,745,58,787,717,910,316,619,61,442,342,560,659,269,157,814,705,234,105,244,28,76,780,898,487,503,899,75,329,691,554,241,277,986,111,563,670,364,661,820,564,131,255,770,654,153,205,747,894,858,249,929,48,646,325,353,552,318,622,60,403,659,300,669,813,561,443,848,670,588,419,611,404,136,234,966,136,463,525,539,615,837,663,369,832,474,650,241,710,1000,470,118,889,782,706,932,322,525,883,396,111,580,484,397,650,81,889,687,589,879,361,73,452,785,327,826,180,598,841,4,20,383,398,486,592,287,111,27,106,496,829,822,982,283,921,739,906,371,196,158,353,81,833,740,941,494,538,853,793,379,58,751,55,887,930,739,634,203,200,751,52,970,500,26,100,149,421,747,879,756,779,251,363,565,84,639,740,196,332,41,433,131,795,903,250,656,346,803,318,517,658,617,822,509,437,880,591,266,269,669,736,979,682,116,388,781,920,810,657,730,621,757,379,902,265,936,463,869,497,900,837,141,476,13,89,490,558,468,182,55,527,229,788,578,646,527,167,418,912,43,974,174,602,140,709,345,333,179,901,850,335,455,192,107,11,826,699,779,649,67,228,893,425,836,480,18,945,660,840,15,226,180,642,515,7,471,140,134,60,956,108,310,898,586,760,286,671,399,777,597,146,351,607,942,682,395,556,962,987,593,730,1,738,16,864,917,58,317,231,392,745,955,578,1000,244,24,72,806,621,269,993,57,586,52,12,890,933,732,907,968,631,650,418,367,818,453,135,583,813,216,795,946,986,588,254,290,802,899,301,837,137,212,852,446,804,916,752,224,650,555,604,164,362,659,36,485,498,918,563,312,110,692,571,994,823,403,266,434,211,770,892,353,499,886,106,708,665,995,778,129,244,136,549,350,725,262,836,350,482,112,456,603,649,695,303,374,677,733,87,49,911,255,331,526,568,625,731,818,512,233,171,154,981,251,628,703,995,516,806,682,43,428,575,646,636,712,851,103,272,48,326,921,425,961,50,993,802,3,675,530,751,53,654,452,842,961,630,918,482,816,48,420,673,800,391,493,574,354,449,573,921,597,903,402,57,313,97,187,365,503,307,768,807,620,359,91,522,228,387,255,725,5,830,554,846,771,85,825,266,296,265,584,947,199,979,776,387,418,721,73,528,795,217,176,439,535,948,564,289", "873,888,479,897,841,984,815,600,164,699,585,24,193,902,705,518,960,350,387,837,42,605,680,597,986,70,505,741,975,68,225,967,20,523,924,478,34,684,197,451,531,701,326,512,750,60,167,261,699,755,888,259,39,558,833,407,359,600,736,723,611,371,556,732,119,381,496,106,906,809,536,49,61,37,215,878,880,431,267,153,478,317,831,564,533,161,506,56,538,180,108,857,688,75,462,277,323,590,220,839,485,331,44,410,300,365,42,246,300,971,404,984,603,382,3,277,868,640,580,367,728,801,996,633,223,598,169,983,619,304,457,561,141,232,466,661,672,718,881,236,182,834,111,637,591,227,434,920,518,86,592,409,454,747,206,710,393,661,16,193,470,101,805,866,206,836,69,230,432,670,718,229,939,894,254,181,884,428,903,844,66,258,934,795,538,358,361,307,634,176,863,947,346,235,977,662,609,570,140,946,140,843,89,563,886,15,596,16,150,805,694,168,978,402,885,144,738,749,286,231,729,75,792,319,245,963,218,882,613,585,744,417,870,299,441,13,155,284,360,418,338,719,977,133,952,825,985,869,199,713,396,270,426,848,929,965,311,244,3,620,30,822,293,672,503,878,953,922,546,861,759,170,794,915,22,365,486,253,479,9,529,161,73,778,736,806,712,341,311,41,987,659,455,82,592,310,42,675,639,875,475,907,172,856,399,829,799,150,92,670,436,15,912,392,495,227,850,653,539,855,568,557,846,221,623,893,799,366,451,805,997,920,138,621,303,475,875,2,984,205,950,45,465,623,885,393,719,930,463,929,157,807,630,962,241,814,845,437,109,53,697,957,583,605,586,626,891,88,331,389,658,212,863,689,891,677,786,269,247,785,888,361,247,412,198,475,39,807,208,166,16,848,579,554,628,36,685,531,449,534,270,357,992,492,223,846,757,330,316,477,12,210,787,16,27,396,888,432,237,63,641,616,7,849,637,293,380,357,305,469,239,50,859,627,714,495,343,0,694,577,754,56,626,976,219,649,513,247,109,744,465,243,242,328,640,120,604,784,696,423,895,628,14,145,144,254,626,983,733,326,626,970,790,70,719,583,823,179,577,847,120,679,834,511,48,988,829,142,89,369,483,447,476,176,1,643,166,319,56,658,585,584,721,945,904,848,876,16,675,768,357,865,540,141,207,396,451,113,766,906,877,449,8,200,848,532,689,973,987,528,778,849,321,308,724,808,789,961,202,298,847,703,97,315,404,904,810,649,952,992,821,314,384,751,22,143,833,708,659,210,35,44,372,170,834,924,997,505,218,827,751,726,192,178,958,925,233,960,647,741,50,466,870,232,294,203,546,507,788,896,32,620,269,868,735,484,295,338,424,433,734,738,913,925,137,260,233,246,410,78,181,211,302,59,527,511,353,8,935,620,457,322,98,636,798,6,790,74,839,307,165,890,579,360,595,499,242,61,687,860,599,882,388,248,172,671,79,232,187,68,169,938,543,921,950,314,648,943,16,382,140,170,531,889,154,734,534,563,693,842,374,26,900,446,371,812,686,908,180,991,726,834,217,290,501,520,310,583,462,841,14,50,644,844,4,244,890,697,574,494,299,998,455,461,225,138,745,484,814,521,346,105,710,659,284,983,34,147,125,656,325,315,294,379,566,109,885,518,110,133,45,241,85,593,288,287,149,277,848,223,299,814,574,687,974,358,834,118,989,325,198,441,471,527,222,380,804,276,98,202,479,636,304,460,322,557,559,188,607,606,670,318,106,296,680,887,307,333,340,182,580,757,6,363,578,414,810,886,773,19,117,837,544,977,510,600,890,590,557,774,226,115,441,649,794,34,521,662,178,308,697,656,498,218,569,583,57,319,458,454,82,243,407,383,341,329,800,103,141,710,718,804,469,847,274,980,280,361,147,529,303,430,189,480,887,409,740,951,441,641,850,542,120,653,85,498,207,911,447,603,797,437,822,848,442,473,353,393,811,102,808,83,515,629,96,493,338,341,185,287,208,88,291,675,621,849,822,960,724,280,528,440,41,563,23,683,647,447,164,349,958,277,53,952,954,252,582,927,832,42,434,165,339,166,550,669,145,251,33,623,431,220,352,350,816,934,206,205,370,977,533,49,585,793,911,674,76,850,510,688,454,280,383,226,12,150,315,886,190,923,69,273,754,445,177,873,718,12,596,374,601,570,850,875,96,364,782,862,732,215,408,49,482,81,486,551,518,820,109,408,894,204,676,476,122,741,904,524,184,384,230,593,895,694,720,987,852,670,645,588", "902,999,344,800,707,694,64,912,336,795,97,760,713,547,319,700,613,753,276,139,84,413,260,170,674,277,886,515,512,757,499,828,660,187,524,293,256,864,453,193,139,478,877,133,412,24,842,173,97,494,191,996,719,779,405,55,548,101,145,689,905,247,275,615,454,409,946,71,795,887,367,778,330,320,561,360,433,715,893,534,808,433,178,909,714,25,507,200,934,768,577,595,379,529,887,59,123,307,585,366,743,388,922,878,930,345,297,267,649,979,513,351,65,508,485,75,338,587,536,658,51,635,858,308,822,127,859,906,652,784,86,450,361,40,191,404,193,946,948,531,61,829,90,121,312,162,965,214,776,267,600,41,903,633,947,918,220,966,509,680,833,453,941,793,711,644,732,322,14,964,381,156,784,841,711,696,834,361,205,839,940,688,216,34,99,82,493,318,869,349,172,839,320,868,128,326,845,539,73,774,853,184,920,872,929,954,145,686,973,870,336,622,755,659,650,825,484,407,15,76,278,848,683,482,42,343,300,866,396,253,976,854,312,554,967,697,646,474,292,407,835,902,66,274,734,33,959,623,726,780,699,685,761,494,691,653,325,712,760,316,524,637,162,592,142,346,655,720,955,829,79,377,614,230,56,763,637,883,53,975,820,867,987,715,109,646,949,394,506,593,794,654,763,81,116,419,932,316,69,168,481,665,790,54,15,245,414,214,403,102,408,431,7,966,39,638,475,219,615,686,320,134,82,350,994,368,939,454,419,318,513,732,237,92,154,220,204,411,595,410,658,774,996,317,323,327,483,971,653,184,35,439,772,186,566,73,613,829,891,813,433,286,152,556,958,733,952,172,734,357,573,494,967,22,500,153,963,696,866,438,529,625,523,919,363,946,321,517,370,70,771,962,215,104,953,605,198,267,563,770,568,257,480,144,390,583,189,60,4,773,186,242,593,401,952,261,291,80,607,341,168,369,530,161,909,100,15,268,802,462,717,719,996,875,695,430,898,694,0,396,468,449,24,220,31,701,784,748,197,659,637,397,486,323,829,593,376,793,77,988,443,572,381,201,637,457,510,514,180,586,593,967,580,856,720,725,613,8,508,75,523,149,126,805,834,751,381,988,571,898,946,403,600,994,985,310,477,702,706,477,876,25,372,950,108,964,410,276,567,405,61,63,40,550,176,425,505,401,469,441,199,553,659,40,825,446,649,492,298,368,157,603,948,201,781,878,956,455,25,8,863,350,529,545,222,933,791,844,563,404,471,365,331,99,217,943,685,821,527,427,539,389,582,69,735,348,701,75,616,985,985,636,679,382,640,433,283,606,341,469,636,570,282,350,401,509,547,293,271,451,296,147,152,439,758,44,893,481,355,359,57,398,799,801,819,366,104,610,506,26,486,496,823,76,459,395,444,788,993,97,506,78,844,521,530,381,901,588,296,698,310,643,511,662,48,374,700,750,867,552,470,238,83,100,492,745,881,628,948,188,772,201,105,829,142,531,18,606,61,726,484,708,330,486,752,566,574,526,815,386,355,559,852,488,490,313,68,341,56,775,738,536,256,241,688,196,349,847,605,95,34,589,687,869,822,772,49,495,914,265,451,118,371,840,608,426,475,366,264,290,435,457,304,129,389,242,78,955,364,531,340,312,426,357,41,549,482,154,960,30,674,522,29,821,758,253,966,673,152,510,47,750,911,601,339,466,259,159,585,687,417,655,507,198,574,527,192,222,947,46,447,768,685,126,225,151,838,634,405,751,952,735,974,221,653,78,75,509,565,121,354,221,484,603,83,546,289,37,588,741,809,477,649,865,148,809,639,114,999,891,692,873,5,298,76,735,819,405,527,959,711,421,176,169,809,718,200,31,743,102,603,138,84,815,705,38,125,887,219,260,92,958,99,797,814,202,149,259,248,5,176,659,873,8,120,153,232,510,453,588,624,771,27,433,758,982,62,494,484,904,954,526,394,913,208,688,43,574,827,969,102,184,309,830,401,774,294,811,213,610,60,502,737,796,16,113,471,815,883,101,754,602,757,375,454,129,594,147,232,363,59,374,347,952,214,541,622,521,881,772,103,791,226,233,912,763,776,928,73,27,164,844,874,311,444,667,24,586,236,168,896,573,831,493,119,503,77,724,170,137,12,935,936,146,410,555,198,803,447,61,352,912,992,83,193,119,352,814,416,628,527,758,191,971,174,795,277,425,46,787,519,131,112,351,770,90,246,46,227,60,39,762,101,143,499,171,55,915,766,12,6,121,156,539,909,573,706,654,324,713", "529,235,571,53,919,394,714,977,723,229,238,925,359,98,903,104,681,457,904,350,271,935,154,337,68,635,573,2,394,949,34,329,310,905,52,622,674,867,554,517,677,819,98,846,908,904,111,190,89,583,97,579,953,813,737,597,483,205,487,43,246,316,696,66,134,878,357,479,462,786,458,176,233,1,252,362,60,571,381,27,997,506,588,64,892,578,530,585,40,811,300,95,698,167,324,960,481,458,502,828,64,40,993,100,890,760,582,434,706,980,292,739,339,196,854,666,591,6,200,753,532,82,468,52,943,846,619,182,701,751,609,222,155,822,180,577,600,83,473,703,453,84,616,119,574,377,826,291,123,663,560,284,219,971,714,766,749,245,359,146,515,588,999,315,967,896,578,800,161,340,99,638,645,381,229,560,28,581,817,470,951,149,90,665,952,472,78,87,358,948,895,784,607,217,70,121,358,214,669,880,979,567,436,515,207,630,944,714,354,769,951,649,527,904,950,144,647,298,348,959,514,531,419,785,798,834,218,263,467,220,561,359,351,180,55,69,798,731,782,183,99,466,345,24,92,345,149,665,798,540,164,16,717,169,312,74,829,577,19,867,961,787,959,31,4,630,227,334,857,905,69,677,101,664,291,458,609,596,810,700,474,472,492,723,536,105,669,879,213,393,272,16,271,267,268,22,461,355,721,699,896,471,602,755,32,567,106,30,235,936,62,663,899,347,222,270,845,700,446,633,66,54,512,126,85,624,361,544,790,214,68,849,835,80,188,833,110,886,963,251,602,626,319,609,964,353,76,570,634,479,286,765,735,76,410,208,864,737,209,996,883,436,916,395,642,107,687,414,767,255,472,852,640,15,362,775,182,605,627,873,916,767,811,493,538,290,727,244,944,734,55,820,657,930,813,800,359,533,520,845,574,272,904,630,263,709,454,883,38,878,291,775,529,910,525,627,456,725,548,813,308,952,791,419,283,438,236,812,735,171,25,432,715,265,82,48,655,577,396,0,867,796,340,220,293,322,881,986,460,682,693,72,989,63,79,958,196,876,389,531,760,41,149,364,486,374,856,594,313,117,152,169,764,850,280,796,474,186,275,674,662,847,16,489,114,451,325,884,773,199,500,298,412,580,340,759,694,492,771,158,932,787,899,547,532,827,383,527,42,273,145,262,406,184,543,931,497,894,807,301,538,51,884,626,566,259,891,347,507,420,494,695,428,40,386,215,751,951,59,208,162,84,745,804,862,717,863,539,284,658,540,217,882,592,218,961,542,764,484,333,43,703,164,568,13,741,299,677,386,739,711,904,625,516,860,174,33,503,624,107,832,365,114,811,815,627,478,413,330,968,188,294,866,476,481,704,38,602,974,708,668,419,151,994,438,581,804,994,468,60,265,814,191,574,279,622,716,303,430,35,675,734,691,514,33,667,711,460,855,503,189,157,602,7,243,121,280,847,102,246,566,535,566,410,42,811,545,960,762,949,970,855,593,205,298,136,457,145,848,592,226,493,950,209,446,844,895,179,550,671,726,287,723,316,450,252,961,341,454,210,119,724,184,144,492,977,461,598,114,275,423,12,819,723,476,955,917,269,152,797,946,127,857,121,61,949,835,771,659,561,824,687,49,818,1,940,189,8,135,777,952,908,605,703,56,148,697,144,408,484,426,967,535,652,946,512,879,999,186,338,591,557,555,450,380,336,797,587,764,269,579,581,747,176,992,49,477,833,372,174,589,360,863,339,960,248,410,14,582,382,667,233,155,510,363,734,248,950,571,136,679,582,310,298,995,640,710,467,152,94,102,616,124,641,99,211,519,136,91,378,139,268,44,945,460,867,924,648,935,42,969,242,893,347,249,441,589,53,1000,36,685,838,279,531,787,288,856,954,880,531,306,376,892,443,715,84,836,693,59,236,2,273,211,984,151,820,712,479,453,560,810,858,784,139,390,141,157,541,562,931,837,897,868,469,575,33,199,703,406,79,255,853,212,466,344,50,520,394,521,367,709,899,708,235,551,348,7,111,254,5,163,108,621,499,621,996,752,502,94,303,485,253,8,855,576,666,616,556,272,364,448,370,829,978,621,744,685,554,206,559,394,825,772,881,104,529,160,13,133,514,725,123,189,42,161,848,649,919,374,289,26,618,590,512,781,620,951,307,485,705,218,781,218,695,343,257,84,515,597,713,682,737,229,126,879,15,873,559,444,993,178,823,892,402,451,717,121,427,362,511,297,658,945,627,487,669,226,663,502,57,987,138,824,400,146,633,226,657,455,47", "362,727,294,800,348,477,482,584,740,873,555,511,76,616,79,741,992,942,260,39,142,914,733,176,130,294,919,624,88,483,400,980,985,237,190,447,880,15,16,743,932,595,494,223,183,846,310,695,88,848,83,420,524,552,340,559,975,659,270,836,406,938,46,511,681,218,982,995,226,304,329,550,718,166,813,878,148,626,343,843,535,207,283,243,450,146,446,422,201,779,231,417,877,556,497,147,888,159,916,602,814,29,365,896,490,525,122,651,459,996,610,921,320,975,591,207,30,675,233,658,741,50,713,460,831,977,905,799,973,322,549,595,275,385,14,354,622,41,335,669,965,176,105,447,631,322,472,79,265,299,129,330,812,967,511,340,465,1,944,569,399,914,864,815,890,428,421,936,109,501,12,462,89,446,271,332,457,453,863,31,955,412,648,243,437,917,535,508,926,456,562,181,408,714,266,771,386,959,420,330,587,75,570,652,517,478,161,138,301,510,334,55,248,187,890,551,154,693,763,955,15,289,647,852,708,97,267,570,86,530,64,175,558,531,233,381,474,34,848,534,864,126,258,556,28,930,85,218,173,702,384,501,383,244,892,620,382,325,627,591,597,125,563,877,44,593,471,973,370,625,87,3,394,344,833,562,664,88,142,513,798,461,298,276,837,358,58,809,149,844,636,745,898,169,764,619,270,484,755,737,559,619,797,662,40,440,976,571,556,880,337,953,916,605,654,967,422,15,477,322,20,905,721,436,295,463,799,59,742,550,107,160,316,466,546,901,901,417,702,298,671,361,834,675,888,158,26,224,978,636,699,212,860,940,153,352,606,585,659,825,696,251,358,98,909,562,911,106,962,13,318,1000,2,760,513,766,669,149,54,445,915,870,738,46,694,459,130,181,60,791,881,443,577,154,406,914,718,966,811,890,467,422,226,88,42,802,416,796,609,284,908,831,86,275,185,538,483,672,885,679,500,246,55,486,341,349,215,536,152,792,936,194,462,105,510,404,389,754,468,867,0,194,43,801,13,718,210,541,234,577,762,32,681,343,57,713,659,355,468,563,765,387,362,955,436,258,532,837,837,391,150,702,218,215,17,76,952,499,127,554,108,495,186,268,811,201,847,80,36,233,588,699,897,80,842,89,868,790,416,529,326,522,301,605,410,585,283,442,602,567,198,287,764,996,623,718,512,708,463,400,703,100,936,215,55,689,137,669,9,367,318,368,925,479,991,781,84,84,732,710,488,166,407,212,82,294,699,873,808,904,953,154,416,730,292,331,864,903,110,795,391,531,122,998,603,729,396,658,843,988,319,550,829,932,672,369,600,795,897,182,230,554,754,914,152,795,906,415,540,728,802,280,261,525,50,108,414,897,514,76,47,90,622,342,137,58,143,998,424,29,998,569,413,780,30,638,152,457,488,660,278,660,291,794,936,602,322,782,752,984,141,748,104,393,332,416,199,600,855,32,100,458,450,359,917,464,643,670,231,712,730,420,662,845,322,74,820,925,835,38,470,61,730,303,268,409,142,558,426,423,121,432,931,411,955,416,49,470,84,730,297,493,780,560,161,867,186,281,151,856,769,23,146,945,158,523,25,701,858,790,360,862,72,782,277,472,52,543,833,247,772,599,816,801,82,502,24,354,868,324,135,382,759,621,201,210,457,704,856,181,569,225,249,217,203,616,160,678,725,355,700,46,818,822,486,872,557,80,539,60,360,893,829,124,524,820,384,476,364,397,130,340,618,710,902,523,215,24,351,652,578,512,687,25,317,24,748,853,718,863,7,640,631,909,171,214,520,831,213,194,179,302,861,447,428,640,485,487,517,715,961,306,149,78,947,638,537,596,347,269,721,895,785,914,110,579,929,124,663,382,693,388,955,757,162,18,277,131,914,294,344,983,964,410,234,602,491,659,665,223,910,546,939,333,201,432,862,502,516,818,350,515,223,751,656,974,759,190,387,65,73,822,387,118,209,531,801,127,254,434,723,209,836,32,279,675,428,730,165,638,41,773,920,950,288,907,619,894,552,169,78,347,206,593,575,253,619,980,585,831,720,633,454,582,57,185,723,609,27,619,147,533,611,923,986,352,715,220,842,206,20,907,469,419,697,761,573,173,566,97,177,683,494,668,924,165,621,75,611,175,490,919,927,522,226,450,228,542,620,902,711,363,306,187,127,399,934,691,809,248,21,52,31,379,225,792,428,64,943,892,752,18,659,362,259,469,927,936,394,177,329,517,334,713,371,676,891,336,981,879,363,533,499,186,892,23,946,159,932,140", "225,913,498,860,140,145,886,199,579,787,486,448,713,616,72,120,219,343,990,764,766,814,754,750,311,313,564,781,192,22,662,831,637,254,303,929,813,161,845,716,640,114,574,72,945,820,631,771,369,805,989,855,311,602,917,410,43,151,248,28,254,668,848,494,771,895,507,267,219,51,229,83,964,151,717,417,16,956,201,756,251,830,597,851,839,8,291,893,718,699,372,787,977,349,958,443,176,289,363,92,895,587,735,589,847,37,200,925,617,541,427,90,354,266,114,563,908,138,137,332,87,735,917,894,667,55,214,729,126,810,491,14,195,513,192,652,14,768,600,872,491,179,543,546,548,203,564,441,637,227,221,391,559,687,496,584,167,74,282,812,405,410,710,615,683,948,934,945,471,599,398,282,66,536,764,901,349,971,113,441,377,336,194,866,468,641,37,819,162,470,169,215,144,857,53,509,125,549,723,646,783,159,572,927,708,267,124,605,925,924,262,389,784,141,830,162,762,559,893,414,586,546,998,63,572,391,270,75,55,637,721,958,71,129,225,200,805,554,763,472,798,220,607,166,697,664,842,563,522,387,694,441,177,49,678,992,602,502,27,548,836,671,852,457,246,164,937,662,704,738,431,958,207,876,752,728,123,874,852,769,178,647,255,13,215,501,711,274,627,630,654,656,881,305,191,903,56,249,277,538,326,970,553,447,429,583,66,973,777,530,580,648,920,436,427,989,922,127,740,409,114,830,876,612,135,530,600,914,147,452,337,100,575,124,76,733,331,891,573,909,155,910,179,735,305,986,523,179,456,303,855,552,948,789,784,886,799,277,791,462,766,610,277,922,948,374,514,254,284,398,575,595,936,777,422,754,134,890,303,955,576,207,193,786,225,195,725,484,750,255,869,518,863,294,256,597,157,894,470,597,764,390,106,375,865,542,522,606,662,397,371,820,523,585,278,550,744,373,424,319,906,634,632,5,748,432,872,797,358,792,727,675,898,307,566,335,556,56,449,796,194,0,700,356,364,379,739,778,17,380,471,417,455,320,840,738,87,563,171,75,97,251,288,300,287,43,973,998,22,345,871,950,251,950,679,446,219,574,165,421,180,478,853,806,693,63,528,313,399,699,317,295,362,928,827,116,383,655,622,468,100,675,681,950,762,915,42,647,139,665,232,264,643,747,209,290,712,112,621,286,423,702,210,182,110,433,405,991,618,663,267,697,739,318,521,93,474,875,286,873,655,287,357,556,550,765,254,483,614,950,382,209,479,832,989,792,395,346,617,826,846,468,816,942,692,714,209,791,194,768,99,592,948,472,906,164,640,170,69,133,464,642,666,635,580,477,202,285,858,274,950,856,986,616,743,577,468,730,673,895,908,424,442,642,199,907,53,520,797,49,11,854,889,778,293,772,43,777,694,647,975,226,137,273,157,615,159,695,84,971,679,330,72,4,14,519,969,871,568,294,175,952,905,907,730,695,95,222,25,943,200,571,186,34,952,166,488,512,293,85,471,74,673,423,619,490,443,216,190,284,96,13,709,248,68,404,894,330,664,782,349,5,31,374,12,853,882,276,643,361,581,499,926,765,226,321,459,229,895,363,700,380,120,390,27,85,717,579,705,582,249,851,178,905,312,624,503,289,992,831,659,97,306,104,763,353,813,223,616,929,341,326,251,868,131,629,477,581,308,801,528,303,55,841,407,79,838,860,941,787,906,102,595,417,978,162,834,28,995,891,672,195,670,280,580,154,99,886,544,404,626,772,801,125,412,254,139,465,214,805,642,562,348,301,289,692,867,38,814,402,535,150,169,670,903,839,33,212,199,328,845,16,925,115,743,362,738,972,784,360,308,95,541,747,311,751,407,134,545,123,504,622,249,866,700,547,779,514,989,191,440,184,627,265,166,299,696,449,243,398,410,570,209,298,21,180,535,526,642,791,126,2,773,226,736,966,373,377,797,668,192,223,782,633,26,735,442,987,662,166,547,908,554,310,633,779,944,547,509,124,499,751,771,861,594,4,756,813,468,672,494,369,919,25,455,338,723,331,909,875,397,243,628,81,758,461,157,989,193,924,90,852,773,133,387,60,474,795,410,991,413,669,805,701,382,70,901,789,12,31,894,110,436,804,556,470,652,37,78,556,631,422,603,614,366,754,303,756,542,376,507,479,64,244,756,374,141,723,328,358,493,225,730,302,355,878,984,584,427,180,972,931,160,936,893,690,826,338,425,438,856,894,825,853,725,252,100,53,777,758,363,703,530,156,731,957,336,962,633,785", "936,128,719,105,44,115,439,75,975,984,813,858,275,622,214,558,594,322,447,721,715,413,385,749,437,363,295,138,61,446,845,117,470,207,787,855,403,927,156,105,295,568,801,448,813,606,451,287,926,124,327,902,287,35,563,8,337,95,323,443,696,102,366,120,520,427,392,961,282,983,965,910,453,883,19,457,506,583,151,822,159,565,60,497,740,361,467,974,977,909,853,277,145,562,706,255,574,369,590,60,925,325,91,558,236,662,483,267,288,111,767,461,952,373,349,853,481,321,602,158,856,411,983,731,915,684,166,15,714,679,677,364,686,2,585,216,138,680,428,518,357,703,932,289,856,404,148,697,736,261,907,187,848,866,228,69,295,520,794,496,81,787,829,136,203,393,179,116,670,129,750,308,40,791,860,716,356,917,925,68,873,631,899,457,991,903,461,626,201,746,462,779,372,16,455,178,60,646,941,214,158,629,623,226,253,267,237,86,429,477,688,1000,451,261,575,837,693,232,145,445,91,919,533,853,193,63,917,783,44,276,939,861,816,823,190,905,886,568,990,783,143,498,281,842,473,76,529,408,185,442,915,99,752,490,237,796,45,181,248,319,18,835,20,413,90,275,152,713,323,421,457,263,701,423,670,999,772,209,923,508,846,338,269,76,771,204,25,786,281,982,359,992,920,487,470,992,582,684,679,958,38,751,857,105,90,475,903,57,97,17,621,8,658,373,993,694,661,804,323,936,448,777,946,529,544,411,358,349,421,172,943,299,340,608,587,311,712,579,113,376,165,125,533,234,936,72,751,259,553,718,783,220,242,792,295,894,179,116,685,70,489,225,633,438,498,951,661,591,447,591,992,319,83,311,53,776,979,655,8,491,126,390,411,263,320,324,776,965,42,836,257,320,557,752,591,770,442,908,68,866,570,313,207,576,385,485,295,314,116,6,830,366,334,744,901,559,47,377,740,646,928,639,944,992,333,985,742,856,962,990,574,478,609,212,91,436,98,626,24,340,43,700,0,350,674,663,869,983,224,714,513,730,571,99,957,879,21,778,12,848,517,109,962,774,3,214,349,873,995,202,254,735,743,363,915,31,701,133,343,771,166,641,248,130,331,790,922,681,100,124,494,389,151,959,95,150,192,121,412,175,177,166,493,97,364,358,758,934,60,129,849,853,674,315,225,796,66,72,711,137,951,920,30,261,17,461,279,522,645,705,508,63,856,993,99,838,36,480,161,308,734,707,954,292,420,792,523,908,85,933,630,886,928,850,770,230,695,2,817,227,60,383,959,808,837,296,56,269,783,657,794,384,457,316,636,772,222,109,378,1000,859,311,491,518,373,345,895,454,424,392,709,905,26,253,826,512,384,939,652,179,151,932,390,966,599,9,483,759,826,695,778,479,103,232,707,977,674,680,502,866,713,639,465,66,436,593,869,948,41,222,604,119,538,735,721,630,525,985,804,309,43,694,884,994,106,631,100,848,391,569,649,977,207,285,411,697,502,365,411,55,795,94,244,156,726,31,87,146,928,116,866,715,903,629,97,370,624,317,899,491,900,607,559,752,871,82,977,431,33,47,944,962,824,943,383,977,776,171,171,443,262,288,738,587,478,95,621,400,70,667,770,175,595,254,654,166,116,914,51,765,517,205,63,313,761,286,133,873,992,614,292,942,232,153,574,816,12,105,705,408,65,689,878,840,721,651,363,979,175,505,645,640,374,545,71,927,936,466,573,811,589,276,953,243,538,439,641,520,330,461,582,201,580,586,869,24,444,254,720,424,542,986,985,126,634,834,370,131,224,219,612,504,280,893,218,238,615,113,928,488,618,62,926,741,732,239,135,354,286,264,890,476,443,850,698,644,277,406,236,291,363,205,408,671,9,789,25,292,483,39,112,43,908,389,984,882,619,647,52,853,610,547,711,491,729,604,902,207,659,548,70,202,948,645,621,167,657,849,895,938,762,597,882,736,265,483,172,263,353,762,926,132,373,253,794,20,781,73,396,632,450,729,784,192,363,98,273,269,18,773,353,520,456,946,106,650,283,701,384,271,595,31,199,990,938,102,86,891,873,383,595,160,259,525,672,341,878,655,905,120,764,375,409,405,797,107,736,308,369,199,884,477,728,957,117,71,657,147,292,107,562,805,954,233,2,535,902,370,463,127,558,259,294,452,446,729,417,934,332,846,324,580,585,925,896,131,460,380,486,314,771,400,917,194,151,931,663,905,769,187,678,273,306,786,723,801,306,461,884,343,283,455,471,393,63,240,764,37,372,829", "743,904,921,1,526,292,496,817,13,501,567,429,946,750,260,335,736,257,206,410,160,443,447,86,172,313,911,883,655,251,734,945,124,278,78,54,780,222,885,129,527,874,713,84,902,823,231,429,530,379,372,481,460,306,903,228,685,616,77,921,418,690,357,248,369,363,697,177,831,437,989,312,703,121,964,43,811,138,313,218,676,794,328,786,256,253,370,432,741,295,8,726,470,150,976,76,515,606,14,406,150,121,446,376,352,629,395,591,324,52,37,615,902,456,33,502,998,795,913,516,893,133,999,718,102,687,479,880,995,27,271,837,532,528,279,661,311,597,208,255,89,611,876,203,912,51,860,502,987,591,78,24,117,947,500,876,696,685,941,710,71,374,817,196,202,6,945,351,910,86,357,943,181,713,786,507,809,545,697,805,443,746,787,517,391,522,503,633,470,926,835,909,50,111,532,490,838,648,962,128,160,665,691,304,563,516,394,186,971,989,109,519,730,349,848,376,860,652,553,928,290,405,102,35,868,917,878,98,295,884,774,341,374,23,461,83,731,287,222,481,595,69,13,895,914,916,622,322,270,387,738,170,325,166,16,638,815,829,404,393,833,71,303,554,704,836,359,253,434,413,80,747,334,494,314,835,371,671,377,79,737,969,486,37,792,840,841,882,95,205,798,896,473,388,855,140,36,328,373,41,303,959,56,573,969,695,204,34,346,977,693,141,75,649,39,862,150,128,622,879,782,571,405,822,845,707,161,217,595,696,719,106,408,416,888,336,558,770,785,119,590,387,866,72,346,789,966,665,194,429,935,789,239,646,239,889,796,391,282,181,292,304,237,239,886,452,283,621,12,927,204,85,637,935,619,190,578,891,400,119,609,340,909,21,36,165,140,123,723,737,422,445,865,129,104,405,985,9,62,981,926,14,950,785,133,201,538,614,531,984,951,762,715,265,822,102,281,121,418,191,118,646,782,798,411,815,786,357,486,68,67,89,101,908,289,772,607,976,220,220,801,356,350,0,483,874,287,758,117,482,460,195,731,317,209,322,150,986,410,319,629,622,589,998,964,148,392,170,325,577,997,727,359,201,205,854,382,640,473,937,838,987,980,294,702,926,520,264,368,77,941,166,569,607,559,257,620,284,503,629,732,570,557,458,50,780,95,901,98,845,974,77,567,829,742,791,228,149,584,361,268,201,541,841,123,479,51,435,720,307,54,79,122,553,831,250,56,878,222,13,814,252,695,9,791,946,511,758,31,648,534,919,713,421,304,869,436,13,666,401,335,337,604,232,669,756,580,368,154,890,789,309,591,622,361,542,301,869,491,746,260,825,532,584,166,321,360,379,751,100,169,938,15,673,735,828,2,547,682,293,343,593,384,829,841,575,364,78,731,225,370,976,137,251,898,440,278,928,665,297,818,663,323,799,206,154,549,776,212,921,176,525,819,767,298,842,533,167,436,180,483,143,923,103,449,419,238,748,514,865,360,222,306,879,313,873,444,909,309,489,50,51,636,836,372,822,805,541,862,197,287,359,771,558,366,815,602,9,345,847,321,195,680,818,805,81,364,550,776,317,843,503,634,190,512,731,307,673,42,644,612,89,663,569,934,49,707,555,652,739,848,268,585,506,618,419,377,801,693,254,654,292,575,147,157,559,288,439,215,452,478,137,561,309,626,275,347,484,635,276,203,40,962,474,704,219,61,928,504,204,96,959,188,508,731,285,671,671,809,991,607,827,566,980,41,207,843,283,700,487,971,570,483,822,618,709,436,77,543,962,867,931,148,112,427,1,125,284,526,509,452,83,220,657,561,302,109,519,304,837,967,829,333,252,487,906,921,482,305,781,449,697,606,539,727,513,742,135,349,177,923,330,416,40,499,354,505,798,978,35,6,48,906,328,113,743,313,239,260,508,620,845,120,399,360,470,497,720,244,703,763,569,814,922,940,206,386,37,614,906,389,11,177,266,272,838,244,891,205,123,888,540,841,965,322,528,519,346,338,761,855,433,143,238,662,860,256,34,660,862,926,668,23,30,47,844,175,127,368,744,93,397,670,740,502,290,227,981,57,661,48,1000,460,198,594,3,543,447,41,454,216,690,967,277,911,284,813,801,10,55,996,251,502,113,281,682,915,104,18,776,423,461,890,146,689,127,994,103,717,955,228,540,12,104,887,528,313,711,453,986,845,915,765,565,400,300,600,121,415,977,734,925,968,540,400,311,609,171,692,453,659,242,808,763,588,287,317,310,792,450,290,441,53,7,630,96,975,704,773,719", "782,57,571,616,636,971,496,60,488,554,603,305,214,982,770,835,275,564,878,100,759,263,31,969,266,846,852,355,382,860,752,789,127,134,93,440,280,973,490,321,504,485,285,957,34,932,969,45,618,487,613,497,714,451,859,462,884,330,11,286,921,46,416,678,580,825,558,205,197,702,718,823,685,884,641,902,342,781,546,378,583,281,67,46,241,234,539,692,142,727,416,367,31,274,666,980,655,707,836,241,840,501,408,340,150,782,779,588,118,997,111,809,392,592,545,96,165,315,365,608,850,653,686,738,425,47,61,650,54,952,725,118,407,609,816,365,536,955,408,326,744,108,552,558,650,676,69,414,203,827,979,843,865,376,664,625,841,925,331,320,262,349,586,631,74,627,437,365,79,738,274,300,249,842,564,540,475,901,922,301,762,906,852,70,206,768,412,446,238,687,53,58,781,752,141,737,593,979,83,300,157,596,50,302,733,550,423,288,533,628,817,254,209,555,736,88,649,759,300,706,24,580,969,679,610,225,834,640,43,541,408,480,343,426,809,386,580,508,869,586,893,941,447,857,473,115,672,273,447,102,648,147,946,725,340,51,959,624,827,862,659,240,299,268,667,624,226,669,882,972,301,799,563,435,317,14,541,230,279,458,898,299,380,180,365,300,702,672,321,33,236,344,108,67,683,101,429,379,467,902,721,198,854,195,31,676,809,312,23,875,927,471,587,179,478,333,909,772,160,675,16,706,95,848,754,962,723,994,671,646,356,562,172,23,485,794,40,563,760,799,615,844,900,670,640,363,594,689,332,903,404,768,641,373,43,766,744,376,736,791,157,597,874,975,866,194,723,411,791,297,956,397,595,51,799,222,497,883,788,832,335,332,992,313,698,592,8,193,370,787,495,166,197,30,282,737,948,509,740,255,652,707,130,508,878,950,285,49,474,881,729,952,181,593,818,21,745,539,247,164,763,849,578,180,672,39,943,745,156,816,177,79,425,688,791,538,926,219,31,293,13,364,674,483,0,464,874,936,195,396,824,423,949,938,628,842,483,804,430,761,88,539,67,875,15,820,426,248,112,508,615,518,180,920,232,985,272,656,946,530,208,388,860,840,731,436,862,976,213,681,212,353,783,8,942,431,120,837,950,424,939,552,351,454,257,737,835,304,625,930,599,816,120,196,853,71,915,774,425,415,47,68,485,397,356,370,540,947,929,357,524,991,126,923,20,600,284,137,781,624,160,836,500,890,2,323,921,185,7,599,843,610,571,57,668,11,907,247,340,906,528,429,524,300,650,829,268,71,623,487,683,142,337,87,388,635,606,797,535,226,839,3,250,398,332,438,823,344,652,623,497,316,682,840,642,783,757,89,683,881,338,242,160,384,416,108,205,595,749,10,603,981,575,965,958,247,740,757,519,359,254,729,962,250,631,466,70,340,450,763,750,772,465,464,836,214,516,811,608,67,395,360,71,716,408,999,846,999,544,610,352,177,994,276,748,78,89,946,431,509,419,53,622,50,950,927,675,759,422,258,766,901,479,409,765,877,851,558,200,534,692,363,684,280,948,972,601,342,548,965,569,916,81,767,292,394,162,237,861,617,462,591,622,67,552,539,726,103,3,931,781,342,96,351,351,348,779,177,526,582,897,991,310,737,514,809,826,16,889,714,154,294,920,672,561,326,768,308,237,714,115,323,198,498,430,830,803,697,631,508,166,125,23,603,752,217,842,882,329,388,410,161,481,999,155,501,604,635,962,143,117,859,546,308,688,74,47,6,222,240,409,421,521,72,485,306,316,407,6,242,849,636,301,293,881,862,590,758,971,253,184,247,925,974,930,910,548,770,579,283,197,544,329,271,211,468,574,45,654,317,640,47,155,786,625,661,538,659,260,267,160,963,270,673,154,767,712,867,32,93,557,314,665,611,891,689,276,18,788,144,855,218,876,456,534,7,522,800,586,659,772,834,550,732,277,984,406,295,404,270,749,174,918,362,520,573,58,343,466,805,587,996,896,146,477,894,53,598,309,986,590,907,63,639,987,462,416,344,889,392,834,114,616,373,911,905,198,792,952,575,676,985,486,658,406,648,444,988,188,704,926,798,681,452,687,622,654,34,925,647,334,278,519,940,67,844,384,302,680,973,820,860,521,272,497,847,107,619,800,798,786,245,160,635,730,390,14,848,688,676,940,284,622,831,984,196,295,683,38,836,996,586,759,699,770,47,137,56,780,9,965,647,986,851,262,554,678,840,671,411,775,2,292,197,350,207,941,933,784,796", "307,300,881,56,479,911,11,55,468,308,219,249,615,754,616,795,889,20,601,184,557,107,376,54,117,943,934,373,885,519,537,194,534,83,119,136,315,851,915,88,180,460,332,401,357,6,164,489,268,369,710,562,335,366,688,880,920,696,827,664,310,363,504,504,770,791,913,599,640,957,468,581,860,670,716,258,307,94,361,224,413,350,889,200,360,279,839,287,990,31,831,56,337,907,12,468,99,294,551,551,165,431,2,276,368,16,49,165,40,377,18,756,516,983,585,556,411,324,642,186,993,412,264,571,756,917,995,106,328,368,937,634,994,954,204,861,820,806,109,313,59,321,201,992,888,657,418,45,42,290,52,359,963,756,262,748,792,162,280,196,885,176,668,605,578,247,915,43,654,694,484,831,671,805,796,98,932,930,963,379,824,855,170,630,346,914,274,181,686,781,518,706,964,195,419,52,934,33,740,207,613,937,260,974,518,98,692,357,175,459,909,433,700,67,391,631,114,343,292,501,922,677,476,589,235,936,734,491,372,208,174,965,995,109,624,383,607,363,56,309,686,613,309,892,406,863,461,582,967,492,539,308,135,535,652,919,297,288,900,882,344,988,495,811,656,169,324,141,652,2,989,363,909,761,291,125,343,236,277,325,420,440,142,26,856,33,656,347,616,368,455,509,702,673,955,996,924,152,977,286,22,647,504,103,998,655,6,305,414,675,320,971,151,510,900,284,538,929,931,788,784,322,653,83,230,879,537,85,137,793,431,291,175,312,244,83,808,131,959,100,876,73,476,448,52,182,893,43,111,668,875,370,382,265,970,702,595,148,629,870,475,114,192,268,749,239,846,102,721,234,864,988,355,221,298,234,852,370,179,246,226,900,930,352,500,534,654,420,835,803,421,756,927,181,109,383,533,390,643,816,866,946,668,302,649,802,124,488,389,116,741,445,436,672,266,551,331,542,872,706,61,969,528,493,570,568,160,984,807,382,655,115,972,910,994,544,415,649,701,322,718,379,663,874,464,0,644,851,595,711,827,319,936,265,974,986,23,529,566,549,777,870,833,552,691,169,900,342,189,387,33,116,410,180,679,726,862,893,643,284,904,82,140,395,332,734,784,222,772,848,777,878,100,222,805,593,84,664,31,500,942,531,714,761,899,461,811,146,776,470,551,21,600,128,201,840,532,132,9,226,460,233,287,925,762,58,749,459,336,484,561,651,357,912,887,300,911,168,420,352,467,907,520,636,494,385,745,613,561,897,651,558,13,681,224,595,675,498,780,577,909,333,337,128,308,854,594,285,23,55,824,389,604,391,4,146,644,300,647,778,290,909,832,255,424,987,618,771,372,794,869,882,995,35,989,707,877,767,243,155,524,807,342,534,710,706,716,188,393,856,639,680,495,980,592,392,393,290,230,925,591,970,237,896,745,641,665,285,138,885,802,532,945,336,751,854,278,506,227,961,495,2,884,691,997,337,229,518,896,17,261,235,44,220,888,458,257,15,962,109,93,247,530,634,625,162,764,814,390,941,241,114,12,67,564,349,620,945,230,889,529,767,261,354,414,310,807,866,585,665,299,940,117,587,275,296,119,568,950,169,179,368,759,874,242,922,112,938,286,551,750,270,10,269,580,668,393,595,553,254,173,890,503,961,319,741,177,287,169,404,920,485,762,681,379,473,781,161,927,409,958,85,15,538,200,465,430,650,167,391,26,301,781,64,401,869,627,958,252,776,802,763,804,438,693,825,336,105,377,747,535,786,471,383,278,306,752,494,54,353,844,777,185,699,171,577,472,561,54,804,491,11,440,289,146,390,316,814,409,964,399,482,21,242,895,753,733,191,273,794,71,849,518,569,230,662,769,20,373,354,374,534,136,201,619,513,628,975,45,923,485,300,980,23,984,608,963,952,436,138,933,515,446,252,833,919,501,27,800,633,282,856,989,1000,447,371,938,574,642,637,809,913,744,129,228,351,213,232,586,464,33,522,96,568,637,191,244,762,419,246,474,768,165,721,439,50,502,912,145,436,671,530,289,105,106,881,994,173,415,685,242,682,864,184,487,853,258,972,554,135,771,648,12,38,469,785,960,362,370,350,728,998,101,58,549,527,364,903,993,163,304,185,724,457,265,588,603,494,684,871,171,801,791,191,683,785,585,267,998,212,791,745,888,791,483,710,912,750,290,667,49,648,228,924,773,500,278,239,791,214,743,556,996,662,602,541,883,200,498,879,167,279,971,55,725,268,136,600,141,98,714,412,547,758,627,618,505,381,777,601", "217,25,136,840,5,75,736,644,882,765,116,866,806,830,285,476,782,282,181,760,90,810,337,190,569,782,587,63,355,992,269,17,111,776,559,573,45,618,233,411,579,646,652,497,341,935,150,758,900,879,184,331,173,617,541,350,645,377,62,68,395,258,122,476,163,655,442,546,318,156,971,768,553,750,337,677,719,985,430,253,450,631,67,893,23,15,899,879,423,31,120,323,938,365,390,185,245,924,863,4,836,117,711,627,558,43,760,68,692,887,725,786,99,37,133,911,813,735,612,884,924,931,249,146,480,450,865,396,815,336,279,860,699,983,124,881,346,42,27,585,171,621,120,417,318,64,123,892,175,699,739,593,899,522,536,896,824,783,189,478,443,113,271,728,130,218,382,652,323,775,376,162,941,311,315,110,800,103,757,954,768,228,479,651,917,402,126,709,748,230,900,908,438,520,840,261,5,112,42,437,294,64,504,303,662,384,564,292,401,387,879,50,146,594,878,898,92,94,270,212,576,424,758,505,991,248,550,598,633,13,32,541,379,242,386,989,308,630,942,150,930,471,546,521,606,696,470,111,488,141,484,270,724,806,347,614,248,541,297,684,789,403,933,439,209,337,767,420,525,386,474,988,47,198,953,123,672,223,541,866,677,19,16,911,302,904,852,89,445,860,946,719,665,700,1,660,715,867,998,344,707,224,694,791,746,963,799,192,687,716,534,864,286,620,472,790,648,102,770,224,232,949,260,781,984,532,378,672,934,949,748,504,21,530,526,318,264,274,130,10,187,206,566,223,129,17,308,67,242,839,578,481,404,32,765,410,205,664,612,518,539,413,889,26,214,307,327,236,756,631,675,188,569,790,952,533,170,33,254,234,50,214,24,38,614,277,828,252,635,667,537,966,18,970,612,982,891,708,3,829,808,187,896,359,694,862,126,39,51,66,32,600,349,404,148,526,630,256,952,585,25,548,965,941,791,166,739,879,493,535,20,623,5,948,455,376,216,513,784,881,210,739,869,287,874,644,0,243,887,707,355,670,883,133,106,303,488,887,246,440,460,976,831,439,118,5,623,562,499,427,683,869,77,583,919,219,653,75,801,108,423,457,166,239,755,95,575,153,356,817,770,25,869,58,628,299,124,824,823,277,410,392,296,136,944,136,5,501,248,895,549,57,724,957,920,88,74,363,428,990,65,832,291,372,902,447,646,240,852,468,879,737,20,346,45,955,484,457,994,357,860,704,134,11,354,714,103,414,915,661,409,85,706,752,286,40,928,46,545,417,454,115,619,872,218,61,592,148,929,915,382,762,793,914,52,977,278,365,291,677,457,6,491,488,826,662,586,305,703,259,842,211,815,586,179,541,555,797,680,913,997,283,154,996,134,194,44,574,50,110,862,989,575,888,181,851,948,21,897,446,986,52,853,810,937,189,183,127,749,348,107,979,104,666,616,274,588,554,11,8,480,59,812,919,36,870,143,186,335,246,517,357,455,169,657,636,480,284,815,455,523,945,939,961,757,816,391,906,358,615,792,103,960,894,626,132,582,87,515,628,590,295,664,940,559,486,784,845,750,833,621,460,272,287,982,162,831,988,468,393,921,183,267,742,350,177,787,485,332,437,599,43,271,989,358,613,744,880,730,670,67,502,697,314,61,925,108,805,949,964,960,985,325,49,388,604,548,153,84,901,775,731,454,67,807,824,85,623,156,727,990,888,391,428,103,385,914,225,857,753,915,624,935,211,745,136,251,697,702,906,713,546,444,293,859,93,245,826,835,382,518,509,939,924,184,799,957,57,757,470,140,582,500,309,595,818,64,113,287,383,818,339,526,381,484,375,189,863,139,797,484,276,218,80,484,625,116,53,352,537,684,191,546,170,555,192,903,596,550,419,664,372,314,638,59,574,976,149,705,97,234,117,790,52,986,548,347,575,471,834,586,709,332,695,953,867,583,846,360,88,627,150,850,729,992,150,98,75,598,248,580,164,706,560,614,630,194,782,449,353,596,226,900,34,224,435,576,500,245,884,130,582,822,570,415,976,962,243,538,372,713,218,566,533,265,953,969,386,64,878,207,610,45,680,345,57,93,683,826,948,849,900,469,78,890,380,857,423,34,337,689,274,55,732,582,614,881,451,496,224,724,240,544,404,828,80,50,158,868,342,312,201,319,805,621,294,162,510,250,369,828,866,871,907,284,406,299,456,988,881,393,396,324,60,783,8,520,28,143,286,923,451,75,154,956,375,799,383,729,157,709,193,935,16,529,701,757,938,113,487", "300,764,929,279,507,372,304,75,55,21,700,917,995,347,53,438,111,239,67,948,236,726,941,765,848,4,181,426,856,431,534,71,140,666,730,551,946,170,310,666,823,646,723,954,915,715,917,882,283,180,734,422,57,742,431,167,439,225,749,429,674,600,282,956,516,454,254,228,278,895,911,770,986,744,274,931,216,312,533,160,684,581,676,314,338,883,956,343,394,272,564,678,747,612,838,779,167,421,722,401,206,927,860,687,74,54,728,933,72,30,75,738,25,585,53,352,375,804,9,735,3,814,105,182,981,141,166,179,6,764,709,321,576,880,761,975,651,225,67,668,158,288,187,876,838,942,782,207,707,784,193,862,238,411,412,387,167,431,572,397,998,918,103,962,533,124,691,149,880,770,101,720,972,671,259,36,465,239,320,468,429,987,554,281,3,843,751,315,341,202,447,984,469,770,813,689,819,280,910,870,752,359,512,84,385,197,335,24,641,36,122,969,287,905,854,926,39,85,401,410,653,560,611,126,761,617,792,199,894,145,149,207,29,713,102,689,517,534,585,227,657,581,487,596,107,262,58,707,52,588,514,975,678,421,823,55,255,751,540,607,924,97,647,472,60,464,556,661,765,895,689,188,202,901,111,59,309,508,93,930,880,896,113,70,747,743,610,776,551,305,323,480,312,865,897,71,693,421,798,928,184,939,556,251,150,964,948,246,697,228,165,515,317,116,207,764,845,692,317,987,468,46,220,147,101,242,257,33,686,304,489,946,872,185,624,220,566,19,746,286,721,516,432,59,886,859,128,680,463,192,301,687,542,479,279,505,206,134,345,621,947,345,204,765,230,831,857,253,501,117,353,653,43,928,521,176,309,750,572,529,828,514,28,23,972,890,67,128,123,140,491,737,921,318,591,538,592,716,894,559,115,894,65,855,397,642,918,284,350,202,617,152,916,653,297,757,941,309,43,613,129,960,155,240,656,403,508,482,195,760,218,283,891,823,220,714,665,247,748,986,541,778,983,758,936,851,243,0,273,132,575,545,444,13,957,917,128,842,218,73,640,966,639,127,251,95,334,987,822,368,828,305,165,63,421,614,169,235,41,419,828,802,937,116,789,56,23,963,672,671,798,683,583,312,994,546,585,980,352,313,272,242,460,442,258,884,545,824,66,526,434,805,995,267,946,179,674,450,915,111,682,763,458,319,864,397,562,132,414,261,795,441,809,433,647,114,221,864,68,830,340,250,373,993,984,959,711,509,616,625,749,702,125,917,247,868,896,432,341,691,159,463,126,957,610,516,798,306,571,90,577,266,627,550,991,65,696,215,338,550,145,933,832,974,270,468,618,415,921,789,923,372,42,787,777,725,340,835,889,143,409,269,935,878,485,983,806,685,701,291,127,629,386,784,89,452,733,910,215,160,399,415,503,327,198,198,983,407,335,511,493,295,286,527,415,532,128,402,857,319,684,688,815,480,445,33,954,430,554,885,121,869,530,624,2,55,950,347,84,239,219,197,448,186,160,326,168,24,313,275,36,422,429,696,229,967,788,278,215,74,8,56,425,669,990,341,444,513,902,122,366,582,402,955,410,400,989,241,125,226,977,605,934,325,761,989,741,379,651,638,945,570,256,334,708,751,957,474,911,814,803,722,602,750,571,120,723,49,425,218,332,671,299,2,577,297,213,206,721,437,75,241,55,728,9,456,51,259,679,522,328,934,411,789,986,921,413,210,332,791,309,626,474,194,988,522,529,130,871,633,265,637,616,26,232,587,47,376,12,471,952,179,770,172,636,234,110,284,341,440,250,772,974,945,111,335,562,224,183,63,419,612,571,54,62,536,793,672,529,516,194,992,579,476,571,751,536,817,960,874,957,511,110,692,566,99,470,576,282,440,874,775,56,704,219,192,111,364,169,171,602,505,945,173,883,369,670,53,524,616,846,795,650,542,326,739,734,129,660,639,247,823,723,979,593,456,384,815,638,938,609,288,45,308,938,467,884,330,364,884,89,490,917,429,504,733,844,190,642,567,129,379,181,136,882,651,131,917,305,162,827,185,280,790,836,201,494,249,449,533,947,99,181,176,161,89,731,665,942,27,651,7,959,840,801,122,142,617,32,228,718,938,340,618,686,34,781,831,627,814,294,341,486,985,171,35,27,647,739,846,238,5,557,973,819,422,890,445,367,572,744,25,262,333,655,456,311,161,957,886,911,7,996,302,347,922,302,804,535,204,37,28,661,226,437,131,874,739,989,487,656,878,258,393,360,603,14,188,290,497", "921,822,603,360,903,893,833,828,957,90,81,643,342,307,328,863,513,124,392,417,31,401,164,333,29,9,150,759,482,249,749,346,94,238,577,512,498,822,207,622,552,736,774,711,969,705,757,410,575,385,656,773,969,763,160,230,144,254,428,398,978,159,580,910,58,874,109,461,248,40,401,537,828,406,440,718,404,269,791,923,446,715,376,104,420,486,77,33,162,424,412,658,232,555,570,893,257,679,695,199,404,426,923,573,592,589,705,431,678,279,975,466,527,968,257,189,67,175,931,822,993,447,87,866,522,430,624,185,714,768,55,250,978,610,916,663,666,979,745,212,100,234,311,684,383,358,515,156,949,185,398,377,644,92,970,206,285,415,508,643,480,35,746,160,113,171,663,287,993,436,431,142,850,953,897,373,886,995,138,704,62,312,546,868,724,431,187,581,702,721,867,665,428,52,183,953,542,273,394,483,722,252,205,232,636,906,56,882,736,158,485,132,717,268,354,216,258,15,965,314,776,613,684,521,846,893,125,585,50,895,962,350,23,995,4,87,879,230,447,670,562,576,344,485,771,234,387,999,191,884,735,982,859,651,659,819,134,893,705,97,909,40,168,436,916,186,878,27,188,997,529,526,113,502,778,230,588,209,296,287,169,836,940,499,911,67,741,893,962,686,546,124,211,973,220,993,607,422,36,254,809,506,907,670,5,631,14,772,27,518,215,13,488,925,135,989,532,83,895,416,558,234,989,257,632,874,23,573,308,593,377,66,153,207,399,562,455,89,22,133,932,866,301,665,645,795,246,914,890,848,943,633,126,433,535,457,549,569,687,479,59,198,721,103,649,432,183,514,837,799,900,26,291,481,398,603,726,839,220,83,166,287,913,638,115,443,650,254,144,763,955,991,459,468,671,694,665,861,718,550,781,879,612,682,600,428,199,640,352,920,213,551,220,183,509,433,583,795,676,25,466,36,964,897,113,222,535,556,832,929,685,178,250,735,27,443,68,109,197,460,234,17,224,117,195,595,887,273,0,640,113,257,734,359,849,616,392,167,369,181,754,28,812,886,493,24,693,302,884,690,225,480,750,30,180,657,392,484,368,809,599,561,207,857,634,367,371,796,82,688,980,720,150,584,308,854,723,249,703,370,116,758,948,28,448,635,880,494,901,324,465,283,176,735,887,236,245,314,913,807,771,922,533,257,674,692,631,759,395,599,447,588,365,572,744,746,983,698,515,124,396,260,163,34,142,855,995,406,786,688,983,109,986,968,986,7,812,501,503,129,948,383,620,968,325,723,398,818,454,395,824,859,368,107,439,522,741,585,931,983,186,785,586,190,857,955,562,256,969,593,439,467,813,111,979,279,771,712,62,952,356,690,757,295,840,821,459,694,174,8,361,479,68,583,789,652,345,93,561,471,433,95,93,475,694,172,629,625,40,430,369,330,66,459,189,887,230,187,489,134,808,175,905,467,265,965,742,242,874,42,428,146,636,929,141,370,515,8,122,85,777,489,762,122,894,186,588,371,207,120,3,234,473,629,443,472,532,171,648,294,786,803,293,679,573,115,511,880,711,98,976,739,499,434,486,472,550,268,961,538,575,864,740,128,791,877,46,599,376,787,357,962,911,60,354,916,932,84,665,675,621,631,989,735,672,122,662,951,300,408,532,655,948,286,855,864,977,872,61,664,32,663,816,521,474,407,760,930,197,679,137,711,813,71,9,488,617,997,789,935,935,533,796,802,508,953,788,127,148,518,126,939,28,225,803,898,252,63,3,242,665,252,886,417,474,992,577,721,203,943,68,123,293,771,255,909,329,864,355,841,431,695,913,693,23,508,120,464,795,568,977,30,472,271,495,74,134,608,701,19,678,306,803,315,863,196,686,48,233,468,499,816,930,290,845,737,438,478,439,188,436,901,515,683,574,473,142,456,766,903,454,322,28,609,827,870,814,270,906,700,491,948,151,577,900,729,953,794,654,516,712,646,806,811,200,380,558,744,170,814,386,104,96,972,718,20,372,716,404,849,647,970,134,778,656,66,894,4,89,291,246,410,69,422,868,203,512,159,227,396,327,503,255,575,453,378,816,808,157,688,438,484,120,216,138,501,531,802,886,517,746,424,507,28,183,175,175,289,251,717,753,250,868,581,806,146,104,284,820,822,594,507,33,607,572,640,63,811,100,623,214,424,617,787,446,636,701,34,503,722,687,829,494,348,812,552,867,97,15,504,399,977,421,78,171,498,468,384,134,804,785,845,666,199,639,671,75,236,199,605", "699,924,541,881,582,645,818,940,676,896,797,376,454,907,586,968,612,132,420,32,662,701,970,29,912,250,108,41,935,153,690,433,763,476,305,121,696,343,709,516,797,920,525,560,325,142,801,610,250,757,368,240,753,653,559,370,684,640,828,218,776,38,714,924,44,790,973,448,68,6,454,413,355,511,584,170,667,365,337,836,247,467,308,205,650,460,974,1,634,28,829,282,164,666,692,643,982,339,710,760,31,777,38,903,132,707,572,233,623,982,20,314,29,710,396,526,338,660,509,273,860,991,361,160,275,365,11,829,851,66,377,454,104,66,457,803,131,91,443,307,387,409,13,830,203,442,86,778,935,101,87,988,769,163,185,150,28,828,873,909,700,480,757,165,147,979,989,286,17,886,498,937,73,418,151,150,658,955,741,128,621,515,689,237,22,85,248,666,278,144,930,607,5,83,658,31,405,568,280,260,46,646,644,734,503,268,491,104,247,574,128,834,493,478,57,738,48,55,372,429,853,10,542,222,86,361,158,301,167,434,341,559,352,603,743,881,545,525,768,760,758,616,27,476,771,948,222,898,904,61,582,967,579,104,997,510,969,40,465,736,524,590,752,467,450,535,106,520,380,786,399,949,657,739,36,1,122,861,154,295,305,650,51,591,306,367,179,184,959,133,652,136,368,381,501,465,270,174,342,615,233,224,596,553,884,92,322,550,872,990,988,482,727,720,796,610,798,19,67,304,829,773,565,734,114,347,836,964,6,246,609,293,654,775,501,869,355,8,466,551,64,103,530,923,222,978,128,124,574,1000,940,469,222,45,942,987,695,297,387,348,184,537,265,752,146,889,358,563,527,778,845,931,268,504,924,753,487,985,668,909,105,898,720,562,659,601,42,87,983,818,239,102,321,560,593,220,714,312,728,82,23,153,569,917,803,772,432,921,951,971,461,365,751,426,485,436,88,826,165,984,931,639,508,153,453,377,522,91,874,285,882,397,357,581,96,281,275,744,659,682,577,380,714,482,396,711,707,132,640,0,644,651,491,933,168,845,866,419,93,555,108,127,957,795,804,576,632,933,72,205,952,678,383,621,825,249,426,159,911,558,133,783,346,664,169,143,466,436,930,2,508,64,369,520,176,421,148,537,679,68,787,292,784,38,845,367,811,802,480,728,219,999,376,978,115,881,529,91,567,218,583,794,341,12,392,569,854,168,976,425,274,39,296,852,570,936,889,554,17,464,675,955,30,764,405,278,219,517,168,492,394,453,817,220,943,480,873,943,997,156,179,769,563,233,424,402,734,547,512,36,24,547,787,22,887,199,120,727,160,670,965,324,235,302,895,899,55,947,840,214,139,970,177,627,576,902,342,969,611,141,789,88,808,389,780,224,621,529,409,400,292,441,525,60,707,345,741,116,438,785,113,290,984,793,341,988,712,449,629,147,491,932,165,793,209,799,107,616,649,434,959,555,634,699,354,881,847,288,309,886,507,270,273,168,987,874,190,97,210,407,464,266,485,510,12,661,548,523,6,434,570,171,88,377,773,800,38,471,649,782,847,939,952,444,604,824,125,473,667,398,118,62,67,924,614,633,15,375,866,547,48,765,377,499,451,246,956,130,966,494,759,884,200,69,23,172,175,816,266,781,35,396,674,163,624,372,978,876,524,989,321,36,378,94,1,90,387,111,283,974,600,918,954,331,981,507,738,438,11,528,140,521,690,106,374,457,226,27,850,598,939,453,676,563,751,458,176,885,496,927,747,382,884,928,896,750,650,454,725,534,820,617,215,944,957,428,158,370,346,148,496,428,977,498,144,196,341,773,863,406,751,151,667,468,717,434,783,250,712,430,242,648,439,798,932,518,636,984,513,576,248,902,725,821,510,158,931,545,616,565,439,498,601,690,601,973,61,936,751,896,803,395,694,17,753,271,724,108,314,629,614,760,388,672,572,780,319,726,28,816,569,479,754,142,653,765,786,488,121,746,385,132,162,993,435,81,610,390,841,4,86,380,973,500,822,590,106,909,696,730,67,277,232,436,562,909,108,829,717,285,724,234,36,919,606,875,822,222,676,891,42,340,949,940,868,752,730,697,712,14,795,812,368,734,495,619,482,846,764,47,93,348,571,792,205,234,221,761,734,810,145,711,889,321,343,656,654,63,245,241,300,22,135,868,641,469,649,281,467,833,343,15,986,226,63,301,774,278,745,957,895,583,745,700,827,698,228,425,824,230,675,510,926,483,516,207,510,49,624,469,108,473,220,389,633,437,625,878,452,474", "664,415,608,322,708,46,393,472,962,523,552,830,80,272,148,418,587,854,237,105,587,386,893,140,235,699,327,484,310,479,798,920,234,108,271,319,882,784,536,927,640,528,275,608,606,41,354,677,256,762,38,606,370,669,92,11,776,527,547,907,777,219,893,742,194,791,7,611,529,898,813,596,786,242,437,94,436,22,97,374,900,691,82,953,671,172,451,212,205,281,734,777,198,936,301,434,530,890,383,341,743,494,803,199,945,468,165,655,365,454,630,443,3,484,644,179,322,231,536,559,743,87,914,748,73,402,334,126,382,413,416,766,222,251,829,574,455,754,57,77,699,711,790,460,465,53,650,145,827,621,919,348,777,903,944,756,700,688,78,472,686,816,354,856,938,185,894,927,670,37,215,603,496,780,510,674,919,66,54,759,308,562,495,628,475,694,365,747,745,280,758,976,42,425,838,666,940,481,606,958,134,610,155,226,704,249,510,979,348,450,509,633,432,864,465,64,415,922,866,356,534,173,958,264,373,784,253,152,565,478,340,335,740,456,175,701,821,902,351,891,964,897,440,991,822,646,548,983,161,975,633,641,813,193,684,900,117,430,170,278,187,640,346,686,793,612,365,435,326,433,989,186,355,137,815,223,596,671,948,294,621,784,843,516,344,989,193,126,268,355,486,317,39,677,121,223,970,372,796,442,76,810,548,128,803,385,939,231,89,744,697,914,950,418,639,298,677,436,881,356,696,702,927,77,718,303,56,179,112,197,915,790,175,550,359,672,99,107,958,454,178,78,443,836,415,803,763,686,541,964,841,955,160,903,354,256,976,993,204,131,359,94,499,280,372,940,912,824,847,267,532,634,906,171,448,958,356,155,406,496,670,42,28,565,545,748,936,329,659,698,606,151,285,65,497,84,309,495,657,912,322,459,183,8,428,648,808,366,400,786,585,239,784,89,272,142,814,372,7,314,323,117,14,469,623,65,720,507,285,509,756,63,593,616,129,103,478,465,637,693,762,471,513,460,824,827,355,575,113,644,0,425,713,905,330,179,301,756,670,437,365,795,517,16,261,666,483,922,19,904,611,37,974,694,30,509,206,429,572,158,645,155,744,123,343,257,890,666,894,227,417,619,429,71,460,50,138,310,280,719,457,508,951,678,426,92,678,525,119,42,426,227,80,942,800,827,492,193,834,425,677,594,630,166,679,36,29,68,452,391,43,993,634,392,181,302,522,621,954,231,527,246,162,874,292,507,51,277,228,773,384,463,595,274,118,929,972,689,285,910,408,583,474,823,731,370,352,19,1000,652,891,748,670,457,946,44,486,797,501,420,536,359,93,88,248,161,16,798,191,744,521,171,470,808,113,270,957,344,127,729,104,968,8,289,248,289,265,224,825,569,429,851,715,305,869,306,50,466,461,112,733,205,758,128,484,540,267,971,943,71,929,323,659,345,63,923,264,514,556,757,632,649,23,310,420,467,532,419,240,90,138,988,613,207,514,467,84,682,716,438,306,928,324,80,486,433,160,865,779,752,212,862,179,299,413,159,374,132,853,711,635,985,150,771,549,192,652,636,572,623,950,109,419,40,813,554,839,337,280,900,222,483,30,962,771,403,515,861,52,441,936,389,510,641,740,821,82,286,484,426,479,704,727,699,308,111,871,605,51,710,348,403,810,789,753,542,343,436,599,229,112,507,685,551,599,178,94,425,371,574,499,167,480,58,107,704,574,617,196,676,129,781,556,363,373,956,382,636,352,779,295,655,238,7,740,259,583,796,379,576,348,984,141,608,637,528,759,864,673,220,855,824,68,535,614,373,31,396,509,463,136,912,358,792,608,413,275,150,281,235,391,261,152,925,331,429,917,494,805,755,362,5,390,675,204,480,414,727,879,658,713,81,638,7,449,620,663,865,315,48,50,161,475,80,160,458,507,968,672,409,542,50,599,494,776,179,356,626,782,622,211,180,106,848,329,244,557,798,876,562,960,629,906,970,747,950,670,259,666,181,237,47,753,953,121,524,625,337,664,731,242,981,596,403,950,223,275,610,578,553,127,766,382,303,266,507,153,70,664,439,803,77,850,387,256,381,720,710,238,994,929,843,287,949,904,257,325,890,401,30,327,414,874,438,147,259,150,20,802,186,803,138,386,222,53,699,933,794,426,488,516,523,570,778,564,862,123,450,863,842,695,90,214,554,438,427,517,65,703,574,137,700,301,355,730,788,557,466,387,495,767,569,655,69,884,704,783,152,750,596,175,479,816,53,838,334,613,280,621,298", "638,526,192,51,988,588,83,291,686,627,261,70,419,5,573,596,75,215,683,936,896,504,714,194,107,235,810,671,228,16,523,377,412,940,3,114,50,44,635,196,771,84,310,849,24,143,808,631,346,958,996,95,632,563,648,147,768,917,878,171,374,167,108,90,842,84,495,970,32,587,453,224,34,971,183,861,403,372,577,108,536,248,964,590,88,52,308,204,31,59,44,428,868,134,791,904,495,602,255,735,289,746,215,569,326,223,377,431,751,96,211,259,32,64,84,307,49,908,997,356,440,907,494,708,861,424,154,708,266,191,738,478,624,188,92,244,345,757,314,998,945,543,604,333,625,196,82,142,375,677,621,968,113,7,825,461,27,908,595,648,348,482,107,105,667,188,696,461,62,421,155,985,849,720,494,498,309,327,875,399,411,369,765,46,195,996,46,250,835,548,757,638,345,266,882,825,881,265,504,519,862,520,834,463,494,43,650,345,461,900,984,55,500,833,615,714,945,233,763,852,444,113,54,767,692,509,645,883,27,161,627,142,478,947,897,631,884,770,609,51,32,960,584,799,595,549,893,571,75,345,713,223,458,208,163,190,660,963,916,869,877,594,243,248,205,969,652,443,496,937,228,966,400,932,922,771,212,721,873,751,745,770,674,464,890,911,442,784,716,241,894,21,563,298,919,139,948,380,989,576,181,348,102,836,918,156,740,13,420,92,607,666,81,758,492,457,452,370,555,810,582,516,46,11,906,681,768,462,537,849,601,347,261,460,950,138,243,889,719,596,140,407,681,71,506,41,554,993,660,293,714,453,479,720,410,635,698,496,71,772,825,873,314,101,837,100,273,173,979,678,241,787,630,660,540,571,462,138,101,311,116,965,354,748,127,890,96,29,743,72,750,292,542,357,917,507,826,334,662,428,876,249,498,989,580,626,914,116,436,956,818,385,196,727,197,241,757,9,887,994,576,597,87,427,765,29,854,492,921,41,818,706,976,93,348,214,925,243,397,72,32,417,730,195,423,319,670,545,257,651,425,0,782,771,246,820,976,490,899,697,447,279,332,434,300,629,644,500,160,842,464,507,998,610,281,653,484,910,961,46,777,667,440,842,827,914,835,20,687,903,380,83,47,16,937,977,377,707,936,999,729,496,705,820,880,801,896,209,756,504,770,626,199,445,524,471,200,902,553,969,253,813,210,519,361,5,176,375,83,149,966,697,487,360,515,481,917,938,248,18,811,905,702,173,890,319,205,960,425,559,354,942,193,116,617,547,15,727,40,777,581,268,383,218,123,568,337,822,648,397,19,591,360,60,436,54,793,550,531,362,649,344,75,631,424,184,639,493,595,907,35,201,953,40,390,600,522,19,518,177,72,851,980,716,32,314,670,860,753,346,556,765,741,870,347,314,746,867,241,901,308,835,960,88,731,219,803,897,752,316,208,271,11,133,153,696,491,129,324,530,416,353,382,275,937,640,666,776,410,989,33,270,115,295,116,663,407,735,590,566,202,194,348,651,720,212,717,967,452,759,503,916,755,840,924,1,467,54,791,509,555,62,692,85,826,194,115,805,969,87,818,350,812,778,110,506,707,855,28,430,578,570,265,835,983,360,115,698,648,171,838,983,534,999,305,585,999,805,450,298,785,6,500,375,148,523,398,479,980,454,379,50,888,429,24,430,968,339,476,485,730,91,503,618,714,2,495,894,223,117,462,78,48,729,2,23,918,762,131,181,369,535,528,743,500,338,345,703,720,14,279,878,349,321,935,720,574,463,428,87,658,894,707,160,70,758,47,721,818,4,433,107,382,337,742,761,137,435,356,344,169,960,15,378,162,339,867,752,858,274,326,485,110,839,100,412,687,447,295,263,673,345,447,873,673,819,927,671,207,710,779,328,368,710,55,528,889,805,765,659,969,44,588,753,417,663,904,930,610,409,678,285,594,449,786,617,96,928,423,188,418,114,901,241,466,202,635,824,487,772,80,24,875,834,382,978,932,410,956,526,416,148,406,713,761,325,329,144,114,780,827,356,370,596,369,657,368,189,890,320,157,380,679,38,527,83,274,361,783,190,237,255,779,980,91,130,535,749,855,84,386,764,144,40,177,248,178,816,387,673,463,803,557,552,758,447,893,552,813,413,683,562,356,15,761,738,305,854,830,731,315,590,94,452,703,527,555,730,631,892,890,19,434,239,540,760,13,96,236,348,260,556,468,553,577,392,146,956,76,453,876,143,465,508,18,690,395,879,552,342,756,814,772,581,427,314,664,568,413,1000", "862,689,118,34,190,209,161,410,734,549,428,754,980,844,76,620,509,617,27,276,571,103,880,802,968,357,440,616,455,948,877,243,319,181,842,682,969,664,64,441,42,867,23,432,257,419,319,367,46,347,268,594,939,247,146,620,612,662,169,22,982,282,776,49,923,711,657,204,106,294,932,401,792,377,701,581,287,600,534,868,588,362,243,184,359,917,162,975,755,730,602,45,909,282,860,178,720,947,600,405,768,913,126,398,41,16,409,708,177,857,43,498,20,403,654,612,586,53,133,393,225,41,554,119,195,288,295,437,430,501,345,932,261,467,927,25,503,439,672,946,575,563,597,270,418,927,191,187,858,779,226,818,739,657,55,457,745,411,888,622,398,553,360,813,708,521,225,921,695,138,933,462,296,901,892,397,677,165,78,174,414,623,31,209,31,684,60,137,950,453,600,948,809,626,914,85,111,452,568,983,846,173,415,678,761,899,440,97,299,466,141,18,371,123,475,813,826,408,985,741,898,685,871,864,524,884,76,521,376,135,579,342,839,308,650,813,358,546,393,474,605,925,630,186,70,666,203,171,541,78,549,506,778,88,803,696,765,903,350,348,202,959,893,627,396,323,717,64,579,72,309,143,677,588,721,485,478,563,549,477,172,540,713,388,826,659,827,350,727,705,320,221,829,476,46,56,125,385,365,319,187,436,450,314,398,571,724,703,267,875,610,364,144,349,190,819,374,447,137,745,467,64,822,373,21,353,67,585,242,302,752,793,171,647,206,538,714,227,349,42,856,96,184,863,17,14,376,403,924,564,914,292,436,349,693,762,710,304,377,856,627,561,96,725,935,539,22,374,803,193,962,807,525,603,562,975,95,385,920,278,657,849,190,685,664,411,570,268,132,354,10,624,841,768,876,301,207,700,347,343,890,544,404,303,529,850,241,379,308,210,474,302,834,500,681,558,40,661,461,562,230,629,267,328,173,473,94,643,774,33,812,760,459,465,546,854,149,242,486,989,681,455,571,731,949,936,883,444,734,491,713,782,0,491,316,550,702,383,413,197,565,560,382,670,397,645,809,206,682,790,176,546,976,330,151,977,666,197,926,959,743,544,422,242,553,432,803,700,841,6,415,119,812,184,978,164,739,855,507,830,395,609,901,116,291,927,897,515,929,988,630,449,253,582,508,866,912,469,92,996,771,716,509,893,115,632,410,209,834,732,838,715,262,210,933,156,656,823,454,675,363,551,969,517,602,959,543,579,14,993,632,879,247,7,557,7,232,614,418,571,800,582,193,312,928,477,135,745,996,933,4,112,765,472,592,146,541,481,198,668,668,316,968,59,835,645,467,963,646,820,811,693,972,279,151,990,223,627,827,893,191,36,423,839,421,971,533,533,373,52,827,199,820,199,767,177,976,331,202,438,757,21,443,286,237,935,889,796,643,885,505,473,657,815,534,147,270,906,119,504,112,569,132,787,642,526,560,984,89,523,477,201,933,101,841,524,922,236,618,218,894,769,450,859,973,176,864,46,989,657,405,625,460,694,438,4,719,637,637,476,493,275,223,40,216,857,553,645,94,635,390,676,934,776,514,947,429,748,781,905,844,303,800,96,803,506,21,887,502,793,88,6,189,952,519,332,306,677,78,917,636,741,216,617,246,676,952,204,376,141,586,219,596,141,642,12,112,388,178,891,751,325,261,321,627,127,248,252,134,682,581,447,510,545,307,376,797,601,680,573,238,705,349,533,166,465,704,638,55,709,74,535,187,613,787,765,362,287,508,286,879,709,633,205,925,562,68,289,172,631,863,112,145,684,571,945,847,896,876,159,778,756,959,646,241,962,890,132,141,726,54,815,200,602,230,623,328,566,360,797,246,493,2,547,896,720,155,305,79,560,671,647,708,413,414,887,740,710,290,714,506,277,784,708,861,302,479,201,976,352,421,720,346,792,772,293,3,409,127,306,469,221,298,622,428,11,864,626,258,670,135,993,346,439,452,123,26,591,979,302,790,699,291,34,172,696,828,919,784,913,268,207,260,464,328,825,659,432,593,821,306,647,104,614,570,632,420,858,775,661,870,718,436,300,753,668,789,188,592,654,248,356,603,846,132,925,7,8,795,404,895,903,525,50,31,133,649,89,723,275,119,490,908,548,731,225,566,949,122,284,785,73,762,294,707,297,855,377,617,527,286,118,992,751,267,912,327,180,281,421,801,889,579,992,715,635,720,468,646,615,475,513,111,553,248,716,131,637,694,696,871,194,136,926,342,672,67,911,698,948", "170,858,36,810,983,681,51,912,491,854,759,951,771,213,600,669,178,730,591,696,647,281,498,274,266,954,692,187,288,542,712,644,61,651,960,131,282,491,620,735,432,598,322,352,858,373,590,803,875,124,444,208,784,14,652,757,871,703,28,292,395,159,799,890,987,391,675,628,698,982,185,196,213,76,630,819,816,533,330,494,301,339,144,326,399,240,438,94,478,763,655,889,960,955,747,378,219,942,217,739,667,596,387,165,642,881,481,376,880,384,81,845,873,972,325,884,122,979,85,581,462,132,802,14,434,739,45,397,221,390,919,617,126,885,978,80,20,900,345,575,293,64,394,465,7,962,625,640,996,427,45,571,45,877,883,677,48,567,472,915,565,280,588,21,258,385,271,265,349,998,700,871,585,79,981,669,288,241,456,393,380,859,963,324,602,915,825,834,257,452,419,556,482,269,109,264,699,59,761,656,686,612,279,419,835,428,668,418,42,264,714,499,160,785,864,669,618,106,704,872,428,675,877,265,361,733,532,900,387,397,183,753,105,859,447,210,149,110,44,153,452,493,171,606,349,376,919,911,207,681,375,584,782,629,216,70,207,601,793,463,913,419,985,875,723,119,205,759,656,535,764,7,1000,630,721,74,29,936,737,192,52,907,979,441,765,894,679,242,522,360,768,211,690,130,513,557,664,887,401,478,305,410,992,236,139,8,206,244,92,852,328,714,990,592,449,811,109,406,489,74,777,442,9,544,307,352,62,968,30,452,166,896,69,487,591,492,433,604,700,627,910,916,912,238,298,171,632,651,789,288,806,819,665,872,991,574,628,787,267,412,362,273,534,698,719,834,862,542,552,900,407,176,275,829,942,90,201,926,661,374,839,65,992,310,653,602,976,434,179,322,385,304,654,81,70,101,528,663,938,614,628,39,805,857,150,306,506,800,473,904,237,431,86,814,703,866,465,317,236,195,596,88,108,216,895,574,590,878,604,579,80,219,293,197,638,752,10,328,323,63,343,320,99,317,938,265,133,13,359,933,905,771,491,0,979,458,901,57,246,893,973,525,892,405,8,743,912,319,725,237,924,864,407,769,635,299,199,472,569,926,718,470,64,863,850,846,455,149,512,994,317,641,628,223,156,125,821,779,438,822,86,593,946,277,831,113,807,661,439,729,219,989,86,171,661,349,481,492,26,120,140,501,744,843,900,980,317,19,614,673,774,829,456,366,470,702,69,748,354,458,542,68,487,182,247,940,559,513,487,284,36,181,879,717,39,791,828,679,442,271,886,175,444,119,313,240,242,949,826,67,874,596,178,449,826,901,609,228,383,197,589,914,205,955,166,867,653,273,946,476,339,242,822,945,60,950,296,293,681,417,186,966,511,347,198,882,9,24,135,70,489,805,941,375,973,84,221,782,164,104,780,232,840,209,6,889,708,271,894,795,188,939,612,857,180,917,997,841,201,836,27,771,335,417,867,523,203,412,90,347,375,42,126,660,619,230,956,146,103,879,752,553,832,244,152,802,234,510,535,476,104,580,546,61,584,800,13,318,526,6,410,66,905,12,947,362,605,219,301,347,268,384,4,645,360,221,527,348,616,654,256,129,551,697,246,752,625,537,291,154,896,580,769,498,539,869,599,274,199,25,836,443,344,393,331,690,382,575,615,561,789,754,273,951,94,56,573,351,565,556,616,788,379,261,98,505,615,116,581,696,511,964,488,608,410,29,422,808,880,987,657,356,770,874,359,816,776,779,608,141,524,659,734,390,713,505,354,611,599,860,269,457,497,27,144,291,421,916,960,501,494,876,137,268,821,806,23,258,247,992,701,899,70,261,677,718,426,376,107,58,27,581,568,666,255,677,694,688,991,21,757,956,420,343,716,171,379,51,781,561,105,419,358,662,920,719,972,527,703,518,391,752,778,382,455,620,63,102,404,991,441,884,532,107,792,991,35,657,115,93,186,879,905,797,792,243,117,493,219,831,979,190,723,900,617,479,155,362,463,638,151,973,28,707,925,832,983,670,75,959,792,226,705,422,672,132,280,343,427,627,569,189,1000,597,359,441,673,934,78,96,345,196,735,222,32,26,510,616,329,253,941,249,654,824,247,264,651,226,966,388,44,252,499,962,846,840,925,896,511,932,947,137,914,915,628,959,89,833,152,932,501,262,311,198,672,285,632,524,545,208,801,700,162,762,167,488,773,362,13,838,33,583,342,284,674,445,594,398,157,660,251,769,613,298,786,421,29,585,838,289,413,556,197,129,372,898,562,184,507,417", "916,224,921,143,55,247,62,479,108,544,522,305,985,812,438,157,542,98,242,482,653,230,424,811,17,275,178,969,92,301,568,26,622,858,873,84,608,418,763,660,829,775,346,271,721,992,560,94,177,477,67,290,88,303,533,795,896,117,221,367,523,13,734,434,425,242,846,522,302,592,977,467,70,930,551,729,521,707,923,977,267,862,484,562,217,554,819,353,885,642,842,353,941,504,925,68,799,402,833,314,946,190,369,192,206,539,8,871,232,669,931,65,429,91,901,797,16,646,34,735,431,503,931,644,911,579,152,151,737,757,390,264,684,795,779,776,495,71,486,530,442,296,89,703,863,90,550,529,426,591,399,455,95,544,60,9,849,933,873,908,223,841,320,786,951,46,571,553,591,33,517,144,811,64,822,650,684,730,677,337,307,172,702,976,423,8,961,239,809,432,759,165,507,93,17,726,921,891,863,223,648,646,908,705,857,332,117,533,777,329,270,820,742,142,742,842,385,598,978,590,841,358,363,593,41,532,210,721,149,399,894,657,943,678,921,805,683,577,590,11,951,648,94,38,886,387,139,548,646,430,330,790,306,937,848,603,94,391,157,378,101,651,692,259,787,598,550,967,917,777,983,416,101,362,138,466,161,490,447,270,67,510,584,290,812,490,854,523,531,973,165,549,975,705,319,9,82,835,142,177,34,664,383,641,658,632,23,466,113,930,64,750,788,13,574,491,590,433,75,126,749,294,576,355,491,871,814,260,437,272,866,696,620,640,216,545,413,853,654,184,62,588,273,621,486,361,443,561,620,841,274,357,194,561,934,273,187,810,311,425,560,325,438,595,303,545,405,7,8,495,646,267,643,317,875,745,324,655,708,425,822,525,819,952,595,489,461,137,636,370,512,740,291,609,773,921,316,25,503,206,723,44,674,838,959,427,33,631,279,631,26,456,953,468,335,300,660,68,847,416,969,831,208,210,851,917,852,715,116,452,726,828,486,511,785,267,907,640,829,79,57,840,957,209,628,974,106,957,849,168,330,246,316,979,0,721,671,98,248,100,764,47,659,918,453,540,633,256,108,827,54,320,981,630,26,491,807,45,503,653,569,131,976,625,397,971,683,132,742,51,794,49,995,729,32,725,214,777,450,321,511,36,218,938,858,287,440,444,523,904,737,419,678,339,126,161,755,365,616,2,717,424,922,876,684,218,677,210,474,300,49,186,316,804,756,256,198,758,78,61,272,763,769,87,662,510,866,795,540,290,507,460,838,346,753,712,449,799,772,367,566,787,655,232,799,681,979,934,380,925,796,752,462,369,179,879,429,194,510,704,100,103,613,928,518,893,728,537,378,944,7,804,240,486,541,742,428,493,530,764,171,744,441,256,409,396,149,110,250,450,700,191,899,854,583,151,525,135,174,537,514,157,690,51,992,367,433,392,210,719,490,472,68,284,970,461,806,554,104,307,669,537,60,468,123,210,670,261,216,5,117,419,378,639,635,15,630,242,470,532,44,983,961,937,210,146,398,321,630,242,271,494,46,473,515,432,532,536,730,190,932,138,246,781,677,367,289,22,300,759,416,712,618,225,912,469,630,878,161,997,277,206,279,196,58,322,352,786,239,173,826,453,72,970,280,999,135,22,969,242,897,684,55,768,409,429,846,517,153,357,155,467,655,689,125,745,864,695,375,651,372,87,251,391,326,641,452,944,37,635,947,884,541,100,60,344,909,972,194,996,34,373,353,129,381,221,159,193,635,892,843,193,676,289,886,779,270,612,566,917,818,495,113,984,125,934,611,725,510,734,42,234,373,543,191,430,583,132,148,711,659,867,936,914,423,861,508,762,900,330,561,436,743,864,896,222,817,457,203,896,452,899,143,562,511,78,762,258,761,446,706,783,186,66,928,602,550,240,39,272,275,325,405,696,443,824,454,367,95,470,345,763,916,843,831,206,308,89,433,718,995,835,806,167,376,259,674,874,929,892,210,535,47,425,408,782,423,901,842,746,120,400,434,196,862,485,187,864,421,964,38,124,261,741,665,21,511,77,463,328,283,511,920,235,580,274,235,587,736,370,393,772,109,854,593,46,547,743,637,485,898,122,612,264,908,728,922,965,114,643,318,695,803,570,346,3,398,178,88,715,284,185,488,329,250,719,476,3,871,685,113,500,310,905,753,113,496,718,504,34,307,676,685,497,72,274,340,945,242,918,97,709,315,914,421,721,181,933,942,677,106,912,535,825,171,707,217,521,57,268,604,856,844,732,867,606,961,976,357,957", "806,381,715,908,243,154,419,684,990,896,373,431,972,192,195,331,836,61,469,292,620,803,219,687,420,797,707,408,721,326,635,38,516,330,171,880,339,37,28,169,855,950,194,916,145,13,27,898,132,706,647,742,274,393,407,938,790,927,384,48,149,393,807,537,306,294,578,468,23,697,5,20,914,612,175,722,168,257,271,960,780,306,23,618,571,725,738,806,110,838,664,262,313,570,370,70,963,545,532,96,473,749,516,550,19,203,57,517,318,702,537,468,400,134,542,125,921,508,457,13,369,45,634,306,415,517,158,151,75,132,37,477,913,260,324,742,625,998,415,250,465,313,744,985,8,215,609,541,192,202,763,57,692,209,753,940,713,599,703,259,702,409,957,870,778,201,405,240,908,385,785,759,486,177,295,477,979,609,740,203,144,351,745,400,51,991,262,533,357,213,55,874,227,494,108,290,774,667,321,221,942,362,806,445,875,713,277,577,147,96,394,512,95,500,824,48,166,329,350,903,931,192,985,617,49,277,479,340,285,328,706,906,569,954,563,775,363,877,131,64,471,796,222,780,861,287,684,455,104,157,124,482,488,894,518,646,227,609,637,98,291,780,660,918,525,829,336,705,51,573,848,281,901,932,489,137,394,749,463,748,783,896,495,978,452,161,839,584,38,752,47,341,722,756,981,829,166,499,796,529,519,612,995,111,303,541,658,125,473,541,744,149,464,528,525,107,152,409,427,591,608,340,123,114,553,51,787,804,710,2,390,170,241,913,109,404,14,224,336,505,605,719,173,931,352,452,482,519,690,28,46,376,632,565,94,493,946,931,784,419,113,937,268,697,452,399,978,701,312,674,336,694,168,611,62,701,166,538,58,425,921,435,68,932,504,152,926,214,659,471,382,90,520,522,76,515,611,764,185,924,247,169,510,758,845,779,278,407,648,536,136,604,991,397,163,86,6,216,417,318,527,618,856,919,30,50,77,565,207,868,864,289,857,421,807,644,783,120,593,958,713,738,879,322,842,986,303,917,616,845,179,820,550,458,721,0,850,666,101,883,860,41,361,94,577,772,163,166,673,532,925,879,37,411,913,800,206,145,936,902,902,247,584,452,357,89,752,970,13,131,339,944,851,44,962,251,687,674,734,179,212,512,321,472,6,617,780,987,729,399,538,560,517,45,481,318,21,612,790,945,105,719,936,82,166,572,419,781,961,162,759,966,55,277,558,163,747,887,773,835,466,987,411,298,86,776,945,915,563,909,407,991,96,697,729,375,25,898,756,819,39,729,476,369,945,231,180,352,111,36,738,530,988,312,315,579,866,984,849,700,201,534,505,482,678,481,77,119,729,994,365,904,132,723,21,510,242,509,8,534,290,909,430,978,208,282,494,59,213,614,610,965,300,941,178,497,570,875,473,622,520,574,712,136,141,320,725,732,628,202,284,915,491,633,941,248,198,8,113,280,846,360,624,904,251,480,222,483,175,957,753,104,985,994,872,376,625,828,981,660,861,98,713,677,828,673,163,777,895,14,844,55,565,78,51,372,849,209,572,503,126,931,346,638,613,713,431,749,491,503,967,239,562,926,586,792,704,713,655,787,494,51,750,255,424,713,485,621,306,613,715,346,13,545,777,640,30,136,277,624,195,842,628,670,546,452,706,701,492,614,321,84,630,615,111,689,557,636,346,514,260,291,612,95,583,106,798,447,34,12,32,903,734,789,844,668,3,271,493,832,948,146,416,877,106,696,302,791,828,259,21,832,8,990,990,920,174,350,705,89,277,642,216,970,549,486,963,568,603,855,656,110,20,555,455,612,244,600,412,920,67,209,596,715,191,498,534,283,58,171,438,265,498,21,42,22,306,909,965,41,957,845,92,874,984,418,784,516,68,200,465,806,392,428,791,363,199,756,899,199,711,304,380,62,932,100,277,697,684,522,811,681,845,362,393,588,382,270,308,956,981,338,71,23,779,328,806,722,713,880,288,723,445,670,956,363,329,636,192,235,571,505,160,959,908,929,327,285,735,411,746,174,913,849,204,125,270,157,726,350,672,722,670,377,590,164,885,195,925,392,591,670,337,23,798,760,94,578,43,230,762,327,675,200,632,132,984,781,931,708,616,964,322,478,512,957,16,635,19,57,348,982,44,45,929,90,577,411,837,512,236,130,106,223,778,115,612,997,699,280,537,573,2,671,105,47,819,418,452,483,496,147,986,754,758,987,656,90,62,605,700,53,124,318,919,331,347,497,340,710,795,497,416,945,114,662,430,625,822,463", "721,526,831,482,621,105,496,837,355,12,608,209,855,958,819,781,193,831,630,325,746,994,9,601,108,5,908,160,14,166,197,538,212,418,618,872,501,207,243,96,569,389,41,682,776,617,349,894,31,673,598,364,429,453,859,9,37,951,652,706,933,304,998,327,210,921,447,957,757,105,196,56,126,545,870,328,404,25,462,129,432,489,874,91,756,484,652,903,580,152,125,699,901,26,77,755,841,875,449,8,317,267,696,941,864,873,491,116,986,417,971,989,151,897,920,87,432,688,910,234,155,836,84,99,194,162,1000,664,942,895,929,277,343,729,324,718,536,880,731,631,844,161,558,60,536,790,139,293,162,221,604,894,461,35,74,958,832,617,303,608,951,413,76,104,860,482,46,908,635,136,9,134,297,253,381,748,52,834,149,114,611,747,689,213,846,395,846,940,756,642,598,873,727,901,399,500,432,389,324,2,542,53,377,797,515,839,889,771,947,238,378,167,207,986,974,956,189,702,139,470,14,301,434,714,757,110,206,989,522,236,10,350,259,657,444,306,105,626,43,477,725,44,859,426,121,190,901,410,591,946,935,494,594,642,309,961,708,932,638,916,178,468,464,168,123,694,311,833,688,689,388,297,400,127,841,318,447,49,798,66,449,618,890,533,474,33,612,28,134,424,481,19,365,855,185,157,881,23,634,692,394,276,443,716,850,712,529,183,824,125,540,526,913,903,345,433,356,574,737,319,802,507,448,599,288,914,940,404,986,50,939,945,623,950,313,617,131,963,325,631,890,978,356,358,125,546,741,336,829,262,693,930,261,189,952,818,847,83,695,696,238,323,899,388,3,805,878,405,227,547,652,574,946,915,649,459,496,126,800,875,628,647,473,869,829,5,18,965,789,469,262,614,937,60,714,726,515,839,363,998,625,546,642,148,385,102,269,292,199,681,145,222,161,243,153,628,409,73,290,458,692,952,15,212,802,698,535,759,404,664,611,774,714,644,404,331,734,604,376,196,659,87,21,150,483,23,488,128,392,866,301,976,702,901,671,850,0,109,63,537,332,616,105,132,860,50,271,848,235,266,123,297,1,798,527,85,595,535,308,206,222,723,69,144,725,626,753,461,448,65,858,403,922,908,184,648,286,296,775,471,970,780,367,9,574,307,705,478,781,48,447,760,440,615,914,364,553,780,856,1000,690,104,164,930,171,729,595,881,87,744,104,290,602,139,115,145,733,737,849,419,904,862,911,196,832,249,650,33,208,181,353,98,104,217,115,118,35,974,276,935,663,936,823,274,726,889,565,45,387,476,376,26,894,589,445,819,700,214,422,84,797,820,766,435,287,587,2,366,32,730,121,989,678,42,796,482,809,964,70,340,93,34,655,693,764,745,272,247,355,11,369,77,649,201,417,450,892,426,567,900,665,275,191,30,235,728,413,936,535,659,667,193,78,285,865,197,399,526,858,985,608,778,727,919,352,204,253,927,211,934,577,705,691,746,958,153,557,716,68,683,568,871,765,401,557,806,167,823,333,588,681,53,24,222,881,409,412,111,974,43,39,792,848,739,816,555,584,901,667,981,331,860,746,748,454,86,994,595,762,645,446,124,710,654,259,969,962,281,946,975,872,842,513,913,847,36,479,126,588,749,290,6,1,49,299,146,252,244,896,994,372,891,100,161,15,78,71,101,314,33,582,673,225,733,744,288,652,448,681,358,815,380,45,460,746,515,101,953,55,535,19,695,97,420,447,135,745,701,80,9,271,791,296,656,470,584,111,375,863,546,980,798,135,361,998,700,885,873,24,21,262,468,776,7,373,399,549,444,706,77,532,605,501,147,513,356,569,385,733,541,899,709,514,507,710,931,548,111,274,437,612,726,6,148,731,993,455,904,222,278,88,778,834,268,961,765,255,766,103,730,403,850,760,776,523,85,662,152,771,631,813,850,204,586,150,342,427,219,562,459,889,913,265,958,751,837,849,562,68,285,919,653,745,640,752,711,430,600,922,929,683,921,39,619,214,409,578,807,159,428,781,964,620,455,702,619,708,251,249,162,205,853,351,713,633,3,995,461,159,902,508,280,19,320,728,752,220,933,585,595,79,623,371,98,11,645,251,778,747,635,627,327,305,221,300,613,974,466,453,166,269,867,26,486,521,406,834,176,878,225,530,435,455,929,651,652,958,386,13,40,480,617,400,512,834,173,173,610,234,25,791,950,337,483,81,496,304,965,313,710,43,61,114,852,493,131,759,575,943,435,113,641,520,738,666,782,189,603,28,123", "100,607,958,932,141,619,372,639,658,168,847,352,710,659,685,552,569,264,347,93,728,9,3,804,286,933,999,790,329,685,789,546,393,882,981,85,875,932,433,792,432,936,635,810,449,518,676,472,898,710,22,122,187,188,17,754,6,625,32,293,657,590,319,90,114,650,726,437,828,128,534,100,729,969,64,59,663,791,852,676,150,624,876,930,569,278,901,625,642,845,754,680,895,679,776,48,682,533,82,307,687,658,26,452,932,954,864,627,26,527,907,668,860,123,457,65,328,222,504,138,846,691,581,264,24,987,671,847,398,914,26,692,865,899,641,842,658,245,106,926,602,532,38,72,299,696,242,210,278,565,408,439,713,86,311,987,850,109,354,582,898,794,294,969,587,689,739,328,850,200,792,815,875,140,670,175,477,753,129,641,681,379,37,833,249,220,15,219,870,164,741,582,605,618,880,807,97,951,887,539,574,456,244,771,235,889,167,959,705,330,187,371,49,184,696,583,904,494,267,273,511,712,449,298,970,304,356,693,285,81,7,881,175,835,208,123,709,34,944,102,282,74,568,557,681,970,930,192,615,939,684,320,19,682,675,396,796,989,768,868,912,904,140,835,815,323,46,504,85,887,687,67,898,470,532,837,835,641,372,149,629,986,807,870,411,734,38,965,325,941,816,362,61,475,465,312,316,475,928,948,583,216,308,160,427,744,866,88,134,407,574,392,740,203,271,864,247,610,556,891,299,706,811,379,444,658,933,504,974,583,279,503,120,686,713,87,191,716,703,769,141,651,390,256,279,24,299,23,509,827,79,749,460,116,996,450,94,557,258,579,839,132,755,334,787,173,985,654,127,358,780,591,588,386,866,554,917,625,769,443,84,523,509,251,221,799,376,77,148,845,293,834,875,396,898,183,495,170,130,907,418,664,962,674,69,961,299,335,989,8,639,543,482,576,869,503,2,202,316,348,409,42,995,240,402,194,45,729,677,974,801,948,420,887,274,273,963,784,793,876,355,563,778,986,804,529,887,842,167,419,756,490,383,57,98,666,109,0,760,282,627,81,555,988,681,471,985,660,925,16,590,380,183,977,920,823,288,58,547,406,693,422,3,97,583,303,243,575,122,25,993,108,675,709,111,955,626,234,603,536,309,75,567,666,864,537,551,553,598,438,213,641,476,918,53,815,997,512,832,794,408,594,970,271,124,582,864,614,518,505,11,726,723,525,981,91,841,628,308,913,323,987,320,485,424,875,985,155,294,249,145,175,360,340,555,495,394,954,626,105,879,43,525,692,412,802,555,938,346,765,96,820,803,16,584,393,831,40,430,724,272,387,278,806,36,570,930,743,649,438,165,261,637,941,370,379,631,414,419,173,751,167,787,622,94,294,211,378,745,332,336,692,151,467,890,151,174,879,575,256,588,428,649,203,444,548,49,192,797,352,595,918,442,610,432,925,537,685,122,309,773,320,148,432,798,155,931,138,654,775,994,126,353,300,491,726,481,258,566,9,73,420,659,934,385,347,347,286,419,242,166,130,538,696,644,913,340,979,148,709,961,943,250,566,123,973,512,215,407,33,23,238,635,665,901,427,252,240,265,842,205,869,713,952,391,632,835,734,849,143,366,568,660,470,56,593,936,587,370,596,907,3,836,396,441,963,498,713,631,89,793,549,676,681,634,540,348,424,397,799,872,759,683,214,361,229,2,447,654,313,939,390,510,443,82,115,739,583,804,10,951,513,856,230,914,882,141,669,900,628,870,646,410,635,493,616,989,619,258,772,459,473,70,800,570,710,795,987,415,617,154,476,70,226,409,331,851,457,793,802,765,212,34,580,440,337,16,547,986,81,596,154,455,307,624,600,178,217,854,26,101,801,934,308,159,617,104,951,32,439,975,151,666,89,562,117,426,335,830,902,993,469,139,189,448,574,167,349,427,345,692,892,747,820,99,305,710,529,534,711,414,798,880,674,528,335,444,823,665,328,383,37,662,948,948,604,561,495,12,701,367,610,753,376,226,930,723,141,851,838,87,380,847,214,848,83,870,720,800,514,902,107,761,690,20,114,670,169,574,32,340,553,191,188,169,451,857,903,299,20,925,656,600,797,341,281,43,578,862,124,815,435,293,50,764,670,131,321,319,928,247,690,183,440,904,403,246,755,401,743,357,879,181,451,358,189,515,492,782,702,843,307,363,246,469,546,600,821,774,501,642,672,948,54,376,874,713,417,531,458,177,175,984,709,755,327,886,212,315,775,614,74,567,608,592,183,321,511,208,411", "395,119,774,521,25,319,810,560,204,159,401,947,948,136,852,628,923,702,749,623,673,457,89,403,410,542,69,356,587,132,294,601,663,256,177,623,805,881,609,898,988,565,190,805,35,148,314,374,478,142,323,338,737,404,260,60,941,770,469,861,400,770,18,579,387,549,954,741,69,515,897,943,176,719,827,559,981,205,504,338,252,736,430,934,438,546,414,289,61,874,944,685,790,200,13,510,498,313,507,835,247,547,728,974,987,437,72,305,858,929,30,611,314,398,548,137,344,169,11,860,651,439,160,98,816,559,263,220,658,941,209,254,687,769,998,712,407,764,846,219,974,724,464,294,94,144,330,715,943,615,719,262,867,327,86,638,70,385,156,375,662,358,332,152,879,166,300,640,798,981,536,103,26,251,822,573,410,91,48,290,638,263,674,496,333,345,430,948,931,423,138,182,207,68,742,609,992,889,871,436,788,246,935,124,541,775,113,44,78,617,14,617,755,868,403,666,778,795,373,140,816,245,820,762,654,184,954,962,490,485,8,109,104,949,629,759,284,78,571,440,725,822,917,521,193,724,725,520,723,448,295,128,27,371,169,763,361,353,834,190,595,180,859,188,711,45,823,890,336,860,702,43,466,335,819,782,43,675,424,373,318,541,223,7,366,383,340,11,159,619,649,977,493,781,128,307,740,471,20,587,197,871,356,882,311,394,955,577,833,486,701,281,25,297,666,767,741,1,609,956,716,755,943,273,842,35,590,103,789,149,277,400,614,872,72,181,861,286,92,640,523,346,513,440,465,113,218,572,347,899,787,465,562,998,671,762,719,297,842,57,899,833,443,523,295,708,911,315,427,240,989,569,47,650,217,294,733,90,850,644,540,862,651,352,378,739,303,686,833,564,266,135,939,985,309,570,854,906,879,136,635,898,878,827,803,608,388,100,226,194,589,273,585,87,107,529,59,616,17,13,925,799,712,783,751,157,76,167,212,652,444,590,962,774,780,349,155,696,77,389,468,171,12,410,430,566,246,218,369,93,670,899,413,246,248,101,63,760,0,272,828,520,792,384,525,36,666,632,30,364,405,463,562,62,587,328,77,815,637,388,108,333,127,926,695,903,992,80,641,450,495,959,728,761,415,52,84,871,276,331,61,269,12,62,694,716,651,417,305,264,334,687,237,151,797,502,430,400,690,374,367,615,730,68,740,962,272,360,611,233,813,218,904,263,124,823,489,523,168,191,156,510,84,10,110,781,539,40,340,240,905,273,816,834,418,705,242,510,787,494,935,619,930,397,667,502,717,546,996,585,836,729,372,438,64,923,4,749,736,822,532,720,598,394,273,499,887,805,655,666,767,742,430,225,523,519,931,620,411,638,344,355,910,821,919,675,377,178,663,194,918,266,735,724,174,300,457,871,257,118,958,870,216,251,601,251,231,533,377,339,964,45,60,913,894,195,673,448,969,176,422,20,138,67,259,985,430,635,777,180,81,30,507,736,928,88,490,171,860,678,324,999,372,800,137,736,486,141,57,395,63,573,173,442,606,199,387,995,907,996,534,826,186,39,194,149,85,667,909,459,305,389,856,17,752,520,504,719,84,653,429,650,685,21,462,256,725,642,736,912,531,14,635,687,64,117,552,683,648,596,534,252,69,826,806,576,925,530,275,935,285,686,428,306,780,654,869,295,16,291,517,870,431,202,596,590,407,642,37,893,280,452,705,866,496,154,597,8,655,42,405,969,125,669,210,819,355,429,158,61,226,77,825,854,973,694,821,798,806,186,504,253,194,140,996,615,365,160,862,769,727,385,256,148,830,624,594,808,636,499,25,182,901,686,204,262,985,788,700,804,738,508,343,737,497,767,265,725,839,242,314,297,675,439,826,765,237,577,301,388,457,768,614,50,921,626,377,18,546,371,270,690,127,955,310,487,945,107,667,423,739,690,98,515,525,125,632,121,207,927,930,394,629,215,448,1000,176,468,393,607,552,214,731,818,881,746,66,733,190,120,218,657,103,897,88,900,989,525,517,464,669,498,483,621,870,871,435,634,237,929,663,175,471,587,739,956,614,835,558,415,122,658,512,391,297,978,225,725,938,435,961,148,718,980,496,946,852,480,392,547,739,191,11,542,977,575,720,993,883,737,754,228,346,62,166,727,227,339,221,304,706,997,66,58,339,396,838,390,267,508,306,216,264,200,880,122,821,472,724,650,559,701,117,409,464,842,602,437,454,755,620,890,6,486,783,476,578,673,598,969,422,381,613,649,993,676,207,526,379,636", "800,646,933,535,64,272,953,723,597,342,199,541,213,665,231,693,664,416,650,278,865,973,583,686,995,117,39,29,928,858,809,682,305,491,344,859,108,812,159,118,8,891,968,761,513,624,960,950,849,131,441,266,974,190,628,931,874,189,966,618,559,375,748,886,345,908,711,476,720,40,898,252,798,484,908,209,317,283,347,327,725,170,986,3,88,935,398,2,165,476,56,858,429,845,200,948,617,789,658,193,49,483,868,324,321,658,78,210,976,425,324,251,931,598,22,214,730,454,674,750,246,528,896,973,875,199,478,96,993,130,229,256,995,904,515,311,199,456,203,6,32,902,492,958,810,292,4,698,241,367,684,65,930,456,398,777,675,249,693,776,534,458,748,438,820,150,866,417,239,625,124,819,101,739,73,949,693,772,707,783,904,152,580,942,447,293,408,176,448,540,298,488,488,612,796,749,93,137,189,370,880,279,823,903,905,210,75,733,361,371,314,336,155,377,412,834,725,50,344,335,157,444,272,87,291,704,730,2,792,225,110,167,917,599,181,900,667,999,516,559,265,933,550,354,273,627,398,556,695,903,299,97,699,256,128,528,471,803,835,499,777,520,69,140,662,990,460,875,123,370,251,584,36,505,746,33,855,800,640,381,323,294,622,656,380,160,13,404,798,3,671,316,199,803,317,703,534,771,91,926,90,535,972,460,114,251,173,338,746,459,364,657,716,37,904,935,569,314,879,865,975,190,425,155,124,674,188,214,784,976,836,833,572,402,521,489,243,247,72,742,884,648,247,455,156,671,917,199,101,577,189,232,264,294,586,447,80,124,146,546,760,613,636,589,178,324,482,575,460,944,24,637,799,955,830,419,983,551,706,498,705,238,513,475,82,87,469,357,557,506,885,288,257,129,677,40,134,50,365,567,540,489,882,104,858,559,838,320,303,161,420,222,647,938,725,432,178,854,948,778,960,152,680,640,884,729,277,623,429,835,225,614,530,304,604,112,290,423,988,531,563,75,848,319,761,549,440,73,181,555,437,697,197,893,100,883,537,282,272,0,463,399,354,117,844,469,786,528,801,380,773,195,205,21,319,654,241,688,78,626,591,426,383,445,934,206,958,714,430,747,801,195,979,505,30,726,46,610,705,638,128,700,261,98,234,540,362,193,564,930,142,354,329,102,846,196,658,376,154,848,531,970,713,636,340,506,58,104,332,929,97,558,469,654,195,38,818,994,450,462,22,117,216,669,709,376,628,419,25,11,433,337,493,643,648,237,29,19,197,958,366,498,493,847,215,59,205,35,503,446,180,443,850,464,320,985,801,214,411,122,537,67,84,580,761,235,432,66,401,296,961,201,901,295,796,432,526,838,791,681,682,879,344,500,921,770,113,988,832,173,735,414,62,425,821,856,309,61,597,175,557,477,727,209,558,954,347,232,708,955,445,670,571,63,830,770,732,724,89,800,973,958,919,910,27,846,757,734,624,398,256,13,693,934,975,431,338,270,511,986,756,845,796,446,452,961,650,745,261,538,432,820,774,215,872,53,419,438,849,179,668,396,343,611,579,885,395,302,870,441,700,398,703,318,822,562,826,931,955,838,185,899,502,356,302,224,141,703,841,230,629,913,105,83,714,254,696,625,428,176,151,549,11,247,279,508,775,917,86,596,617,805,534,713,758,838,20,993,563,508,12,65,794,110,580,293,435,7,933,927,375,635,595,517,508,575,942,83,975,846,459,191,768,678,700,721,721,589,208,745,777,410,312,67,536,797,533,902,284,785,602,231,206,360,721,965,711,532,231,334,177,323,412,918,113,971,791,436,321,228,211,699,61,395,29,457,252,220,974,167,238,420,850,768,531,399,616,996,775,214,830,720,448,841,91,420,313,557,460,306,166,525,489,910,361,426,950,28,965,253,947,986,547,378,786,333,442,505,21,155,119,84,833,733,797,730,822,919,468,670,909,591,238,676,541,680,851,555,796,510,576,663,701,656,306,83,395,430,523,875,516,527,396,559,579,162,113,432,427,182,589,476,246,193,247,197,922,106,752,676,184,181,613,929,962,672,310,253,255,819,46,685,802,22,298,565,503,900,560,960,613,205,499,810,48,191,235,561,59,759,780,124,299,474,21,751,77,870,616,924,275,159,329,724,77,55,341,589,540,953,822,156,356,596,463,727,448,248,332,589,645,849,528,155,497,2,260,313,248,652,253,419,826,955,687,386,867,803,586,830,385,72,993,324,156,649,938,258,424,586,463,478,15,159,738,769,46,756,830,420", "244,544,473,174,537,501,368,704,733,133,675,28,896,156,608,639,93,678,793,289,853,572,57,112,510,687,340,650,78,635,710,986,113,466,361,882,584,274,839,53,924,382,597,330,65,292,774,308,469,146,161,127,687,505,59,422,45,445,677,679,842,958,544,228,283,774,652,760,299,958,82,319,314,91,74,362,611,55,754,858,564,705,158,30,350,666,587,974,234,216,96,186,507,668,16,425,701,260,237,76,588,696,728,517,558,778,199,511,489,891,995,616,52,208,709,150,232,49,385,507,614,796,103,175,145,780,452,913,261,737,435,249,559,486,820,448,630,54,224,496,890,618,19,618,487,747,215,673,676,536,902,194,263,209,430,746,509,410,678,592,998,335,358,836,245,195,299,993,634,528,761,867,389,89,349,203,878,85,60,902,725,594,532,80,779,379,453,263,186,817,910,629,970,927,855,334,841,130,471,725,169,84,709,423,709,942,505,458,749,925,913,596,831,987,81,825,198,917,968,815,469,854,434,309,740,207,583,640,303,57,416,873,122,825,174,27,761,217,76,704,666,834,154,836,56,36,518,93,784,917,583,587,386,233,634,980,130,203,507,527,272,525,194,510,147,154,398,997,255,941,246,240,671,302,26,347,549,144,451,936,7,209,998,9,498,804,822,455,315,254,488,515,337,581,176,183,396,310,529,250,677,552,230,941,801,834,120,973,927,478,536,52,551,686,67,761,40,690,482,729,162,621,701,56,962,487,842,313,566,520,369,197,51,4,384,40,72,497,427,456,651,603,881,330,640,526,190,439,386,451,41,972,69,291,788,790,658,55,749,156,583,37,400,302,865,79,681,921,828,981,608,631,317,661,813,158,748,777,364,532,611,411,469,918,956,279,130,74,968,536,593,519,72,316,514,370,73,859,971,534,956,73,263,950,897,320,214,187,251,725,363,236,157,509,859,483,611,500,654,476,815,152,836,746,398,918,218,447,964,788,59,835,487,966,159,675,836,895,443,760,765,97,517,629,88,777,460,640,754,108,365,447,565,973,764,860,332,627,828,463,0,469,711,191,793,386,466,766,825,756,546,173,533,543,491,82,308,60,929,404,801,89,123,925,5,949,400,104,274,547,669,455,201,257,478,286,363,964,270,244,658,387,873,614,681,987,951,667,982,746,662,890,939,133,780,392,426,835,580,710,528,448,93,10,644,731,17,543,437,415,788,746,972,747,338,634,288,815,316,498,309,991,871,485,477,820,651,835,130,223,969,209,718,514,833,373,856,141,522,367,135,91,412,629,930,310,876,14,113,641,534,980,977,202,895,674,526,540,525,581,475,82,341,856,106,766,279,457,798,595,392,237,199,27,989,577,863,315,955,819,54,640,763,119,878,96,676,286,880,954,96,449,916,682,387,857,131,45,458,813,161,206,148,965,972,432,879,983,591,621,257,580,141,285,356,438,240,62,868,61,729,350,396,583,763,160,967,119,530,407,783,344,678,194,721,447,695,622,708,786,310,362,986,461,211,763,417,526,231,854,532,557,15,124,232,908,285,667,475,676,804,441,469,129,668,311,379,439,502,191,525,64,604,219,221,838,69,670,671,520,519,880,507,982,176,27,857,117,398,345,588,99,838,445,1,319,958,459,438,262,428,253,615,397,374,822,290,839,847,954,972,520,238,480,244,474,596,767,951,487,106,851,536,966,863,307,332,314,298,792,754,404,823,75,824,183,37,143,728,580,605,54,124,791,997,474,342,341,853,578,784,245,444,417,881,305,313,479,935,689,748,115,940,303,582,679,156,367,133,299,991,952,103,376,679,293,45,2,558,350,974,685,614,671,94,644,789,455,891,677,876,271,708,742,158,656,153,59,368,716,859,115,519,482,425,628,499,47,612,559,444,798,582,982,587,527,802,288,748,565,609,584,874,559,497,480,660,399,314,837,952,492,19,189,297,469,614,76,278,142,561,92,217,326,374,784,586,877,654,856,761,782,359,166,952,970,745,573,266,325,29,249,761,321,436,468,607,382,505,536,539,865,282,516,828,212,3,253,443,129,988,78,714,579,11,180,777,395,522,805,612,297,940,453,958,953,544,713,234,565,762,592,922,246,943,412,829,986,760,599,606,909,185,99,473,876,872,555,161,580,242,825,99,824,533,445,712,192,631,192,536,972,199,91,76,566,839,136,46,457,453,36,683,507,468,183,940,720,426,359,981,413,417,421,539,884,702,232,116,690,742,897,677,160,106,733,920,463,621,416,608,990,696,190,905,492,796,136,482,379", "50,202,588,560,171,367,171,300,88,800,723,442,515,522,585,350,977,830,925,401,320,462,932,509,260,790,662,525,162,789,752,643,168,401,963,929,241,727,903,479,538,799,10,912,34,293,562,795,259,260,223,816,576,566,580,730,681,721,952,503,29,977,812,377,632,846,815,720,571,705,193,675,195,495,905,353,968,573,24,604,219,818,484,353,852,914,210,366,755,339,235,394,518,512,108,12,465,515,396,805,366,912,550,663,315,606,394,915,121,941,930,9,624,512,737,85,36,482,624,120,435,750,293,690,309,582,13,267,388,123,292,682,850,733,672,116,351,749,986,15,552,213,528,265,944,840,789,840,763,809,563,407,47,353,653,876,694,680,534,431,97,786,27,682,141,499,267,317,704,857,722,52,678,89,378,823,563,479,451,703,516,643,170,340,332,375,471,54,464,445,735,295,562,987,552,459,540,656,876,767,89,216,759,108,286,421,142,834,668,204,177,249,651,503,497,831,559,154,385,253,506,778,922,773,687,453,383,384,431,325,881,308,655,870,562,442,375,58,870,782,9,565,547,444,980,72,699,719,612,200,407,308,544,563,842,859,103,313,323,898,141,363,613,146,407,207,124,614,658,606,86,454,499,168,412,749,213,191,162,519,992,430,845,314,411,78,851,623,854,710,712,626,903,548,171,689,427,873,526,18,1000,583,696,861,759,714,989,45,653,939,688,344,943,837,641,936,132,712,877,163,758,357,583,440,424,235,951,741,875,843,235,630,100,557,636,308,179,683,616,623,47,815,294,392,269,894,400,51,989,750,461,839,801,482,489,618,527,744,796,833,420,168,340,83,870,180,674,74,381,770,455,395,632,775,862,517,503,662,4,786,242,298,12,739,202,973,166,414,77,118,434,907,977,694,608,437,232,463,545,942,29,970,581,535,88,237,289,549,353,298,94,80,959,794,972,542,349,402,120,369,5,262,745,156,834,744,730,56,803,467,191,660,757,175,660,465,75,628,572,41,387,251,109,622,539,870,976,966,28,127,795,279,560,525,47,41,616,81,520,399,469,0,39,747,211,339,627,904,519,59,284,727,59,821,368,687,890,189,975,283,695,546,20,50,170,864,608,291,426,676,271,227,83,77,580,111,568,891,259,822,291,447,277,134,273,131,405,355,139,808,253,733,252,198,505,346,859,205,197,749,301,371,547,904,880,680,682,842,596,138,834,497,435,826,218,64,740,3,939,941,411,671,727,47,647,599,416,524,525,846,498,478,677,954,348,936,293,48,439,200,748,86,18,92,743,583,669,616,129,391,628,834,891,353,459,124,876,556,603,968,690,148,862,878,443,607,226,864,114,181,543,731,720,228,448,365,844,114,35,767,882,370,526,186,156,870,804,520,362,57,921,309,155,447,426,290,171,659,693,711,391,254,118,189,405,587,923,519,990,61,695,593,291,724,311,923,920,834,827,645,163,79,900,909,520,936,604,586,190,771,444,649,975,267,961,5,657,340,460,887,830,623,948,476,487,106,850,49,973,4,218,113,212,681,329,823,179,270,18,753,639,454,721,424,832,735,221,794,250,328,349,792,836,600,326,48,154,56,505,645,297,193,847,488,843,701,178,234,435,597,531,553,44,512,170,321,730,195,817,375,655,542,389,226,327,751,180,897,565,453,105,900,193,940,131,973,515,873,771,517,696,472,761,645,863,8,391,200,378,979,17,578,894,720,398,386,16,374,617,269,419,311,723,600,515,766,987,863,39,211,57,202,359,944,407,692,337,239,783,48,369,807,927,18,344,7,966,52,249,619,109,713,61,151,24,886,888,299,350,933,524,631,942,417,153,423,839,532,8,463,995,870,278,94,461,285,846,875,93,93,790,353,442,216,746,794,741,475,443,40,991,620,317,574,84,402,784,149,644,322,190,207,746,738,577,655,263,353,509,160,984,317,790,93,506,781,418,593,869,333,765,642,43,96,16,36,385,753,660,306,826,830,363,108,556,571,628,348,846,690,121,854,976,274,980,859,943,753,14,293,166,141,600,7,389,642,390,438,382,104,553,562,798,376,214,837,74,820,890,10,495,500,87,561,155,121,923,896,628,747,900,634,495,398,924,764,25,144,661,309,505,491,661,269,483,183,885,530,665,179,922,929,852,289,803,361,637,377,348,47,896,195,303,383,746,337,924,4,301,626,836,915,173,627,305,92,991,125,159,663,100,715,571,299,501,260,947,863,938,289,388,341,958,865,262,166,483,834,47,768,333,170,339,920,183,386,511,842,166,666", "746,365,207,208,714,219,439,499,994,164,134,306,692,97,293,713,978,635,298,34,435,854,746,554,59,854,45,52,9,789,404,700,797,183,800,135,446,735,403,778,801,217,132,313,261,459,790,799,207,921,742,721,968,477,804,991,335,368,656,309,525,284,557,606,406,56,444,995,658,780,153,655,726,234,202,748,869,710,634,323,893,245,99,104,560,889,654,139,370,640,226,769,290,580,13,901,369,667,134,231,882,477,173,978,143,772,981,128,531,642,256,292,235,885,636,786,595,826,276,456,148,702,16,968,148,783,797,949,579,112,50,654,881,648,409,846,951,960,344,520,832,102,998,497,738,222,413,187,916,672,862,538,62,271,897,914,394,656,762,825,593,163,533,302,919,258,796,136,874,852,173,590,669,344,146,752,998,883,9,192,503,116,43,26,625,876,11,349,554,923,228,415,34,666,162,295,277,66,501,553,351,401,128,87,126,278,784,483,528,231,564,957,347,476,598,198,205,544,78,241,947,396,799,334,167,381,951,349,569,887,237,257,195,586,112,655,361,627,31,670,545,65,739,677,363,388,649,162,509,526,500,399,986,562,954,937,807,135,18,386,999,789,409,746,506,153,497,638,803,831,794,362,96,596,213,90,995,14,262,958,867,285,603,424,140,720,184,771,438,826,175,981,177,732,934,523,499,842,639,734,459,281,47,910,108,663,168,103,971,15,359,343,886,482,950,521,702,562,22,7,133,44,639,601,743,391,22,944,873,849,498,311,635,3,903,289,49,435,220,708,618,350,690,118,179,785,801,9,768,285,154,871,183,42,654,916,720,552,174,650,984,156,150,182,930,354,984,657,284,921,150,870,449,332,281,712,334,510,844,930,754,472,963,213,241,844,17,692,124,464,242,55,566,893,821,232,725,793,506,549,822,73,186,664,495,298,877,641,887,354,527,75,104,486,282,261,998,321,222,819,716,410,969,828,389,655,863,128,371,39,347,727,453,864,840,448,245,14,381,149,362,288,962,589,67,833,831,639,812,957,517,332,382,892,659,361,105,555,792,354,711,39,0,714,920,7,558,683,258,775,895,208,591,571,581,515,347,473,551,396,797,677,197,445,904,428,347,664,165,154,961,402,652,870,553,404,242,710,270,370,606,628,339,896,318,731,74,861,31,613,411,101,827,369,832,530,656,840,369,618,175,899,669,274,113,95,275,592,581,515,899,98,502,417,702,771,649,185,20,563,766,816,493,856,986,225,98,474,442,221,613,380,770,416,302,993,71,111,147,820,815,709,879,102,726,179,887,962,354,170,80,12,116,889,952,657,638,497,104,992,550,448,583,392,150,225,819,752,470,564,600,366,9,466,214,633,482,763,82,677,759,147,69,29,736,149,249,624,819,600,255,252,23,985,672,141,289,601,195,609,953,485,926,880,396,496,526,247,61,845,387,596,639,209,569,419,685,261,68,356,807,725,260,746,446,359,96,812,455,674,539,172,720,708,827,914,56,611,765,540,815,133,916,617,412,698,136,546,495,817,713,742,946,13,986,156,116,944,881,897,273,817,486,805,659,345,830,700,441,940,261,376,708,329,345,891,901,903,813,466,337,562,276,984,968,393,810,383,686,473,51,635,779,92,582,1,340,800,398,400,794,359,975,200,978,261,831,359,749,324,559,749,667,766,827,697,767,779,449,434,10,287,107,124,507,848,446,845,906,508,258,88,474,87,527,136,658,178,490,457,497,895,7,479,466,83,539,659,593,224,228,207,99,184,53,705,786,34,250,358,444,9,837,64,827,700,292,777,556,551,306,978,688,467,689,434,7,409,598,566,355,71,280,605,898,161,757,580,877,838,224,847,649,391,176,2,31,892,518,580,229,934,258,385,814,383,939,239,449,206,141,447,675,244,912,699,210,10,392,803,779,244,613,807,300,384,621,541,916,123,726,384,179,807,4,214,897,933,807,628,840,902,807,28,249,567,172,442,514,454,914,136,483,306,120,595,706,874,887,96,694,967,508,882,876,388,81,899,750,602,267,197,589,227,585,931,166,665,789,799,610,948,187,222,185,350,890,654,198,774,215,368,59,218,515,961,996,10,76,272,85,381,286,759,797,303,180,217,94,907,669,350,480,369,61,676,839,491,385,828,188,28,605,386,609,581,36,737,555,912,632,925,895,659,188,987,1000,712,574,603,201,320,484,534,291,106,609,346,427,169,713,396,328,941,532,296,670,981,739,978,662,586,250,419,756,928,555,592,422,825,784,810,321,342,409,561,668,545,803,804", "500,277,107,277,685,524,698,717,188,413,382,207,364,160,351,400,439,441,923,932,144,197,422,764,912,895,64,529,117,112,784,396,420,178,255,394,249,600,246,872,243,27,406,456,453,640,139,177,770,918,200,31,528,688,504,96,224,417,548,443,162,921,409,18,769,69,187,78,835,440,857,52,9,623,154,685,632,620,522,722,229,922,418,83,91,201,794,870,587,94,121,156,354,270,150,18,617,978,148,266,347,821,589,120,558,134,925,82,857,472,123,70,321,45,716,864,268,307,449,141,929,844,113,7,292,480,876,9,798,648,929,106,127,367,850,443,389,559,913,25,494,100,809,973,773,992,491,15,979,968,423,344,524,789,97,555,548,63,677,585,955,962,561,234,859,968,559,698,699,486,904,87,416,96,923,363,768,910,542,192,590,816,62,550,372,389,955,937,829,137,691,524,546,739,122,884,422,210,928,373,306,573,908,530,115,608,635,786,873,581,666,362,655,17,836,276,224,495,599,360,277,306,231,574,434,230,743,956,78,228,627,152,266,787,746,466,327,838,389,84,509,342,19,988,411,604,401,592,398,762,642,868,745,373,994,651,732,159,865,689,32,772,62,1,619,607,577,560,420,444,428,397,908,458,63,293,980,7,423,309,463,840,512,752,782,994,107,939,157,991,35,110,824,379,170,686,211,281,760,385,907,650,206,888,963,758,379,181,368,407,201,108,868,92,943,882,246,353,760,326,756,971,870,373,512,21,242,572,44,500,153,224,73,458,399,922,545,487,965,414,186,162,195,283,934,564,66,603,999,975,885,886,454,127,40,792,655,348,747,703,965,265,495,951,924,698,584,347,246,396,594,225,785,423,962,614,701,750,873,877,486,657,782,868,249,358,45,143,441,896,707,206,466,852,694,198,559,923,253,209,983,506,777,768,904,974,312,891,169,11,629,672,473,958,329,443,821,457,172,119,328,552,326,32,628,657,386,856,996,58,875,286,519,115,327,434,708,145,201,364,955,300,774,998,875,552,439,127,886,795,16,434,670,405,918,94,132,988,384,117,191,747,714,0,792,989,530,749,863,444,709,183,825,783,467,631,560,613,89,11,205,821,136,662,48,790,979,222,399,566,221,740,100,505,446,403,674,122,208,340,759,826,729,71,999,91,967,28,669,198,715,199,707,355,673,381,70,364,175,373,881,588,358,122,937,5,989,877,39,946,138,900,349,751,38,5,860,709,904,178,17,957,914,597,407,176,515,494,425,890,305,554,382,785,39,360,603,545,168,872,118,844,211,744,145,356,256,295,368,469,585,166,366,929,859,322,581,541,865,937,157,491,16,205,770,174,181,347,823,753,631,141,94,268,389,811,639,30,787,674,449,721,703,837,488,381,167,313,175,585,880,333,890,981,651,630,921,690,928,64,872,510,816,976,602,875,280,553,600,715,759,835,198,630,500,442,474,288,276,706,167,865,216,336,260,584,833,304,648,615,421,623,952,395,698,294,169,375,475,25,29,890,911,202,328,673,533,107,651,784,501,87,987,50,996,701,479,875,182,77,677,520,88,554,226,244,27,301,416,999,402,122,489,336,239,928,43,526,19,295,768,747,145,721,525,770,168,55,132,389,747,201,566,958,906,450,229,474,716,139,606,358,487,439,952,955,440,585,746,671,688,599,721,718,393,819,691,848,546,996,886,259,777,795,248,780,42,567,145,79,324,976,584,494,999,435,752,612,447,994,585,439,885,56,510,29,967,364,634,23,292,453,59,649,326,45,481,383,617,641,908,173,940,26,511,862,683,880,389,620,83,35,811,391,562,35,575,172,642,766,914,347,676,880,767,952,546,903,28,526,545,348,310,273,707,629,946,81,151,872,763,925,503,232,157,503,245,697,555,978,443,108,311,460,711,670,339,957,71,847,372,460,114,46,368,488,956,42,932,399,526,772,202,292,593,161,543,879,757,800,480,892,661,384,35,68,12,511,230,6,385,592,980,608,983,454,924,676,859,308,715,262,704,560,118,769,147,744,903,786,544,328,962,467,43,924,300,499,471,161,77,983,693,332,999,219,746,422,522,526,607,625,565,51,66,415,618,279,666,517,495,30,295,652,882,899,580,233,905,151,665,205,64,419,24,463,414,133,440,60,709,816,762,21,15,127,960,494,591,896,97,422,389,500,657,738,819,749,780,223,335,106,191,188,232,363,516,996,344,300,963,364,666,98,567,349,40,780,673,370,749,657,506,583,334,889,949,328,906,395,84,880,638,246,850,836,912,720,666,772", "962,556,864,693,820,797,939,614,879,634,672,631,527,951,888,112,471,927,476,152,404,925,584,914,629,686,526,7,948,884,461,510,358,897,569,333,448,288,122,178,198,248,116,894,571,59,564,218,705,457,303,778,375,31,612,713,527,345,140,788,867,576,141,136,676,633,890,725,680,616,976,435,917,866,859,260,667,34,550,412,33,192,501,941,864,686,323,586,843,579,439,457,77,958,714,351,31,322,31,953,185,982,816,939,724,998,772,248,168,981,803,740,150,605,824,950,799,472,175,790,176,853,250,39,270,951,308,59,557,629,694,515,350,881,923,805,835,593,812,325,645,945,739,366,528,798,611,658,532,524,753,186,784,255,791,289,969,622,268,487,69,812,943,214,844,353,434,926,122,321,194,727,139,334,138,239,560,84,287,523,354,840,573,566,33,998,344,991,359,346,938,441,319,578,593,170,228,178,182,190,402,754,844,823,417,523,594,492,258,535,492,277,164,737,431,209,988,840,63,316,616,594,519,877,925,324,803,913,846,935,257,132,54,619,643,438,740,517,927,380,826,615,203,436,217,57,274,969,5,113,575,542,571,176,820,474,84,95,882,112,227,114,577,689,469,75,410,940,981,193,564,562,736,827,232,641,412,468,520,867,583,547,251,339,667,319,563,569,229,772,287,164,615,859,772,796,932,135,738,569,990,111,223,236,143,803,718,726,439,40,252,938,839,370,92,984,307,732,75,519,576,709,672,164,322,939,903,87,824,242,718,589,95,469,981,407,884,230,32,428,911,528,790,232,570,636,481,669,743,213,479,84,351,117,659,339,80,418,434,43,302,527,22,58,171,737,306,794,855,545,571,430,953,795,404,218,658,427,377,526,896,824,264,523,858,129,883,246,766,251,968,854,968,504,555,916,41,98,278,667,551,419,578,672,479,113,520,379,77,980,879,177,222,251,702,174,261,534,426,861,81,356,522,395,783,468,962,221,662,900,81,584,785,21,463,621,676,144,637,486,436,287,3,964,15,691,118,251,493,804,261,300,397,8,453,577,860,681,525,844,793,211,920,792,0,116,10,925,656,766,845,54,895,275,185,59,511,883,491,510,546,79,960,297,20,277,80,947,102,270,224,722,954,499,876,225,814,232,607,999,531,630,782,291,568,537,172,331,609,281,835,553,65,821,760,536,753,427,682,728,349,331,249,205,335,275,243,446,53,896,221,418,10,548,888,935,125,571,24,277,571,648,622,542,533,950,624,195,638,919,679,375,305,686,800,83,967,282,673,735,111,456,794,103,16,215,263,304,164,459,927,94,691,222,464,616,135,166,197,483,911,295,230,204,13,101,930,765,986,313,760,679,184,109,378,501,791,562,41,396,164,202,476,885,922,308,698,869,90,419,327,215,993,892,496,927,45,95,518,344,530,839,311,702,528,407,20,86,650,575,776,41,967,534,130,218,629,286,156,358,299,786,207,168,686,965,639,861,522,254,292,852,525,205,603,996,481,815,99,966,650,544,256,207,437,978,629,154,149,478,785,126,39,617,688,564,449,515,740,360,175,980,245,572,176,504,678,812,323,532,987,666,161,301,649,368,601,426,726,363,451,506,644,61,463,486,4,204,89,417,264,659,11,935,750,314,705,812,811,916,362,225,225,556,168,95,164,484,870,579,365,269,679,196,816,220,353,363,768,419,597,53,243,159,408,63,287,212,175,174,286,613,633,496,662,79,927,53,508,855,553,990,121,115,459,432,857,599,719,824,975,651,632,911,964,40,90,752,428,892,350,793,580,418,322,265,547,488,996,756,371,415,365,178,234,526,920,158,485,817,260,233,472,221,722,761,996,797,447,749,259,572,778,544,162,571,38,244,749,914,894,915,930,151,965,670,695,205,744,416,69,269,760,632,56,236,558,641,234,37,138,993,756,1000,710,111,189,446,903,60,630,558,972,52,968,800,491,125,371,453,874,594,319,851,107,906,999,618,481,239,745,290,926,639,703,7,534,395,947,700,226,309,142,92,206,411,281,603,213,799,259,437,33,919,478,923,254,634,531,645,50,822,916,241,441,288,831,422,427,854,297,164,778,952,921,544,948,144,763,899,268,716,408,931,73,36,175,819,475,917,27,186,696,911,87,978,577,337,678,830,837,742,582,681,416,778,321,321,52,443,155,779,402,862,879,474,954,597,144,457,139,771,382,530,163,185,736,38,540,318,926,388,901,425,295,509,340,187,355,383,543,106,710,20,834,621,180,33,376,652,914,178,398,683,326,777,281,938,82,375", "753,681,34,95,43,253,370,535,432,517,915,274,415,395,129,318,389,38,953,822,987,338,70,372,209,482,967,196,526,340,443,524,764,885,360,397,744,708,387,641,262,521,220,583,922,644,939,194,782,55,956,340,119,62,524,286,780,946,441,639,872,406,984,798,143,334,744,939,407,438,714,219,378,409,582,387,489,540,85,264,553,718,924,575,650,738,619,880,993,356,410,883,530,32,687,522,49,998,433,54,155,280,938,907,267,964,887,350,301,743,13,243,547,772,430,402,225,787,445,682,951,36,277,906,33,642,542,790,934,817,418,380,495,400,108,518,327,685,182,809,254,386,853,345,327,368,112,802,616,207,995,593,86,712,121,264,487,807,99,752,560,874,501,622,597,60,16,195,546,171,805,437,660,828,216,193,206,801,602,210,94,806,659,834,168,803,26,345,95,779,365,687,841,181,650,523,24,400,778,214,217,860,548,649,920,402,147,885,732,952,92,596,862,426,333,395,803,878,558,107,370,866,774,178,130,888,600,773,731,578,981,967,412,246,702,111,115,959,84,863,866,119,250,150,320,19,185,744,55,735,61,808,83,473,127,633,404,999,391,614,107,883,796,487,65,557,937,597,506,400,204,206,353,392,158,440,650,826,414,960,742,201,554,33,104,194,638,772,94,372,167,794,438,292,241,473,478,563,664,921,780,82,649,706,238,754,513,908,471,797,172,567,89,918,483,430,602,219,733,901,612,766,582,304,374,867,995,134,444,79,989,935,971,234,841,206,775,961,408,216,353,279,533,242,775,890,446,574,399,283,788,135,876,347,4,203,759,103,560,518,180,211,712,503,254,853,290,996,829,437,991,681,259,505,498,406,477,323,747,36,796,508,90,18,979,697,719,252,784,386,595,814,632,479,526,935,314,579,774,874,120,689,65,113,393,454,784,562,488,280,894,591,946,497,527,869,536,856,474,657,643,209,119,841,832,349,484,367,365,380,452,969,774,931,849,200,341,254,457,374,258,43,214,148,820,169,5,95,24,576,666,629,645,743,540,772,50,471,36,469,386,339,7,989,116,0,859,526,768,16,714,44,478,780,981,805,815,951,542,928,487,350,238,206,153,111,406,86,812,267,18,799,466,942,579,530,159,128,144,684,989,398,38,782,530,862,919,104,89,702,772,449,347,930,887,539,816,482,494,607,691,141,893,11,440,334,738,496,822,593,63,379,201,984,600,805,594,114,282,953,10,674,63,248,487,269,478,822,693,560,456,950,137,719,265,487,334,234,299,825,657,43,486,254,821,91,848,386,219,729,803,692,919,379,722,327,904,564,647,952,863,614,431,576,321,13,827,701,847,348,694,988,256,146,619,39,462,206,274,186,225,124,247,112,260,770,128,411,685,851,765,854,691,376,541,386,586,309,234,100,104,102,388,258,291,123,592,688,189,759,118,722,507,220,569,485,37,309,518,400,650,500,400,716,519,597,390,469,414,832,328,986,900,250,629,203,787,473,178,796,609,267,495,515,922,161,329,234,189,575,311,867,255,891,993,797,776,652,642,783,329,512,106,840,326,949,731,243,932,544,890,287,172,156,333,413,1000,346,82,855,205,42,899,542,263,168,370,923,970,357,355,885,632,933,228,568,352,377,154,941,41,3,427,11,704,295,481,755,452,252,760,98,979,626,998,940,407,104,217,119,963,293,803,196,727,71,634,70,955,287,785,412,359,294,632,926,542,464,143,912,694,50,363,346,656,775,245,338,255,552,648,684,304,858,750,858,434,170,430,698,577,121,513,463,272,375,104,796,399,89,137,120,728,200,967,450,67,338,919,722,475,333,722,486,291,391,703,421,788,68,599,195,629,359,74,754,159,840,298,700,283,797,315,839,800,971,873,521,524,207,199,807,648,867,119,67,316,466,682,516,367,858,934,802,154,985,806,172,743,453,802,579,200,860,564,778,975,91,74,573,999,811,180,986,137,301,487,299,177,728,198,750,924,603,736,280,381,939,63,491,33,485,290,353,647,679,568,633,648,195,807,192,194,912,329,621,936,183,158,246,886,577,63,638,712,587,254,831,562,9,79,429,532,517,806,173,861,552,42,223,473,247,776,424,701,929,960,731,113,968,987,809,74,478,888,414,98,270,937,973,980,999,131,443,180,537,415,533,379,103,591,432,745,460,119,556,537,1,106,688,263,616,873,461,734,653,956,75,229,725,448,320,170,969,738,100,987,248,54,584,680,563,307,616,513,205,470,493,875,364,450,495,321,153,720,286,1,952,959,714", "547,668,556,928,323,589,711,190,637,524,721,337,155,629,948,692,221,809,666,406,606,777,926,842,943,794,446,461,348,637,894,601,23,803,467,963,985,606,368,577,632,254,845,725,1,23,992,523,581,657,564,463,895,137,417,498,451,346,808,720,383,209,209,138,457,787,165,228,351,920,131,71,817,971,925,273,46,875,154,902,619,169,220,342,105,29,486,625,49,576,663,578,706,399,688,796,34,952,109,947,886,578,448,455,567,936,789,261,30,38,817,491,543,525,434,122,97,749,537,843,366,253,980,921,744,884,672,482,73,191,11,12,808,498,159,992,202,193,806,528,428,305,740,7,479,261,58,313,291,738,516,93,495,561,349,875,466,448,257,710,625,328,979,235,559,277,238,810,380,207,438,226,347,625,197,229,627,827,127,24,140,320,916,782,189,99,447,724,913,411,407,512,263,278,914,790,667,94,21,672,448,329,313,295,522,559,461,194,933,745,886,814,857,775,625,322,155,55,660,233,433,591,73,272,830,20,517,937,557,815,852,771,152,915,919,534,265,125,977,916,631,460,718,887,48,8,59,925,589,110,152,130,455,759,131,595,184,353,907,896,186,102,360,687,948,623,791,677,284,275,581,904,860,321,65,188,613,97,573,878,801,156,975,371,385,817,692,70,663,272,712,772,132,711,99,983,80,672,763,953,806,816,754,675,502,985,343,435,965,426,787,694,567,365,32,19,170,889,633,547,404,481,871,301,359,773,910,295,121,38,376,662,793,605,786,268,973,372,72,304,854,920,511,100,442,233,246,334,75,103,126,812,634,969,448,489,165,338,829,379,201,325,473,857,376,574,81,963,260,430,578,599,48,106,819,64,95,453,125,257,515,771,280,997,237,825,711,838,276,644,950,14,349,131,540,92,440,955,800,35,290,791,408,900,792,280,955,186,374,936,326,484,41,2,88,845,506,283,221,719,109,238,396,525,310,850,259,724,710,85,772,868,510,883,996,767,608,626,510,856,532,973,349,392,426,900,623,334,693,632,483,644,809,912,633,163,271,985,666,786,466,627,558,530,10,859,0,577,478,76,268,269,377,982,383,699,418,231,263,107,505,336,260,177,555,428,973,270,901,911,90,82,252,553,366,155,647,44,492,966,59,221,331,838,335,713,226,431,720,131,97,650,476,15,335,454,553,251,370,202,928,801,337,875,454,80,5,707,746,346,844,642,107,893,42,42,507,714,273,398,232,274,819,633,617,423,164,839,774,344,81,890,249,783,396,903,12,794,103,867,424,11,76,296,432,566,704,297,230,676,872,720,408,606,759,89,32,23,113,524,868,912,317,464,94,639,560,102,375,388,675,578,833,434,857,599,88,779,602,611,746,224,28,434,525,890,632,832,397,399,811,660,431,6,723,257,47,277,222,178,488,860,895,948,619,372,317,675,384,753,56,750,212,9,527,780,268,656,105,490,92,613,907,569,286,280,233,886,862,109,121,982,402,252,24,799,501,387,127,122,526,988,584,250,692,497,294,726,974,806,809,997,813,254,326,22,328,297,538,656,352,867,265,385,638,877,204,353,743,541,208,394,274,656,810,111,987,105,152,34,892,72,296,911,595,375,891,140,250,941,307,156,963,827,781,243,105,965,700,292,659,361,164,87,8,710,397,553,994,986,941,980,666,663,275,418,474,375,468,996,794,215,81,21,35,925,873,380,476,231,128,296,432,679,918,408,509,328,823,287,142,836,933,741,988,484,503,444,96,397,366,484,235,407,88,228,88,842,362,140,820,576,880,185,429,233,126,939,581,472,543,369,209,428,299,543,828,454,627,428,440,652,828,752,273,242,294,41,303,187,252,204,696,137,891,481,71,775,560,771,946,415,60,62,324,22,813,604,283,433,561,149,358,280,586,52,793,783,954,590,407,104,26,787,411,654,35,11,812,628,492,324,251,955,302,752,800,604,358,374,911,790,306,607,714,678,527,342,171,850,292,326,965,711,283,209,478,723,561,949,436,690,967,645,726,387,61,491,50,582,347,386,405,717,945,67,620,899,132,745,761,560,23,878,164,639,623,433,663,298,586,517,253,820,828,366,419,114,543,187,454,70,800,704,986,744,3,347,387,945,171,226,121,389,921,155,518,667,166,478,885,884,262,185,882,893,309,236,622,843,638,399,678,959,91,184,175,902,724,873,488,159,352,39,38,753,331,219,205,271,478,390,415,300,515,497,106,669,40,919,201,507,401,483,768,897,485,849,901,569,85,751,183,506,944,377,874,226,925,64", "889,350,490,461,800,699,482,302,23,198,762,130,801,62,469,181,301,540,549,720,591,366,544,654,654,835,564,174,979,958,53,48,404,772,194,370,335,387,481,525,714,144,217,875,828,176,803,432,702,810,698,689,635,835,664,142,952,459,420,866,738,734,434,747,75,22,660,23,763,841,756,195,653,517,681,658,830,260,215,370,37,944,980,821,475,575,441,874,387,315,456,161,89,124,356,397,440,667,947,888,366,857,832,493,70,703,319,141,681,241,993,507,109,456,224,563,650,131,460,343,176,699,550,316,234,626,601,193,26,458,664,395,762,59,759,476,273,806,470,480,592,907,784,588,965,367,818,729,813,576,360,737,998,323,500,585,842,889,122,854,427,850,958,67,154,658,977,381,906,62,495,476,767,839,615,581,386,12,52,86,434,328,36,502,932,515,930,580,661,753,493,662,315,711,833,844,109,513,414,504,497,416,357,177,243,212,455,512,975,260,720,402,946,677,821,210,667,112,354,809,637,851,139,69,944,670,833,983,980,122,911,613,449,722,745,582,857,77,877,796,502,766,902,884,57,401,329,604,499,944,496,780,774,204,802,837,827,97,646,686,323,929,823,254,770,170,60,332,118,103,847,385,197,192,835,517,484,447,634,343,552,256,152,754,385,179,136,342,913,486,633,218,767,762,430,917,923,660,75,468,546,268,513,937,415,297,970,309,792,555,499,451,603,163,976,621,764,117,634,385,144,208,81,174,955,400,76,851,966,345,268,331,378,876,394,25,751,403,801,198,967,743,931,838,803,98,622,12,113,275,492,672,740,181,622,205,17,55,654,279,401,646,246,643,580,181,984,818,24,366,510,763,836,993,118,829,636,775,975,167,590,912,51,920,726,117,525,191,74,48,397,986,342,640,226,927,540,25,424,507,938,258,975,338,746,533,827,86,949,275,646,913,230,668,196,195,993,804,243,264,407,491,179,803,642,534,745,527,671,798,676,564,644,280,624,477,541,983,514,594,837,998,873,170,248,342,562,987,302,933,922,500,206,319,256,166,848,660,632,528,766,904,683,749,925,526,577,0,947,743,529,765,944,868,94,709,348,94,819,17,444,556,719,421,492,360,517,759,301,529,635,162,963,840,868,104,62,606,521,283,839,122,522,577,252,879,596,680,210,876,858,833,271,555,135,687,823,511,610,673,97,456,161,149,76,404,561,923,818,626,681,800,380,937,697,520,443,942,403,376,366,965,241,495,891,675,300,141,87,639,246,298,158,274,108,936,743,224,781,263,472,383,514,967,17,960,485,171,638,270,44,6,661,833,711,396,112,843,510,343,808,197,461,559,500,179,337,809,945,852,676,470,293,641,812,161,553,74,451,665,906,376,559,904,277,135,590,340,773,269,471,880,898,104,568,925,513,601,159,952,350,856,694,464,238,745,988,365,701,535,435,892,125,76,582,69,152,91,83,903,705,28,507,444,44,20,904,174,426,346,235,474,90,591,120,23,406,222,156,481,488,360,169,663,566,907,50,102,255,852,848,823,653,10,152,88,487,446,525,739,181,683,412,415,2,368,438,899,120,624,840,560,607,258,546,260,796,428,987,998,740,918,627,769,579,616,743,72,869,173,194,921,704,763,501,163,36,390,998,50,616,39,646,189,362,664,830,393,907,651,633,470,333,251,3,23,439,611,271,853,39,880,719,553,334,442,863,125,875,58,426,549,375,711,61,469,147,241,642,786,479,662,658,434,317,271,431,859,950,149,312,676,228,521,389,968,953,924,935,327,430,163,303,422,550,270,285,436,261,990,264,575,633,186,444,782,371,482,151,980,839,486,288,840,908,277,835,856,573,285,511,797,435,710,386,680,724,108,396,160,286,894,281,572,180,223,653,644,509,111,888,666,494,424,701,577,628,847,716,833,593,262,571,129,762,606,298,646,202,20,311,768,867,412,212,39,160,568,489,471,291,339,221,322,609,690,749,205,984,462,408,699,463,568,168,632,504,695,372,982,770,927,240,97,970,712,72,796,1000,205,321,835,377,275,47,215,331,890,972,190,776,858,211,994,659,831,32,801,630,594,191,282,715,761,69,677,968,106,245,451,307,208,352,154,101,26,101,346,509,1,751,902,753,42,168,392,320,426,877,920,819,854,797,722,355,364,868,828,250,827,895,901,703,467,725,622,494,159,348,515,560,642,349,531,630,683,142,526,615,830,979,612,829,767,836,818,700,819,659,766,161,392,45,384,365,126,312,420,333,655,102,898,572,111,233,562,126,135,990,75", "199,496,890,747,535,340,106,770,527,33,488,265,586,957,477,95,623,66,104,785,322,624,319,824,154,999,530,612,107,394,696,269,17,334,798,311,303,200,4,846,824,88,729,878,775,109,684,823,250,269,819,748,371,178,53,794,945,87,558,62,32,727,234,857,890,610,112,82,650,317,148,995,805,157,481,745,321,217,317,902,872,852,219,687,355,601,105,835,708,686,175,148,992,383,720,510,325,269,251,758,930,321,767,97,31,468,648,702,858,177,496,354,834,102,97,668,957,372,328,603,572,367,462,227,437,624,152,104,937,378,699,984,661,189,107,919,818,40,824,264,191,606,290,734,207,80,711,261,854,374,713,234,571,248,798,200,151,735,738,684,23,469,553,467,584,190,637,363,709,949,695,479,687,725,205,271,811,714,965,688,790,254,121,99,383,873,482,563,410,216,171,53,224,374,790,882,426,670,187,104,767,168,70,778,632,134,13,302,932,170,866,993,186,146,29,770,283,114,946,776,953,824,677,678,425,110,475,979,203,961,699,817,19,848,561,916,195,984,509,627,359,552,966,697,338,613,770,509,330,910,639,552,693,302,535,446,712,843,201,361,915,726,737,868,708,715,981,43,721,4,630,251,28,897,647,551,604,74,118,504,458,992,270,700,98,465,847,592,898,227,41,915,651,415,476,583,658,209,830,727,280,778,492,924,610,118,998,72,227,29,284,344,253,739,784,827,748,271,227,722,681,591,190,240,284,244,674,626,369,178,864,592,62,833,834,385,79,954,850,263,483,260,536,761,716,631,826,847,209,888,845,281,78,897,568,999,372,271,835,614,985,177,247,252,701,844,579,634,970,384,57,725,395,438,276,216,419,354,722,621,30,681,749,949,90,124,317,401,320,289,592,311,508,190,965,2,987,845,772,323,421,21,56,72,348,109,701,37,1000,851,642,633,457,69,423,794,342,261,52,733,922,410,725,616,416,507,914,435,255,162,361,899,921,686,179,865,181,733,180,313,837,22,995,325,112,189,499,822,884,72,19,160,682,725,108,673,235,925,30,801,825,519,258,863,656,768,478,947,0,343,506,891,981,618,911,48,682,195,440,72,421,813,331,208,410,209,280,995,265,285,58,331,908,137,304,45,422,763,32,852,473,492,924,371,706,212,518,72,950,536,531,24,608,832,541,572,742,748,377,93,796,889,31,107,487,7,180,376,981,33,873,329,678,99,269,401,476,888,328,667,629,26,921,413,825,512,127,800,79,849,717,281,957,169,679,889,142,421,280,601,900,537,340,243,978,156,952,556,267,124,728,866,824,493,187,994,140,109,135,784,854,869,257,203,561,886,34,849,474,377,852,244,368,393,81,829,178,7,817,453,286,505,667,303,153,936,548,203,630,430,375,157,146,324,715,259,597,614,929,339,112,7,155,423,789,366,491,435,205,484,321,832,978,754,41,91,979,75,883,377,676,720,666,816,770,828,332,504,910,134,737,459,400,455,829,945,434,791,125,14,570,128,660,341,986,592,630,916,392,860,428,829,333,373,570,347,847,208,855,785,716,867,561,66,523,26,406,918,409,922,158,347,429,565,715,527,614,239,126,92,41,189,261,138,859,927,104,126,13,701,466,473,839,896,736,532,589,211,97,52,361,274,619,201,634,233,646,640,718,404,218,43,844,494,366,356,109,991,613,861,884,488,457,291,190,628,604,176,809,378,824,602,454,569,800,944,854,718,779,662,181,460,641,72,146,705,834,651,684,815,70,59,492,336,954,650,489,653,414,936,359,539,729,512,772,579,389,812,411,643,637,518,629,647,858,526,278,723,794,290,894,72,143,830,352,549,982,291,698,678,607,147,128,304,365,135,260,425,902,700,744,463,506,597,302,259,4,772,982,463,782,323,969,222,71,202,829,650,751,997,411,342,601,168,886,974,672,582,86,750,844,689,700,411,983,608,672,635,192,267,814,808,733,775,733,518,509,981,519,90,990,634,553,780,383,182,729,625,148,279,656,703,396,640,424,977,568,764,625,91,712,268,42,565,656,797,429,90,887,341,103,585,380,519,900,266,105,567,726,547,592,813,845,957,846,647,44,932,699,638,313,417,599,184,110,947,23,669,423,152,311,371,731,929,718,376,355,516,70,855,116,210,548,444,520,886,71,704,45,157,113,239,662,164,175,622,318,299,914,8,953,130,364,135,490,650,397,898,672,97,254,259,406,985,709,765,769,281,349,312,387,11,828,194,597,891,430,297,982,909,994,493,630,14,7,135,966,51,646,905", "743,113,874,762,249,421,925,874,699,193,497,246,939,688,650,30,159,72,629,98,985,299,265,427,52,120,4,561,932,433,550,598,872,154,769,254,997,244,185,293,679,586,181,412,464,381,149,138,521,104,794,587,165,106,597,979,620,379,18,748,37,987,955,925,192,814,910,379,177,717,793,455,273,808,530,353,212,304,143,69,846,786,983,809,566,65,164,597,626,679,112,196,813,986,281,823,377,429,629,100,417,239,606,515,829,807,372,184,513,554,635,935,9,946,570,465,125,794,703,810,504,483,823,413,184,449,853,72,38,110,651,323,177,700,964,172,60,143,244,251,883,108,527,408,815,385,658,830,918,21,947,299,144,987,524,331,439,959,832,878,290,594,180,934,760,755,861,158,984,81,176,83,561,43,863,860,395,832,663,808,528,497,53,629,782,317,612,668,529,497,45,953,932,95,271,886,198,326,151,119,255,623,6,398,387,164,960,221,446,113,67,123,395,283,25,152,523,786,799,461,418,844,70,215,636,827,949,255,917,322,629,959,897,424,955,508,12,107,523,396,543,384,53,21,728,317,33,266,658,277,423,432,791,377,768,657,889,940,500,438,705,509,77,801,225,771,100,664,540,370,844,455,2,263,505,900,320,883,583,320,500,566,310,980,594,410,164,903,304,698,670,943,464,787,839,198,268,906,391,949,853,143,540,18,15,478,631,502,914,699,601,992,4,949,423,275,755,719,248,59,618,545,418,198,194,186,124,628,896,530,320,888,579,583,187,683,923,874,543,164,362,878,689,17,963,768,655,383,762,283,223,704,6,851,176,39,609,797,81,513,326,460,106,723,345,233,946,735,534,428,868,524,974,214,829,245,359,566,705,407,647,894,778,150,497,361,928,238,655,211,875,822,647,455,300,821,105,68,745,999,226,568,424,444,734,419,721,674,739,707,491,715,472,137,34,268,786,379,706,148,791,506,146,803,207,352,474,217,855,588,263,893,463,170,42,192,471,326,586,117,391,345,202,577,508,387,427,368,690,205,904,842,790,237,827,532,266,16,364,380,756,59,775,444,766,16,76,743,343,0,635,162,631,364,981,807,184,84,881,389,515,200,852,55,446,713,607,865,762,539,277,236,438,274,940,459,996,248,182,318,555,739,590,302,118,469,759,454,37,267,531,572,630,43,432,94,383,136,828,678,708,568,383,199,662,241,395,979,589,936,830,573,921,961,997,613,448,76,689,657,232,57,175,625,266,235,178,468,799,447,268,981,187,632,454,153,204,949,891,247,579,428,31,425,525,516,650,701,219,563,825,467,278,49,473,320,608,605,576,369,918,251,279,269,248,566,969,538,567,690,195,472,942,751,814,921,653,825,591,985,81,569,484,930,310,295,584,530,320,979,235,191,197,859,555,109,114,349,288,375,228,582,787,433,30,795,784,583,524,905,438,780,240,847,853,645,796,775,131,625,780,227,788,894,490,661,368,429,98,319,698,688,906,137,215,242,154,532,13,663,710,553,773,436,746,104,195,294,416,760,453,686,701,830,157,189,684,441,113,718,671,412,551,711,670,62,470,219,502,866,182,431,144,918,686,865,610,702,58,481,172,567,720,130,295,484,737,497,85,647,910,997,927,907,5,9,158,75,823,579,669,990,778,443,462,58,368,151,906,666,208,424,904,866,630,901,869,501,472,35,370,903,834,665,318,126,388,247,916,957,200,925,797,606,160,72,595,941,75,915,754,894,547,74,836,183,211,463,34,957,427,319,7,463,277,415,600,970,536,814,331,153,245,965,794,438,80,937,90,574,344,750,813,795,20,835,985,455,583,915,220,354,208,407,803,545,870,591,477,843,418,933,909,732,270,708,483,732,274,94,463,960,190,285,310,887,239,438,106,47,500,546,788,932,719,171,141,201,361,811,986,809,139,406,535,251,819,889,368,128,345,738,205,216,19,576,902,674,233,968,977,836,129,509,47,856,422,735,439,494,420,96,932,520,81,778,713,456,382,412,630,26,75,923,296,188,954,63,469,576,639,858,803,269,214,898,351,185,698,122,364,449,416,664,56,905,225,115,512,266,981,887,400,663,240,162,189,249,93,241,213,549,703,367,516,166,106,117,333,343,872,643,146,511,816,779,77,928,599,10,814,712,77,685,264,330,660,170,639,748,830,360,22,837,944,983,418,534,136,569,728,29,550,50,826,799,303,391,277,457,466,885,976,747,864,663,416,34,468,408,987,266,355,106,330,114,298,731,296,626,398,303,232,568,250,498,512,256,210,710", "611,14,642,718,92,192,562,740,195,514,103,287,529,78,898,620,423,236,185,476,74,708,498,625,351,18,552,1,406,184,835,445,874,355,957,271,173,484,535,37,898,544,825,54,68,43,474,370,6,533,698,899,7,618,606,653,158,404,415,583,814,425,788,683,73,682,713,685,282,464,621,153,585,399,75,632,796,549,523,533,282,92,895,522,369,447,64,717,146,841,934,93,852,412,692,36,651,86,558,37,631,503,641,801,710,491,371,611,290,613,373,75,11,950,86,890,735,189,55,116,747,316,86,184,759,690,953,456,9,98,805,850,241,914,123,299,403,719,282,729,692,945,506,631,415,725,922,838,200,610,257,97,44,593,370,849,2,956,350,201,47,693,805,478,856,821,40,502,461,515,617,956,11,65,862,208,486,855,298,601,917,600,619,75,523,848,148,982,586,426,944,965,19,883,343,782,218,898,163,774,48,77,965,916,725,654,717,359,466,685,635,287,164,990,412,783,913,225,147,939,979,582,312,996,755,636,4,700,379,577,844,106,32,47,741,790,578,966,251,61,63,617,552,320,219,77,996,736,532,51,687,840,150,332,990,887,912,998,312,80,741,715,729,126,388,930,815,626,970,815,416,518,401,135,546,560,988,796,614,323,413,616,248,377,923,393,918,92,271,135,701,186,428,270,746,979,871,950,635,395,973,884,296,816,361,165,214,513,82,924,64,873,71,258,881,231,289,354,648,235,971,612,142,634,383,391,562,432,916,933,698,157,659,678,438,509,157,409,949,740,937,128,264,138,793,397,847,906,595,567,262,236,652,635,386,416,465,915,608,93,277,835,138,699,348,666,380,893,85,604,921,419,979,280,25,267,408,247,168,979,333,250,920,333,755,950,203,623,436,528,84,764,45,924,53,800,97,171,212,23,487,260,106,964,107,524,821,462,636,790,112,659,637,323,613,778,418,332,388,732,938,845,390,161,425,909,565,747,702,712,569,43,373,607,71,170,662,626,593,152,150,871,254,997,615,33,683,828,225,952,611,464,176,924,54,925,123,590,405,773,546,284,895,709,845,714,268,529,506,635,0,616,765,740,224,285,898,13,80,845,991,309,21,683,851,547,371,642,93,958,146,727,638,874,760,888,1,374,926,569,407,369,102,617,785,928,604,969,58,26,472,207,761,151,513,251,139,763,350,612,136,597,14,746,22,851,657,835,303,985,334,613,314,326,404,809,38,243,522,620,919,873,544,402,747,655,406,595,263,484,816,603,64,116,680,630,112,979,845,274,727,600,9,537,601,496,147,449,245,813,636,859,819,747,353,404,843,34,898,68,847,798,56,636,664,377,303,338,320,715,99,887,800,421,61,604,530,771,49,638,766,148,302,649,130,273,558,129,967,787,192,617,986,771,727,588,85,901,13,862,344,939,161,527,856,244,51,439,402,646,450,117,484,987,532,363,750,171,933,514,523,73,316,643,984,611,78,219,803,735,352,49,93,87,987,823,462,850,791,39,123,489,77,247,601,421,446,761,906,605,854,321,13,763,147,892,182,338,751,782,913,611,87,372,421,244,429,564,633,172,325,270,6,238,885,715,682,591,808,459,223,44,714,178,299,140,93,216,283,387,665,338,145,342,392,465,863,768,589,359,914,444,503,33,956,124,920,132,554,586,91,973,933,90,937,453,876,163,54,644,921,276,533,821,824,967,358,889,512,574,189,619,255,669,397,884,502,6,384,782,151,663,254,555,766,22,708,613,1,411,847,587,436,41,254,718,986,383,641,26,2,122,433,663,753,9,792,524,275,260,371,885,848,859,611,774,54,560,338,870,550,254,789,412,243,623,271,349,289,529,825,248,511,587,724,656,349,742,914,209,911,789,94,691,952,480,257,283,93,612,790,773,629,288,886,217,343,422,989,38,926,132,37,584,696,356,831,99,813,50,188,971,452,910,59,701,383,499,10,325,858,770,705,273,628,833,848,121,443,587,162,541,149,619,696,91,42,524,881,447,878,933,560,295,953,178,704,891,625,403,404,520,863,148,573,74,556,186,116,628,780,401,797,233,536,862,364,854,888,569,832,470,857,612,283,292,934,496,417,44,266,753,480,210,488,217,145,915,799,958,884,310,353,149,269,706,723,224,282,3,909,511,410,559,231,822,80,622,667,541,994,250,903,26,698,79,23,750,228,325,255,726,97,606,939,923,749,718,11,838,606,836,729,238,324,433,561,312,55,744,67,284,352,321,569,510,674,21,531,388,794,334,737,907,266,709,780,316,630,621", "357,914,256,635,178,999,341,459,214,909,69,983,88,299,983,46,780,558,153,542,387,523,326,808,411,160,170,415,107,443,310,496,459,42,986,885,520,923,625,19,166,609,315,145,332,142,404,868,784,883,173,816,31,901,624,273,654,787,906,505,833,846,916,465,548,504,96,637,413,184,753,77,650,58,277,196,808,224,816,653,971,33,137,143,51,604,99,198,30,819,977,971,18,959,747,207,530,214,521,282,424,885,415,236,144,411,345,701,785,370,939,993,660,794,150,176,411,47,36,535,132,655,840,799,555,289,403,796,214,255,720,479,963,217,579,434,106,956,661,787,856,991,451,395,656,305,351,278,631,439,228,608,611,765,672,969,242,886,161,122,621,674,299,604,811,353,667,682,296,893,783,366,363,438,95,856,624,42,521,851,212,501,154,402,728,358,842,256,767,681,513,370,136,409,356,304,194,590,73,941,741,775,854,105,174,358,576,34,165,744,532,298,220,984,586,116,670,755,268,800,797,550,254,307,154,316,990,291,568,201,336,170,98,33,825,452,461,380,481,943,947,971,633,30,550,917,556,750,239,545,309,23,778,370,887,266,125,505,93,323,74,319,448,726,480,265,332,645,602,475,435,849,183,244,224,511,564,125,263,582,965,911,313,825,502,473,972,353,839,581,938,419,993,536,731,807,366,3,339,5,642,823,436,550,549,781,61,851,299,239,128,81,293,74,763,190,530,885,907,535,381,536,976,543,257,582,679,688,640,815,996,343,76,678,36,913,951,56,353,118,47,442,84,715,32,732,304,604,123,785,453,237,605,990,232,397,559,66,772,613,304,440,35,348,834,666,934,315,765,870,568,249,375,11,562,738,628,941,505,489,711,249,84,236,351,883,641,884,113,273,578,962,210,524,554,188,640,696,856,598,959,232,87,655,377,947,311,3,170,844,599,804,429,807,537,625,911,545,693,447,508,129,225,485,732,225,155,26,86,204,879,455,309,83,418,136,925,970,967,169,702,950,735,727,518,116,869,305,480,678,37,507,546,864,320,879,297,380,463,195,173,727,208,183,54,44,269,765,891,162,616,0,237,302,501,367,799,838,100,874,331,690,888,265,371,518,630,712,980,505,334,429,787,7,139,476,793,682,618,567,938,80,975,905,665,605,374,690,301,671,260,653,496,504,1000,486,618,927,161,391,352,609,646,409,216,248,451,704,983,215,995,821,342,249,98,372,997,321,614,291,495,442,948,284,409,477,159,26,227,743,263,967,763,638,889,595,647,574,333,903,621,923,731,684,734,620,562,88,515,276,861,450,376,17,468,783,664,484,814,866,534,318,13,701,12,38,711,72,144,995,628,18,906,473,638,369,8,367,92,348,419,593,128,449,700,247,974,864,461,506,622,179,532,892,865,476,816,338,376,490,906,228,557,218,893,402,918,657,329,351,182,111,517,864,726,109,694,384,836,978,548,233,484,139,80,742,52,433,628,893,57,408,372,691,877,192,903,540,149,437,759,429,787,407,649,110,881,993,904,694,378,998,94,877,215,537,138,97,994,926,156,706,278,257,231,662,86,641,304,776,467,174,866,261,872,726,572,105,949,331,174,602,728,702,515,827,958,466,910,518,262,295,514,999,878,282,663,532,74,451,690,523,734,308,822,499,663,451,8,302,552,88,912,72,384,994,100,753,331,51,693,102,407,586,946,256,611,491,176,50,557,489,57,960,793,714,777,561,983,5,128,36,413,683,831,557,78,875,154,382,74,239,747,644,287,220,510,340,481,731,321,723,606,245,94,722,104,416,571,831,975,51,798,460,890,979,100,980,853,633,803,788,841,204,635,264,751,223,744,424,426,484,245,332,883,425,698,728,291,114,982,842,817,439,796,147,606,156,909,757,183,897,730,934,800,113,715,420,315,636,346,689,940,865,38,823,761,878,353,231,138,185,702,371,214,697,545,548,487,991,838,939,765,870,91,602,684,470,859,384,974,860,465,581,380,390,885,768,772,934,674,950,284,709,26,136,224,328,236,992,773,923,268,556,448,63,409,634,611,572,743,31,330,313,538,825,595,989,118,356,153,124,834,8,782,748,17,369,289,467,543,621,114,773,57,101,970,337,251,784,792,181,569,287,980,628,816,50,460,719,29,601,986,976,713,150,722,680,555,49,938,74,528,827,184,348,712,412,1000,567,361,907,961,236,642,668,795,531,661,938,479,800,102,133,170,464,183,511,113,678,495,390,452,967,729,19,665,111,438,934,806,554,561,623,945,770,728,245,164,839", "952,813,945,225,146,53,529,430,941,285,325,457,612,668,178,124,892,893,355,830,939,754,449,231,660,274,169,182,59,901,291,37,499,231,759,520,10,732,827,351,705,552,937,826,874,36,159,806,18,851,583,666,805,515,549,978,749,650,194,851,489,131,137,529,574,312,832,264,516,808,921,288,53,910,767,729,797,467,395,454,7,861,173,422,427,513,652,480,89,758,717,524,976,930,947,223,174,52,94,149,185,651,679,474,341,840,468,876,814,674,83,993,763,76,976,289,810,93,515,412,354,647,799,550,573,895,63,152,360,452,787,847,480,544,277,374,962,71,583,733,72,881,974,888,991,554,477,230,4,590,402,947,907,536,502,257,904,117,665,847,41,532,65,557,963,328,434,725,822,239,141,684,223,229,744,530,217,379,742,133,304,379,692,69,517,741,902,282,468,23,807,171,972,151,346,154,349,791,964,182,349,101,562,287,267,977,966,396,693,804,109,216,183,183,319,515,361,618,782,828,139,149,878,469,186,529,718,831,385,550,516,551,891,219,414,331,4,434,909,160,426,49,365,824,892,622,237,405,980,419,317,514,645,44,430,172,906,857,94,699,199,800,407,525,363,585,409,595,941,572,406,269,162,619,792,442,621,772,715,740,805,469,51,174,397,665,347,291,185,527,929,974,769,631,169,614,249,826,98,613,222,336,121,572,782,738,198,863,56,295,918,80,845,384,237,409,925,432,253,518,121,168,545,74,418,727,304,162,245,425,213,28,48,388,629,763,189,858,496,553,22,720,605,224,623,107,468,875,49,732,594,823,964,551,816,492,134,546,330,161,509,996,310,548,480,319,126,585,391,365,893,23,550,74,685,772,343,427,767,998,259,815,409,84,358,529,855,600,785,999,444,169,388,521,721,935,465,90,217,947,293,546,223,40,971,644,788,30,739,878,733,950,874,178,46,471,178,881,825,943,500,898,18,855,717,177,196,304,251,409,403,301,80,356,923,577,131,790,580,764,218,251,743,359,180,410,77,165,750,383,974,998,976,407,981,37,1,183,562,205,533,59,591,825,895,478,377,944,981,631,765,237,0,418,214,446,129,919,203,104,9,99,705,75,687,476,184,184,46,513,254,460,609,82,70,293,526,596,109,55,98,377,273,557,311,111,84,316,763,862,729,886,748,789,340,133,979,541,68,94,281,838,98,500,60,343,416,219,666,38,58,211,879,138,479,23,563,290,735,40,162,826,898,333,294,432,612,751,476,103,354,920,709,871,57,411,399,228,11,147,73,854,574,692,237,239,553,632,94,977,906,101,392,726,246,218,957,553,478,820,302,200,411,377,901,433,330,861,417,165,115,883,893,674,17,227,961,168,908,973,786,621,512,935,527,607,501,722,777,862,722,120,410,655,183,925,255,571,616,446,76,922,98,401,727,115,968,272,138,486,100,570,187,947,107,897,168,229,959,277,51,570,961,177,778,284,978,942,419,232,24,818,992,675,538,783,585,148,968,12,680,386,477,275,170,847,927,532,684,756,869,857,805,613,737,14,456,960,2,278,347,72,171,264,722,630,170,972,541,909,122,274,574,818,891,734,134,892,764,458,799,95,97,922,894,182,872,818,63,527,800,894,873,545,78,266,94,996,405,384,488,165,129,194,779,878,468,765,587,922,385,212,328,906,400,934,770,208,665,196,661,350,919,465,194,809,399,223,267,686,572,152,84,7,843,336,973,114,687,464,880,242,368,791,13,623,994,562,240,186,971,783,426,822,519,933,810,454,172,896,583,291,488,253,241,117,341,713,479,679,414,247,571,126,359,374,745,811,773,920,224,298,254,175,607,199,797,644,805,386,577,651,31,303,715,191,85,522,203,700,613,193,838,232,656,95,414,568,277,662,36,234,288,51,499,500,372,465,556,916,642,471,448,589,757,913,260,997,667,559,29,20,906,938,374,34,8,808,642,556,498,269,657,783,705,70,344,752,999,401,503,598,277,861,642,664,706,975,98,968,376,433,676,806,450,234,353,866,770,979,228,157,460,55,501,277,34,241,43,587,735,594,900,592,856,153,34,599,211,83,334,16,984,869,659,733,950,713,913,847,130,500,738,335,396,299,924,62,990,15,283,689,30,399,82,592,618,77,712,762,136,91,358,361,957,121,198,573,474,307,455,786,943,348,81,275,738,707,85,615,183,582,881,354,837,792,807,690,951,683,854,275,792,434,461,497,722,166,463,857,914,517,830,860,952,997,370,891,716,472,578,727,988,327,267,555,722,96,842,758", "781,974,701,458,125,339,829,217,756,608,282,568,731,803,465,840,408,515,701,807,660,986,507,168,642,855,408,129,861,821,704,279,624,463,257,301,881,80,837,7,380,938,518,114,174,542,63,193,893,944,358,986,51,890,645,806,643,334,365,376,788,253,739,739,815,581,409,57,159,290,100,447,604,741,19,903,308,864,802,655,309,85,470,726,71,300,745,324,617,568,844,805,336,220,37,971,162,805,219,220,240,336,449,5,198,269,373,190,547,322,845,719,156,917,300,554,115,760,115,438,359,764,714,311,628,707,451,872,55,744,846,621,211,869,104,397,892,359,372,484,952,934,87,615,732,123,422,4,437,983,633,182,815,489,870,776,180,897,600,960,592,549,25,111,227,679,92,203,595,708,334,474,489,147,552,170,303,663,378,615,12,589,564,156,774,391,937,460,438,380,803,65,816,210,269,740,101,618,449,305,839,727,20,710,102,440,376,957,279,154,590,782,332,784,519,467,256,401,643,671,374,898,390,26,754,187,861,738,388,162,935,10,939,601,271,654,870,806,301,865,207,133,913,5,854,42,557,160,633,185,380,483,768,18,523,952,156,197,596,312,550,251,152,494,77,722,63,999,944,615,626,627,233,811,189,702,831,166,264,737,828,445,745,845,122,382,955,824,272,335,75,326,77,44,519,924,995,689,324,758,336,103,773,592,214,596,838,38,589,601,283,496,245,312,142,417,735,726,508,802,859,153,963,319,164,746,503,400,451,454,684,942,552,607,722,608,700,68,512,79,341,821,327,814,991,575,324,854,150,56,217,507,258,559,267,649,122,585,732,607,332,339,40,413,615,455,811,992,468,944,114,20,559,845,592,248,301,392,58,348,219,191,584,41,902,240,498,75,2,344,760,499,217,612,652,406,630,9,114,279,679,164,875,637,305,279,23,553,476,246,108,194,814,847,683,504,653,533,222,837,828,489,857,966,658,847,328,224,407,136,127,735,797,651,217,285,705,70,856,850,215,950,363,201,920,180,583,63,30,621,694,610,330,769,630,411,798,977,62,21,543,821,571,783,275,780,982,868,618,364,740,302,418,0,828,386,27,151,851,976,689,271,36,387,24,539,3,972,935,571,732,205,686,937,797,273,119,329,198,730,458,937,24,32,626,568,338,465,78,130,991,413,281,910,5,303,513,159,113,626,324,837,766,111,797,241,826,920,886,18,551,170,875,54,214,794,796,824,772,231,308,737,392,493,355,846,5,230,582,400,183,111,464,976,476,751,707,427,335,575,997,238,571,5,298,177,872,51,549,193,776,964,120,818,403,173,809,98,58,526,798,799,564,842,894,321,496,409,930,190,858,919,586,300,696,163,555,785,969,525,270,582,554,312,53,146,472,1,48,783,378,923,442,557,733,343,656,93,902,833,176,727,444,797,803,844,378,32,438,811,490,931,866,766,392,452,481,591,229,942,305,931,921,4,670,859,737,382,642,221,423,852,362,14,713,483,951,402,27,56,552,868,669,490,716,508,69,796,133,547,964,403,539,626,273,852,307,360,11,383,62,666,672,57,399,803,72,628,296,516,491,444,976,40,919,512,187,749,267,463,528,523,670,238,617,436,787,25,440,92,431,418,753,327,580,380,322,809,864,802,858,890,768,698,73,499,412,867,301,188,329,427,416,834,204,202,94,849,20,336,517,975,712,984,521,765,29,293,822,718,102,431,344,110,17,669,728,248,167,49,652,250,331,394,365,121,638,109,723,599,314,201,790,991,685,540,35,92,725,960,188,926,806,785,757,990,974,785,416,854,728,311,466,186,719,854,188,783,357,868,973,507,851,20,682,718,707,785,872,198,299,411,584,925,177,569,458,850,764,693,705,181,114,570,502,648,789,87,178,920,844,547,720,601,800,363,427,579,795,153,112,816,797,352,521,105,225,47,605,42,184,445,112,880,624,84,272,107,168,651,167,353,830,299,805,37,189,62,990,852,398,176,20,157,786,156,554,159,652,893,141,355,547,994,181,634,71,225,514,426,140,627,963,8,501,184,92,791,331,188,64,572,485,396,992,952,184,343,653,280,973,759,975,222,477,402,966,136,378,407,529,745,566,54,34,147,882,920,139,485,365,447,342,463,738,580,125,701,329,96,211,8,168,234,476,612,961,226,312,860,928,144,533,193,460,146,817,207,498,216,524,567,302,298,606,378,368,728,955,567,630,635,461,99,158,47,506,993,48,955,540,422,57,625,167,225,611,451,795,156,992,765,937,317,690,398,761,313,381,927", "899,528,214,617,77,250,260,242,230,755,550,370,246,426,947,961,656,978,403,146,84,346,291,792,739,119,482,876,793,699,560,210,718,912,31,240,488,613,232,229,664,205,539,574,474,61,228,943,249,671,133,709,587,934,753,931,425,551,883,266,15,393,596,32,612,16,417,726,487,50,247,349,51,369,835,891,747,153,580,96,113,313,684,23,730,279,19,664,771,25,341,687,722,669,296,397,137,368,331,978,886,453,9,773,954,613,347,320,835,480,248,789,428,248,337,836,687,698,548,697,794,882,669,491,575,320,217,712,443,364,279,865,820,215,624,508,625,437,612,517,686,458,944,518,285,677,409,227,236,522,866,204,993,942,380,330,325,584,597,448,775,913,770,508,963,710,166,657,778,169,493,207,624,291,148,756,747,44,412,974,319,774,151,837,274,231,657,701,215,203,434,875,499,300,169,118,200,70,254,611,805,202,949,770,874,730,970,336,471,980,587,665,266,534,970,250,920,691,357,959,83,470,700,175,256,29,922,869,330,576,510,54,406,56,108,926,373,396,686,557,140,477,839,985,535,837,31,658,126,314,872,830,548,233,623,320,9,144,739,385,489,259,662,53,312,936,843,104,80,286,93,519,409,301,223,118,99,305,672,473,16,256,363,509,489,126,542,90,725,945,637,335,240,356,450,868,679,988,829,55,405,241,548,355,666,250,366,964,265,236,478,407,261,637,640,874,743,542,382,976,445,603,664,112,955,737,98,377,734,410,794,906,59,251,365,914,344,303,974,32,767,665,699,496,112,332,680,776,889,859,837,638,480,24,765,398,505,851,225,337,303,120,86,598,92,170,78,202,801,647,704,689,336,564,910,405,248,744,448,435,804,935,730,952,329,577,957,612,169,500,865,217,187,237,760,742,455,101,742,16,837,931,916,424,353,286,306,128,478,384,58,889,782,887,288,792,283,816,579,626,167,711,374,986,902,670,395,178,805,81,456,864,462,110,791,913,526,719,720,280,17,679,915,205,232,679,919,421,180,825,30,281,151,635,26,913,527,920,587,319,491,368,581,467,185,981,383,94,911,981,224,501,214,828,0,161,708,143,796,802,662,875,680,508,243,827,73,930,993,924,717,696,261,716,229,13,987,872,508,861,909,752,491,585,119,165,857,321,505,124,362,545,629,391,613,726,261,225,484,324,39,560,415,280,872,324,351,414,435,58,862,209,410,214,95,967,374,178,514,340,85,652,21,598,113,427,208,214,424,807,152,755,396,281,669,593,401,698,193,219,788,844,350,481,814,63,34,30,77,594,413,299,758,400,39,39,332,722,181,924,465,175,83,704,206,210,960,861,365,250,32,950,959,600,361,692,587,807,661,252,63,810,639,758,690,48,312,806,188,898,14,283,593,134,218,959,249,675,445,455,152,609,413,427,561,86,410,326,502,469,602,569,517,851,411,859,919,387,206,370,627,484,72,441,139,243,277,223,986,46,710,687,233,467,423,26,449,504,930,913,920,40,715,214,850,855,684,401,58,118,860,749,935,595,334,92,532,174,81,53,518,345,778,953,860,425,868,738,532,20,311,230,263,796,877,706,828,36,18,376,534,430,639,728,841,831,679,145,33,457,50,765,65,973,2,800,21,75,636,620,610,371,940,873,907,590,547,953,900,174,88,674,480,960,96,330,949,752,182,980,124,929,744,410,612,667,842,386,950,846,336,660,805,797,187,708,469,729,59,632,913,501,435,719,960,395,48,282,787,934,133,900,596,954,384,540,77,247,809,280,507,154,607,210,224,642,694,567,383,274,399,525,750,851,291,174,815,341,920,157,269,834,430,27,955,642,958,126,91,30,348,317,523,694,324,236,785,184,34,783,895,698,678,668,380,360,34,502,325,805,272,487,911,695,752,517,165,712,403,93,49,922,295,672,490,641,582,869,346,799,29,387,147,975,361,465,455,261,107,536,665,561,353,536,143,117,116,213,298,109,166,502,992,781,345,421,324,532,364,794,968,272,686,380,343,375,100,528,38,450,310,552,95,544,175,572,904,898,97,457,345,165,148,625,485,659,111,422,191,642,393,395,614,787,786,281,686,705,211,193,506,59,910,372,999,411,301,600,892,99,636,194,1,237,630,394,620,96,350,498,720,107,614,912,379,395,549,849,399,180,875,741,74,649,713,52,79,344,37,655,854,70,980,518,295,882,596,231,36,927,750,325,723,155,3,301,572,22,736,583,993,341,306,73,272,512,537,955,22,964,722,902,461,114,830,476,812,243,320,97", "548,389,45,128,374,510,941,923,726,137,907,266,649,934,918,822,234,280,234,430,252,908,854,158,892,84,71,583,165,174,895,15,238,600,595,697,16,176,886,390,134,97,130,338,273,990,43,39,653,296,128,285,65,320,387,258,937,964,94,621,927,682,642,334,365,988,312,585,175,591,359,510,716,76,918,135,558,822,236,110,374,354,771,809,354,372,520,21,122,766,158,539,276,510,886,896,771,156,157,557,449,847,204,985,947,3,576,429,419,721,574,479,403,395,709,812,5,651,924,342,52,933,890,23,237,74,897,280,801,153,82,688,9,522,738,41,733,382,422,825,198,523,645,995,125,838,640,870,677,254,685,504,89,619,942,326,512,925,324,531,886,957,653,924,860,633,326,73,531,176,850,255,639,928,371,604,838,580,549,237,328,343,932,575,529,324,681,339,736,293,420,340,808,391,820,420,670,496,121,280,34,73,570,952,363,330,825,314,265,389,708,815,203,382,557,853,30,558,87,267,762,470,854,224,610,490,570,900,989,774,108,582,851,97,852,981,192,947,961,369,579,961,27,199,764,632,277,63,449,782,128,75,528,686,646,119,762,90,762,341,53,952,448,114,766,995,123,976,321,827,857,880,989,446,64,207,419,51,904,65,454,16,107,713,70,86,16,13,557,937,686,737,504,36,499,225,877,464,811,793,373,282,319,16,872,300,851,776,221,255,677,407,938,940,119,683,995,52,933,553,837,210,954,821,868,309,978,219,514,189,312,600,251,176,249,757,289,57,786,117,155,341,320,931,797,485,698,778,157,535,729,311,952,337,925,284,457,201,857,924,133,711,227,183,663,378,431,97,823,493,654,500,758,452,198,638,983,360,456,391,465,579,841,479,992,775,578,798,490,953,166,323,109,409,805,344,243,386,892,596,507,449,617,339,831,197,521,621,540,944,86,318,44,402,147,639,972,574,690,204,978,825,606,64,200,415,792,900,655,118,565,550,739,818,369,782,811,583,725,796,76,446,31,854,985,726,219,614,657,249,509,653,977,299,491,800,85,823,328,654,82,687,515,631,59,805,699,709,48,807,285,367,446,386,161,0,367,764,158,165,807,869,398,484,730,245,315,468,445,884,847,99,372,848,796,122,618,40,554,992,627,797,626,354,575,208,821,276,740,236,340,25,511,281,332,221,17,366,847,830,807,121,809,268,629,728,518,544,792,967,459,145,694,919,111,699,752,558,514,862,884,136,654,206,252,632,961,732,65,159,288,365,929,413,428,174,970,268,532,929,413,198,725,264,262,978,340,168,851,151,123,391,909,588,823,580,727,505,463,123,495,599,992,534,185,688,307,490,915,783,70,124,467,129,331,555,634,286,299,163,998,405,932,79,419,357,438,168,385,531,809,44,122,162,782,626,391,533,102,63,189,629,100,128,688,27,723,458,333,973,62,22,830,31,722,87,476,180,426,535,916,675,208,216,804,729,795,420,394,542,656,272,480,242,928,438,894,990,755,328,30,332,467,962,657,32,266,268,226,236,446,359,930,428,681,291,894,810,677,534,267,885,385,446,70,268,434,802,755,286,631,810,218,882,80,354,903,278,41,661,338,71,971,503,854,737,596,408,790,653,262,79,137,869,593,818,253,834,110,154,54,474,325,548,695,960,761,149,633,593,411,493,642,45,99,2,712,31,298,613,376,339,382,131,285,759,711,681,172,193,565,882,279,510,352,89,986,51,589,947,885,4,878,202,110,965,111,93,723,827,34,722,297,610,300,813,926,802,967,254,419,672,873,198,691,121,139,416,42,401,998,997,724,363,320,582,311,868,69,507,555,631,448,813,164,278,645,472,627,897,433,270,830,402,980,18,919,461,325,136,678,450,314,695,98,581,710,248,922,276,124,943,299,755,215,904,668,230,865,632,167,114,322,791,785,359,814,248,538,924,875,166,636,430,855,905,608,40,618,356,494,787,55,762,636,89,598,798,509,903,478,680,7,775,620,837,540,780,41,617,376,757,306,720,62,975,609,812,637,8,516,947,278,555,127,464,155,174,705,790,699,737,143,849,308,661,671,227,576,954,152,336,361,495,190,188,943,966,802,667,984,800,943,254,588,265,153,254,117,174,515,459,454,700,819,332,345,340,649,343,636,549,432,502,82,967,51,946,609,344,131,84,994,294,281,581,574,649,91,357,394,397,632,265,353,977,218,537,286,29,223,657,739,821,51,990,481,267,660,352,749,640,669,796,552,445,638,280,15,793,575,295,830,104,566,32,263,438,364,210", "507,490,937,272,432,284,279,541,559,931,718,152,829,877,768,321,454,746,829,907,665,264,591,875,10,519,641,697,811,596,36,446,994,439,52,162,297,458,591,397,959,579,436,389,18,153,879,212,95,821,254,397,657,883,638,127,827,361,674,542,979,609,597,487,717,318,222,860,800,328,491,622,372,990,249,675,418,561,767,407,556,792,984,800,846,230,68,616,38,595,589,575,897,237,339,817,979,301,516,256,704,877,579,57,471,341,731,3,16,89,362,239,168,173,439,781,956,734,472,264,897,768,636,667,73,646,100,685,558,598,595,145,419,428,775,758,710,102,398,226,885,414,27,746,858,785,940,605,490,665,264,603,370,954,891,640,843,858,877,460,629,624,52,230,652,690,642,168,395,26,901,211,817,465,147,485,65,603,836,278,557,319,962,600,540,102,179,567,582,97,194,298,628,220,546,284,911,562,825,471,390,659,793,395,892,86,637,582,682,834,203,797,21,857,935,645,496,729,681,837,212,800,52,656,280,215,347,424,831,139,73,622,308,227,882,611,637,747,681,590,869,615,820,379,903,649,533,284,818,327,148,928,666,235,106,276,830,309,877,497,355,652,198,919,148,9,442,716,962,819,998,386,286,750,889,773,278,910,288,196,927,760,265,346,993,290,625,889,10,717,692,925,663,990,487,672,320,638,376,271,302,858,984,765,518,448,971,131,296,896,345,740,620,336,304,657,77,873,522,929,588,522,510,550,496,52,805,986,636,580,918,798,5,500,212,736,341,83,956,769,543,113,146,847,84,216,587,693,957,813,597,876,190,760,14,245,258,248,977,842,192,286,304,563,803,424,572,21,151,592,652,691,855,186,595,676,176,721,633,741,206,948,270,630,813,681,269,660,641,229,458,244,862,322,657,511,788,789,324,841,313,547,305,55,571,22,59,528,556,939,919,523,702,632,560,860,357,465,202,959,422,935,184,608,509,129,888,50,414,831,625,78,584,492,466,188,84,823,613,474,952,219,701,382,272,862,653,169,392,426,206,484,666,199,807,206,595,288,77,241,308,890,347,560,511,815,418,348,682,184,898,799,129,27,708,367,0,35,433,854,338,514,482,998,193,205,876,160,897,805,651,319,115,899,288,642,60,455,239,233,505,795,537,918,652,636,301,815,259,690,832,268,316,905,947,519,194,956,864,407,973,696,599,115,297,38,325,608,876,4,715,468,587,496,3,41,466,389,961,966,500,19,19,767,599,686,772,217,943,65,249,8,186,626,850,26,198,715,994,559,597,741,652,300,663,268,33,183,41,953,446,246,802,913,669,359,223,217,700,711,43,477,59,333,909,742,856,150,495,702,333,520,552,464,727,549,577,980,478,537,963,596,521,694,489,32,700,597,49,540,573,784,403,307,959,954,581,46,251,353,887,240,745,69,637,311,826,79,697,799,796,88,182,522,416,797,344,526,402,597,669,209,858,951,907,68,404,363,449,386,882,175,777,529,911,495,905,913,479,982,528,19,141,458,814,479,536,61,640,231,610,792,345,624,999,22,926,174,754,791,341,88,431,605,958,487,155,838,324,319,492,412,804,631,62,288,276,35,243,556,163,671,531,177,371,961,140,850,23,450,835,987,67,261,636,614,245,250,963,39,982,658,598,994,349,527,13,741,977,239,892,87,412,683,691,848,730,454,75,587,825,642,24,752,279,750,31,788,957,5,900,840,542,721,508,601,521,227,776,176,800,848,250,849,562,723,357,223,938,505,384,581,824,886,35,20,113,41,494,330,74,891,811,643,532,388,437,539,406,831,485,879,136,231,834,688,544,834,829,142,509,554,52,319,378,829,866,231,488,280,603,276,447,122,984,929,761,446,232,250,565,100,386,323,664,435,107,494,369,897,697,295,847,679,863,689,919,61,75,924,334,456,39,507,575,595,509,166,895,216,533,465,418,307,693,553,941,511,250,556,135,176,129,715,700,127,678,727,62,556,648,341,515,80,853,497,905,93,793,885,887,241,710,178,463,915,890,494,204,373,520,534,95,911,694,826,649,883,528,680,774,672,832,13,713,528,958,472,346,607,142,476,325,219,202,408,803,426,666,348,409,747,344,125,993,583,206,601,520,156,120,45,633,579,735,597,322,341,569,769,994,258,990,701,351,518,933,790,962,981,48,880,986,834,852,189,972,471,695,666,284,585,137,951,250,119,286,237,607,468,174,761,428,346,246,577,353,209,235,949,63,715,626,721,599,987,223,287,285,283,110,448,941,694,302,765,860,849,411,543", "875,491,929,463,388,43,925,619,17,425,851,738,917,743,422,576,79,663,203,207,329,308,170,661,390,800,988,194,539,648,98,698,353,411,145,920,88,50,948,857,224,796,38,712,835,414,334,975,464,648,161,528,732,484,116,722,44,11,721,590,932,838,147,241,779,331,832,848,909,357,320,679,510,591,232,498,14,702,670,624,336,337,23,983,168,620,283,388,692,882,275,828,728,456,466,68,655,526,269,828,957,49,600,726,231,236,484,120,827,932,629,563,717,359,791,929,630,222,442,555,339,775,366,469,697,540,612,194,875,93,197,148,167,877,195,527,682,418,876,960,863,201,841,60,7,521,817,889,297,507,44,394,205,644,970,387,470,585,36,288,22,511,580,270,204,601,242,320,680,571,798,986,705,33,252,25,681,911,700,732,28,733,226,648,636,398,339,195,943,311,370,457,182,363,250,204,60,440,899,305,862,313,417,237,438,653,206,714,941,958,595,500,70,653,944,810,761,684,354,440,897,141,73,869,958,711,881,302,918,849,984,455,222,24,171,9,35,132,102,74,412,583,371,29,63,466,585,548,643,972,332,47,810,421,384,323,349,947,21,223,604,340,861,101,137,752,710,355,866,950,437,776,543,738,586,804,897,114,313,203,914,865,759,948,922,417,811,920,124,580,109,191,500,122,12,884,485,824,461,174,205,113,549,429,718,58,13,18,684,494,223,361,809,27,108,205,627,543,435,427,505,343,385,963,826,883,417,553,632,941,151,78,716,569,333,171,534,670,406,889,43,800,203,742,620,511,705,172,195,331,2,189,986,766,517,250,247,830,440,884,904,283,35,92,220,364,928,111,817,462,782,111,636,817,195,665,624,511,570,992,162,948,140,266,486,81,690,413,160,268,796,961,531,739,826,677,466,456,202,472,586,767,359,957,292,349,397,908,820,160,215,543,455,289,755,362,987,284,106,704,840,998,485,984,11,984,343,758,813,840,544,14,473,340,913,197,564,179,8,186,499,574,133,640,656,893,75,235,484,159,429,910,197,472,45,145,535,58,815,688,60,189,473,613,883,951,231,94,195,84,13,838,919,151,143,764,35,0,484,662,942,882,617,122,416,858,310,713,754,185,941,536,384,907,71,923,202,810,405,227,315,193,287,64,656,384,296,515,239,322,881,768,42,740,691,715,600,522,929,454,514,235,344,369,678,916,783,274,698,774,896,790,742,680,144,788,178,689,270,529,250,550,562,246,589,991,836,400,668,483,860,459,608,51,550,665,845,565,131,330,469,104,711,26,290,732,605,744,230,173,121,734,814,471,924,879,230,131,486,730,672,346,362,576,982,34,374,574,616,577,286,419,208,133,787,756,744,145,296,373,238,493,797,86,888,688,809,329,940,728,551,221,806,684,345,176,726,583,109,856,229,314,334,858,612,504,529,12,921,623,320,640,367,433,606,212,285,282,993,86,395,699,756,770,862,197,908,790,829,428,779,403,950,176,89,940,646,514,289,28,370,956,319,841,327,213,395,908,81,283,299,359,463,84,724,559,853,379,31,344,692,62,510,635,774,54,631,661,813,885,512,722,465,357,258,766,536,708,168,528,438,337,854,978,392,556,239,947,625,628,606,260,44,115,833,440,671,709,859,708,25,494,934,840,658,387,913,69,595,888,437,628,400,778,519,774,975,307,849,626,208,661,388,565,164,551,622,857,753,434,32,137,415,98,453,999,996,971,431,424,974,655,991,19,262,969,466,352,427,132,920,929,268,470,777,747,249,48,146,859,511,128,587,132,890,872,960,533,22,622,228,953,577,645,942,247,143,889,9,543,578,430,499,424,471,22,770,52,256,340,571,984,700,473,961,576,280,303,681,141,562,639,691,281,84,763,951,892,853,530,616,137,548,581,829,205,988,751,451,922,191,175,692,45,485,756,914,460,76,51,835,710,319,869,114,814,111,772,61,551,47,810,25,233,89,183,901,531,218,886,517,520,1000,98,164,142,790,659,20,805,890,280,209,754,791,427,899,559,241,822,741,145,8,117,206,924,951,412,833,565,831,754,738,661,807,328,239,106,380,245,224,579,645,353,842,441,476,156,988,489,432,217,111,17,807,469,876,38,458,480,347,686,489,757,766,219,868,736,916,369,365,301,958,326,862,62,914,810,446,311,761,594,938,813,64,122,605,207,182,469,257,34,585,198,372,161,99,431,244,432,446,541,496,942,397,297,489,713,449,695,219,615,201,295,182,157,953,864,962,427,798,207,113,286,997,93,846,172,959,57", "434,550,415,260,758,354,327,92,113,410,888,824,937,344,274,598,553,999,235,495,479,124,475,720,819,573,276,610,344,487,569,133,194,150,289,105,665,278,547,898,577,158,583,913,218,969,771,87,34,625,737,936,620,857,777,814,227,680,956,629,170,450,55,904,191,571,227,544,16,276,676,171,860,731,453,80,287,124,460,191,979,444,826,987,948,705,161,307,388,802,75,809,867,764,74,244,788,77,165,176,218,816,886,934,232,679,945,795,954,949,549,730,4,542,994,235,284,312,133,758,921,776,702,227,42,736,810,911,702,353,688,35,649,175,692,426,280,160,59,872,947,659,31,280,232,894,884,581,233,995,600,911,70,756,307,384,877,950,518,859,92,548,471,134,508,138,417,343,64,563,953,889,59,212,361,262,44,454,570,160,377,595,904,778,861,816,629,382,324,222,702,339,744,984,595,559,652,39,254,540,585,935,569,223,805,298,730,57,158,334,575,644,360,378,763,73,209,838,655,568,891,363,830,527,865,341,178,379,847,642,733,784,288,861,529,403,201,805,683,430,253,221,747,95,172,335,189,485,301,161,498,159,708,115,633,408,933,485,853,16,227,556,389,42,170,83,907,404,792,605,440,788,633,396,155,839,57,342,919,358,23,672,423,413,930,218,6,73,542,636,683,152,503,866,772,979,626,981,90,251,67,310,485,764,197,824,931,495,778,711,740,236,204,263,898,114,971,345,27,143,686,300,717,638,919,588,651,140,467,995,393,195,779,997,160,71,592,834,812,771,151,386,257,319,296,563,568,405,711,740,108,588,914,790,269,592,406,681,94,562,491,407,992,563,979,665,179,66,232,672,831,709,130,39,864,507,266,865,860,232,668,569,349,607,432,61,113,631,383,298,25,972,277,730,751,380,869,285,293,939,107,95,643,733,882,497,399,655,67,559,410,842,457,58,607,961,185,145,720,10,61,596,516,671,214,639,404,870,985,132,421,83,113,549,746,379,134,577,508,275,127,165,343,473,946,643,801,41,368,911,572,961,926,569,503,936,308,547,637,78,929,975,551,89,491,542,263,819,440,881,80,100,203,851,796,158,433,484,0,725,862,762,257,624,850,692,4,229,466,125,634,472,56,119,6,883,153,314,626,804,779,720,105,444,403,599,207,412,613,838,737,807,438,74,531,333,566,192,429,187,768,488,677,580,588,521,659,623,728,270,917,905,818,89,37,55,377,802,41,195,111,856,435,85,998,761,15,915,545,518,997,696,177,286,237,551,546,899,103,622,469,97,909,468,464,397,148,58,275,93,118,551,554,342,628,916,132,410,523,112,383,357,22,601,913,114,738,738,128,949,209,357,879,151,656,727,230,183,248,752,768,448,610,413,241,993,287,241,575,756,378,214,795,366,532,650,403,996,785,521,664,773,116,338,206,676,801,346,587,268,234,578,661,782,86,390,535,7,445,19,567,632,610,673,520,760,450,555,34,651,716,372,763,627,98,885,81,806,396,466,249,608,818,650,778,825,823,794,670,551,778,969,319,100,549,394,96,190,249,102,363,362,489,487,967,111,723,797,403,336,346,936,278,121,810,744,224,201,60,953,250,635,176,834,423,330,117,383,847,662,461,121,166,646,978,310,267,606,897,801,661,193,997,126,269,36,623,708,474,170,458,165,470,390,225,604,602,864,634,445,169,455,382,45,12,70,510,550,534,249,450,987,503,82,495,823,509,408,183,596,777,572,731,199,39,420,84,872,947,900,602,949,211,332,263,361,33,574,102,992,978,306,814,477,15,259,922,859,475,810,930,239,273,848,851,186,297,906,865,119,531,563,163,637,661,546,214,624,625,944,780,961,865,12,335,580,196,20,93,82,68,346,111,757,7,979,620,446,774,686,697,242,482,862,206,68,107,519,606,588,11,112,264,989,891,981,14,897,590,779,242,967,860,854,936,761,279,861,567,132,602,765,781,11,788,442,802,435,51,695,131,377,297,708,761,327,682,263,566,908,593,831,760,877,905,315,113,563,134,576,732,21,909,724,244,137,730,21,560,548,604,431,390,300,210,69,581,313,783,579,668,156,377,48,786,849,949,214,174,494,247,457,809,307,829,265,562,828,181,412,609,939,823,9,206,160,421,564,233,475,564,327,649,989,871,49,754,382,224,564,630,268,322,473,590,598,502,526,338,739,962,201,11,247,434,493,480,9,462,61,919,714,529,239,959,114,926,68,359,310,512,987,17,255,145,898,721,355,260,482,712,352,830,819,418,675,551,517,142,130", "702,983,221,74,158,49,901,105,670,805,424,383,302,918,489,797,182,39,319,629,684,293,269,976,950,207,463,346,377,977,542,4,454,565,391,14,628,198,671,210,157,576,428,208,562,190,82,423,287,648,942,408,267,657,831,508,333,737,354,389,249,312,266,6,984,909,57,594,975,2,139,791,661,749,387,615,578,29,208,441,624,877,482,719,240,817,431,85,881,421,89,797,973,363,417,123,480,336,288,41,844,333,56,490,956,992,575,946,34,738,954,681,686,636,782,854,237,119,219,24,566,975,440,910,220,645,192,418,483,184,766,406,720,298,203,423,283,988,961,921,701,199,399,547,5,647,150,347,442,62,327,614,731,891,808,316,923,211,927,691,94,391,953,772,877,592,905,885,356,796,817,811,189,794,369,818,955,340,980,687,622,125,79,349,87,955,618,927,286,706,504,77,476,252,731,582,673,790,845,755,481,799,749,60,285,18,644,565,61,965,405,188,303,466,701,627,465,535,494,178,311,636,582,338,908,9,439,847,901,581,81,264,735,319,311,997,157,887,163,975,787,473,983,480,673,112,670,546,664,208,925,839,907,678,386,136,61,469,999,155,344,854,702,710,127,687,89,837,941,74,433,478,131,357,15,481,491,856,450,596,61,305,511,341,638,131,231,102,575,535,658,762,190,519,588,199,942,379,199,997,538,267,63,845,658,478,572,985,438,955,846,14,491,750,557,719,883,937,3,176,808,104,403,851,893,414,977,759,291,774,329,704,594,376,45,152,480,997,286,760,765,156,989,198,76,213,845,586,851,324,435,802,186,512,198,261,902,341,372,599,244,228,249,840,583,656,258,80,958,460,980,316,762,89,167,997,2,466,187,72,739,338,865,638,784,39,858,208,867,832,946,461,582,79,382,326,767,712,227,547,582,575,203,345,927,649,183,977,709,642,788,276,761,789,966,300,567,727,566,487,288,814,128,63,962,912,253,620,688,59,70,362,376,380,476,804,786,847,75,674,554,421,771,937,530,284,108,419,809,558,158,46,959,926,653,902,206,406,388,626,404,283,396,11,510,928,107,17,72,389,845,874,104,976,802,165,854,662,725,0,164,484,953,819,498,779,76,634,843,217,798,930,616,863,230,811,105,552,476,101,381,444,327,510,238,132,727,305,956,841,211,778,205,361,869,684,285,962,843,232,493,975,891,193,268,411,846,143,288,897,74,895,126,517,37,789,711,926,879,584,808,244,334,269,405,835,411,521,660,965,676,322,505,865,875,46,88,535,77,649,593,849,347,438,553,363,594,126,401,774,212,834,118,915,404,709,461,353,250,248,336,416,830,695,30,496,490,400,769,714,500,187,846,98,437,157,161,366,805,210,634,198,262,856,571,429,197,63,476,122,943,772,55,405,876,183,876,156,847,369,417,913,635,259,762,858,250,884,275,217,493,826,405,510,639,19,910,534,928,882,452,282,289,169,992,571,349,141,47,704,390,457,409,118,997,361,738,646,81,232,975,847,777,598,465,823,713,769,175,246,352,285,679,642,368,332,786,662,658,749,567,100,268,734,928,567,850,279,312,613,435,933,61,439,495,982,705,873,349,684,772,318,424,842,893,614,193,688,343,494,185,782,148,140,210,702,398,368,74,57,995,970,719,124,154,389,723,222,337,551,29,783,338,512,627,17,540,139,806,363,102,188,619,594,464,781,12,960,363,272,8,220,927,454,4,233,157,355,249,370,688,381,804,619,622,860,450,305,418,902,298,769,617,153,615,321,698,663,291,915,172,278,80,200,232,71,535,791,461,38,926,571,27,420,414,360,749,641,913,83,662,124,583,806,966,328,604,317,317,424,272,736,112,40,12,591,747,762,231,200,481,196,706,564,707,626,18,696,287,344,354,674,962,970,299,744,757,555,831,144,343,338,325,581,310,759,744,293,332,216,356,668,457,555,634,887,129,21,247,179,209,222,640,909,25,920,218,100,395,917,878,231,122,952,363,288,920,411,953,55,440,878,768,128,969,183,214,15,338,569,737,523,512,663,843,404,112,168,750,417,286,872,839,134,952,173,770,841,554,940,501,143,339,881,594,663,977,65,389,933,879,738,964,604,178,230,976,133,996,849,393,535,132,668,660,164,936,753,500,219,714,296,132,780,327,681,777,718,392,427,750,313,473,169,206,935,95,10,809,782,328,759,265,729,307,997,950,384,182,20,125,498,754,243,869,639,327,76,788,540,860,568,594,216,733,12,745,344,508,320,60,655,582,487,518,604,733,203,199,917", "109,812,6,531,121,389,56,976,354,829,482,670,998,895,283,292,827,629,385,331,394,418,184,822,899,481,460,764,394,845,92,745,142,153,795,113,720,209,348,184,428,967,430,840,993,255,970,579,128,530,424,190,604,597,366,533,277,360,92,957,323,795,198,744,747,124,364,812,347,906,821,192,4,274,839,507,300,696,191,442,563,139,387,52,392,869,367,862,621,18,540,430,77,173,738,603,731,497,473,659,204,653,126,460,740,414,767,756,163,947,289,862,340,501,378,489,747,722,882,693,735,721,50,128,565,50,250,699,716,677,864,806,385,281,267,632,425,939,126,596,35,546,826,241,706,401,410,390,978,882,712,137,310,64,611,123,122,68,76,438,941,783,358,674,669,461,432,881,115,636,44,692,174,623,960,303,949,995,162,104,620,120,312,430,121,433,405,449,43,177,557,287,549,489,366,202,761,457,689,28,825,396,905,345,411,147,83,27,403,29,540,724,57,567,708,695,940,769,128,178,413,402,786,509,301,591,878,317,83,734,498,632,419,851,303,451,279,238,935,108,588,69,314,161,82,99,398,839,332,46,324,71,56,753,16,31,650,721,476,101,692,557,849,744,340,579,30,354,774,790,403,527,849,846,298,543,242,480,336,65,13,700,210,762,463,48,806,53,413,236,493,646,638,661,416,668,807,623,198,17,398,408,164,465,400,135,324,837,15,578,975,454,878,100,540,243,18,223,369,664,382,919,862,42,855,16,629,495,194,653,322,452,898,790,656,583,459,974,252,827,838,307,124,998,115,300,678,917,532,594,885,374,865,148,410,516,170,920,60,316,267,758,520,406,999,532,28,143,276,180,250,941,959,891,93,638,611,552,767,748,152,265,462,89,162,305,306,147,924,521,589,355,270,896,691,94,156,302,421,207,257,698,213,354,797,512,911,837,289,679,306,424,466,794,653,143,700,816,182,694,500,525,216,333,31,618,916,521,89,539,765,234,847,589,756,834,309,120,523,662,108,180,166,838,208,904,423,828,599,133,645,777,743,718,569,902,222,693,108,591,801,695,797,205,546,487,505,444,421,515,991,331,9,689,662,807,338,942,862,164,0,651,598,219,578,526,387,850,63,751,696,732,87,839,866,34,447,159,238,509,151,46,39,977,95,74,552,834,151,5,327,439,383,839,86,971,856,64,788,227,679,516,882,719,554,34,834,317,359,334,705,227,863,551,991,597,381,839,632,908,549,949,612,858,197,17,458,792,739,346,419,488,884,931,870,412,4,377,958,222,201,663,858,455,275,680,419,68,681,608,313,644,559,340,354,918,937,908,271,824,334,14,730,477,694,305,303,607,881,908,897,862,191,334,863,619,806,411,156,584,630,401,601,916,401,608,883,18,772,604,942,153,474,418,969,732,734,210,511,520,463,460,716,433,33,952,865,241,85,499,360,506,384,56,218,766,543,483,581,253,352,184,568,236,513,708,92,984,86,275,191,662,830,371,462,475,61,787,943,165,768,383,171,677,902,841,765,153,356,386,586,258,352,909,516,898,677,831,117,111,578,767,512,421,813,433,542,480,53,385,92,180,18,381,70,631,664,46,436,701,370,897,912,352,237,205,816,463,635,48,261,274,204,336,701,690,898,789,709,55,207,966,9,55,66,394,706,483,300,129,911,570,297,189,900,279,620,342,189,8,96,831,82,69,749,854,742,660,874,62,123,411,404,850,807,681,452,672,620,614,899,716,717,484,469,722,907,726,752,916,968,33,840,367,738,561,900,726,435,85,672,482,913,616,327,645,622,743,360,991,101,684,154,736,96,865,761,736,586,877,74,407,166,64,257,725,21,723,306,326,516,495,801,523,253,684,211,7,191,237,712,326,906,997,895,421,584,940,165,347,311,847,141,854,477,185,923,123,933,806,365,569,698,963,899,216,568,706,352,135,382,81,974,696,291,353,432,526,445,850,275,377,976,627,559,317,68,422,161,11,857,229,913,615,221,245,200,749,918,283,480,416,937,413,563,188,827,601,171,9,353,699,373,307,69,379,186,77,405,411,103,649,499,850,333,56,610,333,714,548,780,902,678,51,440,515,316,88,399,161,686,256,320,177,415,646,979,842,546,20,164,948,713,261,927,558,868,995,678,830,875,78,187,656,178,800,564,65,245,901,186,152,58,392,596,530,399,242,445,390,733,373,617,606,469,804,465,714,908,597,759,534,359,233,636,424,783,258,136,770,748,214,201,684,518,71,313,696,517,332,990,935,378,413,411,165,217,229,375,285", "32,652,666,726,868,606,528,429,685,990,735,201,954,12,610,816,290,427,527,877,966,839,332,942,374,68,428,14,439,781,399,457,6,76,891,25,850,949,779,272,453,68,173,159,267,554,595,189,531,673,221,122,797,648,163,846,648,866,126,101,994,385,253,700,313,650,751,901,239,872,217,648,241,98,331,713,394,710,493,107,349,958,458,413,555,694,107,917,70,939,976,408,643,180,797,966,893,328,811,294,63,111,816,994,514,786,406,520,717,997,610,330,896,87,963,74,728,566,343,472,47,863,951,861,397,76,290,535,350,397,294,409,409,522,328,684,615,813,462,622,54,971,415,445,595,975,270,749,822,214,176,977,659,395,879,432,620,410,465,51,999,620,640,845,542,102,702,326,335,625,831,621,43,969,723,550,780,996,170,938,648,483,678,981,73,776,295,497,534,526,671,443,420,641,797,92,885,983,769,701,703,454,106,433,153,410,350,865,530,118,386,879,369,797,762,889,816,119,769,804,855,291,55,878,795,177,83,296,191,808,268,3,113,810,918,171,224,331,48,530,970,936,82,505,590,282,101,55,577,642,27,314,441,213,423,480,895,388,804,995,79,28,487,164,708,565,377,799,14,204,914,524,638,674,339,379,233,439,141,137,727,876,411,985,532,290,58,879,274,483,484,186,331,544,903,400,288,28,940,337,699,901,366,777,353,92,758,326,23,355,113,64,874,738,107,483,862,96,440,732,799,276,67,220,55,950,526,181,376,48,957,691,119,845,526,346,145,885,355,641,851,85,849,88,737,973,431,129,402,949,251,105,922,388,876,272,748,645,764,521,677,579,141,680,485,204,150,148,614,786,176,516,468,775,399,666,538,675,50,627,197,238,42,297,899,796,707,667,618,561,489,772,826,786,996,801,686,761,956,847,875,106,307,624,400,20,98,968,434,579,942,882,35,70,403,540,564,958,440,886,689,602,573,382,515,933,308,944,524,878,658,764,796,615,837,421,273,679,149,847,495,478,641,987,388,82,457,802,561,783,155,667,544,470,131,247,723,422,333,426,89,546,677,821,79,350,336,556,813,200,309,690,99,271,875,869,514,882,762,484,651,0,683,27,33,475,531,561,702,316,53,393,643,389,246,448,823,636,265,108,429,656,935,77,956,881,709,605,884,809,667,244,53,938,598,89,857,401,784,367,471,40,636,203,369,727,95,677,169,634,770,209,346,224,435,40,77,777,106,920,380,73,646,121,554,594,717,149,585,361,609,468,182,853,62,668,677,726,370,790,483,49,882,205,59,479,760,512,747,939,820,522,371,794,577,367,86,687,159,340,659,276,465,886,827,642,835,650,714,611,444,488,126,680,686,133,795,801,673,524,298,132,510,141,856,463,993,143,197,931,549,629,980,186,372,193,255,917,967,785,1,135,438,822,458,197,603,298,311,280,464,780,34,708,696,874,99,460,369,464,513,444,860,552,265,118,274,375,616,840,752,25,717,31,959,642,313,381,135,51,775,858,911,479,930,509,788,298,374,577,509,323,884,34,960,266,785,806,843,707,249,793,895,552,282,894,983,441,753,558,68,116,974,518,136,819,448,747,513,474,104,83,351,650,392,396,319,386,726,150,403,544,518,945,493,433,714,602,733,54,117,500,464,670,586,290,346,118,600,883,599,727,322,912,753,336,721,65,198,333,532,313,153,312,296,389,688,432,228,166,419,768,920,535,421,524,231,357,467,188,212,208,362,928,630,824,416,386,48,213,201,810,619,127,540,585,71,256,309,47,765,120,610,764,46,966,894,836,64,612,98,252,797,671,444,496,764,826,597,95,533,577,575,19,755,615,478,161,736,569,413,494,586,902,597,186,309,980,624,552,716,898,424,674,741,118,931,999,564,174,149,208,531,33,787,430,876,373,186,721,247,809,956,842,304,11,200,994,113,236,914,883,566,801,157,393,819,266,454,672,643,715,543,306,594,1,201,209,899,620,419,509,717,462,623,289,697,507,558,189,435,195,733,353,379,412,135,508,521,311,226,332,806,181,129,233,760,346,61,381,847,963,639,767,846,811,487,248,866,957,190,976,305,734,225,515,340,263,643,760,530,149,433,860,12,479,266,810,971,185,243,950,253,879,747,297,869,641,972,76,366,998,251,100,287,504,359,603,808,174,954,124,12,994,184,277,334,927,565,230,727,871,756,374,571,984,393,15,269,158,975,676,478,213,689,190,698,571,551,657,516,678,70,638,67,934,407,3,941,795,102,804,852,69,795,657,624,487,741,456", "835,170,263,822,961,522,113,685,345,72,637,572,290,409,876,757,790,306,599,737,887,427,945,816,841,789,958,935,812,865,986,31,716,796,686,345,983,966,442,551,468,611,865,346,329,767,872,440,379,465,65,977,894,995,840,961,429,882,707,666,46,865,295,851,709,880,43,187,744,611,640,566,720,335,967,22,538,206,731,77,916,499,923,640,391,668,380,807,212,719,677,122,300,280,573,996,27,147,235,397,765,887,416,568,772,720,212,540,984,843,749,897,814,219,99,278,395,522,439,62,72,141,807,413,215,155,187,309,684,845,946,842,541,19,825,462,903,409,11,128,961,422,859,151,513,12,372,136,158,605,872,666,556,917,554,58,411,68,212,166,323,923,991,622,750,420,423,604,377,7,782,667,358,812,94,918,68,812,190,38,605,980,659,80,59,68,964,125,907,89,597,632,6,283,625,533,831,226,775,62,779,451,50,585,699,197,47,584,419,864,198,359,465,219,175,128,821,840,192,112,714,871,184,653,922,550,518,729,109,618,473,390,902,624,433,370,888,620,475,409,391,272,626,374,747,1000,862,636,814,123,258,327,447,520,428,621,226,895,776,615,163,81,79,525,274,428,507,962,112,837,160,625,715,592,997,303,869,16,483,892,548,633,661,18,801,32,780,543,566,468,517,746,232,235,86,451,977,435,651,78,138,800,947,675,486,44,605,580,42,189,821,562,460,964,386,866,595,676,538,663,991,885,847,43,454,359,56,954,859,433,963,259,469,255,266,598,886,625,878,365,529,403,213,414,372,234,942,790,32,998,654,88,475,87,259,873,110,906,822,148,718,467,371,984,95,325,384,404,626,870,457,470,808,356,704,469,814,524,919,137,863,94,674,367,493,113,301,366,333,685,12,182,233,367,304,864,226,243,453,504,132,781,973,982,591,984,903,21,968,802,461,41,382,265,786,163,413,710,337,872,324,490,739,761,668,977,602,422,171,431,242,47,414,452,798,480,745,834,126,16,186,853,248,980,860,140,166,937,207,346,744,440,422,64,976,584,69,3,127,383,123,20,197,136,960,238,260,719,331,852,21,888,705,36,680,398,482,617,257,953,598,683,0,999,824,378,716,784,647,49,687,564,8,301,995,309,991,884,413,869,962,582,820,201,251,815,404,179,580,400,774,157,235,187,409,719,638,615,135,758,383,392,211,284,696,407,913,840,868,445,799,110,650,186,271,742,403,302,335,129,972,509,298,831,805,550,809,421,135,613,156,954,80,669,413,840,730,950,396,299,732,89,570,440,750,449,736,472,403,684,995,419,929,10,18,764,201,544,390,317,502,356,772,27,844,663,41,24,333,274,669,497,785,150,835,333,657,754,624,820,494,460,764,807,980,557,337,132,488,436,61,850,967,165,489,42,2,818,904,983,442,864,713,377,556,818,429,469,416,122,746,642,428,245,672,201,839,988,228,210,756,757,657,512,847,579,923,892,393,843,312,785,189,94,748,726,913,632,586,221,570,834,483,985,392,284,857,880,288,361,635,670,909,347,585,598,453,312,370,873,366,379,106,760,491,363,280,309,277,73,268,70,744,699,561,818,767,845,582,771,105,270,459,8,475,590,533,379,249,152,870,635,551,111,921,549,987,871,58,749,471,734,996,74,731,427,374,400,590,380,310,515,785,171,249,473,726,792,85,993,209,177,331,831,731,605,875,882,111,343,656,980,919,292,344,339,618,737,745,513,22,867,294,601,833,803,817,962,155,636,959,392,195,271,242,113,920,258,727,514,647,611,974,823,744,466,240,442,48,965,287,641,376,894,431,773,321,389,646,640,344,925,676,455,200,276,781,573,542,141,495,908,316,528,472,175,230,604,694,59,664,361,7,758,935,748,669,758,201,671,193,499,14,811,170,437,336,517,497,823,353,686,744,897,201,942,598,579,521,879,249,838,809,362,118,434,483,784,433,632,448,702,222,959,828,285,963,865,831,478,379,18,229,255,145,94,728,588,815,303,311,818,470,964,414,62,13,506,229,809,756,105,57,615,798,514,10,941,348,542,122,707,564,751,347,549,107,153,928,155,211,759,151,312,101,42,975,689,630,749,483,903,278,54,418,506,773,695,415,610,633,887,188,402,89,995,670,140,749,515,518,922,207,704,150,329,824,605,780,854,649,172,968,656,697,594,505,797,761,981,156,817,826,381,242,270,914,476,159,992,771,69,220,591,344,341,431,170,203,900,486,558,533,201,931,804,652,655,792,732,985,89,379,428,423,184,734,320,732,36", "788,618,1,622,959,695,289,303,20,191,656,667,304,851,567,995,736,848,301,577,605,602,930,84,140,927,86,692,441,32,379,462,114,807,365,466,505,534,431,792,96,64,208,359,294,523,870,516,160,474,625,822,877,849,10,851,940,165,154,724,208,73,427,5,55,201,194,600,763,869,918,123,469,352,13,358,30,999,340,58,761,723,591,687,308,956,258,958,189,939,184,614,682,248,389,736,996,114,363,907,398,985,549,735,962,283,706,894,680,821,847,408,190,70,625,184,673,288,778,801,336,677,8,907,40,646,793,36,800,891,436,177,163,11,664,750,527,699,611,929,257,582,520,401,413,484,77,530,108,266,356,975,128,757,880,612,966,679,393,65,803,874,18,577,904,624,263,184,502,738,492,505,611,908,636,172,36,749,907,757,106,797,286,129,864,750,38,81,36,68,839,897,29,173,576,410,139,731,445,212,19,881,107,894,334,611,376,699,883,687,427,305,653,159,32,62,748,462,680,386,942,814,500,898,131,35,421,369,839,311,508,680,385,947,20,889,469,708,788,575,100,827,126,670,67,117,815,138,447,338,756,217,58,949,33,927,812,651,687,566,30,603,943,871,981,935,127,733,943,653,990,503,381,879,910,673,815,664,49,563,915,215,848,74,291,359,326,968,341,854,137,46,757,651,276,660,978,360,64,672,635,231,425,327,764,85,146,223,149,58,91,860,500,271,879,785,834,455,888,573,274,695,908,516,713,962,979,753,925,739,635,141,439,573,490,245,241,775,412,394,463,645,919,547,788,771,493,962,578,891,235,817,108,219,72,919,93,866,488,554,168,450,879,12,868,84,901,868,551,564,945,475,330,625,101,134,412,96,509,673,784,97,727,268,432,641,281,935,804,595,260,716,138,134,389,893,370,755,171,584,345,963,519,845,865,247,754,793,11,560,494,256,597,268,792,729,149,930,716,450,701,980,960,505,475,9,40,766,126,802,217,50,539,441,544,523,58,511,805,489,268,806,130,294,840,395,239,116,857,664,123,842,242,863,625,452,144,97,926,445,925,50,445,662,297,206,177,421,208,55,683,265,75,387,508,484,998,122,624,819,219,27,999,0,94,357,476,440,356,966,728,319,762,242,815,962,315,529,777,203,224,934,356,954,476,239,763,24,210,447,952,721,579,268,47,387,231,79,987,968,426,954,554,332,996,841,176,512,190,81,169,904,989,819,765,434,775,784,686,582,699,194,183,435,682,950,178,759,217,94,667,92,850,213,593,821,394,554,871,699,662,648,340,439,886,382,345,707,792,856,778,917,93,167,916,139,736,852,495,177,563,4,386,506,502,800,980,207,20,482,198,745,808,885,650,300,603,436,863,429,606,171,863,99,286,226,808,934,140,715,430,365,75,306,60,9,711,116,385,874,328,422,658,197,144,873,306,889,465,336,55,837,984,355,637,365,550,779,466,195,216,356,664,347,111,598,88,279,52,87,499,792,521,294,204,484,43,258,696,693,659,358,983,530,889,221,702,164,95,536,529,509,413,278,957,164,313,98,961,56,296,126,581,904,268,881,960,837,411,258,371,201,900,556,471,903,679,412,308,629,515,58,977,55,473,705,368,122,90,652,684,804,571,725,525,7,352,297,521,613,217,550,303,454,51,176,588,878,855,444,13,547,691,626,143,113,32,21,428,771,646,926,250,934,875,278,618,909,555,38,659,555,128,386,558,97,298,756,324,981,655,848,667,583,545,842,939,476,601,457,319,148,7,946,789,593,936,706,777,527,154,27,42,805,26,275,992,106,902,163,259,309,869,87,797,656,780,733,157,265,663,568,132,994,739,343,691,517,244,369,210,604,117,377,294,157,702,832,225,909,943,27,817,464,205,192,597,41,284,617,387,307,7,866,502,158,321,342,8,218,396,26,324,928,678,971,68,75,824,970,376,490,585,426,500,366,30,78,521,348,469,108,346,448,684,613,805,425,352,469,597,678,228,678,108,541,157,705,217,470,162,984,282,295,41,599,677,529,149,75,790,784,205,193,386,845,523,188,887,809,460,29,248,170,765,148,810,522,989,972,508,924,967,821,747,404,183,233,182,149,671,68,727,547,565,94,417,789,366,886,278,467,814,706,143,779,765,537,19,802,767,893,308,21,273,920,439,711,723,721,986,744,476,777,289,787,622,858,864,309,680,416,25,421,171,604,264,878,872,615,664,393,546,581,858,301,45,248,790,34,312,739,404,652,766,716,624,130,496,197,572,754,121,214,941,741,640,179,714,479", "108,665,314,831,641,531,780,453,78,607,43,809,473,271,960,525,740,669,980,184,298,819,430,901,303,670,100,867,992,343,596,146,710,287,206,803,753,198,423,276,801,938,967,892,940,74,932,983,579,693,46,379,717,898,700,560,716,845,986,61,376,714,134,874,917,554,680,855,729,272,431,528,683,518,198,647,138,580,584,460,379,22,182,683,30,612,969,168,272,485,188,635,615,271,349,329,499,763,567,654,548,874,187,580,297,514,560,469,787,4,514,664,393,86,884,877,359,486,62,19,14,484,830,827,270,6,505,536,370,581,978,18,628,551,327,765,712,678,874,317,777,647,689,899,222,466,123,38,74,241,425,768,676,350,196,961,926,32,383,589,779,816,883,575,650,542,915,873,674,335,430,358,860,15,341,484,865,684,60,803,146,997,47,176,19,245,245,129,975,636,302,408,644,827,629,639,125,697,3,178,477,333,841,669,654,250,71,933,270,26,4,482,191,92,45,807,363,935,968,610,338,593,459,369,701,818,143,854,699,912,882,414,295,502,123,945,91,190,650,792,315,973,452,925,935,621,6,43,112,821,716,122,811,795,943,901,312,834,81,852,424,631,166,359,360,370,905,303,214,200,915,533,396,182,713,177,714,984,878,173,888,512,780,400,105,592,60,951,476,198,457,38,338,72,413,330,151,136,762,124,590,427,694,914,118,269,936,553,552,372,755,704,761,267,948,944,269,228,272,133,389,664,75,843,274,212,923,90,271,105,548,570,469,960,783,809,809,613,765,243,619,438,108,598,150,899,112,879,783,617,919,754,191,533,861,472,121,718,683,282,64,343,947,662,79,644,97,731,707,47,339,861,765,805,891,837,720,313,693,148,727,724,494,815,842,236,516,255,933,496,560,846,556,519,304,953,845,270,149,376,932,519,98,552,227,331,951,583,773,241,867,765,839,705,456,252,642,851,396,324,898,582,859,734,925,406,738,208,683,44,61,298,680,654,969,295,787,48,834,114,811,693,331,702,731,332,755,789,634,169,343,827,553,850,397,357,725,583,695,934,5,170,904,48,20,153,555,492,410,446,851,371,687,24,243,730,193,416,850,498,578,33,824,94,0,604,921,347,428,598,728,657,950,224,576,631,926,429,986,153,638,49,996,66,53,179,441,461,175,905,988,501,385,823,47,150,955,393,449,59,345,400,684,745,660,720,471,689,451,341,733,695,415,197,804,169,771,666,570,274,108,587,492,165,351,35,5,506,337,839,662,681,453,514,261,276,65,252,111,702,220,947,884,940,390,407,703,972,979,645,225,509,38,877,528,894,696,411,232,851,920,881,174,511,671,464,570,884,545,395,226,487,582,987,324,371,133,590,906,75,605,754,320,981,889,34,253,590,451,273,542,717,149,373,496,312,17,147,743,112,764,993,92,841,776,158,143,275,243,834,298,852,20,442,988,189,855,860,541,3,969,159,978,572,658,895,568,911,309,717,885,675,918,208,937,584,470,880,969,227,22,835,555,634,822,33,158,576,465,257,508,644,286,544,404,368,876,595,775,144,673,60,671,34,142,970,931,598,339,166,967,530,14,829,695,529,821,807,8,476,451,839,59,613,358,577,611,585,644,798,791,725,244,15,790,152,410,512,475,113,176,400,571,744,32,743,855,89,70,836,133,972,519,579,552,266,496,293,51,695,917,205,556,635,697,157,949,413,759,574,147,835,878,945,814,233,750,156,295,822,451,861,360,390,963,936,41,242,486,182,929,229,387,781,29,426,569,503,396,800,604,116,513,789,394,887,518,157,713,505,524,369,254,265,810,612,212,794,596,334,718,971,503,253,696,72,21,558,259,337,912,635,886,79,235,457,944,804,484,10,355,380,320,361,101,198,200,859,102,876,459,915,142,239,857,823,905,351,382,639,133,165,135,923,378,127,373,634,485,621,483,296,931,88,389,178,970,396,643,846,436,235,992,775,455,323,539,468,848,158,378,858,767,964,295,599,230,307,874,361,645,440,469,13,123,71,593,567,81,695,838,412,229,27,662,57,739,535,246,949,192,524,917,977,718,569,493,650,215,250,971,475,419,625,473,820,637,782,43,669,29,448,105,854,542,287,768,180,399,53,30,414,571,79,356,31,203,645,673,211,249,780,668,642,403,756,808,493,544,634,709,654,859,191,743,427,229,251,205,322,124,30,664,205,286,900,262,902,739,247,627,712,192,580,929,639,835,207,485,691,382,596,672,428,379,155,450,30,928,565,50,411,598,490,75,862,194,494,159,789", "469,439,643,442,370,805,181,302,248,492,281,265,492,295,254,728,896,223,911,214,197,391,650,609,867,741,220,513,969,177,586,459,947,65,223,571,952,21,349,288,192,769,169,476,976,259,481,690,408,38,148,289,937,143,997,716,345,96,301,666,890,256,369,865,409,297,120,884,189,555,482,158,619,803,689,893,573,716,921,418,556,939,545,189,266,832,395,844,977,705,256,57,749,385,614,371,511,519,585,791,892,368,526,607,226,754,724,19,229,380,433,893,805,714,577,805,913,311,822,830,178,725,751,701,922,976,288,250,348,169,503,151,435,860,789,405,89,247,166,41,817,720,100,341,26,909,626,630,72,862,104,146,215,90,843,454,404,143,514,401,178,848,871,800,967,931,689,291,206,700,319,370,652,28,431,838,257,882,481,377,1000,713,511,490,758,557,799,82,258,604,156,26,542,494,877,905,278,186,92,637,507,620,107,702,732,66,854,410,42,398,459,216,439,425,609,310,670,397,615,354,929,599,365,75,527,444,784,825,796,580,253,473,491,824,895,745,476,153,137,623,799,797,408,957,91,700,931,431,543,371,659,826,479,783,727,384,566,49,441,97,774,174,837,544,833,738,789,351,880,565,236,166,847,956,879,809,983,994,696,857,353,104,769,447,510,717,934,556,803,179,550,888,63,594,331,453,807,918,986,30,705,177,493,736,439,539,270,203,681,612,929,511,283,445,549,686,861,42,515,837,86,796,93,659,86,198,719,788,274,787,260,995,60,774,590,126,964,340,197,867,751,670,92,776,862,178,757,861,819,893,569,786,249,726,521,223,292,470,347,310,105,573,952,657,482,205,752,183,290,146,672,509,466,701,187,327,703,138,54,940,194,878,581,928,566,409,690,596,165,80,883,470,281,207,329,707,183,880,204,207,399,437,503,99,463,698,284,282,454,611,90,703,308,190,511,147,475,967,750,381,366,20,867,588,235,618,320,60,859,792,844,908,436,114,87,22,717,988,751,451,201,63,790,926,436,734,95,56,367,143,257,914,432,846,971,89,626,303,903,206,949,864,428,790,277,111,428,360,209,713,547,518,476,539,827,245,205,858,692,779,526,475,378,357,604,0,629,87,673,282,287,505,507,440,363,718,785,369,883,544,944,626,167,579,175,390,130,537,515,16,734,121,308,683,478,482,526,716,767,499,56,18,77,659,168,294,531,542,689,823,843,966,831,347,341,350,808,519,963,62,855,397,569,209,556,778,619,364,637,219,180,572,960,276,657,908,389,6,235,840,321,288,439,863,425,778,80,516,427,222,986,622,702,913,391,138,213,667,597,279,409,794,75,509,959,992,903,641,987,19,857,298,678,748,715,126,760,538,192,810,470,581,389,798,355,664,154,776,489,121,965,644,691,419,769,676,105,973,721,550,235,178,809,904,355,830,978,913,41,23,910,643,787,776,199,658,67,530,871,371,305,796,61,411,73,464,808,978,631,809,390,717,167,429,780,254,872,444,86,136,979,129,309,254,847,940,172,852,165,167,361,685,381,666,27,490,363,461,770,922,299,245,824,526,917,888,202,528,389,542,56,232,471,251,372,573,432,155,740,65,43,173,887,678,214,750,858,812,945,726,164,288,109,145,127,283,350,449,341,157,915,757,289,376,709,432,319,598,399,250,896,16,225,82,902,384,991,216,949,949,761,373,443,760,196,177,108,126,678,512,960,953,458,236,172,558,407,478,785,792,124,58,123,41,258,414,875,399,17,208,704,135,351,886,981,151,524,127,832,687,104,804,887,445,383,360,532,312,243,211,795,558,981,36,959,21,608,695,34,569,592,556,209,880,339,438,846,465,294,645,346,228,402,316,430,812,349,714,175,29,551,386,110,433,416,924,814,905,781,994,169,163,736,937,385,791,501,576,696,113,350,670,333,805,236,733,696,312,119,390,464,153,604,998,875,568,502,516,297,490,445,530,751,428,554,389,443,716,283,653,117,664,538,765,792,16,586,708,339,888,383,217,974,209,275,312,187,390,17,844,765,158,182,49,760,468,921,271,28,800,975,188,323,557,12,995,303,301,182,331,345,643,314,189,446,328,162,928,811,908,624,748,534,383,903,289,67,211,725,116,61,435,485,746,367,281,545,119,239,311,881,866,63,701,612,185,11,884,187,663,430,162,803,33,528,464,377,669,222,805,90,606,68,299,92,68,875,38,898,760,655,369,609,483,482,449,768,912,160,328,524,525,564,53,231,732,445,789,994,757,491,48,230,6,235,385,647,978,712,144", "171,966,299,410,164,144,460,219,12,910,529,732,733,650,230,907,329,323,81,119,995,810,637,883,625,803,915,710,160,823,114,425,6,722,921,931,501,849,215,578,409,658,321,689,875,501,165,568,51,887,218,145,528,832,825,321,347,385,238,437,322,464,196,515,852,439,712,153,880,749,182,724,65,986,802,650,345,855,43,42,785,799,28,505,293,444,196,836,510,133,460,336,175,271,200,758,451,726,359,340,111,51,743,835,637,656,907,806,807,939,254,873,607,3,924,320,175,614,412,292,358,470,793,733,367,635,9,77,601,647,223,730,794,345,966,896,611,491,100,209,112,964,839,577,37,282,862,195,411,32,636,438,381,249,521,7,946,781,566,976,607,937,835,758,269,386,511,825,901,393,878,859,870,904,25,263,866,130,649,139,842,125,256,337,307,160,950,947,86,943,819,533,348,107,876,291,231,345,403,632,522,976,764,233,57,739,206,356,334,626,552,448,89,67,946,194,873,162,712,631,364,13,611,498,493,988,184,242,493,224,794,84,759,858,918,713,937,476,433,994,409,614,257,337,183,299,406,708,509,95,275,370,324,128,433,6,617,847,15,166,115,370,678,873,467,761,836,17,859,18,428,600,840,608,639,603,890,993,777,642,388,247,550,159,858,565,974,936,317,967,842,821,260,468,355,454,962,783,558,614,615,617,741,573,859,192,205,669,689,662,581,148,106,501,18,535,730,210,102,423,47,298,821,795,972,481,900,253,915,946,132,372,782,546,887,907,555,39,364,599,874,685,471,919,610,186,897,764,971,571,129,467,355,946,506,567,999,818,476,964,939,946,638,982,933,535,561,903,288,239,408,851,600,40,495,315,97,470,68,618,719,444,303,655,872,673,910,92,346,869,533,548,999,892,87,863,387,446,808,859,395,522,673,274,297,850,97,207,105,526,680,146,276,735,315,655,216,127,440,260,821,641,737,993,29,349,246,161,429,200,701,423,210,946,974,246,910,829,381,325,847,528,922,520,862,784,575,23,371,466,890,835,803,455,683,752,753,243,992,958,400,608,347,979,80,406,973,517,280,607,371,630,184,3,73,315,876,310,4,76,387,531,716,476,921,629,0,506,705,890,534,482,796,254,111,644,493,95,485,728,549,634,502,312,465,656,531,57,858,670,107,658,318,339,667,269,841,689,291,81,142,76,60,602,86,621,632,168,636,499,906,498,839,67,168,76,404,158,683,860,547,455,282,944,988,426,820,736,320,635,115,518,441,437,886,109,693,48,660,328,575,235,22,160,374,176,15,136,682,10,686,781,754,818,670,605,547,435,790,954,878,921,995,58,621,266,989,82,396,487,701,556,961,801,15,87,778,538,766,917,70,893,516,77,46,756,748,138,290,950,796,664,659,491,582,851,298,766,650,691,377,563,723,832,269,413,918,874,966,959,59,599,746,43,623,823,698,899,407,527,231,698,91,269,355,224,315,795,274,131,986,618,253,271,344,668,98,673,194,899,341,831,415,378,296,990,444,839,907,686,127,170,845,274,885,656,229,721,346,458,221,566,526,973,45,659,683,241,894,759,376,430,445,815,344,241,62,286,733,818,338,951,931,132,76,286,453,361,364,994,302,16,567,385,288,966,473,325,900,236,792,54,658,602,694,376,985,946,483,832,973,994,440,274,110,306,374,213,129,308,737,160,652,338,109,713,280,240,34,753,33,420,695,917,641,912,299,175,178,749,974,275,89,802,311,969,654,507,687,941,531,265,421,604,196,256,219,812,743,52,264,929,346,212,46,271,965,662,738,101,980,70,969,912,4,960,787,144,58,666,424,181,970,260,724,242,273,498,401,925,623,603,98,319,374,541,280,356,561,50,549,234,318,886,772,703,243,793,710,56,472,214,847,739,125,378,727,746,578,77,167,864,821,584,629,807,54,517,145,366,698,332,967,756,599,942,568,750,108,147,638,86,484,606,908,181,959,998,534,963,412,268,790,11,841,652,589,805,677,323,441,29,142,683,138,142,909,174,499,57,472,778,250,904,836,255,817,861,703,613,352,60,883,899,6,483,710,251,363,831,491,913,729,300,621,838,811,80,449,198,823,790,122,80,16,845,960,613,87,397,282,11,317,450,336,687,165,81,913,718,823,907,575,23,327,509,556,609,474,50,444,352,635,1,591,526,963,388,306,144,822,789,263,282,902,495,716,405,165,163,562,756,926,911,710,621,162,967,234,291,345,650,855,118,419,870,897,526,300,213,388,566,493,151,518,794,24,248,450,517", "993,386,857,74,925,140,640,812,455,410,839,313,921,790,324,334,929,842,319,277,408,814,301,274,776,47,797,726,562,115,946,962,215,403,540,104,602,161,311,913,321,410,814,264,499,118,100,740,598,508,744,99,728,165,688,951,157,273,961,685,241,280,867,45,858,285,703,334,935,896,875,698,486,126,605,313,69,777,727,994,786,783,738,382,516,77,98,817,625,463,728,315,982,336,691,616,554,171,401,531,161,344,564,752,828,598,35,675,239,966,774,612,173,778,580,784,105,713,418,948,805,127,816,558,737,962,975,521,219,646,504,243,472,305,876,18,757,352,545,303,901,740,714,654,587,341,20,115,25,879,545,412,62,219,982,223,303,703,445,73,681,67,816,928,116,117,659,235,638,515,61,772,681,931,855,126,32,131,514,338,555,744,467,870,385,296,57,786,618,991,295,732,873,993,699,17,904,634,20,214,470,667,847,780,846,659,948,403,51,939,824,223,644,292,727,597,241,916,47,252,579,992,181,887,100,898,349,810,937,491,201,390,178,27,54,439,81,634,966,405,330,83,523,409,916,431,35,657,955,148,417,931,635,414,846,170,304,40,345,884,572,636,896,824,661,979,10,490,201,980,148,805,107,415,459,552,243,515,955,681,443,450,299,575,330,728,365,82,201,576,992,385,650,894,958,946,410,860,828,574,770,5,871,347,448,457,15,993,947,3,418,231,632,870,417,177,586,333,623,656,186,77,533,260,601,963,180,291,185,515,177,51,935,191,324,867,76,725,614,160,461,147,197,396,38,356,184,375,781,748,699,516,873,193,204,390,500,858,616,911,375,747,817,479,639,500,26,170,686,482,888,903,404,737,962,45,488,252,682,930,211,509,52,342,347,175,320,482,274,875,157,285,802,674,109,106,9,913,641,533,129,360,239,225,454,205,314,289,966,448,770,801,454,446,933,394,370,205,914,834,863,33,443,552,808,507,257,105,341,950,636,819,492,936,790,192,316,142,988,884,80,313,681,264,976,222,153,963,796,436,666,20,700,149,132,970,461,575,80,714,104,291,664,222,947,86,270,759,995,865,642,712,184,972,930,468,160,713,229,634,850,561,784,440,347,87,506,0,855,994,148,573,199,288,440,333,38,60,324,873,640,83,142,774,530,603,474,100,117,112,486,16,563,890,976,444,188,929,933,574,107,835,871,960,745,346,180,5,931,307,378,523,94,614,460,541,592,805,935,994,538,829,512,18,489,258,702,915,935,322,135,862,808,505,489,205,241,285,984,77,262,677,952,611,406,980,547,52,280,545,911,877,839,839,972,504,158,591,765,139,148,115,945,784,618,105,802,688,23,975,270,251,394,696,812,732,208,565,561,141,544,964,608,490,861,750,670,755,823,645,863,974,225,624,240,706,742,763,165,847,164,834,936,454,428,47,721,85,117,342,80,140,676,354,684,986,639,325,515,939,772,772,588,624,918,869,709,266,520,190,990,42,754,451,779,925,514,345,58,772,191,722,715,512,743,985,716,505,28,448,190,44,232,166,617,225,372,844,712,955,228,132,914,231,946,257,860,41,23,262,436,201,5,470,964,829,585,3,562,534,983,381,136,852,921,816,98,802,263,671,396,547,359,240,454,759,294,649,127,591,964,977,440,758,22,486,660,535,106,206,579,973,144,667,736,783,803,926,11,849,632,672,210,606,797,749,713,633,247,83,862,852,398,205,149,156,718,509,527,301,150,384,870,64,142,194,431,850,247,316,57,795,397,793,884,210,651,652,711,620,349,168,288,647,432,683,436,539,284,275,900,367,687,288,952,511,229,854,682,786,152,186,86,683,731,462,120,624,82,892,911,627,848,431,711,561,808,309,770,136,28,172,953,2,207,892,663,932,360,745,252,427,874,322,31,284,215,842,707,334,813,67,97,411,238,865,262,687,226,825,85,786,673,947,256,287,29,723,389,962,407,226,215,37,456,17,869,13,359,569,207,908,852,370,267,803,485,268,23,134,877,35,986,568,400,692,156,360,912,932,755,709,446,730,598,658,169,368,752,600,542,181,394,608,181,483,143,821,752,674,5,231,138,412,410,174,483,252,801,472,377,842,715,552,19,549,192,241,150,859,213,832,909,573,132,652,281,783,691,306,555,21,291,746,348,798,796,677,544,794,826,519,90,37,290,998,526,175,855,444,889,761,149,271,811,830,353,875,365,196,46,304,117,869,901,335,601,780,813,511,60,882,469,670,938,632,825,655,875,50,982,370,928,947,342,548,500,85,290,730", "886,512,539,411,454,433,557,514,171,432,90,38,274,368,176,722,462,920,741,717,118,550,562,111,350,279,447,610,24,461,758,251,791,420,689,202,364,343,182,392,334,187,262,537,783,735,426,717,52,395,703,682,796,663,631,572,296,702,463,833,181,469,470,186,210,978,655,288,750,926,385,889,633,985,258,715,545,93,635,206,311,162,994,535,517,730,175,441,485,574,480,545,111,948,140,606,401,288,814,392,935,448,370,338,877,134,975,978,201,335,402,902,351,612,373,949,668,637,138,810,576,471,681,162,430,787,715,263,386,173,819,189,511,110,794,141,400,70,39,345,256,386,744,379,26,752,710,691,373,589,204,774,983,51,347,360,309,368,83,371,235,722,523,420,633,115,320,114,556,445,529,192,45,891,884,993,12,536,234,229,52,574,898,556,903,308,952,657,670,752,427,175,921,226,755,165,699,264,493,815,528,455,458,400,840,493,564,21,230,100,892,543,541,80,136,20,623,443,51,674,165,727,268,644,325,141,149,615,100,835,724,560,877,411,293,741,744,162,557,297,719,637,713,329,841,844,646,455,214,366,805,917,226,404,45,293,350,808,916,318,923,941,558,880,948,103,881,140,344,236,378,545,973,112,30,895,559,738,636,246,599,696,678,71,173,324,288,702,326,557,912,949,970,593,522,744,461,606,596,440,850,79,615,540,652,159,276,377,15,866,387,592,999,480,701,946,610,225,39,453,61,662,771,485,227,983,262,627,84,263,501,641,706,230,667,209,556,770,442,545,93,194,194,74,382,399,220,369,988,206,831,756,619,851,513,420,991,749,560,74,957,951,886,659,53,628,840,523,536,334,114,971,372,486,777,783,699,979,603,952,99,876,359,809,630,250,424,309,741,707,288,132,863,749,716,429,696,757,392,170,289,760,638,348,586,714,834,968,432,786,197,627,712,769,114,630,488,521,14,594,548,738,828,941,399,600,456,661,441,92,44,979,967,318,763,710,619,89,571,773,36,399,100,368,213,772,356,672,82,930,894,687,841,512,742,13,448,122,641,430,274,426,165,399,102,812,901,301,265,762,93,980,46,935,993,445,897,754,466,843,63,702,647,356,428,673,705,855,0,807,952,633,333,999,974,44,916,499,927,540,590,467,467,371,862,407,526,670,423,554,736,199,586,337,705,408,633,550,548,179,402,680,158,640,967,506,139,258,641,557,63,466,389,222,164,544,14,275,382,180,867,191,217,839,615,856,102,970,931,798,961,644,149,326,191,453,140,716,701,456,144,239,628,265,211,781,776,178,254,519,522,550,536,420,671,801,564,63,415,495,284,255,987,116,531,966,524,278,521,286,533,553,490,988,294,111,644,551,805,155,230,54,525,116,507,444,626,20,300,800,933,983,206,930,400,914,332,740,424,188,341,842,221,810,256,348,713,304,306,958,731,548,916,22,361,311,183,14,620,388,526,626,676,997,961,299,121,71,524,271,133,486,439,479,370,76,988,730,217,704,957,122,477,210,50,407,704,231,615,574,167,43,36,807,811,549,203,591,802,439,52,373,574,172,849,218,69,317,1,64,370,965,205,38,788,251,515,18,168,456,959,690,447,742,768,839,464,296,86,374,568,946,869,916,447,754,397,809,481,73,376,361,647,477,574,130,723,674,699,825,810,283,814,126,986,36,482,93,577,632,401,411,422,905,282,384,97,313,812,98,911,286,616,696,209,669,505,705,422,70,477,992,574,28,779,558,236,796,621,981,174,52,575,829,340,30,815,149,955,960,432,243,806,922,467,405,282,462,265,74,8,220,894,150,405,960,376,649,127,770,912,237,642,854,645,851,903,222,48,815,529,316,292,321,537,358,997,441,365,573,277,610,40,831,632,709,447,653,26,861,813,972,530,795,306,883,581,137,632,260,471,407,258,543,321,458,832,180,931,387,283,620,496,923,174,212,405,241,586,163,568,284,282,107,235,88,440,900,882,417,500,923,993,494,196,477,229,661,24,33,646,981,478,987,365,880,661,356,470,483,772,678,330,923,501,317,399,980,835,626,982,18,918,362,589,944,790,44,541,393,951,242,390,852,395,648,401,33,549,187,989,495,556,716,297,907,397,527,737,783,845,590,20,426,694,549,292,661,629,59,810,227,159,585,9,21,796,324,253,628,521,685,110,974,314,372,146,575,632,496,401,822,287,709,150,322,801,668,365,793,262,76,155,222,49,792,869,487,818,759,721,655,696,162,715,690,492,797,166,891,986,117,503,945,813,198,523,329,66,647", "130,521,210,459,333,396,566,256,23,339,670,963,280,859,738,565,104,200,516,845,931,72,898,661,165,216,827,520,386,780,613,452,151,204,87,946,564,474,896,608,55,28,266,986,101,874,482,177,535,940,802,833,450,538,427,233,109,164,303,44,874,181,179,154,78,550,597,483,785,410,664,418,651,751,203,835,809,74,871,476,908,461,645,555,681,750,252,291,768,650,964,169,437,454,890,829,432,893,596,567,629,978,99,303,475,411,278,816,515,64,648,412,298,994,197,655,121,793,381,798,188,773,44,729,848,717,700,85,393,238,202,437,664,889,649,298,152,485,717,104,949,172,379,991,336,737,317,279,463,993,236,203,418,265,89,862,438,725,272,418,17,150,872,408,499,588,985,810,393,253,390,531,884,13,799,596,866,515,971,160,955,255,141,956,845,755,122,556,878,701,92,334,617,364,665,421,861,421,28,221,663,818,263,93,336,354,111,500,150,109,588,158,361,951,968,964,900,980,141,242,944,437,224,97,184,305,423,589,767,713,195,227,648,40,420,700,519,30,945,464,294,95,749,307,246,93,621,535,949,977,433,960,828,986,672,217,376,379,561,20,284,878,117,341,800,622,929,849,309,895,291,468,704,201,331,948,403,540,386,503,615,21,919,977,823,470,452,523,671,200,411,761,432,921,441,527,981,845,735,644,784,549,35,31,697,428,211,849,522,664,504,703,212,251,128,130,393,896,605,108,861,22,608,882,55,876,447,641,395,449,250,323,834,763,67,267,141,648,342,411,344,433,236,946,823,962,520,66,38,992,341,432,439,453,564,571,416,496,416,174,332,648,876,402,543,775,549,268,707,974,561,938,403,6,618,873,300,868,233,89,955,994,157,338,126,597,791,648,953,202,540,598,491,347,495,499,98,97,887,913,740,744,169,67,52,192,742,516,386,636,420,993,376,573,589,503,900,606,273,981,601,484,907,35,845,752,869,748,511,354,917,830,584,665,969,698,61,369,898,199,233,699,124,77,681,848,817,671,688,2,227,903,6,994,51,131,65,25,450,747,547,676,154,566,270,267,911,529,285,539,958,505,513,571,924,884,805,185,125,217,751,316,49,966,598,282,890,994,807,0,761,662,969,35,332,598,50,674,910,873,904,21,287,656,143,923,89,244,326,84,127,55,968,299,285,304,34,662,491,934,978,790,361,650,270,822,926,97,232,182,618,988,619,107,761,971,299,942,863,273,773,525,862,591,894,12,435,675,117,396,528,970,970,142,230,771,510,623,347,171,34,820,921,639,716,832,16,88,356,212,190,159,742,901,232,966,717,888,820,227,884,507,708,322,216,812,672,204,122,773,577,411,135,145,366,986,783,618,365,292,381,931,585,605,342,91,539,213,8,195,855,916,397,723,955,610,306,479,869,265,192,116,626,494,504,104,213,760,423,452,665,236,340,819,780,609,741,704,937,207,603,400,24,31,646,971,81,887,573,157,329,296,101,173,60,243,913,461,851,484,320,454,24,448,872,465,389,847,208,628,257,823,634,957,511,94,689,379,758,96,161,597,735,444,739,824,739,474,951,53,122,690,95,973,244,506,417,294,642,196,876,190,290,324,326,163,785,709,966,757,171,197,371,254,593,690,428,276,701,886,476,760,964,684,212,612,426,145,387,952,821,17,634,90,633,815,263,826,19,169,25,954,919,120,967,89,449,27,291,457,912,366,139,662,334,785,235,706,214,192,965,82,109,885,672,678,220,359,505,818,10,290,311,560,91,592,652,904,591,113,798,751,495,910,995,137,726,693,311,1000,543,680,484,171,671,203,2,60,72,617,475,588,954,820,3,614,964,80,468,74,286,325,436,867,640,137,39,263,904,173,447,810,105,886,653,782,196,819,428,682,944,755,557,812,932,392,847,155,729,1,292,846,734,300,957,342,498,919,691,237,408,786,438,644,903,571,675,72,690,573,438,186,978,504,546,314,937,59,37,347,249,569,202,204,266,979,347,295,887,124,307,776,539,880,61,211,956,354,273,131,823,850,547,443,130,678,288,406,39,93,304,564,927,71,657,866,196,888,213,461,839,266,660,658,793,815,659,991,477,612,969,688,967,544,88,71,538,755,559,738,621,735,95,918,914,470,868,922,24,764,677,121,281,909,177,342,933,384,919,709,546,918,151,709,111,143,65,604,597,129,97,193,429,400,964,930,710,475,200,855,553,840,363,735,800,22,361,778,480,598,249,546,940,779,581,554,886,783,604,272,952,513,121,887,719,417,972,486,589,100", "871,589,559,89,458,516,9,41,770,627,442,361,796,246,720,18,230,735,940,197,894,76,669,778,393,493,681,78,911,548,303,910,428,795,933,168,26,373,523,320,247,156,33,249,809,261,383,430,251,197,739,729,968,972,171,35,230,676,946,738,855,824,705,326,904,723,930,745,420,873,708,475,593,330,341,765,829,872,858,162,497,629,620,500,508,875,224,714,806,503,408,346,17,842,693,525,720,615,168,283,740,490,439,961,790,80,425,517,260,477,642,483,536,455,119,33,641,547,779,42,48,531,335,69,486,669,268,671,12,282,376,27,671,854,346,847,120,398,96,19,804,772,964,844,214,730,487,971,100,382,286,499,937,353,613,686,424,179,998,272,168,852,359,653,272,220,461,666,622,714,457,76,515,384,634,77,220,862,232,980,937,766,347,725,360,321,560,148,135,193,248,814,153,430,671,641,917,217,177,459,734,626,479,649,225,73,361,763,505,463,550,51,299,638,717,24,114,415,164,799,362,35,809,161,578,503,957,349,604,521,497,401,449,872,373,718,140,577,515,292,741,622,516,450,129,527,482,999,393,885,608,610,401,865,240,979,854,280,160,902,308,555,906,662,135,365,354,841,315,516,338,46,238,389,922,657,31,33,128,863,157,156,136,826,936,254,868,117,956,108,351,873,275,574,510,146,840,943,812,509,31,852,827,20,106,891,241,382,30,421,963,996,414,772,739,525,121,753,398,980,386,155,575,857,369,284,54,957,465,724,467,899,724,698,947,500,658,410,926,691,336,563,181,330,725,299,255,841,645,737,101,792,999,208,608,196,592,732,587,725,402,173,239,366,775,831,652,148,388,337,765,820,564,807,741,464,871,445,414,961,339,835,453,620,375,596,452,22,177,887,390,474,866,224,510,663,797,441,326,675,512,407,613,793,272,691,701,509,857,47,258,883,748,395,309,95,301,451,365,366,697,296,510,294,23,9,279,676,997,263,471,803,143,741,242,674,442,483,946,500,588,317,494,941,212,777,770,798,980,508,417,380,415,317,794,339,858,993,495,801,669,271,961,221,224,18,90,635,58,277,146,334,254,732,717,847,651,941,634,798,696,53,687,728,728,287,534,148,952,761,0,515,999,694,134,280,882,746,15,294,56,448,451,650,616,6,391,524,456,124,473,963,348,686,216,592,901,178,715,890,354,46,691,173,840,798,512,512,898,305,319,553,845,28,138,668,16,361,31,424,644,825,565,597,485,147,927,293,551,660,911,154,105,584,636,299,51,420,559,411,607,577,414,271,653,635,247,941,56,349,443,727,920,787,559,424,460,164,972,835,220,19,702,533,540,84,798,233,521,562,310,481,491,428,614,345,753,474,554,993,529,917,167,414,603,585,123,873,175,647,899,203,757,840,284,124,184,599,14,501,896,841,903,831,537,343,86,424,655,233,837,336,961,74,121,787,87,397,484,589,53,630,667,994,32,822,433,268,67,961,431,599,285,351,385,136,513,767,97,171,717,826,479,785,450,712,838,334,603,963,465,27,384,518,403,652,901,675,869,520,816,985,776,589,881,272,396,853,571,319,161,602,251,494,708,618,903,689,216,162,816,648,14,632,261,244,908,179,179,548,589,71,921,919,986,406,929,243,862,201,452,34,219,440,359,20,672,144,839,131,659,469,987,257,5,246,236,780,652,523,411,556,91,664,227,376,321,476,355,251,16,686,684,372,898,110,64,561,668,978,338,592,241,665,903,756,199,575,599,557,50,544,548,421,387,669,105,635,949,970,834,70,614,324,791,9,480,790,168,314,550,969,779,791,972,669,30,723,829,348,908,98,277,580,602,927,509,537,452,149,397,424,843,776,879,613,448,669,567,941,734,591,11,630,828,205,906,624,937,582,985,291,979,249,717,383,480,232,824,796,960,746,895,599,534,902,469,158,312,236,349,161,707,818,339,361,689,527,435,917,638,128,344,485,394,327,173,368,227,504,841,128,149,72,859,494,66,285,237,924,263,544,659,876,783,213,26,679,328,20,249,214,191,845,426,118,112,189,304,49,515,268,237,520,135,693,396,402,402,102,1000,713,404,885,89,178,277,411,225,816,481,407,473,403,588,889,212,720,361,789,917,438,500,971,941,934,964,396,159,132,708,139,478,62,210,807,262,92,788,597,400,38,544,330,632,581,866,850,542,236,955,603,504,22,135,849,900,738,209,464,491,937,301,852,162,1000,757,161,104,558,561,314,148,477,624,171,814,679,978,970,500,992,844,72,504,537,19,601,986,889", "752,218,670,577,739,367,235,821,940,935,842,431,541,106,472,895,358,751,520,513,293,829,697,222,431,222,707,530,550,268,879,986,919,296,764,940,84,807,460,978,134,573,667,947,497,643,579,624,748,678,60,113,814,830,403,874,641,940,492,728,475,323,173,206,757,636,259,29,986,962,604,249,392,853,882,397,887,207,239,965,923,117,885,431,358,605,852,594,832,719,215,780,587,372,376,781,19,253,523,977,806,970,724,658,871,768,35,412,40,307,36,257,2,548,864,173,255,679,309,325,188,512,640,66,528,308,310,458,196,331,285,141,127,771,437,317,264,562,362,19,709,110,944,999,678,291,613,767,619,454,537,640,82,462,499,838,128,282,515,426,725,123,910,501,386,661,214,952,674,722,186,406,7,470,820,713,39,495,292,184,244,598,30,675,228,656,757,124,978,191,907,639,845,136,915,896,803,207,94,604,562,891,283,683,250,48,175,56,447,542,146,413,592,776,998,940,594,794,175,472,943,59,999,925,705,218,990,313,577,467,772,29,558,209,61,643,682,70,798,375,514,261,460,951,541,827,891,520,588,424,827,55,691,161,101,592,184,841,172,50,293,904,666,640,35,516,63,631,26,337,80,917,514,225,654,976,798,126,675,140,240,394,590,970,213,700,265,997,563,49,334,7,155,876,115,954,33,574,619,814,354,385,131,588,388,790,542,800,738,373,315,899,306,53,181,194,737,788,651,672,803,198,442,594,490,21,769,265,67,309,892,688,412,943,754,185,626,374,770,21,215,507,577,378,400,332,915,686,733,205,895,750,961,691,508,140,216,523,415,544,223,618,173,621,857,739,188,175,531,404,765,383,625,285,61,707,325,320,828,345,551,920,955,743,627,592,290,11,240,309,558,558,420,557,420,137,916,855,79,684,825,2,240,460,652,148,160,207,277,31,799,132,959,807,697,249,537,162,213,617,156,978,814,92,895,424,709,617,948,763,399,937,583,328,605,691,342,447,403,298,699,295,389,166,353,878,25,683,720,64,619,83,119,641,49,944,403,108,959,195,455,227,402,740,722,799,82,162,331,236,727,429,460,205,696,99,319,536,472,930,732,393,564,319,657,505,482,573,633,662,515,0,152,26,905,884,949,669,486,273,47,585,529,59,66,743,98,589,698,514,125,882,130,686,536,364,320,771,947,694,162,975,578,837,727,872,325,910,730,344,749,210,984,938,908,307,693,177,339,754,242,459,339,443,812,446,452,51,468,937,151,712,224,720,184,14,263,797,815,482,853,581,271,646,460,120,382,484,440,49,561,93,337,764,589,19,347,805,732,10,46,756,691,328,31,937,770,253,672,233,101,488,746,661,893,953,884,616,983,125,726,184,322,491,57,306,699,221,373,761,323,677,625,607,773,504,624,763,498,992,399,787,270,293,772,133,581,810,307,493,129,940,363,473,222,548,462,323,620,861,223,940,551,696,278,459,198,801,266,423,476,67,25,20,487,44,502,934,873,191,886,941,292,657,215,133,196,172,795,102,728,866,677,429,722,616,886,82,538,155,31,195,208,418,330,666,688,327,764,397,322,567,428,677,810,66,647,199,433,856,968,148,131,723,65,94,894,803,591,562,251,202,659,401,456,426,333,510,73,792,809,12,46,769,99,238,416,616,817,604,454,62,13,563,733,883,874,563,20,477,345,383,594,294,142,930,149,496,171,41,902,506,694,656,116,742,47,250,471,877,733,169,699,493,149,539,274,655,76,765,589,298,280,556,711,820,412,870,486,833,504,546,838,589,400,716,128,405,610,483,967,408,997,877,560,608,769,774,219,410,995,21,173,707,569,264,878,960,172,604,601,416,279,549,949,791,972,592,916,590,721,258,953,164,62,868,878,509,112,67,722,636,201,635,952,432,692,570,223,163,695,307,615,448,379,387,728,553,301,336,168,781,926,197,549,696,179,88,260,440,543,591,902,85,799,708,520,249,118,84,425,617,162,81,547,822,253,221,907,176,657,103,326,493,431,627,899,331,311,916,54,778,636,422,533,829,592,855,721,12,815,693,822,298,636,739,874,180,851,18,12,403,880,799,392,632,643,362,522,85,553,92,313,319,374,769,195,778,783,810,608,6,919,505,562,966,581,276,246,893,118,352,124,113,315,937,657,408,453,432,917,209,717,686,667,37,579,681,61,792,502,529,788,618,202,675,652,319,100,184,732,616,108,717,386,359,503,313,569,502,778,807,552,364,222,777,638,396,184,511,765,917,479,241,863,619,165,30,99,114", "217,481,477,969,15,764,410,398,972,499,65,537,402,15,523,851,485,438,758,892,65,69,560,674,915,238,923,684,299,83,753,451,539,447,262,466,576,225,422,695,618,746,89,947,703,629,803,494,71,443,695,346,538,514,201,472,371,191,716,83,97,729,874,214,943,692,755,949,838,864,659,665,169,399,31,681,648,841,734,568,257,616,169,361,105,568,627,972,894,514,178,45,165,332,886,227,938,588,898,276,125,296,954,726,697,90,175,368,531,206,531,982,648,549,484,176,405,420,216,621,928,546,919,516,941,933,80,949,542,740,136,763,209,516,496,794,525,714,987,831,989,605,696,364,915,99,296,759,826,240,307,862,521,940,74,725,56,620,402,655,268,546,471,697,985,242,379,713,552,180,34,781,471,751,29,805,314,294,302,41,405,226,611,307,14,225,649,157,920,340,46,458,328,981,337,891,717,257,741,417,422,131,100,985,182,650,955,97,59,512,228,150,927,114,890,476,592,866,281,187,233,876,31,585,839,481,971,63,866,450,418,661,801,519,392,786,674,167,588,2,97,328,538,161,506,939,429,614,80,954,955,34,81,209,171,161,911,656,986,73,952,717,273,97,787,683,571,233,310,121,478,881,243,33,237,677,628,804,120,921,666,641,722,157,528,139,801,632,647,384,532,332,484,96,899,185,423,511,704,61,592,964,618,84,693,252,171,833,470,490,815,100,308,803,965,103,726,923,664,166,189,692,598,887,886,321,659,282,191,601,314,190,384,425,74,125,672,796,476,414,974,876,158,152,989,789,348,975,18,43,642,927,431,945,230,981,530,79,233,308,776,391,482,153,927,201,757,734,41,698,677,825,40,683,651,13,898,232,523,469,312,293,493,888,803,942,910,344,949,997,582,202,522,649,32,368,717,877,716,255,364,396,484,304,704,652,218,459,212,20,61,554,620,749,80,549,375,3,114,619,854,864,910,134,922,371,254,698,978,634,346,734,387,460,247,442,560,476,600,412,897,362,151,569,783,100,869,583,150,369,429,47,812,628,995,851,922,675,728,979,201,83,652,100,954,466,252,963,908,438,638,787,609,686,261,372,115,384,56,616,87,643,8,762,950,507,796,199,333,969,999,152,0,398,432,353,692,948,729,813,649,679,1,615,25,946,173,833,6,186,175,948,735,360,952,507,247,18,539,885,888,760,924,895,783,859,119,143,260,471,262,462,900,31,390,910,619,640,440,185,631,862,413,159,985,348,773,236,590,34,882,738,271,729,549,379,499,658,146,289,198,19,367,675,279,848,299,218,930,412,928,559,12,967,834,868,790,342,156,405,601,265,746,474,967,370,111,810,584,684,583,950,274,772,498,936,25,659,474,706,473,678,691,588,768,84,854,989,93,771,102,636,858,525,722,511,813,944,501,692,388,304,727,199,360,724,209,875,413,175,419,782,358,641,458,177,376,22,461,593,500,191,872,629,841,544,567,948,979,66,730,116,795,393,16,920,265,55,350,859,441,358,33,931,372,222,957,179,725,242,242,356,898,550,256,878,821,619,372,263,781,314,381,916,280,588,592,55,610,460,989,109,395,974,104,106,8,63,86,671,836,277,549,261,655,503,536,529,281,873,138,855,573,138,720,423,121,200,606,317,804,53,43,646,565,233,141,117,898,46,341,823,225,800,395,808,748,268,870,251,522,647,104,536,42,467,971,595,425,382,767,699,564,310,755,34,965,976,764,989,350,701,327,783,344,771,197,768,154,824,68,86,535,466,81,94,154,844,612,664,997,257,46,23,978,718,414,507,468,312,461,546,721,870,10,899,363,354,344,212,36,337,64,120,220,883,386,958,24,263,931,501,311,79,355,670,869,53,55,481,759,806,137,987,836,651,958,813,162,361,309,459,416,277,910,988,211,481,585,247,878,900,160,32,722,317,381,547,345,726,414,633,390,62,623,385,510,442,642,698,839,266,650,180,239,633,296,376,867,260,313,72,587,968,157,701,280,345,75,808,294,956,220,110,45,207,329,7,854,526,597,547,183,11,276,145,359,594,937,572,373,915,134,389,977,928,317,919,874,201,923,992,744,42,870,836,775,826,124,14,646,800,420,397,141,774,682,291,484,993,721,91,577,717,309,167,4,554,763,910,767,21,310,922,502,306,186,994,462,164,499,545,590,334,809,384,682,586,352,108,929,303,873,97,224,592,303,864,490,314,381,235,189,958,21,671,37,614,316,650,610,367,884,674,792,720,878,675,795,647,681,973,569,279,717,917,22,49,180,922", "896,288,766,74,856,935,959,717,368,73,520,418,456,694,221,479,190,435,257,527,706,311,28,328,840,140,745,515,547,458,437,919,207,948,436,648,301,685,874,44,180,346,934,17,437,478,147,611,910,755,421,499,980,363,101,568,358,690,681,930,246,405,199,668,278,188,478,103,572,613,65,232,487,496,658,512,870,44,754,527,913,563,21,939,475,173,367,293,781,767,309,391,645,45,778,49,350,538,725,758,136,260,746,665,850,203,26,259,466,362,461,357,921,593,579,694,330,478,429,520,861,587,579,974,739,451,209,945,655,310,880,988,709,232,861,3,551,760,455,954,366,590,517,826,260,350,62,910,103,987,941,585,124,416,501,364,855,516,389,503,240,676,148,657,975,114,459,13,432,153,659,404,14,223,333,150,479,684,301,414,19,926,386,549,262,914,342,585,802,208,621,508,691,493,747,408,805,696,860,676,151,203,346,124,53,784,870,656,682,576,91,397,6,296,93,824,617,225,560,100,71,766,989,567,389,259,715,198,628,249,33,540,783,756,357,179,46,65,923,922,81,556,824,572,11,41,882,15,223,498,616,879,976,310,721,381,306,6,682,626,879,738,524,535,275,796,11,553,573,760,136,352,32,471,800,346,37,84,68,834,926,681,208,564,839,861,469,444,59,248,349,723,361,992,366,102,492,963,2,112,401,727,223,20,36,389,895,595,993,517,152,621,777,745,561,803,981,997,893,183,3,199,108,339,490,322,355,676,837,860,669,309,840,667,223,585,826,391,699,130,603,212,138,357,462,527,745,513,766,919,612,844,216,649,468,789,871,767,480,214,947,339,372,177,480,585,697,543,422,844,759,720,10,919,584,367,440,22,490,104,136,758,738,82,465,259,931,880,167,29,181,228,188,889,883,97,681,914,643,841,219,83,636,309,38,706,850,1,414,95,840,460,715,957,402,939,549,280,370,302,29,172,65,806,817,45,14,498,668,410,365,375,979,277,219,125,659,176,994,580,80,928,959,607,8,222,58,312,584,520,71,16,184,223,729,44,908,709,761,505,257,77,870,505,499,942,553,840,137,274,874,7,82,937,716,848,899,907,119,863,839,389,301,242,224,440,254,288,999,35,694,26,398,0,528,534,101,683,861,371,811,467,992,245,846,654,817,789,774,815,269,721,860,71,733,902,508,207,88,150,745,337,796,105,623,483,938,13,383,716,564,805,154,138,159,381,534,476,339,927,976,76,466,672,420,693,231,993,246,214,465,380,300,148,579,426,336,951,983,262,603,260,239,486,242,106,961,679,854,969,374,544,623,553,686,783,692,572,47,152,717,717,94,356,219,818,415,917,424,64,885,649,712,535,325,995,316,23,502,334,568,597,773,342,624,165,362,205,877,896,186,865,832,34,194,810,608,844,234,472,423,849,711,962,908,484,182,479,355,894,851,243,594,398,71,111,484,320,683,916,895,234,923,580,97,673,807,887,134,355,349,261,751,646,995,914,490,526,775,819,326,930,193,556,21,650,158,558,525,1,429,253,331,153,389,634,102,201,314,12,569,595,163,483,207,792,848,67,303,685,231,404,482,995,693,19,560,366,11,412,595,818,429,233,743,318,809,512,814,39,316,655,810,158,342,712,935,559,192,91,424,576,984,718,815,170,99,967,846,445,213,653,828,968,414,712,627,721,60,205,715,236,207,911,74,837,27,320,683,199,800,980,33,860,848,944,863,512,545,860,51,226,795,388,452,219,885,31,857,71,880,374,995,584,72,203,392,706,823,445,820,938,636,724,3,274,834,845,837,894,816,901,122,139,774,999,73,146,287,748,887,227,78,397,216,796,884,46,248,819,639,121,816,3,781,664,818,4,980,194,27,896,191,952,889,211,432,566,212,264,597,631,216,938,718,833,410,645,203,950,383,573,582,368,64,287,909,994,189,596,450,784,405,652,244,849,907,36,555,600,640,464,87,590,870,523,371,703,143,555,48,927,935,190,913,156,741,270,332,563,5,786,537,491,397,538,439,926,232,528,45,161,777,957,280,608,463,7,658,837,937,439,257,409,648,133,784,954,883,811,280,626,48,128,535,945,391,362,881,790,816,5,826,913,545,9,691,446,569,55,331,433,161,262,845,424,589,964,144,922,910,530,925,640,563,697,12,261,861,815,70,608,203,17,961,493,110,50,410,278,700,618,80,413,140,541,428,383,869,485,834,254,573,171,344,556,797,921,917,826,320,135,563,989,356,14,2,253,451,880,781,924,788,513,661,525,961,811,536,473", "446,995,400,672,35,892,527,885,53,507,320,275,110,233,609,225,164,788,316,20,99,31,841,499,351,447,897,761,189,468,631,429,910,562,585,199,786,310,523,130,603,42,864,634,539,483,310,494,669,363,561,577,506,390,406,987,800,37,276,28,816,494,692,354,488,617,829,550,511,70,138,194,428,25,689,657,882,723,443,717,993,122,942,838,140,463,963,516,354,859,631,521,668,163,329,695,200,457,350,70,513,568,593,564,912,175,762,270,956,284,161,408,790,518,155,845,319,754,490,240,973,699,944,362,726,212,990,914,503,22,145,420,313,739,541,846,694,742,877,248,420,754,534,644,950,732,52,894,714,924,156,228,654,378,720,703,861,8,18,915,281,539,68,687,506,153,628,752,781,32,989,824,810,431,358,256,621,914,260,264,398,244,527,334,450,376,387,278,281,574,64,748,489,553,861,418,558,38,722,861,85,844,754,846,586,794,564,99,340,966,965,954,175,184,900,305,815,76,427,758,242,132,477,224,34,923,994,509,813,727,284,867,575,204,883,739,907,989,694,31,353,210,297,887,505,846,50,954,289,795,569,501,922,532,60,542,408,709,322,264,87,442,925,801,604,475,236,920,316,421,211,633,634,266,226,183,694,973,194,959,818,228,734,584,888,697,660,668,960,555,113,944,239,111,73,149,428,383,59,147,513,358,672,284,357,11,520,235,795,149,534,427,437,893,620,648,871,50,319,247,379,746,716,801,266,486,668,814,332,341,380,122,636,212,296,67,791,45,468,369,276,724,76,840,746,627,967,745,657,8,327,702,865,970,581,177,826,423,525,763,908,916,668,342,139,564,102,428,811,116,573,856,876,546,610,729,557,596,499,332,654,603,602,407,898,522,572,381,62,815,306,354,939,713,799,240,87,940,690,826,817,87,643,622,611,250,365,609,28,747,982,318,136,559,903,129,539,722,779,85,224,189,835,545,888,219,631,599,543,938,150,285,79,576,753,649,269,1,985,340,842,827,95,559,942,805,628,994,308,176,460,937,978,156,32,962,184,111,415,30,478,580,553,446,876,579,366,868,304,940,760,139,70,797,229,796,288,71,6,230,866,246,995,815,576,363,111,440,974,332,134,905,432,528,0,471,930,18,631,955,144,507,121,277,884,450,516,370,834,693,856,237,676,241,730,903,264,755,610,697,974,523,798,172,992,63,608,262,615,187,424,173,512,960,779,746,890,434,438,602,984,923,950,618,178,948,724,73,358,584,283,671,46,78,637,234,381,848,885,627,50,10,17,795,997,595,716,419,832,562,927,71,635,912,615,506,246,439,855,782,443,843,504,99,463,852,37,323,221,28,92,878,396,424,576,245,618,827,296,447,852,914,468,576,983,238,627,458,116,381,381,344,362,168,793,933,211,771,707,241,945,331,427,235,46,500,837,648,89,903,656,134,343,965,743,888,961,525,800,598,806,936,254,558,129,406,164,148,975,571,675,663,860,743,119,139,615,616,388,121,674,89,522,432,675,406,128,576,442,284,566,590,195,50,794,725,93,464,710,129,424,393,10,394,125,62,465,644,444,765,723,903,113,117,636,998,9,827,542,272,898,173,180,9,156,961,876,501,493,143,393,503,275,910,206,842,717,476,18,743,215,972,617,738,122,731,873,903,754,648,439,537,676,327,617,812,409,326,629,411,922,94,528,734,201,28,794,767,677,774,165,381,230,149,782,898,644,611,255,376,258,366,132,926,288,706,654,472,750,671,736,110,950,520,618,130,928,9,466,808,704,289,694,693,128,136,655,225,547,139,19,6,532,557,582,341,468,955,767,383,661,97,71,669,595,258,891,796,790,209,771,538,501,767,294,960,521,657,292,768,103,526,940,409,232,495,606,914,143,119,153,620,986,126,742,349,45,265,399,746,868,766,841,81,69,471,46,861,294,937,380,635,785,162,416,74,737,903,24,706,254,148,143,740,417,234,677,225,609,357,856,46,863,696,409,362,173,358,558,895,970,302,359,996,404,991,663,787,191,559,641,564,709,32,480,335,742,296,289,524,101,242,523,572,257,297,326,861,501,893,738,125,887,798,555,141,816,219,18,121,864,760,546,895,939,68,100,190,213,511,549,4,243,691,363,150,162,548,937,881,225,760,583,625,416,871,121,275,921,949,592,604,455,550,904,57,486,600,673,46,519,508,392,831,32,548,448,948,791,952,445,449,993,689,764,353,618,681,204,780,706,946,128,461,793,164,951,282,417,511,924,210,919,357,318,353,711,356,482,140", "66,791,17,930,467,78,370,940,785,421,513,295,256,331,45,102,810,290,813,410,577,66,790,811,424,447,663,378,499,349,702,387,184,238,30,6,361,117,139,283,503,343,29,974,554,32,193,771,586,672,684,488,526,34,487,94,569,265,383,550,99,667,380,732,386,949,373,637,410,406,920,494,729,929,98,275,854,145,21,104,242,310,723,230,720,62,978,919,277,973,977,902,86,265,768,245,166,139,410,672,878,733,170,807,445,414,53,125,369,938,451,16,186,457,52,306,158,714,111,541,579,561,765,937,864,764,783,219,84,453,703,171,833,776,350,892,521,663,753,61,413,491,910,215,24,664,271,582,424,695,923,636,677,381,614,100,529,268,931,880,643,791,501,202,371,939,780,131,693,198,290,849,319,33,547,341,203,524,425,673,253,705,988,877,332,430,68,480,552,886,798,849,39,938,284,3,745,90,147,706,479,728,792,299,216,155,902,843,895,248,560,820,222,615,69,726,929,404,682,631,768,925,865,252,438,772,346,34,555,724,121,188,497,714,464,369,995,342,983,742,167,775,367,712,993,468,102,826,558,32,823,409,679,126,524,789,576,990,326,120,352,781,924,818,575,306,511,529,876,675,823,133,26,399,517,115,680,91,350,601,652,740,619,318,417,747,398,706,608,204,122,46,846,294,447,980,261,27,323,280,195,148,109,219,912,278,430,908,194,689,849,760,393,297,61,991,662,256,742,270,226,810,52,979,756,412,71,445,622,683,320,238,377,562,779,260,457,590,54,526,551,282,37,302,372,790,26,767,67,216,231,421,326,508,205,177,277,419,928,948,246,852,796,990,4,287,73,259,123,995,473,322,126,769,287,84,494,250,249,556,706,361,445,880,405,5,327,281,878,231,925,645,468,500,913,671,591,352,387,64,221,113,698,845,698,650,389,94,109,816,942,346,780,780,360,135,560,400,680,855,310,625,10,647,930,860,678,674,186,450,890,971,370,452,767,313,157,643,310,759,89,116,150,257,431,593,299,546,854,421,50,977,164,125,725,251,648,955,52,726,286,111,404,403,225,530,155,104,45,459,888,476,293,273,13,122,642,923,883,811,34,448,309,962,631,718,644,333,44,598,280,884,353,534,471,0,303,518,747,519,415,859,190,398,374,738,662,388,954,544,424,860,530,393,553,87,708,111,889,241,493,231,705,896,85,645,676,436,859,766,216,574,25,489,561,650,644,313,103,395,166,978,108,241,13,724,183,902,135,455,689,522,117,700,860,836,858,486,812,278,216,835,729,71,33,23,257,952,182,274,241,967,94,320,722,221,989,440,814,195,712,229,720,738,725,544,26,613,758,228,591,287,727,735,515,70,427,955,880,604,349,788,843,315,759,464,88,373,369,906,152,506,448,740,118,561,380,829,243,44,127,410,212,204,170,55,409,631,726,785,676,47,738,536,599,796,832,776,575,610,440,222,143,652,609,845,246,397,257,850,948,864,830,792,924,321,859,611,114,640,478,596,30,780,712,369,534,571,432,70,363,762,201,537,962,4,342,246,926,306,410,195,463,351,141,990,444,715,976,965,200,652,495,682,174,570,447,130,467,993,649,943,607,972,652,515,532,818,653,439,489,300,674,214,770,461,451,763,688,329,873,410,830,846,744,802,943,527,802,74,922,17,920,178,582,905,721,589,709,912,549,624,220,380,11,328,27,54,705,920,861,963,318,990,62,173,355,460,81,500,412,602,160,308,532,70,339,819,549,359,199,914,347,171,932,385,935,492,192,937,942,638,351,70,361,708,232,713,84,633,238,27,771,47,844,987,4,322,549,697,489,919,181,356,731,254,268,465,266,596,189,85,758,396,925,87,362,540,385,946,204,401,853,913,409,580,455,525,474,794,471,972,394,699,360,591,388,657,499,547,107,229,193,527,215,922,974,989,781,560,74,913,929,921,316,877,241,116,653,29,180,353,904,288,772,448,555,524,148,601,692,590,243,239,330,253,179,88,401,311,656,159,183,707,430,209,112,280,610,768,835,951,684,329,257,990,177,743,29,433,439,27,211,135,907,516,8,182,955,332,732,930,710,436,624,696,618,562,498,3,718,32,396,909,488,429,227,567,59,485,42,627,119,309,963,346,501,408,207,55,780,515,406,833,388,430,190,939,330,364,254,229,512,26,784,601,749,720,46,589,359,468,606,940,836,327,396,90,773,574,213,462,489,97,875,764,446,454,978,789,51,422,23,615,684,277,697,567,721,429,784,897,987,737,43,477,667,617,888,145", "223,791,869,663,465,8,646,801,928,693,663,836,983,590,958,368,583,714,569,938,355,298,909,618,951,995,645,859,412,591,779,151,366,121,37,878,68,701,19,524,960,800,870,225,605,2,881,651,401,740,276,402,337,324,751,26,909,362,99,622,407,451,575,468,930,742,294,552,658,546,182,646,78,274,371,62,169,45,88,316,977,627,58,545,327,431,732,137,277,214,208,442,507,706,6,206,184,523,293,543,758,88,400,875,522,11,977,696,52,813,982,884,639,784,614,463,143,139,115,246,727,195,89,8,271,110,598,662,657,826,518,438,355,188,77,119,516,806,225,979,616,701,426,154,925,834,18,903,420,735,397,938,713,931,258,249,315,35,635,3,502,366,596,580,763,163,849,64,963,639,123,59,95,833,784,36,754,942,482,866,341,704,575,470,945,687,84,716,622,3,819,100,488,313,254,731,957,897,160,630,997,710,650,439,471,524,725,943,686,324,451,377,814,607,185,62,914,162,336,759,677,655,348,417,888,244,314,310,963,754,858,65,729,439,523,70,307,514,236,830,594,253,90,843,416,822,318,488,415,805,690,852,260,429,582,610,748,782,951,565,761,210,890,833,640,238,763,923,156,575,935,196,447,140,62,549,622,937,97,470,855,52,279,960,222,205,823,726,947,216,639,58,295,20,219,792,249,772,626,804,879,519,902,326,821,703,949,437,869,708,877,892,200,50,905,671,744,560,878,104,535,790,407,221,559,15,648,657,152,282,585,611,994,982,305,865,597,28,445,484,946,425,624,570,334,399,252,304,903,580,22,460,24,225,257,419,39,814,533,703,765,812,257,6,17,824,44,175,481,436,413,801,597,904,622,405,10,133,132,548,725,841,117,525,352,798,785,891,377,588,390,301,193,953,157,801,753,605,852,186,646,185,706,984,263,361,705,627,273,253,432,524,607,906,754,592,162,440,100,280,20,680,829,267,111,733,220,247,779,416,110,704,994,862,58,502,814,166,477,694,868,383,192,620,120,84,124,585,723,148,138,377,739,821,214,687,286,626,84,46,363,568,242,674,814,159,647,62,422,996,1,793,526,119,987,618,60,202,153,105,447,823,991,315,926,785,493,38,916,50,882,949,692,101,930,303,0,657,823,937,238,616,157,702,982,827,537,36,103,953,527,953,192,248,237,104,447,480,686,479,730,159,664,597,789,45,278,181,818,74,381,527,186,927,52,622,511,315,972,352,284,599,416,371,235,281,856,1,783,355,728,975,26,252,151,105,3,62,427,635,772,630,862,515,211,663,372,270,305,471,713,386,73,412,172,34,182,125,763,206,448,761,861,459,7,636,396,777,377,317,264,528,435,463,498,693,142,491,237,673,907,865,361,795,28,389,601,90,16,976,237,453,52,200,256,773,127,961,55,417,55,990,737,431,415,771,529,975,196,710,905,550,439,878,865,950,48,293,128,955,884,392,219,527,864,469,812,713,451,777,484,229,890,655,783,723,999,249,150,150,46,462,872,918,772,473,114,283,523,582,332,329,969,633,475,384,46,71,92,934,498,793,194,45,685,291,813,565,60,17,528,967,878,397,456,974,331,307,125,808,963,255,816,433,351,642,397,37,649,727,255,513,759,741,653,226,8,571,752,350,878,841,646,792,560,443,365,723,498,29,257,131,279,10,85,568,269,874,282,340,754,823,733,11,448,114,974,736,609,272,632,995,913,542,744,973,881,706,183,238,468,538,62,960,105,98,440,92,499,431,683,424,965,58,826,332,474,703,487,535,717,136,175,234,923,551,407,999,133,411,874,795,371,912,702,360,438,748,264,406,777,162,168,645,197,275,271,305,59,965,141,548,118,102,751,175,798,561,679,756,936,669,461,93,258,617,321,535,315,780,440,563,144,92,183,428,932,452,953,932,62,290,638,530,847,511,300,466,427,12,629,636,53,127,879,125,775,464,746,485,350,586,576,862,547,925,692,925,214,166,331,997,99,28,880,155,137,445,750,724,230,872,685,400,742,619,27,775,4,185,955,938,323,742,323,681,956,910,412,72,369,459,335,601,913,618,642,618,824,316,461,297,873,115,434,5,41,462,566,952,237,206,988,710,343,884,443,439,558,726,174,897,734,450,510,808,451,118,328,891,176,957,807,202,651,216,581,68,438,28,186,459,293,548,804,921,457,276,663,352,296,205,201,547,682,84,569,129,306,302,414,151,899,429,52,92,558,19,10,538,807,550,405,4,423,105,330,983,717,54,208,694,495,187,351,386,670,138,972,699", "648,674,915,387,404,306,257,971,700,258,396,466,678,181,411,492,943,782,722,793,79,973,836,703,739,200,538,19,351,705,788,655,818,461,711,887,561,77,322,844,394,597,801,540,879,729,372,894,353,683,570,290,631,795,155,258,92,607,24,657,996,168,307,563,926,594,548,828,84,144,448,994,224,370,356,130,852,595,657,763,827,111,315,236,953,967,556,205,913,416,24,475,992,941,840,856,997,340,289,218,409,719,441,23,994,289,761,745,702,108,205,692,423,800,299,86,986,501,482,638,183,845,224,779,246,350,232,274,634,35,1,763,927,212,609,917,96,554,136,848,812,139,185,340,870,641,539,571,930,100,214,892,149,245,993,397,430,561,175,446,618,223,608,582,889,439,296,36,704,200,828,645,616,745,925,508,589,34,754,838,344,790,875,307,921,576,914,46,303,424,593,263,520,703,129,418,741,109,410,133,193,398,499,814,995,608,507,921,234,381,825,190,198,35,786,328,878,175,82,967,981,192,226,482,628,131,326,890,422,607,728,391,505,198,992,87,296,389,302,23,642,888,825,1,512,745,985,711,813,281,473,932,135,171,520,957,261,189,347,653,358,105,550,325,852,485,869,756,481,910,564,606,882,747,886,72,328,996,192,734,592,855,948,567,319,956,664,882,924,68,745,590,122,748,820,7,28,124,558,519,590,339,646,535,336,253,465,13,464,321,98,304,719,139,949,603,316,926,59,842,723,537,532,108,65,383,920,801,438,358,105,67,587,501,169,527,155,479,521,440,421,804,645,125,226,955,73,97,614,210,269,387,849,808,69,106,460,500,7,548,324,879,872,924,843,855,230,832,286,171,16,998,924,871,896,764,480,334,653,48,120,790,799,403,699,199,689,501,974,765,857,29,760,44,721,197,269,516,891,817,657,371,90,119,567,927,824,593,872,368,689,723,689,458,991,52,841,696,514,29,537,774,406,141,962,812,136,519,592,904,905,149,699,529,23,834,705,319,702,492,790,655,121,284,837,664,824,980,249,537,310,707,855,779,777,674,296,234,871,610,964,891,710,122,232,128,44,606,763,248,374,682,596,329,872,40,455,810,314,552,159,636,884,529,429,369,95,60,499,674,746,669,948,683,18,518,657,0,422,110,303,491,104,320,951,442,961,498,417,326,399,255,792,442,824,291,179,549,346,824,137,426,956,37,357,118,639,196,736,27,451,825,344,429,127,541,901,759,654,884,17,112,236,494,956,968,927,285,960,432,920,452,996,106,387,365,496,971,17,637,15,57,93,881,719,930,324,246,912,738,833,908,774,326,640,591,414,739,316,868,482,806,707,525,317,841,398,291,59,452,66,514,515,172,658,546,241,33,621,96,792,151,414,570,723,630,477,462,390,814,897,890,580,87,996,634,961,5,399,21,685,933,200,914,745,124,78,908,453,230,535,867,155,66,638,325,835,915,561,364,599,79,631,739,379,62,379,166,280,266,670,204,178,543,7,107,817,32,727,153,826,604,157,452,807,276,464,966,889,68,60,343,343,306,524,556,227,885,252,593,479,487,736,661,941,419,614,354,685,91,73,618,264,750,948,461,813,626,156,955,2,969,986,894,332,677,596,265,360,611,474,509,792,413,568,38,37,820,730,509,274,39,32,637,104,505,668,268,740,632,469,297,527,552,394,618,787,547,81,104,350,476,3,308,336,618,222,66,166,273,950,408,751,286,205,100,571,903,629,864,148,367,811,77,674,628,66,925,115,325,587,63,583,745,537,45,935,572,949,123,739,744,77,248,943,994,550,201,654,373,466,625,570,845,907,638,64,232,850,729,117,471,221,734,75,825,728,391,257,737,263,522,438,298,938,119,265,723,156,307,241,264,42,510,684,935,834,240,550,185,123,964,381,380,374,94,745,922,258,264,100,658,260,252,482,316,672,886,866,826,275,844,187,532,415,902,163,240,651,500,971,901,553,861,918,529,3,387,189,914,471,579,551,863,132,83,627,888,559,616,207,178,545,359,487,207,214,79,888,709,289,768,389,335,89,448,877,74,696,435,880,327,804,179,165,191,588,662,32,13,596,895,527,471,554,491,66,473,823,802,581,634,253,866,182,125,236,423,781,284,212,463,896,421,186,71,612,251,986,462,377,712,795,534,792,5,765,303,941,57,821,497,445,455,778,481,856,743,606,591,474,493,477,370,234,576,453,171,421,884,428,305,478,189,50,315,196,605,476,280,684,937,439,647,192,899,356,858,316,965,603,79,412,908,175,167,631,850,524,775", "352,582,361,973,29,72,43,791,666,899,949,365,392,694,265,405,399,725,314,992,293,440,664,420,504,253,208,856,921,689,712,323,445,40,347,219,850,950,585,415,165,94,96,441,992,440,840,642,182,307,324,305,63,733,769,18,843,812,3,135,759,323,44,862,472,49,490,181,954,910,186,673,348,506,127,59,546,487,287,902,350,70,531,587,926,560,979,652,768,319,69,307,524,706,387,909,361,950,837,590,17,428,915,269,164,512,453,50,307,561,120,937,43,96,823,867,881,5,736,332,834,261,764,312,417,605,422,340,731,51,74,239,560,153,722,172,975,796,428,886,853,674,201,775,780,393,43,866,503,871,948,607,184,212,957,695,406,828,483,307,993,252,96,434,759,11,605,145,117,670,425,8,291,347,489,640,880,543,817,127,156,406,602,740,527,560,446,537,386,78,394,93,758,534,644,91,730,396,580,986,999,861,300,786,712,423,60,22,833,675,286,537,400,975,945,822,186,475,45,246,896,146,370,309,529,240,31,344,335,246,891,724,338,477,519,230,277,313,656,710,436,723,315,633,644,4,999,438,280,30,615,82,496,781,159,144,352,572,640,346,560,132,333,377,839,950,906,755,900,195,148,178,523,775,793,292,770,379,995,605,137,315,419,714,367,367,776,293,890,112,634,755,973,912,350,456,402,151,867,107,364,946,433,637,805,32,246,671,87,943,279,834,618,13,47,353,262,619,126,929,550,66,87,353,886,525,262,173,601,634,776,949,744,147,562,59,760,452,343,466,845,176,145,376,347,108,654,111,610,969,684,116,101,290,234,409,206,275,867,778,949,786,499,202,202,514,224,453,793,666,152,773,766,646,379,969,581,957,417,968,272,432,925,396,254,945,581,385,89,87,504,76,358,200,717,518,898,612,959,857,265,731,88,173,673,285,2,432,564,811,430,479,461,811,184,760,689,349,370,92,411,695,711,7,863,728,890,937,545,595,406,830,817,962,110,645,234,56,706,771,416,622,412,503,950,31,823,352,703,679,280,936,507,438,450,734,775,603,276,705,270,259,270,208,607,144,492,521,32,182,926,618,109,198,508,554,239,405,626,476,238,265,413,777,986,883,485,324,927,910,15,486,729,861,631,747,823,422,0,505,724,179,433,363,689,917,555,581,234,385,915,673,810,787,125,427,288,865,728,23,856,139,90,6,842,197,331,44,687,437,478,643,467,41,207,743,472,58,871,560,398,557,688,821,470,617,511,564,164,998,59,685,111,731,92,401,454,180,731,921,554,223,583,328,128,456,82,92,271,755,113,33,608,729,325,83,544,80,167,259,716,566,431,427,983,528,192,115,363,84,784,433,682,317,98,368,132,508,813,569,103,379,231,146,29,489,576,355,809,423,481,984,234,570,22,305,405,750,801,204,499,836,879,36,419,536,185,892,339,84,83,554,319,627,658,828,78,960,400,401,48,314,404,823,720,736,336,441,493,108,579,109,217,327,550,186,172,552,935,683,929,6,498,384,760,670,627,903,166,706,772,351,593,910,164,906,812,385,363,447,10,121,937,658,427,260,466,546,304,312,856,789,153,690,349,908,406,919,726,4,49,754,294,623,969,621,113,940,220,34,387,280,769,3,91,178,207,413,779,2,340,668,807,897,787,217,269,361,84,778,873,669,592,435,265,481,392,172,784,556,57,516,818,924,194,163,411,634,639,319,397,239,906,869,138,15,559,675,391,31,267,270,656,166,225,874,122,788,687,715,809,649,981,187,931,85,64,613,566,74,187,911,739,872,797,107,320,589,176,894,360,321,474,701,388,409,523,84,332,370,808,680,136,149,177,91,917,804,433,106,701,738,833,961,398,598,109,211,467,987,456,740,229,405,885,150,190,788,956,612,971,611,774,60,489,173,431,712,182,656,739,647,578,574,669,885,676,130,792,309,996,130,441,684,366,874,271,25,665,528,47,525,212,20,298,622,897,907,420,578,20,482,675,549,635,69,815,515,149,710,402,63,632,872,903,85,5,865,684,827,59,617,36,685,748,614,657,908,490,998,103,463,358,178,638,326,438,931,685,322,477,134,586,651,782,46,79,753,673,481,33,160,516,46,945,287,726,987,258,442,827,982,137,120,97,211,410,551,13,267,120,420,171,245,419,427,852,655,501,792,473,771,729,336,288,231,254,356,675,284,19,922,945,453,533,905,591,826,901,172,409,563,692,981,245,182,367,850,122,79,324,382,887,391,162,937,546,102,431,608,71,135,256,862,225,207,173,622,900,338", "497,593,882,674,956,130,710,181,684,381,767,567,730,329,96,536,454,167,843,262,420,391,697,295,522,188,70,589,282,713,537,106,123,726,442,433,416,555,917,30,574,998,197,289,124,431,159,685,912,607,919,356,961,911,400,68,154,589,682,26,477,743,925,512,3,826,765,438,627,813,999,679,243,56,856,869,666,679,712,339,935,296,287,271,830,85,702,601,230,922,821,111,473,526,590,661,68,439,864,9,622,614,354,181,746,936,434,913,72,922,774,626,86,28,139,93,299,83,36,906,815,594,322,898,315,759,96,851,675,583,5,706,691,434,258,882,226,395,555,965,865,277,618,463,184,335,563,279,347,63,492,337,6,590,901,546,987,666,108,630,305,409,369,880,556,629,389,224,156,127,729,327,385,153,873,865,360,68,629,802,613,905,937,281,406,15,710,175,351,867,706,428,821,471,972,540,322,970,720,563,226,577,446,850,763,581,728,742,40,732,623,285,508,101,293,380,861,759,59,282,959,621,902,303,25,362,20,813,152,860,830,303,934,896,320,628,617,248,383,785,263,540,209,979,60,465,460,89,695,962,187,236,746,612,288,619,349,641,602,77,833,969,457,656,719,14,206,309,3,808,951,261,962,845,184,424,397,666,393,320,618,620,678,575,805,875,893,246,372,416,290,910,771,416,502,541,316,23,247,944,327,312,467,405,767,948,391,114,41,356,432,416,369,424,866,392,781,78,421,958,89,570,35,139,727,756,398,616,932,695,872,311,444,426,194,801,418,107,518,126,157,995,101,998,72,915,720,865,254,90,399,537,575,171,351,929,945,432,654,795,237,783,491,275,723,946,298,762,607,887,256,286,392,978,872,132,301,737,454,814,828,544,248,958,838,831,557,208,818,703,684,707,667,733,818,198,309,368,194,85,658,517,164,668,29,540,114,126,894,722,373,90,154,313,993,292,970,85,951,925,435,20,498,340,727,563,841,497,854,89,202,261,836,184,945,278,105,658,477,158,529,468,175,629,424,500,277,313,370,68,719,999,830,822,321,179,471,536,331,638,244,822,370,340,999,684,966,283,852,318,569,567,55,730,861,992,233,227,804,101,509,108,869,203,153,544,728,873,540,873,294,273,813,371,955,519,937,110,505,0,216,664,581,536,832,316,253,966,802,777,490,649,430,378,532,993,584,724,319,533,648,597,815,672,404,705,797,550,782,906,990,661,261,249,756,15,326,451,415,579,567,635,413,658,192,50,599,414,599,213,237,465,686,245,718,458,710,334,826,399,143,44,545,346,958,446,617,668,744,473,11,459,91,983,25,854,291,34,491,606,918,198,20,282,255,671,764,5,885,29,856,663,134,574,443,729,773,262,392,337,487,692,224,616,348,741,121,702,971,201,186,302,383,459,305,509,670,560,732,934,930,284,421,663,629,635,66,384,530,686,525,337,844,614,274,187,395,828,224,585,46,884,296,596,945,30,216,567,292,114,451,801,89,559,177,868,72,887,11,263,146,799,686,175,994,267,518,244,337,671,805,675,589,508,796,811,810,289,205,955,756,208,514,586,544,340,824,84,489,792,241,146,131,384,328,625,989,129,883,578,121,454,720,662,994,114,145,814,707,831,443,475,322,558,60,815,530,899,707,636,888,81,883,868,32,585,120,785,620,113,627,357,803,38,409,384,57,823,859,434,154,335,954,85,172,783,309,38,351,135,735,567,40,823,752,568,335,964,457,530,395,497,531,519,951,499,705,381,248,460,766,740,442,419,344,126,818,964,404,79,152,183,955,201,593,992,965,7,427,867,387,823,35,692,870,632,417,315,315,679,754,998,266,973,733,516,922,159,93,829,717,889,8,849,183,404,197,575,289,710,119,292,165,925,529,870,999,244,563,26,807,518,987,314,555,408,373,176,836,605,666,819,853,590,475,353,535,745,521,218,47,89,118,729,667,670,374,706,265,355,768,832,612,245,361,965,419,587,265,663,55,466,470,573,35,932,310,93,930,34,826,467,557,894,955,475,63,634,679,787,156,531,877,21,501,263,791,799,808,362,287,706,388,33,539,608,735,993,666,801,644,328,737,806,560,195,983,499,68,994,47,864,373,826,64,345,552,863,312,848,770,736,430,551,192,418,371,427,940,713,590,995,115,567,535,674,603,340,696,596,826,166,123,669,792,805,324,721,969,315,928,910,713,108,53,555,703,889,353,940,638,637,697,613,391,957,286,314,927,442,214,818,415,31,214,845,133,678,212,784,646,196,924,845,922,541,154,287,846,429", "782,29,934,275,215,215,408,38,803,276,15,396,542,414,573,839,365,718,650,931,334,233,149,632,364,964,124,143,497,603,997,833,640,368,608,242,56,973,229,500,207,347,407,202,978,258,820,668,47,152,943,651,743,572,122,79,991,832,469,335,293,305,286,182,528,354,376,115,541,463,666,782,631,751,864,724,159,411,64,953,648,467,27,192,181,671,826,742,798,285,125,300,317,462,460,686,554,689,583,899,829,1000,603,275,389,887,663,442,853,784,126,575,729,142,912,758,761,375,200,102,954,617,346,622,307,927,19,18,547,32,150,52,493,542,11,876,809,123,781,126,681,583,246,989,930,473,752,478,251,630,488,721,540,547,315,827,597,802,349,475,356,813,167,791,164,980,688,872,692,245,521,776,448,313,872,886,156,667,944,614,461,761,644,252,895,823,51,475,332,97,719,762,246,665,172,981,318,771,735,521,38,181,318,745,605,704,596,575,253,33,870,792,59,677,762,434,138,376,894,865,114,230,237,696,843,583,420,19,378,246,921,677,803,364,449,121,666,92,423,673,845,221,304,217,974,815,375,479,760,265,74,797,361,672,592,260,320,905,383,888,27,810,11,287,488,137,470,359,66,828,923,687,899,594,328,435,909,581,494,787,931,783,547,460,164,733,413,924,799,947,164,827,388,178,367,118,925,300,832,663,320,272,627,398,474,915,695,533,869,253,200,809,724,322,294,381,215,594,146,774,624,736,558,7,61,228,767,784,348,669,912,953,324,771,111,992,748,24,910,958,579,914,221,659,678,77,616,75,748,585,476,373,749,921,255,286,107,984,932,100,901,984,494,855,333,520,630,517,946,767,784,169,818,380,957,104,787,526,592,495,236,57,689,997,663,144,554,699,677,708,613,744,496,350,241,947,482,881,335,740,16,200,903,727,618,742,931,439,950,986,918,431,473,203,793,584,788,220,433,71,565,906,180,455,80,196,450,71,308,313,285,999,845,510,134,213,244,585,876,932,326,100,177,732,939,942,410,272,116,787,457,729,395,86,511,212,970,309,61,128,658,291,606,759,531,989,59,839,473,555,407,938,98,458,909,627,505,315,779,381,151,429,962,224,638,944,549,640,590,904,56,47,649,811,144,415,238,303,724,216,0,484,589,876,381,435,430,798,930,948,61,197,592,388,423,971,997,747,616,91,615,697,353,994,459,867,826,828,136,584,213,344,193,518,568,762,160,710,16,863,141,108,918,447,830,922,513,903,973,919,430,34,640,979,232,117,47,156,196,933,737,941,979,46,161,155,594,162,546,921,125,502,246,498,3,421,440,706,601,876,120,900,414,660,812,300,282,399,529,860,701,371,501,156,554,644,129,127,414,42,763,547,873,416,216,953,279,902,605,904,830,572,701,681,100,393,31,117,499,604,182,211,456,22,974,307,242,668,26,455,540,192,809,801,408,128,896,290,779,32,375,830,710,430,859,905,59,902,903,140,449,938,647,825,498,927,785,206,241,22,231,621,939,784,899,882,902,711,183,523,867,496,159,613,896,215,114,264,772,934,14,747,333,886,650,748,729,201,359,757,835,930,867,914,643,970,372,521,807,77,932,818,586,436,672,359,268,925,842,569,643,401,587,479,836,830,313,120,163,490,552,476,104,885,992,538,349,679,37,552,602,109,731,454,355,547,1,824,56,714,339,967,691,261,83,546,957,653,779,623,435,213,685,499,284,558,821,620,852,743,620,404,430,69,769,580,708,921,715,306,762,974,410,354,405,662,356,143,110,895,236,327,645,532,272,672,380,696,894,329,763,708,512,914,163,361,198,329,946,459,423,152,914,479,911,688,780,720,568,78,321,118,699,580,835,806,333,961,744,72,213,459,126,413,629,144,446,267,687,300,450,166,611,719,385,706,524,357,447,592,376,993,504,120,332,516,657,999,718,282,846,406,573,140,85,568,276,641,624,599,117,763,599,401,760,447,231,263,47,419,614,947,400,626,518,917,990,483,808,371,781,560,822,333,608,898,531,537,22,310,946,160,119,34,262,339,688,54,855,715,277,29,202,150,244,985,324,672,800,667,457,767,576,834,568,799,997,332,107,763,118,84,694,309,601,585,286,200,871,186,57,973,276,665,439,817,811,603,235,517,671,699,633,252,214,369,236,366,475,830,222,50,801,176,297,989,864,349,741,61,792,801,410,608,584,627,304,541,684,67,859,487,555,433,274,492,353,446,58,59,88,320,310,653,436,76,899,232,58,266,117,131,487,146,423,84,343,108,325,402", "182,787,471,791,265,210,205,460,738,995,366,949,569,959,82,180,105,890,896,344,883,157,965,263,977,296,715,306,357,37,917,276,486,828,80,693,719,990,236,781,133,573,577,519,553,669,472,974,759,472,728,530,890,272,956,715,731,277,569,570,264,439,134,272,157,616,122,259,435,555,903,883,964,189,882,231,721,418,277,18,667,105,856,459,867,685,394,798,758,516,715,688,999,522,698,105,908,299,383,433,348,746,624,692,593,600,539,408,123,415,815,152,519,476,524,612,931,186,534,384,236,85,566,594,230,507,575,429,568,622,343,295,374,642,32,939,361,345,119,395,656,192,346,669,630,904,44,290,595,764,869,353,176,798,17,945,752,398,966,5,505,487,87,11,185,498,811,408,280,952,348,926,798,292,394,950,736,421,100,994,486,380,649,494,379,846,991,136,781,566,677,336,633,678,280,489,416,215,806,855,106,798,224,979,859,74,264,938,890,99,903,848,978,40,176,644,950,495,827,915,419,218,412,636,806,672,475,13,458,439,473,913,381,352,862,93,815,361,58,610,921,853,431,980,733,127,151,932,213,747,421,62,274,205,323,11,658,429,714,303,979,7,541,943,585,815,687,764,453,666,479,435,836,545,817,597,434,30,413,383,737,307,836,446,90,648,232,387,256,12,3,337,99,310,922,387,371,271,736,499,926,713,733,954,134,13,170,96,671,235,496,462,247,924,124,215,648,331,818,411,382,27,447,371,700,577,669,834,744,522,852,396,981,81,566,125,141,755,990,178,483,248,371,872,331,201,76,31,817,70,279,19,126,733,588,444,926,549,844,698,947,412,237,532,300,541,570,305,676,538,185,542,910,480,545,267,566,729,134,317,404,734,447,792,413,39,779,119,256,110,398,850,847,500,72,740,354,10,470,606,927,208,18,90,732,201,916,362,528,303,704,831,343,524,541,642,548,869,837,408,30,729,686,766,913,137,294,436,821,833,162,860,486,588,327,910,28,584,25,787,522,675,166,570,552,531,392,242,758,292,508,496,609,593,36,512,780,75,269,700,387,447,628,826,630,398,221,122,492,739,369,80,377,937,752,797,795,193,720,444,46,656,582,934,49,626,634,83,467,21,448,585,679,467,507,859,616,491,179,664,484,0,448,302,672,978,468,106,219,261,887,234,927,363,143,139,603,355,633,2,169,724,14,751,257,387,755,659,70,536,519,383,913,292,16,569,947,493,189,748,276,61,565,467,857,893,395,919,675,861,664,494,689,808,577,439,429,823,547,306,240,992,834,752,695,548,630,560,426,35,903,424,68,15,578,15,37,865,645,371,699,27,754,65,731,495,641,190,343,454,322,495,575,698,768,632,451,606,964,650,178,73,114,232,187,220,123,265,328,855,553,393,742,33,563,241,10,708,724,530,487,497,701,718,278,151,709,660,240,633,332,272,876,229,968,868,866,618,21,188,474,857,863,750,848,441,1000,283,30,813,557,35,329,643,796,745,898,688,178,245,46,137,921,846,151,53,116,671,108,892,227,49,182,460,15,28,235,484,106,996,454,92,309,758,805,638,526,510,491,682,475,115,941,92,412,606,245,807,88,770,510,27,915,681,601,58,363,20,860,979,506,616,958,812,458,560,722,918,854,609,316,20,455,952,88,813,136,638,742,107,161,632,164,301,951,490,761,915,558,566,381,892,339,88,759,590,156,655,75,154,636,529,926,177,967,312,912,344,62,996,652,621,262,69,317,619,443,262,637,465,525,363,311,106,69,583,250,850,461,439,814,182,806,42,442,196,679,124,320,838,602,849,827,214,274,498,590,580,184,4,195,213,668,327,374,451,167,127,365,561,291,453,672,290,631,738,445,29,895,964,456,100,911,304,239,734,383,440,729,638,436,657,747,70,303,793,525,918,507,350,520,778,684,577,172,921,782,909,99,343,118,167,858,919,90,361,871,416,118,202,91,928,571,806,20,63,235,140,463,933,549,347,236,161,72,257,455,875,7,570,787,851,233,517,105,475,926,299,831,834,755,543,230,20,29,546,421,229,803,46,336,657,313,923,127,186,94,300,888,855,615,12,748,512,922,703,860,613,140,45,144,936,822,596,592,205,234,424,298,889,578,838,44,696,47,243,668,940,199,257,107,184,352,217,298,637,432,548,296,677,975,261,671,197,21,674,836,291,241,477,76,814,695,249,13,819,678,228,7,526,475,892,185,83,567,285,388,137,586,556,225,303,409,841,395,253,398,954,147,448,184,13,349,889,329,33,782,574,321,563", "463,687,397,723,533,312,74,713,861,86,975,529,286,801,493,677,605,116,722,805,200,336,751,770,108,598,535,733,173,764,716,145,369,944,3,131,990,639,149,137,504,56,919,356,679,708,2,877,296,691,38,56,697,3,171,665,653,535,587,985,428,593,997,787,245,365,167,88,957,712,791,577,404,15,443,770,271,188,749,559,766,675,310,857,695,225,475,691,213,557,924,4,466,7,854,146,530,225,265,576,792,873,885,34,185,451,688,565,373,339,785,644,678,913,898,180,359,258,31,811,200,105,216,188,783,148,829,950,260,684,234,248,716,816,645,789,278,882,568,379,453,519,289,825,84,625,63,537,157,895,503,998,728,542,824,239,380,145,353,11,784,617,553,609,222,571,462,120,420,779,989,417,406,321,697,481,724,815,340,432,333,340,298,175,641,893,113,247,73,150,959,184,951,99,996,815,340,929,319,249,120,852,771,200,841,548,128,859,554,301,317,904,187,161,772,593,98,33,456,776,686,204,550,898,920,469,767,27,17,177,27,315,902,896,657,465,389,454,946,603,406,333,626,598,279,178,927,2,370,388,963,435,303,868,670,276,754,86,418,323,646,704,909,658,10,135,497,850,396,558,159,741,159,236,462,192,908,674,919,846,3,189,980,454,963,879,84,137,8,752,218,895,140,631,941,80,586,74,591,953,159,416,928,560,891,998,222,411,779,745,387,50,126,742,905,850,306,870,416,624,52,682,359,447,147,533,982,447,252,822,359,40,16,238,502,623,605,594,747,131,409,260,762,806,407,618,106,150,704,41,14,510,648,415,362,109,911,592,864,556,691,83,922,440,129,334,631,119,172,244,576,202,562,374,630,100,797,864,38,851,412,225,978,850,906,485,366,904,860,254,591,676,906,247,862,607,743,602,602,71,940,925,945,936,114,93,737,114,852,938,898,892,385,938,968,345,949,826,379,892,359,134,170,636,866,455,743,356,635,60,839,225,597,438,709,150,76,721,372,899,301,681,493,557,351,714,296,460,948,784,951,705,901,946,218,321,367,567,12,261,873,277,339,729,782,38,331,522,924,590,102,975,273,24,491,626,537,287,105,327,39,935,820,356,996,167,502,142,467,287,451,529,1,992,121,190,157,104,433,581,589,448,0,941,758,202,38,492,206,350,432,990,800,46,97,418,327,45,759,304,640,734,63,712,456,426,740,676,662,806,987,546,422,490,770,409,868,137,161,279,760,134,360,889,996,449,703,745,636,362,571,809,360,429,452,426,381,207,792,631,856,115,685,174,589,565,747,322,558,491,468,74,947,808,410,280,674,639,121,562,350,587,947,736,299,847,509,152,655,681,444,562,197,23,259,951,343,633,332,524,949,416,150,308,271,568,304,600,302,724,361,857,514,674,252,10,406,57,610,523,467,4,794,245,398,537,70,710,244,414,309,444,215,207,134,554,643,450,11,107,942,665,978,594,841,588,841,829,446,245,838,874,388,563,214,532,386,261,816,20,888,761,885,882,723,347,390,1000,150,704,89,2,842,685,404,219,432,106,918,354,493,284,282,648,751,968,547,764,757,173,699,496,943,351,767,910,274,266,981,495,77,570,283,365,307,841,523,556,249,539,862,943,289,884,814,705,429,89,988,503,341,373,251,373,74,124,175,191,707,281,661,492,224,7,40,490,113,175,947,903,620,5,477,554,296,412,887,455,260,278,197,531,879,635,771,748,571,814,254,510,761,453,369,781,24,311,115,372,895,885,673,663,78,356,964,443,583,606,716,360,62,644,865,767,742,264,596,510,764,893,545,695,691,478,849,961,745,413,9,742,584,229,831,251,406,392,442,571,26,332,538,111,516,864,196,644,725,834,930,987,770,870,509,478,312,844,293,872,225,663,736,351,529,431,406,614,503,706,317,539,519,177,402,630,450,86,933,763,143,294,775,946,212,828,127,473,444,323,331,114,985,344,513,582,218,133,307,885,23,308,138,687,712,467,242,417,87,51,714,726,499,613,586,794,466,99,531,698,711,226,599,19,415,292,17,788,671,931,8,975,371,539,608,846,206,71,316,518,920,39,381,174,349,368,450,594,207,258,56,638,989,775,71,505,143,292,406,769,823,700,260,601,157,713,791,666,269,594,279,541,371,700,695,305,946,546,255,796,543,779,172,876,892,471,598,662,620,128,238,198,599,54,398,205,771,111,614,103,194,804,574,371,802,784,745,65,267,660,609,254,505,479,142,827,180,675,672,521,291,146,167,634,429,415,48,164,384,554,854,20", "557,878,92,360,307,635,150,75,263,969,497,181,795,128,323,462,96,664,22,778,478,778,439,148,337,924,95,419,548,913,684,251,684,256,919,938,101,185,413,973,76,121,865,974,66,679,18,904,208,793,639,373,62,292,834,183,928,661,221,702,438,21,111,90,766,662,328,539,384,649,647,660,373,244,926,298,894,123,189,756,754,228,166,149,123,509,851,784,885,410,968,646,607,363,351,798,511,433,448,367,247,878,63,240,660,380,785,61,652,146,329,348,891,243,93,831,553,544,643,380,298,592,538,430,48,706,283,26,171,155,613,872,757,303,471,652,473,629,258,842,75,259,404,795,615,287,325,944,640,839,791,186,993,258,331,878,936,284,485,599,7,222,5,683,472,760,171,953,149,289,512,912,538,975,805,514,888,625,225,800,80,850,529,31,711,269,29,978,438,66,211,145,395,944,109,631,758,180,798,380,420,369,925,253,101,944,956,494,866,636,739,98,55,69,848,588,328,255,214,772,372,769,993,454,148,788,224,583,959,868,287,273,349,145,703,469,240,516,101,708,349,950,950,333,97,506,889,154,953,745,960,994,322,861,465,713,285,921,785,799,229,16,972,96,680,368,447,619,428,286,254,195,36,182,788,228,326,241,197,173,828,484,743,487,193,876,119,416,346,256,628,545,303,195,845,492,181,559,856,453,269,298,511,734,504,162,207,983,898,335,143,774,36,992,700,39,635,218,985,281,572,491,441,308,87,411,262,213,20,234,653,254,539,957,987,62,621,292,655,456,892,646,430,235,5,615,320,510,23,417,956,791,456,886,953,298,100,267,353,653,3,702,353,527,825,96,590,58,348,179,106,719,295,470,571,184,830,345,605,745,821,574,258,881,959,85,600,873,354,491,536,153,849,927,598,398,221,33,19,250,756,392,40,935,975,418,3,534,457,101,357,851,481,235,180,517,805,561,314,11,242,36,258,845,463,440,562,684,667,65,426,480,75,486,69,768,780,945,950,547,605,950,97,458,454,761,136,442,28,38,678,820,116,277,938,472,9,666,62,98,614,134,896,71,291,782,838,577,371,302,617,905,557,32,585,354,918,64,444,510,977,77,201,954,66,579,312,774,371,656,650,59,615,245,277,398,702,320,363,536,876,302,941,0,314,400,799,831,24,745,317,699,992,233,419,28,758,673,604,412,642,527,75,683,215,172,603,609,948,551,373,323,273,364,910,23,75,549,547,176,246,172,121,659,737,548,996,167,16,896,404,483,680,753,423,988,994,580,183,618,260,946,70,414,302,315,877,578,734,883,605,517,816,570,627,654,813,797,896,556,553,999,326,76,20,844,706,439,833,946,711,292,874,304,509,622,534,887,70,826,933,426,670,525,409,583,382,121,81,822,163,649,858,244,101,605,668,887,142,90,376,944,471,402,466,887,238,850,772,236,514,881,809,586,804,752,546,933,982,384,493,821,673,636,186,444,388,245,386,358,789,480,258,813,732,919,45,764,17,4,764,982,988,102,702,210,152,370,72,986,343,395,346,948,278,388,944,240,431,130,745,51,348,724,22,576,88,294,97,468,848,22,592,156,858,466,919,623,212,620,111,978,231,19,500,214,495,716,541,814,703,987,465,498,135,727,104,900,494,524,861,826,769,956,656,600,605,250,28,400,901,888,344,774,22,534,27,771,627,235,459,107,369,179,177,263,569,410,490,472,503,841,111,134,446,916,270,929,325,632,105,985,467,859,630,582,134,428,530,352,721,676,470,865,199,746,341,815,164,320,349,607,68,17,947,776,815,987,41,303,709,56,753,334,210,860,399,404,309,903,100,776,934,674,707,57,938,835,597,325,901,412,109,105,310,98,798,262,728,615,361,219,116,238,471,424,210,393,765,64,803,82,573,256,77,247,88,743,902,10,432,550,192,790,612,650,715,917,874,152,195,612,593,596,905,671,511,288,806,438,603,730,397,133,256,648,840,18,492,831,29,643,595,613,732,705,123,434,909,41,242,76,62,201,116,311,987,737,636,989,31,290,739,218,285,260,416,394,188,365,447,168,347,434,265,340,472,924,634,687,4,310,946,871,434,168,846,232,677,229,125,117,688,121,823,33,366,317,998,183,684,891,920,464,276,325,410,198,998,59,856,545,775,698,671,747,407,505,304,965,212,501,772,195,109,960,117,858,935,474,196,967,996,281,680,501,663,551,467,387,947,167,214,124,297,77,140,134,167,909,28,254,947,605,292,849,2,779,492,43,968,526,571,432,311,945,531,709,458,413", "20,640,714,238,424,595,496,367,3,802,685,303,596,170,461,2,81,303,237,701,663,712,286,99,92,849,408,348,815,18,159,950,601,604,35,278,697,490,996,422,983,283,455,643,338,559,810,590,212,167,341,125,290,474,176,513,491,573,856,69,904,886,80,726,754,862,363,425,633,506,323,793,154,42,526,598,555,773,687,129,578,103,742,84,811,234,925,864,523,657,347,164,749,802,842,204,222,252,368,948,584,285,459,76,9,567,784,23,589,156,650,464,401,892,379,999,521,917,214,462,873,948,100,158,589,267,174,533,12,372,964,281,117,457,936,67,157,533,291,201,706,617,7,798,626,110,904,667,985,285,293,20,591,739,141,618,944,470,839,436,584,515,792,487,93,532,774,699,408,858,953,373,981,548,522,431,670,696,100,466,982,654,888,434,403,99,635,261,314,967,394,596,322,468,996,463,726,620,297,767,37,644,171,530,78,643,485,113,585,129,506,44,595,212,42,876,313,72,979,3,76,36,60,880,148,32,113,921,756,296,898,502,54,106,651,962,818,473,214,936,775,705,62,228,511,365,802,6,191,474,551,802,869,364,405,390,616,130,982,471,274,901,957,471,436,528,303,949,944,821,66,879,705,254,934,727,329,779,487,671,559,939,252,954,517,188,308,191,513,951,390,937,726,427,268,336,332,927,759,63,832,951,367,658,57,327,938,697,135,39,655,32,210,75,763,637,344,298,368,81,653,735,643,195,915,669,955,441,106,833,184,527,303,763,831,551,973,298,667,694,581,536,551,330,630,854,616,956,846,266,829,329,949,580,78,814,26,702,318,89,981,178,926,129,841,716,402,378,816,130,925,71,73,268,51,142,593,523,926,835,321,44,115,299,922,227,692,976,772,68,331,963,575,108,846,648,686,796,178,979,306,32,733,3,520,790,931,590,185,294,425,993,885,600,200,130,314,44,55,607,809,959,651,550,746,694,662,86,164,479,79,55,205,229,911,75,898,904,108,532,410,762,364,50,257,899,944,258,448,845,426,880,291,831,858,6,574,864,694,234,681,273,318,999,568,530,335,252,706,118,785,665,311,626,119,575,652,656,403,238,95,956,251,476,53,175,465,530,862,143,616,66,25,846,884,374,982,951,689,832,381,672,758,314,0,703,515,886,407,726,29,833,923,172,600,772,853,889,6,50,407,553,661,860,561,878,53,773,318,922,451,940,948,54,716,430,230,769,5,249,732,205,811,767,788,313,909,20,37,776,148,762,646,108,630,606,130,692,188,934,285,539,115,15,580,354,455,364,374,493,276,546,248,221,256,747,721,594,717,306,788,200,275,825,832,56,951,967,538,776,713,599,518,355,623,582,186,288,918,384,768,722,652,886,551,763,680,764,100,707,291,769,57,523,636,377,693,46,460,873,452,124,464,79,230,969,774,478,345,180,449,279,608,170,646,296,720,288,665,843,325,454,741,114,853,15,185,790,88,853,194,58,8,281,885,947,819,335,105,676,513,6,65,582,507,201,267,195,481,139,319,473,754,38,921,474,948,347,580,262,341,963,30,994,606,638,291,522,899,977,921,653,969,547,6,182,540,939,826,659,453,383,731,394,449,387,773,87,342,615,112,592,843,451,525,583,365,811,98,228,491,245,629,652,494,433,490,958,804,561,277,827,47,440,579,714,684,75,105,712,843,914,683,384,949,283,407,133,23,440,820,201,25,756,714,633,251,935,805,919,820,39,863,275,664,341,250,343,507,758,501,22,562,233,554,730,146,514,140,995,757,114,120,502,872,420,372,352,969,949,220,390,697,430,125,119,747,875,973,146,274,548,33,181,290,502,756,361,498,886,522,291,208,453,506,553,495,363,270,660,906,851,165,744,181,660,666,525,184,983,141,147,684,560,328,261,826,577,619,454,302,233,324,569,140,102,76,571,505,863,383,192,785,70,755,892,557,302,416,51,211,55,514,201,888,138,582,400,580,96,448,745,279,361,562,90,119,496,81,975,75,239,429,213,882,199,165,590,413,218,739,241,516,247,6,406,954,376,587,365,754,823,555,59,946,895,249,22,815,720,443,324,739,454,107,329,238,714,646,590,536,409,911,677,222,68,192,140,645,3,690,936,209,132,540,200,639,207,266,172,167,603,589,168,512,671,83,852,825,688,819,829,171,630,706,925,916,349,348,732,704,378,970,9,729,666,928,923,526,606,144,615,275,461,997,947,712,954,778,350,787,325,439,462,596,603,836,2,383,459,35,863,212,260,61,338,912,990,747,257", "849,11,569,270,501,79,805,249,893,410,160,627,11,390,942,494,746,521,768,373,469,450,223,702,80,303,578,39,778,698,748,884,394,438,161,511,699,990,42,338,851,795,185,253,463,336,762,979,414,994,104,673,834,990,119,671,244,625,527,854,16,702,759,891,326,488,863,868,74,467,984,798,888,173,343,367,571,333,276,832,985,972,591,524,497,474,142,3,459,867,829,935,475,791,970,762,295,120,65,303,281,270,445,459,568,951,482,397,525,755,989,510,147,488,28,636,429,119,352,215,198,723,835,159,844,790,214,295,72,699,819,426,614,280,264,104,201,204,597,698,641,442,342,615,44,66,915,466,630,142,219,639,897,259,771,764,624,29,174,293,327,718,541,303,88,898,182,611,694,994,566,754,785,996,334,866,709,62,811,783,262,880,329,507,741,355,334,506,311,711,671,631,650,329,831,403,109,66,49,271,508,888,380,924,697,791,317,26,950,13,669,595,80,101,764,451,206,53,873,655,466,255,595,76,33,138,892,392,760,224,758,99,819,971,282,880,275,606,306,238,849,305,348,248,986,978,555,690,447,701,645,391,579,777,306,607,601,561,15,904,733,896,926,343,112,862,613,416,152,875,779,554,217,625,850,286,421,821,140,392,11,541,8,813,397,535,145,749,197,491,592,288,931,81,734,904,513,264,462,401,719,258,310,943,385,695,913,54,277,214,835,563,325,988,994,203,771,285,999,268,399,550,219,319,783,859,574,1,39,126,907,870,416,504,870,213,909,484,78,716,424,33,862,331,933,212,394,265,904,756,325,917,848,244,31,566,242,916,63,971,146,550,487,894,701,41,163,686,383,414,912,275,870,714,767,229,158,311,591,749,600,884,211,905,821,558,760,825,155,385,449,436,163,13,707,7,160,295,285,517,975,816,589,676,641,726,327,419,165,627,376,392,49,205,12,896,253,603,584,17,175,453,812,803,211,601,408,923,962,700,656,279,893,204,831,807,487,848,964,827,585,915,358,780,737,461,136,884,635,367,92,801,927,113,287,617,307,537,716,540,987,131,731,91,537,862,713,879,212,469,928,605,111,568,165,208,636,384,599,132,74,881,815,239,179,390,656,603,407,923,6,743,946,654,450,738,827,442,917,316,435,978,202,400,703,0,687,976,967,484,894,2,264,813,843,89,291,591,127,499,490,564,376,668,871,835,720,467,64,619,342,886,365,422,588,518,25,124,625,784,724,989,974,573,99,487,787,617,427,357,477,465,120,759,81,251,651,412,156,738,599,509,836,623,459,721,449,871,546,371,606,141,704,204,17,268,351,906,436,826,651,739,290,609,237,247,212,289,397,158,306,785,851,915,705,116,751,507,103,862,745,408,865,156,951,496,506,985,479,353,548,86,178,374,716,954,598,954,610,680,958,404,47,309,267,318,571,919,916,852,373,948,433,946,63,765,121,543,545,53,8,147,240,672,442,251,323,816,921,67,934,305,472,207,217,54,381,71,702,390,263,737,165,575,958,305,560,884,599,267,44,621,707,335,143,261,927,176,192,761,100,189,2,974,297,488,30,757,634,900,883,250,475,994,609,85,584,476,190,663,746,36,912,25,820,661,489,909,755,108,78,821,48,113,163,286,692,931,877,329,474,445,150,377,876,207,505,782,520,478,238,324,85,742,322,303,419,977,189,580,967,797,745,331,639,700,370,384,784,636,425,6,145,777,816,609,23,797,914,646,328,855,755,232,602,562,875,813,40,226,450,706,574,850,234,803,552,251,630,139,179,427,617,894,92,401,302,203,363,161,448,29,403,561,65,149,14,377,506,972,83,793,310,969,323,62,838,966,475,986,77,656,742,144,427,738,720,97,76,896,153,679,238,185,566,473,292,540,39,522,994,68,667,394,200,797,130,704,666,823,645,158,362,440,440,695,676,263,83,60,159,912,611,325,51,523,54,600,392,488,725,306,33,257,746,122,968,770,663,355,437,589,883,532,377,62,879,801,547,230,893,146,984,676,411,290,387,458,537,657,357,50,319,353,544,235,319,31,243,727,260,55,821,148,721,620,126,774,536,624,726,969,406,975,465,542,696,118,538,541,422,693,302,629,821,68,858,540,213,127,568,77,486,952,590,622,606,394,243,96,211,995,934,341,798,324,723,294,919,224,535,462,38,660,513,883,73,102,981,973,26,829,429,818,955,858,607,716,76,353,87,777,937,286,992,741,476,832,603,728,433,475,432,557,371,688,167,859,284,477,420,664,896,371,786,71,525,61,649,214", "685,883,886,588,166,226,363,36,121,411,766,738,713,227,589,456,828,848,34,377,426,229,125,681,819,846,985,635,657,282,176,156,636,552,375,661,248,886,468,36,819,212,864,989,321,384,624,478,739,352,597,499,821,769,682,307,247,170,379,395,260,820,819,637,747,241,351,77,250,115,166,282,570,934,366,488,689,33,744,830,143,652,537,348,850,301,800,850,511,233,505,763,522,615,493,84,5,706,861,585,235,408,57,158,268,840,569,207,876,810,824,967,989,902,68,781,677,220,554,455,587,948,118,140,294,189,297,712,967,42,528,174,723,580,125,269,877,866,79,595,708,424,458,637,349,930,898,432,804,161,859,51,318,115,507,80,941,132,765,46,57,339,517,634,666,432,657,661,838,303,151,318,692,192,802,552,297,232,633,220,464,309,512,191,500,613,492,777,72,510,668,480,259,532,805,974,876,258,778,996,984,805,71,223,556,61,959,130,745,863,365,932,569,86,688,893,835,480,815,722,513,149,681,979,817,995,286,218,947,513,161,585,134,61,647,115,125,577,159,354,584,994,867,547,848,288,917,912,836,694,282,917,877,891,183,995,576,40,282,460,391,406,183,581,364,247,713,771,801,54,429,677,238,964,848,742,804,666,159,64,749,880,889,487,262,152,548,361,743,568,952,768,322,688,736,78,474,566,288,272,564,58,674,994,212,536,729,238,375,297,957,576,404,918,45,282,405,987,434,690,985,135,452,57,795,144,334,70,769,813,3,399,120,672,347,82,370,568,320,696,891,764,357,705,415,119,596,64,669,88,661,914,106,697,996,496,247,31,378,708,871,778,763,296,680,543,116,156,716,362,236,191,384,24,959,407,100,449,857,685,374,205,499,331,646,684,916,640,740,262,292,99,724,807,498,254,37,225,391,260,143,851,842,162,827,876,46,536,764,95,67,937,773,371,756,835,733,532,162,177,630,179,11,359,368,926,685,465,681,868,929,518,895,750,791,866,503,876,410,383,283,42,758,95,835,811,5,545,880,811,678,896,897,807,440,780,705,551,651,362,951,405,74,967,172,919,226,596,518,759,604,374,84,338,857,821,301,296,207,727,552,709,404,763,441,130,531,474,526,89,391,98,173,817,516,662,537,961,555,253,430,468,38,799,515,687,0,272,742,752,953,434,539,690,733,187,63,342,875,876,716,263,589,396,428,866,83,904,663,922,37,583,150,449,622,449,8,137,288,634,950,497,25,677,533,465,231,44,676,511,337,550,269,907,883,464,193,526,415,15,583,948,935,3,766,619,882,444,424,355,123,737,556,873,481,353,585,208,958,34,707,995,437,982,543,719,818,635,168,968,441,695,477,9,934,939,238,103,373,129,612,751,255,521,132,455,142,317,947,84,662,369,514,905,615,518,994,764,390,911,961,181,141,254,263,148,668,11,536,995,425,57,953,352,222,976,927,328,841,974,107,284,510,314,633,899,701,629,276,230,311,330,685,982,331,434,584,774,526,430,179,612,120,891,43,633,747,59,901,610,167,520,867,747,169,840,712,827,408,748,472,48,152,973,681,692,20,460,313,688,77,303,978,922,93,775,37,788,283,429,368,94,871,158,566,965,921,616,517,478,161,401,384,712,368,487,934,816,72,53,829,161,393,571,912,422,29,748,110,307,233,701,240,51,285,716,794,624,860,846,718,556,82,881,389,576,787,549,248,935,461,35,732,625,372,752,271,138,378,970,842,237,635,288,134,101,583,364,144,519,855,451,16,289,647,116,66,886,421,818,973,596,330,815,730,188,275,112,292,706,935,346,505,758,200,574,424,234,671,304,683,878,525,213,566,945,670,404,293,7,756,570,89,755,183,132,822,39,432,123,866,288,720,288,379,444,601,455,660,31,629,225,925,39,107,833,391,131,486,580,906,881,377,93,617,238,27,684,794,70,704,451,999,522,739,8,626,939,711,715,475,932,759,935,771,108,624,328,281,92,24,858,906,724,123,948,478,45,373,453,569,637,68,65,256,696,849,991,654,299,145,24,683,510,586,545,17,444,856,300,110,892,88,515,268,12,72,596,394,324,431,897,129,579,526,950,815,290,199,368,748,473,35,606,551,909,90,453,14,992,989,450,740,893,431,671,984,317,73,482,251,735,902,972,880,408,997,221,590,225,300,173,224,247,62,714,508,896,529,674,482,329,595,52,396,717,49,856,539,385,958,30,392,138,904,227,954,342,785,985,225,801,95,203,604,703,135,283,727,401,55,49,486,861,756,702,55,392,542,274", "956,827,133,401,501,990,333,64,402,77,906,486,601,191,453,835,962,809,401,837,838,728,669,995,639,943,557,824,720,10,151,25,807,296,253,246,45,377,610,406,904,25,747,422,494,487,731,469,835,575,696,737,390,183,552,923,974,24,905,709,600,764,218,875,907,895,502,636,258,70,311,480,872,446,849,280,451,508,446,555,578,473,486,775,915,316,75,219,985,839,581,583,186,477,647,409,272,439,76,92,595,51,96,951,934,302,679,971,433,338,321,620,738,972,831,519,40,939,807,945,750,643,167,681,592,618,662,527,935,150,376,201,481,593,55,498,631,952,306,337,621,736,459,39,436,58,481,528,675,900,895,446,7,910,792,751,854,222,298,629,208,506,779,709,32,465,850,105,386,552,701,401,842,513,422,552,149,156,125,549,458,972,861,139,716,149,217,757,517,796,510,947,427,840,747,83,725,551,876,654,877,575,626,439,134,799,257,367,232,969,740,839,116,676,403,110,218,725,781,787,434,26,225,330,837,881,173,533,774,364,493,748,339,40,269,153,271,713,52,517,710,684,550,14,621,280,18,989,783,4,715,996,446,489,58,802,14,965,275,146,906,79,251,104,220,598,990,951,284,757,263,421,765,416,526,869,162,671,464,830,569,647,328,905,499,439,501,49,280,280,539,506,121,787,856,789,684,539,891,753,839,60,205,415,629,468,389,187,979,323,522,525,897,2,124,984,141,394,128,221,425,253,682,215,295,750,502,599,3,681,693,343,861,61,824,931,955,629,603,58,379,427,557,599,729,883,696,216,584,915,443,807,190,259,265,870,982,908,318,436,120,330,15,148,461,62,208,739,190,256,704,176,865,845,799,685,873,113,945,106,687,171,349,969,566,609,587,276,849,549,76,151,625,86,350,83,604,816,195,827,943,174,193,79,786,469,509,820,112,511,788,631,529,648,539,679,862,751,701,799,448,128,338,523,478,838,966,189,84,958,923,870,399,49,79,161,899,16,276,527,442,647,934,901,304,146,501,824,494,802,525,209,515,661,444,987,478,553,417,193,667,355,861,28,331,104,431,680,72,454,969,690,316,465,321,276,815,515,412,305,834,605,179,24,461,537,57,100,670,244,524,589,833,789,370,388,36,498,581,966,798,106,492,831,886,976,272,0,68,408,565,311,29,364,697,890,50,692,215,115,856,194,574,331,693,818,226,948,634,813,681,249,134,141,878,473,228,857,370,340,946,363,19,740,850,645,251,714,68,57,614,327,520,823,7,250,348,549,915,272,283,569,879,575,403,520,430,613,682,327,9,550,421,800,558,93,322,139,525,116,220,883,623,474,100,429,392,916,652,641,664,613,850,106,499,527,981,628,355,678,294,904,916,889,128,682,905,64,983,383,115,790,28,783,693,378,891,697,470,409,693,588,995,62,215,129,815,940,954,308,365,273,640,55,747,71,180,788,329,501,986,130,471,251,168,585,72,124,405,370,208,158,865,742,684,230,434,767,891,293,606,182,888,145,594,3,266,166,260,73,531,257,29,668,733,112,976,35,294,264,445,292,27,347,718,909,218,568,242,644,470,885,294,43,456,979,312,233,319,815,564,286,66,380,871,806,459,4,190,691,375,552,498,829,186,206,419,275,716,487,115,607,681,892,551,401,505,121,793,524,776,329,658,938,469,933,110,183,146,929,633,603,879,14,521,258,862,192,424,463,675,642,38,62,650,438,165,923,112,924,218,817,83,51,49,140,165,588,510,387,45,224,815,774,829,355,475,304,984,607,289,774,177,13,319,228,523,133,810,25,857,53,132,820,116,569,670,529,743,565,885,836,468,479,609,923,628,368,664,683,927,297,523,474,730,274,892,975,189,742,222,259,860,826,390,239,541,142,938,779,195,685,294,734,12,587,175,421,791,759,897,972,898,612,926,567,968,378,172,714,687,674,200,581,462,334,396,862,208,142,568,586,111,346,645,95,312,981,585,119,764,259,272,414,365,529,31,701,789,981,243,569,338,587,620,789,908,356,763,815,315,284,201,990,426,666,299,577,249,651,654,141,734,851,16,620,762,585,325,691,790,642,137,877,701,541,839,867,802,330,864,362,187,191,162,693,773,912,851,681,137,787,469,38,621,55,82,227,194,241,878,800,673,347,542,50,474,514,644,489,903,533,855,411,789,444,720,866,571,893,814,74,954,512,305,759,469,92,222,298,255,676,62,220,425,454,472,517,536,283,384,276,387,142,715,831,361,874,456,102,898,490,139,415,362,193,903,388,672,151", "834,723,47,704,87,395,577,734,932,203,475,281,402,157,269,454,63,334,475,362,928,922,870,343,455,845,689,383,956,557,496,798,633,302,510,642,681,228,665,597,221,581,434,141,190,400,287,255,713,693,338,985,122,854,508,20,884,917,998,202,944,806,857,959,35,857,801,415,442,460,34,438,782,67,699,473,742,676,734,330,876,290,792,754,275,171,324,767,665,859,129,372,560,352,447,951,208,316,967,126,117,221,615,461,67,616,16,596,633,403,928,317,861,422,175,32,883,268,930,666,11,13,303,952,540,307,712,559,788,795,584,952,619,879,351,915,60,395,62,597,271,184,476,879,527,865,163,571,934,775,129,641,918,304,524,546,235,272,833,47,676,62,726,69,406,646,179,152,893,173,727,887,676,123,419,729,21,177,4,933,671,965,629,633,422,682,141,750,3,675,282,450,741,947,655,24,455,771,588,538,475,398,41,742,931,734,801,585,398,387,939,462,375,704,9,610,549,238,854,338,16,262,121,403,236,499,134,606,429,217,587,855,100,223,80,670,771,214,252,608,22,815,737,565,422,879,673,599,181,492,372,27,282,733,368,490,676,251,54,146,316,133,285,395,834,249,519,535,906,471,828,689,906,683,483,11,631,896,596,314,990,903,455,85,975,117,985,667,846,917,256,417,6,404,265,981,175,655,324,893,812,291,790,197,925,907,431,479,410,590,84,641,309,284,941,115,189,336,658,370,63,668,548,978,831,440,256,970,255,716,475,721,722,349,313,773,292,313,3,422,367,219,723,766,68,704,664,607,237,422,747,160,332,17,944,813,76,538,858,90,378,911,453,98,636,166,165,701,638,124,216,860,896,243,415,116,972,261,642,897,469,459,139,970,79,585,733,847,244,82,112,846,912,618,223,88,466,304,649,447,971,131,324,517,66,618,673,511,839,240,365,314,541,209,427,640,713,998,872,148,478,464,842,140,494,111,967,123,350,836,497,38,481,424,152,427,75,675,567,42,602,139,60,98,625,776,248,66,901,480,119,756,929,439,523,729,781,598,305,564,982,139,31,669,609,89,720,210,950,37,58,301,763,78,505,740,259,239,613,956,151,884,580,210,175,515,858,117,423,326,456,698,6,774,834,954,103,417,234,802,930,219,206,24,407,967,742,68,0,269,602,270,504,720,796,156,458,851,336,522,435,361,605,128,145,303,461,922,478,650,384,539,547,461,633,409,798,217,430,834,41,495,865,468,323,200,113,899,545,286,410,574,15,709,144,214,495,585,28,850,948,64,64,180,136,111,400,204,105,259,103,799,914,126,159,129,51,199,62,394,355,262,89,581,725,765,842,554,437,925,815,510,988,714,785,208,161,731,135,851,56,596,464,912,509,759,437,220,464,272,826,408,912,100,384,843,855,370,848,711,521,684,505,375,616,778,353,464,45,77,594,182,340,806,280,826,952,815,122,181,845,119,218,983,456,376,379,310,821,266,783,571,122,922,33,907,843,270,770,184,927,976,8,769,200,690,167,335,411,194,174,675,40,656,843,430,631,423,13,256,362,943,526,603,474,506,869,999,810,292,12,147,125,371,333,409,609,85,673,146,717,591,906,723,328,646,399,180,482,991,300,359,142,992,20,717,594,107,372,373,323,695,190,495,741,830,704,67,581,64,343,616,895,573,889,400,506,118,150,171,164,154,969,314,355,550,738,819,956,466,635,342,80,842,610,330,183,597,554,323,196,447,936,547,922,606,46,118,776,800,611,722,389,951,338,57,859,505,491,565,362,592,9,227,346,449,78,626,882,385,162,142,461,955,170,344,932,746,535,99,50,50,860,515,809,100,167,218,923,299,480,687,711,729,441,45,590,300,597,865,588,250,902,514,734,957,898,761,628,161,578,577,736,173,444,325,21,438,930,248,970,672,829,986,866,331,542,548,351,154,59,633,203,561,176,193,343,676,879,104,910,405,567,58,67,116,568,470,450,943,858,704,275,30,726,482,841,526,367,675,194,57,345,183,444,446,938,435,465,383,720,775,523,258,793,580,582,297,785,494,892,816,893,845,449,228,163,441,948,652,901,523,509,736,294,617,358,144,264,554,466,730,196,297,938,896,377,929,665,500,350,789,660,489,651,921,548,971,275,770,894,855,915,988,500,736,626,717,419,311,259,657,612,448,195,509,60,96,1,489,421,764,788,120,722,985,839,811,181,13,445,873,5,871,454,48,721,475,531,953,558,900,651,310,436,238,499,603,887,160,464,482,486,625,813,501,24,702,977,256", "676,884,370,258,268,307,154,534,644,991,725,897,589,208,158,190,61,87,511,468,57,360,674,66,413,701,219,234,57,932,90,302,189,690,732,527,575,255,188,48,728,678,923,621,209,510,293,635,23,153,686,394,148,123,913,16,790,139,971,841,452,469,805,388,624,436,627,91,901,907,961,771,729,82,564,398,456,435,851,896,190,266,400,661,794,756,45,326,427,638,290,914,383,641,770,773,597,356,247,91,615,111,580,495,207,999,419,301,39,622,983,403,174,927,718,401,427,833,476,511,973,313,657,948,954,644,957,138,528,556,387,703,823,771,44,824,376,265,718,378,484,49,618,977,89,760,76,436,900,226,145,747,524,280,577,667,303,161,35,913,675,756,427,145,620,696,782,505,683,839,505,615,662,633,547,662,220,126,952,25,707,166,370,56,800,175,610,738,499,165,27,885,838,262,197,798,834,347,745,379,977,523,772,905,914,179,86,954,520,499,883,699,280,584,540,352,928,12,632,285,649,319,984,201,199,732,277,379,720,784,4,10,263,463,740,999,145,851,883,962,876,845,759,865,451,922,366,602,474,590,790,679,862,532,120,702,848,197,764,407,993,304,945,236,2,923,127,496,413,738,58,60,38,464,218,662,306,749,864,805,929,243,954,27,15,895,627,796,592,361,311,33,677,372,674,442,676,276,588,390,116,181,906,498,186,542,559,824,42,474,776,464,690,819,41,221,440,860,837,902,169,178,687,318,123,583,572,995,340,467,122,387,680,221,784,401,275,583,491,754,980,256,508,227,287,305,341,506,760,817,852,811,673,313,330,976,864,497,947,969,451,294,294,928,831,5,756,708,755,65,654,984,838,511,24,461,391,452,476,962,769,912,366,487,241,913,113,144,565,854,74,355,831,281,393,44,958,590,739,188,586,971,172,932,996,416,275,824,473,784,501,571,784,700,630,565,46,233,306,740,510,760,476,448,869,105,463,780,520,638,403,654,534,57,973,817,329,768,405,273,567,665,129,845,930,470,895,526,324,728,42,504,988,729,904,399,48,438,264,930,746,808,613,198,281,702,131,876,536,267,26,671,862,130,124,236,690,322,838,841,5,809,400,447,905,16,670,112,554,84,124,514,186,815,693,544,953,326,385,777,948,261,350,745,726,484,752,408,269,0,481,242,134,219,871,278,87,484,251,607,826,268,82,654,355,487,380,912,216,743,160,887,391,114,693,447,510,698,910,532,178,678,626,506,99,751,645,991,432,414,159,728,188,212,961,323,395,704,558,113,53,625,709,450,368,487,117,175,729,25,675,790,928,769,462,495,829,215,995,337,206,794,392,623,220,454,305,367,522,257,827,624,744,697,538,806,131,585,995,702,334,596,678,366,109,433,455,627,55,170,390,148,884,50,940,943,441,550,606,206,273,22,275,465,475,810,390,643,394,844,66,518,848,792,820,55,362,11,390,603,35,351,45,125,465,174,163,452,153,462,944,658,563,923,732,825,193,528,886,65,228,110,9,6,706,19,742,453,328,190,17,680,878,596,865,561,529,802,723,957,976,602,686,593,864,95,141,848,413,154,443,200,254,321,640,986,643,593,331,849,389,433,904,960,83,362,721,738,536,844,941,630,906,460,580,914,769,994,432,370,459,340,367,822,925,170,629,945,777,708,699,854,247,288,690,544,686,962,935,48,87,777,623,444,194,252,414,39,220,198,809,603,542,397,225,23,920,549,100,724,235,140,262,938,968,406,342,489,637,165,442,405,771,669,264,183,378,378,921,478,670,330,741,114,284,244,597,625,602,458,417,278,189,613,101,161,857,586,349,983,234,594,658,56,146,575,555,636,364,29,201,733,129,108,216,843,987,902,104,188,111,968,983,543,272,866,958,35,76,462,694,939,328,928,246,403,942,117,664,408,819,229,560,144,335,1,615,213,349,58,145,946,436,914,246,354,261,980,555,407,79,567,649,741,198,672,844,940,203,632,201,579,195,800,143,784,221,812,976,817,912,747,77,457,811,98,335,397,736,64,890,106,322,942,797,154,336,823,393,292,547,356,721,591,391,868,51,723,242,55,801,346,414,615,950,310,189,811,234,445,435,223,194,402,993,956,69,547,566,304,398,946,751,973,178,285,985,550,921,175,55,113,227,735,457,246,341,675,769,511,822,606,28,935,104,582,939,272,685,170,544,193,812,502,631,738,732,72,418,190,120,836,660,294,733,372,61,354,940,272,325,812,784,797,628,435,636,730,939,818,165,489,657,446,779,545,158,990,266,226", "28,670,801,575,363,630,471,8,444,625,906,858,23,708,463,697,342,579,519,704,460,584,711,125,218,542,977,450,526,44,700,432,813,570,489,296,314,489,238,61,187,179,155,362,841,910,642,552,407,526,474,65,540,537,615,655,407,592,71,260,330,993,196,691,841,268,100,714,726,667,274,971,828,630,381,576,702,410,611,382,546,232,607,204,306,942,686,568,88,735,177,143,442,816,798,901,690,128,219,700,107,27,743,781,468,18,953,40,639,667,623,301,468,529,47,548,895,560,762,662,209,362,670,953,566,604,904,636,755,206,444,137,280,323,799,704,777,889,102,951,761,260,336,538,336,46,653,119,781,28,79,425,657,667,524,820,97,219,547,796,133,211,564,687,121,343,64,93,186,76,417,26,94,986,337,771,138,178,746,29,412,748,181,367,619,840,841,264,548,318,406,30,517,24,273,150,664,941,247,286,774,310,670,703,416,499,36,362,607,293,261,807,352,137,85,219,559,569,169,983,937,351,588,298,346,601,413,28,457,149,638,716,909,45,779,359,412,650,253,800,583,371,222,719,190,445,915,577,640,102,601,969,184,239,472,371,710,377,518,230,104,895,84,30,112,94,211,946,224,458,965,128,593,634,204,517,712,288,812,983,583,933,341,355,267,781,638,134,942,100,705,908,644,690,132,835,579,299,254,318,462,918,370,498,600,923,703,76,155,18,892,250,22,564,462,511,538,914,632,306,185,988,887,165,208,587,890,71,616,514,597,989,182,737,26,206,867,346,375,749,905,208,24,453,883,122,643,910,143,1000,529,234,625,784,721,546,679,747,280,98,137,529,197,555,269,640,893,887,383,342,484,798,636,447,732,592,471,123,888,127,99,287,742,197,909,971,737,782,389,431,262,579,226,332,410,921,428,215,612,579,561,47,94,505,515,312,99,773,502,507,359,471,674,291,420,827,848,714,541,219,675,967,79,346,672,946,44,526,883,165,553,79,548,546,608,293,691,357,61,145,198,232,849,974,599,551,549,434,465,219,426,770,630,219,737,538,447,213,334,142,662,253,411,715,835,772,97,858,531,531,472,260,729,991,362,340,832,881,737,211,327,667,774,952,988,734,107,486,736,127,473,125,175,269,856,424,527,399,915,490,61,887,432,317,29,894,953,565,602,481,0,937,294,871,547,228,784,998,421,639,760,589,68,401,27,674,28,779,242,160,936,1000,581,964,670,57,450,104,57,367,239,963,49,971,97,749,255,823,367,602,513,559,683,133,158,664,810,654,720,893,257,511,890,507,312,96,727,983,989,912,362,838,432,16,224,259,537,692,157,423,416,59,115,481,916,239,64,632,16,615,685,133,453,953,280,917,449,682,475,536,788,982,422,369,400,830,768,571,470,24,640,493,427,590,909,536,892,456,801,616,42,143,456,707,858,285,647,613,219,594,907,348,188,219,50,856,426,822,860,228,865,362,810,169,252,328,267,40,606,881,583,218,406,309,73,945,705,845,464,805,738,964,755,137,336,905,808,466,957,654,618,332,121,520,910,45,727,286,557,226,919,756,781,652,384,958,828,96,474,216,156,614,405,543,861,417,71,992,612,433,780,527,555,253,682,314,792,199,76,795,939,411,291,586,160,98,82,227,865,494,317,152,272,158,452,390,801,724,784,962,962,382,351,390,279,856,72,859,753,550,564,40,56,665,2,186,833,986,712,800,510,699,14,607,375,810,443,370,492,374,854,27,225,846,399,850,131,774,713,295,942,972,198,192,489,970,22,892,235,481,376,703,615,558,534,819,313,146,232,306,251,725,652,285,292,348,611,414,123,329,186,766,284,456,327,775,40,586,353,668,251,478,5,367,675,942,869,66,948,787,659,848,458,184,790,993,902,989,767,996,473,671,695,785,695,653,832,382,193,926,749,488,951,422,833,114,612,897,296,248,183,113,971,26,591,671,653,794,122,997,970,430,631,259,74,828,517,839,953,526,140,958,428,674,523,33,805,573,612,904,351,865,507,178,1,849,342,486,796,778,542,602,640,372,254,865,748,596,296,659,651,430,761,843,898,978,649,971,33,327,333,691,175,452,452,817,942,260,514,75,652,26,423,759,714,230,470,142,820,430,89,553,600,295,302,510,333,660,587,186,485,991,779,573,603,327,625,499,619,581,404,298,189,51,895,201,224,990,462,741,248,688,592,818,544,349,446,891,395,953,325,674,282,533,102,69,461,354,433,246,487,104,554,445,250,490,59,589,213,789,487,283,780,87,114,201,8,19,748,297", "533,129,455,407,134,279,906,291,352,843,948,566,810,670,987,473,837,245,644,59,408,107,976,131,132,670,765,382,264,763,437,640,588,927,298,886,405,42,395,925,297,858,642,707,413,700,366,525,73,444,232,287,217,549,3,213,294,908,909,606,68,584,644,318,188,813,779,58,891,311,8,569,33,501,999,510,730,612,709,118,941,554,970,730,151,51,819,784,972,492,852,939,443,120,253,394,792,529,668,461,553,11,487,380,895,433,501,791,690,476,756,640,959,134,351,72,912,800,725,254,553,656,975,159,163,788,936,768,724,935,56,95,269,439,250,390,355,99,334,554,470,355,699,687,273,992,728,68,770,134,990,819,768,652,898,732,518,599,360,978,504,729,874,898,573,661,818,430,509,560,787,799,365,506,621,641,431,716,643,204,779,883,774,257,207,479,213,247,672,685,375,931,595,353,376,376,555,79,83,62,196,464,946,268,420,913,409,78,309,638,514,827,283,326,623,842,394,884,238,565,359,690,624,807,967,529,920,66,642,713,799,63,695,377,658,211,562,407,667,874,681,18,715,391,807,515,94,33,142,445,859,37,962,359,565,368,9,650,652,440,798,258,701,689,342,239,120,518,433,709,256,546,160,826,960,322,865,16,852,946,581,729,735,714,595,799,432,68,150,921,749,849,902,520,172,554,697,711,984,229,459,161,347,884,277,612,618,9,970,747,724,516,836,218,878,969,155,53,64,614,273,974,391,859,981,47,782,851,643,64,670,539,953,610,630,509,905,930,596,342,485,301,798,68,90,716,299,40,595,429,849,978,293,414,353,486,377,474,716,386,342,94,550,84,39,684,422,143,925,22,296,747,770,690,132,239,310,767,949,303,672,136,151,494,531,689,123,247,473,91,8,556,301,418,183,698,542,37,453,131,990,371,210,575,59,276,998,307,99,63,95,173,316,374,836,892,758,792,673,113,50,598,480,165,92,532,932,707,791,393,876,292,742,4,622,765,554,865,63,262,287,264,853,77,816,21,57,805,283,999,227,626,449,989,419,560,760,641,687,354,890,733,101,199,553,449,650,833,24,572,207,653,886,413,545,25,268,768,807,778,439,244,157,721,501,121,658,16,199,55,963,882,948,721,237,860,953,255,673,649,197,234,990,699,833,2,434,311,270,242,937,0,995,176,681,577,43,983,117,832,629,252,582,880,619,994,331,909,879,893,729,721,993,591,326,852,501,698,164,898,938,853,284,694,566,460,412,393,317,8,290,822,636,826,526,888,565,229,80,795,297,696,969,184,340,112,171,564,976,543,357,202,716,858,645,428,339,443,974,154,832,237,952,761,158,829,13,97,762,640,268,913,249,555,125,555,130,229,566,359,929,515,341,649,250,495,265,68,27,540,846,598,844,537,578,276,57,399,945,107,886,722,486,925,892,312,668,863,283,911,522,787,265,352,569,942,155,840,814,365,488,380,759,240,431,517,30,865,67,16,268,438,116,785,342,33,56,448,967,922,308,841,782,338,217,69,57,321,316,721,48,365,308,489,856,826,742,300,705,82,12,106,932,650,539,509,512,352,298,2,10,71,189,430,340,595,845,101,762,443,778,565,319,343,319,460,419,606,766,524,625,571,474,892,405,267,989,818,428,942,407,14,284,2,12,37,279,194,607,679,186,609,20,142,296,557,933,602,99,703,640,673,149,266,702,477,407,911,850,755,64,65,939,458,681,72,108,144,785,24,555,169,467,791,949,884,996,184,183,802,529,256,690,935,682,91,591,223,691,94,592,556,906,135,146,246,49,262,216,107,969,124,147,731,806,24,323,125,876,33,46,26,998,235,467,628,411,339,461,223,729,264,424,225,380,285,434,977,699,300,147,761,442,844,923,434,319,239,232,347,581,330,657,40,974,635,327,522,79,540,528,692,160,384,475,616,150,896,601,330,722,735,666,130,33,405,707,909,602,966,259,712,549,312,895,547,611,973,718,236,352,920,288,515,960,852,456,839,663,985,59,601,194,604,985,706,371,115,679,14,470,66,291,268,197,219,320,976,389,787,569,700,763,1000,842,737,610,69,312,844,489,924,224,276,792,741,549,778,340,840,486,473,959,555,396,428,933,64,675,936,228,234,781,516,647,232,638,107,573,125,573,347,771,807,922,371,767,221,887,173,363,536,974,336,598,171,876,634,424,438,477,816,760,58,380,118,728,87,750,925,964,837,944,400,217,928,728,596,693,57,83,238,486,315,859,583,937,667,244,360,177,863,142,24,621,473,769,551,924,293", "256,831,849,823,415,938,921,254,652,538,145,569,440,742,353,499,586,2,443,136,403,425,507,263,13,765,189,684,925,326,723,914,842,586,120,414,478,709,152,839,979,362,153,940,269,704,485,221,529,954,439,417,655,913,955,851,750,855,803,442,645,124,442,541,345,55,498,822,325,338,552,983,294,665,628,117,743,173,696,630,578,909,45,881,267,829,999,718,751,851,440,616,325,397,790,345,628,573,355,698,315,657,970,585,36,150,725,206,814,76,721,23,283,188,489,517,142,131,130,730,848,107,805,640,190,3,338,508,274,317,593,810,809,695,788,971,352,797,208,746,384,652,675,603,524,620,962,987,874,909,272,574,772,22,461,964,133,296,162,161,81,941,5,839,355,578,257,69,484,702,526,193,494,67,968,821,11,10,75,462,67,347,244,398,411,231,425,373,285,225,387,668,40,992,896,945,227,752,189,492,856,420,917,420,195,960,430,594,977,883,720,280,928,740,95,323,449,112,58,933,332,166,706,479,244,442,197,510,779,386,741,187,613,883,813,733,634,120,908,685,952,622,88,223,61,476,326,283,852,524,783,169,154,241,475,87,720,192,743,267,487,99,113,261,935,667,864,967,845,616,42,333,105,505,492,173,625,191,753,62,761,544,854,642,997,855,556,533,75,263,990,682,421,640,401,666,735,552,513,952,582,871,334,958,9,742,883,101,756,206,307,477,849,473,373,137,185,707,968,147,890,664,412,284,423,919,632,152,828,730,627,143,81,344,356,381,173,768,270,114,679,989,431,170,963,518,236,513,758,569,423,401,26,305,575,442,969,323,563,123,411,235,747,445,648,73,674,359,992,623,739,118,888,84,585,345,124,476,376,436,352,836,343,367,268,103,894,666,841,331,74,838,797,829,921,508,210,461,707,507,380,104,866,312,424,778,309,984,118,930,382,403,705,196,739,325,494,965,931,952,491,973,49,914,53,417,678,370,711,368,22,810,733,222,617,891,241,540,40,406,764,643,674,567,120,600,724,995,176,376,80,199,253,86,678,517,440,476,237,329,939,252,827,707,65,347,476,271,608,630,761,496,748,281,629,511,316,42,438,205,383,53,235,579,385,308,318,563,586,968,348,130,735,860,676,530,192,792,810,430,592,927,800,992,923,264,539,29,504,134,294,995,0,767,572,993,931,420,17,439,709,538,586,284,529,540,828,716,866,792,535,863,475,257,122,268,576,14,813,539,595,709,524,78,895,879,915,264,174,314,361,724,426,416,71,60,225,489,857,962,284,217,665,46,617,62,943,259,669,836,378,589,929,185,723,950,292,449,707,910,478,956,786,553,8,772,387,978,779,761,144,670,325,212,800,644,828,756,874,66,18,64,586,106,546,730,883,45,267,107,694,490,231,614,905,381,649,282,312,983,823,583,566,492,377,751,65,865,797,313,430,197,713,445,178,691,962,669,399,328,788,605,764,10,666,61,668,221,788,990,158,735,102,494,837,898,649,120,776,220,998,488,40,910,273,202,673,656,659,793,506,647,336,470,831,681,221,291,810,152,497,118,336,697,668,682,330,34,979,562,790,869,448,810,216,652,730,918,517,397,337,340,352,921,764,296,615,867,664,802,172,149,731,448,375,466,261,14,248,793,806,156,540,806,487,276,540,228,904,472,474,645,342,79,886,796,922,225,562,168,968,632,441,637,750,690,973,591,386,261,524,375,274,43,764,607,215,62,760,347,598,532,698,962,147,679,13,207,594,578,291,183,987,9,95,253,131,639,166,39,309,464,692,755,505,581,826,856,867,770,261,299,810,453,199,151,929,761,729,234,694,368,102,533,978,276,894,955,191,673,199,740,356,853,881,865,824,715,646,307,702,230,408,942,650,902,532,436,110,363,793,131,792,542,912,351,256,913,928,395,668,434,131,959,761,844,530,291,834,248,883,634,646,830,985,521,458,499,97,984,221,990,731,454,21,459,448,874,456,833,237,702,742,602,213,865,533,593,913,404,214,343,642,936,130,794,521,695,745,617,192,403,780,304,604,388,130,346,760,548,915,871,399,12,551,876,756,194,340,307,683,664,985,49,494,372,458,784,27,166,353,287,774,868,379,819,172,34,551,845,266,664,419,850,658,132,677,505,254,297,817,422,555,81,614,89,955,183,798,700,237,447,223,189,405,885,358,691,803,99,311,354,483,137,454,105,733,410,779,606,198,314,211,837,906,324,861,836,761,908,989,212,507,232,76,959,163,575,506,514,559,744,890,488,28,893,158,51,752,920", "904,500,326,406,175,203,504,471,525,103,128,834,126,219,581,987,807,243,803,190,748,45,32,228,178,545,480,309,647,892,272,458,580,202,885,44,365,648,61,641,662,168,614,356,769,346,718,963,101,287,790,814,462,97,124,193,488,152,527,290,180,294,55,191,251,751,939,440,155,37,214,112,368,848,188,417,229,504,125,907,274,877,488,464,100,715,742,856,279,583,388,880,571,55,719,281,326,263,371,114,193,171,528,879,141,292,7,22,597,201,122,614,203,446,75,486,254,503,886,801,565,35,540,244,416,518,345,642,677,879,216,694,840,664,546,172,448,803,709,88,896,627,605,62,697,942,539,107,422,485,892,228,176,730,544,828,646,772,781,751,743,603,987,209,256,979,763,950,636,77,515,782,508,560,448,811,911,474,800,384,81,616,514,940,602,64,29,961,992,874,931,147,714,837,737,146,688,846,585,825,916,349,387,981,29,529,641,921,772,360,417,539,679,830,937,812,536,495,664,211,760,569,112,114,160,889,337,117,993,231,364,448,697,332,930,447,688,916,762,526,779,404,376,34,674,622,690,605,382,924,566,747,997,47,903,825,493,407,341,414,543,611,141,67,670,848,856,817,784,816,863,684,722,139,107,548,915,979,102,563,247,286,176,720,665,444,957,503,491,430,151,158,431,745,743,832,122,786,174,455,372,64,439,952,792,705,641,902,707,758,661,796,149,40,333,527,174,194,589,298,37,796,12,866,26,645,74,623,142,947,637,642,895,647,70,956,116,990,37,308,528,719,422,920,751,35,86,867,734,810,626,211,995,309,349,680,666,792,346,928,446,972,156,509,499,61,166,301,158,680,546,328,844,770,715,717,552,338,205,214,725,857,141,23,941,661,977,535,870,283,726,421,172,658,178,519,666,365,285,431,511,802,46,809,617,261,575,807,848,262,196,584,319,901,757,666,697,891,282,230,975,269,902,188,724,804,61,672,524,215,296,3,480,891,281,217,277,141,550,184,996,747,315,829,196,128,957,267,735,978,942,445,582,171,339,45,615,918,151,102,133,198,369,355,821,930,15,555,832,43,151,504,789,910,391,281,905,740,74,361,839,938,187,268,823,683,339,890,337,299,686,686,360,71,241,393,248,442,787,378,388,363,46,233,172,813,690,364,720,219,871,176,767,0,207,610,547,836,702,954,90,892,123,667,408,138,496,222,911,14,981,370,955,196,280,623,257,627,476,153,24,892,546,173,823,371,265,715,99,251,758,812,167,443,53,425,467,503,711,130,928,841,224,819,741,360,710,492,584,228,579,613,732,367,703,535,271,835,135,156,771,530,829,956,588,878,425,574,5,668,373,847,378,407,82,469,851,461,318,181,177,587,684,131,159,30,799,29,10,826,286,14,74,350,870,619,70,95,107,754,472,105,783,715,972,193,77,970,629,286,898,198,989,393,871,535,268,58,594,826,736,876,311,37,248,915,990,558,689,34,396,954,266,437,362,936,124,428,111,615,110,150,57,974,230,845,183,155,343,431,936,743,739,707,479,880,889,531,816,66,739,904,483,401,624,392,442,926,978,133,401,812,202,334,231,362,527,242,271,89,271,635,395,181,815,484,908,51,851,319,648,933,714,434,472,831,570,121,143,292,70,691,811,632,264,813,683,881,742,807,164,163,51,376,663,494,863,413,943,276,26,572,648,180,649,584,4,723,438,241,774,572,270,83,449,533,527,291,330,510,327,540,825,784,811,533,747,885,819,121,211,974,387,226,601,667,506,924,44,506,857,697,295,459,631,524,514,997,667,632,30,857,570,344,898,891,746,212,98,978,529,663,707,532,550,700,169,52,513,190,337,911,290,179,242,108,626,748,879,259,865,568,86,104,372,144,616,206,178,614,88,465,169,892,133,54,237,71,776,111,350,997,129,73,194,135,850,405,300,246,922,742,420,228,768,928,359,579,496,26,113,925,226,894,446,848,93,990,182,287,422,294,905,193,224,475,210,21,259,276,274,734,762,465,491,842,921,87,354,761,332,286,786,36,749,48,12,232,380,846,112,511,781,982,560,454,99,654,317,507,673,723,211,566,589,107,711,325,501,81,218,995,189,266,656,811,783,861,442,285,627,539,790,735,991,766,337,51,943,826,266,821,292,500,115,655,596,583,690,790,947,123,472,695,307,72,329,656,286,751,70,79,110,374,773,351,694,601,688,704,147,753,871,53,922,412,785,168,961,537,14,864,700,479,153,30,224,944,914,978,838,68,644,528,727,809,560,623,701,272", "606,422,32,50,483,728,752,879,215,736,281,860,430,755,448,704,190,306,359,843,715,243,339,148,815,716,811,622,612,557,943,172,332,28,481,649,291,267,97,108,460,504,316,929,158,686,836,45,852,358,658,928,187,763,281,724,989,481,721,536,151,408,877,888,911,89,590,889,300,153,952,498,286,860,165,289,64,560,494,28,604,136,178,800,827,940,948,213,786,103,140,390,89,846,608,746,480,361,987,994,920,906,690,62,502,197,220,813,19,991,470,199,370,186,362,80,717,855,123,950,609,58,104,808,860,149,238,760,49,935,660,739,241,656,943,3,352,128,323,23,586,856,898,407,584,252,769,844,787,503,624,801,626,785,738,529,706,951,895,63,476,296,674,139,125,665,831,832,840,202,453,253,695,865,396,206,623,664,378,396,361,547,886,35,823,59,556,34,759,263,832,229,731,987,885,514,920,9,12,966,616,577,247,226,928,961,812,426,577,969,384,342,824,208,333,537,112,820,42,584,259,938,413,127,924,863,268,227,877,82,350,808,494,424,806,421,283,723,874,270,526,461,69,812,485,945,282,806,770,193,100,828,949,75,126,90,222,842,512,700,807,245,887,469,23,826,775,452,937,818,289,110,665,274,915,600,114,905,763,957,150,173,937,124,406,71,87,235,63,855,927,947,797,994,913,939,759,806,203,189,80,760,67,718,563,294,341,920,656,335,704,477,901,772,226,503,585,426,959,936,410,538,968,524,550,53,301,987,297,419,906,214,962,495,847,866,266,786,363,559,804,822,89,413,828,757,46,181,524,147,813,292,158,542,86,60,307,257,555,631,684,289,829,518,196,302,777,1000,630,951,675,984,225,494,65,43,889,560,867,40,256,9,183,248,863,89,442,444,112,809,931,562,87,559,295,932,680,354,105,642,386,225,330,78,693,410,973,381,349,756,175,322,38,741,60,991,927,277,349,726,559,821,312,625,280,650,507,312,184,652,731,806,95,298,571,941,986,207,176,543,623,209,225,742,853,201,920,946,887,115,800,524,508,661,126,481,914,53,797,846,780,505,832,673,760,887,335,135,541,432,513,1000,340,5,613,332,947,691,531,869,86,598,409,47,47,478,667,976,705,285,216,536,952,733,730,553,237,824,125,532,423,143,97,419,600,843,733,697,796,871,547,681,572,207,0,333,392,947,883,662,738,790,663,556,119,217,310,295,91,119,962,307,89,752,311,334,222,687,929,650,237,999,559,529,539,660,502,218,693,148,144,121,238,427,437,441,505,229,935,70,295,871,441,304,344,807,682,280,746,915,669,262,107,870,327,965,440,57,709,550,359,885,528,166,852,450,494,234,154,468,843,874,414,12,895,178,301,526,993,225,708,381,679,800,206,99,630,611,878,505,189,466,100,768,854,168,698,230,975,555,283,531,733,252,82,443,587,821,799,889,14,662,934,230,593,332,572,92,982,272,755,940,696,812,105,27,518,482,868,916,202,346,444,155,344,773,34,894,819,204,567,259,852,826,727,919,888,196,133,583,858,424,783,988,672,433,650,147,456,974,288,13,85,18,611,233,479,629,769,682,351,515,342,132,626,163,198,178,682,118,666,195,92,875,991,793,588,819,935,410,895,133,899,328,286,780,854,615,211,963,50,558,550,11,168,393,626,641,388,339,821,79,246,168,146,208,145,69,885,503,708,210,171,564,206,744,191,836,466,582,78,149,243,232,852,902,961,574,320,885,265,51,947,797,388,251,15,383,843,118,872,101,525,686,692,21,479,69,657,880,183,75,779,373,862,666,765,95,569,904,708,85,360,304,424,528,87,684,602,179,784,493,148,652,551,264,651,448,69,689,498,800,189,353,53,979,899,891,814,626,744,974,865,875,668,788,304,287,244,488,522,974,305,973,756,162,705,930,980,941,834,286,295,928,174,87,845,772,367,720,244,318,699,273,883,929,785,215,913,763,692,573,336,812,598,6,270,631,165,917,332,981,876,874,953,96,793,552,599,31,340,74,199,674,603,620,514,562,721,701,232,557,500,13,139,616,633,896,858,110,741,124,678,161,248,985,200,369,911,179,389,430,429,718,803,17,18,49,6,394,351,312,96,348,125,83,303,807,738,646,617,396,292,657,480,577,584,489,52,116,810,310,830,21,260,436,581,832,370,867,420,801,172,435,312,41,922,677,266,120,421,443,41,447,223,995,578,60,159,179,587,946,911,1,144,960,63,994,611,707,312,650,325,831,179,275,973,12,211,435,663,799,557,747,384,918,595,953,69,366", "334,196,329,451,103,848,302,91,90,200,19,576,20,156,850,618,765,466,783,623,545,254,68,299,739,807,682,671,882,42,188,671,117,798,831,562,969,39,608,198,86,503,925,499,50,953,135,915,655,206,458,334,911,496,273,305,524,615,952,589,93,59,386,23,901,415,486,600,187,985,834,729,764,794,88,865,843,952,528,486,505,584,808,714,519,53,250,280,277,182,440,488,438,374,171,835,853,337,504,11,363,940,729,507,796,22,132,786,348,774,671,759,147,400,704,188,562,998,517,86,858,975,422,490,181,799,450,60,859,640,890,127,115,103,115,713,114,576,860,103,391,128,799,147,50,530,510,307,550,192,466,889,123,134,804,214,695,401,3,15,983,560,135,534,318,194,884,677,580,188,325,553,449,832,514,479,662,889,802,460,481,60,605,169,814,764,591,798,859,744,594,796,499,464,410,112,82,616,590,583,897,732,330,18,530,861,521,166,870,760,143,761,664,784,590,321,271,332,805,806,482,297,839,74,114,748,259,688,440,480,154,123,653,346,729,347,925,63,507,239,178,956,664,203,108,695,717,276,408,358,640,513,57,236,960,455,171,118,218,379,279,283,375,694,223,223,642,767,332,966,21,646,339,816,240,484,735,632,54,886,787,787,347,712,723,78,140,642,51,782,127,755,431,256,237,583,25,414,210,887,297,647,718,580,399,211,365,346,667,678,545,581,266,941,524,240,846,244,6,193,765,492,567,551,921,448,760,876,268,812,848,99,381,442,23,849,698,542,884,840,650,84,155,365,72,229,945,4,474,590,85,620,989,965,655,924,592,148,862,868,523,123,503,927,937,674,392,215,93,177,614,984,993,593,883,382,30,658,958,94,168,969,226,562,772,162,389,41,570,951,186,400,718,121,935,512,779,587,818,742,705,918,991,859,690,441,162,186,50,90,439,41,489,122,909,698,27,479,735,498,527,26,266,970,702,270,754,309,526,434,682,599,487,656,58,988,111,396,425,931,718,290,796,791,71,840,88,179,236,881,827,471,866,349,161,318,364,815,502,196,392,346,530,381,536,539,454,687,572,94,251,486,133,303,726,221,519,715,333,684,971,89,719,387,150,482,269,444,408,304,592,364,507,902,903,87,104,291,427,993,971,139,418,28,772,89,187,890,156,278,228,577,993,610,333,0,459,523,824,431,168,46,883,294,577,518,344,201,401,941,910,653,866,77,748,188,541,557,795,305,107,828,409,229,155,232,693,710,618,634,240,638,236,894,87,274,234,706,633,426,84,320,44,875,624,181,130,265,61,97,839,587,39,396,995,173,635,268,836,412,738,119,240,270,104,51,198,931,424,181,95,837,230,777,881,671,664,850,67,922,769,718,861,452,810,296,729,585,44,292,78,863,899,415,945,911,340,645,731,798,388,694,284,8,618,973,278,529,841,359,289,714,224,399,470,305,997,159,917,704,703,974,544,734,955,224,712,735,373,962,510,358,286,797,838,542,504,486,325,555,489,833,661,465,16,236,877,7,357,956,804,728,177,312,440,725,713,870,634,273,610,617,471,693,496,109,382,886,268,405,834,509,366,56,500,578,590,438,851,250,414,656,276,825,538,556,986,403,925,389,157,136,962,394,72,26,683,533,937,467,203,54,221,47,208,381,841,910,135,839,46,144,584,507,560,947,528,450,143,249,820,144,491,772,16,747,475,434,62,992,595,167,179,601,203,781,810,416,972,59,480,45,128,588,605,100,312,104,387,329,946,149,920,448,253,337,69,733,143,746,632,580,579,530,198,286,700,686,704,202,519,159,44,412,892,551,136,818,403,296,754,443,209,504,595,273,6,109,588,551,485,205,420,364,721,178,549,977,516,871,952,398,31,519,178,963,592,981,890,80,539,639,134,461,538,543,86,993,403,895,774,449,783,387,769,222,271,317,2,860,657,254,242,854,175,771,561,678,981,146,609,109,237,135,214,758,618,237,184,91,871,675,94,337,490,152,206,54,897,449,580,673,647,3,835,277,515,937,331,751,516,970,838,867,235,673,407,834,50,835,334,292,66,742,467,870,289,837,914,325,253,494,62,385,794,719,158,93,471,139,251,523,137,809,721,519,66,741,7,127,562,409,651,578,335,308,757,81,986,104,499,236,201,564,433,535,148,326,931,999,796,774,733,370,797,474,276,986,211,238,510,219,591,344,877,597,525,729,759,927,584,619,368,653,576,726,912,321,865,368,213,106,671,406,341,760,107,526,119,747,145,538,444,278,670,600,948,990,693,627", "472,936,750,566,983,258,415,435,757,601,434,244,858,252,215,420,575,455,698,580,504,905,753,239,375,434,579,68,470,863,670,459,169,346,283,614,748,706,945,271,693,127,266,193,825,944,584,476,786,204,9,505,980,236,895,195,240,773,239,310,115,290,329,602,799,446,185,917,456,505,50,712,89,476,568,94,842,19,789,247,785,914,149,818,78,289,180,167,55,604,738,401,137,426,327,287,268,484,871,760,232,104,158,988,287,733,589,246,262,886,715,215,874,285,594,140,185,273,913,155,210,87,893,673,969,358,583,194,516,188,845,845,52,617,405,853,390,460,796,564,44,856,576,254,130,800,257,17,210,568,892,888,79,922,143,622,39,102,206,874,944,757,580,87,610,190,555,515,811,81,788,839,640,723,572,650,233,595,715,338,286,980,828,953,960,856,660,294,116,148,512,393,547,871,150,251,194,567,540,108,14,896,781,154,167,982,780,609,594,699,378,449,348,293,604,123,944,473,776,474,506,477,932,907,638,760,102,579,528,178,766,643,436,573,105,521,863,137,645,165,856,355,979,515,415,632,96,786,323,657,936,49,530,272,761,523,892,825,748,952,17,778,855,529,975,407,758,745,551,490,599,997,549,745,697,725,444,65,858,331,394,356,433,449,911,637,461,40,139,497,542,506,72,157,53,561,785,284,65,536,893,501,50,56,932,672,947,425,919,233,511,184,355,778,919,190,470,12,397,572,207,996,878,171,804,171,111,536,602,821,842,353,225,256,264,268,112,317,237,621,863,449,974,599,718,842,474,109,111,450,804,576,59,340,400,532,66,268,504,513,327,214,158,980,820,779,867,379,510,195,391,836,479,550,452,90,856,150,389,992,653,941,818,105,653,410,993,410,129,917,941,797,875,119,133,637,392,796,868,102,390,545,793,668,658,137,310,426,864,39,802,388,841,795,86,94,199,545,451,947,552,37,791,171,816,130,299,297,382,893,836,295,41,631,124,20,563,451,505,497,512,712,66,228,915,532,74,674,245,529,492,200,912,481,755,21,553,997,430,658,426,859,656,70,753,816,553,823,742,383,139,618,979,513,261,17,194,600,566,285,856,857,638,231,955,526,841,188,633,34,901,320,247,508,264,708,447,179,288,584,997,603,327,758,853,291,63,50,458,87,784,43,931,547,392,459,0,508,452,920,989,977,328,51,613,476,517,681,773,289,3,999,282,928,118,588,803,202,657,792,595,972,23,779,729,539,210,542,703,834,207,288,230,909,438,859,761,344,219,672,491,368,787,495,166,15,627,637,488,465,18,156,804,322,25,617,317,488,556,211,393,523,35,431,65,992,635,199,481,169,987,425,349,222,421,135,869,236,869,916,92,196,641,489,141,157,838,563,502,334,799,972,683,416,162,267,865,582,659,898,525,3,999,188,94,237,914,963,554,909,460,69,223,449,65,872,251,597,506,411,373,323,418,492,831,283,158,660,671,646,711,560,516,97,978,317,181,44,13,164,475,986,248,340,484,405,652,91,414,574,249,186,450,756,453,92,464,114,710,879,7,346,134,613,574,941,573,263,935,971,776,410,760,50,608,393,872,461,183,747,308,163,572,966,738,232,821,303,856,678,267,106,584,323,618,244,161,362,727,633,879,420,451,119,665,957,508,548,942,967,832,405,888,252,405,473,14,565,200,228,208,780,883,595,223,936,267,179,969,938,167,136,541,743,216,838,190,738,840,108,418,221,989,574,695,701,498,514,545,791,567,747,360,159,761,649,902,295,215,243,275,205,418,999,134,122,267,282,594,63,882,296,189,129,502,528,829,764,916,603,212,498,587,226,128,256,156,104,864,601,408,14,55,150,607,437,277,180,135,894,784,372,756,475,668,156,822,701,393,416,413,345,775,954,492,790,33,818,904,949,518,873,584,811,385,851,943,530,564,973,545,512,492,945,847,764,671,609,559,77,876,950,976,294,586,899,125,950,205,783,625,329,89,266,123,668,512,72,349,613,910,507,970,29,819,873,794,56,274,9,47,800,770,965,113,6,333,255,380,795,547,634,296,94,44,612,347,111,572,86,525,647,606,557,605,584,104,276,104,675,706,977,357,112,467,504,903,370,493,677,369,458,186,627,561,146,115,77,584,8,165,900,63,903,622,585,443,358,976,438,561,179,839,39,200,790,767,688,618,673,568,455,605,924,168,995,646,882,304,449,282,291,759,206,536,248,561,389,706,77,482,232,995,591,596,310,228,334,756,987,124,696,855,953,561,952,992,430,535,587", "206,719,458,20,327,574,329,325,863,453,451,613,964,403,832,879,97,116,824,747,928,322,938,303,222,707,611,859,248,136,239,682,773,962,78,652,374,265,291,578,114,643,626,751,458,617,154,326,49,151,561,811,510,939,647,139,442,582,70,494,811,267,770,624,618,579,407,634,893,985,216,40,151,574,698,385,881,700,682,364,269,264,241,458,138,924,382,639,461,417,354,158,533,747,421,245,786,450,813,171,815,882,844,28,515,435,4,926,413,267,151,886,777,756,11,487,994,48,73,906,823,872,844,506,588,855,647,912,611,44,605,995,162,752,989,183,235,736,439,715,580,670,214,408,842,354,10,598,537,895,686,145,295,709,376,846,799,854,505,194,142,605,665,674,505,199,132,891,458,656,756,991,718,240,409,136,562,432,537,751,650,760,694,399,579,773,710,534,88,986,511,642,306,465,973,629,836,903,368,813,952,168,446,767,693,397,714,433,946,117,876,746,724,408,521,708,879,375,89,457,945,294,415,880,696,89,287,179,568,792,97,505,317,296,428,866,87,943,738,616,362,662,262,619,269,98,871,390,983,883,590,519,328,300,335,915,385,226,39,905,690,796,715,627,93,381,982,482,451,355,468,71,790,87,792,465,716,978,114,324,921,62,221,985,363,590,383,812,833,910,345,985,173,97,259,977,485,787,641,623,293,292,688,812,548,523,773,239,776,388,650,852,819,996,506,441,270,887,185,305,731,540,886,428,92,572,193,70,241,10,823,7,887,439,178,275,347,621,297,114,941,736,585,26,257,231,175,973,360,961,738,41,347,651,587,988,356,590,206,291,641,138,485,165,53,235,592,735,588,911,212,578,518,535,481,247,396,455,703,224,376,789,458,61,243,205,249,503,537,611,67,527,59,302,747,626,487,604,29,516,196,840,440,647,294,854,122,877,536,435,249,132,429,858,129,767,348,82,355,619,543,424,348,416,56,719,854,368,212,850,706,185,889,346,602,650,670,113,401,894,708,112,72,149,774,132,363,450,314,91,193,902,469,492,365,612,780,512,400,376,835,205,840,364,427,482,251,511,748,136,763,927,541,159,225,366,956,522,192,962,64,401,615,79,393,716,689,929,550,662,178,771,18,207,755,111,480,549,865,724,747,355,45,673,889,591,342,692,851,484,998,983,420,836,947,523,508,0,421,953,495,566,535,433,459,33,669,108,501,144,220,470,345,608,67,996,958,526,109,47,787,787,316,373,232,323,463,916,998,275,923,509,532,87,653,513,94,664,304,844,832,767,673,897,104,425,496,516,392,948,366,293,264,799,716,691,756,579,564,433,724,545,491,364,308,309,593,936,802,631,636,805,8,287,708,374,658,351,480,413,14,829,439,341,570,736,183,756,925,863,34,332,690,482,529,645,60,320,955,291,421,790,789,426,852,583,633,526,887,388,509,531,746,494,962,590,795,178,744,364,131,759,306,373,832,911,977,690,456,588,313,789,638,180,967,574,575,669,380,28,663,864,932,315,184,146,677,425,501,793,200,263,751,487,249,634,930,471,651,180,763,337,544,762,406,420,201,507,303,935,781,783,427,183,791,902,590,205,129,16,71,897,50,353,246,639,964,60,872,77,563,831,980,629,65,884,88,218,448,147,803,368,627,649,654,351,294,491,579,655,614,864,538,406,27,499,604,757,549,501,362,689,180,56,203,623,796,949,310,667,903,619,24,344,341,856,215,613,555,293,370,943,103,975,448,641,434,339,625,954,226,11,134,795,827,338,558,511,473,266,75,18,498,168,238,757,864,464,182,245,46,9,959,323,476,408,458,205,591,82,378,102,715,648,587,892,235,902,895,183,811,62,581,557,928,382,563,395,703,256,329,724,883,258,894,228,453,581,513,575,69,155,860,105,24,547,416,742,666,496,945,137,177,211,120,764,328,675,35,82,844,40,417,266,128,393,180,161,211,833,115,705,95,35,241,243,441,262,686,178,252,708,356,5,252,801,174,968,459,85,716,733,630,414,452,804,529,106,834,54,964,830,401,410,351,446,539,5,918,543,81,723,803,894,495,928,760,262,712,483,681,333,138,459,468,569,871,347,519,93,195,283,941,146,186,313,727,973,665,923,121,93,84,284,834,906,107,860,710,654,982,635,820,10,473,419,891,203,364,911,901,957,485,14,35,525,458,346,897,97,538,621,598,898,175,104,267,787,76,614,421,13,343,655,965,78,408,136,967,714,503,938,232,132,417,187,3,499,330,176,112,528,993,836,445,854,302,253,990,622", "942,10,445,547,45,425,592,501,604,834,809,746,379,367,968,746,725,189,266,412,192,499,450,396,36,247,200,39,628,680,294,767,477,602,575,291,217,988,31,863,205,329,12,506,281,935,729,962,838,209,88,515,641,643,325,115,778,103,339,617,962,451,377,929,955,626,260,843,926,938,395,812,805,314,719,601,451,626,732,991,613,221,215,415,676,115,40,817,798,615,6,601,426,935,771,252,499,259,302,428,463,302,772,996,986,755,358,686,860,675,437,850,144,20,862,742,356,313,16,238,578,101,32,351,678,765,44,135,758,49,513,727,846,223,659,21,137,219,297,459,159,129,501,441,561,703,788,658,604,407,968,270,502,588,727,493,985,631,587,402,329,20,38,290,733,919,792,747,152,938,586,158,630,350,92,123,955,408,445,289,691,304,139,305,239,609,866,567,868,491,844,486,870,874,39,208,730,371,449,259,788,212,828,437,981,519,502,287,528,430,588,479,31,86,158,456,78,162,733,998,61,78,243,634,564,530,815,700,771,314,806,399,229,92,308,549,651,632,190,537,425,538,781,549,346,259,10,293,918,254,492,976,802,947,219,414,883,156,264,103,702,280,744,680,704,531,272,762,319,450,398,722,174,628,738,199,719,755,330,258,297,825,545,483,848,584,777,424,89,835,427,919,131,902,734,958,556,423,335,614,63,37,481,966,442,252,474,30,755,373,344,767,540,360,865,357,710,876,768,326,17,662,916,918,904,826,372,694,295,599,660,22,83,258,886,311,60,179,723,283,712,794,321,40,300,11,721,194,935,803,393,207,928,659,502,809,251,48,223,466,737,15,400,567,942,49,423,347,876,82,402,196,528,872,19,181,682,198,518,847,963,405,968,617,901,792,457,140,830,518,450,453,306,723,964,137,94,454,77,41,590,351,494,594,817,965,737,403,309,281,477,543,662,499,864,798,958,652,820,728,285,673,183,683,372,813,79,416,352,22,235,168,6,952,665,418,364,766,469,807,463,621,711,584,425,9,428,915,913,567,834,553,92,26,616,790,856,832,690,154,580,197,369,175,682,494,370,610,377,828,350,161,68,113,484,847,864,929,429,843,788,784,135,987,449,767,291,933,548,491,715,947,539,88,610,889,686,346,728,319,616,633,759,604,6,127,875,215,336,251,421,117,17,702,883,824,452,421,0,880,450,309,323,977,204,65,562,262,574,288,661,576,640,884,558,476,678,348,359,99,6,609,403,962,561,303,438,254,193,513,340,757,837,61,919,248,781,668,284,625,592,585,164,295,508,198,567,824,298,902,535,325,373,788,928,971,569,174,17,91,434,171,326,817,427,893,438,251,32,388,368,782,486,861,592,499,820,238,814,620,255,26,480,775,778,501,775,252,495,528,50,984,373,876,666,200,492,100,55,958,980,453,580,200,953,5,509,772,237,607,753,525,476,9,220,157,537,694,802,110,43,375,376,807,656,310,925,921,280,603,340,280,909,831,34,363,624,504,374,772,213,469,645,854,478,56,507,230,157,5,111,63,364,733,368,379,319,939,16,674,364,238,209,150,425,625,633,28,525,791,644,957,325,83,912,203,590,705,24,217,294,228,464,442,415,562,62,892,628,747,287,529,980,632,299,236,487,350,827,233,629,91,632,718,351,876,451,390,319,253,944,166,639,512,181,840,524,122,481,76,319,727,649,447,673,287,447,417,119,417,154,402,576,872,902,206,765,615,50,218,285,174,751,139,108,303,91,461,53,37,80,284,400,852,241,150,500,200,92,783,173,184,212,367,932,155,872,479,140,26,807,786,164,44,288,819,888,584,298,185,303,685,57,559,524,209,953,300,412,436,621,704,268,58,890,86,885,9,32,476,471,240,75,56,94,546,278,89,829,177,627,957,852,150,294,400,773,516,767,562,332,264,420,544,249,73,817,674,572,20,339,143,473,595,515,500,226,743,480,391,940,342,15,152,951,592,228,291,380,705,9,280,492,29,502,368,665,421,738,105,915,734,240,877,109,64,446,639,558,905,703,901,179,746,493,479,110,844,894,129,955,709,92,578,919,206,81,909,734,43,606,710,908,850,737,859,207,169,611,685,602,204,390,819,820,66,286,535,331,474,386,728,425,932,784,628,228,378,93,990,740,549,374,683,646,112,588,260,455,373,698,931,353,336,446,500,908,778,406,535,692,740,619,437,367,918,358,812,924,881,6,788,844,534,193,445,201,485,729,562,883,410,801,194,146,217,550,215,569,446,222,241,768,599,983,573,571,50,568,542", "166,736,665,237,527,63,628,301,762,216,35,887,2,968,425,517,257,281,659,426,597,583,856,792,247,326,450,41,239,592,195,144,244,177,290,583,260,788,781,40,284,791,600,427,507,448,142,298,352,972,976,656,904,412,832,971,849,512,230,837,375,530,986,866,437,871,315,668,778,426,78,900,888,880,828,540,937,350,431,301,434,141,153,340,842,503,758,136,103,758,42,860,57,822,399,88,312,66,584,575,493,743,415,2,538,533,319,318,497,500,94,870,625,245,440,523,333,969,114,589,636,344,464,565,675,867,160,104,604,205,915,48,71,979,469,841,921,219,714,130,670,862,984,869,267,768,985,909,306,650,716,217,811,65,300,640,234,33,120,502,170,951,494,828,736,801,302,922,156,926,58,504,81,739,123,660,466,511,31,406,145,748,414,937,709,181,756,547,324,678,123,830,539,94,491,59,514,409,940,860,360,450,434,19,929,601,383,812,164,937,783,582,850,923,178,656,994,983,232,450,428,791,522,196,122,38,529,761,342,122,914,104,490,626,554,53,939,630,159,46,700,655,777,369,743,52,21,374,981,176,943,148,131,835,587,894,300,228,443,707,976,88,453,34,476,188,134,656,420,238,22,132,70,636,54,351,462,417,764,89,167,250,496,74,540,232,612,361,22,712,803,751,954,818,411,887,98,120,664,133,480,147,373,583,569,295,841,160,877,102,914,657,121,993,344,938,322,988,294,934,516,801,633,190,14,608,76,469,670,971,344,833,668,797,728,797,395,236,264,646,433,39,351,609,839,237,150,368,737,520,365,447,468,431,678,326,167,246,354,818,239,199,91,86,346,940,275,664,700,451,259,307,56,536,674,52,91,143,356,79,342,609,379,308,609,511,557,929,862,156,720,991,315,87,807,328,907,36,585,495,318,401,19,249,646,624,138,626,848,984,78,180,185,709,36,443,500,412,288,396,682,413,947,689,292,892,89,924,446,941,517,615,711,920,50,894,661,906,441,301,400,286,137,361,415,226,990,111,807,218,425,969,996,120,2,945,1000,794,374,848,710,749,618,373,728,607,202,673,93,678,612,391,94,626,324,830,407,454,187,232,227,367,758,968,59,499,81,574,179,934,890,694,885,150,697,241,479,824,23,533,91,2,304,412,50,499,876,115,522,607,639,832,439,954,662,431,920,953,880,0,920,96,520,32,281,254,504,8,917,297,712,258,686,922,192,734,43,229,570,935,949,209,167,277,150,856,986,720,788,244,466,679,209,567,860,642,3,586,813,773,92,445,758,867,792,998,242,674,115,729,489,21,948,371,21,158,328,462,364,604,858,532,430,539,554,604,924,159,292,720,577,941,173,767,47,414,445,705,647,465,301,283,969,724,742,99,462,821,794,338,20,601,762,221,70,726,106,917,307,973,608,218,119,357,450,828,673,7,5,935,853,956,38,572,665,35,968,123,823,953,78,370,675,325,650,421,444,393,867,506,956,700,105,461,168,765,800,993,148,57,455,195,957,378,819,48,716,902,690,993,682,18,129,679,701,191,792,706,114,939,404,589,693,816,153,418,889,230,237,620,413,19,580,713,785,970,851,939,129,36,392,393,635,127,421,882,337,683,477,978,344,300,778,348,583,642,970,640,873,287,992,962,218,610,183,546,298,846,609,361,445,988,823,816,340,721,477,690,217,623,169,341,541,142,33,375,847,517,243,802,20,500,436,47,935,833,136,183,892,962,224,917,410,437,20,920,163,304,882,286,28,174,386,662,715,380,948,340,802,606,435,459,719,428,120,270,30,271,253,848,795,950,457,54,647,833,593,367,607,532,440,988,661,362,730,487,341,115,100,971,840,159,322,729,319,924,369,453,986,753,22,346,909,59,944,218,403,178,188,286,131,707,985,490,120,938,257,748,165,936,542,629,913,842,734,268,663,285,298,145,360,494,542,540,173,359,927,171,331,631,944,616,323,328,461,209,82,139,392,305,997,395,164,269,650,298,555,473,832,674,634,231,881,724,18,581,883,240,620,981,109,451,348,426,964,207,186,29,350,884,437,131,272,568,812,685,112,518,909,962,356,581,796,951,861,465,342,751,862,741,879,952,861,291,550,156,461,397,54,734,57,229,448,857,653,134,436,892,295,201,378,813,731,494,981,463,321,152,64,330,768,976,722,417,176,646,590,857,18,237,422,90,122,72,763,595,122,854,842,418,106,979,419,807,755,228,569,530,568,128,219,161,188,390,486,380,560,146,297,827,533,713,701,393,358,845,697,752,170,910", "38,641,420,307,311,396,305,586,915,490,439,759,471,97,507,86,6,989,752,127,886,61,33,523,612,772,144,348,133,292,410,217,476,814,47,792,343,791,322,135,300,743,644,255,207,263,987,177,257,687,244,600,256,148,432,58,865,145,933,986,113,589,39,300,382,787,723,122,559,311,568,78,163,753,977,893,410,372,948,677,161,259,412,793,522,678,571,734,916,871,882,116,357,431,604,360,95,561,317,605,954,622,314,167,995,283,320,42,690,71,230,975,19,116,269,774,405,845,538,503,247,38,105,6,95,909,165,662,836,113,4,498,152,953,760,608,532,576,730,584,253,990,117,371,592,569,774,884,229,406,766,381,739,408,311,862,416,500,136,711,578,771,711,643,379,16,449,297,411,635,773,861,798,654,737,848,372,256,350,297,455,364,327,919,515,948,52,817,520,182,501,316,289,856,284,35,915,85,187,546,105,91,866,917,341,669,191,563,919,210,303,951,8,938,127,803,610,152,280,429,442,153,40,277,584,274,658,105,844,722,685,737,518,143,148,662,93,909,647,195,576,109,246,746,785,48,214,61,356,798,676,667,307,820,708,939,347,451,972,584,698,497,338,15,342,504,602,93,874,337,400,653,169,69,960,594,261,31,78,388,948,163,303,746,746,725,470,420,754,953,724,181,308,752,575,858,203,884,216,826,373,719,343,839,114,9,997,215,336,690,254,515,862,606,711,834,269,734,492,579,773,592,810,640,527,167,138,47,525,964,558,963,543,835,472,316,9,155,565,483,22,574,328,364,513,864,884,98,489,620,889,441,262,90,420,187,446,436,570,703,28,183,697,283,897,461,249,210,511,87,705,832,18,209,894,489,685,909,678,85,423,549,455,745,134,608,29,626,669,614,226,854,685,71,982,120,520,946,234,356,410,820,775,298,369,736,512,791,153,72,621,547,237,224,220,829,231,935,303,273,813,960,715,952,56,440,410,580,874,563,514,66,248,643,11,81,820,877,199,538,703,423,951,268,47,460,65,682,771,583,677,253,771,140,717,105,690,408,367,531,528,301,175,881,349,691,928,97,796,708,136,352,281,324,39,807,973,514,768,493,679,471,383,426,345,56,142,107,402,978,354,162,888,745,974,493,730,137,856,648,615,169,640,642,407,490,716,856,435,826,760,629,709,90,738,168,989,495,450,920,0,158,432,394,651,106,536,328,164,651,539,939,386,683,445,41,796,461,562,956,864,270,747,315,505,75,302,691,92,760,721,102,485,226,266,540,876,792,531,396,827,588,535,610,884,722,752,690,115,488,444,410,650,264,821,423,5,782,310,197,677,808,465,389,352,858,791,594,976,675,170,545,518,918,556,937,194,285,553,700,435,460,914,252,76,174,898,658,864,94,443,422,917,651,347,902,78,744,996,385,934,9,305,571,921,826,986,967,566,454,54,26,220,891,681,770,812,877,348,906,159,58,775,836,353,520,122,17,707,324,481,189,243,13,913,103,104,718,193,886,958,508,375,418,280,542,996,222,535,423,7,317,337,175,707,534,958,970,454,932,942,715,768,863,996,753,249,386,845,534,277,281,1000,832,486,551,579,575,312,530,762,719,871,120,305,965,874,153,368,801,155,366,385,731,967,386,260,647,578,701,519,274,39,864,829,544,447,517,550,524,574,800,685,505,217,57,107,329,159,867,429,213,912,200,790,583,971,15,765,259,773,195,13,89,229,203,163,914,645,189,734,379,106,455,142,521,852,311,311,881,802,333,672,976,470,211,874,281,877,115,387,108,186,406,460,410,56,704,401,817,376,175,133,548,539,808,428,767,925,334,741,517,90,292,623,719,208,395,202,600,827,958,505,952,314,192,977,525,481,106,700,842,565,219,153,85,585,413,870,593,505,329,138,132,892,263,215,660,128,898,928,600,669,144,102,463,175,113,316,486,586,140,254,433,402,156,59,573,539,681,288,341,391,156,863,774,563,490,855,524,599,941,776,526,563,58,414,213,882,424,896,199,584,565,402,713,655,556,986,385,776,337,929,972,42,174,552,359,688,314,29,959,509,993,279,937,750,544,480,995,911,757,561,992,817,409,76,533,150,895,958,93,737,346,358,925,375,786,655,558,882,528,212,588,110,634,640,568,939,579,470,352,890,546,900,960,877,267,381,986,578,149,833,874,163,354,653,870,391,359,127,849,329,410,106,453,461,35,762,116,479,192,683,871,632,437,610,315,164,58,428,96,430,691,11,466,355,568,938,190,231,646,943,609,597,102,732,527,78,23", "203,227,613,430,248,478,919,186,527,821,684,772,786,18,900,426,150,455,313,725,251,578,118,842,77,49,762,971,729,232,105,440,961,935,287,61,198,149,598,222,401,749,441,792,610,935,601,935,148,246,278,876,247,508,886,481,374,371,450,914,456,753,385,426,233,862,871,759,181,579,348,381,906,264,443,811,442,595,379,258,395,952,861,432,960,913,832,355,989,622,706,795,434,658,265,636,144,730,635,148,485,255,391,346,127,592,651,900,803,616,401,670,669,247,971,350,963,928,450,471,123,346,257,566,289,557,542,613,811,266,308,609,375,952,273,445,740,70,910,645,551,125,673,60,487,636,888,10,598,371,156,247,552,30,457,491,908,738,986,663,316,558,382,41,91,158,45,356,863,575,843,419,39,285,930,470,817,446,792,53,394,541,770,132,198,895,969,21,614,250,778,85,812,907,741,670,278,382,523,753,803,547,474,534,301,980,502,643,381,542,65,723,904,58,126,906,806,415,711,343,524,985,216,477,336,134,509,147,588,230,777,326,881,900,345,506,51,757,116,466,822,80,876,476,911,875,868,51,938,414,891,731,760,523,639,672,711,409,679,949,711,990,680,745,928,348,742,297,236,891,101,260,481,3,645,777,57,870,152,522,415,894,335,673,227,965,54,990,832,414,369,579,514,107,140,368,817,527,406,410,935,46,675,401,708,313,894,704,309,826,577,745,279,191,106,212,758,975,320,902,475,975,723,470,920,144,847,834,919,552,4,744,576,871,636,502,791,68,990,389,485,934,349,91,386,567,431,139,529,754,750,93,7,71,664,787,966,972,914,152,981,475,71,429,721,814,676,767,420,215,74,339,182,187,403,811,837,200,93,824,533,585,29,218,97,564,800,73,397,458,370,844,329,52,423,527,934,859,297,545,224,453,509,720,897,73,886,825,731,399,921,825,650,853,764,706,691,518,225,211,99,853,319,252,491,967,398,45,429,432,67,910,81,221,698,39,564,449,553,51,100,702,920,201,68,233,832,763,922,794,594,813,716,501,424,719,104,594,615,970,448,371,899,588,331,141,801,456,889,568,597,609,838,837,560,121,696,235,488,975,516,40,392,954,400,18,76,835,680,790,46,975,760,337,523,231,159,426,139,597,697,724,734,527,553,564,263,194,361,268,589,252,538,892,790,46,977,566,309,96,158,0,637,802,438,326,570,719,887,277,94,40,475,519,476,597,183,25,91,854,984,291,580,561,323,680,106,929,246,312,212,772,79,150,800,141,929,925,924,433,704,887,639,254,426,499,103,970,462,132,133,199,212,998,871,121,587,796,104,316,506,291,944,310,667,527,773,227,709,165,798,186,145,448,566,304,377,354,935,944,369,249,818,154,191,660,539,55,509,263,761,190,220,647,676,381,588,699,61,878,890,266,390,931,927,321,65,269,738,601,929,827,132,326,363,760,762,886,322,22,321,479,472,136,336,303,193,750,921,982,11,938,31,690,477,679,70,160,170,718,70,798,3,30,635,894,733,427,755,899,454,866,342,102,466,18,96,993,35,729,209,958,837,142,962,279,855,140,301,274,38,587,641,93,57,29,52,93,829,874,547,888,934,609,99,207,866,577,242,444,171,152,250,413,822,522,87,970,518,434,704,20,326,729,299,890,99,720,725,133,928,73,704,594,22,600,305,71,925,751,365,481,447,772,47,519,639,231,292,268,484,920,283,441,703,730,96,983,318,833,76,856,671,854,233,719,574,90,188,797,332,699,378,140,848,33,71,312,13,830,351,797,772,964,922,25,995,175,389,42,235,774,611,757,853,689,915,97,356,291,412,848,244,220,485,806,919,861,535,339,969,370,15,932,519,300,656,984,88,499,873,977,271,440,612,186,326,885,393,330,306,323,100,967,701,113,28,609,574,696,374,214,42,407,141,6,946,229,870,778,965,64,774,3,804,767,95,267,411,126,1,934,762,848,649,127,350,502,558,376,310,27,718,766,677,41,723,736,890,681,160,810,672,920,283,242,524,664,789,346,810,726,355,624,111,420,395,19,979,859,316,221,585,521,742,866,708,168,339,174,579,284,144,241,702,606,386,294,913,289,921,352,991,163,756,921,26,246,658,219,823,263,252,679,693,768,133,541,326,750,26,545,807,993,959,489,554,783,407,885,46,402,988,544,405,576,521,728,854,954,868,667,68,309,574,574,804,741,97,931,551,636,432,368,895,696,731,331,138,636,204,951,419,97,265,281,339,886,23,13,696,231,171,448,191,38,637,946,564,487", "953,538,596,331,973,171,521,747,478,323,251,712,759,933,227,169,771,791,159,339,211,979,398,385,461,679,238,251,281,65,784,397,866,621,829,960,768,613,146,962,72,417,198,283,504,77,281,537,887,262,45,112,831,200,693,920,102,594,142,282,634,613,320,638,9,625,108,449,646,683,565,726,436,251,804,392,230,753,501,263,294,597,94,335,941,171,766,34,420,898,2,508,697,75,328,769,125,395,358,597,775,556,987,575,754,764,698,875,672,292,722,607,429,88,150,192,960,169,434,493,213,98,192,142,866,115,54,935,601,957,916,365,903,25,845,162,360,113,743,563,986,679,807,144,237,946,576,981,385,105,355,844,281,581,64,579,512,460,587,690,990,761,172,658,290,689,150,1000,12,539,339,198,80,661,84,661,9,469,377,281,40,581,120,379,947,251,763,523,812,815,789,57,709,133,749,798,972,701,612,144,897,776,72,74,377,55,657,301,732,169,52,621,246,403,907,765,844,870,664,917,203,734,990,177,614,275,513,668,818,108,452,102,640,339,784,386,375,809,787,243,219,641,56,332,243,838,240,450,498,449,842,125,933,649,459,49,157,356,788,15,889,97,171,601,878,119,367,959,99,236,907,681,390,392,880,376,779,240,308,567,806,54,456,737,957,119,338,698,560,992,100,831,716,529,870,729,24,583,645,69,438,453,705,337,204,418,114,160,568,840,590,871,777,666,841,714,169,29,997,722,854,137,847,811,413,473,443,284,58,676,172,753,197,114,176,927,939,917,914,288,809,982,166,724,846,600,398,244,403,232,268,964,428,81,243,649,128,530,657,56,504,107,348,258,415,40,458,848,446,793,202,706,664,705,316,337,47,335,615,775,948,706,440,212,61,536,416,282,335,883,851,299,936,814,855,439,677,850,974,529,970,587,854,186,698,110,120,629,535,769,635,12,723,142,598,62,759,406,853,368,173,848,853,16,449,596,28,786,413,327,243,640,548,46,874,349,131,8,659,884,936,210,30,541,485,287,291,458,533,341,630,210,509,744,922,936,164,970,730,713,93,547,669,358,249,893,337,161,31,383,14,646,98,766,415,809,599,344,677,891,882,636,211,554,684,77,60,871,158,361,691,578,924,796,798,705,664,956,90,815,353,14,63,75,661,376,589,574,605,82,68,582,586,123,663,883,328,535,323,520,432,637,0,220,942,387,247,148,227,228,650,470,313,414,770,309,921,340,888,957,696,644,947,254,193,300,285,740,277,7,229,711,199,265,584,795,868,179,116,663,886,553,979,951,552,222,442,889,699,761,993,501,20,467,410,787,639,151,654,596,45,217,736,50,608,436,243,19,780,710,454,57,784,169,617,769,286,260,924,368,185,243,428,982,362,537,808,719,98,76,539,406,237,905,934,287,467,205,561,154,209,33,891,846,588,360,136,877,373,302,300,650,526,341,83,954,803,599,904,933,788,372,791,892,819,153,974,157,12,598,930,758,442,803,330,305,808,265,890,56,131,219,597,107,311,410,496,790,7,44,426,813,666,52,654,431,569,931,452,809,998,113,572,853,96,355,824,709,445,603,534,284,627,527,693,619,801,949,577,660,102,918,83,537,981,850,211,103,488,404,14,309,37,704,643,132,575,63,286,8,132,570,885,159,81,330,70,296,435,379,25,210,950,430,481,47,711,381,416,864,795,650,439,864,353,981,348,498,31,151,718,570,640,85,728,800,801,943,812,828,946,636,473,704,987,436,739,896,357,180,824,709,505,42,791,831,120,773,862,64,919,735,753,97,33,183,913,409,754,901,542,767,791,291,747,784,976,434,226,310,487,627,652,984,306,269,412,235,374,651,715,537,991,536,41,886,243,25,308,162,798,5,585,216,345,78,823,462,266,568,743,935,705,235,412,370,146,596,755,518,517,722,31,446,999,479,166,524,124,970,985,811,200,951,898,632,751,921,977,38,915,5,680,928,48,69,688,59,85,139,80,455,500,19,868,738,629,731,981,682,369,191,237,769,26,601,718,381,918,608,986,566,396,706,545,339,29,450,82,718,683,226,614,311,239,598,719,165,312,632,487,454,2,486,406,635,323,920,961,257,177,258,297,42,815,332,795,905,102,239,911,391,904,687,367,627,210,424,944,989,556,590,812,777,515,763,945,363,341,365,687,847,471,755,635,722,585,247,890,728,611,271,975,53,717,936,169,817,336,881,254,86,215,208,962,234,85,237,828,788,350,36,522,689,687,396,357,193,604,856,830,213,934,208,543,772,197,175,941,766", "201,609,755,176,862,348,285,745,960,760,242,463,810,516,126,861,923,37,505,922,101,660,228,418,459,785,125,57,530,788,402,185,768,123,332,102,905,690,748,807,222,609,37,414,120,915,54,909,105,29,993,730,645,930,857,980,205,129,788,679,320,497,162,415,679,162,593,271,446,710,280,125,112,692,482,627,483,213,991,906,625,658,372,801,73,488,567,736,926,278,393,337,95,236,856,498,636,152,211,123,102,215,477,469,110,384,88,748,677,347,914,882,900,312,439,182,489,330,806,392,911,589,137,972,686,730,138,793,728,63,787,615,166,435,601,419,713,88,39,746,572,113,783,962,493,402,760,159,635,848,477,176,338,864,618,327,447,752,18,68,624,106,481,105,877,337,577,230,870,546,100,427,453,204,753,323,751,573,110,185,183,445,282,890,218,33,694,391,352,72,576,232,918,492,536,930,733,331,401,227,463,977,690,75,445,403,338,585,983,654,644,419,620,929,379,633,575,484,509,95,888,200,259,670,186,505,237,22,151,891,559,134,289,742,466,846,589,265,862,707,387,112,142,759,784,267,808,668,89,989,955,801,689,766,921,693,602,862,794,179,407,670,102,901,393,394,545,658,412,309,650,256,56,296,399,265,194,297,218,864,530,939,681,539,707,150,318,620,910,280,875,613,314,713,59,964,865,207,312,864,864,714,453,468,526,273,875,825,575,801,89,786,619,376,181,227,840,554,297,721,259,404,75,279,676,352,884,114,135,84,339,11,563,6,532,789,627,61,809,972,888,532,231,70,350,553,859,825,840,505,444,409,426,752,127,50,265,510,213,174,434,12,287,290,444,804,426,226,447,970,948,77,363,203,415,185,503,151,576,392,139,213,274,514,906,130,612,528,374,31,736,228,844,819,72,363,637,599,659,775,541,499,442,6,442,656,285,425,125,83,216,999,641,976,658,22,467,922,200,850,809,597,321,628,124,414,844,629,779,643,760,796,54,924,815,744,255,200,40,626,215,182,261,841,397,925,372,319,257,12,166,519,893,843,876,82,930,271,68,636,10,904,274,122,205,11,875,149,107,199,746,409,500,111,280,268,115,369,580,193,719,203,284,332,745,659,602,960,640,650,173,837,895,105,172,896,597,37,6,672,994,751,712,683,860,668,396,331,128,654,401,880,284,667,556,294,51,433,977,32,394,802,220,0,204,366,167,466,707,469,335,936,752,224,137,430,835,989,321,268,920,691,595,89,710,377,635,714,686,965,928,585,682,573,714,455,602,767,227,971,740,425,352,559,565,974,986,247,242,564,789,543,403,471,603,293,475,311,691,843,226,81,846,122,452,396,138,606,647,480,383,433,802,498,822,322,230,682,599,134,44,828,482,612,971,883,359,477,29,103,430,775,765,879,158,604,438,752,57,597,185,350,571,636,840,393,63,234,491,31,989,922,361,544,224,8,274,67,444,302,23,941,522,800,432,957,192,371,108,247,586,872,766,140,263,158,362,633,347,224,5,855,421,235,947,509,873,749,131,54,523,333,305,866,361,557,975,896,88,964,722,808,959,230,86,562,414,465,901,750,342,383,418,706,536,586,355,430,524,272,884,952,524,704,508,186,654,564,332,640,354,246,317,583,714,28,43,343,562,84,757,664,36,347,265,552,772,697,344,738,920,494,454,33,991,295,986,157,645,716,873,889,164,34,364,577,923,195,126,511,273,630,974,61,493,997,390,749,448,159,216,569,802,81,748,859,395,694,247,224,273,577,581,535,620,683,442,422,190,659,766,736,448,794,16,287,123,845,44,401,516,383,912,341,525,471,975,854,188,876,858,172,597,425,76,970,344,918,327,763,277,501,730,968,468,895,10,796,31,880,644,320,916,853,275,135,79,854,586,244,281,599,292,822,681,901,972,272,590,729,154,593,501,477,650,198,839,238,768,107,569,775,164,929,844,494,987,558,672,751,85,614,619,478,615,456,228,144,159,63,822,38,48,253,541,446,632,594,152,462,41,896,781,318,369,620,978,748,457,846,736,752,112,209,392,546,574,297,405,463,407,316,760,999,697,242,632,530,826,787,669,659,905,57,696,119,138,701,549,10,812,595,211,273,440,16,381,135,99,388,612,83,298,50,517,623,447,865,330,38,747,573,283,158,141,208,521,849,895,140,936,866,361,560,284,212,897,413,767,848,986,168,818,944,757,971,751,82,168,121,760,5,40,168,820,870,52,719,596,234,226,439,907,903,363,56,777,674,963,996,959,269,913,659,163,912,514,957,278,340", "566,954,870,121,683,37,545,731,288,607,84,781,104,203,9,106,602,968,545,900,277,28,348,317,911,893,861,109,143,146,149,581,510,735,559,516,960,224,585,500,357,59,268,319,975,74,42,928,10,737,939,11,966,365,192,231,177,446,937,391,119,631,695,379,129,54,290,531,309,198,965,633,760,62,209,566,589,962,677,718,519,29,111,204,162,992,754,380,999,303,348,308,859,122,706,253,695,493,641,218,575,108,240,688,561,227,335,23,343,790,671,153,328,181,6,728,1,990,503,482,629,34,471,640,193,559,950,21,954,32,246,327,684,464,268,538,963,527,447,645,666,468,540,292,383,369,675,883,672,759,740,323,664,721,899,340,866,921,189,200,212,124,406,689,151,788,869,319,507,807,248,359,334,216,108,148,432,157,891,544,544,339,80,720,447,541,511,672,777,218,937,831,591,20,142,857,347,504,498,610,470,543,8,434,403,333,931,102,343,796,250,320,408,900,384,231,777,486,273,960,949,405,54,218,75,123,169,162,455,267,370,323,21,617,729,585,58,812,420,104,576,974,540,243,656,632,26,484,891,370,713,361,497,644,776,223,745,711,227,123,523,306,600,826,450,998,306,829,124,573,155,408,31,758,210,991,142,776,729,592,447,129,745,550,25,186,818,404,19,111,776,74,264,774,391,531,60,783,991,592,849,798,86,482,15,891,413,686,574,438,408,918,303,729,800,851,561,49,165,136,214,354,216,316,855,426,284,505,920,551,147,886,94,703,576,442,982,379,946,14,230,571,388,104,977,970,152,324,292,859,909,105,721,262,984,296,285,370,149,367,732,284,421,476,804,713,146,223,538,673,279,594,245,386,738,705,914,328,473,927,497,369,725,8,681,73,571,64,923,195,389,628,694,550,115,288,489,522,874,815,589,21,874,639,74,604,926,457,514,934,372,622,62,477,202,146,142,863,583,177,323,268,822,95,127,209,109,335,893,488,170,83,999,837,258,773,770,848,825,566,55,110,17,123,356,762,902,864,674,392,679,361,115,900,684,166,171,124,740,340,644,880,113,937,335,440,454,76,487,662,22,216,60,797,872,629,297,678,588,268,554,369,696,996,660,168,86,745,967,270,840,727,783,623,992,85,789,357,842,404,459,257,456,215,561,871,428,693,145,355,27,619,529,408,119,577,613,459,204,281,651,438,942,204,0,654,26,740,850,328,326,957,693,878,912,875,33,643,44,965,834,126,117,345,241,954,873,422,93,859,712,290,994,694,231,246,797,489,880,17,151,501,568,673,866,634,3,530,415,93,816,278,690,212,743,365,136,547,279,503,744,248,120,902,492,973,517,200,438,277,939,663,270,787,141,214,474,798,777,903,758,567,501,210,781,378,857,571,845,533,25,372,866,186,404,202,576,191,717,527,776,516,330,975,715,591,921,455,590,413,126,230,572,122,847,591,57,516,310,423,604,470,279,585,785,652,876,583,360,571,562,844,672,171,548,811,65,952,234,388,672,951,554,618,19,154,875,987,917,302,314,79,412,923,92,516,145,666,242,659,877,692,341,740,118,490,23,852,367,564,332,165,306,240,543,750,444,236,922,514,670,956,385,527,281,140,13,491,447,474,743,827,617,962,470,42,557,637,342,34,114,265,544,947,117,852,335,27,826,5,203,319,938,779,479,346,985,241,581,248,55,100,377,474,157,873,812,242,66,127,389,499,452,527,474,99,836,643,747,874,605,722,215,43,45,809,820,160,597,265,123,987,848,147,976,512,983,128,172,714,233,641,48,346,88,758,398,481,308,122,654,673,998,825,209,704,549,927,387,412,949,347,53,490,435,975,236,1000,631,537,497,879,11,121,884,831,411,514,966,316,398,352,714,672,808,962,20,351,446,592,96,327,371,98,666,924,601,387,964,570,103,785,726,792,62,989,675,624,226,415,132,173,24,258,588,291,94,6,942,425,773,287,660,847,223,254,546,972,255,829,800,126,149,761,578,383,6,742,960,694,123,663,421,59,216,648,454,144,594,779,412,901,357,70,433,848,842,517,966,710,981,403,628,236,205,714,964,59,985,641,286,65,32,964,901,676,679,944,45,626,821,160,521,733,212,565,723,350,855,446,884,361,313,835,944,549,446,65,810,549,870,341,712,94,406,530,266,147,16,622,688,10,831,982,675,384,180,711,151,520,610,554,501,185,348,91,277,346,477,521,263,232,382,68,903,739,378,51,777,16,561,453,575,184,98,395,461,462,408,757,51,254,697,698,814,428,66,804,446,918", "409,84,406,682,951,64,342,715,649,431,503,529,222,475,488,57,350,551,333,127,492,65,470,93,4,685,232,956,388,283,737,733,121,108,637,947,29,701,219,544,101,694,662,82,448,441,891,651,346,508,700,895,55,930,362,910,847,615,571,80,679,652,87,826,519,324,373,84,792,157,570,215,173,883,428,275,223,171,262,133,19,824,809,213,682,102,655,915,859,171,128,850,488,846,941,19,112,760,303,518,884,750,812,756,793,10,227,864,970,647,433,885,837,668,151,39,187,291,210,324,21,917,663,876,265,804,342,563,606,444,976,133,874,572,810,897,361,506,887,890,635,299,584,451,762,903,9,139,131,441,150,249,728,895,802,521,294,770,157,646,550,901,847,601,955,567,809,463,506,176,489,909,953,155,975,442,263,574,368,715,898,475,408,310,350,409,190,137,615,90,370,877,800,884,677,620,396,375,834,574,240,287,763,111,415,281,111,345,249,505,341,3,127,944,737,490,689,421,180,750,684,575,809,840,278,767,114,411,961,662,988,84,402,816,544,779,257,695,665,123,256,438,290,73,753,786,279,609,299,970,352,12,301,719,507,852,508,54,256,409,445,659,837,224,15,198,94,915,922,275,599,818,430,83,981,411,500,536,621,886,599,895,831,558,252,964,987,481,525,967,464,93,298,958,902,718,626,89,246,636,246,80,939,86,98,862,863,190,644,817,282,631,619,230,706,60,915,892,270,294,255,875,685,204,423,793,550,392,377,475,917,930,815,341,138,914,6,594,216,570,93,963,162,365,467,680,370,482,215,616,17,66,70,840,832,344,362,56,148,159,674,422,235,569,623,293,887,92,29,496,751,540,912,615,595,928,625,109,479,599,702,9,198,763,426,762,467,520,155,312,289,447,946,46,538,859,996,832,965,464,617,850,654,267,17,857,418,993,756,825,465,270,42,506,796,836,828,404,572,2,727,53,898,949,920,368,443,543,981,863,612,771,708,255,790,371,654,532,446,259,689,433,461,479,370,58,447,397,692,569,36,5,632,980,218,572,729,582,962,506,731,680,95,5,275,334,80,404,7,241,851,248,343,241,324,728,38,916,521,411,34,727,407,841,720,294,621,346,506,822,798,872,859,483,63,645,45,118,197,705,867,387,426,172,878,835,866,818,303,487,674,994,540,138,217,518,476,33,65,254,106,326,387,366,654,0,47,173,91,142,347,549,41,448,525,900,17,345,887,272,521,540,205,496,872,596,915,288,967,631,808,886,398,924,166,342,972,970,197,997,515,814,245,351,227,233,704,222,227,645,67,152,413,503,176,264,897,873,258,364,24,10,390,393,391,90,929,63,938,306,555,663,366,600,262,184,143,241,445,262,587,240,239,68,794,451,607,772,36,155,931,630,513,447,328,956,420,794,698,922,659,892,511,204,231,454,682,781,163,357,593,209,447,229,353,883,965,651,504,442,170,184,590,397,820,763,91,141,353,121,417,418,250,174,414,707,692,812,103,259,908,412,937,475,718,984,73,548,641,698,134,604,682,379,908,185,800,43,368,238,576,190,878,41,796,412,928,360,370,933,402,799,730,30,789,76,646,946,181,871,546,87,41,877,169,601,28,536,706,338,702,150,537,271,478,876,80,577,944,887,251,638,569,688,876,585,627,122,521,969,556,481,265,910,21,716,342,557,149,83,16,356,63,830,943,810,272,461,906,368,992,549,146,819,254,789,194,215,430,81,273,324,136,893,711,731,233,978,446,993,402,272,35,6,653,918,351,748,889,869,268,3,706,185,984,80,622,480,156,734,152,248,874,809,533,567,229,589,335,929,888,974,785,169,657,99,378,925,319,582,641,376,639,547,310,202,235,620,377,701,294,29,2,91,472,686,54,633,191,266,815,89,215,514,38,286,620,626,846,457,262,651,355,681,948,135,492,838,305,758,283,397,315,719,90,96,631,551,950,200,147,779,671,212,279,648,184,371,557,626,597,113,590,535,74,30,920,128,902,67,488,855,350,813,892,301,279,124,103,627,947,677,778,648,438,862,199,684,249,183,372,304,742,255,209,299,103,366,866,889,896,551,535,251,202,614,478,627,713,552,622,482,394,210,764,238,702,29,657,109,131,265,294,201,194,690,223,790,348,907,760,16,615,398,751,760,94,842,937,904,381,471,753,175,654,400,920,730,613,84,786,816,701,823,348,42,998,210,330,812,747,881,136,207,303,574,610,323,573,938,553,955,495,384,200,143,632,962,125,519,148,64,200,114,603,129,578,840,35,898", "64,304,727,696,91,461,934,762,899,439,513,397,127,112,335,412,810,392,286,435,552,230,676,724,487,261,753,127,433,331,29,15,701,333,308,991,283,954,225,390,265,637,779,446,193,870,614,221,286,894,968,830,234,435,629,593,278,533,14,125,3,832,102,226,859,141,253,965,304,500,529,735,151,322,310,515,713,22,982,977,822,268,119,989,382,394,537,915,631,713,706,329,184,844,503,392,576,686,986,225,158,963,882,825,624,198,622,1,658,307,30,293,875,531,689,314,6,838,510,64,275,450,708,471,763,372,838,325,121,928,2,463,906,820,596,490,350,508,962,89,899,393,457,567,75,273,670,994,800,426,243,494,345,880,853,442,806,82,95,691,533,140,612,758,320,385,765,881,823,434,914,118,252,37,157,207,784,235,278,122,377,756,219,711,585,968,13,811,724,968,182,381,173,729,898,949,356,359,423,954,520,583,917,277,337,204,208,707,975,849,76,753,531,419,190,571,161,323,280,691,655,639,292,994,859,393,677,613,833,352,57,718,302,999,152,175,231,844,966,208,326,812,902,323,723,955,596,457,949,920,358,612,603,790,569,735,347,861,921,452,458,721,91,1000,576,315,244,525,624,515,774,975,473,666,766,773,751,620,627,668,222,733,828,471,583,625,324,10,566,955,504,738,917,546,125,871,247,441,24,149,15,308,375,598,919,141,202,398,894,803,238,91,853,72,658,858,584,129,914,725,2,446,946,685,972,912,348,639,521,376,341,498,731,971,420,476,486,794,871,115,801,694,300,715,708,547,361,577,61,978,427,906,886,300,166,920,694,215,32,648,593,794,249,93,106,119,774,340,86,214,54,886,895,712,822,767,696,102,577,901,345,703,22,196,344,18,50,2,350,5,240,482,461,439,371,457,66,612,999,514,600,22,196,452,756,652,642,69,969,81,113,786,429,20,951,484,322,357,142,890,21,358,382,473,282,733,132,765,553,59,233,640,936,233,585,403,153,689,649,891,137,405,279,51,540,749,646,562,631,854,29,176,410,317,677,419,595,864,272,58,17,682,275,989,243,738,5,561,180,395,657,451,416,826,351,518,325,783,659,846,834,95,913,176,471,531,632,180,139,926,512,325,119,938,608,676,278,639,331,797,826,755,740,603,53,720,83,226,461,380,28,331,828,496,310,344,517,669,562,504,536,570,247,167,26,47,0,219,175,673,51,840,463,113,648,208,795,757,36,625,350,10,433,855,121,685,703,389,741,183,817,731,935,683,330,782,693,183,920,558,611,672,544,664,387,277,470,594,297,925,410,651,157,512,427,621,5,242,361,407,284,556,393,797,882,578,866,590,159,153,756,767,541,411,884,798,767,171,839,422,621,434,876,798,649,50,70,658,992,428,75,988,639,955,8,947,898,577,708,693,449,577,974,731,963,347,315,781,561,339,448,680,31,963,6,107,712,635,730,644,539,105,732,731,296,808,997,603,236,850,52,649,140,581,876,506,964,408,779,271,128,859,1000,628,960,815,733,583,748,958,297,342,270,654,778,549,899,897,381,576,954,423,871,103,297,312,177,394,282,187,319,335,848,782,396,412,458,863,273,337,546,649,299,329,991,307,235,900,454,182,551,50,665,299,934,41,85,344,535,473,706,483,9,414,896,834,354,647,120,997,684,401,218,131,31,987,630,561,539,585,685,220,237,70,238,830,863,326,32,946,399,805,136,765,468,549,240,528,104,893,932,631,710,961,343,113,483,585,268,16,424,605,717,762,555,457,531,961,380,832,582,301,541,397,985,147,708,269,454,982,669,286,229,120,164,974,716,873,901,238,207,393,140,368,413,543,828,897,786,593,217,216,205,833,109,330,388,135,610,914,86,822,127,11,335,459,953,844,529,187,928,746,343,120,677,734,993,843,822,102,943,646,588,788,476,822,505,625,702,581,825,634,152,577,292,387,746,593,751,478,11,367,246,877,655,354,178,631,459,233,116,1,286,674,10,604,529,8,931,299,442,983,46,744,589,891,269,310,696,179,701,753,18,748,633,430,366,24,250,387,95,141,532,659,281,253,517,675,967,661,796,750,858,177,896,728,548,986,907,773,830,523,498,640,588,685,362,321,758,569,697,512,601,385,76,549,184,733,853,177,517,950,503,849,884,447,404,310,759,700,439,170,183,818,177,604,774,405,237,86,909,209,238,380,50,321,241,289,5,471,767,241,690,492,374,742,109,840,332,681,92,248,194,604,55,379,424,460,249,639,414,948,199,648,641,469,551,859,214,703", "833,961,935,25,681,50,653,349,269,767,511,242,521,211,839,535,873,28,359,957,689,600,423,122,793,373,930,985,628,512,904,204,218,269,413,161,866,22,107,40,527,365,618,302,826,110,815,251,162,813,57,711,656,108,773,928,329,194,91,699,327,648,343,671,348,211,826,701,457,704,10,312,515,66,485,120,222,921,889,175,97,154,302,419,372,544,767,508,843,209,721,551,885,669,358,5,79,386,315,277,938,358,611,150,304,669,350,330,417,336,71,830,376,371,868,174,94,387,883,58,890,837,496,541,669,650,839,996,412,17,201,632,673,478,684,559,444,39,451,905,843,688,839,19,917,375,9,462,382,365,932,516,579,934,501,982,242,517,186,374,321,608,405,239,320,188,126,68,645,9,589,833,532,884,293,152,736,528,197,392,452,32,706,465,700,391,867,644,477,337,207,826,376,738,43,24,678,614,594,650,592,435,328,594,71,457,957,320,666,474,92,650,671,177,541,155,656,190,433,930,595,563,327,121,4,934,695,678,538,600,784,815,111,584,461,21,403,301,836,605,699,53,427,642,52,899,95,336,811,841,391,395,897,794,96,501,122,922,827,885,513,428,839,149,989,596,384,206,288,983,240,536,769,937,28,562,970,643,953,301,119,400,252,181,927,671,944,206,758,619,655,334,612,35,675,956,759,425,251,466,7,761,258,625,136,8,641,676,659,701,643,990,630,8,670,509,74,503,868,863,437,900,4,958,452,995,842,80,621,872,612,570,848,674,693,820,243,48,872,699,576,238,472,359,435,330,434,788,846,894,800,224,126,503,528,703,445,192,883,297,519,558,884,749,861,922,206,559,993,355,216,301,666,441,854,221,232,258,634,611,750,627,675,438,97,955,269,240,853,579,268,565,730,125,367,95,853,495,486,520,389,473,949,904,647,999,535,498,977,397,884,693,880,188,938,952,23,532,841,837,979,629,34,657,533,349,489,165,112,432,836,607,542,68,953,202,205,973,492,347,669,991,522,435,947,459,240,132,759,168,68,375,209,19,210,781,881,614,360,104,543,842,592,877,446,496,707,923,376,979,835,704,219,920,414,544,608,274,623,143,317,677,840,512,689,542,168,5,258,97,512,910,143,13,262,436,181,196,44,550,828,659,676,609,773,467,904,948,922,912,779,909,716,222,295,201,681,108,262,8,328,719,148,466,740,173,219,0,943,466,945,151,679,66,204,981,8,909,86,14,696,363,803,650,989,298,826,139,996,285,253,293,732,2,397,337,228,286,208,536,806,853,872,711,301,331,901,419,888,599,871,135,233,606,646,751,550,529,483,821,731,736,450,926,914,173,962,361,22,754,608,431,966,886,514,430,202,64,586,799,717,435,874,254,967,39,13,878,834,596,961,59,771,272,351,316,945,891,226,864,6,946,873,711,603,724,209,326,985,220,675,887,707,977,808,912,469,795,970,135,729,853,825,68,125,146,196,94,745,250,267,681,225,845,613,582,890,768,579,885,176,344,171,921,568,218,961,237,154,197,275,187,344,92,492,38,603,727,373,92,877,134,584,224,330,521,294,472,1,449,755,843,970,811,217,58,645,383,821,437,193,172,828,973,629,407,661,910,525,891,292,612,278,556,675,90,790,494,325,573,408,151,110,825,954,480,312,634,758,272,832,260,42,533,579,116,602,790,331,416,43,392,91,935,9,623,497,287,200,477,800,422,916,90,155,468,237,890,745,261,430,224,576,909,104,697,803,354,816,208,230,921,183,603,476,110,190,683,819,445,475,92,654,190,686,909,399,980,126,73,66,515,658,254,121,996,442,464,159,153,714,10,369,157,943,92,355,771,978,767,934,431,873,913,444,136,828,572,541,210,768,27,464,931,973,22,683,446,210,14,372,994,864,780,758,37,75,579,276,596,303,221,149,332,425,263,112,347,244,794,504,412,363,566,748,899,137,23,154,784,294,681,65,306,861,11,931,374,179,541,529,359,126,268,909,432,595,259,312,398,939,6,97,847,757,334,436,178,980,558,538,47,718,550,590,97,201,229,523,8,325,928,545,522,554,219,109,908,418,885,26,975,653,687,906,825,303,690,887,839,140,108,701,423,623,652,889,328,234,575,595,487,603,155,185,746,399,933,650,752,343,929,309,860,321,816,735,432,250,35,607,390,94,347,30,858,936,445,157,420,434,790,582,324,628,610,895,569,99,854,465,877,444,826,29,315,720,391,753,909,833,609,180,272,699,758,75,760,193,394,685,826,358,192,79,364,751,600,103,215", "958,667,530,379,381,753,696,608,961,210,728,302,897,518,724,479,81,34,467,681,951,825,812,869,994,960,35,560,768,291,593,253,405,602,585,560,863,795,464,391,715,973,537,671,978,28,3,367,305,244,573,400,363,545,355,698,685,660,571,935,678,645,483,794,350,420,791,816,26,528,588,667,702,304,368,177,70,82,65,723,421,449,809,372,63,174,399,749,450,255,620,322,889,29,825,187,28,539,789,694,666,117,450,158,47,678,936,6,777,426,315,534,53,451,266,375,706,635,624,352,214,334,803,876,885,478,952,38,375,286,359,129,845,45,505,885,668,369,104,718,416,202,14,99,386,633,842,401,285,446,900,431,671,77,769,420,361,317,760,679,485,286,754,895,882,709,464,546,305,87,190,496,525,210,370,391,534,201,369,42,706,140,819,932,516,617,978,532,833,79,427,249,948,164,741,219,319,891,886,380,606,246,422,504,754,271,587,457,65,549,613,232,465,101,482,113,510,376,313,309,964,323,142,560,682,29,331,954,364,163,712,550,268,547,644,406,99,839,532,324,56,262,803,872,442,459,278,549,772,149,617,156,414,791,470,85,758,120,777,474,615,962,883,218,96,694,750,558,224,691,255,535,204,692,898,18,239,330,951,832,73,472,965,599,66,175,957,268,81,972,212,339,928,666,782,68,800,190,101,111,580,724,432,856,294,463,52,503,227,405,24,760,867,698,611,511,587,751,632,281,932,947,88,826,675,958,169,658,333,740,153,696,14,361,142,219,561,910,605,941,545,38,144,42,267,865,171,809,74,634,779,826,515,492,205,476,768,700,773,542,715,707,401,870,194,781,668,677,808,817,136,684,661,88,860,813,29,323,847,724,285,800,441,280,158,354,309,750,432,38,135,709,142,796,274,147,146,832,233,480,889,287,467,637,536,858,238,907,419,685,400,192,359,463,837,791,719,257,698,852,214,329,992,288,525,537,686,558,730,210,101,616,848,752,509,786,747,987,298,507,9,618,645,720,929,336,852,414,395,976,452,83,834,614,474,961,87,518,611,332,437,596,581,39,53,822,746,818,981,589,303,983,666,886,435,792,876,698,728,288,359,169,868,190,451,689,636,931,641,232,898,730,260,383,615,859,818,736,687,782,136,70,662,948,318,64,663,634,478,216,242,879,866,911,91,401,773,501,574,917,164,887,227,707,850,91,175,943,0,615,794,96,351,251,572,362,679,452,384,448,839,335,867,646,231,139,863,926,98,304,822,737,233,614,239,159,942,252,378,475,524,279,9,722,308,193,110,480,410,763,167,213,727,354,486,984,75,772,451,5,307,342,106,646,5,72,698,329,632,876,383,600,620,84,115,269,551,132,780,33,839,127,638,402,26,316,186,226,707,422,889,409,560,593,20,774,143,534,515,861,671,750,136,161,969,275,185,172,155,766,327,179,9,103,448,534,445,880,725,231,365,566,621,739,29,553,607,484,438,12,342,135,729,538,145,456,996,567,226,817,320,295,976,724,359,274,410,646,28,974,118,719,88,265,494,554,858,387,450,407,84,382,298,365,104,98,15,285,702,773,513,926,329,89,289,925,375,82,987,918,990,981,649,778,980,460,630,390,452,50,581,483,282,288,468,805,829,768,270,181,38,214,853,49,209,47,309,336,669,339,599,221,651,540,692,66,90,696,640,246,88,185,123,10,133,242,267,457,632,151,667,862,329,226,318,976,838,61,864,774,17,976,317,199,804,41,301,91,506,5,988,132,537,737,534,491,241,433,588,349,440,342,486,884,374,399,143,247,267,395,754,316,581,896,732,739,283,723,398,520,685,578,769,970,624,412,47,330,963,495,12,72,42,822,509,913,331,792,807,810,665,6,275,914,964,689,182,272,948,892,266,39,756,497,337,780,221,33,982,637,181,549,224,2,462,38,172,700,835,759,281,271,677,102,350,585,163,45,373,17,328,343,3,593,142,871,706,340,872,993,42,150,606,226,737,518,231,434,410,525,241,620,335,314,304,834,641,385,234,159,66,156,775,65,960,73,452,129,370,372,981,575,783,101,921,732,951,484,623,446,326,666,837,724,522,215,709,987,433,231,552,667,608,445,202,592,421,135,324,876,999,590,961,383,680,183,594,644,5,779,540,490,196,208,498,975,343,245,114,134,918,444,336,617,161,431,806,204,919,755,237,57,421,989,446,47,821,671,198,810,861,188,699,65,89,326,76,515,734,581,629,77,201,744,483,82,239,583,331,905,71,82,8,182,199,394,67,634,136,182", "784,781,366,450,923,587,267,775,876,165,502,445,426,484,907,928,755,857,568,354,537,864,567,8,900,156,504,773,294,640,240,552,686,887,567,858,137,443,251,303,388,685,110,293,134,878,144,393,440,731,740,749,350,399,320,724,454,694,794,406,589,33,905,980,625,728,355,572,767,338,175,431,329,144,467,936,441,831,179,958,85,606,402,960,345,186,68,40,519,594,912,162,486,813,612,744,210,292,34,958,820,909,659,398,893,414,234,207,181,329,909,823,936,895,169,351,296,712,800,39,19,166,187,471,859,287,925,413,629,845,259,603,325,80,735,163,22,971,791,59,888,67,855,934,132,807,691,103,994,220,804,969,975,811,829,822,305,930,896,203,630,366,922,851,227,825,969,47,290,535,715,857,902,671,713,100,215,608,345,533,756,989,180,34,734,990,22,913,945,44,629,609,320,629,690,267,33,887,529,306,282,880,122,591,715,198,749,981,336,610,346,160,196,337,391,92,863,522,335,602,633,624,555,884,580,947,183,475,108,972,8,549,256,492,928,934,422,310,249,948,704,525,531,182,919,123,125,816,861,700,842,531,171,462,54,341,757,589,701,878,644,379,626,386,327,872,769,733,40,429,284,759,782,354,479,748,858,15,89,34,81,672,954,716,319,756,794,458,655,459,131,734,730,192,610,451,438,596,290,967,41,291,385,259,578,835,31,708,775,602,945,395,499,578,515,727,966,247,100,150,289,234,530,565,566,88,1,523,987,297,710,169,72,884,805,485,905,652,451,650,110,953,759,10,448,767,192,953,971,251,319,391,659,966,120,647,417,240,891,925,353,206,87,618,762,601,138,487,38,152,757,728,498,630,431,731,44,563,598,793,282,702,626,49,43,629,686,496,249,4,526,455,649,868,820,907,605,603,136,32,486,955,725,276,727,908,447,451,893,481,889,49,338,138,862,112,92,969,797,485,668,670,576,85,229,350,613,387,957,245,770,816,481,925,734,532,894,528,368,420,367,663,705,307,357,484,468,261,599,425,391,149,732,673,300,162,744,505,233,929,415,138,515,946,896,593,346,626,33,936,985,215,38,18,58,967,4,774,270,897,334,634,445,81,341,823,499,307,557,182,305,344,471,716,187,766,74,27,437,906,584,536,806,551,922,619,922,813,650,743,160,893,792,14,119,941,289,144,288,297,651,277,228,469,328,142,673,466,615,0,645,479,730,550,573,161,841,490,415,861,827,667,753,158,333,263,34,41,540,60,681,18,373,87,424,789,146,252,471,768,954,905,112,871,380,880,522,143,310,711,360,441,511,548,743,103,587,57,331,844,588,799,322,932,825,592,312,481,314,858,431,681,446,460,17,752,509,911,628,697,783,419,357,886,537,296,824,656,21,362,86,357,414,221,694,491,867,576,986,241,202,465,168,431,737,625,299,320,69,39,708,521,14,14,54,29,63,605,732,51,274,173,240,570,3,52,206,575,194,223,21,212,929,458,583,10,395,551,600,710,738,7,81,656,15,342,962,452,143,998,986,507,636,870,48,158,453,562,353,609,100,251,271,275,880,890,57,163,901,656,184,507,296,284,107,10,517,175,386,410,887,716,215,772,837,719,95,213,295,435,973,862,729,827,19,456,755,277,307,725,105,409,700,940,711,323,194,620,281,207,795,407,171,289,990,720,168,919,658,744,273,457,995,688,133,485,651,361,346,956,400,792,718,886,162,276,518,770,471,474,212,648,996,366,965,76,819,452,634,218,769,263,195,374,924,987,728,548,615,908,827,754,193,800,105,559,267,544,265,844,113,690,887,107,280,621,994,904,419,11,702,34,347,312,579,51,79,909,39,814,410,207,967,352,663,835,397,135,501,777,218,411,196,107,342,285,765,75,149,997,979,680,86,712,225,768,175,232,885,933,573,855,466,325,515,911,133,213,995,822,219,793,830,156,418,964,29,821,157,9,425,622,547,359,392,810,419,253,649,892,244,716,739,16,381,743,805,490,110,213,696,842,210,765,905,79,215,538,630,258,553,74,283,556,481,361,380,568,612,206,364,76,744,361,528,134,591,810,587,990,6,976,455,526,257,778,92,856,872,979,97,922,662,318,42,77,284,459,72,3,701,776,344,386,398,596,908,32,954,572,877,412,407,215,817,845,992,349,707,306,656,322,871,944,656,386,519,593,677,107,959,657,32,184,535,519,232,646,816,240,323,295,173,266,661,589,553,31,84,584,629,128,68,530,843,420,154,298,515,383,531,912,116,247,565,332,389,555,675,878", "852,137,822,458,869,751,167,367,862,664,794,175,222,331,442,227,33,853,13,604,567,347,134,244,677,325,572,651,724,613,679,543,573,586,324,923,860,741,79,620,354,509,77,346,687,962,31,652,989,960,756,160,64,219,459,922,623,446,164,408,410,476,280,624,415,104,409,917,150,943,380,464,551,939,238,615,799,465,942,558,169,764,735,200,591,585,975,252,774,320,518,410,52,627,505,493,210,478,517,650,308,515,936,996,725,672,663,144,998,697,226,971,431,691,285,117,47,181,346,37,217,461,581,687,305,547,62,15,82,980,961,25,939,631,86,885,366,360,999,700,998,610,507,573,233,362,467,102,710,607,502,324,95,640,793,656,412,543,860,453,332,578,587,694,833,43,488,496,448,644,64,59,563,576,737,402,539,766,963,366,385,733,849,407,967,70,436,23,587,332,894,874,797,770,766,78,227,115,793,166,429,464,773,744,565,131,397,998,590,827,398,546,234,867,920,222,844,375,328,344,558,807,471,840,529,821,991,878,776,768,339,821,456,992,216,356,594,255,322,28,725,635,554,88,93,676,950,92,144,271,171,753,909,337,837,554,95,339,604,846,518,226,100,213,333,64,687,203,300,91,319,672,728,900,697,865,736,349,378,909,358,568,613,113,814,341,407,791,359,77,237,615,903,424,82,871,561,56,694,545,250,800,924,569,180,518,105,378,576,582,543,374,565,329,823,545,411,297,415,488,360,18,482,205,961,15,542,60,446,945,569,235,949,673,870,520,505,45,184,522,409,585,710,424,812,443,423,425,89,879,44,788,272,692,993,789,991,83,118,730,464,950,407,425,173,25,997,529,997,394,253,404,520,228,861,905,125,919,714,121,332,486,216,411,775,440,31,363,482,967,965,118,268,996,415,594,608,849,428,343,35,441,833,533,486,997,655,826,924,864,123,889,604,405,718,392,977,162,722,836,927,508,702,771,363,936,874,253,756,930,306,295,489,456,454,940,858,778,157,494,318,267,508,54,524,561,879,795,447,274,43,966,838,774,49,759,104,11,813,97,788,834,899,138,221,63,844,681,873,830,334,995,58,551,862,459,715,896,917,74,705,770,799,169,733,843,906,378,63,618,319,749,262,564,424,216,381,451,478,990,213,519,987,373,451,342,37,681,384,160,936,729,535,981,962,910,3,220,661,712,539,94,650,335,326,347,51,945,794,645,0,872,446,196,137,175,1,451,576,18,965,900,104,723,394,660,942,634,606,927,668,739,444,468,481,918,786,997,796,415,724,748,636,665,164,721,789,361,746,3,876,455,885,764,231,208,107,375,501,226,739,455,233,94,557,386,399,509,740,300,943,483,707,90,773,790,305,921,749,658,865,556,335,896,871,735,909,78,568,817,155,774,677,424,911,745,405,733,462,447,220,348,625,14,348,364,394,448,291,11,496,661,107,954,478,454,385,660,593,469,908,695,469,508,71,297,236,572,127,316,205,264,483,750,897,222,671,574,726,967,515,913,407,500,284,97,579,19,251,875,926,978,508,336,161,987,994,519,851,202,426,820,236,841,820,387,486,760,190,745,742,170,894,608,447,187,704,913,606,594,983,67,377,49,290,453,415,410,659,691,65,400,686,451,150,992,424,764,642,186,23,855,158,643,501,982,367,117,791,355,272,246,925,882,571,143,856,490,691,628,787,152,987,593,70,13,484,664,258,894,117,714,116,312,746,889,71,424,333,527,895,168,582,679,387,816,861,379,933,959,469,141,503,481,884,528,208,926,262,233,522,126,50,491,19,258,697,800,195,801,746,882,638,761,35,447,49,2,764,429,251,21,769,479,153,746,633,221,775,497,329,593,747,528,455,336,325,694,62,715,306,730,217,852,764,941,873,880,886,149,693,422,953,832,187,396,36,714,187,713,353,94,326,604,373,34,620,647,548,524,554,5,343,952,9,172,912,994,698,61,438,137,338,184,635,724,358,983,973,933,50,364,398,490,507,887,324,436,868,777,882,894,805,484,755,640,66,292,640,385,96,558,670,583,260,557,973,234,107,76,648,656,343,102,530,563,763,534,68,245,661,399,900,723,599,584,967,104,361,244,366,111,894,423,247,204,931,986,847,690,669,450,834,682,110,872,504,938,201,417,19,749,151,744,103,469,435,22,65,842,864,721,940,38,338,852,65,989,969,222,903,556,156,937,816,543,595,157,736,686,154,719,264,409,766,650,118,181,266,67,718,332,4,327,771,218,763,873,137,950,238,29,806,661,413,407,457,364,282,273", "817,842,203,28,307,573,699,320,100,770,618,155,366,633,618,802,447,663,201,166,632,937,460,960,503,215,440,444,213,593,428,773,583,4,943,219,501,369,5,129,462,24,297,881,283,180,700,750,564,127,948,685,790,63,232,973,290,907,425,574,347,665,24,459,175,695,143,93,460,829,624,224,580,330,520,930,27,328,771,87,792,475,463,688,78,913,212,489,460,55,839,824,900,320,450,217,590,206,855,977,697,669,290,228,755,641,303,437,287,211,265,127,372,410,857,971,943,857,302,44,555,80,49,680,319,297,291,624,782,788,378,415,567,365,26,166,104,555,811,513,330,924,646,831,487,622,153,136,30,954,136,173,245,846,181,740,155,728,380,233,524,17,224,9,235,69,634,562,542,121,707,176,54,636,135,186,491,911,258,962,152,185,252,992,100,188,507,540,360,749,778,795,599,536,960,64,532,721,818,141,663,993,820,974,547,480,116,303,516,377,197,332,455,480,217,942,775,835,914,481,938,897,196,240,1000,441,606,375,689,639,534,676,483,749,926,981,500,427,554,493,736,177,3,986,512,767,255,639,384,556,380,511,601,781,874,502,547,824,386,642,167,70,668,968,100,768,372,511,681,230,909,726,287,607,876,624,581,847,784,627,405,304,756,719,667,492,991,44,772,67,425,502,223,63,307,204,396,646,471,943,884,167,484,746,22,404,714,852,448,498,904,637,806,528,669,80,475,159,156,558,88,646,733,658,991,404,544,497,503,351,216,604,269,695,291,296,54,638,783,612,290,581,399,466,856,257,589,155,67,821,852,237,862,695,538,780,57,621,505,272,548,627,378,782,245,599,970,55,8,865,405,714,556,339,870,17,627,748,231,226,667,399,521,782,311,273,573,860,126,607,745,698,766,932,541,90,79,745,769,81,953,92,22,95,786,367,235,193,986,612,858,234,595,597,163,227,45,170,85,849,583,347,303,965,897,700,108,22,906,468,85,158,99,6,843,942,249,849,603,695,368,697,63,79,991,651,737,441,588,39,993,697,715,829,186,966,290,726,218,558,746,497,98,900,418,379,642,800,329,573,613,821,211,170,209,145,468,790,905,895,227,209,110,904,695,966,498,523,466,988,553,210,462,805,173,574,527,825,643,661,344,383,546,323,940,886,583,249,539,887,1000,721,863,370,307,653,999,470,576,258,939,40,470,936,957,549,840,151,96,479,872,0,325,582,647,98,590,508,660,346,897,764,885,664,947,774,498,708,765,437,158,310,883,988,311,998,778,727,562,662,900,402,145,255,799,612,830,459,266,602,164,991,225,819,309,606,795,454,166,672,321,632,605,719,344,133,560,491,368,469,826,356,501,914,273,502,841,623,483,80,71,772,264,347,191,303,307,243,764,690,965,650,190,860,714,606,206,398,968,400,100,210,616,957,750,989,435,312,679,827,945,727,709,572,520,941,583,460,106,968,797,148,499,684,478,136,264,478,471,971,493,133,498,215,971,673,821,867,727,942,803,832,371,960,165,403,973,456,130,33,483,783,186,92,289,555,293,941,982,218,983,748,366,696,729,220,302,462,522,681,893,897,325,290,170,663,837,446,250,323,356,508,266,760,619,675,91,592,116,939,778,374,20,841,439,953,702,684,250,904,530,457,352,899,99,165,109,426,627,694,508,196,632,928,648,984,631,811,377,549,808,31,839,369,246,107,818,489,902,973,392,832,957,136,645,411,438,57,603,319,485,186,230,437,133,211,208,612,382,527,115,592,542,209,312,233,187,447,972,869,730,223,476,368,23,439,634,320,516,96,220,716,666,974,614,927,63,855,613,648,591,727,190,478,342,278,305,660,564,856,821,514,128,850,420,576,208,346,365,345,106,779,189,201,541,793,993,400,183,455,452,671,28,332,918,647,730,694,952,388,590,840,638,912,969,233,591,826,288,495,938,395,255,472,200,961,555,718,771,154,146,268,938,183,328,149,200,526,621,649,494,513,342,117,150,289,903,210,309,241,139,847,453,20,866,404,41,832,124,210,943,411,172,385,128,913,411,852,708,23,455,756,477,402,970,986,807,205,98,822,421,58,619,480,811,358,903,446,147,491,232,22,950,264,271,348,206,966,108,625,361,669,928,988,118,906,374,954,712,444,298,569,22,496,808,123,521,886,74,601,412,289,110,947,573,439,994,964,91,701,151,977,646,293,787,24,463,857,480,501,846,360,367,220,102,598,913,143,324,611,837,892,217,677,114,223,994,785,851,503,134,892,42,737,986,775,913,154,550,645", "835,79,704,899,21,947,775,980,417,60,915,588,49,920,311,604,575,936,581,286,690,378,857,367,399,958,733,748,945,845,335,718,657,130,239,118,839,188,711,459,268,929,889,557,740,203,75,105,392,194,524,529,760,732,476,173,150,330,311,313,477,715,646,900,6,182,957,154,543,378,880,476,180,984,593,570,843,988,168,24,832,593,692,179,39,6,40,670,479,258,938,255,730,387,524,278,496,228,963,45,380,210,512,263,9,372,970,537,9,166,996,593,710,573,785,36,121,224,128,623,672,357,265,766,553,360,539,788,533,239,436,3,895,231,544,921,452,728,213,540,145,694,63,462,107,392,825,616,368,279,165,50,559,94,361,50,227,17,853,140,56,660,899,522,760,115,805,922,175,840,334,699,857,503,827,322,206,948,380,230,997,352,131,576,558,702,351,741,54,381,171,558,375,240,843,554,955,279,293,817,176,83,704,183,96,572,693,478,569,264,998,900,546,877,37,915,725,741,274,400,557,793,534,96,335,464,226,886,25,419,101,16,226,213,917,338,378,714,302,225,490,2,621,497,3,4,856,815,401,681,137,817,247,415,824,872,768,832,735,463,979,509,503,620,977,471,333,716,580,505,330,69,799,514,137,259,31,995,600,572,398,978,771,741,391,113,53,435,985,660,472,664,637,727,813,829,958,177,600,431,99,516,23,576,94,472,38,532,78,629,668,427,803,268,679,663,704,618,22,1,562,290,418,432,554,694,723,806,988,162,133,523,979,873,997,209,661,604,594,665,380,522,151,638,833,467,769,585,640,167,340,515,480,705,815,153,154,224,949,422,87,99,339,721,864,325,248,339,421,281,269,28,711,300,124,28,518,701,712,801,514,492,25,829,397,62,558,412,678,27,801,814,441,53,148,779,713,254,250,101,506,730,231,596,596,890,505,831,282,474,51,120,6,763,387,377,944,862,743,638,941,45,645,983,761,213,157,901,810,733,341,455,379,819,153,121,929,321,948,428,925,739,856,122,126,357,20,809,365,296,634,487,262,456,316,55,602,723,904,469,972,435,502,349,10,201,107,380,678,921,314,342,879,875,410,694,587,742,818,126,863,346,650,989,415,831,839,94,389,619,845,984,900,154,512,25,186,344,467,261,193,913,422,273,948,365,150,134,547,391,581,993,475,955,89,866,282,345,640,686,386,475,313,752,693,41,463,679,351,730,446,325,0,298,614,702,376,468,14,553,744,586,465,383,522,582,532,653,744,184,183,199,246,295,65,338,705,348,793,632,989,295,726,598,901,584,633,754,375,343,927,431,924,426,586,552,177,213,929,947,62,203,957,713,964,212,129,561,773,277,450,865,231,87,937,275,682,708,351,672,893,397,28,76,805,484,517,151,280,888,697,400,746,420,546,163,932,1,180,742,331,928,845,426,817,599,125,3,725,926,959,218,467,583,796,147,125,484,77,482,57,558,563,878,615,836,897,449,634,179,710,259,617,623,133,529,642,96,7,726,4,694,525,41,995,398,104,31,727,408,800,990,762,555,148,897,854,421,857,212,75,430,286,655,629,369,161,352,122,439,681,369,914,39,346,874,789,33,36,431,966,848,230,151,320,617,976,610,34,170,561,36,130,459,456,853,717,163,286,125,583,838,153,623,325,475,205,99,198,310,773,496,557,477,552,721,181,209,85,205,493,179,929,705,366,970,148,805,546,462,53,614,380,48,140,961,80,404,595,578,13,980,351,396,705,8,685,980,245,525,725,989,528,50,960,67,39,485,647,990,623,520,639,561,698,904,306,54,742,5,528,403,561,717,756,460,651,226,280,168,623,369,715,974,226,386,924,484,214,457,742,196,92,789,776,138,436,17,507,730,713,550,489,322,125,619,151,967,240,423,312,51,259,848,227,922,845,543,223,43,725,629,885,376,475,470,564,530,417,508,398,384,538,111,364,422,847,726,732,485,727,359,948,949,771,690,766,734,590,268,191,201,298,42,661,331,609,364,249,476,501,406,897,643,492,804,938,273,248,189,884,358,465,571,841,553,326,142,283,808,34,179,490,614,834,233,714,482,427,325,116,781,339,447,52,281,348,35,386,970,541,287,444,976,565,864,259,44,726,750,858,163,877,348,20,620,629,739,781,490,545,278,475,281,19,971,238,164,343,908,398,831,488,177,33,131,906,55,635,45,154,936,202,32,899,898,364,76,771,838,896,367,191,324,943,805,76,3,975,157,927,330,876,350,204,163,283,472,811,848,265,829,311,415,913,229,458,398,690,126", "829,937,449,169,469,221,723,478,548,884,205,718,177,226,106,479,33,943,520,724,213,754,130,870,296,101,812,881,145,729,862,918,485,454,976,641,585,978,819,516,485,890,830,386,768,776,618,48,447,899,452,121,999,698,563,998,798,282,34,848,17,613,516,495,6,865,806,695,224,384,532,52,560,752,688,787,636,967,738,882,888,681,643,383,722,776,599,954,538,512,650,395,232,55,17,169,874,268,746,470,193,796,32,94,254,806,604,293,638,912,107,631,385,568,913,193,921,271,328,987,123,948,966,895,991,491,980,598,97,325,836,514,12,924,809,899,151,577,703,668,991,602,905,921,258,225,903,520,240,290,466,302,920,859,157,391,742,103,594,92,805,906,581,787,529,430,944,302,769,690,612,112,671,69,328,268,497,203,925,484,879,600,319,13,437,20,402,208,582,570,485,325,944,707,273,179,107,623,440,416,202,966,768,250,156,997,642,761,58,586,274,197,105,941,752,779,439,799,427,645,24,894,260,383,125,141,787,229,244,386,168,263,13,129,651,303,391,702,538,370,892,589,766,726,49,743,797,80,117,671,875,73,237,69,187,788,42,660,44,964,322,783,424,4,340,427,686,838,184,921,579,237,225,26,520,94,179,735,771,186,21,989,126,111,303,292,6,373,947,550,228,718,384,863,267,557,916,284,660,374,56,400,393,320,892,963,217,59,121,572,898,659,329,466,600,558,572,208,2,890,539,982,164,751,26,64,73,124,222,794,178,806,864,923,74,280,443,676,930,901,131,147,281,369,716,310,778,39,961,215,582,10,91,401,800,135,633,108,565,102,699,874,203,542,394,43,582,187,868,391,715,429,700,274,368,613,892,165,813,905,960,499,606,848,801,754,918,564,597,320,531,402,447,795,584,643,818,236,950,990,567,975,710,785,515,806,961,699,120,726,512,741,321,641,32,389,223,625,338,316,528,517,743,576,632,70,512,395,104,139,888,676,996,480,129,40,48,308,201,40,479,318,993,553,923,912,346,433,572,852,392,360,210,366,804,277,139,525,263,654,747,826,417,751,548,984,893,937,99,961,326,249,138,54,214,919,496,680,89,517,551,224,186,819,197,347,67,614,222,107,28,938,31,138,960,489,927,429,41,249,518,292,490,364,54,422,449,141,461,114,964,591,257,196,752,77,928,608,884,922,683,519,414,224,878,448,113,66,251,550,196,582,298,0,906,575,457,953,32,225,383,157,725,882,707,633,858,153,219,408,707,729,88,466,545,991,235,734,336,781,542,128,111,560,592,968,72,200,340,511,653,260,928,643,568,663,916,574,288,325,86,591,706,876,189,807,255,623,250,47,304,164,572,783,674,470,375,765,355,329,696,241,37,849,111,403,490,780,275,141,845,625,521,169,688,268,369,512,687,518,455,124,981,8,382,807,233,988,374,108,34,4,8,904,487,167,919,397,476,630,940,906,810,489,219,245,267,271,775,149,672,103,262,405,99,219,936,974,349,272,701,372,211,610,141,968,301,534,243,183,526,677,387,345,953,671,542,993,935,503,883,566,29,560,8,567,785,752,390,767,801,965,116,370,797,264,570,663,700,562,355,353,263,468,78,35,664,623,54,940,284,199,449,627,714,445,24,511,794,741,734,895,144,862,600,614,832,589,781,206,396,405,348,556,583,27,520,782,387,702,456,857,79,949,234,656,523,431,585,525,667,211,263,222,588,638,312,581,175,589,242,686,171,979,871,403,587,138,865,248,839,477,177,274,299,361,28,867,464,279,15,897,200,248,756,2,783,625,484,389,757,503,887,645,193,488,642,867,422,928,370,481,610,76,268,816,738,542,910,581,289,575,365,434,793,868,871,219,549,170,168,581,628,432,477,731,765,865,355,485,850,436,298,875,582,568,893,954,790,253,626,909,527,418,101,937,663,229,51,91,720,471,336,963,425,880,643,216,70,449,101,929,673,521,45,77,245,878,940,85,904,964,271,992,887,297,400,346,351,472,304,168,91,426,383,707,38,606,165,280,576,487,794,803,563,68,393,271,640,953,293,571,821,975,326,695,612,753,815,178,588,949,848,981,576,573,562,628,115,20,969,862,177,587,695,702,849,671,303,193,568,58,357,221,960,416,539,388,752,803,630,381,694,774,285,747,958,972,233,852,792,223,871,142,270,797,559,521,535,987,646,116,395,489,223,11,564,31,77,475,500,36,287,918,317,54,649,689,261,866,529,934,161,816,532,327,123,944,69,8,786,667,685,251,243,252,542,980,680,619", "911,810,665,627,992,624,274,217,423,394,675,803,177,766,321,222,422,410,811,206,675,475,818,755,255,385,832,704,885,272,126,713,886,403,121,852,125,576,411,879,875,335,980,961,835,773,281,863,100,943,575,339,736,465,740,206,468,681,726,227,138,446,460,42,330,9,381,580,300,265,354,917,177,374,651,210,832,714,740,770,390,799,307,410,805,479,898,458,277,814,689,299,502,350,289,186,92,325,511,709,842,167,794,341,925,438,163,114,326,59,923,956,447,169,413,631,832,256,177,251,752,611,73,896,59,910,399,58,708,134,247,724,780,498,657,257,833,160,190,739,548,347,766,209,975,549,696,505,553,947,212,826,90,92,211,24,458,717,364,446,368,216,789,142,340,322,697,324,291,381,958,293,722,815,378,54,834,210,381,943,719,10,528,689,410,142,123,715,20,909,411,553,69,294,203,996,295,874,532,235,44,975,546,992,598,416,85,682,703,225,529,801,817,375,412,710,98,313,508,494,1,499,563,859,782,272,876,413,639,725,214,794,385,199,731,779,297,872,578,382,617,359,401,645,500,900,916,898,252,261,608,922,711,933,601,640,575,703,954,378,99,941,453,766,916,564,474,653,768,6,503,511,698,91,742,807,189,144,219,211,984,630,626,819,195,365,778,79,389,599,204,330,907,622,394,805,393,711,791,722,124,265,185,140,920,573,344,811,920,31,262,587,211,24,778,993,923,504,337,778,821,223,925,939,758,349,779,194,504,396,552,171,175,236,459,43,98,522,21,332,130,255,16,287,754,644,300,892,38,462,696,456,497,597,519,104,112,355,96,68,624,130,600,356,690,321,740,227,903,510,324,683,628,11,689,825,718,352,672,976,854,985,901,727,561,816,185,749,816,753,710,808,255,189,66,562,681,628,650,102,933,553,103,881,889,828,942,782,363,80,278,51,198,294,742,620,25,362,983,974,950,539,682,587,17,606,537,313,299,521,345,241,657,139,653,329,646,724,781,386,991,521,99,831,20,887,45,647,744,570,181,515,933,470,756,558,115,981,124,195,338,218,702,38,888,600,42,697,269,997,404,98,479,214,95,111,3,144,37,37,991,435,271,765,804,341,168,460,164,761,138,908,390,159,779,561,52,127,207,756,568,16,770,910,716,588,622,878,633,693,670,326,122,280,311,748,118,67,558,192,445,476,770,137,912,525,648,204,572,573,137,647,614,906,0,370,984,879,702,29,931,78,991,190,832,402,398,647,64,289,47,96,185,907,383,487,251,504,410,350,44,686,1,765,471,767,770,188,355,383,871,519,934,56,795,661,616,711,507,625,252,980,613,36,741,784,603,921,181,779,552,627,424,960,102,581,168,608,34,626,143,8,790,847,267,813,702,153,789,800,498,992,139,150,530,332,598,41,445,351,73,280,812,573,9,652,570,352,411,18,76,782,741,643,687,976,572,838,187,386,831,527,840,257,317,821,144,84,307,400,746,400,937,911,604,374,119,379,215,424,244,63,433,647,715,193,729,870,898,497,542,918,552,698,388,902,375,320,732,546,627,642,56,491,223,469,373,756,596,932,427,7,676,122,869,853,189,978,278,183,174,207,354,336,860,838,377,768,117,246,104,35,535,953,585,208,535,254,701,588,690,336,446,703,153,645,106,964,926,389,168,238,214,74,868,651,437,853,801,980,365,12,299,545,917,125,791,893,466,485,971,710,874,381,806,756,922,647,309,273,36,874,377,547,450,999,560,310,621,440,943,87,553,370,83,997,397,26,781,526,331,509,584,205,136,659,964,882,989,228,619,354,238,175,482,23,619,526,960,810,136,638,216,123,232,935,615,895,831,846,402,813,605,453,432,327,928,615,268,341,799,593,737,862,882,178,508,605,949,509,221,675,117,237,575,205,616,137,798,861,739,95,266,726,535,716,302,450,151,626,404,898,372,188,627,694,239,608,858,866,994,505,717,555,489,845,236,120,335,21,611,863,371,582,791,292,111,901,908,759,260,495,371,490,483,351,4,770,589,359,296,16,143,882,395,258,234,169,408,716,193,713,595,806,274,37,930,190,258,256,950,431,58,581,396,333,649,726,668,661,289,330,279,482,413,782,1000,471,920,486,629,364,551,322,247,299,100,565,77,837,389,460,30,752,726,756,854,321,746,888,720,463,470,412,186,964,208,547,3,360,81,448,267,107,308,945,946,402,9,355,800,898,211,127,136,242,455,493,336,683,821,541,153,45,577,574,271,485,681,558,293,811,684,185,983,177,740,512,308,628", "254,56,158,879,196,363,910,344,462,127,682,615,907,981,849,758,915,480,100,173,76,130,230,146,806,530,11,951,239,870,921,122,271,260,263,753,170,577,893,752,650,472,191,933,810,609,424,611,626,924,917,876,258,566,645,603,342,508,876,949,351,548,744,844,468,871,866,49,371,415,353,157,920,989,801,886,766,190,992,557,296,161,102,985,997,225,345,148,541,80,853,368,995,487,5,946,675,578,353,812,384,390,100,904,585,560,339,607,623,530,549,176,155,835,530,323,294,235,884,65,107,930,406,684,544,916,433,971,32,331,461,931,232,392,169,185,114,913,457,703,697,171,296,269,730,599,73,483,320,379,147,99,187,190,508,347,533,35,901,730,748,159,365,759,604,698,2,623,504,133,856,187,511,377,885,158,476,593,45,148,109,574,158,18,989,348,749,808,446,273,239,939,442,685,809,832,760,839,734,98,286,350,851,765,594,920,278,327,257,337,83,861,265,948,326,777,743,659,410,382,518,639,516,65,225,237,608,255,842,324,717,599,3,744,999,104,956,230,284,398,265,781,502,574,668,258,249,366,206,390,436,252,269,314,74,394,704,772,42,629,392,384,756,687,212,936,439,418,744,213,306,230,633,201,368,689,75,970,634,886,688,647,831,171,418,546,618,610,539,348,808,464,579,936,477,402,916,110,694,159,776,206,343,729,895,10,356,856,247,665,777,586,659,541,203,117,55,450,411,33,179,548,656,275,799,494,214,348,178,715,553,117,43,417,434,870,675,702,373,190,841,20,509,154,961,97,922,92,670,95,715,811,10,766,188,708,937,250,370,857,63,845,798,52,442,595,885,560,28,340,136,907,884,254,121,698,248,998,702,968,254,274,907,839,757,304,351,974,758,25,65,178,467,939,911,224,981,313,517,614,29,906,215,602,65,605,472,127,202,186,920,997,624,923,709,835,323,726,771,167,608,950,850,8,293,643,622,688,8,523,411,490,485,357,160,670,325,808,878,215,781,93,838,250,600,300,955,114,746,936,302,481,156,702,256,163,145,91,823,38,634,64,771,5,935,805,42,520,401,613,809,372,23,794,967,699,41,788,55,789,597,40,742,434,169,350,76,541,544,971,668,307,910,381,746,650,622,541,743,15,762,569,409,23,430,518,449,473,409,447,57,852,268,623,334,188,588,996,476,734,41,597,309,430,875,900,208,981,362,161,175,98,702,575,370,0,706,986,332,592,894,705,252,715,406,936,735,120,674,106,231,850,25,145,435,160,923,776,568,143,628,33,429,790,859,144,918,782,610,923,506,463,460,765,371,523,393,363,747,493,436,50,948,972,372,129,477,942,655,808,243,968,437,374,643,930,292,305,710,722,934,17,387,78,499,44,547,608,487,460,314,539,856,185,373,589,583,372,608,289,631,558,416,505,420,56,763,966,199,426,566,857,970,890,431,50,506,189,276,285,645,347,519,992,559,867,362,598,94,879,764,901,45,10,836,932,987,405,336,539,90,390,717,485,398,411,949,743,881,203,655,713,145,119,498,728,663,843,502,887,972,188,462,907,343,852,206,862,412,849,553,410,400,18,368,206,419,303,55,457,860,436,5,992,14,435,714,36,836,684,702,455,948,347,26,747,570,854,896,581,880,960,453,498,406,532,884,377,764,852,560,611,729,447,227,397,29,112,717,237,898,712,745,926,959,132,114,463,34,756,979,393,602,815,510,106,64,188,907,866,857,990,435,359,206,223,466,159,939,955,949,635,775,826,737,222,500,262,334,793,772,879,758,519,157,370,682,596,275,567,167,476,931,571,961,39,704,894,222,466,487,410,183,248,641,458,934,7,218,956,624,328,19,77,682,356,214,197,896,939,820,906,412,225,140,230,287,277,772,387,728,163,236,703,125,309,955,318,421,250,272,547,739,885,155,8,538,741,621,498,125,918,519,906,797,858,703,974,364,638,980,610,937,749,398,291,406,926,822,95,889,72,578,93,112,466,235,937,428,680,926,685,106,797,359,812,121,796,302,89,81,520,670,131,864,64,129,627,523,721,654,593,543,184,17,739,316,546,460,396,734,66,272,210,542,354,752,982,186,296,577,634,746,231,656,474,683,196,279,429,440,54,690,534,274,691,568,194,247,725,643,675,789,71,317,698,275,767,944,316,422,534,112,428,800,206,694,372,708,124,51,695,142,198,347,293,213,800,97,168,773,149,904,260,330,707,364,168,965,449,242,224,279,626,805,39,844,875,272,957,953,800,126,450,117,759,720,81,68,35", "917,179,322,97,617,693,535,820,298,512,134,292,649,422,156,618,215,407,152,169,9,76,476,727,411,164,913,940,150,953,511,936,884,980,217,808,46,433,762,776,101,775,263,292,531,6,450,883,777,599,606,789,943,360,766,195,493,720,938,587,108,57,244,359,163,645,246,236,921,166,172,787,514,128,449,478,44,674,711,136,122,850,648,164,504,65,878,592,214,282,33,838,994,721,816,346,701,81,805,411,286,792,547,252,113,949,488,547,225,910,418,365,621,501,256,68,274,189,989,168,138,778,535,21,492,439,785,50,345,702,580,920,117,581,764,765,53,227,334,630,596,797,993,927,300,774,159,150,809,828,123,603,358,729,891,560,457,31,766,756,297,221,730,973,863,533,769,418,530,697,134,572,594,739,930,734,760,156,192,598,261,565,64,596,120,157,108,688,967,955,745,426,193,397,554,770,73,628,660,755,539,327,631,261,141,8,480,562,371,172,776,32,773,708,745,779,548,349,693,866,153,650,93,233,871,691,901,85,90,998,149,150,66,852,679,635,43,100,402,95,777,543,700,42,179,208,908,513,241,622,62,786,699,393,915,18,395,391,897,235,869,310,796,578,825,705,395,315,950,161,962,940,234,975,791,40,938,684,528,289,594,253,145,769,737,841,493,770,595,816,649,866,407,244,36,453,20,98,648,851,745,278,563,731,191,764,623,302,374,110,542,897,547,185,725,249,424,944,930,577,643,594,480,961,93,535,989,787,371,936,893,522,998,917,975,170,899,324,808,420,52,92,688,922,786,479,298,748,766,878,996,664,834,254,983,905,427,462,467,550,86,244,714,761,10,423,928,830,965,846,630,454,118,740,134,986,632,48,997,682,23,402,942,976,795,175,43,479,687,869,921,126,773,244,241,997,578,905,440,565,495,958,165,141,486,228,884,416,272,54,832,86,577,869,498,703,874,907,257,697,643,984,404,559,623,941,615,83,460,283,400,581,348,620,617,879,353,789,956,751,84,474,36,56,284,911,484,221,983,889,522,917,656,69,198,747,733,841,489,818,288,740,649,860,125,594,507,443,476,448,38,997,563,796,374,752,466,178,377,711,381,77,403,775,771,808,404,592,14,299,16,693,619,534,890,644,511,901,472,326,160,947,868,75,230,25,8,228,798,510,450,501,576,257,222,541,803,958,678,43,796,183,921,835,33,17,795,8,679,841,1,590,376,457,984,706,0,178,535,19,672,827,664,783,158,89,178,914,934,664,80,575,119,606,551,787,993,827,484,76,59,854,922,589,606,557,452,922,436,597,445,743,329,271,961,352,983,544,469,110,481,801,893,371,729,83,578,293,328,564,415,421,782,171,266,677,528,266,441,328,941,310,253,17,500,482,907,912,524,266,46,939,318,762,250,97,382,637,244,273,52,854,156,667,801,78,46,86,809,67,384,650,959,156,40,47,276,143,942,629,423,2,53,757,241,83,871,877,952,336,215,1,364,531,962,618,139,841,310,270,777,449,50,110,325,399,838,893,766,288,284,340,54,248,440,201,532,486,888,85,116,373,232,613,84,529,196,716,151,702,828,360,177,634,246,716,665,117,514,467,888,750,162,656,127,823,192,334,285,982,350,737,727,295,181,265,705,441,593,978,714,532,478,751,952,372,647,226,442,532,474,858,703,205,530,4,585,564,667,440,420,874,295,135,196,407,320,277,671,216,242,736,302,508,777,323,575,984,85,845,947,895,816,578,488,868,655,145,23,141,683,556,369,254,776,511,141,520,423,551,353,278,994,527,989,346,446,981,776,967,844,766,956,682,398,48,969,876,332,985,598,476,787,799,996,799,737,437,760,636,378,76,21,506,788,646,23,828,334,899,337,357,618,703,923,730,906,842,502,38,445,205,735,672,728,546,487,19,483,461,417,598,101,210,12,531,170,874,367,327,770,795,909,638,945,621,238,368,765,802,262,367,513,96,727,461,794,216,698,19,510,707,480,943,352,486,715,393,660,136,842,116,986,995,282,769,274,875,650,476,237,417,950,439,429,701,861,788,480,104,876,593,549,170,958,157,560,518,215,927,211,57,993,703,269,650,516,793,936,746,469,949,44,593,35,675,516,778,85,718,268,298,355,338,830,188,318,253,223,677,661,193,590,959,575,884,672,459,923,357,758,823,286,335,570,442,803,384,653,61,558,808,761,661,617,750,165,197,932,128,758,203,56,953,372,797,467,110,330,188,64,485,876,866,112,910,222,514,285,631,40,471,861,948,381,542,682,360,952,405", "706,335,293,84,598,442,893,636,834,403,82,686,653,821,307,20,331,296,797,759,169,148,79,867,991,236,675,30,305,298,293,35,669,7,283,303,277,906,885,647,224,455,42,22,652,405,624,706,874,490,54,558,713,68,794,823,407,802,896,986,240,746,399,543,618,439,563,216,377,128,466,660,21,253,746,666,104,272,239,898,258,194,549,288,92,586,3,581,266,603,468,172,628,938,136,557,280,896,838,772,37,394,268,884,480,383,245,808,824,332,557,752,481,701,401,222,984,599,189,714,426,116,502,936,117,630,983,792,758,144,455,436,332,277,897,611,624,394,888,93,481,447,883,175,399,929,405,969,956,811,276,633,330,188,835,438,144,870,245,830,105,265,343,131,522,578,662,867,10,757,398,752,861,866,788,571,497,507,660,342,794,858,288,784,322,500,743,798,604,626,452,872,663,535,277,421,374,901,778,724,394,197,212,332,678,496,700,846,619,261,922,592,586,100,724,716,361,257,791,303,744,729,511,249,610,359,634,535,676,491,155,504,850,508,448,891,971,249,155,81,306,537,308,591,344,216,697,448,956,582,822,830,239,823,287,958,741,981,273,690,112,110,882,668,339,570,532,51,970,375,555,814,640,531,286,138,34,242,776,894,178,174,30,271,124,137,642,480,105,846,63,888,365,563,808,976,160,409,416,986,269,716,433,726,444,627,12,549,868,716,665,673,505,329,469,677,775,24,919,589,843,946,400,889,739,246,982,908,69,912,498,529,1,277,841,190,638,891,187,338,646,951,675,126,766,135,908,914,461,621,370,430,780,983,646,655,551,639,887,438,57,321,488,543,408,553,338,548,876,498,923,736,556,187,331,143,301,190,582,580,840,744,729,16,413,360,140,538,851,332,245,355,713,939,784,837,233,602,500,547,2,801,627,496,453,521,973,990,907,336,2,522,889,560,48,896,28,899,546,358,879,415,241,345,984,212,364,558,843,727,684,962,615,369,494,151,552,961,455,951,84,875,480,878,137,168,457,864,698,554,621,938,823,748,758,887,737,628,523,994,815,3,185,709,571,114,714,942,888,76,243,321,290,824,178,558,389,689,802,926,839,777,302,784,666,519,158,805,275,942,361,177,640,476,434,313,315,759,58,451,710,493,137,549,769,124,137,857,217,698,104,698,14,627,687,557,202,526,348,229,461,25,340,989,643,345,757,909,452,490,451,508,468,953,879,986,178,0,501,570,791,120,644,646,281,842,489,621,670,320,759,150,752,929,456,740,727,158,546,38,32,460,196,981,297,745,297,233,183,163,302,221,695,799,511,757,438,989,627,931,827,280,264,459,152,56,155,502,803,243,660,511,398,458,658,719,954,183,90,110,49,98,275,856,649,587,468,275,376,739,559,726,549,460,430,992,958,80,987,28,54,366,455,96,822,38,720,652,583,502,507,773,555,134,561,614,894,815,866,286,484,526,479,54,66,693,490,305,877,169,83,463,147,673,832,902,498,448,610,2,554,593,179,720,653,46,21,514,84,648,992,587,730,346,987,702,688,883,687,344,393,182,260,495,414,180,816,678,808,669,534,250,484,717,580,617,475,262,826,875,872,464,52,45,433,797,759,853,486,580,395,567,833,367,402,13,471,852,775,224,141,334,827,605,771,446,758,52,613,430,877,172,31,742,532,685,150,929,751,107,621,156,698,200,325,445,807,338,820,559,216,769,403,925,780,89,178,663,274,300,999,507,614,561,583,324,572,308,621,439,843,871,970,245,449,943,432,970,885,178,207,277,47,172,178,923,494,663,625,509,344,59,530,732,588,512,832,525,559,988,387,838,757,99,93,331,794,515,27,622,306,32,556,946,539,107,805,876,910,201,820,782,967,840,750,722,595,606,116,947,85,481,970,454,336,553,540,200,519,144,152,722,193,528,548,434,853,99,199,698,284,997,732,900,506,712,699,629,297,600,4,487,369,813,961,586,101,90,307,482,375,308,803,306,739,682,665,189,638,855,772,719,305,183,988,443,35,202,104,463,530,600,933,425,213,724,204,990,55,734,670,920,986,506,259,196,29,914,371,192,603,56,819,309,270,404,573,954,3,893,966,724,42,286,471,879,945,99,706,693,233,849,102,961,911,113,365,468,446,952,391,781,947,157,318,477,324,250,163,43,57,843,347,214,327,592,62,469,594,895,9,988,650,99,788,948,964,376,110,48,129,796,621,825,670,611,747,274,29,748,932,683,701,301,156,986,946,34,37,403,993,493,740,552,562,21,156,216,938,846", "681,760,927,702,60,41,644,555,146,270,307,184,881,494,666,385,340,118,321,735,886,341,982,587,371,696,306,765,315,223,556,406,423,102,269,272,209,848,177,932,406,721,498,619,380,235,602,620,280,542,246,127,134,63,704,714,198,401,653,597,770,326,78,109,555,561,49,411,677,912,29,19,519,262,77,399,382,539,701,750,999,122,897,230,937,900,538,795,173,977,436,47,431,427,648,748,643,304,518,413,753,316,309,251,486,851,259,845,17,888,206,934,216,622,28,291,510,84,774,431,934,484,136,204,665,699,208,942,697,198,59,751,209,360,948,110,1000,752,962,630,735,568,398,177,741,427,177,979,734,227,715,352,272,676,479,807,881,650,810,110,625,432,340,355,211,45,9,336,737,34,651,813,83,625,811,206,878,433,742,212,788,225,217,89,968,992,839,980,731,948,163,294,847,617,311,882,461,817,469,100,753,945,130,540,531,705,666,624,875,695,573,647,673,368,248,896,405,734,15,498,742,890,997,536,319,115,598,430,321,740,21,859,970,544,53,157,237,780,237,80,770,70,995,781,966,714,288,378,853,602,106,568,287,315,999,190,748,991,704,909,765,96,238,336,703,29,704,172,142,922,930,973,645,567,617,371,560,609,116,530,63,660,950,27,147,342,50,628,816,724,192,197,941,64,146,371,406,816,199,368,494,421,56,169,122,921,270,589,843,560,12,406,898,30,158,945,116,444,119,732,202,806,551,447,736,570,787,91,956,23,661,823,295,391,3,907,135,910,626,326,513,890,55,465,726,577,148,675,641,320,916,955,218,114,370,605,131,149,528,877,792,293,410,447,806,890,656,613,850,429,459,918,421,364,670,446,219,64,266,440,766,964,583,277,719,734,846,618,815,591,200,155,215,737,126,746,815,935,199,805,652,47,848,16,541,460,418,283,879,136,538,390,15,137,282,681,535,728,95,444,446,725,608,721,714,710,200,529,792,428,38,993,614,22,931,376,318,202,25,59,732,286,161,222,781,420,994,68,515,17,954,248,454,354,78,773,849,308,168,450,316,939,20,904,24,282,273,403,328,689,522,614,735,772,514,514,961,270,41,879,632,106,335,686,570,963,683,935,382,863,31,339,440,339,438,103,972,654,871,415,16,189,161,547,5,625,288,370,430,910,57,164,813,476,929,795,657,109,359,570,562,91,888,321,44,887,36,86,384,415,576,660,14,32,702,332,535,501,0,706,432,563,906,977,161,183,264,250,15,582,91,451,221,108,179,463,501,18,227,47,364,658,220,843,954,658,614,276,87,306,614,857,70,960,353,491,763,49,254,667,777,279,644,243,517,437,794,837,363,894,595,314,26,775,633,830,154,593,406,62,617,405,40,192,756,902,563,965,126,211,535,197,901,542,557,580,402,938,248,230,545,119,230,35,542,527,989,910,444,431,635,663,760,859,870,979,887,412,742,342,514,366,969,822,117,557,453,360,818,811,548,532,222,698,438,617,183,4,876,956,347,917,795,831,720,399,794,789,182,117,86,719,583,767,870,545,441,81,882,551,461,107,983,570,526,872,360,101,592,786,882,411,144,367,380,724,530,555,453,41,49,688,195,834,657,230,889,908,719,414,489,670,112,190,629,924,370,370,614,297,238,463,412,164,864,59,808,456,482,504,809,978,414,152,769,189,286,1000,404,361,658,684,294,427,136,296,651,27,896,963,846,444,85,582,563,492,196,387,619,94,216,637,394,666,811,22,24,493,939,562,262,784,484,1,441,550,517,591,995,332,482,73,240,229,410,288,203,223,991,816,164,209,998,488,736,698,852,602,635,303,266,857,172,661,948,824,400,114,502,177,768,995,753,445,692,987,746,7,508,428,377,747,870,260,110,565,46,732,298,92,255,972,4,732,14,442,643,643,511,538,927,699,843,627,269,544,859,124,846,775,656,88,117,53,466,720,563,615,921,426,512,171,622,902,84,926,311,818,645,407,603,139,403,844,920,519,989,189,126,390,300,619,983,962,849,707,686,824,662,836,343,562,610,45,215,738,749,400,781,724,139,366,183,564,355,998,916,365,736,224,328,285,396,898,597,221,396,392,939,148,13,717,268,724,478,374,187,284,739,364,662,793,476,73,262,465,672,187,20,504,405,933,976,774,301,895,439,612,40,879,510,475,878,786,151,533,547,856,436,701,190,697,361,166,969,693,555,872,811,729,360,827,149,679,10,477,825,198,592,679,277,397,314,738,726,596,710,630,333,247,548,26,658,759,235,894,677,311,665,938", "35,197,98,720,70,858,818,611,935,641,695,896,894,408,315,207,503,985,884,694,274,385,437,835,578,178,101,88,932,351,191,931,756,398,471,836,346,81,334,764,467,908,21,313,383,168,829,545,185,646,652,331,529,164,160,593,479,987,94,409,65,118,781,137,327,321,847,69,149,54,404,451,140,960,691,954,881,305,851,29,144,24,201,679,77,985,883,676,388,320,568,191,515,706,186,722,916,752,453,420,449,568,744,885,550,821,882,135,340,582,234,870,242,276,939,176,136,841,931,165,696,984,429,443,107,99,45,463,310,134,116,294,815,99,674,409,741,922,85,686,652,439,462,359,650,959,215,736,833,992,619,585,883,94,103,618,515,438,736,70,468,298,519,369,446,567,874,368,875,710,962,925,467,998,721,588,67,406,367,449,378,40,168,214,902,473,155,255,390,589,205,183,149,62,472,393,118,546,931,897,178,820,581,887,253,184,910,487,978,989,428,650,882,812,430,384,50,721,555,273,457,926,877,694,359,42,162,798,964,513,857,465,426,972,597,987,55,269,522,313,89,41,921,902,902,433,131,192,661,376,365,224,838,712,520,920,30,100,178,885,69,715,939,528,672,307,102,628,280,942,799,962,747,672,312,821,748,553,810,110,684,870,952,390,334,273,449,214,998,75,707,452,111,123,280,724,757,651,31,831,196,438,735,390,373,993,778,575,329,897,665,299,437,372,160,312,883,715,987,210,387,17,494,71,881,839,129,518,601,70,129,679,449,56,702,58,31,902,785,965,709,500,304,997,444,965,31,505,556,534,721,739,801,767,102,344,386,840,98,901,158,453,118,995,170,917,932,815,876,172,846,202,60,816,935,761,876,626,446,353,787,658,418,824,444,733,333,495,397,896,261,991,759,387,738,948,917,732,757,646,854,973,906,220,594,297,756,815,265,181,786,444,641,698,979,53,36,734,587,478,58,208,129,310,937,904,56,530,188,752,627,421,806,367,440,648,622,298,8,208,710,873,308,13,624,352,357,830,124,464,231,18,675,458,61,835,419,913,191,462,498,941,563,178,277,953,398,376,667,657,620,291,40,231,340,862,966,529,195,584,908,920,129,582,274,62,860,994,180,273,424,754,185,927,602,395,352,884,560,579,863,748,279,176,249,784,634,340,834,532,367,898,539,153,650,305,792,47,99,935,956,854,957,268,965,272,625,14,448,861,18,346,553,225,29,592,19,570,706,0,250,244,479,991,860,492,526,435,590,619,447,912,389,278,190,456,914,137,99,322,267,928,43,464,682,705,95,437,163,681,451,626,914,738,378,497,499,311,422,40,829,510,168,466,302,766,573,945,596,548,23,361,212,325,15,62,34,229,200,875,779,978,579,325,764,312,15,383,49,67,375,94,212,45,98,84,193,449,441,493,432,678,801,205,875,809,80,111,862,99,663,256,160,155,18,974,179,927,796,550,147,246,96,628,396,74,708,230,948,963,846,254,501,258,441,427,857,372,465,349,678,97,629,153,497,747,746,434,53,160,756,229,215,943,581,625,983,687,155,958,132,345,63,394,427,221,916,256,742,979,387,542,483,341,129,745,128,915,188,222,375,469,110,51,140,525,667,405,569,889,622,896,844,255,344,422,306,382,808,859,884,152,59,557,816,762,75,901,889,419,456,769,372,922,210,183,225,391,187,675,214,876,408,795,223,219,959,882,990,992,984,6,345,192,717,62,951,158,363,463,516,385,106,613,792,762,703,227,575,507,858,690,392,411,383,222,227,172,915,714,314,694,419,834,682,19,89,815,947,416,183,534,445,428,456,248,483,567,240,525,131,224,190,123,616,139,965,647,419,30,229,809,264,281,255,466,305,220,926,693,920,948,200,954,261,776,114,779,432,926,661,783,626,172,257,796,922,963,885,57,63,44,877,174,453,167,169,568,284,710,8,3,719,413,400,738,587,860,818,905,194,275,476,266,70,829,777,409,109,971,443,862,189,143,456,883,666,548,805,675,809,985,920,332,155,294,823,818,677,466,465,625,442,126,567,582,14,913,515,579,384,311,278,222,908,471,630,695,299,85,302,36,657,372,281,864,29,56,922,491,301,137,800,899,719,451,89,240,164,773,710,143,82,634,659,540,744,311,203,683,768,186,682,72,914,251,132,115,906,881,616,695,139,197,394,7,822,521,723,242,180,44,224,288,34,232,638,433,180,267,677,507,969,871,872,235,204,423,497,691,633,736,475,895,115,542,859,562,18,726,669,838,365,447,647,600,571,560,499,200", "456,991,165,820,57,767,917,932,674,497,390,213,930,776,434,402,207,68,830,199,147,734,679,303,768,634,848,588,644,493,526,614,749,218,654,830,128,226,545,254,708,530,120,819,172,80,752,790,508,27,744,820,227,351,523,92,549,27,336,626,327,903,202,100,971,752,606,296,550,152,598,325,87,932,281,163,443,175,51,305,672,633,897,732,610,326,56,211,337,147,53,426,946,147,840,620,454,900,790,673,443,785,693,64,629,94,556,577,822,21,408,803,727,439,783,182,825,182,299,668,584,737,899,53,356,664,360,700,686,410,864,418,573,548,408,437,200,504,332,766,518,713,958,43,393,386,749,742,517,645,764,394,927,848,326,391,104,746,934,148,132,714,715,823,979,66,879,192,720,547,658,579,88,578,960,196,47,150,488,469,909,542,552,704,406,411,133,115,407,636,168,121,637,402,740,932,220,718,724,997,127,146,637,460,830,979,511,95,156,832,312,757,624,730,435,919,529,120,58,487,273,673,81,366,361,186,744,421,740,538,510,990,192,645,873,612,204,368,346,361,950,352,742,589,662,334,977,636,825,204,14,812,579,319,285,964,491,466,298,69,579,851,333,240,109,99,572,158,453,566,785,404,984,918,663,816,588,329,756,266,788,743,275,73,347,994,867,488,565,337,613,796,57,386,973,688,316,52,220,896,725,16,797,633,70,486,141,586,844,938,82,497,445,603,438,930,392,281,953,127,206,937,103,401,824,497,272,783,611,279,286,285,922,600,669,883,208,987,994,967,222,533,904,127,528,978,957,992,743,363,882,141,696,406,324,217,157,19,600,399,700,835,95,154,807,571,997,361,948,273,76,26,47,357,364,224,31,594,268,660,634,487,142,793,484,256,67,289,760,749,995,721,69,920,945,523,40,501,874,649,860,673,670,663,79,486,729,740,589,124,143,73,612,681,394,223,953,458,811,80,456,355,529,33,407,802,819,813,76,224,94,246,318,55,351,604,60,847,863,162,488,655,734,814,160,467,860,340,396,675,527,811,363,542,272,466,904,323,156,22,309,411,766,17,571,10,232,366,629,232,919,495,162,308,85,884,500,250,111,808,549,380,972,699,108,855,547,538,867,773,644,242,631,976,984,166,284,17,398,567,141,276,760,246,732,724,950,946,41,178,239,938,595,24,237,107,595,787,6,949,864,984,696,920,834,521,350,696,839,827,965,897,744,383,931,894,672,791,432,250,0,488,335,158,712,37,781,197,895,433,809,612,499,902,841,186,224,489,172,468,143,63,973,772,611,743,49,337,491,111,820,828,781,989,350,77,96,579,422,590,327,81,740,943,530,931,514,473,796,248,54,685,451,459,471,699,658,556,710,74,810,829,904,376,831,716,639,512,76,987,501,461,927,301,76,944,112,30,435,955,430,838,663,86,469,292,164,431,433,917,420,443,251,587,495,651,730,914,925,225,983,414,210,168,796,146,349,358,653,67,642,515,351,936,807,504,25,291,455,11,616,736,119,109,18,593,924,184,828,268,54,495,511,28,143,803,202,530,220,301,701,343,728,452,732,423,948,118,648,672,944,693,819,909,147,992,353,253,751,400,389,682,751,611,96,730,137,744,203,307,649,513,649,197,226,376,569,219,827,796,77,963,904,140,685,819,159,226,755,212,298,763,182,655,548,162,64,518,444,592,986,636,642,181,512,948,959,491,510,693,815,312,943,777,509,807,424,65,276,833,792,897,818,441,946,547,611,775,708,419,144,508,92,611,642,31,105,510,489,126,512,953,100,706,854,213,327,950,602,815,260,720,81,362,761,395,107,274,508,371,791,761,687,376,459,441,351,586,828,992,736,432,282,965,120,171,114,347,994,602,569,553,408,84,741,266,878,610,764,823,905,497,857,287,932,189,580,292,600,436,685,827,128,259,891,511,636,420,712,629,662,978,516,575,842,669,677,429,490,779,430,686,6,50,426,694,373,518,207,497,784,437,265,53,526,119,976,516,517,374,114,758,60,418,602,391,199,987,627,643,217,108,519,684,24,539,916,275,727,921,835,579,38,577,945,420,439,475,790,758,92,383,323,16,740,736,454,142,33,812,378,881,32,713,73,125,317,344,26,192,743,227,648,831,919,456,990,417,831,7,498,287,409,491,769,20,17,853,679,690,877,80,630,231,838,768,946,63,463,457,808,200,852,272,350,536,257,270,136,746,648,534,585,657,186,257,529,207,699,852,170,113,830,407,670,398,526,293,364,381,546,71,983,594,788,906,888,26,106,259", "795,995,409,766,62,632,306,505,536,654,385,558,890,625,966,862,705,42,556,604,656,306,185,288,436,12,978,720,726,762,215,884,38,323,658,479,234,19,982,918,947,438,148,231,171,848,235,138,193,691,343,114,773,855,246,327,809,40,331,789,704,358,818,429,498,452,201,494,955,940,967,27,764,627,859,51,199,618,856,51,931,153,209,989,976,2,31,410,701,372,787,127,290,932,864,940,961,881,63,864,718,803,606,501,587,823,264,819,544,749,753,273,46,639,797,316,354,675,127,973,56,776,394,115,833,487,742,945,746,690,138,417,799,49,843,762,884,941,335,173,39,404,118,781,237,380,5,40,176,425,862,535,532,506,644,742,573,733,766,229,43,237,428,815,987,439,487,615,960,704,332,949,324,965,551,388,125,737,222,374,952,448,474,377,553,294,164,492,851,165,473,756,561,730,130,386,577,168,200,531,356,263,73,884,311,548,578,872,963,143,196,205,190,341,634,508,744,795,569,748,127,720,592,103,976,907,946,984,496,445,109,867,638,73,392,989,573,326,256,797,466,176,148,619,840,956,90,280,515,173,828,955,896,950,385,972,632,129,217,613,566,911,830,905,100,314,841,304,678,340,231,762,452,347,706,84,403,320,54,781,302,61,325,476,748,554,107,123,49,67,426,729,636,954,158,410,279,712,933,97,962,859,981,889,181,796,937,426,706,355,506,497,635,218,585,237,540,174,743,464,879,220,13,18,393,889,257,188,637,880,600,766,713,216,158,296,730,433,938,470,199,678,305,811,449,935,960,405,428,730,718,292,266,862,646,581,619,658,678,133,360,389,159,602,907,618,904,59,150,457,746,42,204,935,226,933,911,281,85,100,223,896,800,685,947,158,656,285,943,16,517,348,415,480,642,27,68,706,553,102,512,383,442,629,429,961,302,248,399,85,634,717,107,99,707,833,152,864,623,173,759,347,494,733,547,310,283,929,6,294,313,186,506,903,691,342,403,703,350,84,166,287,707,252,836,907,704,250,260,955,246,905,551,68,763,987,862,987,510,117,991,671,816,957,648,674,274,965,26,57,873,442,826,737,652,136,19,550,856,244,949,73,509,194,587,397,455,829,191,525,825,459,862,76,923,978,599,112,557,635,108,61,134,172,205,989,497,363,495,678,963,853,709,892,999,828,972,787,609,209,270,291,644,691,126,540,10,363,335,667,900,764,586,157,78,705,827,120,563,244,488,0,208,312,161,360,128,782,129,806,777,423,819,445,123,954,881,627,419,771,941,913,177,215,177,690,484,651,563,451,824,580,664,381,534,774,979,974,54,215,774,824,477,258,73,123,93,447,998,492,794,196,206,139,693,69,720,83,49,246,147,145,118,369,818,755,333,247,773,769,144,539,104,283,654,655,787,707,285,655,685,335,237,534,172,878,565,322,988,434,852,577,463,306,32,25,616,251,479,394,322,595,723,160,55,133,302,416,165,975,806,530,270,49,374,459,958,747,520,854,720,529,716,378,909,884,500,778,262,250,653,601,562,375,345,935,985,337,212,366,597,475,847,673,757,878,293,262,635,449,653,644,144,394,316,211,622,909,212,178,18,98,6,826,444,332,306,786,686,960,440,89,410,15,576,389,349,307,930,316,848,290,778,219,7,512,490,197,561,417,572,32,484,933,151,945,979,22,153,318,306,100,857,793,52,682,917,264,276,19,493,999,482,685,464,88,654,127,737,977,664,374,145,131,522,2,587,96,418,298,127,766,120,26,189,111,556,672,307,384,723,5,235,942,614,718,425,187,721,339,58,588,927,103,584,654,731,146,574,567,277,736,606,884,984,243,546,364,681,976,543,795,98,366,507,773,997,425,77,542,42,117,541,47,735,602,744,629,652,882,461,511,844,724,212,941,830,565,386,826,848,727,588,707,267,682,354,634,970,116,191,494,83,743,396,955,746,904,566,411,615,352,624,618,710,616,729,559,589,904,753,917,902,61,359,656,15,395,531,90,629,571,523,493,267,942,624,182,328,701,560,317,678,940,265,37,258,698,431,79,424,377,959,90,469,620,774,628,634,611,778,887,644,826,334,319,513,597,604,150,568,786,96,46,453,184,813,494,582,140,754,417,521,394,19,221,454,725,395,341,57,157,633,830,392,952,299,273,29,638,823,222,338,80,821,857,614,797,299,861,387,338,277,84,890,284,218,756,940,414,592,93,562,537,977,893,581,849,629,225,245,816,865,150,742,29,419,147,139,264,679,79,833,500,986,705,512,458,524,282", "615,876,238,328,893,994,400,746,660,658,848,157,128,24,203,935,568,497,257,829,891,312,900,782,444,466,263,310,97,841,769,774,900,826,559,769,357,564,416,709,874,27,273,293,818,211,428,374,659,165,334,827,151,209,267,410,928,875,376,174,126,377,216,480,494,103,957,884,653,960,508,492,747,902,240,789,532,251,749,783,687,112,390,99,65,150,742,481,864,629,648,159,540,775,192,422,449,265,556,308,312,6,226,937,516,986,725,86,225,344,386,856,124,872,673,747,549,227,605,987,220,567,700,411,211,88,32,987,361,104,275,280,302,265,576,124,788,902,180,961,633,532,338,25,935,401,99,225,974,852,339,410,506,283,216,174,844,527,58,344,399,993,177,3,135,57,525,299,156,25,723,816,268,875,792,461,127,593,240,618,700,114,190,553,644,4,539,434,205,568,43,832,778,402,857,767,908,925,950,537,580,634,73,606,132,890,791,740,305,940,639,866,885,958,657,264,678,639,968,187,582,551,622,850,255,139,220,65,766,322,937,498,762,335,579,274,220,133,668,236,578,347,662,755,820,311,150,549,43,894,855,675,662,40,420,313,348,497,982,365,611,217,795,53,7,955,30,158,258,822,598,122,712,302,674,271,18,403,570,847,150,232,411,911,942,378,308,599,74,495,117,486,614,489,703,377,382,146,475,279,41,496,630,555,143,411,372,762,263,19,768,666,66,888,716,715,840,854,565,56,184,259,626,270,334,104,829,235,938,32,351,234,985,169,397,489,781,4,465,739,318,361,16,331,927,618,301,546,626,574,176,313,688,980,82,679,348,592,66,88,362,622,5,732,439,170,642,334,32,141,258,554,875,763,780,618,988,19,869,226,216,685,469,578,59,19,38,692,8,237,691,63,616,607,285,526,986,534,216,819,547,872,793,595,861,65,122,778,199,194,460,740,855,39,440,926,522,123,85,944,743,941,790,4,266,341,697,24,534,251,489,417,995,810,340,870,659,97,529,745,407,357,954,695,500,520,134,373,163,30,162,702,969,487,769,411,911,320,84,216,871,727,493,914,622,63,819,241,921,175,544,948,898,392,21,654,19,562,435,334,612,646,298,183,492,569,282,512,217,862,565,339,413,466,950,108,416,236,688,413,918,565,360,121,811,974,25,19,865,626,49,284,524,546,559,409,23,316,403,167,747,580,947,595,117,205,433,803,867,753,104,885,465,725,991,252,664,644,906,479,335,208,0,867,755,227,498,218,81,79,986,338,911,824,477,690,772,862,304,48,641,789,691,565,455,209,816,882,746,613,656,628,275,893,151,513,167,753,298,551,705,477,133,429,20,564,320,180,870,10,742,441,577,256,186,607,193,138,719,992,779,980,332,218,783,681,647,352,981,341,463,136,183,509,104,652,459,461,555,965,172,702,932,247,205,468,713,684,946,253,454,445,163,391,528,272,788,1000,655,288,119,389,462,889,561,924,933,217,402,529,793,155,582,9,603,190,928,797,614,381,323,695,150,296,250,712,468,233,35,557,899,602,485,36,346,546,627,528,259,525,567,75,129,720,843,755,486,850,389,797,126,214,712,56,711,674,946,914,479,161,534,970,910,598,582,128,727,914,705,678,976,618,65,619,694,523,529,708,994,646,171,686,77,657,836,870,19,504,358,832,465,664,99,998,850,936,905,389,35,637,327,113,883,684,764,490,454,47,662,607,598,819,394,500,34,875,985,92,962,197,592,932,9,95,417,85,907,187,739,298,907,273,817,485,577,604,866,564,590,645,42,931,395,444,306,67,287,40,652,731,325,304,861,631,595,572,511,345,864,120,104,753,450,904,448,524,426,309,297,231,188,18,898,979,654,954,893,85,893,917,88,356,517,78,934,632,966,186,34,708,122,129,662,751,100,909,435,625,696,29,278,257,651,445,913,30,648,965,695,538,133,272,89,790,184,259,627,82,548,463,403,526,862,682,808,619,675,515,585,346,134,674,726,548,872,692,420,224,111,585,275,770,841,540,186,388,136,196,590,846,718,876,633,282,431,942,848,801,258,157,395,633,314,874,803,611,82,384,553,351,259,104,606,984,161,425,573,343,942,120,263,84,840,337,985,591,20,519,727,695,461,749,124,594,691,110,94,476,257,500,221,355,973,446,836,178,790,542,731,824,314,209,228,758,957,872,722,250,873,965,437,320,885,614,321,309,101,750,119,500,745,266,898,170,886,218,83,878,450,884,70,608,259,84,924,282,398,221,414,267,427,684,26,675,277,460,558,626,70,839", "349,5,94,198,315,759,694,334,640,987,126,171,196,845,313,250,307,97,302,468,616,7,751,750,457,918,157,242,671,306,255,195,163,295,393,557,355,38,71,190,932,120,316,710,676,782,331,162,245,950,439,150,2,646,265,1000,537,177,517,124,552,44,148,928,948,269,502,983,812,683,43,996,522,126,395,726,903,645,822,523,106,861,483,10,88,712,999,850,868,639,427,205,919,34,29,69,960,782,667,366,948,307,694,89,963,519,407,158,908,94,870,349,767,5,702,765,624,375,748,796,568,22,677,771,956,273,500,628,98,641,159,779,323,221,363,432,541,331,372,437,946,945,156,646,530,884,881,80,97,640,757,377,797,380,663,307,638,790,596,782,987,906,719,748,240,470,67,127,820,327,631,882,79,831,253,690,748,372,388,554,90,565,646,53,400,611,522,96,186,121,267,529,153,313,213,227,905,71,588,529,547,794,646,80,446,389,274,523,724,117,443,152,559,936,629,799,808,674,843,425,51,128,405,315,715,640,772,339,931,897,241,109,21,528,857,965,223,971,790,677,249,232,718,1,779,674,566,638,705,20,254,823,221,312,355,313,845,185,438,137,67,395,919,326,917,718,458,903,610,166,415,855,376,881,493,590,260,956,127,786,859,81,672,912,231,143,990,26,29,313,787,55,618,652,127,714,96,369,239,651,95,98,85,801,3,336,53,79,53,342,119,938,764,750,376,815,43,971,463,846,714,549,993,713,957,162,760,159,391,868,359,232,319,759,542,408,730,534,927,30,492,687,405,996,844,904,809,702,773,251,889,380,29,120,448,633,258,836,378,340,161,50,809,10,574,212,923,285,699,204,493,767,866,830,925,522,108,367,405,87,892,970,42,772,455,244,161,792,110,305,1000,796,57,559,574,661,119,433,517,246,47,115,145,608,810,276,593,454,243,472,900,704,749,884,755,419,45,248,749,35,351,817,714,383,223,406,121,216,349,678,161,589,912,755,950,518,300,315,545,804,212,556,292,9,890,636,11,993,34,764,874,173,517,182,87,298,196,485,10,669,485,47,856,597,542,248,633,495,413,625,402,284,333,493,598,206,767,246,85,269,858,121,831,435,165,209,944,18,839,591,597,443,159,672,618,241,371,494,821,658,447,467,889,659,767,573,677,740,468,506,971,694,78,173,529,229,779,373,962,277,315,561,254,89,345,496,855,650,646,158,723,664,383,882,190,715,783,646,977,991,158,312,867,0,496,407,696,884,338,487,451,842,636,182,233,855,283,556,571,729,523,814,851,448,469,868,609,973,465,692,726,220,678,20,618,195,941,58,897,256,773,788,117,751,695,457,751,258,712,542,253,138,966,771,308,227,47,398,210,531,95,852,560,94,918,202,835,519,988,839,316,506,461,736,772,720,124,572,634,396,465,886,38,218,594,449,190,985,970,43,300,240,890,546,807,419,384,855,572,997,643,938,989,449,25,217,230,168,930,254,984,999,102,621,143,643,704,62,41,919,916,891,736,408,471,670,274,177,295,742,15,96,246,643,191,304,595,397,106,26,770,965,738,494,719,245,992,709,798,678,275,140,731,762,183,893,860,815,699,757,808,894,883,72,430,415,86,769,878,379,423,376,258,224,30,370,826,905,548,693,614,194,790,112,571,839,945,310,897,760,736,341,294,760,607,375,707,457,617,486,930,515,971,77,397,561,263,179,692,172,3,967,221,247,993,205,830,885,975,921,496,341,202,578,519,730,939,836,48,273,375,453,288,906,918,415,66,607,105,52,737,294,974,321,951,915,168,101,214,978,835,545,845,619,418,255,223,417,825,757,355,526,622,228,987,773,128,953,493,462,6,602,290,873,483,435,727,104,168,615,434,876,229,243,702,530,628,393,89,595,804,2,924,841,627,284,473,839,233,979,837,130,709,474,832,527,52,50,496,661,928,313,900,581,420,498,196,836,9,559,308,991,341,225,861,213,432,285,459,86,437,165,55,522,142,149,707,812,886,980,201,206,188,936,361,657,444,796,534,45,629,808,786,318,336,113,613,828,909,377,13,840,797,371,715,40,73,809,886,742,496,441,772,8,327,363,104,530,69,444,313,855,359,792,922,949,381,822,651,596,441,640,356,672,631,771,854,948,397,377,213,976,688,847,621,691,39,764,95,369,455,57,928,21,395,378,205,383,697,960,31,689,467,538,809,786,765,393,470,327,699,558,298,919,147,275,416,307,569,704,703,627,249,694,769,32,259,294,523,78,468,947,587,705,651,791,186,957,827,349", "597,342,442,794,76,462,43,864,843,812,265,583,55,930,835,621,922,430,546,174,664,966,96,964,592,606,693,896,381,925,421,94,268,341,600,331,24,9,822,241,630,603,427,47,578,282,660,47,212,802,649,832,352,480,345,112,672,717,46,390,470,105,421,545,320,836,976,45,394,603,680,494,395,551,28,894,514,753,525,705,700,702,606,738,287,822,600,538,544,607,897,329,195,418,45,47,88,431,414,389,377,248,60,553,113,694,725,329,745,325,222,528,481,264,342,639,966,266,638,500,868,525,982,996,472,241,474,324,139,533,325,336,528,557,967,781,204,361,801,418,113,754,217,61,801,814,771,807,491,525,127,562,2,542,722,215,379,134,376,333,360,328,123,466,58,949,474,115,980,537,605,42,278,871,397,678,800,894,438,561,889,846,270,159,842,718,827,583,988,526,403,85,372,288,595,378,105,208,436,699,855,418,106,488,524,734,568,402,807,583,283,592,57,158,511,999,560,676,868,242,113,399,265,110,229,374,367,620,332,791,297,990,446,834,439,833,595,835,120,904,876,942,880,331,506,726,165,69,592,133,335,511,211,486,111,474,540,629,971,547,262,925,468,981,183,149,935,334,354,7,296,297,51,466,582,984,937,94,701,370,256,241,571,72,764,881,392,409,621,983,11,359,261,606,905,309,419,58,362,300,262,469,147,673,439,610,106,120,494,500,668,168,400,534,77,725,884,150,348,211,49,196,626,160,873,942,349,128,660,330,628,377,191,147,792,925,996,407,886,847,20,624,289,977,946,231,256,732,885,490,398,58,734,59,64,950,386,45,817,459,513,233,26,949,54,525,253,170,473,83,134,315,145,964,388,382,942,729,308,407,47,1000,945,647,405,193,924,190,575,808,684,424,614,656,730,510,905,387,302,279,369,916,170,223,44,662,562,949,950,318,97,992,941,813,496,284,876,997,88,196,586,481,807,862,111,485,605,287,849,251,630,657,233,654,858,894,669,404,222,862,82,550,420,791,2,494,354,984,142,405,292,890,602,247,662,86,832,424,110,709,477,647,986,407,533,487,617,891,825,266,747,409,294,355,113,252,599,589,998,405,197,554,805,682,351,556,988,489,615,894,485,812,985,420,178,13,235,956,470,192,830,857,996,737,788,99,533,850,323,99,97,566,895,823,539,155,729,232,561,150,505,323,193,710,241,872,121,989,231,333,394,947,522,707,832,406,158,281,161,860,712,161,755,496,0,975,514,598,748,696,24,902,914,850,276,530,712,801,13,12,723,359,617,817,746,816,210,3,800,446,965,64,553,621,316,235,220,104,505,486,461,941,709,584,216,290,278,652,806,456,684,876,606,839,347,778,568,949,674,45,634,660,618,295,108,660,612,381,252,335,171,622,311,809,664,740,710,467,952,745,34,421,992,197,767,69,621,851,428,288,21,175,978,152,944,470,791,738,257,450,123,87,471,934,136,655,503,657,183,430,440,60,371,16,706,159,672,127,257,474,223,129,981,148,32,975,511,344,492,799,920,150,685,663,972,857,286,595,705,66,954,68,822,224,229,225,659,833,801,400,193,958,140,610,933,707,385,43,179,22,734,496,523,73,524,694,108,858,818,820,81,804,71,776,589,475,536,813,97,37,402,838,240,462,14,485,124,878,633,325,23,101,174,970,775,408,541,686,772,563,884,114,98,485,881,942,945,851,491,614,135,674,795,523,358,807,616,397,677,267,65,249,716,700,119,502,529,518,592,678,898,307,568,467,619,222,960,326,457,807,546,36,962,415,72,491,703,728,304,843,617,177,239,457,526,516,236,697,546,404,684,257,37,788,486,550,968,232,715,65,51,96,371,335,452,508,267,923,476,620,840,661,477,452,919,707,109,259,679,722,598,876,921,89,941,895,794,987,115,717,508,755,459,514,61,958,423,641,83,443,943,175,16,121,477,573,496,491,96,737,18,740,342,229,652,825,934,691,487,147,936,604,381,878,414,191,815,479,79,188,149,504,616,230,907,818,979,980,664,93,892,937,687,79,755,892,387,541,268,179,278,984,583,249,558,704,989,888,804,140,615,793,887,303,474,839,746,478,439,632,693,218,34,655,535,826,835,792,570,919,109,861,304,90,859,969,708,801,82,953,568,178,28,316,603,140,373,43,129,394,376,387,545,523,84,218,56,83,131,456,748,816,889,891,110,246,682,905,317,682,984,513,190,626,870,461,713,81,846,306,411,884,483,426,236,503,876,57,958,895,517,352,60,571,307,474,972,948,254,225", "198,379,877,41,635,559,679,711,880,875,341,437,870,893,948,260,537,780,736,289,267,73,460,881,427,280,829,607,431,16,337,854,741,980,558,832,451,726,673,827,81,397,725,311,207,716,512,23,723,675,950,559,801,256,674,417,795,99,983,808,887,165,229,858,239,1000,128,422,961,947,282,410,907,410,346,291,652,858,964,210,254,354,66,285,359,697,243,242,886,15,319,481,929,12,168,258,700,463,193,171,172,474,699,591,900,919,314,691,80,813,494,81,972,17,415,689,901,947,165,731,283,237,840,340,635,692,932,7,85,354,705,330,985,199,392,738,706,800,921,58,416,112,676,899,755,513,322,922,956,112,836,13,758,752,11,770,338,583,749,300,171,308,657,474,945,525,340,931,80,653,10,831,764,139,911,994,476,689,978,907,943,997,990,573,19,791,380,399,8,67,265,781,511,597,91,634,193,8,465,948,593,345,925,178,952,279,661,745,595,151,446,570,901,307,313,430,426,319,330,277,766,867,682,770,529,475,44,597,858,335,551,736,785,620,577,507,677,693,976,519,189,587,311,223,119,630,584,724,335,789,752,69,718,740,12,568,697,996,32,685,889,933,795,423,818,195,182,800,224,128,388,813,740,924,295,283,35,298,623,829,944,791,284,65,312,237,554,162,859,994,988,567,991,664,769,483,898,981,498,871,725,658,928,48,683,946,533,724,425,824,242,364,647,740,280,688,820,385,676,615,295,449,685,668,453,197,190,160,427,33,357,671,396,159,293,388,438,100,515,492,269,741,611,441,573,514,543,820,560,646,781,123,586,549,279,657,303,889,499,417,160,253,398,317,94,452,482,819,400,234,967,223,532,350,996,6,494,364,547,863,166,163,197,953,309,812,407,900,752,691,439,182,182,545,352,227,262,489,15,205,381,73,127,725,591,520,894,647,990,664,606,616,518,680,777,338,967,899,373,86,385,732,238,279,210,987,241,254,495,474,702,215,792,359,442,956,813,904,933,717,294,765,792,946,323,385,714,959,855,278,507,319,959,940,510,776,249,875,781,376,820,599,225,176,950,269,423,675,512,235,655,477,432,846,427,632,686,991,761,835,17,594,550,950,35,778,426,258,856,12,147,446,348,693,948,724,281,968,617,50,922,893,449,548,313,487,465,645,200,751,749,460,879,371,660,232,539,323,303,856,75,680,300,377,954,596,685,298,139,263,660,774,582,633,402,936,89,842,183,492,37,360,227,407,975,0,695,382,813,605,692,431,424,760,13,754,906,806,272,929,184,32,76,819,737,4,442,292,14,641,298,599,130,250,171,750,577,645,812,422,866,549,300,401,407,413,770,234,822,647,884,735,171,35,329,832,405,64,130,989,880,984,622,137,182,916,759,200,153,800,762,516,181,729,58,246,611,868,176,297,415,5,142,226,940,273,593,111,747,290,880,889,354,471,618,429,422,22,837,592,765,282,549,858,839,308,730,495,414,751,345,678,633,524,925,297,600,553,154,931,237,192,966,208,765,517,402,569,999,246,737,646,689,610,588,243,15,819,442,209,565,721,748,126,874,122,24,855,495,235,829,917,848,700,396,509,639,798,740,750,212,546,811,364,164,825,509,1000,696,36,889,167,318,113,824,676,245,659,942,966,530,869,651,867,227,115,763,392,468,675,971,408,810,438,419,715,974,698,485,427,340,106,40,645,973,168,69,964,433,27,720,538,443,18,35,21,641,567,218,454,749,79,204,586,109,317,377,975,371,899,49,728,896,565,457,599,537,190,562,882,973,792,168,64,407,977,706,933,979,289,323,859,698,706,485,780,5,400,870,761,470,570,955,728,400,561,656,189,289,614,223,416,207,899,591,724,636,438,836,883,496,808,912,753,239,403,31,431,744,810,650,265,740,462,358,911,843,162,396,372,430,146,788,37,856,26,708,509,879,768,548,252,426,896,28,778,162,606,343,440,242,530,969,77,495,611,826,530,461,384,420,221,525,708,91,298,221,564,514,480,586,5,252,988,147,929,98,259,189,95,769,84,863,285,830,468,837,354,347,72,448,124,321,975,106,145,135,578,739,898,952,68,430,442,681,192,436,239,735,360,458,36,675,900,888,497,802,70,81,934,920,180,892,272,790,199,523,295,437,137,429,24,586,951,418,724,807,981,713,861,240,268,977,229,763,343,601,903,257,399,682,633,390,35,426,744,321,428,441,536,394,151,222,117,38,84,375,606,526,507,275,326,295,592,905,587,985,473,686,54,882,361,221,645,14,372,644,594,159,397", "643,132,445,970,477,678,826,840,180,528,492,629,167,992,182,655,349,207,619,854,653,245,185,654,446,887,505,367,354,753,521,607,795,541,466,256,908,881,450,818,126,528,830,453,447,656,841,787,397,390,920,149,676,55,584,816,265,541,699,373,304,24,29,369,745,644,463,586,523,1,521,425,783,260,556,89,287,933,854,81,603,183,445,91,53,968,888,407,272,75,506,181,966,963,383,400,992,661,533,200,155,272,117,87,73,776,850,451,739,689,308,48,545,984,257,412,253,261,124,485,739,102,156,423,132,798,354,202,527,46,594,567,453,105,750,274,988,132,774,726,775,279,948,259,141,318,4,38,9,35,546,212,786,510,307,700,558,387,83,500,753,502,512,422,575,768,954,733,244,635,896,720,295,352,67,753,65,735,877,530,617,329,883,945,274,668,43,814,576,640,779,882,338,254,786,555,678,284,545,601,837,603,926,662,330,115,572,388,359,220,678,611,758,19,880,134,439,816,162,27,723,227,366,782,961,639,253,695,151,568,866,607,568,439,885,244,576,243,716,828,396,120,700,908,484,275,196,890,519,704,535,621,730,18,770,630,209,321,271,725,77,585,203,379,620,736,896,880,469,904,693,851,14,7,341,254,550,714,264,213,263,278,6,796,517,630,863,802,240,869,746,378,628,968,500,401,840,221,452,780,364,940,247,316,254,832,634,276,731,418,283,668,574,337,991,943,980,834,184,174,560,491,931,727,647,431,362,935,936,668,483,502,248,584,400,63,143,548,234,142,753,763,626,261,915,244,244,584,778,985,776,627,32,541,404,124,498,361,994,112,841,52,744,721,277,377,831,569,56,558,346,459,340,631,801,259,183,809,970,257,200,536,581,45,830,754,535,892,338,38,222,424,358,436,92,66,623,688,247,754,606,564,292,201,114,214,734,303,62,243,608,981,176,824,139,154,207,509,952,94,995,211,929,23,710,272,205,672,609,200,691,491,585,659,929,939,561,810,791,863,699,254,523,511,921,745,103,711,995,219,51,205,543,559,866,945,650,985,539,628,651,416,98,515,624,478,164,300,127,178,406,159,612,5,208,961,772,836,15,411,458,717,809,178,5,619,820,702,102,435,927,452,773,231,724,183,856,927,511,599,513,395,703,996,909,787,231,251,113,645,255,412,915,265,502,693,210,463,438,986,302,106,285,635,873,915,703,826,863,34,942,498,532,858,398,735,178,489,264,526,781,128,498,696,514,695,0,817,988,167,668,142,765,156,259,529,518,239,503,541,755,546,256,685,965,523,850,93,632,391,882,760,812,606,5,24,177,826,179,100,270,728,938,157,835,172,91,76,475,53,452,292,194,627,919,509,553,426,640,380,738,523,383,987,179,673,645,852,312,137,689,365,827,448,12,362,454,971,568,268,220,35,999,539,361,392,414,355,293,238,569,726,689,58,594,487,572,152,779,727,604,265,663,249,250,829,493,264,854,426,256,774,920,20,796,244,885,710,245,809,564,100,597,811,488,949,4,107,44,473,547,618,192,665,844,638,6,4,27,626,917,743,668,458,674,321,181,953,870,249,97,991,549,324,899,900,969,86,894,77,66,201,608,955,108,418,373,554,86,954,747,157,751,932,901,444,835,724,687,759,572,514,722,146,496,945,237,485,687,693,162,567,676,683,257,980,429,766,27,276,526,999,401,24,686,124,470,717,747,625,984,403,955,95,434,114,136,385,542,644,59,385,717,366,215,167,482,674,903,909,874,851,303,425,223,92,134,438,814,559,544,736,323,656,147,114,215,139,494,591,834,63,894,917,114,930,775,29,942,56,612,741,843,256,756,266,549,142,339,350,346,818,566,115,708,970,375,590,429,132,368,734,831,276,207,447,986,453,101,705,334,147,929,470,395,326,554,326,687,537,485,507,169,904,951,892,499,455,47,514,393,739,989,198,897,443,602,951,926,506,327,343,420,835,545,151,912,988,906,52,648,950,287,45,940,444,844,52,959,727,402,89,825,426,447,375,179,27,707,801,144,952,15,410,676,876,877,544,944,544,449,848,356,332,178,730,73,923,849,268,469,428,7,917,771,454,959,195,616,922,93,709,442,772,841,122,777,582,803,427,565,676,351,526,61,300,696,94,466,191,461,594,632,507,619,954,743,165,442,328,434,157,87,249,129,267,175,367,144,71,913,95,221,586,925,760,564,57,19,725,985,878,646,848,677,224,544,875,373,686,317,180,494,478,421,906,412,375,45,41,157,984,892,45,966,572,481,356,364,940", "18,231,266,978,538,625,866,680,466,948,686,184,669,331,395,196,556,142,894,691,628,607,84,379,462,148,492,894,17,271,368,840,236,378,825,255,182,152,618,366,217,615,937,678,469,956,376,999,735,680,962,47,236,283,51,688,194,739,93,177,505,779,926,707,278,307,223,418,478,872,224,398,727,280,586,111,263,697,123,238,752,119,348,671,777,448,206,950,629,901,728,130,921,97,103,732,366,1,143,214,139,942,229,247,638,656,804,441,258,398,850,531,15,840,786,482,699,471,750,90,154,210,769,216,579,416,20,63,655,614,698,499,997,131,348,409,567,409,803,865,609,492,154,522,593,380,859,982,669,107,329,669,210,937,533,491,856,302,341,179,659,855,78,313,548,893,793,860,100,12,66,994,68,499,992,940,547,459,352,24,145,76,754,123,77,315,712,114,314,871,859,233,374,780,651,969,19,345,163,604,921,529,795,762,796,672,870,189,250,445,258,968,760,689,365,393,767,111,679,173,117,548,495,269,11,840,666,441,632,816,17,617,554,632,54,512,27,34,511,484,93,230,605,671,731,338,22,892,651,169,440,363,2,111,47,341,280,884,56,182,859,274,722,893,137,304,588,640,231,123,138,213,847,655,996,683,690,468,616,317,299,263,399,903,123,32,866,966,823,594,889,603,747,846,467,242,304,412,475,557,779,226,857,54,40,690,272,997,938,789,854,958,910,840,365,676,137,263,33,628,975,12,606,883,356,896,468,603,387,936,873,78,628,31,779,251,767,120,214,237,333,384,313,816,654,716,359,794,503,588,425,639,351,696,148,812,309,953,529,555,849,953,98,970,729,552,237,135,651,429,240,685,616,328,260,763,593,51,180,719,728,53,848,25,347,757,955,728,902,316,70,509,382,760,311,351,485,874,641,572,770,847,558,149,233,555,60,442,298,136,551,217,391,269,516,390,118,307,175,906,431,618,248,803,815,877,15,554,894,318,101,348,530,947,648,43,443,649,844,539,873,483,908,758,185,613,414,509,406,517,277,960,579,513,795,915,33,155,40,419,835,524,474,494,195,822,839,141,800,468,595,26,751,230,214,732,217,400,915,521,792,149,421,759,506,364,736,915,970,675,293,51,236,993,73,902,1,285,564,414,903,919,745,167,20,617,44,714,899,991,823,393,264,715,218,710,542,916,254,720,691,929,740,714,422,288,389,139,926,41,634,708,653,153,647,120,914,621,250,435,197,782,218,884,598,382,817,0,140,963,850,444,325,560,361,950,301,433,117,784,381,114,674,925,573,115,85,772,335,651,198,424,289,628,164,575,269,240,483,702,381,863,323,177,315,862,674,745,369,630,320,830,614,861,197,477,662,541,901,254,292,755,656,931,192,13,611,451,700,379,278,934,845,69,56,266,403,907,281,898,942,25,316,686,591,271,154,720,914,589,932,951,150,602,189,24,34,979,324,115,109,609,489,232,887,537,986,824,682,409,221,102,728,982,307,916,555,532,634,344,387,571,394,862,869,222,190,724,998,647,973,389,371,929,532,506,302,467,159,129,758,558,856,676,56,64,282,652,592,577,130,339,693,945,886,21,493,463,471,714,372,314,220,25,713,460,246,393,673,109,940,76,770,603,742,776,3,179,273,861,269,625,566,213,896,901,12,946,998,233,374,427,232,248,595,373,875,553,803,217,85,950,320,245,680,112,828,953,872,567,743,127,562,966,540,255,926,360,541,684,116,432,120,109,465,490,257,78,573,63,444,509,165,799,994,794,613,379,790,136,37,483,245,327,475,659,491,595,588,987,435,550,608,208,68,28,782,660,598,904,479,645,886,77,910,200,817,78,958,637,144,479,693,365,206,26,775,832,759,948,252,7,469,913,923,250,195,82,213,119,515,327,382,95,696,162,485,753,458,890,48,925,240,410,671,825,668,716,389,645,433,194,200,236,22,973,154,570,289,90,357,694,244,196,799,111,964,400,897,263,183,688,518,289,545,400,188,420,390,796,946,776,123,181,887,800,747,422,948,526,749,355,645,889,791,38,92,499,849,64,614,354,500,936,329,567,825,721,350,779,54,51,312,108,403,388,977,857,158,353,543,794,628,845,646,152,556,607,137,966,928,711,616,877,526,920,118,413,306,433,669,244,720,115,867,771,217,864,480,951,320,668,277,386,107,861,998,463,439,287,929,149,301,83,79,414,468,895,420,37,779,736,729,891,417,910,198,861,547,459,635,532,45,590,143,824,86,629,917,165,228,433,140,304,693,770,651,954,960,177", "955,783,706,175,938,692,837,945,994,782,760,445,509,267,213,941,739,574,229,903,209,959,916,187,991,189,301,887,278,323,526,22,772,905,413,228,508,201,462,170,764,848,127,459,787,360,789,458,475,827,800,322,421,737,274,379,880,691,290,158,885,660,22,526,103,625,797,205,802,48,47,366,858,923,790,168,500,391,100,384,578,697,145,39,796,188,738,944,683,35,826,354,143,277,772,644,744,148,942,441,810,322,648,821,303,604,801,79,381,942,297,492,678,566,580,365,819,614,84,159,430,370,216,806,934,604,924,457,212,81,364,880,104,422,801,309,78,192,382,429,942,794,55,526,614,671,606,523,313,970,351,948,46,6,21,481,54,721,216,172,971,633,103,964,945,246,138,347,726,708,826,319,20,373,55,890,388,621,134,80,773,555,131,159,539,578,769,74,520,723,114,538,321,810,431,298,415,709,184,804,328,884,958,461,61,672,209,720,150,863,197,750,131,960,449,523,904,350,611,942,673,190,270,338,495,548,761,672,583,306,350,168,359,213,341,489,449,663,891,66,98,256,226,823,349,312,183,115,413,143,435,174,20,902,617,581,50,983,300,7,816,271,43,791,247,857,153,460,834,404,589,326,99,434,657,558,248,427,23,632,778,210,936,788,925,801,855,892,558,751,962,649,637,666,609,655,883,641,707,992,951,368,870,169,226,750,832,302,281,625,618,230,665,370,986,234,363,461,401,172,186,387,63,878,157,951,47,739,246,358,569,832,509,387,400,792,105,900,300,37,966,697,600,79,262,125,540,734,914,945,499,648,343,247,447,531,855,409,852,345,850,832,250,168,261,848,517,815,560,53,17,938,885,478,548,817,141,262,477,36,997,438,137,113,909,515,185,693,547,210,247,745,133,11,379,365,186,961,288,627,553,528,403,120,899,737,583,736,1000,42,909,240,4,766,859,847,313,829,631,712,730,326,222,827,942,50,126,706,565,773,628,715,205,399,806,335,848,952,563,284,808,614,85,31,7,561,915,616,786,168,228,425,14,487,540,563,208,294,340,25,130,525,442,425,638,693,774,87,79,799,263,227,476,582,424,65,943,668,545,660,739,585,135,217,337,637,320,935,931,117,551,468,590,246,358,135,783,960,164,599,973,675,636,16,37,427,676,68,545,432,367,317,174,99,693,618,703,998,193,788,92,246,277,686,93,967,741,996,98,540,606,765,744,219,64,674,934,670,15,590,895,129,81,338,748,813,988,140,0,600,305,793,940,783,502,283,390,581,584,689,342,872,714,584,692,378,983,247,284,803,895,512,653,807,505,331,926,550,155,716,849,9,533,456,505,862,157,630,919,337,707,306,222,344,67,99,553,212,289,779,16,86,229,664,522,129,207,367,191,502,528,959,867,618,361,195,81,678,155,454,110,379,941,545,652,712,311,268,246,346,661,724,849,512,331,662,495,880,921,494,153,357,533,585,970,641,684,958,367,962,672,225,796,79,365,924,64,557,477,988,695,774,654,116,379,357,379,812,492,342,714,943,600,92,997,339,724,775,415,91,392,586,326,663,832,836,244,320,626,767,92,139,994,766,94,825,510,217,985,613,786,381,732,758,260,485,458,235,302,881,296,625,335,770,917,596,206,994,479,783,660,13,363,60,69,37,305,96,550,535,710,11,460,810,804,964,84,69,563,704,225,230,905,749,709,608,816,433,49,7,106,49,764,417,926,651,284,396,822,892,586,619,276,278,637,27,139,852,465,819,872,692,95,548,685,68,628,365,187,494,455,560,423,222,714,308,470,651,965,406,169,802,397,398,88,658,971,194,736,571,293,381,390,588,54,997,62,479,708,541,806,784,164,348,370,570,170,194,572,79,526,854,683,180,787,719,896,327,368,41,179,849,512,362,670,585,738,145,344,192,785,70,632,514,69,488,90,925,612,208,731,21,990,657,78,117,85,520,754,59,576,809,60,340,961,23,45,129,55,50,294,495,668,190,473,975,489,904,171,908,349,717,837,424,208,392,485,535,546,911,966,402,266,686,801,621,800,188,332,843,720,949,580,770,993,974,584,762,793,883,717,403,549,629,328,15,963,817,960,25,64,813,60,752,330,340,388,896,947,934,930,867,463,966,886,457,965,506,713,212,228,489,725,525,604,686,26,160,192,14,703,376,629,756,416,835,735,761,713,215,285,34,914,348,206,448,91,643,301,894,129,636,204,760,587,617,470,244,710,405,982,860,383,395,365,933,350,312,621,489,479,698,912,897,912,846,750,591,565,212", "531,59,312,847,757,897,311,8,894,713,525,787,715,642,237,112,366,680,388,562,656,143,529,646,666,416,633,569,940,13,496,834,489,532,150,668,877,219,399,847,44,576,241,935,326,886,999,561,558,631,985,272,904,978,91,155,51,513,52,979,850,609,633,809,509,403,203,718,323,686,805,544,663,21,216,200,922,169,830,233,989,944,975,279,987,970,150,938,288,861,242,815,181,905,639,483,248,991,825,314,87,134,538,260,802,447,518,270,711,655,88,86,124,124,716,496,32,928,824,210,343,521,216,29,944,518,167,173,160,756,385,293,345,564,822,608,634,860,834,236,964,786,149,804,20,776,624,780,632,654,389,33,343,14,857,763,385,135,607,948,667,259,934,628,616,121,956,209,286,577,410,325,14,671,771,928,663,315,267,273,370,418,246,10,104,950,634,881,273,183,466,91,387,211,228,65,777,931,690,242,769,605,277,820,723,281,170,52,638,222,409,572,741,767,784,539,442,803,548,881,877,796,941,860,409,45,858,525,885,931,759,409,399,341,788,341,937,537,7,957,826,808,648,635,728,164,867,498,90,910,849,861,366,60,39,919,817,64,807,963,939,446,652,921,960,544,965,815,70,704,7,693,904,60,327,670,467,858,447,580,258,908,706,171,339,840,536,527,600,730,909,281,500,963,232,678,599,91,730,665,209,58,2,261,525,68,326,886,631,473,148,557,426,225,569,486,17,615,394,348,212,965,472,228,220,242,940,230,393,65,446,825,313,115,925,487,948,28,257,314,401,362,133,704,823,192,788,517,194,885,226,292,671,437,15,123,259,11,461,372,977,539,275,833,680,907,874,197,528,8,151,288,885,409,988,867,411,918,572,598,187,376,366,3,259,78,154,177,346,912,388,190,605,370,534,304,526,776,787,551,991,92,646,22,686,929,165,781,412,850,624,160,740,624,358,794,994,82,857,312,200,663,84,712,746,78,897,319,826,793,182,290,877,678,503,116,670,992,404,658,904,950,933,648,599,897,661,625,688,492,773,559,993,284,290,909,181,249,240,11,223,846,221,890,919,560,344,639,849,447,484,743,103,400,807,159,65,483,518,965,346,361,613,94,839,219,635,322,798,396,660,937,34,214,584,455,355,432,998,213,919,861,362,896,776,357,511,57,286,414,602,8,314,251,148,634,834,275,513,244,760,312,7,965,859,631,183,285,304,60,927,437,184,408,289,106,664,320,582,619,433,806,79,487,696,605,167,963,600,0,594,970,990,664,76,43,309,3,208,818,900,978,896,887,556,701,261,880,362,110,76,558,360,915,739,525,580,961,732,604,648,834,123,690,689,575,162,969,412,131,198,988,867,493,586,171,588,308,782,633,122,515,857,878,56,462,716,321,285,139,529,405,768,99,972,265,367,9,714,564,527,343,456,206,181,469,574,587,171,272,102,249,660,427,170,706,468,191,872,161,345,245,259,807,758,94,414,644,875,316,961,670,428,540,807,536,646,779,357,538,630,755,81,291,315,935,280,250,133,422,989,127,311,223,487,677,514,108,630,34,994,654,142,116,612,575,152,698,398,604,771,430,935,491,29,690,178,829,300,669,829,328,797,460,67,496,238,912,826,180,895,261,29,250,606,499,8,332,642,875,717,882,787,959,364,437,241,380,693,803,335,106,916,729,741,114,66,105,355,439,752,703,146,531,142,385,431,983,542,965,623,911,467,286,735,275,681,779,345,398,125,989,603,742,179,960,190,76,71,837,244,500,239,866,260,373,191,122,431,257,246,956,461,410,6,823,514,106,797,194,641,139,808,240,483,27,820,973,752,910,29,603,550,431,883,656,203,883,932,239,559,63,656,799,542,682,6,942,1000,183,622,631,36,344,642,936,240,164,326,963,502,306,124,269,559,34,460,825,624,688,563,590,436,260,433,860,23,682,26,191,764,485,136,810,548,242,636,289,267,814,720,591,902,458,434,832,916,378,423,246,317,220,840,160,350,92,301,154,786,355,834,181,985,614,915,657,945,986,416,177,51,509,379,553,876,413,882,224,856,245,834,571,164,659,119,498,7,276,725,85,402,498,814,693,679,171,193,246,271,159,449,20,887,74,895,89,218,401,467,484,777,898,393,997,829,52,873,995,292,503,801,947,282,438,189,742,623,634,913,79,317,979,120,17,86,13,108,380,913,772,887,24,5,952,438,967,994,896,257,896,482,801,100,623,572,774,458,6,586,654,574,231,437,167,104,875,285,764,567,206,47,166,662,851,38,284,977,268,839,571", "431,459,712,324,911,51,263,478,12,878,118,697,482,104,773,815,199,518,105,116,910,335,346,792,920,142,362,440,498,435,81,396,536,535,355,871,430,187,944,20,965,752,966,191,649,94,979,675,742,981,885,606,128,935,112,774,146,887,127,631,250,691,801,700,945,747,785,546,571,362,108,997,399,814,714,22,238,34,965,609,64,631,672,611,987,594,109,539,787,813,131,298,118,435,359,92,765,336,595,218,439,914,260,29,148,806,826,884,206,100,80,413,339,955,5,117,912,584,492,478,337,169,725,76,689,865,813,563,609,254,142,384,274,290,481,782,351,481,46,130,359,320,298,589,503,754,29,833,923,429,231,85,137,46,969,482,398,351,495,492,760,606,767,965,525,53,204,874,634,978,177,797,396,301,922,300,184,243,116,200,714,561,458,929,430,896,242,818,641,837,793,229,225,665,692,54,81,627,488,526,925,478,977,676,214,587,265,801,510,11,870,217,305,317,221,528,647,527,170,46,382,331,881,246,164,984,915,785,784,69,973,512,929,941,53,568,72,578,28,718,98,929,795,445,575,59,94,819,161,448,547,783,570,508,259,243,741,675,106,339,684,278,72,999,209,25,124,13,551,965,284,297,340,314,697,969,879,339,191,381,800,919,67,52,373,528,839,903,235,823,865,665,716,530,785,629,67,839,250,27,416,183,733,688,856,43,628,918,291,430,488,101,73,701,101,786,813,864,856,820,970,504,589,881,112,630,341,526,824,738,304,861,890,547,835,133,350,832,130,747,574,474,938,402,19,679,767,61,794,913,646,203,778,190,859,899,545,766,999,411,130,655,835,328,534,345,330,578,873,101,459,273,77,533,123,673,125,628,722,678,800,587,656,533,994,713,408,355,808,522,205,425,253,66,142,276,114,221,308,384,444,195,601,711,15,611,948,563,228,842,238,106,291,270,161,346,62,181,805,390,622,604,690,824,15,254,269,424,420,291,903,93,110,504,781,726,588,821,471,540,953,382,630,534,843,651,409,749,983,394,384,354,632,36,507,407,353,145,905,433,969,498,613,305,679,456,81,246,717,268,816,263,354,183,152,288,249,860,997,676,419,609,156,667,662,180,115,135,961,528,911,151,882,465,283,689,728,920,59,237,430,664,571,404,148,477,337,614,410,159,513,290,361,758,144,240,207,923,340,466,721,212,229,928,712,808,817,253,822,681,668,158,183,707,47,231,80,759,91,447,809,777,986,451,24,692,668,850,305,594,0,415,246,758,266,733,806,556,794,581,55,114,982,808,470,479,528,64,28,432,959,771,246,982,6,706,32,479,878,769,851,669,502,446,157,353,342,705,425,678,572,512,111,925,604,16,655,294,551,130,31,533,527,209,79,310,149,170,817,558,964,353,114,177,691,228,787,480,85,352,679,73,804,358,3,937,321,146,715,617,410,463,604,926,89,855,580,235,163,534,923,631,430,739,685,682,925,494,436,776,561,692,393,964,191,565,919,555,735,990,695,330,151,432,952,625,531,718,621,942,445,597,288,142,161,660,367,761,71,13,378,821,839,616,126,419,737,297,957,791,180,860,364,546,895,251,285,897,98,428,581,542,142,430,127,670,232,864,772,906,143,975,823,860,101,560,870,734,525,179,418,73,585,385,515,434,997,796,618,24,17,216,387,427,136,835,542,749,647,689,979,777,454,739,52,338,245,727,531,699,631,23,99,522,587,501,854,224,367,986,820,554,245,846,89,862,749,877,882,176,16,142,495,235,873,409,472,46,988,192,468,26,603,982,57,250,461,759,851,852,171,525,784,224,36,782,599,967,551,777,214,974,456,780,783,734,297,178,386,442,896,742,269,33,796,208,625,61,405,542,941,456,771,616,662,735,734,324,592,345,937,148,101,463,251,358,957,366,221,872,536,338,20,676,162,379,616,986,329,947,838,376,375,7,688,715,155,331,309,938,330,944,407,506,986,354,237,482,693,766,70,650,413,729,301,707,45,837,300,202,350,441,637,981,516,374,399,715,473,768,630,258,327,295,925,972,403,911,810,960,593,644,154,427,672,332,275,845,360,533,704,723,519,189,770,571,144,8,745,96,825,204,28,486,798,827,399,235,487,873,985,875,229,162,433,699,175,886,742,507,813,93,307,57,724,610,695,380,601,569,119,612,511,197,162,14,886,80,467,168,985,296,944,743,502,66,544,411,530,273,616,807,319,804,965,494,973,726,839,871,669,879,295,722,570,865,225,473,760,5,912,400,49,713,811,563,897,92,450,600", "49,932,321,706,414,425,568,40,388,184,32,248,891,444,29,79,642,382,594,241,701,436,645,66,509,418,810,333,460,622,747,917,216,877,575,417,195,337,884,26,138,353,96,230,348,469,452,454,432,301,189,921,930,979,894,552,136,771,872,530,400,635,942,968,773,434,446,591,579,157,533,578,741,605,255,985,632,18,489,722,276,248,164,414,292,927,687,365,863,718,246,174,427,337,981,999,7,522,618,626,527,204,519,308,945,488,788,963,11,27,673,563,464,94,258,406,658,88,830,840,964,504,389,565,972,193,109,939,227,208,799,456,134,527,934,695,200,750,85,187,604,477,755,800,271,552,948,95,37,649,148,131,967,283,619,136,177,966,492,436,725,799,356,720,448,152,55,220,224,494,791,713,260,973,450,311,275,313,164,382,3,916,368,190,327,635,267,930,285,162,294,14,528,163,711,849,15,195,100,666,323,763,235,875,41,444,978,813,732,815,349,533,410,553,780,405,478,896,639,816,525,767,934,496,830,59,770,390,871,463,131,999,319,473,357,762,680,590,417,612,135,310,775,44,528,576,205,861,979,59,210,183,1,50,313,315,94,833,214,501,258,52,816,258,22,559,254,829,771,355,570,369,281,513,168,320,496,795,158,875,254,1000,943,198,830,817,511,428,515,983,918,734,223,154,548,481,949,823,333,755,817,777,107,119,109,229,676,494,623,564,884,277,742,365,950,94,486,545,518,52,835,928,176,825,519,869,492,754,91,545,714,170,184,506,863,37,802,466,800,551,167,424,299,170,608,113,671,306,439,448,52,782,739,640,741,585,156,553,740,823,179,541,202,485,265,589,925,87,830,906,2,865,634,253,721,965,371,665,694,736,548,531,914,898,235,25,855,810,853,974,242,335,384,693,472,823,822,294,639,690,826,24,180,262,153,638,12,226,904,838,853,877,928,723,773,174,213,784,169,547,827,70,113,398,586,50,922,159,102,773,897,413,553,298,254,209,419,314,365,217,154,209,886,919,610,558,85,702,109,453,463,942,879,181,460,991,98,175,273,337,209,478,380,554,375,950,890,298,281,981,603,967,920,111,755,365,8,459,696,322,488,468,954,92,681,572,518,862,644,970,154,712,738,380,671,522,975,452,685,465,34,494,809,483,762,465,550,327,574,728,559,822,724,812,121,638,288,509,757,679,102,772,711,585,290,886,731,293,737,18,739,310,199,729,96,850,575,150,451,912,612,423,338,842,902,431,142,444,793,970,415,0,81,628,675,433,187,120,313,875,239,429,756,962,850,537,656,458,986,789,247,445,711,337,226,35,755,293,517,312,597,634,859,11,235,469,459,138,7,341,507,687,518,823,582,898,822,284,352,943,775,193,20,960,514,723,295,782,433,664,576,406,407,26,914,696,633,409,108,157,576,925,713,31,742,797,255,387,59,812,159,485,919,181,977,718,438,713,216,892,173,86,539,761,83,153,507,544,337,682,459,352,239,638,119,974,106,89,136,101,906,142,284,708,393,429,980,156,265,331,573,743,150,606,216,995,342,816,572,487,629,29,36,368,239,647,722,627,657,796,344,553,649,343,388,882,467,1,65,384,859,884,823,584,393,640,166,31,681,540,618,843,504,785,404,415,515,88,993,98,448,203,472,455,823,963,153,654,244,337,393,304,788,44,629,287,560,466,908,582,186,403,977,892,434,855,469,622,647,45,16,927,816,794,412,271,824,10,644,964,963,118,652,705,42,75,867,896,188,527,516,900,559,505,649,598,195,925,608,164,539,933,749,722,114,635,536,693,729,289,274,197,646,953,841,925,729,436,510,136,331,759,371,632,26,607,888,640,643,186,681,596,669,754,169,866,720,922,394,321,620,265,571,67,728,309,510,853,811,765,262,507,204,756,565,254,841,331,677,652,624,86,725,78,100,906,92,595,665,231,963,992,799,171,664,648,27,749,828,234,533,471,998,159,697,994,127,829,53,847,617,454,877,302,376,460,55,157,940,371,330,441,870,238,133,572,337,268,889,31,799,671,761,621,140,969,247,969,826,974,306,913,129,673,693,711,584,937,855,614,970,889,318,261,839,483,433,928,733,236,217,459,548,734,439,771,394,191,451,389,163,849,164,568,511,278,251,511,449,105,973,344,661,202,462,407,104,585,264,774,212,819,848,865,76,604,606,545,20,543,562,196,325,302,404,114,299,470,600,979,78,751,278,232,924,323,516,121,703,480,22,259,134,909,147,464,678,105,319,596,946,959,652,990,244,119,216,242,616,517", "80,907,65,885,700,119,957,823,51,588,35,440,536,89,876,973,366,873,4,284,618,931,215,290,57,748,857,239,56,392,457,315,596,839,33,370,96,250,373,831,506,145,153,220,138,941,767,994,768,656,400,884,829,377,946,474,915,327,552,264,354,265,970,149,828,725,444,90,909,847,201,507,441,690,344,8,408,146,267,995,651,126,644,43,733,257,294,476,354,343,51,175,817,775,430,513,386,144,763,376,760,159,622,198,599,865,777,800,460,984,695,385,232,308,176,943,622,940,754,623,998,141,474,37,633,202,353,459,889,771,349,740,665,923,311,146,431,956,458,237,129,43,908,438,886,381,992,77,511,582,385,758,989,366,254,115,192,961,174,729,235,15,448,817,182,659,185,440,809,813,244,605,2,546,543,31,283,903,938,585,628,754,772,300,831,767,296,7,887,216,932,711,622,260,420,512,584,188,108,888,828,337,146,408,515,26,27,830,441,364,93,960,659,923,821,172,319,508,596,671,105,752,497,806,320,743,665,919,223,1000,685,154,47,972,373,929,68,185,268,501,82,705,546,813,834,262,371,444,96,709,216,34,688,896,682,914,809,14,707,238,81,344,29,928,116,936,781,892,456,64,822,35,520,583,996,530,263,769,193,629,120,483,932,332,386,309,886,580,188,592,859,411,226,86,291,211,991,129,922,975,609,53,791,617,350,632,569,470,776,121,105,282,957,932,106,479,60,936,716,77,849,232,558,660,316,599,533,729,811,787,236,468,673,879,691,107,688,29,324,537,339,278,498,185,499,826,849,820,287,357,523,689,753,536,323,348,169,682,421,228,358,941,39,183,986,574,315,824,72,402,185,554,848,26,54,846,630,254,254,411,121,807,471,7,526,557,853,245,428,121,231,195,987,338,880,829,826,913,149,813,979,428,775,336,930,44,293,879,950,328,637,691,675,118,897,557,463,930,790,950,125,790,918,750,860,108,858,84,205,828,937,412,284,402,97,470,611,384,331,882,416,479,928,713,571,13,706,125,986,817,595,193,247,879,838,96,104,360,816,493,718,677,770,382,305,137,249,158,957,187,64,763,709,464,396,929,186,608,177,505,884,182,80,850,453,960,441,808,149,970,105,224,271,300,46,117,26,996,111,686,640,689,360,680,646,120,269,520,15,188,683,636,426,167,238,236,230,532,837,209,485,79,199,682,994,398,935,732,233,373,444,883,246,88,185,25,119,752,221,389,499,819,911,636,914,424,765,325,940,990,246,81,0,37,483,221,366,311,527,612,586,305,192,60,860,185,68,680,687,593,454,93,546,48,810,820,663,749,273,557,245,532,222,857,647,538,347,924,260,899,789,389,66,457,919,775,200,173,137,390,749,491,6,691,893,132,335,532,834,39,93,273,175,869,336,434,945,390,482,133,774,747,480,442,596,694,933,389,385,720,587,167,869,129,760,904,848,992,562,939,409,297,570,278,397,903,741,811,235,669,62,314,100,934,607,108,225,562,439,809,325,242,277,560,134,971,437,72,716,131,397,177,459,766,472,643,562,394,480,356,520,937,75,807,63,464,824,131,537,336,220,651,914,590,690,256,487,457,680,561,284,144,565,317,521,569,205,516,991,45,955,917,685,550,599,874,933,303,308,417,130,716,966,231,274,823,650,864,510,865,286,794,39,162,230,626,759,638,485,163,235,598,614,946,622,129,813,312,495,16,261,213,719,681,337,148,283,408,389,576,349,45,768,922,587,659,520,135,266,374,161,920,461,765,536,347,488,325,916,994,830,371,124,616,271,15,115,712,322,609,217,447,460,389,653,232,620,754,86,483,953,457,173,785,658,550,460,874,242,548,873,532,949,607,60,834,207,556,210,102,376,133,547,817,56,169,201,214,682,486,775,555,846,593,434,683,244,190,893,666,487,62,237,46,169,493,426,973,207,316,394,265,310,795,396,158,843,564,356,225,110,944,940,816,999,478,977,945,2,48,794,279,482,469,828,340,973,741,240,488,523,721,24,934,7,41,509,391,977,301,238,682,839,198,154,409,673,736,449,488,655,165,204,379,598,162,116,862,335,762,165,959,146,70,93,522,511,714,113,721,949,680,964,325,3,388,3,21,767,686,466,806,793,251,103,316,109,158,386,724,147,307,846,344,562,523,968,670,220,143,57,19,97,857,690,798,777,59,69,351,833,851,123,782,575,660,517,218,872,322,353,264,650,463,395,260,61,302,969,911,296,483,921,62,764,95,512,736,637,794,206,335,103,401,647,146,496,39,143,678", "699,612,914,931,648,567,63,823,106,193,990,908,934,46,195,423,166,826,840,430,126,885,830,933,595,619,272,825,919,477,488,536,810,849,599,441,368,854,129,820,717,41,509,464,116,188,733,5,196,778,5,195,681,574,231,256,897,500,874,253,464,87,510,853,313,6,627,70,526,155,197,37,752,722,114,670,846,947,934,942,288,287,840,212,414,915,114,706,560,850,454,962,277,956,24,623,33,486,545,433,562,752,316,961,770,84,746,861,748,182,318,687,181,697,731,53,370,118,755,541,111,932,693,688,84,852,120,561,541,44,263,838,136,684,469,193,548,877,218,507,43,448,254,582,553,652,796,900,441,957,634,619,484,540,793,210,676,212,930,465,474,74,881,552,587,807,730,87,752,698,746,13,936,168,364,863,12,913,755,251,552,139,190,554,313,232,959,343,453,432,273,725,98,658,269,34,481,97,530,472,691,100,722,347,495,482,816,718,63,242,762,307,584,38,29,133,140,393,322,821,298,738,745,394,781,973,683,732,968,308,223,965,404,289,35,904,955,988,52,726,107,731,195,799,806,57,327,980,937,742,894,920,290,434,302,699,206,542,528,140,177,32,685,92,483,329,754,823,461,494,271,480,803,481,442,499,795,248,933,102,203,921,74,359,119,833,52,667,868,63,497,904,320,853,258,893,176,388,435,307,575,675,68,214,195,634,665,891,330,214,13,482,102,638,950,267,357,581,803,63,211,901,502,622,972,155,288,96,72,945,491,450,723,817,143,239,557,825,820,368,335,668,740,941,895,493,316,140,327,575,21,154,870,732,490,232,94,165,540,186,923,493,817,660,274,202,227,142,57,74,595,931,46,982,363,210,46,806,369,917,718,915,397,902,358,643,836,282,343,632,787,325,319,236,23,976,256,90,1000,628,209,727,137,178,590,699,111,441,558,941,116,153,941,608,212,201,290,264,805,399,491,185,245,662,750,117,401,486,734,496,415,180,272,747,922,263,404,751,99,592,730,832,850,421,57,681,752,917,968,220,274,116,7,717,346,697,217,340,834,643,514,954,416,785,686,719,783,274,169,632,116,638,871,976,281,413,626,51,286,865,931,853,669,213,514,276,437,505,326,142,584,720,729,148,78,700,252,106,731,245,979,808,429,753,108,759,907,823,709,212,133,826,416,443,427,894,909,87,61,567,226,150,265,573,694,924,683,2,614,87,468,988,295,466,907,145,606,929,108,278,902,445,824,182,850,760,156,560,783,664,758,628,37,0,990,423,916,380,567,673,955,541,670,509,84,65,189,989,661,387,178,895,516,234,230,120,176,916,212,915,599,684,491,847,931,36,979,518,151,162,273,471,725,831,800,474,210,232,988,999,734,134,545,382,224,772,377,428,239,500,296,686,397,540,147,110,664,53,24,429,184,892,586,439,277,360,945,238,435,147,452,313,448,215,587,602,553,733,18,285,892,198,37,635,822,459,188,528,817,220,193,361,993,840,544,704,46,415,306,846,560,295,153,732,447,343,550,630,924,455,296,109,459,919,926,182,554,502,844,698,736,874,709,352,552,263,454,981,578,607,440,569,632,31,899,792,876,16,185,266,699,893,308,265,367,756,144,364,477,127,713,417,198,478,879,973,941,386,424,119,834,790,139,196,15,644,662,416,945,30,730,904,791,435,286,387,882,75,230,304,718,969,479,448,28,137,866,678,763,648,139,796,104,187,150,852,91,297,767,311,237,429,395,811,92,756,22,897,61,681,118,451,452,627,692,463,910,532,92,885,276,252,398,759,880,565,541,9,812,26,169,530,955,99,227,928,463,515,5,696,88,726,848,350,789,798,602,925,741,204,356,493,642,210,105,905,218,744,304,59,828,995,794,422,226,360,487,40,747,301,324,675,719,505,946,34,630,884,239,236,859,430,677,25,490,414,178,694,934,275,121,622,835,991,497,50,955,617,107,937,464,354,442,782,173,15,738,424,592,490,267,439,795,579,984,899,14,897,414,744,781,303,62,697,352,311,432,230,427,238,545,765,233,208,632,976,179,483,377,522,130,91,318,249,130,585,94,231,837,129,163,568,515,329,470,519,617,593,632,972,363,378,85,602,744,535,877,302,338,953,124,443,734,477,338,105,937,439,100,567,854,489,633,644,792,78,79,983,9,772,58,446,672,730,229,520,743,786,119,333,420,686,186,32,453,965,708,857,698,190,609,79,664,155,719,292,994,571,899,605,192,612,929,134,288,627,918,364,81,218,904,308,628,688,61,750,557,987,887,318", "35,40,962,724,266,895,260,141,569,129,752,327,483,416,86,852,547,157,736,271,561,532,999,270,823,638,764,794,455,835,912,371,941,1000,909,161,373,948,248,351,862,201,951,354,591,673,243,11,557,299,608,985,658,546,760,916,88,300,720,567,500,304,890,778,309,608,731,445,888,86,908,538,644,411,723,649,723,46,314,624,207,885,527,661,346,548,707,447,72,400,305,410,694,760,217,228,623,79,945,733,739,903,265,232,681,754,288,847,813,354,332,546,395,665,343,311,287,567,816,726,889,327,100,731,16,883,101,263,657,949,457,45,17,9,93,217,939,562,265,545,393,350,656,387,333,268,348,617,453,797,492,249,190,861,456,416,739,346,695,702,835,640,434,143,265,206,311,219,581,149,766,868,244,323,602,800,651,874,128,754,272,577,906,984,203,152,736,953,793,96,79,760,150,868,324,443,933,823,899,796,104,273,282,950,394,428,265,234,54,408,362,258,452,684,106,193,822,88,643,478,547,743,377,142,168,820,240,557,616,916,712,793,272,827,785,49,374,944,253,714,441,820,709,523,1,936,175,819,167,899,17,311,87,884,820,298,590,286,502,208,945,902,718,11,351,769,545,767,582,400,826,276,62,211,371,898,895,436,183,977,881,747,829,524,1000,22,523,398,843,328,663,85,224,243,132,566,925,483,653,607,736,613,879,579,463,17,801,196,311,99,842,833,23,167,93,858,681,785,245,865,861,692,871,782,884,192,794,427,837,660,663,184,985,948,249,201,291,197,601,378,343,697,243,355,683,290,105,470,156,79,587,53,278,626,279,38,185,610,802,739,25,541,381,341,874,519,170,726,956,700,438,135,748,256,76,180,992,743,289,750,527,446,736,909,97,531,278,294,74,66,830,337,514,339,372,925,522,844,23,999,546,318,816,334,763,509,491,771,137,635,824,424,962,859,588,732,48,244,2,780,195,266,588,114,459,214,373,439,554,845,393,123,661,11,462,577,136,22,217,218,292,989,770,304,668,224,286,247,986,943,118,617,557,39,753,729,115,555,418,648,833,348,302,39,800,265,396,108,679,454,680,889,57,476,669,428,850,550,237,875,870,62,413,593,261,657,886,489,191,230,636,184,549,579,637,860,151,387,92,718,232,577,452,423,630,81,883,7,144,961,158,526,71,53,437,87,438,653,919,860,266,800,584,714,231,166,330,397,239,424,481,311,65,545,383,435,551,456,179,190,841,123,477,233,276,13,259,361,502,76,266,675,483,990,0,722,888,250,324,489,938,476,536,32,251,740,598,458,962,56,716,972,343,550,461,251,978,806,455,937,734,63,799,330,916,553,110,162,979,668,844,715,511,379,793,520,149,446,989,524,909,242,984,912,994,174,796,327,336,383,850,569,162,23,668,609,665,943,422,422,732,328,324,843,506,263,231,695,277,125,180,568,448,348,971,947,415,38,657,170,111,166,273,134,369,911,19,937,563,943,329,920,871,194,823,570,193,139,535,142,987,88,949,765,230,791,709,279,804,389,587,985,309,38,678,398,478,195,53,448,941,942,411,308,257,777,817,628,671,807,660,692,54,206,78,980,626,906,621,283,157,987,535,744,633,538,85,277,729,313,959,300,159,775,248,166,262,146,856,166,736,650,352,40,885,673,752,735,537,406,772,39,577,343,58,527,658,839,569,667,952,556,823,938,418,874,644,499,528,800,670,841,756,437,555,9,60,63,860,507,389,9,778,897,894,897,398,233,974,183,11,169,437,673,741,743,755,470,425,850,765,609,632,84,7,493,763,56,52,962,12,161,76,713,634,225,478,294,29,369,445,572,54,483,35,211,23,230,204,805,801,435,528,884,965,4,375,985,165,275,551,403,279,848,358,308,651,665,777,107,179,524,151,988,401,15,363,597,103,982,942,493,734,640,478,715,863,8,502,824,813,499,687,844,299,663,506,663,273,483,802,912,858,646,414,65,771,394,679,462,510,470,729,428,236,722,449,763,968,675,977,315,501,387,302,311,598,323,633,20,881,346,109,398,278,763,565,846,328,749,791,297,642,950,169,503,777,308,986,984,100,949,942,495,623,27,426,574,733,686,429,648,109,388,850,204,230,448,149,139,339,940,828,205,817,815,203,345,778,447,920,768,603,685,289,841,406,101,753,151,728,764,882,185,349,240,871,961,333,745,369,792,60,493,490,601,612,23,494,866,771,687,482,974,291,444,188,643,228,30,36,932,562,286,650,277,460,947,712,864,383,998,972,818,85,609,50,270,894,494", "345,138,71,124,682,664,523,401,90,681,752,558,749,589,826,983,941,915,105,119,466,295,839,559,487,907,392,211,491,367,557,943,945,677,440,32,279,990,385,116,967,754,171,753,271,968,742,939,435,902,85,617,991,196,908,299,388,761,311,880,150,373,182,425,984,744,379,275,998,443,856,882,374,386,898,32,870,900,172,765,225,189,602,271,442,622,990,775,968,207,982,116,680,700,238,975,48,55,968,217,22,16,431,756,809,315,952,577,821,737,575,584,134,433,973,505,464,193,103,310,305,194,417,361,489,442,900,155,678,532,827,457,975,286,506,463,463,478,872,604,693,467,320,896,522,671,357,813,131,478,611,375,825,234,945,838,770,767,33,825,570,786,17,264,126,241,117,380,280,54,265,360,76,445,33,39,326,980,401,150,266,823,504,893,131,780,900,446,326,286,392,718,434,672,275,728,641,495,227,969,336,108,900,203,33,36,98,940,94,849,208,879,695,556,21,753,791,152,696,808,160,723,513,331,635,246,557,515,632,947,334,792,97,78,131,548,636,626,815,369,159,47,190,395,940,613,706,817,710,734,16,638,669,344,121,848,657,770,864,217,85,13,50,926,422,427,356,961,739,795,277,762,849,525,983,869,977,515,186,544,644,933,748,178,356,71,564,661,366,544,968,366,389,866,228,237,449,130,148,789,762,996,296,301,84,886,61,508,47,875,950,905,808,84,915,568,939,162,21,44,995,459,870,698,38,380,236,860,20,498,33,630,994,61,814,825,252,859,745,446,812,620,792,478,501,703,258,983,24,771,622,48,178,689,194,562,400,91,986,451,58,614,946,954,914,828,668,425,403,326,316,189,336,685,560,829,3,338,966,502,10,747,545,392,400,206,490,952,460,964,97,535,161,887,566,485,410,990,211,157,766,968,575,103,218,124,807,832,454,297,619,323,672,156,145,824,931,858,107,276,254,270,860,651,700,507,368,744,774,582,69,538,779,909,655,640,234,143,943,961,331,792,230,869,11,595,40,868,7,480,929,547,7,791,712,375,118,495,705,237,373,936,993,360,83,487,903,936,889,153,630,595,411,751,593,174,26,665,551,46,412,668,840,821,276,908,109,205,453,771,299,14,379,426,234,836,105,365,401,458,117,439,426,988,606,251,464,250,214,323,664,888,60,425,441,274,859,513,248,642,540,141,795,455,246,342,782,337,159,789,918,998,338,991,487,160,787,740,463,456,186,954,690,855,530,754,529,950,283,43,733,433,221,423,722,0,958,214,878,59,585,303,765,405,676,827,707,43,167,164,469,350,449,151,650,305,349,236,498,788,729,913,162,232,126,436,231,23,574,405,402,906,851,780,973,127,281,945,805,251,846,886,851,573,264,303,331,219,974,951,239,750,732,600,16,167,954,993,589,955,325,806,432,829,567,204,601,558,552,646,704,925,55,830,534,734,169,881,17,765,709,410,924,231,957,839,342,772,880,881,522,272,215,36,857,888,276,689,819,34,87,301,297,282,590,489,210,56,945,574,789,511,998,694,472,193,128,206,59,376,184,639,630,646,442,942,30,179,882,563,206,393,431,128,140,995,23,13,730,401,524,344,427,848,319,945,253,873,982,708,215,826,67,327,516,2,915,260,858,557,225,894,17,689,144,574,858,784,986,421,266,56,673,568,897,589,658,159,998,977,108,137,339,873,756,497,163,668,319,850,565,666,774,703,408,637,242,449,28,278,369,201,791,117,164,367,325,795,401,263,327,566,298,284,239,60,394,610,240,697,806,359,82,543,796,120,40,184,870,11,13,271,158,109,186,579,265,156,615,54,6,529,322,336,37,602,263,496,184,364,651,203,823,595,336,231,241,811,847,293,825,780,789,544,150,111,247,90,254,800,338,652,224,87,750,760,459,40,968,594,32,191,957,570,359,916,8,467,248,889,658,147,569,156,634,528,681,382,460,934,642,769,32,234,755,246,126,516,81,914,924,635,347,708,377,480,830,737,423,570,832,631,926,383,662,542,821,496,260,118,178,585,423,207,425,178,458,926,766,945,733,390,395,430,52,164,576,11,419,854,76,671,713,377,155,152,996,301,178,287,781,327,495,107,315,74,192,473,430,309,681,727,896,181,100,907,468,356,751,612,328,540,727,133,521,643,487,835,618,235,202,416,407,541,525,316,427,51,436,468,391,451,91,564,364,20,953,498,401,774,552,175,912,4,698,77,139,501,746,62,699,984,52,867,390,672,818,501,883,622,340,252,576,499,959,98,91,886,760,246", "830,857,172,423,578,536,834,352,572,980,690,310,466,278,335,101,176,51,10,206,650,774,131,293,308,911,741,569,1000,20,597,43,122,920,753,892,614,181,986,143,172,366,268,987,564,298,479,559,801,65,814,513,773,833,163,37,657,569,913,804,647,60,103,345,845,568,892,354,219,322,104,636,831,597,530,67,894,125,49,647,302,243,683,740,901,115,218,681,943,848,383,286,801,358,381,876,457,870,829,933,303,177,752,992,808,968,736,648,798,798,901,581,178,574,512,739,608,856,695,846,901,49,970,224,808,885,430,803,316,235,501,964,536,873,212,901,416,570,937,371,294,702,13,98,188,606,320,995,91,194,94,153,627,605,530,973,460,204,267,685,161,320,798,240,878,522,510,179,973,518,945,575,349,417,566,388,129,961,562,616,433,55,209,30,733,769,437,925,754,586,768,21,783,150,750,217,497,143,886,474,115,989,442,148,477,414,386,416,643,933,60,340,445,33,327,946,760,304,75,663,456,706,636,887,655,674,727,554,417,930,980,495,582,698,106,978,643,733,712,39,563,257,907,78,840,774,281,339,918,600,19,363,474,564,502,355,17,865,976,934,672,724,880,272,937,375,84,967,315,924,189,379,937,977,987,939,326,833,371,997,524,185,111,13,62,650,845,957,596,707,459,604,399,470,574,780,892,303,987,145,893,184,887,797,835,646,424,396,123,785,100,881,830,594,116,301,215,46,138,901,104,589,236,440,849,647,755,303,406,490,81,803,995,951,290,357,36,536,955,626,448,305,722,795,445,761,915,59,321,144,263,938,588,200,427,86,461,564,404,31,289,46,167,768,181,217,800,943,742,948,377,806,736,164,471,314,376,228,891,423,613,721,257,488,40,638,296,794,275,728,444,84,920,462,690,792,981,954,874,774,321,376,589,342,513,65,666,491,969,680,785,371,252,311,741,450,105,564,449,967,405,533,872,505,906,168,560,455,206,759,706,563,62,280,42,390,966,833,685,542,864,395,695,436,907,675,928,896,812,873,972,15,232,828,449,25,35,394,242,29,856,293,71,603,967,334,12,743,142,204,112,647,399,707,401,970,198,845,546,88,4,677,730,394,65,389,693,241,140,510,51,263,499,336,381,858,3,496,454,710,47,429,381,994,130,651,193,348,495,395,810,565,225,467,505,234,761,94,781,3,876,929,868,602,797,972,693,228,942,146,786,778,705,235,251,923,993,727,501,914,224,881,772,283,712,906,518,301,390,309,806,187,366,916,888,958,0,668,956,755,383,104,191,627,444,43,364,501,642,460,498,394,144,941,549,768,368,871,6,52,500,650,721,207,258,511,776,922,675,493,471,471,860,639,887,598,94,941,626,56,971,44,729,174,404,336,845,384,862,89,43,97,51,729,227,886,309,445,388,121,39,763,93,629,992,448,727,344,286,55,410,835,30,325,724,674,566,987,123,363,432,730,854,281,623,885,24,754,399,327,815,957,161,952,832,551,841,323,8,596,877,233,41,861,539,258,323,755,715,542,122,181,421,468,164,433,361,625,866,227,588,577,132,61,39,590,459,297,488,654,193,504,772,986,796,660,920,552,566,232,119,553,122,708,697,496,532,421,777,888,576,398,544,205,123,216,767,58,268,243,551,781,50,853,502,690,794,872,270,46,327,389,880,723,271,315,980,282,472,432,11,904,294,577,756,159,398,429,811,498,931,916,38,871,193,189,956,80,945,897,321,549,185,119,408,929,198,421,913,167,48,135,813,481,808,180,841,12,220,144,911,327,538,54,906,244,764,448,739,301,75,399,585,288,407,699,70,270,194,528,341,131,138,335,58,170,890,730,173,976,5,82,645,722,690,266,713,730,867,508,877,356,879,356,147,515,937,556,64,487,602,629,439,345,806,967,768,538,113,472,314,610,562,592,468,137,514,802,428,686,200,469,404,450,208,597,534,381,520,734,512,388,517,606,241,873,283,307,640,364,129,835,542,556,204,964,305,770,40,115,546,907,702,387,545,973,215,574,237,693,808,844,40,372,184,746,540,902,344,937,796,451,904,550,105,493,304,73,340,543,755,721,76,773,560,660,86,17,65,733,775,825,401,702,337,730,312,42,937,458,318,434,728,766,667,376,759,380,919,203,453,189,541,561,553,292,191,438,34,149,796,641,386,862,123,263,552,394,896,80,327,990,313,815,539,424,530,179,502,507,777,955,490,781,334,456,948,112,22,496,601,86,642,46,982,834,437,603,151,982,344,366,545,185,688,410,736,516,105,835", "687,958,795,731,597,207,747,426,66,786,13,806,521,230,679,62,338,582,207,64,141,634,90,19,453,366,18,774,744,293,277,496,662,946,400,672,260,622,786,459,390,233,188,689,397,843,149,773,139,307,221,431,785,272,201,224,313,469,912,911,971,256,490,938,128,895,119,520,901,265,833,520,578,932,519,529,577,877,511,545,862,818,139,24,161,846,819,853,962,665,356,398,463,230,244,785,339,533,391,729,444,842,486,636,139,154,804,692,37,362,693,796,364,998,351,43,193,15,772,545,694,94,731,594,950,823,485,338,413,228,48,908,938,23,169,885,701,557,383,448,457,529,318,442,635,524,170,865,779,120,338,351,428,696,267,584,63,180,713,103,120,755,598,114,123,12,732,972,461,514,686,481,953,65,157,615,235,575,678,136,877,261,525,803,604,170,80,708,69,808,308,685,284,317,279,647,962,459,896,76,247,691,782,357,589,728,282,349,376,55,400,548,568,902,936,267,315,852,202,392,479,43,961,373,781,919,491,731,902,847,327,181,433,213,377,14,462,771,59,654,307,501,183,943,631,560,680,351,410,485,676,624,811,760,356,188,556,905,797,68,134,162,394,524,965,928,810,743,10,709,880,720,668,432,367,498,445,565,925,633,928,918,481,53,261,654,806,780,466,623,122,838,106,100,201,714,543,976,560,15,367,846,380,438,816,461,409,241,648,436,437,674,955,225,405,122,2,426,700,798,855,48,940,786,30,341,820,667,787,464,593,205,638,562,580,147,698,713,699,893,59,897,156,382,190,287,535,697,712,512,40,231,915,28,597,701,60,245,703,46,814,349,621,508,923,745,697,979,784,835,385,896,996,943,297,148,256,59,599,780,976,894,648,399,711,400,760,222,466,575,561,453,3,808,552,926,434,877,791,681,429,959,586,415,458,801,960,434,792,534,711,392,98,423,28,702,522,647,555,512,125,786,419,638,181,316,354,714,14,145,670,492,417,832,636,397,136,708,821,764,903,346,2,13,247,498,46,432,501,943,689,727,614,679,799,898,974,954,510,19,141,48,111,545,282,234,794,224,421,949,979,574,228,427,698,268,715,565,899,535,377,726,950,554,252,6,48,285,716,623,420,797,658,951,848,486,62,971,180,334,156,823,207,580,692,412,526,549,585,704,654,229,489,503,229,706,344,664,668,586,792,925,179,767,489,970,183,286,252,252,997,727,348,734,504,776,827,158,18,137,489,627,862,556,801,806,239,433,581,3,556,120,311,380,250,214,668,0,882,69,887,921,992,387,436,709,238,704,730,179,760,68,304,91,493,10,993,856,512,545,884,800,266,111,688,728,651,638,875,293,745,41,176,203,751,85,289,779,691,902,891,434,609,78,865,589,830,495,831,876,576,996,335,731,804,36,200,994,624,301,887,945,46,841,808,397,867,825,110,13,414,702,140,136,900,622,978,291,192,170,118,195,703,338,251,422,957,169,609,209,523,466,874,853,599,429,2,291,947,854,390,241,411,712,375,140,694,787,428,939,977,169,126,52,692,65,617,232,64,236,112,444,26,696,990,106,730,963,457,77,787,633,9,903,733,394,300,798,634,42,208,193,203,76,443,813,280,933,818,637,606,499,588,992,896,732,288,142,144,251,682,270,33,774,20,696,288,690,229,166,619,243,246,314,348,853,58,562,160,169,453,174,425,752,891,493,731,267,123,580,714,324,158,333,620,81,518,420,680,331,917,512,396,35,48,720,999,992,680,201,663,511,968,928,368,755,724,538,405,840,652,154,401,163,356,705,80,254,505,62,768,384,425,379,598,415,546,305,980,98,235,115,445,995,276,905,71,825,502,387,745,906,102,423,968,865,634,380,891,147,617,706,543,890,564,18,757,495,391,608,511,917,885,440,822,83,89,526,837,178,602,471,32,858,467,755,489,184,462,750,862,328,527,555,920,326,282,745,32,861,463,802,437,118,601,787,829,392,700,550,625,508,566,238,470,21,948,797,42,85,490,552,164,285,234,208,472,436,841,333,985,377,716,637,691,551,861,920,834,879,669,272,175,336,499,321,615,443,258,804,311,949,801,80,114,521,170,153,268,46,29,522,308,313,51,642,441,720,54,333,923,391,855,398,992,101,830,988,207,222,575,359,691,875,337,74,668,953,193,439,206,541,442,377,228,693,460,199,575,40,884,842,239,42,18,459,587,955,481,993,328,417,738,482,244,713,29,461,522,433,390,398,721,74,52,776,922,821,241,758,540,707,265,863,133,653,661,388,386,382", "406,614,973,15,447,162,627,905,622,667,746,334,745,113,233,49,558,79,158,116,910,218,389,232,201,288,591,986,32,912,234,967,55,491,468,294,326,753,191,645,485,190,386,362,416,892,598,703,630,131,198,788,207,6,924,948,350,872,393,544,496,437,559,581,764,505,727,804,238,688,772,423,631,837,464,926,596,360,762,984,927,476,26,973,714,352,277,728,1000,110,155,463,889,169,393,119,602,545,145,978,635,991,115,428,650,736,291,403,83,254,483,312,929,547,653,872,747,507,935,670,446,164,272,290,951,799,177,715,501,700,501,95,456,963,643,228,360,590,855,70,245,529,568,19,836,748,60,551,164,878,637,260,524,133,547,389,910,937,348,634,713,923,670,531,51,613,536,948,761,153,449,176,947,769,526,747,292,826,229,685,168,518,478,279,124,542,285,97,491,113,477,818,37,684,761,60,497,249,474,604,519,222,713,824,438,673,420,957,593,327,242,464,282,682,500,701,615,744,281,213,315,491,198,412,109,137,875,545,929,216,112,687,622,862,63,237,581,334,629,71,456,594,841,787,274,285,673,836,29,386,723,11,685,680,560,986,452,657,145,959,825,128,140,610,263,377,288,448,224,899,822,534,714,849,289,838,682,347,396,363,14,131,815,329,431,547,581,589,920,476,245,395,814,262,797,272,468,959,458,293,933,217,88,321,606,64,683,695,385,687,231,59,732,991,492,940,63,368,943,183,930,812,492,987,266,887,591,240,620,137,797,182,581,910,100,524,180,654,805,980,727,339,641,307,257,109,621,728,834,761,644,404,343,53,819,225,349,3,417,977,667,963,653,81,64,761,908,633,635,394,667,155,455,16,661,44,85,885,956,205,975,20,815,640,789,677,9,68,53,699,814,654,418,292,322,214,480,719,637,512,151,282,617,469,748,419,212,442,678,806,256,544,208,887,597,128,41,845,342,918,603,202,159,193,264,569,33,22,938,339,526,24,587,172,447,213,463,659,527,484,110,617,817,666,340,780,545,341,503,997,285,40,418,442,772,756,276,626,787,197,522,439,147,168,673,299,103,781,280,891,845,333,11,335,193,532,994,131,103,77,958,370,396,871,111,235,660,984,701,347,559,815,146,983,885,812,427,17,731,826,196,547,792,183,188,156,415,915,28,558,720,80,857,711,935,633,219,304,284,813,531,924,116,227,880,197,920,208,378,471,796,562,793,336,410,568,484,546,227,99,172,419,304,571,13,272,503,117,584,208,794,313,527,567,324,878,956,882,0,136,377,151,77,385,321,651,94,681,69,827,642,455,808,651,41,340,347,315,807,369,987,519,69,140,21,628,525,357,649,260,459,259,795,700,26,880,176,512,819,424,483,506,158,324,475,655,661,827,496,632,265,50,216,616,581,662,410,54,437,356,513,574,836,480,217,872,290,582,599,209,382,305,149,914,304,848,639,704,323,87,808,86,690,16,662,432,255,173,888,432,17,286,945,187,159,169,123,946,509,871,206,95,430,780,532,619,24,606,937,813,314,701,344,419,325,294,414,374,979,437,27,519,227,261,443,757,11,725,333,607,425,787,296,485,916,701,438,581,92,730,573,233,721,305,960,191,488,837,903,434,477,7,373,441,439,632,821,280,502,101,71,817,435,159,584,906,800,633,558,984,138,569,697,848,973,68,110,614,221,178,967,261,505,20,348,49,410,244,394,337,959,947,232,209,7,413,245,900,283,32,757,425,387,725,815,907,739,661,725,816,210,326,888,769,247,124,428,359,85,411,24,632,330,817,267,287,28,999,127,913,914,294,352,126,795,56,589,98,442,23,74,984,47,958,274,340,137,913,866,866,299,971,71,724,220,2,316,492,916,279,123,883,728,853,598,234,700,668,187,591,281,639,639,231,16,272,43,191,815,16,192,226,190,688,548,38,979,109,175,719,725,154,382,49,898,132,236,16,839,663,95,586,695,272,763,676,803,796,664,391,715,347,107,825,625,632,747,916,619,898,612,101,313,717,237,514,89,802,891,37,558,619,47,282,324,420,66,533,765,969,206,460,118,970,21,88,484,355,585,506,356,79,589,831,629,929,428,862,646,34,627,250,905,293,348,268,407,965,915,382,965,377,52,658,652,703,732,416,690,658,394,401,901,857,921,451,75,473,788,169,838,601,683,589,757,406,709,826,552,881,652,663,448,276,572,875,610,468,562,895,884,332,506,648,547,779,237,47,806,744,779,872,674,178,83,704,838,641,19,610,972,436,159,13,319,564,333,266,974,245", "605,164,430,553,734,841,863,647,101,71,626,809,358,281,344,336,718,432,283,937,235,358,929,353,176,658,618,818,349,857,600,71,800,34,759,746,192,756,330,824,244,133,223,632,882,363,694,448,217,106,395,609,458,508,121,8,137,259,921,649,98,134,46,889,506,856,423,962,725,868,492,661,654,940,252,437,148,351,685,660,23,478,883,478,310,959,535,618,326,677,699,540,94,547,460,218,96,834,298,835,622,249,650,626,454,957,550,421,357,148,688,807,486,795,588,411,381,198,985,973,509,833,107,531,429,371,430,10,282,853,221,815,634,367,809,272,450,291,393,861,782,463,380,569,752,627,136,698,299,477,966,348,476,199,866,386,177,458,295,12,852,965,469,531,508,150,594,746,586,899,362,750,340,570,41,99,879,308,360,287,475,176,863,908,433,351,3,925,825,88,912,76,550,797,633,18,862,216,882,672,148,920,612,591,849,474,80,496,36,399,159,872,376,359,971,19,404,214,39,359,356,312,907,36,550,57,512,189,41,152,420,637,6,300,844,831,727,776,742,449,776,607,155,119,547,803,965,659,754,123,560,699,850,321,450,346,674,675,312,148,834,413,536,355,355,985,676,885,599,289,484,902,479,465,46,770,974,776,30,653,966,185,157,711,794,728,765,798,765,359,951,559,180,694,168,126,278,20,800,214,447,521,822,725,299,981,186,637,654,663,586,2,678,275,307,480,653,554,148,560,933,769,462,815,267,155,892,97,116,594,399,28,133,649,955,997,204,875,549,184,368,167,450,719,512,248,881,802,932,118,574,411,985,549,365,106,931,156,507,408,802,609,536,833,923,498,234,606,727,971,865,764,338,582,201,64,19,621,69,923,212,157,942,249,485,159,419,531,333,720,810,327,359,707,525,347,121,163,315,699,982,234,133,602,393,298,342,391,741,198,946,696,53,877,261,204,267,980,325,509,376,331,952,423,405,51,472,378,732,557,913,494,553,506,988,537,525,210,427,333,795,826,227,401,906,577,417,691,129,156,910,777,571,271,367,819,935,105,494,958,367,200,820,872,735,825,867,263,601,247,274,903,147,575,219,929,559,330,622,649,222,790,299,699,702,840,328,77,456,171,411,482,289,262,627,278,635,637,921,399,933,306,631,618,934,738,15,272,850,113,893,795,962,130,70,426,672,844,625,773,396,433,663,971,17,997,558,536,475,768,415,662,632,781,350,143,76,38,47,322,468,771,48,729,12,929,541,784,689,818,581,875,612,673,489,59,755,69,136,0,789,494,9,623,573,325,596,825,484,626,349,254,239,237,188,691,444,52,496,630,623,69,260,750,649,655,666,990,598,83,476,517,222,881,901,623,327,229,48,464,841,563,248,47,459,602,52,583,928,115,155,734,390,363,591,755,292,879,554,288,174,64,522,271,221,752,180,908,63,408,972,70,217,648,65,99,335,28,247,120,598,794,868,731,577,116,74,944,952,498,427,693,948,303,627,929,602,774,238,232,849,808,662,129,487,10,887,289,812,714,591,986,2,51,395,650,572,277,451,149,166,303,501,355,591,669,886,388,816,363,404,900,902,796,265,909,721,567,290,769,54,963,841,893,678,570,692,753,712,80,61,59,415,796,960,311,476,761,637,96,298,389,540,352,125,924,89,716,634,328,215,170,114,625,617,231,821,977,571,869,434,489,732,297,419,201,30,249,507,865,123,972,75,756,310,923,266,784,561,450,603,94,239,174,860,121,353,335,760,82,829,227,476,123,452,229,138,732,287,480,729,550,202,572,719,604,450,937,120,409,388,729,921,316,634,548,686,412,161,273,487,171,138,739,510,135,408,180,988,949,603,907,166,797,502,20,81,236,321,841,50,243,184,728,908,931,949,953,535,185,173,972,392,532,251,272,216,310,931,551,955,744,420,458,91,22,146,301,236,319,650,824,517,977,139,924,643,931,497,506,710,347,203,825,494,173,574,24,55,311,104,687,981,702,333,499,912,517,495,475,650,802,321,304,652,867,305,418,830,962,628,803,561,726,521,390,635,341,167,894,49,298,711,363,968,796,201,890,504,187,612,905,386,508,308,747,453,5,915,59,422,189,933,879,14,567,959,987,492,424,135,148,18,878,147,27,918,843,487,993,679,122,636,334,434,214,443,877,898,70,837,735,579,553,524,846,466,831,489,628,770,226,492,494,161,29,129,62,650,325,485,48,180,638,951,542,166,38,995,698,524,409,931,650,210,787,137,576,915,116,464,327,627,345,404,117,291,552,418,292", "872,338,355,949,570,227,691,757,335,666,492,494,538,107,808,613,53,84,238,663,548,387,211,796,27,528,809,262,529,761,390,971,918,73,824,106,551,267,398,562,743,704,150,867,938,710,774,180,608,249,725,769,747,203,976,470,242,86,94,288,289,199,719,330,625,917,877,567,264,526,232,344,145,994,208,949,16,459,795,674,596,895,723,976,554,256,187,280,375,326,394,294,412,368,976,360,293,119,173,593,560,436,889,358,984,372,8,66,958,946,887,590,200,611,803,787,310,7,391,641,207,529,476,776,699,442,50,627,660,721,383,670,409,240,642,584,682,323,19,914,915,135,937,161,731,585,408,317,506,167,14,26,498,198,926,820,38,3,439,393,49,205,953,156,959,464,254,257,696,527,503,506,589,324,764,938,286,600,648,282,248,698,451,604,866,491,44,126,120,903,367,531,384,646,348,121,784,5,854,892,804,488,603,256,573,966,222,283,254,802,642,372,717,596,954,245,111,750,198,936,663,484,887,776,481,824,147,696,551,405,639,49,122,836,779,882,326,773,799,745,71,694,993,946,168,636,963,994,733,908,835,418,720,657,445,409,962,577,798,420,776,42,668,934,137,491,380,907,339,870,468,746,75,546,166,604,139,874,738,121,287,840,569,927,650,198,344,60,612,435,653,380,182,18,360,518,6,417,120,915,531,951,19,724,889,260,94,652,132,722,786,233,144,513,30,381,448,684,368,426,126,397,825,271,228,158,69,49,690,897,133,175,402,185,473,747,793,166,394,178,624,185,801,567,639,752,651,151,803,244,558,982,905,50,389,942,405,688,271,931,596,287,391,235,336,271,840,453,743,879,169,902,98,752,524,173,94,910,196,587,877,125,941,443,540,101,809,353,377,952,689,939,461,623,293,851,422,22,148,227,643,617,432,348,687,808,995,167,505,110,758,319,427,587,636,468,504,707,469,78,862,768,215,76,234,385,357,834,148,33,894,296,976,309,280,779,539,35,539,43,391,846,60,335,528,909,454,159,948,179,408,581,800,886,566,39,663,879,935,366,135,748,815,118,111,657,424,472,900,579,727,621,73,997,788,413,597,469,469,593,201,483,732,662,220,321,575,262,144,34,607,853,198,603,50,216,772,15,554,143,737,240,856,260,285,599,583,283,948,53,257,297,284,928,295,84,491,832,592,92,827,704,886,740,151,515,611,806,524,954,724,900,989,542,44,628,59,32,364,267,143,941,641,523,723,184,755,381,342,900,55,239,586,955,938,585,383,887,377,789,0,665,350,405,16,221,70,153,35,905,464,424,200,572,795,592,344,417,323,864,418,864,409,69,722,187,586,518,315,287,557,280,912,827,237,284,395,390,717,850,83,808,444,616,119,792,937,199,937,250,292,701,396,244,937,265,265,508,502,697,77,600,865,110,87,584,171,97,121,801,666,854,933,963,124,830,749,317,150,841,553,449,388,321,586,154,46,743,162,50,407,348,500,119,905,277,967,350,796,248,533,30,55,133,87,645,322,73,899,879,423,321,693,738,395,587,4,291,969,779,838,855,534,837,521,80,899,266,641,307,116,999,67,50,768,995,473,452,966,696,60,472,465,670,295,76,243,512,485,852,117,993,86,26,568,802,437,385,124,572,468,509,272,582,629,170,267,545,796,551,236,728,913,216,922,167,960,186,838,655,130,576,30,96,325,303,796,711,594,978,266,636,642,304,214,549,90,812,985,566,388,967,8,858,952,145,861,47,610,652,493,461,731,305,927,804,738,923,664,145,599,704,147,267,158,384,173,181,153,305,394,887,698,811,869,391,208,470,153,347,982,831,646,690,116,693,697,945,478,587,183,235,186,247,655,496,863,746,91,372,749,873,848,415,685,870,793,246,793,128,747,850,382,246,316,151,80,530,913,343,852,578,497,12,788,484,715,413,910,300,762,651,104,17,142,512,686,284,940,524,830,623,417,178,204,145,834,162,961,194,727,691,352,729,79,156,849,498,327,671,834,816,417,131,37,882,48,528,234,472,401,153,891,534,563,405,30,953,780,868,3,229,773,390,790,9,941,538,491,772,474,202,502,568,539,204,141,244,708,473,883,252,741,845,740,720,977,128,13,295,394,572,882,289,450,867,870,977,789,611,951,481,93,720,401,733,668,939,263,305,437,870,695,318,219,690,748,441,506,776,671,344,696,188,888,484,250,823,927,167,895,390,317,572,808,37,757,961,311,172,725,865,371,449,98,232,187,250,446,972,331,540,617,191,73,547,455,600,199,24", "293,5,969,79,236,760,192,950,319,663,320,601,815,962,105,505,407,182,872,149,512,407,534,554,962,939,270,832,121,294,994,101,179,680,491,524,61,603,298,229,134,154,318,174,798,400,13,205,993,53,877,537,77,524,43,661,513,17,550,59,450,349,442,484,255,300,426,378,759,899,651,494,603,397,159,153,98,517,548,200,630,188,680,256,667,828,289,634,246,700,707,646,760,276,953,436,670,869,545,36,885,888,929,511,476,164,214,192,599,7,717,304,234,386,898,56,723,239,623,58,574,810,756,370,497,626,672,771,566,698,581,661,480,894,28,730,248,521,44,392,601,171,783,491,412,802,142,657,5,587,326,290,455,134,673,845,915,676,510,26,522,39,989,980,167,823,783,969,839,907,450,661,98,204,586,133,682,467,668,873,379,67,691,391,131,628,885,886,210,393,582,547,571,47,282,164,610,979,192,349,946,434,704,915,837,974,156,636,773,121,774,29,954,870,377,417,4,125,508,117,35,207,212,415,351,30,639,273,188,57,613,174,364,104,637,190,495,109,74,878,52,664,985,347,182,332,184,609,477,149,579,576,968,572,97,419,194,569,23,963,938,683,111,943,874,580,526,353,753,50,834,454,505,902,901,952,806,526,211,36,290,343,20,629,17,623,804,824,878,123,108,652,712,332,666,418,392,904,914,212,98,519,798,806,235,131,211,684,180,843,524,742,797,917,924,12,58,713,354,414,768,654,729,491,278,200,523,387,150,842,826,821,102,401,239,126,232,375,865,442,157,205,609,70,256,895,259,829,105,624,102,685,36,648,284,217,161,493,45,224,803,432,923,667,375,32,293,990,411,234,544,420,393,229,476,274,446,655,143,30,862,719,883,117,315,929,786,843,25,800,224,808,996,353,706,210,318,902,71,402,667,435,507,419,978,889,95,122,125,612,706,141,724,927,340,651,994,612,604,877,752,88,661,899,731,39,891,294,467,663,930,685,557,788,576,305,615,44,389,703,531,468,383,337,429,333,115,463,383,769,583,268,582,175,787,729,936,43,619,498,91,86,709,844,456,43,11,383,537,428,600,923,854,238,844,198,741,104,97,849,663,49,89,648,947,288,235,677,239,820,577,581,19,260,10,835,630,57,223,44,941,992,115,946,539,509,948,569,64,625,511,696,217,841,871,320,368,767,585,445,588,887,553,425,501,814,672,853,279,905,748,402,295,128,686,33,854,460,658,928,63,913,789,814,359,32,546,114,872,978,114,429,305,541,476,303,104,921,151,494,665,0,863,645,876,269,967,978,15,621,73,180,401,562,449,350,457,666,952,819,878,418,658,48,433,786,325,726,100,386,330,367,660,631,702,792,685,792,976,920,171,125,457,361,833,517,546,571,289,521,54,339,378,886,725,716,667,332,268,141,62,110,417,831,732,746,253,135,704,802,841,949,283,944,252,833,720,906,555,134,45,977,2,574,330,534,479,696,595,103,31,821,66,921,781,669,51,317,879,440,89,863,390,296,188,751,876,469,952,863,125,13,740,547,878,251,477,90,44,423,859,654,497,776,599,244,593,879,377,974,306,734,795,175,224,306,225,656,307,588,163,63,410,300,809,97,373,458,804,794,302,489,303,131,392,766,270,248,554,955,406,29,784,321,854,176,972,503,817,734,656,835,277,512,16,914,377,429,285,263,525,137,148,165,272,974,722,673,843,777,636,811,731,823,398,841,181,205,810,291,583,284,998,668,583,187,472,74,394,403,256,219,42,234,479,704,507,547,875,40,862,380,482,588,335,244,561,333,381,728,877,922,279,403,347,471,236,492,441,276,822,685,162,392,749,714,670,537,608,80,993,566,51,163,187,768,307,777,705,166,672,293,333,395,589,847,911,542,125,41,77,713,486,243,201,50,780,852,571,933,444,406,553,38,185,343,776,570,401,266,438,973,130,470,31,498,544,890,443,301,711,921,109,862,505,777,770,53,480,809,891,489,495,524,32,15,644,321,888,990,462,947,431,177,15,221,506,566,522,930,324,485,303,948,65,280,521,972,786,984,740,986,181,778,997,676,564,643,902,415,324,841,774,706,929,817,81,186,904,319,745,616,719,471,345,831,521,124,520,811,636,225,714,319,475,47,857,809,495,108,518,722,575,602,362,378,608,974,355,59,204,638,586,272,185,135,913,919,337,345,303,169,690,585,614,398,344,509,339,201,382,312,192,526,214,67,243,993,750,536,161,55,454,148,139,786,410,25,947,421,344,498,728,648,949,92,42,749,710,849", "697,467,510,979,559,143,189,351,528,909,526,503,396,560,482,617,250,444,8,612,707,298,568,170,981,243,950,466,238,302,438,271,611,618,926,246,933,892,495,301,931,839,747,919,491,378,582,23,825,544,864,768,939,288,354,559,557,449,397,454,182,704,773,377,865,166,968,398,577,466,646,613,457,32,102,515,432,948,432,271,719,917,124,919,547,854,305,792,96,192,198,470,335,845,690,433,311,271,896,955,120,614,7,551,214,552,814,934,692,190,446,641,944,857,661,21,166,659,971,391,758,822,21,533,36,289,636,11,942,468,853,460,619,272,560,317,50,584,963,117,979,323,35,923,42,616,741,181,786,237,362,288,71,326,610,673,540,620,66,310,779,283,862,303,372,275,275,390,109,998,939,973,800,696,24,754,309,380,351,593,590,596,679,691,499,247,737,785,950,134,671,491,634,644,645,911,41,942,255,141,841,280,595,207,975,843,14,319,329,855,363,620,622,906,997,902,790,617,688,728,588,556,594,420,370,272,228,694,569,594,55,923,950,566,902,362,723,925,742,19,272,559,336,936,935,856,844,410,187,945,927,170,221,876,626,358,54,11,115,908,835,350,271,335,300,770,897,449,188,850,969,234,816,733,297,753,161,5,952,324,120,467,538,70,778,175,625,371,606,271,898,603,749,821,665,737,324,18,482,780,113,583,706,538,260,347,605,469,353,689,417,694,523,413,779,494,907,999,409,753,310,586,731,449,681,498,626,162,236,833,650,275,224,625,474,115,911,127,634,839,129,152,253,925,447,713,311,666,423,100,977,598,180,293,400,330,499,462,748,382,276,885,242,730,159,958,568,902,884,569,215,35,457,965,17,944,28,931,467,174,485,20,436,601,148,688,439,150,710,607,851,566,667,473,246,365,499,281,683,259,67,113,51,272,504,368,258,680,59,606,774,723,749,395,110,483,231,236,22,292,451,841,82,956,317,585,7,239,99,137,502,673,764,441,338,13,837,372,582,164,122,816,959,604,524,337,619,126,620,563,474,383,193,444,655,476,823,525,930,493,412,18,879,211,794,486,76,514,340,31,9,731,574,571,350,725,652,711,909,347,858,882,570,340,884,439,22,952,628,921,414,271,367,239,17,729,862,93,583,545,979,834,685,70,115,836,935,879,64,709,890,969,665,224,441,44,787,673,164,758,535,639,979,352,568,245,544,872,9,112,636,145,726,111,1,429,922,196,220,43,973,177,691,851,617,76,256,674,714,896,982,756,192,670,536,765,191,992,77,9,350,863,0,117,652,697,443,55,905,214,198,425,937,103,804,28,828,537,140,891,658,513,628,270,522,535,667,936,124,973,257,524,434,430,201,716,503,351,54,176,70,584,636,530,152,359,23,990,785,31,478,361,504,615,747,17,223,850,953,889,981,41,830,728,741,375,484,453,685,47,465,196,80,110,380,127,57,954,763,727,371,796,885,223,62,628,336,943,879,463,234,132,267,220,851,45,981,313,420,445,316,573,188,54,981,480,89,877,599,558,717,546,585,453,415,352,476,503,999,811,701,3,198,715,379,55,553,413,316,184,92,561,590,720,242,985,296,737,636,46,77,681,14,120,696,481,631,259,21,372,887,855,512,236,520,749,488,121,715,415,262,428,105,370,24,997,200,489,298,935,3,707,880,992,988,534,636,831,683,931,312,797,529,918,373,550,369,97,464,213,496,140,783,218,581,607,594,157,439,691,79,446,250,77,58,486,841,634,683,530,837,469,77,18,5,402,565,359,248,402,978,894,95,467,447,111,88,835,19,74,189,896,822,226,544,580,500,148,63,863,131,522,468,27,525,964,111,581,849,39,719,370,604,299,607,811,557,221,308,993,675,505,476,88,263,233,225,341,247,25,252,880,407,428,981,711,714,439,298,772,83,336,320,417,969,373,957,167,440,331,733,595,185,272,598,194,904,605,973,724,418,138,242,635,975,146,993,779,102,321,647,929,193,937,862,908,450,929,973,452,436,191,610,280,462,185,119,138,911,667,378,416,150,330,593,416,124,777,975,465,954,323,879,411,480,931,808,328,948,43,274,54,830,919,397,713,499,321,675,729,992,513,218,218,280,884,117,958,472,775,180,987,862,676,31,6,347,432,434,155,803,658,248,954,804,929,564,830,301,237,104,46,375,766,915,57,591,498,985,112,246,280,16,887,44,364,702,479,458,513,166,139,614,968,449,862,24,151,24,255,685,811,779,827,988,766,156,235,912,161,161,379,527,76,19,353,151,611,928,446", "348,894,610,134,417,956,555,926,878,411,666,797,147,815,603,348,925,530,111,297,329,161,685,784,265,450,881,910,690,35,872,55,854,78,499,578,128,731,811,194,241,993,838,355,609,477,325,653,73,319,271,214,663,658,876,140,153,734,536,228,167,890,767,86,797,280,767,681,509,459,345,207,28,88,262,75,76,732,509,807,666,315,281,465,384,880,857,515,385,546,468,224,104,576,987,14,173,253,159,583,648,175,136,876,353,629,509,428,311,965,617,874,618,138,880,194,127,773,565,525,389,983,35,705,708,286,781,846,864,150,197,907,593,215,657,21,536,526,655,352,105,761,645,697,946,926,500,680,993,2,810,437,946,198,15,918,667,721,238,389,659,756,1000,310,859,815,877,123,417,577,117,108,53,388,167,101,208,242,752,816,967,583,595,577,318,220,32,980,469,795,857,327,65,4,966,84,164,472,58,748,864,246,421,390,24,582,141,491,794,65,366,374,650,352,147,896,268,611,719,827,735,184,138,912,971,857,676,151,125,882,452,998,61,826,762,703,225,292,10,892,585,960,260,29,561,517,194,369,256,590,356,368,887,423,832,705,933,836,697,890,338,831,93,968,778,605,574,155,722,645,901,585,384,857,520,667,382,807,101,922,313,714,381,714,134,771,209,506,316,538,113,290,355,950,64,676,880,98,106,679,877,876,647,314,651,591,23,632,856,906,276,452,988,80,166,574,333,927,704,457,641,499,234,386,919,517,113,663,945,538,521,876,366,232,955,805,903,962,617,702,859,983,190,545,591,968,323,818,495,804,806,803,917,409,953,727,804,466,874,383,170,836,186,195,746,968,384,434,952,694,908,433,725,17,564,687,274,274,872,702,650,199,74,505,826,923,303,104,14,105,728,478,392,663,884,53,543,293,517,668,391,179,325,296,786,175,746,387,644,179,487,670,427,255,896,863,211,799,431,414,376,919,106,765,147,122,360,674,722,71,109,356,232,664,161,589,663,170,69,568,998,942,808,232,300,128,872,957,968,233,823,218,312,119,232,369,274,692,397,847,629,92,102,744,103,254,296,967,243,425,537,684,692,5,481,264,300,26,468,438,455,205,440,439,940,863,160,611,265,639,271,646,675,486,795,71,515,881,328,346,46,752,174,414,15,623,3,575,180,450,507,184,46,819,304,875,495,897,295,867,610,254,951,559,673,351,664,711,722,871,665,255,598,560,765,790,589,981,843,464,772,215,565,448,817,819,685,925,584,887,808,962,60,509,32,405,627,387,385,623,405,645,117,0,896,203,883,544,286,954,764,382,231,34,576,827,839,835,151,442,768,934,818,905,89,831,646,66,25,191,67,835,447,705,554,798,182,568,312,938,446,778,425,481,92,174,630,856,371,564,799,116,477,33,260,208,60,25,281,826,108,319,916,211,536,423,728,158,563,143,419,18,943,115,633,46,840,136,653,362,937,561,243,827,793,798,682,838,181,355,360,818,974,926,739,302,102,834,251,393,285,144,265,945,836,321,754,358,318,999,971,486,960,940,463,583,750,204,346,627,989,494,907,898,262,508,411,327,568,653,892,379,970,200,271,793,887,983,380,606,417,10,590,206,400,781,550,471,679,638,41,586,966,914,887,188,116,690,724,195,307,785,716,804,33,57,143,409,757,5,776,863,748,204,262,545,628,997,882,127,758,522,794,126,525,404,719,152,240,536,846,541,237,756,587,560,582,414,204,785,66,950,413,95,419,636,710,698,203,133,51,103,143,59,548,531,432,993,573,567,555,693,595,253,496,197,490,650,603,650,408,762,315,405,438,183,362,469,420,31,660,513,352,997,728,445,995,219,873,254,715,886,857,359,263,20,617,64,103,60,456,470,999,265,557,410,930,73,664,974,994,369,761,50,358,589,153,485,3,506,770,359,986,503,273,782,670,305,286,862,245,630,387,26,998,328,439,153,811,845,378,162,593,448,698,244,866,775,440,469,610,701,115,379,323,509,155,287,934,490,7,355,668,909,187,742,369,557,849,434,356,523,998,207,590,531,20,159,973,76,983,824,957,289,941,130,109,374,71,589,209,906,757,852,833,896,36,740,960,150,606,885,657,139,566,931,637,201,645,384,449,702,525,107,147,577,236,95,325,529,820,847,883,906,432,229,366,626,822,622,685,259,950,814,30,537,500,412,207,834,349,630,267,212,677,731,808,507,934,202,141,222,783,32,288,965,433,703,669,633,926,692,135,867,215,43,721,559,414,735,317,117,829,208,729,158,5,943,277,972", "296,513,957,926,419,426,88,400,751,221,551,247,807,936,189,339,411,614,454,273,597,306,473,238,223,766,789,144,184,706,960,126,791,936,831,783,670,658,908,746,639,81,638,702,869,71,570,183,243,228,768,42,173,984,809,558,768,342,364,641,76,710,804,671,323,978,854,889,94,328,382,132,851,825,586,596,274,439,560,792,858,450,57,190,316,551,784,112,423,998,546,934,56,560,499,343,705,47,124,8,547,126,606,846,8,157,226,468,194,80,858,79,264,165,323,499,389,628,56,285,415,95,784,772,35,182,469,377,868,477,872,993,727,46,616,221,24,553,570,150,118,693,220,770,585,413,838,213,775,427,471,64,546,968,96,61,526,451,935,613,512,853,330,604,42,103,722,917,995,763,592,984,45,845,756,544,730,704,102,353,647,623,929,594,629,196,202,908,986,594,650,628,187,822,454,513,234,493,130,598,886,832,978,696,398,426,779,575,294,713,859,912,989,595,333,183,30,207,368,459,111,398,259,798,383,303,294,440,286,645,53,60,971,512,453,744,261,211,711,910,444,152,243,708,987,8,787,612,779,497,577,898,373,882,89,97,584,426,988,567,224,219,845,461,244,844,532,650,724,287,801,759,824,814,697,566,502,738,107,842,642,757,614,487,394,255,485,368,182,608,248,169,164,836,218,430,154,779,738,201,439,365,967,225,477,824,490,692,824,428,864,388,543,680,921,658,523,821,604,678,508,528,173,567,511,696,439,360,880,672,81,266,620,775,531,226,933,944,497,975,448,364,723,298,86,62,911,204,450,292,930,408,706,774,105,891,361,936,828,452,847,556,125,300,700,969,612,601,519,474,762,49,703,788,228,721,570,359,834,179,727,237,640,126,682,268,101,972,769,206,772,864,924,858,942,249,788,19,351,104,515,850,457,314,938,956,324,891,154,10,190,464,948,35,590,458,883,576,786,443,870,419,396,924,645,315,209,717,76,422,685,903,999,465,713,565,369,834,735,13,603,692,837,669,650,308,218,610,325,424,731,123,928,313,799,945,726,412,667,215,930,743,726,145,16,821,432,17,978,525,601,734,237,298,814,262,663,290,464,553,275,59,750,886,390,425,374,406,211,716,653,460,279,242,997,33,211,719,128,958,161,695,589,302,580,459,766,403,136,368,312,340,617,741,344,624,166,104,508,792,884,426,552,565,866,227,387,301,308,380,164,799,901,592,471,859,606,297,954,682,611,177,455,469,746,737,965,573,692,556,470,850,860,84,251,676,444,436,321,573,16,876,652,896,0,113,972,954,50,558,584,635,879,203,157,861,995,771,670,510,171,17,387,921,551,104,639,861,562,111,632,123,716,457,65,952,245,833,869,896,622,349,883,217,606,689,500,121,938,563,744,870,650,831,998,975,23,51,527,314,235,50,724,692,968,855,602,323,548,962,128,68,829,767,700,157,613,710,658,695,219,546,226,930,71,967,370,981,511,895,898,719,833,518,751,687,468,187,844,19,806,106,999,594,844,957,886,113,700,308,762,775,788,890,652,227,155,111,702,651,302,940,149,376,628,412,895,619,577,679,464,155,695,39,292,188,709,875,867,952,494,299,107,125,905,897,423,160,955,126,890,885,301,430,41,614,961,735,780,297,935,211,748,863,454,661,489,329,395,727,832,347,721,861,830,382,404,130,51,124,74,660,854,886,980,173,84,862,60,30,736,649,565,928,377,832,125,974,103,459,971,575,963,947,608,989,939,117,930,926,675,865,52,964,942,812,627,268,538,277,980,127,642,391,26,836,937,424,888,724,74,575,24,411,197,790,268,69,608,296,366,357,999,231,205,995,746,798,375,121,304,78,48,707,139,108,338,329,877,468,902,994,974,671,947,274,831,809,70,986,848,805,231,447,58,279,373,655,235,190,99,659,896,431,203,884,220,300,710,705,368,318,703,670,415,311,627,793,234,278,54,457,578,615,29,289,71,109,551,221,329,716,204,88,430,444,3,91,510,321,518,910,268,804,432,749,811,97,252,800,894,150,516,322,582,741,491,592,362,622,604,395,797,72,161,481,486,138,795,481,379,28,338,949,620,34,181,988,291,785,439,979,237,287,10,662,289,477,914,251,854,253,275,832,418,326,794,373,702,747,824,591,520,592,989,415,857,477,310,749,241,922,143,782,67,180,843,64,154,533,891,658,166,466,736,295,81,724,784,974,932,465,868,58,973,312,528,236,498,354,410,438,160,642,575,322,490,234,271,214,232,912,628,917,695,336,413,109,108,551", "472,352,696,103,971,241,41,169,825,23,158,352,230,460,487,469,920,208,476,733,724,831,48,248,598,23,820,655,611,520,168,426,102,480,942,511,546,875,116,14,300,670,790,499,21,656,976,749,429,527,666,415,425,944,597,54,254,887,227,738,604,534,194,970,196,393,365,83,281,716,115,980,99,366,247,200,908,635,326,704,866,790,281,173,202,899,149,624,14,678,114,312,905,311,625,615,867,145,595,420,342,675,137,661,689,963,235,274,528,816,289,610,821,415,364,90,79,71,372,154,503,727,189,927,323,522,858,235,834,19,395,798,875,206,902,257,357,20,568,481,429,631,400,831,333,404,79,821,768,604,68,718,428,363,882,477,720,34,737,179,449,719,650,745,810,478,349,443,424,563,32,287,724,418,966,583,304,42,765,380,206,356,173,438,746,688,122,674,784,208,996,568,893,865,670,768,50,971,147,728,920,867,347,196,221,293,497,992,350,633,498,339,610,893,948,334,849,41,630,403,556,869,624,129,579,484,774,263,605,948,510,221,108,910,877,630,295,45,729,957,602,914,461,870,369,848,112,763,422,176,576,98,688,860,25,596,14,448,545,265,496,628,53,364,60,617,828,980,26,398,520,964,36,654,47,603,771,186,591,61,752,59,446,202,220,233,72,321,801,31,993,52,356,32,664,514,388,589,138,427,266,368,348,157,113,904,666,341,972,827,737,376,920,365,231,476,370,384,892,311,854,621,716,591,451,916,162,600,84,428,584,26,554,509,917,532,397,812,942,130,432,12,816,832,868,979,61,515,705,542,473,200,571,571,703,283,593,774,645,616,915,212,550,884,994,794,167,805,365,803,791,701,140,204,530,115,978,906,440,138,175,620,113,653,748,802,117,958,538,470,310,947,266,47,464,273,230,746,630,194,585,573,641,561,970,58,63,772,355,815,638,87,441,613,382,859,528,963,384,824,70,547,988,771,251,509,724,730,176,663,102,961,261,164,716,719,832,924,348,741,729,714,296,756,829,854,61,516,723,402,370,568,477,240,681,231,889,802,502,59,310,583,179,356,215,91,566,960,156,516,496,620,239,177,63,978,268,732,397,363,680,479,449,382,407,778,176,980,781,832,635,120,848,106,595,23,663,930,456,446,155,548,565,315,354,721,619,520,111,487,96,112,62,360,807,181,15,425,198,998,722,499,222,974,634,233,277,331,193,880,721,612,584,968,767,144,557,745,658,705,743,690,209,868,816,4,523,115,378,701,479,537,185,65,740,827,43,709,651,325,221,269,697,203,113,0,264,58,864,442,855,756,308,941,567,604,633,109,973,583,259,591,12,496,365,608,518,614,672,381,763,782,372,914,697,319,228,271,114,524,124,374,92,534,242,80,832,867,893,356,477,115,442,62,910,944,931,873,354,735,364,942,421,995,281,3,77,26,729,219,621,841,73,661,428,810,314,334,253,131,4,830,285,93,169,108,924,789,921,318,17,942,138,925,526,651,860,664,517,629,615,913,695,283,699,579,372,250,74,802,418,783,592,95,934,709,712,730,822,64,904,521,442,102,631,274,692,640,331,714,962,704,241,50,1000,362,481,831,646,813,689,73,722,874,936,478,342,694,454,593,208,399,239,355,96,677,293,523,946,943,600,145,195,418,70,205,888,142,332,867,868,250,914,825,664,550,463,161,610,804,669,619,287,297,185,313,10,684,441,791,874,481,859,372,874,494,450,622,602,930,328,761,161,870,546,820,435,887,756,489,337,481,351,269,919,109,757,178,991,370,335,144,6,996,557,392,339,404,382,57,452,529,23,793,301,260,72,852,463,466,163,627,15,264,412,928,606,31,235,243,630,425,872,68,588,561,518,898,53,966,530,640,368,194,538,628,804,402,204,549,970,273,960,864,892,851,676,876,701,281,615,564,811,104,904,425,873,10,451,59,741,766,954,64,496,630,195,198,651,435,592,383,277,508,168,733,490,747,734,106,702,786,407,675,763,166,554,21,14,713,218,392,590,858,440,513,134,311,344,556,193,180,921,82,795,316,352,72,238,949,400,714,180,745,429,338,317,890,303,4,826,112,69,463,570,682,203,648,165,649,286,397,255,792,424,841,320,531,81,7,98,492,92,359,894,829,222,772,398,439,92,673,601,47,179,509,825,370,168,604,366,664,315,685,756,171,260,993,501,93,717,211,578,389,119,362,344,575,612,991,658,900,880,623,928,800,981,908,201,44,848,292,722,985,491,276,950,859,359,369,635,8,428,756,427,623,412,97,418,486", "951,630,505,578,269,20,663,612,756,829,72,651,875,313,510,458,674,823,201,132,591,386,891,108,249,793,165,415,386,574,349,82,504,436,994,699,646,259,852,236,164,918,164,140,483,610,19,672,827,964,986,293,887,179,117,463,228,348,1,592,434,985,297,728,995,153,125,50,17,557,575,222,393,804,369,497,567,278,525,857,440,759,812,667,594,542,221,389,178,418,673,884,614,978,841,909,613,839,914,808,413,430,37,654,515,181,522,447,834,13,828,274,507,465,743,7,504,529,670,107,403,304,446,873,549,209,582,501,272,249,653,145,990,860,887,731,510,830,267,334,322,580,276,200,126,405,334,341,169,743,720,283,966,922,943,582,190,155,619,306,650,459,119,404,404,365,656,462,307,902,88,778,865,878,296,248,706,665,165,226,932,232,840,849,595,524,50,735,762,796,66,600,599,516,408,439,737,157,631,115,627,475,316,237,386,316,229,696,206,423,595,554,234,511,963,893,789,505,786,712,749,207,786,316,271,316,454,208,563,484,270,139,985,302,308,685,789,78,512,490,233,717,968,160,708,724,342,622,13,177,544,125,101,398,286,440,411,354,856,207,251,815,158,538,319,310,893,654,893,470,308,586,68,896,312,51,919,97,790,567,557,297,39,652,686,900,797,140,508,120,500,484,854,928,159,136,883,226,97,519,625,746,93,214,157,913,726,67,6,753,913,613,282,757,483,665,782,765,620,113,175,973,922,843,210,718,187,441,349,458,894,814,344,531,453,396,419,766,526,645,600,787,711,709,658,795,101,513,887,274,256,272,864,134,720,315,24,883,927,499,923,941,176,371,956,752,221,992,573,393,508,842,10,499,607,952,422,481,116,167,427,568,855,784,47,245,449,695,816,380,602,414,863,255,827,190,943,432,233,402,37,618,359,558,644,357,705,125,96,686,299,673,531,679,170,69,261,961,451,127,209,780,617,91,242,340,599,132,210,835,486,251,232,718,862,984,474,997,701,299,396,209,56,580,268,594,592,798,398,734,352,337,135,242,979,180,565,555,717,205,876,669,887,256,263,848,704,485,952,650,147,562,553,872,34,340,33,605,148,594,419,760,736,345,703,80,15,547,776,16,247,382,299,961,716,257,372,324,82,617,594,630,747,877,455,449,882,430,400,117,727,171,943,710,682,130,627,496,567,242,752,103,442,986,3,704,470,901,110,522,789,830,633,72,770,918,452,297,614,95,49,484,816,609,210,442,850,85,983,261,528,656,68,189,598,707,364,238,94,596,70,967,443,883,972,264,0,93,76,850,220,96,750,521,393,618,268,500,39,335,943,656,71,703,362,806,858,212,848,573,602,248,105,987,630,528,124,693,693,24,566,148,425,314,775,606,233,425,926,516,62,301,883,945,456,73,536,707,240,470,254,160,926,703,825,122,581,792,425,798,102,227,387,157,941,332,154,526,978,836,355,600,151,893,744,621,628,460,670,562,248,34,965,550,529,69,724,164,252,244,288,345,866,655,957,741,85,945,815,334,603,887,839,375,489,628,580,280,949,437,733,353,411,783,467,506,73,487,886,204,802,462,382,833,912,697,144,838,444,47,212,245,760,760,760,38,444,401,676,936,285,444,610,387,830,930,301,116,753,120,40,463,308,57,341,726,266,283,55,804,639,580,898,693,544,526,579,99,849,61,285,923,634,340,6,182,612,716,184,114,175,795,29,396,671,621,380,795,134,214,128,498,877,686,122,680,691,402,251,536,640,183,667,176,754,511,921,793,523,765,11,580,372,205,405,112,511,126,262,377,430,440,289,208,662,581,746,950,59,438,807,544,21,120,240,55,185,178,815,515,977,856,934,796,773,113,818,540,939,103,364,389,912,210,18,976,600,885,862,644,633,691,208,546,436,653,931,766,362,125,841,318,529,37,662,696,514,606,327,40,847,454,79,320,777,307,421,256,907,422,569,335,310,223,770,322,309,852,687,168,453,439,298,908,589,407,721,605,34,356,983,772,342,211,206,619,738,950,191,236,709,288,438,48,714,199,751,381,75,389,670,99,94,368,667,235,933,318,802,519,376,249,850,863,112,914,768,325,783,266,684,694,907,679,688,107,228,395,923,365,109,850,780,821,488,450,146,967,996,806,185,89,413,274,673,9,615,244,859,752,87,500,575,497,141,793,762,507,508,326,903,13,601,291,633,821,824,316,543,541,325,936,677,121,678,68,202,800,132,507,973,824,765,470,61,77,772,415,595,29,947,825,374,339,531,456,108,76,287,13", "117,460,533,97,858,569,150,600,957,125,20,104,996,990,380,602,411,908,110,468,157,128,652,228,949,838,14,601,817,896,230,616,718,932,702,267,742,629,167,380,580,152,560,405,175,427,950,185,481,731,947,641,64,611,393,574,793,968,777,964,225,602,81,726,390,556,138,201,525,443,271,453,69,127,961,704,186,345,99,375,798,273,915,422,788,715,834,55,39,596,798,509,822,688,838,125,991,311,294,712,164,970,163,902,436,554,215,828,497,802,889,787,710,75,553,626,52,233,985,557,377,707,316,963,640,235,796,689,211,730,838,601,764,96,753,641,8,366,342,843,429,465,810,57,758,298,305,314,588,814,186,548,292,84,848,729,540,809,94,139,38,236,404,587,756,402,610,89,913,183,320,615,611,608,622,939,100,264,246,186,238,816,984,121,271,365,326,139,685,708,76,434,631,655,608,337,981,483,485,136,699,745,654,800,202,663,960,437,172,259,678,357,635,74,541,921,313,881,782,767,469,873,22,209,278,205,675,490,101,313,966,226,258,18,909,866,841,234,791,575,223,189,954,37,632,565,191,813,674,59,97,284,743,416,547,784,150,820,866,680,64,414,10,686,518,275,308,676,568,641,545,940,581,526,419,774,438,530,24,68,873,160,907,408,926,998,450,208,671,875,362,213,832,410,250,82,177,599,334,461,150,329,591,420,569,370,858,866,814,848,989,111,401,424,811,368,96,894,802,333,332,508,612,278,794,472,193,760,239,655,98,809,740,766,448,975,949,445,579,778,833,106,932,395,945,725,752,54,781,887,121,51,902,525,333,216,876,894,4,86,694,144,639,158,898,180,804,167,268,744,533,484,857,673,20,498,618,865,930,992,11,503,259,169,418,19,16,529,166,26,73,667,455,15,782,279,12,22,973,636,102,438,469,871,639,728,899,490,365,667,692,256,667,445,121,728,341,563,402,215,43,839,289,57,324,907,585,597,72,981,373,941,588,796,777,437,650,505,75,677,658,791,269,368,71,285,148,306,818,547,19,822,745,949,934,352,45,938,546,35,14,616,962,295,304,386,297,171,556,701,449,88,632,51,30,168,183,744,58,126,68,512,472,707,972,516,136,52,178,88,941,484,218,679,419,952,270,246,92,668,162,560,322,578,364,871,444,613,204,175,983,564,259,492,280,265,637,516,824,674,690,970,889,247,530,222,594,419,480,143,361,459,754,200,188,782,922,233,276,437,337,651,882,973,3,292,93,772,247,880,64,458,680,989,458,43,501,704,681,825,153,978,55,544,954,58,93,0,55,698,856,36,443,109,404,864,991,13,327,212,854,535,823,21,115,504,842,415,396,827,202,413,342,532,777,339,167,166,975,272,175,964,416,599,824,206,886,244,681,899,408,401,427,984,555,796,525,648,488,635,365,14,747,427,61,106,160,180,168,736,388,30,370,303,759,830,888,551,833,655,82,744,87,588,225,74,482,341,302,447,460,799,756,277,236,59,504,129,556,392,798,11,310,278,352,634,865,282,475,476,558,26,240,699,150,769,259,205,262,755,281,622,860,823,563,24,846,902,28,107,216,987,947,186,164,762,501,448,456,772,44,709,633,854,951,776,283,566,654,257,775,49,246,671,489,543,361,4,124,725,806,489,814,668,7,457,954,879,428,730,539,909,117,315,945,329,768,690,844,658,84,66,688,356,738,558,442,865,908,527,33,594,534,269,519,477,35,315,203,15,66,963,574,583,93,319,495,102,832,845,562,577,867,866,721,268,139,776,491,61,136,444,372,820,596,622,735,50,138,445,683,567,629,863,45,462,308,155,106,48,180,740,357,243,449,737,969,156,594,28,491,110,267,370,168,943,965,471,444,529,416,453,380,462,75,17,83,469,382,376,176,445,273,851,274,41,610,992,707,85,44,126,344,58,762,549,847,333,280,130,571,464,244,717,907,667,162,866,353,384,669,102,39,210,494,490,621,795,95,501,456,231,377,319,742,8,831,922,544,976,934,157,187,247,272,418,874,568,642,836,448,425,295,453,995,549,152,192,807,185,691,235,294,267,888,499,533,936,273,927,945,682,795,704,966,537,78,705,570,886,522,982,117,232,508,509,683,732,674,838,146,236,706,622,919,355,78,146,218,725,349,876,788,877,151,740,935,13,722,940,841,42,216,671,173,319,278,382,68,576,509,273,389,274,87,93,785,264,615,125,80,43,877,235,259,54,962,178,547,224,612,181,818,633,52,927,163,357,552,145,795,337,4,300,770,816,813,806,142,629", "464,511,884,905,28,828,13,322,821,549,631,462,189,157,658,340,169,547,299,710,445,163,412,498,436,862,198,118,209,259,946,61,392,323,441,596,320,757,859,892,92,955,476,273,944,635,172,586,319,251,272,390,57,565,858,967,756,767,442,861,875,870,760,548,36,769,593,948,911,175,312,209,913,875,125,905,947,380,69,506,226,222,376,449,135,146,737,782,811,337,858,456,376,965,62,166,525,598,624,404,678,265,612,903,991,966,304,912,137,87,337,35,746,152,969,207,66,562,744,391,681,146,970,458,730,778,869,16,152,734,806,353,748,570,775,925,933,36,164,557,714,870,39,505,645,661,301,591,738,564,154,435,649,888,240,553,289,635,707,453,978,758,174,775,272,573,703,284,412,558,498,168,697,672,517,643,123,301,118,525,289,539,900,375,602,833,935,268,17,670,110,504,8,459,395,183,391,30,960,257,294,480,381,685,362,920,184,8,646,510,101,973,17,664,4,841,751,123,558,460,433,606,706,399,549,193,595,609,291,449,152,836,760,948,383,894,429,549,473,580,122,293,305,232,883,679,927,151,194,966,850,690,933,228,286,833,873,949,72,95,418,327,308,196,811,334,394,608,775,240,493,457,164,619,673,53,404,917,233,46,711,35,646,455,683,996,842,743,249,215,700,576,580,570,661,282,255,234,443,892,230,129,972,620,930,120,119,283,682,325,468,2,652,374,313,740,92,332,708,702,56,270,721,463,445,39,761,125,846,509,336,302,109,938,192,437,3,103,291,946,97,86,793,645,351,854,909,231,923,439,986,910,181,446,682,762,663,822,719,777,702,311,323,122,598,265,457,129,256,994,472,167,876,843,164,181,191,317,135,399,373,235,523,613,679,675,310,346,503,781,806,111,669,551,227,49,4,909,201,181,611,871,359,189,13,927,663,503,925,834,625,972,870,443,199,606,568,834,204,672,41,539,317,957,677,830,221,841,385,826,989,844,246,338,755,293,241,218,616,386,843,194,783,154,623,23,929,571,454,512,1000,648,996,826,380,111,387,346,996,503,113,129,354,368,164,219,230,638,267,219,245,515,94,549,77,851,41,230,275,401,681,747,403,792,979,427,682,280,254,356,56,440,930,854,832,182,305,912,271,744,546,426,558,734,374,546,424,682,105,729,989,976,669,584,746,61,488,392,298,115,115,462,699,242,415,227,297,888,410,310,746,266,375,340,355,610,436,183,87,163,491,563,746,465,800,14,632,335,284,362,28,986,687,661,962,167,642,730,69,484,35,15,905,286,50,864,76,55,0,482,19,958,571,324,25,29,249,561,240,725,349,257,624,914,93,706,626,582,963,552,264,490,24,450,741,906,645,671,997,762,553,531,268,191,166,572,324,460,806,424,690,866,46,252,995,603,790,395,84,331,281,572,677,194,459,715,410,496,14,204,66,972,781,412,312,194,505,250,106,701,549,83,437,361,644,300,729,241,976,98,699,205,925,819,909,997,347,67,666,903,13,42,50,961,171,641,632,977,22,611,59,163,52,965,104,974,69,210,44,560,98,564,175,11,874,788,275,500,689,764,112,525,780,498,691,565,341,678,995,390,372,236,48,913,241,985,787,367,926,617,257,642,323,458,196,27,468,224,506,197,839,576,726,135,491,901,34,774,775,241,167,700,447,58,257,793,407,225,968,353,117,316,185,738,701,909,592,356,791,111,842,306,347,327,476,325,603,705,477,378,679,857,938,498,974,582,122,225,774,801,691,227,197,170,600,613,199,485,843,34,302,478,971,33,37,253,942,392,633,824,406,45,869,923,546,548,548,268,861,292,565,955,580,994,708,920,940,59,6,191,445,300,388,254,454,395,651,171,309,59,665,960,8,733,600,706,915,73,342,167,213,577,114,735,545,123,392,662,275,29,298,191,941,876,471,958,44,889,184,811,158,52,356,609,189,706,794,96,56,626,837,600,529,764,333,274,61,943,206,534,6,965,96,241,746,674,770,917,688,449,390,35,102,260,423,596,252,660,276,659,285,625,126,160,221,662,721,950,213,476,227,828,343,206,595,943,284,607,917,445,407,514,651,886,729,52,443,350,989,664,448,386,395,634,839,800,660,819,623,440,992,73,235,789,55,192,134,216,470,561,889,342,209,94,866,171,629,427,910,607,955,431,466,257,242,132,247,350,668,909,586,734,131,169,235,590,607,77,142,378,641,501,977,585,280,410,797,525,33,102,887,302,517,245,552,780,826,633,44,858,132,396,111,549,455,527,706,91,586,649", "843,179,754,866,151,373,367,451,500,323,751,920,557,398,387,538,633,116,913,80,470,471,144,337,759,322,405,119,114,367,945,263,651,306,811,914,410,78,439,395,412,464,69,426,591,946,454,411,43,893,697,830,76,208,628,869,341,675,527,445,790,305,490,558,308,254,635,884,686,237,501,346,999,280,260,135,970,781,57,400,299,830,612,248,453,17,799,602,409,944,34,32,460,337,639,527,700,106,924,793,877,895,524,396,386,496,793,253,518,49,326,701,905,129,153,675,674,124,349,937,849,167,135,118,251,281,818,522,945,744,190,327,431,477,334,479,842,311,239,462,175,299,560,958,719,253,190,738,930,84,75,190,973,202,743,493,599,326,950,558,969,407,707,918,68,601,71,907,142,966,461,391,660,29,135,607,671,989,488,495,435,926,496,539,14,244,77,740,373,221,359,286,584,54,24,919,365,542,493,517,768,709,807,134,752,126,595,100,867,289,278,632,314,606,40,548,730,350,569,780,879,756,377,261,930,296,709,971,707,566,432,964,536,131,967,234,301,79,987,506,920,401,244,718,75,645,365,633,383,404,695,822,944,861,910,406,535,288,328,701,178,588,687,321,643,781,787,634,804,202,13,465,749,422,216,357,604,753,331,693,358,288,869,352,44,212,407,283,558,792,846,173,36,562,907,866,240,250,115,623,534,618,160,567,922,255,978,666,547,252,944,544,123,153,259,943,259,336,24,527,509,169,304,515,262,596,909,454,746,187,432,293,886,822,547,874,350,352,899,564,663,105,708,402,902,513,241,583,927,722,456,956,326,549,627,522,391,465,870,261,567,161,481,242,766,575,868,718,642,807,289,897,620,965,759,351,715,311,563,756,527,707,140,229,619,533,841,681,145,309,444,890,415,72,952,660,663,199,810,258,616,723,538,98,438,295,81,320,799,907,384,997,94,958,13,164,874,557,975,517,577,881,19,468,489,872,278,438,263,287,504,903,442,373,101,808,710,827,985,739,988,768,657,890,487,55,915,90,395,36,652,397,933,67,925,36,476,765,585,446,641,391,170,469,459,729,676,270,124,563,813,276,977,193,594,151,953,173,93,774,608,939,684,856,645,222,10,545,519,212,349,49,412,969,562,274,471,738,755,473,921,35,491,883,493,371,355,327,259,25,912,543,836,228,915,97,465,948,902,729,488,132,761,564,93,645,925,599,763,711,3,602,343,511,383,923,597,163,306,681,111,451,613,692,446,641,391,651,803,110,432,789,593,387,56,164,460,179,827,626,905,621,214,954,558,442,850,698,482,0,989,42,987,341,757,112,143,220,800,624,536,355,325,630,168,635,702,873,577,617,881,224,949,834,152,249,336,847,386,866,278,265,493,585,851,946,256,21,746,182,131,587,901,743,375,472,489,705,989,909,757,338,491,466,538,53,773,961,544,411,397,657,790,736,143,868,336,765,288,383,504,926,820,152,811,804,104,640,757,884,732,944,318,323,253,958,761,807,734,759,59,788,436,448,9,244,284,977,641,748,562,274,484,58,368,814,406,752,711,677,29,285,501,292,46,57,846,167,241,454,512,245,894,802,436,638,352,970,270,913,8,987,64,431,513,468,95,534,158,382,291,334,630,344,504,820,290,360,267,910,372,397,167,436,307,429,963,457,69,977,79,679,816,713,327,130,78,992,507,353,482,146,543,941,188,794,814,47,878,865,876,694,973,118,892,484,411,204,962,780,810,649,992,607,592,398,394,448,560,968,384,815,875,2,261,88,221,828,404,707,988,849,789,251,904,478,109,347,84,626,85,893,157,901,666,223,932,153,966,3,370,549,335,437,665,44,787,626,244,694,185,476,259,547,452,799,385,615,890,567,928,71,834,662,493,30,56,235,430,397,960,247,616,402,591,226,448,153,422,204,547,529,695,800,510,302,199,523,175,720,565,999,507,971,932,167,702,34,591,803,91,34,647,694,148,292,367,831,465,686,922,816,426,351,913,77,688,31,974,923,432,802,601,818,726,873,56,961,685,78,206,821,228,474,814,948,789,134,267,149,633,184,586,400,515,324,848,201,974,372,280,827,224,743,766,299,525,587,215,340,401,207,817,630,68,970,10,587,148,908,289,465,728,997,361,850,512,1000,704,31,902,189,497,951,598,292,878,288,605,294,551,581,738,491,583,981,94,287,988,217,902,726,574,765,748,537,503,557,525,221,989,790,281,273,600,398,210,631,601,261,230,726,647,124,278,80,206,184,403,956,836,53,807,661,701,861,957,515,579,769", "96,419,968,443,504,843,747,321,192,190,43,821,149,678,774,551,900,922,395,408,648,525,371,609,498,454,968,470,104,527,874,498,838,117,71,227,70,873,736,785,187,108,121,337,765,521,831,661,561,671,125,161,201,303,363,640,83,667,334,806,192,846,953,97,24,125,436,477,386,899,827,288,261,495,953,429,38,239,370,522,736,495,684,224,317,373,328,73,329,584,244,713,668,806,511,75,868,267,681,504,644,152,309,948,716,126,709,628,117,928,806,707,678,733,648,164,735,209,628,340,826,48,779,122,497,852,912,249,402,271,322,132,129,898,68,815,793,645,403,127,871,831,923,133,473,452,175,582,83,473,895,989,953,963,68,994,893,919,839,930,963,114,451,506,325,957,988,572,236,741,523,412,754,410,226,767,188,532,417,279,754,922,994,315,963,338,229,30,184,993,274,96,38,414,845,434,788,140,498,215,323,579,262,55,936,936,759,235,698,64,216,813,107,810,177,953,720,139,923,903,102,125,456,276,438,505,722,204,19,394,287,254,263,398,317,478,863,119,91,195,373,447,145,206,659,689,170,710,506,319,153,10,381,596,418,623,200,32,862,868,527,926,345,936,526,5,985,433,43,430,171,378,802,531,467,426,208,506,178,916,627,74,220,452,285,808,28,403,266,962,693,271,256,10,780,350,435,114,234,727,955,871,761,869,681,278,828,70,862,942,30,886,747,528,225,276,343,592,75,750,474,774,396,864,900,933,859,672,647,166,208,236,440,264,858,913,450,750,221,514,901,466,445,413,190,991,992,706,182,137,526,646,486,944,51,642,992,922,690,933,110,759,376,892,74,968,814,763,940,305,966,895,227,107,625,119,685,867,363,143,147,631,911,1000,911,619,678,272,90,315,980,318,763,421,193,731,660,214,715,137,45,526,989,6,881,790,665,924,887,480,261,346,191,362,757,483,504,349,94,995,934,85,645,228,827,497,182,967,56,96,51,128,311,54,50,252,1000,751,985,711,319,99,794,789,683,824,382,577,824,24,891,19,4,874,796,738,376,96,836,180,534,628,80,585,927,803,872,44,728,825,636,861,906,776,413,123,446,121,118,212,313,820,995,778,225,986,686,911,522,190,443,561,928,374,927,241,713,833,113,11,125,903,468,605,276,606,123,9,103,675,362,357,378,579,669,839,18,366,535,489,444,133,993,789,816,67,410,871,167,360,876,164,927,653,871,506,445,302,614,451,820,824,656,726,965,298,882,198,895,76,959,247,454,178,716,469,498,760,642,349,464,73,198,764,584,855,220,856,19,989,0,449,969,248,763,642,153,981,88,784,257,296,426,362,193,49,952,113,935,509,535,950,811,530,432,62,120,948,702,943,471,878,956,576,399,984,231,366,952,269,226,248,653,802,738,977,325,532,990,183,321,444,38,225,508,191,246,608,99,73,296,325,373,996,598,39,111,401,441,289,249,837,466,457,386,430,569,360,792,383,829,406,308,735,846,539,836,466,964,361,297,977,614,432,829,570,377,22,363,73,814,32,728,720,338,264,176,439,61,253,931,469,462,585,685,623,152,47,843,804,96,989,680,427,668,189,545,256,329,737,35,105,724,140,39,385,550,927,10,428,554,457,32,325,294,301,954,282,199,103,963,79,484,7,237,492,560,720,976,737,416,149,325,679,900,7,177,141,274,13,779,721,878,331,99,788,10,845,943,955,986,466,801,751,776,322,164,421,44,426,55,841,462,543,640,827,687,238,386,684,796,155,489,69,356,463,12,29,638,953,359,251,672,950,925,188,888,14,248,610,712,228,922,459,47,68,575,507,307,716,725,80,434,834,681,781,714,162,469,314,606,499,934,842,673,673,713,681,623,367,48,263,556,310,450,863,981,758,515,637,474,936,595,649,543,9,652,829,416,211,109,714,153,357,32,932,574,515,727,973,256,824,710,15,374,616,60,986,202,616,699,560,96,379,297,816,339,652,784,621,556,702,8,617,275,924,262,82,659,674,998,710,47,44,916,598,839,60,428,470,75,155,662,477,536,36,959,806,183,29,601,610,164,250,671,566,649,414,305,948,90,78,473,825,724,860,83,511,448,515,773,691,704,598,764,728,960,388,855,563,656,411,420,246,854,140,70,52,577,926,794,509,921,787,794,889,462,501,686,663,472,860,261,529,677,676,491,490,532,285,316,99,705,494,624,832,156,660,684,123,200,78,171,962,544,751,384,22,741,564,890,306,469,333,408,979,88,954,110,719,781,73,391,661,732,339,113,897,670,60", "359,826,998,885,236,870,765,604,755,433,417,839,112,602,581,351,320,556,645,313,505,559,340,561,687,516,908,559,750,423,999,640,406,771,596,977,555,97,234,622,562,32,756,661,301,363,487,408,835,283,863,517,303,644,413,370,427,468,106,951,457,423,522,798,258,842,503,847,557,95,935,208,677,4,32,117,609,336,956,218,675,455,504,820,509,231,752,74,496,159,486,574,937,385,303,261,602,773,81,209,598,519,756,13,483,77,794,547,133,638,485,765,97,815,4,24,455,142,428,398,864,733,104,939,208,425,803,10,102,266,406,529,929,439,245,94,533,222,669,206,392,412,153,447,201,90,17,565,82,195,477,104,220,608,77,703,441,21,362,657,329,515,156,344,751,505,400,143,447,36,588,683,646,776,567,294,698,678,754,984,964,449,536,395,759,370,698,526,875,867,338,886,541,96,28,630,103,656,796,354,194,57,390,135,679,634,957,907,368,431,990,207,770,942,791,234,132,56,665,164,343,182,388,820,477,205,570,895,83,315,528,766,113,200,917,65,889,887,217,283,874,6,31,710,735,127,621,294,82,814,541,263,310,409,346,498,220,270,959,79,727,950,859,304,634,566,43,181,184,904,758,804,310,722,249,450,25,644,995,145,405,183,452,641,243,458,709,471,972,794,52,128,935,953,285,95,903,863,8,523,392,696,843,209,793,935,973,381,308,576,253,256,981,587,939,745,676,748,204,500,34,515,930,402,664,378,198,958,839,885,965,675,591,598,43,605,865,222,150,744,230,817,287,665,882,436,14,651,985,972,653,105,977,646,350,282,768,86,166,996,551,189,83,687,755,693,343,190,76,270,800,332,44,172,404,123,699,33,341,332,438,71,415,36,687,665,858,936,276,695,518,793,113,625,449,875,726,839,299,312,222,99,720,890,638,639,179,433,682,794,946,159,838,181,729,452,385,550,27,813,261,887,801,660,16,954,546,806,233,636,743,635,716,771,579,526,470,726,636,904,550,592,384,309,142,389,762,266,859,547,748,591,112,596,752,530,26,820,729,443,980,834,12,166,94,692,720,6,866,467,859,450,101,964,299,391,246,734,551,834,644,522,419,917,509,622,781,877,550,159,727,93,559,544,71,967,386,908,33,459,502,424,74,517,546,141,737,550,799,790,838,202,589,613,262,587,156,293,325,21,410,199,501,543,278,152,651,135,213,441,455,991,431,260,519,463,743,221,857,626,828,580,628,220,64,599,760,424,512,558,771,445,93,895,972,350,394,68,455,254,424,180,425,382,635,756,96,36,958,42,449,0,699,220,948,15,75,559,919,334,974,823,813,746,556,709,428,906,829,869,420,184,342,137,621,881,206,214,160,995,433,891,443,963,898,373,111,230,685,234,823,635,583,777,793,964,974,954,707,984,193,346,424,409,479,522,275,205,129,873,706,149,591,184,573,921,119,864,382,249,410,107,758,834,953,800,293,592,969,38,24,922,939,132,419,793,789,804,953,381,961,661,926,191,536,462,522,662,388,348,187,125,873,138,982,453,334,600,944,990,802,851,24,871,598,903,145,365,729,200,637,256,11,4,667,957,808,930,392,969,582,853,671,825,120,879,450,973,474,753,253,128,524,760,290,309,64,848,519,361,77,125,151,568,907,450,442,428,795,497,572,729,628,969,42,315,52,362,373,577,22,38,89,66,362,159,93,769,291,272,349,825,554,958,602,591,197,181,46,348,776,440,876,156,293,776,273,454,236,73,181,323,472,359,994,549,375,864,866,872,649,896,310,525,941,633,741,733,197,868,959,553,853,979,139,946,778,713,199,730,756,51,582,561,370,701,54,439,229,576,843,557,26,910,184,976,216,79,241,865,546,580,697,706,374,729,817,254,114,714,537,899,622,729,346,837,565,562,434,108,910,201,966,690,252,116,985,864,128,860,978,814,917,862,623,505,212,542,640,290,860,706,393,136,894,803,289,984,114,852,679,184,971,341,421,618,112,305,630,927,877,428,740,599,412,452,535,552,253,183,709,89,640,898,619,716,563,697,233,38,355,532,866,957,40,795,686,606,168,508,870,478,705,926,977,606,149,555,446,322,328,916,115,7,282,153,257,991,401,903,461,745,756,511,802,908,370,855,149,373,251,647,771,262,293,337,30,535,204,595,668,981,361,779,783,502,383,831,340,726,832,967,790,584,715,967,40,144,24,79,71,994,768,424,189,231,963,799,700,712,498,991,785,439,162,778,199,311,246,549,250,231,695,495,362,534,568,354,345,159", "945,155,994,11,19,284,810,201,582,957,60,926,359,814,252,450,953,811,329,768,820,730,384,604,749,90,921,500,810,781,22,987,764,400,95,995,689,37,936,200,509,60,53,551,737,873,146,93,672,241,889,319,488,461,654,273,172,215,361,880,896,771,614,34,690,62,318,886,730,601,144,688,991,869,581,684,467,192,952,841,715,884,419,1000,182,523,99,343,319,68,70,820,761,415,641,877,563,667,686,420,658,802,457,143,783,416,924,529,57,92,455,385,440,199,630,771,494,446,355,751,637,411,647,691,994,980,626,902,221,754,169,990,399,332,66,541,279,6,874,745,760,865,244,123,957,775,893,787,129,967,28,388,635,413,400,116,908,993,93,732,355,636,904,35,44,125,56,81,537,449,26,848,357,524,23,156,468,339,52,176,634,999,647,848,481,359,664,402,839,696,913,39,967,514,895,925,88,26,25,450,383,937,436,770,198,51,954,109,64,400,281,830,758,792,225,860,698,50,941,957,956,861,152,130,99,42,714,699,101,319,810,77,822,511,594,165,600,505,7,773,886,613,511,41,481,316,437,729,938,935,834,133,966,604,506,432,233,180,890,597,673,574,468,100,20,870,176,878,150,607,505,959,206,151,547,692,801,325,526,971,792,299,130,746,543,708,765,885,114,753,871,339,106,868,531,629,121,132,704,668,959,92,934,965,776,260,124,295,997,342,823,539,896,760,346,381,670,85,236,543,447,548,388,921,801,955,394,188,582,110,236,488,108,684,326,812,823,456,798,709,743,658,430,977,12,602,676,899,260,110,218,739,928,825,311,62,960,732,720,736,847,613,745,704,76,540,749,276,518,199,777,273,402,289,161,66,568,479,774,524,490,490,991,724,524,270,47,7,735,55,402,554,30,9,476,711,84,852,280,5,656,335,79,777,361,803,918,736,702,240,155,630,681,606,841,301,84,346,647,42,553,958,720,775,208,877,540,48,347,819,238,233,582,827,758,909,118,192,679,625,829,948,457,591,337,604,793,627,368,787,670,360,765,178,462,988,894,803,372,850,977,891,116,366,691,919,408,661,824,278,819,376,392,120,758,909,802,814,554,118,559,371,929,93,38,702,754,839,536,742,920,337,12,623,635,94,73,774,608,91,246,68,947,816,248,704,556,421,914,928,432,716,929,732,107,39,804,264,373,948,650,212,20,403,690,413,157,233,727,511,885,225,924,928,934,460,329,695,70,914,781,664,275,678,553,130,812,289,653,360,246,711,546,516,343,449,144,304,808,239,200,401,937,231,879,308,750,443,571,987,969,699,0,866,342,498,246,401,276,365,906,650,10,756,96,344,25,779,512,300,552,817,726,155,190,822,933,76,4,622,36,124,648,548,407,555,996,310,200,203,686,737,105,368,549,376,756,298,898,227,405,870,811,533,456,936,511,618,983,783,241,286,461,878,932,628,925,438,564,743,679,506,555,100,747,296,86,140,127,758,698,542,312,644,72,780,7,508,554,534,177,929,228,166,259,74,910,734,990,56,5,248,141,95,657,631,364,306,312,87,59,810,452,249,298,559,270,110,195,542,696,71,846,1,499,224,759,896,504,287,464,798,366,861,914,277,231,840,15,618,567,132,112,709,114,997,578,306,792,240,908,412,406,195,638,885,207,633,880,515,400,318,848,804,387,841,15,753,949,204,387,502,911,299,318,93,52,544,591,499,278,324,241,675,200,679,180,678,277,774,904,388,380,447,354,163,208,310,234,178,775,63,795,847,281,718,965,217,676,416,64,761,959,733,166,757,809,801,914,621,811,884,968,290,14,502,256,344,956,485,673,966,856,613,734,300,43,270,508,311,638,137,533,836,614,789,980,934,215,312,788,702,176,17,124,217,874,107,194,560,133,338,639,869,187,319,62,446,784,29,145,352,727,662,245,26,97,159,475,861,344,331,276,113,931,388,837,665,727,602,717,749,500,270,97,949,642,353,4,267,64,397,842,100,163,6,443,144,660,826,358,996,455,981,504,760,621,725,922,190,374,457,918,87,116,501,657,708,284,665,438,293,81,448,11,201,343,459,541,183,840,223,130,436,319,733,98,945,844,520,757,770,779,912,594,371,584,819,531,628,877,94,346,644,426,413,413,344,23,558,680,35,529,590,907,54,304,154,738,13,171,555,761,996,750,298,889,222,302,652,431,202,116,898,988,26,283,695,764,484,600,668,497,221,956,511,678,124,823,957,803,130,940,636,189,134,74,127,871,463,928,496,917,110,473,267,217,108,567,421", "388,584,214,984,941,246,952,733,653,530,954,871,521,881,192,417,777,866,580,384,454,179,759,176,51,960,869,161,599,387,914,630,28,187,586,513,298,817,457,19,790,243,385,794,252,144,646,62,109,719,439,753,794,985,781,633,137,503,895,819,932,603,843,834,542,333,618,607,788,289,569,881,868,228,322,634,602,559,153,759,677,620,406,638,585,947,947,699,482,580,696,676,751,615,778,366,875,731,842,617,668,373,805,290,508,837,92,239,203,843,854,299,933,547,205,767,351,525,794,135,936,48,443,613,753,848,417,172,249,568,578,717,885,40,650,312,589,976,781,395,648,467,583,647,801,563,696,157,399,688,723,895,669,553,121,915,758,152,839,830,628,320,700,56,460,67,712,25,164,510,789,594,499,491,2,118,956,158,736,474,15,59,952,979,270,651,39,288,367,96,687,321,272,225,171,837,455,491,126,542,498,668,796,703,366,367,217,89,871,96,363,551,911,143,953,706,293,247,457,670,250,637,257,607,314,33,220,709,910,416,783,182,501,651,241,584,233,817,708,814,65,790,668,913,727,63,924,896,21,413,147,911,129,215,69,630,961,11,525,274,392,137,314,558,916,213,540,512,522,673,105,868,946,115,398,922,914,39,472,177,889,12,332,863,843,943,455,94,989,532,826,429,28,391,960,225,100,933,122,812,663,874,585,209,795,546,474,936,388,299,988,827,117,282,140,850,399,147,365,832,723,254,621,821,863,952,256,643,584,441,783,270,978,125,595,491,193,733,947,945,343,700,804,429,299,860,371,959,831,78,636,700,941,569,117,477,522,206,616,217,550,111,294,595,572,461,597,779,739,568,50,941,883,522,863,496,871,615,140,741,383,42,399,56,64,146,645,964,517,632,793,839,491,303,370,907,888,87,515,405,172,493,663,897,304,996,246,351,646,262,927,688,878,855,363,450,36,311,380,810,963,220,470,388,7,907,665,345,702,301,848,736,782,384,780,381,889,178,382,516,932,472,316,622,87,391,914,550,107,22,457,60,472,449,369,312,589,16,438,464,202,353,889,929,222,379,606,833,493,49,747,17,726,818,400,588,913,471,342,915,340,794,10,167,877,913,818,839,420,901,787,764,967,553,912,320,412,326,729,983,498,15,808,570,221,204,873,800,126,769,16,858,185,367,870,396,322,799,788,371,264,998,467,471,212,503,512,606,354,548,764,819,426,643,56,765,271,799,960,738,989,381,893,20,621,250,606,628,807,915,982,337,48,234,550,151,941,91,651,237,572,562,103,34,203,941,521,109,324,341,248,220,866,0,788,477,767,731,705,795,813,918,886,608,344,450,381,81,494,255,647,800,706,639,515,940,725,697,967,772,811,314,636,922,396,982,363,17,749,648,488,839,519,390,432,871,993,795,710,40,637,334,86,399,147,54,919,240,454,229,833,534,983,811,360,590,762,100,976,950,309,392,357,553,545,682,815,478,716,456,318,304,33,953,961,349,549,449,582,483,894,91,827,396,303,290,578,769,614,140,468,357,533,161,731,280,542,118,393,373,120,933,937,427,630,605,207,116,316,939,206,945,840,856,587,318,676,750,115,603,67,139,21,41,855,585,362,652,834,846,286,230,806,432,349,156,855,506,296,554,263,144,836,461,145,898,545,346,676,448,982,933,130,797,515,294,844,836,926,794,379,323,95,743,213,117,166,687,135,866,932,83,711,431,452,639,974,114,357,983,148,953,181,348,928,882,304,622,698,830,678,368,298,754,23,590,733,265,690,265,544,630,923,395,628,531,84,211,873,439,29,673,276,671,917,457,556,22,31,349,575,846,515,383,731,960,216,124,407,378,628,437,273,80,55,470,190,87,232,145,348,483,947,602,219,887,853,515,299,768,815,280,215,128,705,5,673,862,289,298,309,12,39,114,683,963,596,788,390,169,413,285,158,596,981,634,510,561,908,297,63,222,611,828,637,910,463,131,559,261,61,699,511,643,168,283,547,116,972,753,715,852,624,318,804,930,116,510,147,629,253,542,393,30,911,876,227,399,115,503,81,748,866,395,953,376,206,770,571,82,158,637,542,59,976,221,566,48,512,644,796,143,528,461,951,296,930,619,502,424,531,850,4,773,413,712,400,940,325,309,457,784,808,433,817,537,916,44,719,288,136,908,670,382,432,351,840,792,453,779,640,101,229,94,935,923,213,729,655,205,987,796,221,689,689,573,222,671,898,755,668,365,533,672,484,636,316,607,22,125,255,50,913,952,357,904,683,315,542,574", "226,448,388,698,499,152,697,147,834,270,53,482,701,427,531,108,204,321,774,383,796,274,312,639,626,743,509,967,631,233,194,145,204,485,173,464,769,938,719,260,628,793,207,218,541,176,625,795,661,608,396,115,151,271,720,77,159,304,876,526,558,893,68,934,759,171,38,740,879,381,284,222,340,433,818,285,557,229,209,686,472,951,310,67,50,560,576,389,529,642,455,907,450,994,862,890,532,658,943,406,29,703,108,395,627,150,584,627,406,708,493,66,455,403,21,743,891,238,581,161,642,863,813,537,689,734,156,836,477,121,346,985,91,750,501,799,337,553,229,181,891,945,8,39,423,947,564,337,126,700,841,749,257,41,50,319,953,482,555,679,325,170,15,326,944,382,542,37,395,293,648,902,230,570,922,233,837,719,312,492,486,814,971,715,708,759,684,579,300,314,982,811,246,380,435,199,136,443,418,191,185,567,691,124,570,833,450,630,536,781,36,625,395,217,170,252,16,421,159,411,589,615,542,194,69,241,206,56,165,760,456,546,923,750,221,269,856,316,649,397,327,271,158,142,667,577,184,229,753,248,577,495,232,242,184,296,798,741,401,101,299,837,920,682,908,744,273,542,811,796,412,3,337,43,14,763,713,913,58,183,545,316,490,658,55,405,37,125,209,449,865,795,174,369,972,656,205,324,631,230,269,32,810,146,93,727,680,24,518,871,614,951,643,964,750,446,537,579,465,122,256,115,692,825,386,562,555,461,333,930,71,449,95,963,225,89,453,740,606,878,885,731,763,321,543,624,76,913,177,247,728,205,48,834,71,59,445,382,30,350,812,850,805,443,178,145,818,370,666,440,889,350,570,876,787,718,453,900,619,296,441,965,421,446,406,508,925,242,999,895,861,273,75,672,973,480,367,408,483,152,283,532,941,242,714,196,924,740,176,266,1000,486,644,252,375,146,927,334,44,620,840,283,987,994,199,2,748,202,689,949,725,428,838,517,448,275,782,958,640,860,672,906,636,361,388,4,52,991,439,887,946,436,592,826,179,315,445,584,64,320,895,459,952,859,464,722,759,711,187,473,353,468,246,403,39,823,669,924,628,404,354,577,18,916,528,391,670,972,671,232,559,589,834,686,615,722,172,640,325,25,3,578,410,627,256,17,481,558,159,462,224,645,723,703,327,995,25,716,928,21,821,871,410,603,743,176,427,646,486,743,231,309,586,568,795,371,961,511,353,378,350,534,151,618,316,171,5,164,505,739,6,226,810,230,461,650,549,493,41,188,795,449,804,576,157,567,393,404,25,757,763,948,342,788,0,993,216,449,73,831,90,26,240,398,879,766,761,835,6,100,362,89,456,81,293,576,640,619,503,125,248,674,596,436,607,39,869,256,456,470,284,139,321,412,550,296,38,265,770,657,299,934,170,931,375,842,581,310,439,433,961,829,448,496,399,395,480,200,678,630,86,434,949,350,582,723,395,68,973,12,603,868,80,1,496,693,334,130,572,489,805,140,483,948,23,712,220,45,44,662,191,763,221,613,520,617,406,333,226,268,132,81,575,597,58,554,780,30,738,673,278,870,976,125,24,158,650,129,686,35,687,709,628,728,270,318,742,463,791,568,189,416,274,450,532,553,715,107,566,530,283,519,979,7,299,171,126,425,861,485,239,214,327,617,385,665,902,391,429,720,52,517,230,161,209,649,768,574,608,146,404,236,460,156,392,650,896,625,69,702,526,198,836,82,388,984,954,889,888,187,812,546,789,948,229,716,781,389,911,827,282,673,803,980,524,875,494,502,259,707,605,735,794,261,270,283,229,268,304,477,53,198,61,706,307,17,191,135,170,103,934,505,858,778,366,280,520,996,211,94,57,733,427,862,658,748,610,441,354,826,480,654,910,660,248,275,898,728,507,670,18,964,830,675,555,955,122,579,446,882,68,828,289,522,434,35,32,725,815,52,27,532,851,523,119,423,164,493,64,17,807,567,321,19,448,373,462,903,494,43,354,316,777,937,807,22,88,78,502,281,334,173,573,21,889,278,394,929,969,950,235,125,116,877,387,215,402,363,563,39,546,716,405,7,727,943,567,496,820,799,733,253,282,910,42,726,604,982,176,793,904,546,972,190,595,354,841,981,157,810,245,556,616,534,318,548,313,560,936,864,797,463,69,255,238,784,299,342,142,471,919,957,921,787,607,88,340,114,961,205,105,474,780,708,61,225,689,147,566,659,862,866,692,936,899,296,799,576,407,215,522,59,698,545,834,256,339,416,849,95", "338,16,509,613,760,87,811,459,552,933,106,172,214,237,838,863,382,130,987,360,277,196,415,268,564,797,33,259,394,260,503,162,364,762,47,540,237,718,515,970,716,608,830,658,226,939,869,16,344,497,699,675,483,684,494,966,308,996,101,150,250,252,416,787,461,455,421,869,325,289,389,467,690,368,23,849,346,175,588,359,340,656,709,6,223,693,332,326,503,925,258,553,908,867,662,718,858,613,88,848,673,484,877,141,621,110,956,14,481,257,655,480,215,202,531,668,425,301,61,161,559,438,624,668,103,323,734,874,659,896,343,730,789,417,382,111,540,229,729,136,627,664,463,116,567,856,420,615,665,17,907,961,764,234,194,916,511,259,487,782,378,365,223,270,95,981,785,432,818,527,518,68,95,359,597,580,537,30,735,970,786,356,410,490,657,696,795,836,661,904,250,832,445,909,10,555,796,627,910,517,575,268,392,715,800,340,809,562,837,866,339,820,179,613,836,132,63,752,443,80,3,465,801,169,376,208,875,645,224,226,943,323,581,948,951,444,187,955,134,159,712,221,384,408,854,60,512,21,168,297,234,311,138,44,447,725,813,319,865,100,46,967,749,571,907,57,108,867,174,645,579,251,555,29,896,355,618,776,612,23,372,56,914,943,654,452,785,317,869,680,402,64,595,202,125,659,7,358,686,738,511,660,472,620,340,602,63,217,427,528,56,489,242,689,356,99,24,946,728,626,66,900,335,7,416,966,622,5,647,724,588,802,950,756,758,178,947,415,813,222,963,459,805,899,30,444,486,395,925,555,383,113,84,345,893,240,185,622,109,493,749,602,613,640,274,475,929,424,765,952,1000,488,93,786,733,169,144,248,242,679,296,907,13,725,903,551,620,72,137,190,921,875,872,5,865,203,718,29,649,490,514,566,861,878,538,640,236,184,173,269,280,90,787,956,776,782,784,568,888,884,776,137,207,966,918,95,517,800,718,784,205,720,719,443,245,723,706,925,433,174,369,164,772,542,635,146,977,65,522,199,44,54,146,901,879,579,819,393,923,985,674,124,657,322,616,327,89,396,994,320,404,783,218,173,39,580,359,879,916,709,918,367,764,139,894,138,605,504,801,966,424,19,868,783,506,221,34,591,83,854,421,15,280,654,747,268,353,93,129,495,259,428,950,535,965,173,617,691,971,158,423,121,787,293,365,264,621,751,984,103,208,606,552,663,661,523,352,757,491,497,77,774,513,195,235,750,24,575,331,525,706,35,820,120,251,305,768,10,340,691,592,350,28,827,861,604,618,864,29,112,642,15,498,477,993,0,316,111,989,632,36,318,222,283,52,521,859,183,94,768,298,427,894,606,238,187,203,204,226,752,154,773,162,59,253,484,861,163,36,327,671,893,775,759,432,281,733,495,348,541,116,545,457,664,994,859,976,606,432,624,356,330,872,471,108,329,104,76,212,357,414,771,777,679,96,283,339,702,724,343,754,759,598,923,165,156,248,562,670,772,631,657,853,985,128,973,457,122,225,634,97,398,512,232,408,149,87,80,836,266,461,881,33,859,318,859,175,862,309,161,50,802,540,797,79,492,664,556,909,901,42,3,876,418,8,104,19,976,329,116,522,264,405,792,846,741,292,929,318,79,618,952,433,876,988,688,594,930,13,631,631,960,394,404,240,994,767,485,561,193,919,799,445,605,51,835,259,455,563,210,910,779,757,910,715,337,910,64,204,410,166,488,134,451,946,731,614,494,544,169,886,910,60,946,835,455,135,873,988,933,34,831,213,226,757,443,784,141,378,5,547,100,147,941,965,513,834,163,960,566,673,228,411,196,476,605,840,222,955,714,869,742,520,70,456,10,721,90,160,829,719,555,452,655,682,258,312,773,656,334,121,973,186,505,562,453,812,499,238,400,602,388,585,452,532,555,748,643,127,28,205,96,799,402,158,727,587,6,910,370,448,53,342,304,753,497,432,687,738,43,10,528,37,601,446,756,881,899,186,451,331,981,523,205,408,380,826,390,727,6,55,33,452,370,474,701,838,974,834,692,117,247,373,357,291,297,713,355,276,925,448,952,490,836,388,473,645,259,67,866,133,94,348,542,460,271,741,105,986,960,685,213,689,343,575,956,276,416,307,532,934,601,540,412,814,620,386,998,584,474,753,603,434,69,621,37,426,611,457,823,709,116,455,670,472,913,928,85,962,781,642,1000,778,976,238,349,341,875,901,274,613,373,799,947,702,644,307,608,818,207,541,159,688,833,139,747,634,472,954,550", "41,82,980,689,963,106,909,106,272,601,133,571,503,741,762,226,478,867,96,536,332,531,921,583,236,841,793,34,774,727,808,811,614,900,945,274,703,840,208,841,276,162,533,973,442,11,909,794,307,244,999,186,416,477,432,540,280,6,78,539,893,596,286,890,719,282,988,441,701,465,555,741,727,460,898,56,962,281,283,370,684,331,292,117,955,595,672,575,375,545,444,716,361,526,253,794,423,509,552,958,418,585,478,44,734,538,816,708,663,655,784,323,431,381,17,977,847,477,69,56,79,802,552,841,5,411,860,613,415,435,340,189,162,756,584,825,660,962,572,552,446,577,425,547,852,367,468,933,274,258,197,490,404,838,987,541,597,390,930,512,115,765,457,367,119,91,102,876,552,148,279,392,850,258,523,870,927,357,802,334,752,316,25,96,766,851,322,118,894,636,441,453,769,706,176,834,784,840,453,182,225,680,961,824,171,828,419,787,542,563,938,354,389,493,578,539,283,199,86,496,236,539,483,22,715,706,409,813,302,402,194,976,19,60,225,565,129,905,649,582,255,461,880,998,320,267,374,950,553,909,685,552,749,746,32,570,496,535,712,276,351,77,522,363,208,294,55,849,979,610,857,583,303,388,308,655,26,728,470,895,294,542,861,2,313,126,754,739,48,150,728,358,697,414,568,906,203,998,581,137,993,512,248,839,310,544,338,919,866,306,792,470,857,522,479,15,32,966,189,795,111,48,627,832,162,48,364,476,681,838,316,745,476,770,732,278,916,532,566,980,728,340,627,977,91,430,142,58,824,128,236,8,847,534,278,894,840,332,975,562,337,711,338,38,744,826,855,965,2,875,300,828,453,561,858,427,227,893,637,564,397,552,158,258,896,24,812,865,333,353,115,919,772,812,17,349,126,816,927,261,201,716,712,736,535,569,33,52,907,34,760,765,784,236,66,753,5,369,55,441,774,555,738,723,766,707,814,237,639,814,817,268,956,67,366,986,932,233,283,33,600,640,222,301,606,644,278,696,741,120,486,793,541,609,429,866,700,831,4,801,526,876,638,581,135,904,32,112,140,608,843,664,957,809,332,727,223,230,132,461,937,86,201,736,696,213,547,158,564,717,460,347,790,692,246,989,182,414,544,291,440,37,674,813,721,351,585,322,51,829,537,339,292,271,440,635,317,756,569,328,5,587,639,475,136,897,5,550,75,587,107,795,177,916,616,393,983,438,763,499,96,979,167,941,220,577,177,269,926,580,32,755,663,176,978,349,368,993,347,444,344,457,828,839,995,633,268,991,249,143,153,75,246,767,216,316,0,390,770,182,857,251,337,839,823,1000,990,421,668,913,958,330,269,973,245,304,293,795,272,319,846,163,447,8,988,495,682,751,141,277,72,211,396,174,348,705,302,165,377,896,847,281,31,981,612,603,898,630,799,173,444,84,778,242,658,450,427,858,23,516,955,480,530,765,429,576,628,268,837,249,52,582,880,998,544,343,272,410,139,402,693,893,186,728,106,317,409,983,588,239,216,343,130,571,183,957,485,94,463,422,759,295,697,916,708,236,421,939,867,256,493,252,918,142,364,105,864,749,518,502,285,71,317,927,764,649,479,263,251,333,508,433,237,264,101,852,774,122,906,388,267,863,960,117,732,349,731,449,822,794,389,422,49,979,750,13,464,268,707,67,46,758,805,410,895,586,871,998,52,641,129,503,440,398,303,411,848,904,133,292,907,733,224,660,574,306,354,29,626,915,271,168,170,249,234,296,443,844,24,664,451,591,334,273,510,350,366,870,635,638,398,471,307,476,227,470,570,183,297,165,206,34,164,740,452,71,902,529,89,621,360,49,588,322,647,22,578,149,813,671,66,698,675,394,405,832,975,484,699,48,16,828,140,288,880,747,553,490,911,882,380,915,353,474,184,165,702,569,260,20,781,909,205,473,865,827,27,987,665,601,610,806,326,153,914,364,545,799,798,199,939,381,958,410,140,957,745,444,393,871,791,315,735,512,892,419,361,115,382,512,650,672,201,61,800,935,351,60,365,67,524,237,257,399,28,630,311,322,313,920,789,265,514,713,397,803,983,329,974,702,421,687,851,172,59,904,2,258,278,694,795,226,455,670,185,940,852,477,644,580,844,825,805,150,151,963,219,328,936,913,639,653,433,141,164,585,770,752,600,411,677,183,10,906,82,74,497,36,784,723,185,287,905,677,598,703,284,337,221,311,689,534,839,306,178,622,8,427,688,266,11,508,953,220,219,95,656,671,675,814", "429,909,622,931,163,801,895,271,661,243,261,164,807,270,913,67,870,937,200,586,172,787,516,479,400,407,384,141,44,224,755,472,430,182,996,595,608,464,291,482,323,377,250,800,286,58,378,867,437,256,454,53,685,196,50,162,503,289,337,448,982,339,150,557,170,422,852,954,970,845,377,312,670,399,541,920,560,231,931,247,214,14,780,17,25,330,899,550,48,998,451,866,341,635,607,130,916,687,822,441,820,465,379,23,949,31,180,931,96,761,284,915,83,274,376,868,946,821,344,79,632,315,779,483,247,444,305,273,82,121,503,189,538,49,887,45,53,328,858,486,450,339,905,517,840,206,677,409,739,962,367,97,243,473,512,202,251,897,433,495,366,202,136,875,2,839,366,291,709,871,655,606,258,333,394,221,507,575,723,412,36,792,812,828,142,337,634,403,483,179,350,389,943,637,317,618,196,912,540,209,545,131,653,942,316,307,205,514,2,75,213,753,548,588,954,397,94,938,556,744,474,509,997,120,295,231,133,63,597,98,628,405,815,944,115,124,547,826,665,434,345,761,545,844,509,734,62,328,755,810,354,615,209,418,295,529,788,152,257,914,591,155,751,585,507,588,836,763,652,776,16,540,447,783,729,438,134,553,490,734,139,22,773,255,804,704,9,39,147,102,67,272,23,692,526,879,289,261,30,207,756,813,615,260,853,510,887,627,127,947,264,216,173,242,693,561,236,286,260,498,39,656,699,739,623,252,988,241,659,753,637,395,493,298,437,908,808,596,230,715,216,381,452,882,454,715,267,808,954,340,72,958,800,16,568,994,460,341,522,29,104,149,543,151,978,668,186,385,253,762,723,138,896,272,342,65,921,510,10,355,620,328,598,623,868,798,565,443,743,445,471,41,425,212,375,35,438,115,631,72,394,962,316,271,908,109,921,454,830,194,723,95,346,860,342,751,239,733,633,481,129,345,692,860,403,379,434,690,418,705,551,516,383,362,106,959,322,960,606,503,795,170,109,869,797,300,365,215,585,727,797,550,481,228,194,984,214,40,749,214,540,556,497,541,166,564,23,843,109,605,34,484,553,98,722,505,217,131,410,353,908,687,544,852,411,667,435,591,63,888,164,805,342,572,439,440,125,739,80,34,706,865,639,797,594,906,208,139,199,215,692,443,449,835,57,268,488,579,174,462,782,796,151,311,547,873,242,529,772,57,375,454,213,574,711,363,544,989,49,311,579,974,753,58,104,645,826,240,550,961,479,293,749,916,806,236,871,856,315,52,417,666,537,835,771,109,500,13,561,220,981,559,401,731,449,111,390,0,351,691,67,231,933,950,42,428,261,121,543,755,6,873,477,692,607,47,263,223,397,986,223,274,769,866,178,518,74,572,216,50,394,613,842,902,918,442,192,246,796,576,435,241,226,978,194,708,849,428,600,965,852,784,141,836,277,529,808,370,5,933,320,28,966,793,263,926,241,836,159,183,298,572,613,165,125,518,361,518,824,204,700,691,116,14,409,533,640,704,32,120,745,724,440,114,693,763,491,408,764,93,806,62,644,792,101,913,19,174,726,164,254,360,412,641,932,435,275,393,514,298,615,479,895,106,432,118,25,80,705,16,618,946,355,489,764,821,545,650,761,969,270,668,891,345,577,50,249,766,452,205,544,134,555,73,643,359,961,79,564,8,775,226,623,551,643,313,270,114,927,816,829,12,677,614,333,497,687,655,829,787,82,673,513,505,751,855,855,476,836,565,205,934,202,203,372,574,955,137,214,737,252,782,886,747,673,226,83,918,279,81,893,798,997,58,346,511,943,353,262,721,206,517,400,472,310,359,128,848,169,28,607,623,371,490,52,967,648,620,496,734,410,193,939,249,258,28,824,96,926,628,742,544,358,701,502,574,354,515,172,15,180,878,649,669,90,61,556,384,999,340,275,559,644,751,115,269,198,846,670,633,580,143,561,964,894,470,715,181,601,17,31,283,210,208,57,419,425,564,890,206,92,297,106,871,967,579,429,534,527,260,87,228,510,398,237,783,80,275,696,521,454,879,129,806,980,110,444,359,903,896,423,737,223,474,197,994,421,965,426,915,712,789,860,471,368,413,738,783,221,433,937,671,536,449,57,828,9,873,401,467,160,903,872,371,300,154,350,557,819,199,455,537,202,323,380,115,977,967,812,922,391,425,828,438,807,935,438,265,57,914,199,604,865,443,764,588,364,445,327,586,778,190,419,419,306,448,666,458,744,613,411,511,274,65,791,939,78,411,591,910", "367,104,353,623,332,876,375,562,312,429,812,85,865,825,128,386,742,667,459,393,134,859,519,671,802,370,899,594,240,255,761,101,904,335,901,482,585,638,194,389,807,238,992,185,932,150,772,319,839,268,191,350,818,209,243,831,570,417,531,245,941,566,687,680,347,750,294,738,379,350,805,22,725,974,443,365,78,264,204,64,932,27,992,387,624,683,59,776,488,565,27,901,415,698,678,780,117,883,329,793,952,171,920,740,651,491,383,14,305,526,133,482,781,731,227,484,943,604,195,68,819,657,985,593,751,11,783,662,455,446,348,226,782,622,736,426,919,552,613,451,882,729,497,620,765,695,16,620,540,182,410,927,577,455,13,608,226,779,343,389,877,164,91,608,181,704,673,521,493,64,965,419,335,618,21,420,12,496,854,237,733,397,874,876,701,590,955,597,873,240,146,95,333,713,945,23,753,652,776,736,765,482,73,383,130,163,805,601,617,179,636,163,827,893,545,427,939,121,270,955,918,573,370,766,861,772,468,844,495,300,656,657,415,392,916,270,78,202,354,690,640,785,858,846,597,830,825,522,78,260,24,603,290,853,8,645,109,648,505,231,969,300,393,463,742,241,407,611,905,949,507,389,647,406,225,838,403,966,821,311,333,925,666,211,68,412,340,238,558,389,51,29,798,772,589,899,525,142,292,582,181,949,269,99,200,623,218,925,936,835,806,553,274,103,30,937,479,734,133,819,468,501,757,362,171,978,194,371,644,132,826,389,975,743,115,807,155,106,264,618,845,458,343,416,370,240,924,867,584,658,419,995,236,535,842,128,619,152,423,875,276,888,309,388,927,297,837,60,798,92,656,203,308,74,88,483,205,722,275,413,485,484,777,445,810,510,454,194,108,416,942,13,407,194,122,808,840,119,96,514,583,210,323,50,853,381,774,217,696,123,645,222,646,150,800,781,313,957,33,37,890,577,465,226,29,619,540,63,529,458,566,259,444,753,736,869,525,647,341,624,897,69,378,491,535,647,291,338,931,160,501,531,198,383,510,849,422,430,736,411,525,603,104,865,197,647,113,510,135,576,898,814,478,58,181,463,700,486,523,250,271,159,390,495,232,597,790,765,415,820,972,732,156,47,855,814,763,316,167,491,601,645,121,896,717,436,958,525,62,995,157,974,707,135,709,836,556,564,17,364,310,104,654,691,279,258,361,483,451,331,501,166,929,288,507,747,469,627,254,422,422,54,298,897,505,812,179,483,155,732,878,517,273,212,455,498,6,512,807,496,323,952,140,151,670,973,39,327,240,800,88,919,276,705,73,989,770,351,0,431,623,116,806,988,914,79,644,570,672,546,576,80,130,50,185,909,868,695,840,686,628,808,340,694,654,90,959,422,606,443,452,41,108,14,772,431,239,110,319,20,403,106,849,893,715,322,961,897,681,108,391,585,638,447,706,250,504,507,340,988,325,7,240,670,145,940,849,316,883,441,241,751,792,889,937,302,68,341,844,792,127,872,383,152,205,756,276,721,360,939,831,710,315,59,175,299,721,521,596,332,439,64,941,503,856,494,407,825,711,744,355,756,630,840,528,418,1000,823,945,161,942,528,710,565,283,223,428,21,682,417,194,385,938,136,885,103,482,681,481,792,676,10,43,598,170,172,271,922,660,28,396,723,198,192,371,931,987,453,754,354,783,956,359,771,898,578,576,669,767,948,416,982,385,313,909,105,12,799,213,573,374,891,314,990,40,481,563,430,206,962,139,26,197,301,781,526,613,309,761,924,33,430,252,832,36,49,913,906,478,961,602,711,606,378,813,62,630,14,415,688,897,745,698,54,737,179,971,752,946,784,913,236,3,588,116,155,250,87,992,657,197,853,828,344,986,619,786,638,995,406,997,918,432,864,224,380,190,589,301,849,602,749,184,212,26,700,250,332,258,508,297,744,471,537,148,120,24,688,873,221,524,534,123,826,517,299,618,226,664,308,23,661,627,657,817,636,519,660,57,14,711,848,498,37,385,886,897,453,606,496,348,983,291,348,778,575,749,431,534,579,704,869,788,494,142,862,139,915,160,740,565,664,777,803,346,132,167,662,229,21,632,587,434,275,539,732,707,613,525,154,350,151,700,861,553,860,924,876,941,257,425,920,521,271,392,178,104,3,458,880,392,984,711,153,876,128,51,825,652,329,673,408,372,414,865,426,558,667,239,287,865,323,857,151,606,597,406,963,583,565,392,284,818,512,56,404,465,171,207,660,844,750,108,635,558,469,299,127,453,383", "940,608,233,390,910,249,608,518,470,208,379,333,752,790,642,654,907,311,665,51,905,307,705,203,577,468,810,903,351,422,543,365,895,468,560,685,923,666,666,767,270,957,478,105,425,564,806,682,61,661,686,648,380,149,752,567,30,526,255,669,47,348,719,12,253,274,864,801,740,603,331,754,294,8,505,463,536,838,689,687,237,898,28,712,500,345,411,94,41,289,715,297,929,446,361,841,447,457,786,616,400,674,187,769,202,799,600,707,957,970,268,811,426,773,283,455,845,924,700,289,400,6,264,639,291,661,111,38,48,283,672,666,350,876,432,417,58,955,235,900,244,101,572,718,564,638,918,553,979,198,184,656,960,414,524,310,448,168,958,516,532,359,627,700,321,736,270,142,450,931,243,705,268,635,47,113,602,406,84,834,191,830,471,80,764,944,230,9,121,144,683,343,658,499,2,663,910,630,393,683,705,487,837,957,358,297,730,920,403,936,377,285,400,623,728,576,204,188,213,446,616,96,679,964,665,989,381,493,993,97,853,127,999,909,94,327,49,29,909,864,782,380,803,355,909,512,949,758,816,70,900,544,385,670,824,473,739,33,909,994,102,398,723,572,588,601,21,936,284,685,663,876,399,812,802,54,370,697,860,868,12,853,142,459,172,650,254,423,221,331,522,900,560,642,297,665,731,724,709,993,698,117,602,367,149,942,480,607,18,623,677,652,167,514,82,830,922,497,133,574,578,180,811,201,856,170,792,412,598,532,141,937,443,618,844,788,949,831,988,442,84,542,898,666,311,308,902,55,605,320,911,418,211,785,773,928,248,430,365,65,303,447,421,586,600,17,826,186,400,904,307,785,398,78,621,782,994,21,700,317,636,530,475,189,574,626,64,610,684,541,178,91,188,97,870,868,405,22,380,116,41,527,231,736,75,37,748,160,997,98,593,277,593,790,182,284,717,420,591,746,131,383,600,498,83,189,229,527,311,236,644,648,990,806,768,904,883,741,469,107,182,133,1000,746,226,778,677,550,983,670,420,362,668,197,704,700,84,724,822,122,581,968,992,937,483,952,524,343,784,369,68,866,820,526,924,123,711,730,112,248,824,340,317,177,851,279,954,139,495,227,835,10,405,152,782,195,206,868,259,606,876,371,562,556,306,826,34,116,394,337,423,154,910,156,550,412,211,433,91,604,197,316,596,843,503,364,407,821,5,844,226,672,947,325,625,493,110,931,667,40,590,215,551,256,486,422,100,702,716,604,769,312,557,915,937,788,52,545,369,630,864,819,891,442,510,583,335,212,725,624,784,334,365,795,831,632,182,691,431,0,395,79,129,319,650,9,300,394,754,738,681,505,681,675,235,99,751,701,453,402,817,13,989,398,920,708,860,717,577,400,475,280,803,49,802,546,509,181,29,586,472,425,368,640,919,817,820,513,333,197,902,506,654,702,945,72,816,549,653,262,171,315,320,867,917,592,913,53,622,638,623,375,453,816,607,711,187,381,365,455,751,358,777,217,749,577,647,865,167,769,6,198,986,129,174,630,430,622,660,103,871,536,190,939,154,45,306,379,925,271,680,154,495,828,209,369,96,936,813,771,355,724,396,246,334,814,177,41,128,20,236,704,962,559,789,533,758,294,690,509,316,250,36,761,855,621,553,221,336,513,270,637,138,124,612,114,203,218,771,543,976,940,814,660,713,989,960,95,83,456,663,222,984,762,680,498,764,834,577,290,447,763,917,769,500,922,844,840,579,457,41,665,701,196,170,892,399,173,864,68,665,573,380,15,241,538,161,375,679,835,7,340,392,211,725,464,917,158,832,532,737,705,309,886,431,115,478,859,764,888,450,646,861,648,802,496,275,373,858,675,904,942,278,603,553,255,9,101,712,351,627,258,473,803,174,160,677,325,14,892,406,170,429,942,434,79,181,814,736,226,805,571,373,201,666,740,105,47,932,823,5,658,968,559,797,766,521,309,116,683,153,89,692,96,802,703,478,181,17,71,60,10,863,716,519,763,698,564,766,752,631,296,762,241,92,861,971,323,781,632,37,279,933,865,764,896,440,716,557,722,80,798,778,904,698,432,944,104,461,129,283,664,560,132,609,208,635,621,706,182,537,15,172,353,559,847,586,40,401,97,697,746,974,875,376,345,974,317,122,195,370,618,730,583,445,51,656,975,553,892,947,32,898,233,71,948,932,1000,534,280,167,982,677,390,548,895,529,701,723,553,668,547,239,198,60,290,938,98,437,956,968,396,841,423,262,984,678,354,964,294", "474,900,496,532,877,802,664,443,488,877,808,983,386,74,36,78,84,218,526,65,896,357,294,764,910,9,238,379,380,655,384,688,795,811,496,697,899,772,236,576,624,7,210,592,570,31,807,266,618,462,109,583,487,127,426,67,32,923,679,111,738,712,361,773,590,218,311,417,401,856,254,949,413,893,534,712,355,128,484,726,383,484,197,833,700,488,443,149,591,503,33,945,503,197,59,644,1,924,750,319,434,350,320,632,337,335,133,592,162,16,951,674,821,912,670,975,549,719,488,899,722,243,17,231,602,613,929,950,217,833,64,440,799,991,81,515,455,282,31,451,241,429,599,580,389,633,889,648,584,276,17,830,807,492,741,669,102,107,412,442,607,839,339,45,711,856,836,554,903,296,641,554,205,825,390,472,374,839,5,324,226,717,599,475,379,807,421,131,774,211,920,452,864,555,55,337,1000,674,416,721,716,278,416,78,562,819,550,651,32,485,403,369,223,141,557,473,563,803,518,382,436,120,250,828,251,910,132,965,388,629,33,890,510,794,535,925,660,684,677,548,241,306,336,87,455,831,935,461,341,141,414,758,196,999,703,805,213,696,767,849,481,929,38,67,977,89,302,888,177,782,564,126,359,628,747,791,287,850,474,157,742,672,459,138,414,906,890,58,415,617,134,727,371,45,31,213,175,755,366,241,286,532,905,371,263,569,247,120,477,862,559,190,392,989,49,85,471,576,411,611,964,815,920,651,812,327,348,892,178,634,287,126,612,129,510,493,79,107,760,347,430,522,480,941,921,804,355,787,151,664,688,534,139,153,715,8,96,548,34,810,300,519,475,726,379,527,398,718,461,371,103,629,533,336,141,487,82,16,405,505,2,653,977,591,971,677,659,936,568,45,3,929,391,248,472,233,155,155,953,200,551,758,652,877,140,279,509,914,393,413,593,724,107,225,219,635,145,395,888,581,98,183,141,500,980,851,431,477,176,834,8,57,184,58,726,215,396,50,636,832,230,464,859,260,839,290,457,145,186,965,536,649,668,589,100,201,797,272,532,537,475,690,550,157,911,863,868,808,854,918,847,534,302,798,465,495,43,672,383,336,334,659,502,563,920,409,878,148,284,884,220,46,601,717,443,712,448,482,716,918,120,699,350,553,788,651,707,220,355,206,416,832,478,771,359,738,393,724,434,858,677,506,45,226,744,24,284,731,307,588,739,321,62,86,252,436,481,827,777,829,327,774,705,773,461,866,270,381,849,648,851,597,245,599,734,729,500,884,987,623,418,878,658,768,171,259,943,854,349,536,257,974,906,813,90,36,857,67,623,395,0,704,460,505,879,951,65,839,560,276,175,872,717,59,585,146,992,265,817,632,436,22,960,482,977,53,391,567,689,401,136,581,743,914,745,153,928,875,177,250,617,724,95,947,170,824,776,115,689,174,534,221,725,834,922,454,702,31,164,70,56,513,730,67,559,367,658,826,717,899,109,87,580,274,330,289,834,608,832,141,541,558,12,222,996,189,211,395,222,631,81,302,93,477,133,84,4,313,862,442,957,994,24,645,28,488,129,880,197,804,946,382,392,959,413,897,706,661,25,917,83,354,77,534,115,633,754,420,661,671,306,362,116,793,177,170,178,922,925,369,894,158,605,188,32,967,823,471,153,658,646,364,426,220,47,583,431,376,538,363,987,330,487,541,473,191,157,132,428,68,28,170,829,349,312,817,179,182,766,718,684,487,472,506,504,963,121,438,820,472,935,48,450,484,932,849,900,878,343,91,700,916,218,370,927,521,104,504,872,233,954,552,375,96,312,489,407,733,176,482,275,157,533,330,381,71,279,581,564,370,222,602,655,548,78,361,482,479,628,293,245,146,140,672,931,971,787,147,275,864,374,489,151,792,581,674,299,335,678,95,257,800,313,27,302,706,415,379,406,757,47,285,508,795,475,623,685,124,172,381,509,450,889,670,857,603,732,899,669,357,400,682,511,411,212,984,674,267,161,994,650,242,571,605,904,338,209,865,875,151,741,865,942,502,123,581,809,34,127,370,310,36,293,353,537,789,647,116,609,236,679,224,583,688,681,697,537,545,658,987,890,746,473,633,734,207,495,412,583,257,372,751,143,650,917,138,748,351,809,550,283,481,839,523,32,937,34,951,528,347,574,475,535,961,972,706,978,624,284,271,319,380,522,871,723,561,986,313,530,770,821,480,869,222,775,865,833,279,377,172,521,555,619,659,284,598,978,957,478,150,243,880,681,90,531,20,155,106,705,405", "477,971,178,752,116,529,496,953,109,786,600,343,397,222,61,181,154,88,639,280,906,164,935,883,762,176,77,529,493,126,530,931,753,991,682,873,282,299,800,318,547,986,947,708,575,717,815,181,739,639,998,194,794,353,801,679,812,665,67,490,512,518,746,489,79,130,624,604,507,543,136,434,921,598,458,285,826,818,723,108,570,523,613,254,824,942,104,829,516,202,397,642,994,743,190,469,676,707,141,343,272,798,909,381,299,373,388,998,142,664,46,493,136,475,933,523,21,288,18,494,733,430,831,335,493,411,652,168,531,599,296,850,463,231,633,567,795,136,606,358,989,723,802,20,186,992,618,867,110,342,527,204,511,619,703,93,780,711,186,932,366,216,163,947,253,870,787,254,211,280,537,279,331,477,54,424,636,808,112,609,722,969,559,102,81,39,243,698,655,21,627,713,586,519,810,967,566,674,738,199,516,639,83,687,154,270,539,51,851,453,749,539,928,130,676,562,817,775,836,765,97,580,663,517,811,524,507,908,266,908,998,711,272,996,278,124,233,868,474,594,17,231,660,309,246,860,965,609,123,635,639,437,439,426,774,191,775,807,555,532,40,6,167,236,710,928,666,723,960,136,602,137,165,79,281,715,706,421,174,523,491,907,158,384,753,337,412,777,236,765,207,56,247,869,946,471,196,373,727,999,749,65,249,697,402,462,391,128,818,230,812,396,142,109,625,574,811,85,479,639,369,313,766,794,36,946,326,654,401,627,275,410,389,690,592,92,845,356,148,817,75,970,981,259,527,766,804,598,833,308,970,235,22,967,515,404,43,206,657,391,198,517,189,228,578,739,101,922,857,539,443,223,348,772,637,792,726,209,669,464,681,333,440,798,745,173,122,407,779,51,805,616,160,914,499,354,651,403,522,871,697,39,41,63,791,70,817,164,542,935,33,732,545,210,753,910,773,701,195,366,396,265,907,3,431,229,266,844,822,503,840,558,348,857,463,561,111,466,570,365,554,642,311,825,3,909,6,933,785,324,359,344,316,914,103,534,820,387,720,67,82,148,448,491,295,614,912,197,869,251,798,318,200,799,175,599,477,346,357,416,14,276,356,4,881,794,921,115,255,507,19,756,265,717,843,229,761,806,566,198,900,27,587,999,200,739,995,883,262,794,59,237,956,530,885,119,523,545,171,532,808,291,217,81,248,10,556,736,342,799,455,632,203,591,980,50,801,280,279,510,81,824,477,788,941,549,728,863,9,834,669,634,532,684,63,913,650,800,519,69,864,418,513,934,17,591,656,535,257,355,296,823,650,918,26,318,251,231,116,79,704,0,707,971,80,873,775,450,140,605,922,690,149,265,683,915,885,46,929,420,776,780,735,103,264,475,199,82,14,541,458,920,880,604,910,563,885,462,369,679,519,707,552,586,552,896,855,220,569,655,616,745,126,845,266,592,478,560,580,145,835,177,603,125,424,521,583,290,932,329,745,984,923,352,637,764,294,479,400,368,813,23,154,9,491,752,37,232,816,742,728,391,732,691,81,715,885,947,59,565,810,96,230,386,583,452,887,998,976,635,311,116,657,779,510,290,241,907,336,926,580,632,396,23,612,18,124,190,353,663,233,788,16,996,36,740,267,534,488,211,218,668,125,207,56,764,164,398,657,981,411,777,204,901,636,744,862,974,494,912,635,509,587,508,990,755,625,663,743,659,648,955,210,972,934,207,607,364,374,675,794,256,600,909,927,52,610,445,711,417,209,9,834,35,409,887,39,76,705,806,233,720,318,948,143,734,594,889,51,176,875,941,744,189,516,238,61,486,561,324,881,329,153,620,534,10,768,643,303,31,544,938,108,201,574,82,504,542,609,3,594,880,868,422,103,721,140,898,219,736,505,167,423,581,590,86,298,41,585,94,297,79,412,714,469,317,440,663,681,356,919,912,124,694,897,292,483,843,784,451,942,1,33,496,658,491,4,188,189,612,434,232,280,337,84,593,395,132,782,786,452,944,163,601,90,774,154,787,73,243,268,115,819,413,145,195,884,369,272,170,172,713,296,179,895,901,420,500,540,450,268,212,393,599,780,539,721,236,196,692,803,703,273,388,294,853,888,909,352,772,667,719,240,413,927,968,112,120,274,532,310,380,203,236,845,988,944,804,881,375,547,280,331,283,821,229,432,467,385,569,101,199,802,35,647,841,228,530,700,470,450,850,289,187,558,532,445,457,882,982,802,529,876,321,384,815,766,166,818,663,42,439,596,89,601,426,943,777,701,556", "978,763,988,456,41,722,128,990,516,323,452,591,293,12,494,231,436,18,101,341,747,406,486,690,318,160,612,277,806,666,247,91,956,825,853,89,924,650,656,396,419,286,516,625,188,480,923,931,215,846,403,180,12,176,624,167,253,181,107,925,300,842,23,878,349,170,724,202,974,809,501,684,576,824,78,866,655,147,383,837,767,291,300,794,801,289,299,949,778,589,698,882,391,566,387,572,822,835,759,789,430,892,812,634,83,769,77,202,957,740,715,212,649,122,510,305,82,873,104,665,612,556,318,796,477,926,844,942,962,448,818,439,163,367,9,61,12,24,769,413,192,169,961,484,517,588,238,491,552,219,660,854,883,793,285,856,811,28,521,236,248,239,523,739,618,271,160,515,788,601,153,739,35,472,802,782,619,274,650,158,922,482,344,432,39,470,248,193,902,937,111,434,346,862,858,645,81,724,106,577,703,62,289,728,7,423,241,801,935,288,462,451,997,25,780,757,749,31,718,106,76,618,554,725,493,416,406,642,780,211,127,173,375,16,852,388,782,439,756,465,152,777,127,922,781,146,286,615,451,105,166,131,306,93,990,132,611,233,403,389,619,929,472,637,953,987,65,917,956,971,443,282,447,507,123,207,805,232,606,157,96,244,139,188,342,302,617,808,418,424,895,623,662,114,982,442,173,680,771,128,759,501,744,291,564,350,643,67,795,136,261,84,89,74,818,484,662,424,516,517,375,149,127,20,864,77,750,931,428,135,651,110,922,358,33,854,861,370,934,314,136,829,267,931,602,612,538,496,549,511,731,267,411,531,996,309,926,705,1,74,24,520,839,108,440,474,627,47,870,574,273,91,861,633,7,526,804,413,66,335,387,409,886,118,920,291,142,182,104,221,322,247,642,801,776,408,784,173,234,269,841,741,396,511,753,732,908,24,149,187,496,959,14,862,122,112,182,288,272,142,99,746,126,636,109,55,26,564,955,545,904,723,909,585,729,507,580,870,282,114,754,666,491,532,250,832,491,832,586,235,93,75,968,205,613,505,766,278,598,84,341,862,583,16,230,431,317,461,257,279,56,13,411,564,83,992,59,362,22,830,730,465,772,386,174,75,995,945,987,708,702,691,746,94,504,720,861,707,431,20,414,754,947,326,275,290,437,623,89,392,115,952,786,829,528,240,35,491,326,430,465,944,736,846,120,390,393,450,106,322,233,605,957,706,613,948,893,264,644,168,740,477,133,117,709,300,938,323,533,123,502,859,222,491,799,162,721,266,69,260,409,658,628,818,387,12,71,823,624,325,426,813,10,886,240,222,337,933,806,129,460,707,0,905,769,974,74,522,802,38,775,984,801,925,775,544,443,174,66,782,591,495,681,389,59,388,654,468,178,262,809,192,556,76,457,661,197,999,814,577,690,652,90,976,839,427,851,707,3,355,723,901,720,376,999,486,919,63,429,274,301,420,831,714,122,112,769,439,656,89,476,323,68,89,385,792,744,655,790,172,196,945,696,343,957,978,100,437,942,681,426,396,464,319,418,598,848,562,24,110,779,558,723,422,257,218,378,726,171,179,793,693,273,616,578,231,407,789,238,533,829,37,489,822,988,885,26,113,444,378,456,155,257,756,827,884,47,407,927,848,44,276,466,914,161,533,89,210,717,864,13,534,231,667,908,332,307,868,247,571,206,551,532,609,666,289,296,23,226,211,762,704,261,455,327,50,923,858,332,238,837,536,727,557,481,132,634,308,510,881,534,304,782,215,868,298,119,766,692,35,507,186,635,909,40,988,45,924,729,991,9,782,201,964,866,416,298,909,967,967,936,874,929,891,442,214,176,570,535,357,19,938,758,975,403,874,609,131,832,69,243,372,155,373,141,272,379,101,693,59,388,760,879,589,770,624,190,590,389,502,721,470,58,458,971,92,510,393,19,477,903,761,441,605,265,295,841,386,607,628,487,419,287,702,980,997,513,140,592,811,764,279,97,839,860,759,403,917,178,467,102,614,991,649,273,237,485,723,801,236,729,676,847,491,962,286,299,874,105,533,315,580,26,843,690,906,648,434,188,199,252,933,856,824,1000,287,823,912,482,149,544,611,612,745,333,145,694,320,915,366,85,392,337,5,503,739,377,966,919,616,494,386,184,581,844,1000,524,225,114,524,752,846,638,878,940,170,550,673,385,364,159,613,909,66,88,646,277,567,282,562,400,89,53,564,8,509,713,535,112,257,788,798,2,112,931,196,409,949,672,575,95,654,373,257,186,581,575,992,427,329", "867,98,344,497,128,154,100,485,770,11,899,287,268,29,38,587,516,880,935,691,130,964,733,606,115,568,223,407,897,465,225,195,643,438,622,742,853,349,440,421,361,862,808,201,493,300,903,752,792,112,618,307,377,618,641,965,341,160,27,52,745,759,967,384,783,900,281,758,366,751,441,525,123,514,323,601,66,670,753,438,739,170,432,872,889,587,17,173,628,853,108,245,196,382,120,207,896,343,974,287,98,846,210,789,816,518,398,893,973,861,848,54,600,168,591,735,840,959,241,611,716,644,283,816,586,147,922,329,403,273,340,996,298,513,422,386,753,520,809,695,617,121,317,492,11,706,484,679,826,770,715,165,333,290,245,466,343,248,434,473,157,593,67,563,237,611,190,21,56,913,935,515,764,75,507,384,839,560,905,195,540,48,741,900,348,791,196,86,450,563,390,588,226,604,349,243,723,363,100,160,790,187,481,75,50,450,318,709,407,641,928,163,894,626,15,204,375,937,477,74,771,937,5,919,532,674,966,89,223,688,667,159,140,121,763,105,388,436,856,382,663,456,786,899,950,47,596,590,618,667,648,206,138,221,6,94,134,492,514,425,780,560,248,34,959,781,513,379,185,639,607,576,672,655,336,256,282,863,976,715,365,434,327,474,384,460,442,6,579,352,612,439,612,977,211,87,152,844,175,245,438,75,342,197,779,442,538,431,233,172,990,712,556,591,652,906,5,589,332,508,117,503,415,352,710,323,642,543,277,524,378,117,58,834,791,20,858,326,368,528,325,740,412,244,153,672,212,158,213,793,368,201,946,767,813,661,625,998,820,282,340,769,500,440,32,341,373,192,755,250,27,15,944,941,864,114,321,898,776,683,401,260,459,418,162,654,495,223,425,71,735,444,92,776,616,867,75,232,99,120,163,985,389,649,117,44,726,121,115,992,468,362,382,171,803,266,474,959,870,537,953,233,206,426,240,321,896,285,202,355,236,785,851,951,881,976,484,232,350,811,914,635,518,584,398,255,488,974,190,302,88,631,59,955,928,482,435,806,394,580,856,878,392,205,204,576,464,559,203,269,636,701,377,842,704,534,333,576,601,695,477,886,27,506,511,509,58,784,116,322,533,328,474,356,99,738,459,525,427,282,660,65,736,76,825,609,982,474,581,623,481,761,553,956,166,270,431,364,817,539,389,310,50,122,902,393,797,926,646,932,94,719,713,876,36,972,371,459,243,466,943,258,429,751,584,401,157,177,456,690,446,11,857,847,330,232,207,111,140,750,69,48,270,905,921,496,703,21,914,630,362,746,756,608,398,283,839,950,988,319,505,971,905,0,832,633,583,515,310,323,29,610,424,912,268,793,567,240,904,905,200,273,745,866,969,137,203,715,300,672,108,799,567,770,856,68,80,931,915,570,280,100,16,664,663,241,154,644,480,411,185,163,843,185,518,582,113,680,946,913,330,739,389,504,484,870,748,436,696,96,481,440,433,919,493,462,658,650,169,495,351,919,442,92,248,488,285,746,728,840,896,203,207,490,298,48,172,3,951,632,893,701,213,723,889,219,503,679,171,875,883,575,370,420,891,130,949,75,547,24,571,423,387,557,169,101,747,89,770,563,797,128,489,38,425,264,535,172,122,226,786,625,570,144,562,156,928,453,702,544,70,627,373,783,998,528,442,902,516,471,652,54,921,328,499,385,805,391,123,411,595,522,421,811,611,785,975,158,127,860,514,180,404,368,418,282,293,831,538,426,405,784,812,976,218,416,905,657,235,536,648,635,157,740,33,978,364,269,969,909,558,312,741,825,152,173,744,892,858,393,259,734,237,88,86,834,671,526,155,276,560,703,605,361,606,309,467,197,673,806,223,803,143,503,26,837,335,463,804,106,783,116,12,59,276,326,468,376,928,530,350,729,766,733,792,218,743,631,472,520,969,448,396,53,499,901,390,795,606,969,124,458,220,986,384,51,161,576,408,690,414,812,127,307,153,554,835,891,823,499,241,671,209,273,863,843,32,827,629,48,58,787,7,749,638,96,546,245,939,886,246,281,962,7,894,206,913,668,691,426,935,884,885,566,985,646,722,660,760,784,424,119,269,230,956,991,498,86,116,804,139,640,419,590,992,67,892,179,357,619,569,853,972,116,852,955,472,616,120,237,832,106,751,982,834,878,494,519,836,974,323,165,610,325,932,984,806,941,338,114,153,207,278,220,32,295,580,689,853,81,234,141,751,337,68,621,6,711,22,694,745,744,244,442,80,745,882,495,46,983", "975,464,445,438,146,263,210,380,281,234,75,3,339,505,176,892,229,154,891,733,141,408,268,247,786,809,176,604,197,617,685,442,393,554,672,490,677,282,535,31,498,280,392,198,112,58,511,398,836,337,511,283,436,710,521,942,24,411,135,65,684,11,86,614,249,989,310,215,843,748,903,258,611,608,659,618,288,307,558,810,800,131,76,345,826,380,336,648,571,669,734,303,11,789,907,467,966,625,925,542,649,241,794,917,881,152,852,342,780,96,499,278,966,954,168,516,910,426,833,474,274,285,169,367,822,987,46,340,650,375,961,868,262,58,626,259,634,215,125,621,988,624,580,439,550,669,862,814,103,44,166,489,623,521,260,188,515,495,446,435,999,956,674,683,519,533,118,388,499,964,151,916,963,505,584,393,663,639,674,328,350,906,640,224,155,528,257,479,938,934,853,352,74,196,378,533,280,415,745,59,139,852,191,335,439,833,292,768,804,201,219,224,932,494,413,605,610,512,258,648,386,694,993,752,260,659,38,651,543,137,65,8,769,577,420,695,979,807,511,177,957,887,591,87,182,439,344,571,906,1,400,172,840,613,211,818,283,151,624,601,237,128,309,901,434,203,90,799,592,333,837,778,988,289,358,79,43,203,322,944,632,835,27,887,818,146,483,875,47,905,913,141,672,49,211,393,232,974,155,80,641,42,264,219,321,162,402,230,951,718,687,973,596,365,70,130,767,716,699,361,152,32,919,609,151,105,22,897,966,751,709,823,868,616,537,606,253,616,306,301,858,231,38,276,363,963,35,480,3,200,375,829,732,964,960,718,643,436,458,82,790,343,639,969,355,318,9,776,608,251,863,712,53,13,924,477,409,943,486,558,241,855,199,56,226,623,597,309,219,873,451,487,960,788,742,413,473,289,878,919,443,608,639,504,450,612,701,351,438,262,934,630,930,709,575,732,90,154,210,12,823,709,444,112,345,879,49,135,112,409,411,276,540,478,280,364,397,294,401,815,152,580,373,166,332,424,826,270,857,895,248,424,835,166,518,678,287,36,273,761,106,443,150,770,13,321,94,500,561,248,664,12,901,894,206,185,909,982,913,30,694,827,844,502,671,959,621,618,531,216,540,31,967,219,463,725,7,317,983,255,812,731,299,20,832,237,543,100,725,220,916,158,8,588,852,104,65,308,427,554,352,667,608,452,492,391,882,914,5,825,557,344,964,189,741,372,729,152,517,302,530,73,20,695,216,407,835,315,505,689,157,235,647,931,916,126,258,688,21,649,722,433,522,89,551,365,362,115,93,168,193,556,96,344,879,52,823,42,914,650,879,80,769,832,0,450,871,728,826,792,59,209,864,650,846,515,346,946,378,511,883,816,922,847,992,338,793,418,443,187,12,202,791,510,388,28,845,239,161,98,215,825,817,848,512,252,933,294,120,707,605,659,94,921,318,156,963,12,16,387,126,637,569,542,477,511,570,604,624,207,230,280,673,660,294,40,647,739,625,328,488,58,583,793,132,375,625,656,742,41,421,940,497,774,523,108,862,686,363,857,972,736,361,103,298,210,654,720,585,581,382,388,782,756,470,595,202,592,100,38,920,340,182,879,476,969,725,666,192,867,35,558,482,572,624,823,517,485,58,603,437,336,421,531,574,727,756,808,178,94,441,378,979,153,623,699,277,253,297,393,244,405,12,388,442,679,53,456,221,635,763,194,839,397,669,744,651,347,316,882,19,359,577,464,952,643,844,891,251,164,356,479,317,198,765,91,652,436,928,505,780,226,329,300,747,651,697,818,222,199,807,164,16,584,577,580,9,474,75,198,456,839,839,629,515,850,834,418,372,853,162,836,348,41,824,795,829,416,421,397,292,635,134,51,254,567,887,106,643,398,547,514,668,874,215,522,478,580,441,664,880,374,422,427,41,42,870,395,850,240,627,618,162,274,577,186,783,305,197,133,609,700,388,152,226,393,35,37,344,55,455,204,91,953,721,256,341,878,624,772,781,391,366,751,99,773,758,708,807,534,81,186,13,8,902,652,532,323,185,319,556,388,943,701,474,845,887,759,341,930,59,835,75,489,349,511,78,719,879,809,326,404,941,324,969,441,389,781,861,368,505,431,478,468,692,34,733,223,129,719,165,160,714,236,48,579,666,933,390,140,494,296,579,177,285,30,37,217,465,424,210,839,565,539,301,318,162,611,526,541,437,19,211,764,396,517,845,427,87,281,116,95,646,387,559,529,620,617,641,673,421,945,668,955,939,791,120,875,596,382", "632,955,890,363,582,891,631,723,224,71,474,652,351,311,278,95,525,335,925,290,852,43,731,555,401,752,442,198,708,554,674,994,904,298,660,511,978,743,817,31,177,791,911,600,806,722,361,53,108,195,278,920,522,817,803,225,556,912,272,797,634,947,150,623,693,917,262,959,68,126,735,860,493,638,729,495,407,508,622,122,957,827,475,546,731,730,401,682,563,556,15,567,44,533,224,808,125,206,89,59,607,663,849,709,440,315,619,84,913,816,281,442,853,902,874,78,703,957,148,542,608,184,99,324,415,206,795,321,689,343,630,127,950,497,884,494,215,157,319,401,288,593,58,821,354,21,690,575,205,163,251,810,51,793,222,213,245,332,714,481,779,135,967,698,9,673,984,618,344,194,48,720,179,599,933,903,766,87,577,621,591,284,88,719,2,948,758,594,337,402,502,209,871,968,629,912,212,825,999,164,309,829,627,467,359,310,102,521,650,680,215,65,247,889,572,709,372,82,702,765,283,238,998,412,63,898,332,846,4,961,554,741,4,282,607,30,315,233,538,180,246,984,491,460,516,914,404,479,941,10,320,672,745,656,828,33,744,458,673,666,189,508,674,731,976,523,542,722,309,575,993,884,814,157,213,427,49,600,109,774,398,75,386,585,891,554,892,261,595,623,208,184,152,729,388,149,870,581,527,946,779,379,584,657,9,875,598,581,461,541,920,323,993,758,833,599,290,364,818,949,581,413,235,998,924,174,378,970,719,498,903,936,451,757,699,554,278,358,930,254,178,856,638,461,924,488,704,246,354,35,874,309,794,487,520,323,926,934,258,765,867,563,340,958,642,106,73,742,652,192,210,758,580,513,48,94,966,319,571,72,734,243,966,781,495,250,963,735,561,839,357,74,960,849,901,344,686,138,806,273,192,9,414,38,796,15,259,12,415,837,993,468,496,976,590,850,284,41,200,683,125,557,506,590,118,142,211,42,806,41,86,57,893,336,666,172,650,203,509,627,795,477,345,321,438,987,662,468,955,899,161,184,645,867,893,481,587,570,499,235,766,607,225,174,101,13,639,179,886,566,377,38,433,321,210,688,742,34,114,496,305,642,663,800,464,992,266,105,966,812,84,937,370,818,852,544,636,841,528,671,300,495,847,844,56,247,719,429,765,454,239,829,772,878,450,51,992,309,893,604,858,527,436,396,973,90,578,173,72,592,386,133,212,807,784,129,83,56,437,766,931,123,564,457,290,413,172,862,862,575,353,469,538,36,553,436,511,728,628,655,187,786,535,831,104,608,806,504,706,635,49,709,344,450,766,521,1000,428,79,9,951,873,974,633,450,0,261,821,987,33,298,791,103,735,28,104,132,167,67,788,978,193,875,852,479,727,180,577,935,130,224,428,227,850,126,132,596,929,216,346,138,375,700,624,865,464,830,104,775,86,79,674,428,756,410,397,479,380,395,896,348,556,239,273,531,853,375,491,925,67,868,842,965,621,5,491,476,75,561,480,706,128,972,399,96,441,73,50,570,913,973,763,206,983,770,519,263,588,430,504,361,882,358,470,868,170,581,144,742,373,299,796,196,577,244,633,195,936,324,753,294,830,424,422,236,82,83,198,860,737,236,256,996,976,154,252,426,900,488,113,821,75,995,728,600,23,594,591,524,944,450,892,129,846,669,879,940,911,863,833,159,801,665,339,357,844,823,407,481,967,527,786,678,339,488,370,440,399,903,789,75,421,886,603,36,214,194,332,178,218,946,517,250,467,584,950,382,131,410,28,430,56,202,556,662,852,937,77,312,110,915,884,300,32,676,281,991,393,224,412,89,490,937,107,994,262,818,387,660,964,625,686,281,743,334,608,497,771,285,966,763,953,605,537,773,268,235,732,809,937,567,150,931,311,653,464,983,871,999,752,705,483,370,105,734,534,922,368,183,183,574,838,883,154,182,389,466,964,121,297,450,346,139,385,404,885,811,283,575,789,120,179,487,191,351,178,400,424,250,245,794,96,830,785,995,578,211,886,418,314,935,669,7,329,77,952,435,656,23,305,829,200,141,540,188,550,897,434,560,13,239,537,894,234,617,356,698,929,857,828,325,739,205,399,369,143,639,229,405,623,263,391,553,565,776,923,375,815,330,827,115,733,112,938,236,60,660,200,815,641,836,464,9,759,976,443,945,935,828,416,580,238,18,663,874,116,613,60,909,504,292,551,437,334,341,844,58,366,426,487,416,513,959,915,785,746,394,918,619,989,68,253,348,674,455,927,194,674,322,823", "388,314,50,701,11,703,702,618,746,861,766,167,891,333,763,604,262,718,714,78,329,433,198,499,410,471,33,594,325,420,321,219,795,770,928,663,938,808,167,44,224,146,139,19,869,848,295,724,894,563,345,605,173,743,262,79,480,735,208,608,264,437,25,333,589,154,9,261,113,789,771,126,730,391,779,271,364,537,165,301,716,314,618,155,327,347,222,956,50,728,565,559,467,653,818,619,761,625,871,554,875,963,814,390,339,619,598,183,996,493,899,888,427,218,32,727,781,61,952,436,359,813,334,928,29,805,248,47,685,233,547,296,731,478,905,752,89,819,474,826,630,944,920,936,214,247,349,706,137,266,962,510,89,35,844,995,981,546,729,819,560,35,281,29,88,160,554,842,121,785,529,531,39,306,873,914,565,393,75,398,384,289,845,309,23,574,383,442,991,440,111,571,505,992,277,359,691,953,42,193,854,490,487,552,130,835,169,968,917,352,561,927,755,645,868,617,836,417,677,987,828,34,510,456,508,447,233,241,223,289,26,580,844,300,492,4,627,552,629,91,112,902,731,67,252,566,410,567,482,456,883,85,408,272,242,673,687,308,594,402,487,630,284,495,505,864,549,340,585,397,378,998,644,609,939,754,222,682,664,947,26,512,718,415,981,986,531,723,537,865,877,30,437,404,779,370,234,419,255,643,795,899,949,971,690,853,577,195,359,935,551,103,302,636,701,85,423,86,797,370,15,160,121,198,508,755,482,756,156,929,803,554,541,917,269,736,810,844,638,417,160,316,138,712,71,619,658,984,87,602,864,143,785,271,648,716,640,593,861,237,853,271,77,327,659,218,917,159,926,947,821,537,147,561,62,993,978,865,331,890,761,37,46,151,18,840,483,442,462,804,771,808,756,701,288,853,997,734,747,709,868,475,574,122,480,703,992,625,157,552,231,246,10,462,951,317,956,30,145,418,484,50,262,658,216,455,62,608,533,903,895,621,646,132,164,328,81,546,547,478,906,202,895,360,823,618,586,618,562,55,16,639,467,653,728,77,2,930,887,432,279,226,819,181,930,827,560,337,34,969,303,711,330,496,960,307,856,374,738,490,303,835,41,980,570,903,989,802,524,672,798,770,111,415,37,26,396,398,192,764,282,641,509,706,951,212,818,392,842,305,64,13,387,425,494,198,635,593,438,924,791,773,243,138,517,929,866,962,698,312,399,560,129,255,603,477,578,155,794,573,514,93,320,751,278,770,91,674,157,162,342,459,347,979,110,231,776,651,525,666,586,325,667,646,639,518,858,842,626,702,952,428,25,381,761,859,990,261,644,300,65,775,74,583,871,261,0,741,714,458,24,272,394,989,494,990,550,608,226,750,978,864,424,675,724,910,14,619,88,476,790,162,546,245,879,756,819,676,694,933,586,478,630,91,536,260,566,116,568,458,343,381,201,482,976,506,614,127,604,181,682,981,731,949,93,463,704,383,965,859,9,261,105,681,148,384,204,203,200,801,322,250,2,648,717,700,991,171,417,10,948,951,595,929,62,217,311,154,691,961,759,131,504,190,576,478,236,419,505,152,655,568,978,172,744,662,818,687,342,352,703,605,774,578,727,117,722,595,243,451,709,872,220,82,654,522,975,282,204,886,31,898,900,730,176,771,938,535,657,83,13,528,200,200,556,160,255,21,21,123,904,320,286,71,689,154,476,776,292,796,379,22,45,307,73,120,243,890,665,594,27,749,27,991,801,863,963,48,513,596,727,928,681,127,761,998,371,433,971,151,2,309,110,852,790,154,59,595,625,383,390,829,277,671,377,384,627,653,569,802,11,460,934,945,902,58,824,22,771,261,895,54,552,641,931,839,102,613,554,829,889,29,965,637,911,570,823,521,260,518,380,358,159,678,103,547,387,827,564,36,269,18,18,896,277,887,23,344,278,362,180,504,273,904,937,829,10,502,648,390,610,880,998,497,494,688,589,140,886,608,146,815,231,160,889,361,620,655,193,264,650,785,736,811,859,752,834,814,751,981,871,404,397,198,327,346,456,975,460,202,954,890,793,470,828,272,311,55,837,175,132,560,709,555,776,704,803,817,920,632,597,678,704,340,905,783,335,759,14,900,750,762,819,98,970,842,84,984,46,603,880,179,948,794,585,975,95,68,412,962,39,537,532,911,19,897,821,662,669,302,693,468,262,67,870,929,32,173,374,984,955,302,412,414,684,143,25,950,882,870,48,744,962,323,587,786,313,312,601,395,647,185,275,767,478,928,464,617,11,958", "319,12,376,198,573,650,553,987,734,757,606,283,977,503,610,387,171,720,617,775,685,146,55,216,538,968,703,561,597,53,593,319,544,878,841,347,110,130,33,913,54,670,911,3,637,176,363,602,634,707,603,130,222,564,81,860,987,779,941,396,265,250,709,152,222,308,908,176,733,354,295,967,904,21,938,320,840,764,673,521,124,630,511,210,90,818,320,27,726,880,345,247,574,817,140,786,101,920,611,287,218,241,911,477,839,428,799,414,203,330,401,613,715,335,934,910,556,770,515,997,240,438,136,85,972,698,413,513,475,807,922,753,56,427,338,58,560,663,181,108,809,458,945,658,161,760,488,358,927,397,459,530,673,3,100,299,732,838,38,637,401,536,695,382,145,640,654,664,790,666,798,86,98,97,830,527,370,762,146,548,375,169,45,538,494,327,593,705,380,185,359,331,972,943,431,281,216,757,882,276,577,956,524,641,486,18,137,480,4,20,711,888,916,511,157,227,358,64,265,540,633,424,108,755,585,674,939,219,233,879,135,676,630,343,785,536,912,827,815,184,622,462,543,13,688,548,270,929,188,676,641,364,375,902,383,184,775,479,172,260,729,792,904,267,980,480,42,598,549,592,523,550,427,1000,606,605,550,222,350,359,582,349,366,34,340,938,587,266,977,370,517,493,362,276,557,861,643,345,178,632,251,726,753,386,433,930,699,698,564,499,189,37,573,396,675,632,291,36,589,810,943,468,385,358,234,473,970,174,485,77,751,697,760,508,874,665,599,363,947,980,136,844,105,703,434,427,552,182,854,301,910,806,32,958,532,784,610,23,924,759,130,769,274,839,985,197,291,869,932,499,474,414,912,14,197,898,632,589,228,387,545,562,889,411,228,863,518,610,719,752,260,853,398,129,338,539,248,645,892,800,826,550,352,83,272,107,802,149,748,939,805,61,973,688,124,626,523,867,565,922,178,356,370,222,822,175,627,771,846,431,521,885,737,357,806,980,889,507,293,413,415,285,454,379,344,771,305,415,256,947,798,493,963,273,537,119,366,743,805,66,457,864,752,347,765,701,102,809,849,538,338,72,861,409,861,490,150,574,738,400,607,650,24,207,884,641,82,688,278,204,233,253,810,917,323,613,777,291,115,5,399,190,152,439,967,289,635,916,554,367,632,97,978,574,234,931,199,936,251,159,594,227,19,606,200,63,590,361,329,481,509,491,561,623,921,942,293,502,837,945,473,447,180,258,652,234,76,745,630,969,705,138,924,518,162,23,922,638,357,990,518,726,936,66,861,614,212,415,582,873,113,906,779,81,835,183,421,121,570,394,839,450,522,515,728,821,741,0,707,377,861,264,34,509,929,817,684,699,958,510,361,60,965,360,660,501,529,198,5,676,848,325,484,332,320,545,671,403,947,386,459,889,928,400,615,441,386,642,896,776,91,721,665,147,823,240,369,882,887,358,480,930,233,441,39,633,838,938,286,909,64,734,446,920,89,228,802,29,393,494,409,397,930,824,773,559,170,494,366,566,479,801,599,418,536,752,142,571,327,183,185,60,538,28,327,577,621,213,846,781,431,413,177,503,662,432,766,227,157,551,154,901,954,184,595,671,800,709,179,777,943,112,4,853,812,809,240,994,272,720,161,516,504,331,742,243,891,839,791,362,687,285,496,415,801,737,598,754,297,128,430,146,454,17,536,123,512,97,432,260,398,361,458,60,166,878,379,732,419,760,113,751,320,836,264,473,659,190,408,700,737,512,813,64,35,62,243,846,760,193,22,277,323,385,960,681,145,289,512,443,611,738,194,71,147,71,960,747,138,428,938,611,177,176,619,638,904,608,221,426,976,158,651,963,78,649,579,684,108,81,20,801,856,736,744,94,645,57,560,725,209,166,539,445,299,582,13,45,647,329,367,48,544,682,360,748,236,39,769,577,478,234,330,614,228,573,974,292,855,689,6,755,745,436,779,164,67,698,683,203,483,687,865,222,603,206,582,874,57,790,245,356,704,127,3,151,160,396,83,610,549,183,416,581,556,937,467,616,863,349,67,797,46,343,150,595,359,545,600,836,652,494,434,415,482,464,819,739,465,863,857,435,998,575,528,779,131,62,609,570,616,59,111,384,987,191,255,400,508,683,274,397,260,277,758,527,598,447,196,270,216,319,67,830,201,117,776,99,456,305,435,675,91,775,440,519,3,113,988,288,820,61,759,784,248,900,236,959,242,343,893,816,823,118,835,551,99,599,730,685,458,121,830,573,169,458,24,507,633,271", "999,618,620,900,432,872,779,457,822,141,792,156,536,347,342,518,539,988,665,556,567,706,670,508,951,735,119,129,474,670,175,202,836,347,77,110,726,236,463,882,662,857,157,940,968,89,888,922,793,592,171,467,576,850,406,757,31,620,150,247,632,510,304,675,802,104,193,700,954,227,276,762,862,868,955,681,925,247,115,5,747,333,526,404,876,871,170,603,280,631,512,159,568,638,895,53,255,68,113,336,69,549,869,917,884,174,222,339,391,924,912,411,436,639,493,775,902,768,224,326,389,17,322,950,651,807,719,15,287,317,725,334,545,331,70,200,849,924,770,586,385,588,345,587,20,437,132,789,758,625,303,269,314,359,977,824,812,311,265,112,420,915,94,139,324,896,337,830,436,417,446,426,885,923,725,350,516,657,416,246,13,261,266,52,663,160,964,844,974,671,409,987,769,24,731,961,65,444,4,541,985,859,522,655,466,905,471,278,840,543,886,118,236,929,448,394,848,195,121,334,921,566,355,657,120,205,601,59,316,427,208,812,967,137,985,673,908,614,10,805,530,986,78,823,324,552,755,336,208,181,279,963,812,996,569,218,676,291,240,299,865,294,344,402,558,365,972,877,678,827,111,279,310,827,745,416,105,539,851,193,843,882,995,823,989,800,854,573,345,988,269,17,406,646,802,549,586,588,672,739,136,825,308,551,966,771,280,93,755,37,265,922,347,118,632,729,693,809,75,890,215,582,660,156,795,400,253,821,821,502,131,81,628,584,752,848,625,466,293,238,281,908,396,948,738,235,484,468,328,880,216,237,675,981,948,125,545,930,732,618,252,199,974,413,673,399,374,704,861,47,790,81,321,453,893,324,276,849,597,66,555,153,681,59,695,185,462,605,483,216,93,107,830,468,744,65,170,197,456,611,886,943,430,777,867,876,639,312,438,687,77,775,188,31,36,804,558,559,812,856,890,506,143,89,630,106,90,64,231,786,145,317,978,3,703,207,687,788,271,330,540,858,424,751,652,372,703,921,969,840,191,595,646,946,378,729,32,649,655,401,798,114,470,823,986,847,375,945,474,567,320,144,417,930,365,915,495,616,128,769,881,714,333,20,545,987,396,23,521,122,521,672,584,424,221,758,377,59,363,885,529,343,655,833,538,397,168,652,437,522,16,762,779,5,154,424,481,802,32,292,976,709,780,647,438,938,159,22,632,314,740,368,773,250,181,655,328,803,363,596,796,998,870,712,806,822,475,369,919,412,425,7,260,151,979,574,675,875,649,598,315,100,124,25,562,672,848,396,963,577,935,829,512,494,6,94,668,543,672,754,560,140,802,310,826,987,714,707,0,359,112,492,128,527,713,825,799,860,605,455,544,459,115,696,20,135,961,265,495,36,182,887,82,499,173,145,111,504,283,621,749,306,509,535,412,129,639,703,98,476,508,732,272,970,983,238,325,506,366,192,884,585,837,259,70,317,717,529,654,89,976,910,319,414,69,390,803,720,197,393,302,375,350,214,288,769,622,160,634,648,852,18,745,912,18,587,60,897,392,458,123,783,479,130,142,748,566,860,891,779,908,576,106,761,779,377,870,154,679,537,20,818,764,306,688,338,971,938,855,121,980,394,714,37,597,303,269,269,151,325,543,186,760,95,930,539,904,523,156,707,198,829,104,551,892,800,614,569,695,920,927,584,393,402,498,385,752,545,762,345,1000,792,118,170,862,412,277,49,6,763,102,412,107,509,213,422,374,368,547,520,206,468,992,470,619,514,943,444,528,14,301,368,873,303,766,379,479,440,742,483,685,244,429,536,895,432,189,74,906,828,36,244,18,657,671,639,448,926,978,312,829,678,377,34,792,508,661,205,137,789,193,882,746,577,795,204,661,130,660,539,172,917,712,359,837,86,64,813,598,82,26,878,861,137,214,947,243,324,263,182,508,842,204,921,914,829,335,855,561,395,807,624,661,86,56,386,486,875,506,171,876,243,436,542,671,592,231,673,577,948,612,28,97,209,148,885,837,157,624,444,333,621,152,140,681,165,162,806,220,4,316,620,924,80,100,349,585,841,833,610,866,355,791,446,923,493,548,406,194,390,288,394,82,419,828,898,373,591,617,598,495,789,116,180,350,534,203,341,498,315,516,829,797,182,811,573,687,890,608,314,671,325,292,115,933,287,897,556,512,672,397,993,859,170,602,158,153,463,401,135,669,611,529,397,913,960,617,301,752,282,502,700,336,141,683,5,928,258,430,176,904,15,214,549,712,630,931,620,952,882", "409,150,766,928,919,155,629,97,298,25,879,374,253,230,572,277,457,429,820,797,600,160,270,77,734,158,591,455,279,178,481,524,163,230,407,659,677,472,506,331,827,569,972,856,335,760,546,847,402,712,647,436,219,829,325,7,279,856,296,37,676,410,522,746,679,279,633,625,633,736,669,41,143,890,526,921,596,274,190,307,992,112,460,336,253,168,166,797,633,851,134,690,256,805,115,823,930,539,437,370,855,279,949,134,384,607,96,484,815,583,134,110,170,622,483,867,181,856,283,457,392,561,970,168,150,60,114,673,662,33,722,462,789,575,725,269,168,836,412,251,514,796,280,459,832,5,975,694,771,386,807,142,446,257,996,89,46,16,820,54,691,562,815,284,526,606,199,818,223,758,219,568,456,331,448,998,591,638,960,779,911,776,528,11,673,628,45,366,349,831,803,486,229,624,32,285,385,959,874,21,309,253,549,208,650,963,435,844,311,418,270,880,610,504,236,715,483,55,133,177,341,473,909,825,982,474,328,501,255,652,940,856,522,703,824,685,527,127,791,670,618,556,534,119,556,959,722,206,721,657,231,173,131,617,619,637,318,614,826,263,715,430,176,806,670,760,592,51,770,520,386,989,291,956,367,455,566,783,368,46,146,57,341,602,809,751,922,692,229,815,493,51,471,478,217,425,503,735,661,133,230,564,584,737,222,106,65,123,889,956,856,754,582,470,532,343,483,901,94,939,779,179,308,422,496,98,70,203,635,446,530,365,227,819,909,385,751,872,570,529,954,972,913,612,750,192,722,696,613,997,766,899,685,788,458,468,909,230,54,753,322,708,573,804,323,37,129,291,36,778,212,883,195,218,30,794,101,343,706,600,782,277,987,103,423,70,880,165,784,740,271,968,163,854,177,778,91,750,744,921,719,484,57,286,915,357,191,21,251,396,71,959,633,786,103,281,349,355,338,476,361,376,241,789,628,761,677,389,824,348,184,706,729,425,936,928,589,896,451,968,728,274,392,100,623,794,259,789,593,214,744,907,820,476,944,994,730,438,666,296,595,181,564,753,313,348,388,852,377,690,715,995,165,190,250,783,702,577,949,714,908,611,274,482,395,19,487,975,286,773,562,233,684,64,28,228,317,452,84,29,860,454,681,946,776,158,968,641,925,257,615,640,761,668,468,181,169,631,388,720,675,165,710,480,277,306,153,754,876,858,300,469,277,47,779,808,564,243,894,548,248,492,10,542,456,647,53,630,337,131,678,341,899,162,668,405,493,293,260,83,287,386,973,191,111,381,573,827,552,617,509,869,300,255,100,768,913,755,546,738,276,605,38,323,792,33,458,377,359,0,953,269,64,758,238,888,832,16,946,615,882,542,347,549,801,455,43,196,599,270,183,803,127,565,723,682,962,31,280,906,833,286,538,273,432,316,239,519,835,104,290,851,701,906,63,157,515,116,95,946,879,55,439,733,997,581,380,281,490,280,389,803,207,851,776,646,653,406,334,189,122,335,498,626,176,213,919,816,190,42,855,573,120,761,752,249,484,913,818,576,92,444,952,172,913,604,332,986,917,822,871,584,113,229,878,594,810,127,254,484,153,374,627,401,78,527,317,629,72,164,598,49,349,686,337,551,272,203,545,851,277,714,305,842,735,550,960,120,124,102,66,966,105,631,803,934,573,47,187,490,597,838,528,1,69,193,210,641,230,471,99,414,475,977,468,243,90,927,602,577,671,864,906,501,568,515,973,779,980,894,292,938,553,244,912,224,83,418,644,98,665,278,991,962,743,534,711,681,990,926,846,385,505,914,652,176,210,469,201,620,394,895,833,161,258,888,874,882,203,576,84,23,861,281,63,733,105,407,302,905,807,565,845,391,716,432,626,714,894,41,992,887,60,968,394,334,245,432,701,393,348,430,491,142,855,129,542,410,147,763,275,854,708,984,393,790,339,423,242,243,122,217,72,343,592,762,389,692,90,594,596,263,772,902,510,150,324,584,509,8,780,272,923,599,670,429,282,472,380,652,553,784,10,46,134,862,382,910,480,180,872,485,633,276,617,531,463,523,652,10,843,210,770,865,223,812,492,208,945,152,760,742,744,315,228,269,398,421,386,980,945,161,10,373,961,962,132,333,822,372,751,434,354,80,797,703,294,359,503,805,219,907,161,697,349,360,353,476,710,678,717,631,164,354,933,573,538,275,889,660,67,394,470,355,460,353,21,328,450,362,378,818,991,955,328,142,751,492,313,258,227,479,881,773,900,252,90,818,929,557", "145,252,552,344,207,196,532,926,854,239,499,976,610,480,664,467,947,26,388,144,524,752,165,81,53,368,255,809,924,210,556,141,892,28,878,108,329,881,929,742,504,525,274,311,874,589,645,683,653,935,157,781,262,874,389,14,26,919,951,839,730,823,559,776,23,816,630,670,191,510,18,608,882,764,163,805,76,932,909,599,763,248,914,456,181,984,528,352,413,295,637,939,405,413,660,250,215,684,184,892,352,715,645,471,85,447,603,225,892,445,929,643,765,858,297,846,306,423,698,952,410,491,980,655,989,545,892,216,171,350,966,40,592,100,691,137,739,986,268,833,285,55,551,764,388,720,454,194,656,675,893,765,23,679,528,465,388,381,850,380,193,980,50,260,128,968,302,930,430,134,968,161,622,465,637,986,179,464,76,320,850,878,721,304,377,891,839,699,547,169,708,357,547,257,504,71,137,691,607,936,664,843,749,787,151,795,814,379,794,826,806,222,765,939,421,580,491,387,833,623,561,653,414,857,696,219,947,428,885,432,614,645,712,449,717,713,504,927,662,217,317,975,905,52,292,533,816,830,660,304,286,645,347,956,418,751,684,666,532,971,925,870,38,653,47,266,517,960,180,623,763,746,382,580,559,946,753,637,320,749,528,291,978,996,17,763,883,188,290,881,766,744,569,105,732,52,869,997,302,240,227,665,395,129,988,349,247,315,599,31,206,378,682,613,527,590,356,571,271,468,363,189,739,854,497,211,809,117,404,488,205,295,925,92,399,974,31,861,609,992,706,199,310,630,177,635,541,400,710,865,938,90,942,384,222,213,773,456,452,641,735,417,124,942,232,358,277,528,415,439,686,904,764,718,308,225,408,378,431,971,591,297,137,241,337,777,222,608,274,572,971,579,197,384,486,17,424,933,976,625,947,115,891,333,567,772,249,227,616,292,317,743,83,525,968,789,230,123,929,101,23,943,469,260,799,858,708,281,721,981,717,263,457,765,262,594,879,32,296,188,802,950,709,169,497,869,842,923,439,139,521,35,811,339,7,365,121,165,767,961,392,543,600,631,760,694,675,676,852,195,99,628,115,858,32,70,333,286,209,500,897,444,669,198,226,857,701,270,533,577,310,101,583,885,92,591,264,66,784,856,701,322,444,711,713,306,441,664,815,827,685,268,144,373,843,95,987,636,368,577,170,798,454,383,939,555,756,608,383,431,943,826,450,304,552,243,415,660,595,23,54,794,742,253,684,884,452,320,707,198,572,507,789,273,844,402,471,745,459,476,557,330,257,67,632,763,602,202,264,881,535,420,552,647,362,298,958,6,576,681,175,922,775,29,59,298,24,861,112,953,0,597,526,44,829,995,485,604,67,769,716,464,878,27,502,254,889,332,97,550,877,878,511,201,169,844,202,937,862,294,623,397,155,103,472,857,750,237,446,355,260,548,995,400,874,703,507,144,847,212,870,898,733,135,922,438,19,356,467,208,280,433,927,278,430,328,515,527,35,108,913,15,254,254,881,577,853,29,27,666,444,466,136,220,643,151,827,342,752,535,759,564,126,274,397,244,609,607,213,239,740,877,871,13,586,81,742,699,525,385,555,661,418,662,247,72,417,682,860,12,920,976,838,190,737,113,931,711,999,173,980,458,855,713,4,655,637,879,89,943,426,351,845,419,347,690,44,514,860,176,575,824,283,352,128,60,749,162,232,70,831,975,812,812,216,349,242,160,14,830,406,144,530,152,389,13,128,972,762,57,638,527,563,489,977,138,634,646,174,284,703,959,313,831,282,311,706,438,91,345,984,829,256,516,245,242,852,886,866,233,247,570,969,943,308,74,414,351,902,120,870,209,136,568,980,270,146,420,816,606,595,620,824,588,625,150,37,300,97,455,524,504,866,607,151,63,220,771,258,705,997,946,232,221,10,182,439,278,375,44,712,819,218,48,859,309,851,933,668,872,909,775,51,829,20,727,162,770,520,912,937,645,495,457,432,128,392,945,824,598,352,47,91,397,490,538,269,387,274,825,967,636,957,587,573,560,849,533,664,312,585,205,980,628,705,36,561,302,82,708,669,791,879,45,734,737,196,373,741,83,517,75,250,317,409,778,788,566,548,738,165,108,374,382,716,890,223,547,44,635,257,891,457,687,497,56,359,590,393,855,525,456,914,698,608,27,338,102,517,543,949,276,453,351,971,382,846,512,414,223,6,101,902,751,996,114,984,688,513,253,94,186,801,415,917,32,151,677,802,929,593,194,868,712,112,184,11,608,196,601", "748,880,98,688,846,749,989,439,620,670,599,598,620,188,450,788,73,677,90,632,726,76,849,198,439,695,67,887,319,186,451,161,240,77,751,99,913,973,550,856,81,780,191,288,691,428,428,586,756,631,975,948,371,105,884,755,245,978,821,525,880,552,946,3,90,606,467,920,10,412,301,473,808,218,628,487,948,854,165,142,861,878,894,999,51,515,957,147,878,974,947,23,878,236,208,184,886,351,841,234,212,886,766,196,712,265,16,982,175,315,106,671,723,478,390,902,891,568,137,553,700,832,146,416,528,599,471,767,421,90,92,239,448,558,76,751,560,168,215,691,593,642,250,513,987,932,706,190,872,444,984,34,367,224,669,311,774,106,405,313,784,267,390,848,644,882,942,631,873,32,195,295,217,556,244,684,908,599,642,649,340,223,791,459,597,669,541,644,265,73,667,634,331,908,366,116,970,656,831,695,747,524,821,693,800,772,866,618,937,80,275,966,209,921,698,970,960,570,634,619,323,363,447,253,653,18,164,946,118,663,178,856,244,322,260,742,314,528,638,25,650,346,532,909,799,490,476,644,375,67,825,660,501,324,509,734,52,608,819,315,595,517,654,367,636,207,754,171,621,40,804,176,863,133,859,223,611,902,217,321,742,907,905,261,886,78,184,212,597,814,783,709,54,154,400,814,673,894,431,525,544,993,557,691,635,369,264,270,153,327,541,867,895,83,987,988,693,631,800,513,165,402,848,953,814,571,819,348,584,279,905,498,437,346,368,387,854,296,456,363,785,517,674,197,646,201,259,100,72,619,514,732,687,778,103,796,812,582,240,568,298,368,322,739,924,214,943,387,759,63,397,195,114,610,817,600,206,512,639,237,729,938,150,701,779,20,201,399,646,678,470,588,687,584,782,998,350,550,240,604,680,353,842,809,721,10,125,75,417,491,360,404,340,541,162,194,753,588,101,192,287,471,879,677,372,152,969,308,556,226,83,849,583,527,459,617,361,620,147,294,280,856,905,938,316,882,211,372,467,970,171,201,693,242,804,904,989,261,742,201,237,731,366,141,679,988,578,470,244,472,887,18,883,919,950,124,520,419,357,187,862,488,497,745,487,298,556,251,553,411,481,488,950,649,878,287,528,514,433,663,371,495,562,292,599,785,695,613,510,624,133,913,670,847,874,837,425,805,782,941,545,186,57,433,663,663,767,431,600,681,483,356,865,164,627,968,421,511,314,361,685,196,441,138,876,735,292,830,306,988,512,687,389,471,715,906,471,41,259,517,280,367,524,835,123,782,248,413,490,224,950,184,817,800,89,427,330,873,80,505,872,690,984,610,209,791,272,264,492,269,597,0,226,241,216,788,454,988,462,186,247,131,410,799,226,371,531,80,427,85,698,482,487,599,104,39,141,728,516,551,205,359,912,409,691,425,396,520,801,765,131,703,78,369,133,369,143,838,810,31,72,896,941,283,92,503,53,414,805,314,723,790,43,666,818,925,4,512,517,571,72,420,830,135,515,689,478,882,300,594,649,708,349,98,141,900,971,519,912,927,804,748,445,399,453,256,920,461,467,571,58,357,251,295,33,27,560,292,189,954,319,422,334,752,30,417,441,273,665,381,316,846,844,709,46,242,751,693,43,595,140,648,903,774,182,299,57,772,968,49,258,962,507,447,760,398,795,112,482,647,937,339,110,745,189,74,365,370,479,503,765,942,111,861,842,959,582,137,417,345,21,681,673,921,80,496,918,219,753,344,474,400,601,660,66,202,818,654,136,889,686,566,568,187,652,105,222,505,774,164,369,510,49,340,804,217,583,232,191,132,599,612,642,778,996,603,61,210,24,892,946,378,620,611,590,10,963,426,441,769,99,702,852,401,976,343,161,77,320,947,526,511,788,687,464,393,796,371,962,947,501,256,498,49,898,527,132,854,525,803,451,577,792,692,9,148,481,878,622,629,491,438,738,530,984,231,902,657,375,713,379,680,676,370,494,153,865,769,586,568,665,995,804,544,305,838,963,46,284,535,178,842,57,486,243,774,784,543,719,760,694,702,623,733,598,361,330,662,516,465,141,334,832,111,316,351,998,141,178,793,180,596,486,553,274,193,534,260,203,968,573,537,937,308,653,737,190,489,831,214,831,830,467,119,223,712,813,731,11,759,931,638,575,521,844,843,258,453,470,442,943,902,227,342,308,381,159,751,489,893,724,536,177,319,109,82,664,287,784,417,972,84,422,155,519,959,733,39,994,317,842,378,855,692,748,194,857,323,882,150", "136,429,392,842,584,154,160,14,471,315,627,920,748,347,226,297,992,525,185,973,678,815,357,184,61,703,997,939,871,597,955,45,870,182,696,536,466,130,765,208,462,753,185,895,377,232,270,370,44,11,251,94,8,606,789,520,27,580,13,579,187,181,821,417,704,597,20,636,713,776,485,194,50,237,910,437,843,64,230,991,624,443,74,631,987,752,449,850,59,997,271,219,876,66,815,19,205,475,357,848,669,474,538,948,695,922,889,812,322,201,241,528,694,48,676,694,838,521,944,622,82,983,827,837,967,921,107,293,899,222,329,928,354,143,985,600,911,694,944,774,549,381,13,945,434,952,54,744,745,123,391,70,361,281,577,367,986,171,387,240,474,668,548,908,810,377,259,358,1000,382,609,77,254,448,145,943,762,890,262,185,184,354,417,279,175,411,388,336,108,42,161,852,82,267,119,210,48,881,576,528,97,949,118,707,780,769,740,217,644,366,541,691,355,876,722,934,21,967,811,583,95,695,191,990,769,455,240,384,120,466,463,795,63,687,76,589,630,325,701,546,65,875,84,623,304,407,365,111,946,519,670,497,213,980,288,813,685,109,463,878,741,228,435,615,98,642,641,175,534,729,292,931,535,578,652,219,608,333,172,778,894,694,588,79,716,413,615,407,772,952,875,100,920,470,405,480,10,866,75,312,438,164,100,273,294,958,107,281,388,812,635,570,273,302,898,724,665,28,29,612,504,971,243,563,503,622,244,781,542,107,525,866,595,886,692,361,399,606,118,309,860,263,419,25,395,602,231,649,112,464,845,456,851,754,840,859,632,516,82,10,907,224,274,909,962,689,725,777,181,349,478,600,797,49,305,761,808,584,538,726,34,340,692,389,102,61,671,949,950,414,332,784,906,776,41,134,292,217,491,386,597,45,351,14,312,300,834,494,642,427,626,43,573,616,497,750,829,217,502,425,716,828,661,797,632,465,756,828,958,220,824,673,528,580,17,718,73,269,152,866,261,986,26,15,682,995,815,42,813,177,470,953,972,822,240,132,678,637,430,901,199,720,9,94,184,256,833,293,368,942,800,906,893,586,959,467,552,208,879,846,191,126,785,808,582,678,961,394,490,135,491,746,274,712,396,727,435,515,682,134,501,575,197,874,518,851,477,850,988,744,453,249,325,378,414,230,349,8,486,173,518,145,784,802,270,366,541,966,620,446,707,501,231,572,424,437,782,398,26,212,451,206,577,966,606,171,194,614,222,867,111,518,66,725,511,851,860,176,795,222,912,660,434,447,716,372,105,342,24,949,811,342,726,706,456,894,269,477,130,681,717,149,801,424,864,103,394,34,128,64,526,226,0,20,334,59,94,894,836,260,435,466,51,866,814,726,403,794,422,304,471,182,79,906,314,418,469,787,561,579,396,875,957,728,993,187,629,99,768,385,459,868,95,204,958,275,932,415,220,408,644,24,773,328,311,198,768,144,610,845,392,681,635,851,748,928,15,496,233,298,807,240,449,162,967,679,968,237,28,211,938,227,473,342,971,679,19,164,835,900,623,41,13,656,347,755,632,219,915,592,234,539,63,262,149,411,705,190,733,123,648,99,989,476,319,964,433,639,207,199,630,121,316,993,426,350,210,352,244,211,917,13,946,789,196,185,594,561,172,944,794,367,60,894,153,317,929,442,708,290,694,153,371,580,183,770,763,998,472,868,463,693,996,319,497,873,835,472,354,548,114,610,252,723,760,695,51,7,490,782,426,406,638,513,637,210,94,680,32,131,318,229,758,501,942,681,287,171,979,156,979,978,470,126,938,628,989,498,960,325,964,418,356,952,620,466,168,867,672,14,449,476,468,753,135,663,275,871,375,175,613,477,530,71,870,889,692,339,593,32,14,718,530,872,412,975,985,74,314,125,531,93,895,279,563,625,466,830,493,52,493,777,858,973,151,992,415,22,229,143,460,111,575,835,950,168,354,659,186,785,436,23,266,580,863,75,482,573,769,675,934,113,371,376,356,803,798,961,98,761,405,237,198,188,598,340,709,853,393,761,632,963,9,417,391,6,962,583,644,38,176,703,613,431,826,959,877,204,102,55,693,773,631,986,15,343,437,847,733,695,908,946,960,491,317,653,887,567,339,951,472,660,548,574,459,836,137,249,884,982,863,389,34,480,111,174,891,278,278,642,418,245,80,71,364,32,968,981,482,286,88,820,195,333,826,56,647,23,296,546,241,313,208,681,515,215,242,297,968,686,482,694,46,879,122,965,137,436,71,159", "226,309,700,506,704,16,198,653,312,445,991,966,379,631,67,7,980,852,179,558,743,707,211,304,532,570,154,705,57,186,570,862,803,54,236,757,878,565,984,466,12,772,265,749,610,345,618,57,683,559,252,605,542,845,416,636,70,394,855,409,142,357,526,751,361,430,523,440,343,335,255,384,771,393,161,465,249,42,373,594,788,884,756,764,481,142,99,82,30,857,238,975,518,73,781,187,7,104,210,67,411,670,880,475,249,368,563,565,673,66,862,164,145,646,385,650,461,145,12,152,662,898,94,898,761,469,709,64,474,731,545,751,324,988,23,576,487,443,540,676,981,402,249,992,625,589,246,257,504,264,59,400,784,639,739,870,990,18,847,536,576,617,4,866,869,233,237,30,352,914,702,960,160,400,918,173,660,102,571,517,80,893,451,62,42,839,794,708,184,71,826,886,863,126,814,636,429,546,91,897,338,74,668,890,978,9,69,298,719,303,904,651,119,282,138,288,611,909,612,894,347,371,231,235,274,647,80,354,632,964,385,377,200,324,325,69,233,59,198,783,550,966,390,68,146,926,435,603,976,150,925,854,655,943,868,506,811,560,238,62,400,220,782,922,204,901,169,869,546,48,55,469,381,369,371,764,149,774,754,155,622,463,960,784,458,563,454,171,111,900,778,79,387,485,158,469,974,856,914,820,263,393,885,825,993,851,373,328,544,430,86,804,517,915,341,374,584,850,909,721,915,158,174,254,195,663,571,665,640,758,394,750,746,521,95,946,248,770,94,26,691,828,304,595,94,42,70,15,882,681,167,950,161,616,854,117,583,327,189,467,252,245,168,533,241,497,103,736,939,9,28,195,648,781,769,900,161,279,501,811,663,467,168,802,816,542,502,81,163,878,836,658,423,626,367,490,527,738,694,225,967,737,328,962,944,905,298,834,460,591,857,242,104,973,644,523,546,938,113,533,603,671,863,943,435,22,568,603,944,646,846,493,550,461,98,501,452,868,439,476,525,616,253,673,840,35,586,787,111,627,808,40,279,945,486,723,42,941,225,295,27,228,466,268,109,146,434,641,393,751,421,473,674,300,600,129,464,133,151,98,334,680,150,885,987,748,801,696,988,145,428,661,772,535,424,735,463,172,317,574,156,698,23,304,355,915,9,106,714,697,953,555,212,407,12,777,222,287,861,767,918,448,169,498,787,600,411,886,84,460,90,914,87,783,960,374,171,458,775,325,459,139,256,771,839,35,627,861,344,493,925,823,457,831,379,780,639,203,700,881,827,631,430,705,457,914,987,532,450,834,530,137,155,639,81,606,973,692,50,675,59,265,925,912,650,735,989,509,527,758,44,241,20,0,581,597,504,7,641,722,567,373,745,952,593,768,614,142,373,284,968,298,422,355,563,534,807,769,425,915,874,100,251,952,961,797,816,200,408,710,23,11,191,807,30,257,167,674,412,138,385,719,67,420,668,244,527,234,280,627,498,38,908,195,882,800,303,964,886,267,112,96,540,835,20,942,322,803,429,104,573,313,368,559,762,436,29,466,18,296,352,678,655,240,367,402,620,499,744,320,509,710,703,866,102,355,941,874,323,111,297,784,756,521,472,455,333,493,653,344,780,675,583,603,695,293,403,377,482,298,835,432,500,104,929,809,151,590,34,354,4,774,525,555,160,608,494,255,593,713,939,297,84,470,767,176,851,321,474,548,192,699,8,391,379,605,309,454,506,992,829,4,805,59,393,648,574,206,486,192,390,747,1000,175,728,268,857,908,551,588,434,973,44,925,784,58,251,52,355,923,364,816,900,191,279,385,805,696,452,875,725,580,280,596,60,662,805,469,777,837,96,206,387,546,939,195,305,689,161,740,794,15,832,296,125,422,803,594,438,158,782,609,92,28,359,391,918,667,191,730,30,298,358,457,889,459,164,876,924,852,419,421,972,476,111,906,944,488,409,71,354,908,780,136,699,711,860,644,986,494,554,817,427,92,993,230,218,974,407,568,800,359,315,658,384,963,307,759,914,923,92,795,907,929,103,348,512,740,631,874,219,299,56,494,431,785,134,519,992,319,202,963,803,535,219,786,154,953,880,90,869,341,453,907,723,195,836,549,293,112,910,48,887,354,262,404,701,286,555,548,812,657,675,188,993,828,718,979,538,815,881,598,197,503,706,701,832,680,819,794,855,830,590,599,359,995,217,130,799,145,27,789,814,927,912,993,988,228,987,287,326,596,565,791,51,710,965,680,737,944,86,908,589,224,161,891,18,97,585,340", "853,539,723,946,118,648,455,477,524,578,450,35,66,44,419,126,442,421,111,287,404,965,708,339,667,420,129,998,773,983,264,162,533,871,423,180,884,232,307,456,449,117,387,30,134,89,386,86,696,509,2,592,193,387,803,762,580,430,347,739,704,911,548,803,450,41,100,549,447,632,673,13,663,87,629,936,389,691,283,563,420,998,836,613,322,572,106,980,891,51,265,641,309,531,480,490,54,849,653,848,339,471,694,290,975,107,665,848,168,895,836,351,780,965,846,685,333,258,657,418,255,947,337,187,789,530,81,212,633,265,239,562,984,48,461,188,295,332,273,437,766,973,251,707,326,911,205,347,649,56,208,409,102,23,960,606,446,926,575,390,352,835,343,564,515,62,241,447,637,740,569,840,222,508,774,294,16,598,901,54,745,719,623,101,89,329,475,693,206,967,815,663,408,351,392,754,942,860,598,185,334,414,227,508,201,181,540,592,850,641,747,621,286,700,388,691,85,17,760,860,549,228,51,322,689,31,20,623,549,191,497,763,134,596,783,254,171,198,604,228,929,490,307,85,188,409,561,393,364,20,921,341,967,766,997,361,648,692,76,211,151,171,40,882,207,232,418,621,154,627,912,452,787,934,160,724,215,889,908,365,965,352,682,278,126,49,397,265,383,338,431,924,92,36,270,405,329,749,446,284,443,998,791,51,871,844,523,749,282,778,144,864,449,812,99,59,524,157,807,568,828,811,496,457,347,216,348,40,996,13,103,702,941,665,557,478,944,189,396,997,592,168,781,68,399,944,507,940,536,835,272,671,225,512,766,935,380,782,35,178,270,94,224,860,254,731,464,14,710,985,943,901,525,481,879,788,41,165,526,160,616,89,317,210,519,917,510,974,22,299,724,509,790,264,994,984,126,695,270,99,761,902,873,204,775,547,134,682,135,522,372,882,216,632,691,214,865,937,566,961,658,920,885,841,861,402,488,711,999,417,399,784,467,471,55,695,785,735,758,481,50,743,826,735,642,989,179,777,979,576,113,390,151,60,541,21,796,370,523,796,989,448,214,389,378,619,857,812,81,814,61,638,17,696,361,331,727,787,656,437,863,686,835,650,324,715,15,812,294,366,614,893,498,325,576,515,498,658,98,443,554,768,259,509,623,705,934,499,785,538,280,125,800,82,895,881,421,708,592,47,556,566,617,822,141,262,884,514,115,17,773,273,937,674,102,643,266,658,633,15,471,693,186,308,347,329,919,197,67,586,604,582,919,800,793,973,887,751,26,901,237,702,201,554,65,697,630,777,741,152,432,621,190,515,293,238,245,607,185,235,585,683,775,268,846,28,494,929,713,238,829,216,334,581,0,172,837,804,582,595,472,837,427,742,788,381,769,382,808,460,796,283,785,383,707,700,107,157,943,291,255,299,314,960,602,142,518,218,60,543,886,40,381,130,928,307,359,430,303,153,148,856,903,475,742,494,762,969,404,883,671,17,573,289,713,938,910,812,693,291,524,11,659,72,268,266,352,579,698,424,516,512,821,344,170,976,730,391,637,50,870,762,356,537,743,771,103,318,762,193,680,623,913,646,390,515,870,552,282,560,986,962,502,280,802,797,307,693,843,394,556,656,133,653,715,929,388,883,692,590,239,105,843,485,189,736,147,949,780,46,273,675,193,966,198,171,684,141,944,216,938,984,877,104,5,638,144,862,342,902,709,742,834,208,234,324,351,813,746,788,165,183,121,492,319,114,358,393,835,190,945,637,465,419,934,599,432,567,429,512,490,265,581,622,681,5,634,399,807,705,739,336,483,697,806,984,792,360,26,404,48,233,841,245,898,420,558,677,521,250,392,391,462,328,978,663,864,666,864,956,548,219,275,511,358,179,987,580,394,253,601,647,108,202,237,590,23,462,39,384,203,33,93,514,928,297,905,637,312,345,751,382,959,692,285,867,734,51,473,809,987,451,898,986,863,554,291,481,931,514,608,403,167,692,109,926,777,873,853,2,22,855,479,775,547,816,810,348,297,747,702,11,666,457,194,316,174,183,39,144,350,505,549,28,879,748,511,554,585,849,723,438,557,695,861,696,361,44,638,458,736,873,283,124,926,825,135,731,402,481,881,903,459,571,270,95,610,589,444,304,877,567,72,262,879,391,826,56,943,125,743,140,218,159,397,978,397,159,631,680,907,102,546,840,591,856,411,747,33,455,470,612,430,9,783,689,470,155,764,805,177,394,173,667,836,815,766,603,571,102,652,501,338,204,353,588,487,926,513,610", "21,687,753,19,44,11,258,548,830,607,83,52,570,521,514,65,186,493,440,703,830,141,710,856,623,957,409,915,296,772,747,977,528,676,927,876,698,887,320,818,292,575,182,68,91,114,128,634,346,502,203,78,771,914,643,485,965,220,348,962,383,546,640,531,118,598,520,131,655,820,7,752,981,149,870,218,726,553,673,696,882,671,338,818,656,304,230,44,753,918,249,703,562,322,434,759,345,598,193,335,170,680,741,117,867,451,299,49,125,435,491,826,405,474,404,177,908,136,153,17,745,862,202,782,174,955,906,27,373,900,46,536,365,813,414,444,128,377,681,12,825,259,321,123,544,22,817,676,968,646,58,878,893,541,290,161,285,182,541,512,437,282,886,488,473,773,328,746,883,850,74,417,447,515,412,783,270,154,44,640,518,90,560,323,543,885,478,809,246,563,368,483,137,816,397,793,60,293,797,441,871,914,296,278,40,116,732,522,589,889,749,606,747,480,523,984,627,383,87,718,635,688,294,771,165,985,383,839,797,640,282,241,628,666,90,628,577,109,45,350,109,262,662,583,78,6,707,151,493,381,732,259,99,292,538,398,717,101,792,164,410,976,597,693,745,835,284,669,249,585,764,307,865,529,445,565,536,571,731,808,665,5,884,964,33,670,701,704,200,795,588,989,607,13,531,982,509,278,263,642,711,933,696,792,696,622,183,358,374,372,553,959,183,37,19,126,90,936,715,93,669,373,297,537,792,603,821,799,46,797,490,156,147,833,244,414,658,157,358,274,449,543,967,151,379,96,735,159,274,116,219,819,243,842,255,835,756,690,557,781,619,219,164,412,369,787,397,890,200,67,109,260,870,998,551,141,878,789,27,613,263,718,195,173,610,97,237,331,490,64,617,151,560,695,2,209,103,882,261,468,838,512,84,438,799,977,812,477,927,495,362,215,861,899,786,35,957,443,602,268,29,826,831,685,987,170,188,555,811,532,300,42,795,814,184,434,327,484,44,704,108,577,512,828,783,707,541,725,279,902,270,600,990,950,742,510,482,379,519,432,577,365,633,811,501,39,599,161,829,921,604,369,227,163,692,555,549,756,727,157,619,133,333,300,371,126,87,732,111,986,345,953,936,995,245,70,693,546,368,729,644,632,951,622,582,116,939,527,208,806,917,555,644,469,178,671,135,374,499,414,937,304,769,322,214,184,798,430,269,752,790,502,275,470,581,930,677,719,830,62,699,69,607,227,778,832,509,477,99,171,16,898,775,474,520,127,598,85,880,623,284,792,716,798,952,319,528,339,906,249,62,881,822,940,576,187,304,47,909,99,146,915,544,793,515,104,990,817,825,888,995,788,59,597,172,0,696,466,730,353,861,206,604,257,902,19,490,35,188,581,881,894,151,490,181,314,562,860,211,474,205,115,393,530,674,796,304,731,506,309,347,540,608,332,782,789,246,256,63,680,493,745,126,291,709,360,124,29,416,966,746,736,26,332,526,84,5,111,618,412,4,120,949,531,179,331,427,915,901,443,320,490,911,91,586,405,352,150,670,107,509,789,756,293,901,67,890,408,578,26,945,916,775,928,341,275,868,894,351,527,622,997,82,715,757,659,811,113,173,936,987,227,246,854,557,756,600,14,741,845,104,450,371,868,243,738,517,510,259,508,273,52,840,226,554,154,537,551,801,965,687,385,760,865,833,420,904,85,363,270,418,241,189,899,82,207,546,633,961,829,65,474,818,593,998,784,636,314,537,842,479,673,83,408,398,470,356,754,242,398,589,311,271,83,565,635,660,847,205,176,210,583,387,716,29,898,859,794,533,304,846,372,130,856,78,64,661,940,496,294,496,493,207,16,873,744,555,791,999,676,170,988,124,327,805,345,889,348,12,488,562,695,185,955,212,12,369,246,952,349,726,452,863,566,366,109,339,361,57,177,951,975,526,189,744,614,16,877,475,53,317,490,151,387,746,365,614,306,645,789,810,925,482,444,446,783,587,559,497,491,639,482,445,124,561,832,515,81,478,846,166,786,409,230,566,345,160,727,109,501,231,181,526,696,446,920,163,909,350,696,804,417,994,720,636,864,443,116,59,306,465,803,141,511,815,861,59,361,664,182,957,473,440,9,741,123,865,826,777,226,562,475,494,721,10,477,652,329,855,460,366,270,327,64,676,191,109,740,164,539,340,357,738,539,865,350,740,58,671,367,814,24,864,7,631,298,564,746,440,801,506,108,368,711,594,88,658,880,923,690,972,410,114,500,461,538,617,839,758,727", "620,681,83,933,731,383,144,290,339,104,236,324,141,785,377,339,871,425,137,276,856,247,39,275,651,512,492,839,888,474,98,999,811,647,398,245,86,452,677,14,959,576,151,83,784,487,185,88,82,363,523,285,169,137,275,458,261,436,475,766,255,366,763,684,194,642,896,939,715,468,683,709,531,692,602,675,486,184,889,419,624,2,555,72,700,30,878,977,975,390,42,587,488,337,584,695,64,82,439,297,237,795,272,216,889,821,69,893,203,735,801,107,702,916,717,159,817,776,86,545,99,947,343,980,972,616,440,312,545,852,775,329,640,978,918,585,493,356,864,763,634,759,412,335,631,597,400,855,395,907,216,949,358,864,489,524,684,969,237,411,143,780,346,395,879,405,12,202,134,879,542,722,976,100,616,640,379,947,964,799,889,401,330,740,69,151,550,822,230,999,247,20,256,637,593,641,951,236,693,669,915,818,494,212,777,148,470,863,305,31,967,932,7,394,648,104,343,279,413,801,829,941,578,816,99,198,161,485,757,569,764,199,880,930,985,470,867,825,937,591,276,438,145,172,898,202,926,300,294,907,947,573,455,461,449,314,629,242,685,266,493,669,647,416,985,636,428,351,859,581,37,957,399,585,822,796,710,576,933,930,424,974,626,741,203,284,893,764,355,56,797,34,725,350,3,626,227,809,917,914,590,165,41,460,289,658,766,823,861,418,327,81,10,789,224,810,112,212,582,422,839,562,405,337,11,516,778,585,907,684,672,184,229,252,690,727,886,551,114,986,514,143,63,679,176,464,884,23,974,283,255,33,421,498,779,687,399,285,636,995,109,664,356,548,856,229,740,328,385,680,713,730,763,818,412,387,48,299,284,942,636,561,250,777,29,257,602,530,502,145,529,656,329,503,657,356,20,863,286,740,955,609,323,926,358,123,883,397,822,714,248,731,375,89,890,556,564,119,475,244,124,92,659,547,969,452,983,582,909,631,854,554,153,591,909,490,826,295,893,38,414,468,384,2,757,877,555,340,771,342,957,522,223,296,428,242,809,631,931,526,863,844,482,639,791,462,88,553,178,653,530,8,961,555,587,634,577,744,230,161,806,795,657,603,133,760,778,208,644,783,753,884,25,316,618,427,142,241,132,773,129,451,343,534,186,751,238,981,161,131,449,130,828,851,301,664,869,658,820,445,194,377,286,230,474,143,767,202,551,509,305,841,682,375,168,292,528,954,154,34,658,720,193,47,568,405,553,662,553,588,655,822,200,210,149,281,94,289,176,327,395,685,503,182,245,228,124,167,645,336,120,206,933,725,640,203,293,263,868,751,992,885,443,567,346,132,550,684,799,832,485,454,94,504,837,696,0,660,886,754,210,560,909,422,525,306,528,980,657,288,31,774,535,799,504,808,741,496,839,204,546,277,557,564,912,259,206,318,253,896,695,236,846,41,70,414,142,343,735,831,966,602,477,881,865,761,595,769,868,346,438,829,172,173,967,472,296,36,151,443,653,239,702,557,113,19,595,452,689,167,848,685,327,613,870,252,924,188,119,267,261,310,341,393,963,401,781,650,235,624,766,669,531,585,702,523,370,44,846,666,944,516,560,208,790,450,527,370,882,160,356,1000,746,598,902,430,773,263,620,577,786,685,154,322,793,49,197,671,751,375,874,864,199,972,200,320,540,130,760,45,375,557,233,63,650,538,457,579,377,920,567,207,359,791,899,994,567,905,864,32,527,219,722,975,346,917,653,229,150,857,537,219,592,905,749,423,29,556,806,680,169,53,554,402,57,644,130,46,551,360,825,911,514,978,61,332,801,968,121,407,62,355,247,134,421,166,189,300,514,116,655,967,672,338,478,442,426,499,124,606,597,153,20,278,782,473,337,583,968,257,582,437,785,698,7,736,912,957,106,462,513,698,888,3,555,579,775,974,750,777,911,151,713,216,321,439,68,404,156,587,733,866,934,788,316,589,417,789,177,22,557,251,357,679,114,911,381,401,402,205,407,961,487,625,55,737,119,367,938,8,643,191,628,309,644,52,688,313,618,252,653,290,588,325,465,985,311,918,148,972,870,992,127,359,5,903,765,163,443,680,178,882,280,533,364,340,848,629,310,123,458,409,914,788,31,198,456,849,748,657,703,578,379,25,277,57,281,979,182,400,573,242,309,639,365,860,526,150,247,694,195,378,717,784,106,622,777,635,842,475,205,568,258,436,26,979,860,845,205,356,542,707,218,502,32,9,38,869,569,458,449,315,768,924,831,36,116,25,218,756", "89,883,245,650,780,482,518,458,453,109,868,884,53,376,364,430,218,713,894,686,201,352,584,981,635,854,252,794,438,690,470,941,122,50,710,310,862,667,307,873,991,398,531,404,830,655,287,86,233,230,425,759,749,181,111,253,968,167,515,409,101,225,206,45,391,483,149,277,38,433,24,931,39,687,742,187,58,23,409,502,201,738,337,735,868,213,356,248,442,200,294,618,428,967,981,364,301,419,392,166,690,309,530,58,346,85,513,60,105,533,783,471,304,843,783,459,675,726,612,847,492,404,955,724,421,545,417,260,317,140,774,619,150,150,246,716,161,105,284,431,380,869,545,788,76,296,426,392,679,351,458,65,888,215,27,843,640,54,976,464,767,419,558,19,330,247,968,200,408,710,627,239,968,888,164,725,724,132,361,372,280,350,958,470,537,6,902,34,483,200,504,407,313,638,771,202,961,980,854,915,869,707,224,471,456,990,451,562,993,803,39,575,413,595,691,654,787,775,323,787,392,129,983,876,289,7,407,518,184,622,87,209,541,135,36,538,580,411,153,161,897,17,572,565,420,932,295,624,703,242,791,301,31,699,564,689,326,437,392,539,542,286,800,484,488,236,621,114,313,976,648,529,864,864,79,24,163,630,762,803,869,132,487,880,634,782,443,433,30,358,743,170,288,672,818,578,457,451,327,79,281,562,768,611,644,411,849,330,405,845,306,421,856,457,173,441,62,181,244,366,322,445,555,349,681,610,830,908,498,304,685,803,995,449,722,153,730,612,74,297,937,689,913,556,13,108,81,283,433,655,327,356,766,828,744,583,443,987,729,36,419,287,643,149,88,146,923,544,996,654,765,497,725,950,286,274,307,334,543,5,382,81,846,48,835,101,665,106,35,204,103,384,985,584,16,291,212,575,986,273,672,375,801,594,296,288,530,672,397,312,236,741,470,190,741,701,747,908,127,823,255,336,646,410,770,290,185,500,130,595,158,755,663,251,925,920,180,338,481,602,897,730,939,547,89,767,797,835,712,969,344,19,627,293,493,509,964,414,620,838,315,114,763,30,562,206,779,74,7,825,771,367,168,785,807,286,980,145,183,366,411,801,754,436,590,538,538,565,551,618,474,616,659,23,827,955,491,33,508,262,127,606,633,887,288,507,103,628,731,585,682,229,756,461,526,850,236,351,238,705,285,354,260,682,798,241,171,64,132,911,921,623,708,765,608,305,266,183,593,229,556,83,138,398,949,64,426,541,212,308,294,284,173,232,446,945,941,779,512,229,390,792,351,568,833,271,693,166,671,847,948,214,76,697,619,204,795,223,695,701,265,46,174,240,946,167,608,699,860,16,604,988,894,7,804,466,660,0,453,687,537,577,723,421,675,87,770,60,981,806,239,158,685,380,515,450,781,608,896,311,988,91,685,70,791,906,130,981,688,522,808,909,722,16,808,650,789,83,356,266,534,157,406,325,755,72,155,609,13,703,27,832,474,464,91,604,860,661,62,153,674,229,962,281,710,123,512,352,241,647,516,721,456,556,156,351,253,873,519,802,711,750,248,144,394,172,277,331,280,347,125,627,958,217,988,151,512,234,936,504,833,289,72,835,436,806,674,479,531,367,574,191,970,308,94,36,8,393,180,736,814,218,999,231,100,554,753,15,43,419,165,277,958,239,309,668,918,278,291,683,353,701,471,51,158,389,856,493,607,87,944,882,849,599,438,544,303,274,78,940,147,245,863,627,484,626,868,442,830,798,96,603,501,677,660,680,963,786,662,278,494,650,278,466,329,432,708,484,533,549,492,377,391,220,757,249,95,865,131,698,591,300,962,424,84,964,199,701,313,330,944,287,380,427,410,879,675,872,605,779,580,663,571,475,626,985,356,531,413,563,942,825,455,897,472,157,637,249,531,862,207,511,608,837,110,83,667,140,914,135,271,282,231,92,628,30,552,165,620,1000,355,42,696,783,198,395,211,213,906,40,234,915,444,217,650,122,165,968,281,244,979,967,569,768,224,668,746,237,965,911,428,336,886,596,89,887,530,906,811,527,470,774,70,528,268,873,377,435,596,120,389,592,746,315,702,391,997,638,791,646,132,257,218,69,416,906,501,789,517,948,723,140,321,758,758,257,13,573,946,664,293,263,183,645,594,219,615,772,825,566,381,195,945,551,877,576,717,339,821,661,919,120,678,635,709,68,291,661,523,840,555,734,681,454,135,513,596,32,963,735,11,712,673,528,777,571,868,253,928,211,238,112,654,312,986,833,670,831,924,647", "319,888,967,97,416,235,979,762,510,824,375,702,681,694,212,420,939,923,405,588,401,118,174,403,385,819,300,280,760,583,56,153,635,762,28,696,962,389,630,371,253,429,290,604,45,584,223,906,73,211,431,873,31,690,520,31,53,474,617,355,195,179,833,196,27,190,120,834,525,765,334,599,101,678,683,89,33,420,824,408,850,333,293,938,104,361,515,343,645,214,9,84,409,304,46,874,67,389,920,781,454,996,414,195,550,162,47,473,72,852,990,614,888,220,255,989,665,138,157,220,70,592,254,167,165,284,595,348,994,937,998,743,395,199,698,34,517,344,182,640,61,259,826,721,91,453,230,450,447,737,87,1000,905,19,552,8,752,352,163,890,861,860,984,615,629,156,684,323,544,694,1000,670,965,110,913,133,610,246,410,119,462,13,716,369,609,194,202,910,182,786,548,462,756,19,497,711,341,923,59,925,221,870,701,526,763,224,43,485,100,688,635,500,414,913,365,467,911,12,660,968,57,617,572,427,382,61,407,160,268,821,304,763,507,372,876,913,188,507,211,406,932,470,444,776,290,649,773,979,730,312,454,49,384,284,269,160,234,687,408,594,183,343,422,572,835,840,84,465,920,64,966,289,492,470,870,835,765,625,698,856,440,185,795,519,62,119,9,265,592,489,364,199,604,441,576,424,468,736,757,218,801,271,295,98,574,180,394,272,147,176,719,391,458,330,900,802,927,388,634,927,535,138,465,785,698,985,400,956,940,129,99,99,405,18,638,265,374,354,154,187,349,547,927,596,405,119,939,221,861,4,464,839,78,439,772,623,326,25,7,296,202,238,910,451,884,266,79,992,319,99,530,583,115,156,106,290,912,101,370,178,295,469,619,606,503,995,392,716,782,675,165,669,499,966,360,101,381,403,6,444,553,655,404,726,135,7,689,17,806,270,749,469,578,593,292,536,874,463,825,735,227,277,335,335,113,678,667,486,560,308,12,494,264,26,588,987,598,424,355,974,514,673,652,682,683,243,680,889,62,611,127,518,827,681,530,8,70,419,411,791,955,35,82,787,41,274,602,451,817,591,49,92,908,969,661,299,478,296,248,805,156,673,624,863,906,192,766,561,805,365,554,983,474,502,296,880,237,621,813,392,414,964,332,70,918,103,373,355,135,995,475,566,874,318,993,67,869,480,814,647,553,935,924,599,777,445,839,586,780,628,749,483,351,355,34,710,441,90,406,200,710,49,719,210,674,130,640,901,289,782,551,352,137,988,989,805,626,691,819,48,717,976,54,312,869,114,693,975,997,386,702,160,4,967,503,226,272,397,840,453,817,929,66,904,378,67,226,958,605,946,67,462,836,641,582,730,886,453,0,30,645,452,144,695,182,368,42,13,572,393,742,284,837,146,206,308,329,60,355,815,512,718,790,852,130,386,492,795,73,361,619,949,448,422,133,593,322,161,265,580,571,965,882,490,829,731,966,439,725,371,327,486,803,153,919,991,502,438,656,75,929,4,253,718,103,624,810,7,802,343,289,961,285,560,79,959,543,758,181,385,132,797,225,53,51,976,593,791,525,342,283,633,553,898,833,749,194,149,401,131,935,744,150,474,447,53,525,439,112,820,121,815,553,50,698,492,736,499,440,391,243,851,779,712,447,516,924,865,630,350,375,959,641,454,56,228,356,190,45,242,874,672,296,940,170,926,713,116,630,92,866,885,122,883,655,150,810,795,378,988,40,92,995,189,478,408,508,497,677,571,303,866,687,219,527,951,475,915,125,242,909,112,992,604,613,571,901,922,396,150,542,406,844,40,87,246,586,854,407,561,200,853,207,665,468,219,321,730,652,909,921,28,144,522,86,931,756,714,449,484,823,496,974,122,986,753,545,41,725,425,427,143,216,366,661,981,347,431,972,165,106,790,914,783,72,889,705,413,493,922,142,845,950,297,65,685,55,80,337,489,90,129,647,676,942,590,977,290,637,925,769,164,205,414,643,634,737,306,331,558,786,64,444,325,63,514,114,809,668,90,343,589,666,564,941,865,948,889,153,742,965,535,1000,822,344,217,630,271,131,653,345,519,339,286,237,871,442,395,212,34,961,830,821,963,667,569,602,103,885,36,460,197,347,992,489,430,701,9,955,492,61,177,896,665,907,441,708,967,617,962,377,955,669,790,579,169,397,365,314,291,383,471,942,547,47,307,778,594,760,47,681,517,652,485,927,445,852,934,303,545,467,996,128,708,515,557,767,843,807,928,275,724,109,255,119,159,474,185,853,292", "557,13,253,166,806,373,486,361,86,523,52,264,855,912,820,553,80,568,87,71,356,203,529,470,680,167,205,819,860,802,829,420,617,312,540,405,254,980,469,319,865,34,424,359,714,174,21,908,510,56,661,839,115,964,688,340,836,801,187,200,363,669,542,537,517,827,576,526,145,447,396,81,270,452,776,838,67,358,62,822,739,770,317,818,336,427,990,879,914,653,90,728,993,130,709,848,270,38,357,232,320,518,798,483,652,33,898,181,540,256,707,758,454,952,467,252,529,512,741,996,612,339,212,619,485,10,998,978,484,842,238,312,712,830,804,953,357,469,345,956,438,628,83,35,651,56,981,90,775,185,441,290,886,150,362,880,768,34,509,377,91,892,66,246,947,387,933,675,466,114,979,863,240,876,119,711,381,678,339,798,773,32,28,951,146,286,467,230,22,931,791,960,221,842,511,168,581,534,497,256,536,441,80,57,160,911,361,992,624,176,333,603,924,48,526,352,549,228,154,213,342,981,31,84,846,406,3,457,971,833,84,572,885,835,893,16,870,180,675,885,777,502,872,497,280,308,428,752,145,433,862,818,149,216,438,693,389,194,227,659,800,452,873,175,656,814,481,911,863,601,579,698,140,957,316,274,917,304,204,710,637,762,843,309,93,15,382,52,339,779,724,443,38,577,258,178,323,862,95,638,258,412,924,955,677,690,395,392,66,32,636,161,159,234,602,80,386,649,894,788,328,611,65,683,330,613,524,571,458,350,423,736,977,890,390,513,312,31,91,8,548,372,81,755,129,631,651,489,987,362,616,105,13,549,97,398,477,827,976,762,889,410,526,408,534,143,724,251,271,895,858,20,749,857,531,246,288,522,72,346,394,586,660,146,200,37,309,387,787,39,53,933,276,101,438,664,672,448,599,131,661,692,41,481,761,552,251,125,89,85,589,591,136,138,364,824,42,718,655,61,624,998,980,956,313,277,596,122,629,538,953,769,902,937,146,236,841,433,359,708,76,895,179,293,881,155,913,143,952,141,729,177,893,417,764,534,340,173,638,681,819,767,677,674,396,186,611,665,453,985,638,348,973,525,252,163,537,373,752,210,584,524,820,429,75,810,917,141,155,292,993,125,706,334,447,604,673,96,569,337,42,650,524,826,384,862,129,678,851,702,536,359,66,181,225,922,916,413,620,465,700,944,368,134,903,262,422,799,33,697,658,80,672,329,626,722,328,110,62,875,74,246,992,531,45,989,380,254,779,633,130,943,390,999,524,251,56,902,424,464,850,920,176,938,896,524,24,272,762,866,943,995,622,772,125,752,319,986,686,402,632,420,782,905,511,788,750,510,455,615,769,186,260,722,595,353,754,687,30,0,790,62,966,786,136,278,343,629,778,861,844,915,460,459,844,929,925,341,655,977,110,639,724,665,761,342,41,496,111,739,990,747,682,670,308,749,385,828,368,208,796,983,859,340,533,900,718,235,132,219,753,555,50,560,663,129,125,611,959,258,230,571,692,291,654,140,7,733,173,934,252,814,815,857,999,446,112,161,228,640,340,916,119,371,708,70,956,568,322,614,813,913,204,530,585,684,679,792,825,401,525,209,606,7,735,302,454,75,453,330,669,896,109,261,409,883,260,678,298,243,379,333,532,291,520,565,512,562,393,678,973,719,517,391,596,990,478,323,738,904,280,141,748,571,881,747,204,969,886,805,937,685,522,9,687,949,191,1000,785,430,718,820,994,44,344,267,381,455,910,735,791,233,673,553,914,877,865,616,867,331,487,177,933,479,662,877,61,347,318,17,105,794,411,38,230,469,390,313,468,8,260,98,392,684,393,17,369,34,493,627,383,553,859,116,371,280,690,528,149,93,495,686,899,99,281,966,785,121,742,776,217,783,281,5,467,10,620,21,388,76,518,983,134,426,842,899,531,856,775,881,268,37,643,826,199,25,476,666,870,695,929,686,921,812,851,934,599,559,230,99,294,971,29,864,947,828,747,304,177,95,63,693,508,539,940,572,824,666,462,361,229,107,247,405,235,632,151,470,790,67,826,382,571,359,232,514,177,558,483,837,380,407,87,817,165,717,611,819,54,3,909,903,248,869,859,292,821,852,307,481,36,405,632,597,796,22,485,488,799,597,5,919,536,296,286,665,877,656,975,611,88,484,604,596,4,25,630,104,410,432,861,659,62,232,739,451,650,701,108,554,317,242,428,71,207,99,469,957,800,76,919,652,468,764,398,646,382,198,959,17,176,476,237,550,798,179,766,843,331,300", "602,931,563,439,885,648,159,102,936,462,19,995,506,179,530,219,64,946,5,402,546,364,855,250,128,894,729,927,264,290,957,203,274,233,812,359,846,84,404,348,877,661,700,699,563,802,652,151,378,966,854,321,510,928,275,918,172,902,453,462,900,268,467,295,375,224,791,238,955,267,946,514,425,591,528,581,856,877,418,359,570,623,413,46,930,991,589,558,939,931,827,304,281,413,441,81,220,118,681,801,939,643,288,51,517,269,965,56,372,861,329,156,588,227,993,700,755,274,335,74,645,787,470,44,269,602,496,944,554,629,822,981,116,474,966,80,925,264,723,403,717,644,880,606,29,727,561,491,572,340,570,747,912,366,502,943,977,384,917,923,551,715,407,20,54,817,427,37,76,241,604,55,634,15,584,174,699,309,943,457,179,700,565,585,462,604,121,182,198,862,674,69,915,948,197,766,84,649,112,850,399,506,70,110,650,774,638,792,260,186,693,920,377,476,511,432,820,613,791,16,427,818,106,239,339,566,70,861,232,2,203,89,83,302,162,939,549,243,323,134,770,659,9,235,313,676,245,708,162,965,854,524,572,981,55,196,686,203,831,657,870,147,172,971,187,234,570,302,383,848,825,776,678,912,452,337,766,618,306,572,825,335,829,133,542,226,802,647,559,283,405,165,615,48,508,851,885,570,177,493,872,205,574,514,523,395,150,272,799,800,503,132,678,715,500,850,999,741,268,90,19,147,321,754,715,630,676,269,223,658,711,594,974,671,855,851,856,419,677,587,319,110,21,197,19,69,577,262,196,349,867,208,768,347,911,640,147,616,73,513,429,18,640,443,504,145,559,126,123,162,730,80,913,510,222,162,401,735,726,510,20,168,597,3,743,507,621,526,844,392,856,285,747,981,718,330,666,316,859,681,159,225,63,917,928,799,107,821,477,111,21,805,357,457,840,697,167,403,89,825,332,744,221,927,767,4,257,423,722,428,36,400,590,272,274,678,4,734,57,668,47,908,151,343,338,524,997,409,356,789,104,72,191,186,171,290,93,751,344,682,54,882,759,449,164,225,746,906,286,81,766,419,786,270,63,998,963,238,768,634,630,298,494,606,605,470,70,544,230,381,529,726,473,568,852,349,907,792,103,487,763,178,949,933,768,745,612,294,56,334,788,929,18,177,708,769,92,14,255,301,435,369,185,44,758,587,621,717,839,783,865,71,893,696,143,934,941,49,617,779,810,147,779,95,634,880,738,292,16,122,31,775,749,734,909,846,971,891,483,841,83,171,70,446,622,124,566,175,553,278,471,433,36,811,248,154,846,223,628,817,436,776,591,200,883,978,978,361,544,882,716,247,435,567,472,861,210,537,645,790,0,205,811,100,263,280,835,547,744,438,336,410,467,534,908,662,974,824,524,691,758,697,303,276,545,193,707,37,732,51,976,251,150,745,859,764,918,396,394,426,502,342,143,796,408,738,275,288,397,733,579,339,457,483,397,253,75,735,147,960,808,31,94,464,421,754,300,590,536,788,764,786,842,671,543,459,139,816,906,214,503,872,826,249,703,342,100,427,439,24,792,683,81,131,261,525,707,215,247,468,516,219,108,13,979,886,387,563,81,850,317,666,899,693,205,450,488,463,322,759,599,230,994,196,495,724,377,992,492,450,489,623,45,324,987,331,721,716,232,859,237,172,838,77,975,61,960,82,795,402,225,857,609,153,739,589,473,83,242,442,27,461,779,609,156,793,118,277,410,935,483,985,970,646,653,282,20,107,43,497,476,10,870,354,157,435,69,146,426,101,791,478,383,460,146,408,880,168,834,343,248,986,421,574,719,420,998,944,956,49,588,282,468,946,787,391,218,86,306,248,168,895,968,776,582,398,444,798,36,771,489,767,930,575,228,143,731,992,678,1000,380,14,901,286,103,577,690,420,771,754,202,865,602,996,61,355,152,929,227,555,535,925,397,242,13,715,901,115,102,138,940,388,997,552,586,923,36,929,491,785,974,607,131,92,990,650,664,919,887,187,856,480,705,856,629,619,973,526,455,813,867,530,993,517,7,465,743,484,111,384,765,858,890,953,307,725,396,605,533,919,153,54,727,63,731,290,134,851,474,82,896,453,553,224,265,311,193,660,313,323,906,529,821,470,127,949,318,308,743,441,322,631,124,437,537,425,18,128,508,391,812,545,96,264,431,684,81,747,60,929,772,938,385,11,387,34,89,109,630,674,692,611,176,169,646,910,633,630,603,844,658,581,177,411,801,163,266,150,53,637", "206,804,736,746,332,206,89,840,575,792,495,898,410,624,428,722,193,776,888,836,127,424,990,869,34,215,341,343,889,49,678,192,742,777,589,871,92,799,240,421,898,756,116,603,664,543,174,19,917,319,961,619,802,824,588,415,376,233,484,947,235,479,278,641,461,273,392,568,43,203,798,920,710,174,349,512,558,513,352,471,873,951,658,321,925,583,22,989,562,520,388,230,747,400,843,338,475,776,199,991,281,498,965,886,141,473,310,996,105,555,249,600,556,518,461,590,623,807,959,283,585,526,28,676,114,820,275,718,12,826,943,642,572,446,948,300,700,310,856,656,897,57,70,103,21,87,157,438,616,152,78,921,881,222,487,246,56,705,539,823,5,159,754,423,56,708,845,917,364,243,227,812,422,682,887,423,592,357,365,867,755,521,363,61,788,150,316,928,292,51,199,22,392,904,544,823,266,135,397,721,416,777,618,940,598,73,142,778,317,565,85,445,979,233,843,266,846,332,817,399,306,505,287,481,787,543,647,592,67,66,936,15,282,909,176,38,253,45,631,707,700,21,392,776,882,200,91,392,807,792,997,55,4,944,653,491,628,411,451,458,10,391,420,894,595,915,335,32,577,280,257,66,722,39,221,856,318,13,370,717,477,575,189,687,50,148,631,545,748,321,814,778,61,647,741,417,571,865,691,556,381,393,317,617,672,256,517,821,646,45,701,520,598,456,911,941,515,281,269,602,334,138,90,716,962,418,718,82,530,442,754,512,680,665,666,125,378,21,596,348,97,772,350,391,326,708,634,122,899,277,425,293,885,227,149,155,126,685,573,746,235,772,659,703,573,883,534,190,964,274,29,634,480,137,639,799,748,35,278,460,672,773,603,731,51,389,199,685,949,188,26,603,4,944,828,271,454,715,424,558,504,742,208,785,970,611,313,169,175,837,767,52,776,359,201,754,145,704,496,242,252,212,548,145,524,401,234,912,995,186,100,596,178,905,604,956,20,738,398,419,90,424,932,593,242,807,283,269,690,88,968,851,36,966,744,909,34,167,355,879,640,370,147,721,202,124,224,376,505,569,148,593,621,582,810,405,596,493,448,198,401,132,460,171,754,581,893,964,54,931,917,184,678,597,914,788,865,151,379,692,547,73,416,426,722,408,751,904,596,596,982,515,64,587,381,718,196,829,26,283,460,249,243,828,567,240,434,435,127,419,556,772,397,241,8,17,310,98,405,978,829,145,980,852,660,984,523,755,86,515,533,193,491,134,242,886,44,434,506,563,808,125,584,778,349,374,148,964,531,265,878,891,124,314,674,773,163,274,808,13,22,780,495,273,816,193,864,60,459,542,464,131,466,373,837,206,560,577,452,62,205,0,441,217,98,295,178,986,709,755,837,736,521,888,313,912,367,672,261,366,237,513,918,466,376,103,856,116,974,676,690,617,948,527,853,341,877,444,231,572,414,457,308,287,394,943,943,70,811,449,654,990,779,119,327,195,362,247,881,866,452,576,360,778,306,413,22,23,753,758,3,501,609,346,984,413,635,58,389,688,216,414,713,796,996,117,510,975,442,646,792,485,297,49,43,990,519,637,66,253,207,502,366,918,464,600,979,245,599,845,567,775,375,128,340,54,475,105,34,405,526,392,456,568,400,328,735,673,522,110,275,142,411,604,594,26,940,188,517,993,942,40,853,134,856,147,120,6,631,469,515,616,831,103,138,138,771,166,84,243,912,140,266,927,139,621,28,868,454,186,499,784,909,82,454,879,771,701,260,814,595,857,717,970,727,710,689,136,808,255,400,825,144,232,302,209,369,417,571,707,898,836,244,675,582,804,909,283,914,407,510,62,170,705,117,948,891,544,643,814,733,56,3,492,664,798,129,662,602,124,487,617,857,271,773,50,859,346,415,77,626,406,818,725,174,737,302,95,721,16,432,974,306,744,268,745,950,287,695,218,919,16,543,526,330,148,892,991,217,215,210,734,666,604,380,186,692,68,789,569,991,725,253,829,882,595,173,333,537,918,11,406,128,336,18,505,272,210,37,161,419,822,470,171,223,362,361,451,975,759,626,235,825,190,657,359,125,757,625,738,450,811,208,50,283,255,454,398,374,520,233,660,732,9,792,140,470,145,312,28,649,668,928,499,700,596,108,149,805,481,535,97,427,270,425,624,937,84,879,879,628,596,360,453,870,971,826,428,976,602,11,44,773,648,616,674,654,943,471,898,741,656,382,199,871,820,280,445,185,625,939,184,973,922,309,286,642,909,151,299", "759,158,880,837,663,249,91,516,882,39,503,149,781,802,632,125,554,602,630,374,483,151,665,161,806,527,663,172,384,558,76,820,306,858,532,853,542,406,844,398,162,890,410,991,277,178,69,480,67,35,639,294,761,262,223,381,808,145,838,678,549,230,231,425,527,897,81,629,783,404,667,708,826,890,622,941,30,219,669,950,302,677,273,574,571,831,318,263,700,222,567,995,713,836,565,245,495,442,821,992,954,73,987,642,850,309,918,792,286,299,54,765,346,183,23,746,824,470,126,78,270,854,73,202,751,894,802,599,821,151,602,676,127,598,341,847,58,339,479,413,985,110,828,62,801,622,343,260,301,913,592,59,87,918,242,739,845,478,448,616,829,655,345,282,785,804,619,462,23,321,547,317,320,428,321,861,681,74,938,672,997,421,712,852,591,400,333,636,841,46,515,443,658,345,766,510,417,770,415,164,366,113,633,922,919,609,910,152,493,448,566,136,618,623,933,541,53,170,86,204,379,768,869,527,356,281,194,11,773,446,869,491,197,886,867,18,260,52,880,209,118,141,374,233,579,707,928,102,104,95,184,381,853,944,702,751,680,529,622,217,71,960,65,506,899,702,751,800,730,653,603,807,343,359,126,118,326,157,158,114,691,551,180,502,305,63,70,227,243,520,362,45,113,754,796,403,892,425,904,542,982,927,281,122,857,436,823,316,20,998,561,263,597,961,723,28,513,194,122,48,795,740,799,229,285,375,636,561,654,941,760,962,851,655,306,457,753,890,963,228,123,31,761,676,920,101,951,372,85,704,56,647,382,964,54,633,861,238,657,484,323,681,221,330,447,166,534,861,276,794,99,65,277,196,897,580,448,276,153,665,402,211,513,798,878,71,647,609,390,268,347,457,390,593,129,381,255,945,814,920,950,107,754,855,537,41,632,531,311,182,354,160,272,261,402,859,975,102,623,45,396,173,895,480,997,54,269,284,102,513,705,566,680,910,819,204,383,913,799,151,622,442,390,384,160,342,154,935,757,808,8,980,423,511,441,430,655,787,910,344,763,526,69,703,476,247,28,559,667,484,302,128,512,554,639,932,521,797,610,262,601,510,764,863,320,389,516,608,525,585,167,322,691,773,468,843,361,414,231,224,873,114,150,670,652,865,255,916,464,678,422,341,586,684,679,861,641,439,480,969,914,818,428,482,501,239,876,874,638,357,335,264,28,37,790,387,253,275,40,579,904,118,332,560,618,622,383,656,229,857,527,20,6,545,984,851,729,609,158,248,444,457,636,425,883,92,425,416,268,493,956,443,648,636,596,162,447,769,340,989,960,735,681,745,922,875,424,965,115,347,878,410,51,745,427,604,909,723,144,966,811,441,0,630,155,683,288,86,30,888,515,160,790,400,701,45,872,594,360,148,72,92,363,988,708,591,136,814,53,926,295,640,730,634,607,374,790,818,434,151,622,122,182,933,812,538,793,203,735,981,368,252,870,326,83,100,741,669,561,788,326,492,958,547,27,356,366,41,633,766,556,835,252,526,452,465,606,169,732,52,584,480,88,883,814,243,636,164,345,598,549,242,46,7,616,304,944,25,178,758,62,674,289,459,377,155,414,555,882,90,225,622,433,849,927,263,219,491,229,287,17,979,365,78,666,896,443,525,513,752,731,498,134,22,628,710,575,372,758,890,71,772,654,424,560,113,920,90,175,772,564,679,771,374,600,431,393,5,77,982,233,574,782,193,182,71,208,488,100,252,881,837,69,913,893,439,511,207,61,610,231,678,989,583,342,58,1000,506,745,638,764,636,631,454,860,682,344,432,51,649,958,354,550,812,493,722,189,906,273,154,503,694,562,331,683,104,646,386,419,102,744,774,732,964,950,184,38,691,583,143,61,765,843,577,628,477,443,418,909,189,262,858,228,164,994,275,540,689,159,22,967,771,838,307,210,912,185,315,280,434,378,914,840,949,46,884,377,535,271,881,773,183,854,556,338,452,353,861,214,483,841,745,572,770,166,198,889,829,888,44,271,135,603,590,537,244,643,919,34,657,534,694,856,630,645,276,511,897,723,797,50,456,589,233,129,454,777,178,356,775,88,292,256,491,487,438,725,999,684,411,176,874,424,354,626,85,251,277,121,749,340,350,856,714,38,43,554,239,322,401,737,77,462,534,386,360,406,462,986,530,257,292,249,986,907,126,848,335,309,667,414,129,213,902,969,49,496,43,563,793,901,26,52,793,80,499,37,654,156,857,330,972,860,570,100,606,171,415,23,87", "638,451,519,697,999,417,168,904,18,937,458,493,464,145,408,239,572,832,135,416,55,709,746,989,148,374,368,191,675,232,648,505,242,434,540,994,600,183,308,13,886,90,162,841,429,778,770,807,257,463,471,462,36,3,311,315,187,109,822,954,524,24,544,570,562,862,640,701,844,468,797,157,627,845,402,17,297,783,971,746,726,887,876,143,518,993,199,105,273,554,490,549,531,248,394,692,515,699,528,491,854,287,124,108,228,559,681,395,276,437,298,777,540,965,957,625,834,52,697,697,255,836,356,484,2,921,756,779,651,642,500,457,384,687,426,452,790,997,872,523,687,476,905,746,726,928,929,959,223,390,840,555,133,543,930,665,187,600,324,342,114,63,750,130,655,780,822,76,895,958,240,626,822,961,15,635,37,72,500,380,187,161,95,707,224,44,854,716,712,330,928,585,613,459,758,111,617,872,481,633,23,192,839,259,724,191,959,884,552,566,14,51,178,619,197,156,300,43,743,460,617,791,476,491,931,791,9,499,951,816,209,773,239,926,102,789,132,247,519,607,648,715,652,748,186,533,452,572,466,80,206,557,697,20,8,53,949,508,359,545,542,587,143,76,848,599,768,801,139,267,890,632,554,533,575,718,822,584,70,969,508,384,583,686,801,358,33,607,573,899,623,345,226,215,553,777,53,913,485,100,892,336,717,325,148,428,548,932,800,27,631,408,347,549,24,664,649,88,244,538,422,440,81,439,249,300,497,106,337,576,556,984,599,529,946,367,431,447,33,76,185,249,185,998,653,30,834,526,658,337,532,519,549,991,500,405,678,577,84,111,953,577,94,420,183,667,928,502,884,841,388,885,313,692,748,62,971,508,97,419,53,676,442,94,892,985,800,926,64,750,81,670,222,305,221,298,440,236,862,184,321,63,335,373,400,655,986,293,973,941,7,828,439,724,991,724,317,468,925,686,372,490,617,333,637,143,913,669,957,820,528,954,343,478,685,384,398,925,801,994,342,642,966,829,384,534,996,878,295,389,289,716,839,347,256,978,693,622,821,500,119,186,29,837,885,112,434,904,303,930,649,449,935,312,758,79,694,86,413,856,916,141,807,99,981,798,77,490,116,605,414,491,588,342,576,315,795,570,146,616,416,232,308,525,886,156,521,889,912,366,369,649,106,131,800,452,489,341,775,724,252,154,982,612,210,68,798,254,402,886,896,347,76,849,847,78,17,856,192,325,376,369,218,94,295,137,987,931,664,878,209,960,691,382,912,573,174,78,324,47,616,361,530,481,217,534,314,599,191,585,576,963,548,922,436,59,8,866,694,398,482,103,389,866,847,852,675,360,696,549,27,799,866,952,742,257,422,421,695,786,100,217,630,0,535,124,768,716,821,265,904,921,5,520,843,911,43,150,919,868,66,990,11,52,343,906,600,758,512,982,875,164,536,151,368,984,980,395,714,625,847,717,58,245,980,270,159,140,432,676,677,543,5,973,334,759,398,399,396,513,587,366,657,34,987,409,650,243,308,272,470,640,548,160,743,743,532,317,216,717,495,690,309,771,255,316,440,398,308,97,891,368,742,192,534,627,889,447,46,151,75,492,434,567,865,963,133,280,669,64,113,359,511,661,370,695,888,25,200,152,536,537,92,383,305,240,2,262,188,998,158,990,25,595,630,31,429,134,243,216,207,588,178,248,922,665,806,622,134,676,952,272,440,568,940,555,888,212,934,553,18,147,941,76,806,687,744,784,644,20,625,296,554,369,729,854,942,809,556,373,764,184,919,400,171,444,621,368,30,362,478,519,90,81,240,880,867,35,623,522,444,74,844,79,75,525,627,289,868,206,737,762,778,944,673,817,874,430,482,250,419,954,797,214,83,398,48,80,885,73,541,211,564,340,806,180,789,618,395,127,489,107,762,55,358,610,870,180,522,117,228,19,760,544,956,807,172,745,669,152,761,162,797,974,104,852,889,998,468,751,45,347,997,748,381,764,164,51,641,601,610,511,436,223,922,256,428,716,488,754,377,811,772,104,811,247,888,938,689,670,875,81,436,694,455,990,915,37,771,720,210,406,242,921,167,89,177,42,325,627,196,816,619,239,881,863,758,516,102,846,507,136,658,15,301,418,341,805,830,859,248,164,653,960,533,670,715,970,57,338,928,867,610,107,705,218,321,791,612,238,708,634,173,867,306,506,636,720,4,58,618,179,909,216,569,949,401,706,328,69,428,439,893,575,604,198,458,179,741,581,24,952,70,224,244,440,132,342,392,517", "977,768,76,444,915,712,178,344,572,991,400,454,463,808,16,953,690,73,813,332,898,888,629,597,243,337,606,881,286,260,627,792,319,337,914,737,95,297,522,235,214,540,42,613,89,811,119,142,733,489,837,97,942,862,307,378,910,229,112,833,259,700,536,677,50,769,90,274,928,327,754,546,12,316,719,290,87,495,49,484,400,346,777,268,335,84,816,189,124,39,559,613,277,462,197,147,640,856,917,547,456,709,912,869,446,940,670,470,169,69,754,312,350,557,859,308,633,469,873,116,769,11,533,751,625,947,213,334,569,940,821,443,636,972,542,403,175,379,283,653,725,841,348,241,400,179,551,483,764,75,600,339,288,958,388,431,452,382,964,266,405,480,508,819,463,547,859,2,104,16,998,174,882,572,54,859,655,555,194,757,962,817,647,355,909,983,597,219,213,431,455,900,609,895,429,701,273,775,825,5,238,798,952,743,927,457,744,939,814,725,912,924,852,10,871,167,323,736,904,422,692,615,964,497,487,529,278,907,72,905,654,969,625,771,449,947,976,879,249,207,102,457,866,55,815,709,276,566,803,532,763,752,199,820,334,969,78,352,93,648,211,652,766,733,712,642,902,690,224,339,610,657,168,530,986,133,360,958,333,550,982,218,993,213,558,13,939,915,645,297,57,766,500,246,410,895,485,668,704,41,128,220,336,104,109,925,264,417,50,294,327,805,606,750,99,939,345,108,327,800,894,725,686,815,222,586,571,263,924,3,817,147,884,784,123,45,703,771,61,641,314,218,288,735,6,423,35,682,106,924,964,886,608,858,456,213,856,784,516,949,476,251,642,860,852,300,913,488,285,276,92,999,812,516,189,521,74,674,348,110,762,285,121,456,112,254,996,371,894,107,111,865,533,871,623,702,96,331,29,621,193,154,785,108,667,133,198,881,168,136,523,266,860,391,659,470,83,735,639,822,704,349,464,635,801,404,303,806,226,380,532,59,565,141,556,403,486,137,819,438,137,199,599,841,416,710,134,485,840,780,248,32,421,198,409,208,764,94,919,921,878,156,736,488,922,260,525,277,153,310,130,700,527,53,690,419,489,888,241,571,401,856,980,286,889,355,46,861,507,342,603,57,768,624,983,759,28,723,29,348,216,187,271,409,551,951,132,128,509,109,400,250,546,159,206,810,141,570,778,742,76,191,362,971,781,794,649,967,26,537,871,191,805,111,267,499,500,649,756,764,831,818,783,918,108,182,179,192,522,56,79,514,893,224,994,264,404,865,475,459,119,833,152,92,606,242,775,824,166,851,399,898,407,396,607,253,988,178,654,920,977,264,59,969,992,479,724,660,20,801,502,226,814,593,788,902,525,675,182,136,263,98,155,535,0,17,367,146,452,937,273,892,300,992,453,591,403,712,799,521,455,753,304,835,986,569,943,358,497,409,96,737,443,993,928,489,268,530,521,103,703,182,364,343,158,291,525,207,385,20,570,670,384,571,177,298,907,803,385,145,389,111,993,517,948,108,310,791,905,12,363,581,735,626,210,346,971,585,106,626,44,37,77,528,539,802,776,370,16,844,616,685,325,623,388,455,236,595,82,199,303,72,925,526,519,380,79,360,689,512,608,300,783,128,605,797,627,349,369,887,392,630,645,132,779,729,588,705,239,539,710,331,470,930,269,893,172,834,28,482,651,954,722,640,490,99,243,560,850,582,618,815,720,686,202,670,159,654,648,445,512,468,561,65,932,683,354,146,932,44,327,33,415,787,266,509,231,42,446,140,915,441,953,504,531,919,232,210,371,496,298,99,563,134,14,309,115,89,801,444,772,931,362,890,239,355,494,452,43,497,627,501,905,767,30,692,92,71,826,96,901,699,176,407,611,289,224,761,327,577,677,48,195,179,87,200,992,879,705,681,119,143,566,474,436,600,215,187,484,911,773,781,265,608,750,77,968,271,365,576,109,872,312,711,283,45,145,125,235,165,757,731,785,608,906,733,762,137,948,768,670,153,488,586,148,988,871,836,444,928,582,515,969,785,407,745,709,248,49,987,545,10,700,516,942,102,125,774,833,849,25,430,646,525,91,178,589,733,955,87,981,366,8,289,773,728,829,940,863,35,245,906,932,38,530,161,119,670,669,477,639,869,471,638,941,516,325,716,180,78,752,724,592,929,305,573,960,413,925,459,45,903,815,123,565,447,561,853,656,780,504,401,291,76,160,260,471,500,25,838,240,339,344,401,191,737,446,259,935,505,189,190,437,636,716,81,196,33,519,677", "499,954,3,208,174,517,429,158,901,103,841,50,979,991,826,777,417,659,389,741,529,267,843,583,714,283,572,68,282,962,82,698,474,34,260,650,463,444,408,330,966,922,622,415,322,925,642,825,359,3,991,296,40,528,3,234,804,607,75,605,835,426,746,194,783,772,722,373,201,509,596,841,332,639,425,220,419,440,378,784,490,493,37,646,227,70,91,752,269,357,481,324,169,818,929,993,400,146,393,660,200,935,555,308,407,658,212,22,787,893,529,926,626,772,697,934,362,651,622,533,870,621,331,10,495,510,375,330,288,479,493,95,275,864,903,159,466,823,443,872,22,25,995,127,27,260,869,107,253,165,616,974,479,492,406,934,32,430,225,852,904,246,90,655,391,287,147,454,106,126,330,382,783,901,342,757,84,559,484,941,725,869,199,601,37,860,165,836,884,276,266,770,885,102,295,654,572,98,210,770,665,641,703,926,525,127,459,821,787,833,712,635,798,122,730,243,48,329,44,581,438,856,591,829,453,634,923,298,979,97,302,691,173,514,507,982,404,805,579,88,294,318,86,63,361,573,758,888,712,329,545,589,296,421,602,330,678,689,92,390,829,227,31,151,547,113,712,993,651,952,549,914,121,461,99,481,492,806,810,308,412,873,699,717,57,858,268,384,739,292,694,349,186,93,629,254,983,523,823,471,929,122,991,259,797,29,96,700,507,326,445,86,732,513,64,103,792,44,351,577,997,122,944,740,279,246,165,370,943,718,858,34,320,773,749,613,757,535,552,60,151,940,152,792,115,108,577,842,964,773,707,774,332,915,759,129,373,517,261,196,268,404,494,60,285,623,404,227,701,390,544,279,154,751,685,169,363,478,665,673,366,6,701,78,166,396,772,262,460,89,265,549,629,992,852,54,912,860,8,436,769,708,878,751,179,509,941,371,142,568,317,310,160,428,695,765,620,614,726,938,834,858,102,666,366,849,118,718,874,917,276,915,996,109,522,754,592,260,366,581,58,907,9,575,108,706,194,983,821,224,289,314,971,882,396,282,745,294,675,770,96,870,149,381,308,770,890,135,936,295,273,247,607,146,48,357,32,688,993,429,608,463,557,226,34,664,756,750,444,91,585,306,84,165,238,464,389,630,489,741,953,220,568,583,763,496,455,682,759,433,830,495,730,30,99,296,157,736,501,99,174,660,537,883,378,451,50,39,316,296,735,303,484,403,813,44,482,587,902,312,716,755,681,202,660,916,673,13,129,462,310,723,132,772,174,303,336,589,655,602,792,517,359,174,689,80,606,206,572,946,984,373,555,982,39,484,495,518,90,708,53,475,388,137,338,727,910,501,135,455,254,371,726,768,381,19,306,87,368,278,280,295,683,124,17,0,563,968,437,128,311,322,374,616,321,791,925,926,126,332,86,805,778,813,135,494,174,53,236,753,758,54,809,879,890,258,58,174,17,170,502,624,169,116,230,793,402,24,580,30,57,130,951,310,901,781,490,514,959,529,831,850,684,882,413,940,488,963,239,328,709,624,677,180,777,400,911,383,62,315,368,614,945,538,143,331,996,20,603,570,191,32,318,502,980,124,572,879,289,382,880,950,441,435,228,697,194,276,898,470,500,122,505,191,7,863,947,686,460,508,305,181,161,179,863,50,186,617,690,816,592,784,649,544,353,841,565,169,716,75,964,431,838,763,798,226,161,71,405,443,720,306,620,358,976,455,119,105,228,497,702,219,692,209,365,758,491,216,634,51,143,388,757,667,40,918,152,383,343,632,513,298,134,217,111,973,914,53,307,978,51,27,687,855,659,607,399,438,936,650,580,443,861,453,740,666,873,465,348,887,672,27,904,236,116,693,419,899,143,940,114,945,102,600,684,695,346,626,23,670,954,728,160,673,410,639,295,981,295,318,11,783,623,173,935,571,288,423,533,471,478,775,540,140,832,648,126,668,143,961,607,180,53,306,464,793,363,880,66,888,329,231,813,489,125,100,851,357,919,743,441,809,568,833,886,909,77,946,988,856,909,767,899,135,955,901,228,121,852,435,413,80,489,544,620,648,629,453,912,235,397,697,963,83,676,884,727,407,400,213,547,190,386,909,719,421,859,635,52,273,957,282,62,651,727,610,125,101,245,701,482,723,611,61,143,477,533,135,333,688,999,153,433,346,113,69,152,407,655,996,415,736,388,436,730,103,877,854,518,584,656,107,496,135,928,39,243,351,102,87,913,889,864,476,908,133,896,693,70,224,154,56,672,774,365,933,155,23,825,498", "723,695,624,346,549,492,621,27,252,134,679,697,729,427,788,569,762,425,990,797,166,429,279,30,788,539,807,578,783,195,654,548,404,635,21,431,516,380,371,402,641,132,557,671,207,457,467,71,110,227,289,121,427,135,261,97,544,852,786,531,961,887,258,658,792,198,9,818,794,951,320,805,199,811,806,558,687,679,554,499,918,735,957,243,178,235,591,190,2,704,280,346,137,491,455,533,931,558,206,132,506,308,237,777,936,830,590,533,584,970,44,984,225,773,613,689,431,674,153,142,520,405,785,508,725,948,437,272,262,912,245,107,369,889,551,908,762,536,183,977,483,44,324,157,39,805,375,792,986,315,269,739,972,899,399,188,546,441,961,422,561,174,839,684,696,137,328,476,719,450,617,249,133,894,482,667,387,25,65,373,488,496,866,752,482,454,473,76,748,566,916,607,358,766,400,603,962,819,677,46,464,510,30,875,555,158,693,213,645,452,631,927,89,458,228,994,274,430,37,461,667,658,573,449,119,850,965,24,765,825,578,626,727,814,65,778,703,663,484,382,812,326,346,729,597,354,128,580,589,159,678,396,31,861,108,497,486,83,522,26,180,869,197,936,277,30,36,293,377,242,106,648,448,204,90,360,122,274,156,667,937,871,349,185,312,369,738,54,813,332,156,869,85,791,701,151,804,320,321,739,686,45,602,436,995,612,781,747,758,847,839,723,947,482,772,654,215,321,317,62,257,463,437,106,302,990,48,456,930,530,295,789,722,700,295,944,735,742,242,883,498,978,532,730,168,113,255,499,1000,58,763,85,550,9,636,639,397,134,241,200,592,64,136,865,224,957,841,528,43,405,259,149,162,959,50,428,860,439,67,889,299,703,915,288,355,88,594,80,827,77,482,381,37,54,478,537,187,587,918,98,235,528,233,336,741,40,306,982,654,377,47,656,368,89,89,550,230,41,451,266,309,665,516,889,195,399,679,524,28,700,59,188,658,574,398,749,287,233,104,804,143,53,483,364,205,716,44,806,459,621,265,670,533,9,149,494,272,211,377,113,676,804,249,167,698,128,632,590,548,584,558,974,501,472,312,438,700,809,287,197,883,993,337,808,253,154,748,670,626,539,123,699,854,362,627,88,601,477,576,121,279,123,304,382,680,506,142,905,437,455,768,265,883,799,630,729,838,183,775,462,898,539,808,359,857,607,70,13,186,824,909,307,517,490,702,547,907,468,563,15,639,333,647,835,612,759,645,611,207,716,149,295,335,377,796,331,845,830,661,52,937,546,23,630,500,832,233,886,324,256,231,111,996,363,869,861,682,74,959,860,391,199,654,203,793,180,14,529,961,43,889,531,403,614,769,490,528,770,42,343,835,178,288,768,367,563,0,962,80,650,331,66,498,645,871,537,732,742,942,301,169,563,190,470,415,41,940,875,596,325,691,880,253,24,807,785,260,437,530,129,269,273,644,770,940,584,269,906,615,143,30,663,595,35,121,292,601,395,7,726,731,651,906,690,528,911,859,885,188,736,839,818,350,22,399,439,775,730,330,966,273,698,39,508,571,881,2,601,998,978,342,711,175,117,528,240,453,584,955,983,212,803,256,58,706,461,10,16,8,804,743,198,420,348,159,513,449,680,765,422,286,973,697,881,200,216,204,843,847,953,668,137,289,985,631,703,671,289,587,414,928,774,474,140,382,398,186,329,887,473,871,595,675,317,438,688,353,725,747,169,603,488,451,490,541,787,897,841,124,470,99,816,586,81,957,997,693,344,765,717,546,917,92,179,13,865,45,959,197,406,208,115,810,686,115,930,151,291,432,309,480,477,508,299,313,345,118,324,578,497,999,907,974,387,961,111,417,62,646,443,111,462,810,827,735,164,349,961,917,913,835,405,41,412,993,344,948,274,288,353,537,726,639,647,1000,83,35,703,686,165,180,490,151,344,562,890,840,606,702,876,775,86,313,456,796,124,316,947,149,92,343,62,24,466,573,258,326,560,796,906,446,254,578,374,679,422,729,241,918,119,619,233,712,196,86,864,474,310,382,731,854,725,445,172,144,670,274,489,812,551,798,577,652,729,350,572,262,530,824,186,646,287,112,769,818,474,551,108,867,29,120,787,696,574,941,324,671,373,492,130,216,549,1000,416,72,733,882,667,935,905,829,912,237,416,177,403,211,6,821,71,316,69,663,682,339,70,5,774,635,746,531,853,758,478,150,718,297,368,563,903,78,671,135,857,302,66,338,658,477,911,710,743,816,227,421,556,536,856,784,672", "381,751,102,711,545,251,286,158,131,271,147,117,968,645,766,394,572,254,98,650,98,157,728,587,634,52,801,850,781,615,721,17,746,577,177,243,373,404,870,561,902,731,979,841,605,322,381,83,269,837,665,815,511,559,914,880,304,891,152,537,983,536,750,449,286,55,400,119,832,9,726,911,682,388,238,678,13,601,747,268,316,783,947,109,777,678,777,550,730,275,422,877,903,514,205,17,100,531,151,352,139,780,310,338,966,417,409,584,887,309,538,214,298,982,75,357,851,494,856,765,139,61,479,952,870,341,699,513,255,801,263,438,748,970,118,719,690,989,74,21,824,158,838,807,272,510,811,459,415,14,20,765,259,672,119,540,563,476,769,446,390,189,693,65,287,256,658,875,226,733,298,910,467,589,302,625,745,569,142,311,463,101,908,249,606,207,947,796,142,145,676,721,226,926,101,390,267,105,269,880,182,544,57,487,453,962,446,834,225,979,536,152,587,997,628,457,76,176,732,873,371,989,297,524,936,751,584,707,94,164,602,468,414,679,708,225,141,159,938,534,579,565,313,563,556,118,420,894,97,104,644,74,155,23,391,713,325,592,473,365,202,520,33,890,587,490,496,549,420,881,51,721,879,399,777,240,589,743,195,613,790,552,471,96,354,773,185,260,993,501,534,258,835,555,568,653,463,195,824,530,733,338,102,540,71,175,435,642,717,357,508,706,395,895,609,979,403,358,503,228,614,948,833,228,551,22,538,426,3,334,225,684,594,446,70,153,850,189,267,627,362,262,480,565,727,356,351,750,2,4,44,237,602,866,24,813,531,179,288,844,180,425,517,198,667,526,102,495,951,756,66,92,132,37,361,80,488,934,185,579,364,523,792,22,465,180,56,671,771,146,197,650,269,744,812,211,337,312,886,940,264,509,774,571,865,414,562,857,920,542,112,497,442,563,371,478,549,692,831,764,78,825,241,134,96,722,571,65,601,626,125,126,565,957,844,239,111,246,610,994,998,520,759,78,595,188,574,685,694,529,224,860,533,24,110,59,247,378,178,988,286,520,624,313,869,411,832,340,203,530,129,864,722,1,806,168,597,329,241,63,18,143,132,934,590,776,138,755,20,213,873,221,989,205,458,373,90,462,355,702,902,265,600,121,764,985,317,64,220,627,571,68,45,29,611,585,563,756,252,821,658,55,719,477,571,772,658,878,226,656,78,243,151,780,153,608,912,275,965,383,512,247,352,519,381,200,852,451,367,321,170,782,532,428,327,219,384,495,827,583,199,571,990,856,121,867,425,244,460,21,366,230,310,17,256,163,751,572,422,717,567,82,468,715,418,577,619,198,265,196,332,80,794,142,382,35,980,60,13,629,547,986,86,716,146,968,962,0,117,749,253,767,636,850,62,290,434,474,586,244,225,470,82,334,136,990,854,751,257,858,833,12,281,980,673,411,619,412,571,248,966,140,371,258,289,708,490,454,259,523,850,719,375,504,875,214,996,8,794,925,283,476,977,905,294,241,459,797,794,932,608,792,356,783,162,922,805,140,274,669,947,949,417,183,85,3,543,853,392,901,507,950,994,27,804,46,633,318,596,590,316,152,660,894,394,781,282,610,122,960,826,849,999,851,136,847,495,112,994,493,431,887,889,940,697,219,902,173,81,160,947,277,736,302,116,538,259,394,139,673,675,40,256,818,522,318,581,140,815,641,222,735,642,68,889,506,446,98,627,42,781,114,470,33,329,401,92,212,580,702,758,348,169,949,505,716,361,590,884,163,199,955,794,232,514,312,521,139,150,317,279,849,313,22,449,665,137,440,753,82,133,302,155,936,320,830,416,452,618,452,203,750,441,833,996,208,466,976,302,844,562,855,103,57,297,565,808,273,32,306,785,895,583,869,416,449,712,560,738,293,762,91,452,212,938,488,678,970,268,551,530,244,966,957,246,426,772,501,929,129,652,269,382,955,96,899,132,102,95,940,744,156,527,671,624,683,988,502,301,540,665,15,529,834,143,536,154,307,990,724,187,250,356,159,519,380,552,230,581,530,88,429,304,937,122,802,819,300,510,232,934,624,723,694,355,544,719,586,96,456,351,255,813,776,143,774,281,35,524,638,683,676,868,849,136,463,343,922,577,682,730,946,621,670,910,959,93,41,496,615,328,958,567,783,968,261,675,825,723,272,885,215,598,103,908,636,976,391,108,902,759,174,143,432,268,283,889,290,289,174,416,427,470,223,459,787,457,10,358,12,832,545,33,914,611,994,559,23,978,697", "223,230,254,674,430,137,95,786,135,408,416,151,492,400,788,324,996,712,318,736,493,911,249,306,274,133,518,966,33,885,171,616,381,545,99,903,140,141,669,237,828,181,74,970,405,19,430,24,803,186,235,190,554,547,106,412,209,942,955,227,97,990,122,351,23,989,875,326,803,107,719,677,370,100,833,868,599,468,777,841,358,933,804,936,761,373,155,901,494,149,938,364,618,266,619,375,138,872,329,3,696,663,880,865,4,724,33,562,914,237,318,469,622,844,196,909,587,657,708,553,259,301,689,683,685,886,123,651,577,444,462,545,580,459,823,114,324,750,57,638,178,300,642,535,230,994,82,46,109,903,763,159,700,389,889,744,259,362,142,857,164,246,705,158,303,498,741,569,88,973,91,518,642,390,415,4,177,521,161,188,990,649,318,418,199,636,513,62,474,489,358,219,352,670,444,591,94,432,322,795,622,528,322,487,901,390,985,785,354,802,383,371,970,429,262,893,394,431,730,178,90,256,270,72,65,625,715,699,796,679,349,878,604,150,238,47,275,887,308,246,148,651,380,330,635,987,186,141,286,155,714,920,547,484,835,542,994,191,235,916,268,676,495,58,5,823,611,751,260,692,246,202,353,190,836,38,425,137,170,388,726,705,864,809,419,812,146,419,174,979,447,677,908,154,545,856,285,642,243,257,505,270,271,716,622,391,334,955,854,859,454,371,685,301,327,811,742,188,667,222,489,531,877,952,914,200,163,320,727,923,599,943,53,774,216,409,103,198,584,804,579,726,958,175,458,529,895,96,481,147,866,968,842,758,129,215,209,77,355,392,313,201,162,436,923,395,391,651,472,128,413,706,727,994,19,706,940,489,793,877,468,903,283,254,174,625,675,836,298,149,707,367,279,647,975,420,125,478,516,285,941,92,361,503,3,939,438,818,924,85,878,128,369,505,959,820,268,828,657,314,216,234,535,253,596,390,516,900,303,648,468,194,711,386,528,225,27,410,506,468,424,797,826,731,749,393,50,701,174,409,825,753,373,135,250,213,355,745,663,832,880,362,819,175,90,685,397,773,630,320,967,461,777,48,188,385,49,940,575,476,772,197,488,140,451,489,290,823,300,8,175,373,93,877,116,369,16,390,809,971,605,328,302,81,100,479,947,983,464,55,470,27,267,10,878,44,502,925,495,794,864,509,98,29,845,36,992,834,707,21,568,764,280,275,789,487,524,376,126,49,76,773,981,988,252,153,312,700,191,285,817,433,834,239,336,974,862,831,496,928,937,289,785,371,938,893,926,681,806,746,952,685,200,749,456,36,141,216,606,577,689,14,178,300,443,935,88,5,495,599,97,427,422,373,808,188,657,981,572,778,744,709,30,821,452,437,80,117,0,274,672,161,177,303,179,805,294,831,82,199,385,101,280,401,423,621,312,267,946,825,651,614,410,987,502,304,15,143,157,250,773,906,67,615,760,937,156,380,971,936,314,891,702,365,937,477,538,963,895,568,283,919,563,338,376,910,743,461,342,17,770,455,802,785,365,952,156,10,631,527,714,175,820,703,675,318,528,366,243,962,48,895,776,262,795,744,798,968,62,429,130,997,336,823,927,547,55,152,154,935,551,290,242,779,466,944,851,703,740,277,118,425,385,908,485,236,707,238,305,534,181,269,572,207,136,475,5,896,476,596,312,903,706,194,886,46,724,29,32,712,230,796,815,557,261,555,204,237,982,985,859,428,690,462,612,202,565,74,39,851,13,789,119,27,257,263,687,756,251,325,53,908,365,914,357,295,219,212,109,112,107,267,591,707,437,201,217,726,933,889,721,781,242,800,578,131,473,182,831,558,452,813,357,636,48,338,710,77,394,480,56,678,790,553,25,654,157,246,492,576,484,40,303,434,297,301,5,963,602,370,566,492,97,615,493,723,634,466,648,381,269,208,442,380,46,478,598,112,445,369,653,197,626,188,877,349,249,586,23,951,829,49,694,409,567,703,853,859,830,943,147,683,269,251,367,178,797,153,365,962,142,705,719,116,127,45,568,263,848,34,500,16,683,251,832,215,755,682,279,487,295,402,415,693,837,201,644,102,396,102,201,526,255,885,21,912,956,286,81,262,376,809,445,973,988,130,81,248,768,239,100,486,22,481,727,532,496,125,925,131,971,954,924,504,373,218,916,718,587,478,390,166,88,140,367,168,645,821,282,603,171,481,417,185,128,850,541,670,919,192,10,921,97,693,201,242,749,339,483,618,981,53,484,373,456,523,973,972,53,749", "299,61,8,198,738,559,574,24,146,120,610,868,669,702,280,784,427,563,358,152,305,944,131,484,265,715,135,399,237,799,46,647,853,469,811,964,103,330,629,608,446,142,705,851,307,358,551,50,854,939,777,642,305,451,975,168,421,723,918,440,771,935,840,241,406,974,561,51,706,777,536,13,994,901,598,55,785,414,874,499,385,528,86,988,851,497,698,999,727,435,370,135,206,323,458,857,819,119,812,108,964,727,228,20,363,178,694,844,8,903,548,319,56,388,112,844,99,991,355,340,808,151,524,633,581,556,929,251,550,838,471,521,52,856,766,937,823,12,477,948,479,597,575,546,912,90,98,739,46,645,313,811,756,742,999,669,412,826,116,318,820,731,255,880,156,387,324,196,984,199,937,488,561,438,543,253,125,557,268,485,14,395,345,26,816,551,652,480,604,164,830,457,413,186,848,642,687,547,57,888,769,886,209,47,108,508,62,8,625,244,749,860,641,436,667,473,634,693,886,533,42,518,511,819,79,730,847,780,773,714,952,698,925,137,859,462,812,81,873,348,655,403,622,556,120,348,196,578,728,938,969,835,447,773,71,810,16,394,169,914,3,698,125,234,22,326,677,451,452,881,556,839,601,184,506,916,200,347,308,314,949,790,100,134,11,950,763,300,665,982,12,168,207,225,822,957,738,776,114,151,205,425,797,723,905,432,656,672,612,621,842,250,446,655,576,611,715,505,824,106,923,108,79,476,160,434,575,539,984,753,622,651,707,337,155,579,882,55,878,551,96,973,35,307,850,962,781,974,210,84,590,527,135,602,521,64,80,760,985,999,626,881,750,143,776,627,719,207,652,616,996,117,553,30,191,645,654,472,688,368,430,427,611,539,413,220,611,343,11,710,54,307,866,580,252,271,259,270,633,840,172,929,866,257,967,152,632,182,833,364,485,997,833,221,604,276,874,895,401,6,634,224,18,762,263,426,647,866,301,208,885,856,585,133,92,76,106,78,26,60,29,49,695,225,10,856,110,291,8,400,569,346,52,70,450,614,11,332,194,173,954,57,600,585,419,851,399,269,430,979,787,506,862,783,898,531,540,728,756,122,604,931,436,715,273,121,950,645,800,195,647,761,771,896,381,906,976,814,423,201,904,855,724,822,707,353,84,383,272,170,24,540,107,826,505,292,334,863,528,338,94,263,76,103,533,155,428,596,422,362,817,690,888,141,800,460,266,739,211,67,987,769,341,839,335,800,137,379,502,139,558,664,39,500,383,951,89,876,632,115,250,521,31,564,563,356,516,899,424,182,269,234,203,648,470,327,277,50,443,400,401,541,262,672,187,130,476,676,36,270,550,85,304,284,460,581,288,806,393,861,438,755,888,265,937,128,650,749,274,0,882,459,580,148,483,330,848,316,775,874,137,145,708,466,89,910,425,685,220,584,428,327,180,224,307,718,261,579,543,238,180,67,907,358,446,416,68,437,330,931,536,925,332,307,860,381,583,313,557,731,782,789,520,992,168,314,727,115,505,54,592,115,834,234,212,829,186,537,853,264,925,574,859,322,955,957,565,575,299,700,137,625,592,299,370,726,461,17,907,39,2,359,76,863,534,68,277,239,618,707,656,859,150,653,352,55,70,332,107,922,647,227,781,338,295,268,749,103,804,668,211,201,578,791,365,868,942,261,852,671,654,554,5,469,519,219,390,325,86,125,911,940,691,972,945,352,638,893,374,969,500,66,742,419,548,3,664,882,586,533,419,21,67,508,33,565,870,752,91,740,62,295,266,470,101,627,749,121,124,75,661,157,431,390,187,122,392,333,439,946,239,231,207,730,602,317,437,414,62,18,435,763,816,814,556,302,903,956,528,894,425,568,164,216,133,607,318,323,183,764,360,810,939,110,581,438,971,515,501,618,302,17,459,596,410,893,567,582,253,532,437,366,886,67,477,395,932,216,541,265,647,676,495,469,288,217,584,296,987,395,858,980,373,752,836,620,970,620,27,112,758,370,455,179,656,89,578,976,979,581,584,25,652,266,162,93,644,63,265,314,816,86,384,614,155,217,795,9,640,516,353,144,955,173,60,261,191,584,258,468,828,656,145,202,85,857,282,8,434,744,270,944,298,907,889,235,324,560,990,717,282,547,419,130,147,612,341,756,883,404,282,875,297,260,736,12,155,382,681,798,862,779,691,754,136,442,695,372,751,707,553,175,402,843,60,582,870,963,513,826,41,524,499,112,968,605,291,617,726,930,859,725,290,684,821,261,128,127,566,659", "298,834,574,784,797,974,949,876,616,672,890,292,538,111,362,23,109,111,351,986,438,810,935,503,983,821,646,302,827,575,133,477,964,949,630,273,385,268,580,332,419,688,891,846,162,8,513,153,801,418,461,220,226,607,758,179,462,66,765,706,253,816,622,660,183,129,508,360,561,71,313,547,722,403,161,870,832,629,758,131,879,332,731,17,216,960,4,496,261,851,803,487,806,916,58,699,379,61,115,304,841,426,711,928,97,448,518,644,903,252,412,200,821,362,424,599,977,615,826,903,656,531,366,904,553,803,821,605,387,779,971,905,891,707,885,333,958,602,446,433,157,610,206,449,466,233,81,291,595,232,110,227,576,783,135,952,41,372,646,527,158,939,444,562,878,717,509,794,920,15,101,299,266,212,122,354,41,259,26,232,631,71,227,467,129,22,821,930,555,993,562,692,240,919,459,764,529,600,433,107,438,136,791,399,416,452,477,601,88,427,922,690,340,905,282,769,763,341,797,436,527,983,898,750,418,544,948,888,979,814,968,488,610,275,32,671,335,141,831,803,708,735,22,218,886,981,920,499,259,654,625,617,134,969,301,136,190,379,715,855,696,405,169,536,180,417,420,407,125,31,818,199,521,879,409,58,964,290,175,706,465,132,376,850,307,133,724,890,511,989,576,440,666,574,224,930,846,979,584,131,53,250,551,963,927,881,977,346,226,794,880,192,296,555,399,515,510,96,543,561,763,978,581,357,495,266,655,90,136,979,743,560,419,75,365,540,202,594,141,872,830,536,242,773,980,746,680,488,433,488,453,230,569,921,728,940,632,386,524,19,627,828,1000,573,508,714,577,816,986,3,747,70,758,343,864,851,736,423,33,674,78,251,846,649,106,312,641,214,741,174,878,404,912,236,983,260,519,143,994,506,996,631,615,377,392,809,779,749,372,868,321,619,308,598,369,658,142,884,112,829,671,577,614,518,565,861,11,139,745,670,928,472,95,732,431,262,496,181,486,265,998,11,778,370,603,639,862,127,361,292,429,556,827,489,700,610,369,336,918,735,96,921,255,880,327,765,811,471,375,235,192,622,722,378,14,809,573,551,378,943,942,549,61,430,542,965,796,863,933,855,899,323,102,186,381,152,237,897,481,186,830,553,361,163,291,548,662,115,826,390,640,846,694,286,189,78,799,34,50,20,443,761,539,430,25,931,75,961,889,86,155,965,697,845,498,314,46,559,535,375,501,144,463,316,171,762,689,278,528,529,964,576,93,296,850,239,43,576,265,155,292,54,478,799,744,477,62,408,690,131,226,823,686,488,284,671,72,394,452,475,136,458,809,108,12,224,790,848,182,183,877,698,471,968,796,881,31,239,742,844,336,837,515,904,273,311,331,253,672,882,0,510,575,121,810,782,216,208,954,131,365,643,511,327,720,905,559,263,796,26,628,340,523,764,549,28,573,979,470,937,812,533,857,290,874,777,144,335,980,719,929,623,775,457,206,232,468,28,495,622,86,274,233,549,156,353,209,219,881,485,170,373,554,70,53,220,539,198,180,955,56,632,744,124,9,390,590,537,604,784,337,831,213,696,494,854,390,361,37,862,774,91,407,373,809,661,103,766,552,388,970,981,688,761,500,195,210,225,714,461,68,710,947,70,859,669,273,363,468,387,183,295,585,831,166,771,359,868,99,207,79,35,910,327,357,117,548,768,805,455,583,323,7,259,619,331,996,346,604,219,547,771,691,313,13,687,759,757,561,945,979,237,96,399,125,646,547,628,171,735,595,429,985,206,414,362,905,313,690,129,447,5,460,905,626,422,2,984,501,48,127,758,918,579,865,906,74,860,394,434,217,847,26,119,796,510,486,762,946,231,495,858,181,799,153,123,81,745,676,157,486,707,465,869,408,893,404,474,119,386,502,256,568,195,256,747,389,813,51,377,397,5,738,525,281,778,224,205,313,808,623,118,772,355,73,277,537,289,843,198,506,65,956,248,117,991,77,418,975,898,91,22,16,861,817,173,452,842,647,959,706,671,388,351,395,181,766,146,773,744,342,896,93,964,381,757,491,558,239,185,447,705,432,742,802,966,909,730,568,263,621,457,957,373,859,57,270,241,769,262,348,787,972,764,692,500,847,354,448,551,290,896,389,763,221,550,913,78,565,722,895,695,800,823,270,171,297,456,459,769,888,940,264,970,746,171,85,883,663,705,712,513,912,630,144,723,267,792,608,569,642,936,903,549,134,663,591,739,965,538,542,950,891,199,481,986,421,981,306,94", "981,940,804,184,127,70,493,311,445,327,648,618,190,132,754,116,755,482,446,757,741,722,566,607,358,661,154,194,125,582,702,696,223,357,229,22,258,379,948,385,895,884,791,516,77,664,367,540,967,312,691,989,522,367,847,283,736,38,404,108,50,471,471,893,386,747,98,745,885,897,418,257,720,640,487,631,850,914,95,518,280,483,644,153,689,268,699,80,167,696,732,230,837,445,489,720,809,468,315,341,294,248,544,513,39,942,786,109,266,863,864,127,25,271,166,587,213,939,101,850,663,355,511,56,182,882,740,282,795,829,295,675,614,539,312,617,428,918,704,492,556,409,388,804,46,821,477,115,548,465,642,141,262,448,893,138,880,454,476,11,50,740,207,898,742,837,221,626,920,327,3,778,278,4,439,31,163,551,397,150,623,723,774,855,542,754,883,868,484,608,926,686,339,994,680,266,342,228,707,616,412,773,11,372,486,737,799,395,775,447,190,444,518,19,557,561,60,49,42,645,675,783,159,273,362,77,802,71,582,869,314,322,803,576,13,748,647,637,18,795,756,518,501,515,9,454,853,80,349,233,232,860,995,221,553,351,866,319,611,527,84,463,823,111,171,830,371,146,963,535,22,730,132,276,915,778,565,820,737,518,923,117,332,834,725,653,251,691,589,606,542,620,879,52,360,193,372,20,784,664,646,389,469,503,386,614,890,457,236,922,949,237,4,847,385,312,495,820,741,7,670,921,891,79,579,41,650,448,104,29,478,887,402,540,314,750,204,100,915,901,561,123,190,412,198,66,841,729,32,214,515,935,760,301,991,145,648,331,990,788,181,569,2,340,435,587,853,483,133,123,603,955,101,701,597,624,652,139,611,720,551,430,85,92,671,958,284,231,380,317,417,681,994,237,515,222,185,225,279,635,433,824,417,870,144,534,114,477,347,697,875,248,261,27,360,702,982,692,200,385,996,685,520,644,879,301,650,615,534,360,81,568,513,883,911,710,829,211,496,814,569,854,479,976,981,680,989,629,479,441,851,765,199,805,191,965,77,692,266,414,449,309,252,333,215,854,660,880,157,191,617,179,120,923,283,44,784,221,214,772,153,629,850,365,717,644,664,974,983,916,203,677,636,865,344,506,453,890,984,302,572,393,857,649,769,86,369,790,408,148,493,598,490,14,466,863,972,332,984,601,422,190,406,775,372,630,988,59,409,357,774,650,400,625,992,539,939,726,197,94,461,539,136,506,622,516,365,934,959,405,353,406,273,686,569,750,97,996,50,734,701,339,361,116,870,115,301,401,866,587,248,635,737,839,139,893,211,613,41,280,581,920,192,799,202,428,162,325,887,803,878,482,182,298,283,894,774,158,284,915,410,736,160,921,892,322,66,767,161,459,510,0,764,571,141,728,457,744,884,574,720,604,150,158,813,69,544,783,753,404,301,716,464,547,914,614,695,156,369,994,600,538,806,657,55,112,652,848,953,976,597,792,98,753,471,171,946,690,311,876,299,737,728,332,325,542,17,931,384,303,933,38,113,80,456,616,166,691,973,291,164,929,498,917,711,486,81,433,477,529,801,994,417,710,671,587,317,729,19,939,280,262,772,982,135,203,971,889,823,670,507,328,66,539,727,961,769,418,408,281,375,209,525,654,538,809,361,690,55,21,764,716,553,143,844,527,354,647,760,611,136,536,236,868,971,585,872,936,532,156,905,350,860,991,39,261,170,877,422,416,129,464,454,171,205,835,433,835,325,848,104,594,70,256,302,568,253,883,715,529,726,197,90,833,86,610,458,468,382,42,942,212,747,598,41,724,325,783,872,127,592,288,669,445,923,293,255,965,673,908,133,530,67,795,127,813,62,965,761,79,149,849,109,826,633,87,952,230,680,102,387,212,164,816,306,213,241,676,550,777,667,391,188,108,90,686,248,249,206,550,573,788,717,64,483,572,543,846,919,996,843,809,230,482,383,622,261,932,72,654,62,413,398,717,43,580,178,973,53,523,168,32,495,849,450,420,311,672,174,738,738,41,442,449,303,624,115,203,125,534,166,545,223,317,913,938,950,79,511,858,606,975,5,598,766,225,947,585,959,716,58,154,409,229,69,981,476,707,236,982,61,885,439,318,305,623,650,758,822,513,903,253,584,851,548,69,561,563,370,885,932,388,721,143,88,449,436,973,752,53,579,604,272,17,637,44,29,70,826,975,65,663,791,981,769,745,791,539,635,296,92,483,534,465,750,29,993,212,13,374,545,681,775,779,237,101,756,916,897,288", "642,156,798,159,576,306,175,54,725,455,28,642,97,856,691,738,18,264,834,50,697,530,104,837,716,384,767,815,660,190,955,168,154,401,83,505,226,374,134,342,480,225,978,694,452,192,956,603,880,432,595,113,503,614,946,498,792,723,948,395,662,908,18,631,980,491,968,135,782,57,753,637,805,882,908,800,88,718,639,822,538,899,10,642,294,669,644,340,202,305,140,155,955,355,991,793,581,529,999,943,324,294,740,178,810,326,722,246,92,1,318,428,52,65,850,266,608,617,45,736,699,328,27,675,110,366,738,781,970,721,335,32,571,404,234,806,677,712,592,519,725,145,109,699,499,654,588,948,675,606,485,500,963,203,907,606,619,23,869,420,150,242,428,488,511,416,126,678,235,152,278,523,440,878,322,363,296,76,750,667,366,874,949,725,907,555,290,993,835,479,928,149,278,412,907,128,538,479,402,227,273,558,130,10,714,337,589,550,682,236,337,763,947,997,453,852,88,5,790,929,610,41,962,4,321,124,850,166,960,225,764,637,842,203,398,922,333,760,35,109,177,31,590,24,222,754,341,676,787,423,46,690,989,939,751,185,372,768,690,555,537,404,75,271,183,818,976,540,296,17,110,725,83,931,895,967,310,433,654,790,722,399,349,542,238,342,136,949,197,245,893,75,116,638,745,71,218,371,756,237,381,209,16,295,41,88,65,363,158,832,529,939,88,272,934,656,816,108,573,682,989,58,636,79,102,535,186,45,10,933,75,357,431,575,289,720,336,380,895,828,813,137,254,342,448,928,68,368,789,128,962,451,122,76,858,151,636,130,188,587,616,358,184,732,875,492,278,245,958,32,517,645,924,121,793,640,907,325,984,975,785,379,795,470,236,358,197,502,262,785,751,499,49,211,57,927,650,371,34,787,799,938,662,117,739,743,522,634,967,251,26,655,930,385,907,22,563,623,950,504,934,568,217,921,153,136,214,880,253,995,604,960,269,328,425,573,822,302,823,191,413,889,103,137,575,495,575,386,68,525,715,741,820,941,899,300,649,151,735,62,916,155,23,890,993,691,431,898,146,197,986,532,410,442,593,122,403,806,795,55,474,980,967,75,149,691,659,225,206,397,757,625,858,832,362,448,52,580,234,383,701,742,514,858,57,178,514,28,912,884,427,844,231,74,100,899,683,690,373,762,917,220,237,765,866,513,639,771,560,414,677,190,746,521,139,856,318,549,901,212,927,104,183,461,311,181,827,845,867,768,114,407,175,397,162,732,51,335,216,390,396,378,504,477,650,442,883,427,46,901,653,583,105,519,321,775,396,842,108,803,743,880,556,567,791,227,546,484,82,127,511,487,79,422,785,151,535,685,837,460,467,521,790,5,300,374,498,636,177,580,575,764,0,26,806,250,833,237,251,26,747,169,982,901,442,903,442,122,10,46,830,467,133,81,515,354,374,11,210,51,720,440,607,918,787,61,395,657,631,238,961,834,808,271,461,14,392,463,807,130,1,271,541,192,280,387,609,146,855,493,367,256,217,501,257,537,112,551,543,267,857,573,340,558,846,125,78,898,524,467,179,175,671,200,399,569,519,504,17,740,658,801,120,414,76,792,185,412,533,165,859,678,718,353,82,900,852,808,243,242,781,269,781,305,301,24,900,923,443,371,614,804,418,607,314,455,79,332,419,150,341,820,739,278,46,102,174,207,444,950,645,586,896,431,933,388,383,683,305,354,659,819,526,414,283,717,803,609,644,767,102,746,152,144,975,883,221,34,498,798,518,338,239,805,369,893,361,256,309,812,984,283,448,602,279,59,152,414,130,58,837,742,695,203,487,237,741,286,577,681,412,188,35,382,942,375,638,338,868,441,824,296,545,914,904,116,738,953,939,526,856,293,290,474,793,335,138,32,773,18,168,801,781,550,588,756,971,85,271,785,673,942,631,513,236,424,781,982,495,740,665,58,768,803,549,412,201,58,841,504,751,317,220,209,909,361,703,349,193,87,935,643,831,926,625,468,4,194,94,480,117,139,648,920,890,377,89,854,742,655,322,505,828,864,427,258,496,137,536,217,232,2,7,395,762,197,432,369,463,62,347,730,787,319,195,465,452,369,721,992,772,974,698,612,655,487,927,456,492,843,638,33,3,522,267,556,136,955,582,485,83,167,481,141,221,270,361,418,277,791,157,733,988,265,400,841,671,797,433,878,660,205,667,924,673,236,934,134,442,731,375,270,927,942,887,706,209,462,694,43,150,627,881,817,883,551,586,441,213,209", "100,410,832,845,100,933,153,227,318,770,474,566,262,149,790,505,454,429,515,857,642,277,518,197,920,187,572,534,28,581,816,709,474,215,624,114,932,963,348,557,255,254,108,602,411,674,989,848,225,995,212,314,380,826,621,887,68,806,912,555,880,681,481,91,908,822,106,143,900,196,685,368,771,184,402,417,768,934,418,270,78,471,604,351,910,131,384,867,403,86,763,83,796,665,365,258,930,933,476,72,328,100,245,112,780,88,823,354,881,444,256,809,974,259,978,265,41,643,471,667,915,153,555,923,565,774,237,960,189,678,548,91,185,15,26,895,517,235,633,704,870,954,987,910,642,18,215,915,679,280,674,431,945,198,773,791,224,341,357,649,771,194,15,595,812,312,269,383,149,111,169,982,326,746,45,696,456,176,786,886,211,29,781,872,716,525,34,68,917,801,612,304,654,609,254,393,687,25,510,451,881,284,199,9,811,213,768,849,718,943,979,780,598,320,646,420,966,214,711,163,567,244,366,712,660,44,826,182,680,726,882,497,132,435,762,572,329,671,442,603,397,399,595,793,755,556,310,846,62,724,305,697,674,181,265,960,205,281,87,124,324,973,639,2,108,635,48,105,92,234,487,456,825,485,979,116,405,618,849,33,812,269,72,340,81,936,64,398,574,101,824,440,455,399,217,705,549,542,915,154,416,310,315,924,982,700,334,541,34,188,918,951,35,872,220,175,584,529,691,426,979,941,317,790,868,763,784,912,535,561,976,593,464,510,960,440,759,304,960,970,718,309,880,327,4,127,217,2,239,463,43,728,736,239,727,934,221,891,269,535,999,184,259,72,312,810,943,630,747,730,711,780,367,470,574,685,405,419,415,818,510,469,642,828,874,607,754,642,624,727,727,273,625,117,135,164,422,763,487,738,8,343,726,4,515,138,625,161,319,783,153,402,564,398,192,664,349,516,33,381,636,796,279,211,365,86,19,628,251,116,69,830,799,930,153,740,982,59,76,574,780,778,232,251,965,980,888,784,583,60,305,870,199,375,854,941,201,467,724,425,682,447,985,981,892,376,6,104,324,859,771,892,655,557,134,162,307,684,366,405,418,186,165,306,373,419,491,624,930,723,840,607,525,34,168,740,200,87,570,459,681,33,674,244,523,374,905,783,100,50,590,537,614,350,768,415,416,482,876,221,651,647,905,879,186,447,955,272,593,221,424,860,420,169,150,185,762,460,542,45,301,283,509,736,809,729,448,69,618,99,177,26,869,540,23,600,729,731,616,363,244,886,615,33,831,62,945,984,252,743,802,777,368,390,412,759,174,902,14,49,914,604,76,770,510,850,245,332,499,565,201,599,906,355,383,490,799,380,146,459,534,888,400,520,992,616,645,850,303,148,121,571,26,0,136,11,256,64,682,515,979,262,677,509,741,916,792,860,380,111,424,950,396,606,735,463,421,668,765,583,885,458,472,10,587,256,243,441,908,537,15,792,975,436,669,890,567,963,122,756,984,761,99,614,612,165,348,536,843,841,891,370,347,795,7,276,984,651,971,279,394,324,547,487,596,698,432,496,692,301,788,681,466,280,402,828,677,819,790,740,223,781,331,887,628,2,341,481,206,504,658,663,349,305,465,123,732,438,120,942,579,29,19,121,875,73,718,753,34,888,932,349,936,822,365,512,149,860,438,426,178,749,979,716,109,144,205,244,651,115,904,245,751,64,428,522,922,672,605,252,231,332,767,414,185,237,505,696,976,377,96,382,770,161,676,935,605,804,770,857,2,734,730,666,235,421,489,385,52,395,894,803,82,529,786,719,586,687,576,550,841,260,250,533,963,191,813,625,254,239,59,455,901,867,307,590,193,955,262,541,213,345,522,347,605,360,723,688,17,928,545,801,571,938,952,559,394,8,57,674,363,792,46,799,803,344,460,880,733,193,955,50,283,729,476,87,505,155,718,933,682,233,962,517,863,736,602,912,310,632,827,863,127,69,314,356,177,685,360,369,19,37,224,740,275,328,591,339,721,622,26,60,651,301,30,696,494,236,141,110,481,559,286,718,130,233,105,146,452,181,70,96,259,68,514,103,765,847,142,719,276,246,257,63,759,856,206,160,714,975,504,399,432,347,205,156,622,281,959,461,647,259,923,277,558,390,186,262,662,35,694,568,731,252,600,700,20,503,506,319,836,400,633,720,137,961,188,295,350,935,505,656,56,239,990,123,743,629,771,216,356,575,782,473,767,246,611,123,701,713,968,394,507,369,195,94,426,286,812,498", "95,734,883,876,980,457,273,577,562,134,394,973,598,449,115,463,227,200,820,325,631,660,609,691,922,914,64,968,539,556,294,949,480,850,684,314,384,204,992,693,793,106,728,454,995,381,594,459,847,268,642,39,832,436,961,153,613,218,874,881,309,304,657,92,379,822,76,368,743,356,998,62,544,413,384,491,154,485,804,434,872,595,110,299,661,785,621,999,510,789,300,206,200,686,973,668,200,293,186,242,392,193,498,910,763,737,737,863,367,172,657,503,961,540,408,752,423,425,173,543,524,465,285,858,140,164,412,181,512,897,779,248,551,43,237,458,620,233,683,832,275,557,547,306,545,910,824,553,74,880,121,336,886,800,182,326,666,336,454,628,488,322,4,841,746,295,259,894,934,636,403,142,371,52,142,467,557,281,233,358,936,573,366,342,166,437,273,380,672,242,873,70,883,852,986,720,574,41,781,16,248,480,150,466,239,426,342,735,421,511,576,18,172,395,513,363,200,681,732,901,762,943,650,303,598,185,452,706,254,783,233,573,666,18,711,728,630,515,479,946,973,466,431,784,419,194,929,870,364,110,861,39,390,279,331,940,908,636,276,627,776,103,840,908,397,152,681,94,756,130,533,918,800,396,843,832,918,115,290,728,124,486,944,132,75,921,576,369,247,411,22,867,787,800,60,121,120,677,520,172,809,270,125,254,549,210,408,607,749,754,867,810,639,726,236,384,796,427,594,831,764,445,182,776,29,410,133,50,124,67,676,714,363,857,480,128,724,77,38,949,352,608,623,209,737,570,882,802,129,924,442,405,627,367,494,403,14,955,700,572,354,88,604,355,87,127,270,753,749,632,161,516,138,814,948,655,714,836,528,663,788,213,699,29,64,750,203,328,171,525,588,227,273,301,965,735,331,947,676,456,762,735,106,783,583,931,879,57,258,840,624,454,22,494,568,728,763,511,973,902,132,818,961,300,236,645,937,754,408,601,236,651,697,721,907,454,283,527,459,279,30,293,707,898,958,592,181,89,789,707,869,347,767,973,583,178,417,890,174,821,387,426,672,651,496,541,723,568,715,555,727,865,183,733,218,782,959,345,532,876,969,372,489,60,496,769,582,240,400,955,284,773,722,194,793,118,256,996,22,305,100,563,252,101,636,716,615,693,384,940,909,578,905,870,854,945,162,529,666,70,347,676,934,158,404,328,8,351,20,694,911,714,546,688,530,373,250,430,557,98,76,654,104,772,664,58,12,56,361,972,691,914,336,147,668,16,227,804,581,591,937,725,747,260,998,910,456,555,995,375,738,793,549,432,550,432,348,918,772,802,745,910,457,856,388,126,879,320,173,723,169,104,314,563,707,181,504,515,206,844,908,313,701,843,453,321,871,62,179,483,810,141,806,136,0,582,351,295,998,346,662,837,39,327,855,765,519,601,776,682,416,111,845,15,683,80,867,548,105,593,192,936,49,995,457,679,733,132,77,222,761,759,161,276,191,638,952,800,659,157,57,523,149,730,632,401,78,751,792,626,892,262,288,5,863,959,684,185,707,302,593,299,73,925,615,738,165,593,117,369,515,345,463,238,515,422,161,154,981,235,550,189,842,49,498,460,764,535,849,60,94,265,279,209,392,157,30,580,5,450,422,63,454,680,670,931,140,3,849,910,75,607,20,151,766,527,848,91,283,266,501,692,917,135,471,342,963,583,992,889,161,171,872,437,252,877,336,332,884,16,70,743,628,144,609,655,148,171,168,322,613,567,990,890,239,111,756,583,992,284,874,845,359,401,574,585,240,890,549,692,302,431,860,622,588,879,149,259,64,252,253,113,205,69,82,911,446,946,258,880,422,830,348,722,980,382,900,228,517,500,310,365,160,234,478,285,242,759,302,350,335,483,278,287,155,799,379,736,613,107,103,523,959,728,242,166,243,925,25,25,937,694,520,545,810,410,834,698,879,3,689,396,912,631,642,724,923,574,539,435,850,663,526,779,76,231,563,493,90,85,266,209,691,304,167,280,684,75,542,374,207,6,796,533,485,933,702,154,28,232,276,818,71,589,416,138,972,588,708,407,16,288,157,356,290,786,331,961,90,428,429,818,139,351,865,941,634,417,496,833,955,575,591,966,486,293,229,423,630,153,798,903,611,627,856,927,105,277,152,812,380,456,759,104,181,23,266,627,636,792,544,431,102,327,275,156,128,945,292,127,814,700,319,153,150,809,561,441,735,3,220,975,11,505,25,339,629,829,730,282,767,39,785,28,978,166,588,488,371,865", "828,599,137,87,867,864,73,339,571,842,51,932,657,658,921,857,897,835,395,227,728,23,27,201,286,386,297,956,843,703,734,679,411,881,661,676,195,58,312,517,620,215,145,538,181,107,106,654,355,116,710,965,811,539,503,145,698,623,392,556,582,915,925,330,558,80,980,393,249,143,610,145,775,99,102,838,699,138,886,712,881,631,989,518,305,204,893,215,148,238,659,480,826,464,522,916,106,782,710,980,939,316,668,169,996,611,849,459,969,209,651,965,164,478,449,686,651,362,28,893,252,466,708,599,992,174,411,978,739,631,920,283,802,994,207,615,536,344,204,245,118,17,348,776,141,177,16,305,949,615,370,779,901,888,461,921,650,126,171,289,435,986,105,735,479,353,783,898,344,79,208,416,963,399,473,289,447,142,888,688,717,995,70,716,790,886,861,819,637,404,637,961,441,100,113,290,459,735,755,448,130,460,299,736,606,903,372,861,894,826,673,192,941,680,761,194,225,757,253,437,769,940,419,969,773,272,794,503,349,686,561,932,387,180,839,426,206,181,443,585,920,351,885,416,434,849,495,257,261,322,42,276,134,425,684,670,577,857,521,29,983,247,387,12,323,143,940,595,926,591,126,622,714,557,356,376,916,825,480,744,559,691,45,998,328,565,430,595,580,573,361,309,167,251,109,841,386,274,133,447,415,474,93,144,543,459,790,916,506,594,82,187,10,45,312,992,383,401,421,374,348,579,520,791,462,30,635,671,761,949,353,282,114,860,494,460,696,24,939,764,381,466,328,429,771,513,256,10,907,640,541,854,285,905,525,560,276,325,206,307,599,395,826,256,56,39,548,706,489,166,420,666,706,965,149,76,486,136,758,206,52,829,544,454,736,769,827,97,905,331,787,855,444,81,417,534,225,588,445,283,948,970,217,450,660,646,952,122,765,287,194,73,455,688,357,286,686,954,945,581,779,933,381,117,888,279,520,420,183,854,286,632,3,52,689,179,921,511,395,622,638,772,977,440,247,392,851,452,652,345,306,314,177,84,151,497,450,151,300,856,857,290,141,630,927,386,257,925,259,109,588,476,925,343,959,626,954,176,650,183,732,193,42,9,312,676,851,706,914,610,124,504,511,810,933,561,773,634,305,509,393,241,10,605,377,954,518,378,843,943,536,276,381,619,168,911,267,645,200,726,902,381,287,604,202,956,947,316,774,491,745,606,163,268,332,589,97,992,580,84,944,655,652,720,740,246,362,266,195,265,228,696,434,110,609,167,886,36,662,755,265,716,17,208,975,944,73,796,603,472,977,964,376,871,296,281,705,442,431,546,153,563,661,68,28,132,756,545,145,682,844,39,418,534,700,314,808,450,308,929,662,912,45,911,591,791,537,290,805,330,782,728,250,11,582,0,809,849,628,614,786,966,920,593,145,605,238,173,242,685,907,638,237,990,722,129,73,257,281,379,111,403,964,897,270,449,737,901,903,357,562,808,316,701,707,685,755,595,924,842,315,934,802,455,745,721,19,758,773,514,756,518,936,751,754,894,906,43,576,365,791,177,984,881,927,721,516,608,709,626,960,849,510,769,583,980,278,948,358,156,48,147,908,408,7,756,998,688,981,874,671,140,920,780,627,367,804,268,431,186,527,893,39,30,69,969,901,328,174,518,952,745,817,115,14,386,738,13,231,759,258,579,587,607,239,670,63,7,496,686,583,62,1,671,579,534,401,877,453,264,774,596,415,499,511,138,186,113,730,120,93,776,216,647,529,179,223,143,367,264,521,852,823,776,138,19,503,418,390,933,673,322,493,2,334,935,648,398,438,937,792,843,786,377,429,302,69,61,703,6,268,156,3,661,795,559,892,449,808,567,931,925,373,492,453,103,725,915,684,274,567,668,835,253,570,100,226,19,37,358,964,797,698,743,984,624,407,915,237,371,404,288,749,432,649,775,462,471,880,11,423,482,328,886,921,277,157,630,445,702,554,459,29,13,392,463,111,692,341,941,922,380,433,634,849,975,286,407,740,184,310,858,162,869,984,401,765,446,392,666,468,518,778,218,963,566,102,738,380,401,480,687,787,887,465,555,637,878,362,34,448,783,861,746,163,338,134,991,608,909,634,605,843,350,757,624,941,975,286,71,965,932,973,98,226,98,886,565,853,621,655,884,420,895,926,757,820,321,900,524,717,849,462,537,69,182,77,462,414,364,109,820,67,39,456,351,762,783,882,477,380,960,350,165,397,928,614,872,44,164,905,489,559,72,164,915,118,93,49,630", "794,444,694,817,204,437,276,537,801,329,926,51,916,151,508,663,626,815,281,254,294,756,674,192,982,484,346,607,415,52,952,681,356,942,912,247,343,486,556,287,490,718,795,534,386,947,559,870,182,871,769,771,993,649,703,358,591,722,771,747,308,793,297,296,415,833,979,849,596,137,242,416,843,106,377,824,803,378,313,615,778,355,780,979,24,958,334,617,263,372,927,787,328,28,204,893,446,276,397,908,474,735,70,579,371,224,568,39,600,315,349,730,642,831,286,964,775,636,220,642,899,684,400,70,566,405,752,129,747,60,11,423,58,296,596,462,782,507,505,643,198,967,154,495,818,194,387,614,457,192,598,145,505,773,984,891,276,737,332,545,330,289,580,597,368,469,61,685,793,443,833,999,374,192,415,195,144,195,570,880,839,304,908,785,19,95,501,693,377,279,934,23,824,384,538,703,428,724,694,294,263,620,505,871,933,356,64,257,332,742,833,272,157,214,406,237,861,717,818,517,569,962,969,322,143,758,88,690,497,271,231,363,347,200,378,45,36,396,333,250,13,881,790,950,244,70,913,319,261,975,112,104,156,75,295,956,588,447,31,260,493,406,864,443,228,400,227,694,47,844,87,923,604,557,557,592,75,423,460,413,115,598,771,868,248,648,759,336,579,365,262,487,73,247,863,702,924,203,105,859,814,428,481,208,205,560,502,351,196,654,723,453,654,781,41,578,246,841,681,824,39,430,921,76,148,104,275,541,955,872,480,701,465,154,364,974,444,483,444,288,534,769,512,784,112,714,287,361,214,476,811,440,427,446,968,790,820,698,449,927,236,271,778,491,75,558,766,580,288,516,809,663,659,282,93,115,785,575,251,935,424,540,871,647,322,352,354,380,669,282,309,265,637,632,917,935,210,799,162,481,33,388,1,529,76,988,936,274,532,385,63,928,755,505,787,236,87,520,33,127,540,145,864,587,123,391,40,671,273,890,523,973,223,463,701,844,739,353,444,716,152,43,674,278,740,393,948,733,345,741,50,746,976,221,525,570,892,174,457,309,131,171,289,921,45,586,47,513,597,114,85,816,255,656,249,391,581,726,403,876,734,255,2,711,17,105,298,742,332,306,184,624,813,608,211,380,127,961,405,670,31,10,406,668,693,598,994,891,855,441,892,57,649,70,698,340,865,60,492,106,78,588,467,438,576,420,898,945,143,867,405,206,932,369,598,583,382,958,402,193,112,787,459,124,710,611,454,403,81,367,787,633,945,664,665,954,309,200,410,292,265,667,223,60,23,931,536,525,790,489,325,974,756,993,38,733,302,192,239,509,928,885,197,80,845,596,819,671,111,962,202,141,469,807,107,562,741,781,329,925,974,367,872,43,403,925,732,434,294,848,216,457,833,256,351,809,0,860,112,803,200,634,816,822,552,957,476,381,927,225,957,842,622,70,136,474,17,73,619,943,505,192,645,184,353,602,327,922,735,715,879,474,426,733,732,981,303,518,859,372,622,144,838,267,637,534,631,992,362,322,484,53,299,242,180,373,337,236,455,645,456,366,725,757,772,491,539,699,68,902,936,475,447,59,249,810,810,810,658,549,913,937,406,932,652,311,706,61,690,820,657,323,544,528,711,893,953,879,943,682,361,132,424,598,869,354,720,411,880,890,495,366,876,656,309,850,519,134,926,757,943,837,762,902,718,211,71,651,15,11,304,931,753,96,267,138,939,252,368,663,468,637,638,645,826,224,206,539,94,106,330,464,368,225,467,280,63,858,671,523,652,692,860,213,698,441,727,753,632,45,665,28,472,60,675,733,50,713,668,211,607,158,233,151,697,337,354,563,748,273,427,32,373,596,730,840,521,208,82,314,11,527,375,591,198,656,559,891,680,75,965,700,195,861,119,900,625,584,608,188,799,500,66,170,774,556,38,825,267,592,67,106,42,622,88,333,796,529,185,898,403,380,643,41,995,49,617,739,466,453,749,755,845,459,683,60,749,424,324,242,33,200,349,750,322,22,433,6,812,819,200,720,692,147,143,420,648,85,23,666,78,493,317,676,465,919,412,350,753,135,911,586,952,435,260,827,206,211,52,274,298,389,882,122,141,586,427,149,192,24,582,802,232,981,498,451,853,961,817,255,99,823,252,366,466,966,468,953,434,442,397,799,198,747,692,150,416,697,180,561,761,275,655,428,488,620,605,453,388,83,788,243,243,453,263,715,192,433,82,512,405,37,886,131,333,513,901,845,476,596,664,972,112,688,747,385,102,862,104,322", "689,399,608,726,620,910,353,115,724,994,197,782,147,542,841,202,720,874,100,59,861,697,675,893,699,738,238,134,282,758,584,948,544,937,429,761,499,292,140,377,682,257,389,279,648,911,257,986,662,344,719,103,211,106,120,536,420,508,162,28,493,220,111,488,764,604,720,63,74,486,428,951,250,51,725,795,564,966,407,878,224,461,649,430,514,654,673,969,55,306,766,499,475,643,195,991,556,639,651,733,521,354,985,434,281,108,680,866,737,559,819,152,384,940,764,325,708,530,142,420,479,847,459,297,738,663,422,435,352,217,467,52,219,204,380,734,195,388,823,563,621,377,42,490,378,674,891,663,308,464,937,224,786,808,568,746,465,414,693,415,175,481,459,283,415,903,72,958,370,498,409,879,314,777,596,882,40,828,210,257,983,704,561,997,584,202,678,776,626,750,970,875,779,695,891,96,437,507,700,247,559,721,519,66,741,834,718,512,478,132,483,680,734,244,948,698,55,769,36,783,457,798,846,88,665,761,144,690,166,269,751,497,599,894,78,17,188,355,736,813,108,40,72,833,169,185,412,222,47,842,870,273,49,902,675,694,86,425,231,959,607,797,19,315,305,169,602,576,549,96,550,526,325,910,691,98,736,764,660,815,58,95,123,18,357,891,24,548,404,956,198,896,393,122,733,962,507,881,738,912,997,359,535,558,6,309,228,260,75,51,18,463,726,384,171,741,18,870,775,587,20,666,315,768,456,930,884,636,869,571,564,31,327,228,18,855,899,5,534,892,903,798,552,725,596,595,36,866,921,229,370,791,690,183,981,570,594,443,49,271,396,673,931,837,94,607,872,276,659,256,573,830,533,936,867,917,268,516,801,443,128,479,487,558,661,780,64,667,341,788,339,372,127,395,152,244,797,676,763,721,845,932,832,211,810,392,669,619,259,175,689,798,11,118,320,575,434,12,172,174,996,511,583,212,473,962,336,68,86,793,801,69,141,8,71,69,906,8,788,303,457,777,680,928,757,290,21,910,93,116,466,867,331,782,135,875,426,879,871,61,45,659,601,690,95,309,277,601,614,349,901,338,571,93,675,533,46,583,996,156,210,917,818,116,147,973,766,763,740,479,599,763,944,844,771,829,961,5,750,560,117,708,57,887,46,954,764,697,370,550,456,399,282,95,230,645,582,320,100,917,744,699,205,752,191,794,577,891,534,576,733,398,1,512,41,372,637,80,938,449,30,707,461,572,467,868,971,907,678,9,480,409,390,53,943,993,445,994,54,879,508,332,850,25,51,873,707,648,395,705,532,954,298,795,265,495,165,246,110,181,875,462,999,931,239,929,676,403,504,31,937,728,787,769,157,860,496,608,60,341,824,672,594,150,712,926,742,474,831,316,208,744,237,64,295,849,860,0,882,202,252,271,767,733,778,793,593,926,295,604,428,839,690,694,691,937,131,646,881,657,973,60,419,883,738,35,795,910,422,148,261,603,846,287,266,826,581,499,989,270,628,243,929,778,803,496,3,646,637,944,329,247,157,965,193,772,964,585,953,864,476,275,547,205,86,968,328,285,555,502,846,681,803,261,879,62,90,85,738,392,831,451,899,569,745,604,724,406,616,732,74,412,448,459,690,36,6,170,380,632,63,322,777,670,625,950,987,423,334,430,746,459,724,24,635,787,106,317,362,886,61,992,30,720,781,903,909,60,388,124,51,236,624,757,780,420,179,61,264,557,580,451,545,927,586,448,61,359,625,906,418,323,846,393,293,120,55,90,59,104,383,544,387,712,222,214,164,323,974,785,92,976,94,679,109,686,425,996,368,465,551,163,445,13,15,298,536,806,931,541,858,947,486,313,624,564,343,833,22,412,745,306,165,270,496,87,135,217,545,997,914,652,411,568,218,251,341,811,381,147,229,474,960,743,418,186,688,244,641,238,336,712,922,134,118,892,23,387,447,73,256,241,316,406,759,429,16,262,80,804,797,747,27,632,424,477,879,786,216,465,721,888,239,435,273,802,726,826,841,44,507,284,731,498,135,530,67,220,485,238,949,631,375,220,654,782,740,211,290,616,236,244,668,867,999,491,685,631,899,250,543,574,190,779,905,754,177,707,812,792,471,976,338,607,710,91,637,744,339,292,69,467,40,853,764,546,239,800,132,733,17,691,222,621,801,413,425,654,25,557,918,611,41,100,125,365,964,961,791,785,678,386,339,353,445,182,964,281,885,601,291,217,284,469,289,41,73,651,90,534,900,270,473,837,772,179,811,155,184,988", "778,956,28,301,287,834,224,226,916,902,56,355,669,523,665,665,392,389,25,820,684,357,315,247,593,995,997,557,834,967,106,248,562,865,830,759,127,337,420,79,149,403,602,433,983,338,170,248,84,922,587,836,377,139,879,190,515,264,740,263,216,837,263,754,950,152,788,288,408,256,638,435,834,321,569,549,250,302,458,692,599,424,507,643,653,271,489,47,334,287,524,716,89,110,71,197,461,838,660,289,394,573,872,703,757,284,615,383,139,368,262,275,581,988,897,686,175,284,442,193,400,261,796,961,880,966,114,568,721,823,262,873,589,11,519,703,590,902,790,456,79,289,504,10,422,78,812,978,457,497,498,888,666,3,530,148,33,577,26,731,271,500,959,907,560,938,524,260,887,18,740,418,376,434,2,512,635,208,439,155,432,201,741,897,504,204,484,212,395,18,668,577,754,352,57,768,380,860,466,908,884,146,492,879,537,777,477,825,103,749,745,353,19,124,321,175,318,263,780,910,605,888,120,627,743,165,91,770,574,181,711,38,831,138,924,511,244,16,632,845,61,416,969,417,168,709,559,975,37,681,344,575,401,258,957,204,5,773,198,790,907,228,495,683,477,798,667,36,88,523,702,110,962,140,498,164,237,433,726,972,436,280,513,153,875,117,727,702,492,674,582,958,259,776,702,66,580,834,998,869,103,765,999,535,519,641,329,464,391,272,937,119,805,896,513,788,514,480,714,194,784,65,562,370,254,269,8,771,566,176,726,938,951,134,754,852,940,705,614,898,593,933,474,828,496,260,39,464,499,237,272,40,316,329,422,3,606,224,645,862,170,781,168,961,911,435,597,549,167,965,299,55,817,550,243,201,747,229,646,22,931,53,269,942,620,688,334,210,411,693,845,262,443,872,592,681,544,131,726,977,127,385,962,233,259,829,598,385,12,850,10,338,108,702,451,315,102,792,710,971,740,535,447,409,648,448,233,213,771,379,348,132,966,65,832,284,371,935,993,430,488,694,502,665,519,230,897,215,561,438,461,241,202,164,174,473,567,575,257,597,458,693,195,928,518,234,222,159,929,288,13,376,616,902,445,102,251,109,785,847,511,967,904,385,743,721,650,165,424,869,14,498,501,234,707,243,55,399,801,732,499,724,610,142,460,610,390,470,848,606,801,945,312,107,975,731,659,955,55,307,996,61,561,57,717,698,708,226,515,986,462,968,180,687,445,608,244,987,248,441,435,285,555,634,952,176,568,281,155,714,85,108,482,24,422,589,388,624,437,554,502,268,953,281,527,354,240,488,84,989,990,707,898,710,770,348,377,796,319,29,177,369,814,915,161,216,694,947,283,280,862,516,561,425,943,211,839,896,355,655,524,261,360,919,799,126,942,586,82,775,954,884,251,682,998,628,112,882,0,183,204,572,358,838,779,128,330,387,560,979,853,595,201,598,672,65,721,38,771,338,699,586,413,770,162,638,13,191,417,161,520,432,525,407,84,806,209,93,748,825,571,767,875,611,769,550,598,940,803,74,317,812,961,405,401,922,790,543,568,641,22,100,98,67,48,194,636,800,932,473,420,714,976,477,749,651,671,185,606,210,494,453,191,290,115,468,322,528,407,793,939,730,92,274,564,622,451,870,501,819,42,391,454,41,304,189,123,395,329,887,258,754,975,541,102,15,150,672,781,821,738,607,387,348,691,900,530,225,350,756,303,870,768,28,405,210,203,430,477,837,625,889,781,491,287,816,754,70,258,376,682,916,574,14,793,652,849,181,935,192,616,444,759,633,875,281,252,807,351,125,732,552,442,616,805,311,699,13,746,644,650,725,334,976,538,454,947,763,256,534,716,415,373,414,245,171,677,272,966,927,28,974,362,63,86,276,340,392,970,796,861,567,74,392,302,579,584,511,444,49,309,313,854,933,488,19,427,631,389,906,456,82,139,362,615,997,99,777,208,634,240,825,860,19,326,927,497,637,936,255,786,35,377,195,383,284,754,297,779,77,783,865,337,593,271,354,855,835,983,608,505,781,495,194,990,930,486,205,745,628,724,577,875,99,989,535,527,367,304,897,370,187,416,993,678,460,312,810,171,214,993,10,79,21,700,114,945,29,745,909,235,731,873,983,980,147,292,423,956,961,470,369,721,242,327,981,729,970,481,809,505,321,43,473,502,107,263,571,567,213,386,974,134,615,503,840,690,580,584,610,958,31,268,319,361,461,961,259,896,578,702,407,98,265,965,475,128,80,150,84,427,939,540,752,703,245,326,843,173,46", "983,210,318,895,178,181,468,983,513,899,960,771,256,243,632,70,231,619,147,502,190,456,927,728,978,869,940,383,826,416,564,585,899,315,552,372,465,530,153,208,750,710,21,446,896,804,794,3,407,996,357,31,647,178,192,747,203,399,566,536,166,654,501,713,580,127,634,986,561,571,552,692,579,824,862,183,695,543,21,783,410,12,54,522,338,965,919,672,813,408,497,559,814,641,954,161,732,940,659,642,448,465,100,412,248,758,920,117,377,507,322,503,95,541,248,884,299,446,629,619,556,453,631,109,213,263,361,436,459,253,170,723,118,342,802,4,423,25,677,518,275,20,923,769,152,83,595,414,36,305,262,621,915,680,445,769,920,9,715,744,288,739,963,93,817,29,328,355,580,334,901,406,23,59,468,979,877,401,435,613,680,475,995,508,793,73,397,657,153,341,740,65,493,189,325,69,610,894,414,413,319,219,80,537,774,663,392,23,330,48,248,6,260,343,859,89,24,507,691,247,619,269,987,677,979,463,461,830,797,308,859,796,627,611,779,615,704,788,247,486,797,354,120,710,957,878,221,523,87,667,726,554,88,231,216,368,9,853,526,394,234,193,343,405,425,938,284,909,392,858,178,284,673,557,283,190,37,879,35,755,245,790,805,625,638,128,342,424,941,924,133,131,814,466,232,260,58,33,764,481,297,661,911,426,965,591,950,472,232,413,891,637,893,556,690,425,200,508,194,625,319,954,945,369,727,877,826,956,403,37,688,252,485,408,227,622,630,372,881,256,612,343,485,714,533,577,379,704,118,169,896,738,482,563,602,613,284,635,251,424,631,372,781,472,554,508,122,52,929,857,239,290,684,969,82,921,29,265,53,907,637,793,186,661,612,31,424,311,797,761,606,532,215,603,469,359,959,467,142,771,746,860,284,369,850,245,924,946,390,797,538,274,652,879,87,239,287,454,836,427,125,54,264,895,23,23,914,732,32,394,554,59,311,430,16,755,196,620,97,35,660,647,866,297,359,925,446,160,471,785,112,901,438,104,537,622,900,256,118,175,813,711,609,64,344,100,178,952,339,375,862,490,446,833,455,63,353,856,521,369,520,785,983,874,112,550,691,847,188,265,501,992,692,472,241,44,417,21,204,934,604,530,523,90,873,680,911,409,711,206,616,107,983,754,555,798,898,291,958,973,385,878,154,597,527,922,693,864,861,241,447,400,742,518,351,289,273,28,230,493,955,655,965,396,745,297,268,898,454,564,352,157,133,429,422,955,121,301,356,288,697,141,889,826,314,735,470,635,331,909,183,984,227,40,657,541,896,576,20,586,250,679,577,570,98,346,933,386,621,906,294,551,579,915,291,474,204,311,815,977,691,366,148,868,521,332,301,244,199,874,131,574,26,515,346,614,803,202,183,0,1000,927,187,639,416,761,795,317,894,32,79,640,896,461,90,309,768,631,59,598,817,643,215,18,98,509,546,504,98,28,137,83,323,321,51,310,724,86,255,334,534,338,52,512,748,499,608,164,357,382,552,438,770,834,299,991,795,72,932,532,372,446,475,139,619,653,659,362,362,303,824,237,305,989,371,739,355,583,47,815,105,700,755,709,577,973,766,975,654,457,180,962,460,15,615,576,771,296,977,187,179,925,339,65,756,263,702,919,704,275,110,821,102,473,158,292,368,767,287,847,370,102,918,830,870,645,797,853,798,569,569,614,760,937,51,560,648,162,811,590,562,782,454,704,441,670,16,899,612,607,745,280,747,499,823,481,902,679,233,196,622,326,340,747,551,131,147,826,108,7,656,870,652,902,591,582,837,291,712,628,817,672,621,224,262,815,908,607,764,977,938,953,169,881,886,247,968,327,644,639,720,443,429,831,907,49,411,460,931,455,874,398,82,142,908,5,119,615,213,621,924,271,887,143,883,655,730,15,698,254,584,81,54,736,932,255,587,140,103,279,304,807,201,766,655,199,4,680,72,585,234,975,961,89,12,880,601,936,244,475,297,672,475,918,230,252,267,774,402,47,509,302,174,515,655,408,21,580,930,81,471,451,811,532,514,245,573,614,683,60,992,117,830,721,252,762,182,164,790,49,737,595,924,555,791,492,671,681,352,423,897,653,911,847,680,831,405,44,989,487,84,563,131,223,50,145,180,730,282,977,462,194,522,37,128,166,704,807,692,698,323,670,219,839,34,795,698,743,7,987,721,529,914,236,383,947,890,495,248,634,99,370,680,387,598,386,859,774,87,32,351,657,695,963,134,119,750,795,858,266", "201,290,326,295,803,348,914,481,758,116,330,275,318,382,771,843,512,125,349,594,688,121,325,420,655,166,369,979,660,386,221,895,117,861,875,58,705,748,405,236,874,210,748,285,684,908,808,870,338,430,563,976,305,868,321,558,948,806,704,652,194,588,688,989,692,870,77,40,874,7,289,619,524,67,690,738,780,211,578,550,176,555,69,9,412,467,675,709,346,260,970,936,110,727,855,926,293,66,274,108,32,334,749,27,813,242,918,73,494,860,885,348,613,164,290,924,15,441,327,592,982,531,627,865,946,263,499,886,8,716,23,208,217,83,268,864,282,617,523,718,341,522,80,434,614,96,56,776,439,493,303,954,699,400,165,574,680,254,93,48,174,875,727,930,515,942,757,55,263,623,330,186,803,815,366,603,9,240,224,432,758,745,834,471,938,902,515,96,162,206,925,926,982,903,627,227,628,611,731,722,943,360,466,880,365,660,414,118,839,517,962,703,999,364,922,491,417,949,759,983,775,434,955,67,779,893,808,214,393,511,329,427,164,45,744,259,641,415,593,927,865,147,936,729,734,31,425,720,373,391,781,483,231,642,12,261,405,429,959,796,889,428,654,294,545,863,368,645,996,885,260,56,990,936,721,949,187,287,989,74,464,567,279,808,549,188,692,596,297,140,813,336,1,993,746,697,362,874,757,771,816,832,79,302,337,45,20,129,550,834,745,494,908,30,435,405,406,84,589,319,931,114,938,101,13,811,28,596,844,588,675,695,778,106,316,595,565,358,418,518,31,43,794,851,468,420,788,372,74,607,232,103,513,657,126,973,63,641,393,105,237,895,224,173,995,829,742,880,458,632,904,578,807,515,938,861,851,695,983,203,592,82,166,401,98,700,273,476,208,706,775,777,273,419,519,660,36,218,695,441,837,561,927,902,974,883,278,957,364,962,53,917,827,231,628,569,836,342,981,20,247,423,882,426,119,771,352,843,104,166,363,275,123,411,550,803,158,457,506,675,278,975,713,818,254,591,986,399,433,113,733,308,757,780,514,520,665,588,958,557,161,391,953,872,530,104,488,350,112,228,344,906,76,176,152,189,887,229,664,417,463,1,442,328,764,235,377,164,341,192,896,399,388,423,945,127,55,685,499,930,182,487,467,376,452,958,961,693,521,273,42,886,823,472,283,388,525,421,980,608,934,890,209,185,776,659,449,6,671,202,220,100,331,455,73,631,52,54,545,432,430,685,172,465,34,415,220,942,110,527,679,576,774,184,732,325,39,887,513,174,77,62,981,108,235,364,254,365,281,757,321,193,405,637,299,116,847,435,403,472,617,519,690,280,215,138,586,459,749,833,623,205,396,874,255,205,546,988,512,110,758,237,72,66,455,86,169,225,385,137,365,720,747,979,662,786,200,252,204,1000,0,442,742,866,407,951,589,720,73,402,840,746,965,787,444,615,276,212,436,153,730,95,770,644,442,322,172,892,623,797,296,313,195,907,284,113,70,446,129,679,801,480,524,709,588,789,108,996,740,793,896,539,397,271,661,844,697,70,135,410,548,607,236,223,405,609,8,590,592,861,859,623,718,800,949,169,781,128,846,696,688,360,899,257,237,676,497,486,362,744,828,484,757,562,407,675,599,597,818,598,139,104,71,664,770,970,612,390,335,342,663,664,893,585,159,655,890,60,921,979,286,258,729,389,150,612,218,419,840,387,247,560,114,645,36,626,44,536,447,269,415,864,695,387,259,794,618,134,936,499,543,877,986,812,574,668,657,530,590,184,152,174,93,730,390,700,962,972,831,583,752,590,627,476,330,599,737,706,510,54,17,62,658,999,507,809,380,627,728,943,127,659,582,61,4,797,397,380,282,124,83,38,873,371,501,141,697,421,122,837,491,259,563,184,799,923,453,209,821,771,328,607,320,985,418,641,201,327,652,821,25,660,35,889,264,921,985,791,809,888,371,96,713,739,652,645,710,970,28,618,324,898,790,38,232,886,914,219,313,265,918,107,577,85,835,931,841,562,283,846,449,29,637,476,108,917,701,505,75,796,91,90,114,125,4,326,491,413,118,896,907,77,303,409,84,287,116,505,809,57,820,146,538,463,798,909,430,328,707,950,814,484,129,666,115,579,59,181,148,338,462,309,552,47,804,602,967,150,321,549,992,130,852,275,802,89,710,414,368,651,117,713,971,679,958,517,941,137,703,860,745,408,542,295,487,876,717,64,248,600,587,876,500,288,360,911,603,637,21,975,986,987,494,910,266,234,586,640,438,53", "195,117,928,810,153,372,910,672,766,90,228,409,105,144,541,314,340,732,606,278,735,222,8,15,245,604,351,105,621,742,915,238,354,456,947,511,152,737,540,6,412,206,25,405,670,510,328,598,789,999,830,443,405,306,466,285,105,112,71,867,889,721,129,144,330,33,314,717,482,979,253,840,949,350,862,159,539,904,953,525,804,355,772,663,624,509,493,654,588,986,823,64,542,640,693,50,775,597,859,462,883,902,681,480,67,468,929,462,781,783,5,483,34,401,474,422,165,966,268,342,499,572,60,569,578,139,64,958,413,519,26,712,181,753,563,192,964,44,622,694,632,487,272,813,714,377,952,467,231,487,126,254,430,196,589,491,270,424,804,378,484,599,201,984,861,337,913,637,8,632,165,211,636,708,626,674,384,716,574,200,886,678,360,359,797,439,633,127,82,710,224,451,389,343,343,940,457,322,712,52,604,647,858,933,635,268,884,660,849,105,209,485,899,463,894,477,458,572,109,330,641,52,699,599,2,266,518,303,697,369,954,858,91,840,191,615,277,960,24,129,870,711,765,893,166,119,455,274,925,491,6,465,864,658,189,121,749,575,808,515,547,54,745,894,78,403,819,843,196,719,478,896,899,651,187,537,786,394,344,134,702,936,814,385,144,637,949,27,282,54,290,638,517,564,478,124,885,536,112,39,231,258,669,599,376,522,789,573,291,31,600,945,430,540,454,640,114,801,714,706,512,998,268,243,65,676,86,891,664,223,537,255,341,403,161,458,861,916,340,597,915,923,462,873,93,628,969,343,788,935,832,679,10,541,717,138,527,613,600,347,306,507,245,135,238,178,877,9,828,185,766,762,999,153,868,244,858,693,784,853,896,675,122,907,394,326,417,764,891,848,340,131,773,622,44,252,20,186,942,384,574,240,909,885,753,907,298,200,958,681,514,334,930,996,446,57,322,426,318,998,158,784,847,977,207,754,215,751,681,682,436,445,121,30,255,924,353,322,78,734,660,226,639,663,729,970,52,415,95,290,205,835,21,232,157,574,275,428,870,477,206,254,485,510,839,102,860,856,7,582,939,228,922,727,609,629,240,314,773,913,460,135,864,422,993,178,563,834,842,116,841,787,304,849,331,410,990,933,836,284,211,497,4,944,124,404,181,588,684,22,143,722,583,105,531,694,3,790,453,218,9,266,33,350,516,892,577,946,750,465,348,210,928,124,280,558,854,366,119,678,838,335,702,886,421,5,35,25,379,343,73,925,747,892,328,806,763,945,574,64,600,110,41,319,50,942,160,14,572,338,444,346,870,334,934,545,281,241,106,425,724,707,652,100,825,375,478,889,306,286,397,359,875,100,299,115,277,91,718,639,697,513,92,990,753,805,563,470,101,145,643,604,169,262,837,966,634,271,572,927,442,0,296,184,539,399,502,87,218,691,419,441,297,527,122,442,937,847,623,807,437,746,184,440,458,318,856,100,321,141,520,861,62,319,173,653,498,537,911,709,860,686,319,895,645,892,349,554,549,916,944,471,123,372,894,362,357,241,660,38,827,399,810,268,434,858,790,500,275,762,14,831,73,873,73,413,699,528,559,127,924,550,496,419,773,582,571,994,907,185,294,664,419,30,30,307,608,938,679,409,450,229,278,396,739,368,125,222,707,747,158,985,467,641,144,56,221,522,591,831,459,917,750,329,678,375,801,330,154,669,374,79,993,240,834,355,844,911,771,315,833,869,316,566,43,105,488,853,365,688,627,571,866,967,261,709,307,391,509,311,167,691,562,627,126,73,588,357,115,175,491,691,434,417,71,909,353,244,299,144,719,391,199,386,877,503,797,363,29,472,114,537,368,459,40,573,136,254,716,815,426,304,645,163,311,155,396,623,915,463,250,538,539,514,147,171,739,993,350,763,918,665,728,688,488,75,620,436,533,628,963,667,268,416,973,585,659,504,937,744,392,311,325,493,638,120,832,908,980,408,671,720,827,809,68,330,733,822,919,795,897,510,116,471,43,396,857,200,818,624,541,114,811,117,106,363,436,951,200,619,55,738,862,627,421,386,521,948,395,160,90,970,9,205,828,725,790,402,331,73,58,384,601,931,146,402,140,85,353,779,265,974,603,472,932,530,2,195,219,731,69,996,914,49,651,400,127,619,605,327,202,864,751,297,715,307,201,14,734,479,591,377,138,223,890,503,445,17,363,36,952,61,780,818,127,702,124,966,350,24,596,257,215,530,441,363,651,315,792,211,763,290,541,238,757,877,888,530,703,461", "905,878,330,239,696,213,885,120,894,543,556,723,214,975,746,103,132,902,865,793,517,964,209,594,919,662,655,522,577,801,760,743,626,816,272,302,511,44,266,811,967,182,410,898,559,710,691,727,269,737,500,425,450,909,532,70,290,285,923,231,610,248,980,247,325,783,107,367,609,822,88,77,271,79,307,412,603,256,55,277,656,414,281,858,844,371,886,99,154,879,109,798,773,8,549,653,247,128,590,83,783,44,780,51,835,991,962,36,995,681,75,303,458,170,177,793,582,557,509,451,303,110,392,979,343,930,541,60,372,178,302,274,187,191,304,361,725,137,385,924,169,285,501,207,362,643,909,661,897,255,971,188,38,888,762,378,28,421,555,3,857,867,104,892,12,441,938,710,328,837,692,97,695,210,903,860,584,5,880,703,385,688,911,736,298,955,857,865,830,356,480,782,792,286,798,131,487,929,224,576,217,957,719,977,933,887,186,727,365,917,184,416,559,729,817,615,690,721,336,54,588,616,618,303,759,636,291,970,175,581,545,767,145,853,974,440,986,829,785,667,178,550,652,773,719,472,993,34,152,355,62,484,340,356,324,9,831,291,342,957,962,678,763,117,814,17,311,398,336,933,669,543,834,817,585,225,207,355,720,519,407,968,788,473,816,272,190,319,157,829,669,26,716,969,422,820,902,857,886,109,594,2,155,96,968,145,154,48,867,67,147,425,325,143,865,333,731,124,311,481,206,120,132,153,521,821,898,127,809,658,154,278,598,201,749,593,246,101,448,563,937,177,416,246,559,958,437,902,686,372,65,295,780,886,743,71,966,19,423,697,845,704,969,226,389,908,2,302,665,942,103,280,574,223,513,715,519,621,945,312,573,338,710,60,611,348,429,579,583,949,126,697,399,846,580,577,756,792,678,736,372,258,407,677,182,254,620,501,917,586,110,173,941,388,735,988,245,754,908,639,350,781,931,725,945,526,588,244,663,374,750,208,562,968,403,696,81,98,844,691,291,137,465,323,962,237,853,503,93,984,758,960,443,840,690,712,191,649,216,727,148,118,926,816,311,388,895,694,155,787,161,557,98,444,413,100,745,334,116,635,716,438,713,658,92,809,723,936,221,626,903,270,727,711,427,212,737,200,879,421,456,701,794,471,464,47,141,995,505,275,456,486,566,783,733,284,999,789,580,119,305,390,891,571,330,511,974,873,136,168,625,616,845,981,812,416,156,455,230,801,663,237,932,38,992,142,999,316,941,456,804,713,480,586,324,432,93,46,836,522,865,417,830,916,724,421,926,747,677,491,38,424,811,86,170,457,31,226,849,368,95,552,90,16,817,700,630,928,509,538,155,912,957,251,314,393,557,685,790,724,303,918,363,11,304,778,190,82,280,708,511,150,982,677,39,920,816,767,358,187,742,296,0,825,856,142,334,333,459,733,391,855,190,54,400,834,956,517,653,452,508,417,853,948,563,49,782,529,594,976,311,520,924,57,39,512,957,502,246,608,164,360,872,734,221,283,491,420,415,206,836,578,952,348,868,624,168,872,492,415,518,13,963,624,455,9,529,481,991,482,216,268,281,210,563,569,703,422,396,67,940,377,886,73,306,90,860,300,150,217,199,641,414,129,409,968,840,785,618,826,79,760,667,22,425,629,95,122,436,159,602,404,83,277,651,23,640,144,788,360,598,293,858,344,430,725,943,102,146,180,861,480,93,398,681,692,830,604,701,27,436,533,257,214,603,626,730,819,677,757,288,802,62,703,428,553,627,501,890,933,798,125,533,948,271,167,208,897,659,358,135,481,864,29,333,225,974,180,998,511,100,257,488,402,405,197,721,367,367,298,197,794,773,36,449,99,323,401,413,549,348,147,589,676,37,241,720,456,203,358,439,193,222,715,882,536,583,947,62,482,351,386,40,176,301,228,979,890,578,696,714,636,634,87,411,188,230,655,639,455,412,700,152,823,36,843,160,780,139,484,232,50,870,166,211,843,235,950,883,840,194,420,330,353,728,608,921,334,350,421,396,579,158,512,783,583,293,139,931,238,512,208,654,400,22,315,555,787,336,222,109,821,500,296,335,807,738,636,737,846,795,381,617,236,87,604,331,27,681,465,265,445,100,237,865,761,804,731,838,718,96,346,828,774,660,706,110,350,559,44,306,103,419,326,215,724,903,123,781,581,761,486,458,774,588,986,638,13,214,584,154,149,609,496,337,416,74,961,405,189,445,423,954,317,718,318,13,591,725,781,941,324,107,923,129,803,830,271,798,829", "670,725,987,528,80,48,11,18,541,821,994,183,174,109,729,308,703,704,835,702,850,431,346,457,338,483,8,814,39,307,635,590,4,577,329,895,758,812,643,282,200,140,306,257,375,190,889,325,830,827,928,846,644,982,652,76,787,582,852,120,899,801,990,34,83,237,231,258,791,250,606,36,97,267,895,944,978,880,811,605,445,566,346,477,456,923,886,822,562,336,350,117,145,409,561,23,958,955,463,272,943,836,653,157,216,427,986,806,518,852,261,591,101,106,691,851,959,348,192,579,199,546,666,989,502,200,618,268,292,180,821,886,257,737,127,679,3,435,800,301,753,711,614,153,634,536,292,788,793,450,799,603,965,428,776,600,488,345,784,532,934,5,665,994,779,346,804,402,295,562,149,670,917,417,967,198,768,300,623,904,517,138,242,660,475,285,339,763,879,605,704,303,175,953,16,744,542,69,156,354,412,754,784,402,930,116,650,600,702,29,563,42,778,752,909,19,390,52,120,308,511,26,806,346,852,236,25,720,72,888,904,88,642,326,199,528,300,486,824,240,61,903,147,151,951,600,841,770,746,884,699,819,519,57,588,472,373,902,452,447,858,246,384,987,652,654,965,221,632,747,678,834,998,199,324,919,359,973,466,345,416,81,375,247,883,942,346,909,508,31,563,408,94,927,10,962,656,818,680,239,597,177,216,747,397,570,496,737,393,110,457,382,125,940,118,636,470,991,299,664,630,617,251,593,697,687,576,899,877,598,470,73,882,266,288,769,901,711,343,342,119,198,652,619,222,473,224,873,794,628,705,725,282,192,88,331,80,461,26,469,284,504,185,25,155,402,427,737,282,438,602,333,956,83,667,406,90,370,690,886,25,308,603,34,244,212,327,279,109,208,789,43,455,562,441,415,473,315,973,639,773,553,214,878,421,170,871,856,224,591,416,320,42,752,944,718,592,932,3,934,199,879,338,83,466,730,304,75,875,918,279,455,676,429,4,493,833,636,521,514,794,273,66,799,250,896,810,327,475,793,128,88,286,209,51,136,30,203,251,209,965,189,880,976,702,258,948,464,423,433,527,218,401,797,427,128,69,858,338,259,433,822,377,197,841,904,832,454,810,494,831,293,199,962,235,204,431,914,36,663,22,718,245,402,79,309,254,62,375,465,707,925,492,715,252,8,188,426,200,357,571,931,846,636,975,204,731,711,161,431,14,957,426,8,573,505,667,96,35,205,86,534,247,218,197,226,539,686,545,206,358,31,442,439,843,829,629,841,480,271,110,831,728,211,692,995,703,427,194,466,225,409,533,399,931,664,981,978,893,640,947,586,976,664,848,624,91,400,535,273,103,409,728,952,960,530,564,70,852,665,276,466,988,52,835,813,470,334,401,466,327,158,901,509,327,593,822,733,838,639,866,184,825,0,775,785,386,707,247,740,662,709,622,518,93,819,356,472,993,516,706,967,131,720,710,898,851,65,810,974,797,739,517,367,477,93,448,172,686,852,99,653,269,570,166,721,939,764,8,351,18,749,809,441,253,406,184,957,287,650,475,626,766,249,508,866,778,699,625,609,449,890,878,576,700,615,784,996,408,83,727,111,593,36,253,198,196,291,279,111,729,987,734,482,53,171,591,310,55,56,320,974,814,319,281,661,979,448,691,839,698,114,273,124,951,627,76,253,77,165,474,679,871,295,687,108,367,888,288,636,308,731,293,337,949,274,983,682,38,711,769,600,900,171,733,739,166,317,980,219,84,119,676,67,115,894,664,257,323,370,277,256,867,386,289,415,653,410,322,914,181,768,231,674,834,104,398,692,844,386,161,49,798,618,739,548,332,137,614,864,868,611,720,927,76,550,136,619,280,307,9,225,759,340,304,347,159,362,874,563,702,507,629,435,180,461,51,362,151,691,217,436,782,990,212,390,520,769,848,987,403,671,612,391,722,970,43,328,98,996,242,778,166,144,143,197,411,31,168,300,928,291,648,809,731,683,743,614,306,289,176,382,149,72,991,272,842,681,224,802,227,547,668,978,890,215,742,257,142,840,587,890,11,255,826,333,844,644,900,119,221,924,549,58,32,983,24,755,139,478,953,616,676,931,431,829,81,193,725,806,375,425,563,885,335,483,574,483,649,381,912,748,326,171,644,99,90,933,839,998,961,878,885,443,161,197,242,647,550,922,857,382,539,839,616,120,837,822,81,345,780,776,75,475,648,867,110,426,907,918,966,624,651,281,151,597,182,820,982,879,27,488,137,31,427,994,152,96,777,892", "313,758,173,531,791,903,85,750,793,211,211,481,381,919,590,67,350,344,885,357,457,503,848,678,270,416,21,551,283,936,35,822,898,934,571,104,395,65,486,893,797,422,600,846,156,16,775,353,30,866,18,306,171,633,822,658,741,881,305,658,799,571,824,673,461,822,601,14,27,190,137,376,278,145,401,590,702,881,894,825,157,959,685,397,670,690,173,721,720,157,967,63,318,572,608,46,277,218,808,140,103,238,670,900,572,191,67,881,499,460,146,503,219,769,51,590,567,656,73,496,548,932,364,347,538,21,409,304,90,325,142,67,966,282,776,951,896,367,949,98,589,323,277,685,597,755,613,902,968,569,31,555,499,626,70,240,634,920,741,613,251,457,758,902,630,692,948,626,885,35,950,492,912,783,47,204,355,739,970,335,371,771,843,923,309,294,592,631,84,198,913,290,158,364,290,511,10,426,975,894,294,906,639,284,771,691,98,242,502,403,82,219,299,631,930,349,660,479,722,124,421,282,725,899,747,296,170,506,949,94,596,870,173,212,634,268,481,979,746,378,671,788,75,959,896,238,601,824,372,711,977,806,642,444,560,450,607,787,212,642,984,737,262,202,932,875,581,743,511,398,211,626,584,726,512,932,379,96,110,792,953,609,324,538,9,546,303,993,574,902,881,380,828,682,589,621,740,728,165,159,456,156,313,109,565,306,310,352,159,541,675,940,259,357,371,348,906,699,688,273,706,777,194,842,114,661,657,576,651,747,905,342,985,60,65,197,429,641,264,805,331,884,805,598,753,800,235,536,172,795,905,327,784,837,767,921,525,48,958,934,319,864,342,300,336,912,51,895,167,66,51,240,845,161,54,97,124,955,103,750,888,674,8,372,686,195,330,617,297,971,833,662,741,303,35,364,739,992,278,607,28,168,520,627,267,482,867,23,333,314,618,281,111,913,409,881,652,15,735,515,560,737,132,92,623,398,406,777,86,411,248,300,131,636,81,179,740,798,530,33,936,157,436,206,631,745,937,198,694,341,484,731,237,6,992,141,235,444,601,558,972,405,396,602,528,291,619,238,789,30,856,893,727,803,561,688,637,612,206,762,33,458,556,144,776,355,269,428,256,504,537,772,360,908,46,170,415,745,419,629,974,278,398,466,230,267,263,215,616,475,858,892,377,972,82,618,94,852,953,450,921,927,588,840,715,231,963,603,969,737,348,750,817,382,9,420,801,822,542,875,469,172,205,594,767,940,361,591,652,181,3,742,596,277,506,567,992,808,217,221,87,732,741,536,968,281,825,61,459,538,508,479,456,147,375,994,612,194,715,919,170,552,839,663,512,865,536,615,412,432,472,691,993,961,602,674,912,791,130,761,545,376,708,343,986,135,415,136,423,89,720,813,442,741,855,145,552,778,779,416,407,539,856,775,0,288,160,61,486,996,929,475,663,351,944,819,351,285,848,704,708,959,743,736,845,490,48,908,65,369,121,720,317,242,262,302,498,623,554,837,880,915,679,36,631,971,403,856,603,42,81,579,969,833,322,879,626,291,654,422,278,623,630,420,999,300,729,932,763,599,972,790,247,752,662,617,296,395,989,157,868,138,681,816,595,645,254,67,102,82,122,952,858,504,706,264,671,952,228,360,331,945,579,151,906,667,177,525,241,912,829,544,646,238,616,523,221,771,467,84,46,411,954,460,206,366,706,887,206,299,416,143,346,265,251,636,418,382,24,678,373,576,491,469,75,287,701,312,126,243,117,892,939,668,638,118,565,864,37,447,461,265,438,975,790,688,610,772,457,635,143,339,624,799,838,595,258,248,514,63,105,379,421,11,967,658,925,646,191,219,646,354,150,628,698,854,156,733,276,197,304,334,493,327,427,320,848,835,30,879,197,106,722,120,746,758,199,549,558,788,752,5,342,951,234,261,282,717,176,897,137,137,752,446,477,948,340,807,288,637,405,500,935,436,352,499,78,794,941,63,92,520,418,59,679,146,761,762,918,994,519,772,311,286,709,322,414,635,735,810,189,699,355,371,883,202,985,573,999,390,691,437,64,516,858,289,7,496,864,375,752,505,738,932,123,156,709,872,849,55,975,319,261,408,392,694,905,196,244,136,915,530,901,860,258,824,357,19,249,91,66,450,664,742,231,187,807,11,754,545,76,796,806,758,131,219,30,208,638,844,244,626,850,835,181,663,959,891,805,405,996,131,454,573,782,963,182,518,372,935,364,656,432,124,159,165,711,148,900,532,127,142,761,730,325,881,592,513,667,761", "555,453,553,733,526,74,168,538,542,649,800,579,730,467,757,913,254,935,158,689,879,518,301,445,997,198,981,699,439,49,148,394,109,703,169,814,360,849,612,427,824,626,419,776,986,581,781,153,755,986,765,47,322,266,265,711,489,460,397,333,735,258,564,277,66,678,479,711,618,66,776,517,676,975,985,500,180,999,777,486,939,617,754,360,70,751,33,527,935,754,490,199,541,797,93,155,157,866,439,145,863,255,734,475,801,378,13,968,475,244,411,912,291,470,744,209,492,655,312,508,645,497,862,987,578,339,159,560,180,388,792,962,693,36,336,697,94,957,21,686,26,401,341,949,651,462,453,774,894,874,902,903,284,26,744,911,892,794,957,86,469,413,985,649,889,445,216,231,767,473,991,987,612,733,69,645,933,754,75,577,401,37,540,354,762,372,957,80,473,705,874,944,225,194,108,857,107,230,941,776,798,99,818,368,626,475,155,937,617,900,268,532,902,364,462,964,804,382,192,415,298,461,376,190,602,531,348,918,538,195,869,668,917,323,58,129,192,387,169,909,100,538,936,600,819,869,705,3,525,240,352,647,651,909,159,914,96,553,474,89,151,597,644,573,908,569,168,965,613,469,79,802,186,97,470,194,129,374,355,372,319,155,34,998,928,313,500,258,652,589,891,344,986,293,385,60,921,359,65,30,232,753,478,125,621,280,471,876,292,854,926,635,400,79,262,889,326,660,770,35,148,655,940,351,736,826,904,690,441,94,603,729,287,255,112,101,786,180,728,392,525,705,705,363,968,317,902,77,974,89,279,206,668,518,318,240,281,275,785,440,737,129,940,485,59,351,710,8,284,32,786,516,473,528,126,776,82,6,566,883,271,92,326,903,240,853,540,224,483,705,708,341,748,335,486,54,176,873,946,904,248,688,848,784,782,861,225,749,642,879,560,360,910,740,751,868,903,985,567,256,396,454,865,430,983,423,206,729,684,422,162,924,669,661,914,31,941,6,381,667,602,615,593,154,466,641,189,198,172,988,540,219,935,889,367,320,728,548,251,954,432,587,496,875,407,123,372,745,366,795,244,402,115,844,86,27,311,504,676,858,952,197,818,873,158,830,413,47,348,104,343,133,724,484,500,55,771,124,536,635,307,151,537,887,969,318,148,129,778,810,285,312,751,193,443,973,237,583,5,828,826,321,360,393,591,454,347,724,275,625,364,989,599,807,652,56,78,38,527,809,292,878,468,449,69,273,392,271,712,469,937,797,694,360,263,204,448,397,872,752,584,746,375,423,855,3,122,106,715,53,191,522,936,54,842,859,603,708,322,817,824,896,427,241,252,464,260,441,129,316,857,425,187,797,142,796,259,906,386,342,193,103,591,906,569,494,41,990,621,910,905,69,903,916,765,605,957,793,128,761,951,399,142,785,288,0,245,635,906,580,678,689,467,261,548,946,914,243,966,474,36,54,464,659,23,924,393,434,336,163,107,40,135,737,974,733,935,143,192,102,925,147,192,665,906,52,851,785,613,182,853,996,334,172,386,243,137,846,769,793,851,999,889,754,375,737,210,267,620,118,958,641,456,894,271,269,438,963,458,68,457,88,252,270,779,494,531,822,183,427,21,39,142,49,421,782,658,976,208,831,410,714,811,754,544,812,441,422,306,134,139,120,102,941,329,911,943,4,724,543,925,247,159,174,782,343,295,254,276,680,231,770,801,396,977,874,496,384,551,180,475,72,383,301,477,373,972,31,188,734,995,200,273,481,781,446,539,273,811,478,858,240,434,952,464,261,30,990,578,906,80,32,241,599,717,363,949,953,503,530,106,712,432,792,129,215,106,195,394,452,478,603,808,671,477,897,388,317,405,568,145,542,906,247,164,766,968,635,782,650,286,706,221,508,844,376,295,984,848,927,650,177,965,821,58,956,36,585,500,835,564,502,12,921,656,17,526,179,24,382,503,443,58,217,945,998,375,868,641,222,630,428,344,642,458,455,52,630,850,323,545,34,781,562,248,720,659,963,452,17,125,372,115,654,829,486,711,579,398,109,843,198,165,26,729,802,88,108,238,814,953,148,965,650,543,664,810,813,770,641,911,550,801,772,804,279,919,392,826,503,944,260,814,945,862,474,84,271,831,23,568,206,365,872,353,79,386,349,627,572,768,564,259,997,587,137,202,540,765,826,761,399,856,957,955,478,319,107,785,557,471,61,312,468,890,760,352,374,916,782,493,472,737,600,884,752,314,379,982,740,858,904,574,615,938,955,949,73,837,428", "762,652,181,988,923,969,3,756,433,562,573,966,542,435,63,96,832,736,895,959,614,651,624,206,186,971,280,979,380,33,672,644,943,220,894,50,437,196,617,297,631,937,919,535,463,804,90,19,875,452,130,406,808,881,840,348,27,208,407,517,506,853,339,386,655,523,872,870,378,484,621,10,645,128,263,323,90,300,563,313,399,788,694,787,179,477,538,548,668,968,224,113,224,791,559,525,20,509,372,433,186,576,303,711,288,668,665,571,195,137,452,384,431,700,643,444,713,251,454,19,887,682,914,451,380,87,990,202,969,33,284,105,46,360,250,247,36,262,508,927,704,914,266,679,778,676,561,887,528,366,575,180,86,613,316,408,351,716,313,229,598,692,838,123,937,590,141,491,453,26,546,879,67,443,917,668,88,233,805,446,853,440,127,355,988,237,607,445,97,795,951,171,528,561,883,209,552,411,511,640,495,311,258,670,514,559,654,735,601,505,455,52,487,47,635,837,463,262,287,251,510,541,293,372,898,772,476,832,332,320,29,347,527,368,58,681,755,955,754,721,755,403,428,809,251,370,276,125,485,970,593,596,229,365,484,151,927,538,859,754,73,812,494,967,963,323,205,609,632,820,82,721,776,672,74,9,192,289,881,583,809,792,420,153,137,757,757,904,524,613,425,938,806,589,615,64,116,878,910,363,512,422,416,812,321,476,688,893,276,964,906,907,620,107,203,231,966,424,135,103,405,878,917,903,163,550,106,955,738,751,811,864,816,644,361,514,860,392,828,5,914,762,751,615,899,618,639,562,566,137,490,836,354,491,441,151,984,521,229,580,950,963,90,200,692,285,207,38,776,984,217,226,498,109,241,919,747,950,895,426,90,768,890,299,47,338,750,365,11,150,481,368,549,56,554,282,811,761,78,740,149,690,756,363,288,749,703,711,814,585,426,160,842,209,371,768,538,973,57,898,391,172,317,76,218,452,274,374,929,789,152,973,826,753,346,767,494,790,901,711,322,159,869,549,70,665,183,983,629,712,267,803,889,708,433,725,413,49,231,347,879,923,526,280,20,592,317,988,491,784,51,918,968,378,410,723,826,529,801,250,865,603,429,306,143,978,918,721,713,213,86,581,209,182,837,409,529,78,185,66,242,709,70,238,774,571,668,815,353,390,647,668,65,77,587,278,914,633,509,673,986,65,136,63,921,682,315,209,185,299,394,435,125,233,570,763,46,720,989,80,164,565,713,190,621,593,414,154,311,574,321,255,933,945,231,601,727,867,290,180,171,253,484,728,602,77,581,160,410,773,246,275,511,919,581,976,898,849,961,820,776,855,851,154,933,830,566,386,639,239,750,396,629,816,518,304,206,130,492,41,707,856,136,600,943,174,940,854,312,425,559,544,442,792,519,238,476,593,330,795,589,502,334,386,160,245,0,124,434,644,493,55,721,44,922,35,948,115,933,107,429,983,600,462,161,644,875,428,678,518,744,74,783,649,356,135,721,356,574,688,557,711,367,567,358,955,973,266,991,737,628,441,143,685,342,436,159,173,41,300,123,401,60,997,429,789,165,329,30,70,301,597,600,329,496,722,17,220,96,261,60,560,625,116,661,202,108,68,940,119,117,72,513,197,382,666,785,891,602,356,533,777,270,920,581,792,321,945,549,546,748,727,902,762,329,329,408,176,680,856,344,421,231,689,232,794,729,927,130,93,20,824,846,651,657,522,675,154,542,103,960,274,155,715,590,336,404,199,111,295,696,367,509,980,872,710,33,545,369,158,545,835,531,886,480,708,891,691,232,11,548,47,825,675,848,38,134,950,885,254,959,397,299,428,803,950,52,381,706,773,677,296,649,753,757,836,791,697,645,642,299,429,615,405,816,524,705,314,512,297,384,985,386,158,93,177,238,895,831,569,7,703,884,863,847,252,801,877,17,120,481,61,569,644,780,156,276,621,934,637,614,444,9,586,17,344,959,207,868,638,94,222,904,985,220,556,530,237,348,685,561,977,423,943,411,217,110,811,453,760,116,430,225,114,175,317,454,345,468,896,680,245,926,300,752,580,901,81,892,530,735,543,802,260,272,923,807,674,932,546,743,568,52,210,670,543,106,120,321,839,251,336,86,797,560,964,278,804,205,656,648,488,547,7,257,750,552,392,291,819,244,430,537,35,956,264,238,659,824,441,861,537,587,276,506,22,198,808,735,37,25,686,272,144,218,920,598,253,71,567,355,701,207,983,633,267,672,796,182,318,559,829,105,407,934,587,144,680,867,478", "962,41,402,941,824,145,38,455,208,588,260,600,115,826,180,326,994,895,453,138,570,699,388,503,719,719,888,252,511,20,95,154,940,63,386,435,39,233,496,309,406,465,445,602,642,747,283,45,828,818,224,589,147,288,681,941,637,405,928,336,482,772,12,415,509,444,478,954,715,191,182,89,246,793,720,867,522,611,264,68,106,695,619,391,805,233,316,766,107,601,378,914,261,995,897,717,761,604,736,164,788,306,354,934,148,955,433,876,473,469,573,12,107,147,943,600,284,242,613,327,655,381,529,955,401,95,37,532,677,915,510,634,484,273,992,553,243,863,748,265,980,390,632,580,148,966,983,854,63,735,43,70,45,674,367,668,443,559,294,140,472,244,617,530,999,832,194,437,949,354,476,373,527,661,120,985,558,202,205,727,152,341,333,779,688,77,92,659,811,648,685,663,419,962,55,308,932,12,758,201,428,990,180,288,871,130,764,117,815,222,291,387,869,942,741,821,156,450,486,855,596,295,344,811,451,377,177,123,675,784,77,417,612,188,503,947,423,823,128,511,321,603,173,737,937,113,690,22,679,995,763,968,48,629,594,717,210,641,133,322,714,982,129,165,811,788,26,283,92,134,41,318,451,883,976,211,262,998,90,571,876,736,865,360,939,656,246,217,822,643,25,319,639,461,773,674,398,630,183,591,612,492,634,495,355,767,303,854,131,998,393,231,570,147,371,733,46,284,230,585,530,274,914,112,645,939,364,974,648,228,376,757,331,67,290,186,713,428,206,422,534,786,506,912,857,262,107,434,478,139,330,619,66,881,590,429,862,218,62,328,882,461,802,649,916,611,687,898,88,107,313,768,26,540,809,477,953,374,185,460,220,636,996,495,895,861,819,198,880,47,561,683,850,760,346,196,97,238,15,230,261,515,924,215,226,889,926,206,234,467,415,905,440,190,650,221,929,481,266,770,696,191,547,867,426,937,397,633,5,492,862,783,266,52,207,371,538,74,588,460,782,695,948,776,340,285,127,407,625,449,971,897,796,271,392,732,936,192,533,232,983,519,247,553,86,688,675,365,435,583,439,657,272,32,326,458,79,12,346,884,241,298,469,889,275,913,874,85,304,760,424,810,875,479,648,631,975,908,892,384,668,660,710,850,478,919,11,940,464,643,613,863,865,970,821,529,963,526,772,7,967,269,877,234,455,781,781,326,172,320,448,312,3,988,352,966,86,652,910,111,431,322,684,985,851,111,355,720,268,587,146,387,389,238,695,558,344,825,582,908,97,135,453,158,323,26,792,180,496,961,608,205,618,240,310,606,630,428,897,513,115,220,707,644,294,104,116,642,703,519,237,520,99,200,218,731,318,981,795,496,37,116,814,758,358,53,875,751,267,685,263,783,122,860,601,173,381,926,387,317,720,87,333,707,61,635,124,0,479,597,404,716,867,870,183,77,932,345,187,818,318,133,842,156,209,509,804,650,2,543,948,528,404,388,70,401,97,91,296,376,191,934,616,873,143,200,831,343,207,625,610,862,250,269,36,980,872,921,360,768,929,459,792,169,315,720,764,562,643,52,818,800,66,797,917,991,821,854,814,495,713,159,421,328,813,291,625,838,218,179,408,239,826,743,272,318,953,131,746,709,592,769,462,735,429,109,576,171,270,836,30,922,190,69,655,455,774,732,175,140,263,595,954,56,632,471,705,117,501,48,196,258,27,544,505,162,780,802,804,128,534,711,297,490,568,165,908,571,946,526,403,180,521,17,161,185,81,743,488,725,761,32,429,711,625,699,917,382,546,743,155,317,90,622,707,437,741,883,459,722,890,595,9,395,495,314,439,945,25,449,127,514,320,164,688,656,378,71,135,419,512,401,130,677,872,530,712,849,891,292,552,267,864,38,96,147,483,97,51,337,214,431,205,514,674,46,427,781,289,390,307,96,619,151,69,911,518,967,699,347,243,427,578,793,747,762,542,127,354,69,475,896,820,111,899,805,199,445,359,31,662,353,253,789,393,14,847,940,57,909,773,604,208,971,64,545,258,364,297,913,965,782,698,821,159,463,927,401,976,868,616,621,131,421,181,568,473,931,828,231,240,16,588,578,461,705,335,82,842,236,267,230,759,102,508,229,626,669,505,136,903,694,351,738,118,816,947,986,769,589,488,120,595,13,656,751,431,107,716,729,734,181,673,378,125,119,141,46,616,21,590,39,119,225,995,244,406,660,287,450,423,755,508,896,388,138,821,597,824,982,901,565,856,509,751,773,24,839,773,445", "212,207,156,654,658,406,823,860,479,773,853,165,406,730,546,854,708,59,707,231,631,779,87,360,170,311,266,737,756,842,851,348,707,955,921,781,426,107,50,292,182,273,905,567,143,615,322,669,697,646,371,67,708,560,287,951,94,103,608,906,103,164,232,310,129,653,316,309,889,980,240,425,710,817,190,176,795,654,770,416,439,253,729,178,134,396,116,326,535,636,85,863,225,329,406,12,60,24,966,407,94,430,993,957,201,100,629,720,140,782,470,27,661,518,144,517,294,916,908,687,508,689,32,749,244,444,780,151,371,359,447,690,429,705,813,812,483,247,955,644,883,784,450,949,387,895,991,975,900,841,550,551,980,513,490,907,884,651,275,798,239,552,572,269,320,394,712,960,233,343,416,261,351,989,148,90,975,307,395,826,292,522,819,275,752,692,794,112,131,768,905,247,59,36,896,901,367,739,451,332,226,995,733,799,343,815,258,1000,802,815,608,950,487,869,821,354,43,52,391,174,489,43,126,884,341,238,516,791,494,94,989,267,314,619,910,79,147,79,213,706,72,106,764,54,904,875,717,447,580,880,350,892,636,390,801,338,768,465,860,137,804,388,322,291,243,564,607,969,879,102,403,700,9,62,63,814,630,737,345,967,697,89,523,762,719,742,583,864,7,9,759,149,972,78,80,800,956,480,519,373,133,556,301,180,163,536,177,154,521,115,131,829,316,859,844,436,14,359,810,675,395,559,146,160,444,646,143,567,588,655,319,749,648,930,25,931,637,126,318,836,795,459,189,637,150,984,297,625,61,210,417,851,557,802,420,439,114,262,290,862,306,594,532,740,32,913,664,46,942,989,932,484,167,508,128,914,872,649,366,973,598,50,941,514,859,727,731,291,705,229,38,101,387,331,129,613,648,133,119,273,711,349,774,362,364,316,937,155,56,360,973,360,185,877,766,244,7,166,893,296,148,195,787,951,951,711,781,517,975,218,188,743,975,577,485,647,853,839,296,855,752,84,41,212,450,138,749,335,40,629,943,752,643,894,210,628,535,797,377,708,591,990,61,600,650,189,384,701,205,524,402,329,138,438,502,333,697,921,587,275,85,311,416,465,243,41,966,117,306,423,655,307,413,355,89,726,196,453,339,530,26,240,244,772,345,916,536,954,45,394,219,283,797,629,799,841,554,887,237,5,566,738,373,491,590,163,561,985,155,69,291,679,725,374,411,199,809,583,444,862,433,988,946,970,428,747,293,914,246,171,715,59,385,435,277,552,286,110,599,63,121,704,685,563,548,729,425,168,14,544,99,129,983,454,439,432,799,600,681,333,689,569,3,480,120,775,568,896,98,835,446,801,768,408,60,506,253,688,73,111,732,974,53,512,497,236,596,257,946,220,796,753,10,380,776,242,927,295,560,894,73,218,459,247,486,906,434,479,0,944,317,820,87,579,373,487,550,478,461,260,633,11,954,152,76,794,938,923,598,421,898,310,163,55,88,523,32,987,385,733,423,647,696,489,20,303,918,852,574,120,931,812,635,552,754,441,727,850,431,78,468,839,628,513,102,140,684,872,517,233,823,170,754,726,845,313,830,750,341,664,326,295,922,692,208,62,9,483,969,167,782,168,464,546,120,274,961,166,128,161,764,39,981,337,142,529,782,951,851,687,876,337,946,578,421,822,42,393,575,290,829,798,585,597,46,522,760,768,893,85,75,973,703,785,475,875,114,103,100,991,851,714,758,241,254,568,166,489,262,295,910,780,463,672,667,686,341,29,18,440,221,692,339,851,651,707,593,751,256,233,281,564,531,332,791,124,900,49,919,189,90,338,404,422,110,227,577,736,935,857,553,104,212,276,915,951,759,575,648,20,778,905,401,158,291,220,334,531,208,847,457,4,945,19,183,916,968,748,302,553,423,257,901,660,383,884,361,97,39,691,183,401,50,333,650,316,778,63,218,349,199,953,939,432,364,494,825,791,808,561,617,807,626,635,225,408,61,200,787,941,610,931,552,565,972,371,673,529,23,893,359,912,452,267,820,382,676,281,443,273,323,778,692,51,173,198,342,980,721,736,868,957,406,692,938,241,603,429,313,322,537,672,158,582,878,506,860,311,984,970,759,323,924,998,460,367,515,915,69,727,580,911,880,99,652,267,829,847,907,704,297,761,872,203,803,559,631,423,820,696,504,958,174,491,165,724,737,798,124,93,411,824,304,380,111,214,158,210,737,828,462,601,909,247,357,972,123,622,405,354,676,273,134,592,951,195,557,16,870,759", "311,144,163,334,602,485,572,98,441,349,513,876,813,142,734,224,841,258,658,585,197,531,480,989,593,972,338,42,856,935,807,454,610,91,16,30,89,810,959,552,202,127,900,306,433,408,78,281,22,432,420,579,802,338,388,204,416,617,150,272,373,322,828,787,818,53,54,712,415,902,924,938,912,614,773,758,627,49,310,667,774,48,829,454,581,380,446,988,965,579,913,296,922,233,774,769,375,89,763,839,392,306,937,417,910,153,635,216,487,115,136,427,964,830,316,995,163,449,180,659,483,990,559,855,387,84,349,97,973,793,903,417,641,829,646,575,393,40,216,407,889,437,844,761,208,329,516,54,406,64,366,482,330,102,340,661,91,265,689,241,491,358,14,472,491,226,582,108,547,526,136,181,926,244,299,384,459,471,735,469,227,438,611,332,317,798,580,223,272,872,677,194,717,126,830,105,939,171,306,552,872,967,33,199,823,907,338,536,895,593,300,149,622,692,873,718,784,983,37,741,677,466,973,304,868,705,298,321,976,969,705,840,439,448,82,651,373,903,128,152,168,66,899,965,924,89,718,212,502,920,653,955,199,563,990,237,477,143,916,318,809,795,880,388,972,958,251,677,136,13,181,994,123,963,581,127,743,515,740,516,510,712,186,384,951,393,360,119,356,478,992,781,615,752,174,938,133,428,299,741,980,600,370,570,370,263,358,876,711,69,126,892,267,599,753,846,49,667,181,960,999,628,317,78,316,804,4,107,850,946,352,816,35,134,456,350,451,813,781,48,801,110,878,579,913,289,500,301,373,665,447,327,363,707,467,529,70,179,429,379,821,919,493,744,355,612,899,307,440,160,36,740,880,732,18,567,654,351,115,50,670,551,139,472,971,966,232,313,728,986,640,562,995,677,392,131,364,846,303,265,144,414,128,481,354,812,263,875,988,433,749,382,312,779,266,70,94,718,990,405,761,999,280,670,904,966,632,462,399,158,88,837,766,462,369,660,793,307,698,503,984,971,222,921,763,885,348,511,430,147,71,316,885,795,719,202,659,352,339,955,621,61,845,715,575,759,753,535,484,905,646,351,486,811,469,973,799,623,268,217,499,280,122,336,834,23,959,342,958,452,233,493,175,894,903,785,710,230,84,686,455,633,414,236,180,852,995,308,77,844,594,911,313,286,889,359,909,388,607,935,454,601,302,31,413,357,339,220,766,39,11,827,926,108,18,426,67,502,431,99,917,434,253,43,288,290,238,589,346,272,617,812,720,147,125,646,55,13,209,408,801,802,47,143,962,219,798,736,204,411,73,873,783,229,433,624,173,965,108,197,174,655,355,411,707,86,458,776,476,104,355,765,385,710,543,309,896,522,361,739,51,676,926,982,409,753,325,858,825,584,26,404,46,111,682,685,225,604,979,32,402,691,733,740,996,580,644,597,944,0,264,589,983,43,887,919,142,170,775,727,320,338,882,427,496,818,217,330,609,446,347,789,93,524,644,312,651,376,990,359,1000,93,395,638,76,371,606,329,530,946,604,870,195,942,502,374,648,541,528,679,228,893,4,328,265,388,975,692,286,937,879,303,97,125,895,365,724,516,966,271,113,634,189,617,738,225,541,598,388,146,819,82,73,770,658,43,237,522,276,640,583,541,670,242,567,162,203,531,998,933,42,263,888,468,723,384,292,599,123,315,639,826,917,124,888,544,615,484,59,114,865,744,727,80,375,233,520,12,967,452,174,150,230,676,944,442,10,569,730,993,161,702,94,690,546,129,400,719,129,527,921,49,800,121,521,762,596,372,610,226,499,124,481,931,532,752,918,331,513,438,296,67,43,499,280,396,906,980,946,501,49,600,415,864,236,753,951,615,258,698,173,154,914,523,289,122,66,740,856,791,745,323,215,409,144,637,246,477,863,684,240,206,897,797,880,370,824,118,571,841,94,172,702,238,43,387,423,967,296,464,954,144,800,868,757,29,710,365,876,570,844,243,602,380,99,521,920,207,401,404,468,920,26,444,917,411,706,453,87,434,653,385,90,700,376,790,459,513,906,553,699,271,944,754,910,992,776,373,616,912,418,364,230,290,584,829,145,144,436,397,757,457,463,617,520,444,625,581,91,257,776,292,441,462,508,975,71,311,709,987,77,123,571,602,693,674,444,222,935,393,444,709,599,454,239,354,599,336,520,307,764,485,774,797,166,186,813,729,578,277,838,150,580,866,979,892,433,628,924,454,721,522,374,466,56,414,287,544,592,98,408,11,342,508,257,958,868,543,415,561", "572,162,331,9,86,253,915,431,256,388,520,667,47,796,233,542,734,216,120,754,974,588,798,695,500,166,320,395,374,570,579,173,780,610,469,831,53,690,232,986,135,136,526,551,13,32,315,493,723,519,3,232,8,452,83,778,308,388,289,318,711,474,649,930,571,317,893,216,276,552,250,431,981,380,518,27,921,643,863,727,768,706,518,328,295,453,32,376,19,850,295,254,506,119,757,128,124,614,365,12,172,499,135,622,397,347,630,895,596,413,726,461,164,872,867,444,219,414,499,191,103,359,774,450,765,835,418,962,636,899,928,863,278,989,175,939,190,570,347,295,457,386,412,26,142,545,43,964,920,80,462,559,652,604,971,961,137,969,401,678,573,671,22,920,67,410,979,148,544,667,869,435,524,938,15,671,105,550,999,587,683,152,15,144,180,90,450,947,120,981,691,66,59,100,417,229,203,989,801,994,198,582,119,841,699,478,654,801,479,88,591,362,462,466,594,742,653,267,458,810,450,315,608,640,801,204,622,645,927,370,164,534,13,677,894,998,42,764,48,146,568,575,98,447,626,948,202,402,299,602,350,642,9,165,828,837,813,928,487,819,637,773,816,543,491,75,917,353,264,781,689,275,931,602,213,217,509,226,877,846,326,744,408,826,446,26,198,292,210,869,740,101,174,770,454,551,808,599,309,146,525,273,663,27,965,491,120,189,336,712,98,344,260,599,827,102,468,700,358,75,323,883,241,92,17,738,467,187,255,391,536,926,905,835,605,827,785,278,187,380,352,825,586,940,295,668,808,573,113,992,412,941,905,621,541,265,240,577,915,483,796,391,509,884,265,936,381,747,431,669,499,65,301,536,104,594,943,830,174,192,937,539,53,808,342,823,831,322,836,124,372,148,840,152,416,667,803,12,711,807,231,854,143,638,719,538,881,992,864,523,970,279,632,899,655,120,525,200,450,945,41,156,643,572,974,279,432,408,233,881,448,755,922,977,326,820,379,165,310,189,141,679,604,176,750,802,107,493,369,491,929,208,505,188,490,284,667,595,964,445,257,695,387,759,776,118,56,435,321,438,450,182,100,490,602,62,796,320,234,493,360,464,746,55,298,910,59,80,731,665,837,129,419,851,656,676,905,535,83,525,540,332,309,514,449,373,425,365,594,66,907,522,430,898,14,289,460,509,753,853,54,929,300,989,126,593,448,675,327,708,496,945,959,34,76,566,384,507,635,663,420,852,454,300,21,880,569,932,661,102,410,159,587,452,180,704,410,414,382,972,666,841,465,419,128,621,102,388,66,397,296,706,241,833,961,356,444,852,391,902,534,616,723,185,605,79,343,91,508,290,260,131,459,23,886,347,695,808,619,990,976,690,295,875,96,758,691,833,651,428,628,301,830,424,416,907,957,428,853,79,840,419,391,662,929,678,493,404,317,264,0,339,521,2,495,2,45,550,34,5,959,497,850,760,395,743,459,763,150,332,247,163,149,524,14,223,601,377,532,244,314,645,181,832,77,522,639,766,439,844,725,562,586,59,129,594,233,19,882,281,642,958,91,813,47,104,993,777,932,974,681,526,779,986,831,459,354,229,604,696,473,112,906,618,242,919,676,337,708,175,644,434,490,459,658,9,848,831,753,770,139,318,331,706,352,730,588,956,339,552,895,468,608,466,864,991,411,901,783,930,899,57,492,242,249,501,671,458,626,928,370,267,262,869,869,848,395,885,665,182,574,963,913,830,66,136,554,373,914,592,869,854,453,567,936,798,106,702,26,107,100,358,7,869,16,469,16,274,477,35,951,696,230,716,529,238,850,663,788,392,316,226,948,362,607,306,878,97,490,631,929,586,727,386,787,490,555,553,265,524,657,114,529,428,121,109,378,102,443,741,346,220,515,368,900,207,761,702,784,763,415,221,796,292,61,703,567,300,230,369,113,947,625,718,516,409,617,924,606,613,594,118,847,795,962,678,436,539,138,358,290,741,470,401,350,61,116,754,510,289,772,574,341,859,241,581,681,396,17,866,817,63,339,79,226,237,986,331,190,447,255,277,549,107,4,984,275,919,466,529,141,805,690,808,773,382,193,423,408,438,486,671,967,58,974,241,150,218,475,2,840,181,169,707,91,957,999,283,768,577,309,913,934,954,18,383,310,577,14,396,796,76,81,797,778,748,978,907,989,717,563,986,400,669,741,360,930,402,621,16,501,444,560,743,623,97,78,954,995,808,77,191,664,323,902,565,324,885,968,408,834,913,424,439,340,296,274,611,526,82", "852,46,587,294,332,210,41,416,947,245,746,42,270,991,552,859,387,48,427,622,618,550,487,127,701,428,585,798,616,14,833,635,89,751,187,824,368,35,485,373,478,816,100,406,883,570,228,761,403,411,54,266,638,947,166,906,343,303,947,904,71,314,86,592,439,630,984,677,841,988,536,228,160,88,862,687,333,393,641,166,322,277,642,682,131,701,90,853,682,971,282,616,876,531,580,842,980,515,410,389,265,565,853,181,38,476,398,187,985,529,91,621,970,234,924,974,493,833,356,221,590,67,712,367,771,626,173,539,421,204,790,135,496,968,769,22,534,626,382,703,950,797,23,233,796,106,766,937,994,300,945,500,366,811,854,380,937,981,692,189,393,751,133,666,833,948,154,253,663,691,513,849,370,847,645,73,77,93,207,701,184,682,328,390,377,229,277,792,247,568,422,724,757,737,9,497,11,893,997,850,144,462,522,423,686,269,370,521,539,405,699,918,467,719,58,274,555,412,985,49,876,234,540,492,610,247,400,4,508,393,371,972,592,222,65,441,583,351,753,373,572,558,759,91,809,852,725,330,976,761,489,144,663,291,179,27,350,140,859,809,596,986,664,117,766,809,426,449,635,714,525,779,735,347,840,329,140,121,257,497,69,546,753,61,26,900,368,506,151,642,217,738,107,130,324,172,759,404,667,634,135,669,223,563,929,976,882,653,334,976,766,214,511,941,873,75,55,282,995,471,929,45,799,96,438,101,862,401,981,789,134,197,594,695,249,266,890,935,317,658,433,9,18,138,169,713,80,25,986,443,500,931,726,826,86,846,232,321,497,948,234,815,156,97,855,1000,200,797,953,890,592,57,307,945,191,910,572,492,393,486,929,802,659,729,824,864,970,65,336,651,477,22,389,448,848,727,606,836,841,173,762,444,231,846,477,405,337,897,409,321,173,739,556,888,50,618,560,884,393,59,39,984,245,391,10,386,530,109,114,603,159,80,21,299,403,715,58,890,643,157,748,330,119,525,772,532,979,295,330,932,323,271,473,939,472,915,193,918,45,670,580,593,596,835,41,722,750,892,832,780,117,111,570,931,569,22,88,640,578,826,506,780,642,837,852,643,599,140,548,236,336,940,782,243,134,47,550,867,554,337,192,272,444,881,279,948,57,273,182,518,348,787,197,198,662,714,69,531,525,956,26,827,650,922,230,209,680,887,179,521,661,727,218,4,782,857,650,773,663,256,443,577,445,240,175,889,726,951,724,249,463,485,167,313,568,925,835,702,305,70,854,949,196,18,68,841,227,30,972,657,325,149,286,534,829,330,84,784,585,506,221,745,901,163,659,674,381,721,732,851,548,703,868,11,40,540,236,909,949,747,251,617,640,164,737,54,880,12,614,327,340,716,467,950,111,638,842,839,595,640,746,441,855,709,475,689,55,716,820,589,339,0,349,801,783,821,561,891,342,754,648,960,680,635,584,119,684,465,695,994,164,93,401,10,599,412,475,657,947,176,449,789,39,495,640,64,806,822,921,520,416,46,16,230,291,79,37,775,268,713,17,901,493,112,160,672,289,465,660,133,816,136,248,299,847,311,156,224,609,72,99,419,867,873,902,460,8,878,541,928,524,20,71,280,241,937,894,867,541,313,156,560,529,620,913,754,144,216,504,991,679,157,853,229,445,545,275,96,517,691,318,476,881,581,759,658,212,67,670,328,810,216,265,432,48,1,605,719,141,690,876,416,24,436,688,135,423,759,49,138,188,446,274,687,70,7,267,230,407,954,901,236,481,595,16,712,855,348,519,81,514,526,122,574,893,817,941,425,772,290,523,755,692,177,693,97,285,497,281,29,232,774,788,262,398,160,471,923,700,123,460,39,37,597,905,146,805,485,818,713,401,922,234,505,650,690,223,150,274,148,826,2,768,885,870,458,980,133,319,358,741,401,423,808,587,272,193,234,379,942,807,128,376,74,369,959,928,13,985,728,493,142,69,34,984,246,386,2,985,676,792,543,540,303,108,186,803,562,721,356,687,716,784,322,598,77,73,665,201,538,203,555,714,607,393,142,767,594,820,699,84,802,502,475,480,183,27,391,325,656,288,839,245,125,806,575,671,795,105,915,31,929,269,989,803,205,632,421,40,587,901,607,529,775,481,788,319,749,871,380,977,248,50,620,858,832,770,433,657,765,310,376,592,820,309,657,736,525,375,782,642,775,841,252,567,11,373,281,767,744,584,278,184,377,842,574,719,310,212,430,932,695,85,172,623,192,79,816,677,196", "657,689,771,441,104,338,817,524,998,748,711,450,677,32,886,351,456,619,102,141,656,560,49,403,155,115,635,587,368,420,648,992,110,355,321,930,419,855,414,450,378,717,606,216,475,261,539,579,73,747,858,393,152,111,969,884,68,238,786,127,503,80,9,450,598,756,219,653,1000,414,554,339,963,271,487,615,950,558,725,160,586,559,248,138,677,25,48,422,417,72,981,67,2,908,810,43,101,632,199,659,556,531,12,515,926,80,665,205,115,294,393,251,300,738,245,22,994,675,131,993,693,381,435,44,993,155,282,320,385,398,918,577,351,771,206,255,848,56,42,619,180,198,318,38,853,504,727,291,815,671,324,843,474,763,623,638,623,418,858,681,939,668,191,931,447,664,20,366,474,685,221,129,321,944,739,78,766,764,515,416,144,903,616,430,952,194,992,515,583,811,740,385,510,891,78,280,140,900,478,415,216,131,626,252,153,278,11,22,300,887,722,5,464,6,909,492,620,283,551,561,79,99,141,347,17,975,530,19,130,621,405,956,221,714,725,662,989,605,181,630,236,421,507,574,388,290,696,860,208,481,222,704,836,100,641,269,358,339,235,909,146,875,308,425,461,680,239,100,685,420,758,676,168,933,824,558,846,190,142,865,700,980,908,311,226,321,803,971,144,549,997,613,986,945,249,841,375,809,462,17,857,907,495,410,204,803,568,610,14,287,312,523,228,643,595,98,529,282,593,287,519,287,52,364,299,705,581,950,639,537,146,19,85,393,657,923,130,754,871,330,624,720,603,119,105,246,449,721,486,506,530,542,576,592,336,502,453,319,706,763,606,994,905,524,404,79,761,512,306,861,294,260,591,551,964,97,204,372,903,230,583,285,814,313,378,780,192,352,87,441,400,487,678,285,28,547,481,458,951,565,309,329,390,474,40,195,857,375,822,75,858,813,37,860,745,581,44,167,395,123,343,374,19,134,102,999,796,167,907,451,722,958,530,514,95,376,751,579,511,602,104,72,538,819,465,945,104,286,66,165,659,11,657,612,68,491,78,442,60,571,141,291,639,198,967,507,212,125,978,240,484,517,187,866,517,830,182,367,661,405,384,34,428,984,20,787,746,676,916,340,961,363,358,594,343,738,439,155,319,844,809,876,215,809,608,433,953,640,340,848,188,265,713,989,934,224,223,746,476,38,220,132,526,361,572,447,31,707,9,14,107,709,467,8,741,970,959,555,760,160,251,463,163,890,978,354,689,150,849,660,604,919,869,448,448,55,30,140,149,217,933,283,80,943,829,73,387,370,781,790,373,591,461,983,448,872,778,141,638,654,725,126,720,843,94,428,201,665,272,701,995,78,95,191,381,608,846,722,448,682,150,948,730,536,443,809,253,281,410,180,523,464,133,396,845,237,622,690,201,896,965,297,190,622,663,467,721,867,87,983,521,349,0,194,658,669,20,851,985,654,923,112,444,393,106,7,557,715,783,849,913,359,33,158,613,370,945,905,523,751,632,948,481,150,740,154,865,89,338,589,504,962,686,27,608,397,564,448,875,303,420,120,1,736,824,695,565,609,411,935,240,173,522,967,352,474,408,690,236,924,778,494,751,350,880,629,916,213,744,809,227,997,936,46,612,917,781,49,874,227,462,68,33,871,903,957,508,23,691,765,300,371,954,938,971,550,971,836,530,882,617,269,498,572,16,995,247,161,242,965,635,744,835,521,825,932,121,619,202,83,387,169,896,582,80,540,203,255,254,98,487,94,864,438,214,793,387,111,840,693,677,735,625,810,287,551,950,215,905,274,563,430,742,863,981,870,634,603,925,19,911,352,277,250,281,66,490,569,881,952,971,656,416,922,908,785,133,477,660,142,297,393,538,46,589,601,655,490,525,96,490,788,92,26,774,623,793,587,217,43,304,971,340,616,475,677,584,233,128,762,397,637,973,324,683,816,859,457,553,824,540,758,265,190,203,753,625,534,463,792,348,799,970,429,333,257,324,523,235,735,192,401,426,689,616,579,955,916,518,104,259,857,901,449,978,81,903,879,813,610,274,99,729,310,998,913,647,231,328,953,431,173,15,92,908,84,45,686,173,519,447,504,83,291,688,81,39,318,621,196,747,651,881,463,412,15,277,258,613,14,692,886,735,174,180,626,740,229,788,474,181,566,893,966,554,495,626,777,70,674,689,885,54,339,835,766,60,153,897,932,165,375,442,923,660,176,677,909,887,326,808,747,719,931,160,871,500,270,193,966,225,858,858,887,718,404,810,424,795,280", "622,775,204,194,689,36,812,629,357,385,548,643,964,413,200,914,467,588,476,126,536,114,225,11,846,931,990,554,496,572,14,876,14,109,922,716,914,921,371,81,770,648,970,198,67,523,503,390,729,603,233,322,458,259,452,395,788,442,918,651,744,750,317,652,269,955,143,53,220,275,925,821,280,223,328,594,528,778,824,665,137,119,586,490,262,182,601,526,280,239,320,266,355,836,611,61,576,946,988,942,98,545,23,288,555,93,402,166,371,62,25,283,456,102,274,568,212,659,398,683,66,665,584,934,681,671,581,866,188,222,761,442,108,179,952,618,763,877,662,132,950,433,58,428,363,575,659,286,155,556,232,520,978,833,120,567,898,756,802,571,490,550,663,832,656,737,655,365,973,101,150,870,106,647,9,13,940,914,314,88,704,707,756,285,100,513,108,439,702,796,409,809,317,589,152,89,949,176,732,750,713,550,554,336,942,92,147,634,435,903,539,814,493,31,845,846,147,763,388,427,931,858,933,395,108,978,806,404,867,5,471,985,782,73,930,687,787,603,138,334,446,416,437,370,234,369,277,671,930,46,885,12,490,282,979,587,989,633,725,206,812,575,71,120,830,697,204,647,671,754,293,523,250,305,31,886,402,25,527,221,664,354,848,827,241,431,882,199,452,159,285,676,834,786,949,665,891,720,552,577,38,180,408,248,173,166,432,867,856,630,174,588,674,50,335,630,664,101,19,943,355,514,780,3,775,973,881,718,564,712,564,499,385,659,557,290,360,835,700,865,995,857,205,552,899,69,149,792,192,928,579,970,981,3,277,722,397,612,333,950,37,55,829,153,573,379,663,683,719,583,118,73,372,398,837,730,496,703,726,645,646,600,537,208,865,951,445,675,832,542,627,323,767,424,988,509,672,860,701,339,70,602,752,153,371,620,247,552,666,280,433,553,756,478,397,783,137,968,849,439,506,959,409,280,59,933,16,842,825,246,61,214,123,553,145,377,55,360,662,7,393,4,735,767,464,336,666,527,459,793,345,133,815,857,284,633,285,610,913,63,285,724,209,630,534,220,9,76,754,847,987,864,947,766,851,31,522,433,782,510,56,708,245,355,442,776,43,354,22,819,74,473,641,398,965,536,878,66,627,614,801,229,207,586,170,946,352,55,806,792,219,352,445,393,230,399,449,494,9,572,891,326,341,544,122,229,963,977,103,14,954,572,583,904,643,890,156,134,859,155,587,306,391,546,152,471,58,602,512,427,926,181,129,215,348,830,325,136,914,648,963,944,110,115,767,661,157,303,412,736,996,184,878,811,496,471,242,836,447,702,834,845,376,185,921,756,482,147,970,906,400,369,204,807,130,332,41,16,422,670,745,527,634,151,993,879,24,980,987,224,764,547,81,606,15,990,70,694,598,461,787,527,54,518,351,261,44,870,579,43,2,801,194,0,965,459,597,57,970,470,405,327,341,479,790,561,633,885,843,277,29,484,837,388,745,605,811,916,269,538,669,401,232,362,948,821,243,217,237,57,442,332,847,25,859,260,95,827,316,42,11,758,42,379,869,792,781,279,965,759,315,270,164,27,738,483,604,709,818,525,614,938,789,107,881,983,466,627,174,187,682,191,842,487,157,662,549,585,821,375,34,811,357,908,667,576,178,245,876,323,230,339,671,745,923,509,3,405,126,175,930,995,113,806,802,762,711,401,801,158,512,700,296,426,135,965,723,344,859,851,390,630,15,871,997,411,722,93,377,878,92,888,304,731,373,256,185,266,968,688,905,381,64,947,244,279,645,779,68,37,362,504,726,137,194,491,211,235,193,722,290,834,619,890,891,982,488,813,884,185,893,929,370,334,802,768,791,781,886,595,536,104,224,513,646,733,334,326,70,296,528,154,24,767,161,829,83,901,180,297,490,127,29,837,298,161,714,489,653,968,121,558,891,858,376,705,864,469,583,429,536,527,411,409,674,823,642,959,127,306,253,936,402,834,597,864,588,989,502,219,450,99,310,166,506,494,509,185,130,437,406,175,402,893,931,330,823,144,172,827,437,50,917,830,151,298,187,280,957,105,224,241,334,649,927,463,274,396,455,317,866,149,635,89,995,687,675,793,467,713,871,634,713,112,631,587,257,992,737,454,114,782,53,101,117,106,902,435,757,798,650,119,536,363,790,649,601,394,397,134,533,375,210,208,624,166,854,859,679,676,25,717,678,801,969,816,879,873,823,59,144,812,351,512,675,596,986,871,213,501,190,981,154,623,11,28,101,450,204,773", "461,318,607,902,959,277,61,405,184,339,552,538,549,552,91,725,631,653,244,459,870,414,170,522,177,431,571,71,888,254,541,91,953,203,161,762,826,951,773,88,661,662,860,972,384,998,195,632,888,228,713,799,953,304,160,312,743,259,302,256,765,264,890,486,344,378,196,53,146,171,748,284,573,844,292,608,872,54,668,237,66,577,994,790,647,618,60,950,298,43,588,194,831,34,670,548,71,308,955,269,73,134,161,149,831,258,436,959,665,425,355,900,411,474,203,939,94,320,2,47,30,668,917,37,37,840,412,673,501,306,376,773,904,775,18,367,85,659,672,796,318,486,739,416,374,916,625,84,916,262,852,866,402,941,580,45,405,716,862,854,615,501,85,281,560,308,875,737,656,115,287,778,275,908,223,865,408,381,240,427,532,266,498,798,692,829,964,70,309,522,278,508,362,899,455,778,658,975,189,663,518,118,5,401,76,582,750,873,293,869,213,654,410,750,450,928,731,59,27,138,162,294,158,15,815,285,917,841,250,144,117,913,547,370,43,769,677,797,930,628,528,262,797,496,170,364,130,927,323,908,951,387,931,267,97,443,99,702,562,652,566,542,432,461,732,305,783,117,84,549,888,624,524,793,327,818,62,491,178,258,687,631,267,352,341,604,585,369,916,536,274,232,624,433,637,870,285,309,850,31,754,791,546,885,131,269,796,991,33,712,736,939,527,885,60,636,725,230,150,880,73,415,609,530,567,273,837,161,593,937,808,232,226,299,592,74,721,825,881,109,545,499,423,262,616,394,424,453,561,913,387,399,98,963,567,412,933,445,680,115,676,215,183,611,736,20,831,737,296,171,749,878,76,462,793,495,402,264,953,738,655,697,93,913,893,334,551,193,248,278,385,411,753,114,336,30,314,722,503,377,919,309,338,50,199,859,398,647,744,590,349,809,974,250,441,336,836,872,412,875,575,61,887,235,130,698,611,861,525,112,878,271,902,10,949,893,887,595,48,243,332,14,721,298,836,751,616,415,189,209,63,153,534,180,970,941,865,432,894,830,356,311,569,500,130,569,527,582,41,853,532,726,107,392,411,722,416,606,86,639,218,696,672,637,988,199,623,684,361,780,121,222,458,71,743,599,865,638,658,274,408,968,134,804,646,63,222,747,280,820,50,569,178,871,593,470,65,962,220,665,681,363,83,224,847,353,6,808,448,54,478,520,796,487,687,431,40,561,870,18,495,32,528,807,944,618,594,189,331,170,89,977,760,587,971,534,724,900,304,65,124,252,380,633,700,428,941,759,312,143,598,573,932,360,399,108,658,277,706,945,922,266,999,518,318,410,976,823,983,63,874,133,958,30,928,782,70,808,133,308,859,853,607,368,928,890,807,673,502,307,549,914,515,735,683,722,136,691,672,90,444,122,400,93,944,548,922,183,373,887,495,783,658,965,0,416,835,560,256,172,76,143,75,278,933,872,332,610,18,805,5,913,943,776,94,473,675,550,156,614,537,836,451,694,621,194,578,563,697,642,606,505,164,264,234,241,276,983,1000,707,882,117,20,250,790,664,337,678,661,791,412,314,645,629,161,713,290,902,239,695,254,634,36,281,652,829,46,414,800,737,211,92,600,793,780,254,270,582,399,517,859,311,808,609,480,523,992,660,98,968,964,47,898,437,791,128,946,460,930,547,514,419,406,786,770,692,510,290,614,831,567,902,783,849,344,114,856,511,174,841,740,724,46,138,740,410,404,589,363,620,117,668,350,93,941,662,124,461,848,445,576,928,849,603,748,626,647,467,146,950,487,190,385,286,504,621,575,667,732,881,977,580,890,94,181,855,639,846,605,632,550,892,795,9,612,745,518,238,971,698,118,80,852,75,611,643,407,448,511,755,405,541,983,607,265,586,776,707,561,459,345,987,624,894,190,445,378,508,466,864,139,734,721,896,686,607,172,521,377,6,370,997,346,6,562,93,576,32,231,732,375,535,692,176,265,240,160,586,500,656,720,611,805,989,726,425,957,491,155,989,78,332,481,787,798,128,726,149,821,371,137,604,260,454,912,501,169,420,444,976,65,243,142,966,362,233,510,116,532,232,611,584,966,764,177,34,985,417,798,202,800,679,449,864,956,148,122,17,39,890,36,741,480,703,55,752,805,368,599,799,563,991,968,91,207,453,890,410,575,236,844,101,291,963,738,393,525,62,502,696,206,39,19,811,484,22,313,226,439,915,115,596,395,109,293,452,917,543,381,986,368,750,197,500,791,397,841,941,142,149", "101,311,979,117,217,533,730,827,771,940,964,230,884,785,87,144,783,159,145,112,96,201,324,595,883,339,944,529,884,307,58,676,126,272,335,462,149,821,696,755,229,650,918,643,932,181,117,128,60,424,333,767,568,761,389,480,449,480,814,108,229,945,566,664,848,1,323,819,513,754,906,84,561,264,926,776,576,24,265,108,730,657,863,874,107,737,687,812,17,649,968,737,482,784,475,330,919,337,321,972,901,417,326,300,69,190,820,69,259,32,862,953,91,785,779,154,704,787,49,316,255,970,965,741,914,963,429,346,104,948,592,305,178,599,828,876,927,29,999,966,300,436,199,699,721,689,724,41,296,46,819,791,975,598,100,435,417,340,250,335,556,124,180,384,705,954,578,104,450,171,231,60,851,665,743,485,215,989,136,902,215,907,551,720,89,367,542,560,950,234,503,629,174,16,432,916,517,854,472,871,130,361,897,102,533,243,312,47,235,89,735,610,539,459,17,153,64,740,895,213,825,951,542,134,640,397,353,318,481,403,337,813,406,606,804,495,907,139,608,299,115,298,417,152,756,276,485,164,264,58,188,739,80,911,44,279,968,836,260,656,730,746,829,166,706,608,354,680,304,748,248,526,723,176,545,989,899,272,624,777,48,856,751,781,226,259,501,756,488,555,919,84,23,975,62,8,628,144,666,230,348,89,597,507,56,815,519,995,500,710,166,36,213,167,478,306,732,321,613,174,913,181,281,442,77,21,863,769,43,753,992,795,149,17,936,122,760,168,131,533,874,875,200,89,438,190,191,18,684,60,788,281,179,278,527,146,132,417,859,812,336,750,959,774,55,954,599,614,301,776,561,448,759,533,872,783,479,761,106,619,475,867,463,191,219,266,564,928,229,845,186,498,376,824,805,831,137,245,540,150,718,959,118,221,428,177,65,334,333,282,17,284,691,554,881,556,527,536,416,565,681,226,262,25,101,853,738,826,336,487,708,347,598,898,179,528,930,499,374,121,416,519,630,842,214,854,274,532,887,799,923,696,147,917,461,248,197,925,195,770,438,923,419,442,218,485,780,69,91,645,363,109,897,452,859,87,797,212,390,19,766,874,201,365,189,658,823,986,311,609,787,548,177,111,888,796,950,325,828,187,128,868,554,752,296,765,976,71,826,55,856,942,691,535,332,305,872,590,157,35,770,760,954,8,591,883,107,912,534,29,454,941,147,167,976,50,47,614,979,974,651,25,272,419,470,429,487,24,662,706,855,718,904,602,947,734,674,622,848,99,830,833,127,46,157,810,332,830,194,868,39,921,628,590,395,329,450,529,250,72,454,592,486,582,156,397,506,240,238,157,703,369,275,257,307,789,414,650,593,749,764,341,374,984,489,258,785,411,304,718,28,614,354,463,80,129,474,937,65,309,615,442,834,819,819,946,35,77,487,919,2,821,669,459,416,0,120,28,43,469,283,927,147,956,966,63,687,458,34,348,606,931,380,286,101,243,428,727,937,252,731,601,820,404,540,67,407,338,130,395,563,928,774,86,523,509,473,989,302,566,119,809,838,650,419,236,417,586,147,817,591,836,113,394,178,577,221,779,516,603,626,309,790,508,33,45,517,515,748,917,936,920,54,120,343,744,1000,943,629,66,592,373,706,839,35,754,709,757,666,826,4,265,542,478,492,9,530,736,922,920,331,614,650,19,435,33,998,285,832,669,244,234,883,853,46,678,615,159,309,72,87,687,761,233,809,430,387,871,731,724,663,589,952,938,564,404,303,459,988,807,695,40,220,387,451,625,262,386,789,49,326,931,934,147,471,959,394,63,369,962,308,544,557,428,447,940,997,578,323,165,920,94,566,917,462,664,736,207,241,648,6,155,607,429,495,872,261,80,360,567,185,890,190,158,473,65,762,189,442,383,586,935,636,104,573,47,843,530,259,394,117,64,723,642,341,588,42,563,455,951,265,203,944,447,100,329,863,520,291,167,571,689,74,579,385,821,532,203,179,847,264,96,880,468,45,243,284,167,284,771,11,552,482,477,444,426,583,627,608,876,576,83,920,788,927,511,379,241,411,696,264,836,794,161,338,223,401,45,430,527,538,570,716,286,460,146,208,184,330,14,770,223,230,70,101,924,274,577,656,695,374,909,554,331,265,906,185,674,702,697,288,531,603,377,714,859,897,285,72,933,494,646,505,668,888,321,62,525,719,565,357,108,347,717,255,881,140,291,358,69,202,323,894,904,922,957,439,602,780,658,593,231,283,287,423,224,398,558,268,672", "771,247,404,969,466,632,597,836,130,8,395,391,412,121,785,44,960,621,808,620,200,562,610,268,559,55,378,797,584,99,665,951,136,73,358,358,695,483,998,520,847,284,709,591,96,725,525,72,556,570,196,968,685,238,263,439,713,442,308,453,9,884,944,970,275,492,641,460,83,258,892,611,555,732,261,296,845,278,767,180,56,751,962,621,515,204,939,74,721,412,40,619,156,343,841,521,301,167,860,439,860,71,754,599,183,423,138,370,995,126,513,703,931,188,561,542,883,60,546,91,716,793,97,518,80,300,296,43,531,229,325,562,758,272,226,41,200,606,661,247,747,56,69,9,689,825,934,669,416,484,304,66,196,942,506,435,711,295,585,438,189,268,372,344,829,714,99,536,845,609,319,221,604,236,619,928,930,413,429,760,177,924,227,609,549,495,773,766,863,312,784,55,344,583,807,47,541,972,835,12,838,731,688,359,574,611,333,708,174,282,578,741,924,174,582,441,421,555,808,292,65,507,701,263,158,582,183,351,869,510,598,715,447,365,728,115,862,851,757,963,383,488,894,322,185,934,865,281,581,926,266,494,902,6,40,521,756,616,893,314,780,256,772,600,453,98,125,906,807,310,5,409,418,632,383,966,548,506,688,605,441,149,343,742,205,179,958,131,224,686,596,499,914,184,414,798,44,103,331,624,168,21,84,450,609,174,672,158,201,93,276,966,816,370,463,169,295,109,192,786,839,73,838,237,218,731,411,579,339,377,95,110,789,27,448,906,658,382,836,628,966,855,741,779,134,803,369,190,577,295,811,990,186,361,462,416,345,295,254,512,170,975,987,379,301,102,131,773,934,389,724,496,943,131,742,864,170,106,909,489,920,162,502,577,725,204,951,664,827,902,890,269,513,990,936,525,899,451,677,182,901,584,402,827,556,216,919,631,890,500,308,508,950,185,901,864,521,661,896,132,955,228,968,784,590,355,31,525,518,241,939,932,138,562,893,792,739,242,700,280,199,969,525,533,516,278,588,128,230,107,264,491,270,997,806,198,399,537,673,732,240,920,685,474,629,37,268,152,979,796,750,694,168,481,919,476,344,285,535,910,543,99,839,550,855,67,698,639,183,741,87,462,376,484,961,832,48,835,78,395,896,866,643,546,720,121,927,180,952,362,426,155,962,268,572,997,251,795,537,968,812,762,803,274,57,965,712,469,445,63,385,583,125,919,572,506,276,894,887,179,730,616,788,384,791,422,572,34,495,468,580,438,848,553,415,169,566,978,639,335,749,720,57,840,613,314,154,888,505,336,111,119,925,762,480,104,427,808,504,816,702,478,919,113,963,479,614,369,325,515,507,143,932,167,359,246,142,789,322,385,918,877,790,980,268,58,260,619,15,261,573,695,374,421,867,73,17,131,721,768,276,937,956,356,351,914,948,932,550,142,45,561,20,597,835,120,0,2,813,963,542,491,533,958,773,883,472,355,592,640,305,65,263,639,495,948,826,320,959,983,310,41,514,108,437,933,680,703,702,233,793,964,478,405,547,270,161,818,944,160,678,296,191,340,926,68,966,927,963,613,594,538,311,704,679,58,866,162,248,926,82,862,230,908,58,757,244,713,799,833,949,597,470,916,691,586,611,766,452,14,499,404,885,76,134,150,593,892,454,556,126,22,658,870,312,235,490,479,982,764,693,927,56,142,359,211,422,731,71,555,694,317,515,799,363,722,200,746,620,681,661,137,165,213,316,274,697,679,435,181,211,354,632,235,927,936,350,3,611,711,650,479,280,469,136,888,319,751,344,781,83,180,160,499,969,385,583,675,751,368,854,958,644,218,494,707,636,278,442,12,976,406,421,664,112,185,783,954,476,199,911,75,334,96,19,765,709,805,408,469,491,58,994,339,146,333,210,619,392,947,840,176,261,147,88,934,593,672,164,767,638,154,516,777,315,722,788,930,702,382,113,934,491,232,627,194,996,579,111,641,157,792,211,34,991,118,332,534,740,514,589,73,100,107,157,344,648,791,788,879,312,62,483,939,251,919,820,878,832,431,484,287,655,909,415,957,68,223,140,863,59,930,767,876,370,572,361,842,732,409,84,897,320,408,38,168,351,693,497,252,291,220,944,768,188,774,619,215,896,95,87,650,977,368,104,892,1000,779,161,824,687,785,291,123,298,801,859,122,488,952,792,541,885,703,840,674,723,566,766,991,7,614,528,911,638,600,598,557,308,454,202,484,909,484,707,449,3,688,126,253,395,254,739,787,850,368,173,909,447,298", "644,748,137,201,184,420,543,795,663,126,132,306,750,952,657,919,911,909,55,474,422,813,921,296,525,839,448,761,80,730,80,880,940,466,306,755,727,893,160,21,448,30,928,549,36,396,670,667,347,749,216,768,265,894,337,603,457,182,417,951,74,485,543,701,456,655,382,905,131,113,973,596,718,528,551,705,499,138,974,309,743,869,747,620,751,415,216,739,384,588,513,135,252,108,829,809,5,209,682,5,607,474,790,195,394,17,955,350,668,592,377,871,123,510,594,670,54,914,665,814,774,937,713,238,1000,849,373,488,979,81,967,72,279,336,225,906,347,926,561,853,235,438,278,160,796,179,934,151,91,420,101,330,365,464,760,446,590,534,902,415,467,654,203,613,224,215,583,124,150,641,90,641,886,534,818,71,239,624,385,908,420,866,448,646,261,424,247,661,704,219,354,94,88,731,555,337,954,44,531,170,4,780,145,833,636,173,268,602,18,719,707,844,369,775,27,602,127,23,958,384,649,207,231,577,478,106,546,361,371,588,29,69,339,76,524,378,967,401,611,197,989,667,796,328,433,980,385,795,986,322,828,873,290,382,374,708,378,757,223,489,261,68,934,230,612,467,66,156,787,242,197,204,886,9,889,227,686,321,112,195,222,760,117,292,911,464,805,394,470,289,932,418,588,761,568,464,667,725,192,143,904,658,661,285,116,882,329,897,748,535,994,745,366,467,221,887,150,465,173,708,160,620,465,512,911,188,131,86,803,100,656,996,440,72,212,134,976,641,507,445,803,171,747,296,688,466,955,500,219,116,343,217,316,247,609,509,331,563,955,748,662,331,913,757,791,531,786,297,106,128,477,485,83,431,255,960,391,448,373,177,431,462,157,736,253,307,861,804,490,600,623,291,85,323,210,652,709,948,108,549,581,806,511,591,524,34,772,817,780,108,809,833,428,144,975,216,431,735,182,153,632,887,207,222,972,339,288,16,598,468,865,273,432,101,616,247,634,61,750,847,600,871,985,167,811,506,554,402,187,616,514,129,906,841,554,8,526,685,448,724,62,834,261,288,286,309,656,91,75,775,171,384,229,591,387,180,526,282,7,534,483,460,988,779,860,530,899,325,14,704,397,323,22,320,525,776,293,915,960,828,290,618,450,933,288,543,328,788,815,11,822,840,669,58,92,159,597,178,694,123,877,886,599,67,516,651,635,795,880,605,660,460,484,397,838,189,143,815,412,927,914,251,1000,855,738,22,152,979,880,191,235,713,992,733,38,881,987,291,704,28,317,906,954,136,710,334,526,551,250,765,401,864,438,100,200,76,858,370,507,549,31,560,63,680,12,380,127,882,506,116,144,838,415,674,430,256,343,83,161,828,396,444,818,395,530,174,437,412,143,579,979,156,11,668,548,257,73,646,38,631,212,847,517,472,285,243,115,345,478,170,550,891,851,57,560,28,2,0,157,992,949,225,337,989,594,294,660,688,345,913,834,401,454,813,470,325,130,377,462,451,115,664,628,165,601,437,411,215,430,436,677,505,817,595,378,13,953,544,349,332,488,654,281,827,581,177,647,942,647,692,489,436,94,952,831,457,919,245,104,883,507,619,793,137,827,265,236,137,390,785,976,584,984,484,523,7,490,587,809,193,914,618,156,901,548,203,735,897,81,83,510,317,787,508,932,920,705,916,391,995,266,424,493,990,83,536,230,818,60,401,378,728,161,59,94,963,863,589,83,781,655,929,400,731,714,578,502,527,962,772,602,129,649,811,860,756,705,491,297,253,407,379,757,947,20,762,438,132,931,76,42,888,763,886,571,384,371,939,997,539,667,825,726,873,775,590,322,800,346,720,670,423,248,783,575,167,312,612,563,403,250,92,563,267,33,233,147,410,896,562,376,401,895,217,463,869,271,333,506,129,382,504,764,674,197,624,757,493,691,202,207,882,32,34,818,884,519,3,687,22,75,171,857,607,838,848,302,720,686,62,116,989,705,567,547,798,664,298,310,745,460,883,10,861,529,351,807,428,52,935,279,402,780,636,990,178,889,510,208,153,515,337,728,781,909,642,190,478,149,410,204,318,398,544,575,492,664,367,885,518,116,491,857,123,18,697,557,665,358,506,74,119,917,650,895,56,288,32,537,293,62,124,986,554,149,540,731,46,195,399,269,328,296,724,538,927,317,904,589,874,377,862,753,340,873,492,702,537,901,879,855,610,415,573,948,574,725,368,899,886,88,560,817,547,418,990,728,471,581,165,159,964,961,37,890,644,909,872,351,188", "925,318,688,451,313,213,601,122,498,996,444,929,109,932,786,60,835,474,477,9,355,602,469,976,60,933,768,684,610,561,636,617,3,395,209,29,206,768,512,208,95,410,105,242,884,920,203,344,316,837,675,472,189,528,479,580,180,874,379,745,154,428,84,317,332,22,992,222,991,929,624,944,445,119,956,614,290,439,833,27,689,582,108,834,949,451,635,804,826,365,699,192,696,928,951,346,547,116,599,685,745,23,554,251,17,445,129,241,869,974,465,915,975,854,269,270,579,891,829,980,677,884,674,9,548,943,873,115,111,753,856,643,700,781,194,247,771,25,814,693,227,280,40,461,263,981,582,717,937,929,653,743,768,737,648,883,500,109,870,31,824,173,765,624,922,391,532,718,897,194,788,3,957,370,432,414,670,987,341,821,673,94,123,456,370,320,79,896,803,915,816,72,726,293,753,744,679,602,536,103,558,725,941,93,643,716,170,910,796,926,412,480,21,834,87,255,745,207,913,789,671,710,882,718,684,748,325,707,889,708,893,321,673,178,378,51,673,501,598,266,582,244,325,659,121,100,303,117,600,265,37,843,550,435,998,770,10,850,442,889,364,695,133,266,486,74,574,544,564,903,445,375,79,809,852,982,619,436,892,828,903,978,55,182,124,859,495,835,938,474,83,609,377,500,509,78,30,704,105,65,62,14,430,242,933,8,522,453,198,307,430,275,645,100,140,826,234,950,72,249,628,507,136,351,614,742,176,802,877,706,947,796,300,730,533,515,466,797,552,182,247,429,247,73,679,128,794,398,486,746,875,517,282,794,620,969,441,760,301,871,156,858,905,413,796,724,702,881,999,59,272,954,626,4,761,712,33,417,99,993,701,91,822,953,845,151,347,239,527,531,563,940,129,489,480,648,942,945,160,223,279,116,103,611,565,950,396,489,542,708,294,374,745,174,907,873,774,835,595,544,519,29,411,149,685,110,431,108,846,814,280,221,915,882,146,617,203,687,867,102,855,568,804,436,608,227,11,857,489,649,556,324,119,201,104,113,858,122,969,89,868,827,68,276,156,518,105,83,883,131,933,836,959,229,206,426,402,993,445,928,581,369,228,466,541,871,407,515,620,937,484,620,461,683,800,575,128,561,400,224,779,21,11,982,665,545,841,329,122,390,860,814,399,594,982,917,506,744,802,823,348,322,904,444,310,504,730,970,725,732,593,106,77,476,187,276,942,866,742,796,925,479,655,572,257,837,779,324,921,872,163,216,562,18,657,17,123,192,323,247,150,555,763,653,658,253,978,833,106,288,441,382,564,976,678,212,23,5,340,653,164,580,429,946,16,395,604,887,366,95,847,810,220,412,303,63,735,356,265,368,394,231,434,714,521,17,530,571,157,543,470,369,210,765,105,281,619,881,771,59,436,623,653,993,848,966,933,187,461,775,34,342,985,970,256,43,813,157,0,764,721,377,80,949,853,851,99,570,634,152,112,484,929,785,432,596,146,218,732,910,648,67,671,770,405,697,915,19,38,157,185,177,68,392,961,343,876,33,968,505,448,459,788,160,415,87,74,827,61,992,92,868,990,234,302,950,336,912,957,95,251,989,295,621,59,240,964,507,910,292,277,751,452,809,280,265,495,456,941,919,144,856,825,50,206,194,556,49,81,280,562,880,773,676,433,879,973,545,190,114,640,526,128,155,711,341,870,209,298,979,841,39,90,14,665,702,475,458,934,929,492,959,583,753,401,205,96,155,473,321,178,606,930,768,94,441,326,959,690,162,899,721,767,902,718,631,852,48,752,128,383,383,49,487,337,187,957,533,520,228,552,365,946,809,1000,110,68,166,315,842,815,863,656,747,519,790,302,69,774,589,771,565,271,990,595,536,880,872,694,341,450,573,640,391,89,482,772,493,946,649,467,216,500,918,835,31,947,637,680,666,119,280,888,248,323,174,527,2,703,877,154,296,475,340,864,873,267,309,749,99,235,630,633,59,229,47,326,139,317,250,441,762,973,418,818,521,657,195,115,980,930,479,842,356,397,642,67,631,858,333,899,752,424,1,302,752,131,231,129,254,329,114,448,126,574,322,481,818,191,385,670,81,870,625,712,313,378,248,245,985,693,103,232,41,119,528,981,370,859,462,300,915,425,837,617,651,840,689,628,860,249,985,247,718,254,429,347,327,67,966,290,705,726,447,51,247,90,99,796,651,382,955,588,738,133,853,230,494,625,227,219,95,854,319,798,292,968,60,305,102,301,409,662,471,656,183,387,725,313,156", "761,828,572,589,774,53,31,296,536,242,154,350,136,600,151,467,213,376,829,770,759,978,550,145,706,191,616,66,221,220,613,399,181,572,499,420,681,187,846,914,818,689,526,978,308,18,576,525,173,607,778,703,568,869,331,440,824,996,878,980,304,29,517,230,402,30,134,766,101,997,846,37,720,772,312,986,610,22,451,175,606,232,777,330,395,922,423,262,479,818,788,429,442,864,400,754,372,477,825,81,23,264,465,501,817,374,941,28,647,519,637,113,419,812,341,346,554,989,896,542,190,780,938,355,730,59,757,177,319,61,778,599,416,313,475,839,130,266,721,63,732,717,443,665,52,850,542,199,325,836,237,909,825,482,311,432,204,688,106,287,763,429,649,173,408,563,515,793,366,187,447,914,229,871,642,36,679,437,80,291,819,352,677,597,309,175,993,172,255,371,344,785,930,44,793,424,703,528,788,658,4,370,959,91,969,817,189,955,23,515,94,21,974,893,826,90,873,264,956,131,543,248,127,929,604,627,342,124,386,187,910,817,611,907,719,576,504,696,418,159,564,158,251,362,93,861,141,159,838,119,1,966,82,520,794,796,647,700,699,108,940,178,648,669,591,832,9,667,158,779,536,392,333,895,346,296,166,923,350,274,62,177,243,761,387,124,42,678,625,168,900,207,349,569,559,955,722,91,379,21,748,778,338,97,669,858,173,480,252,952,607,694,157,6,39,759,822,933,413,670,485,93,738,65,287,674,704,809,167,972,72,516,764,601,441,485,395,905,761,15,443,114,822,453,460,593,499,840,542,99,886,470,733,950,304,309,508,79,984,793,336,786,119,719,13,373,217,339,52,196,226,301,782,511,712,575,319,329,832,972,136,376,346,634,256,921,238,711,539,1000,490,633,280,828,230,546,211,98,336,947,43,303,422,316,602,471,756,216,515,322,753,507,901,491,535,283,247,592,233,210,26,365,420,464,276,58,337,405,155,716,355,416,981,267,581,801,200,860,552,246,32,294,309,180,67,961,8,319,134,434,757,530,504,836,307,280,985,309,176,800,61,645,356,706,358,400,490,903,377,625,514,978,277,942,370,535,597,86,19,882,253,464,210,195,3,371,527,939,388,207,589,861,593,916,598,610,955,364,401,585,32,188,107,384,843,53,974,501,181,603,228,365,328,826,272,704,411,364,110,953,906,22,933,302,423,442,644,135,231,51,469,968,482,630,386,285,629,286,342,550,225,394,288,997,450,592,727,115,494,161,534,892,939,285,170,765,363,170,87,120,841,134,727,362,695,131,836,655,701,383,289,249,743,950,630,357,516,933,988,262,70,145,274,913,387,896,181,358,192,946,212,31,408,138,153,680,831,266,580,208,426,572,151,625,103,170,129,248,250,238,937,994,51,583,593,379,943,657,338,598,153,807,452,516,704,474,107,818,260,727,5,754,654,470,172,469,963,992,764,0,283,628,859,464,747,825,67,366,825,708,538,6,280,92,346,900,471,373,241,473,707,371,843,120,881,470,669,986,450,320,332,360,486,99,741,203,711,229,808,916,51,75,491,268,157,422,308,61,831,588,155,450,957,70,386,105,9,828,241,737,449,112,658,216,288,674,679,888,199,640,998,419,407,453,406,295,88,1000,402,826,267,410,685,292,445,319,234,215,490,233,258,55,524,371,113,984,694,502,194,239,373,459,741,355,599,868,169,660,597,687,406,770,906,510,713,108,910,114,277,360,124,756,897,453,228,965,481,762,147,384,420,624,922,427,282,316,529,306,780,48,684,66,700,601,233,372,739,71,410,430,943,642,573,400,827,215,668,235,577,658,11,797,75,440,402,312,764,775,738,257,849,325,658,884,736,670,394,371,653,497,193,342,924,243,864,243,434,888,7,636,696,162,735,744,559,461,666,524,27,788,374,446,564,815,981,11,837,928,844,403,50,581,643,352,640,59,495,139,534,526,913,539,82,669,239,82,504,264,786,281,236,444,88,745,125,87,878,904,110,654,126,567,740,947,839,485,12,439,656,192,57,109,866,692,538,458,808,739,427,525,178,735,500,123,425,690,219,391,703,878,71,582,159,846,203,924,138,428,517,659,62,391,900,599,377,966,612,627,17,26,436,694,246,840,907,985,668,995,373,446,236,350,671,790,532,702,659,2,396,213,945,253,902,706,873,961,808,451,529,298,938,883,333,638,992,437,467,979,818,220,593,538,672,679,865,939,759,679,840,531,440,348,444,341,676,161,895,764,814,86,559,879,648,344,872,915,448,654,706,974", "286,500,967,106,735,823,163,953,855,984,203,778,21,147,141,384,302,66,640,149,936,273,306,925,852,378,77,520,899,204,115,763,536,701,285,411,568,350,358,617,398,147,138,82,929,541,967,661,667,335,150,533,545,821,108,104,404,36,166,486,130,920,322,704,228,247,47,255,20,505,59,780,679,370,241,62,955,211,904,583,143,43,246,636,868,110,984,328,239,459,886,38,993,954,769,29,235,810,65,666,284,191,775,41,933,275,911,692,632,650,766,472,627,14,782,328,335,402,798,873,519,542,969,415,766,617,911,896,115,423,616,461,607,789,468,114,722,593,274,446,629,279,105,993,463,69,979,688,240,573,859,232,584,36,858,753,641,43,493,567,815,551,922,722,879,831,330,319,496,968,223,930,427,943,615,563,144,96,761,868,858,464,672,366,926,236,953,835,133,945,846,286,805,38,38,759,412,396,574,104,434,34,443,894,193,409,840,190,718,350,230,742,619,880,190,834,464,950,898,629,168,563,243,830,343,785,644,528,700,629,34,636,727,486,503,523,384,407,82,845,671,152,49,287,419,542,545,101,806,762,518,599,613,546,274,328,879,384,604,637,167,438,995,874,247,187,198,582,323,777,261,305,545,138,848,114,190,934,178,619,247,228,900,873,680,391,711,947,853,320,43,641,587,5,382,513,722,401,844,224,154,514,616,473,97,458,281,851,499,3,985,691,57,882,688,935,6,290,566,840,530,880,249,83,107,515,586,226,873,415,462,314,227,144,215,45,559,506,528,17,238,353,135,622,595,361,661,220,195,149,237,705,591,583,114,938,197,779,843,559,221,437,377,520,313,782,113,437,141,941,95,909,270,321,589,784,80,326,546,346,981,258,596,494,385,465,227,755,838,284,671,436,435,151,241,993,261,17,295,745,113,623,594,251,426,409,683,531,978,258,356,24,66,330,627,194,759,322,352,650,187,531,906,353,268,133,390,704,166,703,922,504,412,750,605,985,751,599,470,566,100,175,43,483,395,495,480,684,808,959,632,416,112,27,669,846,608,773,422,973,729,163,807,167,299,650,92,705,676,780,523,548,51,305,627,916,669,395,567,452,352,513,756,216,969,305,231,772,526,603,53,223,500,895,806,440,884,599,48,46,375,474,942,493,325,8,107,986,845,35,865,488,788,736,755,703,373,131,43,78,159,321,788,23,604,170,539,729,365,274,908,797,57,940,831,645,423,484,514,147,983,322,119,643,123,765,604,109,153,345,923,173,409,892,111,709,432,118,808,598,553,45,371,937,219,4,355,82,549,504,249,410,679,309,86,414,955,320,325,171,56,835,301,330,126,348,682,480,884,879,870,72,644,385,148,493,966,534,571,796,502,414,622,847,703,502,269,966,773,180,812,600,720,885,192,111,505,973,699,817,730,437,508,706,708,36,429,318,633,320,959,648,923,405,76,283,542,949,721,283,0,664,657,471,953,270,401,461,390,23,974,733,727,828,899,952,406,286,362,677,650,247,88,159,573,772,531,392,500,63,679,43,694,801,225,198,497,84,999,48,24,493,170,467,518,426,720,938,576,370,491,863,90,261,684,491,414,927,717,323,305,740,926,712,90,245,705,931,105,307,619,136,464,708,752,646,233,507,681,132,147,913,582,154,740,799,511,979,69,610,418,290,716,92,532,85,913,883,781,344,919,174,858,737,533,614,560,85,100,863,348,162,877,292,454,698,529,914,77,144,7,382,402,861,537,503,240,339,578,515,482,150,394,280,296,462,813,843,931,771,217,958,184,162,457,585,552,120,532,857,730,376,74,503,609,541,671,232,401,70,684,513,715,19,774,13,570,370,307,59,958,735,231,700,859,607,9,589,172,336,468,358,260,756,611,272,344,5,764,57,481,5,567,125,172,127,38,538,439,634,569,254,106,115,244,594,690,820,887,7,511,81,740,883,824,907,854,882,300,74,892,306,60,445,359,78,926,547,184,57,765,95,170,856,308,630,189,703,263,826,513,345,712,274,129,597,849,844,671,129,647,193,169,673,614,904,150,181,135,800,285,921,235,923,923,433,680,506,687,473,214,315,206,439,194,739,645,555,281,418,612,760,318,454,935,316,44,425,263,564,442,340,625,60,806,103,551,668,435,146,98,863,820,21,50,167,667,519,351,509,169,380,182,89,38,358,57,429,969,227,971,90,687,199,325,134,744,873,165,833,595,690,112,217,279,895,30,108,344,758,211,693,937,905,414,872,466,200,299,704,309,435,701,460,985,614,503,299,260,883", "275,276,206,322,829,430,389,103,230,718,567,677,896,945,107,475,382,369,747,237,358,877,511,364,120,693,337,996,604,814,517,653,654,829,55,884,163,985,450,550,889,714,361,516,402,661,886,164,145,929,613,567,121,853,240,463,50,963,625,246,563,889,73,397,853,649,940,531,808,138,190,629,666,114,896,62,144,422,467,84,861,430,773,259,479,387,688,131,770,911,359,801,933,802,271,21,98,958,136,936,573,345,832,728,654,636,813,303,460,686,402,918,830,500,387,718,593,295,848,127,419,445,972,557,940,863,778,598,379,401,172,157,867,205,631,821,905,193,85,895,574,96,452,751,925,136,713,989,465,632,287,34,147,270,372,181,983,487,324,922,621,958,885,373,427,365,998,680,132,157,190,308,766,222,221,932,359,611,667,187,938,643,881,939,721,231,626,872,154,687,304,219,754,707,678,927,254,33,664,420,775,221,825,484,46,782,542,788,349,442,564,89,237,114,953,751,989,205,960,189,722,700,106,130,541,25,220,230,758,360,695,246,296,743,537,679,549,103,477,98,61,625,743,488,372,9,520,256,611,383,334,300,527,136,811,640,954,569,909,930,318,764,228,704,426,100,693,234,956,630,277,327,433,558,626,52,324,566,628,319,335,522,451,379,510,50,565,692,387,653,307,778,789,599,619,834,411,239,935,574,134,239,630,649,482,146,656,491,446,54,805,171,182,247,223,579,642,245,44,314,176,559,722,588,431,4,489,823,424,217,757,273,527,74,550,902,217,51,783,757,86,741,552,742,256,900,348,996,664,231,759,220,241,53,882,400,487,723,996,5,660,492,321,827,163,527,455,674,82,820,109,968,479,944,230,668,946,12,691,790,68,734,424,285,953,156,487,183,203,751,509,248,64,42,448,378,64,751,4,295,306,517,308,418,608,579,846,492,573,667,449,458,451,925,66,694,799,672,104,205,291,467,53,705,780,284,586,593,750,928,955,546,836,929,718,331,52,882,238,535,458,952,694,143,360,2,59,688,175,555,649,353,569,771,537,360,778,320,20,958,350,79,725,865,786,500,613,28,720,227,73,233,570,931,484,675,209,699,632,282,184,444,757,356,159,796,698,772,626,400,630,940,191,234,936,222,392,79,314,884,830,857,665,821,454,147,284,130,119,351,362,380,605,876,940,974,323,759,375,370,58,479,372,941,470,184,105,853,566,173,695,148,558,906,527,347,2,526,366,246,414,595,389,938,87,282,265,609,357,245,631,86,297,198,166,410,730,195,86,794,449,977,796,561,546,830,600,744,83,926,837,107,506,392,434,771,480,28,7,315,513,177,420,739,637,556,981,930,585,55,898,896,24,719,856,745,602,157,965,983,342,457,122,717,182,624,273,140,906,67,533,538,440,458,936,403,192,60,586,643,95,746,417,967,959,54,983,133,11,338,497,960,112,327,143,927,491,225,377,628,664,0,251,288,442,642,221,706,972,11,761,773,23,296,928,829,859,185,237,452,398,417,410,819,830,431,755,996,247,959,885,555,329,612,34,151,345,141,418,249,29,873,166,165,239,963,871,47,983,238,981,960,704,220,953,938,287,191,370,37,597,487,473,671,534,674,103,601,614,520,862,12,723,599,620,589,891,857,296,862,471,196,349,100,902,584,537,559,690,112,978,64,766,719,229,632,348,259,738,96,892,305,836,310,766,929,741,841,243,950,304,130,616,373,199,43,576,875,797,187,906,218,322,572,88,875,315,823,566,302,89,6,685,82,773,227,920,257,141,398,446,966,454,582,802,639,342,859,519,888,52,221,495,791,571,15,184,147,712,657,490,351,315,969,15,284,550,684,877,983,609,633,611,303,65,906,840,794,897,93,119,376,630,173,841,882,475,182,147,915,573,244,773,823,618,559,327,489,420,63,720,990,383,741,488,350,731,270,651,175,944,322,777,639,637,912,917,114,28,128,665,732,76,641,369,663,179,998,104,320,781,128,464,930,298,535,71,738,497,448,874,744,923,162,696,922,137,284,724,319,875,700,123,42,507,943,735,799,367,359,674,49,765,348,30,416,910,956,724,700,141,771,718,53,200,886,560,260,118,667,410,376,654,484,995,415,492,10,430,718,187,276,525,103,894,937,845,39,871,361,711,527,793,440,896,939,791,146,543,381,232,162,598,549,638,425,653,243,528,176,389,367,702,667,496,200,245,619,520,93,740,355,777,417,408,297,301,239,294,440,618,353,652,833,378,162,558,959,354,350,247,347,700,832,225,787,725,647,986,593", "297,191,595,482,644,75,26,928,680,795,907,102,200,380,685,122,496,967,489,289,741,967,370,323,330,673,287,302,25,793,48,848,42,823,602,573,891,52,705,517,496,914,181,679,889,670,454,832,94,205,530,232,371,878,56,818,697,517,560,138,271,826,329,162,769,906,604,343,276,710,356,642,198,547,460,537,659,775,220,97,716,1,516,123,187,227,490,866,76,409,529,462,652,138,366,57,283,43,671,864,13,439,692,918,239,297,908,166,3,648,731,380,188,283,811,467,513,956,815,443,180,222,894,264,362,594,705,196,833,748,421,960,649,135,603,803,217,627,156,716,180,723,124,473,162,788,569,221,180,287,667,116,31,98,938,810,333,512,205,442,54,551,78,398,242,523,745,533,429,427,574,679,638,941,901,662,851,371,530,206,607,773,160,944,908,65,865,935,540,286,860,475,443,692,640,776,711,152,325,686,800,840,658,11,609,65,866,364,240,971,825,641,17,4,499,848,784,693,774,235,106,420,574,666,622,703,753,319,216,304,521,414,47,250,903,554,279,670,5,553,721,194,365,193,470,38,122,407,521,69,825,435,159,675,442,361,105,551,664,107,436,45,992,188,313,883,951,308,150,764,663,994,835,629,120,537,850,631,839,846,884,720,809,832,353,299,127,191,618,808,360,394,329,511,695,687,136,748,850,933,299,397,677,23,706,188,870,590,250,171,228,612,385,637,249,122,554,410,767,311,524,435,339,393,266,38,117,932,391,282,809,408,143,838,591,983,278,613,876,35,298,404,862,599,979,45,440,218,814,996,703,976,834,406,363,821,522,466,559,385,318,953,74,335,696,242,22,819,454,812,447,853,533,672,909,757,714,818,667,315,822,674,696,119,590,390,510,247,20,381,504,743,172,532,199,266,786,333,289,862,731,859,869,917,212,319,529,176,670,586,514,145,222,656,777,492,805,623,549,920,354,263,129,243,24,977,521,866,924,602,225,430,454,562,831,525,970,388,83,566,450,905,884,923,71,884,812,815,905,634,23,382,132,335,60,624,727,148,138,919,396,900,260,216,207,400,907,507,666,788,316,484,961,921,72,208,858,756,610,289,568,860,657,664,978,61,91,588,676,24,667,551,872,923,254,143,219,631,404,296,710,863,978,673,741,240,510,471,218,45,810,759,764,311,696,544,418,306,376,675,775,472,791,522,279,590,732,825,621,240,469,499,563,810,840,519,53,479,969,96,210,723,462,989,471,549,663,489,533,259,430,539,570,37,273,924,854,703,690,868,388,2,885,243,226,285,151,87,437,820,466,758,555,357,949,777,530,966,240,320,730,603,831,389,569,239,731,233,837,439,733,941,773,67,903,126,477,406,882,859,143,308,182,58,364,169,644,371,67,907,857,806,607,472,49,964,645,419,413,215,770,184,853,131,743,464,600,842,954,882,850,680,444,341,75,147,533,337,80,859,657,251,0,446,559,783,318,430,505,753,114,970,341,959,915,433,413,759,228,282,395,915,717,654,591,437,436,855,896,102,653,316,698,118,119,186,823,173,665,870,831,648,599,75,393,914,766,957,944,392,931,402,995,597,97,675,349,820,655,506,689,957,824,901,797,413,382,263,768,229,122,613,276,803,256,356,819,617,138,667,761,504,518,672,187,240,255,592,132,369,118,226,222,137,822,941,44,317,550,166,916,27,888,404,289,778,167,12,947,889,760,498,127,453,483,566,441,873,535,426,160,306,628,807,705,139,251,199,75,808,330,586,719,209,741,558,269,936,608,539,988,681,409,874,637,535,393,679,878,457,535,881,981,260,387,635,557,986,962,152,916,149,259,869,623,865,41,877,224,340,276,858,585,193,892,204,762,896,741,472,992,243,670,932,189,276,838,507,237,150,181,303,135,604,63,25,309,485,953,809,51,667,614,240,588,606,83,277,625,967,38,556,844,166,314,300,314,147,53,640,579,926,885,931,973,984,256,953,617,261,847,227,465,581,567,603,220,665,834,179,155,200,886,152,336,883,573,426,187,452,975,289,571,853,712,59,588,145,367,352,149,955,973,974,64,979,895,811,499,569,334,640,535,75,987,173,834,838,428,818,788,230,743,555,509,20,707,318,168,628,586,423,222,99,121,100,38,605,163,869,842,877,506,765,228,564,50,896,467,704,781,505,946,819,65,54,173,757,295,37,811,24,134,639,436,27,2,137,306,830,216,941,211,672,498,339,835,537,832,202,186,697,298,828,755,389,139,163,226,986,843,933,774,56,940,627,749,644,51,271", "246,218,5,542,115,619,543,855,931,346,724,220,46,128,297,722,983,253,720,836,460,903,798,753,999,67,838,87,416,234,146,460,784,127,298,921,798,657,691,907,67,775,843,543,211,407,51,790,650,12,755,778,109,851,921,125,511,601,17,770,938,322,50,496,354,257,800,350,270,145,727,686,45,276,73,42,756,909,274,438,713,349,138,798,122,825,622,751,120,267,39,553,670,636,895,809,721,684,519,596,36,212,899,866,768,972,164,885,902,61,874,41,201,531,26,457,597,740,553,748,3,175,829,829,9,369,173,902,754,43,900,19,474,692,611,917,463,950,966,556,747,132,21,352,558,484,33,662,315,749,140,227,355,680,116,512,56,691,591,162,373,721,701,974,424,445,408,631,747,510,972,234,825,340,398,521,727,601,836,591,410,65,220,58,271,712,502,44,587,531,502,915,631,905,813,709,317,38,379,825,533,457,345,90,937,138,413,738,759,455,338,53,706,978,933,649,808,219,170,585,108,128,811,139,754,408,338,854,307,348,260,160,763,433,432,552,294,442,382,916,154,580,656,274,888,301,633,608,57,770,17,287,226,530,339,15,568,946,108,382,241,440,603,751,908,175,259,796,653,360,398,813,943,769,123,49,174,29,59,2,434,2,872,829,692,687,26,757,154,983,872,873,587,44,156,601,226,964,791,901,505,12,586,385,797,994,236,990,231,17,51,410,246,623,196,326,880,676,716,505,743,605,192,739,908,482,965,83,440,950,331,97,80,159,276,16,40,662,119,701,72,924,210,725,622,680,484,163,502,564,606,200,165,20,970,343,157,800,903,560,705,689,542,674,130,384,837,974,855,103,855,219,858,7,283,273,507,331,938,434,708,432,459,422,46,8,989,659,603,111,595,315,492,164,750,560,701,593,713,184,145,175,738,813,460,516,360,551,354,524,207,980,953,165,330,111,51,768,367,246,280,124,441,668,295,793,799,807,699,521,501,754,728,999,503,713,500,248,100,410,359,907,994,103,716,691,919,480,467,699,310,275,787,417,468,904,919,432,67,910,583,909,746,336,168,716,569,444,816,894,643,139,177,4,441,216,951,770,673,169,236,552,512,347,572,411,269,624,997,31,994,696,629,580,558,652,527,739,823,596,430,750,594,636,114,672,314,251,983,125,169,240,10,37,812,734,492,373,807,325,836,136,892,800,585,397,731,68,739,570,508,684,878,489,257,992,757,54,822,628,168,160,889,449,934,858,249,232,585,807,739,761,278,635,134,231,281,338,16,731,321,574,223,827,930,93,893,588,361,152,457,834,100,553,350,679,765,793,670,867,67,125,714,504,542,273,949,441,259,733,135,283,328,420,475,291,881,325,490,340,796,287,933,245,343,116,770,258,615,358,290,657,918,10,995,897,184,883,770,18,644,440,948,720,736,659,462,156,152,427,760,635,393,479,278,956,958,989,949,464,471,288,446,0,664,858,119,754,875,334,368,403,750,767,292,11,204,744,186,579,390,367,482,160,594,276,852,846,164,869,494,155,920,205,530,872,764,473,7,804,793,662,792,919,228,821,264,312,172,246,955,689,888,255,870,132,887,444,740,927,505,866,198,608,580,984,607,281,338,791,877,696,253,109,541,890,384,224,193,700,671,520,632,400,578,49,719,803,433,286,289,201,596,62,307,972,787,95,655,416,903,860,259,293,820,481,520,857,271,87,14,793,424,199,769,29,512,797,281,143,49,426,498,448,770,165,561,282,194,728,697,317,175,588,206,918,551,523,383,868,714,973,194,74,924,39,373,860,179,179,584,461,923,643,627,294,419,432,23,832,93,542,910,220,251,647,994,25,868,602,46,340,771,75,422,534,329,729,562,870,351,277,769,279,110,910,514,790,584,510,64,660,69,690,51,190,595,349,562,244,497,239,690,251,358,342,599,417,692,264,759,731,21,40,267,604,290,428,459,190,303,15,832,969,661,535,891,667,713,472,343,696,493,876,726,727,129,109,874,259,12,16,915,130,536,433,294,97,243,437,49,570,78,473,454,947,272,252,260,372,657,957,556,369,70,230,350,738,439,985,426,416,981,348,180,843,378,233,638,815,18,525,42,916,546,137,574,499,766,680,373,655,537,489,379,921,872,550,698,317,143,63,723,597,924,192,135,517,70,183,10,651,262,230,278,322,528,393,80,258,966,271,249,349,143,204,391,9,282,994,181,48,325,567,753,313,862,757,896,84,160,37,329,641,810,362,559,136,904,369,594,216,338,313,13,462,520,484,207,672", "904,503,895,746,935,463,593,883,594,773,602,511,535,334,353,690,238,717,504,116,348,770,518,805,576,25,695,762,476,293,524,527,753,524,499,914,167,507,55,830,520,347,11,849,474,124,35,549,491,628,484,387,603,582,210,126,459,574,846,701,449,512,504,579,73,516,488,223,335,854,35,742,832,753,212,25,358,407,153,24,525,688,222,787,950,838,657,325,412,910,585,216,896,436,225,554,74,846,165,775,551,762,733,159,748,806,716,875,938,424,95,578,374,41,371,297,36,807,937,363,740,547,77,193,20,319,228,719,910,194,48,318,444,213,382,202,365,296,290,872,125,644,37,598,921,56,797,280,606,629,498,132,196,800,461,436,565,552,643,419,937,243,65,466,968,995,84,831,265,23,380,827,655,994,364,256,113,479,764,870,359,43,916,387,842,120,71,942,133,920,28,512,962,772,928,996,583,580,606,952,936,714,287,149,516,195,722,261,211,207,271,767,436,646,525,671,194,355,626,217,780,135,538,882,267,159,474,442,234,147,315,175,199,254,120,953,178,934,295,403,505,595,422,53,65,637,903,651,533,342,712,9,68,378,77,625,215,638,909,732,988,83,485,834,108,751,194,299,897,877,103,869,631,727,627,975,657,329,155,986,396,487,270,854,595,646,86,419,799,440,721,82,581,798,506,132,884,778,534,940,809,634,50,808,233,300,854,302,689,381,702,839,384,282,546,562,455,477,385,58,158,30,481,81,574,371,517,618,710,756,372,412,491,743,658,942,937,83,279,261,184,753,857,848,159,304,404,856,357,529,205,854,421,754,532,790,956,778,225,622,534,118,233,301,180,911,495,661,553,607,553,699,360,403,361,18,339,243,625,923,816,348,854,455,629,912,313,696,739,596,54,242,589,506,867,156,924,717,839,549,733,380,355,727,960,55,956,52,386,590,561,466,242,395,638,584,195,747,963,2,574,456,630,16,972,70,236,779,299,664,867,517,429,717,571,413,26,172,492,42,917,730,106,449,408,997,36,445,265,354,420,937,642,867,123,251,352,798,259,27,763,520,446,260,686,519,286,44,770,490,984,80,778,670,139,804,907,862,520,992,513,265,847,111,658,73,355,918,961,646,32,278,841,97,129,609,864,379,720,945,859,848,841,186,853,442,633,168,456,465,252,431,666,248,105,955,831,832,656,650,353,336,819,432,785,820,296,125,29,3,71,478,615,219,317,559,241,66,117,396,796,55,561,25,136,839,250,887,970,758,685,83,397,822,369,957,623,251,662,577,586,330,62,793,71,169,744,225,644,811,386,953,747,545,582,96,429,263,145,917,559,424,122,484,477,531,93,39,70,997,922,92,311,668,742,709,865,755,829,533,408,394,812,980,158,230,940,289,760,446,874,55,787,587,457,270,353,738,162,98,442,458,563,710,845,23,161,209,76,496,395,584,106,790,933,966,773,594,853,747,953,442,559,664,0,97,986,905,337,344,463,499,723,698,486,582,845,713,448,318,615,773,920,397,785,805,655,836,234,146,338,827,711,135,791,741,60,970,225,223,220,862,529,268,185,370,664,327,583,990,521,983,451,376,996,502,118,793,120,356,362,754,509,820,265,245,14,39,459,914,377,778,577,842,201,625,934,800,660,524,977,535,779,985,11,609,469,476,2,739,823,488,469,810,656,17,403,596,364,795,574,9,515,165,902,816,356,781,480,190,752,32,35,553,209,673,635,679,459,657,70,147,617,625,682,962,478,216,20,534,965,963,625,364,96,455,851,490,141,730,208,955,336,110,742,396,787,496,114,269,514,448,645,974,345,750,773,382,745,345,549,381,314,501,737,727,666,911,537,42,787,433,396,545,540,465,599,596,298,188,703,704,728,934,694,597,225,154,179,235,588,205,730,72,140,597,171,34,453,588,298,66,616,463,182,443,881,722,204,348,869,489,430,76,65,894,357,913,833,30,372,627,865,444,714,881,141,304,992,538,997,583,974,896,452,936,296,400,860,369,617,132,140,595,681,725,480,828,965,781,271,886,556,221,506,100,939,354,152,907,662,668,96,909,335,548,123,103,410,762,160,15,761,963,860,395,415,539,361,948,384,923,366,673,385,975,314,988,308,540,104,157,199,169,424,623,730,282,289,785,84,576,731,302,190,823,431,663,696,105,483,64,61,338,107,324,106,130,637,302,722,11,582,877,861,448,628,761,784,841,293,493,930,77,158,858,896,320,109,545,581,403,942,737,669,937,678,33,839,64,751,148,49,305,367,732,426,24,14,385", "24,751,787,391,807,196,847,117,105,259,150,303,366,866,357,676,182,587,350,171,520,491,659,614,938,618,521,501,775,377,794,641,583,892,188,813,723,274,899,79,163,855,927,121,579,243,348,340,307,580,624,742,475,732,211,268,899,325,259,614,669,735,942,460,381,128,498,708,800,953,271,622,325,301,802,885,473,927,892,375,733,814,166,491,179,817,918,33,138,690,202,693,314,823,659,956,815,736,485,710,252,47,80,732,559,459,240,497,645,243,655,655,895,212,199,968,423,414,181,838,342,509,724,78,362,506,156,261,500,389,691,926,644,105,743,441,843,296,384,331,230,750,348,663,946,735,816,85,869,782,455,832,369,604,154,43,263,778,841,293,894,920,465,75,129,624,162,570,258,444,574,760,298,109,976,658,763,70,820,188,245,608,462,870,571,710,607,831,167,916,300,778,799,22,981,375,530,714,759,772,750,80,189,998,249,905,887,386,248,629,396,61,149,300,724,928,359,650,801,247,13,284,20,126,338,83,136,629,230,750,887,865,590,862,659,931,16,78,271,944,189,681,110,904,65,119,842,324,737,562,827,613,643,535,171,186,16,830,55,2,269,732,130,885,609,728,579,957,839,532,861,355,24,24,497,871,42,488,76,586,508,24,732,202,756,38,565,389,929,340,224,185,564,703,998,743,523,292,33,952,712,851,590,274,781,531,70,443,952,319,98,958,664,1,229,15,407,3,333,985,117,899,870,567,714,167,188,806,908,177,114,33,274,434,252,488,169,483,544,919,738,203,191,448,373,618,232,297,296,37,50,886,16,786,831,843,181,388,177,402,618,57,240,534,159,835,651,121,296,656,669,75,617,544,672,123,997,596,287,719,668,550,741,317,25,937,258,919,864,576,15,942,25,544,411,558,579,728,327,421,294,972,462,932,740,377,33,879,887,477,558,481,856,273,595,745,252,135,937,717,897,842,175,339,83,985,905,746,242,803,609,354,831,688,639,730,100,671,745,811,464,695,631,419,999,337,870,33,965,881,467,640,526,523,210,480,204,155,985,846,160,936,359,584,965,597,280,20,828,661,611,742,284,859,243,729,68,197,760,571,708,118,579,598,895,464,224,869,299,971,822,459,544,673,406,845,469,62,736,30,905,441,588,444,15,251,899,585,376,174,328,517,61,915,27,224,283,911,310,421,520,303,153,957,652,763,808,146,553,52,297,136,836,245,821,867,83,693,557,74,146,133,924,217,655,308,829,537,641,94,682,153,903,459,911,839,885,422,432,116,154,534,628,798,967,108,621,74,300,804,430,800,296,682,723,283,576,926,940,592,367,521,112,870,511,853,463,633,317,581,438,503,198,244,494,360,761,72,731,900,738,943,538,270,291,793,584,708,937,416,777,112,61,256,679,449,602,35,638,509,322,318,49,898,490,924,644,509,794,818,743,119,7,561,872,63,883,294,851,825,270,642,783,858,97,0,991,480,901,265,246,391,648,119,187,710,45,35,507,359,646,846,997,582,510,89,501,266,217,121,143,28,475,599,955,304,666,70,196,92,436,670,658,654,483,281,984,665,303,139,283,419,906,112,873,483,349,687,143,16,896,973,472,500,499,905,691,743,640,761,263,633,440,414,178,848,697,14,462,75,37,724,816,805,853,631,315,213,158,870,931,609,160,507,221,921,576,261,277,663,777,876,713,431,115,565,452,576,443,432,957,801,10,839,55,684,109,610,907,629,205,881,464,754,130,835,44,865,590,674,234,871,818,822,511,749,744,25,763,301,601,991,876,349,234,319,586,862,903,380,427,242,404,499,602,131,449,645,363,620,674,494,790,402,989,665,731,334,4,114,707,174,738,510,891,124,468,582,736,384,501,583,186,481,246,793,874,716,17,359,429,485,115,667,523,907,149,316,451,923,425,10,980,58,641,275,528,799,579,722,204,309,921,754,822,929,379,420,711,112,894,242,504,453,224,233,557,591,504,300,853,152,218,590,109,258,654,429,451,6,5,290,28,637,363,243,239,899,743,410,442,104,130,8,560,210,790,696,676,279,471,10,239,555,52,989,504,518,790,355,665,644,229,246,659,460,70,779,507,779,259,314,767,996,336,816,345,314,901,869,817,565,327,544,137,714,196,412,791,315,556,458,878,954,851,16,435,435,205,427,728,475,313,58,691,194,257,11,883,925,262,179,12,322,942,276,324,993,700,487,873,168,582,385,443,149,563,15,549,754,87,108,83,142,648,435,630,406,772,660,485,961,107,818,113,800,952,20,412,396", "327,994,47,529,283,760,648,45,617,546,442,585,258,16,159,805,303,582,154,757,947,579,195,138,56,81,479,892,613,643,185,529,438,536,831,408,205,686,999,529,352,130,22,300,910,513,832,690,674,921,49,111,4,431,410,894,58,210,342,14,431,90,594,133,915,723,98,499,720,314,639,587,834,52,263,831,535,30,138,579,38,566,490,895,771,221,394,878,306,657,978,388,131,834,57,95,478,796,621,819,707,753,459,411,701,51,98,406,157,554,465,998,637,381,175,428,43,160,117,409,79,130,517,984,166,294,931,642,621,530,903,902,608,372,770,443,780,855,925,832,963,396,936,292,959,853,466,249,442,86,255,549,119,492,110,614,557,263,371,886,14,442,986,578,210,884,638,594,22,693,664,886,35,903,859,223,467,884,381,519,43,189,204,124,780,746,121,570,23,116,696,174,166,796,360,222,704,243,680,544,516,769,93,275,630,187,406,834,421,336,752,288,110,129,80,74,909,937,894,145,557,948,385,945,191,761,798,766,827,153,873,513,256,517,802,276,462,298,571,353,357,259,756,815,390,486,639,12,237,739,599,794,905,679,782,180,961,9,566,308,442,61,230,645,787,899,676,380,881,420,805,634,818,117,316,332,63,961,260,211,208,69,311,67,996,378,84,132,318,139,223,338,64,362,967,43,943,217,364,194,762,814,555,926,594,244,108,501,903,613,630,410,562,920,606,41,75,530,120,233,93,936,211,896,408,280,776,919,253,349,325,278,695,536,908,292,183,219,543,636,218,112,583,308,617,945,226,554,850,382,959,700,234,763,247,719,698,870,353,838,675,965,638,329,913,271,669,928,531,994,410,764,573,887,193,301,377,268,304,76,693,154,823,622,852,551,414,663,863,49,541,550,966,648,369,368,948,586,830,893,351,735,67,532,176,182,771,863,523,339,17,95,917,901,575,582,249,952,72,721,179,113,673,661,438,707,694,220,58,280,177,502,240,2,261,299,149,79,881,545,643,95,100,238,846,229,143,954,742,847,532,666,560,203,670,222,253,931,430,757,967,604,96,833,639,390,233,904,332,368,78,52,978,737,277,795,404,908,450,349,92,274,923,88,568,808,315,709,121,81,433,198,567,807,164,246,812,379,336,216,59,1000,841,388,185,323,701,72,379,163,267,30,668,990,518,712,158,977,925,444,122,193,974,192,876,91,997,196,607,206,236,264,897,267,144,362,871,490,453,708,349,302,933,230,503,730,493,986,684,414,925,507,741,188,19,342,24,957,255,74,46,479,336,682,370,924,628,482,729,104,569,293,86,815,395,339,628,241,849,913,658,583,769,748,570,375,704,838,717,380,19,53,768,527,762,124,595,155,966,718,275,943,793,159,525,402,269,490,156,68,144,652,395,243,733,737,327,795,13,546,172,856,782,851,48,393,875,804,938,217,459,684,557,633,332,687,472,660,99,67,401,221,318,119,986,991,0,581,985,669,360,135,140,232,42,748,995,874,468,866,312,97,496,92,353,400,598,559,357,126,906,908,361,902,266,570,438,713,224,968,954,308,400,178,747,247,366,300,335,379,363,954,109,440,664,165,285,255,150,470,834,78,505,328,9,731,700,387,160,252,710,989,323,19,626,680,331,421,233,348,467,939,300,707,689,201,411,726,651,350,440,781,673,939,794,940,118,169,97,783,60,921,402,822,324,53,747,810,665,814,937,801,203,35,257,80,519,457,59,876,204,715,244,83,298,159,577,43,431,580,547,680,236,199,20,193,357,935,894,854,604,874,605,900,360,474,643,188,981,177,862,728,400,968,724,513,502,515,6,740,495,854,392,978,900,217,534,50,899,29,512,143,128,239,761,694,484,235,406,701,385,401,484,218,820,1000,988,407,388,949,652,132,305,230,734,95,183,83,124,220,429,441,889,611,726,658,303,954,493,353,100,56,570,327,197,705,259,265,761,107,608,677,756,838,987,188,751,985,976,10,765,73,474,709,68,163,972,729,486,48,473,4,930,538,381,852,528,404,473,956,11,452,604,117,675,784,503,379,74,979,7,172,209,570,72,111,526,565,861,695,128,57,660,140,192,870,33,358,327,643,792,330,421,897,184,210,611,669,767,45,25,663,657,891,595,337,569,628,682,853,455,100,833,441,55,458,857,836,455,278,848,234,635,563,975,421,123,281,845,734,90,713,297,243,270,920,424,433,261,689,57,429,606,594,814,735,457,802,4,329,2,745,219,232,666,65,26,746,309,410,347,651,716,431,419,131,667,628,153,362", "474,171,844,74,48,490,138,955,359,564,336,5,858,356,158,149,380,774,681,111,474,350,752,576,459,673,623,149,505,148,695,585,48,484,457,647,130,955,97,386,230,141,26,520,285,419,965,805,941,177,30,6,750,922,127,203,868,671,551,686,569,834,227,348,774,574,431,692,715,271,951,408,768,330,944,168,960,107,425,942,20,120,600,154,452,404,432,736,99,793,163,627,11,333,507,484,205,619,847,418,881,530,70,759,622,438,522,885,963,595,801,423,647,404,982,449,43,925,96,112,695,693,436,360,652,383,269,580,228,702,219,574,281,626,240,973,752,739,412,130,50,312,212,352,646,879,112,203,818,682,646,698,122,989,121,950,791,670,848,680,440,622,243,858,323,600,324,3,899,388,170,203,749,60,164,89,705,129,155,583,801,487,395,50,853,185,452,550,854,532,457,668,956,175,43,872,501,920,897,406,630,5,105,539,52,52,55,184,47,101,850,367,583,470,559,233,470,663,429,894,32,140,102,550,835,24,860,364,970,257,245,114,949,804,734,176,208,118,161,844,212,337,12,672,814,965,796,26,228,85,830,19,171,591,716,206,142,760,867,33,562,292,335,617,654,450,734,863,152,596,573,627,270,932,657,738,562,635,606,112,305,529,383,959,39,763,103,410,643,345,99,228,76,925,385,614,609,742,574,241,115,274,267,436,642,979,859,284,773,340,312,821,151,93,739,897,868,828,849,531,301,306,193,977,215,243,620,829,630,110,604,298,4,596,788,455,208,160,256,183,283,918,249,175,866,568,855,816,805,140,761,881,868,536,198,53,792,473,56,260,604,945,141,849,244,546,114,857,866,425,206,655,373,344,970,917,383,366,189,12,220,994,479,935,810,45,9,949,135,197,329,194,332,501,647,587,632,14,735,340,924,22,132,155,564,356,286,206,77,305,971,63,618,749,414,799,927,695,694,573,432,598,590,511,896,872,901,402,256,510,238,693,640,708,226,735,421,232,628,960,670,222,848,748,999,518,186,430,242,288,419,776,984,412,261,483,927,138,635,734,119,586,812,304,861,469,886,174,504,429,219,433,942,382,223,420,363,790,555,141,984,375,892,279,911,978,795,266,71,887,268,801,948,887,148,397,713,166,441,567,902,283,829,245,790,816,629,124,310,452,40,865,221,558,482,735,660,690,921,393,17,750,157,371,583,141,603,94,484,575,572,478,449,271,84,598,877,305,360,230,358,416,217,168,657,495,264,824,958,644,494,544,811,528,937,772,754,169,173,944,743,696,943,838,981,789,460,341,241,640,360,592,140,478,68,702,268,836,316,53,826,290,439,436,604,491,383,938,529,281,356,414,144,234,969,29,769,609,439,235,288,70,203,140,207,24,906,454,380,437,335,848,657,441,132,901,922,910,191,504,892,100,529,65,908,434,428,650,923,330,763,465,715,885,610,458,355,688,570,366,461,706,430,754,905,480,581,0,992,825,975,951,899,970,424,444,595,107,646,905,929,305,436,862,862,829,930,436,270,31,197,897,307,275,938,174,704,826,599,547,735,517,745,554,885,510,14,942,628,794,426,5,625,445,908,835,688,911,899,583,65,887,806,368,361,35,3,608,186,920,987,231,916,489,349,211,834,181,920,176,177,489,74,624,372,565,771,349,307,604,852,157,13,788,63,37,102,771,167,115,963,2,23,627,179,718,789,367,679,150,629,195,702,446,616,519,511,642,297,328,414,318,759,312,720,249,767,396,368,682,914,121,450,302,578,716,768,621,68,277,561,277,294,579,420,466,389,583,233,224,121,134,420,213,117,284,489,397,464,590,683,236,342,45,615,79,6,748,104,301,887,595,114,906,29,600,392,406,958,141,947,599,641,601,85,67,526,93,668,753,888,162,362,34,524,598,363,715,520,828,709,181,462,597,832,952,427,46,210,534,376,28,929,958,499,552,977,457,204,526,40,821,144,451,485,546,180,545,331,209,727,466,389,1000,480,603,347,424,386,839,209,451,910,732,366,805,739,716,755,86,731,176,52,679,413,27,883,193,304,669,433,366,198,6,983,897,919,870,236,492,529,977,190,375,816,461,405,951,433,518,33,94,129,344,33,531,140,792,381,362,45,639,420,581,227,558,565,80,558,862,127,165,761,80,98,749,450,576,820,885,975,612,830,331,261,634,279,732,138,117,301,153,994,187,247,655,542,217,173,424,196,649,525,479,323,695,223,855,224,817,812,268,2,641,671,520,252,979,128,284,46,205,33,55,445,428,853,462,612,94", "455,530,458,858,38,338,134,882,169,265,278,109,980,25,702,491,734,382,564,272,371,880,670,778,822,297,694,11,133,207,220,963,512,235,598,646,769,823,395,768,157,684,972,33,499,336,291,572,760,998,204,453,840,434,808,106,43,18,137,593,957,5,14,826,133,480,787,851,291,548,329,235,335,975,130,4,566,495,879,513,597,184,484,135,685,22,85,314,262,980,504,84,758,812,938,374,235,475,639,332,947,619,438,236,4,721,947,729,714,30,314,700,772,736,790,93,845,186,491,591,315,394,337,442,706,401,359,52,615,28,498,196,874,478,869,476,851,788,395,736,438,607,260,856,728,137,361,639,725,777,173,676,142,649,970,723,746,173,146,150,653,940,74,497,264,135,689,351,786,348,212,348,268,903,82,271,53,427,282,899,911,632,470,367,785,875,282,906,711,828,631,774,25,766,585,591,635,345,939,631,124,811,718,979,51,985,840,89,959,903,546,366,389,285,468,483,117,897,744,215,769,873,143,797,257,170,509,573,485,292,157,289,583,280,185,85,3,289,960,39,334,255,355,302,514,766,468,113,623,544,87,295,342,987,157,480,243,376,718,463,884,881,184,93,575,439,743,492,433,944,515,655,607,569,583,833,305,657,223,998,923,70,432,758,960,190,938,930,858,712,267,98,83,433,503,343,472,757,415,730,497,270,63,108,858,976,449,125,590,473,905,969,16,879,149,191,870,664,877,497,595,629,979,230,118,214,223,578,952,707,670,328,730,897,795,801,595,130,295,889,823,711,944,859,486,42,912,493,9,785,408,105,995,312,191,57,280,263,604,609,316,209,770,350,59,946,847,22,32,148,629,396,925,975,101,579,217,867,431,673,561,432,4,930,30,362,181,908,551,807,567,166,959,906,474,966,884,715,314,529,530,958,581,206,479,798,147,369,917,316,822,807,182,402,726,771,279,817,429,248,734,845,466,421,186,283,765,633,505,906,512,856,596,87,752,202,747,187,948,762,231,25,391,514,544,896,335,554,874,309,240,410,89,90,216,175,211,654,777,624,530,190,455,648,522,414,862,426,910,98,803,628,419,642,986,394,449,829,34,47,86,616,393,52,309,631,274,520,524,573,67,266,979,134,975,257,451,280,493,292,903,30,446,386,88,921,276,405,821,153,606,67,788,689,868,373,671,456,280,867,707,921,12,108,360,353,236,745,438,194,127,471,634,775,307,94,952,877,818,948,653,165,402,930,183,414,854,682,367,875,436,337,235,817,563,880,399,609,888,952,162,595,879,181,511,921,670,302,976,757,792,969,127,716,973,724,837,159,883,622,717,932,656,696,624,925,965,286,654,490,467,805,610,280,404,416,868,13,725,132,397,811,735,432,385,580,615,259,971,330,980,953,631,908,77,903,735,422,417,98,623,321,594,810,65,336,678,2,598,609,150,695,783,843,18,34,592,345,634,825,390,972,505,875,337,901,985,992,0,598,645,259,344,174,360,120,725,837,451,782,41,306,690,220,924,618,687,732,118,188,470,324,803,72,271,18,914,868,438,36,823,716,447,663,422,195,976,59,338,187,532,784,792,200,356,719,229,573,258,320,941,538,719,366,835,46,323,775,892,269,525,51,297,703,490,691,365,18,723,658,107,464,962,922,367,768,592,886,285,318,179,468,803,339,241,70,228,609,383,11,663,887,244,816,386,548,750,945,762,167,68,670,160,708,421,345,272,464,320,456,282,675,458,187,955,198,638,442,883,174,943,836,889,750,488,349,941,839,395,572,924,85,827,245,609,926,365,998,867,610,122,875,483,970,576,261,308,650,164,207,493,349,716,72,747,881,783,982,596,911,106,519,365,206,379,872,550,908,217,757,645,728,498,67,950,957,293,924,322,532,644,281,731,879,748,780,671,646,904,200,831,625,922,200,848,727,363,560,873,969,273,171,956,333,951,233,99,933,186,732,947,379,336,136,813,457,259,548,536,844,297,752,795,864,256,75,581,641,766,626,252,730,825,976,377,620,363,661,940,475,384,893,741,386,481,252,97,553,774,238,334,67,736,499,589,553,503,412,913,731,294,264,203,384,422,605,271,373,997,689,933,923,721,400,899,377,657,915,490,104,498,811,7,486,122,357,268,145,887,80,457,695,272,978,459,980,935,795,257,957,637,685,902,450,719,176,937,270,937,664,271,753,692,750,565,448,807,30,939,102,482,29,973,757,700,744,711,129,328,731,723,69,244,563,421,204,991,796,294,120,878,398,42,873,221,681,18,226,130,186", "395,884,451,355,796,757,430,877,649,928,813,189,761,366,42,613,349,154,143,479,60,406,763,897,817,243,716,2,40,415,391,347,186,460,440,687,321,903,197,739,492,149,326,19,419,935,942,490,510,359,523,733,31,46,380,729,696,541,452,503,53,206,658,980,360,546,335,415,523,799,618,19,30,467,836,972,986,127,49,227,296,351,111,568,110,642,545,942,244,349,61,760,91,568,362,980,632,408,302,396,7,94,962,347,583,68,751,681,239,956,838,995,720,631,9,767,891,78,57,56,203,845,541,903,72,277,303,168,175,90,334,193,926,535,588,115,303,895,273,199,20,726,787,203,750,515,534,429,889,399,545,368,419,642,530,320,243,732,815,320,613,27,657,693,298,179,507,14,242,71,204,676,381,639,580,526,817,402,118,650,646,24,189,495,263,953,844,586,186,769,922,887,862,193,182,67,822,846,397,221,742,319,190,174,261,129,149,675,250,912,90,946,402,223,601,807,613,36,166,64,612,212,536,894,445,232,251,921,695,648,884,762,123,238,431,475,362,942,195,566,659,488,947,369,566,539,430,557,611,849,454,777,264,918,77,925,581,768,888,681,505,416,233,383,277,272,469,246,880,744,401,953,604,607,586,736,242,318,966,552,767,683,526,70,937,824,315,578,877,517,173,98,804,820,527,265,246,919,374,983,397,926,112,853,417,17,917,866,71,952,393,501,631,9,600,782,607,486,283,752,938,52,623,709,938,891,110,403,575,376,376,859,602,981,470,920,528,927,17,729,872,570,626,40,295,522,466,328,781,18,716,610,458,115,353,883,531,219,776,374,884,655,935,702,73,92,574,984,368,415,611,638,707,296,7,38,510,336,990,355,297,759,585,509,116,156,296,131,77,143,617,97,185,695,951,519,417,809,34,570,886,827,277,67,287,203,436,747,105,290,28,403,245,658,533,716,882,88,934,428,573,491,881,63,88,75,109,386,982,910,275,935,40,95,988,299,879,68,188,949,712,943,569,865,610,17,246,885,42,886,90,989,523,347,5,957,934,775,180,398,407,771,674,615,254,832,109,346,134,319,735,893,232,221,46,542,386,428,651,704,275,840,843,87,717,809,131,190,271,157,961,423,66,355,571,850,777,266,108,114,140,813,245,358,853,67,230,370,266,462,881,16,990,34,916,962,646,588,603,506,324,982,598,247,571,121,850,250,12,223,316,971,179,149,400,879,336,169,811,963,67,975,529,254,430,751,426,409,962,316,776,682,669,220,943,881,327,209,432,498,50,103,463,355,895,318,562,447,98,884,383,38,758,456,12,343,249,183,441,638,899,329,89,96,207,67,859,909,89,280,208,314,845,627,883,966,346,703,371,219,733,449,981,676,20,30,143,523,936,931,719,976,238,537,222,357,715,148,161,28,797,141,976,974,369,163,518,543,421,446,332,994,849,277,805,348,640,913,152,708,23,11,753,334,344,265,669,825,598,0,452,785,665,467,912,705,662,638,355,431,597,296,316,591,675,499,596,615,833,709,118,86,877,669,902,130,37,245,938,536,261,580,219,451,146,135,451,698,416,573,241,297,593,624,980,91,502,240,276,157,363,6,688,83,182,478,695,700,30,188,61,850,334,228,491,64,401,507,222,432,307,151,613,708,581,865,748,299,44,514,266,607,137,235,547,987,248,232,133,103,150,357,267,838,459,595,992,587,301,807,601,82,953,36,236,543,772,79,185,671,658,488,578,657,757,178,19,649,234,344,945,276,351,342,85,798,385,145,115,167,132,523,696,213,151,915,467,546,725,159,927,982,716,706,280,936,18,835,577,668,54,422,746,315,231,383,13,253,494,220,391,318,803,639,654,537,489,865,612,287,471,624,535,548,984,1,209,284,52,781,382,751,827,88,932,428,532,13,721,808,429,874,566,177,102,899,213,232,436,679,319,652,742,222,725,479,430,566,632,309,973,902,829,379,18,119,234,900,760,140,267,321,190,518,33,607,701,663,487,17,714,203,155,200,926,103,811,482,329,342,57,802,746,66,154,245,957,315,993,696,556,73,980,32,641,923,206,827,527,164,460,77,316,413,141,78,430,996,745,588,183,657,521,75,180,874,90,920,587,693,789,258,505,477,681,718,930,133,673,462,459,933,319,130,590,575,307,206,572,961,612,717,958,934,116,831,514,881,906,331,561,292,782,190,455,884,168,359,859,260,192,155,382,505,606,485,910,167,374,429,556,539,184,941,657,891,724,912,460,713,241,771,636,59,950,2,415,130,718,835", "148,538,269,46,924,161,266,718,80,365,709,859,407,431,715,56,254,261,881,695,291,991,144,621,165,678,14,200,758,471,157,474,455,708,62,834,437,883,779,999,302,56,268,343,445,965,969,184,255,22,176,559,840,805,670,109,895,384,295,410,541,723,284,112,783,406,339,810,833,323,93,575,975,242,671,989,108,838,201,155,515,768,72,15,313,142,700,562,529,577,226,473,704,616,351,545,724,257,432,255,591,767,26,199,753,819,689,538,488,178,528,778,696,920,5,100,221,754,756,248,866,411,356,593,362,265,94,762,204,330,213,75,323,156,34,484,633,607,585,196,518,629,6,447,822,725,764,137,157,25,389,194,884,244,345,106,909,821,535,951,989,415,725,656,920,279,987,851,190,935,938,896,455,386,62,585,475,605,714,388,822,530,775,296,55,939,40,952,341,227,842,852,23,896,79,986,148,819,735,113,676,223,498,640,792,586,58,617,879,671,794,621,438,476,131,587,967,964,619,545,585,6,403,902,714,535,931,696,808,531,686,654,703,592,233,237,143,612,216,284,131,987,795,371,779,312,176,438,547,902,676,166,220,75,61,190,429,680,68,776,942,342,647,782,829,641,790,497,584,92,931,400,364,498,911,840,118,715,956,504,121,498,113,780,137,589,578,725,991,938,855,586,341,981,509,820,969,911,405,978,26,227,786,357,18,657,499,624,467,703,78,93,6,949,760,24,431,59,815,202,140,17,427,568,177,788,426,181,921,877,741,747,533,387,534,946,474,717,782,856,889,535,23,761,2,575,490,809,661,777,292,997,37,877,302,396,976,692,593,36,964,545,465,847,590,484,758,437,407,958,410,345,913,72,740,240,35,261,204,941,352,523,428,267,125,722,364,715,608,9,942,163,785,912,647,732,736,885,783,997,339,260,115,338,794,191,390,428,712,495,607,427,890,363,35,751,447,223,458,86,988,558,151,868,419,310,68,334,433,174,232,7,736,844,600,729,756,169,772,970,730,200,649,360,352,261,517,121,428,507,138,33,477,375,117,753,577,994,81,256,783,444,539,421,292,328,121,235,737,698,352,57,24,423,710,656,882,779,716,390,191,752,312,499,885,390,986,990,133,329,431,476,730,349,675,948,484,670,579,451,449,557,838,789,194,934,311,208,783,944,583,268,158,396,202,510,711,313,340,956,481,11,930,586,562,417,52,267,342,21,205,493,710,672,746,764,215,83,548,846,642,806,793,984,440,345,256,221,672,961,561,459,62,193,329,522,815,523,17,427,407,31,234,360,898,17,248,460,699,732,829,24,698,318,603,754,52,298,241,623,109,745,476,481,230,868,9,64,976,389,280,723,392,498,671,746,438,27,327,753,579,654,368,677,570,57,30,850,314,536,929,597,961,15,761,562,879,261,520,137,296,520,311,797,121,107,744,948,898,347,247,164,913,29,5,606,305,834,112,538,974,761,114,368,463,246,360,975,645,452,0,323,434,5,671,212,159,489,630,581,373,397,372,591,681,178,671,654,931,75,19,100,602,990,922,446,621,349,850,985,918,820,789,602,556,824,407,571,702,458,474,31,792,349,217,276,427,315,689,265,573,574,185,40,388,6,217,971,548,606,58,548,776,483,165,448,952,498,910,777,327,84,157,608,971,709,561,261,162,346,488,422,840,897,946,874,168,20,979,991,883,112,805,92,477,843,608,154,465,148,523,519,714,8,795,730,967,161,875,465,803,657,266,631,621,779,490,412,722,275,225,867,338,666,924,60,478,291,419,375,796,445,449,957,857,631,279,452,754,249,347,258,663,116,751,764,709,789,412,49,761,460,879,332,204,170,36,232,254,266,194,634,532,131,899,611,244,212,693,960,227,978,264,392,114,574,310,627,229,44,521,628,756,946,772,581,586,964,75,731,573,225,51,144,983,645,4,366,523,540,70,408,862,432,164,797,849,451,603,93,934,856,407,354,926,290,870,296,501,169,948,777,935,851,429,339,870,120,870,182,736,249,273,681,369,976,602,277,287,84,383,434,927,404,795,687,968,866,190,841,404,769,23,350,553,417,515,38,893,988,387,310,711,504,843,969,83,564,554,908,530,284,750,471,347,629,440,139,730,763,473,207,594,632,102,498,427,628,563,413,267,158,935,786,18,350,644,688,621,121,210,242,976,229,862,650,35,645,139,95,953,286,821,642,28,221,55,661,412,293,893,229,647,182,720,393,383,174,173,691,353,300,731,775,243,510,791,819,382,379,801,191,180,920,864,649,894,937,570,660", "330,653,716,530,559,64,439,174,20,612,766,250,951,587,917,281,965,897,130,7,60,568,884,796,798,272,607,266,363,398,808,747,980,991,621,968,985,63,293,214,440,808,10,964,996,684,78,516,716,565,165,930,928,196,404,412,31,927,137,994,879,526,51,993,670,429,233,878,972,722,173,199,640,457,736,552,335,699,394,654,170,257,55,488,342,427,884,386,184,792,578,492,607,41,300,937,327,300,338,338,988,367,106,678,449,548,388,223,518,328,910,543,906,8,204,155,740,35,818,200,685,555,126,967,671,680,12,807,176,537,921,896,376,972,593,304,511,610,571,631,426,57,915,625,183,86,654,206,569,498,923,526,283,907,864,43,595,632,725,710,92,782,534,65,704,339,685,752,357,253,67,848,816,280,29,685,35,61,733,536,179,888,298,262,624,7,933,170,290,554,551,307,80,304,387,24,969,45,652,700,404,388,936,935,877,19,720,438,759,829,945,443,922,89,476,474,685,90,665,100,451,912,508,737,527,959,551,488,16,129,480,409,507,417,34,558,966,80,417,839,245,20,328,707,128,91,963,806,517,897,985,357,660,454,743,440,225,25,154,230,185,862,110,820,444,771,639,923,430,595,865,597,353,942,143,848,900,384,658,807,135,359,884,21,496,209,554,450,585,633,28,124,613,896,669,901,525,924,332,693,478,93,505,391,636,65,51,201,268,926,719,610,244,116,120,539,50,104,670,655,282,524,962,827,448,943,975,40,143,676,874,352,44,625,947,544,383,85,766,511,407,541,820,163,284,618,978,374,148,679,315,114,172,276,553,917,377,428,390,134,292,244,881,727,330,882,767,801,463,588,323,827,208,549,262,659,602,413,80,964,402,490,775,638,83,797,641,775,402,209,609,57,871,604,620,556,675,921,922,523,287,876,675,148,353,236,48,721,29,44,40,928,585,96,676,228,969,121,943,621,327,845,380,702,253,757,852,65,507,889,295,738,864,257,753,881,779,938,201,855,420,571,977,222,177,235,357,869,146,270,988,270,201,42,419,104,705,126,30,13,344,649,172,623,852,986,982,474,459,688,49,408,818,852,687,272,175,403,372,457,662,25,785,792,675,717,618,42,486,296,599,67,116,261,663,864,229,204,109,801,938,35,874,480,58,305,330,158,571,658,218,438,735,954,346,358,560,789,280,700,189,938,758,872,844,418,649,681,135,212,264,133,259,103,400,901,1,463,532,254,515,530,155,999,60,678,774,102,225,670,692,352,314,361,920,272,957,466,286,693,348,821,132,818,719,942,34,799,205,944,406,922,542,304,868,759,582,572,751,375,87,984,323,440,280,842,261,734,910,803,433,790,681,38,17,736,829,832,486,555,339,990,252,543,670,130,663,719,891,925,623,792,834,792,759,808,474,603,432,83,313,861,520,739,720,40,74,528,310,789,163,93,359,484,913,931,65,401,484,6,733,773,970,403,499,391,135,951,259,785,323,0,892,537,726,931,916,80,609,332,905,250,118,363,955,233,777,267,89,405,645,436,525,971,644,255,451,640,326,872,371,756,82,930,689,716,732,264,721,631,353,168,925,389,128,392,26,918,903,563,159,881,428,40,60,425,615,135,519,286,959,39,611,223,141,980,410,694,672,193,646,590,181,764,200,292,485,820,779,928,77,989,115,995,91,254,819,247,737,29,40,253,758,868,996,348,968,957,865,207,780,846,617,327,88,895,665,286,619,463,822,199,32,823,931,38,201,232,536,516,699,232,983,898,684,696,344,700,374,51,582,190,805,607,231,790,464,526,708,287,179,995,284,962,917,42,83,52,111,341,73,557,224,569,103,195,48,957,91,407,230,277,933,723,35,195,744,861,340,359,361,891,933,806,421,286,126,900,603,381,927,950,943,684,109,924,895,686,192,776,362,257,913,986,830,839,836,882,966,512,654,158,474,277,994,572,735,796,846,289,262,60,494,645,516,584,668,522,699,456,336,491,426,967,442,310,278,387,431,32,539,535,834,463,169,586,499,887,489,698,335,349,92,337,584,936,647,827,463,912,615,897,449,508,646,51,928,91,558,703,386,10,53,324,244,958,270,283,907,769,151,97,418,574,273,933,647,813,494,513,398,999,392,382,583,613,878,727,555,282,778,958,593,105,406,431,645,489,775,246,73,98,137,997,220,510,657,758,785,93,381,175,106,937,626,905,601,248,272,3,636,996,312,890,727,241,272,273,923,102,167,978,499,789,248,733,675,178,231,574,587,761,406,891,82,395,222,868,327,735", "919,69,260,200,160,626,858,536,285,390,238,387,425,677,832,49,224,383,67,550,809,158,764,791,116,330,185,868,632,400,322,577,972,69,857,110,527,234,213,905,256,930,34,876,286,691,222,196,754,718,580,560,536,72,130,258,869,49,315,304,446,592,738,69,101,529,898,753,267,405,863,285,520,288,534,566,146,35,528,174,70,811,566,579,431,959,877,585,78,257,945,552,60,329,700,61,444,255,909,561,98,82,291,824,685,359,893,737,457,504,809,385,374,26,294,417,587,392,323,847,348,565,166,230,792,911,853,362,914,285,628,702,964,286,655,51,530,847,823,827,290,168,171,594,334,725,864,66,974,715,213,830,357,995,395,56,658,886,225,117,210,783,59,861,846,189,467,297,458,247,184,82,841,417,967,113,580,656,282,527,699,142,179,495,334,277,360,842,980,371,739,172,851,418,272,888,172,325,139,588,413,428,951,446,589,636,150,10,792,502,884,647,626,553,642,945,773,829,900,159,610,980,161,165,348,602,178,38,665,433,5,856,804,895,581,813,185,15,566,18,201,822,277,855,927,656,815,961,613,883,814,304,802,587,398,871,207,252,504,507,783,624,736,404,715,866,217,994,635,368,499,611,881,911,768,489,454,133,405,645,190,824,385,202,716,560,612,440,601,363,96,791,910,560,368,189,698,166,45,759,885,358,73,81,120,457,622,829,937,820,344,252,138,603,873,907,791,919,244,547,272,294,417,445,733,72,638,508,775,610,236,447,411,674,473,869,14,171,187,791,908,41,493,235,524,832,601,139,888,648,952,744,404,771,598,573,827,169,437,756,443,171,86,514,322,493,502,450,111,216,259,135,871,575,76,241,819,657,780,437,739,206,212,931,792,430,950,514,538,226,475,867,988,519,913,83,579,469,984,865,189,628,988,344,994,494,692,616,949,918,651,220,718,621,439,614,383,598,43,539,624,864,50,426,344,331,569,82,964,782,848,956,801,661,573,652,251,543,105,593,662,186,207,306,994,44,455,530,636,273,613,115,933,126,378,985,691,353,507,693,678,975,720,952,525,900,402,90,400,906,93,372,992,362,233,480,777,950,763,409,830,717,189,521,918,167,253,754,439,101,285,25,795,751,860,830,890,178,217,89,647,329,388,258,8,472,685,865,122,563,406,116,102,266,444,286,516,638,909,105,243,31,442,766,672,250,140,225,729,929,483,498,617,262,937,45,364,147,222,501,351,270,582,102,371,633,920,728,796,428,393,239,100,993,871,215,161,874,945,948,500,66,267,974,833,138,965,756,925,318,308,939,312,33,80,598,880,613,792,453,580,923,68,433,673,965,105,446,319,207,927,43,635,908,573,26,172,474,803,50,457,779,870,5,384,951,595,375,702,332,775,98,808,975,161,316,426,846,525,323,195,62,924,517,317,135,783,404,163,93,149,401,33,837,943,380,263,454,929,280,727,23,341,750,723,648,140,899,344,665,434,892,0,930,345,614,26,239,200,519,874,713,564,423,237,786,418,148,128,795,282,64,301,908,420,334,989,964,31,606,119,614,345,458,582,82,499,227,638,866,44,251,980,125,666,983,507,192,247,467,651,206,462,349,66,636,734,3,107,17,996,64,466,410,801,878,987,986,733,18,728,897,350,890,949,224,561,950,690,891,48,77,316,595,995,256,952,205,983,657,389,882,170,276,740,210,843,865,420,12,534,88,508,984,65,29,452,612,213,382,686,535,170,915,287,34,966,584,714,987,965,51,725,116,902,825,971,953,213,44,224,632,84,178,385,600,518,889,743,694,958,397,593,310,66,6,895,985,749,876,562,791,194,100,325,714,534,215,957,601,987,938,611,229,533,916,304,225,26,216,686,144,462,680,662,535,452,938,350,368,805,58,485,516,519,361,711,521,467,990,453,489,273,522,85,976,642,481,347,940,184,99,513,513,752,626,22,267,282,524,788,529,279,899,103,901,126,842,77,224,19,930,604,239,381,984,29,300,505,772,511,638,565,628,846,931,653,268,30,176,388,423,823,886,919,888,874,838,291,724,494,789,114,517,865,999,227,695,204,452,803,170,137,133,820,310,58,349,671,964,452,926,715,281,743,663,752,825,54,817,735,782,790,801,650,621,399,267,781,786,693,832,937,665,212,606,775,367,15,89,819,729,439,614,775,838,500,480,700,76,337,36,364,184,625,846,23,939,40,563,109,991,86,662,710,805,904,557,372,930,324,255,682,997,796,750,514,117,335,31,698,789,397,210,98,942,577,982,245,961", "710,728,849,344,206,395,20,461,548,795,895,921,622,11,59,419,237,639,239,860,822,141,427,617,718,958,675,568,109,963,717,501,756,633,915,531,289,398,970,576,204,24,262,503,897,299,42,62,518,842,897,860,719,13,274,906,602,70,291,984,351,921,391,387,411,896,251,852,937,608,564,153,98,226,664,161,625,277,660,93,229,985,250,387,21,829,149,59,783,449,926,100,836,419,229,932,559,463,922,480,280,332,75,138,480,847,318,77,218,806,475,658,10,174,283,959,61,520,302,73,998,936,540,713,499,913,690,103,377,570,592,323,860,919,866,431,817,924,954,783,345,664,518,122,581,59,186,536,8,146,393,171,744,24,674,472,9,498,153,279,237,212,748,168,213,318,166,91,582,377,817,586,603,838,360,675,546,750,937,836,805,220,957,738,205,693,921,548,60,576,619,768,508,474,246,707,815,85,831,106,978,589,555,792,841,75,369,809,479,739,386,973,475,113,843,569,283,407,132,863,319,52,187,349,214,29,417,833,761,565,286,671,133,380,651,187,992,311,577,391,690,186,378,892,720,463,102,805,310,861,612,891,110,609,330,600,762,210,953,94,735,607,849,202,88,825,761,175,334,328,319,557,162,119,259,255,218,617,583,870,244,588,270,98,89,696,320,740,141,970,842,854,942,547,796,745,381,43,978,955,998,318,505,998,735,825,855,342,584,345,874,790,461,120,731,299,662,695,157,474,724,378,602,917,634,389,417,803,584,322,374,864,888,648,109,756,969,707,461,321,746,402,484,702,720,551,122,890,540,436,995,546,436,517,311,428,570,711,421,364,191,660,95,424,434,190,141,315,620,331,352,256,997,901,485,496,639,167,418,845,613,634,216,780,54,212,566,448,249,845,163,316,638,425,596,183,114,297,375,736,707,491,510,357,569,863,507,521,725,959,942,573,291,343,713,934,756,429,398,86,394,130,698,774,700,126,887,470,716,925,151,168,477,49,821,462,363,921,829,205,845,34,285,879,276,220,169,624,929,168,207,295,101,660,639,994,746,300,736,934,194,267,708,395,205,250,252,591,455,137,87,691,675,14,467,242,529,176,627,118,371,31,94,294,208,429,271,451,479,173,351,20,393,646,743,792,655,543,327,559,825,643,563,813,281,207,982,742,922,923,309,785,494,437,155,797,97,180,831,461,13,690,803,140,171,174,581,845,538,458,750,215,623,405,911,10,531,673,698,258,936,49,9,621,16,524,20,982,79,540,964,638,934,840,194,36,952,853,187,303,119,921,220,926,518,925,550,277,819,323,735,132,644,953,1,923,998,165,889,816,274,352,89,919,660,621,681,920,414,851,278,666,851,195,289,332,173,464,153,560,483,119,326,973,571,310,35,504,365,307,457,753,271,436,276,701,733,287,407,321,907,319,57,367,242,737,649,388,55,524,524,10,158,388,776,286,639,813,785,92,828,296,959,767,698,119,232,970,174,467,5,537,930,0,867,565,127,291,638,1000,120,31,169,49,355,894,361,256,572,618,304,209,117,677,589,485,986,984,340,902,676,664,841,482,810,203,281,658,847,627,69,929,259,577,314,465,132,922,691,564,367,973,422,521,599,985,610,495,52,592,47,947,510,641,432,387,758,4,198,387,326,467,392,40,762,41,680,739,77,179,672,165,315,307,141,701,924,660,203,442,994,591,899,221,371,453,589,334,438,482,283,975,163,636,660,146,609,278,291,462,187,809,370,571,804,439,551,649,624,465,386,388,921,392,386,871,721,488,391,846,674,393,480,24,378,275,442,416,329,523,71,224,370,635,36,658,980,876,905,334,387,617,988,172,532,637,280,595,868,66,254,72,582,949,729,67,284,392,32,856,583,293,349,94,58,178,458,389,570,326,995,601,413,348,995,436,344,599,214,932,477,276,995,329,763,701,914,232,761,768,228,415,336,971,88,486,738,297,352,871,600,877,569,886,233,625,444,988,979,490,454,578,796,564,630,566,879,76,10,485,495,327,628,288,64,53,139,172,500,341,450,433,789,298,180,144,30,463,852,57,993,780,763,169,872,865,528,888,304,468,565,174,519,62,767,446,223,590,201,567,615,405,496,310,424,5,433,105,593,11,677,16,619,192,5,606,172,661,963,592,383,411,354,136,233,282,301,266,183,449,505,540,850,110,233,569,443,371,472,337,231,26,655,733,721,22,605,960,127,823,980,715,757,283,678,699,254,105,474,844,901,886,73,822,700,474,338,550,489,864,935,289,576,888,724,635,291,452,784,803", "485,14,592,955,490,717,186,461,725,687,704,982,532,138,11,962,712,777,111,253,12,327,101,834,51,617,491,497,2,484,734,376,737,71,536,46,450,43,715,351,564,19,963,283,910,142,565,242,228,563,352,596,261,321,509,15,696,788,888,535,283,903,717,328,794,894,953,158,743,644,145,516,365,243,791,332,631,496,59,879,781,863,476,232,173,445,55,640,250,825,732,384,86,371,498,755,938,767,232,244,235,453,202,296,854,933,513,1,106,331,309,294,362,119,315,909,639,214,211,561,637,590,351,620,260,556,948,442,727,783,257,885,260,962,69,144,564,823,372,832,73,589,541,974,458,698,512,143,860,932,69,16,477,259,797,860,486,188,97,248,923,234,680,886,60,540,145,868,58,900,336,894,327,684,509,222,691,98,460,878,409,579,834,262,819,471,733,255,581,740,699,3,836,356,542,966,592,368,354,959,201,602,406,162,301,906,237,684,424,602,923,650,780,517,680,227,739,383,626,764,650,176,768,432,792,393,811,436,890,842,525,756,994,234,923,145,596,288,701,265,36,329,213,45,173,483,512,222,760,454,953,829,379,304,178,268,409,967,873,847,87,677,128,96,322,840,96,938,526,519,149,331,587,815,742,257,629,13,465,457,592,656,683,349,314,906,403,411,352,748,28,381,175,727,218,347,245,990,434,715,876,969,352,85,75,150,299,284,472,832,732,486,45,840,868,130,889,271,599,501,546,531,251,326,555,222,850,256,451,935,901,855,73,158,637,38,768,282,659,895,633,729,451,643,384,771,130,409,592,820,62,806,936,222,836,998,911,915,171,749,495,598,899,198,619,384,103,21,905,820,996,857,274,188,372,204,968,704,417,123,35,460,368,880,91,957,73,7,954,151,965,913,990,433,13,292,527,974,892,422,618,799,974,53,459,473,28,542,174,279,414,512,733,646,557,979,708,98,187,866,527,751,331,224,984,655,396,517,332,849,529,823,855,824,919,915,565,950,142,298,322,952,411,313,748,888,657,2,141,987,514,116,841,619,635,872,958,491,928,975,721,961,827,698,603,629,24,120,829,215,987,877,538,713,423,928,911,89,98,997,462,959,748,204,937,780,344,779,370,60,385,487,16,995,119,924,783,7,550,177,498,796,214,732,885,217,331,684,33,732,73,342,837,362,344,838,978,967,34,168,913,477,330,263,548,414,876,613,145,583,897,971,133,99,604,836,962,832,438,441,807,374,603,143,706,925,796,307,365,807,191,119,607,544,823,857,832,599,159,627,905,781,851,739,751,526,529,236,909,253,846,419,72,961,496,165,544,125,937,607,330,637,385,493,294,5,148,89,69,776,430,818,748,882,713,526,967,91,919,663,397,327,83,334,177,901,121,875,937,860,206,471,461,669,191,707,732,266,84,51,284,173,39,477,262,974,356,70,88,644,14,599,613,745,94,101,495,470,432,346,899,928,915,292,486,187,42,424,360,912,671,726,345,867,0,187,296,543,234,28,966,375,893,802,996,531,908,303,79,491,466,309,575,550,386,979,857,379,240,448,726,858,702,718,220,746,400,603,138,203,65,388,52,567,377,342,715,970,687,129,50,783,438,243,869,959,17,65,773,602,953,616,166,585,324,842,830,530,81,572,161,640,495,985,616,969,846,212,372,971,433,140,55,885,943,753,193,410,11,380,93,335,868,644,17,90,639,236,884,474,75,516,746,1,828,75,501,721,534,298,315,385,699,162,852,61,855,317,411,158,892,963,608,526,514,991,621,455,837,506,11,790,754,554,590,401,631,620,656,716,179,207,17,287,612,279,16,568,595,496,589,951,312,148,585,655,995,168,183,204,436,361,532,181,244,957,167,280,175,750,139,444,672,659,352,690,349,347,558,7,332,699,848,628,39,275,99,215,222,340,571,384,881,950,903,696,789,839,351,616,930,769,751,63,507,995,552,363,482,81,637,602,625,108,180,26,623,622,442,863,786,792,269,568,109,385,801,353,621,613,692,881,516,883,940,548,560,256,36,436,321,350,783,331,257,387,39,301,272,860,541,957,599,900,649,52,197,563,765,148,902,8,267,106,187,896,692,213,164,679,654,427,685,801,42,371,596,333,71,65,69,915,417,628,782,886,447,226,326,510,101,903,343,368,412,72,205,817,549,982,657,92,719,545,27,438,627,826,783,918,406,880,322,240,522,220,179,682,145,344,832,553,96,147,118,273,693,33,156,965,174,326,700,897,474,183,919,200,14,570,319,660,938,728,214,235,136,789,111,451", "709,905,462,789,866,79,967,776,454,931,728,251,50,258,977,152,333,451,149,96,450,226,113,475,735,289,480,407,292,288,701,70,513,983,989,668,496,281,669,863,794,745,173,494,804,711,503,784,416,748,972,385,365,693,564,869,355,193,680,648,531,531,893,28,951,221,321,628,767,31,170,516,195,771,822,629,651,832,879,571,453,580,749,598,490,492,246,151,836,154,140,830,482,439,890,164,286,219,919,932,757,339,315,529,608,299,791,597,556,742,660,648,396,935,478,712,432,220,152,263,704,857,578,38,406,168,870,547,628,119,739,621,960,309,756,947,382,892,228,863,471,107,800,107,791,94,687,438,21,560,475,613,542,412,495,886,495,578,339,436,216,513,51,571,130,521,790,948,63,660,75,386,737,527,408,571,128,35,670,287,54,38,49,621,419,47,125,464,163,660,728,743,434,752,245,705,754,241,675,213,227,813,677,734,712,334,208,892,796,486,903,653,717,601,968,710,679,866,962,900,304,296,188,990,141,723,53,503,36,146,453,955,684,758,957,868,685,714,697,959,498,525,777,850,859,971,738,346,487,424,222,221,99,876,359,818,505,691,450,380,68,127,413,350,974,813,415,922,9,629,643,223,872,755,386,585,901,729,304,76,434,324,879,265,645,566,316,759,656,794,964,376,845,307,16,199,312,184,287,788,891,220,118,998,94,652,476,988,641,482,90,871,740,747,50,919,93,669,776,806,428,163,422,773,945,59,97,521,206,81,986,209,458,481,870,418,459,716,438,107,675,465,662,189,244,286,339,455,374,615,563,848,480,214,343,704,429,672,739,553,297,120,727,24,994,950,658,416,824,822,637,186,793,938,700,27,164,260,474,34,604,790,492,982,957,420,967,578,249,241,486,654,629,74,721,599,410,848,584,376,297,487,626,261,88,790,915,11,563,222,76,448,895,252,312,539,139,406,235,626,933,239,206,309,167,947,786,330,696,288,619,585,113,457,508,606,84,314,531,136,74,166,697,873,78,458,636,55,370,874,467,663,524,230,15,376,153,726,88,431,447,5,914,294,996,203,799,23,945,242,823,192,783,483,26,438,495,940,885,361,475,642,726,484,584,254,668,925,76,243,136,44,920,914,139,321,723,107,186,868,927,745,532,919,947,54,434,230,907,825,945,33,898,936,773,542,317,574,363,765,103,679,305,158,811,707,506,582,456,10,222,673,529,219,374,932,618,902,617,427,504,459,190,643,159,297,244,916,924,536,565,974,108,704,570,888,551,429,169,929,277,669,45,302,687,651,69,59,997,958,539,793,780,349,693,156,343,518,302,711,289,764,792,462,40,491,384,228,390,646,328,925,928,800,938,84,472,604,991,129,253,195,100,759,298,781,292,214,477,381,232,171,14,890,638,685,981,826,806,310,113,653,512,93,302,733,135,401,523,312,223,412,370,605,473,243,948,325,596,900,952,829,433,11,582,710,748,444,120,705,212,931,614,565,187,0,610,232,780,345,912,364,925,300,393,335,587,786,689,689,182,600,133,162,617,362,66,147,296,152,288,4,807,354,55,312,295,326,683,69,252,827,146,892,511,152,809,528,858,465,128,865,407,180,923,118,593,50,963,897,794,836,610,597,318,688,719,316,832,931,374,674,451,300,958,512,531,673,204,542,512,26,997,602,365,362,939,431,791,969,955,50,561,929,35,681,613,937,381,348,156,941,390,21,745,207,366,25,121,612,730,835,990,599,402,637,221,586,135,532,204,629,520,941,4,866,170,19,603,629,613,902,867,576,793,684,981,712,76,888,399,891,386,486,746,815,708,71,721,198,588,480,818,656,298,32,25,149,229,361,263,770,556,512,292,757,793,520,323,308,323,785,611,91,879,428,2,803,313,163,902,948,680,31,749,426,314,598,543,600,757,279,754,112,637,31,854,504,420,752,820,400,99,133,123,493,491,937,449,879,306,275,895,845,271,542,426,190,275,801,291,932,805,459,91,826,920,296,263,391,648,122,584,592,67,471,882,745,267,551,213,953,392,129,337,674,80,590,513,866,224,109,288,525,986,296,638,643,302,131,81,298,169,626,95,613,76,185,57,226,702,208,691,905,1000,175,338,336,450,611,260,120,987,680,461,785,367,156,664,484,937,33,816,507,151,52,131,372,685,555,640,57,19,348,990,855,182,747,666,66,13,324,974,737,371,863,885,281,696,245,676,91,766,330,466,62,212,606,6,789,417,77,455,670,192,347,771,228,477,747,939,975,812,387,543,240,433,156,649,387", "341,147,850,221,432,839,710,643,985,179,335,547,64,135,227,866,39,497,537,744,485,517,507,710,168,912,809,387,431,4,893,787,8,657,868,810,556,819,928,234,755,409,312,768,90,209,400,939,781,353,259,430,336,876,687,413,322,723,761,84,752,809,870,972,149,151,78,284,629,70,62,63,556,966,130,372,655,851,42,110,140,912,177,145,267,735,761,981,734,943,572,675,18,47,470,994,990,889,677,464,886,148,379,691,47,914,973,453,357,809,964,95,147,764,820,308,299,263,986,180,462,981,810,856,589,348,361,47,952,546,781,642,182,825,553,476,288,779,395,658,514,358,52,405,912,506,290,761,670,629,949,983,686,224,172,770,859,60,372,85,975,390,343,110,952,4,233,265,634,811,964,327,974,210,144,201,887,442,838,945,301,128,993,109,365,549,360,665,494,126,559,341,334,781,801,330,699,705,768,23,557,566,483,139,495,954,445,688,71,834,653,986,251,769,16,921,442,411,995,213,556,207,337,836,636,689,701,504,265,970,556,251,157,543,154,721,451,604,155,830,724,474,514,225,351,72,301,902,43,284,903,465,439,358,133,44,74,231,553,733,86,298,621,514,121,516,301,789,171,250,921,934,406,809,438,105,290,988,132,380,954,24,436,219,589,148,744,635,297,572,714,171,771,610,405,470,501,814,704,312,685,789,775,260,401,500,790,123,618,399,208,336,955,615,59,996,739,406,788,190,553,491,574,189,718,344,487,56,571,945,970,486,328,41,714,780,647,194,67,680,245,560,282,930,195,629,286,154,706,562,29,658,659,130,933,989,232,708,628,426,555,674,272,913,359,785,85,982,216,27,518,289,992,883,502,111,16,221,822,657,35,674,838,448,702,136,28,876,235,490,895,184,520,413,675,932,239,123,718,602,854,900,548,848,60,111,395,831,253,275,814,810,318,671,975,383,513,102,564,176,237,973,978,680,512,163,506,347,680,476,393,589,952,15,111,62,639,648,18,457,820,488,502,444,89,257,480,950,515,190,84,407,922,956,630,625,557,481,490,338,695,657,56,169,481,787,501,406,434,154,462,903,585,951,449,894,905,646,81,738,61,313,913,43,470,872,98,514,988,913,513,502,265,490,615,859,999,817,172,72,785,898,386,45,819,381,584,434,843,193,705,56,649,124,34,504,181,575,624,800,104,70,808,362,65,692,964,890,996,395,671,821,642,936,119,987,139,498,183,857,25,958,928,704,672,600,885,555,64,646,919,106,225,46,193,276,841,2,123,602,967,51,981,102,468,860,724,504,347,761,836,789,7,549,334,248,272,361,68,187,834,294,744,658,647,476,204,802,803,653,515,4,15,303,910,5,296,860,502,125,75,362,741,398,907,490,601,996,538,583,468,946,392,567,952,755,303,581,209,724,70,498,957,448,498,935,721,97,32,651,601,475,945,811,675,428,826,130,146,471,406,859,413,204,845,45,995,595,725,662,159,916,26,127,296,610,0,952,664,183,460,876,619,429,700,445,510,28,175,317,269,251,981,502,933,699,985,589,254,343,974,836,939,637,612,822,722,745,278,819,49,216,379,809,422,436,722,989,357,758,506,701,610,256,361,148,601,121,443,709,296,834,63,408,979,869,378,612,352,194,321,872,672,580,58,86,136,573,309,846,228,134,574,905,381,750,953,791,864,170,250,863,787,505,434,721,689,158,283,963,409,238,528,471,840,887,436,531,937,116,622,572,612,614,323,995,469,706,424,753,64,266,530,128,82,411,468,530,176,433,583,277,902,720,73,652,674,592,205,507,580,670,965,391,5,33,969,394,764,614,400,975,897,685,497,629,157,34,538,835,310,339,715,229,735,578,154,709,601,345,335,915,344,29,636,823,648,533,526,678,540,12,346,918,223,688,268,399,853,902,881,530,109,800,662,382,140,819,223,445,454,784,965,139,137,130,597,207,735,140,613,216,251,852,852,464,283,895,955,346,186,425,469,456,850,168,646,297,282,184,27,981,99,774,501,525,226,10,13,432,807,796,173,537,223,900,583,769,244,443,537,359,82,699,450,224,582,718,230,914,840,592,883,982,241,344,509,548,314,901,507,463,688,757,61,402,25,533,977,682,446,305,220,759,457,171,413,705,166,454,7,5,299,595,862,330,479,773,307,641,327,442,381,264,25,821,67,634,887,480,330,873,672,899,71,400,464,344,621,5,962,767,847,405,776,443,114,523,998,259,542,8,891,284,894,174,810,536,722,583,19,547,486,279,787,237,42,231,616,162", "871,88,840,131,511,274,264,762,321,767,867,555,974,354,879,508,86,329,554,875,872,806,598,291,712,775,942,95,754,295,740,383,331,685,506,866,567,756,721,616,650,625,422,742,764,33,516,893,643,631,938,454,199,899,76,233,142,441,726,50,578,636,217,67,280,494,696,897,77,697,627,958,303,786,280,211,137,968,283,168,985,29,239,335,754,619,543,177,178,901,487,448,131,804,27,464,617,619,157,372,975,686,397,900,396,421,683,927,760,973,63,696,994,489,989,153,320,233,3,912,425,999,896,809,522,39,220,543,507,547,226,513,850,821,85,777,101,977,746,184,384,402,590,711,73,446,700,633,503,379,288,92,492,825,239,517,980,3,314,252,351,783,418,340,489,271,287,787,957,717,689,704,5,956,611,61,965,550,630,175,959,839,74,697,363,524,514,594,45,926,448,227,729,320,887,275,119,349,857,827,209,104,303,970,769,71,872,801,219,981,186,722,520,933,821,977,642,739,696,190,863,392,484,24,768,965,978,130,985,428,877,457,871,335,419,686,393,908,278,37,691,264,332,685,702,464,400,993,55,483,649,443,788,150,441,981,976,849,2,713,596,530,494,591,432,197,744,269,502,315,612,948,405,297,133,427,464,832,332,651,623,971,180,44,413,532,180,136,869,964,519,822,195,866,548,599,129,756,856,630,982,243,531,688,37,698,975,774,991,191,32,498,963,220,910,462,151,749,779,353,946,733,585,735,909,769,720,125,967,578,229,192,253,771,870,273,883,104,671,619,48,680,705,847,194,379,339,158,21,619,594,684,945,156,491,662,255,684,494,285,388,99,465,796,669,413,495,432,215,878,532,147,318,405,900,901,771,944,493,404,154,149,6,91,813,660,940,59,57,927,405,127,747,576,282,753,841,949,993,703,965,286,153,459,178,816,141,334,105,448,309,478,459,719,839,678,824,128,779,170,279,923,461,457,486,184,957,841,947,602,655,136,537,174,134,813,740,943,606,145,925,512,365,909,946,15,284,347,8,97,682,735,236,146,242,828,716,258,171,270,622,340,611,375,815,473,387,222,791,532,850,540,148,402,504,990,913,514,806,646,787,381,632,258,880,444,673,345,730,461,767,934,55,526,616,611,249,32,552,887,206,688,261,764,335,71,774,767,270,528,845,448,120,428,894,486,44,669,504,993,718,160,265,633,952,812,408,768,567,551,574,867,96,974,379,405,841,448,4,372,291,747,797,62,127,553,710,532,557,779,555,89,562,415,139,689,323,291,946,774,350,317,313,834,187,664,164,129,67,807,466,804,508,449,130,562,410,518,341,381,608,479,655,650,739,75,203,29,720,406,527,512,496,964,812,111,36,661,438,611,735,247,669,399,803,514,395,8,963,313,28,690,463,963,800,595,518,499,93,86,446,537,502,172,623,143,356,91,987,376,377,657,905,916,550,727,320,377,218,373,286,185,759,744,713,35,874,107,837,638,489,80,239,291,543,232,952,0,631,259,884,468,839,17,673,569,321,610,969,12,539,476,233,62,857,541,412,683,69,451,18,630,838,128,57,768,712,672,474,352,253,222,341,540,64,290,932,557,134,216,674,105,404,86,754,172,693,86,689,714,721,152,792,335,833,617,407,540,767,913,263,450,747,788,936,881,247,814,873,881,227,895,818,457,270,666,617,56,746,817,753,461,114,343,941,473,428,156,356,16,119,504,822,659,647,130,665,295,648,139,296,210,262,498,271,362,229,143,578,818,906,527,944,765,172,382,724,652,904,136,552,513,268,439,342,768,928,755,933,105,289,190,70,948,178,476,418,882,963,70,944,388,870,394,498,763,666,410,119,326,358,330,436,277,63,75,532,517,670,671,607,505,469,534,843,847,321,629,328,507,670,425,603,80,877,258,779,167,781,435,129,164,267,780,772,477,461,77,447,765,887,49,640,975,918,573,476,826,493,691,689,669,22,620,293,407,990,3,912,927,720,367,511,517,718,643,786,901,700,773,63,787,676,28,111,758,762,835,135,65,2,356,590,95,876,571,358,490,201,224,266,572,459,855,419,32,313,100,790,995,299,277,850,699,401,510,136,911,3,104,977,369,215,728,658,372,788,373,276,451,256,785,381,87,254,564,256,292,151,57,69,144,984,538,741,745,191,156,572,919,966,743,704,961,14,838,869,912,537,296,39,632,300,999,608,937,649,770,403,18,220,87,693,948,704,921,448,856,120,654,636,876,734,837,888,590,496,62,592,30,442,404,743,78,279,71,701,907,798,513", "669,291,359,555,231,903,802,383,248,518,393,617,735,388,797,937,205,780,191,816,100,584,421,364,903,550,228,954,994,477,834,675,137,973,323,234,973,992,563,952,548,326,521,876,962,826,517,687,844,772,311,143,72,678,288,219,539,434,723,703,332,441,616,469,113,998,617,88,737,672,452,885,20,116,792,892,231,620,628,738,108,32,623,495,694,684,19,469,939,18,679,488,555,336,631,464,599,981,976,67,825,544,703,20,115,452,121,303,667,767,337,539,287,8,135,954,891,72,987,320,56,377,214,837,658,282,400,472,3,758,508,520,376,114,198,476,427,841,411,87,439,28,8,977,202,986,726,697,94,163,375,410,529,853,580,832,710,919,538,847,141,923,143,925,141,243,591,645,831,567,296,846,901,534,772,852,9,325,296,628,188,405,68,563,135,599,29,467,817,981,926,454,389,935,248,829,239,682,707,369,607,155,328,529,744,501,81,572,21,31,967,703,462,201,452,709,172,427,231,404,258,883,362,394,570,434,289,730,308,110,868,832,568,398,803,555,770,266,376,305,917,49,459,793,191,583,156,837,971,327,221,490,749,174,463,134,324,104,969,99,486,916,919,301,342,411,684,378,784,776,123,524,411,632,874,545,59,195,262,129,204,336,707,742,261,50,221,905,750,251,222,848,495,527,636,275,202,353,27,976,874,194,491,496,808,94,506,813,931,883,175,492,4,4,320,460,340,32,903,266,298,139,962,157,349,490,939,379,117,335,168,307,560,421,788,877,318,233,339,914,132,686,855,187,872,797,190,896,946,625,236,1000,448,664,382,144,385,935,408,617,316,977,605,284,895,463,584,126,39,610,660,764,668,125,781,164,244,63,248,58,738,13,191,994,447,556,124,760,68,474,999,552,405,259,837,755,117,159,981,809,51,164,825,800,352,486,66,437,779,581,458,949,298,315,48,891,606,943,747,979,392,592,266,652,442,308,811,21,935,201,403,523,398,548,688,479,196,16,61,848,835,293,411,309,431,962,815,84,122,210,716,590,618,103,470,981,68,566,860,511,708,460,765,475,99,178,127,156,125,13,791,149,968,27,930,755,479,289,396,81,943,135,586,696,969,86,194,58,217,851,97,873,350,775,388,114,150,727,935,11,241,178,816,17,105,702,526,891,770,886,464,967,776,111,819,325,13,380,374,148,193,170,890,347,234,103,779,579,226,600,726,727,7,349,215,336,310,610,876,465,455,520,614,41,257,154,245,634,477,357,735,136,439,306,535,819,8,947,509,238,796,879,420,251,844,517,252,556,666,734,964,953,554,582,572,670,139,824,844,365,832,400,790,169,625,561,200,393,197,334,35,517,233,886,693,618,151,62,656,959,147,881,561,396,385,959,7,794,895,557,495,311,807,122,659,924,859,989,748,255,129,911,246,686,554,192,574,296,385,990,532,947,523,269,156,937,959,462,732,241,362,237,228,186,448,507,468,646,451,355,630,609,200,638,234,780,664,631,0,391,830,954,299,134,662,964,949,877,664,415,86,704,39,320,142,403,385,58,865,507,45,221,546,392,900,505,424,96,693,934,19,630,726,324,314,73,959,728,987,386,975,874,839,841,761,168,149,60,510,705,787,600,584,770,262,742,675,251,306,220,559,553,835,993,868,487,306,273,833,416,341,734,264,724,341,779,522,952,442,430,66,257,123,687,586,876,916,659,952,970,76,203,109,275,223,804,124,52,692,401,733,66,462,615,616,637,276,234,512,967,195,259,272,966,750,927,607,466,365,619,783,226,403,973,378,771,586,34,861,252,515,286,397,634,991,774,573,509,161,53,640,738,166,663,161,673,145,384,182,384,216,602,279,633,747,354,814,230,818,658,146,505,157,447,831,998,51,455,128,790,795,753,871,553,792,334,299,487,706,14,808,309,367,238,707,845,838,482,196,59,222,816,25,738,779,628,207,540,451,291,731,253,237,445,743,696,207,188,848,269,321,70,255,508,817,940,647,183,454,920,21,470,17,269,596,259,428,462,12,592,269,142,341,632,781,338,870,930,835,19,614,677,200,239,780,462,658,155,604,832,131,821,750,934,850,683,391,91,31,197,918,22,343,788,63,569,5,854,181,800,571,769,932,889,45,595,499,432,151,360,40,194,878,218,584,586,40,640,651,257,586,346,377,959,19,337,12,238,800,448,600,532,248,589,186,49,513,553,174,432,158,69,904,491,654,106,366,497,712,781,435,998,901,43,765,23,416,404,129,754,624,718,590,563,486,373,963,701,214,421", "27,192,296,217,445,630,265,575,40,997,99,146,311,167,9,226,616,515,952,12,147,825,486,632,668,526,322,625,885,330,906,874,866,116,875,190,540,353,6,925,580,335,477,21,724,788,283,968,447,273,305,577,308,754,371,865,460,262,960,528,527,726,583,970,555,482,770,224,380,332,82,541,911,926,519,71,743,893,430,888,500,219,627,805,57,435,307,81,582,745,398,956,557,88,278,908,522,3,450,819,137,969,375,934,569,616,281,135,290,164,896,762,531,730,701,218,729,655,885,651,441,365,567,643,407,647,62,423,404,844,460,624,283,7,156,814,548,536,47,821,599,406,186,653,788,787,348,16,147,779,285,607,188,971,674,307,384,189,132,328,486,279,456,145,652,17,892,742,59,884,853,897,855,339,435,866,476,341,645,649,657,256,327,48,487,351,32,341,571,63,367,464,383,68,471,738,47,649,43,19,699,262,967,522,459,48,684,2,692,111,498,310,708,544,750,778,899,926,84,765,929,91,425,595,472,645,71,181,392,562,876,123,537,220,432,767,3,470,824,27,139,44,353,926,47,733,291,61,796,854,288,968,998,234,971,440,130,967,959,945,287,151,349,419,365,532,675,85,210,241,308,888,24,278,442,557,720,385,649,573,488,781,781,927,764,201,63,225,361,833,355,633,505,773,318,118,16,672,822,124,104,935,912,312,892,849,894,458,273,487,55,714,755,762,944,24,542,855,477,398,929,275,968,310,436,330,75,370,291,50,443,277,912,652,916,603,906,900,158,655,103,237,540,44,569,116,307,838,146,162,878,755,869,594,504,148,407,364,368,974,264,807,311,901,255,83,791,341,284,147,575,279,383,710,976,181,709,84,800,431,229,392,482,737,208,36,935,751,610,483,78,543,628,192,463,227,155,209,457,422,285,438,395,224,178,988,302,12,309,545,721,137,705,920,740,275,975,153,689,741,822,568,435,74,289,25,207,846,996,61,384,408,992,447,986,867,332,382,726,592,38,85,55,489,509,109,455,239,85,407,438,566,218,879,532,660,683,9,678,986,786,887,540,25,966,796,122,481,14,663,39,437,12,56,913,328,982,28,466,232,165,51,221,693,227,136,899,772,704,484,171,191,859,819,121,640,150,153,683,263,22,245,20,4,676,390,430,293,184,65,805,922,220,615,204,555,164,28,772,57,886,718,56,224,388,259,271,885,817,710,967,942,726,272,424,539,270,2,956,349,11,854,381,919,474,931,809,344,988,538,990,101,809,846,142,34,596,854,871,232,248,440,445,393,19,629,244,392,903,759,361,381,534,483,489,772,402,204,792,455,141,368,172,495,328,480,801,494,393,189,108,571,298,267,291,412,443,153,75,258,960,866,788,513,145,529,726,925,568,731,622,876,130,756,157,842,372,270,825,334,679,709,608,852,837,102,688,376,733,359,244,176,751,538,614,252,983,451,910,473,677,452,282,579,318,359,866,905,782,431,581,332,519,1000,28,345,183,259,391,0,948,769,346,313,839,140,325,356,795,65,355,381,924,497,532,811,962,556,494,526,401,813,765,489,523,412,901,78,515,815,794,139,263,683,465,84,646,869,532,356,932,722,2,388,445,916,615,440,437,816,519,470,220,152,987,250,836,652,469,827,762,321,876,717,51,709,625,621,458,152,425,797,908,42,698,336,638,600,829,933,300,308,998,301,833,340,508,691,162,916,791,681,468,402,855,986,850,267,977,290,517,28,670,629,593,183,198,931,663,710,808,500,944,367,265,367,250,395,732,668,670,479,420,633,472,620,825,384,87,143,373,977,901,178,792,1,641,950,980,191,651,887,702,950,788,384,825,656,638,927,363,40,710,74,736,300,799,196,284,763,945,92,909,50,492,223,357,254,827,864,39,614,308,288,637,996,195,948,627,55,235,162,346,709,431,888,198,720,859,323,688,109,271,349,419,20,391,508,33,948,810,181,66,493,894,816,178,21,303,9,878,306,318,343,927,41,114,766,629,89,790,91,439,644,324,219,844,927,798,311,976,903,117,93,274,544,570,419,564,408,825,413,142,936,32,912,440,140,666,518,745,707,147,330,887,109,457,248,895,876,762,821,521,268,282,435,36,501,636,200,104,336,256,8,733,968,475,521,862,411,803,496,783,143,409,505,915,611,172,317,777,683,933,248,336,453,688,21,835,556,626,906,153,679,418,460,444,911,800,373,762,861,128,150,676,211,2,964,387,426,392,704,960,514,858,645,400,690,236,617,248,771,254,869,764,745,72,63,324,687", "5,669,830,275,841,282,317,503,661,477,942,817,448,186,567,226,689,313,248,249,414,624,917,56,910,187,67,620,65,160,48,131,979,802,484,602,545,263,107,91,532,779,888,284,31,798,564,782,709,376,73,374,312,149,584,385,273,842,632,639,513,640,759,242,507,655,393,400,767,293,870,790,648,211,788,137,405,886,850,811,23,148,857,862,460,33,427,308,618,367,233,690,226,929,223,497,400,601,266,17,273,647,806,269,933,694,321,238,71,680,826,970,914,917,943,555,702,480,65,327,461,814,362,660,475,496,658,492,461,547,849,860,517,71,575,194,579,159,784,476,808,393,510,254,851,466,959,705,527,707,945,316,457,189,60,541,720,347,623,752,227,894,9,654,284,231,985,795,523,844,503,266,135,428,235,358,403,445,826,215,655,810,429,12,799,326,886,878,566,324,691,15,775,725,420,29,33,560,937,559,311,24,680,356,452,172,692,105,851,366,630,216,549,61,821,390,509,42,463,2,381,833,512,191,361,468,695,379,54,417,944,788,947,414,215,808,108,328,991,497,734,370,609,834,495,364,100,633,131,589,187,669,509,686,89,449,735,675,419,945,48,448,320,359,86,332,812,177,349,514,64,697,848,98,486,664,442,587,293,621,874,673,905,605,47,665,509,716,119,293,323,593,638,61,328,259,475,132,952,163,524,675,751,495,227,238,903,787,312,15,324,172,863,818,925,541,641,491,93,817,916,91,487,786,120,768,232,914,417,560,440,526,590,323,585,666,960,737,685,775,513,567,417,66,955,891,680,70,597,854,306,730,148,7,177,730,43,83,149,357,775,828,858,409,621,426,316,863,281,104,618,532,507,983,667,869,843,610,629,712,443,52,633,153,283,552,745,864,31,13,411,469,590,381,748,481,581,528,778,87,718,128,637,570,703,849,404,849,11,698,817,313,920,285,148,785,309,952,376,198,239,83,834,128,572,423,938,672,469,968,686,624,363,907,109,375,41,140,484,226,470,471,795,50,419,93,523,219,777,464,306,202,894,752,44,861,568,73,324,756,310,830,815,29,650,609,526,488,570,710,123,759,680,552,920,30,528,370,249,975,768,775,570,659,22,979,341,191,957,320,717,886,441,326,674,478,46,826,929,146,231,46,888,764,513,263,179,606,927,228,738,308,998,110,567,489,475,663,213,455,958,70,131,5,672,908,128,176,320,738,515,803,4,701,244,90,777,554,347,678,616,720,323,916,223,237,564,387,695,630,695,906,325,560,987,87,877,390,206,849,533,89,316,285,806,615,288,798,13,59,297,961,177,894,805,631,693,700,127,751,541,813,196,351,488,706,322,409,302,122,913,72,807,112,524,4,653,674,929,230,808,452,326,587,389,831,731,283,283,782,86,299,1,984,57,315,622,628,571,534,801,860,164,99,880,925,557,191,423,1000,314,449,632,669,537,731,310,115,648,707,650,398,395,390,615,646,312,929,41,597,373,905,874,120,966,912,460,884,830,948,0,577,919,989,320,158,353,73,586,907,340,681,398,746,71,737,775,439,864,547,833,959,287,784,285,211,322,681,374,931,654,447,164,315,529,192,155,503,510,660,199,819,987,577,424,286,452,370,928,473,648,716,87,995,750,206,147,615,631,19,163,631,797,839,821,863,40,393,66,917,643,139,134,722,536,584,556,288,284,848,413,41,704,36,949,343,456,750,43,985,279,381,853,284,571,557,615,526,379,145,911,850,581,253,47,223,347,445,761,334,835,726,2,175,255,99,282,348,119,521,37,713,11,933,817,829,945,54,59,270,323,212,903,358,644,291,136,44,871,843,927,41,429,935,568,645,883,450,86,545,363,96,763,941,166,467,798,24,411,648,340,99,383,970,116,83,904,449,55,193,57,633,813,727,218,334,996,804,657,989,301,371,403,212,146,960,284,734,764,416,150,175,220,105,100,392,933,632,630,638,962,983,676,401,790,995,925,333,444,575,432,536,595,535,467,513,46,751,316,806,723,57,824,359,399,633,314,634,850,22,668,818,268,12,834,264,881,272,805,340,113,475,865,513,231,94,673,415,69,415,822,212,922,841,240,713,823,60,413,777,474,177,263,980,329,15,838,914,314,605,511,996,295,592,289,320,943,876,409,452,278,200,57,952,861,660,97,660,447,12,878,430,714,515,294,15,73,713,399,740,946,644,735,9,547,573,757,620,12,63,266,701,920,258,173,382,280,213,67,347,828,229,725,896,183,984,516,820,514,300,372,191,636,176,919,421,532,241,52,355", "643,742,724,964,657,966,325,143,717,624,926,541,227,929,514,943,686,218,383,545,315,504,535,846,621,915,65,340,794,403,619,402,449,539,175,633,244,36,535,356,128,522,787,882,131,818,813,109,942,806,610,241,286,420,20,991,526,685,860,155,593,507,581,29,515,86,8,148,762,234,241,61,965,901,360,48,400,271,653,981,574,351,479,285,121,73,62,660,223,57,346,117,47,101,236,748,312,552,81,945,311,499,124,903,336,665,202,598,809,690,631,313,782,228,561,316,761,645,403,194,873,202,200,391,9,318,732,298,55,604,933,272,93,809,506,893,805,304,649,228,837,788,82,164,647,637,227,279,565,31,622,962,665,126,334,860,965,524,396,908,271,451,632,432,985,222,743,686,564,175,516,900,213,934,143,274,162,408,90,620,114,729,82,319,200,939,692,897,403,409,357,730,275,594,486,332,514,17,712,310,548,948,243,573,919,354,338,164,245,657,668,531,509,456,300,953,189,372,808,498,121,377,161,390,652,444,992,891,683,106,163,36,935,997,999,4,683,411,820,421,75,380,512,681,190,408,48,756,288,488,591,696,376,388,860,644,379,730,165,889,440,707,237,301,156,463,998,340,254,492,437,913,141,960,424,624,656,730,28,341,803,917,51,230,986,869,60,703,339,751,456,348,809,865,514,231,514,686,309,579,601,782,336,945,732,743,585,434,471,788,820,654,979,53,205,658,413,94,815,87,36,94,340,782,673,403,853,769,24,666,926,883,939,931,885,747,425,913,312,670,525,319,533,952,659,243,935,397,608,937,432,467,392,738,749,561,349,300,445,988,995,92,860,254,541,252,419,177,996,705,657,34,339,647,384,774,867,529,774,400,404,409,439,995,851,346,939,894,847,777,467,839,938,628,392,812,780,783,58,26,223,266,376,470,266,106,716,678,707,276,471,71,374,657,146,897,77,604,339,886,7,992,235,89,474,596,490,777,318,701,123,571,161,564,250,978,433,170,708,493,61,74,94,51,53,247,945,197,489,266,928,194,769,553,983,98,871,420,999,845,362,623,133,890,544,267,988,360,128,553,489,429,386,868,40,332,19,956,608,847,383,858,834,358,835,129,831,722,122,454,826,941,358,930,89,596,462,604,6,799,621,137,761,982,6,737,612,182,976,110,964,841,488,150,259,833,986,864,469,195,508,798,219,855,951,412,859,344,295,7,913,832,694,372,63,390,449,593,917,97,736,529,695,891,129,192,100,571,774,755,330,142,242,295,88,301,233,241,95,808,30,863,573,144,106,913,345,11,42,788,977,661,929,91,140,657,893,691,872,358,558,23,945,919,58,128,250,397,375,335,15,420,240,96,11,120,239,229,4,571,31,576,492,366,111,850,651,476,919,789,274,737,271,761,523,934,144,243,767,338,480,686,360,653,915,147,711,934,647,93,645,789,948,401,836,601,41,664,67,371,247,417,915,367,773,846,97,305,306,296,397,250,713,31,375,364,876,468,954,769,577,0,867,514,921,472,436,685,967,163,333,215,886,704,257,95,918,200,691,176,530,537,470,920,968,295,6,419,899,964,579,901,817,802,211,217,226,678,811,489,399,668,356,807,95,454,425,93,996,427,183,103,20,444,914,763,851,433,356,375,499,712,504,890,551,433,602,228,160,493,130,835,399,37,485,928,964,206,783,372,183,481,139,512,501,75,389,792,168,38,810,715,552,935,280,187,526,236,45,394,988,458,713,686,56,524,39,114,317,834,599,444,776,843,143,55,828,462,88,930,878,221,788,685,102,148,939,711,750,565,264,649,278,848,187,589,136,234,916,12,48,99,450,967,394,204,520,277,54,857,636,564,653,610,571,890,975,184,700,649,780,157,961,343,382,175,567,370,810,460,260,478,194,575,949,329,311,760,998,726,882,370,385,167,990,27,164,123,272,362,834,253,812,880,159,842,645,936,422,576,965,50,88,609,682,906,276,868,601,838,338,164,586,665,993,281,53,423,784,235,670,898,769,394,679,399,67,916,41,14,865,655,862,157,851,184,643,306,102,471,638,461,739,42,779,410,285,626,413,720,790,92,77,434,798,156,277,122,764,318,743,67,376,445,854,747,962,944,665,242,635,162,172,888,97,34,118,909,623,675,624,31,151,782,740,995,201,512,727,614,333,596,276,445,277,211,496,585,623,369,497,980,718,77,2,698,847,788,151,961,173,55,406,816,686,716,327,733,425,979,98,749,242,769,582,628,532,798,119,868,963,800,627,966,504,694,201,387,859,746", "840,260,101,137,468,337,453,421,626,616,591,32,920,55,412,745,759,127,926,823,823,630,740,518,184,106,266,151,328,776,56,865,273,127,297,287,559,599,823,656,194,144,973,872,134,765,840,971,590,561,518,582,964,451,129,979,927,765,993,400,996,656,46,62,193,366,3,948,84,175,398,960,126,474,877,171,890,966,451,437,210,306,969,580,261,482,433,187,15,738,540,796,582,288,478,747,420,18,841,727,900,907,586,622,646,773,833,850,720,808,16,3,972,511,301,906,37,208,342,427,803,244,636,765,338,225,7,610,72,470,234,691,598,29,102,441,175,534,481,745,250,379,239,909,454,754,142,313,960,535,625,7,134,167,643,912,904,503,258,433,667,878,980,772,947,953,107,8,287,238,60,43,998,432,335,122,303,32,410,539,959,211,200,110,908,928,805,451,529,391,314,503,255,797,512,797,259,466,972,793,940,196,179,257,354,271,428,553,447,644,679,905,280,889,734,60,71,944,154,750,859,368,129,461,290,525,476,995,9,369,390,536,309,463,792,621,379,467,458,836,829,275,135,232,589,111,627,700,991,187,446,79,560,914,124,329,493,138,499,581,397,652,661,718,38,858,945,806,495,465,355,278,602,924,412,48,624,46,259,17,314,376,291,382,592,648,689,960,847,211,373,506,617,983,405,7,386,713,994,850,338,248,567,432,492,662,73,430,953,932,586,276,160,334,33,775,541,591,555,814,639,557,721,236,263,5,189,777,589,574,304,929,504,915,475,272,283,408,22,966,198,686,894,95,887,340,358,465,515,171,798,397,103,660,630,855,524,753,491,637,228,769,153,308,350,168,887,983,287,298,163,856,73,562,880,272,923,364,675,441,821,591,257,158,643,936,895,908,791,192,971,521,639,403,936,176,510,315,187,958,807,531,642,780,556,968,75,763,515,176,287,788,85,578,104,251,59,237,933,689,850,47,238,22,276,305,395,323,379,867,492,660,564,745,19,797,131,531,330,950,730,673,244,636,622,530,939,448,762,485,324,348,450,832,961,713,765,659,372,796,986,948,916,911,256,495,584,169,660,773,77,787,477,669,715,467,141,319,818,777,171,911,483,983,555,309,415,715,477,24,479,292,33,193,522,30,872,157,498,686,939,921,885,988,65,165,120,888,8,9,755,782,40,57,852,661,248,932,645,957,375,3,597,421,554,937,1000,171,976,81,407,371,525,211,433,717,50,179,795,629,119,716,150,736,981,966,597,394,654,81,151,284,277,153,949,297,41,411,430,662,55,390,188,265,999,695,866,310,50,436,614,926,228,827,483,853,186,116,383,777,12,154,696,442,583,972,2,930,350,498,254,830,449,540,659,949,702,962,253,692,94,360,958,657,993,684,906,977,563,520,233,728,541,99,149,802,838,929,875,52,524,319,872,269,679,192,367,616,696,395,181,39,481,232,451,820,514,628,671,843,88,410,717,482,920,997,496,436,690,316,372,118,564,169,893,925,619,839,299,346,919,867,0,453,91,72,252,777,985,429,108,762,132,849,959,597,915,926,994,337,236,191,944,913,69,571,609,606,935,715,644,192,610,602,733,161,641,376,779,641,596,435,946,383,607,289,910,555,290,585,725,279,857,566,108,875,624,484,725,326,570,103,447,38,998,169,749,24,924,603,25,545,691,147,314,138,441,335,101,215,612,731,238,265,26,763,936,825,671,555,366,537,384,437,551,134,390,272,351,740,473,550,808,387,195,401,758,714,445,561,260,499,275,695,670,554,915,97,693,225,952,752,999,26,817,135,543,431,245,389,105,420,829,849,754,915,134,710,321,928,146,795,627,172,777,22,239,44,184,26,593,912,754,743,30,495,794,557,710,478,418,41,6,47,706,733,988,779,590,793,217,799,209,546,584,170,738,438,40,332,405,620,672,774,875,203,74,457,459,322,602,650,645,774,471,78,526,997,945,976,669,861,209,559,214,920,11,384,180,197,745,499,391,361,865,638,707,13,782,94,182,209,209,869,303,42,519,338,654,876,505,889,409,546,52,727,938,293,302,798,890,816,949,161,484,7,508,341,201,852,824,94,487,548,865,411,631,555,831,526,155,634,82,756,959,738,640,714,362,384,753,266,460,948,686,561,760,550,329,884,943,725,95,122,129,514,945,180,187,409,297,658,449,336,483,178,882,47,383,748,921,99,149,208,122,405,426,740,943,566,753,579,162,670,426,80,820,217,146,864,27,417,428,553,688,811,517,42,193,936,226,515,787,472,258,489,836,353,578,599", "999,206,730,204,723,290,549,152,203,270,929,541,685,408,979,85,401,269,617,994,591,866,337,300,692,983,323,704,787,537,279,480,817,943,409,437,182,155,782,131,408,554,265,639,741,900,677,506,691,538,95,505,583,626,629,479,832,407,236,378,137,138,302,959,39,536,42,914,813,64,918,138,358,842,864,95,337,892,729,545,412,11,303,2,571,925,419,647,178,933,415,35,986,218,804,816,502,413,881,810,245,382,365,670,604,255,505,524,366,254,113,178,754,362,329,805,629,700,556,308,449,507,356,762,546,475,504,429,836,274,326,760,298,207,455,340,559,226,247,929,249,953,384,163,577,179,785,799,968,101,580,129,592,875,526,373,781,388,936,162,474,201,93,436,145,619,550,303,390,610,995,221,137,394,491,229,831,944,681,122,845,332,937,147,658,852,720,408,46,204,194,437,796,341,883,167,25,857,371,64,377,696,492,431,674,421,975,782,174,216,387,439,849,907,283,719,251,159,87,228,509,420,315,642,483,452,889,906,702,246,359,479,187,887,198,577,593,533,98,6,386,544,817,335,175,57,673,780,359,87,201,169,652,489,312,639,508,216,358,524,113,709,697,875,907,675,475,990,292,274,826,571,709,98,630,78,545,341,364,697,976,348,494,945,852,18,658,515,243,701,504,181,913,65,934,836,403,369,500,756,865,849,402,552,450,244,247,489,874,227,954,169,390,949,523,953,662,226,979,268,211,182,610,3,36,989,508,214,246,258,537,877,967,52,374,905,428,101,416,568,453,285,405,625,617,123,835,645,252,527,311,1000,461,778,617,562,829,577,926,826,61,576,687,821,586,819,146,930,328,58,450,784,204,257,392,447,117,635,91,531,163,85,519,507,262,527,34,40,615,253,207,110,984,279,501,927,299,920,538,50,711,333,910,719,291,391,443,54,82,859,283,226,992,478,94,11,268,758,760,474,867,330,59,478,683,362,977,453,355,406,463,285,977,804,429,348,795,889,486,209,303,423,156,836,50,634,961,186,122,510,80,651,859,244,937,677,401,934,800,446,461,476,617,202,207,515,250,663,341,436,247,407,275,490,214,962,458,841,650,598,677,479,985,530,634,254,378,512,210,448,785,657,931,556,432,780,918,452,384,175,784,846,882,102,582,575,891,145,769,6,137,338,910,974,826,465,340,315,854,378,418,30,107,235,618,475,628,921,724,656,500,960,41,610,647,485,110,720,831,153,109,378,296,408,148,208,811,862,116,291,432,708,560,732,765,282,861,712,780,129,133,296,54,945,594,283,655,278,961,448,432,191,166,396,948,985,728,14,152,217,222,9,343,92,793,399,648,824,214,626,254,135,162,835,72,531,557,281,718,291,464,778,547,34,517,882,690,905,338,992,549,332,192,614,730,455,267,778,611,512,709,895,734,570,36,665,567,873,489,638,832,495,150,362,694,404,108,165,770,120,159,819,654,160,397,582,92,862,220,591,591,363,423,49,802,300,429,17,134,313,989,514,453,0,55,828,191,824,511,674,340,963,255,270,743,799,232,950,514,636,565,266,90,812,628,894,202,271,734,195,170,730,363,72,507,982,368,178,280,114,727,548,450,671,359,553,944,354,69,449,888,262,862,372,605,96,379,686,938,752,374,614,784,914,968,838,323,775,405,636,762,473,742,988,675,667,89,104,642,658,310,689,403,63,334,184,280,145,206,742,455,49,290,801,751,330,299,17,165,975,725,406,775,597,426,22,904,407,156,395,130,47,714,399,303,387,94,805,605,322,36,85,777,40,186,792,975,667,766,33,616,50,413,131,359,970,28,698,357,359,634,976,352,34,14,937,407,267,119,431,916,583,977,125,343,368,937,141,432,266,980,700,990,854,730,48,263,569,360,539,136,889,176,908,627,13,109,746,791,772,924,861,663,864,400,59,994,236,107,273,167,160,930,217,41,47,922,390,101,131,853,368,494,909,969,679,806,755,792,103,203,991,464,789,414,641,927,674,123,490,476,436,521,926,765,494,151,561,504,366,27,967,913,515,816,242,119,842,381,734,736,749,969,154,414,687,543,945,725,424,467,250,199,240,88,824,309,169,724,997,979,595,40,100,613,427,798,953,630,890,855,544,262,833,842,535,287,389,637,468,522,872,755,882,583,908,681,831,428,978,301,963,979,898,401,897,713,549,338,181,889,175,491,918,637,87,544,859,494,934,387,805,949,276,114,601,465,906,558,177,36,625,499,895,236,208,170,998,957,751,81,618,749,889,154,757,165,860,710,705", "940,152,795,388,124,656,104,508,709,448,344,397,194,256,872,239,837,238,69,570,571,846,290,559,714,604,530,671,960,813,556,919,509,577,364,347,390,646,375,194,924,405,382,460,701,730,259,544,53,218,444,537,351,34,271,931,443,305,86,864,637,305,71,269,447,644,160,27,549,495,501,976,197,937,611,394,85,647,168,316,242,477,660,240,807,756,130,190,606,768,618,510,874,914,121,509,507,201,674,254,519,642,312,98,465,946,143,285,365,18,32,921,44,919,19,680,159,265,18,331,633,289,7,427,759,63,330,122,946,434,922,445,467,470,675,919,758,148,922,446,632,565,488,90,921,203,197,326,284,225,904,454,413,486,617,954,916,890,108,131,332,822,330,486,626,510,857,869,889,615,28,172,371,710,631,471,934,798,366,844,873,246,479,389,840,755,19,423,904,595,889,835,187,119,326,80,822,861,502,628,470,293,775,858,20,333,430,72,408,124,232,164,883,714,706,968,640,875,600,664,628,518,46,796,809,320,445,728,592,439,989,917,249,880,538,390,508,543,816,466,667,499,174,915,931,254,834,277,939,146,506,331,103,653,365,919,404,663,911,464,750,278,763,980,93,875,22,743,928,148,311,371,667,862,600,473,106,583,879,194,274,169,158,866,143,754,272,126,780,602,800,413,738,57,797,243,927,118,106,37,139,327,738,729,477,623,6,73,859,559,419,346,256,736,877,602,555,864,322,725,853,703,150,326,773,459,646,207,931,211,982,767,824,805,954,994,603,877,385,650,826,908,523,7,400,314,840,693,735,542,548,212,228,205,596,672,934,587,298,342,878,446,526,454,483,354,512,242,877,831,548,415,927,426,832,391,435,881,563,695,506,113,91,2,200,953,421,305,448,727,914,908,820,341,442,7,813,462,422,31,123,553,946,92,720,478,666,678,805,845,661,170,951,824,92,378,364,360,303,951,281,376,211,626,668,388,59,516,606,791,151,160,120,151,648,18,903,154,752,446,268,619,726,372,950,625,757,160,894,12,486,720,973,152,210,828,557,385,137,452,211,487,412,328,437,922,692,566,986,746,601,649,170,716,850,657,814,327,778,465,902,930,392,889,822,847,296,743,50,872,450,215,372,21,675,712,772,807,760,994,899,151,723,702,507,958,43,594,200,706,336,217,273,230,727,16,484,184,478,819,280,635,311,947,19,718,960,568,359,15,284,165,995,141,715,398,325,653,720,497,18,909,250,471,32,765,488,869,379,315,952,393,134,447,230,590,539,375,532,487,87,188,981,836,844,699,957,352,171,9,829,536,259,303,23,128,106,409,205,749,996,491,957,248,132,96,717,773,288,176,881,515,967,20,268,179,113,710,103,654,421,306,27,987,948,413,528,294,376,168,156,325,280,612,632,745,637,803,769,748,588,645,221,166,631,906,358,143,20,76,77,640,740,948,621,540,437,601,405,881,573,830,591,594,785,510,353,862,924,675,681,955,237,355,996,393,700,673,662,839,320,921,91,55,0,494,380,836,151,378,952,205,549,275,938,108,131,11,621,828,243,983,760,974,504,736,343,118,88,164,899,426,35,76,831,158,969,564,611,210,441,165,791,145,955,735,479,376,119,687,582,861,554,77,871,872,645,708,186,301,922,967,857,288,260,764,954,83,395,96,752,327,915,919,716,896,119,999,69,99,94,916,594,27,403,126,70,488,481,891,253,416,998,437,526,395,637,961,340,256,652,160,342,849,438,572,573,875,532,768,857,567,156,97,935,60,533,793,860,273,213,799,64,998,3,385,586,110,888,119,671,36,957,683,981,239,487,508,799,98,979,142,242,750,826,757,793,451,151,178,699,763,329,744,134,105,45,578,763,377,989,40,65,529,553,424,613,579,905,413,9,31,340,952,589,277,938,632,602,120,640,986,919,294,407,275,431,8,369,464,505,907,976,526,860,692,889,58,913,310,47,479,721,720,353,687,594,742,552,895,237,675,221,356,161,912,386,396,484,655,718,377,870,447,42,71,381,342,721,33,240,779,352,59,6,426,980,396,778,586,795,528,23,809,167,300,943,615,925,131,727,816,72,339,451,630,514,41,569,817,802,497,897,13,257,607,979,25,676,718,87,568,301,200,122,865,631,949,43,925,545,874,29,203,96,855,981,708,95,32,25,340,15,989,1000,684,70,88,722,455,384,950,835,515,656,359,390,245,672,214,836,633,495,463,325,728,550,238,787,986,523,369,526,476,971,226,682,389,714,25,435,415,103,865,764,441,652,520,864,137", "489,419,997,96,940,166,412,839,679,468,523,839,467,194,579,422,417,508,939,767,391,347,452,421,624,768,38,724,780,569,161,258,219,53,10,958,357,865,486,848,710,551,519,527,291,261,273,790,513,8,494,58,404,397,902,960,274,217,831,862,603,58,149,378,488,222,982,853,538,269,690,289,855,558,470,289,979,791,845,340,662,603,316,119,166,735,501,49,836,67,523,428,814,434,910,760,180,752,138,475,704,756,256,720,1,152,595,480,671,535,381,347,325,796,375,861,66,618,823,741,826,668,512,962,519,840,354,463,939,967,588,114,729,306,584,550,971,749,592,868,86,41,914,7,567,176,320,157,660,266,77,918,492,11,981,599,237,33,683,338,631,64,13,607,955,750,753,915,277,605,416,386,665,509,170,869,690,170,261,885,125,952,344,281,483,488,817,780,941,960,651,250,891,325,362,548,873,190,97,77,240,406,577,215,339,890,479,431,516,410,712,193,376,63,106,905,707,477,299,938,369,884,682,430,308,389,156,993,615,985,684,841,523,356,944,240,803,509,577,624,896,255,703,423,407,183,817,812,321,923,797,964,61,503,190,275,85,652,603,390,876,896,557,926,466,496,877,662,891,551,402,881,843,342,926,549,164,701,54,938,502,956,713,172,48,462,575,406,288,565,98,236,857,800,279,387,512,425,220,45,289,363,857,404,589,917,261,350,501,609,787,87,479,166,808,419,521,318,709,146,611,35,809,490,541,551,675,214,463,910,669,297,694,524,594,182,933,778,526,674,135,687,120,936,660,956,593,236,968,585,621,268,160,398,351,70,928,197,339,556,452,183,324,121,59,138,921,755,22,473,71,96,549,635,227,63,743,355,889,648,956,623,175,521,551,441,80,417,847,29,279,251,52,515,271,680,488,414,727,75,260,777,357,723,328,1,675,158,526,991,285,110,330,977,286,48,111,971,309,390,987,349,716,750,818,676,452,449,953,172,637,612,305,146,146,986,250,734,566,844,409,490,31,822,927,162,816,326,186,661,433,212,176,802,146,673,806,347,736,961,763,106,698,673,978,161,497,907,592,104,421,110,847,508,855,32,479,213,825,823,841,509,284,221,33,940,990,985,407,465,712,133,222,650,406,369,473,276,670,267,882,53,347,210,201,305,633,3,690,19,905,69,202,845,919,236,405,146,56,48,542,894,410,509,154,984,815,218,274,342,97,403,398,968,193,411,399,46,399,747,593,884,712,670,975,517,949,222,357,935,625,429,971,343,791,489,258,140,619,10,645,751,480,321,957,579,741,634,641,244,570,462,74,290,712,973,317,533,756,577,189,752,978,488,375,441,700,559,769,213,577,689,679,942,266,331,19,123,624,140,754,413,356,409,108,940,911,241,910,314,353,542,387,165,401,721,534,496,550,499,789,892,283,721,971,52,955,200,303,371,522,64,154,821,194,67,933,437,697,470,772,431,437,276,805,89,400,829,618,499,178,233,786,894,531,335,445,569,964,140,158,472,72,828,494,0,25,206,48,729,11,16,597,323,704,898,300,91,504,908,249,9,612,972,332,926,848,986,592,192,215,836,237,72,624,552,255,18,363,569,393,53,253,921,977,887,265,623,592,365,772,427,626,53,303,386,460,876,991,695,58,9,258,935,177,850,264,557,709,555,300,26,549,206,93,86,567,291,276,919,58,211,345,998,783,614,331,228,243,550,993,12,409,746,476,76,438,318,373,811,406,533,362,845,833,212,211,342,342,597,751,90,460,359,656,406,551,3,953,496,855,861,940,990,967,170,381,330,465,50,652,120,140,256,492,708,379,409,913,299,534,685,155,177,58,136,913,607,698,273,887,113,613,886,696,430,999,84,904,713,243,470,587,596,490,906,143,532,512,256,87,44,993,334,231,708,95,131,90,843,176,434,198,286,780,655,311,380,891,966,130,34,336,609,194,237,868,484,488,724,395,886,460,872,667,534,365,543,936,729,429,96,177,124,394,219,367,800,737,301,530,614,530,279,873,168,750,608,798,234,350,683,287,525,82,925,500,844,260,560,145,711,38,650,626,558,771,376,186,379,205,124,661,162,251,987,395,894,131,686,448,914,264,729,967,178,978,656,666,273,395,751,375,727,159,689,974,601,421,764,810,484,98,312,36,795,3,322,963,923,21,859,356,275,487,372,755,373,17,303,348,74,150,321,953,28,195,859,211,845,782,978,565,444,448,905,219,918,40,348,572,925,29,856,624,590,988,269,268,476,705,671,133,704,339,668,323,831,276,55", "803,84,795,121,212,637,156,769,367,496,601,568,603,869,630,607,468,661,235,916,846,824,132,736,66,750,889,237,892,762,426,951,174,21,764,183,130,452,582,243,830,454,820,219,864,6,930,865,109,756,918,262,453,563,245,442,494,442,676,836,308,152,271,606,787,904,142,627,815,199,86,390,526,361,169,237,528,979,662,769,448,117,659,142,648,687,367,936,506,383,254,978,660,274,125,391,413,645,231,640,443,16,853,9,659,571,407,602,195,228,500,486,909,759,690,292,609,426,673,658,757,372,421,32,60,764,176,360,732,744,666,740,382,676,560,837,919,708,933,881,433,357,841,4,945,63,376,961,678,780,422,602,675,537,627,249,67,991,907,215,552,8,118,851,583,933,798,887,145,838,629,134,571,51,401,546,92,780,418,292,371,969,270,392,540,325,749,755,453,967,271,306,166,452,909,139,861,44,138,802,554,379,673,319,311,770,770,841,734,800,541,236,712,526,107,42,97,995,481,929,214,464,664,721,254,145,255,398,936,234,333,838,669,628,671,120,834,613,823,149,198,577,610,847,200,117,111,653,91,7,3,18,828,657,255,790,852,642,653,976,297,57,438,760,503,117,281,475,379,896,685,373,675,758,817,337,347,459,545,725,802,631,631,367,924,221,111,303,948,259,208,650,639,310,614,686,761,964,746,440,64,995,750,227,589,457,688,645,125,51,54,594,395,528,412,976,142,142,809,806,420,588,33,848,30,352,370,150,457,737,508,969,683,901,50,671,924,799,30,500,866,958,53,232,207,859,891,311,199,698,921,926,884,204,668,68,29,255,943,927,57,462,443,685,548,26,58,722,681,250,851,408,698,117,434,162,659,930,750,149,611,198,212,904,963,654,228,884,874,949,767,106,477,460,647,723,118,26,124,423,616,561,788,594,708,480,598,76,243,664,850,232,897,531,81,620,464,151,577,742,472,945,98,897,142,209,937,669,31,545,966,73,884,976,882,429,656,534,574,895,142,443,87,805,675,764,391,168,588,548,160,717,864,234,398,163,167,347,486,650,417,850,136,533,629,329,294,50,630,195,446,881,927,69,684,266,536,395,823,713,765,788,857,702,158,172,444,716,704,389,838,196,957,158,128,534,114,464,627,518,902,116,390,152,267,560,747,266,167,742,808,57,673,183,888,877,652,677,507,716,996,733,496,873,875,73,733,961,410,962,579,973,104,301,729,949,838,21,794,746,924,500,468,274,511,402,4,190,379,280,531,980,437,550,709,210,323,694,24,887,322,876,89,754,886,372,85,865,632,284,377,522,910,578,220,457,409,640,276,647,211,37,100,285,625,73,991,170,622,919,853,478,968,322,352,427,595,512,810,7,300,22,366,650,310,488,859,459,743,727,209,17,609,348,78,19,631,3,598,608,108,349,491,939,403,851,973,831,918,606,639,806,865,243,578,407,680,411,915,669,531,755,436,852,655,501,598,930,687,596,671,777,418,361,908,587,510,321,949,325,353,436,252,191,380,25,0,287,95,373,497,341,933,514,779,911,761,693,485,832,104,875,617,819,127,956,513,282,222,110,81,929,72,512,103,656,133,390,84,69,433,436,39,731,526,458,760,324,199,41,860,284,37,226,554,318,769,990,253,235,496,124,240,843,184,87,10,734,759,985,256,560,389,167,220,174,603,439,527,185,784,138,458,210,930,614,372,525,200,94,561,74,676,594,264,635,84,785,733,247,224,22,508,907,571,895,838,354,590,702,818,966,52,130,329,585,621,871,419,451,272,776,189,154,838,961,593,379,487,885,15,403,861,387,787,407,300,229,214,326,496,889,153,207,839,228,386,715,680,305,939,724,804,318,172,911,150,278,6,632,863,718,681,548,830,296,420,79,428,771,948,819,917,826,70,116,344,614,815,657,925,499,290,36,372,201,885,874,571,306,58,785,721,602,106,391,848,926,659,497,256,780,370,811,588,634,984,699,90,564,976,397,811,56,193,425,829,818,383,801,556,662,432,924,932,937,527,357,255,479,380,762,225,446,618,667,430,140,605,669,396,533,692,602,871,147,776,785,296,445,133,473,94,793,80,653,102,50,143,188,194,450,539,951,854,344,354,795,329,983,280,535,96,978,233,642,829,89,873,332,862,631,330,517,939,72,686,734,106,249,52,818,170,321,529,175,906,572,614,953,268,211,905,146,316,319,763,970,446,350,249,175,432,916,178,823,771,133,225,57,341,528,814,48,178,862,506,62,887,600,717,142,665,380,630,677,391,779,723,292", "164,814,415,329,387,967,54,581,492,102,363,900,838,16,201,799,183,13,663,754,264,633,198,786,746,633,703,463,834,77,81,136,844,738,953,776,668,797,328,828,721,698,656,84,372,907,958,242,658,93,825,731,437,678,19,317,953,967,359,654,839,410,992,967,980,767,264,543,238,570,560,684,558,490,382,363,10,645,565,942,608,434,415,749,236,71,330,984,653,723,373,193,502,192,776,230,596,424,952,280,162,63,378,64,266,419,6,84,684,603,726,382,948,937,45,611,605,563,518,918,156,927,213,621,935,156,811,749,367,86,228,763,204,344,743,310,295,502,311,513,743,485,616,885,383,890,521,988,438,142,198,551,5,227,835,93,208,110,76,321,826,383,763,70,628,780,71,449,616,134,610,250,762,708,747,578,765,707,753,685,68,318,69,988,433,244,626,923,865,635,123,964,397,416,27,965,695,662,888,236,255,451,562,577,799,758,416,924,75,219,288,999,598,739,698,323,318,951,168,163,188,806,859,234,235,18,388,275,850,370,872,21,151,125,865,337,590,509,518,392,606,559,477,145,348,352,661,21,832,816,699,690,955,122,670,780,28,607,326,796,95,962,301,610,419,335,28,876,748,137,70,147,404,533,858,336,786,461,665,526,608,401,213,887,342,852,452,138,927,642,663,557,274,153,943,577,885,581,590,939,325,734,178,208,718,750,345,297,447,812,916,541,631,113,680,722,191,603,485,253,83,78,413,905,519,808,171,885,920,995,447,581,14,955,868,380,566,791,238,462,184,52,234,552,674,127,571,268,254,410,951,268,130,645,74,457,91,682,828,228,161,938,830,737,528,727,253,713,508,521,11,320,394,905,764,459,671,730,777,826,207,278,606,887,861,399,414,244,415,159,697,325,203,461,186,759,292,517,282,252,602,691,902,10,826,294,947,927,910,708,686,227,152,95,316,19,321,996,387,353,706,883,960,808,272,560,205,494,298,694,154,23,988,358,506,405,346,563,526,179,558,216,146,541,759,814,906,24,371,523,865,967,46,510,321,777,823,286,141,745,526,49,546,107,154,234,726,102,916,294,761,993,532,796,401,268,61,908,794,769,153,298,880,164,576,852,839,505,231,847,334,172,179,558,576,571,283,966,903,244,711,671,1000,370,195,884,59,166,335,453,466,321,656,155,196,7,91,425,230,902,222,427,790,749,987,548,583,237,646,452,19,456,31,534,870,743,893,514,789,434,184,778,233,177,344,569,107,724,812,250,718,156,72,630,279,56,755,787,606,289,73,469,877,358,113,250,945,282,977,977,22,662,734,769,45,122,983,704,721,865,395,232,437,746,656,50,171,494,160,816,29,882,237,803,579,915,452,352,7,733,590,23,41,243,791,963,885,797,461,115,219,931,146,536,751,758,992,646,940,164,996,554,420,764,856,785,266,343,852,329,766,822,89,217,563,338,703,215,19,986,392,996,855,846,836,266,559,436,732,615,654,267,148,256,303,786,28,610,877,356,73,685,777,824,836,206,287,0,502,659,210,857,973,888,997,193,214,760,935,734,815,74,26,506,91,395,42,340,911,977,894,967,382,25,842,217,514,980,744,563,811,588,691,299,204,585,452,821,760,174,538,203,406,565,172,435,567,441,626,548,968,141,634,546,943,773,450,615,517,582,445,968,646,268,740,613,352,449,594,162,63,536,403,151,880,60,653,906,256,358,722,483,666,604,312,916,155,340,687,438,287,545,528,342,215,738,349,444,318,382,553,812,791,263,446,928,847,691,363,419,930,953,306,936,446,354,938,215,271,522,729,224,2,296,457,970,598,554,159,205,78,331,10,20,688,944,159,699,953,828,497,910,784,768,461,432,134,103,527,74,586,506,804,756,191,271,73,47,418,349,908,975,965,410,98,965,545,114,962,220,645,365,818,711,835,628,666,600,725,773,174,980,527,690,552,180,210,819,903,538,181,845,368,426,296,460,714,657,106,144,404,202,43,661,943,554,584,6,903,862,564,828,236,332,899,339,475,932,505,940,420,388,211,677,727,9,788,601,347,542,747,877,450,240,850,127,10,490,751,439,564,37,610,224,833,280,979,669,748,427,660,344,83,563,23,101,75,111,511,634,902,758,715,700,965,159,141,364,273,378,894,785,681,967,933,261,217,153,89,979,62,441,727,296,595,89,618,909,532,336,185,107,368,247,318,470,447,704,624,14,541,433,653,236,95,348,790,58,777,244,965,522,931,329,867,155,828,540,524,655,829,666,333,963,286,548,854,487,954,378", "806,656,475,156,855,735,103,627,964,330,284,639,672,734,903,400,138,101,853,291,556,946,973,918,648,136,859,600,209,985,90,729,76,327,888,464,905,680,365,175,914,408,765,600,662,751,691,847,802,322,795,806,543,645,824,336,915,134,899,891,341,454,446,443,589,186,257,706,219,567,107,885,710,72,297,691,824,986,990,488,396,196,710,21,356,189,627,91,392,282,721,765,605,445,273,598,901,703,498,761,377,957,300,725,788,790,744,404,764,846,465,383,69,688,146,472,622,422,221,985,208,809,91,897,312,783,53,887,151,155,433,758,12,489,644,567,825,733,455,347,71,868,660,682,374,897,81,527,524,309,907,504,39,227,869,75,465,378,494,885,786,80,454,446,719,145,870,438,45,680,802,713,253,893,399,340,393,245,667,463,723,762,421,386,56,194,516,380,632,869,579,382,334,190,159,403,686,148,755,757,948,291,594,268,102,716,992,668,581,508,680,718,859,244,358,335,291,234,943,667,94,580,7,524,448,672,578,12,835,292,785,760,78,72,565,411,690,832,632,906,330,621,31,278,600,200,521,568,407,956,122,596,987,986,431,146,816,300,108,145,339,290,301,915,224,568,63,612,303,89,634,329,324,739,945,406,605,965,417,303,938,971,442,40,336,545,302,362,930,74,918,174,767,133,213,235,371,657,955,716,121,187,730,76,385,734,672,910,716,942,202,50,888,138,4,785,665,875,390,592,470,372,90,231,683,956,171,38,542,863,927,51,49,181,259,228,741,40,594,946,137,77,827,915,769,355,638,292,466,265,677,657,378,650,159,464,728,644,284,272,894,647,739,660,583,366,120,953,649,219,748,480,981,282,918,865,413,597,936,59,798,141,429,977,293,230,293,498,117,964,784,617,493,601,129,888,722,888,97,704,252,825,97,546,782,577,145,166,37,556,943,868,117,421,582,171,198,448,489,303,392,214,648,660,117,964,694,766,491,47,437,348,419,630,389,541,803,693,815,550,426,190,928,862,422,390,358,313,207,6,779,452,989,535,630,895,333,419,57,261,231,973,495,651,149,189,974,255,392,416,906,904,684,133,58,226,640,81,670,175,356,374,288,95,465,165,907,28,615,208,603,795,725,525,442,432,523,889,166,337,183,108,150,72,481,599,901,260,411,328,957,316,659,343,133,357,414,501,157,690,535,755,7,131,917,641,748,154,28,143,251,130,727,243,898,881,766,84,182,53,828,262,35,295,492,999,44,998,492,133,621,265,716,924,804,945,715,428,937,812,899,952,599,318,700,74,815,475,22,641,363,388,990,614,44,225,588,32,360,167,222,816,942,728,742,570,417,366,634,190,27,300,28,429,698,901,689,241,802,173,536,753,633,308,905,239,188,794,342,505,881,384,855,843,792,773,362,637,803,357,740,549,415,8,603,613,991,207,574,530,439,921,338,237,697,130,702,430,38,450,500,247,896,164,234,217,357,270,118,833,931,89,128,572,79,689,175,969,664,795,586,967,985,511,151,48,95,502,0,802,114,887,91,137,577,76,866,32,442,827,569,849,138,32,266,928,244,970,589,610,952,724,973,327,646,615,377,560,570,614,807,473,681,899,941,908,43,398,516,302,190,16,435,507,656,822,819,440,712,780,762,841,22,849,179,459,118,993,330,930,161,974,520,412,806,872,753,92,755,94,71,892,786,215,338,886,620,986,963,982,989,961,658,350,273,917,903,532,736,212,897,65,261,202,788,52,99,292,171,184,809,78,738,950,38,777,399,5,955,748,578,324,305,424,445,673,367,414,170,889,98,64,830,413,934,102,424,72,965,874,466,447,4,695,185,184,59,85,480,104,941,406,841,733,452,684,186,583,865,589,671,781,753,518,883,653,1,45,491,518,226,307,41,104,231,731,977,257,502,604,106,232,438,870,682,906,495,616,271,842,362,604,342,927,856,348,873,475,591,978,919,771,732,385,167,982,957,821,7,869,969,29,449,295,665,264,819,892,369,854,982,25,248,274,18,257,143,476,252,593,482,343,887,797,78,871,137,999,869,283,537,149,542,599,897,226,257,316,295,56,323,894,926,53,548,125,924,628,816,647,204,103,360,199,143,341,736,87,636,211,688,938,692,762,524,669,857,592,249,872,58,459,852,164,364,501,436,366,74,382,33,766,708,141,211,747,602,612,982,90,239,51,101,118,606,221,269,651,941,896,233,987,491,32,868,184,165,155,932,68,280,435,730,692,165,834,864,533,587,935,628,155,728,429,645,993,959,242,515,833", "187,236,851,488,65,177,668,340,544,547,636,80,776,12,576,724,844,146,543,31,952,837,952,589,409,389,178,503,677,586,909,557,974,352,32,914,546,561,117,772,897,79,353,640,585,630,129,235,847,964,862,323,566,727,220,305,310,651,406,997,850,423,726,329,643,436,263,492,118,13,41,288,973,604,208,819,535,79,24,259,144,643,175,585,4,971,902,208,519,66,907,640,497,761,108,578,143,173,498,672,157,371,982,223,866,563,536,127,510,568,496,371,225,83,423,550,180,69,277,571,588,571,704,973,48,167,821,910,456,783,905,413,817,259,585,613,33,784,374,851,744,901,837,943,497,980,745,540,720,717,780,99,76,493,89,895,298,533,903,852,403,709,293,57,875,237,651,440,443,589,369,234,967,62,792,394,670,234,928,531,516,647,361,490,22,647,951,327,312,802,669,489,578,755,922,898,863,468,117,217,350,400,979,299,299,820,227,855,776,677,666,124,878,76,203,871,917,416,141,232,647,504,438,77,623,641,290,484,22,675,119,952,591,185,481,507,548,402,954,21,375,977,31,989,693,451,615,462,499,771,402,828,443,780,223,482,655,236,299,944,453,179,947,880,816,852,411,434,763,173,603,874,808,708,987,549,836,710,2,512,692,839,152,484,973,921,934,635,702,192,989,564,223,840,581,957,251,57,858,742,337,444,21,237,84,289,845,296,244,756,73,560,984,834,721,800,226,514,465,626,928,357,388,535,376,284,922,681,930,554,297,187,411,964,373,718,629,618,216,348,354,706,100,838,38,140,543,322,197,695,202,381,401,899,801,179,320,129,971,583,316,476,950,512,519,702,658,234,781,925,426,834,13,255,229,456,957,908,472,161,450,571,382,201,475,988,112,998,321,577,942,304,925,968,199,489,495,852,991,435,698,780,852,701,638,960,504,388,353,790,511,693,645,323,173,914,521,686,674,90,124,882,332,164,972,517,780,391,177,52,341,932,596,609,525,677,318,842,386,671,423,284,116,197,258,941,615,275,120,434,752,759,657,476,242,14,588,242,395,538,854,4,817,784,478,575,806,852,860,760,605,694,756,547,118,236,231,283,551,246,386,577,361,536,257,167,686,448,574,628,963,102,242,1,284,70,582,68,706,671,523,892,704,986,139,267,610,73,194,190,654,721,793,431,583,956,574,793,5,993,423,899,44,54,302,698,958,197,974,998,875,33,408,183,497,203,288,648,117,160,268,250,557,742,799,246,473,647,342,422,942,331,131,455,389,574,542,939,813,714,879,863,558,999,308,802,334,476,611,748,73,348,56,140,662,634,239,120,939,769,631,742,681,840,41,913,10,566,648,42,666,594,211,104,424,443,167,647,343,934,788,758,766,272,12,328,736,932,17,54,485,303,493,841,626,514,322,944,74,382,793,916,206,351,42,182,737,625,120,946,844,520,589,57,642,395,233,436,157,320,63,959,102,869,146,121,126,31,188,709,75,405,795,618,491,689,317,12,415,65,907,163,429,674,378,729,373,659,802,0,322,311,992,377,575,244,441,7,725,481,383,837,98,455,406,880,682,357,646,928,178,486,536,849,494,861,601,114,653,570,4,863,375,5,172,884,698,571,622,174,130,98,915,478,1000,17,775,331,91,283,207,522,425,284,981,26,311,244,36,896,69,847,945,517,503,146,116,442,739,198,542,68,301,132,151,672,336,734,487,614,935,393,97,159,157,679,319,784,267,33,12,25,293,709,605,653,724,487,555,355,126,525,87,579,695,444,384,56,134,844,927,748,446,393,843,640,868,555,945,909,176,474,435,232,739,822,663,879,943,897,871,674,321,938,338,515,320,582,880,270,786,149,955,576,849,286,644,322,168,602,767,553,119,905,535,695,702,292,836,374,144,419,279,635,514,338,244,22,955,165,877,209,38,901,411,693,794,900,576,204,848,343,888,682,603,910,660,527,573,551,280,854,227,759,552,902,466,743,838,163,627,288,345,283,102,748,794,223,921,93,944,280,94,388,974,497,609,970,276,878,723,816,562,868,184,471,869,677,356,659,475,77,190,619,133,185,288,796,767,241,3,994,539,529,600,306,427,727,673,141,952,347,79,479,594,731,831,293,544,149,482,658,795,769,460,643,508,183,737,873,467,488,98,498,926,728,443,466,691,874,440,633,966,665,217,803,94,522,511,869,565,526,168,603,116,401,574,481,251,130,782,40,484,99,107,802,516,805,636,884,610,726,52,957,836,539,857,875,845,452,379,524,397,381,342,862,887,67,646,63", "989,262,274,645,382,766,113,686,852,550,445,617,937,131,577,628,56,208,491,805,693,725,16,389,108,887,491,627,431,341,816,550,566,703,502,928,792,649,289,786,884,654,214,592,625,334,964,954,409,304,910,964,786,914,834,36,297,829,477,112,797,4,327,607,703,80,908,299,965,837,990,66,68,30,179,542,77,849,897,999,462,774,33,284,233,110,714,155,388,71,91,441,214,108,854,550,339,740,230,134,336,685,599,830,114,233,901,843,356,678,132,715,39,693,734,217,510,275,662,213,781,301,890,382,721,89,447,33,375,635,357,280,712,819,214,108,322,594,787,788,789,437,502,505,593,888,573,274,862,180,85,702,173,831,620,739,582,46,993,625,811,595,395,494,455,306,764,289,131,504,424,522,401,882,293,432,143,721,759,906,23,923,111,219,698,342,873,968,275,404,395,866,490,119,67,496,174,225,304,278,632,598,816,866,634,901,414,588,647,328,349,551,332,246,548,494,278,705,953,119,753,712,990,817,121,820,497,934,213,813,442,938,723,720,695,148,18,271,261,922,306,788,204,117,544,281,276,740,614,940,599,146,268,448,481,155,128,266,674,208,21,398,932,331,617,694,649,719,206,626,294,771,448,431,475,516,905,436,247,617,77,468,792,55,643,215,760,467,613,443,661,217,430,403,896,838,796,535,297,150,761,581,490,318,509,528,278,552,519,740,127,594,812,61,92,88,979,659,693,262,714,727,402,9,670,886,498,318,716,90,478,688,677,516,127,819,811,392,571,560,335,412,920,284,52,565,680,697,243,259,628,177,464,519,789,244,853,609,116,56,618,619,278,481,311,671,662,162,697,883,968,126,441,852,797,211,181,36,163,364,873,271,539,671,262,333,113,404,521,583,350,943,20,91,289,705,873,667,488,799,196,220,513,308,861,655,527,275,797,199,193,347,521,924,745,191,249,163,420,947,532,551,733,192,313,876,239,971,923,238,715,180,996,113,132,5,517,374,355,726,121,96,866,287,766,241,792,36,3,570,212,503,405,104,271,844,681,166,63,432,532,218,713,501,785,311,809,848,428,453,854,378,869,964,860,446,610,299,778,352,586,509,635,529,508,361,127,190,167,257,465,728,242,429,566,363,332,60,772,805,867,227,89,343,319,44,167,531,174,17,618,48,506,936,858,804,249,200,111,682,7,454,426,523,314,134,297,275,118,986,926,483,800,526,542,655,284,992,86,756,54,653,899,15,920,737,547,973,714,989,445,573,397,296,587,789,122,977,314,591,423,125,717,971,762,418,603,558,59,562,814,187,5,468,191,97,216,745,831,6,81,728,426,896,421,973,948,479,852,855,444,649,938,573,516,320,848,516,289,252,764,3,556,470,363,709,839,608,770,592,170,933,367,891,892,756,484,329,317,552,896,944,836,18,81,853,628,610,931,604,725,416,504,442,606,563,793,677,185,332,679,885,653,494,338,143,906,197,470,118,19,645,282,304,466,182,269,539,86,355,340,333,108,340,952,11,497,210,114,322,0,246,430,989,897,512,380,976,550,851,513,582,583,329,822,29,988,726,163,15,166,426,645,612,93,790,8,195,41,626,989,896,158,541,958,83,65,139,156,160,631,393,956,976,457,886,171,896,974,372,393,939,872,323,520,963,936,827,423,448,853,293,529,943,968,947,267,396,62,509,313,708,937,146,708,409,409,863,821,614,825,536,682,101,260,839,537,315,282,127,128,344,122,704,377,452,120,337,748,268,495,753,407,424,441,281,364,803,40,344,139,221,651,46,744,812,621,651,392,195,384,366,912,560,306,963,833,101,116,307,951,923,794,394,870,518,132,819,824,12,621,122,213,801,863,813,733,169,969,288,868,858,353,216,868,34,663,641,273,683,88,228,956,462,357,689,399,24,639,687,411,793,946,84,662,609,901,786,443,543,233,223,948,619,522,508,828,888,306,166,751,89,540,645,264,858,855,556,93,805,545,421,894,312,198,148,783,428,833,495,124,881,366,978,803,278,738,252,877,393,381,267,675,159,860,591,987,221,742,401,565,51,477,482,963,765,286,643,524,489,848,119,11,183,572,107,750,461,765,116,844,200,143,104,628,565,340,324,745,72,705,173,47,790,863,203,379,314,405,269,33,898,680,413,469,159,167,662,527,759,154,497,391,209,475,779,475,174,159,464,887,742,391,960,116,478,136,459,108,357,972,664,541,800,913,585,221,46,879,858,8,324,461,351,406,866,567,646,483,761,463,320,464,226,138,455,667,789,842,71", "178,476,953,398,504,349,700,690,961,336,850,774,989,794,245,969,336,962,791,537,847,391,265,591,285,301,439,851,359,884,802,127,636,250,334,931,68,500,822,528,389,73,91,200,70,473,957,802,782,874,438,747,907,919,40,70,703,976,983,21,43,429,471,357,383,756,894,241,122,813,752,964,480,844,451,271,274,559,629,197,823,66,907,598,297,218,821,892,912,687,507,780,114,107,454,879,849,87,129,885,484,988,507,350,278,317,414,969,79,245,331,339,883,84,510,716,151,667,762,34,528,106,99,749,329,749,315,314,600,111,1,603,439,986,413,99,990,829,162,428,223,132,813,201,932,530,570,967,5,17,879,634,842,267,502,383,544,457,34,284,268,698,14,685,372,399,280,775,393,998,453,223,432,564,570,377,943,629,833,685,405,34,339,237,93,226,4,542,326,899,337,150,805,117,302,35,854,280,800,603,139,830,558,95,875,712,460,621,503,363,95,122,73,297,269,478,443,46,625,71,98,808,263,163,655,808,438,465,464,83,195,302,347,142,645,256,902,975,706,130,164,245,795,835,441,806,982,983,635,511,963,580,916,10,147,680,171,243,286,925,411,300,861,814,298,588,379,795,27,771,22,303,999,184,1,301,662,469,393,911,456,972,701,769,660,763,114,328,524,627,469,941,989,398,338,382,675,100,934,31,194,243,781,356,937,855,364,736,377,850,66,973,927,397,714,959,847,449,231,621,421,29,554,170,443,323,848,557,844,895,145,335,329,274,256,711,204,562,95,334,684,651,438,344,280,549,274,772,872,271,709,338,251,573,552,71,498,746,25,280,879,416,147,952,632,748,92,277,333,894,890,721,61,979,968,288,18,448,967,427,93,933,431,844,208,63,748,574,596,130,435,573,126,183,802,518,992,154,586,589,685,827,761,519,945,695,944,156,751,482,424,28,124,632,850,687,942,517,332,517,799,507,316,177,486,19,155,331,883,275,95,186,544,225,253,722,658,26,559,287,432,13,715,359,901,114,103,422,234,171,862,916,625,580,494,55,53,130,573,820,557,113,742,87,126,867,997,823,829,686,321,998,857,403,749,359,792,359,969,285,258,323,670,509,644,685,170,44,43,823,27,866,356,253,590,762,329,343,351,675,496,49,2,395,473,621,520,257,675,680,332,365,647,743,424,728,186,263,63,18,317,866,813,333,79,604,342,187,719,507,978,783,990,677,918,713,340,587,719,229,495,601,602,96,150,646,618,389,943,127,597,743,177,109,985,511,181,169,701,986,321,13,546,486,775,783,887,26,163,274,32,125,248,357,763,398,343,724,710,198,302,391,396,203,940,763,951,801,18,573,466,708,227,313,512,490,685,721,961,814,786,501,835,640,581,624,818,792,455,115,373,38,256,370,262,518,53,247,812,438,539,471,578,749,579,996,441,862,812,870,562,46,962,332,505,928,964,505,177,360,43,555,316,155,827,28,908,897,324,86,100,436,64,209,309,600,251,476,704,381,681,215,762,963,205,16,341,857,887,311,246,0,327,831,912,280,418,605,140,510,686,125,38,226,614,705,969,378,326,158,902,259,759,442,444,484,78,410,22,653,880,469,868,65,929,677,83,768,35,401,378,743,434,833,894,948,560,623,888,844,709,106,46,468,409,100,665,26,558,114,3,876,744,138,333,324,650,473,648,591,783,199,900,440,431,456,802,139,475,155,324,273,789,829,44,362,237,337,152,24,557,24,204,905,391,171,961,626,445,601,428,903,101,442,834,587,773,184,455,329,571,894,815,748,472,564,443,931,402,433,799,505,645,916,646,259,834,991,232,770,991,146,64,411,873,164,428,109,147,574,547,899,709,168,516,9,920,139,279,646,127,554,278,783,736,520,608,426,523,783,8,954,588,749,770,478,318,723,420,272,61,921,497,532,764,281,637,932,772,718,817,283,888,590,300,95,98,399,346,218,675,351,77,518,866,443,726,581,217,128,563,675,717,600,253,942,861,684,298,241,795,290,806,587,290,498,927,62,548,223,405,264,16,698,589,292,736,68,694,722,609,121,28,782,721,861,660,330,243,602,671,718,282,493,530,733,628,682,417,187,760,773,996,661,348,879,569,635,716,452,431,963,432,293,443,657,559,130,107,19,536,257,880,217,967,706,802,252,24,911,808,25,955,777,262,807,369,451,725,245,174,627,991,124,671,353,887,147,676,608,530,689,16,496,470,4,602,680,706,693,24,116,230,139,712,329,475,116,439,978,792,919,728,379,453,879,145,710,499,555", "257,806,899,23,586,119,736,248,608,70,798,145,62,153,53,509,354,513,738,766,663,38,351,714,472,689,347,258,374,371,29,415,22,261,990,772,105,318,861,82,573,317,983,345,224,346,349,595,262,790,505,653,560,88,60,543,145,651,89,541,803,86,417,947,106,129,299,794,866,566,104,40,67,634,52,418,365,174,343,737,634,929,723,3,545,744,682,103,400,342,861,52,472,856,376,261,298,115,782,718,831,202,205,531,552,776,666,722,246,200,459,805,209,937,406,728,632,521,886,984,683,742,475,290,896,925,841,927,701,847,927,478,28,831,19,359,693,451,279,987,831,69,598,319,576,923,813,900,754,271,857,899,791,428,862,929,603,294,74,565,824,484,6,792,987,810,935,796,622,762,583,671,532,668,274,334,477,822,724,595,438,11,5,6,925,757,43,8,451,977,357,834,176,692,699,934,869,426,603,180,709,137,167,226,733,499,670,610,691,371,89,730,387,828,823,575,284,746,52,642,985,70,321,118,30,849,175,683,392,545,63,951,498,130,144,398,829,674,421,839,857,278,566,2,161,455,809,124,583,949,180,551,228,520,836,699,896,78,949,207,924,746,772,412,191,113,723,98,338,297,63,516,140,304,518,299,360,279,123,371,496,613,585,48,96,896,667,971,349,231,272,707,558,492,716,300,73,892,81,657,94,948,494,89,939,238,794,771,433,633,924,27,494,371,802,621,169,417,173,507,126,197,371,31,490,185,881,868,581,404,602,242,316,31,491,161,499,321,768,236,739,803,994,915,237,229,715,827,793,230,803,51,659,309,200,262,561,638,59,844,112,304,386,845,238,432,405,231,468,341,398,283,765,644,750,214,708,226,833,801,829,709,254,484,741,528,2,401,782,153,635,441,434,842,159,673,93,772,157,612,566,3,623,668,986,581,887,253,167,151,354,724,386,953,402,445,778,407,808,334,499,190,759,68,859,89,102,948,405,588,951,405,78,786,58,915,617,900,852,723,931,709,903,771,479,12,960,429,473,88,179,755,460,546,46,565,24,538,173,774,15,212,946,987,39,255,813,653,333,701,13,94,805,539,935,930,345,463,319,679,352,884,909,413,286,381,845,232,36,634,384,677,898,331,195,201,969,343,593,589,159,182,842,346,754,707,867,29,40,878,121,308,336,739,783,177,450,751,364,129,337,342,666,305,412,682,270,344,88,636,508,186,762,387,552,145,54,730,583,215,511,562,485,246,685,689,192,371,600,311,288,150,459,459,309,998,421,126,344,2,693,740,585,960,788,592,839,240,52,484,728,873,141,533,221,512,130,440,315,986,93,732,464,207,497,206,595,599,745,120,136,349,473,368,821,911,327,456,285,815,842,609,252,548,735,677,350,356,802,834,554,113,217,347,288,936,299,157,961,770,397,123,952,809,969,334,143,250,635,195,586,16,686,847,164,774,478,817,68,486,694,329,698,920,711,475,361,307,803,877,602,525,301,117,575,133,981,233,39,924,398,886,132,255,549,597,933,973,91,992,430,327,0,256,439,969,344,339,851,315,372,219,575,898,360,512,824,103,829,936,946,599,795,980,691,216,974,403,738,666,448,570,562,631,271,768,291,601,746,323,424,93,517,930,946,851,121,640,965,661,830,535,132,752,593,353,696,295,435,612,137,766,875,220,795,529,416,28,836,889,200,417,101,111,347,173,388,296,342,151,828,653,766,883,734,915,628,572,799,169,722,926,190,136,184,563,56,26,255,694,873,122,878,332,147,586,362,648,766,913,379,400,376,104,291,232,413,230,184,212,850,901,56,543,317,728,341,686,136,858,23,575,729,272,809,514,461,382,470,554,216,877,98,883,280,993,571,932,744,841,461,496,870,931,794,102,390,259,807,64,13,931,636,181,338,157,622,926,229,395,368,154,179,281,218,701,489,216,692,438,720,551,174,557,230,881,319,991,59,504,795,37,9,902,818,96,400,611,217,475,787,302,683,598,992,312,405,837,580,813,778,566,937,247,127,155,539,3,507,445,787,128,999,440,453,6,718,64,312,20,830,940,633,633,520,938,83,736,398,473,918,765,126,779,559,964,745,967,286,723,432,962,615,798,400,538,297,781,582,653,290,255,94,18,666,560,994,574,933,976,311,658,241,51,364,145,639,561,114,316,401,942,283,754,347,191,283,689,541,853,38,11,675,395,530,765,951,260,100,783,847,192,413,839,585,879,140,69,679,822,870,260,454,912,572,716,991,116,997,712,24,338,155,134,818,891,522,976,350,667", "835,589,29,214,70,493,399,880,115,555,516,633,850,315,764,761,963,566,757,543,171,712,308,825,470,586,168,496,694,381,514,282,345,93,382,932,912,667,12,576,772,478,739,35,24,846,243,289,741,495,516,835,361,612,515,97,680,300,386,360,96,669,291,486,803,436,963,165,672,409,781,974,974,163,552,579,66,35,7,684,309,906,304,974,626,247,929,351,714,208,511,528,472,856,539,525,273,891,988,339,558,990,441,774,96,321,441,893,801,68,894,730,623,764,216,20,816,91,384,198,40,691,640,997,671,945,980,404,829,386,724,997,584,362,173,774,935,822,110,739,50,97,849,680,152,738,414,615,811,435,965,788,532,238,673,490,536,68,843,115,991,672,187,458,573,603,535,116,913,580,230,696,752,57,523,317,427,347,378,796,762,55,428,70,477,672,432,7,233,453,999,351,809,803,903,257,643,568,447,277,339,719,945,480,527,591,840,370,619,903,52,221,798,382,260,720,777,459,419,614,880,826,715,636,842,135,858,891,400,912,533,756,579,717,505,817,288,729,787,290,42,698,830,81,899,4,363,333,751,254,539,137,991,722,897,330,530,295,784,48,47,500,291,945,912,360,788,974,43,721,271,909,966,783,847,937,104,889,943,817,539,150,943,469,554,521,877,935,71,369,933,730,55,575,611,147,742,400,790,879,756,430,441,375,894,58,958,992,881,695,862,421,354,321,830,450,950,306,762,521,491,593,840,679,433,423,478,701,868,569,557,2,197,383,181,878,558,766,85,852,192,415,67,76,755,348,109,871,136,387,979,138,657,400,180,474,929,251,442,778,559,991,935,360,606,289,341,887,846,590,673,181,70,962,748,348,725,687,572,243,347,399,96,806,644,241,284,619,527,988,752,975,777,61,553,491,467,780,919,433,949,70,951,841,63,255,891,553,159,338,215,308,677,170,282,644,901,456,399,421,153,682,779,315,420,347,946,363,85,70,525,363,726,557,739,148,822,446,488,316,411,248,629,558,409,67,894,696,629,377,299,840,694,61,473,78,222,696,442,215,124,681,13,50,617,891,254,10,373,830,763,877,613,626,595,428,624,84,100,642,909,34,347,278,544,666,274,166,807,957,518,429,550,153,50,537,633,306,910,508,613,460,685,948,38,335,747,668,656,596,520,489,470,707,988,312,756,487,733,679,175,102,52,866,923,379,654,92,265,870,336,92,555,345,698,119,248,346,767,943,28,375,36,643,663,610,665,929,92,223,142,606,766,919,38,694,468,52,419,51,738,547,453,940,890,95,375,699,965,58,720,138,95,161,613,232,571,114,59,129,477,691,319,490,774,983,929,418,912,761,220,98,342,559,344,91,613,556,560,857,671,346,526,160,626,180,22,783,785,234,70,80,501,795,5,751,242,965,405,834,271,372,348,441,833,172,685,269,552,942,59,230,27,25,264,86,405,595,392,99,801,612,118,205,135,599,902,275,72,669,990,971,908,677,550,162,502,62,320,497,746,704,849,270,275,323,514,888,137,377,989,831,256,0,583,194,627,199,452,10,780,664,353,660,314,507,29,971,96,743,13,991,577,441,399,951,505,643,357,434,885,336,734,433,21,310,500,784,618,714,419,612,398,841,720,853,255,426,229,189,735,329,270,48,453,71,82,471,485,23,68,613,811,536,635,656,291,619,201,668,772,465,808,429,542,318,71,727,209,636,607,580,345,237,661,156,691,124,666,140,479,769,785,77,672,350,710,478,498,774,256,472,440,727,229,633,814,280,515,429,289,278,435,349,851,614,655,143,479,766,325,474,614,951,207,20,989,352,172,242,436,55,248,799,50,46,624,245,383,346,627,382,377,515,580,181,115,599,74,338,912,560,920,544,974,911,618,927,132,584,992,868,186,853,476,291,581,904,147,203,123,829,643,983,33,552,474,253,504,577,453,103,472,990,312,961,79,498,566,249,177,790,429,622,674,465,169,153,679,843,990,726,232,289,749,158,638,529,854,116,889,166,181,584,558,538,787,717,711,963,114,968,983,347,29,299,926,152,167,65,888,527,12,401,113,519,981,603,3,374,533,40,554,178,657,762,2,407,112,175,829,173,130,215,95,459,73,732,798,900,868,328,419,409,253,228,56,929,867,573,110,747,479,861,784,302,207,110,723,525,500,968,824,357,691,187,609,320,441,178,502,937,437,546,508,792,806,236,902,956,851,739,501,600,791,456,860,677,530,29,750,77,257,385,963,675,266,903,691,112,691,38,315,302,390,464,132,204,793,343", "516,155,442,709,704,957,458,878,242,305,465,261,262,454,828,278,915,770,903,61,576,21,22,471,730,705,876,856,352,300,883,501,828,538,293,339,88,269,589,959,335,519,990,174,693,184,783,654,797,918,450,2,33,299,930,413,476,924,929,701,635,151,432,201,969,536,778,216,34,182,695,252,272,507,419,857,64,385,32,360,310,973,644,206,815,483,731,387,694,251,796,282,207,498,781,121,182,640,900,439,429,961,851,122,251,122,342,679,569,496,80,984,440,269,335,308,465,4,430,392,699,785,999,833,324,75,329,873,63,12,960,856,743,562,823,33,462,198,834,73,83,312,832,964,676,718,906,613,991,453,762,549,451,299,556,637,625,467,577,21,17,383,942,772,827,823,712,787,942,796,781,109,92,571,662,371,868,282,715,183,132,4,404,80,354,699,994,307,737,709,183,613,46,731,235,312,995,813,232,34,179,676,297,67,388,859,49,55,506,576,830,265,40,190,43,834,264,18,744,246,669,988,617,265,790,586,343,737,949,737,342,253,665,761,715,664,258,159,944,991,2,867,491,998,450,37,640,852,524,499,59,954,198,927,272,153,886,22,691,201,788,926,25,709,264,198,82,503,287,187,61,307,781,868,282,126,204,983,333,565,323,909,665,935,550,90,285,359,591,200,458,796,769,99,561,9,114,915,548,840,785,88,204,334,645,459,531,712,729,505,517,519,540,297,975,344,230,961,456,327,933,470,565,481,944,933,201,898,266,407,825,871,97,354,643,168,349,146,713,210,132,560,529,614,50,735,835,183,296,632,438,107,961,175,840,251,319,127,767,36,829,66,99,574,856,13,307,552,613,550,493,863,944,377,98,806,753,459,656,569,860,124,213,942,543,989,709,195,586,925,978,651,431,810,540,558,540,893,71,511,422,509,256,615,113,674,927,960,149,543,165,144,583,836,614,539,807,613,272,456,952,351,643,669,307,345,657,165,339,427,836,673,959,733,844,617,509,371,490,450,955,68,97,366,765,564,626,229,443,773,413,924,438,584,515,51,881,644,606,872,232,329,986,996,688,993,326,152,570,157,147,215,737,273,334,681,999,724,549,368,516,960,585,957,404,27,885,617,811,511,403,722,256,389,794,962,475,524,164,796,896,15,404,278,921,143,169,733,843,865,910,856,831,479,672,440,453,249,368,701,707,466,654,361,92,908,778,492,494,48,161,289,148,953,388,498,440,987,870,581,143,345,346,191,972,588,844,532,997,487,161,216,472,926,678,472,164,692,325,395,395,878,415,463,652,934,489,150,104,368,338,982,657,731,520,408,183,693,175,174,133,81,418,298,523,770,62,536,18,752,643,141,971,762,170,586,870,156,79,999,543,984,452,743,210,777,399,162,365,212,53,456,257,7,863,754,180,193,401,299,661,894,868,253,322,386,342,36,754,502,129,291,608,859,234,523,547,378,961,741,225,34,119,530,791,955,266,938,271,902,922,644,420,589,386,617,933,857,142,532,71,257,959,743,938,704,779,997,577,575,897,912,439,583,0,928,993,327,530,432,605,823,25,749,716,782,640,85,710,94,447,67,719,734,634,10,715,394,913,746,714,391,259,607,253,449,929,350,95,9,926,329,150,616,336,65,175,823,990,231,962,1000,136,312,313,157,508,789,315,356,447,8,509,724,926,767,357,640,534,408,234,276,132,572,812,216,28,998,437,234,983,121,292,266,624,934,201,208,227,400,66,647,792,996,421,74,154,91,9,835,136,58,833,460,518,63,63,975,657,720,863,504,579,405,784,269,574,359,930,667,589,61,884,342,768,245,818,973,268,398,74,558,557,892,176,438,567,177,164,526,91,514,833,983,584,91,408,801,508,268,356,567,453,99,160,538,367,726,468,715,615,431,35,887,780,247,623,272,725,90,41,546,18,608,547,316,778,807,399,832,90,4,832,967,876,596,465,521,377,695,81,694,319,816,484,418,647,508,764,758,905,948,269,316,989,740,546,504,184,68,264,718,867,24,694,775,284,547,575,437,179,142,870,963,897,761,571,973,861,392,975,94,68,521,312,232,478,738,879,153,665,927,369,454,202,893,264,165,452,171,781,97,164,982,239,258,166,165,993,31,861,301,607,208,438,774,906,294,396,464,396,582,312,637,57,728,623,958,811,123,40,322,463,608,211,858,230,414,117,617,195,701,810,310,620,882,499,500,804,844,828,443,126,160,229,61,233,221,46,302,134,489,83,180,70,383,900,571,256,656,584,874,723,448,71,820,739,353,468,327", "172,935,830,875,459,388,984,492,783,595,159,825,788,770,902,940,880,64,58,622,825,443,706,477,368,317,362,143,559,351,476,526,577,48,144,822,854,513,750,588,15,829,520,912,83,432,862,576,826,831,214,908,48,54,206,445,196,772,295,239,111,181,102,653,401,405,244,445,564,8,739,420,237,683,739,37,71,521,909,495,177,759,512,267,720,881,479,494,649,548,539,563,256,243,804,710,90,933,212,142,38,815,270,988,49,131,289,337,815,866,538,691,826,326,624,442,550,970,333,806,153,629,201,448,111,16,163,4,901,186,281,479,741,756,995,19,861,204,803,592,17,196,487,885,378,831,986,945,655,969,590,450,840,661,486,242,338,655,734,155,897,334,640,107,233,766,182,558,355,194,209,559,375,653,433,606,337,853,874,786,818,978,910,951,180,229,91,604,520,966,948,209,214,568,75,109,974,771,43,281,268,314,102,457,669,704,914,448,236,206,504,342,563,658,395,304,499,372,473,656,179,791,821,723,690,630,442,691,722,472,924,537,359,716,343,855,487,951,308,529,834,630,336,889,696,407,1000,869,119,341,925,300,787,497,911,971,998,964,848,391,400,103,860,560,850,53,99,648,354,468,542,657,846,486,665,682,401,68,104,462,716,591,821,782,495,688,290,948,997,10,320,973,500,616,52,931,196,755,57,306,910,845,349,882,216,731,495,760,211,388,493,27,565,647,787,431,379,886,576,622,310,736,971,22,154,601,366,83,659,236,797,652,771,115,435,597,833,161,34,53,847,802,778,540,915,824,89,586,678,478,652,498,638,44,950,373,128,486,473,140,967,124,173,789,893,920,148,158,910,537,126,805,564,114,363,64,712,510,535,814,752,69,874,753,709,824,998,231,197,322,605,551,444,882,213,635,442,217,916,879,896,361,901,645,287,185,46,916,285,465,600,39,948,172,811,47,472,201,395,60,856,348,700,241,853,150,192,557,71,156,719,817,969,7,989,32,437,812,313,252,416,404,370,815,877,349,132,967,472,800,159,1,4,800,432,372,409,913,199,53,908,823,156,701,564,797,22,88,347,189,892,537,14,852,92,291,22,559,394,332,898,266,598,164,368,490,656,225,549,94,652,616,878,634,725,4,384,556,906,811,215,28,219,388,474,261,840,112,430,561,45,826,681,880,433,725,92,634,379,191,534,18,431,557,516,185,549,38,554,158,987,555,897,671,902,728,201,702,545,625,803,935,546,304,857,243,638,506,339,677,660,995,643,182,398,193,433,65,294,650,587,251,352,583,227,709,628,769,974,814,264,453,631,280,617,149,957,763,299,630,84,715,598,48,108,519,217,752,587,249,151,900,679,436,976,405,252,351,959,446,459,413,465,743,346,400,439,922,952,829,220,616,537,276,959,894,373,772,922,991,844,362,624,406,879,243,436,980,441,374,594,79,397,260,241,509,270,13,343,203,198,151,186,872,741,304,570,174,18,130,446,255,334,485,979,362,699,541,403,811,737,95,597,799,108,898,911,193,76,244,512,280,969,194,928,0,961,944,494,94,469,721,644,896,841,923,647,553,708,957,752,895,302,787,572,856,281,980,982,951,894,853,300,77,592,815,468,751,82,120,927,744,806,482,784,618,893,864,384,803,330,991,211,964,77,537,160,300,75,515,234,114,7,784,243,875,596,341,392,909,53,589,156,95,72,354,487,457,154,330,197,384,292,227,498,510,963,235,41,521,544,542,444,324,994,879,177,621,766,177,820,8,664,295,712,701,935,257,142,952,559,891,488,590,69,407,597,126,553,978,898,415,100,820,382,700,558,119,406,734,422,239,280,79,439,342,572,182,80,306,954,920,607,729,481,317,141,717,517,150,627,973,192,469,545,722,514,712,924,78,665,593,823,385,258,67,372,940,352,282,425,66,807,713,601,966,261,477,358,765,869,770,26,996,304,552,935,231,314,156,705,547,405,544,316,860,884,895,15,469,868,382,55,532,746,963,741,342,686,822,165,82,860,279,33,716,110,866,731,707,933,582,558,757,633,981,371,286,772,198,280,872,140,312,988,150,593,603,459,862,302,111,246,593,961,423,175,857,794,840,724,4,416,851,955,210,286,212,448,350,348,781,875,435,885,134,444,585,906,766,858,888,257,364,56,212,264,687,754,519,357,603,233,901,571,6,634,915,789,454,217,110,391,162,955,952,426,301,160,769,290,897,440,763,713,709,135,482,78,945,462,316,350,347,23,568,275,201,718,273,431,183,270,505,394,324,804,821,77,253", "594,197,374,129,831,574,689,914,664,628,259,625,364,441,88,591,802,314,86,366,111,872,327,304,195,729,751,625,9,510,391,907,731,304,243,865,256,742,524,325,790,887,55,517,555,276,360,788,525,615,125,791,907,223,878,421,672,120,713,749,549,746,726,305,982,94,565,674,275,877,697,264,172,377,549,914,198,597,717,707,58,448,264,518,519,477,213,823,343,401,117,62,673,444,669,766,279,702,429,629,572,798,263,395,72,705,709,629,490,665,77,699,541,366,917,647,378,452,124,329,483,370,492,823,557,653,986,905,856,646,280,827,708,784,484,224,338,527,185,530,900,110,499,414,376,830,538,665,323,338,381,732,329,616,82,124,634,120,723,60,576,324,106,34,559,522,927,886,348,388,222,506,226,566,686,830,406,625,612,145,57,638,36,181,295,117,28,347,586,450,971,303,901,871,100,340,829,34,72,209,525,184,463,994,105,364,963,558,804,95,403,512,622,164,2,630,630,254,403,543,542,626,889,220,847,637,700,526,866,963,285,155,288,8,924,29,894,586,345,624,998,81,10,489,496,215,216,101,779,455,197,24,607,869,856,895,129,709,975,708,431,538,613,332,305,730,61,868,632,386,988,273,751,682,586,977,440,811,532,685,547,759,552,12,722,84,952,890,115,150,222,99,431,22,361,975,616,503,790,920,386,136,681,326,936,732,354,583,61,606,158,817,197,880,76,477,815,229,732,367,261,272,714,278,62,135,309,844,939,270,92,667,952,615,931,806,675,669,696,284,313,613,641,154,297,665,362,156,658,424,951,20,441,986,648,114,709,564,416,610,168,805,573,979,738,531,740,552,369,287,301,978,891,108,202,719,453,193,556,445,190,137,708,354,138,288,677,750,146,471,755,491,63,235,698,349,952,476,675,321,988,196,989,71,839,319,121,940,838,955,296,9,745,272,670,518,756,271,599,45,478,907,124,101,695,527,106,601,137,121,720,721,215,815,571,333,880,686,68,961,49,894,624,602,851,620,582,788,532,38,374,467,719,13,532,849,412,340,387,419,285,179,116,479,449,776,328,487,847,684,182,138,456,307,532,894,926,853,96,786,677,785,453,313,876,363,229,372,203,689,901,886,821,102,93,342,46,227,812,810,114,235,432,944,948,927,712,976,631,529,727,742,221,889,650,713,464,930,319,792,958,96,569,975,145,800,899,603,858,453,994,293,854,542,375,663,532,688,441,983,202,985,627,595,286,15,6,302,724,514,367,342,562,554,478,128,361,617,414,572,4,477,476,750,155,712,580,259,69,406,176,334,364,542,406,87,485,491,721,430,4,885,848,172,862,263,311,142,60,484,827,971,19,29,730,352,924,253,543,112,139,635,606,532,971,911,775,805,156,186,539,166,112,984,684,906,337,964,790,795,697,357,168,184,626,137,159,872,727,648,233,37,564,95,276,473,161,953,876,711,497,345,823,764,60,666,438,704,914,37,621,451,989,986,857,66,985,412,385,962,775,918,915,232,131,300,761,214,866,441,380,418,344,627,993,961,0,636,315,563,979,592,620,68,79,309,469,22,70,723,656,517,182,312,116,391,291,249,144,549,973,391,595,405,230,71,935,193,856,910,731,490,955,426,67,620,187,764,881,974,944,697,805,723,394,640,733,263,853,662,172,931,16,583,92,377,343,119,607,987,693,302,86,392,127,31,397,551,25,913,696,80,546,685,885,198,437,850,604,82,266,27,588,655,223,305,498,640,314,347,822,285,520,387,875,69,702,278,345,169,749,383,49,530,582,431,423,209,3,889,668,157,34,794,792,773,801,419,195,913,215,603,405,113,218,600,57,689,500,631,124,435,411,160,176,844,674,73,294,366,572,103,188,783,169,847,193,920,360,577,193,434,678,623,961,454,568,297,299,846,275,856,954,152,75,693,207,647,852,841,912,664,567,388,692,3,832,449,709,178,233,202,310,908,596,642,367,480,827,575,895,993,465,924,436,450,426,360,420,795,420,529,696,820,278,364,662,620,924,521,704,980,209,279,819,238,155,815,722,500,902,898,521,913,460,63,225,983,647,868,614,935,77,967,309,655,206,85,65,742,225,24,230,816,6,252,171,515,881,62,637,657,486,523,100,767,135,224,287,9,13,79,570,645,959,578,832,136,112,180,739,820,997,324,315,997,902,435,130,748,746,200,843,41,459,142,186,520,66,521,499,105,444,784,570,946,696,714,817,292,890,277,831,268,248,225,302,358,489,605,391,541,182,445,816,830,359,960,272,705", "661,623,754,491,492,422,85,889,917,115,551,821,290,791,631,482,672,836,591,820,908,988,49,448,679,656,831,414,246,902,233,466,164,6,411,206,46,963,234,740,597,441,543,298,878,921,453,539,863,380,184,619,165,532,729,344,399,433,473,170,481,888,937,445,773,479,523,600,922,782,849,885,66,900,687,584,412,970,118,992,854,161,854,838,463,552,642,508,228,107,793,377,876,463,166,210,191,286,884,964,217,407,313,369,250,164,283,379,601,100,150,230,952,114,278,748,814,154,569,547,446,39,743,643,341,622,101,965,244,183,834,441,678,445,319,450,36,986,226,702,496,549,852,871,13,166,498,97,184,228,551,801,860,823,666,78,562,42,333,960,150,763,950,241,290,110,170,160,687,278,614,554,103,249,314,84,557,543,963,190,397,317,806,390,197,702,606,720,820,378,85,535,414,482,778,173,803,404,607,950,395,127,969,865,467,413,12,891,790,73,670,868,471,886,884,251,137,88,638,438,335,319,233,33,118,717,757,997,329,461,822,121,63,25,807,110,251,583,326,127,36,735,236,82,558,153,366,706,119,443,737,54,949,696,214,201,818,249,17,244,721,714,118,383,266,636,674,754,366,187,298,141,849,608,344,355,444,824,93,866,302,676,353,494,858,674,51,811,850,716,733,598,505,48,645,727,492,25,56,920,585,701,333,243,364,790,233,758,83,147,196,582,244,989,950,662,728,433,245,208,282,990,241,175,915,45,395,176,157,682,517,973,900,446,204,897,557,992,724,611,403,483,629,258,763,523,299,800,987,892,613,495,396,826,287,917,304,443,372,457,730,677,178,161,715,936,487,381,489,914,584,403,260,326,755,944,172,149,118,645,595,169,14,304,513,784,470,814,138,152,162,315,585,747,594,749,167,159,142,371,55,914,140,926,846,214,407,893,982,640,857,994,453,741,710,663,342,855,149,396,885,135,625,61,936,245,492,239,456,246,111,957,366,852,938,722,591,908,341,341,470,330,317,9,558,945,87,278,171,471,132,54,637,318,536,209,111,979,995,438,667,270,944,875,515,652,297,446,208,441,338,97,960,360,174,810,174,379,190,662,831,806,312,98,595,461,721,844,591,379,675,82,619,201,464,246,71,885,385,289,264,484,106,240,347,176,827,35,423,802,286,300,291,531,147,870,114,471,939,706,970,993,931,896,666,43,897,727,387,562,519,941,421,993,320,843,486,883,81,687,530,337,528,397,595,819,4,467,775,108,761,816,394,502,195,206,625,232,374,277,291,90,503,204,111,730,280,205,210,752,439,600,306,118,333,80,94,408,521,622,313,947,562,3,686,588,154,571,897,913,342,519,164,466,391,150,188,873,758,161,816,58,169,317,585,383,730,140,10,537,198,691,551,651,185,43,236,585,543,72,70,241,872,957,291,846,173,921,850,541,19,775,448,827,983,989,818,544,33,229,84,141,173,473,970,70,713,826,868,245,349,640,964,984,379,147,589,683,58,556,439,200,926,950,11,91,693,760,32,7,976,605,339,199,327,944,636,0,158,113,573,413,295,163,494,656,488,626,329,145,530,221,392,224,687,110,259,508,901,595,821,282,267,313,852,328,498,110,482,949,276,724,739,656,260,494,39,857,455,912,528,569,272,762,578,583,934,19,148,697,645,75,151,193,328,846,258,6,71,126,485,272,512,231,940,688,533,615,58,907,592,10,888,261,694,794,523,31,623,427,432,674,952,563,863,485,595,913,826,936,808,458,419,755,327,172,124,882,662,598,943,223,843,126,496,571,232,572,663,972,805,314,324,272,272,230,121,661,996,257,3,931,295,684,582,303,436,214,197,991,349,843,71,250,982,663,575,472,524,338,344,483,370,377,589,166,433,764,587,145,911,78,544,736,352,347,798,730,745,208,511,663,759,515,955,904,712,642,928,743,343,935,135,307,302,989,674,789,979,114,531,515,58,818,321,195,434,962,469,924,945,4,790,923,733,92,999,214,304,312,637,202,556,57,742,121,620,684,924,624,491,457,42,264,597,856,51,732,559,379,48,639,182,584,90,837,35,849,157,259,771,376,246,380,186,975,158,877,984,945,728,295,804,233,291,747,895,823,63,675,505,923,96,254,298,672,60,563,835,942,829,698,538,374,730,861,816,468,264,430,16,193,872,291,504,528,637,403,78,460,462,313,218,516,816,955,674,130,995,566,351,989,177,333,258,296,55,498,518,579,432,638,311,585,883,799,337,960,85,2,910,961,678,828,915,332,90,181,363,242", "77,546,622,668,220,513,738,901,134,522,656,166,783,347,525,571,879,24,709,265,587,14,787,276,15,611,296,749,780,829,329,108,602,929,840,633,336,729,670,986,935,670,829,996,303,908,996,785,431,428,607,904,868,84,11,626,989,985,640,74,108,293,646,461,848,513,693,354,829,940,49,852,691,687,134,651,820,925,553,644,202,796,633,844,514,548,618,408,210,147,576,400,60,84,522,280,556,889,24,512,99,489,749,895,266,337,760,671,136,382,664,119,549,246,996,323,485,548,441,299,378,100,830,321,651,791,509,945,831,190,644,370,323,242,201,960,455,822,859,52,678,880,759,535,653,779,628,62,637,16,65,463,394,405,151,554,113,351,96,697,839,429,480,278,197,107,947,321,501,54,76,180,748,146,955,218,453,672,40,836,488,224,321,999,668,503,550,105,150,422,692,465,868,512,336,500,613,469,35,78,40,867,163,549,959,356,745,138,807,647,829,377,869,544,756,748,498,306,209,689,919,649,216,820,259,866,782,720,760,121,527,716,181,396,160,652,663,737,183,354,466,127,430,772,874,854,441,885,650,523,345,882,759,337,512,389,572,719,101,275,424,675,969,84,229,138,685,762,70,299,736,774,817,535,306,959,297,753,941,596,84,53,206,448,137,245,212,770,826,11,461,592,14,716,524,944,741,465,7,549,614,664,805,786,398,952,412,463,971,537,680,544,959,196,471,724,871,994,558,475,980,378,894,46,437,483,394,545,58,970,5,871,223,323,587,99,244,322,290,666,897,538,815,723,588,941,724,588,519,943,563,535,626,149,508,327,804,192,820,481,25,715,737,273,670,599,589,143,570,257,121,497,235,265,388,499,988,57,571,110,978,296,467,95,967,100,430,124,531,920,148,802,242,995,13,163,24,117,954,925,568,279,648,76,992,147,214,250,915,541,506,882,495,896,7,860,718,189,300,423,766,762,804,687,109,929,272,966,476,253,39,677,799,392,870,138,266,180,56,454,84,664,899,345,200,230,515,215,648,649,853,791,637,526,730,572,974,148,907,849,475,18,881,182,740,642,538,525,855,113,751,994,2,11,81,677,754,31,249,658,117,843,370,961,775,770,346,712,802,758,869,538,372,314,710,926,92,252,363,205,772,106,918,431,580,192,408,294,13,723,557,705,810,816,456,634,710,651,16,114,454,35,452,88,242,368,381,373,450,353,851,982,857,935,732,502,888,687,882,155,220,212,259,106,705,442,27,159,415,630,71,572,480,844,53,59,866,64,979,451,969,44,999,346,702,822,949,262,44,711,61,944,312,393,226,836,463,764,596,660,862,59,24,951,363,430,691,327,392,818,752,912,835,18,637,670,119,519,181,228,906,389,732,216,106,62,330,274,631,853,180,973,543,971,707,576,455,953,568,932,135,660,492,287,654,769,41,360,431,528,882,268,875,316,1000,302,944,349,968,808,999,418,665,7,225,196,224,599,438,938,850,326,31,340,240,296,254,69,865,494,864,691,994,514,621,504,485,935,442,725,550,140,851,452,530,494,315,158,0,888,754,461,74,812,60,643,102,584,59,567,148,290,14,604,926,204,219,799,585,180,166,242,695,757,206,530,344,317,292,853,221,744,80,908,855,921,295,526,474,388,784,349,18,807,49,836,868,144,122,312,237,54,789,534,408,626,282,586,648,144,354,168,547,27,801,213,480,206,191,359,482,891,615,319,498,561,747,914,688,977,716,301,401,538,68,650,429,384,427,791,993,204,281,40,855,217,615,274,666,295,797,21,738,811,951,553,278,698,318,42,972,475,999,157,559,558,776,776,723,947,921,836,619,166,754,421,235,959,119,318,500,685,627,484,571,369,58,273,480,260,534,84,478,881,526,814,726,757,410,504,913,737,239,799,327,224,197,342,117,451,562,485,768,477,684,830,903,763,466,766,424,974,882,451,147,280,453,839,835,520,449,261,367,326,27,700,603,515,28,615,802,480,30,146,537,564,272,678,111,641,984,335,67,234,286,426,409,900,58,283,844,298,38,500,396,861,16,998,429,90,542,56,924,560,20,984,955,530,611,583,441,198,12,882,531,270,430,42,532,266,619,995,388,674,486,702,733,150,61,572,536,433,340,680,979,743,134,897,575,902,252,703,237,117,758,442,181,963,466,346,104,584,765,600,143,575,334,580,529,270,427,610,683,214,456,718,564,737,297,832,620,741,10,399,106,94,211,73,624,827,685,844,189,482,499,13,26,724,646,739,914,988,759,881,993,712,531,114,110,209", "28,492,73,139,308,339,357,657,698,184,849,802,528,6,376,362,84,242,281,821,49,702,560,291,295,845,73,504,33,183,597,897,632,462,953,828,826,852,541,516,894,212,418,370,475,553,844,916,75,353,526,906,290,628,498,353,425,842,220,327,865,969,602,887,768,753,652,120,54,87,931,868,624,388,268,178,449,93,989,396,672,694,244,308,259,26,87,590,298,582,926,85,973,798,604,748,558,247,844,25,52,646,70,21,115,801,522,634,345,400,402,731,807,180,270,918,585,972,669,158,370,413,328,290,596,723,167,401,65,888,24,322,480,722,943,94,151,920,919,291,656,804,366,979,166,351,400,404,401,467,213,737,9,752,571,989,216,810,810,951,72,278,671,37,404,544,528,325,139,198,365,189,496,536,756,565,407,125,577,244,135,555,827,401,788,599,806,641,614,165,621,843,272,724,525,420,391,524,284,498,311,823,508,234,173,764,99,63,841,335,771,48,192,610,925,623,880,392,500,598,423,530,386,61,452,216,306,420,368,732,56,22,559,675,314,395,950,880,340,123,409,812,671,39,889,761,280,509,570,3,816,188,406,957,294,93,19,569,2,722,869,919,120,888,698,613,530,154,692,799,952,78,193,797,726,829,101,108,263,46,37,346,768,45,286,951,654,531,604,722,895,666,608,327,318,687,882,627,266,722,77,389,296,950,582,444,879,841,376,769,127,511,409,298,610,980,734,88,685,722,439,106,301,278,735,368,21,475,17,798,437,860,947,780,144,704,350,456,956,979,672,967,645,541,954,246,34,48,48,708,772,925,453,146,218,709,462,542,901,138,465,178,488,854,356,945,965,154,803,160,710,898,746,935,692,478,472,206,337,577,339,999,94,926,372,34,866,914,821,333,938,305,696,118,45,897,518,655,798,290,901,795,600,377,10,157,634,45,608,24,531,504,119,342,68,997,173,494,303,381,195,769,89,546,962,816,623,49,585,357,619,442,102,153,162,924,269,991,775,210,730,782,491,847,534,889,628,74,294,782,711,509,476,6,190,503,43,709,996,179,676,753,897,77,360,783,656,739,785,718,782,926,278,383,53,534,791,344,102,749,111,707,873,56,144,922,458,955,439,96,520,155,263,12,129,306,934,593,447,955,934,996,354,130,262,761,748,264,256,957,226,82,152,66,974,273,879,180,674,939,932,729,809,964,659,238,576,92,407,609,202,218,212,503,546,887,85,344,551,958,301,366,525,26,66,209,626,129,91,34,13,487,356,698,448,376,227,236,437,149,779,423,811,627,651,64,437,755,560,677,253,990,87,373,268,266,422,93,332,103,442,565,110,632,857,504,961,183,458,576,535,927,900,296,50,107,267,802,385,640,214,688,52,717,626,315,966,669,527,264,955,291,267,279,302,365,645,864,641,532,410,38,415,650,422,793,300,768,78,679,281,713,303,42,707,566,160,332,505,916,48,249,870,804,223,92,968,547,36,536,985,872,606,902,448,152,343,451,507,526,547,176,337,636,828,908,832,734,827,481,851,510,315,10,432,94,563,113,888,0,651,516,620,496,544,472,620,596,190,574,123,60,656,384,932,405,174,280,12,716,802,505,988,845,745,649,538,458,230,406,438,826,327,206,147,619,783,635,582,603,650,326,43,398,586,385,853,67,417,680,389,384,222,840,133,783,404,753,438,324,328,384,193,584,171,21,969,961,39,103,56,221,280,890,212,493,646,759,558,728,358,111,542,688,412,609,543,142,773,620,548,282,525,776,201,327,61,211,294,837,30,771,409,463,714,95,955,982,33,379,37,794,447,159,100,30,91,945,60,121,497,401,304,208,766,262,684,142,495,595,819,387,894,795,888,469,742,958,721,554,767,166,978,218,646,598,724,756,699,501,592,855,596,396,716,786,656,78,726,883,938,688,150,18,598,51,531,782,45,168,25,767,396,555,949,808,72,251,862,811,718,236,420,959,700,924,423,311,329,117,116,195,273,630,793,36,517,347,798,826,900,347,937,246,630,548,180,445,281,501,530,357,937,132,9,344,805,975,376,870,239,636,702,143,34,935,724,845,677,156,800,307,170,184,277,216,42,389,944,223,152,147,211,214,435,701,198,293,432,212,377,177,731,848,157,193,193,973,114,415,771,28,744,570,595,781,99,220,498,466,97,979,534,870,687,617,474,819,818,95,316,327,713,571,694,961,437,896,183,651,625,867,135,209,674,532,827,346,331,848,432,952,552,17,666,502,233,958,558,348,645,58,635,458,11,675,791,478,259,343", "961,794,622,276,770,453,148,257,672,166,903,766,473,958,504,908,342,552,454,566,696,745,494,32,95,454,994,320,119,374,3,731,597,462,176,895,320,169,136,381,592,24,323,740,827,781,882,287,441,467,945,447,483,469,253,853,824,410,670,171,649,983,847,630,865,302,395,251,976,949,901,807,315,123,334,906,589,159,7,553,425,416,304,739,198,812,879,531,366,901,74,776,683,704,619,192,935,422,595,887,848,601,837,505,819,358,789,621,683,305,671,144,896,911,745,852,250,314,641,728,779,816,134,906,693,949,94,336,761,784,417,125,948,218,860,147,279,228,402,880,528,300,200,254,139,906,414,454,349,831,958,326,537,822,744,607,175,716,275,600,938,878,370,354,25,837,48,464,318,491,719,494,560,251,919,886,361,213,690,594,112,443,362,522,988,527,760,853,759,630,414,210,773,761,490,481,941,408,993,841,621,293,132,167,365,985,444,352,159,386,97,950,870,365,743,563,972,394,768,671,775,501,436,190,928,603,681,417,559,226,253,891,72,526,488,1,801,323,213,808,210,183,820,356,799,79,384,350,871,222,241,518,662,528,264,838,627,689,756,616,935,417,95,696,384,292,684,715,56,249,730,552,970,280,47,106,878,740,304,974,369,134,868,134,242,679,56,948,224,751,754,779,459,767,929,576,941,194,207,629,704,42,184,494,729,101,267,258,622,246,883,122,119,419,355,299,852,908,108,613,87,145,220,619,678,742,65,800,312,776,38,461,712,455,283,739,335,739,578,847,792,698,193,343,381,206,661,126,713,946,9,283,784,723,684,505,35,837,551,785,838,904,33,773,423,58,28,646,880,798,937,467,142,126,412,49,100,573,782,674,557,645,953,647,437,624,814,566,689,782,831,794,379,838,971,797,981,40,735,140,536,682,392,558,217,526,50,691,518,599,928,718,443,720,23,171,222,964,840,620,464,650,113,220,939,289,618,616,262,763,173,638,259,188,862,707,669,726,738,119,297,349,900,321,692,529,590,8,786,847,635,555,493,410,932,126,39,961,534,668,804,639,273,677,175,329,352,181,716,671,913,156,347,62,518,267,341,692,363,567,578,249,366,296,673,299,221,228,52,161,816,31,781,569,424,410,498,479,10,756,14,454,493,745,341,100,472,445,362,976,919,12,497,739,288,610,7,763,364,404,942,209,998,722,877,576,954,877,84,100,426,983,75,883,627,972,116,393,461,132,701,597,567,770,954,565,917,758,392,994,378,629,520,736,941,184,588,112,27,166,838,859,701,989,302,904,733,281,98,29,931,802,59,120,132,461,759,806,439,871,957,810,779,893,972,361,759,185,123,92,759,804,623,352,870,509,261,711,132,340,503,216,584,495,44,368,273,947,714,925,56,164,857,394,593,791,456,476,22,372,548,827,518,475,278,851,123,929,468,228,642,17,420,11,882,119,678,488,448,51,24,29,831,793,220,436,954,735,823,261,918,371,119,676,726,288,974,18,45,401,833,530,236,565,243,249,104,815,569,383,513,686,372,780,605,469,979,573,754,651,0,741,166,399,176,827,875,268,714,261,484,983,984,165,243,574,246,900,831,957,815,271,538,953,664,937,608,230,679,914,341,440,161,244,800,859,864,462,969,307,957,124,243,10,854,317,678,341,12,517,990,567,251,739,255,79,959,880,393,439,109,9,812,464,580,805,528,893,458,594,160,559,444,578,718,44,457,515,364,917,273,197,410,751,808,643,585,178,905,90,995,11,449,593,101,476,834,338,440,617,140,972,422,309,241,356,114,815,600,766,929,367,710,299,690,825,150,510,918,605,350,825,530,590,646,711,122,123,640,729,786,489,664,718,242,807,997,96,527,642,657,225,771,364,293,205,798,902,881,365,333,170,918,844,771,484,529,728,546,914,26,622,163,139,597,43,654,38,769,206,268,609,946,775,513,220,658,99,132,380,27,458,934,304,503,616,570,910,660,733,945,698,271,339,154,469,31,161,154,690,687,103,904,797,947,236,283,571,110,594,968,99,56,925,493,244,944,320,638,838,691,870,153,65,299,306,66,576,366,466,941,642,629,378,712,507,177,984,94,463,273,394,117,152,891,911,162,899,890,863,123,916,735,381,618,546,94,680,990,306,107,102,882,744,366,995,476,235,155,508,769,123,720,786,848,250,679,785,655,899,890,942,673,798,951,132,810,396,386,768,479,314,536,147,940,362,922,869,767,162,301,774,286,69,52,259,341,683,3,665,428,80,886,454,517,364,825,224,417,964", "222,179,190,678,832,676,343,545,173,873,467,320,497,627,888,292,438,778,332,988,710,309,530,980,820,294,485,229,444,364,721,206,654,354,73,7,219,385,509,373,404,157,677,662,613,771,319,490,703,1000,476,129,491,94,403,173,258,447,726,672,878,977,873,462,683,486,740,396,89,934,165,409,891,128,951,439,795,31,443,557,279,36,803,792,510,264,325,696,343,115,963,12,677,757,785,413,872,607,824,415,893,154,297,712,377,837,759,666,612,328,647,246,943,694,426,345,97,374,295,773,641,685,955,919,383,445,898,229,750,38,48,752,346,642,27,958,832,346,631,992,124,491,977,374,918,310,693,578,644,47,732,211,128,636,570,848,262,599,646,878,485,657,878,6,248,19,839,795,347,470,823,233,862,142,692,842,513,587,417,758,729,933,424,842,966,974,551,5,427,332,822,476,752,15,224,66,345,212,429,294,911,528,531,742,436,857,77,585,903,225,147,517,430,697,99,679,810,426,853,99,762,148,564,217,166,557,444,828,860,115,641,535,460,745,901,155,751,876,437,178,926,883,909,530,34,666,121,827,666,137,735,964,195,646,885,883,562,228,216,874,310,903,91,812,955,411,443,68,479,974,953,224,829,634,325,392,165,407,71,771,355,398,21,535,692,621,410,781,555,744,332,920,552,681,717,425,860,27,601,537,746,837,343,884,623,626,589,484,126,803,947,142,704,474,306,319,420,395,388,767,785,526,76,138,974,276,412,315,551,54,622,69,217,390,716,699,699,324,757,611,704,46,596,486,912,63,812,153,112,199,49,463,280,232,858,180,637,425,583,199,591,76,991,8,17,327,141,23,870,965,295,206,486,94,239,444,520,744,512,180,496,147,704,52,244,74,855,717,636,607,853,403,742,184,452,931,798,592,502,258,186,187,132,579,531,687,278,929,358,693,985,462,211,632,101,651,478,460,508,409,937,104,359,340,456,24,732,41,629,686,511,46,479,298,285,611,736,834,536,724,493,5,607,195,363,767,295,56,803,939,985,62,275,66,138,931,792,943,826,396,441,454,817,520,980,512,867,683,867,412,611,706,72,666,345,885,88,62,362,100,767,793,379,126,60,245,566,132,373,597,985,195,314,595,393,195,793,487,121,208,747,92,284,51,963,189,48,292,943,602,756,106,118,904,13,617,346,337,238,589,715,958,113,808,692,190,423,134,382,251,820,748,430,566,642,188,373,182,107,345,343,475,75,965,68,721,743,558,586,654,821,29,937,874,942,639,577,444,519,303,855,654,3,494,940,521,353,622,564,285,469,851,810,933,81,881,295,62,64,536,994,96,558,701,736,882,131,60,783,444,564,748,41,678,762,789,310,750,797,916,872,414,480,690,37,614,698,949,175,574,632,929,573,324,299,177,366,275,100,446,607,399,13,626,623,999,401,459,839,893,958,901,120,758,117,809,296,654,459,75,493,873,648,662,862,670,308,517,716,580,820,756,614,664,858,4,836,630,221,813,959,537,191,266,983,9,875,74,849,837,582,125,219,664,823,721,592,413,461,516,741,0,660,127,33,35,173,815,839,711,513,806,628,933,427,293,984,208,195,118,90,625,636,933,604,104,231,493,442,791,211,484,740,668,133,399,997,242,164,949,276,520,827,290,514,175,62,154,190,36,647,622,453,729,407,120,863,744,476,410,591,927,935,498,605,808,754,97,499,266,956,873,798,309,515,354,442,97,833,409,197,956,340,960,716,890,12,341,137,251,480,293,81,899,700,874,898,763,222,823,742,862,281,354,541,459,239,449,270,652,376,171,507,778,126,496,426,88,306,180,473,819,554,239,537,78,808,139,159,69,133,992,839,639,466,935,437,217,450,515,258,671,612,100,518,202,858,450,456,382,982,367,921,551,149,243,633,427,230,733,132,10,797,549,383,29,450,89,429,850,272,82,545,542,749,936,348,778,721,173,285,595,889,314,239,172,676,948,733,243,715,626,785,462,264,88,142,734,653,401,558,365,484,81,537,960,534,114,221,262,837,631,689,593,461,350,279,765,25,182,679,593,845,868,485,524,90,75,805,644,204,5,152,658,982,652,712,883,756,578,969,400,942,874,378,917,7,473,701,200,560,287,276,122,506,911,198,689,712,593,351,966,435,946,782,993,992,449,548,718,255,923,931,700,283,455,782,191,534,531,148,632,163,291,137,978,718,738,282,629,963,986,445,850,57,602,839,946,825,436,728,784,847,649,55,547,854,855,195,998,661,1,153,875,181,682,772,138,516,929", "953,487,271,673,239,262,992,813,629,566,175,330,432,293,435,860,351,487,660,460,250,975,348,667,90,12,859,335,710,527,279,148,128,741,13,57,765,398,700,702,582,969,96,706,825,148,639,991,669,352,977,734,795,566,46,555,317,598,826,374,191,696,564,944,939,396,788,742,949,365,40,529,363,207,48,32,608,552,184,237,530,239,472,925,294,708,724,261,554,128,622,85,159,565,985,55,160,931,499,303,112,667,539,737,477,232,853,363,530,276,421,482,830,362,662,599,553,199,354,10,718,318,854,584,181,960,237,337,802,696,455,415,639,588,42,72,856,412,662,350,883,929,767,610,594,994,294,436,367,802,248,331,836,727,553,638,844,370,783,60,624,253,507,391,683,33,138,381,830,902,110,622,263,98,409,496,737,928,732,625,596,56,341,261,140,767,431,377,993,979,735,109,784,570,823,892,279,451,520,805,604,749,349,494,787,197,858,530,988,216,902,958,907,598,120,573,294,744,701,640,47,515,870,174,732,167,710,292,63,665,978,179,228,184,266,209,99,640,679,167,903,304,545,200,586,377,394,481,907,692,966,107,210,375,594,277,501,959,447,747,708,677,390,94,556,299,560,713,374,638,605,778,423,549,940,95,218,33,932,565,975,221,797,915,574,749,50,1000,426,442,901,466,14,844,214,772,13,122,307,621,12,867,75,343,85,715,95,485,841,134,870,953,80,582,353,645,366,803,317,582,883,300,877,39,86,739,241,454,840,867,907,954,770,102,739,415,923,7,993,516,663,326,418,248,493,242,465,991,748,337,310,133,512,440,791,257,929,611,16,186,584,744,126,149,254,681,655,752,699,999,656,98,25,235,847,242,522,745,914,514,973,16,333,330,280,471,519,322,856,364,222,21,616,482,539,740,658,740,89,959,144,516,519,37,530,66,371,116,728,524,783,781,34,729,915,994,831,312,318,781,387,517,418,772,659,791,677,529,372,21,913,985,614,980,968,586,979,217,256,184,780,31,559,680,684,261,664,425,293,952,150,692,223,905,246,346,848,250,186,343,469,721,486,88,245,106,265,412,561,551,87,278,171,672,778,385,431,510,489,268,512,895,106,581,671,824,526,914,574,735,776,208,381,163,10,463,194,736,937,514,333,309,282,348,30,2,152,27,526,686,781,932,336,483,85,471,134,544,209,693,768,837,572,959,341,878,871,584,298,271,236,366,286,29,56,462,232,260,983,63,728,847,129,738,822,748,668,856,326,142,839,36,75,709,411,630,132,26,227,501,534,497,198,907,149,442,411,860,175,501,462,24,452,937,575,33,697,644,941,190,24,230,723,213,361,358,504,538,479,952,126,445,13,655,356,756,341,248,225,119,826,713,88,309,77,945,39,417,820,859,744,498,340,547,73,984,725,547,98,475,236,810,963,766,630,889,60,792,628,4,91,493,1,42,20,838,191,281,788,491,170,166,599,792,529,658,400,745,447,219,789,82,345,841,702,807,939,838,546,765,287,470,944,90,760,612,617,26,138,98,583,38,575,353,25,644,620,295,74,620,166,660,0,354,394,679,163,130,341,415,736,942,465,768,388,711,892,413,127,158,797,185,89,736,588,803,190,898,94,96,683,618,470,264,612,649,244,821,441,708,208,588,891,758,723,927,949,20,23,597,704,339,298,338,161,378,217,660,956,517,210,709,251,882,874,551,823,254,859,262,203,689,374,909,257,590,219,418,695,120,38,169,349,814,81,939,71,676,314,584,355,743,951,51,281,464,738,562,58,169,29,552,318,173,657,338,602,156,117,758,44,544,602,543,974,908,317,865,544,806,342,342,505,477,387,596,811,496,84,819,758,4,258,912,70,383,889,305,159,240,739,699,331,756,35,596,594,493,483,437,668,528,36,864,59,146,38,21,949,359,945,313,138,821,552,415,458,232,172,991,157,800,706,859,113,292,929,658,637,337,482,832,656,243,150,949,397,693,273,711,94,94,636,253,862,915,616,49,981,931,341,625,49,212,925,636,963,875,984,332,284,734,404,515,626,943,251,478,853,477,263,488,181,502,143,977,654,181,190,240,18,865,737,974,614,689,451,547,835,581,115,986,140,386,26,225,247,820,324,645,277,729,1000,890,605,319,146,227,534,841,927,528,752,979,752,459,683,296,650,589,374,577,160,102,879,833,317,920,819,432,801,721,873,488,188,275,714,227,18,223,86,443,664,527,475,260,435,747,86,877,70,26,940,913,110,988,851,423,525,755,250,989,750,502,272,591,101,155,523,803", "604,555,412,94,828,313,903,949,359,122,883,449,853,17,612,577,217,22,947,84,303,6,120,485,68,393,654,234,610,80,397,448,820,621,74,957,28,120,375,551,471,20,516,736,564,295,635,100,318,309,741,411,912,821,390,399,71,387,716,711,707,643,75,118,793,453,3,137,55,316,969,934,971,994,962,389,916,697,416,962,502,173,63,263,601,406,271,647,868,829,302,69,456,771,402,64,956,18,282,650,190,757,208,154,985,851,932,875,536,984,802,879,631,561,87,234,530,719,997,262,636,642,70,963,735,34,353,181,239,303,407,349,223,6,249,174,21,803,612,897,672,150,554,250,448,503,146,675,14,394,120,300,327,44,799,840,76,342,654,383,719,905,231,783,308,478,506,48,203,729,106,578,304,234,983,920,737,223,749,714,303,757,853,957,759,73,941,272,521,505,419,195,720,153,787,886,536,472,571,298,565,451,87,788,189,954,852,305,803,19,353,834,394,70,142,451,863,943,2,358,819,367,690,231,555,701,20,48,884,250,938,636,946,389,449,439,323,70,428,583,543,235,399,606,248,337,67,681,713,319,867,589,458,568,334,589,473,247,492,686,571,826,495,605,155,467,643,478,810,723,17,18,606,962,693,201,635,902,811,358,440,901,954,531,964,850,454,443,429,762,483,4,384,751,997,266,631,312,461,677,181,160,293,384,811,965,214,278,714,749,724,483,552,749,670,354,545,885,180,591,478,789,639,466,333,40,986,971,817,891,391,4,600,311,427,983,195,660,242,194,226,262,42,182,347,103,284,288,55,78,860,542,915,622,23,454,860,275,781,691,37,638,160,379,35,134,241,325,233,5,440,766,517,272,865,5,103,525,896,182,113,484,347,824,595,559,666,624,389,321,758,196,161,785,54,69,537,322,905,950,696,352,82,138,474,104,708,495,238,75,606,781,631,260,267,448,391,36,39,97,878,449,765,898,539,718,674,508,322,540,807,257,289,714,894,960,682,290,241,144,560,374,752,818,280,354,940,669,679,444,771,85,40,12,781,638,739,566,39,611,129,424,805,554,572,840,385,415,66,711,372,257,264,57,953,446,605,635,487,734,421,552,760,904,34,526,973,231,172,444,589,418,916,483,394,351,45,661,658,586,886,758,648,724,994,974,973,347,603,593,652,650,697,401,18,693,613,762,150,816,863,142,853,230,740,41,103,224,365,275,841,696,655,560,491,907,613,495,570,394,452,673,720,494,224,126,458,676,663,116,616,368,807,352,308,646,61,696,261,355,837,776,715,898,376,102,783,823,11,292,585,871,249,427,597,859,916,792,503,939,645,386,422,723,103,470,190,28,130,172,274,399,656,240,537,293,393,144,53,371,249,796,883,771,528,538,508,183,703,322,124,917,558,487,925,881,757,205,67,139,223,268,624,249,420,754,997,169,513,328,813,112,736,379,250,650,340,827,160,268,467,165,75,919,268,654,178,554,663,451,602,930,458,482,718,354,637,128,392,489,784,920,913,812,974,972,819,506,32,455,329,226,898,660,749,896,68,163,812,496,399,127,354,0,871,732,190,651,707,374,543,991,165,613,875,352,20,365,295,416,241,468,689,48,244,642,847,991,243,512,128,863,611,417,163,237,348,186,910,594,531,164,372,120,739,997,644,180,166,866,840,362,614,30,429,697,200,494,918,782,29,218,458,478,846,688,558,133,713,343,161,134,873,806,585,357,782,130,108,489,788,223,305,690,316,803,58,821,435,993,693,22,978,761,49,484,419,299,961,242,85,497,568,57,425,341,91,7,457,599,810,136,730,268,233,986,994,808,988,950,658,879,239,981,739,12,268,617,657,154,238,908,488,719,507,435,731,109,324,243,128,34,912,785,882,417,16,506,510,273,736,865,247,457,592,500,788,589,571,394,882,164,573,18,900,820,626,332,400,796,792,647,864,176,169,483,411,259,617,345,19,309,411,667,592,268,594,607,721,739,280,73,184,705,512,241,814,344,578,107,28,756,490,247,320,379,732,210,462,6,394,655,103,482,992,591,513,822,44,242,585,27,997,654,605,661,287,155,38,451,151,880,198,351,748,107,852,988,806,69,240,918,862,401,178,426,250,685,82,237,605,232,947,764,113,318,513,655,244,372,149,559,191,315,867,25,724,785,562,528,141,572,526,532,384,539,719,877,948,356,45,441,843,839,565,849,923,67,698,832,584,760,585,355,220,720,134,197,951,798,722,880,652,330,46,289,746,942,889,857,680,282,903,229,636,5,254,469,507,292", "611,710,275,764,764,924,916,616,506,490,697,197,146,672,155,532,942,288,296,859,396,275,322,377,112,562,312,1,28,503,262,849,185,481,31,203,502,595,441,60,201,993,856,312,193,613,568,229,917,698,629,178,244,919,230,105,458,257,320,640,352,155,414,211,155,649,986,397,276,601,166,251,697,150,781,691,113,553,783,867,210,156,84,312,64,998,905,364,925,908,716,222,94,859,41,565,94,93,131,366,57,499,363,552,426,818,871,721,557,648,389,846,246,365,333,577,81,520,518,625,936,237,220,247,232,168,541,259,772,940,221,583,482,497,657,420,555,67,40,232,984,762,47,136,24,409,711,88,50,396,196,565,727,609,2,579,661,855,889,475,139,767,537,796,876,225,629,13,505,235,437,725,15,128,5,400,76,105,307,352,836,825,209,488,932,21,302,926,387,651,775,185,57,514,491,841,986,131,165,601,968,442,83,94,947,935,762,368,536,178,312,957,531,542,667,313,989,549,712,686,529,521,454,727,831,313,14,218,902,780,410,434,464,659,611,638,38,101,371,834,653,241,131,600,349,697,336,769,90,184,709,555,480,369,726,39,618,285,993,627,15,681,382,445,657,822,864,606,870,101,623,413,927,948,203,53,955,400,713,410,930,549,761,649,451,956,219,993,16,887,78,497,931,507,793,974,95,853,171,749,416,701,236,431,374,48,144,642,156,250,418,735,24,739,483,235,990,407,46,65,560,791,289,102,487,560,950,589,321,63,375,357,913,768,124,760,166,794,632,654,936,678,618,12,650,693,545,19,680,12,895,878,137,524,942,963,533,972,681,598,407,415,815,100,691,24,910,718,351,771,703,583,398,511,212,297,597,916,636,917,889,527,532,509,787,450,365,956,560,28,30,683,677,5,412,842,867,432,723,978,550,228,229,588,823,957,69,155,641,245,904,876,723,345,140,855,456,970,96,5,338,223,708,43,473,279,290,377,26,652,182,795,156,529,556,649,116,501,688,492,161,12,871,805,948,414,559,990,573,604,549,826,216,947,677,613,816,123,194,579,668,832,659,226,176,326,638,2,523,670,421,231,722,399,860,70,958,774,967,928,813,282,491,268,142,917,45,946,849,739,881,330,280,207,125,141,685,941,427,544,650,805,751,22,606,297,681,718,474,864,384,539,668,624,611,496,574,406,425,153,996,962,96,86,118,796,297,330,104,880,820,729,629,8,223,343,84,414,526,427,732,757,843,719,229,874,674,56,832,612,126,239,63,552,257,442,39,990,443,591,521,599,379,262,628,631,467,563,874,46,685,598,298,630,58,318,708,101,856,154,28,583,257,889,298,868,576,327,142,913,397,453,347,367,743,901,963,394,51,708,703,996,814,255,539,143,571,85,675,955,9,711,846,596,615,927,772,86,48,619,405,434,455,508,999,375,429,315,102,265,47,160,824,869,790,419,926,581,415,157,518,239,393,228,185,483,747,885,422,146,556,689,582,810,220,55,612,57,900,523,285,968,69,628,504,332,127,91,266,406,822,614,360,314,716,841,79,494,60,544,176,33,394,871,0,234,445,156,134,486,742,833,331,978,503,557,369,2,621,220,377,528,154,269,53,72,749,68,532,478,438,412,667,881,931,577,730,787,678,619,868,16,805,247,244,888,326,369,200,208,436,148,878,639,987,47,965,343,225,110,978,169,954,810,667,413,209,409,427,906,736,549,70,776,839,97,394,836,521,784,577,991,367,888,464,796,723,705,8,608,529,760,974,859,521,522,262,99,93,110,4,812,104,199,962,985,706,464,839,265,982,478,855,362,135,841,862,28,497,917,113,678,709,46,736,907,756,270,510,830,615,439,2,742,824,647,767,751,254,498,832,471,712,460,757,485,646,551,210,222,968,897,642,682,989,15,329,464,777,295,355,285,954,743,986,192,670,636,299,898,553,869,827,940,215,245,778,714,426,158,756,703,699,395,832,194,587,92,713,928,668,237,59,764,293,418,716,255,208,721,285,5,64,43,824,211,256,276,560,437,739,307,675,7,978,135,564,116,135,309,447,816,285,470,421,262,737,206,738,79,819,730,572,304,286,213,454,156,240,46,919,67,809,758,876,198,664,956,686,633,820,72,670,734,506,86,677,715,24,884,828,657,754,468,755,15,268,17,330,997,25,188,593,16,533,676,101,418,979,716,618,951,197,447,535,911,471,268,951,384,566,898,239,976,776,593,404,756,765,452,556,172,110,747,136,187,244,418,879,535,677,263,613,956,271,736,274,547,691,506", "111,215,427,731,273,444,982,465,410,64,274,832,909,771,147,685,273,773,17,345,40,706,961,884,246,117,414,850,366,938,438,507,737,902,911,321,260,408,622,167,786,29,46,728,60,967,911,83,762,359,2,7,520,875,979,989,914,322,419,776,214,992,289,337,743,444,597,909,197,709,258,645,817,161,140,152,321,454,199,868,231,178,5,938,582,418,512,579,324,207,295,525,657,578,278,795,865,112,288,807,597,697,714,16,796,683,950,548,35,160,220,555,700,357,464,931,410,901,55,687,424,294,329,507,942,822,985,329,913,513,419,689,387,781,968,635,513,53,362,213,672,100,464,248,863,232,384,474,885,666,930,370,677,727,171,360,379,199,177,511,246,174,514,354,54,763,760,808,163,788,569,781,861,443,794,417,792,452,708,565,741,735,200,802,539,696,409,680,204,520,130,96,369,388,370,217,775,77,934,564,489,141,976,835,962,207,845,570,508,594,417,945,604,712,111,430,111,709,599,299,341,445,63,662,518,64,369,933,153,571,623,155,203,554,92,584,473,4,87,732,493,638,622,134,143,10,137,317,37,316,286,794,188,408,226,937,132,555,374,903,682,951,914,959,581,403,850,173,766,69,7,191,784,175,772,756,523,932,216,877,514,216,958,352,308,101,931,281,900,899,661,961,714,845,340,895,386,868,865,451,687,841,276,200,944,522,784,41,498,914,145,353,537,423,341,628,597,372,863,837,754,167,60,280,188,360,388,916,510,710,252,175,236,130,792,948,348,382,431,895,99,59,434,317,742,487,953,789,100,943,510,993,546,55,413,67,377,977,435,864,806,577,741,232,191,244,652,596,858,187,421,549,249,99,858,293,426,457,172,34,381,259,899,928,550,684,568,855,757,372,310,871,1,679,353,99,474,118,717,297,599,942,208,207,42,108,42,762,210,387,154,858,765,677,455,685,912,795,86,78,113,732,968,956,355,69,902,956,31,594,740,277,922,192,26,428,388,520,196,977,867,853,82,81,972,310,486,341,115,824,192,194,857,362,367,713,555,973,149,885,311,735,345,244,504,949,877,368,26,62,244,662,630,803,425,268,487,54,111,567,433,894,363,881,970,888,659,257,218,824,272,666,588,792,62,990,291,419,260,340,748,638,968,576,638,488,692,909,506,95,958,509,682,392,233,109,941,420,625,418,753,279,355,562,490,412,312,521,98,890,387,220,369,567,469,852,529,180,872,221,423,878,755,245,225,122,321,64,836,575,419,647,464,263,777,942,590,106,757,669,80,244,55,508,412,274,506,24,788,57,623,903,559,605,554,859,236,913,494,45,488,452,218,219,210,170,478,577,748,604,244,256,755,402,771,67,401,172,976,70,342,117,243,316,802,331,881,3,318,957,390,486,125,698,738,721,491,968,194,653,609,858,9,866,300,737,789,720,140,388,104,672,695,792,664,236,68,177,87,422,426,963,914,821,370,281,247,510,195,135,824,716,82,203,746,312,822,768,505,412,211,295,571,894,736,926,956,395,928,880,29,705,512,507,782,923,309,656,643,472,827,35,679,732,234,0,722,648,156,771,224,300,317,801,960,117,791,921,383,833,283,221,641,979,796,469,396,475,595,808,202,546,702,99,157,735,597,244,484,554,361,478,1,519,386,834,191,561,269,442,230,166,248,971,788,469,388,234,505,222,509,150,856,719,457,583,130,147,504,298,810,473,757,42,760,819,437,180,974,540,830,776,149,283,42,106,491,821,203,383,249,809,593,482,625,65,729,198,861,59,855,365,416,377,47,125,351,480,855,676,800,873,158,995,461,338,172,918,849,855,775,809,761,371,813,947,554,260,720,387,78,431,39,358,428,16,114,511,792,121,73,525,172,572,46,310,366,967,157,665,490,378,851,936,864,443,14,859,123,133,361,871,262,80,629,857,364,924,273,741,281,363,63,967,583,72,374,749,531,930,401,220,850,113,856,325,877,602,591,790,281,989,82,36,653,206,858,139,87,440,784,240,373,359,885,952,281,514,680,306,547,916,252,713,217,316,218,6,818,105,571,221,192,4,674,347,902,260,298,975,105,130,20,193,785,50,299,668,627,506,544,129,888,511,398,753,84,987,871,482,93,130,996,240,627,238,946,91,556,288,794,398,875,665,791,361,470,525,592,916,624,898,522,788,606,311,695,501,396,108,292,945,216,521,69,843,710,250,743,198,702,652,29,365,596,978,595,437,382,437,528,429,630,746,842,359,980,677,596,755,793,785,751,652,322,335,876,948,728,117", "296,94,398,778,149,115,428,710,86,682,306,226,192,159,401,844,315,870,926,117,10,165,269,40,731,90,386,518,156,970,181,26,273,942,893,944,446,619,508,20,918,690,416,967,601,801,520,814,502,766,366,554,949,588,881,450,327,653,136,875,43,721,759,587,673,324,565,545,79,920,837,749,52,783,265,347,992,943,94,136,620,307,181,367,893,968,885,662,480,688,530,762,486,286,132,985,827,939,932,368,718,70,115,190,643,65,533,70,621,110,309,899,863,639,139,685,619,549,218,260,103,434,45,309,23,231,691,65,279,589,74,774,161,261,846,556,707,927,281,64,71,73,508,710,365,78,951,354,87,71,409,383,912,246,714,470,187,733,85,206,14,529,395,840,104,508,419,583,182,491,982,594,815,766,880,842,23,412,523,648,562,192,205,721,843,221,741,176,9,965,953,859,108,721,40,32,7,262,636,333,799,840,410,205,71,913,807,883,734,612,703,162,62,672,622,976,593,830,290,462,644,697,109,29,364,753,466,126,288,840,325,481,292,700,525,646,320,94,587,860,245,252,610,212,996,503,506,297,581,34,959,759,393,47,933,161,164,246,226,269,855,964,81,220,128,569,804,35,247,585,247,649,497,216,489,733,721,675,292,193,340,873,881,643,587,387,880,508,785,606,928,12,480,789,102,481,260,786,690,606,112,329,17,259,789,342,302,172,266,612,215,658,809,382,252,916,643,323,979,472,200,686,894,231,508,258,663,736,469,3,794,527,261,560,457,262,139,229,167,471,568,998,610,102,471,225,662,301,333,129,103,974,325,857,127,18,429,949,15,901,298,933,604,890,743,71,591,74,263,966,974,800,151,603,496,257,133,349,677,79,624,754,615,886,507,185,964,588,855,511,715,575,587,734,487,746,982,833,680,808,682,897,996,840,165,266,195,293,850,46,599,35,790,529,850,671,994,635,242,991,511,561,924,130,148,918,248,118,81,392,473,661,44,753,172,858,781,310,349,461,186,882,977,364,601,807,784,444,511,125,652,115,553,605,289,431,584,512,85,395,379,221,830,27,678,731,204,438,406,470,429,86,170,72,868,434,155,631,723,850,542,983,280,960,931,202,683,860,69,739,396,688,592,848,465,444,813,614,466,824,729,526,547,88,291,30,20,218,869,141,828,512,330,442,479,382,573,201,633,889,249,855,824,414,23,928,177,294,15,57,486,302,161,785,373,206,196,816,360,916,948,293,486,992,659,24,181,282,244,152,737,722,824,454,817,30,459,730,11,886,899,593,553,411,895,692,73,846,275,846,152,145,270,207,780,175,421,19,407,306,129,887,378,503,654,581,236,621,566,332,609,920,632,620,103,890,781,277,593,956,100,510,636,440,776,996,2,543,528,565,590,81,78,432,165,516,539,328,636,659,8,790,529,778,729,210,165,764,684,975,993,289,565,781,337,417,966,647,74,308,720,871,766,264,664,984,366,14,976,451,407,732,499,281,400,295,722,712,424,901,322,6,609,202,343,848,513,42,244,682,988,969,824,29,640,647,469,488,102,620,875,173,163,190,445,722,0,571,197,419,755,493,192,774,964,846,138,140,173,247,164,609,223,906,544,688,582,612,803,517,251,884,78,112,627,709,441,724,352,165,449,9,640,585,226,58,203,564,932,470,754,76,224,945,343,564,430,262,146,876,296,581,596,674,352,638,133,491,179,157,225,460,755,668,565,276,312,130,575,416,140,308,500,867,929,143,634,853,77,641,590,328,797,172,292,552,855,430,494,445,751,278,449,825,420,649,153,974,552,602,169,326,876,44,802,588,35,953,566,159,587,910,23,133,164,993,202,656,752,155,4,29,151,850,841,869,875,236,636,434,320,170,79,438,546,794,515,11,959,902,236,710,932,453,273,557,750,977,570,55,732,922,643,598,312,838,753,914,442,650,933,224,954,51,835,820,381,162,956,840,898,736,606,496,216,776,989,177,424,282,491,270,986,670,656,708,951,917,664,611,983,467,250,582,403,339,428,927,460,869,378,401,592,100,756,857,957,560,958,533,219,640,19,297,252,111,492,866,638,747,429,704,928,21,294,811,931,238,114,796,545,144,780,181,635,407,505,881,992,119,637,136,55,330,550,523,87,37,89,758,633,38,861,132,276,589,484,335,14,276,233,118,976,236,24,785,778,229,988,977,319,60,586,219,811,545,482,719,503,367,855,576,527,41,748,439,696,6,863,345,725,892,856,593,619,489,162,51,50,787,961,231,271,711,700,986,876,261,482,254", "784,707,206,196,191,895,271,828,648,794,415,377,965,788,993,409,128,339,182,890,933,461,437,896,598,258,226,286,391,149,218,656,726,941,521,720,518,471,146,279,951,553,335,567,644,39,260,844,887,260,623,774,247,825,260,231,24,433,436,832,883,994,930,333,970,613,422,760,717,650,597,97,690,405,681,737,919,243,632,584,215,405,98,98,7,859,812,619,352,518,270,74,449,138,8,808,183,66,862,19,97,208,974,834,457,510,622,997,609,208,403,966,612,981,516,56,822,141,583,187,925,384,481,365,491,42,803,59,605,791,547,952,720,641,437,468,925,213,697,762,362,337,570,709,666,738,335,291,285,267,983,205,714,177,581,554,893,569,345,98,513,177,795,823,87,233,246,998,585,478,916,754,876,448,847,334,245,937,108,497,220,872,132,827,124,616,648,772,640,572,667,613,315,92,683,940,756,447,899,692,347,50,457,981,520,32,773,41,12,179,21,823,832,127,915,214,383,315,121,661,236,480,623,352,18,569,273,355,713,689,785,93,475,379,667,768,63,70,951,922,929,497,436,894,637,87,492,609,222,177,724,682,888,887,46,492,531,665,22,164,214,278,360,216,317,526,763,325,397,576,623,461,501,91,3,382,266,504,349,459,491,841,307,941,491,713,143,641,249,141,348,205,879,174,593,433,3,836,521,629,225,396,340,683,139,219,909,324,931,723,732,635,736,971,814,346,517,721,353,486,656,635,248,890,567,242,460,874,117,659,322,690,270,21,280,343,517,640,395,539,38,424,144,996,927,836,617,594,448,974,11,595,330,103,635,11,633,715,951,960,542,59,742,780,614,484,881,741,87,616,655,467,264,417,774,98,987,254,403,783,292,356,137,932,83,138,400,5,481,76,999,603,732,254,246,411,492,264,29,485,104,839,130,294,733,853,680,353,678,489,542,583,212,568,419,450,227,665,666,860,945,429,137,206,304,771,541,657,648,41,270,383,236,595,940,356,920,583,847,598,281,276,431,550,342,866,845,513,880,473,636,805,645,219,22,749,901,215,667,302,439,794,700,301,812,243,353,899,918,219,564,641,972,628,738,802,838,661,797,279,480,441,309,837,598,528,241,41,317,474,853,327,55,67,644,715,565,354,546,84,201,510,764,294,522,757,460,568,999,848,96,352,34,926,629,886,263,507,28,230,386,140,709,465,852,360,394,472,285,163,760,462,352,752,756,862,716,678,101,256,118,262,850,709,833,855,953,652,320,698,297,627,131,981,628,179,297,963,725,388,266,879,413,327,619,640,487,902,500,167,47,365,110,116,30,862,939,174,825,379,880,998,726,679,720,144,419,213,860,986,607,461,219,499,318,408,650,331,791,568,427,975,164,398,370,20,601,853,366,575,537,433,898,496,593,608,699,285,800,362,590,500,481,699,932,267,329,562,872,692,777,465,609,279,678,586,927,942,827,61,938,47,957,312,327,665,300,942,59,698,571,264,227,658,603,326,745,672,96,78,681,419,606,271,118,986,282,340,970,357,726,378,103,971,85,553,22,626,584,596,268,815,130,651,156,648,571,0,75,889,357,845,729,982,678,301,522,383,276,657,164,535,509,477,235,649,366,824,872,808,590,61,871,81,441,74,715,977,663,386,750,633,184,785,239,912,729,424,836,561,606,591,951,545,840,400,506,931,917,774,543,526,325,933,889,643,747,196,560,804,56,460,10,961,315,167,557,74,951,715,751,149,907,537,540,186,552,667,696,12,295,795,7,48,812,125,62,788,19,685,673,868,79,616,722,705,500,148,644,725,51,87,328,657,920,634,553,827,215,515,884,11,810,630,76,245,504,557,314,87,224,787,908,444,165,839,405,727,120,137,120,180,823,595,197,181,262,583,573,171,243,684,214,864,720,380,740,571,303,567,786,651,125,774,915,764,739,33,55,486,940,612,849,201,501,690,566,599,304,187,925,641,763,96,738,474,991,901,826,296,166,138,876,589,425,793,24,734,483,940,516,701,386,286,379,716,123,934,615,208,804,749,411,4,789,192,789,668,913,323,424,582,279,331,758,659,495,745,889,332,269,416,316,547,105,674,188,855,143,836,639,888,808,562,818,334,832,618,821,291,511,647,229,299,46,421,300,21,192,623,399,931,473,75,298,223,795,379,458,122,224,49,745,834,880,763,469,443,310,656,813,304,303,31,760,710,779,797,418,778,101,201,982,722,639,23,845,118,876,107,371,167,407,361,896,477,403,911,307,557,122,164,554,912,705,3,228,878,979,844", "967,326,953,10,607,53,947,209,22,925,728,350,357,111,473,482,611,916,898,236,92,644,372,359,769,392,544,730,251,977,914,219,213,177,828,362,430,301,106,483,647,664,881,767,592,375,964,161,171,480,956,461,192,189,23,409,714,357,867,918,430,557,913,736,168,395,418,483,77,512,355,688,394,435,208,543,981,432,209,407,223,157,433,143,378,70,316,419,592,385,221,371,478,784,607,180,239,792,57,752,26,731,224,196,171,368,789,722,877,148,997,399,845,200,693,343,533,863,168,706,336,66,917,517,420,54,480,977,718,681,921,286,170,589,72,292,891,858,636,696,173,681,414,941,926,230,564,722,299,771,674,819,656,376,93,381,711,752,667,942,216,863,743,294,397,811,478,399,275,579,275,79,622,389,52,655,786,90,560,150,929,404,431,106,258,91,69,862,420,44,766,600,256,810,677,596,790,905,417,217,994,741,441,100,382,545,248,7,75,559,669,579,9,262,655,95,619,98,566,344,738,455,655,701,138,142,335,748,685,230,869,864,916,433,339,989,732,153,785,6,992,810,354,143,159,737,874,479,108,807,619,706,562,16,417,669,846,132,455,741,527,517,872,493,633,837,902,506,638,803,369,18,403,624,279,383,98,999,96,829,724,420,154,99,481,786,391,893,704,498,256,959,779,367,821,958,7,196,86,213,841,363,517,666,144,248,916,956,934,569,663,165,545,295,220,839,553,225,32,518,339,482,147,160,179,383,76,297,677,946,492,51,978,163,731,644,302,836,770,557,612,168,111,945,439,606,158,128,653,814,872,951,611,545,310,586,943,295,542,327,975,55,701,314,114,364,54,960,858,831,87,548,638,8,378,576,227,566,18,820,262,775,473,704,570,563,158,80,227,928,823,933,302,890,625,213,732,946,638,513,743,23,320,939,276,152,98,884,648,728,488,869,789,462,265,66,345,805,518,977,333,982,60,791,591,332,940,894,281,251,769,42,206,710,841,68,810,462,605,114,151,643,33,776,548,585,750,902,711,667,572,969,94,301,300,491,667,407,909,870,502,250,441,416,323,932,743,120,409,502,633,304,541,296,532,755,324,813,403,312,53,753,277,411,339,389,894,23,1,951,571,764,610,303,444,976,60,685,304,489,359,491,757,97,899,634,313,242,810,413,474,298,979,978,769,268,935,303,525,237,845,301,445,901,367,370,282,1,702,901,190,522,122,390,596,412,151,808,592,742,648,635,389,798,801,495,870,592,626,398,957,657,537,578,671,882,488,457,333,816,641,377,316,568,577,331,886,28,689,241,843,729,195,316,738,309,867,726,711,925,197,976,171,171,585,742,505,846,891,917,213,467,915,744,762,578,235,280,525,322,439,442,345,308,16,603,998,392,243,299,604,477,524,692,117,709,68,555,932,362,592,275,991,625,763,620,30,643,517,286,932,660,411,965,661,147,963,647,61,831,576,983,944,172,583,303,335,628,338,416,702,721,638,847,138,683,278,474,693,515,374,899,935,734,88,592,222,911,589,646,163,326,829,96,710,708,70,329,59,190,714,839,341,707,134,156,197,75,0,758,835,185,321,262,422,550,902,685,635,893,263,371,951,59,637,858,198,218,920,22,757,180,501,789,681,925,661,78,203,523,929,824,486,232,9,358,842,481,920,659,644,83,452,871,297,265,481,186,848,850,249,318,5,30,314,538,358,718,342,181,424,959,456,684,850,343,214,37,896,358,715,888,224,112,536,194,618,868,163,89,213,63,38,766,480,753,420,302,145,354,766,215,715,382,429,287,857,325,664,390,706,720,932,962,636,883,669,726,625,971,274,870,577,994,126,663,937,831,187,49,283,368,735,752,244,738,261,848,918,199,916,448,361,528,373,653,104,103,821,303,838,542,407,821,9,631,334,506,347,564,599,298,242,588,660,782,321,429,232,793,971,481,366,953,88,146,448,917,175,447,909,739,53,194,498,822,817,101,116,472,917,657,809,672,212,266,336,542,882,616,92,443,606,531,985,489,319,165,391,965,223,60,65,964,38,682,30,107,304,740,9,527,885,934,461,362,622,164,740,204,13,147,630,778,404,726,792,198,374,129,429,21,430,621,729,29,212,752,435,505,791,696,506,984,221,769,110,289,281,985,710,148,535,814,643,712,857,141,113,274,974,646,901,13,903,376,474,547,331,982,153,615,505,900,911,760,213,399,501,104,270,307,98,115,926,763,665,525,203,986,365,465,241,892,854,767,897,726,518,256,740,593,474,564,746,497,507,973,152,165", "175,469,138,87,382,405,383,539,560,557,344,273,529,342,157,860,416,56,144,166,405,560,307,528,969,96,462,803,259,453,4,115,286,36,306,974,156,862,828,245,217,989,911,855,796,36,959,237,422,545,503,650,308,462,19,69,330,40,357,418,917,291,91,913,533,663,887,196,206,876,470,863,62,773,314,981,234,889,976,35,426,133,645,23,79,744,830,516,203,732,76,462,587,590,925,939,435,450,972,903,216,749,864,842,481,623,63,220,702,189,760,705,829,144,303,540,436,309,688,537,608,742,389,712,269,163,154,728,768,916,391,799,478,728,675,864,855,590,970,543,482,135,695,176,749,747,714,933,684,949,92,925,273,740,7,201,736,702,946,183,841,265,139,773,737,106,183,862,608,161,603,531,782,383,118,587,759,54,478,453,823,199,828,289,863,243,353,855,158,121,912,416,947,675,607,545,474,532,890,827,230,72,44,252,467,642,415,690,554,803,41,713,967,326,144,643,179,110,115,718,171,751,611,466,317,898,393,642,884,215,829,274,840,706,266,534,272,780,54,53,130,772,182,582,698,683,619,250,39,806,744,462,863,371,380,978,347,346,634,450,442,221,689,112,377,836,751,952,359,165,145,344,715,320,409,365,128,686,774,99,464,834,34,789,158,176,915,56,312,638,55,909,215,931,570,326,508,32,773,268,980,127,681,857,919,140,987,428,423,394,969,4,690,176,430,312,996,383,286,559,669,858,645,325,520,457,776,840,899,629,491,182,1000,355,317,463,632,361,245,126,709,39,376,713,73,545,517,550,897,113,698,971,632,903,819,386,701,838,341,599,170,218,390,387,558,110,225,77,873,333,569,696,340,511,586,258,656,640,5,938,884,787,367,400,545,613,24,953,386,651,473,349,994,71,27,928,428,737,194,39,921,297,411,25,164,583,591,120,485,167,805,897,552,46,195,512,851,458,531,159,912,43,69,50,30,498,697,965,973,6,967,230,397,130,952,939,657,841,95,275,856,361,47,317,965,665,833,122,98,398,623,87,635,347,759,503,981,33,459,441,191,328,940,999,532,544,541,624,922,866,172,776,909,516,20,286,319,885,336,613,385,558,73,258,166,542,759,262,64,53,319,397,460,685,765,965,17,91,312,792,757,682,173,468,977,900,688,644,292,154,216,2,562,133,682,405,971,935,791,620,534,274,603,750,564,933,187,449,773,656,745,681,439,767,932,849,702,669,786,979,672,449,797,678,400,235,249,577,767,604,791,796,336,607,807,563,654,77,607,363,307,974,184,653,679,714,204,107,764,454,804,200,542,939,673,161,256,164,744,271,804,635,179,875,581,373,152,781,779,822,239,571,592,320,193,26,624,347,342,614,24,646,598,97,844,570,978,901,962,700,784,529,467,301,369,626,902,502,473,303,861,762,482,609,599,118,70,52,233,937,974,133,935,759,791,817,613,692,992,588,370,238,392,246,990,139,379,794,187,573,458,631,866,627,203,69,819,352,934,815,931,964,715,195,164,192,110,977,610,928,15,158,936,743,94,957,723,145,567,574,261,711,415,374,486,771,419,889,758,0,169,441,509,587,754,968,520,792,902,888,674,32,820,147,43,104,836,524,844,401,724,983,582,849,857,220,608,157,93,862,62,804,358,33,581,25,254,620,611,734,463,578,802,633,537,194,241,451,915,714,737,965,575,888,454,987,47,456,972,809,883,858,232,496,653,94,458,880,862,241,660,164,555,391,730,978,250,545,860,388,773,35,493,466,91,823,262,599,23,108,731,939,823,548,777,191,961,786,199,339,414,994,283,319,690,364,961,128,523,27,121,879,211,581,120,740,831,583,967,936,860,26,725,384,523,331,939,934,930,326,969,193,631,679,274,738,975,622,430,463,355,909,700,266,593,80,649,127,354,16,980,676,27,31,418,228,914,668,888,157,964,68,884,846,842,570,818,498,779,963,157,834,313,991,991,570,51,737,167,725,482,911,18,251,935,349,759,934,889,645,188,451,123,412,256,72,602,799,704,678,461,521,228,879,340,431,616,551,301,661,715,420,183,260,991,281,742,940,616,399,571,588,64,588,32,528,946,46,174,541,270,846,25,839,225,36,881,132,675,545,926,439,80,437,396,814,95,344,991,931,839,561,325,34,564,865,929,686,629,276,927,623,364,202,936,834,492,734,719,428,616,886,419,331,382,857,926,178,691,315,568,384,489,60,620,524,609,996,331,488,464,273,974,776,791,290,308,283,980,415,461,468,898,208,830,705,502,10,806,783", "448,456,198,3,895,463,605,227,793,305,806,446,630,820,655,143,45,861,445,939,865,204,334,173,979,114,644,2,18,576,275,673,138,972,648,381,721,846,502,219,91,634,814,946,830,836,729,114,888,97,685,208,124,530,989,771,154,468,557,903,316,71,136,505,106,293,569,823,494,971,564,518,573,244,347,21,617,989,795,51,335,582,750,660,273,807,927,422,688,684,372,929,363,917,388,298,631,309,297,195,428,297,848,41,778,793,276,970,675,635,961,383,958,757,117,725,416,11,565,679,754,185,674,520,367,413,41,334,999,154,939,42,724,361,582,562,335,81,371,608,871,593,787,125,141,668,583,20,685,413,282,145,80,614,104,8,337,92,982,291,14,838,880,308,60,234,201,734,260,175,841,87,428,481,92,395,818,49,513,55,740,405,573,160,195,135,419,708,398,783,42,395,78,576,115,98,580,475,960,965,285,590,633,827,499,268,529,555,52,362,665,404,930,102,239,583,235,705,881,124,510,584,43,892,997,816,722,322,724,47,689,183,819,292,806,442,621,472,995,254,737,467,732,664,326,175,562,452,424,13,968,117,517,114,412,261,364,87,210,546,839,628,61,794,486,689,66,157,670,250,567,91,78,309,655,270,149,426,827,273,324,643,168,52,275,601,894,945,19,919,390,766,188,253,741,847,195,635,290,960,26,994,287,662,147,509,948,283,180,446,671,830,110,827,660,604,45,735,203,575,224,13,224,138,681,370,692,178,890,946,443,453,770,968,765,295,57,65,407,312,805,345,680,102,67,557,210,902,984,726,233,743,419,709,870,97,211,539,196,908,728,317,425,577,656,630,755,16,889,20,762,870,492,371,775,299,616,763,121,54,191,60,734,550,960,649,314,689,174,108,370,387,216,907,606,763,726,800,30,471,218,935,187,809,585,832,577,188,859,777,327,794,490,690,182,778,234,591,140,560,53,165,657,771,413,368,875,487,743,880,420,142,25,749,365,611,730,14,34,423,769,581,944,843,569,299,621,366,976,118,950,818,390,268,416,967,331,23,305,700,525,349,261,402,987,890,208,840,158,182,325,467,122,491,311,631,492,512,346,435,92,68,268,371,967,56,376,436,370,122,161,322,989,231,723,200,528,73,856,241,835,475,699,848,921,883,77,470,12,443,156,10,790,401,351,834,776,781,644,413,277,38,534,342,332,402,319,755,513,184,742,893,681,801,427,553,828,534,882,387,944,653,126,275,193,829,97,130,92,771,180,344,220,440,660,206,193,787,425,404,116,306,92,892,464,962,802,216,112,512,96,637,696,206,278,50,493,254,355,680,946,311,793,883,382,299,655,431,908,871,740,58,234,509,680,945,766,125,283,813,792,792,549,891,616,191,342,507,48,137,337,801,179,788,515,960,936,846,420,824,859,14,216,449,972,958,301,818,823,879,681,816,240,315,412,591,594,489,92,155,491,981,931,955,521,283,363,426,532,241,474,353,44,69,65,252,49,253,19,794,654,579,644,170,899,215,81,894,952,178,166,902,946,13,447,752,656,530,148,123,484,513,736,543,742,224,755,357,835,169,0,871,97,809,399,530,852,342,132,712,992,384,484,364,862,488,577,550,677,682,41,572,918,904,704,975,473,970,863,623,320,172,365,701,804,807,301,879,409,419,51,710,143,695,761,594,803,65,857,446,417,2,81,530,884,779,798,18,859,782,546,590,259,888,461,129,374,429,218,358,367,973,771,782,948,853,489,877,40,742,880,36,964,771,793,984,560,780,984,396,60,387,691,618,640,23,400,19,468,656,456,914,43,701,795,321,192,686,514,554,618,674,714,636,167,537,571,583,166,326,440,82,204,984,518,971,29,555,400,740,588,635,164,180,145,980,334,554,167,59,638,738,563,496,147,755,45,212,336,925,97,926,800,301,681,285,439,165,763,575,650,626,4,81,604,769,906,308,941,634,351,64,349,467,600,875,227,282,628,246,598,466,129,915,369,245,172,319,431,807,894,983,792,490,803,614,73,756,181,408,757,275,602,730,85,106,162,293,210,795,834,169,338,556,183,61,133,719,223,438,131,592,345,201,756,117,360,403,959,857,220,646,806,436,979,128,738,638,521,607,911,381,144,180,344,340,12,658,547,924,641,946,666,337,422,856,96,218,18,699,606,592,498,417,444,224,777,964,533,891,849,55,217,398,748,799,775,831,943,226,950,321,715,1,908,493,480,484,433,602,584,912,732,316,243,737,413,510,365,330,658,852,701,456,154,272,336,475,335,523", "130,186,947,644,187,422,606,662,857,609,398,272,68,704,280,128,763,207,314,943,31,34,132,813,807,403,667,40,901,432,123,119,571,727,37,199,169,900,670,103,344,360,247,178,601,386,160,406,572,358,306,517,767,956,169,157,659,183,512,209,230,791,220,340,70,775,842,492,221,423,560,319,408,537,119,288,53,467,531,871,597,308,319,103,548,903,148,697,519,742,567,724,471,822,453,923,384,882,955,461,147,981,863,823,678,752,59,778,657,978,575,468,177,919,284,23,607,682,134,777,682,256,465,579,272,780,841,58,483,955,326,561,7,311,2,413,808,38,822,501,437,918,384,53,184,108,236,186,107,312,838,851,513,131,491,220,152,294,744,153,104,226,722,974,465,941,329,823,281,443,127,25,441,594,948,969,967,411,800,669,296,429,860,192,459,644,12,292,616,241,466,791,679,253,595,367,443,144,727,741,382,970,86,532,248,261,528,70,313,183,454,181,698,467,737,167,305,717,18,920,823,422,193,153,616,191,578,720,434,216,66,724,674,263,330,277,88,418,736,956,449,702,445,404,104,557,818,57,888,443,559,545,210,404,899,349,282,665,482,652,245,395,765,604,2,397,735,160,551,939,447,545,282,295,274,533,921,276,17,301,43,514,361,959,346,893,936,918,331,507,368,263,385,23,160,848,886,415,617,769,618,234,865,941,262,528,670,840,30,132,264,819,305,33,592,98,615,839,559,321,234,334,528,501,500,605,241,944,147,612,401,274,131,736,728,405,517,125,793,479,217,126,504,165,128,184,189,591,261,594,972,128,299,977,473,224,816,936,388,417,165,672,498,832,602,52,399,505,205,339,393,796,937,815,209,899,705,139,85,66,678,989,814,54,862,596,906,471,334,687,18,36,921,175,882,264,930,41,326,938,955,117,335,961,458,808,810,606,920,301,796,371,691,836,61,863,2,465,539,621,301,933,217,656,158,743,123,316,915,763,175,63,742,926,463,757,621,50,589,12,23,499,962,503,916,940,460,582,739,62,109,350,676,384,712,239,860,238,389,398,64,792,376,122,666,287,394,560,347,431,270,174,274,444,230,810,412,722,936,933,180,116,70,201,530,232,430,201,965,690,602,567,109,404,903,652,967,618,789,146,930,115,496,22,653,250,303,885,147,200,614,71,869,812,515,509,410,783,957,19,281,587,284,383,165,799,335,843,926,507,170,897,369,965,7,410,360,250,411,542,693,644,214,140,958,917,991,339,139,430,860,553,651,569,692,393,504,633,787,900,999,734,561,379,155,704,462,987,525,245,989,256,71,945,870,802,252,360,756,154,382,116,693,575,388,796,568,413,576,584,877,357,539,710,623,916,669,627,633,913,683,485,242,368,685,32,711,950,895,625,831,994,175,681,345,849,475,681,714,237,623,831,268,890,790,641,597,800,170,303,526,136,173,270,314,836,538,436,868,450,863,960,402,689,983,419,954,5,784,297,31,168,251,929,388,827,216,222,630,139,447,901,192,730,426,836,929,967,724,486,426,259,599,991,67,895,517,221,290,60,983,806,942,991,833,300,493,845,185,441,871,0,178,210,291,716,924,956,246,756,867,535,739,544,654,224,787,2,711,94,111,415,257,570,374,159,376,159,187,809,465,557,426,239,930,736,856,875,654,924,246,76,864,415,301,218,66,344,700,342,316,728,869,938,580,119,88,109,387,379,730,843,891,707,587,245,746,869,564,160,810,143,641,963,980,469,373,626,954,751,582,158,169,996,142,657,865,985,296,585,836,205,405,331,586,690,320,120,736,233,563,568,616,14,814,689,544,706,230,276,585,391,735,245,895,848,90,165,796,580,470,570,169,819,379,491,574,53,713,408,592,308,689,970,614,513,674,125,913,919,63,122,405,953,564,127,687,456,441,244,822,961,180,51,592,55,787,991,87,514,900,250,855,37,240,704,402,568,588,292,601,675,504,449,297,225,450,187,327,684,705,914,339,117,608,553,961,580,12,838,513,225,461,813,742,405,268,503,264,660,68,79,671,291,280,639,927,463,659,309,431,543,904,315,276,81,741,478,649,191,565,295,718,475,122,559,143,169,291,469,452,366,840,113,543,470,396,174,967,907,396,409,101,893,301,911,857,909,520,102,979,117,752,443,348,680,687,585,686,794,685,354,226,45,868,424,48,333,192,30,461,918,741,916,103,79,590,860,669,643,4,575,21,910,46,931,809,933,711,135,39,996,502,510,476,244,326,8,304,187,123,805,207,927,411,954,377,437,299,30", "611,82,234,914,513,575,553,925,260,812,342,335,436,353,769,649,220,234,939,515,860,260,797,863,346,222,704,458,114,414,384,814,125,575,722,34,291,930,246,865,717,547,82,266,969,601,900,333,76,115,959,837,428,16,408,564,543,542,887,503,580,638,946,781,743,679,421,980,16,996,175,738,415,711,16,461,827,159,121,883,868,936,797,509,986,593,685,960,116,847,848,915,303,498,786,667,683,177,760,107,900,999,980,262,220,340,821,898,331,166,187,983,89,274,811,801,766,169,428,69,936,510,426,640,596,77,813,123,875,308,640,562,609,942,229,731,658,571,52,280,155,633,50,231,605,129,418,853,830,314,570,34,53,707,481,449,436,263,766,592,276,673,735,219,791,465,909,753,924,162,910,118,627,983,344,345,298,835,40,391,933,689,256,710,592,534,619,939,649,145,588,287,414,217,771,637,715,821,664,227,635,322,19,572,281,807,340,171,530,784,216,717,866,227,834,647,79,684,901,607,803,128,189,589,61,485,88,316,157,994,219,624,536,274,992,972,817,69,290,593,776,26,133,322,822,695,666,411,195,336,92,416,306,253,471,387,205,905,519,925,935,346,199,136,357,810,261,836,749,144,271,725,317,435,796,37,613,769,528,972,738,109,885,928,173,704,971,723,355,242,205,43,838,188,653,268,815,819,2,805,828,226,969,667,360,417,778,617,214,668,399,593,244,923,365,726,223,497,33,185,184,71,906,939,448,368,318,379,151,286,18,617,993,113,806,703,470,724,659,400,335,582,546,89,694,303,412,76,504,524,530,314,508,502,823,440,223,754,493,516,44,829,605,77,894,766,478,498,634,877,77,820,243,176,514,573,772,947,121,277,828,968,243,716,499,933,581,312,279,146,72,797,604,398,296,950,265,230,128,140,194,697,894,964,189,647,872,169,231,435,996,128,677,95,99,627,815,743,653,113,780,749,236,869,371,563,468,877,608,237,988,698,757,611,169,819,757,644,687,819,146,926,824,634,81,117,272,402,499,67,419,812,934,4,618,562,746,635,856,703,604,836,708,489,161,172,274,607,429,144,6,866,574,976,263,218,804,465,278,61,18,974,744,900,14,471,445,5,205,95,251,428,395,482,113,495,878,264,153,131,867,941,943,592,969,475,978,294,125,254,405,189,448,202,342,366,760,427,325,580,1000,641,627,418,306,730,848,970,329,296,894,325,914,116,676,400,177,484,144,483,819,144,712,731,140,848,549,693,994,935,364,649,914,632,54,431,772,9,296,902,67,795,590,970,695,241,382,947,780,894,680,11,846,840,976,540,918,412,630,495,392,657,273,370,782,196,978,177,106,113,871,251,63,703,913,775,531,958,553,204,81,297,46,742,325,318,175,994,776,592,213,417,671,466,463,510,447,803,976,305,718,73,281,878,247,456,600,66,754,97,779,248,522,164,645,113,311,94,990,957,90,704,995,888,451,906,109,625,792,593,792,925,980,259,52,146,379,341,726,263,164,817,610,363,35,237,72,382,973,536,645,759,795,577,719,302,182,392,14,656,984,628,465,165,331,317,192,729,321,509,97,178,0,532,914,953,118,643,725,879,582,837,796,294,819,60,253,516,29,454,900,885,385,153,756,939,30,224,524,732,601,910,341,86,451,86,460,722,310,717,607,422,398,937,321,226,944,937,403,543,386,275,266,13,371,620,372,105,414,102,102,557,503,658,553,896,525,482,432,119,670,375,127,476,224,826,702,884,820,501,213,441,968,34,527,191,591,401,102,727,419,711,158,286,289,930,96,892,555,100,947,693,859,602,7,389,13,550,270,33,87,193,8,828,55,475,855,468,842,143,873,212,2,317,807,620,677,414,348,374,74,100,130,146,476,826,495,642,403,887,496,370,467,616,630,916,141,981,867,908,876,445,93,929,56,770,236,391,78,208,35,557,811,176,726,857,342,904,242,638,545,154,55,827,951,434,998,769,973,366,137,778,376,641,140,773,909,611,915,420,197,953,992,126,146,590,788,440,10,593,78,41,586,921,633,344,602,899,993,208,150,882,219,193,300,23,164,290,916,206,613,836,7,801,607,597,805,963,422,575,580,261,477,327,76,463,568,77,315,287,147,640,991,903,280,396,977,548,231,343,489,96,44,461,329,233,26,213,829,409,971,371,888,702,917,467,574,454,912,681,316,227,174,637,985,498,804,878,847,655,605,174,901,361,75,772,911,833,103,213,407,851,860,639,879,48,905,829,855,356,777,763,850,941,995,568,501,418,667,778", "998,830,745,500,554,2,287,69,703,675,750,883,958,995,828,239,745,994,95,688,673,719,650,20,820,3,346,457,83,756,950,693,195,893,471,825,384,242,569,950,640,500,128,518,960,486,104,982,304,623,362,868,628,864,974,672,274,617,843,930,944,304,641,163,641,340,587,700,729,12,26,816,289,250,578,670,11,921,343,521,630,532,132,133,625,98,991,700,57,218,138,83,370,919,457,564,400,679,240,799,468,597,941,29,631,78,815,541,161,513,697,324,705,202,514,595,663,803,329,63,142,934,492,258,559,358,121,883,569,751,736,775,591,257,441,108,383,347,534,140,444,43,965,421,92,240,864,717,283,856,61,410,690,281,169,739,247,126,211,697,62,503,211,251,20,893,773,156,304,177,359,251,737,308,538,415,838,247,91,793,50,510,738,388,950,572,262,691,355,8,291,852,603,922,172,132,370,998,810,502,881,402,664,34,804,10,230,151,220,903,300,129,290,789,145,693,254,364,574,697,997,51,650,400,456,861,892,209,565,442,234,588,891,534,16,797,906,974,645,191,451,678,549,141,854,743,507,394,714,69,375,403,811,146,208,640,213,588,278,114,722,56,683,488,74,294,224,991,123,271,201,824,592,172,185,375,665,795,692,916,466,162,976,7,328,525,864,871,139,126,202,171,195,850,316,819,657,819,183,211,391,789,467,980,290,68,370,286,671,180,245,796,125,596,942,929,989,999,346,229,974,572,476,424,382,829,782,755,250,515,443,6,312,253,903,326,788,959,643,182,661,784,829,944,645,732,35,608,520,926,87,73,959,605,792,524,791,333,392,698,781,724,169,598,537,954,45,863,26,888,571,575,715,969,550,3,423,482,931,108,187,762,970,261,391,209,220,86,283,90,175,748,61,771,107,85,509,817,893,547,900,205,299,552,790,823,545,264,533,370,421,161,332,961,660,751,484,267,851,760,867,325,954,986,461,472,899,851,784,74,714,184,692,653,172,436,379,844,869,723,945,765,943,190,767,587,287,955,434,924,40,778,776,645,225,926,748,665,17,318,219,600,329,336,301,156,656,258,565,918,238,261,818,40,796,882,631,357,121,439,381,518,699,556,829,251,815,470,38,973,494,677,974,995,117,682,397,750,690,384,914,92,351,156,547,994,922,43,371,321,543,430,810,334,132,56,50,183,83,713,832,93,527,706,240,30,782,811,89,284,608,290,39,370,122,18,634,717,367,341,909,394,56,762,610,700,324,945,766,491,546,343,590,31,206,128,986,903,485,796,50,175,720,200,39,50,833,186,498,802,427,4,1,856,125,797,142,641,840,828,959,779,616,420,756,577,172,503,761,229,13,295,262,866,646,928,585,217,898,530,131,49,7,192,623,502,117,27,262,299,696,710,200,280,238,769,59,261,477,989,800,873,210,576,752,894,329,797,726,125,986,299,967,27,629,394,704,952,234,70,261,220,597,255,376,112,440,445,200,624,349,389,125,577,567,892,809,540,324,683,315,802,602,72,76,72,512,25,327,849,612,442,980,441,734,787,312,224,604,384,165,933,768,613,978,801,774,982,262,587,809,210,532,0,140,941,242,770,550,313,789,37,262,544,737,246,672,477,431,946,106,288,495,956,932,108,932,914,662,342,809,443,148,597,636,709,661,383,342,158,11,369,205,663,668,722,61,525,60,895,18,281,57,901,175,350,512,272,300,549,454,973,141,627,389,795,713,28,727,727,956,457,675,215,58,250,831,423,72,789,715,574,548,781,333,401,507,500,434,342,154,484,949,677,871,964,72,696,273,567,956,466,487,551,653,269,893,477,821,65,724,765,223,79,180,571,459,767,338,880,270,974,757,819,184,341,326,387,730,271,230,553,390,171,662,646,285,245,910,58,415,439,519,320,172,938,530,131,872,805,847,889,588,684,790,548,573,472,235,199,96,270,531,679,200,176,424,155,869,759,464,758,500,470,17,116,81,201,922,67,970,293,458,398,288,824,835,494,155,899,781,218,239,745,6,103,166,300,303,262,500,843,976,698,235,89,578,67,130,809,138,390,695,558,662,787,619,875,119,232,728,854,746,429,59,416,338,955,823,918,534,667,579,166,113,172,657,238,976,251,693,247,138,268,723,403,248,360,984,361,797,951,718,776,716,166,755,493,327,410,38,675,427,996,387,421,453,329,136,26,576,52,973,783,403,876,721,228,39,839,505,801,225,511,739,826,308,386,145,137,966,605,137,198,975,198,915,929,804,192,526,535,396,607,394,928,189,424,51,284", "669,22,669,643,997,386,511,78,849,201,525,706,242,512,297,795,871,367,907,860,552,53,483,88,886,428,875,638,85,543,97,726,459,970,496,75,564,574,203,584,820,373,110,30,571,26,649,756,796,249,398,770,100,820,187,482,404,869,441,274,65,366,751,658,348,693,324,691,299,697,743,2,962,756,447,782,797,527,830,439,434,478,340,999,646,632,59,547,607,480,872,552,827,61,699,462,579,501,802,559,108,642,668,607,845,128,399,185,288,799,903,260,653,202,678,610,984,544,720,914,770,178,530,816,698,486,619,409,664,192,453,899,495,994,450,4,115,98,17,118,218,449,174,976,693,841,775,906,179,368,20,280,614,138,722,798,123,891,329,262,183,986,439,525,484,14,65,169,880,368,321,463,792,524,88,70,410,365,206,105,517,694,917,465,752,894,720,841,536,130,255,108,357,808,947,419,960,658,660,889,853,565,211,816,182,913,760,510,88,319,297,998,968,499,585,783,506,512,522,604,356,677,779,419,247,834,608,701,497,396,243,789,538,659,879,749,132,242,443,981,251,173,24,607,65,751,900,30,270,910,953,138,286,483,25,988,321,253,888,313,473,528,309,91,485,912,112,639,953,864,576,276,339,156,320,529,593,626,960,901,422,796,276,220,328,120,847,464,222,579,509,543,960,288,6,375,700,694,993,222,942,952,836,24,96,185,30,851,993,833,394,395,526,609,391,461,467,489,375,358,435,416,830,751,791,852,919,498,670,942,579,326,281,248,187,265,932,269,635,135,308,889,92,482,796,409,950,499,102,32,439,494,98,344,133,632,576,202,59,690,774,45,184,913,255,649,876,528,210,576,258,400,560,947,349,534,696,248,467,817,93,530,112,45,20,499,711,923,123,230,429,648,689,144,969,452,621,147,600,708,579,843,447,69,363,89,378,514,201,544,354,259,570,724,446,719,749,740,409,574,103,907,667,789,476,89,892,603,495,101,420,324,660,982,342,401,902,4,822,476,158,226,383,512,292,275,982,410,486,614,813,110,514,360,912,586,454,901,752,822,221,326,345,239,649,333,810,546,715,686,885,872,891,919,877,80,62,258,810,495,70,136,561,471,695,372,344,964,788,244,708,810,104,693,636,174,456,948,349,328,643,412,767,858,6,609,93,456,333,640,861,340,216,231,626,500,608,791,912,785,486,57,693,536,543,789,396,217,289,107,447,170,346,797,869,368,246,580,380,129,147,316,711,183,933,396,899,886,94,29,895,388,690,899,78,140,796,733,916,265,768,224,242,271,292,1000,912,164,691,436,668,667,499,587,24,79,364,932,528,209,413,510,578,891,470,244,744,662,779,878,586,33,149,102,390,341,702,988,833,585,261,43,616,534,388,980,528,804,795,370,494,671,399,402,515,583,249,879,749,371,949,73,563,700,662,271,496,917,845,895,831,847,352,738,161,178,679,831,302,386,684,953,97,870,996,873,664,908,356,980,217,128,666,314,377,511,422,64,314,465,529,211,733,507,831,624,103,842,646,494,93,444,691,399,634,572,116,687,926,932,243,427,388,875,503,960,964,678,422,754,399,291,914,140,0,438,43,500,82,456,757,382,242,120,814,730,388,508,34,49,173,820,357,592,423,117,582,664,403,57,822,12,112,890,692,755,401,874,596,838,314,251,773,668,525,792,903,152,45,909,122,602,675,128,784,607,190,891,576,415,899,442,619,694,550,799,799,358,315,854,900,282,155,493,513,584,909,551,51,832,241,857,103,540,532,309,134,77,844,49,307,774,819,209,473,509,915,605,746,811,72,605,521,809,240,973,10,147,944,803,766,903,880,10,291,5,506,882,869,342,78,623,316,131,474,874,175,801,184,346,425,194,621,199,603,265,210,588,950,882,294,80,909,909,323,401,558,624,727,372,299,298,976,387,973,534,65,419,333,927,528,997,304,409,390,951,874,734,152,882,713,955,13,967,193,135,246,143,445,986,540,575,729,165,946,706,867,37,936,227,29,789,940,300,363,200,747,716,331,805,584,632,689,938,421,511,877,454,735,376,243,432,685,768,713,32,753,108,308,511,954,617,642,941,296,988,797,448,769,809,689,208,331,590,33,393,623,935,691,967,615,394,230,481,24,28,407,152,357,184,372,203,199,549,403,565,431,527,335,377,589,397,258,308,86,235,471,769,818,244,617,247,551,828,499,875,301,434,616,674,133,741,766,793,665,203,135,848,496,303,138,721,300,935,112,210,499,292,482,373,887,676,726,730,858,667,605,144,802,248", "350,865,47,579,630,120,891,795,295,556,24,231,54,82,931,536,13,473,368,341,471,480,169,333,630,621,741,78,383,424,762,290,171,326,323,854,423,216,571,914,193,860,704,742,470,153,779,164,607,907,32,152,579,315,993,4,20,824,130,569,875,518,345,547,665,69,4,139,497,93,252,49,459,38,558,676,550,628,39,54,499,762,601,592,128,462,706,466,279,875,5,828,811,844,961,751,53,653,635,6,283,409,514,371,48,520,770,326,84,104,349,943,547,779,548,936,530,541,926,784,722,390,313,599,737,486,690,847,260,834,976,735,940,577,298,594,414,933,273,860,450,497,766,617,80,416,551,883,530,790,318,432,123,919,49,159,118,799,994,593,109,580,371,934,830,401,663,427,146,344,367,592,669,107,515,442,364,823,773,165,195,83,970,744,137,758,922,206,311,659,286,993,459,106,230,287,116,132,566,147,348,223,43,357,557,822,323,79,818,841,335,908,631,77,548,794,131,739,708,796,751,380,340,294,125,8,198,650,909,568,817,879,597,767,970,432,288,963,803,143,846,417,436,418,122,97,514,269,881,42,134,783,188,737,369,300,801,554,460,352,895,312,354,157,734,451,982,510,467,846,424,641,202,38,165,401,149,254,348,143,596,966,857,662,79,418,266,822,359,124,989,97,419,373,80,271,425,993,152,904,929,411,718,805,450,976,589,426,902,512,664,716,643,834,13,289,749,47,578,537,354,5,972,946,303,495,352,371,131,966,301,815,731,389,323,633,637,589,884,582,426,99,945,508,647,359,592,450,905,583,29,207,902,71,306,633,52,252,411,673,507,861,195,591,15,153,73,396,662,594,640,927,9,431,42,203,228,905,259,210,362,912,801,541,277,641,111,597,737,712,329,51,37,246,385,205,464,227,85,803,416,759,424,384,890,227,507,595,438,734,898,167,243,462,539,609,109,384,435,761,728,452,318,390,529,175,720,542,408,321,318,15,316,46,471,558,265,244,772,955,523,321,977,731,394,296,162,400,472,633,554,506,947,221,469,792,86,427,520,562,838,48,891,928,368,413,111,260,527,865,715,726,734,512,706,354,288,766,744,982,631,819,818,903,529,573,241,829,251,506,618,66,106,19,998,570,974,461,908,625,970,606,910,466,182,85,775,979,409,986,417,595,652,362,163,578,393,902,203,970,551,29,619,586,750,76,412,58,925,10,187,663,874,264,853,206,716,617,724,745,992,211,674,893,707,509,900,21,825,690,251,882,256,792,980,995,660,394,701,909,995,306,985,793,188,362,697,762,565,638,189,957,224,318,158,492,105,435,418,369,897,290,231,130,595,633,662,432,377,594,81,27,411,355,515,275,523,151,749,684,525,990,304,627,455,124,240,46,744,726,854,587,569,828,422,980,810,62,651,739,169,413,569,615,617,269,722,991,313,365,459,311,474,483,713,577,58,457,950,105,491,938,675,132,502,483,165,835,719,91,276,392,983,465,342,152,436,290,73,84,192,217,161,982,158,552,656,217,615,861,790,484,216,951,10,856,391,110,204,405,574,293,711,352,557,117,846,301,550,968,530,716,953,941,438,0,192,255,109,491,173,386,60,520,642,806,195,973,146,902,327,719,40,56,426,162,818,892,421,995,832,855,566,355,351,756,14,237,309,522,734,903,780,239,108,152,61,500,999,283,170,417,904,364,197,367,578,351,634,187,619,46,836,834,246,604,376,435,207,844,991,185,745,868,921,803,754,70,296,204,952,688,714,301,315,258,922,536,150,341,322,509,345,72,692,241,458,39,692,696,33,523,434,686,824,329,533,314,716,681,782,120,443,347,143,469,820,334,208,608,718,607,578,263,410,7,933,254,486,932,254,61,97,162,485,748,380,644,709,497,737,161,232,144,266,629,944,864,521,856,636,966,920,876,740,943,806,931,983,408,41,341,963,342,134,860,416,898,972,811,34,78,795,824,876,740,38,408,779,753,768,360,532,604,248,394,139,158,68,812,681,546,941,611,604,843,7,606,596,929,768,512,396,838,666,116,665,423,346,450,644,894,342,286,351,503,893,592,109,605,151,401,955,892,904,650,66,175,818,291,576,659,679,597,673,69,58,196,511,447,540,466,319,373,104,12,708,500,434,513,3,926,314,619,569,215,554,378,238,117,259,980,939,144,753,97,512,956,578,47,404,878,229,973,326,58,252,982,400,457,970,315,546,290,233,293,84,763,612,6,444,662,775,90,349,519,595,959,886,506,353,600,41,244,629,443,252,674,594,831", "234,589,270,508,52,896,537,821,308,970,147,75,873,226,819,76,933,960,563,742,726,686,383,966,358,353,167,670,960,217,198,653,27,459,797,792,386,425,238,118,48,616,954,217,507,699,908,112,718,868,804,568,874,134,919,662,210,635,81,300,503,687,256,146,389,476,781,497,418,113,359,963,926,311,720,210,857,316,260,300,118,366,43,399,586,474,533,644,364,929,771,903,108,944,968,356,881,343,381,51,727,203,524,908,469,972,247,661,546,432,323,483,108,783,470,522,952,99,460,845,227,177,857,488,131,391,901,462,387,282,941,146,154,363,449,975,814,148,193,398,141,406,986,648,738,403,541,177,662,81,47,319,267,571,674,716,169,963,279,666,461,872,125,598,912,723,588,820,977,508,898,541,198,703,590,752,480,842,718,809,963,85,986,918,805,300,946,545,41,563,168,329,573,911,479,421,64,961,633,545,314,59,284,74,862,781,165,889,205,59,442,342,79,504,496,248,42,971,277,611,458,348,37,71,946,232,756,887,445,559,38,287,287,717,933,935,324,380,669,581,209,724,908,555,986,483,290,489,614,204,364,216,701,955,345,596,869,702,142,747,787,672,698,412,149,736,199,894,180,46,898,727,203,593,388,810,125,817,878,970,291,738,416,820,449,447,488,355,884,342,276,697,160,521,408,723,849,984,921,940,768,504,920,904,209,795,989,69,14,947,861,632,384,366,749,283,30,405,623,569,935,66,59,182,728,953,942,178,708,471,87,407,959,8,61,143,930,139,741,332,873,123,655,418,227,870,538,207,638,226,618,465,312,706,863,793,714,316,26,51,832,75,992,729,810,794,980,716,259,382,834,178,811,575,591,194,670,820,404,243,829,717,808,486,131,60,401,48,668,569,298,941,431,150,923,287,186,834,408,935,70,311,187,520,758,324,955,602,273,829,650,76,21,653,71,61,703,480,178,421,37,369,859,670,944,610,958,128,592,750,109,13,717,490,274,209,936,890,49,917,25,459,776,307,162,119,831,989,550,15,839,707,429,527,630,704,994,252,504,826,69,154,901,43,601,1000,987,796,614,610,682,572,134,187,828,903,276,536,224,705,664,448,767,679,821,432,62,585,515,417,903,647,8,560,9,447,331,813,406,989,372,245,274,919,540,584,37,312,609,643,71,845,730,527,198,590,872,590,590,851,579,52,801,355,444,646,458,645,375,517,704,837,789,570,189,419,665,475,530,128,353,622,946,860,385,639,969,493,510,178,285,467,487,876,626,23,920,300,438,721,473,225,296,887,709,481,144,501,341,352,545,808,759,676,650,664,864,275,1000,96,706,241,407,949,202,195,818,766,870,810,742,560,705,941,870,868,370,512,194,679,707,519,944,889,236,572,453,633,798,461,390,317,519,677,161,278,810,90,671,355,781,699,703,784,296,438,17,821,830,724,354,156,408,604,290,221,866,919,336,9,414,287,349,887,118,349,285,688,229,502,427,26,507,132,715,809,722,932,959,646,155,226,641,368,969,255,133,514,377,601,8,78,974,505,715,281,291,259,219,174,246,984,892,20,369,791,138,522,902,520,852,924,118,242,43,192,0,81,519,220,715,6,836,256,781,398,472,781,988,849,908,154,735,181,841,111,627,562,790,484,6,891,790,459,527,69,472,194,60,533,596,755,823,746,624,105,441,627,771,215,600,616,978,608,444,921,324,352,366,841,653,828,874,828,526,19,157,598,517,964,729,441,807,952,5,835,971,759,951,162,47,793,696,631,979,780,132,532,155,394,408,146,906,32,550,518,668,10,744,68,323,421,499,809,499,525,68,968,370,595,767,519,165,111,215,993,78,606,872,711,178,701,115,855,974,938,8,484,752,722,584,252,278,930,7,159,114,433,40,568,171,618,353,846,32,346,984,257,425,955,11,88,49,913,813,407,23,289,869,832,552,601,188,947,994,678,142,492,628,86,401,323,829,621,270,282,836,268,198,198,434,122,976,995,792,130,627,865,241,92,312,150,224,15,496,556,179,637,478,160,34,198,467,332,667,45,154,782,582,930,165,721,329,405,684,995,957,261,745,612,878,757,316,209,426,13,727,925,746,21,492,888,862,715,731,710,86,669,138,723,767,944,535,723,492,685,118,436,228,507,35,877,466,661,931,162,997,388,939,731,174,668,697,294,63,800,514,304,210,388,41,504,610,838,336,421,942,714,284,177,295,950,597,762,946,827,528,403,205,896,911,322,701,570,259,407,490,207,815,312,955,47,524,601,106,250,405,635,572,477", "272,375,799,878,938,422,243,888,739,541,834,580,539,686,147,20,436,562,816,318,619,904,654,588,905,150,813,404,90,275,98,419,193,734,447,153,885,110,902,481,801,734,43,877,917,768,159,885,784,809,568,238,177,942,912,83,286,380,672,422,358,929,349,702,585,638,922,958,567,304,610,653,907,57,70,629,520,914,655,232,473,377,610,774,920,754,168,931,556,190,732,36,878,729,877,562,395,838,35,450,250,995,836,590,908,889,2,690,733,799,957,49,798,698,293,761,292,956,715,531,701,317,133,43,506,606,327,343,552,622,406,566,113,584,128,201,779,979,461,223,637,429,180,205,246,376,112,146,390,370,927,827,756,42,149,551,595,250,123,646,954,996,930,65,249,689,752,137,694,949,788,916,994,147,291,84,825,394,120,371,15,21,586,908,699,336,639,565,720,883,309,468,388,247,981,612,779,715,826,994,748,795,937,438,376,219,943,529,246,87,709,182,983,879,583,210,840,261,592,71,584,931,892,25,406,620,545,119,361,874,345,231,90,506,18,99,239,437,771,908,595,720,438,944,707,897,628,184,481,684,220,440,371,627,860,84,146,752,858,731,507,646,410,410,284,540,83,664,837,27,479,34,622,842,92,70,685,735,401,509,337,845,764,118,647,384,658,532,136,738,502,776,47,80,906,198,629,955,66,553,214,905,898,564,967,662,246,566,805,413,598,195,305,356,150,107,886,230,75,144,118,894,14,410,717,723,183,959,203,881,566,992,434,477,539,173,595,741,564,870,165,79,624,495,620,231,623,641,628,778,297,751,177,542,912,693,409,663,287,637,383,91,878,608,167,953,515,555,667,835,830,471,353,709,480,386,382,11,815,299,592,126,830,260,396,170,928,525,46,599,377,536,347,425,33,573,750,149,980,996,957,613,135,893,286,660,446,455,240,557,756,335,699,717,718,63,32,204,422,750,507,150,935,294,760,95,218,764,133,985,753,250,565,348,129,587,463,697,495,269,701,229,171,673,237,568,988,241,268,375,337,855,748,348,878,713,595,240,719,931,670,56,903,526,426,346,105,428,239,702,591,105,892,749,36,278,35,708,201,873,46,747,845,412,807,155,286,3,18,294,689,199,63,366,827,130,307,626,919,129,521,807,266,623,939,476,788,233,85,593,992,101,918,242,178,438,461,205,705,939,575,93,949,430,236,946,863,383,82,175,913,446,33,663,978,303,117,262,555,915,253,909,914,815,43,798,86,463,217,829,897,1,457,16,906,13,552,798,581,567,452,656,737,983,875,831,838,448,678,970,256,930,896,750,129,556,749,393,823,936,661,907,789,75,592,936,687,227,154,127,699,292,190,874,552,894,44,234,149,792,215,637,25,447,595,879,584,318,968,17,361,729,504,819,154,948,810,85,185,583,128,528,422,996,395,963,220,854,750,516,229,224,690,709,902,779,162,245,912,828,927,191,820,444,793,687,255,911,573,240,315,918,192,922,970,528,989,557,728,869,503,678,376,178,564,18,390,980,560,114,195,410,403,643,394,980,249,508,799,280,900,208,413,365,2,921,140,383,685,792,342,956,643,770,500,255,81,0,684,441,165,372,524,685,62,744,514,129,113,295,137,211,653,724,750,678,412,744,826,902,507,92,720,904,769,891,926,675,493,517,447,864,383,795,167,47,778,582,848,6,368,972,607,243,922,359,157,214,212,239,410,160,940,969,421,502,195,304,74,418,197,272,181,437,54,132,438,363,817,295,715,613,306,200,742,910,694,911,773,233,507,747,537,863,963,796,862,802,399,690,653,274,649,937,643,237,669,177,359,842,300,189,875,88,478,201,776,530,8,708,307,29,821,610,718,179,481,339,496,696,666,139,115,439,425,282,161,702,125,998,472,392,336,101,319,925,930,460,16,229,287,861,596,414,823,616,551,846,942,290,742,332,990,330,46,546,880,770,975,799,955,484,20,18,743,159,609,255,457,84,42,502,124,567,396,792,254,745,60,412,145,540,644,150,956,445,784,487,588,244,284,243,347,199,480,795,165,520,615,901,507,120,535,218,895,922,58,1,706,326,911,879,909,424,880,309,968,572,18,146,55,568,430,423,506,542,719,463,945,893,152,883,577,548,283,401,279,931,81,112,399,406,340,561,981,336,980,128,890,788,123,794,119,563,558,197,572,607,158,47,909,532,689,202,551,83,523,260,747,380,542,761,881,293,998,789,171,799,311,248,955,225,148,263,74,70,883,608,377,601,570,197,38,323,224,218,70,196,582,156", "149,312,300,52,264,569,101,297,534,530,174,380,740,79,123,447,464,393,949,71,730,266,496,174,463,496,184,461,577,460,557,58,6,215,149,103,591,112,148,210,172,949,846,535,631,631,389,303,852,1000,482,143,988,127,220,254,435,4,711,684,665,530,564,243,70,382,523,239,432,248,917,996,937,432,375,31,152,551,306,419,862,607,815,673,184,552,31,910,420,254,593,824,589,934,884,991,460,131,919,377,854,270,134,899,388,316,764,62,84,444,748,366,489,42,572,773,225,266,217,171,479,639,912,683,71,420,652,453,293,993,814,637,551,777,725,852,521,448,274,547,528,863,532,361,414,841,190,676,712,144,138,229,802,328,573,597,238,637,665,568,304,130,232,342,265,49,844,506,72,968,662,589,402,308,623,533,220,313,301,10,109,676,304,31,678,678,93,764,24,501,437,61,670,411,964,713,330,966,729,139,68,238,883,522,70,145,874,945,835,931,383,978,315,267,780,573,136,755,22,445,93,630,163,872,252,479,149,730,802,222,853,437,545,848,262,986,885,443,559,735,356,658,928,14,530,140,606,696,823,496,751,604,29,372,157,649,660,239,312,273,943,916,77,157,933,29,952,974,272,710,160,512,161,142,496,766,254,605,981,182,662,811,257,961,681,221,674,202,702,416,170,329,629,953,749,948,264,992,750,823,414,757,427,507,748,439,614,671,215,438,249,898,810,757,352,948,471,365,916,211,214,784,648,337,320,886,892,618,23,880,717,235,189,363,574,504,538,512,596,637,754,371,795,662,636,485,291,29,825,226,973,22,869,774,948,454,259,594,427,107,413,299,240,230,368,296,275,262,194,596,28,636,138,756,190,327,530,478,476,954,203,204,8,523,254,489,661,281,506,527,54,845,557,185,384,599,686,509,934,548,387,264,751,169,535,667,160,789,590,643,878,973,581,79,500,346,653,404,135,851,264,897,918,322,917,214,755,397,181,864,123,686,531,779,233,557,869,574,914,152,858,895,171,42,861,950,468,125,961,866,280,28,781,616,161,655,762,265,84,955,671,505,813,19,726,82,152,987,126,58,808,949,764,267,18,41,243,168,60,349,436,513,582,308,8,740,733,562,168,642,216,433,86,11,542,467,125,156,726,883,807,88,981,212,826,190,283,319,673,331,612,762,517,271,682,851,183,129,24,129,312,829,577,524,922,181,273,821,987,386,606,250,36,700,278,55,514,826,453,188,751,212,479,699,179,740,894,471,985,300,98,65,680,185,621,730,566,634,92,290,966,307,636,380,867,646,444,456,995,270,329,392,504,115,686,909,518,514,945,813,25,336,238,547,100,324,342,157,679,254,525,189,733,323,282,351,846,936,401,825,247,66,178,46,82,289,955,596,62,907,37,19,17,790,981,358,658,738,606,47,846,559,396,408,989,458,96,814,341,966,604,609,236,818,239,516,248,104,957,241,717,370,655,740,120,143,150,899,258,276,689,903,247,691,687,858,357,134,987,532,510,811,779,280,611,363,84,744,570,653,41,22,738,357,913,982,144,901,585,12,831,195,127,295,621,383,173,276,635,902,132,246,725,550,82,109,519,684,0,320,812,967,814,570,997,285,342,859,378,441,410,212,328,242,845,82,897,602,397,654,874,966,858,598,102,616,440,900,327,9,503,275,428,222,814,450,816,419,770,284,314,66,381,204,770,195,252,725,288,172,410,802,662,647,568,164,106,424,459,574,896,588,799,414,447,35,108,763,393,866,404,976,329,298,17,204,452,489,754,324,811,254,81,742,529,881,872,897,780,830,127,263,910,347,845,477,20,912,884,354,618,816,21,468,255,285,554,61,306,153,459,688,306,316,732,327,927,491,535,297,927,422,138,856,503,720,993,339,907,71,627,605,164,935,517,252,419,63,502,394,68,461,282,646,491,537,413,721,204,722,293,216,137,430,650,568,411,480,292,992,147,585,980,936,907,669,415,888,434,810,635,390,801,333,451,826,562,451,731,696,594,114,544,860,647,774,920,305,242,871,228,55,196,18,756,764,623,920,207,23,162,433,223,299,616,954,422,591,185,949,256,628,997,485,420,976,299,298,743,902,867,913,37,272,198,748,112,90,264,272,600,39,473,524,288,876,383,579,310,68,658,305,830,530,971,233,334,873,439,942,13,32,508,221,634,874,34,485,853,328,988,10,146,516,30,168,979,371,8,104,911,800,861,615,643,408,201,716,182,255,521,733,628,338,81,521,542,998,974,590,280,50,983,716,365,2,423,268,329,9", "714,626,67,830,872,189,532,479,559,354,439,835,864,511,723,182,457,705,501,675,263,979,620,506,948,940,549,242,910,280,284,823,603,936,846,827,98,144,211,664,885,944,709,270,613,653,887,545,341,409,999,457,677,810,324,100,694,581,609,244,92,656,887,688,583,274,411,740,722,587,421,324,130,93,738,589,946,1000,761,242,519,425,836,846,439,859,420,295,187,389,910,555,440,894,975,561,884,974,772,104,138,988,656,990,943,383,242,730,979,642,381,502,410,876,767,135,103,356,214,831,363,24,846,296,771,623,802,128,501,967,290,348,744,327,117,95,302,743,707,256,302,446,372,176,480,10,994,532,696,896,456,970,998,411,150,543,542,384,188,243,785,510,388,273,710,382,141,975,895,647,513,715,47,369,112,612,721,985,753,929,62,498,983,167,307,912,733,488,642,504,500,33,592,558,592,530,336,851,491,37,531,587,18,713,422,48,759,740,858,990,947,546,25,542,999,132,854,762,711,801,79,873,926,660,415,825,694,92,634,209,79,214,72,227,454,683,767,127,499,112,113,218,615,358,656,644,642,789,877,394,306,346,867,807,112,571,450,203,992,669,201,33,936,182,13,406,910,897,830,170,568,535,186,584,458,892,982,125,85,38,920,564,613,258,163,971,457,300,125,63,333,892,784,94,325,846,948,772,869,921,28,461,542,850,695,810,242,291,651,449,351,151,917,957,392,223,842,364,975,32,277,679,871,348,432,689,567,705,326,859,785,317,129,197,805,738,504,541,277,190,970,177,502,110,433,594,469,214,135,380,614,819,134,936,588,721,569,606,984,509,418,164,740,721,249,361,260,652,170,245,754,489,856,639,579,524,245,700,514,451,885,609,979,855,116,567,972,484,896,615,609,326,209,24,621,126,129,928,788,842,919,716,410,680,325,297,60,452,669,633,767,239,355,508,553,786,178,389,863,446,105,487,219,41,965,685,507,54,109,254,499,106,120,898,268,867,497,494,265,797,790,363,443,644,617,169,393,226,538,547,900,430,905,654,997,787,645,842,653,838,520,645,466,295,363,855,34,998,92,481,459,331,458,463,376,661,556,528,953,684,701,474,771,629,476,65,818,534,456,196,162,856,671,412,272,993,808,955,4,578,77,770,495,620,659,663,429,815,146,849,433,443,397,89,118,250,747,16,217,36,530,874,660,272,514,871,337,437,918,410,594,323,431,562,183,457,467,875,41,222,400,178,161,757,22,750,77,714,613,669,428,384,561,266,283,401,232,42,730,769,696,588,46,606,952,813,47,772,390,913,737,969,287,603,35,901,502,298,161,771,917,926,533,24,38,753,352,551,537,484,385,954,123,111,560,527,666,504,131,401,468,253,758,151,199,382,983,590,429,39,862,939,740,740,235,156,549,392,210,815,696,127,67,83,157,68,261,495,664,271,696,72,924,525,695,603,926,883,95,737,323,37,506,927,356,16,470,583,320,157,265,563,467,564,129,465,758,216,386,356,660,489,641,114,210,569,69,563,614,570,626,653,666,434,746,951,549,595,180,716,957,118,158,416,220,833,247,657,893,888,712,756,879,313,456,491,220,441,320,0,254,192,341,990,256,932,598,429,51,847,44,587,799,548,518,75,739,95,433,843,827,619,819,750,728,557,516,57,682,3,123,450,309,27,458,593,84,570,49,62,139,953,461,388,430,546,316,194,491,118,676,990,789,313,438,279,679,786,144,740,350,867,884,180,369,648,378,669,556,239,162,967,103,275,578,534,575,144,300,151,246,41,747,521,998,169,973,455,34,595,794,429,544,305,802,421,123,738,591,668,672,396,285,507,942,417,590,152,302,601,904,769,875,343,478,244,712,792,983,132,235,855,759,119,248,480,676,287,291,927,55,621,508,976,909,882,902,456,656,699,943,128,87,571,412,427,714,469,426,601,469,530,95,540,149,324,940,287,648,168,429,944,520,53,800,756,346,251,849,741,639,764,838,653,548,83,785,384,691,88,196,489,615,324,189,538,755,340,753,674,152,503,553,468,295,563,706,402,896,311,976,179,279,519,227,635,535,194,659,506,78,363,923,212,58,888,681,381,629,488,504,411,323,322,63,7,178,417,93,943,810,439,812,884,96,990,552,852,771,988,147,694,365,936,191,143,58,471,463,42,804,844,690,916,482,152,343,52,429,519,345,673,675,690,552,323,14,918,56,653,527,74,973,873,547,764,957,727,66,165,832,879,80,736,625,213,277,932,412,533,309,316,896,403,190,251,80,376,499,753", "942,550,102,363,260,414,262,612,298,509,238,735,938,76,693,367,870,816,467,11,242,607,492,425,586,59,628,881,441,122,927,593,179,510,83,151,542,851,514,151,928,717,228,566,234,471,959,157,251,26,945,931,412,937,762,312,395,592,754,165,528,86,761,19,469,947,73,141,154,908,622,211,979,126,57,628,121,143,792,364,410,247,387,961,431,658,24,961,734,365,501,472,420,731,686,119,679,890,846,395,949,840,785,518,858,191,291,944,174,693,137,732,364,429,389,7,945,864,514,372,44,731,680,294,131,379,69,892,306,152,186,694,92,962,246,841,250,463,207,166,181,316,71,309,82,450,406,94,975,923,393,102,47,792,148,775,78,563,835,564,209,518,156,913,756,385,663,382,642,266,705,333,723,97,964,817,702,386,262,195,944,1,608,393,730,588,918,887,877,500,428,908,94,401,762,585,334,678,581,666,824,809,549,62,396,619,503,206,541,691,61,556,73,965,831,573,877,968,724,594,493,91,562,731,368,797,911,577,241,635,55,452,23,292,42,664,146,406,510,264,887,315,932,675,427,340,811,106,413,537,998,159,809,903,617,452,841,404,141,49,545,982,344,567,163,167,730,390,983,78,153,502,504,995,778,589,759,725,718,685,916,222,290,208,903,890,281,953,56,203,806,517,950,193,623,233,780,613,869,742,649,252,679,54,792,350,101,350,672,354,37,892,920,391,291,229,638,868,677,571,513,201,643,249,642,743,200,626,620,853,239,264,75,625,668,103,992,866,39,944,902,346,635,442,213,998,573,6,221,318,855,173,391,660,874,68,101,344,742,224,461,494,521,30,375,161,678,773,983,580,576,663,62,481,290,137,370,89,299,766,542,230,25,482,254,111,775,257,460,411,940,533,662,987,312,427,796,759,363,919,306,200,802,430,89,44,337,814,146,936,307,717,529,806,633,720,898,190,378,747,900,889,910,753,945,237,454,225,688,30,413,78,291,461,310,644,900,299,451,946,360,700,262,612,462,179,921,977,575,48,222,578,844,256,277,494,446,205,429,185,519,297,337,768,451,205,892,740,41,172,223,174,799,528,534,338,163,438,250,772,370,104,105,515,451,43,338,983,959,876,816,968,836,595,898,649,963,2,49,121,932,510,77,111,453,746,368,564,717,389,780,778,337,271,666,414,308,71,294,392,762,547,102,884,670,546,546,193,990,887,983,356,966,355,174,860,888,872,49,375,389,18,534,808,734,212,66,372,786,829,581,859,284,699,157,524,119,208,573,54,60,163,77,417,494,689,212,44,372,8,35,582,464,67,687,42,285,615,942,355,83,580,829,571,920,294,703,154,20,153,555,319,648,297,986,622,944,833,935,525,516,207,62,75,303,880,212,316,130,2,774,280,658,223,550,48,913,831,494,105,688,924,940,727,868,457,60,713,326,113,473,99,778,614,254,626,82,507,251,449,305,597,689,505,362,896,834,65,941,363,573,159,651,367,50,128,506,674,975,932,199,399,596,727,441,393,433,811,807,4,989,880,448,885,714,894,973,821,166,802,815,90,797,241,377,283,164,164,263,674,992,867,582,789,757,173,715,165,812,254,0,402,877,566,625,859,227,282,467,142,467,495,734,159,304,775,429,240,970,456,7,299,468,926,854,778,593,533,318,842,898,284,10,340,325,472,366,893,140,251,907,779,468,939,653,128,242,7,963,897,570,338,752,371,72,831,520,914,180,444,249,6,408,949,510,639,114,179,975,967,671,690,563,121,715,503,259,939,670,938,29,534,325,674,15,222,202,271,827,777,268,162,208,986,163,321,235,917,662,134,402,749,644,105,541,587,797,926,77,34,108,695,346,758,601,653,6,27,300,772,528,299,500,694,72,213,431,987,465,288,227,394,582,778,573,117,314,737,350,12,854,800,979,242,406,993,94,333,526,439,922,277,517,770,954,829,908,929,289,832,91,684,675,826,942,882,954,478,598,495,42,486,601,188,350,368,308,496,514,271,935,855,273,457,860,643,900,822,439,541,107,978,214,826,788,193,838,607,489,519,412,834,726,85,111,537,91,93,219,966,812,36,507,186,201,1000,200,689,87,484,397,772,331,882,7,93,371,162,50,445,939,114,860,654,766,974,252,579,628,561,164,983,935,451,411,136,365,505,312,169,935,782,276,676,539,750,682,871,808,716,950,320,693,623,309,455,689,932,102,287,919,99,573,529,487,899,267,363,367,566,595,108,701,387,44,322,307,567,177,425,656,376,269,535,978,219,805,456,99,184", "501,221,566,921,187,596,223,716,623,949,478,161,301,183,781,39,176,133,83,843,862,601,118,737,816,730,714,20,575,227,205,241,198,724,586,544,692,180,328,158,973,64,792,739,814,537,857,618,580,968,782,464,531,744,461,266,237,213,387,505,29,863,653,196,104,948,380,2,851,843,936,518,627,53,634,821,875,718,660,774,713,645,539,544,753,207,311,447,413,763,947,84,22,433,324,866,246,521,543,858,301,210,584,118,770,244,115,346,94,923,144,32,869,745,30,243,908,59,187,297,811,537,417,796,890,735,158,19,681,14,171,848,344,962,443,982,23,725,821,567,71,245,507,332,721,67,772,846,505,42,14,567,890,311,162,690,704,961,722,575,855,470,763,186,529,795,194,702,794,338,910,88,76,150,431,83,363,824,463,913,110,17,57,775,304,486,110,847,136,996,946,618,154,186,763,881,89,683,834,170,835,721,793,590,403,152,887,617,979,697,605,774,716,337,561,311,291,580,718,921,471,277,41,792,328,599,767,257,653,437,36,611,546,100,720,354,56,449,120,666,930,948,94,28,387,70,646,444,868,763,317,979,509,565,905,122,87,972,362,233,411,719,361,428,509,331,646,796,481,483,931,566,224,107,491,934,491,323,60,112,241,82,550,107,158,190,510,230,205,331,819,904,967,718,391,975,431,971,945,73,871,620,853,982,905,257,156,966,499,372,40,717,275,641,436,577,512,151,680,68,196,710,664,849,309,285,578,136,829,148,274,493,519,643,847,737,843,704,276,158,491,972,109,604,507,129,610,55,617,26,135,886,879,729,850,88,324,832,66,27,997,922,333,701,47,450,203,924,642,130,71,832,853,119,165,644,330,191,692,856,376,546,271,839,616,253,618,613,281,711,330,627,53,963,910,101,29,850,592,734,231,823,50,426,257,292,951,348,86,511,620,442,110,932,375,520,220,85,147,915,296,137,893,271,535,590,595,640,90,292,36,348,454,357,701,316,837,998,118,127,862,380,288,89,591,368,183,605,864,765,483,570,303,129,206,51,124,869,650,899,880,193,562,747,506,42,72,918,189,567,44,602,95,523,430,71,671,337,635,318,897,83,270,58,839,173,951,381,690,190,648,148,277,818,173,943,255,969,754,454,818,27,570,978,383,36,94,286,591,433,527,565,340,635,195,656,163,897,228,393,719,888,918,952,956,87,649,172,981,716,67,508,848,353,207,436,750,464,688,469,682,98,970,894,496,546,201,314,381,328,542,884,144,893,987,344,553,193,233,963,472,63,681,10,299,73,245,709,236,987,105,853,798,139,709,3,71,479,528,724,354,632,37,423,340,830,605,901,818,374,661,422,99,784,962,997,516,289,744,209,219,502,674,492,72,950,803,152,997,359,91,262,801,781,189,147,937,451,453,700,360,550,377,111,138,88,560,159,295,634,112,419,494,938,634,309,862,619,989,112,740,487,957,866,754,973,78,887,538,6,574,881,206,973,783,865,701,105,874,722,819,668,435,548,165,53,436,588,473,863,896,469,570,336,391,853,391,282,242,505,271,625,185,468,528,221,609,535,371,32,384,535,837,37,382,386,6,372,967,192,402,0,318,890,402,164,565,344,813,410,527,848,498,423,47,915,363,494,433,381,536,920,337,48,764,50,690,511,230,455,460,339,685,491,454,503,747,88,534,241,115,202,930,175,394,822,547,13,69,549,8,215,187,14,963,77,568,338,925,34,193,330,619,461,598,618,675,430,675,774,242,481,406,290,170,333,69,275,944,286,256,780,972,542,237,946,722,844,642,37,975,243,130,149,524,447,464,824,258,992,206,988,250,724,575,562,242,597,842,91,526,12,124,417,552,394,553,887,367,501,248,429,102,261,828,266,824,927,681,692,704,564,851,626,388,748,464,683,582,244,562,772,558,561,871,648,552,67,198,907,742,990,411,347,112,426,753,163,583,703,154,19,694,508,700,424,705,338,167,98,995,705,86,705,619,711,297,679,516,82,551,65,273,670,64,967,896,446,626,792,53,223,498,327,917,526,316,15,385,634,486,298,787,759,474,530,879,433,658,295,435,292,77,181,418,870,49,871,900,92,805,871,938,309,726,406,107,366,474,844,985,73,552,339,211,2,157,704,74,765,471,492,607,428,230,980,24,751,13,181,713,439,282,942,243,481,936,561,211,133,96,523,872,460,51,374,703,992,436,856,523,737,122,55,440,780,623,544,678,498,246,760,280,302,817,841,401,312,438,212,661,561,285,272,876,717,529,370,372,104", "378,670,502,839,911,996,948,409,816,266,142,453,983,115,501,144,265,774,328,184,640,898,702,349,523,576,589,345,255,140,87,36,360,233,643,580,618,377,359,538,739,977,227,428,666,758,352,726,233,687,67,363,45,47,573,848,233,658,162,901,731,314,42,587,129,221,968,208,572,265,632,513,354,273,163,993,451,86,377,899,987,558,191,947,552,533,803,510,168,222,637,439,263,956,976,633,685,837,482,465,309,953,867,45,673,367,329,143,410,59,499,245,479,9,431,805,623,331,476,383,799,733,872,774,557,920,863,483,738,919,282,926,390,179,190,932,648,355,411,226,874,691,840,642,875,182,138,933,373,316,883,700,907,787,693,955,17,423,356,457,511,887,303,770,135,679,756,918,216,141,335,981,534,152,665,992,942,278,460,586,889,987,388,531,119,930,387,947,599,634,848,524,194,920,321,436,987,116,843,577,187,549,608,956,103,898,815,121,228,638,644,149,958,901,216,552,900,529,603,532,700,207,195,695,407,991,951,682,921,317,575,726,769,138,438,206,590,25,878,475,686,924,983,260,10,291,609,740,902,402,242,234,438,704,525,904,269,541,992,887,310,560,22,867,469,296,266,964,3,487,438,94,385,983,180,209,587,379,666,11,84,365,68,992,659,459,936,722,359,375,833,915,896,960,133,100,695,504,82,365,738,424,601,36,118,407,769,463,436,672,423,833,543,332,277,334,93,407,890,555,36,738,875,127,251,698,426,427,55,654,139,681,456,41,64,847,857,18,669,738,87,329,961,732,167,855,550,240,628,597,445,882,673,231,255,242,815,807,584,908,218,639,15,897,641,22,763,248,610,601,754,254,243,246,896,743,685,892,834,472,4,734,128,158,313,615,504,358,442,190,389,345,330,497,257,531,232,703,137,173,585,258,904,655,184,724,616,428,478,859,795,710,51,464,170,95,498,728,698,752,811,797,208,265,364,575,714,898,558,741,998,861,30,110,904,487,141,455,371,857,72,120,738,663,622,759,267,934,740,377,30,265,800,551,279,750,710,713,685,502,507,847,276,145,644,899,296,627,261,720,714,728,97,670,639,971,531,854,176,424,912,351,459,977,59,887,931,136,447,290,14,131,549,429,180,607,816,986,294,720,586,915,283,231,731,912,871,66,906,904,555,319,352,395,92,276,572,50,464,635,871,934,83,524,385,41,299,828,649,215,377,266,230,263,354,5,162,52,195,110,751,6,910,883,523,811,608,220,732,797,142,823,565,308,535,427,122,203,721,841,465,410,14,590,107,722,760,633,48,64,724,671,366,21,628,876,317,895,710,396,77,396,489,387,182,424,774,954,764,627,418,334,989,756,502,82,560,72,150,606,108,366,289,434,925,441,256,660,336,76,407,772,120,331,842,908,406,899,191,755,899,496,886,593,681,252,625,421,922,189,906,867,751,789,36,790,230,793,295,658,926,473,824,198,509,472,505,806,719,688,185,428,462,422,438,407,610,404,839,2,987,356,946,450,791,253,39,691,681,375,158,868,562,734,259,300,595,267,695,988,538,636,89,689,154,641,223,509,951,820,484,739,796,262,242,60,836,524,814,341,877,318,0,811,992,188,669,114,529,730,420,124,269,23,896,805,128,159,996,970,639,877,615,766,155,300,195,924,493,990,241,469,711,195,697,355,645,920,882,275,721,270,416,655,771,391,291,7,130,520,726,241,979,24,110,345,628,895,754,746,966,287,319,641,667,50,239,237,157,37,811,732,563,337,133,936,929,294,516,897,360,964,442,204,781,321,43,738,403,805,604,941,916,309,241,67,881,367,55,531,606,195,147,765,660,711,859,505,436,161,433,553,420,161,848,277,627,473,535,684,499,541,636,555,898,115,957,349,530,495,769,576,132,969,958,833,603,121,921,103,266,20,768,917,650,194,372,546,556,481,42,679,656,849,40,666,420,689,266,269,583,993,952,492,96,376,652,427,372,627,804,617,701,749,912,818,840,892,987,963,583,476,493,970,584,633,977,992,920,489,466,97,44,780,620,49,186,193,51,884,115,125,561,389,921,195,774,201,156,940,380,949,629,99,902,814,206,491,779,535,987,873,857,122,514,110,100,556,378,245,625,430,874,190,645,791,146,844,195,60,273,232,240,794,947,443,622,632,453,85,364,736,111,40,965,685,278,886,815,784,88,904,762,378,869,597,826,675,539,429,300,749,893,445,134,715,648,603,287,514,513,148,501,529,811,643,259,539,462,163,37,60,128,830,587,495,511,727,714,420", "192,295,796,113,918,4,859,362,200,468,983,545,294,514,35,135,545,347,592,611,25,808,4,200,122,45,785,199,901,64,432,293,909,307,476,395,880,300,798,986,963,642,337,113,174,747,560,994,390,876,504,29,606,894,420,606,936,974,494,102,252,383,422,719,117,998,232,217,703,240,145,820,85,87,923,106,479,993,215,334,760,317,963,290,701,460,836,76,560,23,524,766,116,814,883,135,651,723,231,633,833,199,691,847,983,825,113,861,503,82,850,750,185,134,455,407,167,34,966,925,256,845,499,917,472,153,929,718,956,184,617,909,981,398,153,155,82,928,740,760,819,547,952,986,906,112,667,910,69,242,79,853,196,803,559,410,620,67,137,195,180,177,536,548,367,70,262,943,298,69,765,692,440,382,290,925,687,331,989,613,786,354,32,820,955,131,716,565,2,791,286,18,691,887,997,498,453,157,887,89,159,835,878,985,243,826,501,337,572,973,991,974,400,135,540,819,995,854,867,188,742,25,101,77,289,89,276,633,115,326,87,452,301,543,329,935,89,423,577,11,59,158,488,638,741,160,218,943,411,663,282,691,144,105,757,743,347,557,180,614,477,536,645,650,238,253,666,900,254,472,336,136,941,755,841,255,90,794,412,554,976,671,902,113,740,570,185,690,794,727,767,3,799,128,774,361,191,370,67,197,242,716,709,313,319,748,144,39,386,3,74,543,916,202,722,967,862,217,410,992,810,425,829,17,410,278,526,886,858,480,906,788,295,265,384,786,5,70,250,228,563,470,832,426,28,583,688,256,678,9,469,238,817,276,971,906,679,741,569,819,562,489,868,633,41,471,539,120,631,295,545,49,333,776,194,563,461,560,368,401,942,645,941,834,838,286,534,112,627,510,818,55,295,653,797,101,405,740,939,876,666,770,336,898,23,177,658,59,157,155,302,517,386,922,85,17,283,629,440,282,193,334,59,904,887,791,237,464,795,759,562,1000,677,215,142,213,476,461,840,121,782,390,587,569,67,874,742,325,128,499,962,835,96,697,196,255,654,952,21,356,982,488,984,721,61,542,911,769,138,130,178,702,922,238,728,503,177,978,834,842,352,650,8,55,613,678,132,852,742,324,632,723,261,233,9,972,433,894,623,662,436,681,365,19,394,25,158,380,723,960,253,343,921,181,875,825,966,353,442,127,120,609,537,704,527,877,329,973,778,772,49,760,151,468,336,992,656,45,834,51,611,826,598,72,73,364,955,25,758,460,430,584,317,265,744,848,708,76,305,893,670,300,120,206,125,874,760,854,913,431,140,825,861,41,728,418,927,106,565,246,534,23,822,557,879,422,578,184,306,401,662,752,476,521,280,715,208,835,474,7,13,918,459,567,526,435,58,894,823,863,373,982,414,887,49,408,932,569,290,709,257,419,73,36,816,270,116,328,692,617,618,873,350,107,281,508,908,137,621,216,712,671,901,608,820,500,328,368,366,83,40,40,349,521,243,180,256,86,841,388,577,807,383,671,145,921,731,299,899,5,541,65,631,433,607,77,405,313,757,845,953,933,736,48,269,979,906,477,59,147,364,544,294,544,120,520,256,685,570,990,566,890,811,0,211,992,355,585,331,204,980,737,179,758,550,68,3,536,302,990,713,840,474,522,453,67,377,657,435,727,622,936,834,177,215,469,879,687,373,978,384,372,713,751,268,826,265,863,535,943,549,376,445,394,740,178,658,27,992,476,456,259,298,62,280,395,96,151,424,222,798,684,117,269,632,631,172,664,725,46,265,874,777,195,30,957,802,710,73,956,767,99,15,326,621,872,273,201,224,317,588,881,240,970,29,873,521,822,339,468,773,149,912,104,193,653,257,695,442,292,314,942,809,552,656,523,500,81,90,709,733,596,280,69,405,619,26,612,855,488,634,427,42,515,209,281,113,139,75,484,393,930,100,56,312,170,348,355,30,2,993,923,267,898,785,809,226,489,575,693,896,285,814,628,559,990,549,221,755,98,979,821,306,528,428,844,762,837,385,7,726,102,390,840,424,350,970,346,767,799,651,903,807,692,282,585,946,35,885,758,434,473,223,462,655,768,838,197,66,879,943,593,67,831,209,57,384,655,294,488,424,610,318,886,41,676,958,278,105,277,201,428,220,675,672,594,752,964,386,422,70,369,749,102,476,352,29,702,289,171,194,186,252,513,343,129,379,406,774,520,715,503,855,112,972,541,548,56,25,302,626,608,266,664,69,162,542,356,971,232,920,52,177,669,241,612,94,652,380,760", "28,353,11,129,541,697,463,543,793,392,25,345,118,844,240,150,909,762,952,707,181,121,457,79,876,981,270,777,991,691,981,724,631,885,978,777,400,132,733,920,365,616,373,418,704,652,490,271,833,495,598,601,659,267,779,640,516,92,958,998,87,713,260,241,991,214,869,721,498,414,669,956,701,485,666,497,111,127,309,666,814,604,862,437,522,691,857,109,190,243,239,404,301,228,353,69,883,240,463,239,863,620,468,85,27,171,356,843,36,472,660,361,586,483,771,527,83,394,877,722,391,923,811,525,196,587,431,470,978,165,833,119,198,234,894,702,145,397,959,68,877,351,575,978,636,346,207,529,601,223,469,683,750,765,436,231,497,598,919,175,223,980,914,247,624,627,53,155,855,144,337,46,22,739,952,756,100,806,302,512,428,474,38,428,682,608,717,226,978,193,639,961,112,396,569,789,579,459,874,250,336,6,114,2,613,557,719,365,885,646,870,287,289,68,208,464,368,673,164,852,806,357,810,421,746,887,387,309,219,959,267,144,22,826,794,301,397,504,245,657,243,772,272,617,580,720,448,293,604,772,648,645,23,970,217,218,503,17,850,144,802,13,623,208,196,942,83,852,322,209,538,539,943,785,561,930,932,856,926,950,591,496,107,22,706,24,922,429,719,619,265,30,272,253,94,957,142,155,921,766,570,263,855,286,388,712,288,976,150,379,931,102,251,986,812,663,125,30,890,346,630,905,545,393,154,247,723,864,570,209,273,637,689,38,580,928,360,650,417,309,753,751,911,145,318,785,577,777,720,836,966,891,715,695,996,344,779,399,567,355,59,791,64,529,265,340,802,971,628,796,359,370,334,187,425,97,633,316,324,655,836,449,916,968,946,872,105,494,494,608,586,426,305,336,621,835,654,571,481,682,680,325,732,707,254,518,645,523,959,296,79,302,235,647,989,221,914,167,494,306,592,113,436,637,62,295,549,677,248,32,745,58,71,458,821,181,13,225,608,61,277,27,478,934,552,242,350,761,791,451,771,983,803,246,58,424,259,391,462,302,176,843,968,525,463,263,595,579,859,295,299,515,894,617,841,854,371,392,423,893,237,392,475,473,358,214,76,921,768,326,261,65,655,743,156,652,351,332,969,994,672,601,307,500,449,820,566,871,328,83,682,319,764,815,991,538,738,246,415,421,305,99,981,508,281,169,991,629,980,837,290,619,320,78,860,14,127,433,657,140,96,444,582,430,524,164,108,713,260,67,127,393,521,367,633,319,697,443,960,678,295,809,696,400,905,936,760,951,241,513,39,120,914,855,270,8,764,432,283,334,115,612,988,169,476,236,727,595,688,78,247,30,319,472,802,757,790,436,447,735,979,464,377,865,519,228,706,394,927,534,809,135,76,628,498,7,652,745,115,577,237,773,306,253,595,779,661,813,208,738,242,902,880,881,652,33,58,827,59,288,90,534,797,580,265,499,9,361,835,182,388,60,66,599,869,923,361,754,761,445,424,95,607,359,955,977,526,204,941,172,958,929,271,21,253,592,230,852,206,745,664,604,588,244,53,796,544,235,637,43,862,654,819,737,814,642,781,62,997,256,625,402,992,211,0,422,838,711,8,602,118,305,63,307,794,712,651,23,919,131,653,353,338,170,671,69,684,380,607,675,92,927,535,186,117,340,498,207,160,953,563,643,2,799,896,134,566,337,732,383,768,250,318,992,907,881,639,804,360,392,420,348,771,264,439,943,425,186,348,914,402,715,593,543,585,317,308,915,684,217,478,510,655,186,901,795,201,695,570,995,86,513,138,652,39,780,167,355,694,880,81,700,203,593,350,79,588,137,972,779,202,390,686,942,482,462,768,950,518,106,199,341,536,144,159,536,634,728,937,597,255,324,74,999,808,461,328,318,553,837,629,335,825,282,633,536,31,622,930,478,896,411,411,267,298,999,429,129,540,875,491,975,574,499,664,918,910,410,828,59,924,484,58,420,49,826,754,160,229,768,588,829,871,311,742,379,104,777,841,176,240,498,229,380,725,204,790,57,325,296,929,614,747,983,741,730,342,957,800,411,419,400,943,855,946,756,716,359,37,244,488,168,631,920,902,53,198,12,282,764,757,712,413,40,853,832,301,80,569,129,203,851,630,926,474,43,268,798,361,441,454,632,532,584,47,591,125,717,493,252,214,558,458,671,971,709,593,315,347,847,755,679,476,423,156,621,399,903,605,283,671,713,174,844,638,216,392,503,500,215,590,228,372,38,981,966,345,931,352,771", "891,690,186,710,328,939,91,452,514,393,864,438,223,964,783,544,457,381,109,256,737,721,50,728,235,546,778,834,254,835,924,690,478,698,213,3,777,595,993,462,828,119,756,183,456,476,354,660,976,233,377,915,776,377,688,364,150,605,475,72,586,134,819,77,843,148,675,745,865,792,387,781,788,162,296,515,593,652,975,942,680,913,327,458,896,295,946,513,260,115,636,30,25,117,919,4,548,490,167,33,251,710,353,668,373,306,806,505,645,735,380,663,899,641,935,835,474,197,330,117,346,714,390,781,609,826,439,60,451,303,810,590,76,236,337,632,546,955,144,833,278,535,670,603,421,898,994,634,74,121,196,82,739,598,84,915,171,356,43,398,165,41,114,453,278,239,897,175,156,670,579,121,931,724,990,722,206,774,540,248,753,503,130,238,455,708,282,366,594,363,316,312,418,337,527,533,908,671,212,29,37,132,133,16,835,169,595,722,83,773,12,327,407,975,964,985,716,873,287,171,8,879,841,205,294,949,861,545,876,864,7,996,440,225,217,1,790,595,442,652,315,521,472,323,609,895,750,657,237,139,625,201,911,379,554,661,250,711,972,926,25,788,413,874,753,9,566,945,742,847,813,398,633,447,465,927,115,723,30,729,192,891,58,636,80,263,260,983,366,923,777,582,545,12,954,373,960,194,45,198,586,589,319,247,42,481,415,817,107,144,432,442,817,692,433,994,23,913,685,666,973,29,634,285,936,330,498,635,889,856,885,520,739,63,634,492,830,128,761,867,948,153,256,400,533,312,316,939,166,54,855,305,594,293,936,94,136,616,581,142,873,419,271,4,737,529,21,106,443,158,624,228,556,493,34,255,475,700,674,686,724,878,352,851,101,161,966,595,680,54,153,585,35,738,549,39,338,896,139,28,231,526,9,935,705,786,582,82,855,350,54,894,330,457,83,284,740,344,616,447,53,718,971,96,251,421,466,845,587,345,416,576,284,416,733,519,89,138,426,949,472,85,95,49,539,922,177,989,877,246,403,360,506,752,322,713,969,632,256,224,27,701,393,770,486,168,375,616,927,484,140,827,182,436,831,737,961,556,330,614,205,396,590,705,577,750,286,816,839,163,244,94,503,318,961,515,642,677,621,114,359,58,841,214,387,661,965,806,646,362,314,460,296,484,793,556,232,639,562,882,965,207,850,186,140,601,307,407,460,719,453,675,617,35,838,435,823,797,230,525,730,332,128,415,694,825,418,460,485,496,670,640,569,756,538,945,496,813,191,570,76,97,481,781,897,478,38,776,985,468,385,879,277,585,318,104,649,118,223,814,633,18,885,101,969,82,117,671,338,527,72,417,964,455,797,659,450,806,53,302,886,600,155,963,380,697,461,781,547,68,661,203,792,2,460,756,311,604,468,973,676,582,90,198,645,494,202,291,62,225,919,460,629,983,829,45,757,265,240,674,245,674,413,984,245,905,731,35,46,478,6,425,636,985,959,118,148,172,168,916,286,454,289,553,735,887,458,585,908,884,83,677,768,310,449,815,71,328,530,649,937,104,803,642,72,469,688,649,858,104,488,224,60,246,730,806,398,744,285,932,859,164,188,992,422,0,388,729,148,156,429,965,156,404,581,43,365,934,25,172,507,901,184,698,377,421,490,819,694,414,606,269,157,276,809,779,102,690,983,651,72,453,886,582,873,569,765,303,107,315,892,906,616,982,737,963,211,466,60,810,246,226,308,303,540,606,672,602,188,499,666,476,490,575,981,97,782,822,174,453,198,172,892,671,460,250,827,989,92,107,288,862,590,537,723,462,186,6,668,908,224,276,997,67,5,121,723,905,465,261,669,977,895,88,292,556,43,781,396,124,361,542,756,107,805,102,682,687,778,950,779,753,541,422,371,237,864,346,321,359,6,924,995,762,571,691,84,383,50,167,573,986,492,153,130,789,952,988,58,875,986,90,376,266,373,892,440,581,925,574,70,794,541,124,40,170,285,191,61,283,980,532,812,155,900,104,448,801,589,809,505,519,941,844,590,332,159,142,688,759,910,737,65,925,669,393,792,576,449,947,646,256,601,621,514,924,609,106,754,412,710,929,833,792,930,99,671,425,676,146,55,628,373,569,166,94,401,26,573,320,640,548,433,198,23,162,342,958,925,176,151,159,463,154,403,907,941,251,51,310,897,759,250,897,8,650,349,489,363,69,342,256,534,14,620,124,46,676,576,809,195,238,154,358,667,271,888,758,721,653,268,691,729,691,484,183,488,997,860,242", "694,167,127,623,517,246,700,994,228,567,757,308,174,230,638,40,762,350,269,148,397,539,529,823,68,332,212,284,247,478,137,77,646,85,744,245,885,497,427,201,81,449,7,341,198,768,584,444,521,21,837,674,742,729,193,135,786,740,651,547,462,720,583,66,834,451,108,830,308,292,330,857,612,795,620,211,953,205,686,964,919,226,683,16,806,603,363,9,134,669,408,23,379,656,935,600,446,984,710,369,58,430,924,686,761,698,409,867,673,451,773,367,365,223,382,669,658,789,442,793,493,228,674,110,974,523,953,936,697,521,215,203,513,10,530,521,301,865,319,728,887,770,515,661,589,667,204,431,912,860,98,608,491,388,97,394,956,711,938,203,219,444,434,441,55,658,640,266,351,45,592,529,446,249,950,369,311,659,920,554,94,588,758,477,971,422,835,934,46,576,128,463,939,541,535,104,715,479,880,677,783,866,931,719,574,111,553,271,642,184,310,860,236,44,325,280,475,228,221,658,389,347,541,309,323,198,780,273,481,471,389,777,250,348,572,784,955,453,385,613,570,914,456,928,312,516,185,672,520,854,323,423,66,828,41,903,652,182,243,423,984,938,217,672,450,773,979,141,600,795,770,135,706,301,208,597,971,514,557,272,39,28,211,500,876,62,733,688,501,438,991,864,658,585,938,498,865,900,845,582,880,460,665,31,359,87,670,435,510,357,451,861,479,59,894,95,381,717,571,87,505,801,830,715,541,894,488,85,554,837,251,906,268,72,479,377,260,174,695,318,228,792,473,230,962,56,20,185,217,251,806,162,904,1000,83,567,358,231,316,698,607,498,266,515,324,554,692,419,257,24,854,794,670,119,292,484,312,229,63,858,190,922,396,413,403,275,617,11,325,886,20,712,803,795,953,826,892,825,724,579,560,370,203,89,265,896,153,313,175,54,227,980,906,424,697,385,422,543,641,663,377,509,28,866,16,678,734,528,403,45,150,321,224,221,148,719,490,745,475,835,52,717,621,707,726,112,787,741,46,956,515,115,21,625,352,485,962,835,725,141,857,178,810,168,4,370,891,743,104,737,93,958,872,787,679,596,140,239,117,193,816,319,533,368,611,858,453,98,464,785,908,894,536,809,876,532,397,596,113,145,268,363,523,495,773,489,921,459,399,721,792,419,615,908,588,986,821,964,62,337,874,866,211,654,13,28,235,661,630,95,415,91,976,664,377,714,192,759,889,667,137,306,727,86,108,509,373,246,458,238,232,166,205,144,85,253,532,280,488,692,243,373,631,550,423,342,444,283,787,95,550,450,231,362,742,19,479,25,428,177,754,124,26,747,725,83,722,800,971,317,417,441,433,333,307,811,527,674,525,454,387,979,414,133,79,194,10,282,55,277,103,971,185,341,764,998,706,724,322,766,497,571,860,196,254,531,108,625,9,541,676,8,916,466,46,517,244,236,964,679,705,103,382,607,14,691,700,3,323,695,217,615,734,610,17,593,601,693,149,615,452,425,910,944,479,265,760,452,43,698,65,83,291,500,929,468,935,498,344,538,608,231,190,847,749,396,582,366,198,836,577,787,253,672,388,195,472,514,342,598,227,565,669,355,838,388,0,26,619,847,889,425,734,677,892,188,230,32,471,941,499,102,260,871,475,639,658,654,98,475,175,63,403,806,227,234,296,76,655,129,170,167,428,551,54,789,613,180,403,41,345,530,714,219,195,665,179,632,423,333,921,406,203,315,752,536,401,632,17,973,371,975,591,101,398,427,652,91,666,353,916,602,536,193,385,174,984,863,154,257,635,524,962,57,443,178,532,919,104,47,921,924,584,522,924,537,488,801,224,877,557,123,149,564,612,348,414,650,37,319,369,477,868,105,257,775,249,682,99,803,881,302,426,29,164,133,974,336,195,669,7,224,164,216,357,929,7,836,221,556,478,108,566,212,728,780,629,67,36,472,580,53,546,835,4,217,832,656,518,16,184,84,379,906,518,997,256,681,264,637,33,978,625,875,748,425,44,546,850,996,248,673,771,628,481,35,353,808,286,246,665,687,713,750,667,798,209,982,930,40,145,966,132,251,351,659,86,634,374,920,127,840,830,886,227,908,583,231,574,741,751,472,749,687,723,140,212,408,418,62,581,150,626,286,877,630,131,881,128,716,650,855,927,779,415,774,522,906,586,948,514,971,893,561,472,387,814,244,257,255,684,690,293,736,244,109,165,301,543,923,306,540,400,797,707,953,711,901,601,37,779,314,884,493,410,782,160,450,671,791", "37,99,426,992,743,41,195,374,687,383,810,381,333,914,103,411,448,170,5,906,970,685,374,582,23,110,606,863,577,117,14,438,604,577,342,723,59,955,7,496,484,655,605,123,162,612,848,826,411,552,357,485,347,40,658,276,235,702,502,504,730,110,790,582,310,64,239,123,729,426,955,300,376,530,20,446,551,276,769,921,897,127,244,360,677,534,521,20,517,782,205,774,594,114,668,59,555,787,394,274,522,755,697,692,281,194,543,179,280,166,756,73,753,482,406,729,251,953,974,657,55,111,497,172,582,404,375,414,617,170,481,6,451,245,310,809,496,136,256,989,922,604,985,192,502,695,570,1000,286,497,647,101,610,208,869,227,950,653,768,31,782,201,597,532,712,944,944,269,118,932,250,620,916,177,818,769,357,730,34,789,258,298,475,819,239,585,329,146,949,564,352,184,554,727,274,291,790,736,718,209,761,337,261,984,274,819,660,175,104,772,312,65,916,744,720,965,434,997,873,661,222,149,932,783,713,147,536,214,706,81,707,87,397,710,824,89,94,42,545,207,442,187,359,171,614,985,910,193,282,730,301,416,124,897,966,770,252,525,380,189,171,421,646,860,104,529,708,499,688,63,772,22,388,382,268,929,892,125,438,689,831,477,844,115,385,236,426,294,797,300,376,517,454,378,172,708,945,59,151,813,98,298,882,269,678,452,295,76,456,953,263,852,239,259,923,657,937,873,231,754,483,194,490,638,228,749,597,672,888,310,657,234,365,986,681,130,457,410,205,423,556,140,456,940,944,480,193,294,286,694,914,932,171,609,43,318,710,107,969,876,821,14,365,621,906,112,89,980,481,767,796,773,936,434,106,322,47,600,321,605,21,643,382,955,474,488,483,158,597,393,369,760,865,455,269,708,951,261,925,697,807,65,31,527,317,486,358,288,422,881,580,267,920,868,197,696,585,762,735,749,762,748,983,8,188,42,68,573,757,103,41,879,724,647,764,848,558,484,366,771,543,579,400,555,103,938,485,379,599,130,861,698,887,537,786,621,281,734,642,703,117,234,383,55,204,923,140,72,126,497,216,466,818,25,145,408,850,947,383,688,463,386,379,122,585,812,361,802,296,709,179,803,529,512,501,818,37,265,940,814,925,20,556,716,87,909,616,4,180,738,199,606,867,51,819,403,303,60,892,683,153,577,103,564,491,536,900,910,390,213,410,592,610,623,768,36,334,853,908,405,744,786,914,769,858,1000,554,393,235,912,864,31,516,364,277,873,421,933,837,753,512,458,259,471,160,694,401,566,367,534,927,973,840,652,463,976,263,80,21,41,420,190,113,89,666,198,595,709,938,629,682,273,639,493,693,113,370,479,439,75,563,245,555,280,360,276,16,610,152,239,766,889,412,481,535,688,61,406,528,975,486,994,300,291,67,822,68,838,483,598,337,878,213,627,414,515,713,137,507,888,931,601,263,281,39,743,387,608,775,700,971,135,3,495,65,50,121,86,60,440,370,93,555,354,376,623,324,821,398,571,139,768,601,784,350,751,193,110,317,458,230,493,898,991,68,475,612,824,218,524,550,2,516,477,508,973,781,129,859,429,282,344,114,585,711,729,26,0,373,430,665,277,591,470,740,530,946,255,98,297,776,733,701,569,597,379,823,562,717,37,778,100,15,830,654,605,902,49,270,244,637,878,147,620,785,335,291,11,886,616,656,799,845,534,3,431,458,189,777,224,400,555,661,290,204,625,382,1000,324,427,337,826,712,747,565,360,542,878,539,66,293,564,701,337,818,776,624,927,218,90,926,429,558,390,607,511,704,299,4,240,852,123,874,599,593,635,262,58,367,310,679,225,131,700,589,742,474,305,112,181,556,561,797,510,423,205,507,204,895,616,357,555,67,305,171,246,350,323,484,521,928,203,168,627,223,161,147,317,282,683,623,856,40,292,297,901,566,689,195,543,505,859,590,170,185,267,46,978,859,243,771,998,461,310,789,862,168,321,291,819,434,33,729,906,259,838,520,307,943,5,808,962,387,882,527,759,886,691,13,639,92,771,628,977,941,650,196,643,794,428,617,814,974,409,401,410,881,830,638,322,10,464,407,161,443,870,843,607,897,183,407,714,536,68,44,746,401,421,755,939,971,658,693,987,517,349,690,497,102,755,766,919,425,933,523,325,330,402,189,538,492,916,694,48,755,882,635,952,411,662,70,266,260,54,148,501,51,724,698,693,937,514,871,941,461,119,659,33,740,933,845,863,445,909,55,555,454,371,787,729", "788,370,656,97,975,657,364,961,745,978,295,80,213,592,343,766,146,126,767,882,523,380,169,666,784,471,495,420,97,943,33,283,826,40,435,911,589,758,97,638,888,490,311,232,196,259,749,970,667,429,542,409,714,482,873,161,225,686,537,309,475,90,756,30,235,186,456,181,966,26,679,100,393,416,444,847,792,654,371,216,858,508,232,539,760,118,929,678,453,192,27,947,427,514,362,212,160,606,937,235,616,554,877,272,708,211,399,351,771,246,836,314,612,394,524,39,474,671,514,364,364,103,952,753,748,802,856,543,898,617,369,213,309,416,348,292,549,305,562,677,434,103,238,342,165,484,419,29,52,398,81,392,469,468,129,230,504,721,787,809,813,978,341,28,192,673,73,125,683,455,604,759,649,232,338,363,679,176,593,152,417,648,587,999,898,761,770,673,328,592,991,14,489,8,721,343,559,636,193,425,954,823,386,8,29,898,531,312,568,438,622,908,511,70,859,267,909,451,613,96,730,61,972,6,88,683,83,75,222,870,507,28,418,993,133,325,707,103,800,629,680,942,308,734,530,945,615,137,389,948,84,742,118,538,465,431,201,43,287,317,324,517,786,543,504,135,781,289,442,867,537,580,569,287,229,397,784,370,475,459,232,840,604,866,370,669,314,375,766,381,561,326,999,319,90,371,925,919,97,594,405,800,787,795,823,304,21,617,923,859,595,140,68,790,150,162,784,393,776,980,803,146,344,285,968,55,167,241,358,464,470,235,93,519,596,798,4,771,153,14,658,942,84,907,150,192,73,33,775,896,644,182,208,408,825,459,822,787,199,257,422,854,94,459,720,522,33,96,247,80,895,302,728,176,263,870,529,646,10,328,776,682,599,401,863,890,144,813,637,158,421,198,770,268,578,584,524,663,231,466,141,543,192,303,61,542,929,6,280,4,794,261,8,707,379,817,106,884,711,586,758,654,716,696,296,809,626,57,6,732,544,725,796,158,534,786,468,814,264,659,833,705,70,652,3,286,332,651,376,966,52,648,502,291,239,306,946,849,736,841,398,435,686,132,89,970,250,869,13,85,283,910,63,440,33,790,23,625,847,343,635,726,249,90,644,945,364,263,86,966,179,591,281,814,493,653,649,360,220,707,842,860,249,541,342,755,517,190,482,536,76,766,664,851,935,925,856,872,628,477,368,242,488,332,447,706,454,525,452,295,659,116,34,54,117,836,285,486,719,569,203,686,705,878,818,696,86,673,302,826,772,681,991,477,729,982,777,818,903,712,485,804,21,679,955,454,676,654,926,158,10,474,15,834,791,329,251,705,682,128,661,353,444,770,192,860,243,179,855,72,860,665,207,653,843,173,882,531,112,453,81,599,882,669,689,898,8,122,154,618,552,823,533,206,849,981,690,616,407,654,362,907,150,279,102,183,940,218,969,388,708,541,744,174,800,748,799,390,910,199,105,614,768,338,459,640,160,186,892,30,548,519,107,52,773,963,443,689,510,437,928,996,290,69,119,592,199,760,516,622,156,35,746,618,95,82,856,482,292,230,679,442,94,243,532,595,803,872,920,844,677,711,29,431,34,146,988,113,378,51,467,813,529,331,8,148,619,373,0,875,697,996,730,257,549,609,814,636,821,722,293,469,139,281,21,117,312,286,708,321,163,517,736,824,208,18,324,299,202,12,749,272,32,615,928,12,781,573,995,12,890,751,978,834,457,716,468,444,851,882,400,260,929,992,766,565,858,967,965,592,614,410,857,551,72,199,351,814,414,418,476,820,468,456,116,679,192,617,817,461,36,681,258,828,661,115,472,505,152,777,516,288,968,526,396,942,221,714,991,691,293,430,888,589,876,245,568,417,44,326,581,825,596,785,290,600,61,777,450,424,678,11,835,888,730,493,457,428,659,750,62,802,858,649,157,561,319,444,254,96,362,864,553,797,906,757,365,789,854,400,946,630,228,847,582,753,438,987,717,932,422,227,633,659,188,338,587,810,626,469,147,825,579,122,584,563,175,611,394,424,146,728,956,407,207,946,905,499,958,482,125,690,276,648,408,823,217,94,76,268,893,214,938,29,208,739,778,829,121,692,813,138,720,919,707,766,892,957,657,542,384,284,356,663,249,556,318,99,269,695,962,618,677,437,190,479,900,468,974,579,873,565,212,747,952,448,563,22,62,870,265,788,572,184,801,201,12,611,737,359,283,858,656,445,519,498,147,345,399,356,811,930,207,796,635,945,69,419,623,523,946,623,10,672,918,867,104,496,228,658", "495,833,576,807,485,801,942,932,575,81,91,395,338,671,632,20,785,647,37,459,155,533,710,464,900,998,886,531,563,286,623,353,747,543,596,935,624,991,252,306,322,619,622,449,187,861,292,746,618,254,110,185,186,391,845,477,647,432,814,67,484,594,884,669,66,620,650,36,790,780,153,150,384,483,247,39,602,706,613,466,320,119,532,956,743,341,587,476,495,317,383,945,178,528,326,780,102,25,630,58,673,530,990,224,413,991,670,718,246,628,647,716,731,501,184,253,224,901,819,455,991,843,951,533,155,32,790,509,495,175,104,624,565,141,193,684,476,447,623,334,797,523,887,191,641,314,410,941,160,809,762,351,100,352,213,844,833,643,343,346,895,722,791,788,63,881,758,144,458,124,942,746,913,445,315,817,130,421,60,878,92,747,74,147,276,393,672,695,763,890,681,568,851,925,979,981,280,940,144,545,967,929,946,733,342,130,577,848,890,316,303,769,647,857,968,947,248,695,14,505,799,420,937,847,734,947,17,132,711,184,545,558,93,639,489,647,810,293,194,389,826,43,104,3,909,698,706,130,53,535,939,388,436,595,598,424,421,438,202,186,597,966,165,932,345,587,665,180,438,440,166,173,2,786,102,857,484,162,247,534,966,19,247,203,635,841,894,57,866,470,580,150,455,861,5,965,852,10,829,662,406,603,301,88,505,335,918,469,51,625,323,282,823,858,834,621,321,939,752,978,576,33,501,306,594,191,1000,754,727,511,989,323,460,30,716,423,327,903,710,744,570,507,19,125,536,893,962,781,378,447,27,604,924,948,10,703,540,508,658,575,961,203,467,598,284,166,955,891,229,369,681,123,49,447,768,128,646,888,896,635,409,660,459,412,714,358,492,889,46,617,60,401,415,401,158,268,502,196,782,338,338,411,815,955,819,736,407,570,162,613,513,383,695,48,524,447,50,521,114,637,208,384,268,883,679,472,538,411,481,213,260,45,726,771,152,688,182,521,290,561,247,582,667,739,931,551,437,638,787,494,441,171,793,154,173,613,975,143,912,230,345,597,473,389,417,357,941,173,701,647,387,518,527,92,457,653,450,628,662,494,48,150,152,652,798,726,994,671,374,757,548,562,873,39,143,439,727,611,34,831,569,979,539,814,615,108,478,691,991,844,795,524,802,319,410,389,678,77,747,978,801,444,404,640,474,338,182,891,50,435,691,939,170,940,246,684,982,580,414,889,307,960,678,379,820,36,954,109,881,180,906,540,45,127,313,708,888,637,434,80,852,794,372,638,126,593,936,257,617,382,428,753,618,846,568,116,333,16,417,20,671,663,378,563,867,737,451,777,121,164,12,381,199,344,394,936,160,367,820,330,850,845,90,64,512,470,804,960,935,707,388,670,165,504,60,874,820,732,793,457,744,185,217,111,82,427,119,179,167,146,175,928,809,187,737,917,833,785,292,640,307,520,229,791,914,761,252,920,269,188,606,286,17,592,602,897,709,714,705,816,473,427,585,449,687,365,41,174,302,174,160,401,323,714,9,120,910,949,853,406,914,791,96,512,478,808,517,808,22,401,682,94,454,946,49,902,849,295,441,847,142,410,730,204,602,156,847,430,875,0,29,304,907,968,714,895,504,642,320,163,522,283,767,728,783,34,966,437,398,760,774,26,474,257,832,536,845,277,293,71,210,333,898,968,681,982,237,613,37,728,17,49,305,924,705,986,132,458,116,456,348,491,127,610,76,867,182,321,292,664,27,490,868,191,640,915,879,503,796,150,449,54,976,774,287,345,347,427,968,252,132,682,464,66,740,34,880,672,555,506,520,21,217,733,670,441,180,643,300,990,91,893,635,248,892,999,548,221,162,381,776,527,913,478,81,514,190,102,556,353,264,797,496,121,173,92,615,462,436,432,985,686,150,627,717,88,889,361,968,991,976,604,560,581,104,552,37,455,193,931,63,739,371,940,273,438,537,985,992,435,942,771,250,126,598,812,857,400,978,12,345,330,183,500,589,481,902,303,784,523,651,443,955,66,303,167,808,980,391,763,670,26,79,665,451,809,448,490,711,63,886,949,804,356,109,302,386,655,653,954,704,426,179,401,508,860,203,840,27,806,425,234,631,348,18,497,414,831,423,741,772,987,49,433,572,207,336,12,832,450,10,295,620,85,366,575,115,37,838,751,879,824,328,978,412,108,45,669,720,437,308,766,21,950,310,362,261,280,418,161,421,110,662,747,440,343,697,157,553,25,27,345,9,342,287,687,328,180,766,984", "961,642,398,906,967,12,891,299,547,927,113,927,419,196,901,687,768,114,839,186,562,285,888,97,479,623,500,163,76,600,844,746,932,594,643,540,626,164,706,806,359,396,649,508,311,398,442,584,237,473,309,721,160,529,730,700,684,581,202,157,208,276,464,853,597,441,678,186,336,426,734,132,405,811,521,473,420,712,697,688,591,98,956,348,327,822,741,863,195,96,252,598,579,573,310,1,193,912,754,676,53,478,821,912,457,840,404,671,835,26,922,135,753,382,733,474,577,60,503,120,680,529,78,240,710,685,432,898,584,500,59,690,246,579,627,482,185,443,595,503,929,25,731,49,211,9,209,368,272,2,455,862,520,122,128,360,687,739,755,859,159,173,510,505,519,218,481,656,175,678,55,57,458,590,546,807,310,956,960,933,529,546,258,967,947,286,130,84,19,201,28,340,300,353,423,309,31,176,432,854,554,967,465,559,38,170,383,82,800,935,18,293,165,774,118,457,972,1000,443,515,470,273,823,968,884,191,893,57,497,742,684,961,209,833,946,613,836,565,997,656,959,907,449,950,420,593,109,267,143,149,471,277,949,35,286,247,214,134,417,336,988,889,272,12,28,117,879,723,968,793,730,470,868,510,567,515,206,837,24,468,710,635,387,464,114,576,285,457,860,838,128,902,686,947,657,963,500,997,695,696,651,896,666,158,918,938,551,775,177,163,869,878,776,115,482,506,477,492,64,162,354,968,623,321,845,774,889,312,703,473,478,415,381,838,417,945,188,684,885,599,753,808,767,212,945,513,265,735,386,656,689,773,838,104,111,631,861,188,406,264,3,555,664,475,86,742,18,129,576,883,8,559,959,318,792,873,57,707,90,322,24,768,380,173,14,739,787,325,273,48,454,513,333,698,36,371,249,200,556,263,799,763,71,994,925,57,318,532,551,6,878,912,478,967,502,895,590,515,417,642,329,792,103,639,100,559,441,861,951,929,761,648,97,180,33,434,55,346,435,824,772,249,770,848,781,750,599,945,357,759,936,838,88,896,826,715,872,366,531,629,588,531,51,747,264,355,307,194,466,910,665,262,800,431,50,262,835,606,461,185,261,403,870,684,791,164,302,396,568,171,589,251,138,316,393,489,255,474,387,443,643,506,862,703,112,78,161,375,300,941,939,625,172,648,895,157,267,563,287,344,155,171,14,354,743,702,551,292,581,973,65,778,561,284,104,702,350,395,489,622,649,440,976,423,81,889,747,940,296,895,143,618,955,713,959,215,576,606,477,61,117,302,887,41,890,208,285,775,257,291,554,253,567,286,189,522,508,618,194,236,306,233,456,797,35,236,709,943,980,598,920,316,630,780,556,987,356,574,121,669,317,567,225,113,608,500,743,826,551,656,970,507,859,658,94,671,657,74,939,180,828,294,199,729,122,21,117,408,782,819,644,524,227,682,211,936,949,976,277,998,619,862,122,877,377,263,710,987,525,61,58,959,996,47,953,794,296,721,787,519,648,183,725,888,582,772,860,538,190,130,631,378,424,419,926,927,731,276,221,438,341,211,683,128,438,202,251,590,757,724,41,111,900,106,173,327,908,137,410,44,467,527,420,980,118,429,889,665,697,29,0,401,315,879,334,84,368,310,1000,391,458,472,276,295,807,465,923,814,344,818,337,796,298,803,156,896,245,769,739,769,586,589,40,48,746,705,215,46,912,698,499,329,599,587,957,388,730,387,532,354,614,536,407,585,329,789,920,323,523,959,201,660,396,417,374,965,424,133,939,811,198,53,408,452,88,143,696,421,856,290,921,165,629,698,447,959,216,7,873,450,130,528,876,666,943,732,164,592,397,349,338,151,462,437,270,978,620,469,755,724,725,824,499,765,884,321,385,399,520,831,774,917,674,422,202,157,852,231,369,220,231,182,887,837,598,429,337,345,565,787,341,650,395,212,918,679,574,495,927,405,765,865,517,28,8,509,900,613,902,935,142,993,497,332,24,40,68,309,813,424,757,713,817,124,240,535,699,34,228,582,127,708,451,911,792,312,2,478,943,93,262,176,545,677,757,366,315,503,50,490,2,713,993,418,745,639,161,923,132,957,235,174,696,281,553,81,475,23,657,219,270,56,166,627,180,417,282,152,775,620,300,604,860,833,804,760,78,955,972,599,138,161,713,812,405,608,196,31,781,435,951,667,757,798,93,239,259,863,242,739,850,22,116,424,928,771,674,837,977,488,536,488,749,14,999,454,30,172,365,560,279,781,427,112,156,170,592,664,350,539", "770,437,723,592,608,28,411,864,772,817,812,41,732,794,548,867,533,986,482,408,814,947,763,982,592,187,63,985,854,458,471,70,156,779,789,219,621,649,129,638,331,737,863,859,984,548,852,443,796,927,186,630,646,918,834,727,296,549,499,964,91,421,687,382,300,29,694,922,653,123,704,503,318,592,557,981,859,823,817,889,181,358,250,780,150,57,770,574,483,828,431,8,739,226,786,84,43,133,764,375,891,980,465,120,408,326,855,761,230,52,405,431,370,183,995,910,525,874,70,344,700,986,746,939,69,515,889,70,258,93,924,547,447,778,971,472,283,826,314,906,932,299,875,227,705,994,80,896,364,723,857,628,405,600,526,899,331,185,147,419,557,292,382,732,471,459,368,593,281,712,905,199,735,951,408,850,32,857,55,2,89,553,870,171,447,694,529,354,933,703,660,728,97,552,249,659,206,897,896,394,601,685,287,937,996,516,227,192,815,403,433,515,186,840,88,380,699,656,316,650,420,22,128,160,186,789,118,351,550,413,14,765,627,231,192,119,657,644,128,769,137,147,738,827,192,254,831,579,570,399,797,13,923,320,841,937,633,229,345,519,194,825,210,219,83,585,635,104,349,219,4,931,636,304,105,918,562,405,668,261,358,584,751,40,414,172,537,38,178,251,399,294,191,75,676,305,138,856,824,132,581,925,309,912,712,413,42,584,731,81,35,266,980,719,218,582,394,575,973,938,581,94,213,366,306,866,297,66,350,639,867,641,375,979,132,528,211,486,716,220,435,164,689,196,840,992,609,894,26,861,725,65,83,642,454,382,998,601,102,628,922,440,327,219,801,227,749,968,761,634,35,569,585,13,880,928,371,366,128,70,9,266,317,791,428,367,266,615,673,822,353,543,586,231,666,552,60,254,469,862,112,613,465,112,207,474,336,137,489,463,809,446,746,474,582,107,567,516,845,577,11,465,955,74,481,467,306,206,748,323,976,39,242,765,104,801,527,105,457,687,599,851,175,268,342,270,43,570,962,884,389,983,6,580,453,346,842,568,14,913,99,553,635,201,659,885,156,921,473,997,338,295,894,418,765,79,987,260,121,782,274,544,635,804,725,288,16,547,946,197,71,202,855,655,503,300,513,509,280,475,401,616,943,987,592,821,401,552,359,630,411,571,149,933,133,136,106,831,529,300,366,152,309,246,827,150,50,612,483,862,400,374,36,199,35,455,737,567,670,896,513,89,618,376,804,167,157,76,625,261,975,843,917,417,300,826,398,499,7,59,993,489,855,586,885,399,444,49,642,334,457,128,132,230,416,264,433,946,385,704,362,788,155,128,558,256,872,112,394,49,976,846,121,675,656,227,1000,191,815,896,666,775,622,359,300,122,198,849,290,859,981,328,678,663,265,140,323,412,730,962,484,664,641,987,952,39,72,239,168,82,434,20,997,191,92,920,597,584,751,419,136,12,613,696,778,633,989,231,51,850,548,39,64,947,616,836,834,152,600,470,716,103,279,262,861,427,284,203,16,98,393,743,93,612,329,744,490,724,744,826,440,484,618,863,412,546,884,61,180,983,572,415,885,288,820,719,154,211,212,587,495,848,124,737,305,965,425,277,996,304,401,0,411,604,907,951,888,558,283,686,18,164,108,107,433,82,896,332,585,40,586,342,953,236,162,199,876,690,327,737,270,874,429,93,778,325,523,199,868,91,496,729,513,678,558,175,406,808,576,931,240,817,899,658,587,750,941,978,321,312,748,20,804,529,96,653,951,726,90,832,895,499,742,922,24,63,681,172,91,550,528,161,680,497,345,581,557,500,117,492,595,535,379,591,201,861,819,841,986,439,819,484,677,302,981,128,174,319,219,986,921,954,74,891,177,490,714,3,235,180,341,419,656,551,211,629,857,270,231,942,748,375,312,934,160,102,715,65,659,212,437,685,400,291,180,34,145,676,365,240,149,252,540,650,110,991,185,499,218,356,897,743,614,828,291,277,203,693,769,545,287,154,519,777,506,160,721,244,9,906,783,685,666,655,951,338,560,120,158,783,10,123,952,397,942,326,246,45,418,575,774,266,264,338,988,33,30,427,190,417,304,23,869,636,708,320,434,380,764,566,81,657,679,542,28,392,269,590,447,404,385,842,754,573,254,832,217,122,582,372,776,826,441,684,882,305,152,461,567,41,763,259,798,379,687,71,692,680,793,640,914,220,586,210,785,424,56,376,284,531,384,441,572,520,953,64,425,798,211,22,470,998,171,264,848,119,149,105,613,111", "736,746,266,985,24,206,202,24,980,162,506,683,897,297,874,920,954,774,353,342,736,521,527,665,690,487,224,197,554,491,271,485,728,369,82,956,517,354,753,950,544,585,789,255,778,157,85,120,521,853,45,438,159,807,224,9,913,848,299,822,552,908,505,962,82,778,151,48,46,623,319,81,306,466,941,625,435,154,324,6,812,2,278,229,746,217,568,829,496,258,37,477,972,195,82,300,222,690,58,798,14,970,595,984,43,655,444,501,839,494,159,658,849,26,706,119,148,153,973,907,418,13,501,753,956,727,51,284,664,67,823,455,844,860,2,120,345,488,944,129,402,621,435,518,48,616,252,633,813,322,203,133,719,602,650,100,237,465,588,818,29,797,828,531,701,615,597,474,187,380,920,831,942,514,104,866,356,460,124,585,541,593,2,898,726,705,507,751,177,941,873,753,497,880,662,20,462,727,377,236,794,369,375,380,684,793,723,559,202,292,818,919,727,882,26,405,994,819,539,794,403,31,474,414,306,57,280,829,265,579,779,760,329,734,30,752,640,593,622,548,405,319,283,355,538,471,979,181,855,226,346,716,520,791,545,123,121,740,678,837,140,783,404,284,194,719,893,41,423,720,75,136,654,976,221,111,746,865,542,991,12,915,936,330,780,671,167,239,412,150,379,257,296,488,850,941,163,389,62,182,393,585,908,592,572,819,235,851,466,637,876,82,445,242,517,202,787,982,513,417,269,81,112,221,288,128,381,48,964,416,446,433,68,651,871,386,246,58,725,386,812,429,282,627,375,937,634,531,655,266,531,932,276,433,717,297,714,975,134,539,368,375,712,299,721,633,540,368,419,380,895,819,946,302,522,74,501,321,433,492,223,531,774,189,391,673,557,37,551,18,589,418,169,147,519,803,69,411,6,54,183,716,547,940,468,286,988,523,818,56,692,725,206,579,806,350,876,92,513,618,661,711,658,97,207,200,879,960,363,519,617,367,639,654,853,235,229,710,304,49,816,178,595,585,96,10,271,256,911,200,510,534,189,769,72,13,513,660,635,105,838,44,779,566,11,632,963,704,839,927,145,514,873,753,65,137,67,44,166,148,204,518,551,571,244,109,567,359,869,371,921,659,573,810,275,674,759,792,769,322,587,958,289,465,843,48,384,498,142,906,291,474,731,714,899,962,584,980,980,778,385,250,37,317,617,537,665,278,282,729,686,20,130,449,535,948,727,833,112,844,649,410,65,258,71,318,751,770,335,29,823,504,685,198,159,67,544,588,373,415,86,303,512,966,301,239,610,246,323,630,32,524,112,806,274,405,237,355,938,962,116,16,257,489,482,996,220,4,714,349,838,844,316,583,133,246,746,970,553,109,899,375,433,511,783,505,420,999,242,150,688,66,718,349,279,920,544,448,92,460,757,419,414,734,858,142,513,826,464,73,490,71,936,842,600,54,470,984,452,407,464,723,276,253,577,440,323,916,297,334,776,611,466,510,166,610,63,792,584,220,87,20,857,862,554,626,37,406,435,915,956,434,517,398,150,806,955,739,80,327,161,740,470,611,667,702,78,871,501,582,918,257,385,495,357,40,735,653,328,799,734,498,269,179,63,156,734,591,730,907,315,411,0,645,753,85,219,51,151,932,785,82,534,402,415,532,687,597,662,82,448,302,122,408,921,556,96,644,339,84,611,807,906,806,757,591,271,140,216,527,406,732,441,84,265,571,36,497,39,67,611,261,393,883,982,308,576,354,220,509,255,431,602,179,842,360,898,226,9,966,237,276,676,594,665,533,169,933,192,425,126,367,653,366,945,33,655,632,425,119,869,853,169,620,865,590,765,550,825,293,173,359,918,94,350,227,497,99,699,378,661,3,192,347,510,339,238,612,291,552,468,488,146,937,238,118,167,10,32,529,983,215,500,326,236,757,841,501,882,391,927,605,661,598,511,450,891,755,371,679,292,561,366,525,142,640,701,790,534,456,354,659,764,106,463,352,984,46,337,525,893,503,346,528,392,938,641,174,282,280,815,705,321,364,48,376,942,301,79,29,893,352,811,654,950,899,112,913,916,281,99,292,272,701,510,828,184,626,854,421,804,968,378,889,905,964,113,613,47,840,284,977,321,183,993,546,747,700,245,323,794,610,371,158,430,246,763,175,661,307,22,877,760,152,980,181,408,437,901,461,619,310,675,285,858,2,504,837,159,597,600,52,406,392,120,194,492,637,146,86,237,893,811,329,427,380,496,666,987,943,781,313,161,803,187,269,499,854,639,521", "207,565,895,349,647,396,954,646,640,598,526,528,416,911,784,155,551,826,830,254,18,400,978,655,240,296,736,414,976,904,482,625,289,671,196,610,63,869,633,826,95,304,131,803,627,35,329,254,494,967,536,251,137,224,738,239,452,814,393,184,144,819,442,255,809,246,388,232,970,959,365,934,134,940,672,733,70,765,155,247,104,486,60,87,114,547,442,740,475,47,311,840,540,378,206,409,477,755,421,370,245,871,907,341,57,259,49,748,822,606,528,812,810,725,291,212,532,668,950,299,844,278,300,766,972,656,281,345,292,405,601,284,306,716,903,573,941,16,155,682,545,674,846,856,982,54,718,115,302,968,496,95,384,190,84,583,800,14,308,811,834,999,593,81,367,166,990,722,855,145,117,44,151,786,153,288,862,410,231,766,48,571,719,566,818,56,290,192,10,604,760,807,767,624,885,231,232,944,299,544,815,808,344,455,529,946,901,942,317,785,244,717,264,280,644,181,82,418,488,388,716,960,881,80,204,802,206,118,782,119,223,605,314,935,221,736,2,803,652,734,641,252,91,356,890,383,288,591,150,752,34,223,845,162,110,630,543,486,260,794,253,638,532,337,541,796,306,729,391,231,962,324,393,526,882,725,948,467,227,795,690,717,12,697,301,810,521,411,685,66,81,594,212,181,645,369,652,795,130,781,55,520,443,355,856,359,337,164,330,918,588,522,834,530,266,285,400,625,580,852,672,403,327,464,722,600,819,632,164,273,161,397,277,661,662,643,147,460,547,400,550,876,297,821,278,67,620,879,530,832,679,682,709,15,710,146,15,943,430,464,496,569,806,41,474,627,937,894,221,124,168,847,308,724,988,639,213,199,174,555,935,370,12,842,26,823,11,937,200,47,59,10,455,732,51,11,346,10,358,833,544,273,679,17,184,871,22,179,321,293,287,131,784,737,948,729,974,91,652,737,901,960,241,228,565,495,146,794,982,318,324,354,437,747,996,434,788,659,129,818,801,905,254,506,351,269,989,334,60,69,641,999,952,498,970,545,913,470,687,83,445,512,92,958,935,933,827,763,896,907,342,999,545,327,973,869,261,115,646,140,336,945,111,725,15,145,385,240,916,254,919,401,138,158,910,214,741,413,3,558,479,812,884,498,451,113,712,829,992,460,586,892,448,434,328,394,323,629,632,348,731,413,704,583,962,271,299,556,288,827,451,841,459,627,953,347,295,367,190,255,197,15,619,224,776,113,932,603,770,250,860,785,550,478,775,327,205,992,441,796,26,131,236,914,430,355,387,671,458,344,325,760,709,432,450,792,264,489,136,559,793,996,756,38,572,976,82,853,37,686,190,709,993,603,653,854,598,308,50,261,693,128,849,661,128,191,348,851,779,653,761,539,353,305,209,780,528,459,274,15,562,30,129,482,504,49,197,743,546,770,459,280,46,487,793,120,916,484,809,453,708,599,803,109,842,414,19,489,703,228,483,223,410,641,585,597,408,335,770,152,995,444,566,372,77,53,226,565,507,478,976,833,930,841,616,482,426,656,908,206,244,668,264,417,881,99,112,81,789,849,904,570,153,956,592,56,181,724,242,548,159,423,23,758,307,404,677,470,257,968,879,604,645,0,870,672,625,433,120,934,383,686,240,100,766,178,966,102,720,750,755,79,912,717,684,665,743,659,853,126,613,255,562,551,638,130,127,572,365,154,329,236,734,942,338,882,373,671,81,660,658,995,740,246,384,837,460,882,872,910,90,855,157,651,308,837,229,989,356,88,191,658,306,893,950,360,203,500,436,585,527,223,96,467,61,383,537,418,698,3,248,575,93,829,2,662,301,19,288,418,561,554,636,770,464,858,294,115,436,152,233,764,310,55,206,14,962,464,730,791,434,734,181,16,111,230,203,608,655,118,172,945,961,146,48,53,270,399,915,178,728,593,909,277,410,677,244,162,249,229,193,341,637,587,757,853,398,351,653,992,443,117,862,368,650,519,907,837,934,304,111,643,332,789,237,395,689,639,801,789,951,539,980,337,53,183,887,700,870,55,90,488,916,456,685,960,577,649,655,478,322,291,549,44,892,761,156,240,743,643,765,57,82,446,188,19,327,548,668,165,332,292,425,787,249,780,53,697,551,698,239,601,710,742,742,538,917,965,112,947,474,409,943,865,377,860,696,121,623,493,256,710,37,124,277,423,275,935,425,135,636,9,586,191,107,549,28,73,239,42,1000,653,296,163,52,573,805,836,634,437,264,632,447,938,102,638,16,462,966,488", "903,23,899,872,760,835,444,476,105,792,282,505,890,208,298,763,11,42,722,405,597,913,126,237,512,26,940,58,863,843,749,825,743,446,167,264,547,309,510,690,847,446,756,813,245,332,875,780,23,976,913,31,62,181,860,734,365,272,590,879,528,607,562,348,322,94,431,704,744,450,380,950,605,712,824,381,115,546,743,582,401,854,377,6,392,726,636,135,99,227,628,489,934,86,329,641,30,358,395,768,814,747,955,258,718,282,779,698,128,841,214,76,129,416,487,79,534,909,363,225,737,384,168,979,840,21,743,395,389,603,491,494,417,787,673,319,152,556,413,199,284,955,846,789,830,662,519,863,68,312,359,877,9,855,352,820,751,916,755,824,756,867,536,827,763,586,95,442,126,179,44,711,303,688,788,520,595,646,87,200,160,531,306,537,922,101,715,309,97,777,195,739,926,540,513,624,368,570,197,447,864,14,61,350,453,685,710,979,244,259,439,467,26,862,905,451,304,202,590,53,26,685,43,202,829,220,726,837,992,518,851,91,443,698,153,225,299,427,561,497,427,48,333,414,153,927,27,136,448,202,447,132,331,913,228,944,45,80,513,208,498,439,56,317,21,796,152,550,441,437,163,209,467,2,781,795,147,591,510,972,877,638,826,733,153,739,90,195,13,55,509,891,41,685,982,415,962,377,557,195,481,56,904,486,603,752,192,92,744,587,957,148,182,280,983,450,921,835,167,450,587,457,943,629,259,87,642,415,679,965,326,397,401,636,682,503,172,427,259,559,173,986,776,550,966,954,867,496,727,292,877,670,413,972,381,261,463,555,226,168,201,454,275,323,14,267,612,253,974,130,359,157,152,102,877,325,532,287,579,976,252,268,995,657,354,301,978,711,307,34,208,115,30,682,267,284,500,983,266,959,178,751,660,60,459,939,872,369,526,332,991,438,920,601,647,222,457,539,575,521,281,309,490,851,174,93,922,364,224,945,464,380,989,384,216,151,578,284,389,1,82,312,654,618,351,580,358,708,354,23,740,305,519,539,280,777,847,56,64,714,1,170,582,906,750,228,781,501,736,5,392,878,78,580,2,593,636,833,978,210,701,493,921,525,790,127,288,454,447,593,986,456,720,342,206,770,653,568,91,60,836,458,814,135,525,163,368,186,20,580,160,405,375,472,286,72,618,65,299,583,967,822,643,714,470,478,934,675,468,19,150,439,456,714,585,26,181,402,629,344,226,576,694,30,589,824,901,742,917,606,101,404,599,879,248,516,123,896,439,960,568,392,520,887,41,96,830,489,196,504,294,290,114,349,532,846,101,764,885,789,177,36,827,425,624,154,654,812,597,337,737,46,426,695,715,557,902,94,698,409,205,340,927,370,605,7,159,136,466,352,500,727,82,465,392,627,711,690,564,615,407,30,409,53,706,421,382,272,120,658,658,241,612,157,780,343,691,523,280,406,752,620,256,541,201,178,626,349,490,491,165,141,801,432,324,318,979,833,262,987,750,914,108,605,871,303,554,172,656,1000,457,894,946,720,336,784,67,260,855,147,800,133,612,163,931,157,627,441,681,857,704,374,756,932,423,426,841,750,845,518,304,47,896,550,794,581,892,740,549,714,334,907,753,870,0,442,857,211,221,871,734,932,488,687,176,997,662,168,557,575,190,477,680,914,934,472,784,201,100,350,89,582,551,508,41,888,788,108,157,682,322,52,226,219,767,216,273,372,355,316,292,128,344,796,156,253,976,760,236,988,712,669,86,847,814,301,774,964,635,760,97,215,895,149,697,971,498,2,631,607,384,551,832,621,564,206,681,102,271,220,387,289,949,851,296,424,96,476,528,670,816,626,979,548,156,689,271,878,723,825,90,247,581,707,324,733,730,255,762,798,911,487,778,87,596,95,799,331,52,698,432,187,564,107,618,297,999,851,265,96,878,81,313,547,499,531,471,714,282,354,308,669,789,313,27,528,831,256,384,110,247,86,400,180,79,638,885,472,845,786,679,769,800,731,454,391,976,732,511,719,306,250,614,583,594,506,256,504,724,454,300,994,260,508,329,803,490,299,544,733,775,800,182,674,9,549,732,44,557,431,633,231,133,852,970,141,37,586,123,224,749,166,981,267,52,779,520,776,736,643,12,223,903,787,496,146,422,768,244,50,824,167,656,523,316,770,748,667,216,449,145,706,117,685,516,666,443,217,713,181,293,271,872,516,252,26,901,92,336,806,773,444,723,889,265,304,201,939,686,768,424,653,150,938,571,388,500,407,78,367", "664,956,439,383,861,161,548,717,778,79,817,867,754,496,874,843,660,856,891,72,210,816,548,656,335,683,197,850,769,480,701,241,838,254,882,410,424,461,257,489,274,45,500,94,309,27,435,726,618,665,200,138,787,977,17,663,805,512,961,513,272,431,776,351,662,894,286,206,509,301,490,858,724,285,292,410,970,394,357,371,884,80,33,69,937,704,103,510,151,386,433,573,51,746,62,458,311,103,519,654,839,522,131,190,668,17,400,516,668,900,726,912,685,64,108,338,648,865,593,326,676,171,358,329,962,398,272,280,358,417,405,71,764,770,534,70,778,614,559,574,768,849,413,201,270,902,59,787,758,437,172,822,208,417,874,586,520,32,676,708,217,587,364,609,322,851,584,680,614,966,487,35,856,8,579,943,643,324,546,358,997,949,463,259,27,834,5,603,733,452,640,97,706,371,5,112,868,499,98,270,84,362,377,792,820,830,150,513,44,204,796,795,557,262,11,867,461,430,916,77,849,13,55,719,643,245,470,307,725,275,50,655,515,266,383,205,376,433,955,95,320,119,226,584,714,939,513,606,900,554,436,635,177,11,218,614,236,137,14,345,631,600,953,265,684,188,719,509,925,62,23,466,471,621,327,265,244,965,298,240,943,148,37,530,690,273,844,955,142,525,40,253,183,888,769,27,336,95,395,586,295,959,576,715,783,440,858,269,282,819,490,236,392,97,917,678,68,415,915,642,614,723,402,452,152,509,412,274,337,667,589,449,24,670,218,415,652,678,352,112,236,117,213,920,330,854,318,653,864,501,311,265,621,62,402,662,552,599,918,654,646,124,89,74,288,509,460,727,483,234,169,576,608,266,614,644,399,139,232,481,634,75,694,17,367,759,221,850,57,713,600,369,973,682,911,366,188,150,633,360,381,438,770,960,143,609,507,46,294,493,36,222,955,112,441,366,57,747,305,972,27,493,209,58,643,89,835,817,863,800,995,905,162,915,334,275,646,983,242,940,502,624,166,419,348,668,613,751,916,172,821,585,332,869,999,640,36,593,117,254,319,321,1,450,314,568,243,163,532,9,465,282,266,380,800,818,614,440,310,702,690,433,549,7,152,283,966,759,754,690,406,426,423,712,842,461,226,38,178,815,830,560,705,727,583,286,487,206,717,914,98,267,466,831,780,26,244,884,236,642,386,522,132,28,42,876,41,90,805,456,992,953,853,445,208,747,265,13,924,422,376,389,523,370,475,676,444,776,596,499,560,415,874,973,166,2,216,732,632,311,802,766,749,188,614,677,930,543,27,820,301,309,997,156,553,741,852,821,103,533,170,740,884,264,823,252,522,809,303,551,113,242,350,293,929,756,430,36,492,883,450,54,263,695,797,863,513,847,944,55,195,961,900,123,157,367,893,36,622,576,675,307,968,171,264,782,666,318,274,43,9,937,917,662,254,744,586,7,265,295,646,589,356,890,625,848,680,211,691,64,448,980,878,387,842,688,869,617,742,250,206,763,875,96,872,386,318,435,822,17,886,948,851,853,65,618,620,494,921,619,859,399,649,237,577,735,709,74,925,220,975,159,939,108,117,162,111,678,82,75,775,915,805,68,712,43,188,530,609,895,84,951,85,672,442,0,65,154,58,794,504,165,146,781,437,233,666,959,771,209,106,13,694,278,400,622,808,366,232,976,176,292,148,257,491,82,106,969,564,834,323,684,104,450,11,705,56,351,461,69,522,925,52,939,439,542,888,745,732,567,965,784,368,155,422,66,895,149,658,522,560,238,462,144,607,257,416,721,283,710,207,930,825,780,968,511,563,677,727,557,86,197,63,368,376,318,58,298,220,431,444,402,471,12,465,831,899,183,628,819,633,272,657,510,46,508,488,781,14,933,484,917,311,698,231,634,626,214,184,939,405,254,336,860,119,285,586,826,779,289,918,82,322,396,591,847,335,718,557,10,780,965,948,41,558,833,529,860,334,203,918,558,303,347,771,211,194,705,656,908,419,434,699,691,459,263,17,769,842,191,384,286,435,802,917,857,465,473,702,855,898,524,965,718,412,568,227,503,622,184,935,492,4,251,481,743,254,648,444,369,967,141,979,889,661,165,873,628,952,188,906,942,410,365,36,997,341,154,156,914,37,290,734,784,73,265,422,189,565,21,527,405,527,10,268,424,574,739,213,727,13,116,387,102,805,975,99,261,525,819,225,278,718,901,658,432,336,150,76,532,741,561,625,209,350,537,979,53,662,943,376,856,481,200,9,283,913,561,325,682", "21,830,509,83,226,359,581,856,623,736,237,235,151,483,39,472,257,505,847,423,443,502,252,53,84,280,650,897,157,893,464,968,193,222,900,607,523,629,742,283,369,489,988,815,346,896,893,684,479,306,427,165,545,802,183,198,467,202,773,596,364,300,634,890,233,41,880,744,602,436,229,2,116,152,183,486,67,565,846,943,289,672,756,819,309,988,440,599,615,257,28,769,117,565,53,517,707,374,431,562,63,494,984,94,906,754,257,488,29,491,188,217,965,438,576,50,989,574,170,299,981,177,345,125,325,613,592,923,766,49,246,833,773,747,805,42,295,639,690,583,979,587,307,689,933,260,933,309,168,657,636,252,360,19,825,568,66,518,270,887,48,343,208,842,273,551,632,970,645,928,99,587,191,415,117,498,326,857,33,715,410,788,41,981,42,436,132,316,139,775,302,72,488,289,758,323,844,686,804,805,203,894,234,962,99,481,332,478,638,85,674,906,310,342,834,157,964,135,810,603,518,363,551,577,228,693,96,998,623,273,172,234,414,851,799,326,403,150,169,492,634,170,809,5,864,409,797,397,473,131,95,398,741,778,222,553,197,27,342,258,654,509,77,883,693,165,787,65,822,49,371,284,971,847,150,40,471,899,291,184,889,266,367,701,249,473,656,599,827,672,755,500,656,688,154,763,237,721,592,650,679,212,853,569,724,710,262,344,586,377,146,564,395,495,37,562,707,103,317,795,727,730,397,914,549,327,199,59,23,997,684,189,585,644,273,74,74,307,405,945,703,647,255,672,111,782,951,448,349,982,893,966,925,729,669,629,212,447,948,352,164,340,167,577,761,443,525,861,604,362,569,276,324,349,590,978,301,63,714,490,653,440,169,844,267,553,551,323,401,279,967,281,110,954,451,125,967,606,567,890,369,249,919,467,85,475,506,756,200,648,456,251,337,346,479,738,55,327,687,266,416,436,35,985,294,850,554,796,82,336,929,914,733,660,853,258,527,34,78,189,24,503,116,377,779,393,744,957,932,175,82,999,306,599,135,30,479,936,552,696,958,730,340,229,705,352,105,36,589,158,863,663,94,322,21,253,245,671,267,398,898,714,987,352,410,350,473,294,397,428,929,333,121,935,717,451,8,37,207,530,313,722,429,104,365,692,934,419,594,769,82,989,261,570,854,683,161,88,487,970,260,87,575,43,557,80,85,790,829,755,424,702,717,24,535,570,705,471,370,306,569,349,529,826,536,245,835,3,206,8,870,515,933,941,262,915,767,288,821,476,437,270,488,116,961,293,301,361,468,290,954,64,578,855,715,292,774,545,482,758,178,267,47,535,517,426,975,240,269,272,931,751,210,403,388,600,773,8,736,260,488,475,219,888,627,947,449,495,851,70,210,769,852,732,30,804,953,6,451,771,599,608,840,591,671,658,785,953,961,237,848,894,781,549,270,1000,611,490,495,88,233,891,819,384,934,697,331,834,365,401,952,410,987,758,830,719,378,407,675,836,147,851,624,379,645,460,769,567,819,775,171,560,121,255,175,893,187,39,295,783,864,997,244,348,730,597,441,715,661,608,473,376,30,932,582,818,627,412,897,739,429,363,128,3,651,365,230,946,814,504,368,888,219,625,857,65,0,529,507,509,824,243,264,524,662,189,184,475,687,366,474,634,375,401,824,520,185,392,753,308,436,483,921,249,525,570,926,397,205,383,200,53,367,904,201,298,28,494,931,922,299,937,968,662,566,466,904,980,436,169,700,474,799,72,101,505,520,830,988,214,339,29,236,159,402,990,461,26,215,43,157,254,973,903,661,262,822,407,173,401,847,532,194,776,877,377,203,107,971,809,562,343,397,278,967,361,717,782,362,417,887,625,54,536,152,690,812,314,99,265,544,727,198,620,389,695,843,895,754,657,416,506,172,977,853,547,954,33,223,910,228,582,790,18,794,926,796,501,666,324,861,602,108,538,179,880,513,462,357,289,981,243,795,987,329,766,836,917,184,610,90,608,544,513,261,84,460,431,77,671,205,27,267,771,800,784,692,451,74,217,958,215,229,457,649,647,126,378,760,469,774,271,51,103,256,976,825,859,4,471,200,951,447,54,738,301,225,696,820,757,221,151,476,818,374,205,182,126,527,121,295,612,312,122,922,405,682,538,665,66,75,14,27,271,469,713,222,211,73,97,346,501,135,2,139,309,374,619,476,750,952,385,783,788,538,607,28,556,644,968,284,993,67,813,578,783,709,986,904,414,901,509,729,331,459,863,269,86,294,660", "345,266,1000,351,362,70,988,871,946,77,607,284,616,695,483,498,421,368,961,732,473,176,680,943,222,474,339,837,954,922,225,123,758,665,840,253,493,743,183,569,668,644,26,443,636,514,135,36,343,923,322,850,978,970,863,504,276,36,483,769,328,547,399,310,857,417,264,807,569,952,845,424,901,255,350,431,362,697,692,87,687,326,736,654,626,800,831,650,460,256,624,832,756,83,998,564,141,91,630,633,338,302,26,225,829,971,317,760,476,642,989,668,676,476,542,662,646,248,692,886,771,89,386,618,748,232,532,901,742,692,320,336,971,378,331,918,879,85,119,177,510,449,712,238,827,565,432,916,77,508,425,334,139,371,333,616,38,885,721,457,674,907,273,279,643,47,173,899,394,211,950,853,619,419,71,180,465,650,931,77,400,303,904,610,918,681,344,387,63,894,886,599,928,983,86,467,458,982,891,901,467,836,639,677,39,346,398,423,683,137,424,326,143,124,445,377,827,8,459,208,794,255,380,339,181,615,716,421,594,250,416,438,33,193,992,207,298,389,175,413,898,525,565,370,10,788,38,419,435,678,347,639,882,934,45,414,352,120,256,39,517,279,547,611,667,966,25,548,186,959,380,15,915,635,92,79,426,884,360,678,41,736,548,348,642,758,497,147,597,689,101,799,630,890,43,157,897,427,495,86,692,68,38,550,485,67,749,367,223,221,612,458,318,639,820,251,586,308,304,22,638,769,545,661,842,203,820,730,151,150,571,129,531,660,879,589,947,314,23,241,234,827,509,952,127,700,276,42,851,419,431,926,581,256,597,244,763,347,975,675,561,706,950,691,679,907,196,575,941,785,220,309,709,421,816,648,482,340,522,320,532,335,249,341,639,226,666,233,763,357,41,695,426,664,134,418,30,112,394,399,70,384,666,520,287,680,498,864,105,321,62,547,677,533,167,701,589,418,125,207,924,731,952,953,418,205,114,619,153,459,449,76,278,918,894,340,167,147,955,8,354,289,914,801,177,595,880,474,84,816,286,805,677,274,22,136,126,587,683,625,459,195,800,474,812,377,965,390,211,75,768,532,996,809,75,834,250,709,606,368,789,602,871,297,512,449,325,649,809,276,243,510,200,559,476,763,571,820,413,899,120,918,89,900,811,931,816,275,107,994,227,818,14,121,615,533,362,218,350,640,647,970,63,343,637,577,344,494,768,277,764,684,163,511,254,854,441,852,370,382,219,307,708,905,813,659,724,179,994,332,734,88,303,386,146,260,58,142,280,761,385,248,121,690,735,523,116,4,224,360,282,848,306,506,107,929,122,650,681,294,922,534,407,172,485,900,282,994,269,203,711,693,352,377,883,14,263,393,499,678,463,105,491,25,349,686,680,112,703,332,225,418,808,438,580,268,879,170,870,296,597,938,785,310,952,976,891,131,166,522,831,867,49,585,582,943,766,587,456,1000,507,857,617,224,800,14,421,181,18,507,498,694,986,4,530,316,612,540,251,652,615,433,484,686,708,876,990,441,440,331,896,623,640,426,823,864,764,857,526,635,462,242,821,186,787,244,724,977,78,157,970,159,224,914,664,892,562,744,602,95,240,494,159,536,23,934,32,255,636,642,310,558,51,433,211,154,529,0,74,16,621,717,790,327,850,379,468,976,961,144,421,274,898,102,641,104,371,257,506,741,376,488,497,944,806,155,859,644,293,537,349,315,325,167,120,465,845,539,592,906,110,503,838,485,874,592,706,264,838,666,487,437,101,126,846,287,798,294,550,953,469,345,176,428,879,577,623,763,148,784,557,838,305,273,786,464,546,31,97,997,383,507,245,561,663,514,895,824,709,294,143,164,697,176,391,400,141,242,707,4,183,771,499,523,755,458,798,209,888,800,182,597,219,676,158,639,281,735,420,810,854,672,450,838,154,6,230,105,61,135,761,314,196,717,896,572,532,299,965,101,396,200,829,444,229,214,898,488,360,655,810,548,174,150,592,549,785,850,811,135,900,282,280,369,646,709,405,308,120,145,327,236,78,904,851,277,352,745,346,526,551,508,103,912,651,277,722,867,863,520,382,867,437,101,866,511,203,10,625,901,558,406,810,640,774,297,489,812,98,663,904,692,54,981,933,68,326,932,753,611,225,89,340,58,441,449,892,298,82,310,282,73,338,756,751,703,18,673,47,155,907,649,750,11,846,695,727,716,637,472,781,924,344,330,676,884,694,282,751,37,91,223,249,883,461,119,47,241,631,759,514,476,891,410,201,604,527,110,440,964", "480,866,517,431,600,493,562,194,247,212,367,172,581,399,118,518,208,73,801,286,873,251,922,390,70,983,922,462,104,44,859,962,80,137,106,896,608,652,436,662,853,595,985,297,439,736,364,988,751,34,682,573,531,19,797,585,328,691,27,728,440,340,491,201,441,519,646,327,350,46,34,443,196,543,661,388,260,240,844,605,599,592,647,987,260,528,416,448,127,523,943,791,980,432,906,337,125,703,486,29,335,190,382,844,913,834,375,57,623,878,871,340,893,729,873,649,297,180,969,908,28,284,893,642,781,623,266,339,189,140,156,11,196,696,11,995,72,398,314,638,653,578,973,218,901,360,123,7,611,273,727,240,810,275,552,849,278,589,786,415,605,392,836,745,882,944,516,421,300,856,173,68,22,283,250,496,299,931,894,925,455,322,746,837,588,229,99,160,155,71,95,53,674,59,732,279,608,165,560,655,511,551,30,34,773,245,62,712,529,300,90,416,292,53,274,297,988,903,599,842,470,338,476,816,289,567,203,417,252,933,31,44,371,575,751,892,473,203,980,452,73,101,386,452,426,46,562,609,880,896,191,428,613,431,906,425,86,418,233,374,393,353,576,397,622,684,21,931,919,42,677,395,827,853,130,887,525,588,2,993,50,792,561,920,758,681,140,98,98,951,47,501,738,486,251,604,75,195,746,620,736,705,52,479,228,574,471,628,831,356,950,514,192,726,878,975,117,239,30,7,493,558,595,674,341,808,325,192,717,369,488,957,270,993,431,409,41,86,159,320,191,469,900,491,984,514,764,637,89,340,660,495,242,744,332,733,408,522,797,104,897,529,680,810,76,746,915,60,909,756,792,45,464,810,756,785,568,145,291,227,170,498,926,762,553,821,773,163,170,751,402,746,804,897,339,260,279,675,404,304,629,8,634,602,696,526,830,37,867,337,442,368,77,720,244,543,951,352,742,629,657,289,548,243,806,644,40,534,779,409,35,102,646,592,357,182,418,125,364,135,868,992,51,693,526,553,730,911,665,266,484,450,78,199,969,277,588,370,648,428,438,817,398,716,811,154,700,998,97,823,589,74,405,864,636,110,963,859,897,74,709,733,58,521,475,341,900,127,481,701,862,73,606,192,18,688,752,730,779,707,163,854,988,494,98,877,72,716,372,432,865,428,248,143,211,937,727,448,827,873,578,518,286,562,342,944,535,325,270,307,642,250,286,794,701,896,593,775,614,808,827,930,994,548,97,942,687,273,479,642,525,993,308,424,856,858,268,144,502,637,124,554,715,724,780,946,753,124,506,267,199,519,792,296,566,318,906,761,481,690,925,488,927,122,58,488,204,272,151,545,999,43,244,482,692,741,620,180,440,298,322,34,229,200,369,460,765,994,740,107,714,408,243,120,5,431,943,380,501,977,818,679,618,55,228,208,602,746,128,276,753,541,874,821,399,629,452,809,941,402,681,296,138,193,660,462,233,920,723,222,910,672,733,198,81,832,352,767,306,469,631,356,725,938,186,991,253,626,712,91,974,888,965,229,990,384,881,455,474,582,969,164,441,910,678,484,352,663,203,93,863,187,524,662,403,421,790,826,397,433,970,433,996,302,919,25,471,98,821,320,1000,283,151,120,221,58,507,74,0,989,280,62,23,850,211,398,927,34,695,661,496,774,839,192,647,344,804,46,603,612,251,117,289,34,274,686,755,748,936,511,759,706,179,822,533,222,163,769,508,160,348,555,696,809,772,700,791,566,250,50,409,447,565,653,595,922,151,735,368,239,639,349,823,558,369,842,218,279,68,905,284,830,307,756,634,378,843,606,6,261,742,331,336,956,373,890,139,78,405,335,384,457,742,698,894,757,806,363,742,456,689,641,344,255,257,126,809,202,451,453,547,611,911,455,259,855,447,327,704,303,630,353,202,458,575,489,52,426,113,70,98,86,519,568,269,544,467,3,559,168,433,204,965,856,59,571,824,820,410,504,672,630,268,936,776,597,45,751,845,836,486,885,486,363,604,825,17,628,309,425,334,412,907,512,135,323,149,752,340,312,320,24,818,152,983,435,206,790,950,548,701,200,137,212,517,402,257,384,599,646,934,109,401,496,584,587,874,992,686,520,615,90,950,378,163,156,253,120,408,250,989,831,521,387,534,229,945,167,188,89,408,418,688,945,330,345,552,982,70,202,863,283,942,555,153,794,892,86,712,210,372,850,562,125,21,217,408,601,535,951,375,878,846,753,222,348,886,171,368,525,420,812,716,445,76,852,609,320,504,585", "604,792,991,323,681,509,116,530,967,598,984,379,561,6,625,382,607,33,496,234,960,342,100,893,847,125,964,893,553,55,538,854,359,608,334,534,676,35,927,81,373,785,944,602,484,453,259,671,778,884,356,317,95,60,133,745,659,94,28,38,848,904,147,897,466,845,701,157,201,134,451,549,997,428,288,439,538,267,267,924,608,288,325,360,912,933,34,562,150,66,119,679,419,801,760,290,228,128,116,742,910,49,418,330,773,637,179,977,862,805,402,696,644,964,908,346,941,385,999,277,786,70,631,334,244,56,879,323,345,75,301,679,546,505,150,822,939,977,122,53,157,222,470,633,810,809,639,156,399,293,781,312,133,819,540,766,912,198,580,5,413,969,979,520,62,256,81,854,254,170,691,556,705,798,218,726,941,881,499,756,764,361,801,351,415,181,416,134,881,981,530,420,42,80,447,214,643,320,540,292,770,976,289,391,251,826,482,117,493,410,206,568,165,546,709,256,876,86,234,836,340,780,829,437,125,77,347,523,252,571,291,620,891,608,651,20,418,655,277,582,598,355,576,902,726,448,498,843,416,442,736,45,609,672,155,197,248,120,699,149,125,832,757,500,531,63,708,220,275,421,620,149,954,510,792,229,782,810,816,958,716,80,358,849,975,540,649,445,640,473,550,562,651,806,83,948,44,400,991,963,440,950,144,944,486,237,789,917,420,237,440,331,798,843,513,534,325,927,189,113,292,172,959,191,157,661,75,266,146,481,294,891,156,89,725,910,808,76,429,534,415,528,83,833,138,911,208,99,657,675,323,489,934,46,724,561,128,522,694,314,281,286,531,164,729,10,350,253,479,474,314,153,527,667,917,483,946,611,730,864,908,303,237,595,95,968,454,816,609,151,898,856,654,315,640,987,928,970,135,693,916,604,81,905,348,536,72,411,980,100,460,452,214,393,722,643,574,68,253,651,488,202,86,60,517,153,733,563,316,523,81,960,970,864,215,598,912,656,531,777,324,831,765,254,582,254,670,814,675,781,426,298,917,25,242,624,749,596,596,176,262,375,400,139,916,941,292,50,52,579,359,451,384,802,620,154,39,708,801,57,55,54,749,613,113,157,236,591,73,886,201,792,317,91,743,329,350,509,2,636,490,609,503,524,228,329,53,487,373,370,494,942,793,292,963,467,633,147,233,287,701,434,8,84,34,887,473,573,181,725,186,904,125,741,588,581,978,224,297,859,796,316,646,693,37,966,759,861,783,875,179,98,417,119,166,557,243,251,101,96,572,955,415,195,297,943,120,725,197,910,103,361,240,554,530,79,388,969,792,509,369,211,848,226,603,113,886,720,325,851,173,595,211,298,590,845,577,736,391,243,759,405,287,152,887,508,422,493,277,922,461,281,242,942,450,186,682,632,819,187,598,409,826,56,360,831,356,709,161,640,770,313,227,375,517,66,14,193,919,826,132,862,667,700,524,75,348,176,658,432,777,193,18,387,572,931,194,913,220,827,19,375,326,752,301,695,235,548,780,283,372,844,661,189,231,803,974,912,388,603,307,949,708,594,619,554,165,386,523,862,623,809,732,342,57,995,484,902,654,843,456,381,970,990,131,172,941,297,722,163,391,686,932,934,871,794,509,16,989,0,553,500,370,416,634,430,418,859,136,912,805,945,792,67,867,330,169,97,11,814,484,826,199,2,959,294,648,118,741,881,16,142,538,102,90,537,833,251,283,609,197,810,42,128,856,887,218,700,295,248,59,135,773,839,690,409,161,780,793,398,460,998,579,134,636,132,801,476,635,409,375,126,701,829,535,201,129,916,392,813,59,457,385,424,721,918,789,818,170,377,981,444,500,903,308,155,137,125,304,546,207,609,332,496,714,418,949,523,899,663,723,50,677,21,844,967,758,754,351,224,210,798,577,75,210,928,130,234,587,807,234,723,302,491,380,432,476,597,518,557,551,290,16,149,248,515,502,843,857,882,917,545,791,953,333,746,462,405,320,361,972,735,819,422,859,4,167,186,375,25,877,668,18,802,684,927,344,410,681,234,162,538,89,940,848,243,187,329,154,358,902,983,205,244,361,364,771,252,474,459,558,30,242,937,646,270,59,837,800,697,766,871,965,952,359,4,80,455,873,751,977,710,114,143,938,893,310,787,972,533,257,876,310,236,24,337,666,648,872,325,804,415,797,642,615,340,675,41,204,248,390,194,171,94,743,577,468,293,382,258,940,348,51,756,53,229,397,244,998,306,67,310,773,401,284,887,33,772,674,600", "451,56,77,391,528,365,400,145,406,555,399,571,259,127,875,471,406,899,634,505,62,449,619,141,333,455,160,713,485,516,750,146,967,388,354,64,584,22,398,555,306,712,154,913,188,561,886,904,299,724,915,931,176,961,170,428,826,623,10,739,909,273,561,346,70,734,867,440,786,925,978,349,377,596,408,854,897,45,255,372,60,938,897,804,468,316,890,727,679,997,722,977,939,879,680,774,120,154,342,475,890,126,352,986,647,118,405,622,20,886,661,797,847,82,515,240,738,934,570,99,745,720,413,718,451,22,285,338,20,403,55,870,254,553,184,24,343,180,843,407,323,48,390,875,663,122,762,359,958,938,33,627,314,644,306,367,957,400,653,542,580,480,100,446,986,806,792,845,69,760,598,131,175,885,561,96,920,699,585,3,198,658,299,434,359,44,304,307,277,154,117,990,883,511,805,901,31,957,832,581,257,183,179,718,915,360,358,272,123,29,469,887,608,919,676,101,866,429,793,762,424,793,849,56,265,138,676,772,65,955,59,224,113,612,496,943,163,417,467,986,726,39,817,748,608,728,439,913,644,117,950,423,17,124,211,57,287,667,102,703,671,96,947,314,634,656,977,392,414,664,10,960,98,416,468,529,687,254,355,182,187,861,522,793,381,543,28,274,8,887,253,464,7,327,53,246,374,990,578,856,681,230,525,448,886,746,297,186,37,139,852,995,207,721,810,395,96,368,937,497,221,336,410,342,514,368,203,488,159,33,188,612,248,55,786,92,269,861,999,402,576,863,687,151,205,156,798,827,77,391,18,917,782,6,320,842,565,994,237,94,558,707,247,994,924,265,778,366,752,97,495,631,243,777,861,198,661,619,184,531,869,511,174,127,337,922,889,285,506,980,277,338,400,421,375,685,582,33,559,832,456,176,206,483,876,914,899,783,919,503,999,932,707,703,388,565,127,410,373,702,752,89,875,174,694,297,524,705,986,949,631,91,944,561,552,9,43,325,340,952,135,659,517,654,897,173,67,803,621,35,479,785,636,836,897,195,290,907,534,151,428,655,794,606,362,41,659,616,361,669,914,690,488,858,610,54,982,25,661,995,207,117,471,217,176,915,792,964,376,476,452,809,804,424,215,873,878,274,340,888,552,316,341,861,491,474,829,115,323,459,317,407,806,70,50,203,879,803,629,992,519,704,132,757,114,251,706,408,38,105,23,530,583,734,690,880,714,141,238,884,77,848,171,614,402,530,572,269,660,717,418,448,130,834,736,225,551,682,71,298,468,406,262,307,935,600,40,806,839,372,963,77,908,263,283,618,267,270,676,316,894,218,44,786,437,821,31,161,543,277,980,140,917,835,239,104,786,814,243,379,599,526,17,536,392,305,286,431,118,647,68,375,781,579,422,527,361,63,42,179,139,450,79,320,331,410,533,592,764,583,139,156,462,34,859,592,499,914,144,267,147,471,761,671,977,37,467,177,107,307,327,646,728,326,161,374,321,263,559,762,163,499,570,374,922,58,496,968,762,207,393,709,830,735,962,330,944,528,784,650,957,276,208,531,868,361,449,750,929,62,320,465,601,809,822,832,6,507,874,827,7,536,639,713,653,507,499,776,293,522,458,18,785,383,734,504,824,621,280,553,0,178,6,999,349,974,991,505,179,920,213,331,156,139,639,317,55,855,954,797,69,174,388,716,814,419,654,417,670,939,89,567,409,361,802,360,928,974,528,309,964,693,653,466,29,533,116,240,678,68,353,159,956,602,844,579,983,435,810,656,436,48,946,466,307,497,426,381,244,607,735,917,353,600,633,161,111,781,965,502,670,683,391,989,706,466,365,54,697,235,810,855,261,964,682,360,99,517,177,505,553,300,204,44,287,560,147,412,73,629,694,563,94,379,744,229,483,909,821,231,190,572,843,884,613,258,486,746,391,844,288,142,848,526,29,658,348,208,159,243,577,145,124,133,42,682,193,637,412,896,435,335,190,588,636,799,504,305,140,322,194,812,642,374,303,267,89,503,445,716,149,101,542,575,878,297,76,311,311,652,654,136,606,595,547,598,972,969,674,258,518,251,867,271,969,459,138,307,740,524,554,844,108,165,616,896,715,865,166,104,935,586,822,839,402,750,310,922,505,815,63,269,168,88,900,56,144,663,978,616,738,736,823,688,620,581,272,610,555,489,963,269,910,916,51,515,85,874,311,905,814,400,320,688,534,923,346,288,342,252,981,73,264,643,580,552,381,641,572,279,162,269,872,609,580,811,258,27,185,539", "271,337,617,359,416,595,21,879,206,805,973,461,653,936,209,984,527,101,531,920,246,121,36,911,932,566,480,120,842,356,417,80,283,923,273,456,181,75,364,571,622,854,344,106,541,463,710,318,382,416,283,75,598,332,603,878,846,71,716,162,163,799,844,169,625,302,214,603,749,426,183,180,81,215,645,939,563,583,664,250,963,487,100,651,587,916,402,840,466,108,968,381,65,344,484,571,914,274,138,311,862,12,550,836,625,464,904,589,536,366,827,952,127,585,770,647,124,589,181,712,732,253,740,469,941,903,431,875,207,878,583,86,34,808,21,215,30,329,251,794,927,268,380,33,614,430,702,619,271,581,594,103,766,619,179,948,965,673,720,579,113,732,909,418,666,978,387,419,74,846,697,206,838,678,191,149,621,517,905,20,726,186,375,6,267,141,462,905,298,256,592,576,266,782,941,138,827,963,465,73,87,671,532,121,459,308,165,780,173,735,315,901,458,790,256,742,82,536,550,628,704,114,732,977,755,405,86,898,993,622,712,478,798,923,197,737,600,101,186,217,456,132,883,571,221,289,376,871,643,733,558,268,602,363,99,2,372,1,566,945,543,400,204,59,437,292,735,419,530,195,281,509,295,455,872,74,670,722,205,315,884,410,316,328,192,70,729,385,469,640,129,401,250,148,769,143,847,301,413,323,960,857,516,427,452,771,606,831,253,765,795,500,966,726,783,679,201,178,644,197,348,292,91,849,923,840,472,546,618,527,172,210,463,111,237,742,61,483,604,223,314,865,829,272,697,643,536,229,871,91,731,98,465,17,13,329,563,53,427,982,428,875,894,324,227,505,158,987,615,545,631,898,812,686,124,620,310,294,146,101,940,77,363,197,872,550,363,106,881,164,823,704,186,736,390,974,221,645,247,623,129,690,719,387,192,566,437,891,86,85,152,116,55,249,603,527,555,927,148,267,411,966,722,2,998,528,462,88,235,599,547,581,30,559,881,960,974,315,312,908,382,97,205,292,991,890,502,722,631,396,704,6,741,443,684,842,6,3,252,549,253,542,359,358,225,3,361,39,274,990,444,523,165,890,371,474,658,494,193,970,966,500,734,550,400,757,54,977,361,760,34,12,53,576,972,410,841,39,668,81,476,20,373,826,245,445,161,607,695,340,152,14,156,691,558,54,420,368,91,962,274,20,570,664,265,638,483,151,214,409,855,457,838,895,336,960,532,334,463,152,963,290,686,194,838,869,514,625,13,882,73,203,716,790,650,894,781,270,817,389,509,29,428,785,211,145,463,489,576,397,79,125,412,144,519,952,863,668,10,250,158,668,276,625,336,75,898,516,186,714,458,648,13,432,105,450,685,218,851,333,230,392,979,537,630,181,973,887,425,227,710,209,269,29,63,893,132,322,391,925,104,229,760,974,945,714,777,769,39,541,318,560,68,811,311,373,404,618,856,410,913,196,504,520,535,724,939,489,464,151,84,590,897,467,640,674,872,450,553,321,631,712,103,614,967,9,124,141,841,522,939,106,535,329,1000,991,697,569,349,326,124,520,588,164,16,478,9,633,824,804,172,557,910,443,12,855,891,92,966,619,299,920,877,840,353,901,102,733,469,283,472,164,82,686,932,165,243,717,62,500,178,0,797,584,621,148,726,386,380,532,473,184,540,237,917,659,647,879,682,864,685,356,275,986,719,32,562,647,575,397,801,724,64,380,1,215,979,792,519,392,693,15,6,876,723,40,492,219,164,604,200,590,860,223,385,273,914,394,847,870,48,760,47,834,268,161,815,688,510,957,770,184,960,657,463,291,944,15,493,918,268,68,732,381,816,435,914,783,748,939,142,895,559,594,844,315,76,689,898,920,121,541,128,20,516,86,251,849,899,742,545,110,170,662,755,203,547,485,228,38,678,125,167,62,503,916,53,74,370,800,137,207,554,217,569,112,351,724,705,456,804,77,758,658,608,42,929,562,864,453,105,471,40,805,484,473,94,362,535,590,623,38,886,367,832,806,893,670,336,837,561,441,157,640,448,80,850,949,762,798,541,610,418,875,69,523,672,568,640,839,358,662,57,133,553,376,751,520,453,992,953,140,812,974,852,638,462,684,679,398,636,135,216,995,100,958,362,23,79,758,168,336,904,528,290,919,238,993,477,249,596,42,300,677,116,159,985,932,632,25,485,719,330,264,630,192,185,448,158,797,910,518,900,738,32,31,621,62,365,755,363,940,650,177,957,113,648,410,289,83,280,597,355,65,758,622,184,197,277,320", "99,424,659,930,971,142,111,578,370,173,458,19,951,767,762,876,815,790,252,668,3,160,645,652,359,966,824,516,334,307,963,200,699,958,37,533,623,809,605,45,514,661,94,941,655,958,152,555,393,296,195,249,569,363,659,672,746,73,313,782,329,426,219,595,20,703,220,999,356,357,79,463,147,202,437,209,757,58,110,299,216,326,604,239,420,64,252,559,983,923,166,711,4,492,599,981,91,724,149,386,112,9,146,548,196,458,802,564,708,797,455,318,802,589,775,556,562,584,481,895,16,282,15,295,329,231,654,972,67,950,6,877,713,688,584,762,967,315,217,152,707,180,415,8,356,196,125,977,409,879,231,298,132,361,342,259,910,617,255,199,293,503,976,808,772,336,985,458,340,513,508,770,971,736,730,606,731,255,509,12,406,647,62,436,576,125,425,820,981,231,60,918,495,952,882,647,327,266,358,932,493,159,411,988,45,829,348,250,150,912,78,367,209,593,459,259,872,663,778,362,688,199,436,994,867,352,785,494,251,801,175,814,842,88,883,1000,713,86,513,376,959,694,789,968,585,262,79,834,128,190,193,52,205,537,168,252,188,912,539,697,176,304,307,896,830,840,885,380,754,905,710,223,651,105,341,226,758,359,214,649,637,785,338,544,613,387,264,264,569,776,773,685,65,846,476,817,650,41,365,912,21,878,332,592,539,531,479,700,426,240,831,297,43,534,371,575,456,676,143,199,887,359,138,979,559,789,376,370,223,16,97,742,377,985,610,818,154,443,982,42,791,943,326,208,33,209,40,64,724,179,764,2,653,157,706,622,71,833,871,506,921,988,1000,672,150,611,149,602,793,615,982,336,153,802,842,211,142,321,737,530,856,428,707,351,308,429,706,498,242,975,417,258,546,9,301,74,799,901,64,979,447,831,90,202,849,510,305,999,888,184,667,465,947,527,336,52,646,852,228,316,631,80,702,210,105,292,545,588,647,332,890,604,452,267,840,654,174,294,426,605,759,306,63,575,310,503,697,602,989,674,727,500,216,344,55,628,1,836,69,11,615,389,975,487,225,427,164,646,619,778,503,734,129,768,940,325,598,934,997,719,9,464,996,303,571,289,658,440,647,964,219,46,43,984,617,830,646,32,807,883,104,455,251,769,629,150,393,681,190,367,272,284,540,811,550,221,451,627,632,218,39,326,885,36,544,569,9,110,853,700,158,352,153,144,446,453,478,827,412,59,904,778,77,790,240,651,722,566,363,787,585,472,966,139,352,17,50,33,435,540,272,784,105,716,748,195,308,814,726,167,484,151,406,836,979,433,960,891,43,36,605,125,466,570,421,995,900,504,760,305,855,903,946,500,843,371,154,999,779,532,994,456,365,92,645,161,697,889,385,781,947,525,781,19,454,39,424,777,454,339,71,278,667,814,579,811,270,462,981,670,331,529,33,357,808,706,885,156,825,685,582,349,518,632,779,816,300,74,962,613,157,181,350,392,495,451,672,747,835,876,797,504,447,784,857,258,240,634,22,425,872,46,132,270,136,211,805,272,18,43,243,827,891,372,805,1,640,184,486,358,365,426,341,148,112,566,790,720,858,819,468,337,615,474,338,184,260,701,139,767,276,108,534,240,488,146,264,790,23,370,6,797,0,761,350,35,495,240,758,552,732,238,399,642,288,804,913,56,728,542,208,192,34,571,649,151,523,145,443,612,966,561,220,939,419,365,477,853,215,726,604,317,872,661,306,915,552,969,793,736,509,231,203,687,966,288,49,349,882,483,920,458,440,123,25,273,766,326,457,690,717,333,729,471,607,354,697,668,492,817,830,289,155,984,428,305,102,491,308,573,810,581,503,799,312,80,944,542,403,300,738,879,427,843,672,984,586,123,96,882,19,588,597,992,228,602,895,456,625,283,113,317,691,93,832,858,556,550,342,531,746,587,22,903,592,313,786,519,984,337,861,617,186,793,373,727,879,503,560,932,890,744,185,52,767,259,541,823,11,265,303,349,967,254,282,493,227,547,584,555,347,470,517,783,788,786,623,478,176,403,439,788,722,850,849,248,643,430,816,988,308,603,26,301,234,856,922,95,289,379,957,312,633,691,359,229,272,812,10,808,857,886,470,513,976,373,460,957,785,368,152,39,580,664,21,313,47,60,59,155,874,727,420,441,591,809,344,298,577,490,679,444,925,308,317,145,940,306,700,346,832,503,177,148,628,91,10,120,840,739,829,331,998,540,954,690,606,582,986,71,936,258,728,431,502,901,508,386,820,313", "81,136,695,967,781,234,369,52,568,312,931,506,485,509,182,446,100,551,553,324,986,488,728,681,508,371,347,454,808,463,459,55,962,280,382,112,675,199,96,244,313,428,586,268,444,21,452,714,458,899,431,1000,142,36,26,588,910,845,653,575,681,70,905,596,177,375,602,156,249,336,693,959,837,351,719,557,794,891,882,651,697,351,352,572,532,764,137,470,349,860,106,367,424,18,795,666,668,152,676,580,357,351,296,33,276,698,485,949,64,773,228,169,572,709,790,161,646,215,518,684,86,466,655,381,856,618,819,736,894,555,480,328,610,479,792,450,765,76,262,690,149,21,469,474,488,782,498,831,454,110,787,996,786,194,673,985,167,923,608,768,840,778,540,619,77,569,3,270,955,322,603,780,723,849,464,180,3,323,782,373,776,597,897,914,827,424,767,767,57,24,461,271,88,345,71,323,149,576,659,112,306,321,586,668,943,914,29,272,73,637,147,278,823,398,404,723,821,634,602,399,193,309,974,769,233,90,745,371,125,347,2,112,518,278,420,102,319,454,28,908,115,649,775,297,290,227,912,119,307,904,798,239,779,972,668,710,396,742,51,739,449,196,13,66,952,375,354,465,632,669,681,736,365,854,370,473,51,5,920,515,325,281,706,26,546,321,795,495,628,745,671,634,716,987,213,622,435,272,129,150,653,7,383,796,654,267,519,279,202,870,851,504,256,225,803,582,43,298,871,290,88,825,654,318,343,956,630,228,325,450,374,699,450,620,511,177,633,70,995,172,971,704,291,101,965,828,937,360,458,230,518,361,634,675,193,91,620,401,916,401,50,703,716,619,773,431,24,73,329,390,335,38,268,284,463,788,686,645,77,825,11,369,418,425,445,936,997,138,150,470,257,269,918,809,977,457,60,223,984,330,975,772,288,208,632,776,929,4,622,64,126,203,754,311,7,547,470,843,807,261,343,536,795,521,727,468,848,779,565,399,42,584,506,478,625,841,602,379,357,703,621,104,313,147,737,961,314,750,735,163,699,375,617,393,768,670,49,396,826,247,397,226,200,439,556,11,87,189,201,443,33,308,194,698,873,548,994,840,126,124,55,670,74,454,744,376,602,758,477,684,440,769,646,718,738,846,792,637,897,868,885,952,373,956,652,377,571,892,495,822,158,2,806,632,11,47,119,649,718,610,864,729,159,347,947,688,414,825,49,940,643,899,623,862,703,498,751,605,164,557,140,219,657,112,462,867,146,213,60,959,385,455,231,196,40,689,853,774,159,352,582,321,370,804,863,418,57,668,135,436,7,568,195,461,7,876,117,345,598,761,188,207,914,144,531,728,730,331,95,842,713,774,789,104,485,868,322,231,712,291,196,568,78,383,132,179,881,940,908,338,70,654,305,121,680,30,598,670,41,65,664,396,22,319,151,754,920,735,337,242,706,620,871,908,609,839,76,901,50,292,154,100,672,400,985,805,707,624,922,708,608,764,890,40,985,300,580,788,993,717,839,890,38,914,288,935,843,546,849,284,323,468,752,48,312,964,723,762,807,398,10,290,758,120,247,519,585,785,232,33,701,239,86,597,890,355,459,904,598,750,926,48,766,522,170,698,871,569,281,728,295,107,402,100,687,781,524,327,850,416,999,584,761,0,937,561,723,101,974,128,642,105,959,425,220,407,575,132,220,539,279,348,524,924,856,690,789,185,41,478,648,134,686,574,564,38,769,908,951,399,840,343,93,758,532,316,503,621,825,642,307,119,267,621,515,170,602,913,568,781,526,700,440,380,156,564,1,110,885,27,914,316,946,416,485,431,497,339,820,92,358,54,16,326,862,279,848,641,480,874,12,954,432,629,61,109,490,557,927,440,115,459,477,622,406,888,83,342,193,725,777,287,137,642,512,447,753,970,103,559,174,536,273,873,437,467,604,598,883,944,386,734,38,941,149,62,620,48,62,644,982,545,190,295,339,530,10,401,932,38,814,631,797,916,88,489,588,301,247,960,367,679,227,162,149,452,149,562,437,644,776,378,512,276,466,221,306,610,283,362,767,116,347,61,486,240,787,208,909,377,981,286,273,307,339,641,97,391,358,107,174,119,256,815,133,106,899,532,489,564,796,810,413,458,330,143,121,453,730,717,6,396,484,794,510,356,851,967,72,882,562,837,215,415,625,859,16,177,345,782,657,852,522,789,622,802,522,999,594,631,604,511,790,168,543,979,942,834,212,636,2,155,473,904,223,500,48,128,440,349,165,32,742,682,416,28,384,75,221,414", "131,669,334,986,46,819,898,733,80,377,500,892,469,459,504,32,632,769,591,959,749,494,472,910,786,502,158,284,371,196,643,978,664,608,632,823,722,307,722,245,235,625,917,440,568,598,562,295,390,681,87,693,325,246,719,125,407,425,514,777,259,911,294,281,418,906,746,6,551,158,679,562,850,725,868,466,960,321,704,74,594,90,992,225,87,211,524,470,135,447,954,124,552,223,243,242,865,378,423,943,622,670,953,681,83,690,598,756,376,725,291,901,855,891,720,327,857,468,764,261,900,652,534,342,519,147,984,974,633,399,563,181,262,193,483,166,70,361,428,39,211,287,20,787,499,472,742,568,539,807,594,344,97,915,736,740,701,396,478,747,197,720,351,623,336,668,983,566,423,789,836,276,274,485,997,401,409,849,645,286,157,430,935,729,968,32,694,465,242,109,717,507,7,864,216,219,661,382,247,362,436,981,808,116,691,456,73,968,592,443,84,192,97,598,532,854,852,68,388,622,760,537,592,863,697,434,231,768,813,54,895,161,230,663,336,520,357,793,985,562,250,779,973,770,740,112,725,174,17,27,733,471,678,775,638,457,143,64,107,733,845,985,874,276,701,72,890,809,626,558,859,850,237,768,548,586,357,453,566,247,863,541,960,203,435,281,582,703,682,165,187,822,953,165,821,660,404,166,79,829,266,849,908,365,710,468,275,753,449,403,683,917,609,724,615,770,125,204,32,233,717,313,67,733,901,470,58,128,859,400,562,858,29,158,205,862,488,138,97,204,577,485,778,228,398,414,718,303,907,281,380,707,323,992,699,457,269,95,399,854,864,943,915,686,349,751,621,236,418,902,637,289,993,676,317,79,831,259,593,829,135,568,840,602,799,889,617,819,690,414,695,563,59,33,626,79,421,507,609,300,350,90,729,7,846,205,672,211,931,193,626,178,994,743,15,23,44,113,489,996,916,837,965,795,294,45,3,642,331,864,431,222,50,117,972,21,140,566,41,56,201,763,761,157,514,319,61,571,672,624,308,148,246,331,409,546,299,441,806,279,374,327,978,952,168,704,8,362,634,462,956,822,779,73,907,695,349,658,269,154,66,586,731,51,32,709,694,22,574,212,359,99,565,815,122,744,560,104,787,32,992,88,74,656,494,876,912,551,741,925,452,12,487,264,168,208,665,654,351,183,829,299,81,265,117,876,896,954,209,711,501,99,325,600,153,406,952,771,864,816,685,7,836,571,14,227,496,896,69,364,515,823,274,15,885,144,502,20,584,125,629,854,24,33,454,70,341,7,491,307,237,907,638,145,299,988,732,577,170,855,32,56,161,562,574,600,176,742,930,735,4,182,196,929,189,243,793,100,447,520,495,400,666,305,779,863,200,697,485,295,859,538,301,875,670,69,869,625,304,756,770,739,425,281,906,544,581,429,142,567,352,913,903,667,480,35,134,548,206,445,740,902,187,578,11,853,689,372,367,581,971,200,949,762,616,958,58,936,868,51,821,551,998,968,260,177,184,943,179,981,520,409,593,453,313,77,394,578,49,586,854,514,723,739,244,386,226,239,9,581,804,930,451,636,692,351,527,769,102,728,854,764,155,453,671,377,475,597,21,783,807,433,415,766,176,437,662,850,211,634,349,621,350,937,0,501,967,795,909,662,159,444,815,681,939,476,731,69,570,903,919,260,21,323,897,864,478,89,583,275,911,104,898,581,861,506,339,161,230,912,398,988,162,964,388,896,29,973,18,351,671,404,348,157,142,172,306,332,811,158,35,535,442,327,921,1000,911,436,570,76,514,474,574,787,376,896,666,110,449,127,65,647,253,53,299,468,577,917,557,254,74,441,221,219,893,175,388,868,259,175,789,376,586,896,930,71,619,620,373,790,221,286,293,358,751,676,750,539,566,812,748,945,210,171,243,428,119,984,393,7,115,458,11,685,45,641,536,430,32,630,910,432,387,414,437,74,338,562,757,900,401,574,975,534,978,787,209,51,804,150,67,721,520,240,398,843,209,184,502,333,965,559,534,597,820,108,701,420,257,992,417,318,18,743,188,166,571,56,598,139,151,808,161,845,214,581,321,540,271,188,469,365,751,462,998,793,937,638,307,140,907,315,635,625,697,898,56,625,694,858,921,871,428,117,772,44,93,227,754,177,81,151,785,819,619,268,582,557,887,999,570,938,68,224,928,114,417,486,187,238,423,733,37,900,98,963,707,166,452,138,855,566,783,903,784,961,562,855,293,399,15,8,648,134,660,660,497,880,778,175", "902,2,797,306,230,305,20,158,790,278,355,978,195,894,185,556,964,38,746,410,66,126,468,822,982,835,643,721,726,364,104,830,684,763,365,833,525,298,121,208,202,218,522,680,935,333,755,484,368,543,801,811,463,757,681,448,473,462,569,159,122,951,345,80,380,390,782,440,918,421,144,96,511,26,623,991,907,747,172,896,627,179,52,940,274,619,778,350,498,217,656,16,123,163,622,618,607,630,382,711,106,755,354,595,119,223,703,341,984,987,836,43,848,252,954,747,209,989,830,644,936,434,21,798,694,499,782,41,735,466,288,504,271,589,672,790,574,583,337,522,583,687,523,70,435,99,212,842,377,468,855,693,58,16,47,841,45,472,207,499,847,796,120,862,752,394,461,682,204,978,750,500,100,474,121,49,841,758,651,308,95,750,889,518,889,656,223,251,307,878,299,244,184,714,500,956,731,830,436,25,455,699,677,573,126,160,260,163,137,850,373,337,39,165,620,365,924,798,78,146,575,203,752,848,381,743,181,758,71,487,983,720,126,591,3,374,805,445,960,545,608,156,999,475,678,302,803,894,452,330,114,76,655,893,780,924,110,298,947,172,248,847,364,288,470,970,285,725,558,835,234,53,346,305,291,730,96,562,704,408,597,944,341,946,573,976,497,967,424,856,339,80,437,802,466,887,251,331,496,265,439,50,954,982,311,111,770,506,376,363,831,792,936,988,415,674,619,618,676,484,717,359,409,436,456,502,846,153,912,213,565,178,165,803,351,861,967,921,681,268,845,965,719,769,636,340,14,255,449,533,5,837,205,25,232,544,306,444,300,516,412,335,310,338,180,145,59,163,139,129,535,974,320,84,774,574,18,69,591,380,690,190,69,182,983,243,813,527,399,669,542,358,964,152,753,80,476,358,743,118,46,717,575,663,565,930,464,304,949,542,648,892,647,338,636,722,26,812,979,840,455,82,610,128,356,358,622,812,717,292,271,98,150,449,191,611,709,109,549,148,210,353,286,559,809,741,925,120,122,372,111,523,676,690,429,452,146,963,576,508,822,751,261,955,95,295,710,664,233,58,124,499,878,499,590,960,527,387,36,389,394,290,427,176,743,432,376,486,130,612,20,238,233,170,731,802,443,505,217,585,538,813,124,600,433,207,422,401,830,170,390,37,276,813,393,381,957,351,876,546,544,890,330,552,852,585,834,480,47,323,982,165,475,614,645,532,372,446,59,762,819,512,870,839,485,115,945,901,37,437,434,963,823,644,673,574,690,696,906,924,170,176,997,57,661,205,726,457,901,429,492,450,885,898,171,688,349,50,172,621,967,764,533,156,727,23,771,243,539,550,655,299,185,809,736,738,49,554,516,565,724,328,896,240,729,50,216,219,236,268,669,809,24,73,931,969,354,950,189,263,970,368,629,661,667,812,792,109,529,162,730,754,957,576,523,754,150,203,194,319,799,584,240,49,609,631,201,565,768,865,709,292,224,41,969,512,86,881,487,709,863,433,169,838,764,850,87,773,459,26,963,100,353,71,157,537,640,583,836,385,317,175,927,997,888,834,58,912,358,25,807,736,86,709,755,756,69,891,616,557,778,50,300,67,69,421,639,379,117,34,465,82,532,178,997,233,189,379,398,430,974,148,35,561,501,0,255,63,776,647,685,703,364,449,530,506,210,382,743,8,675,260,551,833,795,554,701,15,271,849,802,277,24,856,742,458,818,65,311,227,388,644,622,680,803,670,690,651,636,764,691,255,764,528,776,885,924,379,250,949,675,78,431,421,41,31,54,733,770,426,596,60,734,380,195,18,82,809,744,211,102,729,973,311,107,875,250,566,441,364,450,984,474,850,854,754,801,708,465,842,308,471,321,657,905,791,994,331,714,691,358,164,215,213,511,768,599,372,851,792,24,322,105,693,500,665,13,267,96,943,377,155,190,834,724,500,290,881,60,292,34,346,418,438,62,941,175,138,843,567,848,899,41,884,465,806,568,373,574,438,79,927,805,666,716,512,855,968,608,391,539,775,271,97,856,239,332,173,768,918,211,845,586,929,783,921,874,177,442,235,687,758,319,199,249,453,523,512,701,90,680,257,894,841,784,849,870,294,801,442,77,229,638,845,945,671,753,694,357,324,403,614,608,141,15,893,211,877,730,957,202,204,399,743,866,583,411,831,501,476,434,124,516,660,69,767,459,619,415,609,792,942,243,434,495,104,519,4,929,622,886,226,727,867,379,235,800,718,770,741,970,232,166,868,639,758,748,958,123,703", "314,568,375,796,837,924,653,218,262,78,119,606,814,986,327,752,52,771,734,851,552,142,303,387,463,19,632,715,625,36,183,794,782,336,365,423,238,386,676,958,468,540,588,14,696,843,664,553,83,708,545,400,404,886,929,349,550,667,701,73,34,365,283,67,919,871,325,409,474,650,697,209,438,472,855,500,506,182,450,511,116,907,207,179,564,594,502,934,180,750,393,284,49,995,489,323,639,257,892,665,565,205,947,723,492,594,918,55,18,735,253,833,441,682,931,360,705,982,800,854,998,422,92,750,363,144,389,757,494,699,773,548,79,540,967,277,199,150,373,738,358,642,124,284,898,491,570,203,765,808,59,152,580,543,171,170,538,692,476,816,15,811,364,208,9,748,758,40,457,10,648,15,301,494,335,98,990,948,390,272,842,163,668,983,849,806,744,464,257,158,405,836,690,416,480,16,28,927,338,784,584,685,147,160,82,990,414,950,324,202,831,805,523,459,590,218,534,236,881,268,107,467,241,278,580,496,540,739,973,506,952,584,145,255,57,831,134,242,96,283,490,233,935,307,420,951,333,575,832,637,11,507,331,42,938,321,108,226,866,995,944,174,189,84,967,181,396,636,471,287,311,442,285,318,410,221,774,558,974,908,266,714,903,981,770,335,424,155,275,494,512,114,591,672,349,135,162,179,257,851,795,765,587,882,342,870,11,51,434,616,476,648,63,61,532,561,400,622,200,378,196,530,173,732,72,187,381,203,529,172,423,101,57,478,303,855,868,547,912,253,334,502,482,812,399,877,21,555,674,759,88,624,694,552,855,591,454,455,255,173,150,669,399,80,853,537,378,179,273,964,100,430,849,353,789,767,786,181,98,8,742,591,402,277,795,663,921,923,380,591,622,522,13,900,803,46,632,955,418,237,609,310,905,3,272,726,668,190,760,648,839,124,505,200,80,394,48,46,95,2,968,81,317,581,252,32,709,250,148,758,249,229,584,75,888,682,345,885,482,697,457,813,133,288,826,177,108,723,662,978,871,398,952,382,846,706,252,498,925,775,290,180,831,440,164,481,397,830,646,368,920,663,468,412,547,761,13,913,623,723,706,346,374,588,855,319,985,660,723,426,672,416,141,99,873,943,365,668,269,120,349,136,175,605,490,505,29,505,704,629,801,279,540,683,626,841,508,294,451,298,447,99,70,772,335,627,354,312,309,194,367,109,205,832,106,884,647,758,808,75,159,490,19,945,124,763,237,12,305,241,997,153,650,662,752,858,794,288,800,89,267,972,200,143,489,888,266,954,34,963,560,442,207,545,126,594,731,249,271,553,823,164,89,928,756,594,938,891,904,960,637,57,594,151,147,517,197,753,924,512,377,735,443,2,588,186,204,902,707,749,273,361,900,718,140,901,720,987,123,702,612,125,95,979,177,441,321,576,782,203,588,144,508,178,992,709,593,735,556,234,511,537,255,719,469,315,411,771,592,748,561,485,561,680,846,531,136,247,306,625,40,602,749,323,954,264,10,450,118,311,936,665,696,82,508,160,733,934,868,853,678,62,949,644,326,191,203,729,842,254,301,856,460,661,401,14,472,926,440,516,593,690,195,377,684,490,658,823,312,966,923,896,687,966,662,666,184,468,927,418,991,726,495,723,967,255,0,41,935,909,571,156,680,901,290,975,542,975,351,558,493,984,172,933,822,4,910,122,118,852,409,862,545,788,128,138,838,875,327,549,583,61,771,197,481,798,949,541,675,429,926,570,869,696,129,961,924,600,899,586,735,872,130,985,866,664,768,445,704,254,2,426,298,148,515,242,469,179,838,953,363,202,936,207,429,527,47,783,536,450,463,119,591,832,152,73,622,844,626,615,859,399,493,408,554,361,339,821,740,436,355,943,911,77,435,211,424,729,715,263,815,618,904,515,32,809,857,539,122,809,356,450,197,690,141,803,554,131,896,366,468,787,856,622,423,31,75,593,594,756,343,338,596,941,679,683,444,269,404,742,986,901,759,884,715,36,621,871,747,786,443,740,523,163,384,870,866,603,576,210,292,566,944,809,716,293,278,429,517,38,443,981,887,260,615,483,500,838,114,474,836,587,203,364,386,157,694,754,563,446,67,94,857,565,440,822,550,300,143,464,903,429,766,578,969,652,640,712,812,147,305,220,493,442,658,139,299,888,615,603,725,897,11,945,2,503,792,381,472,370,986,130,808,77,270,729,607,781,7,531,45,655,850,765,502,441,760,908,146,213,751,682,679,875,36,312,35,136,871,438", "436,584,721,625,541,312,498,976,773,33,801,285,112,87,232,39,828,890,87,471,351,598,907,959,380,706,528,137,465,291,459,143,598,376,70,779,629,479,440,111,821,891,498,982,464,906,654,386,200,657,784,982,409,506,324,139,958,210,16,226,291,171,383,65,856,733,484,888,306,890,373,873,713,783,693,446,509,216,276,594,865,667,925,25,433,939,65,692,61,433,655,162,381,315,424,241,530,348,330,363,225,309,894,798,267,860,679,873,733,145,826,548,48,531,528,222,170,326,121,151,507,359,164,665,427,136,319,275,150,532,862,99,150,802,61,207,963,468,844,491,623,863,989,723,456,952,230,324,503,946,287,218,183,818,834,825,780,626,830,773,387,937,506,283,591,797,947,247,694,47,652,202,709,825,253,740,845,345,341,688,9,212,415,505,609,305,988,483,583,915,295,326,446,670,270,919,293,48,430,647,965,475,200,729,238,317,218,186,685,410,471,419,645,546,192,484,487,433,545,173,412,437,449,970,489,329,536,831,360,23,176,805,261,245,426,85,730,989,111,912,19,193,948,635,647,542,984,980,3,683,820,209,620,229,742,425,858,273,40,549,867,148,701,447,285,994,533,291,409,301,379,296,964,115,317,375,976,638,413,271,768,176,721,177,954,639,65,125,462,589,827,555,688,315,502,338,257,222,77,471,946,422,312,555,215,679,886,119,773,463,370,83,142,715,740,712,991,852,504,401,758,248,852,941,599,486,297,627,330,400,710,293,758,978,298,142,250,746,92,694,67,659,653,154,726,140,191,853,870,799,217,868,112,337,21,898,163,711,606,159,945,411,164,161,827,389,883,772,631,725,894,213,789,191,512,436,825,669,763,827,897,863,242,419,935,65,677,113,418,820,9,547,860,145,462,593,943,216,58,207,256,849,389,838,658,422,350,961,298,886,871,930,677,459,748,744,303,637,918,749,287,735,127,104,97,391,547,369,474,467,464,573,172,183,782,980,333,518,154,144,704,223,873,439,16,287,805,49,951,876,605,479,204,575,517,701,244,713,530,917,839,897,359,585,484,755,553,393,640,151,132,451,765,867,953,149,741,69,708,222,483,118,400,878,89,598,946,535,674,145,144,616,117,967,903,527,723,268,361,785,679,638,191,250,958,782,748,121,67,945,724,194,228,881,641,910,548,491,390,846,517,720,296,697,27,122,647,634,336,620,117,426,99,589,964,377,226,52,456,901,226,197,504,310,878,392,485,946,96,380,796,654,864,416,735,784,872,690,633,716,545,503,489,409,329,142,283,879,774,457,720,428,633,346,425,930,449,766,922,221,471,398,210,453,808,591,535,839,523,120,879,772,561,590,949,510,671,15,865,562,992,673,525,262,705,617,843,173,238,103,363,690,923,753,3,328,411,423,395,919,390,222,122,448,525,422,945,171,951,531,956,216,23,245,660,757,892,897,49,215,979,559,592,803,476,213,726,349,886,299,261,820,950,739,212,673,573,814,273,621,393,228,24,775,83,557,734,615,993,244,827,26,295,471,789,300,263,19,144,67,341,154,20,180,369,561,564,424,481,620,879,875,722,383,874,237,194,675,900,57,533,511,924,657,380,819,654,562,286,437,814,332,597,102,168,959,475,976,34,859,505,386,240,101,795,63,41,0,5,696,262,580,105,97,732,754,413,378,586,228,741,152,484,314,171,474,918,79,826,91,869,189,56,114,906,171,893,456,229,124,12,904,602,87,257,408,263,670,715,588,994,377,316,817,83,863,671,727,166,998,218,632,23,426,60,884,931,607,216,569,123,427,115,895,498,933,83,364,410,408,411,972,866,513,756,782,574,67,622,98,815,932,429,191,448,430,501,629,55,232,102,758,548,522,374,468,605,14,317,672,515,598,961,272,323,523,586,324,481,679,532,885,400,247,214,565,112,843,285,471,393,584,603,168,413,282,108,773,33,809,664,128,438,459,578,178,549,22,716,858,82,893,737,656,508,632,179,892,378,946,996,54,79,262,633,447,74,213,551,357,540,601,254,629,610,708,528,920,912,225,807,323,844,298,71,838,105,520,8,271,296,389,54,621,920,767,521,619,150,508,202,706,158,896,60,726,35,232,621,573,660,817,402,617,799,900,605,587,154,252,879,288,745,936,615,979,237,967,535,970,404,386,782,243,787,43,420,860,616,330,518,787,209,141,54,786,395,17,671,315,574,216,689,229,992,569,568,649,896,417,501,996,7,364,700,579,839,791,49,761,327,826,763,719,545,555,397,475,29,484", "979,294,220,65,235,678,915,574,330,570,781,534,512,578,742,247,162,432,355,629,802,420,175,983,168,454,287,119,30,965,563,402,671,415,627,136,649,265,147,802,954,252,791,215,849,837,635,666,467,572,452,674,908,249,896,39,253,877,893,408,311,644,533,441,65,313,756,70,126,80,475,540,620,446,834,777,581,113,773,149,550,366,530,987,194,467,621,896,13,629,939,51,280,124,88,329,412,177,803,103,291,428,994,975,867,445,269,306,987,708,237,56,283,379,440,887,684,461,585,566,493,128,887,536,356,842,173,761,383,859,160,490,512,941,431,1,810,714,949,781,757,392,905,569,966,247,767,302,927,85,151,228,973,453,261,251,885,87,207,290,589,383,980,256,831,805,671,279,448,965,202,843,355,271,485,218,402,839,405,390,894,453,528,581,778,516,574,755,151,426,568,105,695,159,753,874,407,244,750,854,867,308,445,428,927,892,338,39,201,612,725,824,362,162,727,421,475,937,541,771,243,980,377,434,621,324,762,367,226,598,37,24,940,295,785,669,818,11,566,371,928,568,338,762,796,827,371,999,234,892,598,753,614,318,939,621,179,811,253,670,263,193,185,801,25,969,127,597,604,951,879,239,608,430,81,704,3,746,913,389,384,658,736,9,493,13,817,965,63,621,112,667,987,696,227,32,150,165,501,912,850,448,305,173,679,210,727,299,814,975,254,380,287,554,281,402,232,374,467,451,5,21,982,310,85,950,342,55,483,449,810,147,875,691,89,605,510,379,744,781,210,870,973,225,546,98,236,95,998,524,793,88,916,527,406,362,165,762,943,294,451,81,2,688,880,330,582,892,961,96,438,8,33,357,808,683,902,336,403,99,742,448,637,846,591,557,726,270,802,412,808,650,509,222,104,335,655,596,185,554,88,773,388,309,819,418,85,160,124,480,966,244,375,434,776,82,233,489,471,1,351,138,477,469,367,393,357,388,495,415,376,686,231,478,922,115,179,110,960,408,856,616,992,215,889,169,949,425,300,524,51,980,376,615,153,492,896,631,275,86,847,565,749,746,870,452,994,907,718,906,554,8,587,301,900,633,977,595,474,337,300,600,590,855,70,399,483,106,699,387,839,817,898,846,754,802,498,740,84,620,37,742,707,28,804,520,110,793,581,777,784,607,904,742,388,135,942,579,319,609,550,725,435,344,826,521,120,758,669,281,791,627,198,781,926,764,442,613,482,889,755,561,358,897,633,468,687,998,550,693,618,244,510,945,537,986,270,229,558,634,796,817,298,757,395,332,55,428,775,69,976,795,880,676,861,13,822,452,660,336,153,657,717,702,178,524,657,791,156,124,89,968,172,34,780,259,751,43,630,393,492,522,513,188,239,690,847,81,305,804,468,55,443,34,849,174,880,334,329,704,335,707,436,691,241,306,549,270,851,998,339,504,691,876,98,666,454,81,81,490,69,690,132,433,2,158,651,307,285,44,162,779,690,77,372,204,309,873,833,458,66,160,924,405,395,709,759,517,330,36,423,558,435,485,315,75,853,148,122,417,12,190,23,166,200,269,932,836,920,611,409,654,310,342,596,309,60,493,327,682,318,230,493,435,607,694,98,717,708,398,344,585,662,720,557,771,687,961,695,136,179,380,758,974,909,776,935,5,0,816,427,579,357,939,840,280,334,814,500,365,313,350,208,747,760,600,592,813,169,351,388,42,664,261,522,273,888,156,409,607,666,449,649,771,970,509,138,950,4,60,452,470,675,617,519,873,370,893,915,908,805,433,186,761,531,411,745,375,339,109,422,575,458,999,343,369,817,897,11,193,631,590,313,323,855,629,645,247,946,102,107,351,533,875,524,663,841,826,235,56,875,874,222,334,860,346,118,154,138,821,636,222,402,923,391,928,578,265,890,306,18,247,484,852,308,124,550,908,949,801,26,970,737,625,731,191,698,709,463,656,37,642,201,358,847,456,231,982,352,986,161,44,664,301,363,889,148,258,502,762,139,864,817,399,697,301,324,799,477,453,904,148,809,743,543,832,578,604,229,556,350,604,190,42,365,123,3,644,139,160,578,782,491,561,559,276,515,725,693,915,829,218,671,257,742,395,388,92,710,94,178,773,433,30,540,898,636,327,371,45,37,917,221,98,172,739,373,802,763,696,460,788,328,929,287,235,7,904,919,847,588,254,212,435,463,827,292,594,345,859,433,101,856,778,754,502,229,904,475,548,395,559,381,81,245,743,751,691,964,578,644,253,609,381,299,969,125,331,391,448", "634,362,739,379,391,123,933,134,839,440,571,717,280,674,702,742,171,513,260,352,515,614,258,278,1000,835,892,448,674,457,397,518,878,982,865,593,968,511,364,80,935,988,928,560,446,250,100,424,363,249,932,139,376,267,565,953,225,613,855,527,570,576,929,319,269,967,426,485,720,299,940,484,233,49,260,947,747,656,701,103,476,894,446,911,509,818,263,499,836,461,946,362,434,498,103,126,608,628,10,560,888,248,626,50,339,45,900,839,766,47,69,171,140,512,755,575,63,64,918,652,221,813,903,433,331,181,336,884,588,991,369,157,997,364,985,148,680,982,438,427,648,996,356,363,815,23,796,263,840,679,747,784,455,400,233,777,268,216,856,790,768,141,943,649,652,705,564,255,345,759,966,603,514,163,194,646,575,172,228,635,563,249,609,844,926,765,889,243,647,462,585,740,962,399,676,444,658,293,803,716,993,611,118,264,30,183,825,466,131,371,919,312,406,853,272,983,21,12,251,666,256,9,607,231,987,609,468,722,772,172,401,187,88,350,853,641,327,525,364,431,383,110,893,989,148,493,752,188,268,514,890,982,112,220,920,890,618,427,925,630,192,848,495,160,995,551,151,761,678,636,341,129,548,898,214,903,884,944,447,632,268,165,633,50,35,458,404,467,743,12,357,391,239,730,991,340,500,922,548,418,691,261,580,482,200,527,130,540,806,183,110,409,284,940,475,991,682,852,364,159,665,476,472,379,853,563,411,88,588,79,30,875,730,786,67,240,741,210,90,330,852,956,896,36,618,905,117,334,644,687,717,849,978,905,660,191,801,972,216,441,832,332,930,652,894,678,458,328,971,159,87,813,25,296,935,483,85,27,601,211,754,464,136,805,541,518,214,233,796,992,496,796,247,686,873,164,672,778,475,606,883,905,530,879,704,501,259,819,664,505,835,531,52,980,161,845,939,918,605,669,610,684,742,197,982,343,388,21,11,196,915,766,522,207,780,954,901,133,30,484,181,929,614,452,714,404,964,218,408,989,710,454,141,561,357,614,994,89,935,596,954,453,324,671,579,252,986,651,404,666,586,302,922,188,174,593,239,888,170,551,129,883,380,444,836,250,832,206,825,952,131,604,46,445,648,74,29,632,778,113,552,107,281,400,561,478,307,524,64,708,962,679,472,807,339,839,967,655,253,361,524,133,379,738,5,969,997,272,339,207,355,694,310,206,389,852,532,430,504,419,212,417,832,760,325,675,693,233,535,803,24,337,865,30,406,421,46,166,984,328,551,734,935,5,727,867,804,730,241,977,737,497,515,448,485,631,794,205,28,513,658,981,864,544,94,944,83,362,707,102,943,49,944,354,46,508,375,419,350,678,450,110,752,998,539,816,953,160,534,668,387,21,371,888,910,518,890,430,887,275,342,747,159,839,912,134,546,836,687,933,552,991,765,323,968,826,556,83,280,233,610,112,369,286,739,870,350,604,318,514,346,928,891,179,971,542,846,881,416,152,917,493,603,636,96,555,985,582,930,896,448,114,612,23,356,515,662,697,312,680,517,36,597,866,208,442,470,561,659,734,419,924,717,158,838,522,533,517,9,3,842,455,990,727,675,414,475,37,321,760,818,40,82,750,575,209,366,144,661,912,920,532,552,128,662,647,909,696,816,0,306,373,928,242,359,726,758,301,248,749,562,883,145,13,46,875,785,896,533,374,310,702,855,698,711,593,554,183,815,920,106,44,393,184,609,482,148,271,3,550,609,713,42,812,289,581,634,715,924,548,135,587,930,486,810,610,1,283,590,830,413,871,986,896,907,961,644,160,92,503,368,993,399,424,456,169,330,575,113,70,252,779,806,858,963,303,659,247,943,868,980,787,167,532,522,590,530,150,183,882,265,103,99,189,565,35,685,941,186,888,288,658,878,927,803,208,630,751,57,994,589,383,110,257,155,54,889,776,439,995,708,898,580,697,289,264,125,402,84,203,322,272,199,64,226,7,881,43,215,581,361,671,370,401,845,483,152,336,50,696,525,975,652,185,443,211,60,419,801,339,620,680,615,785,922,337,892,510,595,483,452,322,704,519,690,168,798,506,725,98,955,325,212,658,392,834,457,421,350,900,780,261,770,209,133,741,306,366,482,91,159,315,704,523,58,67,284,548,820,718,804,205,785,870,603,875,76,360,358,103,29,144,525,720,3,875,911,620,590,843,669,50,794,507,831,129,669,95,201,746,865,787,162,884,376,633,823,783,464,62,361,873,689,884,178,192,771,401,228,237", "63,421,464,201,594,445,398,895,508,609,800,737,94,972,373,931,234,368,989,873,580,302,568,129,658,588,133,193,538,22,452,451,777,218,949,385,860,911,381,415,813,244,550,649,408,916,575,590,302,99,143,261,30,69,851,953,521,709,213,717,860,210,456,450,554,606,927,548,142,895,846,997,879,616,759,916,237,341,221,369,131,252,712,953,295,441,381,926,907,59,691,404,351,25,468,705,885,547,572,104,593,712,595,326,82,361,692,774,170,179,878,74,412,908,546,449,261,621,707,620,927,286,933,633,200,637,383,136,359,474,364,918,831,761,949,52,220,881,265,684,951,737,936,653,848,344,427,369,45,317,279,760,428,758,705,820,639,317,317,612,188,702,379,527,891,66,89,764,400,802,963,343,383,534,565,338,438,766,748,484,675,593,302,191,290,153,13,686,504,572,521,437,109,199,205,442,575,269,854,780,904,657,897,624,48,744,691,988,468,86,641,555,394,872,355,197,959,767,749,265,594,150,445,368,109,384,784,852,685,83,190,891,620,72,8,87,209,935,773,270,595,822,221,219,342,320,339,754,638,411,301,392,975,809,289,402,572,547,632,853,830,433,680,899,342,344,556,54,900,898,183,316,569,645,512,201,172,546,508,791,389,587,272,454,182,616,690,967,345,947,143,162,643,725,958,435,639,917,754,340,522,37,740,791,121,36,332,45,698,183,25,948,264,778,36,272,931,424,825,875,776,732,665,68,769,332,721,866,692,28,260,142,283,574,846,334,787,39,271,466,939,468,480,22,447,266,190,501,576,148,275,144,192,267,379,261,538,593,742,60,980,954,840,201,252,689,270,835,400,674,811,808,706,856,849,223,874,37,992,681,726,771,413,663,58,635,121,573,542,510,995,485,134,597,419,101,584,163,505,146,846,559,777,140,514,397,545,277,770,441,116,799,94,506,826,305,456,718,501,492,824,728,47,39,483,181,529,3,487,500,949,47,966,236,945,397,850,45,674,426,569,341,292,478,154,920,960,332,532,321,348,379,586,789,155,321,372,793,285,617,972,105,559,688,365,760,941,633,218,208,91,552,385,329,88,411,892,437,458,29,911,599,310,13,133,896,973,579,810,821,659,454,341,213,439,922,257,469,873,627,602,161,661,901,277,238,233,776,343,699,962,186,474,164,821,46,832,614,944,445,574,928,25,920,203,556,684,832,599,795,272,508,773,396,168,560,474,877,809,456,298,572,465,736,23,971,162,374,710,335,17,393,286,730,772,266,327,619,138,215,236,656,3,776,832,868,639,539,167,79,416,572,400,982,239,631,389,544,396,270,646,411,13,70,441,450,13,687,198,66,426,258,794,4,273,273,874,165,375,973,489,275,731,158,710,592,668,947,181,211,183,764,614,932,75,952,495,746,258,110,663,158,602,698,829,139,748,30,876,42,895,679,300,230,964,4,126,510,562,258,418,978,118,289,823,931,440,852,179,266,488,77,48,672,433,512,228,227,341,425,643,130,25,762,752,300,256,445,161,69,853,3,137,68,447,234,172,645,237,389,990,647,704,840,436,230,754,606,644,463,51,246,607,11,314,734,596,447,503,123,898,460,241,622,92,606,175,778,163,774,337,586,448,755,190,106,474,421,496,805,213,473,732,642,159,685,571,262,427,306,0,97,940,927,274,649,74,737,157,817,585,106,801,981,79,652,720,524,140,374,875,558,815,4,39,343,182,91,463,570,549,459,927,323,885,764,795,983,802,225,238,209,500,555,794,887,707,350,446,45,895,843,41,912,498,248,879,854,13,616,753,476,176,111,579,244,881,930,137,831,460,697,332,573,917,448,662,662,264,605,988,693,522,679,20,754,675,952,632,557,461,657,64,867,425,41,175,155,116,569,35,982,750,833,552,137,723,354,220,988,899,588,768,877,574,152,649,604,651,464,503,568,189,706,875,172,371,104,656,603,541,97,415,579,682,755,966,352,709,24,529,157,950,78,948,929,699,291,389,988,971,231,888,186,431,557,807,836,146,574,738,446,387,214,287,150,393,670,931,29,639,372,815,984,691,3,87,288,471,841,898,411,727,573,45,547,179,533,607,61,295,816,327,635,666,389,827,416,17,938,510,786,638,482,909,83,42,465,43,166,20,248,237,89,758,832,570,905,961,833,457,25,94,884,298,556,326,907,383,614,582,114,117,754,761,704,110,591,215,948,177,744,688,461,279,838,427,256,790,918,407,734,259,511,458,656,300,438,993,607,59,771,6,551,854,903,585,816,243,566", "164,304,67,693,274,105,893,452,660,216,623,217,470,675,982,51,213,587,829,895,556,228,258,694,418,201,501,349,774,479,800,96,524,381,567,794,647,890,81,476,420,76,664,489,27,81,610,782,356,117,856,752,684,582,345,320,511,588,342,731,521,370,62,282,495,832,14,184,245,54,515,485,86,656,546,151,801,969,350,935,218,882,762,410,816,815,993,528,552,248,602,378,425,433,160,853,699,380,343,149,905,168,41,750,943,681,404,321,823,891,984,481,939,496,831,168,322,880,652,3,409,664,892,681,710,35,72,473,776,893,851,442,290,130,664,82,351,308,435,340,49,657,642,399,247,22,296,118,35,231,132,967,4,475,516,625,111,674,674,63,5,986,208,298,514,952,945,533,688,551,860,429,681,874,676,85,352,430,91,15,779,35,321,397,139,194,316,175,620,919,480,679,779,215,104,608,538,16,753,8,630,717,461,544,665,595,52,80,862,691,545,939,436,137,220,789,384,672,516,61,633,850,791,790,581,328,972,157,124,890,540,285,823,729,599,620,720,253,307,889,668,607,991,262,940,116,810,210,364,904,900,985,900,766,293,459,741,456,990,104,273,880,212,925,387,200,563,617,341,112,907,437,775,627,933,479,724,252,135,564,209,181,126,529,431,565,601,402,165,826,70,810,856,385,325,112,55,703,747,553,819,970,229,536,35,715,402,380,891,244,170,621,793,423,82,844,166,321,809,261,925,25,368,8,558,703,222,70,660,447,882,615,830,662,464,261,242,316,749,173,91,191,757,357,205,722,582,17,24,191,629,823,678,86,851,417,5,826,333,674,871,140,889,202,430,659,896,662,321,762,680,691,759,156,735,669,42,295,889,795,48,559,375,509,693,473,865,393,235,891,853,168,898,444,94,131,243,759,434,302,650,116,746,591,653,184,78,30,524,903,848,464,850,786,224,88,96,146,172,491,626,819,71,353,151,740,138,197,171,803,938,3,615,250,33,869,335,241,522,967,225,326,942,137,294,485,985,671,655,36,403,50,219,754,467,84,891,549,686,805,520,900,749,599,269,98,980,470,43,424,973,88,212,427,674,493,87,628,165,783,570,727,515,547,972,16,994,973,283,17,469,62,823,653,537,17,131,297,669,357,109,632,492,888,827,324,701,329,616,854,382,609,645,163,79,144,405,864,166,988,800,73,210,494,319,481,401,260,221,407,246,196,496,405,238,611,858,172,978,769,763,32,664,341,101,408,567,427,11,106,216,304,794,904,39,56,389,243,569,170,728,835,707,863,347,250,580,909,700,679,149,729,318,933,214,960,422,134,723,637,364,777,534,627,378,892,528,285,829,966,351,962,367,774,675,52,864,277,959,719,623,142,498,990,331,784,137,277,269,201,295,716,804,349,607,745,366,459,754,821,664,985,404,114,544,120,727,922,337,263,468,157,371,339,47,265,22,317,880,55,290,64,226,201,488,609,781,157,468,607,422,989,77,165,140,26,134,895,734,797,139,835,545,473,327,26,560,968,974,847,293,876,766,613,8,114,931,75,54,384,567,622,339,362,148,166,76,591,83,578,710,76,422,369,251,903,755,864,275,450,284,339,469,936,927,269,63,100,517,26,796,342,302,79,477,13,634,274,774,945,331,184,238,105,444,703,156,580,579,373,97,0,424,336,129,488,311,645,442,401,287,692,13,605,951,225,793,929,760,610,718,604,247,323,304,682,132,518,542,49,856,752,651,493,553,185,587,752,52,758,612,140,480,744,502,808,354,48,544,553,358,455,958,614,306,595,768,155,875,767,344,719,450,852,833,508,986,274,921,346,577,648,54,576,219,556,490,475,549,656,317,217,657,379,940,153,249,598,338,4,283,721,726,867,502,182,746,615,63,540,859,993,904,233,487,136,508,364,526,498,298,307,402,521,910,199,760,868,678,633,308,281,405,479,909,948,634,559,543,950,412,608,571,190,20,567,788,878,143,419,271,202,432,290,371,515,597,287,958,621,433,663,700,647,825,744,377,980,376,780,467,378,336,159,184,175,954,109,176,78,204,740,588,181,76,411,549,832,305,340,437,323,778,362,370,598,26,948,634,694,960,387,963,952,206,410,209,835,432,227,495,801,25,501,322,780,526,647,155,881,833,911,217,967,316,540,548,627,931,838,362,396,8,440,751,773,702,903,25,635,358,776,326,525,292,721,599,170,518,452,685,456,530,756,599,295,222,480,995,973,824,151,967,701,580,846,42,357,822,731,310,64,923,10,427,187,131,877,764,79", "849,621,62,135,263,454,140,801,484,533,681,264,748,589,78,616,130,190,725,277,593,869,673,70,241,324,264,544,872,248,574,689,15,400,325,855,926,393,423,535,190,563,354,230,571,325,44,864,309,784,745,148,817,630,869,120,262,474,499,112,187,214,950,695,808,656,456,933,160,748,616,711,220,404,444,816,689,962,813,953,806,324,855,215,765,545,385,280,399,140,971,894,671,710,77,792,987,927,107,495,290,789,164,494,681,477,137,117,345,745,900,117,971,26,357,173,102,683,469,758,725,150,550,56,870,304,334,427,814,819,269,688,17,287,890,792,693,119,783,276,55,835,878,266,677,57,680,639,195,517,486,54,884,263,399,907,229,18,44,765,183,237,5,998,979,281,470,18,90,977,701,852,551,547,103,183,271,64,880,590,100,555,846,168,681,712,866,31,744,23,919,510,482,341,6,862,85,796,423,446,892,647,629,787,167,63,835,37,610,277,467,648,852,103,381,108,542,213,33,344,565,408,379,821,516,441,232,14,840,404,724,397,492,483,973,946,219,434,215,611,137,115,527,300,124,845,254,908,598,856,700,615,465,852,118,142,874,960,937,614,782,933,983,838,793,492,185,181,151,477,778,438,592,115,220,778,475,127,249,153,799,215,202,814,838,634,867,904,172,848,126,98,865,202,996,25,334,883,782,251,362,497,421,196,490,868,714,422,857,624,709,293,861,781,962,511,682,955,57,10,113,196,887,189,416,499,629,863,392,309,108,801,487,407,877,92,232,483,91,268,582,890,454,236,949,146,681,942,803,775,934,92,915,833,86,675,627,401,10,925,619,498,668,961,531,457,931,887,272,837,495,533,409,316,161,392,675,106,516,426,837,939,761,974,927,752,110,419,420,984,818,56,961,94,392,708,453,994,328,304,322,866,336,442,334,189,60,331,329,552,712,989,359,380,708,731,859,238,16,7,16,236,681,443,297,829,331,92,655,367,612,465,795,568,609,294,455,85,29,535,249,251,232,561,920,762,325,299,948,378,810,888,596,273,655,630,100,676,428,534,238,193,667,721,679,979,666,333,844,904,933,912,328,416,480,642,412,400,470,338,297,322,785,691,519,225,440,144,814,634,987,13,225,828,676,920,279,527,592,803,731,164,224,344,47,85,240,658,895,247,351,20,342,51,246,584,888,538,639,823,685,704,950,454,938,265,218,42,651,171,925,632,557,348,214,729,703,31,414,372,182,484,99,294,174,810,676,232,460,916,387,788,39,791,577,673,880,246,697,114,913,277,880,748,721,914,898,117,447,816,325,628,848,130,327,394,49,555,198,138,426,204,231,373,979,129,200,496,104,105,845,507,60,525,193,840,199,958,641,517,45,411,134,25,470,649,289,736,572,578,585,553,418,936,20,817,876,724,975,102,893,467,83,273,646,102,902,190,946,888,608,853,954,671,898,542,658,787,773,524,716,766,222,596,469,160,673,13,803,137,840,115,316,315,55,997,574,818,264,908,134,399,691,742,915,549,389,646,520,945,529,744,875,811,509,7,16,151,789,222,251,453,298,614,878,248,224,951,452,802,143,864,398,205,773,780,823,383,428,309,10,685,711,834,535,157,403,15,736,474,298,953,122,912,680,694,375,898,839,792,156,540,399,959,815,364,680,105,357,928,940,424,0,809,715,452,980,398,724,819,810,647,7,426,945,909,36,376,15,784,778,761,688,126,298,119,984,231,95,580,828,455,580,814,52,447,811,193,598,523,515,304,211,151,632,762,279,251,594,903,998,89,955,608,298,568,904,463,820,132,506,539,748,690,15,24,380,929,405,596,774,715,945,796,232,816,157,271,642,996,915,389,676,609,462,940,701,958,485,432,391,103,239,591,523,589,466,676,788,65,96,155,595,891,110,156,700,890,401,500,236,610,807,619,577,379,849,943,828,377,977,262,855,864,204,214,889,841,171,411,216,387,617,894,564,409,703,978,302,264,200,652,371,74,99,292,955,456,774,805,284,278,699,919,772,271,677,664,924,890,606,827,512,648,555,466,447,293,35,899,54,944,556,882,758,228,755,342,120,828,790,158,309,919,373,714,845,958,877,32,724,505,703,156,128,756,675,288,707,861,321,774,612,573,165,112,729,985,801,422,481,94,248,327,328,540,394,312,794,725,276,980,215,669,785,379,746,333,234,591,638,306,491,431,424,624,264,867,439,905,715,790,529,736,972,188,319,151,581,165,17,832,381,210,214,651,450,48,83,466,472,911,750,554,989,623,322,690,974,243", "736,582,396,814,372,944,264,450,209,183,54,74,787,526,871,870,853,15,669,112,767,555,888,903,507,586,641,162,391,229,16,541,207,146,433,464,333,857,406,585,890,391,345,136,305,891,723,341,839,352,267,178,631,409,16,907,41,520,280,32,685,143,225,422,584,71,958,545,283,228,170,800,837,822,981,305,102,39,491,274,641,204,490,54,630,926,220,996,908,314,845,587,679,736,476,618,414,374,532,591,739,713,240,667,766,132,693,745,583,664,622,552,556,771,555,182,285,920,721,555,870,175,608,361,895,918,657,620,947,203,254,224,475,357,415,67,185,693,457,513,234,359,939,49,442,856,488,186,303,103,705,891,325,860,833,602,470,680,619,343,449,269,956,948,688,133,696,620,972,841,752,236,469,181,940,232,88,992,613,183,633,569,677,20,494,146,475,145,603,534,315,98,985,279,444,679,197,66,636,75,642,276,256,731,192,886,707,147,220,832,320,28,270,174,629,138,203,674,828,703,588,613,810,448,406,311,991,608,259,154,378,94,265,591,932,549,343,365,131,656,175,109,507,827,662,285,631,978,718,94,411,452,775,408,843,818,582,822,401,462,263,50,47,329,535,462,935,389,796,902,959,806,619,484,12,193,364,953,382,355,327,935,109,353,840,575,226,288,754,406,810,109,748,9,104,96,723,224,321,307,928,247,198,799,672,867,690,545,646,856,44,766,382,817,594,308,734,835,48,491,819,12,786,989,467,980,42,142,413,875,704,349,675,433,612,30,485,946,17,821,714,662,803,470,605,22,497,67,181,859,678,313,422,541,952,301,816,291,70,572,427,692,327,549,786,543,268,304,172,465,349,980,342,203,258,56,876,330,408,646,222,290,454,164,232,778,675,461,171,466,6,840,363,659,797,457,386,173,691,366,215,116,11,937,287,548,731,789,432,958,535,577,330,492,664,865,324,118,927,437,947,836,718,979,931,911,114,881,691,469,93,603,398,735,595,519,192,593,821,652,217,868,153,309,672,681,49,2,286,94,789,429,141,951,689,615,161,681,306,713,480,940,766,718,196,626,663,251,494,866,90,72,906,834,960,45,683,778,390,512,189,912,171,626,579,82,274,667,126,90,257,563,800,968,327,178,10,552,435,38,454,301,7,774,440,742,51,938,573,288,390,142,79,376,168,507,252,406,512,816,505,594,430,33,779,910,131,533,540,289,882,928,477,556,74,447,205,742,152,922,655,933,998,760,970,438,683,248,810,729,427,44,162,435,343,568,723,314,848,625,216,512,992,204,861,825,693,315,58,713,679,969,804,797,617,404,979,73,192,124,220,901,667,783,153,846,200,415,551,631,419,447,894,555,966,226,972,239,454,391,324,604,22,595,930,544,985,302,207,791,831,143,607,822,151,115,656,24,541,473,585,641,277,124,238,941,762,69,578,468,466,229,938,745,437,478,870,508,676,371,92,719,137,62,810,507,939,788,339,235,897,995,595,307,885,602,905,457,724,42,722,37,147,988,919,206,167,268,412,517,943,138,220,536,724,784,583,193,534,840,739,729,338,30,639,971,945,545,871,633,695,415,937,663,668,239,746,795,222,27,340,491,195,177,186,276,806,830,824,257,803,236,408,717,914,278,401,102,192,67,139,237,642,425,681,449,901,97,939,242,927,336,809,0,391,387,936,812,352,636,792,59,619,110,52,462,101,491,844,830,792,30,403,893,711,762,648,277,479,533,920,946,891,781,852,576,861,483,21,88,236,721,772,529,217,510,855,256,225,455,719,138,251,544,728,608,625,80,194,638,881,812,874,214,935,163,586,3,641,149,69,596,364,272,92,183,429,238,371,453,684,789,915,59,101,649,639,269,584,825,938,495,180,303,220,611,393,398,181,105,311,679,934,352,112,67,934,948,131,878,397,442,915,561,878,233,755,779,384,460,429,204,406,112,469,137,168,124,315,486,251,542,352,22,661,527,828,776,299,950,539,602,872,594,633,111,77,131,98,736,379,730,915,292,186,93,496,61,705,334,980,880,316,825,610,891,951,901,287,971,389,443,35,688,348,684,247,742,949,406,357,698,258,825,983,160,181,916,760,89,429,580,946,654,819,560,994,153,630,23,398,543,953,692,109,110,356,383,259,801,897,943,824,369,617,367,74,914,87,851,318,936,900,333,890,916,269,936,177,301,684,615,546,359,431,393,89,909,142,874,244,362,387,938,63,511,105,453,849,488,772,588,326,894,789,264,721,485,820,702,320,261,315,861,67,648,326,293,824,198", "283,439,530,498,648,221,674,650,615,313,818,141,839,831,815,371,720,531,420,52,678,613,120,169,577,504,961,501,950,742,647,834,323,410,848,697,659,991,797,637,159,456,668,837,801,145,451,461,276,564,250,211,814,410,935,857,853,463,833,137,566,408,86,620,724,752,152,597,390,104,242,418,336,658,490,229,862,814,238,604,410,727,64,598,605,962,413,736,777,734,846,690,867,477,977,553,744,90,422,951,848,11,297,70,174,375,816,300,600,829,950,409,944,27,474,369,582,385,297,454,659,687,730,626,473,890,598,340,747,844,549,569,502,432,425,533,781,56,515,184,208,305,766,209,125,917,978,428,514,319,113,57,944,774,415,779,539,458,767,796,670,701,641,459,114,910,589,995,18,23,187,244,499,822,590,815,928,234,471,678,379,588,805,345,544,501,301,764,927,464,545,252,661,606,64,763,506,340,661,37,448,729,533,465,78,3,272,662,330,353,452,364,266,637,931,97,119,379,27,560,221,276,216,894,96,336,501,964,516,986,940,85,97,11,862,862,367,562,810,377,198,998,316,829,833,231,996,104,563,48,312,526,387,325,900,350,258,630,162,363,767,275,723,266,455,224,343,315,183,930,279,86,41,365,872,807,953,839,6,438,709,649,791,788,561,896,82,958,247,987,534,289,415,118,578,772,542,129,483,967,12,426,833,853,94,404,780,376,233,542,881,912,925,283,759,921,284,197,518,97,59,539,698,23,318,894,767,403,355,498,650,244,388,679,222,499,205,149,262,634,97,300,973,333,619,758,74,65,673,286,251,242,812,837,566,209,959,747,999,76,999,730,902,65,863,374,214,460,947,619,771,960,804,699,765,79,111,499,108,170,133,86,170,602,684,89,94,811,539,248,891,821,769,861,421,285,673,98,718,118,108,134,505,467,118,901,472,78,776,287,526,467,415,373,68,416,998,492,788,939,396,33,949,28,770,306,62,296,67,288,914,764,755,606,380,456,107,288,758,946,203,131,574,626,561,379,388,577,855,1,753,24,642,94,125,111,15,634,780,758,244,131,827,393,816,998,275,3,366,630,937,384,400,204,96,99,691,519,225,627,900,753,249,143,552,902,110,736,986,633,5,733,395,414,617,582,85,394,265,409,355,951,40,22,579,322,285,469,889,690,279,296,886,663,146,560,405,27,181,340,217,22,481,991,479,21,31,579,692,990,571,648,552,583,868,227,530,532,769,210,548,151,850,607,775,419,257,595,804,741,136,629,230,286,58,897,271,348,973,617,922,16,988,262,830,664,544,945,257,327,900,42,387,515,385,240,750,643,371,612,47,636,908,998,623,669,556,801,892,803,347,760,153,160,198,554,200,309,56,596,987,594,628,630,269,353,631,116,136,365,166,844,314,365,766,14,309,635,102,158,159,144,651,951,616,329,329,655,421,723,864,445,971,923,791,492,312,932,433,113,532,229,822,307,656,221,794,63,241,547,946,91,995,141,943,365,381,270,341,698,536,485,314,675,716,93,220,740,806,503,968,333,795,635,926,243,92,328,408,133,255,407,161,429,987,788,343,840,297,537,761,301,321,668,525,108,624,167,814,458,325,454,697,215,117,809,227,654,208,832,156,162,921,684,934,400,824,641,647,867,639,917,288,220,939,530,290,732,840,359,274,129,715,391,0,910,461,373,533,669,732,25,314,624,128,366,273,152,431,442,892,898,870,213,763,495,18,455,602,511,520,634,113,649,468,754,671,425,945,264,259,464,905,106,55,950,826,708,878,400,438,549,931,759,222,56,100,75,850,452,205,281,550,38,362,590,404,454,844,224,194,23,477,854,337,603,647,418,798,918,985,187,840,130,267,995,275,566,725,783,340,318,410,791,904,948,391,64,965,502,279,306,468,112,993,719,666,392,435,247,947,200,312,848,695,117,741,1000,823,393,702,221,702,414,955,951,379,354,281,501,110,171,293,766,587,723,82,743,569,394,29,33,285,887,524,493,465,213,619,244,257,813,716,742,764,140,879,154,485,899,668,244,434,436,737,196,400,30,764,252,505,694,965,614,85,457,894,874,980,971,314,799,883,465,721,114,51,688,328,289,621,933,993,397,651,754,459,41,608,103,754,670,605,748,711,222,996,198,271,356,753,617,579,164,609,25,114,955,821,502,38,437,527,281,242,421,967,246,346,503,278,853,210,854,670,799,628,699,312,228,913,712,362,188,575,753,932,204,874,51,246,33,306,993,458,399,930,578,988,767,753,552,47,275,807,663,546,252,348,831", "210,825,888,358,593,249,221,953,649,400,365,954,117,542,48,140,811,971,896,805,268,712,282,849,112,173,187,501,53,79,611,978,137,727,737,626,78,155,514,767,191,582,734,970,96,790,593,186,804,804,421,878,712,971,682,686,246,928,59,199,201,892,821,610,631,692,967,205,126,816,693,425,308,165,946,92,779,639,63,921,762,565,427,225,360,810,909,507,708,801,92,844,217,500,554,93,910,71,749,499,455,928,612,106,126,357,110,603,587,562,490,829,930,542,507,862,138,723,82,867,611,992,30,478,671,75,182,565,148,40,744,107,357,840,713,818,771,945,170,575,581,584,771,424,417,905,200,976,232,292,294,392,331,410,579,678,395,617,986,994,541,925,403,960,609,171,732,127,967,980,540,638,760,155,198,209,709,239,374,447,262,609,203,813,198,337,683,10,512,91,304,100,52,595,322,512,699,749,677,865,892,229,199,684,587,664,103,250,647,899,123,553,942,779,540,828,840,28,695,509,652,945,300,461,149,703,999,741,397,537,632,616,340,588,730,798,870,579,830,250,726,959,222,237,310,422,703,826,698,443,414,432,484,337,992,425,260,646,710,990,782,620,33,676,588,364,192,820,671,585,469,55,557,668,164,854,377,820,40,179,863,49,770,675,428,461,501,919,261,980,767,99,975,827,504,427,585,397,346,183,526,367,628,19,486,664,919,81,203,253,639,548,185,190,71,850,941,753,113,938,127,609,502,899,703,517,381,174,870,225,404,443,25,675,147,676,438,230,237,434,713,446,764,273,263,111,360,956,512,471,967,672,377,622,776,651,644,253,210,248,816,383,755,462,216,209,10,831,341,744,545,562,886,964,994,22,857,460,959,419,782,237,248,91,159,236,672,308,4,711,582,615,646,475,843,227,649,122,225,659,775,217,178,530,808,539,733,454,487,820,11,721,236,409,169,452,95,976,493,198,199,107,894,560,525,581,687,682,596,119,126,351,586,83,381,884,11,287,253,512,616,629,816,275,326,473,604,297,864,90,542,430,12,56,745,689,78,540,654,838,474,973,697,819,220,940,418,23,356,901,453,994,934,202,330,2,848,774,604,17,279,336,473,113,266,384,306,783,36,815,246,883,808,712,812,905,568,618,481,384,547,490,490,534,714,303,716,933,400,544,856,557,796,494,208,947,473,499,840,721,57,600,47,295,346,716,987,116,66,720,143,984,721,27,651,397,4,685,189,183,162,945,936,375,408,715,980,373,964,114,835,287,626,387,527,589,315,853,68,231,167,914,534,545,382,550,526,329,793,130,7,315,841,294,665,994,13,359,931,114,583,744,332,528,699,879,160,737,800,934,690,398,317,608,171,154,320,668,228,990,331,26,710,31,893,841,703,538,475,868,771,527,455,512,527,386,850,787,15,292,655,56,23,627,523,911,329,455,822,384,991,545,550,509,128,9,235,920,879,984,85,632,941,972,17,921,940,37,70,987,874,254,256,701,753,362,750,666,779,336,584,928,138,667,896,86,174,613,872,146,947,324,529,656,767,875,377,846,626,783,79,120,378,697,47,469,564,400,265,194,594,218,226,722,792,152,105,47,450,593,472,503,355,469,340,779,234,605,18,536,896,199,556,665,472,622,520,104,344,330,317,659,804,407,476,506,975,754,280,726,649,488,452,387,910,0,281,157,635,504,853,384,882,791,135,427,123,232,204,66,812,867,522,621,155,757,269,700,151,410,398,889,407,862,978,899,374,488,132,942,120,257,234,388,67,328,248,211,861,120,371,830,712,849,122,383,773,585,664,783,564,153,796,901,597,272,359,317,806,8,788,480,260,530,118,990,413,684,362,708,836,149,971,998,353,656,548,529,185,745,94,47,949,393,110,50,756,375,747,756,873,494,414,573,908,437,234,797,165,293,203,936,575,726,556,879,103,690,11,363,198,778,358,284,142,35,40,987,389,665,628,940,536,550,712,454,632,931,775,889,678,724,969,392,729,971,778,307,235,514,413,524,219,742,355,388,330,671,313,865,634,231,307,805,825,43,674,80,64,670,687,997,396,672,269,124,401,654,982,714,280,425,311,344,231,85,10,185,903,100,967,529,885,95,881,805,653,466,248,503,302,942,617,831,315,726,633,623,742,91,369,127,569,648,221,934,315,305,231,566,760,464,623,147,349,633,931,401,230,995,793,901,217,321,945,797,290,909,591,282,518,966,777,119,673,769,552,213,966,821,313,239,515,596,710,31,244,984,843,328,956,235,412,846,846,3,263,28,404,761", "5,45,346,847,792,131,426,13,202,726,675,99,404,226,809,900,519,729,948,200,834,531,341,217,343,426,836,511,127,351,125,520,127,359,276,268,41,770,441,41,254,644,718,738,546,621,853,149,111,718,733,120,704,501,753,994,510,177,920,129,882,555,435,181,952,873,890,247,630,247,349,599,63,437,875,426,814,882,147,862,834,908,504,235,437,724,200,707,142,513,118,555,337,558,418,879,474,321,790,982,635,506,488,712,205,292,486,212,33,459,996,454,264,75,803,211,781,159,164,69,111,661,928,931,107,184,997,815,996,661,438,48,64,569,518,452,399,280,514,94,585,154,486,236,70,513,445,359,810,782,355,318,729,782,929,969,919,988,326,469,545,914,402,488,551,777,213,304,800,926,826,705,251,929,759,705,610,173,845,459,18,891,799,567,385,757,949,687,328,936,74,708,394,959,462,599,379,485,677,532,155,986,411,362,46,377,173,4,826,990,638,499,590,27,419,958,28,693,821,551,866,528,172,907,497,889,857,576,892,182,759,452,493,913,727,521,707,828,572,54,159,429,617,940,794,412,767,541,24,828,448,659,692,167,856,212,724,793,814,362,62,830,171,885,283,876,209,738,707,542,964,664,150,338,59,36,968,621,266,716,767,712,174,832,56,654,108,927,966,814,109,479,804,912,659,860,155,839,986,332,913,18,593,119,36,173,699,186,854,709,660,533,530,751,87,817,856,543,545,353,853,202,824,280,568,845,157,866,301,760,100,790,463,492,755,736,143,879,819,940,967,858,886,681,945,278,955,919,89,310,952,623,236,97,766,533,449,862,817,275,598,874,128,301,70,106,998,631,694,693,555,643,243,174,434,487,530,690,198,899,599,775,714,424,125,941,824,802,442,970,69,485,918,316,315,132,994,717,192,608,775,729,638,888,683,446,84,985,773,32,728,744,660,775,83,690,79,651,875,313,842,728,882,373,442,884,747,670,287,854,462,651,112,647,289,147,826,149,966,879,160,477,12,347,768,781,548,213,977,387,343,968,112,573,864,557,71,348,869,20,596,515,767,691,353,407,474,439,109,869,876,100,770,94,949,712,730,975,602,540,620,721,726,32,496,991,374,803,482,263,236,874,748,627,409,721,269,787,392,57,1,761,113,27,684,419,794,110,506,686,72,933,922,863,145,528,14,604,524,477,107,305,711,986,985,342,630,602,90,168,856,631,181,520,437,29,585,150,286,225,64,979,905,707,541,974,429,875,84,66,542,560,759,882,658,658,980,58,110,821,960,377,636,628,404,463,579,768,407,78,177,52,15,844,902,767,464,961,987,203,431,862,307,442,277,940,255,598,614,573,44,795,929,494,684,537,540,918,356,478,721,940,575,429,172,565,671,259,5,942,359,354,79,149,848,738,519,106,150,368,890,221,640,76,221,943,408,774,42,292,411,275,971,3,946,530,490,705,973,694,913,348,44,787,403,576,118,102,228,248,168,819,952,924,193,939,953,617,522,638,556,964,441,89,119,567,603,352,753,116,267,650,416,291,357,596,343,258,282,404,959,863,217,200,965,388,430,506,481,241,803,66,944,61,903,61,441,778,816,84,366,747,645,879,498,102,296,902,324,845,245,876,96,743,784,808,185,371,804,169,55,647,913,575,731,210,542,413,334,758,74,311,980,936,461,281,0,123,968,381,206,969,391,977,916,490,685,396,488,359,242,383,867,699,259,388,576,332,597,209,640,434,449,372,436,663,171,818,429,719,251,772,230,920,863,653,115,178,410,780,31,500,724,243,805,266,306,191,959,510,294,448,223,963,386,14,858,393,703,585,369,209,177,640,710,630,692,296,817,989,771,930,7,606,269,952,101,148,187,65,338,760,171,215,688,175,680,854,575,420,234,810,723,896,164,25,249,255,803,122,637,429,197,151,907,66,246,385,305,355,400,129,878,82,465,627,746,920,51,691,588,805,743,916,203,350,171,230,279,745,656,129,984,30,845,736,498,973,659,236,400,119,110,986,630,500,974,670,117,802,741,106,702,888,62,20,944,841,689,777,969,536,702,694,125,550,903,520,159,93,975,380,100,312,789,465,188,72,843,661,553,270,838,890,629,18,307,597,433,255,707,621,279,361,365,560,614,7,542,595,687,589,132,651,744,452,378,570,622,67,489,333,812,806,253,964,910,921,322,922,568,443,560,817,900,1000,681,809,372,63,304,774,910,662,399,62,399,66,151,316,34,395,329,954,473,109,426,312,656,317,51,400,659,481,814,116,462,987,437,494", "131,208,67,895,626,967,628,720,330,851,20,559,231,561,303,490,496,121,93,937,860,333,627,418,613,579,427,827,407,396,759,223,722,218,284,814,878,405,168,595,706,25,176,896,911,70,904,792,870,890,40,681,870,952,853,10,524,526,182,522,761,35,895,602,407,596,248,656,9,227,529,645,422,245,216,839,560,826,56,330,612,101,524,422,754,960,630,510,353,111,137,7,691,628,355,290,777,714,832,370,140,878,804,652,480,410,229,628,182,859,125,392,799,382,997,455,435,461,972,66,891,300,54,459,449,728,673,502,665,114,948,17,28,630,538,68,166,574,954,903,691,357,848,943,604,769,663,628,700,550,469,51,573,561,659,969,826,964,160,85,182,928,7,295,7,533,31,471,884,210,184,430,485,238,647,145,169,584,409,217,706,530,99,416,775,671,811,23,404,828,320,551,539,80,608,125,301,567,945,818,705,268,666,396,407,408,86,769,200,669,753,862,255,481,206,917,252,627,562,585,591,342,560,579,314,210,399,132,978,283,389,145,775,569,487,297,903,668,327,28,984,986,421,950,223,273,665,714,368,325,66,153,373,595,546,101,112,319,527,36,737,821,38,306,632,444,885,980,292,809,715,113,500,378,570,379,998,271,345,46,195,742,28,434,715,262,432,80,886,558,671,608,628,183,431,811,81,840,252,6,954,393,378,540,998,547,387,52,372,639,259,646,587,164,924,533,896,254,642,696,22,486,393,862,409,565,556,462,553,618,763,511,957,948,944,449,671,32,144,797,800,538,886,221,354,678,173,115,519,979,857,889,632,166,125,382,746,345,581,996,63,698,72,885,18,962,559,943,679,516,317,490,213,480,395,159,572,174,697,611,287,771,729,656,252,237,122,25,163,123,794,851,877,980,997,294,766,858,487,673,986,990,428,299,515,571,952,758,571,980,709,988,403,186,797,618,46,190,670,738,166,38,978,461,114,293,566,595,915,838,209,401,86,331,151,349,699,277,673,999,678,581,105,484,308,161,153,206,872,111,436,339,388,351,695,636,101,424,295,993,767,873,779,848,363,104,375,611,991,501,163,753,208,849,752,31,454,307,864,139,342,65,792,21,293,216,213,926,93,826,780,563,268,721,326,589,874,547,172,823,824,915,175,771,75,977,624,183,118,962,859,602,225,413,69,450,565,757,122,690,329,71,381,157,241,557,561,790,696,919,490,811,209,782,853,112,564,929,1000,391,518,22,389,457,686,698,766,553,69,105,749,466,638,75,839,159,282,562,614,977,186,429,831,997,130,161,99,690,225,992,141,362,753,836,391,485,268,79,453,218,376,974,868,902,253,911,21,754,569,47,514,112,442,255,141,551,130,278,190,323,716,188,372,134,834,169,289,394,896,261,868,647,332,860,91,13,134,317,672,767,60,522,144,253,771,4,176,732,393,599,901,96,836,405,460,736,479,916,545,502,883,259,317,95,596,261,169,771,609,232,20,247,205,660,410,431,791,56,952,600,288,206,335,104,999,291,439,449,92,442,396,473,28,619,640,341,119,6,586,753,880,744,660,494,343,234,262,931,186,451,65,344,937,525,152,500,627,582,419,570,893,88,920,687,207,690,76,49,299,277,769,690,644,659,201,366,392,257,46,97,855,879,56,132,69,382,975,378,814,301,737,645,398,812,373,157,123,0,807,406,263,205,826,509,393,724,621,312,164,183,3,350,168,532,122,765,522,519,190,2,665,533,804,282,6,291,271,998,461,957,498,663,371,712,819,242,178,226,983,583,718,498,633,829,77,101,807,916,186,632,384,211,429,698,659,957,734,581,172,408,832,46,755,261,118,466,330,734,42,174,313,373,184,961,181,476,311,710,966,481,340,882,458,421,903,684,459,751,742,805,82,821,46,660,556,754,704,926,884,408,383,686,220,853,104,366,711,70,385,831,404,125,218,557,62,972,950,185,579,747,479,252,963,488,174,872,266,57,64,61,675,752,791,796,703,465,622,585,932,738,395,514,695,866,198,678,704,400,238,272,797,158,583,566,303,87,475,559,572,586,422,240,938,655,304,296,389,480,228,692,707,522,411,903,896,733,457,276,557,521,986,306,577,27,766,636,769,470,291,538,573,548,574,457,228,89,701,176,121,60,164,297,504,639,742,724,831,328,382,320,243,691,776,842,211,702,281,51,726,449,584,106,176,380,651,759,547,361,837,536,626,640,765,431,986,620,795,875,384,764,415,155,986,954,708,197,570,541,883,417,973,890,233,355,2,189,345,113,172,12", "117,249,264,906,755,433,639,726,118,599,981,36,260,954,293,456,62,769,572,568,70,938,168,665,827,620,287,837,734,522,656,554,63,920,809,595,497,690,51,837,415,626,800,559,474,577,580,489,734,781,854,47,738,780,680,527,219,300,554,978,293,921,426,927,870,468,564,583,321,579,744,744,107,377,767,625,666,146,230,462,828,783,124,754,668,933,466,113,390,217,967,7,326,981,3,627,813,130,94,883,971,108,326,600,572,819,249,125,918,991,440,943,270,651,277,204,473,875,746,384,161,609,923,276,955,683,458,325,398,444,986,196,25,337,22,663,851,572,260,172,535,830,853,463,619,12,152,140,367,28,996,736,965,134,648,952,624,302,467,476,628,958,535,59,290,533,296,593,638,64,623,573,862,622,866,923,82,958,194,945,138,481,378,260,331,372,680,594,2,344,505,881,926,107,525,209,787,648,848,473,151,123,843,691,166,173,751,799,131,503,267,264,417,719,597,264,809,644,361,66,915,959,252,383,433,540,757,959,738,968,848,836,855,86,874,287,580,601,526,499,779,378,829,886,187,166,420,186,228,664,180,748,842,335,962,497,291,48,270,932,702,667,307,31,254,19,920,155,540,729,816,522,14,229,1000,186,990,866,533,390,85,119,663,174,613,992,715,829,545,115,124,486,383,974,257,643,95,271,687,485,80,655,288,289,103,647,256,88,431,420,834,150,956,36,346,405,781,119,119,693,375,691,528,590,313,977,605,962,160,868,90,865,57,618,508,566,800,614,556,329,163,328,949,220,125,690,725,450,570,442,230,260,403,335,238,976,181,874,584,740,35,201,670,47,750,775,961,758,774,88,389,7,862,175,648,68,342,461,13,340,4,153,778,168,82,305,791,497,105,80,672,401,493,910,533,205,218,787,189,89,406,625,717,88,956,762,83,964,416,856,601,717,111,624,442,938,358,367,25,318,110,559,320,695,741,272,731,118,826,328,411,772,220,622,747,4,779,848,152,186,725,308,705,635,237,927,84,721,61,283,599,476,178,565,375,346,314,397,16,563,951,771,449,546,768,217,468,271,613,472,54,331,665,20,182,298,75,849,634,806,189,198,85,428,51,949,129,11,577,19,652,20,870,60,629,709,282,81,784,859,56,558,947,627,105,189,860,146,150,935,753,99,562,943,885,143,200,549,481,217,159,925,416,645,581,149,539,331,640,658,691,377,85,387,801,717,667,751,404,187,444,153,35,617,772,485,27,803,563,355,647,908,485,230,569,998,472,160,221,571,838,285,683,882,51,610,849,844,968,507,274,373,949,926,429,561,707,564,754,771,538,494,247,516,297,863,21,297,695,187,860,482,708,593,944,801,760,291,45,738,232,517,758,243,28,716,587,139,476,852,99,760,419,438,283,231,926,362,781,287,921,591,788,77,467,724,680,175,575,123,783,517,530,126,930,922,982,391,190,194,781,738,550,655,364,277,97,167,383,133,979,737,983,203,11,791,864,746,442,829,284,783,101,642,69,276,527,594,755,739,62,648,836,201,534,392,607,71,648,438,393,476,956,918,225,505,146,917,848,915,857,700,403,60,45,999,771,848,770,49,140,534,882,373,160,983,655,270,202,293,739,327,339,853,100,232,753,506,603,11,954,682,728,220,570,743,351,586,500,248,157,442,724,352,533,635,968,807,0,17,724,356,336,602,119,170,145,191,247,382,973,400,570,80,122,267,436,300,128,747,96,263,145,368,233,631,592,359,834,942,572,551,503,216,137,833,527,171,945,834,683,209,374,78,941,49,519,850,238,864,913,440,23,200,987,824,125,464,951,808,758,82,680,989,518,885,804,272,448,919,738,899,47,274,410,260,127,992,442,762,123,545,150,621,943,147,782,197,668,866,789,155,615,473,390,606,813,587,48,287,354,318,71,59,306,732,16,469,528,320,824,649,771,564,282,731,195,215,710,167,128,238,859,808,709,253,219,201,694,605,45,39,752,732,580,297,562,606,318,362,489,345,954,277,24,532,36,394,351,272,570,661,410,966,825,763,371,126,686,869,813,259,851,800,241,392,454,107,357,201,466,583,302,939,530,805,268,210,687,786,396,381,455,203,333,899,104,884,246,838,831,556,388,768,86,68,450,730,869,902,126,748,255,623,122,908,267,225,264,632,420,396,752,902,984,323,346,514,162,652,816,355,50,771,199,377,276,921,906,692,675,793,776,160,709,805,930,493,882,828,516,626,343,84,351,659,219,536,785,210,624,739,627,854,388,303,278,273,798,62", "978,63,744,570,535,694,467,657,847,931,762,988,465,499,187,753,151,307,527,523,466,631,981,824,19,481,694,350,258,335,204,858,532,378,674,500,966,842,667,799,987,858,233,460,592,219,555,376,670,835,186,741,563,162,428,247,167,647,195,505,722,76,599,947,773,529,814,650,268,756,88,593,913,783,306,418,886,691,818,208,245,876,969,689,396,818,964,150,500,326,995,30,922,263,514,474,609,478,116,914,235,288,119,966,623,463,881,661,323,536,105,832,932,169,715,556,547,908,167,214,352,497,855,203,88,754,50,113,276,321,979,943,734,928,903,30,139,19,561,469,611,388,925,368,633,989,395,827,248,447,498,219,394,918,900,700,591,461,433,524,860,904,452,822,919,174,748,730,562,215,439,537,903,243,647,529,809,577,514,309,668,819,479,287,740,136,460,749,172,175,962,296,987,371,308,808,607,758,242,279,360,652,999,57,720,491,983,55,552,6,41,795,82,827,559,540,655,386,440,462,384,75,231,471,776,740,31,537,407,615,173,911,744,267,186,273,585,771,20,126,127,529,519,671,701,64,456,685,887,397,97,312,811,502,475,513,543,125,242,96,628,303,658,577,959,855,665,279,640,271,718,565,266,874,105,990,856,148,96,234,101,426,490,411,491,578,897,224,723,581,555,549,182,600,129,769,729,817,551,484,446,37,333,315,818,767,214,705,224,487,359,347,644,485,793,238,660,245,250,171,43,947,505,721,706,730,436,321,469,999,845,353,557,435,182,727,277,440,748,926,278,497,777,613,412,798,773,403,87,864,372,967,492,443,386,909,195,568,5,222,42,92,361,581,648,755,70,89,701,597,469,46,717,413,609,77,511,908,977,622,857,571,278,954,511,4,289,804,919,55,452,954,750,878,303,241,584,804,817,154,842,104,607,158,286,98,785,890,230,693,132,309,343,256,674,798,43,357,389,651,732,370,4,36,683,128,657,730,466,286,636,357,17,361,43,926,649,223,510,338,355,801,408,276,714,409,901,437,664,974,229,485,891,556,651,514,33,799,291,508,487,517,434,996,419,119,996,853,861,35,644,51,196,336,980,613,587,626,445,363,8,333,993,771,695,949,308,849,632,169,523,477,251,205,411,912,340,104,556,434,714,566,903,235,712,580,846,929,171,48,550,703,168,276,503,249,228,501,76,623,867,751,864,716,248,83,585,416,246,744,628,549,205,702,980,237,440,107,361,675,592,318,637,486,563,427,276,217,704,439,689,582,163,304,667,977,432,169,178,869,655,263,931,127,124,804,61,658,353,353,13,577,204,794,720,193,67,8,354,543,363,912,571,471,393,833,123,128,920,490,176,647,290,713,216,965,45,683,242,904,859,993,890,216,482,75,414,673,596,671,207,611,150,426,266,759,757,886,821,847,979,831,360,165,84,543,856,140,290,315,930,691,882,175,547,920,764,995,114,239,344,96,166,416,795,663,783,115,11,103,991,29,657,442,380,969,170,817,430,933,848,372,215,658,99,919,185,162,94,198,509,591,889,668,408,909,987,126,144,324,439,410,517,782,110,222,876,774,850,714,446,342,543,895,909,283,215,6,284,62,251,241,275,978,953,651,129,244,12,71,769,737,84,126,350,976,308,741,612,814,797,864,542,539,903,8,558,228,365,749,817,401,819,636,669,504,381,406,17,0,192,371,858,652,158,844,113,478,721,419,991,212,875,405,798,613,665,583,722,671,951,12,984,963,200,400,160,918,995,81,683,416,632,633,803,718,331,586,465,79,699,818,920,239,262,193,463,685,66,914,776,164,627,428,305,464,536,423,564,737,292,329,630,509,55,440,719,147,132,491,622,176,971,888,804,717,729,220,370,99,84,370,152,649,195,174,546,742,659,789,483,408,805,974,703,189,699,668,374,810,784,249,731,700,857,57,682,549,880,775,318,517,490,801,818,30,717,932,54,167,793,602,5,340,675,833,927,160,654,460,394,989,907,389,555,652,634,356,397,494,846,860,295,11,194,556,568,946,616,608,69,435,128,471,400,410,971,140,463,421,926,455,828,878,532,425,504,897,629,690,191,686,586,696,190,24,826,719,698,641,509,968,46,800,610,90,26,978,347,346,962,457,697,958,551,391,325,778,41,167,347,172,338,951,795,701,193,886,545,358,429,830,818,401,420,463,74,594,317,734,821,958,754,107,450,118,439,572,176,705,290,35,268,566,221,217,500,437,712,874,95,117,160,31,951,323,269,581,33,763,824,285,258,724,840,952,469,66,681,169", "379,468,772,936,235,240,614,950,346,269,557,550,128,269,894,896,841,964,742,945,267,967,7,759,37,969,390,347,913,716,433,632,139,716,690,594,869,49,173,931,587,392,610,140,32,858,141,808,143,316,123,284,903,850,963,412,179,745,836,159,434,367,563,450,388,708,706,519,981,453,300,240,376,279,610,689,143,318,113,768,55,922,406,293,845,444,613,68,409,486,589,873,559,797,347,831,585,452,77,602,7,786,461,5,942,202,666,357,569,136,921,357,41,104,6,707,987,63,287,252,227,161,244,994,837,512,528,387,287,898,505,188,844,509,85,249,617,344,432,127,421,718,190,15,252,418,661,707,592,12,648,573,629,860,793,542,734,440,190,710,137,864,237,71,922,560,785,513,229,182,733,561,352,295,696,953,463,229,575,29,2,460,597,235,12,271,853,680,974,426,906,936,51,848,557,327,857,170,908,510,293,783,999,269,296,740,248,312,776,216,144,991,419,668,764,286,602,262,463,34,566,39,384,411,165,915,132,21,209,776,948,18,949,589,15,94,5,908,204,448,852,193,985,3,263,995,756,399,303,789,696,110,738,33,65,653,961,382,301,449,86,909,235,710,649,636,742,103,927,884,954,603,882,787,876,182,657,270,469,769,790,474,264,642,636,851,569,732,834,64,708,746,532,255,407,988,290,216,632,163,707,378,956,745,19,633,811,615,107,321,818,847,177,260,486,952,44,420,581,561,313,78,797,692,982,36,307,412,221,619,649,393,306,206,72,550,937,662,209,187,489,870,609,900,776,773,430,197,13,300,939,263,698,869,414,685,218,474,137,836,244,633,122,781,240,352,183,239,537,983,877,945,712,680,216,45,457,165,814,424,346,541,127,920,990,410,253,835,79,483,264,156,200,258,341,57,135,368,849,266,8,390,329,29,195,966,185,882,557,156,430,145,496,841,804,523,229,131,930,219,244,881,348,5,135,685,23,401,817,305,974,66,945,333,893,200,67,299,47,591,700,528,65,203,115,958,775,75,32,600,112,730,751,616,372,260,582,872,517,12,106,696,10,886,597,963,794,39,884,370,921,693,661,517,124,376,825,208,169,102,96,532,209,646,917,761,737,632,401,25,411,345,522,715,922,549,754,350,57,154,339,381,620,459,843,967,718,633,164,87,564,640,968,26,708,820,208,362,319,169,429,365,795,873,55,16,685,43,88,273,787,808,493,456,365,898,420,621,658,214,986,306,327,930,884,340,526,85,225,752,979,186,235,718,952,108,11,453,967,434,130,525,312,758,74,669,285,84,117,482,779,22,387,379,52,919,46,775,783,976,987,635,206,652,244,159,904,430,927,597,575,937,694,939,938,687,375,353,874,280,237,942,71,207,651,964,928,675,312,654,79,136,341,178,501,258,943,61,738,370,286,459,598,474,46,925,344,263,829,639,899,318,617,930,514,331,693,266,640,373,919,892,916,903,574,777,60,963,663,150,883,40,389,994,93,955,250,753,66,300,413,183,612,310,94,58,784,63,71,542,313,783,200,772,234,53,693,485,354,328,109,591,210,29,978,509,296,543,249,737,417,316,386,18,122,170,600,368,314,139,907,115,721,384,563,72,170,637,749,210,586,270,611,613,89,176,436,376,251,484,69,685,208,279,919,675,493,741,313,562,585,287,810,792,732,853,206,263,724,192,0,904,9,643,139,76,794,738,905,430,909,683,645,250,888,721,638,80,838,147,371,171,420,879,328,948,251,80,26,738,866,768,873,562,270,167,189,693,419,908,580,289,263,810,239,48,323,246,909,561,559,431,733,300,178,197,228,58,110,816,550,138,605,762,888,244,710,969,173,885,72,530,722,367,920,498,779,137,608,48,351,77,992,391,551,416,766,999,672,722,747,403,953,863,50,448,343,621,983,748,70,926,484,658,161,173,225,86,231,940,165,464,751,539,439,606,439,597,819,304,216,652,309,172,459,823,673,618,263,142,886,196,826,671,172,520,503,876,517,97,654,37,426,517,921,558,627,105,565,384,330,539,548,598,977,424,34,425,850,354,311,480,82,549,423,752,480,213,517,312,65,545,535,860,394,444,631,890,548,702,850,715,251,941,469,651,661,776,926,445,814,836,668,312,252,279,665,490,115,362,839,573,356,281,163,855,738,739,212,26,636,339,388,672,526,676,140,163,708,420,235,737,275,678,673,184,364,670,60,611,796,644,450,5,718,796,97,615,681,739,795,709,173,389,998,991,236,494,716,224,826,654,555,400,684,640,503,53,871,395", "488,764,726,826,739,856,480,637,913,213,244,603,517,969,446,874,880,473,953,941,523,989,14,65,222,526,810,427,817,509,823,484,989,527,392,40,301,599,711,997,578,253,313,549,840,240,299,452,455,563,106,389,47,244,641,524,337,295,125,496,883,900,712,388,706,893,312,343,167,240,280,199,948,724,114,670,964,671,606,234,730,280,152,382,716,79,516,207,358,428,542,768,976,962,827,402,619,559,241,644,382,241,457,719,495,729,296,123,773,521,726,395,309,405,228,508,781,315,756,288,706,826,278,316,542,997,112,342,270,1000,609,140,272,888,621,216,258,700,795,695,5,120,995,81,774,284,998,122,592,967,30,890,129,365,474,732,555,763,286,569,302,470,245,578,456,251,324,931,230,150,853,985,31,567,956,401,669,797,77,361,80,564,723,634,257,116,851,896,821,998,89,767,713,294,682,358,952,191,326,422,808,846,450,851,624,372,858,358,582,693,254,278,349,394,569,460,158,770,712,805,942,274,667,774,986,2,198,544,124,886,370,935,406,3,780,913,289,655,145,146,371,485,516,77,905,663,443,165,156,479,548,299,418,566,826,744,473,189,766,286,51,195,684,495,137,609,989,978,314,343,613,117,220,545,228,147,973,966,298,978,225,578,778,883,273,43,561,932,321,965,112,927,671,493,441,255,767,872,114,609,221,192,947,460,268,113,591,296,306,975,487,836,195,461,878,454,519,159,481,311,579,989,510,298,259,662,611,945,431,632,263,787,61,737,116,912,207,539,210,789,493,366,139,266,675,441,890,20,393,870,958,672,516,784,547,563,422,189,699,133,42,60,359,944,609,818,155,872,89,355,7,888,586,134,865,13,506,383,540,234,998,531,585,486,704,361,902,333,252,498,825,86,254,603,835,333,191,916,989,488,931,909,711,238,469,439,643,369,884,27,604,65,681,266,492,449,937,471,690,981,213,362,949,95,894,650,693,779,545,716,694,967,90,360,206,35,228,814,750,557,46,303,689,40,323,85,731,241,663,918,507,91,325,788,87,291,673,759,870,65,851,472,287,259,53,293,215,880,488,903,276,102,350,975,929,339,642,661,455,188,831,313,177,926,205,373,160,672,411,954,556,383,647,236,94,624,823,476,516,335,967,892,5,107,914,797,556,603,154,777,40,673,632,572,210,144,780,689,727,341,213,481,650,889,100,356,220,392,185,457,152,31,179,857,12,712,874,156,684,876,636,100,113,515,114,106,999,950,230,703,777,403,598,969,556,137,904,174,261,489,576,137,797,522,660,619,923,66,316,146,721,38,502,323,517,799,758,226,956,940,330,509,551,54,405,801,320,146,584,838,824,339,153,297,984,385,557,701,672,141,172,40,772,588,954,431,774,40,903,554,35,536,820,749,692,579,837,992,607,102,258,917,293,679,411,247,421,595,798,826,57,476,269,995,419,614,927,424,526,459,174,305,27,860,9,876,921,2,887,357,112,253,882,591,335,50,863,461,257,308,41,481,731,689,916,211,138,536,892,68,708,199,417,465,276,589,302,272,168,384,9,927,709,218,169,150,581,526,318,965,2,728,275,281,602,417,616,972,66,953,779,202,270,372,643,453,167,878,272,333,589,874,807,255,582,292,483,488,117,826,174,356,192,348,260,260,984,152,350,883,106,692,647,59,25,384,969,205,356,371,904,0,970,457,205,774,60,826,819,140,949,879,388,870,390,103,234,430,755,51,10,972,568,878,728,137,422,333,104,633,359,419,962,324,596,888,225,511,792,675,307,201,529,148,302,943,475,750,189,651,255,922,688,584,445,838,122,120,617,882,885,491,776,73,734,151,63,590,650,332,836,586,391,450,907,102,914,142,770,905,570,107,786,423,369,460,277,514,179,371,926,855,508,734,381,703,165,66,161,746,115,623,20,628,52,200,627,914,481,912,473,410,189,950,476,490,580,221,299,262,325,986,682,442,172,871,728,858,394,833,114,202,697,447,298,603,66,78,151,129,430,702,157,133,311,571,639,590,33,653,860,78,531,768,748,377,710,945,407,822,905,743,667,805,757,909,850,458,129,480,35,547,457,739,967,767,468,552,575,774,402,517,560,152,666,519,513,818,832,931,4,72,966,670,993,726,502,727,928,376,27,138,576,967,417,187,259,605,134,774,106,275,82,934,895,809,781,748,29,192,311,187,336,691,525,56,942,282,4,899,562,483,344,691,801,460,979,120,777,564,713,446,846,661,847,463,191,69,519,351,472,787,600,394,340,987,964,947,888,501", "392,594,838,397,8,553,89,591,649,940,362,81,464,163,463,504,375,790,672,932,233,416,820,316,735,65,111,400,117,712,183,794,34,566,519,189,28,339,945,304,402,759,777,346,716,911,21,379,899,897,933,23,292,622,479,268,106,703,956,366,597,72,926,949,809,365,516,847,928,56,119,806,672,900,594,755,676,3,292,953,52,219,698,334,66,816,227,288,556,90,973,501,742,76,333,849,246,306,817,810,87,504,789,895,954,476,21,441,996,242,852,649,714,909,857,323,404,133,353,812,157,538,662,171,591,920,945,519,173,544,930,447,763,736,275,879,887,227,138,858,780,481,481,677,799,430,116,568,162,27,731,88,455,73,223,404,760,759,11,612,485,917,974,201,738,835,474,916,615,989,472,433,14,329,343,324,74,175,354,426,308,883,519,882,217,906,761,792,849,616,811,548,105,333,490,484,105,232,199,512,398,569,635,455,648,915,76,599,560,18,861,660,3,188,16,938,889,329,811,336,481,631,325,677,549,801,90,388,993,479,900,795,941,874,271,348,737,4,459,91,186,93,20,312,208,378,911,783,349,790,493,989,791,423,953,211,362,629,376,286,105,173,411,351,44,503,436,581,800,80,742,775,526,776,576,374,82,642,155,448,894,113,914,978,240,778,268,219,921,263,14,723,67,886,277,67,802,412,755,635,512,754,436,963,525,638,186,866,634,149,188,110,537,798,364,528,534,847,919,535,384,20,370,403,279,257,132,653,310,12,543,154,803,762,944,61,257,948,188,504,336,408,18,483,944,254,387,65,562,419,560,200,770,76,474,69,456,752,569,253,90,14,941,737,318,412,196,803,677,450,507,991,425,414,182,195,476,799,289,64,331,907,760,235,633,137,400,819,855,425,140,453,236,572,101,925,52,955,429,517,999,125,724,32,435,706,281,798,278,299,275,829,419,691,637,594,886,264,892,629,638,945,928,322,37,267,294,905,520,661,901,500,32,479,409,767,893,574,911,555,818,55,878,962,198,15,454,55,816,954,685,503,261,379,251,612,225,683,431,794,536,761,107,777,243,803,81,719,457,834,533,407,919,712,744,382,24,388,382,619,82,153,331,250,556,443,652,210,422,919,91,594,104,207,528,220,733,3,818,954,691,339,477,369,683,745,82,879,969,623,56,149,441,648,171,491,883,180,649,541,912,447,439,164,377,63,237,91,123,995,987,839,929,79,299,745,295,698,294,408,642,857,883,971,98,40,401,320,905,146,454,977,614,479,823,339,294,425,505,732,30,148,529,794,854,287,634,688,185,543,878,89,911,95,230,445,805,623,359,814,487,587,532,921,12,665,286,454,393,528,283,110,371,84,877,760,233,471,296,748,838,853,654,178,722,838,474,256,706,5,910,236,739,979,917,587,762,30,387,918,729,750,858,871,954,159,231,954,585,917,492,881,498,113,406,650,56,493,128,741,858,836,888,259,515,713,402,23,244,267,805,758,170,899,868,561,787,114,123,998,704,139,238,403,594,345,458,403,786,301,937,900,101,808,132,156,86,512,547,193,812,935,251,458,954,856,596,325,5,575,81,869,266,57,675,904,978,607,381,461,468,930,416,713,2,886,428,147,32,898,40,429,906,562,551,148,921,497,289,199,388,275,34,524,21,551,172,484,208,145,801,13,7,619,314,882,391,826,336,858,9,970,0,409,985,603,386,636,111,155,543,363,712,228,41,626,563,445,362,695,2,714,657,544,116,503,509,646,15,689,65,106,23,853,513,546,236,411,188,88,829,425,990,839,46,22,459,783,709,558,417,431,920,950,869,69,573,640,608,87,411,910,388,492,292,637,958,282,714,861,973,86,711,452,911,494,661,542,490,284,73,304,790,675,880,714,242,225,681,25,549,23,719,635,215,771,475,599,826,405,907,231,659,243,722,147,54,822,717,273,574,605,526,136,364,961,25,764,304,705,380,264,191,184,945,666,179,569,616,155,778,758,82,854,409,64,339,350,265,283,722,995,640,540,520,212,718,203,829,300,358,548,895,82,446,400,643,5,433,196,155,717,566,26,535,178,727,396,617,82,25,743,947,8,128,249,919,469,848,202,291,352,949,784,751,748,86,323,218,187,585,223,284,197,23,350,656,851,465,430,212,306,74,538,506,353,942,314,465,663,891,430,940,532,996,891,301,960,526,664,113,714,307,345,913,120,968,319,403,622,935,860,168,159,475,696,188,366,661,343,652,31,729,41,471,456,363,389,622,284,264,728,430,415,307,746,191,120,351,251", "649,90,590,333,808,22,777,669,780,984,998,497,783,133,364,445,881,746,625,612,760,700,596,262,199,958,781,230,969,648,237,152,862,387,654,182,483,674,113,693,944,512,332,762,427,675,616,469,13,312,809,997,368,974,684,517,347,408,730,795,538,998,22,223,374,170,775,893,219,350,617,185,886,255,443,423,732,965,800,841,714,111,211,461,632,323,619,444,441,923,165,572,341,788,56,649,800,833,795,954,504,897,500,983,249,845,123,770,468,50,283,64,911,145,143,11,78,458,507,703,181,336,609,793,504,96,971,460,881,234,427,72,376,63,100,784,127,832,698,15,192,472,167,674,44,78,470,490,302,520,577,974,861,550,157,30,320,107,358,526,992,897,341,335,845,145,110,947,279,789,559,899,485,185,893,804,413,800,264,78,841,806,265,977,242,250,151,75,736,931,806,14,210,36,485,221,463,938,10,198,558,710,198,484,512,443,644,768,420,77,789,788,7,595,118,392,885,718,884,341,700,559,911,659,291,365,694,890,135,545,614,882,199,354,485,199,197,921,920,212,660,703,692,599,535,90,329,375,507,649,575,673,819,426,834,895,808,888,184,874,314,32,202,606,878,352,814,367,143,462,175,605,932,598,181,855,197,142,417,782,794,819,361,74,54,356,173,930,230,610,183,372,46,569,67,872,371,348,599,275,601,104,89,268,468,307,245,789,988,878,440,599,324,898,334,379,577,517,82,289,657,323,721,126,71,101,889,377,521,281,940,846,398,202,420,166,731,869,687,34,336,506,295,743,825,566,899,197,472,724,90,106,233,535,894,690,27,265,844,500,617,119,875,1000,214,54,990,322,47,683,29,445,711,435,995,625,958,567,175,826,30,722,358,876,682,250,490,263,199,263,636,206,985,785,720,177,542,326,600,822,926,130,79,750,827,826,403,974,144,993,95,466,117,12,575,625,216,104,308,156,724,168,566,468,860,186,597,644,242,710,786,812,384,401,168,110,425,687,601,450,822,841,840,474,498,538,67,728,521,331,551,618,321,261,391,95,733,214,202,110,966,645,124,795,159,196,21,553,291,665,821,586,465,984,410,131,752,565,45,594,69,312,831,934,635,760,338,606,905,120,664,294,536,911,734,380,11,308,924,85,261,88,554,179,384,331,881,14,314,444,665,266,637,180,564,772,595,56,447,142,200,772,864,34,474,830,70,935,10,688,593,369,705,949,545,926,135,200,427,795,181,793,684,77,485,645,24,245,749,531,739,892,946,448,938,873,577,752,20,297,96,165,918,126,886,297,340,356,738,941,331,66,299,743,161,605,410,551,771,660,541,508,609,328,388,339,71,17,402,1,352,745,580,470,104,865,63,51,940,571,77,134,424,248,640,763,140,818,194,469,327,868,278,716,135,607,902,720,348,830,389,329,344,295,460,174,689,56,597,124,242,581,572,806,786,19,142,990,155,355,737,310,404,293,165,431,822,627,816,838,92,868,276,221,644,929,505,343,687,301,36,512,265,63,27,998,210,151,215,132,146,440,111,429,572,95,392,231,27,584,464,498,882,478,810,719,674,933,30,888,530,938,13,901,128,364,608,243,204,388,939,175,655,751,799,582,551,620,615,968,48,93,806,551,508,257,249,944,34,2,716,986,571,924,323,833,933,314,747,13,981,605,426,110,624,791,977,509,602,652,643,457,409,0,267,437,522,149,195,215,790,463,479,854,722,315,110,593,836,78,342,485,282,642,855,287,4,113,679,625,914,739,808,476,37,867,293,144,647,683,957,851,278,164,517,904,398,327,420,410,599,94,862,807,307,451,454,167,864,812,348,329,658,505,338,633,52,662,200,649,853,865,742,930,309,153,972,182,624,412,300,316,693,342,848,599,63,904,853,139,981,689,146,164,145,979,77,829,1000,743,722,79,475,600,647,864,26,618,694,272,522,726,117,450,314,835,923,36,48,561,263,703,683,298,103,652,782,952,382,631,178,728,368,137,641,932,434,561,447,128,977,657,959,454,29,174,684,956,230,455,662,702,998,78,145,463,304,945,504,755,652,969,342,575,333,910,53,379,114,66,26,345,200,62,769,861,478,13,62,863,435,723,254,154,273,230,622,689,150,820,250,349,834,17,910,672,584,306,902,101,740,521,157,699,102,117,348,561,394,195,147,660,429,572,563,564,826,819,877,296,968,872,48,410,681,927,845,261,335,281,680,121,659,957,253,100,935,910,512,288,150,759,40,825,179,79,787,862,327,967,234,899,772,46,11,614,628,440,752,627", "951,745,964,62,65,91,903,814,750,133,915,495,577,937,395,969,578,751,463,88,456,352,569,605,106,14,677,451,761,912,143,392,489,218,697,813,801,805,425,687,428,258,358,735,302,450,686,554,974,274,383,646,582,958,719,293,232,890,354,442,173,602,640,357,846,171,269,410,634,229,245,69,631,310,119,770,625,129,158,826,955,13,410,18,41,414,893,626,710,776,982,802,952,944,176,107,336,719,975,80,815,453,302,164,143,884,977,385,745,305,420,36,749,491,566,637,9,182,549,745,716,522,318,203,817,855,232,481,908,131,841,485,698,905,979,497,569,629,755,427,747,462,878,632,8,641,204,709,227,232,266,137,320,22,399,620,300,482,917,910,61,869,820,438,258,276,135,937,180,668,142,425,235,615,231,698,747,38,698,401,964,792,360,392,635,520,647,762,414,983,160,193,983,516,151,450,222,323,469,227,457,420,554,712,715,605,252,815,731,974,831,24,728,617,262,84,140,825,291,398,937,999,964,271,386,543,322,877,126,357,685,639,141,16,397,100,744,297,22,368,376,13,403,3,810,442,389,897,487,619,509,920,850,428,492,401,250,919,898,30,803,195,221,838,999,431,895,70,365,115,172,230,346,721,425,60,779,905,962,572,334,50,567,372,266,220,552,756,38,463,190,836,697,523,827,237,673,505,230,863,145,493,848,365,443,380,890,895,505,79,338,567,940,902,848,543,288,236,902,152,322,617,206,466,333,980,93,653,141,294,641,677,797,78,688,637,554,218,439,886,172,246,889,741,125,498,546,427,436,8,21,719,919,137,703,524,363,270,948,756,582,461,223,894,949,249,349,880,654,287,669,761,757,877,124,809,58,565,418,289,318,13,62,221,350,456,109,105,289,229,391,760,16,182,564,405,563,263,86,200,493,62,977,344,551,630,343,274,257,461,422,135,592,77,192,303,537,112,699,382,617,363,47,164,772,578,401,244,971,262,935,731,558,147,60,542,836,974,339,380,486,407,721,704,430,200,807,9,474,981,599,714,627,98,326,583,744,361,596,580,863,863,507,248,408,727,35,334,190,318,824,946,194,521,612,285,279,164,12,464,749,296,731,875,697,196,109,797,282,967,227,142,42,74,201,11,448,336,194,172,83,759,296,177,949,639,389,521,355,194,2,702,750,649,206,16,223,203,673,33,790,47,353,364,157,943,238,9,133,133,70,246,366,234,917,959,196,325,136,223,512,52,764,397,881,973,686,680,709,142,52,434,622,28,418,756,756,891,348,419,325,272,373,525,980,185,6,738,701,188,99,362,318,213,209,51,895,643,898,713,473,990,666,499,442,357,689,536,498,69,128,189,183,767,5,833,650,158,170,881,975,856,560,922,490,798,382,522,886,519,357,971,46,109,471,239,718,781,691,870,150,678,430,687,206,782,232,632,46,888,249,759,16,802,770,435,359,83,711,599,533,766,289,820,902,115,324,179,386,459,477,996,740,371,17,35,434,941,586,833,949,501,26,334,403,783,930,880,338,151,708,431,347,542,812,72,127,940,801,171,580,605,874,846,667,457,352,889,314,454,884,580,371,175,784,197,444,922,770,430,653,394,771,268,896,873,54,785,928,681,746,778,757,638,41,491,525,806,274,959,814,719,649,856,897,795,822,171,760,46,79,951,945,52,128,135,916,393,119,158,139,205,985,267,0,399,866,918,359,226,207,214,960,735,198,264,236,317,946,434,563,889,604,320,147,231,882,403,920,520,297,770,240,509,174,454,318,957,937,102,653,157,838,145,251,799,558,862,52,242,240,467,994,124,556,909,29,384,913,505,568,996,973,194,728,711,544,941,404,20,434,953,304,611,415,968,128,265,475,225,628,684,320,333,10,132,683,598,807,811,557,742,176,877,152,213,879,199,480,55,922,18,24,739,545,19,596,393,358,482,413,734,462,184,216,898,805,268,543,811,8,803,994,273,735,251,599,99,156,679,430,947,674,527,389,241,977,627,955,994,572,798,268,920,228,242,515,269,770,488,409,435,295,119,423,95,805,324,400,180,188,567,37,485,355,350,167,590,843,455,483,865,249,848,978,81,613,7,601,680,596,809,61,525,747,810,966,78,709,817,694,98,461,363,597,129,216,709,713,610,804,443,335,110,506,151,291,935,615,647,917,243,543,450,455,669,517,421,946,170,411,179,623,370,426,814,71,568,791,845,247,103,425,477,44,706,247,71,200,498,20,632,54,206,690,759,209,286,818,762,65,44,311,827,530,866,391,211,123,44", "927,7,760,296,759,684,861,827,454,838,243,342,739,939,791,529,545,484,353,599,652,193,104,541,17,582,867,678,935,428,530,80,777,935,978,239,869,810,599,802,926,333,650,165,472,774,292,292,30,436,264,869,509,122,108,291,846,855,36,369,369,821,812,605,502,705,309,591,547,299,144,546,975,46,953,162,492,311,175,533,99,701,675,269,809,536,688,239,923,379,877,715,712,531,851,161,888,574,778,905,643,304,321,662,316,765,46,423,11,706,13,776,436,768,583,598,734,440,838,929,26,62,236,733,762,75,75,30,165,478,472,919,678,323,271,712,821,712,636,473,507,759,334,136,157,903,113,655,95,24,57,983,626,337,416,181,264,560,76,826,858,232,267,853,676,837,769,155,24,85,204,913,359,380,112,438,835,94,319,210,420,561,474,268,984,75,46,399,126,561,83,215,334,262,152,902,941,208,464,485,655,845,256,54,312,775,264,651,843,94,559,75,826,681,905,393,20,626,988,375,727,959,573,932,676,743,778,49,651,636,646,507,940,663,829,293,768,55,966,57,287,375,180,312,299,437,81,95,523,600,238,989,512,305,518,241,355,739,659,137,735,985,622,871,909,874,601,734,462,687,600,838,874,524,992,617,796,908,59,921,19,522,515,14,607,532,849,816,8,677,247,416,377,168,813,586,523,13,797,280,111,522,451,9,253,321,979,253,239,260,157,769,391,703,199,597,12,232,693,501,793,516,160,499,513,545,153,241,728,789,737,756,654,921,863,11,723,288,347,979,612,470,776,611,682,500,130,849,970,321,32,848,640,151,589,307,361,400,970,478,876,668,520,33,737,867,770,442,178,73,19,415,812,110,540,749,940,448,837,770,128,511,887,57,919,227,170,2,847,829,523,84,55,380,334,14,238,114,212,652,764,955,937,37,212,149,149,518,137,761,404,271,81,538,504,495,17,456,836,777,806,274,198,425,446,661,1000,948,443,612,439,136,372,718,204,554,480,358,466,336,872,79,651,219,830,465,824,456,407,507,178,2,127,505,641,106,288,229,590,293,307,8,848,780,63,71,925,442,628,126,967,256,809,765,667,759,750,551,70,781,854,389,605,278,157,177,713,749,384,89,376,930,467,837,28,328,114,618,163,783,546,590,412,263,283,700,576,258,550,252,186,477,690,584,744,747,936,623,287,375,583,519,981,577,873,810,830,623,242,485,13,107,970,656,125,132,407,445,296,219,948,682,490,561,942,168,124,112,608,385,338,855,129,137,874,497,159,493,49,201,303,974,550,404,173,313,182,558,909,794,788,159,93,117,649,835,586,313,578,989,191,755,289,385,679,844,154,123,385,193,60,74,770,176,638,420,538,389,926,747,61,147,113,665,99,226,398,318,46,219,117,585,102,144,342,670,211,903,900,645,612,375,725,108,366,343,794,471,522,544,501,658,995,762,692,33,211,536,341,868,614,929,778,481,816,565,53,718,548,595,843,348,210,453,90,681,721,473,876,340,343,75,763,184,126,614,614,60,886,672,409,456,173,318,216,354,31,688,213,21,805,808,551,688,413,583,638,643,538,987,779,119,620,350,607,367,921,359,195,546,128,822,391,826,134,569,789,335,12,982,705,325,591,130,888,82,570,155,686,294,419,32,151,690,864,554,4,474,600,875,652,225,909,462,366,427,490,724,170,844,76,774,603,437,399,0,647,715,908,540,536,483,667,918,797,579,375,855,560,991,599,268,31,662,193,229,831,914,974,238,360,276,947,6,243,224,910,397,408,850,503,704,125,287,704,252,737,305,888,609,189,914,916,511,331,162,786,971,319,515,590,405,140,40,918,228,826,407,548,394,509,612,339,992,730,294,950,809,431,769,25,636,462,869,940,648,132,316,52,534,405,611,161,274,627,669,943,395,464,903,531,838,8,735,314,842,982,305,124,810,413,489,576,38,968,677,600,279,384,472,396,76,585,463,969,946,278,328,69,872,420,564,493,682,5,409,591,411,947,881,793,990,760,91,929,26,312,30,489,273,517,146,153,150,716,582,330,848,951,333,333,439,464,865,415,504,56,973,502,555,39,407,327,157,264,125,479,35,103,267,934,269,813,155,185,487,511,801,994,500,751,155,575,98,952,183,519,466,465,399,265,75,981,322,559,236,805,394,665,863,613,153,395,921,342,563,446,964,794,251,88,935,468,591,176,719,188,805,563,599,816,550,726,222,218,349,279,408,972,446,673,192,835,814,692,711,21,529,352,651,752,392,661,520,996,934,957,813,212,929", "757,24,201,431,13,191,457,582,705,320,509,392,675,488,222,623,244,128,432,273,567,620,281,765,928,145,14,279,685,601,799,389,855,315,96,928,160,716,915,671,993,590,109,361,600,538,503,597,726,953,588,280,12,380,561,141,371,481,166,750,725,952,266,182,769,520,798,968,485,566,2,933,643,598,378,982,568,95,416,724,2,410,279,967,522,933,183,572,839,997,68,496,307,842,477,794,383,459,937,65,141,944,727,894,933,211,802,498,600,732,876,770,564,122,330,369,172,254,600,599,551,510,111,556,188,962,383,2,876,119,442,888,543,224,982,372,106,661,761,563,171,739,710,367,24,514,866,436,584,125,834,542,261,569,554,940,338,287,928,17,436,115,239,75,153,773,221,50,994,379,102,136,544,751,171,412,523,832,94,932,11,554,293,416,162,537,423,715,767,930,191,78,522,819,920,487,260,631,387,243,324,371,660,501,899,561,255,127,446,954,643,829,598,568,680,971,178,538,749,576,355,980,122,509,307,833,992,375,810,840,654,988,870,100,903,567,785,510,738,309,774,591,770,136,889,131,237,584,25,577,307,246,497,48,802,658,35,514,167,147,304,848,410,253,584,333,399,551,844,800,553,833,990,69,722,385,192,694,491,138,846,687,130,970,258,969,436,585,82,695,146,822,655,895,363,930,396,803,223,827,343,598,790,42,754,544,41,677,155,592,882,363,590,806,283,590,263,540,225,696,346,718,318,674,708,751,89,486,494,320,76,198,465,582,411,233,785,984,388,488,588,326,156,516,126,622,829,488,974,141,636,88,509,182,802,169,992,854,628,271,659,318,52,16,688,652,72,410,271,432,804,744,299,982,213,162,170,611,353,125,824,613,269,226,471,81,123,362,231,136,358,976,865,237,311,202,138,467,68,237,707,745,696,598,563,108,520,369,95,787,383,217,945,929,651,926,7,423,742,301,520,471,579,606,789,772,134,686,202,273,218,733,888,25,64,628,18,834,259,797,557,838,363,61,803,430,85,51,760,738,94,495,248,615,452,798,652,2,407,435,332,391,446,42,287,634,873,863,604,388,358,611,399,29,842,711,31,622,510,12,742,688,875,618,949,108,280,713,97,449,321,149,971,27,794,27,974,222,411,309,957,156,887,569,407,370,787,862,738,414,833,407,973,4,191,475,267,796,447,847,971,639,348,923,812,272,863,497,267,651,484,818,148,523,791,114,320,807,651,959,959,917,454,263,945,69,470,828,816,431,245,469,813,866,644,163,398,731,410,30,796,722,369,719,84,10,612,442,592,814,10,93,52,166,768,259,871,270,576,960,157,625,296,805,53,823,476,512,752,210,749,365,763,851,144,904,457,856,713,204,960,120,920,806,243,161,186,581,724,390,548,872,174,205,963,63,71,909,530,797,218,801,943,367,706,295,729,705,760,615,671,212,247,711,510,998,422,230,870,169,560,741,167,520,356,452,747,789,750,992,608,968,843,589,639,613,689,428,916,508,456,389,936,280,70,331,372,653,620,336,409,802,388,71,28,487,397,533,480,969,528,754,823,558,209,130,133,747,358,47,798,88,372,512,190,578,324,157,252,316,242,547,291,265,566,765,613,291,781,237,215,523,271,127,788,106,926,859,755,648,654,562,523,789,478,701,910,918,592,785,720,793,36,101,273,123,685,621,145,113,794,60,386,522,866,647,0,463,958,71,17,838,122,395,522,237,904,480,773,646,399,180,698,36,455,701,765,710,685,482,379,216,205,882,765,755,265,198,833,437,266,534,232,79,305,68,469,612,919,684,191,194,780,922,592,549,146,575,708,931,758,779,33,447,414,718,123,387,675,279,90,622,247,44,552,543,298,233,653,710,653,202,946,976,715,770,351,714,429,48,938,485,461,778,90,905,49,750,443,273,351,603,904,396,567,532,84,579,20,877,788,710,575,572,119,619,840,94,243,660,739,334,65,242,958,81,710,268,734,551,229,219,801,225,399,530,394,711,742,100,448,510,346,71,495,884,203,549,115,307,643,898,643,725,409,469,826,687,354,48,497,609,916,340,130,608,332,779,379,866,68,342,809,452,56,495,378,465,664,669,880,753,696,244,893,423,182,72,630,982,42,440,93,223,710,978,529,68,473,498,569,170,920,432,581,220,180,718,328,939,691,756,166,689,792,74,85,170,39,706,335,288,433,593,157,87,922,428,916,975,83,515,48,508,225,521,614,3,62,910,805,62,862,220,100,126,155,845,244,852,189,47,341,754,513,356,459,265,710,531", "835,252,16,960,59,882,133,892,780,835,381,329,748,37,877,351,911,566,629,398,264,401,402,876,910,282,56,716,398,710,241,578,737,253,725,684,724,621,959,33,863,279,609,495,908,126,932,348,706,677,234,651,626,508,643,483,134,513,64,57,760,410,589,250,356,187,777,710,537,156,157,714,546,86,801,715,566,279,888,403,384,113,939,511,725,795,407,574,363,481,398,325,637,316,683,739,445,341,518,480,986,15,528,158,959,941,865,202,308,317,202,527,87,879,364,28,195,289,62,420,576,695,118,517,614,885,367,151,283,524,168,20,726,365,323,117,552,336,865,106,860,995,913,935,866,356,533,819,958,728,923,433,854,454,341,299,543,338,175,163,634,607,184,249,243,411,851,314,485,869,435,619,863,973,103,870,168,970,520,455,4,54,875,87,304,711,511,757,56,896,159,298,36,327,364,191,223,750,728,668,583,298,398,436,740,426,201,104,668,991,552,860,275,164,86,310,284,850,77,835,360,537,214,234,533,950,91,788,112,54,305,40,839,624,702,661,596,929,943,602,216,889,553,583,370,209,961,921,120,305,785,47,240,263,824,896,841,115,240,591,450,933,465,115,554,482,933,347,811,729,389,38,218,961,194,631,549,489,596,119,850,612,887,357,589,217,104,185,361,226,378,780,166,658,748,275,101,277,813,789,854,349,685,731,83,908,940,784,720,938,601,240,425,957,877,887,37,876,771,904,961,601,693,163,593,99,201,243,165,936,718,123,216,18,364,208,460,730,915,36,697,968,665,545,269,501,532,188,788,883,832,83,890,860,932,918,988,216,866,392,324,518,518,26,929,767,962,944,622,363,8,67,585,587,897,213,470,714,165,63,857,836,245,465,797,23,490,626,986,412,498,911,175,68,435,695,233,410,311,634,226,928,994,691,895,993,759,688,320,739,976,457,861,931,518,599,41,619,624,372,96,125,126,145,94,863,736,232,930,628,303,99,47,341,815,636,945,118,159,587,80,860,979,928,697,650,623,259,930,438,425,894,252,116,944,447,448,447,642,7,314,200,845,567,212,70,380,125,176,247,889,491,223,293,386,681,788,857,550,960,660,432,882,909,413,126,240,633,313,27,476,496,595,320,767,54,736,66,634,38,653,655,455,410,133,384,549,192,819,39,986,911,591,723,836,434,179,949,417,517,15,231,498,195,242,461,326,287,457,361,664,489,805,431,893,463,277,338,27,882,491,264,47,179,851,964,717,953,433,983,727,622,312,678,499,668,429,267,244,249,711,673,97,152,862,684,716,865,356,47,845,769,544,687,574,455,998,114,669,95,132,663,23,391,456,407,776,97,545,641,162,370,998,321,862,85,579,493,116,969,82,6,90,622,560,71,329,140,29,325,768,936,207,244,583,7,651,60,225,853,419,330,102,888,887,254,927,117,768,484,458,67,161,401,290,285,731,818,209,660,85,841,12,857,781,576,810,367,945,587,154,957,865,334,236,937,158,156,659,691,750,792,825,145,488,228,525,906,986,734,863,139,296,727,998,457,551,615,206,961,893,97,254,133,409,147,491,196,718,456,18,109,105,272,891,351,352,214,725,194,7,13,7,863,337,303,180,11,573,613,46,199,140,572,108,969,397,644,748,118,417,647,145,185,89,15,122,79,813,896,524,929,376,491,152,232,396,312,191,478,738,826,636,149,918,715,463,0,275,860,309,694,179,608,355,193,588,578,898,321,253,119,881,84,988,840,346,853,301,314,64,647,451,282,399,206,755,495,861,579,624,371,323,903,683,332,691,840,527,391,39,134,4,381,241,393,1,261,803,427,368,152,917,649,794,320,20,917,228,375,70,177,29,738,379,314,570,911,4,621,419,396,307,808,439,201,315,57,394,475,800,286,421,435,554,619,440,536,492,176,242,645,619,659,437,835,855,467,751,311,754,656,870,420,875,660,596,218,149,709,454,605,214,298,283,88,670,621,758,19,118,829,313,852,547,842,103,803,613,61,723,523,134,429,371,337,865,653,998,306,827,634,679,754,962,37,520,421,503,238,535,361,52,819,949,540,164,409,646,524,445,743,279,162,590,51,379,830,281,117,288,779,460,708,406,605,262,472,106,480,255,626,972,498,107,239,3,590,106,617,828,570,774,109,171,455,270,344,350,823,850,886,93,161,869,584,18,810,218,638,71,639,50,115,548,335,610,136,950,408,54,389,221,558,345,92,394,604,478,870,320,849,104,118,392,641,122,968,868,615,288,270,520,676,133,965,389,714,603,699", "567,528,9,424,364,530,711,200,998,760,237,404,729,929,786,773,723,761,494,280,477,775,486,919,754,343,431,821,111,210,584,397,494,741,232,490,411,329,329,963,81,507,257,130,619,126,779,210,68,611,82,524,993,971,592,325,371,364,240,382,604,503,529,440,802,920,528,98,390,733,551,106,215,55,147,624,342,275,749,751,818,632,273,662,340,820,586,72,484,24,497,169,689,431,598,981,847,727,676,197,428,829,436,602,109,245,715,91,607,989,435,84,980,687,144,683,549,852,299,431,865,523,706,674,381,730,754,89,421,600,835,695,392,214,37,217,445,823,463,296,466,305,778,539,297,392,119,683,468,314,647,606,943,273,685,53,486,912,552,950,57,123,824,608,209,334,330,755,372,775,32,589,130,633,535,202,462,224,69,886,479,786,694,445,63,121,377,223,343,494,919,522,514,874,261,493,19,295,498,491,612,735,884,819,526,910,488,760,175,844,375,901,754,887,578,598,880,740,756,298,714,38,320,52,390,711,547,406,729,827,884,638,910,354,237,112,796,456,766,387,873,485,508,459,867,345,11,772,200,298,692,864,616,707,632,715,507,78,68,127,10,450,135,56,466,180,615,530,356,47,906,623,887,28,919,877,976,62,491,218,90,159,525,854,974,722,785,461,642,667,166,643,252,565,984,217,202,99,386,623,946,954,477,644,114,847,501,9,944,334,331,391,996,854,543,36,232,45,790,802,972,348,594,514,508,483,767,158,834,622,973,596,504,923,851,316,192,128,412,888,439,109,990,323,169,78,268,555,534,717,488,915,562,595,367,286,182,988,236,316,38,913,847,1,266,365,892,802,415,506,142,508,61,668,944,814,355,886,358,481,24,787,580,745,592,194,298,336,797,264,853,971,2,606,865,658,89,31,49,352,717,805,440,775,579,993,905,404,749,751,587,950,767,194,411,54,78,152,578,46,252,488,472,499,174,732,840,979,330,701,409,194,818,621,967,599,660,989,585,764,539,941,175,504,631,167,156,679,197,11,371,223,134,581,37,34,681,654,37,933,298,378,906,145,175,955,476,875,809,916,512,176,267,822,950,172,957,753,534,363,874,228,111,555,759,678,34,247,812,291,355,171,425,683,677,705,609,166,639,351,779,75,260,490,23,784,248,424,956,220,712,850,386,438,466,62,969,310,119,243,765,292,31,126,66,906,32,200,632,346,258,902,546,585,466,34,671,820,896,990,510,276,662,692,491,433,747,872,49,542,531,647,495,763,528,319,811,123,394,507,594,843,464,240,60,441,184,908,791,878,943,291,591,135,608,563,52,927,767,83,428,743,226,123,221,481,292,432,762,230,232,479,472,474,342,363,377,607,630,886,795,631,175,134,850,405,887,815,32,86,805,532,444,651,992,496,15,388,350,798,840,154,146,288,206,276,130,501,893,59,626,670,242,801,614,832,71,60,298,597,100,243,947,271,480,443,665,679,762,301,465,865,420,438,884,381,283,356,952,162,43,168,671,206,481,243,200,256,963,487,821,475,342,209,437,154,25,58,191,39,458,499,859,713,427,504,179,560,342,972,859,387,414,300,576,634,366,212,288,491,963,69,130,535,732,107,403,886,995,37,912,868,216,365,157,564,205,293,936,741,670,575,443,41,583,271,118,826,169,533,140,760,15,844,431,204,488,164,247,721,905,819,111,195,359,908,958,275,0,205,540,920,552,803,163,669,332,727,4,986,103,277,520,294,219,280,184,20,766,587,655,218,301,266,163,478,434,21,597,740,885,388,83,203,369,344,513,11,904,10,275,449,793,171,277,980,764,36,434,70,934,539,945,842,665,770,745,9,772,221,664,389,331,211,110,845,714,563,764,261,662,746,88,379,34,866,516,153,417,979,660,339,194,449,446,897,396,515,543,406,423,701,919,245,589,672,61,530,964,691,112,784,658,216,460,7,298,760,89,475,263,158,832,115,526,901,113,55,159,958,469,134,486,208,202,604,206,617,663,512,252,977,297,149,937,544,839,521,376,7,631,738,60,534,64,544,992,677,538,569,971,817,4,156,739,57,349,941,764,320,296,321,683,794,535,424,958,490,68,723,905,92,628,321,197,720,879,609,276,82,396,609,550,538,482,269,659,152,78,478,488,195,116,837,101,745,232,618,548,898,988,16,234,10,603,43,693,127,361,649,64,213,544,923,591,598,439,97,992,538,479,494,129,164,985,575,395,792,58,709,446,512,655,956,247,344,178,291,74,501,794,398,705,835,736,253,956,775,264,38", "472,973,160,916,50,691,487,473,761,288,662,424,364,259,614,635,714,637,555,265,608,954,745,583,496,744,599,879,566,531,952,119,895,378,551,896,411,974,972,768,603,427,607,756,846,14,807,759,455,191,557,380,683,172,562,972,708,863,701,271,350,63,69,102,720,715,555,287,796,478,590,953,314,567,792,881,26,576,666,209,229,797,353,165,127,31,903,972,68,192,908,418,109,531,599,928,988,873,265,826,198,513,725,202,59,980,555,342,337,587,798,736,388,868,406,780,183,714,999,839,888,589,829,508,377,812,270,929,216,584,43,550,865,878,209,517,402,558,397,894,305,894,549,151,382,713,310,518,615,804,680,728,508,583,926,958,64,250,271,620,862,794,26,268,856,547,170,262,636,383,721,401,651,385,252,498,928,47,633,682,967,779,893,271,594,207,326,597,264,188,385,680,346,73,433,351,677,371,744,996,453,667,136,916,41,211,847,728,571,675,192,27,684,243,17,544,544,363,855,705,318,949,257,777,337,642,839,502,855,256,472,58,117,607,470,314,511,161,470,218,406,639,716,947,668,76,595,503,152,256,314,723,673,897,117,587,512,317,554,943,954,1,672,860,682,809,358,537,205,194,377,90,679,525,170,449,780,290,814,154,240,30,703,662,287,863,56,463,624,201,164,524,928,42,99,288,445,255,14,565,466,868,47,270,67,232,868,989,670,291,805,626,385,679,192,171,957,117,778,149,743,286,321,652,503,323,662,16,360,611,794,647,946,539,613,883,482,39,161,242,258,75,58,985,668,587,105,948,650,644,731,7,82,106,970,293,338,657,115,904,855,146,548,476,221,143,382,747,828,221,63,263,28,336,201,512,409,658,26,540,262,220,976,818,605,29,993,72,713,418,299,64,560,720,629,316,491,112,596,386,36,830,896,833,789,323,513,213,991,623,710,893,32,146,673,710,910,963,485,648,391,234,834,28,927,986,383,420,451,755,448,213,470,420,957,81,840,325,687,269,60,787,505,204,508,391,727,522,679,528,574,117,682,696,635,12,358,313,893,927,792,979,508,79,174,287,231,58,378,957,574,50,686,718,846,193,5,434,249,272,62,166,343,38,574,512,753,83,98,457,251,41,382,199,774,920,272,273,319,135,623,154,278,472,440,636,935,463,466,198,800,755,261,241,582,992,938,667,417,802,259,268,151,511,127,368,946,477,151,956,894,973,462,525,485,756,216,559,963,992,693,19,607,172,614,27,625,567,7,965,699,45,16,648,800,850,498,580,337,865,978,777,213,536,30,791,114,527,111,865,955,272,499,866,146,210,641,816,948,456,68,659,211,411,635,967,796,260,345,471,70,503,868,548,902,270,920,87,92,805,402,469,772,676,582,443,473,641,712,125,455,156,950,115,889,686,11,124,756,569,387,669,180,636,299,680,93,48,85,114,928,328,965,158,831,669,555,401,979,687,863,950,889,87,190,432,814,150,167,807,148,207,12,482,474,348,963,16,970,916,985,38,555,742,891,550,94,358,982,614,614,155,151,636,234,330,913,907,359,103,594,266,262,343,906,298,157,804,181,809,782,379,102,549,415,187,841,239,172,118,897,549,520,943,383,315,41,616,12,728,698,91,527,154,682,834,383,537,511,881,939,397,612,478,275,849,852,91,351,374,374,610,784,830,442,66,359,183,382,419,430,140,155,215,226,540,71,860,205,0,497,718,909,24,506,662,662,536,471,421,482,309,343,131,992,815,217,553,957,926,924,430,540,418,655,996,11,343,2,268,93,228,116,2,606,836,185,7,966,677,145,892,70,528,637,663,985,643,649,463,984,799,759,94,550,253,247,653,19,712,469,271,377,285,512,239,372,96,928,105,105,126,844,219,391,391,385,860,894,886,430,314,464,616,717,581,728,510,520,965,634,372,144,797,852,754,850,784,552,612,894,971,263,905,97,155,33,863,891,745,318,629,711,324,317,642,985,479,49,249,721,794,28,339,18,88,789,972,279,704,557,940,446,123,519,541,103,510,101,980,769,455,820,603,275,895,135,876,569,531,670,69,813,625,714,735,75,461,579,736,162,524,884,518,246,726,805,491,869,94,819,452,527,917,464,38,67,994,553,976,416,134,283,346,829,154,658,529,747,95,507,299,21,411,366,791,649,741,856,639,76,649,517,429,680,302,536,101,983,115,636,266,249,30,944,617,170,998,95,10,895,355,376,850,527,6,726,575,728,394,356,365,182,127,185,540,880,79,700,598,230,953,410,101,389,83,204,347,133,462", "530,117,868,47,485,712,708,946,392,775,818,309,625,598,348,906,940,251,354,785,772,167,49,692,257,570,115,908,172,2,591,397,63,411,387,128,351,130,399,610,746,830,48,876,420,258,317,283,962,463,451,377,238,933,522,844,600,505,271,197,552,856,552,790,579,395,976,446,338,482,862,411,259,399,332,727,351,615,67,585,743,843,607,895,467,790,32,327,788,351,149,534,487,324,859,573,649,433,335,579,979,979,906,140,684,738,129,309,531,193,948,255,153,472,836,84,840,504,421,324,331,342,275,170,809,817,716,597,541,94,316,833,775,476,161,506,578,675,675,168,522,736,251,562,203,463,872,339,375,178,540,745,462,90,226,806,241,582,991,978,547,851,959,491,943,474,150,451,999,646,448,558,102,279,323,131,547,179,898,681,534,246,291,221,848,675,689,570,182,150,764,621,901,485,550,561,993,190,453,306,636,217,264,289,518,226,38,286,248,387,85,346,758,577,730,724,664,211,101,770,63,612,361,649,864,412,10,251,385,955,717,208,923,290,737,607,635,983,149,544,352,265,508,794,354,879,669,849,985,568,621,743,12,62,107,34,525,654,619,974,521,960,233,297,262,22,507,170,979,573,757,189,51,909,480,871,756,281,202,889,413,812,372,241,158,519,65,467,783,308,41,111,679,484,87,790,239,82,357,727,722,764,200,551,665,625,602,122,602,80,136,44,502,84,608,113,220,623,834,818,371,166,174,556,40,143,289,738,11,814,275,40,767,173,970,819,871,742,729,544,150,300,988,800,240,141,93,228,380,722,472,202,548,887,949,338,337,135,151,372,468,712,463,342,510,875,266,57,130,200,461,748,129,603,884,26,251,27,489,807,204,744,722,64,692,266,197,732,437,566,814,894,863,715,443,196,551,234,954,55,751,246,113,398,442,616,553,554,871,39,799,360,73,492,396,637,835,178,980,231,779,304,670,877,663,554,881,239,130,556,821,388,565,13,783,541,15,198,417,579,360,906,645,96,166,26,990,328,137,140,499,462,581,511,947,32,815,939,280,375,754,17,258,324,286,785,128,426,824,200,189,557,572,102,336,565,900,32,450,8,123,419,656,659,147,960,33,862,911,912,16,902,767,800,165,861,632,950,397,735,435,636,197,503,820,425,461,675,635,809,510,64,524,774,78,595,167,903,154,20,773,484,718,273,389,992,399,800,667,400,117,392,53,667,971,979,242,216,846,984,815,493,598,3,135,720,984,743,106,623,631,16,261,139,670,565,931,714,959,123,266,636,496,846,736,874,175,33,842,876,986,349,278,932,404,910,129,829,416,663,28,648,762,595,763,527,379,398,1000,99,831,765,463,192,709,418,567,944,866,937,225,515,564,952,618,720,871,222,230,911,583,905,645,904,161,583,304,51,303,569,247,374,861,308,416,231,20,196,75,865,370,810,635,512,567,244,694,378,841,406,348,304,760,14,752,957,937,629,68,601,523,780,534,283,75,156,409,119,76,791,279,810,366,455,253,993,561,722,989,935,825,324,828,607,983,197,696,592,482,56,160,956,203,161,736,810,225,56,424,883,546,730,102,454,899,619,653,410,410,676,570,8,726,549,768,892,345,656,890,17,499,496,406,329,322,323,200,349,759,16,89,801,966,648,911,802,409,869,388,310,875,718,778,792,892,812,242,3,973,991,909,949,543,790,207,536,17,309,540,497,0,126,482,448,328,401,497,926,793,371,492,317,239,428,853,573,596,322,842,395,112,130,617,515,136,818,49,461,874,280,607,287,483,288,910,830,184,981,722,777,786,604,497,411,690,533,102,31,143,783,73,679,550,751,207,642,734,984,390,811,117,835,55,399,458,547,757,970,53,273,14,186,426,985,67,84,858,304,679,712,666,1,780,875,14,881,724,770,48,402,967,117,500,62,713,368,700,515,399,23,840,128,833,654,225,304,387,295,223,48,435,363,424,964,952,108,732,5,902,652,690,706,247,254,518,17,363,604,363,862,476,137,519,318,472,71,556,688,24,298,154,740,31,436,197,953,649,711,330,103,159,162,897,39,360,914,788,757,596,597,972,354,990,208,478,573,849,6,583,373,190,945,434,388,678,732,597,930,195,449,387,217,356,184,582,173,649,939,562,642,68,213,393,946,220,571,141,575,6,710,272,407,808,316,172,450,517,152,363,104,938,472,125,679,742,907,329,246,417,735,900,150,841,281,349,8,192,933,680,51,154,738,485,370,728,762,131,160,884,391,13,69,664,707,879,991,328,720,591,849", "589,290,124,52,393,446,677,765,96,52,814,3,568,775,7,910,659,734,631,678,522,63,787,171,638,299,341,773,873,992,989,490,833,765,221,287,575,257,643,228,269,883,557,508,77,50,4,993,738,485,218,638,756,59,431,532,75,104,66,777,944,47,857,472,52,569,419,604,538,135,69,753,734,128,822,530,590,680,95,207,699,725,216,240,280,672,747,126,766,950,204,131,620,345,473,501,338,19,515,181,351,845,130,648,687,742,358,973,100,595,976,380,180,363,739,126,575,617,179,784,839,585,395,960,270,798,294,86,95,639,859,981,535,844,945,686,546,209,371,480,546,81,815,165,866,641,477,448,234,345,203,187,717,643,867,382,82,876,171,686,900,873,911,897,720,770,553,742,825,569,274,374,501,316,885,737,812,722,451,71,571,594,577,655,154,309,298,868,455,180,777,167,602,748,161,754,842,934,42,331,348,500,474,754,364,217,335,843,372,966,54,284,456,372,348,334,114,156,821,406,526,597,432,692,175,798,165,918,870,977,833,176,948,861,831,103,651,569,370,527,288,2,989,762,467,196,808,83,791,884,644,300,8,400,820,705,149,724,999,691,199,443,458,697,928,977,811,823,356,832,208,898,209,909,36,660,912,746,727,702,88,876,86,245,451,450,503,705,93,886,564,990,171,728,39,838,347,969,733,462,976,345,978,152,764,102,84,231,961,942,530,728,620,625,853,539,714,488,760,741,869,644,857,685,159,1,531,419,236,7,793,830,136,185,270,698,809,31,533,187,150,295,643,888,169,605,144,115,56,12,662,801,322,97,413,793,14,341,899,63,696,526,749,153,780,462,833,244,753,533,134,162,216,698,145,264,601,882,25,389,976,583,232,237,111,810,139,783,755,245,278,86,178,673,498,528,298,41,387,951,792,721,17,213,408,455,757,532,442,206,750,473,367,525,485,315,786,695,755,457,849,903,305,482,221,772,91,56,934,740,659,550,42,279,705,374,226,441,655,581,893,102,640,959,125,301,888,934,711,521,167,78,447,964,884,903,380,390,452,635,404,578,88,976,613,412,296,549,602,925,619,489,152,431,660,882,840,137,987,220,411,768,980,555,835,953,420,852,286,366,686,506,699,980,381,963,995,408,239,567,213,529,531,841,201,6,35,642,342,603,699,65,375,572,149,167,136,619,402,500,195,920,570,630,499,549,805,422,862,792,714,832,614,211,710,393,736,769,444,6,312,999,819,967,674,538,403,127,49,911,23,927,213,796,841,666,916,324,947,972,636,811,140,541,649,481,795,594,306,694,466,825,324,83,236,779,503,12,982,222,170,955,704,522,194,786,22,361,792,414,975,942,693,699,742,241,207,882,885,685,857,616,679,272,815,306,595,735,796,940,323,350,586,245,171,62,931,236,870,614,560,79,480,731,143,770,824,258,973,744,267,216,744,700,902,234,317,728,39,770,162,130,498,793,32,801,801,195,670,82,519,846,88,975,516,941,238,504,203,681,381,715,537,49,416,12,74,483,961,393,536,273,653,580,121,384,80,10,891,221,559,873,689,134,549,473,460,460,959,858,590,843,557,973,442,46,828,160,802,990,338,215,241,376,250,906,530,799,751,49,329,729,732,236,52,684,53,315,706,142,567,724,561,134,104,277,862,189,42,702,558,604,761,30,898,867,383,350,400,212,683,879,363,463,214,483,838,694,920,718,126,0,103,517,164,891,156,903,120,877,289,238,757,88,112,221,375,142,62,863,984,120,910,714,836,904,970,243,849,532,830,265,703,425,416,902,129,153,904,310,84,551,882,79,810,214,479,710,371,833,220,194,924,347,225,311,786,652,196,517,594,500,83,79,185,22,433,939,744,689,825,185,599,86,61,892,652,151,551,503,591,312,278,351,295,757,125,993,377,420,785,443,338,120,787,402,340,498,178,728,314,451,901,772,842,156,322,829,363,167,256,751,216,979,118,564,50,378,882,198,686,884,495,425,31,246,984,432,948,959,566,722,40,878,854,485,536,173,686,738,332,349,744,405,413,101,362,30,113,746,483,301,391,740,767,683,512,831,300,204,524,449,100,131,274,721,660,397,261,905,887,699,831,614,737,680,237,10,941,446,307,817,512,601,315,31,203,808,394,578,209,240,34,751,160,602,417,975,783,988,421,868,603,513,195,641,93,257,772,869,642,503,336,156,103,592,519,534,813,953,197,251,51,829,880,221,496,922,503,388,900,262,881,209,88,753,346,17,868,834,737,975,830,593,168,363,107,781,711,383", "959,548,267,69,960,837,428,598,468,170,156,330,575,991,772,521,217,798,217,158,506,3,363,139,328,529,786,30,591,289,148,514,438,862,331,16,388,598,112,932,723,10,520,980,68,909,27,56,768,814,721,647,135,777,839,658,160,268,555,223,464,902,580,123,910,763,29,392,800,498,419,473,327,932,263,727,733,798,716,229,940,900,252,119,610,183,16,541,442,374,408,919,898,750,457,617,808,829,749,654,607,478,485,989,760,974,869,981,12,494,198,464,141,415,446,799,774,995,870,576,185,636,562,677,503,290,73,449,575,354,520,444,323,771,926,747,92,413,621,55,910,911,103,919,851,266,991,197,105,376,803,84,686,680,284,467,746,883,475,769,125,909,676,991,294,570,187,928,320,340,727,777,745,510,437,791,865,384,43,703,198,493,154,321,803,437,800,921,423,199,70,480,286,865,671,421,438,786,325,240,278,986,106,257,464,982,437,374,613,627,76,544,498,977,570,957,666,311,568,96,909,765,791,501,88,140,956,231,766,146,325,159,164,796,719,787,192,751,560,933,938,10,327,962,741,637,988,400,614,119,136,255,280,720,368,8,201,106,795,835,445,572,344,31,838,120,475,538,900,565,888,975,639,476,286,388,996,506,475,711,708,23,379,730,762,880,192,79,512,898,197,21,970,105,604,728,850,901,189,881,461,490,809,179,504,470,762,996,81,831,185,151,449,103,700,57,87,449,523,324,767,696,413,870,15,338,233,306,478,534,616,328,823,649,379,380,882,838,298,483,375,436,61,189,843,301,803,768,132,738,60,44,882,338,269,427,971,559,639,770,13,119,455,214,792,626,632,973,443,252,823,599,546,26,698,785,913,167,313,243,915,361,14,613,222,607,445,493,363,971,923,401,580,25,273,359,6,561,345,893,81,44,210,180,1,835,471,184,770,550,310,332,122,811,467,533,531,902,501,717,687,147,485,812,761,119,817,787,358,327,111,755,932,689,440,588,180,471,507,747,829,595,374,188,23,781,391,411,813,690,480,48,510,488,541,734,45,510,705,595,823,894,474,584,633,359,432,375,454,797,255,57,84,344,805,279,542,415,503,927,404,920,919,128,878,458,695,398,616,139,684,694,564,33,230,318,913,751,906,40,685,926,879,111,25,145,732,38,80,542,14,939,274,270,243,179,541,24,576,436,13,283,640,974,452,146,136,916,329,718,116,957,380,263,874,602,302,403,85,345,943,482,394,221,795,443,955,562,764,467,99,816,719,104,756,774,38,158,232,75,642,731,783,237,565,859,29,534,347,973,801,554,241,711,460,757,440,677,385,984,829,210,261,421,839,678,45,458,118,475,812,111,996,8,834,189,359,849,122,522,609,831,771,440,720,620,675,642,815,691,7,860,896,751,872,1,753,624,768,760,114,993,93,293,346,801,846,27,703,727,262,265,835,296,783,883,515,161,90,906,877,616,127,424,35,10,203,702,160,953,714,617,508,163,746,390,528,822,109,468,853,552,384,290,998,409,676,666,658,97,682,789,766,345,292,292,546,888,615,280,444,798,374,873,70,757,755,10,456,232,259,891,503,141,619,836,874,940,662,789,752,187,979,445,318,616,714,845,978,305,599,513,441,734,226,104,367,325,179,538,409,64,220,686,898,24,545,56,664,855,815,247,688,403,870,522,867,168,570,875,645,388,712,479,960,667,122,179,552,909,482,103,0,958,873,179,859,500,301,252,290,223,893,18,878,156,519,478,629,152,653,546,452,394,130,678,938,177,280,722,700,120,938,912,978,421,471,597,80,505,390,734,322,377,952,165,289,912,719,524,894,436,801,667,948,444,309,377,767,705,533,522,76,82,777,151,970,870,846,446,963,37,411,741,305,42,442,533,497,176,22,82,660,13,52,529,714,719,658,869,691,827,752,873,850,921,469,800,490,726,639,808,956,977,857,455,445,136,87,446,369,859,387,396,846,91,7,456,104,128,824,41,544,699,743,518,836,737,124,603,168,458,898,848,522,408,373,811,774,66,545,189,717,619,640,329,690,556,220,791,555,113,291,630,664,943,208,743,540,791,468,827,492,160,37,549,336,838,605,697,465,74,349,559,801,983,148,337,780,701,216,462,8,677,457,353,94,403,16,95,188,269,803,273,396,752,794,689,494,383,973,424,728,969,374,272,228,222,489,702,268,275,637,122,267,662,917,810,623,981,915,912,699,741,827,144,961,211,172,142,842,132,415,881,762,2,398,475,99,698,130,122,981,814,45,577,394,745,750,193", "213,202,460,164,972,726,159,555,305,422,923,828,473,797,229,365,923,929,888,509,359,572,18,110,461,989,990,268,407,246,955,535,985,474,559,233,232,807,709,762,697,138,54,765,430,486,837,152,149,143,873,958,67,169,462,670,952,793,322,749,8,70,894,516,918,148,397,834,834,491,339,297,353,761,535,692,984,26,936,807,700,266,330,328,797,357,738,722,875,982,652,915,46,25,140,347,794,206,302,611,307,102,556,761,950,14,976,219,962,626,945,328,284,554,896,421,250,581,740,673,698,610,809,314,807,400,104,455,113,161,150,92,67,973,826,533,112,378,455,435,23,534,105,996,477,33,852,676,542,901,860,977,37,659,547,969,353,289,990,767,972,884,108,554,166,106,344,487,253,358,698,10,201,818,714,622,930,227,901,182,864,628,520,156,579,943,832,257,530,904,187,157,723,440,466,798,352,365,514,672,617,433,364,531,552,330,109,328,327,654,642,579,579,624,395,170,711,686,158,198,148,307,499,502,354,838,762,693,695,548,91,636,945,871,665,932,720,97,918,123,196,233,153,159,765,251,246,900,202,974,929,356,608,591,864,966,908,882,223,982,542,420,340,219,922,943,941,964,353,728,461,6,908,977,96,823,363,774,325,353,635,286,739,586,408,257,162,706,268,87,724,815,981,361,532,967,972,792,699,284,488,100,2,830,699,43,532,145,663,845,844,675,695,584,506,550,800,800,982,265,948,22,746,460,858,681,894,653,81,854,668,194,748,54,352,499,43,786,648,149,268,162,719,654,272,906,63,780,431,32,386,102,472,10,86,628,12,653,436,683,290,960,71,830,737,757,173,144,681,41,286,173,315,713,778,958,738,51,592,271,932,328,977,493,730,217,22,423,442,663,401,469,482,779,299,701,189,424,860,605,675,194,435,866,93,803,138,524,428,389,874,838,381,128,80,82,303,375,388,227,191,612,524,498,989,134,548,206,734,503,82,857,443,158,207,571,642,527,198,176,124,417,545,508,603,64,428,789,71,106,58,729,545,608,100,789,460,443,866,517,75,720,87,494,496,294,679,711,569,606,669,960,7,110,797,510,721,98,82,454,850,535,292,386,945,236,917,205,696,662,372,656,310,860,149,990,542,286,869,823,499,177,635,134,756,777,625,62,842,397,607,458,43,83,232,601,743,344,872,47,89,441,85,61,527,819,765,90,226,886,312,136,48,222,381,815,508,925,582,192,777,685,500,247,523,18,95,966,417,286,522,794,681,187,437,703,871,333,209,756,304,823,218,756,928,372,396,269,327,118,751,958,675,431,156,910,398,614,313,762,349,972,455,811,397,339,307,60,170,977,812,861,319,391,208,899,791,599,883,9,153,103,374,568,686,358,317,68,557,972,259,991,431,64,437,671,96,757,28,937,645,240,398,337,265,396,651,544,785,80,869,432,521,426,849,853,799,59,14,510,292,373,453,199,553,839,35,446,708,36,8,327,984,636,1,21,471,659,275,402,284,935,437,801,437,746,594,604,350,159,101,829,883,237,266,227,685,261,319,890,578,309,909,806,776,42,668,961,684,496,888,707,658,627,694,834,828,969,647,313,371,14,24,394,992,982,219,534,834,924,587,678,84,942,219,450,904,167,822,102,361,380,939,574,581,856,788,114,261,698,4,323,126,893,213,621,699,532,80,405,250,870,228,854,735,918,395,608,803,24,448,517,958,0,923,454,292,728,667,713,222,38,798,451,457,780,272,543,487,831,77,178,619,521,142,710,465,899,833,379,783,925,923,287,72,338,569,724,388,653,257,959,457,397,975,155,66,944,661,28,73,352,686,942,316,127,476,213,433,586,232,408,182,437,479,579,497,911,659,833,659,90,515,100,204,324,46,457,135,267,251,725,634,356,5,66,984,820,883,300,374,729,893,246,945,16,887,164,584,784,599,289,999,34,616,133,676,109,144,285,733,100,638,676,133,739,173,95,189,137,343,320,447,12,21,63,597,71,257,298,488,791,238,858,379,847,998,558,7,34,812,536,340,769,167,360,405,3,633,570,366,725,164,422,263,154,487,850,946,787,271,597,870,650,131,87,855,766,491,22,238,855,149,480,946,109,783,412,430,373,510,105,270,519,765,57,28,118,648,24,275,353,474,347,473,569,857,903,955,651,95,893,738,658,25,532,602,547,166,899,473,958,797,859,202,245,829,102,37,466,80,142,733,665,431,623,753,381,457,770,123,535,368,864,35,553,626,358,955,644,566,568,266,723,382,51,700,929,683,902", "74,264,928,479,970,790,468,503,384,830,657,434,671,321,78,356,877,729,303,186,954,222,526,574,681,449,884,855,814,230,36,556,321,606,466,858,60,857,204,727,278,779,85,382,280,560,437,937,131,628,646,134,655,689,389,443,748,819,861,672,280,671,132,174,58,621,591,768,830,665,67,316,424,556,491,914,221,673,530,522,281,908,892,125,306,782,684,724,77,232,61,866,707,500,233,897,621,669,950,485,687,196,629,319,80,514,450,824,829,147,750,662,71,860,414,100,581,76,256,398,138,602,497,155,332,920,631,274,309,657,838,846,631,276,433,296,605,196,582,419,295,221,97,883,740,405,735,917,530,254,623,239,38,987,115,564,165,446,116,65,835,818,621,484,450,407,775,71,482,528,297,483,35,987,644,680,176,355,379,82,169,306,990,814,708,727,718,103,450,419,711,389,926,679,380,345,347,882,41,754,985,338,276,595,881,182,138,981,564,262,261,247,200,587,112,588,972,947,831,805,452,634,347,902,533,766,808,248,100,439,463,366,132,736,3,422,494,721,393,972,692,97,877,110,3,47,858,885,147,60,844,983,381,489,730,413,235,936,14,509,569,528,195,53,376,669,726,797,930,85,55,852,637,176,720,552,650,974,433,578,830,442,503,22,537,177,817,735,253,728,446,737,748,178,244,560,328,513,974,412,961,262,296,956,940,334,533,290,243,66,287,867,811,138,51,45,305,802,153,430,627,464,253,801,978,546,456,894,448,830,434,154,481,505,10,714,603,636,123,269,541,542,833,736,177,580,482,796,460,824,86,194,661,435,824,902,303,537,474,182,988,353,563,871,704,826,266,616,968,934,491,399,483,787,128,604,523,275,692,911,304,928,919,163,975,878,586,440,933,836,884,559,823,272,919,897,710,70,233,808,628,414,163,51,595,465,420,376,437,652,652,512,687,359,696,434,271,112,270,310,370,684,760,753,116,13,967,135,358,443,566,391,752,778,453,632,515,222,574,992,524,978,71,731,752,401,103,986,9,374,107,2,307,410,60,844,746,82,496,508,824,398,527,999,662,632,918,61,800,160,397,793,843,17,187,352,508,453,495,4,807,421,344,558,814,172,641,149,209,334,898,116,755,848,782,62,744,205,138,752,284,967,771,446,714,816,372,650,610,225,375,681,764,449,852,203,216,341,902,935,229,703,728,493,474,254,468,155,318,162,746,645,140,588,806,510,777,780,563,717,509,464,34,993,358,35,434,540,926,735,587,412,337,150,555,408,193,620,7,310,214,398,581,587,377,874,671,519,476,892,776,602,200,452,392,715,303,333,909,680,312,934,327,611,669,488,73,166,862,468,216,842,497,379,234,82,899,438,655,687,739,138,600,940,202,976,438,889,261,945,619,39,933,428,252,579,267,780,405,51,36,834,681,949,251,977,657,505,475,375,869,48,825,135,344,46,363,94,665,713,454,199,483,769,209,55,257,616,421,236,795,88,65,660,828,745,840,647,223,855,571,280,551,751,526,476,264,312,273,157,260,44,734,661,624,498,885,694,498,212,718,515,257,585,839,760,565,315,850,653,461,587,553,389,550,246,526,421,568,438,72,963,110,740,907,737,195,3,457,705,957,558,265,338,767,11,201,120,533,90,802,1,419,564,861,742,128,906,522,711,39,304,298,711,763,155,259,122,122,798,888,390,41,722,198,797,522,355,163,506,328,164,873,923,0,118,136,898,567,180,749,866,101,363,534,679,950,286,324,776,11,550,881,344,355,766,27,943,785,900,627,590,366,446,933,242,392,714,326,43,937,250,284,464,62,297,663,833,333,884,152,681,774,516,734,531,546,330,114,342,592,287,9,841,699,373,612,121,139,405,704,1000,815,187,900,482,537,899,128,224,239,616,371,231,52,985,552,363,809,342,936,331,834,468,307,609,593,812,142,125,226,122,921,336,423,495,446,479,981,97,348,659,408,640,75,380,862,240,555,16,379,342,622,33,631,91,309,444,421,400,494,273,208,854,115,260,435,965,162,711,136,981,332,121,983,968,915,361,104,55,772,793,991,836,72,190,250,774,950,889,256,43,571,814,622,365,159,634,170,866,290,682,727,530,8,956,108,581,92,768,941,184,638,514,798,136,201,944,196,959,551,29,601,992,479,354,628,667,79,285,737,224,62,521,19,554,25,843,563,781,447,34,222,179,479,869,837,833,87,929,513,525,931,981,932,208,228,784,408,235,464,600,202,181,375,317,693,947,682,816,673,502,182,353,602,181,157,950,756,599", "904,831,316,380,967,197,675,111,698,998,900,537,924,247,409,389,951,348,738,762,63,471,696,792,569,709,630,754,980,759,259,569,307,340,249,298,342,629,783,844,697,917,153,146,591,706,95,675,206,54,738,591,475,222,939,896,335,74,724,133,188,74,859,159,468,321,556,328,984,400,888,508,658,753,580,926,387,188,96,22,777,587,960,688,781,208,72,501,334,153,700,719,58,425,966,334,390,875,978,621,798,966,680,343,25,526,211,499,138,129,2,530,222,842,883,50,866,598,348,208,505,742,51,378,933,589,406,26,902,16,92,889,436,898,223,166,597,446,358,443,618,200,826,179,52,369,250,65,842,792,625,67,150,167,720,683,263,311,773,883,424,726,916,690,918,454,907,696,868,762,459,937,901,483,904,461,77,627,733,381,575,287,744,177,102,300,696,290,875,756,930,359,385,944,767,712,849,158,87,973,811,602,226,958,668,251,135,938,55,5,390,183,381,895,450,21,659,708,771,620,275,779,424,530,865,185,716,551,443,332,568,275,181,89,993,732,126,436,136,457,274,211,349,165,555,608,328,67,18,649,786,705,595,892,412,137,711,832,739,809,125,879,242,468,538,228,40,402,640,196,875,21,189,831,547,660,791,150,172,499,620,749,342,63,452,375,917,314,544,900,773,814,996,187,270,661,789,812,546,366,649,508,609,29,275,994,69,905,231,668,629,538,22,609,457,891,313,242,58,102,577,186,690,545,394,83,969,265,662,53,246,76,213,972,386,998,29,301,595,549,77,727,501,739,405,954,685,918,914,118,345,508,736,886,451,263,883,648,495,688,590,298,699,165,863,193,45,432,903,69,321,851,341,531,457,521,976,428,836,986,26,197,47,164,864,317,982,881,223,772,196,584,991,625,286,664,991,65,454,547,744,815,575,914,614,103,540,653,790,351,798,557,1000,667,955,42,84,125,466,281,209,486,349,907,162,831,868,513,247,385,38,925,939,588,459,295,7,380,527,49,820,162,927,285,217,869,385,921,488,457,704,23,376,29,344,668,515,115,154,575,183,386,136,435,79,926,408,469,944,72,884,714,336,669,708,89,601,999,823,233,681,524,339,97,233,558,912,156,669,785,110,742,34,944,898,173,973,100,15,568,558,312,748,916,633,609,752,438,330,23,810,72,607,533,902,781,838,856,206,833,203,730,800,997,99,789,549,468,976,276,889,411,961,638,756,106,323,89,492,62,807,88,875,205,807,21,114,255,651,275,501,271,148,852,9,637,189,81,413,923,549,841,607,560,832,494,621,477,325,484,322,591,679,639,650,337,411,497,105,498,817,207,50,785,744,370,120,878,412,243,349,959,873,605,324,207,994,544,150,949,589,138,431,555,670,455,688,506,555,352,331,261,388,522,877,534,138,420,210,560,626,355,692,274,636,874,522,162,875,233,848,1,932,965,114,678,722,963,702,108,698,43,566,29,673,684,80,519,345,543,730,895,29,146,75,207,887,130,804,986,557,187,134,330,395,76,635,916,917,679,839,362,915,156,934,510,198,794,561,493,44,354,590,357,97,819,276,167,343,94,129,245,896,795,799,604,19,502,164,279,831,77,345,178,881,963,665,431,716,986,388,175,571,882,216,705,298,465,222,537,360,215,365,38,506,458,138,171,273,593,343,682,119,762,495,757,388,765,267,613,721,103,626,315,264,579,237,193,669,662,401,891,179,454,118,0,684,412,100,163,777,819,815,268,580,114,617,49,838,241,919,458,526,369,35,831,114,625,152,516,518,871,237,45,3,147,639,724,823,21,519,324,519,737,530,944,179,259,351,889,573,558,365,806,999,419,895,120,442,680,793,911,322,380,208,914,440,989,434,275,616,531,116,715,287,489,369,76,784,193,27,111,595,468,595,489,269,263,773,258,614,15,126,811,349,796,699,675,568,423,962,816,376,817,62,593,894,839,224,429,256,14,695,121,351,789,55,555,580,204,734,385,105,991,352,82,494,812,100,870,324,918,100,668,125,358,490,736,579,665,52,383,697,68,141,208,539,275,874,253,974,928,5,312,38,329,709,99,611,430,540,875,16,498,630,477,867,352,929,289,381,471,876,729,272,98,681,983,320,623,861,252,937,626,668,837,980,682,532,660,477,962,415,919,237,241,404,21,773,486,784,436,798,709,218,833,230,784,238,784,70,670,438,267,779,328,470,423,837,786,413,317,182,153,653,813,80,962,227,995,835,81,794,238,725,867,488,247,499,628,253,721,262,464,698,988,356,43,715,521", "270,235,325,496,711,263,927,45,777,692,533,392,279,332,538,748,248,231,935,565,216,468,896,100,49,245,896,596,469,98,831,826,491,256,280,532,818,835,833,285,114,441,345,249,108,254,446,46,616,801,205,165,150,643,700,208,116,21,10,411,59,546,495,317,575,323,415,72,223,5,201,354,635,669,992,448,412,602,140,129,514,502,898,691,87,643,520,948,347,199,713,154,388,360,422,23,949,216,983,308,463,634,630,178,468,490,702,410,735,607,469,893,384,865,44,515,541,562,556,425,125,240,82,189,764,213,68,399,995,933,37,377,221,658,937,923,373,474,48,156,898,922,347,18,317,979,84,572,640,227,295,71,860,724,298,687,306,970,960,656,775,965,312,922,15,260,475,75,216,575,613,21,804,60,853,744,494,544,812,958,142,281,495,356,133,229,581,245,31,260,55,240,877,375,422,722,497,525,143,350,283,73,793,171,868,494,104,244,851,734,762,208,147,396,728,105,377,754,948,398,313,373,671,807,653,369,878,398,547,717,6,772,259,403,709,913,394,649,109,141,850,89,362,413,284,815,252,71,698,999,240,94,556,187,483,293,273,941,543,262,172,816,376,446,694,63,501,573,370,499,147,79,652,745,562,29,624,797,161,610,338,215,455,836,510,512,35,456,664,72,637,732,68,36,410,506,856,726,142,310,539,463,508,758,677,710,816,827,668,792,254,792,32,648,468,85,637,453,524,243,977,548,992,369,655,418,778,143,400,211,168,584,689,136,865,149,781,78,651,86,969,617,238,619,110,599,780,618,13,355,973,230,100,643,672,52,414,667,975,895,599,426,219,23,632,979,916,704,151,565,722,467,995,234,996,273,936,134,604,277,956,226,442,449,766,497,678,1,62,707,485,248,83,270,633,76,494,214,561,866,657,377,470,228,482,683,62,993,956,827,51,331,506,256,661,722,616,402,119,434,570,619,199,956,93,56,549,359,541,714,876,776,470,112,886,649,471,804,192,477,384,834,936,671,842,627,914,413,617,226,574,918,797,422,909,3,101,739,597,942,37,16,658,752,927,542,509,147,854,595,502,777,973,728,469,986,521,996,509,157,452,231,618,298,750,407,299,718,505,235,64,47,965,863,644,355,881,571,559,335,821,912,571,270,251,23,271,165,183,920,443,108,215,527,961,810,190,215,765,136,163,96,801,390,836,194,240,237,838,518,71,438,80,312,922,64,575,178,196,951,424,654,985,830,616,641,136,926,284,681,854,824,283,91,60,242,956,518,245,266,90,181,594,582,125,450,380,35,603,411,164,197,180,974,896,910,848,687,12,764,179,607,923,975,651,440,243,379,277,90,242,582,835,309,351,546,567,303,810,191,473,771,393,888,159,119,353,446,204,638,996,170,383,922,336,401,939,179,203,648,44,844,830,983,418,496,675,780,114,520,395,605,121,723,856,615,200,863,475,910,529,576,441,512,635,109,519,511,272,772,967,665,452,609,501,366,436,665,124,850,615,526,390,299,637,438,84,155,903,319,537,237,628,691,201,963,437,523,747,646,457,442,219,782,394,437,312,557,214,458,374,746,525,713,799,376,157,195,106,679,520,568,628,658,639,211,179,458,468,132,730,406,36,373,273,56,28,845,163,833,928,979,477,769,339,818,838,893,888,554,182,132,984,648,18,269,576,522,436,665,638,234,563,110,236,375,904,588,332,662,497,156,859,292,136,684,0,248,460,208,768,804,772,171,554,226,694,748,996,504,774,380,121,364,269,925,629,40,552,742,37,277,696,320,584,313,442,943,736,637,379,646,246,225,442,608,511,409,297,882,404,708,131,482,567,14,766,692,15,480,76,146,738,728,468,26,502,814,432,236,904,216,190,254,688,736,415,412,330,569,596,592,566,407,170,105,345,202,339,185,446,194,737,173,121,756,242,37,660,727,540,993,141,864,356,952,315,546,830,839,783,656,536,177,67,340,192,115,95,155,201,55,580,290,260,537,876,21,826,566,429,563,571,399,195,436,514,46,198,778,645,406,699,15,152,716,732,449,647,404,479,527,929,387,574,68,602,334,925,759,816,469,290,757,66,218,889,552,579,857,376,377,529,91,651,322,3,430,728,907,929,779,467,543,944,231,741,404,915,71,301,481,375,129,961,582,586,229,754,627,15,776,720,946,697,934,337,801,901,714,606,93,497,94,191,571,926,404,711,265,224,605,382,346,334,264,643,705,143,682,574,27,786,242,139,596,918,73,537,914,58,799,89,3,588,780,291,148,143,597", "677,162,173,455,876,511,897,553,635,788,32,273,950,302,924,268,481,842,85,457,103,968,732,992,31,807,20,701,239,438,896,208,1000,907,759,824,362,118,297,731,57,412,170,968,46,906,811,966,729,735,343,629,389,220,136,353,716,772,831,151,182,869,418,366,85,49,810,567,978,204,771,894,824,958,470,178,37,977,634,781,470,451,2,450,604,350,204,352,372,118,13,101,69,889,82,910,629,926,743,352,988,725,143,26,614,854,323,313,915,939,549,164,632,763,124,90,442,141,815,477,895,100,278,394,513,11,196,785,124,899,805,507,121,107,23,516,216,295,745,980,267,181,773,962,247,157,730,531,128,517,230,124,768,357,873,417,360,745,744,133,279,191,947,457,661,23,185,567,410,903,142,58,405,322,655,704,798,105,325,329,645,497,699,762,858,320,530,60,142,330,231,853,122,868,361,111,171,697,917,271,994,969,600,557,403,124,917,576,450,420,52,554,919,737,703,906,88,36,56,911,275,286,860,573,155,750,73,448,920,818,159,716,230,926,76,986,150,338,49,663,824,317,755,356,109,643,711,309,55,380,164,758,666,50,840,998,720,142,674,372,472,157,199,245,10,405,189,415,174,831,738,703,544,405,454,803,641,721,248,577,552,536,981,769,770,450,915,905,329,205,153,479,100,727,83,879,737,845,771,440,822,438,542,575,379,821,13,676,753,239,572,624,152,244,57,528,968,352,565,953,523,759,355,209,955,502,625,65,332,964,429,224,959,631,136,169,334,354,957,250,595,678,364,878,832,995,792,5,379,95,927,558,549,847,473,259,367,140,771,320,391,365,565,986,338,222,805,758,867,573,546,932,973,482,788,493,243,590,339,863,414,550,687,883,199,335,77,843,102,619,17,939,870,484,589,283,63,450,485,530,643,155,168,323,892,295,830,802,114,686,477,743,767,895,143,817,586,876,872,489,338,829,532,89,634,767,411,334,774,793,252,975,293,31,950,635,140,276,222,833,476,28,466,671,882,958,225,210,997,27,617,762,601,808,972,271,953,583,8,83,143,374,178,612,53,464,328,241,718,941,6,561,114,248,729,51,227,971,408,355,672,357,737,756,156,478,175,509,705,706,561,250,976,512,611,460,706,903,675,964,620,344,814,929,935,797,138,923,597,549,370,144,62,291,574,416,738,613,615,183,914,983,943,749,643,215,528,890,61,770,424,57,404,581,647,188,984,663,387,158,65,127,92,885,397,567,385,360,396,779,224,10,408,297,63,449,80,420,900,784,812,205,157,414,974,622,795,315,705,204,421,181,678,114,625,64,904,655,799,834,182,364,858,158,347,399,890,732,49,927,160,137,472,454,813,633,905,274,795,1000,83,166,5,212,654,105,725,98,237,893,346,877,683,672,332,877,252,61,430,162,536,911,604,682,382,384,154,802,103,12,885,719,619,344,511,159,746,589,458,114,914,875,873,797,679,610,457,642,464,79,161,286,612,278,721,25,531,295,52,267,526,236,272,17,961,318,785,340,532,784,315,337,572,124,208,235,850,31,914,759,515,97,418,130,836,180,130,74,37,880,429,869,482,28,358,435,598,304,424,786,914,338,895,27,804,466,632,189,444,458,387,808,497,671,372,351,494,539,769,251,974,792,853,908,161,65,875,456,156,183,91,518,231,277,455,700,332,519,300,583,80,430,445,593,317,855,480,578,727,536,926,903,500,728,898,412,248,0,488,845,71,653,857,366,915,231,8,333,294,7,637,182,982,314,847,581,942,661,6,408,114,748,158,896,560,794,178,880,442,537,928,43,870,216,436,495,998,230,756,209,974,605,727,986,619,397,151,202,866,805,976,226,973,377,671,174,614,377,319,580,588,766,249,636,300,161,705,844,64,708,960,950,136,40,394,820,508,960,479,345,52,682,490,99,583,715,159,588,764,759,671,337,107,172,507,2,782,486,546,400,81,74,395,47,759,749,134,605,678,571,715,948,347,309,424,28,570,304,525,182,38,644,719,587,460,848,820,267,309,421,647,567,223,756,997,485,262,978,185,991,549,937,675,941,727,703,937,368,16,473,576,170,723,981,513,869,717,712,992,834,342,916,735,130,801,544,256,521,337,229,712,154,755,548,160,803,824,970,685,30,46,537,903,727,505,657,240,42,917,815,831,273,70,901,930,773,700,184,885,467,964,9,778,863,533,903,681,815,315,528,442,288,505,440,959,448,203,96,915,434,673,742,853,539,674,908,742,12,674,230,172,250,572,614,194,524,953,558,106,176", "787,683,52,615,786,936,216,782,548,113,46,789,482,927,89,585,978,926,377,961,460,719,6,431,828,665,201,557,10,59,981,741,369,767,843,88,742,972,564,449,353,809,350,936,76,653,86,590,533,307,975,420,540,35,664,6,93,14,305,682,308,891,189,596,806,783,514,480,512,186,152,368,161,132,423,453,162,75,178,336,430,473,748,811,553,198,863,26,156,983,984,124,779,479,129,539,124,201,375,862,273,433,578,659,156,682,853,106,970,211,729,402,480,506,476,979,159,340,971,285,171,61,104,946,926,384,779,303,891,426,314,842,563,394,647,438,588,795,789,786,812,156,425,447,518,592,890,88,553,358,223,246,382,122,230,145,60,225,731,796,344,266,924,784,118,252,963,259,423,180,317,223,776,376,308,791,564,977,982,11,744,696,319,114,737,809,137,843,234,278,204,445,322,180,204,67,512,760,329,350,208,954,885,526,69,563,982,267,479,462,240,51,822,91,718,373,235,517,903,2,684,840,354,18,510,312,333,948,259,303,904,73,652,24,566,907,854,120,621,394,264,634,605,270,436,177,875,425,304,167,387,470,539,105,720,61,418,112,419,922,785,15,613,146,433,507,866,610,286,182,988,543,938,529,164,268,450,769,925,38,799,770,276,144,750,518,135,573,169,330,627,342,339,865,911,564,827,456,747,361,543,853,608,57,349,674,842,592,758,97,753,270,535,837,544,768,997,949,41,208,295,653,209,212,154,327,873,705,358,754,589,973,148,65,710,510,206,601,233,141,744,306,468,681,702,289,946,726,487,782,617,718,559,980,393,970,514,723,561,38,389,861,101,324,470,584,270,896,594,921,509,135,101,806,983,971,785,814,531,4,622,810,267,136,959,778,847,423,769,802,489,896,313,531,791,927,356,377,64,54,393,25,726,135,141,183,808,772,246,163,987,676,970,621,320,106,207,472,842,198,438,472,783,50,530,22,269,967,39,820,80,383,936,369,756,23,134,98,947,372,364,995,573,809,329,252,857,332,789,850,196,131,680,880,194,493,55,804,655,975,728,617,490,447,508,143,823,642,779,75,384,983,687,167,59,589,776,431,183,249,620,467,745,324,295,785,178,527,422,214,668,471,764,545,255,81,183,629,391,457,852,62,254,325,805,914,378,112,554,100,492,785,760,330,320,972,840,555,50,892,645,318,812,448,747,430,104,745,864,471,333,603,595,175,309,907,85,274,619,363,276,737,962,975,677,218,542,541,822,345,367,644,389,767,860,28,945,680,283,561,985,810,439,204,103,602,134,203,477,962,44,46,277,357,69,204,133,829,213,577,766,374,332,127,316,903,665,419,6,602,14,417,354,506,746,961,864,78,378,785,242,84,77,934,648,228,747,627,982,374,604,422,305,605,884,453,368,264,477,811,447,771,701,38,24,551,542,804,100,967,665,141,202,859,174,309,620,83,934,277,77,797,535,281,459,907,59,297,320,185,875,619,213,291,534,121,937,648,692,977,379,45,351,165,340,373,733,687,736,267,282,152,799,666,227,41,604,623,688,558,364,833,695,108,521,974,575,951,896,862,218,564,432,727,315,207,517,74,459,144,180,925,754,992,360,60,423,777,851,116,532,576,39,81,355,461,931,592,508,283,528,519,215,951,230,311,327,229,409,815,463,542,95,479,602,151,597,190,128,722,838,755,362,836,946,560,773,898,4,471,793,120,301,667,567,100,460,488,0,836,651,694,84,72,350,358,847,342,10,201,418,742,40,883,486,530,494,530,371,418,589,290,265,862,356,20,946,737,685,976,618,913,62,927,428,816,127,544,347,28,479,152,998,420,230,698,293,84,393,892,518,480,301,798,650,939,98,101,598,937,643,671,315,666,124,71,678,20,190,687,252,830,668,748,112,807,25,420,604,281,938,66,729,506,691,689,587,194,57,99,930,209,529,335,605,312,322,455,486,439,627,963,531,721,9,616,442,768,119,361,734,701,577,418,197,425,189,390,985,547,850,738,554,210,581,571,418,803,954,916,254,685,551,82,715,728,892,427,88,634,478,374,901,734,141,727,388,191,796,981,622,577,799,259,583,226,778,729,569,362,600,25,636,58,386,909,768,887,240,656,357,563,742,37,299,199,304,288,885,462,394,332,3,303,501,670,51,867,463,759,962,945,458,931,934,230,386,163,276,222,732,15,154,193,154,868,525,839,834,77,365,945,527,166,267,704,838,845,379,401,229,946,965,341,913,127,94,781,428,772,98,132,131,92,601,768,154,481,647,112", "884,648,820,750,423,938,734,755,783,410,190,263,725,556,600,119,408,261,766,107,335,352,66,787,438,279,295,713,635,113,436,276,419,644,142,252,102,277,533,470,629,611,908,821,993,320,935,374,686,302,175,472,678,453,351,901,440,555,797,843,345,577,324,81,868,797,847,977,822,744,544,5,252,889,644,696,80,529,506,559,570,613,829,979,546,904,89,881,738,418,330,652,570,495,523,634,852,251,416,272,236,400,782,521,954,829,16,539,967,776,936,974,823,264,677,523,466,427,24,500,185,814,49,339,435,116,286,182,223,958,592,629,221,914,10,126,742,160,83,249,127,335,460,222,753,404,899,991,307,959,229,106,437,918,271,982,920,993,756,358,681,974,345,741,447,63,548,686,770,482,274,505,222,152,707,44,394,98,299,886,597,845,509,443,87,172,688,899,56,917,326,289,220,642,270,664,695,742,830,335,71,231,538,716,839,313,527,222,75,823,596,329,478,25,86,283,866,252,23,734,773,692,579,628,398,664,263,655,739,967,377,903,623,827,529,824,550,204,233,584,52,184,516,527,86,923,201,67,427,404,685,869,502,487,866,54,956,550,25,206,238,860,645,558,341,867,736,49,150,88,164,494,78,602,343,808,342,265,583,534,521,799,459,368,161,489,671,388,90,424,823,747,967,485,743,328,657,520,160,991,947,650,330,83,73,521,344,409,905,511,818,153,861,645,685,628,450,875,331,80,448,125,776,517,631,154,187,737,755,757,730,203,197,851,972,737,21,995,828,914,692,381,918,476,788,379,492,111,545,201,960,739,700,547,97,37,821,12,543,326,172,455,787,779,651,174,514,240,793,518,720,374,562,495,949,929,833,902,780,945,288,195,846,293,395,60,390,692,909,193,399,21,515,26,229,435,663,480,174,372,850,304,638,643,621,337,737,218,143,723,909,24,343,718,664,16,792,106,251,518,617,808,638,543,134,69,290,519,647,985,360,456,674,25,911,264,60,202,46,174,397,891,811,991,388,776,753,791,935,598,676,181,573,987,996,832,535,10,42,846,580,269,457,994,855,912,287,786,662,915,782,5,464,49,632,947,176,424,596,370,614,188,513,981,822,792,749,301,70,192,978,877,989,860,376,500,238,864,31,530,743,996,510,632,919,646,970,924,323,724,374,24,347,510,885,59,108,293,218,962,189,833,828,159,874,81,893,261,774,474,527,319,578,589,273,866,845,300,94,463,833,977,197,921,267,454,644,684,892,398,986,964,576,311,507,278,897,331,32,450,566,291,691,785,459,930,214,15,378,780,426,348,774,983,702,410,292,787,573,290,718,675,238,860,882,789,594,760,763,577,830,345,548,992,788,829,32,940,988,430,442,243,982,553,445,497,169,42,985,969,219,416,354,252,16,264,663,557,837,590,269,315,27,711,678,180,103,128,991,452,182,690,83,851,841,72,681,781,929,360,144,187,426,143,657,629,876,328,456,671,465,463,382,462,298,612,116,139,401,290,145,394,740,975,256,811,247,438,212,33,127,24,169,140,400,521,82,427,977,728,917,409,120,489,784,540,416,715,358,241,358,160,119,727,854,844,964,418,574,740,444,34,746,476,392,810,333,224,882,456,354,931,67,660,316,69,922,906,160,609,309,392,726,399,912,227,549,124,607,920,570,49,580,533,511,410,209,2,747,671,147,51,695,78,434,991,646,321,986,421,371,877,252,713,180,163,208,845,836,0,760,274,486,45,726,791,227,240,602,452,880,123,166,44,840,749,259,651,238,215,313,510,438,77,434,849,769,53,461,999,170,587,635,251,994,284,414,793,312,202,773,648,685,838,55,140,511,78,259,924,291,179,720,679,80,250,331,445,559,345,750,158,799,426,724,56,830,528,781,639,714,843,123,583,481,288,143,368,398,586,634,868,703,40,363,847,99,25,493,324,298,163,56,633,97,295,420,802,504,873,748,652,293,780,653,939,629,845,509,426,635,510,236,649,554,388,847,995,167,100,895,488,462,251,222,398,677,950,632,604,836,817,284,43,838,406,315,836,460,869,223,233,569,902,881,126,358,773,566,345,505,195,258,71,493,326,701,350,949,884,690,546,52,508,628,487,838,428,651,417,542,319,816,983,314,216,798,934,931,137,932,212,88,152,611,85,735,634,51,195,919,622,977,916,488,21,292,335,574,273,780,192,84,498,647,513,449,543,945,72,80,983,927,295,984,734,692,550,966,251,398,165,674,382,911,747,136,535,486,575,443,866,320,120,619,252,385,60,525,469", "287,530,394,957,412,427,162,233,382,24,617,151,747,960,101,907,276,440,114,822,784,895,194,528,395,830,655,952,339,778,858,790,280,760,504,142,387,654,37,578,273,601,304,657,272,758,125,247,323,808,904,355,180,106,164,503,546,365,550,675,675,508,356,855,199,442,915,642,71,497,381,15,173,758,889,455,833,168,795,973,822,730,30,391,78,750,878,739,903,69,557,746,318,76,343,580,983,205,338,258,383,651,148,824,31,513,840,257,177,347,963,59,152,504,959,519,515,582,949,565,7,472,796,245,845,395,228,703,426,349,734,569,415,944,113,343,42,304,8,278,505,427,651,479,87,790,305,597,778,243,742,219,170,253,181,219,720,513,79,729,48,327,720,127,746,897,653,220,551,573,416,719,156,977,894,193,461,789,692,764,936,442,31,417,365,726,311,325,206,97,417,430,302,550,312,640,427,199,731,724,999,444,783,147,353,834,386,265,436,552,202,602,967,510,341,723,342,654,796,219,177,608,179,994,851,847,9,153,394,499,262,199,805,479,210,80,475,263,334,659,130,771,488,903,439,466,78,144,508,701,439,791,786,860,728,756,39,609,32,792,928,286,924,348,531,404,22,412,248,779,868,767,418,85,374,288,297,409,613,467,901,262,100,392,605,339,474,173,476,856,57,292,621,96,490,366,104,657,421,565,223,915,472,237,859,774,245,977,406,742,391,102,211,802,780,234,784,708,696,963,2,408,741,20,407,778,950,403,834,883,989,590,606,595,842,972,817,860,47,64,705,888,334,345,910,833,952,415,893,802,30,451,447,735,97,794,312,162,515,870,138,968,328,297,736,423,295,152,275,820,235,28,967,47,315,795,222,453,288,733,123,316,472,431,193,241,614,916,379,703,996,351,937,997,55,393,599,574,211,460,628,559,651,629,959,642,467,346,976,272,679,667,733,548,360,105,571,845,380,314,17,676,534,750,252,363,707,371,604,210,196,123,151,132,389,696,956,479,447,589,130,672,589,607,410,802,915,309,935,939,129,369,238,657,34,948,19,951,405,459,605,419,497,585,553,694,142,479,181,754,151,128,880,652,913,885,800,974,777,688,899,212,22,655,451,124,974,150,477,965,338,733,350,51,258,412,468,148,267,395,620,652,761,105,820,328,842,218,196,235,854,555,598,327,265,480,418,370,285,224,734,76,946,216,605,273,932,430,17,212,895,485,13,242,36,857,947,999,216,516,792,664,592,496,65,749,59,116,586,125,820,963,349,237,389,369,321,917,757,603,388,583,79,66,971,328,128,66,679,810,55,776,904,148,526,166,907,82,374,447,684,794,837,514,19,75,27,113,102,671,406,21,114,829,165,65,527,147,40,718,27,912,233,18,512,702,603,781,859,500,547,129,659,231,70,774,468,580,625,562,415,833,436,769,373,475,960,534,851,174,574,876,387,390,740,87,661,655,492,124,7,906,160,49,70,205,204,414,282,658,803,822,686,187,315,730,622,296,733,517,911,988,473,725,652,406,224,287,897,12,128,557,722,479,66,544,266,432,716,358,273,197,38,788,577,830,140,751,715,660,367,810,670,956,900,991,729,197,896,350,249,193,966,456,420,246,921,400,400,348,614,240,611,658,292,522,299,110,348,197,964,693,604,840,398,388,583,12,666,106,549,856,828,920,520,398,640,665,96,951,371,10,2,342,563,599,399,253,103,482,492,289,290,222,749,777,768,71,651,760,0,873,225,831,755,896,919,403,631,230,749,10,929,382,845,931,75,71,663,278,555,424,297,677,19,926,463,889,621,657,735,557,294,503,892,449,696,392,169,743,273,912,67,458,54,155,865,9,926,759,42,375,746,160,947,278,912,509,591,978,97,606,730,413,408,479,396,873,624,446,690,830,147,779,780,946,805,26,823,101,447,261,91,502,310,352,55,316,815,895,622,221,460,337,748,721,163,278,337,275,313,808,880,38,750,232,341,885,881,229,914,871,882,249,401,680,79,165,671,199,680,812,202,521,513,968,512,674,178,547,301,818,19,780,683,690,73,840,527,849,821,827,319,585,427,352,196,404,83,800,566,377,570,452,526,717,901,195,635,116,687,503,54,459,579,35,789,266,62,939,673,71,736,284,846,362,860,378,499,893,137,670,494,632,579,878,287,919,294,547,171,490,357,93,282,940,676,736,535,131,338,795,234,155,535,852,502,862,820,567,257,91,737,669,39,313,775,266,132,486,546,484,4,245,457,228,688,16,237,489,367,258,868,364,316,995,397,598,778,267", "569,873,410,397,254,718,769,493,713,303,775,513,700,264,773,598,404,145,966,19,440,859,639,321,484,450,253,932,245,760,117,291,522,238,265,327,855,904,980,644,993,720,874,492,107,310,111,293,489,720,80,915,181,923,308,769,630,695,782,514,284,358,269,11,848,541,295,510,729,621,345,65,170,204,800,406,14,695,735,263,60,107,952,197,425,925,886,837,957,360,445,138,328,912,558,340,442,434,209,864,365,175,800,182,434,815,692,468,156,471,892,148,168,249,992,182,875,284,820,941,426,541,334,420,373,210,372,99,600,358,357,888,667,319,563,309,317,967,925,266,913,519,919,205,121,740,864,553,95,886,369,871,813,631,772,865,529,985,63,678,942,21,328,68,881,613,83,563,723,568,615,758,15,528,344,56,357,663,220,297,15,164,849,63,856,186,292,115,707,489,611,441,274,493,15,452,541,732,527,323,278,304,458,358,911,72,959,895,673,75,329,819,142,689,642,459,917,510,699,798,652,866,772,865,337,199,523,739,558,718,365,986,563,317,569,744,462,44,69,494,97,231,201,919,435,365,318,768,968,22,741,223,857,768,440,274,48,331,634,696,71,990,958,469,528,23,171,975,35,626,119,689,369,830,661,108,910,869,915,55,137,881,43,384,570,382,388,934,817,35,163,393,76,533,793,914,334,21,697,586,757,436,712,719,475,43,734,900,855,919,404,738,377,123,750,600,978,45,359,703,648,91,34,450,708,986,639,590,259,114,350,876,680,92,326,757,645,329,428,298,78,914,845,26,152,532,464,248,598,510,742,780,473,270,192,137,151,287,687,254,472,908,981,921,869,213,604,483,647,964,347,277,733,1000,439,624,394,239,807,282,114,738,895,821,197,679,118,575,688,97,772,917,836,80,553,404,348,294,110,584,568,570,777,960,117,48,822,257,670,94,617,475,751,537,806,523,262,219,299,92,663,445,766,502,217,916,843,84,357,79,954,394,517,435,57,949,108,636,768,360,340,195,276,827,161,763,624,626,533,453,781,535,705,356,373,146,695,513,969,191,54,311,895,439,990,50,836,662,460,894,663,36,242,250,501,4,848,655,572,381,716,208,867,848,861,58,275,384,992,82,592,169,701,226,366,602,538,367,270,497,404,621,453,985,39,855,237,817,447,140,27,169,532,540,51,45,221,943,174,917,379,856,636,569,722,324,631,224,976,648,168,186,980,686,874,990,895,507,637,385,897,374,932,341,249,79,385,432,619,989,554,118,45,429,9,201,549,512,425,94,967,284,446,950,575,761,498,963,857,649,841,440,388,953,198,488,733,673,891,763,487,256,536,180,359,421,749,751,412,864,144,681,610,4,183,474,219,245,92,820,461,140,574,147,468,219,488,114,428,66,771,464,819,332,743,596,637,451,889,782,864,869,533,600,576,72,274,711,714,150,963,416,169,630,724,687,137,929,959,756,382,218,306,426,147,881,715,318,675,488,657,199,535,809,385,835,572,210,66,28,850,458,550,406,160,533,22,545,65,25,344,24,926,769,647,542,27,674,301,111,197,956,169,223,991,776,308,149,888,164,973,143,375,457,282,185,441,272,588,867,6,330,287,259,348,226,406,555,260,491,536,817,261,995,128,925,937,503,555,810,693,15,317,343,988,644,61,904,449,44,459,752,455,946,634,889,434,533,263,12,171,972,714,485,889,268,180,119,277,309,317,238,223,38,866,819,804,653,694,274,873,0,829,940,849,655,856,157,43,931,324,106,653,924,970,869,375,178,832,227,182,470,671,510,871,160,641,900,373,513,7,492,981,39,641,19,689,482,934,370,830,662,302,427,313,388,479,513,240,203,342,894,428,467,374,164,363,456,86,782,554,172,45,308,108,13,577,272,994,871,578,271,429,833,201,584,991,77,538,588,69,235,575,70,131,210,616,831,701,330,898,394,210,729,62,186,587,243,196,263,633,181,320,941,77,513,515,858,273,946,462,64,113,341,263,653,316,359,196,563,853,932,242,546,519,158,465,438,883,310,607,120,61,664,664,437,858,43,530,872,866,369,910,330,256,871,938,124,775,913,896,411,644,555,727,151,490,754,182,962,297,85,943,943,167,748,950,70,735,216,742,739,286,682,302,389,365,986,22,612,953,787,655,936,109,747,959,797,93,536,567,589,658,294,15,857,361,59,551,949,784,999,269,371,585,683,812,166,678,672,150,373,790,820,787,808,24,532,113,167,577,819,630,686,342,626,797,152,292,312,251,457,602,855,428,393,977,517,574,460", "182,286,759,293,107,186,996,939,672,616,959,605,732,756,834,879,892,354,575,773,390,733,16,122,641,319,281,386,892,622,941,78,496,278,397,132,712,497,448,799,456,401,699,436,868,195,763,556,454,190,749,417,717,180,325,309,973,965,941,163,891,817,901,861,879,403,364,390,902,726,917,385,932,516,480,170,340,266,274,503,371,892,959,799,488,612,368,698,151,881,123,595,898,205,913,898,359,69,565,55,356,225,430,65,722,596,198,422,818,801,692,661,892,136,832,965,173,88,623,929,108,394,751,590,566,154,585,131,989,512,610,163,834,689,186,944,788,722,609,483,486,926,835,738,152,267,779,493,605,264,181,868,263,216,774,761,160,958,543,880,630,327,281,852,927,148,775,59,899,368,298,964,882,582,258,301,306,602,395,393,555,90,933,73,157,995,44,168,227,401,339,284,94,261,291,288,54,255,416,566,28,141,195,605,774,504,221,318,48,213,170,667,632,939,692,421,168,929,259,636,373,510,102,962,336,941,870,930,149,433,141,812,607,406,361,828,159,865,787,801,852,376,786,65,794,250,386,660,112,254,884,406,197,160,39,759,168,708,859,383,367,180,249,215,801,925,467,827,489,43,864,585,244,745,277,600,77,80,33,198,42,253,90,745,675,761,776,596,983,798,785,842,816,22,452,665,580,625,767,415,585,174,357,188,568,402,651,244,953,358,768,826,707,412,215,144,225,476,994,485,531,2,965,582,706,727,729,935,76,5,795,278,51,862,409,324,137,548,620,284,38,202,762,170,150,206,774,270,957,212,328,182,523,757,574,664,301,805,280,44,92,955,471,494,102,382,603,958,358,674,245,675,824,57,797,84,540,555,238,621,314,773,713,980,565,543,30,770,718,218,943,701,978,120,283,798,958,510,977,562,874,91,669,185,942,671,793,603,621,335,219,505,697,522,816,43,585,773,418,185,91,247,714,266,444,448,373,475,618,942,448,311,130,486,561,344,310,304,685,863,618,670,953,566,481,804,935,474,796,676,556,528,349,770,353,416,97,856,125,768,124,723,7,885,121,363,933,658,641,547,254,413,368,331,435,878,250,991,731,804,717,362,294,667,360,123,89,870,574,109,241,699,327,795,132,160,62,811,656,531,430,262,369,467,863,755,635,83,936,262,225,467,698,825,947,128,989,103,751,410,106,671,473,802,215,136,710,576,317,996,582,230,351,171,377,435,816,614,394,106,818,145,9,202,716,204,717,120,276,603,245,652,768,395,778,791,185,396,387,239,8,998,250,413,963,161,877,574,938,992,462,876,380,181,836,134,224,513,314,917,472,600,727,404,577,886,27,320,107,906,530,673,252,805,121,818,722,863,995,994,779,266,782,941,561,692,451,470,690,742,691,454,526,767,628,415,638,545,781,454,695,316,257,900,491,383,155,297,758,230,913,24,896,15,46,761,165,400,583,897,402,322,628,498,617,464,244,759,458,578,266,32,170,370,699,990,612,262,462,670,581,713,808,775,342,362,508,528,261,293,122,204,190,785,792,444,588,952,401,542,410,340,349,305,367,149,500,907,224,555,771,641,127,675,155,745,807,181,799,884,408,619,319,298,771,308,203,661,929,127,407,899,393,740,344,52,968,838,696,42,653,6,872,93,162,622,771,602,649,393,927,651,580,891,113,407,449,804,145,984,420,568,657,282,604,31,698,881,520,343,239,757,893,798,101,815,772,857,84,486,225,829,0,365,955,84,986,196,977,739,120,613,84,789,928,61,855,368,178,879,903,873,641,864,747,943,451,296,637,396,756,83,457,648,580,849,237,262,204,137,664,755,636,981,932,606,443,421,519,110,587,570,706,893,478,519,326,467,580,775,797,785,518,726,689,826,230,791,917,415,612,262,752,656,875,396,330,497,794,555,11,169,984,852,255,477,951,675,47,855,476,436,103,378,574,12,822,305,736,699,600,863,823,460,181,939,978,239,700,598,674,263,933,445,582,174,685,362,611,575,56,348,101,899,520,53,999,488,378,881,153,967,482,859,801,948,319,166,996,311,696,829,559,648,158,118,870,523,754,90,767,73,790,945,478,861,147,627,984,145,181,417,139,958,137,936,383,781,609,523,138,269,112,251,787,542,324,791,762,828,482,337,156,327,330,641,75,765,350,250,866,76,716,905,126,341,906,454,178,764,748,83,963,471,261,779,633,917,795,412,474,254,624,841,220,826,458,930,683,267,704,664,182,756,149,544,539,663,153,23,229,327,438,633,467,394,33,667,31,374", "11,333,46,645,395,141,168,716,75,926,627,336,1,769,891,821,873,500,987,62,525,323,135,731,306,46,370,11,900,298,209,793,930,68,671,959,306,707,157,133,103,84,849,746,188,663,561,625,381,751,257,281,966,294,466,501,105,905,807,676,54,827,842,61,767,590,45,826,603,123,479,583,733,539,235,15,193,885,575,61,306,357,743,189,621,152,614,674,37,374,398,663,691,660,410,85,616,918,287,977,18,696,328,279,129,594,705,105,977,538,642,960,665,98,295,548,951,129,397,890,78,65,616,355,13,735,288,784,205,40,339,31,204,329,273,234,392,491,835,884,880,181,962,326,904,669,368,845,18,910,690,529,399,626,998,569,557,384,461,188,993,53,223,420,690,440,514,101,962,350,819,640,131,579,44,258,418,612,495,611,604,206,767,14,220,32,28,93,175,214,652,954,585,484,333,853,893,507,642,200,301,439,95,508,478,448,90,125,299,369,428,856,878,443,526,251,380,499,179,56,193,368,790,762,911,272,158,318,940,987,93,289,409,366,970,303,547,332,128,534,387,140,614,705,420,164,589,841,243,956,429,290,372,911,548,722,271,832,481,522,818,995,724,700,596,153,418,876,192,377,459,763,255,397,284,671,849,44,11,835,521,373,820,490,140,268,88,508,471,867,834,373,271,149,807,589,446,807,813,435,515,820,912,931,968,64,12,508,155,719,735,332,736,800,93,481,158,692,914,577,929,169,775,669,506,843,516,188,619,321,617,678,483,602,609,727,32,616,234,196,592,193,245,1000,609,557,945,398,749,53,770,480,958,115,69,174,847,77,729,86,71,524,480,632,438,402,769,147,4,697,421,23,457,438,684,665,63,973,271,236,294,416,912,158,739,9,858,110,838,997,683,842,114,983,52,11,997,985,149,897,292,456,547,97,700,39,628,829,102,861,124,637,376,521,950,359,379,439,93,241,662,286,466,115,393,83,875,692,99,612,388,972,274,570,715,481,898,460,126,339,710,280,243,980,999,438,211,194,802,563,363,743,533,874,129,877,420,230,669,678,791,600,479,56,115,346,741,434,72,74,555,683,791,394,719,202,849,19,199,619,484,928,601,583,390,41,802,64,28,885,665,493,783,388,926,308,960,77,166,519,69,69,781,859,275,232,288,51,547,938,846,791,962,784,797,588,574,975,139,437,455,854,704,81,43,893,961,909,199,366,679,437,396,979,547,359,578,561,666,613,441,131,95,578,700,586,366,109,278,742,846,705,922,811,897,117,119,35,725,174,858,668,77,95,947,870,686,583,498,607,543,156,447,348,82,451,660,505,990,769,506,909,557,368,464,603,991,836,509,501,152,921,723,59,492,593,975,627,189,44,609,927,193,76,65,209,490,33,462,419,313,171,414,414,144,499,645,927,491,704,387,566,214,171,469,301,715,490,241,676,830,436,582,871,138,233,213,731,753,453,861,572,807,448,625,754,83,312,187,657,631,823,915,571,162,599,614,498,615,629,253,686,387,597,849,845,907,342,202,709,704,905,136,77,996,324,655,563,538,688,751,960,814,690,888,283,867,537,112,391,782,963,476,215,493,868,952,437,414,180,949,461,641,62,264,303,315,290,992,610,585,658,883,246,796,939,662,485,809,128,466,876,661,758,964,680,197,87,771,184,323,493,814,781,649,862,372,282,368,963,879,878,544,642,320,662,36,84,294,131,428,88,18,451,363,268,171,366,72,45,831,940,365,0,66,228,213,691,718,657,528,412,756,143,316,321,544,780,356,790,523,4,980,775,249,347,366,710,49,829,472,161,169,935,265,299,253,306,308,348,653,381,806,249,296,248,557,576,32,640,353,30,382,198,500,417,350,617,168,467,521,924,483,680,641,664,862,482,413,80,261,798,500,802,688,711,387,619,376,888,933,238,874,504,368,819,306,799,577,933,159,800,943,960,600,967,512,122,53,339,770,551,484,798,3,322,858,809,687,892,696,139,35,951,668,925,729,822,104,831,965,265,297,211,564,366,600,158,671,420,699,550,182,173,637,510,740,598,180,463,782,161,582,787,88,679,86,890,160,363,796,505,616,111,375,579,309,945,911,34,48,814,355,960,43,432,824,188,392,428,439,115,567,501,432,85,530,491,293,194,31,588,382,497,74,64,160,90,547,999,952,31,910,255,285,604,460,915,172,18,679,30,455,103,559,898,48,103,127,672,305,523,264,163,862,436,909,590,563,198,436,264,436,766,234,299,531,958,101,519,788,354,855,248,84,18,193,940,348,613", "604,221,246,50,785,274,859,583,73,951,376,329,511,472,714,316,520,551,152,756,609,530,997,643,97,428,281,682,654,308,31,606,923,388,319,220,944,377,490,300,696,525,929,641,675,85,924,877,221,484,199,756,868,867,172,310,197,7,257,872,368,37,499,14,76,589,481,226,928,263,31,410,848,733,537,160,443,30,999,416,471,7,255,56,16,860,346,716,385,697,620,573,888,514,298,815,142,489,877,274,778,795,989,53,465,109,173,26,531,188,569,373,109,281,798,155,784,397,51,783,766,833,495,982,522,758,122,332,804,984,410,745,771,450,233,792,310,859,488,763,957,101,202,252,841,739,570,840,527,86,815,817,693,749,668,516,810,808,702,585,438,877,278,375,358,767,729,973,545,533,463,449,762,100,643,612,716,580,866,525,578,879,417,183,317,656,267,338,191,931,338,474,759,629,609,992,448,585,8,353,550,390,937,656,7,647,121,872,283,628,534,13,697,818,422,242,872,619,149,480,765,446,182,763,650,793,738,507,667,438,781,746,691,844,852,791,422,458,573,108,256,911,835,519,833,322,456,643,696,132,541,938,560,430,829,178,31,473,939,465,42,470,222,828,946,381,260,83,832,58,338,286,925,451,601,475,381,474,732,251,354,47,109,438,8,457,185,85,593,512,625,84,255,444,295,84,295,799,667,801,249,919,218,223,948,974,732,529,508,135,959,43,307,483,41,949,46,68,12,523,59,701,897,186,280,392,324,987,697,190,839,629,552,906,810,573,513,847,513,430,767,284,118,58,436,222,423,228,411,614,862,908,891,611,512,504,654,179,859,584,174,618,677,942,284,661,619,409,546,628,833,545,831,70,484,656,338,10,694,912,539,372,170,853,824,705,42,265,683,178,581,26,414,566,977,942,809,427,825,487,280,834,748,936,8,274,27,742,211,192,781,665,826,198,739,915,326,470,752,880,882,850,35,131,376,241,242,761,668,703,684,939,580,608,934,154,586,322,225,960,902,580,538,41,155,693,745,988,508,751,373,500,166,359,381,106,447,914,210,700,997,515,466,510,459,656,988,317,146,836,766,831,13,365,960,110,562,262,39,622,469,630,833,545,963,258,311,142,779,672,903,149,344,452,288,532,105,674,225,951,769,317,24,630,664,602,134,49,922,968,399,949,147,811,388,605,695,448,108,20,142,233,987,748,45,711,343,104,804,965,387,133,705,871,450,206,488,583,811,792,946,522,417,519,119,109,215,465,637,179,89,42,587,92,894,164,408,48,815,860,952,583,58,419,608,546,122,93,974,592,640,293,354,928,388,946,574,751,40,500,504,927,481,418,952,36,801,264,213,568,389,80,760,393,319,998,346,484,478,344,156,139,182,806,932,365,541,329,612,548,13,205,283,185,609,511,826,586,287,441,259,43,603,733,75,477,590,568,254,944,66,688,80,997,740,809,316,714,401,228,537,88,705,770,682,130,298,720,955,757,621,931,287,804,852,402,323,271,616,593,47,56,195,426,438,833,571,215,788,605,377,391,184,672,421,994,223,863,68,412,808,716,81,316,464,42,929,540,536,730,948,980,224,58,513,921,5,54,447,369,510,598,667,280,439,540,752,204,766,76,329,587,982,384,156,439,566,874,772,856,29,723,306,532,388,803,481,257,970,609,885,553,52,852,468,978,436,6,233,200,328,728,116,855,147,193,455,988,219,992,853,112,878,457,534,580,554,915,350,726,755,849,955,66,0,614,983,167,813,659,567,203,869,353,188,138,352,669,155,570,366,30,197,479,729,848,47,133,915,414,838,298,983,700,472,411,894,721,879,878,743,128,786,486,219,66,685,721,620,477,962,28,504,676,761,556,142,265,422,14,44,906,568,819,940,885,7,82,820,164,85,744,217,608,933,367,410,574,7,972,215,671,901,679,513,145,907,545,794,601,891,126,69,217,430,386,328,570,700,464,824,422,649,40,906,549,663,234,67,825,54,951,179,818,781,670,531,147,975,677,354,691,726,641,859,156,584,457,824,684,176,677,191,275,296,747,286,396,805,263,123,857,236,519,706,863,700,853,968,561,752,148,194,359,907,379,420,633,694,852,895,17,93,23,502,687,819,416,270,565,529,319,550,255,36,388,638,892,441,818,696,350,185,130,91,170,98,853,651,585,865,874,783,22,517,985,29,923,78,945,464,566,597,481,941,795,316,45,381,674,564,146,45,572,76,881,218,936,782,777,423,631,847,475,331,736,533,466,271,575,959,846,541,320,617,100,348,594,514,331", "384,223,275,469,784,981,901,922,597,760,440,6,369,270,123,835,500,933,629,270,734,981,20,138,115,840,988,919,313,996,904,72,144,156,925,758,486,434,442,159,987,994,223,418,704,801,336,525,386,8,338,615,245,669,114,882,701,972,804,988,938,298,565,512,451,589,484,399,391,15,749,293,143,713,181,840,903,726,471,480,354,328,26,512,932,846,557,920,170,856,594,947,538,558,164,206,77,962,943,128,252,437,514,681,654,344,912,650,850,784,923,872,324,417,144,615,723,552,35,969,834,214,793,961,649,781,164,108,491,652,284,107,138,483,953,890,213,578,900,958,94,847,898,410,899,666,814,269,133,781,941,186,585,894,424,304,994,916,349,960,578,921,353,42,347,177,654,466,971,165,910,946,299,146,803,272,215,374,423,324,928,733,908,397,129,327,161,97,413,698,687,33,644,789,957,676,365,214,641,657,937,212,503,591,380,520,318,373,384,100,656,404,599,144,95,363,228,956,221,898,893,894,896,291,420,896,255,142,925,648,167,955,850,22,653,907,509,486,347,846,940,571,208,171,940,997,902,141,444,836,499,123,777,472,424,155,461,698,720,180,450,198,401,871,488,385,551,752,582,250,263,593,640,357,378,568,169,608,186,476,32,562,465,997,499,937,231,866,320,843,989,843,959,481,199,149,541,902,538,242,137,454,828,708,32,192,949,306,202,621,991,732,89,371,256,345,855,277,243,216,38,548,655,470,84,542,693,902,223,128,929,429,528,695,477,114,678,90,806,551,754,491,166,259,126,212,354,754,628,823,421,969,962,943,405,88,115,423,173,246,15,472,430,3,866,766,387,207,748,613,111,855,79,676,175,300,297,107,448,989,516,529,822,281,441,230,902,117,818,265,367,897,771,279,643,140,914,49,971,527,543,421,594,210,931,294,91,334,472,488,892,486,539,828,498,127,661,455,639,52,251,893,74,186,357,589,182,927,689,995,848,486,9,248,167,537,760,557,151,248,523,154,439,207,501,825,136,522,953,458,956,338,465,816,221,696,135,882,819,721,474,766,83,29,432,775,484,271,705,183,22,557,623,121,395,965,723,969,420,860,722,824,803,842,936,414,969,194,558,678,756,539,771,219,706,70,98,628,874,499,580,619,311,582,341,562,101,140,606,406,850,884,679,533,251,100,701,641,303,920,521,719,436,859,809,731,113,697,41,76,816,211,8,403,999,223,868,324,22,762,547,2,85,730,502,317,167,490,27,960,862,75,659,756,897,367,929,720,907,121,145,187,486,636,989,820,680,319,582,398,827,776,163,882,984,731,306,855,481,922,963,52,132,282,643,214,863,473,422,515,13,496,695,648,114,784,917,626,408,267,793,621,71,687,683,758,787,401,202,3,687,835,717,237,655,138,224,448,816,670,794,105,626,739,287,373,336,165,568,442,136,135,540,411,410,430,274,578,205,965,503,875,139,165,962,835,159,249,198,178,779,38,34,439,61,637,995,362,637,183,223,524,401,22,572,212,895,738,52,653,452,171,563,350,74,879,305,485,650,609,643,890,939,803,796,106,143,186,194,978,853,469,826,250,584,803,835,132,35,648,639,618,50,395,943,606,536,625,565,867,789,750,308,837,253,542,466,592,700,887,533,40,915,316,896,670,798,408,509,482,764,185,447,576,754,899,663,291,631,400,948,137,503,287,231,229,701,840,280,815,573,221,156,780,679,114,226,231,358,791,896,655,84,228,614,0,788,530,780,861,698,234,666,471,165,679,982,311,225,85,758,5,494,44,437,30,455,360,458,692,81,139,526,54,653,275,522,879,404,72,21,154,139,986,56,879,511,91,503,200,115,686,601,608,826,222,167,870,867,466,286,677,430,123,683,717,17,787,627,206,929,8,607,230,881,949,206,169,724,174,689,431,299,176,178,239,998,68,602,392,630,382,344,926,634,616,623,513,914,698,428,185,12,881,301,93,774,228,444,982,93,365,686,973,606,973,305,916,668,912,910,710,417,685,910,167,303,657,93,393,621,586,111,185,431,498,984,363,952,73,755,853,915,117,26,532,961,718,430,531,857,573,197,929,268,911,732,186,493,339,866,983,918,181,256,793,269,226,616,151,886,71,593,767,556,494,78,898,207,504,483,187,586,93,587,423,885,442,373,526,181,852,900,685,836,795,178,607,410,771,646,928,62,559,506,490,296,104,708,493,115,47,352,768,739,986,764,196,841,848,355,76,624,900,132,231,314,359,265,600,972,95,625,765,599,843,162,283,269,823", "440,95,400,67,220,777,93,471,599,904,289,28,346,248,955,275,220,376,58,601,337,543,882,393,951,695,567,178,910,302,388,445,496,383,688,649,887,844,209,767,843,54,998,38,894,444,540,300,991,984,244,408,96,802,238,262,365,128,645,236,166,542,818,340,681,171,173,126,975,668,161,189,318,63,885,378,811,656,786,324,114,469,876,575,997,951,65,365,292,358,54,727,583,123,516,868,835,652,179,112,886,40,596,873,571,874,804,753,778,873,516,90,9,426,756,75,972,657,597,621,109,764,96,786,883,705,826,62,193,673,624,505,950,638,175,408,252,11,81,581,705,493,909,428,445,303,984,619,623,620,190,121,584,674,341,772,759,518,435,40,871,94,401,246,951,692,299,772,43,66,362,432,498,148,927,338,375,696,157,207,295,377,668,958,884,548,272,970,140,944,39,839,778,905,277,952,658,894,843,14,132,272,872,32,59,928,446,534,576,185,363,918,543,661,402,500,607,922,679,934,336,640,726,687,174,787,101,18,470,736,639,275,848,116,350,434,401,993,104,370,544,770,427,727,55,157,345,406,181,285,417,234,757,693,111,268,80,363,663,730,924,893,710,618,855,445,245,392,409,780,150,591,349,366,522,265,712,864,144,941,174,790,162,844,507,196,585,844,680,250,384,707,223,217,397,764,463,20,200,629,646,168,26,86,676,421,220,521,276,404,985,690,647,19,812,348,657,419,902,968,246,741,294,77,893,281,646,222,611,212,463,223,857,490,439,634,199,26,750,964,340,624,377,660,946,598,257,854,613,203,876,144,751,175,735,617,847,828,597,285,557,263,474,761,436,844,146,160,624,127,909,595,947,288,915,730,234,782,754,946,342,805,7,98,195,934,24,572,574,755,760,700,547,660,461,203,447,515,259,992,430,915,278,544,248,270,628,904,788,331,52,791,55,196,197,727,706,498,985,950,275,876,475,333,625,918,287,418,553,646,11,730,453,968,413,439,286,559,838,410,215,99,641,843,604,336,251,529,788,176,382,345,704,776,159,302,745,141,355,721,342,987,539,967,857,245,503,431,834,211,708,78,994,638,48,111,357,466,84,450,907,416,817,939,41,875,654,431,236,220,199,274,197,885,654,339,440,66,122,705,708,443,115,134,250,875,583,165,46,342,131,996,13,747,15,312,498,434,91,163,852,574,739,395,820,233,483,803,301,819,861,208,685,587,560,466,655,572,24,703,611,587,907,939,529,377,482,257,139,190,749,867,520,22,398,325,198,999,739,353,861,472,841,710,939,435,691,495,122,394,687,273,208,304,954,614,354,855,563,844,121,610,634,293,844,194,963,659,374,973,128,918,51,574,358,636,653,868,508,381,118,28,208,744,354,491,897,92,565,664,759,433,803,505,148,186,206,61,754,16,618,488,730,166,701,972,404,908,166,10,554,423,203,722,404,387,697,502,96,481,240,315,251,561,478,44,577,767,638,19,490,201,966,551,855,221,469,229,276,198,347,39,758,904,573,211,838,349,99,724,120,961,56,710,154,177,498,595,429,543,585,12,71,58,723,491,634,552,618,250,489,373,702,831,909,754,971,438,108,378,114,675,239,96,425,672,401,382,858,182,920,941,576,460,976,888,904,706,791,218,116,492,552,503,29,690,949,263,138,148,795,587,811,861,671,374,171,271,592,160,251,422,509,4,882,831,765,346,184,217,596,375,519,272,950,617,694,8,847,227,919,856,986,213,983,788,0,443,710,851,282,283,859,603,69,616,335,520,963,198,31,91,388,352,906,981,802,771,730,204,190,440,456,433,127,890,545,765,403,335,332,942,921,552,892,424,236,534,463,697,776,879,620,614,706,326,213,149,417,274,479,672,886,266,482,571,960,910,708,322,423,888,98,452,763,21,654,940,430,602,192,610,604,619,683,986,560,935,321,40,285,18,863,330,732,840,680,358,712,272,520,381,737,590,498,754,601,753,288,885,244,827,61,588,505,664,391,492,415,346,389,735,400,126,233,404,318,697,368,66,350,90,50,620,114,983,657,736,965,845,278,362,976,349,548,999,574,407,311,977,102,572,305,757,375,463,675,233,44,976,976,209,337,521,733,890,817,421,619,715,157,488,923,707,139,762,526,986,483,278,861,127,903,561,178,399,371,692,403,937,415,814,604,977,751,310,737,769,603,641,176,940,713,688,731,695,956,617,690,744,27,174,904,764,241,220,293,211,278,842,87,391,642,862,919,635,27,465,738,947,498,345,891,320,76,762,599,11,36,113", "914,665,664,923,876,558,630,365,951,408,173,906,444,216,852,625,182,235,31,71,213,671,713,130,937,710,629,535,602,17,782,200,365,529,141,68,735,886,86,954,893,977,896,168,291,861,715,664,256,773,554,249,243,72,789,773,855,924,643,751,600,372,77,986,476,595,208,565,205,311,120,1000,975,469,471,860,732,770,503,641,138,628,98,76,240,148,318,930,31,365,730,281,478,506,338,691,545,432,463,943,493,30,90,471,489,913,971,578,587,728,151,236,761,259,665,29,623,313,898,150,242,793,473,836,686,3,328,140,48,785,904,874,192,304,850,153,309,850,458,299,825,923,454,955,570,194,587,626,806,87,756,654,221,954,248,149,328,156,923,748,509,56,311,495,466,552,897,577,630,494,333,344,698,426,275,632,263,962,403,840,396,670,401,776,672,586,215,832,937,516,8,47,106,905,912,398,338,818,362,444,860,952,210,959,561,471,751,630,267,237,527,378,858,372,206,754,144,283,509,491,651,575,875,756,715,844,552,376,199,659,258,272,637,896,581,84,457,181,450,869,697,355,856,363,613,655,257,90,386,538,970,235,471,812,739,978,867,273,409,419,575,784,847,288,13,278,10,285,918,670,679,602,782,316,37,383,200,142,419,577,786,237,894,947,595,580,686,897,232,780,708,114,586,13,994,818,134,812,370,805,615,670,619,583,425,192,502,394,680,464,712,375,541,694,538,50,8,181,285,628,298,304,646,218,584,975,917,241,474,13,711,533,637,36,624,102,41,80,301,633,725,319,782,512,296,832,564,906,445,27,201,236,9,658,338,131,457,152,427,125,249,474,125,335,410,512,203,908,559,475,555,695,943,420,105,294,880,400,818,568,642,453,424,387,682,803,980,776,537,365,370,675,608,455,229,297,256,489,12,504,866,893,346,600,469,487,867,371,249,598,230,372,37,59,555,11,642,47,173,91,258,643,298,186,753,444,510,967,608,360,963,703,124,204,523,187,671,188,634,14,24,886,520,283,635,105,697,130,127,885,636,703,638,779,193,791,701,669,429,589,341,863,659,364,599,338,444,859,651,463,613,875,562,109,282,93,223,352,872,305,726,386,962,476,242,399,507,850,796,359,575,655,768,31,472,819,92,925,788,381,921,262,372,428,343,813,364,588,118,489,774,184,207,885,383,104,514,339,461,304,311,90,896,694,160,978,585,354,91,452,379,612,980,138,310,159,145,308,493,227,775,96,187,836,518,975,674,78,852,76,877,896,135,897,233,795,421,992,661,335,47,74,634,698,117,887,402,102,225,448,238,454,310,622,889,494,29,476,430,840,438,445,308,831,891,332,48,190,368,779,972,219,7,206,393,314,229,442,497,455,277,868,488,784,146,216,841,212,74,882,757,835,609,696,171,113,539,359,70,899,134,853,819,317,312,31,199,571,489,569,373,759,255,93,589,871,679,527,155,762,339,823,199,282,216,865,43,396,442,649,412,232,584,649,317,586,706,143,234,931,445,114,714,407,875,342,354,444,292,487,337,626,26,478,91,621,640,913,384,142,178,341,676,821,705,821,853,667,868,545,877,626,884,423,551,70,759,363,763,669,179,430,237,151,186,602,632,1000,967,321,323,978,354,882,760,745,980,264,566,700,240,219,969,621,973,651,541,670,950,271,983,752,193,483,425,488,818,998,359,918,80,333,646,113,403,914,710,853,20,553,322,142,478,543,286,49,748,333,342,240,403,157,196,691,167,530,443,0,114,148,993,745,979,132,149,74,117,84,435,844,37,267,853,19,945,140,555,696,618,64,951,69,424,444,569,791,721,239,59,627,68,140,791,169,407,344,63,88,790,395,949,702,51,651,493,321,899,791,796,529,993,712,242,245,880,330,554,250,850,721,988,652,160,337,38,638,494,750,650,162,599,198,120,658,467,528,76,188,745,523,902,295,615,106,269,458,766,81,297,726,488,836,43,415,148,920,258,588,793,543,165,249,225,413,716,334,984,466,941,622,478,978,828,309,711,536,304,220,10,159,335,266,14,912,71,446,170,307,16,155,387,491,305,154,236,837,733,913,720,76,263,835,926,443,519,4,159,171,691,931,381,226,462,497,339,539,682,131,836,396,181,185,149,102,98,706,487,66,429,924,563,766,545,149,171,837,600,89,706,46,941,224,125,297,496,181,49,639,749,376,425,787,315,527,54,575,87,398,436,151,113,446,339,435,526,115,800,721,371,929,740,241,66,495,887,370,390,862,846,538,613,103,61,667,873,323,853,185,181,10", "286,884,787,552,21,152,989,919,499,508,646,258,695,402,209,484,63,593,951,117,37,420,438,112,422,496,648,102,511,899,982,158,130,114,94,480,696,548,751,540,650,709,725,977,117,193,133,152,595,960,513,360,819,866,166,405,705,641,460,244,15,237,575,842,176,971,761,7,504,819,454,962,24,712,629,554,226,704,624,576,86,201,461,491,550,188,292,413,297,608,948,30,207,968,726,586,875,716,488,59,470,246,371,171,470,175,74,349,515,293,346,14,986,285,83,596,49,473,349,940,944,302,522,451,42,219,793,467,466,572,85,543,88,518,976,71,93,3,701,237,366,564,963,945,864,506,820,405,890,251,599,922,116,508,298,791,823,328,741,500,403,662,782,995,810,877,575,433,520,129,805,285,418,864,858,85,472,288,535,944,368,688,440,236,931,845,599,407,520,632,511,822,266,127,608,585,766,46,732,696,782,779,944,331,190,671,42,531,880,165,45,837,105,474,291,543,804,963,884,764,885,12,347,17,55,43,39,233,756,324,256,900,830,90,471,282,600,107,284,573,465,553,688,823,184,101,729,3,738,946,357,128,537,735,21,340,311,612,856,887,712,166,207,535,326,847,829,842,527,159,485,375,835,807,446,357,106,243,62,93,129,572,406,861,641,213,777,328,210,649,420,36,213,751,217,516,580,48,690,794,628,96,428,582,155,630,348,70,120,966,949,762,625,35,607,534,703,763,478,355,924,262,3,328,809,400,846,420,943,363,667,616,731,84,584,711,347,465,747,171,66,503,594,205,375,858,372,771,544,467,874,703,655,581,154,723,212,125,707,800,695,990,907,362,958,926,51,124,39,57,423,854,257,932,729,547,616,140,233,558,280,17,170,953,286,943,220,278,40,696,291,252,245,902,829,965,735,994,549,784,106,51,388,346,740,164,424,554,823,19,710,820,465,873,63,60,445,43,168,382,924,301,109,154,368,399,225,121,60,309,993,365,533,200,485,482,399,607,405,582,351,544,330,700,962,377,702,871,148,496,352,720,55,608,635,828,80,900,158,208,853,39,593,634,719,255,96,950,684,34,1,154,240,723,787,723,938,427,947,418,752,48,155,601,486,17,687,247,621,505,599,76,154,857,750,549,499,115,687,248,715,637,895,530,507,40,144,510,776,637,713,183,594,819,843,387,545,625,53,882,311,188,357,247,597,446,268,816,506,634,933,382,245,865,621,939,23,621,939,575,708,418,739,48,592,371,903,573,465,71,882,188,266,61,974,401,913,680,725,760,610,394,683,203,930,756,251,832,774,560,386,236,234,698,888,544,626,836,206,579,820,711,510,538,251,178,513,408,547,980,762,753,490,486,835,537,150,830,677,910,410,454,100,644,932,634,124,580,39,586,561,325,644,976,168,730,94,625,258,612,936,365,677,980,126,188,111,946,262,730,914,49,254,377,363,731,435,962,473,147,578,566,75,194,20,590,431,368,883,234,722,536,714,624,411,135,424,578,512,663,761,317,445,156,532,342,590,318,171,555,748,445,255,498,9,766,314,826,427,773,905,137,314,435,8,203,77,696,163,860,40,954,820,72,51,296,951,817,393,556,975,675,157,424,348,188,17,324,965,292,523,321,220,872,236,732,436,838,250,295,678,164,793,825,18,636,675,715,4,3,802,52,598,21,945,132,429,461,834,995,26,104,15,679,920,974,685,301,766,957,842,62,629,487,324,838,996,294,10,602,631,43,977,718,813,780,710,114,0,418,868,568,504,326,743,549,246,592,669,724,260,916,953,362,470,30,151,279,434,143,299,611,372,638,359,969,664,298,3,974,921,165,834,528,98,176,873,778,989,316,792,575,427,101,353,719,900,285,830,25,161,111,645,78,324,562,400,695,954,783,927,97,265,137,188,246,525,886,662,400,302,187,787,427,169,530,812,673,740,675,901,831,225,824,586,857,575,900,639,45,803,507,948,26,194,902,33,60,369,160,845,242,37,237,302,611,362,756,38,553,302,636,867,36,229,275,337,66,414,950,280,21,171,819,392,291,190,567,210,156,345,761,369,295,857,200,631,792,619,197,419,783,943,605,732,56,287,422,921,618,265,231,957,529,93,244,968,46,512,75,971,898,755,27,512,631,310,519,182,167,575,355,808,33,637,99,649,955,127,24,379,573,18,209,607,603,591,135,803,812,825,838,137,390,267,703,502,335,425,815,512,596,513,819,424,99,903,299,655,78,495,656,320,144,405,160,485,490,592,516,220,550,712,548,172,103,679,587,130,67", "110,235,817,198,6,635,343,736,649,516,976,75,742,197,946,251,931,560,76,220,393,904,770,185,97,445,430,827,483,541,365,997,878,439,829,953,318,495,806,446,731,347,101,575,485,108,596,737,683,966,615,919,414,804,266,907,140,832,156,703,968,80,563,676,146,999,621,618,402,391,725,77,506,920,218,429,537,205,369,844,878,854,29,636,793,612,214,124,488,223,902,859,428,455,302,866,870,260,799,246,914,811,635,236,266,185,125,953,460,924,697,678,334,541,404,300,358,241,180,256,88,868,355,779,464,590,66,883,11,696,263,314,968,484,832,457,532,805,792,551,547,81,125,767,460,875,868,505,622,462,102,602,857,837,187,468,625,907,955,799,672,901,273,635,484,177,775,342,425,493,673,566,176,23,381,93,513,879,732,666,332,429,552,175,863,972,990,561,39,729,832,247,811,936,175,728,890,697,794,434,328,539,968,205,292,89,255,503,883,680,524,632,626,745,143,786,591,725,654,744,781,894,795,851,452,871,506,711,217,30,318,883,889,99,656,535,792,279,166,449,882,384,360,811,188,696,300,873,330,291,62,795,637,59,693,33,564,259,876,391,391,394,878,102,129,607,493,95,145,363,645,387,311,814,751,493,261,679,45,758,121,432,412,673,825,965,433,949,263,375,729,732,860,814,201,704,126,720,670,614,59,801,544,541,735,639,230,957,241,400,348,322,230,583,906,186,179,77,375,763,540,792,129,199,443,871,688,897,693,657,343,802,279,322,984,224,374,550,39,794,804,901,80,902,605,435,280,821,150,576,720,203,339,780,213,354,616,558,101,57,250,623,179,190,63,976,220,770,546,71,744,953,617,761,10,798,22,574,420,431,68,286,218,539,142,139,398,91,446,712,856,195,688,977,647,27,560,167,912,531,692,540,408,850,666,690,480,745,304,675,403,203,30,216,845,320,405,587,668,857,549,40,607,217,282,228,379,470,863,668,480,958,150,168,431,208,777,606,751,382,652,404,461,487,143,747,906,633,518,927,779,14,709,141,892,259,9,628,61,745,578,211,224,23,824,552,397,149,815,957,411,382,186,599,934,827,505,132,900,902,916,213,636,457,182,208,941,316,981,818,557,765,824,71,671,359,431,325,715,460,306,465,885,352,758,226,519,387,800,165,295,802,578,121,118,329,791,954,37,286,881,797,180,224,265,993,16,208,5,218,959,527,525,248,440,955,141,439,562,507,419,298,298,273,678,899,909,63,819,837,176,527,374,681,183,263,167,201,816,82,652,403,530,133,926,489,536,845,801,968,684,73,178,830,187,169,915,565,962,457,472,417,881,426,164,218,596,700,520,894,57,344,782,192,190,842,857,798,571,735,935,186,252,20,44,51,470,702,851,533,945,848,767,377,322,120,106,906,376,607,499,688,757,219,243,734,295,526,295,993,592,138,98,878,620,724,181,772,321,384,515,302,808,728,534,674,580,682,174,344,275,516,987,465,158,532,753,818,967,710,334,834,561,395,768,597,702,382,184,355,268,601,694,774,835,177,347,936,791,620,90,251,584,993,608,383,641,12,89,388,742,751,501,789,832,204,162,295,866,239,967,774,37,222,914,499,973,427,592,664,959,312,509,910,988,567,169,666,50,248,68,604,736,642,351,764,429,588,60,550,225,758,523,88,264,942,719,957,942,81,738,633,689,625,520,238,482,314,587,926,395,863,152,831,776,241,504,7,201,452,230,931,739,657,659,861,851,148,418,0,107,9,953,737,790,642,66,35,642,884,164,355,317,521,64,274,400,560,868,331,556,894,581,519,402,987,79,308,849,33,891,450,889,480,637,789,143,263,186,663,303,727,18,918,684,235,184,604,755,776,538,603,928,745,656,212,936,950,996,661,359,573,447,386,381,35,279,491,113,969,569,932,94,874,390,978,160,413,737,64,245,33,816,771,202,802,269,340,624,505,194,569,527,999,209,607,850,706,957,671,698,411,565,414,696,40,663,777,344,541,545,722,721,772,887,811,764,871,830,601,17,506,616,824,549,184,839,931,949,499,810,667,893,176,420,546,140,263,387,252,574,702,96,972,570,463,61,505,987,653,791,843,956,938,464,548,358,122,226,785,293,416,611,399,18,853,4,590,294,625,981,172,444,314,721,873,240,747,435,916,608,431,495,295,245,801,745,858,292,834,212,762,970,199,809,989,200,461,987,813,503,428,650,578,655,706,541,288,756,310,183,321,650,964,241,973,403,446,694,185,921,976,963,935,798,424,976,876,789,333", "760,8,860,698,904,279,85,251,928,547,201,806,365,460,392,450,212,60,470,756,691,182,281,644,429,129,591,908,326,618,254,623,812,561,49,87,691,352,879,970,460,701,392,271,781,288,806,165,767,579,312,131,713,845,334,376,939,918,368,998,389,761,38,900,606,964,675,369,427,965,655,370,595,992,302,780,873,360,129,230,303,943,429,355,175,259,153,752,328,504,831,159,959,869,810,388,919,935,649,142,65,602,10,369,197,565,224,436,924,799,335,761,518,727,31,420,189,980,784,554,514,131,340,976,98,102,530,161,977,49,644,894,325,69,594,803,388,254,315,694,289,32,674,732,361,483,912,852,764,405,563,989,670,159,143,93,80,827,656,145,223,809,430,421,899,601,41,336,207,610,572,626,590,659,114,508,357,580,642,910,195,282,615,361,243,452,436,933,505,207,770,99,862,332,27,660,478,212,93,392,141,482,810,421,58,350,945,723,220,212,485,741,886,291,205,726,142,693,147,483,617,961,94,515,454,375,186,51,834,962,901,863,198,811,582,79,595,594,85,914,438,623,563,566,994,891,22,328,852,986,412,918,856,932,13,828,871,107,982,116,603,262,331,157,339,849,432,183,60,726,797,383,553,607,419,590,117,740,126,856,526,2,275,152,92,568,184,206,948,680,690,769,285,497,784,143,769,564,568,855,206,500,359,484,271,490,513,641,993,260,551,605,463,142,274,921,831,154,909,28,33,724,672,276,65,48,32,944,546,808,502,105,480,34,998,597,27,769,529,163,653,881,356,213,266,361,629,884,227,580,547,80,675,917,890,989,265,151,674,241,836,258,647,95,175,18,215,433,819,206,994,366,396,844,119,450,13,552,148,75,569,84,231,942,348,774,867,37,959,220,142,789,504,762,499,839,539,706,737,739,705,844,641,911,503,206,962,210,241,148,160,214,982,602,898,861,952,742,409,178,207,936,794,597,774,392,838,589,401,605,177,656,593,978,464,699,597,670,952,667,578,626,582,971,117,535,713,265,126,747,295,279,74,524,843,21,271,870,226,777,784,57,228,292,975,648,366,312,70,427,847,74,971,314,133,34,384,920,602,298,968,201,959,319,929,704,531,57,174,10,50,589,68,880,736,199,683,587,809,766,762,525,673,721,501,450,855,45,611,442,942,529,291,211,872,946,567,226,80,28,802,332,824,273,123,402,424,230,988,769,469,115,725,839,943,949,683,843,262,858,144,127,907,375,898,49,874,444,872,244,16,516,161,118,11,327,48,663,210,829,493,256,837,51,675,337,640,562,691,384,796,181,775,678,812,886,271,205,139,41,935,209,534,405,356,946,727,737,206,292,638,474,426,390,945,479,537,96,303,791,483,499,881,625,327,143,99,758,13,419,979,104,102,96,613,93,330,418,682,745,543,627,288,84,117,995,696,403,910,161,869,188,487,92,117,663,211,602,178,420,482,89,330,697,965,234,547,914,943,945,225,699,965,386,892,204,64,906,195,808,835,599,260,130,857,751,818,553,809,126,495,428,873,256,136,820,822,808,993,548,995,480,355,693,529,249,590,295,213,773,880,582,213,715,241,952,47,715,404,162,671,242,811,798,402,666,371,337,614,27,201,748,255,90,712,965,700,487,409,59,353,200,509,307,671,691,926,994,452,609,238,612,515,236,259,120,251,498,572,683,866,359,65,914,297,360,379,64,655,924,112,984,653,77,11,919,774,637,418,880,749,324,120,528,567,698,282,993,868,107,0,367,196,370,375,68,905,151,607,392,568,182,433,369,523,434,327,678,245,60,272,572,66,119,310,285,644,521,733,670,607,177,145,68,67,574,758,554,385,503,235,284,423,447,617,724,465,12,433,920,405,371,716,393,641,133,485,783,529,707,37,24,435,311,618,684,786,772,78,689,545,452,813,798,414,894,115,505,968,965,470,703,22,192,173,456,419,792,343,290,885,351,56,303,297,743,582,212,660,188,283,572,100,374,927,324,116,89,693,399,478,119,860,747,541,677,331,585,899,130,888,459,472,285,5,130,369,965,3,215,879,646,567,477,506,598,804,840,564,426,165,507,781,342,726,710,897,898,45,390,787,261,654,324,57,240,392,358,780,641,86,268,565,602,655,844,780,651,909,991,767,863,222,788,540,242,552,765,486,674,550,366,847,212,426,290,593,602,687,779,823,322,405,918,17,919,691,149,254,862,457,769,220,705,118,726,873,876,538,299,48,82,263,6,624,986,486,146,220,552,658,342,312,296,10,510,645,289,133,833", "639,839,333,698,304,862,575,655,252,458,856,145,121,468,151,982,507,281,44,333,438,196,447,997,148,343,624,988,778,43,394,249,261,673,630,846,258,754,222,902,900,765,887,288,145,307,884,410,10,515,784,852,875,249,120,460,847,688,233,765,364,329,87,112,942,708,246,677,471,244,946,532,35,225,514,309,508,728,491,511,858,809,906,532,806,237,691,857,161,683,429,862,823,512,668,103,254,503,489,312,498,214,502,762,86,576,410,324,791,4,788,602,98,108,594,800,960,89,616,752,25,478,620,16,118,761,469,222,82,993,792,612,481,568,110,511,558,258,977,141,330,987,57,639,126,323,805,702,949,45,205,33,711,892,916,232,528,621,86,972,872,764,956,90,252,316,449,982,865,41,915,424,769,239,595,978,605,725,647,240,746,499,123,920,858,300,671,66,979,475,555,95,481,61,694,530,437,430,384,294,616,350,195,114,857,609,990,254,883,62,966,751,327,115,843,40,870,405,987,989,428,2,41,151,128,992,903,395,591,783,51,116,664,908,304,143,152,185,634,884,551,201,70,831,172,523,455,854,170,39,731,613,150,363,182,996,142,486,784,802,677,928,366,30,506,218,746,629,953,840,704,475,179,482,749,263,345,11,248,933,446,749,435,694,247,655,654,24,634,556,746,823,976,301,129,560,912,354,181,499,816,30,977,288,264,567,588,817,142,316,960,59,603,224,509,846,135,296,299,900,453,553,370,445,666,881,109,276,128,129,205,165,717,267,256,554,886,446,684,831,50,945,216,491,505,500,273,72,817,443,435,171,240,300,402,21,547,249,254,9,280,210,519,629,827,615,886,541,717,335,423,566,835,258,648,378,118,409,997,18,710,796,370,29,915,155,728,140,14,757,775,622,471,103,718,645,998,314,47,136,668,519,207,245,719,461,288,327,43,489,308,718,483,807,718,923,863,558,870,207,18,720,561,522,861,564,921,116,432,525,413,331,562,778,886,518,146,318,735,233,512,772,201,570,859,786,546,637,939,382,655,878,535,659,193,832,791,646,77,410,245,202,207,453,651,684,484,676,59,319,587,239,783,201,900,722,581,929,949,769,33,810,392,148,229,135,265,795,52,290,544,298,86,374,110,914,424,63,649,740,974,363,663,676,22,706,451,224,722,405,972,256,183,974,101,149,747,11,284,174,333,699,709,577,987,272,605,921,132,263,141,592,989,477,87,635,556,871,784,690,508,766,273,453,307,728,851,509,692,500,142,900,920,451,169,566,135,511,326,227,461,219,469,103,865,481,183,577,227,815,155,323,63,368,546,910,168,934,26,665,48,9,304,784,479,517,928,512,468,938,527,400,406,747,637,673,219,603,866,233,985,784,837,296,33,388,816,348,789,21,237,594,746,382,567,776,464,323,916,280,877,571,802,119,892,200,367,180,780,702,854,446,94,888,668,589,354,129,606,624,150,6,586,317,963,871,680,121,836,276,867,232,51,388,963,629,266,527,259,500,726,444,499,47,567,90,966,812,78,525,753,903,122,472,58,8,285,458,204,282,11,293,743,22,760,809,328,795,63,35,36,158,441,574,857,688,793,613,976,967,690,481,732,684,715,476,975,826,410,490,660,20,431,855,669,784,474,437,447,135,159,590,231,119,404,255,570,377,470,713,209,140,304,721,464,257,772,663,551,416,768,419,106,739,770,276,216,647,218,430,130,120,546,178,550,458,380,182,742,123,10,106,613,412,203,234,283,745,568,9,367,0,385,342,488,690,752,784,609,972,418,99,494,367,674,863,847,176,120,23,734,859,617,605,624,868,761,389,975,174,396,507,174,757,10,646,905,635,435,948,526,780,677,890,624,817,926,224,911,166,193,344,431,21,751,56,609,63,743,645,849,627,521,319,31,401,386,428,17,909,775,414,651,968,440,421,987,79,319,397,921,57,956,187,125,447,527,866,714,902,809,918,9,413,681,942,375,963,436,597,682,160,397,934,11,886,938,866,53,27,612,213,259,982,997,480,390,974,918,656,953,915,500,966,851,371,365,585,363,734,410,809,6,806,893,133,522,389,252,106,800,142,92,748,702,62,849,14,150,8,52,919,375,205,398,166,411,686,567,567,588,653,724,488,2,744,588,69,117,85,992,191,62,260,623,62,837,529,385,648,142,160,203,944,507,728,168,197,128,525,627,301,884,884,692,73,402,736,699,979,705,185,81,38,985,307,174,378,736,32,988,415,957,586,347,415,141,868,447,352,515,855,509,253,202,92,534,175,784,280", "284,225,452,741,305,988,415,422,127,473,567,735,332,144,357,547,818,808,439,791,954,381,866,213,368,749,613,138,487,675,936,992,709,342,657,589,614,990,680,349,180,765,661,20,781,959,950,689,318,797,360,75,513,761,701,511,483,17,44,736,718,420,602,22,441,198,217,337,105,250,623,124,995,909,772,840,304,460,829,120,445,490,757,972,912,777,473,249,356,723,831,878,777,950,184,472,569,104,520,264,928,831,795,376,686,917,868,986,457,500,203,741,509,569,52,630,730,728,913,440,489,973,183,754,913,543,491,902,458,531,478,203,620,874,294,219,658,332,121,93,319,363,909,445,307,33,241,580,95,422,351,643,388,448,337,849,698,123,733,726,958,165,869,940,420,184,298,389,641,599,81,102,329,301,313,359,453,816,739,165,908,485,940,972,144,629,917,776,661,59,72,928,214,944,459,163,782,334,304,534,753,837,378,655,5,970,179,953,166,903,747,574,677,30,68,977,237,281,95,895,428,193,517,832,134,32,779,2,830,459,789,737,289,806,432,430,764,556,17,291,457,87,81,273,3,623,643,268,115,827,820,623,926,6,72,830,707,604,343,8,775,48,84,879,845,358,602,770,747,332,388,611,208,173,886,578,835,154,833,19,565,481,508,898,612,485,112,465,508,894,939,609,534,171,308,18,45,444,819,518,736,107,863,377,970,756,628,179,142,316,934,42,78,448,836,73,169,980,561,467,740,210,774,85,387,379,455,492,100,816,538,303,109,602,821,142,325,4,857,656,750,44,844,220,553,884,623,474,720,290,230,436,480,519,695,615,665,695,972,299,556,42,485,705,510,238,261,386,133,457,457,767,246,776,774,359,829,718,464,539,685,989,405,868,396,893,402,899,89,305,574,614,64,717,261,514,535,449,280,869,763,709,589,64,784,390,597,242,868,766,240,922,339,83,520,384,862,836,734,994,572,688,110,220,612,651,32,663,15,512,665,40,993,354,841,718,351,106,974,155,687,801,580,483,546,471,444,616,28,884,238,349,187,734,676,8,296,410,825,312,444,359,99,59,632,304,235,228,492,7,436,747,426,790,596,297,824,268,211,617,840,619,195,7,387,351,421,397,575,311,548,280,535,995,950,347,965,583,981,442,410,311,78,470,562,574,16,815,389,771,198,690,987,387,525,920,360,134,400,386,672,378,505,581,848,35,717,183,537,195,503,542,528,177,553,775,369,970,484,392,92,120,817,288,568,896,303,165,95,239,495,559,461,452,437,298,813,968,888,476,731,42,77,143,52,351,667,867,197,875,489,472,795,298,789,60,170,202,197,701,450,834,782,812,317,250,681,813,992,553,563,601,638,1000,465,83,592,501,687,673,970,909,69,554,415,757,586,169,119,67,96,70,152,770,990,216,368,846,574,747,986,866,62,676,939,273,509,521,463,94,453,274,864,304,350,952,632,649,930,922,394,685,719,175,625,818,236,450,889,351,338,983,725,921,608,520,530,944,272,944,2,776,275,714,156,460,52,791,738,87,407,101,878,440,833,664,520,419,281,525,449,81,951,978,974,593,797,7,38,493,964,169,968,548,103,714,696,306,329,103,563,406,563,117,593,490,591,712,857,868,396,804,602,157,86,368,799,101,565,773,956,860,203,267,348,764,869,316,675,42,500,480,211,772,905,234,230,371,503,632,873,962,23,808,240,947,205,451,301,540,617,910,452,619,881,526,121,982,40,166,929,653,84,756,869,666,859,979,504,953,196,385,0,636,107,735,823,947,627,677,332,86,767,542,746,711,831,586,901,31,912,831,164,381,830,683,957,388,312,728,522,934,829,29,335,975,359,609,484,864,107,443,327,4,334,944,395,884,263,394,998,479,380,953,946,928,42,628,157,697,364,376,145,419,785,69,627,420,21,679,575,421,799,523,828,792,307,390,634,944,850,689,658,957,421,765,3,915,122,246,28,279,413,94,997,51,402,898,96,355,290,228,418,173,554,532,935,400,398,316,14,996,289,656,617,143,730,665,268,684,25,524,593,498,698,804,72,801,856,682,485,849,218,88,645,118,420,481,758,17,890,855,793,313,420,789,589,324,815,927,865,853,138,296,164,851,558,603,661,176,824,67,492,578,127,694,32,109,496,724,430,513,503,510,317,297,512,918,993,470,797,627,18,30,929,253,757,770,270,227,679,242,496,293,828,771,61,193,332,893,894,304,722,539,221,953,607,796,133,916,998,67,416,178,41,346,408,935,120,986,615,304,511,674,229,198,656,940,13,779", "3,756,897,676,809,779,907,606,872,702,104,959,343,404,927,253,745,676,587,715,309,711,34,225,576,926,117,203,623,83,381,491,687,211,953,399,269,567,107,185,670,217,737,261,124,796,51,643,772,897,739,743,915,766,972,356,395,297,49,613,286,590,66,847,233,282,629,156,955,302,334,185,649,75,854,868,588,902,228,793,624,218,88,432,372,859,443,945,827,578,196,503,771,793,904,412,937,106,61,21,177,482,508,436,233,233,977,362,997,689,817,959,300,700,322,303,362,31,489,379,4,331,494,171,598,474,2,574,253,925,832,825,876,893,402,453,782,603,92,301,84,853,17,511,720,774,930,164,65,388,678,721,281,790,31,408,7,360,550,766,925,830,295,850,217,158,708,784,888,410,952,881,491,479,673,184,151,801,295,509,294,279,658,378,887,356,190,172,699,703,396,706,680,887,727,672,728,155,79,135,693,392,520,63,608,971,640,613,460,71,588,919,590,667,147,597,413,706,51,566,661,554,139,736,520,543,825,477,475,898,830,530,485,438,139,699,864,623,11,346,685,74,969,926,987,704,461,409,126,606,558,88,512,150,501,162,546,277,893,380,206,750,232,779,808,266,991,280,580,956,953,658,213,308,508,207,866,685,837,694,769,718,949,285,583,246,174,101,620,718,232,574,123,965,582,762,463,176,916,941,23,553,773,516,945,978,262,946,614,395,606,41,844,449,396,916,107,337,95,523,452,18,87,716,807,758,375,451,822,232,522,430,657,463,940,615,193,453,556,549,506,942,847,764,426,401,987,689,145,921,972,175,544,664,978,67,227,712,363,48,476,969,135,112,167,964,197,154,477,430,734,662,957,128,527,744,889,522,575,690,203,869,335,188,478,703,926,878,229,698,41,120,88,767,751,973,658,333,620,327,918,487,971,566,936,660,152,158,996,904,691,708,413,349,947,665,419,535,184,760,801,575,697,395,757,638,689,6,389,255,831,924,38,71,855,994,607,296,221,510,25,125,586,822,308,383,293,26,225,928,7,321,613,390,289,990,656,635,854,67,417,944,184,649,911,858,407,521,336,463,41,644,822,991,954,610,886,470,332,153,367,127,271,946,781,886,604,793,829,560,421,556,466,584,520,171,58,745,187,419,354,106,356,865,233,850,289,774,951,669,192,935,9,226,686,448,159,795,852,662,976,140,42,535,147,6,762,603,737,374,481,209,50,274,370,826,254,245,1,411,611,26,485,906,467,565,425,799,548,866,235,505,765,627,673,284,481,928,769,123,305,234,18,59,964,269,176,866,170,2,69,359,847,754,948,946,249,203,301,196,484,35,215,976,198,467,127,64,470,244,489,660,513,175,419,408,905,677,219,553,646,82,913,369,787,667,81,949,27,508,399,256,144,161,890,647,225,393,14,499,812,967,703,67,668,481,980,17,672,690,567,687,438,731,93,938,235,811,768,427,280,82,209,588,364,822,199,302,750,342,666,898,116,392,526,941,128,765,966,367,175,843,695,399,97,359,130,263,950,579,424,442,332,727,460,295,387,755,40,776,593,899,51,761,859,482,172,48,766,466,771,996,34,781,540,301,631,200,298,275,121,290,337,269,543,575,101,747,551,191,417,529,179,651,847,155,72,126,653,839,602,223,687,621,157,528,696,817,617,812,555,744,151,529,106,388,920,712,216,633,562,324,853,476,509,6,882,282,266,418,515,714,394,521,344,369,364,314,883,44,382,924,789,143,353,471,603,132,326,737,370,342,636,0,675,707,408,295,385,701,16,945,480,891,207,766,525,473,992,418,466,920,298,680,902,58,474,912,126,153,478,561,521,4,629,422,634,737,570,737,898,124,249,579,100,166,730,590,385,672,552,865,818,274,308,457,652,423,926,211,846,889,535,834,982,426,847,635,381,992,973,853,834,561,317,104,810,898,159,42,718,809,566,687,270,503,553,955,629,458,447,786,447,575,195,236,168,464,281,129,749,629,251,947,604,225,391,905,92,393,178,623,768,385,779,456,850,858,6,733,603,928,934,369,547,865,202,589,527,660,302,401,576,624,54,74,524,764,170,561,609,946,279,192,91,846,269,517,286,383,351,975,714,759,479,124,309,747,97,889,341,884,211,447,65,763,114,785,40,837,11,390,707,35,35,884,593,110,139,61,78,185,443,602,285,831,177,948,650,133,567,88,392,204,162,416,429,556,927,60,543,371,188,352,890,303,547,378,656,217,554,169,734,298,708,973,632,742,29,36,65,907,960,429,313,6,853,349,738,900", "523,840,618,831,359,683,24,133,913,850,40,754,245,77,847,425,614,741,789,433,294,152,459,70,256,31,479,267,448,191,581,967,766,989,417,430,133,696,192,615,665,798,740,526,287,215,598,665,789,376,599,428,277,435,132,888,621,643,68,561,946,87,36,574,548,296,332,69,653,345,294,773,845,47,166,261,627,66,253,948,710,613,512,492,1,244,846,928,511,81,325,668,657,691,580,482,683,872,31,876,67,35,90,494,903,468,246,730,54,653,758,593,676,573,106,848,869,985,690,636,794,611,873,865,704,922,658,83,240,570,981,360,877,23,750,96,734,543,383,454,510,189,462,906,613,356,510,348,652,387,13,35,341,559,415,122,591,977,801,410,446,150,907,399,55,530,774,930,790,200,586,211,276,528,34,486,707,979,902,488,538,42,742,193,954,843,642,675,787,93,163,276,386,746,266,890,450,742,823,443,728,244,820,353,697,237,360,376,846,346,495,330,989,66,601,919,916,610,825,418,937,577,606,273,394,100,537,8,499,501,977,255,965,142,785,227,409,945,582,250,491,218,705,803,637,701,528,726,730,282,793,883,564,762,304,504,757,98,173,896,980,771,560,148,668,799,602,341,475,458,701,98,326,820,812,904,72,176,309,284,843,148,577,884,122,518,277,911,204,765,735,986,153,176,627,185,798,780,915,466,783,306,519,938,288,326,416,549,779,819,539,477,337,26,486,543,647,878,88,129,125,696,266,565,924,392,932,944,874,343,438,288,979,447,357,769,905,72,632,320,905,653,180,668,228,339,59,27,659,752,518,360,980,73,359,729,170,451,311,33,3,823,256,947,278,602,509,56,206,175,732,568,14,336,883,364,600,532,374,299,449,624,807,785,831,273,391,371,856,94,727,948,58,312,513,7,168,914,80,277,160,7,434,444,906,238,612,664,651,509,476,141,745,10,266,842,932,892,800,742,234,296,871,923,659,964,408,830,233,591,661,978,453,153,462,122,942,680,653,363,317,412,869,618,688,278,859,232,803,896,740,935,787,713,886,990,470,493,973,536,881,407,53,326,964,750,88,389,954,277,254,287,519,685,384,300,35,777,263,615,738,540,242,789,29,981,196,884,340,91,387,711,81,72,618,932,826,537,931,344,405,69,964,199,554,234,647,829,338,264,489,682,95,601,692,253,761,827,241,715,470,848,791,620,976,653,555,476,534,924,884,312,960,299,83,737,776,449,441,383,642,189,577,918,619,457,223,994,685,260,873,649,536,692,741,239,808,368,247,452,927,479,5,548,942,919,754,721,600,261,356,994,281,23,229,835,234,372,781,170,932,409,868,218,765,584,761,35,619,912,977,66,637,728,934,398,749,660,527,914,653,454,893,729,266,40,957,505,257,33,125,302,975,676,239,529,467,293,793,823,574,261,428,115,638,781,872,161,667,546,936,70,214,373,941,564,927,860,94,282,296,773,741,206,96,511,20,578,488,85,924,684,902,386,514,4,82,172,750,265,255,143,670,303,935,656,329,446,38,695,441,834,147,229,518,712,875,327,855,201,101,700,281,49,521,625,292,812,480,91,793,142,527,333,532,315,979,742,17,578,715,170,133,632,585,981,398,565,72,640,374,96,842,308,814,422,101,846,595,690,844,385,966,515,142,776,129,83,519,289,794,502,632,217,55,67,863,819,137,803,270,596,513,37,174,243,765,399,163,655,136,836,130,142,355,35,269,847,486,840,845,970,928,316,188,165,69,149,743,790,375,488,107,675,0,784,560,336,845,376,656,301,870,540,63,541,380,540,267,975,388,263,374,346,979,183,122,768,668,286,176,536,764,60,894,766,97,278,298,391,296,349,946,134,359,837,805,97,209,206,138,603,245,919,165,482,467,735,781,504,590,771,454,488,777,490,522,894,911,73,627,984,820,906,399,884,993,865,269,811,585,441,955,565,165,954,589,860,588,745,999,964,428,763,822,376,725,760,840,622,995,59,478,536,368,656,259,447,203,948,726,690,45,251,21,609,470,7,619,5,886,307,952,283,720,988,67,426,616,771,776,90,798,447,803,802,240,375,142,384,60,882,1,897,205,931,259,675,671,570,602,959,829,245,331,526,782,621,888,399,363,50,665,652,167,499,480,485,127,706,823,761,584,264,315,695,927,517,177,626,273,503,316,382,222,809,250,461,355,549,797,196,64,811,698,4,484,790,949,695,129,803,545,574,86,442,168,469,954,311,139,205,553,363,369,309,674,816,786,505,879,593,506,380,557,787,708,833,139,428", "275,748,760,92,276,555,35,710,713,807,914,481,609,729,290,538,298,169,210,860,957,580,159,877,992,484,587,766,160,949,179,223,3,540,788,76,706,267,837,362,465,331,391,801,505,4,617,817,354,106,367,629,192,492,438,186,450,599,4,100,223,132,96,645,536,280,666,986,686,726,476,721,53,748,272,327,584,485,362,14,253,371,351,1,330,351,875,543,980,823,159,553,565,243,51,997,840,507,180,618,875,605,385,131,793,911,755,1000,137,128,259,447,794,544,922,117,768,322,870,597,336,29,585,207,890,172,737,332,935,679,799,21,686,376,1000,544,472,597,236,198,499,37,936,982,493,207,647,118,901,413,734,158,827,956,164,397,530,878,837,819,856,38,787,535,472,732,327,719,26,252,374,427,723,470,45,787,479,320,957,807,613,498,635,259,585,335,420,871,413,381,990,834,628,249,800,583,424,935,728,64,467,182,717,96,930,108,99,687,753,101,225,748,879,832,297,984,20,209,747,718,147,731,799,509,86,309,11,320,130,418,353,334,378,665,301,169,170,473,637,435,720,765,493,845,92,144,401,225,434,17,293,33,313,750,547,576,476,72,264,334,250,985,187,68,69,855,528,182,27,101,681,750,907,119,331,105,358,390,719,26,39,612,728,937,435,910,611,584,360,206,608,961,390,464,909,634,487,534,938,238,430,295,72,263,586,87,729,575,201,594,199,170,414,62,870,416,584,61,393,141,592,442,933,702,677,974,396,532,808,360,864,767,839,206,336,27,867,379,985,577,549,664,73,293,114,495,602,317,324,682,117,729,644,168,461,462,610,18,964,291,340,613,540,302,635,187,649,564,555,417,261,238,494,920,945,814,746,625,290,650,856,359,106,980,263,521,88,638,342,819,302,573,617,707,370,155,743,760,648,423,946,512,573,209,504,69,449,754,506,100,733,817,421,657,91,948,773,526,97,274,583,306,682,532,529,651,52,368,587,21,684,347,83,610,95,757,682,887,78,734,24,254,24,709,74,306,93,587,898,750,259,720,765,505,779,920,584,616,694,797,305,692,705,45,40,858,228,968,650,415,718,220,933,540,540,813,20,747,361,321,561,585,113,593,426,151,256,210,30,592,669,820,94,203,130,385,332,45,85,126,662,583,443,746,730,803,116,355,57,183,970,91,253,667,21,337,649,338,150,380,211,33,831,683,512,918,457,110,491,987,528,233,67,361,997,222,511,943,550,222,31,111,604,415,222,599,92,794,68,373,409,598,347,463,743,60,180,755,124,229,804,704,402,531,812,109,511,268,613,88,463,549,718,590,716,455,296,574,526,892,849,887,298,416,91,950,998,62,514,224,138,202,210,268,599,470,423,680,951,877,282,879,439,854,509,918,997,716,263,565,646,568,883,935,111,179,280,120,652,481,668,709,553,894,118,446,710,185,686,129,798,7,793,256,662,404,936,756,441,316,462,227,558,918,455,749,193,716,349,798,60,696,825,871,991,866,411,382,927,367,99,55,554,387,60,406,585,928,777,444,281,587,586,633,63,701,69,172,217,327,476,874,464,484,522,65,552,125,753,823,984,657,191,401,309,258,780,910,204,534,503,333,936,631,317,97,427,360,199,915,965,653,360,837,301,66,505,287,922,409,579,273,288,170,172,885,961,863,873,581,887,808,762,510,950,328,653,242,833,718,167,888,546,867,454,224,755,206,478,996,818,904,678,710,766,831,925,581,530,749,931,869,61,321,138,679,616,74,549,642,68,690,735,707,784,0,401,946,634,265,46,321,584,544,728,218,697,478,363,437,881,777,458,322,982,75,65,679,667,287,352,332,96,990,793,349,823,175,855,210,145,43,773,436,417,251,290,861,46,840,211,876,329,704,302,85,884,83,350,652,376,406,796,150,169,758,422,72,399,633,118,352,429,997,799,469,518,125,417,531,866,408,501,925,54,291,248,409,692,653,802,896,107,524,555,352,365,200,144,75,48,189,410,263,734,250,516,69,546,446,186,187,466,598,751,40,25,260,297,820,522,24,956,835,859,791,488,765,362,166,151,492,382,737,587,487,777,408,750,600,79,41,741,850,401,456,451,421,624,434,717,660,496,951,593,693,112,171,105,688,790,917,785,211,212,877,428,412,338,176,49,347,835,657,441,385,100,888,787,788,93,566,425,886,536,697,877,245,34,981,284,639,817,288,599,876,770,247,975,191,598,493,555,618,319,242,431,542,890,287,23,728,750,627,494,704,645,978,967,630,162,197,780,361,203,934,41,673,74,264", "968,901,943,846,533,710,537,763,304,79,983,890,918,585,718,733,792,701,827,994,279,406,796,882,258,676,876,994,229,946,105,994,777,985,630,785,65,522,729,43,359,895,764,364,981,731,332,701,655,321,849,915,16,415,642,308,123,957,372,817,307,23,581,329,68,158,526,65,778,307,862,2,347,863,948,665,231,810,918,139,456,530,520,131,967,447,726,267,997,318,984,225,891,518,378,958,472,106,784,63,625,889,520,611,146,664,385,793,356,898,498,57,350,939,831,503,858,440,247,838,286,850,927,327,924,702,693,834,966,632,305,785,335,848,926,863,824,300,945,82,262,238,718,565,726,7,951,123,680,586,322,543,674,460,196,944,459,952,800,880,841,485,111,561,158,280,171,661,479,58,196,191,947,503,82,524,432,671,746,734,350,184,817,242,40,466,917,478,220,287,18,207,902,718,973,954,324,154,831,642,590,610,258,451,254,626,851,697,143,693,436,666,16,677,324,767,92,185,884,741,928,49,653,818,26,441,333,312,440,36,348,360,727,944,949,885,475,853,295,893,279,674,687,226,927,752,19,982,354,564,339,689,313,384,129,386,827,898,144,801,201,877,738,911,331,762,533,515,176,872,620,246,842,708,210,420,730,434,120,867,273,414,728,462,452,538,479,470,113,191,766,226,167,309,661,568,625,280,188,653,981,441,323,567,440,486,353,11,607,223,175,122,743,423,427,56,554,718,11,108,389,913,998,615,485,971,895,433,95,896,661,427,570,547,843,988,46,800,518,620,208,778,939,237,315,461,810,922,123,690,317,891,190,236,300,322,662,510,977,627,49,43,315,877,932,804,339,912,953,813,751,583,245,791,65,894,193,812,663,574,508,98,176,944,519,195,912,472,564,611,5,401,135,33,933,919,49,177,528,819,782,236,925,839,418,944,720,223,207,264,525,124,768,121,870,837,838,371,344,694,836,729,733,463,340,931,449,313,814,592,215,599,375,348,392,682,395,307,75,248,748,139,444,436,47,752,245,47,252,650,583,574,362,354,270,174,111,989,821,533,313,337,786,481,90,434,88,953,489,600,986,510,810,35,77,926,113,249,33,698,900,71,920,936,569,524,219,651,815,652,105,412,154,392,928,935,474,935,64,818,356,250,583,341,146,552,66,475,859,378,22,591,131,506,479,69,902,558,500,948,874,71,120,442,983,351,531,190,241,728,208,187,39,28,397,500,141,432,517,227,105,556,866,66,960,537,134,613,628,191,472,195,488,910,755,394,841,724,428,138,738,507,565,432,627,757,921,139,199,221,12,375,965,733,781,135,443,955,613,399,900,39,119,905,652,382,371,243,943,83,634,818,94,857,432,356,29,963,475,865,20,771,511,942,231,152,693,361,687,870,547,253,221,605,756,223,63,55,849,902,657,307,627,664,565,539,33,81,341,400,106,267,387,185,124,303,350,705,326,529,813,920,269,551,851,744,357,768,941,385,478,344,971,721,621,170,468,724,607,250,282,828,915,94,533,551,621,847,399,384,364,773,362,814,63,935,702,124,615,61,834,898,738,419,262,729,855,62,420,262,560,865,591,507,134,922,132,694,452,575,259,69,929,172,308,782,652,542,351,879,424,951,898,229,774,895,520,798,151,161,983,914,49,602,306,924,924,671,370,634,707,354,279,855,826,248,115,178,527,331,189,225,236,293,318,910,265,755,434,11,49,970,938,465,27,114,629,942,494,259,75,375,855,544,352,982,335,117,246,66,905,752,823,408,560,401,0,589,411,925,807,370,702,826,46,561,277,157,348,978,472,517,893,906,917,588,706,953,581,786,623,53,235,414,543,430,239,582,947,969,138,407,513,463,51,671,482,379,189,972,563,638,612,59,588,500,451,841,859,328,478,594,271,618,970,714,409,775,259,424,151,569,154,883,16,312,941,397,348,890,693,395,419,963,554,880,483,396,486,300,565,626,420,774,931,500,719,479,223,200,522,133,493,553,105,966,130,625,125,751,304,754,193,826,912,213,122,117,18,796,754,648,358,468,360,223,335,578,785,734,741,35,427,249,140,238,245,819,454,675,365,718,833,40,906,657,170,136,956,160,564,47,366,304,682,816,397,497,319,971,342,314,147,388,699,839,142,617,69,457,458,532,150,315,913,191,60,294,378,831,846,234,714,371,64,511,989,517,534,723,353,166,471,492,670,217,104,127,460,446,620,107,773,773,318,285,964,45,335,558,680,152,490,589,972,916,505,59,891,325,885,309,108,281,901,34,177,462,880,501", "342,385,24,775,921,68,311,302,195,891,394,916,317,36,777,775,616,869,471,143,714,149,499,172,448,432,554,547,898,365,101,909,711,379,446,223,652,254,121,635,233,585,190,228,928,332,684,928,491,985,380,242,900,384,590,234,242,961,476,81,183,36,204,593,352,428,951,664,352,481,648,79,866,929,95,500,836,369,399,665,669,232,259,664,424,834,561,913,910,490,287,710,366,142,266,665,409,833,725,102,767,701,569,257,863,98,144,656,997,379,779,207,144,226,845,768,728,911,941,134,420,296,882,348,838,661,664,427,316,384,6,433,531,298,39,722,422,324,846,544,666,881,941,657,781,563,144,599,231,491,964,483,46,161,164,71,250,255,94,525,555,16,95,753,142,689,898,331,857,681,773,29,651,417,74,957,760,905,790,582,976,112,97,125,669,934,223,612,858,92,87,74,729,150,591,511,278,128,598,384,111,155,908,957,181,790,322,565,227,512,925,800,403,267,572,981,435,122,929,283,573,205,818,185,698,85,640,368,222,636,384,267,953,73,643,304,39,319,715,975,486,474,155,957,857,247,168,14,859,317,683,199,318,464,465,304,907,660,243,888,15,487,661,584,334,25,886,912,754,685,477,32,546,912,878,489,504,197,637,530,885,72,824,297,393,313,476,712,739,190,393,255,248,438,240,184,70,316,324,262,293,464,656,943,180,742,477,841,792,902,495,468,546,273,200,823,629,200,891,130,450,488,839,628,789,267,280,78,423,765,934,532,8,265,829,995,396,34,710,783,670,604,742,332,914,595,172,191,473,809,624,527,831,521,47,232,117,452,223,705,37,124,877,183,434,380,846,309,187,101,614,411,352,727,231,377,834,955,371,563,794,650,576,531,204,456,106,187,582,278,498,185,802,539,484,466,4,384,409,883,965,525,767,20,588,15,697,14,67,29,276,220,664,189,423,404,844,267,773,362,182,321,611,171,325,5,878,574,210,39,216,728,740,880,894,862,556,333,509,950,853,465,254,77,6,494,826,376,63,454,796,463,287,611,612,350,375,619,798,902,479,239,34,383,752,170,842,924,653,970,383,340,454,92,247,802,41,48,574,663,726,256,258,706,503,127,812,652,149,904,635,870,844,706,9,492,703,572,613,964,143,850,606,815,514,251,886,304,505,378,892,223,639,924,69,733,295,511,200,340,281,312,773,422,128,748,961,683,433,548,926,447,485,867,26,262,520,970,591,172,510,672,564,607,326,190,438,379,365,122,46,925,325,532,470,610,12,538,359,732,923,547,359,993,268,178,793,776,485,828,29,864,217,265,389,873,844,137,309,173,878,76,766,657,436,131,433,846,444,418,646,654,680,908,567,754,556,786,915,616,107,701,207,809,42,383,344,590,756,752,628,883,34,804,583,143,858,90,181,679,530,391,501,257,864,273,545,743,29,719,702,230,111,266,461,459,3,491,959,306,843,257,936,523,490,25,935,621,839,145,291,700,953,488,455,19,530,652,466,395,348,462,97,805,793,3,871,691,5,56,803,184,648,280,975,257,278,882,274,211,338,763,562,299,99,198,430,788,302,599,780,985,401,500,77,536,532,911,489,144,939,275,294,664,915,822,91,878,814,503,133,726,226,989,964,149,830,294,735,780,435,394,349,913,332,379,600,727,893,715,350,48,251,256,708,211,178,226,171,586,693,511,411,144,957,397,198,495,21,343,461,243,177,899,943,625,40,661,530,651,71,178,368,780,669,311,520,84,592,35,151,784,947,295,336,946,589,0,881,276,232,839,80,618,310,64,357,204,468,499,81,536,197,404,246,642,598,364,448,40,168,706,45,770,709,150,269,18,154,798,271,966,92,502,382,222,989,148,373,417,513,507,290,644,993,688,646,521,362,501,930,124,964,369,471,790,226,522,786,476,974,999,88,453,603,556,680,964,499,326,137,334,486,563,857,707,127,765,750,354,156,261,175,541,157,695,507,22,825,289,332,335,144,361,161,347,614,82,468,553,869,372,315,927,29,723,135,25,338,782,239,11,254,734,127,877,387,228,523,202,970,698,774,863,394,31,560,121,151,929,289,223,543,491,704,886,945,49,478,236,664,177,982,546,515,920,340,930,152,463,217,546,763,11,415,350,246,649,341,127,97,246,108,808,194,9,526,931,718,535,364,873,951,297,162,724,994,266,427,887,375,775,50,683,6,6,473,694,280,800,110,929,293,509,398,110,538,722,114,263,827,28,956,59,985,349,790,734,637,418,201,377,493,921,360,141,22,655,540,260", "759,514,834,142,150,186,783,548,235,683,939,648,355,546,714,857,755,274,946,741,886,731,448,942,66,961,219,699,343,756,270,303,382,248,319,305,693,874,584,150,895,877,75,229,29,14,736,981,574,2,786,397,473,303,61,6,107,465,134,34,387,314,28,503,445,210,348,848,58,979,312,544,322,146,542,606,426,513,510,799,804,243,409,666,80,615,483,287,815,183,142,758,891,932,775,749,79,374,333,799,222,535,802,234,903,152,836,334,948,334,326,520,122,604,376,253,937,360,140,269,467,894,446,673,887,569,156,241,675,338,671,38,365,92,640,807,706,899,419,197,860,785,691,533,583,652,595,359,549,784,829,717,223,908,317,543,372,315,613,767,459,894,813,628,265,771,257,496,808,530,7,970,893,479,257,446,986,851,7,700,863,563,405,982,521,874,794,699,575,825,130,923,352,659,843,711,204,685,48,116,313,189,59,222,35,213,371,49,183,488,336,343,852,636,161,221,623,719,887,207,987,426,510,397,765,59,651,938,597,303,867,278,516,383,825,665,470,935,457,240,80,300,170,992,744,988,836,511,960,953,653,322,421,28,6,693,593,974,613,261,87,996,1,175,124,752,46,634,747,209,523,319,823,17,909,974,773,345,283,285,60,839,334,393,214,207,963,430,327,6,89,291,161,563,265,538,264,759,461,66,402,371,53,598,603,421,400,830,857,546,240,339,565,812,889,934,912,328,110,158,231,590,482,415,94,189,854,781,634,101,216,585,706,966,88,453,881,341,430,702,151,738,313,284,517,344,795,166,850,265,235,768,290,262,652,733,684,602,666,21,263,351,712,879,105,612,266,373,792,902,586,407,802,541,401,873,105,566,819,463,709,651,365,490,451,449,2,688,235,321,611,95,359,331,443,667,264,170,117,122,659,217,905,727,655,685,992,180,204,114,367,468,136,291,976,200,714,513,888,696,934,114,723,609,673,369,378,26,873,764,775,637,908,348,107,805,962,340,565,571,718,214,720,543,222,54,835,12,3,725,379,428,508,599,566,705,863,258,806,284,935,783,250,617,428,430,362,935,414,536,641,481,172,725,809,967,494,146,102,291,435,309,727,777,396,832,743,711,955,591,949,486,612,823,466,192,487,949,566,404,110,461,716,164,140,630,421,984,491,921,235,691,166,44,657,143,215,473,92,802,877,13,862,190,172,889,380,819,588,615,262,972,647,464,781,334,423,885,995,915,489,307,590,105,457,562,814,790,187,431,988,608,916,92,425,240,220,405,85,287,664,875,248,573,538,991,523,491,843,404,638,866,676,690,911,988,24,214,761,864,343,705,692,235,928,410,971,760,528,644,174,136,32,551,429,242,806,662,125,867,43,260,61,556,446,343,765,884,251,91,171,715,498,770,992,367,671,59,935,233,590,509,890,323,37,811,369,488,18,129,26,407,840,968,848,988,611,297,690,780,931,141,608,383,141,763,894,68,395,115,419,374,213,391,837,603,176,904,365,732,119,88,693,605,860,953,419,363,955,134,40,455,766,515,657,142,345,662,666,294,440,222,58,961,93,861,494,19,145,23,984,296,102,434,844,150,155,773,754,300,670,944,516,725,684,174,666,539,414,796,939,90,9,356,635,658,988,550,368,793,810,847,882,568,811,250,899,166,915,924,446,544,594,225,878,861,410,983,945,465,419,792,188,647,937,408,833,861,597,2,874,849,280,833,785,152,552,6,371,238,663,832,178,356,155,225,963,435,669,642,607,609,627,385,845,634,411,881,0,411,475,716,354,563,855,856,496,999,949,672,22,714,265,530,880,321,792,44,435,922,436,620,2,291,501,58,710,975,13,463,557,974,897,282,648,4,163,67,774,343,629,232,903,322,619,915,371,677,695,395,667,18,720,422,106,582,194,501,293,321,694,220,789,115,633,590,265,830,527,758,585,169,345,594,162,231,49,132,284,165,528,994,78,756,781,650,997,531,171,771,579,548,88,418,723,808,207,640,769,83,227,704,511,839,326,382,548,482,815,539,863,905,612,848,652,686,474,995,728,459,147,556,754,12,657,705,950,201,453,247,815,3,245,466,637,261,999,98,571,600,212,668,503,950,852,215,575,769,796,268,662,733,794,603,546,484,904,797,897,854,501,440,535,286,479,763,352,980,156,553,548,654,256,551,83,803,330,301,11,148,317,185,261,657,272,765,769,820,542,350,806,164,490,88,604,241,166,350,309,633,206,110,128,105,35,402,473,756,76,359,620,512,282,336,935,488,527,276,446,813", "765,720,426,839,496,640,799,843,708,448,358,678,222,154,154,98,650,120,997,320,892,308,354,934,102,205,607,702,94,599,582,833,671,3,555,893,438,612,84,266,22,818,266,104,949,895,970,421,179,376,229,955,709,80,729,93,139,710,470,35,571,800,582,899,908,393,152,540,448,718,831,918,85,541,165,491,60,24,841,487,859,276,944,929,256,685,466,958,895,954,58,410,959,748,214,618,471,281,676,976,122,283,832,27,633,725,22,770,102,446,581,30,113,424,347,485,910,157,290,770,88,92,269,756,766,179,443,222,643,606,860,163,931,808,977,666,395,700,67,553,122,770,723,337,90,756,121,439,948,796,853,744,156,183,991,62,999,24,325,428,58,99,919,774,582,43,634,953,516,599,984,23,440,745,465,136,44,307,94,981,553,977,424,900,520,191,539,881,998,401,764,203,15,385,74,603,119,271,500,153,113,232,403,291,876,29,906,813,759,385,638,809,547,541,786,920,200,616,461,185,877,396,675,749,585,287,312,50,408,69,890,886,898,824,308,343,217,739,307,499,913,184,390,495,658,245,752,253,808,477,480,496,342,110,534,362,811,279,581,810,592,668,654,711,808,673,299,154,605,77,382,4,233,862,114,168,919,76,232,151,332,940,928,372,743,499,583,488,9,319,500,545,866,234,153,225,191,424,427,491,890,536,990,49,923,907,684,336,682,712,238,374,332,959,633,476,608,707,647,743,246,136,659,312,39,473,183,747,995,81,994,301,17,583,63,459,252,558,179,280,862,213,158,235,938,815,468,653,996,593,783,830,252,263,277,607,381,439,887,481,546,844,115,964,344,301,865,304,429,792,391,129,704,88,733,542,809,427,834,446,661,773,395,650,530,483,528,49,112,99,566,122,461,33,309,367,291,448,642,465,693,214,680,400,784,249,97,312,87,592,708,63,163,883,595,810,597,121,235,712,639,323,884,615,203,298,262,757,244,685,912,818,23,304,229,788,987,182,121,136,863,805,424,962,240,353,382,471,242,534,576,87,286,860,917,89,546,772,186,785,689,48,358,641,892,698,140,327,936,814,26,731,896,960,280,254,330,859,992,915,85,47,514,527,800,687,52,620,960,113,970,833,664,445,808,937,535,123,74,79,895,439,360,320,995,139,818,607,565,478,481,94,39,506,880,746,243,266,783,606,115,830,64,659,714,869,832,445,349,908,233,869,990,279,526,793,551,178,332,714,126,384,645,52,807,882,559,136,494,257,192,164,994,885,850,697,144,840,411,480,145,40,402,567,277,370,765,61,34,707,953,872,416,265,827,933,664,737,924,68,91,806,35,536,505,28,151,193,14,98,284,889,131,588,512,398,680,278,242,331,497,814,610,373,140,632,717,163,325,740,735,529,798,857,284,264,523,104,192,196,184,311,933,370,447,478,158,725,440,527,107,954,693,688,445,807,711,253,162,48,771,398,539,868,730,301,854,277,572,167,375,51,44,846,506,629,433,136,619,668,521,930,225,322,273,496,451,419,748,844,344,329,913,429,720,952,169,598,295,837,617,823,169,242,110,59,445,685,354,108,396,585,727,342,49,341,394,233,324,151,938,286,897,46,217,453,353,66,418,150,811,832,966,88,760,522,214,953,239,398,656,870,483,781,158,949,586,998,908,548,45,553,903,455,400,120,780,583,834,79,908,675,88,683,102,850,437,579,740,268,280,532,722,379,900,516,742,408,418,215,278,227,879,790,570,85,198,844,724,884,392,972,677,701,376,265,925,276,411,0,509,899,855,439,140,882,829,266,310,397,280,183,994,996,338,878,531,256,172,910,847,163,696,19,685,710,507,607,600,314,45,722,737,114,935,753,705,5,637,68,981,245,988,922,134,637,230,804,712,182,708,149,545,384,331,370,402,946,698,44,451,350,763,744,126,401,927,735,120,742,672,570,411,24,220,503,886,569,838,326,117,768,503,465,930,986,750,437,969,256,384,101,17,377,307,188,523,817,678,175,818,671,632,309,115,977,489,778,733,639,437,468,535,11,542,922,468,721,838,757,277,38,30,523,338,521,601,907,312,726,857,364,319,313,513,617,845,97,110,212,354,795,383,81,485,209,841,963,500,569,206,440,660,2,147,765,278,959,284,63,525,356,127,140,264,898,101,563,215,83,414,394,816,46,716,845,500,365,604,725,969,526,407,634,352,592,973,932,13,594,106,137,390,116,824,773,343,125,865,645,760,665,963,518,279,861,316,22,602,669,631,70,934,138,704,76,634,706,530,872", "907,113,894,268,606,200,657,55,176,559,665,152,572,983,628,12,655,37,228,625,9,71,566,288,100,547,348,266,474,479,995,868,344,824,31,44,44,228,444,398,248,663,720,132,835,604,699,44,870,167,80,495,368,401,837,456,639,495,423,469,996,290,538,149,234,996,505,530,591,508,17,436,233,265,446,20,131,782,318,708,637,501,928,527,83,572,179,860,385,565,84,301,615,100,712,425,356,115,611,206,739,683,887,505,298,713,14,394,341,859,616,756,801,100,855,265,351,950,32,307,303,157,195,458,340,167,336,513,949,809,655,656,770,447,208,166,579,682,333,98,750,47,55,625,156,237,610,263,902,178,103,113,170,412,374,292,505,306,215,390,529,800,217,668,531,513,459,354,130,578,198,688,160,721,724,86,925,425,53,673,679,201,667,952,289,939,168,877,605,711,314,292,578,403,572,412,642,797,356,954,810,409,41,463,238,730,681,146,247,663,183,642,738,422,119,938,308,852,42,150,71,213,988,159,303,867,297,12,741,877,416,37,54,987,384,94,131,443,941,216,730,663,548,270,181,91,27,408,951,978,11,928,1,200,221,650,814,297,414,746,898,919,151,969,347,799,877,423,579,861,977,690,724,679,384,378,683,846,151,9,999,64,772,673,585,787,959,536,221,655,690,563,846,183,362,272,343,661,813,110,845,790,511,638,535,35,911,625,720,604,31,233,810,805,489,568,227,129,649,185,858,355,925,624,322,440,153,734,1,441,279,277,951,520,346,492,784,949,23,640,957,944,392,388,960,107,419,987,500,818,55,653,290,881,5,963,447,727,871,65,65,868,358,55,940,423,796,995,755,850,499,659,109,448,968,64,654,429,397,992,378,467,771,246,28,694,874,546,100,262,900,450,355,140,7,252,693,641,92,236,564,68,76,808,786,710,145,807,543,217,4,117,322,427,819,234,100,280,986,132,76,632,685,609,808,329,73,943,350,926,485,729,475,764,287,356,593,580,354,679,7,642,542,867,409,844,518,952,665,820,348,658,879,269,818,277,980,459,504,602,748,369,444,908,350,577,820,430,359,331,2,321,583,188,507,419,74,511,978,172,672,765,647,154,604,104,264,349,432,798,834,504,997,820,704,942,717,739,187,152,236,814,62,349,757,179,973,289,362,670,376,592,309,857,183,632,275,75,173,435,387,351,919,766,233,268,582,475,440,827,522,730,623,15,331,772,353,207,482,314,512,723,42,737,546,973,544,37,455,246,468,539,830,276,765,806,911,652,24,729,599,862,978,555,980,335,11,136,302,988,359,649,64,544,282,34,451,252,33,665,700,233,507,648,780,430,2,22,301,665,703,686,318,434,490,589,169,494,909,487,476,595,231,764,915,513,546,199,53,62,595,726,518,2,874,521,652,383,616,622,152,167,798,277,461,858,545,761,221,921,100,901,677,905,576,695,650,407,899,684,217,446,988,714,208,601,604,561,924,132,796,582,224,674,11,613,583,552,783,670,37,878,952,36,213,855,272,930,578,927,139,571,379,289,863,559,749,943,797,30,140,742,29,85,4,855,751,673,766,731,60,836,419,154,307,322,408,507,811,246,29,256,360,265,478,198,916,293,476,449,198,895,237,191,97,560,339,469,639,460,436,48,920,526,35,675,735,218,805,135,895,358,998,719,438,371,31,718,683,699,580,307,829,957,653,503,266,624,885,93,607,830,700,783,627,518,37,114,589,313,555,182,903,523,366,758,31,37,260,164,568,418,332,16,656,46,807,232,475,509,0,170,397,926,292,766,59,81,706,440,38,598,460,705,773,859,637,211,451,975,643,562,609,509,356,837,344,60,154,727,891,229,582,769,889,350,492,204,377,42,752,95,639,8,699,952,165,466,395,547,975,646,20,4,78,16,829,588,887,231,809,137,82,660,282,817,745,254,930,378,455,546,220,239,961,860,142,920,7,443,675,428,940,809,976,858,202,637,380,970,856,826,136,162,546,449,4,113,929,710,822,358,776,488,861,392,682,12,851,89,955,634,847,183,311,136,987,410,469,233,254,729,759,708,113,890,87,758,974,706,682,989,553,657,398,918,776,590,372,619,874,610,746,659,110,799,607,635,194,734,627,839,285,360,21,341,880,998,913,460,663,594,141,441,227,605,601,761,563,622,187,439,601,420,500,764,118,907,514,346,340,488,259,482,928,604,115,210,691,160,743,986,479,806,797,178,977,670,852,411,787,78,187,670,204,92,305,382,454,949,337,461,919,8,107,684,729,428,991,796", "624,972,126,538,147,301,11,568,495,195,474,116,437,58,885,11,430,958,312,567,911,206,103,446,864,314,761,424,734,931,180,381,845,731,517,840,232,775,41,405,237,727,258,680,5,178,867,256,70,212,204,533,538,842,664,444,658,959,280,819,448,296,120,130,244,127,166,413,923,601,408,786,165,442,715,948,561,139,851,908,409,91,597,136,28,661,894,824,345,319,155,785,804,161,599,669,449,697,399,189,505,668,516,137,901,765,433,767,275,289,17,210,89,928,455,205,696,960,720,162,117,718,683,769,524,363,143,559,48,519,991,378,974,83,631,380,567,643,718,4,74,645,86,692,860,487,609,987,143,508,851,86,685,158,908,491,744,618,533,230,309,215,715,761,556,268,891,302,870,255,237,200,95,432,814,639,113,966,181,783,109,905,829,798,447,715,606,564,559,355,362,444,704,501,737,876,315,155,683,808,574,186,460,517,753,43,128,463,706,392,762,181,568,106,659,70,556,708,468,518,323,262,914,804,687,51,333,987,501,273,681,855,535,650,892,666,114,885,218,137,86,26,387,638,525,245,892,138,206,76,709,583,224,940,235,584,750,65,134,580,668,716,244,263,201,802,906,94,848,91,568,477,788,496,500,584,241,694,234,746,266,806,987,468,82,265,797,995,8,803,551,823,519,643,558,32,962,934,970,670,675,514,307,913,876,155,128,501,262,522,755,39,310,962,106,167,63,608,334,719,54,979,118,498,60,213,419,521,841,664,161,828,642,94,779,3,246,958,694,137,547,52,549,614,104,895,262,651,294,656,898,152,467,58,219,628,665,137,447,389,296,899,392,247,635,970,428,236,296,807,147,690,581,289,674,31,426,280,683,70,317,762,824,758,865,737,981,972,787,380,794,314,750,152,339,473,906,384,931,192,904,270,245,927,594,404,363,950,15,394,686,760,687,137,656,503,836,336,206,817,348,208,397,425,232,228,269,115,5,338,857,160,377,636,50,424,730,757,221,582,640,562,986,931,421,777,509,179,252,617,984,894,709,457,495,642,798,473,253,231,115,807,9,173,793,121,576,163,539,153,122,723,291,926,154,672,891,128,306,278,482,120,611,27,116,804,929,168,243,751,70,546,257,938,289,638,136,744,911,183,327,182,644,607,114,427,596,774,592,330,703,556,464,697,75,580,205,18,184,459,108,797,735,736,641,3,301,92,342,754,126,223,520,897,509,879,278,277,73,694,953,5,931,294,36,792,736,483,560,956,26,933,371,252,609,359,327,154,632,550,704,380,894,693,127,144,580,444,478,849,251,896,761,630,673,831,591,782,430,573,916,720,186,635,226,56,309,277,368,278,959,566,229,973,265,311,53,650,112,177,10,857,678,184,441,298,917,955,908,295,429,197,338,734,845,852,692,544,444,326,174,691,125,256,265,240,835,32,692,49,358,236,735,381,928,40,479,379,721,66,958,966,681,973,955,991,874,277,85,523,445,190,632,393,790,902,277,513,226,479,713,221,752,85,799,861,776,953,324,748,221,894,400,278,504,891,383,223,21,771,972,862,552,497,812,365,278,868,215,939,387,205,711,484,774,509,146,747,254,41,534,780,964,874,510,172,602,564,820,54,53,499,276,658,215,238,29,345,349,998,48,760,458,700,535,78,872,632,433,587,843,455,89,138,549,830,500,498,209,818,289,201,425,851,157,704,534,371,388,228,287,265,120,925,590,871,277,748,290,510,424,470,873,4,30,5,91,267,916,355,182,99,86,945,301,321,370,839,716,899,170,0,781,177,418,404,167,543,607,136,121,548,119,395,578,343,632,667,101,259,495,103,194,568,52,95,152,98,54,940,825,891,182,518,713,823,553,280,342,119,105,800,844,657,854,44,108,663,143,855,261,387,978,159,399,331,86,651,802,561,167,60,626,690,349,668,283,482,307,484,536,756,232,334,645,463,567,647,616,355,524,97,713,327,993,522,843,710,144,66,64,670,956,370,373,409,329,820,210,163,23,976,894,585,188,42,427,730,240,324,245,984,660,158,966,204,836,399,638,368,943,907,200,784,198,538,685,394,944,95,211,195,95,451,509,472,779,866,876,570,613,604,753,652,983,145,748,938,833,787,715,50,973,344,182,59,280,458,767,325,281,726,954,394,153,608,155,723,268,145,108,786,203,51,203,110,277,888,172,499,334,815,624,898,203,822,749,203,938,470,378,683,798,520,764,554,117,297,10,696,375,298,207,924,835,515,731,781,539,729,394,44,672,299,427,414,265,898,61,543", "468,196,413,803,111,599,792,560,552,184,512,432,188,329,360,688,514,970,12,574,423,995,986,848,696,171,396,206,916,682,44,336,529,685,717,324,30,364,439,371,226,719,916,833,16,401,428,369,952,317,341,853,205,306,552,187,609,415,610,953,183,271,322,173,906,336,310,955,453,53,962,608,855,503,442,670,520,402,304,672,360,256,116,988,535,250,909,46,216,468,342,236,243,845,2,405,659,952,414,663,650,388,124,592,465,437,788,449,793,814,642,83,111,781,434,62,209,981,920,263,985,617,698,908,542,402,502,871,307,69,774,110,929,662,840,45,856,288,692,278,591,405,210,595,222,91,22,341,763,806,539,604,8,371,103,295,737,343,843,577,141,273,612,270,691,71,584,473,500,611,857,28,884,744,773,818,28,853,503,174,869,597,861,155,292,464,872,241,484,530,142,777,231,737,748,820,67,364,37,16,343,273,6,979,2,25,971,52,140,431,965,724,813,152,252,202,31,191,780,186,12,436,442,919,969,871,459,438,366,734,485,252,662,538,775,109,721,66,233,318,602,764,811,66,816,62,968,608,316,134,596,547,352,987,24,821,943,173,317,946,984,69,319,878,93,547,964,285,657,735,82,33,45,741,697,864,143,19,722,458,265,110,826,587,462,70,540,45,102,321,333,510,208,935,190,739,759,73,371,443,972,216,811,41,739,760,703,905,293,817,222,962,95,713,52,636,741,539,83,386,210,705,896,535,880,168,7,518,410,328,971,761,729,779,92,204,862,82,158,647,744,874,415,560,551,980,879,352,502,583,738,124,281,109,776,270,362,860,735,783,297,351,54,95,590,120,135,715,117,618,16,641,891,702,879,245,968,497,948,164,469,657,457,19,817,453,865,272,750,194,755,515,972,949,683,452,206,432,85,852,547,168,996,471,317,755,967,651,194,254,364,762,674,918,533,811,836,91,660,729,602,860,254,569,948,251,197,338,787,922,760,760,539,969,797,728,1,6,484,310,631,348,985,148,521,185,939,770,886,215,141,707,633,497,113,216,135,70,194,206,940,927,837,940,580,513,880,303,729,245,433,606,488,806,607,873,811,587,814,80,913,610,974,42,513,887,346,288,806,495,614,838,46,636,694,351,175,77,739,955,645,806,865,68,120,617,330,177,9,741,615,906,692,295,779,579,418,498,212,719,186,772,753,448,48,706,541,654,486,193,50,476,639,200,584,758,994,47,240,419,100,235,395,974,962,168,323,245,423,461,603,749,124,398,632,82,538,401,330,202,147,482,95,595,642,6,372,372,971,789,672,310,959,923,803,213,334,886,252,380,218,318,635,157,329,202,110,323,873,991,313,568,758,44,581,271,554,278,992,933,870,717,989,919,953,134,92,794,365,266,985,90,239,730,359,823,860,387,759,340,93,562,533,867,438,434,531,429,339,800,7,481,625,64,849,220,280,757,767,700,184,454,409,194,336,876,605,294,827,696,449,805,84,480,754,867,902,268,403,420,11,788,999,777,64,940,189,306,305,446,651,815,376,435,579,488,49,843,738,409,422,281,318,568,104,416,449,79,715,823,691,405,158,949,819,345,906,537,81,747,325,972,442,777,655,892,536,701,468,976,408,742,676,306,895,462,236,176,823,579,946,47,440,440,442,431,130,23,186,930,41,958,955,251,931,712,724,633,374,920,263,529,990,278,838,125,232,323,83,116,483,703,938,923,366,237,696,158,265,438,297,671,641,980,197,494,388,853,953,317,433,494,767,480,870,584,702,80,354,855,397,781,0,955,551,720,549,171,844,769,199,758,266,485,139,69,909,399,215,228,167,8,529,467,819,469,389,480,257,449,731,789,721,837,966,861,919,169,246,879,434,474,144,106,636,112,118,243,989,142,484,987,112,390,431,29,92,138,386,119,329,361,963,273,121,79,136,525,600,278,447,420,342,882,971,658,540,588,442,272,98,601,524,391,807,61,843,149,841,274,318,78,917,712,61,794,576,419,713,170,509,556,614,339,819,367,66,141,260,159,725,728,632,282,263,349,528,216,976,929,30,442,275,606,455,246,51,376,22,964,843,596,630,767,429,325,525,122,730,519,31,408,514,124,316,573,45,138,700,730,102,460,421,21,846,498,228,619,81,885,926,21,251,265,539,904,649,159,849,9,244,493,468,963,113,271,257,66,927,344,296,936,227,684,178,507,800,444,108,179,106,393,129,984,58,464,530,536,698,717,479,846,781,46,579,579,59,457,875,899,77,788,947,967,937,767,940,832,115,855", "674,509,484,695,541,320,52,640,809,424,946,497,745,522,705,482,388,195,699,55,489,956,925,314,336,109,963,263,155,667,249,230,443,407,894,399,483,101,236,669,101,386,395,457,598,389,175,741,32,28,820,322,473,595,304,10,414,176,255,62,411,316,884,109,948,805,167,705,237,353,683,180,770,355,740,236,315,336,965,564,63,740,297,16,140,282,450,672,942,951,998,601,627,708,554,753,421,147,514,673,86,252,645,814,693,729,100,291,604,404,603,573,623,141,473,261,445,714,367,466,717,975,802,226,755,28,18,351,853,844,695,264,976,752,318,952,40,368,543,601,301,644,794,450,829,470,961,777,207,48,498,490,517,774,222,606,981,535,383,597,895,983,995,682,979,514,831,124,103,56,823,402,921,880,254,898,456,532,614,530,308,306,423,9,137,200,501,538,692,976,104,242,968,548,603,141,482,979,998,817,753,292,48,201,512,136,769,189,183,846,993,927,124,866,82,92,171,470,27,605,277,717,891,62,786,946,624,241,342,13,468,890,457,33,126,507,906,847,361,548,133,566,502,659,816,712,841,378,188,26,420,112,966,134,616,555,43,597,780,207,213,378,498,59,681,943,220,227,510,517,892,891,548,427,425,78,698,966,61,807,270,730,55,186,407,884,358,968,826,468,137,934,374,280,193,59,102,204,854,431,452,302,685,352,100,846,862,372,244,856,156,956,822,155,909,802,328,698,811,861,193,864,218,186,70,290,739,234,178,63,987,207,380,930,408,627,682,255,992,155,787,309,252,184,373,514,34,684,987,21,62,691,622,883,138,551,816,41,838,98,169,925,887,480,81,693,125,894,372,65,719,446,17,655,468,913,206,382,381,762,778,942,468,791,869,351,949,101,17,722,149,439,99,14,735,903,112,523,268,435,80,134,743,521,844,865,663,338,156,141,228,740,993,877,251,782,610,124,47,362,128,871,905,520,801,761,459,296,876,261,905,959,373,532,458,756,738,363,603,298,909,301,126,112,72,699,924,172,417,944,608,160,205,27,984,970,361,800,140,360,303,18,64,26,418,463,185,422,512,965,663,245,253,785,210,198,643,132,477,200,616,764,823,805,789,445,212,647,922,910,324,589,23,724,693,70,234,248,872,201,532,42,767,17,502,894,815,13,227,114,558,135,755,459,373,530,999,168,367,428,406,964,97,794,346,185,397,190,884,800,491,368,561,248,205,519,527,172,229,834,706,942,444,321,415,64,656,327,222,410,982,722,616,759,84,543,54,163,817,572,267,588,467,253,391,996,205,820,33,251,950,525,733,395,980,226,273,747,832,15,370,948,909,740,300,556,852,385,303,962,831,187,501,925,622,83,402,466,604,479,354,970,583,400,504,217,179,232,914,470,206,833,805,666,401,776,213,712,633,747,730,627,948,386,975,952,886,711,851,121,869,595,810,947,603,387,469,947,902,601,162,582,874,74,110,349,900,579,245,213,957,607,178,24,554,576,720,439,973,633,933,685,26,40,998,990,154,936,424,393,46,748,104,349,405,590,530,126,811,463,309,354,173,57,199,377,825,616,382,548,618,331,286,677,209,72,32,863,742,521,674,542,204,195,186,671,193,337,456,774,452,922,594,893,149,144,159,428,558,134,466,834,123,380,327,421,985,426,761,486,912,614,608,544,759,849,243,829,78,239,810,148,839,164,145,287,79,903,203,2,288,425,912,287,446,45,320,896,862,77,677,510,864,775,479,44,352,19,362,521,369,367,542,891,540,544,826,618,563,439,926,177,955,0,277,413,204,583,533,985,797,688,816,942,221,861,462,92,821,48,352,458,590,61,430,973,652,664,119,242,171,621,878,733,614,504,611,230,466,845,783,891,860,900,891,281,666,254,442,350,834,141,413,14,104,740,621,97,295,768,110,559,966,860,985,164,561,285,349,641,175,623,311,633,122,418,147,104,443,47,773,218,246,970,599,642,901,759,887,116,767,960,186,186,484,404,310,535,506,119,991,576,145,373,41,619,101,14,363,959,14,325,823,632,155,816,602,435,273,402,249,380,201,90,722,995,427,444,680,480,142,852,93,332,626,260,629,318,616,984,469,235,197,189,894,445,982,762,694,472,860,304,528,465,345,678,589,702,689,951,108,954,835,216,905,165,604,310,18,538,471,92,377,942,922,525,723,482,503,614,722,517,942,750,340,468,27,429,829,523,696,45,54,59,668,998,27,290,278,868,617,776,863,467,321,840,190,786,9,214,586,649,913,673,964,458,492,563,276,876", "891,601,412,765,85,466,935,778,188,857,936,580,371,833,656,43,797,1000,631,133,773,808,765,409,78,189,682,785,372,366,439,186,211,187,734,742,492,213,206,192,612,367,634,918,706,38,377,427,435,670,624,30,159,817,104,607,150,156,382,865,263,553,760,312,624,723,11,845,254,996,408,165,431,737,159,830,861,74,623,879,165,264,342,891,929,109,781,109,709,565,836,329,626,885,15,832,832,76,859,624,706,796,151,322,534,903,78,163,230,888,23,186,135,758,488,802,894,603,677,617,159,913,78,205,940,191,13,526,171,778,889,288,348,199,621,877,452,881,56,981,638,846,292,573,53,607,538,190,299,908,864,615,880,570,147,265,251,7,125,782,306,481,849,148,841,457,714,56,631,519,844,900,515,809,485,751,486,516,280,894,196,594,312,269,122,770,104,243,501,283,609,105,852,396,567,790,667,641,578,959,47,611,894,30,212,390,14,912,611,443,116,813,9,544,553,207,687,679,427,695,905,3,572,342,109,966,293,308,668,612,931,201,146,599,956,848,691,937,154,605,688,526,193,834,251,787,183,840,404,474,508,173,797,928,624,519,570,879,170,907,818,486,165,963,706,428,851,228,965,671,333,826,163,76,389,599,341,427,998,241,462,813,277,489,53,569,166,436,924,630,683,193,86,487,467,719,881,583,660,29,136,379,248,431,265,23,984,593,424,79,734,125,674,786,913,126,142,414,659,451,654,348,737,383,527,493,807,15,155,622,181,685,395,867,321,63,423,993,244,162,450,375,288,626,225,243,366,82,451,250,326,804,305,112,578,644,914,193,6,673,435,403,510,449,575,310,722,714,149,162,165,442,51,357,325,455,922,752,260,336,547,628,680,795,400,831,618,429,251,176,115,367,16,202,219,538,405,871,560,373,401,611,877,262,157,17,4,419,438,976,289,891,910,292,68,229,158,460,520,835,881,275,707,990,693,508,766,208,918,271,462,744,555,798,273,183,16,578,83,995,171,289,634,427,485,171,184,636,474,957,637,70,925,144,125,549,998,570,996,721,582,344,827,511,322,272,429,550,772,794,753,94,241,757,224,691,532,890,15,232,327,46,744,26,394,383,46,432,467,995,791,400,978,3,128,361,923,943,797,593,272,442,742,947,872,92,730,319,346,284,534,146,505,631,862,198,134,238,932,120,460,922,33,16,88,984,985,686,374,105,19,23,698,756,136,157,989,178,410,682,854,614,306,951,72,407,147,475,714,6,57,114,271,880,7,796,906,356,267,719,158,335,447,496,26,557,405,596,37,904,925,941,166,628,524,757,510,673,36,241,927,143,40,33,747,662,790,960,766,743,282,652,942,784,681,565,57,329,613,662,157,727,342,171,531,111,13,514,357,101,414,86,369,235,574,138,698,222,875,551,390,126,271,289,790,464,480,625,651,521,16,16,287,244,748,451,136,20,718,233,457,802,637,924,742,234,360,420,609,151,857,231,385,378,590,793,73,342,378,472,817,102,817,186,3,967,838,446,445,843,744,472,291,851,784,69,582,496,951,714,241,541,657,425,962,47,420,722,429,777,640,586,289,871,473,692,550,963,529,998,15,237,781,30,901,460,385,818,116,287,88,24,665,950,697,607,402,879,369,636,307,268,25,156,921,41,866,60,531,810,498,306,298,728,222,122,805,77,941,262,239,302,46,517,251,704,305,683,369,606,910,416,978,72,933,3,584,560,356,434,19,871,747,249,729,437,906,945,470,64,523,674,746,207,63,728,46,310,855,140,292,418,551,277,0,283,830,386,640,578,214,177,523,831,929,954,631,598,916,433,653,699,136,960,626,2,90,933,675,714,736,365,904,191,387,146,884,671,469,880,610,296,815,200,221,399,723,19,426,338,606,636,790,667,756,216,100,927,297,286,645,490,442,294,399,691,680,333,773,931,184,295,345,684,725,203,969,753,462,632,670,931,969,607,563,437,587,838,41,308,40,258,889,811,95,482,876,764,893,491,276,570,19,796,772,969,57,678,150,882,143,975,388,128,660,224,66,852,838,552,323,506,425,93,30,716,902,611,291,629,245,49,922,441,882,61,268,935,228,98,534,370,269,278,773,271,236,646,55,637,397,82,981,456,233,245,692,48,289,238,374,809,967,294,595,64,343,182,32,544,306,789,753,129,499,752,554,344,427,360,717,331,734,72,987,212,417,471,750,892,911,362,650,902,213,439,159,100,930,400,364,945,857,781,113,794,118,340,223,94,66,837,854,839,669,515,262,350,781,710", "81,160,769,125,646,344,669,249,428,108,313,301,737,822,72,583,834,130,578,861,399,645,423,169,755,766,184,316,978,644,833,289,249,622,757,891,979,241,506,50,884,913,347,939,735,787,309,397,798,400,806,696,110,127,14,709,222,825,825,888,497,2,933,262,284,842,603,232,454,680,461,278,170,771,718,217,803,172,561,526,494,861,896,342,924,840,374,921,950,855,737,274,178,826,585,275,767,406,327,973,527,651,383,579,948,388,758,100,997,536,743,72,534,932,289,86,662,960,760,291,503,473,961,674,142,864,554,430,397,672,180,167,831,998,748,668,242,621,562,409,803,106,876,909,972,244,625,699,941,425,765,9,237,640,911,260,985,52,204,939,900,809,845,762,22,795,36,356,98,571,857,351,172,604,601,630,38,679,661,9,862,62,852,539,337,953,791,941,737,355,220,814,551,657,312,326,546,289,313,645,178,578,996,981,803,19,560,152,80,954,981,99,28,32,129,773,451,471,510,338,835,692,303,221,759,590,452,487,862,622,543,63,101,89,651,851,667,552,631,452,296,69,243,95,259,334,921,832,155,981,387,966,109,973,525,725,996,958,34,331,695,129,811,226,999,426,460,920,13,972,606,875,462,860,243,748,221,191,94,691,87,707,243,972,990,527,982,494,112,728,704,651,565,269,783,920,472,768,944,851,871,969,605,279,663,891,861,240,82,135,71,813,666,151,272,712,203,190,624,492,792,181,949,116,229,63,242,636,353,374,981,653,655,512,144,911,466,180,225,751,782,938,563,608,876,369,830,851,305,629,761,222,305,442,127,344,230,354,502,948,300,87,873,42,93,397,677,831,919,461,980,325,481,577,496,68,890,501,802,581,34,505,476,663,757,616,634,115,28,358,920,836,271,192,609,433,235,597,498,587,761,161,271,975,415,392,223,322,622,470,148,455,470,700,169,9,446,449,859,900,238,5,819,706,809,216,15,790,327,50,925,211,466,750,770,739,864,414,546,640,214,692,834,1,306,577,799,234,992,428,528,758,562,291,934,486,700,710,615,965,679,7,700,862,265,375,233,270,579,438,9,722,117,990,642,121,388,872,259,71,645,966,466,275,887,360,271,683,405,137,9,716,718,274,136,708,551,994,107,992,672,196,264,776,420,401,188,228,449,244,819,246,581,524,666,286,122,757,155,270,410,25,183,287,758,80,147,909,399,559,258,439,904,2,659,370,346,923,288,19,213,718,67,915,491,977,114,659,308,823,250,635,15,565,493,120,244,705,287,604,384,244,111,197,836,392,112,622,253,478,188,633,757,531,875,443,350,226,49,538,521,734,988,978,651,852,154,681,379,534,311,105,681,58,5,635,644,432,571,877,435,710,58,444,919,973,865,312,295,627,362,610,893,421,585,19,441,214,281,131,700,73,167,415,688,261,708,699,707,762,469,712,551,279,626,625,888,762,631,372,585,639,535,39,396,319,474,466,926,915,631,790,600,275,401,684,652,768,771,620,829,148,135,792,385,170,961,354,673,640,812,564,232,614,269,407,431,571,553,95,356,459,338,341,985,125,649,705,287,191,23,690,930,964,509,241,518,796,881,169,222,946,321,957,795,250,174,776,679,345,143,63,533,360,971,257,990,577,842,132,497,161,273,564,1000,31,664,884,411,610,248,595,568,608,56,383,266,101,49,193,48,943,22,904,799,252,68,332,344,836,830,902,421,338,242,147,313,794,20,849,926,160,943,347,848,30,981,140,30,274,434,863,711,766,541,218,561,64,856,882,766,404,720,413,283,0,120,612,459,493,914,690,739,635,123,247,176,359,756,9,331,794,959,425,245,486,389,945,88,405,33,544,418,73,874,321,724,791,888,809,674,57,866,616,300,76,782,308,39,871,722,156,903,201,498,813,928,70,577,103,44,860,152,734,445,791,40,253,874,644,745,822,788,380,984,471,801,457,378,764,790,165,76,972,607,970,583,266,292,822,189,87,840,958,267,327,895,927,357,250,546,169,703,236,838,427,378,183,981,775,863,107,524,614,106,190,1000,578,270,25,662,414,15,876,377,375,766,8,500,48,89,313,232,854,785,247,340,694,19,81,585,105,729,125,46,402,944,812,10,416,163,947,939,97,253,466,639,459,331,68,572,28,136,548,331,716,463,961,523,890,731,75,607,878,883,62,248,347,92,753,696,26,666,740,607,945,891,806,873,990,921,385,905,299,327,649,815,653,534,785,736,164,310,866,712,33,467,635,33,34,17,864,68,607,329,547,305,12,94,282", "205,133,301,263,710,123,542,485,171,226,897,105,506,184,26,935,703,68,583,485,648,526,85,754,986,969,108,782,840,543,307,918,699,425,705,256,954,799,560,841,424,2,403,335,234,684,161,978,213,180,44,46,589,329,838,847,359,413,328,833,405,445,211,863,399,656,426,659,348,356,17,824,191,625,206,492,710,204,293,845,458,785,825,632,34,872,293,79,424,429,476,758,184,338,335,844,500,374,420,939,715,712,528,675,396,808,521,66,716,534,807,908,202,763,967,785,657,410,909,378,402,881,531,473,432,80,809,562,141,316,362,813,531,705,366,235,718,690,103,296,191,744,678,434,70,833,71,263,690,643,610,4,48,533,921,85,661,397,434,39,889,442,949,476,373,581,87,14,33,610,319,932,531,594,30,269,226,107,446,465,345,738,903,677,308,434,796,81,938,730,130,974,888,48,47,122,214,879,959,701,906,336,631,959,283,321,823,288,150,725,784,732,618,452,548,225,590,244,117,587,49,592,484,834,138,97,321,11,598,184,757,768,62,506,763,917,690,259,165,846,87,115,664,17,155,638,48,994,43,803,149,231,172,835,828,279,592,152,523,509,500,874,446,629,807,263,18,55,324,282,889,102,169,354,69,267,116,890,262,267,618,957,316,498,718,988,580,30,760,8,291,292,174,74,450,725,57,256,607,386,377,981,877,963,92,617,469,227,460,134,671,919,235,369,574,902,835,113,242,764,339,973,566,285,988,329,566,607,462,459,867,653,175,985,901,302,788,433,591,386,752,975,964,236,775,997,325,959,322,574,797,920,469,4,945,860,4,896,857,37,170,505,29,983,358,592,291,966,897,346,856,55,967,465,749,724,801,84,413,317,788,363,892,220,507,486,934,394,412,58,277,11,184,937,285,482,262,798,137,699,481,437,291,983,246,486,273,841,284,525,40,104,624,596,87,653,588,994,253,804,657,841,150,394,90,816,120,898,601,972,18,383,745,208,640,958,917,810,289,710,520,867,370,125,316,472,957,110,577,158,759,47,68,421,611,963,885,795,365,711,156,966,292,683,547,104,126,285,389,80,792,104,341,974,694,139,437,960,922,535,622,894,240,992,518,532,965,436,282,726,480,128,414,834,655,232,407,550,320,965,380,679,596,815,372,302,275,523,78,597,313,49,826,514,765,700,267,864,872,30,56,995,913,123,398,622,708,399,143,267,697,634,306,783,964,682,446,494,203,89,327,425,287,168,703,706,215,491,470,514,461,536,115,541,763,40,764,80,28,450,173,561,88,490,937,339,511,735,942,109,888,741,809,84,494,784,366,83,913,161,104,594,45,364,697,937,59,145,479,711,706,222,287,251,634,660,130,708,901,61,69,689,1000,621,232,914,45,521,219,749,905,458,361,489,240,503,727,164,252,147,962,588,208,653,610,30,891,917,593,596,16,855,950,645,647,262,319,438,852,739,552,342,393,373,787,586,643,389,365,467,279,464,518,442,631,981,674,928,586,825,945,939,543,975,586,381,593,938,367,868,621,443,413,655,574,597,423,232,278,955,114,239,602,91,706,351,153,500,857,961,400,320,96,72,915,458,668,862,872,973,202,722,43,802,201,827,984,624,192,347,696,681,169,203,498,416,461,623,218,801,426,815,766,1,911,54,768,931,745,1,879,768,904,625,100,773,306,807,519,463,323,475,459,398,558,737,469,691,513,185,184,129,471,569,392,639,442,178,946,769,463,641,451,366,47,455,802,555,151,400,327,847,831,525,380,697,277,357,496,829,59,167,549,204,830,120,0,288,538,585,736,960,543,697,114,240,933,733,142,71,603,511,252,319,169,559,917,500,446,912,345,50,692,771,923,823,304,430,989,907,459,576,318,921,591,271,475,228,697,271,123,36,470,870,332,383,431,581,903,326,834,690,627,46,518,327,27,645,583,176,193,200,561,661,386,480,690,398,984,540,612,568,99,76,890,252,466,465,109,746,50,901,764,994,419,437,710,948,261,652,174,270,275,145,965,516,8,635,898,680,182,760,865,416,448,316,221,847,158,202,113,171,185,909,658,237,348,610,738,376,994,562,68,464,193,932,402,784,45,190,201,52,97,311,330,822,66,843,553,963,196,494,423,632,526,901,737,674,541,317,734,600,987,302,488,520,424,812,463,193,527,373,114,528,381,772,421,192,392,901,162,715,751,455,238,625,385,564,974,610,288,722,199,449,886,916,501,767,883,21,864,533,495,424,519,617,201,912,304,818,2,536,477,264,958,784,215,680,775,654", "226,350,349,627,749,342,311,294,804,359,450,922,32,255,186,601,127,503,210,631,940,828,604,894,251,851,742,335,684,858,495,304,772,269,835,424,837,938,452,27,611,326,504,342,205,902,257,543,87,567,482,301,603,85,41,288,741,428,722,73,784,256,549,88,218,380,694,202,995,182,961,120,116,760,63,66,298,708,643,622,998,546,836,486,14,453,841,526,726,887,962,325,226,683,222,542,210,412,232,926,52,744,887,270,215,692,274,423,601,894,662,543,691,3,144,893,985,18,22,148,975,102,426,275,695,491,237,615,609,729,230,494,328,281,225,225,310,179,436,311,813,147,430,566,214,314,854,905,770,562,872,632,504,811,346,540,558,312,712,24,712,446,707,805,950,538,561,946,535,379,202,678,574,628,88,855,875,277,177,521,137,919,902,609,492,808,202,759,959,994,685,546,767,587,640,516,94,452,284,657,450,841,247,51,503,258,370,180,180,574,933,661,560,637,38,514,742,885,118,757,857,63,882,539,97,565,143,400,64,415,252,827,955,40,749,372,227,824,243,448,782,422,286,691,279,922,720,827,117,661,898,292,955,193,125,204,197,461,18,522,847,661,736,117,484,161,63,594,907,752,963,74,798,98,532,580,750,606,817,924,304,660,439,143,782,97,510,881,765,791,764,343,214,765,281,877,480,832,315,529,133,904,131,450,846,798,70,743,952,929,572,976,364,855,888,304,440,350,487,502,930,959,27,456,354,954,905,112,617,733,283,897,647,273,844,122,877,954,104,866,839,994,734,813,749,541,882,508,792,235,829,483,559,954,102,979,819,777,587,264,231,382,852,624,138,73,2,952,216,179,813,730,622,261,438,884,496,280,775,115,235,986,721,194,818,769,228,613,75,709,395,498,42,280,40,344,909,547,777,95,245,346,651,905,614,598,941,789,369,739,438,395,333,342,533,958,829,262,910,809,404,533,145,977,220,241,292,402,432,769,433,966,742,309,770,646,58,886,37,467,831,38,131,284,407,561,57,284,721,370,864,721,289,916,725,568,873,987,160,532,367,52,777,880,488,796,939,436,812,937,524,416,713,785,567,416,539,533,859,791,743,836,442,106,157,312,662,539,462,693,790,405,507,845,225,713,999,201,589,7,696,124,510,987,352,203,112,133,626,625,146,262,856,997,95,686,282,464,479,271,704,175,409,845,481,480,269,980,247,544,800,320,54,625,882,596,981,663,223,815,950,187,40,101,728,933,139,595,651,106,759,693,712,9,56,184,448,254,999,937,181,333,835,650,424,404,126,50,392,347,14,733,801,211,502,141,870,918,906,375,504,889,924,269,818,77,595,289,440,681,438,505,171,52,399,847,46,484,922,347,146,136,506,368,210,53,959,139,212,121,313,468,256,385,890,418,753,323,807,826,972,357,897,410,772,990,691,382,751,372,274,348,215,779,467,386,751,132,48,71,120,859,679,860,496,862,188,583,998,546,452,526,889,416,620,712,592,755,34,384,54,711,431,667,110,330,379,215,414,555,651,931,230,143,359,126,209,572,698,982,815,449,156,7,464,480,974,148,325,786,19,120,892,696,605,39,10,802,897,455,271,844,738,710,695,989,863,927,617,427,421,172,933,500,2,721,26,763,279,476,381,688,326,110,436,733,445,607,375,283,854,155,463,80,75,585,191,916,850,685,246,750,783,327,862,305,612,840,11,7,981,153,597,724,714,724,943,880,737,53,889,900,296,710,133,360,771,696,279,560,678,176,586,473,540,478,157,204,999,266,81,543,171,583,386,612,288,0,179,567,133,403,41,135,425,460,64,902,641,706,826,339,209,923,239,926,915,797,236,949,428,978,320,977,798,306,568,629,444,772,135,763,55,849,568,879,503,693,879,262,648,418,505,965,750,106,640,647,555,326,932,943,846,153,44,974,840,724,123,816,155,361,630,555,219,783,958,682,541,499,208,908,186,150,396,821,48,316,203,648,238,493,382,456,750,821,473,646,98,154,200,357,619,779,832,607,532,8,366,941,847,952,864,82,149,985,259,613,239,229,220,524,453,221,582,916,413,836,602,683,715,955,689,624,901,286,319,98,254,281,472,804,473,417,1000,873,569,846,354,457,364,909,946,874,119,411,401,970,595,650,744,483,787,265,296,582,62,169,101,885,326,960,768,411,281,556,111,857,53,620,89,439,227,323,972,310,261,50,664,904,260,562,781,152,901,538,648,461,149,38,683,727,261,262,437,357,717,817,736,530,648,932,247,84,918,508,26,865,337,734", "907,444,973,877,708,449,687,495,703,900,881,128,54,433,107,797,949,72,49,292,959,141,561,152,328,952,890,834,257,362,434,288,577,774,858,384,915,284,41,25,610,50,297,709,48,638,84,564,742,548,494,57,1,528,812,769,192,367,91,245,196,918,144,593,442,597,379,827,806,437,693,818,917,156,740,635,127,752,342,372,231,474,467,428,562,151,23,827,683,629,612,795,735,932,206,769,278,896,26,251,531,733,854,656,789,774,334,402,322,757,160,350,316,608,769,732,935,857,117,323,473,916,623,726,733,888,929,713,730,634,239,391,807,854,174,793,405,702,183,431,919,279,91,171,367,905,779,44,416,748,40,281,57,926,762,248,245,273,839,96,961,489,84,910,627,743,262,815,698,391,429,397,939,21,60,92,959,637,276,296,646,192,258,456,256,486,11,628,299,499,594,745,211,118,569,405,916,647,179,29,116,252,66,420,246,237,61,785,312,452,88,662,837,233,593,249,137,561,183,779,131,8,32,591,760,491,21,583,108,71,930,254,460,849,35,204,720,455,823,818,792,766,349,124,477,763,911,149,96,690,420,98,463,11,85,938,493,87,67,950,805,27,271,779,702,474,884,564,109,638,689,343,315,180,382,764,799,734,948,128,771,556,841,429,719,947,627,511,284,425,27,712,360,900,230,115,639,332,560,162,565,468,941,267,96,596,250,296,695,109,758,842,594,200,440,89,431,705,843,685,559,240,891,938,761,314,690,240,406,604,76,129,838,528,676,293,315,723,874,776,454,627,237,419,879,498,250,964,233,83,141,322,136,80,954,753,681,797,72,51,328,23,148,18,817,326,723,818,486,140,208,716,645,926,348,697,833,475,45,336,659,41,722,886,406,166,500,743,794,414,788,554,611,399,465,320,456,919,516,252,871,122,226,252,641,110,569,484,408,153,895,41,612,377,975,955,835,421,311,903,953,54,926,166,5,394,165,243,885,104,465,93,570,466,29,631,317,773,588,152,213,814,224,526,6,54,757,341,203,346,673,818,172,960,510,603,24,415,862,231,133,249,556,389,996,399,581,261,411,90,275,571,479,416,383,42,406,22,475,461,360,64,48,902,713,243,738,284,265,311,168,610,468,837,547,84,133,654,176,427,894,320,764,41,969,363,292,810,882,602,232,216,867,667,569,704,594,182,140,253,401,389,754,44,308,156,454,126,267,265,195,516,742,484,989,275,776,625,991,947,602,721,652,214,304,979,494,588,965,797,851,729,322,812,52,870,739,505,127,120,153,381,19,603,888,382,262,138,633,84,248,197,914,873,259,378,635,279,478,679,872,51,729,969,222,312,625,512,742,990,91,774,979,355,807,205,551,533,396,318,426,808,745,30,371,307,197,150,109,124,690,382,309,52,549,390,632,974,351,108,831,115,659,322,457,578,232,546,256,610,477,519,905,68,146,789,344,931,752,410,532,519,878,179,114,903,981,233,867,725,754,708,743,329,656,76,205,933,861,87,59,750,245,766,888,465,487,271,170,945,392,402,184,479,930,553,3,663,318,33,600,270,117,457,839,855,552,644,664,199,468,736,555,273,746,692,744,399,780,34,827,642,403,73,570,92,154,218,817,968,856,91,192,436,631,283,215,148,68,635,244,510,457,885,570,770,704,216,339,590,13,875,820,194,850,664,959,186,238,66,909,189,709,420,52,888,919,527,904,966,722,904,80,388,326,823,736,442,685,461,621,373,637,49,915,458,730,618,434,868,245,120,901,992,267,363,348,468,949,310,706,607,844,533,640,459,538,179,0,332,254,37,327,853,844,614,945,599,746,813,358,93,592,741,800,518,825,219,420,287,748,750,801,440,556,974,780,99,206,331,650,994,987,234,818,364,113,384,886,989,775,721,428,551,141,866,760,999,402,953,176,942,391,457,832,714,40,397,713,820,414,807,700,710,540,147,192,514,487,389,933,460,538,852,433,932,236,899,97,86,110,755,935,894,766,569,307,829,509,821,300,182,643,85,323,575,749,215,876,717,575,844,690,543,72,738,322,197,464,556,426,329,587,522,270,508,668,138,873,887,616,566,902,422,593,655,12,80,614,979,289,997,554,395,128,506,78,12,388,489,616,64,692,536,678,15,760,52,818,578,411,61,127,201,837,509,407,586,953,421,20,422,97,480,529,766,639,85,482,935,212,779,741,318,445,475,995,991,219,444,905,304,630,987,636,816,570,273,534,829,822,241,410,19,516,328,983,70,588,545,330,1000,684,147,648,438,786,168,286,156", "158,846,720,119,357,638,757,598,346,558,979,194,73,301,581,113,248,185,624,685,129,754,869,860,279,492,634,521,295,487,812,847,656,379,604,225,112,669,27,45,216,682,517,609,794,104,818,144,291,542,304,501,896,479,714,189,628,598,338,31,576,873,61,915,441,164,918,474,647,151,541,257,976,908,837,702,421,497,885,130,343,777,337,628,702,644,870,696,214,718,921,63,3,31,321,668,362,133,58,869,36,829,289,206,209,742,295,839,952,371,248,867,430,482,992,429,200,726,23,889,800,67,778,684,588,963,667,364,617,901,831,7,629,787,455,853,895,384,965,506,498,769,366,225,970,238,838,548,206,512,144,96,485,487,652,521,294,790,606,978,407,112,683,905,518,243,928,351,737,493,319,855,410,548,239,616,729,776,319,892,352,265,835,586,923,642,758,64,930,686,701,961,414,509,660,248,801,285,972,623,123,550,475,713,119,172,789,296,616,915,117,379,279,724,174,573,492,319,801,53,428,529,94,142,43,10,612,546,409,354,871,939,356,612,124,501,900,542,181,460,607,554,944,248,849,959,895,67,508,426,525,70,281,453,36,842,536,231,453,892,92,473,629,655,191,940,421,147,151,275,741,540,55,818,6,574,143,13,933,639,708,847,912,630,847,795,900,360,257,215,961,867,872,897,283,963,839,56,223,841,161,78,385,372,461,390,112,891,161,864,169,74,353,935,872,941,474,603,406,80,232,499,935,155,601,271,999,316,763,693,573,322,175,717,67,782,280,388,342,360,167,727,998,221,374,585,315,921,847,468,158,983,13,661,659,726,384,210,896,915,261,998,993,833,26,671,670,637,281,855,227,806,588,310,377,163,981,207,238,340,392,814,309,563,787,731,4,499,119,60,500,648,887,788,658,73,390,805,403,202,169,418,911,418,824,199,401,178,941,443,269,828,384,460,823,60,677,788,830,149,621,542,501,297,86,299,262,106,535,536,68,181,213,416,924,79,231,19,741,94,194,402,219,509,242,804,470,440,943,148,220,4,631,501,734,855,21,617,769,334,299,619,551,620,756,89,472,990,643,574,260,831,679,854,274,401,831,622,810,38,991,612,965,163,505,211,101,275,74,1000,314,483,312,894,139,633,411,373,894,867,329,838,893,303,949,161,706,25,385,458,306,107,770,632,904,202,63,245,26,848,817,42,901,401,122,734,982,73,395,844,801,96,5,389,228,567,967,509,816,416,815,339,731,978,843,289,591,987,406,194,852,289,609,26,962,11,301,62,913,409,305,728,74,650,724,57,377,445,824,626,610,868,621,439,707,5,638,81,961,835,233,176,991,909,199,110,383,443,483,926,345,164,156,923,705,176,360,549,150,17,101,255,638,362,496,978,406,317,112,75,129,42,812,395,692,933,45,785,125,7,583,175,358,914,635,906,11,743,233,226,35,81,274,37,950,49,781,76,128,430,857,888,457,179,269,380,177,224,610,159,249,287,694,523,716,888,507,105,252,143,270,565,389,33,119,50,885,522,889,909,195,433,212,766,667,978,889,972,42,379,766,652,758,599,265,676,602,725,390,339,656,233,100,567,811,696,68,690,830,595,777,37,805,956,995,107,257,90,461,252,290,550,425,585,607,710,43,784,905,409,607,957,690,27,76,426,254,569,109,830,616,767,132,638,452,783,510,632,864,914,561,651,558,410,242,609,684,391,10,677,777,310,505,653,43,21,637,537,976,999,657,513,396,829,414,692,204,64,143,331,60,23,31,418,975,437,978,499,672,397,440,136,769,985,578,493,585,567,332,0,247,508,576,375,89,458,277,881,865,291,569,987,158,78,247,814,13,710,416,712,450,845,824,896,770,979,261,572,707,739,113,142,256,573,752,661,628,198,846,921,913,547,827,126,318,643,939,921,355,690,840,876,932,309,216,525,834,467,920,101,717,905,108,124,407,242,238,796,141,767,380,551,693,214,275,849,142,254,88,912,512,70,49,73,518,572,238,123,770,567,361,122,227,699,138,502,41,427,875,875,14,312,882,510,117,369,9,658,298,850,769,21,980,126,293,765,769,877,176,424,607,53,166,506,474,470,248,520,316,429,566,160,715,619,146,823,222,658,779,10,589,458,92,257,884,848,825,419,386,507,846,37,883,346,199,112,131,752,670,603,854,858,247,826,734,455,528,509,606,471,728,378,101,515,696,726,56,382,61,281,858,636,700,220,848,945,772,903,230,525,838,343,888,865,691,894,616,796,156,986,927,97,636,592,793,955,232,135,582,114", "473,464,343,195,354,124,47,224,613,474,117,728,780,573,430,41,438,288,408,612,401,902,950,577,646,373,231,898,141,569,253,444,417,364,264,136,349,922,687,301,534,167,939,743,346,562,607,656,555,21,419,331,884,866,70,871,426,636,766,381,211,877,802,857,104,372,623,504,873,500,734,378,479,286,282,723,354,469,650,75,107,338,212,474,751,349,915,762,868,581,402,317,543,563,419,588,56,245,306,759,449,15,866,340,840,761,816,171,996,60,399,951,258,368,788,665,399,911,419,357,354,880,400,451,924,925,920,856,222,807,809,53,848,147,636,126,735,304,831,601,298,935,630,974,742,372,443,560,288,140,325,467,530,283,244,231,890,401,404,571,78,782,701,238,259,377,572,650,807,989,324,618,930,149,135,906,968,722,817,352,843,358,6,715,43,281,976,381,17,269,888,694,392,784,546,716,831,161,703,313,568,291,882,290,538,788,208,232,583,464,5,167,71,283,690,66,409,56,37,663,577,46,799,599,100,677,609,53,886,20,93,875,69,70,83,683,367,781,35,932,633,5,232,4,905,741,823,794,59,357,433,809,609,386,699,806,59,947,311,978,661,151,429,231,380,453,678,818,977,724,646,465,215,755,491,460,641,912,941,953,71,47,235,688,52,373,822,115,916,548,364,715,36,619,513,94,559,871,789,74,484,217,39,416,255,746,400,22,54,291,203,465,135,408,524,240,874,578,554,92,991,355,235,239,71,964,833,303,948,714,736,333,51,41,969,833,433,546,482,850,936,334,596,566,521,957,581,86,635,102,93,841,390,181,369,175,699,757,627,715,30,414,162,606,390,335,942,261,53,918,855,199,682,425,537,473,472,180,815,136,706,608,762,103,460,498,413,276,559,900,217,183,673,225,954,327,322,649,934,952,216,843,8,727,367,767,673,482,963,605,274,752,487,598,162,30,242,341,281,805,372,788,413,76,249,195,612,537,630,312,516,367,579,96,434,815,392,117,809,102,179,535,612,452,849,491,140,250,68,496,855,433,863,494,42,656,262,154,727,177,991,109,306,83,371,137,543,264,637,344,371,975,414,728,399,998,485,228,930,926,101,98,287,259,524,795,980,900,8,543,550,967,461,816,19,238,874,466,360,387,763,602,545,709,220,448,935,857,162,417,251,969,261,30,708,519,882,46,807,795,376,235,542,516,654,152,669,66,754,113,746,220,528,757,619,167,844,344,164,183,260,58,325,835,617,323,834,435,169,641,171,274,217,169,12,13,75,768,914,388,394,877,189,408,74,452,430,683,406,85,712,959,811,29,605,547,398,893,602,7,954,875,9,558,807,915,390,611,685,846,984,369,979,364,739,210,825,492,542,105,791,400,764,478,298,51,208,279,107,661,447,942,984,894,302,673,665,92,732,656,752,491,135,181,143,80,548,155,281,499,951,514,563,362,487,326,83,42,383,943,730,52,535,584,514,427,862,121,122,927,347,179,958,71,179,399,580,289,515,373,323,264,105,616,671,652,15,729,98,176,384,799,850,325,589,898,668,805,972,37,929,376,44,810,982,800,169,51,706,414,456,563,947,956,72,33,323,653,127,794,268,975,604,767,86,288,635,926,36,132,921,528,126,527,384,207,157,557,284,375,735,770,717,914,514,596,2,123,422,413,753,344,506,881,205,564,294,384,913,776,559,255,417,599,240,189,191,39,275,145,786,84,390,257,937,519,379,928,618,170,735,7,756,472,838,81,190,951,299,556,272,734,912,466,388,881,472,81,22,280,38,121,199,797,214,914,736,133,254,247,0,717,897,773,446,27,702,715,972,64,597,954,418,29,717,134,688,492,312,650,573,458,993,411,160,565,493,780,732,145,406,378,690,335,789,819,180,972,871,788,246,434,922,604,581,701,138,318,618,294,68,875,516,533,915,474,203,611,991,514,728,966,425,626,5,93,574,653,767,142,416,208,213,158,485,122,50,651,152,735,767,334,591,95,345,262,73,305,867,847,40,938,183,443,402,779,783,932,708,989,604,165,524,560,600,922,941,727,114,429,857,745,699,241,4,189,646,56,731,918,160,809,219,429,631,5,903,514,159,435,986,688,705,300,682,67,249,269,990,168,498,437,220,466,199,150,236,704,281,690,314,957,572,792,426,689,979,154,920,684,165,909,490,715,554,56,517,938,652,604,774,544,48,423,825,728,86,162,190,194,46,850,779,755,994,158,112,30,456,327,275,502,685,372,486,36,289,817,397,833,211,245,61,75,850,230,886,195,876,444", "622,507,210,596,33,667,551,178,160,496,506,440,712,341,722,416,631,448,297,725,660,775,226,771,658,843,954,442,964,935,868,7,192,937,694,936,97,988,754,361,108,404,569,370,7,570,460,693,154,951,477,33,501,611,856,287,693,64,777,428,526,954,470,778,572,308,485,777,788,550,142,900,569,261,495,394,109,336,221,697,350,650,240,804,19,117,593,832,813,106,377,635,391,697,920,734,372,907,766,493,9,777,302,47,337,971,520,254,601,637,493,785,159,380,583,115,673,405,572,779,376,138,616,3,827,683,873,981,135,42,572,726,233,627,984,566,623,447,391,707,709,973,549,261,451,704,580,458,266,633,949,354,620,225,365,691,420,580,925,64,339,901,90,648,290,148,563,444,904,664,286,268,998,991,857,878,274,325,906,532,76,430,329,396,395,975,397,657,279,320,864,315,551,765,128,767,446,376,356,576,668,963,547,182,136,796,614,387,465,232,232,81,379,744,294,486,527,329,86,790,733,530,468,321,80,12,701,515,151,488,43,819,234,419,319,138,594,790,656,274,557,187,471,555,882,204,157,820,431,478,830,568,561,891,789,963,516,95,669,89,565,33,181,466,898,15,425,107,755,127,915,902,775,852,69,598,274,118,489,209,504,185,636,55,265,509,715,950,563,781,749,79,429,783,143,383,841,257,720,228,334,679,733,323,653,485,504,534,702,645,59,501,827,154,696,366,744,444,61,483,756,637,201,603,692,899,121,503,14,518,629,300,276,375,478,523,800,19,447,576,671,770,552,656,412,420,587,71,473,367,523,13,497,546,893,640,636,549,381,484,718,489,280,292,657,997,861,187,296,393,42,904,643,930,233,534,183,325,992,782,485,453,351,875,320,495,680,11,868,63,719,316,806,130,68,519,580,462,636,307,230,25,895,853,875,630,35,89,740,992,418,866,410,421,428,365,833,535,307,139,338,654,376,238,327,974,391,383,291,654,322,882,966,958,38,397,745,837,477,616,302,150,504,83,636,11,582,772,123,428,824,107,112,876,234,110,468,476,385,323,952,713,978,35,415,120,369,575,518,750,885,51,247,311,525,997,879,953,239,571,684,252,641,309,369,558,70,367,220,680,969,408,546,901,6,27,795,625,321,823,708,849,695,56,390,29,346,53,142,278,725,124,299,857,85,159,296,9,786,950,175,774,767,383,673,248,286,515,316,690,882,716,403,503,354,476,766,59,209,534,720,588,304,545,177,859,63,550,802,139,525,197,447,530,161,271,399,384,294,729,887,922,896,762,575,529,440,567,45,893,228,553,884,673,735,100,471,798,711,340,552,941,782,312,164,884,829,738,244,385,829,510,978,816,336,583,911,377,406,794,478,825,636,519,99,27,115,849,267,157,5,212,283,803,431,322,28,976,552,870,590,691,481,768,339,32,47,317,564,124,696,526,430,504,190,931,180,888,383,642,376,221,881,461,448,242,728,134,875,982,258,995,397,224,207,891,670,190,286,977,212,649,420,50,36,120,403,224,64,474,366,505,901,474,61,415,157,314,475,794,367,171,544,136,478,873,326,87,720,994,914,568,693,466,605,523,421,274,263,429,162,243,941,99,513,862,524,429,681,682,165,161,367,223,551,930,254,838,830,126,917,184,333,316,474,60,426,427,575,871,476,719,539,812,281,153,448,211,440,164,431,922,431,94,467,914,194,134,449,892,604,551,734,959,250,324,646,43,913,587,557,492,83,161,298,139,440,69,611,894,572,859,831,920,263,777,517,536,714,183,598,548,758,688,177,690,960,403,37,508,717,0,152,629,446,153,422,572,518,45,389,766,982,68,72,195,665,910,936,999,837,276,671,573,261,633,891,419,998,298,160,783,797,128,349,946,118,981,488,533,616,697,186,249,167,78,751,915,491,226,809,453,904,817,997,766,517,618,8,930,368,172,922,660,885,878,848,100,421,928,322,923,814,66,392,456,370,62,600,916,481,414,545,194,711,614,64,903,448,557,305,228,101,324,793,457,981,285,65,93,505,914,722,907,123,760,912,755,477,723,819,268,554,312,726,880,114,36,58,755,735,865,316,910,602,733,470,607,301,475,13,615,454,579,610,254,95,923,40,641,207,983,63,86,846,686,783,43,369,815,293,374,994,118,88,654,895,382,830,210,365,802,27,766,968,510,892,219,828,826,62,563,520,669,720,909,896,385,989,399,426,394,829,582,973,195,837,197,951,713,171,89,549,43,871,454,726,186,348,651,845,961,768,462,111,491,766,242,797,930", "67,733,915,480,80,105,106,939,124,244,954,897,560,731,773,209,966,103,274,476,755,853,302,874,811,163,418,371,712,620,546,264,514,820,77,763,447,361,637,216,92,226,244,15,283,942,482,30,773,435,648,205,291,515,982,183,789,726,286,173,853,746,867,647,526,770,111,156,96,552,706,778,232,211,400,593,781,419,711,796,720,691,657,707,143,658,813,326,799,480,807,502,704,269,249,773,214,821,186,796,350,725,322,111,287,753,693,672,376,157,46,686,277,517,890,819,977,590,866,153,389,390,789,310,477,569,44,778,569,139,344,150,647,452,822,489,614,426,281,562,361,991,311,177,469,414,329,280,843,901,493,302,758,855,439,14,306,98,521,606,162,930,903,639,102,727,11,275,531,216,57,385,177,234,943,741,293,485,822,728,331,835,25,581,827,137,157,994,867,925,190,353,921,139,201,116,412,273,778,479,630,806,861,371,215,213,839,789,238,409,999,224,600,457,240,41,690,651,543,311,389,30,30,729,289,498,639,810,715,253,618,662,729,316,789,861,548,967,65,862,909,15,648,88,624,261,614,895,633,289,724,15,522,190,18,645,349,99,767,366,301,48,504,667,587,740,30,773,226,886,118,501,812,272,406,360,405,741,480,941,58,329,271,851,3,892,498,11,198,755,611,228,242,964,324,721,235,167,280,101,305,775,985,777,402,815,595,888,87,603,72,487,427,566,183,319,222,34,860,780,395,462,557,321,461,996,853,600,135,6,380,505,830,953,838,510,908,802,656,45,185,674,275,148,318,736,565,597,496,568,859,742,539,118,268,906,696,928,877,156,834,256,468,516,598,30,563,663,362,947,802,816,290,327,764,887,808,794,981,999,61,509,455,616,44,192,474,933,844,340,705,426,981,585,194,592,88,958,844,975,935,329,974,297,488,676,498,35,907,135,807,211,27,223,631,491,114,315,499,513,337,220,252,533,375,921,27,780,544,113,257,309,180,871,681,361,955,544,649,124,861,169,280,220,301,440,500,974,293,977,68,382,145,137,373,20,776,70,256,412,103,61,688,811,365,728,209,633,629,813,848,798,571,466,750,724,136,577,273,27,154,797,376,869,254,981,969,687,894,484,779,997,721,122,532,771,371,570,474,35,512,827,691,753,697,403,505,132,461,189,652,147,810,570,360,44,189,959,164,457,133,611,791,912,998,874,229,658,581,887,638,666,561,887,238,931,956,530,998,445,81,927,861,845,239,698,894,608,397,808,784,646,460,955,76,158,585,425,352,921,698,279,822,315,24,23,289,629,869,157,922,853,968,276,794,147,307,997,606,392,375,744,201,741,16,300,277,194,429,505,256,49,470,900,483,387,514,391,844,411,383,144,631,90,563,687,810,313,591,431,460,747,448,82,860,493,472,94,442,652,627,434,864,231,624,241,825,90,531,481,230,122,742,726,385,934,160,763,49,573,74,495,981,923,645,404,400,420,483,716,663,284,593,370,17,386,965,70,397,901,903,278,829,413,957,140,861,2,830,435,912,645,56,614,884,100,34,324,999,447,710,507,602,730,855,158,876,328,932,283,43,616,859,487,521,434,499,649,910,544,208,130,916,15,138,590,962,558,258,464,629,680,653,96,832,825,973,305,307,701,353,960,729,946,574,734,298,115,458,986,176,450,748,874,550,796,223,429,23,627,733,688,920,862,994,916,780,4,793,70,497,882,322,457,284,519,246,870,62,635,294,981,457,169,983,526,456,424,372,581,66,617,164,298,374,458,893,197,265,994,460,119,266,816,523,739,543,41,327,576,897,152,0,432,630,891,478,662,712,637,706,294,535,90,698,399,802,281,810,602,938,177,4,708,341,224,452,109,98,268,776,878,64,384,953,190,544,419,278,139,776,339,502,986,46,686,221,989,805,744,4,633,627,666,962,133,308,540,291,333,97,438,346,276,174,365,960,521,166,142,777,150,730,864,487,328,192,886,275,934,257,57,305,605,983,541,207,928,199,487,940,580,625,111,225,359,280,6,563,908,93,583,192,413,574,731,637,70,125,64,846,522,95,399,738,756,860,573,985,803,933,244,78,890,178,984,774,153,559,278,872,905,1,379,919,955,200,543,167,988,44,518,28,583,850,721,188,687,893,195,998,554,197,691,600,760,716,506,449,356,152,856,880,68,899,988,389,190,520,611,335,14,863,5,199,656,906,582,967,989,483,883,104,288,425,873,442,102,39,109,661,554,48,69,68,916,917,792,922,511,935,401,550,524,247,468,311,13,958,343", "981,303,640,138,28,180,87,526,98,437,861,278,532,379,253,25,630,558,302,860,101,976,214,936,20,493,138,437,26,692,429,228,633,770,218,166,500,992,659,335,506,723,813,601,217,864,198,207,428,937,697,871,575,179,822,206,271,269,968,599,657,473,873,987,138,901,654,232,779,387,349,482,500,262,309,564,757,339,698,324,64,194,445,256,394,355,53,130,729,717,543,326,750,726,225,326,602,845,984,248,822,206,557,849,884,403,705,674,752,530,487,303,545,364,351,58,955,333,325,919,617,625,711,449,171,713,535,115,240,715,771,287,496,832,289,323,112,586,467,306,630,538,643,759,137,409,76,979,624,437,457,785,239,269,84,347,614,287,585,87,981,537,664,182,389,50,50,767,180,342,493,883,603,984,45,495,933,592,841,770,848,620,769,70,85,581,183,500,125,286,279,293,384,823,355,359,290,770,249,273,485,221,739,253,951,102,540,781,970,216,249,460,956,166,484,846,891,827,763,589,503,94,172,673,997,727,368,100,363,863,879,139,405,951,874,9,936,325,979,905,847,233,764,115,446,103,315,620,320,191,573,380,627,413,672,624,707,838,620,406,727,314,663,790,534,985,59,287,835,349,10,709,106,782,374,375,714,113,222,658,33,627,19,126,767,199,400,123,732,848,121,993,857,389,245,68,825,241,39,127,976,632,103,280,434,83,226,637,370,742,627,884,26,970,253,18,814,259,518,207,199,824,172,385,264,368,771,973,270,139,712,722,671,455,864,711,45,518,605,171,823,467,510,758,410,200,714,404,93,433,510,898,878,685,907,573,122,53,554,119,862,140,126,159,692,33,814,13,693,507,542,999,466,484,394,572,158,946,162,995,728,968,965,707,466,239,537,146,131,294,265,952,172,334,258,542,167,677,184,261,194,176,298,304,638,899,640,632,179,647,455,125,308,837,788,626,427,67,709,361,729,120,644,604,544,453,887,511,362,191,784,758,477,32,21,779,578,977,865,641,447,670,893,657,293,289,309,945,771,498,535,337,684,268,543,555,7,226,148,918,376,151,467,391,178,200,428,186,647,795,859,460,126,186,851,363,231,645,848,420,736,671,894,87,265,36,912,288,150,171,791,877,870,139,557,47,912,845,701,692,914,214,478,334,430,561,758,820,955,613,285,731,453,344,304,412,129,323,44,54,548,757,291,341,825,809,120,254,896,107,761,974,717,645,175,571,682,732,488,428,362,103,631,619,457,706,917,208,398,240,224,953,389,99,713,109,288,379,126,316,811,403,226,405,411,793,208,863,923,901,459,979,290,671,261,941,476,58,378,211,96,189,964,825,584,32,671,71,536,914,516,340,126,191,697,716,978,220,40,38,460,232,454,81,134,855,686,22,707,390,905,598,602,529,622,2,60,679,616,902,476,417,29,674,799,599,675,622,332,931,716,574,863,137,286,147,499,886,487,400,503,791,260,643,974,499,968,213,970,706,116,962,310,635,287,486,391,948,634,178,358,848,849,131,683,256,387,296,413,232,560,916,543,951,342,820,794,272,157,159,299,778,543,268,362,995,44,657,962,319,701,14,602,551,809,686,809,937,347,305,986,149,309,326,652,537,57,390,828,66,698,497,366,467,621,780,903,273,756,829,600,657,471,416,787,380,148,895,999,896,111,852,690,214,38,901,963,698,200,428,300,584,950,807,124,511,922,381,171,528,411,79,377,397,464,737,225,216,927,251,503,39,648,935,700,54,433,444,638,519,119,605,381,680,346,322,906,404,530,996,705,395,485,942,831,635,697,135,853,375,773,629,432,0,600,755,767,487,43,979,419,914,282,107,412,45,661,644,34,632,655,528,423,117,247,302,546,452,205,509,923,128,374,262,559,655,409,549,442,150,846,670,846,332,527,262,743,710,355,845,401,354,439,217,715,308,949,661,717,270,434,581,395,417,679,77,137,472,819,471,403,59,132,980,551,357,341,570,254,387,258,565,901,112,424,120,954,242,163,440,605,222,572,811,336,285,434,441,350,640,388,952,432,251,603,128,291,579,979,356,448,65,313,209,354,890,384,825,600,568,532,583,181,323,831,601,861,831,436,230,682,329,408,646,944,114,797,762,170,447,929,839,350,16,556,651,914,659,609,10,611,901,162,43,562,13,359,869,200,418,63,844,649,997,945,692,847,224,631,948,762,81,410,222,886,277,415,973,154,474,941,143,977,386,651,983,595,884,176,645,190,604,769,287,810,974,404,275,172,225,927,589,922,892,753,974,956,389,296,769", "858,597,221,858,356,965,70,442,222,596,94,3,510,997,527,804,133,448,884,810,675,314,552,653,294,370,19,163,872,486,965,397,244,330,303,746,371,469,261,58,567,95,655,50,783,352,70,511,201,954,750,220,527,875,970,618,102,364,952,698,287,980,755,130,397,50,361,247,583,710,720,748,128,55,860,705,849,886,263,685,486,343,179,207,100,937,80,472,86,394,806,813,54,527,919,156,611,906,43,577,923,217,73,226,319,200,546,30,997,308,522,553,844,154,558,370,378,480,41,197,363,237,840,968,625,843,509,407,560,788,297,354,425,158,237,717,143,173,492,635,21,603,800,230,619,878,769,296,222,361,574,37,499,958,43,193,857,258,267,667,786,284,752,449,264,81,235,690,630,580,554,41,105,129,129,339,646,87,201,816,503,845,938,799,995,25,722,679,754,317,901,150,971,791,577,431,638,677,68,675,868,341,30,179,753,704,182,766,385,303,752,88,302,345,253,193,399,311,711,358,644,810,662,27,111,273,998,167,330,807,486,522,669,328,108,348,935,332,948,110,384,344,715,224,713,623,643,895,850,882,34,679,38,708,263,275,841,919,187,252,380,848,569,722,910,859,381,649,95,941,655,343,441,635,816,198,514,858,20,250,214,144,406,314,802,47,305,309,783,113,687,138,268,5,428,948,18,641,669,52,906,52,515,625,407,602,988,408,143,493,335,692,895,32,365,414,279,308,356,758,168,447,236,34,911,285,920,393,686,590,534,257,560,470,271,333,460,881,89,12,102,151,44,622,671,102,21,155,425,177,340,189,466,183,582,334,961,441,417,363,304,401,68,896,498,347,644,998,323,247,955,597,836,438,644,678,632,669,775,800,296,404,829,506,184,471,771,978,720,270,195,296,340,603,214,250,921,661,161,515,694,474,804,251,467,397,387,379,706,578,106,790,775,243,922,822,464,53,974,320,800,411,788,966,864,286,808,101,546,637,869,415,78,681,369,666,1000,510,148,99,428,903,218,561,881,146,595,111,255,144,614,742,571,821,191,455,373,409,830,113,679,24,689,562,234,967,299,444,858,20,611,890,359,719,291,320,834,942,851,414,96,444,431,797,810,959,4,952,405,671,972,560,10,774,582,844,702,907,388,870,163,274,849,210,125,65,200,116,170,101,292,806,199,898,424,892,502,476,288,647,539,853,747,525,209,533,164,121,732,280,35,614,756,193,482,961,398,588,736,456,761,584,595,418,526,485,114,68,88,483,36,841,653,227,634,186,407,598,795,634,869,347,544,438,197,301,662,45,546,666,47,139,14,917,270,965,227,346,813,725,312,516,866,152,577,676,377,147,895,652,245,804,938,279,806,29,61,757,87,230,146,302,860,240,14,659,115,449,437,187,626,41,279,786,588,334,675,109,805,591,330,71,333,834,838,717,848,707,791,532,529,893,981,194,504,471,969,571,337,827,609,571,387,627,345,602,724,117,576,280,751,917,66,36,612,746,5,178,991,792,644,187,754,359,981,492,787,457,934,739,306,646,317,207,768,382,792,272,559,100,690,126,974,233,135,461,802,920,636,690,795,814,7,653,240,824,499,643,845,802,163,524,241,621,39,723,443,607,661,740,447,345,945,61,564,968,661,786,634,535,633,463,607,485,376,195,515,498,343,907,579,833,15,935,362,597,386,659,987,305,178,445,869,307,556,331,592,241,277,637,690,810,952,975,62,530,442,436,428,994,892,641,580,265,472,653,127,569,359,402,310,624,830,902,979,982,917,246,880,338,773,578,139,221,929,123,114,425,844,89,446,446,630,600,0,772,809,985,47,287,630,992,659,262,897,932,574,521,930,802,241,884,416,558,135,131,624,670,196,803,605,140,277,252,701,943,173,689,301,282,829,459,929,963,166,412,58,381,752,499,829,301,212,527,228,96,242,272,232,105,444,112,904,203,378,717,768,901,404,638,33,197,615,200,247,210,90,498,317,670,658,653,697,157,664,868,237,117,488,6,46,773,645,315,536,252,629,351,40,398,708,325,496,811,137,573,711,730,78,466,996,510,706,54,965,6,788,774,63,288,804,926,508,24,101,472,11,5,217,408,4,648,568,63,718,764,951,577,879,824,751,13,142,993,524,260,183,770,952,526,692,483,719,548,289,457,289,23,97,291,213,748,271,474,559,778,352,945,610,452,238,563,339,958,812,163,516,306,864,499,408,966,968,429,702,122,333,586,338,220,784,81,138,296,536,799,881,995,770,456,17,101,360,991,655,811,782,101,258,369", "790,568,94,596,181,56,111,371,934,295,395,84,773,865,798,569,305,374,941,238,875,915,948,276,742,341,290,509,851,703,613,309,641,312,857,705,403,342,886,712,321,760,831,710,358,878,936,340,621,155,317,727,744,535,702,756,193,844,175,633,115,346,715,85,344,221,725,740,982,721,87,150,391,790,465,668,380,804,606,968,953,989,806,621,976,545,377,802,852,898,731,333,569,693,422,876,491,682,905,90,834,646,619,571,981,585,81,876,903,748,982,377,13,772,506,997,466,782,548,871,642,634,948,245,313,944,119,145,662,380,951,595,871,318,274,895,616,300,322,179,724,318,969,585,929,107,458,353,360,741,522,55,371,559,990,675,895,985,123,440,534,427,286,135,700,709,137,414,440,220,77,854,244,208,752,32,582,458,786,65,384,21,998,931,762,455,966,181,571,213,635,178,678,16,287,761,887,933,915,424,813,641,192,434,967,649,730,926,497,534,942,856,68,113,479,397,623,64,926,345,380,857,332,21,179,699,425,932,601,65,677,11,340,385,885,132,713,131,561,245,998,283,130,556,142,31,629,387,6,443,597,13,930,937,695,431,908,702,241,631,393,254,369,158,140,762,884,308,519,109,907,245,218,503,487,457,81,108,848,906,927,241,764,825,304,369,852,558,780,425,775,913,961,316,864,716,884,445,807,242,866,619,460,746,491,777,441,736,773,135,74,367,150,672,867,405,597,981,155,547,891,365,620,60,648,57,808,460,238,872,973,526,477,499,809,863,681,85,644,947,715,290,771,570,306,216,97,618,986,393,439,201,499,81,952,284,402,298,628,924,736,169,150,146,375,203,85,571,349,890,66,787,360,338,152,183,64,32,442,753,417,352,762,479,465,17,769,196,343,475,97,792,485,803,382,892,412,224,336,945,812,414,3,595,84,336,730,432,591,559,816,694,611,800,726,813,413,257,404,699,293,123,147,756,496,699,455,375,445,961,919,918,712,543,121,677,244,600,809,211,640,839,238,302,862,390,818,335,909,196,373,761,945,806,430,612,399,331,624,971,293,886,434,35,526,450,543,782,526,835,774,979,374,854,174,582,688,247,186,360,865,496,773,656,612,21,960,511,960,203,669,608,899,999,341,987,360,638,409,632,361,498,961,860,119,149,574,569,344,161,348,24,151,891,528,551,528,408,819,833,808,689,784,471,704,567,974,996,739,621,447,927,460,488,23,39,48,512,698,248,395,654,572,255,516,780,930,28,658,27,782,925,232,928,225,579,699,415,56,548,391,471,580,183,790,260,581,462,548,223,68,946,502,457,283,513,470,511,62,464,489,238,416,173,580,281,384,71,432,176,242,217,628,385,984,898,332,249,246,469,408,209,682,880,309,607,930,665,201,122,422,724,59,719,879,935,733,686,311,582,599,909,225,104,595,363,38,437,124,752,238,817,870,491,621,959,385,384,187,215,541,15,635,294,750,131,513,284,261,936,764,42,6,658,279,815,33,476,774,1,291,589,915,970,239,708,407,970,102,822,963,259,728,20,245,700,773,230,558,30,825,496,908,986,841,338,588,634,883,364,321,689,389,269,973,329,525,237,477,421,321,447,67,872,780,462,178,511,115,34,959,581,33,383,206,511,262,464,378,201,161,291,354,431,896,18,242,933,369,961,244,508,24,163,590,272,14,957,824,464,197,838,69,451,909,162,549,393,980,663,533,214,165,155,297,944,608,495,816,284,449,19,849,299,411,275,890,791,969,987,285,868,683,58,183,75,588,642,321,878,859,343,69,861,954,247,240,460,614,458,27,153,891,755,772,0,872,80,176,945,100,80,701,618,6,230,171,849,649,201,150,773,761,647,660,793,304,659,134,353,893,945,521,58,348,319,645,412,204,190,427,218,550,405,804,871,176,496,684,549,852,164,222,963,709,648,74,591,644,705,993,447,145,118,730,22,60,757,778,264,833,198,190,821,775,165,55,493,853,662,129,168,599,486,807,285,522,137,308,330,363,102,290,640,789,954,645,1000,472,235,79,490,177,76,314,920,304,523,240,432,292,204,508,722,439,212,167,466,129,777,638,741,170,233,882,486,452,782,281,463,100,196,113,966,728,286,881,493,550,4,774,15,195,342,617,981,792,277,282,834,545,119,110,412,293,659,658,806,300,243,467,945,448,524,491,834,435,336,662,348,728,701,976,328,178,183,414,500,631,704,8,617,770,427,518,459,173,690,260,960,724,316,737,741,370,151,988,83,921,869,953,343,193,916,581,20,3,50,799,366", "268,640,937,439,864,446,628,532,211,730,893,166,695,153,733,553,998,987,338,279,35,660,465,203,67,461,481,638,829,322,399,473,121,991,80,222,800,435,144,768,912,504,303,685,559,5,548,365,398,906,615,522,187,842,664,835,529,242,265,202,262,47,419,138,501,117,88,596,926,587,154,164,721,604,185,816,705,708,842,433,328,69,294,15,586,741,452,72,110,358,328,21,303,706,240,371,274,70,495,508,609,873,313,305,827,749,298,973,678,588,645,685,316,562,456,62,785,644,27,908,917,935,256,583,861,382,143,690,366,857,381,102,361,492,427,652,244,458,157,974,195,200,506,193,19,576,337,760,256,525,544,158,811,136,432,849,552,860,809,575,573,722,98,361,875,764,591,209,5,632,372,151,994,578,752,151,463,69,675,786,614,671,133,164,288,290,222,100,38,901,67,76,401,331,193,411,866,789,259,378,248,798,501,78,578,181,61,128,534,260,542,519,366,243,606,125,129,962,709,499,774,89,227,505,499,785,400,873,747,244,227,119,369,555,216,687,386,724,531,775,354,546,54,803,279,373,504,341,9,708,955,642,388,192,435,711,721,735,90,679,780,924,212,877,167,464,524,338,706,553,173,766,745,414,118,705,602,909,675,745,119,191,657,782,904,404,449,186,990,670,386,618,573,953,542,994,925,747,481,945,646,452,520,185,715,151,157,211,754,242,561,87,124,244,40,323,818,418,348,557,828,653,951,609,887,258,242,334,967,495,40,203,466,277,566,449,68,765,751,338,21,226,453,74,937,611,798,198,171,837,96,288,648,671,926,65,783,814,593,526,862,51,211,536,407,24,204,52,654,339,635,795,278,237,832,759,709,517,516,875,797,594,231,871,274,287,732,204,598,110,721,644,610,368,870,787,804,948,748,646,116,948,336,650,999,491,42,656,105,206,39,602,54,57,785,793,83,487,979,431,182,509,607,731,723,785,994,688,640,453,869,875,761,752,834,139,24,890,639,519,485,33,615,109,590,316,64,562,329,341,31,137,847,23,583,244,549,851,594,791,45,888,7,575,920,67,828,371,278,985,54,100,745,188,815,311,544,143,297,749,761,764,321,780,212,608,787,229,376,2,30,769,363,73,468,4,438,64,523,417,198,590,745,399,747,14,424,670,932,857,611,323,929,746,87,136,829,458,888,593,428,915,976,975,549,229,716,442,283,994,49,63,651,642,619,704,969,832,852,483,107,731,511,223,236,5,775,782,971,820,599,729,620,463,478,265,70,546,589,686,208,236,500,362,268,72,746,308,548,932,575,778,256,556,229,834,570,943,630,917,407,61,298,744,9,991,627,960,189,210,852,583,989,805,792,859,801,95,586,390,880,369,344,867,115,399,151,137,217,392,2,325,152,586,149,648,50,425,699,837,737,353,974,398,258,949,134,741,900,918,850,941,634,211,575,394,583,371,957,668,671,184,557,419,773,449,502,489,308,18,709,83,895,980,16,708,969,418,573,641,136,136,134,28,487,379,300,598,424,663,833,834,341,989,818,558,801,121,776,91,150,426,317,994,862,172,35,553,669,961,192,544,13,893,10,533,68,669,20,123,235,464,881,273,167,186,532,704,472,880,216,557,655,537,681,563,822,546,843,129,111,944,697,497,666,82,469,83,817,644,881,986,380,586,404,359,858,734,125,536,228,122,573,454,29,786,146,1,764,985,102,479,289,66,663,179,511,998,127,414,696,689,237,253,894,522,545,721,664,79,644,761,957,474,122,65,706,598,792,531,637,632,909,462,631,176,933,64,945,277,702,422,478,767,809,872,0,812,949,853,822,474,363,632,648,417,162,882,460,218,473,304,156,794,557,270,396,771,294,936,55,174,848,66,893,312,346,924,67,646,601,509,636,255,148,165,176,364,664,656,196,387,748,364,475,357,283,765,147,546,914,722,654,151,255,685,129,317,424,84,691,934,523,54,796,713,464,655,430,596,363,40,606,707,747,866,445,159,384,221,253,550,692,830,849,443,190,762,275,126,543,545,450,185,369,822,33,426,253,684,588,851,335,692,964,71,659,588,689,300,697,938,112,986,154,825,976,275,350,398,595,107,850,866,111,305,21,374,141,316,714,21,911,443,96,79,607,868,952,750,767,768,19,372,26,78,691,956,269,289,387,301,635,849,642,153,48,415,376,500,839,938,193,788,761,428,434,590,341,887,222,672,287,875,911,120,60,804,301,234,952,474,686,970,223,772,926,275,242,564,640,667,649,726,247,723,541,799,761,637", "176,328,576,930,889,9,694,871,423,969,280,566,695,161,798,726,437,402,749,799,865,355,662,638,786,210,460,858,553,566,411,394,434,895,878,258,123,515,246,722,668,935,81,267,289,251,846,268,769,244,507,633,624,592,141,458,241,711,926,658,114,976,9,422,604,728,756,333,41,984,521,689,110,176,611,871,573,50,946,950,187,626,494,494,991,28,797,342,115,419,993,46,88,662,861,561,325,227,514,60,490,678,315,474,711,602,395,724,564,448,689,570,20,104,107,543,598,880,191,746,571,334,477,106,832,205,121,759,54,781,377,488,516,315,527,185,314,199,189,620,882,254,465,7,394,166,642,891,202,698,714,705,910,42,114,106,128,293,355,874,625,289,167,888,501,843,788,762,573,299,231,930,214,568,497,577,393,174,496,659,162,945,168,317,649,10,763,386,484,506,385,968,250,600,880,770,509,804,250,365,568,70,640,971,224,742,906,887,409,317,287,679,470,253,930,551,803,366,358,304,979,791,656,544,229,53,544,861,394,523,261,15,945,575,702,392,12,611,801,416,58,35,375,865,49,27,410,249,426,582,631,650,489,260,51,523,261,359,804,559,426,405,957,483,536,841,949,422,417,923,929,178,104,771,285,866,739,640,751,480,932,575,839,619,161,852,683,520,645,563,149,769,427,647,375,131,973,810,446,586,295,517,760,782,917,687,545,156,223,925,176,717,281,418,923,431,601,932,858,671,456,367,692,516,986,96,33,913,684,539,343,448,677,273,446,425,542,729,314,914,164,147,783,287,532,969,373,429,657,439,862,573,415,339,743,35,36,195,464,466,56,348,621,627,111,793,568,737,347,874,877,429,128,861,61,569,756,932,103,15,108,903,525,696,405,817,732,549,424,707,420,619,768,251,762,844,47,357,190,295,576,263,468,311,683,69,665,351,331,806,861,445,710,628,14,48,167,463,957,895,737,43,219,11,14,837,702,401,285,290,235,705,127,528,266,148,72,590,114,136,487,212,113,519,758,814,113,224,864,773,396,435,896,258,132,600,444,457,808,436,2,299,409,172,158,338,454,482,723,455,560,980,811,783,341,868,834,889,906,641,736,826,389,733,794,695,144,854,649,60,723,774,354,146,955,322,748,232,84,315,329,580,413,404,875,377,234,529,746,586,414,125,761,212,684,818,764,205,584,367,767,97,434,854,927,589,873,464,723,904,2,855,226,867,526,894,876,525,602,567,274,146,345,417,697,400,29,660,194,973,967,436,754,515,294,156,270,305,98,412,470,492,148,469,69,852,950,155,268,153,507,713,344,22,268,163,183,353,14,158,733,486,909,892,474,393,653,747,74,469,886,232,498,696,360,794,968,865,854,313,168,417,432,35,89,438,291,440,726,333,984,783,414,687,259,398,713,996,13,291,706,244,180,692,248,953,950,883,49,331,663,425,603,235,667,63,675,939,533,235,232,147,986,432,382,645,515,397,650,835,789,52,985,876,568,71,394,882,509,950,44,234,710,698,508,409,229,554,72,879,101,991,686,352,973,119,419,661,776,945,510,88,865,808,28,918,953,827,726,128,686,706,550,477,147,314,968,177,912,738,917,824,367,201,355,6,919,299,505,672,7,500,632,418,102,677,407,31,606,916,781,15,668,339,110,809,179,364,897,160,930,274,929,3,454,317,393,581,464,423,58,120,640,167,384,971,575,261,36,643,31,710,912,944,833,259,409,230,544,793,392,482,262,306,721,879,765,239,298,308,521,389,388,912,768,679,953,364,44,256,211,667,399,92,598,359,733,902,599,881,715,572,662,487,985,80,812,0,488,908,543,964,981,126,258,753,405,892,225,657,442,903,663,974,796,535,977,673,63,440,450,472,35,192,820,290,906,254,484,146,415,836,113,849,107,673,706,983,40,901,862,576,499,759,892,522,571,784,447,318,420,263,199,52,551,646,395,632,353,382,779,234,827,64,440,123,955,167,622,447,822,810,37,11,134,258,86,520,900,188,342,117,545,796,416,927,789,234,184,215,914,968,119,211,209,432,832,977,244,760,37,335,311,891,383,913,776,586,223,72,455,186,651,938,654,700,251,773,868,605,176,43,699,500,990,446,579,276,300,570,632,512,729,907,371,775,970,254,622,685,777,349,211,199,84,785,497,340,366,498,726,911,81,716,538,54,233,775,925,631,242,185,86,864,464,885,572,67,36,491,388,700,813,321,965,966,75,6,760,189,615,277,599,527,993,632,960,65,947,202,238,419,848,911,259,349,500,684,603,377", "998,932,995,922,143,568,514,618,177,926,764,850,391,43,253,341,614,637,93,870,50,350,160,152,35,862,485,895,363,458,240,911,429,391,14,406,505,394,945,253,543,632,496,399,584,824,17,258,412,86,495,660,823,313,430,989,717,120,877,244,785,350,509,755,168,466,272,553,138,894,858,226,39,216,137,799,900,217,469,359,759,143,53,649,861,630,321,980,436,297,100,58,58,15,571,7,292,607,249,909,358,372,17,512,251,27,54,410,854,61,609,612,397,853,256,470,114,601,992,124,631,827,496,439,988,173,364,892,290,455,215,576,671,697,100,435,661,156,619,34,705,709,471,420,836,739,614,674,780,122,342,921,150,611,405,815,851,494,551,778,948,766,625,613,505,570,524,757,282,919,341,907,864,214,280,10,3,661,242,612,31,357,41,406,681,815,412,616,268,127,266,921,35,933,751,708,642,226,363,90,857,121,462,26,651,233,221,487,454,15,760,422,944,256,526,516,102,446,523,98,725,816,975,129,273,331,962,338,132,220,404,986,626,813,999,812,563,897,453,439,485,244,336,68,446,328,225,427,150,184,338,689,864,554,866,217,250,88,311,562,570,542,380,621,393,848,531,806,288,121,881,597,122,711,301,506,587,996,964,96,616,621,274,349,41,374,889,30,245,958,529,758,515,199,723,521,630,593,290,184,53,242,672,966,241,20,95,492,511,530,366,550,17,599,35,732,281,462,45,208,315,253,723,864,962,687,788,256,623,318,607,465,396,927,111,160,801,912,727,611,156,111,529,302,341,992,875,917,348,852,448,148,989,718,725,863,499,502,460,755,53,497,886,412,295,79,436,671,504,371,861,648,795,358,659,425,532,201,247,406,759,442,723,246,936,561,231,437,902,914,501,372,792,18,97,580,776,565,569,793,460,489,633,407,16,198,789,470,966,830,709,347,676,565,333,46,868,934,620,469,231,751,163,866,786,658,532,964,799,474,220,75,146,396,895,792,806,557,999,91,517,199,928,304,971,409,287,183,355,863,509,356,876,247,148,412,706,793,636,321,558,350,598,642,485,919,627,151,794,583,338,853,773,357,920,69,829,9,865,913,586,597,646,157,596,34,58,682,127,72,829,219,344,287,767,549,264,850,332,315,946,184,9,309,973,506,671,743,535,349,123,876,729,98,602,403,916,591,298,607,925,356,226,188,387,335,901,159,398,419,764,613,280,422,960,222,332,559,635,240,508,574,864,825,546,870,942,598,736,752,551,510,86,5,29,615,194,980,442,161,153,441,63,420,608,463,59,106,861,966,307,199,956,31,304,960,297,262,415,832,176,561,967,858,75,224,569,138,906,201,866,191,960,452,26,533,121,131,407,468,834,571,51,623,801,936,432,753,933,439,501,872,130,576,64,438,668,368,746,712,510,299,998,844,514,503,885,459,919,513,788,772,925,193,732,369,751,997,520,577,401,712,962,23,745,363,6,464,164,577,412,111,749,905,595,721,764,963,161,980,871,916,321,357,799,913,214,159,965,943,116,232,136,172,268,406,195,996,723,60,918,306,544,988,497,849,566,215,625,523,514,230,270,821,944,716,370,359,884,591,662,258,55,224,694,668,104,4,152,555,873,117,425,698,271,727,173,97,6,392,965,493,492,820,449,744,838,410,11,92,137,921,405,641,844,806,703,172,951,564,110,617,608,864,913,319,708,803,434,649,143,371,719,661,333,351,297,756,347,312,169,934,204,308,879,404,403,59,3,849,733,975,312,126,668,667,581,448,435,172,451,101,215,821,916,756,142,641,746,865,972,518,712,43,47,176,949,488,0,543,783,553,344,839,892,40,288,298,359,645,107,976,744,178,656,283,979,518,633,908,918,407,556,944,96,846,751,953,634,137,144,62,617,459,735,675,817,638,521,313,498,85,731,447,169,365,149,503,320,448,876,639,237,571,526,571,962,597,802,965,346,496,554,960,433,27,258,357,950,125,715,809,139,777,83,199,609,28,838,106,79,755,801,77,956,604,611,560,752,109,547,175,914,336,567,596,156,200,143,176,132,221,234,627,674,990,18,504,778,399,194,216,538,370,304,479,432,925,839,886,596,24,536,38,727,384,565,919,26,500,118,762,363,265,867,250,587,159,713,931,640,615,782,752,906,923,51,115,494,172,728,65,216,742,713,340,97,266,11,448,928,967,498,954,778,403,989,956,399,198,132,835,911,123,323,36,837,729,527,206,584,231,985,75,512,366,67,515,436,233,894,289,255,27,443,11,639,537,150,289", "811,520,751,316,916,837,117,852,423,313,231,713,891,573,327,378,602,698,809,420,127,805,733,515,265,332,107,463,572,470,646,780,144,716,728,884,258,795,636,116,307,663,202,332,472,828,818,940,398,319,631,544,751,335,306,729,108,959,152,551,860,441,351,199,166,150,491,759,168,602,50,841,785,815,693,630,844,833,827,171,598,649,250,78,90,804,928,616,50,542,733,109,689,808,306,762,655,8,821,453,924,289,197,655,252,206,773,972,975,581,445,19,618,127,499,904,922,353,838,405,899,298,980,818,378,553,288,559,912,853,361,837,987,701,386,137,495,3,101,956,379,996,508,286,904,325,185,596,788,183,648,29,731,473,803,527,432,333,146,20,594,382,817,366,355,738,279,671,14,943,635,186,368,998,94,792,235,651,643,526,305,850,238,8,252,207,811,622,550,332,486,849,509,722,26,668,426,208,570,120,416,697,690,54,362,515,217,791,270,5,115,364,314,197,71,206,19,608,430,316,464,825,578,99,841,217,150,374,158,726,978,593,64,718,651,163,184,934,558,794,616,303,689,585,4,536,309,342,631,720,753,593,905,418,110,332,236,661,347,985,166,19,146,258,279,129,692,391,442,832,831,618,611,633,641,505,571,431,606,56,139,789,78,102,147,587,114,264,653,465,599,749,473,450,143,849,507,185,745,937,54,416,325,910,849,707,307,206,306,214,716,698,823,24,314,128,384,478,425,975,562,117,198,564,816,230,828,793,124,267,226,541,442,157,343,516,171,622,916,447,424,296,5,259,258,278,702,147,769,375,527,378,346,382,544,14,286,747,751,244,447,373,706,132,280,525,728,958,18,438,306,480,183,955,641,768,501,359,675,291,96,953,211,460,804,524,681,460,567,520,905,249,308,559,953,310,668,208,121,712,333,726,373,241,629,797,497,855,873,165,537,729,541,620,616,359,150,635,962,143,888,514,830,434,477,769,35,891,391,609,271,991,306,380,931,5,621,774,891,378,715,328,488,837,253,964,383,63,841,406,463,344,159,992,711,920,77,802,499,228,350,933,566,766,817,722,428,980,290,915,870,633,920,868,157,507,142,543,119,83,877,95,640,265,334,569,666,786,770,617,348,410,212,748,383,697,406,729,370,679,459,4,742,903,146,972,304,565,99,983,329,33,234,978,179,296,603,82,185,532,334,291,310,876,412,929,238,153,520,11,429,648,168,928,810,466,985,988,303,525,371,567,120,757,404,761,56,904,571,910,777,136,483,696,369,54,528,98,23,273,347,276,863,31,296,466,438,48,292,3,716,730,485,349,477,566,165,721,688,532,482,324,967,393,198,412,802,428,828,620,233,132,325,875,404,304,407,698,561,8,343,707,649,522,444,650,309,82,889,946,48,127,58,550,252,937,211,465,644,628,54,144,511,386,63,530,254,722,189,438,392,290,19,722,881,962,368,539,228,658,70,657,152,832,345,620,740,590,207,668,49,341,876,334,496,198,614,70,53,191,843,12,928,359,98,299,326,205,874,897,307,770,858,242,398,734,913,257,947,121,605,180,806,950,917,855,159,515,971,27,554,276,33,65,803,681,595,842,354,668,134,992,531,317,880,908,47,240,777,506,450,492,119,3,220,557,401,997,261,813,502,918,817,92,127,211,953,408,193,503,831,346,596,149,224,8,585,408,808,737,816,882,87,812,505,515,931,427,70,463,783,833,524,28,884,889,882,209,28,202,743,370,137,348,878,72,335,627,974,33,670,174,728,153,286,287,786,40,922,910,975,259,228,48,433,9,71,706,813,291,64,45,637,979,287,945,853,908,543,0,915,757,102,954,566,244,61,677,829,572,936,194,581,281,386,353,990,459,228,374,502,154,200,600,872,129,327,388,332,695,164,838,847,489,887,990,22,211,972,7,973,512,119,151,824,669,290,232,242,193,767,459,82,776,777,637,975,573,427,803,419,547,334,298,218,233,529,204,979,251,294,99,90,967,899,631,440,105,528,382,437,322,319,995,978,2,399,782,850,840,682,310,236,755,650,846,297,407,586,419,212,869,220,506,830,309,556,472,979,49,845,855,240,752,849,789,727,512,377,493,810,613,207,603,957,151,932,902,49,824,642,607,903,994,654,20,459,226,15,228,406,677,133,702,755,557,164,330,28,602,565,10,397,567,271,61,871,208,645,491,39,50,101,952,83,393,389,190,113,639,701,627,623,853,731,239,266,465,64,419,916,924,936,719,198,338,742,728,883,601,957,366,713,342,934,80,953,76,889,768", "987,288,235,917,455,211,617,992,250,755,276,735,325,924,947,690,270,566,60,652,356,507,435,799,75,941,564,55,801,938,850,468,357,736,922,729,437,508,62,346,510,733,320,779,182,8,373,235,827,151,703,598,90,811,719,87,985,317,15,779,254,186,731,934,579,294,699,635,252,22,879,193,6,832,887,245,12,604,275,249,338,172,202,53,321,170,772,621,500,729,549,303,831,927,230,826,760,552,749,462,514,64,522,142,866,957,259,236,912,285,880,948,542,783,47,598,398,992,543,205,445,403,89,149,617,112,127,916,997,316,852,738,1000,659,571,203,743,99,53,13,1,348,454,303,657,161,397,93,261,72,319,861,15,270,332,608,274,470,484,640,346,614,777,506,214,782,361,235,355,272,359,900,590,72,897,246,263,380,908,278,574,349,347,879,798,557,340,971,797,887,284,23,390,449,830,725,348,749,48,754,565,623,605,76,890,133,681,272,775,192,757,95,267,103,917,726,336,175,10,475,927,796,740,885,65,829,486,506,876,287,84,399,723,474,559,473,616,966,463,966,464,379,758,193,179,140,524,918,188,769,798,844,297,32,246,913,982,168,591,415,732,127,10,430,162,916,79,509,192,959,684,687,807,634,306,782,246,760,937,185,938,365,974,246,693,958,240,843,566,882,585,304,759,434,832,62,36,766,406,610,683,726,887,582,662,896,551,642,815,800,122,968,708,23,933,561,942,139,868,321,621,537,217,779,396,609,482,419,787,246,42,289,395,594,447,69,879,828,504,279,27,889,408,729,222,156,23,938,434,271,791,214,751,347,472,749,73,229,893,971,672,400,734,262,954,776,942,25,159,337,869,489,355,761,608,782,118,410,514,254,424,34,507,740,850,423,167,557,352,971,28,406,187,788,994,974,1000,773,553,557,203,186,916,988,60,81,21,773,3,275,343,676,857,716,850,909,108,487,678,452,599,20,227,19,951,39,630,532,595,805,667,732,504,702,342,881,269,226,692,139,961,845,618,967,184,399,818,419,431,751,136,169,778,701,659,67,532,765,25,211,974,524,355,914,260,475,440,839,894,220,550,803,224,973,269,555,509,578,531,662,74,533,344,663,718,592,424,152,912,475,908,995,36,887,661,489,777,117,808,754,423,195,584,100,274,83,683,885,50,234,186,46,694,529,784,754,212,378,303,440,741,412,487,858,949,888,207,714,685,702,251,591,623,370,136,487,598,387,266,131,791,277,104,355,684,470,612,479,293,29,214,331,953,88,445,6,341,235,74,487,982,822,131,660,366,163,807,180,565,370,725,756,673,575,53,673,206,206,897,737,275,881,936,259,456,89,11,938,36,394,247,599,964,725,48,846,62,591,200,260,248,898,958,444,772,580,480,133,721,239,127,592,837,841,253,792,607,551,650,817,17,719,100,161,105,106,959,890,90,296,316,523,911,290,977,308,854,667,552,11,684,490,916,93,549,674,495,683,493,54,761,73,562,387,589,588,400,944,640,651,927,48,146,634,979,534,496,78,466,871,951,991,23,436,74,422,215,3,921,497,350,473,342,658,113,775,587,884,274,121,618,585,87,724,766,782,767,300,618,672,402,206,606,588,81,224,921,852,516,520,130,595,869,248,387,86,847,383,742,59,670,268,830,358,65,102,363,411,631,368,460,577,774,69,194,788,369,832,758,292,550,885,411,348,568,590,758,368,934,984,73,220,894,73,152,573,404,974,479,773,273,830,664,653,743,21,332,68,921,891,607,396,522,478,176,352,623,168,436,847,643,495,167,352,653,331,603,826,358,569,597,389,706,419,630,100,822,543,783,915,0,612,924,640,642,532,181,909,354,456,752,336,677,773,605,251,108,967,283,342,588,488,954,193,667,865,482,701,265,284,62,460,365,684,837,761,485,526,554,9,793,949,407,803,18,61,441,346,385,974,792,944,524,693,669,722,531,704,944,555,174,438,484,344,131,744,740,590,674,496,852,234,318,559,479,788,543,722,453,582,488,541,180,752,153,91,353,900,89,150,685,81,948,11,130,927,43,318,710,721,917,789,78,774,846,165,770,331,304,785,70,344,779,717,565,387,295,357,229,71,121,276,457,945,817,572,505,322,735,520,654,634,501,521,854,955,420,823,531,674,939,994,558,635,601,735,622,122,93,925,48,871,325,351,827,863,451,905,544,373,812,922,721,168,526,908,982,785,895,512,806,673,629,571,519,276,589,699,173,840,143,789,583,156,134,456,690,719,816,143,795,678,838,799,61,323,663,159,926,584", "130,663,914,751,731,865,239,84,523,791,637,63,714,692,595,231,470,702,509,678,400,200,460,359,926,613,719,813,972,748,586,887,441,661,881,486,330,599,138,217,334,768,522,594,139,801,318,127,534,357,837,292,541,873,474,190,352,139,832,98,674,526,44,894,213,533,365,263,496,183,748,651,83,483,770,209,432,701,150,683,855,1,948,614,991,389,434,261,617,998,413,270,141,295,689,870,725,840,645,212,231,573,343,643,839,142,656,760,589,507,88,430,881,718,970,317,274,335,664,162,373,516,806,825,529,915,524,469,101,812,892,369,118,955,880,155,262,492,280,234,252,320,419,340,102,310,327,297,823,993,9,433,104,760,690,24,835,71,242,236,569,421,535,636,958,470,858,74,564,877,616,611,248,394,990,962,919,302,537,707,779,812,438,681,264,213,79,879,440,51,901,881,89,221,815,676,254,273,493,80,783,525,66,109,591,886,731,172,693,425,485,140,216,703,883,537,536,737,458,612,855,104,439,822,549,592,344,253,163,587,28,978,844,810,729,188,884,131,359,655,731,916,554,651,70,395,765,306,403,213,329,874,952,585,949,968,366,401,717,489,987,819,64,112,381,675,246,314,154,448,943,553,720,108,945,41,682,924,389,767,575,809,715,259,366,683,598,385,103,756,771,195,554,939,261,833,613,193,308,329,818,62,96,616,379,294,876,662,100,148,318,862,716,90,218,817,738,687,600,725,553,363,813,611,153,969,702,399,345,811,972,215,31,611,470,607,597,352,892,187,562,341,308,387,533,989,541,760,980,714,91,673,92,882,310,114,689,764,374,399,661,984,418,152,225,904,549,781,580,840,240,470,423,587,846,63,906,723,512,749,82,112,91,564,833,415,265,862,867,236,131,956,953,48,373,286,120,275,590,546,666,439,597,324,625,528,881,966,362,537,681,114,328,257,82,67,545,321,318,327,887,656,891,957,823,280,312,794,276,118,491,534,714,692,736,7,993,115,873,268,306,16,62,829,247,482,339,612,695,151,912,960,756,899,867,209,605,212,182,699,685,631,71,347,233,333,652,486,72,354,254,788,298,507,834,631,554,430,563,124,407,577,925,568,971,556,181,186,237,588,98,21,337,227,97,919,162,471,680,998,152,213,229,776,548,793,878,836,50,594,766,26,368,663,493,443,498,102,685,988,517,848,627,172,347,974,393,10,578,34,21,727,369,481,638,410,476,838,857,224,761,736,753,526,257,570,741,645,381,603,974,759,457,726,572,529,131,115,984,171,831,685,522,513,357,627,544,740,955,549,80,51,966,846,198,228,34,517,745,705,157,329,874,734,839,490,460,611,244,895,570,612,418,580,233,372,355,300,853,98,986,836,354,74,931,443,477,302,781,231,758,288,742,260,113,843,158,163,725,672,62,391,257,49,379,712,397,595,338,67,226,755,352,834,580,544,958,825,365,797,513,351,149,542,381,494,854,236,349,422,460,557,791,617,951,480,975,388,738,887,41,99,795,976,142,685,889,331,447,674,923,146,575,55,558,239,603,931,836,401,825,819,342,879,678,809,910,11,870,879,674,391,193,765,903,120,519,189,816,396,749,988,195,881,700,276,924,123,288,21,528,535,853,575,289,197,532,507,331,457,683,68,289,54,647,729,202,972,590,993,697,648,715,596,23,480,209,46,82,329,138,491,910,329,996,405,779,152,539,799,679,194,436,352,681,558,708,605,152,648,912,662,755,381,128,154,942,140,165,450,177,507,934,561,536,332,53,706,620,163,562,103,8,458,699,794,511,339,93,987,954,766,294,914,992,80,474,964,553,757,612,0,741,779,31,989,230,588,876,161,26,683,653,154,770,140,331,622,392,752,755,7,174,28,587,504,658,370,181,189,616,373,750,119,110,780,932,326,150,34,513,752,738,516,391,87,891,101,368,672,236,354,867,215,835,749,284,320,86,590,30,28,757,744,520,158,827,725,949,546,789,390,127,371,157,714,535,643,445,111,172,125,515,3,338,238,430,459,671,666,844,511,709,607,43,309,744,149,617,511,777,745,710,638,452,587,394,264,504,401,75,783,748,569,150,753,111,233,569,972,533,691,530,371,350,555,705,861,208,92,866,380,646,517,211,226,179,357,64,341,875,206,580,646,727,425,139,531,337,898,90,576,889,789,488,976,125,516,795,816,633,558,598,555,522,317,484,861,320,851,144,552,36,482,15,31,12,277,286,752,66,521,238,147,123,15,467,110,259,780,994,195,587,224,8,82,440,922,524,783", "307,519,855,203,655,280,425,430,750,579,655,627,929,17,4,168,190,848,593,119,376,507,638,134,927,200,932,913,203,35,173,787,273,710,149,177,79,740,930,523,685,531,131,844,333,595,192,676,359,470,637,292,29,270,145,161,550,538,645,425,95,26,134,149,808,515,538,165,293,566,416,642,932,672,357,470,605,353,388,610,669,411,66,463,215,293,309,114,371,16,930,130,91,970,846,184,340,545,278,927,446,763,760,807,661,305,877,983,80,812,818,815,86,790,942,237,174,108,138,209,887,812,32,336,108,905,810,101,84,695,389,552,565,345,15,878,434,454,742,852,646,734,839,293,808,776,762,998,55,151,802,776,52,459,790,644,622,974,394,657,831,240,59,979,139,69,640,324,83,393,543,248,356,610,10,237,276,8,973,582,695,412,834,682,186,782,469,650,882,52,483,922,934,848,630,351,773,393,88,624,111,281,476,429,159,311,582,713,180,225,229,9,880,172,710,813,878,720,474,139,592,234,101,817,374,160,546,179,883,889,79,729,515,561,652,694,234,959,575,641,68,465,100,766,603,200,657,920,394,940,348,634,847,751,443,992,234,796,744,322,551,859,28,195,117,479,536,742,102,656,811,413,421,802,916,561,485,432,544,87,501,762,135,686,58,718,835,979,349,301,166,819,629,913,417,348,541,677,565,326,957,132,280,838,530,339,951,123,467,465,900,176,507,675,200,681,276,984,482,266,297,377,291,638,959,512,228,581,677,762,165,698,973,586,829,851,502,879,439,744,626,198,650,530,489,584,183,926,890,612,103,714,581,738,873,149,845,318,973,988,136,649,458,187,26,522,346,161,915,733,92,674,944,690,291,262,344,896,351,308,861,545,608,811,263,433,487,517,175,898,239,312,822,185,345,40,351,376,120,35,203,686,356,825,818,494,450,446,247,568,508,342,637,332,722,480,386,960,906,346,570,907,170,577,282,974,16,851,300,318,828,290,488,494,769,761,57,441,5,44,149,925,926,333,925,21,526,571,913,667,358,15,959,70,936,596,501,34,901,61,614,942,280,676,472,722,828,288,143,208,789,841,254,851,430,448,52,499,163,583,166,575,676,132,503,209,970,86,642,954,277,173,64,78,71,181,168,221,136,266,914,668,831,934,33,310,525,468,860,658,284,998,102,707,148,209,587,715,57,661,90,244,652,597,53,785,140,369,769,347,769,190,715,610,216,183,787,757,172,190,687,606,450,622,37,955,843,886,390,550,456,371,173,848,54,322,138,445,47,138,646,162,468,352,999,15,21,357,580,335,434,582,856,515,61,411,164,400,698,309,533,153,929,237,839,937,934,177,18,833,969,642,356,280,841,130,247,962,207,392,421,244,550,844,362,861,508,155,242,207,918,669,695,250,205,786,233,445,334,621,658,199,488,798,421,432,299,9,404,43,948,692,277,619,890,557,644,726,946,75,715,315,259,910,314,790,392,342,716,746,879,224,194,988,312,818,897,870,166,702,429,450,627,352,242,155,153,10,4,321,794,64,729,248,557,280,405,295,619,304,530,554,505,239,709,761,23,810,577,211,714,735,8,223,880,443,165,875,21,285,644,250,147,240,203,997,584,874,968,217,876,379,169,93,949,63,194,245,336,385,391,732,155,16,253,973,936,866,313,399,332,54,945,364,477,260,177,755,680,630,605,776,388,658,973,140,33,917,945,759,550,924,801,686,774,365,131,727,998,685,67,302,636,806,786,139,921,791,834,889,145,174,829,521,764,96,235,45,2,696,609,194,529,590,136,959,252,209,592,158,418,982,535,282,659,701,363,981,344,102,924,741,0,1000,144,191,675,661,59,86,698,918,937,796,367,175,666,97,981,116,776,21,611,354,634,409,5,926,378,200,530,337,567,889,911,933,455,982,864,97,518,277,731,433,703,716,240,585,986,98,101,96,656,350,872,786,152,964,32,138,373,108,223,864,544,30,84,513,997,556,960,64,223,34,354,551,829,647,183,51,151,56,271,929,251,714,660,867,206,761,847,633,665,697,678,556,522,455,73,626,329,114,276,273,569,745,61,542,56,539,73,813,10,117,103,17,264,675,387,866,374,45,63,205,763,374,325,359,521,739,117,775,870,799,315,974,119,666,459,298,731,365,499,66,485,382,787,598,253,230,788,606,727,388,690,300,114,322,732,704,714,772,215,452,261,729,859,844,680,299,100,877,664,310,240,633,225,384,631,713,883,460,541,793,176,764,695,100,460,570,944,845,177,968,821,616,129,859,62,819", "735,741,548,557,620,10,839,937,186,967,275,516,520,737,886,568,831,664,824,323,627,45,123,254,854,409,463,645,124,25,503,286,723,45,455,78,207,924,588,500,63,392,242,26,764,321,893,31,729,538,313,916,761,472,359,21,98,584,823,368,245,171,448,686,139,823,515,655,550,590,407,831,996,198,897,627,213,459,166,580,197,370,351,510,775,169,742,710,345,648,108,708,569,777,975,169,235,139,801,385,594,667,261,959,994,946,911,712,879,772,425,480,946,276,741,982,707,93,939,3,166,157,777,927,254,688,232,875,359,515,477,844,435,946,99,971,954,7,800,314,225,523,53,720,870,37,373,913,67,38,184,531,731,943,897,392,921,391,473,523,334,674,93,703,130,378,787,290,264,729,748,757,376,78,599,226,822,441,598,817,672,306,940,157,95,445,278,895,756,186,575,508,384,928,345,206,540,924,92,47,615,888,234,289,293,666,546,442,453,509,329,878,501,733,654,633,759,872,425,521,862,697,930,269,567,430,283,451,606,871,963,297,347,118,846,103,543,932,692,157,778,742,750,380,317,60,439,750,389,565,9,860,739,747,906,15,285,905,739,242,545,692,656,374,256,318,662,974,479,92,419,278,721,482,860,105,273,909,374,261,660,385,565,756,706,637,494,874,616,782,448,540,822,298,365,760,848,750,222,511,569,909,819,363,71,710,490,494,267,926,138,353,82,384,644,542,704,946,512,875,168,2,281,394,915,542,240,987,465,962,931,622,671,638,489,496,586,730,482,76,384,200,681,499,571,416,144,386,623,736,260,221,284,642,194,210,986,156,700,128,373,643,529,897,400,772,746,253,49,431,234,973,47,887,669,828,206,198,300,153,648,12,874,674,681,454,685,669,893,647,347,552,70,882,21,500,972,746,353,285,279,97,69,717,19,253,89,813,862,78,557,640,408,511,797,850,295,123,999,411,454,450,39,394,130,61,112,229,361,133,168,367,604,330,616,332,586,649,298,945,78,115,741,252,974,242,381,54,693,468,792,378,646,261,914,715,147,580,686,395,671,417,605,880,221,486,752,840,830,407,412,204,175,20,27,813,319,424,637,806,64,19,455,994,253,880,260,683,854,820,580,707,120,397,669,356,645,734,149,973,479,327,251,674,181,969,213,479,515,56,456,235,533,532,652,504,226,648,559,362,292,220,984,425,490,169,368,157,970,312,479,478,974,76,123,248,799,99,661,123,376,884,904,228,788,728,256,77,588,431,780,632,785,350,483,336,335,995,958,739,690,392,27,997,231,264,120,243,994,437,834,561,613,383,706,196,740,472,54,886,330,620,891,88,629,107,945,176,657,161,943,778,952,596,245,856,134,424,665,684,574,675,812,79,890,453,299,936,800,730,579,445,203,533,69,377,151,13,976,224,999,386,402,618,11,792,428,395,422,499,362,177,250,890,94,428,218,873,809,440,19,969,869,220,501,402,978,45,72,315,332,569,100,172,148,656,685,394,663,950,935,967,172,34,750,177,207,20,695,938,394,411,272,799,892,79,113,684,166,208,590,239,477,981,46,371,133,630,994,581,636,245,828,79,10,347,111,88,468,507,105,724,765,970,593,67,522,599,526,733,666,591,620,829,851,368,776,561,956,424,989,381,984,326,53,311,207,513,323,424,573,576,796,272,854,530,640,261,989,509,762,73,492,505,194,40,447,649,842,94,751,347,667,942,516,806,482,986,420,838,458,427,981,249,486,986,552,169,528,480,68,757,29,4,60,990,414,770,291,19,509,568,467,61,960,425,319,923,741,78,29,68,90,107,262,618,632,126,839,954,640,779,1000,0,295,125,777,776,406,413,691,957,278,963,749,629,801,801,481,770,751,891,756,327,700,999,843,668,141,99,240,168,859,10,234,528,14,963,387,604,743,386,872,92,201,690,309,581,356,193,78,205,909,980,711,241,870,722,882,824,972,924,458,994,853,220,258,766,720,641,661,697,116,434,212,35,59,321,675,41,274,868,69,798,978,739,415,670,995,295,666,967,978,121,617,951,169,379,395,757,180,77,252,495,178,157,103,947,713,239,101,316,729,345,647,502,757,251,141,121,554,33,523,698,988,903,821,541,854,203,49,1000,526,428,95,741,79,944,46,227,444,531,811,968,787,469,447,653,189,263,311,699,371,531,430,754,26,585,677,739,927,151,757,773,63,487,277,669,710,938,92,723,671,194,422,834,500,482,760,521,397,661,760,451,995,870,677,121,320,671,39,992,282,732,527,855,316,928,671,762", "414,115,434,26,704,144,960,566,537,855,789,19,219,563,288,683,538,121,938,360,383,362,335,20,338,973,890,887,247,874,686,658,201,229,772,622,297,437,528,702,182,274,57,756,74,232,13,439,142,670,952,232,902,674,303,648,366,791,587,16,494,730,754,63,227,719,73,136,847,224,157,42,361,395,591,637,646,273,944,584,203,73,742,643,328,722,810,347,254,17,889,460,278,865,83,381,79,286,995,801,998,296,303,225,983,960,417,385,559,8,768,878,40,928,297,73,33,179,711,84,96,582,717,168,440,620,668,253,991,122,494,970,574,626,376,849,853,454,545,599,743,872,638,671,771,624,901,12,600,56,939,17,364,408,405,993,405,262,775,583,224,240,257,649,313,118,61,363,186,378,999,723,98,476,439,550,647,428,470,836,845,494,953,32,394,63,186,827,121,623,819,302,567,194,692,501,211,218,900,986,652,447,362,592,277,958,398,572,81,976,14,389,824,607,274,902,783,537,907,910,504,601,429,624,247,561,922,356,298,552,691,286,131,341,296,772,808,471,338,977,808,244,532,572,21,388,671,493,540,449,742,582,562,83,143,328,936,791,642,876,295,15,697,592,963,244,293,329,142,774,909,286,515,93,804,589,961,612,990,739,438,299,349,188,634,492,143,543,202,662,804,578,440,540,570,386,537,128,973,355,988,523,904,18,592,699,684,382,77,268,756,921,89,387,405,394,853,658,325,377,541,746,433,702,131,558,402,425,600,465,657,236,870,126,480,327,480,455,251,719,46,698,267,241,749,416,54,896,533,68,798,789,610,929,57,727,815,245,555,601,751,601,170,33,876,826,247,257,564,782,881,991,774,649,674,832,876,429,977,117,443,653,767,957,499,398,508,145,973,379,710,408,99,706,907,993,705,407,451,388,750,280,47,60,942,196,944,760,255,731,407,593,384,668,274,303,577,606,638,996,812,865,766,795,705,826,877,772,255,146,159,979,986,726,202,870,52,794,76,460,947,743,732,487,930,895,484,62,23,717,608,162,241,677,423,191,513,440,204,29,94,153,898,767,722,291,273,908,352,803,243,635,607,682,955,164,378,471,661,966,257,755,200,739,696,339,724,731,645,3,602,569,220,216,595,731,197,75,177,733,911,374,406,707,290,323,566,609,809,146,327,467,978,550,551,595,128,587,524,730,623,485,306,76,435,657,413,943,624,579,153,342,226,268,232,641,996,93,948,616,459,984,448,987,486,400,756,910,54,883,783,26,658,789,35,37,58,276,274,510,116,749,525,728,205,412,240,449,708,665,681,370,734,731,307,476,452,310,737,431,381,534,442,86,515,994,902,619,671,258,308,996,620,60,898,78,421,84,468,393,719,582,493,75,239,740,313,320,578,602,865,923,487,963,82,429,697,15,538,262,507,877,405,739,967,129,803,495,110,280,607,693,281,891,181,447,494,775,1000,402,774,15,623,251,737,989,900,615,747,231,204,103,325,532,585,298,497,498,161,788,568,394,777,14,826,58,839,688,185,338,870,873,809,50,176,439,218,582,754,766,646,537,387,739,736,813,164,76,126,120,167,895,55,180,291,143,215,478,255,942,541,575,660,29,350,5,924,593,396,670,943,201,865,2,296,376,877,663,373,721,706,816,428,862,299,107,429,756,855,456,917,219,232,92,337,118,710,118,518,55,888,734,292,338,728,918,414,794,665,550,207,225,948,316,734,999,567,619,230,55,54,313,932,296,219,56,892,407,98,637,67,10,335,629,894,793,543,709,501,685,356,52,819,430,626,245,169,239,800,247,717,72,698,412,897,6,648,258,892,566,642,31,144,295,0,798,514,326,574,37,923,675,863,663,168,687,89,815,673,44,797,102,509,963,520,621,149,947,889,519,590,413,287,363,15,464,69,541,843,63,791,624,624,728,793,85,970,570,206,771,520,707,262,627,581,84,204,554,48,113,684,62,804,365,279,954,816,758,579,677,559,159,810,888,545,129,802,750,177,74,966,801,26,45,994,355,23,262,737,210,675,186,417,944,732,178,760,301,867,618,562,559,183,842,430,151,261,945,380,143,854,505,178,798,273,91,781,108,730,264,929,438,239,145,400,727,210,83,79,717,78,172,771,383,695,36,662,587,24,674,161,154,194,486,279,611,118,331,307,554,765,201,710,375,752,362,278,704,177,513,847,661,173,692,70,347,548,131,333,630,517,40,140,430,860,190,656,482,873,492,104,846,236,806,994,657,467,299,224,727,714,713,355,304,496,85,529,407,63,991", "822,152,415,735,544,488,52,711,209,424,636,975,296,943,525,906,302,314,389,400,142,470,919,83,930,902,331,860,993,654,150,537,817,625,762,282,91,601,153,808,563,490,919,878,993,454,79,886,202,747,700,914,877,152,420,24,601,801,431,861,134,208,829,250,238,755,937,980,571,940,639,664,99,154,146,958,513,277,527,521,88,961,546,695,438,720,231,6,487,747,323,291,648,339,868,310,391,829,840,66,388,616,292,196,808,902,404,251,408,863,452,249,146,722,763,65,296,832,796,509,820,829,322,195,609,949,878,952,576,179,304,705,603,642,194,396,655,319,566,491,347,640,872,459,525,719,362,336,792,447,814,675,205,795,937,194,756,475,298,805,499,808,330,697,413,410,72,177,828,684,773,487,887,57,896,932,980,305,364,815,136,789,549,784,54,607,401,580,476,203,26,202,526,72,944,787,789,508,593,509,167,345,978,371,273,393,99,849,232,545,416,439,43,480,9,834,283,643,248,609,465,742,410,216,859,765,225,722,597,492,816,616,469,622,103,179,814,590,928,63,98,96,151,824,20,253,688,15,903,432,573,789,344,3,602,875,401,296,482,437,168,269,592,603,541,475,792,333,957,447,385,813,605,792,111,634,25,440,256,939,298,362,234,708,654,112,451,252,906,354,805,32,276,15,64,198,356,834,98,201,681,683,940,713,860,197,83,501,25,622,815,537,54,605,445,513,880,694,413,542,362,627,489,491,121,920,161,953,335,361,425,68,696,928,772,794,500,335,594,494,970,111,806,619,111,640,871,351,60,876,884,477,768,35,761,686,254,570,307,872,595,998,698,449,639,84,54,309,94,263,490,819,538,486,75,387,312,516,396,176,903,475,720,515,56,77,867,641,560,209,276,58,333,23,848,728,616,654,86,678,629,514,676,727,275,461,964,74,677,74,162,132,546,437,854,737,934,530,636,507,32,504,475,475,162,527,512,940,561,742,196,383,46,647,678,665,12,34,735,867,638,362,239,906,910,753,375,536,508,434,413,339,962,718,861,498,356,337,262,457,644,423,161,952,761,391,242,277,549,545,623,264,199,718,642,278,829,22,546,328,725,615,276,343,72,438,242,462,851,614,927,264,883,796,258,254,275,825,91,516,688,451,392,57,502,62,945,923,100,575,775,628,276,700,264,273,256,892,209,487,719,806,269,970,975,99,543,92,412,51,746,278,386,816,935,458,799,331,824,139,441,243,524,773,550,561,266,200,997,656,734,607,550,798,211,602,170,905,340,135,693,714,964,445,995,928,55,737,920,44,781,701,300,960,17,605,71,359,179,115,71,10,214,834,850,262,58,638,639,888,74,603,466,662,420,64,166,964,219,17,420,804,722,525,355,666,345,830,131,317,906,293,237,191,911,302,337,298,454,815,809,503,197,548,658,215,950,314,227,396,306,97,66,982,855,940,707,590,110,312,13,284,865,647,727,665,217,79,881,383,170,195,714,637,655,32,629,763,673,384,645,204,22,937,757,136,228,944,184,515,518,164,514,46,438,342,600,303,421,262,711,78,596,12,907,947,993,245,663,740,537,848,475,571,5,469,993,201,285,417,587,562,711,873,79,121,537,635,942,441,732,861,590,662,424,318,377,514,890,918,466,435,305,279,468,875,527,782,629,169,448,556,816,183,603,990,630,466,885,440,244,151,637,633,711,228,718,320,770,253,642,311,444,127,531,419,14,397,698,140,155,388,606,248,66,879,424,344,176,789,574,646,975,422,766,349,430,150,58,710,837,95,469,973,2,486,559,926,518,814,134,195,399,45,932,230,417,753,40,244,532,989,191,125,798,0,293,840,86,659,968,162,795,844,954,443,93,233,703,169,593,410,150,623,783,600,490,24,677,786,552,899,447,609,586,968,432,117,306,712,964,179,591,343,931,46,458,444,544,176,726,268,516,535,724,245,543,741,973,58,512,949,136,602,471,829,948,493,820,34,55,968,804,384,899,504,528,14,362,244,805,984,284,413,420,50,119,656,564,361,182,379,523,889,727,764,805,726,177,275,939,486,269,953,125,914,632,119,35,352,749,230,165,986,909,106,936,299,8,812,59,980,916,125,240,909,232,116,838,223,293,296,310,864,505,135,817,807,552,820,293,990,797,344,66,500,759,311,939,557,126,761,208,278,372,583,983,766,788,458,517,490,331,892,931,982,902,543,587,11,112,82,180,199,798,103,229,996,178,66,645,422,668,957,134,333,588,745,426,946,163,502,276,168,554,781,553,737,155,515", "625,722,280,95,462,270,415,801,209,872,585,336,231,830,488,121,53,756,774,792,262,254,733,823,45,51,622,897,781,983,443,881,535,459,324,96,430,4,58,991,245,377,885,122,633,41,821,563,852,607,498,982,762,641,343,517,119,550,881,818,390,645,402,635,813,306,588,740,94,321,882,690,692,43,268,449,697,538,63,670,737,546,196,972,351,634,839,957,800,967,902,900,94,352,587,98,59,257,243,701,550,334,64,633,578,806,540,104,732,594,767,175,518,322,235,918,272,844,170,626,50,650,660,415,624,980,290,444,341,757,781,319,771,768,864,998,517,273,192,665,684,204,26,257,238,508,180,466,167,324,867,278,681,801,935,510,774,810,968,462,740,510,110,55,687,370,180,521,907,903,291,181,656,688,880,436,729,774,830,407,232,977,633,220,536,782,70,975,56,69,639,979,598,212,532,766,847,891,35,296,541,26,845,757,658,759,643,800,822,507,646,176,651,995,22,83,70,476,864,398,778,190,50,104,800,97,811,181,171,614,299,495,940,70,645,863,558,772,216,333,649,539,179,1000,633,356,263,189,246,925,674,960,660,187,987,377,188,817,239,194,535,448,606,488,599,653,836,821,669,395,574,458,303,418,574,884,837,149,300,341,791,74,571,509,578,37,234,832,239,915,196,737,451,859,554,140,511,680,232,398,483,742,393,167,965,565,503,772,882,296,925,957,869,771,976,704,634,306,427,876,382,459,425,934,862,66,30,888,879,355,612,202,763,709,964,190,320,928,772,404,821,564,852,81,837,473,965,551,308,884,390,962,486,923,463,220,897,430,754,755,852,430,155,883,269,137,287,777,960,160,620,378,896,960,894,228,396,796,531,392,53,837,966,140,912,978,687,524,736,37,521,960,345,711,17,652,141,61,482,501,893,959,913,78,451,628,353,850,308,627,650,326,889,555,189,822,454,56,196,207,820,109,880,75,243,666,547,313,693,678,12,33,614,351,541,977,890,521,819,924,537,738,135,921,548,733,189,793,120,783,275,867,890,426,508,534,569,16,985,252,789,839,757,546,996,703,294,835,982,870,271,751,797,707,958,645,866,770,214,604,21,478,781,691,21,846,273,120,903,964,509,878,386,884,891,268,271,728,917,922,780,167,442,938,756,838,670,628,167,555,40,411,894,169,651,6,156,235,953,341,208,919,412,344,236,378,828,355,47,79,633,305,924,738,615,934,737,794,400,965,351,546,426,128,968,656,549,817,62,203,297,888,460,602,23,263,890,71,137,408,697,670,111,995,746,606,185,969,940,787,714,54,43,216,191,840,902,128,971,478,279,768,176,671,834,818,824,904,448,874,414,61,168,805,558,661,189,199,321,369,998,909,189,627,494,873,118,416,473,437,74,255,741,813,446,69,354,536,947,908,380,797,721,332,925,106,52,439,577,906,878,285,490,488,639,997,636,322,68,764,570,550,41,994,666,731,534,6,783,13,36,48,534,280,995,25,157,666,145,825,883,520,239,407,793,913,386,159,59,320,132,428,461,624,567,572,57,436,235,684,122,808,811,268,756,554,202,504,937,831,571,90,855,459,506,820,78,776,554,590,797,242,859,521,588,723,488,262,221,180,164,819,765,301,96,58,203,895,139,789,365,914,102,848,577,250,47,574,645,330,662,490,157,429,647,413,692,330,804,719,710,63,958,52,544,826,123,20,745,247,734,786,309,476,546,895,766,151,293,511,865,479,443,557,685,511,236,63,873,143,758,905,359,634,97,823,239,269,710,507,344,152,389,652,90,389,917,915,825,13,688,665,802,661,574,171,162,405,288,61,181,230,675,777,514,293,0,458,595,844,942,978,740,595,266,459,678,681,26,708,210,575,403,525,593,436,703,90,659,589,937,460,24,713,414,34,656,858,822,851,474,710,276,45,921,680,888,569,59,446,917,858,763,405,459,295,889,280,257,637,661,904,391,77,86,494,958,64,710,517,257,567,850,454,48,256,799,862,699,774,611,708,210,564,493,751,146,718,276,365,665,834,459,194,914,891,317,613,289,689,79,246,834,27,979,751,291,534,260,258,876,253,495,789,222,983,885,888,29,190,917,184,264,35,774,348,471,298,573,513,109,452,41,737,622,874,60,489,400,508,600,937,598,234,145,574,712,98,510,873,600,143,244,823,650,18,613,451,723,975,647,929,913,708,485,265,407,588,376,706,254,402,417,539,286,984,617,134,470,511,29,961,867,454,332,611,508,684,933,647,538,967,643,846,491,769,870,774,732,887", "147,948,83,549,593,187,810,425,175,918,570,147,919,587,357,716,385,116,744,899,782,261,880,29,373,541,241,275,536,489,83,956,913,301,819,605,452,407,674,13,930,217,56,10,764,435,455,929,783,349,946,548,220,521,163,250,977,870,830,688,748,380,255,670,755,788,685,253,2,827,426,705,752,148,893,584,562,521,497,669,489,189,61,745,835,507,200,724,590,65,322,803,530,548,670,689,612,275,592,515,495,141,621,600,555,577,71,946,804,760,106,890,409,68,809,649,948,410,785,463,263,881,640,340,24,814,522,327,971,338,757,608,197,621,928,673,851,185,581,78,378,910,120,501,285,690,283,235,649,518,942,394,608,992,836,926,975,648,314,526,875,750,164,290,949,833,848,801,842,70,285,844,564,261,122,873,142,650,309,423,477,291,715,974,203,642,896,458,275,585,954,943,224,735,539,745,247,298,416,330,907,976,357,118,376,7,743,60,611,887,745,635,69,758,987,191,701,815,492,300,360,858,617,568,390,847,245,637,658,376,971,175,27,985,44,760,655,962,669,598,433,702,884,144,361,671,793,427,258,852,708,15,120,371,153,893,932,367,349,31,834,871,630,811,109,930,974,233,329,389,353,443,66,885,588,192,147,895,2,939,954,130,390,166,790,530,951,484,323,645,76,62,338,362,490,261,562,906,521,455,177,358,229,978,497,352,528,670,459,160,925,442,292,492,201,9,996,351,465,200,742,394,632,549,319,438,190,168,646,579,20,314,567,913,819,69,147,989,369,284,857,895,719,885,901,435,48,912,159,546,645,545,964,249,908,469,190,385,207,992,245,262,882,93,914,953,115,214,597,511,667,315,637,925,829,592,3,892,523,950,411,166,90,381,237,166,352,818,902,279,837,656,576,590,612,450,422,909,239,431,867,743,138,796,466,317,310,178,787,125,950,560,73,353,244,794,907,269,877,208,157,835,392,963,721,230,684,297,548,930,193,458,270,755,791,106,933,662,405,648,596,972,354,482,770,191,863,672,464,250,150,752,132,376,762,283,385,547,788,220,455,532,580,903,797,421,41,856,291,591,349,223,644,785,126,472,231,52,624,317,723,161,573,517,558,465,498,624,222,80,537,960,958,46,796,465,305,391,804,159,720,127,571,835,361,966,404,368,218,636,586,339,955,52,448,109,104,902,300,115,395,861,235,918,1000,925,897,771,330,909,221,660,484,542,895,7,437,515,114,647,586,364,309,953,232,189,142,78,479,883,178,640,874,925,230,496,730,825,913,180,945,537,581,219,798,31,178,156,59,626,162,439,270,124,135,222,529,848,752,859,581,643,570,526,418,387,22,608,926,882,351,210,867,469,677,940,300,701,730,34,944,283,906,289,452,465,324,452,182,414,860,965,286,625,946,61,563,806,763,607,627,363,367,137,646,195,381,945,736,980,97,497,569,813,846,578,278,800,166,775,370,684,877,25,911,334,50,748,982,253,232,957,215,595,168,149,34,410,384,656,450,277,44,267,451,607,715,699,85,582,819,109,382,245,177,182,689,214,959,142,123,139,496,617,270,260,656,557,831,583,583,165,468,767,882,334,606,530,61,152,926,597,505,822,137,905,801,58,714,643,592,841,550,19,476,298,107,824,78,818,54,783,491,641,917,566,783,67,247,575,662,475,271,238,418,684,296,734,272,147,969,590,282,662,941,407,387,917,9,653,984,652,377,213,330,120,692,202,84,78,9,513,421,576,721,91,534,88,778,263,554,635,609,737,278,175,582,18,975,607,60,98,480,664,933,945,500,797,219,710,492,910,281,644,521,849,882,892,298,677,909,588,661,776,326,840,458,0,481,535,565,511,69,3,146,978,488,883,138,131,717,363,219,214,515,873,627,76,490,999,209,754,273,257,17,741,739,599,134,794,96,374,858,107,391,877,236,522,348,374,181,73,624,814,494,211,15,552,31,152,644,106,275,853,723,995,556,323,70,590,295,461,330,721,604,131,300,275,410,383,954,127,46,799,402,167,893,362,922,122,290,370,103,714,6,57,403,188,924,717,44,261,751,967,23,279,413,615,504,421,254,111,651,469,59,473,855,416,616,673,900,988,628,670,267,251,283,428,318,647,763,951,272,769,693,604,622,751,792,39,103,487,966,813,807,212,868,166,399,696,799,724,517,550,869,988,45,556,63,770,686,618,787,159,630,562,930,724,156,822,262,490,468,985,872,220,310,300,197,955,450,290,226,281,790,798,793,551,651,916,893,29,679,752,185,682,432,847,292,891", "210,318,405,702,295,147,85,70,10,643,294,654,943,55,280,168,191,121,208,372,112,507,21,744,16,100,155,370,759,168,749,980,910,533,845,440,651,468,97,110,169,76,231,297,96,898,624,472,624,867,295,934,170,958,67,469,286,816,380,914,430,550,137,135,297,249,331,290,523,15,24,785,773,619,877,478,109,369,624,106,73,767,123,627,908,813,578,234,628,575,774,770,19,567,779,794,655,995,92,767,844,431,461,443,615,263,927,386,225,509,693,488,555,810,420,866,385,177,947,254,185,402,487,406,956,563,224,407,534,241,432,4,104,94,564,663,451,35,491,217,292,454,879,497,41,72,875,346,772,710,800,157,474,840,398,804,682,57,347,236,854,833,578,307,647,648,203,673,970,32,737,445,185,984,306,934,302,410,17,477,761,710,880,758,397,431,761,64,328,267,630,586,969,878,814,648,546,181,410,289,879,815,113,747,424,28,707,51,309,506,580,381,273,262,488,433,965,256,784,913,842,548,404,643,16,554,692,110,289,950,81,136,894,182,837,533,692,479,921,396,401,109,315,653,767,46,66,96,430,441,361,94,358,446,701,322,125,773,805,312,1,275,566,314,456,136,892,584,577,979,492,469,857,930,183,117,132,750,255,872,551,309,697,169,136,350,258,732,577,207,419,637,243,365,786,811,405,766,760,153,160,504,487,714,244,889,752,907,266,302,86,800,300,394,670,433,741,541,621,474,763,822,540,354,486,128,751,356,872,559,561,239,609,834,739,338,325,805,344,610,482,231,135,763,218,272,94,160,491,110,94,429,846,553,52,763,570,374,719,987,878,709,752,192,682,650,703,571,811,219,158,542,820,929,634,301,29,558,637,647,664,216,572,778,347,239,564,932,317,733,296,94,547,277,18,53,468,567,854,980,457,166,246,826,777,527,665,915,997,236,334,415,216,60,659,743,814,512,650,500,889,999,752,280,477,689,560,76,596,365,983,533,847,100,97,230,732,178,527,935,347,784,286,305,579,273,139,529,795,712,281,858,141,107,900,58,733,986,700,974,891,8,877,28,447,788,303,573,698,477,289,744,805,872,91,627,488,256,625,317,306,736,542,244,259,294,401,82,48,468,452,172,24,248,790,266,59,257,433,93,568,365,26,597,498,475,293,664,923,364,353,461,191,513,69,588,864,895,412,100,202,535,374,327,631,319,786,978,963,39,775,564,214,910,831,218,760,27,502,419,828,681,297,493,715,289,339,958,708,932,386,643,242,741,204,184,173,502,866,988,478,608,849,873,375,235,815,594,6,244,469,229,508,407,170,955,89,169,946,764,564,303,535,155,372,660,771,221,978,203,902,24,672,777,521,496,514,313,652,493,956,914,273,868,43,348,578,618,831,62,394,673,577,254,258,703,748,931,256,764,728,29,367,614,191,394,706,25,935,946,490,281,881,884,605,323,442,346,315,738,307,877,224,868,537,4,899,104,596,494,254,91,957,868,183,229,538,119,182,638,86,54,184,119,151,698,680,953,480,880,824,147,470,383,164,80,500,197,119,495,640,159,84,657,510,720,752,314,187,967,166,796,842,338,869,208,872,8,306,302,77,842,436,339,972,465,224,367,991,300,397,986,825,288,528,220,971,709,405,170,697,748,308,480,557,441,536,622,946,113,264,549,642,371,798,362,817,42,448,132,173,650,714,200,404,548,675,228,772,19,390,196,767,433,114,442,15,866,393,259,926,240,519,32,620,503,463,790,989,186,385,435,484,570,298,855,947,154,13,600,154,54,257,119,675,88,446,236,420,416,312,936,810,34,930,649,460,225,359,829,354,876,59,406,574,86,595,481,0,679,679,315,281,545,548,229,377,486,827,78,282,716,510,886,41,308,521,986,200,878,67,46,91,310,724,527,458,88,371,57,239,695,735,212,897,486,241,693,838,708,230,987,193,357,584,971,476,834,449,894,797,73,255,401,681,251,849,447,236,683,544,783,194,386,746,173,566,41,574,243,230,622,314,146,908,367,688,3,825,287,662,295,996,484,190,791,380,532,427,65,45,467,805,349,221,143,404,328,630,270,238,986,213,393,12,486,244,830,340,646,378,363,485,489,111,137,594,23,410,723,458,586,169,107,649,645,959,123,505,258,961,133,542,828,776,609,56,143,589,611,641,543,637,68,481,154,287,370,914,565,719,942,747,186,220,296,593,533,177,918,873,393,872,875,435,86,70,124,531,24,905,81,660,612,476,632,887,106,645,351,698,528,527,535,218,991,904,143,166,81", "875,60,104,424,507,263,178,50,997,808,174,895,860,334,137,708,718,779,113,925,316,265,483,68,645,147,105,990,538,602,424,380,801,612,435,597,708,304,187,740,230,385,693,62,478,904,106,646,543,59,780,52,222,491,285,846,211,767,987,898,830,7,284,479,363,888,926,216,284,95,510,354,276,200,40,550,707,691,423,212,766,161,908,147,58,270,686,62,723,376,838,349,118,151,99,101,139,30,293,361,347,484,792,729,538,68,986,538,431,723,947,232,287,349,941,205,597,564,666,444,433,595,628,772,526,888,642,669,876,494,442,891,769,166,496,935,205,469,158,23,162,154,752,255,634,891,286,157,380,156,479,262,469,356,688,417,553,442,566,7,186,339,664,854,192,772,926,273,491,79,660,883,215,438,353,811,123,370,398,74,977,947,214,60,144,281,661,99,12,316,53,9,812,610,999,190,964,369,182,754,247,677,111,48,424,129,158,991,519,681,793,184,646,524,264,765,323,290,757,866,983,639,924,123,707,263,554,192,701,833,74,188,767,388,951,192,407,863,127,871,734,473,390,621,748,960,261,354,786,805,746,694,567,544,612,347,827,164,920,499,886,858,135,398,164,175,531,862,618,330,408,319,783,136,76,646,942,191,959,323,480,975,197,90,954,29,97,51,661,36,961,929,902,843,589,88,579,655,425,694,315,793,525,47,962,322,513,401,919,221,447,445,979,348,382,575,759,877,380,342,194,530,158,108,682,709,129,113,304,936,6,868,162,602,353,649,877,669,300,625,270,44,346,48,697,156,700,912,56,55,861,610,272,743,166,120,120,250,343,174,592,312,959,93,29,486,845,53,55,767,197,144,580,288,173,489,781,335,150,137,266,688,353,545,392,62,53,949,786,846,302,759,342,25,689,860,571,635,855,671,924,769,479,821,229,590,578,783,341,761,163,218,550,714,236,920,125,747,317,950,672,406,702,565,690,685,176,450,330,647,502,962,997,929,392,365,907,308,959,42,269,360,264,781,283,794,797,516,568,430,235,274,726,58,330,171,541,81,804,167,677,463,838,526,749,68,187,285,678,843,529,424,386,198,30,897,280,340,944,424,326,569,141,369,337,645,925,892,815,74,149,604,263,819,209,596,965,737,106,829,78,561,332,325,886,986,7,683,299,29,668,223,673,190,689,551,601,183,436,971,600,339,651,763,537,582,593,767,495,814,497,856,457,581,846,956,636,622,177,30,992,976,231,462,65,614,350,637,541,239,442,186,548,204,805,364,976,387,866,949,587,80,39,254,121,243,515,28,191,694,314,576,311,378,103,714,621,28,784,888,370,31,357,276,853,964,261,426,312,576,120,892,14,837,250,294,116,330,909,627,49,407,154,206,497,887,497,452,558,18,434,908,681,239,880,6,273,541,534,977,943,472,298,864,219,452,773,449,857,501,631,29,952,185,632,165,12,720,842,257,59,983,340,602,42,114,29,301,911,220,266,407,601,66,204,361,835,326,384,927,545,857,26,431,178,273,305,828,104,270,12,574,554,346,526,306,631,991,318,595,729,69,819,154,830,387,155,87,49,936,326,580,143,880,342,608,711,708,153,601,34,91,161,468,779,261,877,310,691,990,349,439,293,418,670,431,809,294,335,377,235,939,573,874,254,364,450,98,102,70,605,656,996,453,918,708,989,174,919,491,885,332,861,649,20,394,279,375,221,712,811,517,705,586,342,680,480,805,892,924,759,203,110,640,477,200,697,395,316,663,503,948,864,737,391,210,969,798,463,314,727,940,449,242,714,405,912,949,287,712,650,999,602,632,802,201,218,657,645,572,456,161,86,413,37,659,844,535,679,0,771,453,693,31,182,762,56,473,421,81,684,840,365,392,107,787,369,919,966,932,291,515,827,502,37,813,171,370,369,686,159,866,24,948,5,462,286,695,94,785,306,421,450,287,663,875,465,846,356,249,584,628,595,711,469,984,20,999,39,108,583,393,810,230,84,930,282,557,371,13,66,681,981,659,589,880,992,479,540,796,496,675,951,72,961,635,525,33,599,2,562,255,968,760,169,291,38,35,705,968,121,795,588,222,594,207,686,437,43,287,944,764,200,658,57,382,173,92,44,590,167,957,102,14,291,87,329,810,655,129,953,782,568,131,288,234,253,952,963,192,874,960,367,187,275,262,851,960,130,622,813,545,15,628,714,458,312,804,864,227,64,952,187,103,891,548,107,267,285,817,290,939,503,808,817,455,751,537,480,258,55,632,584,306,308,207,706,118,848,104", "778,973,197,479,389,664,937,711,640,577,692,748,999,762,829,933,833,768,196,721,36,475,187,444,934,307,789,775,994,462,905,845,296,695,483,961,274,399,648,440,649,559,565,255,980,233,901,866,261,665,378,300,446,669,868,557,694,749,234,937,941,348,638,846,18,83,418,882,207,638,536,211,317,683,747,872,11,267,150,58,199,164,346,3,189,457,141,139,302,695,539,1000,632,288,747,483,552,387,122,34,2,166,872,26,934,649,506,65,788,150,89,881,433,717,911,70,336,336,645,272,277,844,791,751,589,538,200,313,72,342,134,951,786,978,570,504,312,382,995,243,882,430,505,803,33,229,591,390,373,475,427,389,354,517,709,72,610,838,673,720,189,331,562,152,610,613,382,939,273,972,502,695,286,525,149,958,896,794,523,262,998,310,306,390,326,840,994,780,417,787,295,51,646,154,127,471,974,714,756,124,86,79,860,570,721,555,604,271,865,57,410,381,336,372,612,255,661,580,517,845,580,217,770,79,112,874,190,696,555,475,663,170,489,713,319,869,70,10,555,717,945,442,271,463,108,345,883,53,957,654,468,927,304,255,813,122,236,603,929,106,303,931,835,61,119,225,484,37,274,19,518,706,886,251,750,376,335,475,504,202,287,71,822,610,759,862,613,855,510,634,758,191,712,486,750,561,876,808,269,379,20,75,629,243,228,219,727,452,230,191,747,86,53,457,469,747,130,229,614,691,574,507,400,269,44,149,159,908,528,931,214,246,39,531,659,975,567,854,18,441,151,315,378,772,150,506,963,581,898,575,565,555,636,96,550,165,153,112,110,152,397,605,975,939,854,473,734,856,291,395,421,403,394,788,587,369,428,103,44,978,553,243,497,264,933,883,241,91,176,98,715,157,526,174,80,654,597,655,763,199,618,956,997,667,732,753,64,407,820,430,442,739,285,861,182,719,719,587,546,865,116,677,667,754,94,169,342,116,711,116,579,684,102,448,408,578,968,697,711,969,721,308,890,449,197,71,484,194,977,242,391,326,54,27,561,438,899,596,738,238,876,995,224,545,259,599,252,511,607,418,825,426,577,299,348,433,603,571,780,272,516,413,495,210,912,346,623,911,529,286,397,601,931,639,771,189,141,263,701,717,321,291,538,901,522,77,756,927,480,201,251,729,199,337,498,485,408,811,621,840,827,969,715,277,497,641,217,934,12,410,329,821,742,289,402,624,378,306,768,229,736,543,188,6,51,223,346,144,806,559,896,681,873,356,801,651,5,745,299,603,183,993,719,715,304,630,977,491,445,185,606,843,638,628,934,869,360,607,913,450,222,544,19,560,162,625,895,976,829,84,870,946,449,96,392,496,655,944,921,383,588,510,503,737,627,672,999,203,452,435,217,133,412,59,422,268,427,858,716,938,127,114,197,868,646,478,677,127,553,49,929,232,971,893,550,920,976,670,815,849,958,609,276,46,787,707,512,887,106,391,194,230,987,254,436,263,310,358,216,363,363,636,593,916,699,887,939,497,941,786,621,547,216,627,91,954,124,349,500,819,786,133,758,238,615,78,4,224,283,860,440,470,873,270,78,718,178,307,459,904,108,526,433,773,202,669,557,679,293,91,338,819,173,561,816,444,562,143,384,981,810,142,810,12,74,450,463,815,107,252,988,317,915,684,985,836,771,313,738,622,72,836,973,853,434,509,90,70,664,469,117,594,533,232,592,793,76,976,518,291,42,342,587,353,962,115,776,949,792,303,235,526,107,898,296,145,138,271,557,45,891,825,731,171,736,33,345,428,748,450,573,837,938,655,241,150,473,442,107,936,752,26,698,691,923,968,942,565,679,771,0,184,922,612,389,439,682,140,666,488,55,756,907,23,832,580,272,293,579,333,860,50,694,699,158,697,922,136,324,762,672,788,752,363,790,293,706,272,141,233,661,328,710,509,725,182,101,616,822,950,754,574,525,570,259,956,228,223,210,97,478,442,845,952,298,294,926,825,238,655,866,237,4,630,670,109,993,497,60,755,145,761,497,40,856,440,536,206,553,60,941,843,23,675,57,617,835,187,411,265,912,598,167,202,681,500,599,887,645,659,196,442,944,401,487,800,675,719,434,491,542,665,243,607,842,654,564,427,653,588,614,136,886,339,46,203,876,329,700,770,260,474,784,438,453,50,701,817,92,248,430,653,278,999,94,354,409,292,33,555,358,53,86,797,582,21,770,928,515,866,203,6,249,506,534,397,329,369,164,719,833,419,218,647,548,516,952,293,350,50", "175,239,213,674,530,695,760,828,328,723,54,3,258,122,280,669,537,898,357,496,148,246,653,575,330,10,319,824,249,732,532,988,166,962,302,959,821,650,646,991,381,789,974,747,92,121,432,15,333,491,898,277,318,351,402,672,765,381,955,908,768,277,816,724,37,369,57,566,392,77,530,63,629,944,454,212,547,999,156,204,532,571,798,362,129,788,80,150,118,836,131,477,931,507,115,29,384,552,674,232,667,292,786,46,684,312,789,471,835,986,399,724,376,44,88,892,639,546,833,323,616,64,633,525,85,57,230,361,517,349,296,853,262,416,864,41,504,16,776,318,202,474,807,843,700,231,378,493,954,616,153,170,202,724,723,229,52,922,915,956,353,580,352,641,357,207,671,144,403,756,697,826,431,423,695,116,604,500,601,790,323,381,820,553,64,3,894,575,788,152,998,717,394,718,355,887,565,410,387,77,554,185,956,299,484,41,863,628,409,14,458,751,377,442,910,329,713,116,21,777,357,250,634,237,908,846,191,162,344,306,446,121,15,319,937,253,580,729,399,50,229,145,491,367,991,641,89,890,368,599,817,599,875,252,658,75,927,845,433,200,655,511,393,657,202,282,586,299,788,709,914,727,232,72,610,809,206,513,818,369,973,559,532,426,199,115,324,621,382,50,471,60,796,135,791,802,148,228,814,76,725,924,891,521,337,190,315,268,236,597,503,42,379,613,352,782,436,138,237,575,393,322,52,230,155,578,611,606,920,130,156,818,401,290,3,763,604,21,668,558,547,629,342,658,535,626,152,512,653,294,793,958,177,835,736,375,698,322,926,154,166,300,647,741,437,50,984,140,615,636,437,271,748,634,191,223,476,891,43,286,835,452,173,876,795,72,956,16,671,896,185,822,679,306,232,962,234,506,978,723,93,270,881,67,298,411,981,548,232,791,866,705,26,552,127,959,972,552,855,977,193,270,1000,690,585,811,899,423,120,99,598,690,516,176,809,367,631,656,421,242,895,95,476,697,544,849,276,992,30,648,261,485,815,581,436,265,709,154,508,420,271,870,847,348,572,195,204,797,147,933,248,484,651,411,317,270,276,984,961,736,495,494,908,604,635,228,603,627,316,325,424,416,501,121,538,85,548,522,738,889,118,453,111,412,291,656,570,297,687,733,478,264,740,911,800,205,14,62,704,159,958,370,537,501,879,376,216,431,72,207,593,514,196,575,813,328,76,32,995,809,432,795,18,602,96,416,818,479,784,63,742,596,532,493,435,203,82,906,971,907,235,566,370,886,78,425,856,110,300,476,499,557,137,437,505,742,49,623,236,646,602,938,938,703,836,686,54,158,678,23,209,378,476,206,391,493,967,287,28,553,282,62,694,762,501,27,907,750,813,763,847,530,188,455,830,156,32,947,415,953,659,537,794,611,354,603,296,514,104,600,586,774,656,929,892,94,406,423,863,325,735,633,858,340,433,174,143,595,519,318,634,277,938,72,361,770,339,330,602,40,96,564,912,583,763,113,724,910,406,149,122,899,877,382,514,920,435,843,685,387,489,992,4,908,439,431,29,787,368,26,82,570,212,974,623,607,701,29,688,769,695,12,553,149,390,977,123,225,430,893,151,484,359,554,626,402,343,164,457,444,855,895,581,954,441,984,119,932,351,779,693,217,389,789,187,149,930,373,899,176,530,586,86,865,953,612,622,177,389,271,835,500,522,408,287,911,146,226,480,179,375,894,570,30,28,686,879,702,575,727,284,780,443,124,349,43,407,966,974,722,229,891,789,621,365,544,50,978,750,845,458,276,177,528,884,773,304,903,976,194,336,683,918,957,675,162,978,511,315,453,184,0,542,835,918,528,113,448,163,116,710,825,428,606,714,566,619,886,454,188,524,565,908,873,752,498,733,895,919,844,453,370,932,897,99,761,581,2,302,945,432,411,988,139,845,241,25,105,909,279,767,577,793,870,501,25,747,962,139,884,190,610,160,475,186,443,142,313,986,575,614,571,707,910,480,262,171,215,999,142,525,522,214,775,193,304,662,466,913,942,565,549,149,624,609,526,134,590,916,421,825,242,453,578,343,817,762,897,483,376,390,168,197,475,849,654,475,568,199,503,234,567,470,504,442,899,528,843,686,93,11,901,42,318,969,407,458,475,51,313,505,873,973,437,755,771,967,529,221,686,366,133,62,334,654,233,980,419,595,590,544,102,449,867,544,401,429,348,107,619,419,869,992,306,134,492,784,426,35,600,530,56,89,619,133,869,185,48,764,325", "388,488,852,86,650,592,98,727,917,31,25,638,119,419,511,338,936,821,404,820,319,879,38,442,796,494,144,239,653,656,507,406,188,34,754,625,780,889,856,448,796,673,852,425,493,130,793,355,215,544,23,135,940,833,896,428,346,250,33,473,590,247,399,732,142,662,760,600,545,764,445,870,483,394,362,245,272,330,144,829,249,463,89,422,559,734,996,973,865,669,408,48,921,443,870,473,941,991,651,568,631,417,67,938,129,991,832,621,225,974,161,405,644,957,925,557,40,385,277,580,651,2,133,892,554,99,420,954,84,476,320,577,259,501,176,308,920,990,392,256,549,58,486,266,63,359,98,607,38,604,727,227,770,250,931,893,153,900,335,924,359,493,570,150,873,279,806,880,950,761,899,30,36,807,834,147,355,369,495,860,444,74,304,286,421,937,585,702,14,784,15,241,114,871,326,919,621,243,968,680,995,578,395,780,174,770,783,222,657,215,613,573,244,395,800,937,77,139,144,756,255,275,686,965,400,41,666,104,433,970,383,41,543,402,228,466,505,385,365,804,673,266,772,614,274,589,827,508,991,66,120,319,627,226,754,337,989,350,57,430,335,329,795,189,560,813,204,389,359,947,300,328,338,174,208,496,228,709,22,580,488,173,891,815,34,735,602,630,503,631,669,385,140,899,650,350,534,815,494,261,565,816,622,488,909,228,362,141,841,629,161,353,844,122,379,921,548,935,855,258,688,278,21,371,138,5,587,426,232,547,5,98,944,959,231,336,29,170,538,274,236,20,830,542,547,193,661,667,681,686,297,237,504,887,186,373,717,755,478,277,168,734,40,433,96,934,708,626,480,477,563,167,575,573,875,801,782,259,171,221,380,20,38,223,392,115,624,601,812,8,448,415,776,956,158,372,219,124,979,785,248,620,497,815,269,551,335,560,830,558,36,357,71,111,902,172,876,66,550,168,663,271,308,302,6,15,715,406,720,478,955,965,551,711,911,934,650,498,176,893,785,541,443,606,329,518,218,579,472,439,152,110,200,568,743,498,514,455,343,850,708,278,649,310,778,629,696,435,128,909,511,245,31,584,523,830,447,700,865,112,801,586,316,117,886,402,98,848,292,436,843,279,311,816,501,758,118,438,833,8,699,672,516,109,208,742,89,523,711,129,5,424,356,290,189,420,55,581,268,322,505,15,991,730,11,639,205,873,42,967,747,128,92,365,605,19,21,556,753,264,282,98,898,290,371,207,566,693,164,656,269,669,949,642,528,823,645,102,71,166,186,51,604,857,48,872,934,267,388,259,934,26,533,273,858,520,588,371,3,861,655,108,758,605,348,281,552,651,377,861,136,620,468,387,462,207,672,380,144,859,468,170,562,778,905,904,974,441,357,816,26,67,35,901,348,3,373,486,373,169,582,368,773,720,150,808,649,320,212,415,727,788,416,370,795,566,421,248,656,658,231,611,585,771,396,738,128,114,365,803,532,933,611,582,532,556,715,436,279,710,763,653,754,977,329,613,804,784,841,955,213,709,98,377,833,607,411,71,627,894,664,839,258,488,2,39,151,908,735,725,204,169,2,757,316,578,115,821,306,875,346,124,420,912,686,895,149,131,888,635,462,677,918,636,979,471,397,697,742,500,261,559,503,432,221,474,591,429,533,806,522,657,676,915,840,971,7,184,47,971,722,391,711,742,304,339,247,29,331,377,55,83,76,182,9,322,738,973,301,720,746,428,706,382,504,601,620,51,427,18,423,677,327,249,946,773,513,92,897,737,582,182,721,878,904,418,692,320,801,824,993,671,4,423,416,761,156,663,744,581,677,653,937,278,863,795,740,69,281,693,922,542,0,891,601,76,780,307,299,627,584,703,211,108,817,615,932,236,927,444,716,703,207,705,877,181,405,248,772,855,995,746,361,712,450,54,826,885,877,464,576,645,987,565,585,89,262,895,100,41,320,696,57,43,928,573,517,627,360,76,970,240,404,499,778,695,886,26,531,262,487,971,240,971,827,435,998,755,785,404,631,599,857,120,79,293,939,87,24,267,960,863,756,393,422,760,166,567,131,745,166,948,49,708,230,183,103,948,848,657,641,409,910,28,917,494,412,760,744,186,820,774,572,112,567,675,326,228,686,317,432,837,376,116,274,895,787,310,403,7,647,511,401,187,909,851,854,783,185,968,207,726,83,723,873,213,903,10,481,658,342,280,168,101,396,378,786,889,370,55,452,803,187,681,553,312,236,971,252,479,842,361,963,65,158,230,550,965,994,650", "671,813,907,978,938,990,193,395,698,871,298,648,88,574,436,236,56,443,530,173,266,306,33,25,250,651,690,775,353,401,174,494,178,566,82,706,673,228,555,584,56,377,603,824,262,333,302,568,871,428,128,737,956,353,506,77,819,444,825,571,118,384,256,75,207,79,825,21,961,443,875,217,338,418,366,615,401,340,435,23,855,572,854,401,704,187,615,975,37,602,653,754,908,996,169,291,742,551,697,35,379,964,6,688,294,752,795,947,831,952,550,352,374,268,630,661,308,5,7,26,159,623,965,938,442,592,658,706,272,584,501,516,947,738,776,625,498,931,762,346,554,144,713,496,439,305,49,561,635,905,136,505,667,704,508,635,455,215,293,880,182,958,707,946,87,144,855,515,394,664,781,217,307,773,541,565,853,841,395,302,899,202,633,341,15,529,325,250,123,891,355,570,368,915,979,585,331,801,166,321,859,478,878,266,764,861,583,701,786,848,562,493,825,902,922,574,49,150,11,552,852,305,957,370,698,308,907,430,207,429,970,692,393,990,384,88,314,286,313,693,356,2,889,808,327,397,454,359,933,174,216,621,825,230,217,892,458,113,113,97,439,298,44,919,47,933,546,968,838,487,550,216,676,354,385,934,705,409,112,52,394,535,671,89,300,955,770,844,488,33,461,814,440,749,699,841,944,186,263,701,285,173,155,441,132,851,882,643,259,796,551,14,996,422,276,529,95,794,25,933,854,507,951,123,605,456,296,607,474,812,710,473,988,149,46,162,189,209,145,637,669,402,641,736,258,863,874,672,750,380,719,987,463,644,124,231,517,245,137,42,431,677,693,370,429,270,26,153,68,133,897,187,391,355,416,637,682,400,479,423,845,751,661,170,925,682,786,223,569,765,939,657,770,606,735,48,792,995,389,905,923,319,21,301,864,305,981,157,214,66,522,574,777,231,40,840,610,242,456,98,38,636,657,192,543,869,93,137,741,673,397,96,862,727,934,444,418,218,169,347,914,747,850,539,271,569,80,476,271,798,925,839,602,666,864,21,507,307,737,768,742,94,391,273,544,359,137,710,304,732,587,332,303,925,694,402,122,473,12,40,523,902,528,377,79,316,319,431,321,867,776,549,79,3,767,396,102,298,961,849,580,290,864,105,453,144,755,474,729,108,367,225,853,179,353,364,150,557,58,729,952,932,536,968,121,547,833,913,822,352,528,850,789,434,453,77,506,946,445,281,965,366,979,873,335,899,115,365,348,799,33,754,607,210,884,595,722,423,724,797,247,163,299,359,707,68,796,370,254,547,842,910,836,80,778,70,322,490,588,648,548,201,975,361,41,743,641,963,34,281,568,611,753,546,328,16,338,427,522,116,946,705,331,944,767,236,387,833,636,814,119,795,382,867,722,661,596,313,414,881,61,459,36,927,628,671,753,164,276,864,386,262,922,334,9,917,664,783,747,884,700,303,193,75,545,510,239,906,206,639,131,723,229,949,181,512,229,277,633,74,941,610,743,125,744,886,318,768,733,576,801,168,883,515,983,729,160,250,484,795,718,639,912,719,742,358,850,444,752,384,984,819,317,819,131,263,855,610,316,343,758,417,161,104,942,88,564,700,589,248,437,302,94,770,548,12,278,176,698,903,964,594,799,629,219,850,832,191,875,858,679,379,609,59,130,998,606,961,274,888,367,450,452,930,611,992,44,738,211,285,399,79,82,437,841,380,728,377,798,679,160,467,893,198,676,608,614,651,101,918,447,890,4,579,134,436,463,502,282,114,769,518,837,733,191,73,771,977,440,896,411,573,708,117,558,647,794,974,178,281,773,154,796,963,663,844,595,3,545,31,612,835,891,0,180,713,60,292,861,211,875,367,83,467,224,585,974,953,817,55,655,978,547,436,559,72,881,602,166,588,885,997,698,921,438,756,982,719,160,125,214,143,535,338,50,754,207,920,63,21,567,942,818,686,242,609,316,569,178,145,226,165,61,35,381,680,732,272,361,702,68,111,881,450,655,664,119,192,435,592,828,665,325,952,991,98,158,872,660,441,718,507,659,882,29,466,633,641,894,898,544,314,658,880,277,601,151,710,676,788,985,486,357,158,831,340,708,821,702,565,857,495,970,372,969,789,201,429,876,493,436,265,630,901,840,447,292,272,363,119,2,272,628,953,124,451,838,478,127,245,675,693,732,483,553,792,946,259,211,227,788,906,613,902,220,411,966,198,962,721,112,989,719,974,693,288,38,245,205,670,381,858,988,993,485,899,281,977,470,806", "762,322,357,189,349,950,574,233,909,427,54,498,845,719,749,216,501,653,120,352,461,104,338,706,306,825,217,726,485,204,679,170,237,205,989,963,499,325,669,173,814,957,87,611,128,713,933,42,782,813,946,78,662,979,414,288,346,675,88,59,477,375,314,11,554,710,471,953,353,164,407,461,232,201,249,279,410,94,820,589,314,990,947,281,149,957,38,207,200,682,114,527,16,748,505,370,380,983,837,615,901,460,302,288,490,856,923,232,795,192,426,260,311,763,882,865,138,454,676,213,222,68,811,289,62,412,570,429,824,156,983,267,785,162,143,158,416,192,343,518,145,572,386,22,413,716,557,796,772,502,132,794,348,373,115,783,36,392,907,758,704,815,170,460,293,930,536,737,263,793,736,486,348,390,757,909,706,632,284,805,657,944,311,361,196,256,149,579,958,435,362,66,521,996,646,713,936,105,483,624,803,9,77,128,815,596,248,234,508,434,196,338,321,421,299,874,107,343,171,66,39,176,460,232,312,785,538,111,469,650,744,400,803,307,395,726,148,689,396,451,631,930,282,299,834,865,679,607,927,372,327,4,291,932,752,28,216,112,889,484,516,739,640,481,289,966,523,766,194,404,722,862,438,952,892,32,738,260,110,254,727,65,504,336,671,905,958,108,45,984,606,284,914,692,907,683,220,834,448,884,487,805,38,577,798,744,119,623,323,120,802,837,823,101,376,936,230,788,852,291,307,936,18,430,444,72,842,353,897,223,145,815,524,121,40,47,957,927,549,504,959,316,36,90,30,112,54,362,762,140,558,936,495,304,672,808,746,364,527,899,115,93,946,23,568,725,69,545,158,913,265,625,545,224,270,907,934,454,588,28,684,609,677,785,349,800,596,957,152,611,548,272,209,430,220,66,212,385,793,674,47,795,201,636,87,921,65,425,322,681,539,680,111,782,12,715,608,846,347,155,281,801,342,933,405,291,24,43,630,923,741,971,565,335,209,695,367,569,809,249,110,311,698,727,211,230,484,571,495,932,331,100,230,255,896,42,710,624,497,531,158,461,176,707,162,74,891,386,365,270,724,883,715,177,324,980,984,961,335,12,253,597,472,294,235,430,374,711,537,640,879,949,355,781,294,925,751,938,398,183,835,631,196,310,506,427,183,730,441,216,675,380,881,242,53,721,607,928,890,319,314,519,41,468,884,310,109,444,509,663,455,420,776,793,432,682,788,539,692,255,120,507,654,483,452,591,708,206,370,542,796,169,60,105,965,336,690,968,220,502,655,187,607,263,139,588,773,168,454,452,673,184,614,55,366,456,647,52,116,802,78,574,403,606,824,334,931,78,792,63,980,590,135,939,978,873,478,410,86,371,787,117,683,673,30,116,961,996,48,556,796,127,942,307,980,795,730,624,245,886,4,40,449,76,698,477,757,688,915,236,787,398,908,802,612,462,112,575,519,736,859,65,892,422,540,891,761,29,379,654,899,35,533,729,244,292,735,63,747,736,166,571,30,343,134,696,172,461,452,849,863,516,280,580,584,481,176,982,571,888,242,466,70,507,824,428,841,165,244,523,518,379,807,184,474,410,974,718,732,478,601,552,848,193,482,292,612,589,876,892,270,981,350,464,156,465,967,391,894,308,682,844,312,61,893,854,152,448,524,963,20,940,462,101,267,353,269,181,410,804,920,907,911,309,415,730,552,379,110,512,458,185,777,479,699,208,468,671,650,80,947,374,478,500,761,826,706,493,353,684,617,624,334,100,359,417,51,382,648,935,889,713,966,614,387,874,923,798,556,770,160,261,341,247,135,660,557,796,656,386,605,770,367,749,168,954,266,146,548,182,389,918,601,180,0,303,489,118,163,206,92,544,26,543,78,646,69,660,242,854,896,692,539,276,910,72,164,622,485,827,159,212,204,729,395,69,219,404,763,770,786,779,73,296,416,374,982,571,493,181,825,780,160,978,824,679,680,710,75,154,557,307,834,465,30,72,752,108,116,643,501,265,295,74,154,73,731,366,316,987,741,237,418,463,728,948,236,371,213,951,841,377,159,401,221,804,819,324,900,578,502,421,271,832,479,493,647,896,732,235,963,976,228,219,736,500,795,901,577,914,400,646,786,444,878,214,555,778,469,49,616,788,957,926,954,609,836,646,84,461,435,345,172,313,48,468,219,866,321,410,159,97,715,469,463,811,563,791,937,727,616,890,573,454,639,516,542,63,845,39,499,250,205,150,605,213,456,952,234,652,518,188,662,55,525,892,978,443,586,425", "352,616,4,763,42,790,301,692,565,86,905,718,319,479,218,679,143,884,110,605,32,424,436,515,788,399,271,979,575,93,699,556,722,44,574,969,159,44,269,437,832,517,573,14,635,483,787,723,448,582,296,691,729,205,61,294,442,397,400,205,278,931,62,743,930,102,308,933,889,658,292,111,837,855,376,662,11,342,123,206,780,833,877,739,279,229,463,733,913,570,324,336,995,843,246,108,584,694,823,284,974,353,491,212,545,532,455,210,846,869,948,561,919,109,997,527,909,679,114,895,910,783,947,944,14,519,980,680,947,446,304,647,614,207,713,714,440,724,910,879,606,21,221,416,564,673,95,455,609,621,914,743,728,953,266,713,364,962,896,840,272,200,859,147,886,27,232,206,896,405,166,307,805,123,121,661,826,50,426,522,224,300,698,121,772,54,281,222,405,766,793,381,954,857,650,656,433,219,224,697,664,213,294,169,754,755,425,11,860,419,788,661,777,69,151,482,954,195,754,155,262,650,267,222,170,921,805,993,294,13,536,697,713,298,317,208,190,172,742,213,210,966,285,801,731,264,701,887,539,904,908,844,500,110,970,677,644,234,858,598,487,801,949,907,967,155,716,670,114,117,932,759,79,574,770,435,50,863,547,731,82,465,610,386,850,862,725,739,440,601,646,41,704,401,735,887,785,333,703,46,816,642,270,266,914,973,330,749,964,210,525,771,421,115,408,166,982,478,301,945,236,343,783,574,832,43,744,266,910,178,951,655,683,650,662,821,526,939,646,666,633,820,561,41,975,381,240,211,369,430,766,221,928,892,960,122,675,570,378,600,667,967,393,427,578,432,276,612,811,591,843,504,725,485,385,672,411,485,914,175,482,390,417,457,682,934,935,76,12,655,910,175,208,112,763,645,397,199,168,195,177,263,111,38,979,695,425,171,977,157,445,565,808,448,283,664,73,833,745,611,565,498,61,419,866,109,59,100,953,291,410,884,966,260,640,473,818,583,718,441,579,751,644,513,468,662,625,751,74,518,429,412,623,677,222,22,931,600,767,399,656,285,2,629,571,754,481,680,135,708,656,425,191,569,236,18,929,576,580,591,684,186,175,157,457,812,541,561,358,137,613,791,670,664,960,87,175,119,598,404,806,738,644,98,553,738,132,274,45,843,942,285,865,108,979,178,437,382,86,924,192,300,886,895,831,202,330,136,913,835,336,576,138,868,327,356,646,107,987,466,171,773,954,435,508,724,970,26,570,682,208,866,834,905,4,231,266,865,2,20,496,768,811,20,108,561,113,943,395,799,673,976,789,470,280,10,22,967,155,496,361,82,874,309,795,608,839,649,508,733,270,10,663,195,663,744,442,879,931,280,391,948,104,817,692,693,111,208,338,302,510,813,375,590,382,559,840,564,171,247,797,573,99,550,854,897,836,656,951,753,490,160,785,768,745,664,185,167,790,670,607,906,204,534,465,124,694,600,872,537,611,195,916,67,957,757,578,75,354,300,467,890,495,368,105,430,911,432,684,286,813,9,993,181,91,317,844,663,369,469,807,935,383,435,647,16,869,839,738,331,971,491,620,341,874,7,938,179,327,244,653,394,277,653,462,556,348,742,245,999,978,128,227,858,689,831,361,400,757,155,360,315,80,109,175,754,73,430,663,303,754,153,940,649,995,656,952,476,260,717,498,102,494,153,968,294,543,314,845,239,547,22,151,579,373,914,26,174,939,250,278,164,519,417,556,222,326,321,719,235,724,817,944,166,837,251,671,222,4,753,350,823,861,504,146,321,823,306,974,979,565,633,224,302,131,793,270,535,283,353,251,140,175,629,687,443,459,978,229,762,439,528,76,713,303,0,862,310,968,94,694,474,906,89,310,39,567,37,181,315,996,375,105,141,954,870,149,771,159,538,322,41,370,621,394,511,536,462,592,575,337,491,325,48,113,981,482,503,799,791,461,391,592,334,257,322,489,219,157,659,856,490,684,921,649,347,58,784,738,121,79,731,571,429,781,45,207,238,607,17,678,309,467,550,563,290,345,184,939,103,580,701,333,799,192,722,471,957,697,141,39,432,867,534,617,151,409,747,171,667,798,600,414,548,283,830,718,571,343,222,753,512,164,692,564,197,151,250,381,320,243,121,249,377,499,461,727,53,369,683,372,20,611,543,119,517,983,236,656,934,313,720,707,519,969,159,746,710,669,382,622,641,947,954,725,913,977,162,561,647,38,372,722,758,973,571,677,954,130,864,315,446,223,63,90,510,247,525,906,259", "550,336,99,34,308,235,863,640,837,145,895,101,63,422,697,913,540,768,640,513,2,186,336,126,313,93,180,914,367,466,592,479,895,402,1,827,309,917,158,533,468,866,419,309,429,452,807,171,860,653,526,249,324,731,48,818,36,816,502,401,896,270,609,254,262,823,868,613,599,142,892,868,59,549,933,190,275,717,819,321,451,365,985,928,882,457,183,765,377,834,60,74,664,54,610,411,523,923,355,654,747,262,951,356,96,39,781,718,105,81,827,296,93,960,27,749,323,283,493,37,928,699,107,342,271,120,152,88,879,142,768,292,11,12,101,804,101,659,890,461,785,426,312,920,441,121,114,633,798,735,659,679,901,931,434,344,258,877,592,61,446,226,289,549,932,808,943,731,889,196,266,396,594,107,572,245,221,357,861,937,928,259,16,727,709,647,677,387,553,757,130,9,400,974,862,283,601,534,636,97,692,33,338,779,244,812,832,348,373,844,648,527,712,289,544,941,878,55,340,314,256,866,835,650,973,733,939,265,156,16,75,539,390,412,877,208,303,438,157,175,743,947,412,929,489,627,969,341,136,543,256,703,26,996,874,35,306,908,763,641,785,501,837,450,203,190,955,533,125,913,341,50,681,139,284,274,149,863,350,422,87,696,283,525,747,749,505,99,341,503,117,871,344,854,642,98,663,136,103,135,464,885,410,209,277,811,20,799,978,166,148,66,508,403,880,828,123,996,98,703,229,759,329,896,342,286,138,150,458,909,32,419,658,370,464,325,475,644,938,479,690,290,56,218,367,664,479,93,260,812,562,744,925,206,602,264,772,681,256,418,555,90,811,853,768,966,658,250,173,169,300,823,792,353,811,190,41,654,185,574,649,14,631,441,5,854,530,535,331,63,860,974,11,110,634,247,902,549,51,118,991,141,150,46,902,428,518,226,635,246,66,192,454,274,57,41,148,208,745,406,504,116,364,146,802,294,611,263,367,342,298,779,827,95,702,602,453,57,200,589,929,407,277,742,574,769,116,536,134,636,917,687,328,694,817,306,548,178,265,616,153,846,31,946,38,159,71,724,260,483,349,698,85,458,785,919,761,280,196,747,211,309,230,702,944,349,280,808,997,39,448,972,869,818,521,362,798,265,109,197,333,445,725,798,495,720,822,892,590,987,869,434,824,626,899,549,277,563,885,369,977,656,243,10,411,235,388,828,331,397,325,208,436,871,928,214,23,805,746,305,114,997,893,727,267,636,375,775,170,6,625,720,207,218,375,241,713,634,316,81,863,307,557,617,338,518,818,965,651,385,713,216,980,190,520,721,578,648,250,275,482,504,609,467,829,497,102,579,661,105,146,963,275,305,864,555,426,675,756,690,218,891,646,874,92,419,417,466,710,903,486,62,638,193,900,892,521,343,677,968,397,136,323,136,156,388,791,378,759,951,555,471,133,791,518,736,783,312,302,394,9,840,762,329,599,468,484,392,550,489,244,744,304,284,167,793,154,532,814,799,798,975,794,937,45,999,150,134,186,644,733,920,571,115,408,141,674,575,58,742,997,437,889,731,767,114,875,405,261,939,29,574,677,326,175,933,8,481,927,712,6,553,627,257,768,43,414,474,568,548,620,174,497,294,271,899,717,141,806,137,99,76,944,490,388,801,622,501,841,659,675,249,701,639,275,548,101,311,127,729,779,914,661,972,128,950,298,570,714,372,757,433,970,497,612,440,502,614,98,331,912,363,326,350,142,167,213,899,900,184,465,926,395,730,805,290,482,989,163,705,492,553,919,611,884,724,304,568,780,261,493,891,452,546,624,304,396,977,979,990,108,331,666,801,89,93,678,488,377,56,682,113,780,60,489,862,0,837,960,79,474,365,337,111,856,31,304,390,228,550,63,310,77,886,745,616,389,152,366,474,154,367,263,530,378,417,311,723,868,547,501,181,694,702,772,667,44,60,271,65,843,901,683,760,439,914,546,359,141,879,716,792,941,73,139,856,472,693,203,365,195,148,788,215,553,58,784,853,799,909,123,147,833,444,475,412,844,752,350,76,468,463,871,318,470,455,230,553,418,647,174,8,751,968,553,479,299,873,680,733,46,900,658,574,664,668,149,570,464,834,479,309,675,593,159,941,831,198,328,197,240,800,79,544,984,384,290,914,825,955,439,307,513,352,38,772,910,904,674,962,158,618,528,20,898,67,379,255,66,454,948,729,978,295,331,854,910,326,832,784,140,459,357,252,572,48,613,525,151,454,270,861,469,406,319,339,379,370,599,61", "496,241,969,950,910,528,431,934,908,468,926,546,235,194,401,311,971,58,514,804,235,240,603,46,161,124,732,890,268,14,630,482,15,828,811,488,701,416,933,180,196,544,750,961,517,663,627,750,191,926,540,291,528,245,202,626,62,245,645,940,500,608,621,350,601,577,317,108,557,252,709,422,566,452,51,819,299,557,356,872,994,714,268,70,430,721,166,843,119,198,815,217,27,591,216,567,822,805,835,94,721,59,77,147,567,321,360,586,106,630,434,908,783,374,594,154,278,542,234,77,185,160,496,450,440,706,314,124,477,798,551,89,978,984,86,897,976,322,501,854,399,448,886,457,514,645,851,788,58,671,871,195,492,871,627,901,109,564,104,224,964,471,582,221,467,52,850,694,312,763,222,556,947,779,518,128,453,82,881,725,780,885,989,920,171,627,230,246,837,62,853,50,807,454,8,971,514,963,40,72,897,679,31,208,847,402,549,372,554,993,813,444,722,448,817,725,90,728,460,716,598,990,874,700,592,154,378,987,639,66,381,599,890,382,857,826,902,681,237,111,774,70,253,697,358,399,470,341,171,164,141,927,366,737,409,70,286,879,305,386,607,622,58,71,368,519,831,515,730,666,288,446,424,276,678,663,878,369,787,247,161,594,437,677,462,372,263,923,778,224,342,648,857,12,505,65,59,187,921,850,161,242,706,458,239,959,256,211,876,437,532,1,148,431,442,587,253,849,511,769,441,520,359,637,222,979,278,319,493,17,555,93,291,72,75,22,921,525,655,315,590,329,23,339,265,518,251,826,162,812,727,103,41,36,786,867,445,550,103,177,995,31,693,879,633,407,619,763,723,937,185,189,301,583,554,32,42,685,20,695,992,941,294,940,446,173,85,812,223,36,478,718,947,811,687,18,952,712,859,943,238,483,111,939,395,590,373,807,926,106,127,103,170,19,215,868,774,22,205,182,306,709,560,603,94,993,889,130,711,469,799,655,686,523,752,953,135,319,31,53,124,134,406,135,45,20,53,817,608,984,494,447,566,688,457,909,111,217,725,996,59,875,892,81,244,840,775,108,425,732,742,728,522,850,184,461,446,303,20,762,7,980,604,832,804,714,356,309,441,263,669,592,53,4,657,540,561,723,211,575,961,29,834,262,363,97,39,975,300,902,66,977,715,748,891,977,180,395,9,453,525,984,25,796,514,620,135,572,792,135,694,346,17,219,615,197,828,876,7,220,347,425,85,104,923,438,590,832,194,942,61,922,556,744,985,811,730,380,492,236,746,777,221,64,329,898,540,471,171,615,681,79,934,87,996,90,149,620,87,373,479,542,131,197,416,771,613,684,205,407,420,426,871,689,666,791,499,872,714,528,86,544,386,430,71,899,62,976,77,956,762,965,338,955,228,449,208,833,272,327,380,254,401,619,733,317,697,71,575,615,553,923,477,781,238,207,954,612,69,371,589,794,896,729,596,582,235,406,908,865,212,861,225,392,280,520,709,517,230,196,24,184,557,141,578,84,278,103,583,322,169,139,932,599,801,717,73,472,273,958,96,217,305,109,751,511,236,727,848,934,555,53,414,387,801,254,484,339,491,792,27,887,473,695,950,781,650,305,417,221,469,319,99,115,878,183,782,242,363,125,517,689,542,557,868,708,844,629,826,247,952,598,958,269,566,529,148,710,992,220,137,142,542,182,265,809,233,911,563,96,970,939,870,911,121,989,814,377,101,445,509,456,467,617,265,870,149,791,285,604,12,224,884,590,97,861,379,148,67,5,204,280,169,230,671,791,430,629,99,572,780,419,109,452,670,659,771,673,518,459,967,622,97,801,815,233,681,883,486,473,140,448,307,292,118,310,837,0,680,532,879,631,861,242,314,239,866,26,81,196,991,67,895,558,644,817,603,216,488,354,496,996,234,349,353,551,229,579,536,460,559,666,918,106,49,473,491,293,8,727,259,943,390,716,133,792,510,838,623,768,43,345,605,432,20,476,869,525,179,86,220,508,680,318,614,649,902,260,39,608,800,621,813,321,650,167,484,735,807,170,844,302,993,905,472,847,410,675,381,523,140,643,199,826,162,225,535,915,755,96,946,687,514,255,586,299,631,87,858,403,571,989,285,525,727,838,632,927,558,178,416,485,959,676,942,990,445,649,929,613,285,434,553,505,477,877,312,627,275,144,377,249,359,885,404,192,945,636,506,207,25,179,770,348,367,299,64,957,363,236,28,868,755,282,166,276,102,295,599,120,478,251,199,822,186,22,38,48,29,274", "82,957,116,927,587,992,611,642,967,338,348,786,23,395,525,307,45,40,720,463,128,278,555,489,252,450,786,822,620,59,255,437,954,502,933,450,394,690,451,951,519,749,797,572,299,449,998,666,783,53,248,639,804,44,817,907,234,323,940,866,737,592,608,498,812,921,481,847,533,336,176,581,455,191,208,29,685,911,466,183,537,717,457,601,484,749,433,223,935,134,758,637,555,326,831,691,145,185,424,979,873,668,321,396,40,848,788,489,827,94,118,956,564,209,169,787,339,309,743,240,121,154,23,207,548,217,455,467,548,667,856,106,375,806,412,392,934,70,439,138,769,581,763,918,10,846,819,77,231,392,407,48,69,275,777,958,524,924,150,194,757,56,28,255,540,395,488,999,985,534,767,293,714,1,310,708,764,420,299,951,833,617,259,460,477,696,614,211,116,925,820,403,736,87,609,800,56,110,943,324,116,512,735,679,457,227,24,644,949,824,378,227,128,456,831,866,624,86,763,203,80,921,491,847,396,581,26,119,108,204,940,832,110,974,369,134,673,8,718,634,870,164,415,322,583,624,473,999,685,901,110,733,768,770,570,308,746,67,246,781,298,928,879,90,371,7,582,363,616,471,681,47,819,949,345,246,917,670,445,887,919,377,626,771,133,161,626,969,707,928,842,184,916,148,382,494,442,895,935,343,387,243,459,719,691,229,596,71,622,765,461,538,707,815,482,904,27,226,172,695,925,93,666,192,965,566,677,93,343,483,287,645,504,389,559,315,453,970,954,396,66,146,134,425,718,806,621,160,25,455,978,159,795,427,290,859,447,355,692,411,665,613,570,928,953,305,368,708,49,4,180,95,747,683,578,763,750,4,850,811,493,312,53,233,629,758,17,721,103,874,190,670,724,478,432,780,655,53,472,12,977,711,33,82,317,880,126,984,572,117,22,816,523,117,833,918,942,658,277,648,165,263,837,304,599,434,701,846,65,749,875,843,336,214,957,648,583,458,743,1000,663,545,236,349,654,373,352,960,701,513,805,295,360,991,203,965,274,854,839,775,368,93,518,151,749,298,560,396,902,274,914,291,203,764,34,325,232,681,93,231,191,624,694,225,484,175,561,770,365,904,567,916,55,980,292,385,679,156,467,289,744,895,930,728,270,76,432,189,597,104,948,699,646,879,814,516,135,703,32,986,481,88,308,31,966,377,610,541,807,501,62,365,507,549,268,896,334,910,508,926,994,77,893,168,476,836,429,759,572,1000,405,394,210,304,165,847,867,891,916,321,91,705,308,103,877,53,939,444,309,890,623,241,215,232,211,160,813,496,992,858,628,609,832,673,421,285,554,108,137,302,816,441,375,161,864,999,124,605,449,149,306,643,419,482,826,143,646,302,394,528,946,761,868,262,517,808,82,22,966,644,282,716,413,280,276,405,645,135,648,258,265,700,660,886,971,241,476,563,774,653,172,897,741,562,298,736,406,958,217,612,693,340,26,32,175,323,601,670,818,284,411,700,710,432,763,904,6,527,865,168,969,279,744,74,508,517,294,524,480,721,527,450,159,324,254,792,636,120,918,930,400,713,348,730,184,486,752,496,535,983,300,367,535,442,518,396,37,112,44,162,755,219,699,436,723,628,362,707,742,304,177,898,403,927,259,465,626,55,235,943,632,338,485,584,725,185,187,966,442,370,608,770,490,624,475,431,653,4,764,928,53,744,846,659,139,434,432,319,598,559,591,86,580,168,422,867,417,796,830,755,433,911,263,385,209,46,189,373,774,637,377,342,246,466,469,888,989,444,206,707,732,998,98,205,196,134,294,63,633,228,283,392,981,481,673,703,26,138,827,421,666,163,299,861,163,968,960,680,0,873,665,776,852,890,462,811,245,333,515,510,461,333,641,741,918,315,479,576,446,875,535,211,695,448,615,179,397,833,948,319,993,617,536,391,725,890,521,821,109,52,248,299,339,495,142,749,487,479,751,185,337,314,841,677,634,447,598,855,344,769,502,221,888,783,70,540,766,729,188,854,803,20,264,715,136,150,486,850,983,477,666,283,356,342,797,782,523,48,987,363,769,212,531,801,316,196,647,439,184,504,839,924,576,473,187,535,232,736,571,886,299,202,76,23,410,264,420,797,376,249,223,408,796,499,50,874,279,157,821,672,734,240,526,177,749,214,986,573,221,426,350,946,268,83,982,465,696,940,693,934,372,218,547,862,899,987,553,293,766,912,272,522,875,196,123,749,773,506,875,79,136,351,622,464,833,460,330,594,596,376", "985,892,474,895,124,108,1,14,83,593,189,801,648,369,19,651,925,629,173,83,896,648,711,881,925,417,886,883,777,339,722,773,397,165,326,701,998,652,249,695,923,783,624,226,924,671,668,46,380,29,501,495,756,316,37,595,100,594,994,620,490,860,491,240,654,91,75,615,521,398,255,818,380,479,972,545,68,180,827,689,762,583,763,504,475,161,663,369,846,37,60,126,989,79,862,938,741,982,594,872,809,500,94,268,890,599,270,654,670,901,360,885,187,145,640,690,842,934,360,216,356,203,334,355,774,371,395,498,548,830,450,484,213,424,210,825,200,763,707,605,801,315,303,941,527,546,873,628,469,750,400,447,147,290,481,457,76,925,651,88,679,55,621,266,209,430,196,966,275,587,974,18,44,734,737,467,257,40,903,72,172,149,393,662,590,630,947,62,393,833,890,484,689,9,863,448,157,440,522,318,405,488,941,42,463,144,815,112,795,918,812,765,340,262,199,139,741,108,440,758,4,506,538,876,879,282,95,6,924,657,80,688,132,249,657,172,511,81,613,126,395,70,421,71,618,695,719,850,405,398,682,193,522,231,890,121,315,464,198,851,655,510,186,541,179,905,208,181,831,751,847,611,860,279,660,970,342,743,134,675,390,870,616,901,860,871,534,292,860,653,435,823,651,313,526,866,896,922,85,265,670,275,830,854,348,113,596,145,824,865,309,875,682,787,136,150,433,451,131,916,781,711,382,332,781,814,823,708,567,535,18,514,249,560,345,141,875,607,462,726,968,115,498,501,719,205,192,849,749,747,288,669,33,241,742,877,281,275,373,648,802,964,666,440,16,645,676,179,344,781,299,683,686,121,767,612,865,834,436,917,568,315,855,314,832,519,942,808,914,822,717,612,317,678,680,306,532,75,424,800,285,970,532,259,218,239,607,860,592,441,239,610,749,215,772,934,785,287,872,504,988,67,623,403,909,175,154,570,300,799,981,878,745,763,141,248,813,454,102,36,382,123,291,177,317,354,537,874,19,576,755,263,797,21,896,41,437,26,242,214,716,93,580,872,914,700,771,160,700,94,209,114,700,693,783,136,250,141,82,200,237,552,59,909,10,29,50,136,573,173,941,590,481,194,768,946,756,307,987,710,72,964,987,615,660,896,123,742,865,188,787,300,307,259,626,871,894,256,476,753,106,499,162,880,316,701,914,210,810,777,715,345,730,170,341,939,899,201,428,693,602,542,917,615,620,883,132,948,79,183,542,321,102,59,275,293,508,147,279,841,372,166,993,60,468,966,103,529,59,567,367,865,312,145,94,829,671,734,657,675,293,3,69,806,397,966,829,81,789,905,606,769,175,740,956,676,606,779,484,93,248,814,102,250,96,940,443,844,480,894,231,79,441,541,500,567,314,412,927,639,124,815,549,307,197,568,642,419,20,698,524,123,142,595,698,648,199,403,589,497,336,93,472,870,188,384,701,141,757,287,960,359,216,856,750,308,345,671,658,763,648,649,478,266,377,713,632,74,589,602,288,646,841,338,268,150,366,338,260,554,642,515,240,243,498,121,434,137,199,326,740,408,374,271,346,932,722,696,297,132,772,501,684,292,106,124,319,181,326,381,724,986,378,152,825,819,417,4,456,546,505,920,300,440,175,842,615,232,56,868,557,4,432,825,783,745,65,481,762,99,48,905,284,412,225,769,710,621,261,105,273,689,446,833,405,275,236,580,937,345,978,782,775,467,14,466,274,529,25,776,920,166,394,672,206,840,972,417,343,68,42,119,879,845,880,809,907,772,331,739,145,298,268,509,803,353,936,440,908,374,342,752,116,770,44,169,708,131,78,81,488,116,627,211,206,94,79,532,873,0,315,1000,845,516,23,406,712,744,424,6,500,73,914,271,681,651,118,185,855,703,451,372,210,697,320,896,558,773,269,888,318,658,897,133,510,549,485,108,999,881,709,219,244,571,352,65,113,593,391,852,280,315,190,479,77,922,663,723,956,638,947,49,609,908,257,211,904,942,111,349,8,936,130,98,667,854,594,321,191,543,375,409,743,418,266,640,804,969,560,198,550,107,463,823,143,971,469,549,290,762,712,419,348,996,21,843,834,862,296,775,96,734,105,935,259,610,711,667,912,349,532,580,736,421,772,706,266,186,293,850,368,678,16,647,914,770,127,260,484,396,217,825,898,759,592,909,289,686,985,892,262,447,444,470,649,84,641,35,150,460,156,911,864,408,678,727,741,111,439,966,519,377,937,793,925,72,754,795,960,868", "340,196,421,947,492,543,193,455,800,796,611,156,965,591,732,499,625,804,466,459,102,692,983,636,463,165,879,616,647,542,397,252,24,20,310,882,877,761,872,266,578,215,421,526,120,832,175,866,7,575,945,992,506,510,813,706,261,207,400,518,303,901,35,543,621,298,327,130,521,693,809,814,785,298,994,186,397,713,164,860,594,872,324,485,275,667,26,351,670,712,815,879,559,275,534,903,480,320,767,93,427,258,384,281,950,663,816,881,81,344,402,208,919,19,262,154,907,225,912,350,253,484,133,155,481,366,123,629,604,286,664,381,64,578,190,289,849,256,131,681,841,23,585,117,500,305,664,156,311,525,733,996,194,522,376,400,446,723,648,995,613,823,9,918,672,507,698,292,825,40,445,36,251,639,488,297,595,268,320,274,391,69,913,266,675,913,205,638,55,516,43,317,441,390,538,547,851,787,676,488,948,723,621,142,470,753,107,267,509,649,481,850,229,789,371,194,518,957,575,974,978,13,135,271,149,635,670,192,372,962,36,562,89,670,720,249,94,317,238,128,58,56,377,148,845,119,273,233,998,198,149,376,113,660,644,925,810,456,509,72,969,287,933,930,564,683,451,811,203,214,263,239,759,527,722,479,754,798,995,709,491,865,718,251,487,612,771,41,820,449,876,398,328,841,769,221,791,522,615,341,416,911,361,522,335,854,714,918,400,983,741,467,797,859,437,134,22,913,421,280,798,418,40,840,841,214,61,77,276,537,352,166,381,533,769,278,27,700,291,904,800,927,574,867,292,383,896,225,509,138,691,279,475,26,674,551,334,492,876,641,557,484,507,374,476,315,929,659,755,359,879,168,865,83,473,358,719,647,961,311,431,165,46,563,755,889,736,624,65,588,957,541,566,131,333,301,750,322,177,818,467,140,899,135,264,169,439,516,509,701,125,651,279,953,272,214,926,902,58,569,720,346,758,952,936,39,355,594,697,810,501,852,955,544,363,533,216,82,603,685,693,504,363,923,640,374,684,957,678,248,362,673,246,757,452,957,612,101,314,830,859,790,229,763,894,283,946,286,744,463,911,982,613,705,895,678,565,562,68,481,712,716,664,943,355,551,549,28,277,447,734,721,759,27,103,204,936,241,456,119,213,456,770,361,906,153,866,222,588,111,659,147,702,865,744,952,784,329,471,22,700,873,798,644,398,294,86,768,665,218,306,106,713,168,799,820,337,820,377,920,569,42,88,434,840,496,368,252,526,622,941,620,376,828,551,825,877,617,123,50,749,672,675,456,902,530,364,416,665,928,48,546,788,348,57,719,66,410,197,904,245,594,243,223,292,763,889,20,193,807,595,99,613,794,548,170,597,580,823,495,168,733,744,419,901,114,111,562,56,425,495,149,824,213,310,931,11,745,28,720,83,426,348,9,304,145,299,512,778,173,657,460,297,536,118,6,911,250,771,193,468,119,992,351,703,501,385,947,645,471,227,361,686,583,139,323,335,607,146,945,340,780,418,980,989,243,863,586,671,767,868,127,461,912,356,627,572,344,534,767,657,258,739,128,832,73,320,120,916,969,588,592,74,230,425,254,584,666,927,235,528,248,499,314,199,361,369,556,581,776,725,921,661,233,90,633,887,183,689,207,553,121,738,115,789,308,859,102,875,980,461,283,391,938,340,94,338,340,123,84,351,570,73,300,628,25,653,419,662,105,14,825,963,659,704,616,904,588,643,750,97,554,797,521,44,286,479,993,161,538,405,193,998,552,138,211,563,513,629,981,752,105,434,783,610,674,459,135,650,113,406,160,776,923,605,893,55,450,918,502,588,755,776,751,797,593,210,717,282,684,55,710,584,875,92,694,474,879,665,315,0,329,882,805,970,231,791,238,557,194,667,311,355,852,978,475,166,157,991,409,863,741,190,276,327,182,699,585,549,697,362,47,405,572,252,98,639,684,470,543,949,354,237,215,86,365,752,578,308,137,675,539,486,205,294,616,555,479,102,524,717,922,423,831,920,214,438,42,387,740,792,747,86,954,439,919,550,750,611,629,956,356,598,467,318,310,852,807,695,913,858,163,995,768,759,283,357,568,69,306,394,450,61,295,469,476,818,324,855,997,166,716,483,484,368,672,633,610,460,413,930,972,253,573,362,433,900,311,35,649,379,914,861,312,845,664,826,28,277,920,196,367,621,251,198,511,764,274,302,832,591,171,743,777,808,369,233,353,419,786,13,79,411,473,879,374,508,577,259,49,727,148,602,51,137,690,131,640,746,643", "915,691,86,759,893,239,832,254,125,498,442,10,903,510,265,901,131,741,325,282,493,804,574,14,390,866,575,135,851,108,200,901,932,996,742,807,743,400,973,494,541,36,364,745,822,207,860,769,453,970,829,462,475,407,614,182,782,765,932,510,528,505,450,712,637,352,73,250,178,303,630,618,264,717,51,931,303,339,824,694,658,359,363,927,727,663,656,685,819,953,550,414,765,614,371,831,781,761,996,556,693,976,361,271,897,143,718,124,872,894,25,443,440,353,11,19,358,381,592,835,631,598,62,334,91,237,876,183,746,430,99,160,194,937,909,188,923,586,470,212,48,102,677,82,315,407,738,73,928,282,569,136,428,23,459,646,316,60,481,933,747,485,353,911,393,142,655,86,250,317,800,114,848,669,512,71,371,936,555,317,677,277,547,756,764,205,628,261,134,525,384,520,785,794,970,668,680,937,830,388,254,708,406,889,552,216,139,291,285,940,563,818,218,731,140,421,878,590,364,541,397,423,159,122,929,365,40,100,490,400,811,491,422,276,812,371,907,624,76,386,229,267,366,369,122,568,644,419,42,328,645,71,24,104,697,974,196,668,587,507,873,832,608,421,92,755,345,452,602,64,302,74,19,908,923,15,630,664,989,107,819,944,464,818,938,955,542,714,313,707,501,166,909,665,606,664,782,170,355,983,225,13,449,165,117,311,516,420,483,704,90,530,117,380,577,732,665,516,112,545,725,791,623,157,573,557,728,64,943,184,105,898,858,230,148,228,358,764,347,392,430,935,826,943,609,269,266,556,858,75,594,934,373,292,74,348,281,986,775,436,715,778,204,539,530,303,506,507,777,385,575,202,47,468,969,948,913,370,150,140,403,197,441,626,845,320,353,159,778,188,371,715,751,612,662,205,368,978,547,343,970,930,5,469,839,188,433,18,777,32,802,331,580,173,465,437,635,238,629,267,636,803,711,490,579,467,258,126,934,269,867,594,427,411,234,961,795,243,138,838,388,622,205,330,47,534,191,511,306,902,5,345,493,956,899,845,726,801,297,720,115,353,934,925,915,797,415,894,463,960,789,842,193,181,698,450,100,639,346,196,326,898,361,27,380,386,234,172,610,810,591,258,806,896,526,401,669,264,740,292,459,100,870,219,851,679,288,259,250,968,848,761,230,568,974,398,372,724,240,346,842,977,5,320,352,29,822,27,6,411,730,779,550,581,593,906,357,782,747,948,553,117,356,876,661,808,734,7,854,631,456,265,133,995,403,780,356,706,883,243,873,293,505,470,994,640,389,453,960,71,263,580,702,483,733,555,698,193,853,942,146,880,372,803,635,953,29,801,882,565,620,702,477,15,219,988,153,663,496,686,895,56,774,954,699,945,462,855,678,568,858,849,296,345,365,925,527,306,974,443,38,304,147,225,334,542,429,401,905,154,114,39,393,104,80,155,75,92,565,342,358,376,243,277,704,583,401,599,728,624,978,891,144,293,444,785,915,505,505,92,99,157,41,700,40,470,718,506,781,553,858,554,496,560,567,973,103,483,84,166,225,671,699,34,471,525,170,180,448,193,635,308,100,553,194,61,252,139,422,855,299,429,541,942,341,542,477,561,825,527,824,954,3,764,247,272,625,771,641,609,300,541,879,459,376,471,399,758,874,787,657,721,103,495,318,47,760,882,545,370,77,107,304,316,684,636,202,396,746,126,186,185,37,90,1000,531,216,766,671,158,606,172,785,924,906,677,672,712,111,603,371,344,479,865,603,876,638,507,232,245,95,800,474,891,296,57,576,763,994,142,378,783,878,128,140,945,174,472,407,154,488,7,21,891,102,410,575,363,716,840,756,825,703,367,544,474,365,631,776,1000,329,0,644,809,340,24,963,409,408,154,573,677,470,579,780,437,719,517,909,996,461,538,346,802,184,776,456,5,298,798,809,419,892,202,362,482,304,763,577,325,283,764,278,591,400,18,231,714,704,393,652,125,162,568,428,812,852,795,352,834,401,955,346,206,576,106,698,869,152,552,543,480,739,236,164,720,942,545,957,394,372,184,45,204,671,955,665,480,534,98,775,781,849,900,463,701,144,155,873,932,360,659,435,734,916,413,307,561,658,588,558,896,388,968,723,920,972,306,336,692,79,313,836,350,781,961,599,628,776,550,572,777,374,282,55,322,949,370,83,217,821,20,969,515,566,65,12,383,774,634,944,489,292,296,653,724,729,539,790,460,916,111,567,60,406,387,30,64,560,376,321,748,375,265,680,150,705,511,632,721", "946,424,950,83,574,161,447,998,901,512,995,413,155,564,261,787,79,427,81,596,609,932,786,951,942,108,375,524,802,439,343,490,191,57,995,782,333,502,648,740,98,163,301,59,317,86,130,194,608,253,478,747,475,123,473,676,694,731,10,65,968,388,137,245,699,234,633,428,247,892,329,875,183,424,514,224,517,3,901,315,652,5,209,798,909,262,970,797,976,180,857,939,161,328,79,194,603,281,562,45,639,30,141,501,669,75,169,635,434,523,405,389,609,729,984,245,850,928,711,179,619,634,416,915,143,631,500,809,515,725,785,737,786,774,478,341,388,411,696,307,152,361,407,994,711,297,506,633,159,64,469,438,92,437,934,878,716,302,800,627,927,326,54,553,372,718,164,695,508,131,680,306,329,402,355,458,866,512,155,293,454,874,453,769,112,276,806,799,747,806,571,474,634,855,243,182,700,219,271,403,980,809,710,677,38,921,699,742,257,938,269,976,884,547,875,945,528,706,796,118,435,35,639,603,386,549,771,706,13,62,811,385,786,404,419,130,105,881,249,586,690,3,75,760,433,882,166,462,990,596,660,274,708,585,841,39,815,617,713,182,636,171,460,299,616,386,270,309,685,167,294,488,841,215,509,713,634,484,361,194,959,685,929,451,464,520,721,461,308,188,681,366,492,289,103,197,682,862,256,495,540,566,28,244,168,377,426,220,337,902,323,571,568,560,849,172,547,345,227,749,56,456,683,265,842,735,375,568,212,372,494,603,394,537,934,708,511,824,556,954,893,691,208,915,911,707,517,709,349,335,101,613,847,717,718,995,500,689,913,701,929,694,115,38,953,649,434,586,87,197,448,848,910,978,473,331,28,446,78,478,770,775,171,712,384,385,11,260,727,586,227,485,437,741,678,719,875,610,904,50,84,316,150,973,596,741,706,535,853,261,52,893,618,322,935,237,243,258,832,477,482,185,868,911,604,514,762,269,62,841,316,333,927,743,469,93,946,407,84,279,955,249,408,416,155,136,546,110,803,725,390,447,2,420,143,92,6,934,675,448,519,442,258,503,930,315,60,281,506,190,94,817,838,114,678,314,386,691,111,706,906,424,7,817,320,110,318,953,40,105,11,953,137,191,940,853,461,42,229,165,126,911,509,116,165,238,720,860,902,983,458,442,408,86,865,31,756,883,75,909,565,271,585,916,714,2,127,464,275,196,217,189,489,628,737,412,618,967,870,200,408,541,517,229,477,912,831,469,683,36,771,571,547,794,279,789,879,543,728,184,848,333,476,999,974,368,912,380,8,834,556,697,176,947,427,452,675,939,828,278,140,868,155,143,134,605,965,856,746,845,824,852,530,832,275,124,20,571,974,899,968,3,732,797,176,102,810,103,790,164,181,109,545,522,160,373,375,165,362,429,873,645,589,759,493,906,615,130,401,914,529,37,538,224,852,607,334,563,271,924,260,630,670,769,728,186,484,641,498,535,264,933,462,349,672,611,344,469,157,909,383,961,6,990,65,587,681,804,753,119,353,278,870,920,453,192,188,370,478,978,771,612,331,912,712,172,79,823,361,631,164,689,130,390,621,97,278,115,138,759,500,102,636,809,536,756,868,797,596,913,499,74,192,310,581,657,54,499,344,332,204,128,427,477,586,321,493,548,222,167,64,726,239,180,410,949,171,458,150,152,992,786,790,693,320,462,946,307,88,844,426,599,411,515,815,116,190,249,315,799,730,45,518,483,568,430,886,242,645,928,716,431,380,818,245,329,612,290,903,988,639,844,144,860,815,866,318,55,987,256,690,797,64,374,277,521,848,35,556,200,954,174,611,756,509,150,403,219,510,365,907,428,211,83,26,906,337,861,852,845,882,644,0,234,489,902,670,290,723,466,193,671,9,714,277,572,53,109,526,960,191,325,995,383,99,373,547,243,659,790,161,144,187,605,751,619,99,202,246,20,236,214,451,296,772,643,79,68,832,717,887,240,651,354,795,539,673,876,73,439,505,961,856,386,844,665,634,286,925,651,135,834,158,16,955,103,19,201,981,318,726,894,71,723,844,90,589,483,171,966,744,724,109,368,329,264,314,637,447,935,658,169,758,220,607,146,253,348,230,552,508,62,819,38,516,385,666,194,952,86,526,964,439,81,472,511,172,695,558,797,708,784,94,680,782,942,250,460,323,606,684,411,301,86,446,658,921,687,953,935,126,117,39,602,998,587,555,868,185,509,796,616,418,515,377,169,370,622,508,857,45,336,381,606,590,225,348,539,117,931", "803,249,62,330,341,592,18,1,958,923,338,132,799,542,398,251,608,555,330,35,611,568,596,497,214,190,502,613,378,839,968,890,254,89,141,242,852,801,403,393,68,14,530,172,730,72,918,530,729,886,564,337,63,590,943,863,677,678,466,828,648,353,23,652,825,919,496,201,786,88,393,754,697,562,710,891,379,412,850,893,88,920,536,633,252,960,59,729,206,413,638,366,856,754,866,638,152,518,284,939,379,209,214,486,7,7,159,159,126,707,511,182,822,100,614,412,314,373,552,341,592,423,568,121,177,296,985,270,489,920,748,847,764,649,645,376,522,621,829,791,845,545,886,296,635,750,369,114,641,136,707,14,135,236,775,986,715,772,87,930,590,812,436,65,649,855,79,969,298,675,835,302,450,652,639,298,889,2,551,314,213,762,129,326,334,359,461,570,588,860,200,78,334,430,927,534,920,591,678,222,684,538,132,631,975,683,478,623,80,165,163,976,309,755,558,250,304,522,503,607,727,123,927,670,114,778,541,238,427,383,176,601,826,37,861,498,513,931,783,924,964,865,918,540,46,943,226,887,743,71,742,33,871,370,54,903,55,909,660,916,854,413,656,472,602,951,98,710,928,260,409,107,35,538,743,757,793,402,468,445,384,166,546,650,953,440,701,833,701,979,958,392,920,853,878,722,457,406,310,28,539,552,238,36,262,802,142,253,859,67,497,850,758,567,872,668,410,627,835,122,872,764,701,297,750,934,551,429,353,138,134,433,737,809,861,933,210,137,233,723,413,121,313,940,422,663,90,182,645,901,680,482,633,703,690,653,833,64,104,197,529,610,595,46,76,905,297,990,887,189,546,751,876,65,464,869,455,18,335,164,874,553,336,56,157,512,467,634,20,883,413,457,702,447,764,317,190,596,172,915,634,942,824,811,907,182,790,854,589,272,406,378,443,157,301,244,492,467,419,697,558,628,9,30,415,770,829,116,168,927,73,173,758,561,365,590,986,383,815,531,757,866,671,40,786,201,170,692,315,821,675,873,547,343,562,874,148,308,439,841,482,216,385,232,151,839,62,572,597,285,691,439,232,570,668,695,323,281,757,564,997,674,758,464,361,433,886,2,831,886,630,164,987,952,409,913,93,510,405,925,413,304,478,238,744,185,288,826,514,543,184,844,942,104,875,519,475,258,56,59,219,440,216,853,672,91,11,931,914,107,852,201,322,432,862,225,703,840,260,954,84,47,78,243,452,753,276,913,180,344,616,67,817,422,848,544,356,890,853,728,415,395,88,265,671,194,210,462,733,662,310,706,17,602,862,655,394,249,344,603,672,422,373,503,51,537,637,736,577,391,588,401,71,296,511,327,278,475,122,99,776,492,964,214,407,600,827,57,553,216,799,826,914,347,234,492,591,270,63,831,371,163,676,340,327,247,405,677,158,523,428,597,46,513,75,429,96,267,990,243,756,173,932,279,934,481,218,601,67,548,392,806,680,94,659,91,29,534,447,50,970,343,47,854,529,596,548,756,518,905,216,783,931,544,99,469,783,377,881,218,364,100,756,785,460,572,438,595,528,679,180,970,146,171,199,162,930,439,856,119,694,261,555,552,144,107,105,510,785,478,765,891,347,55,707,510,536,523,255,496,44,20,843,622,896,657,408,522,334,532,867,867,591,303,791,393,215,421,621,649,391,423,675,342,333,869,976,808,379,219,985,86,741,100,187,715,254,636,666,426,413,308,726,680,819,123,266,245,78,745,393,21,953,274,919,704,59,644,322,922,8,657,106,900,200,616,921,849,234,573,335,128,384,262,252,58,66,192,944,600,193,28,354,327,963,623,525,214,886,392,23,606,108,467,543,89,111,242,890,516,805,809,234,0,254,387,200,247,175,578,602,335,918,608,894,237,614,505,207,62,828,5,179,914,368,23,7,986,371,412,666,39,485,250,286,959,241,111,578,952,480,50,690,940,738,997,988,496,934,703,56,202,176,69,318,813,790,108,123,865,312,492,332,522,875,99,608,195,437,900,338,886,992,856,855,1000,790,560,730,508,664,316,88,6,853,112,896,359,959,365,972,56,313,42,965,616,747,944,67,522,608,333,86,515,150,492,929,19,331,432,969,179,255,226,807,385,627,150,983,679,617,98,357,555,219,947,928,886,368,553,8,729,206,65,724,26,75,152,601,364,872,83,980,17,708,879,111,156,134,60,630,856,59,362,387,241,854,209,227,875,346,317,362,271,316,397,254,634,62,610,512,171,647,994,537,154,553,464,292,732", "441,932,216,348,652,124,333,755,632,500,133,164,844,66,160,197,806,755,868,961,396,3,39,918,7,189,953,241,970,525,553,415,391,404,418,876,765,797,783,637,233,508,120,850,907,305,729,933,477,899,595,911,287,268,597,734,220,348,811,691,415,41,413,565,972,297,299,616,561,612,892,806,780,75,950,35,629,930,876,922,280,929,460,421,158,141,726,847,214,75,602,476,388,128,19,986,521,657,79,489,196,189,99,828,430,20,727,50,333,731,665,867,600,255,145,100,987,132,560,577,917,811,681,298,271,665,781,699,629,767,3,154,891,790,120,168,695,322,237,28,406,678,539,251,418,921,683,278,2,261,276,858,853,825,456,95,388,139,673,159,747,241,618,466,475,180,860,742,878,747,263,727,216,893,164,409,799,598,126,456,409,160,438,961,215,591,941,336,890,794,887,700,552,99,554,338,535,869,137,960,336,640,892,607,264,215,377,606,828,566,823,796,392,573,309,772,144,461,201,573,820,447,850,383,656,581,542,214,394,237,500,867,39,337,536,927,808,412,223,566,920,48,949,396,851,947,363,622,113,921,547,827,850,361,904,321,151,353,816,54,396,333,92,274,359,337,265,456,521,271,116,286,345,343,147,224,303,485,925,983,215,433,101,774,244,38,819,863,249,829,641,498,305,113,699,709,995,963,411,223,156,677,499,137,477,235,496,513,475,257,232,733,44,773,973,179,141,313,59,109,784,575,680,236,546,713,29,378,680,803,701,209,275,477,92,597,11,889,548,449,565,908,596,497,284,304,20,183,444,455,944,527,870,488,198,944,117,978,602,162,212,720,798,148,681,531,631,230,986,25,256,667,61,212,431,156,693,50,254,572,373,625,237,867,472,453,433,934,473,776,512,658,576,482,234,764,506,329,568,364,526,927,31,927,966,476,72,230,81,668,418,842,594,85,542,770,973,140,959,898,783,495,215,236,737,289,406,322,888,311,953,632,288,480,970,515,588,341,705,787,162,700,9,499,625,619,555,566,863,510,204,673,896,716,511,984,731,159,826,91,425,746,814,157,965,800,324,180,302,310,952,796,656,502,380,98,664,84,7,707,895,741,935,205,101,416,772,207,632,653,828,62,836,889,232,409,258,684,885,529,629,239,312,471,181,566,379,390,734,272,790,923,650,372,668,178,668,894,94,944,153,612,345,275,808,472,335,973,964,342,764,541,125,477,882,140,923,750,110,261,741,735,934,702,919,239,207,923,787,642,662,728,56,226,358,150,147,564,598,908,685,589,263,557,947,538,18,75,600,493,450,374,124,219,658,682,405,258,986,553,931,103,141,26,254,773,911,744,795,716,625,976,870,125,358,805,782,626,986,281,582,664,950,83,611,684,735,297,25,133,153,633,904,605,478,453,198,496,86,907,501,311,37,304,427,164,816,872,291,289,121,905,589,646,611,495,19,33,595,864,611,841,189,110,694,246,820,85,950,984,114,421,662,58,352,879,636,843,831,492,116,382,706,730,553,490,830,191,883,535,868,736,794,974,160,545,169,589,526,646,293,518,35,882,757,46,546,197,373,274,145,614,476,662,603,485,7,425,503,248,72,828,898,656,159,805,257,423,290,81,884,177,510,206,324,46,152,755,257,714,287,516,672,406,930,905,554,374,860,522,425,502,523,220,904,110,688,903,943,195,551,369,880,848,10,940,715,439,34,391,67,61,305,204,900,287,688,300,124,724,408,108,689,641,940,683,482,880,324,656,641,751,946,308,165,302,588,993,619,134,699,854,636,891,221,300,591,568,818,752,789,349,953,559,701,348,893,820,96,872,667,587,634,700,520,783,593,515,41,107,832,714,817,224,78,310,856,314,462,23,970,340,489,254,0,283,990,898,843,653,37,620,657,831,438,602,352,34,919,627,310,185,97,843,191,558,205,571,18,817,718,125,72,918,238,772,37,991,255,706,115,226,859,99,322,717,584,543,315,277,24,338,714,895,306,673,644,36,958,823,776,742,452,518,161,25,699,729,637,348,54,975,665,628,246,337,679,652,503,116,861,196,230,407,272,613,499,182,866,941,409,170,403,857,746,945,84,353,256,576,190,498,761,43,951,3,887,85,312,823,418,643,60,803,386,434,406,788,657,6,873,117,42,892,674,254,18,339,130,935,865,577,666,512,413,404,728,315,645,30,663,595,621,847,500,817,588,904,46,125,475,328,562,307,38,480,915,707,101,991,947,193,400,76,842,26,759,442,809,467,359,29,790,663,863,129,723,281,354,877", "822,603,409,651,447,348,493,565,998,865,900,923,513,18,828,337,862,953,345,343,437,811,325,391,928,808,937,370,830,775,751,697,804,492,688,277,710,140,406,437,441,374,729,286,120,743,529,828,60,813,940,907,836,801,434,193,690,172,696,941,624,539,354,862,137,263,175,418,50,18,678,521,762,353,778,33,63,501,987,438,888,397,454,45,702,36,423,501,721,399,464,204,280,854,650,286,266,145,75,163,160,62,773,437,476,269,371,221,90,174,166,328,763,621,330,321,141,566,623,787,453,661,103,599,614,696,754,60,129,369,725,282,778,455,335,60,737,554,327,441,261,567,208,233,126,999,241,17,630,333,252,683,111,755,348,74,129,514,890,490,127,987,556,976,26,193,270,307,938,985,352,896,644,705,406,201,845,364,16,863,52,265,876,678,843,743,717,12,609,925,476,375,909,32,812,231,313,843,174,895,557,539,886,883,15,150,819,452,104,223,201,912,45,623,174,798,646,633,673,467,279,721,564,434,771,32,899,436,376,755,383,993,758,899,463,682,389,580,103,922,269,537,967,926,879,999,224,967,252,343,35,91,209,472,228,368,39,910,986,916,325,79,582,427,216,775,880,112,933,897,402,53,400,685,825,967,66,285,586,27,164,665,736,652,932,345,409,652,224,932,685,501,8,346,799,215,38,979,436,446,594,119,609,423,115,882,867,507,591,777,133,316,668,80,315,569,417,811,29,858,997,597,206,677,624,881,415,403,490,85,192,437,846,624,179,940,707,304,908,610,302,676,883,30,615,585,671,194,426,614,443,198,949,938,91,42,96,816,802,206,295,139,991,745,394,160,234,410,557,309,78,881,46,619,764,40,175,290,15,996,926,707,462,464,126,520,692,136,97,818,534,33,18,27,595,654,382,591,931,808,394,838,662,188,721,824,918,631,53,156,715,839,342,598,172,930,808,414,297,97,92,514,380,872,407,750,64,991,962,24,802,947,842,874,782,986,254,329,38,288,18,547,789,354,661,513,192,99,196,158,480,819,720,171,78,418,993,617,765,420,628,794,383,503,670,971,22,223,259,887,480,147,95,648,360,581,435,763,979,626,421,118,748,192,198,924,703,892,709,782,205,868,651,211,495,580,617,935,150,870,144,734,844,424,660,473,444,239,957,866,993,434,902,144,788,963,156,228,546,218,85,186,78,135,962,686,459,22,689,285,941,793,619,731,178,230,730,722,565,776,266,602,632,530,707,403,447,250,719,936,735,309,169,360,308,111,515,18,234,931,870,847,233,410,274,628,976,17,706,30,863,729,217,887,748,258,832,28,619,255,971,721,272,837,567,268,570,94,204,432,150,343,889,422,179,345,473,985,753,966,398,798,184,398,289,695,164,565,654,607,123,87,116,360,285,103,656,87,276,49,141,155,241,347,320,766,524,530,220,122,109,146,601,733,643,872,765,233,536,243,272,882,276,910,597,793,1000,67,957,1,574,286,535,178,690,428,823,847,998,223,83,175,733,48,424,906,296,271,653,695,34,520,102,911,538,722,847,166,814,598,205,202,596,417,485,310,794,181,653,738,980,513,826,646,265,748,159,282,720,480,213,266,115,523,536,102,775,205,600,514,321,490,339,14,733,508,690,458,126,418,560,86,984,888,71,791,361,468,346,590,41,182,589,611,948,50,175,684,147,174,416,460,714,599,132,648,770,201,866,391,84,892,42,324,482,489,736,161,71,56,479,13,826,664,885,717,571,330,562,212,133,56,928,457,482,85,500,688,915,637,952,44,112,281,399,76,271,879,364,661,819,946,190,655,943,319,312,290,846,129,865,504,409,999,621,600,436,873,308,787,580,566,615,585,646,39,31,239,811,406,231,24,902,387,283,0,757,161,824,813,827,466,584,832,37,54,764,139,504,727,888,997,635,143,902,347,766,419,609,817,858,156,175,110,976,93,685,350,44,533,50,131,376,161,482,413,600,709,926,128,978,413,17,205,80,939,948,278,725,830,275,522,211,473,759,63,351,585,686,882,221,198,650,823,183,510,397,358,28,81,314,425,574,388,401,293,720,224,532,941,504,47,723,591,74,351,1,511,102,548,471,74,322,861,805,91,165,921,347,211,287,251,589,368,616,145,728,378,161,744,259,719,587,171,861,135,977,496,518,452,884,787,214,16,883,570,11,2,725,550,385,883,65,459,966,611,149,242,86,530,103,675,825,424,302,87,658,73,556,48,772,200,144,63,584,366,260,746,853,248,163,231,588,981,433,207,131,47,442,500", "142,677,559,773,701,117,773,161,959,303,990,252,388,62,382,179,869,242,441,395,23,216,688,52,5,394,593,519,753,737,558,760,905,694,623,521,502,582,698,898,864,519,804,934,33,46,216,91,284,649,363,257,857,807,96,276,858,343,312,802,552,848,519,48,811,789,195,736,171,897,375,48,35,561,183,389,329,479,464,509,77,68,87,576,541,21,974,971,374,535,704,824,543,136,231,43,968,821,706,708,430,743,104,864,734,109,688,547,708,141,655,51,754,607,885,562,947,740,258,219,609,202,282,284,758,939,419,478,519,790,483,531,593,512,207,709,402,807,556,95,595,770,270,778,187,433,329,113,764,839,943,235,325,305,257,764,34,188,380,285,756,135,759,659,530,541,666,526,927,699,606,778,846,342,765,915,198,890,539,435,376,576,503,584,927,745,951,792,551,634,727,295,708,297,692,269,699,777,111,657,364,704,747,776,653,709,759,50,418,451,993,686,595,898,182,859,624,792,81,58,647,222,10,619,551,627,502,879,300,481,893,628,516,539,106,279,820,218,81,593,437,505,819,324,344,348,727,922,697,194,603,641,807,483,440,495,103,40,227,192,667,968,40,576,660,320,632,211,358,380,735,352,846,616,812,967,325,739,835,222,712,156,299,342,874,364,367,650,872,847,244,721,797,818,96,585,84,32,533,52,518,266,452,414,101,717,750,917,482,593,910,96,675,574,837,856,849,333,616,951,847,428,472,994,699,818,121,851,224,490,748,548,550,972,193,377,899,174,90,114,747,968,296,725,295,279,807,179,545,380,83,783,735,770,66,42,225,395,420,408,360,538,860,44,426,20,299,478,84,10,620,965,454,713,592,196,599,867,486,313,402,248,806,411,343,186,954,826,628,263,637,468,985,718,383,125,767,125,81,905,226,669,437,946,881,137,539,878,152,626,656,766,939,377,573,562,154,773,597,492,186,743,452,439,59,122,227,996,522,498,466,373,981,28,35,78,290,800,125,856,277,779,25,505,538,628,903,470,686,931,414,927,155,379,762,784,455,104,237,313,499,741,939,245,695,873,813,653,4,239,257,606,414,789,34,710,107,951,620,18,584,931,669,597,200,814,243,663,447,196,906,878,958,432,606,455,321,834,190,999,446,383,293,210,666,292,601,541,898,958,902,319,532,616,304,592,822,453,278,403,585,326,823,79,20,54,953,683,182,765,873,993,151,765,508,287,906,595,46,114,878,744,966,628,109,31,986,195,896,240,734,510,201,487,651,247,937,757,700,949,793,911,225,930,831,804,600,83,915,56,981,817,874,853,610,312,975,824,786,9,787,140,379,335,887,235,823,645,661,626,37,161,692,803,987,889,337,356,545,785,444,129,38,48,224,346,349,808,157,318,81,952,738,723,242,725,559,135,340,411,697,396,720,159,848,968,705,712,334,66,378,805,655,334,407,261,709,147,880,434,344,475,838,514,225,874,988,526,293,209,310,126,452,458,349,2,648,321,51,357,904,567,988,263,613,143,420,73,1,702,663,608,390,618,367,514,193,433,726,724,798,858,594,16,646,366,515,262,104,975,334,674,495,285,210,380,114,161,993,676,431,824,957,500,634,682,249,507,61,190,385,714,238,962,730,488,812,798,809,949,147,251,586,83,619,994,339,605,118,530,175,746,466,393,391,756,680,459,782,546,766,277,242,63,683,132,351,315,516,385,858,652,442,46,537,369,415,705,678,830,396,577,230,862,7,17,960,554,400,936,485,609,42,652,467,884,451,646,371,230,165,108,118,666,723,782,475,503,113,628,180,118,544,409,173,645,346,906,751,327,482,658,5,843,149,490,703,627,521,369,272,619,932,974,69,567,304,866,245,712,791,963,670,200,990,757,0,499,938,348,447,503,26,147,360,775,588,178,379,591,251,715,928,633,195,508,270,291,49,868,622,220,652,659,218,673,42,685,807,397,381,910,852,39,518,227,870,250,432,636,463,846,361,953,488,540,527,156,693,999,484,525,869,673,825,647,383,240,980,234,590,361,554,714,397,875,292,319,54,133,338,772,32,212,871,894,589,360,633,25,975,14,903,489,399,714,627,406,853,891,866,962,928,656,474,666,634,335,168,187,146,47,66,485,987,284,313,317,225,350,858,746,462,699,54,53,579,43,433,690,630,843,654,672,201,886,653,282,816,250,178,645,678,534,492,810,133,84,715,693,289,818,68,101,887,212,335,782,497,182,457,690,585,823,832,599,718,549,603,455,989,402,676,655,433,473,316,654,485,140", "297,122,488,914,258,779,40,400,632,486,133,132,187,904,929,465,8,484,468,356,978,137,714,940,653,23,782,876,731,366,859,652,75,136,187,443,450,799,582,117,87,932,787,769,873,953,280,436,642,899,723,282,913,355,486,376,753,517,235,66,79,804,304,185,576,626,537,706,140,264,901,638,515,150,378,238,504,242,38,488,398,438,765,626,227,801,9,661,979,756,614,200,95,782,24,487,968,402,816,375,378,912,887,457,749,692,973,848,25,363,258,574,276,271,924,283,979,185,443,810,194,125,822,726,844,769,72,17,562,633,555,442,406,920,872,660,575,72,624,418,592,287,49,808,105,372,28,730,567,674,76,862,505,712,532,565,92,313,207,409,637,196,743,283,43,531,694,929,219,57,976,271,28,154,397,76,629,79,118,998,936,24,263,477,608,878,130,196,426,411,527,247,448,846,843,578,87,495,712,247,713,241,10,146,346,124,621,444,211,632,241,890,311,970,897,462,41,350,786,945,388,704,250,485,957,574,580,400,411,42,872,889,859,139,777,266,249,128,175,623,407,763,733,154,302,278,629,52,723,685,612,790,555,446,57,450,778,896,29,170,94,279,414,964,429,352,259,236,415,723,341,872,352,901,64,627,370,811,177,688,733,123,227,673,400,364,453,263,967,85,56,53,252,980,630,906,781,516,379,754,216,109,281,607,646,369,761,45,273,148,349,65,609,873,856,863,762,393,878,116,73,988,127,16,890,440,256,47,889,336,235,930,639,159,310,166,936,766,609,783,594,973,343,730,28,72,969,856,209,868,244,786,953,799,63,282,421,86,587,87,335,133,640,818,759,853,450,290,270,722,501,423,336,984,339,383,886,413,432,53,530,654,250,366,382,373,473,79,403,531,326,826,479,584,670,556,112,761,737,580,363,193,11,8,679,967,867,114,257,770,211,758,68,188,724,882,169,273,458,297,631,741,920,49,263,435,108,531,845,483,825,646,515,188,845,475,802,103,887,954,131,514,292,798,659,975,596,576,48,545,727,671,305,51,258,516,904,951,577,557,47,475,239,697,205,521,604,644,772,438,283,156,568,87,502,248,494,892,446,696,940,999,758,41,859,905,793,932,653,819,624,509,813,566,914,525,535,240,788,244,267,440,872,393,525,540,455,142,761,35,989,239,436,206,287,981,701,581,89,178,413,885,462,854,351,633,844,446,272,75,880,400,967,865,605,277,842,606,732,779,610,629,186,393,259,431,453,82,327,164,324,853,214,40,665,90,556,495,668,953,246,542,341,73,809,402,885,469,73,235,758,254,107,515,441,773,484,96,638,101,147,898,101,463,106,732,521,57,130,714,300,77,339,594,580,348,583,531,41,121,798,662,691,80,761,626,961,273,246,323,745,230,953,688,759,915,891,217,392,460,421,623,456,362,835,635,314,849,531,740,102,485,490,326,448,80,805,410,872,888,5,182,507,790,154,716,407,93,924,284,627,900,938,389,347,803,533,629,455,254,449,370,779,569,579,532,79,47,45,292,641,426,259,927,726,712,920,764,757,756,902,450,493,506,551,967,11,583,103,622,554,125,642,245,588,644,433,702,339,287,987,927,349,81,728,687,682,204,777,102,399,3,612,464,255,781,314,209,202,523,412,849,123,342,620,331,821,14,154,150,155,615,676,398,64,375,854,751,197,742,999,514,225,904,598,316,714,57,153,860,304,151,533,457,899,76,412,844,20,528,873,272,791,482,82,787,910,250,695,950,783,63,628,423,735,83,841,521,677,804,466,663,243,254,19,308,228,693,384,198,972,981,419,549,689,412,924,254,953,388,701,370,926,668,947,24,90,76,986,919,293,886,236,953,660,37,390,26,333,744,238,409,290,247,898,161,499,0,174,914,224,414,850,264,549,610,132,450,850,503,469,840,265,499,702,387,465,542,251,531,783,385,935,660,551,836,193,206,934,967,849,65,951,708,556,387,9,188,474,139,699,299,211,18,168,34,974,442,378,441,112,254,453,600,505,537,38,592,643,730,829,544,704,215,106,516,172,370,50,49,503,24,257,195,388,695,437,24,541,715,347,730,989,869,455,521,355,463,212,168,76,616,346,94,892,522,80,942,728,359,494,43,356,873,62,327,222,932,283,790,550,403,105,986,601,420,429,484,728,767,675,301,270,400,553,352,272,859,764,467,687,349,320,233,429,162,717,941,971,48,353,730,153,368,521,527,185,537,717,42,634,719,896,339,372,241,997,78,327,787,440,966,955,374,981,58,694,745,206,84", "409,731,511,494,565,827,129,423,45,87,261,857,724,989,255,196,30,237,862,439,884,950,159,383,77,399,38,662,622,40,495,101,194,369,786,395,193,153,36,778,807,866,836,858,982,542,148,665,28,500,226,440,776,354,707,363,156,148,348,985,143,559,25,643,962,855,305,171,136,823,273,378,397,942,141,531,3,523,166,904,384,652,554,437,184,585,568,13,775,690,302,969,303,726,95,561,825,988,98,649,770,551,801,485,674,435,49,342,748,290,198,543,351,822,907,116,490,37,291,304,846,865,921,984,129,346,231,874,441,270,347,278,689,828,459,501,57,144,275,713,916,480,272,320,324,744,216,70,256,221,420,385,69,243,657,794,221,139,346,338,162,505,144,567,970,999,388,984,727,526,826,232,993,261,882,918,169,355,666,294,175,590,664,44,538,108,429,29,553,416,904,701,390,384,461,44,718,961,255,785,670,344,882,750,986,979,44,191,655,403,695,297,595,855,685,504,351,958,354,320,349,15,458,969,811,237,594,754,556,583,481,646,994,427,714,381,374,864,130,32,392,112,46,286,903,727,196,206,131,185,66,7,338,476,312,294,129,534,710,345,390,767,520,301,719,705,580,926,581,274,934,745,942,729,108,938,534,956,59,880,960,774,369,715,784,389,219,754,288,987,574,853,423,391,733,915,82,315,935,987,454,956,715,430,242,296,590,307,179,703,653,867,940,934,495,49,731,970,9,193,175,86,865,980,751,428,872,691,691,843,205,797,658,386,390,657,177,402,835,935,985,199,623,548,479,200,611,344,87,601,113,335,66,745,937,62,257,692,85,871,239,176,455,879,659,342,827,243,823,441,696,238,6,398,227,181,478,95,231,862,568,495,601,914,214,264,259,19,193,414,358,36,111,441,917,687,955,885,773,122,775,680,78,617,955,541,264,956,841,425,583,151,778,654,112,74,934,740,622,463,61,551,279,482,544,900,123,849,280,792,695,280,20,231,620,592,899,141,219,880,914,989,483,978,260,45,550,282,233,616,879,207,79,781,761,68,222,32,301,460,612,443,449,555,744,524,283,509,982,106,93,909,277,178,325,922,369,853,774,287,165,564,201,284,102,781,710,360,26,428,937,112,162,212,143,474,315,550,956,563,687,729,225,765,184,39,660,938,628,76,767,232,110,178,244,890,393,513,829,188,870,393,266,586,446,191,529,210,948,149,886,183,240,355,949,772,502,116,298,432,764,652,34,89,679,744,101,213,368,326,592,811,682,747,777,254,64,391,187,535,793,125,247,664,70,204,862,382,342,430,515,114,194,299,354,656,699,926,995,712,275,219,693,804,643,809,260,560,660,894,97,320,593,438,394,12,968,413,725,742,36,602,583,885,327,23,917,32,492,183,676,680,939,17,302,684,680,545,970,931,122,915,203,874,30,782,512,891,208,856,443,818,525,70,511,360,408,896,694,7,764,147,237,584,179,17,388,668,322,52,229,603,350,570,558,313,526,328,128,827,55,810,590,360,905,512,428,418,491,836,273,523,807,132,468,924,360,587,410,699,881,456,483,510,210,157,959,573,821,430,167,913,403,910,950,709,40,125,907,291,465,681,530,90,937,778,99,895,450,556,520,235,291,730,762,14,99,888,451,899,73,899,96,193,373,714,740,317,138,183,116,63,788,181,965,747,575,742,668,659,672,179,681,853,807,52,429,394,417,894,679,551,497,135,128,784,330,64,190,781,624,994,917,413,820,627,708,850,954,996,529,743,157,926,781,350,859,362,695,712,395,143,989,442,426,39,697,879,886,846,871,488,278,442,301,204,67,484,634,332,265,181,378,141,889,677,659,490,200,966,579,454,927,817,242,181,228,81,515,424,557,408,723,175,843,824,938,174,0,644,977,172,545,114,611,888,586,617,153,277,284,829,203,383,552,323,282,900,883,463,392,443,837,238,804,81,551,204,328,382,734,303,92,646,583,328,493,177,943,890,316,907,752,447,985,928,473,591,712,10,124,86,367,688,19,686,289,258,507,479,171,309,463,213,280,314,282,522,946,613,227,291,12,538,703,299,751,681,973,408,457,749,286,173,176,826,150,796,707,190,667,366,789,63,676,957,562,673,196,917,681,114,634,541,393,225,866,901,300,948,446,468,578,969,813,452,218,555,288,701,64,416,797,285,80,694,785,352,741,249,903,67,474,802,477,344,614,980,814,180,131,836,905,194,536,743,161,77,434,296,835,302,415,733,773,576,284,409,823,500,249,797,924,267,437,968,664,876,212,487", "773,939,618,387,510,951,638,114,673,321,770,122,928,475,88,127,319,29,205,286,587,957,565,248,644,883,665,192,228,827,848,219,356,827,496,814,875,679,909,779,219,181,417,809,137,458,142,196,13,940,594,620,477,136,844,959,287,904,342,475,241,990,213,561,40,964,341,43,655,305,714,25,84,199,724,187,984,359,218,816,497,484,260,565,160,631,707,880,746,191,821,248,644,18,296,649,436,479,123,941,624,966,699,244,124,595,727,235,353,844,20,615,207,147,306,312,253,380,516,993,550,368,616,224,296,524,493,33,954,589,176,745,845,619,451,273,560,468,873,601,342,685,405,754,406,543,378,738,217,420,845,320,557,552,556,872,109,920,120,726,920,921,611,9,398,751,783,18,971,665,978,379,320,667,881,762,553,15,228,418,563,233,76,623,901,95,782,598,539,123,434,640,641,853,715,90,888,888,68,970,670,471,558,745,205,967,564,757,992,888,410,79,862,1,863,316,725,246,245,579,489,650,81,180,744,933,731,526,535,313,25,202,979,180,628,378,182,699,367,407,617,484,382,697,463,505,765,622,455,792,584,329,55,793,494,19,281,315,168,91,218,237,235,914,529,706,313,452,382,645,718,515,841,680,214,416,840,727,673,222,419,494,258,408,498,541,311,838,597,139,846,362,722,774,405,228,81,386,108,589,306,56,797,467,90,48,539,924,126,164,179,266,749,595,309,852,699,129,986,757,297,731,435,449,977,81,849,520,828,778,181,474,920,719,63,888,299,88,55,258,548,298,151,747,158,668,721,200,430,558,464,611,402,641,886,588,90,723,285,304,175,780,874,415,134,861,224,388,867,241,429,223,201,209,851,102,933,808,564,728,999,101,800,682,763,834,258,683,192,491,721,43,21,347,550,726,809,236,364,93,746,273,127,348,629,339,220,940,374,873,136,815,463,856,278,148,430,62,296,654,955,71,967,854,624,785,453,612,914,895,778,602,182,291,662,588,301,710,260,531,294,191,39,35,267,923,419,440,468,565,658,710,560,561,446,200,278,439,388,306,559,40,206,978,416,207,433,111,463,47,612,757,662,920,805,276,897,530,686,344,347,174,671,617,876,994,56,745,861,682,582,67,361,264,119,794,780,185,612,26,300,638,663,64,983,522,31,779,161,462,996,347,363,614,488,80,416,575,177,286,593,330,568,244,592,266,187,14,892,997,149,455,423,485,509,387,38,947,92,926,823,882,708,595,722,810,705,119,41,963,345,765,486,301,107,800,487,608,591,185,128,41,25,974,986,549,644,376,167,397,637,714,560,768,826,334,48,628,406,351,864,736,59,106,398,937,518,725,539,41,455,947,32,158,253,488,257,563,425,776,771,124,143,73,577,670,913,306,576,764,157,102,526,928,350,274,75,997,796,455,837,463,358,563,879,650,297,292,847,791,741,713,96,296,755,567,469,562,341,636,57,915,150,510,235,359,949,753,532,781,44,381,368,326,7,163,678,507,790,864,193,460,793,539,413,256,771,349,518,374,683,783,64,584,715,78,577,145,504,501,365,382,437,273,222,665,902,171,303,463,59,919,887,58,882,497,568,998,71,927,288,692,495,709,597,950,803,616,424,353,831,180,552,791,798,933,265,800,453,663,629,742,882,725,790,691,436,672,821,882,569,540,65,105,502,756,420,805,866,789,722,371,25,139,811,534,48,475,979,886,712,503,176,267,224,193,569,708,687,639,446,871,415,80,164,206,322,721,783,661,707,645,697,211,504,652,328,501,395,182,547,855,142,350,338,871,271,262,989,921,788,533,139,150,282,190,646,146,137,695,284,189,200,99,519,786,589,999,878,932,333,188,444,55,854,315,550,196,510,6,194,154,466,578,653,813,348,914,644,0,845,135,945,659,791,103,839,224,860,1000,553,895,107,451,439,960,183,215,72,71,570,194,458,215,433,319,408,840,733,821,174,540,64,886,91,268,109,837,889,473,48,953,374,832,982,682,442,185,787,722,912,959,23,153,501,918,47,705,207,219,268,978,647,749,305,548,680,829,814,531,259,315,933,280,275,360,198,203,373,392,344,220,375,937,175,775,926,847,378,913,356,745,968,651,754,98,813,831,813,142,75,407,73,424,341,906,765,96,967,868,230,274,711,832,440,242,84,868,532,625,799,713,84,962,835,757,918,144,593,962,59,465,93,648,755,191,221,484,228,966,450,5,704,729,704,778,977,77,21,412,728,777,433,455,257,326,306,587,938,701,347,905,817,309,712,151,402,7,671,316", "356,960,766,644,804,762,642,114,814,859,834,400,953,495,356,906,605,119,448,341,494,397,779,742,394,87,927,123,321,629,607,108,594,740,470,293,629,664,696,363,440,294,535,988,834,196,445,504,384,922,403,870,358,250,942,821,984,530,34,792,591,32,175,667,428,941,820,973,219,467,286,90,554,253,383,30,561,988,926,285,64,335,214,916,976,661,633,916,217,501,76,720,54,184,377,129,684,331,355,74,285,543,115,304,722,799,760,689,569,703,935,898,709,438,210,864,342,795,755,575,821,886,355,281,107,225,364,73,962,496,90,144,572,366,521,546,420,806,616,706,652,212,247,479,554,630,257,759,8,327,259,418,664,11,128,148,865,198,246,543,832,806,270,353,36,562,963,22,916,138,19,918,103,737,221,669,240,117,699,781,565,318,783,814,199,137,52,820,751,565,215,274,128,480,651,12,779,438,481,804,867,755,757,356,949,876,597,376,328,725,887,767,58,276,678,530,414,529,410,593,350,179,962,755,478,366,190,104,608,177,629,751,837,956,328,909,74,139,729,895,651,623,491,316,279,72,562,147,573,369,413,685,942,827,671,842,306,72,684,999,159,521,134,384,357,752,679,783,158,479,235,551,644,388,161,545,456,783,510,195,78,499,872,428,111,366,791,360,195,973,950,402,448,877,715,367,665,456,612,242,41,312,573,721,766,579,194,197,812,19,702,415,319,619,895,409,998,337,581,747,32,867,354,98,181,794,303,565,616,309,459,466,947,588,24,976,20,521,832,971,645,307,468,442,410,807,770,347,355,459,891,78,751,268,507,184,690,184,365,827,751,224,298,611,913,147,746,932,39,18,306,785,731,112,775,388,24,223,949,610,549,522,175,955,973,109,949,510,796,237,598,47,423,721,195,16,516,366,248,940,28,901,626,221,904,319,33,282,113,155,178,722,174,465,608,382,276,731,115,47,632,34,664,43,893,912,331,325,136,919,494,22,606,467,30,323,837,718,92,306,344,440,112,6,160,485,664,874,499,439,713,779,671,105,706,465,88,975,457,166,444,991,141,443,69,199,561,888,782,500,790,183,36,844,272,124,697,616,697,354,311,149,193,387,459,169,472,252,813,944,985,722,309,597,153,471,440,123,971,807,450,436,736,803,141,994,629,195,578,694,473,581,793,88,522,539,413,69,627,131,505,306,743,281,96,815,928,372,266,979,693,452,312,850,221,728,445,85,255,661,905,461,122,804,598,650,334,515,179,502,937,262,775,324,179,338,602,511,281,173,747,77,252,994,848,970,633,176,213,960,474,537,133,815,480,121,16,742,997,627,374,505,388,783,547,567,380,209,172,992,524,526,14,782,601,562,582,942,427,217,489,487,61,541,677,954,835,785,484,360,486,387,856,545,335,567,965,914,861,874,491,250,439,702,197,286,384,552,457,745,346,401,490,528,405,185,491,376,450,696,481,573,181,64,588,429,652,888,644,382,521,927,805,995,332,902,540,670,795,39,57,260,217,136,9,87,948,908,226,144,88,8,13,992,615,665,193,911,913,592,333,982,668,736,968,490,236,243,838,355,638,63,496,415,294,737,171,472,627,55,227,704,769,733,255,779,881,357,678,264,774,341,468,434,911,484,544,182,547,723,694,545,19,777,221,358,355,515,636,265,35,859,96,311,279,873,234,82,789,483,747,926,549,981,557,405,938,800,660,430,666,591,22,251,239,27,596,960,252,714,690,578,612,261,85,929,423,988,927,359,37,849,364,846,590,376,478,930,667,708,975,261,484,834,606,722,123,648,775,913,246,616,776,846,829,427,601,415,144,164,62,616,530,240,590,552,937,209,67,291,860,524,716,655,896,996,63,991,461,500,667,573,193,602,37,827,447,224,977,845,0,427,421,564,285,499,634,567,738,182,305,865,280,789,906,364,246,185,407,225,713,32,284,281,130,875,662,219,395,569,337,373,315,247,975,735,141,33,737,261,32,390,237,721,401,316,198,822,451,552,41,421,86,707,573,438,147,439,904,887,925,291,390,178,810,384,143,975,137,454,197,198,443,651,91,569,910,902,272,341,200,418,131,332,342,262,263,747,228,341,653,560,768,143,581,328,339,155,280,480,679,149,659,231,510,324,136,899,371,333,565,908,495,704,37,478,427,880,498,723,166,694,553,223,266,29,934,894,157,605,727,455,89,186,30,551,901,114,966,503,687,45,609,797,927,194,825,191,413,255,107,102,564,377,445,726,955,461,462,658,246,143,441,773,6,869,973,162,281,818", "890,571,232,66,90,679,914,875,924,363,318,608,555,47,153,654,631,598,107,563,71,43,451,203,352,883,110,841,579,435,402,773,220,119,629,419,731,38,569,635,673,752,278,861,544,204,143,250,472,184,811,430,741,656,138,442,562,590,592,833,746,818,952,100,569,649,209,912,40,998,879,44,326,247,800,878,931,59,769,575,883,571,705,856,119,446,488,974,685,784,357,439,266,590,382,677,795,448,79,943,576,398,636,569,663,180,623,292,234,230,140,534,995,715,356,888,361,401,409,712,305,663,33,495,539,899,599,689,632,195,584,782,775,645,123,797,161,463,519,81,480,410,143,549,240,183,468,574,447,497,490,915,935,150,899,543,969,330,377,751,12,304,806,958,443,177,669,655,964,55,444,154,575,708,634,129,971,297,920,28,40,574,447,725,752,321,623,432,322,737,166,761,678,432,531,320,944,855,371,219,595,680,531,222,104,665,418,862,606,812,258,666,729,454,855,591,132,136,766,205,915,450,191,122,404,207,819,758,941,913,22,28,172,596,213,722,622,845,886,648,343,844,321,452,497,288,551,619,566,857,606,114,873,264,488,270,472,878,204,19,659,13,396,710,174,188,393,886,866,339,786,385,239,680,72,379,286,328,430,703,890,813,460,674,774,769,464,482,565,557,30,151,974,679,974,398,820,897,487,465,534,749,739,61,733,823,371,636,596,168,599,338,248,533,100,379,773,218,910,101,498,840,238,721,668,873,89,99,987,502,693,994,181,823,59,899,604,537,664,208,816,567,965,989,496,733,775,991,229,786,245,554,806,638,601,625,912,875,81,296,476,877,333,386,233,96,377,613,42,216,731,886,178,850,365,515,567,397,63,860,660,208,329,863,841,868,92,450,701,89,6,727,183,100,927,198,949,188,675,78,884,379,345,423,962,974,563,591,186,866,225,220,329,576,210,1,708,135,234,619,927,593,541,339,306,602,777,621,884,560,18,232,697,113,879,652,137,804,958,376,983,184,43,48,963,300,372,775,816,498,81,328,647,419,783,806,778,151,768,525,798,620,447,108,269,807,149,666,323,546,773,897,234,547,487,943,295,137,242,674,847,208,499,307,915,163,214,427,972,755,291,636,459,631,620,972,563,964,611,518,166,657,351,82,147,68,225,685,577,939,671,330,131,465,974,639,345,155,957,707,329,323,935,599,327,89,746,994,39,680,422,671,51,436,675,163,205,481,972,783,497,511,129,2,876,265,147,327,849,306,148,507,555,675,524,652,629,917,639,972,850,713,880,369,805,273,691,445,577,247,936,899,338,280,654,973,828,544,918,258,489,167,760,116,514,150,358,166,917,887,504,511,718,609,647,695,437,825,143,783,767,617,765,211,48,728,405,895,40,810,707,212,293,801,483,668,700,652,567,398,259,538,193,507,106,706,985,267,4,323,220,922,788,154,541,890,58,401,573,162,5,244,303,660,205,485,132,162,281,751,628,950,58,601,699,948,12,425,753,614,633,478,799,889,31,44,819,975,307,419,228,954,931,868,431,593,434,78,737,855,170,367,528,865,897,378,710,684,542,909,738,122,370,439,80,161,618,392,605,621,394,564,576,596,324,753,302,555,11,797,917,419,488,734,487,917,727,597,611,50,563,110,588,287,286,164,943,598,222,103,982,993,155,679,306,494,810,821,155,408,403,855,23,689,742,611,485,286,339,314,1,312,82,725,616,111,592,950,830,843,830,271,262,798,744,8,888,652,97,573,24,627,376,889,771,406,594,124,18,149,646,387,987,141,636,156,36,418,721,547,434,697,339,670,459,218,509,836,62,838,460,373,337,168,413,899,460,754,46,515,50,565,703,978,692,375,310,67,333,73,311,677,671,335,620,466,503,414,172,135,427,0,616,998,885,816,677,94,870,131,138,831,989,552,837,703,296,171,57,161,654,610,192,867,24,846,923,47,342,28,707,733,930,707,745,714,622,768,68,358,456,65,527,252,163,921,908,598,265,989,783,838,492,820,946,461,101,72,517,884,342,823,388,183,271,553,524,68,916,529,530,637,929,152,496,153,605,509,986,115,25,529,950,97,927,615,964,752,2,278,384,199,826,500,313,50,38,668,593,924,850,32,706,724,794,181,235,777,815,369,8,724,358,889,417,10,774,997,142,752,504,307,977,841,54,890,19,419,343,758,106,817,978,424,807,188,984,800,468,745,804,538,911,935,429,270,514,527,344,651,676,349,543,935,435,432,171,11,978,450,235,819,225,209,94,429,399,991,690,608", "170,430,239,219,290,837,908,963,838,180,217,818,453,885,785,850,613,340,317,338,176,313,644,828,443,189,375,483,761,257,700,705,600,646,150,936,475,260,450,720,369,121,346,763,128,795,686,429,176,222,565,906,593,562,648,183,590,156,288,49,681,191,774,812,725,774,424,869,179,294,510,610,826,528,358,716,703,914,142,804,835,29,673,804,276,364,209,758,757,105,587,46,196,44,693,944,318,343,527,491,850,133,304,914,583,353,682,221,135,665,93,535,301,578,264,855,498,347,358,978,206,9,60,879,258,230,83,25,86,306,973,741,241,957,563,143,437,983,181,355,319,996,948,596,217,604,719,104,887,100,617,161,356,601,502,705,720,727,443,30,684,120,117,89,453,297,578,315,111,648,643,545,326,371,421,667,297,837,360,856,787,551,589,587,413,562,249,223,747,193,830,120,874,333,859,347,761,917,639,230,887,765,252,842,300,859,794,457,761,726,213,331,808,786,676,619,972,188,213,421,685,281,220,924,220,528,997,24,973,975,347,281,89,302,516,47,390,434,543,248,779,13,453,367,805,978,973,239,777,950,268,462,731,235,839,264,110,476,847,630,482,459,215,202,66,868,236,200,606,99,928,225,622,262,902,208,159,604,881,588,998,187,967,32,778,631,437,587,77,657,900,98,842,47,738,543,805,166,749,354,874,231,42,744,440,165,808,623,390,733,831,117,462,556,691,711,738,395,768,456,286,895,523,714,958,877,470,624,89,776,602,285,626,314,801,196,511,624,915,531,486,614,923,390,948,655,233,72,332,766,715,508,637,508,897,555,427,187,243,655,808,578,426,556,591,165,653,564,5,84,839,459,467,425,578,690,246,281,623,829,171,996,308,72,875,775,993,845,378,364,581,752,798,172,225,113,301,627,396,157,850,598,481,928,299,957,694,192,958,214,47,907,582,453,5,519,552,870,638,818,128,109,76,948,369,104,96,170,892,881,166,682,4,169,686,911,212,469,99,892,964,627,908,906,270,980,314,56,930,601,638,368,708,358,186,392,834,666,614,489,582,317,675,311,760,648,358,494,969,788,629,730,288,720,911,299,847,548,482,962,141,531,14,7,142,736,847,874,530,557,979,201,416,216,986,394,144,381,774,987,611,747,529,573,684,667,925,294,736,328,695,657,792,169,305,134,775,860,852,985,138,100,705,292,371,215,343,864,756,86,953,28,259,298,117,236,735,970,4,626,857,844,662,924,921,740,929,382,512,124,101,204,846,719,151,224,439,885,639,392,382,486,407,761,231,960,208,273,114,616,595,622,639,215,910,186,140,358,432,473,151,423,879,12,668,931,159,539,712,60,866,788,530,92,108,185,785,455,216,281,930,857,843,564,195,160,41,583,303,939,465,164,290,571,278,835,195,411,74,82,563,539,222,629,722,221,386,864,945,215,515,234,92,24,983,190,994,895,640,735,567,773,135,69,730,115,305,362,731,827,756,943,485,413,848,680,346,603,871,308,813,194,209,176,340,993,917,965,41,279,956,588,636,186,35,823,678,544,239,596,918,921,36,247,642,851,932,214,407,700,563,405,467,519,909,232,353,336,164,508,582,851,132,280,74,541,426,67,835,496,674,656,146,181,778,311,198,219,911,677,94,170,597,137,293,215,911,961,402,99,750,904,595,934,468,414,723,46,615,805,953,508,719,146,176,161,461,421,194,464,780,278,660,634,371,595,566,136,668,123,147,429,752,500,217,607,98,160,265,447,435,521,145,535,454,796,271,964,720,545,20,978,112,413,790,903,470,505,428,827,922,186,502,846,929,550,636,113,617,847,365,750,567,859,287,447,24,273,91,827,694,908,207,547,539,105,77,895,641,914,355,470,9,918,657,584,26,850,545,945,421,616,0,131,138,779,305,732,540,722,780,724,691,938,283,465,355,608,420,455,470,965,221,307,741,749,167,123,153,574,901,388,740,656,157,126,724,521,841,101,447,729,561,877,489,898,893,827,363,966,319,711,964,834,825,806,845,90,39,646,2,454,726,477,989,726,782,132,484,663,526,684,864,378,183,838,757,523,344,360,217,865,487,984,144,127,61,801,328,972,425,227,706,825,559,632,630,123,826,204,654,835,725,889,733,948,785,581,495,892,299,682,999,52,988,959,266,581,159,386,950,204,201,965,449,693,513,348,131,571,11,450,702,671,950,786,137,296,828,436,533,474,187,911,666,915,320,508,8,706,173,822,137,252,110,656,637,625,769,616,182,411,399,15,209,312,386,306,507,310", "201,280,591,333,221,892,880,88,324,204,435,644,604,878,402,426,605,402,485,65,748,902,360,72,669,432,422,165,637,140,615,283,153,155,582,599,633,597,682,222,582,143,445,982,550,714,437,948,414,425,435,166,656,184,850,535,279,890,637,993,455,181,972,961,481,353,743,149,228,607,731,747,456,498,813,780,616,485,15,346,177,557,697,721,693,72,213,728,180,671,919,771,353,998,661,328,707,226,758,258,270,866,171,404,873,891,824,707,572,690,117,936,641,372,889,256,127,293,803,528,215,466,205,270,570,83,298,973,311,989,840,274,72,745,658,120,24,201,241,35,319,305,287,593,832,790,445,706,908,136,292,401,145,564,577,28,341,421,396,623,396,139,280,803,77,253,543,570,618,250,207,392,146,355,346,749,254,684,208,196,339,866,340,976,99,492,919,825,44,839,887,157,257,32,773,548,397,884,969,714,402,591,504,400,183,793,153,494,40,706,184,570,924,565,417,52,973,614,354,257,55,395,211,982,669,614,78,236,756,916,931,93,293,680,785,232,791,145,384,634,892,675,218,585,90,381,971,583,932,256,432,388,48,217,970,636,526,746,1,274,557,615,865,95,626,968,710,67,166,323,912,512,579,65,267,273,990,297,808,22,61,277,153,164,206,921,930,732,850,628,521,940,80,194,456,974,343,655,162,355,989,928,249,879,338,393,70,511,49,410,120,397,509,983,825,457,940,350,894,443,913,321,209,556,981,541,214,552,170,215,117,77,883,338,534,992,113,467,513,861,198,938,55,893,251,47,325,47,465,391,382,562,746,998,367,820,916,483,671,183,166,633,247,98,948,337,145,489,287,604,485,656,841,17,431,394,661,644,515,643,319,531,949,640,89,367,203,154,29,11,512,81,356,638,920,935,107,304,988,350,593,984,493,613,440,666,366,331,879,796,678,602,105,755,459,127,258,476,323,877,905,548,931,268,615,274,322,32,772,155,653,279,342,592,709,987,852,847,797,443,410,265,389,328,673,23,638,704,290,690,7,710,413,662,66,428,268,89,50,910,982,574,244,460,632,867,280,424,222,932,288,934,51,601,695,755,679,581,862,970,854,33,811,866,239,937,739,322,795,812,249,635,277,938,126,699,92,380,60,314,719,70,431,256,560,394,39,734,173,928,785,40,542,892,973,461,954,105,150,490,132,967,235,822,98,514,120,780,497,712,832,332,848,875,237,703,672,454,732,172,287,724,751,841,89,462,470,95,362,269,463,756,593,505,988,87,345,440,231,532,246,243,428,50,447,864,546,851,735,402,649,729,869,128,660,505,288,701,864,803,792,581,589,59,874,311,678,445,359,968,607,687,872,28,202,955,698,897,366,5,575,271,577,340,179,673,412,869,434,110,869,816,474,938,287,253,861,568,392,142,184,514,715,435,120,508,158,38,19,409,368,505,26,767,607,158,339,217,391,744,125,823,604,690,72,667,230,34,879,88,946,684,516,348,628,31,918,80,553,288,727,575,546,908,952,334,826,410,104,635,462,749,181,853,887,385,623,736,799,396,844,551,864,457,682,936,453,864,821,266,496,953,616,320,909,144,846,101,935,976,778,626,969,69,999,422,29,305,888,121,422,551,937,16,87,698,620,676,455,21,379,662,992,642,358,213,77,272,923,189,833,233,891,352,112,573,896,660,473,974,863,734,635,164,877,274,778,435,449,616,875,351,13,356,231,468,407,40,748,583,779,833,656,802,608,230,452,337,137,386,311,319,419,834,488,150,618,369,422,384,4,159,390,14,667,201,870,965,551,126,604,249,986,332,963,405,255,849,459,489,684,119,889,10,363,609,713,257,310,502,699,873,705,436,276,141,886,558,741,271,852,579,714,608,831,832,147,264,114,659,564,998,131,0,2,338,778,621,543,113,527,452,327,13,387,937,802,931,781,677,132,751,613,922,966,831,314,860,715,919,551,492,541,704,918,471,959,674,298,951,743,601,977,86,411,265,62,609,191,108,334,505,258,301,52,725,169,604,518,276,812,692,455,436,781,683,507,536,592,904,43,117,789,375,775,827,366,790,109,418,359,594,64,966,128,272,808,267,966,318,974,397,917,346,920,765,792,515,926,764,47,373,889,581,18,559,387,102,449,116,461,228,72,242,177,467,517,173,989,171,125,138,191,644,833,947,85,258,909,838,214,261,341,293,59,774,740,201,486,647,253,262,277,31,949,515,535,826,153,486,616,423,244,835,827,903,636,649,270,179,239,760,849,59,415,242,74,458,603,789", "815,976,556,87,926,640,163,645,994,535,235,319,205,650,488,710,893,346,816,381,618,367,940,32,793,74,698,478,854,176,126,946,194,543,345,5,284,595,194,817,356,348,222,616,59,772,40,233,496,445,783,85,840,456,494,835,775,357,49,892,361,578,115,753,596,817,25,576,623,824,303,348,71,923,368,337,890,370,21,205,981,454,560,260,953,395,159,761,453,439,855,647,571,793,35,535,860,533,413,14,113,710,759,355,757,67,69,197,386,258,671,273,778,737,508,147,735,354,283,21,292,250,657,810,246,945,536,168,674,881,701,64,703,274,727,272,16,506,148,395,48,433,979,475,324,643,406,942,746,680,71,77,511,238,383,899,390,977,499,954,989,70,756,688,298,730,530,398,111,466,820,759,563,509,881,196,400,868,477,658,821,658,198,198,236,216,120,152,963,977,718,162,149,772,958,619,562,138,278,741,423,551,189,433,862,385,104,748,698,887,473,262,384,264,9,329,207,871,58,251,279,139,477,241,734,682,189,117,835,790,991,122,46,874,575,731,258,859,833,19,758,89,98,965,814,8,924,941,100,898,474,718,490,646,7,79,616,468,348,148,777,785,12,978,808,25,837,949,555,635,16,190,811,38,263,526,515,226,24,915,190,257,870,994,882,244,58,387,984,259,627,735,948,489,187,245,901,610,899,413,726,303,405,544,769,68,840,127,939,72,283,213,815,960,299,922,929,713,792,433,452,727,651,374,445,176,811,874,662,676,294,598,875,750,326,356,304,78,330,91,6,247,363,586,959,944,580,985,930,799,774,429,575,69,170,276,110,707,993,692,447,373,784,954,458,736,601,284,66,633,885,114,123,910,601,284,901,982,419,706,973,156,895,289,767,216,609,22,769,914,945,158,935,455,770,531,938,552,146,634,95,533,744,598,452,573,838,385,100,515,602,458,589,450,233,236,417,339,742,580,47,928,668,179,290,724,894,859,520,392,64,496,805,712,938,276,446,274,814,715,234,166,984,113,154,984,59,219,845,601,449,55,414,920,928,791,961,562,921,361,587,84,912,711,56,119,586,701,71,719,886,800,499,800,752,215,863,829,206,299,477,787,170,502,857,385,125,31,306,932,717,952,910,718,742,360,183,374,489,555,385,303,406,77,328,200,107,12,444,246,695,974,912,133,756,538,492,24,294,120,892,701,412,681,666,38,677,758,337,225,187,918,227,582,575,125,728,336,14,257,932,212,100,627,941,358,395,696,670,559,251,565,434,946,401,750,806,822,16,251,316,201,981,358,58,892,436,274,545,591,543,346,187,705,248,562,880,502,224,174,581,590,770,276,215,653,103,299,837,394,151,464,412,359,237,212,7,472,661,467,228,773,628,806,87,410,993,416,297,581,408,306,793,952,155,570,119,218,302,908,799,147,882,180,746,844,93,96,183,144,900,650,774,161,265,473,146,463,89,559,172,618,63,51,140,523,734,524,748,932,772,109,519,995,39,749,223,877,792,637,218,949,584,627,589,231,70,98,231,514,357,770,338,476,780,258,961,352,327,716,771,149,59,592,989,864,273,720,9,593,147,564,630,172,323,266,32,319,517,909,573,388,958,405,808,371,164,171,730,173,202,211,238,111,596,231,389,158,259,844,744,755,228,512,751,511,435,323,391,565,552,487,110,112,993,908,164,556,390,703,50,381,215,145,152,627,90,554,446,717,14,295,52,5,52,595,170,394,112,481,780,201,875,688,933,881,763,38,188,381,618,31,785,982,777,169,970,471,106,331,78,399,431,104,756,498,332,750,141,318,581,167,46,527,166,804,148,107,735,887,837,110,911,234,15,586,414,17,724,37,158,752,877,559,910,954,745,644,918,681,978,780,277,894,438,37,360,549,611,791,285,885,138,2,0,858,284,380,721,344,730,214,990,479,398,830,978,973,752,826,507,264,603,176,246,365,813,604,903,954,153,957,97,528,857,164,460,474,361,370,759,238,113,75,891,430,777,369,156,723,46,973,184,537,220,93,301,511,671,344,643,548,514,39,747,713,786,956,884,703,863,193,23,78,526,778,493,485,811,897,156,958,286,879,388,779,427,592,754,576,193,295,229,600,456,595,976,746,903,58,993,728,433,59,990,349,944,314,924,542,277,458,553,953,324,828,927,51,507,802,692,63,533,796,662,446,766,905,490,721,493,120,995,279,975,115,552,786,314,605,602,978,507,13,60,358,581,828,936,157,451,432,945,919,748,172,377,319,464,946,777,172,650,7,51,468,105,180,417,288", "931,144,351,427,273,722,240,482,837,931,185,198,397,296,137,33,652,914,31,971,787,537,678,949,217,703,291,945,928,426,825,813,892,817,915,283,514,664,977,637,733,546,613,919,567,417,885,337,360,285,418,373,642,342,541,694,775,390,275,630,759,350,846,984,476,92,755,673,893,569,700,610,138,842,953,163,469,843,981,233,735,164,517,25,391,613,246,107,662,827,60,426,764,275,790,214,195,820,73,171,497,444,451,991,479,992,482,609,2,97,378,102,537,594,38,521,892,782,875,768,968,958,993,882,173,354,212,127,682,242,913,976,128,594,527,120,691,926,540,644,815,512,308,238,31,973,748,693,444,84,862,763,269,349,526,142,247,511,451,172,943,328,599,993,839,68,155,954,257,932,873,799,705,753,416,753,669,88,529,444,851,206,392,935,55,911,571,202,28,234,206,43,516,192,346,18,711,586,426,9,921,78,504,271,561,914,247,546,400,897,747,3,732,304,696,989,786,475,797,295,407,508,169,724,391,390,270,104,377,830,392,747,238,324,787,778,340,691,51,443,48,813,112,134,778,767,67,522,694,94,712,259,165,609,693,977,332,47,369,550,965,728,275,250,103,348,89,702,5,137,69,317,320,830,707,38,776,451,491,306,430,815,155,807,637,959,797,610,943,541,667,746,271,396,616,458,960,143,26,207,521,967,489,559,94,159,67,894,76,244,367,640,20,721,557,908,113,712,626,592,597,184,475,89,770,947,437,132,804,374,364,751,57,121,687,756,204,72,858,858,871,426,20,851,569,781,293,506,41,152,550,129,714,158,747,982,856,583,355,964,493,732,133,226,235,493,242,302,660,986,688,637,848,828,248,512,461,508,315,210,505,812,4,404,164,871,943,680,46,574,967,285,244,704,852,479,916,230,601,651,304,32,272,690,803,638,603,412,843,294,485,65,816,244,963,996,267,36,397,298,543,603,703,527,994,157,523,721,246,882,498,973,863,385,938,58,804,980,202,84,602,299,882,743,767,608,574,192,737,973,620,528,887,719,602,363,765,117,626,426,527,402,699,670,236,67,52,577,202,171,217,113,500,363,517,904,689,205,68,744,185,430,437,158,823,791,378,284,883,392,383,432,988,833,349,591,428,94,173,408,706,793,614,247,261,797,833,587,325,403,653,635,351,54,162,543,790,547,400,938,263,113,370,901,924,286,734,37,780,768,396,647,922,568,205,309,546,553,442,796,189,941,909,284,895,911,326,162,585,34,358,254,683,34,15,760,967,83,272,272,151,50,711,589,279,851,653,41,123,226,9,837,319,5,275,453,747,574,380,160,674,86,624,326,522,464,547,582,86,334,63,393,975,391,590,12,736,157,981,10,143,50,477,180,200,639,344,449,301,438,893,213,335,559,799,100,900,251,579,5,923,171,536,461,758,376,177,147,916,637,207,690,623,829,586,65,333,869,482,461,127,559,25,190,597,907,95,598,780,428,581,924,361,436,275,426,688,258,334,996,334,329,170,13,277,708,116,965,731,338,689,478,157,291,247,67,454,347,224,786,484,243,146,500,15,443,557,380,631,80,755,127,916,938,401,629,346,925,252,882,117,748,833,619,461,237,133,246,493,92,157,629,118,230,95,634,695,639,855,967,229,203,602,447,676,768,211,523,928,35,137,136,156,67,719,437,25,754,606,189,448,703,771,979,213,669,905,619,897,581,881,757,529,66,985,489,105,820,807,288,946,584,396,711,367,949,21,638,246,35,684,401,69,426,490,758,714,790,582,370,16,331,29,740,216,813,383,106,866,643,701,78,686,262,412,871,165,673,675,990,761,780,933,528,464,968,34,741,527,813,697,498,181,72,72,870,616,817,315,651,475,437,572,237,602,54,775,610,888,103,499,816,779,338,858,0,323,768,674,730,174,480,974,259,600,296,231,963,531,642,192,788,5,505,737,585,817,446,665,56,935,110,878,304,612,428,245,361,719,229,708,67,956,413,51,376,117,180,550,856,883,58,491,94,148,916,336,260,637,814,708,16,199,115,136,353,981,647,133,506,691,466,67,54,475,251,629,580,683,163,107,300,377,87,845,808,206,546,183,616,592,154,931,393,18,427,148,658,900,501,825,532,208,462,644,152,12,661,761,677,527,717,215,581,910,74,844,676,51,869,664,846,897,88,692,346,485,779,794,317,810,432,712,685,614,866,91,860,128,40,129,395,495,795,369,354,184,291,10,985,798,327,315,850,358,159,966,392,161,251,960,942,357,590,524,332,326,5,308,818", "486,894,839,163,147,154,558,717,758,77,571,81,864,490,781,556,658,663,744,797,555,310,342,174,100,634,279,711,627,224,336,974,540,557,708,112,690,947,447,63,732,135,864,847,481,72,938,794,166,593,5,143,127,686,801,684,750,624,243,369,197,692,356,945,394,847,889,319,651,895,809,762,911,157,348,604,574,740,719,16,688,642,576,163,680,167,233,922,546,511,577,56,549,669,446,410,324,679,129,976,91,691,568,183,50,945,128,463,842,486,800,999,695,511,80,834,493,316,628,322,503,132,934,459,908,918,25,199,426,271,260,221,736,505,312,597,906,329,649,192,753,129,359,850,299,388,76,174,463,227,47,294,831,848,301,203,919,836,737,433,68,732,607,700,938,65,667,968,789,658,708,861,984,291,91,332,762,50,652,220,829,378,328,393,277,809,906,996,551,580,733,329,920,442,506,454,778,334,241,132,296,427,163,580,557,841,363,22,47,551,216,860,614,172,458,188,850,685,235,688,641,66,672,892,836,248,879,119,869,854,395,825,659,546,305,986,320,724,941,395,610,998,416,864,30,279,721,127,409,285,647,367,819,486,289,125,30,276,997,341,284,252,132,601,9,801,425,697,307,273,320,120,844,987,465,275,242,725,846,838,577,912,908,28,502,698,344,577,512,591,27,93,78,414,76,591,141,900,292,491,748,390,136,205,549,17,483,548,365,762,643,626,121,114,593,37,836,226,624,146,428,193,925,866,907,226,430,741,162,305,53,273,237,238,784,935,921,994,548,798,696,467,570,448,407,327,954,869,993,263,378,363,32,92,655,900,480,894,498,918,986,949,747,724,514,581,75,475,337,161,170,947,153,114,64,672,186,616,487,592,274,505,770,144,3,251,109,218,518,143,689,17,574,516,140,933,985,406,980,839,503,11,381,110,409,230,382,126,758,19,162,501,448,150,553,341,90,427,154,998,639,744,917,244,463,829,564,618,659,501,356,169,981,219,29,894,916,280,149,836,491,696,619,313,712,963,976,111,438,61,663,889,740,972,550,199,255,426,377,950,802,784,210,339,558,316,793,628,829,141,343,715,372,427,165,668,919,988,107,757,923,876,336,321,905,501,727,215,581,847,480,692,211,410,45,388,932,745,431,373,524,525,503,88,826,130,391,175,21,942,832,327,256,237,705,86,33,416,773,257,215,28,146,972,601,620,993,75,221,175,36,730,845,893,616,955,487,540,643,922,580,830,435,473,794,843,554,485,738,460,957,841,244,630,363,459,768,89,43,216,80,780,714,153,373,676,931,610,392,448,652,565,62,673,898,812,553,354,190,677,299,298,190,468,478,983,387,13,64,245,220,796,985,918,23,369,912,637,347,620,731,859,443,789,992,295,948,712,5,971,404,241,138,394,379,226,625,341,584,119,453,739,583,51,199,295,238,483,968,246,761,223,793,83,776,762,210,271,772,666,38,327,309,595,171,149,183,363,671,532,586,895,711,344,99,314,268,779,299,195,996,311,738,109,938,95,344,545,977,244,399,318,622,581,623,372,568,798,197,656,529,633,38,788,329,14,750,740,334,649,45,687,141,530,558,944,984,930,419,902,314,464,603,26,328,864,974,350,457,615,852,857,167,203,799,626,843,281,447,758,483,547,895,753,750,599,424,586,578,685,723,508,700,934,666,234,249,704,813,699,343,165,475,77,879,943,49,440,396,728,724,125,714,984,552,269,345,508,25,143,805,991,330,387,410,206,654,494,525,279,786,386,627,847,522,422,409,226,194,402,829,86,92,621,100,928,431,640,760,939,138,751,221,743,58,176,176,706,817,22,485,932,455,14,69,432,656,739,458,171,922,733,405,881,164,149,389,603,479,118,166,719,53,614,352,764,588,132,586,839,634,677,305,778,284,323,0,186,468,469,320,469,905,327,658,5,9,863,197,334,540,771,21,765,551,65,694,458,77,428,824,850,951,693,690,531,365,142,830,144,566,22,331,881,538,669,215,304,203,648,908,776,286,758,901,182,254,585,382,331,77,435,77,519,427,710,602,801,97,642,79,934,23,533,761,968,740,307,123,725,878,181,62,221,59,126,308,330,566,525,10,403,326,346,227,187,265,665,550,984,414,936,668,571,569,170,343,707,109,960,68,323,352,324,948,875,261,307,628,717,346,928,965,514,921,635,925,278,996,553,807,850,353,15,259,638,890,565,280,386,361,764,153,750,445,749,43,278,428,697,461,534,714,851,929,448,57,248,29,473,496,369,889,934,449,338,986,884,42,522", "626,356,689,279,725,730,485,975,915,981,798,473,356,435,30,174,292,616,648,886,440,717,662,961,476,512,27,146,722,378,422,631,445,699,43,2,295,784,445,315,869,536,784,988,140,29,414,355,816,409,873,96,798,853,361,192,31,373,295,234,15,23,637,667,555,794,789,394,325,610,139,412,36,402,620,601,318,928,107,317,463,335,548,291,593,25,114,943,623,35,706,954,332,235,576,837,910,175,660,398,881,767,255,888,889,878,869,744,752,636,922,319,42,441,880,161,137,613,141,746,985,889,289,557,111,614,415,193,916,361,761,770,508,803,270,630,165,267,229,871,656,910,491,992,643,472,195,219,549,367,530,998,444,959,954,688,893,663,42,84,62,74,871,813,769,306,550,591,715,28,519,177,753,262,264,296,247,491,50,681,482,685,150,6,319,94,634,94,32,490,526,33,671,927,82,787,507,572,740,427,731,559,527,131,665,171,727,200,978,485,972,949,942,199,413,948,41,256,780,672,72,845,54,168,107,468,987,787,460,841,153,319,981,937,575,257,527,187,320,738,546,538,566,122,174,279,733,700,210,169,129,585,288,33,782,853,348,988,238,348,22,238,24,525,24,454,518,95,26,328,350,638,587,440,677,454,180,252,491,134,771,623,302,69,510,829,292,334,107,804,749,13,694,991,480,847,217,549,199,365,400,993,45,727,492,931,790,501,500,41,732,397,78,991,379,215,63,989,873,433,589,820,45,558,170,702,298,189,453,801,509,722,817,941,457,19,534,734,144,233,479,205,853,858,141,49,556,316,477,658,123,408,183,613,199,146,554,577,448,441,829,753,814,748,243,62,866,10,480,152,648,876,272,979,205,856,75,679,66,100,60,408,119,591,217,827,779,759,548,661,18,276,587,240,253,887,120,679,225,201,577,120,13,604,518,106,341,424,351,805,745,98,303,888,884,873,391,671,873,703,189,264,28,758,367,25,180,586,186,731,649,702,56,230,594,211,752,361,259,693,659,449,647,239,867,952,149,364,478,936,865,805,710,527,240,756,766,335,18,28,288,149,10,957,641,466,783,847,650,201,422,420,465,579,712,230,61,751,519,555,123,373,517,342,351,576,746,842,137,155,232,570,481,645,265,657,452,922,712,176,357,918,706,743,577,704,131,421,438,117,382,522,913,71,930,993,818,742,516,748,660,609,596,272,387,626,843,579,33,232,714,694,543,954,137,318,19,200,643,963,292,565,625,839,987,162,326,753,145,825,366,331,190,884,597,40,538,526,191,310,530,852,439,485,655,876,766,992,662,153,829,562,446,862,728,499,490,515,589,325,335,41,590,376,580,871,827,45,813,432,771,371,74,667,462,246,957,249,431,21,992,346,418,618,879,981,274,560,963,515,474,676,32,8,736,19,584,811,511,615,209,993,947,362,549,984,895,97,748,477,702,150,587,901,707,189,619,333,493,524,538,489,485,349,34,316,83,715,646,13,964,686,521,599,215,598,399,167,487,948,804,760,438,746,632,131,614,114,257,22,24,723,926,904,272,940,297,730,342,78,728,427,21,589,464,859,977,571,506,127,212,456,981,131,624,864,257,460,63,456,737,683,121,612,318,346,336,323,428,462,231,270,10,608,331,214,895,735,327,754,909,485,456,970,539,372,729,324,265,941,354,364,890,948,392,797,255,926,587,668,621,66,599,829,199,395,750,536,515,510,770,993,719,820,363,263,202,960,420,368,26,77,497,619,574,169,940,750,886,491,772,428,420,635,894,72,775,522,501,946,588,651,138,97,927,70,581,647,999,921,318,915,989,710,381,496,364,983,638,211,526,326,982,963,541,117,858,599,88,370,136,895,248,602,622,771,152,216,576,185,157,517,109,505,34,139,178,450,617,224,567,94,732,621,380,768,186,0,268,557,819,585,485,195,873,856,546,315,504,614,984,650,562,421,249,395,727,400,209,901,310,702,433,387,306,575,214,382,470,958,520,101,379,135,776,881,432,125,175,37,263,922,773,81,583,953,266,918,698,328,675,417,410,784,426,245,467,844,371,691,92,454,309,324,343,728,472,731,882,123,782,779,918,568,51,646,508,297,402,673,301,477,395,14,121,701,663,970,208,153,72,19,274,741,778,68,275,284,419,676,862,741,790,129,9,921,762,597,244,554,447,767,209,273,465,683,723,605,965,646,105,608,140,218,528,347,263,579,369,226,386,662,984,29,772,112,679,100,402,203,755,264,580,115,944,859,124,971,741,264,319,272,284,429,416,712,657,518,481,513", "223,855,387,443,871,412,621,320,236,545,510,56,718,620,908,795,888,794,475,834,720,867,255,739,574,156,779,16,270,330,486,995,220,512,690,937,273,830,445,583,776,320,309,897,499,191,544,879,667,591,363,986,660,565,81,497,130,498,210,987,59,88,295,910,887,527,472,31,308,675,250,288,866,355,215,240,463,371,862,886,978,88,251,491,965,280,810,546,749,637,460,126,902,17,863,973,935,251,860,736,394,358,214,836,901,820,630,287,873,961,376,470,18,139,360,258,367,499,360,48,638,242,181,231,742,246,167,729,194,459,907,188,336,224,411,499,279,94,147,279,315,198,892,861,867,333,167,831,504,967,523,757,882,56,163,755,512,827,290,382,365,197,237,348,111,837,387,481,600,333,127,998,378,165,808,538,67,357,943,542,191,515,139,553,930,385,695,871,67,444,675,424,94,115,397,264,297,579,486,199,295,883,396,951,679,696,438,638,355,155,24,554,770,733,296,331,803,76,754,273,616,239,894,867,565,84,92,525,170,223,430,6,246,537,634,373,702,719,349,71,461,394,571,428,207,591,833,484,674,398,262,212,855,357,964,823,674,605,875,866,999,577,328,278,5,565,51,788,204,535,245,433,870,829,925,680,763,725,639,770,516,663,230,328,427,595,206,711,668,593,455,651,796,125,623,118,378,97,325,670,318,225,955,694,426,535,325,919,126,126,468,671,733,811,767,32,549,534,216,310,579,149,840,510,599,760,291,150,11,8,747,619,34,90,654,437,660,360,418,913,793,478,204,564,543,575,39,934,992,804,356,873,251,970,52,849,237,198,880,333,212,647,48,312,315,908,729,142,676,753,722,466,278,838,238,869,905,454,843,245,36,832,805,578,531,469,635,521,53,618,609,525,221,619,523,516,314,775,748,623,663,581,833,757,60,23,801,562,438,179,72,145,997,879,194,222,190,995,86,890,566,841,861,24,214,452,26,684,70,691,204,293,887,431,658,568,224,147,248,59,665,243,52,260,32,436,705,169,439,751,315,765,290,703,39,899,103,830,546,965,748,644,392,71,234,682,954,716,751,361,989,315,556,795,403,865,75,451,606,831,933,186,497,8,382,696,578,707,632,729,824,223,585,203,399,499,953,258,182,836,447,507,317,902,619,666,486,791,930,664,193,79,928,776,980,403,904,666,767,165,128,574,755,590,964,846,822,276,982,885,187,952,223,790,798,421,483,519,511,885,600,386,696,233,115,396,687,458,344,624,221,677,893,239,103,968,113,837,815,931,913,571,298,3,235,701,362,707,275,422,416,434,784,289,507,238,911,172,301,14,678,585,389,928,441,999,564,647,598,701,258,962,314,191,39,952,106,531,972,388,678,415,909,395,705,295,288,738,602,501,119,550,773,57,613,37,608,381,444,213,821,350,62,151,558,848,831,51,302,863,784,274,217,180,561,442,392,506,946,27,439,420,953,562,453,451,124,520,904,721,75,192,467,214,222,543,853,781,706,627,657,998,40,791,602,90,815,962,502,955,639,420,229,147,725,352,299,745,117,726,546,230,949,571,777,123,570,303,347,354,336,441,867,872,727,521,425,16,502,656,350,582,921,855,553,321,195,484,659,436,369,231,32,655,52,184,754,420,704,351,821,228,625,103,566,851,715,481,890,186,220,526,401,131,435,165,803,884,48,374,983,161,826,1000,480,464,443,492,543,520,48,377,658,883,809,773,339,479,604,398,823,538,794,376,7,724,430,650,662,113,78,17,21,381,911,399,259,786,293,698,887,802,386,295,297,577,903,555,402,355,618,491,805,355,752,684,664,40,521,972,554,150,864,387,843,306,822,134,371,369,324,919,772,166,485,159,366,488,446,855,991,909,526,207,919,504,379,850,153,860,738,870,540,543,721,674,468,268,0,228,72,639,222,762,684,100,69,581,989,319,599,419,153,185,268,23,442,37,323,474,439,226,586,40,88,209,72,964,944,448,331,450,553,968,83,854,267,206,871,104,750,693,896,532,343,441,427,378,674,49,406,132,577,368,316,713,465,501,403,761,585,380,363,761,645,941,816,998,137,75,371,228,717,378,960,101,201,481,610,51,386,607,679,938,751,658,177,272,889,91,9,127,186,470,460,227,835,442,251,960,952,409,462,701,291,816,140,516,991,806,637,563,706,906,524,748,642,774,831,604,149,250,740,577,227,588,866,449,273,923,845,607,595,319,384,644,461,16,220,999,402,90,563,241,119,885,734,261,432,458,503,147,121,956,4,614,773,892,156,297", "290,794,944,445,507,269,217,42,970,875,469,306,444,841,898,326,941,320,769,388,765,387,532,809,354,799,411,372,784,440,708,901,428,542,871,131,344,323,501,245,92,669,403,764,972,553,558,286,305,773,20,207,322,413,686,90,783,798,324,896,336,277,236,147,188,591,340,762,146,960,150,183,552,803,585,301,475,765,56,452,140,907,154,911,865,490,250,35,299,994,79,716,241,308,75,892,319,941,982,872,542,3,743,531,112,667,7,852,780,610,460,688,686,170,212,765,676,697,194,979,989,726,352,766,309,959,412,365,919,946,404,498,775,916,380,352,476,515,192,182,998,939,72,736,252,446,398,785,672,588,22,342,842,735,667,906,731,755,558,809,10,346,441,710,724,824,427,170,324,242,72,105,557,613,962,938,640,472,570,464,553,432,957,454,953,594,783,742,689,362,916,502,490,910,941,877,455,244,87,205,784,894,732,342,329,97,465,427,424,910,62,526,972,856,167,249,509,466,562,558,389,734,522,289,995,263,419,150,730,736,477,299,152,238,979,745,410,649,638,892,977,974,130,62,219,594,47,18,818,490,524,958,355,56,166,311,482,340,921,820,712,254,178,394,276,2,121,290,413,373,198,663,276,466,904,807,690,678,48,600,700,784,450,135,374,774,947,375,327,823,247,318,342,139,411,295,758,727,232,729,299,325,312,644,823,570,516,180,612,355,866,613,456,835,727,268,37,493,81,187,369,88,297,975,20,641,221,742,778,37,399,187,481,870,938,418,16,179,712,733,386,846,674,667,209,995,262,399,653,12,4,216,116,145,504,758,838,569,22,596,555,889,646,751,231,718,513,579,841,489,951,995,642,210,398,125,377,291,774,677,691,814,872,771,801,628,95,707,402,384,309,866,947,223,697,29,507,374,13,867,652,353,141,204,370,8,756,994,163,896,497,362,961,113,883,778,631,562,630,991,144,224,903,855,34,902,721,176,712,95,551,775,769,185,256,423,650,529,5,236,223,398,853,508,93,138,97,171,188,896,48,659,714,518,272,199,730,902,371,253,565,322,803,847,37,516,590,833,997,811,38,636,916,153,93,632,924,922,588,144,806,721,823,218,639,113,77,334,260,1,796,163,247,950,746,547,932,264,656,605,592,350,539,10,454,823,580,759,248,408,926,540,395,111,941,895,949,496,562,936,898,696,518,729,570,457,102,596,637,933,713,388,43,253,861,250,461,144,538,57,436,826,29,979,717,372,537,890,192,688,872,652,666,236,982,594,472,178,16,551,343,933,772,506,190,281,125,85,29,204,211,108,29,298,670,400,882,15,849,892,95,94,502,530,664,752,36,329,82,393,705,947,125,730,384,349,462,862,165,76,1000,77,189,127,681,318,353,293,370,618,386,777,18,674,107,358,188,147,49,621,771,763,482,691,788,927,569,337,553,684,763,148,43,297,459,383,947,129,649,788,634,63,809,244,588,923,220,828,200,808,731,776,990,932,340,600,902,435,14,55,989,726,332,772,120,843,657,220,604,165,687,272,395,203,90,282,846,208,451,883,914,733,359,394,295,133,55,567,564,16,925,244,908,805,372,856,955,229,394,699,12,244,103,488,837,359,669,521,750,432,220,942,529,118,698,939,657,810,303,224,231,38,283,559,812,792,263,679,306,888,988,498,500,878,247,293,122,408,287,810,748,746,405,743,55,903,273,176,406,965,402,420,869,300,342,258,185,345,281,586,101,588,555,888,972,174,602,162,400,969,689,909,679,992,73,633,424,476,321,44,231,561,119,768,286,103,326,326,953,690,294,226,744,845,499,549,656,901,313,7,9,34,97,604,63,712,851,794,57,686,762,844,855,588,827,538,474,354,875,703,409,996,960,62,627,727,591,503,277,1000,182,131,722,113,344,730,469,557,228,0,739,500,496,87,475,295,824,133,285,616,226,518,727,78,304,404,234,259,885,740,112,273,937,924,211,76,910,731,73,352,726,770,127,952,362,729,952,11,750,673,306,178,51,169,263,304,939,55,988,728,572,379,386,837,639,728,901,146,645,241,708,321,473,611,453,866,452,574,239,791,819,838,507,180,982,190,725,874,33,943,27,867,655,820,535,642,257,931,501,382,960,94,21,464,865,370,91,380,467,954,132,434,776,477,916,417,135,375,725,413,383,696,338,524,350,205,636,174,557,14,387,512,838,815,887,807,618,793,104,426,782,433,319,295,368,430,712,523,81,910,536,31,280,51,51,761,991,945,676,412,967,384,747,55,129,515,627,56,274,255", "722,830,336,189,777,81,825,761,350,941,926,981,102,921,504,536,386,70,569,224,594,102,407,154,615,1,350,508,693,760,838,267,159,190,707,544,921,929,681,925,859,141,439,404,297,423,381,605,864,601,571,391,89,931,310,622,66,804,114,546,663,802,546,410,623,115,105,917,502,242,994,47,636,468,90,655,689,572,919,228,966,948,560,389,970,845,632,283,159,635,429,311,436,782,496,514,357,588,820,238,456,923,429,662,761,422,279,710,579,232,872,444,711,696,475,494,92,989,275,553,63,323,135,469,601,952,151,651,329,963,968,924,936,597,51,904,801,785,748,571,946,727,563,698,921,237,115,264,387,966,821,199,888,55,245,138,432,899,350,715,554,263,235,841,55,471,238,801,351,145,804,424,592,201,38,357,272,208,55,459,210,907,365,33,571,728,506,39,889,963,14,838,980,974,728,476,217,695,972,598,77,289,143,832,545,69,970,943,711,172,104,232,835,795,145,997,520,533,15,17,601,576,259,365,258,222,825,676,260,933,994,784,538,164,643,703,523,855,333,972,773,355,687,53,973,498,878,796,677,255,32,545,566,75,359,786,182,679,511,679,604,908,932,238,747,787,779,108,825,158,602,48,189,650,613,796,876,142,657,91,496,993,907,186,546,888,904,202,536,155,490,174,647,904,764,844,446,239,278,438,729,955,335,340,895,11,603,419,643,226,791,671,816,687,208,571,286,591,337,418,795,968,479,631,409,654,101,932,467,29,260,562,571,500,268,753,156,216,727,564,928,698,149,272,336,137,505,591,826,898,68,648,404,868,973,897,806,623,312,1,469,161,817,698,330,924,632,510,317,809,533,455,908,331,867,579,449,817,495,758,183,459,813,556,329,369,697,435,374,357,16,859,856,188,918,629,170,364,807,534,707,112,456,195,123,717,387,744,809,669,195,391,995,161,356,140,130,505,287,187,349,872,135,770,508,446,119,469,116,883,779,212,918,791,474,802,555,303,176,2,910,410,610,620,557,933,234,602,436,803,50,969,506,391,275,711,403,993,270,947,609,190,779,372,138,367,407,593,411,986,926,346,642,112,49,167,334,191,11,343,365,247,353,396,133,350,167,813,471,292,960,695,878,383,868,107,62,100,739,666,376,520,519,432,302,645,906,897,970,819,749,528,668,350,834,774,518,945,332,542,928,374,517,154,103,262,943,303,181,573,353,590,725,626,739,272,417,152,927,63,685,848,278,837,508,430,485,48,785,563,536,624,487,859,942,32,314,602,192,955,852,444,83,770,99,615,841,44,298,547,109,910,145,309,18,602,380,180,602,406,257,297,721,350,880,705,269,367,26,348,997,501,531,30,203,726,513,207,106,518,380,626,262,489,119,11,537,762,566,302,502,667,168,363,103,964,799,229,309,924,328,918,351,217,752,650,7,214,423,240,415,826,304,490,345,586,840,382,467,374,569,720,51,497,298,425,429,709,831,429,573,362,453,477,571,757,881,129,808,235,301,882,405,924,640,176,925,645,106,877,411,61,368,123,41,425,275,511,562,938,26,132,945,882,355,361,732,786,599,980,97,822,876,847,299,636,11,287,68,943,854,562,266,634,629,6,7,928,62,985,231,748,983,172,432,405,416,854,630,210,190,678,113,174,748,24,815,532,18,288,899,298,236,397,947,203,637,383,354,784,70,115,907,722,922,531,351,242,423,634,967,785,691,374,936,614,446,52,938,634,447,69,11,933,215,689,192,599,302,569,545,775,575,973,627,118,151,974,694,451,809,167,329,110,645,44,834,932,176,840,68,809,4,401,829,852,196,862,498,973,793,513,518,743,791,964,474,96,239,159,672,453,995,885,159,322,154,496,535,451,863,461,191,828,310,888,251,469,284,553,305,138,780,527,730,174,320,819,72,739,0,32,912,32,789,188,953,775,696,510,637,770,856,487,327,328,917,873,774,294,464,326,14,762,304,129,215,76,961,779,585,514,720,955,937,738,975,459,796,922,137,7,905,11,38,427,466,748,77,977,84,480,579,837,103,113,525,349,567,639,755,255,206,643,835,16,508,234,541,381,13,473,213,379,382,26,263,919,898,590,100,408,346,287,538,329,688,293,686,302,571,271,672,450,31,578,901,607,568,271,562,112,509,330,606,988,711,82,442,376,775,199,116,366,792,5,150,700,303,745,344,360,793,402,751,161,715,81,249,390,164,827,831,35,786,722,955,653,570,179,813,494,782,928,374,443,672,703,24,33,748,691,592,293,600,191,916,166,768,467", "178,721,262,148,462,203,76,595,420,959,77,500,396,297,931,748,506,316,953,923,47,148,366,107,492,1,603,878,50,931,43,734,781,666,462,34,818,35,922,549,461,986,986,743,922,285,286,791,851,918,281,712,214,710,585,458,248,21,562,733,515,417,109,165,433,420,943,918,253,391,403,30,372,299,729,257,411,17,474,568,694,490,185,707,747,488,593,588,320,612,724,308,172,237,432,114,301,392,994,25,544,790,816,923,339,102,18,905,607,374,585,15,29,460,664,430,353,158,523,798,161,296,302,668,120,670,726,220,877,503,382,53,99,884,911,186,324,61,845,228,319,203,820,592,824,715,142,71,762,4,487,308,955,867,396,470,975,372,322,781,738,416,38,454,288,95,54,392,448,662,13,471,124,186,273,541,2,104,737,854,19,740,251,941,755,660,163,744,139,909,316,334,964,611,118,606,819,518,720,861,907,617,109,814,567,419,273,872,898,704,701,1000,955,410,49,794,280,881,17,469,515,145,206,333,427,302,267,332,987,633,667,684,766,830,480,678,465,311,914,944,974,166,895,702,780,974,559,452,997,918,428,544,785,840,822,224,217,241,55,367,789,475,348,812,578,435,176,231,397,797,774,159,581,676,996,975,707,6,339,44,500,666,971,679,661,489,902,280,930,709,905,607,693,791,61,555,303,272,595,275,136,473,506,136,841,289,652,764,425,493,164,177,853,745,99,447,173,372,468,597,541,980,62,394,826,55,12,915,485,121,60,200,856,688,691,524,154,837,844,379,708,147,501,71,326,670,244,331,960,384,315,405,838,939,727,609,276,531,422,896,24,684,913,380,87,289,649,838,480,214,446,447,734,355,240,664,600,228,345,838,420,52,998,2,409,501,311,92,810,311,657,275,639,138,678,953,302,608,747,162,332,242,882,730,731,362,836,477,24,961,859,534,171,206,405,218,343,221,70,878,313,210,874,770,538,452,496,21,116,955,519,953,604,992,209,334,604,430,659,273,546,570,547,845,314,515,117,505,901,395,161,44,277,752,325,304,850,469,690,986,584,207,244,460,993,858,104,262,342,809,132,689,471,816,922,114,456,175,112,338,569,809,686,26,165,670,864,67,407,846,746,307,900,573,766,229,290,658,647,819,993,778,177,550,233,158,881,972,672,229,488,692,434,997,286,449,873,137,264,629,600,214,722,593,785,651,646,221,549,855,94,840,629,909,95,547,598,722,699,44,827,727,257,130,755,146,507,925,70,590,338,86,62,430,493,191,610,471,226,744,578,406,336,359,659,564,318,126,191,529,714,201,352,12,964,388,915,878,749,170,800,79,470,729,374,483,18,48,878,430,946,256,93,298,33,452,698,511,790,983,14,406,858,107,143,783,726,91,492,17,256,391,801,792,523,797,500,474,313,271,607,665,386,436,5,177,703,431,257,206,221,2,971,127,987,935,176,504,216,446,254,990,667,239,66,10,441,181,625,874,225,257,489,276,384,279,530,164,309,162,371,370,620,861,986,434,499,365,232,209,793,921,154,829,546,66,856,663,485,688,622,10,313,164,285,871,922,651,298,676,926,961,445,889,298,966,88,861,461,128,800,772,20,427,335,924,224,203,802,686,182,375,215,945,187,254,506,672,353,798,572,125,317,536,945,322,618,885,247,658,588,307,610,442,200,936,429,686,318,249,926,623,231,79,18,838,603,645,701,372,117,443,827,729,331,15,194,682,66,868,261,235,169,238,671,431,610,198,187,932,452,414,421,853,984,352,569,999,220,350,137,60,361,559,490,860,690,943,942,876,875,453,633,354,301,164,387,576,85,512,949,752,277,386,624,179,710,374,695,866,788,370,746,997,212,41,367,996,211,372,741,538,325,5,185,997,715,840,829,895,865,831,724,452,214,480,469,585,639,500,32,0,784,517,1,157,860,544,41,289,189,32,45,205,4,198,23,974,302,998,951,860,190,82,493,852,995,941,796,50,503,456,588,106,885,767,780,17,564,201,639,931,224,616,51,58,598,240,299,214,743,702,255,637,898,742,651,33,287,68,731,38,745,379,965,254,807,435,126,302,452,867,441,376,777,808,761,988,908,780,33,169,884,35,856,457,76,218,595,106,6,1000,396,413,10,273,607,470,900,943,728,472,74,77,144,736,590,846,530,816,887,166,106,417,505,790,856,382,344,214,775,657,598,931,95,219,534,369,25,222,701,253,181,639,188,51,227,907,999,745,58,951,349,622,771,45,64,748,874,636,954,289,588,106,270,84,186,328,318,89", "39,988,156,665,209,201,898,12,309,367,100,394,154,155,648,925,782,941,947,763,65,638,580,490,987,131,895,427,607,75,66,44,930,878,521,304,935,112,117,294,870,947,643,75,415,461,977,404,244,39,705,576,538,713,897,595,891,360,472,236,736,269,240,116,851,860,855,760,53,421,984,561,258,494,766,342,765,49,754,362,348,310,820,312,185,567,658,14,52,836,940,306,93,300,37,804,878,407,914,3,28,242,719,759,497,668,84,194,297,341,359,754,931,570,461,204,398,949,75,183,965,346,674,265,379,501,601,6,652,985,461,997,537,46,943,672,955,443,481,600,50,43,22,633,638,625,93,229,353,716,295,980,222,196,742,219,892,209,585,921,816,106,787,430,253,155,455,492,477,576,486,835,542,284,819,29,427,445,958,863,3,870,341,751,69,737,501,947,474,455,55,507,88,354,546,139,929,478,940,837,369,643,674,763,413,520,174,125,224,222,320,520,171,936,880,760,570,637,763,62,185,887,320,459,594,124,577,885,336,140,348,770,906,758,44,845,728,695,482,351,586,394,127,953,542,310,165,839,662,671,68,640,766,569,159,932,965,929,191,388,242,285,11,572,734,455,145,528,118,296,402,14,249,867,109,1,979,335,346,774,123,374,166,699,714,906,428,31,887,138,980,925,835,300,18,977,629,619,268,233,414,417,682,420,891,127,293,951,950,734,259,3,783,636,7,626,111,550,528,788,719,412,305,322,543,112,202,236,295,286,228,519,578,310,974,722,34,271,634,270,242,923,575,157,205,868,430,937,462,645,525,460,807,924,547,975,987,425,210,308,209,778,406,610,169,252,862,89,15,483,474,184,126,171,654,689,188,109,170,248,807,112,187,98,813,192,658,539,961,476,607,97,440,158,94,988,41,380,228,73,146,611,296,785,30,248,242,239,193,400,818,224,739,297,254,126,579,845,353,714,521,16,746,934,675,938,842,611,894,128,700,969,137,116,478,330,164,189,873,211,939,209,711,120,665,446,790,945,515,694,475,588,784,778,405,380,760,139,127,547,874,746,613,114,756,934,26,571,601,139,37,940,448,797,295,322,39,692,264,325,698,956,744,324,135,333,821,97,258,734,895,615,160,582,841,193,638,260,578,853,504,684,402,192,324,362,377,898,829,560,951,160,131,129,295,783,584,177,420,913,669,42,31,501,726,355,588,149,224,466,326,638,885,527,266,739,101,193,843,877,128,588,651,709,459,788,169,240,632,436,20,725,237,677,734,957,562,32,190,420,497,553,320,986,896,811,529,344,941,695,153,966,727,39,830,585,353,649,184,429,313,412,58,766,422,370,18,544,861,491,232,498,895,358,93,863,888,608,914,134,901,818,228,762,566,623,639,452,97,459,568,188,781,46,959,698,66,960,854,887,320,728,40,782,342,965,884,205,901,897,796,768,340,29,624,636,261,764,500,564,106,383,614,690,616,980,889,462,922,566,51,913,273,995,881,754,109,267,367,346,403,385,672,663,919,198,290,818,438,38,946,497,179,643,18,807,954,759,768,150,163,797,138,573,954,262,643,125,242,27,800,180,93,588,976,920,49,596,282,87,979,558,768,42,825,995,164,168,858,150,887,312,500,961,564,336,172,450,202,577,843,167,691,273,210,105,904,400,484,878,768,402,807,915,312,575,197,220,71,731,484,20,659,475,24,8,904,619,919,144,500,338,752,893,834,126,737,490,729,703,91,575,984,874,901,299,604,120,787,94,813,651,799,834,820,429,154,88,789,763,82,626,963,966,442,152,627,846,391,932,516,904,627,439,212,222,748,499,731,119,407,738,731,872,624,591,276,858,735,24,752,932,361,698,204,370,263,234,695,210,190,346,995,179,97,635,928,265,203,107,280,989,691,327,990,974,905,485,222,496,912,784,0,798,32,583,563,735,409,755,180,11,25,656,367,399,84,877,725,351,998,225,193,955,713,191,287,58,129,468,131,340,710,56,330,699,588,234,237,349,935,710,29,272,999,221,970,859,205,494,979,989,920,180,258,641,872,176,253,69,3,887,342,335,232,308,859,205,306,935,786,841,142,292,711,48,914,913,575,380,526,254,127,225,91,164,869,603,496,644,69,450,849,325,956,683,321,201,853,56,295,621,995,501,80,147,796,129,995,723,548,691,102,53,307,352,822,107,661,36,945,543,43,262,740,87,19,722,455,420,225,2,253,47,864,836,190,639,499,361,605,580,70,425,458,409,488,235,851,846,558,387,894,566,846,380,941,166,432,768", "873,887,978,866,996,59,172,256,790,842,214,805,855,590,19,835,206,875,916,152,469,454,724,815,667,725,811,758,34,584,287,173,895,988,490,318,689,992,99,765,105,587,854,531,392,937,671,906,592,757,952,887,336,800,663,230,858,561,920,374,407,121,545,245,323,536,252,405,970,801,596,782,580,817,902,756,473,186,868,870,409,685,51,97,620,172,209,777,533,664,634,592,568,219,739,576,410,305,950,569,719,987,421,746,7,218,696,123,925,592,543,730,583,18,734,276,344,420,964,946,816,666,566,818,57,721,425,487,133,429,498,727,335,327,437,889,669,445,795,953,368,620,37,238,245,267,358,860,413,496,236,482,872,229,288,877,461,419,416,661,466,965,359,412,860,397,309,48,67,887,790,898,508,857,839,623,956,400,907,372,524,87,619,385,56,412,584,713,487,797,517,755,58,541,975,44,767,654,567,560,845,400,417,453,170,542,406,296,254,667,645,801,517,717,635,8,914,633,457,259,651,41,963,235,818,261,755,710,346,476,679,776,428,586,165,74,99,357,784,513,288,520,266,780,818,379,211,747,540,672,920,359,127,162,932,147,67,511,385,256,936,546,232,730,884,752,512,759,671,783,672,994,272,486,518,735,473,647,914,664,856,449,233,788,287,304,132,807,195,795,627,586,514,511,419,432,184,609,111,920,180,543,990,459,491,846,930,162,971,255,810,313,273,506,2,856,73,950,987,350,524,854,891,138,154,897,21,618,65,603,204,44,390,525,215,932,411,355,402,217,448,426,589,102,527,112,755,627,206,558,833,665,748,71,481,6,911,12,902,973,87,285,925,966,996,970,60,954,368,120,962,301,235,454,344,942,693,284,546,236,294,887,918,254,161,749,853,264,660,821,83,425,551,562,180,886,567,381,357,700,430,621,434,701,888,960,945,329,213,939,143,807,239,264,845,938,464,652,106,581,666,561,396,418,383,251,660,9,450,264,370,569,118,37,417,395,362,480,8,984,333,298,491,399,611,252,52,173,683,17,80,753,708,382,696,62,776,189,955,378,559,738,807,46,1000,802,787,129,168,406,584,865,589,352,672,791,507,45,989,581,963,842,897,928,923,805,584,411,543,300,599,448,32,368,81,527,530,252,574,590,120,577,630,790,569,440,93,612,986,144,422,384,959,73,928,387,811,211,544,842,144,407,446,477,792,681,788,332,2,325,604,912,376,418,726,885,210,528,627,174,259,707,445,474,514,37,904,410,514,260,676,78,46,25,640,570,592,858,688,458,12,38,417,503,431,104,37,58,876,800,357,690,662,114,675,452,474,669,212,942,27,714,458,733,427,105,896,682,137,142,221,49,279,457,514,566,3,837,783,426,286,725,164,55,474,173,647,212,615,596,195,108,550,799,728,743,170,743,933,143,985,688,176,990,951,821,863,514,660,797,292,885,616,837,894,104,147,674,918,815,115,741,240,251,463,58,611,597,200,177,144,986,522,329,950,112,800,780,238,709,212,167,774,864,294,286,36,711,870,901,84,532,281,983,608,713,152,515,477,18,139,549,821,18,743,80,598,774,588,31,301,51,929,684,387,876,913,414,646,571,242,561,917,515,282,762,216,627,649,627,837,934,326,146,107,860,977,838,458,75,884,62,93,873,171,693,515,247,852,927,877,521,619,561,848,726,151,853,59,700,658,628,243,600,739,735,396,659,245,797,62,120,873,246,468,811,173,99,506,40,502,70,852,504,679,176,619,658,427,874,798,968,523,561,906,997,883,453,115,744,660,690,273,860,294,734,46,153,457,309,533,817,666,217,527,963,364,759,447,151,803,516,433,92,728,343,45,107,212,948,363,897,712,921,729,621,530,349,448,697,276,802,383,914,843,143,633,499,383,451,789,552,938,13,479,259,327,195,762,87,32,517,798,0,54,514,215,26,481,848,317,929,399,835,603,238,901,865,169,894,229,52,683,967,115,443,90,812,793,433,668,896,69,956,833,950,849,493,919,347,311,224,694,587,527,341,325,249,106,924,916,693,50,989,872,532,11,684,351,989,862,102,916,966,585,63,949,876,941,44,148,596,823,866,746,701,306,174,10,382,989,378,953,744,954,663,424,667,466,397,76,440,449,889,204,250,70,843,111,415,75,675,433,469,899,735,97,532,336,177,396,440,418,850,868,423,847,299,312,2,528,722,485,814,696,331,881,758,453,112,445,256,623,100,295,584,544,374,765,266,68,209,222,554,357,796,832,351,91,879,687,578,154,729,194,983,77,438,462,331", "601,318,879,855,989,764,816,972,497,474,518,824,947,925,194,61,208,304,659,854,69,968,166,509,385,697,894,932,757,806,84,962,176,138,474,873,419,527,648,884,143,886,944,951,355,404,754,297,982,521,260,673,252,975,706,293,379,883,227,873,964,743,205,297,310,651,478,42,87,744,866,546,247,295,456,136,21,21,343,477,284,820,486,143,978,745,490,144,956,750,344,640,733,917,79,84,797,692,163,74,84,571,680,254,551,516,124,999,145,685,414,72,725,4,236,752,360,347,852,545,411,327,787,51,883,652,252,63,612,19,780,561,100,973,132,32,613,884,486,115,894,91,234,216,942,165,162,469,499,27,792,247,526,466,347,964,828,612,810,241,82,711,477,412,147,664,689,674,103,121,947,303,100,976,644,299,522,169,381,827,728,16,804,202,249,919,831,869,178,846,979,143,228,660,378,881,818,171,498,686,880,663,641,405,455,241,599,355,88,862,414,972,243,410,400,84,335,366,346,742,494,3,971,618,215,754,669,613,293,10,491,535,666,78,260,625,604,562,848,588,176,316,439,726,531,859,151,152,108,936,589,655,714,612,474,409,668,785,751,546,355,513,408,620,840,493,377,256,367,920,329,40,31,847,358,875,179,820,389,509,584,999,829,820,392,312,303,489,4,437,329,275,338,279,390,292,929,516,329,901,175,790,328,189,608,604,469,961,743,944,968,155,878,714,706,234,446,419,90,612,777,727,884,386,151,226,981,134,452,748,94,587,671,219,242,444,768,450,45,969,826,423,311,846,797,90,855,945,403,977,62,789,964,981,552,210,660,128,877,974,737,679,623,869,830,983,94,38,737,959,52,937,162,42,76,374,678,539,317,408,24,460,680,95,729,441,899,892,664,720,95,155,329,683,9,314,127,650,821,473,597,327,542,985,111,278,921,762,628,780,741,641,207,365,141,480,541,379,341,581,109,780,420,107,692,70,34,923,838,380,612,203,50,759,494,816,659,887,120,151,201,21,729,360,891,833,986,883,574,753,160,417,861,455,443,932,523,448,310,786,497,577,300,368,710,154,411,762,886,535,696,38,757,521,490,785,575,485,891,310,899,304,201,678,378,236,629,238,321,957,534,379,722,64,69,215,847,482,669,475,332,172,450,612,140,440,617,926,866,335,833,475,761,194,174,769,385,120,249,734,102,141,999,650,62,948,476,425,462,515,373,969,475,101,535,155,12,548,269,453,891,267,913,832,61,856,951,671,69,433,162,100,169,490,478,359,468,467,548,91,788,185,969,273,203,904,662,762,471,510,32,252,245,683,555,532,184,90,26,434,302,469,971,792,41,734,277,360,214,855,10,898,563,889,928,366,555,110,72,842,103,174,994,358,436,935,1000,938,493,410,256,90,588,803,242,984,774,418,488,883,418,488,301,212,234,58,847,674,383,880,61,870,475,298,190,573,88,197,835,981,244,488,588,358,182,641,726,832,848,102,983,830,85,763,903,637,662,772,707,431,146,990,875,400,407,780,372,835,682,411,662,764,218,33,547,601,75,955,684,598,597,383,552,900,986,629,312,915,660,418,681,592,56,790,973,740,813,823,491,412,406,871,650,209,633,571,357,223,157,717,598,160,236,48,618,119,853,154,575,210,613,503,832,437,243,500,32,214,308,803,574,910,577,878,695,556,907,104,306,857,161,52,722,647,545,314,567,437,589,852,713,787,850,945,307,349,121,583,691,363,310,131,255,368,513,178,683,467,169,390,414,440,828,317,399,799,16,603,633,126,282,349,121,985,399,445,518,44,832,216,915,997,962,715,228,709,475,892,169,824,18,391,703,201,793,931,921,391,897,5,790,99,450,438,395,394,378,353,615,320,327,184,99,368,191,902,195,702,552,439,906,837,283,387,398,600,658,873,684,475,789,1,32,54,0,4,921,640,594,614,801,330,436,227,744,630,283,488,28,884,468,859,672,196,291,98,865,521,410,191,978,791,365,347,647,309,617,586,146,211,166,30,642,113,660,284,563,16,178,484,289,263,92,243,540,46,62,319,316,190,759,111,295,311,220,746,625,777,108,910,404,21,162,740,945,198,209,235,789,950,778,886,227,605,275,225,847,968,64,874,156,715,38,318,315,125,646,549,140,935,661,288,534,916,898,14,184,523,822,373,450,419,84,407,256,990,921,29,349,595,724,982,344,337,92,246,743,15,541,468,893,384,92,963,178,180,869,43,519,727,988,526,450,741,742,68,446,38,469,930,687,417,396,504,292,338,867,844,997,778", "741,723,623,267,491,616,165,462,496,385,657,490,907,870,587,343,965,954,462,424,363,220,340,969,912,738,434,537,899,382,766,479,167,135,749,633,391,265,855,768,958,959,2,739,922,92,957,773,120,935,161,537,592,615,670,377,780,942,966,473,503,625,636,236,467,979,191,929,821,472,511,754,374,713,524,912,333,795,66,32,907,625,222,678,876,109,508,664,848,14,599,437,558,962,402,832,87,749,334,429,669,839,693,676,825,894,958,501,146,204,285,986,146,577,708,266,618,779,441,767,476,50,212,29,346,643,988,909,181,916,570,264,980,231,227,40,778,659,651,5,70,951,908,854,736,713,163,700,56,830,661,9,148,162,669,256,537,644,838,534,31,49,451,704,101,393,322,255,997,325,349,306,857,588,141,782,31,948,411,782,84,148,941,95,71,372,724,415,959,570,232,746,175,699,647,825,708,341,425,562,837,51,167,778,788,793,765,517,162,104,765,722,553,271,839,35,467,963,162,349,109,665,70,515,903,536,709,938,945,835,810,498,378,706,627,505,161,852,837,125,426,274,839,292,694,529,298,227,914,193,906,256,734,993,124,977,278,594,322,374,80,843,773,737,458,881,39,988,716,480,469,273,128,748,835,602,923,155,76,339,546,837,133,86,766,412,306,166,244,973,682,775,54,268,383,678,113,845,864,272,27,725,660,817,817,138,759,959,301,981,730,331,264,444,252,270,487,366,308,701,734,349,979,504,567,635,927,360,198,776,986,277,736,956,537,635,539,419,867,980,485,473,563,443,891,145,648,958,546,45,529,20,357,177,404,930,295,7,846,819,730,577,873,409,705,343,983,329,16,675,272,29,575,253,624,635,467,857,862,94,630,735,933,740,827,32,928,337,689,676,295,173,945,129,288,864,397,30,118,674,310,11,517,195,287,145,336,190,441,888,118,672,847,318,765,47,577,789,955,55,979,977,517,172,852,417,118,681,441,763,384,150,129,880,592,757,36,409,153,820,432,180,604,470,689,919,548,369,473,271,458,663,302,620,824,100,85,574,487,333,480,655,384,488,111,985,654,606,974,251,356,823,913,105,641,359,595,756,981,759,216,11,942,971,127,733,807,865,458,342,902,387,317,287,471,922,511,316,885,353,516,921,86,650,102,695,238,567,331,1,114,616,844,135,87,222,851,764,73,268,463,6,479,198,989,135,822,263,38,911,34,233,470,937,716,8,531,434,544,167,511,682,30,527,958,26,892,825,488,860,379,906,493,414,715,916,137,755,38,22,484,343,373,782,884,425,696,549,958,302,932,116,26,963,955,555,165,61,700,79,706,317,92,218,42,534,887,748,947,129,182,527,625,459,297,109,579,83,889,899,577,737,275,610,600,571,83,488,723,893,747,686,756,344,166,624,556,186,19,655,641,75,228,390,261,956,252,46,884,370,703,458,677,161,445,47,934,624,31,11,594,350,606,342,443,275,658,952,727,899,645,839,976,701,696,31,382,477,845,888,960,27,203,59,275,655,201,628,906,693,609,281,701,552,316,966,693,904,830,51,43,29,415,820,192,857,838,764,782,228,285,55,770,548,534,943,407,616,537,427,993,648,194,281,536,691,929,161,561,88,429,102,757,53,297,285,547,6,489,928,258,916,858,467,428,665,809,565,124,208,152,199,379,233,117,879,66,366,732,57,173,200,147,864,19,842,532,835,672,754,368,402,921,16,609,796,756,715,689,847,352,210,477,819,145,239,986,528,530,978,894,421,792,104,884,469,312,556,590,401,817,668,79,164,691,791,327,974,714,525,474,766,133,308,96,648,357,522,365,669,61,87,716,690,85,46,680,877,486,462,293,761,54,756,69,511,417,551,179,896,182,776,373,23,558,347,508,387,323,960,364,703,465,937,830,296,5,856,100,295,188,157,583,514,4,0,609,592,339,76,137,709,186,942,805,546,20,414,284,232,509,933,959,806,346,991,926,788,768,373,909,550,797,319,757,543,33,767,778,410,400,328,959,451,127,528,211,768,421,627,550,710,755,170,569,472,860,192,384,925,326,822,666,347,942,118,251,128,512,359,565,59,389,427,180,819,933,624,601,115,382,723,631,17,500,582,789,36,976,655,43,512,452,319,753,746,726,482,156,237,545,439,505,11,667,411,873,399,668,626,341,392,578,944,320,834,630,441,915,808,673,135,31,574,992,540,383,847,743,379,728,332,427,368,324,237,292,931,935,635,647,60,727,279,4,700,462,811,130,196,203,583,510,19,299,126,946,311,933,227", "88,560,634,417,232,170,36,173,291,76,476,40,725,788,318,9,497,870,61,248,19,606,677,74,778,984,234,627,232,769,138,398,189,727,743,107,468,640,664,983,775,213,522,303,318,690,687,23,278,513,149,11,870,217,724,796,663,484,409,388,854,924,501,937,467,328,431,290,304,324,617,382,335,955,326,904,231,63,786,557,890,11,117,367,167,27,488,369,927,897,613,294,324,546,505,583,695,59,207,34,600,801,64,324,345,574,757,924,399,635,648,207,344,773,56,783,58,858,924,719,584,134,126,920,565,683,139,720,654,974,97,60,205,719,126,911,144,34,976,685,420,701,449,392,467,524,175,971,926,377,126,859,398,844,957,634,916,873,893,476,733,545,409,839,429,454,405,777,490,384,785,205,127,786,479,993,134,230,410,491,271,820,263,954,311,487,951,751,200,3,859,893,130,745,485,896,248,605,949,985,676,808,952,363,106,230,616,950,18,996,165,174,269,704,948,544,561,93,548,275,215,925,277,296,891,96,319,574,62,368,934,696,754,750,434,512,293,145,883,473,270,831,964,786,582,929,276,75,391,498,806,313,468,291,387,600,657,908,128,507,323,802,656,302,628,855,954,965,168,644,266,613,925,55,400,511,4,570,355,444,580,191,943,903,90,499,292,442,677,487,516,587,814,939,613,599,590,98,255,829,687,574,995,962,874,940,597,254,602,500,368,50,909,67,915,71,690,993,462,800,929,584,867,550,285,924,922,146,435,897,105,810,698,366,784,25,160,158,689,628,526,335,972,878,625,85,327,812,591,540,689,569,437,273,457,928,578,728,521,154,833,574,555,680,637,697,742,586,399,666,438,333,648,620,312,614,743,418,974,730,44,248,808,34,186,262,91,35,189,594,273,165,984,891,432,687,310,518,254,753,961,611,931,250,820,133,362,895,879,925,806,989,765,924,734,821,38,80,245,627,904,619,60,968,108,129,790,612,95,947,631,55,250,304,714,514,485,740,232,712,862,535,902,497,276,501,347,670,142,724,507,904,479,63,454,277,662,167,945,442,660,263,621,956,189,806,35,298,672,819,831,761,260,225,582,814,509,914,14,744,568,200,598,68,373,696,54,262,832,498,469,728,381,909,46,974,300,672,676,535,657,782,933,715,76,676,27,968,542,615,612,150,530,850,845,271,943,328,817,663,175,946,166,839,675,492,505,112,172,133,620,591,564,663,302,538,170,853,859,169,636,354,648,52,423,708,499,668,90,23,616,92,426,178,863,8,514,489,979,146,715,776,957,670,220,873,514,847,44,199,574,985,97,596,122,748,702,556,250,181,415,440,510,743,870,922,23,236,243,542,439,132,466,164,905,339,775,667,705,531,690,302,540,870,215,288,35,678,634,567,389,248,971,460,243,407,38,688,427,730,201,620,979,520,282,36,801,427,361,824,567,980,584,714,378,843,593,757,947,837,690,731,83,599,881,528,303,427,363,213,4,836,642,914,789,854,140,461,838,198,284,164,74,994,431,311,885,666,495,794,901,637,489,474,778,261,207,712,903,531,654,450,458,626,670,364,753,739,321,914,439,787,236,573,65,806,23,551,413,714,94,552,372,113,31,84,7,147,319,889,337,715,841,270,999,586,954,230,52,130,486,53,556,604,119,13,857,112,550,630,649,760,849,755,741,103,246,711,16,682,225,627,54,26,596,982,84,855,61,850,700,340,469,887,593,699,242,159,587,99,55,616,951,306,907,998,560,76,812,160,115,987,307,810,993,518,941,680,265,927,745,283,136,561,680,40,27,840,40,834,203,517,308,949,242,74,283,571,149,290,441,891,240,309,970,458,888,236,241,286,706,581,826,982,219,536,311,229,397,558,699,456,547,7,205,766,270,465,282,183,246,296,355,802,978,231,9,546,69,824,953,860,563,215,921,609,0,219,138,470,528,998,324,564,232,867,308,646,146,210,270,32,839,668,398,26,665,236,776,209,522,188,463,433,426,13,191,394,362,196,768,690,194,550,899,991,40,860,774,883,194,713,986,403,388,945,929,917,780,966,504,39,28,786,53,448,390,935,748,367,224,303,42,958,674,229,440,940,316,382,148,190,139,467,426,330,896,563,677,462,818,721,56,584,282,725,837,508,77,223,282,44,114,65,33,691,108,111,440,607,174,421,741,958,814,491,66,262,927,995,160,692,78,567,361,275,258,109,913,960,409,924,143,680,930,505,897,527,64,801,920,953,187,898,265,231,974,303,762,465,393,26,610,744,840,646,876,724,74,890", "690,688,258,553,39,292,51,377,830,171,484,236,980,161,379,526,663,573,219,888,65,752,237,485,183,166,597,331,415,534,840,967,700,734,603,664,785,944,767,854,82,41,274,493,381,979,776,599,365,549,510,448,511,380,144,682,868,724,78,439,549,513,122,615,417,567,732,387,16,821,859,532,891,161,21,466,244,551,842,901,939,879,699,816,705,361,462,483,467,170,582,194,549,566,539,445,724,325,824,262,300,11,376,963,155,884,461,779,585,129,557,107,533,977,174,252,424,191,586,931,596,567,821,823,870,8,718,222,943,929,788,837,9,544,59,108,437,528,645,907,435,825,488,94,262,250,64,395,980,768,686,191,407,925,691,715,710,430,880,562,683,819,711,885,597,392,422,237,45,115,700,363,137,623,223,67,195,312,838,161,474,958,298,49,712,191,26,938,670,838,81,270,157,835,916,633,664,736,253,899,961,392,421,211,762,870,546,304,326,59,672,386,34,245,634,66,169,998,276,969,732,531,455,711,361,699,800,894,290,793,243,37,42,114,37,255,356,949,787,166,890,576,595,575,901,685,106,222,825,301,189,57,527,189,560,296,152,764,208,872,447,735,770,691,668,603,586,22,11,295,767,488,251,52,653,546,675,559,777,979,760,909,620,201,82,664,73,646,7,425,407,533,557,537,600,421,302,206,705,3,55,339,22,697,214,65,857,623,921,762,357,192,539,901,583,950,701,81,877,996,35,272,931,45,571,880,613,831,331,827,142,800,700,707,884,393,290,946,881,997,411,208,37,89,928,758,544,687,414,679,602,301,381,676,389,438,283,781,92,670,477,438,43,62,267,103,141,866,988,450,993,519,177,954,799,642,349,44,710,814,956,606,958,92,304,879,407,892,106,594,812,753,30,912,43,874,49,920,527,721,383,785,214,141,701,854,353,334,507,141,798,469,261,13,846,914,939,398,249,163,262,28,975,967,502,927,116,925,186,286,168,183,893,31,719,91,498,951,510,479,502,526,207,720,18,27,575,53,456,108,968,930,201,102,367,697,152,349,107,505,399,353,541,42,446,172,11,646,582,889,99,878,997,47,869,248,166,460,897,293,706,994,579,75,634,312,517,687,180,919,158,553,547,994,861,989,466,886,130,745,999,909,763,917,571,263,684,378,548,213,897,896,291,405,772,317,530,675,674,285,113,229,524,238,624,838,625,347,700,213,647,826,530,229,450,741,874,99,124,568,420,634,965,50,641,509,455,716,925,682,986,595,973,694,8,467,802,184,109,301,413,570,167,305,300,10,606,333,889,523,515,864,159,788,579,643,569,384,332,814,379,663,393,631,395,368,344,39,324,410,278,854,830,876,637,361,974,140,413,856,420,95,689,180,187,423,703,970,466,582,813,249,85,880,925,915,825,244,631,15,327,436,890,769,717,585,877,781,97,118,300,133,233,489,508,530,672,493,637,928,820,270,277,417,722,799,954,46,560,232,366,882,481,232,839,504,819,77,482,720,734,123,457,236,8,380,874,600,616,900,786,932,216,253,807,477,647,642,763,782,38,89,232,332,636,924,914,33,429,668,165,991,391,472,419,931,289,846,721,469,333,67,546,139,622,383,836,317,444,361,345,65,501,399,851,826,33,105,426,234,746,74,550,598,984,267,539,843,908,751,604,868,943,779,1000,690,385,70,469,549,86,914,822,618,393,305,579,467,530,784,515,498,800,164,812,675,37,588,194,25,316,831,675,799,545,68,935,188,673,413,505,79,390,898,865,125,397,964,830,735,254,482,525,285,333,253,645,724,397,467,611,618,540,661,272,591,765,784,503,232,346,101,585,581,570,444,569,522,693,695,272,2,885,719,404,462,723,579,833,773,585,5,243,986,571,419,291,542,900,215,185,171,608,931,973,963,863,315,581,133,775,544,735,26,640,592,219,0,266,106,565,151,334,592,182,811,492,825,987,854,143,572,352,13,318,289,515,92,468,65,967,159,325,963,580,925,778,14,24,449,816,55,862,632,789,643,67,983,261,459,861,307,522,574,477,100,538,512,106,247,135,905,935,457,826,65,419,822,341,194,871,524,157,116,196,971,539,826,535,75,859,563,146,774,524,770,802,269,939,162,630,939,189,109,957,390,967,463,432,673,831,518,35,234,199,20,553,307,524,358,74,68,750,172,339,249,195,84,620,57,423,988,619,25,736,13,540,333,125,933,705,909,920,490,114,48,251,644,320,853,229,204,797,986,281,819,330,163,933,866,512,130,180,77,808,272,277,747,527,11", "295,644,805,94,221,254,509,969,948,494,39,571,23,549,463,377,816,555,764,804,986,6,202,810,24,24,850,246,784,155,339,669,670,68,264,107,80,926,859,170,592,180,717,89,753,994,272,76,860,466,588,633,481,496,920,359,891,457,135,963,863,953,688,421,946,973,600,354,879,359,672,364,758,365,260,280,175,301,762,854,184,550,832,267,997,995,551,94,283,949,802,288,157,550,529,324,712,543,740,45,50,684,901,643,326,615,821,35,716,885,75,837,953,520,661,954,273,116,334,977,77,470,752,845,283,838,638,224,527,497,421,438,7,856,453,170,236,976,997,92,671,403,230,832,70,503,926,826,766,234,510,735,835,23,7,544,861,610,908,795,410,624,54,499,408,883,627,595,630,171,919,925,244,431,236,408,98,315,484,582,98,12,224,752,789,139,802,421,968,336,761,817,503,950,17,243,598,479,546,545,79,501,336,731,735,649,245,274,433,379,203,563,781,627,667,67,104,843,365,360,946,282,550,242,278,551,52,326,961,309,771,405,762,341,165,881,27,409,344,295,403,167,258,263,972,155,834,271,746,730,620,65,590,899,213,216,946,286,214,814,188,325,100,69,790,986,441,703,286,892,220,484,608,631,951,327,23,920,275,597,182,309,406,840,650,893,283,170,342,826,696,212,962,57,901,769,949,71,248,451,34,630,472,106,856,632,496,721,154,955,542,602,689,772,105,634,318,241,831,863,914,895,836,406,5,975,100,842,298,821,177,222,390,624,244,49,74,26,119,882,696,653,237,654,292,285,458,277,333,920,560,858,660,725,572,710,431,69,517,318,436,26,89,440,126,175,74,367,6,432,758,299,144,59,892,370,811,735,668,957,33,694,578,475,387,66,851,142,152,948,621,156,130,505,508,790,39,856,96,891,570,323,929,823,981,968,827,150,593,40,817,933,773,593,297,849,126,875,942,710,387,544,492,679,275,209,529,390,931,830,797,625,145,558,169,272,918,441,453,453,516,642,659,244,788,800,471,524,766,314,672,610,976,404,95,684,771,427,667,21,314,509,916,932,903,743,812,202,86,368,813,353,667,605,346,538,895,76,590,332,352,113,521,824,485,119,145,226,931,691,312,301,345,189,294,781,427,866,792,521,718,99,143,874,505,83,794,172,351,349,296,601,834,300,367,2,564,35,572,298,316,870,124,768,226,305,702,244,835,995,548,288,417,51,151,621,367,199,846,284,712,970,695,496,83,879,47,389,612,26,329,665,207,934,502,248,428,462,175,236,910,401,440,286,710,451,327,280,184,175,727,128,475,390,446,127,260,999,258,736,406,681,19,472,850,183,278,769,263,147,375,525,493,924,312,57,750,914,493,775,771,721,159,522,484,533,686,268,648,253,51,206,271,733,25,237,267,641,389,698,652,533,578,848,176,500,17,289,39,571,230,319,128,653,466,259,164,691,680,844,887,651,625,692,204,579,493,210,873,436,523,966,347,761,351,420,223,447,196,859,764,272,459,107,369,891,571,725,271,576,443,772,692,504,399,358,852,928,466,45,769,429,172,400,299,273,442,55,232,888,763,87,78,235,333,983,869,942,204,426,526,198,556,75,930,50,221,282,254,968,565,659,882,915,265,779,223,61,113,587,391,370,342,883,393,96,122,285,949,57,651,678,828,384,823,11,305,385,528,880,231,481,717,694,358,124,20,751,964,552,399,178,490,584,142,568,660,764,57,493,815,701,47,577,794,602,321,745,740,737,968,319,634,159,269,417,348,499,527,120,930,307,600,349,773,874,583,123,713,920,991,8,291,717,232,644,147,447,320,242,385,368,986,356,206,544,59,348,838,94,141,302,877,160,763,592,868,536,948,269,549,298,659,371,18,609,49,251,883,72,407,57,420,781,752,531,197,504,989,285,696,41,409,481,594,339,138,266,0,268,233,564,152,666,797,800,533,774,132,141,610,393,368,38,325,45,806,576,910,462,243,230,558,37,712,57,844,422,910,339,50,985,109,265,561,621,196,893,418,157,873,7,818,395,837,855,859,955,25,15,5,239,980,193,972,514,512,984,959,644,446,44,686,176,909,465,259,996,165,437,931,341,744,495,76,959,43,194,420,210,575,991,420,696,286,237,431,466,493,712,527,417,624,895,920,919,322,869,753,709,62,388,327,199,562,317,830,367,794,903,152,907,256,230,981,446,618,494,608,24,703,879,81,347,536,323,777,169,417,978,549,1000,130,499,710,442,48,311,11,506,363,905,486,293,377,301,486,403,84,213", "272,44,64,423,962,306,123,277,226,751,39,662,955,951,416,305,411,551,890,174,56,144,920,831,219,520,784,575,796,38,184,543,941,370,834,977,530,118,583,119,634,585,834,416,763,65,957,912,646,346,690,781,8,492,201,538,842,659,146,967,693,564,601,183,445,525,416,736,891,395,477,564,231,234,118,540,479,446,25,898,646,720,387,902,699,474,88,464,758,878,80,67,49,862,373,75,910,718,508,552,263,229,804,784,933,751,392,81,697,856,38,817,746,399,381,630,377,381,356,930,418,282,480,373,359,419,308,944,833,333,136,528,88,369,716,115,743,657,77,717,417,283,476,711,789,763,693,142,94,197,522,933,150,713,918,476,556,374,717,537,577,837,382,915,980,513,848,725,552,3,99,211,634,386,505,695,234,205,157,420,565,818,332,106,549,918,541,386,45,458,366,994,105,839,145,251,90,19,694,954,416,193,679,160,451,758,426,816,682,609,909,484,517,345,276,78,172,585,90,541,536,558,543,294,469,744,74,219,285,285,617,828,498,828,192,381,430,510,69,450,380,231,261,352,276,520,184,114,531,874,591,750,523,892,12,84,856,708,641,297,287,833,145,904,669,341,450,586,348,977,352,487,180,376,525,380,897,344,750,668,381,110,305,95,884,147,216,598,300,92,414,804,470,562,338,186,379,117,225,13,854,765,51,975,73,391,808,554,836,102,48,485,650,358,987,787,658,287,139,295,815,555,947,2,349,735,15,116,192,630,368,253,189,13,7,296,446,734,604,354,302,875,365,480,290,308,256,138,906,501,545,593,650,392,448,364,341,330,324,337,55,701,65,300,18,831,896,651,200,470,547,282,145,876,761,804,498,634,550,498,447,229,661,667,940,991,451,382,231,885,420,544,710,165,952,244,61,616,126,250,306,548,918,194,66,271,161,244,875,392,988,951,115,990,658,459,333,656,454,806,486,562,251,518,539,613,234,887,288,801,194,272,278,946,174,241,563,641,588,560,818,791,548,703,144,633,834,616,903,629,409,409,352,991,470,522,631,345,423,155,837,160,123,399,60,453,628,20,750,128,50,231,559,42,799,924,216,51,779,216,135,236,879,970,621,390,366,825,387,237,236,336,726,596,937,560,12,826,309,218,282,343,294,152,863,60,70,714,154,58,248,330,248,246,720,860,973,82,20,145,486,778,970,107,415,758,581,794,759,822,524,495,508,91,626,498,327,698,775,710,629,116,538,661,443,768,514,645,208,191,947,231,316,275,824,889,686,750,719,319,300,266,331,862,705,59,40,130,811,720,973,860,861,169,882,28,20,340,508,226,757,356,477,520,240,183,362,577,182,763,44,803,52,852,345,177,777,135,922,881,754,16,22,117,911,471,165,551,381,532,377,550,785,193,25,371,592,238,906,254,821,628,696,987,897,835,120,390,691,841,369,358,762,968,864,394,767,202,666,403,7,175,967,264,348,722,353,534,969,679,540,512,940,768,616,752,445,765,59,323,416,362,322,273,464,966,306,773,842,204,543,718,438,577,832,765,841,743,766,168,206,850,991,796,898,741,650,486,793,157,575,514,208,199,927,408,832,290,722,601,439,907,481,484,478,167,556,683,96,991,787,212,391,178,96,289,910,135,70,807,844,800,531,944,7,943,809,471,801,994,464,633,377,460,393,363,355,831,320,775,940,912,273,272,482,810,877,311,691,612,23,728,726,784,125,423,727,759,99,324,895,330,855,933,601,392,40,523,675,64,965,397,944,42,811,531,890,326,758,742,378,484,278,641,931,644,176,816,820,101,514,930,333,270,105,705,546,318,448,193,974,672,98,193,771,176,446,374,708,785,233,945,464,125,770,575,547,460,319,888,697,798,790,412,817,817,868,531,463,71,225,161,455,677,826,642,334,614,319,616,510,289,755,848,614,76,470,106,268,0,196,465,761,16,537,858,628,498,773,250,738,218,825,581,138,87,153,208,466,811,539,563,696,572,923,781,718,531,670,969,570,225,595,48,622,839,299,893,469,235,454,261,850,805,151,151,867,850,60,243,516,78,552,636,988,233,731,556,367,296,270,846,920,596,94,847,939,531,365,789,471,676,83,511,963,37,397,952,648,388,303,648,333,887,197,735,855,283,880,327,712,177,544,70,781,143,589,993,811,477,296,348,961,796,623,778,561,730,922,306,913,296,285,820,162,718,899,944,81,484,591,23,850,304,616,671,628,639,676,715,522,988,365,917,171,664,546,631,173,249,823,27,173,993,204,700,584,216,569,374", "189,946,603,992,152,43,198,295,136,248,172,880,200,204,586,356,939,429,769,148,562,601,193,146,836,562,722,262,299,185,638,115,488,2,555,294,376,317,251,292,820,959,215,583,371,671,480,384,843,148,967,838,469,777,582,707,299,16,462,835,323,76,979,983,294,725,233,598,764,381,994,230,300,727,864,10,818,725,97,922,912,18,491,462,792,378,321,214,286,79,327,983,630,110,557,824,565,284,190,403,10,291,328,695,535,378,822,175,657,577,218,780,154,223,106,969,694,499,325,904,891,717,313,273,603,950,339,143,31,97,329,785,817,766,786,998,320,864,543,216,129,482,635,55,406,664,227,228,660,624,917,732,146,690,899,801,925,326,677,609,21,93,438,30,481,648,951,376,662,928,694,195,113,157,506,608,549,509,140,342,161,912,282,550,78,857,656,268,709,629,221,75,238,592,671,289,721,962,991,422,652,347,7,751,147,380,24,335,739,714,100,141,631,256,264,393,238,955,55,95,297,22,239,249,44,824,794,722,238,121,50,60,203,880,535,403,689,515,86,610,350,684,876,704,808,5,101,289,610,81,82,397,164,161,778,458,786,742,79,579,99,593,381,141,900,310,599,264,610,196,546,482,301,13,478,659,408,845,651,568,265,175,170,280,323,934,583,505,286,265,65,327,434,467,672,482,913,108,419,777,107,369,535,687,198,740,889,535,160,134,660,958,164,108,33,316,198,348,507,560,928,90,715,979,580,117,480,378,55,926,584,339,701,677,262,915,700,821,805,509,230,659,659,156,820,743,584,452,258,847,365,536,283,624,332,876,885,829,656,28,137,720,293,570,188,191,415,72,249,743,849,754,636,185,231,99,591,761,827,405,392,644,623,437,771,896,505,188,542,950,478,988,609,239,319,923,914,545,527,820,175,716,127,587,505,934,123,729,386,367,893,755,730,921,478,562,168,284,115,724,686,798,114,690,184,540,43,404,583,24,519,753,139,115,909,358,312,850,624,810,350,126,70,763,855,282,586,846,454,614,542,678,421,441,345,811,813,692,739,119,952,984,726,526,630,802,492,311,844,345,188,138,29,184,29,875,533,835,242,356,382,914,249,376,483,464,698,85,283,408,349,168,414,450,380,74,629,275,996,47,846,118,775,195,383,159,704,687,59,145,183,722,883,922,244,657,545,844,339,360,586,965,985,569,132,283,825,504,281,219,554,938,398,720,404,125,770,284,656,8,662,191,133,928,943,548,393,433,731,764,838,963,394,121,813,658,200,862,725,650,762,438,733,245,368,741,847,571,158,565,256,978,344,413,68,205,781,275,297,805,47,919,903,969,627,574,180,478,508,275,712,451,493,419,751,951,911,271,142,268,202,432,967,228,773,478,180,530,269,437,397,573,673,955,937,404,67,336,456,584,25,963,714,403,137,564,481,307,183,94,113,741,397,121,139,117,638,207,119,50,511,944,38,759,869,204,100,376,273,319,70,654,184,228,930,820,454,887,222,688,150,834,602,167,505,130,58,174,362,848,233,817,720,453,90,869,912,343,424,25,268,272,157,792,553,281,933,940,971,964,650,900,35,96,528,41,552,742,293,469,922,742,42,393,896,573,478,623,362,976,341,437,927,728,878,918,228,761,98,234,288,137,746,386,115,377,356,393,26,589,503,308,977,429,702,198,400,404,824,318,165,473,574,522,413,413,788,754,112,894,840,314,639,599,226,962,540,671,930,298,622,898,476,159,891,630,285,902,901,245,470,921,850,718,585,866,693,137,585,672,455,536,447,175,184,745,193,155,414,717,728,368,97,434,444,993,914,420,876,767,792,236,101,78,520,726,917,181,230,306,661,432,576,214,786,337,501,559,993,318,362,809,161,666,718,858,622,783,392,570,713,654,470,132,507,192,540,984,599,226,637,189,180,317,801,137,528,565,233,196,0,249,414,23,707,56,339,492,165,33,601,431,465,721,536,711,124,375,581,960,576,486,136,698,516,628,182,702,212,120,414,80,294,901,969,471,357,303,91,520,601,736,648,124,715,510,707,15,185,844,918,397,40,103,672,630,360,733,848,768,568,392,891,533,689,461,579,153,62,78,633,852,732,927,582,957,986,48,805,761,708,117,181,293,665,24,550,969,176,798,801,415,961,49,131,863,343,591,925,865,872,739,531,154,135,833,68,218,445,557,10,4,579,639,638,252,486,996,647,329,373,339,272,437,608,769,363,609,83,379,670,43,677,336,692,459,67,184,150,375,833,921,558,428,707,188,951,651,916,274", "397,988,919,97,667,547,645,103,903,596,880,304,875,545,130,404,687,47,997,103,276,392,917,744,480,21,913,496,80,49,366,871,14,720,480,604,194,662,192,915,617,239,821,336,334,146,732,747,39,493,467,603,683,20,512,741,619,669,128,420,798,464,861,380,612,226,801,316,494,558,180,599,830,688,753,879,153,379,305,373,69,391,134,963,961,32,424,182,803,621,465,299,857,443,428,855,856,261,465,453,567,878,225,359,693,832,159,815,530,499,145,755,420,785,71,787,988,394,999,344,918,908,248,221,844,247,919,247,698,982,839,99,1,306,837,871,169,798,837,992,124,139,880,826,656,735,336,150,903,609,76,756,653,420,104,497,381,108,645,103,836,819,855,789,364,535,882,411,742,816,784,826,443,128,495,771,575,749,471,293,302,991,567,390,66,357,582,114,778,877,278,520,597,353,534,984,845,881,646,838,606,117,74,623,273,285,64,156,310,703,222,435,427,540,163,753,847,539,329,227,594,659,15,162,307,126,131,996,526,36,758,936,869,859,261,283,88,286,459,21,638,120,628,94,670,696,578,656,611,591,877,482,916,884,140,602,197,962,159,568,642,941,9,102,308,227,488,487,308,328,335,399,366,187,648,472,992,835,3,913,219,615,636,391,367,170,693,155,246,106,500,944,967,250,937,620,438,749,154,46,539,972,242,818,917,382,251,185,881,231,345,551,925,462,872,509,44,25,902,50,523,860,331,134,474,61,348,52,528,62,785,764,582,658,696,762,308,287,164,406,300,772,313,23,888,816,278,98,949,920,502,493,117,918,457,832,701,674,729,51,111,159,353,839,65,456,518,365,990,206,954,504,499,393,131,166,423,711,90,649,916,494,150,338,838,23,613,786,783,45,97,52,905,718,105,881,719,538,398,424,206,857,692,83,587,597,574,767,278,238,470,593,635,245,246,98,851,986,50,398,170,765,797,926,980,334,455,48,6,529,570,941,636,325,180,120,110,542,771,858,515,2,202,569,218,856,709,795,322,760,50,285,720,884,763,681,850,892,690,84,492,317,384,772,558,579,324,768,689,738,971,185,20,445,387,166,465,710,967,668,81,883,838,490,296,153,332,786,620,786,161,781,633,784,635,913,636,844,130,89,406,167,946,612,192,912,451,674,633,946,113,735,634,742,318,254,512,40,143,494,140,64,811,775,173,397,634,412,271,793,5,395,384,471,898,918,795,997,88,3,978,494,272,313,175,252,739,194,21,485,376,992,265,622,499,147,469,328,154,824,651,973,595,630,318,766,454,464,52,999,824,814,331,285,828,96,909,559,744,571,285,912,761,448,618,838,504,234,842,854,819,577,777,421,382,975,151,282,845,37,865,974,771,19,781,775,490,244,208,366,5,788,942,50,694,288,106,712,82,81,660,667,636,671,137,502,61,96,401,172,947,401,637,558,734,64,154,882,280,581,81,322,556,731,489,309,56,28,171,652,408,158,99,415,769,400,784,49,816,109,175,253,650,160,907,34,785,980,604,343,223,283,551,103,4,770,664,935,974,767,609,82,800,647,869,363,224,612,481,68,626,250,557,270,997,341,601,332,216,530,277,990,679,930,411,986,108,856,864,604,650,685,605,593,81,82,582,314,86,723,142,207,587,734,458,155,450,584,970,383,568,281,262,204,221,778,129,125,649,517,464,410,605,726,734,489,710,656,784,971,128,451,808,289,122,816,993,337,209,163,221,394,436,800,126,382,18,295,831,33,703,57,689,809,441,408,395,334,169,570,546,756,420,623,295,822,200,361,807,905,966,172,438,581,112,447,722,263,639,459,944,354,96,205,707,268,858,73,987,421,328,411,645,143,779,491,181,666,617,658,47,419,144,39,125,156,220,385,443,194,32,610,965,751,264,788,771,650,419,518,770,32,11,929,330,709,998,151,564,465,249,0,959,913,803,918,111,915,161,986,568,340,869,759,727,100,97,123,102,452,89,875,45,359,775,97,216,495,188,449,268,745,260,940,191,782,208,970,373,120,215,132,348,354,443,986,689,148,915,900,689,569,378,329,110,525,250,566,925,806,845,445,423,754,958,324,431,733,425,519,372,446,229,364,326,223,348,57,298,115,339,633,30,784,521,67,421,533,59,753,852,185,98,128,813,994,67,224,664,210,877,590,565,46,202,574,384,10,822,242,800,188,624,943,778,212,866,56,339,562,912,793,641,42,896,480,732,716,772,316,796,326,980,936,97,726,597,284,911,402,138,778,621,290,573,213,609,111,96,51", "631,512,87,737,200,950,880,708,924,509,209,279,95,205,797,774,228,724,927,548,153,546,748,538,291,535,518,471,193,970,885,114,760,492,586,751,259,333,960,505,303,413,936,155,506,97,150,575,576,622,795,639,98,357,327,947,788,3,482,728,648,601,27,957,8,396,16,283,996,196,632,580,734,239,827,163,563,326,999,119,777,338,308,434,223,117,527,257,725,594,913,409,93,115,646,381,746,576,962,386,966,577,910,113,936,375,682,318,373,858,235,301,980,902,729,96,476,487,62,487,890,115,28,518,168,653,929,432,273,319,468,989,294,366,316,117,112,555,451,710,367,871,526,61,118,645,42,229,479,810,40,31,967,38,581,197,879,183,49,502,362,746,771,882,679,716,454,275,812,493,801,900,387,625,84,415,541,230,276,460,256,5,205,835,655,560,927,284,500,114,278,596,405,933,597,846,116,460,389,8,324,981,597,248,771,796,826,577,613,255,687,494,66,753,326,673,3,594,528,540,375,204,351,689,106,218,326,426,540,114,310,906,600,98,44,19,473,809,892,79,317,247,733,919,700,444,756,106,104,346,437,916,298,529,996,408,990,311,802,34,451,271,876,193,268,632,638,933,514,835,302,777,989,265,200,895,284,30,461,74,953,307,417,983,370,285,358,468,239,24,205,797,940,80,153,237,727,837,809,386,142,656,833,140,926,247,828,543,558,16,604,950,468,452,810,866,246,786,878,867,80,436,713,852,384,366,662,494,909,830,12,352,113,701,688,589,677,562,313,674,417,587,682,688,211,856,368,5,407,614,61,675,515,48,958,10,630,731,278,88,465,185,320,222,547,907,552,617,790,3,917,167,85,197,708,850,79,342,179,139,611,95,958,901,345,257,649,26,222,254,40,860,247,861,152,45,453,163,982,255,796,592,451,975,300,281,234,683,966,631,223,965,950,597,714,283,411,272,256,555,173,831,432,875,608,977,111,74,14,147,524,841,199,679,678,593,692,120,27,784,223,773,948,814,876,989,332,650,28,388,599,594,346,532,916,845,204,747,98,833,19,790,179,202,972,200,251,867,700,205,452,702,906,112,147,636,418,319,860,457,974,566,809,585,931,604,967,673,496,438,707,926,390,405,785,929,53,187,441,118,573,858,212,593,785,611,999,200,203,436,971,666,646,420,699,242,492,417,473,542,254,774,200,164,24,315,152,363,677,830,343,255,538,336,372,519,909,732,117,719,516,83,89,900,16,426,989,200,990,136,375,799,310,835,687,569,404,527,382,517,104,130,185,387,703,954,79,244,356,507,710,917,276,158,289,799,205,644,471,373,508,124,441,396,162,883,273,330,204,708,218,792,858,972,959,526,713,231,950,643,602,306,838,760,265,540,151,966,442,886,738,717,631,283,520,749,42,922,139,54,35,268,634,612,752,12,569,619,50,702,625,423,973,891,721,723,516,32,888,643,740,777,844,21,430,921,570,929,956,742,862,474,513,336,751,99,965,640,25,271,220,812,645,930,976,336,721,527,342,888,948,888,174,472,832,26,567,135,882,396,946,545,706,864,827,63,954,849,366,884,4,855,811,531,304,963,188,990,137,95,517,411,656,100,411,492,566,40,553,560,395,400,661,909,313,322,790,196,519,302,848,554,22,38,11,190,197,603,737,110,189,405,855,406,702,358,878,218,771,490,751,189,526,117,462,576,575,870,658,263,833,901,956,999,921,376,141,107,529,56,460,210,103,943,69,344,863,615,225,816,22,956,658,566,955,501,419,486,345,411,220,232,342,311,345,788,561,630,700,108,425,922,346,395,904,145,654,199,237,82,524,867,656,909,262,516,763,624,193,450,710,988,987,535,73,325,694,918,536,897,405,892,187,485,72,175,652,935,837,458,284,192,221,613,603,5,21,562,153,727,856,45,25,399,436,186,324,334,152,761,414,959,0,169,790,159,518,437,622,199,352,845,558,413,932,610,761,25,274,378,549,198,400,790,285,841,788,1,656,902,25,823,935,914,131,466,950,288,15,889,789,237,364,246,277,392,442,177,428,107,818,295,606,21,645,831,588,787,93,931,937,470,592,215,786,854,264,735,913,260,208,120,829,527,988,74,570,336,49,945,612,778,394,805,973,380,370,188,582,93,744,394,672,506,958,751,834,958,154,238,961,478,167,384,467,499,155,947,862,699,86,8,222,763,921,469,218,794,764,420,859,874,615,86,22,574,304,372,785,225,923,301,637,457,429,247,138,99,466,294,440,250,502,408,21,146,999,82,246,616", "546,979,809,177,311,8,628,292,464,678,135,701,449,199,958,260,396,777,946,155,132,631,955,263,931,878,495,201,627,13,705,434,793,456,412,987,224,40,427,158,437,424,860,599,3,767,847,642,825,312,272,456,340,446,706,683,904,730,480,898,948,892,530,179,704,452,322,448,217,696,690,593,348,267,898,654,34,269,449,906,414,623,300,949,61,234,811,446,588,280,128,199,947,365,8,31,326,308,700,383,855,396,213,501,13,374,99,742,803,164,431,344,579,524,395,28,751,76,295,690,502,716,181,452,871,852,868,457,655,493,645,488,30,483,218,658,245,389,586,374,365,919,989,325,321,444,424,681,92,586,877,477,382,243,969,342,75,220,345,268,841,888,565,851,469,33,659,543,179,553,22,681,182,474,850,278,556,686,333,306,986,482,109,387,797,353,72,424,927,746,265,91,73,713,2,863,314,91,508,297,413,457,43,188,192,500,231,435,348,565,841,970,857,157,193,183,69,953,764,689,262,540,174,571,249,704,99,169,860,837,55,807,902,462,796,67,664,618,234,26,698,139,679,505,248,871,844,311,683,736,327,635,71,161,330,61,577,167,752,144,83,451,52,298,693,707,645,327,964,968,357,511,717,9,149,139,546,310,922,411,470,758,831,592,558,381,462,430,909,885,416,15,579,394,145,440,648,612,850,685,719,684,281,316,388,958,304,66,85,677,376,357,973,448,971,339,1,858,725,264,476,398,456,528,771,878,935,815,10,276,5,499,794,470,82,528,44,986,546,116,960,780,358,240,198,713,703,963,598,975,282,999,878,422,144,184,934,738,182,373,554,11,841,8,351,646,122,374,928,833,59,698,489,156,244,916,407,130,960,248,209,173,83,470,977,943,152,910,857,223,619,166,686,902,177,756,337,281,328,144,484,100,854,628,655,985,576,966,48,329,616,236,992,461,784,149,916,31,141,626,40,253,566,147,554,306,415,306,571,364,328,530,585,567,584,708,571,653,433,139,751,226,645,922,456,1000,695,542,609,672,494,449,792,107,843,362,586,820,515,733,189,93,807,292,52,860,955,412,411,216,910,371,938,880,975,430,307,869,854,555,696,801,362,426,88,998,756,947,923,644,818,197,62,652,162,921,127,532,684,729,140,919,828,596,70,325,522,581,561,914,26,130,830,228,273,854,945,266,595,540,433,3,951,929,258,719,577,566,102,156,952,472,111,963,188,906,638,900,53,413,575,743,790,581,121,896,198,236,657,810,7,171,795,991,844,156,450,555,49,977,17,470,272,26,670,64,320,717,609,971,15,862,113,596,522,402,473,751,537,201,795,694,605,53,274,154,904,614,921,984,48,692,973,476,692,189,216,92,297,826,996,744,307,544,608,140,344,957,380,67,525,64,513,729,545,432,622,134,362,736,889,416,87,391,446,921,644,151,333,238,718,808,324,858,896,642,777,34,248,352,883,639,166,40,76,754,327,958,333,222,432,277,513,971,63,133,139,975,738,349,105,880,774,217,526,609,602,690,927,682,619,590,557,990,967,996,388,307,451,555,775,542,859,176,940,967,51,201,953,846,81,37,176,679,409,342,947,330,430,540,770,347,849,56,267,153,212,292,797,581,212,291,598,277,547,396,18,717,568,491,526,217,903,941,685,834,690,168,625,257,706,479,864,112,414,284,82,557,564,801,539,950,136,450,184,38,572,420,216,905,654,772,977,34,336,817,864,172,335,633,337,729,378,960,217,926,330,106,824,771,192,187,957,687,565,925,963,563,594,24,239,334,882,633,684,380,661,555,710,124,626,660,276,417,203,118,151,52,571,776,693,215,350,980,627,535,405,814,357,287,509,139,565,338,296,48,702,106,391,133,572,202,605,250,918,110,659,660,238,215,281,867,307,922,176,505,765,421,185,78,487,205,656,835,227,942,564,592,666,16,23,913,169,0,109,298,84,696,894,33,845,24,755,31,957,256,477,372,7,899,883,731,696,695,186,939,462,257,514,90,498,833,402,807,764,951,717,497,450,718,570,468,684,953,484,400,902,863,868,871,370,797,432,833,945,288,397,916,292,943,135,476,854,980,509,221,919,95,100,376,349,296,618,154,651,997,20,674,14,800,238,139,702,543,724,508,34,560,998,710,954,805,111,915,618,1,529,736,648,448,630,531,191,550,579,607,833,995,656,575,923,113,10,968,916,649,44,66,516,452,415,170,238,150,757,677,767,887,910,427,97,83,122,679,260,119,611,734,371,844,469,673,26,505,937,506,908,975,723,181", "178,431,605,97,195,63,331,231,66,420,762,113,806,95,824,39,628,477,233,88,201,852,767,34,190,40,862,503,478,683,599,357,628,38,44,520,298,953,629,792,492,293,553,103,154,510,238,444,843,644,276,758,67,149,686,570,395,841,91,81,479,679,927,711,537,818,381,677,767,216,306,342,98,657,227,648,10,702,582,51,716,227,931,673,563,941,931,34,715,329,373,448,771,219,736,229,879,224,465,819,640,774,133,77,653,244,709,45,499,146,560,974,452,3,431,799,200,620,302,845,226,383,168,262,819,388,245,700,689,424,945,142,355,463,512,838,619,28,404,662,671,650,92,696,711,441,43,997,305,160,699,520,396,995,381,738,170,977,750,259,929,135,570,215,724,579,326,161,353,615,69,247,332,763,427,931,598,426,438,209,996,357,532,923,816,331,406,846,256,568,622,40,782,740,745,473,995,20,812,127,732,813,713,861,210,852,998,96,204,714,742,28,264,461,172,12,502,300,327,991,189,483,288,130,635,908,157,889,686,520,848,405,376,916,408,439,443,270,965,335,49,545,77,938,665,916,50,699,439,317,62,143,955,239,921,582,469,565,567,64,780,931,991,267,956,603,134,350,179,666,204,95,850,637,935,40,181,600,320,98,752,112,794,162,604,254,546,700,311,406,294,958,37,162,627,25,72,902,751,277,274,236,558,529,401,923,345,950,903,434,711,926,571,886,234,99,127,422,265,529,827,868,934,640,557,904,188,262,343,228,279,795,564,959,877,849,681,592,615,47,868,193,883,241,475,542,28,430,130,192,540,828,991,508,899,558,974,375,30,712,367,370,796,833,268,804,813,240,105,355,187,258,980,920,442,867,696,475,744,832,431,601,328,575,972,353,436,881,794,264,485,103,750,128,730,223,487,64,672,518,534,295,756,742,305,409,227,712,422,951,778,473,190,71,331,404,518,972,39,950,552,139,404,673,655,580,292,400,736,458,33,438,655,576,181,614,994,85,758,390,656,736,621,940,534,447,953,326,827,572,776,786,772,792,831,393,150,99,525,797,297,506,4,593,968,564,302,212,983,19,59,214,374,624,361,855,693,114,936,634,291,157,118,500,389,875,599,256,174,903,339,549,623,244,416,316,879,415,366,667,85,90,127,905,755,51,739,462,176,246,591,33,985,768,883,175,847,128,515,173,402,804,898,844,588,90,292,748,350,418,9,200,364,425,627,797,945,506,466,400,842,396,184,420,477,28,897,22,78,548,688,664,396,497,299,634,208,920,898,139,142,31,598,998,415,496,777,907,189,932,374,623,931,981,434,158,865,115,148,666,475,897,265,499,577,182,937,228,914,393,859,9,151,111,285,744,321,628,65,199,61,268,210,956,750,832,562,246,46,477,281,483,236,476,810,649,88,118,615,932,264,973,411,722,477,656,780,69,650,43,516,587,683,376,686,341,315,818,323,640,824,637,314,267,65,822,197,499,951,725,164,994,752,88,507,123,137,918,779,419,100,159,471,41,860,194,106,552,856,603,522,300,230,312,876,304,692,302,147,949,513,749,113,169,215,583,835,501,88,842,604,240,726,200,390,134,994,46,650,149,954,112,40,312,298,130,728,297,906,104,918,180,511,410,499,591,794,896,269,380,29,569,592,149,45,724,141,413,731,155,875,909,204,469,955,142,465,62,282,818,439,476,364,314,216,968,119,875,460,97,225,842,857,616,423,62,356,507,605,97,748,62,574,600,430,634,732,269,586,202,173,125,421,270,165,54,554,857,162,220,961,645,971,122,725,984,386,219,540,407,5,885,174,679,378,730,255,551,526,777,669,835,872,711,581,724,459,494,584,663,725,845,585,50,416,113,772,49,725,510,252,362,751,286,238,976,218,551,804,433,130,24,741,966,246,737,551,249,268,304,327,4,367,603,744,805,232,182,797,537,707,803,790,109,0,247,16,446,814,574,694,77,385,134,937,824,145,539,31,917,137,505,690,725,394,770,301,584,300,61,146,530,96,347,895,59,693,24,927,688,765,217,968,457,9,204,865,95,2,274,227,902,301,64,299,547,521,133,821,21,301,399,919,876,186,808,752,443,456,414,199,519,606,241,390,665,914,869,487,504,293,612,392,691,405,404,795,561,122,287,771,387,821,872,328,435,481,170,130,83,253,965,117,957,501,624,909,890,862,322,734,639,452,152,361,937,462,982,136,827,705,994,4,537,917,523,106,665,611,940,357,296,373,105,685,227,786,927,376,221,571,135,653,37,358,354,231,291,735,950", "718,640,36,858,652,73,591,356,249,213,351,834,349,833,664,121,845,93,866,371,932,790,876,332,319,86,942,824,402,918,782,797,186,432,269,906,555,731,911,725,40,509,845,455,805,451,233,937,207,990,452,451,682,12,118,403,757,632,266,304,51,805,560,50,554,606,776,837,931,555,402,400,20,205,603,596,610,835,993,668,429,870,435,464,442,636,216,16,336,350,998,713,991,698,420,674,980,36,829,95,692,976,989,209,208,760,539,388,726,519,327,624,188,959,623,297,478,759,965,666,740,679,173,825,471,385,746,147,635,75,473,629,706,721,657,638,783,903,415,366,124,798,482,410,632,500,579,433,990,261,558,374,600,5,10,31,79,545,626,206,524,167,748,958,644,375,66,496,458,74,556,764,664,212,778,323,738,103,707,39,398,408,8,677,219,70,527,885,511,577,217,799,205,78,631,990,866,649,387,463,992,792,923,467,901,595,657,668,214,492,21,407,83,293,103,188,870,380,139,450,381,352,73,236,583,337,514,253,198,160,935,415,267,928,756,440,451,376,260,215,524,124,195,429,786,489,134,580,410,436,842,614,57,678,882,641,3,903,862,745,600,174,508,36,236,682,149,741,199,869,367,635,648,713,569,393,832,669,490,481,112,273,483,657,645,829,355,926,328,384,405,309,44,582,207,321,446,105,282,20,910,213,927,553,39,8,613,678,693,826,149,327,236,320,684,767,869,508,544,971,685,199,745,424,579,262,576,169,481,937,128,617,741,682,2,606,863,776,870,413,958,671,894,327,908,984,268,812,183,339,960,692,671,684,240,737,544,712,900,36,870,213,906,616,440,644,791,955,708,976,485,866,698,754,775,929,631,928,5,317,484,91,764,527,130,898,392,549,728,52,743,667,450,446,814,786,676,118,766,823,945,511,840,257,110,567,498,78,597,519,552,268,176,517,408,999,498,955,352,966,253,725,431,430,715,446,792,628,376,687,647,801,271,9,949,830,823,498,982,141,974,966,167,206,7,371,867,739,870,780,179,617,293,991,206,588,342,305,125,730,469,781,214,161,800,778,752,39,608,576,701,697,34,84,465,905,553,814,761,887,353,393,434,366,178,568,942,287,212,571,361,696,385,849,74,877,125,902,874,670,568,361,473,671,892,523,8,334,193,354,671,405,521,928,929,771,764,393,500,359,156,767,632,494,291,96,387,899,585,964,172,961,422,880,694,858,621,712,720,738,669,955,259,498,573,778,443,973,117,242,715,648,158,50,663,528,597,326,132,924,512,498,194,328,311,630,307,667,706,167,616,505,388,634,35,727,827,269,120,740,623,292,295,901,186,389,829,573,829,790,309,148,992,906,867,614,439,30,685,25,355,745,912,807,77,648,890,426,478,395,778,572,424,87,410,775,333,892,997,255,921,585,188,970,948,17,156,911,316,387,409,272,816,705,607,588,722,884,174,59,907,912,300,604,894,929,705,552,233,479,797,572,626,486,995,493,130,573,628,20,392,842,78,47,692,237,391,180,348,910,508,95,881,961,596,552,3,989,280,808,220,936,292,483,245,72,820,690,146,570,769,704,857,176,951,860,678,546,568,324,829,426,666,170,999,789,780,901,757,552,679,34,450,677,531,847,926,572,544,432,658,112,313,62,641,500,803,282,191,54,172,948,214,137,951,35,627,972,731,30,606,490,961,835,898,677,619,660,7,155,304,156,455,133,495,593,952,2,312,295,721,186,12,967,386,616,840,458,857,802,456,447,765,503,954,291,880,707,231,503,860,463,658,418,203,471,480,783,147,242,93,878,365,77,717,22,685,646,571,637,722,749,786,241,84,245,295,211,971,875,182,241,89,754,374,981,667,473,890,549,98,482,619,959,772,93,673,836,81,319,875,846,749,831,365,585,65,395,23,404,328,198,399,238,630,546,867,811,800,858,56,918,159,298,247,0,578,536,40,698,17,609,509,403,155,797,25,807,25,146,937,479,95,378,361,5,753,240,629,351,718,900,894,538,26,252,313,348,952,281,456,446,990,444,643,299,18,661,895,821,322,767,709,423,727,184,335,230,514,374,378,92,106,466,606,981,426,914,297,348,14,391,754,140,642,890,404,971,722,370,362,160,114,885,456,400,710,614,465,498,954,864,339,893,456,821,851,978,597,644,405,324,27,886,86,735,353,11,420,562,595,947,603,749,641,111,658,997,150,800,875,555,203,62,323,397,803,390,727,948,984,361,847,773,571,301,826,481,65,185,16,101,117,986,538,419,593,110,805,39", "124,688,197,890,81,889,964,780,132,168,375,394,129,448,782,707,855,188,178,424,660,426,336,62,679,554,451,756,982,328,950,28,736,848,461,767,355,833,805,178,122,825,606,242,34,768,902,771,325,680,234,882,2,546,686,857,447,273,658,148,740,266,701,228,727,120,873,561,48,254,344,235,187,497,572,309,818,314,68,569,63,426,581,548,282,643,250,809,564,778,866,59,634,181,812,511,20,983,229,863,95,66,242,167,244,699,143,905,436,339,59,885,773,921,627,990,699,278,236,151,571,645,159,389,315,108,988,412,313,988,244,410,947,150,821,733,341,81,391,337,644,908,249,707,945,92,631,485,567,848,455,288,369,41,541,11,885,581,119,649,44,410,52,828,831,752,88,428,61,331,226,819,954,168,122,351,451,28,217,611,765,555,20,224,789,961,819,26,141,245,169,893,242,463,890,165,956,695,807,78,359,593,596,679,112,987,666,302,731,8,629,414,855,424,635,387,13,844,441,51,827,698,689,148,879,552,969,931,492,834,932,533,511,112,100,628,756,412,61,191,689,781,82,186,878,335,895,621,610,280,789,765,626,138,352,512,730,588,537,865,334,191,190,11,419,798,612,41,235,251,85,198,585,265,316,649,73,44,661,424,807,328,783,461,478,461,889,160,150,954,48,325,80,569,666,987,762,203,990,74,907,221,499,495,215,412,806,831,820,171,767,438,866,305,488,597,605,591,34,645,332,434,975,294,128,919,851,505,881,103,57,151,285,874,74,598,238,735,191,757,286,988,33,526,677,263,119,486,163,381,667,374,294,449,20,843,507,210,321,174,244,222,804,109,321,268,846,848,167,301,982,2,44,346,486,159,657,937,741,815,334,581,679,815,556,5,285,199,420,503,926,584,697,9,818,887,110,895,756,917,707,560,886,484,947,82,369,500,822,654,527,650,636,148,277,486,430,332,866,733,358,615,518,443,209,730,810,30,220,499,596,839,319,123,498,975,403,207,62,157,759,373,657,386,522,938,583,734,814,319,356,96,3,35,308,382,427,710,632,822,614,418,897,543,491,975,800,160,672,902,383,545,8,272,455,608,941,111,279,129,432,819,483,30,970,502,568,29,405,675,689,179,510,907,737,241,775,163,271,374,276,871,444,511,557,54,626,396,343,261,653,707,458,359,785,561,671,180,226,927,59,95,751,987,94,631,746,137,163,29,912,555,847,643,239,703,238,699,563,587,677,746,627,196,496,162,602,154,85,636,155,27,843,955,506,681,534,282,236,643,686,544,904,439,627,195,421,162,794,702,60,212,837,510,32,587,27,198,24,105,685,483,841,390,783,466,10,974,335,339,851,481,415,944,734,16,68,552,55,476,152,950,185,172,968,126,840,772,598,932,224,543,781,505,834,462,796,23,99,587,985,659,230,43,340,526,276,518,778,423,617,193,859,864,172,42,788,519,527,495,854,917,314,290,357,379,259,977,99,430,849,735,22,738,552,491,597,476,207,391,933,645,526,922,889,868,848,210,873,660,828,98,319,79,465,935,832,674,453,72,658,348,929,411,778,374,381,566,448,818,906,402,342,424,874,416,142,880,411,940,908,753,420,348,429,952,629,566,365,37,574,145,891,244,471,335,796,532,467,476,348,351,786,620,536,290,554,108,698,889,371,634,889,168,379,40,746,950,195,717,439,580,25,923,805,600,840,596,298,33,387,322,445,676,446,894,315,782,322,420,163,587,822,512,328,623,680,766,575,269,419,527,3,553,589,248,483,127,49,886,142,567,540,147,969,801,690,958,192,238,574,848,960,137,768,60,129,395,962,975,531,284,152,870,204,543,889,15,476,465,101,25,262,207,982,482,44,491,521,485,639,304,99,241,37,685,42,193,551,408,662,923,167,314,813,817,694,727,442,234,917,23,84,901,283,20,308,492,533,628,339,111,518,84,16,578,0,180,259,815,715,387,273,164,569,633,769,594,166,660,540,134,29,296,557,786,614,682,330,705,249,36,371,492,441,602,441,478,796,164,794,43,561,914,289,238,162,55,605,769,511,192,874,440,966,26,203,30,686,54,799,511,712,941,852,516,758,339,462,320,590,872,427,833,170,41,794,703,13,704,181,218,673,655,633,957,87,382,533,601,616,172,18,225,293,274,126,381,73,798,724,237,770,424,646,174,396,667,63,318,776,483,33,803,740,386,657,270,369,680,125,369,906,665,102,342,967,492,255,2,553,991,288,726,649,615,721,625,294,969,803,436,65,895,638,231,344,854,942,778", "397,805,183,591,95,91,91,5,882,606,856,319,921,773,243,487,416,26,192,563,843,95,642,826,121,255,44,350,990,343,618,549,124,244,912,631,473,273,257,581,166,886,556,55,826,73,301,404,317,769,963,347,352,796,173,832,764,872,287,924,384,850,737,609,985,808,528,822,72,77,614,805,86,433,371,958,962,545,991,41,620,679,505,172,485,110,82,20,567,202,428,302,94,710,697,93,672,816,453,336,867,29,76,371,540,854,315,710,705,546,418,876,604,73,854,676,687,729,86,875,210,773,117,954,315,250,747,682,560,905,895,320,687,204,672,323,775,112,901,912,951,448,447,777,282,673,366,954,291,581,211,400,661,733,45,974,191,31,295,794,407,181,994,454,592,984,624,924,339,412,358,313,805,73,269,535,212,60,396,90,864,908,837,524,895,903,135,691,853,74,178,151,544,139,340,840,24,604,797,740,522,19,619,490,384,186,405,108,311,581,397,679,666,586,690,210,295,782,456,12,498,212,596,556,883,969,697,490,969,641,632,5,905,790,990,685,300,521,245,887,622,172,387,558,822,158,796,218,640,205,809,162,895,241,809,880,542,471,239,696,812,283,397,445,83,364,413,785,602,48,799,383,966,648,121,305,922,619,998,59,445,655,526,645,333,239,273,505,262,159,246,760,914,181,124,417,306,503,473,796,461,729,940,502,882,423,723,485,873,896,895,392,103,929,985,747,697,707,454,687,404,879,77,562,985,781,96,336,219,569,121,503,718,510,80,271,150,18,848,257,968,402,778,391,804,821,491,263,522,703,74,360,509,674,273,148,997,955,55,827,488,714,893,219,479,167,246,498,745,722,475,420,961,349,680,901,732,223,13,159,574,770,988,203,845,426,81,645,570,234,588,793,53,825,179,2,654,644,437,583,408,133,14,731,61,481,41,883,442,407,427,999,152,481,936,422,63,520,626,859,435,113,237,7,312,300,495,604,339,903,673,989,383,179,984,993,266,911,494,541,190,377,849,37,800,574,846,129,270,726,626,928,409,657,89,270,219,529,121,919,76,593,933,879,125,91,604,568,635,674,499,548,808,107,261,40,511,772,861,21,526,266,784,78,396,516,750,723,241,72,527,88,442,36,903,116,464,240,25,706,641,416,323,288,302,600,939,862,676,980,794,909,499,579,215,678,609,161,743,171,573,267,921,558,6,551,593,23,45,821,994,718,726,216,608,974,368,629,615,860,429,904,82,836,491,606,951,570,520,289,331,749,564,617,663,382,381,745,16,931,284,890,605,153,793,198,256,866,96,34,986,542,665,561,725,6,987,846,688,47,124,843,386,795,305,964,502,292,855,423,933,878,22,488,51,877,404,165,80,666,929,287,315,745,271,668,606,501,112,216,205,846,982,155,698,471,529,387,777,140,791,504,655,328,807,179,621,967,63,967,924,234,457,469,521,563,930,3,2,139,882,114,147,428,913,420,265,457,933,566,451,796,267,297,363,937,207,826,540,508,632,936,997,390,58,484,926,819,475,527,888,399,991,498,521,231,449,789,839,251,99,778,658,259,714,749,162,599,917,498,308,568,904,155,734,898,492,770,480,287,929,163,689,355,129,988,67,689,789,455,495,676,755,162,714,718,501,299,3,597,208,724,519,48,430,881,131,773,709,776,104,559,841,124,354,987,920,185,215,932,597,221,764,36,268,279,94,218,760,863,295,829,136,109,479,839,546,486,455,802,278,243,305,122,570,513,358,81,900,340,792,866,915,955,860,409,396,765,132,569,920,647,588,104,753,457,398,682,514,796,653,100,521,472,901,757,317,632,597,573,704,320,964,722,554,741,280,552,834,846,616,105,895,920,571,503,60,293,821,108,684,763,202,111,991,350,685,206,204,840,219,47,123,860,604,446,458,400,37,259,873,974,877,865,488,414,646,825,774,498,492,915,437,696,446,536,180,0,674,427,610,449,92,530,892,965,152,979,462,972,46,351,880,913,476,254,785,536,562,348,860,194,603,151,978,948,221,140,72,928,879,862,293,131,363,877,176,913,537,149,699,397,241,386,717,397,370,830,940,428,63,114,185,352,86,363,302,3,582,727,369,159,546,324,322,309,589,232,515,358,180,994,224,378,842,921,556,955,606,162,231,270,516,113,414,80,593,246,102,963,30,408,667,957,966,960,808,957,990,632,409,998,418,850,488,276,951,755,400,927,861,796,447,615,53,869,357,429,901,715,984,478,658,663,292,450,125,78,269,823,848,853,132,943,149,920,266,271,657,495", "234,386,639,23,307,873,823,718,320,39,300,251,428,327,161,572,881,244,325,334,232,772,638,456,856,233,246,958,95,891,666,258,356,457,293,520,961,834,184,895,517,66,891,840,92,385,897,658,489,612,474,928,649,768,275,536,682,424,278,607,917,4,760,190,263,206,88,916,595,834,892,521,717,268,721,634,887,461,189,629,611,534,367,673,487,493,281,281,926,637,360,594,518,103,685,259,162,829,709,250,791,368,648,986,319,956,533,217,582,146,415,368,639,454,349,325,484,481,399,873,827,54,738,180,317,347,806,466,519,594,746,849,781,740,711,398,921,258,222,856,895,494,255,421,315,295,458,618,596,184,884,772,530,441,303,927,280,920,714,252,599,706,811,509,517,983,849,918,798,941,415,885,431,246,586,894,57,612,227,876,957,590,106,826,272,269,64,479,365,956,705,399,893,760,811,937,818,166,512,953,457,987,846,727,574,888,365,879,870,666,249,82,749,266,432,531,379,396,238,343,3,800,613,977,995,86,55,746,452,743,812,622,455,173,411,312,648,867,559,497,522,333,943,8,189,338,202,396,435,794,402,556,600,618,659,993,786,10,816,283,725,176,404,518,651,376,537,776,812,532,902,613,463,664,871,307,728,313,664,308,449,509,969,297,820,63,494,176,399,949,281,886,345,803,165,757,704,485,643,933,316,860,890,991,276,716,128,628,743,13,378,512,497,911,157,649,120,67,584,404,407,681,382,608,527,597,202,254,32,676,237,793,520,513,477,522,685,136,239,420,829,223,865,472,731,71,312,243,523,700,191,584,677,173,455,6,391,949,829,630,693,100,384,435,19,238,267,384,979,908,76,729,688,175,188,639,134,692,215,141,224,360,80,948,208,188,181,368,295,376,70,702,767,37,219,534,182,885,36,775,713,581,177,972,780,110,304,148,272,238,692,790,830,347,157,462,74,549,485,132,924,666,884,1,509,290,146,762,898,293,670,62,182,406,512,32,434,447,484,562,387,797,895,614,586,642,360,660,906,28,782,423,127,115,433,308,562,534,207,468,278,869,807,757,371,74,358,489,192,233,10,487,642,168,107,618,250,61,567,247,445,454,433,521,643,297,108,389,586,690,435,260,642,555,24,653,746,651,665,265,624,118,331,806,416,392,711,208,879,555,122,602,97,496,913,981,559,211,480,331,539,411,977,672,942,950,751,154,373,157,698,771,732,70,858,364,765,297,921,818,490,566,548,9,96,343,926,289,754,267,309,828,356,107,273,460,520,32,839,497,940,443,973,811,234,651,907,353,56,591,202,640,727,908,815,910,665,670,873,932,172,784,607,606,197,121,648,855,561,242,668,622,229,409,473,475,156,620,337,870,227,695,280,669,365,143,702,929,445,541,313,919,495,718,879,880,185,447,208,103,809,937,639,98,288,24,934,699,218,296,606,379,553,583,377,455,702,687,703,534,300,28,53,459,833,711,761,204,186,632,603,846,282,352,482,449,735,493,451,33,630,422,945,101,913,488,659,903,591,573,306,346,59,566,377,314,709,979,835,862,132,721,637,617,426,531,956,304,175,779,941,588,242,869,152,972,628,975,292,648,289,583,266,30,540,58,36,195,854,193,927,365,371,249,282,557,666,965,559,518,159,705,984,62,32,60,896,33,463,439,656,543,171,315,281,389,51,579,710,54,819,299,304,48,543,384,243,149,89,891,223,363,87,144,981,224,830,546,486,504,337,196,736,53,700,914,712,297,639,624,343,714,122,629,588,692,486,750,284,838,7,616,442,443,462,378,984,541,487,141,767,421,166,819,404,778,424,353,802,427,944,86,32,882,48,973,257,31,449,356,822,909,100,63,493,799,271,8,109,999,470,577,246,578,255,44,807,934,328,733,395,342,153,715,903,665,77,209,323,885,774,302,725,169,28,284,146,987,132,773,165,161,622,894,814,40,259,674,0,896,547,259,136,216,115,738,510,861,907,835,738,103,503,235,487,468,838,800,872,330,738,468,179,317,390,177,588,348,44,883,939,812,347,998,163,528,351,803,759,525,789,824,44,972,503,445,627,497,651,794,620,320,39,248,842,347,554,432,117,56,113,969,563,828,845,118,581,469,570,175,703,746,802,167,766,865,744,944,183,932,616,923,859,599,265,366,224,267,271,786,831,687,527,809,163,366,466,794,714,628,290,160,116,312,736,326,173,584,858,884,115,675,983,717,745,822,209,930,606,230,279,711,871,161,739,194,60,488,117,457,92,339,728,909,515,829,300,145,376,892", "251,809,333,84,739,829,41,752,215,836,833,534,881,973,238,524,196,138,521,992,134,433,451,643,763,932,22,540,308,219,542,558,80,796,545,744,306,872,428,915,95,312,167,881,109,740,728,485,655,73,515,375,159,611,880,522,154,123,706,848,685,689,379,828,158,259,76,933,823,265,292,716,914,113,306,318,662,731,11,734,456,809,757,522,176,583,3,812,109,518,814,546,771,166,274,358,960,761,691,599,206,323,153,409,202,160,233,659,675,785,200,287,570,753,147,422,861,23,206,237,707,768,433,647,857,500,520,548,677,808,660,863,650,662,876,656,763,110,36,840,933,504,699,838,89,474,10,61,508,796,781,63,166,768,752,373,189,459,461,103,79,790,799,961,109,123,268,193,678,848,617,47,352,132,464,225,58,147,845,715,360,424,733,899,900,488,771,302,631,579,861,813,638,883,95,860,625,167,41,282,979,785,49,926,415,236,579,498,195,696,774,105,494,16,434,58,841,634,143,380,680,987,911,858,824,948,554,10,763,581,680,279,345,897,622,886,468,214,686,535,799,179,635,737,671,521,110,736,561,197,207,551,738,583,211,510,661,569,515,439,3,241,432,982,409,314,296,992,221,828,227,275,113,289,959,126,56,38,24,730,292,408,550,565,164,77,866,830,762,897,24,233,118,351,616,524,824,768,483,455,963,61,974,682,585,381,651,617,202,330,107,54,295,5,37,779,325,943,745,71,861,756,369,588,223,930,682,387,419,377,911,527,560,416,814,766,265,861,934,864,275,17,62,783,823,140,244,54,837,151,536,117,719,563,850,144,645,956,660,796,247,657,379,604,185,143,712,670,898,531,154,816,43,347,655,125,508,262,990,505,935,53,434,85,478,452,859,822,27,858,63,826,667,117,839,38,836,641,557,900,614,593,466,491,809,18,448,198,437,282,632,462,770,180,871,883,473,143,341,991,822,704,618,188,721,883,784,634,328,852,562,644,161,706,777,976,211,603,904,931,65,668,938,906,659,637,88,639,700,816,622,188,306,93,718,956,459,711,927,670,142,333,628,800,453,573,374,471,267,968,325,991,556,651,536,356,556,551,132,179,850,672,632,348,846,490,147,962,163,573,917,440,698,600,706,29,485,500,528,355,599,202,114,438,51,488,715,142,104,407,997,966,984,26,763,146,77,833,391,631,681,126,38,751,425,200,478,784,17,9,61,154,485,449,866,638,802,600,426,905,779,411,463,559,737,440,506,90,59,814,938,234,225,937,483,934,734,861,663,506,524,301,724,845,278,435,422,384,626,803,616,290,602,297,52,370,601,633,221,823,381,451,628,969,133,297,390,689,395,243,872,629,143,71,809,53,587,1000,489,695,555,218,434,152,576,961,876,129,369,265,808,996,740,933,3,11,898,73,634,279,888,744,455,996,637,382,637,347,349,464,613,942,824,429,6,951,382,22,877,526,74,128,640,190,30,112,107,526,732,309,93,289,524,871,81,879,140,691,291,948,638,576,976,131,310,724,497,538,978,551,166,218,504,249,695,156,178,114,520,811,380,173,337,345,158,930,840,187,447,963,634,292,638,759,882,811,86,799,992,168,832,703,269,2,875,875,472,543,400,931,405,240,679,229,354,10,324,101,168,557,243,456,337,644,630,292,366,809,656,995,603,950,411,486,501,665,691,747,167,167,304,262,705,561,811,472,660,709,475,745,48,167,446,285,97,429,839,400,439,873,275,263,699,339,464,698,272,726,45,505,290,902,246,458,745,653,300,354,165,326,443,355,272,47,632,764,540,499,389,767,142,928,142,471,638,264,84,382,965,803,555,590,138,824,113,58,637,152,894,249,950,279,41,21,181,791,65,727,52,881,543,325,20,952,706,533,397,967,382,821,569,28,574,919,954,56,428,901,474,740,294,998,351,894,884,232,210,854,141,250,33,986,199,33,574,698,815,427,896,0,283,735,979,642,689,588,156,50,959,897,54,247,295,824,553,905,583,605,740,203,226,46,831,605,405,961,609,473,397,410,329,834,99,110,834,834,229,775,463,856,946,8,869,807,372,294,35,463,94,576,227,305,141,24,640,669,101,948,770,669,432,977,514,502,676,94,976,761,679,819,438,903,982,848,676,756,269,664,301,611,123,366,121,463,359,782,350,457,754,474,344,547,41,543,84,242,395,885,858,686,236,716,886,737,294,712,316,940,562,870,746,782,799,450,712,864,997,329,177,830,714,327,825,524,109,833,600,821,453,368,563,463,256,275,509,291,408,995,932,981", "503,863,991,945,685,512,843,608,351,27,588,247,201,853,325,689,801,246,32,908,654,84,847,675,68,478,526,146,149,92,873,223,109,877,982,494,987,927,558,534,964,580,10,326,503,738,238,165,365,86,874,641,258,461,778,98,572,117,789,700,955,70,806,336,362,985,758,101,302,396,833,735,73,30,736,588,33,478,142,493,994,247,374,770,369,55,902,737,457,375,152,139,340,385,662,916,158,246,553,957,339,571,233,871,670,679,190,115,677,757,127,723,335,846,563,208,397,717,612,232,101,158,96,46,369,550,37,622,374,774,941,419,522,132,987,295,950,127,699,389,467,625,439,547,203,167,240,725,115,244,227,243,440,731,83,113,683,20,765,292,33,292,462,801,818,700,883,718,505,442,745,677,945,506,361,110,334,42,832,553,633,129,731,39,736,106,257,876,759,820,101,164,403,202,69,684,696,368,440,609,960,505,675,530,925,978,27,365,193,320,489,109,324,628,716,754,698,62,396,121,542,429,312,196,304,122,356,857,422,575,926,692,555,171,80,349,25,625,151,527,462,193,203,853,367,254,368,436,522,646,399,38,458,139,888,424,603,442,6,221,879,384,645,217,446,970,524,88,508,257,563,94,991,787,419,636,953,756,328,983,298,315,693,352,169,687,342,942,915,638,684,349,204,608,390,992,739,80,116,873,181,384,143,980,699,570,643,303,4,861,90,97,493,810,926,191,414,852,65,199,573,811,805,960,73,977,206,382,776,244,250,683,273,948,584,33,636,906,691,886,556,645,358,648,316,511,853,973,998,728,146,333,455,465,487,809,794,213,130,811,359,172,273,188,768,782,177,116,352,311,519,339,186,997,276,866,112,766,110,922,158,796,279,669,268,136,201,974,193,353,979,108,796,419,234,292,618,859,661,918,787,691,659,842,211,416,494,396,391,263,263,313,909,64,440,714,495,587,180,874,559,449,814,211,418,649,208,176,529,854,830,283,587,825,293,960,770,797,954,837,73,192,762,389,772,809,627,247,491,569,211,418,469,186,995,981,889,414,930,909,561,765,840,480,874,999,911,291,814,977,858,838,498,167,665,494,135,47,602,209,275,643,448,469,436,445,638,407,568,438,638,543,839,640,254,180,350,971,47,768,117,91,985,603,211,725,475,568,910,79,970,259,221,113,692,609,876,115,940,944,288,1,915,85,773,147,11,294,328,425,438,146,727,101,994,980,262,4,512,194,430,615,403,308,18,242,327,357,576,720,330,533,110,464,802,642,512,463,95,710,830,711,418,378,54,592,569,669,837,91,699,860,717,63,27,448,610,580,524,5,509,942,487,124,609,450,610,6,807,122,909,491,460,354,987,317,733,355,90,929,535,919,378,761,109,607,775,652,653,647,623,843,665,682,689,423,403,256,240,304,371,392,412,242,405,503,614,243,199,954,594,807,540,536,370,265,113,75,154,913,892,665,579,303,372,894,608,40,947,973,934,262,788,600,637,306,613,689,731,810,962,965,669,853,47,395,256,181,919,280,751,675,795,177,81,705,233,531,449,718,27,285,482,19,756,401,898,925,909,157,351,601,545,464,713,34,401,955,147,429,91,154,583,993,491,986,580,505,946,63,765,149,292,193,308,780,861,396,433,551,577,804,861,982,910,34,468,664,37,708,541,412,216,251,110,628,588,479,128,793,216,325,380,263,8,396,739,454,263,318,435,256,369,733,348,256,783,81,627,748,313,633,600,770,824,428,520,488,803,194,885,809,28,447,999,802,565,156,528,117,675,524,98,773,670,790,612,208,933,380,416,322,777,403,33,833,691,779,346,419,174,30,373,972,684,512,661,644,797,584,754,767,320,567,825,461,843,259,248,709,949,283,236,480,115,50,381,849,734,174,337,707,901,551,153,935,824,310,439,112,464,951,998,229,468,509,270,143,610,738,601,568,352,845,694,17,715,610,547,283,0,362,104,420,857,79,307,301,131,441,134,449,323,469,679,87,58,224,532,819,472,781,414,103,189,961,477,354,215,607,467,799,429,845,307,556,132,921,78,830,615,863,728,746,286,388,397,871,429,638,65,966,118,76,822,366,922,694,268,316,908,453,483,715,836,605,13,918,52,682,447,363,695,710,431,767,878,299,534,774,115,417,374,772,966,21,202,789,964,42,914,126,550,778,530,448,246,92,66,919,838,365,78,269,220,606,888,782,403,701,740,16,870,652,609,129,504,873,39,393,256,542,831,602,199,3,323,127,408,430,761,711,678,572,383,863,623,545,767,142", "64,329,644,621,403,3,605,417,191,625,591,725,718,399,824,289,835,379,573,948,308,700,480,894,682,758,121,422,461,822,437,139,312,67,986,753,200,465,78,393,381,621,208,717,618,750,493,363,450,979,142,77,756,454,604,359,287,24,925,314,953,277,211,990,114,362,419,355,743,288,925,431,424,722,926,865,138,619,914,821,16,998,257,36,884,411,722,505,495,301,691,326,701,221,357,528,326,653,793,513,575,208,86,781,455,130,990,211,142,95,695,757,947,567,544,201,305,196,391,409,828,345,92,987,230,366,820,947,519,720,446,771,669,567,509,683,849,327,818,730,908,131,88,407,131,474,688,352,939,939,515,208,210,664,939,453,502,498,22,738,529,146,754,602,956,635,232,80,109,741,992,929,993,828,565,944,73,405,626,634,460,392,456,430,284,307,431,571,143,212,29,373,658,714,508,928,249,389,245,643,790,645,770,459,372,377,756,336,499,163,251,760,613,960,301,84,906,420,642,379,3,147,535,772,908,739,622,660,837,448,327,884,949,280,916,980,87,962,670,652,422,725,131,545,311,321,695,386,757,698,896,610,97,590,271,370,405,471,917,571,976,776,215,877,391,102,829,380,450,326,346,489,953,479,532,10,877,357,311,715,487,821,907,395,869,669,410,990,549,36,882,684,586,833,288,200,629,896,750,588,658,964,634,926,851,791,119,947,637,464,562,103,131,708,748,495,82,316,880,40,801,872,679,551,331,457,288,227,134,452,250,501,221,683,411,705,695,345,610,812,907,545,404,293,992,161,741,845,273,110,30,831,841,734,249,306,285,38,208,804,691,8,189,224,315,325,553,492,765,786,415,855,998,874,828,458,576,511,809,397,705,194,234,6,684,14,728,652,800,861,7,126,658,726,640,569,939,850,105,369,923,994,516,579,472,244,966,344,824,399,623,516,445,723,467,72,732,609,286,554,685,378,152,607,581,882,944,366,111,715,422,216,61,824,387,613,892,437,526,897,822,223,597,11,834,913,150,823,948,479,180,114,221,879,835,338,913,798,394,591,92,642,902,892,594,811,790,339,808,836,770,939,269,353,561,787,176,810,765,222,377,715,702,108,235,530,86,226,284,186,128,591,266,464,148,353,586,901,525,832,763,928,344,730,55,306,932,586,405,567,430,712,990,925,573,109,950,705,342,616,341,934,5,614,287,779,367,681,343,622,137,268,359,929,505,610,367,487,171,275,686,352,526,991,740,530,343,694,809,591,944,471,944,354,912,769,388,802,586,347,623,921,138,162,457,383,335,102,600,34,560,706,749,222,532,53,806,143,534,658,450,1,419,458,700,346,880,755,624,217,775,438,111,908,451,490,866,42,129,686,925,16,914,162,872,180,86,269,197,676,118,809,58,233,396,482,380,241,825,807,96,311,700,778,500,443,444,427,953,144,118,128,758,527,997,203,934,171,296,539,306,732,926,15,627,242,677,821,379,902,856,60,529,877,602,275,216,669,253,181,983,50,861,368,479,886,780,845,771,854,89,351,37,790,694,547,202,515,261,236,458,595,832,309,703,220,736,641,739,834,64,675,154,758,955,78,323,484,585,944,684,19,993,923,975,90,53,859,630,739,865,252,561,341,669,965,602,200,204,290,145,77,617,545,432,346,787,128,642,898,97,608,387,542,171,940,805,252,238,602,652,986,264,703,803,76,334,605,158,629,363,751,859,100,659,14,656,74,963,652,808,181,863,551,422,185,381,836,507,569,351,918,279,786,964,896,626,261,994,768,428,97,601,218,931,165,568,908,460,551,208,923,150,59,197,198,934,234,496,547,438,28,108,924,62,949,904,106,73,628,574,577,696,942,780,391,901,943,299,219,354,764,214,50,226,131,910,65,303,540,373,733,388,492,957,110,850,702,226,273,326,860,225,52,859,933,32,572,393,218,431,340,845,24,77,609,387,449,259,735,362,0,641,339,731,104,361,504,694,423,457,730,875,325,496,23,905,581,266,934,360,773,611,388,733,778,438,361,855,942,713,802,883,399,411,18,234,384,887,488,605,615,399,305,969,280,966,93,602,99,298,527,834,994,896,523,84,430,56,554,123,811,205,754,641,254,643,678,516,88,618,531,646,10,5,181,100,720,819,951,254,781,101,616,619,952,54,911,698,152,942,325,437,613,933,928,823,732,43,281,944,500,20,955,682,806,489,156,204,604,835,781,970,776,975,29,252,326,792,850,837,864,461,574,748,657,588,24,890,124,877,799,423,303,847,169,250,471,135,886", "990,152,570,755,955,769,449,928,265,777,563,882,895,179,653,220,895,251,352,421,458,435,348,462,923,448,854,175,576,179,215,155,978,78,328,187,639,908,404,971,727,963,924,839,315,618,999,161,724,608,851,912,193,416,112,224,292,637,81,965,560,779,673,259,181,990,350,963,791,214,402,993,327,457,610,866,375,817,255,428,740,888,916,871,319,619,870,500,93,341,426,515,757,834,748,422,25,467,648,41,408,484,122,411,843,595,148,49,480,31,711,224,764,68,427,516,126,767,952,743,166,524,606,184,711,576,219,302,703,247,867,958,275,646,566,293,381,97,969,348,122,407,981,156,663,618,978,5,615,892,519,777,21,488,639,673,286,939,321,701,279,131,459,420,524,996,176,81,447,21,578,163,780,293,349,897,426,206,949,871,918,587,852,397,265,729,173,888,118,840,943,640,251,986,150,935,960,868,615,406,177,105,568,890,372,28,649,39,173,201,19,340,296,952,891,927,216,786,9,948,608,37,876,863,804,454,717,630,727,912,612,482,666,440,323,252,374,501,184,685,80,639,832,159,592,755,382,267,855,271,875,499,47,945,431,486,781,475,111,527,566,890,700,895,489,543,980,877,632,999,221,135,965,560,514,437,43,3,316,35,443,246,703,884,307,941,606,911,37,173,947,885,727,484,85,667,177,331,498,330,530,967,281,994,448,139,846,534,270,85,678,748,414,100,396,359,209,103,246,464,592,55,687,376,470,449,514,419,992,575,373,23,575,251,410,171,867,429,877,661,340,230,412,482,320,156,865,727,817,55,840,238,794,979,161,524,452,726,681,815,556,577,968,898,611,764,635,833,188,173,53,198,988,26,874,702,373,862,802,197,101,847,561,619,188,914,515,251,646,476,197,488,246,925,661,528,139,921,846,797,609,155,615,450,657,417,272,144,238,272,606,59,264,506,265,70,197,735,483,786,316,398,620,95,704,976,101,26,620,933,599,382,211,644,390,576,353,822,394,868,387,782,882,177,550,744,850,723,151,754,106,901,298,905,806,71,265,880,629,238,217,43,807,661,319,180,306,221,733,129,705,765,657,830,353,55,129,25,781,640,976,543,222,346,992,751,484,215,282,978,344,902,650,87,143,904,576,553,212,612,599,571,513,397,514,33,759,111,567,649,631,549,731,226,336,237,976,95,15,323,391,762,680,619,660,671,246,65,3,547,338,938,948,673,717,937,513,369,622,476,6,624,862,341,342,969,420,244,60,902,407,998,940,442,858,32,517,437,695,203,417,109,242,593,578,277,310,39,529,647,96,393,500,611,851,342,326,561,123,968,889,33,287,220,388,139,998,745,661,72,51,738,575,780,898,151,934,696,647,921,397,543,840,797,312,53,313,382,626,495,772,230,768,962,912,328,643,316,860,201,713,325,152,166,935,58,9,578,939,800,847,376,265,411,346,944,491,857,475,82,60,76,885,832,865,504,756,144,336,829,407,494,279,569,625,895,251,22,237,66,676,88,209,494,721,460,370,368,732,227,540,77,9,429,319,405,310,58,367,420,934,889,656,411,699,850,606,763,53,313,349,504,55,500,13,795,829,20,980,520,675,694,952,267,574,376,546,590,228,371,517,540,366,637,789,948,108,829,965,16,124,758,186,190,387,418,856,438,201,580,415,571,617,352,293,536,743,963,859,5,309,682,191,683,994,585,65,214,832,711,424,216,387,638,408,695,536,395,531,293,880,320,823,484,649,12,737,43,948,527,56,9,413,447,428,107,420,175,78,503,940,713,524,246,969,76,99,186,538,693,213,814,730,132,615,190,523,827,554,334,484,757,223,458,804,136,391,275,255,595,525,793,57,818,160,592,683,390,339,244,237,278,451,690,859,376,852,951,92,64,315,930,740,541,97,878,951,433,586,937,14,190,193,683,672,959,839,352,368,825,465,869,558,755,385,509,273,92,136,979,104,641,0,707,424,890,554,881,46,936,755,730,564,62,936,537,21,285,885,531,655,317,476,600,784,129,927,198,316,620,6,831,102,440,315,180,976,468,572,759,659,10,774,500,212,757,347,181,457,641,107,81,940,269,60,328,58,285,109,297,307,572,468,94,956,674,153,244,762,702,117,55,722,733,800,687,884,525,445,284,577,927,991,652,290,539,830,461,524,991,903,463,37,353,35,501,165,616,830,777,111,837,465,706,542,42,746,659,247,738,384,826,838,178,639,656,864,296,234,143,717,312,51,340,578,163,278,434,915,265,364,363,191,529,397,91,839,804,13,484", "295,131,761,459,525,862,123,129,690,4,882,884,656,252,595,44,798,173,171,350,899,516,313,764,435,21,836,775,434,553,450,787,105,854,484,645,443,668,172,922,216,737,153,600,24,518,171,234,496,431,81,614,392,968,726,431,573,133,234,228,385,92,991,913,564,851,105,509,89,916,430,442,595,879,325,646,953,349,878,819,366,494,62,114,589,590,804,47,508,728,79,693,428,218,726,360,770,29,611,486,235,514,789,2,646,244,568,786,741,715,82,415,381,580,530,732,595,979,2,944,992,145,894,852,779,937,823,419,416,3,997,648,858,708,318,175,909,219,710,504,448,897,669,734,753,111,557,565,300,834,642,856,11,982,934,373,893,673,794,672,728,224,803,832,776,604,218,176,785,275,299,649,187,627,811,147,743,831,925,859,765,822,961,486,93,639,170,312,877,341,572,61,547,883,791,25,158,603,894,703,348,895,456,180,200,872,134,670,713,513,329,585,651,650,256,293,209,547,182,510,433,927,229,367,440,370,471,652,306,46,22,779,420,319,878,11,932,457,644,908,375,246,154,240,957,282,848,506,497,388,672,576,204,194,129,888,79,981,263,984,329,341,669,237,568,118,216,354,915,988,227,702,211,124,203,927,633,870,415,186,579,778,871,188,655,492,325,734,448,249,169,123,155,135,538,47,62,52,918,418,541,24,97,187,325,776,474,268,711,54,21,941,204,848,809,81,465,444,502,350,453,950,173,419,965,2,834,428,117,51,675,392,374,500,88,793,756,917,717,795,305,150,806,138,185,359,6,17,560,313,168,879,607,811,388,536,935,999,945,428,435,186,881,271,52,810,897,904,931,623,94,790,348,340,525,23,113,762,85,200,981,450,650,826,154,43,907,395,112,525,986,541,603,448,987,398,243,84,842,559,969,899,615,41,833,286,742,698,454,2,699,841,119,966,865,38,489,759,51,118,795,572,857,424,396,969,757,122,592,538,123,798,275,638,92,133,499,848,913,469,118,633,736,266,732,129,729,979,577,142,848,241,622,797,167,23,958,674,215,676,326,96,28,384,851,986,607,322,775,509,273,870,783,299,536,762,715,233,11,909,627,306,959,448,775,428,606,37,107,504,485,85,180,590,740,288,862,861,20,245,401,806,582,133,201,257,935,346,58,741,259,312,454,894,812,135,294,35,152,328,156,848,928,478,847,212,877,306,593,359,184,183,949,521,555,749,96,813,902,266,50,618,682,225,229,77,835,196,340,458,506,159,816,782,646,234,606,118,272,825,178,862,635,448,615,508,223,210,764,694,379,136,270,828,523,304,153,964,826,559,670,496,702,986,152,385,497,436,86,343,829,530,835,136,986,387,788,783,676,812,242,526,949,974,711,306,456,955,188,469,355,482,803,517,631,886,41,406,19,766,739,493,823,144,436,217,586,793,432,868,795,74,190,409,6,447,232,607,340,669,445,641,931,969,444,453,838,451,136,379,354,645,899,886,108,845,852,620,445,493,401,609,559,909,720,872,811,426,385,759,645,518,902,622,816,544,908,818,326,959,304,314,243,667,395,113,496,96,194,991,467,449,827,470,967,824,621,18,936,53,826,508,492,898,499,266,835,170,847,940,28,650,525,587,313,41,538,444,856,149,133,658,793,295,414,438,622,459,358,697,579,190,894,22,766,550,916,488,808,340,172,442,184,298,273,463,242,298,115,324,964,979,396,676,640,121,177,47,721,780,38,941,460,798,40,881,590,415,26,999,303,413,94,575,763,524,774,541,756,465,809,327,391,970,607,972,76,150,852,214,158,66,864,980,200,821,54,64,960,298,344,744,864,994,365,602,77,853,401,711,570,870,43,686,978,334,760,716,495,571,215,591,296,940,99,161,39,708,646,886,247,707,656,704,528,304,693,387,40,924,762,82,955,967,196,806,668,13,38,581,721,759,413,31,134,403,164,530,216,642,420,339,707,0,917,812,790,288,662,731,939,418,920,63,398,617,227,39,671,142,716,751,733,399,100,752,82,405,919,81,832,214,414,171,224,31,773,408,968,621,8,70,970,230,617,749,32,783,956,191,221,592,744,278,943,187,699,220,494,11,20,653,2,542,374,415,55,752,340,382,5,352,408,46,52,304,289,356,67,349,803,913,778,942,534,285,870,744,920,868,155,892,24,465,150,303,660,797,951,956,530,552,892,973,333,214,959,603,346,478,329,860,875,298,238,415,386,735,353,922,683,480,510,660,781,373,567,36,902,150,486,18,404,154,48,888,584,228,976,1000", "733,603,180,536,289,225,361,191,28,392,661,828,742,271,180,789,393,197,259,474,808,521,643,984,164,152,954,634,609,554,566,641,623,645,182,934,812,611,913,229,333,992,839,785,388,815,810,310,959,988,758,329,335,54,603,509,672,690,868,351,787,645,932,289,339,102,767,549,357,350,332,410,49,751,261,24,354,562,585,447,802,279,893,484,180,83,650,347,133,896,285,323,608,101,378,26,777,737,611,633,580,579,844,175,68,982,583,845,959,734,875,696,12,609,630,948,760,225,909,24,467,381,12,805,414,733,53,24,119,813,263,795,389,592,814,445,151,472,629,878,150,26,819,141,380,865,862,295,538,861,988,680,558,491,751,377,865,298,376,949,122,968,136,514,407,915,244,173,661,327,780,433,104,401,594,771,914,554,41,810,556,575,302,814,595,60,538,329,828,78,657,500,771,29,734,282,358,110,606,518,227,159,465,355,189,922,397,736,342,457,878,976,303,859,576,692,606,55,84,443,941,613,635,555,960,670,37,842,86,173,858,535,942,454,67,155,545,462,436,38,532,818,603,175,853,607,156,840,715,795,512,454,886,693,918,163,573,105,942,570,173,765,997,782,990,179,54,92,507,64,86,187,184,868,827,787,348,769,947,928,966,794,316,780,957,218,870,390,86,290,11,682,69,439,451,480,338,963,570,556,168,366,214,215,781,508,712,889,275,43,284,867,145,81,306,319,210,23,343,852,808,723,544,901,911,651,564,777,969,905,706,709,537,392,707,255,695,34,158,740,297,940,765,403,198,399,17,618,920,116,893,903,667,731,90,998,958,61,825,235,74,208,915,674,613,471,37,994,393,870,303,701,161,877,543,685,391,212,94,768,225,302,672,770,430,256,270,783,631,378,51,352,519,420,619,103,203,564,323,857,859,522,381,631,296,514,791,583,811,263,911,933,722,373,100,610,392,678,135,775,854,492,409,205,453,888,571,573,888,426,81,885,543,999,424,502,886,442,208,575,209,26,265,272,277,228,992,593,900,653,329,466,428,792,376,779,751,528,448,541,374,16,249,35,107,137,714,609,733,47,628,91,705,805,143,636,700,89,788,25,559,594,828,684,455,554,908,456,235,546,394,799,239,870,417,772,547,918,298,361,760,20,218,256,888,746,771,645,67,198,74,895,21,446,598,214,586,241,951,461,863,649,48,615,223,279,655,861,142,392,635,328,771,45,489,398,727,961,84,70,426,710,808,861,652,495,545,799,961,434,986,697,999,173,414,755,241,601,763,494,204,505,975,698,29,168,770,494,333,148,297,894,97,637,119,753,914,894,517,797,857,658,980,384,226,404,494,779,56,592,20,984,950,699,863,746,316,198,942,851,13,330,46,104,283,464,796,96,877,288,73,383,549,863,642,921,995,759,326,655,652,638,36,143,352,945,17,747,364,757,962,369,203,674,562,100,627,838,864,239,359,369,973,661,714,224,987,485,813,18,926,516,103,233,180,271,852,293,743,894,790,682,214,969,353,667,588,296,167,552,264,866,818,674,484,316,596,321,27,700,503,239,150,592,832,856,216,738,498,991,600,297,951,17,193,876,270,743,907,800,942,700,96,785,664,373,4,185,582,273,8,110,142,757,27,558,179,229,59,248,42,608,373,339,437,62,423,578,847,289,682,20,564,661,587,712,203,174,709,675,459,172,945,103,735,969,958,283,526,317,952,118,846,133,75,351,67,759,9,653,750,77,181,3,906,301,498,148,194,209,297,681,997,195,822,555,931,157,781,930,976,993,807,599,563,607,890,396,433,275,485,392,487,551,247,775,796,440,433,218,131,520,544,853,279,471,86,723,681,469,259,501,928,242,824,257,439,133,142,352,86,400,772,738,322,482,518,556,583,91,975,745,157,918,857,612,690,306,88,211,304,493,713,115,291,346,398,318,325,138,536,727,932,957,937,155,569,892,115,689,857,731,424,917,0,115,873,440,331,670,309,341,927,34,190,302,710,260,466,440,864,478,829,805,202,135,998,452,233,6,901,231,97,353,964,734,362,1000,19,429,439,224,989,14,588,248,997,273,812,852,8,342,647,585,463,252,993,308,558,674,105,378,184,377,324,154,774,554,386,781,509,614,172,969,524,164,619,368,149,341,223,778,291,691,75,884,837,547,207,267,117,353,593,945,230,435,39,479,316,641,442,528,262,239,97,720,251,327,93,515,313,555,402,395,371,340,762,385,724,579,915,454,189,916,739,319,560,488,538,61,399,342,926,793,80,999,98,125,572,205", "948,77,673,719,474,147,833,462,363,337,74,378,29,181,608,186,843,80,890,862,931,909,153,188,35,665,749,789,146,431,87,820,314,926,112,553,481,310,981,612,496,814,346,121,175,40,826,721,655,850,624,961,980,42,704,446,757,150,851,837,443,848,870,214,190,666,538,872,550,156,980,712,862,299,439,404,166,524,250,729,832,961,607,736,440,713,560,504,392,876,308,211,846,411,378,131,864,428,321,73,808,70,46,339,930,661,996,444,373,733,886,907,646,863,386,239,7,471,677,788,353,494,197,884,164,856,654,299,176,137,512,725,22,785,452,14,211,51,102,401,36,778,753,942,837,37,580,119,50,403,178,166,909,788,801,135,732,194,534,444,52,375,507,824,353,687,398,483,124,166,441,304,56,634,886,746,606,84,744,451,665,116,780,139,969,49,594,961,557,527,548,719,42,499,261,202,905,113,591,931,308,776,530,562,647,379,108,363,105,644,313,86,672,310,208,460,925,148,659,710,578,944,348,120,674,223,21,395,265,503,378,369,146,69,768,516,883,261,800,540,415,476,461,71,548,655,270,501,4,558,430,407,470,634,755,701,884,616,518,573,694,808,305,947,85,206,326,71,470,252,325,774,397,791,606,925,502,418,28,726,479,815,560,935,804,575,182,331,25,939,525,864,735,873,963,203,987,165,554,807,543,435,117,3,304,951,685,806,165,581,626,764,578,330,762,45,389,191,138,6,718,816,538,409,23,932,180,51,971,569,940,490,534,984,543,923,443,785,549,426,926,955,146,11,98,505,728,807,18,392,601,889,396,431,153,527,490,781,51,260,391,645,495,699,972,366,692,777,992,84,551,168,964,403,868,59,545,825,957,594,357,601,326,44,103,330,254,139,584,75,359,589,896,736,344,264,163,874,349,934,168,569,443,66,162,858,842,943,198,329,590,886,469,585,183,104,825,378,514,315,671,503,474,614,622,248,906,667,377,131,609,920,180,399,941,112,106,473,688,33,531,735,483,838,984,351,150,456,729,765,244,202,11,243,259,328,837,335,1000,680,784,36,567,68,906,301,678,690,518,856,833,602,70,37,117,89,127,183,442,920,317,1,285,613,323,389,181,17,88,314,327,708,633,523,234,448,925,529,622,965,447,63,133,648,138,122,108,95,116,672,828,547,459,848,6,758,899,243,592,209,774,127,69,456,254,648,354,11,871,810,724,149,690,77,845,291,461,586,926,829,694,616,619,213,825,611,151,111,23,832,354,994,478,15,65,246,873,787,676,173,145,777,146,244,289,733,322,490,274,292,816,803,949,910,423,497,364,470,299,766,603,491,997,51,393,885,688,164,386,762,727,231,168,711,554,365,589,395,590,934,715,148,884,852,45,793,124,899,349,217,277,622,412,736,724,277,49,429,927,199,645,120,843,197,499,998,344,762,494,29,678,959,753,823,93,329,194,848,873,82,78,663,984,535,881,233,188,546,457,119,290,584,901,625,26,542,464,407,696,816,995,906,920,679,687,534,634,460,982,902,858,443,96,465,418,860,642,195,700,924,616,172,949,268,194,325,776,474,822,570,875,225,434,116,135,740,282,159,669,756,882,424,376,809,918,892,217,267,753,438,509,991,640,853,528,833,880,214,571,515,682,42,727,530,74,941,31,178,456,264,755,567,409,527,723,454,350,872,253,833,823,871,666,652,251,946,81,88,901,642,108,564,91,739,380,789,340,749,616,939,232,513,939,322,549,93,754,920,902,607,743,942,51,236,376,352,500,695,650,986,858,522,61,642,437,970,252,821,932,849,122,456,328,357,210,165,713,123,27,233,744,158,30,220,954,829,494,995,251,984,956,25,573,609,679,322,914,792,749,65,365,18,643,997,717,413,227,387,328,268,735,714,126,471,164,428,531,575,209,76,129,852,191,443,98,991,26,289,45,87,711,100,610,256,824,797,633,965,738,588,79,104,890,812,115,0,598,776,977,578,357,704,890,150,738,950,607,44,412,942,775,797,484,405,83,823,449,422,857,624,180,240,264,532,530,421,590,727,943,432,38,290,713,468,185,308,640,976,123,227,837,674,428,216,547,557,77,258,915,527,667,266,925,346,417,873,228,973,922,828,944,330,552,543,165,130,752,857,139,574,430,768,464,245,846,124,184,972,610,245,426,606,104,539,262,334,411,642,929,519,858,256,550,463,425,188,453,999,98,134,969,172,119,985,924,435,144,12,592,189,701,865,218,304,921,151,854,784,814,580,386,522,642,184,138,879,382,11,852,498", "449,781,802,128,172,221,977,625,463,711,875,531,921,589,937,946,794,186,761,405,734,170,616,482,628,734,678,969,687,249,155,594,596,370,546,777,685,461,722,307,934,521,884,947,628,402,840,630,513,905,547,48,972,94,351,665,573,112,719,974,790,11,528,303,753,523,432,591,745,814,90,917,135,633,281,4,142,524,933,378,699,874,146,473,498,695,757,237,970,271,9,175,694,824,782,197,170,90,426,877,13,102,447,130,661,145,938,955,248,45,28,900,557,527,492,837,615,838,531,155,658,739,993,37,650,95,502,641,954,908,468,639,622,476,546,140,389,793,999,863,881,842,660,851,10,638,58,443,54,215,620,626,114,899,888,164,196,856,635,233,919,808,376,837,483,50,604,505,286,523,822,482,84,42,205,764,663,406,439,658,263,366,858,887,589,152,780,25,64,852,769,224,55,993,855,972,564,927,15,190,591,737,757,768,254,150,185,108,149,366,384,583,834,131,914,795,24,312,360,716,122,569,271,113,552,525,882,445,378,672,135,985,336,17,811,887,419,18,822,257,883,256,138,112,380,465,812,980,388,84,307,836,521,810,980,605,837,791,428,959,863,527,401,541,214,344,106,153,341,933,702,844,798,175,992,290,802,363,722,601,78,607,862,160,896,325,215,618,476,331,887,800,134,176,478,397,738,170,63,937,586,772,180,317,637,554,580,151,720,926,147,616,940,697,435,654,955,259,140,458,917,837,68,618,723,852,439,720,550,353,176,383,145,753,882,633,993,874,484,534,860,72,646,268,487,869,389,372,11,110,319,65,544,49,140,137,535,182,284,658,853,952,725,641,417,611,876,973,884,801,325,924,777,185,24,841,591,745,87,302,660,298,188,211,789,634,989,226,523,301,132,625,946,240,522,37,942,610,464,168,684,655,906,51,191,811,244,349,200,151,177,758,472,205,268,943,992,798,118,633,56,963,218,308,364,133,432,162,311,213,231,324,690,696,653,234,708,353,43,199,801,442,172,244,406,213,98,384,953,786,557,635,864,117,674,806,849,444,176,851,586,385,172,12,999,487,527,749,509,422,848,684,344,189,116,598,678,901,802,218,68,201,963,805,539,443,959,869,440,937,173,520,296,371,677,555,692,3,897,419,231,235,307,840,582,968,624,312,568,844,517,611,448,93,270,618,125,441,228,82,563,350,688,228,546,184,178,931,706,419,358,200,766,245,236,406,794,101,311,777,373,729,675,432,934,826,912,964,45,916,237,127,977,738,771,126,283,829,803,574,834,770,993,866,71,490,309,621,61,367,339,289,642,463,164,432,545,715,618,521,732,4,513,161,35,811,589,67,486,389,162,902,354,860,291,614,417,211,977,599,901,892,377,889,145,363,316,132,249,584,537,261,201,602,923,157,617,16,497,4,710,832,160,411,78,375,959,542,825,710,436,928,625,642,576,863,996,302,267,504,926,179,256,891,141,557,751,180,259,234,870,668,126,444,623,426,283,990,207,178,925,276,11,806,594,365,984,714,957,466,855,726,400,169,647,884,367,434,603,423,570,676,397,594,587,877,989,991,817,51,227,450,998,81,246,38,836,609,415,346,954,705,652,226,910,440,832,46,438,537,900,185,701,398,831,529,513,898,824,502,193,929,879,10,338,175,75,549,231,125,966,788,703,828,82,632,171,266,219,927,673,728,179,782,599,278,710,670,113,985,732,50,7,173,862,55,192,134,442,629,341,515,978,858,663,774,601,258,33,850,582,375,402,168,725,365,719,507,997,750,202,843,843,901,587,583,466,48,236,142,50,370,192,341,90,55,464,955,258,529,740,827,84,258,816,948,958,556,849,20,228,747,517,316,680,489,546,510,487,113,752,231,79,988,584,600,870,9,493,109,141,622,724,959,460,245,365,214,72,910,215,995,287,90,865,926,665,515,806,153,124,97,761,477,145,25,769,152,510,156,307,361,554,790,873,598,0,873,468,434,174,682,564,311,946,374,848,350,486,558,449,669,431,952,171,121,471,256,766,719,289,508,534,196,89,333,141,910,635,731,900,684,425,36,520,387,927,540,270,973,545,379,506,627,176,27,416,294,105,471,696,736,472,41,460,845,24,594,409,806,806,778,321,926,331,344,618,535,115,104,956,540,930,470,842,199,287,358,660,839,615,841,641,761,460,37,720,580,687,568,527,360,333,840,906,274,927,430,965,258,933,997,417,579,265,954,698,941,329,140,321,366,733,814,317,445,607,783,244,675,647,76,331,241,24,992,394,592,191,773", "540,325,137,992,634,373,39,216,671,157,788,869,30,671,121,114,940,560,747,924,609,786,132,304,76,509,195,944,2,405,710,429,936,177,495,872,293,274,357,634,979,297,361,211,772,955,815,955,659,597,966,754,824,91,753,583,266,833,124,672,623,81,710,943,103,691,21,854,632,131,434,586,822,265,14,60,730,974,58,80,688,900,609,26,342,52,883,687,769,762,567,254,459,69,919,148,722,518,850,949,277,336,40,517,485,840,147,23,581,405,328,192,293,941,914,381,456,634,594,55,493,905,203,470,201,352,832,922,728,652,588,605,360,787,594,858,962,602,206,106,982,909,388,274,867,412,95,387,675,23,463,326,694,763,919,808,857,343,126,611,417,736,259,182,242,543,474,730,66,892,438,74,213,49,772,274,993,511,83,572,742,133,242,736,860,571,402,330,849,790,542,241,224,111,802,59,67,870,535,818,875,712,110,445,407,482,986,845,298,874,565,405,367,347,943,769,370,808,22,136,481,589,963,829,345,289,174,236,703,7,562,512,586,897,8,680,761,970,307,306,653,849,786,732,826,775,45,26,249,576,25,782,720,548,141,789,624,273,765,416,466,557,867,607,512,506,942,832,142,979,794,649,709,182,903,772,127,539,307,531,744,29,998,694,809,461,664,203,798,947,484,184,914,989,41,500,684,724,930,400,44,724,809,54,112,353,597,591,126,609,105,762,298,387,62,707,193,190,185,564,532,448,774,969,681,286,658,921,574,847,45,360,661,77,285,348,624,356,159,520,55,80,984,686,894,250,324,194,718,432,582,494,371,155,907,384,935,496,256,843,164,37,240,677,434,261,724,442,503,599,488,237,778,813,120,317,160,547,717,600,767,83,330,345,499,287,324,476,442,64,510,123,388,160,6,589,133,497,874,317,356,891,406,227,390,608,556,243,237,464,607,271,61,98,827,64,323,657,242,84,174,968,371,173,171,55,348,216,863,649,180,446,857,559,222,58,665,393,574,703,127,987,263,891,295,232,75,815,794,488,798,824,626,493,874,722,562,823,468,555,877,753,442,511,618,299,342,205,981,735,121,470,752,62,213,798,727,531,435,100,422,209,865,425,468,716,998,13,900,59,368,249,376,703,225,524,925,387,907,587,263,140,885,18,400,770,328,981,470,940,839,973,874,990,631,237,950,262,291,139,490,502,59,144,972,371,631,374,340,253,983,526,734,878,120,926,216,90,818,409,518,559,515,285,691,530,988,400,129,378,482,829,945,424,394,516,307,392,796,24,162,53,779,775,109,747,852,795,943,831,652,984,353,131,493,687,799,181,226,309,899,188,140,576,37,283,140,698,875,692,770,657,659,644,481,306,789,213,290,559,115,991,535,998,125,880,947,102,586,296,289,932,58,912,574,630,739,262,637,680,970,908,780,31,794,868,207,127,791,365,539,13,534,959,32,520,579,720,309,264,547,998,953,667,304,591,985,545,548,900,296,522,842,988,622,190,895,3,188,21,333,868,384,755,742,543,699,657,821,743,556,581,611,153,508,895,480,962,515,311,910,948,693,607,92,602,177,901,101,737,282,187,769,201,143,408,268,255,888,251,478,338,427,489,410,581,656,978,987,985,613,499,790,351,256,860,462,488,820,843,637,562,503,401,562,138,593,22,982,402,352,878,978,776,743,931,230,57,201,160,618,858,569,952,99,328,268,621,55,479,5,378,456,95,240,555,115,605,768,845,885,858,239,809,234,228,753,588,60,706,212,963,898,464,760,200,479,22,531,437,637,710,149,759,838,266,465,316,899,254,651,62,886,570,498,493,655,167,357,204,590,725,513,766,758,493,64,323,447,999,223,962,627,569,710,219,359,838,479,593,578,714,68,496,543,709,250,188,177,837,33,768,521,674,474,361,142,382,964,731,76,941,58,812,521,788,236,92,576,208,375,123,25,372,539,807,594,979,861,50,301,504,881,288,440,776,873,0,170,610,60,441,301,419,340,531,9,67,924,426,429,968,524,865,693,110,728,624,900,580,711,894,807,416,895,974,440,20,531,209,841,609,642,308,93,169,927,35,633,659,888,946,902,28,840,559,44,319,6,765,190,134,971,39,12,576,83,266,245,136,59,793,663,854,546,554,970,749,211,118,167,883,288,619,185,998,831,156,232,518,281,466,798,516,715,334,913,257,244,251,814,950,735,692,658,185,861,352,357,721,155,86,989,461,251,875,768,261,111,865,784,321,929,719,138,808,272,984,387,828,368,577,975,575,297,623,805,244,439,209", "728,321,78,591,987,886,382,200,973,976,86,884,4,295,278,382,210,123,134,29,841,995,361,244,805,499,972,847,308,888,676,678,856,339,377,850,794,36,859,859,962,169,201,28,988,619,623,935,214,779,455,120,660,596,653,391,822,901,238,351,366,676,369,445,794,486,819,501,162,268,921,780,398,778,398,245,845,556,774,166,126,251,437,808,563,28,266,903,546,758,609,169,880,120,767,577,507,603,315,53,1,515,360,84,202,592,661,820,493,556,898,180,424,9,867,173,429,23,239,332,872,967,765,885,357,506,453,733,498,699,808,465,181,698,991,845,287,794,149,648,983,642,955,108,309,247,248,641,337,102,134,344,235,518,124,562,498,503,770,593,318,615,963,928,46,216,929,803,318,793,590,540,247,622,468,966,140,307,422,856,403,605,15,145,68,499,195,261,778,297,975,868,847,35,536,450,54,794,837,617,494,706,753,304,963,119,234,643,406,473,987,329,831,841,476,538,903,965,664,426,290,85,934,622,965,502,603,364,709,901,174,186,71,118,132,211,40,252,354,435,957,740,126,332,988,270,628,299,89,338,778,639,793,153,446,89,623,728,129,386,344,572,992,974,783,105,126,586,531,660,632,172,990,430,21,94,282,274,710,713,637,383,935,368,450,166,73,208,272,148,737,650,287,974,861,6,508,560,247,957,37,237,831,564,17,497,592,705,67,250,688,842,750,182,734,593,247,464,790,574,293,870,254,525,599,232,480,35,555,779,67,944,441,726,457,45,71,316,220,189,448,861,542,243,334,770,636,747,320,170,414,659,581,57,232,231,362,870,928,333,862,35,547,873,88,934,413,391,334,976,414,123,743,468,227,29,728,683,239,679,844,503,715,368,313,803,6,199,162,140,220,304,172,70,944,289,796,227,288,132,238,423,597,277,213,5,482,740,821,197,272,704,396,655,53,956,158,539,289,427,64,724,937,251,788,485,854,323,3,58,916,933,988,887,439,609,995,811,827,406,254,662,353,205,404,586,598,638,654,121,876,487,258,219,929,713,68,665,393,796,654,660,514,230,481,177,171,984,519,439,443,859,999,990,298,509,62,218,51,395,161,899,831,352,848,283,534,359,882,37,227,118,867,143,609,148,214,189,420,265,47,463,23,492,580,663,281,585,450,203,953,718,456,182,165,184,205,686,380,392,855,558,85,159,255,557,459,179,872,649,973,621,590,940,335,822,698,307,645,109,207,589,585,459,487,461,906,897,55,423,693,53,2,592,679,81,640,700,664,55,961,480,102,440,551,734,687,95,206,465,784,114,4,559,64,738,798,601,664,116,669,189,592,408,344,575,886,683,506,90,520,375,186,986,931,645,177,906,637,230,102,217,271,468,235,66,149,95,23,987,843,72,841,310,539,445,466,80,936,72,28,980,139,168,941,641,868,354,808,876,138,985,463,127,231,291,111,686,749,786,184,104,617,713,992,504,976,331,536,760,501,699,77,979,442,275,955,912,848,303,444,601,180,792,552,936,90,106,7,838,93,217,217,679,764,15,827,469,28,329,660,733,273,721,713,591,424,826,116,167,628,327,973,922,445,779,198,457,434,849,598,167,372,575,828,925,518,859,717,992,902,218,534,653,384,334,357,360,410,857,412,864,560,932,757,843,594,716,352,84,709,143,302,299,569,775,279,64,694,654,263,394,616,382,156,69,734,758,159,49,902,882,104,189,555,580,95,678,119,509,881,273,700,687,67,444,288,793,369,957,660,436,96,281,840,144,223,825,171,969,380,144,841,887,41,292,109,203,97,88,152,600,275,254,317,853,430,622,950,979,674,949,997,720,579,820,710,70,236,39,210,139,360,178,75,157,141,623,751,391,308,704,832,934,315,926,432,474,943,889,737,68,841,298,361,719,830,470,944,73,961,796,129,793,410,768,776,468,910,466,581,102,274,7,31,25,166,462,907,959,131,694,46,662,331,977,468,170,0,832,431,219,125,268,97,129,783,741,978,386,510,804,952,59,332,537,130,762,494,927,28,311,83,563,273,177,214,857,903,170,990,340,500,898,323,123,561,164,893,768,996,816,139,965,424,72,966,584,56,341,801,172,342,395,176,239,520,686,411,480,28,670,121,659,187,207,53,44,659,460,23,532,432,771,861,709,874,628,731,84,740,189,559,516,782,682,386,419,379,479,802,597,532,616,337,236,725,118,786,506,451,268,613,282,323,155,986,36,94,847,120,784,676,970,472,428,569,804,430,195,963,586,730,594,120,463,58,343,455,168", "801,501,680,861,30,830,466,968,836,138,753,873,724,600,785,657,952,732,810,312,927,892,421,317,797,963,201,261,209,284,644,97,427,752,661,314,253,509,668,619,880,451,476,993,790,107,183,571,721,67,604,920,920,944,966,657,490,752,787,509,120,527,856,868,11,530,713,421,587,775,187,626,770,601,846,93,931,804,390,320,845,842,393,940,603,866,724,1,339,760,901,859,275,951,990,174,754,528,413,926,314,15,185,963,741,59,382,386,115,679,701,78,752,997,671,612,725,634,818,928,822,870,793,44,378,152,158,714,338,714,835,157,380,269,880,354,298,909,560,258,83,100,498,625,35,960,529,567,371,800,364,342,125,3,159,560,823,93,991,367,124,495,972,28,704,663,288,507,253,265,251,955,724,206,204,154,213,512,234,181,96,221,119,966,29,636,573,870,644,869,938,452,731,254,820,419,323,536,255,637,335,919,682,987,504,65,317,50,918,236,547,185,812,909,627,340,845,351,541,689,719,778,227,479,859,209,198,156,443,506,412,667,261,57,551,881,841,989,743,984,599,433,98,416,563,306,559,734,720,835,865,296,6,223,667,157,682,407,814,903,766,256,213,75,245,248,309,360,717,775,159,394,455,996,738,167,946,354,269,485,613,47,259,51,845,248,995,104,891,712,915,845,10,449,979,820,777,16,465,688,880,802,762,296,599,382,988,728,763,348,618,721,245,126,658,1,360,317,855,864,795,693,13,187,671,15,622,96,784,56,729,835,815,383,536,813,258,104,372,170,636,551,182,978,58,7,961,585,25,106,484,526,507,661,394,152,480,130,132,237,811,869,479,377,584,830,147,651,62,279,679,752,258,439,651,210,873,694,225,417,301,385,172,67,967,654,333,266,491,504,269,443,565,407,310,362,872,508,586,173,271,53,116,290,183,301,496,522,765,3,696,508,597,333,14,204,931,915,956,769,860,579,781,24,736,685,878,615,735,244,974,479,590,302,458,253,778,102,969,79,434,166,762,123,270,464,248,938,516,746,562,772,670,831,892,880,285,328,607,510,856,306,454,6,239,728,850,462,90,494,587,384,401,852,109,903,556,886,695,917,11,620,478,469,158,653,963,569,417,347,504,84,260,555,357,601,166,914,578,663,419,933,308,831,96,355,92,119,943,632,526,236,833,287,917,91,783,178,705,305,524,376,139,63,829,626,233,541,993,892,933,649,268,85,21,95,19,482,407,971,497,904,346,86,147,384,52,263,50,246,766,847,48,490,462,914,364,550,391,311,194,809,321,469,221,106,168,501,534,686,621,852,267,261,17,43,199,17,308,683,357,612,811,690,55,789,608,203,171,594,912,713,785,494,514,789,22,40,925,99,138,215,881,751,165,888,92,940,951,395,198,654,504,632,435,702,453,804,255,585,618,408,484,300,63,222,638,69,561,570,358,728,792,306,732,167,641,62,99,281,57,320,261,472,538,300,10,209,844,140,169,456,224,490,863,801,346,927,269,9,575,838,197,103,895,729,564,144,869,163,805,128,475,843,758,469,575,924,615,117,733,243,711,739,928,790,282,296,472,725,246,684,366,67,986,753,198,84,810,741,495,98,627,693,59,574,16,243,932,435,935,356,456,992,110,203,289,655,504,882,896,453,932,38,900,567,756,858,986,203,24,419,264,950,394,889,745,61,605,460,142,833,155,631,679,872,551,19,958,249,652,198,128,137,16,204,155,571,361,426,229,946,598,892,825,982,885,543,160,671,188,597,355,129,622,75,200,289,771,256,970,66,274,116,308,822,746,648,86,912,735,916,934,387,670,662,596,447,125,251,496,546,556,641,677,34,517,590,683,108,97,884,76,145,154,659,879,768,185,852,137,393,717,703,277,128,636,139,890,473,261,358,101,951,370,229,144,958,448,352,779,50,468,433,191,373,209,65,462,811,960,452,378,899,917,146,660,972,835,897,441,423,936,731,670,578,434,610,832,0,197,942,742,322,437,330,906,327,774,338,890,412,258,60,570,948,203,552,261,615,378,141,84,561,850,337,158,473,129,54,534,781,391,857,299,537,362,748,780,545,239,98,398,297,189,150,717,449,746,678,779,647,784,430,643,198,170,733,756,594,590,104,287,256,506,384,130,569,795,399,137,54,967,995,957,825,100,879,446,496,337,206,837,352,171,943,702,801,707,469,993,293,255,12,943,63,402,694,391,349,153,950,998,576,795,611,51,748,371,315,607,342,680,335,432,203,183,451,343,65,212,906,972,863,817,125,530,949,677,929", "351,876,825,91,171,290,605,875,330,658,760,211,250,152,358,442,116,948,808,78,87,437,680,438,899,373,976,358,958,490,820,272,896,286,496,264,41,701,582,37,604,892,271,366,237,643,950,884,865,657,2,443,538,512,71,343,961,111,926,248,911,634,953,261,11,251,226,242,931,504,844,204,712,469,474,918,295,30,329,106,540,141,299,625,931,383,488,559,468,486,549,352,760,870,374,971,354,186,665,160,612,938,881,703,599,710,147,83,905,231,19,559,60,273,784,918,763,362,22,250,979,874,926,587,654,44,593,175,122,393,435,934,551,69,614,694,564,623,314,462,15,134,698,792,623,320,347,251,91,953,854,68,271,826,90,28,917,787,397,926,6,998,992,14,311,70,479,189,84,711,128,654,28,934,758,853,483,396,763,717,732,770,727,746,626,671,164,222,296,625,540,140,732,661,221,309,745,314,721,709,943,786,441,728,242,736,576,718,107,990,143,694,932,316,404,407,16,685,458,513,409,176,758,627,842,388,890,536,125,338,421,428,405,726,462,469,464,338,970,721,593,190,878,97,232,614,618,340,537,9,483,806,255,16,211,971,51,268,39,265,429,566,949,225,39,889,696,60,957,215,272,391,12,451,816,266,708,969,145,124,293,757,591,984,562,197,635,643,792,730,980,894,29,973,605,654,548,456,632,436,764,918,556,801,216,351,76,414,719,941,726,76,266,677,245,950,495,778,86,11,443,472,244,978,994,759,800,881,377,823,686,964,763,661,633,855,31,613,854,132,341,802,996,776,633,110,858,150,882,188,631,532,118,936,525,405,524,80,247,213,163,66,97,807,450,180,311,983,588,420,396,584,70,711,562,113,608,473,737,366,975,191,736,21,976,94,749,490,267,476,16,714,798,15,751,130,678,272,902,337,236,531,470,353,734,260,989,994,696,372,77,106,781,75,386,623,350,985,841,450,57,756,544,251,265,745,669,630,175,707,973,28,469,918,78,769,129,808,102,255,723,547,926,888,749,33,580,609,712,385,960,80,135,979,210,288,919,383,552,576,761,826,914,385,745,198,292,408,990,420,162,974,503,398,166,478,648,517,131,878,857,419,379,597,378,117,412,207,500,249,841,425,313,48,856,692,331,471,20,55,614,549,138,29,448,437,24,764,858,201,140,352,237,422,332,871,625,252,9,997,599,310,80,822,800,597,116,529,42,244,50,494,191,904,611,889,510,375,603,443,784,753,134,437,936,420,648,183,294,317,70,617,794,267,510,924,129,625,715,104,727,891,647,610,329,702,453,456,6,922,556,679,64,61,807,10,939,31,23,153,400,434,764,414,455,120,146,483,876,596,937,379,436,554,608,810,557,234,769,294,940,210,773,45,757,329,343,744,829,858,506,62,751,827,850,554,749,797,786,234,324,671,232,928,92,630,94,475,617,844,290,493,348,253,375,571,157,116,235,236,765,781,847,343,997,853,765,727,297,267,948,336,19,454,786,291,186,720,321,878,432,338,745,203,237,429,976,404,969,627,545,563,787,990,905,868,895,945,802,116,945,715,94,280,668,281,491,166,917,482,598,705,137,970,540,768,434,42,635,639,42,995,804,896,924,70,184,771,422,942,142,897,354,443,247,918,981,810,672,917,435,105,890,814,401,848,343,82,161,322,529,271,200,539,29,678,656,675,45,394,886,114,778,178,430,420,229,118,469,721,690,686,824,343,379,734,201,715,734,635,914,462,674,696,54,93,244,165,845,698,283,682,290,749,995,48,522,332,579,384,856,64,318,767,40,189,50,238,110,512,767,481,257,258,658,129,363,822,715,294,852,789,960,661,559,55,257,295,544,583,478,190,970,226,557,856,716,43,337,280,675,652,887,56,24,978,463,699,316,48,32,456,447,743,759,708,566,520,331,726,585,503,131,668,978,909,522,967,243,539,576,89,549,883,137,937,540,46,738,54,134,457,755,939,309,357,174,60,431,197,0,483,403,662,286,263,464,722,7,140,823,58,821,738,790,305,372,949,974,691,169,269,403,860,345,84,639,342,796,925,75,749,181,419,36,658,318,682,309,848,250,554,381,636,532,393,66,468,795,381,463,626,859,921,78,697,66,391,588,836,618,980,228,350,663,429,682,383,447,534,751,634,632,425,23,364,625,38,137,508,180,430,138,352,607,618,455,518,400,911,109,892,3,49,557,11,372,97,374,923,467,191,667,221,981,56,273,396,85,602,934,792,322,26,496,778,480,996,129,52,560,570,506,702,333,234,942,253,606,899", "2,240,283,261,900,344,22,425,595,146,749,401,425,838,170,611,453,710,998,830,804,480,131,348,104,626,794,806,440,901,535,861,627,593,173,188,163,36,608,11,78,156,37,715,131,608,109,685,827,82,157,205,52,92,687,516,63,462,135,932,598,713,999,29,993,607,975,783,137,611,295,379,406,566,468,893,955,106,97,88,649,356,398,104,597,421,141,541,241,519,136,767,853,591,712,710,107,709,356,137,178,699,437,157,586,216,582,746,893,867,247,716,822,75,356,643,786,298,855,682,152,394,159,643,472,194,726,327,475,757,233,739,55,778,82,407,493,980,556,950,815,51,318,906,666,662,701,375,923,401,280,454,257,346,27,846,826,777,543,227,78,144,324,984,840,891,16,214,120,555,984,187,695,698,263,177,849,495,338,861,77,78,666,581,886,383,661,342,317,742,549,251,461,447,627,673,310,313,565,148,488,395,671,839,146,749,698,633,961,899,872,352,293,185,212,937,47,164,964,639,790,485,269,114,777,804,352,715,491,932,599,877,470,324,29,372,314,32,145,882,671,832,729,754,710,460,820,168,156,635,980,751,583,94,898,68,271,908,202,765,333,351,827,33,857,744,37,825,154,743,395,572,871,102,801,966,4,930,889,116,541,123,465,1,503,647,669,479,524,866,808,385,382,277,908,25,46,386,697,590,669,195,584,98,540,243,780,153,45,358,548,552,954,667,478,956,191,951,775,516,175,259,903,635,153,938,525,852,360,250,406,131,622,918,73,639,920,406,297,372,616,531,271,363,41,602,859,258,325,624,32,493,223,100,52,703,385,767,488,201,49,351,126,500,284,814,644,662,263,238,517,880,938,553,829,212,377,637,25,426,204,67,792,384,487,533,660,740,863,713,322,258,824,890,344,988,462,235,184,462,712,182,615,690,429,5,569,310,951,293,473,429,308,191,557,612,504,479,802,99,361,112,959,240,321,604,834,468,64,837,415,240,836,150,631,37,244,83,184,853,209,908,132,540,174,522,164,288,646,132,629,24,993,190,535,723,653,37,214,663,782,830,136,592,290,750,326,699,634,96,541,860,598,176,502,680,341,520,377,231,229,509,18,678,858,664,268,908,923,569,128,617,72,927,46,590,997,579,482,466,947,347,687,643,745,589,858,259,704,579,958,920,702,294,981,675,329,708,280,395,941,27,455,38,126,113,1,359,150,716,364,513,201,964,863,72,707,308,139,862,437,917,674,165,604,221,950,688,495,220,650,454,279,439,470,635,835,508,347,687,691,489,929,701,716,786,439,231,965,816,702,184,397,699,567,528,381,283,661,89,682,232,279,812,204,179,815,687,243,263,645,680,23,817,403,925,251,915,164,971,388,734,183,347,731,231,62,156,49,980,65,413,317,863,663,459,755,747,35,975,898,720,50,291,520,428,222,896,807,243,741,142,799,936,535,689,792,989,630,444,95,128,227,696,583,152,73,466,752,321,777,491,930,578,792,932,425,367,70,306,536,164,499,991,675,96,397,202,29,288,421,675,302,726,948,382,993,4,480,195,698,626,94,73,237,989,270,138,657,911,466,914,778,293,575,360,122,502,390,764,486,705,617,285,484,794,84,998,227,771,993,743,659,117,86,558,243,548,630,545,335,471,744,631,574,899,338,893,44,272,157,202,652,602,33,724,129,752,39,989,196,202,758,728,947,564,219,829,134,794,706,884,41,320,342,385,55,948,701,510,871,64,263,139,951,365,827,249,242,411,572,160,228,629,59,189,133,335,548,101,826,670,78,960,258,87,901,493,755,70,334,414,57,565,653,168,40,810,809,99,234,390,64,697,159,968,567,461,783,393,442,610,240,165,307,490,792,345,314,315,539,125,240,202,338,413,846,299,907,953,390,65,729,601,238,67,22,101,450,770,514,456,340,896,791,550,188,159,230,563,486,875,198,731,505,479,134,351,103,247,449,730,730,418,341,704,682,441,219,942,483,0,870,796,66,1,503,317,914,116,227,200,386,651,758,181,962,128,613,553,85,710,280,569,525,586,375,533,906,655,793,649,129,767,812,624,648,914,378,662,284,921,688,740,166,778,548,198,702,380,430,292,572,138,232,645,990,307,721,648,358,975,914,912,926,627,616,350,713,198,688,57,498,550,92,774,864,227,603,845,174,569,228,504,538,494,930,971,454,554,618,389,867,149,511,693,789,384,531,499,187,587,399,34,84,861,518,911,903,505,491,138,134,254,987,643,109,644,175,459,342,380,743,49,499,517,714,745,974,38", "553,152,630,411,638,379,574,519,127,177,549,280,192,929,436,45,566,589,663,91,522,516,285,41,566,801,660,629,61,388,678,648,125,61,667,214,481,381,784,955,969,581,992,513,679,126,15,136,369,107,615,873,659,86,714,829,794,319,974,497,181,538,61,265,507,142,894,32,697,838,971,577,542,961,338,453,986,445,260,233,1,12,895,935,636,162,339,748,109,730,546,299,709,834,818,474,209,897,11,138,658,944,773,180,293,19,816,473,535,152,927,127,985,780,567,71,3,592,448,9,579,960,492,783,712,131,822,806,25,701,308,599,536,362,787,642,396,426,943,445,942,741,124,227,755,752,191,753,269,570,162,652,774,59,328,666,625,221,108,27,849,484,845,35,425,370,437,175,977,788,908,911,575,918,62,595,448,924,394,828,694,292,375,661,357,839,428,290,662,815,435,607,874,200,67,685,141,676,139,640,772,747,289,305,926,734,497,179,348,626,590,366,502,993,712,266,141,428,418,220,291,779,827,32,452,103,598,846,91,395,834,268,73,231,504,444,17,274,233,250,534,721,141,761,946,337,517,838,426,182,943,230,300,413,925,60,347,108,107,715,581,599,784,503,972,263,518,974,393,987,320,371,614,734,608,186,343,785,50,861,968,368,865,282,508,872,335,179,199,559,512,219,206,982,735,54,909,720,819,768,220,958,750,201,428,461,330,691,55,647,289,432,345,686,433,623,221,558,753,935,574,367,477,309,844,611,760,154,146,385,464,236,829,601,452,552,862,387,448,370,235,34,112,954,501,890,518,464,622,155,667,484,484,587,612,96,488,456,666,864,351,988,888,430,13,942,963,492,104,630,984,873,559,461,353,881,831,7,380,47,211,952,352,114,80,128,94,37,53,159,541,860,819,302,606,175,571,533,382,310,614,259,861,236,164,384,465,351,946,809,337,843,43,915,302,928,421,800,907,356,810,33,64,746,542,565,575,530,338,574,784,771,354,239,611,967,136,515,309,212,836,554,373,841,918,96,706,45,806,162,906,875,346,723,47,445,745,662,731,701,359,363,483,980,926,924,965,463,553,932,149,465,277,20,992,7,515,1000,297,122,913,717,229,228,767,538,790,852,993,202,149,162,587,935,863,243,99,551,675,470,400,236,712,595,279,883,906,272,275,195,428,288,742,905,876,94,89,356,492,164,776,718,500,48,149,590,286,126,606,739,398,342,298,271,371,578,480,803,403,189,265,902,726,55,381,525,287,518,668,840,413,877,482,795,729,347,542,566,107,981,352,495,193,115,204,407,298,377,96,426,8,971,842,511,321,37,958,210,627,692,511,280,97,127,91,487,231,865,436,772,495,676,266,427,167,482,357,444,205,29,997,666,854,997,785,813,24,527,694,373,956,398,220,127,526,29,845,27,377,961,790,827,870,648,418,344,904,820,626,602,470,69,970,402,692,74,211,705,633,88,170,464,465,493,974,218,474,389,795,190,935,426,604,796,269,805,469,511,255,318,595,586,391,464,221,177,811,43,449,345,894,717,683,232,269,55,465,790,30,273,271,785,636,184,59,82,986,876,809,18,129,339,376,458,729,532,976,124,801,838,601,86,701,814,58,541,379,461,633,250,497,614,764,862,400,303,795,174,268,791,190,40,185,797,975,41,596,737,664,199,950,432,371,872,285,969,984,791,752,907,826,697,82,368,674,493,801,313,486,28,247,495,544,447,622,105,580,347,577,236,882,113,933,35,179,686,61,225,37,565,100,397,418,251,478,410,493,144,88,17,136,956,917,186,889,840,764,382,935,49,591,545,305,901,697,599,606,37,139,90,318,127,223,116,810,804,850,330,194,810,845,160,404,61,834,684,941,605,841,190,486,162,651,176,714,17,361,211,752,374,237,527,561,977,113,956,331,379,553,127,720,588,710,69,365,797,463,325,558,696,136,45,400,696,690,95,29,880,503,295,323,875,564,920,927,890,564,301,125,742,403,870,0,606,151,800,313,735,47,22,594,985,133,157,419,829,518,949,270,781,740,343,477,260,700,473,179,800,361,719,731,808,109,372,691,110,318,682,959,867,370,936,807,325,241,633,971,406,993,727,627,875,78,281,624,835,858,746,527,353,416,229,719,829,112,352,498,448,630,683,220,992,769,798,463,398,776,348,687,579,828,835,513,147,771,923,980,592,778,23,337,512,794,562,205,296,312,971,242,692,333,543,396,458,304,519,184,446,526,224,697,121,809,424,366,908,82,123,662,168,558,899,871,319,103,302,19,50,324,421", "75,734,661,717,276,174,750,939,270,817,657,705,926,369,487,519,510,446,254,74,281,516,27,171,646,74,691,666,808,963,43,264,813,55,486,466,6,76,704,6,368,694,942,7,122,628,322,893,282,77,758,366,874,970,17,414,15,849,980,659,919,4,742,705,31,122,239,981,909,929,358,5,529,622,314,46,513,683,161,217,426,220,462,705,755,494,701,552,824,106,330,222,671,131,984,537,606,880,756,698,873,464,454,491,569,539,805,12,183,194,482,8,75,358,397,480,536,229,875,833,966,947,575,500,493,129,117,662,559,44,984,325,354,535,739,791,273,619,870,925,60,735,928,376,166,11,104,932,634,174,745,742,416,126,322,692,28,346,264,636,793,531,459,853,192,768,673,798,605,697,58,883,636,894,428,39,751,145,534,213,770,879,690,107,315,371,446,985,734,96,323,284,471,825,727,622,696,88,90,613,804,540,846,488,759,182,133,205,413,811,206,271,180,893,502,833,758,937,220,814,346,780,333,864,798,104,980,873,710,265,734,657,952,240,615,435,760,279,144,59,679,137,126,805,724,405,662,695,298,380,778,480,558,799,192,347,43,822,278,853,3,536,970,677,320,230,186,538,479,174,796,164,705,191,425,275,590,104,315,318,450,175,7,160,1000,207,908,313,24,807,938,591,892,939,440,694,379,55,345,877,918,572,505,826,533,796,343,448,473,820,455,989,407,258,99,611,282,732,584,568,360,459,204,54,721,318,491,719,828,271,574,337,735,672,988,222,892,436,435,489,737,728,227,899,771,897,845,263,175,575,280,457,367,982,360,981,644,412,764,321,38,523,454,667,126,483,335,343,967,809,200,82,885,41,995,675,643,602,878,84,222,511,217,994,968,156,311,456,233,671,176,849,31,290,407,931,177,483,817,933,279,172,4,371,468,784,109,490,14,602,51,264,7,103,869,282,282,202,990,44,142,755,48,908,820,544,286,574,675,194,135,610,56,266,523,480,549,629,830,466,32,310,253,965,362,568,560,308,811,993,970,834,439,900,425,670,640,948,818,656,166,108,306,608,639,603,711,568,780,520,619,581,861,157,781,775,80,98,708,952,615,462,255,678,964,765,11,370,494,204,72,81,968,190,696,239,28,863,549,573,626,161,467,613,361,532,724,414,30,800,674,515,602,193,874,337,266,5,29,269,526,766,19,253,761,535,674,268,226,16,490,117,42,992,582,93,943,306,844,143,53,61,548,522,878,708,45,289,190,160,729,302,469,579,428,708,556,238,825,702,729,524,937,379,88,675,908,319,241,351,617,341,100,643,19,601,410,208,657,96,411,337,839,307,953,191,160,222,542,902,457,370,580,92,692,444,679,217,414,864,552,604,556,748,608,489,466,671,409,752,248,717,209,69,779,13,459,632,195,89,38,809,166,809,59,642,985,111,635,380,401,34,429,834,176,579,34,567,59,745,856,930,581,876,896,590,709,1000,864,518,851,967,239,564,568,459,456,517,508,343,535,665,361,789,356,124,56,661,295,283,312,600,598,289,316,532,924,923,146,630,339,462,253,705,764,36,670,589,672,251,915,117,641,398,165,604,995,567,333,653,188,705,749,628,420,124,906,310,659,126,332,828,106,368,180,347,987,150,936,953,588,805,52,916,534,884,941,656,301,64,78,290,74,594,887,392,30,796,732,389,671,447,854,137,527,682,225,852,208,339,254,425,699,12,33,991,290,309,418,649,249,341,445,951,818,973,588,413,237,414,374,934,173,947,536,263,553,361,418,377,162,370,712,186,811,958,994,456,894,73,95,194,605,112,157,486,707,11,777,967,559,371,34,434,888,384,454,721,386,230,952,475,499,35,465,921,73,432,677,479,205,568,354,69,895,205,953,18,447,832,721,252,877,86,75,413,881,135,968,952,955,106,56,956,347,319,433,963,37,572,698,359,790,695,725,378,296,913,235,824,469,325,62,63,34,150,311,419,268,322,662,796,606,0,314,71,881,115,721,39,531,730,83,587,154,809,626,973,148,27,618,764,503,534,414,341,818,231,498,703,933,773,566,156,172,960,338,675,482,475,607,48,852,275,928,576,141,948,68,711,893,504,459,296,324,552,949,793,699,254,150,136,2,644,288,345,885,373,467,878,929,902,997,752,247,838,700,297,418,132,155,832,159,470,14,374,514,518,474,902,85,321,116,22,250,468,796,512,849,73,549,947,408,625,967,90,959,855,478,567,545,472,965,413,175,377,186,279,216,618,205,798,183,852,545,472,64,89,184,838", "595,13,843,702,703,273,443,924,968,204,207,815,488,942,968,755,80,476,253,292,60,863,640,665,922,688,203,96,141,838,583,829,585,90,447,967,166,945,327,663,201,527,918,476,274,431,552,469,13,186,638,146,511,664,826,618,829,329,758,22,42,105,695,568,253,31,301,426,712,997,205,873,344,111,433,94,758,435,35,561,953,850,431,218,953,674,669,21,439,350,242,334,592,863,46,965,361,13,676,568,659,305,304,549,232,364,423,153,257,566,793,98,361,174,470,684,713,892,490,482,323,543,132,279,365,434,496,63,387,554,854,625,978,359,470,669,12,959,83,103,843,721,811,134,969,663,243,870,450,790,803,867,612,522,679,71,842,291,28,715,471,358,749,754,795,797,324,453,628,678,7,452,721,20,523,748,996,384,306,834,186,96,380,267,698,748,875,746,387,41,891,7,848,855,957,845,243,407,241,131,539,702,862,851,799,213,555,989,139,116,840,19,387,15,924,576,244,825,149,894,268,355,704,347,381,523,462,24,406,499,551,374,882,295,160,927,145,837,316,344,101,200,422,829,560,26,44,656,395,602,363,288,96,196,388,447,520,385,77,984,725,351,417,2,239,843,281,185,827,436,20,260,983,644,123,873,836,17,409,288,756,718,497,942,618,777,147,447,443,810,661,44,275,92,592,936,587,212,411,875,574,644,161,564,358,320,194,584,650,812,967,115,349,345,773,176,365,676,173,519,346,341,419,700,456,583,220,322,987,502,964,454,176,198,704,404,444,528,180,813,725,612,79,53,708,924,436,329,953,187,10,318,442,309,707,162,64,687,854,343,197,854,858,117,703,77,817,60,619,761,405,246,690,301,963,69,183,112,991,962,525,589,78,889,888,348,568,641,176,463,398,393,199,766,805,241,361,416,98,223,434,340,661,259,205,21,685,71,175,904,463,525,692,353,439,928,506,635,999,514,950,209,119,202,930,681,618,490,674,144,845,311,976,839,166,865,350,96,401,344,279,633,794,322,520,637,614,938,200,435,747,382,452,617,408,956,752,948,881,306,952,556,120,983,703,736,283,168,383,81,696,380,642,786,345,620,853,164,761,363,221,623,145,108,295,792,841,267,196,266,859,547,157,913,409,330,880,132,635,35,518,72,242,732,562,377,123,365,726,143,523,960,213,224,953,490,123,252,502,650,563,677,868,541,578,74,10,909,737,381,507,150,661,887,791,112,352,739,920,456,526,359,872,142,414,91,940,545,473,350,301,376,828,984,236,377,204,470,625,333,79,32,862,323,430,763,589,742,746,913,275,421,163,168,448,446,140,57,817,802,212,84,860,153,721,351,889,603,671,510,432,494,863,993,109,446,114,650,643,947,586,380,338,381,906,125,573,624,567,836,117,43,909,314,76,392,683,424,383,12,232,68,211,731,679,458,220,899,225,99,350,984,333,597,265,385,991,547,229,125,308,298,567,726,452,109,68,480,256,33,429,442,381,630,109,91,850,718,817,927,467,993,865,414,161,394,193,943,665,102,198,253,992,749,989,746,436,733,537,793,154,264,862,512,293,653,656,425,212,935,369,608,140,288,946,248,792,396,451,548,350,619,912,559,49,40,518,789,188,598,24,291,463,650,79,771,329,592,776,333,636,484,767,88,978,465,679,508,363,226,948,371,99,633,524,729,845,703,580,555,172,298,409,641,389,5,399,547,202,18,518,31,743,21,631,352,260,424,197,554,401,263,582,668,781,606,505,716,302,696,927,11,554,604,368,734,105,161,723,307,546,373,61,484,95,267,419,750,766,518,345,711,983,424,664,807,747,134,83,899,479,157,354,212,545,899,48,604,746,84,298,186,778,381,30,649,139,20,634,77,294,428,795,318,306,80,488,168,985,982,401,163,489,411,891,51,538,776,83,362,937,885,330,833,647,757,426,580,712,923,516,775,285,186,394,361,557,476,487,553,679,496,936,398,190,738,946,340,97,437,286,66,151,314,0,785,53,921,327,202,421,772,994,970,851,177,937,386,363,350,794,769,739,350,661,12,333,369,709,837,556,136,876,604,155,181,46,221,998,992,402,20,181,285,891,82,322,401,905,420,21,390,347,979,616,677,121,975,966,960,187,633,391,36,419,348,732,824,481,829,307,523,245,3,784,858,622,776,739,427,45,985,473,563,698,152,754,374,544,364,784,987,645,561,337,532,821,439,280,548,608,566,879,952,193,445,76,63,284,453,278,423,154,206,491,476,520,195,396,67,134,551,959,854,487,346,659,65,156,199", "907,707,964,901,265,988,385,447,972,801,400,644,301,140,898,587,216,28,14,105,719,965,342,969,402,836,642,982,687,655,786,845,60,787,117,22,419,605,492,288,352,714,140,362,491,727,861,380,441,941,846,264,894,326,791,727,794,836,734,690,147,840,158,865,764,38,491,415,301,732,257,434,980,457,916,802,194,571,774,648,561,415,120,963,814,119,518,6,855,974,842,177,874,62,382,142,326,673,796,608,588,999,549,409,311,480,341,799,344,41,828,615,325,839,924,3,549,537,150,140,341,272,687,418,910,992,706,68,342,534,791,499,799,798,469,838,686,337,269,879,541,855,545,160,204,164,828,639,288,363,395,964,182,729,388,848,228,887,737,328,633,547,583,57,490,174,339,974,428,96,929,764,529,620,697,505,909,155,334,636,789,821,791,536,198,431,262,669,851,388,120,26,348,289,230,227,953,217,141,470,505,771,164,118,28,937,976,631,542,196,248,887,968,507,757,76,906,399,795,299,902,218,337,896,999,968,112,770,831,895,976,56,826,300,307,206,998,304,759,865,424,768,138,440,383,959,452,678,45,19,706,633,43,40,24,609,23,934,925,252,443,993,126,437,359,304,930,607,15,407,533,896,118,348,407,701,469,383,481,776,934,771,178,470,68,299,265,498,78,826,481,597,38,41,205,674,42,870,663,596,669,568,63,555,48,554,101,169,957,836,722,264,799,387,708,446,129,848,791,554,370,119,66,975,820,820,707,918,558,159,507,715,73,243,837,649,969,551,586,79,857,672,672,371,609,108,205,773,506,734,641,166,763,670,987,113,995,227,306,617,840,203,77,96,483,870,76,144,247,555,830,582,411,28,523,210,275,594,268,422,42,536,737,739,970,991,616,963,747,373,368,462,441,270,189,177,862,2,162,722,192,329,896,789,630,296,301,264,857,147,995,322,819,590,102,924,992,200,898,324,891,665,400,255,649,176,686,891,385,200,231,426,845,654,73,455,725,493,774,50,675,779,20,528,573,191,630,467,380,81,950,978,123,479,782,363,711,604,746,83,970,571,595,454,7,280,209,632,182,778,91,390,664,156,421,837,497,142,327,288,245,289,94,541,599,16,652,803,477,979,494,822,701,156,362,253,155,83,69,932,917,257,417,705,90,62,948,529,482,784,33,852,865,475,96,152,668,801,368,298,58,41,738,446,383,30,604,432,518,743,887,289,331,297,292,466,486,682,519,883,119,656,692,149,191,298,444,400,975,92,707,460,340,899,722,480,964,21,632,499,156,15,908,509,444,166,407,8,674,77,924,618,6,283,373,756,957,419,636,703,984,593,759,554,256,178,361,206,592,150,128,153,75,230,926,783,911,122,634,828,923,186,452,764,733,100,258,683,703,620,991,580,361,356,231,463,60,477,284,880,886,330,843,683,146,455,556,805,408,521,61,246,257,864,240,821,118,798,47,87,630,535,603,727,936,258,163,603,75,607,339,310,984,566,385,826,168,643,940,41,513,281,638,641,912,219,425,554,264,748,148,942,312,158,740,963,450,92,564,36,469,88,915,241,418,206,708,793,266,349,245,553,773,824,706,394,130,792,826,83,368,711,818,990,826,170,997,862,338,812,40,277,352,519,638,211,766,549,597,746,799,473,259,489,787,806,683,632,889,7,929,515,292,111,493,971,736,465,297,652,520,603,64,932,241,409,530,842,604,88,17,246,518,63,91,82,537,28,425,388,680,653,174,925,670,973,664,334,611,40,324,886,532,225,656,250,966,347,808,188,449,409,794,404,482,327,437,821,569,572,262,614,541,120,868,285,866,258,199,631,788,714,551,35,129,504,256,131,173,930,294,443,695,680,72,347,856,476,447,922,616,812,539,813,673,939,540,34,928,682,316,921,898,265,430,376,669,881,854,729,738,767,699,950,309,543,13,925,57,781,628,97,841,939,770,5,786,254,468,905,87,23,537,617,302,950,374,531,129,330,263,1,800,71,785,0,458,823,21,648,341,173,896,394,81,677,337,275,791,836,344,255,908,903,378,234,800,141,102,123,671,546,572,765,486,383,709,575,108,234,519,922,436,177,843,631,615,460,870,646,449,440,668,355,467,455,706,569,677,367,585,101,612,678,265,20,474,17,926,818,769,100,316,176,58,531,253,234,394,521,947,858,451,895,176,353,244,539,818,963,936,278,332,46,807,490,573,866,385,889,589,644,58,34,579,889,125,67,864,400,58,945,994,768,297,277,377,547,421,215,434,549,784,975,939,918,781,675,896,468", "299,607,443,488,664,561,172,356,718,600,129,923,306,231,623,2,722,524,475,690,263,660,777,106,776,185,301,270,385,618,337,696,133,739,997,9,654,813,428,879,654,307,895,108,134,993,432,13,115,706,966,568,197,515,200,260,240,377,120,504,6,814,552,330,235,250,900,662,204,58,670,979,897,100,267,224,538,74,619,685,75,698,86,247,967,684,545,673,996,790,964,758,985,676,850,283,153,537,958,697,554,314,862,94,266,93,850,702,219,829,910,830,849,574,36,449,499,892,681,314,196,849,648,716,330,689,29,119,432,962,496,951,523,848,911,610,440,559,402,861,539,685,713,534,292,208,591,942,401,451,565,620,595,89,306,351,280,590,54,930,280,128,855,689,407,955,484,92,146,939,97,244,280,60,152,99,46,767,71,322,252,558,304,443,445,176,89,432,468,216,571,458,253,693,72,443,992,292,948,427,765,315,922,580,602,91,886,20,191,189,653,373,25,129,780,477,22,156,875,366,332,166,525,550,344,822,300,797,183,868,277,725,131,677,382,176,899,670,326,510,580,18,264,160,600,56,392,499,129,919,854,439,178,94,464,713,917,426,112,700,793,786,171,777,447,305,83,982,512,105,66,228,924,701,962,656,710,640,784,682,963,683,332,747,880,713,869,148,956,658,301,917,803,798,379,39,232,577,57,349,984,945,354,546,207,428,86,716,639,987,776,493,342,973,958,299,380,29,694,444,777,384,577,480,384,51,508,787,561,858,879,225,482,937,733,215,997,818,870,486,564,148,924,102,297,596,707,166,626,379,40,947,982,420,483,852,747,768,331,756,949,318,772,764,925,259,470,904,499,455,159,423,486,472,245,807,426,83,666,594,114,374,442,848,499,242,275,28,990,580,513,927,106,710,289,480,102,369,550,801,450,270,772,750,401,453,197,49,263,922,22,408,63,652,952,823,698,845,987,36,2,619,263,331,856,647,245,137,423,199,357,319,757,270,12,912,262,338,294,520,428,944,781,519,58,244,194,884,558,610,670,932,26,155,423,329,430,561,66,395,745,628,706,924,534,381,478,504,729,713,42,885,706,554,324,540,905,790,682,920,200,697,728,157,230,586,589,485,229,347,66,253,280,741,173,179,137,627,815,310,990,455,87,123,119,879,478,31,841,221,805,456,533,210,793,206,512,174,665,555,414,723,629,632,6,920,529,595,231,805,324,903,609,400,111,235,715,665,989,666,976,15,420,707,815,221,844,188,489,301,45,55,973,14,449,830,305,948,747,912,849,644,450,155,3,554,721,831,770,688,262,112,443,547,462,881,745,425,519,478,674,395,403,835,341,400,620,582,231,324,392,865,482,218,777,587,381,165,737,747,36,692,353,164,762,851,326,988,853,970,77,178,703,177,563,111,749,879,754,601,914,733,235,743,761,52,530,199,61,920,116,386,324,588,160,532,332,664,326,878,189,71,220,129,296,654,972,347,581,701,870,278,29,879,801,920,646,786,647,114,46,53,707,927,386,367,829,584,819,794,783,861,405,638,546,741,426,999,272,517,31,142,616,814,716,858,951,24,336,759,172,961,909,835,867,139,627,254,562,785,308,297,840,549,754,285,256,168,587,857,68,203,984,907,885,194,836,785,45,462,504,94,541,588,209,568,444,179,148,881,699,597,955,77,465,778,498,622,562,634,503,66,339,434,977,591,394,103,206,789,363,984,836,597,309,494,876,570,189,847,79,316,685,729,531,305,391,984,362,663,116,938,935,391,259,516,130,614,207,523,4,329,576,310,876,895,710,473,307,238,73,64,207,954,237,522,445,86,609,440,543,535,829,59,802,528,799,300,566,282,926,142,886,732,752,58,472,869,598,663,555,852,673,790,644,948,527,974,473,442,198,908,893,62,777,117,215,432,267,952,975,780,588,849,617,33,191,778,844,718,182,216,788,462,301,753,614,785,838,583,58,905,21,227,710,607,848,9,783,906,464,503,313,881,53,458,0,245,418,201,633,920,919,276,201,124,681,255,395,199,453,895,58,454,937,163,550,107,142,777,110,979,817,835,838,777,849,418,232,77,536,453,366,423,843,106,292,338,28,939,170,806,953,478,801,641,339,554,519,798,42,33,73,173,487,440,695,754,628,789,509,898,911,570,277,433,105,283,231,51,537,324,369,69,970,646,212,177,716,377,851,150,2,146,198,945,671,204,357,742,703,371,73,240,167,510,40,596,96,761,934,353,865,692,215,268,761,648,46,125,357,953,258,551,136,564,699,323,607,967", "469,375,945,350,944,899,167,988,188,145,268,221,145,550,637,265,378,270,609,887,54,450,479,950,735,803,457,63,290,439,94,837,702,313,841,303,298,924,484,560,604,341,502,742,51,807,713,236,514,61,339,826,771,417,846,315,733,703,869,437,691,82,856,679,199,101,316,385,61,155,232,710,702,444,992,468,70,622,175,597,592,20,470,269,68,601,448,399,32,761,560,356,452,16,946,910,550,902,275,557,492,327,756,580,579,748,296,562,466,698,203,809,430,333,147,527,519,425,737,71,140,553,169,50,594,357,418,367,883,330,76,419,150,995,948,846,273,969,905,159,190,290,733,325,921,712,344,783,184,145,984,75,251,611,515,747,117,810,625,533,563,721,756,775,820,473,244,608,850,604,482,349,652,565,809,74,365,26,491,87,419,893,376,127,602,996,87,798,264,786,187,44,59,598,582,369,540,711,128,330,671,101,910,422,170,324,277,917,276,633,717,382,283,34,94,309,354,274,60,636,813,651,517,373,503,54,19,414,546,892,364,76,651,864,376,421,597,535,208,659,596,684,857,769,606,345,79,359,409,671,624,704,645,367,889,542,720,358,662,603,324,906,510,76,420,79,938,284,787,960,121,320,314,159,116,189,608,247,20,929,155,125,276,364,626,222,395,606,232,488,120,444,13,184,201,684,363,197,271,796,486,414,111,287,249,511,275,871,592,84,667,549,787,560,933,340,394,209,211,586,818,768,409,359,694,774,701,30,576,401,930,180,690,442,9,230,932,19,361,811,44,946,56,393,534,341,671,245,596,238,816,843,189,832,232,750,801,691,36,256,731,654,412,702,52,171,586,720,634,919,705,533,269,773,895,327,855,171,292,880,443,427,583,419,363,357,546,36,8,553,355,472,895,767,881,959,860,299,558,668,877,30,623,107,549,676,542,713,346,512,530,69,768,888,12,695,574,191,841,100,815,393,464,837,831,611,419,176,777,477,252,255,166,714,656,583,836,341,811,394,730,547,73,346,343,762,782,330,744,390,259,410,591,362,901,636,600,495,733,430,573,348,874,676,395,939,723,695,625,456,524,768,975,159,532,780,93,659,263,411,749,507,588,705,307,708,805,268,661,295,285,221,345,270,358,88,445,888,515,93,483,875,51,434,496,801,45,701,526,812,573,839,593,21,552,54,72,968,421,473,213,736,731,594,742,128,8,259,434,490,436,210,364,346,901,937,393,189,189,548,516,395,224,812,479,564,52,420,904,154,837,157,741,897,763,737,770,797,916,517,498,321,929,287,91,21,605,922,917,31,82,305,144,116,903,899,444,564,660,181,267,132,917,891,878,424,655,874,673,584,945,769,573,974,873,559,401,968,306,304,929,68,861,51,137,357,560,502,859,620,418,973,349,685,493,692,424,786,297,936,219,822,950,614,762,630,237,445,200,207,754,2,523,989,586,203,534,298,139,904,703,738,665,109,400,429,729,424,641,663,120,387,300,76,353,296,297,901,183,766,751,423,13,674,396,800,818,6,892,223,428,684,837,529,504,342,360,214,678,347,161,734,49,344,255,139,917,734,542,934,319,580,611,494,37,158,865,745,451,384,496,679,892,221,160,191,681,321,810,400,309,693,46,837,472,705,917,850,751,405,305,362,823,301,51,373,269,892,258,43,291,287,456,131,213,307,973,585,606,356,876,78,350,561,627,411,711,803,617,972,604,432,737,71,444,812,21,304,390,995,165,359,362,822,147,916,492,466,756,777,89,866,400,905,447,69,625,82,640,817,113,820,419,535,764,927,948,646,829,123,305,903,928,242,117,137,159,520,28,105,722,643,647,321,750,14,862,275,41,557,825,313,26,272,108,784,693,525,855,723,479,795,876,108,36,278,156,442,591,185,822,598,827,609,369,180,304,125,206,11,459,17,234,493,586,767,394,14,422,531,702,495,1,257,584,240,682,536,800,605,224,581,285,39,260,44,350,67,741,327,722,317,735,115,921,823,245,0,120,151,365,395,516,926,795,125,694,949,186,825,192,726,609,787,719,928,258,31,657,211,360,870,777,868,606,5,920,625,241,418,955,927,38,618,910,239,733,243,754,82,964,926,484,418,978,459,704,104,789,10,693,728,327,421,452,396,645,813,592,207,897,239,104,102,287,353,849,191,340,136,579,321,450,86,616,522,394,673,458,821,854,70,961,160,542,768,440,450,204,925,820,331,765,329,476,405,326,619,298,205,253,197,84,905,457,289,780,674,116,958,555,587,940,392,757,964,519,729,934,33", "258,159,868,620,563,397,470,725,214,904,58,642,527,846,833,28,383,951,148,907,54,131,20,497,559,185,923,939,735,282,32,715,921,411,753,24,939,170,982,137,232,344,306,906,812,985,615,244,622,156,954,159,683,223,779,429,391,863,30,491,915,906,163,904,965,272,516,455,797,499,982,516,935,799,943,978,307,330,939,161,271,880,80,286,858,799,92,515,853,728,875,703,268,560,561,316,474,37,327,712,467,114,359,812,363,121,476,687,753,606,72,726,178,698,577,713,884,861,211,11,235,86,183,863,329,460,104,143,842,402,662,402,479,170,453,800,427,350,306,411,880,206,554,925,866,950,85,457,943,832,335,163,298,505,227,57,925,604,486,122,575,12,356,510,273,44,728,408,153,144,744,924,504,384,297,655,874,180,597,811,582,854,675,958,307,125,593,307,351,240,916,136,714,268,54,578,820,326,57,739,894,357,719,733,929,939,776,237,251,278,422,375,170,980,343,289,225,986,984,581,970,711,332,559,274,365,915,595,91,57,834,494,383,315,434,619,791,586,495,339,78,934,542,171,25,455,165,828,582,507,466,707,560,647,406,240,609,26,234,107,885,164,971,358,950,163,63,571,678,883,116,154,173,724,268,571,297,121,504,659,371,686,703,283,192,988,388,139,678,471,605,547,854,587,924,867,816,127,60,873,844,579,57,383,161,789,942,501,391,425,387,894,259,740,458,34,895,436,420,454,693,991,733,26,704,91,150,204,985,718,201,262,687,115,314,905,260,318,457,902,820,810,533,562,869,896,630,833,212,969,192,542,856,343,491,360,757,96,411,204,59,597,153,628,983,232,304,817,811,981,621,60,630,346,347,15,494,823,886,817,2,278,345,460,27,521,18,121,412,489,101,272,970,4,398,785,217,152,23,412,587,969,934,283,332,323,706,917,981,870,698,190,462,657,241,113,683,174,891,817,528,657,724,887,733,285,110,814,989,866,68,834,38,146,378,213,350,185,213,521,165,509,396,338,466,419,449,364,170,841,666,956,979,463,842,192,922,12,190,523,266,846,887,859,947,63,561,372,148,382,881,772,98,652,364,41,793,20,566,953,918,558,815,217,874,339,677,23,24,887,237,907,75,332,558,401,750,559,149,930,808,7,714,909,81,547,373,789,367,976,612,663,913,259,599,897,349,459,738,832,882,890,981,152,960,902,931,312,410,110,868,309,249,351,908,428,660,638,126,805,517,531,111,886,79,514,959,390,171,786,300,940,240,414,968,423,40,42,619,495,327,888,973,934,510,14,34,544,688,974,659,630,660,972,494,186,393,890,57,17,161,782,178,823,624,250,193,57,577,509,824,586,769,407,853,497,402,281,331,177,491,789,214,641,948,919,796,301,830,27,975,53,193,360,90,341,324,216,779,244,313,919,883,306,918,850,348,359,787,401,510,985,235,502,500,179,740,310,317,110,263,497,834,874,860,451,486,386,766,487,870,431,505,10,621,263,282,700,454,629,316,784,782,123,484,737,383,903,369,921,833,298,580,854,184,686,420,304,111,798,154,653,981,578,208,87,664,483,882,889,431,12,915,155,936,68,241,60,731,691,514,516,987,755,229,61,264,291,626,978,813,769,337,934,845,656,184,811,845,320,140,535,11,247,804,574,404,378,502,215,389,958,774,98,619,235,659,932,318,397,517,151,265,447,955,947,742,613,663,279,363,948,124,257,421,100,826,525,985,167,671,196,611,104,975,668,415,941,38,344,693,53,398,92,203,546,125,468,769,678,929,210,713,506,893,357,261,98,509,770,867,448,199,163,488,308,384,900,838,528,453,445,183,675,177,362,699,410,574,371,238,986,531,361,116,738,203,179,344,956,102,352,73,123,958,725,693,378,712,787,451,265,363,191,156,550,203,175,871,750,796,564,237,919,146,778,362,24,910,670,212,188,656,514,300,629,330,562,872,740,532,266,885,671,466,412,486,924,978,774,7,914,47,721,327,21,418,120,0,734,899,430,71,59,948,382,72,644,12,521,508,759,576,850,790,288,116,163,73,792,858,8,753,729,310,164,770,200,346,70,797,937,611,929,95,294,94,704,246,710,841,396,110,563,405,235,502,781,502,952,951,794,849,472,711,105,694,399,970,168,456,962,840,908,307,558,998,62,256,953,238,834,59,430,237,371,478,433,878,331,525,285,310,670,509,506,373,750,296,346,402,379,584,275,711,899,859,937,560,45,283,826,999,691,154,709,615,690,640,294,779,318,860,78,83,868,214,430,740,751", "40,446,455,526,128,739,539,461,425,365,512,128,132,582,726,969,567,462,709,212,789,771,506,837,724,884,453,758,564,95,148,58,621,502,276,369,808,923,646,570,719,120,137,595,213,651,319,337,204,241,187,945,813,316,263,814,86,919,551,956,874,499,936,686,638,449,793,499,520,13,940,446,80,355,868,734,230,951,267,506,444,293,835,703,49,637,908,610,33,864,397,656,187,474,427,797,243,761,207,44,292,676,242,132,885,471,841,794,275,287,512,583,874,662,412,409,793,698,425,146,718,333,100,239,194,171,882,861,74,598,137,402,376,157,98,27,911,564,981,304,883,463,460,977,215,399,221,771,420,779,523,366,689,16,207,580,202,689,750,837,905,140,43,170,54,808,691,733,476,892,352,874,181,624,557,322,90,921,752,533,422,804,217,245,414,271,750,82,936,444,938,420,513,902,121,956,143,814,245,143,372,512,587,59,364,966,974,812,899,761,161,783,861,810,284,274,67,395,914,495,819,14,907,301,278,319,782,985,52,214,886,470,662,34,198,666,719,836,196,863,482,923,19,930,880,255,673,601,297,89,306,645,545,996,312,342,880,472,283,940,121,665,91,397,317,122,264,628,312,968,850,777,38,546,36,450,640,729,940,977,320,183,963,156,195,276,260,743,946,706,201,338,612,232,470,583,684,61,546,856,901,170,767,844,396,267,217,70,961,768,449,457,89,347,372,351,632,695,881,25,195,117,417,676,195,928,215,186,523,492,877,956,847,753,469,605,816,614,529,226,100,818,851,282,18,251,50,371,119,465,941,627,560,64,652,816,558,990,527,174,823,79,691,497,945,303,26,33,317,655,406,158,500,181,175,723,520,430,271,691,117,322,724,571,605,732,700,904,388,311,647,463,136,620,224,284,725,409,458,977,793,449,634,467,632,149,506,673,678,209,70,287,194,43,990,123,542,10,893,56,893,313,226,110,758,383,762,122,349,431,422,152,672,342,112,249,482,287,610,367,638,124,632,761,805,246,353,884,814,4,181,526,302,638,746,235,929,701,120,875,325,690,96,308,700,491,949,982,279,412,447,934,968,893,794,617,885,805,908,55,283,189,303,470,361,888,323,134,33,124,924,176,808,563,895,311,724,616,710,34,371,570,726,41,975,230,453,981,675,817,904,985,404,276,31,449,613,85,105,674,424,681,682,462,694,67,299,398,525,213,777,241,476,472,759,680,136,855,390,675,374,90,585,980,188,480,727,796,908,355,202,371,488,744,675,570,115,85,898,475,671,990,452,490,321,713,356,976,449,923,674,927,826,753,43,451,871,206,14,71,994,786,467,499,772,245,264,790,948,8,598,568,675,568,2,491,205,244,558,95,785,569,483,601,768,743,906,540,943,112,898,523,87,369,85,941,242,465,77,475,265,795,840,289,994,323,685,31,941,404,289,676,735,219,656,847,514,745,250,654,826,448,179,259,369,6,48,839,626,17,182,32,772,485,613,391,184,773,920,89,806,235,94,490,655,301,801,862,854,93,495,241,813,116,68,822,795,312,641,826,690,401,931,107,721,440,611,940,616,645,807,838,420,899,227,812,92,412,696,88,271,82,963,98,768,283,637,819,469,12,424,545,525,304,786,908,610,135,836,361,322,590,265,960,150,438,742,946,762,581,988,621,805,736,244,514,236,738,362,494,97,129,283,128,994,881,100,61,512,704,862,959,603,298,400,870,566,182,547,100,199,563,575,831,677,912,346,622,553,541,399,27,316,393,948,446,751,553,83,175,710,163,170,119,491,250,652,154,821,567,847,557,487,440,6,330,221,188,106,382,582,111,51,41,74,244,774,383,243,13,655,575,262,702,643,121,365,86,769,638,524,834,439,865,823,830,999,441,10,722,552,989,966,108,723,856,648,37,104,673,922,201,349,347,211,410,196,449,339,969,120,449,902,90,61,351,705,348,330,203,819,934,531,142,440,942,558,426,386,338,140,116,22,39,202,648,201,151,734,0,174,613,92,954,152,965,834,54,912,925,453,357,227,72,865,421,917,251,184,265,128,337,194,767,541,621,711,522,769,67,415,518,417,732,292,793,812,726,379,447,835,348,379,254,656,144,483,342,734,519,45,828,521,50,259,36,719,87,922,572,676,663,178,524,244,567,673,731,252,275,141,325,892,899,413,131,727,214,4,44,830,507,325,774,20,868,500,136,306,297,469,319,160,49,615,237,202,790,200,711,589,387,751,351,904,308,470,925,458,648,512,509,709,484,997,726,187,90,648,760", "524,415,470,733,263,169,881,17,585,76,281,162,952,279,423,453,642,331,566,802,667,281,491,548,92,788,826,515,629,206,777,981,532,434,943,671,637,52,356,82,151,486,983,810,887,724,281,798,746,674,605,736,184,799,52,727,980,282,974,145,669,165,382,575,483,929,387,291,386,129,407,396,196,584,449,783,742,178,568,653,326,498,627,75,578,382,194,43,164,659,367,450,944,957,946,96,116,109,614,933,763,373,359,671,628,844,985,856,775,715,952,164,714,400,839,719,719,244,439,480,210,674,165,792,675,8,82,915,450,115,637,857,650,959,11,879,724,104,118,419,562,961,980,677,749,700,537,507,897,89,68,720,868,994,940,837,371,769,660,98,442,284,512,346,135,78,883,389,740,643,632,612,763,746,872,906,942,413,906,116,783,285,835,856,322,657,906,234,922,912,285,827,635,334,696,760,148,915,774,77,211,420,965,35,867,893,966,133,168,866,890,659,307,527,350,387,153,986,513,145,553,502,785,61,130,156,809,786,211,824,429,586,569,102,15,415,119,279,413,110,363,258,205,15,660,349,738,343,603,591,367,309,825,416,700,642,383,934,388,454,174,224,672,250,388,639,521,619,356,285,473,241,939,860,317,120,581,439,164,342,480,912,404,562,598,838,23,534,652,692,532,609,451,288,55,876,31,481,760,824,959,451,725,650,289,573,638,870,266,617,678,39,703,984,179,633,792,753,650,314,972,817,741,18,210,426,315,879,516,648,221,376,199,848,14,461,41,449,956,492,63,485,349,559,716,361,813,228,952,299,351,694,548,449,934,243,864,976,397,116,116,527,259,46,848,73,590,199,985,977,183,655,945,150,731,893,487,458,833,989,6,994,898,148,238,608,672,731,80,726,894,124,70,314,585,117,226,209,397,898,863,280,678,237,922,770,402,770,286,708,18,852,3,99,725,748,241,16,704,920,339,649,440,712,628,477,670,721,762,344,766,815,675,65,100,467,112,208,60,709,41,499,450,855,587,474,596,89,386,86,237,416,790,151,120,571,683,367,218,516,29,121,694,715,226,33,436,770,656,630,878,674,376,141,968,376,887,890,593,440,480,435,311,162,645,383,441,877,646,307,263,657,294,5,970,656,230,207,402,826,781,787,499,242,75,893,569,243,194,912,351,59,214,274,340,580,910,716,915,634,896,160,369,41,123,488,442,939,241,696,882,139,501,304,260,926,842,772,300,809,114,629,275,201,149,586,402,946,349,834,350,330,523,781,977,832,546,490,612,650,834,462,436,7,518,218,983,934,390,432,998,877,358,715,354,331,791,92,711,60,650,452,102,241,781,794,650,245,612,780,352,665,934,800,22,639,407,979,786,63,974,991,841,610,670,441,446,665,147,758,91,168,935,19,266,922,33,721,783,297,918,897,194,176,519,545,561,662,610,468,772,792,192,450,720,264,589,460,441,126,513,874,155,12,617,5,473,209,252,714,736,539,511,495,692,648,27,63,21,790,723,670,182,476,718,530,556,564,982,944,124,795,778,889,264,165,420,637,984,900,687,558,341,28,285,784,983,516,92,188,894,513,197,781,29,681,312,145,594,196,935,551,583,979,588,980,33,434,147,345,757,287,893,111,679,419,90,900,486,972,194,623,303,367,67,79,986,996,139,361,971,433,284,379,257,413,400,395,489,846,654,430,722,977,572,793,448,723,252,557,476,566,168,488,494,324,429,38,850,895,680,853,56,965,354,910,389,478,302,545,478,612,14,178,726,186,304,869,227,818,822,23,509,991,276,546,174,200,300,361,40,305,940,605,46,363,253,342,79,437,488,172,151,274,966,805,611,954,230,66,866,614,487,68,501,79,195,220,502,947,717,401,505,312,776,275,484,112,124,912,41,783,319,334,46,883,908,263,750,306,137,639,935,311,166,400,768,816,50,570,414,268,25,498,146,718,249,860,738,226,472,360,655,716,864,775,449,429,510,890,823,227,594,531,421,341,633,365,899,174,0,944,735,309,62,325,963,79,538,939,51,300,619,193,719,16,408,233,411,76,121,407,853,995,24,122,49,481,960,549,797,744,423,603,518,672,715,590,853,520,276,964,303,988,662,717,314,557,913,742,21,725,449,270,227,957,707,908,690,21,917,431,5,875,47,109,399,350,245,202,195,106,7,703,81,595,786,986,899,926,749,658,816,717,407,875,209,856,541,510,303,386,620,582,905,571,415,977,382,812,852,226,810,966,324,250,785,615,138,941,448,504,638,273,52,95,149,648,231,480", "845,422,458,350,453,137,2,361,437,895,953,500,584,830,743,430,41,872,364,519,869,339,47,776,558,88,233,653,840,749,958,607,212,129,82,229,12,767,367,605,352,623,527,154,894,361,543,67,867,195,530,132,36,421,543,421,469,274,484,110,110,372,505,618,96,871,642,104,470,541,209,849,978,415,860,579,227,842,594,847,811,705,753,825,101,440,580,207,191,846,289,194,520,106,364,526,367,757,541,303,719,429,112,395,118,404,437,96,856,988,833,682,395,695,167,48,659,161,823,682,135,324,950,989,336,214,550,367,79,208,882,787,816,146,14,79,733,742,639,811,709,784,683,564,579,893,496,721,839,455,460,876,529,918,623,414,829,517,656,806,66,269,850,700,505,410,479,808,320,152,981,910,234,225,931,445,394,327,932,752,154,41,188,689,67,66,905,361,623,681,220,498,230,640,779,472,942,815,18,209,19,52,990,627,12,83,635,294,538,706,681,566,463,977,813,387,399,206,972,156,323,72,653,665,448,302,435,809,377,623,4,968,995,426,875,128,463,85,589,41,321,884,545,746,669,221,621,575,922,511,740,766,468,77,381,874,547,26,246,220,840,783,784,580,586,493,705,618,623,715,324,142,461,154,514,919,419,898,155,566,951,821,608,222,829,719,923,67,568,371,105,515,802,14,635,474,86,362,982,996,369,181,499,939,433,921,255,351,333,423,538,584,218,872,786,322,186,228,362,447,609,652,805,93,642,3,678,841,981,957,364,666,358,500,298,166,367,809,465,985,692,194,520,173,527,73,58,113,89,632,579,91,358,538,94,166,357,598,730,266,292,578,85,104,842,91,581,887,346,894,748,945,906,472,520,608,532,932,490,418,159,666,797,743,648,481,938,344,984,4,339,46,472,172,653,429,528,127,604,972,963,912,955,62,75,871,66,381,532,14,462,879,457,198,622,968,458,564,688,990,717,166,232,899,387,505,378,809,462,624,759,708,819,322,177,786,456,88,502,899,773,751,729,433,996,768,226,490,104,380,47,148,699,973,400,505,921,610,657,527,249,854,967,262,309,485,690,927,703,26,933,950,433,355,272,757,241,280,831,878,416,195,818,984,440,217,29,35,981,776,544,103,956,786,302,159,872,178,63,467,560,851,613,76,239,146,637,569,57,747,865,601,343,734,74,673,507,733,734,231,199,810,191,896,663,855,983,6,620,842,894,847,406,168,495,685,116,719,619,985,758,571,770,206,504,5,89,776,717,181,441,441,721,303,315,631,907,552,101,802,816,947,191,355,910,392,772,157,35,802,710,428,996,852,316,981,315,297,848,10,242,944,614,671,391,96,785,356,28,272,47,995,113,359,855,482,961,967,64,693,607,725,745,511,153,809,254,15,683,370,22,32,643,37,209,380,200,888,865,672,107,510,420,382,772,34,977,353,931,920,574,543,401,99,611,96,73,883,762,567,345,744,200,16,132,290,4,451,730,203,249,535,638,327,881,122,981,787,470,91,57,898,209,436,377,614,662,828,25,280,881,290,566,166,718,82,529,202,335,347,103,365,625,756,5,240,467,701,443,451,983,225,953,218,789,546,150,540,114,489,855,65,476,821,829,532,978,33,825,330,713,154,503,643,769,434,608,282,885,735,812,38,349,679,721,927,901,54,864,671,231,663,278,730,813,524,119,514,345,860,37,702,995,657,798,990,510,523,977,940,137,722,458,791,273,918,563,644,738,488,812,932,348,265,691,710,735,978,636,722,119,213,996,623,690,187,754,372,704,671,358,976,556,576,570,169,270,357,182,122,938,228,580,222,773,102,550,117,755,322,541,125,56,868,801,984,708,127,622,681,237,571,971,111,265,731,148,508,221,49,922,955,961,492,742,522,525,254,86,959,421,838,711,505,973,58,776,922,693,178,7,931,710,224,30,328,690,55,985,225,80,745,823,833,530,900,36,194,468,46,781,773,317,751,478,797,669,968,804,412,58,200,985,730,772,173,920,395,430,613,944,0,717,375,70,914,995,949,268,429,168,506,490,74,795,143,550,796,323,704,191,321,393,358,753,513,538,788,536,721,33,710,46,710,221,204,841,344,122,602,166,901,41,186,210,920,804,969,719,877,74,612,829,410,590,324,439,227,285,300,597,25,602,471,590,451,760,435,716,25,43,171,691,677,269,170,797,486,596,648,462,937,832,79,769,201,286,610,899,546,57,517,97,456,470,136,654,90,901,225,73,501,650,43,495,279,819,615,808,387,659,744,489,286,974,535,423,396,846,757", "281,808,710,364,400,866,760,52,249,886,539,830,433,942,995,379,464,22,932,99,986,360,180,322,162,17,701,840,852,276,409,807,849,499,714,255,403,773,117,103,62,298,553,512,841,772,175,73,896,493,102,373,140,408,941,86,711,852,827,995,499,858,955,868,637,993,942,168,395,834,452,562,386,488,660,735,349,952,120,739,852,197,777,259,288,106,411,726,904,983,459,882,419,727,856,224,658,669,746,618,567,158,615,988,858,975,479,505,355,333,133,854,209,878,511,814,415,607,856,376,384,43,352,158,537,229,90,73,312,561,520,479,140,411,109,178,949,823,665,505,634,37,411,153,971,672,818,261,335,822,722,840,382,23,474,718,45,344,436,238,878,656,736,825,259,163,14,932,230,713,572,423,621,601,337,178,900,907,455,851,283,540,370,778,455,552,469,407,83,493,386,619,872,487,727,125,198,244,352,994,980,190,714,695,371,346,422,220,78,829,453,924,912,140,360,569,508,497,692,245,733,865,643,382,109,203,260,262,362,740,955,151,985,168,165,723,863,925,529,42,156,817,15,799,82,990,193,140,102,406,936,540,301,177,251,676,141,846,400,502,581,697,439,33,165,966,344,532,734,583,8,471,849,829,217,333,400,439,281,579,530,817,818,777,126,883,97,669,219,225,920,175,279,494,554,871,872,515,244,752,892,61,786,27,345,415,286,295,937,220,771,89,169,174,856,423,77,307,740,241,867,169,940,319,544,308,912,755,642,842,250,779,25,901,59,761,966,398,236,213,537,441,633,722,594,125,863,143,244,794,439,398,842,423,174,957,534,535,520,451,634,582,923,122,331,648,512,854,460,912,892,393,124,526,958,749,541,601,522,185,134,890,949,284,735,642,28,931,41,496,680,735,153,824,874,91,907,268,216,979,986,626,919,66,99,353,476,708,982,189,590,81,376,106,461,232,651,949,857,207,866,871,103,173,994,762,782,327,821,422,498,383,759,989,240,810,603,291,737,708,920,771,784,143,896,165,900,917,96,973,753,406,291,28,434,160,39,753,103,396,761,976,508,704,142,290,967,240,396,75,560,284,676,547,686,306,710,209,760,768,937,733,470,282,469,974,142,986,478,539,659,326,220,537,359,183,685,545,632,557,822,233,586,62,429,984,68,338,345,77,507,194,642,762,199,647,970,630,240,881,584,672,237,781,421,350,46,97,335,210,805,453,897,91,371,106,986,305,983,920,60,523,841,188,616,252,825,123,837,985,637,870,24,62,501,926,702,164,313,321,417,431,610,668,268,590,342,187,102,601,47,740,455,624,777,523,735,106,498,863,571,163,991,209,366,830,736,704,97,923,91,804,371,315,479,445,487,569,444,508,131,253,572,436,488,568,578,529,269,455,16,495,831,224,691,433,349,239,337,475,577,116,330,149,311,781,423,253,552,26,341,540,426,310,805,880,100,10,973,740,712,923,886,915,140,28,930,910,825,155,273,834,565,628,516,584,99,676,17,439,824,769,209,521,870,530,432,236,248,94,366,806,937,181,867,860,696,556,67,937,904,484,49,490,64,373,250,386,606,123,792,461,992,239,940,941,224,644,544,615,273,273,493,306,871,812,625,729,579,183,817,519,346,332,800,699,544,280,486,819,642,886,967,227,520,805,759,79,817,370,888,700,699,915,716,219,110,695,954,295,426,157,640,959,268,760,346,134,297,446,519,40,898,238,208,100,571,719,554,462,202,242,101,297,726,417,400,828,867,721,860,259,289,768,45,466,193,315,511,632,776,894,614,145,19,703,275,619,643,227,183,101,625,572,645,290,692,545,801,319,180,515,271,69,26,284,210,46,314,981,4,707,240,881,295,571,788,680,888,609,423,346,856,332,452,211,869,453,367,23,86,492,964,258,184,491,286,773,896,51,905,224,29,694,642,959,194,862,109,595,294,260,935,402,96,894,371,603,179,831,414,611,476,733,829,484,431,524,952,258,821,386,133,83,994,896,919,516,71,92,735,717,0,845,667,15,986,266,549,637,886,243,937,16,305,877,396,827,5,349,535,239,728,696,959,910,388,187,208,636,400,26,689,584,356,733,450,886,935,814,963,991,548,373,461,674,20,71,739,864,60,556,627,736,335,888,283,797,127,182,697,436,828,531,105,583,489,557,583,976,945,655,421,58,557,500,415,944,982,773,554,673,982,419,775,270,553,269,655,982,665,867,310,5,635,928,50,948,935,167,201,491,249,286,991,986,279,724,574,637,363,155,54,670,86,200,198,835,772,242", "892,798,493,31,748,383,855,857,164,907,603,294,735,927,283,442,252,503,209,392,572,381,197,61,312,710,734,520,698,761,157,4,945,719,596,250,853,893,922,781,508,687,639,889,231,444,606,231,416,115,802,444,231,728,315,791,169,131,482,50,632,816,974,473,933,786,193,128,845,518,475,242,579,717,679,706,756,820,810,432,400,903,307,709,326,46,617,934,881,434,91,935,578,200,757,370,287,859,66,366,115,159,495,871,245,656,30,216,988,273,302,369,789,804,228,164,871,220,919,317,8,269,55,983,214,231,436,162,629,16,968,926,43,119,634,855,561,506,868,356,861,607,808,789,960,564,453,522,613,809,347,885,774,317,171,963,145,290,746,811,279,491,707,681,881,685,770,99,236,989,494,929,52,524,583,135,43,650,639,307,564,450,889,549,860,250,198,191,199,262,841,998,94,438,535,381,482,518,569,20,273,341,500,946,580,732,33,527,767,525,612,178,701,148,275,82,699,682,380,811,260,835,500,973,514,72,738,426,727,479,797,819,763,726,353,939,480,25,496,49,812,192,835,286,853,764,932,868,540,649,866,965,400,47,50,34,811,953,117,125,436,366,223,945,685,32,422,459,671,316,159,370,404,545,941,73,962,421,438,820,18,565,828,99,30,731,298,41,215,747,193,541,82,726,358,996,212,90,918,525,844,100,556,756,892,954,484,718,808,923,988,778,654,930,236,298,806,906,641,482,9,513,696,673,963,63,5,235,705,961,830,920,675,766,883,674,35,622,306,556,84,243,576,315,768,376,837,552,506,438,198,188,346,278,42,584,688,530,208,162,692,748,965,824,974,911,844,12,105,852,594,692,398,519,8,447,85,129,790,62,636,751,129,55,748,670,739,636,699,341,692,207,517,633,348,752,693,463,811,905,358,776,80,246,755,164,488,440,600,227,757,250,198,968,483,442,497,784,233,72,510,857,181,387,221,469,103,946,218,660,736,11,907,30,462,40,649,675,796,235,950,861,192,238,146,721,34,429,972,500,953,713,34,707,196,959,619,376,897,559,321,274,882,560,92,353,645,97,640,923,295,709,806,994,380,720,178,754,877,128,413,353,964,295,13,209,683,568,987,880,876,493,110,491,996,707,400,359,872,894,333,517,794,201,213,676,65,587,183,457,178,604,936,465,674,3,29,414,877,724,565,920,769,318,59,813,744,847,314,765,484,20,643,426,490,797,995,183,962,332,418,493,540,936,230,988,426,181,424,614,981,238,934,697,387,383,387,285,717,304,131,177,280,909,804,858,211,247,260,818,44,599,981,318,937,205,512,871,37,716,605,601,649,273,751,785,811,127,209,599,397,544,376,658,775,124,625,768,325,539,92,829,770,223,586,833,374,834,251,179,861,849,926,740,304,634,750,435,593,918,85,471,353,72,286,562,943,789,565,444,859,303,689,166,989,468,107,861,418,947,274,162,152,130,595,637,538,732,976,200,681,463,628,288,883,592,774,28,269,644,359,394,869,926,447,279,924,332,274,388,978,587,247,584,24,279,820,57,234,246,797,81,212,247,43,359,582,286,531,412,490,813,126,745,300,611,15,150,860,324,457,670,970,528,311,155,875,906,122,500,124,777,528,789,731,691,513,369,363,422,374,367,254,162,240,666,884,262,399,401,186,647,919,292,742,742,986,866,277,11,517,133,540,454,920,91,71,429,149,123,318,878,848,858,854,668,399,587,210,251,521,546,899,211,641,685,126,309,36,772,747,982,656,385,251,598,826,927,839,309,488,585,339,373,796,236,145,779,85,699,443,324,111,811,315,640,830,796,77,995,752,3,929,798,45,413,564,799,146,659,630,910,971,450,74,429,215,318,783,908,831,206,386,522,518,473,673,600,688,153,707,820,834,301,537,94,758,81,532,169,11,616,272,587,113,451,550,632,265,48,901,940,914,807,347,538,492,151,317,605,103,388,600,399,805,405,952,865,59,60,738,651,157,587,970,394,276,926,59,954,309,375,845,0,413,391,34,162,935,136,673,532,819,191,666,319,477,489,692,552,405,377,61,618,198,996,548,778,368,588,302,111,515,262,480,81,35,724,92,584,830,573,618,489,83,871,187,895,949,893,139,86,811,682,285,340,283,314,710,393,209,522,342,138,913,871,130,908,391,728,99,343,953,453,875,395,529,47,949,184,623,655,317,584,487,152,942,231,584,144,179,47,375,631,582,824,342,562,152,787,64,988,115,756,467,653,505,795,606,875,784,329,641,83,852,235,858,389,255,921", "64,299,378,590,515,219,126,637,304,254,697,348,348,767,517,516,154,668,768,633,347,327,690,746,82,111,331,440,981,876,412,812,631,655,436,558,405,700,985,648,795,809,672,683,384,159,388,534,799,41,91,302,663,345,662,71,388,916,111,265,271,695,99,643,382,646,59,165,388,404,253,816,156,537,261,748,356,796,831,442,675,246,595,459,959,169,454,502,157,732,826,410,123,462,560,83,307,791,663,765,955,554,361,626,512,434,157,935,362,701,263,212,699,580,849,949,513,660,326,37,846,846,900,26,748,510,94,316,306,870,425,474,558,519,282,136,772,731,397,287,104,696,697,434,225,175,850,356,655,779,898,103,183,720,380,866,130,852,648,595,742,425,361,733,197,525,12,485,146,572,117,740,895,616,861,800,993,785,34,353,503,226,683,616,317,506,395,551,621,344,34,975,840,649,992,698,5,815,27,132,798,445,758,500,220,513,810,84,444,249,326,268,951,886,535,551,561,898,52,391,284,266,705,405,589,215,653,861,685,706,111,588,668,242,374,104,62,521,471,485,228,64,514,248,848,255,236,899,296,672,833,136,887,241,689,535,709,681,89,859,768,449,547,856,260,148,35,697,767,49,943,529,701,570,22,107,278,852,562,507,390,235,710,763,375,541,809,165,522,382,755,378,537,945,992,297,629,953,802,734,430,299,234,636,644,733,482,804,887,808,459,859,555,510,166,72,258,831,617,699,497,393,675,561,245,978,992,415,835,10,734,687,324,479,328,573,82,491,852,645,57,925,456,965,588,976,303,934,486,108,6,295,629,398,419,667,650,235,658,429,319,793,417,528,529,135,633,677,932,694,144,909,644,679,53,555,99,81,570,778,365,303,765,692,435,648,60,475,685,986,307,789,936,462,761,40,847,958,804,185,39,546,209,650,175,600,973,492,571,369,791,988,49,101,726,829,223,922,980,781,770,340,6,68,676,737,10,291,203,647,2,434,673,613,601,977,695,621,16,551,288,594,363,662,477,439,224,504,718,822,121,761,172,925,862,908,214,226,88,579,436,980,876,118,206,647,726,970,424,296,953,26,450,181,343,62,463,791,905,969,563,379,414,41,123,275,138,400,365,61,783,431,45,397,404,430,742,487,903,955,608,105,466,116,882,411,256,620,444,811,1,985,130,491,603,835,819,452,109,18,402,283,26,369,216,892,589,757,304,905,755,866,492,383,483,359,282,988,849,155,602,267,186,361,907,147,447,887,208,915,516,133,7,352,302,662,545,234,237,652,37,15,462,187,432,440,206,272,423,726,916,412,504,804,807,408,892,967,385,519,904,90,273,863,99,995,859,3,148,670,490,305,356,384,547,561,55,224,63,940,990,882,166,922,148,886,679,143,367,656,817,450,625,275,167,849,322,273,271,230,835,43,728,991,709,248,411,393,972,917,241,108,616,506,726,45,157,529,818,839,129,696,336,536,681,363,381,366,377,926,369,169,846,64,940,67,501,111,596,324,399,679,303,765,42,873,932,899,18,974,803,290,127,558,694,33,278,742,286,630,947,537,925,320,824,885,403,379,985,256,803,742,146,6,363,604,496,956,647,189,860,64,584,428,742,900,748,259,584,589,240,506,392,237,454,459,261,646,604,859,303,832,282,149,398,716,715,633,697,845,431,825,772,186,764,355,630,198,24,194,921,311,520,29,228,929,495,371,937,519,472,854,522,379,115,125,195,460,581,222,513,519,520,564,859,910,233,711,229,887,541,997,617,779,21,751,912,29,326,115,861,188,819,41,772,838,965,832,323,138,402,793,225,336,536,789,849,416,956,978,153,338,251,978,994,420,493,402,908,589,670,480,827,655,154,781,553,614,70,257,920,576,844,875,161,759,825,505,19,501,573,946,825,52,220,148,901,583,343,263,38,51,999,527,660,127,899,789,561,622,969,191,131,764,895,26,441,978,390,405,189,733,784,100,202,83,171,693,332,570,790,758,419,154,851,81,201,795,948,152,62,70,667,413,0,467,74,23,711,747,965,877,530,279,46,397,313,434,201,45,124,394,498,768,409,143,313,822,79,299,837,909,205,222,68,702,933,430,809,51,976,534,984,69,791,274,87,968,386,870,598,689,856,62,933,523,696,649,930,488,176,31,127,752,501,677,206,225,146,824,440,701,734,616,506,436,506,278,492,501,799,128,931,627,445,67,431,420,222,40,67,269,649,606,130,549,425,666,503,277,483,938,686,375,412,666,610,58,549,737,911,766,854,777,22,274,812,740,608,826", "50,683,467,971,777,304,747,424,867,354,982,910,497,138,905,330,221,536,668,124,642,290,732,802,888,92,862,999,739,92,138,622,758,830,344,306,438,730,52,202,333,488,515,428,350,782,863,98,631,836,684,402,470,266,838,639,302,644,611,720,464,876,872,110,896,50,140,344,862,525,9,697,146,782,914,474,762,528,285,483,813,990,485,96,228,993,677,276,742,340,230,504,277,77,860,612,121,563,297,553,853,691,39,55,812,500,771,642,989,275,220,901,201,266,737,503,749,998,948,428,584,266,910,721,794,842,545,782,262,614,482,621,386,695,844,335,408,976,949,65,271,496,877,459,275,511,36,15,936,303,18,324,808,723,626,537,12,564,856,681,633,22,878,905,369,75,878,864,225,827,390,996,534,395,411,988,456,890,354,654,930,38,749,45,681,810,933,418,588,783,121,398,626,15,933,515,256,534,804,480,534,946,951,449,338,914,425,234,328,324,278,615,648,688,999,793,722,857,481,443,544,153,566,582,904,653,953,583,603,712,355,859,889,42,554,845,888,637,307,937,148,759,285,839,735,273,670,836,570,180,852,935,18,53,79,478,740,559,699,431,418,527,407,746,30,364,552,484,59,463,161,112,515,331,885,313,736,330,31,729,5,294,377,186,274,655,708,373,256,599,284,49,300,268,190,614,917,803,625,331,524,774,106,926,830,34,91,998,558,454,672,377,187,909,437,709,451,541,433,328,479,432,763,87,537,178,328,783,167,549,393,898,667,74,353,879,350,706,469,762,74,570,198,548,21,411,4,432,947,102,749,51,426,913,289,163,213,935,969,280,729,788,714,296,662,204,72,261,369,644,950,795,210,185,208,511,127,287,45,831,455,301,190,203,519,694,182,935,935,571,902,25,523,424,809,375,740,83,820,975,773,824,889,327,851,47,31,111,475,101,555,888,576,558,233,467,111,242,869,789,954,65,222,180,818,562,895,248,984,307,399,762,834,469,669,964,303,849,113,348,907,4,98,860,894,50,435,733,20,590,524,325,696,832,485,929,409,930,900,162,468,859,388,769,411,679,387,712,977,188,178,136,234,634,375,975,915,427,315,183,188,412,62,599,71,312,142,692,880,211,213,627,207,538,991,209,619,207,85,475,898,475,99,311,199,290,696,789,446,98,849,706,794,842,620,277,873,804,64,581,713,242,601,620,648,301,891,334,834,79,640,404,804,707,351,812,769,443,707,294,391,942,388,657,818,929,375,800,392,657,374,572,41,311,311,542,973,208,514,867,882,221,185,742,749,513,619,418,596,873,598,452,760,930,22,380,419,579,886,763,338,774,237,843,773,578,752,151,885,429,538,838,803,963,816,832,737,668,514,572,650,595,198,256,988,909,422,536,178,89,173,420,468,328,280,975,22,802,354,252,931,396,608,272,322,720,217,14,371,411,581,186,579,494,425,243,344,351,521,485,597,922,883,433,725,243,852,805,620,103,976,586,931,53,548,471,525,758,259,219,633,399,42,494,71,168,937,339,257,497,278,498,155,538,775,716,364,121,426,548,236,960,636,379,211,952,339,716,489,72,614,405,590,103,200,843,556,445,774,538,643,967,633,844,379,104,425,838,563,481,535,160,938,395,391,263,84,709,825,4,267,806,493,452,843,512,36,447,301,483,557,744,271,93,140,388,500,678,532,556,558,571,212,174,242,26,884,337,544,541,71,485,408,847,260,358,436,848,571,398,968,158,53,366,156,167,404,536,275,811,677,480,143,456,609,40,213,723,382,977,392,42,367,619,969,427,516,607,575,502,779,457,359,285,252,954,443,927,604,2,91,238,714,739,355,50,751,167,367,880,109,262,435,664,73,45,58,649,540,211,214,106,665,99,25,63,647,537,686,918,438,461,806,725,93,916,182,953,441,304,427,58,221,341,284,528,991,643,621,839,471,782,466,951,59,252,602,948,177,961,961,778,129,752,135,823,121,110,537,948,305,181,829,809,177,677,124,125,382,965,325,914,15,391,467,0,348,205,545,636,636,194,439,13,512,194,413,601,176,956,56,209,474,724,732,732,145,470,331,161,169,10,135,134,22,243,970,551,797,749,13,764,365,357,904,275,795,830,670,249,991,982,494,80,460,836,232,180,479,79,94,965,799,76,155,591,667,189,732,9,384,135,362,555,347,940,354,356,797,303,58,770,179,303,100,183,964,515,890,547,540,439,473,995,820,873,220,262,897,513,752,103,619,228,991,465,199,167,588,923,17,846,272,406,920,227,791,741,87,765", "994,47,194,381,114,546,839,587,500,219,271,203,743,775,6,652,177,751,183,632,393,321,966,352,886,518,923,584,230,32,668,355,263,29,718,953,838,156,784,869,775,66,628,932,779,965,98,389,868,974,571,486,839,176,165,579,291,532,918,391,717,407,480,815,92,996,364,544,612,106,397,676,559,941,956,653,350,14,858,142,221,487,717,883,104,630,492,808,714,976,638,686,294,149,175,284,784,338,953,561,99,680,810,988,354,993,984,598,624,765,870,865,330,362,590,424,249,478,964,384,164,840,301,186,636,984,914,534,415,174,616,98,522,635,898,231,425,124,880,191,856,531,689,510,83,156,730,578,199,920,874,201,775,256,865,767,902,274,553,625,859,831,531,932,564,119,630,637,551,316,708,336,158,613,859,182,26,268,325,686,482,591,625,13,318,261,546,812,562,260,842,828,862,409,386,331,513,627,669,48,604,352,933,965,220,597,453,812,430,394,531,382,294,981,522,624,800,840,279,347,495,390,213,578,738,18,496,97,988,653,814,565,761,566,254,156,88,250,28,368,207,398,533,244,544,568,212,537,371,685,434,889,880,875,446,807,294,388,146,174,944,986,819,643,245,751,980,980,149,427,426,930,634,832,767,553,170,517,752,825,360,248,51,658,575,315,368,606,266,7,671,765,846,267,441,344,188,749,851,153,276,131,735,639,303,558,392,700,574,799,70,852,338,657,849,437,534,130,955,880,238,342,191,690,378,406,372,891,881,350,529,472,818,212,750,82,717,822,306,408,271,831,54,874,242,49,423,773,865,860,317,598,384,15,214,629,352,43,50,452,578,601,706,702,718,740,466,758,522,251,218,959,646,689,165,140,931,284,831,161,591,245,69,402,917,992,217,15,620,33,987,868,803,334,114,226,391,302,549,69,271,174,894,950,455,429,444,724,745,530,796,823,427,669,40,905,589,739,229,154,853,614,233,233,600,820,944,634,325,796,555,742,985,69,88,546,374,822,471,7,619,756,273,256,53,502,576,844,372,106,625,329,828,983,187,327,578,723,989,113,607,943,81,147,281,568,61,72,568,954,704,224,353,71,100,609,890,899,113,214,827,135,13,677,593,187,909,156,661,956,26,899,329,439,663,112,27,214,5,63,531,926,531,987,165,387,849,908,938,335,342,371,521,921,514,515,794,529,446,883,655,524,718,978,454,279,269,436,641,215,66,41,938,38,4,121,274,35,686,823,199,624,136,444,979,98,179,747,485,945,399,337,509,432,598,821,215,472,89,305,48,506,119,369,811,134,738,874,252,56,839,535,621,116,88,826,361,429,897,698,209,154,485,32,758,211,834,160,837,282,269,963,798,307,810,515,119,746,114,824,664,173,889,428,871,77,729,154,797,578,452,311,4,591,684,286,433,726,855,267,841,857,921,842,414,659,110,847,673,706,681,803,955,509,957,284,648,807,657,12,849,137,573,294,480,239,528,739,363,811,602,499,653,139,560,882,226,762,428,844,314,67,519,151,381,750,527,475,143,609,738,927,539,787,284,110,662,620,409,180,283,534,963,732,256,281,428,123,319,602,73,268,788,166,747,7,179,784,920,755,900,896,977,762,104,448,44,520,175,902,699,721,641,689,976,17,460,405,17,167,89,893,227,149,209,855,621,74,324,152,807,377,677,496,879,330,974,704,36,568,627,639,718,684,515,312,203,865,839,103,556,536,373,998,435,490,514,820,418,677,512,465,999,600,584,303,318,304,337,764,331,390,730,850,470,25,122,135,548,489,682,427,66,101,57,378,8,532,749,41,783,981,280,434,629,645,190,789,611,399,353,430,660,415,23,119,146,893,688,992,993,171,998,119,731,207,784,902,766,904,438,698,634,608,699,351,383,38,289,47,147,101,845,169,301,336,254,266,427,939,466,598,970,325,563,211,40,67,196,299,357,208,950,717,693,313,441,221,588,609,477,438,927,82,998,449,471,728,130,203,372,962,518,626,937,337,681,694,72,834,963,995,986,34,74,348,0,244,394,302,638,965,73,680,372,771,900,767,445,663,481,295,744,693,371,183,881,608,376,142,767,409,782,539,818,875,190,6,267,557,50,339,358,648,847,494,660,311,213,415,93,270,163,903,712,450,731,823,355,517,663,306,517,564,774,100,227,163,157,970,404,70,38,824,749,989,325,898,77,208,671,314,320,830,517,143,10,235,33,325,855,512,77,745,27,692,549,327,867,945,648,260,123,660,522,620,365,738,765,894,292,312,751,984,874,995,14,444,134,160", "630,260,984,803,893,576,402,424,212,744,78,898,258,731,730,752,375,588,869,702,987,571,255,152,523,172,164,768,195,604,773,856,895,183,609,913,950,401,468,124,590,413,652,930,181,407,886,558,329,342,586,274,60,835,319,737,575,269,379,158,672,651,551,970,764,199,940,305,800,185,599,68,88,291,323,670,861,35,267,777,623,222,552,38,635,479,86,630,922,686,217,305,965,711,352,426,849,989,276,589,21,731,139,495,496,32,476,125,600,695,797,472,768,928,758,649,698,323,22,811,375,231,425,545,698,163,982,509,22,417,713,570,288,692,935,28,743,267,334,993,619,234,695,456,702,969,62,674,82,901,727,139,440,355,596,961,525,168,406,106,551,856,551,657,277,224,364,123,558,799,607,632,619,307,501,627,854,72,632,119,594,386,271,248,931,327,834,217,872,736,323,354,256,85,865,736,881,977,443,865,5,709,256,75,231,810,180,185,483,435,409,845,110,611,906,352,867,576,187,120,674,567,705,8,387,851,486,207,815,827,97,627,136,654,566,792,386,371,497,189,333,437,82,518,669,811,36,15,484,576,258,236,611,952,617,35,502,403,924,310,95,169,847,394,839,716,294,515,810,658,762,988,986,793,71,503,968,24,259,433,535,374,564,648,243,121,489,237,786,617,528,83,329,266,643,867,677,558,190,33,211,892,872,174,432,545,52,38,821,404,64,388,1,902,856,893,867,669,304,37,323,360,958,69,241,329,922,190,109,980,578,406,688,325,439,85,724,940,306,910,454,947,338,782,857,995,500,27,189,437,677,214,538,878,573,960,851,192,584,76,65,997,345,255,727,843,374,486,104,911,222,916,997,55,294,523,114,573,615,918,164,652,976,374,137,364,644,327,93,118,658,753,552,259,840,47,450,767,877,684,408,753,968,339,558,388,461,980,767,771,159,265,113,244,24,247,977,120,435,349,290,616,568,807,694,374,906,109,831,233,30,969,947,720,162,746,677,960,815,111,894,813,269,34,598,912,500,190,716,909,337,144,919,670,864,285,807,141,525,432,382,753,899,744,603,633,491,796,764,63,891,328,866,225,528,812,494,559,563,15,601,508,506,529,567,390,174,360,356,354,679,331,7,926,787,280,775,79,865,634,537,299,698,737,590,458,991,356,435,397,486,115,695,87,562,937,56,106,639,240,556,664,381,748,144,124,310,178,385,538,292,832,273,606,770,796,875,202,824,818,987,182,196,796,980,259,27,422,535,986,715,268,391,230,323,496,574,436,802,418,528,566,138,557,97,311,950,568,660,961,60,552,725,510,78,390,115,534,453,564,865,787,723,827,708,886,814,396,157,472,387,46,961,759,348,81,367,237,809,666,919,333,829,716,836,946,241,307,153,976,842,672,194,339,75,407,6,826,835,774,562,200,334,681,635,963,811,940,529,453,396,562,916,185,491,167,791,428,195,439,844,284,426,97,828,899,404,716,661,482,277,887,268,172,256,745,10,835,462,927,634,916,338,561,342,608,357,932,476,970,252,62,3,717,547,866,620,684,900,445,571,114,875,210,276,514,927,934,165,799,756,503,440,300,716,606,637,487,305,340,822,446,992,837,777,801,546,307,611,303,34,244,174,639,732,769,431,308,628,186,503,670,547,562,184,968,871,213,799,336,836,980,664,61,154,671,670,400,394,946,105,590,203,956,269,30,549,653,521,510,688,173,811,558,965,736,46,267,803,950,674,438,488,158,457,657,697,220,66,871,585,974,665,858,7,260,117,25,482,778,12,730,141,14,678,183,635,8,215,427,932,285,6,441,351,1000,762,234,560,782,900,459,867,670,262,656,718,362,3,479,497,215,755,192,366,238,853,260,729,942,42,869,286,195,729,585,240,592,258,705,439,72,90,604,511,260,585,918,378,55,748,240,859,249,16,768,860,983,893,893,303,970,288,497,24,348,478,140,348,473,354,361,198,405,452,422,256,624,762,552,949,128,949,973,386,275,255,949,644,54,79,949,266,162,23,205,244,0,912,848,789,253,699,933,543,87,936,323,69,774,272,600,195,524,321,131,921,791,854,862,832,414,160,104,184,177,64,259,153,271,304,412,103,845,896,145,597,392,874,513,969,366,319,390,181,118,340,508,613,266,400,654,666,320,173,358,442,497,486,67,109,812,286,182,917,241,451,874,925,117,80,180,170,322,258,996,143,162,389,359,580,857,122,69,821,643,618,900,479,999,44,553,257,827,50,896,400,668,370,916,583,195,325,845,674,667,398,117,864,604", "380,871,178,419,20,342,158,820,69,842,908,456,797,616,328,60,905,545,755,190,368,635,94,843,591,798,189,26,953,543,812,651,989,599,336,75,654,439,540,139,875,295,903,996,355,517,20,603,923,432,624,547,115,679,490,72,658,135,676,662,945,912,832,558,127,836,510,547,593,311,82,24,918,158,962,142,959,130,506,311,36,350,17,316,486,845,697,587,733,157,515,766,771,975,268,447,71,987,891,798,927,422,25,414,707,769,335,191,610,825,103,388,153,279,659,181,760,775,711,846,446,6,527,222,982,468,537,743,763,882,248,482,207,282,967,221,221,890,85,458,244,138,338,837,990,563,695,352,122,581,592,378,135,277,757,730,308,373,100,543,393,252,797,783,196,688,20,211,107,681,79,588,983,360,797,115,326,275,596,741,101,945,141,658,367,200,967,894,366,260,320,624,445,156,127,73,556,687,376,666,678,508,28,992,879,487,5,226,241,572,492,194,141,431,635,459,838,396,711,943,722,805,946,502,322,783,692,915,167,503,147,955,266,278,15,787,196,11,515,534,200,924,359,457,76,950,196,795,411,153,68,908,297,542,81,108,327,26,285,918,384,804,934,457,935,730,517,373,223,478,553,686,712,650,303,916,636,555,955,70,901,232,468,372,54,684,510,370,777,463,88,218,534,947,18,866,831,189,8,107,188,521,906,12,590,997,390,14,162,16,893,954,969,648,633,668,582,722,312,520,919,133,325,449,805,586,614,71,860,170,39,921,786,937,845,280,665,812,157,457,162,759,658,276,76,195,39,20,333,566,457,149,791,50,148,704,485,747,359,764,601,142,373,709,500,728,38,435,613,698,203,747,114,311,985,625,909,292,554,617,275,23,478,907,691,177,947,660,903,983,262,893,89,836,630,426,548,924,48,629,633,990,530,180,428,99,584,453,91,336,125,546,237,167,514,16,414,894,108,928,102,111,409,997,477,373,398,60,398,183,316,593,180,483,812,25,733,724,883,254,552,468,18,660,309,145,245,642,404,696,664,114,784,75,421,735,159,851,517,427,505,14,750,903,213,648,50,1000,625,469,625,236,770,514,38,637,204,241,134,338,171,521,229,149,81,17,499,912,470,273,328,311,854,232,191,610,4,888,684,679,22,831,711,636,413,537,654,763,465,736,796,679,745,354,721,331,274,834,558,620,986,789,918,457,594,103,696,980,234,630,640,124,248,165,589,302,650,104,662,677,627,328,590,534,664,189,707,948,546,416,473,889,977,427,633,260,237,841,891,830,234,522,911,849,252,344,191,642,276,685,428,253,922,147,502,727,382,527,606,766,875,73,801,629,807,418,751,83,624,380,274,284,98,914,297,478,938,965,668,462,887,537,888,488,444,988,918,990,365,979,647,174,94,721,542,740,812,841,983,402,283,818,350,224,735,452,453,57,23,87,17,721,518,130,155,284,788,52,115,656,671,724,187,243,965,743,473,755,940,329,287,489,30,500,36,267,13,135,12,798,850,41,654,504,721,798,255,505,252,276,877,548,507,711,575,731,924,924,58,281,110,221,984,462,560,680,460,615,391,704,181,264,10,303,331,596,478,588,242,753,439,626,920,385,841,589,850,943,394,784,228,9,282,801,511,842,77,120,309,375,445,336,584,437,502,608,747,551,477,50,146,376,924,705,485,313,117,238,351,616,565,33,829,230,770,489,115,998,376,101,24,686,774,7,162,579,198,309,954,632,178,883,378,671,824,93,368,10,414,830,899,918,268,6,619,297,18,338,815,733,851,240,260,363,150,981,898,366,876,875,708,65,563,350,40,472,275,184,752,850,89,671,206,995,737,564,276,922,825,540,60,999,785,435,316,607,799,39,188,111,387,152,925,437,637,686,980,643,507,207,904,517,39,518,671,637,382,698,674,988,77,299,205,106,178,421,774,261,418,469,91,373,15,450,927,952,796,72,44,397,215,855,316,919,233,857,766,900,494,261,974,613,270,148,363,791,395,186,12,912,538,268,549,935,711,545,394,912,0,411,789,904,748,931,647,67,724,229,229,398,394,755,420,799,594,880,436,321,762,182,983,299,915,340,705,291,857,336,286,741,852,275,692,468,242,101,825,386,825,475,473,365,249,853,484,361,435,383,508,172,911,347,356,499,268,301,606,2,273,510,755,703,179,161,610,522,539,128,298,189,593,160,219,331,606,993,758,745,426,445,229,36,461,944,701,912,607,933,600,825,239,252,681,973,673,313,295,311,777,170,344,496,951,51,999,302,122,596,624,184", "785,344,44,488,299,500,193,616,839,205,673,327,644,459,777,402,72,184,598,206,400,331,71,306,129,28,316,34,456,498,522,512,513,297,535,59,243,581,250,916,93,109,63,41,325,721,253,774,828,275,706,556,402,467,735,837,70,683,660,131,320,866,951,877,295,357,453,705,963,278,480,97,688,249,779,259,632,457,47,605,523,771,489,895,25,273,709,691,233,221,903,688,732,591,698,509,790,406,363,569,259,214,616,437,915,611,974,689,714,590,126,143,191,530,543,258,48,461,89,524,312,41,797,668,766,960,240,631,529,623,858,395,368,314,732,304,584,767,537,88,997,16,326,678,403,632,945,231,407,171,568,313,952,33,996,865,806,989,110,777,531,768,514,365,752,257,598,544,850,635,379,227,340,842,650,276,205,877,557,631,785,808,971,760,768,263,377,626,530,570,649,780,409,939,682,126,333,278,34,120,916,346,313,955,755,932,217,191,379,197,541,254,827,234,179,130,29,976,186,109,39,286,384,759,761,838,109,854,511,930,12,769,492,74,67,186,756,857,437,743,927,544,405,351,139,566,547,978,27,375,628,645,240,758,578,541,868,507,52,65,903,341,270,907,389,469,305,277,413,585,847,235,703,90,302,476,624,90,716,295,256,862,71,292,675,329,912,542,687,422,473,734,518,283,50,567,641,813,490,851,649,995,246,865,347,905,698,104,880,813,672,231,160,283,146,371,28,732,421,758,961,906,492,922,203,689,710,361,483,37,107,762,138,657,556,953,347,591,539,831,696,563,200,723,135,881,866,358,727,74,438,636,208,877,180,819,957,363,988,625,452,618,39,306,559,580,727,364,997,195,323,972,48,262,452,598,580,620,554,48,95,434,822,603,833,79,817,894,381,890,288,107,792,703,753,590,993,779,926,876,914,12,64,75,712,366,555,820,897,47,653,64,441,894,664,510,764,965,927,639,300,905,712,73,48,409,659,242,645,920,329,585,785,539,587,652,87,280,101,5,169,672,773,862,986,436,884,567,849,730,731,780,913,959,964,411,428,838,464,182,536,293,602,786,799,195,582,205,91,576,403,992,979,426,450,8,373,822,576,569,9,311,809,75,695,844,57,932,483,131,20,916,526,528,559,768,185,709,827,787,310,834,226,989,218,657,299,815,383,64,778,14,617,761,701,751,9,54,905,981,385,346,608,846,779,627,179,558,159,258,385,210,189,280,359,89,476,463,836,466,643,701,846,45,93,95,801,526,911,177,768,31,301,238,20,118,693,333,37,962,472,930,667,434,800,556,236,836,659,78,470,183,190,629,281,6,512,260,496,752,151,243,236,48,534,314,981,610,444,652,825,535,761,923,747,846,8,911,90,361,187,918,44,754,928,856,119,724,962,581,959,738,480,622,374,184,819,44,608,47,846,624,421,802,810,17,760,909,893,434,866,356,104,437,989,771,879,935,980,192,129,319,452,437,781,410,956,86,475,342,84,698,176,341,436,551,432,65,592,311,22,14,876,366,33,234,479,940,593,878,393,223,445,963,437,707,521,624,283,501,594,262,332,6,437,306,869,208,965,678,408,660,593,262,805,929,160,244,871,674,541,792,489,7,176,809,996,5,424,523,582,906,280,789,719,191,671,145,425,25,716,837,555,644,333,391,786,357,453,696,574,780,890,334,899,865,802,272,272,608,384,653,300,455,488,273,307,306,7,980,298,738,66,34,711,665,778,421,916,604,547,310,881,420,684,393,66,159,950,601,130,656,684,733,5,820,796,782,539,639,89,324,159,959,882,775,680,941,717,875,989,93,908,640,398,235,126,215,109,840,150,666,761,295,210,361,365,122,287,796,755,142,404,592,987,17,909,608,854,349,740,552,651,900,348,882,234,730,479,219,887,884,646,276,344,814,331,328,49,728,977,214,494,924,484,627,883,459,157,235,520,120,889,718,688,281,164,928,883,410,607,942,620,81,6,624,719,580,927,615,691,553,781,27,350,836,199,825,521,925,939,429,637,136,747,636,302,848,411,0,996,967,17,20,855,870,479,269,897,696,121,301,651,429,477,721,424,749,746,412,859,785,870,90,536,399,841,209,578,482,255,868,956,178,411,475,628,903,986,908,906,638,194,376,657,246,340,983,811,17,976,126,522,194,232,223,908,643,810,594,861,110,960,859,974,713,793,585,167,40,182,162,739,283,284,751,326,739,282,553,620,89,789,620,563,38,198,817,768,183,609,92,483,667,855,23,865,135,165,558,540,498,539,173,79,687,311,110,100,935", "60,638,765,319,530,682,933,400,938,307,214,138,52,752,290,719,284,782,770,920,243,846,22,793,863,474,844,767,81,63,98,659,203,903,915,843,870,874,245,811,89,889,896,661,386,815,996,781,503,251,405,249,12,926,491,244,334,815,511,520,937,158,496,332,843,210,269,647,831,298,950,345,947,502,308,916,958,797,122,839,68,230,811,99,365,687,950,132,553,781,142,716,671,825,504,57,607,997,646,326,642,245,643,841,164,401,324,94,82,874,916,396,462,293,623,438,336,501,974,29,207,19,805,262,931,395,773,993,356,853,318,711,285,114,810,354,903,524,3,249,620,219,892,925,955,594,475,145,496,995,226,794,42,712,701,646,583,281,308,654,182,889,746,515,845,662,509,133,538,6,992,902,422,891,111,857,879,754,457,177,5,946,297,386,132,982,633,57,494,654,588,852,370,957,831,1,298,37,35,974,133,408,334,631,172,245,260,968,640,447,355,778,304,203,700,122,699,46,51,206,415,436,668,331,523,860,950,992,426,13,905,467,169,704,709,250,454,152,779,897,363,975,259,19,970,8,241,793,305,96,373,444,291,303,460,611,384,823,230,386,69,953,54,928,260,433,286,298,379,118,751,850,731,123,945,692,360,875,267,918,743,174,81,307,369,706,953,63,22,743,735,463,367,893,212,125,442,770,739,159,401,854,374,963,808,224,485,709,800,793,123,678,612,628,815,893,693,241,284,832,448,548,515,880,867,744,827,770,482,355,864,75,3,662,514,172,885,737,450,269,737,905,528,585,257,518,774,218,1000,739,875,819,812,411,524,664,580,257,384,254,624,561,941,701,645,939,254,695,226,124,488,542,733,496,528,594,203,235,673,106,126,724,41,92,832,894,948,554,69,426,393,483,776,23,581,277,756,296,189,795,387,895,263,841,465,466,818,460,24,735,257,426,641,387,770,117,204,242,694,29,176,873,549,739,927,782,919,265,346,996,857,639,886,408,195,908,49,528,754,163,78,494,353,926,590,671,130,129,647,67,242,827,268,792,38,746,781,87,669,589,539,166,267,544,259,807,347,321,712,639,404,773,228,140,310,516,520,741,732,737,353,226,756,790,838,765,472,755,772,823,249,54,597,45,641,835,955,289,59,156,946,755,599,31,739,357,145,315,720,890,542,470,192,332,232,516,47,964,703,109,776,810,986,736,412,947,701,538,66,553,96,943,884,576,296,81,237,530,343,465,217,560,718,629,892,769,144,749,966,51,630,799,238,545,881,178,808,985,558,628,401,324,378,356,894,193,709,448,285,206,75,709,374,253,334,55,650,87,348,631,741,268,729,58,81,935,871,549,333,553,967,178,405,92,702,166,643,428,343,229,856,11,271,377,582,909,619,187,142,584,706,738,117,26,207,310,200,507,505,509,449,541,396,227,189,125,116,773,359,653,817,687,259,406,78,11,312,279,930,57,647,875,975,49,271,442,11,731,384,57,383,335,388,450,321,213,807,2,269,976,668,865,505,27,240,350,380,420,482,723,381,405,787,114,179,933,704,491,844,530,968,837,284,394,739,547,378,804,223,461,757,68,78,500,584,768,34,284,228,152,107,53,466,726,240,505,248,808,146,651,127,783,815,951,306,384,205,327,334,877,149,561,347,776,965,539,443,540,904,525,738,467,606,980,668,634,741,797,570,69,330,860,358,662,409,517,643,827,631,769,154,332,545,812,136,52,645,647,254,836,301,607,153,699,176,621,350,335,280,17,888,953,25,603,886,522,754,239,863,437,955,245,725,14,143,863,182,847,575,14,604,505,93,388,708,79,543,914,547,682,685,844,847,666,675,182,665,290,662,496,145,525,631,828,741,678,123,800,803,8,792,543,135,338,54,221,590,829,171,268,925,342,2,812,643,708,77,675,406,572,84,743,979,916,289,550,194,861,873,454,601,215,789,570,765,456,794,879,939,329,467,713,6,832,901,180,289,711,28,378,169,85,740,618,794,344,453,192,508,453,51,168,886,673,965,636,638,789,789,996,0,12,307,993,399,19,591,190,281,388,551,877,805,913,388,69,984,447,947,476,202,872,852,681,467,258,583,611,740,827,149,202,361,712,615,531,192,759,126,809,696,314,785,905,422,468,612,536,115,959,382,515,59,509,907,867,594,654,763,839,254,463,837,850,859,458,185,960,198,591,864,849,821,883,918,6,252,52,357,899,953,7,729,669,149,479,546,649,213,180,427,89,97,229,392,688,26,646,115,958,972,957,373,435,230,300,196,634,795,562", "341,799,755,131,472,873,445,126,689,277,78,492,94,168,708,75,758,995,218,421,788,186,863,161,712,983,214,601,637,887,732,291,840,537,694,523,925,871,359,556,584,545,150,711,130,159,449,870,428,394,859,120,515,38,664,847,304,379,458,431,631,323,736,882,82,430,90,387,70,230,926,244,943,680,958,874,755,428,708,973,891,585,311,419,727,589,29,429,94,219,543,639,757,258,588,123,522,382,832,923,749,874,459,445,504,331,309,876,574,368,305,88,468,560,34,809,18,336,70,47,317,82,384,471,227,556,125,207,517,925,712,844,928,408,616,808,665,203,518,412,759,696,259,855,648,128,366,690,550,555,189,986,994,174,642,448,642,964,772,150,247,532,144,906,145,210,720,944,589,623,521,813,765,189,398,719,161,445,201,182,17,959,998,625,697,257,278,860,856,706,42,754,505,679,833,370,675,662,500,275,791,415,600,107,742,5,521,387,621,542,731,42,275,220,366,893,952,433,949,854,991,415,540,457,810,524,252,483,490,899,351,349,954,391,16,635,318,561,405,33,984,56,290,238,785,767,5,326,315,192,81,138,759,331,923,670,131,792,228,679,219,481,749,89,129,163,468,403,795,606,809,503,515,918,786,935,532,62,512,375,951,371,147,6,76,844,999,336,872,922,783,844,880,924,181,6,528,810,117,587,919,914,546,767,280,181,800,15,900,903,951,624,954,625,136,729,801,611,461,401,249,712,10,615,405,377,940,501,933,859,32,807,166,814,675,931,493,603,704,817,593,152,219,237,278,421,915,532,956,392,360,610,917,636,224,482,657,660,192,742,849,178,474,897,736,155,78,509,466,46,192,961,312,662,801,358,194,713,654,67,234,438,746,715,334,872,893,386,989,792,649,476,771,403,76,859,573,248,736,557,526,342,404,769,907,850,776,859,478,55,232,840,754,979,550,246,633,230,387,420,202,915,466,404,119,433,109,252,656,744,34,683,845,347,562,418,911,440,602,108,347,369,520,668,907,530,582,379,970,277,981,356,207,226,124,174,964,380,498,476,865,141,197,328,437,192,386,835,268,858,520,923,157,627,552,947,534,145,21,523,699,332,105,784,412,158,778,709,678,850,214,778,547,161,564,951,938,768,617,531,160,543,19,290,241,50,24,284,775,106,602,66,403,286,557,970,800,830,901,451,337,726,566,752,901,677,753,47,156,74,558,411,358,487,16,520,417,600,562,625,108,317,876,808,937,84,952,355,402,509,258,671,682,765,346,585,844,377,619,803,153,485,416,523,150,180,288,425,625,821,155,89,457,542,173,33,672,228,983,296,865,115,676,787,186,669,404,183,621,784,636,842,237,795,11,786,191,336,589,107,480,406,135,811,515,767,233,250,705,25,671,41,139,60,6,858,720,284,781,302,29,114,579,547,699,372,430,604,912,385,63,716,857,175,332,552,62,402,479,109,193,700,289,570,886,104,452,176,893,802,434,349,423,433,350,953,796,356,142,903,818,655,889,967,779,683,762,388,343,816,267,264,128,968,142,582,980,457,298,357,99,631,734,655,307,916,401,749,60,521,275,79,41,843,632,512,198,243,55,503,978,223,97,102,498,519,673,962,728,443,708,685,705,539,250,286,27,236,412,668,101,441,470,378,559,775,740,601,148,975,446,378,827,880,244,231,106,158,661,435,539,78,548,702,435,146,898,634,738,455,740,349,189,536,981,383,406,567,685,817,818,120,967,550,677,586,90,266,21,506,459,915,524,928,307,24,648,11,905,468,634,984,728,325,975,107,760,952,844,312,165,914,583,952,325,490,545,968,175,310,81,511,633,967,186,379,834,370,295,675,761,522,599,665,237,309,147,621,20,936,747,480,834,886,975,198,361,544,309,978,291,823,454,692,548,16,435,417,132,379,480,702,989,693,263,710,713,307,7,261,736,132,237,468,217,446,43,862,812,834,799,802,831,214,231,240,508,894,311,141,269,710,343,764,769,255,895,726,759,357,300,506,243,532,877,194,965,253,904,967,12,0,861,636,138,820,905,173,501,691,573,423,993,959,160,321,714,918,454,747,764,479,630,119,439,495,453,780,496,229,709,880,851,532,840,588,477,466,334,200,491,670,939,430,770,101,902,799,436,796,816,344,312,896,937,929,88,872,959,280,915,404,281,640,383,682,885,611,803,588,521,145,896,454,709,254,247,106,206,845,497,529,822,402,414,572,379,730,452,901,125,146,673,841,900,977,262,95,275,584,457,573,786,797,946,75,491,625,665,618", "278,881,523,741,598,424,478,331,883,245,727,723,398,978,925,173,765,223,434,718,177,398,767,109,986,458,499,623,275,907,265,766,726,579,278,374,901,579,616,553,417,624,313,67,864,157,890,89,572,572,406,638,482,521,235,42,936,129,563,691,20,248,909,191,649,390,848,692,807,242,939,546,909,115,169,692,789,803,339,129,930,715,780,46,905,955,456,424,173,96,821,225,169,959,243,159,101,584,394,607,781,346,546,839,156,164,393,781,897,688,577,274,578,93,963,513,163,92,371,980,546,490,256,974,872,468,281,843,944,767,411,785,692,347,436,242,521,728,519,919,667,884,52,513,505,46,642,800,909,258,904,728,456,313,911,881,768,538,330,886,887,650,43,22,956,127,737,163,215,537,586,178,77,112,839,250,8,76,58,547,854,132,781,98,430,737,3,338,835,474,170,730,251,19,156,942,576,151,345,813,130,235,765,691,17,608,758,115,518,53,891,95,180,716,739,625,964,20,164,926,186,456,394,718,503,568,87,990,969,272,758,960,87,613,15,471,400,992,346,836,503,550,204,954,633,708,88,418,387,580,157,917,121,719,994,988,23,460,641,476,739,755,533,517,766,983,21,248,62,247,643,351,107,549,229,639,98,566,567,114,893,589,97,679,239,1,791,738,103,994,898,160,127,826,618,825,378,359,470,957,427,221,64,353,509,130,103,711,345,564,29,580,742,108,606,34,153,49,345,110,515,116,917,1000,1,55,974,682,727,729,213,614,429,975,244,123,169,818,802,548,622,216,723,776,149,753,732,953,206,123,110,608,122,483,454,481,833,980,514,687,107,814,954,382,41,34,174,195,31,830,329,959,606,596,436,18,803,112,451,114,885,447,746,371,964,670,832,384,219,418,696,81,62,497,870,359,509,672,578,284,461,328,618,909,190,371,876,293,716,624,689,915,549,119,843,255,450,789,901,337,987,270,657,238,405,411,840,773,59,830,979,847,591,414,319,107,255,41,757,621,206,919,456,23,63,289,822,181,134,232,596,370,260,705,261,913,620,847,483,246,282,600,589,962,33,194,405,377,42,803,863,268,460,963,95,278,95,8,909,512,373,806,57,205,229,182,250,446,330,547,191,636,183,777,709,684,323,389,36,877,119,230,415,739,516,319,683,201,523,322,640,291,780,786,500,838,770,401,179,348,929,355,396,112,357,778,18,718,775,283,670,172,465,794,143,670,950,933,610,442,519,678,633,786,687,863,15,645,266,379,327,761,839,233,109,423,40,716,47,561,891,303,150,998,516,921,438,295,126,228,662,640,918,393,573,452,201,510,291,762,942,819,847,7,13,7,397,416,152,10,957,57,198,907,666,409,628,886,666,247,705,128,603,772,969,899,712,356,719,652,388,442,648,651,796,162,692,731,495,174,637,811,158,668,355,115,225,208,452,90,339,784,901,402,481,482,483,780,842,866,169,123,571,78,556,130,604,52,741,746,927,92,823,789,783,392,173,590,341,117,268,862,409,913,352,287,225,211,887,562,675,16,999,983,870,558,209,42,38,937,56,689,404,103,675,252,592,411,65,228,602,671,586,976,689,396,467,347,196,553,214,498,44,390,229,941,771,387,956,955,451,666,321,980,614,435,267,78,907,18,542,157,517,512,534,271,523,254,809,652,387,336,512,316,434,307,702,583,410,128,548,531,895,998,295,153,643,679,60,820,31,744,717,340,332,697,699,223,551,284,19,61,482,182,191,111,50,14,171,616,472,500,593,934,952,956,358,254,612,535,847,660,632,823,388,524,865,864,690,882,524,722,192,432,496,177,450,119,914,236,948,709,665,978,417,523,459,103,996,951,497,214,857,325,418,467,833,813,264,130,86,739,158,992,665,650,554,704,463,647,390,388,726,455,514,199,77,410,577,386,579,255,920,50,92,755,986,522,818,850,648,348,364,684,968,990,561,293,347,99,429,883,102,414,97,264,534,807,83,84,403,280,477,503,739,908,58,609,576,227,619,490,937,819,530,439,73,699,748,17,307,861,0,773,58,865,223,852,941,905,867,909,773,585,6,995,395,313,159,73,363,745,241,936,881,78,75,991,446,814,280,727,545,338,31,637,416,822,788,495,734,780,41,913,195,127,767,886,172,689,986,822,620,916,45,805,489,184,978,604,371,350,321,145,197,485,25,869,627,301,909,757,688,431,718,654,938,838,448,381,638,507,236,686,5,909,923,506,185,404,371,340,437,470,922,570,658,505,112,480,786,797,136,552,856,72,975,445,69,829", "468,997,121,671,381,61,20,229,837,495,962,592,708,489,189,270,727,606,172,24,204,98,269,353,412,207,867,570,714,415,902,450,72,531,504,902,897,894,727,297,556,199,620,562,870,169,800,105,33,873,930,355,275,808,703,118,987,582,914,307,645,898,592,11,384,825,772,699,100,23,669,790,398,160,493,353,932,944,135,216,158,174,508,9,628,865,920,984,490,287,731,311,700,152,933,149,480,793,819,53,996,223,813,575,507,869,126,55,600,724,214,501,581,877,476,445,6,636,679,797,382,160,295,638,528,606,790,440,718,467,829,36,582,766,376,647,302,765,118,519,31,966,582,478,340,467,493,534,683,173,974,893,604,740,248,323,220,368,638,872,311,998,852,229,154,215,956,410,246,272,343,571,38,697,362,240,369,420,445,316,353,767,246,551,632,267,474,141,250,50,144,798,542,112,655,910,961,364,836,294,493,341,568,631,913,204,87,20,670,848,258,238,784,228,583,677,260,430,5,74,566,953,345,879,943,844,19,788,92,417,670,316,216,515,329,642,456,102,910,275,604,307,164,745,631,984,189,432,301,477,711,559,861,333,500,323,653,278,776,775,83,29,154,807,636,196,69,821,549,641,23,425,878,400,272,936,827,140,528,823,153,430,979,95,872,304,455,768,685,146,82,953,252,78,136,520,907,141,45,146,296,882,664,552,204,838,369,762,377,852,888,974,656,353,102,86,32,463,810,309,583,435,535,683,215,617,70,924,651,283,973,335,661,59,231,258,503,843,817,802,274,391,173,631,602,523,504,472,463,910,162,699,480,972,41,958,189,550,991,55,592,99,895,806,578,378,109,945,39,457,354,993,730,322,615,186,505,771,559,185,798,5,400,483,621,838,959,695,405,687,51,665,740,865,167,825,399,485,647,797,214,209,290,51,248,651,418,933,801,819,4,105,782,716,986,173,512,53,863,488,388,237,472,834,391,398,689,705,857,424,741,839,959,132,671,510,331,563,375,499,593,25,946,30,639,105,570,136,778,436,403,596,464,422,741,849,455,214,621,193,516,7,227,467,919,912,717,275,565,269,148,556,55,8,544,555,911,117,724,663,307,181,615,193,27,49,904,730,923,443,845,422,11,957,32,329,742,335,685,21,34,20,292,218,247,353,510,990,258,942,372,268,304,36,13,867,965,410,746,426,972,624,706,209,70,648,748,550,65,556,583,385,571,803,882,131,439,425,45,126,684,940,282,318,79,285,410,889,686,553,295,621,198,208,398,207,372,637,282,726,534,948,330,207,322,82,48,453,160,474,477,898,87,30,21,370,61,398,348,241,502,413,491,749,8,329,198,581,140,46,587,486,188,929,457,230,309,596,564,405,856,336,590,104,785,135,196,159,116,266,351,449,920,301,533,869,147,498,194,515,476,117,512,978,371,654,114,971,267,700,79,322,449,893,787,477,939,636,356,692,673,42,853,473,221,8,117,679,386,66,404,337,886,298,331,129,537,95,632,93,12,157,546,515,59,525,446,677,797,868,159,698,440,347,963,757,279,264,500,132,925,593,515,482,7,713,100,4,964,879,730,291,921,698,938,838,332,199,18,468,826,327,780,840,380,844,628,882,407,66,911,655,364,337,583,802,771,904,512,802,575,640,783,276,597,97,163,629,743,185,214,159,648,825,436,805,888,566,966,471,598,768,82,78,119,150,725,754,534,603,436,405,619,769,121,68,15,756,82,43,780,664,859,173,275,185,620,912,819,824,285,966,498,369,283,835,468,734,848,11,183,158,282,632,128,614,416,82,543,510,560,907,413,251,811,76,185,211,336,755,11,607,697,121,944,889,194,714,484,72,40,775,120,952,463,550,444,321,715,98,954,236,16,856,628,823,714,215,213,749,178,183,477,436,39,115,519,784,368,837,837,637,180,989,243,170,403,574,395,805,124,354,246,953,457,444,914,131,998,110,845,399,440,171,353,532,196,416,563,561,860,569,260,534,350,903,454,787,850,72,193,74,16,191,279,13,680,933,931,20,993,636,773,0,748,956,90,353,951,33,365,208,719,265,646,857,643,832,856,60,69,699,526,630,531,236,291,621,204,172,528,991,399,557,726,908,317,327,654,742,668,636,564,482,408,402,62,772,983,544,356,679,91,711,252,198,628,649,968,541,29,118,119,277,735,945,197,67,177,322,193,293,976,652,746,357,361,605,885,814,82,51,667,844,815,470,74,867,397,584,974,282,923,303,733,180,125,246,500,826,946,76,80,563,115,302,218,693,819,61", "828,342,834,756,288,156,311,968,411,265,605,401,364,891,493,218,591,630,752,365,492,134,961,407,383,890,822,995,951,534,937,474,272,393,685,739,619,857,350,344,186,40,603,851,954,280,700,679,160,983,261,579,242,433,385,241,643,377,364,170,8,524,912,615,302,149,660,871,822,269,211,654,761,165,822,890,574,204,204,590,219,110,112,169,557,393,33,581,853,381,844,919,142,244,812,486,884,463,109,410,91,770,151,644,823,433,751,74,369,864,662,477,887,799,748,626,997,588,989,430,85,851,893,571,682,978,906,536,162,415,432,855,760,567,349,807,820,130,516,264,592,962,838,459,217,493,332,910,45,69,472,485,823,122,9,303,926,657,794,980,52,128,759,681,571,834,663,919,23,265,549,800,114,622,375,774,729,11,739,423,479,57,336,71,91,820,911,395,607,281,866,804,205,87,459,26,861,699,274,725,229,340,710,25,965,965,98,933,797,156,894,781,65,497,770,213,32,366,978,716,94,716,673,638,623,109,372,285,506,202,526,671,152,516,308,808,539,645,511,435,22,526,583,426,874,302,664,779,442,69,512,607,196,818,645,53,916,809,847,349,869,56,740,225,158,332,635,101,747,894,246,573,642,17,138,810,609,682,225,806,705,720,518,915,806,135,120,771,968,216,284,429,112,683,767,375,475,244,960,625,22,330,725,196,859,470,532,307,190,269,475,994,636,368,614,431,64,841,981,104,957,422,543,94,337,951,459,758,785,708,273,671,737,680,398,317,712,634,870,158,581,389,541,368,324,36,278,361,947,211,979,609,634,284,981,556,228,810,987,575,606,382,480,788,152,389,908,837,721,850,802,243,526,10,246,294,703,40,373,130,95,685,462,777,768,841,49,702,600,724,562,799,58,12,205,651,796,486,328,646,580,423,257,102,434,314,973,427,688,339,790,119,182,24,897,225,62,419,173,239,478,698,806,165,358,529,372,654,449,449,81,192,668,303,331,32,526,23,454,621,575,455,106,47,987,106,415,882,656,562,950,369,328,672,665,204,702,848,870,247,828,389,585,43,478,329,945,47,656,214,573,448,501,501,175,127,694,206,244,843,69,129,798,386,662,760,836,598,501,130,426,533,276,280,480,257,323,89,748,501,262,29,17,285,6,544,586,426,793,797,254,197,604,749,139,235,113,351,493,964,42,111,545,392,433,438,633,590,960,481,260,128,841,563,395,864,429,213,215,567,24,265,431,336,755,830,676,791,801,876,925,140,154,632,278,425,184,691,324,521,563,65,593,590,582,795,714,995,221,814,536,619,116,911,889,474,800,237,778,92,123,145,962,638,902,77,327,556,681,134,573,243,598,103,194,566,644,89,941,235,629,18,537,811,407,955,86,519,127,162,395,303,890,30,485,984,143,135,990,655,108,106,783,890,883,829,175,64,820,376,226,598,978,931,798,444,251,990,397,538,614,507,712,454,506,560,675,413,481,154,795,584,919,180,257,337,223,876,781,274,834,851,52,816,6,82,618,727,78,184,860,589,453,29,897,633,819,597,396,9,493,461,626,992,978,217,756,789,38,340,85,280,633,235,421,666,667,480,756,295,788,917,620,424,725,590,481,527,207,303,792,951,48,53,594,917,800,851,135,684,878,448,788,466,820,856,384,610,543,443,287,184,555,610,737,825,62,303,825,400,977,748,446,145,423,716,409,962,64,275,197,413,640,167,983,141,152,997,715,838,683,664,801,637,296,431,114,71,392,549,5,851,698,547,720,859,360,127,652,542,311,966,263,155,660,106,448,149,72,117,600,123,574,603,137,314,369,209,567,650,130,43,678,617,732,727,914,6,190,961,856,193,79,991,728,563,475,650,136,667,439,164,955,855,246,183,397,106,280,305,810,271,989,781,747,136,427,426,316,639,103,898,258,872,540,569,388,477,837,151,715,443,277,484,9,643,289,363,163,834,307,411,315,224,964,530,89,895,273,850,345,525,700,414,661,378,937,719,790,865,719,795,305,666,46,512,372,543,647,855,399,138,58,748,0,101,548,114,485,773,55,464,516,685,503,538,846,182,107,242,437,929,10,728,245,279,159,956,630,775,43,946,308,920,274,596,578,97,432,454,115,839,374,926,174,804,474,148,811,9,87,902,362,232,772,533,189,333,285,649,93,514,195,722,571,969,513,705,356,642,65,181,552,742,609,237,54,952,779,502,262,520,692,999,132,473,19,741,166,695,66,752,534,638,683,346,201,368,106,139,644,262,880,815,753,333,334,564,832,824", "213,572,711,970,224,632,54,225,608,251,789,786,646,601,875,221,635,574,329,665,574,398,686,380,333,541,856,8,67,587,204,745,226,112,818,414,436,9,647,387,391,59,616,269,983,577,52,945,631,146,430,437,892,987,921,471,547,985,611,859,546,574,256,66,687,752,230,70,310,463,514,777,616,287,858,454,26,620,69,181,948,913,984,968,273,347,433,865,364,748,64,800,922,32,168,839,951,163,527,684,548,636,394,512,780,993,845,241,303,455,257,249,790,444,552,911,833,381,5,455,202,253,430,233,30,316,793,473,310,232,801,679,189,444,773,245,776,746,716,474,141,545,452,984,518,305,615,343,671,419,838,487,49,929,696,97,588,219,119,615,733,895,796,430,661,629,490,771,804,781,447,184,766,142,281,214,796,474,937,954,391,310,884,78,651,264,806,779,800,384,454,654,964,95,5,413,607,703,462,57,948,287,110,519,230,902,391,741,607,260,679,950,168,794,179,321,322,837,103,358,977,826,851,508,836,981,46,196,67,728,829,845,610,848,311,672,910,303,391,940,451,968,712,309,322,990,490,920,179,351,556,580,673,71,869,470,642,78,543,76,717,778,420,156,235,514,553,494,38,576,384,722,502,238,716,140,993,609,637,552,438,999,18,446,396,972,287,134,644,198,319,237,485,472,417,907,726,110,97,202,127,30,774,130,860,822,618,882,353,276,521,117,355,880,721,132,498,691,821,7,23,576,77,566,939,446,101,133,282,242,943,206,620,48,132,20,987,747,688,377,493,483,169,838,219,612,983,311,339,528,606,160,573,550,809,932,211,530,123,800,645,993,263,509,387,409,63,998,579,961,994,965,965,437,326,492,327,899,324,729,860,654,527,678,429,406,789,821,228,478,708,459,856,850,924,693,329,697,428,882,29,346,306,654,123,415,497,678,730,133,906,461,49,457,735,701,678,476,846,534,364,162,511,10,840,898,609,326,597,903,69,491,10,173,910,141,568,683,129,996,253,338,650,844,462,881,976,651,66,909,223,657,825,132,21,125,619,83,871,197,212,642,931,924,923,621,67,215,797,898,74,63,277,184,572,464,826,924,137,404,379,233,514,845,57,468,255,658,317,678,118,829,145,608,335,990,681,448,614,263,339,546,788,260,406,235,545,666,580,154,865,219,388,48,616,673,6,446,479,207,174,420,339,546,848,862,430,97,73,361,557,913,553,68,258,64,701,724,738,582,539,37,942,113,892,468,876,38,621,413,972,969,409,976,763,178,746,551,420,390,405,280,416,531,741,316,199,549,662,948,36,716,501,876,278,701,935,783,575,861,581,195,286,96,652,952,346,937,165,862,560,774,340,348,316,345,52,887,865,632,619,505,244,247,745,901,864,380,45,93,181,624,377,696,933,401,420,530,930,408,917,363,583,215,202,486,317,545,382,790,237,77,81,330,128,426,919,178,642,458,904,943,59,947,100,210,784,27,252,245,687,936,888,144,387,674,900,571,338,544,264,184,727,242,426,925,667,9,871,471,591,292,6,299,761,981,238,856,861,344,244,350,943,591,135,316,857,192,682,431,106,639,344,89,511,116,45,795,764,563,193,526,49,350,204,332,35,759,946,167,312,338,376,183,506,857,784,277,323,927,297,80,786,221,108,239,870,708,832,211,150,175,466,891,196,43,20,87,763,410,424,377,400,463,95,582,469,37,544,895,953,101,329,360,968,208,716,485,728,406,690,437,948,510,747,498,983,446,291,184,130,371,804,865,988,791,223,877,686,922,136,204,349,816,224,190,316,985,738,369,922,760,731,128,573,920,822,432,596,846,927,309,556,951,178,764,891,57,791,635,440,304,293,98,948,290,412,167,150,854,919,720,103,1000,337,510,875,516,314,548,384,553,726,683,713,353,710,245,713,728,113,742,641,532,46,472,945,100,855,151,510,986,392,400,204,299,238,877,528,834,556,18,180,31,734,421,333,974,177,337,84,586,473,341,12,234,163,928,288,421,16,143,877,319,397,194,771,87,67,870,19,820,865,956,101,0,525,252,507,717,448,101,201,917,909,673,586,919,27,522,163,791,646,467,849,235,668,495,8,735,551,568,121,127,902,85,685,627,418,54,193,683,878,913,186,676,567,968,725,516,911,891,320,657,917,925,453,536,865,137,719,796,942,988,938,975,396,72,294,633,569,652,252,878,733,997,453,774,444,462,229,720,27,657,198,880,103,750,32,565,325,862,383,513,722,673,518,6,843,400,826,420,977,776,252,286,952,134,844,939", "711,487,136,751,610,802,448,537,866,849,421,357,258,525,287,931,229,208,898,489,693,806,415,791,557,252,489,888,764,896,777,994,539,177,719,547,303,739,152,85,502,12,312,692,919,838,193,313,952,641,19,410,487,563,733,267,924,765,253,402,957,190,594,664,694,507,992,960,164,587,445,462,169,966,254,124,499,793,653,576,564,380,627,988,314,735,522,748,567,841,417,256,852,908,252,232,556,191,248,526,276,955,119,548,768,700,985,152,312,160,145,359,279,177,427,685,767,656,532,322,827,890,793,993,669,509,440,120,978,799,748,725,600,924,566,152,160,940,521,589,965,584,386,610,857,987,759,807,245,743,587,290,856,497,29,15,69,220,416,684,139,415,229,87,224,829,284,242,575,474,565,279,904,594,132,139,416,911,433,932,32,489,139,327,606,19,975,867,821,831,352,40,679,829,456,60,219,622,777,357,352,840,667,761,680,100,53,808,764,405,816,436,827,264,228,129,333,800,950,641,833,906,650,619,245,791,878,3,480,963,218,805,44,955,144,743,80,227,875,990,406,159,86,254,723,813,226,711,264,667,354,719,307,968,243,997,999,739,524,673,986,279,403,629,210,806,939,197,332,399,151,691,382,286,856,926,496,935,459,59,684,659,791,270,183,201,590,36,597,951,748,71,344,91,201,1000,231,862,575,116,513,190,829,627,251,27,239,640,928,129,787,471,559,9,628,113,20,303,194,983,41,509,346,67,596,294,416,985,530,62,497,875,644,83,499,479,852,619,911,315,718,810,652,612,505,88,48,707,878,864,638,412,966,142,998,303,861,232,598,575,832,140,181,962,161,177,205,843,715,305,662,261,707,786,88,527,419,476,936,203,610,25,537,50,347,595,296,302,812,722,169,666,966,563,340,582,7,803,859,863,77,593,87,470,227,464,751,658,606,488,559,75,460,662,587,688,27,584,455,601,285,417,490,75,397,364,432,975,1,674,249,577,878,84,910,634,625,647,594,752,619,723,283,175,416,994,962,131,894,108,275,368,659,280,511,270,708,870,435,922,3,390,166,300,254,936,620,331,429,351,556,409,34,92,904,155,649,951,730,112,186,760,10,523,739,921,817,169,399,288,112,592,359,463,742,177,956,877,657,791,688,421,671,416,954,319,17,299,582,336,748,320,130,12,633,407,333,539,110,186,552,395,29,574,842,199,366,201,452,380,973,411,326,393,234,129,861,204,749,14,916,258,848,613,387,837,877,92,800,882,403,247,673,179,565,458,540,861,66,635,30,521,124,20,491,352,751,152,721,789,959,563,657,227,394,838,351,80,749,971,809,884,299,546,532,435,456,467,162,382,849,784,709,512,174,160,688,530,948,151,973,272,643,888,709,228,474,552,568,644,766,115,89,494,702,765,648,67,486,21,701,436,293,742,985,711,454,258,676,459,986,73,903,823,726,583,820,889,67,808,150,735,588,272,939,790,503,883,97,957,968,647,874,30,39,80,583,358,870,570,881,643,938,119,980,500,430,788,137,869,987,736,718,926,571,371,155,51,16,805,944,279,251,513,564,218,957,789,30,616,162,927,602,578,877,665,154,165,623,706,838,316,186,970,790,159,353,886,905,808,2,560,942,887,256,465,692,352,149,344,76,850,623,306,701,332,866,528,578,60,393,954,447,951,400,674,944,475,371,971,34,710,643,304,805,330,826,520,992,135,649,362,690,405,915,539,732,262,892,315,73,858,319,740,286,984,657,170,190,839,369,365,72,202,67,488,335,387,474,468,987,836,528,602,66,1000,221,259,322,9,941,912,637,291,711,304,33,832,156,297,43,744,522,169,760,805,317,403,380,525,536,662,939,158,236,345,844,484,486,594,550,942,19,790,679,397,292,172,282,680,143,524,782,507,786,981,602,467,465,901,525,651,872,11,62,860,929,538,859,867,707,689,442,902,865,18,162,176,351,229,132,234,976,773,362,590,141,440,214,158,639,375,179,818,333,800,550,258,116,917,408,550,396,477,313,413,900,936,724,479,591,905,223,90,548,525,0,168,166,146,274,757,915,792,406,48,897,584,770,4,926,689,299,249,517,998,262,275,378,470,843,602,426,929,525,58,839,29,479,294,316,146,167,816,552,719,767,606,608,43,215,976,154,682,494,809,847,271,381,555,992,8,164,385,570,889,984,497,865,418,976,405,54,849,112,64,929,301,416,587,944,69,420,59,739,979,615,781,423,959,577,181,777,443,762,436,316,704,1,318,506,600,62,267,76,225,983,806,510,506", "17,984,668,675,115,549,144,182,638,29,430,428,15,991,371,769,59,577,123,734,846,901,498,541,966,319,768,211,445,714,21,638,268,257,476,597,112,980,711,998,208,243,289,400,937,249,714,494,909,312,653,173,532,6,203,97,504,470,307,420,392,38,122,446,783,877,336,642,367,330,574,45,570,744,539,146,651,615,347,932,947,226,656,993,302,433,582,812,199,519,410,655,406,703,459,759,172,200,261,20,662,419,210,285,221,285,586,971,798,146,80,670,618,577,956,806,46,855,631,845,142,304,747,63,428,634,167,925,829,720,814,264,167,580,726,163,648,116,721,823,402,568,396,574,566,681,440,780,385,325,903,251,546,86,389,710,360,168,899,101,694,624,422,445,859,143,836,421,337,67,925,658,124,974,52,584,116,296,957,721,181,774,828,46,189,903,382,523,756,361,547,931,64,456,562,361,716,469,864,727,838,784,135,143,343,401,362,518,450,340,772,935,224,205,776,620,380,831,765,930,647,463,328,67,908,930,851,432,995,202,629,955,39,339,313,834,83,53,191,69,642,194,966,571,603,359,226,572,908,823,243,16,779,680,550,827,641,242,946,383,337,603,588,670,144,473,154,921,762,347,177,183,897,44,261,178,653,437,248,60,957,911,595,247,731,546,696,585,992,900,225,109,432,449,483,460,523,204,166,229,406,337,668,633,524,778,115,92,137,708,316,5,988,571,497,75,560,515,674,755,971,415,378,903,414,436,302,890,17,738,38,643,150,781,302,71,649,268,158,700,122,902,929,510,125,298,595,234,619,929,95,890,848,746,912,35,522,773,372,107,602,471,665,476,119,157,102,19,120,714,834,595,685,670,149,238,223,639,316,439,389,92,727,657,544,555,48,17,443,17,376,530,642,877,553,348,942,657,702,818,978,916,444,242,27,883,615,275,475,515,470,595,561,163,579,796,486,116,311,342,628,322,858,313,405,61,674,519,864,469,977,773,224,686,765,869,731,447,147,502,980,331,701,127,344,173,243,917,4,829,610,189,432,343,77,157,251,720,634,106,253,438,665,499,634,183,899,890,90,185,186,634,241,791,898,174,883,412,21,168,77,346,941,188,535,271,861,368,980,406,189,855,594,7,296,743,910,74,908,799,54,229,931,394,376,31,444,577,297,823,596,976,346,232,896,834,255,5,844,29,359,19,450,297,517,684,24,229,129,568,234,852,142,271,169,627,788,990,400,913,275,698,801,828,541,354,544,499,188,224,911,969,736,483,846,926,902,920,533,341,953,972,777,159,592,72,381,192,950,134,806,697,708,399,929,974,60,275,431,323,34,369,874,245,323,656,975,616,806,910,533,543,853,740,183,727,313,906,889,470,526,210,919,938,248,121,310,230,263,63,146,203,854,236,154,446,85,220,205,580,505,951,139,257,573,579,345,364,281,513,331,665,879,144,149,627,878,510,631,739,181,799,145,252,354,696,379,193,553,315,866,827,838,463,301,590,769,490,930,419,272,306,293,842,396,844,140,601,999,677,221,68,64,152,973,286,815,732,998,975,320,765,478,822,116,6,560,668,107,551,293,463,899,67,454,423,782,520,920,402,607,15,193,346,57,142,808,691,499,980,478,120,301,700,504,473,451,745,752,410,311,949,478,610,420,173,603,920,604,419,670,109,293,901,30,80,841,559,126,140,425,945,5,945,324,848,687,421,677,876,711,30,556,3,361,275,449,978,427,836,840,43,166,598,396,363,736,307,567,931,965,585,801,589,426,765,578,228,995,721,410,399,216,435,852,578,847,613,197,658,727,755,70,579,730,523,426,977,200,407,318,149,455,379,301,726,613,188,532,33,206,466,87,872,371,184,752,735,850,321,750,545,201,560,652,358,319,370,522,829,975,68,132,536,956,647,801,844,501,146,349,33,176,684,319,192,917,512,955,850,15,148,177,863,95,661,55,913,803,775,921,384,468,408,1000,727,910,20,857,473,342,533,800,231,369,141,107,31,163,251,233,796,827,489,434,601,767,323,229,269,190,173,852,353,114,252,168,0,249,4,826,144,428,435,309,234,100,647,730,950,297,581,80,367,55,126,221,369,125,896,98,334,501,690,847,990,936,953,253,408,657,68,669,267,182,710,794,562,199,24,582,328,502,980,477,137,637,681,708,160,982,577,997,107,980,773,494,68,360,649,769,276,948,159,610,880,739,859,915,891,770,35,501,589,531,994,311,719,304,585,291,330,287,833,857,256,129,740,532,361,608,809,475,386,653,838,123,505,231,997", "190,96,888,855,941,15,272,852,464,632,856,883,791,862,740,886,747,807,795,858,196,302,81,382,242,710,723,775,783,884,874,853,557,503,769,529,897,757,498,581,101,884,343,613,474,328,409,937,793,404,33,700,884,618,846,843,862,427,288,614,269,956,884,15,382,442,878,929,772,414,492,814,448,237,132,357,201,452,954,45,190,754,5,449,51,283,667,270,120,338,59,400,486,447,683,720,179,385,549,221,668,300,4,435,148,17,603,948,101,478,302,732,299,662,597,607,342,992,329,446,667,182,252,39,141,27,866,720,671,279,684,123,769,582,887,487,118,884,142,346,345,380,906,737,648,752,228,233,158,443,768,647,388,279,718,454,931,541,194,570,433,944,380,636,507,390,38,820,864,159,867,335,994,354,289,221,30,357,55,26,681,855,851,193,97,615,865,864,473,801,741,538,583,240,890,820,302,465,565,542,724,664,541,507,417,308,4,226,648,954,340,447,572,490,692,173,437,934,82,538,816,89,50,452,777,464,38,194,946,616,923,550,795,275,261,253,1,534,998,410,250,646,221,680,87,714,332,246,365,167,618,521,160,791,559,70,406,362,681,669,867,576,758,633,645,475,464,3,571,530,867,605,312,194,809,414,995,313,225,357,97,778,193,722,598,536,263,196,205,414,278,976,694,900,205,576,181,6,456,377,811,95,786,431,70,344,547,70,264,99,654,462,802,925,902,790,586,315,891,563,119,20,343,16,758,56,491,957,758,865,116,746,653,158,274,583,229,476,211,439,224,801,386,443,350,217,284,400,535,20,424,777,500,959,625,172,912,68,677,842,728,58,956,828,207,824,11,898,192,873,237,276,890,276,891,576,450,673,107,647,640,785,358,571,30,878,247,529,650,391,739,548,157,888,578,394,902,148,789,468,169,449,952,484,471,210,559,864,421,421,623,898,526,368,359,562,637,146,676,690,639,811,540,80,802,754,69,638,696,462,419,771,744,435,905,792,818,164,232,94,585,909,384,368,889,415,538,305,89,717,578,890,593,427,463,726,249,800,237,752,443,382,789,471,531,158,132,972,887,698,116,611,43,331,97,705,528,833,560,750,405,61,348,887,246,28,703,752,835,39,304,721,937,658,289,29,412,696,490,808,855,803,8,188,587,243,856,249,785,393,296,389,760,380,858,50,380,918,894,350,688,979,82,405,966,249,250,523,370,612,107,708,283,640,408,523,480,55,781,515,727,431,258,909,268,347,944,849,332,856,810,826,449,377,328,766,344,834,765,167,780,786,975,973,362,238,75,807,213,267,183,233,284,115,969,834,365,696,534,781,127,272,105,939,185,23,460,863,220,480,664,719,393,631,39,109,618,811,153,790,455,37,34,689,49,852,382,581,848,265,773,125,742,141,28,392,23,485,745,930,75,200,931,142,999,398,468,297,443,906,190,201,813,172,821,608,832,208,858,427,135,367,367,260,152,676,74,304,774,993,190,463,291,852,272,513,244,201,835,564,805,102,302,381,778,260,605,347,869,356,742,694,312,167,861,772,722,559,429,376,638,25,853,44,135,818,958,913,304,301,210,659,993,130,735,346,582,615,207,896,489,385,51,767,325,688,286,13,958,391,943,158,79,870,724,702,74,346,340,681,311,762,176,283,257,768,576,912,229,801,931,176,35,287,764,64,689,572,686,463,850,407,433,504,400,951,354,503,538,569,330,113,220,633,104,874,647,185,88,460,527,530,996,180,805,952,965,16,210,949,3,363,856,527,616,362,785,523,728,838,469,638,976,273,838,270,158,239,464,298,114,477,125,979,78,240,253,244,143,586,710,617,73,395,867,177,289,924,427,599,553,913,24,660,213,939,350,807,983,191,611,957,981,730,503,28,54,50,946,814,137,916,484,592,884,133,97,371,403,645,567,287,253,351,316,384,780,106,25,60,185,915,428,868,2,895,605,537,759,463,78,887,572,968,19,943,635,531,903,129,796,906,361,498,709,102,142,657,73,184,411,323,5,692,201,176,445,69,229,897,281,501,941,951,485,507,166,249,0,95,420,149,772,403,930,420,872,976,256,78,200,813,675,893,245,619,131,595,335,875,340,824,621,628,377,10,992,243,835,223,672,272,981,594,793,92,446,714,852,633,258,262,569,344,484,826,629,747,697,351,662,629,166,485,452,815,652,433,501,799,552,795,34,339,268,533,147,802,249,130,334,203,373,679,7,459,141,321,487,934,310,452,716,630,997,556,91,111,43,166,683,923,528,523,907,276,261,79,458,201", "952,757,467,933,795,535,144,159,297,823,663,66,33,112,904,647,729,902,531,653,534,326,660,775,14,151,55,147,143,837,829,829,256,710,513,646,420,543,416,821,88,681,840,337,191,600,756,703,763,407,473,133,847,773,261,667,326,339,986,621,73,208,298,585,744,162,784,713,946,454,144,604,711,132,118,518,790,310,559,326,97,358,992,888,452,879,683,838,599,557,641,573,874,566,238,794,365,163,788,908,375,362,285,749,646,523,508,453,473,505,586,258,869,467,718,448,56,603,713,911,864,133,483,956,699,803,596,684,323,478,150,509,943,702,84,680,560,343,654,853,473,580,947,957,618,140,205,504,245,638,247,504,107,109,458,879,540,712,928,314,692,65,575,845,456,108,586,610,445,449,527,945,596,282,294,866,203,893,131,100,125,88,22,402,460,855,361,562,521,260,86,339,394,784,564,498,690,758,152,248,77,246,178,929,24,982,459,686,794,812,329,681,716,437,432,605,640,909,862,990,761,430,938,308,210,991,149,975,431,522,594,626,826,815,82,595,661,754,601,544,333,922,726,442,286,184,343,188,699,333,228,688,466,380,915,365,228,982,603,145,774,40,672,259,370,153,821,87,255,730,450,838,811,769,940,728,724,158,519,297,672,99,848,543,870,153,923,45,182,210,999,875,688,146,8,804,524,39,570,145,936,330,962,151,545,949,851,775,290,857,735,34,330,597,635,487,738,847,765,584,42,651,883,299,747,238,886,179,889,494,635,951,685,572,704,661,476,2,6,221,410,775,101,72,604,892,740,183,794,42,32,189,519,640,705,254,448,990,527,738,502,719,324,142,202,235,159,106,133,156,57,111,170,497,357,882,822,270,480,925,237,37,47,433,115,458,146,732,503,471,54,427,747,10,279,856,840,478,566,17,82,325,77,98,272,173,513,688,34,800,563,246,758,174,522,399,800,846,520,637,265,935,105,172,292,714,519,292,433,958,387,231,106,498,816,752,512,349,363,303,831,875,271,744,392,685,372,162,291,285,553,320,821,627,328,350,162,514,929,676,129,104,799,161,645,246,745,190,341,122,628,572,587,188,457,790,680,565,548,417,411,381,542,809,949,800,613,600,626,93,49,12,572,837,524,433,72,435,998,362,715,46,975,365,365,727,300,651,494,292,659,787,548,846,110,835,795,543,129,884,314,859,718,463,710,183,387,8,372,206,76,23,808,953,716,721,104,734,724,579,921,79,157,377,179,72,544,64,843,245,960,974,488,522,749,945,937,879,969,894,868,984,465,76,622,949,389,185,476,149,29,38,665,503,950,692,67,521,579,632,370,170,533,886,319,305,202,349,4,180,312,760,761,874,144,501,252,527,742,67,813,161,657,670,987,435,731,530,34,314,744,534,655,110,232,666,666,238,628,81,796,619,238,840,390,109,896,913,273,553,447,538,610,827,371,876,431,153,333,525,800,359,352,372,907,279,979,669,238,696,841,912,724,57,860,866,443,224,19,408,340,471,798,734,586,560,669,542,283,659,401,722,20,65,392,198,500,379,90,870,838,182,477,242,309,105,533,323,740,661,795,309,208,809,376,450,930,901,23,311,519,634,884,799,296,759,246,639,482,763,93,783,29,55,454,855,217,526,312,234,652,798,403,362,992,918,210,225,556,339,29,78,899,971,252,670,777,586,869,421,354,822,196,755,180,333,48,238,569,531,103,746,791,570,55,253,404,991,634,869,849,872,311,463,263,73,845,155,156,499,215,734,682,660,771,166,734,202,459,757,233,368,929,402,552,25,202,229,556,850,429,723,64,356,466,432,684,760,176,419,721,511,626,757,618,275,689,717,65,2,60,942,267,441,951,103,76,170,477,543,629,394,318,508,116,81,133,49,613,531,454,529,663,904,703,506,642,691,761,241,639,68,69,989,190,925,966,247,15,243,844,900,107,871,274,821,769,149,525,856,830,488,759,621,429,432,731,209,170,54,925,655,719,703,837,123,777,211,792,265,76,704,349,552,45,956,663,774,398,696,388,691,905,33,773,717,146,4,95,0,868,155,573,250,220,658,776,127,589,841,405,191,477,356,175,23,459,643,627,787,573,166,925,348,777,936,590,963,198,875,619,875,531,258,180,715,581,831,598,288,921,17,245,453,443,700,17,926,640,966,826,358,822,16,566,372,332,33,285,813,413,410,678,237,957,972,171,448,838,638,13,339,837,557,377,477,570,322,931,811,961,198,191,127,638,57,745,454,947,969,610,232,608,440,788,822,682,684,616,605", "370,77,799,133,565,981,895,225,72,196,139,282,461,577,100,196,716,742,255,921,839,922,719,504,378,140,776,437,972,215,171,803,870,435,854,370,109,811,328,440,619,786,986,524,156,859,726,44,387,74,987,990,659,825,691,498,528,412,133,845,986,427,425,252,571,967,481,942,106,989,908,26,93,539,339,523,381,975,84,826,453,955,453,139,766,483,25,208,36,748,842,986,956,310,802,963,30,236,786,282,625,695,920,809,905,619,237,107,111,605,255,529,247,581,416,892,833,755,941,683,899,216,458,767,682,988,279,486,909,58,394,656,827,813,461,318,174,85,754,945,934,654,189,331,955,80,507,367,791,917,610,490,199,384,327,748,37,432,735,649,365,97,363,997,408,994,143,731,956,810,968,421,369,793,883,806,969,927,334,173,975,673,140,493,242,201,237,14,697,365,314,395,341,730,342,600,854,813,414,792,785,44,798,454,436,685,956,969,20,238,335,759,74,135,484,392,800,775,863,764,911,317,414,367,980,926,959,501,713,462,321,332,912,946,363,113,587,408,454,271,600,343,228,994,112,207,946,183,222,858,542,515,88,300,541,82,61,946,833,235,50,31,663,547,595,431,218,852,656,550,22,969,198,480,847,298,454,86,107,715,699,505,89,403,582,645,770,310,797,415,317,198,787,319,574,123,574,106,785,519,703,8,937,506,626,674,34,388,416,776,350,805,895,884,814,380,557,599,342,166,327,306,122,940,754,16,74,372,180,268,766,723,116,66,147,244,355,996,242,812,183,677,871,112,879,481,579,105,954,118,518,15,149,759,679,458,182,770,231,303,915,632,843,973,256,623,999,524,959,670,473,346,943,289,203,559,880,113,443,150,729,20,49,760,88,528,847,362,984,990,397,627,329,176,624,21,225,454,775,810,426,24,687,526,978,988,454,312,681,727,963,399,488,119,342,827,587,165,694,958,28,48,63,523,246,948,37,59,895,817,19,696,290,510,210,598,233,958,59,485,720,397,595,93,834,242,713,827,246,724,127,157,306,569,283,672,205,902,663,184,988,553,610,77,50,886,761,776,103,364,780,743,735,64,345,699,774,831,604,286,103,847,122,460,192,975,352,542,982,304,515,815,373,937,101,439,369,880,103,287,277,336,371,447,754,260,110,654,892,547,651,569,915,112,741,334,547,81,955,437,29,316,683,407,981,372,95,325,981,364,648,455,34,293,193,654,876,670,139,384,835,424,395,13,278,448,449,614,720,834,593,306,655,130,791,733,796,669,206,49,3,740,954,983,604,400,670,691,227,633,601,355,438,81,235,117,524,454,704,37,310,172,315,246,556,829,954,67,316,872,585,694,632,219,350,231,653,470,965,826,867,419,534,875,545,413,854,88,500,816,342,166,322,481,276,468,78,949,724,471,91,55,512,587,691,843,680,965,323,699,255,203,274,437,137,576,484,515,899,178,285,674,149,657,662,471,7,433,334,556,404,615,494,993,541,224,537,266,614,825,113,638,890,736,795,145,396,747,537,475,565,609,830,888,975,280,902,48,542,239,691,679,263,585,447,571,219,424,9,715,834,431,150,138,243,644,165,507,162,976,412,486,115,651,929,910,665,92,125,670,262,10,893,90,300,898,958,551,320,162,654,541,439,767,417,211,292,807,350,620,639,204,54,389,505,687,969,422,813,926,311,905,155,652,188,333,497,535,971,670,159,483,555,366,772,974,479,549,478,223,821,866,696,782,123,755,278,387,345,810,879,410,485,302,776,151,741,970,147,277,254,943,30,249,323,662,113,220,426,769,857,819,846,448,996,292,588,37,132,212,917,777,329,180,562,939,79,44,45,562,941,565,960,718,841,580,468,844,666,375,956,372,726,664,861,314,338,503,227,259,197,530,526,43,863,691,79,92,585,708,755,731,3,862,759,326,504,135,5,516,918,689,818,370,227,322,511,699,789,946,615,605,659,8,439,38,900,841,990,534,75,793,731,933,556,671,110,360,858,128,121,191,535,405,124,56,481,272,394,121,551,573,867,365,55,448,274,826,420,868,0,418,169,935,533,616,169,985,798,417,693,836,45,350,438,444,83,850,864,327,89,128,635,736,270,820,232,641,805,491,475,676,473,862,86,74,700,325,412,485,990,633,627,894,296,177,568,122,681,872,653,994,59,51,611,238,927,413,906,564,508,370,956,364,487,559,899,958,488,617,475,74,796,195,812,515,834,135,102,708,926,746,706,373,301,63,954,692,336,548,183,513,394,294,31,34,242,39,91,265", "464,843,429,489,101,21,336,774,375,477,334,832,487,958,25,838,825,823,235,868,524,371,154,787,135,522,767,691,428,975,609,482,340,24,331,432,217,348,491,952,557,649,399,858,344,980,980,524,463,951,357,724,69,252,825,33,985,235,830,237,98,745,312,172,527,111,603,827,464,854,690,570,209,169,778,637,229,822,626,340,784,66,133,325,344,125,808,662,461,989,378,457,729,577,296,698,328,368,136,893,298,312,643,220,699,666,379,70,607,151,252,519,814,558,161,662,238,738,12,998,639,158,468,585,711,369,683,691,99,960,994,495,862,98,135,500,926,497,22,961,944,96,831,842,790,922,948,49,779,73,890,494,26,179,478,25,585,316,134,198,858,937,212,787,172,368,185,741,728,178,301,346,302,959,198,596,179,760,67,306,823,477,852,981,335,534,931,454,601,601,973,367,98,935,511,608,973,760,418,922,253,720,477,480,206,798,941,666,871,478,3,378,612,856,116,396,565,638,387,209,232,455,960,35,528,846,8,721,722,444,146,976,583,366,401,16,453,907,339,488,457,629,338,362,945,157,172,67,239,990,528,993,964,609,956,941,666,728,521,80,599,93,99,595,468,716,494,472,214,98,969,985,729,535,672,680,918,133,361,895,594,486,601,599,518,711,399,325,707,913,601,773,129,343,950,990,192,894,943,846,196,888,947,833,434,204,415,336,688,647,910,266,826,511,972,487,678,231,691,249,4,835,462,429,461,525,942,792,467,39,150,276,282,469,314,462,381,112,476,544,297,808,952,367,248,213,36,894,690,549,509,642,868,895,117,63,452,873,178,437,418,450,794,183,731,387,291,340,748,358,830,157,367,157,974,853,546,303,299,707,433,823,763,627,266,376,91,38,368,247,586,123,387,123,733,485,872,328,236,206,638,889,104,82,432,550,674,225,818,976,226,458,307,133,592,661,510,85,26,462,210,793,683,942,575,971,833,651,755,848,481,180,325,314,448,103,171,277,374,253,633,243,31,397,114,682,218,185,410,234,766,380,647,189,511,722,853,107,175,181,78,562,948,983,822,577,560,858,585,449,401,31,594,572,165,737,672,754,431,872,649,963,707,29,524,188,60,181,18,564,268,693,915,439,242,27,459,327,463,706,29,657,539,168,823,55,892,141,816,356,430,700,871,511,124,292,634,723,709,131,959,221,226,316,403,304,141,928,575,76,656,756,179,571,713,593,593,920,366,311,579,377,633,840,984,124,848,354,949,571,644,913,165,91,297,390,451,272,460,298,229,986,323,824,395,714,99,235,828,184,610,532,293,748,125,247,237,879,869,279,36,713,580,281,388,200,890,797,620,485,205,702,963,299,505,181,290,774,535,382,530,822,694,81,10,80,725,429,16,86,896,545,505,559,818,518,493,631,577,451,90,738,208,890,437,198,245,782,778,271,277,555,99,50,604,83,287,337,752,735,921,49,955,957,668,10,172,366,67,73,769,897,789,780,957,109,359,572,677,413,475,461,816,749,528,711,533,877,149,77,51,121,940,527,94,872,898,639,56,636,870,593,488,27,816,221,640,582,527,420,169,543,882,390,432,894,721,120,433,179,834,298,125,903,614,737,687,771,690,26,176,123,352,488,994,524,215,508,24,538,136,610,788,116,318,845,566,323,604,680,372,740,944,443,694,997,536,240,259,455,480,743,717,969,567,439,609,361,817,69,162,301,113,725,793,928,527,937,374,233,827,369,829,161,857,853,362,491,761,667,646,809,849,401,90,492,35,698,556,38,729,907,442,380,506,414,171,524,329,21,745,268,522,65,510,204,851,335,221,869,789,745,114,77,559,486,246,261,467,255,843,549,863,507,377,701,463,302,283,409,356,184,894,316,196,425,772,24,291,315,198,637,684,117,193,466,934,454,380,321,255,38,887,102,111,822,39,905,239,78,397,569,295,797,902,767,192,397,824,8,863,615,10,70,224,290,684,609,340,781,749,649,808,773,136,546,979,870,8,337,407,321,239,377,394,209,295,600,755,301,877,423,909,208,464,101,757,144,149,155,418,0,366,546,781,537,563,98,505,537,286,86,444,933,896,55,590,517,302,621,280,410,972,800,799,76,114,271,651,922,771,722,936,724,450,216,938,598,249,583,562,972,513,357,777,164,841,297,38,275,801,13,578,603,857,981,469,585,547,951,504,557,483,326,427,903,881,649,426,125,476,482,689,963,736,149,526,874,521,465,517,946,942,641,318,974,622,225,385,765,625,177,665,78,409,79,918,167,496,463", "291,367,25,195,837,921,630,929,203,122,548,563,94,338,77,211,237,25,634,796,781,177,586,367,767,601,928,633,120,848,331,86,461,394,41,743,404,389,275,885,87,804,161,378,82,975,331,125,940,898,820,575,12,871,439,63,687,244,932,148,49,984,34,665,954,241,54,859,145,788,820,599,665,704,686,567,231,384,152,780,704,872,754,179,633,951,804,855,341,240,977,534,570,568,558,845,264,241,194,412,500,943,372,744,147,516,253,456,827,530,129,98,242,524,500,86,653,958,50,547,809,41,349,593,488,672,281,627,458,142,268,637,923,725,413,397,919,398,690,909,885,983,898,596,938,117,277,302,281,414,33,180,585,632,828,819,943,640,416,815,492,644,979,304,546,83,874,826,245,880,213,400,56,816,179,543,621,846,922,571,828,455,402,662,397,148,594,267,847,590,57,421,681,326,560,595,514,588,557,865,10,707,346,834,330,398,826,967,209,200,113,681,931,270,277,808,141,247,152,894,918,992,122,205,615,549,438,341,700,396,130,765,830,687,453,557,718,90,372,509,372,469,679,785,511,805,832,312,224,389,210,436,550,389,341,736,58,806,342,494,753,729,497,940,990,328,614,654,555,743,807,488,799,70,167,822,649,889,362,666,740,146,100,384,288,493,468,725,828,297,297,707,77,361,81,569,144,819,22,196,684,794,721,673,519,192,105,113,308,555,289,576,278,462,816,344,542,876,590,760,597,537,971,825,780,69,429,698,813,392,871,207,606,504,474,99,799,686,685,314,858,129,370,238,677,790,980,221,513,180,966,366,892,421,870,921,364,8,236,189,627,264,62,826,339,607,192,645,454,255,9,321,816,719,951,296,498,42,104,391,699,656,846,530,851,824,773,102,845,899,310,447,606,791,997,316,894,333,320,521,244,64,267,347,959,327,991,639,445,602,838,191,606,692,425,657,473,533,688,916,250,535,464,269,329,130,666,100,989,121,823,573,189,532,367,894,154,53,347,8,454,628,199,670,616,864,566,280,69,36,382,679,104,1000,920,670,351,761,471,613,714,798,187,693,916,63,23,211,380,416,797,330,900,485,148,143,832,738,390,839,499,639,564,248,917,323,883,394,918,927,237,822,134,257,523,211,335,804,358,388,202,313,608,347,555,821,88,734,893,721,761,763,399,781,678,66,296,803,92,272,509,585,614,760,628,742,532,545,783,744,343,477,490,821,595,543,549,986,183,278,38,959,314,797,583,321,356,500,580,164,154,129,204,318,642,395,904,175,118,711,773,181,879,957,797,180,94,294,343,586,164,866,81,866,116,373,257,129,788,933,293,296,26,962,943,141,793,46,924,633,980,623,9,56,549,526,588,70,1000,571,993,470,856,436,700,489,445,304,683,384,93,223,828,286,71,778,317,375,875,811,114,862,654,11,64,165,926,698,692,944,549,714,729,917,260,920,655,728,424,500,235,765,973,556,96,239,209,198,736,980,23,449,114,763,599,288,82,459,200,142,865,739,949,969,23,38,692,450,542,190,477,28,633,12,68,140,521,182,924,702,153,845,181,997,285,192,19,279,885,183,338,904,219,695,685,342,329,535,223,279,726,787,561,807,747,65,713,628,276,79,545,952,811,916,260,965,229,103,818,89,606,418,722,347,18,586,944,844,190,615,815,588,556,35,965,396,702,938,851,828,82,667,566,342,37,464,916,52,4,813,897,391,291,164,991,5,929,675,901,569,319,910,559,582,236,915,976,305,369,893,567,6,218,576,798,382,427,774,754,30,759,200,275,201,425,15,185,453,587,980,699,554,95,313,706,508,335,311,234,220,78,710,276,252,183,269,834,751,805,968,23,149,756,659,159,333,871,993,356,743,598,45,71,88,230,574,32,257,12,933,443,929,864,789,23,67,23,309,363,473,206,745,342,916,295,666,28,935,980,552,40,378,606,432,301,709,874,241,44,869,728,399,774,970,989,713,425,642,500,391,181,129,109,566,876,572,817,777,753,194,853,393,728,61,498,474,744,195,420,651,805,993,773,719,516,201,915,428,772,573,169,366,0,616,890,273,395,383,911,367,913,430,523,57,503,358,687,679,901,904,675,538,900,451,977,294,564,760,300,25,388,923,899,297,942,377,874,230,619,274,822,743,972,543,47,80,130,856,750,234,738,332,668,733,336,205,252,8,488,929,358,884,969,975,698,478,752,156,234,598,197,280,686,696,767,64,384,404,586,516,992,257,428,187,906,838,48,384,184,551,289,901,912,145,652,872,509,560,976,499", "918,32,817,268,655,188,716,482,869,35,278,204,376,19,458,867,555,826,454,469,282,510,967,950,483,241,609,49,599,159,828,523,947,935,401,805,639,291,719,110,413,565,615,27,625,975,4,828,388,857,205,189,995,809,599,138,138,180,640,943,843,899,819,728,113,324,878,631,209,509,820,566,314,720,441,644,303,525,591,106,713,628,806,510,454,899,146,443,877,129,19,943,788,248,314,163,388,168,748,779,886,168,703,268,337,569,948,464,395,380,561,894,637,63,664,949,338,994,680,982,129,430,385,404,499,350,80,239,896,942,530,626,786,213,451,627,245,850,52,116,778,336,368,900,557,34,304,521,52,975,261,328,632,421,942,379,672,943,150,722,136,889,717,68,684,177,569,965,744,99,249,345,180,894,659,909,763,298,702,452,49,231,119,579,83,310,351,640,857,133,552,782,678,506,174,873,814,381,38,256,571,490,69,852,654,565,417,129,327,55,822,168,977,671,853,702,246,994,957,802,225,97,278,232,284,670,705,490,285,854,795,803,837,675,543,10,821,142,60,693,98,264,982,476,579,656,441,354,651,457,465,235,341,751,178,916,982,841,766,120,706,844,64,743,334,979,747,254,955,852,395,238,70,900,721,601,121,362,443,999,629,161,76,950,993,964,607,954,830,334,407,845,791,529,954,211,486,746,821,490,965,202,78,754,632,953,844,364,939,914,210,441,557,718,178,65,542,828,260,260,200,737,308,992,597,237,38,280,691,248,145,482,325,788,522,745,63,576,628,133,733,498,871,956,987,847,580,922,416,562,412,370,901,611,427,277,59,81,338,719,972,591,128,446,869,499,739,364,595,165,552,560,44,689,389,745,913,431,851,257,617,676,684,101,156,636,465,588,144,627,746,356,445,772,668,343,801,84,5,379,884,625,153,101,590,819,781,524,732,51,514,963,280,73,104,324,808,415,957,476,777,463,296,423,821,431,340,532,735,741,745,417,607,784,845,568,981,952,952,855,582,81,990,740,373,184,533,790,422,919,303,38,614,597,235,377,713,690,587,929,579,376,222,332,241,638,878,994,519,664,233,313,592,396,625,849,13,661,300,134,850,767,751,170,977,557,899,608,362,71,520,298,389,409,572,135,601,179,178,33,150,923,846,434,59,148,515,851,845,591,843,1000,12,982,161,742,94,894,578,568,993,521,311,999,236,255,659,522,101,361,102,402,614,975,806,184,170,506,564,222,577,90,874,371,249,975,332,936,770,659,427,673,379,249,950,430,550,336,970,363,390,778,411,289,72,745,368,267,206,400,250,957,448,395,877,357,399,806,494,865,353,179,843,7,701,540,470,343,80,276,628,733,417,494,28,696,325,528,822,359,517,171,630,694,516,544,172,937,251,614,964,317,864,718,589,218,676,220,99,532,125,627,400,255,516,26,300,821,51,754,107,607,310,830,454,788,909,781,1,123,923,348,974,369,909,555,570,6,499,32,350,508,517,169,900,525,699,855,239,936,513,42,161,154,809,650,602,240,599,619,482,782,633,401,521,312,913,584,560,143,65,868,502,654,470,4,297,331,934,260,556,315,193,558,768,286,405,218,299,519,85,759,389,692,983,925,750,977,648,665,677,397,654,456,508,718,457,912,152,940,595,875,850,61,743,929,809,298,42,785,984,181,882,688,614,672,694,655,800,878,549,805,26,575,485,865,340,819,156,625,39,740,630,422,836,312,387,941,734,902,585,330,648,787,519,117,349,154,295,176,477,806,88,624,447,737,249,863,12,523,708,784,606,90,93,876,909,221,522,126,241,312,399,209,54,722,692,891,627,506,774,638,273,495,842,953,27,967,349,760,675,624,393,882,401,799,318,905,342,418,467,204,723,6,407,388,212,195,538,280,651,152,378,375,78,54,533,324,761,611,643,379,335,966,311,347,786,457,193,636,103,329,21,833,64,423,440,386,972,807,746,305,500,230,14,468,36,308,898,857,419,767,372,156,604,765,835,868,729,767,995,358,696,618,768,724,693,524,799,429,913,959,585,265,685,917,792,435,403,250,935,546,616,0,954,20,404,546,907,71,709,532,95,717,986,622,534,806,601,491,520,980,788,625,156,804,264,129,183,371,221,920,749,221,671,70,254,465,757,571,391,739,223,278,171,111,262,574,656,552,821,963,971,655,142,661,943,538,380,284,343,350,435,694,677,319,256,291,397,163,515,104,56,741,20,490,386,517,910,528,40,295,861,19,906,674,751,4,743,317,956,984,124,785,284,186,560,680,208,862", "454,840,322,776,613,345,119,146,838,504,401,155,402,132,31,370,873,920,374,602,632,718,120,128,612,74,543,407,789,298,325,26,165,321,98,973,306,730,281,188,52,470,795,765,489,686,429,78,590,831,431,74,371,451,691,831,708,270,916,207,84,138,785,64,409,922,77,942,686,904,278,240,868,20,716,842,445,173,940,213,188,688,396,302,819,60,321,545,834,781,401,734,392,415,869,665,694,400,185,187,608,487,359,131,564,54,675,497,665,696,52,591,686,985,412,29,264,219,639,99,714,397,61,285,246,358,14,899,572,59,980,154,628,789,46,140,750,795,278,234,668,711,28,433,442,402,364,130,202,558,388,280,772,194,502,22,144,155,563,513,111,850,925,928,622,848,424,898,495,84,768,939,655,23,951,541,272,973,409,981,337,854,776,556,413,426,7,561,416,417,245,439,879,683,494,806,700,7,217,34,980,284,529,283,235,733,269,732,585,111,152,762,658,839,585,906,428,914,78,660,537,913,918,99,775,39,286,607,559,850,120,801,338,837,122,289,779,441,525,314,884,219,947,860,134,600,177,322,186,589,194,623,606,147,321,464,221,67,424,259,540,805,91,575,606,754,822,556,66,655,150,615,37,191,926,661,580,965,800,13,377,153,993,625,492,13,896,736,678,867,884,753,975,148,75,894,715,201,408,950,425,193,431,139,824,495,368,663,89,952,987,766,150,413,158,224,996,606,47,888,398,674,2,516,961,905,331,365,412,238,115,530,212,252,513,189,697,452,922,716,49,847,243,148,19,54,556,806,725,687,980,673,359,949,191,65,522,653,905,806,320,153,264,531,581,522,340,422,607,686,257,706,76,440,305,995,438,605,995,260,515,180,896,15,232,811,664,322,822,453,323,372,371,684,631,616,414,197,470,635,193,465,765,118,330,726,395,689,785,454,510,706,227,930,116,524,906,335,389,585,859,790,430,663,516,177,737,418,899,780,815,641,910,932,297,403,251,954,214,576,57,758,938,502,911,487,265,836,868,606,266,527,570,359,580,590,633,20,739,962,11,214,185,999,441,712,164,659,900,56,536,538,856,992,485,308,713,807,210,952,333,846,347,765,718,12,6,181,589,657,135,636,977,648,257,907,913,165,638,539,244,127,206,265,946,721,268,16,449,391,898,842,551,560,248,467,44,495,919,812,279,742,239,697,205,209,281,554,921,528,530,970,834,326,274,17,958,259,355,908,945,469,803,715,558,106,178,329,993,119,672,693,598,130,169,52,105,499,21,968,790,997,480,941,161,429,667,888,595,515,671,40,11,953,387,291,28,980,142,764,537,895,690,894,474,188,828,150,100,617,705,598,391,431,879,446,465,268,344,232,7,223,645,455,942,620,144,122,832,155,381,913,427,130,416,963,465,654,989,514,4,421,22,826,858,729,752,159,173,910,4,393,998,151,912,927,415,909,302,425,923,30,64,70,335,52,72,983,589,641,553,646,865,872,649,986,450,419,780,32,231,779,484,414,167,626,871,850,897,133,963,721,520,113,312,988,460,90,20,34,299,485,143,605,421,674,252,758,461,991,183,276,300,662,713,351,684,895,616,227,111,474,921,282,741,669,667,941,408,451,757,942,950,685,329,412,649,651,983,848,547,69,849,486,188,783,716,71,365,922,691,76,758,348,85,269,125,304,241,532,423,757,535,333,355,415,130,949,739,714,360,767,664,263,72,38,574,727,141,881,427,256,158,88,706,26,548,236,857,420,506,893,645,54,803,587,140,394,657,338,113,198,455,722,30,377,658,582,270,293,4,726,738,354,965,439,964,383,674,830,846,452,569,178,430,125,979,23,221,169,57,609,422,29,221,192,470,472,797,266,318,671,844,853,272,401,871,388,703,275,91,496,183,775,526,475,761,343,645,453,835,965,232,585,220,942,53,826,972,988,672,110,645,945,299,727,966,717,503,372,286,969,212,617,588,185,520,93,323,299,36,812,691,172,155,486,838,606,310,541,24,753,959,198,409,732,371,321,594,477,388,160,6,646,503,909,406,309,930,220,533,781,890,954,0,847,830,126,428,348,925,744,376,124,847,139,367,859,963,281,170,14,892,560,82,521,255,304,827,809,840,251,313,646,245,592,327,675,49,251,736,291,684,185,928,530,890,783,288,994,414,974,171,512,225,182,700,849,732,223,132,614,567,721,45,148,958,130,642,51,819,460,254,366,909,691,895,862,802,167,23,381,845,729,563,776,890,389,39,71,975,61,732,277,301,265,447,739,675,406", "239,777,339,634,991,152,529,103,115,698,840,662,68,554,211,318,723,445,737,735,431,347,260,990,372,426,175,716,271,662,635,856,49,742,707,796,202,999,556,661,542,130,640,702,173,920,773,541,360,30,717,6,783,877,127,625,365,163,303,656,181,876,960,719,209,453,198,484,779,207,804,572,225,196,788,659,526,461,462,170,78,973,398,545,376,729,254,85,353,239,144,111,116,860,277,503,836,905,19,38,964,576,321,32,186,996,63,701,821,195,302,681,965,170,353,25,867,260,605,627,103,678,628,429,741,623,739,353,665,451,268,66,987,978,535,858,970,901,969,682,943,580,833,338,603,845,317,804,599,823,433,37,349,629,668,210,827,245,930,148,426,468,818,439,868,156,401,823,745,982,646,563,65,988,871,260,151,828,29,996,195,713,982,935,279,628,879,984,4,47,924,437,742,863,485,879,48,890,471,948,823,311,233,781,525,15,369,404,381,582,60,600,648,491,416,945,259,670,466,372,188,187,839,610,837,24,21,593,637,296,637,372,301,491,830,461,483,264,896,2,475,439,502,299,464,889,123,324,368,272,755,619,700,173,466,842,503,685,353,838,348,358,193,561,500,686,407,44,878,504,419,351,632,12,76,369,643,709,630,390,928,215,700,355,891,776,826,269,92,438,159,374,918,578,19,594,672,180,960,374,885,820,951,847,642,780,146,259,198,560,597,428,994,269,974,438,540,673,244,736,755,35,339,453,273,78,522,350,161,834,348,854,211,33,676,962,888,248,492,932,70,868,545,309,556,982,995,985,501,998,999,595,122,108,355,697,223,138,131,517,895,469,937,758,443,664,709,698,930,126,801,571,930,654,861,694,267,879,760,525,368,789,687,682,405,108,916,964,488,409,400,503,39,759,29,153,483,366,605,229,203,893,791,311,851,411,267,304,652,583,39,996,627,536,879,904,656,778,594,469,986,944,200,268,77,513,911,248,535,469,228,812,906,959,503,80,628,252,541,666,185,461,102,290,905,853,953,201,203,875,507,83,632,441,274,164,3,114,956,672,180,837,350,219,288,587,639,831,266,905,862,825,153,952,659,661,528,328,69,173,56,811,549,148,569,995,483,483,944,866,693,739,928,133,297,516,618,191,326,608,985,186,71,340,895,620,12,620,228,868,978,737,876,454,985,870,612,928,206,685,937,866,598,242,714,299,253,219,732,134,563,986,233,695,37,739,157,196,998,471,420,620,611,40,704,145,730,567,974,498,332,711,162,585,503,164,493,321,88,796,9,676,931,130,481,338,235,499,943,324,566,795,201,376,215,297,630,110,862,896,789,901,906,206,845,550,272,595,349,531,36,361,6,785,748,920,985,873,217,514,465,362,276,990,102,648,670,802,215,217,757,938,258,233,138,566,919,782,535,245,326,386,315,333,289,802,580,463,198,992,984,142,913,298,501,511,957,642,752,690,433,416,979,230,548,989,111,897,553,923,417,51,999,865,52,296,224,32,462,912,94,410,7,687,300,558,147,127,226,185,765,861,938,519,232,150,63,837,984,935,306,524,977,661,262,347,111,659,362,281,61,81,23,787,32,503,995,922,954,635,537,530,195,585,730,393,798,650,823,809,366,326,899,960,803,568,647,277,435,243,598,523,248,240,166,921,293,838,123,337,3,411,228,684,457,124,550,296,392,425,752,909,178,910,350,504,608,540,57,735,914,683,943,154,190,329,68,703,727,126,352,871,118,679,863,532,999,837,200,546,598,133,118,74,802,487,238,31,705,521,890,538,246,995,716,375,237,916,508,765,189,880,756,890,6,212,71,913,990,309,165,587,745,157,151,914,751,279,143,291,617,526,760,466,804,722,455,847,782,640,310,955,90,112,613,293,894,695,299,360,569,153,838,827,778,251,968,728,941,866,16,254,308,63,746,118,448,65,514,233,630,525,831,288,547,184,26,397,445,294,388,280,757,749,248,308,387,169,123,537,658,624,110,960,181,383,777,5,164,621,122,513,910,996,143,732,183,131,880,721,69,321,995,857,538,673,48,234,420,658,616,537,273,20,847,0,421,977,485,367,369,78,956,617,797,116,719,496,527,915,20,911,440,521,876,742,359,609,748,343,752,879,379,854,261,820,37,318,167,771,746,514,429,241,654,366,812,827,231,83,888,105,574,703,432,220,635,929,695,955,47,336,65,408,147,933,803,31,583,592,798,912,288,2,668,729,600,319,426,639,182,536,310,686,298,50,925,270,184,437,710,541,485,471,439,200,197,545,144,232", "399,640,141,871,940,612,869,346,343,724,641,450,678,279,694,460,962,927,322,178,100,235,162,209,827,295,265,49,626,273,567,8,298,978,844,224,801,767,222,388,991,94,821,96,351,434,30,982,736,847,949,899,527,925,146,275,455,20,536,748,401,427,205,576,219,150,779,970,86,592,886,847,916,756,967,275,118,593,57,320,370,299,998,3,449,85,349,406,384,861,327,624,165,656,190,941,173,330,804,605,97,796,852,849,299,685,389,817,436,874,716,795,562,312,324,107,699,991,109,745,699,235,801,795,919,339,47,138,713,708,194,673,24,437,787,599,134,869,980,892,141,432,32,997,351,573,775,98,629,464,284,699,232,892,868,522,533,975,913,780,33,348,615,227,194,588,943,127,396,739,860,870,382,24,759,622,958,481,611,123,76,353,314,149,719,170,981,285,338,567,31,278,73,894,551,594,456,781,713,866,854,610,543,883,968,584,957,499,36,295,204,670,53,155,481,546,951,828,743,612,83,407,463,322,466,983,604,395,182,802,583,938,87,336,670,731,347,698,160,60,925,784,604,798,80,316,376,486,717,664,64,552,931,538,267,443,311,648,593,112,873,256,711,791,62,439,69,501,728,579,290,421,297,128,614,8,949,840,796,849,16,833,790,175,944,586,322,436,767,196,902,53,721,250,285,594,750,788,662,315,771,214,249,885,256,837,850,981,134,723,555,171,427,988,63,806,112,36,462,813,293,16,222,914,483,777,730,896,727,963,471,106,722,489,135,159,40,601,579,65,733,72,30,89,683,513,454,385,735,250,305,481,579,446,416,824,207,837,847,984,399,465,264,568,136,665,801,836,122,560,920,857,432,337,156,146,143,447,33,689,22,50,801,46,774,914,56,886,567,62,413,193,64,658,878,257,725,184,911,896,274,895,44,478,187,918,844,862,133,70,754,729,953,289,190,227,944,867,959,155,630,458,856,995,970,76,280,907,148,221,776,591,695,870,621,435,703,582,622,616,723,157,86,227,198,258,969,494,512,822,153,274,420,673,235,885,995,670,614,310,777,74,890,746,831,254,623,32,105,225,364,595,34,184,111,671,958,239,581,770,610,487,107,810,493,303,710,143,790,196,396,874,317,784,326,8,642,588,438,735,324,94,316,472,249,126,72,762,163,51,649,610,756,99,200,289,347,760,81,112,750,708,719,632,964,103,517,109,951,591,763,807,714,612,930,316,560,29,916,630,439,774,82,73,989,135,73,825,584,7,275,584,116,94,777,576,304,615,484,201,941,564,808,109,486,317,933,533,284,848,649,686,343,206,402,713,311,444,139,440,647,420,648,913,887,897,311,359,585,463,561,330,962,134,511,163,311,377,630,177,743,361,511,915,125,629,274,819,755,795,491,950,496,105,972,102,412,740,527,573,491,521,555,844,7,88,901,927,342,776,275,767,647,187,169,379,68,190,131,219,680,910,895,350,123,504,526,919,503,206,515,928,227,528,197,638,582,313,658,440,673,285,508,543,943,771,776,10,257,288,286,660,83,981,478,593,225,35,955,724,66,90,654,287,737,902,492,495,622,742,133,741,164,619,753,893,957,58,422,535,91,879,774,946,342,792,209,196,217,448,315,246,112,577,490,227,126,722,206,187,972,672,643,787,571,874,278,105,3,892,87,549,755,247,894,401,903,389,454,504,480,850,727,53,167,56,332,164,349,75,788,512,208,487,250,709,602,937,388,358,196,938,870,86,700,961,574,733,631,140,804,522,420,524,240,777,245,560,950,601,87,685,51,427,902,766,348,413,668,769,646,114,860,384,788,167,659,776,18,556,770,394,61,103,261,632,291,413,404,38,835,134,166,633,819,471,230,410,523,804,852,665,589,896,499,720,589,437,751,198,910,605,757,366,493,629,740,472,816,452,508,807,859,949,625,251,390,419,512,731,360,250,588,397,521,335,203,370,627,35,397,966,347,32,997,640,927,927,561,362,318,648,318,338,46,709,849,920,770,711,49,538,388,548,313,145,881,921,436,424,984,714,395,643,846,586,897,100,872,776,169,563,395,404,830,421,0,29,267,367,973,765,113,831,791,155,261,243,332,1000,845,372,748,968,708,377,1000,280,151,895,152,101,190,581,857,153,810,966,664,974,706,494,767,980,811,327,16,192,510,209,42,55,769,571,917,666,388,777,97,126,403,440,340,644,985,682,834,586,717,701,617,339,190,589,302,35,334,636,134,354,474,928,70,317,639,376,402,238,867,857,957,406,649,870,421,984,872,259,455,3", "914,38,662,454,305,888,350,260,492,445,195,248,199,710,881,593,365,381,285,595,825,322,550,857,224,371,754,387,253,314,611,819,731,880,215,527,835,201,805,650,352,611,985,696,244,538,157,949,877,776,449,292,846,523,414,49,912,363,914,329,567,22,127,663,920,56,978,904,795,499,706,321,736,175,373,31,632,891,47,345,2,121,238,567,935,31,644,197,546,146,932,311,90,865,95,763,448,372,550,657,772,730,124,733,409,383,734,440,679,409,578,295,813,965,50,863,358,14,862,228,332,950,146,38,702,490,296,475,119,329,158,52,860,107,172,51,856,423,693,884,109,716,526,178,691,557,175,629,236,623,937,985,807,544,113,363,807,893,906,366,12,442,130,456,333,757,223,983,527,893,503,904,864,353,715,413,455,595,714,382,991,510,864,158,44,5,964,669,587,123,861,701,615,877,806,497,257,366,789,913,853,307,533,416,556,425,903,506,324,219,873,696,734,977,758,88,758,381,175,951,159,819,658,338,722,672,144,290,670,744,755,7,852,568,216,768,134,909,478,885,214,819,385,137,577,232,547,877,535,465,911,112,925,61,663,699,81,66,772,804,538,637,611,916,190,408,86,432,39,657,259,843,643,955,158,259,562,784,311,681,518,309,67,720,356,492,601,229,720,667,332,368,291,340,249,257,185,510,767,682,451,92,36,383,706,278,138,582,975,171,952,450,775,227,949,379,222,881,168,893,962,970,555,918,354,559,919,849,218,847,441,829,895,816,512,483,855,590,226,596,933,199,387,816,928,25,60,240,33,822,650,834,440,994,183,569,857,510,758,376,638,183,617,254,265,365,657,890,717,824,736,878,666,519,215,963,892,496,509,950,456,450,270,845,686,966,72,332,2,636,901,914,36,424,510,465,701,210,837,387,877,688,682,153,417,191,7,251,582,296,222,69,567,559,863,198,99,262,447,890,135,446,123,469,376,894,436,863,582,325,802,278,157,869,596,478,995,927,521,556,609,989,891,981,792,972,386,249,159,222,70,361,858,934,587,195,461,169,835,253,395,820,654,422,422,831,433,801,567,115,854,989,599,343,422,227,472,106,313,841,333,248,153,522,650,301,251,821,44,888,402,180,919,954,861,182,618,662,931,993,672,300,518,924,22,774,596,585,441,723,971,69,194,654,369,837,111,262,909,518,544,168,165,530,59,366,675,908,484,810,534,205,482,753,190,546,518,914,365,695,475,628,384,809,888,578,923,721,762,276,845,937,862,231,308,11,73,443,355,890,538,643,328,374,138,890,318,936,607,201,414,606,459,770,363,355,322,359,915,716,116,500,434,668,759,434,55,545,841,523,302,662,583,519,554,909,918,435,271,558,484,451,897,37,774,453,489,300,682,9,558,79,137,146,588,738,350,211,367,614,413,948,787,644,496,108,81,401,980,373,919,594,231,280,420,241,223,478,231,391,506,956,811,738,103,518,565,870,412,827,38,91,695,888,563,643,718,100,155,140,415,626,341,945,615,376,785,490,316,796,643,330,736,603,738,603,983,849,530,845,576,75,181,155,206,260,866,745,164,940,719,478,290,875,108,592,261,1,591,194,93,433,201,35,957,576,982,643,94,490,503,45,913,649,299,503,378,867,790,329,969,568,430,208,56,177,429,520,644,510,288,832,342,742,874,654,520,480,107,897,213,458,396,379,590,973,779,409,941,461,757,831,743,850,774,99,334,368,191,773,404,124,523,890,853,718,407,913,792,263,840,389,481,764,375,408,819,121,201,907,758,394,376,444,611,8,610,836,138,877,56,36,573,825,774,466,588,586,504,472,331,264,542,947,945,119,534,615,328,35,187,590,567,641,324,957,553,675,48,969,807,480,483,359,182,224,360,24,681,203,902,509,523,790,485,580,307,731,998,574,234,435,205,876,777,128,935,822,984,556,733,566,787,916,133,230,30,830,497,463,871,93,181,783,273,976,540,35,164,748,682,914,682,675,221,575,418,625,200,522,481,788,187,778,822,470,608,791,321,749,447,918,313,832,182,919,584,647,976,127,985,98,383,546,126,977,29,0,625,132,571,839,58,773,586,583,928,218,283,458,694,382,497,542,35,895,570,594,145,395,791,687,552,11,491,146,941,165,355,924,659,658,522,312,980,112,281,495,331,641,257,953,684,395,759,172,384,473,1000,897,140,992,88,862,773,913,93,761,900,338,829,672,872,426,607,539,225,95,10,193,829,757,842,409,204,400,400,436,550,955,89,403,605,234,419,613,993,942,689,780", "451,541,560,976,438,224,462,114,122,628,596,775,26,565,220,874,273,970,75,41,988,874,493,427,967,474,856,220,170,909,988,995,970,663,909,343,942,872,994,197,91,746,465,801,445,465,996,618,542,340,713,679,52,27,862,11,461,166,953,189,338,488,600,364,375,821,229,325,375,885,783,708,283,856,776,889,277,698,163,962,608,50,627,625,4,79,797,799,279,97,17,947,856,402,169,957,492,177,25,945,462,967,427,655,959,142,299,582,101,570,120,171,507,439,591,958,259,412,463,97,730,675,874,605,518,99,530,96,436,589,411,934,327,468,475,755,671,838,112,193,83,242,175,614,685,236,208,599,678,299,633,952,508,584,550,954,148,411,869,512,614,33,435,398,545,363,363,170,105,144,195,112,556,981,220,759,136,114,984,422,640,991,841,86,404,239,557,105,240,374,476,838,240,680,81,724,370,567,365,484,20,372,494,942,448,279,218,210,650,594,983,180,654,408,867,437,424,183,641,121,445,581,464,723,171,224,175,978,874,495,542,555,251,819,623,848,76,444,110,640,382,803,829,810,359,186,82,441,746,487,983,271,892,723,126,955,531,400,461,650,634,435,485,645,161,959,866,714,681,554,884,207,106,271,757,443,152,258,761,113,751,6,426,821,473,150,651,961,418,37,466,994,885,120,950,661,570,509,384,327,532,11,572,313,671,450,754,597,845,292,256,90,500,226,588,756,388,464,446,656,65,45,637,772,905,247,489,190,486,497,797,555,400,235,561,834,18,749,189,767,993,153,880,164,32,782,147,616,275,994,942,934,754,671,49,478,784,865,506,36,107,552,575,381,302,774,327,69,742,498,309,96,956,923,882,490,199,784,558,933,821,562,91,554,871,373,282,725,355,974,785,719,202,225,968,615,892,600,850,780,237,26,805,196,367,336,980,837,948,382,963,621,916,224,441,335,743,477,996,247,653,51,631,60,466,600,636,257,332,147,872,174,831,243,749,493,516,832,881,272,27,193,873,57,952,554,64,449,227,676,664,783,775,78,736,925,159,574,558,255,522,890,198,522,427,562,663,630,726,512,888,118,211,653,191,576,346,380,783,554,714,866,928,989,215,182,363,752,541,213,402,851,874,883,501,955,824,32,685,666,800,888,920,634,815,536,394,325,948,242,33,312,340,317,911,914,572,712,734,909,480,339,312,826,985,866,967,418,623,587,68,98,427,815,258,460,215,371,736,299,790,634,553,886,804,739,849,350,793,725,360,855,335,837,986,419,340,258,585,504,491,902,948,71,795,303,802,273,917,974,305,168,541,571,563,276,313,903,160,557,609,540,188,691,341,560,837,600,833,652,82,516,644,992,585,350,148,596,131,483,111,975,723,771,833,912,812,510,279,640,239,511,536,452,708,380,753,290,304,683,118,395,336,900,864,238,892,976,721,616,466,820,328,957,444,411,140,149,129,703,687,724,499,439,410,790,861,236,913,527,893,558,204,304,765,302,230,790,604,666,69,413,201,725,925,186,296,751,295,767,524,243,398,3,879,459,647,157,611,677,366,805,190,38,738,298,638,889,740,616,223,649,916,119,308,109,745,706,185,659,219,658,156,885,800,449,930,794,76,711,50,418,916,655,544,622,760,863,950,154,674,640,816,909,598,442,517,8,139,595,471,305,120,949,980,982,159,228,357,629,517,129,617,114,843,502,379,646,764,579,596,300,540,946,950,611,925,16,796,566,83,775,754,160,968,430,311,720,619,387,564,252,758,170,142,750,454,151,453,312,974,944,22,680,291,500,738,602,873,176,731,58,985,600,63,129,689,223,778,979,304,504,56,713,380,35,260,504,630,705,411,916,131,894,900,697,418,381,987,560,695,534,171,959,866,532,633,541,973,373,272,986,344,109,811,683,123,882,137,239,541,126,306,941,108,512,748,341,959,367,848,925,93,292,821,514,686,940,651,94,429,602,457,956,812,123,270,633,893,780,309,378,959,482,998,108,232,241,346,769,960,536,208,368,79,331,376,854,762,746,947,454,159,856,107,27,770,730,256,589,798,505,911,907,428,485,267,625,0,945,857,21,829,917,158,23,213,384,312,400,128,572,182,522,259,606,267,6,358,479,742,782,729,714,268,307,165,300,118,366,875,796,204,185,257,484,323,992,121,853,944,853,810,477,174,797,674,554,317,817,489,7,534,983,308,755,745,161,963,732,675,353,361,930,506,97,327,666,798,606,667,341,271,566,994,498,917,29,268,514,367,569,271,209,271,90,93,56,417,625", "281,59,647,605,9,529,867,131,14,746,242,649,560,339,215,253,890,907,415,76,928,775,388,649,151,674,883,855,551,767,661,463,533,33,639,621,369,857,123,453,746,558,232,917,895,727,717,381,431,528,703,267,50,703,355,253,30,833,452,61,959,777,54,399,973,740,98,148,649,121,814,335,3,991,718,167,600,700,112,692,494,505,688,813,751,790,32,997,25,598,255,223,653,686,856,987,915,428,342,403,478,440,200,280,781,993,832,171,461,321,61,908,878,296,118,288,12,339,338,809,732,8,230,347,421,56,298,694,421,303,343,269,923,711,514,983,882,161,895,823,340,42,260,848,40,122,242,22,69,7,81,778,289,701,493,837,349,653,517,451,453,302,825,281,77,46,462,585,443,433,378,558,870,391,129,76,224,721,929,651,458,469,231,896,801,645,23,844,569,612,516,766,53,121,177,57,938,855,265,367,663,480,241,673,825,324,543,324,405,156,473,562,303,538,951,794,662,895,312,994,705,560,819,40,925,688,183,400,109,647,896,253,317,623,141,977,303,111,388,477,458,302,454,187,34,67,516,611,38,157,489,747,637,599,271,441,199,452,288,857,431,817,534,992,73,531,825,973,519,276,544,508,594,6,445,976,503,648,87,44,743,803,811,296,70,343,551,243,352,118,123,101,744,530,979,573,45,202,613,766,580,331,734,55,293,630,527,244,611,323,732,764,883,753,434,523,51,252,943,590,372,19,562,359,500,351,870,149,852,871,525,187,837,413,701,689,80,779,599,581,970,916,2,293,203,162,926,309,52,805,108,850,877,687,936,241,436,635,148,568,357,370,58,946,129,314,976,497,279,779,183,140,415,365,34,83,819,349,309,419,959,609,457,534,881,14,292,200,405,152,554,153,739,792,487,118,225,783,26,883,38,426,949,200,686,968,765,154,257,182,999,106,192,434,60,973,436,209,543,123,433,840,497,115,420,324,864,505,912,602,40,697,811,841,127,6,806,42,772,364,619,924,383,661,575,135,878,533,396,891,439,190,661,96,370,392,902,32,415,819,805,10,774,526,854,9,298,594,547,266,569,356,83,280,642,954,607,245,579,940,548,957,155,972,250,331,831,674,393,461,102,18,201,811,893,332,316,13,322,801,667,855,39,687,720,624,324,691,652,55,327,844,307,507,179,325,86,483,43,962,995,174,632,787,641,889,661,885,446,990,245,822,325,178,256,396,927,192,224,85,758,611,351,742,140,898,268,779,883,85,533,614,762,129,984,854,543,804,506,187,772,415,43,589,481,4,519,927,445,372,948,508,183,82,39,925,920,896,740,722,236,450,199,426,930,13,175,836,610,10,708,465,38,319,849,696,972,120,653,837,384,759,797,720,849,235,551,232,487,516,185,858,217,181,407,401,135,616,897,60,896,160,222,119,375,814,530,868,736,912,529,699,953,105,976,696,863,410,254,878,473,700,569,985,762,355,695,492,731,164,988,703,452,468,148,131,914,995,832,518,415,720,852,424,131,379,445,439,56,241,489,602,473,374,153,862,868,259,583,156,466,644,240,451,79,975,747,332,204,399,438,191,206,232,511,605,612,326,949,506,966,295,940,758,411,947,40,428,268,63,490,575,281,478,733,184,469,520,548,358,258,839,988,377,139,235,38,271,160,483,841,340,828,406,971,714,93,692,201,690,312,480,82,66,455,555,866,524,320,736,597,204,791,787,889,430,759,473,981,345,800,913,90,363,561,531,977,76,197,252,426,106,17,561,384,600,675,929,247,726,706,95,964,480,629,48,376,683,887,424,918,755,803,568,288,777,300,72,399,49,785,401,539,239,143,352,258,421,270,968,265,421,745,898,578,141,647,523,363,198,913,98,966,365,941,941,25,715,408,392,341,115,360,418,897,163,725,123,75,791,381,302,935,44,910,359,367,194,644,296,768,806,931,943,21,374,54,428,794,576,638,99,641,191,852,227,973,659,768,545,848,662,867,475,992,234,77,418,70,67,549,721,636,588,299,161,142,862,182,412,476,747,73,60,242,522,4,950,78,841,417,537,367,71,348,367,367,132,945,0,346,601,869,105,441,30,925,746,478,89,641,399,466,594,438,7,166,385,854,43,609,922,784,401,159,807,198,164,972,917,727,649,438,609,566,520,58,640,377,118,500,351,263,576,616,6,479,558,209,668,850,330,936,218,412,98,823,585,830,238,511,258,437,587,995,826,519,965,415,873,763,660,219,793,151,463,16,563,755,55,224,494,911,527,642,181,539,392,666,286", "720,160,840,380,902,445,382,981,815,987,530,51,946,286,335,924,535,411,158,895,171,928,852,330,459,130,110,789,699,885,453,305,253,257,839,573,507,469,320,999,302,885,397,761,84,125,37,404,406,337,151,176,42,793,315,595,616,284,908,29,860,260,566,328,306,224,755,456,723,718,443,372,777,861,699,571,365,692,90,5,595,489,230,377,786,414,649,681,885,313,464,496,605,407,498,969,807,423,650,286,39,528,38,387,164,638,389,321,482,6,346,848,455,279,255,713,924,380,199,979,152,226,961,866,470,727,928,691,976,688,272,721,484,884,313,672,102,993,953,112,238,369,33,18,389,158,196,800,388,743,311,901,477,782,836,654,318,180,162,657,928,569,386,682,764,543,487,76,206,160,161,312,643,391,654,975,177,59,669,518,468,313,863,313,678,612,289,133,869,53,24,48,702,243,632,776,852,809,553,940,221,338,111,618,725,859,620,280,963,597,513,135,453,264,40,149,493,334,512,82,71,29,69,362,354,934,666,328,581,543,2,299,74,852,369,574,771,758,33,197,784,258,56,388,264,937,677,114,631,137,214,853,304,950,804,782,811,38,981,164,826,163,920,67,776,912,363,939,837,665,546,713,442,896,642,167,519,895,754,889,616,350,279,248,907,479,690,394,773,784,736,496,988,728,555,439,716,922,2,870,795,420,323,677,410,779,166,753,938,170,222,386,326,900,76,313,395,491,53,525,811,747,92,69,253,226,411,355,561,729,77,471,860,874,431,848,571,953,451,344,384,706,490,175,505,42,436,99,723,317,72,839,148,606,898,343,201,325,600,460,537,928,672,405,912,952,856,576,22,218,289,884,930,931,476,737,135,875,720,857,657,729,638,703,408,280,716,131,144,477,240,439,806,67,529,246,518,635,139,243,482,439,972,280,171,341,30,253,540,14,472,638,616,376,882,856,630,276,650,179,581,140,730,307,508,64,731,748,260,561,171,815,897,695,366,529,682,434,103,448,147,90,595,48,676,771,207,947,327,42,803,237,870,345,393,591,508,340,122,46,612,495,215,607,297,79,586,191,592,981,832,153,334,973,393,152,142,224,668,501,780,190,211,508,971,345,491,5,951,839,1000,12,923,280,738,732,461,596,477,644,457,615,381,4,443,726,431,790,901,801,333,489,683,673,389,253,525,681,606,356,911,579,487,669,286,896,796,26,326,6,661,421,116,588,950,734,211,603,328,302,92,778,259,496,615,952,469,54,717,402,704,970,165,163,100,76,755,311,356,612,474,324,274,209,379,826,376,945,407,280,90,870,840,158,546,448,789,423,565,80,679,268,252,935,59,239,132,652,866,843,669,141,176,202,723,804,870,389,345,380,765,626,50,210,25,397,798,934,295,353,447,606,232,70,16,480,911,236,370,992,907,90,109,221,752,953,735,616,868,418,141,84,431,224,65,264,59,204,329,71,214,141,334,426,160,665,128,529,294,460,387,386,803,565,902,81,840,299,131,745,822,790,824,467,727,205,133,564,323,3,848,671,918,533,665,302,614,771,441,800,941,204,18,151,819,105,429,269,13,571,131,565,613,728,954,151,878,911,256,78,812,435,380,434,419,646,145,617,893,886,2,774,99,322,775,935,774,382,701,902,518,358,308,981,151,687,443,296,578,452,898,437,790,357,314,280,975,707,466,191,65,35,25,26,483,39,68,445,296,162,972,524,468,271,256,540,816,576,622,505,566,896,767,796,752,857,102,263,419,574,165,800,890,609,60,79,365,289,815,857,682,211,843,142,245,89,994,715,616,607,160,735,933,532,804,638,697,455,194,845,70,75,73,101,854,749,876,254,238,121,912,825,166,544,502,39,174,140,769,550,858,775,744,972,409,504,975,347,457,344,200,25,217,359,156,107,878,782,371,819,13,452,786,148,404,565,224,871,446,270,568,845,937,135,301,378,799,63,620,227,65,298,107,221,8,837,545,888,996,239,250,284,370,607,402,519,536,955,797,415,797,33,400,302,837,169,767,832,983,859,202,764,363,69,437,163,926,297,200,405,693,286,913,709,925,369,973,571,857,346,0,255,790,909,520,41,965,326,447,519,195,98,679,413,517,50,566,320,979,501,586,558,455,675,896,674,913,719,962,758,330,85,192,510,627,921,675,362,605,83,228,873,404,716,458,897,414,79,652,848,134,498,353,436,809,609,887,341,99,983,725,373,830,129,381,648,564,516,35,540,369,374,37,410,631,94,811,36,739,933,876,359,839,835,423,372,201,347,314,465", "215,765,462,868,863,486,686,380,258,528,557,205,370,429,229,360,261,568,616,311,173,284,721,392,675,691,489,258,608,314,93,510,680,873,883,498,105,307,534,515,562,40,698,814,580,671,317,66,126,9,392,898,361,259,444,812,643,800,724,841,860,149,142,495,344,699,214,851,367,524,989,366,611,825,902,655,500,887,50,431,53,433,53,70,720,263,735,575,141,294,770,549,843,591,857,157,721,619,726,760,557,356,91,33,722,365,248,809,341,966,534,373,873,530,551,989,437,3,972,648,179,338,686,113,708,959,304,354,411,53,459,631,197,681,398,998,608,650,11,596,49,471,154,186,224,173,177,766,552,993,947,285,611,763,934,38,427,105,270,465,918,528,736,308,865,747,802,395,250,727,45,596,698,556,195,66,238,477,427,813,283,161,201,572,266,788,393,795,97,590,698,117,553,471,809,835,20,348,484,916,932,238,928,832,476,619,402,155,163,952,959,904,718,602,611,374,793,481,783,15,179,859,638,302,834,937,69,493,741,59,500,103,4,517,358,486,114,426,739,852,772,883,855,829,602,691,325,947,139,829,86,98,478,190,913,234,637,647,585,827,413,608,697,369,552,129,852,989,559,958,723,984,366,695,980,475,511,683,433,874,864,499,343,204,108,626,647,64,943,422,692,402,49,695,70,919,953,893,359,554,470,42,841,922,711,469,305,378,207,204,122,296,481,662,329,473,59,199,533,984,13,193,134,354,890,960,388,904,138,178,432,62,881,681,360,891,983,551,429,897,709,169,999,714,264,968,815,739,696,344,733,371,655,646,538,787,589,437,156,31,311,112,947,725,180,314,263,668,684,925,812,547,20,514,816,682,34,762,336,935,899,278,85,456,666,436,180,656,157,745,529,282,463,598,110,31,448,549,663,506,909,599,667,789,712,909,589,746,235,410,819,868,98,867,466,507,627,845,991,306,143,875,614,556,291,802,122,218,118,841,468,984,183,287,177,243,43,165,791,370,533,852,160,1000,985,648,610,99,503,340,77,255,718,196,772,670,280,553,658,685,297,500,368,625,164,429,517,282,813,887,470,124,16,759,395,336,476,579,156,143,902,976,759,924,475,643,913,231,242,266,713,403,992,626,125,930,297,895,134,328,767,12,174,310,324,969,897,642,523,346,691,924,664,723,430,494,647,333,710,581,757,284,454,659,65,551,750,975,666,976,399,58,781,949,431,66,57,56,285,36,383,887,104,441,793,68,428,51,403,498,723,889,959,568,949,671,721,949,79,905,202,841,54,906,28,112,249,682,514,827,78,478,223,637,716,952,265,737,664,798,224,212,933,884,835,537,560,494,355,210,791,334,703,963,438,417,992,592,519,407,858,235,456,406,430,697,577,624,402,144,705,975,2,96,288,687,586,244,187,117,77,970,821,924,505,148,543,621,957,364,805,802,173,241,243,836,930,318,114,582,315,771,640,416,15,644,57,977,264,77,310,10,170,174,8,298,592,277,821,707,212,92,94,250,816,124,473,37,894,994,119,718,765,40,927,111,935,376,198,307,642,5,865,880,730,130,704,416,147,588,592,295,836,854,617,401,757,879,628,363,36,292,949,473,400,256,966,814,214,949,713,266,292,291,800,492,271,867,200,983,251,662,603,286,808,758,981,389,782,322,411,323,158,698,799,425,380,522,583,686,545,547,743,345,865,407,342,743,321,524,354,449,827,597,43,875,469,170,577,195,377,411,73,505,148,573,572,835,783,702,507,142,855,946,882,41,718,223,3,364,989,195,596,852,49,313,562,955,566,53,809,865,244,583,926,741,938,186,216,855,344,783,813,316,505,230,253,111,986,795,598,242,948,314,421,432,8,643,212,107,163,781,724,56,170,47,14,730,749,220,418,529,865,594,958,300,181,779,228,838,473,867,841,596,21,59,303,524,44,846,392,445,470,476,399,92,511,114,320,305,966,527,81,592,342,674,379,946,816,98,554,921,936,48,20,922,453,927,937,518,744,710,26,111,909,10,409,414,299,785,872,479,745,699,929,791,689,581,813,191,836,86,430,532,744,78,765,839,21,601,255,0,605,334,970,774,878,465,906,405,269,341,409,499,610,696,221,448,114,119,284,208,64,235,973,764,703,815,789,765,862,549,454,574,976,479,277,343,55,739,691,892,595,470,74,251,234,244,72,367,78,658,571,466,177,616,914,992,664,194,699,565,306,336,683,577,572,436,809,325,555,202,879,772,952,474,201,559,325,740,805,479,439,521,502,326,145,931,4,529", "62,92,761,472,58,727,65,927,606,315,196,640,722,350,822,119,9,412,90,531,841,366,870,655,319,29,352,821,152,347,708,625,816,42,876,975,676,773,772,145,92,365,544,286,856,646,600,507,660,755,264,216,973,848,469,261,719,71,810,369,459,976,70,437,303,998,89,139,752,644,621,258,235,943,567,366,828,826,743,370,519,953,27,490,137,21,686,525,369,437,88,622,800,860,977,194,122,271,149,766,47,840,470,794,135,100,914,899,437,966,608,287,891,262,371,947,348,226,230,35,770,408,701,333,234,666,156,874,258,771,693,193,425,377,581,175,253,204,665,579,762,502,710,653,612,627,382,248,158,49,947,575,927,604,898,600,40,938,191,693,766,276,751,457,150,77,703,879,176,760,107,673,79,309,762,505,841,659,60,966,882,990,951,263,966,982,765,415,93,328,708,844,262,608,516,245,803,966,198,861,479,194,328,532,647,469,263,332,403,710,731,800,788,330,383,783,984,627,581,247,198,243,812,712,741,586,913,860,210,901,765,473,478,644,790,270,200,509,777,431,926,318,732,663,17,991,729,993,510,32,395,851,990,764,719,404,570,681,168,943,904,519,441,497,932,563,426,798,982,287,63,603,601,765,805,56,796,281,937,286,4,930,939,29,667,995,985,998,147,684,97,338,883,490,24,838,669,533,579,870,140,925,608,908,774,816,573,220,507,292,316,627,521,793,349,364,163,737,32,390,933,367,747,270,65,453,706,24,438,663,623,675,626,256,627,665,372,159,536,33,767,289,884,391,816,429,344,518,35,618,671,888,905,238,856,711,301,893,743,42,915,508,651,297,825,720,920,385,536,599,26,397,341,267,568,412,26,567,184,486,914,462,948,731,156,58,352,268,81,327,320,439,942,930,654,182,342,911,935,219,622,792,711,924,130,133,1000,574,820,70,711,580,729,756,181,8,264,207,359,246,683,476,249,66,692,869,920,987,226,759,920,76,102,314,698,217,428,339,226,829,611,773,259,460,486,12,45,181,255,949,850,779,436,735,109,337,19,191,512,802,940,87,59,565,778,532,253,715,845,400,857,834,984,975,614,361,325,645,377,339,678,305,151,967,419,314,729,138,390,660,404,880,744,48,887,710,873,527,586,737,576,748,349,946,739,406,129,137,509,414,175,224,985,211,429,62,606,138,908,796,561,144,2,905,32,535,858,653,837,455,900,619,339,848,58,272,993,819,396,657,323,644,606,772,887,430,7,312,549,814,519,318,146,515,942,713,76,801,589,386,502,774,830,757,338,69,850,795,651,224,473,705,130,542,405,490,514,223,777,778,583,393,856,885,75,894,709,434,791,770,879,832,613,803,557,994,127,746,339,87,890,825,589,242,646,963,652,723,415,955,432,5,7,259,157,787,952,668,416,830,303,9,500,549,738,965,802,131,406,230,690,502,15,334,142,794,767,398,448,159,206,718,535,981,761,229,660,190,203,316,711,53,137,519,267,169,883,850,750,147,922,77,487,199,72,661,94,610,926,539,11,282,126,554,369,246,77,246,12,170,629,152,737,198,572,20,928,316,630,64,345,718,7,746,642,955,316,909,997,923,507,77,629,223,943,601,132,974,938,804,993,264,272,549,182,4,51,437,137,205,867,57,26,273,161,319,887,54,491,704,727,778,309,258,883,311,100,411,302,586,535,457,947,200,249,327,809,279,683,884,990,100,492,870,571,16,290,723,799,258,570,644,790,616,194,197,305,926,943,96,781,92,793,279,1,741,833,543,245,319,553,95,630,93,922,232,68,689,902,166,219,316,78,181,508,170,112,651,538,240,779,748,10,729,178,165,495,651,213,588,167,453,49,658,271,867,751,199,531,463,995,849,109,313,403,723,903,989,286,375,131,950,487,64,286,377,62,918,717,507,213,441,142,823,162,389,42,157,686,920,891,423,592,854,919,106,712,185,39,141,118,834,940,744,647,428,506,902,139,398,381,688,807,852,181,436,366,38,611,417,423,46,689,515,205,135,782,160,915,870,852,630,241,526,10,646,299,80,675,477,45,444,523,95,376,956,113,58,829,869,790,605,0,532,552,391,804,928,721,317,912,638,459,551,547,27,694,945,512,199,696,257,63,517,770,432,370,876,791,267,936,381,22,127,344,766,833,574,572,340,210,425,436,785,136,884,166,558,536,330,871,953,44,816,488,316,577,197,604,515,78,734,961,836,163,414,153,129,179,757,81,787,910,905,908,254,682,312,785,968,845,927,660,492,968,93,991,862,667,121", "962,32,410,410,951,165,561,238,127,531,480,87,527,486,23,417,613,489,767,617,69,436,208,213,342,180,266,148,430,442,603,111,224,293,1000,660,335,111,839,507,264,655,350,416,256,368,754,169,399,469,183,688,80,784,804,270,585,61,354,265,731,555,567,898,297,954,199,420,499,488,944,570,664,201,9,151,64,55,547,448,274,227,287,333,112,125,244,717,586,962,487,506,234,624,911,583,587,660,209,536,533,233,798,42,226,684,423,747,789,149,903,687,253,914,30,347,77,12,85,548,956,212,22,245,881,124,3,542,663,168,808,358,502,587,591,580,349,735,72,45,3,929,233,192,166,220,239,766,149,950,774,337,477,512,530,975,481,367,22,573,943,493,991,151,33,825,332,264,6,533,941,154,950,196,269,813,593,92,504,688,978,425,26,13,175,133,538,527,120,844,614,327,22,560,231,843,820,250,739,656,192,424,758,531,253,598,231,766,192,19,324,581,311,84,929,993,443,448,692,488,324,459,743,217,193,953,319,100,511,165,851,375,694,754,533,795,513,278,428,21,831,343,808,325,641,969,903,860,162,973,104,303,491,971,976,954,74,3,78,968,833,89,740,570,603,761,766,492,525,21,578,187,13,82,700,740,455,16,748,982,815,869,71,594,477,609,934,808,868,730,212,621,235,814,338,59,563,811,844,418,426,203,683,534,810,30,185,64,864,941,244,292,715,951,193,481,93,456,239,821,254,683,9,973,38,826,839,428,135,919,296,446,578,255,819,417,361,375,474,897,340,985,104,451,491,331,438,961,578,751,263,703,668,444,158,489,234,874,628,119,493,955,590,574,432,839,966,264,959,950,959,32,654,98,678,482,872,589,857,919,683,196,105,135,494,7,808,943,866,297,813,791,146,694,951,980,479,277,1,968,797,488,209,847,185,975,500,686,509,852,348,484,614,945,814,493,41,698,337,856,825,785,214,77,771,971,259,714,226,577,810,942,237,274,41,420,575,166,233,978,923,133,525,198,658,38,680,176,575,940,387,980,300,222,854,23,320,188,391,22,453,561,218,51,952,517,820,761,957,663,612,8,869,222,787,495,219,353,48,881,51,734,312,821,625,189,300,412,852,658,885,799,42,128,798,436,115,471,651,806,834,512,368,871,454,975,579,877,736,615,452,276,49,566,718,385,557,459,850,951,992,241,486,57,964,251,177,687,724,526,723,480,447,981,581,210,703,309,898,372,16,826,984,8,303,442,917,108,629,693,189,261,70,329,495,377,773,80,831,508,568,706,919,852,949,463,863,704,886,743,825,926,436,59,7,836,713,474,803,904,688,599,824,566,489,234,555,415,446,865,45,111,431,535,695,720,359,315,286,817,953,190,233,921,525,83,729,694,693,173,742,598,395,68,356,887,435,867,993,721,409,205,296,58,932,650,260,421,692,290,808,475,92,649,966,161,876,544,126,846,439,53,75,348,963,246,140,375,384,413,504,324,133,62,106,626,982,699,934,330,841,434,548,240,339,162,793,224,53,529,183,493,779,178,454,593,967,380,882,184,378,658,974,351,304,193,21,547,778,588,201,475,801,429,941,892,209,424,485,212,186,181,99,462,855,621,251,409,29,356,418,338,701,44,674,251,103,101,212,244,271,133,301,307,845,199,260,621,561,519,573,362,919,825,465,344,312,903,939,696,860,739,8,62,848,157,452,162,794,518,208,131,160,650,814,498,757,981,259,71,452,555,945,111,359,929,757,443,605,972,342,748,313,192,897,850,40,491,466,313,657,451,767,332,441,854,464,624,422,506,429,910,890,323,24,233,986,938,370,752,717,569,117,345,798,986,789,469,393,222,202,578,708,880,832,534,968,826,801,823,768,900,368,42,857,591,489,869,173,937,332,97,984,966,879,87,221,568,378,180,379,376,292,866,740,427,958,116,176,596,533,754,215,980,876,466,941,352,248,24,76,994,269,278,585,216,627,28,965,297,636,740,325,275,285,177,423,618,929,732,603,710,584,262,222,134,539,104,340,90,681,119,936,630,728,467,249,367,893,356,350,933,57,717,124,617,831,773,917,105,909,334,532,0,830,285,307,318,623,201,937,356,834,856,522,718,90,677,811,51,870,871,498,706,270,609,67,555,320,304,56,510,644,104,725,697,698,936,546,628,762,778,138,469,997,784,565,382,818,449,879,595,500,175,642,490,332,143,990,853,726,473,92,717,208,908,132,576,733,282,915,839,834,411,238,365,701,970,65,928,332,651,894,808,126,890,138,239,634,462", "8,56,764,549,266,94,989,594,39,374,301,729,133,594,914,946,516,191,97,537,963,622,128,636,988,156,747,684,693,72,629,306,690,337,263,204,356,556,914,765,588,471,426,742,805,712,933,402,770,985,477,781,702,259,652,721,222,656,549,358,392,765,690,495,217,342,716,10,400,191,455,84,821,136,283,816,972,705,435,409,858,653,925,457,363,758,569,832,892,809,121,778,646,435,981,363,266,382,4,623,584,285,377,998,123,162,727,414,241,312,535,98,423,746,489,46,274,589,525,217,134,238,583,732,500,451,22,609,880,482,400,650,620,192,19,734,222,557,802,984,267,767,748,450,613,816,384,810,161,119,575,752,332,358,290,993,824,826,826,604,747,978,641,631,487,280,37,38,299,10,318,943,246,80,369,593,775,485,33,299,788,97,448,446,243,759,891,489,54,237,753,809,118,531,914,997,33,764,125,19,45,522,670,597,889,149,730,184,240,820,703,979,596,542,412,807,600,840,636,709,514,444,804,553,432,865,587,400,809,669,71,756,285,793,138,269,310,184,538,575,422,277,943,489,677,165,388,653,616,423,229,783,106,978,514,890,531,705,138,990,20,502,189,928,362,148,664,364,45,488,256,889,521,866,250,472,412,83,840,808,554,226,58,224,964,299,606,442,852,416,718,665,366,837,802,685,69,638,114,787,108,587,355,115,665,41,442,646,317,524,288,202,484,283,879,617,620,999,461,730,161,832,486,355,355,25,776,807,524,393,549,390,647,901,662,903,482,423,36,17,624,234,738,735,33,377,791,738,274,218,409,656,308,348,414,719,97,791,651,104,489,672,185,860,613,426,550,721,751,134,342,414,527,679,991,861,716,601,644,936,447,36,744,816,448,618,623,182,689,536,657,318,380,329,220,205,775,206,362,436,759,849,366,690,194,267,732,785,973,919,143,533,150,673,992,757,38,912,733,910,75,862,936,949,218,966,437,245,717,911,804,9,249,196,500,149,646,550,912,621,986,387,672,594,406,469,345,161,453,868,256,91,753,32,593,798,728,169,297,298,958,155,515,66,921,806,828,69,846,240,283,782,659,477,786,190,202,842,786,594,440,225,101,747,473,446,621,410,395,793,89,392,870,535,555,624,434,554,782,560,568,922,450,434,107,465,526,701,294,950,452,792,494,589,803,794,605,468,737,861,817,702,406,696,901,202,896,906,522,257,599,811,52,576,396,542,269,270,597,281,740,334,161,327,474,681,771,403,328,679,770,839,93,470,623,155,560,114,629,308,539,929,397,833,620,570,112,966,729,766,724,977,319,976,727,388,397,197,346,698,681,780,1000,985,349,617,776,482,923,223,734,316,826,219,861,636,5,702,237,165,307,657,129,167,91,676,350,355,837,60,802,766,762,514,290,465,260,999,678,252,84,828,335,32,123,543,272,181,938,584,773,480,908,927,362,338,370,575,574,203,194,200,987,180,860,659,192,816,422,141,843,244,820,767,187,95,241,401,850,887,240,798,865,88,451,251,80,833,548,600,572,530,559,657,202,961,309,186,531,277,712,982,614,748,286,785,294,105,404,32,756,122,607,59,296,904,426,880,420,58,201,418,902,655,946,514,351,401,208,109,745,988,510,892,9,481,256,866,517,361,969,553,234,339,214,249,615,920,559,690,45,370,373,983,721,231,789,896,530,190,394,967,128,769,978,264,56,590,535,246,478,274,37,131,622,630,66,513,583,493,526,727,478,375,907,268,375,519,732,570,726,702,420,91,205,401,906,704,637,513,398,509,429,626,882,785,193,901,593,474,631,602,178,831,101,882,154,654,304,849,565,150,103,647,273,909,222,59,12,594,681,343,230,277,479,617,553,162,316,143,759,463,329,965,746,74,399,455,176,175,342,927,144,128,388,845,59,51,960,982,382,777,711,746,945,180,674,196,909,94,689,958,786,509,186,606,852,86,842,640,822,896,60,943,463,547,176,840,424,189,532,166,241,928,891,843,843,910,95,292,518,221,356,480,68,22,818,184,705,536,467,439,881,531,245,849,517,55,245,175,438,896,503,986,847,797,791,586,158,441,520,970,552,830,0,91,297,275,446,238,795,945,650,674,417,914,82,349,526,464,288,375,170,330,811,643,744,359,109,886,830,744,629,491,292,8,393,993,12,78,847,945,428,670,30,793,670,947,349,409,406,137,73,989,170,927,933,728,277,375,171,56,597,639,485,900,483,162,342,770,930,341,371,864,518,885,344,453,398,322,648,71,747,560,78,805,184,492,575,751", "208,662,177,277,135,23,337,5,868,428,528,538,821,73,968,660,597,27,263,737,552,998,56,51,434,875,11,797,509,959,904,331,659,377,137,194,510,999,570,815,507,755,972,690,436,625,927,761,355,444,11,920,569,391,509,26,770,596,917,645,333,561,165,318,243,904,45,439,38,636,221,63,278,106,185,98,572,910,141,386,402,906,269,126,256,915,454,914,825,971,140,112,2,316,624,958,535,946,67,708,780,282,508,403,19,729,596,174,314,615,37,521,336,115,201,977,129,649,681,103,828,271,30,283,918,352,536,180,813,622,956,421,742,119,164,571,604,902,859,442,139,521,523,52,51,889,977,559,694,139,143,426,199,939,69,477,753,284,891,960,771,509,191,558,672,418,380,659,519,362,826,970,794,700,102,42,726,101,16,360,689,612,980,869,989,799,620,664,308,287,893,119,744,71,236,254,426,382,925,893,817,390,334,401,926,141,155,593,927,473,383,97,944,718,643,956,785,564,893,986,250,924,995,475,100,431,867,214,957,914,280,132,475,670,332,827,185,469,77,363,535,369,254,248,378,885,326,684,181,17,225,324,319,314,85,891,58,29,749,517,830,585,295,898,598,132,135,816,162,7,633,469,316,135,44,405,85,514,449,682,566,985,947,786,507,25,879,176,157,617,634,687,67,385,925,143,359,93,272,783,716,904,559,69,884,167,460,959,362,529,208,851,297,107,763,104,834,757,159,218,820,101,50,490,82,216,86,272,737,842,445,688,649,607,970,491,484,237,309,425,233,817,955,349,451,708,34,959,662,430,598,631,301,831,859,47,626,407,910,681,719,198,936,527,938,382,731,480,898,548,446,339,643,33,124,274,435,52,540,298,270,171,185,159,582,275,753,657,66,517,902,820,991,487,706,538,967,88,817,995,960,170,828,519,955,125,196,202,519,204,355,608,861,340,474,244,623,804,302,497,398,277,271,860,398,409,754,511,621,49,429,766,730,120,626,518,636,669,763,744,352,60,341,3,648,785,57,89,378,752,381,130,668,26,46,760,752,451,978,565,953,121,961,415,544,173,366,677,647,162,292,748,733,402,281,188,408,441,849,663,515,515,42,404,820,328,838,174,648,815,178,632,836,945,141,696,5,491,46,195,799,703,594,168,329,542,950,541,617,310,817,741,372,107,17,719,584,569,859,465,409,606,635,119,676,614,728,825,215,778,584,358,281,573,333,354,650,404,221,864,736,319,425,363,839,192,454,388,15,171,571,483,522,519,27,152,660,521,929,747,204,817,713,896,34,682,914,537,52,299,860,606,733,221,943,473,803,994,132,432,697,539,287,646,511,356,704,464,493,812,737,351,959,786,696,864,903,391,871,717,725,359,454,89,178,884,572,544,201,261,966,225,197,103,786,555,827,491,460,762,287,725,807,983,156,664,923,568,241,829,382,183,84,463,233,223,572,492,322,924,739,886,173,843,395,460,870,461,605,78,969,958,310,446,896,613,344,510,683,109,713,156,411,824,630,987,653,280,125,306,107,733,964,762,893,423,655,975,270,216,507,652,689,107,213,50,811,674,726,528,117,559,597,416,988,650,13,309,976,888,1000,870,814,768,756,924,659,410,739,302,639,33,828,761,549,743,976,511,402,364,459,376,856,641,581,453,483,767,276,168,547,598,714,160,114,85,465,733,805,24,444,767,249,861,81,125,495,51,424,726,573,721,549,87,365,477,218,869,226,326,717,151,861,579,379,911,463,4,56,463,710,62,789,846,931,456,657,886,261,617,918,472,325,260,61,247,932,286,655,470,5,733,984,601,472,486,825,700,479,789,387,753,17,502,91,106,983,473,486,207,500,817,183,601,493,151,479,225,196,971,283,701,264,616,945,351,714,521,826,775,262,615,127,272,779,808,126,646,101,190,26,808,48,701,198,819,229,971,465,847,461,324,854,221,808,981,516,363,347,669,366,523,328,187,252,557,27,559,72,150,393,778,633,576,82,631,106,239,294,793,672,204,733,81,702,243,875,177,291,399,258,495,78,236,279,235,998,126,619,23,444,55,358,622,139,116,155,583,23,30,41,774,391,285,91,0,564,430,740,15,143,100,632,259,567,742,664,702,33,321,74,792,455,31,57,887,945,869,707,390,884,501,999,449,708,969,846,403,380,777,414,105,258,63,858,744,609,620,893,770,817,834,835,259,71,463,486,171,472,682,816,107,261,137,660,998,97,485,17,304,993,842,48,474,777,368,162,227,342,296,604,755,602,727,995,98,590,496,906,131", "617,451,39,392,131,53,754,9,750,942,438,295,546,25,13,446,626,888,552,877,649,763,64,212,857,778,293,444,188,793,964,75,596,708,436,245,879,128,403,832,924,518,644,498,915,630,62,250,132,711,968,63,832,669,817,1,498,357,529,948,546,399,51,672,193,771,145,756,877,913,636,582,316,297,83,589,250,101,761,696,862,239,314,174,349,566,188,689,737,538,2,825,148,724,651,357,711,717,69,1,330,532,691,431,898,582,528,433,143,206,679,579,532,480,208,920,982,623,842,264,526,77,148,398,833,823,228,777,68,510,685,425,522,874,649,128,24,460,978,334,473,359,242,835,9,398,49,262,336,608,654,702,706,583,654,881,784,299,394,42,97,3,596,334,649,460,109,865,997,170,701,248,317,414,295,743,222,475,812,43,48,743,312,654,889,322,99,331,372,752,338,899,122,247,836,171,176,96,777,633,319,539,584,640,304,96,569,610,590,934,40,47,828,275,38,175,987,664,794,116,926,896,233,1000,287,587,373,679,315,571,776,517,5,121,394,242,156,941,393,696,85,246,396,566,678,471,447,365,756,387,231,57,977,915,931,308,411,853,354,980,881,93,601,979,607,650,293,17,680,616,632,604,562,793,549,437,163,560,884,34,27,735,847,150,473,742,909,671,293,253,780,258,261,967,181,311,963,866,670,301,617,509,854,641,261,116,323,50,241,943,366,514,607,690,143,331,477,98,502,632,484,947,312,814,542,658,186,28,9,664,989,37,544,748,608,853,499,899,746,590,829,96,876,922,861,511,509,753,314,192,488,249,719,304,577,496,509,14,794,684,679,82,65,628,922,218,304,918,776,749,300,178,957,305,119,907,287,69,957,54,318,193,599,105,378,534,563,372,166,143,554,590,288,742,178,920,863,999,238,464,897,251,983,872,734,682,895,615,177,913,770,714,955,361,19,196,235,291,169,491,596,10,463,697,347,135,35,328,287,595,704,951,609,375,204,305,712,145,776,685,715,474,878,543,444,960,93,731,816,730,720,535,789,510,547,94,220,857,225,503,544,923,996,618,948,861,419,968,44,189,934,17,950,966,686,943,803,476,949,977,316,340,975,183,637,162,811,483,401,659,277,643,775,391,816,618,41,66,79,983,997,860,207,846,238,696,815,839,358,189,942,549,458,711,18,158,104,871,207,342,76,386,323,138,679,478,548,303,709,92,967,903,348,562,649,752,516,573,396,29,454,513,573,104,746,436,959,977,963,193,144,433,511,617,426,996,86,170,428,453,141,81,499,36,181,203,768,78,443,525,83,149,98,566,567,645,983,421,167,944,537,721,823,722,78,698,803,819,548,492,196,998,877,154,361,443,765,997,442,611,396,125,777,177,589,727,262,719,644,191,909,947,432,765,331,637,206,685,312,182,116,790,738,24,709,810,807,473,603,145,193,27,45,274,510,401,361,664,481,138,645,560,834,378,415,70,33,405,271,430,83,270,58,223,692,76,509,136,391,457,823,277,631,309,514,395,102,979,924,427,750,628,745,2,264,175,206,158,430,42,177,712,451,852,454,299,931,188,792,946,360,143,805,338,797,66,727,968,299,681,200,49,206,838,716,609,86,881,778,386,161,30,184,156,732,254,825,203,257,771,138,751,922,97,321,523,500,521,515,798,179,26,845,181,51,10,188,457,268,826,631,468,919,478,613,479,378,379,958,805,849,660,336,855,159,867,889,717,778,701,901,490,147,309,420,732,675,159,287,61,897,849,589,269,259,451,170,945,999,845,776,779,525,629,268,340,402,319,12,248,903,470,774,861,11,452,976,251,432,727,295,111,264,757,781,936,885,855,244,686,599,762,103,151,647,409,299,535,647,469,357,144,314,747,84,1,627,355,150,926,263,964,61,808,427,206,308,508,201,725,263,761,914,306,209,933,440,539,259,939,579,431,264,919,752,426,758,302,554,101,922,84,58,699,993,77,416,44,966,717,66,548,971,141,322,615,292,733,94,812,715,841,450,35,933,970,190,64,857,841,583,453,75,291,159,668,262,221,131,459,83,590,687,534,367,719,261,928,213,925,965,878,804,307,297,564,0,111,675,418,371,473,738,799,307,790,947,118,260,77,596,283,740,158,466,750,189,967,371,858,592,601,262,829,21,302,68,314,519,290,36,105,669,533,696,546,116,533,13,701,979,350,482,366,47,689,833,216,164,106,711,991,251,513,340,460,277,518,304,910,981,476,346,901,8,531,81,287,917,628,308,99,349,896,619,304,262,869,565,589", "285,449,138,907,44,415,901,877,36,806,492,166,213,987,814,484,974,55,870,823,203,257,274,605,569,247,273,629,319,316,759,851,217,49,112,854,217,667,371,248,148,466,3,840,703,921,185,975,608,340,893,455,794,254,547,229,360,362,18,138,307,25,69,895,259,426,961,308,935,812,130,347,179,98,897,720,507,344,727,643,300,333,27,894,261,893,813,744,343,582,312,615,400,191,737,756,727,579,653,733,704,586,456,707,420,716,970,975,880,617,567,242,689,969,210,427,80,689,322,991,285,650,995,783,939,984,983,100,706,892,239,517,238,76,575,258,948,268,384,544,469,347,492,985,969,140,861,878,721,48,606,486,187,460,657,966,742,170,73,225,746,20,341,483,621,851,93,880,82,335,864,334,60,136,868,743,942,425,260,552,24,159,483,98,604,720,932,413,661,958,195,153,166,974,79,372,710,27,475,199,350,435,909,27,542,493,214,267,970,751,214,492,66,191,599,313,686,108,192,329,539,747,996,450,265,679,77,67,998,373,634,651,322,947,793,365,319,482,714,257,424,76,977,372,44,962,453,190,841,814,604,434,469,768,48,803,286,346,511,907,261,105,335,948,190,137,424,917,613,1,280,310,926,478,16,728,280,63,449,38,828,865,875,505,178,6,387,691,122,31,445,235,36,450,552,909,409,855,397,847,844,429,472,685,832,237,38,868,41,371,901,388,560,710,851,488,149,913,181,797,107,357,904,847,160,308,692,108,168,84,970,239,514,880,329,942,588,204,135,8,287,235,786,6,87,97,173,24,681,545,531,530,530,511,140,185,302,874,479,573,363,541,921,465,532,212,527,138,839,943,825,761,401,855,349,826,329,853,523,847,203,995,368,341,755,935,727,914,99,155,897,326,916,429,231,224,240,616,960,456,881,505,485,728,860,514,873,440,774,198,616,186,835,436,373,206,888,319,370,345,685,528,74,511,321,678,365,886,84,826,593,322,954,403,657,80,851,251,928,554,220,795,655,447,988,362,683,665,808,697,710,749,188,616,743,578,933,903,725,900,713,896,10,279,144,552,114,106,932,249,496,369,713,136,705,966,426,156,214,65,88,263,689,233,782,928,80,252,33,991,411,362,826,362,219,562,462,473,753,499,332,613,258,232,714,118,290,867,144,811,260,778,784,325,49,93,276,347,169,751,533,294,920,701,944,627,986,690,987,856,104,446,35,628,726,982,793,954,392,56,142,597,343,530,478,239,195,857,817,246,8,928,714,593,574,301,17,153,862,5,244,186,321,740,988,648,325,705,350,587,511,555,945,48,496,259,329,965,662,104,545,236,912,660,719,929,817,739,406,208,373,141,204,953,44,116,163,638,395,819,605,757,178,42,733,407,530,586,102,584,730,585,369,847,961,878,211,631,810,164,505,402,636,755,872,813,674,931,429,144,423,391,686,396,116,45,842,367,818,428,555,260,838,233,539,779,358,951,373,996,564,283,349,590,213,185,548,911,91,248,60,122,555,169,41,894,50,669,628,727,461,682,967,407,165,857,85,877,42,389,984,883,547,988,156,668,238,855,198,46,403,169,963,955,448,175,925,572,298,381,689,871,491,197,359,106,634,830,829,655,923,427,626,240,44,648,859,10,384,252,307,520,95,391,540,512,838,619,725,506,533,948,958,916,688,185,72,276,210,719,890,552,469,13,7,35,465,830,490,491,6,397,838,766,634,352,552,712,729,350,195,754,627,945,633,186,233,171,422,505,898,14,324,517,675,421,136,49,98,97,590,866,122,318,935,694,784,98,80,520,514,607,153,831,5,782,275,773,925,512,357,233,675,251,108,299,888,416,830,437,887,897,948,710,896,747,873,915,439,549,568,155,637,944,353,511,406,463,796,847,747,752,801,267,592,546,330,297,481,874,919,988,913,174,235,624,940,826,996,531,153,733,735,95,443,914,339,3,432,948,694,430,285,220,308,258,294,319,584,449,468,198,406,948,401,460,338,243,704,726,590,344,886,724,430,551,6,259,336,209,611,780,991,621,956,495,275,369,595,643,850,517,679,806,859,496,243,218,384,746,326,465,928,318,275,430,111,0,230,142,730,943,338,501,197,225,891,353,192,617,892,858,188,540,678,871,975,865,294,100,280,460,796,566,752,29,602,334,138,809,120,343,840,853,888,584,253,735,799,122,864,15,588,9,745,371,94,481,971,876,276,832,664,248,878,489,145,215,980,304,50,977,158,697,458,839,966,95,955,194,381,189,628,869,960,977,211,502,577,587", "391,517,974,893,133,16,348,943,308,533,381,363,957,161,218,41,950,485,984,379,792,305,160,337,531,771,286,63,198,160,278,143,874,706,827,974,951,208,81,128,360,489,850,487,873,607,561,789,492,966,337,660,355,997,198,770,247,13,318,498,413,35,984,152,988,588,80,885,822,974,979,900,634,161,869,452,345,335,934,953,932,58,934,878,103,982,505,164,632,683,945,67,372,675,366,817,500,261,518,644,264,627,599,258,659,454,247,154,432,589,957,935,903,343,520,49,45,806,298,172,768,392,80,33,486,998,937,192,555,792,189,433,926,864,472,558,843,443,573,455,374,220,494,711,202,199,163,252,196,456,744,969,964,914,257,533,898,314,362,868,499,170,632,199,408,175,879,157,177,977,175,945,799,547,827,798,616,13,6,912,458,52,951,119,554,239,929,979,932,45,185,365,316,738,19,505,883,503,888,39,897,155,459,450,296,553,694,934,999,4,286,436,228,993,409,173,983,236,12,549,208,933,919,373,954,869,200,429,107,104,174,660,540,684,244,641,853,176,269,593,569,943,956,929,832,350,709,920,815,339,773,619,888,108,168,89,67,824,949,879,383,305,236,974,282,444,405,492,27,841,306,395,237,396,199,911,824,660,378,711,282,298,663,8,220,651,766,225,749,395,311,996,143,307,895,286,42,19,499,611,423,123,54,111,494,962,726,985,746,60,416,636,598,724,409,947,104,393,961,918,23,427,572,981,268,288,955,255,995,775,552,218,921,596,654,21,509,954,725,723,593,963,907,163,328,334,642,923,80,450,299,553,312,610,915,632,881,689,135,666,192,646,312,430,501,967,914,846,995,792,339,563,495,523,899,87,755,934,199,227,461,13,618,263,40,380,798,132,385,662,181,59,965,531,413,370,246,176,939,856,476,705,201,902,769,900,884,905,197,817,434,136,988,221,976,36,938,493,79,51,253,210,281,769,584,526,42,790,853,635,921,153,744,208,280,456,103,33,73,206,842,410,905,41,188,370,826,942,157,712,238,855,592,329,637,43,585,299,938,560,234,628,76,666,763,42,543,245,699,93,417,289,913,378,211,802,666,988,174,389,399,643,630,182,43,811,449,801,549,477,225,522,124,881,18,498,566,823,673,68,107,140,56,677,646,538,199,802,264,234,514,340,27,501,6,471,104,519,611,862,150,913,961,549,45,713,907,887,433,872,361,147,386,115,668,186,936,3,939,922,33,604,942,69,439,735,616,158,960,271,745,733,113,632,733,178,65,268,646,915,708,904,675,960,291,165,783,570,989,215,448,446,844,512,820,67,974,426,229,461,658,196,482,760,879,857,920,465,194,945,741,178,102,880,638,59,443,791,212,54,533,625,356,325,955,400,824,96,396,258,568,959,463,142,90,362,52,899,171,790,809,331,737,139,849,770,932,828,313,436,408,325,173,455,532,430,732,885,191,517,281,118,428,638,361,507,327,433,997,745,554,907,671,201,164,57,314,3,31,895,413,764,831,724,569,131,143,748,816,673,765,417,286,112,452,794,65,984,532,944,94,756,835,806,240,627,114,143,374,174,959,291,422,823,769,818,746,18,743,629,87,900,779,66,37,754,374,638,121,653,132,190,854,743,557,444,4,625,599,474,740,453,289,358,271,701,114,150,693,725,607,634,877,760,328,903,843,557,687,698,548,575,848,62,601,103,664,281,68,869,583,261,605,491,170,929,579,992,569,949,635,182,984,911,694,493,44,691,921,987,45,150,815,286,671,624,956,478,571,110,372,876,730,616,228,19,45,254,614,316,159,301,559,436,217,281,350,868,839,377,229,569,387,141,730,8,29,616,340,43,645,483,848,676,732,171,680,755,184,290,69,873,447,67,256,102,853,212,707,378,228,2,328,966,754,183,566,402,610,33,898,908,575,10,789,601,316,535,165,365,62,425,913,100,456,297,462,582,117,770,268,56,109,494,558,915,105,6,56,746,795,702,993,68,905,870,28,754,246,379,853,122,935,92,809,797,267,153,286,578,740,496,446,204,630,8,378,125,335,627,864,302,901,601,963,527,332,283,312,478,447,906,721,623,446,740,675,230,0,675,143,52,949,918,186,981,801,711,136,198,564,639,728,72,238,293,563,588,463,817,380,402,39,434,632,541,699,396,231,728,616,312,93,290,962,80,864,935,85,418,697,85,951,339,793,272,296,719,646,411,412,659,675,890,355,208,932,733,584,733,432,950,257,669,543,522,412,349,367,170,264,322,942,982,437,738,543,780,289,107", "544,476,919,987,411,109,599,539,603,646,352,996,708,99,303,893,343,492,520,804,416,384,306,490,983,358,757,776,847,735,252,346,58,691,798,44,63,543,340,192,836,27,506,911,447,760,215,611,387,811,172,205,864,8,857,268,529,904,806,555,458,476,988,669,916,77,75,960,7,115,338,320,733,875,4,451,345,715,456,946,423,895,573,768,118,895,899,92,84,445,54,620,733,674,218,917,918,794,117,222,24,385,388,379,468,860,659,947,483,462,21,119,636,845,546,559,647,851,595,272,409,394,120,601,182,844,497,909,591,999,885,945,629,295,727,126,456,274,219,808,401,376,920,402,160,939,83,183,908,954,284,169,229,227,404,713,241,634,102,84,375,830,655,232,979,258,447,598,15,74,416,766,165,794,503,860,642,589,25,475,928,685,823,874,91,80,434,373,378,569,605,768,764,985,680,74,755,649,506,888,780,966,658,195,25,481,864,163,197,852,495,267,319,753,877,722,57,548,85,532,369,578,336,372,564,134,389,63,804,989,619,225,528,807,686,786,975,447,498,79,536,904,930,160,694,120,963,277,504,40,548,535,205,735,309,290,771,627,746,131,775,61,985,54,768,88,820,255,962,359,111,6,644,754,740,98,871,276,705,75,480,771,810,594,473,684,638,772,337,576,102,350,846,651,394,876,574,678,468,948,37,254,952,752,802,917,747,202,239,575,462,990,736,196,792,508,732,374,949,712,314,967,54,34,348,964,881,727,93,465,918,473,604,123,452,520,750,310,661,558,812,30,398,912,845,422,3,661,244,972,758,46,269,133,320,932,626,224,592,184,46,916,633,903,865,183,226,376,173,228,355,268,410,999,5,702,7,68,457,506,795,279,962,62,157,517,731,997,107,144,898,218,911,209,246,361,169,518,560,950,471,848,632,266,53,514,842,626,240,10,298,538,545,721,384,240,921,442,65,624,569,252,140,703,485,383,925,945,993,924,856,668,963,28,636,338,272,623,27,559,206,991,120,454,704,350,948,27,688,14,994,84,654,253,485,230,595,20,435,960,565,747,272,517,899,223,187,451,638,241,44,467,847,407,193,667,348,489,494,933,161,760,749,149,669,908,198,472,187,612,816,85,14,790,121,3,952,802,481,994,763,45,638,229,590,541,368,330,554,445,75,840,166,81,394,139,675,93,685,741,895,289,257,10,626,552,773,839,231,979,244,491,970,20,661,296,746,893,148,491,812,150,120,444,632,360,922,353,25,159,96,236,721,972,686,287,733,46,34,59,473,319,729,150,785,649,266,886,664,340,515,322,520,644,799,866,702,915,21,129,987,692,149,784,809,828,632,863,390,152,83,793,55,90,458,306,680,646,34,3,919,738,775,627,87,213,186,456,102,468,263,716,62,719,428,34,274,250,214,49,57,73,846,478,55,641,546,231,322,397,438,656,519,317,232,527,409,518,385,659,418,667,818,815,948,779,643,518,689,588,908,769,964,567,679,226,901,104,197,876,777,318,526,997,817,686,188,427,647,141,116,187,723,175,171,840,742,945,266,223,463,578,581,69,46,506,796,836,129,541,857,469,575,918,809,291,21,146,902,488,484,92,535,879,244,412,920,322,692,954,957,417,421,643,431,369,471,901,646,459,524,992,379,107,188,90,474,508,915,98,61,694,32,89,289,100,661,521,786,641,702,774,202,863,680,267,669,117,723,94,373,905,697,22,866,289,857,834,362,884,116,962,145,34,852,339,976,931,618,653,390,8,927,383,570,434,160,236,600,212,619,570,519,984,98,81,190,281,979,429,435,475,278,230,408,463,398,605,886,493,71,972,866,121,264,812,190,673,646,287,659,376,657,788,235,667,733,96,504,762,306,932,935,522,576,548,891,168,190,913,341,278,972,318,576,616,525,673,51,943,590,780,380,382,950,115,382,75,437,789,78,519,260,376,414,348,320,727,56,669,316,554,297,11,674,527,471,765,341,678,381,380,727,711,420,646,939,82,710,447,520,602,814,584,51,749,557,271,741,482,827,229,814,172,775,735,470,896,875,787,327,621,904,491,281,915,1000,458,400,89,519,405,317,201,238,15,418,142,675,0,152,560,747,718,939,589,380,140,491,317,265,686,520,655,346,319,861,442,774,647,751,509,640,256,319,156,31,348,814,324,411,728,403,272,288,62,125,36,66,338,556,994,753,369,94,991,551,652,133,854,875,621,368,204,82,166,121,726,979,899,895,174,416,737,874,114,663,714,404,388,161,280,38,811,421,834,584,269,241,35", "521,672,138,408,77,392,209,538,933,167,737,788,726,680,976,401,953,275,76,994,581,640,962,393,270,569,820,894,536,735,832,704,410,143,48,633,947,319,242,668,931,766,293,92,41,481,845,764,836,750,151,987,506,7,18,966,736,902,722,588,784,965,331,707,404,434,779,679,358,815,540,476,610,873,573,995,962,760,414,251,214,891,177,850,489,369,978,440,630,804,204,736,813,12,684,256,578,283,606,575,492,838,478,502,4,432,460,488,691,75,137,111,513,776,491,58,697,670,601,819,80,89,573,635,187,653,853,105,136,206,759,240,938,234,296,922,252,773,993,883,669,835,424,623,834,2,881,120,673,395,997,232,11,42,798,518,585,637,771,550,472,728,539,739,278,962,690,886,998,100,882,65,492,446,293,800,273,91,997,499,718,839,280,54,889,446,759,690,271,91,594,849,508,476,41,474,984,632,706,683,137,360,503,606,92,901,39,357,293,477,987,318,861,55,436,667,937,809,882,985,202,694,874,385,240,424,415,817,42,202,716,511,83,364,636,586,874,821,649,407,33,38,387,76,166,559,83,17,779,508,230,281,917,36,385,205,396,607,716,202,814,395,810,156,511,412,571,280,770,11,127,486,397,377,789,225,597,538,266,985,846,929,788,73,877,268,279,385,903,194,403,175,625,539,311,864,838,707,969,365,547,365,766,959,166,355,702,950,33,729,266,996,929,946,241,313,626,543,436,794,915,125,425,364,408,722,488,435,835,707,305,792,776,233,470,548,22,212,114,87,704,7,295,490,146,756,560,288,230,853,181,869,114,123,259,359,182,227,735,868,312,86,445,139,434,695,933,297,215,145,429,252,718,953,175,816,92,452,979,378,721,826,396,546,75,992,583,171,498,426,457,90,864,15,183,988,566,436,433,251,277,14,955,929,157,938,487,927,233,861,508,134,724,509,667,760,129,74,8,260,843,581,769,542,467,282,338,399,480,839,858,863,628,29,300,870,48,431,164,394,20,413,764,216,926,728,849,651,438,795,929,386,248,941,898,762,79,925,961,613,762,900,85,495,268,473,454,307,313,213,266,543,130,529,506,984,409,432,247,879,686,530,483,671,29,624,823,377,989,969,481,553,646,816,864,718,237,581,33,47,118,144,989,125,536,422,748,864,466,435,652,486,353,218,351,251,706,195,602,879,958,921,177,812,821,622,830,140,552,97,366,232,541,969,289,577,469,966,13,301,378,568,263,313,693,458,93,543,64,449,825,217,949,363,429,781,775,29,627,422,883,745,992,606,439,286,684,522,448,401,773,328,757,796,733,133,421,712,632,283,890,803,544,424,326,325,597,857,288,760,517,180,693,869,736,465,178,132,961,909,153,450,88,196,981,547,646,351,201,828,621,58,347,276,429,448,298,543,993,737,820,58,795,953,975,911,743,240,537,757,486,288,447,866,611,538,84,116,670,62,612,410,788,18,384,259,792,33,933,183,530,151,452,615,654,702,507,977,918,762,474,743,155,979,802,448,194,660,204,952,844,760,432,829,781,724,225,728,619,152,273,969,115,240,919,544,545,639,429,270,220,452,580,534,689,576,492,55,867,504,397,805,987,943,488,710,127,10,813,704,235,304,804,765,633,967,200,558,934,558,554,953,957,174,469,680,836,202,829,955,295,960,724,429,621,967,553,986,396,509,850,402,291,435,596,934,880,288,905,819,190,887,465,238,290,381,376,342,600,690,687,297,181,48,895,866,976,381,265,791,787,52,865,351,602,717,564,664,212,354,874,613,31,469,534,585,201,472,289,566,986,13,872,682,4,100,595,176,596,810,121,533,374,554,929,59,917,900,378,944,196,390,641,985,963,798,46,946,839,712,394,360,658,608,190,471,866,76,667,356,653,384,425,974,193,592,10,301,386,27,100,33,526,989,778,382,148,859,931,471,633,372,208,349,199,14,590,369,113,432,908,123,307,20,105,667,696,190,801,779,463,430,627,893,21,449,170,964,841,835,276,166,963,830,976,13,50,304,852,255,149,709,280,528,43,551,843,98,340,573,89,280,675,520,170,20,845,694,128,641,195,269,912,937,795,143,371,730,143,152,0,72,375,366,779,611,316,397,194,939,453,338,347,301,273,224,494,718,492,61,651,935,618,901,602,761,496,924,720,596,353,435,113,39,388,333,965,288,982,929,700,473,994,281,789,422,23,867,834,471,731,100,881,700,390,582,177,843,993,827,975,372,599,263,267,909,251,290,408,566,857,916,691,351,129,549,114,220,529,972", "254,902,965,739,961,569,545,76,296,626,160,301,74,773,578,187,880,799,963,642,285,329,181,837,103,742,592,255,337,302,809,640,930,228,304,380,550,602,856,126,64,529,60,225,345,863,974,928,656,791,541,614,538,385,853,938,751,712,977,311,859,745,338,632,851,233,917,171,905,205,464,512,49,302,991,625,764,393,51,250,662,283,398,399,399,823,17,785,803,630,738,478,654,176,877,827,587,680,44,912,516,5,392,881,953,372,56,695,36,570,652,130,525,732,392,674,81,649,892,638,572,914,842,210,602,426,387,674,950,740,995,695,157,586,95,381,145,899,341,244,244,157,5,514,651,719,263,284,220,761,863,151,508,869,525,775,940,899,868,682,605,573,826,202,558,161,647,367,318,538,426,760,73,565,657,704,597,974,451,786,971,288,348,965,117,354,45,32,234,910,339,716,775,687,437,867,290,36,384,350,53,643,719,875,989,858,546,534,317,170,87,431,126,142,222,236,791,392,619,623,895,129,809,460,331,787,678,19,539,22,789,418,249,181,37,306,999,702,890,770,19,393,797,504,827,357,115,225,300,841,287,469,303,892,733,180,894,635,898,438,564,862,771,867,706,995,485,364,636,734,919,193,306,899,762,385,341,311,489,602,933,90,307,96,825,316,12,260,983,575,524,91,977,719,574,964,640,663,529,97,880,487,262,865,326,718,367,861,250,640,584,686,166,705,248,455,235,368,660,114,214,421,668,495,886,516,917,757,310,606,467,356,872,542,357,614,491,415,975,27,375,945,221,811,385,889,465,570,355,383,887,114,918,620,570,289,101,32,28,623,800,113,705,587,247,470,7,246,546,343,571,514,299,614,338,419,750,281,278,871,571,841,937,946,566,492,753,740,224,589,407,4,189,346,702,288,108,688,816,463,913,286,467,895,929,921,936,9,396,531,879,594,961,972,6,672,599,171,884,989,711,901,754,124,606,550,705,275,316,473,596,770,87,269,870,250,326,220,844,825,907,669,375,690,798,998,900,7,484,812,843,764,356,249,122,327,623,656,148,205,592,634,381,30,716,247,70,208,417,549,753,621,500,745,59,800,747,217,457,738,256,149,903,68,448,748,790,842,495,688,407,92,800,5,760,32,206,634,160,864,84,936,775,117,409,693,473,362,730,223,26,473,287,995,312,523,977,283,204,952,93,352,258,595,160,482,523,108,667,922,111,22,287,862,330,634,949,724,717,137,881,786,84,855,218,36,709,794,813,20,204,459,680,378,648,327,825,522,250,189,252,616,513,885,979,397,694,982,386,207,691,916,770,143,253,94,687,789,587,664,746,703,611,119,404,739,678,435,394,742,75,596,773,341,873,803,882,257,830,903,54,811,292,816,366,190,287,255,526,656,457,154,730,246,818,783,389,574,10,595,146,384,381,616,319,550,568,16,672,457,671,839,504,149,584,570,897,491,81,391,760,376,230,525,923,314,330,94,923,657,284,97,926,405,427,208,463,369,22,821,177,67,634,595,497,914,450,344,103,347,200,773,962,173,97,4,24,295,995,147,394,400,986,918,67,129,144,888,21,846,646,366,261,667,208,659,888,568,913,411,772,871,873,593,168,929,840,464,138,426,174,23,968,57,231,141,951,406,109,30,844,140,312,119,365,257,587,706,218,325,816,387,505,580,933,529,270,306,381,968,715,517,352,723,809,269,753,779,92,452,945,699,74,855,682,471,377,916,25,546,503,85,417,814,17,983,209,226,231,843,261,919,853,975,959,660,47,177,668,795,610,604,408,235,370,105,52,804,997,160,688,615,905,329,648,196,107,43,24,613,276,691,45,33,438,980,184,988,363,764,442,168,409,486,976,600,900,687,924,419,450,659,169,333,498,74,962,616,366,745,560,199,227,397,295,154,403,477,607,867,408,169,254,378,886,723,190,563,341,676,852,446,120,296,519,391,872,159,969,977,453,811,572,653,378,266,736,134,172,647,626,292,875,504,390,440,806,926,396,348,964,901,991,573,534,764,339,412,275,868,202,880,727,991,946,568,602,334,824,166,128,410,538,980,14,911,372,382,572,399,98,341,638,356,945,100,473,943,52,560,72,0,784,584,350,115,818,670,97,592,344,734,201,445,110,493,872,470,826,850,945,780,48,883,44,441,261,302,245,29,700,246,910,694,588,93,488,221,171,103,515,195,565,49,353,278,332,180,142,941,310,240,574,858,863,509,59,234,143,240,761,564,563,176,600,68,704,532,13,767,611,951,467,659,62,808,559,588,657,560", "215,22,727,799,778,650,229,257,878,436,374,947,441,809,449,757,231,159,785,374,476,504,881,52,401,638,563,445,575,838,776,129,272,979,333,834,939,266,707,210,844,912,684,484,386,288,24,624,834,858,586,352,218,751,358,858,85,561,233,936,735,924,101,976,547,801,661,817,386,919,754,760,775,897,945,458,913,273,462,190,607,25,856,535,72,844,435,553,488,491,861,197,499,743,752,739,995,782,174,149,884,998,219,331,808,957,803,810,833,922,96,975,434,427,272,46,684,445,937,351,306,433,368,467,905,395,686,266,456,125,410,258,930,207,847,502,400,268,762,332,33,246,609,579,852,60,45,594,84,951,53,558,159,361,408,696,588,350,295,190,368,901,303,408,545,444,292,988,590,536,186,871,791,469,450,599,779,130,819,739,373,501,29,366,357,316,47,330,819,402,262,375,523,787,237,530,963,793,450,933,543,817,438,924,375,676,521,928,695,550,247,767,282,133,222,831,232,316,800,359,350,245,765,410,193,369,175,31,947,846,153,476,407,719,158,586,131,87,976,181,590,800,941,478,570,818,843,936,998,815,42,363,920,43,280,665,931,105,505,716,430,142,75,568,189,78,655,935,290,622,384,194,327,548,181,726,281,956,299,828,602,873,6,250,184,430,687,578,242,771,515,95,884,855,785,162,23,746,432,641,811,509,202,479,107,721,394,764,737,617,573,2,444,518,285,293,837,846,555,203,599,937,526,316,825,148,721,767,893,610,817,451,478,333,632,880,176,585,288,359,451,939,447,744,852,627,426,119,14,444,511,258,584,432,635,728,39,743,266,277,840,214,85,264,255,68,847,245,650,572,697,404,591,421,30,193,942,752,868,467,410,422,546,38,897,139,858,968,994,215,915,120,687,342,270,534,469,370,208,190,990,671,620,586,677,778,851,418,114,793,664,571,976,239,856,932,722,857,917,828,493,959,949,334,876,465,626,310,380,841,355,61,356,54,149,93,921,352,874,772,469,805,409,967,681,101,469,959,120,368,287,144,603,654,612,675,371,600,718,499,922,495,286,295,408,776,800,352,599,703,480,114,738,566,910,943,344,111,809,964,320,433,278,727,105,534,122,715,556,967,473,313,420,826,546,396,988,253,516,373,694,822,71,688,911,302,35,187,196,194,423,959,774,189,96,137,357,941,390,861,737,991,297,211,521,394,498,701,608,662,894,950,444,177,279,746,44,42,268,800,32,96,840,359,34,675,442,628,60,887,28,548,964,85,109,495,401,308,905,933,741,719,218,657,237,255,907,117,395,817,704,115,779,528,282,348,851,860,434,560,473,273,612,269,941,205,704,998,82,744,250,486,631,453,283,141,280,218,821,248,727,208,256,619,8,386,112,813,255,145,957,409,787,257,139,861,882,190,79,924,538,601,617,676,261,801,52,588,158,463,967,245,83,635,966,716,320,857,870,900,318,654,743,42,366,767,421,129,721,521,750,418,715,496,685,691,688,215,343,521,263,376,82,40,897,264,539,83,360,79,143,996,615,130,164,416,230,804,388,211,117,942,140,862,809,888,780,808,430,25,806,840,477,579,331,679,862,430,37,323,331,938,857,67,631,833,830,407,720,179,696,869,378,82,133,979,447,810,401,242,108,812,633,256,751,894,203,158,671,212,327,963,703,946,993,885,838,577,455,46,251,560,949,254,61,813,696,460,628,527,434,831,349,149,727,876,529,735,636,52,54,943,139,355,93,918,337,462,957,956,654,375,138,714,829,496,366,982,503,383,746,753,514,197,269,729,97,473,554,715,705,454,1,408,568,113,850,699,536,207,457,530,63,523,239,916,264,628,485,200,944,197,910,357,228,414,658,514,576,348,61,435,758,86,761,322,928,346,789,968,768,826,706,917,229,931,326,395,679,655,346,884,127,953,227,631,139,146,744,83,732,229,829,618,606,754,427,546,563,514,483,205,468,2,184,925,472,971,342,784,859,572,78,459,347,668,953,484,110,379,303,41,548,618,984,365,358,103,692,956,361,851,545,399,308,121,426,501,621,925,635,972,900,788,892,440,748,497,182,466,679,409,459,834,650,632,738,338,949,747,375,784,0,993,670,515,770,902,38,973,708,267,667,419,762,966,116,647,780,94,615,722,174,619,768,256,366,951,147,982,329,512,755,413,958,566,748,395,368,583,336,75,789,653,131,667,108,675,492,692,2,328,829,345,193,547,136,116,797,701,221,886,802,764,257,877,533,41,362,262,288,192,987,376,40,474,492,744,702,297", "559,352,270,175,84,117,847,554,683,213,154,6,833,901,136,294,600,678,740,593,714,75,851,307,740,112,534,887,803,618,632,968,59,972,103,395,551,312,569,737,90,139,21,452,100,260,591,285,112,531,641,484,724,855,809,592,234,22,157,253,924,982,658,311,205,290,657,534,296,975,907,563,719,746,418,920,352,839,852,441,175,35,241,419,30,992,68,888,503,722,466,972,53,413,946,397,316,189,676,837,450,71,250,708,699,124,531,950,450,53,540,604,810,235,570,774,790,151,624,898,621,235,679,282,915,614,629,635,920,366,907,698,34,494,803,686,747,26,288,270,986,515,71,490,849,355,847,281,259,477,485,886,609,229,518,730,691,538,135,503,939,891,656,678,454,491,964,532,226,109,846,328,235,625,201,611,852,308,73,208,532,564,499,979,298,196,332,358,399,54,722,47,599,369,188,213,541,847,855,925,269,865,992,750,23,593,647,445,626,214,636,500,569,240,269,576,750,300,289,993,347,15,263,14,667,134,680,558,87,821,785,496,484,520,347,911,142,457,615,338,845,758,381,677,777,495,569,739,123,255,559,99,888,433,287,144,432,960,934,573,898,328,345,738,467,574,492,449,381,718,656,356,992,264,112,184,35,580,537,504,394,744,395,986,866,434,573,187,203,750,690,78,101,84,342,291,633,366,154,590,369,382,62,323,545,236,909,381,121,260,548,421,208,824,359,329,742,414,532,430,686,12,516,181,648,290,869,55,244,58,604,793,62,838,439,667,310,284,358,643,273,336,345,971,452,254,41,148,350,220,626,796,572,398,423,698,124,487,504,667,952,258,348,905,967,432,717,371,535,121,828,185,793,8,824,232,87,75,75,706,556,508,450,993,544,910,888,658,232,630,243,318,386,204,100,126,719,96,355,717,348,38,926,948,330,765,661,346,449,45,744,647,960,118,896,118,768,611,7,310,27,389,668,235,572,519,669,40,482,738,845,812,122,601,894,836,425,350,311,881,419,701,405,277,452,58,78,840,216,734,949,40,846,824,264,200,98,797,980,810,246,398,759,652,931,424,704,154,184,367,210,773,335,54,372,254,125,17,307,604,177,860,54,547,854,383,80,552,716,544,403,319,397,913,895,909,710,866,46,826,309,596,505,121,677,629,606,191,297,402,759,555,868,266,348,809,112,146,819,291,346,163,42,273,733,210,640,423,445,318,423,264,976,587,482,231,593,286,724,899,713,46,337,792,655,900,772,845,752,74,486,734,325,602,388,107,702,313,293,879,845,471,218,139,287,792,679,232,634,630,598,7,912,461,910,542,172,471,275,132,633,388,745,230,324,399,340,575,419,315,317,553,986,907,124,511,533,69,963,869,63,50,491,239,289,909,769,776,885,202,373,229,319,63,351,746,122,779,21,555,463,931,236,931,408,772,210,578,582,617,58,125,291,89,764,286,408,123,625,599,454,484,555,916,673,996,897,344,400,75,471,574,281,310,801,905,757,728,788,268,980,445,756,100,13,729,951,563,199,479,104,661,798,215,982,851,816,233,674,214,152,874,386,401,758,511,181,562,621,839,436,113,327,166,590,597,715,423,272,322,882,309,122,831,920,792,886,161,919,401,281,636,889,446,852,889,54,640,496,937,165,974,691,815,462,841,364,896,257,658,635,952,156,654,397,95,890,27,203,800,941,152,784,154,525,155,244,708,321,917,388,614,559,480,530,729,91,130,58,508,459,943,958,960,23,181,521,497,529,938,324,205,296,759,245,951,304,546,950,81,659,652,124,189,278,125,311,417,395,619,300,579,379,646,63,966,866,500,38,603,945,371,205,698,145,125,35,670,489,658,401,475,28,158,219,548,574,255,473,996,295,734,220,515,43,861,656,94,63,651,143,500,825,346,600,393,346,14,938,820,287,35,225,744,605,17,467,774,495,511,927,364,527,154,241,140,833,324,828,502,715,754,94,542,377,346,41,39,395,430,921,138,281,296,979,355,478,418,563,254,988,186,373,489,69,357,648,845,468,178,712,532,338,557,920,127,929,690,628,348,736,800,451,625,560,521,968,542,522,594,413,499,551,856,674,259,799,501,918,718,366,584,993,0,602,543,713,255,864,370,936,393,811,677,64,771,496,996,920,597,705,945,185,430,554,493,552,924,917,456,990,134,526,511,615,942,165,850,853,846,819,359,274,176,859,606,980,473,256,397,573,39,679,474,218,811,851,535,763,766,513,638,884,201,998,726,362,726,746,768,224,279,722,652,551,67,399,797,832,130", "184,970,191,752,857,589,542,170,909,460,921,945,296,116,685,968,36,227,137,445,724,306,892,353,332,511,304,51,375,43,860,489,142,809,997,655,224,103,71,217,668,560,463,895,703,848,875,742,50,595,27,366,154,682,196,605,259,976,624,293,567,513,270,101,408,396,531,774,795,852,530,839,99,376,51,611,111,352,943,360,829,936,905,704,16,597,424,373,313,76,467,848,771,725,402,288,239,966,867,990,787,276,694,961,422,179,359,850,848,951,781,707,588,827,747,856,321,196,264,187,260,807,81,960,90,397,675,745,685,571,90,805,595,714,549,219,607,547,994,353,488,310,100,656,476,430,993,570,399,916,199,40,772,895,734,564,613,39,28,89,712,768,435,881,499,105,620,434,610,401,83,319,656,409,948,241,786,436,182,453,608,785,953,334,76,523,606,886,30,574,175,525,476,438,461,592,650,669,996,400,543,748,819,297,470,510,864,324,383,146,97,136,111,720,905,701,607,501,348,739,290,795,300,810,458,388,331,712,582,454,683,331,18,130,74,764,241,245,844,125,77,826,192,273,663,748,315,789,761,581,638,884,614,442,517,816,720,17,597,277,130,546,144,115,725,378,154,925,57,19,939,60,375,516,187,555,62,570,908,637,484,728,345,873,483,889,338,887,410,71,485,462,109,634,975,221,700,390,549,932,905,132,427,445,361,950,315,305,465,503,126,760,562,142,573,368,78,840,473,482,355,500,231,773,782,942,129,751,226,957,151,205,586,976,165,416,730,903,608,143,880,730,34,5,424,144,56,891,280,472,157,549,482,498,48,331,173,81,839,939,595,289,860,343,308,614,561,671,131,949,625,543,600,44,797,611,399,60,649,349,100,195,122,626,918,631,158,363,296,48,674,458,477,23,205,257,887,210,480,460,168,658,938,984,926,608,808,531,129,49,577,205,743,896,152,182,123,235,764,234,393,700,478,831,864,873,844,395,834,858,855,372,451,308,103,338,961,816,444,104,697,382,797,911,687,549,890,801,138,495,904,177,132,247,908,632,11,341,496,48,943,924,797,882,73,701,986,101,110,516,488,57,396,34,999,588,993,807,829,178,415,12,418,565,542,903,16,19,297,88,588,374,141,545,939,488,343,182,945,64,601,592,143,823,222,821,551,162,938,993,714,396,379,656,125,721,467,186,820,550,358,756,815,440,212,764,588,623,202,42,247,271,565,695,413,656,35,471,478,719,73,453,985,922,535,888,841,646,330,895,798,439,3,744,850,315,337,51,348,14,740,345,280,566,10,424,688,508,839,68,764,282,594,951,42,460,59,368,539,609,734,294,333,956,969,369,905,528,828,228,409,274,15,723,926,815,364,416,667,859,731,283,487,881,773,719,818,143,21,85,859,69,195,759,865,163,141,905,700,791,798,146,87,431,392,804,670,461,878,520,974,806,688,995,177,460,38,18,712,377,935,995,509,546,385,336,184,33,899,180,347,273,743,424,42,1000,61,658,63,282,329,854,959,613,257,967,854,23,143,594,628,348,400,95,239,955,6,291,486,435,891,378,26,178,876,398,635,818,729,225,979,543,76,113,33,673,731,506,198,63,7,726,514,209,902,930,227,443,707,508,553,708,905,188,970,661,738,774,584,646,616,852,359,133,998,784,386,60,742,392,666,206,128,819,651,881,629,766,333,610,469,666,751,273,747,185,893,406,197,464,678,737,801,946,8,272,651,801,386,628,579,167,137,43,502,256,733,339,93,464,57,398,164,479,331,593,682,515,852,485,110,983,316,894,773,46,330,1000,128,146,682,610,919,944,718,728,111,990,727,957,817,350,763,988,400,240,774,267,111,57,487,849,917,831,736,283,664,586,187,21,469,916,607,150,951,805,474,892,676,754,581,313,559,920,456,18,227,121,751,535,538,856,91,954,275,500,426,524,76,963,582,326,988,651,390,642,170,322,845,676,836,641,956,374,324,417,460,12,176,643,78,232,624,324,616,467,801,978,405,656,662,210,461,83,791,904,847,896,242,411,615,840,31,726,274,902,525,847,377,777,270,799,977,156,82,876,708,35,259,438,517,610,547,522,417,567,307,197,186,939,779,350,670,602,0,599,368,887,919,733,446,795,514,534,515,534,103,706,85,428,347,109,906,365,715,418,901,148,973,935,957,278,74,624,355,55,557,441,813,187,575,541,377,445,514,706,801,632,466,101,692,103,31,678,520,781,379,256,680,447,634,153,543,457,766,221,958,382,523,514,399,290,942,145,113,136,586,245,64,947", "805,140,780,288,877,546,484,815,928,34,531,40,69,93,148,252,528,626,249,470,721,69,923,110,17,979,416,819,944,619,822,998,909,818,263,90,440,294,46,211,406,603,598,244,603,850,381,740,937,813,432,935,774,113,598,209,605,238,597,352,415,900,327,882,326,194,531,156,746,210,561,841,824,418,975,836,135,960,695,784,319,9,297,280,101,610,75,16,596,871,803,66,259,665,968,437,815,731,982,251,437,656,846,146,83,100,54,496,928,231,213,169,218,39,664,391,15,815,719,357,158,944,538,611,706,114,859,189,499,763,891,335,454,624,736,8,926,404,380,866,182,672,362,304,436,319,811,420,233,4,172,296,692,82,663,714,332,969,845,461,884,971,183,311,85,5,491,598,471,874,966,597,87,94,219,747,780,906,974,383,384,381,928,494,691,503,52,917,124,241,781,846,18,125,485,941,429,479,345,201,702,35,279,872,178,888,496,986,194,298,40,962,352,105,141,607,751,747,985,696,321,701,910,881,592,4,984,601,370,714,761,675,539,897,12,452,356,447,234,152,575,134,892,421,852,449,296,725,586,308,631,235,161,796,455,235,742,715,712,228,375,952,390,847,253,733,644,847,656,565,834,579,650,468,640,963,110,120,6,243,34,590,340,2,393,808,916,668,971,693,270,349,304,136,702,890,140,619,784,417,802,584,858,752,208,540,112,70,707,181,161,343,653,953,113,339,999,86,600,223,578,14,127,300,229,969,808,31,696,473,205,675,825,956,885,469,488,22,33,600,332,4,492,934,10,768,288,607,587,806,346,601,609,631,116,149,48,982,941,522,759,26,819,34,564,973,788,60,584,50,151,660,873,610,145,781,40,82,315,464,957,526,202,559,135,809,982,389,924,441,289,953,158,836,327,690,175,571,569,609,539,709,885,538,881,799,83,402,145,393,965,722,429,744,605,535,239,429,290,229,858,716,134,1000,51,460,626,854,773,149,437,409,565,225,409,67,50,934,667,529,761,70,107,284,622,527,380,122,501,619,257,248,925,264,728,132,645,281,946,191,412,764,303,899,36,929,744,26,947,166,217,101,299,147,411,265,583,469,265,230,646,479,506,94,287,289,845,549,907,71,889,769,774,9,68,429,884,125,287,345,585,205,292,33,68,68,909,693,896,956,230,428,819,811,83,519,504,313,66,156,925,921,332,16,565,238,685,652,592,77,204,348,864,702,782,474,675,879,374,451,125,184,591,949,826,497,122,152,340,89,827,771,388,535,204,74,730,642,268,567,720,831,884,931,662,841,107,509,800,970,728,153,371,296,726,271,904,413,732,208,207,853,145,991,441,143,783,779,898,269,778,193,343,195,825,861,340,906,569,292,290,255,438,863,728,421,474,774,912,857,57,981,465,856,941,338,586,754,114,492,909,402,604,829,694,279,543,705,506,444,241,575,81,687,34,146,168,697,313,966,316,415,20,137,975,816,210,531,377,874,629,933,663,5,371,175,402,372,569,435,15,747,738,427,607,178,344,101,341,731,565,879,538,459,258,210,252,747,702,701,911,917,225,426,198,753,407,334,29,36,128,470,463,172,393,69,710,542,748,7,93,406,110,57,53,99,908,870,766,860,81,320,964,19,141,165,301,297,587,270,896,638,229,106,793,849,157,726,395,834,389,410,756,560,754,805,18,636,899,90,651,519,748,230,810,487,423,605,720,38,732,680,983,109,956,98,322,544,909,487,35,748,936,432,687,793,890,539,244,548,240,166,851,124,526,693,816,920,215,209,799,145,573,445,271,402,822,873,506,823,67,254,955,114,764,286,305,446,384,151,572,555,374,903,727,909,348,251,137,382,800,654,494,340,500,830,668,299,535,843,476,413,146,492,3,91,666,522,957,98,328,50,632,765,595,427,187,701,658,642,329,457,164,663,225,582,330,770,959,37,957,223,74,997,665,890,41,309,118,94,605,254,674,415,154,873,845,576,239,198,697,645,835,552,677,455,641,459,235,144,717,920,674,871,274,275,494,145,101,475,531,588,637,908,596,85,58,990,10,936,820,76,294,804,521,742,377,895,606,7,50,696,27,718,914,742,790,225,981,589,611,115,515,543,599,0,274,560,252,622,217,169,975,471,589,816,970,581,876,138,798,759,202,673,422,242,149,881,835,521,862,654,14,117,614,706,141,266,134,864,54,807,112,41,691,980,621,61,956,203,445,267,513,472,384,227,252,309,923,961,944,508,331,283,486,478,200,284,924,355,378,780,796,372,491,532,669,629,774,814", "737,513,59,861,378,981,350,886,555,753,412,611,896,356,789,581,284,255,484,920,543,466,662,187,707,819,810,129,722,562,995,757,247,657,508,854,209,759,396,544,779,663,217,689,376,384,445,917,516,677,587,551,497,78,508,380,858,963,958,928,786,493,596,825,819,422,742,761,103,708,488,653,991,790,757,45,497,610,750,205,919,442,157,598,85,951,152,483,977,808,419,211,443,565,853,165,96,725,149,486,979,403,407,82,109,94,143,565,415,93,41,957,139,270,122,669,608,752,434,393,111,789,290,79,280,319,236,555,637,252,947,734,897,656,144,12,520,964,369,874,581,592,877,751,193,877,98,118,488,145,982,887,123,227,590,974,704,375,231,920,152,5,287,472,625,422,476,718,405,950,150,21,537,749,218,176,63,427,51,259,88,475,757,887,175,150,569,608,36,666,595,997,397,713,238,130,210,614,52,282,946,768,915,386,437,520,988,639,57,251,432,924,311,437,944,982,446,893,758,627,12,630,89,828,605,37,828,347,509,524,829,803,353,578,493,496,561,707,715,842,882,405,91,297,278,412,418,392,408,611,556,85,833,787,388,631,295,96,78,42,864,973,970,87,362,531,372,729,712,830,43,141,497,762,486,628,270,187,512,337,696,818,490,653,404,869,28,423,107,57,916,844,491,842,880,539,691,71,153,790,461,483,853,390,592,563,266,602,158,888,341,740,435,44,514,664,366,484,995,292,382,361,142,117,561,901,482,727,985,952,136,239,151,55,544,499,327,38,29,957,190,728,573,530,867,890,359,532,730,252,57,946,649,388,419,773,901,400,323,958,416,500,571,235,529,631,131,850,168,875,203,779,926,403,464,437,701,512,783,385,9,159,51,289,698,970,859,434,480,196,293,236,187,9,439,160,669,725,569,328,502,732,840,967,291,385,899,71,670,684,303,602,470,874,337,238,585,530,801,465,857,889,219,542,549,373,271,551,865,623,316,822,716,300,429,242,993,206,24,160,573,901,736,813,654,364,857,142,531,482,325,178,7,651,922,984,251,43,852,235,829,25,180,580,175,960,3,101,23,106,145,970,924,882,301,153,206,876,562,976,979,266,773,417,768,67,960,192,397,538,212,195,682,691,100,227,443,236,726,552,286,234,406,366,192,858,90,773,377,69,470,933,172,783,303,66,903,727,286,461,375,26,795,381,723,702,362,889,421,284,931,206,259,849,1000,683,516,945,187,89,317,813,20,381,835,802,777,556,388,218,399,394,3,877,230,192,312,441,407,959,977,521,117,637,289,320,228,683,660,10,960,257,584,930,604,741,2,738,707,635,495,888,694,498,389,639,335,131,373,398,788,534,437,836,135,59,848,501,602,821,134,454,725,758,829,859,551,281,956,282,270,476,452,206,634,134,427,177,945,671,430,140,331,81,905,919,106,335,860,625,150,671,39,675,985,208,351,557,378,612,44,492,707,574,314,345,611,140,657,90,440,647,752,433,596,338,25,788,5,36,838,962,640,798,979,978,354,75,736,831,340,569,297,73,166,286,171,895,733,198,162,7,247,250,664,84,505,832,212,881,738,396,568,657,623,58,86,719,112,178,371,107,100,384,198,671,583,843,892,203,475,434,113,327,37,873,225,489,874,59,715,462,272,899,937,870,694,35,388,457,827,209,675,994,459,653,307,769,104,26,661,513,86,622,966,511,182,262,879,67,597,237,148,783,108,681,3,256,768,838,789,950,383,824,819,269,817,682,968,358,392,411,558,309,782,112,397,340,575,841,607,748,45,982,236,944,66,569,78,222,249,95,200,797,951,881,21,579,565,932,505,705,325,821,210,232,471,283,594,173,675,475,412,708,795,718,149,631,232,834,818,307,253,929,887,165,634,80,562,813,339,38,630,792,976,148,265,663,177,257,688,76,869,424,847,789,896,802,43,397,986,348,570,20,914,404,794,589,581,976,13,643,153,55,774,228,24,83,520,170,66,990,858,949,121,706,339,704,502,483,314,804,20,187,87,795,660,597,825,628,192,477,416,317,578,685,839,936,992,590,232,114,564,264,255,359,1000,570,267,166,566,221,694,90,82,664,947,891,801,380,316,818,770,713,368,274,0,585,919,300,952,687,262,714,572,752,119,713,801,4,581,349,453,213,580,959,682,351,865,846,347,957,253,96,918,974,833,92,22,567,121,37,328,27,751,387,603,926,846,67,827,570,932,281,814,172,354,845,161,357,637,197,830,897,357,260,709,320,194,769,826,161,625,915,843,997,950,44,897,724", "774,198,213,39,987,572,678,334,662,14,878,907,595,155,974,759,785,159,89,356,342,719,956,617,675,569,471,476,101,961,173,573,527,471,134,307,44,721,556,382,7,380,782,370,121,303,508,630,30,718,178,872,736,967,972,82,410,745,20,111,779,424,375,117,490,459,593,131,664,967,119,356,835,800,572,8,770,314,968,89,161,713,197,840,572,631,199,847,54,509,402,923,969,760,36,194,174,755,602,167,531,248,43,708,922,310,29,364,949,727,65,969,340,578,66,467,444,913,441,534,549,382,737,161,614,633,252,259,562,582,349,500,746,32,877,907,621,458,541,902,482,791,180,710,836,705,599,67,833,535,411,733,35,988,488,493,559,519,972,546,799,927,273,13,90,142,116,920,632,946,70,43,644,112,64,67,544,392,451,730,181,199,719,932,304,44,461,725,145,547,113,429,697,218,861,924,897,3,451,731,584,749,395,707,536,10,988,329,366,837,391,663,258,645,105,611,762,35,956,646,127,860,236,555,232,922,671,261,908,275,940,940,532,700,904,769,822,126,115,992,989,591,541,201,66,49,619,710,859,332,168,639,854,544,50,479,635,960,413,370,262,272,138,168,794,707,118,666,892,845,386,252,637,409,646,690,434,589,395,551,872,616,976,224,518,126,973,175,833,965,468,185,908,671,16,318,387,267,546,485,944,825,395,329,472,766,352,481,725,868,344,907,862,9,174,966,235,657,562,55,802,555,105,869,722,748,975,234,761,187,659,42,832,236,637,178,636,754,805,859,280,800,422,652,356,780,605,157,233,861,326,137,67,192,955,828,167,466,174,787,698,677,611,180,200,158,790,663,165,256,460,584,652,137,851,197,301,644,857,62,404,971,677,183,941,861,683,104,125,515,158,709,163,215,764,556,108,172,70,14,615,972,117,759,394,668,100,192,390,220,5,804,529,313,148,996,283,457,638,791,575,621,425,95,35,732,825,306,209,502,599,588,819,36,613,112,802,205,586,13,173,789,308,801,34,903,423,617,802,846,890,816,8,226,965,781,778,578,480,561,986,144,217,233,819,731,347,346,669,117,915,337,62,920,600,254,601,38,828,133,842,810,695,789,180,211,613,241,527,755,720,778,291,446,190,567,439,423,987,863,200,424,769,317,140,540,453,912,929,547,142,64,34,861,807,741,370,973,535,397,786,246,905,135,350,29,321,328,135,459,986,966,44,671,471,196,778,99,284,240,344,494,519,822,792,70,582,607,896,401,235,191,21,302,448,473,42,720,965,987,128,124,958,201,477,531,395,732,819,587,388,991,819,619,982,105,258,783,613,621,412,909,320,86,781,229,759,62,591,421,566,260,847,549,731,361,629,789,103,852,851,398,999,516,940,635,108,35,286,8,241,707,369,160,417,991,149,707,29,681,328,85,27,193,196,392,120,82,311,581,218,795,318,793,417,184,693,665,248,627,425,10,318,499,988,314,669,792,915,920,139,813,825,105,333,336,533,373,854,501,914,944,714,953,25,656,795,111,87,293,324,635,781,732,165,212,515,823,150,293,899,473,820,685,956,987,881,618,752,132,638,174,77,238,935,196,669,463,90,417,162,366,556,655,12,425,231,607,957,840,23,380,613,548,586,628,696,812,992,837,865,684,812,532,638,294,754,232,92,421,416,835,288,153,41,466,597,470,884,978,776,818,323,689,78,801,72,472,609,994,930,10,337,412,581,983,430,521,887,428,266,70,781,188,416,226,421,131,46,122,358,686,603,747,621,171,497,930,769,963,635,938,138,762,646,812,843,846,12,658,269,923,543,762,577,493,374,276,919,902,322,861,359,541,83,116,298,428,23,92,719,568,760,821,901,571,570,87,736,862,324,561,348,19,85,921,335,942,673,831,155,668,123,515,746,658,665,970,272,931,293,218,603,667,968,36,563,269,194,952,48,57,336,674,869,971,703,232,469,761,918,678,244,752,554,973,594,266,686,733,391,307,746,793,975,569,554,104,781,342,557,969,71,895,968,830,311,392,386,903,759,466,822,327,97,627,29,953,243,963,641,271,760,129,304,609,280,594,6,385,320,448,945,677,349,702,118,353,711,140,397,670,902,255,887,560,585,0,824,596,585,443,140,114,37,705,131,272,29,945,649,809,824,962,980,177,519,933,919,400,559,934,130,224,780,9,279,786,834,697,763,492,49,783,626,153,371,845,442,647,262,875,871,673,905,285,970,626,574,339,725,283,254,903,541,381,500,859,529,632,911,351,940,152,774,61,118,616,766,519", "661,595,694,40,612,213,98,878,809,142,387,214,33,936,534,997,581,979,91,843,15,323,725,668,569,869,547,890,228,578,817,673,78,780,309,94,853,936,251,568,892,568,640,817,657,219,617,970,186,389,670,127,570,225,376,228,591,912,775,343,985,967,747,906,590,411,347,524,102,858,901,570,191,645,617,485,716,752,59,167,688,632,951,897,929,756,584,88,509,728,361,578,638,80,838,598,852,929,200,135,957,91,67,275,14,499,119,893,775,161,370,374,565,982,817,619,733,311,745,948,400,442,446,391,274,903,509,151,962,192,516,619,563,442,996,410,497,850,702,317,918,623,187,169,572,256,38,608,178,168,98,182,877,68,2,10,592,424,862,665,464,865,115,35,542,138,202,505,258,425,817,816,837,183,704,152,876,376,319,445,803,452,630,33,882,747,646,417,854,212,884,376,318,248,558,519,255,431,742,47,238,355,956,815,561,957,727,480,437,98,387,896,682,834,141,785,6,66,538,643,422,839,160,587,468,219,516,83,789,682,832,658,376,388,850,704,821,971,385,483,893,585,300,410,209,516,552,759,184,490,729,332,68,906,617,708,475,397,307,907,264,557,450,569,968,89,604,928,623,508,564,371,127,270,150,163,310,781,430,555,26,935,545,727,561,689,201,110,398,281,544,660,613,575,171,916,246,254,537,756,773,253,148,855,630,645,287,442,58,777,853,563,807,276,653,102,38,234,761,859,396,162,8,473,56,123,365,982,580,45,131,908,702,766,617,275,739,483,979,452,326,468,99,553,579,734,328,234,458,520,103,800,265,547,146,92,222,113,328,812,999,86,707,407,241,660,773,665,587,121,941,99,623,359,598,645,850,728,775,606,666,704,296,78,799,478,768,746,326,546,223,521,960,830,490,165,491,651,115,577,178,449,712,340,438,971,752,103,526,492,538,362,164,37,746,450,898,527,974,605,533,625,469,81,366,241,939,78,664,728,274,657,848,726,259,980,3,370,236,133,566,12,369,10,925,993,34,32,886,764,401,387,795,966,114,931,747,862,392,59,760,661,94,905,475,113,387,509,423,333,799,251,990,139,892,117,520,458,181,996,546,971,415,366,399,725,87,150,737,559,361,783,484,569,213,59,558,781,258,312,871,298,823,998,645,213,14,851,665,566,820,675,551,442,738,7,493,665,331,54,655,658,102,99,855,657,758,234,324,72,847,108,726,303,920,279,85,706,739,164,26,582,727,651,570,81,803,137,947,467,487,451,767,338,149,430,937,54,915,492,13,520,472,645,914,81,923,674,623,148,855,401,531,502,176,986,278,221,525,706,583,352,915,116,861,405,14,609,617,386,548,203,733,293,402,664,310,517,885,307,474,374,684,102,863,52,867,524,81,434,769,236,721,714,496,608,192,812,745,352,707,353,681,725,244,826,321,842,984,91,475,105,621,467,798,330,497,358,245,17,263,430,168,766,308,901,767,381,490,587,730,494,54,593,71,450,977,276,181,636,314,665,362,630,676,666,329,511,636,544,745,716,582,798,993,448,881,63,61,432,890,701,324,82,686,871,992,821,435,675,521,967,315,976,691,511,138,945,264,93,50,474,378,294,282,676,574,897,657,27,657,764,47,668,123,952,820,98,686,800,166,679,10,489,307,801,563,621,710,350,17,432,707,630,608,248,433,291,246,347,926,832,218,150,709,994,630,106,276,553,195,941,780,430,92,320,728,337,240,651,62,735,609,392,270,616,619,836,512,226,780,567,661,97,888,105,319,152,796,500,194,833,700,694,55,10,553,354,388,779,990,40,167,170,879,550,141,300,26,49,735,208,521,854,79,838,573,318,410,44,434,199,744,702,577,343,464,858,571,296,855,658,230,331,312,347,168,728,196,813,280,593,826,926,903,900,550,208,889,501,686,595,496,466,64,976,677,939,420,648,805,298,49,14,487,722,13,515,570,679,52,516,762,340,386,922,409,245,411,756,588,721,527,699,966,677,519,789,502,734,913,719,739,949,386,670,213,874,825,986,126,334,788,654,432,418,479,253,835,198,805,651,300,183,827,748,151,145,358,854,979,114,512,811,526,33,260,192,136,491,194,97,38,864,919,252,919,824,0,288,97,717,36,613,471,928,281,880,158,342,822,446,140,758,281,953,934,773,978,404,762,443,717,757,429,460,45,461,51,151,138,979,441,688,400,439,282,981,100,695,168,871,630,884,675,36,195,325,102,106,268,759,962,423,200,20,996,871,644,297,481,815,211,631,988,86,33,580,571,243", "784,85,381,346,313,572,302,421,410,362,444,218,880,168,697,495,481,364,170,110,430,401,849,570,589,719,572,540,161,225,952,339,151,137,853,758,96,940,619,409,828,23,138,260,701,337,632,14,965,273,348,307,834,51,116,146,829,961,331,887,406,194,220,271,363,425,365,787,92,119,363,616,807,21,295,465,843,997,194,240,537,152,916,291,583,242,19,628,596,670,902,754,575,209,579,310,584,482,276,301,894,257,587,700,847,572,125,30,106,509,623,86,581,408,913,556,694,388,937,64,467,969,100,608,41,721,164,389,836,521,562,812,433,79,424,161,550,805,805,997,335,331,444,462,966,858,372,515,761,7,833,600,714,37,760,299,713,726,330,895,26,149,630,129,853,683,913,930,701,913,537,896,744,956,639,211,579,509,959,699,828,437,300,686,257,824,415,122,527,504,312,781,831,541,844,893,421,889,146,588,131,227,244,599,609,943,891,883,503,524,648,501,739,268,60,734,987,850,869,516,393,620,584,249,837,252,242,865,947,393,572,773,394,773,314,476,46,172,439,708,114,559,5,523,275,847,724,960,376,689,741,355,608,145,526,743,558,119,206,261,944,562,950,500,361,662,818,518,59,597,260,160,855,483,203,641,808,310,589,579,804,356,762,437,794,137,381,697,942,175,746,968,652,307,232,597,768,93,776,681,9,822,542,290,449,672,138,150,891,15,946,510,620,442,83,869,197,69,813,763,516,208,380,811,790,397,646,587,987,323,589,951,561,459,69,517,989,84,535,919,265,409,737,875,593,564,243,902,573,77,482,478,685,157,896,24,230,408,480,604,832,471,877,336,927,329,83,808,643,393,112,41,730,600,957,221,1000,698,7,512,105,621,638,658,652,6,308,604,172,35,297,115,47,922,505,441,963,989,674,717,126,396,737,562,42,396,221,924,985,164,149,677,825,76,352,531,80,147,767,90,674,444,517,468,311,343,377,199,332,209,471,121,756,251,994,394,675,977,168,514,97,31,199,55,647,163,337,228,517,47,30,673,404,388,643,708,635,124,547,759,599,309,907,151,917,968,945,1,152,343,958,784,15,485,99,174,156,480,412,849,20,185,610,886,53,116,397,859,783,738,789,810,993,55,511,485,726,284,442,848,186,889,700,183,3,127,992,681,500,304,430,936,845,285,646,127,677,923,474,734,558,219,239,388,446,109,569,575,876,3,690,625,750,193,486,429,718,693,364,773,192,140,695,596,919,934,427,966,934,484,873,389,686,953,139,309,458,333,382,424,295,811,775,384,251,7,365,838,440,908,563,903,628,424,793,960,694,433,154,182,257,772,366,804,368,623,900,570,598,980,738,968,695,112,481,182,123,948,36,481,82,520,411,846,35,273,29,638,262,744,262,982,992,975,833,909,24,792,909,423,950,779,465,806,136,503,839,236,970,257,2,915,196,713,202,14,252,506,985,26,564,718,628,680,540,869,45,362,104,693,763,513,817,11,65,611,682,451,800,200,605,242,384,890,718,273,983,634,211,149,72,452,653,900,31,350,62,675,572,212,863,200,645,237,633,482,119,291,505,545,607,907,287,251,967,447,723,893,272,943,445,844,245,488,764,146,741,183,542,806,219,566,840,165,224,188,757,663,520,697,104,398,808,564,140,442,446,573,94,900,938,227,861,23,103,503,255,538,838,346,445,931,187,820,817,500,982,480,82,976,449,446,701,373,768,623,907,229,656,417,939,216,523,428,565,151,715,396,75,785,641,567,176,889,399,688,971,463,268,569,734,787,730,472,637,416,963,457,489,10,168,641,988,447,824,4,316,570,500,824,520,92,739,203,717,223,513,647,723,590,491,503,186,565,914,222,834,403,886,775,997,588,552,432,823,211,187,359,917,142,480,924,204,764,58,501,984,153,91,382,302,106,644,397,874,655,462,162,210,388,761,115,945,800,504,370,704,358,175,819,682,88,702,382,781,828,806,136,480,594,836,648,353,254,960,367,798,10,952,519,742,877,864,893,870,249,415,513,475,908,809,200,495,742,454,54,294,408,223,875,491,922,25,371,809,343,895,395,479,43,501,119,199,51,464,321,77,617,198,317,939,592,973,370,733,622,300,596,288,0,854,540,631,523,48,637,940,427,183,446,156,261,526,3,763,723,275,270,383,57,843,248,241,650,599,854,523,891,504,219,537,229,713,939,351,123,303,469,915,330,609,433,940,487,18,295,892,498,283,902,223,565,573,561,699,747,427,839,827,675,936,962,282,300,605,613,874,485,298,246", "206,601,534,963,8,239,503,543,121,412,129,853,3,191,963,21,783,280,299,647,254,657,521,69,501,344,932,732,746,948,519,137,766,805,134,246,243,495,544,502,103,589,295,175,383,58,217,863,893,272,729,342,364,923,745,902,700,978,43,250,966,881,434,365,263,939,660,239,635,975,423,691,937,430,824,93,19,115,376,205,41,62,778,566,32,523,682,177,977,441,300,322,878,583,83,917,688,41,799,105,794,503,860,561,216,131,171,353,60,357,847,437,421,669,51,597,549,225,56,319,127,933,80,708,617,313,9,965,142,935,598,449,4,419,323,397,696,129,206,792,817,400,828,427,848,130,922,372,375,324,402,715,900,73,607,563,521,66,958,332,514,948,469,968,141,925,184,168,916,164,651,267,167,121,426,847,610,691,768,129,776,173,794,310,677,143,971,337,271,412,968,513,598,909,233,746,169,678,529,241,661,133,305,843,193,560,138,320,257,41,332,626,647,697,678,187,430,429,359,251,663,268,658,725,506,988,199,213,743,230,912,929,888,498,906,815,604,177,159,578,885,687,249,67,805,208,771,709,868,304,720,301,785,559,879,201,22,868,600,90,991,119,358,864,357,409,540,738,523,583,891,198,154,350,354,273,185,445,754,403,96,262,556,746,256,18,159,88,362,754,245,744,267,798,511,320,237,880,100,290,541,594,713,327,979,716,46,314,50,458,265,431,782,861,776,233,208,195,289,984,132,735,392,398,845,863,562,762,75,604,3,638,288,648,316,573,18,838,711,968,157,432,630,229,550,517,829,610,42,157,961,432,255,652,988,1,560,45,665,562,730,94,126,746,486,731,827,685,90,688,461,748,989,15,335,341,882,380,663,526,421,772,600,470,602,357,595,30,206,425,799,417,162,991,72,136,893,23,435,150,75,955,138,352,124,859,195,505,695,217,406,612,43,485,311,51,758,399,751,406,548,502,495,151,388,38,489,952,328,422,156,856,763,94,306,663,530,533,896,725,177,894,884,996,334,304,689,718,746,93,327,463,895,44,318,616,627,815,739,780,606,505,669,665,27,987,171,751,311,872,884,792,283,365,636,515,120,347,609,393,164,243,633,278,30,61,282,213,845,621,917,608,721,331,549,42,174,212,827,770,57,578,260,684,690,568,989,137,350,398,89,228,266,627,617,562,369,121,386,57,882,823,911,612,884,131,697,595,999,701,669,361,858,568,629,440,268,233,662,710,743,754,461,441,109,920,565,928,930,777,985,163,466,124,339,681,318,923,965,135,394,636,180,449,854,98,109,146,992,289,656,461,877,531,904,685,795,937,350,537,372,667,85,139,505,263,750,616,495,945,165,573,908,910,881,957,458,723,460,36,896,233,176,507,245,957,120,683,376,270,348,61,772,504,955,634,582,471,235,897,814,265,265,375,915,944,251,267,759,776,840,31,747,871,800,770,291,74,693,436,442,187,586,373,104,817,25,45,498,789,473,398,735,677,69,260,446,256,571,104,511,635,753,855,87,395,280,902,688,482,705,431,290,868,861,348,637,505,536,377,123,560,277,605,820,93,637,511,791,926,911,396,147,693,615,540,767,152,600,810,939,985,625,424,757,55,751,407,384,425,270,81,284,332,749,906,221,904,615,766,935,636,857,796,907,77,67,660,178,780,510,495,321,398,754,302,707,573,831,962,814,4,585,250,694,751,42,255,396,416,387,307,216,510,941,861,929,712,357,542,673,742,138,439,529,886,157,181,971,293,86,588,824,341,363,790,342,217,662,206,627,715,102,860,397,163,196,364,616,589,498,207,44,929,751,774,714,632,118,642,654,866,117,49,78,293,109,763,458,167,542,234,820,857,400,753,479,571,299,96,166,558,508,969,418,287,146,494,681,75,679,850,654,47,993,825,414,72,9,960,571,6,69,76,156,43,818,630,575,303,708,339,612,238,293,362,181,180,703,438,447,618,117,5,509,944,806,59,28,590,618,358,416,150,187,585,42,693,951,45,21,74,60,139,598,991,93,969,473,906,696,491,734,668,115,193,316,657,672,619,475,771,388,221,840,752,152,791,742,609,586,284,696,870,288,74,596,892,564,265,453,344,708,936,446,217,952,585,97,854,0,547,487,861,868,444,105,243,803,651,563,427,245,956,574,906,95,553,28,778,563,737,700,211,361,433,801,367,484,992,39,51,537,519,605,585,144,17,960,149,735,996,740,447,314,853,130,539,196,816,743,200,999,937,484,380,202,625,691,394,436,357,393,799,922,675,807,550,479,422", "345,341,970,861,855,522,792,234,478,882,307,895,625,450,782,887,68,378,174,753,232,386,449,977,854,531,837,357,235,743,352,110,337,418,569,17,58,214,251,162,529,470,387,183,165,895,801,932,699,288,829,301,800,911,477,722,611,643,276,814,17,293,758,65,831,850,79,630,86,183,345,653,397,490,717,454,903,334,760,174,885,513,437,66,437,562,527,259,426,274,48,776,5,236,410,328,415,171,910,782,887,695,156,796,838,837,758,367,927,801,370,438,349,751,754,757,33,888,884,677,672,859,184,721,232,295,389,126,870,929,90,592,836,325,169,485,833,344,591,653,615,665,342,817,507,703,109,361,260,880,986,753,751,196,227,796,240,257,288,735,965,700,680,532,709,295,1,897,926,698,68,356,319,126,292,416,738,986,25,143,447,382,238,291,217,782,329,476,486,836,264,553,439,156,845,473,531,769,253,909,313,85,749,144,502,589,112,292,791,916,707,880,136,740,220,111,336,881,707,229,320,691,519,205,420,977,702,346,562,218,835,239,49,76,999,794,956,659,856,626,775,326,464,93,200,104,821,516,86,6,155,209,888,943,626,533,420,505,173,662,423,40,306,120,698,673,611,82,332,160,162,650,694,873,168,804,513,835,237,432,721,20,240,22,164,830,53,909,984,202,352,914,777,983,753,446,917,894,852,153,435,635,401,447,754,778,756,393,786,996,597,835,792,65,125,558,310,441,836,963,834,198,185,163,763,770,875,371,943,120,873,275,44,346,749,784,855,537,86,9,274,682,161,959,614,714,771,23,278,898,974,52,393,32,495,206,581,962,704,263,182,649,112,919,824,400,224,733,232,855,389,15,311,183,672,168,713,996,383,378,842,454,338,360,279,442,484,290,935,749,906,95,226,756,332,576,889,151,157,800,89,215,960,659,121,356,148,330,3,106,552,472,764,875,204,81,390,291,763,675,156,699,105,291,515,494,527,237,735,908,190,977,688,924,358,947,751,49,573,123,683,110,477,251,278,185,274,938,424,348,414,803,903,252,695,964,327,435,191,124,909,491,350,205,186,809,226,902,371,643,310,181,689,447,194,459,45,686,939,535,948,950,887,467,414,435,11,832,590,735,438,6,91,433,4,627,897,463,982,736,973,838,601,891,936,77,450,787,789,946,553,234,664,539,396,409,458,93,728,229,528,263,391,83,361,265,512,487,590,776,450,669,163,58,364,54,298,849,793,143,227,417,749,640,861,180,676,711,867,898,875,849,806,443,940,727,434,391,377,148,572,225,987,702,253,492,850,236,73,465,411,745,94,850,546,213,226,671,151,15,751,719,392,640,431,391,762,59,789,161,108,537,946,48,903,473,409,140,197,405,453,660,874,136,906,282,787,676,809,944,787,885,974,399,575,605,802,976,731,653,484,974,445,425,530,260,336,230,323,292,181,929,651,634,679,223,220,119,103,694,340,276,423,655,157,565,663,639,811,258,207,999,782,16,915,120,305,785,769,336,996,162,266,544,568,751,535,758,938,658,173,963,255,328,301,781,657,923,433,177,916,287,729,232,72,130,136,647,696,439,381,409,640,247,394,466,944,883,39,439,114,73,430,610,712,628,472,714,284,234,56,657,977,292,166,942,151,692,90,871,586,135,886,810,315,229,94,817,773,261,786,801,774,543,670,942,621,548,556,457,836,72,223,349,98,155,440,626,609,134,217,817,462,105,184,252,779,154,563,319,71,739,269,115,319,71,488,185,898,416,268,653,67,884,50,917,314,546,733,440,839,50,460,304,82,947,494,909,64,458,437,983,518,839,13,15,21,512,762,607,634,380,775,1000,172,296,452,951,586,957,665,567,774,495,646,512,309,989,202,734,716,896,62,179,643,251,47,43,114,407,149,32,835,373,728,532,936,19,127,94,271,1000,450,440,715,512,721,939,991,648,117,633,778,139,612,160,218,994,746,903,363,531,55,352,614,330,778,793,670,104,980,975,229,136,633,101,33,728,794,828,725,612,556,86,689,982,270,366,365,638,314,670,780,636,839,683,146,68,272,875,676,722,923,920,251,879,101,687,782,922,558,208,257,871,375,792,283,858,639,686,338,734,267,393,795,169,687,443,717,540,547,0,914,612,34,394,742,561,591,420,883,932,618,611,898,929,149,756,40,227,999,179,572,903,834,243,67,656,796,221,970,791,425,510,550,180,676,107,587,850,605,654,580,875,928,580,109,682,212,900,501,267,578,680,500,711,551,123,953,502,115,459,67,712,703,714,66,636,264,860", "994,719,20,481,543,559,528,231,514,727,921,692,933,467,218,366,600,682,696,381,886,40,798,818,667,783,427,526,123,235,764,667,805,987,656,790,960,258,265,16,335,52,690,845,716,806,471,745,137,338,964,494,776,37,84,715,586,956,612,440,830,341,613,190,973,290,182,609,25,836,892,321,744,194,479,621,471,561,889,110,894,510,747,79,853,638,322,134,752,812,734,708,274,693,410,338,693,948,429,267,616,495,155,538,571,514,516,910,350,264,89,243,651,295,571,429,173,577,447,830,353,724,36,767,608,922,166,911,476,725,689,909,125,584,52,745,123,740,600,185,839,753,823,503,948,812,524,778,443,138,81,972,63,562,287,511,442,322,608,258,284,841,237,827,246,607,546,438,321,234,659,846,466,25,643,346,347,792,770,812,152,53,977,378,461,246,623,737,655,643,915,65,102,220,984,407,974,899,795,333,542,462,305,381,159,389,570,891,183,249,775,187,834,109,293,966,499,809,898,672,992,288,603,305,819,821,625,827,772,743,696,64,959,726,862,121,259,397,276,874,940,953,672,544,425,878,492,658,100,212,802,187,71,974,463,649,574,376,836,137,24,942,967,503,391,157,443,277,463,687,196,781,47,144,96,118,244,367,793,516,202,771,218,878,381,974,209,463,789,596,288,243,570,92,215,874,576,616,157,454,434,537,202,693,782,463,949,699,935,23,135,641,816,456,998,847,828,169,179,734,251,977,766,545,748,304,178,495,887,803,154,468,249,250,926,443,495,105,802,375,464,436,887,995,141,667,511,44,550,379,839,451,188,91,915,408,923,270,319,444,662,925,926,509,27,610,326,156,508,924,235,671,506,782,357,446,509,703,148,663,297,463,972,414,545,685,457,744,765,499,81,170,721,902,347,770,316,699,922,185,437,173,2,741,848,207,537,146,472,396,29,636,823,223,740,886,249,236,171,483,152,779,519,199,507,875,3,830,367,510,999,37,828,94,555,124,53,585,831,189,494,436,728,502,519,724,55,340,507,571,874,557,525,499,803,322,305,293,11,299,185,661,480,64,696,74,121,753,731,146,353,569,30,342,1,454,633,489,823,132,713,253,188,814,571,485,317,909,20,95,500,919,577,161,243,119,734,896,137,430,276,44,157,920,209,486,740,469,660,751,600,781,419,790,292,651,186,84,425,448,212,252,904,298,313,294,601,603,961,344,834,928,877,357,551,690,355,102,476,82,648,521,124,356,304,892,351,616,463,393,229,164,793,734,828,896,728,855,52,18,882,714,862,525,275,92,780,706,235,728,420,756,346,4,972,689,455,536,700,172,143,240,337,419,478,553,819,111,116,10,374,937,960,887,459,440,914,321,347,632,553,732,424,658,932,62,696,868,445,298,972,439,698,432,591,843,232,338,873,911,129,603,100,563,901,814,86,759,924,441,169,269,881,713,449,230,944,917,232,246,625,525,222,537,199,327,657,420,7,505,594,392,790,619,417,987,220,381,932,256,295,172,460,262,301,375,96,715,692,795,47,432,94,419,607,875,486,96,340,731,735,276,1000,947,670,996,55,229,506,80,144,101,991,138,230,319,535,577,473,812,860,552,874,318,413,373,749,536,356,631,166,679,321,425,981,410,476,54,950,965,822,216,470,413,635,638,857,402,433,770,638,25,612,953,605,617,279,574,388,697,668,966,284,834,461,575,93,972,550,283,356,512,8,270,638,937,467,755,742,816,736,286,112,567,550,593,923,149,755,611,565,724,492,211,665,785,147,763,794,660,285,973,421,528,981,939,423,946,692,92,220,63,28,350,142,195,911,729,363,903,501,646,870,526,771,310,41,272,169,102,243,470,572,970,786,164,675,285,76,105,483,388,819,255,60,589,66,356,634,73,659,706,725,889,433,208,668,274,186,21,672,396,849,449,38,452,56,189,420,333,181,30,394,702,392,114,673,224,802,982,695,646,722,408,172,552,321,663,121,287,228,914,719,2,391,612,73,327,849,521,449,829,627,811,856,494,163,319,249,194,785,939,41,564,374,878,167,669,981,531,473,936,899,749,313,379,190,552,729,784,455,64,63,498,170,455,740,188,728,520,347,201,667,811,514,975,262,140,36,631,487,914,0,14,184,70,231,422,402,941,554,485,196,881,647,453,400,778,206,639,11,158,209,224,727,471,635,958,11,326,48,137,54,876,23,192,721,780,650,165,923,187,336,109,373,336,232,398,755,962,536,425,379,979,123,332,102,749,418,590,973,7,903,239,369,768,937,93,762,920", "238,608,39,800,461,932,681,687,791,698,414,351,433,490,317,252,876,346,298,31,449,173,353,717,803,752,859,670,652,874,852,939,748,365,70,630,162,531,516,184,90,934,209,167,527,116,373,536,400,251,845,913,363,957,365,23,484,746,791,194,358,246,269,399,982,20,574,301,261,445,833,367,549,58,797,612,985,205,343,104,608,971,465,688,300,74,9,581,109,891,656,159,81,213,517,831,576,499,315,898,498,765,173,264,550,421,630,738,881,587,958,972,443,657,975,620,52,366,24,927,754,244,141,765,650,545,645,560,165,154,233,881,989,696,516,523,203,61,18,689,552,88,862,655,868,469,255,390,247,527,946,560,985,927,305,807,251,775,773,466,622,978,583,969,119,205,202,672,545,500,378,392,632,503,396,964,93,328,67,784,229,279,410,426,472,492,847,746,378,287,151,486,383,121,504,331,356,130,248,807,541,14,628,497,216,590,38,500,920,572,799,446,816,602,33,618,936,566,131,114,609,345,694,759,602,338,411,230,426,708,718,790,209,851,83,507,456,47,156,762,110,527,537,596,24,997,985,113,251,346,422,736,550,416,833,964,517,216,777,288,743,995,527,386,886,452,173,984,403,663,603,771,56,847,744,779,482,936,922,364,762,444,464,780,577,495,968,412,553,681,758,594,844,699,720,714,930,359,737,109,151,448,399,397,309,566,203,369,540,498,730,771,178,749,518,270,533,187,72,462,246,449,616,851,293,781,307,89,134,9,507,197,303,28,343,195,377,965,292,770,416,551,393,561,382,237,259,652,666,359,870,33,18,664,213,882,870,389,202,536,46,275,980,302,770,400,46,185,589,217,144,429,618,199,787,210,821,533,271,410,291,452,998,37,656,796,37,305,412,180,451,488,730,666,728,66,887,29,832,975,587,366,551,880,916,985,948,613,404,473,361,879,780,336,913,233,990,671,423,834,126,372,202,989,902,843,823,991,809,864,44,330,502,453,141,53,654,793,493,42,668,804,957,113,940,457,732,618,28,792,438,552,50,962,570,478,221,50,542,474,99,269,369,419,911,478,389,42,929,511,149,287,399,463,237,700,579,757,9,668,261,879,402,706,79,746,450,573,426,918,971,505,717,262,691,309,450,421,120,551,665,696,713,464,132,952,893,38,489,973,295,516,850,735,657,578,627,284,932,857,588,679,687,50,835,201,385,155,383,386,682,988,348,221,322,534,338,961,73,634,831,394,594,672,90,272,526,877,966,997,162,568,251,477,205,181,766,398,658,878,289,319,676,107,832,359,821,622,789,997,246,511,644,773,190,343,670,449,861,353,650,413,5,590,468,565,98,384,180,373,382,308,491,354,571,9,788,758,992,597,224,9,354,15,38,651,574,849,973,907,764,318,612,347,966,350,981,607,983,847,666,472,237,885,860,945,797,102,998,462,707,989,463,112,864,70,768,650,41,840,60,103,99,489,169,544,891,581,486,477,632,382,801,192,628,680,759,87,889,8,592,888,948,833,200,727,978,700,762,769,790,293,18,409,208,435,523,254,680,848,381,122,890,764,734,240,330,299,984,437,180,893,903,268,481,373,723,548,524,884,654,339,190,886,40,569,687,68,663,348,627,542,183,787,267,365,818,981,378,952,839,995,513,458,625,845,565,617,30,209,482,501,573,692,748,831,361,457,768,958,312,670,197,17,363,98,223,498,538,346,184,601,677,519,514,626,543,548,37,983,284,682,251,501,255,767,707,102,27,399,602,488,578,447,652,211,388,11,603,2,360,344,21,465,456,97,632,874,536,257,466,86,583,16,993,342,443,907,265,994,521,517,799,428,383,864,737,769,107,14,607,504,112,372,444,692,593,525,23,935,484,968,38,226,803,368,485,873,541,424,231,724,889,581,59,462,571,741,470,464,450,413,325,889,318,319,584,109,696,887,293,784,805,543,691,885,655,378,167,848,710,10,733,46,969,543,926,854,659,256,350,912,829,644,36,678,173,421,472,50,270,410,736,682,62,80,903,390,853,376,905,430,913,482,926,913,816,267,594,258,862,724,297,221,646,854,581,11,714,401,675,235,517,706,330,31,158,540,72,655,301,445,419,677,534,471,714,114,613,523,861,612,14,0,990,810,872,598,182,96,295,588,664,12,802,804,519,601,249,785,905,608,704,227,943,128,397,193,60,34,629,673,532,288,137,166,70,693,243,224,462,714,716,396,73,542,167,54,724,637,808,451,596,785,575,590,80,795,602,908,987,107,910,593,222,188,997,617,508,916", "979,663,952,907,724,672,137,732,436,390,131,771,430,32,931,86,349,26,336,566,269,11,984,68,118,430,18,463,971,4,516,115,708,193,570,137,249,221,754,248,593,597,81,133,532,307,315,32,331,904,620,980,567,334,927,686,657,531,134,285,102,566,940,367,474,733,727,293,413,621,18,744,601,721,917,15,398,493,944,339,130,819,37,768,146,171,525,347,136,498,295,399,264,756,541,743,812,117,659,446,52,777,710,208,186,472,977,886,519,848,136,191,267,853,199,447,599,111,147,319,827,505,733,386,529,129,219,326,401,119,610,197,652,23,841,551,719,479,998,317,870,497,878,24,820,114,362,646,815,137,103,895,493,622,619,866,269,745,447,124,594,52,3,706,446,550,843,244,441,14,751,215,416,809,60,686,542,636,986,59,142,961,477,144,769,655,143,895,783,326,691,363,505,815,328,485,773,828,451,603,253,40,495,224,851,820,231,174,457,630,474,326,925,240,926,378,306,427,784,834,106,838,188,114,930,349,188,686,507,238,523,22,106,847,81,330,76,479,797,85,722,377,753,95,612,58,956,768,190,918,550,831,390,90,605,721,988,87,239,227,37,756,7,973,243,719,862,540,119,68,62,97,883,143,986,93,752,429,292,885,346,961,397,428,579,829,561,235,672,477,78,231,101,454,285,692,78,816,565,890,492,349,3,867,619,780,413,608,386,137,723,697,266,527,966,912,267,267,251,650,824,946,807,952,342,348,188,721,337,624,370,262,26,380,904,414,493,268,664,407,363,57,519,651,438,456,99,36,268,607,980,332,661,689,227,553,421,673,148,880,823,702,182,710,271,883,344,794,293,876,437,851,170,31,415,775,896,608,450,299,398,695,404,237,78,416,883,658,354,821,181,370,906,38,898,552,757,282,842,323,26,343,463,551,773,450,360,594,437,294,168,806,911,926,771,146,200,680,128,384,307,203,326,901,530,266,14,332,264,287,131,349,895,151,163,449,452,911,119,161,924,556,117,281,67,265,582,686,183,205,147,758,31,846,346,512,300,764,977,21,473,483,61,24,87,888,921,168,718,816,269,980,82,738,630,819,735,766,206,660,927,747,89,143,356,367,336,132,694,914,941,562,309,845,363,963,510,186,97,192,439,47,791,276,540,590,431,621,651,178,302,647,658,991,480,335,561,834,784,653,110,693,367,517,944,194,76,185,680,398,110,118,20,960,247,274,830,911,262,659,919,19,691,631,859,790,61,526,886,829,433,511,103,338,817,100,667,992,652,147,450,475,31,147,418,894,488,919,55,361,854,802,426,413,595,575,185,57,553,559,917,927,503,992,692,776,970,987,350,961,716,653,317,262,270,741,31,758,489,796,265,792,626,301,530,727,941,136,988,889,692,305,655,205,486,757,498,710,980,680,115,932,865,335,258,862,560,508,460,508,91,803,412,631,956,101,188,895,119,907,806,894,121,379,424,137,595,227,122,681,102,583,650,5,782,461,457,254,45,733,289,97,686,842,122,159,233,965,524,460,863,443,666,253,438,885,100,298,979,157,618,506,605,113,506,627,550,46,221,396,344,301,280,723,24,104,492,283,288,96,766,211,645,41,853,166,723,44,249,18,180,28,993,249,52,36,374,933,163,359,402,100,976,330,697,945,440,799,540,133,909,322,165,109,711,315,365,228,86,551,252,993,23,910,597,952,710,107,482,829,582,315,457,765,798,668,944,160,299,314,846,302,787,432,36,556,139,98,512,18,655,2,127,65,167,212,699,415,546,147,21,182,846,345,233,253,526,119,678,884,199,846,850,556,524,617,96,371,867,654,854,211,315,95,695,505,622,693,649,291,842,442,567,969,878,564,159,727,410,259,368,723,516,807,386,616,987,62,393,341,510,794,733,18,990,644,569,778,460,865,31,10,956,204,315,753,282,957,286,197,665,521,973,724,405,456,633,842,766,676,431,5,800,52,524,165,331,546,187,506,663,926,112,288,419,265,487,452,711,259,227,590,335,285,933,460,712,181,484,657,422,770,195,408,174,186,552,182,793,180,86,450,942,671,245,261,857,491,268,159,896,973,770,270,811,57,466,678,238,346,273,110,762,64,515,589,572,37,471,48,868,34,184,990,0,676,237,577,448,315,216,310,105,248,342,354,226,134,344,276,287,802,122,808,91,90,613,113,8,935,87,780,170,341,958,722,323,780,249,315,181,41,239,160,29,383,137,590,145,513,201,718,926,872,890,422,199,516,367,651,793,392,75,44,370,116,291,929,923,353", "394,861,195,122,511,394,733,578,918,713,509,494,876,609,159,256,736,394,22,578,765,767,775,883,355,843,626,42,857,952,481,653,154,755,584,552,458,2,751,822,941,19,937,58,693,505,314,783,144,200,91,595,812,50,232,266,359,725,749,770,527,469,552,235,176,429,777,872,730,960,500,980,695,54,682,38,315,570,236,847,831,701,917,124,41,410,387,151,649,440,158,359,483,434,357,893,360,786,380,323,309,537,783,64,576,29,188,772,21,803,167,391,189,890,130,64,203,498,655,74,24,562,472,730,832,506,325,862,854,136,593,522,800,124,766,148,76,637,35,776,508,134,498,931,434,503,958,213,988,638,171,272,406,854,350,597,423,841,874,595,979,758,711,762,848,56,61,837,14,35,67,105,296,309,366,717,686,135,405,829,181,373,715,281,867,93,650,946,874,814,416,796,876,427,34,627,73,741,79,124,166,674,294,632,692,188,110,722,347,34,598,525,307,640,690,491,912,310,653,144,475,936,558,44,754,871,159,804,32,189,495,61,632,573,157,405,244,50,943,763,593,467,323,843,579,958,543,110,338,97,534,921,988,636,554,247,474,456,724,201,701,574,172,32,536,95,899,578,21,982,142,548,161,510,704,614,813,51,103,349,398,387,833,34,86,230,227,866,375,95,85,863,362,163,823,946,852,583,91,678,65,436,215,438,218,483,310,252,763,44,101,113,968,261,921,572,518,180,614,566,541,530,747,603,425,337,339,904,325,572,442,760,84,17,953,640,297,441,751,997,116,10,996,640,269,87,263,7,986,619,720,974,414,191,855,971,659,987,146,358,136,820,329,107,830,483,119,10,487,561,746,639,666,545,383,237,719,524,384,861,858,583,692,816,315,824,561,198,951,333,693,48,195,620,741,168,27,364,572,29,203,173,253,669,216,994,918,393,978,964,846,847,316,117,951,892,960,589,845,449,724,287,595,254,11,370,186,254,465,35,706,782,339,818,890,701,842,674,503,848,165,470,71,682,844,588,614,34,175,234,259,447,133,840,3,957,613,670,575,751,876,183,676,463,978,414,155,392,376,779,706,628,592,580,394,332,597,219,160,164,558,297,995,779,31,281,687,652,549,470,934,966,167,424,150,346,808,71,211,418,817,243,666,325,200,622,671,55,921,285,510,232,132,766,577,308,146,906,628,134,634,768,627,623,549,690,549,746,183,596,872,906,620,416,299,691,188,113,465,540,456,221,110,771,969,199,300,920,457,52,699,278,316,105,815,907,376,101,703,27,867,47,6,577,326,829,450,355,192,850,140,908,413,712,354,956,940,828,860,847,138,968,739,67,34,923,842,191,534,962,890,737,653,404,95,123,198,257,430,22,311,140,85,418,161,610,324,463,130,235,500,623,487,156,293,624,451,91,147,831,579,530,761,483,824,474,964,229,367,975,957,205,15,587,148,924,774,56,528,985,103,937,100,921,623,714,337,558,357,718,498,613,621,606,886,785,171,564,595,968,320,34,561,535,865,689,642,159,669,643,203,657,560,228,774,134,767,672,743,193,546,911,319,318,86,238,523,421,769,814,340,911,396,403,28,12,685,401,876,990,974,2,791,676,832,94,140,746,556,497,417,392,546,780,779,997,205,68,156,4,750,958,373,143,898,671,822,900,898,741,83,780,112,110,222,726,560,89,68,391,279,726,350,672,129,183,978,239,269,154,173,31,353,57,136,837,231,803,199,216,362,389,542,85,388,494,762,706,631,853,844,744,694,763,499,877,839,350,484,765,341,59,498,678,245,466,901,411,15,848,150,686,721,651,260,981,79,775,250,20,955,226,974,741,36,135,874,604,645,87,654,899,675,789,214,197,941,838,264,610,672,920,385,385,434,145,284,327,225,906,324,181,948,559,349,152,170,68,227,370,578,273,683,250,125,746,725,390,237,735,24,67,380,508,404,400,957,921,865,756,767,181,687,304,164,130,344,554,207,384,429,627,352,345,348,20,440,396,105,36,957,324,888,340,523,836,450,118,361,246,468,101,127,402,804,676,719,710,92,715,74,216,377,70,592,820,153,146,307,807,674,764,432,609,643,887,750,871,293,319,224,493,966,771,534,816,752,705,928,637,444,394,70,810,676,0,37,322,21,991,594,29,641,506,448,398,348,461,30,834,746,110,478,302,760,774,548,714,835,14,754,483,345,559,383,2,550,159,185,720,398,675,301,409,751,972,905,838,349,110,379,646,596,933,941,831,144,279,522,655,172,770,335,350,800,99,271,925,580,639", "685,509,784,455,154,734,843,132,397,588,360,19,921,968,800,672,742,682,197,995,591,787,504,516,806,360,766,624,247,463,691,248,408,136,42,487,506,179,507,343,448,785,321,316,187,770,905,419,439,98,789,960,660,83,869,379,474,459,203,268,831,338,828,434,484,830,530,661,788,523,855,832,678,415,71,833,474,5,624,119,35,782,321,982,489,456,630,630,478,143,876,890,3,449,535,201,638,385,11,526,865,197,191,452,146,83,45,524,202,238,236,564,661,281,802,735,315,334,293,720,397,71,606,686,314,262,868,457,908,520,913,492,746,570,976,788,858,316,960,891,920,239,211,338,398,858,404,915,843,641,646,592,854,640,647,533,381,873,888,56,181,448,434,825,194,356,599,683,633,700,851,453,855,961,986,866,861,102,747,914,875,873,246,233,447,489,820,732,92,297,871,404,614,873,665,636,36,189,557,165,81,664,347,325,958,828,221,42,470,409,464,116,615,981,875,976,360,643,181,139,816,662,606,522,115,544,794,252,974,176,335,720,942,4,417,305,538,604,361,962,269,249,29,111,466,800,890,917,724,202,535,866,199,717,852,419,314,161,733,454,697,573,232,52,490,88,773,335,259,576,734,28,45,763,692,862,219,261,78,920,189,705,686,744,590,726,196,53,983,645,549,832,16,257,527,769,227,126,934,483,949,766,241,763,308,105,59,183,669,407,922,493,118,332,587,512,670,856,803,428,518,461,375,361,96,800,721,891,800,456,956,606,51,685,91,324,519,377,987,458,757,892,110,800,376,376,501,981,436,437,966,146,696,540,581,166,725,857,781,606,911,736,918,48,889,559,519,934,695,122,863,719,609,124,220,849,661,582,991,229,683,108,468,80,342,967,636,976,626,328,610,644,809,473,169,500,335,665,699,53,113,130,960,825,574,508,408,51,712,97,716,73,920,34,455,106,658,499,617,679,418,813,75,393,501,115,550,618,932,546,824,517,409,637,877,14,961,76,77,649,621,652,657,915,384,603,881,781,175,221,150,893,649,925,398,16,974,131,720,77,872,885,839,414,577,98,518,320,355,77,723,816,618,125,620,345,322,868,421,936,868,869,670,765,203,545,165,281,292,868,964,581,4,589,162,501,451,612,410,371,811,668,269,410,639,606,984,82,548,985,333,638,677,337,584,757,115,107,228,436,640,133,210,447,446,223,184,399,594,908,504,374,629,539,100,568,318,365,672,744,990,454,94,854,708,523,696,118,965,873,175,251,109,937,203,468,759,830,732,918,870,857,347,236,794,222,146,78,134,512,70,370,413,400,841,276,852,9,924,586,748,112,377,892,733,375,84,255,203,132,223,190,887,701,610,865,456,13,701,485,193,470,251,341,119,125,671,343,81,324,847,650,927,622,229,941,853,637,292,405,59,2,804,574,357,84,278,626,515,71,999,632,277,257,122,274,619,288,981,668,551,845,38,872,730,196,569,565,268,930,427,878,399,172,447,367,413,256,499,475,943,118,760,287,631,974,829,141,857,508,379,559,994,56,906,444,135,60,134,193,94,198,146,513,677,946,87,300,110,95,12,857,977,248,407,708,118,279,383,552,252,157,146,958,301,401,212,401,318,414,282,269,747,53,520,341,182,326,253,80,310,362,460,121,56,753,550,605,636,306,42,526,729,356,996,633,614,701,450,325,665,502,656,584,216,519,529,3,659,658,649,203,94,28,201,980,741,824,304,798,860,365,324,530,638,78,526,487,310,4,780,588,32,114,480,428,142,246,904,278,880,280,228,589,692,639,737,401,760,825,236,783,188,914,183,792,607,970,587,459,420,179,119,79,662,817,60,622,959,329,564,528,326,201,555,151,831,632,420,711,633,972,666,627,406,728,313,222,866,765,136,235,785,387,944,12,343,275,835,91,901,607,321,70,646,726,837,967,431,855,550,421,370,34,795,710,87,556,744,269,878,100,884,289,619,752,618,970,53,130,682,616,498,885,732,474,695,645,694,719,707,439,283,283,696,232,731,340,435,340,612,902,767,62,474,567,767,794,446,581,700,938,874,254,327,37,810,941,165,198,913,703,370,67,744,945,189,975,563,861,494,872,116,496,103,970,119,131,281,940,105,742,231,872,237,37,0,314,772,177,188,258,768,966,679,480,238,304,880,825,79,279,893,946,424,551,542,843,962,355,356,417,549,330,462,323,361,567,833,252,359,443,244,475,9,613,162,485,405,15,726,234,523,856,218,899,347,592,548,458,1,880,476,510,271,169,83,990,569,909", "131,621,683,8,900,883,101,379,907,773,626,454,391,247,606,967,338,699,690,352,554,64,319,934,404,89,859,137,971,240,429,2,991,24,910,653,453,460,665,19,200,693,706,855,379,484,71,798,102,28,467,391,384,120,411,624,523,531,657,213,892,635,967,402,98,363,248,36,894,616,6,820,238,957,500,278,501,351,525,332,272,253,945,51,526,114,139,453,693,511,959,313,557,884,454,687,281,861,278,790,275,487,789,704,717,255,661,579,429,398,698,255,113,847,217,498,997,911,937,397,60,48,170,559,945,199,662,109,158,731,125,370,952,600,689,174,860,846,281,903,210,509,816,576,828,858,1,928,701,124,195,412,915,902,681,467,112,288,196,623,896,679,660,706,57,785,354,228,871,422,212,743,961,747,146,230,556,141,71,902,366,35,237,692,520,648,109,888,816,148,946,552,536,338,349,829,120,930,441,802,586,684,867,145,195,353,844,297,938,497,105,894,299,470,643,437,703,327,343,638,218,701,838,989,295,984,332,601,862,998,815,999,73,727,682,653,65,98,486,880,479,523,366,421,698,399,223,268,30,225,773,798,867,740,847,529,65,911,165,396,856,984,107,415,482,771,99,527,896,92,177,611,123,566,222,305,519,307,919,584,576,941,902,823,135,993,141,300,376,887,310,838,201,551,135,501,805,900,843,769,313,130,777,123,987,765,751,430,406,305,396,393,451,977,747,813,138,140,890,677,345,370,827,71,821,793,53,381,894,319,796,286,580,703,485,508,941,752,303,604,67,850,531,539,173,178,663,537,467,197,32,452,907,209,785,181,235,240,653,809,461,197,386,135,89,769,254,156,730,280,652,630,783,160,45,42,530,149,601,344,458,84,966,570,814,249,898,446,563,889,291,886,270,760,917,9,265,435,382,304,470,352,862,196,481,114,742,622,280,224,882,911,171,886,312,938,841,462,215,697,598,810,178,390,205,267,965,393,139,338,63,346,549,790,440,748,630,850,724,919,75,37,147,104,302,494,451,831,289,761,20,552,89,896,178,635,466,321,993,870,555,530,491,133,337,270,667,426,516,928,224,50,77,701,96,340,341,736,564,753,995,641,140,537,645,119,81,783,661,922,396,276,554,964,548,408,118,251,551,427,603,940,594,198,207,394,317,227,971,550,660,107,505,51,489,81,77,860,378,892,568,541,424,865,65,790,733,933,644,32,938,954,739,388,565,194,253,468,187,311,417,725,476,948,801,295,94,413,506,995,886,511,158,439,345,356,380,988,416,843,977,809,432,95,373,772,967,146,216,1000,52,855,344,940,981,416,477,873,876,40,351,120,966,179,223,815,984,400,341,333,547,489,567,286,589,826,849,573,9,488,660,145,277,805,670,101,373,922,248,560,354,758,456,281,423,975,961,744,423,44,181,195,731,483,19,271,804,669,915,311,283,421,258,992,17,577,215,32,370,995,668,39,605,550,282,412,628,80,145,133,628,727,267,661,226,156,705,292,432,521,876,909,550,389,949,601,89,364,592,183,314,130,574,929,294,585,224,563,897,973,680,689,227,655,715,91,37,21,289,344,658,909,548,360,152,500,436,931,579,852,579,704,844,278,80,26,408,421,99,831,152,590,700,697,776,154,126,932,120,455,922,23,957,453,625,694,300,587,327,366,465,647,985,383,198,623,7,176,730,778,490,727,851,306,709,466,68,590,152,529,939,808,403,118,944,682,404,970,288,934,378,986,791,491,892,898,986,66,519,590,651,69,109,785,485,412,617,649,797,959,998,458,619,702,48,459,674,970,52,419,704,43,687,659,770,277,868,254,159,226,823,357,666,944,587,807,489,751,123,810,427,843,228,429,778,250,198,927,797,667,610,306,194,150,788,378,317,932,901,96,899,777,581,102,314,661,707,284,442,380,607,470,201,843,549,482,508,463,466,283,969,533,188,560,561,614,382,955,944,664,299,720,525,356,368,857,535,749,44,569,383,350,448,373,824,17,754,813,399,87,908,227,797,314,649,180,823,508,383,983,536,799,886,772,148,968,606,562,714,831,325,598,230,465,675,318,966,165,300,164,719,815,876,555,359,869,967,865,588,442,718,470,647,996,706,581,713,272,880,427,243,561,422,598,577,322,314,0,247,331,201,174,716,560,79,26,940,602,580,852,472,459,835,97,457,35,733,540,425,333,571,676,160,588,440,463,114,342,894,377,835,726,515,728,570,310,884,440,268,745,137,227,606,389,766,424,14,540,607,855,181,222,517,225,553,245,831,537,842,456", "822,813,218,770,464,703,754,23,156,621,436,916,252,891,593,195,119,399,624,396,246,856,499,109,415,852,809,727,947,532,471,666,996,624,458,763,787,949,154,620,406,706,556,926,883,881,969,174,309,854,807,563,331,941,747,59,404,144,660,498,353,353,929,881,886,958,374,522,195,112,699,566,378,470,921,571,35,526,484,142,718,714,432,837,122,494,419,427,940,97,404,848,447,298,645,429,187,773,53,92,25,829,428,845,876,230,4,962,38,683,395,198,646,338,525,809,439,893,411,496,405,670,296,856,660,497,259,728,309,300,688,747,11,549,974,626,485,900,214,506,974,926,472,307,151,320,667,991,887,99,19,863,776,496,289,909,103,951,419,650,543,386,49,444,467,599,759,801,448,120,336,160,956,599,839,896,791,489,914,740,144,389,294,473,411,411,252,390,351,821,246,379,769,264,414,271,383,111,140,634,509,921,891,710,431,528,640,348,346,553,344,610,318,807,986,221,419,550,456,970,971,450,659,783,455,204,972,297,768,461,485,823,748,446,998,39,313,435,843,683,634,821,128,456,453,804,579,354,117,897,370,835,752,710,651,231,912,676,944,356,579,923,644,661,721,734,534,496,18,223,914,731,278,798,62,307,410,499,118,127,359,708,998,451,680,527,347,182,728,50,252,146,296,247,593,452,978,744,781,493,198,567,236,428,271,197,706,403,598,285,782,26,360,585,468,925,782,969,134,36,92,134,102,908,54,360,253,244,232,13,347,464,615,361,807,369,161,503,797,672,504,922,108,121,707,299,432,323,575,740,181,406,3,900,994,889,37,646,959,62,60,750,145,147,517,780,861,356,609,243,98,609,453,796,956,143,369,910,764,83,571,987,578,895,574,859,501,113,342,734,670,353,270,733,418,164,731,784,974,61,824,168,78,923,887,594,967,133,253,741,243,688,506,328,625,402,651,973,607,865,645,441,728,196,824,869,497,726,227,48,989,54,838,774,787,546,918,510,170,374,611,78,292,18,680,684,496,627,251,734,802,813,723,511,88,19,453,319,883,616,161,665,385,440,678,937,166,877,70,599,282,460,712,329,350,649,569,916,233,500,678,972,749,19,673,239,913,691,629,24,159,246,763,144,937,207,328,986,13,940,235,199,279,998,266,243,73,194,275,921,587,573,254,943,52,986,584,710,93,295,939,326,944,330,810,348,853,650,5,954,201,712,781,752,77,247,223,446,20,203,831,395,257,397,82,437,466,306,713,292,742,449,386,100,778,751,919,207,690,487,789,495,434,325,702,398,996,218,470,704,577,149,23,325,157,307,644,401,941,401,809,274,919,357,129,330,46,508,498,822,44,831,339,555,444,777,748,946,955,799,313,312,121,830,669,245,492,577,768,990,448,822,492,959,630,286,817,339,956,989,148,219,838,649,249,831,205,505,69,709,768,40,613,737,39,656,896,537,859,373,435,871,163,698,289,791,682,558,887,673,563,555,781,963,326,664,166,151,151,862,409,623,329,637,43,421,873,273,249,737,405,107,933,867,396,906,287,835,575,114,990,712,534,244,24,556,89,192,281,991,547,520,231,984,357,434,228,81,310,771,628,74,195,105,569,573,418,755,269,423,775,447,245,551,736,156,527,753,408,873,505,79,785,730,694,357,143,154,371,482,43,155,801,259,271,742,542,121,869,41,115,928,465,902,713,465,473,106,78,747,562,394,16,648,196,532,915,685,885,931,499,22,762,293,441,207,483,429,182,294,909,117,496,40,127,338,69,341,897,284,913,767,81,689,289,331,541,595,818,386,281,369,893,609,952,282,952,622,713,15,531,64,459,46,24,552,400,792,505,655,653,686,686,876,469,381,328,558,376,912,460,336,952,983,657,161,225,283,300,967,371,815,495,449,924,761,109,419,251,467,568,900,853,111,140,156,77,432,493,880,176,59,582,998,122,465,533,606,183,301,534,819,445,67,149,139,115,211,659,795,447,713,630,467,481,926,628,592,970,922,690,285,127,710,930,479,355,613,508,811,115,436,172,983,811,725,608,199,852,598,412,249,619,757,49,167,664,355,118,972,962,789,791,320,109,707,371,294,463,774,492,826,780,920,85,876,801,29,158,183,803,591,402,182,448,21,772,247,0,722,986,437,938,615,722,481,888,119,680,751,223,994,177,247,738,900,635,971,484,81,178,881,729,210,52,155,418,226,360,413,428,589,353,133,643,92,732,604,930,968,239,949,421,236,230,677,239,492,166,743,250,248,634,981,818,520,620,393,666,510", "717,37,146,153,356,758,678,637,422,626,947,655,588,331,416,93,235,932,347,772,541,476,582,490,841,475,655,269,742,577,684,78,298,686,253,929,511,512,297,625,550,603,54,95,187,135,92,153,246,565,728,775,734,566,544,841,58,741,884,327,711,565,84,901,380,156,663,206,788,295,475,84,394,927,560,712,458,842,342,942,896,334,547,7,267,842,517,110,290,350,788,19,991,932,418,54,1000,521,140,52,905,608,598,950,712,255,800,732,467,568,828,478,413,534,766,343,72,67,876,732,126,129,679,457,244,707,500,866,258,746,784,537,634,97,988,685,226,203,901,128,838,186,735,987,334,698,933,72,989,128,811,194,669,662,154,567,357,614,688,850,107,218,967,695,364,72,79,860,286,606,727,12,398,909,7,634,764,164,485,773,627,482,502,966,738,149,707,333,397,401,421,969,966,933,744,888,62,575,497,6,515,78,298,657,399,359,775,133,962,153,499,907,134,770,116,534,111,896,679,232,721,402,955,322,825,429,961,53,838,940,455,730,902,618,872,154,504,921,445,419,599,438,779,164,541,601,259,171,562,305,862,204,184,121,66,337,279,326,579,292,251,256,158,189,292,192,765,153,814,601,186,609,909,186,728,125,103,188,27,371,812,348,597,426,539,6,735,742,217,910,933,250,406,811,626,308,908,52,464,767,496,745,275,396,416,169,665,994,695,576,551,374,913,422,634,956,558,164,411,932,862,824,716,982,393,871,46,23,943,502,668,542,428,162,110,654,187,657,114,601,262,450,46,818,784,470,786,115,73,709,49,814,820,617,542,537,980,159,352,889,68,754,81,424,612,54,181,38,153,221,533,157,761,808,265,144,519,332,875,16,824,418,74,636,680,235,693,403,561,964,306,363,436,723,313,782,685,321,253,340,890,710,675,988,295,986,888,53,914,21,110,259,201,946,301,600,698,398,779,148,381,545,636,696,269,37,191,167,294,77,657,498,80,904,980,650,482,688,137,289,175,556,107,776,973,871,224,814,717,810,186,413,275,932,715,57,166,928,737,924,580,179,828,60,830,973,478,920,855,10,3,719,762,96,498,343,769,369,475,219,830,76,515,802,211,311,718,306,59,764,132,893,910,922,881,55,891,462,267,713,517,257,541,59,172,96,482,241,770,175,186,125,297,826,116,104,8,654,990,201,579,750,989,38,549,907,177,752,779,572,417,444,490,803,837,725,677,952,504,683,7,341,500,377,953,137,191,433,212,503,507,105,724,567,447,612,203,222,658,993,611,108,155,529,747,439,806,725,561,31,926,373,558,309,810,532,580,467,257,97,550,532,616,619,719,827,603,683,315,372,635,214,951,548,304,226,657,664,492,597,323,28,749,859,477,701,130,682,239,717,551,513,843,461,153,71,255,292,961,487,338,731,718,381,91,23,656,136,727,987,577,587,14,454,890,695,95,293,462,446,146,361,869,317,785,315,853,862,80,462,413,282,786,592,510,484,454,57,360,411,452,675,884,468,925,764,332,378,872,873,269,19,976,573,464,766,9,942,902,415,306,593,841,372,884,288,758,623,985,931,924,102,343,361,184,513,507,112,68,988,561,765,60,277,129,320,62,939,695,741,620,404,323,698,643,914,121,611,250,751,815,758,368,717,858,324,464,252,45,91,166,881,422,801,356,91,595,60,902,167,362,376,430,101,610,399,498,617,478,95,642,578,95,24,959,660,71,30,462,137,893,612,828,194,818,504,278,924,167,625,991,85,724,837,706,176,457,127,854,63,460,325,885,951,238,68,317,650,578,507,690,815,195,10,526,834,750,685,931,228,674,341,298,227,674,820,508,39,258,129,588,93,317,493,49,320,197,178,249,349,413,692,86,679,6,744,350,790,948,868,333,369,892,116,542,677,960,676,960,954,271,943,56,415,935,237,223,673,712,327,798,753,93,710,287,498,601,162,932,611,774,951,284,349,341,574,104,118,460,399,534,198,683,878,829,818,789,207,168,572,21,300,182,393,488,79,517,266,172,17,959,796,689,544,9,516,43,24,633,288,485,583,274,571,251,771,974,924,366,917,758,765,267,304,886,390,858,100,817,647,61,850,94,597,428,138,4,945,342,446,651,420,941,96,315,991,177,331,722,0,482,951,580,286,144,487,708,387,664,716,790,245,510,15,429,606,710,953,364,852,221,755,534,406,789,22,748,220,967,414,145,37,176,880,385,239,909,495,848,856,431,579,522,646,830,984,600,421,895,217,918,845,257,253,342,647,472,124,906,577", "397,195,915,338,42,609,573,106,988,560,928,317,244,897,553,523,654,961,462,241,351,391,735,444,265,223,639,646,142,128,968,787,908,866,607,29,667,599,115,828,885,812,824,303,22,325,425,436,591,705,196,358,882,960,735,895,691,532,1,348,834,725,342,879,921,259,369,852,201,307,457,386,191,123,613,437,109,65,82,970,591,931,691,554,146,434,440,42,471,644,339,177,113,677,814,260,785,617,457,521,812,104,683,259,533,475,258,414,956,333,549,911,42,353,386,607,870,169,358,763,941,78,689,590,982,831,747,578,800,382,957,390,793,79,363,126,517,320,658,955,539,358,217,858,700,413,585,129,375,243,18,678,42,800,24,181,589,566,53,65,177,497,553,8,279,403,527,229,423,460,636,61,110,853,572,729,821,959,39,161,518,720,619,44,602,638,841,839,968,515,594,435,854,49,238,650,244,925,622,987,874,339,433,686,92,707,460,365,587,236,754,513,786,215,395,8,779,170,599,339,540,736,234,691,188,103,274,727,751,126,811,26,413,999,24,78,569,241,243,723,247,582,91,747,866,166,116,342,767,703,920,11,617,588,116,374,952,875,526,472,36,78,895,693,819,654,214,599,892,867,424,732,8,916,355,894,222,352,579,611,725,857,633,794,840,710,93,790,88,591,354,748,724,214,664,379,712,18,360,509,615,729,284,793,262,635,662,642,933,791,639,354,823,866,112,445,314,409,905,390,721,591,177,219,147,174,761,118,208,372,655,662,424,262,146,498,435,974,906,323,859,697,382,826,444,625,760,502,761,758,943,373,147,255,324,701,196,460,254,984,790,389,49,260,27,763,899,64,536,595,330,927,347,861,241,638,893,935,9,861,359,312,775,894,914,389,514,503,328,613,498,58,804,289,443,85,46,306,91,717,647,943,951,12,327,138,906,689,181,335,358,212,795,819,158,256,413,238,194,361,773,796,824,473,283,317,231,459,84,711,721,881,288,799,681,719,816,454,12,26,490,631,562,423,820,171,724,294,753,145,803,683,119,947,284,348,269,247,754,275,242,922,188,709,837,980,885,819,116,814,909,29,136,211,720,636,994,365,564,714,875,366,518,767,249,881,823,555,810,677,708,118,767,910,225,780,176,377,120,590,671,107,371,856,167,211,251,878,894,55,485,573,817,266,810,499,165,982,740,378,470,26,556,747,870,760,517,343,540,877,19,298,545,630,389,643,661,391,405,768,498,57,221,213,568,429,461,669,228,801,813,973,147,854,920,328,453,575,394,679,951,518,803,820,824,92,185,349,889,902,794,251,680,457,245,934,844,160,425,697,283,310,494,569,165,115,880,274,516,751,257,831,472,812,877,562,703,293,61,5,906,649,340,248,639,482,216,730,100,282,290,903,638,647,798,965,99,69,470,84,462,69,96,912,66,568,648,903,580,77,309,901,692,114,36,374,87,62,300,236,98,711,842,143,84,556,455,127,457,459,267,778,693,383,101,937,7,69,40,803,278,624,943,522,545,810,862,894,58,467,33,536,311,110,396,858,13,829,252,771,107,351,927,149,828,794,633,399,710,839,641,979,489,797,372,3,35,399,658,147,164,471,273,201,203,640,581,971,962,772,300,385,794,239,12,37,295,225,989,977,63,168,152,6,921,403,903,879,37,159,20,833,481,897,753,369,687,164,126,347,839,27,212,740,804,265,569,828,488,507,68,209,188,275,551,477,301,46,394,932,137,953,482,31,696,483,861,563,575,981,767,992,430,11,823,49,458,97,501,525,663,281,926,108,374,572,734,744,411,846,314,293,998,611,692,545,767,777,640,406,939,875,731,444,161,293,600,103,961,953,614,11,432,436,616,243,240,416,223,532,930,79,526,617,873,259,858,550,446,230,565,8,299,461,277,527,68,862,952,132,562,728,295,75,661,545,282,831,527,712,801,852,744,954,771,954,616,231,616,123,115,254,577,803,223,430,956,167,23,137,751,688,220,929,307,769,509,897,456,676,917,597,697,209,176,94,663,400,911,976,382,816,986,356,87,911,215,582,258,921,990,562,822,391,736,746,706,659,875,727,330,862,936,56,830,884,592,280,380,751,651,945,615,705,347,798,581,649,822,156,563,883,554,295,216,594,188,201,986,482,0,143,97,985,726,877,957,525,21,476,730,293,757,524,642,480,297,1,659,398,474,876,52,921,67,744,53,453,830,352,403,976,498,54,685,549,760,30,25,35,413,3,249,398,576,768,633,896,915,652,211,398,165,642,396,588,571,505,88,616", "715,915,520,773,972,942,221,478,279,90,717,992,160,939,604,400,715,199,583,879,252,540,211,592,815,907,109,300,598,276,767,541,514,302,201,172,145,539,407,298,788,986,220,426,742,893,985,786,239,292,11,894,778,351,887,772,984,230,462,22,557,222,475,638,120,819,496,443,717,886,928,516,908,226,77,45,771,714,945,330,470,614,630,590,213,572,272,41,654,887,158,501,388,406,112,850,516,961,556,294,911,494,130,7,767,260,656,382,698,181,898,827,542,463,529,635,461,428,635,671,226,892,921,976,824,553,852,361,554,572,296,784,283,736,715,560,525,137,458,854,412,706,294,438,346,372,855,172,128,801,189,164,541,728,171,175,946,242,323,469,13,735,475,344,925,217,928,606,279,959,771,189,417,854,551,490,665,813,982,79,84,549,982,878,457,56,251,384,219,886,243,551,110,780,496,466,929,210,249,559,116,817,779,308,341,346,16,89,252,790,273,901,936,258,306,898,404,370,938,431,498,840,974,720,477,120,120,567,902,142,528,919,993,526,488,767,192,360,664,961,529,222,119,66,582,527,429,48,53,3,698,595,140,895,318,560,440,787,643,182,323,469,216,737,848,710,21,693,157,990,686,269,868,675,893,371,130,14,898,194,948,92,47,859,349,507,184,677,431,25,461,578,492,724,235,535,418,347,30,659,793,427,116,5,327,183,171,38,959,358,541,700,753,623,687,154,583,782,728,723,243,344,72,700,112,467,267,665,81,222,438,612,605,4,176,61,511,248,238,398,916,166,586,649,599,65,950,395,807,849,790,736,799,268,599,789,616,785,799,792,26,442,471,647,51,657,184,661,430,770,696,165,308,503,260,466,846,346,872,114,959,962,452,676,394,781,659,83,399,153,972,517,278,175,936,814,750,335,142,468,956,888,32,160,136,815,268,114,98,915,323,485,384,306,509,431,739,871,323,334,945,196,50,839,612,674,952,682,795,670,215,299,427,811,402,427,48,280,935,618,919,422,805,461,860,801,240,341,250,711,138,562,490,137,185,982,867,690,228,159,825,929,28,816,742,999,884,854,210,712,511,601,91,8,107,549,258,301,327,296,78,998,922,893,780,866,907,21,227,121,139,352,21,530,760,515,957,712,420,995,699,184,700,545,603,995,735,800,855,113,991,347,422,821,310,236,900,635,549,813,352,545,590,573,341,16,950,929,490,412,749,569,278,381,460,675,193,781,933,186,287,157,355,976,178,24,594,244,489,947,93,344,307,489,768,540,189,359,401,122,481,722,658,847,591,673,89,876,342,189,509,647,35,784,556,601,825,903,920,746,481,380,386,853,160,733,179,397,829,434,891,830,660,657,567,475,578,263,177,919,529,668,350,164,869,723,549,946,486,547,896,253,33,259,903,932,823,467,369,563,309,996,346,748,450,206,488,694,911,123,913,607,886,782,741,909,650,124,915,350,863,527,877,63,576,458,100,165,695,933,158,958,832,411,903,33,5,144,194,496,200,31,725,872,874,484,631,785,459,488,898,257,658,747,582,888,79,698,703,28,102,966,528,559,657,398,38,931,148,561,946,117,96,951,203,926,877,406,305,694,983,492,232,428,851,548,150,658,618,987,604,842,610,601,223,290,612,89,831,710,269,336,39,396,871,614,429,288,917,315,248,911,94,943,617,127,589,297,748,172,573,138,306,521,443,75,170,570,195,299,213,240,269,353,29,962,481,537,332,212,670,787,337,588,350,187,127,766,355,172,863,191,513,390,761,347,532,246,440,356,594,726,21,954,809,28,600,483,61,37,957,374,554,901,483,119,768,349,615,677,994,206,365,531,154,990,937,487,133,782,136,901,837,265,788,121,800,485,408,580,972,313,964,98,117,719,746,403,468,274,908,724,682,228,458,717,323,741,409,434,112,472,621,675,288,439,44,518,417,177,415,185,394,805,387,864,172,270,923,366,417,781,927,913,778,768,540,883,532,54,634,57,992,902,523,100,898,239,962,663,431,25,436,522,31,965,306,654,347,126,515,344,822,679,902,891,976,328,262,17,633,972,743,739,291,514,494,658,796,649,85,549,381,510,744,501,601,460,402,509,935,780,722,945,109,759,349,809,446,261,427,932,485,588,310,29,258,174,437,951,143,0,92,222,566,88,327,830,173,885,616,593,532,146,645,258,502,79,341,117,628,182,409,943,835,667,568,479,483,574,602,989,826,33,491,993,4,651,962,897,43,1,478,12,603,250,867,620,531,684,265,849,828,942,727,353,249,898,456,566", "607,662,335,13,42,128,962,763,705,954,749,874,152,414,46,7,94,51,667,362,167,692,214,790,155,521,15,945,248,66,384,236,973,947,48,482,666,790,749,599,105,104,838,151,565,365,481,424,705,46,764,809,25,191,298,345,655,605,508,916,534,401,171,517,591,44,405,715,566,825,278,121,526,662,340,905,24,818,150,576,457,93,573,694,485,769,934,296,598,937,113,565,232,770,416,666,427,985,342,33,740,391,836,286,369,755,858,430,196,23,63,186,522,309,891,253,186,808,523,72,39,748,791,183,49,598,666,458,214,965,952,869,485,217,497,92,705,999,723,594,954,220,737,429,708,934,682,488,997,926,599,95,595,843,62,880,803,248,635,712,888,399,361,225,673,796,519,221,881,171,54,849,864,653,532,864,473,575,273,574,191,105,541,765,831,645,185,182,278,987,683,750,378,86,779,291,161,987,427,480,318,149,130,828,697,316,610,229,992,582,847,891,103,439,828,998,839,510,664,819,918,914,606,427,158,259,697,570,797,899,983,742,580,459,30,676,947,979,465,241,352,503,573,114,585,402,162,690,973,300,239,356,732,247,363,389,204,810,997,454,846,148,217,402,899,407,261,93,494,264,416,89,909,493,930,848,338,583,534,391,423,932,904,369,891,270,73,563,168,215,253,739,452,151,187,791,569,277,537,853,493,124,273,134,301,683,50,558,72,443,337,997,809,649,180,719,363,891,393,559,238,437,293,787,873,59,54,518,751,691,998,75,436,8,662,136,392,75,599,900,331,703,193,294,743,363,257,226,37,618,915,500,525,947,421,203,42,857,918,962,59,390,532,329,742,823,342,246,886,166,685,367,800,212,414,259,622,555,71,153,446,684,370,647,333,839,707,407,704,264,845,920,411,743,303,538,720,928,253,556,913,480,993,6,205,132,186,307,608,623,402,520,995,637,128,732,840,492,410,359,207,396,559,174,221,590,157,832,636,570,904,832,908,718,682,338,420,383,936,590,927,603,954,890,521,791,544,486,868,889,386,356,908,914,488,44,26,183,346,329,99,852,605,762,582,131,262,797,548,77,410,986,358,168,614,432,990,958,649,132,187,251,207,308,668,63,575,291,159,281,478,124,310,925,583,406,807,795,171,115,633,352,695,775,589,934,902,673,915,227,779,771,555,292,830,201,63,820,374,731,890,807,812,283,712,615,503,309,196,407,151,22,475,694,30,789,590,947,976,682,409,633,973,688,28,586,632,720,725,282,307,661,846,633,603,727,541,691,901,636,93,575,248,883,520,601,413,788,209,497,921,771,529,808,616,540,805,872,521,974,839,203,184,972,714,112,948,260,797,354,457,467,548,675,72,494,379,183,896,536,821,928,856,653,471,611,1000,621,22,419,389,584,3,923,611,973,252,40,721,131,552,914,828,326,664,365,547,351,880,571,934,529,735,53,480,554,977,986,425,671,820,793,506,723,731,878,833,761,272,319,935,593,937,354,343,816,299,984,878,783,57,151,95,755,29,98,330,681,852,98,680,880,241,479,312,257,570,538,237,744,882,435,752,191,754,875,861,473,535,325,666,752,44,718,199,314,466,340,830,365,935,607,240,220,630,433,626,693,677,49,860,754,371,710,903,734,312,340,521,114,168,904,580,484,428,608,766,745,221,704,237,217,248,824,579,569,132,504,255,338,356,576,74,157,335,981,920,774,116,21,393,34,803,474,601,415,375,903,3,88,494,655,156,382,185,586,903,545,808,444,222,62,503,707,584,835,150,108,535,127,141,954,251,835,967,136,987,787,127,883,572,994,197,162,719,110,19,211,782,133,558,580,499,811,194,797,598,966,542,568,886,42,376,630,957,249,79,959,796,736,253,836,439,357,42,587,462,105,578,711,495,358,999,72,553,215,352,790,462,776,509,74,995,433,534,505,114,35,624,544,961,98,672,111,821,339,18,516,859,121,374,101,991,778,291,464,930,288,432,967,632,498,769,997,245,316,911,104,840,178,5,602,828,342,127,799,517,666,356,522,59,312,620,91,362,320,154,502,569,245,627,513,972,223,684,429,767,522,204,438,192,454,22,644,629,999,262,796,39,640,618,48,174,185,906,202,453,824,140,526,245,618,196,664,105,641,768,716,938,580,97,92,0,993,504,971,854,121,56,236,73,165,580,101,120,957,391,387,375,829,766,979,67,660,962,858,680,198,86,6,548,534,61,827,654,194,401,902,220,292,591,797,410,27,884,723,949,977,534,371,372,397,670,226,765,292,304,418,8,973", "502,284,561,374,463,811,393,842,775,781,468,73,358,548,266,763,447,136,713,464,781,699,147,42,946,133,57,168,958,328,207,364,994,395,332,986,41,487,671,35,887,713,328,862,385,675,242,865,2,140,633,694,407,850,169,47,895,944,606,820,654,382,418,500,221,25,43,33,629,562,468,6,103,835,297,415,463,115,206,288,55,60,727,566,47,430,201,92,878,821,175,23,172,151,386,540,599,87,442,785,917,947,872,892,598,308,154,725,337,780,328,608,849,304,513,779,72,859,14,664,889,834,5,278,839,357,121,794,856,68,951,656,879,978,847,264,28,883,327,778,36,474,185,816,873,661,913,268,516,263,722,409,365,646,60,807,639,782,959,367,941,639,377,187,183,710,68,524,463,506,804,207,741,255,679,957,315,317,643,775,353,13,352,254,167,943,733,295,186,394,733,433,502,198,198,61,313,216,455,444,710,556,828,333,313,799,628,539,515,278,75,119,800,611,541,520,605,405,983,258,83,369,205,93,808,160,594,48,64,904,29,504,597,719,58,150,856,746,194,781,746,300,402,374,99,367,222,906,502,281,5,9,841,785,85,424,545,687,186,868,598,269,183,505,99,716,978,506,849,96,958,403,382,590,482,774,649,699,376,698,317,86,793,658,734,58,743,99,499,641,381,949,43,410,499,450,950,749,612,590,202,54,540,130,702,521,39,73,969,184,161,20,741,701,730,789,304,537,90,573,711,781,562,446,814,325,412,78,359,467,87,717,287,658,124,132,354,536,760,456,392,972,218,106,157,115,489,422,289,97,283,851,424,177,718,184,945,326,272,185,839,590,564,735,47,529,419,61,62,877,816,695,790,505,386,714,933,202,373,378,249,781,316,783,737,790,605,131,13,173,706,654,605,875,248,893,988,418,537,650,403,11,165,120,385,924,309,195,592,313,868,832,926,943,942,478,86,508,934,457,218,684,146,48,167,85,568,82,118,74,190,89,543,672,132,365,673,226,146,512,522,614,233,146,272,191,404,985,581,321,222,15,548,915,329,45,486,440,62,724,824,289,386,21,681,443,185,722,444,685,559,976,361,234,912,502,701,326,989,780,656,100,704,21,642,701,23,746,585,909,62,113,922,640,625,833,202,534,245,567,252,217,305,698,168,341,972,347,988,735,573,807,81,500,21,564,903,10,683,494,546,993,777,158,94,398,849,860,208,215,744,496,281,774,752,71,959,157,774,72,491,830,446,847,316,951,507,115,525,438,57,202,344,644,685,133,561,875,857,334,720,602,954,906,592,47,274,877,94,951,787,262,590,433,534,412,150,371,271,875,523,236,581,116,236,938,794,277,182,80,687,119,574,188,262,721,25,645,665,296,470,499,714,960,638,61,416,670,481,130,763,851,522,277,627,98,366,853,242,223,47,49,774,171,742,872,7,738,99,602,954,775,174,101,703,331,368,554,837,790,21,440,765,597,302,954,441,80,978,130,786,105,665,136,368,507,595,538,218,143,952,782,122,882,203,312,517,967,164,498,413,217,51,861,637,364,645,374,117,570,744,946,979,315,468,665,132,75,814,34,337,443,461,776,549,619,661,561,530,936,451,428,794,675,926,198,286,987,437,433,833,573,158,742,787,784,122,58,387,143,88,528,664,794,117,141,578,936,98,523,89,967,327,369,164,648,651,639,623,951,281,967,538,699,110,322,432,109,837,411,946,751,273,347,992,919,129,727,303,152,632,936,327,497,130,93,561,149,33,314,788,260,510,35,264,657,315,808,286,140,441,394,265,216,294,548,302,265,201,346,792,118,691,43,548,412,372,199,752,702,635,646,66,968,486,344,234,813,828,131,339,318,116,901,926,377,544,676,499,421,573,350,81,555,892,171,699,986,969,832,704,889,52,242,953,581,324,129,701,477,330,77,501,469,916,11,65,234,895,70,49,128,506,915,872,893,225,113,599,463,772,616,652,942,691,245,470,619,771,995,425,550,798,752,3,176,570,102,908,524,875,471,531,138,752,76,564,320,499,194,509,896,916,711,232,657,682,980,344,453,894,357,543,278,185,241,980,312,185,609,510,574,127,104,491,449,829,566,434,256,901,883,619,430,365,673,213,962,758,3,956,611,881,12,248,506,966,560,615,286,985,222,993,0,645,526,561,333,725,24,682,940,354,316,47,562,701,285,110,248,871,110,146,739,86,330,786,169,654,119,741,805,132,412,389,736,742,424,547,617,876,351,879,985,283,133,285,84,653,917,923,859,869,995,260,290,586,90,11,24", "400,749,873,709,353,998,64,479,980,841,259,547,759,918,676,869,732,251,268,590,737,20,769,310,692,77,592,122,679,68,286,85,107,93,204,318,484,635,814,813,943,600,432,493,823,255,904,423,973,776,598,416,94,205,408,314,689,79,851,110,465,367,457,747,573,923,176,831,337,991,937,391,42,254,348,533,742,224,12,780,676,297,654,621,860,527,627,718,515,523,175,589,313,433,362,965,458,884,60,116,180,343,444,837,524,572,517,892,720,189,70,847,507,221,336,568,730,916,75,652,687,242,732,101,34,538,304,872,918,622,140,727,454,24,240,476,819,767,399,971,949,984,613,640,729,444,324,324,337,254,312,246,291,353,261,274,186,373,59,8,682,803,976,368,596,691,274,93,173,201,63,56,44,196,835,38,137,720,46,3,426,690,944,344,173,919,319,278,29,993,300,947,78,104,401,90,901,751,853,304,459,705,907,368,300,624,998,903,85,763,598,17,443,610,62,975,956,454,776,778,332,791,98,309,428,900,910,868,6,547,164,661,780,913,692,677,582,402,795,726,486,292,492,947,360,805,962,72,47,100,840,947,781,643,490,802,69,716,62,962,298,64,780,104,729,640,256,93,406,965,395,815,844,201,468,393,253,131,592,759,843,985,783,878,898,511,681,192,277,522,37,708,885,192,980,84,22,473,169,236,907,392,314,951,91,87,151,35,315,644,520,529,214,14,298,986,676,676,65,932,359,95,851,138,597,305,461,906,22,721,774,410,592,320,158,445,738,49,593,60,959,603,734,200,640,749,400,418,955,951,355,764,365,31,863,872,628,151,62,105,827,736,471,559,960,667,838,954,101,749,779,860,903,171,532,247,567,496,243,141,742,494,74,552,850,450,572,261,770,827,53,973,42,266,237,792,781,479,656,882,944,583,740,493,180,780,965,580,659,582,214,340,764,724,857,748,315,514,91,955,42,80,734,182,501,194,961,12,502,519,180,789,527,887,390,828,800,12,410,781,226,366,2,689,497,683,828,171,806,343,53,761,731,628,250,929,521,904,166,77,533,803,609,15,416,180,882,355,520,264,231,713,957,476,379,82,351,862,871,327,178,287,150,273,403,612,327,348,9,177,210,315,502,563,416,388,651,792,419,535,214,298,946,671,512,798,880,542,500,457,603,922,614,115,260,433,622,473,646,981,900,959,515,141,406,751,884,321,498,817,103,808,19,285,726,317,575,318,301,914,769,392,836,621,603,418,619,867,604,189,724,462,562,792,289,521,553,337,921,434,401,362,804,432,989,179,673,151,866,598,794,293,907,817,318,814,151,300,392,376,32,845,844,852,48,236,585,758,811,797,497,223,459,993,879,10,277,594,907,286,127,700,38,533,941,143,72,910,727,147,221,548,267,558,856,226,466,764,327,50,804,651,660,644,231,353,257,118,652,693,18,481,180,117,55,265,104,149,617,532,50,896,228,924,190,851,55,98,459,590,18,406,212,233,412,151,862,741,584,409,861,740,129,583,96,36,939,933,364,926,469,967,364,784,57,56,959,730,758,595,366,782,752,867,755,791,276,298,643,564,422,348,329,716,403,569,931,981,971,191,411,230,947,672,474,23,877,517,190,572,804,254,430,742,496,73,922,441,534,938,900,290,21,510,772,15,969,615,172,58,758,316,328,617,609,221,744,742,122,795,163,417,506,102,506,559,581,171,101,366,220,160,396,473,479,237,961,505,501,611,579,109,330,74,91,587,178,171,637,721,540,623,317,35,315,441,913,194,479,264,227,153,539,905,595,331,488,296,837,199,426,88,600,562,289,293,26,84,906,755,601,727,485,787,279,66,145,807,776,288,46,969,274,840,954,499,984,942,50,772,362,781,472,219,674,861,54,601,813,440,37,417,988,177,324,910,948,9,291,916,606,144,80,899,898,667,33,199,920,781,131,813,958,618,328,456,293,414,265,359,966,619,290,534,75,846,842,185,861,957,23,92,463,247,784,58,277,287,307,244,47,590,105,913,501,155,774,173,268,232,907,937,45,252,772,917,494,477,484,443,296,777,47,171,928,654,811,980,257,566,627,976,344,725,292,708,21,752,632,319,602,44,768,554,715,422,580,980,281,763,574,898,647,802,342,448,679,79,722,144,726,566,504,645,0,523,39,72,644,772,887,985,955,473,308,455,624,549,142,23,516,292,418,984,699,363,793,586,103,62,332,876,433,325,12,577,490,350,412,25,475,624,471,529,779,333,712,208,740,128,445,490,252,671,819,321,289,233,908,661", "937,33,916,839,417,103,522,185,820,49,366,295,727,936,615,740,413,645,108,828,587,313,452,149,457,229,991,28,254,351,208,793,989,897,342,224,712,770,859,55,990,912,910,87,379,958,422,447,454,701,718,627,809,777,178,830,988,459,858,330,78,322,768,410,240,232,193,176,424,130,59,316,426,329,590,793,41,312,799,858,965,314,671,405,424,884,71,715,51,217,564,654,217,432,834,311,851,534,565,120,106,74,737,2,977,345,587,563,751,721,124,680,849,553,238,691,636,285,434,937,276,957,991,64,135,260,697,69,247,372,721,354,759,326,969,482,361,567,610,254,662,856,207,196,218,990,509,365,566,163,429,21,448,866,944,815,539,484,427,755,500,782,452,244,373,305,829,738,833,90,175,399,90,981,7,769,837,49,302,452,312,830,127,487,67,631,629,301,427,470,171,537,599,683,825,254,348,253,130,119,136,657,898,323,214,166,847,263,261,372,903,410,475,846,57,111,138,390,139,722,219,121,177,43,591,907,144,998,528,730,689,265,518,450,456,286,581,157,60,196,214,980,205,475,984,914,78,303,450,383,213,480,383,499,279,463,748,751,325,133,993,153,530,459,330,345,949,379,717,476,296,290,1000,178,557,534,796,711,704,166,298,295,999,187,267,657,764,610,157,385,222,755,552,606,554,307,390,119,733,101,126,598,631,894,104,153,250,207,154,746,572,813,207,211,570,639,380,122,275,781,349,760,809,65,840,838,636,38,930,406,797,492,601,693,924,23,470,204,692,248,888,44,355,127,515,599,807,128,770,606,747,463,477,964,62,502,532,727,457,496,488,41,241,391,625,693,582,349,526,224,979,692,479,463,757,476,566,281,450,989,519,157,362,378,927,839,800,354,390,674,599,300,827,276,56,124,947,780,526,381,604,404,14,152,27,877,805,76,584,652,665,404,208,93,675,550,387,140,784,987,49,972,556,199,498,250,747,705,863,429,197,595,601,718,309,11,391,150,555,620,450,754,535,127,847,785,80,35,146,656,699,738,225,959,719,90,406,403,727,55,445,361,581,127,778,537,893,364,886,330,822,150,121,612,395,967,518,62,49,681,800,504,329,920,756,185,509,798,21,342,807,937,306,697,871,430,216,5,427,674,369,637,546,747,671,324,408,50,736,246,327,371,89,655,436,535,585,419,112,463,960,489,763,208,530,760,447,816,975,845,469,123,971,747,756,698,884,477,895,251,20,952,178,691,140,724,954,771,686,742,610,407,523,78,841,643,292,74,451,214,733,378,929,229,415,509,9,740,171,292,889,337,54,537,548,620,963,154,178,345,937,988,1000,955,579,60,975,527,573,703,56,712,836,828,391,477,57,219,441,665,949,596,43,670,516,477,733,959,532,612,550,69,556,390,927,98,966,546,981,145,602,400,706,99,187,79,750,816,267,674,383,788,626,106,752,906,892,540,651,702,167,939,564,192,823,16,458,749,980,575,350,431,606,282,72,52,330,745,586,505,660,995,514,908,855,795,72,261,501,728,159,706,145,302,728,212,578,861,442,781,995,993,459,25,15,361,589,223,712,865,856,680,233,166,565,215,162,336,233,143,136,980,443,594,43,162,630,349,479,207,760,832,246,538,146,265,405,449,229,893,56,919,313,356,44,893,652,979,739,67,832,540,540,367,25,934,452,724,908,701,855,187,353,117,151,236,220,455,745,791,571,602,752,569,354,241,582,657,670,85,878,747,641,64,170,423,399,837,99,873,242,62,297,884,695,385,191,9,763,898,605,608,904,165,64,716,520,582,509,112,689,654,760,13,457,659,78,785,923,557,735,425,382,469,611,500,574,212,609,234,203,407,895,447,609,461,384,990,874,706,433,961,511,947,254,135,53,420,452,242,478,10,959,467,828,74,875,921,816,417,988,736,147,735,14,411,691,20,919,143,863,994,751,1,435,821,274,80,366,782,21,952,539,285,884,124,199,998,709,825,364,774,398,838,858,531,433,353,558,567,109,451,583,871,677,591,100,358,301,223,867,929,805,198,533,925,809,137,826,700,177,164,80,111,530,366,327,112,484,520,921,479,766,697,8,969,302,29,541,156,761,441,256,493,418,242,959,177,953,723,906,929,453,804,354,398,480,26,481,487,877,88,971,526,523,0,418,5,512,926,489,893,790,70,953,981,861,144,618,643,213,62,926,883,283,253,420,281,932,341,261,721,486,968,93,903,21,549,948,906,500,306,178,232,440,500,227,446,466,812,727,176,788,84,759,186,231,988,910,578", "653,812,478,956,733,821,277,97,673,876,427,776,755,159,956,15,501,466,425,182,62,273,513,5,543,548,176,826,77,768,950,266,630,84,417,503,389,650,885,435,833,328,628,845,35,552,589,520,320,943,374,675,662,846,102,504,583,531,124,821,101,188,705,783,522,545,900,706,554,910,779,82,552,118,683,931,457,615,112,317,26,68,847,462,752,940,52,613,744,30,297,42,575,416,989,979,14,623,311,380,275,251,931,237,140,720,397,150,977,212,827,936,557,854,310,592,162,760,756,36,680,273,321,594,246,256,918,428,531,940,340,776,122,370,126,384,675,320,409,894,171,449,445,778,640,224,577,896,498,510,808,333,28,874,772,283,983,287,132,128,66,82,357,57,20,266,842,878,958,961,602,179,897,168,328,785,95,827,519,648,570,352,339,990,77,856,259,205,915,491,597,584,578,800,715,475,923,234,464,422,812,385,534,533,86,152,89,315,671,464,995,826,235,400,155,952,410,513,983,987,703,681,631,118,153,527,260,300,954,849,547,471,263,570,34,287,159,1000,610,793,198,458,788,854,832,759,633,280,469,663,506,36,755,888,946,643,549,181,349,126,999,75,795,151,807,629,865,358,385,990,655,202,716,894,498,801,633,115,117,430,724,559,944,534,641,656,119,660,500,505,314,18,573,354,1,295,300,525,368,250,84,832,669,224,423,105,708,231,224,508,318,458,728,713,355,736,844,902,420,498,440,767,579,711,139,423,112,558,643,342,854,344,299,799,692,656,758,941,399,795,349,164,724,479,903,407,258,306,409,863,982,3,352,616,609,49,403,676,167,774,225,622,484,98,531,365,434,432,50,635,669,800,672,145,214,708,713,738,634,93,710,449,245,210,538,359,928,662,172,782,929,740,366,54,456,974,878,266,106,300,335,41,328,884,498,359,657,854,60,658,999,322,345,220,936,915,242,674,418,9,765,5,867,795,452,773,759,957,405,443,570,620,421,419,966,450,493,315,198,951,228,303,902,994,107,585,50,27,104,654,933,305,566,89,476,577,834,246,227,341,712,637,36,960,321,415,309,868,71,660,80,722,198,961,549,51,933,914,754,777,564,359,824,439,808,11,556,796,796,933,262,657,186,12,121,190,581,765,852,603,236,432,255,407,83,723,997,474,626,341,625,767,955,596,581,148,443,891,588,321,877,554,945,521,266,94,404,735,343,992,435,521,238,958,854,275,672,324,439,132,17,299,790,39,373,807,743,217,26,623,695,104,968,79,406,487,191,668,75,443,668,608,564,366,857,825,615,935,629,878,462,30,304,916,313,386,219,350,104,974,34,944,524,472,666,660,95,598,687,294,359,813,137,718,826,652,281,615,708,877,318,108,554,715,325,533,882,93,496,341,913,561,136,186,105,886,468,239,729,180,967,127,110,90,807,386,552,947,829,444,310,319,740,902,805,185,1000,731,840,659,667,791,50,135,431,435,857,450,935,307,644,645,775,301,205,131,479,191,40,915,97,201,945,681,981,3,686,217,436,443,167,802,639,207,623,264,832,816,181,99,476,992,683,724,268,470,484,795,857,929,96,687,26,755,431,554,997,980,334,58,365,24,622,752,268,342,131,690,900,336,78,217,763,917,422,422,682,892,945,310,144,238,47,851,93,211,640,237,373,284,570,548,394,74,114,315,378,831,267,193,738,259,942,348,291,805,180,270,232,649,141,417,794,857,628,404,586,240,51,735,287,959,75,160,98,885,371,600,649,240,552,837,512,593,927,100,60,526,352,101,601,155,649,604,343,463,424,62,407,131,979,895,716,359,289,658,691,497,51,164,622,139,787,447,118,759,712,868,56,253,876,458,787,292,836,727,290,445,279,266,900,599,172,928,18,977,579,429,218,84,427,774,266,517,927,844,261,762,140,135,711,590,796,97,184,873,108,553,322,589,343,67,834,529,481,851,126,593,224,350,202,54,830,870,837,184,287,831,874,100,625,864,776,700,622,253,105,849,998,673,399,760,489,130,206,667,227,442,606,908,594,88,489,628,189,453,847,637,629,17,568,841,130,262,890,812,16,281,323,58,675,277,833,698,393,846,68,602,699,31,496,261,366,552,901,149,682,519,934,275,95,149,400,519,226,348,238,940,888,708,957,327,854,561,39,418,0,46,302,693,80,940,473,69,779,258,562,926,832,529,72,633,361,753,493,953,438,902,873,268,31,106,874,515,832,435,265,670,515,123,90,979,883,985,883,223,344,891,931,700,291,831,558,138,704,144,858,816,135,481", "653,480,11,600,999,190,372,907,505,372,458,975,850,70,822,227,421,690,820,291,487,219,883,692,276,279,745,477,723,810,537,182,537,676,958,942,925,92,220,579,868,52,164,155,654,614,243,821,62,153,792,119,487,355,526,360,280,542,969,361,619,320,131,4,569,829,679,646,701,337,386,470,327,961,297,591,550,461,140,639,445,283,853,573,396,975,717,696,5,208,721,67,90,634,320,635,644,456,922,611,222,568,956,304,313,386,128,648,638,12,530,918,832,52,849,894,751,591,579,3,477,424,165,253,810,448,255,856,960,760,341,326,933,849,276,443,364,560,694,36,782,179,820,503,131,571,167,983,909,980,228,408,447,661,808,885,521,396,226,666,973,93,28,197,526,174,780,178,673,556,276,430,136,584,535,616,564,275,317,852,917,801,576,560,839,623,99,921,822,736,421,764,856,412,247,450,765,867,960,216,324,225,25,978,195,232,239,631,763,596,929,134,178,244,714,67,763,944,578,52,365,163,175,145,117,777,91,98,716,472,517,807,217,612,731,160,704,767,985,701,233,158,212,175,537,289,581,773,878,360,265,206,852,649,862,898,387,463,457,563,891,900,427,106,212,549,530,176,789,67,21,735,802,112,144,323,812,622,833,457,168,389,328,629,172,218,962,35,3,155,383,688,753,486,721,209,107,16,109,503,168,272,579,306,105,866,750,924,562,438,562,834,263,182,55,63,436,80,647,255,669,214,805,27,958,131,132,536,362,720,210,643,217,723,239,630,728,567,33,233,36,929,343,629,618,803,671,631,936,191,831,76,472,132,578,754,269,322,947,555,766,859,35,53,269,337,641,560,458,586,605,103,101,718,798,2,691,891,739,936,923,240,478,739,182,198,675,428,899,341,75,896,322,105,786,178,532,263,327,172,925,427,354,956,773,274,139,820,126,703,534,169,483,865,765,674,299,606,105,138,830,111,986,388,473,329,688,779,574,388,997,640,254,46,270,762,574,886,803,307,542,756,370,103,619,267,158,647,284,63,794,854,949,833,3,411,176,755,339,589,192,377,737,494,321,533,236,828,704,170,622,680,573,226,849,946,790,810,382,718,65,603,605,711,493,884,609,677,324,384,92,408,994,261,275,939,68,303,655,340,366,548,796,505,852,294,221,514,717,675,499,221,183,583,832,326,358,203,260,152,267,783,363,849,147,842,310,432,245,349,22,886,164,972,321,767,459,250,612,115,853,273,542,764,43,981,165,864,160,634,380,585,670,983,101,835,438,953,473,877,939,974,830,626,477,370,244,13,427,288,501,535,154,44,560,998,328,557,3,317,951,804,225,616,933,200,68,447,890,359,590,731,249,979,56,329,979,772,967,656,308,149,239,970,716,135,667,41,125,756,78,563,955,262,277,565,953,800,970,730,150,619,350,933,11,349,392,986,847,222,577,749,229,435,368,674,779,46,689,2,519,146,896,517,663,435,836,576,795,206,688,489,367,266,817,372,773,156,640,611,660,512,180,831,708,322,734,153,366,466,662,252,561,110,958,687,136,468,963,220,235,449,296,785,17,525,335,379,141,686,218,585,213,493,527,378,388,128,873,471,505,751,632,964,798,958,881,497,468,12,955,122,175,965,768,189,538,298,167,787,663,993,60,967,227,877,712,967,802,548,905,627,312,914,955,305,570,328,225,886,739,605,314,561,935,394,718,344,618,741,575,975,689,903,667,21,229,42,867,634,919,797,765,90,853,442,692,89,955,747,765,529,918,110,517,888,294,931,980,563,761,723,159,310,182,961,812,169,586,752,154,382,506,869,23,806,956,340,115,330,122,531,598,653,331,311,98,166,143,952,329,475,310,272,646,53,914,649,157,186,311,628,695,886,339,496,43,484,555,868,880,997,581,173,51,676,307,597,516,375,82,846,129,532,523,399,111,307,869,993,591,224,958,736,170,978,381,246,267,457,789,911,461,744,547,972,358,156,628,879,38,227,348,297,776,234,283,191,62,731,350,435,557,908,225,189,163,497,2,643,654,872,184,649,333,536,271,681,747,926,122,297,856,574,783,827,192,495,992,640,362,343,574,936,993,403,314,334,396,348,924,302,951,924,148,881,351,933,773,270,553,756,778,601,134,461,304,602,119,387,525,830,121,333,72,5,46,0,635,206,149,434,157,519,58,436,297,197,460,345,494,22,637,658,539,258,90,718,162,187,436,247,498,833,718,192,345,796,445,787,277,539,675,179,453,647,469,712,126,424,230,195,702,954,35,440,442,38,973,899", "352,949,470,429,854,73,660,373,679,873,908,291,676,312,879,741,75,188,626,143,328,212,975,752,414,961,930,523,999,970,133,156,958,324,583,580,415,512,468,369,898,46,98,876,338,389,527,867,348,760,639,32,592,787,443,889,358,348,13,723,888,593,728,953,822,212,857,761,959,65,253,258,449,704,268,816,838,165,744,923,869,342,982,22,770,473,888,278,211,34,666,490,346,40,61,851,97,790,115,798,110,24,573,625,104,838,440,263,642,893,789,794,197,167,726,953,529,693,648,763,46,368,512,938,619,389,797,393,258,365,889,604,513,14,342,448,781,33,364,767,157,673,500,9,300,117,893,26,822,615,173,209,659,92,328,98,788,553,643,79,542,66,339,749,755,511,198,696,98,73,615,597,173,694,550,21,89,892,692,11,988,307,980,28,272,896,668,231,613,589,867,344,313,399,31,421,459,439,493,756,532,676,577,883,646,240,354,992,822,555,251,18,319,618,643,782,1,998,871,489,938,13,565,142,61,778,323,41,299,479,678,718,73,541,767,874,513,385,173,399,433,338,107,113,926,920,931,776,14,982,975,666,180,57,399,375,372,982,167,499,661,188,505,134,408,912,992,129,486,219,38,920,297,64,5,346,742,490,641,367,77,127,460,104,395,535,185,980,363,858,572,804,141,754,594,964,114,516,232,838,9,311,94,855,583,202,968,743,431,669,467,842,404,566,279,803,88,472,392,705,277,298,376,904,789,418,243,661,866,48,270,523,387,470,631,724,639,438,583,908,464,249,732,774,800,554,413,797,856,118,176,269,453,956,60,690,962,320,322,548,59,817,34,4,702,611,621,417,657,645,655,675,804,862,39,83,762,173,351,458,401,806,363,278,400,324,83,277,406,935,688,688,9,758,605,94,469,550,796,679,644,655,23,959,195,81,992,389,255,717,104,63,856,143,950,764,33,575,870,458,689,669,431,959,863,186,221,342,99,15,940,814,439,348,61,515,354,190,447,485,620,542,463,717,800,998,868,739,820,245,426,830,122,152,871,837,878,401,221,540,631,348,555,591,52,379,622,250,45,639,667,555,474,312,399,609,962,446,224,392,245,808,780,723,544,187,474,544,253,919,788,453,462,861,921,330,438,941,501,696,475,296,543,304,825,919,590,644,419,769,619,887,798,690,370,931,976,364,455,64,381,407,341,895,16,937,759,250,114,707,65,74,343,233,746,944,923,163,40,906,679,29,731,95,129,713,442,480,192,913,601,264,220,9,753,618,34,193,788,898,263,355,301,822,310,168,859,722,910,605,686,204,738,719,936,584,936,819,458,122,528,881,114,120,390,815,412,196,608,503,393,11,884,538,943,855,182,825,617,975,743,805,322,57,180,333,935,496,925,883,565,370,582,662,152,853,434,132,481,282,321,605,559,839,754,627,291,769,907,935,14,871,788,757,599,702,161,195,628,396,351,543,467,70,696,205,455,820,257,572,621,775,15,183,549,685,307,572,651,172,447,727,187,428,95,963,106,89,74,691,527,24,114,723,811,754,112,264,466,498,155,548,650,562,330,592,14,458,113,629,18,686,829,327,335,238,939,890,439,463,312,13,453,386,361,925,128,102,974,832,972,582,661,112,244,565,665,82,188,972,978,477,59,72,754,730,812,535,763,820,961,931,794,87,821,231,622,382,264,545,212,134,465,394,615,665,328,350,548,856,6,783,494,955,79,773,754,917,463,51,294,93,350,547,651,373,403,706,127,435,486,385,993,139,177,787,378,718,156,215,563,268,849,18,32,523,463,101,953,670,920,830,449,200,97,300,269,366,494,28,93,337,253,189,307,939,510,399,589,963,700,51,403,363,84,369,825,929,821,293,35,776,558,368,130,518,433,728,288,532,498,142,159,989,507,51,628,244,991,725,442,530,995,336,822,668,440,524,753,811,925,664,154,648,130,597,73,102,271,754,964,698,524,920,207,610,660,232,731,446,137,603,687,418,739,394,231,340,256,252,245,716,583,391,146,732,157,486,273,810,763,959,978,968,285,865,381,708,697,640,681,38,750,656,288,231,510,331,121,377,605,55,572,546,12,380,519,138,231,814,720,245,147,917,973,835,865,919,978,383,28,40,206,249,344,30,880,580,680,664,21,173,56,725,644,512,302,635,0,769,877,552,216,212,635,847,259,485,514,736,491,122,912,22,532,490,497,682,978,769,186,650,206,951,533,392,356,860,672,817,948,843,89,940,718,522,987,645,450,542,763,113,779,133,338,268,189,79,994,798", "619,133,583,600,307,647,484,969,351,354,297,52,4,721,10,790,103,849,391,8,908,47,290,644,859,680,929,11,176,917,371,738,437,519,40,444,988,655,294,89,141,960,986,980,702,352,29,776,690,187,532,362,954,632,393,614,667,271,500,16,662,633,835,372,280,58,742,890,780,820,882,710,373,402,130,375,700,300,814,726,166,75,629,515,634,358,622,920,948,358,356,125,124,629,235,274,989,591,115,51,399,285,510,868,144,795,818,78,306,623,386,80,736,961,76,796,571,12,645,106,820,777,710,122,472,513,750,479,688,392,855,590,577,865,334,918,658,106,222,13,807,568,470,131,964,221,570,698,815,573,622,140,259,865,137,232,278,458,152,619,653,162,792,45,816,548,136,281,512,153,114,332,534,319,131,804,33,32,346,413,629,195,569,386,229,7,4,486,495,662,518,210,406,661,4,157,200,572,958,380,753,166,102,882,824,702,907,75,17,505,20,569,299,696,198,585,990,557,114,554,507,956,590,180,377,208,413,836,494,738,311,655,916,709,345,204,848,294,307,49,286,62,883,662,152,96,16,293,713,453,769,678,93,690,645,3,771,601,77,445,875,549,401,620,54,871,320,435,542,784,873,620,305,324,797,674,231,722,739,311,921,303,813,17,698,938,676,105,345,300,144,617,58,820,466,873,504,708,405,93,837,667,903,939,853,802,384,669,455,391,132,783,456,464,875,508,833,95,723,190,661,966,966,487,181,502,386,281,415,994,865,645,591,561,398,873,674,116,190,540,369,227,23,243,310,311,427,378,674,452,608,426,752,188,744,413,205,209,759,984,685,71,732,521,566,326,707,109,999,869,30,997,17,146,829,363,802,4,599,848,661,972,251,888,915,874,28,782,821,152,603,418,157,105,130,885,102,73,181,693,692,774,878,301,621,654,82,573,700,151,91,13,518,493,607,648,15,503,209,822,287,635,451,973,440,255,720,499,63,499,358,168,374,975,40,910,449,923,61,705,902,376,127,955,798,212,342,846,822,241,488,731,284,932,685,512,225,743,304,953,192,47,912,896,443,103,843,827,157,748,541,49,307,860,180,344,981,311,564,427,901,174,854,721,634,663,50,794,628,709,597,432,164,815,949,364,28,57,792,596,830,677,779,965,688,224,225,489,311,511,581,173,700,790,867,999,438,911,373,330,986,885,365,140,622,904,700,35,134,306,842,601,908,852,888,316,357,43,879,881,690,638,824,369,394,861,328,951,14,79,569,774,143,772,151,235,149,439,169,70,305,59,237,622,749,604,752,940,607,294,663,595,13,288,864,474,913,199,880,195,347,375,524,237,140,641,962,270,314,805,855,759,982,815,125,460,400,566,962,611,441,481,401,338,78,688,905,615,131,404,722,885,485,35,812,621,442,733,809,977,549,327,44,998,545,572,819,589,704,393,396,380,474,798,799,697,824,399,860,213,509,381,704,183,105,427,278,885,957,961,121,246,89,449,982,555,641,919,257,317,12,614,409,978,32,923,249,979,382,874,759,911,316,525,123,519,180,430,346,466,508,718,589,528,997,916,276,122,274,276,699,794,409,410,377,117,731,788,942,42,169,181,85,422,441,176,716,755,579,450,599,372,307,947,50,21,66,310,89,533,616,249,155,882,177,957,147,970,696,718,833,838,725,851,502,566,67,320,632,358,26,774,663,195,647,863,939,823,898,639,710,988,383,651,285,486,627,815,759,195,547,536,250,999,585,526,937,46,24,916,674,648,470,61,626,788,831,535,553,83,622,145,9,538,544,890,193,885,421,603,684,210,356,418,291,243,289,498,172,602,925,898,230,263,554,557,873,696,611,192,770,313,7,119,461,683,955,613,672,850,649,550,797,553,935,452,690,767,701,625,723,752,386,171,802,869,717,554,806,413,376,816,723,177,373,626,607,358,709,477,865,210,238,448,83,644,798,963,786,474,42,152,991,868,267,245,839,518,84,496,508,845,579,132,427,521,51,136,953,275,202,25,976,728,824,9,970,67,510,594,839,280,604,541,649,137,555,160,351,966,872,275,234,552,994,83,209,641,853,118,83,739,340,628,78,777,290,809,728,324,596,29,982,456,935,521,846,400,404,57,778,227,639,785,276,834,825,852,751,716,476,885,236,24,772,926,693,206,769,0,674,374,156,491,90,687,456,997,360,378,708,337,551,955,14,167,582,919,873,941,641,857,918,107,922,86,296,16,511,302,313,322,40,91,695,560,57,446,239,657,455,94,434,862,178,570,96,884,57,145", "733,947,601,92,510,715,5,19,31,78,67,57,250,883,351,5,473,285,927,866,772,932,153,612,743,612,320,800,589,157,573,581,409,375,630,827,545,754,657,438,293,55,239,350,831,225,882,885,332,238,562,49,533,764,74,488,112,405,334,743,802,953,397,367,952,893,659,981,143,605,856,875,16,541,191,853,682,304,640,918,512,180,77,451,614,548,406,461,248,619,130,639,511,570,158,510,940,531,737,170,538,693,756,560,77,386,224,398,951,501,524,503,78,635,488,405,433,986,768,197,842,709,920,236,428,330,387,865,967,369,881,98,292,471,727,194,164,402,202,514,9,381,573,433,491,171,433,185,264,563,65,859,445,752,76,742,300,158,701,974,259,444,945,94,418,128,604,990,245,467,848,397,244,542,737,24,595,161,111,190,502,611,481,514,607,987,332,196,701,802,579,853,277,908,291,40,980,351,920,377,599,401,812,214,486,251,654,80,691,140,308,712,623,533,264,444,865,453,318,899,521,434,589,131,952,890,858,340,841,247,251,789,155,773,748,698,829,757,812,894,924,757,667,956,706,455,188,245,89,440,327,410,249,825,615,462,56,390,784,879,745,731,897,640,230,261,978,502,390,292,980,276,880,481,555,478,441,943,446,38,201,509,486,779,776,776,174,155,408,777,601,257,879,785,560,994,787,759,35,912,884,313,990,47,242,528,907,109,876,724,432,905,38,885,141,231,111,715,884,442,965,801,693,496,646,340,933,396,82,215,709,231,9,63,904,918,910,496,719,440,886,706,274,195,829,821,42,613,815,588,473,75,976,762,480,987,675,854,450,872,225,437,73,81,334,676,110,991,726,142,682,892,703,210,287,98,678,533,224,920,217,987,252,486,667,494,755,165,590,428,88,756,594,841,494,646,638,865,524,380,461,708,98,529,588,321,40,112,584,261,678,283,595,450,365,507,45,869,820,719,980,327,496,254,92,330,767,73,671,60,285,92,685,562,20,8,573,69,352,218,711,507,558,228,786,791,312,238,594,300,516,315,785,501,113,236,530,357,706,822,536,896,632,97,155,591,638,895,113,830,994,938,455,928,875,131,48,761,630,750,186,954,649,986,709,430,444,826,521,546,400,917,499,70,592,254,186,821,473,826,222,975,172,212,819,535,300,903,259,822,404,363,237,947,420,796,561,901,698,768,578,46,687,936,688,381,439,607,918,656,864,412,398,792,720,422,758,57,510,616,877,823,314,455,376,240,434,320,703,317,119,212,57,58,728,202,796,206,838,837,437,204,104,685,241,366,87,841,955,551,472,668,171,136,797,753,639,455,392,370,574,547,752,832,494,836,39,216,671,219,525,931,863,881,743,366,573,381,377,88,322,535,737,928,752,999,829,328,971,282,895,932,83,694,380,655,397,17,505,462,992,202,306,961,76,768,244,488,297,444,796,977,181,650,563,288,687,269,249,945,169,232,781,10,483,728,848,975,637,612,210,73,819,505,657,640,327,966,586,777,878,333,297,301,25,21,52,62,33,440,154,808,401,500,40,357,739,16,104,97,769,255,374,141,25,624,233,224,974,927,606,685,971,38,589,259,174,123,13,804,935,713,364,70,454,151,650,766,873,10,138,776,22,474,824,527,75,282,408,257,738,596,874,562,81,202,305,404,460,804,457,362,276,318,38,760,489,243,420,429,636,106,891,147,917,613,691,850,988,76,272,421,973,95,737,784,15,831,962,919,171,567,866,952,865,181,415,941,379,608,550,142,797,78,273,93,846,364,548,414,187,108,244,471,306,731,527,326,20,854,165,365,152,63,213,467,387,726,728,565,48,90,788,311,765,126,600,799,641,874,260,505,647,2,435,372,439,285,734,368,379,572,708,8,865,884,630,675,64,799,166,504,950,125,692,664,346,447,637,383,775,887,548,396,450,341,174,74,62,296,872,877,961,630,253,405,724,30,831,344,914,942,903,155,117,426,615,281,740,337,180,174,828,155,45,947,537,579,238,141,195,43,945,99,440,384,404,109,755,861,254,915,371,29,93,719,992,982,662,826,653,801,738,821,414,888,42,257,944,500,228,691,210,762,847,414,36,120,616,411,353,700,329,990,957,862,347,559,762,843,563,999,11,905,287,746,79,472,223,790,730,616,73,682,887,489,80,149,877,674,0,311,172,602,140,20,599,787,575,471,289,388,606,786,839,543,634,720,514,945,984,604,796,189,406,925,228,549,374,315,221,465,947,961,264,414,452,867,650,410,243,625,750,762,565,387,150,746,378,225", "275,204,973,276,421,315,758,346,667,52,492,991,921,62,188,759,23,452,55,611,813,586,414,34,364,221,756,448,429,670,704,445,854,137,417,369,403,228,268,845,759,967,110,314,283,533,491,886,183,750,219,200,347,239,2,939,303,960,224,338,609,940,670,821,383,528,859,808,147,692,984,479,524,28,863,615,529,63,136,275,172,858,39,441,30,250,616,533,327,346,393,264,902,13,299,250,883,938,937,168,276,498,452,370,749,279,678,856,455,383,478,334,818,831,612,517,170,210,245,453,924,318,481,608,729,435,244,61,316,679,418,975,239,933,474,862,724,720,955,575,720,722,999,646,615,431,727,146,59,480,187,384,570,454,810,453,821,658,602,9,397,628,549,453,459,875,182,813,155,563,597,294,154,421,716,479,986,774,376,341,325,395,951,566,441,684,264,894,156,639,96,12,143,976,306,406,757,619,151,155,14,625,902,708,107,473,362,807,350,896,855,389,11,556,589,306,580,140,575,530,756,868,276,413,190,94,851,838,897,106,736,299,104,778,49,873,167,275,63,671,80,589,757,595,234,965,406,332,629,157,853,458,340,410,735,648,995,922,219,930,740,726,86,631,758,786,70,70,359,491,326,956,209,238,778,101,950,866,356,736,145,374,440,804,192,300,810,490,963,765,689,142,939,825,984,799,216,629,60,614,442,689,412,913,368,928,698,808,49,908,424,131,126,264,618,400,515,411,843,489,122,445,606,875,657,334,341,250,940,792,383,959,528,856,715,222,320,623,928,701,521,697,612,18,424,270,848,323,371,656,437,374,526,823,778,35,733,411,184,38,995,899,759,230,589,78,26,554,410,842,493,629,873,595,363,760,740,43,921,605,280,223,252,355,340,893,270,333,663,813,20,79,939,540,10,130,949,618,668,70,56,282,111,187,726,828,191,205,59,4,44,968,493,561,400,166,487,630,718,310,207,617,213,480,82,147,528,254,910,347,558,674,841,935,520,163,921,273,912,781,363,479,259,540,245,745,201,5,507,22,523,590,73,262,500,130,435,879,997,156,972,195,925,422,779,432,399,901,239,360,250,74,786,144,741,84,880,594,268,313,152,124,172,744,654,162,352,519,685,918,38,209,545,608,604,229,459,497,771,166,50,261,876,501,829,462,173,533,657,606,298,536,447,123,801,774,179,957,931,976,149,402,847,866,10,471,170,390,444,322,721,289,831,223,463,534,823,843,475,695,80,222,209,57,387,268,157,668,376,979,612,819,19,446,764,416,641,541,601,735,870,638,46,259,922,664,500,42,431,581,860,981,555,908,463,603,653,537,984,618,475,280,846,106,296,464,537,319,325,907,456,638,389,598,140,270,242,195,955,484,631,97,77,867,724,153,912,958,954,875,695,388,167,568,456,884,799,691,321,194,130,864,103,878,796,564,430,120,761,709,76,248,566,119,991,531,785,328,985,253,380,162,505,651,64,475,234,612,685,717,242,98,729,540,92,57,442,743,346,683,430,596,658,963,340,859,818,441,766,633,497,25,942,968,322,603,820,193,584,979,123,923,577,572,188,898,118,49,646,623,592,354,371,675,397,980,668,794,32,844,782,439,736,369,632,159,855,919,565,295,161,826,877,409,167,405,14,73,418,876,736,42,727,837,151,204,220,386,788,205,25,396,980,936,437,464,333,691,396,830,339,275,430,660,243,153,756,886,16,649,407,868,424,893,224,436,776,273,945,622,490,589,76,31,874,852,814,224,573,431,366,160,627,185,503,566,234,873,654,394,439,786,493,92,789,75,373,960,422,858,909,802,856,844,748,945,301,911,65,10,871,576,606,699,201,761,143,724,543,960,474,873,511,272,345,20,307,434,240,678,914,777,784,729,577,787,843,301,416,713,694,307,204,138,63,846,928,767,563,696,199,166,691,440,419,392,421,68,388,348,739,590,478,531,965,324,237,408,687,547,126,325,463,892,353,606,841,466,189,206,430,569,835,832,985,858,324,321,834,325,106,171,655,343,701,135,70,812,703,110,463,404,350,118,514,796,8,577,629,358,994,13,332,963,974,105,55,953,853,351,873,892,425,778,945,105,105,343,312,728,435,246,512,134,278,654,957,934,443,248,737,179,158,608,802,110,279,459,994,245,293,593,165,940,985,893,940,434,552,374,311,0,608,843,904,172,92,803,26,607,102,635,576,88,895,565,859,973,166,627,421,240,208,193,77,708,160,174,817,909,827,136,66,610,146,790,21,551,587,596,432,377,911,907,173,352,755,68,886,983", "753,246,266,650,702,877,35,504,103,980,983,281,413,997,125,122,954,81,854,620,174,14,393,831,554,782,634,181,523,385,585,523,564,58,786,17,320,441,847,578,470,143,1,667,814,683,930,124,121,247,273,822,914,360,508,16,734,322,172,776,605,347,777,245,710,129,196,541,485,97,246,78,55,304,659,917,542,507,707,953,395,844,677,321,696,917,512,333,185,411,118,474,264,600,359,898,612,924,647,617,675,77,683,589,745,55,393,954,296,309,409,22,594,440,389,770,898,551,208,601,255,61,770,201,511,835,577,589,77,193,741,317,781,521,755,416,335,661,2,555,70,404,693,293,812,561,636,751,243,362,114,612,127,334,657,721,828,714,801,901,886,335,703,993,976,363,484,845,633,239,192,580,599,922,861,839,634,631,293,84,616,969,936,91,470,705,25,250,657,817,426,29,974,266,226,197,695,101,456,619,7,895,126,422,747,736,951,784,309,57,20,207,898,944,724,374,290,474,686,642,68,10,889,326,151,692,811,853,192,204,859,774,577,628,449,367,264,146,905,731,659,401,530,793,62,577,597,755,837,843,317,635,386,8,284,424,27,513,477,318,128,621,422,83,568,47,562,359,397,137,81,953,554,162,719,387,382,278,707,89,186,593,514,525,59,56,443,582,862,925,675,924,461,779,515,522,344,846,461,997,152,990,489,804,345,208,464,752,169,579,556,395,456,429,906,170,714,589,37,918,72,248,587,264,388,882,178,569,734,514,805,293,484,939,296,954,16,813,392,929,887,945,748,624,827,790,489,31,985,135,560,758,968,17,161,952,678,839,792,720,85,168,886,517,592,99,418,432,709,898,942,473,778,18,40,419,302,116,53,35,493,286,664,901,379,313,63,782,481,30,788,236,923,875,521,5,239,470,894,471,634,943,918,128,31,809,702,655,917,782,541,931,745,863,291,764,692,994,684,217,639,128,825,522,356,391,154,799,605,921,141,357,854,776,93,607,597,754,992,218,306,64,294,12,160,888,319,557,33,135,570,94,762,311,310,106,455,181,66,356,199,303,895,389,402,745,678,703,662,22,903,528,943,533,74,994,986,938,322,473,58,12,968,476,859,803,635,90,110,151,544,717,590,203,455,512,293,445,729,123,801,671,892,772,171,38,224,855,612,28,189,974,223,472,172,733,839,485,353,722,833,988,471,361,831,753,183,94,336,871,940,110,488,871,470,112,286,347,878,139,630,338,228,928,545,977,87,277,629,120,511,848,97,672,882,407,386,442,683,579,695,586,375,950,143,315,575,216,466,738,261,361,761,670,69,434,433,202,711,730,535,331,638,751,579,9,532,67,292,161,914,575,34,197,218,327,309,945,669,604,124,427,462,610,592,433,237,567,924,297,800,721,481,731,759,420,198,222,43,522,852,751,419,885,806,259,537,595,872,599,81,50,893,536,968,603,291,296,247,902,182,598,946,262,61,313,635,830,902,958,976,137,439,850,719,19,381,704,377,933,714,276,449,979,15,356,170,727,708,966,391,955,283,824,463,233,997,872,765,534,720,931,160,526,593,522,976,745,901,364,498,226,888,427,258,939,697,119,508,690,276,282,111,749,532,463,927,425,212,620,713,441,760,943,656,527,27,338,688,310,823,300,420,215,785,399,493,782,328,785,94,8,215,900,527,623,812,776,752,818,388,82,940,429,543,395,166,93,234,517,808,603,728,738,62,798,720,70,458,977,357,658,716,910,783,900,604,125,18,495,847,203,18,443,316,425,714,951,256,816,601,203,468,377,753,607,114,768,97,247,490,27,880,649,271,448,635,81,216,397,325,889,727,371,710,208,244,517,637,367,784,973,401,628,172,611,513,553,526,16,861,374,94,206,666,214,654,270,797,84,553,977,201,191,533,897,965,209,706,338,116,106,102,418,84,578,741,750,327,961,531,565,167,191,117,27,770,667,527,41,550,437,37,24,593,104,641,798,559,837,138,228,513,159,473,451,369,450,59,892,7,691,421,953,734,362,38,286,179,960,837,281,321,119,195,942,164,997,166,822,59,578,668,971,171,574,769,684,810,263,404,595,436,138,428,258,669,840,93,403,113,910,755,526,74,14,253,130,717,241,700,572,209,704,122,478,893,835,177,510,757,532,580,354,955,790,473,157,216,156,172,608,0,118,772,562,167,574,15,841,696,520,98,647,712,238,886,289,478,627,99,69,193,220,745,662,685,145,220,13,63,484,999,458,943,617,384,995,662,353,604,895,562,502,631,722,662,688,45,251", "257,782,88,489,158,162,707,455,362,212,411,359,590,28,869,168,94,303,483,643,709,309,556,516,874,715,807,764,748,290,146,969,992,94,221,186,95,728,175,643,508,802,386,798,914,581,853,924,469,701,420,550,516,649,916,376,520,295,850,319,431,786,606,79,813,289,237,771,918,8,518,262,724,316,441,684,830,769,651,436,665,494,362,829,894,237,933,474,446,282,229,141,394,300,172,507,641,439,804,632,321,415,866,650,479,65,249,324,606,327,708,725,568,71,156,711,156,141,69,35,964,443,292,999,393,65,387,989,774,84,772,769,884,610,894,142,421,80,936,265,279,62,602,577,551,294,557,931,947,35,418,716,182,998,841,572,623,211,395,796,210,804,205,875,992,443,852,593,850,534,581,845,464,654,359,25,239,737,413,104,924,891,880,613,568,701,283,162,459,676,548,847,763,751,146,787,9,961,868,305,630,457,388,523,770,704,720,524,385,112,407,759,883,606,111,399,162,257,914,545,91,413,458,879,886,43,589,484,868,759,952,691,640,3,39,274,695,474,597,68,513,821,149,21,413,442,94,662,30,262,938,598,63,377,404,84,465,339,381,50,566,890,612,477,847,460,579,362,994,719,823,32,853,684,402,498,329,339,728,883,157,58,80,921,683,192,362,168,557,508,167,121,592,770,618,19,205,402,105,783,156,103,658,909,485,990,1,513,136,635,501,136,488,20,597,460,245,823,78,209,410,419,639,742,366,822,399,694,965,812,490,605,305,635,415,577,868,964,781,670,351,996,344,749,884,693,989,846,874,54,371,533,394,998,884,533,365,590,941,297,981,298,291,746,379,742,847,120,524,751,738,140,347,502,881,798,459,116,81,442,119,54,790,17,798,885,852,328,449,821,515,320,585,150,656,598,991,165,955,612,466,590,842,524,597,52,294,753,719,632,178,934,813,251,249,717,21,875,412,426,171,48,716,696,61,727,343,513,928,679,591,924,180,875,296,270,903,445,83,695,187,244,452,104,635,791,805,973,607,868,778,452,294,198,905,223,929,451,58,596,91,383,659,500,862,460,959,467,164,837,26,827,348,193,649,294,834,813,473,169,392,994,656,777,191,33,1,37,974,709,330,686,334,17,550,26,548,455,336,669,176,197,471,195,630,660,247,411,448,935,51,336,189,695,435,370,39,14,336,417,874,544,755,560,982,175,818,347,617,944,38,947,177,142,412,428,335,214,786,197,231,80,758,21,523,229,249,386,756,17,197,865,857,730,185,541,862,377,589,553,318,272,766,814,782,685,497,671,257,491,529,779,996,382,255,69,141,323,153,583,961,283,878,982,177,759,911,830,115,697,698,521,480,503,159,64,639,551,790,596,437,270,534,107,929,346,416,783,504,260,823,143,141,252,104,895,747,621,473,37,275,297,326,443,758,997,35,13,203,454,797,620,966,363,91,377,123,724,718,706,89,549,819,230,338,58,563,331,450,934,229,997,614,110,545,348,264,961,959,248,515,445,336,898,989,275,321,296,141,665,209,777,754,357,608,901,324,291,600,870,786,700,102,532,16,788,236,834,13,202,417,45,702,996,308,144,294,563,221,916,676,942,40,102,584,154,779,933,747,85,812,684,152,865,523,10,271,756,945,236,688,677,441,415,819,743,442,243,929,870,884,440,669,333,281,147,806,842,902,401,672,934,532,572,450,921,689,161,10,429,316,513,969,658,521,709,946,901,931,916,93,294,905,255,22,685,977,297,209,295,212,944,30,602,382,886,371,297,551,46,420,51,963,942,129,878,528,411,480,826,715,766,68,997,474,524,849,716,742,567,351,789,388,531,375,278,823,550,68,187,438,437,187,953,313,543,352,505,177,647,312,282,680,65,512,16,672,400,285,962,223,841,965,644,796,88,514,273,906,524,366,417,53,850,407,944,958,172,199,796,154,46,384,550,957,886,424,957,809,543,778,613,353,465,945,539,761,516,516,352,352,504,147,470,563,895,69,86,430,899,703,677,58,453,616,555,824,182,161,859,850,640,145,277,722,988,385,107,485,16,51,603,733,655,512,703,571,395,477,576,716,470,785,469,670,63,533,853,290,272,39,694,413,511,624,117,96,224,757,650,211,903,224,227,808,302,946,97,247,15,524,146,101,316,473,70,69,519,212,491,602,843,118,0,939,867,708,417,389,993,434,735,264,621,433,808,149,174,669,970,828,942,814,891,542,223,262,420,554,191,43,945,204,76,704,178,963,315,527,134,539,431,409,828,926,627,552,239,172,561", "766,244,141,804,19,417,982,941,311,943,6,819,278,187,910,139,759,303,105,793,796,643,621,959,623,904,115,871,398,920,745,587,421,996,798,373,477,259,172,217,289,530,501,899,520,444,797,959,676,849,895,692,250,170,355,887,966,825,605,132,92,613,692,568,111,758,229,93,125,858,616,790,232,733,349,960,371,617,442,475,171,824,501,222,394,924,932,454,393,188,484,455,445,58,868,632,737,946,45,180,741,681,673,389,333,638,394,672,982,480,456,237,61,810,360,283,643,959,649,923,469,337,278,297,963,38,423,170,655,399,765,418,849,894,289,684,61,647,970,639,28,628,552,857,19,728,400,271,222,105,53,714,272,746,674,406,518,740,290,507,701,179,767,875,243,885,616,312,602,328,326,715,972,255,404,788,453,427,852,859,841,191,809,299,443,975,742,442,38,555,666,722,43,328,361,124,295,828,326,168,538,572,845,758,199,566,860,177,537,192,378,281,988,767,798,403,894,204,787,521,151,738,49,853,985,27,653,81,164,714,223,47,551,693,141,381,158,747,443,60,872,1,783,517,559,215,240,592,853,383,703,542,338,110,800,589,315,892,595,717,866,360,395,256,816,717,68,137,830,900,989,74,121,708,696,549,730,425,313,674,364,978,468,438,378,423,63,557,229,126,726,287,889,376,102,630,708,906,359,962,789,377,881,899,240,378,423,184,965,430,676,882,343,782,926,484,225,382,133,245,495,387,456,536,502,181,376,944,960,781,56,881,988,565,355,56,111,592,262,577,180,76,736,284,926,780,722,54,600,17,497,971,802,807,646,295,43,537,722,747,407,805,595,224,359,230,762,795,59,724,330,452,418,604,747,390,374,597,57,672,876,534,983,925,110,183,223,83,319,170,454,580,678,767,670,206,43,282,942,444,23,288,410,675,952,754,27,717,494,211,409,596,428,967,394,182,60,36,927,213,224,683,158,223,782,616,549,848,997,475,617,996,183,102,268,796,402,177,193,343,127,756,446,887,730,483,621,819,572,641,564,703,707,672,753,778,651,358,339,463,76,746,188,657,879,119,91,725,175,944,698,184,81,460,713,281,852,64,590,206,596,184,697,289,743,528,591,290,314,111,632,667,809,961,904,784,804,778,288,792,297,21,598,109,706,513,62,789,195,104,895,598,405,307,312,797,200,35,446,176,163,405,635,284,675,654,177,30,161,656,338,573,33,270,186,800,570,327,151,394,838,821,957,395,84,763,129,107,416,86,162,76,690,229,349,525,123,228,757,524,219,185,915,30,67,756,141,173,242,583,677,783,750,432,238,621,164,380,876,445,972,821,940,834,285,976,19,201,933,349,608,844,111,706,397,676,365,877,579,4,537,425,386,705,305,113,177,968,373,736,270,88,221,600,181,926,692,801,502,128,802,715,215,161,131,587,956,656,803,239,778,858,554,790,207,714,298,538,254,873,38,638,65,278,107,691,975,261,719,116,862,220,775,233,27,990,25,14,19,336,294,277,483,401,1000,487,529,595,211,217,475,262,347,691,211,571,315,504,143,687,848,283,879,384,533,606,24,880,903,936,444,868,917,387,86,753,63,558,634,482,539,243,965,476,47,403,415,523,952,366,405,882,980,377,316,268,469,751,330,24,620,116,591,625,619,866,658,787,287,603,298,751,785,890,242,349,253,211,984,420,526,895,996,563,455,342,792,869,603,680,172,195,374,25,19,218,697,930,934,488,282,15,126,285,517,836,751,496,607,245,426,507,929,285,222,536,64,162,83,716,500,203,113,922,499,883,381,281,529,734,554,968,899,945,559,491,642,538,713,271,827,488,690,430,752,372,650,869,481,275,453,755,909,124,48,119,38,477,749,914,845,55,782,724,413,883,201,553,80,835,266,54,449,833,662,692,921,465,524,350,792,505,307,868,256,320,814,339,562,623,135,202,467,579,501,86,646,966,163,84,530,933,35,150,230,262,460,715,782,171,607,538,771,14,698,176,970,616,237,413,81,269,557,875,506,347,749,917,610,974,859,383,197,735,571,938,570,980,452,566,611,857,336,142,225,432,917,759,174,616,458,74,136,997,30,858,696,888,962,288,388,588,958,615,355,614,918,780,429,599,361,834,727,943,91,760,424,457,738,429,642,645,120,47,308,953,779,58,635,90,140,904,772,939,0,610,213,895,578,285,824,400,857,868,259,601,515,915,336,428,200,521,870,899,457,343,137,799,107,364,408,396,825,673,375,676,589,349,597,361,883,329,841,35,897,443,315,3,24,990", "839,810,299,157,960,608,780,844,27,275,276,288,862,817,619,602,880,457,631,455,248,367,760,4,614,7,738,178,618,446,949,647,90,785,286,839,383,468,388,522,698,591,829,973,2,260,628,304,104,896,408,271,158,370,101,664,546,825,927,482,525,42,770,642,860,289,529,878,382,283,656,503,76,688,497,27,825,215,795,377,966,864,293,277,806,396,797,655,291,195,744,57,892,985,560,189,938,908,581,607,516,189,621,648,876,73,200,666,594,504,664,865,31,956,327,853,371,662,98,617,777,764,650,332,521,149,183,153,396,708,990,161,816,22,330,900,803,93,271,19,764,570,768,550,167,377,396,343,921,441,809,827,650,104,198,194,605,899,984,512,63,138,935,603,555,248,396,523,917,724,62,629,870,514,560,696,469,607,21,42,571,966,671,940,896,867,949,845,284,320,127,172,897,75,860,642,166,871,69,79,292,578,513,41,16,636,508,708,295,233,126,890,173,633,101,822,171,29,103,771,332,899,432,559,815,958,289,353,339,476,757,167,613,253,487,13,596,931,783,640,451,10,508,621,64,62,396,11,955,322,908,667,463,297,352,609,755,424,445,866,563,353,800,305,52,74,587,224,939,340,545,822,690,793,276,819,564,842,815,652,207,687,34,128,914,946,835,635,354,519,92,331,403,733,260,930,614,287,955,603,99,808,117,316,543,395,566,182,966,284,172,956,935,855,14,49,164,136,37,901,428,683,691,392,568,39,977,213,207,414,170,405,789,583,599,909,187,940,905,812,955,362,736,678,207,201,28,768,662,107,296,185,351,849,995,891,233,504,777,879,714,163,63,102,916,226,148,366,33,68,905,371,927,249,958,535,446,907,658,95,630,255,576,680,517,73,498,255,420,813,309,811,39,725,357,717,416,414,240,314,766,402,181,811,705,575,864,966,858,791,752,303,816,601,833,997,912,197,413,364,354,150,634,567,588,696,230,829,414,819,443,675,66,34,636,289,57,873,119,257,399,374,729,528,390,710,294,422,640,469,862,527,297,285,113,115,652,189,396,727,566,337,987,738,474,556,184,622,622,983,79,348,275,146,52,581,189,122,598,935,530,277,594,787,427,464,526,998,372,143,581,37,384,493,57,601,921,481,231,805,989,674,662,960,925,883,714,444,509,582,201,171,885,72,41,474,790,525,500,646,354,576,722,212,384,400,604,858,431,386,852,439,131,797,964,206,442,592,533,7,768,857,872,378,218,343,267,861,835,13,14,604,798,520,240,316,263,693,406,846,690,135,57,537,180,171,793,319,132,981,676,502,298,351,784,37,585,115,128,51,706,229,170,878,30,443,897,117,287,360,27,843,174,701,978,191,860,576,169,25,425,624,360,218,573,69,403,261,218,12,171,449,270,700,23,757,150,413,107,166,89,307,724,197,219,137,264,751,559,354,748,832,495,649,453,859,801,927,429,961,358,425,54,322,324,194,421,634,176,831,650,510,838,569,438,855,821,838,337,453,15,211,178,897,684,372,175,89,747,803,779,807,191,187,858,6,997,528,575,617,250,455,833,539,676,311,785,763,376,834,224,424,467,421,235,97,800,197,874,152,750,481,685,352,591,907,774,325,448,575,608,305,181,860,770,424,713,703,345,337,581,159,809,859,268,583,139,43,235,875,556,773,379,916,421,633,964,702,323,463,676,809,891,564,669,563,74,584,43,302,450,641,272,532,554,833,934,773,230,21,940,857,341,604,985,795,310,181,603,801,290,728,253,831,809,697,511,724,803,845,764,110,271,525,752,62,772,556,766,455,56,510,988,692,778,834,153,54,340,61,863,976,300,754,362,583,18,988,154,262,50,771,851,451,468,517,772,877,214,770,664,322,942,26,404,570,886,352,694,757,29,890,693,947,446,346,635,683,748,205,5,790,352,423,990,834,491,249,317,778,833,574,499,607,624,735,174,960,366,242,448,928,501,303,435,334,37,334,682,943,618,494,923,374,152,353,646,522,371,131,595,170,500,395,436,940,989,241,522,713,458,682,485,945,969,975,889,773,815,372,238,981,205,661,182,220,666,172,797,6,897,251,884,784,793,744,546,584,80,62,333,93,566,942,55,706,974,9,460,854,433,243,471,128,90,774,551,35,900,606,480,258,957,562,455,981,258,436,847,687,20,172,562,867,610,0,450,222,635,808,640,556,324,300,55,366,914,674,694,926,341,775,278,759,647,745,609,876,474,419,822,889,320,388,179,705,410,420,55,894,613,992,361,635,747,150,711,22,403,773", "814,48,916,259,930,215,937,857,906,307,275,43,529,778,946,131,522,379,270,631,49,945,708,948,553,620,847,758,914,614,959,493,945,880,899,57,345,105,305,991,248,613,622,82,352,786,225,184,318,228,706,4,962,696,382,594,395,893,469,779,662,175,153,59,450,478,317,158,313,149,546,846,394,60,699,151,816,587,742,674,821,626,802,256,402,706,300,784,449,114,574,98,843,879,54,814,430,767,840,57,697,494,473,825,468,769,541,552,982,194,911,624,265,381,343,187,906,899,111,694,616,187,918,550,16,124,613,523,604,332,293,466,345,672,61,464,234,141,392,77,156,917,735,40,979,290,277,256,325,602,191,848,646,327,524,516,446,858,290,180,482,917,303,320,457,153,662,397,920,104,742,235,120,969,939,546,181,119,375,146,297,497,855,790,840,68,943,417,485,922,190,449,273,284,852,577,80,27,931,505,549,227,243,506,202,240,861,176,69,457,839,462,660,263,770,190,864,760,995,151,344,198,46,419,708,160,794,854,711,203,34,859,997,812,437,382,845,436,165,569,367,113,126,366,449,184,281,988,873,827,558,279,377,212,826,188,124,809,446,994,399,888,894,800,32,598,377,644,654,170,40,799,410,574,980,214,704,560,897,37,83,372,35,368,297,695,640,535,361,10,776,418,298,389,304,856,382,369,511,368,508,932,302,498,586,266,4,298,79,76,843,14,14,869,110,142,213,278,337,339,870,851,965,723,139,999,706,379,203,492,318,445,214,863,530,139,37,158,608,665,147,977,231,15,482,414,762,440,164,924,874,485,125,798,70,428,899,797,301,263,187,89,850,303,752,766,11,460,126,265,576,201,369,71,635,946,516,877,562,361,609,417,901,235,792,602,9,477,335,638,704,586,294,720,374,617,168,865,271,135,714,748,644,386,61,513,790,328,688,534,563,265,618,480,148,782,445,541,318,97,712,330,36,134,762,924,136,284,668,5,480,273,621,52,684,274,313,718,352,84,934,141,417,313,14,912,162,890,63,649,123,555,855,632,496,612,958,515,838,448,839,924,1000,819,954,537,175,494,318,418,23,712,738,817,79,574,972,605,502,95,399,334,505,622,229,377,963,526,146,65,866,579,682,110,486,749,457,856,254,324,864,836,620,117,916,73,508,720,60,939,224,876,358,329,922,276,767,458,908,590,653,521,585,897,180,920,774,936,806,519,65,994,906,559,208,694,803,62,547,822,946,614,722,205,56,601,175,998,735,108,886,606,777,743,871,427,552,460,709,466,748,913,591,500,843,260,762,278,247,94,491,383,889,840,299,426,770,977,51,656,978,432,550,494,37,945,821,776,897,353,338,258,891,832,397,109,526,717,397,630,18,937,406,321,960,152,211,675,916,155,297,436,361,20,266,820,416,425,263,704,710,201,903,242,30,202,238,431,631,599,978,770,626,601,890,897,859,317,347,808,57,653,173,528,106,257,123,279,937,514,35,657,500,443,627,182,67,869,12,688,73,496,882,713,70,755,906,618,602,94,475,369,283,609,230,634,902,637,334,474,679,782,317,719,101,695,778,469,474,492,777,48,574,453,471,512,514,572,34,343,682,936,278,29,125,941,522,330,563,115,196,152,408,696,748,574,222,18,552,666,272,985,344,16,582,411,299,420,7,76,326,702,746,269,967,931,910,281,346,74,140,781,301,826,517,446,85,18,693,536,517,93,228,602,25,230,337,700,386,292,676,361,906,460,29,178,737,49,591,745,593,168,757,177,250,877,989,994,330,500,118,277,257,723,554,248,421,111,639,528,517,892,389,847,352,435,48,233,97,871,451,125,114,26,278,983,613,45,287,851,701,967,854,838,219,983,910,312,986,127,826,949,250,75,728,11,653,272,785,918,934,19,513,85,766,485,925,723,642,636,150,856,822,847,921,630,66,195,830,561,68,384,155,833,909,353,396,808,466,395,246,823,165,660,39,411,720,913,386,702,455,930,980,514,754,244,212,394,478,727,786,797,415,529,506,354,325,451,539,793,185,885,25,197,513,396,984,494,652,332,927,469,252,943,700,635,388,384,674,479,414,234,166,565,670,609,116,253,864,125,965,488,748,165,557,141,833,279,45,523,801,67,635,397,613,548,542,733,635,710,297,502,391,701,624,861,562,297,259,456,599,92,167,708,213,450,0,281,391,372,494,596,251,335,704,779,844,752,864,341,955,570,715,959,733,998,11,443,435,631,16,376,929,566,813,571,748,510,851,13,90,511,661,40,311,878,987,263,579,555", "308,661,97,655,522,671,125,9,601,559,818,808,983,28,777,241,562,397,60,569,216,853,152,621,308,850,748,49,814,928,598,346,116,99,553,954,127,447,161,335,754,369,722,948,394,5,942,451,960,963,731,721,433,88,482,327,32,866,70,879,841,976,576,522,828,2,22,11,45,561,978,964,661,999,24,619,386,825,695,940,807,255,443,680,387,225,23,760,169,451,484,869,395,109,143,395,170,830,349,45,88,13,911,314,665,677,532,271,743,3,926,215,235,780,776,571,990,264,647,230,692,32,996,785,378,238,567,544,148,958,548,685,592,625,449,373,337,396,248,145,296,692,442,699,748,323,449,217,471,601,765,989,783,882,727,818,86,931,245,448,105,256,338,61,957,577,55,464,367,815,139,909,443,432,183,741,260,210,552,698,297,236,788,761,791,586,701,646,62,348,388,972,679,827,613,666,585,321,472,913,389,553,249,78,564,402,137,677,792,738,913,129,160,164,183,972,766,804,452,283,769,229,101,35,207,618,903,330,311,248,357,459,519,216,579,490,880,562,733,855,604,350,459,759,420,620,758,537,693,92,844,135,389,130,163,656,544,615,658,900,768,464,171,413,846,593,406,528,989,636,478,28,834,546,440,436,806,520,424,856,156,78,730,113,315,499,164,993,793,195,562,864,817,493,574,265,243,948,551,391,109,967,69,759,392,829,65,886,352,202,558,988,479,977,782,321,955,141,539,529,176,488,355,551,888,441,896,639,906,987,454,615,136,305,934,763,140,826,50,971,704,823,702,195,895,938,420,196,256,91,851,621,900,906,534,661,21,247,248,740,722,105,478,687,364,816,245,362,809,944,375,2,684,877,944,537,89,641,340,95,258,36,293,504,517,308,420,408,717,958,985,104,51,680,634,258,740,498,333,237,96,455,384,331,564,133,896,383,239,560,351,859,40,955,292,473,32,503,166,152,599,552,121,65,244,385,430,666,964,670,666,426,805,85,15,245,97,12,814,515,691,723,934,711,848,750,510,445,811,281,450,730,377,524,718,997,386,492,390,248,136,4,712,749,597,1,902,159,299,534,750,412,707,207,344,649,471,207,526,10,242,927,797,858,251,669,388,175,575,604,850,681,586,50,600,720,276,743,356,721,349,291,128,858,349,102,896,866,96,272,990,634,691,656,677,986,688,346,778,857,870,728,247,413,711,730,405,445,204,593,989,964,55,521,547,372,384,469,856,521,63,797,250,383,83,903,367,463,761,380,80,545,59,786,961,51,394,199,826,831,441,919,498,412,64,993,507,382,350,287,490,831,222,792,342,611,752,967,825,975,624,467,673,519,217,935,662,99,556,476,102,453,278,680,159,740,150,339,365,104,128,84,462,791,413,407,6,825,718,382,456,973,418,503,627,321,697,654,571,807,414,14,123,647,208,540,659,107,423,336,907,433,777,394,410,285,122,904,327,451,429,243,757,393,130,11,281,732,270,881,645,758,480,371,826,747,634,912,238,21,713,585,47,549,88,373,572,909,612,522,174,451,689,320,414,915,435,403,580,819,785,191,920,877,418,501,229,443,547,734,964,333,454,329,769,956,304,607,485,52,871,561,886,702,717,251,906,402,22,37,31,461,437,121,667,739,211,673,982,648,610,932,298,177,557,831,888,860,904,360,907,903,333,936,246,401,921,51,514,594,163,748,960,819,421,964,170,810,127,101,152,257,222,547,843,784,801,184,163,335,736,59,454,915,923,607,769,639,135,858,602,197,770,948,461,245,517,266,301,365,907,888,66,482,344,347,192,857,85,509,938,219,190,224,945,336,415,775,266,208,905,516,322,585,704,766,451,556,370,960,817,529,783,478,866,236,904,627,573,260,28,370,460,152,315,2,282,859,352,144,894,419,348,258,905,779,278,605,774,174,700,382,107,299,29,441,262,84,367,730,218,10,947,995,890,11,667,957,794,885,92,732,616,797,479,642,580,257,419,801,518,971,592,518,374,539,177,673,433,214,986,486,944,47,278,356,898,874,128,585,960,611,869,67,705,72,497,68,433,33,413,585,8,538,849,929,777,473,554,558,79,244,558,382,947,620,533,735,935,36,288,221,395,850,441,266,92,786,461,891,367,656,958,193,113,714,843,540,971,953,1,79,387,285,549,144,926,197,485,997,787,803,574,417,895,222,281,0,218,629,178,786,890,18,355,662,421,288,78,33,907,644,233,675,789,184,94,999,301,113,274,266,528,951,835,248,17,639,359,743,640,231,176,405,730,10,952,464,771,890", "402,585,951,193,360,160,775,792,928,378,268,69,315,694,900,390,578,887,861,284,161,582,392,300,59,639,29,901,749,532,345,214,585,923,8,200,614,432,352,987,756,584,195,833,299,542,214,339,332,625,446,481,470,870,639,608,648,921,489,891,461,976,603,235,687,408,193,423,793,659,394,175,52,655,43,191,610,144,903,54,762,762,548,899,782,513,985,783,492,938,734,349,602,629,648,236,162,676,93,978,970,850,404,844,846,692,714,280,664,964,172,843,733,425,285,402,913,851,984,500,380,370,894,251,197,173,893,233,766,785,758,907,149,167,183,604,865,367,784,234,699,968,351,183,258,948,404,169,454,616,418,299,878,40,278,589,355,658,342,910,475,244,411,340,779,574,790,286,248,13,85,789,577,439,630,210,700,837,78,637,643,131,638,382,706,146,286,853,237,770,668,500,267,522,956,73,882,607,827,369,656,645,611,603,520,769,737,426,958,372,923,594,580,142,403,815,504,608,574,293,586,460,956,958,65,93,80,784,317,928,546,260,363,135,475,949,153,531,897,700,730,196,879,237,500,701,620,345,906,919,432,42,247,127,752,754,835,526,497,365,960,506,912,280,675,181,414,762,974,226,63,476,856,302,987,455,316,871,252,197,340,163,504,129,3,347,239,443,810,883,459,185,356,836,271,51,210,164,634,503,505,677,648,844,140,940,690,723,775,904,322,255,793,99,758,495,496,387,496,740,541,278,843,952,668,853,869,221,652,195,482,498,259,967,76,739,174,265,224,278,886,376,197,390,957,369,818,200,922,660,327,281,680,99,761,633,602,489,76,585,484,703,179,710,995,272,45,904,290,283,427,60,937,538,187,475,435,644,181,504,395,360,509,699,936,497,400,75,385,21,40,923,274,655,380,323,746,220,581,713,124,305,871,762,699,763,681,734,793,565,189,428,49,146,538,244,337,588,261,502,990,554,16,116,288,183,205,206,560,112,733,355,905,640,141,761,187,596,416,597,809,328,332,453,688,290,250,367,100,467,863,631,617,545,504,699,13,782,267,332,46,301,574,780,144,106,724,348,914,136,228,1000,85,498,37,91,695,182,338,809,445,565,761,864,205,222,306,855,632,597,542,61,352,410,673,46,663,606,675,969,741,241,238,935,348,981,529,571,1,685,462,424,803,286,266,211,618,897,406,18,391,854,890,767,151,613,237,157,919,677,969,91,635,535,3,708,653,594,436,723,463,299,873,697,131,257,144,439,713,913,467,20,69,119,333,436,896,575,552,489,506,337,985,207,154,501,508,68,668,988,532,340,302,453,142,457,600,812,652,553,284,385,385,836,465,828,669,456,512,710,517,470,278,819,631,164,247,821,314,410,508,879,986,612,925,655,821,723,587,681,459,752,277,506,636,900,180,25,567,692,368,734,781,550,638,765,824,716,820,520,989,657,70,397,575,72,488,589,67,529,969,528,295,80,637,883,845,138,937,906,139,785,700,472,783,666,887,537,800,835,399,623,383,338,722,17,614,532,982,511,159,725,541,441,117,789,130,78,529,818,655,534,819,948,979,396,988,310,331,719,533,192,912,136,818,578,210,158,853,429,808,211,815,289,493,51,586,189,62,838,781,567,901,623,216,213,73,47,70,872,555,632,577,345,887,501,615,616,919,358,383,25,234,177,346,230,322,726,162,317,708,29,526,877,946,794,39,218,361,983,363,772,489,166,563,238,901,885,276,574,535,551,178,172,78,410,603,749,803,292,687,128,270,650,355,34,534,427,11,604,514,172,927,503,427,92,392,53,482,606,652,828,520,631,610,662,376,925,11,645,544,795,732,677,177,788,723,63,914,130,92,221,185,127,321,656,674,275,221,484,277,83,323,601,645,725,816,764,741,593,157,343,131,909,490,794,996,965,831,557,303,344,661,312,349,915,927,620,794,922,445,822,862,656,862,420,63,990,714,858,66,43,830,951,316,929,687,244,379,707,400,454,778,474,544,818,716,458,878,4,899,596,982,949,492,797,77,925,298,167,198,803,627,177,356,294,865,360,501,285,906,547,488,380,732,695,97,1000,317,209,652,72,536,818,349,893,13,799,85,66,982,171,368,853,813,134,22,834,51,504,484,796,11,60,8,835,962,425,484,364,659,341,375,110,142,618,832,460,514,360,575,26,15,389,578,635,391,218,0,969,906,849,980,520,575,430,306,634,92,496,410,218,427,691,777,372,334,208,771,71,117,880,388,278,849,501,614,827,879,965,867,356,542,407,959,455,182,971,673,581", "528,135,306,882,459,235,48,736,266,854,916,693,457,819,261,286,874,129,625,638,101,572,201,559,343,244,941,233,114,80,702,793,798,489,695,157,921,674,190,80,867,115,955,288,542,582,269,638,500,320,579,568,940,66,66,722,75,234,292,184,744,374,349,140,157,299,40,86,69,648,913,444,970,35,560,974,960,511,443,351,146,593,909,759,200,655,581,20,732,555,169,544,274,320,616,580,813,774,653,593,395,5,141,601,345,165,45,892,487,255,890,292,881,625,362,73,367,485,802,379,122,565,596,357,327,192,103,761,484,738,667,691,468,296,951,70,809,691,499,794,442,448,783,898,436,983,118,756,434,197,62,935,380,281,221,988,213,789,34,451,382,286,528,165,271,143,71,290,335,662,34,406,991,551,850,456,720,196,143,927,43,605,307,524,663,770,189,679,593,9,132,464,332,543,856,575,370,417,214,159,164,137,238,552,912,784,220,299,628,513,814,670,640,253,730,601,105,4,921,218,158,353,659,259,482,786,879,746,974,331,179,519,760,514,643,254,875,429,423,855,251,619,193,937,56,386,324,264,405,61,699,820,335,945,99,77,190,35,608,493,607,1000,164,914,231,343,381,600,272,52,162,438,257,132,453,563,473,720,282,996,851,915,452,370,442,71,133,156,398,347,591,30,359,915,200,313,237,722,441,131,923,875,546,217,982,592,151,683,142,515,902,101,506,351,316,801,626,911,595,309,9,751,599,662,702,366,865,270,324,104,596,132,548,241,749,309,488,133,303,557,672,491,826,961,666,64,890,71,134,912,502,715,514,73,783,538,299,504,155,115,903,216,472,767,92,784,960,119,720,487,678,42,316,130,979,887,911,432,29,156,931,572,371,812,609,195,586,654,398,755,318,918,527,29,274,948,303,654,327,298,947,311,48,471,514,899,111,952,413,456,688,913,771,274,467,678,642,990,164,252,502,654,785,895,295,869,686,492,366,998,393,87,139,494,834,246,365,374,628,713,248,358,846,986,676,667,369,572,623,833,842,892,527,208,34,280,40,702,508,589,457,626,603,223,457,688,873,515,8,569,325,567,615,216,655,357,666,469,739,782,390,230,981,309,322,805,144,444,496,129,236,792,108,278,46,589,352,591,284,315,61,477,198,474,732,973,674,893,489,170,741,438,99,751,120,238,673,97,535,237,359,954,728,848,520,84,86,420,755,107,222,701,45,987,360,124,61,895,701,242,457,861,965,960,456,399,71,287,215,772,168,543,351,333,745,468,80,40,881,628,776,345,112,834,533,93,326,576,909,217,285,726,652,779,471,823,411,922,329,892,271,569,364,974,424,416,302,305,672,678,543,442,642,794,680,539,694,661,291,432,391,879,530,238,459,996,71,272,478,798,769,53,791,319,792,524,561,557,213,698,651,479,581,922,844,826,441,729,696,307,717,765,674,134,236,933,952,874,966,298,227,176,37,258,302,925,734,117,664,331,95,93,76,337,918,66,480,296,448,556,740,369,748,181,455,303,953,336,90,869,464,245,853,178,617,454,748,460,270,95,899,531,432,356,716,108,977,656,982,428,891,30,681,26,244,47,388,47,328,519,716,133,784,171,252,310,948,538,870,751,435,41,461,493,449,727,97,155,202,325,489,25,490,782,999,476,603,330,847,103,614,635,591,301,503,995,922,449,652,734,420,192,664,296,170,251,706,638,649,115,104,869,702,899,781,784,714,467,222,273,131,949,764,18,945,771,641,376,812,834,779,525,227,133,549,981,723,887,148,725,346,499,344,614,360,753,901,620,935,471,604,826,611,948,452,348,500,631,448,491,373,816,704,739,513,458,975,770,565,622,248,686,968,245,410,934,962,144,426,396,920,217,606,364,30,550,250,467,249,962,605,758,571,838,721,317,553,646,604,14,745,214,36,2,595,808,995,57,903,306,557,242,699,575,322,562,318,632,628,686,919,281,777,956,641,519,568,251,479,469,911,554,23,902,364,963,377,821,331,44,926,648,773,184,501,303,208,117,189,40,591,588,301,322,642,633,418,649,799,813,564,951,929,284,223,955,126,897,817,668,848,367,330,449,409,770,701,122,418,338,929,103,583,846,187,864,567,697,151,219,992,221,326,34,935,14,355,333,81,852,398,117,829,248,23,643,529,345,736,378,471,607,841,993,285,808,372,629,969,0,695,986,365,205,858,142,378,180,61,547,395,89,588,612,493,137,720,986,5,216,982,718,254,884,214,217,751,343,129,110,572,473,562,826,674,920,917,744,743,632", "912,99,220,169,142,332,912,13,228,294,845,208,644,677,620,112,610,751,247,124,127,745,384,845,539,136,712,96,539,789,747,675,514,468,854,377,69,171,707,9,526,651,9,811,487,5,326,986,476,112,517,140,642,735,55,495,565,371,839,798,619,414,857,201,920,170,864,983,725,910,34,613,233,983,710,302,887,666,227,734,876,58,467,918,855,289,341,180,846,987,668,352,360,174,917,53,970,817,642,482,19,548,238,34,985,276,992,242,620,528,403,82,484,711,980,603,966,754,780,62,537,475,632,739,937,128,761,35,180,255,390,869,534,186,975,136,47,33,533,668,870,166,795,180,638,801,334,577,170,853,444,748,871,908,265,668,444,342,47,931,676,850,697,614,917,311,428,693,448,910,949,947,704,312,653,750,511,661,529,355,763,964,795,891,48,446,214,961,153,929,391,95,429,953,46,679,736,658,298,883,788,847,410,947,316,567,324,732,569,743,643,748,543,836,650,995,617,428,191,329,28,97,630,474,673,124,16,382,112,434,127,372,990,292,656,224,110,242,660,597,954,550,686,703,657,585,67,483,241,875,852,749,187,392,678,625,801,379,821,390,175,974,555,664,850,711,941,59,681,743,405,220,142,814,453,172,772,916,800,553,517,680,686,654,387,534,833,864,783,899,897,69,893,833,893,372,207,329,39,409,970,657,202,652,234,148,775,223,744,617,358,390,902,275,566,763,534,850,714,600,744,680,916,933,723,571,140,928,65,43,239,792,207,701,496,300,6,781,235,349,336,965,682,24,465,66,826,500,508,365,563,639,928,267,889,884,62,987,125,699,185,169,245,897,241,673,452,374,2,571,95,19,639,529,374,530,867,923,620,532,29,816,524,918,557,798,576,575,254,387,596,7,224,883,957,517,95,329,255,175,243,94,565,667,38,78,508,80,579,291,410,987,525,92,65,550,597,294,657,820,815,493,606,685,988,22,309,845,363,617,742,149,582,320,107,364,503,601,527,682,21,493,324,845,940,49,828,744,214,343,695,890,286,801,307,537,480,843,306,645,453,836,201,335,139,263,488,560,953,728,255,361,183,524,854,394,284,257,962,328,733,727,156,680,124,90,822,889,401,97,955,502,929,700,519,359,296,474,19,928,792,76,599,196,704,26,482,814,421,544,248,477,311,70,421,510,568,538,692,422,127,868,611,986,610,786,909,434,237,959,903,151,154,646,81,51,558,9,190,180,808,387,437,31,748,682,913,929,285,887,985,562,833,420,369,391,327,884,652,770,671,303,246,349,891,717,903,509,586,902,316,832,431,640,919,709,677,391,673,947,319,101,159,323,210,580,693,435,397,717,949,943,418,855,907,340,195,919,383,861,812,628,257,708,45,415,316,885,390,862,888,579,157,836,544,717,761,918,386,323,117,591,761,857,244,761,861,734,504,764,563,310,689,533,844,494,792,377,290,938,971,389,811,966,722,262,90,301,271,561,953,381,337,231,406,13,330,39,600,626,946,497,921,889,384,348,268,185,239,565,887,174,38,502,195,217,746,462,427,316,890,148,801,45,618,292,319,813,153,616,849,461,316,576,617,404,41,909,988,345,950,96,88,194,214,897,514,492,265,879,951,763,619,256,145,13,346,907,863,804,963,485,679,657,570,434,725,518,588,29,582,358,638,684,278,793,568,584,816,821,235,311,113,968,411,88,335,71,64,636,938,642,268,473,447,70,606,964,732,780,338,784,748,679,464,646,176,425,825,212,823,627,679,567,797,284,353,375,317,969,340,334,296,722,717,696,162,89,212,728,774,62,335,762,238,728,839,242,928,39,812,633,714,927,847,517,647,686,719,813,430,366,207,675,159,313,158,377,350,217,196,821,684,872,663,385,178,687,903,59,727,106,11,214,493,810,807,105,149,387,344,775,945,528,724,673,160,423,152,913,10,800,86,923,734,595,776,409,290,236,838,944,111,530,442,858,527,814,802,993,109,618,337,85,784,936,851,854,525,830,749,462,554,623,799,58,671,80,593,182,864,521,909,193,65,569,976,769,552,413,508,504,358,343,132,47,403,140,489,850,134,78,871,879,406,817,979,864,697,556,700,515,336,819,575,54,121,763,138,537,39,970,48,629,87,754,356,571,178,221,474,628,766,871,516,213,72,494,491,708,289,102,696,434,824,640,494,178,906,695,0,429,869,958,546,509,461,86,225,610,690,605,107,352,158,895,158,894,275,35,644,605,260,638,156,377,798,502,118,393,429,67,207,263,740,93,826,630,195,883", "260,321,434,220,19,30,516,397,148,998,821,488,403,115,973,676,232,383,222,296,508,866,613,41,294,448,723,213,955,604,32,447,854,802,554,554,173,267,422,979,550,887,154,491,282,308,816,798,636,376,700,676,521,568,425,225,817,109,759,256,516,905,419,279,923,123,854,861,31,681,686,32,722,63,895,179,876,422,714,345,102,24,884,187,177,887,120,345,621,347,323,435,923,444,277,357,903,445,276,774,582,292,979,325,219,614,440,474,265,287,547,637,282,94,532,923,347,524,975,661,709,823,121,363,759,466,867,227,928,485,481,389,408,370,572,173,725,360,639,37,288,234,901,149,805,826,393,957,417,211,709,894,477,897,224,615,686,381,21,377,828,178,426,472,467,33,212,56,869,760,377,272,517,983,120,637,960,645,213,229,342,837,764,615,214,880,657,139,105,77,141,638,677,207,421,231,522,934,950,620,249,173,447,377,108,98,465,960,906,178,251,217,414,368,71,926,261,240,785,319,224,241,462,889,830,290,737,101,676,867,790,411,899,448,432,75,200,25,725,995,657,40,863,324,842,559,95,448,361,714,238,605,637,247,155,268,192,688,358,303,127,454,528,313,566,314,157,682,350,718,282,419,646,214,140,253,52,364,294,174,474,401,60,238,124,394,733,521,709,950,678,276,855,738,932,468,168,574,202,99,234,802,412,42,711,896,474,223,441,782,62,550,516,990,84,699,898,374,169,69,669,566,671,520,647,118,360,730,851,12,690,439,857,105,640,417,128,645,397,171,747,617,878,452,640,146,485,235,686,630,329,629,634,245,433,913,407,208,751,875,319,865,568,118,977,738,513,968,936,980,977,993,437,844,348,879,618,615,623,310,443,88,672,508,651,398,743,624,224,479,435,942,373,332,107,138,28,794,946,27,336,828,904,300,216,810,484,30,492,106,802,52,500,405,190,171,920,817,687,954,633,42,902,311,631,599,162,734,862,153,736,666,472,56,853,618,307,570,758,737,52,225,580,915,284,648,866,25,424,15,90,19,118,700,676,573,617,307,216,849,36,915,320,106,771,616,159,642,130,29,726,907,582,567,70,397,585,34,201,759,373,871,817,416,30,606,789,761,822,193,603,529,303,618,508,468,205,493,922,910,801,814,54,967,378,829,329,74,764,193,688,816,354,79,443,219,455,621,740,90,849,667,271,168,554,816,209,790,57,657,556,977,936,116,448,695,808,988,697,44,200,338,320,689,816,633,95,149,34,24,296,196,851,686,792,451,990,842,663,226,344,169,280,630,658,211,13,273,734,726,99,967,202,101,957,116,183,425,408,32,380,199,613,165,839,238,468,675,993,631,276,902,245,830,102,357,378,120,471,659,545,596,292,634,903,736,69,215,166,779,940,604,733,400,431,849,275,611,974,670,713,377,486,382,626,399,537,181,958,485,986,376,885,375,101,646,541,862,705,883,90,367,24,271,11,179,713,153,753,292,286,175,36,26,880,324,873,632,532,906,644,980,99,175,950,74,211,107,51,526,742,627,11,937,701,110,200,313,610,327,942,632,721,441,951,945,60,304,615,886,55,918,227,52,247,878,504,532,10,673,320,523,904,186,558,759,971,916,788,824,667,259,310,710,706,116,501,649,283,415,269,719,444,852,938,124,897,787,254,144,114,776,306,615,853,901,443,106,355,958,737,187,714,872,179,935,288,639,213,266,472,503,275,958,34,670,93,9,15,192,795,999,83,30,566,928,940,787,838,762,322,301,242,88,196,639,166,775,185,526,488,815,936,517,331,26,715,439,779,378,544,563,14,81,563,701,938,185,967,50,922,558,772,151,661,490,929,618,942,545,653,133,726,693,97,720,618,249,946,825,367,20,411,83,595,883,645,349,67,465,455,817,450,261,120,432,850,608,250,512,360,657,543,722,982,135,692,988,907,296,4,188,8,113,639,947,483,998,160,716,365,500,837,552,528,256,360,950,597,293,892,389,512,321,987,278,150,70,285,507,658,937,673,655,128,770,314,180,160,162,849,145,757,293,181,652,405,276,795,410,370,557,884,350,614,336,440,992,7,330,498,658,953,595,137,834,350,15,85,994,473,195,75,359,541,807,37,492,979,229,51,791,137,673,780,483,417,676,881,755,876,182,979,110,292,62,633,22,122,337,388,635,520,735,400,556,596,786,849,986,429,0,403,985,671,320,823,676,167,631,754,408,491,57,126,581,171,115,226,256,681,60,550,258,65,368,628,459,349,158,69,619,871,964,997,52,308,776,927,992", "754,450,419,309,826,472,36,207,260,990,164,705,974,499,202,560,255,288,239,381,102,104,883,744,412,186,31,878,564,952,955,782,774,711,829,730,419,686,369,415,308,600,776,288,921,25,272,592,293,124,477,817,418,821,472,493,24,889,956,256,824,652,799,797,280,838,391,566,156,600,986,186,535,186,5,221,654,203,682,255,85,167,818,669,373,993,680,15,717,908,484,78,619,284,222,958,772,976,732,200,421,302,379,501,613,801,191,754,294,290,62,47,78,257,136,380,655,794,591,343,638,557,723,150,501,796,654,464,81,687,679,514,279,133,855,940,276,366,198,742,76,344,441,618,502,624,881,421,725,71,706,994,133,154,406,951,577,438,544,487,683,652,911,630,135,517,13,968,345,519,216,788,20,487,652,302,539,806,92,721,982,430,556,832,245,903,780,210,906,206,680,671,149,967,356,723,633,981,297,743,590,38,706,840,296,445,587,815,815,806,169,764,71,491,928,254,972,440,454,988,278,739,194,728,126,501,553,931,330,622,540,734,872,664,5,785,211,514,261,924,618,663,819,169,374,672,844,277,681,16,988,741,664,972,653,779,766,854,782,144,545,901,756,3,84,948,927,452,455,510,662,318,656,874,991,732,838,765,619,848,367,142,251,275,648,832,423,26,732,45,667,119,312,578,818,278,114,486,670,378,9,248,683,518,425,257,161,456,514,819,821,322,873,480,103,693,524,969,508,785,716,730,653,18,620,659,145,921,926,12,379,163,749,419,468,296,470,547,694,433,426,411,425,842,975,219,654,812,505,936,169,542,867,740,982,996,105,830,838,664,373,120,275,798,282,671,840,188,450,686,888,120,129,25,4,77,320,257,376,681,846,5,528,895,506,202,514,83,871,118,780,972,877,657,768,314,454,791,575,880,459,699,394,245,415,868,793,4,393,826,653,846,451,705,213,251,588,31,988,231,394,697,788,218,718,346,974,512,805,617,33,60,637,29,522,796,768,850,191,229,31,730,585,765,622,228,871,262,617,986,214,434,992,162,685,2,400,363,264,528,683,173,484,191,382,873,352,349,364,550,97,961,881,302,980,632,137,585,11,265,617,756,826,25,664,68,263,149,287,429,504,788,873,80,392,606,201,477,945,713,410,695,398,996,970,429,595,954,788,812,592,760,483,110,41,591,605,598,619,122,329,68,975,818,501,701,238,582,421,32,156,646,202,395,267,142,761,650,361,224,852,277,885,467,889,390,221,301,914,5,944,325,123,186,60,91,313,239,448,492,696,690,16,267,166,578,601,389,131,574,705,790,116,229,921,455,10,828,372,898,522,802,909,610,565,18,262,91,859,164,453,227,80,590,546,738,717,678,942,62,96,360,249,173,815,388,663,598,88,691,264,272,988,633,102,462,655,41,134,219,971,138,458,539,850,856,587,673,174,774,400,592,54,210,291,505,885,753,726,333,687,702,134,249,582,12,297,994,692,782,821,106,364,655,322,974,672,300,248,153,735,718,149,491,835,150,905,368,101,168,391,991,675,437,810,391,843,218,683,713,673,163,873,843,197,216,586,303,505,419,217,741,174,973,551,229,610,689,146,675,693,872,762,252,458,250,893,694,572,328,757,798,675,37,117,387,135,750,942,797,910,330,925,522,68,516,11,209,212,525,117,326,491,546,210,217,560,176,50,754,275,336,307,48,623,468,433,50,544,249,125,336,637,797,222,438,497,778,154,84,234,269,963,455,597,62,713,315,137,970,405,884,496,392,64,817,471,50,261,407,259,624,227,942,734,666,751,227,741,101,48,520,863,410,339,976,193,86,498,101,721,598,215,757,173,331,913,787,747,15,278,62,83,732,715,707,528,359,268,898,621,969,301,980,621,65,678,320,474,93,89,978,702,341,995,712,353,140,740,838,793,598,43,485,344,31,78,619,256,285,579,624,222,10,452,603,33,418,116,886,78,20,465,892,262,550,333,735,532,255,3,867,794,116,645,332,2,961,310,325,816,832,982,317,931,179,320,170,219,739,821,896,688,976,552,252,54,948,34,678,956,483,969,435,567,65,340,88,534,936,353,571,44,500,73,835,482,588,951,753,994,565,789,274,377,112,328,49,441,713,537,425,54,532,170,345,549,160,729,534,52,409,67,146,418,926,361,637,912,551,606,576,98,264,857,324,251,890,980,365,869,403,0,63,948,7,466,549,593,114,825,18,756,762,371,857,172,820,721,455,450,287,947,421,10,61,436,472,230,456,269,720,170,595,793,295,1,916,324,38", "367,513,183,887,580,905,409,848,199,145,599,406,667,498,798,539,977,651,272,607,694,532,674,411,101,747,88,306,511,584,55,431,256,836,41,795,538,745,324,565,263,677,111,198,587,327,249,849,804,592,26,711,123,285,861,229,482,583,405,184,268,332,486,169,146,233,735,501,992,793,239,931,963,442,829,790,135,39,220,680,282,809,644,979,761,25,417,465,241,836,709,489,225,176,656,253,444,746,19,605,699,359,434,837,388,613,958,465,261,447,423,708,394,599,710,345,87,238,76,875,721,630,210,694,695,581,709,788,958,6,100,632,704,706,453,791,981,188,91,872,720,118,519,262,332,230,860,292,308,12,671,239,165,446,864,165,314,372,433,210,500,247,310,749,531,258,29,192,117,354,848,856,743,14,215,908,265,367,65,307,763,401,163,825,829,283,825,388,35,153,859,674,171,342,465,221,319,504,866,261,214,683,988,996,509,286,573,33,512,799,778,346,877,317,600,376,774,160,414,867,322,736,200,997,521,980,225,434,42,216,668,367,457,951,968,761,753,204,479,725,444,287,427,823,715,274,862,215,124,857,94,430,758,533,176,942,724,576,453,308,612,927,887,132,290,83,471,232,685,401,597,270,516,532,734,476,876,495,887,112,362,236,99,132,987,252,510,825,996,372,111,227,251,48,102,793,310,74,428,18,168,979,296,531,879,634,917,938,725,880,153,592,775,675,94,239,542,856,938,693,520,606,664,187,989,489,637,185,778,105,224,483,334,821,436,265,166,903,331,336,872,715,849,921,784,336,767,258,748,651,774,673,537,229,110,527,161,121,580,913,877,576,206,265,271,589,184,223,212,240,839,680,283,168,83,481,715,504,157,431,263,706,704,433,779,772,569,228,375,445,303,81,160,774,585,398,28,500,209,569,315,16,127,680,142,862,163,247,315,552,907,204,55,781,595,431,207,258,603,695,92,502,644,211,384,979,589,423,230,382,766,591,910,790,36,850,807,875,971,126,379,302,925,565,831,924,907,333,787,226,554,239,751,762,497,671,512,246,200,155,507,627,534,188,530,461,39,531,135,50,606,236,354,298,518,265,951,198,247,729,606,374,381,421,205,299,282,271,709,400,22,618,97,413,831,940,547,370,453,108,608,249,205,281,9,818,52,512,120,502,818,58,137,374,447,344,924,898,437,72,410,309,53,944,185,823,380,324,989,184,937,293,32,489,107,198,661,99,166,288,272,84,614,538,891,35,586,83,348,952,743,302,782,32,493,564,815,42,276,494,188,585,887,212,466,389,291,274,169,765,494,584,898,94,787,670,906,438,414,233,871,35,66,325,539,663,67,775,170,354,351,342,71,599,840,539,784,635,547,232,264,453,986,867,123,436,682,103,140,754,970,17,265,720,327,537,428,100,615,839,679,223,774,839,835,957,276,378,491,797,669,820,339,208,963,668,703,340,447,638,199,667,639,349,877,322,243,187,750,190,642,937,184,733,240,737,899,999,589,679,9,77,208,918,515,321,146,247,118,603,960,124,395,546,310,162,41,516,214,571,798,291,488,839,447,521,219,31,900,331,398,916,637,783,828,973,838,202,516,690,623,460,378,513,671,897,561,48,184,978,798,379,285,124,685,102,2,11,555,642,916,264,308,789,224,660,945,141,435,720,754,525,431,359,854,321,817,380,771,107,678,691,345,410,370,591,593,115,923,30,679,156,122,859,179,267,94,863,193,498,155,371,471,103,481,559,688,527,390,199,918,884,293,204,811,288,492,683,657,634,482,898,684,750,72,740,455,323,318,515,423,669,5,222,958,328,788,864,954,952,168,555,452,773,692,892,708,159,186,628,999,334,723,483,469,519,20,885,83,759,251,515,86,17,847,459,534,233,802,648,186,424,671,293,279,685,15,218,577,815,402,931,262,814,337,574,567,25,230,820,639,943,763,968,152,749,803,850,312,737,269,955,706,973,239,463,840,692,616,12,49,149,562,22,561,46,146,160,670,774,717,79,419,584,627,303,830,322,331,283,883,454,431,652,742,878,849,159,339,237,364,326,975,694,721,408,644,862,983,218,436,466,816,175,989,259,366,9,339,369,281,49,653,176,445,41,27,783,688,939,519,510,876,288,341,559,330,588,210,406,921,943,660,739,984,883,753,658,22,955,786,88,647,621,868,300,335,18,520,205,958,985,63,0,630,701,805,185,560,214,532,584,53,676,591,248,488,531,466,282,943,718,922,270,557,156,676,960,413,83,408,647,283,697,472,5,259,336,974,67", "8,70,307,270,833,503,138,49,11,654,798,56,413,969,280,693,249,600,712,440,98,265,231,593,976,885,214,2,994,94,544,105,151,571,764,770,947,947,824,531,858,655,819,727,94,226,174,144,660,207,286,296,654,515,204,58,813,171,424,109,959,688,132,879,931,47,282,687,878,573,379,523,665,319,759,238,434,234,124,513,242,119,647,900,254,816,752,758,814,227,356,606,27,168,462,947,351,330,388,195,384,792,240,812,683,992,111,772,245,857,687,129,520,478,873,578,471,62,109,924,50,822,399,878,635,74,925,717,476,559,435,17,690,123,92,715,256,531,320,72,605,173,80,438,45,879,652,719,639,744,706,542,643,829,471,465,112,407,473,945,268,485,784,649,659,242,437,325,253,46,924,209,163,276,266,280,906,882,762,479,504,607,423,485,918,715,328,895,201,154,687,584,805,713,898,620,993,394,726,581,939,374,250,126,425,799,380,540,535,821,163,99,811,530,255,821,979,993,319,971,72,724,620,308,898,526,644,963,629,212,329,176,423,4,11,258,705,96,409,560,646,371,157,647,859,608,643,934,356,934,656,683,217,167,766,19,49,819,643,950,713,891,705,511,657,879,87,630,482,762,266,881,654,577,925,435,231,665,573,654,807,597,581,192,749,911,295,245,103,976,834,727,600,768,19,249,449,87,363,298,731,842,333,79,322,329,664,830,446,248,484,201,806,536,545,958,418,312,346,819,223,725,780,991,62,843,6,618,615,885,629,249,611,224,193,952,17,498,689,196,575,960,269,690,301,993,904,728,654,161,835,409,484,594,896,551,2,220,905,31,702,419,664,76,316,653,521,116,634,478,150,242,510,242,869,801,140,369,598,639,848,576,488,542,27,252,816,550,581,607,464,109,81,655,968,280,150,810,944,755,992,422,696,773,737,18,901,477,34,292,399,927,911,586,414,907,774,532,997,654,159,868,657,821,272,752,875,523,439,26,838,425,685,307,773,895,620,96,174,879,225,355,896,400,984,773,284,655,446,63,438,540,267,167,72,105,834,469,880,497,468,305,291,232,163,734,38,630,490,826,939,642,837,606,295,353,250,372,434,307,469,571,242,171,286,92,902,811,150,964,135,202,224,140,32,836,682,234,533,53,584,13,771,680,729,955,396,305,722,631,544,380,454,773,223,877,168,175,367,763,106,574,717,757,348,348,50,628,446,535,816,787,899,223,308,347,617,788,969,34,350,890,321,809,110,426,925,79,206,438,502,404,575,453,490,364,539,18,572,161,888,614,44,677,736,119,633,87,235,748,624,715,988,935,607,472,82,807,865,71,723,647,88,932,301,874,870,440,602,933,971,308,364,359,591,865,106,709,47,739,431,870,907,306,565,730,339,908,367,136,746,637,400,137,275,69,488,125,503,34,958,890,588,616,181,955,506,125,165,166,741,309,835,624,738,888,840,873,51,992,325,496,436,143,861,942,270,247,565,455,28,626,625,721,522,371,71,608,186,418,547,2,122,637,656,953,316,318,606,116,116,671,530,508,620,955,459,816,456,694,951,137,188,565,535,69,811,760,911,382,748,103,985,403,499,326,336,551,30,552,309,51,869,343,971,8,472,755,801,412,93,687,858,277,516,805,139,846,153,615,51,630,317,622,928,69,2,54,463,3,761,292,424,431,670,945,900,651,199,450,673,525,913,681,426,176,157,548,591,944,742,103,267,202,479,779,191,533,154,647,535,585,261,559,941,506,731,54,267,809,17,692,828,162,698,599,670,6,272,352,928,203,178,340,987,607,238,972,445,696,825,720,199,886,812,178,761,464,778,83,526,522,261,63,70,931,485,630,220,714,94,654,873,553,463,969,898,404,982,592,198,566,446,708,500,966,492,429,477,755,30,807,950,59,975,614,259,528,227,887,751,95,740,696,92,992,361,736,981,162,638,778,921,916,361,641,740,488,736,294,220,682,542,333,97,425,906,658,337,943,557,511,205,250,337,807,198,542,509,20,407,769,775,487,445,100,517,258,606,284,918,709,718,746,609,733,112,610,268,957,487,427,698,677,45,147,985,773,308,412,809,177,488,642,170,71,47,745,793,94,789,353,131,859,514,691,751,626,400,351,605,550,23,137,958,383,462,440,52,789,67,835,962,86,699,283,493,539,532,14,839,895,712,433,259,55,704,355,575,858,546,671,948,630,0,308,293,851,225,738,280,713,618,189,376,513,432,501,25,314,629,866,60,120,515,955,738,859,411,267,63,161,711,205,681,766,467,932,420,688", "301,896,287,963,483,385,140,962,219,829,484,663,189,38,742,885,416,814,857,765,530,554,945,314,387,560,64,537,59,449,25,351,402,762,287,981,278,541,505,201,648,705,857,141,907,693,440,719,657,550,433,362,397,967,344,234,821,361,30,562,560,353,704,643,891,508,519,829,873,3,452,291,872,693,364,61,328,694,961,136,761,852,992,858,416,303,674,293,320,954,938,768,183,540,983,513,965,108,535,326,989,613,902,973,61,723,254,114,526,37,753,130,972,526,447,551,784,380,896,678,474,864,429,973,215,537,576,273,584,597,144,101,112,765,302,257,349,103,740,191,249,468,602,878,335,162,199,538,147,294,52,805,409,633,451,308,621,343,537,521,882,145,975,961,31,479,62,717,918,441,888,43,688,820,760,768,915,144,974,473,776,985,329,923,391,519,719,982,647,420,784,295,136,300,637,976,125,263,81,155,754,930,209,56,690,76,643,186,933,697,507,935,962,584,395,946,604,506,209,759,22,481,106,439,227,583,382,509,236,905,734,501,487,138,342,911,962,983,410,275,476,712,476,716,823,82,888,866,583,155,758,140,460,330,534,715,231,287,159,557,835,518,421,401,434,547,155,813,722,173,564,564,128,589,525,594,25,363,389,868,870,56,414,2,739,713,804,330,467,921,924,477,92,444,404,298,910,168,824,444,231,452,879,93,790,375,743,955,891,458,783,642,307,113,847,297,594,620,28,247,584,73,143,442,836,142,934,237,67,72,678,373,855,367,487,881,586,169,505,39,764,739,837,117,319,715,185,398,460,293,789,633,35,739,902,557,27,145,854,409,37,179,183,681,11,642,215,437,141,444,624,272,448,127,557,39,568,964,537,15,738,672,222,724,157,900,31,63,926,243,597,314,789,249,361,352,775,879,979,674,350,838,416,245,102,309,192,520,981,14,310,12,926,332,524,473,989,859,801,686,897,589,964,796,48,962,972,997,947,101,744,167,166,358,284,357,359,364,795,15,792,878,131,300,196,500,406,456,636,301,427,760,912,488,274,47,173,546,122,2,183,92,106,363,185,653,753,683,650,799,923,668,792,378,882,977,119,161,493,997,804,984,270,604,900,68,495,830,322,930,849,675,592,541,548,327,84,576,905,555,627,819,111,501,666,858,717,759,985,738,349,118,105,351,995,597,995,104,918,595,453,574,936,971,91,42,321,610,47,519,543,24,898,11,945,293,750,948,693,232,536,284,309,786,246,744,760,414,448,967,66,114,660,965,601,20,424,459,875,29,484,398,364,731,295,362,821,93,590,537,832,967,26,923,88,913,74,935,426,948,561,841,646,984,318,116,929,519,158,573,382,381,32,995,856,350,622,68,307,451,684,971,126,506,447,103,70,636,168,442,171,44,841,961,156,182,620,365,840,795,517,503,986,120,663,478,22,119,724,186,360,657,766,166,393,321,674,492,247,437,134,200,27,204,448,276,920,655,448,884,221,905,846,22,220,863,400,937,49,460,573,698,405,87,359,28,319,470,221,401,478,353,765,792,882,952,142,955,718,961,132,978,275,849,911,843,545,710,760,857,799,79,498,876,875,58,421,83,168,323,455,374,597,129,709,650,387,882,201,108,239,71,2,423,666,975,309,695,794,340,515,192,145,802,114,767,503,786,827,875,704,721,624,393,799,797,1000,759,377,118,184,56,120,927,814,719,87,335,598,617,907,592,662,245,869,328,571,903,868,513,852,683,779,898,795,490,695,575,703,989,919,73,771,416,4,876,217,6,765,592,604,822,507,468,212,945,625,310,475,726,728,909,656,277,163,183,428,885,403,393,908,317,729,487,347,982,265,562,296,458,354,233,213,792,811,159,67,192,465,909,511,65,658,879,817,611,810,162,344,191,551,188,786,774,115,866,638,347,588,807,161,219,87,331,246,540,275,13,446,718,252,212,469,649,937,111,386,276,326,712,606,806,42,214,720,188,274,185,236,63,11,693,296,468,532,490,945,768,506,868,875,201,270,152,67,183,143,996,993,751,6,254,654,357,237,997,64,880,533,972,559,903,478,319,148,933,682,913,755,98,609,616,316,490,927,463,689,371,272,991,422,278,667,606,706,980,387,153,439,123,585,180,192,166,722,2,323,463,155,22,744,667,858,330,363,253,953,258,490,167,543,565,238,808,601,366,779,662,430,142,509,320,7,701,308,0,868,820,889,315,353,615,683,48,89,712,881,514,175,704,765,556,903,475,875,440,996,764,954,365,571,65,359,426,213,98,620,263,866,798", "917,564,216,648,779,772,70,893,609,815,124,598,503,709,940,809,690,680,769,937,562,200,549,470,238,414,274,899,859,683,422,363,104,760,353,128,877,615,301,336,475,823,395,973,134,452,396,328,642,674,386,169,582,832,208,743,319,522,151,986,511,857,309,716,737,603,766,730,869,253,670,476,314,585,293,188,188,929,287,51,399,83,882,604,973,258,563,822,864,193,33,135,90,386,317,321,407,175,116,484,448,229,732,783,240,827,29,595,38,417,246,718,378,633,577,686,489,655,334,46,202,132,26,144,257,61,414,591,326,366,643,333,767,431,671,523,802,213,311,121,374,775,855,143,410,337,188,741,705,248,778,490,734,774,803,907,323,450,307,459,340,161,187,386,933,152,624,195,331,36,145,657,505,954,106,172,505,127,192,936,316,641,828,398,913,909,328,848,6,971,228,519,543,794,866,788,830,554,39,112,12,299,158,299,782,532,422,859,730,678,934,52,916,703,893,352,441,16,53,809,474,17,794,488,322,860,860,589,33,765,170,953,463,628,184,839,199,314,537,118,525,644,214,832,720,441,862,210,978,682,239,895,212,95,322,381,36,958,414,729,315,877,54,390,365,841,274,452,525,610,803,916,150,228,936,399,979,735,762,253,954,526,625,112,843,307,136,351,870,790,657,979,37,862,97,614,647,752,153,444,63,759,94,13,450,295,235,244,898,945,27,692,392,622,589,766,721,59,833,440,886,104,741,187,62,353,803,935,301,806,936,343,189,418,927,15,520,523,419,529,997,500,388,212,691,643,978,76,499,697,596,691,180,424,867,167,48,468,588,627,934,717,104,591,746,143,893,254,722,822,128,302,678,602,350,269,633,937,548,428,452,326,374,359,98,400,927,904,527,925,198,75,409,417,257,804,460,735,276,65,498,494,41,173,812,936,537,607,637,461,604,640,235,349,965,650,365,420,314,142,216,90,956,315,7,225,760,147,593,978,936,206,676,752,383,497,91,782,277,873,428,984,460,600,295,278,299,311,701,774,517,13,327,773,340,819,173,600,821,260,940,991,609,516,736,956,331,142,397,303,749,795,807,368,596,218,286,99,480,950,465,393,914,264,262,875,716,353,801,710,900,652,303,428,448,396,569,453,591,703,304,678,614,663,928,607,49,469,839,732,446,728,733,694,578,525,646,267,358,122,461,804,169,751,277,998,241,895,821,232,595,463,364,564,946,213,165,964,555,638,257,218,101,765,682,321,564,468,91,994,544,299,517,708,612,953,530,587,610,129,250,344,702,808,81,344,824,785,607,503,156,40,283,213,340,928,497,438,558,932,986,228,277,806,162,613,32,3,153,538,846,159,968,217,411,740,777,291,778,650,81,826,848,636,561,877,5,976,645,695,85,29,671,188,128,77,605,964,690,698,941,445,638,837,959,319,198,141,737,813,930,736,60,854,525,62,723,702,90,467,744,245,2,391,628,324,424,542,807,168,55,601,23,605,179,885,464,649,513,444,757,847,426,544,390,195,763,447,269,574,136,887,951,806,499,426,186,674,564,437,810,718,714,923,471,710,482,779,213,926,775,590,804,721,301,252,942,523,979,14,689,703,826,379,593,349,814,635,12,45,259,692,504,275,443,99,374,727,892,675,85,185,940,522,417,459,792,395,292,911,110,599,264,89,628,290,681,547,276,439,364,942,968,845,71,188,922,610,439,170,329,519,917,829,837,470,926,681,525,449,502,812,633,48,316,296,956,87,502,200,691,402,61,429,484,770,104,473,769,973,115,749,800,27,417,891,385,261,995,56,86,896,906,415,516,414,434,572,989,389,982,484,859,277,548,902,407,930,593,312,409,980,903,946,563,746,379,945,696,289,764,12,921,111,588,149,133,717,614,221,901,984,137,740,552,91,890,263,866,618,715,534,19,881,743,383,258,540,618,899,486,866,218,44,462,658,657,951,173,316,888,489,746,959,251,453,927,861,725,402,372,789,312,796,821,573,671,440,373,500,209,286,553,942,431,964,10,143,758,326,252,247,938,361,54,453,929,739,147,171,899,881,752,256,958,803,834,93,745,823,887,914,577,332,933,486,833,94,296,551,23,332,108,980,801,621,603,371,282,303,144,676,721,70,323,550,361,114,418,748,53,568,680,786,793,420,438,90,497,582,634,859,886,149,515,914,844,421,306,378,461,823,466,805,293,868,0,378,702,357,614,211,308,911,237,672,839,141,759,497,348,53,722,313,393,123,904,241,499,179,723,680,264,978,314,482,348,634,783,721", "351,677,258,658,982,467,5,761,973,627,467,72,755,409,912,652,522,916,101,969,1000,3,860,428,354,906,716,393,441,470,102,571,400,593,725,861,618,411,175,98,593,414,766,384,336,890,9,693,763,930,20,794,126,169,546,166,762,74,757,385,286,366,193,874,538,552,761,810,309,258,111,886,782,128,357,195,335,106,921,441,671,792,632,408,49,589,112,716,616,298,746,106,803,387,172,278,524,65,60,349,55,110,855,912,407,908,827,289,960,352,279,657,792,320,750,453,759,490,83,41,327,879,118,444,523,384,42,159,311,356,552,866,675,830,948,180,434,930,392,254,902,370,251,832,591,482,771,970,105,172,522,588,898,592,531,497,785,281,730,569,246,424,988,578,701,288,226,26,407,252,935,384,751,2,404,233,195,8,307,226,997,921,647,989,18,50,839,698,996,688,742,675,626,859,704,170,40,718,551,496,776,52,386,582,542,898,854,340,922,250,759,149,289,787,910,745,741,255,197,273,168,956,101,93,223,131,519,250,404,857,637,740,160,394,357,87,49,687,782,951,658,397,740,874,24,208,359,504,22,448,203,430,575,102,593,311,434,129,626,992,746,786,42,463,682,373,100,96,34,39,401,299,160,163,749,134,926,102,144,187,833,585,265,100,253,405,85,930,455,307,496,682,805,254,132,551,915,331,904,707,799,344,506,256,142,336,626,206,2,774,701,880,289,794,1000,857,61,238,529,149,278,644,418,438,850,555,271,135,737,251,471,889,800,815,273,112,510,997,280,445,775,86,356,366,54,578,490,333,824,288,307,689,67,615,428,659,184,760,653,535,845,228,158,414,356,896,879,902,450,419,245,231,60,84,891,927,512,111,303,105,373,345,30,820,686,89,709,177,530,56,909,399,604,326,3,431,359,990,488,648,758,121,615,401,161,103,499,495,793,761,707,260,773,42,786,63,317,636,388,7,710,791,211,865,865,623,739,517,117,339,324,217,310,218,338,759,522,862,425,559,64,584,380,121,683,239,456,161,34,278,65,96,180,362,945,418,610,821,472,313,720,125,346,996,38,75,219,526,898,391,718,531,690,728,231,537,237,431,9,384,714,15,476,878,902,38,405,875,668,475,738,319,864,383,948,90,129,171,826,889,541,228,103,551,923,716,856,92,811,72,891,87,410,601,60,729,882,787,812,854,35,741,817,82,346,210,289,569,671,646,157,857,76,31,402,800,197,376,872,433,270,756,750,393,905,428,57,895,643,896,411,470,218,857,23,498,179,955,468,62,823,509,479,507,724,575,316,264,77,557,660,144,695,729,114,85,36,265,667,1000,313,530,567,941,611,60,173,113,463,275,512,751,981,130,747,58,635,661,594,701,747,428,335,720,853,854,774,391,821,372,883,70,797,295,945,462,453,961,580,743,137,17,13,822,891,107,808,46,798,729,402,525,153,859,62,525,566,537,99,979,873,619,137,9,761,993,433,217,30,359,661,248,939,960,682,281,344,770,553,911,620,788,740,859,245,859,970,704,651,481,459,147,260,236,500,301,520,130,737,896,396,738,227,67,268,250,719,797,399,178,831,860,878,228,434,982,714,260,371,918,932,992,675,406,315,489,244,952,611,669,863,680,837,935,217,261,619,716,86,41,874,448,306,999,486,619,381,17,594,620,591,170,867,909,699,909,809,361,921,572,670,282,319,261,568,805,428,136,97,998,246,534,810,102,833,423,404,815,839,543,862,166,917,103,45,104,617,398,335,461,149,736,193,556,790,247,127,694,820,932,210,203,444,429,471,806,564,50,991,382,162,385,582,973,306,500,590,67,956,190,785,861,844,669,131,543,588,724,533,804,292,419,10,259,791,710,255,636,940,686,274,383,687,156,904,242,84,941,980,484,114,800,296,201,786,860,565,579,449,793,81,369,722,758,15,847,109,333,494,944,996,56,794,66,982,997,270,755,584,940,782,156,659,603,327,999,430,352,118,694,97,384,971,512,439,866,204,450,750,136,856,610,269,231,420,515,235,162,745,739,52,106,838,605,952,774,301,859,802,448,958,649,156,291,130,31,586,761,161,585,341,992,197,143,728,171,216,481,719,652,867,180,675,473,632,61,926,845,981,469,17,107,780,693,780,159,567,342,226,220,453,479,198,169,586,281,902,718,682,919,720,973,289,174,915,674,752,288,634,180,86,676,549,185,851,820,378,0,372,332,497,92,731,885,190,104,974,482,810,511,954,267,886,686,722,671,68,664,445,802,294,136,347,618,369,785,751,442,459,247", "988,490,162,221,61,9,354,467,647,578,240,349,875,327,48,326,800,515,273,606,88,86,263,77,94,228,392,861,546,582,287,456,677,534,674,839,2,306,303,870,111,643,976,270,453,620,6,193,273,269,856,815,295,951,165,885,307,726,820,781,960,226,174,329,915,244,17,864,781,155,371,234,12,408,751,729,64,646,210,21,897,697,772,919,556,8,178,4,766,479,509,7,169,66,868,425,344,170,557,372,889,327,278,635,940,504,871,452,476,804,969,222,237,747,499,111,355,480,788,135,250,662,250,264,907,577,983,810,100,866,487,372,82,804,329,829,255,914,733,836,495,235,350,939,937,906,627,992,993,252,2,839,604,243,911,484,342,209,736,125,488,733,47,609,392,941,530,834,498,504,96,87,356,185,408,515,966,401,765,334,349,913,864,429,211,832,348,142,613,662,374,123,366,668,383,603,112,896,756,65,656,487,640,5,381,127,226,834,37,500,833,284,229,628,524,132,699,831,402,156,768,736,652,814,324,801,515,548,885,918,110,552,653,808,242,304,642,240,801,299,428,366,726,714,281,902,874,404,721,111,187,489,148,604,301,80,469,979,314,556,635,10,115,779,115,854,323,777,247,626,352,737,248,801,898,504,91,548,730,570,454,56,234,716,875,427,498,584,889,569,732,662,148,706,279,178,346,910,344,280,930,165,340,161,652,616,194,214,938,607,746,721,581,567,451,500,250,602,995,966,262,52,111,660,332,914,430,292,388,721,146,575,154,352,520,2,466,162,304,194,185,629,567,210,524,937,695,315,707,596,393,885,784,145,466,906,435,4,345,697,732,577,218,331,818,793,410,313,184,88,772,526,463,548,841,763,891,635,318,370,821,897,764,599,278,269,938,975,854,644,38,604,896,138,1,45,204,646,696,746,459,567,548,262,463,763,280,504,316,435,936,677,121,171,127,316,81,531,215,56,939,652,447,684,895,708,426,131,627,3,793,687,117,877,720,878,228,732,46,444,943,427,486,415,38,791,988,957,503,745,703,236,281,13,242,452,234,774,724,248,426,159,427,344,540,229,205,615,672,277,11,661,951,955,36,286,607,244,462,182,908,269,159,872,739,898,165,365,365,200,209,100,490,869,791,773,306,421,901,353,684,7,194,467,526,76,539,222,181,418,395,750,779,688,159,759,304,76,924,842,762,97,336,168,477,330,5,99,198,816,736,480,771,77,9,97,932,110,811,180,136,940,119,470,317,441,19,420,301,257,530,600,872,698,494,401,502,481,562,650,927,339,458,934,784,612,543,615,142,525,684,24,764,655,961,962,784,57,239,534,530,700,282,338,526,909,374,988,401,889,414,489,482,799,33,671,842,523,760,108,60,976,309,4,656,518,635,108,282,751,663,826,433,350,292,414,388,791,584,7,703,363,214,81,805,785,735,616,124,578,621,375,897,679,502,719,766,901,796,818,165,520,306,282,784,700,261,173,939,859,412,272,40,127,145,696,621,403,174,800,12,151,943,494,672,211,446,624,941,251,108,676,100,902,804,160,66,995,297,183,386,282,18,698,951,743,503,418,501,691,943,669,847,39,616,400,284,747,8,56,102,436,539,774,347,363,257,411,737,720,242,793,159,425,713,525,476,637,712,204,311,158,700,594,187,415,472,671,345,590,215,518,439,142,312,591,372,837,906,176,60,4,403,335,791,563,916,950,992,95,417,813,623,37,87,837,711,315,834,945,820,678,795,127,381,708,690,436,425,987,254,699,332,927,949,975,460,280,542,13,691,938,108,829,750,873,974,664,219,61,190,989,967,154,864,631,341,36,399,113,895,320,680,710,333,587,376,156,177,864,33,595,481,211,937,669,66,506,693,985,302,774,953,134,46,86,715,971,814,228,966,468,828,486,314,128,280,369,273,104,249,25,455,453,541,743,913,125,608,81,647,339,764,516,136,150,369,400,858,562,403,204,247,346,93,98,965,357,786,391,374,531,242,849,280,385,357,204,296,306,541,899,655,584,222,890,33,389,426,282,357,206,448,885,779,444,416,915,249,838,488,426,234,397,642,583,717,900,963,830,99,664,604,990,277,472,164,971,646,133,834,142,492,256,466,956,846,442,100,915,960,587,650,243,249,185,833,894,360,967,830,483,86,654,103,932,873,162,978,873,514,166,478,669,336,694,864,78,92,61,225,167,593,560,225,889,702,372,0,684,349,126,61,79,143,530,210,303,857,16,126,201,153,206,194,712,714,722,493,713,113,604,92,180,444,986,895,747,819,91", "696,703,249,396,449,739,319,112,418,142,778,515,903,974,769,924,955,334,753,655,413,246,828,137,494,667,486,533,549,84,842,832,434,681,751,917,98,251,679,809,662,758,655,793,755,926,834,955,712,791,449,579,605,799,395,61,253,495,626,216,489,579,369,86,718,2,147,876,925,333,60,49,742,83,939,87,468,753,631,698,484,45,166,104,856,130,460,487,597,813,71,808,348,660,667,375,581,735,909,962,517,350,326,821,816,143,312,302,121,291,217,226,350,52,784,53,3,219,354,156,919,798,919,337,827,552,842,220,945,726,235,153,415,390,33,442,72,61,224,828,374,886,339,211,195,339,264,731,795,574,152,207,770,735,54,12,817,160,534,863,143,502,306,977,651,130,799,753,514,374,53,348,486,104,397,120,909,341,959,35,604,788,849,880,154,519,224,591,353,643,760,824,403,574,821,300,388,67,35,221,909,138,224,927,489,461,334,361,14,692,637,146,853,704,679,422,922,660,549,986,26,1,38,189,835,668,486,496,415,985,647,751,196,819,855,956,621,459,496,330,30,629,792,532,408,545,948,792,816,694,327,720,487,594,329,550,999,907,246,309,611,333,84,148,108,711,414,281,428,40,197,305,80,699,51,331,842,666,306,506,757,479,604,801,108,828,726,149,193,277,396,657,335,150,571,867,340,134,278,363,734,569,164,463,142,701,241,15,180,545,881,893,987,378,382,702,985,169,918,308,720,439,322,91,908,460,48,367,101,204,484,530,344,852,491,184,35,162,98,478,214,595,385,685,177,271,194,352,583,528,570,669,670,560,610,804,810,773,771,545,907,134,377,857,286,926,58,277,852,855,534,419,127,514,216,415,948,693,503,258,337,357,273,711,176,117,837,101,646,430,454,724,868,909,250,188,110,770,832,607,673,589,902,171,696,700,223,746,67,328,785,448,120,761,74,90,499,727,254,854,905,50,919,867,201,423,360,124,727,648,824,841,642,572,400,845,387,215,787,993,892,180,314,977,836,214,881,886,722,957,574,348,421,838,918,483,25,501,650,652,359,663,169,300,318,725,271,830,97,457,838,938,683,567,927,29,468,432,61,20,597,158,992,615,247,760,163,196,793,855,464,184,314,485,952,574,302,884,172,940,67,526,804,387,606,353,385,298,13,190,953,925,606,704,179,927,449,614,881,418,116,931,881,121,521,812,471,854,810,240,686,501,838,475,355,168,128,48,729,267,746,414,500,327,682,536,725,37,894,896,273,979,322,190,866,774,507,993,895,325,167,201,513,202,974,991,541,125,378,221,123,79,484,205,205,781,723,914,287,280,770,470,562,114,541,504,984,288,135,660,223,893,286,145,455,367,475,840,47,554,929,602,667,58,780,584,746,902,603,707,705,975,878,935,127,364,83,785,610,987,860,36,584,345,405,557,37,21,93,277,16,782,932,676,696,565,991,879,651,220,833,93,830,994,841,487,689,424,102,260,293,3,563,823,344,245,5,18,432,373,63,961,566,934,214,845,350,14,896,130,357,608,783,956,844,769,521,566,832,651,768,629,223,832,384,198,367,778,104,315,226,643,655,839,674,457,177,380,104,653,287,856,429,520,847,69,255,662,359,437,739,640,597,135,181,819,750,472,210,248,905,797,346,631,238,609,370,315,859,843,948,452,905,874,228,282,63,536,692,705,611,899,622,281,845,599,975,408,538,10,735,953,981,466,929,786,265,528,77,72,567,672,412,672,674,493,744,151,815,813,862,979,893,60,695,191,446,800,350,594,160,470,179,523,892,990,610,904,444,281,194,399,989,474,499,704,887,491,198,639,512,851,299,938,630,11,706,822,918,227,555,590,658,227,727,382,454,207,934,892,832,634,935,60,125,530,693,48,180,966,503,745,436,647,605,40,386,226,923,426,390,222,420,112,468,379,960,933,24,484,329,562,420,452,827,800,680,927,884,870,701,604,738,478,515,134,258,721,506,349,923,499,692,73,548,889,742,925,346,297,510,546,982,144,40,547,325,359,445,553,899,845,381,814,502,462,587,891,130,638,617,125,598,163,51,592,701,338,732,238,983,194,515,853,375,682,106,876,411,854,471,941,692,397,101,203,67,647,695,330,149,850,165,224,315,720,252,377,413,414,352,574,6,119,62,341,268,187,769,941,945,627,627,970,428,926,341,33,496,547,610,631,114,214,738,315,357,332,684,0,371,710,378,641,707,174,840,154,662,930,107,420,815,696,264,813,864,368,255,681,209,280,463,182,539,411,487,106,196,756", "570,977,210,15,490,23,351,70,155,921,232,869,779,977,467,995,789,632,838,653,780,443,716,4,13,510,948,572,342,81,554,496,884,187,844,493,358,506,816,810,420,369,25,379,488,850,82,678,16,897,674,632,363,607,296,648,651,176,83,828,991,212,881,124,571,249,61,981,928,447,479,919,535,483,887,641,282,204,711,437,46,457,383,982,696,892,336,898,708,766,479,701,514,573,47,105,177,816,681,766,616,651,479,736,991,637,390,988,38,118,593,625,115,25,255,565,927,390,896,806,598,11,827,253,515,916,505,4,384,577,89,246,239,516,234,720,252,686,133,86,271,859,890,498,202,32,759,933,610,831,926,888,331,919,161,229,51,986,496,855,666,744,85,225,902,8,969,934,920,907,925,373,774,767,848,973,570,422,472,509,532,258,38,460,495,951,755,965,620,82,574,180,72,612,493,235,70,722,746,608,648,683,755,336,165,950,916,719,628,351,762,944,315,298,728,865,618,141,282,872,377,483,991,438,512,511,226,397,372,929,978,629,138,822,731,737,49,79,314,660,12,730,560,110,830,473,654,9,364,642,317,753,522,947,262,407,669,866,453,393,145,680,819,9,377,611,992,320,148,417,335,357,446,664,520,307,856,140,679,625,690,298,956,638,40,46,776,766,661,504,856,431,270,24,488,574,130,917,49,11,601,235,815,466,125,26,275,706,388,46,88,871,498,981,953,957,789,933,257,494,367,436,352,6,520,291,841,40,357,205,813,702,171,927,850,434,201,826,482,666,777,197,986,850,256,589,217,72,319,834,373,897,65,474,958,635,658,968,309,63,277,917,535,35,58,159,878,949,153,59,389,520,266,553,210,997,469,353,358,955,829,290,577,909,315,202,508,195,942,929,535,662,245,278,607,517,409,643,502,776,975,969,797,120,518,110,787,646,820,135,569,176,301,682,420,636,771,298,262,147,559,92,496,381,947,314,555,100,147,512,415,396,284,836,577,149,255,408,519,178,752,972,771,734,996,743,393,911,687,895,137,260,801,33,97,496,791,642,559,253,981,100,713,963,926,448,478,979,254,466,606,479,854,630,750,223,174,446,919,125,759,975,771,664,627,655,562,46,262,553,491,732,381,834,445,213,414,428,409,638,859,475,574,947,144,87,958,255,445,120,325,964,198,147,587,584,282,421,6,106,479,551,254,760,263,747,767,465,861,323,154,846,896,500,800,773,758,129,360,677,648,592,745,699,984,394,985,779,129,482,616,78,353,609,771,552,777,328,884,485,895,382,166,141,932,658,325,80,641,989,200,71,600,987,105,642,185,199,865,167,821,450,400,153,437,292,955,820,669,67,6,724,88,27,470,814,205,555,681,317,772,11,414,618,504,656,531,759,171,553,712,65,660,505,814,109,788,678,958,721,745,952,154,780,996,471,25,590,411,838,501,642,165,25,206,357,7,855,382,593,595,740,216,181,293,873,57,196,482,192,893,636,109,980,832,676,962,220,158,762,266,173,753,387,836,782,249,541,233,782,972,530,847,851,828,290,499,351,620,625,479,963,86,584,566,702,855,101,270,568,950,4,605,505,133,970,295,542,911,527,919,523,300,715,755,342,684,70,283,308,850,914,600,636,293,225,952,781,372,390,814,910,832,604,423,792,986,574,433,669,177,685,715,244,913,518,304,626,675,290,796,562,935,680,247,816,83,54,479,895,900,197,915,80,513,413,224,442,365,80,257,150,474,305,564,115,27,113,512,503,457,705,894,543,129,598,620,110,806,106,743,378,106,696,911,921,288,260,905,858,46,426,483,941,408,8,222,388,132,701,806,144,100,92,517,112,254,262,873,64,358,544,342,788,616,622,948,25,372,262,591,944,126,630,475,103,289,353,131,450,687,804,533,253,602,129,361,386,845,782,164,701,225,445,893,728,409,705,703,591,373,912,859,415,705,875,125,861,115,746,740,835,384,329,313,969,933,155,451,153,467,187,333,549,608,589,703,820,402,469,303,57,665,179,67,540,855,580,229,620,953,497,638,82,262,229,944,770,334,13,475,476,197,515,819,798,617,829,675,511,725,699,78,726,171,816,711,276,412,875,731,310,2,573,692,445,827,262,168,609,735,605,923,462,181,398,359,835,428,145,403,602,548,741,332,261,31,436,186,641,984,421,99,828,200,341,955,907,410,395,690,754,825,532,280,353,614,497,349,371,0,956,140,164,408,482,157,615,852,311,465,738,617,475,140,902,950,772,798,591,712,786,654,646,340,350,735,603,302,857", "416,243,135,324,271,814,811,763,998,255,867,299,213,568,284,699,974,220,638,934,120,432,470,203,204,228,419,504,401,603,108,509,181,190,234,952,384,798,225,234,719,530,224,9,731,669,945,663,489,19,383,435,168,671,804,229,254,703,601,895,341,754,567,748,277,287,754,809,52,898,864,717,888,315,424,867,186,662,214,368,637,26,615,570,345,865,654,83,874,109,310,877,519,61,36,367,306,64,330,61,607,374,188,138,494,952,165,272,371,214,173,622,28,514,276,610,420,756,735,426,748,322,282,645,372,707,666,835,611,185,816,105,429,752,499,683,575,882,788,949,189,32,84,584,985,87,395,563,476,849,594,165,217,577,352,700,581,371,819,202,236,740,650,676,588,331,539,66,656,989,192,367,485,892,515,284,657,398,684,603,633,828,5,696,187,409,280,938,735,539,662,958,346,525,400,594,901,966,394,1000,866,862,407,260,8,981,167,500,285,767,912,536,62,367,65,481,962,378,712,771,305,741,991,585,997,562,392,527,794,497,845,380,452,740,167,940,631,64,925,242,655,582,820,55,364,343,367,588,742,491,743,822,663,297,237,874,814,243,487,928,87,237,601,411,270,517,909,302,155,889,998,816,307,330,121,136,642,169,731,555,425,91,383,891,170,207,638,517,43,818,347,390,760,937,312,6,382,570,846,47,405,351,535,208,859,182,567,198,86,64,426,275,887,364,886,849,830,812,202,297,581,648,908,203,269,345,260,579,857,202,831,834,803,29,60,967,958,413,388,91,693,596,711,660,671,452,416,989,65,715,615,142,61,860,511,290,557,203,516,538,907,968,652,424,131,862,682,40,749,505,567,398,172,926,331,65,107,33,718,334,156,116,974,160,92,689,731,391,151,448,189,819,625,128,132,523,190,749,5,764,59,84,659,923,262,467,701,153,970,485,947,485,107,755,857,554,750,56,816,666,780,481,134,234,708,464,844,855,372,613,472,690,297,190,714,261,725,49,131,823,18,931,400,925,586,556,396,7,829,583,700,556,889,583,709,147,950,672,701,419,413,715,396,364,388,320,390,612,259,885,836,800,275,635,325,657,761,541,714,498,534,676,69,393,712,369,756,304,76,840,937,616,235,254,449,462,151,305,563,637,487,892,371,167,615,777,30,676,873,836,674,837,314,753,946,619,291,13,788,979,192,636,86,5,232,881,241,877,188,295,719,360,367,36,898,149,203,796,827,507,534,93,266,558,513,151,878,736,636,801,807,751,264,79,687,175,955,417,332,48,390,312,139,222,465,900,936,43,501,790,78,994,668,796,474,1000,287,604,323,982,480,850,89,207,19,551,302,61,611,394,101,536,820,789,612,24,568,734,517,242,938,44,129,179,401,107,853,174,481,175,513,663,205,656,700,820,243,386,31,529,408,61,149,776,131,61,686,39,824,150,444,775,375,717,39,108,614,610,955,538,690,355,941,48,493,168,429,649,29,155,229,996,991,715,553,91,767,87,69,861,701,55,579,805,633,978,175,433,987,40,664,689,192,739,443,897,105,989,741,867,314,986,443,760,898,652,576,201,307,384,321,575,174,801,741,315,950,761,800,74,99,737,749,503,679,256,690,266,858,766,22,220,52,9,271,278,385,924,850,194,400,518,503,511,733,942,130,216,101,50,744,456,790,362,712,966,774,640,793,35,644,483,860,121,103,550,515,389,494,355,150,251,912,142,525,317,605,288,945,983,91,373,254,523,146,47,174,446,596,428,769,185,304,371,803,493,107,929,164,137,986,683,393,45,362,385,722,562,304,636,850,394,883,143,966,617,672,700,835,627,673,552,877,723,40,82,402,490,393,952,53,102,280,906,890,641,729,179,218,447,171,489,117,856,328,675,818,730,836,5,45,538,474,262,978,395,764,662,607,433,827,253,2,256,384,332,924,909,879,23,339,793,874,170,994,555,369,796,675,782,16,781,826,860,555,172,997,86,268,950,191,587,543,947,566,644,371,331,379,319,386,517,867,47,269,439,512,857,36,89,7,529,507,51,520,720,69,35,203,339,74,482,280,104,460,912,339,672,353,258,373,565,734,473,56,107,991,832,659,621,100,240,328,39,103,267,570,875,871,433,996,654,187,714,41,675,443,726,589,37,976,989,534,805,876,721,106,247,650,857,604,240,69,942,521,775,570,644,218,89,605,408,18,584,713,615,211,92,126,710,956,0,174,775,491,631,256,258,117,65,878,344,503,200,409,283,320,333,185,946,887,322,200,327,169,806,171,308,205,873", "444,630,677,725,884,719,989,222,535,946,289,293,598,402,157,540,104,959,683,547,309,257,634,587,468,197,575,923,475,62,807,736,35,842,669,295,641,165,141,619,298,975,83,59,909,825,820,214,139,694,836,313,235,829,857,200,856,618,683,374,850,298,647,378,632,213,801,261,603,36,884,700,574,855,141,171,927,572,907,676,304,77,27,231,990,792,6,339,573,313,626,100,485,440,956,443,38,963,381,464,595,393,613,426,722,96,326,89,133,656,486,781,477,772,118,497,574,944,612,26,812,285,758,711,652,491,965,965,418,996,178,657,794,18,866,146,861,927,490,413,995,471,213,139,671,583,676,54,841,299,824,417,168,805,219,682,411,454,50,78,98,324,373,694,151,305,779,644,368,450,447,89,646,460,613,60,677,671,383,651,271,615,384,843,829,261,788,222,856,550,503,334,114,572,508,603,835,315,713,639,335,137,294,70,856,134,728,773,931,846,30,197,951,211,861,414,532,62,390,886,401,234,512,631,669,52,430,834,295,622,831,970,599,49,118,500,697,819,950,517,938,131,408,400,534,313,318,727,959,929,837,445,650,476,828,980,384,226,280,314,91,382,928,849,416,36,189,638,481,298,649,604,827,762,662,723,633,957,762,536,204,472,83,663,997,712,228,981,323,178,405,525,483,98,918,124,32,218,561,890,796,471,927,35,694,639,112,934,616,58,436,385,111,257,960,655,926,867,290,143,871,951,553,20,480,269,16,846,139,879,938,721,571,930,774,389,142,474,157,759,478,685,447,889,584,431,218,134,278,655,236,604,448,252,626,972,817,770,402,484,334,755,441,373,135,896,248,219,933,755,670,988,108,855,679,429,440,617,768,694,985,757,340,799,18,474,738,10,465,551,367,212,992,689,592,75,758,510,517,641,941,495,98,880,637,392,939,404,237,906,479,822,993,950,720,236,871,826,920,30,252,594,473,797,151,944,450,592,46,941,101,147,35,650,28,149,5,482,112,892,659,160,917,968,759,996,324,996,494,745,301,468,579,342,315,986,337,948,117,826,417,571,328,666,901,170,415,829,406,976,729,102,792,461,723,739,428,496,529,754,359,478,220,546,192,609,926,117,155,363,301,108,189,573,993,489,899,478,692,697,555,185,802,214,275,937,392,62,5,660,282,944,211,871,911,368,759,343,844,419,683,432,215,40,382,136,690,444,699,173,264,367,191,287,211,904,56,621,149,969,585,562,898,298,190,222,646,729,204,100,319,278,650,664,482,912,490,738,506,180,317,192,614,783,868,880,677,877,977,281,171,768,497,221,780,778,905,865,857,677,869,289,53,278,211,437,412,759,529,470,902,177,195,814,430,864,258,681,652,428,385,773,213,909,291,496,758,143,417,402,912,791,667,56,319,67,243,339,268,914,542,780,609,75,454,312,272,119,304,580,560,841,442,678,19,347,528,415,588,672,112,777,211,325,930,582,606,525,973,382,647,312,86,757,96,766,847,693,904,128,920,406,162,949,495,565,432,653,491,484,541,16,413,501,126,440,444,177,10,135,536,445,664,585,239,29,527,982,98,489,715,21,901,225,766,546,597,881,861,973,573,122,893,855,476,534,293,260,656,21,116,586,406,586,872,718,783,344,562,171,320,900,177,790,37,243,808,689,856,794,688,530,529,387,362,777,910,765,776,268,450,344,168,659,425,726,48,221,129,376,841,51,699,733,931,182,382,505,527,927,737,790,624,264,45,352,904,339,513,650,220,81,722,188,545,555,773,293,490,390,479,798,129,54,650,905,199,781,630,700,779,829,104,977,968,770,287,813,911,623,629,36,664,671,140,180,417,468,872,187,86,449,168,613,573,947,978,770,547,444,743,292,39,59,562,825,68,153,905,704,609,911,187,277,507,495,153,984,595,319,831,181,253,623,92,427,143,920,81,850,272,641,615,238,4,203,906,447,983,799,870,970,838,875,402,119,417,989,613,998,667,399,396,408,879,58,73,765,584,160,620,97,310,375,649,473,77,122,461,789,729,822,236,667,692,27,420,501,373,837,796,689,686,56,254,288,190,872,361,437,830,306,961,92,597,261,251,664,675,368,881,574,829,679,31,513,932,871,630,940,740,580,336,716,239,301,244,515,353,176,498,826,61,132,433,486,874,498,206,918,796,208,193,814,870,278,715,233,427,588,107,491,756,53,618,683,308,731,61,378,140,174,0,882,96,246,514,458,489,541,616,425,117,472,892,717,464,302,648,624,426,910,141,160,729,853,818,732,757,484", "784,613,290,825,416,862,151,757,751,86,135,167,981,983,52,176,552,304,139,934,119,597,242,574,599,563,482,713,836,940,905,440,623,686,671,87,81,817,718,95,482,451,735,286,77,259,333,380,103,326,720,129,755,279,798,911,87,741,789,174,307,6,475,134,377,157,871,441,459,932,553,785,640,790,58,562,325,299,432,125,316,261,801,611,638,990,48,398,516,490,854,849,993,438,883,634,109,792,748,432,466,520,994,516,481,732,69,215,136,983,901,378,960,884,546,223,214,926,920,197,523,479,491,875,910,610,105,514,448,570,241,852,591,350,555,391,133,535,408,653,798,664,69,227,415,263,339,762,733,605,957,473,591,606,924,716,877,602,125,865,702,952,904,415,109,356,486,200,99,804,949,111,496,479,295,393,608,765,437,126,900,113,446,664,510,337,405,450,739,458,143,206,54,97,123,883,447,365,504,970,697,332,16,68,855,869,613,304,391,378,566,232,160,511,522,752,98,520,550,485,506,468,600,605,865,151,264,8,517,345,451,311,445,370,143,784,528,825,653,859,32,198,407,633,241,144,460,237,185,658,833,542,279,791,765,930,737,256,444,538,433,700,685,739,248,733,295,170,387,463,700,738,680,848,86,879,563,667,127,452,677,452,671,226,912,846,409,250,718,901,383,71,511,711,387,671,968,36,411,867,483,468,943,456,167,123,151,487,440,662,52,903,695,747,176,300,326,499,523,68,403,190,283,495,18,10,503,759,659,595,623,486,343,849,768,855,747,318,577,467,412,2,16,128,758,417,845,181,895,119,150,591,861,311,689,338,454,452,232,931,114,15,73,904,105,584,971,756,166,44,83,137,935,315,976,200,789,858,392,984,948,713,606,192,492,516,978,746,942,102,192,184,80,742,131,908,493,580,756,288,490,633,618,488,100,981,980,444,977,997,334,525,372,476,2,983,415,845,389,453,565,303,242,731,877,174,691,924,349,176,655,366,850,64,4,547,830,81,351,402,362,936,194,540,699,662,60,302,348,700,355,553,992,284,914,754,483,54,409,955,421,299,941,98,425,969,300,767,985,747,238,133,434,99,155,821,346,942,239,243,233,213,591,581,580,483,911,869,222,735,852,717,958,171,689,97,429,189,981,613,433,83,784,124,461,286,138,220,871,294,533,400,837,53,1,653,206,655,534,807,871,368,208,168,68,207,492,826,65,266,409,220,324,918,127,260,953,825,679,871,657,537,170,919,626,117,848,891,760,623,804,232,463,155,974,4,781,482,648,638,572,526,968,32,58,623,121,235,585,273,962,424,221,689,708,976,677,443,151,390,222,187,564,220,764,334,414,784,397,355,751,319,333,927,9,7,436,454,485,71,11,648,902,216,76,135,478,432,185,843,630,981,924,239,153,39,453,353,319,236,295,818,496,475,573,468,144,225,380,866,743,252,923,801,811,717,911,573,738,679,217,417,672,567,77,385,594,479,757,505,182,890,662,283,147,330,405,948,491,150,258,816,670,276,463,444,916,236,32,99,800,496,839,600,160,763,784,333,399,209,147,850,527,355,976,365,41,722,115,60,1,910,361,511,793,290,762,293,615,873,529,55,445,112,423,14,736,54,445,950,424,210,392,191,516,901,788,330,125,94,688,738,148,168,900,434,77,229,778,507,461,756,736,938,188,119,662,431,160,566,5,691,159,957,477,222,508,558,164,850,281,829,741,665,981,153,346,440,166,295,669,820,841,163,572,768,764,435,819,578,705,38,539,352,574,618,773,509,88,116,806,520,984,59,902,299,449,152,987,220,755,582,288,386,429,427,875,321,123,853,571,482,310,194,430,199,539,985,875,103,797,867,101,902,454,954,295,348,862,470,777,296,602,362,307,424,101,368,194,729,797,935,911,31,13,795,750,29,319,295,35,639,47,100,963,368,680,490,347,304,437,42,86,150,537,62,665,615,717,450,652,776,178,298,395,985,579,461,282,576,221,34,458,625,952,34,240,329,275,49,582,456,5,631,606,995,745,69,944,620,669,402,686,844,999,657,59,589,679,557,195,963,696,741,366,2,589,426,930,587,129,336,836,717,639,137,513,248,890,204,700,858,345,474,678,472,281,673,884,487,447,875,109,396,160,409,475,728,133,880,54,33,827,412,325,968,515,833,951,107,189,193,220,891,899,759,959,675,691,612,352,57,762,676,189,48,911,885,79,641,164,775,882,0,773,929,542,187,765,736,900,501,466,389,754,564,326,200,331,30,333,70,727,161,334,636,815,36,346,813", "581,262,752,479,9,674,615,970,757,61,410,960,11,478,856,520,499,989,815,976,727,209,93,613,84,650,861,393,151,967,163,982,708,941,763,611,27,302,479,197,300,665,689,252,387,254,749,599,547,430,700,875,42,418,635,679,684,455,202,91,181,962,82,486,845,526,314,827,824,572,575,82,283,522,505,474,873,772,997,584,571,356,284,132,611,763,800,565,530,39,129,780,175,835,341,495,533,50,662,55,600,251,519,241,989,685,629,155,24,110,409,131,30,767,903,632,375,63,669,205,286,839,630,307,373,437,105,268,107,951,569,64,720,926,24,690,323,766,1000,620,274,963,222,724,294,365,664,606,367,274,485,13,422,961,954,293,777,47,768,945,969,154,923,601,416,515,745,127,820,234,351,393,496,914,10,325,262,682,363,651,777,364,204,749,615,240,905,668,114,476,638,533,264,651,493,708,380,565,400,767,234,718,199,337,739,457,959,955,908,507,60,781,292,684,637,430,504,885,33,764,56,431,315,564,288,435,660,711,405,610,806,97,351,160,869,630,903,674,26,572,466,304,680,305,335,936,546,349,398,648,558,646,305,167,66,795,301,474,450,654,381,713,979,56,292,81,733,744,725,450,433,826,652,584,687,375,269,458,783,881,391,647,179,288,857,77,500,437,268,262,470,59,264,368,986,965,449,877,188,27,401,456,27,932,610,258,469,306,597,344,355,676,846,494,995,56,670,219,70,165,972,694,796,956,800,454,287,638,575,396,629,402,556,635,393,352,752,95,7,87,809,489,457,368,932,297,52,708,644,510,57,688,709,675,710,149,376,333,107,227,189,65,154,897,483,780,844,813,994,519,156,184,84,345,567,371,74,560,576,849,833,736,905,632,457,168,827,6,413,476,249,909,64,372,995,703,34,920,82,577,772,868,432,379,22,292,956,126,67,759,134,295,591,593,45,738,697,27,797,263,920,770,847,370,962,377,237,599,172,157,811,543,151,280,23,598,554,486,770,451,259,893,151,400,770,602,783,347,812,827,730,577,715,674,421,758,81,376,464,687,539,501,532,567,295,738,515,836,709,864,324,170,461,158,3,51,246,397,959,869,636,689,344,858,929,482,710,901,49,800,162,386,21,344,764,875,52,50,245,391,274,567,745,297,997,992,904,425,454,733,102,217,906,922,144,576,536,965,193,755,632,895,962,820,903,303,374,29,89,661,766,102,943,317,136,330,372,670,10,872,186,977,886,147,870,38,677,417,587,572,965,924,395,719,291,698,334,244,547,951,808,214,449,288,973,928,678,259,280,600,544,189,956,689,61,238,598,764,606,548,775,558,8,32,396,341,684,248,913,460,996,109,826,912,783,631,26,135,927,207,387,616,969,569,160,928,150,268,128,60,144,769,673,990,150,456,263,445,361,383,487,127,337,648,782,890,218,995,111,979,623,567,660,969,484,255,638,948,133,865,279,408,498,753,158,443,814,323,700,606,720,727,710,678,118,466,776,704,654,676,173,686,426,114,325,448,178,95,868,107,913,470,585,791,229,713,570,258,106,674,940,57,475,220,776,596,748,639,926,620,908,46,75,739,665,233,946,998,643,547,487,440,134,972,156,620,244,148,519,310,928,785,120,107,252,658,538,676,21,743,534,32,628,543,98,495,270,992,754,831,279,599,972,63,575,673,399,986,709,221,718,801,475,253,44,218,225,345,985,527,349,880,827,431,932,653,334,959,267,984,39,787,220,862,76,739,241,526,424,655,118,985,221,890,86,319,318,398,604,824,797,764,58,668,213,327,886,901,636,848,994,973,425,651,702,518,911,965,323,731,519,15,240,422,860,798,286,872,435,891,582,544,396,220,639,725,331,367,899,649,808,653,998,387,38,302,887,521,536,704,927,429,666,949,60,369,445,772,384,368,786,188,864,295,178,324,930,114,536,616,608,896,22,757,917,323,102,53,745,712,609,975,639,238,371,924,265,251,323,795,981,84,304,967,193,579,167,476,711,615,905,470,635,582,130,820,27,821,701,563,149,414,5,815,132,198,739,531,7,377,812,736,767,20,909,668,302,607,506,995,381,683,163,208,485,660,340,878,355,82,390,863,193,218,520,384,814,905,675,18,314,928,373,73,29,751,9,570,643,385,685,491,654,389,12,93,832,718,533,922,406,77,745,542,457,647,733,789,777,493,158,126,371,591,376,89,237,190,143,707,408,491,96,773,0,171,134,96,520,687,692,122,205,766,22,814,60,767,478,484,563,160,308,904,699,734,350,895,850,710", "829,721,535,418,14,138,276,825,991,457,958,56,937,510,437,4,352,658,806,425,447,55,845,5,629,833,467,113,182,256,706,292,392,191,100,880,663,145,392,308,233,298,461,744,756,163,124,842,703,852,584,888,313,799,424,472,137,998,789,570,915,789,151,345,609,828,294,66,709,969,110,135,54,277,551,985,656,169,625,406,541,174,744,33,949,559,149,740,276,877,328,744,106,974,750,993,86,739,252,230,363,775,807,138,544,866,418,836,466,315,514,867,736,556,213,407,971,596,244,775,785,270,542,933,162,758,976,590,75,555,570,980,423,98,16,420,671,874,830,442,832,474,98,543,635,488,529,353,431,599,476,92,958,309,392,388,619,128,706,996,974,727,70,96,861,726,902,149,218,548,826,593,11,852,890,454,506,854,316,952,397,501,752,303,671,704,320,181,537,728,884,389,438,242,125,361,469,184,530,553,577,519,610,355,208,586,84,569,805,502,723,178,626,780,59,511,410,849,705,976,714,289,242,659,19,32,841,577,967,357,18,749,295,471,925,605,736,844,562,758,531,611,705,171,60,994,269,350,742,718,382,671,334,435,795,846,60,889,360,336,242,144,696,75,336,470,437,736,430,21,875,983,541,287,536,785,359,162,37,238,671,607,149,227,875,156,212,314,25,36,694,348,436,427,369,482,723,356,868,514,802,3,210,340,591,310,689,894,124,879,201,37,616,296,939,808,827,20,75,174,414,764,14,820,190,111,276,361,195,420,253,280,666,835,192,905,907,429,457,276,557,615,11,341,941,641,908,555,983,912,287,877,767,458,502,673,782,90,805,374,256,349,732,231,405,915,936,812,59,31,764,340,885,776,638,101,396,42,173,94,275,690,251,971,981,569,549,556,297,423,154,200,797,697,594,350,528,400,367,601,829,47,44,810,141,565,252,750,880,435,804,538,859,253,60,852,821,423,438,284,220,771,631,872,361,714,269,860,423,155,472,834,41,160,863,732,846,551,90,717,469,690,931,311,47,541,8,922,552,698,788,392,635,445,721,987,496,874,842,386,884,260,296,349,509,100,497,818,765,663,433,464,497,47,301,990,577,297,114,639,424,190,341,301,639,449,621,335,792,22,1000,359,671,556,353,764,92,315,182,957,492,285,65,77,947,741,227,454,48,372,69,928,324,412,960,726,248,78,445,228,437,696,234,870,739,574,742,315,326,589,650,598,805,54,242,707,797,611,477,235,257,893,218,275,461,84,224,910,617,774,494,323,260,292,444,77,456,713,779,542,37,67,862,965,312,800,68,54,410,398,751,231,511,573,225,349,703,588,597,895,865,532,509,295,517,844,143,900,960,353,114,82,56,993,689,298,979,513,445,99,34,674,49,949,260,39,718,283,850,582,723,745,236,123,809,351,715,182,461,947,876,702,416,867,963,760,920,244,214,892,97,11,176,816,22,881,600,574,853,939,895,297,339,313,858,149,735,695,744,485,393,241,805,699,273,62,443,921,106,211,382,716,80,601,728,905,823,348,184,802,585,4,879,456,61,709,946,296,94,532,362,602,260,720,593,978,439,23,763,524,493,931,772,826,203,293,827,789,408,764,899,780,715,541,621,124,109,501,498,362,771,424,194,549,26,432,607,884,217,577,923,31,91,979,963,104,729,569,502,129,838,295,188,511,753,769,62,620,805,217,796,460,696,100,706,349,521,92,575,6,8,221,144,623,208,813,264,448,704,734,313,808,826,436,881,986,220,115,99,706,726,307,953,303,442,242,285,110,241,773,178,554,464,998,439,649,916,538,816,945,158,195,873,983,122,459,120,966,36,239,276,31,633,834,190,103,984,220,86,548,21,401,378,411,516,913,854,299,987,84,369,724,587,241,480,87,212,527,743,778,194,270,915,515,358,354,749,112,644,430,722,51,836,584,180,237,505,48,323,671,769,480,574,677,523,397,342,869,822,864,129,29,656,415,340,435,954,875,155,611,56,861,519,90,445,889,510,405,899,237,571,136,928,824,549,873,692,643,912,38,479,572,909,470,473,880,979,994,459,477,515,149,64,490,691,729,35,539,97,826,648,577,414,908,900,998,460,489,208,166,582,509,547,811,781,227,172,285,36,295,853,580,336,542,383,972,613,310,92,239,549,993,194,736,577,903,435,192,392,86,925,708,662,223,343,745,998,184,372,137,895,581,857,248,513,712,672,104,530,174,482,631,246,929,171,0,498,336,285,632,158,224,57,817,97,44,130,792,806,236,901,124,863,392,28,663,484,443,734,100", "870,100,984,240,178,258,357,24,418,18,52,78,993,68,287,774,189,236,81,715,523,451,767,592,133,672,149,420,360,36,804,960,797,51,443,951,47,652,887,731,750,232,587,450,974,989,866,61,217,912,947,292,244,679,78,751,503,765,726,830,545,75,218,399,77,555,143,397,975,932,905,832,828,415,951,586,349,846,987,31,770,252,296,691,602,146,84,265,221,732,398,546,317,724,707,27,965,304,814,570,439,86,636,988,395,386,495,667,713,983,235,618,732,392,832,53,853,408,387,285,774,10,93,816,443,881,287,220,149,475,635,649,509,196,689,256,133,904,144,863,955,277,46,222,25,494,424,744,458,896,468,792,232,398,149,492,904,345,298,851,91,19,616,656,966,430,387,292,443,325,572,122,784,97,231,572,557,315,423,146,894,966,571,980,572,314,769,411,698,866,74,988,192,897,326,357,581,291,208,953,691,735,371,413,331,422,721,680,712,206,908,517,633,972,718,310,373,373,470,363,161,506,393,261,358,944,156,519,421,602,839,852,913,129,304,775,880,42,154,105,309,950,66,704,208,86,790,838,467,981,630,865,776,572,531,821,924,359,771,452,35,920,399,212,674,465,394,124,907,231,737,145,564,90,510,8,433,648,358,710,912,528,190,286,432,372,451,815,348,609,972,405,509,822,44,577,98,106,511,800,810,130,529,171,671,658,504,566,854,407,244,504,192,9,166,429,207,37,970,54,645,353,500,494,891,502,907,427,438,195,650,627,16,913,248,299,486,674,158,821,323,378,523,700,410,975,512,975,763,454,770,508,58,175,505,208,880,76,595,480,787,656,819,78,551,60,420,607,503,504,770,609,912,472,548,128,526,327,600,224,783,590,134,158,719,927,844,508,980,240,566,430,384,546,420,758,138,26,734,179,684,561,454,233,391,130,76,134,240,154,737,340,89,433,622,731,465,635,78,967,580,554,555,40,471,138,587,334,876,901,475,837,315,591,117,315,771,518,246,121,927,826,663,609,137,883,520,302,867,228,557,146,720,594,181,656,304,713,602,867,702,947,670,40,340,987,106,700,769,416,561,183,722,506,572,481,353,489,926,327,783,698,431,45,835,768,162,601,869,361,757,503,37,797,618,446,558,196,367,286,353,388,267,140,712,476,954,472,721,61,461,728,861,785,63,912,561,408,201,569,610,731,85,52,378,610,109,720,76,553,118,913,76,649,455,364,467,747,825,204,529,581,83,416,713,375,544,198,470,458,973,516,61,994,188,139,948,29,237,166,757,243,24,433,528,981,202,962,797,210,384,963,678,222,689,341,284,364,406,529,833,445,713,580,845,58,25,236,617,21,984,664,647,988,470,564,860,596,852,469,89,654,496,401,471,243,297,889,541,870,267,791,934,743,561,762,192,964,961,890,717,124,74,110,182,352,598,406,158,433,78,373,677,879,313,140,598,725,230,759,30,301,835,862,896,563,457,223,711,910,383,272,904,254,693,212,114,448,366,2,280,327,820,465,550,219,771,790,165,516,221,602,140,860,233,135,696,55,211,827,922,839,435,134,404,595,696,845,665,609,480,809,911,308,135,84,528,171,201,957,267,623,648,548,399,46,165,51,147,261,674,56,492,28,901,336,28,694,408,468,346,621,10,942,707,519,607,568,229,669,427,222,319,105,932,552,399,795,930,500,97,979,188,935,247,279,614,394,395,726,192,496,961,753,228,80,643,203,838,692,775,24,458,909,218,764,293,800,903,541,873,174,607,547,168,431,964,538,166,343,977,117,530,27,159,815,501,648,570,772,112,837,442,595,333,173,60,75,837,266,589,12,225,500,656,229,617,310,70,107,770,429,786,966,542,977,910,64,553,641,233,729,555,854,915,658,335,185,161,977,825,514,320,535,581,184,43,679,461,712,955,227,190,544,869,292,897,251,777,628,363,732,304,767,106,803,967,357,209,997,504,252,864,386,762,144,698,768,986,51,273,518,184,959,76,125,40,326,859,202,415,654,50,342,425,220,549,618,607,198,546,379,923,74,19,103,615,311,141,570,834,526,384,386,895,600,334,225,327,519,564,572,153,132,483,97,277,145,932,121,177,59,136,851,379,252,354,970,195,892,130,109,232,167,137,905,162,884,732,909,760,4,401,742,490,21,265,345,356,296,228,160,685,262,137,609,11,94,334,720,158,171,172,488,432,881,839,974,210,840,157,256,514,542,134,498,0,371,6,827,571,193,787,277,368,261,563,178,521,333,90,132,569,839,250,251,119,773,189,29", "378,807,861,353,92,562,364,737,474,142,975,930,523,490,253,92,676,740,362,104,861,316,75,591,734,333,106,767,999,965,144,319,981,679,843,50,522,351,723,204,110,592,180,231,803,707,606,486,953,594,560,443,829,869,982,78,663,671,48,490,831,138,64,102,6,178,123,813,876,506,263,102,338,522,35,888,159,581,35,894,876,252,22,764,237,507,830,119,50,454,311,272,436,444,796,135,452,30,272,109,985,56,680,111,451,810,758,351,613,250,167,581,597,29,512,212,738,529,660,475,463,483,229,102,23,625,725,938,43,182,691,792,740,566,255,598,316,336,352,970,324,905,476,516,624,275,372,344,810,210,641,614,779,949,894,660,462,478,324,461,784,946,161,277,402,103,650,848,653,366,386,359,439,234,113,790,890,401,573,527,938,302,521,466,476,323,816,661,420,198,791,468,537,641,939,783,508,303,871,901,328,448,65,629,405,172,755,778,559,219,126,685,321,640,693,86,133,791,909,149,936,515,316,53,763,973,75,13,876,873,922,541,157,11,94,592,425,547,894,597,102,756,673,94,471,567,307,963,914,894,978,593,464,674,593,620,757,776,236,908,398,989,674,642,134,956,661,799,960,867,276,653,764,982,626,180,540,547,740,11,321,167,879,571,843,631,512,29,789,192,647,935,178,190,33,301,808,97,58,49,579,896,438,141,133,834,990,480,188,97,619,792,135,122,357,756,105,221,276,540,340,834,322,740,835,417,245,890,681,416,34,628,65,16,209,539,362,111,174,416,26,699,446,274,729,441,147,382,290,549,276,873,436,711,193,392,786,650,49,298,810,193,712,625,813,639,214,616,103,666,330,832,607,973,216,314,530,194,710,224,560,305,538,74,727,36,313,743,129,351,431,338,493,487,319,444,133,192,564,92,315,370,691,651,253,79,811,864,295,742,489,135,750,772,269,656,831,514,856,217,224,161,613,680,643,808,639,287,211,811,201,702,548,860,65,681,85,820,46,427,936,338,905,171,56,200,28,804,97,425,466,956,468,398,933,90,965,417,437,803,232,863,981,780,187,248,669,819,281,34,312,511,166,993,22,267,209,713,68,76,258,571,170,248,207,912,967,780,487,778,161,313,614,921,681,454,19,605,850,314,446,137,660,134,954,832,342,517,475,354,354,596,836,168,994,321,389,136,485,530,315,331,237,719,51,323,840,391,515,31,181,143,3,689,493,168,110,274,198,423,207,849,878,307,81,606,875,861,244,6,726,121,302,571,643,501,112,461,47,38,961,993,151,703,236,908,800,178,525,631,22,799,124,671,147,875,337,445,963,701,279,457,535,689,427,366,950,959,301,328,688,287,23,228,155,746,845,32,934,957,109,943,43,706,500,351,368,290,670,963,792,539,134,629,441,783,433,281,259,495,64,966,961,426,518,374,253,660,210,628,954,281,909,873,226,291,557,368,494,679,108,239,537,757,320,15,802,855,129,167,174,273,557,105,33,606,523,856,497,964,213,733,217,906,238,918,133,58,155,805,46,680,69,677,221,482,714,498,73,346,869,946,747,197,756,437,6,118,525,996,484,933,833,386,848,763,403,799,716,727,363,544,603,56,903,676,301,724,345,280,837,376,637,73,92,150,556,282,601,293,288,62,120,834,166,4,781,649,904,95,256,480,151,453,204,213,66,875,493,437,615,120,366,910,71,408,3,604,792,575,933,922,211,381,784,962,705,96,845,550,266,532,930,590,936,196,211,721,299,288,876,378,796,378,469,542,45,722,350,125,670,297,536,290,100,653,767,461,273,903,30,197,102,884,586,690,804,6,729,465,699,277,384,482,482,996,134,300,124,267,928,348,889,198,63,162,326,957,293,35,353,539,868,209,707,73,782,537,77,77,191,527,508,826,828,291,278,100,16,523,653,907,639,374,43,931,527,644,169,639,609,716,372,887,665,390,492,429,930,329,873,326,296,735,385,12,941,261,36,748,396,911,446,855,63,67,596,619,937,790,977,90,948,562,666,262,327,900,933,817,649,730,506,867,741,750,781,719,321,322,135,874,404,517,862,319,636,95,666,965,516,436,129,576,162,485,518,215,733,726,843,234,116,535,256,309,845,626,325,498,539,682,398,54,590,838,485,440,604,495,30,651,902,424,350,549,670,796,860,16,549,174,145,420,799,876,443,999,208,986,894,115,820,531,501,514,141,482,303,154,615,258,458,187,96,336,371,0,911,470,921,855,377,289,834,497,650,269,254,961,6,272,188,305,186,352,162,957,406,235", "368,17,840,110,142,714,656,670,396,18,168,685,679,140,601,945,625,371,109,803,140,935,320,815,560,763,468,832,676,204,76,444,671,751,556,908,773,260,773,17,309,216,840,313,259,164,866,979,192,321,582,104,205,153,815,421,806,777,834,15,104,20,610,715,773,653,82,211,441,636,134,791,875,525,258,729,707,727,972,235,683,789,262,875,83,392,656,802,913,738,244,410,869,875,217,926,326,694,654,701,231,635,414,46,787,570,757,268,847,23,746,640,869,117,483,12,913,980,90,692,371,28,943,392,540,152,662,279,961,156,861,987,313,146,302,939,293,687,126,881,692,985,105,105,463,944,35,735,325,273,528,659,64,286,846,307,532,906,296,292,151,183,460,819,827,742,691,308,847,828,7,845,392,854,719,515,703,82,704,326,509,415,682,26,721,70,391,321,887,682,788,355,20,175,411,985,692,750,280,332,679,641,933,804,227,637,427,837,172,819,477,924,888,978,557,927,480,277,310,290,709,710,863,392,247,384,581,767,147,74,6,250,90,616,889,738,205,183,75,565,376,884,162,262,600,347,489,271,429,762,895,950,145,339,717,18,753,852,410,303,346,96,766,627,781,794,151,57,726,113,34,484,892,110,929,343,411,122,306,981,545,644,192,614,459,689,33,562,975,571,265,298,908,822,769,360,414,451,760,755,873,863,878,248,494,385,439,44,419,907,45,724,29,245,677,604,443,800,951,709,317,440,960,989,763,201,33,975,990,521,49,875,335,571,244,808,137,984,260,155,415,35,144,244,679,191,987,564,713,405,361,335,518,845,867,902,63,688,339,110,509,913,350,818,2,731,421,330,401,559,756,331,352,737,378,143,477,799,476,574,512,925,11,424,775,498,218,146,75,371,406,499,311,447,197,99,44,163,267,151,695,327,950,874,71,586,320,30,70,808,465,334,505,960,797,195,976,939,536,840,968,111,359,160,791,482,483,472,848,293,23,446,809,158,702,881,825,109,227,362,394,425,769,692,780,498,143,535,15,824,387,76,646,157,942,62,313,531,454,586,116,938,739,673,355,54,40,659,349,468,55,113,463,48,736,660,235,449,359,788,136,551,203,790,485,160,234,813,818,480,104,569,316,917,204,978,10,476,122,927,58,586,609,167,778,603,785,536,531,940,433,693,761,961,611,865,706,967,729,568,164,138,828,596,777,573,332,753,734,84,266,324,975,261,336,965,330,29,592,497,699,629,450,569,846,526,373,547,710,586,839,703,969,899,228,746,22,522,806,995,311,750,24,669,498,201,132,547,33,601,741,700,823,898,566,901,221,327,583,723,377,882,112,853,87,426,882,242,752,450,513,784,296,987,764,440,205,963,303,800,630,471,563,328,25,102,563,289,919,513,608,635,442,771,735,882,82,885,896,248,248,350,405,907,372,916,71,287,737,924,995,767,887,823,439,358,308,899,625,840,344,294,832,896,109,549,4,224,328,374,173,923,372,474,156,6,998,120,712,387,67,425,146,558,787,40,225,777,932,636,879,706,679,530,46,78,817,518,624,331,767,825,86,951,765,382,863,876,203,331,433,711,103,145,496,612,205,311,182,66,367,678,287,25,605,576,543,698,399,418,977,284,146,239,336,76,644,751,535,382,342,365,840,212,452,929,7,896,475,201,790,995,581,849,874,966,151,384,882,712,681,777,661,512,200,972,62,478,58,728,680,503,172,457,408,227,143,915,379,966,132,113,683,563,782,841,278,371,655,756,538,736,133,656,954,890,335,114,309,865,852,10,698,278,930,534,883,149,534,230,456,951,39,176,338,260,301,760,527,64,173,286,631,760,873,178,470,197,531,285,515,107,370,962,845,561,832,363,766,150,419,790,185,227,101,556,497,717,434,21,413,344,8,153,936,10,428,402,220,81,570,999,499,765,519,935,64,320,417,676,83,772,785,910,611,727,255,901,606,177,39,792,234,353,724,592,329,111,94,371,85,903,526,478,284,864,96,298,560,200,382,901,935,152,503,897,867,479,600,768,213,452,185,397,166,32,423,304,487,931,102,521,586,910,802,426,134,10,798,415,35,809,179,733,342,17,304,980,584,979,993,143,797,763,680,923,161,574,102,283,196,212,755,724,145,349,405,268,930,848,25,962,220,547,412,948,515,445,672,511,374,817,220,554,107,474,435,301,771,5,275,226,721,466,25,175,759,810,857,662,852,117,489,765,520,285,6,911,0,769,412,787,702,242,841,264,730,680,16,962,793,954,729,276,385,487,284,323,423,687", "224,24,436,219,576,67,256,493,202,54,642,562,479,441,902,139,742,303,377,933,229,971,931,330,684,548,562,181,750,487,463,772,944,157,66,162,995,790,920,367,433,707,197,674,715,332,493,21,522,611,321,941,918,748,394,83,860,923,220,951,881,7,386,491,213,347,563,624,275,347,811,366,681,328,389,671,253,269,350,600,675,337,582,780,510,287,800,442,285,391,90,124,797,760,439,883,943,177,778,900,444,273,211,361,673,295,817,767,418,439,138,4,551,708,243,158,101,70,299,293,133,173,360,335,565,602,155,994,288,912,879,363,122,284,992,98,888,457,372,487,389,513,919,542,540,538,587,789,161,156,605,39,650,490,107,955,963,14,318,543,31,975,742,891,706,460,729,638,443,453,908,273,346,509,658,73,710,781,284,692,767,548,748,836,984,517,399,230,561,367,917,667,588,682,397,531,157,407,206,636,469,252,514,334,905,823,339,924,837,290,750,261,140,323,139,775,609,196,505,798,626,484,643,984,305,423,583,434,865,389,113,135,359,680,10,512,370,553,108,126,104,671,197,529,193,267,5,207,712,476,866,214,767,627,793,577,886,579,446,685,179,22,751,295,498,424,19,941,350,407,666,31,772,760,240,973,181,560,359,502,375,862,305,778,550,150,116,21,912,522,989,639,110,395,691,431,740,317,271,879,761,311,741,248,379,96,803,75,689,332,987,146,540,649,991,766,544,254,341,272,922,895,580,342,81,784,917,377,565,782,532,286,53,685,927,421,354,380,540,995,661,63,398,742,913,3,762,642,746,306,265,856,352,251,576,35,49,728,302,531,740,588,970,280,198,647,75,516,679,311,916,659,686,337,318,855,338,282,5,806,931,468,85,551,576,364,700,856,307,459,419,729,391,624,950,764,511,526,80,134,918,689,423,649,658,604,179,449,526,748,312,471,210,1000,121,553,50,382,356,102,935,777,956,416,884,108,271,498,245,242,360,343,347,678,520,601,266,408,60,511,177,438,187,453,9,879,286,204,504,230,495,453,615,660,677,605,710,458,755,830,690,289,978,370,383,584,919,766,312,408,744,678,857,955,583,352,949,695,310,540,770,657,900,34,691,328,291,511,759,598,558,502,650,826,780,789,538,280,79,442,59,556,254,909,350,728,985,283,953,272,246,57,908,537,707,368,77,714,562,128,58,636,788,234,16,938,681,909,581,584,67,611,157,866,683,449,188,748,679,691,852,225,884,704,306,507,686,459,405,654,871,480,911,605,30,62,496,433,744,698,172,536,255,633,354,44,507,224,102,261,564,712,957,755,659,274,311,586,565,553,172,982,257,81,281,487,870,343,282,362,253,417,546,287,805,801,356,735,545,76,674,898,793,69,838,87,903,174,192,826,569,296,731,216,3,477,512,601,578,634,600,24,189,918,935,782,567,450,828,454,808,744,326,59,915,69,454,886,227,531,758,440,202,84,545,754,329,817,731,429,691,102,930,844,965,789,259,654,781,426,347,979,864,177,986,348,57,244,68,884,858,693,822,29,302,945,292,579,827,848,162,436,877,798,452,437,345,107,986,488,602,135,213,137,303,6,896,248,255,165,566,498,514,302,283,809,923,693,356,161,488,531,86,42,806,532,968,37,951,258,252,755,739,636,138,622,531,417,548,746,918,973,165,488,51,821,316,764,828,874,739,564,343,288,498,446,910,870,709,394,51,388,142,770,235,995,682,434,401,251,486,167,267,198,777,848,842,929,78,310,299,32,916,217,311,287,558,263,633,645,411,696,717,868,400,785,21,38,829,525,327,713,109,645,220,960,234,189,206,419,840,752,713,521,492,66,511,955,24,817,866,619,55,721,39,647,784,236,912,460,786,460,509,875,991,48,182,42,296,412,255,651,706,486,157,985,697,203,999,910,179,745,361,266,727,635,801,853,978,715,379,316,225,427,940,948,2,715,230,830,393,850,143,922,579,189,140,865,847,315,602,505,224,567,453,400,761,205,45,711,812,225,167,787,277,513,945,999,825,183,180,901,404,584,695,565,959,585,934,811,708,465,516,528,167,639,354,193,606,873,540,325,757,282,770,304,910,304,733,899,827,240,701,766,447,961,357,339,106,902,816,900,962,637,513,110,15,745,968,856,35,897,292,617,25,906,123,787,817,302,315,909,13,191,364,419,631,113,71,216,35,256,455,282,314,704,497,511,16,930,311,65,541,736,687,632,827,470,769,0,223,369,910,291,27,397,546,751,443,894,755,207,720,686,418,513,167,391,41,526", "956,534,14,78,113,423,629,191,326,808,60,654,753,314,950,221,465,668,319,838,568,693,572,478,39,872,566,5,297,667,641,16,571,260,639,989,976,493,516,260,769,451,636,374,72,649,244,820,152,629,45,339,941,905,700,59,992,325,116,154,536,435,111,863,17,344,686,745,400,83,398,323,22,491,506,719,440,227,54,965,878,914,939,722,397,932,943,203,322,124,436,68,926,881,266,22,914,125,246,967,820,188,914,386,939,588,352,541,23,457,346,286,900,622,154,883,329,189,709,125,417,430,519,133,673,195,501,304,202,408,23,414,710,449,840,212,687,120,396,513,706,25,519,965,997,250,609,631,13,10,235,438,214,886,776,604,930,869,45,80,592,180,685,533,872,606,643,263,634,777,142,685,650,753,419,423,966,413,86,668,872,601,653,131,113,161,393,187,802,970,546,679,151,193,351,804,148,551,940,712,919,429,161,560,541,663,549,436,389,458,87,988,472,292,175,984,119,587,986,922,642,971,123,350,807,22,424,112,88,708,358,394,62,686,95,402,420,576,974,241,348,43,524,173,232,841,471,2,815,89,306,142,906,155,361,29,416,783,502,129,337,917,91,185,14,452,903,5,686,930,940,993,939,438,941,901,806,512,309,241,674,859,994,320,550,820,615,125,89,671,338,356,953,785,516,720,566,295,874,96,663,735,462,249,677,494,66,688,510,594,421,307,312,41,605,46,330,757,707,294,686,397,601,827,539,955,798,792,641,1000,785,869,764,579,452,237,622,230,302,182,381,616,459,477,616,843,3,835,607,206,230,818,359,899,672,568,904,482,607,389,827,587,383,609,788,781,188,897,364,471,631,453,370,749,562,245,820,435,990,413,129,201,869,815,851,688,498,356,677,802,489,414,762,316,653,262,967,253,37,956,386,618,167,492,650,428,230,281,949,667,985,536,164,964,530,414,743,143,795,835,7,159,405,533,308,821,464,553,509,420,611,937,649,990,916,586,296,894,39,297,329,856,678,659,965,167,923,37,399,675,767,876,475,251,106,700,43,177,620,385,742,388,662,749,543,680,201,161,387,987,67,495,914,540,993,749,63,219,512,860,748,516,486,312,382,524,345,60,721,249,561,778,610,320,706,51,807,684,324,214,88,225,505,28,787,433,225,384,558,325,487,83,989,14,312,213,482,503,883,219,428,204,350,226,561,553,92,833,629,629,718,837,927,529,821,242,64,932,277,633,170,245,70,703,411,275,317,635,982,574,669,22,296,192,36,699,601,390,779,524,725,161,685,926,410,848,973,612,887,230,890,498,803,668,862,613,689,778,392,668,521,802,788,234,116,416,48,893,502,378,94,972,241,326,177,506,542,11,467,919,692,741,901,428,240,913,78,416,10,41,642,92,375,356,220,380,405,291,702,99,587,596,445,966,364,493,355,423,462,721,77,584,808,144,115,202,202,88,219,440,211,618,186,160,581,87,2,812,723,556,353,167,324,901,174,417,542,636,435,392,828,98,27,36,523,572,341,965,280,610,8,24,870,750,134,462,890,432,685,432,301,728,70,722,556,528,725,371,365,464,584,39,407,966,138,444,911,955,521,832,595,246,513,626,671,195,306,937,811,421,536,384,237,1000,773,741,284,91,375,940,981,363,829,2,855,886,45,501,395,865,407,824,17,772,246,313,34,415,516,95,795,713,652,150,20,673,805,320,446,356,154,900,842,123,464,835,574,673,229,398,546,577,704,436,423,355,87,740,495,183,48,988,998,554,139,23,680,827,206,760,787,375,479,617,364,736,864,683,822,838,275,171,661,190,784,724,952,615,584,916,143,66,883,397,104,645,29,450,905,290,203,419,452,112,499,38,140,28,272,156,13,916,796,346,947,772,457,634,835,728,107,676,173,616,451,798,461,755,402,536,813,58,605,68,988,647,920,229,549,522,670,796,923,97,357,984,553,984,279,714,256,837,717,683,915,701,321,784,120,607,934,491,697,545,278,58,934,253,283,589,852,73,201,64,483,752,648,44,239,609,427,125,371,974,66,325,577,291,310,961,926,517,992,40,23,182,474,829,667,763,369,555,81,915,930,993,981,50,432,895,975,761,221,513,634,944,637,725,268,223,743,501,536,808,201,379,726,137,239,431,413,43,591,876,475,500,90,277,948,313,221,827,63,43,408,822,16,274,117,982,644,681,450,943,629,765,348,954,126,107,465,878,616,900,692,158,571,921,412,223,0,11,106,319,863,161,775,405,781,283,333,210,917,515,426,643,518,150,101,714", "237,892,529,229,56,220,151,806,726,306,578,736,19,698,568,825,941,47,296,562,412,16,647,889,730,400,798,833,154,842,642,922,703,232,242,851,190,261,553,903,527,754,537,308,43,514,743,944,7,954,600,624,766,112,630,435,293,874,2,121,930,148,92,925,522,106,781,921,390,569,218,150,782,450,167,214,29,28,415,666,368,747,500,516,850,407,28,731,496,599,712,45,81,861,317,770,654,941,821,283,415,257,45,621,433,622,309,217,376,104,684,560,772,414,250,10,129,14,559,237,251,336,683,381,796,966,530,11,866,187,603,307,608,13,941,153,600,458,742,806,881,102,603,183,622,832,32,346,906,705,687,673,996,292,715,227,793,636,562,481,376,976,138,430,143,737,657,715,484,30,695,241,523,460,888,23,631,166,903,248,226,883,874,783,818,792,867,751,573,478,246,97,698,159,704,652,445,57,209,760,162,329,525,270,540,788,597,794,949,444,997,875,532,554,440,580,700,558,683,13,312,369,49,86,64,825,555,368,867,534,827,173,342,581,385,571,981,500,148,544,277,230,560,513,669,433,834,32,430,532,465,354,714,238,365,435,734,139,175,343,138,566,169,382,719,820,21,277,924,103,269,789,856,971,46,511,405,430,534,657,719,847,773,946,335,867,673,521,601,96,742,84,176,875,951,894,861,423,631,205,675,123,484,66,272,770,634,62,42,600,766,997,460,792,470,774,108,517,710,336,893,419,833,146,930,39,15,438,805,492,207,245,881,384,308,724,794,151,522,840,257,27,102,118,478,532,306,438,908,39,815,271,538,542,423,729,768,699,838,699,750,68,661,129,228,162,338,279,482,699,133,695,796,955,202,877,435,23,246,241,988,615,348,624,157,605,947,874,711,200,960,699,640,496,879,88,900,829,25,347,495,138,132,986,784,989,447,99,437,248,681,798,118,705,67,515,659,55,469,668,652,170,304,621,476,457,773,150,363,419,750,62,111,234,175,41,265,204,762,658,517,894,273,242,647,279,451,28,977,510,569,143,513,769,912,53,61,175,890,72,897,341,586,657,106,563,507,392,11,266,284,390,517,422,341,640,715,615,987,568,214,678,558,739,596,525,650,882,655,546,314,807,367,135,946,422,550,937,382,818,320,303,479,254,325,475,801,276,900,812,104,238,212,864,650,106,232,938,410,161,96,951,36,439,453,955,248,609,77,128,332,892,330,934,541,224,485,683,397,736,113,816,608,627,884,326,180,532,860,231,879,259,483,612,932,984,86,398,872,409,865,55,811,692,438,292,824,181,302,726,306,991,130,365,866,373,534,190,284,547,555,529,798,141,95,513,744,816,700,818,186,84,313,596,394,108,707,712,996,652,611,656,26,439,339,889,671,427,921,524,936,483,270,575,975,960,37,217,407,370,876,257,423,624,656,472,701,755,601,522,191,278,747,812,596,323,484,560,95,348,693,353,697,37,403,108,745,268,69,539,300,978,255,886,326,77,8,876,998,704,229,749,417,625,369,925,528,522,435,726,324,116,260,77,489,316,277,638,844,952,774,784,26,880,172,429,892,167,465,273,912,996,851,605,721,662,322,225,733,879,108,760,148,608,713,238,540,514,930,110,488,441,893,653,444,561,993,223,878,348,73,940,331,155,566,226,655,996,559,787,734,151,832,588,33,239,395,155,626,117,709,446,31,759,632,192,62,849,512,365,738,262,132,535,600,81,27,742,946,165,484,819,664,264,631,76,391,241,656,321,82,415,67,169,205,728,152,28,110,665,78,298,846,776,945,164,533,727,241,343,502,89,554,604,81,316,474,277,231,924,789,521,460,661,846,422,961,290,81,939,6,869,803,989,250,372,459,868,522,911,79,111,616,317,193,200,690,719,302,777,102,349,822,423,432,327,534,264,90,31,494,951,580,209,526,60,953,204,1000,988,43,326,301,83,296,361,991,478,711,327,542,864,312,480,454,865,366,321,784,342,792,138,121,472,423,945,353,197,826,387,226,501,491,988,938,103,260,553,252,92,89,146,340,282,752,862,181,330,452,198,746,946,257,295,381,536,928,757,341,660,374,202,787,839,341,842,476,977,950,174,372,564,886,638,153,508,197,283,759,565,200,267,425,451,718,646,234,227,949,579,3,1,797,351,624,306,979,539,843,322,465,136,484,945,396,889,376,266,880,718,605,60,287,718,866,556,53,267,201,420,738,344,425,501,122,224,193,855,787,369,11,0,670,759,75,864,741,907,611,700,991,537,68,769,174,659,974,422,769,853", "86,626,762,348,15,485,36,119,45,550,705,739,248,339,105,104,522,770,830,506,449,745,779,900,563,699,31,995,374,431,591,851,630,952,640,474,777,774,916,317,819,634,653,253,65,424,888,498,779,332,916,115,117,612,313,407,593,938,54,508,317,899,521,985,473,57,224,762,980,547,250,676,57,939,281,752,320,361,417,17,66,725,614,560,934,906,88,767,192,364,347,626,692,28,317,867,961,946,773,941,821,952,255,155,53,129,322,21,304,554,458,784,381,412,702,703,327,750,109,253,951,485,586,168,329,257,722,72,86,638,111,644,72,235,58,40,303,40,527,81,974,85,154,893,448,541,503,976,549,76,882,379,68,224,798,687,46,158,250,335,459,244,686,656,770,435,39,953,733,106,427,186,802,337,202,370,706,408,695,184,798,61,695,901,665,666,596,144,274,787,593,724,11,566,704,954,257,826,581,396,31,574,427,656,959,389,580,875,307,658,831,307,309,604,317,609,613,388,161,392,295,114,938,601,948,728,679,960,696,7,398,710,406,847,488,676,582,312,832,337,632,341,84,448,954,811,872,581,689,664,913,263,981,528,365,912,599,460,191,580,344,395,834,317,292,402,984,448,712,313,239,33,408,44,161,500,330,335,530,517,309,419,827,433,838,761,723,276,501,932,579,432,919,686,806,407,483,197,816,403,862,326,279,91,627,894,589,611,893,838,766,905,444,243,736,115,669,578,5,466,894,497,655,92,983,767,867,202,951,963,180,994,409,105,871,774,60,119,584,114,202,320,862,963,943,532,591,977,384,489,778,666,838,632,156,579,586,876,152,513,855,443,525,989,705,782,23,700,880,856,698,506,806,279,347,696,655,29,723,115,715,139,450,441,756,600,849,827,331,968,561,965,35,590,809,140,636,473,897,645,809,339,671,798,321,987,436,898,930,601,348,506,614,884,231,55,807,782,887,366,849,318,598,772,16,443,495,782,673,849,520,128,433,572,532,955,584,676,101,945,334,825,306,808,986,971,75,661,421,926,655,465,111,613,535,124,114,984,6,993,677,958,250,506,710,307,401,45,828,355,352,452,830,57,306,669,626,201,17,594,201,70,533,404,672,564,855,469,696,940,148,552,884,563,128,23,405,439,887,415,310,409,142,947,439,432,95,387,651,784,554,486,507,700,325,671,995,232,801,188,430,419,522,907,575,495,194,180,201,68,4,217,876,161,153,279,876,701,314,475,830,865,259,249,483,295,494,45,383,437,295,134,921,929,562,52,642,721,674,931,371,454,779,135,160,722,765,818,517,647,469,785,940,533,692,799,839,419,818,239,619,876,2,751,646,959,962,823,336,991,801,422,208,565,173,368,218,673,128,468,176,382,52,893,344,864,135,470,97,499,903,534,927,782,11,350,886,284,98,680,500,215,954,651,432,737,207,508,909,374,664,184,719,351,395,894,909,817,854,444,937,652,298,329,942,83,219,2,244,184,731,499,682,73,700,455,891,734,901,960,725,242,428,499,526,29,814,931,730,52,461,230,454,257,83,350,831,311,189,552,286,847,940,652,110,630,856,407,241,974,732,502,860,137,300,775,701,148,628,80,701,280,501,266,174,154,400,871,207,662,749,572,811,296,723,625,67,249,846,51,264,650,998,473,783,727,850,7,381,162,259,967,381,326,306,515,329,986,343,160,173,846,729,40,54,835,862,104,655,182,485,881,415,368,202,794,786,853,965,674,4,630,182,436,847,624,642,66,320,650,263,957,416,734,553,750,490,956,128,963,187,207,781,863,857,310,495,261,410,888,685,549,48,769,138,737,686,599,985,936,583,238,541,760,236,668,867,226,660,503,249,992,187,719,205,722,357,755,875,864,411,567,418,362,400,144,585,896,415,433,564,543,137,244,945,315,714,580,563,280,782,349,70,222,450,727,187,797,130,365,677,980,637,122,373,847,288,658,871,825,831,461,51,510,189,218,733,929,676,680,322,134,809,965,154,994,865,84,999,751,810,650,249,115,686,619,123,257,681,483,97,673,437,923,534,383,777,287,716,191,706,942,428,861,845,310,70,842,271,219,37,879,910,834,371,48,346,158,257,416,599,563,802,884,543,331,830,254,962,573,999,578,379,596,926,596,523,606,421,522,249,478,410,879,471,178,883,675,89,40,947,66,999,204,825,320,929,528,388,254,260,550,947,922,60,903,722,886,153,815,617,503,117,466,205,57,787,377,702,910,106,670,0,488,663,747,484,747,709,270,733,486,232,71,668,858,141,230,29,365", "648,618,746,141,400,699,31,118,190,691,41,978,616,19,707,518,417,83,846,802,525,623,564,231,97,948,373,657,558,552,980,405,802,60,844,304,264,830,379,302,727,224,361,974,399,719,469,370,96,602,199,899,635,957,336,229,435,876,465,769,579,795,615,83,770,16,901,168,118,372,250,896,922,729,959,916,731,387,823,341,27,272,884,829,3,351,638,395,182,641,857,370,800,110,633,307,859,730,129,943,929,308,335,633,546,568,773,436,192,974,756,349,594,381,275,325,725,229,881,905,24,443,929,297,104,16,598,963,585,531,444,491,156,999,317,282,195,456,808,66,803,906,155,141,758,59,353,925,476,729,103,669,296,119,850,889,679,747,539,292,563,534,614,388,567,492,833,432,338,929,134,408,894,385,746,741,325,269,217,561,477,924,561,49,327,236,510,707,834,195,409,480,368,329,723,773,161,662,674,290,997,194,174,914,45,954,700,889,674,25,400,730,615,871,445,825,80,91,99,754,589,274,77,489,640,887,659,504,369,686,474,900,312,389,687,31,973,47,55,803,477,185,394,433,940,739,465,431,623,637,364,974,581,414,164,193,67,893,963,359,417,690,422,744,819,696,232,431,499,9,350,830,665,700,687,774,775,932,829,210,917,952,348,816,221,422,889,678,603,921,801,556,53,81,218,561,719,481,161,249,39,683,189,53,201,934,555,847,491,699,887,536,28,430,862,277,977,914,586,760,116,206,886,65,408,412,261,917,173,458,954,773,15,935,943,901,683,498,251,821,444,354,350,179,276,205,473,370,30,334,889,462,101,619,295,877,665,92,599,585,183,61,44,168,477,893,806,569,68,319,585,439,77,223,661,988,789,680,719,812,607,424,703,639,49,199,87,332,470,509,980,90,15,274,289,628,318,655,173,642,766,271,81,231,548,148,405,79,96,84,380,460,774,384,392,203,426,321,158,228,761,372,219,761,139,959,580,256,496,863,181,245,392,180,774,689,947,476,143,627,713,853,786,763,851,55,154,226,78,483,69,508,553,298,825,318,852,709,486,324,160,865,419,583,20,616,483,384,194,106,321,967,860,625,73,796,721,295,255,216,684,638,201,652,428,53,118,670,162,779,477,364,674,989,461,615,4,647,391,31,653,841,827,605,462,557,203,142,310,797,445,315,232,479,831,406,591,132,194,390,691,97,689,903,184,384,604,272,744,530,327,677,350,816,45,626,866,301,738,895,407,150,84,694,426,592,478,590,395,167,722,909,62,134,286,867,46,74,178,650,449,148,827,867,642,985,470,633,245,124,333,439,636,672,936,947,306,419,512,198,659,321,112,337,387,915,323,118,141,955,415,155,681,791,667,711,502,528,708,764,169,199,793,575,401,476,857,223,693,112,549,465,942,473,505,165,131,469,265,387,288,530,317,281,124,600,983,896,247,466,323,377,931,512,109,904,484,547,319,341,905,833,828,641,737,142,232,641,563,941,775,789,997,822,897,670,284,837,43,514,896,769,553,895,476,856,48,329,692,957,351,139,912,385,180,347,268,585,482,17,69,649,913,330,747,746,593,361,892,776,316,510,639,198,935,90,570,263,338,736,387,302,529,664,844,358,797,941,796,747,14,520,329,163,889,209,813,883,753,756,643,177,540,904,903,867,765,364,81,884,511,701,210,894,993,596,954,954,84,31,389,661,41,825,206,814,220,118,956,127,370,209,881,864,181,238,242,539,341,382,245,686,756,766,475,900,862,495,144,964,6,586,178,298,363,627,589,59,105,518,670,924,46,467,781,866,424,262,19,865,372,43,69,287,296,741,970,527,75,719,156,147,793,451,806,957,454,281,612,808,506,306,681,974,150,758,252,282,196,408,473,60,515,271,76,63,823,339,733,455,377,935,252,835,919,850,851,115,241,51,928,622,425,554,741,279,898,986,499,917,336,936,457,679,105,773,726,663,161,524,602,574,340,660,916,304,814,719,970,335,26,254,424,413,206,768,692,905,691,351,966,43,286,756,375,228,660,827,973,667,229,841,470,303,638,513,443,833,630,127,373,641,187,19,729,686,317,409,566,793,410,772,905,411,864,474,901,697,669,737,263,176,764,201,457,283,897,903,423,561,937,680,979,785,872,933,856,389,236,646,398,12,27,985,529,232,985,179,940,91,961,610,458,76,673,388,566,951,278,884,638,258,421,270,120,475,313,686,206,696,475,200,472,389,766,817,277,289,242,291,319,759,488,0,914,623,107,709,539,283,723,509,416,629,760,565,360,936,719,181", "448,59,944,223,212,427,529,591,658,122,560,526,758,152,976,534,298,697,53,515,904,62,303,136,218,917,325,845,206,601,922,502,539,612,382,986,655,60,334,318,826,302,796,56,404,447,988,192,191,139,838,179,686,469,154,9,603,981,842,97,250,644,530,64,803,670,570,605,122,881,32,948,69,255,325,808,707,643,135,608,926,141,716,559,922,376,532,680,64,269,370,546,196,922,284,801,436,380,772,125,139,265,361,566,454,14,104,835,475,127,266,2,685,637,2,487,135,540,849,281,216,252,662,915,849,797,424,609,7,31,509,850,965,927,464,539,622,94,62,744,91,421,619,773,870,992,768,25,841,559,219,977,892,475,973,745,790,140,762,560,700,558,613,739,387,810,850,420,882,526,193,387,900,816,318,959,297,205,380,759,519,646,2,182,268,229,289,191,571,579,293,898,946,913,741,298,436,669,14,838,882,304,966,19,688,289,636,413,581,256,939,93,555,933,598,898,922,535,70,117,51,258,154,193,424,957,128,605,12,739,277,518,737,757,156,643,723,224,410,919,854,558,169,754,814,803,185,92,478,769,461,805,340,102,246,780,700,987,785,22,526,365,121,168,295,991,974,119,602,584,704,351,127,418,215,600,433,801,965,326,340,661,697,869,414,544,418,644,311,912,684,662,732,672,977,514,71,269,875,62,949,845,673,664,903,766,122,425,675,248,943,168,173,172,621,384,410,739,614,925,841,197,118,847,363,706,632,434,566,494,853,353,191,699,775,12,180,646,519,989,142,623,256,557,351,831,942,203,694,228,947,216,276,655,615,625,141,976,808,81,329,122,517,833,947,813,509,811,820,641,131,161,482,291,411,196,703,88,107,167,194,375,788,645,369,642,478,677,856,804,82,570,942,730,844,364,989,746,365,594,795,43,700,750,464,742,302,835,425,435,29,664,505,453,399,27,983,939,335,276,617,44,506,151,47,22,29,490,44,807,807,156,277,363,126,882,199,122,499,487,371,725,723,588,262,725,956,437,171,516,884,18,248,786,171,919,493,755,783,156,106,262,756,334,834,513,768,365,597,330,569,729,952,167,272,552,599,182,145,733,518,67,931,766,379,231,419,938,715,581,624,222,792,356,793,684,423,192,162,214,436,395,180,292,596,371,604,715,436,628,250,859,76,153,179,341,596,417,146,486,11,265,687,363,98,200,55,699,483,843,771,114,204,532,577,805,112,156,726,115,670,742,924,769,236,905,421,143,365,104,570,147,764,288,650,390,982,52,83,210,98,139,988,215,575,491,61,52,552,278,408,162,189,484,899,702,178,306,56,60,284,384,931,68,559,785,587,835,683,328,917,519,515,51,836,594,32,777,515,398,646,871,80,604,191,908,302,459,201,968,134,750,887,767,25,397,333,289,965,598,360,441,718,151,159,884,633,388,357,56,902,842,160,675,293,922,707,418,798,676,414,378,755,810,669,648,666,671,421,657,243,248,796,700,474,192,894,888,765,858,183,582,688,236,971,624,178,867,165,836,406,712,572,963,70,23,248,883,499,666,52,55,110,46,136,842,619,896,854,791,243,476,879,975,112,349,259,74,81,625,44,817,811,69,638,667,707,461,635,440,999,953,427,52,265,350,578,461,222,53,580,957,954,223,784,379,502,700,245,376,458,580,214,789,458,710,473,708,351,951,998,847,471,179,690,692,100,392,247,185,728,88,762,35,375,725,139,674,913,911,457,342,149,234,331,132,919,887,405,241,624,347,41,708,369,494,972,985,35,279,204,835,579,321,113,712,519,437,516,691,486,871,68,810,536,370,223,993,512,198,134,123,176,995,994,134,332,790,476,817,534,134,553,693,605,973,572,166,123,678,879,406,377,316,842,584,832,372,773,257,445,435,110,827,748,358,929,944,119,51,374,771,458,357,742,4,265,281,710,171,692,97,429,260,685,571,649,292,739,109,199,748,578,781,739,921,317,138,472,432,496,987,366,175,491,297,215,457,154,904,324,495,991,467,412,991,522,50,673,855,392,900,922,733,683,722,762,857,997,638,301,318,906,906,563,298,639,204,994,151,631,952,908,238,518,777,8,458,543,874,267,600,257,998,766,486,357,541,200,699,484,500,123,575,890,941,218,766,230,830,576,603,884,283,779,440,883,453,718,695,264,146,943,704,375,179,813,835,849,214,156,65,10,557,515,875,393,722,194,264,140,409,892,754,22,97,368,834,841,27,863,75,663,914,0,142,471,503,811,68,429,989,129,61,750,648,97,39,57,929", "10,640,873,37,935,752,864,153,609,143,54,481,112,925,93,59,714,787,514,512,313,357,10,995,512,61,492,565,425,768,764,940,529,590,898,525,748,787,157,912,754,356,225,568,226,257,976,352,695,566,964,894,460,613,119,426,655,268,240,795,923,755,961,279,376,204,316,64,473,36,148,250,821,381,412,393,545,638,696,927,973,477,77,608,952,89,761,774,673,443,751,560,815,631,295,503,917,190,576,860,158,876,669,229,693,89,274,816,751,381,141,946,60,418,820,343,272,605,351,93,735,177,252,135,579,299,159,633,16,768,867,149,656,145,6,894,588,679,324,78,487,813,153,276,120,936,909,820,509,31,770,125,556,450,480,239,832,811,437,301,772,464,420,614,669,772,528,952,880,301,24,915,191,900,40,278,684,165,65,314,694,982,95,676,684,644,986,972,267,525,465,347,191,605,431,546,459,133,863,256,341,240,6,862,556,466,13,919,285,235,685,326,149,7,9,900,298,351,801,726,720,590,288,198,174,246,704,740,681,4,435,937,95,333,760,59,613,495,864,797,869,433,158,16,343,486,376,514,844,526,190,633,475,293,436,281,949,243,198,556,89,917,949,271,239,680,323,903,788,963,418,439,872,132,411,42,989,856,307,334,410,378,327,247,759,769,131,999,139,61,353,431,406,890,153,357,682,437,297,337,38,769,865,418,735,97,659,24,861,932,510,681,518,246,45,678,435,824,6,235,29,264,145,496,707,112,766,484,491,435,829,812,836,311,855,197,673,992,244,620,961,853,400,306,318,371,58,621,387,466,393,805,866,407,33,764,333,878,494,90,280,234,161,951,224,193,153,618,144,347,680,589,601,848,263,792,7,464,963,181,857,851,573,216,218,729,397,369,165,254,37,691,31,530,573,834,697,697,945,379,548,700,691,801,685,617,447,908,313,851,940,120,328,804,958,452,380,507,187,534,491,852,955,301,616,777,703,211,822,387,572,112,40,373,976,309,979,741,171,669,676,252,801,287,554,268,375,131,498,207,704,690,716,421,707,331,131,327,476,649,733,166,928,889,621,205,897,126,891,114,510,19,997,225,512,445,987,157,898,12,71,934,804,716,155,732,870,632,690,554,171,777,720,14,164,277,105,899,937,845,76,253,675,849,603,688,703,831,238,435,490,583,959,30,275,760,310,187,217,380,466,281,396,56,395,143,379,758,82,420,218,223,163,327,574,39,910,986,596,542,398,29,282,32,503,587,906,824,933,875,865,464,95,627,277,672,834,776,704,787,232,786,766,43,322,276,77,927,780,80,979,778,134,636,296,644,622,448,404,290,598,815,196,621,529,746,786,551,5,142,32,959,215,710,815,88,9,571,557,646,910,820,499,198,737,133,66,787,242,605,663,29,706,246,339,928,513,41,475,386,911,363,318,597,165,752,267,138,972,414,565,574,871,596,452,957,449,990,292,161,872,162,389,362,937,435,65,520,204,891,510,733,750,474,183,347,174,590,23,645,984,628,811,208,226,590,862,155,834,539,866,329,716,675,383,568,225,799,13,502,259,547,988,289,187,359,489,477,767,290,737,244,48,198,210,519,407,70,521,213,322,841,643,162,216,271,953,119,945,343,454,64,380,573,304,537,783,119,348,229,552,113,690,500,961,235,441,579,743,633,656,846,651,264,399,31,109,197,659,323,991,463,456,79,759,711,126,641,344,540,762,753,2,553,317,867,596,908,127,747,228,626,544,299,736,231,635,370,160,973,986,415,346,973,309,704,916,349,402,861,92,515,579,840,794,33,617,357,328,894,36,454,916,974,799,151,772,632,366,338,456,15,764,870,657,333,611,798,632,455,397,492,312,288,213,571,48,276,749,727,374,387,169,397,26,366,599,241,576,326,726,432,656,903,172,159,448,859,885,761,443,45,409,796,68,700,231,819,442,664,459,726,247,119,227,301,615,450,194,833,3,657,163,373,319,151,445,808,428,203,778,643,908,377,476,277,268,289,709,308,250,279,986,653,666,465,620,896,313,23,688,977,570,180,346,673,436,256,556,57,63,974,838,674,776,50,376,400,498,463,94,474,254,365,885,368,531,839,522,114,909,68,877,726,221,478,260,381,20,747,380,711,332,590,422,831,899,424,677,984,768,250,723,133,333,500,223,647,522,560,414,790,617,178,676,705,571,248,501,217,377,368,61,156,955,440,123,671,712,813,902,283,717,564,814,44,261,497,264,397,161,864,747,623,142,0,899,597,609,345,990,957,803,177,97,286,390,316,144,502", "856,908,838,50,668,873,676,787,912,837,774,88,687,76,172,404,112,46,779,798,219,476,245,668,525,814,30,615,315,332,875,149,313,607,284,211,424,359,847,792,540,205,415,602,342,246,342,388,413,402,298,972,958,770,859,530,705,677,251,583,301,85,748,762,396,235,910,878,129,225,736,84,318,938,404,885,575,77,113,355,110,833,95,189,833,984,79,32,594,323,509,598,884,822,890,523,299,598,768,837,824,33,572,484,733,684,787,755,228,13,348,203,999,246,355,309,440,503,683,448,707,73,282,519,267,379,829,669,155,885,951,43,302,304,928,870,874,349,967,448,779,139,40,826,233,20,920,515,345,415,476,853,317,681,962,381,282,686,210,173,23,583,170,298,547,811,616,257,387,871,274,66,19,329,98,409,512,266,443,678,52,918,612,444,761,165,308,112,886,433,424,877,421,266,173,278,684,402,770,498,931,668,791,979,118,508,256,849,663,907,930,668,479,354,20,541,27,738,60,884,514,177,894,334,740,219,156,834,261,615,673,39,994,737,597,911,77,797,628,861,653,597,935,627,530,531,427,569,736,366,413,738,946,83,101,257,737,553,804,585,6,338,526,979,704,700,487,134,715,163,329,913,11,962,681,57,561,986,87,396,201,475,899,709,911,884,526,186,232,278,441,230,876,517,417,348,80,989,740,193,871,911,170,523,736,718,327,973,227,217,423,961,553,278,449,734,102,140,846,812,830,141,114,440,236,922,420,284,540,765,484,726,894,82,339,109,891,982,973,414,826,163,616,849,212,966,188,347,576,533,296,747,393,879,89,450,148,931,297,337,201,28,646,113,727,866,568,154,503,530,613,556,769,386,302,593,195,658,102,507,214,646,968,791,442,212,853,674,633,889,330,618,116,264,989,90,483,427,786,318,644,784,580,248,223,677,735,627,557,170,838,263,207,738,978,700,985,817,377,447,787,555,345,133,146,463,945,757,434,899,125,833,406,598,539,503,776,904,55,226,891,100,306,317,678,136,799,874,468,510,783,395,131,29,217,347,759,886,578,938,920,483,555,949,180,470,485,312,430,298,674,665,370,611,537,638,223,953,721,745,313,407,652,624,450,445,897,825,492,886,814,638,878,2,951,697,330,356,546,133,899,398,672,2,836,167,135,361,499,636,59,937,163,224,973,107,228,3,550,560,355,339,357,777,461,632,424,75,239,154,763,994,283,123,271,844,222,946,710,859,526,419,398,259,876,985,412,86,350,285,225,678,512,918,460,818,437,922,838,137,187,410,156,721,490,950,772,163,826,206,88,199,74,316,799,307,8,666,465,938,978,766,409,6,620,394,313,99,928,751,151,733,242,965,766,658,38,868,767,382,633,280,37,458,446,896,338,457,749,291,591,993,209,611,629,614,901,73,128,859,603,651,13,182,711,314,672,821,123,287,324,719,500,986,917,439,3,728,968,895,466,558,139,559,678,630,26,252,991,724,791,675,514,338,919,771,810,496,416,400,516,532,517,170,682,988,506,828,864,857,567,475,991,266,900,275,302,337,26,233,341,854,851,746,244,980,162,403,897,308,413,326,905,915,499,595,490,883,542,277,307,401,259,542,392,888,711,659,69,697,30,425,496,805,201,979,709,47,886,397,381,648,606,48,562,800,760,839,751,823,300,42,450,721,930,244,426,570,219,269,236,191,363,787,209,21,155,122,178,880,131,346,398,626,693,488,918,742,94,136,688,797,539,531,533,314,27,390,485,403,486,141,408,632,674,645,505,790,473,316,305,731,59,190,118,467,201,717,983,616,289,726,917,404,881,988,926,960,67,742,690,467,695,677,467,588,508,793,887,751,329,784,236,38,456,677,613,102,773,741,508,30,370,254,759,260,718,997,284,306,955,171,637,636,377,966,57,124,734,991,672,64,488,832,446,462,974,330,48,546,67,597,138,611,786,826,721,125,60,600,323,588,278,567,560,854,607,272,569,183,480,109,82,186,520,377,761,780,615,470,785,819,279,505,610,199,365,400,295,865,26,262,658,125,201,518,316,129,91,745,954,622,48,751,890,925,402,400,917,16,811,201,682,701,344,162,81,966,412,663,251,704,533,362,958,200,709,500,996,427,202,551,102,80,199,144,347,14,239,600,633,867,949,285,712,227,344,469,987,57,452,21,384,963,589,410,748,17,614,751,798,628,436,676,738,996,904,68,714,864,950,320,464,326,60,130,563,650,730,546,775,741,484,107,471,899,0,904,128,454,911,169,787,433,506,779,37,169,778,235", "196,996,795,312,332,174,620,944,157,306,940,493,903,681,471,795,508,735,353,349,650,133,904,843,915,222,338,398,817,27,968,252,635,646,968,353,83,121,783,338,50,159,27,79,146,252,508,78,562,164,784,122,237,972,628,51,541,83,866,799,296,2,826,551,559,654,753,523,214,173,887,158,765,939,267,341,532,770,223,583,193,505,623,920,903,657,873,253,319,787,51,426,522,424,722,830,117,337,701,263,873,793,287,735,236,321,782,485,434,440,154,239,772,502,291,500,32,604,585,289,639,365,33,640,232,830,45,884,649,871,635,75,663,414,483,331,676,100,995,837,465,729,305,796,960,641,187,898,549,111,170,250,326,397,90,642,810,912,907,506,497,953,397,624,318,423,461,583,400,676,277,387,414,295,68,844,966,883,133,322,973,87,275,431,619,605,644,147,251,347,344,769,631,787,209,307,536,632,125,239,981,98,542,972,349,879,912,339,620,545,201,102,140,35,779,187,90,522,700,926,860,784,529,455,666,278,987,392,269,401,617,167,669,695,572,275,412,72,217,132,644,981,777,608,603,244,415,232,13,678,296,445,339,629,991,511,10,644,559,989,730,699,356,592,935,219,912,106,590,932,419,696,917,741,123,746,242,31,991,62,613,469,582,532,723,450,735,767,280,511,141,54,895,241,187,589,387,346,428,144,379,845,985,182,816,550,279,858,468,658,935,349,850,835,735,466,110,41,286,18,62,442,772,339,478,621,499,835,56,731,182,405,763,711,626,123,255,730,395,23,248,816,179,953,57,289,315,282,657,8,612,256,541,692,457,172,82,917,640,408,654,554,737,91,724,169,91,771,396,412,996,27,129,128,581,272,714,868,421,969,774,614,96,282,423,309,58,189,879,722,86,336,188,663,831,161,994,780,12,78,708,308,263,225,198,475,56,82,440,682,505,794,102,926,151,806,92,350,431,184,593,918,761,257,514,377,644,35,255,90,824,37,365,715,958,865,387,524,915,663,336,53,461,310,840,600,383,739,384,49,152,879,637,585,521,497,575,212,673,258,463,834,592,328,33,493,849,420,297,731,21,111,891,451,955,280,287,864,355,344,696,3,655,130,30,789,526,655,797,783,679,396,675,253,282,567,983,858,102,678,232,954,521,779,2,859,283,874,603,730,589,667,575,944,12,526,334,499,215,146,568,886,193,674,462,962,460,760,583,298,873,785,472,944,485,875,514,34,630,562,293,147,221,294,57,473,375,629,312,764,473,105,736,364,947,501,603,821,641,576,250,25,235,559,234,859,415,357,633,184,954,311,127,607,576,608,427,458,171,98,957,166,949,711,617,918,312,599,258,492,677,39,297,680,603,880,869,253,843,198,630,445,654,179,259,693,658,10,339,617,739,212,462,123,829,872,845,651,80,774,637,315,591,820,148,379,796,597,622,544,885,310,270,871,543,602,688,471,60,764,200,959,163,136,33,406,746,979,796,912,819,178,117,550,200,228,536,62,404,690,820,798,42,998,389,269,62,540,533,875,646,116,116,903,571,201,358,960,724,958,683,855,423,942,418,677,51,911,726,283,510,8,829,929,292,959,207,608,998,932,567,312,539,356,503,758,901,33,419,157,172,798,666,836,939,53,986,241,171,244,641,410,582,128,855,718,908,791,691,783,438,357,48,485,578,984,312,541,536,581,494,69,389,862,286,529,845,968,291,79,160,17,475,358,947,247,73,12,781,535,16,152,663,958,466,359,465,862,490,446,146,868,935,742,816,978,59,734,756,22,382,781,457,786,340,635,912,817,70,796,817,186,792,275,995,83,275,65,515,728,719,110,100,121,299,745,684,551,106,537,369,426,971,245,952,954,525,295,506,111,577,64,622,634,442,746,549,78,409,587,461,11,625,649,319,392,248,971,261,945,703,748,235,351,38,811,303,163,311,631,184,284,99,734,927,481,625,78,488,821,127,24,434,36,488,784,783,984,804,451,996,644,123,279,195,547,648,674,690,925,615,615,724,795,58,167,738,668,311,135,646,95,505,246,368,6,704,740,111,454,692,225,384,4,389,270,238,436,29,563,36,559,312,970,453,227,287,95,349,714,290,532,41,726,382,284,320,859,871,839,625,123,749,795,516,279,592,540,492,421,896,620,977,84,208,446,891,712,645,446,867,551,995,315,349,420,510,639,827,343,502,459,472,960,859,764,241,664,722,368,772,333,302,200,767,792,178,269,680,751,405,907,747,709,503,597,904,0,718,144,522,929,562,966,848,984,858,268,945,317", "146,874,296,367,465,771,901,919,875,561,501,422,380,694,11,700,417,558,386,396,157,689,801,366,52,49,519,787,474,563,154,529,315,92,873,128,88,885,198,801,888,665,427,1,191,400,320,165,641,995,714,56,13,265,382,222,242,988,319,502,574,378,171,181,826,296,139,946,268,927,706,756,512,489,239,308,699,708,630,494,129,278,294,949,301,179,298,786,745,868,119,132,888,655,507,527,883,79,739,521,407,625,403,145,219,668,593,660,769,138,151,592,234,238,532,711,893,501,491,973,517,490,55,649,686,906,937,607,107,753,511,695,367,906,297,804,19,605,402,774,560,683,367,116,793,662,792,264,983,826,936,941,701,871,915,167,349,299,417,373,498,296,555,974,632,355,722,936,622,483,88,812,274,40,868,629,177,234,333,15,433,142,669,864,98,841,695,478,158,738,672,200,406,822,679,723,467,300,472,156,858,463,739,929,764,768,365,771,567,820,593,374,954,489,107,291,509,469,76,567,160,618,761,42,607,195,186,495,94,593,524,242,727,134,293,411,166,592,110,682,776,449,89,866,324,353,177,292,277,487,639,178,833,887,266,256,657,416,937,880,472,787,316,751,256,151,874,242,445,854,599,831,634,916,297,72,370,626,845,822,874,444,734,366,287,80,671,557,23,498,100,764,45,984,293,895,279,635,917,458,486,206,183,600,382,125,232,621,962,113,40,838,107,301,680,401,274,206,101,484,323,101,390,270,5,729,674,205,730,760,66,352,891,569,57,330,86,500,938,790,843,420,162,504,36,524,231,937,626,585,440,103,116,852,244,872,2,5,654,71,212,822,706,618,170,960,243,40,413,123,121,745,980,201,264,358,325,485,670,456,253,87,459,546,816,427,383,598,571,951,90,967,525,446,953,624,608,794,499,805,634,6,758,214,805,918,423,488,439,959,668,426,197,954,477,149,480,623,192,110,263,487,6,24,847,104,500,588,665,128,440,710,649,393,541,621,418,184,766,502,981,777,884,792,671,141,729,989,134,624,750,552,694,838,57,340,943,315,598,424,621,47,422,906,376,875,901,333,982,296,531,438,716,795,22,15,285,962,260,508,517,941,792,496,928,994,300,875,166,604,978,184,795,451,417,721,717,316,431,212,58,147,291,492,383,284,727,456,887,939,213,244,506,914,211,119,756,330,569,297,938,23,604,963,408,125,249,193,331,515,137,851,811,69,681,272,285,37,333,18,364,139,414,523,958,686,45,917,621,567,760,319,637,81,712,883,151,241,19,915,446,947,912,414,271,359,595,552,44,403,110,246,871,22,407,818,688,744,207,437,478,818,672,22,641,619,601,730,430,313,802,994,968,737,571,923,569,928,807,959,603,185,156,741,935,70,477,358,483,726,965,13,694,701,730,44,476,90,150,87,21,792,725,982,900,982,182,824,405,592,968,212,193,213,381,780,126,581,305,814,299,354,226,904,839,772,309,128,294,460,382,231,335,489,14,477,722,592,129,236,514,119,193,957,714,268,887,524,587,845,483,439,997,691,256,718,489,85,646,558,3,195,525,889,879,596,50,307,518,980,365,304,855,804,482,886,815,377,974,412,177,438,462,971,500,721,601,740,623,553,365,211,987,634,686,662,904,631,368,998,572,289,986,440,293,770,146,49,964,464,993,822,83,820,988,843,656,883,785,33,716,519,622,327,818,352,244,868,74,700,884,868,99,955,682,499,537,674,428,486,237,292,153,101,271,265,738,846,592,694,220,447,120,29,786,967,891,637,76,602,454,539,875,9,223,33,304,736,588,156,397,348,922,172,770,921,242,947,436,883,816,259,460,320,224,426,933,651,645,480,164,35,252,205,234,130,151,599,875,439,259,560,508,62,809,853,603,327,823,938,462,978,769,270,464,161,29,741,432,676,24,874,851,91,469,130,762,933,11,173,150,911,466,371,376,65,294,269,117,453,408,890,915,902,538,814,244,387,430,343,129,175,662,216,396,421,46,116,640,458,138,808,574,606,549,588,765,370,777,165,115,275,112,500,106,843,1,532,43,947,336,385,184,743,39,184,867,550,268,755,739,325,785,65,398,342,917,955,367,404,408,13,362,746,523,924,194,529,644,827,691,953,418,602,367,522,548,607,166,895,915,531,534,653,740,466,931,126,450,239,650,587,662,527,597,55,851,359,879,129,118,349,230,413,411,954,499,445,493,255,798,185,648,331,478,806,521,254,16,443,781,611,709,539,811,609,128,718,0,304,763,861,915,954,383,375,470,836,512,405", "484,212,199,307,78,921,788,638,272,793,457,604,224,119,477,100,523,492,707,9,426,824,291,931,172,558,296,288,999,642,768,402,969,752,260,824,690,237,322,523,21,688,97,5,576,820,339,133,722,963,418,12,529,308,539,367,659,484,340,649,979,423,625,998,487,48,65,351,496,483,327,297,959,880,990,43,665,176,48,709,797,963,410,826,83,763,573,974,933,972,7,29,964,381,820,548,969,845,284,993,613,639,528,515,684,732,797,591,14,211,777,757,718,508,425,34,385,340,383,341,251,791,226,129,593,41,957,139,687,345,950,758,865,409,66,63,303,838,441,836,46,250,181,910,213,534,794,325,880,222,341,51,786,304,536,672,896,197,201,692,548,748,789,718,752,272,605,938,588,183,262,510,551,683,30,741,202,742,87,558,62,258,189,715,402,498,37,615,212,530,299,552,923,206,8,159,577,666,621,286,880,813,394,168,161,755,262,118,118,617,525,810,339,886,482,543,315,501,452,603,174,518,609,888,502,133,3,674,917,661,549,760,897,402,396,326,171,228,415,355,962,576,60,767,40,424,365,122,92,610,824,966,625,910,349,144,349,832,950,1,308,202,985,38,107,794,406,58,472,924,440,879,914,822,570,34,33,857,481,306,552,818,711,238,913,240,334,831,933,682,89,128,153,515,809,264,60,14,179,763,993,600,210,405,523,42,359,956,327,412,125,15,310,462,405,731,404,185,485,778,892,612,581,974,307,725,992,239,34,992,38,319,82,749,824,734,602,152,271,416,937,700,808,776,22,828,808,350,52,949,246,850,304,644,846,1000,74,648,467,873,280,237,552,667,612,387,269,752,110,867,276,256,121,281,447,760,232,121,31,671,748,345,485,586,927,270,760,575,7,408,899,275,717,211,953,151,961,90,740,763,640,402,32,818,515,422,581,843,422,834,181,325,185,520,618,650,37,360,338,910,620,516,331,270,435,283,773,444,279,998,641,636,689,359,489,595,721,384,12,57,879,758,343,450,411,98,157,487,804,469,596,342,696,289,268,710,435,775,969,586,416,768,825,395,652,364,569,655,909,626,388,934,472,156,964,793,283,427,482,320,332,795,732,197,565,757,213,50,891,272,970,511,647,880,511,429,54,965,608,784,266,448,146,43,459,477,401,102,160,818,789,360,514,978,435,747,987,176,446,827,190,13,856,996,757,519,639,394,905,383,950,503,848,8,558,957,631,403,247,726,381,264,267,78,895,54,41,165,489,206,5,596,794,218,864,622,982,758,610,116,972,421,161,735,214,369,29,145,858,956,719,549,463,125,215,207,266,613,660,956,150,663,575,694,673,989,395,685,176,258,929,317,686,944,102,690,458,211,928,17,844,625,857,581,505,224,911,12,618,930,538,374,43,713,282,164,596,534,84,32,975,211,781,879,532,740,318,982,354,98,408,430,966,501,986,658,253,165,102,86,704,350,986,369,64,660,410,284,120,713,379,574,31,864,570,747,583,30,754,617,300,868,936,751,25,476,600,655,935,452,761,978,712,112,656,273,605,2,739,348,665,998,755,857,535,755,787,557,256,415,330,187,356,192,373,506,312,601,590,533,425,212,163,232,215,653,37,933,523,25,560,22,943,437,768,943,414,759,525,306,279,83,71,349,399,741,213,761,578,62,607,731,466,702,767,328,317,417,210,763,224,351,284,967,762,651,852,615,501,598,391,834,698,644,816,628,914,230,772,575,489,312,23,519,575,600,947,538,516,185,552,352,986,36,505,630,325,418,359,669,949,729,899,214,94,34,818,530,545,986,833,651,511,225,456,869,564,202,233,601,143,780,570,671,727,946,647,916,351,258,719,600,479,670,652,864,454,120,79,966,49,376,857,610,467,248,455,787,500,701,658,450,616,179,946,251,473,264,458,412,33,636,846,879,930,196,465,866,506,249,375,402,294,844,221,185,969,823,457,368,430,124,265,150,61,580,675,828,195,65,52,459,168,618,67,215,125,958,294,648,941,387,637,875,737,923,894,916,170,558,958,584,480,826,139,400,318,361,166,969,548,765,551,317,71,437,857,955,514,55,933,740,968,928,322,296,628,194,170,388,566,767,262,768,514,355,769,632,297,675,394,502,590,908,651,655,458,855,743,217,652,684,371,917,128,812,700,424,542,657,410,596,353,134,361,894,13,743,965,110,393,158,456,83,267,365,179,802,713,681,591,946,624,30,484,236,333,961,962,894,283,700,270,283,68,345,454,144,304,0,363,296,465,366,886,101,554,676,72,890", "229,342,149,885,957,89,450,579,354,838,773,806,259,340,810,803,684,267,798,485,416,227,723,664,689,944,755,659,375,996,925,960,182,103,105,599,645,91,847,585,935,517,866,141,723,497,746,590,642,961,892,778,652,295,161,306,976,289,869,530,576,68,692,724,239,912,389,922,179,158,766,762,256,586,953,745,550,944,252,579,170,962,148,644,601,572,172,664,901,288,37,414,181,806,479,42,457,250,32,607,741,40,449,117,964,723,420,843,641,228,765,290,602,963,258,248,690,581,54,705,447,55,553,400,370,483,302,171,377,638,564,487,495,180,893,403,485,742,103,58,710,605,146,628,949,930,312,725,141,748,618,311,955,838,911,520,130,131,969,294,776,47,477,669,808,856,894,191,684,846,401,386,608,684,73,960,370,525,235,882,157,520,741,599,884,625,57,128,549,83,200,492,653,720,539,332,903,49,105,389,488,233,496,792,808,848,608,816,638,980,904,692,619,746,586,84,488,535,918,630,380,608,424,7,129,79,607,124,313,717,112,92,432,228,703,487,918,623,124,548,853,857,252,718,610,11,705,677,336,306,350,766,123,338,492,903,169,746,274,464,620,558,932,821,597,943,289,29,833,780,944,697,275,829,834,562,116,427,924,432,437,183,849,821,629,904,931,63,948,301,413,187,115,503,691,640,291,896,435,755,649,494,152,791,495,827,639,660,874,130,114,536,257,305,76,456,446,966,138,739,257,664,271,617,537,98,999,635,559,725,329,216,628,300,599,371,237,302,619,921,340,917,318,681,917,803,399,726,987,873,629,999,449,144,948,993,43,15,239,339,514,186,403,5,838,143,785,923,951,899,470,764,446,941,460,872,796,545,805,941,87,20,106,825,683,38,597,581,784,285,122,80,310,645,16,812,515,961,75,846,194,124,173,753,709,656,241,757,365,777,131,254,451,687,904,511,828,231,8,546,558,268,183,367,766,569,743,589,26,601,511,235,7,341,514,388,73,230,6,987,363,363,283,290,775,714,709,656,785,108,175,756,871,413,604,795,113,614,422,463,608,333,784,84,914,450,85,102,994,398,794,806,578,992,722,575,110,798,712,60,990,102,985,572,50,491,388,982,986,952,500,765,681,781,924,784,208,603,71,646,117,184,167,968,35,420,55,898,464,165,487,177,559,838,663,145,124,112,222,533,231,696,830,959,51,148,414,685,71,531,238,134,265,786,293,953,40,993,548,669,546,679,427,468,517,882,157,228,479,47,912,946,206,904,383,340,344,540,972,464,331,344,161,317,232,635,947,795,132,836,781,250,928,255,522,541,11,411,844,968,243,42,95,745,421,68,647,458,904,227,593,842,482,86,652,972,449,238,275,176,658,939,330,24,189,154,710,832,981,859,542,545,150,968,767,905,664,900,427,351,986,763,941,27,127,858,559,901,676,408,834,932,225,190,368,593,395,159,301,559,309,247,843,594,751,485,347,46,878,241,801,587,698,935,319,939,19,442,624,248,372,963,226,81,435,705,717,829,628,379,463,792,24,691,584,431,391,910,914,645,428,661,250,680,677,793,961,122,740,461,658,123,777,526,887,353,955,570,280,309,656,661,37,920,590,268,779,845,946,27,279,470,781,264,424,376,901,514,420,67,162,280,936,165,15,970,751,327,644,361,59,310,472,320,753,956,51,973,624,824,826,472,264,234,65,752,189,288,794,230,13,737,130,566,673,253,58,172,98,443,367,251,229,788,959,972,498,613,220,921,658,515,615,65,879,162,885,201,620,631,337,394,77,586,66,17,2,648,330,927,211,845,935,927,17,953,640,238,894,957,795,994,944,39,714,163,538,893,698,55,833,530,842,381,518,315,270,478,136,519,727,321,45,512,359,163,989,440,249,347,246,235,182,239,777,960,496,319,503,967,748,954,558,687,687,203,393,512,363,823,833,138,440,469,571,16,803,848,92,563,761,877,364,486,399,386,647,368,963,212,560,342,558,205,134,434,357,555,779,512,448,659,363,784,911,17,292,583,344,540,972,457,786,946,644,826,506,608,683,610,183,625,289,956,975,710,957,89,367,224,876,805,845,332,648,604,308,381,264,161,857,611,288,224,399,378,826,911,481,936,436,115,973,987,793,172,1,181,250,918,211,265,372,923,445,727,291,230,763,455,243,432,604,539,883,613,90,640,867,572,429,69,269,408,63,571,723,294,113,209,712,887,426,333,563,901,90,6,793,755,333,991,733,723,429,990,911,522,763,363,0,329,820,653,851,673,292,869,264,19", "344,778,675,215,826,607,981,758,480,805,153,624,908,936,282,313,301,368,648,43,60,858,723,51,511,67,175,179,765,198,205,323,143,914,699,220,31,440,250,388,369,235,650,815,305,172,317,927,717,568,972,566,711,595,423,715,702,896,566,360,931,616,331,337,482,710,624,154,481,537,122,749,624,703,757,798,271,235,294,785,92,901,485,952,115,405,708,650,715,207,115,239,585,65,701,951,31,6,968,435,630,321,87,731,216,72,722,155,367,517,195,14,246,917,243,964,216,313,708,261,906,648,172,302,848,204,39,54,412,586,14,849,576,444,811,985,295,72,427,508,825,774,157,183,965,136,478,938,91,925,768,605,893,115,65,213,787,372,642,679,980,61,697,278,1000,37,482,22,226,11,788,113,226,980,320,27,744,89,775,104,681,547,65,188,883,345,244,749,437,904,385,154,565,121,859,411,837,231,526,471,24,392,637,537,417,844,771,746,935,9,451,517,492,455,753,979,503,347,79,582,846,614,332,359,617,48,262,746,94,833,932,865,342,549,746,605,160,991,133,48,737,738,754,669,48,769,734,887,404,662,688,260,951,80,712,187,235,418,364,260,670,96,42,883,709,446,25,305,716,711,334,442,683,812,212,905,421,421,363,745,282,448,589,7,230,589,103,982,765,908,962,67,688,556,420,118,963,10,305,467,862,247,169,996,118,636,838,512,141,211,413,485,724,451,637,836,363,162,276,213,1000,911,645,540,394,504,63,750,796,374,242,591,637,588,92,392,329,701,266,758,833,527,785,131,285,975,322,599,427,697,616,971,505,93,836,807,64,293,583,737,482,290,404,574,28,789,561,945,395,737,676,31,835,667,57,512,160,861,206,389,283,580,336,64,140,379,666,794,4,211,836,919,359,315,526,970,791,624,759,639,427,722,147,427,267,28,813,937,764,613,849,391,918,974,715,202,80,230,298,934,967,822,606,459,908,804,336,214,332,986,926,982,592,142,570,488,528,593,121,138,533,703,455,441,2,412,193,878,845,473,479,814,194,556,856,497,641,74,381,478,990,170,810,880,178,495,751,898,493,303,334,554,727,765,902,295,448,207,352,655,935,804,89,754,411,48,566,370,117,513,992,917,973,924,210,897,694,79,135,196,131,13,634,526,863,664,49,490,482,489,283,863,744,68,799,538,696,528,241,713,646,231,213,269,254,64,948,826,82,912,29,892,829,667,811,800,471,493,26,838,71,79,684,947,352,361,984,433,698,166,400,959,335,308,998,252,366,707,436,327,540,498,379,117,912,8,825,337,396,53,73,231,496,50,59,159,508,511,750,396,880,439,654,744,945,253,185,121,15,479,194,378,694,908,501,410,315,112,724,476,581,184,972,952,190,56,743,545,53,725,950,681,627,394,39,489,972,270,939,657,987,290,324,488,142,904,829,565,273,11,913,695,858,981,750,231,254,964,409,879,435,347,933,216,148,961,651,205,398,771,191,761,789,289,660,975,547,404,718,771,191,800,515,618,415,671,142,666,155,524,320,919,338,38,874,183,541,961,988,58,80,1,989,282,263,785,231,164,593,468,852,805,763,535,676,600,47,197,50,316,376,561,60,52,228,691,314,863,623,345,781,998,313,632,653,856,509,476,812,310,269,597,258,32,8,232,682,826,253,873,771,64,911,261,552,235,400,890,739,285,654,787,728,899,44,392,47,270,398,953,69,975,122,568,502,721,799,250,132,866,258,457,327,354,846,95,345,103,550,976,342,855,304,907,593,197,309,377,512,70,461,44,788,649,837,864,536,932,1000,97,245,961,401,589,101,343,667,419,289,366,678,195,845,992,713,502,967,29,528,632,419,56,361,858,188,446,861,251,351,377,148,748,336,171,29,231,402,966,797,905,143,819,411,760,172,942,369,272,147,384,691,289,387,578,417,583,26,130,905,27,921,778,250,673,135,101,436,853,339,463,711,799,363,18,342,522,76,577,586,906,570,380,899,798,551,549,953,587,318,509,504,744,155,329,766,846,312,195,496,498,957,573,797,76,262,420,600,809,923,232,513,177,901,984,61,541,406,403,569,494,359,479,927,651,71,755,99,189,322,280,916,951,192,279,290,780,161,351,815,962,357,459,7,107,392,770,880,222,248,845,398,849,397,859,490,176,831,195,113,94,625,377,895,431,329,992,511,231,356,473,67,619,720,647,161,65,680,136,604,280,786,322,910,70,160,124,132,272,954,207,210,537,486,509,989,957,169,929,861,296,329,0,733,760,213,714,470,259,629,120", "870,657,941,565,559,196,210,75,128,229,171,840,843,567,609,202,33,548,992,934,676,549,881,467,394,664,875,626,354,319,156,739,404,842,899,164,60,95,318,179,617,805,824,371,125,307,426,905,325,305,553,91,109,459,636,686,474,32,604,652,440,992,638,782,130,911,517,527,171,953,924,6,611,456,252,525,984,514,922,932,641,362,995,575,547,978,333,783,537,241,459,623,819,212,700,637,801,99,217,740,60,629,625,963,17,87,64,673,440,710,69,50,956,682,592,407,476,627,31,980,940,175,649,561,260,569,794,619,67,856,632,515,275,686,762,155,867,85,940,220,786,397,935,594,536,765,348,942,474,178,655,940,601,370,320,735,769,804,726,118,46,670,961,119,349,234,47,1000,939,915,851,103,648,129,637,71,352,386,710,594,542,865,301,517,53,265,774,530,420,565,708,422,779,30,780,143,421,14,320,249,157,103,690,975,112,796,132,139,318,221,844,256,122,204,60,376,860,514,175,537,662,603,638,284,883,426,487,239,359,601,657,205,44,990,259,528,474,389,10,842,124,194,590,609,318,308,53,454,709,373,425,34,728,922,907,909,947,167,414,336,280,860,494,437,730,98,543,802,60,274,662,662,694,242,198,942,473,218,296,429,764,345,603,363,479,154,200,285,807,72,733,938,55,946,607,503,677,128,480,152,335,519,181,707,523,306,395,989,586,273,572,210,266,924,170,807,793,718,114,504,482,808,195,789,200,516,625,468,780,5,464,274,358,906,6,255,602,606,218,467,689,456,271,305,567,35,262,355,439,599,276,42,833,989,404,400,105,998,996,845,560,139,635,1,878,826,282,109,161,507,272,499,824,989,815,198,729,739,336,484,686,631,940,260,323,42,839,202,440,886,542,480,253,278,158,206,782,245,502,678,273,44,648,11,76,387,279,798,155,904,985,418,991,413,735,211,679,458,277,435,541,874,582,735,374,509,438,403,29,531,339,42,809,46,812,39,795,895,156,824,499,530,471,53,292,547,935,258,666,220,816,772,136,197,844,416,520,567,613,15,696,339,321,638,398,321,183,572,630,232,737,561,988,937,461,830,941,113,830,582,378,852,379,121,598,230,493,928,503,121,844,479,569,788,919,987,495,412,256,924,487,349,429,571,212,896,486,139,486,657,780,142,890,644,557,444,855,993,768,701,943,171,934,913,697,200,199,358,8,116,806,42,311,685,684,126,861,740,658,365,983,833,26,587,60,221,892,140,912,662,49,652,103,628,972,576,545,265,159,627,617,728,527,829,628,428,374,4,111,807,391,695,917,913,698,688,953,274,108,841,681,596,373,244,668,348,275,830,214,881,868,855,46,589,338,114,768,654,109,237,177,973,860,70,437,672,816,33,484,290,891,775,881,507,785,559,112,473,540,695,494,541,107,137,761,574,105,856,134,342,424,85,858,154,197,283,739,961,662,648,701,700,774,338,49,107,716,33,42,636,180,406,397,576,938,812,486,743,590,254,636,627,787,749,103,133,665,333,728,397,464,728,155,315,723,270,182,678,759,635,886,153,750,903,613,751,271,554,474,898,701,207,850,396,726,41,524,38,983,896,269,285,128,177,372,729,884,445,10,9,427,171,161,447,150,481,729,891,716,773,872,355,728,742,648,166,679,763,609,689,6,923,750,315,47,412,659,233,627,258,555,600,430,772,311,661,341,520,705,410,664,830,981,266,182,262,89,572,131,320,868,602,438,855,541,625,891,61,712,963,312,509,511,960,506,780,108,493,282,934,919,672,947,913,854,68,477,247,684,636,61,768,550,922,360,193,649,848,255,713,838,587,177,282,355,276,643,679,527,584,218,89,963,988,662,223,469,199,622,937,602,375,381,647,790,588,676,955,924,817,441,225,399,849,650,357,889,284,121,747,592,588,894,154,396,510,610,180,486,173,558,621,502,26,653,117,65,132,728,256,678,423,191,404,926,642,331,975,730,972,506,743,871,183,959,784,258,940,860,709,638,489,54,641,854,272,751,325,951,539,373,786,136,80,880,977,62,475,528,608,394,665,912,124,732,485,649,605,271,911,839,439,660,894,747,602,349,628,942,38,691,467,987,722,942,796,625,940,211,282,393,67,903,910,75,335,476,517,634,257,165,828,670,869,252,788,558,702,779,434,750,911,562,409,841,361,661,176,542,562,207,871,170,283,711,359,264,347,92,463,654,200,141,727,308,863,569,188,729,720,917,68,232,416,129,803,787,562,915,465,820,733,0,536,220,501,595,482,893,939", "673,755,533,658,501,535,594,191,192,418,405,598,909,700,956,319,895,544,935,861,299,415,696,952,472,857,740,723,615,425,984,542,646,553,381,802,872,355,779,511,137,526,478,459,831,4,878,281,382,390,534,124,889,524,259,504,245,950,518,332,165,164,118,546,258,552,1,818,467,474,206,222,851,729,76,129,129,16,885,762,379,68,978,944,648,537,582,251,522,798,426,849,969,148,499,142,910,96,452,84,494,703,81,632,164,941,407,105,545,502,297,755,13,538,100,595,27,81,757,617,869,528,723,55,626,340,441,833,64,892,230,316,607,422,23,386,6,881,311,322,273,359,430,950,596,117,206,696,957,641,806,620,77,914,322,669,252,481,364,694,13,534,202,276,897,273,717,445,804,79,502,370,571,275,272,441,913,313,120,764,306,317,310,445,446,457,527,570,205,847,651,812,48,102,459,115,979,616,830,765,173,882,871,913,68,9,773,339,591,674,209,733,717,691,154,640,256,41,526,58,809,379,667,832,682,128,493,724,553,207,349,325,842,188,986,835,446,840,606,161,505,161,638,17,295,106,732,180,623,903,727,489,245,740,79,995,590,566,613,564,448,13,67,298,351,340,375,91,844,795,575,980,940,693,73,638,16,394,435,520,572,747,634,819,142,380,569,873,806,52,936,634,45,760,617,459,485,639,427,717,573,690,464,802,23,211,682,742,648,392,393,319,896,48,526,61,402,961,891,67,942,437,556,327,755,46,465,411,934,68,504,458,65,804,577,935,257,45,581,763,352,846,798,799,343,987,977,723,561,732,187,301,280,196,588,569,606,286,229,23,845,965,684,878,814,106,880,406,238,897,638,331,200,942,773,185,406,908,316,305,840,796,751,604,859,671,844,834,688,444,112,149,636,648,651,297,187,164,453,768,972,34,497,982,753,578,931,666,341,303,873,939,197,561,517,598,549,207,896,754,598,468,480,69,450,848,525,350,226,843,402,990,730,452,491,325,217,694,539,400,186,156,393,7,197,758,16,393,199,389,53,581,926,129,732,945,738,608,649,159,190,920,342,246,683,153,506,111,14,568,907,623,327,317,114,104,694,286,819,487,413,69,428,214,490,6,151,947,945,887,72,241,279,513,357,737,187,908,862,845,146,889,415,432,260,371,861,415,625,446,87,24,488,528,747,278,953,836,599,393,609,448,208,659,698,114,648,192,182,247,661,737,415,251,185,450,948,552,759,447,594,500,675,705,571,645,45,304,897,851,713,990,401,688,818,499,185,863,13,345,191,648,76,208,917,756,339,300,549,661,661,495,110,952,545,833,220,65,635,423,90,89,257,442,955,674,767,573,549,773,712,692,879,224,204,500,924,312,255,550,411,922,570,224,636,774,227,914,373,684,199,779,817,369,28,72,688,837,752,963,910,238,923,31,730,615,407,509,592,508,439,172,887,623,500,287,787,37,471,344,460,832,56,313,305,818,431,55,873,59,920,891,210,888,728,387,279,78,563,869,176,966,472,889,865,704,380,963,429,381,226,379,134,302,448,505,445,828,881,458,454,875,502,229,956,652,711,912,564,208,456,927,941,607,730,244,601,323,716,403,535,272,830,669,38,691,493,909,672,342,112,264,803,938,938,200,331,410,445,401,609,65,431,682,134,868,875,719,381,884,551,10,554,861,275,846,481,355,854,724,400,394,415,46,827,520,754,676,835,101,707,593,814,723,353,464,3,614,92,120,364,855,633,248,320,765,320,667,548,935,296,253,674,429,380,361,281,921,336,138,8,299,967,673,839,607,264,84,147,592,75,462,524,892,991,916,726,911,27,342,799,224,968,732,304,168,846,752,535,306,647,619,65,993,55,63,406,822,464,793,51,265,606,994,663,981,655,374,267,309,773,209,15,59,7,590,934,429,956,55,293,106,566,729,504,19,744,77,293,993,428,290,408,505,37,986,895,943,909,275,572,303,529,154,793,184,241,575,594,863,702,49,319,852,854,975,551,392,78,484,273,286,670,83,777,406,984,845,51,173,435,797,552,563,815,776,267,386,523,440,294,78,145,785,277,471,870,234,209,527,835,521,492,808,560,727,896,869,982,811,351,659,376,652,145,372,915,152,631,300,799,712,239,593,44,350,510,225,981,253,642,942,226,995,671,84,138,954,133,862,762,907,502,828,35,635,40,405,407,826,263,964,595,697,205,426,978,618,180,182,646,327,160,161,904,392,839,305,276,686,515,769,71,629,61,177,433,966,954,366,653,760,536,0,306,869,543,70,739,138", "738,777,422,738,195,191,198,543,279,373,94,59,500,346,414,137,529,755,59,212,313,53,138,259,79,71,570,142,824,99,474,466,542,30,407,441,996,215,257,281,359,420,142,23,447,326,748,352,535,22,845,87,90,763,143,997,62,867,645,788,448,721,382,13,219,522,597,35,601,900,223,15,117,521,662,740,929,788,418,496,710,172,348,710,636,329,774,183,729,276,214,755,886,295,327,547,621,867,519,949,246,280,78,471,251,215,46,984,185,925,46,354,679,883,914,344,958,402,788,421,300,198,993,886,753,654,613,919,959,307,533,462,902,157,829,563,973,894,188,498,223,51,691,864,257,984,732,580,905,999,835,868,694,629,574,96,129,213,89,981,929,304,250,637,705,467,821,975,635,793,581,775,535,306,167,152,401,918,882,695,150,87,618,580,271,573,825,518,600,161,165,395,637,937,187,588,500,439,298,451,903,883,910,43,860,291,224,54,340,388,477,339,645,242,221,561,662,102,622,33,116,605,108,80,987,71,718,524,58,399,946,348,508,744,866,233,787,1,824,183,63,878,586,991,831,125,914,720,860,158,826,310,296,691,301,217,967,435,750,744,148,902,783,452,690,531,267,265,474,392,104,707,141,696,653,265,884,346,703,295,586,595,216,218,538,739,877,70,162,663,839,692,409,689,75,799,41,495,660,45,907,288,607,58,194,716,636,192,354,132,922,250,319,590,4,119,971,652,752,646,308,820,376,118,563,817,698,340,66,717,484,385,551,55,364,502,436,845,967,949,228,653,963,267,430,393,388,235,881,633,312,873,633,713,112,201,242,642,514,257,300,853,996,436,695,105,392,456,973,953,492,882,925,718,336,737,47,574,924,449,888,237,368,133,853,493,773,589,220,803,950,653,782,781,827,43,4,843,210,706,49,213,394,964,73,16,681,708,279,58,80,638,780,128,926,873,984,492,47,724,934,140,306,632,767,658,375,810,764,268,63,918,283,911,60,489,176,720,909,146,892,731,63,630,350,627,529,360,639,633,838,427,342,372,867,114,666,592,993,738,905,183,409,850,326,720,944,233,7,250,266,945,267,690,830,566,302,997,418,518,411,795,423,941,75,235,518,342,813,719,504,863,717,661,318,43,351,175,225,922,423,329,48,311,61,786,756,362,813,779,114,621,28,727,384,670,561,445,983,358,597,191,543,163,814,603,641,79,199,565,413,986,913,243,983,117,381,562,235,647,788,986,277,651,307,14,966,693,912,38,811,244,647,61,85,959,688,133,319,404,73,949,19,729,695,427,531,770,455,701,732,362,473,357,834,139,219,791,558,262,531,601,186,80,939,455,478,169,712,900,112,748,122,161,353,461,831,986,119,798,801,309,100,244,716,365,421,611,456,821,481,237,883,195,978,164,747,772,703,134,266,757,129,427,325,938,934,751,951,257,340,623,718,11,791,423,850,890,656,872,985,225,940,13,367,113,419,445,221,950,864,82,98,724,214,543,787,279,486,764,919,504,258,154,764,339,630,286,645,342,138,453,818,390,71,394,816,915,993,11,517,181,272,636,271,322,700,705,746,830,154,411,995,394,858,629,106,224,365,190,978,876,587,241,981,484,410,55,918,287,156,848,187,102,571,9,459,201,76,284,580,758,502,416,660,639,36,545,299,178,854,427,989,67,807,846,814,2,388,840,684,340,307,11,530,996,513,133,736,389,879,168,45,382,602,698,588,194,601,619,316,428,467,84,617,599,76,873,172,798,10,202,229,313,557,203,901,360,935,704,107,427,937,964,669,329,958,918,648,793,850,111,247,753,655,581,247,259,443,934,61,8,821,527,496,554,491,185,218,308,548,133,158,485,525,90,319,186,833,925,137,680,590,537,863,433,433,981,437,712,6,94,209,415,51,524,449,416,4,129,600,270,846,194,292,299,840,808,377,204,707,573,21,937,358,538,638,149,515,509,383,847,397,48,80,138,24,297,120,817,333,499,103,545,487,939,136,757,83,997,52,974,86,852,22,920,874,674,999,79,230,946,856,115,753,252,76,653,907,788,31,409,652,284,301,439,421,419,271,642,423,502,968,126,78,995,619,960,437,421,129,62,40,551,113,491,843,774,988,605,922,703,369,222,370,800,271,553,818,342,396,727,765,260,819,759,704,35,338,178,565,173,631,926,897,747,311,730,959,674,740,997,793,472,681,213,314,369,444,539,340,169,729,334,699,28,250,186,385,418,426,174,668,760,750,97,506,848,383,886,851,213,220,306,0,594,607,823,46,234", "250,470,227,191,588,89,834,926,878,295,105,286,311,353,349,796,570,250,847,148,317,366,632,852,412,722,945,972,510,541,227,972,102,317,947,142,250,188,342,220,14,151,20,997,465,542,885,941,137,101,378,84,635,790,62,869,741,743,344,288,186,948,20,190,554,873,717,245,586,998,285,945,667,705,93,784,83,722,517,416,469,393,839,98,431,186,767,250,226,420,880,47,101,936,131,309,778,419,293,421,543,934,230,778,934,638,70,103,444,879,369,151,898,307,331,370,450,307,391,324,23,644,404,937,959,779,101,215,49,487,296,629,172,185,197,129,293,449,901,919,33,880,574,552,118,150,7,265,711,93,59,941,353,387,950,269,389,943,656,182,698,124,904,112,601,927,83,866,577,679,831,163,374,228,891,63,274,211,332,786,401,157,81,181,338,444,458,3,743,147,392,638,777,959,398,537,864,42,568,222,175,279,246,476,543,955,887,859,979,699,109,845,189,659,72,716,698,367,743,614,312,914,685,404,755,958,108,144,828,76,237,369,429,855,901,365,977,491,759,485,71,572,325,341,624,401,466,750,549,910,309,971,766,507,841,937,514,730,26,856,607,649,397,474,557,470,925,2,309,277,364,633,827,95,269,732,502,650,209,463,771,111,134,533,955,614,787,805,464,690,701,16,646,931,32,333,464,277,168,518,299,727,177,592,940,566,527,333,274,715,350,770,206,162,495,820,894,842,455,904,111,114,529,692,635,236,761,25,229,152,189,585,512,249,382,865,117,826,744,801,438,349,164,942,421,932,163,329,970,108,412,428,467,397,953,664,78,747,831,983,713,476,736,73,329,821,113,232,676,721,552,326,459,187,517,833,952,896,900,460,908,561,538,650,817,210,7,948,379,567,274,719,897,566,103,138,571,845,407,292,497,588,115,77,15,302,895,856,85,679,371,308,286,999,595,513,406,465,259,56,955,101,780,49,603,587,777,313,247,22,669,845,198,701,318,940,439,987,573,633,23,957,240,96,207,618,701,603,671,437,334,314,672,898,606,662,782,183,676,769,492,386,561,836,777,286,377,562,135,498,709,770,555,398,476,32,765,93,675,604,165,657,184,741,862,385,794,548,198,417,537,619,917,525,353,477,386,167,207,541,84,33,164,945,338,71,702,193,501,545,201,473,893,809,918,600,952,854,573,845,102,38,772,912,428,129,469,364,394,332,407,775,229,252,177,759,542,21,894,600,906,705,460,791,474,372,572,770,846,284,563,119,146,750,609,98,410,653,564,117,547,92,353,158,336,623,456,816,527,861,339,534,267,904,256,747,95,939,469,984,20,426,581,745,791,927,928,458,630,252,184,194,965,891,588,538,36,833,159,179,163,286,606,440,81,933,556,994,523,261,986,101,551,94,166,915,385,179,245,119,234,877,803,994,881,955,587,773,195,958,296,192,404,28,397,224,368,644,183,915,614,787,627,462,732,800,131,428,681,2,649,395,942,635,235,240,237,71,373,745,421,694,489,757,441,668,677,548,993,862,455,879,891,464,820,324,830,332,712,675,364,682,591,5,736,335,986,3,497,705,272,954,568,928,667,443,250,218,2,251,219,717,495,612,966,183,782,555,867,687,170,119,269,638,388,283,863,604,852,887,811,622,901,28,660,758,312,555,969,192,903,187,623,648,663,3,116,189,303,952,640,987,746,614,866,934,356,965,253,83,991,363,577,51,181,988,780,524,768,252,995,393,394,18,100,843,762,323,103,424,510,92,198,6,787,934,34,141,488,76,684,414,767,458,515,547,784,508,438,955,230,491,468,974,811,20,723,349,11,80,323,82,616,855,85,781,769,682,991,207,516,869,230,899,892,510,339,22,460,72,690,150,225,154,129,207,473,58,968,151,869,429,312,242,468,332,338,712,614,515,191,84,380,983,338,126,646,272,301,700,188,213,146,506,354,419,231,920,829,291,863,169,91,888,999,879,992,623,463,125,234,517,302,472,346,918,564,964,868,726,95,535,200,235,274,227,995,667,302,687,300,75,72,302,333,286,225,838,276,822,34,79,872,186,265,200,984,613,90,181,372,326,93,890,805,98,304,977,738,834,549,808,474,67,136,532,997,61,86,613,675,714,768,188,116,99,169,245,520,647,588,353,292,290,321,186,144,440,268,570,387,352,722,627,443,150,878,10,455,920,93,52,295,5,766,98,482,785,986,411,350,806,853,636,734,663,251,352,487,513,643,659,858,565,648,286,779,984,375,101,673,714,501,869,594,0,718,226,115,140", "949,233,581,136,558,761,984,692,552,501,113,889,890,938,545,278,443,44,425,11,400,208,795,559,556,894,753,722,200,396,499,390,929,756,739,826,984,750,915,154,45,476,675,387,811,846,942,920,924,101,960,738,992,218,791,336,734,280,942,468,299,766,923,272,335,872,207,232,131,86,177,61,676,756,88,202,904,14,638,775,216,815,956,995,444,896,28,593,416,727,506,929,569,239,509,22,316,324,490,533,941,70,24,996,798,835,913,329,61,271,527,147,180,925,358,711,81,619,444,362,163,139,353,925,634,237,730,135,509,612,86,269,794,684,138,753,514,937,161,716,171,627,145,124,767,282,629,449,276,524,665,65,866,47,953,512,761,384,272,511,744,491,66,400,857,366,981,58,643,401,595,188,530,273,380,603,716,651,15,106,81,365,559,667,912,38,738,605,559,16,360,207,421,314,222,673,31,507,173,483,215,203,398,516,220,68,389,557,768,884,623,203,627,963,188,294,230,866,768,170,326,277,197,813,845,36,588,138,978,874,913,810,544,669,617,746,392,227,860,514,395,264,606,260,416,184,565,23,649,606,474,293,407,568,151,577,58,463,818,547,623,140,493,535,978,619,966,269,831,173,712,62,794,537,590,981,904,529,452,711,641,273,200,565,681,379,736,532,38,515,958,934,116,925,851,500,600,614,147,817,846,215,381,149,471,119,230,832,282,398,315,626,913,964,633,732,166,155,932,449,774,294,900,265,423,541,204,50,465,554,581,210,928,754,766,488,241,977,401,655,488,342,473,371,751,767,711,367,15,181,276,501,411,597,864,874,883,126,652,39,353,947,586,65,945,22,668,199,600,899,517,999,860,720,71,917,614,864,863,325,886,223,529,70,302,86,356,749,943,940,864,682,756,710,122,15,685,740,489,418,331,505,386,246,682,439,365,950,536,877,457,885,830,528,872,128,738,716,340,644,350,954,811,480,165,9,371,304,193,398,318,460,351,750,739,898,535,852,706,226,946,336,764,975,941,505,757,14,75,625,613,664,67,562,961,430,189,321,207,46,796,511,668,912,281,1,874,126,966,512,780,728,722,761,812,263,860,846,551,733,217,624,734,640,194,647,24,500,523,972,19,165,22,961,711,667,670,631,173,154,343,782,384,531,912,525,55,903,24,158,8,769,158,560,595,948,992,302,571,697,732,637,197,514,66,578,551,751,67,389,457,913,458,542,740,720,682,156,677,571,888,512,558,186,972,644,481,651,750,977,897,216,496,557,50,91,736,661,333,291,455,42,151,5,413,412,108,813,706,957,113,568,217,683,339,634,656,78,299,678,155,943,575,882,120,194,464,24,931,90,11,857,137,18,487,617,116,670,474,766,266,642,171,132,196,155,536,559,973,128,421,756,586,426,588,118,102,811,326,750,586,888,830,152,592,949,144,24,557,868,274,79,810,101,841,398,173,909,387,448,503,725,749,520,426,952,667,853,18,415,894,222,577,291,136,433,42,701,963,72,532,201,836,165,652,323,391,854,959,887,667,145,522,132,739,804,359,90,531,791,825,772,101,254,274,876,876,228,507,502,336,377,501,189,605,252,405,70,423,80,805,529,511,94,345,488,160,454,104,328,592,149,499,16,500,913,269,527,609,33,258,184,508,384,497,748,35,397,125,771,585,131,322,326,546,263,462,345,278,469,503,964,191,628,391,957,459,389,956,204,328,107,394,700,157,356,291,953,154,385,397,977,33,193,348,162,599,853,679,976,645,534,656,853,708,41,177,22,527,634,729,265,940,492,262,305,215,26,786,232,886,766,311,956,782,3,541,500,639,953,663,440,129,316,529,553,870,432,904,706,952,185,550,281,978,247,379,38,330,754,131,705,348,553,723,131,316,694,664,402,973,399,386,74,105,326,986,657,773,627,916,186,941,77,867,946,876,277,486,584,951,609,999,908,231,593,344,266,300,408,623,250,839,584,98,382,394,805,58,530,942,714,19,64,659,781,699,519,214,187,149,423,198,858,812,791,14,398,122,311,196,491,975,218,334,952,983,123,261,682,242,918,509,560,447,197,872,993,93,539,201,145,991,138,184,590,262,211,543,584,114,559,492,399,586,669,950,118,33,874,807,66,937,997,291,271,83,831,620,472,571,249,304,586,289,231,858,442,189,96,150,755,662,552,315,711,987,952,182,917,826,308,1,259,467,620,348,751,895,487,735,171,818,815,350,484,119,162,284,167,518,974,141,360,97,390,37,858,470,554,292,470,595,543,607,718,0,111,148,996", "264,547,470,994,952,182,953,111,249,346,50,744,142,415,824,7,314,258,998,943,54,865,664,243,623,213,250,844,475,347,518,668,488,635,102,696,757,537,995,887,687,415,715,259,474,547,9,953,388,970,213,30,279,177,574,152,255,501,898,55,796,82,53,163,355,22,795,514,661,537,48,403,583,234,720,348,402,869,343,81,279,604,911,848,89,999,996,112,218,40,711,800,8,533,268,649,313,229,520,160,914,448,983,454,947,191,611,54,193,378,32,256,498,193,893,945,200,289,98,307,74,141,583,483,925,978,311,473,959,530,404,970,237,456,835,201,826,919,551,890,168,461,932,877,700,832,111,917,351,509,136,950,205,564,284,101,787,308,782,166,115,134,48,570,838,544,42,831,983,525,201,678,385,599,755,155,859,179,792,437,348,816,561,885,412,907,799,538,621,294,298,456,253,486,332,942,885,736,304,438,492,602,639,682,147,672,253,428,529,987,334,807,543,657,413,938,142,543,934,805,708,983,6,52,532,867,198,506,817,813,378,542,626,914,30,563,644,454,290,535,687,480,7,588,510,197,999,185,731,210,2,565,251,509,923,923,992,919,679,448,650,136,492,868,493,351,477,11,704,676,637,140,758,856,888,880,669,63,224,39,411,507,314,517,346,921,542,953,732,262,825,524,301,2,713,801,76,841,347,17,831,62,921,950,151,557,476,401,590,59,566,446,489,327,386,103,531,976,817,21,819,519,784,311,678,536,79,250,628,171,43,838,461,889,161,147,714,685,410,720,826,360,776,963,653,796,466,295,365,997,585,180,712,547,455,419,200,838,26,89,515,416,370,574,583,764,580,157,337,771,877,360,579,381,451,868,715,255,940,641,110,935,23,726,393,850,342,893,148,399,657,235,774,685,899,491,103,992,792,272,872,626,598,403,685,295,234,591,32,890,283,734,586,779,242,660,630,87,32,188,961,85,954,898,525,86,177,455,663,976,641,219,465,985,989,452,948,670,654,657,159,962,37,704,933,381,938,188,236,878,280,568,911,184,976,625,603,511,526,756,136,842,545,720,938,952,226,135,51,256,316,245,96,313,243,438,849,172,517,203,229,487,320,179,494,978,248,85,329,486,601,30,49,811,356,617,138,850,622,287,108,574,554,709,990,61,392,388,702,990,19,551,51,623,953,990,430,253,50,752,527,946,175,957,804,840,859,600,634,555,364,154,398,980,512,81,360,216,311,560,26,458,626,957,948,594,356,954,591,268,92,242,39,987,270,886,516,388,266,552,600,749,611,943,109,97,76,806,91,515,897,354,108,315,416,472,671,411,127,354,106,777,992,495,875,674,617,507,620,818,608,323,436,97,926,839,25,831,185,843,150,909,415,342,33,23,856,23,972,127,981,916,441,286,488,93,862,155,843,795,640,530,271,96,513,73,680,839,16,543,611,816,424,450,941,558,909,872,725,654,299,647,644,484,24,20,628,462,226,130,937,868,982,452,789,156,231,907,701,63,241,387,353,860,520,831,779,487,242,67,789,710,976,204,353,821,960,181,114,478,224,138,155,469,547,948,261,878,973,10,475,437,418,424,144,674,635,196,268,376,456,370,727,652,931,997,450,371,496,180,664,105,854,462,407,561,86,110,320,772,27,197,386,75,880,958,136,475,331,401,816,877,690,293,252,28,987,113,273,66,53,947,120,440,211,813,265,714,775,347,720,781,745,929,950,43,148,558,481,60,598,517,667,940,594,283,11,185,587,876,289,175,940,349,833,673,462,655,276,706,428,898,832,563,350,12,680,865,168,135,195,242,13,389,101,50,799,684,537,76,159,922,859,928,407,737,774,847,143,118,293,48,965,977,443,525,370,48,594,795,640,511,539,464,281,47,654,745,876,7,162,991,306,458,180,5,884,518,892,56,166,328,166,438,844,311,724,747,403,216,651,111,82,975,291,110,854,271,145,995,545,471,804,228,125,11,592,244,343,949,253,745,50,89,65,675,323,729,430,90,648,396,835,389,740,741,444,117,596,110,634,625,445,693,564,134,806,505,79,684,39,167,560,680,739,545,259,942,56,392,347,931,862,239,492,496,869,502,780,269,220,588,744,797,245,629,44,616,580,485,550,636,93,617,929,925,990,537,393,124,505,898,418,90,233,988,816,38,79,884,746,68,688,239,3,22,263,464,971,744,630,776,916,336,932,263,634,442,747,106,603,308,732,36,895,443,773,957,323,391,150,422,230,936,39,316,169,268,836,676,869,259,482,70,823,226,111,0,125,756", "995,913,328,706,887,869,356,754,407,12,632,711,346,732,765,696,937,478,201,838,888,341,490,17,78,9,919,469,860,216,946,38,507,69,937,229,512,763,985,587,111,224,595,91,714,733,126,292,888,958,273,799,287,816,199,415,216,923,67,571,128,111,273,607,584,903,919,272,67,610,989,582,765,601,367,376,10,68,857,259,993,469,334,191,419,993,880,459,284,628,498,131,204,29,936,430,52,569,559,3,860,360,715,124,93,846,211,291,989,560,309,730,223,294,241,827,912,23,183,403,517,838,643,101,383,292,366,712,313,805,495,936,516,674,383,564,974,658,339,935,153,458,595,275,286,97,126,172,170,503,486,665,578,917,648,123,589,861,968,742,283,460,64,596,789,116,173,392,788,907,330,667,726,302,554,92,234,553,108,110,963,129,796,201,576,647,751,28,892,476,749,409,944,541,637,291,973,771,386,561,792,270,453,691,807,808,246,877,448,576,190,267,691,153,592,44,969,980,869,99,283,385,917,101,20,954,126,402,141,573,919,549,482,438,657,267,914,816,551,321,637,504,172,716,111,322,764,636,539,185,167,474,224,707,913,407,561,413,185,297,85,549,951,137,614,769,888,350,938,606,550,343,154,840,652,99,133,126,68,281,383,211,481,278,628,654,973,779,591,280,608,567,706,150,310,682,740,618,198,845,481,280,671,164,958,983,73,654,40,998,362,979,690,970,857,821,605,623,890,90,537,414,512,869,974,956,719,282,308,835,705,715,736,792,758,663,613,964,469,911,107,653,508,680,591,76,429,766,673,630,599,740,244,645,16,146,45,216,641,931,925,912,384,863,152,457,20,479,980,836,165,443,212,346,377,494,57,970,323,660,444,78,999,256,696,482,607,86,351,145,471,424,245,973,853,114,260,836,115,246,213,442,959,593,136,896,326,873,51,413,536,781,398,859,606,532,515,551,36,424,574,558,291,493,801,800,977,627,551,409,347,302,905,190,778,766,564,645,324,455,932,633,372,773,784,777,113,290,199,452,621,413,698,507,357,822,28,208,379,830,482,166,803,666,82,959,925,990,646,210,630,164,842,381,320,364,411,959,142,199,375,741,732,714,159,712,450,290,66,589,986,99,180,536,482,888,972,524,900,846,325,321,854,458,747,649,542,672,977,266,748,924,752,701,69,693,535,990,568,170,78,564,941,278,446,35,214,103,136,675,282,550,690,680,308,68,952,938,665,499,106,524,70,827,254,159,364,960,565,839,450,616,143,887,894,760,105,386,974,418,199,710,928,277,108,418,287,142,586,579,670,345,567,542,849,954,675,591,453,964,705,701,427,46,596,322,11,633,952,929,196,882,71,585,513,758,218,924,853,331,53,151,23,392,519,825,784,978,53,566,306,897,213,812,371,49,104,184,173,858,438,703,798,777,667,837,867,773,870,415,526,677,795,204,142,268,447,351,313,706,260,986,51,207,14,412,153,612,130,718,570,327,245,784,111,649,616,798,214,324,52,859,578,710,864,276,723,954,515,646,842,499,350,793,468,77,272,363,110,259,417,516,523,507,691,728,482,979,152,806,335,299,667,51,802,594,572,582,329,499,99,372,714,380,352,860,671,787,228,766,350,613,639,966,78,325,294,440,504,674,185,277,820,221,778,123,871,29,391,228,243,764,974,824,348,404,437,172,798,681,871,888,351,752,123,212,710,603,264,133,591,711,750,683,756,715,143,106,647,525,778,574,31,348,514,269,36,181,130,789,133,784,13,738,139,74,880,540,446,530,991,61,115,276,781,94,775,337,286,582,876,797,958,296,258,799,761,603,150,889,926,524,62,671,63,155,732,292,166,848,350,764,994,470,586,906,599,29,596,960,746,632,117,292,354,442,485,206,212,671,281,690,507,603,417,308,42,481,156,274,768,318,432,462,997,933,74,527,84,569,916,96,246,723,735,805,942,657,376,932,767,135,13,976,572,852,191,439,455,677,606,974,324,184,156,896,607,934,740,648,231,846,772,255,608,87,134,864,624,100,795,665,69,819,832,844,510,231,458,616,91,496,976,208,675,144,455,689,417,666,314,4,667,634,575,906,565,577,289,241,529,657,702,832,64,774,897,766,571,298,479,264,762,508,923,580,569,842,666,906,88,456,8,11,908,910,135,973,994,57,378,886,45,172,24,403,579,771,673,743,195,927,324,974,420,866,783,459,819,196,302,205,757,346,850,734,189,406,423,41,101,769,29,719,57,144,778,945,512,72,264,629,893,739,46,115,148,125,0,178", "873,804,976,299,90,282,615,299,823,509,738,437,999,899,501,303,758,899,69,148,774,947,127,83,684,438,756,264,851,423,653,22,979,697,938,476,835,349,915,966,543,921,590,967,536,647,303,665,776,407,861,136,956,895,714,816,95,248,232,469,342,863,439,446,5,597,578,554,817,694,280,785,433,895,943,111,838,776,945,718,38,592,387,416,150,191,159,679,468,640,82,205,520,91,777,692,275,944,185,906,451,254,461,770,778,253,469,419,250,439,573,600,15,197,465,187,269,872,433,387,560,262,280,665,741,90,735,233,103,641,808,457,944,853,496,38,190,623,124,160,152,872,214,844,868,835,99,147,224,600,328,457,211,453,287,716,216,642,327,47,738,983,570,503,554,235,52,392,409,532,155,563,142,996,683,596,14,351,778,821,564,492,48,344,967,595,861,884,472,531,503,973,116,849,500,944,757,127,67,48,216,361,224,444,479,733,503,356,159,802,964,185,200,690,456,444,447,123,819,784,461,196,430,627,883,260,956,882,747,861,452,255,324,627,644,642,181,823,801,167,366,878,369,792,451,561,244,825,81,905,894,612,576,432,169,776,105,184,181,572,598,807,415,777,188,358,587,921,402,84,784,180,491,220,957,260,207,259,3,875,895,910,605,976,72,786,275,350,858,464,655,829,145,769,725,362,719,880,941,521,595,754,565,605,371,403,459,394,33,763,856,793,356,481,16,297,974,188,248,960,639,524,876,993,791,460,136,83,783,834,165,358,377,195,873,773,242,297,711,232,711,208,201,18,154,88,983,592,35,102,83,696,522,215,404,315,66,673,651,235,397,271,588,54,143,940,689,584,573,505,210,293,418,471,887,961,185,724,361,77,587,699,702,220,394,838,526,560,286,325,612,826,280,881,80,804,184,866,403,404,250,682,522,953,408,199,189,127,477,132,386,648,404,585,177,356,603,523,370,555,398,670,832,533,481,796,966,30,718,178,308,351,863,796,188,132,289,588,713,47,140,785,829,719,796,601,487,497,605,474,298,1000,948,417,957,463,123,411,636,420,379,666,804,772,375,714,64,75,905,710,621,839,758,927,97,210,543,57,130,917,285,456,36,479,789,144,517,730,647,100,889,114,922,473,140,145,699,775,338,429,402,563,20,413,257,214,274,151,256,226,297,293,920,272,366,627,587,622,542,910,23,487,766,340,918,898,703,215,182,878,273,645,126,619,628,35,405,846,938,200,259,282,839,349,225,397,940,177,212,571,600,517,678,318,494,246,835,382,245,292,24,849,446,972,551,486,13,629,649,769,60,159,421,574,95,550,814,910,383,294,405,556,329,983,382,823,958,271,882,557,601,150,159,340,610,727,756,647,292,300,637,299,87,517,677,498,672,697,749,659,94,288,209,498,865,630,322,988,46,266,53,461,829,892,761,428,478,445,759,561,82,196,280,773,149,672,298,188,156,974,883,593,271,672,385,396,362,94,186,835,660,735,961,803,451,387,162,513,421,687,355,746,599,705,137,55,292,378,833,63,71,555,667,343,327,253,705,242,209,343,964,929,803,292,506,117,254,844,165,783,523,30,778,284,248,831,477,156,9,753,184,104,420,760,771,242,791,729,658,984,539,111,521,488,367,682,660,964,585,600,539,320,313,414,175,703,438,484,448,237,566,79,243,198,831,761,494,12,62,169,395,501,251,627,44,929,531,699,38,462,849,383,193,902,599,521,597,176,112,469,267,460,374,613,331,823,113,10,67,333,833,280,779,900,428,264,501,260,813,872,796,543,855,876,710,282,654,734,156,114,444,930,343,769,369,366,637,377,289,768,584,783,819,762,991,515,887,891,81,104,50,325,650,806,425,259,61,274,376,868,643,721,931,732,877,500,140,84,487,316,818,608,310,789,288,818,522,513,297,255,467,89,768,331,778,227,890,11,213,374,274,51,616,181,950,39,778,495,892,981,142,886,484,1000,205,498,773,209,168,929,899,38,421,838,199,468,967,33,751,760,480,757,242,921,826,765,160,604,184,935,562,618,829,61,824,939,506,997,201,605,265,463,499,862,406,232,3,780,625,286,465,529,121,462,751,131,589,587,107,35,972,560,297,130,947,814,724,519,243,246,422,860,920,916,353,639,909,456,510,577,616,566,973,24,661,578,481,899,798,145,225,983,251,561,990,773,555,890,581,632,883,992,38,67,688,798,721,247,91,756,857,873,484,813,710,100,29,235,687,526,714,853,365,181,929,502,235,317,405,890,19,120,939,138,234,140,996,756,178,0"] private lazy var graph = parseData(content) func solve() { Greedy(graph).solve() } } ================================================ FILE: performance/KotlinVsSwift/ring/src/InlineBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation func load(_ value: Int, _ size: Int) -> Int { var acc = 0 for _ in 0...size { acc = acc ^ value.hashValue } return acc } @inlinable func loadInline(_ value: Int, _ size: Int) -> Int { var acc = 0 for _ in 0...size { acc = acc ^ value.hashValue } return acc } func loadGeneric(_ value: T, _ size: Int) -> Int { var acc = 0 for _ in 0...size { acc = acc ^ value.hashValue } return acc } @inlinable func loadGenericInline(_ value: T, _ size: Int) -> Int { var acc = 0 for _ in 0...size { acc = acc ^ value.hashValue } return acc } open class InlineBenchmark { private var value = 2138476523 func calculate() -> Int { return load(value, Constants.BENCHMARK_SIZE) } func calculateInline() -> Int { return loadInline(value, Constants.BENCHMARK_SIZE) } func calculateGeneric() -> Int { return loadGeneric(value, Constants.BENCHMARK_SIZE) } func calculateGenericInline() -> Int { return loadGenericInline(value, Constants.BENCHMARK_SIZE) } } ================================================ FILE: performance/KotlinVsSwift/ring/src/IntArrayBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class IntArrayBenchmark { private var _data: [Int]? = nil var data: [Int] { get { return _data! } } init() { var list: [Int] = [] list.reserveCapacity(Constants.BENCHMARK_SIZE) for n in intValues(Constants.BENCHMARK_SIZE) { list.append(n) } _data = list } func copy() -> [Int] { return Array(data) } func copyManual() -> [Int] { var list: [Int] = [] for item in data { list.append(item) } return list } func filterAndCount() -> Int { return data.filter { filterLoad($0) }.count } func filterSomeAndCount() -> Int { return data.filter { Ring.filterSome($0) }.count } func filterAndMap() -> [String] { return data.filter { filterLoad($0) }.map { mapLoad($0) } } func filterAndMapManual() -> [String] { var list: [String] = [] for it in data { if (filterLoad(it)) { let value = mapLoad(it) list.append(value) } } return list } func filter() -> [Int] { return data.filter { filterLoad($0) } } func filterSome() -> [Int] { return data.filter { Ring.filterSome($0) } } func filterPrime() -> [Int] { return data.filter { Ring.filterPrime($0) } } func filterManual() -> [Int] { var list: [Int] = [] for it in data { if (filterLoad(it)) { list.append(it) } } return list } func filterSomeManual() -> [Int] { var list: [Int] = [] for it in data { if (Ring.filterSome(it)) { list.append(it) } } return list } func countFilteredManual() -> Int { var count = 0 for it in data { if (filterLoad(it)) { count += 1 } } return count } func countFilteredSomeManual() -> Int { var count = 0 for it in data { if (Ring.filterSome(it)) { count += 1 } } return count } func countFilteredPrimeManual() -> Int { var count = 0 for it in data { if (Ring.filterPrime(it)) { count += 1 } } return count } func countFiltered() -> Int { return data.count { filterLoad($0) } } func countFilteredSome() -> Int { return data.count { Ring.filterSome($0) } } func countFilteredPrime() -> Int { let res = data.count { Ring.filterPrime($0) } return res } func countFilteredLocal() -> Int { return data.cnt { filterLoad($0) } } func countFilteredSomeLocal() -> Int { return data.cnt { Ring.filterSome($0) } } func reduce() -> Int { return data.reduce(0) { if (filterLoad($1)) { return $0 + 1 } else { return $0 } } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/IntBaselineBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class IntBaselineBenchmark { func consume() { for item in 1...Constants.BENCHMARK_SIZE { Blackhole.consume(item) } } func allocateArray() -> [Int] { var list: [Int] = [] list.reserveCapacity(Constants.BENCHMARK_SIZE) return list } func allocateArrayAndFill() -> [Int] { var list: [Int] = [] list.reserveCapacity(Constants.BENCHMARK_SIZE) for item in 1...Constants.BENCHMARK_SIZE { list.append(item) } return list } } ================================================ FILE: performance/KotlinVsSwift/ring/src/IntStreamBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class IntStreamBenchmark { private var _data: AnySequence? = nil var data: AnySequence { return _data! } init() { _data = AnySequence(intValues(Constants.BENCHMARK_SIZE)) } func copy() -> [Int] { return Array(data) } func copyManual() -> [Int] { var list: [Int] = [] for item in data.lazy { list.append(item) } return list } func filterAndCount() -> Int { return data.lazy.filter { filterLoad($0) }.count } func filterAndMap() { for item in (data.lazy.filter { filterLoad($0) }.map { mapLoad($0) }) { Blackhole.consume(item) } } func filterAndMapManual() { for it in data.lazy { if (filterLoad(it)) { let item = mapLoad(it) Blackhole.consume(item) } } } func filter() { for item in (data.lazy.filter { filterLoad($0) }) { Blackhole.consume(item) } } func filterManual() { for it in data.lazy { if (filterLoad(it)) { Blackhole.consume(it) } } } func countFilteredManual() -> Int { var count = 0 for it in data.lazy { if (filterLoad(it)) { count += 1 } } return count } func countFiltered() -> Int { return data.lazy.count { filterLoad($0) } } func countFilteredLocal() -> Int { return data.lazy.cnt { filterLoad($0) } } func reduce() -> Int { return data.lazy.reduce(0) { if (filterLoad($1)) { return $0 + 1 } else {return $0 } } } } extension LazySequence { func count(where test: (Element) throws -> Bool) rethrows -> Int { return try self.filter(test).count } } ================================================ FILE: performance/KotlinVsSwift/ring/src/LambdaBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class LambdaBenchmark { @inlinable public func runLambda(_ x: () -> T) -> T { return x() } private func runLambdaNoInline(_ x: () -> T) -> T { return x() } init() { Constants.globalAddendum = Int.random(in: 0 ..< 20) } func noncapturingLambda() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambda { Constants.globalAddendum } } return x } func noncapturingLambdaNoInline() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambdaNoInline { Constants.globalAddendum } } return x } func capturingLambda() -> Int { let addendum = Constants.globalAddendum + 1 var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambda { addendum } } return x } func capturingLambdaNoInline() -> Int { let addendum = Constants.globalAddendum + 1 var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambdaNoInline { addendum } } return x } func mutatingLambda() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { runLambda { x += Constants.globalAddendum } } return x } func mutatingLambdaNoInline() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { runLambdaNoInline { x += Constants.globalAddendum } } return x } func methodReference() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambda(referenced) } return x } func methodReferenceNoInline() -> Int { var x: Int = 0 for _ in 0...Constants.BENCHMARK_SIZE { x += runLambdaNoInline(referenced) } return x } } private func referenced() -> Int { return Constants.globalAddendum } ================================================ FILE: performance/KotlinVsSwift/ring/src/LoopBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class LoopBenchmark { var array: [Value] init() { var list: [Value] = [] for n in classValues(Constants.BENCHMARK_SIZE) { list.append(n) } array = list } func arrayLoop() { for x in array { Blackhole.consume(x) } } func arrayIndexLoop() { for i in array.indices { Blackhole.consume(array[i]) } } func rangeLoop() { for i in 0...Constants.BENCHMARK_SIZE { Blackhole.consume(i) } } func arrayWhileLoop() { var i = 0 let s = array.count while (i < s) { Blackhole.consume(array[i]) i += 1 } } func arrayForeachLoop() { array.forEach { Blackhole.consume($0) } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/MatrixMapBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class Pair: Hashable { init(_ pair: (Int, Int)) { self.pair = pair } public var pair: (Int, Int) public func hash(into hasher: inout Hasher) { hasher.combine(pair.0) hasher.combine(pair.1) } public static func == (lhs: Pair, rhs: Pair) -> Bool { return lhs.pair == rhs.pair } public var hashValue: Int { var hasher = Hasher() self.hash(into: &hasher) return hasher.finalize() } } class KMatrix { let rows: Int let columns: Int internal init(_ rows: Int, _ columns: Int) { self.rows = rows self.columns = columns for row in 0...rows-1 { for col in 0...columns-1 { matrix[Pair((row, col))] = Double.random(in: 0 ..< 100) } } } private var matrix: [Pair: Double] = [:] func get(row: Int, col: Int) -> Double { return get(Pair((row, col))) } func get(_ pair: Pair) -> Double { return matrix[pair] ?? 0.0 } func put(_ pair: Pair, _ elem: Double) { matrix[pair] = elem } static func +=(lhs: inout KMatrix, rhs:KMatrix) { for entry in lhs.matrix { lhs.put(entry.key, entry.value + rhs.get(entry.key)) } } } class MatrixMapBenchmark { func add() -> KMatrix { var rows = Constants.BENCHMARK_SIZE var cols = 1 while (rows > cols) { rows /= 2 cols *= 2 } var a = KMatrix(rows, cols) let b = KMatrix(rows, cols) a += b return a } } ================================================ FILE: performance/KotlinVsSwift/ring/src/OctoTest.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation struct UnsupportedOperationException: Error { let message: String } class Leaf : NodeEntity, Equatable { static func == (lhs: Leaf, rhs: Leaf) -> Bool { return lhs.value == rhs.value } var value: T init(_ value: T) { self.value = value } override func toString() -> String { return "L{$value}" } } class NodeEntity: Node { func toString() -> String { return "" } func set(x: Int, y: Int, z: Int, value: T, depth: Int) throws -> Bool { throw UnsupportedOperationException(message: "set on Leaf element") } } private protocol Node { associatedtype T func set(x: Int, y: Int, z: Int, value: T, depth: Int) throws -> Bool func toString() -> String } class Branch : NodeEntity { var nodes = [NodeEntity?](repeating: nil, count: 8) override init() {} init(_ value: T, _ exclude: Int) { var i = 0 while (i < 8) { if (i != exclude) { nodes[i] = Leaf(value) } i += 1 } } private func canClusterize(_ value: T) -> Bool { var i = 0 while (i < 8) { let w = nodes[i] if (w == nil || !(w is Leaf) || value != (w as? Leaf)?.value) { return false } i += 1 } return true } override func set(x: Int, y: Int, z: Int, value: T, depth: Int) throws -> Bool { let branchIndex = OctoTree.number(x, y, z, depth) let node = nodes[branchIndex] if (node == nil) { if (depth == 0) { nodes[branchIndex] = Leaf(value) return canClusterize(value) } else { nodes[branchIndex] = Branch() } } else if let leaf = node as? Leaf { if (leaf.value == value) { return false } else if (depth == 0) { leaf.value = value return canClusterize(value) } nodes[branchIndex] = Branch(leaf.value, OctoTree.number(x, y, z, depth - 1)) } if (try nodes[branchIndex]!.set(x: x, y: y, z: z, value: value, depth: depth - 1)) { nodes[branchIndex] = Leaf(value) return canClusterize(value) } return false } override func toString() -> String { return nodes.map { $0?.toString() ?? "null" }.joined(separator: ",") } } class OctoTree { let depth: Int init(_ depth: Int) { self.depth = depth } private var root: NodeEntity? = nil private var actual = false func get(_ x: Int, _ y: Int, _ z: Int) -> T? { var dep = depth var iter = root while (true) { if (iter == nil) { return nil } else if let leaf = iter as? Leaf { return leaf.value } dep -= 1 iter = (iter as! Branch).nodes[OctoTree.number(x, y, z, dep)] } } func set(x: Int, y: Int, z: Int, value: T) { if (root == nil) { root = Branch() } do { if (try root!.set(x: x, y: y, z: z, value: value, depth: depth - 1)) { root = Leaf(value) } } catch { print("Exception") } actual = false } func toString() -> String { return root?.toString() ?? "" } static func number(_ x: Int, _ y: Int, _ z: Int, _ depth: Int) -> Int { let mask = 1 << depth if (x & mask != 0) { if (y & mask != 0) { if (z & mask != 0) { return 7 } return 6 } if (z & mask != 0) { return 5 } return 4 } if (y & mask != 0) { if (z & mask != 0) { return 3 } return 2 } if (z & mask != 0) { return 1 } return 0 } } func octoTest() { let tree = OctoTree(4) let to = (2 << tree.depth) var x = 0 var y = 0 var z = 0 while (x < to) { y = 0 while (y < to) { z = 0 while (z < to) { let c = (z + to * y + to * to * x) % 2 == 0 tree.set(x: x, y: y, z: z, value: c) z += 1 } y += 1 } x += 1 } x = 0 y = 0 z = 0 while (x < to) { y = 0 while (y < to) { z = 0 while (z < to) { let c = (z + to * y + to * to * x) % 2 == 0 let res = tree.get(x, y, z) assert(res == c) z += 1 } y += 1 } x += 1 } } ================================================ FILE: performance/KotlinVsSwift/ring/src/ParameterNotNullAssertionBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class AnyInstance {} let OBJ = AnyInstance() class ParameterNotNullAssertionBenchmark { func methodWithOneNotnullParameter(_ p: Any) -> Any { return p } private func privateMethodWithOneNotnullParameter(_ p: Any) -> Any { return p } func methodWithTwoNotnullParameters(_ p: Any, _ p2: Any) -> Any { return p } private func privateMethodWithTwoNotnullParameters(_ p: Any, _ p2: Any) -> Any { return p } func methodWithEightNotnullParameters(_ p: Any, _ p2: Any, _ p3: Any, _ p4: Any, _ p5: Any, _ p6: Any, _ p7: Any, _ p8: Any) -> Any { return p } private func privateMethodWithEightNotnullParameters(_ p: Any, _ p2: Any, _ p3: Any, _ p4: Any, _ p5: Any, _ p6: Any, _ p7: Any, _ p8: Any) -> Any { return p } func invokeOneArgWithNullCheck() -> Any { return methodWithOneNotnullParameter(OBJ) } func invokeOneArgWithoutNullCheck() -> Any { return privateMethodWithOneNotnullParameter(OBJ) } func invokeTwoArgsWithNullCheck() -> Any { return methodWithTwoNotnullParameters(OBJ, OBJ) } func invokeTwoArgsWithoutNullCheck() -> Any { return privateMethodWithTwoNotnullParameters(OBJ, OBJ) } func invokeEightArgsWithNullCheck() -> Any { return methodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) } func invokeEightArgsWithoutNullCheck() -> Any { return privateMethodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) } } ================================================ FILE: performance/KotlinVsSwift/ring/src/PrimeListBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class PrimeListBenchmark { private var primes: [Int] = [] func calcDirect() { primes = [] primes.append(2) var i = 3 while (i <= Constants.BENCHMARK_SIZE) { var simple = true for prime in primes { if (prime * prime > i) { break } if (i % prime == 0) { simple = false break } } if (simple) { primes.append(i) } i += 2 } } func calcEratosthenes() { primes = [] primes.append(contentsOf: 2...Constants.BENCHMARK_SIZE) var i = 0 while (i < primes.count) { let divisor = primes[i] primes.removeAll(where: { $0 > divisor && $0 % divisor == 0 }) i += 1 } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/StringBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class StringBenchmark { private var _data: [String]? = nil var data: [String] { get { return _data! } } var csv: String = "" init() { var list: [String] = [] list.reserveCapacity(Constants.BENCHMARK_SIZE) for n in stringValues(Constants.BENCHMARK_SIZE) { list.append(n) } _data = list csv = "" for _ in 1...Constants.BENCHMARK_SIZE-1 { let elem = Double.random(in: 0.0..<100.0) csv += String(elem) csv += "," } csv += String(0.0) } func stringConcat() -> String? { var string: String = "" for it in data { string += it } return string } func stringConcatNullable() -> String? { var string: String? = "" for it in data { string? += it } return string } func stringBuilderConcat() -> String { var string: String = "" for it in data { string += it } return string } func stringBuilderConcatNullable() -> String { var string: String? = "" for it in data { string? += it } return string! } func summarizeSplittedCsv() -> Double { let fields = csv.split(separator: ",") var sum = 0.0 for field in fields { sum += Double(field) ?? 0.0 } return sum } } ================================================ FILE: performance/KotlinVsSwift/ring/src/SwitchBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation struct ConstParams { static let SPARSE_SWITCH_CASES = [11, 29, 47, 71, 103, 149, 175, 227, 263, 307, 361, 487, 563, 617, 677, 751, 823, 883, 967, 1031] static let V1 = 1 static let V2 = 2 static let V3 = 3 static let V4 = 4 static let V5 = 5 static let V6 = 6 static let V7 = 7 static let V8 = 8 static let V9 = 9 static let V10 = 10 static let V11 = 11 static let V12 = 12 static let V13 = 13 static let V14 = 14 static let V15 = 15 static let V16 = 16 static let V17 = 17 static let V18 = 18 static let V19 = 19 static let V20 = 20 static var VV1 = 1 static var VV2 = 2 static var VV3 = 3 static var VV4 = 4 static var VV5 = 5 static var VV6 = 6 static var VV7 = 7 static var VV8 = 8 static var VV9 = 9 static var VV10 = 10 static var VV11 = 11 static var VV12 = 12 static var VV13 = 13 static var VV14 = 14 static var VV15 = 15 static var VV16 = 16 static var VV17 = 17 static var VV18 = 18 static var VV19 = 19 static var VV20 = 20 } struct NumbersObj { static let shared = NumbersObj() private init() { } let V1 = 1 let V2 = 2 let V3 = 3 let V4 = 4 let V5 = 5 let V6 = 6 let V7 = 7 let V8 = 8 let V9 = 9 let V10 = 10 let V11 = 11 let V12 = 12 let V13 = 13 let V14 = 14 let V15 = 15 let V16 = 16 let V17 = 17 let V18 = 18 let V19 = 19 let V20 = 20 } class SwitchBenchmark { func sparseIntSwitch(_ u : Int) -> Int { var t : Int switch (u) { case 11: t = 1 case 29: t = 2 case 47: t = 3 case 71: t = 4 case 103: t = 5 case 149: t = 6 case 175: t = 7 case 227: t = 1 case 263: t = 9 case 307: t = 1 case 361: t = 2 case 487: t = 3 case 563: t = 4 case 617: t = 4 case 677: t = 4 case 751: t = 435 case 823: t = 31 case 883: t = 1 case 967: t = 1 case 1031: t = 1 case 20: t = 1 default: t = 5 } return t } func denseIntSwitch(_ u : Int) -> Int { var t : Int switch (u) { case 1: t = 1 case -1: t = 2 case 2: t = 3 case 3: t = 4 case 4: t = 5 case 5: t = 6 case 6: t = 7 case 7: t = 1 case 8: t = 9 case 9: t = 1 case 10: t = 2 case 11: t = 3 case 12: t = 4 case 13: t = 4 case 14: t = 4 case 15: t = 435 case 16: t = 31 case 17: t = 1 case 18: t = 1 case 19: t = 1 case 20: t = 1 default: t = 5 } return t } func constSwitch(_ u : Int) -> Int { var t : Int switch (u) { case ConstParams.V1: t = 1 case ConstParams.V2: t = 3 case ConstParams.V3: t = 4 case ConstParams.V4: t = 5 case ConstParams.V5: t = 6 case ConstParams.V6: t = 7 case ConstParams.V7: t = 1 case ConstParams.V8: t = 9 case ConstParams.V9: t = 1 case ConstParams.V10: t = 2 case ConstParams.V11: t = 3 case ConstParams.V12: t = 4 case ConstParams.V13: t = 4 case ConstParams.V14: t = 4 case ConstParams.V15: t = 435 case ConstParams.V16: t = 31 case ConstParams.V17: t = 1 case ConstParams.V18: t = 1 case ConstParams.V19: t = 1 case ConstParams.V20: t = 1 default: t = 5 } return t } func objConstSwitch(_ u : Int) -> Int { var t : Int switch (u) { case NumbersObj.shared.V1: t = 1 case NumbersObj.shared.V2: t = 3 case NumbersObj.shared.V3: t = 4 case NumbersObj.shared.V4: t = 5 case NumbersObj.shared.V5: t = 6 case NumbersObj.shared.V6: t = 7 case NumbersObj.shared.V7: t = 1 case NumbersObj.shared.V8: t = 9 case NumbersObj.shared.V9: t = 1 case NumbersObj.shared.V10: t = 2 case NumbersObj.shared.V11: t = 3 case NumbersObj.shared.V12: t = 4 case NumbersObj.shared.V13: t = 4 case NumbersObj.shared.V14: t = 4 case NumbersObj.shared.V15: t = 435 case NumbersObj.shared.V16: t = 31 case NumbersObj.shared.V17: t = 1 case NumbersObj.shared.V18: t = 1 case NumbersObj.shared.V19: t = 1 case NumbersObj.shared.V20: t = 1 default: t = 5 } return t } func varSwitch(_ u : Int) -> Int { var t : Int switch (u) { case ConstParams.VV1: t = 1 case ConstParams.VV2: t = 3 case ConstParams.VV3: t = 4 case ConstParams.VV4: t = 5 case ConstParams.VV5: t = 6 case ConstParams.VV6: t = 7 case ConstParams.VV7: t = 1 case ConstParams.VV8: t = 9 case ConstParams.VV9: t = 1 case ConstParams.VV10: t = 2 case ConstParams.VV11: t = 3 case ConstParams.VV12: t = 4 case ConstParams.VV13: t = 4 case ConstParams.VV14: t = 4 case ConstParams.VV15: t = 435 case ConstParams.VV16: t = 31 case ConstParams.VV17: t = 1 case ConstParams.VV18: t = 1 case ConstParams.VV19: t = 1 case ConstParams.VV20: t = 1 default: t = 5 } return t } private func stringSwitch(_ s: String) -> Int { switch (s) { case "ABCDEFG1": return 1 case "ABCDEFG2": return 2 case "ABCDEFG2": return 3 case "ABCDEFG3": return 4 case "ABCDEFG4": return 5 case "ABCDEFG5": return 6 case "ABCDEFG6": return 7 case "ABCDEFG7": return 8 case "ABCDEFG8": return 9 case "ABCDEFG9": return 10 case "ABCDEFG10": return 11 case "ABCDEFG11": return 12 case "ABCDEFG12": return 1 case "ABCDEFG13": return 2 case "ABCDEFG14": return 3 case "ABCDEFG15": return 4 case "ABCDEFG16": return 5 case "ABCDEFG17": return 6 case "ABCDEFG18": return 7 case "ABCDEFG19": return 8 case "ABCDEFG20": return 9 default: return -1 } } var denseIntData: [Int] var sparseIntData: [Int] func testSparseIntSwitch() { for i in sparseIntData { Blackhole.consume(sparseIntSwitch(i)) } } func testDenseIntSwitch() { for i in denseIntData { Blackhole.consume(denseIntSwitch(i)) } } func testConstSwitch() { for i in denseIntData { Blackhole.consume(constSwitch(i)) } } func testObjConstSwitch() { for i in denseIntData { Blackhole.consume(objConstSwitch(i)) } } func testVarSwitch() { for i in denseIntData { Blackhole.consume(varSwitch(i)) } } var data: [String] = [] func testStringsSwitch() { let n = data.count for s in data { Blackhole.consume(stringSwitch(s)) } } enum MyEnum: CaseIterable { case ITEM1, ITEM2, ITEM3, ITEM4, ITEM5, ITEM6, ITEM7, ITEM8, ITEM9, ITEM10, ITEM11, ITEM12, ITEM13, ITEM14, ITEM15, ITEM16, ITEM17, ITEM18, ITEM19, ITEM20, ITEM21, ITEM22, ITEM23, ITEM24, ITEM25, ITEM26, ITEM27, ITEM28, ITEM29, ITEM30, ITEM31, ITEM32, ITEM33, ITEM34, ITEM35, ITEM36, ITEM37, ITEM38, ITEM39, ITEM40, ITEM41, ITEM42, ITEM43, ITEM44, ITEM45, ITEM46, ITEM47, ITEM48, ITEM49, ITEM50, ITEM51, ITEM52, ITEM53, ITEM54, ITEM55, ITEM56, ITEM57, ITEM58, ITEM59, ITEM60, ITEM61, ITEM62, ITEM63, ITEM64, ITEM65, ITEM66, ITEM67, ITEM68, ITEM69, ITEM70, ITEM71, ITEM72, ITEM73, ITEM74, ITEM75, ITEM76, ITEM77, ITEM78, ITEM79, ITEM80, ITEM81, ITEM82, ITEM83, ITEM84, ITEM85, ITEM86, ITEM87, ITEM88, ITEM89, ITEM90, ITEM91, ITEM92, ITEM93, ITEM94, ITEM95, ITEM96, ITEM97, ITEM98, ITEM99, ITEM100 } private func enumSwitch(_ x: MyEnum) -> Int { switch (x) { case MyEnum.ITEM5: return 1 case MyEnum.ITEM10: return 2 case MyEnum.ITEM15: return 3 case MyEnum.ITEM20: return 4 case MyEnum.ITEM25: return 5 case MyEnum.ITEM30: return 6 case MyEnum.ITEM35: return 7 case MyEnum.ITEM40: return 8 case MyEnum.ITEM45: return 9 case MyEnum.ITEM50: return 10 case MyEnum.ITEM55: return 11 case MyEnum.ITEM60: return 12 case MyEnum.ITEM65: return 13 case MyEnum.ITEM70: return 14 case MyEnum.ITEM75: return 15 case MyEnum.ITEM80: return 16 case MyEnum.ITEM85: return 17 case MyEnum.ITEM90: return 18 case MyEnum.ITEM95: return 19 case MyEnum.ITEM100: return 20 default: return -1 } } private func denseEnumSwitch(x: MyEnum) -> Int { switch (x) { case MyEnum.ITEM1: return 1 case MyEnum.ITEM2: return 2 case MyEnum.ITEM3: return 3 case MyEnum.ITEM4: return 4 case MyEnum.ITEM5: return 5 case MyEnum.ITEM6: return 6 case MyEnum.ITEM7: return 7 case MyEnum.ITEM8: return 8 case MyEnum.ITEM9: return 9 case MyEnum.ITEM10: return 10 case MyEnum.ITEM11: return 11 case MyEnum.ITEM12: return 12 case MyEnum.ITEM13: return 13 case MyEnum.ITEM14: return 14 case MyEnum.ITEM15: return 15 case MyEnum.ITEM16: return 16 case MyEnum.ITEM17: return 17 case MyEnum.ITEM18: return 18 case MyEnum.ITEM19: return 19 case MyEnum.ITEM20: return 20 default: return -1 } } var enumData : [MyEnum] var denseEnumData : [MyEnum] func testEnumsSwitch() { let n = enumData.count - 1 let data = enumData for i in 0...n { Blackhole.consume(enumSwitch(data[i])) } } func testDenseEnumsSwitch() { let n = denseEnumData.count - 1 let data = denseEnumData for i in 0...n { Blackhole.consume(denseEnumSwitch(x: data[i])) } } class MySealedClass { class MySealedClass1: MySealedClass {} class MySealedClass2: MySealedClass {} class MySealedClass3: MySealedClass {} class MySealedClass4: MySealedClass {} class MySealedClass5: MySealedClass {} class MySealedClass6: MySealedClass {} class MySealedClass7: MySealedClass {} class MySealedClass8: MySealedClass {} class MySealedClass9: MySealedClass {} class MySealedClass10: MySealedClass {} } var sealedClassData: [MySealedClass] init() { data = [] for _ in 0.. Int { switch (x) { case is MySealedClass.MySealedClass1: return 1 case is MySealedClass.MySealedClass2: return 2 case is MySealedClass.MySealedClass3: return 3 case is MySealedClass.MySealedClass4: return 4 case is MySealedClass.MySealedClass5: return 5 case is MySealedClass.MySealedClass6: return 6 case is MySealedClass.MySealedClass7: return 7 case is MySealedClass.MySealedClass8: return 8 case is MySealedClass.MySealedClass9: return 9 case is MySealedClass.MySealedClass10: return 10 default: return -1 } } func testSealedWhenSwitch() { let n = sealedClassData.count - 1 for i in 0...n { Blackhole.consume(sealedWhenSwitch(sealedClassData[i])) } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/Utils.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class Blackhole { @inline(never) static var flag: Bool = false @inline(never) static func consume(_ value: T) { if (flag) { print(value) } } } struct Constants { static let BENCHMARK_SIZE = 10000 static let RUNS = 1_000_000 static var globalAddendum = 0 } ================================================ FILE: performance/KotlinVsSwift/ring/src/WithIndiciesBenchmark.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation class WithIndiciesBenchmark { private var _data: [Value]? = nil var data: [Value] { get { return _data! } } init() { var list: [Value] = [] for n in classValues(Constants.BENCHMARK_SIZE) { list.append(n) } _data = list } func withIndicies() { for (index, value) in data.lazy.enumerated() { if (filterLoad(value)) { Blackhole.consume(index) Blackhole.consume(value) } } } func withIndiciesManual() { var index = 0 for value in data { if (filterLoad(value)) { Blackhole.consume(index) Blackhole.consume(value) } index += 1 } } } ================================================ FILE: performance/KotlinVsSwift/ring/src/main.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation import benchmark var runner = BenchmarksRunner() let args = KotlinArray(size: Int32(CommandLine.arguments.count - 1), init: {index in CommandLine.arguments[Int(truncating: index) + 1] as NSString }) let companion = BenchmarkEntryWithInit.Companion() var swiftLauncher = SwiftLauncher() extension SwiftLauncher { static func abstractMethodBenchmark(_ instance: Any) -> AbstractMethodBenchmark { return instance as! AbstractMethodBenchmark } static func classArrayBenchmark(_ instance: Any) -> ClassArrayBenchmark { return instance as! ClassArrayBenchmark } static func classListBenchmark(_ instance: Any) -> ClassListBenchmark { return instance as! ClassListBenchmark } static func classBaselineBenchmark(_ instance: Any) -> ClassBaselineBenchmark { return instance as! ClassBaselineBenchmark } static func classStreamBenchmark(_ instance: Any) -> ClassStreamBenchmark { return instance as! ClassStreamBenchmark } static func companionObjectBenchmark(_ instance: Any) -> CompanionObjectBenchmark { return instance as! CompanionObjectBenchmark } static func defaultArgumentBenchmark(_ instance: Any) -> DefaultArgumentBenchmark { return instance as! DefaultArgumentBenchmark } static func elvisBenchmark(_ instance: Any) -> ElvisBenchmark { return instance as! ElvisBenchmark } static func eulerBenchmark(_ instance: Any) -> EulerBenchmark { return instance as! EulerBenchmark } static func fibonacciBenchmark(_ instance: Any) -> FibonacciBenchmark { return instance as! FibonacciBenchmark } static func forLoopsBenchmark(_ instance: Any) -> ForLoopsBenchmark { return instance as! ForLoopsBenchmark } static func inlineBenchmark(_ instance: Any) -> InlineBenchmark { return instance as! InlineBenchmark } static func intArrayBenchmark(_ instance: Any) -> IntArrayBenchmark { return instance as! IntArrayBenchmark } static func intBaselineBenchmark(_ instance: Any) -> IntBaselineBenchmark { return instance as! IntBaselineBenchmark } static func intStreamBenchmark(_ instance: Any) -> IntStreamBenchmark { return instance as! IntStreamBenchmark } static func lambdaBenchmark(_ instance: Any) -> LambdaBenchmark { return instance as! LambdaBenchmark } static func loopBenchmark(_ instance: Any) -> LoopBenchmark { return instance as! LoopBenchmark } static func matrixMapBenchmark(_ instance: Any) -> MatrixMapBenchmark { return instance as! MatrixMapBenchmark } static func parameterNotNullAssertionBenchmark(_ instance: Any) -> ParameterNotNullAssertionBenchmark { return instance as! ParameterNotNullAssertionBenchmark } static func primeListBenchmark(_ instance: Any) -> PrimeListBenchmark { return instance as! PrimeListBenchmark } static func stringBenchmark(_ instance: Any) -> StringBenchmark { return instance as! StringBenchmark } static func switchBenchmark(_ instance: Any) -> SwitchBenchmark { return instance as! SwitchBenchmark } static func withIndiciesBenchmark(_ instance: Any) -> WithIndiciesBenchmark { return instance as! WithIndiciesBenchmark } static func callsBenchmarks(_ instance: Any) -> CallsBenchmarks { return instance as! CallsBenchmarks } static func coordinatesSolverBenchmark(_ instance: Any) -> CoordinatesSolverBenchmark { return instance as! CoordinatesSolverBenchmark } static func graphSolverBenchmark(_ instance: Any) -> GraphSolverBenchmark { return instance as! GraphSolverBenchmark } static func castsBenchmark(_ instance: Any) -> CastsBenchmark { return instance as! CastsBenchmark } } swiftLauncher.add(name: "AbstractMethod.sortStrings", benchmark: companion.create(ctor: { return AbstractMethodBenchmark() }, lambda: { SwiftLauncher.abstractMethodBenchmark($0).sortStrings() })) swiftLauncher.add(name: "AbstractMethod.sortStringsWithComparator", benchmark: companion.create(ctor: { return AbstractMethodBenchmark() }, lambda: { SwiftLauncher.abstractMethodBenchmark($0).sortStringsWithComparator() })) swiftLauncher.add(name: "ClassArray.copy", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).copy() })) swiftLauncher.add(name: "ClassArray.copyManual", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).copyManual() })) swiftLauncher.add(name: "ClassArray.filterAndCount", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).filterAndCount() })) swiftLauncher.add(name: "ClassArray.filterAndMap", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).filterAndMap() })) swiftLauncher.add(name: "ClassArray.filterAndMapManual", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).filterAndMapManual() })) swiftLauncher.add(name: "ClassArray.filter", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).filter() })) swiftLauncher.add(name: "ClassArray.filterManual", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).filterManual() })) swiftLauncher.add(name: "ClassArray.countFilteredManual", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).countFilteredManual() })) swiftLauncher.add(name: "ClassArray.countFiltered", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).countFiltered() })) swiftLauncher.add(name: "ClassArray.countFilteredLocal", benchmark: companion.create(ctor: { return ClassArrayBenchmark() }, lambda: { SwiftLauncher.classArrayBenchmark($0).countFilteredLocal() })) swiftLauncher.add(name: "ClassBaseline.consume", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).consume() })) swiftLauncher.add(name: "ClassBaseline.consumeField", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).consumeField() })) swiftLauncher.add(name: "ClassBaseline.allocateList", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).allocateList() })) swiftLauncher.add(name: "ClassBaseline.allocateArray", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).allocateArray() })) swiftLauncher.add(name: "ClassBaseline.allocateListAndFill", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).allocateListAndFill() })) swiftLauncher.add(name: "ClassBaseline.allocateListAndWrite", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).allocateListAndWrite() })) swiftLauncher.add(name: "ClassBaseline.allocateArrayAndFill", benchmark: companion.create(ctor: { return ClassBaselineBenchmark() }, lambda: { SwiftLauncher.classBaselineBenchmark($0).allocateArrayAndFill() })) swiftLauncher.add(name: "ClassList.filterAndCountWithLambda", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).filterAndCountWithLambda() })) swiftLauncher.add(name: "ClassList.filterWithLambda", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).filterWithLambda() })) swiftLauncher.add(name: "ClassList.mapWithLambda", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).mapWithLambda() })) swiftLauncher.add(name: "ClassList.countWithLambda", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).countWithLambda() })) swiftLauncher.add(name: "ClassList.filterAndMapWithLambda", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).filterAndMapWithLambda() })) swiftLauncher.add(name: "ClassList.filterAndMapWithLambdaAsSequence", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).filterAndMapWithLambdaAsSequence() })) swiftLauncher.add(name: "ClassList.reduce", benchmark: companion.create(ctor: { return ClassListBenchmark() }, lambda: { SwiftLauncher.classListBenchmark($0).reduce() })) swiftLauncher.add(name: "ClassStream.copy", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).copy() })) swiftLauncher.add(name: "ClassStream.copyManual", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).copyManual() })) swiftLauncher.add(name: "ClassStream.filterAndCount", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).filterAndCount() })) swiftLauncher.add(name: "ClassStream.filterAndMap", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).filterAndMap() })) swiftLauncher.add(name: "ClassStream.filterAndMapManual", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).filterAndMapManual() })) swiftLauncher.add(name: "ClassStream.filter", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).filter() })) swiftLauncher.add(name: "ClassStream.filterManual", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).filterManual() })) swiftLauncher.add(name: "ClassStream.countFilteredManual", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).countFilteredManual() })) swiftLauncher.add(name: "ClassStream.reduce", benchmark: companion.create(ctor: { return ClassStreamBenchmark() }, lambda: { SwiftLauncher.classStreamBenchmark($0).reduce() })) swiftLauncher.add(name: "CompanionObject.invokeRegularFunction", benchmark: companion.create(ctor: { return CompanionObjectBenchmark() }, lambda: { SwiftLauncher.companionObjectBenchmark($0).invokeRegularFunction() })) swiftLauncher.add(name: "DefaultArgument.testOneOfTwo", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testOneOfTwo() })) swiftLauncher.add(name: "DefaultArgument.testTwoOfTwo", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testTwoOfTwo() })) swiftLauncher.add(name: "DefaultArgument.testOneOfFour", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testOneOfFour() })) swiftLauncher.add(name: "DefaultArgument.testFourOfFour", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testFourOfFour() })) swiftLauncher.add(name: "DefaultArgument.testOneOfEight", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testOneOfEight() })) swiftLauncher.add(name: "DefaultArgument.testEightOfEight", benchmark: companion.create(ctor: { return DefaultArgumentBenchmark() }, lambda: { SwiftLauncher.defaultArgumentBenchmark($0).testEightOfEight() })) swiftLauncher.add(name: "Elvis.testElvis", benchmark: companion.create(ctor: { return ElvisBenchmark() }, lambda: { SwiftLauncher.elvisBenchmark($0).testElvis() })) swiftLauncher.add(name: "Euler.problem1bySequence", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem1bySequence() })) swiftLauncher.add(name: "Euler.problem1", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem1() })) swiftLauncher.add(name: "Euler.problem2", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem2() })) swiftLauncher.add(name: "Euler.problem4", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem4() })) swiftLauncher.add(name: "Euler.problem8", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem8() })) swiftLauncher.add(name: "Euler.problem9", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem9() })) swiftLauncher.add(name: "Euler.problem14", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem14() })) swiftLauncher.add(name: "Euler.problem14full", benchmark: companion.create(ctor: { return EulerBenchmark() }, lambda: { SwiftLauncher.eulerBenchmark($0).problem14full() })) swiftLauncher.add(name: "Fibonacci.calcClassic", benchmark: companion.create(ctor: { return FibonacciBenchmark() }, lambda: { SwiftLauncher.fibonacciBenchmark($0).calcClassic() })) swiftLauncher.add(name: "Fibonacci.calc", benchmark: companion.create(ctor: { return FibonacciBenchmark() }, lambda: { SwiftLauncher.fibonacciBenchmark($0).calc() })) swiftLauncher.add(name: "Fibonacci.calcWithProgression", benchmark: companion.create(ctor: { return FibonacciBenchmark() }, lambda: { SwiftLauncher.fibonacciBenchmark($0).calcWithProgression() })) swiftLauncher.add(name: "Fibonacci.calcSquare", benchmark: companion.create(ctor: { return FibonacciBenchmark() }, lambda: { SwiftLauncher.fibonacciBenchmark($0).calcSquare() })) swiftLauncher.add(name: "ForLoops.arrayLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).arrayLoop() })) swiftLauncher.add(name: "ForLoops.floatArrayLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).floatArrayLoop() })) swiftLauncher.add(name: "ForLoops.charArrayLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).charArrayLoop() })) swiftLauncher.add(name: "ForLoops.stringLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).stringLoop() })) swiftLauncher.add(name: "ForLoops.arrayIndicesLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).arrayIndicesLoop() })) swiftLauncher.add(name: "ForLoops.floatArrayIndicesLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).floatArrayIndicesLoop() })) swiftLauncher.add(name: "ForLoops.charArrayIndicesLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).charArrayIndicesLoop() })) swiftLauncher.add(name: "ForLoops.stringIndicesLoop", benchmark: companion.create(ctor: { return ForLoopsBenchmark() }, lambda: { SwiftLauncher.forLoopsBenchmark($0).stringIndicesLoop() })) swiftLauncher.add(name: "Inline.calculate", benchmark: companion.create(ctor: { return InlineBenchmark() }, lambda: { SwiftLauncher.inlineBenchmark($0).calculate() })) swiftLauncher.add(name: "Inline.calculateInline", benchmark: companion.create(ctor: { return InlineBenchmark() }, lambda: { SwiftLauncher.inlineBenchmark($0).calculateInline() })) swiftLauncher.add(name: "Inline.calculateGeneric", benchmark: companion.create(ctor: { return InlineBenchmark() }, lambda: { SwiftLauncher.inlineBenchmark($0).calculateGeneric() })) swiftLauncher.add(name: "Inline.calculateGenericInline", benchmark: companion.create(ctor: { return InlineBenchmark() }, lambda: { SwiftLauncher.inlineBenchmark($0).calculateGenericInline() })) swiftLauncher.add(name: "IntArray.copy", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).copy() })) swiftLauncher.add(name: "IntArray.copyManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).copyManual() })) swiftLauncher.add(name: "IntArray.filterAndCount", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterAndCount() })) swiftLauncher.add(name: "IntArray.filterSomeAndCount", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterSomeAndCount() })) swiftLauncher.add(name: "IntArray.filterAndMap", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterAndMap() })) swiftLauncher.add(name: "IntArray.filterAndMapManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterAndMapManual() })) swiftLauncher.add(name: "IntArray.filter", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filter() })) swiftLauncher.add(name: "IntArray.filterSome", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterSome() })) swiftLauncher.add(name: "IntArray.filterPrime", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterPrime() })) swiftLauncher.add(name: "IntArray.filterManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterManual() })) swiftLauncher.add(name: "IntArray.filterSomeManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).filterSomeManual() })) swiftLauncher.add(name: "IntArray.countFilteredManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredManual() })) swiftLauncher.add(name: "IntArray.countFilteredSomeManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredSomeManual() })) swiftLauncher.add(name: "IntArray.countFilteredPrimeManual", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredPrimeManual() })) swiftLauncher.add(name: "IntArray.countFiltered", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFiltered() })) swiftLauncher.add(name: "IntArray.countFilteredSome", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredSome() })) swiftLauncher.add(name: "IntArray.countFilteredPrime", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredPrime() })) swiftLauncher.add(name: "IntArray.countFilteredLocal", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredLocal() })) swiftLauncher.add(name: "IntArray.countFilteredSomeLocal", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).countFilteredSomeLocal() })) swiftLauncher.add(name: "IntArray.reduce", benchmark: companion.create(ctor: { return IntArrayBenchmark() }, lambda: { SwiftLauncher.intArrayBenchmark($0).reduce() })) swiftLauncher.add(name: "IntBaseline.consume", benchmark: companion.create(ctor: { return IntBaselineBenchmark() }, lambda: { SwiftLauncher.intBaselineBenchmark($0).consume() })) swiftLauncher.add(name: "IntBaseline.allocateArray", benchmark: companion.create(ctor: { return IntBaselineBenchmark() }, lambda: { SwiftLauncher.intBaselineBenchmark($0).allocateArray() })) swiftLauncher.add(name: "IntBaseline.allocateArrayAndFill", benchmark: companion.create(ctor: { return IntBaselineBenchmark() }, lambda: { SwiftLauncher.intBaselineBenchmark($0).allocateArrayAndFill() })) swiftLauncher.add(name: "IntStream.copy", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).copy() })) swiftLauncher.add(name: "IntStream.copyManual", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).copyManual() })) swiftLauncher.add(name: "IntStream.filterAndCount", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).filterAndCount() })) swiftLauncher.add(name: "IntStream.filterAndMap", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).filterAndMap() })) swiftLauncher.add(name: "IntStream.filterAndMapManual", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).filterAndMapManual() })) swiftLauncher.add(name: "IntStream.filter", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).filter() })) swiftLauncher.add(name: "IntStream.filterManual", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).filterManual() })) swiftLauncher.add(name: "IntStream.countFilteredManual", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).countFilteredManual() })) swiftLauncher.add(name: "IntStream.countFiltered", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).countFiltered() })) swiftLauncher.add(name: "IntStream.countFilteredLocal", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).countFilteredLocal() })) swiftLauncher.add(name: "IntStream.reduce", benchmark: companion.create(ctor: { return IntStreamBenchmark() }, lambda: { SwiftLauncher.intStreamBenchmark($0).reduce() })) swiftLauncher.add(name: "Lambda.noncapturingLambda", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).noncapturingLambda() })) swiftLauncher.add(name: "Lambda.noncapturingLambdaNoInline", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).noncapturingLambdaNoInline() })) swiftLauncher.add(name: "Lambda.capturingLambda", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).capturingLambda() })) swiftLauncher.add(name: "Lambda.capturingLambdaNoInline", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).capturingLambdaNoInline() })) swiftLauncher.add(name: "Lambda.mutatingLambda", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).mutatingLambda() })) swiftLauncher.add(name: "Lambda.mutatingLambdaNoInline", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).mutatingLambdaNoInline() })) swiftLauncher.add(name: "Lambda.methodReference", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).methodReference() })) swiftLauncher.add(name: "Lambda.methodReferenceNoInline", benchmark: companion.create(ctor: { return LambdaBenchmark() }, lambda: { SwiftLauncher.lambdaBenchmark($0).methodReferenceNoInline() })) swiftLauncher.add(name: "Loop.arrayLoop", benchmark: companion.create(ctor: { return LoopBenchmark() }, lambda: { SwiftLauncher.loopBenchmark($0).arrayLoop() })) swiftLauncher.add(name: "Loop.arrayIndexLoop", benchmark: companion.create(ctor: { return LoopBenchmark() }, lambda: { SwiftLauncher.loopBenchmark($0).arrayIndexLoop() })) swiftLauncher.add(name: "Loop.rangeLoop", benchmark: companion.create(ctor: { return LoopBenchmark() }, lambda: { SwiftLauncher.loopBenchmark($0).rangeLoop() })) swiftLauncher.add(name: "Loop.arrayWhileLoop", benchmark: companion.create(ctor: { return LoopBenchmark() }, lambda: { SwiftLauncher.loopBenchmark($0).arrayWhileLoop() })) swiftLauncher.add(name: "Loop.arrayForeachLoop", benchmark: companion.create(ctor: { return LoopBenchmark() }, lambda: { SwiftLauncher.loopBenchmark($0).arrayForeachLoop() })) swiftLauncher.add(name: "MatrixMap.add", benchmark: companion.create(ctor: { return MatrixMapBenchmark() }, lambda: { SwiftLauncher.matrixMapBenchmark($0).add() })) swiftLauncher.add(name: "ParameterNotNull.invokeOneArgWithNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeOneArgWithNullCheck() })) swiftLauncher.add(name: "ParameterNotNull.invokeOneArgWithoutNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeOneArgWithoutNullCheck() })) swiftLauncher.add(name: "ParameterNotNull.invokeTwoArgsWithNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeTwoArgsWithNullCheck() })) swiftLauncher.add(name: "ParameterNotNull.invokeTwoArgsWithoutNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeTwoArgsWithoutNullCheck() })) swiftLauncher.add(name: "ParameterNotNull.invokeEightArgsWithNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeEightArgsWithNullCheck() })) swiftLauncher.add(name: "ParameterNotNull.invokeEightArgsWithoutNullCheck", benchmark: companion.create(ctor: { return ParameterNotNullAssertionBenchmark() }, lambda: { SwiftLauncher.parameterNotNullAssertionBenchmark($0).invokeEightArgsWithoutNullCheck() })) swiftLauncher.add(name: "PrimeList.calcDirect", benchmark: companion.create(ctor: { return PrimeListBenchmark() }, lambda: { SwiftLauncher.primeListBenchmark($0).calcDirect() })) swiftLauncher.add(name: "PrimeList.calcEratosthenes", benchmark: companion.create(ctor: { return PrimeListBenchmark() }, lambda: { SwiftLauncher.primeListBenchmark($0).calcEratosthenes() })) swiftLauncher.add(name: "String.stringConcat", benchmark: companion.create(ctor: { return StringBenchmark() }, lambda: { SwiftLauncher.stringBenchmark($0).stringConcat() })) swiftLauncher.add(name: "String.stringConcatNullable", benchmark: companion.create(ctor: { return StringBenchmark() }, lambda: { SwiftLauncher.stringBenchmark($0).stringConcatNullable() })) swiftLauncher.add(name: "String.stringBuilderConcat", benchmark: companion.create(ctor: { return StringBenchmark() }, lambda: { SwiftLauncher.stringBenchmark($0).stringBuilderConcat() })) swiftLauncher.add(name: "String.stringBuilderConcatNullable", benchmark: companion.create(ctor: { return StringBenchmark() }, lambda: { SwiftLauncher.stringBenchmark($0).stringBuilderConcatNullable() })) swiftLauncher.add(name: "String.summarizeSplittedCsv", benchmark: companion.create(ctor: { return StringBenchmark() }, lambda: { SwiftLauncher.stringBenchmark($0).summarizeSplittedCsv() })) swiftLauncher.add(name: "Switch.testSparseIntSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testSparseIntSwitch() })) swiftLauncher.add(name: "Switch.testDenseIntSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testDenseIntSwitch() })) swiftLauncher.add(name: "Switch.testConstSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testConstSwitch() })) swiftLauncher.add(name: "Switch.testObjConstSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testObjConstSwitch() })) swiftLauncher.add(name: "Switch.testVarSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testVarSwitch() })) swiftLauncher.add(name: "Switch.testStringsSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testStringsSwitch() })) swiftLauncher.add(name: "Switch.testEnumsSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testEnumsSwitch() })) swiftLauncher.add(name: "Switch.testDenseEnumsSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testDenseEnumsSwitch() })) swiftLauncher.add(name: "Switch.testSealedWhenSwitch", benchmark: companion.create(ctor: { return SwitchBenchmark() }, lambda: { SwiftLauncher.switchBenchmark($0).testSealedWhenSwitch() })) swiftLauncher.add(name: "WithIndicies.withIndicies", benchmark: companion.create(ctor: { return WithIndiciesBenchmark() }, lambda: { SwiftLauncher.withIndiciesBenchmark($0).withIndicies() })) swiftLauncher.add(name: "WithIndicies.withIndiciesManual", benchmark: companion.create(ctor: { return WithIndiciesBenchmark() }, lambda: { SwiftLauncher.withIndiciesBenchmark($0).withIndiciesManual() })) swiftLauncher.add(name: "OctoTest", benchmark: BenchmarkEntry( lambda: { octoTest() })) swiftLauncher.add(name: "Calls.finalMethod", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).finalMethodCall() })) swiftLauncher.add(name: "Calls.openMethodMonomorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).classOpenMethodCall_MonomorphicCallsite() })) swiftLauncher.add(name: "Calls.openMethodBimorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).classOpenMethodCall_BimorphicCallsite() })) swiftLauncher.add(name: "Calls.openMethodTrimorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).classOpenMethodCall_TrimorphicCallsite() })) swiftLauncher.add(name: "Calls.interfaceMethodMonomorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).interfaceMethodCall_MonomorphicCallsite() })) swiftLauncher.add(name: "Calls.interfaceMethodBimorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).interfaceMethodCall_BimorphicCallsite() })) swiftLauncher.add(name: "Calls.interfaceMethodTrimorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).interfaceMethodCall_TrimorphicCallsite() })) swiftLauncher.add(name: "Calls.interfaceMethodHexamorphic", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).interfaceMethodCall_HexamorphicCallsite() })) swiftLauncher.add(name: "Calls.returnBoxUnboxFolding", benchmark: companion.create(ctor: { return CallsBenchmarks() }, lambda: { SwiftLauncher.callsBenchmarks($0).returnBoxUnboxFolding() })) swiftLauncher.add(name: "CoordinatesSolver.solve", benchmark: companion.create(ctor: { return CoordinatesSolverBenchmark() }, lambda: { SwiftLauncher.coordinatesSolverBenchmark($0).solve() })) swiftLauncher.add(name: "GraphSolver.solve", benchmark: companion.create(ctor: { return GraphSolverBenchmark() }, lambda: { SwiftLauncher.graphSolverBenchmark($0).solve() })) swiftLauncher.add(name: "Casts.classCast", benchmark: companion.create(ctor: { return CastsBenchmark() }, lambda: { SwiftLauncher.castsBenchmark($0).classCast() })) swiftLauncher.add(name: "Casts.interfaceCast", benchmark: companion.create(ctor: { return CastsBenchmark() }, lambda: { SwiftLauncher.castsBenchmark($0).interfaceCast() })) runner.runBenchmarks(args: args, run: { (arguments: BenchmarkArguments) -> [BenchmarkResult] in if arguments is BaseBenchmarkArguments { let argumentsList: BaseBenchmarkArguments = arguments as! BaseBenchmarkArguments return swiftLauncher.launch(numWarmIterations: argumentsList.warmup, numberOfAttempts: argumentsList.repeat, prefix: argumentsList.prefix, filters: argumentsList.filter, filterRegexes: argumentsList.filterRegex, verbose: argumentsList.verbose) } return [BenchmarkResult]() }, parseArgs: { (args: KotlinArray, benchmarksListAction: (() -> KotlinUnit)) -> BenchmarkArguments? in return runner.parse(args: args, benchmarksListAction: swiftLauncher.benchmarksListAction) }, collect: { (benchmarks: [BenchmarkResult], arguments: BenchmarkArguments) -> Void in runner.collect(results: benchmarks, arguments: arguments) }, benchmarksListAction: swiftLauncher.benchmarksListAction) ================================================ FILE: performance/KotlinVsSwift/ring/src/zdf_win.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation let zdf_win: [String] = ["-де", "-ка", "-либо", "-нибудь", "-с", "-таки", "-то", "а", "а-конто", "а-ля", "аба", "абажур", "абажурный", "абаз", "абазин", "абазинец", "абазинка", "абазинский", "абак", "абака", "аббат", "аббатиса", "аббатский", "аббатство", "аббревиатура", "аббревиатурный", "аббревиация", "абдикация", "абдомен", "абдоминальный", "абдуктор", "абдукторный", "абдукция", "абелит", "аберрационный", "аберрация", "абзац", "абзацный", "абиетин", "абиетиновый", "абиссальный", "абиссинец", "абиссинский", "абитуриент", "абитуриентка", "абитуриентский", "аблактировать", "аблактировка", "аблятив", "абляут", "абляция", "аболиционизм", "аболиционист", "аболиционистский", "аболиция", "абонемент", "абонементный", "абонент", "абонентка", "абонентный", "абонентский", "абонирование", "абонировать", "абонироваться", "абордаж", "абордажный", "абордировать", "абориген", "аборигенный", "аборт", "абортарий", "абортивный", "абортировать", "абразив", "абразивный", "абразионный", "абразия", "абракадабра", "абреже", "абрек", "абрикос", "абрикосный", "абрикосовка", "абрикосовый", "абрикотин", "абрис", "абрисный", "абсент", "абсентеизм", "абсентеист", "абсолют", "абсолютивный", "абсолютизирование", "абсолютизировать", "абсолютизм", "абсолютист", "абсолютистский", "абсолютность", "абсолютный", "абсолюция", "абсорбент", "абсорбер", "абсорбировать", "абсорбционный", "абсорбция", "абстинент", "абстрагирование", "абстрагировать", "абстрагироваться", "абстракт", "абстрактность", "абстрактный", "абстракционизм", "абстракционист", "абстракционистский", "абстракция", "абсурд", "абсурдность", "абсурдный", "абсцесс", "абсцисса", "абулия", "абхаз", "абхазец", "абхазка", "абхазский", "абцуг", "абштрих", "абъюрация", "абы", "авалист", "аваль", "авангард", "авангардизм", "авангардист", "авангардистский", "авангардный", "аванзал", "аванзальный", "аванкамера", "аванложа", "аванпорт", "аванпост", "аванпостный", "аванс", "авансирование", "авансировать", "авансовый", "авансом", "авансцена", "авантаж", "авантажный", "авантюра", "авантюризм", "авантюрин", "авантюриновый", "авантюрист", "авантюристический", "авантюристичный", "авантюристка", "авантюристский", "авантюрность", "авантюрный", "авар", "аварец", "аварийность", "аварийный", "аварийщик", "авария", "аварка", "аварский", "авгиев", "авгит", "авгур", "август", "августейший", "августинец", "августовский", "авдотка", "авеню", "аверс", "авестийский", "авиабаза", "авиабензин", "авиагоризонт", "авиадвигатель", "авиадесант", "авиадесантный", "авиазавод", "авиаконструктор", "авиалиния", "авиаматка", "авиамоделизм", "авиамоделист", "авиамодель", "авиамодельный", "авиамотор", "авиамоторный", "авианосец", "авиапочта", "авиаприбор", "авиапромышленность", "авиапромышленный", "авиаразведка", "авиастроение", "авиастроитель", "авиастроительный", "авиастроительство", "авиасъёмка", "авиатехник", "авиатор", "авиаторский", "авиатранспорт", "авиатранспортный", "авиатрасса", "авиационный", "авиация", "авиачасть", "авиашкола", "авиетка", "авизировать", "авизный", "авизо", "авитаминоз", "авитаминозный", "авифауна", "авокадо", "авось", "авоська", "аврал", "авралить", "авральный", "авран", "аврора", "австралиец", "австралийка", "австралийский", "австралопитек", "австриец", "австрийка", "австрийский", "австрияк", "австриячка", "австро-венгерский", "автаркический", "автаркия", "авто", "автобаза", "автобиографический", "автобиографичность", "автобиографичный", "автобиография", "автоблокировка", "автоблокировочный", "автобус", "автобусник", "автобусный", "автовакцина", "автовесы", "автовокзал", "автогамия", "автоген", "автогенез", "автогенератор", "автогенный", "автогенщик", "автогипноз", "автогонки", "автогравюра", "автограф", "автографический", "автография", "автогужевой", "автодидакт", "автодоение", "автодорожник", "автодорожный", "автодрезина", "автодром", "автожир", "автозавод", "автозаводец", "автозаводский", "автозаводской", "автозаправочный", "автозаправщик", "автоинспектор", "автоинспекция", "автокар", "автокара", "автокатализ", "автокефалия", "автокефальный", "автоклав", "автоклуб", "автоколонна", "автокомбинат", "автокран", "автократ", "автократический", "автократия", "автокружок", "автол", "автолавка", "автолиз", "автолитография", "автолюбитель", "автолюбительство", "автомагистраль", "автомат", "автоматизация", "автоматизирование", "автоматизировать", "автоматизироваться", "автоматизм", "автоматика", "автоматический", "автоматичность", "автоматичный", "автоматный", "автоматчик", "автоматчица", "автомашина", "автомашинист", "автомеханик", "автомобилестроение", "автомобилестроитель", "автомобилестроительный", "автомобилизация", "автомобилизм", "автомобилист", "автомобилистка", "автомобиль", "автомобильный", "автомобильчик", "автоморфизм", "автомотоклуб", "автомоторный", "автомотошкола", "автомотриса", "автономист", "автономистский", "автономический", "автономия", "автономность", "автономный", "автопарк", "автоперевозка", "автопилот", "автопластика", "автоплуг", "автопогрузчик", "автоподъёмник", "автопоезд", "автопоилка", "автопокрышка", "автопортрет", "автопробег", "автопромышленность", "автор", "авторалли", "авторегулятор", "авторемонтник", "авторемонтный", "автореферат", "авторефрижератор", "авторизация", "авторизованный", "авторизовать", "авторитарность", "авторитарный", "авторитет", "авторитетность", "авторитетный", "авторота", "авторские", "авторский", "авторство", "авторулевой", "авторучка", "автосани", "автосборка", "автосварщик", "автоспорт", "автостанция", "автостоп", "автострада", "автостроение", "автостроитель", "автосцепка", "автотележка", "автотип", "автотипический", "автотипия", "автотипный", "автотомия", "автотормоз", "автотормозной", "автотракторный", "автотранспорт", "автотранспортный", "автотрансформатор", "автотрасса", "автотуризм", "автотурист", "автоукладчик", "автофургон", "автохозяйство", "автохром", "автохромный", "автохтон", "автохтонный", "автоцистерна", "авточасть", "автошкола", "автоштурман", "авуары", "ага", "ага-хан", "агава", "агалит", "агальматолит", "агама", "агами", "агамия", "агамогония", "агар-агар", "агарный", "агаровый", "агарянин", "агат", "агатный", "агатовый", "агглютинативность", "агглютинативный", "агглютинация", "агглютинин", "агглютинирующий", "аггравация", "агент", "агентский", "агентство", "агентура", "агентурный", "агиографический", "агиография", "агиология", "агитатор", "агитаторский", "агитаторша", "агитационный", "агитация", "агитбригада", "агитировать", "агитка", "агиткампания", "агитмассовый", "агитпоезд", "агитпроп", "агитпункт", "аглицкий", "агломерат", "агломератчик", "агломерационный", "агломерация", "агломерировать", "агломерироваться", "агнат", "агнец", "агнозия", "агностик", "агностицизм", "агностический", "агонизировать", "агонический", "агония", "агорафобия", "аграмант", "аграмантовый", "аграрий", "аграрник", "аграрный", "аграф", "аграфия", "агрегат", "агрегатный", "агреман", "агрессивность", "агрессивный", "агрессия", "агрессор", "агрикультура", "агрикультурный", "агробаза", "агробиолог", "агробиологический", "агробиология", "агроботаника", "агрозоотехника", "агромелиорация" ] ================================================ FILE: performance/build.gradle ================================================ import org.jetbrains.kotlin.RegressionsReporter import org.jetbrains.kotlin.RegressionsSummaryReporter import org.jetbrains.kotlin.BuildRegister import org.jetbrains.kotlin.MPPTools buildscript { ext.rootBuildDirectory = file('..') apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle" apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter'} maven { url 'https://cache-redirector.jetbrains.com/maven-central' } mavenCentral() maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } jcenter() maven { url "https://kotlin.bintray.com/kotlinx" } maven { url "https://dl.bintray.com/kotlin/kotlin-dev" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-build-tools:$konanVersion" } } def rootBuildDirectory = projectDir.parentFile task konanRun { subprojects.each { dependsOn "${it.path}:konanRun" } } task jvmRun { subprojects.each { dependsOn "${it.path}:jvmRun" } } task clean { subprojects.each { dependsOn "${it.path}:clean" } doLast { delete "${buildDir.absolutePath}" } } defaultTasks 'konanRun' private static String getAnalyzerTargetName() { // Copy-pasted from tools/benchmarksAnalyzer/build.gradle. String target = System.getProperty("os.name") if (target == 'Linux') return 'linux' if (target.startsWith('Windows')) return 'windows' if (target.startsWith('Mac')) return 'macos' return 'unknown' } private String findAnalyzerBinary() { String result = "${projectDir}/../${analyzerToolDirectory}/${getAnalyzerTargetName()}/" + "${analyzerTool}ReleaseExecutable/${analyzerTool}${MPPTools.getNativeProgramExtension()}" if (file(result).exists()) return result else return null } // Produce and send slack report. task slackReport(type: RegressionsReporter) { def analyzerBinary = MPPTools.findFile("${analyzerTool}${MPPTools.getNativeProgramExtension()}", "${rootBuildDirectory}/${analyzerToolDirectory}") def teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") if (teamcityConfig && analyzerBinary != null) { // Create folder for report (root Kotlin project settings make create report in separate folder). def reportDirectory = new File(outputReport).parentFile mkdir reportDirectory def targetsResults = new File(new File("${rootBuildDirectory}"), "targetsResults").toString() mkdir targetsResults currentBenchmarksReportFile = "${buildDir.absolutePath}/${nativeJson}" analyzer = analyzerBinary htmlReport = outputReport defaultBranch = project.findProperty('kotlin.native.default.branch') ?: "master" def target = System.getProperty("os.name") summaryFile = "${targetsResults}/${target}.txt" bundleBuild = project.findProperty('kotlin.bundleBuild') == null ? false : true } } task slackSummary(type: RegressionsSummaryReporter) { targetsResultFiles = ['Linux': "${rootBuildDirectory}/targetsResults/Linux.txt".toString(), 'MacOSX': "${rootBuildDirectory}/targetsResults/Mac OS X.txt".toString(), 'Windows': "${rootBuildDirectory}/targetsResults/Windows 10.txt".toString()] } private String getUploadedFile(String fileName) { def teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") if (teamcityConfig) { def buildProperties = new Properties() buildProperties.load(new FileInputStream(teamcityConfig)) def buildNumber = buildProperties.getProperty("build.number") def target = System.getProperty("os.name").replaceAll("\\s", "") return "${target}/${buildNumber}/${fileName}" } return null } private def uploadBenchmarkResultToArtifactory(String fileName) { def teamcityConfig = System.getenv("TEAMCITY_BUILD_PROPERTIES_FILE") if (teamcityConfig) { def uploadedFile = getUploadedFile(fileName) def buildProperties = new Properties() buildProperties.load(new FileInputStream(teamcityConfig)) def password = buildProperties.getProperty("artifactory.apikey") MPPTools.uploadFileToArtifactory("${artifactoryUrl}", "${artifactoryRepo}", uploadedFile, "${buildDir.absolutePath}/${fileName}", password) } } // Register external benchmarks reports (e.g. results of libraries benchmarks) task registerExternalBenchmarks { doLast { def reports = externalReports.split(';') def jsonReports = [] reports.each { def reportFile = new File(buildDir, it) if (!reportFile.exists()) return def lines = reportFile.readLines() if (lines.size < 4) { project.logger.warn("Couldn't use report to register benchmarks. Wrong format.") return } def name = lines[0] def options = lines[1] if (!options.startsWith("OPTIONS")) { project.logger.warn("Couldn't use report to register benchmarks. Wrong format in options description.") return } def optionsList = options.replace("OPTIONS ", "").replaceAll("\\[|\\]", "").split(",\\s*").toList() def status = lines[2] def compileTime = null def codeSize = null lines.drop(3).each { if (it.startsWith("COMPILE_TIME")) { compileTime = it } if (it.startsWith("CODE_SIZE")) { codeSize = it } } // Create benchmarks report. def properties = [ "cpu": System.getProperty("os.arch"), "os": System.getProperty("os.name"), "jdkVersion": System.getProperty("java.version"), "jdkVendor": System.getProperty("java.vendor"), "kotlinVersion": kotlinVersion, "type": "native", "compilerVersion": konanVersion, "flags": optionsList, "benchmarks": "[]"] if (compileTime != null) { def compileBenchmark = MPPTools.toCompileBenchmark(compileTime, status, name) properties += ["compileTime": [compileBenchmark]] } if (codeSize != null) { properties += ["codeSize": MPPTools.toCodeSizeBenchmark(codeSize, status, name)] } def output = MPPTools.createJsonReport(properties) def jsonFile = new File(buildDir, it.replace(".txt", ".json")) jsonFile.write(output) jsonReports.add(jsonFile) } def merged = MPPTools.mergeReports(jsonReports) if (!merged.isEmpty()) { mkdir buildDir.absolutePath new File(buildDir, externalBenchmarksReport).write(merged) uploadBenchmarkResultToArtifactory(externalBenchmarksReport) } } } task registerBuild(type: BuildRegister) { onlyBranch = project.findProperty('kotlin.register.branch') def uploadedFile = getUploadedFile(nativeJson) if (uploadedFile != null) { println("Use file from Artifacrory $uploadedFile") fileWithResult = uploadedFile } // Get bundle size. bundleSize = null if (project.findProperty('kotlin.bundleBuild') != null) { def dist = findProperty('kotlin.native.home') ?: 'dist' dist = (new File(dist)).isAbsolute() ? dist : "${project.getProjectDir()}/$dist" bundleSize = (new File(dist)).directorySize() } } task registerExternalBuild(type: BuildRegister) { onlyBranch = project.findProperty('kotlin.register.branch') def uploadedFile = getUploadedFile(externalBenchmarksReport) if (uploadedFile != null) { println("Use file from Artifacrory $uploadedFile") fileWithResult = uploadedFile } else { fileWithResult = externalBenchmarksReport } } registerExternalBenchmarks.finalizedBy registerExternalBuild def mergeReports(String fileName) { def reports = [] subprojects.each { def reportFile = new File("${it.buildDir.absolutePath}/${fileName}") if (reportFile.exists()) { reports.add(reportFile) } } def output = MPPTools.mergeReports(reports) mkdir buildDir.absolutePath new File("${buildDir.absolutePath}/${fileName}").write(output) } task mergeNativeReports { doLast { mergeReports(nativeJson) uploadBenchmarkResultToArtifactory(nativeJson) } } task mergeJvmReports { doLast { mergeReports(jvmJson) uploadBenchmarkResultToArtifactory(jvmJson) } } subprojects.each { it.afterEvaluate { it.jvmJsonReport.finalizedBy mergeJvmReports it.konanJsonReport.finalizedBy mergeNativeReports } } task teamCityStat(type:Exec) { def analyzer = findAnalyzerBinary() if (analyzer != null) { commandLine "${analyzer}", "-r", "teamcity", "${buildDir.absolutePath}/${nativeJson}" } else { println("No analyzer $analyzerTool found in subdirectories of ${rootBuildDirectory}/${analyzerToolDirectory}") } } task cinterop { dependsOn 'clean' dependsOn 'cinterop:konanRun' } task framework { dependsOn 'clean' dependsOn 'framework:konanRun' } task helloworld { dependsOn 'clean' dependsOn 'helloworld:konanRun' } task objcinterop { dependsOn 'clean' dependsOn 'objcinterop:konanRun' } task ring { dependsOn 'clean' dependsOn 'ring:konanRun' } task numerical { dependsOn 'clean' dependsOn 'numerical:konanRun' } task startup { dependsOn 'clean' dependsOn 'startup:konanRun' } task swiftinterop { dependsOn 'clean' dependsOn 'swiftinterop:konanRun' } task videoplayer { dependsOn 'clean' dependsOn 'videoplayer:konanRun' } task KotlinVsSwift { dependsOn 'clean' dependsOn 'KotlinVsSwift:konanRun' } ================================================ FILE: performance/cinterop/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType plugins { id("benchmarking") } val defaultBuildType = NativeBuildType.RELEASE benchmark { applicationName = "Cinterop" commonSrcDirs = listOf("../../tools/benchmarks/shared/src/main/kotlin/report", "src/main/kotlin", "../shared/src/main/kotlin") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common") mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw") posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType } val native = kotlin.targets.getByName("native") as KotlinNativeTarget native.compilations["main"].cinterops { create("macros") create("struct") create("types") } ================================================ FILE: performance/cinterop/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/cinterop/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.jetbrains.structsProducedByMacrosBenchmarks.* import org.jetbrains.benchmarksLauncher.* import org.jetbrains.structsBenchmarks.* import org.jetbrains.typesBenchmarks.* import kotlinx.cli.* class CinteropLauncher : Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "macros" to BenchmarkEntry(::macrosBenchmark), "struct" to BenchmarkEntry(::structBenchmark), "union" to BenchmarkEntry(::unionBenchmark), "enum" to BenchmarkEntry(::enumBenchmark), "stringToC" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringToCBenchmark() }), "stringToKotlin" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringToKotlinBenchmark() }), "intMatrix" to BenchmarkEntryWithInit.create(::IntMatrixBenchmark, { intMatrixBenchmark() }), "int" to BenchmarkEntryWithInit.create(::IntBenchmark, { intBenchmark() }), "boxedInt" to BenchmarkEntryWithInit.create(::BoxedIntBenchmark, { boxedIntBenchmark() }) ) ) } fun main(args: Array) { val launcher = CinteropLauncher() BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> if (arguments is BaseBenchmarkArguments) { launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, arguments.filter, arguments.filterRegex, arguments.verbose) } else emptyList() }, benchmarksListAction = launcher::benchmarksListAction) } ================================================ FILE: performance/cinterop/src/main/kotlin/org/jetbrains/cinteropBenchmarks/structsBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsBenchmarks expect fun structBenchmark() expect fun unionBenchmark() expect fun enumBenchmark() ================================================ FILE: performance/cinterop/src/main/kotlin/org/jetbrains/cinteropBenchmarks/structsProducedByMacrosBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsProducedByMacrosBenchmarks expect fun macrosBenchmark() ================================================ FILE: performance/cinterop/src/main/kotlin/org/jetbrains/cinteropBenchmarks/typesBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.typesBenchmarks expect class StringBenchmark() { fun stringToCBenchmark() fun stringToKotlinBenchmark() } expect class IntBenchmark() { fun intBenchmark() } expect class BoxedIntBenchmark() { fun boxedIntBenchmark() } expect class IntMatrixBenchmark() { fun intMatrixBenchmark() } ================================================ FILE: performance/cinterop/src/main/kotlin-jvm/org/jetbrains/cinteropBenchmarks/structsBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsBenchmarks actual fun structBenchmark() { error("Benchmark structBenchmark is unsupported on JVM!") } actual fun unionBenchmark() { error("Benchmark unionBenchmark is unsupported on JVM!") } actual fun enumBenchmark() { error("Benchmark enumBenchmark is unsupported on JVM!") } ================================================ FILE: performance/cinterop/src/main/kotlin-jvm/org/jetbrains/cinteropBenchmarks/structsProducedByMacrosBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsProducedByMacrosBenchmarks actual fun macrosBenchmark() { error("Benchmark macrosBenchmark is unsupported on JVM!") } ================================================ FILE: performance/cinterop/src/main/kotlin-jvm/org/jetbrains/cinteropBenchmarks/typesBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.typesBenchmarks actual class StringBenchmark actual constructor() { actual fun stringToCBenchmark() { error("Benchmark stringToCBenchmark is unsupported on JVM!") } actual fun stringToKotlinBenchmark() { error("Benchmark stringToKotlinBenchmark is unsupported on JVM!") } } actual class IntBenchmark actual constructor() { actual fun intBenchmark() { error("Benchmark intBenchmark is unsupported on JVM!") } } actual class BoxedIntBenchmark actual constructor() { actual fun boxedIntBenchmark() { error("Benchmark boxedIntBenchmark is unsupported on JVM!") } } actual class IntMatrixBenchmark actual constructor() { actual fun intMatrixBenchmark() { error("Benchmark intMatrixBenchmark is unsupported on JVM!") } } ================================================ FILE: performance/cinterop/src/main/kotlin-native/org/jetbrains/cinteropBenchmarks/structsBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsBenchmarks import kotlinx.cinterop.* import platform.posix.* import kotlin.math.sqrt const val benchmarkSize = 10000 actual fun structBenchmark() { memScoped { val containsFunction = staticCFunction?, CPointer?, Int> { first, second -> if (first == null || second == null) { 0 } else if (first.pointed.string.toKString().contains(second.pointed.string.toKString())) { 1 } else { 0 } } val elementsList = mutableListOf() // Fill list. for (i in 1..benchmarkSize) { val element = alloc() element.floatValue = i + sqrt(i.toDouble()).toFloat() element.integer = i.toLong() sprintf(element.string, "%d", i) element.contains = containsFunction elementsList.add(element) } val summary = elementsList.map { multiplyElementS(it.readValue(), (0..10).random()) } .reduce { acc, it -> sumElementSPtr(acc.ptr, it.ptr)!!.pointed.readValue() } val intValue = summary.useContents { integer } elementsList.last().contains!!(elementsList.last().ptr, elementsList.first().ptr) } } actual fun unionBenchmark() { memScoped { val elementsList = mutableListOf() // Fill list. for (i in 1..benchmarkSize) { val element = alloc() element.integer = i.toLong() elementsList.add(element) } elementsList.forEach { it.floatValue = it.integer + sqrt(it.integer.toDouble()).toFloat() } val summary = elementsList.map { multiplyElementU(it.readValue(), (0..10).random()) } .reduce { acc, it -> sumElementUPtr(acc.ptr, it.ptr)!!.pointed.readValue() } summary.useContents { integer } } } actual fun enumBenchmark() { val days = arrayOf("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") val enumValues = mutableListOf() for (i in 1..benchmarkSize) { enumValues.add(getWeekDay(days[(0..6).random()])) } enumValues.forEach { isWeekEnd(it) } } ================================================ FILE: performance/cinterop/src/main/kotlin-native/org/jetbrains/cinteropBenchmarks/structsProducedByMacrosBenchmark.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.structsProducedByMacrosBenchmarks import kotlinx.cinterop.* import kotlin.math.abs const val benachmarkSize = 1000 actual fun macrosBenchmark() { memScoped { val ints = new_list_int() for (i in 1..benachmarkSize) { list_push_front_int(ints, i) } val floats = new_list_float() // Copy integer list to float one. ints?.pointed?.apply { var current = _first while(current != null) { list_push_front_float(floats, current?.pointed?._data?.toFloat() ?: error("Null elements in list are not expected!") ) current = current?.pointed?._next } } // Reverse list. var previous: CPointer? = null var current = floats?.pointed?._first while (current != null) { val next = current?.pointed?._next current?.pointed?._next = previous previous = current current = next } floats?.pointed?._first = previous free_list_int(ints) try { if (abs(list_front_float(floats) - benachmarkSize.toFloat()) > 0.00001) { error("Wrong first element!") } } finally { free_list_float(floats) } } } ================================================ FILE: performance/cinterop/src/main/kotlin-native/org/jetbrains/cinteropBenchmarks/typesBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.typesBenchmarks import kotlin.random.Random import kotlinx.cinterop.* const val benchmarkSize = 1000 actual class StringBenchmark actual constructor() { val charPool: List = ('a'..'z') + ('A'..'Z') + ('0'..'9') val randomString = generateRandomString() val randomChar = charPool[Random.nextInt(0, charPool.size)] val strings = mutableListOf() init { // Generate random strings. for (i in 1..benchmarkSize) { strings.add(generateRandomString()) } } fun generateRandomString(): String { return (1..benchmarkSize) .map { i -> Random.nextInt(0, charPool.size) } .map(charPool::get) .joinToString("") } actual fun stringToCBenchmark() { // Generate random strings. for (i in 1..benchmarkSize) { charFrequency(randomString, randomChar.toByte()) } } actual fun stringToKotlinBenchmark() { memScoped { val result = StringBuilder() for (i in 1..benchmarkSize) { val pointer = findSuitableString(strings.toCStringArray(this), benchmarkSize, "a") val str = pointer?.toKString() result.append(str) freeSuitableString(pointer) } } } } actual class IntMatrixBenchmark actual constructor(){ val matrixSize = 1000 val first = generateMatrix(matrixSize) val second = generateMatrix(matrixSize) fun generateMatrix(size: Int): Array { val matrix = Array(size, { IntArray(size) }) for (i in (0 until size)) { for (j in (0 until size)) { matrix[i][j] = (1..20).random() } } return matrix } actual fun intMatrixBenchmark() { memScoped { val result = allocArray>(matrixSize) for (i in (0 until matrixSize)) { result[i] = allocArray(matrixSize) } val resultMatrix = multiplyMatrix(matrixSize, matrixSize, first.map { it.toCValues().ptr }.toCValues().ptr, matrixSize, matrixSize, second.map { it.toCValues().ptr }.toCValues().ptr) val resultOutput = buildString { for (i in (0 until matrixSize)) { for (j in (0 until matrixSize)) { append(resultMatrix!![i]!![j]) append(" ") } append("\n") } } } } } actual class IntBenchmark actual constructor() { val size = 20 val array = Array(size, { (0 until size).random() }) actual fun intBenchmark() { for (i in 1..benchmarkSize) { average(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9], array[10], array[11], array[12], array[13], array[14], array[15], array[16], array[17], array[18], array[19]) } } } actual class BoxedIntBenchmark actual constructor() { val size = 20 val array = Array(size, { null }) init { for (i in (0 until size)) { val element: Int? = (0 until size).random() array[i] = element } } actual fun boxedIntBenchmark() { for (i in 1..benchmarkSize) { average(array[0]!!, array[1]!!, array[2]!!, array[3]!!, array[4]!!, array[5]!!, array[6]!!, array[7]!!, array[8]!!, array[9]!!, array[10]!!, array[11]!!, array[12]!!, array[13]!!, array[14]!!, array[15]!!, array[16]!!, array[17]!!, array[18]!!, array[19]!!) } } } ================================================ FILE: performance/cinterop/src/nativeInterop/cinterop/macros.def ================================================ package = org.jetbrains.structsProducedByMacrosBenchmarks --- #include #include #define define_list(type) \ \ struct _list_##type; \ \ typedef struct \ { \ int (*is_empty)(const struct _list_##type*); \ size_t (*size)(const struct _list_##type*); \ const type (*front)(const struct _list_##type*); \ void (*push_front)(struct _list_##type*, type); \ } _list_functions_##type; \ \ typedef struct _list_elem_##type \ { \ type _data; \ struct _list_elem_##type* _next; \ } list_elem_##type; \ \ typedef struct _list_##type \ { \ size_t _size; \ list_elem_##type* _first; \ list_elem_##type* _last; \ _list_functions_##type* _functions; \ } List_##type; \ \ List_##type* new_list_##type(); \ int list_is_empty_##type(const List_##type* list); \ size_t list_size_##type(const List_##type* list); \ const type list_front_##type(const List_##type* list); \ void list_push_front_##type(List_##type* list, type elem); \ \ int list_is_empty_##type(const List_##type* list) \ { \ return list->_size == 0; \ } \ \ size_t list_size_##type(const List_##type* list) \ { \ return list->_size; \ } \ \ const type list_front_##type(const List_##type* list) \ { \ return list->_first->_data; \ } \ \ void list_push_front_##type(List_##type* list, type elem) \ { \ struct _list_elem_##type* element = (struct _list_elem_##type*) malloc(sizeof(struct _list_elem_##type)); \ element->_data = elem; \ element->_next = list->_first; \ list->_first = element; \ list->_size++; \ } \ \ _list_functions_##type _list_funcs_##type = { \ &list_is_empty_##type, \ &list_size_##type, \ &list_front_##type, \ &list_push_front_##type, \ }; \ \ List_##type* new_list_##type() \ { \ List_##type* res = (List_##type*) malloc(sizeof(List_##type)); \ res->_size = 0; \ res->_first = NULL; \ res->_functions = &_list_funcs_##type; \ return res; \ } \ \ void free_list_##type(List_##type* list) \ { \ struct _list_elem_##type* current = list->_first; \ while (current != NULL) \ { \ struct _list_elem_##type* next = current->_next; \ free(current); \ current = next; \ } \ free(list); \ } define_list(int) define_list(float) ================================================ FILE: performance/cinterop/src/nativeInterop/cinterop/struct.def ================================================ package = org.jetbrains.structsBenchmarks strictEnums = WeekDay --- #include #include #include enum WeekDay {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; int isWeekEnd(enum WeekDay day) { if (day == Saturday || day == Sunday) return 1; return 0; } enum WeekDay getWeekDay(const char* date) { if (strstr(date, "Sunday") != NULL) { return Sunday; } else if (strstr(date, "Monday") != NULL) { return Monday; } else if (strstr(date, "Tuesday") != NULL) { return Tuesday; } else if (strstr(date, "Wednesday") != NULL) { return Wednesday; } else if (strstr(date, "Thursday") != NULL) { return Thursday; } else if (strstr(date, "Friday") != NULL) { return Friday; } else if (strstr(date, "Saturday") != NULL) { return Saturday; } abort(); } struct ElementS { long long integer; float floatValue; char string[32]; int (*contains)(const struct ElementS*, const struct ElementS*); }; int elementContains(const struct ElementS* self, const struct ElementS* other) { if (self == NULL || other == NULL) { return 0; } if (strstr(self->string, other->string) != NULL) { return 1; } return 0; } union ElementU { long long integer; float floatValue; char string[32]; }; union ElementU multiplyElementU(union ElementU element, int coefficient) { union ElementU newElement; newElement.integer = coefficient * element.integer; return newElement; } struct ElementS multiplyElementS(struct ElementS element, int coefficient) { struct ElementS newElement; newElement.integer = coefficient * element.integer; newElement.floatValue = coefficient * element.floatValue; int i = 0; while (element.string[i] != '\0') { newElement.string[i] = coefficient * element.string[i]; i++; } return newElement; } union ElementU* sumElementUPtr(const union ElementU* first, const union ElementU* second) { if (first == NULL || second == NULL) { return NULL; } union ElementU* newElement = (union ElementU*)malloc(sizeof(union ElementU)); newElement->integer = first->integer + second->integer; return newElement; } struct ElementS* sumElementSPtr(const struct ElementS* first, const struct ElementS* second) { if (first == NULL || second == NULL) { return NULL; } struct ElementS* newElement = (struct ElementS*)malloc(sizeof(struct ElementS)); newElement->integer = first->integer + second->integer; newElement->floatValue = first->floatValue + second->floatValue; sprintf(newElement->string, "%d", newElement->integer); return newElement; } ================================================ FILE: performance/cinterop/src/nativeInterop/cinterop/types.def ================================================ package = org.jetbrains.typesBenchmarks --- #include #include #include #include int charFrequency(const char* string, char charToFind) { int frequency = 0; for(int i = 0; string[i] != '\0'; ++i) { if(charToFind == string[i]) ++frequency; } return frequency; } const char* findSuitableString(const char* stringsArray[], int arraySize, const char* stringToFind) { for(int i = 0; i < arraySize; ++i) { if (strstr(stringsArray[i], stringToFind) != NULL) { char* result = (char*) malloc((strlen(stringsArray[i])+1)*sizeof(char)); strcpy(result, stringsArray[i]); return result; } } return NULL; } void freeSuitableString(char* unusedString) { free(unusedString); } unsigned long int sum(int array[], int arraySize) { unsigned long int result = 0; for(int i = 0; i < arraySize; ++i) { result += array[i]; } return result; } double average(int count, ...) { va_list list; int j = 0; va_start(list, count); double sum = 0; for(j=0; j project.ext.buildSteps.keySet().each { dependsOn "$it$number" } } } task configureBuild { doLast { mkdir "${buildDir.absolutePath}" } } (1..project.ext.repeatNumber).each { number -> project.ext.buildSteps.each { taskName, command -> tasks.create(name: "$taskName$number", type: Exec) { commandLine command ignoreExitValue true doLast { exitCodes[name] = execResult.exitValue } } } } task clean { doLast { delete "${buildDir.absolutePath}" } } task konanJsonReport { doLast { def nativeCompileTime = MPPTools.getCompileBenchmarkTime(project.ext.applicationName, project.ext.buildSteps.keySet(), project.ext.repeatNumber, exitCodes) def nativeExecutable = "${buildDir.absolutePath}/program${MPPTools.getNativeProgramExtension()}" def properties = getCommonProperties() + ['type': 'native', 'compilerVersion': "${konanVersion}".toString(), 'benchmarks': "[]", 'compileTime': nativeCompileTime, 'codeSize': MPPTools.getCodeSizeBenchmark(project.ext.applicationName, nativeExecutable) ] def output = MPPTools.createJsonReport(properties) new File("${buildDir.absolutePath}/${nativeJson}").write(output) } } task jvmRun { println("JVM run isn't supported") } task jvmJsonReport { doLast { println("JVM run isn't supported") } } jvmRun.finalizedBy jvmJsonReport konanRun.finalizedBy konanJsonReport private def getCommonProperties() { return ['cpu': System.getProperty("os.arch"), 'os': System.getProperty("os.name"), // OperatingSystem.current().getName() 'jdkVersion': System.getProperty("java.version"), // org.gradle.internal.jvm.Jvm.current().javaVersion 'jdkVendor': System.getProperty("java.vendor"), 'kotlinVersion': "${kotlinVersion}".toString()] } ================================================ FILE: performance/gradle.properties ================================================ kotlin.native.home=../dist org.jetbrains.kotlin.native.jvmArgs=-Xmx6G org.gradle.jvmargs=-Xmx2048m jvmWarmup = 1000 nativeWarmup = 10 attempts = 30 jvmBenchResults = jvmBenchResults.json nativeBenchResults = nativeBenchResults.json nativeTextReport = nativeReport.txt jvmTextReport = jvmReport.txt nativeJson = nativeReport.json jvmJson = jvmReport.json analyzerTool = benchmarksAnalyzer analyzerToolDirectory = tools/benchmarksAnalyzer/build/bin outputReport = ../report/report.html artifactoryUrl = https://repo.labs.intellij.net artifactoryRepo = kotlin-native-benchmarks externalReports = coroutinesReport.txt externalBenchmarksReport = externalReport.json # Avoid building platform libraries by the MPP plugin. kotlin.native.distribution.type=prebuilt ================================================ FILE: performance/helloworld/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.getNativeProgramExtension import org.jetbrains.kotlin.getCompileOnlyBenchmarksOpts plugins { id("compile-benchmarking") } val dist = file(findProperty("kotlin.native.home") ?: "dist") val toolSuffix = if (System.getProperty("os.name").startsWith("Windows")) ".bat" else "" val binarySuffix = getNativeProgramExtension() val defaultCompilerOpts = listOf("-g") val buildOpts = getCompileOnlyBenchmarksOpts(project, defaultCompilerOpts) compileBenchmark { applicationName = "HelloWorld" repeatNumber = 10 compilerOpts = buildOpts buildSteps { step("runKonanc") { command("$dist/bin/konanc$toolSuffix", "$projectDir/src/main/kotlin/main.kt", "-o", "$buildDir/program$binarySuffix", *(buildOpts.toTypedArray())) } } } ================================================ FILE: performance/helloworld/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/helloworld/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ fun main() { println("Hello, World!") } ================================================ FILE: performance/numerical/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.benchmark.BenchmarkingPlugin import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.konan.target.* plugins { id("benchmarking") } val defaultBuildType = NativeBuildType.RELEASE benchmark { applicationName = "Numerical" commonSrcDirs = listOf("src/main/kotlin", "../../tools/benchmarks/shared/src/main/kotlin/report", "../shared/src/main/kotlin") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common") mingwSrcDirs = listOf("../shared/src/main/kotlin-native/mingw") posixSrcDirs = listOf("../shared/src/main/kotlin-native/posix") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType } val native = kotlin.targets.getByName("native") as KotlinNativeTarget native.apply { compilations["main"].cinterops { create("cinterop") { headers("$projectDir/src/nativeInterop/cinterop/pi.h") extraOpts("-Xcompile-source", "$projectDir/src/nativeInterop/cinterop/pi.c") extraOpts("-Xsource-compiler-option", "-O3") } } } ================================================ FILE: performance/numerical/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/numerical/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the licenses/LICENSE.txt file. */ import org.jetbrains.benchmarksLauncher.* import kotlinx.cli.* expect class NumericalLauncher() : Launcher { } fun main(args: Array) { val launcher = NumericalLauncher() BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> if (arguments is BaseBenchmarkArguments) { launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, arguments.filter, arguments.filterRegex, arguments.verbose) } else emptyList() }, benchmarksListAction = launcher::benchmarksListAction) } ================================================ FILE: performance/numerical/src/main/kotlin/pi.kt ================================================ /* * Computation of the n'th decimal digit of \pi with very little memory. * Written by Fabrice Bellard on January 8, 1997. * * We use a slightly modified version of the method described by Simon * Plouffe in "On the Computation of the n'th decimal digit of various * transcendental numbers" (November 1996). We have modified the algorithm * to get a running time of O(n^2) instead of O(n^3log(n)^3). */ import kotlin.math.ln import kotlin.math.sqrt private fun mul_mod(a: Int, b: Int, m: Int) = ((a.toLong() * b.toLong()) % m).toInt() /* return the inverse of x mod y */ private fun inv_mod(x: Int, y: Int): Int { var u = x var v = y var c = 1 var a = 0 do { val q = v / u var t = c c = a - q * c a = t t = u u = v - q * u v = t } while (u != 0) a = a % y if (a < 0) a = y + a return a } /* return (a^b) mod m */ private fun pow_mod(a: Int, b: Int, m: Int): Int { var b = b var r = 1 var aa = a while (true) { if (b and 1 != 0) r = mul_mod(r, aa, m) b = b shr 1 if (b == 0) break aa = mul_mod(aa, aa, m) } return r } /* return true if n is prime */ private fun is_prime(n: Int): Boolean { if (n % 2 == 0) return false val r = sqrt(n.toDouble()).toInt() var i = 3 while (i <= r) { if (n % i == 0) return false i += 2 } return true } /* return the prime number immediatly after n */ private fun next_prime(n: Int): Int { var n = n do { n++ } while (!is_prime(n)) return n } fun pi_nth_digit(n: Int): Int { val N = ((n + 20) * ln(10.0) / ln(2.0)).toInt() var sum = 0.0 var a = 3 var t: Int while (a <= 2 * N) { val vmax = (ln((2 * N).toDouble()) / ln(a.toDouble())).toInt() var av = 1 var i = 0 while (i < vmax) { av = av * a i++ } var s = 0 var num = 1 var den = 1 var v = 0 var kq = 1 var kq2 = 1 var k = 1 while (k <= N) { t = k if (kq >= a) { do { t = t / a v-- } while (t % a == 0) kq = 0 } kq++ num = mul_mod(num, t, av) t = 2 * k - 1 if (kq2 >= a) { if (kq2 == a) { do { t = t / a v++ } while (t % a == 0) } kq2 -= a } den = mul_mod(den, t, av) kq2 += 2 if (v > 0) { t = inv_mod(den, av) t = mul_mod(t, num, av) t = mul_mod(t, k, av) i = v while (i < vmax) { t = mul_mod(t, a, av) i++ } s += t if (s >= av) s -= av } k++ } t = pow_mod(10, n - 1, av) s = mul_mod(s, t, av) sum = (sum + s.toDouble() / av.toDouble()) % 1.0 a = next_prime(a) } return (sum * 1e9).toInt() } ================================================ FILE: performance/numerical/src/main/kotlin-jvm/launcher.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the licenses/LICENSE.txt file. */ import org.jetbrains.benchmarksLauncher.* actual class NumericalLauncher : Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "BellardPi" to BenchmarkEntry(::jvmBellardPi) ) ) } fun jvmBellardPi() { for (n in 1 .. 1000 step 9) { val result = pi_nth_digit(n) Blackhole.consume(result) } } ================================================ FILE: performance/numerical/src/main/kotlin-native/launcher.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the licenses/LICENSE.txt file. */ import org.jetbrains.benchmarksLauncher.* actual class NumericalLauncher : Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "BellardPi" to BenchmarkEntry(::konanBellardPi), "BellardPiCinterop" to BenchmarkEntry(::clangBellardPi) ) ) } fun konanBellardPi() { for (n in 1 .. 1000 step 9) { val result = pi_nth_digit(n) Blackhole.consume(result) } } fun clangBellardPi() { for (n in 1 .. 1000 step 9) { val result = cinterop.pi_nth_digit(n) Blackhole.consume(result) } } ================================================ FILE: performance/numerical/src/nativeInterop/cinterop/cinterop.def ================================================ package = cinterop ================================================ FILE: performance/numerical/src/nativeInterop/cinterop/pi.c ================================================ /* * Computation of the n'th decimal digit of \pi with very little memory. * Written by Fabrice Bellard on January 8, 1997. * * We use a slightly modified version of the method described by Simon * Plouffe in "On the Computation of the n'th decimal digit of various * transcendental numbers" (November 1996). We have modified the algorithm * to get a running time of O(n^2) instead of O(n^3log(n)^3). * * This program uses mostly integer arithmetic. It may be slow on some * hardwares where integer multiplications and divisons must be done * by software. We have supposed that 'int' has a size of 32 bits. If * your compiler supports 'long long' integers of 64 bits, you may use * the integer version of 'mul_mod' (see HAS_LONG_LONG). */ #include #include "pi.h" /* uncomment the following line to use 'long long' integers */ #define HAS_LONG_LONG #ifdef HAS_LONG_LONG #define mul_mod(a,b,m) (( (long long) (a) * (long long) (b) ) % (m)) #else #define mul_mod(a,b,m) fmod( (double) a * (double) b, m) #endif /* return the inverse of x mod y */ static int inv_mod(int x, int y) { int q, u, v, a, c, t; u = x; v = y; c = 1; a = 0; do { q = v / u; t = c; c = a - q * c; a = t; t = u; u = v - q * u; v = t; } while (u != 0); a = a % y; if (a < 0) a = y + a; return a; } /* return (a^b) mod m */ static int pow_mod(int a, int b, int m) { int r, aa; r = 1; aa = a; while (1) { if (b & 1) r = mul_mod(r, aa, m); b = b >> 1; if (b == 0) break; aa = mul_mod(aa, aa, m); } return r; } /* return true if n is prime */ static int is_prime(int n) { int r, i; if ((n % 2) == 0) return 0; r = (int) (sqrt(n)); for (i = 3; i <= r; i += 2) if ((n % i) == 0) return 0; return 1; } /* return the prime number immediatly after n */ static int next_prime(int n) { do { n++; } while (!is_prime(n)); return n; } int pi_nth_digit(int n) { int av, a, vmax, N, num, den, k, kq, kq2, t, v, s, i; double sum; N = (int) ((n + 20) * log(10) / log(2)); sum = 0; for (a = 3; a <= (2 * N); a = next_prime(a)) { vmax = (int) (log(2 * N) / log(a)); av = 1; for (i = 0; i < vmax; i++) av = av * a; s = 0; num = 1; den = 1; v = 0; kq = 1; kq2 = 1; for (k = 1; k <= N; k++) { t = k; if (kq >= a) { do { t = t / a; v--; } while ((t % a) == 0); kq = 0; } kq++; num = mul_mod(num, t, av); t = (2 * k - 1); if (kq2 >= a) { if (kq2 == a) { do { t = t / a; v++; } while ((t % a) == 0); } kq2 -= a; } den = mul_mod(den, t, av); kq2 += 2; if (v > 0) { t = inv_mod(den, av); t = mul_mod(t, num, av); t = mul_mod(t, k, av); for (i = v; i < vmax; i++) t = mul_mod(t, a, av); s += t; if (s >= av) s -= av; } } t = pow_mod(10, n - 1, av); s = mul_mod(s, t, av); sum = fmod(sum + (double) s / (double) av, 1.0); } return (int) (sum * 1e9); } ================================================ FILE: performance/numerical/src/nativeInterop/cinterop/pi.h ================================================ /* * Computation of the n'th decimal digit of \pi with very little memory. * Written by Fabrice Bellard on January 8, 1997. * * We use a slightly modified version of the method described by Simon * Plouffe in "On the Computation of the n'th decimal digit of various * transcendental numbers" (November 1996). We have modified the algorithm * to get a running time of O(n^2) instead of O(n^3log(n)^3). */ #ifndef _BELLARD_PI_H #define _BELLARD_PI_H #ifdef __cplusplus extern "C" { #endif int pi_nth_digit(int n); #ifdef __cplusplus } #endif #endif /*_BELLARD_PI_H*/ ================================================ FILE: performance/objcinterop/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.benchmark.BenchmarkingPlugin import org.jetbrains.kotlin.ExecClang import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.konan.target.HostManager plugins { id("benchmarking") } val defaultBuildType = NativeBuildType.RELEASE benchmark { applicationName = "ObjCInterop" commonSrcDirs = listOf("../../tools/benchmarks/shared/src/main/kotlin/report", "src/main/kotlin", "../shared/src/main/kotlin") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common") mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw") posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType } val native = kotlin.targets.getByName("native") as KotlinNativeTarget native.apply { compilations["main"].cinterops { create("classes") { headers("$projectDir/src/nativeInterop/cinterop/complexNumbers.h") extraOpts("-Xcompile-source", "$projectDir/src/nativeInterop/cinterop/complexNumbers.m") extraOpts("-Xsource-compiler-option", "-lobjc", "-Xsource-compiler-option", "-fobjc-arc") } } } ================================================ FILE: performance/objcinterop/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/objcinterop/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.benchmarksLauncher.* import org.jetbrains.complexNumbers.* import kotlinx.cli.* class ObjCInteropLauncher: Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "generateNumbersSequence" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { generateNumbersSequence() }), "sumComplex" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { sumComplex() }), "subComplex" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { subComplex() }), "classInheritance" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { classInheritance() }), "categoryMethods" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { categoryMethods() }), "stringToObjC" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { stringToObjC() }), "stringFromObjC" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { stringFromObjC() }), "fft" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { fft() }), "invertFft" to BenchmarkEntryWithInit.create(::ComplexNumbersBenchmark, { invertFft() }) ) ) } fun main(args: Array) { val launcher = ObjCInteropLauncher() BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> if (arguments is BaseBenchmarkArguments) { launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, arguments.filter, arguments.filterRegex, arguments.verbose) } else emptyList() }, benchmarksListAction = launcher::benchmarksListAction) } ================================================ FILE: performance/objcinterop/src/main/kotlin/org/jetbrains/objCinteropBenchmarks/complexNumbers.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.complexNumbers const val benchmarkSize = 10000 expect class ComplexNumber expect class ComplexNumbersBenchmark() { fun generateNumbersSequence(): List fun sumComplex() fun subComplex() fun classInheritance() fun categoryMethods() fun stringToObjC() fun stringFromObjC() fun fft() fun invertFft() } ================================================ FILE: performance/objcinterop/src/main/kotlin-jvm/org/jetbrains/objCInteropBenchmarks/complexNumbers.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.complexNumbers actual class ComplexNumber() {} actual class ComplexNumbersBenchmark actual constructor() { actual fun generateNumbersSequence(): List { error("Benchmark generateNumbersSequence is unsupported on JVM!") } actual fun sumComplex() { error("Benchmark sumComplex is unsupported on JVM!") } actual fun subComplex() { error("Benchmark subComplex is unsupported on JVM!") } actual fun classInheritance() { error("Benchmark classInheritance is unsupported on JVM!") } actual fun categoryMethods() { error("Benchmark categoryMethods is unsupported on JVM!") } actual fun stringToObjC() { error("Benchmark stringToObjC is unsupported on JVM!") } actual fun stringFromObjC() { error("Benchmark stringToObjC is unsupported on JVM!") } actual fun fft() { error("Benchmark fft is unsupported on JVM!") } actual fun invertFft() { error("Benchmark invertFft is unsupported on JVM!") } } ================================================ FILE: performance/objcinterop/src/main/kotlin-native/org/jetbrains/objCinteropBenchmarks/complexNumbers.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.complexNumbers import kotlinx.cinterop.* import platform.posix.* import kotlin.math.sqrt import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin import kotlin.random.Random import platform.Foundation.* import platform.darwin.* actual typealias ComplexNumber = Complex actual class ComplexNumbersBenchmark actual constructor() { val complexNumbersSequence = generateNumbersSequence() fun randomNumber() = Random.nextDouble(0.0, benchmarkSize.toDouble()) actual fun generateNumbersSequence(): List { val result = mutableListOf() for (i in 1..benchmarkSize) { result.add(Complex(randomNumber(), randomNumber())) } return result } actual fun sumComplex() { complexNumbersSequence.map { it.add(it) }.reduce { acc, it -> acc.add(it) } } actual fun subComplex() { complexNumbersSequence.map { it.sub(it) }.reduce { acc, it -> acc.sub(it) } } actual fun classInheritance() { class InvertedNumber(val value: Double) : CustomNumberProtocol, NSObject() { override fun add(other: CustomNumberProtocol) : CustomNumberProtocol = if (other is InvertedNumber) InvertedNumber(-value + sqrt(other.value)) else error("Expected object of InvertedNumber class") override fun sub(other: CustomNumberProtocol) : CustomNumberProtocol = if (other is InvertedNumber) InvertedNumber(-value - sqrt(other.value)) else error("Expected object of InvertedNumber class") } val result = InvertedNumber(0.0) for (i in 1..benchmarkSize) { result.add(InvertedNumber(randomNumber())) result.sub(InvertedNumber(randomNumber())) } } actual fun categoryMethods() { complexNumbersSequence.map { it.mul(it) }.reduce { acc, it -> acc.mul(it) } complexNumbersSequence.map { it.div(it) }.reduce { acc, it -> acc.mul(it) } } actual fun stringToObjC() { complexNumbersSequence.forEach { it.setFormat("%.1lf|%.1lf") } } actual fun stringFromObjC() { complexNumbersSequence.forEach { it.description()?.split(" ") } } private fun revert(number: Int, lg: Int): Int { var result = 0 for (i in 0 until lg) { if (number and (1 shl i) != 0) { result = result or 1 shl (lg - i - 1) } } return result } inline private fun fftRoutine(invert:Boolean = false): Array { var lg = 0 while ((1 shl lg) < complexNumbersSequence.size) { lg++ } val sequence = complexNumbersSequence.toTypedArray() sequence.forEachIndexed { index, number -> if (index < revert(index, lg) && revert(index, lg) < complexNumbersSequence.size) { sequence[index] = sequence[revert(index, lg)].also { sequence[revert(index, lg)] = sequence[index] } } } var length = 2 while (length < complexNumbersSequence.size) { val angle = 2 * PI / length * if (invert) -1 else 1 val base = Complex(cos(angle), sin(angle)) for (i in 0 until complexNumbersSequence.size / 2 step length) { var value = Complex(1.0, 1.0) for (j in 0 until length/2) { val first = sequence[i + j] val second = sequence[i + j + length/2].mul(value) sequence[i + j] = first.add(second) as Complex sequence[i + j + length/2] = first.sub(second) as Complex value = value.mul(base) } } length = length shl 1 } return sequence } actual fun fft() { fftRoutine() } actual fun invertFft() { val sequence = fftRoutine(true) sequence.forEachIndexed { index, number -> sequence[index] = number.div(Complex(sequence.size.toDouble(), 0.0)) } } } ================================================ FILE: performance/objcinterop/src/nativeInterop/cinterop/classes.def ================================================ package = org.jetbrains.complexNumbers language = Objective-C ================================================ FILE: performance/objcinterop/src/nativeInterop/cinterop/complexNumbers.h ================================================ #import @protocol CustomNumber @required - (id _Nonnull)add: (id _Nonnull)other; - (id _Nonnull)sub: (id _Nonnull)other; @end @interface Complex : NSObject @property (nonatomic, readonly) double re; @property (nonatomic, readonly) double im; @property (nonatomic, readwrite) NSString *format; - (id)initWithRe: (double)re andIm: (double)im; + (Complex *)complexWithRe: (double)re im: (double)im; @end @interface Complex (CategorizedComplex) - (Complex * _Nonnull)mul: (Complex * _Nonnull)other; - (Complex * _Nonnull)div: (Complex * _Nonnull)other; @end ================================================ FILE: performance/objcinterop/src/nativeInterop/cinterop/complexNumbers.m ================================================ #import #import "complexNumbers.h" @implementation Complex { double re; double im; NSString *format; } - (id)init { return [self initWithRe: 0.0 andIm: 0.0]; } - (id)initWithRe: (double)_re andIm: (double)_im { if (self = [super init]) { re = _re; im = _im; format = @"re: %.1lf im: %.1lf"; } return self; } + (Complex *)complexWithRe: (double)re im: (double)im { return [[Complex alloc] initWithRe: re andIm: im]; } - (id _Nonnull)add: (id _Nonnull)other { if ([self isKindOfClass:[Complex class]]) { Complex * otherComplex = (Complex *)other; return [[Complex alloc] initWithRe: re + otherComplex->re andIm: im + otherComplex->im]; } return NULL; } - (id _Nonnull)sub: (id _Nonnull)other { if ([self isKindOfClass:[Complex class]]) { Complex * otherComplex = (Complex *)other; return [[Complex alloc] initWithRe: re - otherComplex->re andIm: im - otherComplex->im]; } return NULL; } - (NSString *)description { return [NSString stringWithFormat: format, re, im]; } @end @implementation Complex (CategorizedComplex) - (Complex * _Nonnull)mul: (Complex * _Nonnull)other { return [Complex complexWithRe: re * other.re - im * other.im im: re * other.im + im * other.re]; } - (Complex * _Nonnull)div: (Complex * _Nonnull)other { double retRe; double retIm; double denominator; denominator = other.re * other.re + other.im * other.im; if (!denominator) return nil; retRe = (re * other.re + im * other.im) / denominator; retIm = (im * other.re - re * other.im) / denominator; return [Complex complexWithRe: retRe im: retIm]; } @end ================================================ FILE: performance/ring/build.gradle.kts ================================================ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ plugins { id("benchmarking") } val defaultBuildType = NativeBuildType.RELEASE benchmark { applicationName = "Ring" commonSrcDirs = listOf("../../tools/benchmarks/shared/src/main/kotlin/report", "src/main/kotlin", "../shared/src/main/kotlin") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common") mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw") posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType } ================================================ FILE: performance/ring/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/ring/src/main/kotlin/cleanup.kt ================================================ package org.jetbrains.ring expect fun cleanup() ================================================ FILE: performance/ring/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.jetbrains.ring.* import octoTest import org.jetbrains.benchmarksLauncher.* import kotlinx.cli.* class RingLauncher : Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "AbstractMethod.sortStrings" to BenchmarkEntryWithInit.create(::AbstractMethodBenchmark, { sortStrings() }), "AbstractMethod.sortStringsWithComparator" to BenchmarkEntryWithInit.create(::AbstractMethodBenchmark, { sortStringsWithComparator() }), "AllocationBenchmark.allocateObjects" to BenchmarkEntryWithInit.create(::AllocationBenchmark, { allocateObjects() }), "ClassArray.copy" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { copy() }), "ClassArray.copyManual" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { copyManual() }), "ClassArray.filterAndCount" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { filterAndCount() }), "ClassArray.filterAndMap" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { filterAndMap() }), "ClassArray.filterAndMapManual" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { filterAndMapManual() }), "ClassArray.filter" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { filter() }), "ClassArray.filterManual" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { filterManual() }), "ClassArray.countFilteredManual" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { countFilteredManual() }), "ClassArray.countFiltered" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { countFiltered() }), "ClassArray.countFilteredLocal" to BenchmarkEntryWithInit.create(::ClassArrayBenchmark, { countFilteredLocal() }), "ClassBaseline.consume" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { consume() }), "ClassBaseline.consumeField" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { consumeField() }), "ClassBaseline.allocateList" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { allocateList() }), "ClassBaseline.allocateArray" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { allocateArray() }), "ClassBaseline.allocateListAndFill" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { allocateListAndFill() }), "ClassBaseline.allocateListAndWrite" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { allocateListAndWrite() }), "ClassBaseline.allocateArrayAndFill" to BenchmarkEntryWithInit.create(::ClassBaselineBenchmark, { allocateArrayAndFill() }), "ClassList.copy" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { copy() }), "ClassList.copyManual" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { copyManual() }), "ClassList.filterAndCount" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndCount() }), "ClassList.filterAndCountWithLambda" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndCountWithLambda() }), "ClassList.filterWithLambda" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterWithLambda() }), "ClassList.mapWithLambda" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { mapWithLambda() }), "ClassList.countWithLambda" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { countWithLambda() }), "ClassList.filterAndMapWithLambda" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndMapWithLambda() }), "ClassList.filterAndMapWithLambdaAsSequence" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndMapWithLambdaAsSequence() }), "ClassList.filterAndMap" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndMap() }), "ClassList.filterAndMapManual" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterAndMapManual() }), "ClassList.filter" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filter() }), "ClassList.filterManual" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { filterManual() }), "ClassList.countFilteredManual" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { countFilteredManual() }), "ClassList.countFiltered" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { countFiltered() }), "ClassList.reduce" to BenchmarkEntryWithInit.create(::ClassListBenchmark, { reduce() }), "ClassStream.copy" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { copy() }), "ClassStream.copyManual" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { copyManual() }), "ClassStream.filterAndCount" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { filterAndCount() }), "ClassStream.filterAndMap" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { filterAndMap() }), "ClassStream.filterAndMapManual" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { filterAndMapManual() }), "ClassStream.filter" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { filter() }), "ClassStream.filterManual" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { filterManual() }), "ClassStream.countFilteredManual" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { countFilteredManual() }), "ClassStream.countFiltered" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { countFiltered() }), "ClassStream.reduce" to BenchmarkEntryWithInit.create(::ClassStreamBenchmark, { reduce() }), "CompanionObject.invokeRegularFunction" to BenchmarkEntryWithInit.create(::CompanionObjectBenchmark, { invokeRegularFunction() }), "DefaultArgument.testOneOfTwo" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testOneOfTwo() }), "DefaultArgument.testTwoOfTwo" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testTwoOfTwo() }), "DefaultArgument.testOneOfFour" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testOneOfFour() }), "DefaultArgument.testFourOfFour" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testFourOfFour() }), "DefaultArgument.testOneOfEight" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testOneOfEight() }), "DefaultArgument.testEightOfEight" to BenchmarkEntryWithInit.create(::DefaultArgumentBenchmark, { testEightOfEight() }), "Elvis.testElvis" to BenchmarkEntryWithInit.create(::ElvisBenchmark, { testElvis() }), "Elvis.testCompositeElvis" to BenchmarkEntryWithInit.create(::ElvisBenchmark, { testCompositeElvis() }), "Euler.problem1bySequence" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem1bySequence() }), "Euler.problem1" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem1() }), "Euler.problem2" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem2() }), "Euler.problem4" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem4() }), "Euler.problem8" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem8() }), "Euler.problem9" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem9() }), "Euler.problem14" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem14() }), "Euler.problem14full" to BenchmarkEntryWithInit.create(::EulerBenchmark, { problem14full() }), "Fibonacci.calcClassic" to BenchmarkEntryWithInit.create(::FibonacciBenchmark, { calcClassic() }), "Fibonacci.calc" to BenchmarkEntryWithInit.create(::FibonacciBenchmark, { calc() }), "Fibonacci.calcWithProgression" to BenchmarkEntryWithInit.create(::FibonacciBenchmark, { calcWithProgression() }), "Fibonacci.calcSquare" to BenchmarkEntryWithInit.create(::FibonacciBenchmark, { calcSquare() }), "ForLoops.arrayLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { arrayLoop() }), "ForLoops.intArrayLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { intArrayLoop() }), "ForLoops.floatArrayLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { floatArrayLoop() }), "ForLoops.charArrayLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { charArrayLoop() }), "ForLoops.stringLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { stringLoop() }), "ForLoops.arrayIndicesLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { arrayIndicesLoop() }), "ForLoops.intArrayIndicesLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { intArrayIndicesLoop() }), "ForLoops.floatArrayIndicesLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { floatArrayIndicesLoop() }), "ForLoops.charArrayIndicesLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { charArrayIndicesLoop() }), "ForLoops.stringIndicesLoop" to BenchmarkEntryWithInit.create(::ForLoopsBenchmark, { stringIndicesLoop() }), "Inline.calculate" to BenchmarkEntryWithInit.create(::InlineBenchmark, { calculate() }), "Inline.calculateInline" to BenchmarkEntryWithInit.create(::InlineBenchmark, { calculateInline() }), "Inline.calculateGeneric" to BenchmarkEntryWithInit.create(::InlineBenchmark, { calculateGeneric() }), "Inline.calculateGenericInline" to BenchmarkEntryWithInit.create(::InlineBenchmark, { calculateGenericInline() }), "IntArray.copy" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { copy() }), "IntArray.copyManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { copyManual() }), "IntArray.filterAndCount" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterAndCount() }), "IntArray.filterSomeAndCount" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterSomeAndCount() }), "IntArray.filterAndMap" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterAndMap() }), "IntArray.filterAndMapManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterAndMapManual() }), "IntArray.filter" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filter() }), "IntArray.filterSome" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterSome() }), "IntArray.filterPrime" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterPrime() }), "IntArray.filterManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterManual() }), "IntArray.filterSomeManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { filterSomeManual() }), "IntArray.countFilteredManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredManual() }), "IntArray.countFilteredSomeManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredSomeManual() }), "IntArray.countFilteredPrimeManual" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredPrimeManual() }), "IntArray.countFiltered" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFiltered() }), "IntArray.countFilteredSome" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredSome() }), "IntArray.countFilteredPrime" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredPrime() }), "IntArray.countFilteredLocal" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredLocal() }), "IntArray.countFilteredSomeLocal" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { countFilteredSomeLocal() }), "IntArray.reduce" to BenchmarkEntryWithInit.create(::IntArrayBenchmark, { reduce() }), "IntBaseline.consume" to BenchmarkEntryWithInit.create(::IntBaselineBenchmark, { consume() }), "IntBaseline.allocateList" to BenchmarkEntryWithInit.create(::IntBaselineBenchmark, { allocateList() }), "IntBaseline.allocateArray" to BenchmarkEntryWithInit.create(::IntBaselineBenchmark, { allocateArray() }), "IntBaseline.allocateListAndFill" to BenchmarkEntryWithInit.create(::IntBaselineBenchmark, { allocateListAndFill() }), "IntBaseline.allocateArrayAndFill" to BenchmarkEntryWithInit.create(::IntBaselineBenchmark, { allocateArrayAndFill() }), "IntList.copy" to BenchmarkEntryWithInit.create(::IntListBenchmark, { copy() }), "IntList.copyManual" to BenchmarkEntryWithInit.create(::IntListBenchmark, { copyManual() }), "IntList.filterAndCount" to BenchmarkEntryWithInit.create(::IntListBenchmark, { filterAndCount() }), "IntList.filterAndMap" to BenchmarkEntryWithInit.create(::IntListBenchmark, { filterAndMap() }), "IntList.filterAndMapManual" to BenchmarkEntryWithInit.create(::IntListBenchmark, { filterAndMapManual() }), "IntList.filter" to BenchmarkEntryWithInit.create(::IntListBenchmark, { filter() }), "IntList.filterManual" to BenchmarkEntryWithInit.create(::IntListBenchmark, { filterManual() }), "IntList.countFilteredManual" to BenchmarkEntryWithInit.create(::IntListBenchmark, { countFilteredManual() }), "IntList.countFiltered" to BenchmarkEntryWithInit.create(::IntListBenchmark, { countFiltered() }), "IntList.countFilteredLocal" to BenchmarkEntryWithInit.create(::IntListBenchmark, { countFilteredLocal() }), "IntList.reduce" to BenchmarkEntryWithInit.create(::IntListBenchmark, { reduce() }), "IntStream.copy" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { copy() }), "IntStream.copyManual" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { copyManual() }), "IntStream.filterAndCount" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { filterAndCount() }), "IntStream.filterAndMap" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { filterAndMap() }), "IntStream.filterAndMapManual" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { filterAndMapManual() }), "IntStream.filter" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { filter() }), "IntStream.filterManual" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { filterManual() }), "IntStream.countFilteredManual" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { countFilteredManual() }), "IntStream.countFiltered" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { countFiltered() }), "IntStream.countFilteredLocal" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { countFilteredLocal() }), "IntStream.reduce" to BenchmarkEntryWithInit.create(::IntStreamBenchmark, { reduce() }), "Lambda.noncapturingLambda" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { noncapturingLambda() }), "Lambda.noncapturingLambdaNoInline" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { noncapturingLambdaNoInline() }), "Lambda.capturingLambda" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { capturingLambda() }), "Lambda.capturingLambdaNoInline" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { capturingLambdaNoInline() }), "Lambda.mutatingLambda" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { mutatingLambda() }), "Lambda.mutatingLambdaNoInline" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { mutatingLambdaNoInline() }), "Lambda.methodReference" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { methodReference() }), "Lambda.methodReferenceNoInline" to BenchmarkEntryWithInit.create(::LambdaBenchmark, { methodReferenceNoInline() }), "Loop.arrayLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayLoop() }), "Loop.arrayIndexLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayIndexLoop() }), "Loop.rangeLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { rangeLoop() }), "Loop.arrayListLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayListLoop() }), "Loop.arrayWhileLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayWhileLoop() }), "Loop.arrayForeachLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayForeachLoop() }), "Loop.arrayListForeachLoop" to BenchmarkEntryWithInit.create(::LoopBenchmark, { arrayListForeachLoop() }), "MatrixMap.add" to BenchmarkEntryWithInit.create(::MatrixMapBenchmark, { add() }), "ParameterNotNull.invokeOneArgWithNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeOneArgWithNullCheck() }), "ParameterNotNull.invokeOneArgWithoutNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeOneArgWithoutNullCheck() }), "ParameterNotNull.invokeTwoArgsWithNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeTwoArgsWithNullCheck() }), "ParameterNotNull.invokeTwoArgsWithoutNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeTwoArgsWithoutNullCheck() }), "ParameterNotNull.invokeEightArgsWithNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeEightArgsWithNullCheck() }), "ParameterNotNull.invokeEightArgsWithoutNullCheck" to BenchmarkEntryWithInit.create(::ParameterNotNullAssertionBenchmark, { invokeEightArgsWithoutNullCheck() }), "PrimeList.calcDirect" to BenchmarkEntryWithInit.create(::PrimeListBenchmark, { calcDirect() }), "PrimeList.calcEratosthenes" to BenchmarkEntryWithInit.create(::PrimeListBenchmark, { calcEratosthenes() }), "Singleton.access" to BenchmarkEntryWithInit.create(::SingletonBenchmark, { access() }), "String.stringConcat" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringConcat() }), "String.stringConcatNullable" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringConcatNullable() }), "String.stringBuilderConcat" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringBuilderConcat() }), "String.stringBuilderConcatNullable" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringBuilderConcatNullable() }), "String.summarizeSplittedCsv" to BenchmarkEntryWithInit.create(::StringBenchmark, { summarizeSplittedCsv() }), "Switch.testSparseIntSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testSparseIntSwitch() }), "Switch.testDenseIntSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testDenseIntSwitch() }), "Switch.testConstSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testConstSwitch() }), "Switch.testObjConstSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testObjConstSwitch() }), "Switch.testVarSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testVarSwitch() }), "Switch.testStringsSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testStringsSwitch() }), "Switch.testEnumsSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testEnumsSwitch() }), "Switch.testDenseEnumsSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testDenseEnumsSwitch() }), "Switch.testSealedWhenSwitch" to BenchmarkEntryWithInit.create(::SwitchBenchmark, { testSealedWhenSwitch() }), "WithIndicies.withIndicies" to BenchmarkEntryWithInit.create(::WithIndiciesBenchmark, { withIndicies() }), "WithIndicies.withIndiciesManual" to BenchmarkEntryWithInit.create(::WithIndiciesBenchmark, { withIndiciesManual() }), "OctoTest" to BenchmarkEntry(::octoTest), "Calls.finalMethod" to BenchmarkEntryWithInit.create(::CallsBenchmark, { finalMethodCall() }), "Calls.openMethodMonomorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { classOpenMethodCall_MonomorphicCallsite() }), "Calls.openMethodBimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { classOpenMethodCall_BimorphicCallsite() }), "Calls.openMethodTrimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { classOpenMethodCall_TrimorphicCallsite() }), "Calls.interfaceMethodMonomorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_MonomorphicCallsite() }), "Calls.interfaceMethodBimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_BimorphicCallsite() }), "Calls.interfaceMethodTrimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_TrimorphicCallsite() }), "Calls.interfaceMethodHexamorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_HexamorphicCallsite() }), "Calls.returnBoxUnboxFolding" to BenchmarkEntryWithInit.create(::CallsBenchmark, { returnBoxUnboxFolding() }), "Calls.parameterBoxUnboxFolding" to BenchmarkEntryWithInit.create(::CallsBenchmark, { parameterBoxUnboxFolding() }), "CoordinatesSolver.solve" to BenchmarkEntryWithInit.create(::CoordinatesSolverBenchmark, { solve() }), "GraphSolver.solve" to BenchmarkEntryWithInit.create(::GraphSolverBenchmark, { solve() }), "Casts.classCast" to BenchmarkEntryWithInit.create(::CastsBenchmark, { classCast() }), "Casts.interfaceCast" to BenchmarkEntryWithInit.create(::CastsBenchmark, { interfaceCast() }), "LocalObjects.localArray" to BenchmarkEntryWithInit.create(::LocalObjectsBenchmark, { localArray() }), "LinkedListWithAtomicsBenchmark" to BenchmarkEntryWithInit.create(::LinkedListWithAtomicsBenchmark, { ensureNext() }), "Inheritance.baseCalls" to BenchmarkEntryWithInit.create(::InheritanceBenchmark, { baseCalls() }) ) ) } fun main(args: Array) { val launcher = RingLauncher() BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> if (arguments is BaseBenchmarkArguments) { launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, arguments.filter, arguments.filterRegex, arguments.verbose) } else emptyList() }, benchmarksListAction = launcher::benchmarksListAction) } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/AbstractMethodBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring /** * Created by Mikhail.Glukhikh on 06/03/2015. * * A benchmark for a single abstract method based on a string comparison */ open class AbstractMethodBenchmark { private val arr: List = zdf_win private val sequence = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" private val sequenceMap = HashMap() init { var i = 0; for (ch in sequence) { sequenceMap[ch] = i++; } } //Benchmark fun sortStrings(): Set { val res = arr.subList(0, if (BENCHMARK_SIZE < arr.size) BENCHMARK_SIZE else arr.size).toSet() return res } //Benchmark fun sortStringsWithComparator(): Set { val res = mutableSetOf() res.addAll(arr.subList(0, if (BENCHMARK_SIZE < arr.size) BENCHMARK_SIZE else arr.size)) return res } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/AllocationBenchmark.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.ring var counter = 0 open class AllocationBenchmark { class MyClass { fun inc() { counter++ } } //Benchmark fun allocateObjects() { repeat(BENCHMARK_SIZE) { MyClass().inc() } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/CallsBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring private const val RUNS = 1_000_000 open class CallsBenchmark { interface I { fun foo(): Int fun foo1(): Int = 1 fun foo2(): Int = 2 fun foo3(): Int = 3 fun foo4(): Int = 4 fun foo5(): Int = 5 fun foo6(): Int = 6 fun foo7(): Int = 7 fun foo8(): Int = 8 fun foo9(): Int = 9 fun foo10(): Int = 10 fun foo11(): Int = 11 fun foo12(): Int = 12 fun foo13(): Int = 13 fun foo14(): Int = 14 fun foo15(): Int = 15 fun foo16(): Int = 16 fun foo17(): Int = 17 fun foo18(): Int = 18 fun foo19(): Int = 19 fun foo20(): Int = 20 fun foo21(): Int = 21 fun foo22(): Int = 22 fun foo23(): Int = 23 fun foo24(): Int = 24 fun foo25(): Int = 25 fun foo26(): Int = 26 fun foo27(): Int = 27 fun foo28(): Int = 28 fun foo29(): Int = 29 fun foo30(): Int = 30 fun foo31(): Int = 31 fun foo32(): Int = 32 fun foo33(): Int = 33 fun foo34(): Int = 34 fun foo35(): Int = 35 fun foo36(): Int = 36 fun foo37(): Int = 37 fun foo38(): Int = 38 fun foo39(): Int = 39 fun foo40(): Int = 40 fun foo41(): Int = 41 fun foo42(): Int = 42 fun foo43(): Int = 43 fun foo44(): Int = 44 fun foo45(): Int = 45 fun foo46(): Int = 46 fun foo47(): Int = 47 fun foo48(): Int = 48 fun foo49(): Int = 49 fun foo50(): Int = 50 fun foo51(): Int = 51 fun foo52(): Int = 52 fun foo53(): Int = 53 fun foo54(): Int = 54 fun foo55(): Int = 55 fun foo56(): Int = 56 fun foo57(): Int = 57 fun foo58(): Int = 58 fun foo59(): Int = 59 fun foo60(): Int = 60 fun foo61(): Int = 61 fun foo62(): Int = 62 fun foo63(): Int = 63 fun foo64(): Int = 64 fun foo65(): Int = 65 fun foo66(): Int = 66 fun foo67(): Int = 67 fun foo68(): Int = 68 fun foo69(): Int = 69 fun foo70(): Int = 70 fun foo71(): Int = 71 fun foo72(): Int = 72 fun foo73(): Int = 73 fun foo74(): Int = 74 fun foo75(): Int = 75 fun foo76(): Int = 76 fun foo77(): Int = 77 fun foo78(): Int = 78 fun foo79(): Int = 79 fun foo80(): Int = 80 fun foo81(): Int = 81 fun foo82(): Int = 82 fun foo83(): Int = 83 fun foo84(): Int = 84 fun foo85(): Int = 85 fun foo86(): Int = 86 fun foo87(): Int = 87 fun foo88(): Int = 88 fun foo89(): Int = 89 fun foo90(): Int = 90 fun foo91(): Int = 91 fun foo92(): Int = 92 fun foo93(): Int = 93 fun foo94(): Int = 94 fun foo95(): Int = 95 fun foo96(): Int = 96 fun foo97(): Int = 97 fun foo98(): Int = 98 fun foo99(): Int = 99 } abstract class A : I open class B : A() { override fun foo() = 42 } open class C : A() { override fun foo() = 117 } class D: A() { override fun foo() = 314 } open class X : A() { override fun foo() = 456456 } open class Y : A() { override fun foo() = -398473 } open class Z : A() { override fun foo() = 78298734 } val d = D() val a1: A = B() val a2: A = C() val a3: A = d val i1: I = a1 val i2: I = a2 val i3: I = d val i4: I = X() val i5: I = Y() val i6: I = Z() fun finalMethodCall(): Int { var x = 0 // TODO: optimize fields accesses val d = d for (i in 0 until RUNS) x += d.foo() return x } fun classOpenMethodCall_MonomorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val a1 = a1 for (i in 0 until RUNS) x += a1.foo() return x } fun classOpenMethodCall_BimorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val a1 = a1 val a2 = a2 for (i in 0 until RUNS) x += (if (i and 1 == 0) a1 else a2).foo() return x } fun classOpenMethodCall_TrimorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val a1 = a1 val a2 = a2 val a3 = a3 for (i in 0 until RUNS) x += (when (i % 3) { 1 -> a1 2 -> a2 else -> a3 }).foo() return x } fun interfaceMethodCall_MonomorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val i1 = i1 for (i in 0 until RUNS) x += i1.foo() return x } fun interfaceMethodCall_BimorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val i1 = i1 val i2 = i2 for (i in 0 until RUNS) x += (if (i and 1 == 0) i1 else i2).foo() return x } fun interfaceMethodCall_TrimorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val i1 = i1 val i2 = i2 val i3 = i3 for (i in 0 until RUNS) x += (when (i % 3) { 1 -> i1 2 -> i2 else -> i3 }).foo() return x } fun interfaceMethodCall_HexamorphicCallsite(): Int { var x = 0 // TODO: optimize fields accesses val i1 = i1 val i2 = i2 val i3 = i3 val i4 = i4 val i5 = i5 val i6 = i6 for (i in 0 until RUNS) x += (when (i % 6) { 1 -> i1 2 -> i2 3 -> i3 4 -> i4 5 -> i5 else -> i6 }).foo() return x } abstract class E { abstract fun foo(): Any } open class F : E() { override fun foo(): Int = 42 } val e: E = F() fun returnBoxUnboxFolding(): Int { var x = 0 // TODO: optimize fields accesses val e = e for (i in 0 until RUNS) x += e.foo() as Int return x } abstract class G { abstract fun foo(x: T): Int } open class H : G() { override fun foo(x: Int): Int { return x } } val g: G = H() as G fun parameterBoxUnboxFolding(): Int { var x = 0 // TODO: optimize fields accesses val g = g for (i in 0 until RUNS) x += g.foo(i) return x } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/CastsBenchmark.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.ring private const val RUNS = 2_000_000 class CastsBenchmark { interface I0 open class C0: I0 interface I1 open class C1: C0(), I1 interface I2: I0 open class C2: C1(), I2 interface I3: I1 open class C3: C2(), I3 interface I4: I0, I2 open class C4: C3(), I4 interface I5: I3 open class C5: C4(), I5 interface I6: I0, I2, I4 open class C6: C5(), I6 interface I9: I0, I2, I4 open class C9: C5(), I9, I1 interface I7: I1 open class C7: C3(), I7 interface I8: I0, I1 open class C8: C3(), I8 private fun foo_class(c: Any, x: Int, i: Int): Int { var x = x if (c is C0) x += i if (c is C1) x = x xor i if (c is C2) x += i if (c is C3) x = x xor i if (c is C4) x += i if (c is C5) x = x xor i if (c is C6) x += i if (c is C7) x = x xor i if (c is C8) x += i if (c is C9) x = x xor i return x } private fun foo_iface(c: Any, x: Int, i: Int): Int { var x = x if (c is I0) x += i if (c is I1) x = x xor i if (c is I2) x += i if (c is I3) x = x xor i if (c is I4) x += i if (c is I5) x = x xor i if (c is I6) x += i if (c is I7) x = x xor i if (c is I8) x += i if (c is I9) x = x xor i return x } fun classCast(): Int { val c0: Any = C0() val c1: Any = C1() val c2: Any = C2() val c3: Any = C3() val c4: Any = C4() val c5: Any = C5() val c6: Any = C6() val c7: Any = C7() val c8: Any = C8() val c9: Any = C9() var x = 0 for (i in 0 until RUNS) { x += foo_class(c0, x, i) x += foo_class(c1, x, i) x += foo_class(c2, x, i) x += foo_class(c3, x, i) x += foo_class(c4, x, i) x += foo_class(c5, x, i) x += foo_class(c6, x, i) x += foo_class(c7, x, i) x += foo_class(c8, x, i) x += foo_class(c9, x, i) } return x } fun interfaceCast(): Int { val c0: Any = C0() val c1: Any = C1() val c2: Any = C2() val c3: Any = C3() val c4: Any = C4() val c5: Any = C5() val c6: Any = C6() val c7: Any = C7() val c8: Any = C8() val c9: Any = C9() var x = 0 for (i in 0 until RUNS) { x += foo_iface(c0, x, i) x += foo_iface(c1, x, i) x += foo_iface(c2, x, i) x += foo_iface(c3, x, i) x += foo_iface(c4, x, i) x += foo_iface(c5, x, i) x += foo_iface(c6, x, i) x += foo_iface(c7, x, i) x += foo_iface(c8, x, i) x += foo_iface(c9, x, i) } return x } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ClassArrayBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring open class ClassArrayBenchmark { private var _data: Array? = null val data: Array get() = _data!! init { val list = ArrayList(BENCHMARK_SIZE) for (n in classValues(BENCHMARK_SIZE)) list.add(n) _data = list.toTypedArray() } //Benchmark fun copy(): List { return data.toList() } //Benchmark fun copyManual(): List { val list = ArrayList(data.size) for (item in data) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.filter { filterLoad(it) }.count() } //Benchmark fun filterAndMap(): List { return data.filter { filterLoad(it) }.map { mapLoad(it) } } //Benchmark fun filterAndMapManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterLoad(it)) { val value = mapLoad(it) list.add(value) } } return list } //Benchmark fun filter(): List { return data.filter { filterLoad(it) } } //Benchmark fun filterManual(): List { val list = ArrayList() for (it in data) { if (filterLoad(it)) list.add(it) } return list } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.count { filterLoad(it) } } //Benchmark fun countFilteredLocal(): Int { return data.cnt { filterLoad(it) } } //Benchmark // fun reduce(): Int { // return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } // } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ClassBaselineBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class ClassBaselineBenchmark { //Benchmark fun consume() { for (item in 1..BENCHMARK_SIZE) { Blackhole.consume(Value(item)) } } //Benchmark fun consumeField() { val value = Value(0) for (item in 1..BENCHMARK_SIZE) { value.value = item Blackhole.consume(value) } } //Benchmark fun allocateList(): List { val list = ArrayList(BENCHMARK_SIZE) return list } //Benchmark fun allocateArray(): Array { val list = arrayOfNulls(BENCHMARK_SIZE) return list } //Benchmark fun allocateListAndFill(): List { val list = ArrayList(BENCHMARK_SIZE) for (item in 1..BENCHMARK_SIZE) { list.add(Value(item)) } return list } //Benchmark fun allocateListAndWrite(): List { val value = Value(0) val list = ArrayList(BENCHMARK_SIZE) for (item in 1..BENCHMARK_SIZE) { list.add(value) } return list } //Benchmark fun allocateArrayAndFill(): Array { val list = arrayOfNulls(BENCHMARK_SIZE) var index = 0 for (item in 1..BENCHMARK_SIZE) { list[index++] = Value(item) } return list } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ClassListBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring open class ClassListBenchmark { private var _data: ArrayList? = null val data: ArrayList get() = _data!! init { val list = ArrayList(BENCHMARK_SIZE) for (n in classValues(BENCHMARK_SIZE)) list.add(n) _data = list } //Benchmark fun copy(): List { return data.toList() } //Benchmark fun copyManual(): List { val list = ArrayList(data.size) for (item in data) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.filter { filterLoad(it) }.count() } //Benchmark fun filterAndCountWithLambda(): Int { return data.filter { it.value % 2 == 0 }.count() } //Benchmark fun filterWithLambda(): List { return data.filter { it.value % 2 == 0 } } //Benchmark fun mapWithLambda(): List { return data.map { it.toString() } } //Benchmark fun countWithLambda(): Int { return data.count { it.value % 2 == 0 } } //Benchmark fun filterAndMapWithLambda(): List { return data.filter { it.value % 2 == 0 }.map { it.toString() } } //Benchmark fun filterAndMapWithLambdaAsSequence(): List { return data.asSequence().filter { it.value % 2 == 0 }.map { it.toString() }.toList() } //Benchmark fun filterAndMap(): List { return data.filter { filterLoad(it) }.map { mapLoad(it) } } //Benchmark fun filterAndMapManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterLoad(it)) { val value = mapLoad(it) list.add(value) } } return list } //Benchmark fun filter(): List { return data.filter { filterLoad(it) } } //Benchmark fun filterManual(): List { val list = ArrayList() for (it in data) { if (filterLoad(it)) list.add(it) } return list } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.count { filterLoad(it) } } //Benchmark // fun countFilteredLocal(): Int { // return data.cnt { filterLoad(it) } // } //Benchmark fun reduce(): Int { return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ClassStreamBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class ClassStreamBenchmark { private var _data: Iterable? = null val data: Iterable get() = _data!! init { _data = classValues(BENCHMARK_SIZE) } //Benchmark fun copy(): List { return data.asSequence().toList() } //Benchmark fun copyManual(): List { val list = ArrayList() for (item in data.asSequence()) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.asSequence().filter { filterLoad(it) }.count() } //Benchmark fun filterAndMap() { for (item in data.asSequence().filter { filterLoad(it) }.map { mapLoad(it) }) Blackhole.consume(item) } //Benchmark fun filterAndMapManual() { for (it in data.asSequence()) { if (filterLoad(it)) { val item = mapLoad(it) Blackhole.consume(item) } } } //Benchmark fun filter() { for (item in data.asSequence().filter { filterLoad(it) }) Blackhole.consume(item) } //Benchmark fun filterManual(){ for (it in data.asSequence()) { if (filterLoad(it)) Blackhole.consume(it) } } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data.asSequence()) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.asSequence().count { filterLoad(it) } } //Benchmark // fun countFilteredLocal(): Int { // return data.asSequence().cnt { filterLoad(it) } // } //Benchmark fun reduce(): Int { return data.asSequence().fold(0) {acc, it -> if (filterLoad(it)) acc + 1 else acc } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/CompanionObjectBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring open class CompanionObjectBenchmark { //Benchmark fun invokeRegularFunction() { regularCompanionObjectFunction("") } companion object { fun regularCompanionObjectFunction(o: Any): Any { return o } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/CoordinatesSolver.kt ================================================ package org.jetbrains.ring import kotlin.experimental.and class CoordinatesSolverBenchmark { val solver: Solver init { val inputValue = """ 12 5 3 25 3 9 3 9 1 3 13 3 12 6 10 10 12 2 10 10 9 2 9 5 6 12 5 0 2 10 10 14 12 5 3 9 5 2 10 10 8 1 3 9 4 0 3 14 10 10 12 0 4 6 9 6 12 5 6 10 11 12 3 9 6 9 5 3 9 6 8 5 6 8 3 12 7 10 10 11 12 3 13 6 12 3 9 6 12 2 13 4 5 5 5 6 12 5 5 2 1""".trimIndent() val input = readTillParsed(inputValue) solver = Solver(input!!) } data class Coordinate(val x: Int, val y: Int) @SinceKotlin("1.1") data class Field(val x: Int, val y: Int, val value: Byte) { fun northWall(): Boolean { return value and 1 != 0.toByte() } fun eastWall(): Boolean { return value and 2 != 0.toByte() } fun southWall(): Boolean { return value and 4 != 0.toByte() } fun westWall(): Boolean { return value and 8 != 0.toByte() } fun hasObject(): Boolean { return value and 16 != 0.toByte() } } class Input(val labyrinth: Labyrinth, val nObjects: Int) class Labyrinth(val width: Int, val height: Int, val fields: Array) { fun getField(x: Int, y: Int): Field { return fields[x + y * width] } } class Output(val steps: List) class InputParser { private val rows : MutableList> = mutableListOf() private var numObjects: Int = 0 private val input: Input get() { val width = rows[0].size val fields = arrayOfNulls(width * rows.size) for (y in rows.indices) { val row = rows[y] for (p in y*width until y*width + width) { fields[p] = row[p-y*width] } } val labyrinth = Labyrinth(width, rows.size, fields.requireNoNulls()) return Input(labyrinth, numObjects) } fun feedLine(line: String): Input? { val items = line.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() if (items.size == 1) { numObjects = items[0].toInt() return input } else if (items.size > 0) { val rowNum = rows.size val row = arrayOfNulls(items.size) for (col in items.indices) { row[col] = Field(rowNum, col, items[col].toByte()) } rows.add(row.requireNoNulls()) } return null } } class Solver(private val input: Input) { private val objects: List private val width: Int private val height: Int private val maze_end: Coordinate private var counter: Long = 0 init { objects = ArrayList() for (f in input.labyrinth.fields) { if (f.hasObject()) { objects.add(Coordinate(f.x, f.y)) } } width = input.labyrinth.width height = input.labyrinth.height maze_end = Coordinate(width - 1, height - 1) } fun solve(): Output { val steps = ArrayList() for (o in objects.indices) { var limit = input.labyrinth.width + input.labyrinth.height - 2 var ss: List? = null while (ss == null) { if (o == 0) { ss = solveWithLimit(limit, MAZE_START) { it[it.size - 1] == objects[0] } } else { ss = solveWithLimit(limit, objects[o - 1]) { it[it.size - 1] == objects[o] } } if (ss != null) { steps.addAll(ss) } limit++ } } var limit = input.labyrinth.width + input.labyrinth.height - 2 var ss: List? = null while (ss == null) { ss = solveWithLimit(limit, objects[objects.size - 1]) { it[it.size - 1] == maze_end } if (ss != null) { steps.addAll(ss) } limit++ } return createOutput(steps) } private fun createOutput(steps: List): Output { val objects : MutableList = this.objects.toMutableList() val outSteps : MutableList = mutableListOf() for (step in steps) { outSteps.add(step) if (objects.contains(step)) { outSteps.add(null) objects.remove(step) } } return Output(outSteps) } private fun isValid(steps: List): Boolean { counter++ val (x, y) = steps[steps.size - 1] return if (!(x == input.labyrinth.width - 1 && y == input.labyrinth.height - 1)) { // Jobb also a cel false } else steps.containsAll(objects) } private fun getPossibleSteps(now: Coordinate, previous: Coordinate?): ArrayList { val field = input.labyrinth.getField(now.x, now.y) val possibleSteps = ArrayList() if (now.x != width - 1 && !field.eastWall()) { possibleSteps.add(Coordinate(now.x + 1, now.y)) } if (now.x != 0 && !field.westWall()) { possibleSteps.add(Coordinate(now.x - 1, now.y)) } if (now.y != 0 && !field.northWall()) { possibleSteps.add(Coordinate(now.x, now.y - 1)) } if (now.y != height - 1 && !field.southWall()) { possibleSteps.add(Coordinate(now.x, now.y + 1)) } if (!field.hasObject() && previous != null) { possibleSteps.remove(previous) } return possibleSteps } private fun solveWithLimit(limit: Int, start: Coordinate, validFn: (List) -> Boolean): List? { var steps: MutableList? = findFirstLegitSteps(null, start, limit) while (steps != null && !validFn(steps)) { steps = alter(start, null, steps) } return steps } private fun findFirstLegitSteps(startPrev: Coordinate?, start: Coordinate, num: Int): MutableList? { var steps: MutableList? = ArrayList() var i = 0 while (i < num) { val prev: Coordinate? val state: Coordinate if (i == 0) { state = start prev = startPrev } else if (i == 1) { state = steps!![i - 1] prev = startPrev } else { state = steps!![i - 1] prev = steps[i - 2] } val possibleSteps = getPossibleSteps(state, prev) if (possibleSteps.size == 0) { if (steps!!.size == 0) { return null } steps = alter(start, startPrev, steps) if (steps == null) { return null } i-- i++ continue } val newStep = possibleSteps[0] steps!!.add(newStep) i++ } return steps } private fun alter(start: Coordinate, startPrev: Coordinate?, steps: MutableList): MutableList? { val size = steps.size var i = size - 1 while (i >= 0) { val current = steps[i] val prev = if (i == 0) start else steps[i - 1] val prevprev: Coordinate? if (i > 1) { prevprev = steps[i - 2] } else if (i == 1) { prevprev = start } else { prevprev = startPrev } val alternatives = getPossibleSteps(prev, prevprev) val index = alternatives.indexOf(current) if (index != alternatives.size - 1) { val newItem = alternatives[index + 1] steps[i] = newItem val remainder = findFirstLegitSteps(prev, newItem, size - i - 1) if (remainder == null) { i++ i-- continue } removeAfterIndexExclusive(steps, i) steps.addAll(remainder) return steps } else { if (i == 0) { return null } } i-- } return steps } companion object { private val MAZE_START = Coordinate(0, 0) private fun removeAfterIndexExclusive(list: MutableList<*>, index: Int) { val rnum = list.size - 1 - index for (i in 0 until rnum) { list.removeAt(list.size - 1) } } } } private fun readTillParsed(inputValue: String): Input? { val parser = InputParser() var input: Input? = null inputValue.lines().forEach { line -> input = parser.feedLine(line) } return input } fun solve() { val output = solver.solve() for (c in output.steps) { val value = if (c == null) { "felvesz" } else { "${c.x} ${c.y}" } } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/Data.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring fun classValues(size: Int): Iterable { return intValues(size).map { Value(it) } } fun stringValues(size: Int): Iterable { return intValues(size).map { it.toString() } } fun intValues(size: Int): Iterable { return 1..size } open class Value(var value: Int) { val text = value.toString().reversed() } fun filterLoad(v: Value): Boolean { return v.value.toString() in v.text } fun mapLoad(v: Value): String = v.text.reversed() fun filterLoad(v: Int): Boolean { return v.toString() in "0123456789" } fun mapLoad(v: Int): String = v.toString() fun filterSome(v: Int): Boolean = v % 7 == 0 || v % 11 == 0 fun filterPrime(v: Int): Boolean { if (v <= 1) return false if (v <= 3) return true if (v % 2 == 0) return false var i = 3 while (i*i <= v) { if (v % i == 0) return false i += 2 } return true } inline fun Array.cnt(predicate: (Value) -> Boolean): Int { var count = 0 for (element in this) { if (predicate(element)) count++ } return count } inline fun IntArray.cnt(predicate: (Int) -> Boolean): Int { var count = 0 for (element in this) { if (predicate(element)) count++ } return count } inline fun Iterable.cnt(predicate: (Int) -> Boolean): Int { var count = 0 for (element in this) { if (predicate(element)) count++ } return count } inline fun Sequence.cnt(predicate: (Int) -> Boolean): Int { var count = 0 for (element in this) { if (predicate(element)) count++ } return count } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/DefaultArgumentBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Random /** * Created by Mikhail.Glukhikh on 10/03/2015. * * Tests performance for function calls with default parameters */ open class DefaultArgumentBenchmark { private var arg = 0 init { arg = Random.nextInt() } fun sumTwo(first: Int, second: Int = 0): Int { return first + second } fun sumFour(first: Int, second: Int = 0, third: Int = 1, fourth: Int = third): Int { return first + second + third + fourth } fun sumEight(first: Int, second: Int = 0, third: Int = 1, fourth: Int = third, fifth: Int = fourth, sixth: Int = fifth, seventh: Int = second, eighth: Int = seventh): Int { return first + second + third + fourth + fifth + sixth + seventh + eighth } //Benchmark fun testOneOfTwo() { sumTwo(arg) } //Benchmark fun testTwoOfTwo() { sumTwo(arg, arg) } //Benchmark fun testOneOfFour() { sumFour(arg) } //Benchmark fun testFourOfFour() { sumFour(arg, arg, arg, arg) } //Benchmark fun testOneOfEight() { sumEight(arg) } //Benchmark fun testEightOfEight() { sumEight(arg, arg, arg, arg, arg, arg, arg, arg) } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ElvisBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole import org.jetbrains.benchmarksLauncher.Random open class ElvisBenchmark { class Value(var value: Int) var array : Array = arrayOf() init { array = Array(BENCHMARK_SIZE) { if (Random.nextInt(BENCHMARK_SIZE) < BENCHMARK_SIZE / 10) null else Value(Random.nextInt()) } } //Benchmark fun testElvis() { for (obj in array) { Blackhole.consume(obj?.value ?: 0) } } class Composite(val x : Int, val y : Composite?) fun check(a : Composite?) : Int { return a?.y?.x ?: (a?.x ?: 3) } fun testCompositeElvis(): Int { var result = 0 for (i in 0..BENCHMARK_SIZE) result += check(Composite(Random.nextInt(), Composite(Random.nextInt(), null))) return result } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/EulerBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring fun fibonacci(): Sequence { var a = 0 var b = 1 fun next(): Int { val res = a + b a = b b = res return res } return generateSequence { next() } } fun Any.isPalindrome() = toString() == toString().reversed() inline fun IntRange.sum(predicate: (Int) -> Boolean): Int { var sum = 0 for (i in this) if (predicate(i)) sum += i return sum } inline fun Sequence.sum(predicate: (Int) -> Boolean): Int { var sum = 0 for (i in this) if (predicate(i)) sum += i return sum } /** * A class tests decisions of various Euler problems * * NB: all tests here work slower than Java, probably because of all these functional wrappers */ open class EulerBenchmark { //Benchmark fun problem1bySequence() = (1..BENCHMARK_SIZE).asSequence().sum( { it % 3 == 0 || it % 5 == 0} ) //Benchmark fun problem1() = (1..BENCHMARK_SIZE).sum( { it % 3 == 0 || it % 5 == 0} ) //Benchmark fun problem2() = fibonacci().takeWhile { it < BENCHMARK_SIZE }.sum { it % 2 == 0 } //Benchmark fun problem4(): Long { val s: Long = BENCHMARK_SIZE.toLong() val maxLimit = (s-1)*(s-1) val minLimit = (s/10)*(s/10) val maxDiv = BENCHMARK_SIZE-1 val minDiv = BENCHMARK_SIZE/10 for (i in maxLimit downTo minLimit) { if (!i.isPalindrome()) continue; for (j in minDiv..maxDiv) { if (i % j == 0L) { val res = i / j if (res in minDiv.toLong()..maxDiv.toLong()) { return i } } } } return -1 } private val veryLongNumber = """ 73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 62229893423380308135336276614282806444486645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 82166370484403199890008895243450658541227588666881 16427171479924442928230863465674813919123162824586 17866458359124566529476545682848912883142607690042 24219022671055626321111109370544217506941658960408 07198403850962455444362981230987879927244284909188 84580156166097919133875499200524063689912560717606 05886116467109405077541002256983155200055935729725 71636269561882670428252483600823257530420752963450 """ //Benchmark fun problem8(): Long { val productSize = when(BENCHMARK_SIZE) { in 1..10 -> 4 in 11..1000 -> 8 else -> 13 } val digits: MutableList = ArrayList() for (digit in veryLongNumber) { if (digit in '0'..'9') { digits.add(digit.toInt() - '0'.toInt()) } } var largest = 0L for (i in 0..digits.size -productSize-1) { var product = 1L for (j in 0..productSize-1) { product *= digits[i+j] } if (product > largest) largest = product } return largest } //Benchmark fun problem9(): Long { val BENCHMARK_SIZE = BENCHMARK_SIZE // Looks awful but removes all implicit getSize() calls for (c in BENCHMARK_SIZE/3..BENCHMARK_SIZE-3) { val c2 = c.toLong() * c.toLong() for (b in (BENCHMARK_SIZE-c)/2..c-1) { if (b+c >= BENCHMARK_SIZE) break val a = BENCHMARK_SIZE - b - c if (a >= b) continue val b2 = b.toLong() * b.toLong() val a2 = a.toLong() * a.toLong() if (c2 == b2 + a2) { return a.toLong() * b.toLong() * c.toLong() } } } return -1L } data class Children(val left: Int, val right: Int) //Benchmark fun problem14(): List { // Simplified problem is solved here: it's not allowed to leave the interval [0..BENCHMARK_SIZE) inside a number chain val BENCHMARK_SIZE = BENCHMARK_SIZE // Build a tree // index is produced from first & second val tree = Array(BENCHMARK_SIZE, { i -> Children(i*2, if (i>4 && (i+2) % 6 == 0) (i-1)/3 else 0)}) // Find longest chain by DFS fun dfs(begin: Int): List { if (begin == 0 || begin >= BENCHMARK_SIZE) return listOf() val left = dfs(tree[begin].left) val right = dfs(tree[begin].right) return listOf(begin) + if (left.size > right.size) left else right } return dfs(1) } data class Way(val length: Int, val next: Int) //Benchmark fun problem14full(): List { val BENCHMARK_SIZE = BENCHMARK_SIZE // Previous achievements: map (number) -> (length, next) val map: MutableMap = HashMap() // Starting point map.put(1, Way(0, 0)) // Check all other numbers var bestNum = 0 var bestLen = 0 fun go(begin: Int): Way { val res = map[begin] if (res != null) return res val next = if (begin % 2 == 0) begin/2 else 3*begin+1 val childRes = go(next) val myRes = Way(childRes.length + 1, next) map[begin] = myRes return myRes } for (i in 2..BENCHMARK_SIZE-1) { val res = go(i) if (res.length > bestLen) { bestLen = res.length bestNum = i } } fun unroll(begin: Int): List { if (begin == 0) return listOf() val next = map[begin]?.next ?: 0 return listOf(begin) + unroll(next) } return unroll(bestNum) } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/FibonacciBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring /** * This test checks work with long numbers using Fibonacci sequence * * NB: all three tests here work CRITICALLY (x4...x6) slower than their Java equivalents * The reason is iteration on a progression formed as max downTo min or min..max step s. * In case of a range min..max primitive types are used by the Kotlin compiler, * but when we have a progression it's used directly with its iterator and so. */ open class FibonacciBenchmark { //Benchmark fun calcClassic(): Long { var a = 1L var b = 2L val size = BENCHMARK_SIZE for (i in 0..size-1) { val next = a + b a = b b = next } return b } //Benchmark fun calc(): Long { // This test works CRITICALLY slower compared with java equivalent (05.03.2015) var a = 1L var b = 2L // Probably for with downTo is the reason of slowness for (i in BENCHMARK_SIZE downTo 1) { val next = a + b a = b b = next } return b } //Benchmark fun calcWithProgression(): Long { // This test works CRITICALLY slower compared with java equivalent (05.03.2015) var a = 1L var b = 2L // Probably for with step is the reason of slowness for (i in 1..2*BENCHMARK_SIZE-1 step 2) { val next = a + b a = b b = next } return b } //Benchmark fun calcSquare(): Long { // This test works CRITICALLY slower compared with java equivalent (05.03.2015) var a = 1L var b = 2L val s = BENCHMARK_SIZE.toLong() val limit = s*s // Probably for with downTo is the reason of slowness for (i in limit downTo 1) { val next = a + b a = b b = next } return b } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ForLoopsBenchmark.kt ================================================ package org.jetbrains.ring class ForLoopsBenchmark { private val array: Array = Array(BENCHMARK_SIZE) { it } private val intArray: IntArray = IntArray(BENCHMARK_SIZE) { it } private val charArray: CharArray = CharArray(BENCHMARK_SIZE) { it.toChar() } private val string: String = charArray.joinToString() private val floatArray: FloatArray = FloatArray(BENCHMARK_SIZE) { it.toFloat() } fun arrayLoop(): Long { var sum = 0L for (e in array) { sum += e } return sum } fun intArrayLoop(): Long { var sum = 0L for (e in intArray) { sum += e } return sum } fun charArrayLoop(): Long { var sum = 0L for (e in charArray) { sum += e.toLong() } return sum } fun stringLoop(): Long { var sum = 0L for (e in string) { sum += e.hashCode() } return sum } fun floatArrayLoop(): Double { var sum = 0.0 for (e in floatArray) { sum += e } return sum } // Iterations over .indices fun arrayIndicesLoop(): Long { var sum = 0L for (i in array.indices) { sum += array[i] } return sum } fun intArrayIndicesLoop(): Long { var sum = 0L for (i in intArray.indices) { sum += intArray[i] } return sum } fun charArrayIndicesLoop(): Long { var sum = 0L for (i in charArray.indices) { sum += charArray[i].toLong() } return sum } fun stringIndicesLoop(): Long { var sum = 0L for (i in string.indices) { sum += string[i].hashCode() } return sum } fun floatArrayIndicesLoop(): Double { var sum = 0.0 for (i in floatArray.indices) { sum += floatArray[i] } return sum } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/GraphSolverBenchmark.kt ================================================ package org.jetbrains.ring class Graph { val nodes: MutableList = mutableListOf() val size get() = nodes.size fun first(): Node = nodes.first() operator fun get(nodeId: Int): Node = nodes.getOrElse(nodeId) { nodes.add(it, Node(it)) ; nodes[it] } } class Node(val id: Int) { val neighbors: MutableMap = mutableMapOf() } fun parseData(content: List): Graph { val graph = Graph() content.filter(String::isNotBlank).forEachIndexed { lineNumber, line -> addNeighbors(line, graph, lineNumber) } return graph } private data class ClosestNode(val node: Node, val distance: Int) class Greedy(private val graph: Graph) { private val visitedNodes: MutableSet = mutableSetOf() private fun getClosest(node: Node): ClosestNode? { val nodes = node.neighbors .filter { it.value != 0 && !visitedNodes.contains(it.key) } val clostest = nodes .minBy { it.value }!! return ClosestNode(clostest.key, clostest.value) } fun solve() { var previousNode = graph.first() visitedNodes.add(graph.first()) var cost = 0 while (visitedNodes.size != graph.size) { val closest = getClosest(previousNode)!! visitedNodes.add(closest.node) cost += closest.distance previousNode = closest.node } cost += visitedNodes.last().neighbors[graph.first()]!! } } fun addNeighbors(line: String, graph: Graph, lineNumber: Int): Node { val node = graph[lineNumber] line.split(',').forEachIndexed { index, value -> node.neighbors.put(graph[index], value.trim().toInt())//.trim().toInt()) } return node } class GraphSolverBenchmark { val content = listOf( "0,604,802,57,278,84,33,758,908,420,610,484,195,474,254,969,172,463,130,335,704,507,358,852,356,444,396,95,446,86,397,893,56,812,967,40,229,33,112,913,548,902,793,563,318,311,579,58,145,304,133,440,159,219,300,855,443,385,157,770,29,97,229,734,829,324,917,380,817,597,461,386,536,942,533,774,71,996,752,6,741,644,701,782,870,947,159,464,412,807,765,174,334,77,930,536,885,533,202,191,825,342,578,76,394,432,786,313,693,587,659,55,491,467,33,955,883,353,452,60,588,87,109,473,66,965,973,950,952,492,624,810,87,62,218,435,559,283,562,798,349,201,383,249,69,263,415,961,56,755,616,27,186,63,247,800,503,767,869,13,252,746,6,436,793,189,926,442,465,225,573,379,875,620,294,452,832,739,354,781,348,264,790,110,369,393,678,873,8,708,268,177,722,49,448,849,381,720,166,208,178,634,557,595,969,968,384,682,558,298,726,899,444,420,481,714,524,633,897,279,760,755,101,37,769,460,252,869,700,182,507,389,263,88,291,885,106,638,375,661,375,941,487,58,890,700,121,852,700,888,814,546,374,771,683,730,478,446,456,447,369,727,258,307,794,669,438,604,549,921,848,918,694,512,390,913,118,776,441,438,488,187,813,668,373,522,411,772,943,183,6,84,984,619,453,729,744,166,880,800,860,869,805,873,296,706,901,155,111,286,958,119,652,2,140,248,809,475,752,368,924,108,276,472,469,704,92,680,374,473,372,607,251,454,718,228,252,116,812,561,49,248,826,682,598,900,239,652,367,293,196,868,18,555,746,142,170,75,788,675,661,697,632,185,283,838,509,843,222,690,783,963,550,621,211,276,133,303,695,211,957,685,686,98,902,725,707,758,194,461,411,177,912,818,92,512,480,795,586,161,962,546,891,223,476,937,669,938,516,247,668,751,195,678,848,764,888,40,291,456,710,685,129,637,876,293,194,102,153,903,414,766,368,31,561,537,962,873,902,529,362,225,936,743,782,307,217,300,921,699,664,638,862,170,916,806,721,100,395,800,244,50,746,500,962,753,547,889,199,743,611,357,952,781,899,548,507,875,434,702,109,32,835,788,108,469,171,993,886,130,871,752,217,896,446,66,223,648,352,497,782,182,463,557,20,849,685,956,834,676,28,533,256,904,606,334,472,206,942,166,38,203,953,201,566,409,64,833,958,784,852,817,835,829,911,254,917,706,681,35,456,795,615,349,597,198,643,18,955,531,431,49,80,699,35,345,830,687,406,605,872,293,697,348,296,472,951,117,464,843,96,359,945,388,226,338,41,429,367,940,474,477,978,867,975,632,388,319,999,409,145,748,136,226,853,21,620,89,319,557,602,206,759,638,977,499,723,381,223,299,298,981,642,100,95,828,794,689,778,983,201,195,905,670,313,555,762,962,212,311,572,852,657,622,461,101,771,644,925,761,286,275,297,246,904,24,327,474,455,395,148,330,919,710,485,709,341,871,669,27,5,643,840,999,940,489,803,164,806,187,989,178,257,835,516,172,594,661,77,28,961,222,953,604,611,111,296,784,967,175,448,130,611,998,669,350,234,272,149,714,942,501,378,192,28,891,694,37,788,495,961,770,736,207,903,664,21,345,480,604,451,271,99,81,131,902,314,436,979,634,63,164,849,736,283,210,5,131,117,978,379,488,392,649,951,927,757,835,567,472,530,589,959,213,74,904,270,677,787,884,287,569,182,11,604,384,440,914,286,110,760,639,284,3,523,275,968,342,759,765,907,624,468,674,891,81,205,226,907,158,473,622,67,981,858,790,268,176,998,811,987,130,307,735,414,822,625,147,210,875,778,175,388,671,762,352,550,496,82,985,340,915,946,803,441,822,142,297,409,773,356,890,170,201,815,931,486,626,223,290,722,178,39,873,601,741,88,690,295,272,189,397,631,546,178,718,124,397,234,251,503,64,990,295,733,948,449,540,728,801,351,2,553,75,595,907,299,469,258,40,524,845,281,892,64,50,994,630,380,785,60,341,278,468,828,213,711,17,190,952,370,464,291,918,454,239,399,914,451,281,720,215,62,962,8,208,617,285,391,544,521,254,215,559,184,805,737,774,661,784,206,345,994,238,979,394,685,131,822,717,397,715,607,502,400,937,653,653,352,619,733,275,753,257,766,839,814,308,402,528,912,260,754,367,8,301,917,351,988,696,570,416,444,784,581,829,870,378,368,224,956,237,86,648,448,10,856,196,146,484,229,344,870,673,738,250,949,264,995,873", "604,0,40,254,413,440,450,189,382,388,460,802,266,415,70,10,137,344,215,456,530,796,664,686,149,440,863,46,325,418,304,904,295,948,626,722,167,27,396,183,396,822,81,117,114,950,786,101,888,750,550,293,584,254,732,694,278,971,813,730,589,978,214,629,781,358,941,962,144,609,629,25,779,492,412,778,302,220,159,617,673,703,602,256,997,805,922,332,116,639,333,384,526,980,764,929,183,987,806,519,293,758,992,261,587,366,154,544,480,983,148,855,372,746,876,207,833,719,607,546,124,719,555,154,264,486,643,437,828,729,571,950,71,908,63,125,560,335,612,16,296,884,446,530,622,121,742,378,816,616,307,115,492,646,831,308,254,860,338,739,614,918,21,493,370,512,817,584,872,221,184,321,218,878,919,841,327,320,949,838,138,537,868,329,759,923,496,960,488,452,407,844,390,619,477,822,968,17,632,471,639,273,142,763,708,694,395,53,976,778,842,967,875,668,980,367,48,424,692,958,223,374,929,828,450,465,411,75,199,145,705,227,66,620,982,33,317,925,780,598,712,29,191,650,287,301,735,765,117,501,324,264,10,538,808,114,389,563,375,421,267,265,554,862,609,244,662,714,194,853,788,359,355,944,781,907,520,52,669,597,292,269,463,378,64,452,672,474,660,455,32,871,305,571,646,477,890,624,850,69,155,897,498,813,295,719,696,381,341,877,30,213,227,394,332,421,924,385,405,407,486,681,293,515,590,497,657,130,680,535,881,478,474,541,522,135,163,180,442,380,478,682,218,350,355,533,870,515,757,740,73,837,600,762,337,555,950,316,235,236,786,502,476,804,44,717,793,688,246,854,85,476,243,513,895,569,29,561,528,525,333,986,829,680,587,336,182,909,196,614,118,198,700,94,100,29,381,933,46,32,920,646,46,482,479,588,596,263,550,902,261,326,272,780,568,295,597,704,46,768,76,731,369,25,421,622,846,756,686,176,583,435,364,415,614,571,145,888,999,235,727,913,128,904,57,300,25,764,822,924,415,526,689,858,224,381,526,607,119,646,544,202,365,277,556,681,668,350,496,113,14,914,813,974,528,389,490,491,550,983,812,652,170,618,665,439,966,386,512,521,589,218,481,288,995,791,791,674,582,593,29,787,687,878,640,11,883,827,723,884,670,129,831,500,422,196,936,719,10,736,641,227,538,609,954,84,304,961,667,781,137,842,79,937,810,56,179,335,760,197,991,995,876,5,342,379,132,231,783,59,459,932,907,612,40,138,857,958,614,164,338,5,467,894,513,352,630,460,511,179,419,826,155,584,448,16,82,909,104,608,900,971,763,98,464,955,314,12,618,150,252,880,429,309,539,687,681,883,888,13,931,804,158,451,768,954,695,751,230,61,834,940,156,410,734,599,444,399,956,210,290,117,878,725,758,453,652,41,207,144,162,46,689,775,318,311,247,748,318,828,500,276,191,218,503,751,994,171,530,884,538,653,69,728,14,905,147,88,291,192,669,742,260,206,152,419,84,814,656,236,262,476,806,589,155,935,197,623,546,492,794,179,487,555,710,215,94,707,326,469,456,186,82,830,22,865,589,375,312,626,550,221,670,295,353,690,167,99,370,833,642,437,746,565,23,956,830,266,866,792,56,337,424,136,669,2,568,584,294,362,421,304,621,582,439,825,45,208,249,63,468,764,594,90,745,7,24,252,528,973,117,290,548,202,264,831,235,162,683,648,530,873,286,333,221,223,95,665,884,235,8,839,225,756,840,748,901,385,514,720,113,972,196,509,601,160,133,350,444,846,464,507,733,303,597,568,640,328,932,520,288,663,519,741,115,152,722,948,318,60,973,239,488,813,322,616,336,241,957,892,196,691,424,249,932,603,677,122,731,939,960,571,430,280,976,144,894,356,855,794,830,721,988,887,318,723,560,688,644,44,946,988,512,979,431,640,688,805,386,809,863,329,152,131,603,77,781,325,321,501,876,240,152,734,13,707,607,375,159,446,415,422,808,798,299,683,47,260,871,344,638,799,881,997,342,572,487,984,96,757,77,843,367,32,840,777,640,38,541,59,160,765,92,32,56,662,451,449,517,476,672,902,22,352,970,140,513,198,595,85,601,341,719,608,663,861,509,621,813,37,195,915,662,284,749,33,812,480,949,133,947,204,246,782,244,810,48,661,585,135,99,321,450,513,70,896,564,677,490,703,977,243,630,613,262,721,100,807,17,24,534,892,626,618,59,640,908,996,874,212,342,778,657,755,777,470,233,547,913,804", "802,40,0,321,721,986,467,509,781,544,43,803,544,354,937,252,687,373,142,628,327,167,769,538,459,857,820,971,750,652,904,223,132,909,607,679,461,628,781,698,361,121,216,819,304,475,74,324,59,349,120,555,62,299,840,451,353,402,539,565,562,424,973,187,553,859,381,51,696,343,79,63,286,499,302,842,682,896,576,942,68,454,786,497,517,255,417,518,417,523,896,784,55,673,417,665,893,870,4,795,396,418,483,566,132,985,566,605,837,448,985,334,36,409,227,428,625,275,207,176,190,881,447,530,458,382,466,65,16,85,21,223,921,353,134,593,511,430,516,646,640,294,623,203,717,762,715,496,442,11,113,751,888,803,934,210,870,900,656,780,679,147,201,135,932,785,923,240,390,636,534,846,415,993,977,910,132,949,7,624,684,720,651,556,534,661,852,457,259,348,990,365,284,260,652,788,918,689,104,967,837,653,656,465,154,321,722,553,402,768,262,257,941,118,51,170,229,865,45,982,109,575,320,879,331,990,887,921,368,294,743,78,415,23,434,618,22,574,692,953,154,656,121,543,160,848,724,366,765,598,880,5,389,660,481,221,771,398,304,816,918,372,353,586,487,698,386,823,849,784,78,850,855,107,868,269,162,197,338,314,996,294,133,874,638,314,711,534,132,564,482,430,564,128,996,185,345,714,848,217,648,244,67,94,26,492,982,336,300,246,275,61,888,197,978,191,448,747,975,182,972,469,986,770,12,700,977,216,324,839,723,259,101,875,823,242,809,249,681,417,257,492,881,511,86,105,262,641,977,257,182,126,672,693,864,252,424,351,634,190,90,507,122,398,763,207,252,209,561,354,206,829,537,510,279,277,316,143,32,948,772,901,538,930,299,181,886,162,473,446,210,8,431,161,747,529,206,568,758,752,346,738,131,601,827,22,448,216,892,617,622,39,447,898,759,749,103,341,435,900,113,994,760,96,410,175,731,591,318,731,431,338,476,193,735,106,716,479,344,571,294,498,719,921,571,881,136,929,603,541,608,192,118,36,921,715,831,958,774,933,473,588,207,107,864,34,556,490,890,874,642,256,945,701,214,45,937,929,415,221,6,666,263,1,314,643,299,857,539,210,559,670,477,766,400,17,869,915,361,882,934,471,397,92,714,569,886,133,47,370,801,455,849,326,32,329,750,458,445,665,420,613,596,755,870,406,727,935,530,366,822,203,704,449,665,158,322,293,927,98,165,409,238,94,442,877,445,266,706,312,712,321,65,914,962,71,172,795,973,430,355,969,510,610,957,696,505,533,884,754,968,998,994,214,388,509,980,622,353,233,496,178,988,344,445,890,50,376,620,766,552,98,392,700,723,753,83,245,967,253,563,736,880,519,76,3,624,102,254,8,574,804,798,832,883,137,694,608,28,318,326,928,330,987,173,553,181,402,156,163,331,587,771,204,607,979,404,137,688,572,967,206,595,5,895,787,47,844,458,451,269,716,260,849,592,462,850,840,359,296,830,724,101,730,795,997,795,415,475,851,274,953,899,29,442,830,374,754,622,73,622,190,271,412,275,427,398,206,953,138,198,947,234,745,669,47,270,799,300,67,102,566,502,796,11,186,127,426,656,576,398,723,266,895,899,439,509,1000,517,991,77,617,659,695,334,797,375,721,220,739,464,67,62,396,530,888,346,67,264,744,772,726,838,590,964,760,201,16,9,160,868,124,267,460,928,316,325,173,52,820,394,410,759,46,246,275,400,664,787,817,860,333,452,897,618,760,943,24,834,426,894,126,413,484,412,769,301,349,973,720,343,210,915,640,221,94,937,576,995,751,235,914,855,548,434,415,280,83,405,104,197,213,852,907,357,4,99,969,116,474,421,86,950,62,216,409,559,488,511,618,766,232,239,591,556,351,839,689,387,944,336,262,156,978,879,623,634,258,805,64,603,919,87,809,605,36,197,183,639,333,991,644,570,761,180,673,802,137,78,680,825,283,630,661,843,964,443,945,868,455,470,458,710,493,378,467,194,984,178,44,765,755,523,121,834,711,136,668,888,467,799,429,25,817,322,339,141,662,560,647,840,462,761,410,764,177,39,138,974,919,138,965,727,270,191,780,59,213,694,381,534,970,20,39,952,195,784,683,218,146,915,520,335,561,873,916,478,11,470,583,601,973,266,88,141,299,916,97,951,306,220,434,419,183,307,287,216,258,162,249,210,135,677,290,752,535,984,861,840,436,14,529,762,746,944,873,838,795,296,199,149,675,941,533,422,227,581,470,328,976", "57,254,321,0,726,976,877,679,555,918,259,522,153,491,650,419,377,449,295,813,575,548,550,571,135,708,85,803,595,15,973,375,674,439,832,866,244,950,993,821,818,906,58,492,863,955,503,775,396,520,652,572,404,747,304,949,222,7,383,658,89,188,122,919,600,45,473,37,105,517,619,545,30,163,866,785,54,219,573,636,635,557,930,80,595,94,675,781,143,384,363,838,109,41,294,160,950,754,224,659,377,26,517,74,503,784,953,482,526,469,13,183,732,180,775,752,408,597,866,425,684,790,475,48,839,592,379,950,990,980,716,332,189,908,819,65,555,158,438,681,78,447,931,721,183,377,333,839,570,636,296,301,947,552,920,443,592,793,781,277,326,971,673,208,83,916,373,413,642,157,212,366,680,482,876,431,961,307,10,286,188,982,970,237,614,274,50,808,973,66,918,456,370,723,118,301,412,789,988,80,886,457,333,603,737,985,546,479,222,881,247,954,128,478,249,511,378,363,108,577,932,170,241,733,500,357,200,713,503,588,513,833,440,189,241,10,210,56,331,982,572,675,525,801,546,827,99,741,130,337,869,743,702,585,401,725,478,889,796,244,310,251,484,862,94,179,486,991,626,301,855,974,793,135,183,768,746,162,3,73,810,559,822,836,74,250,739,982,336,284,604,411,974,808,349,808,688,280,743,824,396,664,467,751,156,576,183,930,471,667,564,731,900,938,249,300,542,745,24,119,41,486,869,298,149,310,350,146,568,159,209,243,164,575,305,881,528,618,755,484,103,720,541,355,467,478,787,937,241,812,835,148,453,881,774,126,782,884,518,356,981,248,862,177,472,490,194,179,788,663,855,673,728,479,937,890,328,961,91,311,494,25,587,780,924,897,532,749,460,8,857,632,316,271,872,797,99,729,76,585,832,837,838,4,777,300,30,78,656,867,583,57,407,584,442,766,895,420,238,492,552,379,572,399,353,828,763,588,735,331,837,551,855,570,15,700,400,897,800,53,800,860,105,1,616,56,840,279,360,881,322,51,34,810,143,908,482,932,521,535,174,560,208,277,693,95,928,461,747,762,718,635,225,458,617,128,272,463,260,74,531,726,822,622,831,442,410,74,411,459,89,577,969,74,672,930,663,387,973,674,275,791,723,360,238,270,588,401,704,258,575,407,823,406,50,451,566,20,547,237,307,430,331,176,121,682,696,25,379,450,458,28,899,169,627,879,97,84,702,720,820,766,328,198,794,41,970,978,175,847,324,706,885,931,724,124,423,731,15,553,949,79,979,134,926,103,578,97,905,866,443,885,11,984,698,613,689,931,623,390,532,752,456,497,438,363,701,198,900,928,344,688,842,506,946,19,933,650,97,166,439,746,837,697,444,208,346,711,674,198,784,184,159,845,876,87,817,726,301,895,295,810,239,528,531,733,988,941,654,334,9,294,441,194,902,117,969,201,451,589,106,322,482,542,746,391,529,74,858,355,46,530,200,344,955,789,221,131,555,217,275,964,137,204,388,96,121,329,156,488,645,398,23,214,709,875,129,491,668,139,276,678,673,94,764,731,778,196,10,87,3,644,914,500,643,579,508,878,52,830,363,921,839,113,129,710,623,992,97,807,906,592,985,349,872,383,83,351,431,323,391,359,930,967,986,306,796,625,65,379,201,693,135,814,498,358,847,895,906,570,936,826,397,333,62,296,431,960,424,916,47,52,69,164,479,380,496,455,615,750,957,397,293,645,50,469,67,923,552,198,698,698,741,676,831,92,846,775,142,839,268,538,803,695,765,125,263,627,877,119,195,596,480,138,858,596,439,930,922,316,917,751,203,557,26,735,95,549,702,424,479,674,86,978,189,763,34,950,927,895,947,759,83,330,348,651,773,914,494,387,644,66,219,333,87,427,163,279,443,445,189,148,665,866,855,267,417,553,94,423,992,97,737,177,97,858,890,591,23,84,945,621,755,459,536,719,128,992,591,861,91,261,411,717,702,901,488,350,620,526,733,350,364,31,590,971,381,803,419,488,319,131,741,671,756,970,751,675,855,933,133,489,195,268,776,634,871,454,976,605,380,868,472,410,549,277,392,907,893,987,408,739,799,175,752,288,861,39,40,346,963,861,481,800,907,122,455,8,770,153,338,773,13,374,709,839,956,600,429,600,92,276,650,489,804,157,259,655,193,882,169,220,309,887,270,963,648,658,221,396,15,324,725,825,479,418,240,353,110,219,78,229,348,141,223,37,50,312,367,307,885,215,565,658,738,191,136,994,706,299", "278,413,721,726,0,584,44,514,846,58,260,489,486,66,420,805,805,115,978,230,125,277,219,921,253,211,368,206,811,700,708,271,620,26,885,289,859,190,731,963,186,586,52,700,83,981,733,396,915,102,122,905,891,296,198,736,352,527,836,911,443,87,176,376,531,656,959,381,929,609,312,81,1000,453,659,936,930,252,904,894,70,352,793,354,862,234,644,180,361,702,792,312,448,312,410,924,337,720,907,222,319,153,584,855,512,917,630,916,484,362,926,942,653,37,484,416,381,553,441,433,689,677,393,767,8,904,387,965,540,463,362,112,154,430,25,850,374,206,544,833,198,844,658,692,135,85,377,546,260,736,21,40,309,74,164,250,183,886,464,540,586,85,769,967,781,41,271,412,854,961,528,724,947,269,7,530,363,253,495,230,683,634,851,906,983,610,966,563,165,217,116,528,285,413,431,736,366,235,90,514,739,357,806,963,754,213,427,819,981,661,158,123,21,946,140,526,149,85,254,710,100,317,239,471,217,966,557,263,433,940,597,706,38,330,856,790,509,460,143,434,493,332,536,989,647,96,247,695,888,276,684,916,343,55,767,754,289,190,185,906,463,10,235,374,696,742,176,98,799,394,334,620,956,45,119,527,444,102,62,169,396,806,906,889,931,706,303,468,620,208,428,374,89,572,288,456,506,667,725,392,37,641,545,137,495,653,317,90,734,473,599,566,508,383,727,957,237,607,595,683,954,325,619,544,66,607,614,236,324,201,96,373,275,738,567,516,698,89,387,14,354,780,507,305,462,897,623,397,247,241,442,888,513,754,614,277,764,716,100,162,636,592,792,827,181,620,758,118,311,525,676,765,933,298,257,668,939,971,661,4,853,257,935,245,552,766,465,922,650,824,706,553,75,185,901,342,892,859,356,312,803,982,221,565,799,161,557,185,453,164,931,35,304,724,451,305,491,572,297,716,348,606,789,268,887,224,574,308,86,348,942,839,86,52,523,396,839,841,707,919,348,140,44,526,636,479,5,507,903,582,708,988,190,983,55,243,621,141,25,64,537,171,714,685,820,43,323,800,535,249,92,178,146,125,77,374,432,388,758,158,121,868,961,959,641,370,164,925,454,333,458,739,15,856,35,467,465,404,29,956,215,265,533,307,424,501,166,501,87,268,363,134,415,175,483,103,983,327,45,527,311,248,973,862,683,951,91,681,381,923,869,307,21,469,992,196,617,598,60,70,57,62,893,315,76,635,477,538,938,757,911,414,700,648,266,682,578,597,447,734,570,236,559,417,419,971,269,858,28,151,504,236,19,941,499,760,963,163,332,910,877,116,41,128,146,582,11,573,432,919,207,846,584,704,118,44,731,780,416,806,885,332,663,999,915,174,549,545,430,738,797,127,576,100,980,867,204,620,287,178,803,153,696,80,791,526,923,824,658,602,86,332,104,689,959,217,466,184,313,774,735,829,644,115,935,807,283,48,38,796,924,559,160,206,490,866,432,511,231,445,841,657,468,723,124,940,212,387,855,65,382,504,586,70,704,459,831,492,220,308,770,832,239,828,764,273,149,191,607,382,895,187,513,554,997,630,52,938,264,872,260,187,911,918,541,328,517,743,975,485,967,608,24,647,760,861,226,362,600,681,528,416,971,781,46,230,837,541,235,391,594,274,263,372,648,593,792,626,755,535,235,739,8,808,65,759,13,59,364,50,485,393,960,972,970,967,711,876,786,423,412,254,107,395,785,784,220,876,21,6,904,304,305,809,359,276,533,921,150,496,606,147,111,541,85,646,710,749,708,357,354,33,80,28,356,181,864,889,143,916,455,731,655,620,704,544,462,593,295,507,389,530,650,938,349,42,308,910,587,124,492,893,574,341,652,447,701,258,565,510,804,90,290,221,926,273,147,725,871,507,777,462,209,996,989,491,232,39,221,962,152,667,200,311,195,652,81,95,307,739,685,403,955,525,289,474,172,634,987,30,171,900,638,276,703,265,664,944,563,128,263,453,400,748,515,777,114,893,20,299,530,472,598,381,288,224,610,115,941,795,565,101,837,655,613,991,940,305,438,9,902,863,58,951,266,135,131,44,133,411,77,961,778,84,857,877,378,987,612,313,8,855,543,461,724,511,154,900,464,356,42,972,42,463,353,417,733,999,854,307,510,421,702,158,19,960,930,522,360,459,142,19,826,580,833,483,779,982,61,449,490,271,884,416,9,14,178,92,142,576,113,56,15,400,212,935,668,332,465,78,957,826,559,501,195,588,558,952,887,90", "84,440,986,976,584,0,109,366,390,794,546,750,18,671,300,198,220,770,609,610,544,818,439,158,84,27,534,980,462,713,488,755,518,552,134,652,299,852,156,676,904,251,841,175,504,116,242,248,794,281,805,595,59,924,109,36,87,931,779,556,782,393,576,675,456,939,788,887,922,858,606,22,943,781,129,203,381,316,445,851,976,223,902,231,910,48,531,336,936,64,421,685,890,581,899,792,947,188,981,373,819,114,983,410,313,752,402,350,142,295,285,2,25,319,458,666,716,671,842,659,288,987,558,590,853,878,812,337,210,805,262,360,209,461,756,97,523,220,821,140,285,367,287,922,213,359,961,319,674,229,245,848,181,394,165,388,319,497,690,797,985,796,96,484,873,694,607,736,713,371,559,476,446,7,431,981,181,64,237,962,445,63,561,882,980,211,458,409,222,559,641,570,185,33,389,435,961,606,170,962,72,777,127,261,532,979,344,263,451,602,48,408,122,297,161,685,422,83,288,284,866,289,828,859,732,853,816,481,776,586,175,168,591,206,784,533,541,381,423,522,148,569,995,386,382,119,123,876,440,695,838,940,338,791,594,427,825,688,535,185,420,307,834,229,508,748,502,745,643,656,122,190,543,340,552,360,441,988,911,846,39,154,10,577,874,447,240,332,512,112,357,714,536,203,95,570,861,815,978,287,31,875,428,246,888,903,710,205,946,117,457,713,368,959,930,361,614,446,575,234,875,264,620,608,952,510,256,966,191,610,786,661,45,108,333,399,371,971,354,102,382,937,739,149,732,597,236,703,633,191,512,569,328,903,32,657,890,789,873,258,187,634,205,397,870,895,344,448,910,415,595,81,977,659,648,742,463,7,65,572,807,967,221,16,131,72,635,394,389,609,382,805,632,55,538,92,696,452,703,891,218,502,645,815,611,696,310,328,129,186,275,164,28,379,136,194,322,483,572,630,357,673,216,738,994,171,174,216,51,175,878,821,883,356,825,69,512,984,694,394,477,145,115,292,971,911,75,372,893,645,46,588,209,681,247,154,105,619,319,272,501,367,219,524,797,253,589,699,340,421,192,999,53,339,250,510,284,43,354,49,389,606,522,695,531,805,144,140,433,396,516,367,764,935,892,78,8,306,72,130,215,210,312,635,595,79,226,990,395,307,630,279,938,203,728,848,258,574,425,63,396,478,171,348,37,64,461,50,753,587,751,573,947,221,624,363,693,442,41,858,767,632,994,759,462,559,678,625,692,897,51,425,119,567,895,664,536,207,162,841,227,760,143,956,426,241,20,569,828,373,843,870,284,246,152,87,106,801,876,249,802,529,722,154,263,891,703,650,872,155,196,749,154,16,648,11,383,482,235,373,648,206,249,417,712,517,492,251,137,559,974,70,306,933,457,864,437,910,834,181,348,372,213,48,903,74,969,145,406,485,253,210,338,36,277,533,632,420,213,53,823,430,75,619,463,196,760,490,338,757,161,64,626,395,717,79,839,274,903,630,282,966,337,290,656,166,637,967,735,177,766,349,119,493,957,388,574,422,513,339,453,676,262,313,924,444,115,895,53,405,463,422,575,2,386,120,896,422,569,189,414,596,996,4,697,939,246,41,657,801,12,28,206,396,835,161,359,70,493,509,365,595,142,234,819,305,924,312,678,123,445,105,454,944,221,249,131,967,433,694,240,856,553,22,91,684,191,882,530,691,712,446,837,726,790,197,263,511,936,938,427,718,186,141,274,981,777,558,152,635,279,862,988,779,683,555,710,68,186,640,200,301,599,320,466,344,123,342,449,638,124,667,105,180,965,56,446,9,568,837,211,865,280,10,144,488,270,187,147,263,664,695,592,990,950,790,235,528,992,108,543,239,161,592,124,348,117,779,827,951,762,679,837,892,640,722,154,730,412,269,81,203,201,59,764,616,170,292,254,306,43,547,950,8,63,73,889,91,873,829,512,3,769,862,225,147,221,373,886,830,290,344,379,174,273,988,561,899,397,739,169,137,866,383,219,304,546,576,342,500,682,873,424,61,156,632,802,549,15,535,981,21,921,188,345,152,612,888,224,529,445,486,727,165,94,23,53,415,16,109,392,569,650,117,589,546,981,572,213,572,239,522,559,932,672,394,734,883,703,758,609,942,128,811,998,103,821,190,73,647,715,315,877,162,417,608,215,671,160,235,332,30,472,905,503,385,772,467,9,739,23,814,719,862,674,138,258,562,714,67,423,220,485,699,427,752,873,174,771,921,89,607,196,535,191,89,761,182,869,282", "33,450,467,877,44,109,0,352,21,21,261,739,777,16,839,512,876,59,263,709,919,213,354,765,858,223,556,268,898,611,385,74,864,503,490,891,805,551,77,475,499,367,648,899,319,175,223,988,808,296,3,216,197,192,807,627,976,46,264,139,974,339,715,810,819,945,897,607,144,862,835,899,562,391,157,933,691,918,516,169,380,484,378,977,227,914,681,70,970,789,910,187,914,381,999,749,341,828,857,735,438,782,840,517,151,305,449,120,631,278,314,880,642,84,408,693,358,960,799,544,434,865,975,997,6,484,873,206,860,36,171,814,737,834,185,148,472,479,969,463,751,379,202,58,855,233,826,245,408,345,736,303,16,576,212,586,909,532,443,1000,180,352,740,341,215,940,618,140,760,427,228,771,698,371,882,533,728,996,572,242,143,962,133,390,664,786,580,895,212,873,589,171,625,558,770,356,535,784,930,214,210,51,932,163,617,662,588,139,152,417,852,326,445,917,924,798,425,323,297,389,483,151,569,529,292,298,569,270,942,671,785,569,805,232,328,315,966,65,852,726,788,349,169,870,783,324,281,584,278,219,120,909,935,557,541,706,587,419,755,576,642,363,387,228,385,632,2,815,899,790,587,494,813,65,477,543,874,356,33,518,998,110,306,25,965,769,226,909,535,597,878,101,87,32,404,194,555,544,597,886,282,890,215,973,211,751,527,769,887,873,704,803,864,296,609,396,229,670,895,222,739,438,40,256,939,377,256,512,335,850,182,404,680,529,297,362,801,53,607,385,80,880,586,930,860,162,509,899,464,917,31,743,275,381,874,906,921,596,405,75,522,322,838,198,354,885,657,580,519,588,224,156,745,834,34,768,258,68,722,727,255,819,521,605,886,353,937,657,340,105,332,240,945,437,260,398,945,948,762,39,474,897,604,11,965,945,709,705,151,240,772,682,688,692,676,177,308,504,586,118,109,445,610,344,751,510,120,104,959,131,925,680,736,812,763,985,268,815,64,714,482,886,439,496,496,11,736,304,833,818,393,83,161,51,62,419,496,372,810,953,368,171,439,698,939,370,711,482,106,925,562,341,529,829,260,941,279,925,327,901,56,528,113,289,780,181,460,640,557,566,9,235,410,959,527,370,646,257,43,710,408,205,74,150,496,805,363,333,577,154,471,906,921,504,752,302,415,329,592,628,305,919,521,285,545,342,934,653,696,267,167,699,775,723,274,910,535,893,644,818,917,306,400,694,43,679,826,866,837,311,263,568,957,63,260,523,834,747,627,863,691,192,189,555,88,41,663,150,13,367,747,765,810,952,697,811,909,895,375,608,664,496,128,100,210,631,702,553,779,629,532,989,160,198,455,258,144,518,979,486,159,89,91,168,178,429,621,286,95,574,949,493,175,153,273,73,276,353,224,468,914,910,885,11,85,168,3,38,823,572,915,41,817,812,61,730,597,543,601,31,163,389,26,543,593,847,648,138,134,430,266,439,858,20,186,967,710,264,802,265,317,325,453,549,104,412,156,54,103,668,113,700,736,399,458,984,689,85,738,357,148,343,992,903,916,982,428,271,947,383,605,606,553,287,511,891,537,243,101,532,262,223,948,859,463,91,700,195,364,942,891,411,202,954,444,548,581,988,562,116,400,21,111,369,898,20,653,498,915,933,398,893,140,264,674,221,426,628,639,467,614,480,89,777,903,861,457,133,711,487,708,677,428,159,468,675,927,897,216,734,162,769,996,168,859,901,93,630,989,343,85,575,415,907,24,35,537,311,783,799,657,11,792,52,935,669,542,311,687,757,47,551,106,87,70,111,628,694,514,117,617,239,425,839,960,52,415,810,85,178,937,760,98,193,574,301,863,431,611,1,193,832,447,18,333,493,773,40,129,638,642,914,908,880,163,240,558,485,621,217,825,76,898,172,816,165,36,51,509,123,198,645,880,628,331,591,964,91,823,41,843,605,449,123,361,833,977,39,382,466,605,22,574,750,443,385,172,167,470,539,881,2,760,855,126,747,839,402,158,193,933,445,478,20,311,54,448,144,272,144,895,336,630,716,119,529,869,350,462,867,382,686,65,561,989,337,754,901,348,599,209,545,229,847,542,484,350,678,98,302,503,792,528,681,137,733,843,101,754,678,573,221,962,393,64,522,277,372,660,484,5,758,35,707,982,780,937,125,775,48,912,516,36,409,138,140,70,5,354,319,351,811,989,151,615,276,357,364,656,256,629,151,36,31,529,864,676,620,901,788,450,981,210,594,198,834,984,953,356,615", "758,189,509,679,514,366,352,0,16,948,324,345,508,350,958,671,191,112,473,406,520,758,86,333,694,407,370,771,674,426,505,434,727,207,989,692,965,677,716,680,907,936,958,437,991,17,26,520,62,551,559,991,725,857,542,434,948,381,285,492,768,785,292,660,971,74,410,654,894,494,772,171,721,50,30,345,332,991,807,406,79,962,361,385,671,639,703,192,930,605,515,398,40,15,193,759,461,212,870,888,208,809,105,879,722,693,840,129,647,159,759,668,390,542,938,186,921,931,876,323,98,161,612,366,943,400,117,683,948,673,784,636,61,936,794,170,167,509,986,13,375,779,478,393,292,552,119,960,292,334,973,949,25,417,447,821,398,782,166,274,576,392,929,16,621,938,983,853,129,116,868,436,86,47,806,981,197,160,320,323,721,619,998,763,152,4,591,731,795,633,419,666,491,146,905,454,658,97,210,591,875,959,158,278,218,106,749,847,63,667,580,959,648,234,62,275,765,225,714,273,324,532,228,819,588,784,99,727,574,839,948,234,389,326,594,396,467,750,366,713,4,265,870,415,442,696,720,732,153,578,286,636,400,68,607,755,853,301,494,359,193,11,664,49,972,444,933,753,543,631,801,419,164,442,419,916,736,57,504,204,868,692,404,680,681,544,553,215,835,276,581,167,624,183,953,552,245,760,305,58,657,230,43,759,770,252,321,126,333,939,937,281,864,383,720,204,137,198,413,911,21,306,600,683,155,219,280,959,67,655,926,355,280,663,80,404,474,647,558,732,377,821,462,46,327,46,1000,936,412,585,804,956,239,61,384,489,226,356,638,990,527,670,763,73,270,807,180,821,786,832,877,433,468,532,438,276,544,53,47,372,257,43,765,652,81,518,314,145,923,466,908,757,846,365,626,919,875,274,927,242,716,829,145,68,911,884,352,766,704,419,589,351,5,560,146,226,139,8,984,354,384,369,149,993,511,918,356,447,999,173,125,654,494,491,878,548,653,600,912,977,584,199,75,817,60,55,644,75,828,940,472,291,410,912,479,684,837,639,560,723,704,300,499,717,614,535,190,302,770,874,740,459,430,217,242,923,541,619,92,105,976,429,685,303,453,302,219,812,514,256,41,821,398,717,885,940,801,971,791,181,38,460,713,75,367,249,36,64,734,534,8,291,254,471,879,91,435,325,501,301,586,186,747,745,731,715,762,349,608,775,367,320,980,478,217,344,820,636,555,611,932,505,746,334,864,711,840,680,945,8,478,40,823,823,141,401,352,426,905,647,757,950,351,926,400,169,612,600,322,451,321,604,201,733,147,459,106,271,562,518,443,953,990,485,380,723,618,987,457,97,926,439,14,653,477,548,290,458,762,361,102,840,516,904,344,158,27,158,786,24,876,311,54,227,577,339,537,115,226,983,481,672,120,18,750,538,756,455,860,98,431,416,524,629,405,827,836,795,122,296,953,103,928,855,883,117,45,955,882,877,718,174,536,461,461,776,643,762,383,575,503,143,421,152,508,839,769,581,627,340,686,690,248,880,878,492,914,889,901,657,257,545,813,949,616,465,710,828,209,539,227,662,925,69,78,795,821,888,297,479,612,716,409,362,543,452,994,374,961,932,299,864,24,646,476,717,856,871,194,530,145,879,578,52,733,158,218,976,574,134,895,452,801,450,650,953,13,720,726,657,950,637,591,669,814,827,582,892,200,473,946,765,598,555,503,111,45,553,782,755,233,493,939,716,583,922,471,365,919,736,251,655,422,606,133,710,763,302,548,843,55,568,560,640,778,249,485,294,495,598,224,178,939,526,442,371,532,871,618,852,992,84,430,937,566,711,801,425,70,50,711,828,727,395,233,692,640,934,642,14,455,254,998,1,755,565,161,400,423,114,114,875,963,88,645,482,717,975,320,42,761,595,12,256,972,462,173,377,969,277,295,103,708,292,231,356,780,5,718,752,608,417,928,129,191,462,625,216,200,968,875,425,519,939,924,447,356,988,725,461,17,361,52,857,637,424,587,424,820,616,400,126,331,229,968,225,537,182,852,159,225,774,929,482,146,103,346,260,114,131,981,380,927,238,594,5,9,877,943,539,538,76,257,554,170,815,886,334,878,421,543,234,231,687,732,578,132,379,23,637,106,478,763,842,479,185,97,907,373,969,19,346,504,455,941,844,857,9,792,736,13,397,207,848,49,962,893,761,467,112,70,763,222,757,970,825,24,737,670,493,191,806,119,118,591,153,787,944,919,638,579,758,75,191,543,926,692,111,754,299", "908,382,781,555,846,390,21,16,0,495,554,294,295,629,687,230,555,311,18,358,529,427,183,32,412,279,915,63,722,811,624,517,195,57,654,14,815,500,464,742,842,641,923,117,654,955,690,491,962,786,155,695,926,374,383,406,957,187,738,930,945,404,533,218,244,681,924,640,849,880,78,395,920,72,272,622,583,278,571,10,211,329,173,393,793,509,839,152,287,549,202,741,557,931,904,155,418,527,881,546,216,551,185,918,485,259,73,953,402,701,729,299,354,681,251,359,99,179,420,502,390,842,589,332,80,446,572,19,331,830,440,585,514,601,150,845,943,520,438,947,309,441,43,680,725,146,201,407,364,388,855,747,933,882,213,828,769,181,777,96,443,927,478,364,290,121,831,447,54,76,45,195,375,94,57,589,889,119,143,613,371,209,57,89,326,539,207,631,658,639,993,433,715,489,956,860,812,165,634,688,682,306,567,447,804,698,943,273,255,287,147,195,163,166,594,671,903,873,660,948,695,589,81,54,718,408,135,697,926,581,527,309,884,887,512,715,381,960,181,236,39,358,579,427,377,734,814,621,370,279,218,107,442,525,533,416,212,222,225,349,213,352,213,784,397,824,381,38,642,764,616,286,278,43,471,258,732,57,651,810,559,307,586,80,625,815,379,492,101,148,593,329,630,646,343,509,647,892,134,194,988,370,770,145,941,910,526,70,937,608,253,730,227,983,527,889,952,220,890,762,86,788,359,82,499,954,120,843,213,731,440,107,909,448,105,167,971,462,604,806,910,349,365,911,363,539,768,415,102,508,501,509,624,812,288,262,73,464,930,953,798,736,960,740,835,891,268,438,611,174,520,824,452,884,179,255,894,19,553,936,616,104,673,92,234,454,653,442,939,476,470,249,130,772,156,414,695,314,152,662,621,132,970,341,732,562,314,607,845,84,235,645,375,135,284,242,533,184,334,573,70,659,922,577,634,401,917,341,552,404,197,67,713,260,556,943,617,164,336,723,740,579,975,13,488,468,882,55,957,676,962,686,734,491,108,990,355,658,204,597,733,88,994,188,879,432,637,23,527,699,195,214,941,756,230,726,559,17,113,670,354,685,345,20,78,248,12,455,171,23,770,940,972,368,53,785,928,700,666,684,803,738,861,263,3,893,121,402,932,644,444,352,652,525,215,90,757,863,604,762,915,527,478,960,288,649,899,269,961,876,862,100,417,548,423,462,298,834,146,935,674,536,660,640,843,880,180,466,994,894,12,388,51,106,569,90,572,66,622,101,335,319,528,878,751,825,756,957,821,500,192,755,582,653,834,552,272,661,312,470,488,109,516,770,281,224,746,734,822,298,854,620,471,312,524,830,339,453,510,86,936,575,882,18,572,901,252,131,135,146,616,445,725,318,562,571,801,724,916,513,758,766,894,541,793,542,433,208,479,441,256,947,998,357,184,771,130,663,498,536,855,230,680,931,594,105,617,359,169,649,80,20,285,548,725,454,985,321,248,40,661,717,626,203,709,679,367,492,964,544,852,961,608,115,242,783,664,917,134,698,672,173,629,359,506,410,86,648,22,560,793,857,260,703,849,295,308,739,534,559,298,623,816,200,793,514,228,687,745,575,547,772,980,640,105,778,623,946,247,967,406,206,370,568,80,790,262,773,330,839,508,660,484,209,615,649,202,330,118,847,346,913,649,780,750,454,705,780,998,761,392,96,468,305,384,698,777,635,548,783,382,713,672,75,73,597,599,951,499,649,928,252,127,872,913,713,304,195,235,708,176,495,552,809,188,428,171,804,703,346,613,160,124,98,222,934,211,423,177,423,250,523,750,186,537,209,209,175,10,997,640,328,917,698,909,565,837,908,967,83,800,125,901,958,632,998,959,632,45,673,814,924,838,324,994,837,758,915,236,970,350,420,309,790,497,496,291,830,948,226,136,903,924,464,66,249,132,882,320,215,351,191,265,690,28,363,463,671,973,836,330,595,127,270,968,972,718,188,214,425,585,437,249,164,304,867,500,212,69,839,938,689,883,837,411,608,866,638,464,297,72,375,203,869,838,115,343,492,122,14,815,258,606,127,39,868,750,36,308,603,933,296,878,683,909,928,555,662,809,410,121,478,514,791,436,918,397,907,156,422,988,279,705,775,980,820,673,505,679,351,31,667,103,362,311,27,906,601,928,266,228,148,260,199,11,219,609,973,647,418,155,998,535,751,757,991,418,474,396,202,326,726,45,190,658,609,912,157,875,272,354,480,128,192,279,878,552,249,407,823", "420,388,544,918,58,794,21,948,495,0,906,650,437,53,933,817,60,131,55,582,893,880,829,213,669,73,736,131,573,120,403,566,346,932,878,9,187,198,621,731,396,65,529,612,196,130,591,875,15,187,802,769,214,671,331,611,474,305,521,745,991,195,227,791,853,739,158,898,390,180,403,79,812,252,187,260,706,2,142,852,582,265,22,190,134,824,608,952,465,637,875,648,756,91,38,732,141,802,664,824,107,364,957,216,205,78,98,510,295,359,166,476,23,533,618,951,242,228,42,758,301,431,961,245,778,830,396,406,618,552,777,542,287,627,859,457,90,342,314,568,326,952,541,216,593,909,164,816,460,891,999,294,884,228,991,978,487,168,649,868,100,979,942,304,625,552,300,340,275,986,223,626,801,650,714,197,186,558,811,755,44,622,15,820,55,960,518,850,870,876,109,984,273,167,528,279,578,338,938,996,663,465,603,70,140,509,83,122,85,655,328,177,197,911,890,562,659,736,183,903,747,944,880,324,820,773,395,676,435,637,505,729,232,145,282,353,322,285,771,498,64,112,157,333,211,631,751,496,404,917,846,328,238,740,853,596,377,188,313,234,928,472,832,69,551,786,359,763,50,85,365,77,821,660,782,662,468,724,52,110,936,392,778,750,872,407,562,867,951,404,277,454,202,514,458,514,958,770,505,709,114,212,20,463,105,113,674,566,6,540,134,164,106,200,639,839,382,227,91,934,918,362,35,509,326,231,284,753,833,627,620,407,116,261,421,775,292,441,923,764,249,734,52,37,886,981,178,845,796,670,917,277,905,449,777,206,819,542,236,609,518,117,1,202,725,710,812,678,179,352,713,136,383,896,582,749,340,979,70,588,389,826,430,288,898,467,637,462,179,299,471,503,301,433,701,553,759,861,224,387,451,624,833,83,911,305,280,247,796,112,742,398,55,211,326,388,669,331,536,181,330,645,935,158,519,881,517,629,451,427,619,771,557,523,353,20,368,699,795,229,873,787,984,501,554,308,765,21,90,896,523,627,549,854,544,896,12,168,159,342,133,800,164,413,634,517,524,198,33,193,514,909,285,608,755,137,931,425,410,805,829,990,72,191,607,492,910,410,432,339,627,935,499,73,507,421,693,258,899,381,276,995,86,969,802,410,411,77,203,991,625,843,538,103,736,200,601,453,834,216,490,821,323,760,607,431,439,767,210,165,664,770,60,884,394,127,512,403,270,641,497,654,658,987,812,875,528,948,782,713,878,184,588,193,129,681,980,786,667,71,666,663,909,411,221,23,829,125,549,323,190,433,957,530,270,933,601,243,429,208,877,786,323,11,234,71,861,757,141,25,239,670,315,445,578,607,104,109,824,523,462,792,39,937,991,103,134,271,408,120,672,327,455,770,134,842,329,994,902,899,116,90,543,821,211,649,562,588,773,349,388,245,748,385,339,940,8,126,996,242,984,718,795,346,773,259,546,564,265,928,365,612,390,795,687,931,179,767,518,997,477,624,616,270,448,468,496,102,330,547,550,336,70,555,305,595,628,115,522,184,166,873,566,122,490,64,682,794,925,557,305,609,812,675,201,556,970,541,530,354,509,949,266,468,392,393,567,383,978,81,927,817,162,598,792,79,736,77,212,598,555,805,173,312,377,278,78,33,570,440,609,216,533,183,313,400,726,851,599,931,269,213,940,984,133,838,320,835,760,288,775,52,170,422,830,998,692,788,113,410,24,303,616,926,951,760,904,408,508,516,547,458,473,702,850,807,79,891,683,448,559,195,184,424,857,108,226,359,900,558,474,496,244,437,596,295,730,969,926,313,755,791,579,967,855,424,872,918,643,808,577,723,31,871,427,86,145,468,338,593,796,498,512,923,500,865,303,486,87,321,859,363,180,204,535,931,77,981,545,875,941,959,367,842,474,385,76,171,494,751,248,596,509,678,420,213,168,606,39,836,27,625,777,4,392,337,711,157,976,138,658,146,177,817,204,801,600,145,904,365,76,895,886,907,254,354,219,744,842,205,307,277,245,495,265,251,849,29,632,823,196,477,122,35,504,698,724,445,628,746,987,528,315,531,374,428,942,806,533,646,167,626,436,213,460,34,753,14,142,362,412,882,727,698,390,713,588,773,621,626,560,90,954,781,841,49,876,372,873,354,78,52,980,212,943,275,307,559,378,854,294,998,990,145,654,829,815,627,578,142,921,255,946,86,61,457,18,142,18,54,808,306,550,691,122,143,837,306,561,793,838,805,229,418,373,295,501,346,12,509", "610,460,43,259,260,546,261,324,554,906,0,354,773,953,227,795,438,900,794,598,528,234,86,872,523,742,913,352,841,518,392,982,264,47,325,816,178,620,786,202,218,529,921,751,224,543,129,72,529,848,167,509,840,471,851,544,945,328,797,300,43,899,845,307,420,634,460,995,662,779,939,880,64,655,936,602,814,436,545,729,248,617,917,301,305,250,368,491,354,760,119,984,940,302,476,19,145,863,675,876,400,435,56,906,480,543,342,408,906,639,211,571,731,354,484,964,466,734,815,262,678,553,703,270,455,894,302,697,499,126,746,585,828,929,102,782,766,478,295,512,484,542,210,58,727,292,704,596,371,828,238,415,730,183,660,372,459,530,857,541,450,302,879,922,274,836,203,712,257,866,581,518,280,188,924,223,425,619,149,349,797,664,629,295,188,39,786,204,897,506,84,563,739,84,710,906,691,848,873,689,547,480,769,287,418,185,62,9,606,582,451,450,475,717,851,373,989,311,731,911,300,882,402,442,805,102,764,89,91,847,808,110,311,977,927,702,260,517,71,656,487,158,191,280,797,416,64,286,23,26,751,700,179,956,955,732,322,865,592,89,131,242,656,763,26,494,927,990,85,958,282,810,146,859,375,634,189,387,557,56,324,285,579,696,111,693,55,214,439,339,329,789,270,472,485,373,67,4,98,868,871,926,70,757,489,240,180,719,210,32,484,403,29,679,450,658,80,891,54,654,653,725,385,85,119,952,38,817,466,633,222,661,480,560,181,364,52,213,503,431,117,206,295,637,815,756,216,965,396,748,843,896,953,608,7,311,690,903,664,116,340,956,819,17,26,846,453,259,905,635,185,368,174,505,573,423,922,923,425,339,481,426,487,26,374,839,319,795,63,663,21,433,777,702,414,112,381,396,791,10,780,563,851,835,224,150,552,634,864,437,954,164,398,629,624,388,530,579,497,945,746,770,922,945,364,507,932,164,869,183,839,943,467,271,948,753,334,585,97,238,555,486,813,567,603,219,116,700,81,797,552,261,428,759,522,373,608,847,401,199,675,723,134,382,672,915,721,762,488,497,103,69,325,282,550,907,718,851,888,424,482,735,637,656,43,281,529,839,90,670,442,842,65,520,320,513,663,396,949,767,15,366,975,497,685,160,766,906,475,725,906,948,145,128,281,19,434,451,809,35,439,684,251,242,84,503,513,511,728,502,794,618,915,205,675,682,134,82,307,695,390,385,848,126,265,341,492,686,760,525,118,32,35,990,752,752,690,13,746,626,492,320,526,666,551,158,72,20,631,751,43,417,60,954,53,106,133,261,812,379,808,600,452,899,75,474,766,606,792,879,499,599,627,991,450,83,236,868,375,52,19,495,503,458,400,841,679,147,416,610,890,648,28,474,394,51,926,197,56,960,330,228,556,994,211,800,573,260,853,513,520,746,711,548,552,964,395,132,444,154,203,567,907,724,602,150,442,336,278,813,709,766,238,895,704,728,335,867,393,99,942,926,591,929,344,523,601,363,284,636,445,850,798,516,465,159,259,551,656,849,903,467,175,883,697,274,306,415,728,344,806,398,342,750,525,24,147,834,174,439,238,478,142,983,25,864,757,810,295,91,113,812,506,526,282,817,237,607,367,984,399,973,458,931,500,355,119,801,781,571,800,623,681,54,818,365,675,20,981,762,557,244,362,998,915,243,509,381,237,662,818,814,156,923,657,900,533,32,46,190,617,775,959,627,376,440,289,173,646,976,201,856,567,104,40,914,983,394,939,358,665,474,512,946,936,313,897,450,881,979,117,506,954,861,94,395,893,280,764,231,276,637,655,275,789,636,585,570,294,174,692,54,25,298,54,905,895,926,348,189,611,442,995,338,133,900,990,133,261,770,834,318,217,435,235,185,571,798,510,469,926,77,100,214,518,657,476,484,39,39,172,880,209,135,762,351,375,856,300,833,588,591,563,882,661,74,875,788,86,753,760,749,549,657,207,400,129,268,58,512,281,953,539,603,697,982,271,78,908,673,214,78,727,962,605,789,421,430,856,663,139,334,548,278,401,840,641,195,596,242,530,557,196,480,301,528,438,492,381,352,737,160,374,154,921,531,412,878,387,444,129,307,921,414,131,509,360,626,436,947,928,717,749,468,259,366,427,458,908,297,67,492,983,411,6,276,275,818,268,916,845,821,164,599,798,484,124,467,240,778,232,867,289,135,410,958,52,975,168,642,60,578,705,41,560,54,774,940,501,457,773,153,171,405,94,105,113,50,632,738", "484,802,803,522,489,750,739,345,294,650,354,0,879,269,568,43,905,661,885,938,831,68,641,935,878,424,774,63,352,484,122,756,55,875,305,105,785,232,574,24,310,982,609,630,633,802,420,952,8,600,243,323,748,412,46,140,483,755,879,204,434,514,32,906,660,831,705,293,929,793,341,215,442,575,543,913,296,33,61,1,675,259,733,932,89,250,531,728,444,924,356,253,864,245,829,293,562,126,657,764,376,26,326,613,405,70,267,388,239,405,991,507,952,270,279,784,547,601,9,771,828,645,421,60,617,643,832,489,455,24,754,444,321,709,110,178,788,787,271,923,880,858,213,818,463,238,241,242,389,35,682,165,872,22,102,508,436,251,254,252,363,874,2,925,635,866,371,982,618,354,97,473,293,594,643,262,253,479,868,250,430,681,359,356,818,66,626,323,817,498,670,61,545,837,327,532,772,557,269,374,38,735,954,340,158,99,414,601,618,473,248,789,754,567,381,793,563,852,151,66,537,192,881,421,920,487,354,240,58,859,61,174,385,73,644,570,154,570,199,136,920,70,917,712,603,907,475,901,368,40,288,313,235,770,101,496,492,7,867,627,968,424,60,541,306,792,486,824,923,926,644,497,194,335,471,855,326,189,369,357,598,119,848,553,387,339,136,543,111,352,659,347,542,180,502,606,996,320,414,974,388,625,396,256,863,479,711,522,356,627,729,668,458,74,245,311,369,780,68,689,124,95,512,100,672,142,650,243,104,153,296,149,680,654,304,88,529,72,214,49,866,885,244,411,123,105,565,701,256,382,804,444,503,406,877,729,542,11,212,86,766,903,311,204,340,354,518,180,854,131,904,615,956,834,153,54,142,423,861,961,231,126,765,160,710,299,41,656,592,432,82,387,69,699,697,143,935,143,736,872,11,716,975,987,366,742,145,838,686,651,383,400,185,859,801,740,171,975,7,124,402,916,231,750,195,347,194,552,823,598,251,666,440,747,400,724,922,24,760,925,511,448,858,429,305,249,866,917,643,376,830,70,754,951,305,431,209,352,947,541,28,442,306,207,631,274,337,130,265,246,287,983,457,568,370,266,152,738,824,383,670,201,572,667,809,265,732,313,38,963,361,431,537,418,275,295,836,466,365,567,396,949,529,181,303,627,738,486,281,897,858,566,569,834,860,576,244,613,746,887,759,772,712,463,781,529,397,242,302,445,175,155,588,718,803,615,292,686,184,896,213,558,157,171,583,437,629,184,445,787,697,248,440,908,327,558,310,806,334,809,494,601,503,797,247,352,651,104,462,920,821,839,926,871,482,172,571,164,85,333,983,343,591,287,3,652,167,283,156,374,976,598,920,966,35,52,324,884,702,264,995,898,149,493,454,50,697,117,151,868,292,618,642,566,973,932,51,782,355,771,275,409,723,183,481,579,966,600,165,876,667,42,450,643,538,230,391,306,929,350,778,677,102,220,511,303,585,5,109,189,859,250,387,921,982,251,547,555,617,146,817,541,32,541,397,839,568,900,639,80,617,774,145,633,261,825,625,821,166,802,766,320,330,449,197,832,226,377,350,273,446,272,335,883,706,231,75,580,380,835,735,161,453,545,345,438,308,381,80,395,927,41,683,528,505,867,235,284,172,379,571,461,19,506,892,978,606,285,534,717,737,217,264,74,141,954,99,559,36,988,550,603,81,497,495,342,392,329,404,424,309,3,330,828,434,537,392,273,789,263,151,513,605,336,329,6,28,906,258,75,806,145,735,959,754,481,890,916,648,678,152,116,432,497,580,301,105,922,128,194,728,440,897,278,3,84,166,566,850,713,735,63,627,516,19,975,336,147,654,895,748,3,638,648,498,718,101,546,786,801,156,10,413,132,164,923,252,132,857,122,400,608,818,644,319,198,81,473,56,306,981,500,394,805,824,490,40,236,571,662,880,304,279,701,113,834,394,319,251,534,247,725,882,884,828,378,531,869,884,873,211,401,280,705,815,644,923,221,642,128,162,500,830,294,348,910,203,898,456,327,138,492,723,592,401,786,357,428,883,66,282,832,563,204,155,662,450,248,775,649,51,205,640,87,729,538,295,166,363,996,788,301,947,6,945,40,611,907,214,218,853,895,692,351,771,494,19,454,916,655,317,992,874,73,547,295,776,975,291,52,57,991,281,359,819,288,43,808,69,693,208,488,705,406,56,663,598,72,349,515,869,299,293,167,960,56,78,930,685,562,654,736,739,978,526,481,88,493,422,604,806,624,840,598,59,286,889,744,711,437", "195,266,544,153,486,18,777,508,295,437,773,879,0,171,471,291,787,106,859,102,784,760,146,473,131,720,555,110,194,684,590,158,346,780,667,911,951,198,340,54,504,549,491,280,220,347,268,486,9,299,597,386,352,938,893,767,400,262,637,281,979,87,554,476,847,195,19,3,745,892,732,862,901,991,990,135,976,17,242,402,856,4,260,205,751,300,780,861,242,36,508,58,527,966,612,88,946,542,398,439,223,254,44,520,883,533,793,287,467,423,118,227,758,547,842,612,906,609,671,520,52,952,506,658,506,736,465,73,739,56,52,258,590,651,441,968,711,451,283,906,890,172,416,632,677,774,433,108,677,398,220,984,888,47,459,716,683,93,360,919,697,416,372,851,248,911,958,927,471,818,648,640,460,869,473,588,539,484,126,75,351,749,262,897,271,671,168,21,927,892,512,908,721,508,346,279,119,263,7,105,905,122,454,331,189,635,672,219,199,360,362,368,711,736,232,33,812,149,232,900,183,916,943,257,953,108,750,326,454,652,382,618,136,870,184,920,194,204,774,47,642,203,113,199,514,789,31,26,708,46,854,492,577,582,701,357,398,928,755,604,890,723,30,404,154,321,978,583,520,677,503,325,244,18,482,447,694,887,529,930,618,981,790,196,925,714,441,208,772,568,673,629,299,960,54,528,520,413,911,314,543,205,128,227,287,795,386,817,471,779,151,867,632,514,667,356,151,152,320,631,943,801,687,314,692,872,406,647,143,726,114,183,905,195,554,923,626,181,558,300,429,354,760,809,272,102,948,52,325,171,426,986,253,884,52,651,725,460,707,654,316,922,996,342,585,843,895,8,291,654,58,99,536,353,44,999,944,470,197,564,525,137,683,450,148,161,608,698,61,758,209,726,580,698,668,37,820,215,276,651,161,914,587,155,479,670,998,468,167,486,40,974,795,968,514,310,426,439,872,339,781,979,282,376,438,168,75,439,314,507,184,117,90,153,956,392,710,193,713,359,76,713,275,946,214,615,806,995,342,454,80,419,980,771,985,972,855,710,948,213,896,515,692,364,527,415,155,801,586,939,529,88,612,731,246,649,829,917,937,302,998,954,290,304,473,492,733,921,274,280,796,541,402,456,110,256,983,678,392,730,542,569,286,795,596,11,713,601,402,589,23,810,440,126,430,20,858,964,379,2,471,786,759,810,104,222,127,521,897,426,222,366,49,177,177,907,649,653,881,894,930,890,128,196,55,870,167,669,509,715,482,891,536,934,483,749,466,521,745,358,538,815,396,147,807,230,875,996,189,557,149,112,359,521,701,214,503,807,865,752,386,397,293,268,339,351,891,977,536,253,610,620,748,379,66,570,141,53,681,855,506,410,781,464,463,979,729,968,492,669,538,190,97,262,598,657,916,147,669,256,318,105,214,174,381,730,542,115,406,813,47,270,677,964,549,884,412,750,109,136,21,896,200,46,535,366,258,858,980,761,407,951,425,622,532,50,64,974,735,311,448,227,920,685,194,467,603,838,672,776,937,989,62,850,262,788,364,290,783,528,473,497,432,853,146,909,192,965,357,529,630,68,436,958,242,54,873,539,740,864,938,301,983,294,118,223,174,333,213,338,419,732,897,416,890,754,151,616,581,561,259,653,951,485,469,195,814,112,512,280,94,470,748,787,839,117,404,231,260,465,128,517,464,783,577,739,675,748,729,364,625,568,575,473,671,924,279,950,482,725,747,700,732,1,511,369,346,444,695,742,365,121,332,343,245,609,918,317,355,222,572,437,188,745,371,737,506,32,54,73,780,712,560,532,510,773,695,695,391,891,325,714,929,520,219,296,231,919,943,860,999,258,119,88,845,319,63,235,23,648,965,903,155,799,844,513,388,187,724,928,953,555,453,604,205,397,864,356,718,444,102,396,154,855,947,907,725,980,23,955,200,875,95,449,806,349,129,921,428,881,201,718,895,656,742,29,921,30,4,724,250,425,192,926,488,301,306,145,527,132,952,584,433,735,348,497,743,258,797,644,52,94,398,708,364,646,258,15,791,33,461,487,94,376,402,68,678,199,26,560,946,370,722,527,133,821,546,213,957,708,726,74,441,833,296,69,896,595,33,880,3,625,933,433,430,876,921,391,252,588,244,160,152,358,759,727,755,850,676,4,250,921,413,590,278,862,529,983,315,457,644,403,974,667,413,189,503,755,875,903,779,213,598,981,11,937,993,523,679,479,753,19,248,616,758,112,687,903,380,224,259,908,843,909,500,311,890,142,346,999", "474,415,354,491,66,671,16,350,629,53,953,269,171,0,370,567,309,812,670,925,317,695,660,548,423,717,659,520,184,281,506,575,658,880,711,541,122,654,833,38,195,850,264,354,217,256,39,184,807,183,471,522,274,155,496,90,624,931,714,44,118,891,255,22,446,569,488,980,299,928,550,209,256,703,953,165,935,415,478,737,450,369,683,385,492,491,299,906,31,551,157,957,995,608,806,928,415,414,584,674,887,262,776,668,872,272,736,764,135,252,749,734,961,373,784,490,33,703,725,50,816,160,609,225,428,208,796,654,70,363,657,29,630,903,90,529,456,379,560,32,748,629,629,795,890,766,557,208,680,979,556,753,93,468,788,141,686,944,305,220,724,198,262,741,86,238,844,624,344,283,813,60,483,650,935,200,613,321,737,389,657,292,152,794,800,60,22,392,784,791,25,517,115,576,414,831,724,381,143,143,498,710,458,409,623,637,56,732,322,616,476,823,651,177,177,963,532,708,58,356,615,888,120,815,324,718,333,44,996,809,145,441,106,40,451,445,450,204,698,356,912,827,438,785,49,268,600,613,827,643,647,267,626,616,561,860,764,38,459,285,35,225,932,474,511,864,284,321,385,469,244,767,950,123,635,871,405,57,596,930,517,297,949,388,28,235,526,902,135,336,105,708,119,844,440,306,102,914,858,564,738,819,886,318,218,173,317,512,504,111,840,105,424,424,340,847,438,403,74,124,609,54,846,348,389,134,686,913,262,21,141,764,28,221,963,203,50,354,646,924,388,955,933,773,856,796,209,839,188,679,662,768,161,566,554,647,267,532,122,992,263,149,387,670,554,98,736,617,550,693,1000,768,159,673,292,163,117,157,893,890,558,844,217,152,464,967,55,64,537,840,224,791,530,709,18,274,298,227,504,799,684,824,204,114,723,863,320,934,53,455,505,933,643,159,360,731,251,782,210,339,645,921,179,314,363,959,641,231,604,131,973,433,927,515,741,195,680,902,547,98,616,616,622,750,982,754,830,347,307,907,272,5,844,213,812,192,958,659,136,665,156,522,97,160,951,395,629,62,957,688,78,299,668,803,426,934,877,743,344,918,895,12,409,851,271,295,650,790,368,859,246,106,15,694,233,331,590,181,694,329,414,959,801,128,170,390,227,191,157,208,708,670,742,219,755,156,252,403,367,968,97,18,933,516,203,475,112,211,518,484,331,633,920,226,766,981,422,821,494,408,776,625,24,845,930,893,992,331,267,642,104,444,89,46,416,589,278,230,113,281,107,962,560,815,936,460,313,990,157,398,678,602,814,881,427,237,741,270,825,790,74,222,12,29,505,311,333,503,347,230,480,188,347,631,44,521,785,376,694,912,179,624,802,145,808,991,427,645,400,702,111,132,856,149,449,658,151,542,523,243,382,144,975,109,919,467,435,826,730,142,796,991,32,413,552,785,121,952,932,600,147,945,380,128,334,866,16,356,25,366,431,587,677,11,138,258,135,354,388,167,186,929,55,408,256,194,869,16,734,12,131,794,153,315,454,770,441,791,347,6,958,627,293,17,672,771,159,788,111,342,820,704,353,995,512,82,226,686,79,511,76,183,115,514,844,964,230,914,592,671,196,794,297,911,208,496,483,695,399,6,127,936,767,509,459,894,986,87,578,674,972,675,589,526,831,542,226,561,954,499,269,969,163,133,937,939,488,37,929,259,598,775,991,797,321,247,332,302,927,556,960,264,756,769,472,270,248,216,402,197,460,468,144,404,77,729,585,36,546,154,983,58,329,522,833,822,184,255,433,301,573,341,731,379,997,865,153,161,43,573,924,692,17,737,563,943,830,587,55,334,762,122,419,574,719,479,422,194,395,369,591,510,564,542,66,18,62,904,989,475,495,47,885,878,650,296,490,435,620,841,921,297,155,590,925,870,788,161,549,951,204,545,205,199,95,833,448,773,327,973,853,399,179,252,271,181,589,671,295,600,152,838,929,369,942,140,231,550,846,582,279,830,942,927,767,138,775,731,616,459,752,168,978,489,891,601,525,991,862,112,577,958,338,19,132,554,279,710,565,339,286,429,350,486,594,73,25,987,161,99,680,773,809,901,116,93,356,155,936,168,191,450,467,490,32,609,968,247,891,331,897,939,414,548,918,936,159,70,312,721,883,62,997,28,187,817,778,28,694,819,677,115,499,498,969,38,709,409,327,974,977,568,402,983,478,510,68,490,140,441,314,698,339,19,152,925,76,681,694,119,340,936,567,700,346,353,938,415,732,899", "254,70,937,650,420,300,839,958,687,933,227,568,471,370,0,417,780,847,487,857,293,818,622,123,96,762,744,354,512,654,425,493,763,12,396,149,785,594,312,273,841,941,480,554,262,675,654,65,908,547,131,166,475,995,10,529,720,343,818,8,865,416,795,542,26,225,147,801,708,703,382,440,35,368,104,866,595,94,458,87,637,278,164,524,254,56,414,615,330,50,373,616,659,986,328,671,395,473,566,432,162,751,708,574,481,253,616,700,446,405,557,269,708,132,895,182,994,518,499,509,225,150,547,619,820,705,884,841,302,64,47,376,399,926,732,112,225,176,258,702,647,849,288,149,199,493,908,733,864,180,164,932,363,9,638,989,563,182,88,858,205,171,21,76,518,828,597,754,817,721,957,126,819,14,573,342,789,880,88,572,621,310,501,485,382,890,360,890,774,460,506,905,286,538,744,307,855,148,235,378,944,1,554,368,718,69,96,452,398,354,191,385,742,801,431,971,906,415,345,560,932,630,189,160,393,933,371,856,909,844,423,998,301,201,319,39,14,815,505,893,233,930,42,306,780,455,635,671,116,194,90,292,11,418,360,293,966,373,489,668,285,671,95,87,420,807,702,590,591,36,377,705,380,105,479,291,745,326,698,649,794,94,923,798,491,571,786,498,357,129,412,268,816,118,890,642,197,471,557,835,712,386,144,198,266,452,915,822,348,437,343,172,388,94,319,56,869,596,183,333,734,948,47,133,333,914,393,496,894,901,147,755,232,433,258,77,772,142,970,621,307,621,903,917,606,585,913,78,516,365,918,323,623,901,566,953,59,252,599,719,473,21,919,603,781,454,173,660,431,924,737,425,428,33,60,264,699,919,369,763,863,479,163,73,322,2,176,939,292,526,890,449,596,241,922,314,195,576,857,608,80,300,880,65,203,902,949,389,567,438,268,946,672,968,366,739,986,160,245,339,215,43,347,579,318,85,86,951,627,479,628,302,938,320,643,859,995,705,319,903,79,72,214,260,770,616,285,53,328,586,148,573,76,600,438,195,819,685,852,231,608,585,293,351,888,129,948,469,477,650,898,983,178,465,947,918,768,422,274,489,283,610,876,567,960,254,230,324,176,738,720,472,523,221,609,45,958,411,265,96,573,82,493,323,461,942,589,453,269,158,463,987,353,581,448,850,215,832,968,425,507,900,227,126,9,488,335,839,724,907,442,618,311,106,321,849,156,307,666,315,434,966,203,313,835,948,182,395,213,237,773,29,876,195,86,826,335,679,233,344,808,105,482,603,189,487,510,380,658,387,774,581,252,192,531,838,762,913,128,642,36,61,494,38,176,278,763,610,342,572,664,450,226,67,419,514,377,364,212,820,530,428,632,408,16,826,788,766,788,280,362,754,691,790,115,921,508,841,665,632,771,541,746,729,590,757,63,180,546,734,233,552,886,200,91,87,785,657,786,151,141,107,685,297,353,357,159,158,702,42,715,917,832,59,11,977,227,879,797,9,567,514,412,979,872,579,630,201,903,576,577,245,53,764,828,902,88,631,525,376,504,888,435,612,155,147,401,993,473,157,655,280,769,828,297,931,819,147,123,723,693,781,501,35,240,783,638,103,343,632,901,548,874,784,298,874,39,483,118,625,875,209,762,182,504,185,327,232,742,702,373,982,78,871,815,48,809,303,293,187,894,446,463,364,395,791,222,877,786,614,348,7,772,229,78,409,538,924,89,600,101,773,834,891,714,123,955,852,209,946,392,151,357,927,847,290,718,777,714,154,628,885,360,705,656,72,26,186,107,581,430,722,773,253,527,798,733,798,253,327,947,595,4,886,288,525,488,357,280,137,829,280,511,436,749,218,697,401,525,19,732,265,261,398,160,828,382,929,255,88,356,153,785,402,488,137,781,30,908,898,504,931,648,19,194,587,318,379,463,416,586,130,797,958,824,664,782,243,161,238,325,824,653,595,180,608,937,121,278,785,358,170,436,487,968,898,623,637,833,726,423,743,995,283,517,905,6,730,328,777,290,708,925,189,493,875,287,371,740,904,100,25,77,458,31,211,694,881,220,215,335,229,822,23,914,968,13,814,218,303,976,578,449,136,685,148,789,974,534,697,963,782,218,317,931,159,800,606,593,416,553,604,46,266,676,615,956,822,879,10,351,188,125,869,910,619,946,777,900,261,620,973,202,798,280,742,940,912,48,769,467,284,157,52,856,437,287,253,601,902,950,568,105,707,976,93,172,471,11,477,810,282,609,956,414,349,545,824,765,501", "969,10,252,419,805,198,512,671,230,817,795,43,291,567,417,0,669,407,187,539,62,456,304,977,900,967,804,163,336,640,427,233,478,804,284,994,373,134,567,694,759,761,88,361,216,196,886,340,312,440,30,811,652,51,758,529,324,113,509,431,992,697,80,283,626,159,963,640,734,917,633,332,458,82,736,793,446,626,233,69,310,933,325,244,45,196,69,374,264,613,748,66,299,484,672,515,531,836,420,883,621,429,297,175,171,239,897,489,48,262,455,486,490,358,491,917,621,68,359,325,958,922,438,864,471,318,771,14,724,71,932,259,356,383,296,389,651,275,178,549,624,102,291,911,218,471,841,909,306,185,587,609,154,477,303,657,544,821,302,270,303,546,429,549,515,122,199,867,262,296,754,34,214,761,210,141,746,334,404,32,807,695,306,393,134,310,137,511,494,786,913,467,697,889,413,105,49,631,639,959,939,628,169,732,275,248,427,593,256,150,117,205,323,794,59,600,32,445,436,272,209,371,361,625,559,62,193,825,813,83,955,814,429,679,570,439,716,83,493,864,879,374,159,429,730,78,782,852,374,237,901,587,499,225,998,418,113,211,156,283,224,672,408,665,343,858,85,890,339,371,674,685,664,738,867,168,819,811,819,817,882,715,941,429,410,653,937,428,188,822,501,96,964,18,315,523,954,520,502,992,290,659,91,113,885,624,310,512,751,453,873,930,748,432,905,132,849,674,454,874,793,50,454,780,958,343,247,313,567,850,609,254,788,711,811,438,183,294,950,273,254,976,671,937,89,567,348,251,360,823,160,509,618,345,147,788,767,506,486,833,365,206,471,271,831,279,297,116,335,507,778,646,887,364,977,784,836,656,129,558,169,931,228,133,632,785,648,519,330,413,286,932,351,476,455,481,608,152,674,53,567,217,375,929,469,709,335,187,460,52,500,895,602,94,252,165,947,205,187,787,463,994,443,71,760,65,523,667,99,818,974,661,774,29,45,711,372,518,700,104,741,120,558,335,835,795,476,438,863,968,418,596,620,669,157,331,781,552,628,693,639,350,713,400,112,318,692,181,95,30,620,46,124,840,961,822,321,576,598,797,292,816,757,995,525,728,907,334,722,565,18,895,851,479,225,102,368,492,405,536,839,180,677,462,2,494,456,835,454,190,697,473,499,987,704,618,420,879,746,517,86,426,169,861,106,57,412,535,479,928,227,802,604,479,222,758,618,20,385,207,402,862,935,250,621,260,655,196,941,112,815,79,973,423,852,983,101,62,49,336,613,505,617,348,339,469,458,602,340,538,551,351,450,417,108,863,226,67,386,654,78,181,231,587,892,95,604,387,518,277,467,788,297,7,126,65,339,430,420,553,219,722,125,239,953,777,569,394,324,784,23,116,738,505,463,857,663,202,665,70,843,314,103,308,67,913,96,326,854,224,542,859,351,914,725,144,44,919,60,467,384,475,122,722,690,676,805,149,491,613,56,281,49,419,962,152,866,508,937,226,226,943,745,85,239,422,607,799,400,724,628,969,509,761,278,940,591,482,571,362,908,292,860,577,532,685,844,409,482,860,143,128,649,239,795,536,76,20,447,182,367,39,144,135,150,544,40,411,766,20,687,867,920,155,763,843,472,498,518,382,471,984,876,446,32,556,752,39,247,742,931,51,616,870,371,140,900,490,456,753,896,874,504,445,969,529,623,351,773,635,906,910,521,365,356,389,748,268,585,119,907,598,879,821,316,835,275,625,484,251,450,982,547,253,425,538,733,775,857,98,12,11,688,482,43,583,935,601,797,113,41,416,209,25,804,569,553,726,341,378,690,231,168,568,683,906,121,716,168,708,933,669,338,236,216,679,913,311,307,651,499,901,787,251,197,337,179,465,196,127,906,654,850,426,710,33,556,174,795,326,536,748,925,835,61,343,9,526,377,305,356,404,774,260,39,121,707,487,572,524,689,289,220,44,789,186,946,114,382,657,442,611,45,519,755,587,2,265,28,969,453,430,379,442,516,330,652,752,60,402,719,75,173,270,218,221,931,769,886,647,196,838,211,867,370,318,460,593,874,253,924,360,119,417,946,660,446,484,41,893,401,187,757,294,968,252,581,759,997,495,21,887,366,252,86,256,672,967,195,93,523,400,7,763,869,740,15,227,741,790,5,759,122,168,139,602,131,241,390,286,112,676,560,539,693,885,809,652,326,924,995,699,540,176,520,4,774,92,945,139,221,825,104,518,534,59,404,795,700,100,803,313,202,319,137,796,278,7,696,303", "172,137,687,377,805,220,876,191,555,60,438,905,787,309,780,669,0,676,334,535,110,499,368,115,167,93,409,442,485,233,729,548,200,876,622,439,257,847,921,91,385,914,469,58,706,858,307,636,277,311,413,744,988,697,463,635,601,20,450,955,448,809,805,954,160,645,63,139,986,676,831,656,920,827,776,465,599,199,149,553,204,956,86,616,803,55,462,526,701,599,883,75,572,571,325,666,847,750,26,949,367,617,394,710,982,566,351,51,430,142,705,697,255,436,82,706,910,302,52,414,824,800,383,176,913,630,806,788,267,26,608,719,532,365,687,980,278,191,139,92,852,34,768,784,627,691,447,74,46,598,475,183,584,339,356,226,73,709,953,913,369,331,737,283,21,749,500,570,703,271,59,350,252,457,638,43,989,427,63,355,4,959,680,858,500,813,281,67,235,220,452,676,32,838,494,375,622,135,585,695,691,642,220,671,755,236,832,486,206,10,776,648,169,636,65,532,116,110,549,370,315,775,99,423,812,864,837,582,44,641,812,895,853,725,276,463,212,295,64,892,770,693,848,362,535,674,31,193,605,18,604,928,56,626,433,382,179,458,978,771,671,749,109,205,93,232,159,598,110,594,946,969,862,566,224,416,385,108,118,752,353,225,557,522,644,985,171,649,495,555,148,566,163,552,643,513,918,666,503,778,486,59,46,714,636,214,122,674,647,684,625,398,34,74,248,555,429,577,64,650,671,435,583,252,809,321,931,473,881,905,668,984,673,348,917,419,322,258,872,781,695,520,351,158,24,649,587,172,110,252,938,812,137,790,77,499,26,72,631,587,67,26,498,988,772,250,858,282,594,854,769,6,896,140,296,221,669,276,262,509,66,358,670,409,287,352,482,85,328,705,581,906,680,526,835,782,611,777,594,410,245,675,884,783,723,540,989,954,20,481,303,625,132,704,669,805,695,592,950,914,649,394,559,456,689,189,414,558,490,601,424,500,890,574,787,667,220,960,613,681,992,219,594,736,275,889,782,111,513,612,587,75,509,178,542,836,193,569,923,664,93,977,978,439,471,389,221,301,623,159,423,780,892,408,656,234,454,79,553,182,827,290,790,736,740,896,329,929,462,104,230,358,485,190,164,810,583,943,399,454,365,105,605,96,81,746,828,962,63,61,342,837,586,807,190,765,575,97,725,257,6,150,771,923,602,350,810,873,81,755,33,447,575,33,422,915,215,331,340,503,207,705,568,307,922,537,349,556,739,366,199,642,366,166,547,941,176,338,558,718,53,407,250,925,411,920,674,411,169,633,900,320,953,777,204,382,478,870,742,907,84,154,436,516,229,525,262,171,539,457,947,73,992,980,442,186,871,218,939,80,64,193,554,572,690,417,762,572,996,427,109,755,18,454,227,897,626,720,392,231,512,340,132,703,350,254,832,994,708,841,734,387,456,467,631,783,960,911,835,213,302,382,496,983,238,182,303,380,734,349,254,965,224,237,712,333,39,86,205,616,689,686,759,401,837,417,468,183,138,844,56,336,354,963,915,880,802,672,879,84,342,438,351,217,942,273,315,128,611,416,45,763,220,745,871,13,933,436,464,457,870,176,265,545,909,457,762,448,146,785,768,533,954,551,11,660,257,421,208,607,406,527,815,100,632,964,52,828,162,171,234,213,130,853,720,811,519,496,62,151,841,880,375,881,578,545,244,911,723,714,940,659,217,923,877,951,248,481,978,408,276,404,892,873,520,500,220,182,63,931,212,507,818,745,614,298,792,616,755,650,655,430,514,388,797,834,703,127,949,248,438,631,966,630,133,305,998,437,614,602,270,470,190,831,538,302,53,385,191,718,833,537,936,56,501,143,540,971,45,925,625,131,79,608,806,862,869,8,30,319,605,631,613,605,893,652,658,292,888,941,386,506,782,206,208,965,497,663,816,411,939,687,228,396,628,845,855,416,881,196,801,835,895,798,393,843,794,940,210,952,116,453,566,510,80,216,722,378,383,567,642,41,464,252,154,221,177,375,905,72,284,758,765,727,591,635,229,59,747,729,716,825,237,555,873,723,962,365,273,890,535,261,9,613,516,597,626,974,950,343,953,880,231,600,36,528,284,785,581,481,783,68,600,876,349,736,742,338,119,235,654,715,94,447,732,413,501,421,75,103,473,23,954,94,759,880,522,562,578,874,610,232,255,977,249,416,690,522,800,955,789,974,104,552,499,352,189,676,625,742,465,941,522,417,298,714,112,508,417,523,684,301,33,895,529,570,443,314,937,758", "463,344,373,449,115,770,59,112,311,131,900,661,106,812,847,407,676,0,40,23,996,231,587,141,284,596,718,189,487,11,264,597,427,921,151,214,109,947,617,842,393,142,840,240,51,446,53,749,512,341,949,115,55,309,951,611,910,245,274,827,124,507,726,978,615,539,989,338,870,1,883,789,220,534,777,976,672,700,106,711,306,160,359,687,576,905,598,694,529,391,686,503,55,934,24,774,331,257,348,383,315,442,239,828,341,228,829,684,218,38,943,866,564,80,686,965,898,820,698,4,113,969,362,489,124,794,684,376,808,848,527,102,939,359,344,226,613,390,189,327,413,267,669,63,543,301,230,373,437,17,381,273,792,586,494,596,997,68,843,946,55,174,651,469,430,871,815,958,754,652,816,936,572,906,641,438,940,267,449,284,739,370,539,909,249,310,235,493,166,574,972,223,418,517,407,721,677,76,534,959,726,319,11,963,27,20,694,15,137,457,66,239,552,777,226,687,799,490,316,72,102,762,762,16,11,639,957,36,326,603,107,428,845,444,836,578,744,769,237,688,796,70,910,357,685,665,519,584,16,574,502,38,975,705,388,729,701,76,538,956,56,207,950,623,31,584,751,272,818,480,390,257,661,934,137,990,647,710,786,629,702,650,685,460,982,231,600,617,994,915,672,468,206,222,748,787,30,146,664,249,610,727,197,610,501,682,327,862,285,694,497,177,359,192,336,568,63,293,73,776,317,127,6,260,476,86,503,831,271,203,679,271,356,340,756,652,323,849,49,539,976,420,244,243,847,36,477,578,211,681,279,34,303,268,165,867,503,318,75,296,866,245,490,768,948,718,541,112,619,276,988,324,596,822,397,586,381,438,67,776,289,111,329,895,621,944,125,324,370,208,149,966,437,910,113,345,63,259,757,86,357,325,149,884,459,802,915,917,191,113,208,488,579,420,545,219,237,325,390,4,28,597,484,268,562,740,571,176,631,377,683,280,988,889,589,718,338,350,753,457,942,343,322,257,564,20,282,239,124,132,854,215,617,730,98,61,831,264,702,416,678,830,635,441,927,38,809,540,66,72,236,558,893,515,978,280,746,663,999,39,629,427,306,848,669,223,323,842,920,200,735,751,438,435,788,290,714,782,725,167,718,890,116,664,303,521,848,809,334,87,579,245,2,243,306,466,455,116,189,281,989,455,791,37,968,551,392,28,34,857,853,663,936,943,410,480,407,296,118,985,68,42,497,97,430,780,207,142,574,680,518,382,873,826,157,915,51,582,79,432,84,182,444,530,614,208,823,908,547,116,922,556,811,866,321,130,867,937,667,311,218,88,18,880,154,335,718,720,988,429,26,677,525,852,421,493,425,713,923,568,946,776,602,832,73,659,425,254,712,563,111,482,264,429,200,835,815,874,389,619,125,732,902,704,344,935,736,895,59,258,216,48,619,588,653,159,621,909,474,376,66,369,967,253,717,587,582,774,382,154,261,897,383,639,777,451,497,329,780,515,313,218,127,269,238,508,661,13,101,146,208,962,513,566,770,64,314,836,24,242,552,778,487,22,288,773,870,339,916,56,861,207,234,994,367,473,960,562,393,705,816,133,774,347,762,381,350,170,126,647,114,986,774,826,42,856,505,368,73,33,899,101,790,551,769,38,771,890,432,513,368,587,190,15,531,971,729,121,769,307,964,473,790,746,751,484,128,566,761,637,251,734,798,929,729,348,231,842,926,261,440,145,354,500,551,933,376,235,593,560,60,281,808,676,741,169,701,869,274,120,37,958,970,195,1000,130,68,503,72,185,288,448,103,558,448,374,987,402,637,698,566,702,848,664,121,314,756,116,121,779,768,898,821,443,653,884,768,58,40,629,804,741,427,555,755,953,242,484,237,29,119,598,340,402,346,914,663,616,794,320,70,316,941,875,304,954,870,573,555,551,429,47,724,777,477,93,188,26,244,138,246,379,251,173,197,80,186,560,123,732,948,710,589,446,476,28,524,270,951,462,331,872,22,503,668,536,751,588,545,184,782,995,223,606,630,574,208,577,807,902,742,823,25,826,920,445,927,381,970,907,411,568,412,489,191,27,888,55,485,492,275,799,159,678,227,626,255,159,979,364,280,378,682,346,26,394,682,699,399,932,961,199,51,136,251,645,466,690,188,849,285,452,81,303,303,457,379,397,887,129,751,383,288,651,600,814,680,916,515,334,632,220,959,304,989,658,236,740,371,303,668,47,770,83,697,787,46,735,558,492,267,368,548,544,755,250,44,258,478,899", "130,215,142,295,978,609,263,473,18,55,794,885,859,670,487,187,334,40,0,961,451,126,268,474,960,830,869,969,534,5,142,574,324,240,649,478,379,779,978,288,265,48,517,758,431,775,101,841,59,565,609,600,483,562,234,912,588,224,640,155,46,208,705,846,944,668,919,230,828,211,293,675,498,622,456,910,498,713,451,566,903,793,250,285,666,433,188,760,297,268,318,403,663,268,45,149,105,440,737,112,30,34,631,609,949,101,804,103,980,490,400,985,795,955,738,549,602,81,464,431,306,133,576,436,121,85,1000,477,79,861,968,54,330,872,148,631,773,247,854,632,999,466,589,948,295,626,680,535,14,267,211,999,598,403,838,616,282,315,903,701,734,430,311,6,40,969,578,562,77,279,84,595,910,152,289,681,342,269,390,14,386,356,822,356,314,690,752,244,920,199,6,186,808,652,82,808,587,370,105,14,935,1,695,414,904,912,820,662,780,29,348,175,724,245,246,913,731,902,406,635,370,657,138,795,520,629,133,864,237,731,806,973,478,166,932,15,569,160,803,867,207,650,268,340,942,455,325,869,3,35,23,211,983,45,108,421,254,540,947,513,27,487,75,635,335,198,317,426,692,305,556,259,827,64,367,789,280,473,895,85,264,616,786,207,162,227,445,971,409,769,834,971,438,492,387,574,573,939,850,923,956,814,562,254,902,773,280,489,392,547,349,574,739,42,738,126,940,601,425,112,244,862,733,905,315,942,371,961,881,976,908,415,33,265,542,60,148,427,825,27,441,441,25,579,272,366,28,650,613,770,956,745,353,303,182,874,824,565,184,139,148,84,45,327,479,81,550,542,340,210,878,857,72,454,491,649,580,293,805,24,69,447,152,629,771,586,353,309,421,846,380,39,82,287,249,337,433,36,589,71,940,54,626,712,646,59,401,499,879,893,101,434,46,695,471,700,892,140,501,586,783,982,973,579,852,98,81,971,50,457,708,450,337,621,301,823,717,387,276,904,260,990,447,206,878,601,181,67,392,420,237,683,27,591,242,469,630,347,749,650,793,925,298,923,476,953,666,549,104,629,185,153,355,701,403,234,829,203,235,319,385,527,599,301,980,911,81,319,741,516,940,520,758,257,316,813,569,722,314,843,650,896,722,22,237,768,34,401,475,511,519,644,443,803,359,783,698,824,266,659,752,313,159,505,545,333,286,359,467,568,13,201,581,520,811,100,152,797,321,884,830,556,257,302,546,736,619,894,229,388,105,594,4,840,736,105,10,207,158,283,238,872,8,111,454,476,201,110,299,913,395,645,329,580,774,987,96,200,459,665,526,639,101,935,891,925,714,617,665,820,388,90,185,179,111,440,137,894,405,87,5,888,630,135,813,389,990,98,318,358,351,446,834,515,820,395,281,100,25,147,349,606,865,835,885,158,895,453,707,658,120,427,102,476,244,145,808,55,477,829,640,747,489,720,504,350,154,681,564,143,881,130,67,239,111,149,537,554,191,952,248,383,926,617,69,939,235,663,853,543,491,791,738,757,903,58,86,591,709,281,454,332,660,947,296,17,926,182,898,144,445,314,939,95,907,368,563,816,949,501,467,83,328,592,952,109,269,5,767,37,839,482,353,830,722,891,847,961,801,496,634,531,252,553,591,746,734,87,355,260,989,829,725,669,420,896,948,93,572,527,742,953,672,625,463,353,432,629,494,555,354,631,217,888,303,738,935,85,377,766,114,966,575,987,152,629,58,31,951,76,470,44,439,587,789,210,827,471,946,997,228,312,12,699,631,578,583,210,49,624,408,297,274,302,884,941,338,749,93,809,60,509,593,824,938,389,774,744,208,113,196,357,404,530,120,110,640,514,720,173,466,325,81,330,868,345,441,468,862,205,448,107,317,485,816,31,744,648,475,769,569,953,947,916,659,462,61,219,764,890,769,997,927,946,233,866,178,192,325,521,32,573,352,171,259,890,761,747,134,810,808,998,663,254,253,14,475,609,148,709,566,364,932,209,768,668,183,869,755,598,770,218,434,172,752,329,898,123,795,531,255,235,634,454,374,737,322,285,75,415,158,616,90,767,97,263,552,870,984,520,76,963,785,740,137,249,484,89,91,170,299,174,696,298,336,22,197,690,624,347,462,583,667,713,268,108,425,820,626,391,927,55,854,483,105,631,270,60,861,625,247,222,239,272,712,857,769,101,273,753,838,638,683,139,815,806,81,362,109,377,319,296,830,846,53,514,779,353,386,707,798,648,992,935,59,847,425,998,201,69", "335,456,628,813,230,610,709,406,358,582,598,938,102,925,857,539,535,23,961,0,564,541,18,691,671,992,980,200,957,281,761,131,916,499,866,525,447,991,102,120,116,344,457,957,671,801,139,906,787,718,463,818,851,42,296,9,4,335,558,419,182,611,5,695,103,414,217,81,545,573,987,608,545,100,559,274,257,452,785,833,387,649,451,627,727,694,916,473,544,67,930,143,551,906,222,144,697,334,527,215,677,180,299,982,127,552,921,74,629,258,512,679,852,100,210,700,642,531,578,329,172,337,815,560,18,175,173,602,66,193,368,223,775,357,305,854,682,582,549,693,373,326,337,706,361,85,130,39,581,475,889,658,193,73,80,97,446,415,668,284,208,499,376,498,299,111,476,811,985,132,844,395,73,166,162,661,414,234,473,509,500,98,256,952,626,722,544,862,238,666,842,448,591,822,228,692,835,867,440,485,352,407,319,955,808,426,552,722,389,252,153,299,914,703,564,48,939,849,414,573,193,871,940,468,404,567,675,711,464,42,905,689,580,213,387,684,704,814,223,366,284,118,126,721,741,663,19,32,475,4,193,288,265,37,444,108,696,496,664,960,531,80,420,642,507,711,837,52,15,664,798,220,379,419,846,269,463,25,785,620,293,112,807,637,913,600,820,998,126,760,172,100,318,874,152,667,380,796,628,94,2,968,870,940,270,36,594,595,685,321,732,387,601,750,10,410,432,792,493,43,51,654,700,57,255,775,735,355,200,527,490,123,766,537,109,504,947,537,775,572,527,193,962,295,794,1,396,118,371,114,856,463,70,707,533,213,964,350,480,877,284,421,485,657,180,953,889,249,772,28,361,139,31,494,86,739,838,182,684,460,166,550,841,386,440,750,517,242,716,532,605,532,825,732,399,897,261,660,805,283,238,32,710,603,914,629,698,252,635,852,137,352,812,100,153,431,882,246,920,407,127,4,752,995,210,52,831,492,514,213,777,265,848,874,445,503,944,837,139,350,39,764,721,410,100,184,760,948,417,32,105,936,276,696,482,292,325,93,623,278,289,401,34,932,152,822,406,720,785,98,476,542,830,807,146,430,907,207,495,629,331,877,737,577,184,214,119,277,717,845,197,513,892,527,20,410,938,793,992,262,931,344,805,778,701,373,377,837,362,468,704,59,136,190,843,623,580,747,412,426,127,725,339,922,900,127,435,957,681,354,604,166,286,724,206,173,169,759,735,694,199,604,829,468,174,289,854,691,903,562,116,241,284,430,271,119,206,64,116,937,663,149,612,297,273,733,132,468,710,80,408,313,768,384,383,360,536,586,393,51,65,280,341,691,733,290,78,775,556,797,144,632,973,558,287,703,276,686,588,71,402,836,374,416,332,741,797,650,736,152,986,757,50,857,325,227,254,59,820,502,594,278,793,702,357,689,959,138,231,585,754,622,141,126,459,112,620,474,9,770,149,237,289,836,116,171,757,111,272,479,695,7,550,860,253,96,744,875,816,12,249,545,823,994,570,767,916,754,291,31,805,537,766,543,61,622,366,820,265,821,566,988,460,84,859,345,117,890,236,166,939,943,515,688,860,341,742,318,71,675,11,843,184,611,707,256,148,906,882,459,186,408,342,254,405,72,423,732,286,234,505,920,668,324,959,410,851,471,629,352,873,895,277,112,52,805,200,937,568,523,945,941,932,612,88,599,273,398,280,265,785,678,158,509,186,762,565,457,961,107,822,19,773,62,756,270,601,71,117,220,756,333,791,715,433,860,994,143,741,320,625,567,574,55,133,861,485,631,292,685,612,725,476,860,810,238,279,799,870,420,652,678,119,323,360,400,792,899,372,925,721,496,820,173,352,605,513,804,463,83,459,282,596,35,961,343,395,356,439,286,341,563,338,65,381,971,797,886,834,388,224,923,763,152,854,424,248,888,804,174,148,103,548,155,88,371,424,563,334,992,908,948,421,350,474,862,405,924,29,312,78,830,91,74,292,105,690,887,907,212,802,519,99,392,633,124,632,702,190,206,920,421,718,24,365,665,489,734,858,653,921,868,796,469,602,735,178,595,41,76,895,311,531,617,537,737,877,823,379,804,994,642,374,593,445,470,920,356,843,110,647,753,381,31,566,578,995,352,396,772,241,879,362,464,590,828,182,291,143,8,866,611,620,643,793,455,631,569,284,638,124,296,381,607,440,765,937,969,606,655,653,934,547,934,976,425,715,104,803,933,838,562,506,802,515,512,798,349,396,9,485,43,934,861,212,148,11,943,838,148", "704,530,327,575,125,544,919,520,529,893,528,831,784,317,293,62,110,996,451,564,0,818,652,964,387,318,521,261,165,483,239,417,828,995,62,168,179,42,224,832,281,356,885,459,93,317,449,469,118,909,631,847,359,805,622,712,925,802,585,207,301,445,390,678,550,584,783,111,805,122,112,989,711,106,168,343,853,231,7,109,501,733,883,707,20,726,39,590,303,516,457,206,368,152,612,452,229,709,470,799,404,973,124,446,955,614,524,435,668,159,125,840,410,238,114,416,680,41,630,967,818,424,474,34,894,637,605,184,616,844,769,503,763,630,380,23,671,17,708,154,427,964,446,436,56,554,746,643,333,448,739,558,711,219,235,163,554,574,166,95,895,323,257,323,140,264,48,38,335,333,148,608,777,620,336,460,952,111,13,262,131,952,753,416,386,865,459,176,926,793,482,762,885,147,945,86,376,730,732,290,88,866,181,887,163,771,574,903,146,461,369,23,535,362,18,398,648,854,501,436,102,12,683,878,655,324,242,660,72,119,418,212,132,783,266,505,225,670,928,923,217,784,914,516,712,322,859,241,515,312,731,939,51,219,103,57,882,461,591,370,74,225,832,337,542,304,829,832,357,568,406,494,343,206,323,882,945,564,220,93,6,946,890,448,102,545,569,463,137,29,859,960,467,744,84,259,197,385,671,899,754,251,59,63,676,153,761,224,530,997,694,957,661,446,218,143,15,421,541,640,306,439,39,63,299,865,147,696,917,56,705,64,451,425,115,384,932,751,211,251,364,15,874,138,439,552,488,346,451,666,10,126,341,793,422,994,782,34,248,726,895,403,963,857,630,75,250,118,325,948,503,863,525,619,717,642,632,480,9,685,609,194,973,865,313,270,570,671,352,651,148,885,996,794,771,992,471,458,1000,273,784,982,153,933,356,460,483,509,61,969,992,315,455,260,997,245,368,792,772,50,53,381,288,243,347,157,767,88,316,639,341,445,608,363,933,267,474,42,84,271,142,766,715,160,759,557,90,236,31,662,587,896,571,647,653,620,746,728,673,865,853,320,435,144,404,987,606,591,322,985,74,387,939,660,84,252,665,329,479,684,394,966,887,605,298,197,995,408,118,931,894,293,65,706,99,577,355,79,293,420,334,883,200,478,663,469,426,838,928,57,460,408,403,748,715,545,504,928,192,597,886,251,211,101,277,492,552,689,951,537,567,632,690,213,675,76,9,169,886,274,147,656,891,616,664,267,653,628,209,656,910,701,618,126,561,466,650,141,910,235,548,512,707,329,597,724,591,157,445,470,648,505,820,454,796,277,332,172,134,905,896,906,747,130,141,852,329,685,567,600,524,726,678,743,404,830,856,201,401,356,546,127,483,55,898,529,166,98,493,305,438,741,697,642,631,728,294,861,684,190,688,735,517,850,457,879,614,570,631,197,974,618,656,536,870,96,200,422,355,759,936,358,741,460,348,520,947,474,371,60,291,60,809,822,12,450,485,872,100,147,414,315,823,591,571,391,846,264,556,952,693,847,663,171,576,825,111,908,587,49,696,710,250,303,396,40,10,933,92,405,865,31,860,673,552,471,726,619,730,263,242,862,640,25,181,737,397,970,523,155,562,814,736,18,597,210,443,473,873,960,62,246,3,986,749,66,552,351,802,515,580,556,593,767,678,268,834,860,70,466,267,523,233,760,456,652,567,264,477,608,772,522,506,359,954,63,216,103,460,335,784,440,390,525,609,734,337,213,37,393,691,438,954,309,294,957,279,714,886,892,9,911,423,489,773,399,648,940,959,129,401,660,755,101,675,875,35,865,50,127,356,400,376,627,383,142,262,782,112,316,36,148,319,266,461,32,2,235,128,896,102,493,609,611,396,437,23,978,884,587,494,71,176,748,618,787,555,440,720,765,594,47,65,469,69,363,19,65,986,56,562,276,153,132,201,932,660,843,232,134,654,308,458,899,808,931,734,609,841,927,87,804,522,281,60,719,263,54,54,789,667,869,986,572,347,642,393,987,368,400,243,788,177,204,492,574,693,846,196,534,839,524,781,282,632,431,100,825,988,928,171,173,841,69,963,552,649,203,792,416,581,285,476,714,724,721,543,342,15,430,254,232,886,449,269,765,591,554,246,541,351,252,167,781,737,587,62,487,328,908,772,813,174,709,796,248,49,216,161,101,127,508,102,694,98,530,562,1000,88,413,780,120,309,119,727,447,523,861,140,229,568,412,449,525,904,313,219,650,157,426,416,60,676,299,313,317,400,54,888,774", "507,796,167,548,277,818,213,758,427,880,234,68,760,695,818,456,499,231,126,541,818,0,253,24,452,95,64,826,727,77,988,67,57,877,89,355,338,517,755,736,371,820,301,912,686,86,206,212,1,443,810,940,799,698,861,924,335,630,434,265,90,699,838,363,740,377,333,222,86,171,794,984,907,268,979,16,26,111,298,878,277,858,826,659,272,260,606,627,532,654,119,843,918,462,552,310,954,895,890,622,179,331,414,32,683,795,420,210,161,62,833,199,351,334,92,657,106,126,249,429,978,814,474,243,653,979,263,732,864,214,950,763,61,276,848,868,499,396,871,87,15,366,261,986,992,650,515,2,397,983,215,159,491,289,799,952,668,60,676,676,566,918,86,951,934,716,990,924,530,124,358,928,739,599,903,259,842,515,932,947,918,333,279,153,918,394,37,590,598,622,648,440,791,620,963,244,582,319,536,912,419,73,73,53,50,140,490,319,836,328,843,948,441,685,479,100,797,614,294,137,108,551,411,678,37,51,808,828,19,424,178,638,438,332,149,13,665,3,195,341,472,993,371,12,636,621,985,962,316,226,67,381,510,554,881,75,432,219,443,575,559,892,880,425,374,49,602,24,923,444,39,970,803,54,340,746,187,292,102,418,228,334,962,968,161,308,532,659,323,208,942,342,223,991,389,329,957,554,279,596,664,741,502,924,115,378,745,98,827,996,101,984,715,456,974,452,902,862,267,214,44,637,422,334,296,980,238,467,290,974,362,48,93,861,158,562,223,443,87,8,969,946,29,147,449,396,146,584,740,449,562,383,940,506,583,362,837,81,998,472,418,220,725,491,982,506,288,586,546,798,622,180,132,741,453,857,684,436,214,309,774,34,349,945,265,95,235,216,447,777,709,757,665,788,420,820,47,960,87,163,299,948,654,264,884,225,529,154,97,880,129,543,842,911,886,498,721,572,584,523,411,226,441,645,489,219,409,80,519,904,597,486,789,569,502,558,395,605,413,935,914,814,413,443,263,107,810,726,401,701,386,504,103,281,230,803,994,9,457,973,572,462,854,197,925,338,777,366,624,299,708,523,754,986,346,908,264,308,124,293,418,839,427,602,819,391,810,814,550,72,76,829,69,311,31,66,298,973,440,391,233,157,336,778,712,450,229,728,922,360,584,107,425,45,243,254,905,322,499,583,61,578,979,660,28,65,230,600,825,864,347,937,378,754,475,130,76,148,341,385,734,306,312,7,966,73,245,607,959,143,335,436,931,885,532,295,774,634,218,358,387,407,298,161,306,831,386,128,163,471,525,559,730,179,274,196,531,787,859,307,357,164,406,964,408,43,433,146,706,160,752,76,815,707,965,141,247,352,118,203,364,424,151,709,888,267,429,157,911,944,810,722,530,277,660,23,756,697,357,456,121,222,964,431,503,518,651,699,779,531,588,550,560,114,414,201,562,813,602,978,273,877,967,903,770,491,579,350,880,406,991,568,158,141,327,226,517,806,584,825,624,504,630,866,846,347,824,633,946,837,725,391,38,712,21,443,872,988,14,702,745,309,975,6,275,706,165,461,644,560,204,34,260,719,53,480,686,904,266,979,607,601,898,808,121,721,539,685,380,533,285,947,521,400,913,816,502,176,251,342,449,121,160,488,494,126,142,598,420,614,302,228,869,555,613,712,531,333,938,631,967,989,416,700,352,193,620,401,775,954,167,63,3,572,222,471,468,968,719,352,895,859,733,323,530,981,543,671,420,904,182,196,381,711,152,580,406,149,731,308,71,206,995,956,808,645,526,828,141,754,902,775,853,976,314,915,660,355,350,805,507,200,507,45,362,470,254,261,507,265,475,246,879,306,104,424,186,240,278,648,692,804,932,568,3,811,216,137,950,957,397,43,313,902,367,537,310,717,867,387,102,148,638,454,968,220,606,752,6,144,601,392,546,631,852,790,426,95,772,433,84,700,435,516,521,909,170,786,995,892,437,480,516,516,863,965,660,450,131,771,281,339,360,381,327,290,321,571,635,331,846,186,398,98,134,398,806,901,302,326,922,371,177,510,718,347,235,322,874,775,928,284,366,436,622,998,763,257,305,384,640,329,504,75,306,69,466,719,323,401,657,386,40,173,11,767,787,64,856,476,391,540,692,699,20,313,273,219,212,47,932,586,14,309,643,367,945,853,582,572,745,866,104,532,265,554,200,3,86,246,443,432,257,597,209,55,451,316,935,971,693,16,745,623,62,357,476,133,689,824,227,858,549,415,53,366,208,865,341,947", "358,664,769,550,219,439,354,86,183,829,86,641,146,660,622,304,368,587,268,18,652,253,0,873,213,93,216,408,976,798,427,620,229,638,875,168,304,548,176,848,393,716,954,364,180,31,116,597,499,229,688,965,829,632,71,116,674,382,836,308,277,187,821,18,426,800,223,405,95,286,638,630,998,569,967,425,319,599,101,383,380,246,138,664,836,680,607,124,624,19,911,747,889,747,704,317,309,578,799,893,894,585,961,592,173,370,116,513,706,498,523,688,103,128,686,789,343,46,735,217,305,918,288,22,68,526,533,934,201,466,52,814,48,463,97,340,976,652,122,182,203,535,808,108,19,356,898,23,769,409,399,616,160,32,764,311,244,595,84,554,436,483,95,209,909,473,713,662,326,509,370,814,427,285,808,288,695,177,771,849,512,961,512,499,803,834,395,481,421,25,297,433,486,417,202,606,223,189,662,310,670,459,242,382,273,883,412,132,35,773,880,962,339,54,810,852,368,395,654,756,643,745,668,113,29,129,382,424,858,327,110,912,592,511,65,77,645,292,855,71,431,759,156,604,537,557,909,379,949,444,113,117,960,45,412,406,156,899,873,657,179,933,804,389,484,126,726,619,789,565,177,903,808,631,988,940,326,844,314,623,114,228,538,491,528,772,39,853,280,336,412,587,722,869,300,70,718,141,152,935,716,634,270,568,477,411,114,314,20,261,561,903,27,65,751,393,735,572,419,742,6,459,245,147,72,51,538,737,674,471,474,742,943,372,17,58,611,142,434,94,996,801,267,775,739,345,528,380,628,853,429,192,291,428,804,561,797,825,497,493,1,414,626,873,221,686,168,11,349,73,988,86,144,336,627,149,701,143,352,684,373,835,523,826,582,816,981,518,548,906,822,330,350,879,962,778,390,868,386,326,188,496,653,803,352,38,886,295,430,155,826,594,125,477,457,844,58,905,368,4,594,862,783,386,969,829,420,295,115,490,22,507,602,267,975,245,190,680,260,154,733,754,385,447,31,376,337,941,164,970,893,714,880,498,424,219,9,3,89,583,57,932,746,422,584,70,926,544,319,265,498,326,449,507,291,854,591,170,475,269,184,332,945,930,430,650,637,301,562,898,669,697,560,28,841,790,909,836,664,697,149,965,751,439,286,223,125,669,870,674,711,976,507,32,339,68,753,938,450,856,33,118,398,228,348,470,676,423,812,567,134,460,857,130,818,230,476,79,982,437,679,185,900,751,96,460,185,84,916,529,346,645,215,830,999,839,131,90,389,929,211,534,568,685,473,48,891,652,412,144,371,340,384,759,312,415,921,516,519,705,294,935,486,733,268,731,198,55,670,270,165,849,357,211,708,710,39,584,174,529,855,990,665,746,629,843,279,728,249,131,935,566,104,518,609,27,674,675,315,927,325,8,209,346,848,301,624,388,87,480,798,487,49,225,170,324,610,921,469,550,306,511,370,798,518,659,195,752,670,763,144,884,764,427,101,113,507,598,421,486,917,535,740,337,290,452,132,198,973,952,16,265,351,308,22,706,327,49,787,560,494,530,348,120,322,961,269,437,372,307,334,132,797,650,483,169,383,654,496,620,492,118,702,4,457,50,529,374,169,710,888,763,527,978,126,548,252,680,922,100,619,36,645,728,472,468,303,907,175,258,568,258,673,888,120,282,341,627,168,981,7,14,820,596,569,104,281,402,486,745,49,787,363,18,526,696,896,732,6,66,194,639,16,135,997,20,882,713,438,770,281,447,866,34,459,159,796,499,448,354,566,103,986,925,765,423,85,604,561,869,950,226,302,214,552,948,465,662,160,733,435,460,638,123,335,919,733,880,21,483,187,653,38,33,338,436,336,603,555,711,983,574,786,596,39,325,688,714,159,565,779,451,644,360,940,678,342,662,255,532,407,366,580,724,166,340,677,237,202,920,193,917,748,955,767,876,336,642,638,451,847,480,348,313,643,153,616,132,361,421,680,131,285,27,640,342,777,479,20,506,491,47,180,197,690,732,966,255,94,71,22,863,767,269,961,686,415,498,81,660,719,154,586,967,120,260,162,550,493,388,852,721,870,208,128,56,64,274,160,306,962,181,881,851,892,923,662,956,725,849,521,449,798,353,984,775,504,319,499,582,735,211,214,147,769,452,513,883,975,290,153,414,393,556,621,760,708,152,392,201,384,613,883,674,231,945,549,860,263,828,716,470,634,242,93,845,767,75,320,931,572,647,779,564,303,10,245,904,801,291,723,723,881,696,138,632,795,664,490,127", "852,686,538,571,921,158,765,333,32,213,872,935,473,548,123,977,115,141,474,691,964,24,873,0,8,930,962,128,274,555,24,852,567,553,386,709,481,436,99,42,651,318,186,953,242,868,322,603,543,476,937,625,980,128,910,71,368,12,513,915,810,455,175,3,589,602,871,700,319,567,456,140,54,679,382,793,213,730,283,920,779,726,107,369,208,116,113,877,36,63,136,148,977,282,753,58,490,62,174,879,995,452,956,528,23,778,609,878,237,651,935,523,846,732,84,937,118,925,814,228,708,664,236,756,535,434,794,929,188,760,676,505,949,981,609,19,147,647,6,2,568,709,661,704,54,775,311,963,388,678,497,446,71,675,468,462,233,29,798,779,555,662,992,172,122,388,677,157,318,482,881,164,395,114,98,131,921,93,823,385,789,82,631,112,82,320,959,237,653,41,151,685,240,260,169,823,62,171,504,950,750,577,281,887,713,454,760,113,141,72,774,525,400,15,344,845,779,755,564,36,162,224,805,381,34,873,417,500,482,831,537,226,159,489,219,211,732,328,651,275,976,432,472,972,812,483,217,171,78,440,452,939,483,679,563,544,981,381,809,543,455,305,935,766,596,417,48,97,336,381,834,729,820,333,304,352,445,444,963,145,873,557,27,583,843,142,817,457,577,406,648,230,927,74,395,558,264,490,650,814,270,745,453,584,911,973,510,612,270,278,646,26,391,83,194,310,299,164,541,328,277,228,688,665,145,746,991,984,629,65,2,123,973,465,916,141,534,376,825,296,978,102,151,264,224,627,538,151,169,783,754,731,63,423,816,616,963,90,137,660,926,864,880,921,448,990,895,449,703,640,907,155,247,549,118,15,156,338,818,49,85,165,314,695,13,785,294,734,579,908,461,736,307,792,509,567,241,563,798,176,841,32,949,567,643,87,133,811,412,330,525,137,51,459,631,72,37,800,213,707,88,9,968,338,931,610,825,864,69,283,837,852,966,48,238,562,898,597,170,337,176,750,749,86,969,54,190,765,333,29,140,194,802,274,811,687,601,804,403,686,112,509,554,764,914,372,842,654,824,427,625,808,231,168,792,158,875,661,720,976,822,942,816,84,901,609,883,274,111,661,778,222,674,328,499,811,618,703,420,295,632,263,770,148,99,702,681,995,343,66,125,131,263,228,148,299,239,303,396,792,523,842,385,418,317,93,724,122,869,8,244,960,367,870,755,146,727,867,587,835,303,288,782,750,964,881,654,379,187,646,792,66,290,933,270,559,293,19,232,353,796,554,170,784,238,248,108,228,498,337,609,561,604,176,639,268,583,479,671,203,764,883,690,606,247,555,499,216,508,77,81,198,184,304,339,856,275,981,403,470,250,869,161,989,597,583,30,587,306,484,503,607,837,197,691,201,192,893,247,728,420,15,594,457,678,445,206,503,360,989,695,127,403,11,522,595,268,296,976,145,925,364,323,753,805,614,138,576,778,897,621,796,791,617,834,475,710,291,364,632,56,846,518,300,559,421,736,786,918,589,389,591,714,825,471,477,304,448,276,291,32,980,667,485,377,884,40,896,359,528,173,813,863,20,88,333,966,588,174,506,425,737,349,200,79,728,823,582,666,464,97,982,665,655,237,656,53,943,390,893,141,911,652,681,910,822,387,959,983,278,129,694,70,903,169,849,217,418,665,824,759,65,316,262,605,541,765,876,919,583,692,171,139,110,574,792,100,992,431,787,528,321,122,731,643,138,393,130,112,185,644,997,213,225,70,877,882,172,942,934,288,446,848,314,409,169,754,894,152,860,577,771,874,936,653,276,203,638,152,515,799,359,134,254,20,83,823,29,744,68,444,575,442,25,706,515,126,46,489,881,636,14,951,497,918,391,52,940,383,248,742,203,828,72,32,949,174,961,739,809,154,107,490,815,509,969,74,485,810,831,146,744,538,263,34,332,62,826,456,643,675,894,462,764,984,188,482,304,244,317,438,348,41,171,665,969,106,950,497,837,548,776,322,61,746,802,352,152,843,306,793,161,109,353,407,380,791,541,382,775,504,787,367,950,128,990,209,857,427,649,330,392,655,213,636,51,212,605,337,490,393,837,52,307,353,110,187,617,668,570,69,977,818,717,68,883,516,934,109,490,444,592,790,42,310,149,5,692,752,644,612,34,831,516,959,4,948,621,300,559,845,41,744,411,593,314,470,428,77,137,4,203,587,574,613,5,592,591,815,330,478,889,900,231,136,995,668,843,366,931,664,51,467,952,259,852,559,243,17,83", "356,149,459,135,253,84,858,694,412,669,523,878,131,423,96,900,167,284,960,671,387,452,213,8,0,135,511,388,733,119,454,770,527,977,384,286,345,139,774,3,896,861,342,433,219,528,849,703,763,327,234,107,613,928,57,591,91,323,727,210,537,641,54,493,515,412,568,605,121,540,805,771,506,967,376,534,779,19,8,495,936,27,229,799,819,946,537,504,789,534,434,818,323,600,182,193,719,736,367,835,176,517,84,236,831,126,565,864,898,985,975,186,91,450,315,995,974,872,463,308,855,342,277,978,960,916,283,517,545,291,856,770,160,811,270,899,145,116,410,246,271,696,231,914,436,140,805,679,173,582,29,752,740,130,624,667,115,69,303,349,284,384,126,456,103,371,936,329,666,348,667,346,848,341,194,702,168,29,316,395,869,855,391,87,92,690,874,361,395,182,810,423,345,389,604,306,727,668,367,900,215,240,561,30,661,119,906,202,830,862,140,681,790,155,263,22,715,792,177,732,551,995,604,640,771,232,766,649,596,519,26,948,255,430,80,960,514,462,88,753,597,557,985,61,60,184,783,787,861,768,820,732,91,471,868,790,220,395,550,580,625,11,229,740,251,439,745,200,514,197,993,280,880,859,749,532,433,763,844,410,978,814,686,329,611,663,5,57,794,946,351,13,704,290,732,718,496,906,200,850,739,759,294,16,357,37,544,56,88,44,165,120,204,315,881,333,577,663,840,574,941,564,626,76,40,338,251,501,410,200,510,348,923,437,939,335,672,379,563,764,857,880,333,905,985,62,971,214,530,717,558,764,955,940,735,337,205,157,218,594,254,264,501,781,168,893,866,40,89,218,624,239,8,802,824,688,329,157,250,762,789,919,304,919,373,326,845,422,864,699,946,743,841,422,109,454,953,397,48,791,507,766,85,402,262,535,412,31,684,982,673,78,211,747,396,835,216,882,734,419,699,384,210,673,584,803,205,110,506,419,679,253,635,378,995,983,831,986,674,68,130,311,437,172,266,117,569,848,29,912,235,107,968,266,17,420,108,286,410,995,510,260,59,912,629,209,943,654,154,52,351,411,660,642,739,892,10,390,819,950,899,374,841,140,303,867,625,776,350,165,393,431,915,840,351,424,951,739,504,522,364,977,108,337,92,80,819,639,455,413,218,132,13,178,815,739,375,222,36,247,612,77,461,459,911,4,487,793,994,900,677,503,399,296,255,806,411,991,371,578,768,436,444,457,592,427,446,462,991,666,920,509,57,595,823,487,308,453,201,176,27,962,981,265,223,598,249,949,436,759,498,687,749,51,626,564,236,400,802,577,910,762,318,115,786,401,410,538,951,734,53,439,61,532,667,623,651,635,385,680,128,34,806,148,243,714,788,634,274,265,983,358,716,920,922,286,982,699,593,978,655,245,919,338,270,997,186,719,170,593,500,701,155,846,177,883,559,525,60,706,852,120,330,999,576,938,56,459,822,817,165,798,116,718,51,735,168,712,903,668,910,621,184,692,714,624,66,746,648,409,108,285,472,470,730,368,195,679,15,295,95,820,90,68,112,246,731,598,769,969,979,807,346,820,886,630,358,905,463,948,586,816,523,122,876,235,68,23,784,900,479,592,690,240,512,335,84,222,70,847,333,932,359,508,786,982,463,380,168,1000,658,418,241,507,577,112,343,613,827,19,37,222,735,199,106,17,928,910,754,496,257,638,328,461,681,569,49,31,828,438,395,484,641,306,97,115,951,937,422,97,429,148,368,576,256,992,258,448,66,102,100,864,696,336,78,755,986,251,328,279,646,658,811,20,294,742,67,786,35,265,75,926,927,854,338,930,45,373,16,645,934,330,796,250,306,788,313,161,252,925,463,390,942,214,7,928,5,653,77,644,394,352,443,669,793,217,100,476,574,354,615,492,987,667,385,912,778,183,24,219,836,480,291,931,190,319,679,121,856,763,68,682,923,435,164,35,628,76,805,797,899,104,566,646,922,402,776,735,559,724,92,558,162,312,82,888,886,523,591,129,863,712,986,412,383,333,557,966,242,14,378,135,767,483,612,372,827,224,967,151,459,675,319,342,988,434,857,569,531,983,270,103,401,740,332,17,707,675,569,589,501,854,667,803,118,355,806,404,415,841,265,815,155,946,692,457,543,276,414,859,743,364,554,874,623,614,553,308,59,343,539,294,412,101,976,387,238,354,94,494,13,204,468,599,84,629,133,734,560,684,39,730,563,97,218,512,525,915,52,172,689,511,394,472,79,412,556,623,78,684", "444,440,857,708,211,27,223,407,279,73,742,424,720,717,762,967,93,596,830,992,318,95,93,930,135,0,392,530,608,328,271,341,90,140,472,212,167,781,718,147,197,993,337,764,233,377,70,102,425,306,970,951,945,636,924,752,167,867,901,265,581,739,891,25,734,46,598,521,348,95,142,667,357,879,30,609,946,53,263,766,314,539,625,877,111,59,637,929,336,844,653,503,732,866,832,657,829,413,245,973,781,739,187,50,40,589,140,390,967,787,800,551,817,906,388,381,582,245,543,981,2,372,612,111,950,837,566,659,23,679,344,654,850,491,870,237,203,850,107,327,586,731,452,550,810,451,167,72,907,497,670,26,554,396,308,720,307,199,654,721,418,409,826,962,787,729,702,906,600,679,643,976,756,804,197,361,504,450,758,133,998,168,881,753,17,798,608,441,296,783,735,702,991,787,460,720,392,433,678,824,238,91,982,872,56,832,729,903,445,113,486,578,287,474,338,133,933,400,619,809,694,670,818,30,184,136,955,632,996,141,434,292,69,542,565,883,925,46,207,663,611,381,394,875,119,517,327,416,460,766,296,287,571,461,265,655,752,716,377,244,938,404,47,952,460,338,771,787,815,733,453,111,895,484,523,582,692,390,219,526,830,227,893,881,246,236,167,68,566,194,687,866,439,767,373,513,85,303,665,58,885,796,209,188,54,839,363,554,585,238,769,424,271,195,687,854,255,490,906,524,669,865,231,988,607,930,36,384,247,965,283,422,542,124,88,406,255,926,407,586,87,906,390,971,359,313,318,155,102,517,98,238,888,284,628,212,860,206,461,598,320,147,383,90,516,660,2,934,640,238,315,187,586,603,642,511,85,794,58,958,520,936,712,345,763,234,345,798,194,447,194,323,920,932,988,26,122,923,856,128,908,793,394,593,536,591,182,682,562,769,886,953,798,464,492,840,344,838,450,499,475,874,874,231,285,874,90,359,560,382,907,266,918,93,70,854,406,70,277,635,294,313,363,313,846,943,782,4,9,250,699,235,357,954,275,797,5,933,542,117,687,790,854,895,686,482,794,835,999,120,18,160,274,855,119,84,519,800,573,207,481,68,789,927,670,741,803,47,279,216,493,222,238,140,447,447,995,200,253,188,964,296,598,924,849,303,846,943,845,701,542,670,765,545,716,807,434,707,247,326,772,49,679,785,893,685,261,373,960,156,325,215,958,101,385,530,164,236,696,178,634,12,466,918,606,280,887,148,189,416,142,418,748,619,638,907,911,366,288,658,528,939,243,450,766,23,793,838,862,322,454,516,90,960,743,797,841,407,370,468,9,176,160,568,809,752,471,968,735,158,368,695,703,570,420,957,512,854,819,167,894,215,527,374,337,283,539,52,133,715,821,661,384,187,914,386,484,738,995,869,166,604,662,483,416,198,971,719,311,972,166,428,115,931,431,339,55,839,933,191,378,693,673,67,25,618,81,673,297,243,678,272,330,958,617,289,912,775,550,526,187,915,106,983,604,768,750,633,136,389,887,301,689,586,705,317,729,656,611,845,454,294,12,393,562,117,90,258,392,96,114,403,222,3,428,621,353,150,496,940,59,730,576,45,981,546,332,110,471,998,623,187,487,296,26,683,280,474,983,125,455,566,966,371,502,835,19,706,454,835,588,201,324,586,504,173,426,579,620,481,969,526,65,958,14,582,145,282,343,744,570,299,529,989,449,709,245,807,665,279,830,450,319,46,428,840,695,710,496,445,129,343,749,926,31,484,676,432,961,205,547,314,171,109,189,766,969,851,952,492,373,843,163,493,370,341,461,210,862,332,941,613,200,409,973,902,51,541,100,147,307,10,494,651,825,399,93,124,450,417,165,866,108,190,189,808,394,23,399,883,87,883,189,432,74,703,634,512,156,799,1,1,131,725,697,738,984,166,24,520,562,21,535,878,40,86,554,255,233,932,478,758,448,21,152,665,734,509,499,963,373,626,801,74,688,836,185,803,185,884,788,88,17,710,111,92,518,172,798,28,474,983,458,207,890,541,252,319,710,151,140,522,601,241,74,426,295,371,474,674,130,691,29,180,156,875,778,247,771,358,569,742,638,112,511,979,819,569,869,719,344,531,783,752,430,843,360,89,852,475,223,907,521,133,77,229,548,279,961,680,612,221,782,715,904,7,620,850,639,244,136,448,186,747,885,560,414,906,228,667,510,228,197,563,650,833,672,333,763,548,872,400,699,948,917,61,814,222,49,558,944,67,664,857,71,722,894,213,9,438", "396,863,820,85,368,534,556,370,915,736,913,774,555,659,744,804,409,718,869,980,521,64,216,962,511,392,0,900,77,745,968,52,97,341,18,418,53,305,301,718,621,641,566,324,468,154,792,470,65,824,547,889,90,460,677,734,40,640,368,168,156,661,579,260,273,700,600,204,844,449,907,905,134,58,955,818,578,195,675,417,236,192,418,659,238,928,360,824,133,127,584,722,992,108,382,987,160,340,478,396,849,486,533,802,608,827,71,385,471,370,912,284,30,306,928,144,773,328,959,458,356,211,153,743,702,658,432,64,251,741,105,54,36,969,972,388,874,833,433,970,263,582,365,131,300,222,15,167,315,733,156,181,757,221,494,933,32,537,61,53,293,784,234,365,155,388,439,16,15,217,974,171,282,547,884,937,902,652,173,597,564,569,493,735,47,144,474,291,454,24,619,846,257,878,116,512,131,299,776,783,783,307,225,187,724,827,310,341,21,852,941,864,447,417,410,152,194,575,265,747,529,788,563,913,614,94,80,148,629,93,72,289,694,813,811,150,393,13,467,993,102,885,908,184,688,615,357,145,102,64,361,316,468,408,862,975,211,117,918,847,34,210,776,431,121,598,541,364,928,668,483,327,704,527,337,57,400,3,868,725,537,687,969,355,141,434,198,301,843,918,288,405,275,264,674,468,166,327,900,83,614,861,534,166,528,914,528,334,515,753,812,684,275,526,677,279,248,853,877,341,419,651,363,705,170,792,887,621,743,119,701,275,52,517,618,729,777,228,495,751,616,786,920,129,966,949,560,98,81,883,815,103,493,53,764,188,935,859,758,539,659,38,220,825,865,466,212,892,322,992,334,648,727,828,481,556,54,259,461,276,273,708,517,69,224,193,625,951,54,204,476,743,687,55,507,567,222,155,372,298,592,352,767,383,351,102,679,635,841,199,677,882,262,530,412,428,664,233,391,490,620,626,354,625,997,105,326,479,811,465,92,526,601,79,249,399,11,505,886,573,919,564,295,911,852,934,587,181,150,108,327,810,440,692,178,707,908,999,69,39,340,662,45,64,526,967,446,564,530,4,552,170,169,408,482,71,641,988,276,463,460,428,958,86,100,220,915,797,447,827,681,707,923,745,897,663,645,538,208,70,124,715,535,95,408,578,985,557,689,219,977,765,189,480,811,682,579,611,200,450,144,762,238,125,861,232,753,930,35,504,572,440,733,812,832,11,913,675,306,101,848,978,263,157,693,829,505,492,301,633,362,810,857,272,764,392,741,18,591,618,809,270,950,881,789,820,165,14,198,405,968,908,921,869,509,33,793,384,899,810,238,77,612,223,176,442,33,703,119,591,255,67,997,154,129,409,492,252,300,205,729,341,663,368,606,572,807,801,518,135,646,154,767,572,64,297,346,238,997,940,369,351,655,8,21,981,280,888,266,338,320,585,635,990,571,944,378,448,768,616,77,337,287,838,695,521,479,623,694,716,14,607,185,675,491,480,809,942,228,322,67,65,266,323,530,38,889,703,859,178,491,439,347,168,876,362,751,831,296,73,994,485,859,654,312,414,386,226,544,462,644,667,704,346,875,741,167,813,184,549,628,714,589,785,270,778,212,606,495,886,500,63,224,736,940,197,650,339,922,964,160,480,824,347,158,643,632,528,287,892,133,501,264,641,961,187,836,427,287,694,390,810,111,781,677,867,14,56,431,599,115,341,786,990,884,630,896,20,201,295,655,253,281,370,281,988,567,629,648,430,591,624,613,117,479,587,876,554,219,607,348,761,396,963,682,184,108,742,890,634,231,954,418,138,19,290,481,460,485,107,564,719,932,463,890,331,622,241,155,105,789,319,144,690,217,271,180,732,786,886,879,575,375,502,953,937,593,782,38,665,927,110,375,422,698,291,279,27,779,411,350,603,895,811,894,434,234,597,850,784,722,913,518,495,862,942,451,44,246,22,526,121,854,836,954,749,678,195,972,201,976,794,660,691,203,642,301,457,923,453,826,233,701,734,331,862,923,164,189,316,844,214,499,867,822,856,489,768,723,55,776,767,928,609,543,175,265,754,856,883,110,489,352,266,747,11,293,273,286,757,820,592,563,534,304,416,810,471,547,572,932,837,427,859,18,626,766,859,809,655,639,109,15,57,592,991,176,745,930,929,320,756,634,807,115,738,847,748,29,941,712,723,31,88,214,64,274,716,392,486,948,419,575,482,861,467,149,106,468,562,566,798,31,373,325,492,30,338,519,296,755,175,875,740,570,945,753,250,919,756", "95,46,971,803,206,980,268,771,63,131,352,63,110,520,354,163,442,189,969,200,261,826,408,128,388,530,900,0,492,882,490,660,480,216,925,575,165,974,995,391,559,338,861,311,617,37,53,659,525,153,516,88,746,365,255,772,67,175,677,690,544,857,607,617,767,644,882,454,293,696,937,892,183,611,575,839,23,150,472,123,987,735,918,18,369,51,589,281,357,637,359,294,996,953,117,664,39,792,786,627,720,259,522,994,337,159,302,746,35,642,305,488,191,534,177,709,7,718,443,21,734,858,543,945,661,111,486,209,496,426,686,140,549,197,736,551,308,368,133,666,48,113,317,917,496,11,736,489,173,399,499,643,448,62,673,496,205,352,949,209,555,154,958,761,314,477,278,213,435,600,339,173,84,322,623,22,708,240,570,381,892,397,127,687,584,674,259,204,785,203,529,807,618,869,230,337,705,647,484,289,555,867,940,676,333,552,727,17,424,79,377,13,374,75,873,358,152,631,587,875,691,446,764,388,396,712,211,23,187,582,774,730,916,623,721,784,787,705,880,493,544,768,619,755,299,299,833,76,906,372,596,289,59,627,265,909,552,131,62,540,978,697,958,102,875,71,377,344,237,672,953,551,983,122,382,77,573,473,626,768,462,32,419,639,417,809,203,647,945,716,292,634,646,628,631,97,774,556,581,204,742,479,448,944,514,288,385,399,787,179,611,258,481,368,756,381,364,425,546,885,894,869,959,473,499,683,729,884,902,523,494,482,241,552,410,42,645,10,736,7,921,939,248,141,909,754,830,708,795,862,698,602,616,514,528,624,480,988,433,250,540,804,185,223,884,42,294,104,983,979,69,32,907,237,890,613,203,25,463,166,48,860,297,714,799,871,621,451,937,556,761,381,206,338,939,912,675,659,989,312,106,979,125,399,541,887,802,77,322,601,550,81,474,310,345,120,156,917,37,238,933,108,485,351,985,113,804,109,599,901,844,540,883,807,934,193,515,741,515,2,624,781,138,883,355,373,63,426,759,41,484,671,616,187,969,408,160,790,356,29,650,525,52,529,7,196,461,174,612,561,1,415,182,129,876,583,697,194,610,346,764,14,935,692,867,513,710,726,610,520,78,530,684,515,761,378,859,19,856,589,143,306,733,419,348,39,635,824,383,234,450,382,684,309,622,671,68,859,39,41,348,971,251,57,109,956,127,985,560,773,651,444,748,881,704,951,940,30,765,88,588,720,310,242,896,607,367,894,887,569,440,333,239,825,794,211,569,774,986,818,262,832,466,910,144,655,415,601,118,119,470,559,500,161,967,259,34,141,594,903,379,529,277,407,604,198,594,561,129,455,809,887,939,705,998,915,839,794,280,819,927,343,172,191,881,68,578,850,966,399,302,194,815,534,968,956,607,134,557,383,979,105,522,814,551,699,979,252,737,42,395,798,587,554,71,529,797,761,684,66,520,996,302,87,762,501,892,149,11,2,200,266,868,568,497,407,387,95,954,625,620,340,151,704,671,724,237,463,600,503,627,851,258,496,856,143,625,414,749,504,320,229,335,234,1,850,518,286,730,803,2,40,458,457,638,78,670,404,461,242,881,20,345,199,777,834,284,863,420,531,163,985,197,414,58,850,897,837,462,893,713,120,516,454,284,721,715,137,119,448,193,349,544,162,501,501,511,827,837,350,347,427,400,230,451,678,279,716,821,879,908,773,30,268,855,754,596,701,557,713,952,932,386,11,682,919,178,535,102,827,908,988,138,203,267,766,994,547,699,702,266,424,206,263,785,316,782,335,834,521,898,442,371,437,163,509,638,858,895,463,55,813,913,645,887,860,897,275,370,990,775,824,239,775,726,979,914,890,822,883,616,135,524,613,241,370,519,876,662,192,123,841,483,165,478,945,711,146,16,372,508,878,427,758,932,537,627,331,246,575,262,496,471,201,503,824,756,350,958,540,146,422,175,775,634,789,969,944,847,261,358,806,629,666,96,982,270,63,939,758,515,653,840,520,440,999,584,768,26,34,767,601,623,570,995,8,888,211,775,147,437,691,633,49,407,716,49,387,220,855,789,258,821,148,684,797,444,629,63,776,894,255,445,887,51,819,129,476,890,540,732,357,526,670,463,42,624,137,727,269,646,300,945,168,122,28,826,477,523,11,800,448,181,764,871,178,758,49,901,233,96,213,878,306,2,537,899,393,861,533,572,504,923,713,393,113,420,767,832,181,5,833,995,657,845,565,615,398,787,288,659,179,626,723,142,972,722,844,469,264", "446,325,750,595,811,462,898,674,722,573,841,352,194,184,512,336,485,487,534,957,165,727,976,274,733,608,77,492,0,383,129,57,115,794,896,829,523,476,567,959,492,596,239,16,265,809,732,470,156,464,66,480,332,55,412,873,600,123,658,25,157,550,202,615,371,574,461,425,659,412,548,161,161,287,160,969,617,516,450,605,718,571,725,322,222,250,787,600,606,51,898,594,843,917,789,174,486,914,698,218,315,589,757,961,663,875,573,665,556,212,323,736,456,566,37,723,662,953,613,751,162,227,431,233,863,595,353,53,908,645,710,241,28,681,337,661,356,348,815,438,444,860,570,20,33,638,322,717,812,351,276,920,717,746,603,79,274,43,3,201,210,758,436,141,899,708,979,627,280,645,784,743,492,285,95,268,990,740,721,465,292,738,621,329,389,437,837,223,178,899,708,708,511,295,101,580,504,562,168,815,471,841,151,337,879,442,650,949,271,211,593,522,37,229,765,675,26,313,895,293,458,235,414,405,501,528,377,257,952,887,908,769,206,239,883,974,383,497,907,824,384,966,477,630,958,57,62,87,274,550,963,993,71,970,655,724,769,247,628,541,48,275,357,831,135,797,827,426,334,291,621,78,635,411,988,590,445,392,431,364,987,338,468,173,237,125,557,769,291,231,866,20,808,473,726,177,556,349,801,770,712,611,274,353,560,550,98,240,177,362,209,682,305,461,495,921,581,61,427,770,238,243,719,619,597,3,330,825,232,424,107,799,332,867,424,907,274,805,929,534,631,159,841,762,688,780,131,725,798,287,766,115,46,664,509,882,310,55,670,512,464,951,4,409,320,742,843,919,13,896,646,958,260,256,341,772,61,846,186,528,391,983,291,16,776,805,49,715,639,965,310,344,358,732,190,185,75,798,907,697,577,924,460,446,130,107,874,360,912,84,286,33,726,102,919,910,306,815,860,942,789,710,545,369,34,659,893,797,879,517,967,13,946,361,652,296,738,975,512,394,88,192,61,655,382,885,355,856,482,935,310,228,455,288,92,721,14,329,587,928,78,162,9,117,948,526,348,979,107,932,406,107,59,861,793,165,811,539,344,377,394,439,812,441,992,969,160,562,24,386,911,550,299,547,189,499,412,351,921,282,497,357,173,548,815,778,657,720,956,57,526,264,925,647,612,882,470,248,628,239,133,729,281,530,143,388,433,628,768,294,724,213,945,145,885,239,150,305,315,932,644,726,97,671,381,431,354,17,278,940,498,460,56,919,455,491,1000,744,32,349,529,121,238,690,184,611,386,817,209,114,104,750,810,599,631,394,774,44,240,351,380,493,806,897,197,708,325,597,474,279,924,319,871,57,773,296,888,438,760,860,264,889,384,675,286,282,783,781,33,237,827,125,660,28,539,843,415,282,834,826,660,621,577,39,283,439,380,511,756,856,374,616,368,496,888,884,584,80,610,221,899,604,25,416,476,775,613,505,133,40,758,363,632,109,2,292,431,754,994,885,65,794,328,787,960,780,892,834,209,677,431,359,374,694,352,559,9,246,780,33,119,444,710,610,28,366,156,391,251,259,18,901,114,83,85,383,960,90,577,910,441,575,255,901,991,254,247,577,97,563,76,854,554,976,863,769,157,954,104,553,485,842,334,808,371,726,625,465,30,674,538,774,872,391,950,53,127,407,734,258,913,817,117,969,761,935,685,398,111,566,172,873,591,407,814,980,469,239,10,635,339,245,892,900,654,313,910,602,511,483,326,778,487,623,448,160,229,898,343,94,474,734,916,155,372,978,840,684,257,295,141,964,712,26,872,851,829,553,363,572,801,972,203,124,247,993,781,536,759,538,994,249,653,353,485,575,367,268,620,777,647,851,802,378,970,830,753,731,622,228,321,579,761,637,854,928,627,722,270,784,693,50,607,34,757,899,232,415,784,796,299,80,193,627,478,402,982,990,95,308,149,461,576,434,609,146,687,2,308,209,958,440,61,808,141,687,385,290,735,564,629,840,852,698,981,739,230,195,953,456,81,637,275,714,951,67,764,445,783,143,972,428,120,599,789,271,626,253,170,551,699,608,152,430,693,509,188,319,198,847,536,337,575,803,375,944,722,101,228,161,746,235,123,652,971,857,247,971,947,742,142,598,248,958,679,254,77,723,999,176,589,429,523,748,398,618,914,814,749,114,539,955,564,511,994,59,859,441,546,549,342,401,475,836,151,182,360,999,676,750,297,154,374,558,206,425,315,817,474,999,375,765,354,615,824,510,200,475,860,851", "86,418,652,15,700,713,611,426,811,120,518,484,684,281,654,640,233,11,5,281,483,77,798,555,119,328,745,882,383,0,806,714,266,69,179,807,425,846,564,334,148,810,112,360,273,168,723,779,511,273,761,417,813,184,955,183,592,912,48,14,777,968,274,799,314,56,563,488,650,887,162,697,487,726,431,332,510,412,92,215,347,858,459,169,208,899,615,522,322,9,663,351,174,547,524,774,66,935,563,511,532,816,238,297,570,455,180,596,541,629,180,169,986,749,471,423,564,10,117,149,858,617,681,82,534,286,183,396,404,986,517,112,147,874,64,542,323,661,149,88,520,814,621,134,855,29,429,127,938,920,758,980,985,236,44,748,730,783,915,654,30,800,768,27,407,184,641,90,637,653,291,579,372,187,731,514,201,526,254,418,458,601,31,30,194,582,539,345,759,95,563,765,416,849,512,864,221,351,194,91,375,228,424,983,388,807,279,521,318,697,625,710,937,959,58,686,387,750,582,532,433,342,269,592,612,84,80,683,745,654,253,855,427,841,527,573,818,1,122,276,141,377,225,911,804,568,952,355,844,937,441,678,129,128,813,688,697,438,601,187,154,819,718,366,604,189,44,912,956,30,661,152,346,431,420,275,670,708,977,86,375,749,344,544,452,75,394,977,705,329,881,856,495,955,744,462,172,34,12,296,139,189,92,336,531,951,485,362,436,356,513,420,285,890,268,947,852,555,176,593,793,777,636,815,936,427,309,218,149,695,874,585,731,441,458,924,606,592,763,653,504,318,313,438,859,956,904,258,917,192,118,809,524,157,912,268,627,79,49,449,840,727,781,514,349,25,282,764,971,740,351,307,315,782,236,742,138,362,516,306,588,40,996,835,153,746,713,705,855,624,34,877,251,350,261,816,486,686,657,940,466,222,255,419,823,944,226,74,916,916,343,118,692,965,501,533,737,32,156,671,220,666,551,984,613,308,306,308,873,274,321,532,919,266,311,596,171,68,757,949,483,22,446,251,860,519,992,431,249,153,479,16,948,542,301,326,166,685,132,858,635,789,789,112,884,340,637,958,394,433,184,443,901,821,699,174,596,648,487,977,845,781,865,32,343,177,823,115,461,780,548,268,83,458,468,349,591,705,689,713,603,37,764,913,18,698,282,10,557,932,44,763,326,892,557,42,863,136,680,592,292,232,65,788,146,283,331,512,291,640,613,593,845,729,272,870,953,298,223,351,493,762,841,306,925,16,753,271,323,13,435,622,392,477,835,367,20,293,912,857,761,294,302,35,706,520,574,896,259,367,527,423,781,387,233,260,727,224,255,422,655,126,666,465,617,554,420,53,670,178,210,186,597,186,983,772,474,690,583,802,290,49,558,232,260,962,195,615,885,799,575,582,190,581,556,703,52,758,967,416,386,742,801,307,936,49,33,20,842,935,570,14,420,572,254,307,99,730,561,220,204,814,793,234,293,377,643,148,207,415,471,398,400,963,484,288,4,295,477,330,160,403,776,537,813,569,762,77,985,586,341,884,371,381,300,351,510,902,829,183,374,364,527,80,503,938,970,149,977,453,576,432,414,756,543,424,217,275,460,280,122,227,140,64,691,835,478,117,943,286,600,458,491,904,843,480,893,922,44,55,516,356,307,463,196,364,36,291,965,457,22,479,248,229,742,79,351,396,522,335,716,509,712,648,912,428,601,710,210,531,2,992,289,246,230,759,98,438,59,113,778,760,622,298,308,996,302,17,899,541,618,43,675,83,191,949,946,365,756,599,479,931,682,667,366,644,543,858,362,487,569,935,620,692,486,703,322,566,458,470,938,748,35,25,874,654,983,489,168,602,462,732,656,401,204,93,466,14,59,339,542,108,439,839,525,775,737,366,40,827,629,435,257,140,176,426,224,378,330,440,760,931,75,584,806,382,769,534,155,38,185,49,970,13,683,918,328,343,891,219,92,822,179,553,554,431,249,405,888,284,490,901,388,963,838,655,618,439,282,95,206,749,276,761,876,92,32,604,543,498,63,887,907,415,534,587,896,714,884,837,215,975,848,159,298,662,273,314,909,767,885,314,347,442,72,959,793,316,160,735,735,302,838,618,43,619,562,961,578,225,948,743,235,874,4,952,463,240,532,577,128,276,66,328,68,351,768,810,970,917,157,670,385,290,920,446,614,928,532,80,789,604,952,584,94,449,683,470,582,84,81,603,62,940,967,256,36,965,204,487,667,842,431,552,601,768,332,27,563,642,996,198,319,425,99,541,396,347,216,423", "397,304,904,973,708,488,385,505,624,403,392,122,590,506,425,427,729,264,142,761,239,988,427,24,454,271,968,490,129,806,0,500,19,949,953,345,971,962,839,732,325,290,11,445,78,904,992,30,398,35,59,817,89,224,157,955,876,736,232,567,492,30,241,888,678,871,753,546,449,666,408,803,937,332,314,213,694,594,295,294,765,436,143,496,495,683,463,49,574,516,610,266,751,672,385,367,781,267,425,123,737,548,957,24,705,750,685,267,550,933,173,285,953,269,406,218,625,702,726,258,854,738,383,193,523,879,350,895,550,279,448,194,89,391,527,118,51,644,296,715,523,535,731,861,878,356,171,899,782,944,520,879,739,626,23,656,643,121,318,457,92,152,794,422,424,712,858,906,65,813,283,773,790,542,531,670,555,125,76,297,277,112,630,676,411,281,869,973,548,108,549,226,185,560,344,760,491,433,776,630,574,287,447,674,903,381,747,187,811,185,985,302,70,765,261,838,133,993,275,286,461,694,562,430,632,848,334,163,262,156,146,764,631,153,146,554,860,110,128,941,660,109,676,609,187,217,796,455,115,707,514,199,383,769,488,440,440,5,680,79,338,161,809,153,940,125,290,841,505,220,913,299,349,416,545,5,3,494,628,469,948,741,860,170,126,792,383,897,27,497,152,572,86,36,631,342,905,536,217,474,603,597,371,777,399,997,70,813,869,680,408,454,58,481,810,735,377,813,644,760,275,212,943,673,167,417,936,424,391,169,502,230,727,813,745,855,109,563,711,33,555,651,599,866,879,586,61,269,926,260,468,713,845,394,651,806,552,948,899,307,698,718,595,312,807,849,124,860,788,911,742,703,828,607,200,870,662,955,93,194,559,271,332,303,320,323,813,550,234,961,331,56,594,260,658,232,856,806,898,31,394,445,462,491,705,113,857,518,862,349,328,550,841,860,618,330,998,414,400,939,353,994,123,992,983,906,631,971,188,875,34,717,77,693,559,790,725,225,499,34,400,662,845,734,752,537,269,534,749,690,798,523,877,712,568,635,197,789,294,809,710,752,404,784,461,443,894,53,696,550,835,310,291,704,560,895,36,98,569,542,92,399,986,379,596,586,114,946,758,613,303,879,753,437,631,702,779,788,712,537,997,917,716,684,159,748,176,151,496,90,700,437,723,272,943,188,670,239,294,195,410,105,784,402,149,737,29,904,593,240,679,428,335,862,126,921,511,293,556,191,526,215,769,255,421,337,521,368,526,496,81,747,457,488,912,557,597,277,234,600,390,994,438,872,960,168,349,230,946,945,874,999,22,914,194,503,808,755,761,543,384,530,247,225,685,674,321,593,175,481,556,451,955,570,264,747,98,470,56,829,957,678,76,648,627,82,654,721,171,46,133,702,955,816,294,734,952,584,106,564,221,915,760,635,35,148,672,95,851,807,579,833,648,14,541,58,665,80,636,613,115,517,48,146,524,794,185,695,220,391,157,808,322,717,734,701,893,740,834,906,48,619,56,279,556,161,426,81,90,909,816,802,29,514,883,476,391,233,329,597,3,721,279,397,262,438,181,218,914,4,275,123,384,950,97,762,198,98,557,284,927,205,87,432,981,924,137,14,33,623,844,471,271,482,749,701,464,225,859,538,750,417,963,459,643,104,183,459,563,397,452,800,574,16,647,611,125,759,656,204,433,823,183,237,143,530,799,241,584,952,591,989,148,955,36,259,831,896,981,436,858,117,941,209,31,904,388,782,982,365,254,394,936,381,581,179,105,101,270,582,995,180,44,249,439,833,307,495,434,812,253,868,546,429,965,613,399,411,240,646,850,586,173,503,686,150,443,83,749,424,905,532,507,174,679,699,592,630,255,722,397,200,343,968,553,751,558,859,495,848,607,402,700,615,126,825,336,422,486,708,838,43,66,287,84,766,138,840,339,184,638,366,885,705,599,782,950,618,666,542,873,437,215,450,566,87,155,710,676,644,820,535,678,43,583,786,337,94,32,148,777,958,409,157,412,138,668,773,812,522,98,732,265,902,937,204,777,21,874,829,171,609,331,828,325,635,567,611,988,661,453,93,708,603,629,904,964,759,278,252,832,809,776,632,860,822,995,173,817,952,519,352,764,852,516,481,691,429,471,684,968,767,384,207,286,208,950,537,133,371,573,704,585,146,745,949,959,598,345,702,747,32,955,55,544,25,422,102,287,842,554,108,807,905,163,706,804,144,76,463,641,642,591,980,922,764,875,968,154,768,925,205,156,984,474,227,499,518,946,653", "893,904,223,375,271,755,74,434,517,566,982,756,158,575,493,233,548,597,574,131,417,67,620,852,770,341,52,660,57,714,500,0,126,276,671,125,556,179,628,311,665,594,340,115,195,834,240,860,740,164,145,473,502,670,332,922,645,981,296,286,786,838,389,175,673,803,246,587,725,687,82,935,486,615,778,216,402,237,530,570,759,474,338,513,217,949,914,682,736,813,467,541,248,29,14,794,895,66,34,549,523,545,32,3,669,157,824,271,192,210,283,324,375,724,339,96,833,252,15,311,587,663,328,258,236,328,991,407,19,514,730,871,415,631,167,986,812,450,235,902,804,563,620,192,481,528,470,403,605,897,850,649,213,694,683,350,630,385,311,220,486,31,477,535,398,285,688,98,407,710,949,305,879,395,559,648,780,797,323,524,261,853,233,312,896,960,693,450,144,74,739,614,318,663,82,781,452,648,304,701,798,610,89,347,821,538,182,102,544,857,634,983,967,53,108,983,512,284,795,128,880,443,334,37,172,197,561,663,26,196,911,121,768,930,856,379,87,866,831,517,489,332,301,291,340,474,355,541,59,974,164,991,851,599,230,285,992,158,858,32,248,793,91,559,294,126,893,791,74,972,379,812,328,682,815,995,484,538,292,334,681,381,938,460,728,373,547,395,134,300,560,997,110,932,611,464,675,117,396,171,176,320,52,40,854,144,792,410,122,247,91,289,824,921,579,532,971,379,729,941,48,115,548,905,568,768,651,582,808,505,641,205,399,607,439,138,354,836,276,6,914,995,468,721,97,884,853,603,295,519,958,344,625,252,297,619,412,211,532,287,829,847,452,612,50,729,683,995,875,365,882,886,919,93,23,141,94,345,428,741,530,619,490,12,545,165,42,174,67,232,249,203,33,936,489,596,139,435,677,83,612,186,188,450,533,194,711,371,341,715,927,767,217,566,750,46,632,113,729,983,283,559,192,28,674,955,315,285,919,980,398,518,159,894,358,595,539,967,828,329,980,831,117,945,789,194,17,71,346,433,920,377,243,644,26,38,538,546,601,682,986,643,700,396,510,524,601,48,269,598,445,496,37,279,210,15,446,698,133,4,745,457,31,462,146,459,425,962,251,452,910,986,451,919,429,387,151,655,323,106,833,276,145,251,950,884,156,25,798,302,432,640,914,458,172,671,459,682,767,144,217,440,397,185,581,733,15,204,253,552,543,773,718,918,713,122,936,35,406,931,614,884,774,195,94,854,607,840,22,834,396,917,315,536,371,943,43,496,967,71,971,101,271,55,126,426,82,616,61,263,498,640,987,630,145,162,811,472,101,365,688,931,91,195,442,994,219,319,202,524,141,161,45,862,162,977,999,941,153,420,203,192,820,505,792,698,548,17,616,647,477,696,168,709,949,679,681,948,248,585,895,238,743,590,822,394,644,154,348,454,173,635,992,876,91,676,951,880,617,399,763,653,848,460,527,641,529,585,963,347,474,747,577,501,376,70,787,383,675,874,131,402,865,480,919,258,951,136,729,557,550,127,415,282,501,526,907,466,108,897,731,206,148,448,849,507,26,656,219,115,673,119,814,693,726,290,653,419,58,823,593,241,36,293,724,690,77,438,283,353,746,70,485,625,825,241,968,123,962,854,146,80,200,55,978,830,794,143,402,518,451,96,689,541,834,978,520,223,554,858,632,484,794,152,392,80,389,578,397,119,397,490,514,535,556,569,826,208,741,276,790,291,78,793,606,72,445,200,158,997,623,249,992,491,967,223,994,909,303,833,868,381,336,230,186,289,918,304,288,847,444,7,264,228,397,309,473,394,911,780,468,887,787,286,658,537,881,956,980,380,845,988,406,494,170,556,479,482,437,773,252,901,490,890,415,697,760,652,101,219,108,773,705,283,946,813,974,631,995,901,267,734,44,173,962,479,398,967,669,543,115,871,114,434,357,797,28,549,258,558,223,139,155,787,641,820,594,429,678,97,272,861,648,264,829,845,696,837,715,58,981,607,807,4,812,622,355,856,651,512,659,291,766,450,474,745,994,638,853,829,803,482,86,523,26,856,8,819,995,463,305,510,625,111,306,331,75,851,143,346,704,640,129,968,489,998,757,573,673,339,137,110,667,939,115,653,248,2,666,78,787,541,236,364,85,793,266,182,156,738,581,445,523,969,587,647,493,346,214,793,675,447,782,431,105,351,363,571,456,832,496,509,736,440,982,292,960,319,444,772,16,922,851,405,502,940,149,252,529,402,960,323,739,542,466,972,390,668,38,22", "56,295,132,674,620,518,864,727,195,346,264,55,346,658,763,478,200,427,324,916,828,57,229,567,527,90,97,480,115,266,19,126,0,897,271,659,573,383,611,885,405,848,699,379,648,93,218,473,398,771,379,679,342,853,453,121,443,371,767,882,808,573,42,862,473,453,891,955,227,958,102,81,139,887,666,6,782,837,780,548,663,337,610,557,69,129,488,336,920,66,463,93,195,681,866,349,259,754,100,334,815,969,537,934,528,28,721,574,947,459,657,232,663,672,221,44,226,805,953,195,672,191,493,975,262,485,958,683,395,507,85,477,188,455,579,602,732,388,620,822,788,93,593,277,721,878,758,237,217,361,815,825,378,109,243,874,804,190,232,467,561,715,234,339,185,150,739,861,406,895,234,275,341,559,265,618,189,70,857,294,457,427,921,629,460,704,621,794,186,78,331,572,794,123,941,728,555,335,474,234,409,339,81,620,450,674,217,751,90,609,888,437,440,994,817,971,261,676,25,251,985,956,366,830,679,913,478,410,878,313,532,132,142,96,359,410,593,747,716,268,932,303,727,851,891,422,139,674,911,312,502,898,551,629,994,328,708,347,324,160,462,870,910,491,994,372,999,286,529,234,26,32,47,483,958,302,12,580,956,370,809,329,835,167,227,396,419,999,552,202,474,260,975,809,852,540,737,561,573,989,23,506,676,237,246,23,62,104,774,893,180,808,96,395,261,602,508,643,909,185,854,944,532,121,406,922,77,571,113,530,624,868,520,285,478,980,276,447,439,918,247,131,690,564,334,511,416,825,150,551,554,205,891,258,140,545,402,334,556,171,330,222,781,926,112,473,547,816,166,341,746,495,168,403,816,395,441,411,122,71,955,796,490,912,744,391,248,535,864,612,358,178,613,651,646,435,479,798,597,6,638,941,559,775,933,469,391,388,950,924,763,283,930,39,847,898,416,37,802,971,346,896,662,68,425,714,855,698,946,564,763,435,102,386,94,475,586,20,660,310,985,637,470,124,127,534,111,140,94,763,234,412,319,61,622,516,212,393,663,305,113,168,797,420,358,764,23,404,17,872,874,459,499,624,718,238,994,353,194,454,142,6,716,114,710,947,6,215,791,151,428,919,539,207,910,184,366,818,445,123,640,486,369,684,601,394,636,807,633,189,813,588,842,580,332,117,169,773,477,244,476,961,866,768,510,121,701,218,405,686,573,583,657,485,886,271,884,669,423,756,749,38,900,163,268,741,795,236,772,489,536,216,596,810,941,945,122,662,55,800,918,179,611,854,791,102,504,718,392,651,838,406,764,28,204,364,614,430,904,895,795,753,956,643,393,904,795,544,836,163,892,240,870,803,533,528,811,122,635,617,274,742,306,242,319,474,404,746,381,853,964,223,154,474,480,411,356,544,562,899,117,354,626,4,898,109,943,940,707,610,780,89,110,14,953,126,136,940,3,181,536,654,42,784,753,583,438,48,512,186,455,980,972,756,737,513,8,331,137,866,979,449,273,817,509,219,174,844,76,974,566,636,22,345,828,577,731,164,602,632,597,654,128,820,185,737,273,726,213,286,138,571,125,195,459,171,27,193,6,603,179,198,360,909,631,478,646,604,826,747,932,156,728,289,743,838,193,758,80,359,967,283,699,962,664,684,782,598,671,878,777,524,15,207,323,137,127,722,63,532,139,989,34,862,489,777,855,737,494,895,63,833,438,985,321,307,491,1000,369,419,280,522,496,930,923,144,496,365,130,878,812,261,709,687,766,3,777,711,382,671,344,845,529,443,211,249,699,772,577,656,417,192,514,633,244,641,121,434,429,144,357,441,273,723,201,817,535,913,910,801,296,166,188,178,237,722,895,15,954,397,24,932,191,254,391,804,905,75,194,356,594,220,600,153,194,892,540,445,220,428,159,781,930,895,176,167,189,700,670,941,488,14,760,793,628,186,736,124,356,80,109,312,978,105,623,314,596,936,856,427,896,627,125,813,585,60,133,702,921,621,532,212,849,945,631,758,263,895,989,513,203,840,726,72,272,226,539,268,557,256,870,340,461,947,165,49,298,731,970,533,253,680,816,224,690,659,596,217,874,58,410,930,272,59,142,909,247,527,78,151,766,337,805,748,708,154,408,991,996,298,908,514,973,994,107,989,630,537,958,437,409,854,564,992,421,90,945,116,585,798,514,854,774,256,151,402,104,400,677,434,884,181,35,623,708,392,797,981,671,944,571,703,630,802,539,529,313,635,315,969,182,143,404,646,542,102,929,488,507,979", "812,948,909,439,26,552,503,207,57,932,47,875,780,880,12,804,876,921,240,499,995,877,638,553,977,140,341,216,794,69,949,276,897,0,406,545,822,554,704,814,512,285,329,674,956,121,655,534,857,147,130,932,814,413,613,609,533,574,517,993,519,46,217,328,427,435,133,32,973,925,796,521,262,915,817,572,427,768,632,986,9,979,986,351,4,264,190,12,482,571,183,857,739,527,56,326,970,857,851,762,200,813,694,950,52,199,140,882,539,825,457,959,687,168,838,505,78,651,860,995,598,567,167,307,42,810,306,720,862,97,952,543,915,349,328,260,888,448,75,824,971,592,958,582,430,383,770,18,751,115,540,947,373,96,307,40,324,99,655,68,883,489,571,954,172,58,523,476,507,247,765,617,360,750,390,580,999,220,503,944,673,521,927,883,108,658,895,336,935,994,680,386,325,247,744,880,404,736,279,931,757,677,95,139,758,125,471,719,153,411,955,886,476,712,687,240,348,753,664,919,163,903,775,804,697,603,107,962,218,140,59,109,473,528,990,515,108,188,410,911,601,722,542,256,423,259,140,355,918,41,463,354,283,634,215,675,934,700,572,571,374,382,15,29,615,839,873,873,451,515,515,747,394,334,660,601,775,21,33,691,437,111,989,314,447,361,126,660,930,782,98,341,209,266,911,589,670,163,146,714,786,541,674,607,478,411,889,774,414,81,225,473,947,316,587,191,139,512,728,112,608,201,205,716,371,448,893,117,704,411,212,199,337,741,942,10,63,613,229,445,164,317,653,137,952,697,641,955,221,760,90,678,421,426,471,996,570,502,912,16,899,404,663,509,589,684,600,975,62,465,780,881,407,864,162,8,680,639,350,961,597,694,421,100,196,561,36,928,462,345,929,670,627,787,918,246,765,792,497,951,110,712,312,276,593,616,264,7,105,844,959,106,258,184,763,869,341,793,262,912,869,817,816,801,443,909,601,538,462,42,192,64,288,941,736,266,124,523,187,905,237,254,207,278,134,83,776,666,238,476,108,940,181,651,858,330,418,882,256,491,466,401,183,178,897,885,803,772,334,154,355,42,231,463,912,600,439,411,150,565,153,76,796,807,287,65,722,403,420,204,795,296,447,948,562,238,121,461,40,726,368,828,944,256,604,438,552,296,302,690,570,927,586,202,28,798,346,962,602,177,814,935,621,123,735,108,333,269,602,887,586,4,130,454,403,260,980,7,102,398,218,323,826,295,341,980,541,378,905,532,535,877,839,849,1000,677,920,946,491,34,73,680,618,78,936,480,436,932,323,306,117,771,400,187,485,762,900,182,335,468,811,991,825,438,554,298,770,878,347,230,28,77,182,54,871,676,647,50,762,312,233,777,858,434,337,34,635,577,545,469,949,357,401,215,850,881,942,937,865,315,861,456,816,577,934,703,220,63,955,91,610,751,355,109,203,272,73,466,395,572,701,829,823,127,524,892,536,484,235,460,708,991,69,633,71,983,657,685,973,116,802,539,127,943,577,53,21,738,327,352,703,250,261,93,538,48,304,6,929,462,462,354,741,621,481,902,942,941,177,36,972,727,575,893,970,326,459,734,215,936,510,724,233,307,885,698,85,577,40,543,594,779,369,671,446,254,222,665,137,608,388,923,958,280,608,763,336,376,415,982,218,381,400,146,410,727,359,218,920,378,716,527,566,387,218,935,315,253,741,378,411,765,862,474,606,340,256,907,767,644,760,238,278,68,388,156,383,529,114,439,561,673,342,211,989,540,985,379,248,3,824,731,685,407,187,622,425,269,774,379,364,937,820,770,330,312,991,895,391,716,736,661,710,45,229,625,459,301,533,612,695,962,34,566,205,44,402,828,502,165,20,996,57,89,404,492,694,136,369,827,740,119,646,155,543,817,557,699,512,542,190,666,878,988,138,135,727,734,68,370,2,720,492,456,38,432,848,244,457,796,877,67,78,854,645,926,370,177,339,752,286,593,61,55,90,787,739,313,411,502,434,129,499,719,655,830,29,183,599,297,903,537,579,531,393,112,177,257,503,710,435,24,394,935,321,742,978,880,663,33,257,873,42,293,337,377,708,49,706,691,143,228,979,972,809,818,657,471,780,137,805,418,987,365,193,755,136,24,624,686,866,302,947,395,93,897,84,676,324,519,375,137,58,94,996,785,880,99,923,489,468,802,711,836,571,762,760,593,534,681,187,190,842,686,941,191,51,679,751,157,260,232,952,60,612,590,607,646,92,752,103,914,842,553,30,317,756,635,69,697", "967,626,607,832,885,134,490,989,654,878,325,305,667,711,396,284,622,151,649,866,62,89,875,386,384,472,18,925,896,179,953,671,271,406,0,352,114,710,187,521,922,379,983,956,176,705,159,602,29,494,890,905,937,977,346,35,73,12,633,805,541,909,534,304,818,730,355,644,826,153,261,98,855,894,863,419,717,379,257,814,582,557,870,364,557,881,950,382,499,578,939,193,433,187,997,673,217,108,396,427,46,8,926,627,366,462,601,621,455,269,878,474,183,315,709,942,767,277,967,502,698,262,332,135,385,23,718,503,671,562,45,712,745,470,95,706,550,386,798,286,634,580,584,596,589,421,815,548,727,276,442,868,760,993,937,296,929,126,256,275,847,6,247,85,180,320,545,200,90,84,161,275,425,553,718,317,700,461,339,554,759,15,972,424,693,571,53,362,988,98,130,926,766,817,865,148,418,993,309,190,382,445,750,295,760,32,915,148,367,862,658,824,364,235,446,384,118,813,456,993,347,536,61,685,558,930,793,500,269,715,327,10,649,618,597,410,785,703,433,832,943,281,518,129,707,744,391,927,489,711,761,698,98,798,263,843,124,800,41,973,341,396,189,146,460,324,176,707,985,410,358,385,237,141,939,658,145,803,781,811,495,613,837,713,981,4,987,645,121,584,164,261,356,423,247,643,234,150,519,627,800,612,998,124,505,640,974,360,675,998,396,516,118,918,546,511,493,64,917,442,979,240,860,632,620,52,827,569,388,514,238,678,977,989,499,574,336,78,199,673,325,728,466,684,48,929,662,425,96,953,768,50,600,806,449,974,935,895,105,568,894,613,653,396,334,226,308,364,240,107,331,696,44,561,153,757,905,382,908,983,488,808,496,215,446,204,532,127,642,182,721,834,31,300,590,974,107,297,976,478,346,809,368,320,29,921,721,470,810,240,944,232,517,351,754,450,900,519,407,847,610,755,710,559,502,796,846,708,589,582,225,864,681,624,8,177,770,924,524,52,190,303,787,78,93,119,559,730,577,305,271,3,842,960,873,171,618,981,177,344,361,963,800,255,569,360,467,194,798,769,957,986,759,257,31,595,52,145,289,391,795,891,686,365,206,223,921,540,689,87,933,764,262,436,585,30,37,711,347,442,608,80,3,919,35,161,375,253,510,732,489,298,120,885,481,831,283,78,575,290,47,287,829,332,559,637,308,413,585,567,324,943,239,976,121,263,217,283,269,471,654,658,559,393,600,558,466,825,413,150,355,575,33,599,909,440,753,400,468,759,824,491,926,499,831,942,994,702,441,811,71,596,95,586,173,47,945,996,901,560,496,682,853,622,672,660,928,841,77,407,878,751,696,236,423,927,398,710,28,540,812,589,532,540,914,260,21,177,99,811,630,229,83,624,684,661,912,429,830,552,875,947,272,329,571,169,894,386,921,16,469,187,321,922,161,335,358,306,209,499,285,55,602,298,499,188,831,457,598,440,62,621,857,915,536,989,868,506,323,875,484,175,297,409,364,10,764,953,888,32,502,334,990,382,293,144,243,411,840,953,176,73,13,74,31,911,893,521,828,306,648,37,722,471,496,323,797,447,149,846,83,586,643,476,978,213,744,342,435,596,643,789,82,196,167,882,900,840,106,334,354,273,37,382,632,365,365,70,627,865,949,567,325,433,848,737,276,284,809,674,690,392,519,654,697,978,96,725,232,551,387,221,331,559,466,249,280,759,843,142,504,265,397,671,319,925,688,141,94,829,49,630,657,953,417,788,630,446,319,555,31,517,717,894,734,757,705,835,858,604,264,694,77,218,303,857,80,878,14,728,922,881,149,455,772,762,324,819,845,435,483,302,754,82,989,574,1,811,933,326,310,742,995,141,418,688,623,187,786,496,470,629,150,582,345,915,708,43,690,871,707,462,521,490,474,749,743,603,264,834,555,480,586,412,44,269,461,912,293,545,982,986,328,484,182,112,546,495,377,661,496,173,667,486,447,117,997,841,753,276,943,82,714,596,436,344,718,609,336,535,915,694,278,504,685,818,719,476,769,513,854,331,41,401,98,707,844,215,909,639,839,883,876,1000,263,137,436,112,827,798,48,304,333,103,997,263,508,134,309,853,134,569,656,70,570,584,42,910,458,253,607,201,48,332,204,342,417,958,583,40,630,417,786,221,798,286,899,553,8,695,854,554,829,41,764,287,353,725,674,751,844,234,669,671,763,100,443,843,556,66,639,242,640,844,382,898,284,968,873,260,105,699,899,381,407,947,739,102,937,938", "40,722,679,866,289,652,891,692,14,9,816,105,911,541,149,994,439,214,478,525,168,355,168,709,286,212,418,575,829,807,345,125,659,545,352,0,310,336,656,507,41,260,375,99,406,593,307,816,240,12,690,244,765,408,961,959,699,532,274,333,241,510,709,631,550,340,107,628,666,492,999,435,386,337,618,992,376,845,652,713,979,824,679,210,388,107,151,436,977,379,701,759,568,457,440,516,479,236,520,525,221,683,254,436,348,60,833,140,116,243,943,938,773,370,564,869,318,236,340,946,633,363,712,745,39,94,701,698,464,121,611,694,872,815,948,577,110,168,382,121,790,590,779,492,871,51,506,48,218,753,295,134,349,94,682,100,707,856,993,481,498,351,245,383,326,46,522,660,303,37,222,413,70,667,818,330,349,643,400,967,963,289,201,245,748,22,177,191,699,726,296,313,526,674,299,123,133,183,321,573,301,709,258,469,762,976,309,719,195,828,762,327,783,926,230,220,474,528,833,292,546,877,742,305,86,445,870,917,75,430,796,204,165,767,745,839,513,495,204,801,823,969,666,255,978,347,578,644,951,918,584,75,702,125,561,408,916,843,515,923,773,262,683,873,162,14,29,340,835,709,59,364,850,643,463,66,584,612,37,496,687,319,736,337,87,656,262,376,186,64,708,836,877,501,101,36,980,733,606,332,140,457,484,998,182,716,479,279,719,751,548,869,911,886,72,497,764,572,907,124,971,598,352,309,1,638,190,449,534,81,9,506,810,628,304,816,563,957,424,408,691,302,990,253,950,167,122,302,487,797,307,634,310,558,64,621,113,664,804,348,518,842,327,119,226,971,623,173,11,423,61,428,402,15,546,569,780,232,425,465,387,2,459,88,943,291,774,639,914,785,659,465,519,393,763,641,893,447,73,615,484,922,41,962,48,447,918,786,928,451,630,483,387,285,280,76,319,769,902,47,631,969,35,68,894,669,527,248,281,199,251,344,457,65,439,888,801,478,293,622,447,929,855,54,440,136,573,551,512,121,319,114,682,131,84,880,872,85,623,859,882,929,135,394,333,397,963,370,311,254,271,885,520,301,240,697,162,920,105,14,113,25,345,466,803,571,931,104,202,946,168,940,466,648,199,6,878,887,219,433,242,693,131,938,278,511,661,246,642,527,296,886,414,44,649,562,614,652,291,583,792,61,960,102,516,947,991,161,560,858,923,219,118,641,852,753,808,303,272,836,830,479,769,557,331,832,256,255,228,668,871,417,370,441,161,32,892,672,294,746,106,524,246,578,783,511,699,267,596,914,227,977,995,513,464,540,274,595,482,685,697,873,89,742,490,511,663,347,110,659,108,99,536,757,180,876,245,310,696,405,359,871,853,994,737,650,431,243,903,964,273,22,505,114,314,676,247,761,759,372,58,511,302,895,104,814,50,435,781,30,831,824,930,716,762,462,358,755,29,420,411,884,573,921,914,813,408,647,646,687,834,968,110,531,46,668,810,866,234,190,602,633,287,437,347,958,183,776,464,914,928,931,772,932,339,822,865,206,633,828,895,7,57,957,203,321,944,720,362,974,381,199,34,825,75,854,792,153,103,827,151,544,580,395,777,3,245,723,911,935,540,219,956,610,264,410,607,253,896,534,64,456,533,112,823,833,423,779,136,593,385,794,855,464,697,626,268,814,595,500,594,40,189,182,813,239,928,684,490,896,128,287,16,233,858,298,532,824,88,252,142,327,132,959,220,758,649,68,480,953,87,846,589,399,430,76,785,223,305,893,44,840,324,399,742,891,256,424,384,225,136,936,763,166,746,705,222,258,406,884,729,486,177,78,622,282,96,605,440,597,961,959,625,706,963,969,827,488,450,701,882,807,782,242,876,277,521,443,395,814,293,419,936,599,5,283,112,2,937,131,544,34,304,318,873,633,107,664,107,977,294,604,751,987,520,906,767,631,520,744,494,753,187,645,934,553,777,872,850,314,264,188,214,466,967,22,9,303,24,369,671,229,255,250,558,306,953,913,75,59,843,523,374,902,739,414,547,597,529,646,370,432,743,805,973,796,224,527,343,621,573,498,975,660,204,194,245,854,974,44,633,380,834,395,655,90,854,307,94,758,246,17,790,630,137,552,487,653,763,929,29,172,482,986,318,224,503,942,580,444,827,369,17,186,373,839,57,954,200,157,377,554,730,795,770,981,128,861,839,917,493,952,295,87,611,880,951,50,908,162,989,851,474,304,986,525,211,353,128,824,599,220,164,802,441,142,826,696,229,476", "229,167,461,244,859,299,805,965,815,187,178,785,951,122,785,373,257,109,379,447,179,338,304,481,345,167,53,165,523,425,971,556,573,822,114,310,0,153,876,804,859,472,364,502,573,351,181,496,790,304,743,367,765,359,16,450,964,328,948,617,440,43,730,703,481,131,94,972,304,414,269,165,66,350,577,165,199,649,204,865,998,953,996,244,239,866,203,723,649,281,749,77,990,905,16,751,620,756,142,673,532,525,582,944,376,463,88,253,161,507,87,681,920,83,256,359,904,330,606,681,744,702,713,805,780,289,988,740,714,88,928,493,668,600,672,907,841,819,521,40,941,558,137,9,327,309,302,913,697,22,793,154,909,879,341,581,955,732,584,8,420,183,193,955,391,79,970,229,928,217,238,856,491,154,195,193,128,842,303,353,94,104,138,267,313,59,702,604,372,487,231,663,525,258,305,723,824,215,248,630,949,831,315,331,65,978,568,978,626,526,935,662,790,843,547,708,607,714,685,983,651,374,258,903,620,565,614,43,408,616,60,201,510,826,23,832,710,36,916,465,853,24,623,646,481,191,343,584,782,737,37,992,12,427,905,986,865,737,268,717,245,712,221,51,907,687,40,541,679,464,242,719,89,992,881,300,474,717,492,73,601,136,122,261,203,267,445,708,866,339,807,906,956,674,721,244,510,400,535,668,949,24,499,274,325,573,112,511,733,10,496,403,661,223,363,519,84,579,785,889,362,948,130,493,443,155,863,116,966,870,620,533,914,414,989,670,149,404,44,923,966,365,645,337,161,741,79,642,227,918,879,816,210,804,360,986,177,222,746,740,587,989,21,610,344,127,476,9,586,892,830,689,866,25,972,822,15,193,366,829,85,666,102,160,8,833,792,834,503,912,35,650,764,380,44,714,831,428,94,956,759,35,270,509,112,347,174,799,930,62,963,558,790,299,654,955,715,521,196,924,822,245,220,538,171,76,567,917,745,305,202,999,414,830,723,906,477,34,256,674,880,813,403,780,280,315,45,946,498,696,882,50,969,282,608,339,501,875,805,108,584,241,446,249,448,744,985,335,303,997,173,520,10,881,488,16,297,88,665,628,720,850,983,505,753,952,501,602,364,564,26,84,576,301,786,361,68,561,850,416,56,719,990,101,697,699,248,45,681,575,314,405,478,365,291,969,748,374,217,260,343,198,768,905,960,29,283,866,863,137,860,501,839,585,125,170,46,277,209,346,128,234,357,355,24,451,908,182,508,877,430,195,96,368,373,279,614,260,326,192,551,61,933,128,670,546,646,742,320,410,70,555,689,298,769,237,703,608,585,923,899,282,924,853,677,978,938,110,726,677,329,913,466,878,884,698,86,862,962,254,846,92,542,600,95,463,516,373,140,103,385,258,226,932,384,195,343,499,127,465,705,152,511,758,395,360,437,39,426,89,53,368,419,914,826,149,695,727,206,681,568,163,891,798,167,723,205,130,769,321,437,985,527,289,450,496,556,567,973,540,545,244,559,182,390,357,130,668,905,546,792,68,105,912,88,854,256,46,336,826,320,219,765,28,502,260,446,518,430,156,721,169,291,384,564,423,386,885,591,98,542,692,618,880,400,777,885,59,589,624,626,621,517,63,547,424,523,493,608,676,584,181,623,675,722,525,238,629,649,968,860,647,926,333,659,78,41,878,497,966,869,301,28,483,801,869,160,724,411,411,351,575,388,232,60,342,818,362,742,102,387,855,712,306,944,486,887,735,696,318,691,258,614,269,133,706,65,652,693,438,44,232,30,483,492,979,954,837,915,112,349,97,447,500,371,403,800,123,505,258,437,330,79,207,297,91,430,452,651,708,274,821,780,673,499,159,309,701,394,998,877,743,333,852,765,710,502,450,193,875,629,731,475,633,284,514,690,295,273,344,921,818,935,689,419,391,468,785,80,530,376,194,259,224,298,555,355,473,961,306,987,200,639,443,812,481,685,293,794,253,41,163,481,6,166,419,654,298,939,808,637,12,403,853,405,438,838,950,654,243,870,925,901,897,619,436,303,112,897,420,109,217,404,639,306,202,801,835,942,369,507,105,676,335,356,510,879,217,951,63,947,550,939,551,224,440,209,44,853,96,243,58,960,162,249,458,506,453,787,511,667,145,666,41,484,712,389,925,415,988,545,403,320,95,477,383,345,127,614,921,69,173,419,538,947,278,877,618,2,98,358,384,641,81,27,663,47,522,773,995,976,190,777,264,655,748,424,83,88,690,645,31,60,872,996,250,984,757,512,835", "33,27,628,950,190,852,551,677,500,198,620,232,198,654,594,134,847,947,779,991,42,517,548,436,139,781,305,974,476,846,962,179,383,554,710,336,153,0,636,824,690,230,321,896,269,479,951,740,713,401,891,908,530,467,603,945,713,693,486,424,981,809,67,431,167,780,782,171,630,686,553,631,529,221,534,823,274,171,891,556,815,211,629,863,411,924,11,314,622,566,267,49,538,922,572,198,25,996,101,4,709,793,475,259,993,442,605,516,305,513,77,733,808,155,501,836,573,553,460,908,702,707,778,893,600,15,228,458,223,735,211,401,958,285,322,850,236,91,809,63,12,129,170,51,416,486,27,919,494,798,244,93,879,520,994,997,507,324,867,274,897,852,965,614,129,719,958,315,57,675,583,153,511,70,350,320,730,965,498,993,232,544,915,394,226,323,943,210,974,650,309,539,615,992,825,645,251,49,769,381,678,640,927,612,933,908,489,341,153,435,877,349,573,388,530,125,784,871,603,334,853,195,440,692,68,268,496,947,373,907,826,270,771,292,219,935,158,992,418,345,42,884,1,331,944,318,903,757,249,797,847,74,408,107,397,120,151,254,307,418,832,407,533,549,560,418,525,393,280,101,842,108,366,91,974,265,982,857,234,926,560,188,850,770,777,827,609,240,25,740,167,622,655,658,241,419,147,441,83,229,352,645,83,919,474,696,668,278,882,662,475,123,326,151,595,620,305,241,322,4,917,295,791,105,674,189,971,434,930,896,850,358,927,934,105,218,673,794,874,580,507,211,284,759,737,241,86,482,99,505,816,212,143,949,549,42,611,385,303,779,930,105,329,376,98,29,258,248,600,901,109,510,351,601,313,49,874,910,39,881,576,475,451,130,314,923,657,839,580,286,516,329,688,352,606,10,358,913,564,463,574,154,977,833,977,973,255,786,425,946,432,169,782,678,383,177,868,988,270,776,486,848,110,79,279,221,83,848,590,3,546,972,871,697,387,190,819,684,864,867,15,161,927,222,973,851,618,170,822,343,784,44,664,491,418,37,207,932,881,812,274,727,735,600,288,708,606,387,200,244,484,923,732,80,613,176,458,50,278,198,209,949,966,534,198,21,849,161,343,474,373,807,225,685,310,117,701,77,950,555,973,990,639,185,490,990,886,377,228,255,489,42,709,648,267,39,706,265,988,788,791,149,613,690,224,701,954,22,795,443,741,369,188,978,576,577,433,906,848,81,226,19,564,38,9,726,881,152,201,219,187,337,250,854,948,990,181,622,753,756,267,603,892,731,658,875,259,629,757,78,873,97,37,817,938,718,840,464,638,666,772,299,650,349,282,743,808,130,236,472,881,973,130,565,232,887,452,667,389,980,84,799,406,183,297,444,380,404,141,330,268,379,374,963,204,58,486,292,337,530,748,737,44,812,65,849,196,233,107,810,690,35,855,921,951,821,483,893,768,187,350,985,52,657,507,274,686,955,823,903,883,63,234,398,43,281,819,756,992,353,263,36,599,155,646,865,452,797,680,561,649,500,318,667,269,513,742,963,729,852,169,385,398,120,595,408,619,471,301,862,846,900,930,242,574,216,425,110,112,144,851,180,377,300,132,595,497,955,758,991,164,649,354,869,309,461,629,743,652,35,22,75,809,199,307,298,386,479,265,511,911,890,393,857,991,155,770,405,690,842,49,599,339,674,805,810,716,621,329,974,130,257,598,807,857,629,835,118,972,277,654,904,497,707,377,434,844,886,548,495,352,754,990,567,696,267,522,254,874,612,228,775,364,101,213,241,799,938,284,669,922,988,361,992,469,342,435,515,394,795,508,599,740,924,437,601,4,407,468,304,399,650,889,228,325,44,917,416,690,652,761,400,502,801,797,140,582,799,153,679,664,38,260,597,595,664,947,784,830,323,929,35,112,992,527,265,640,944,926,118,317,662,333,40,953,731,833,273,834,872,927,465,908,668,611,310,461,274,36,509,701,36,381,76,945,605,813,924,170,923,52,767,773,893,700,730,156,401,439,581,874,871,579,894,857,9,739,980,757,543,811,348,389,291,730,999,767,201,872,857,469,307,773,111,556,999,128,667,208,543,319,602,266,312,103,294,759,721,936,940,495,214,258,531,221,2,179,460,949,512,599,539,790,487,635,770,650,92,512,655,754,228,441,728,259,468,105,447,432,674,171,267,686,745,947,541,615,411,306,251,506,798,165,817,302,145,652,351,260,790,493,261,774,830,60,787,359,121,885,237,91,440,95,355,215,188,750,537,763,349", "112,396,781,993,731,156,77,716,464,621,786,574,340,833,312,567,921,617,978,102,224,755,176,99,774,718,301,995,567,564,839,628,611,704,187,656,876,636,0,634,880,367,291,800,380,358,7,279,299,800,601,318,951,884,884,930,921,2,719,23,701,861,760,289,366,519,158,114,203,857,217,823,727,126,677,667,568,882,584,996,892,952,870,490,564,739,891,50,532,857,342,273,13,282,684,878,505,999,515,939,392,996,894,603,942,959,141,716,709,821,324,813,409,745,552,623,742,854,256,787,946,953,811,33,260,577,802,76,176,417,725,730,148,393,776,273,776,773,177,610,671,35,338,150,725,834,274,600,583,59,274,801,337,696,65,755,931,548,808,266,345,654,507,723,479,467,222,179,227,619,442,22,728,918,31,479,524,902,26,987,938,346,4,855,911,287,35,147,787,89,348,107,810,944,750,898,106,996,347,652,43,378,825,968,484,7,720,551,635,356,768,298,564,212,122,442,221,349,99,539,146,830,766,352,131,394,547,387,885,885,976,694,59,898,823,39,786,396,81,217,511,149,64,674,959,934,459,354,510,399,98,571,984,342,902,443,541,65,240,253,367,778,432,880,468,561,626,309,423,12,420,643,860,885,414,364,649,151,827,477,129,41,359,957,177,485,390,134,890,966,33,219,317,609,924,208,952,34,150,438,479,711,698,22,383,202,523,946,900,583,17,492,511,500,413,983,739,188,665,438,223,228,724,288,632,960,732,626,379,392,514,114,895,574,15,785,373,489,592,802,821,351,914,592,894,67,429,260,989,846,956,750,138,327,39,756,643,153,316,118,617,54,524,676,88,912,741,884,340,288,406,695,728,500,259,85,586,755,261,408,250,248,268,915,37,592,510,201,432,790,629,823,67,594,109,316,71,675,558,522,693,200,591,750,748,211,678,625,291,819,892,797,304,444,433,699,911,311,905,934,285,522,543,33,447,785,204,490,757,59,9,848,631,997,673,431,929,197,453,554,16,845,156,885,490,915,233,310,207,709,536,635,64,620,763,28,243,433,609,159,839,903,403,246,122,387,368,481,4,185,535,625,827,837,232,886,591,948,547,671,348,779,442,431,423,349,215,311,182,896,523,460,422,874,523,139,19,322,585,917,229,236,149,413,996,42,468,610,665,188,238,395,152,61,97,608,945,291,31,781,322,598,146,748,585,219,225,107,464,251,79,5,711,819,411,893,762,885,177,334,545,982,416,71,822,673,450,618,462,399,944,884,373,129,248,385,986,786,191,330,398,298,495,811,908,116,852,167,859,439,736,234,936,457,719,515,208,291,194,666,236,800,656,440,535,817,167,33,463,506,929,550,765,984,307,320,677,307,630,469,404,240,844,308,522,408,371,870,669,629,580,948,134,348,992,312,556,140,420,153,405,540,266,643,486,612,617,496,50,959,232,485,414,371,773,696,998,160,512,846,358,450,705,691,55,899,999,97,395,197,779,293,213,970,715,669,928,721,563,6,107,535,823,782,375,486,582,328,365,117,289,822,861,12,589,750,524,234,670,541,136,509,700,375,441,622,508,146,106,828,502,670,246,569,203,571,238,902,148,211,514,328,359,798,733,993,427,7,97,252,706,129,753,633,510,257,742,183,436,927,398,364,605,96,722,121,676,440,147,364,381,81,423,406,797,514,441,168,51,667,173,711,945,113,425,599,915,959,329,972,399,643,112,709,204,783,833,297,564,533,37,980,448,157,490,442,209,86,751,806,879,222,680,107,192,837,729,121,584,84,444,41,439,236,206,506,560,452,41,27,687,754,637,659,261,886,144,246,945,636,62,138,930,588,528,153,58,674,97,187,648,646,856,555,669,269,158,933,451,249,872,973,648,403,783,406,698,582,36,909,696,569,450,682,194,977,447,445,445,501,681,922,117,99,648,855,664,767,859,583,251,192,960,427,629,911,805,257,184,428,558,78,404,172,913,981,722,357,859,668,582,608,784,704,327,492,428,484,982,646,356,367,117,922,985,52,784,468,540,250,245,359,616,727,350,647,152,711,498,416,328,491,275,719,281,556,222,805,994,123,320,534,772,839,914,570,403,371,81,340,242,856,707,569,71,46,396,556,251,619,544,251,265,516,754,751,507,665,154,297,115,407,749,671,814,859,885,220,468,294,657,268,847,175,172,388,305,161,352,190,707,422,369,324,824,505,301,175,303,679,816,225,141,718,479,392,887,723,773,920,516,553,916,379,334,157,847,783,198,322,847,250,318,779,257,342,915,995,985,915", "913,183,698,821,963,676,475,680,742,731,202,24,54,38,273,694,91,842,288,120,832,736,848,42,3,147,718,391,959,334,732,311,885,814,521,507,804,824,634,0,825,126,977,599,271,612,352,534,649,208,203,99,308,108,1,202,765,370,611,451,992,42,846,387,568,305,771,189,985,806,458,44,833,585,442,455,143,507,274,717,127,365,655,510,463,481,928,350,52,800,134,649,619,981,365,151,906,251,184,675,609,74,208,997,359,620,706,473,770,871,918,164,952,170,969,549,341,1,695,160,119,462,297,646,396,812,944,339,6,665,240,906,994,598,714,433,448,652,864,113,383,317,977,628,332,611,740,167,875,997,60,217,332,319,501,609,557,665,68,53,600,486,656,772,336,431,27,552,865,545,106,766,862,266,806,575,285,560,899,512,614,280,499,888,820,875,224,866,540,461,815,613,391,678,88,782,656,607,300,996,520,831,400,749,815,615,93,382,778,406,231,761,30,582,168,732,608,655,539,264,286,42,645,706,207,58,506,606,177,501,176,421,539,636,35,968,200,91,27,890,359,658,974,842,33,910,526,122,487,237,501,742,576,322,503,444,165,695,466,683,473,104,920,30,265,624,864,135,181,248,141,170,962,10,85,5,531,850,301,200,296,590,358,713,898,103,844,66,519,272,229,948,315,943,39,13,602,338,14,919,208,52,311,653,622,71,392,939,593,889,826,197,89,746,125,365,958,4,252,362,627,158,363,263,399,776,951,324,775,212,427,480,528,584,79,338,425,874,430,342,861,441,731,87,886,421,254,77,631,331,535,364,285,598,120,612,782,593,834,29,287,71,255,345,973,98,15,82,4,963,931,818,616,960,441,303,642,211,91,77,320,862,975,238,397,47,422,735,51,489,170,340,623,94,652,683,901,414,244,196,292,611,735,939,365,474,677,730,108,639,944,833,101,916,326,754,777,431,61,223,337,91,66,553,123,325,7,603,143,434,378,740,668,780,347,680,845,451,193,517,743,716,105,129,321,88,411,666,622,516,927,196,441,735,660,169,96,792,898,118,53,479,778,872,178,641,577,525,846,293,37,19,351,7,229,390,397,857,898,210,184,272,551,792,276,288,578,913,392,608,320,978,695,44,130,283,524,844,415,30,500,781,137,973,422,338,36,406,597,48,61,925,839,641,108,198,271,578,863,40,135,222,962,807,500,544,390,40,391,303,620,129,459,516,879,752,776,647,932,764,254,918,709,190,241,827,818,366,170,847,20,26,831,820,351,116,143,459,645,824,562,229,301,194,746,14,236,380,892,395,785,622,200,19,260,970,841,482,389,767,576,318,396,421,31,31,44,913,882,331,742,856,208,466,456,818,14,873,371,319,348,421,398,13,235,330,402,561,237,608,332,385,342,557,693,517,287,377,79,208,236,6,811,282,893,427,297,309,292,552,986,373,450,81,88,755,520,21,208,914,617,550,517,907,830,79,529,386,768,739,999,214,905,576,351,863,234,616,952,925,91,356,656,131,194,848,243,828,175,772,786,528,82,576,959,588,325,740,986,516,381,373,702,551,60,167,20,279,483,245,219,103,865,950,584,914,118,481,210,664,151,158,538,986,920,462,201,496,638,306,806,638,950,826,690,489,283,569,662,81,555,571,45,244,245,208,958,111,802,80,415,476,535,585,637,767,41,595,837,799,931,997,304,693,687,802,671,33,963,768,610,228,932,762,727,844,285,731,449,470,578,644,799,133,300,159,767,954,540,446,970,902,349,185,615,362,43,635,150,266,398,405,371,669,192,50,841,27,25,45,301,361,216,335,58,712,768,722,253,116,346,217,523,500,702,808,991,13,110,740,440,991,448,584,173,437,533,180,951,695,266,494,740,393,637,437,898,117,778,779,363,635,720,222,817,637,63,315,583,245,925,549,294,765,884,768,983,854,170,119,292,915,505,158,792,725,178,581,895,915,534,393,971,922,229,612,307,634,859,619,37,11,955,6,663,288,879,560,137,570,82,605,103,781,648,202,869,124,139,916,811,556,553,297,344,387,85,998,581,821,440,952,885,110,188,661,388,650,197,453,999,515,145,507,765,815,832,248,128,192,668,126,210,737,217,211,544,382,568,409,502,162,16,184,248,822,343,19,620,625,828,298,599,35,813,55,435,579,369,89,438,845,578,643,217,522,991,335,987,80,9,979,415,565,531,201,336,98,870,809,810,234,619,95,197,308,731,204,17,367,260,903,317,302,318,912,792,338,801,523,585,388,179,511,281,220,154,887,587,966", "548,396,361,818,186,904,499,907,842,396,218,310,504,195,841,759,385,393,265,116,281,371,393,651,896,197,621,559,492,148,325,665,405,512,922,41,859,690,880,825,0,208,684,473,706,130,446,885,211,143,367,99,258,196,77,706,32,895,875,793,422,661,77,655,499,786,700,126,53,775,324,233,156,651,39,229,893,487,98,771,439,972,401,737,425,70,901,151,837,763,490,232,140,518,706,934,198,959,106,367,958,414,627,484,431,462,407,368,129,251,454,698,627,101,420,364,350,759,154,443,210,805,254,580,759,791,370,965,916,684,499,760,120,584,852,104,556,536,995,770,834,303,239,335,915,776,781,703,436,557,48,252,480,451,388,290,354,259,936,47,347,750,858,901,702,412,187,114,433,472,868,402,445,154,769,95,858,683,342,779,77,797,641,377,304,634,237,610,235,262,500,581,253,592,167,122,347,834,892,499,342,628,922,211,673,46,837,822,877,873,748,556,314,713,762,27,949,253,468,502,269,4,172,641,497,365,168,648,778,637,53,884,157,618,477,555,641,500,160,745,798,892,289,862,659,244,34,127,545,346,116,761,826,202,478,521,174,217,732,267,988,502,509,703,586,23,333,889,666,321,590,210,910,505,274,283,271,236,96,383,881,293,798,889,703,96,779,575,309,23,938,756,586,604,634,613,379,21,248,676,642,40,275,392,110,270,266,415,270,204,496,995,427,357,598,855,556,395,561,897,330,305,939,598,56,559,916,737,484,620,937,229,74,827,35,789,581,358,252,947,154,96,924,965,563,968,900,938,774,56,892,960,807,262,663,172,888,922,835,834,879,92,415,309,290,862,464,525,232,804,893,755,320,442,496,979,576,982,591,856,537,185,70,584,812,282,510,389,663,46,289,583,851,181,804,999,988,833,975,337,755,660,62,17,569,741,710,158,969,863,979,315,701,351,296,446,569,475,652,49,738,275,709,181,849,306,608,561,106,315,317,734,306,891,530,629,16,531,139,677,932,640,295,527,504,180,579,823,552,797,640,771,42,432,829,855,569,432,988,8,924,538,801,243,198,262,632,714,824,679,898,166,705,380,664,134,959,224,577,157,428,453,468,96,801,192,409,321,334,55,247,134,618,180,603,503,960,394,165,574,207,133,504,76,983,851,819,904,221,728,187,297,979,662,460,86,693,114,205,284,300,401,72,222,357,101,265,527,715,388,354,462,268,485,875,650,101,224,406,467,708,947,874,932,630,81,126,217,764,44,965,138,506,717,862,967,172,390,485,244,743,134,931,241,639,300,164,580,92,412,187,562,509,790,628,716,276,323,807,270,624,547,419,361,498,177,224,54,662,827,504,81,462,12,449,292,959,991,253,865,877,898,162,886,214,966,641,902,828,446,419,895,480,255,793,620,490,682,149,750,874,412,967,200,797,824,631,406,182,202,135,478,378,770,661,229,847,448,95,818,398,889,496,67,520,163,352,230,157,492,302,440,256,204,564,794,755,650,548,580,532,128,194,408,924,710,830,721,914,897,884,389,573,772,335,15,790,597,935,894,592,404,582,471,201,786,918,951,647,217,91,344,717,640,820,193,48,801,172,885,928,973,739,963,365,828,81,484,888,322,359,331,544,95,847,274,369,668,853,373,306,622,514,313,235,202,468,821,954,935,813,420,190,890,159,191,254,706,415,987,587,578,402,944,428,926,993,863,81,603,746,269,723,697,278,697,114,57,353,629,273,993,456,103,696,987,843,893,650,731,460,900,180,670,665,465,359,233,895,22,248,237,226,101,612,884,424,611,610,216,534,108,92,506,567,321,912,668,543,307,510,334,685,63,182,563,245,930,169,230,649,381,796,56,814,832,468,196,519,923,578,541,98,68,233,441,864,87,807,219,440,673,369,582,356,733,732,869,776,92,859,461,870,105,143,958,775,82,592,634,820,617,303,437,492,40,122,166,517,95,964,381,727,216,333,496,934,979,962,880,604,78,969,368,201,352,654,604,232,719,151,352,62,508,795,333,775,590,875,93,89,584,417,556,186,391,502,208,101,88,619,557,87,413,52,542,991,352,91,746,302,562,92,264,588,507,924,148,360,836,931,64,844,90,668,406,779,7,892,828,103,529,335,90,593,941,448,200,406,550,885,788,105,887,943,990,833,868,898,141,293,759,470,508,289,698,248,754,756,867,526,550,308,263,858,648,475,593,111,662,420,719,298,482,300,233,750,110,309,433,769,527,819,727,826,754,540,50,888,21,935,369,617,137,359,14,45,687,111,543", "902,822,121,906,586,251,367,936,641,65,529,982,549,850,941,761,914,142,48,344,356,820,716,318,861,993,641,338,596,810,290,594,848,285,379,260,472,230,367,126,208,0,641,88,268,757,539,283,405,356,594,265,179,605,753,735,959,145,736,685,678,902,215,835,136,218,592,401,512,660,310,625,936,828,67,433,37,868,126,352,51,923,546,496,508,709,892,44,666,464,693,191,79,536,635,232,248,99,996,562,90,971,393,687,743,951,744,70,989,380,456,44,219,607,604,7,362,876,613,569,155,380,962,718,84,406,524,90,82,832,16,679,527,474,46,422,122,735,105,411,810,444,357,720,536,495,546,589,468,965,937,975,150,609,880,862,813,554,642,556,693,362,889,247,961,61,195,6,895,414,687,987,847,627,323,243,986,523,495,36,515,480,256,490,731,879,192,813,356,780,266,472,345,339,742,463,639,232,418,656,991,99,735,228,384,443,668,337,33,842,437,319,535,264,930,119,61,395,576,639,403,58,632,873,865,112,499,835,491,314,629,246,74,315,464,540,832,907,515,58,561,790,423,855,127,717,71,408,410,144,14,464,73,191,728,570,883,699,746,116,177,647,121,611,326,743,94,933,207,216,860,295,748,556,305,673,961,952,913,697,491,397,376,702,256,13,788,386,467,299,699,794,796,964,361,597,763,173,105,757,802,42,773,968,619,796,485,291,259,26,106,53,289,585,811,219,968,572,22,275,873,128,57,739,201,995,176,752,863,354,981,954,188,488,144,303,599,328,128,192,194,149,920,741,864,414,829,384,535,149,112,790,466,975,898,855,179,785,150,412,84,461,96,960,682,936,278,326,932,561,136,628,823,898,354,564,399,693,678,512,509,992,105,250,78,375,811,706,200,69,968,49,559,731,110,526,472,824,38,596,103,933,219,648,321,415,95,210,303,552,215,991,562,775,991,722,998,361,902,495,539,766,798,754,986,556,715,911,88,953,981,769,487,993,44,315,765,701,478,819,595,114,568,874,485,460,646,646,736,920,528,84,867,598,775,950,389,936,565,891,382,799,217,27,248,521,254,144,88,586,544,609,552,938,205,97,579,796,158,576,967,68,611,64,938,769,658,410,187,28,156,573,746,346,42,343,800,597,94,998,347,573,56,121,283,795,212,25,581,678,179,858,362,168,504,503,127,643,329,791,743,749,417,609,59,694,637,365,973,685,509,24,929,890,335,472,775,455,721,908,530,438,27,120,603,397,528,615,848,576,752,353,145,41,201,754,366,233,190,133,704,154,839,993,81,670,918,152,955,464,108,32,60,243,793,608,162,377,238,957,7,986,286,862,280,791,146,670,857,569,525,780,753,772,117,575,576,398,429,34,661,756,890,90,540,922,132,731,181,142,688,884,225,254,106,215,718,257,403,710,210,206,182,140,422,626,937,465,273,127,136,816,717,648,662,650,284,30,410,689,147,714,914,775,347,855,130,141,684,149,56,808,930,24,19,745,409,625,326,335,779,522,144,554,405,551,454,698,408,79,654,73,317,478,519,829,887,441,670,212,24,157,969,20,993,29,690,553,664,989,634,360,547,500,373,860,616,734,949,944,717,64,977,642,616,119,449,655,490,619,396,737,585,304,446,45,489,644,595,785,712,854,661,428,625,218,540,891,252,988,244,76,563,391,456,582,644,25,626,858,392,253,759,512,258,333,590,279,507,427,830,883,10,138,779,917,441,412,809,611,601,720,401,84,525,994,54,977,709,347,701,765,765,217,798,331,895,585,877,818,663,727,719,386,367,913,2,326,50,682,167,404,226,723,95,760,504,935,632,663,733,768,531,392,274,490,377,217,76,385,559,789,673,377,957,517,866,544,749,783,215,36,163,14,508,374,519,932,866,181,294,752,121,143,348,546,135,536,320,669,141,986,947,587,886,959,213,41,180,585,959,239,413,424,293,509,825,886,66,312,580,621,963,737,992,814,521,297,169,451,892,156,581,694,527,714,307,341,344,120,486,623,298,687,809,488,66,413,295,109,889,545,624,199,40,59,12,243,884,681,786,649,804,565,470,130,94,611,746,558,885,40,365,655,471,755,518,466,489,27,766,529,912,139,560,603,663,380,568,23,589,470,52,934,597,19,785,693,706,603,812,986,104,713,600,912,328,52,46,960,55,967,143,802,530,591,613,369,584,115,651,887,600,677,655,705,823,414,643,758,369,530,975,451,665,298,232,592,216,707,451,754,634,224,302,356,205,159,665,688,517,235,805,526,420,151,476,415,224,921", "793,81,216,58,52,841,648,958,923,529,921,609,491,264,480,88,469,840,517,457,885,301,954,186,342,337,566,861,239,112,11,340,699,329,983,375,364,321,291,977,684,641,0,438,867,729,43,24,58,214,419,195,449,860,328,109,866,403,359,786,574,682,838,848,727,170,867,525,171,636,152,930,705,571,804,990,447,128,857,950,239,389,956,670,67,640,751,59,810,1000,851,592,670,790,230,549,991,369,500,465,173,35,596,698,308,651,823,119,288,453,856,318,902,452,726,929,920,15,6,886,947,37,423,766,88,400,867,422,458,686,588,502,536,635,927,12,252,241,448,926,884,965,307,455,197,511,132,303,647,83,686,152,979,611,650,642,609,75,834,721,980,235,694,456,901,677,505,281,109,478,337,629,322,600,4,364,117,989,904,902,532,790,490,441,876,128,761,219,220,214,636,560,410,288,828,733,576,928,454,107,106,424,160,158,355,273,835,850,824,852,53,4,701,166,777,119,801,238,284,687,345,309,125,643,413,320,278,208,20,165,356,221,339,812,817,525,439,265,795,646,172,696,572,108,177,557,317,428,310,509,232,672,3,349,767,589,829,671,994,453,876,312,481,565,270,28,863,710,861,779,944,106,322,853,120,648,675,346,779,179,388,934,904,754,499,527,603,775,644,335,934,937,726,68,723,156,794,32,388,63,458,300,228,720,566,979,770,351,696,292,589,104,136,10,843,833,118,679,32,212,789,501,326,374,934,678,84,943,38,311,59,190,78,224,544,179,984,988,625,953,31,987,876,239,244,111,103,281,858,659,426,331,234,693,218,873,341,559,913,494,923,213,280,241,636,308,693,417,653,837,685,18,16,723,623,74,891,62,614,630,300,735,638,883,917,144,515,948,643,730,535,790,308,632,114,897,148,355,198,476,148,445,483,273,693,331,486,615,490,508,607,254,260,930,169,462,545,711,889,291,244,104,790,824,38,663,464,676,3,91,93,263,263,895,335,960,35,326,877,98,494,574,801,713,285,332,652,723,774,525,275,310,23,322,346,194,41,635,190,968,597,10,132,406,116,220,845,217,729,181,825,315,937,518,539,130,436,38,583,428,430,173,865,208,967,169,321,814,262,266,33,667,89,934,864,29,870,801,96,197,407,577,919,865,455,185,864,747,434,923,155,642,153,614,316,925,266,626,12,600,644,441,198,37,268,662,779,618,537,110,77,297,889,830,980,191,263,42,498,21,120,148,273,316,427,725,830,937,127,241,966,96,153,509,951,171,268,188,386,223,150,318,747,838,638,790,164,560,476,69,121,756,53,385,207,830,533,250,992,478,210,947,516,808,392,911,139,911,157,972,274,191,185,265,387,182,151,531,290,424,700,116,410,162,42,622,557,979,74,705,891,791,978,108,728,145,795,389,602,21,748,25,410,306,600,419,919,445,905,900,526,100,606,970,860,918,709,928,105,526,138,361,181,843,11,927,22,26,972,326,268,10,34,262,963,173,312,422,521,477,888,787,973,265,382,519,820,656,765,353,214,91,983,739,990,520,55,543,829,418,323,677,96,516,856,46,416,335,881,911,814,247,82,128,110,704,954,43,846,709,228,792,227,337,373,756,7,605,311,622,649,863,789,131,756,500,988,26,985,944,154,344,94,586,917,522,588,498,791,928,550,664,354,345,668,734,718,176,800,233,610,313,777,332,358,650,109,609,257,607,48,557,520,54,85,153,345,170,350,908,304,874,699,849,929,223,998,896,725,101,392,887,661,737,740,391,764,190,75,266,720,258,916,395,634,347,403,504,297,517,939,569,244,813,655,831,303,81,496,202,320,522,131,242,57,919,885,56,231,693,565,974,852,603,87,573,419,750,797,624,421,364,301,530,120,729,804,787,836,417,535,278,346,445,222,613,864,784,309,403,439,986,643,854,944,2,522,274,717,834,215,821,936,860,553,845,606,556,891,167,10,208,924,153,839,346,884,361,201,476,271,37,992,942,918,140,895,502,306,137,983,527,553,639,672,515,628,652,903,63,896,150,313,620,603,616,312,289,343,840,986,399,161,615,795,640,821,985,465,232,397,698,544,350,426,972,644,3,850,506,293,60,684,21,463,598,217,782,640,138,295,387,690,209,81,937,321,706,556,54,824,220,838,328,432,910,628,164,98,986,239,110,1,386,501,829,622,722,195,955,9,154,776,111,819,857,395,766,976,655,25,224,83,735,689,461,587,180,840,197,636,537,653,361,796,225,415,27,427,97,866,650,824,478,142,20,675,715,595,590", "563,117,819,492,700,175,899,437,117,612,751,630,280,354,554,361,58,240,758,957,459,912,364,953,433,764,324,311,16,360,445,115,379,674,956,99,502,896,800,599,473,88,438,0,752,566,320,297,213,597,810,563,743,121,71,497,4,551,788,167,73,421,90,402,435,989,509,423,285,285,698,648,871,1000,896,534,492,148,342,385,816,986,443,449,219,69,990,606,903,788,753,132,756,582,918,980,205,220,484,395,473,318,27,914,783,912,51,620,538,16,579,327,626,946,406,223,898,412,360,848,981,544,83,625,335,423,636,969,945,865,187,890,794,538,57,90,255,919,455,310,539,738,787,954,994,851,803,469,285,307,790,998,121,535,249,38,180,235,899,757,636,955,498,757,535,215,330,428,608,139,653,119,126,830,688,377,479,262,138,243,536,853,73,139,711,431,760,357,900,742,761,540,240,852,239,91,821,351,558,85,74,195,682,873,597,107,172,561,908,721,865,87,193,946,977,32,375,605,205,739,714,179,339,818,714,334,678,294,320,638,901,430,331,852,4,493,743,435,390,237,298,202,941,215,422,883,444,173,456,828,248,750,343,810,538,273,442,502,130,458,568,779,188,502,920,786,224,370,469,619,603,780,73,897,528,406,579,400,871,756,354,412,728,608,484,824,606,292,902,47,463,433,526,348,563,88,714,465,462,91,435,135,565,232,769,320,913,80,196,642,796,247,176,21,446,610,156,8,22,654,28,225,632,259,478,189,240,705,768,958,9,929,172,99,163,411,619,28,492,818,327,342,303,241,205,440,614,55,713,517,262,398,974,607,928,755,628,308,396,408,723,264,883,84,699,231,684,975,765,110,513,53,399,395,535,712,386,27,977,203,694,629,286,772,740,899,676,382,495,300,870,554,734,919,98,669,457,539,609,416,62,236,627,168,188,246,791,697,283,945,285,472,95,749,97,423,665,321,446,497,692,893,428,728,613,490,75,627,23,991,267,474,83,75,637,390,130,512,133,846,223,72,448,84,957,401,497,954,711,560,608,849,432,352,271,916,682,810,805,761,330,912,313,456,894,583,725,875,878,412,54,145,826,114,574,338,389,712,913,208,840,159,346,359,892,476,689,264,537,986,249,947,947,17,634,974,225,540,441,289,202,519,356,974,643,253,989,422,141,621,362,707,940,356,929,499,193,751,506,427,255,792,283,414,319,82,446,302,671,293,346,881,557,386,961,933,292,22,619,313,819,231,293,710,47,311,453,678,459,935,191,230,220,464,354,753,987,689,362,632,867,174,919,355,702,499,140,405,273,426,337,661,551,794,218,658,973,800,185,105,592,708,625,201,198,600,19,3,940,856,311,288,895,749,30,68,83,404,604,359,699,603,991,841,613,415,671,841,970,851,846,516,694,602,454,538,534,279,433,446,285,405,898,257,846,776,535,602,567,306,551,406,216,198,972,643,591,549,242,978,82,516,679,543,849,121,300,520,33,19,343,964,876,503,283,494,768,742,876,21,284,882,872,639,460,527,219,84,600,640,592,200,345,35,174,912,517,298,996,370,740,662,706,736,312,728,967,567,767,855,946,178,266,518,30,742,217,877,535,270,566,739,428,113,418,183,341,123,232,449,508,859,255,803,813,94,815,443,297,602,913,106,941,268,440,680,14,982,215,560,649,489,230,136,837,970,738,896,559,460,140,549,346,762,735,165,361,495,130,756,876,508,980,765,382,146,249,968,936,821,657,492,436,746,641,418,38,168,977,575,271,288,20,261,526,801,364,228,229,104,132,680,833,457,918,939,335,342,709,609,743,370,15,601,50,710,685,267,399,332,779,594,844,26,756,878,122,10,297,62,255,747,425,824,611,14,309,961,572,226,526,745,59,172,850,286,934,769,858,809,988,861,763,982,616,919,847,988,897,764,404,743,75,531,951,739,303,493,89,416,583,336,155,599,103,455,242,55,840,881,326,717,839,600,785,121,947,211,28,993,366,715,513,7,476,362,108,742,906,595,810,154,512,889,683,428,932,930,996,41,661,711,67,562,851,269,692,400,613,337,524,858,378,27,765,702,96,696,801,917,761,814,286,416,742,690,498,840,487,911,92,225,484,452,895,244,689,370,817,260,175,183,845,167,133,58,316,855,926,95,303,426,151,862,493,87,845,155,876,980,350,314,667,798,899,973,82,948,833,288,811,491,288,198,727,141,973,384,270,793,379,9,59,286,252,744,450,231,313,674,374,308,253,974,56,568,602,79,1,5,141,815,371,459,23,997,387,259,91,967", "318,114,304,863,83,504,319,991,654,196,224,633,220,217,262,216,706,51,431,671,93,686,180,242,219,233,468,617,265,273,78,195,648,956,176,406,573,269,380,271,706,268,867,752,0,959,664,268,830,946,536,541,953,851,468,50,828,534,94,452,300,576,642,695,641,548,157,42,105,384,508,566,880,729,329,454,522,408,426,831,42,622,65,313,472,942,656,175,217,421,684,642,336,912,475,987,684,399,958,719,73,115,525,35,488,511,122,228,764,343,509,211,266,645,199,735,219,290,502,515,497,80,938,995,168,764,656,54,18,108,515,153,743,974,670,776,316,274,53,948,669,772,43,730,583,614,853,584,924,581,589,775,168,642,427,461,176,515,136,809,725,984,818,357,269,433,177,910,110,848,188,661,929,533,116,307,671,111,255,8,587,945,438,397,840,935,140,230,181,299,603,714,486,954,737,747,923,794,828,343,141,429,953,311,264,146,938,416,351,239,510,4,298,242,1,602,813,577,738,626,251,950,811,275,476,945,447,702,53,927,442,252,681,213,403,245,344,789,735,331,672,470,510,396,269,717,282,145,884,561,715,248,498,439,673,59,776,307,379,603,501,552,977,34,551,304,222,84,561,586,79,944,243,261,548,661,801,277,663,393,291,472,52,707,244,869,327,130,569,302,920,349,220,517,586,966,907,225,519,921,608,531,25,482,557,465,97,680,64,837,758,33,396,551,218,715,718,547,741,70,552,866,472,33,715,1000,899,816,371,490,251,208,34,327,176,212,578,242,211,100,44,562,236,635,55,703,600,533,699,791,952,800,945,377,615,740,849,476,444,750,445,425,66,2,878,495,665,638,383,402,73,420,451,153,280,489,892,842,973,579,625,204,228,170,611,683,510,364,637,890,607,502,3,767,646,161,260,909,403,641,342,303,641,63,765,167,790,488,276,414,873,389,500,227,746,74,166,966,541,331,686,447,207,69,152,396,958,3,190,17,386,205,744,746,517,132,381,750,412,908,183,945,813,902,34,357,341,915,969,325,606,24,257,858,721,145,776,449,35,513,65,34,261,453,571,922,1,828,775,464,68,332,874,174,474,273,18,835,218,562,993,267,329,294,940,976,875,499,783,101,809,497,703,437,539,554,605,879,992,124,978,553,679,66,338,463,321,494,190,209,841,413,269,769,158,50,825,458,281,507,207,610,504,120,975,448,193,826,978,134,687,283,740,768,835,810,531,652,380,383,172,171,818,676,578,207,447,469,787,326,649,348,138,116,591,271,564,397,416,882,938,798,491,609,869,21,483,175,944,591,765,301,737,252,541,226,442,286,932,425,570,575,188,493,112,806,869,637,968,335,874,691,377,610,134,91,784,830,45,714,563,664,277,429,89,322,207,605,405,307,162,77,452,411,995,181,386,648,983,896,684,670,559,375,156,986,463,642,143,433,13,883,475,67,384,932,96,36,884,308,929,402,889,211,474,579,910,285,499,419,445,996,286,897,910,804,90,764,962,724,31,131,134,741,701,291,864,372,662,585,625,70,224,24,693,83,555,878,303,475,827,613,825,564,193,60,601,644,592,796,830,601,969,960,571,470,507,917,631,613,234,814,666,174,704,456,198,162,196,187,311,984,778,627,245,309,346,636,439,484,188,541,655,444,568,935,696,464,849,446,408,27,571,305,801,96,546,911,474,592,32,840,716,427,302,472,600,908,619,846,420,77,68,430,280,591,108,46,76,993,272,107,868,188,675,704,894,291,117,485,781,145,781,124,287,505,981,928,29,949,835,5,16,598,706,735,234,205,48,794,346,7,283,217,783,358,559,289,584,472,182,139,333,764,74,993,633,764,96,478,980,92,493,262,128,635,429,517,299,924,120,822,317,730,907,120,33,873,982,137,834,544,128,550,59,567,481,140,499,972,297,922,415,392,355,922,318,381,753,763,371,334,506,3,154,805,34,826,92,109,503,618,315,24,388,175,628,772,988,790,237,131,679,122,274,491,134,51,812,213,887,894,841,231,384,350,779,181,355,325,386,130,864,870,954,983,919,937,474,191,156,344,82,625,489,173,351,244,445,895,84,580,856,256,805,436,915,703,873,447,41,345,386,100,703,603,376,121,657,701,383,165,716,527,532,693,187,379,883,187,22,742,565,385,823,379,35,654,338,702,831,283,814,914,520,2,352,394,299,542,487,282,921,587,94,907,134,336,453,755,488,731,909,77,387,756,974,803,259,715,72,43,65,399,404,226,342,146,191,576,723,305,125,831,447,465,811,474,714,536", "311,950,475,955,981,116,175,17,955,130,543,802,347,256,675,196,858,446,775,801,317,86,31,868,528,377,154,37,809,168,904,834,93,121,705,593,351,479,358,612,130,757,729,566,959,0,6,724,543,988,115,77,57,895,461,937,927,240,577,446,911,730,121,10,666,706,829,350,574,223,597,242,84,744,143,320,905,56,970,226,730,847,430,181,909,747,484,314,293,88,145,787,829,321,109,713,80,751,677,343,149,465,147,230,414,359,135,152,210,493,857,226,756,687,951,319,492,302,645,746,643,244,891,93,65,314,731,612,946,72,363,993,738,322,149,146,57,563,271,613,419,245,753,322,614,785,24,180,286,790,673,665,709,70,434,178,251,435,978,154,381,586,216,602,24,14,203,459,250,873,932,820,282,884,361,649,824,783,740,139,210,637,573,876,580,531,725,977,958,190,547,14,329,885,23,282,627,863,816,542,764,504,221,711,465,898,568,459,392,282,952,85,994,832,846,627,951,725,172,456,241,270,277,755,743,73,551,300,755,858,909,418,729,676,529,840,799,718,130,363,119,937,484,974,572,548,895,771,477,444,416,548,839,866,944,507,960,391,601,922,828,419,384,92,976,986,914,793,277,790,936,846,947,26,911,872,39,137,827,227,82,664,862,470,578,452,784,89,205,896,911,88,506,62,626,653,887,498,963,44,929,638,867,301,268,150,723,928,922,333,41,687,161,336,672,688,647,973,201,692,176,825,270,716,643,71,241,974,881,835,551,747,718,705,917,824,908,286,391,905,854,697,123,46,506,470,522,883,70,615,972,501,869,404,331,689,719,306,861,678,27,942,66,603,514,645,533,337,44,185,681,156,292,251,534,834,388,763,890,530,617,827,800,151,226,335,884,395,86,101,871,366,23,359,757,174,811,828,361,53,21,988,910,802,529,834,831,833,108,560,317,917,453,305,148,917,733,36,260,498,913,757,319,87,203,304,311,955,708,388,739,641,126,124,16,706,582,60,24,904,846,820,606,823,932,6,935,715,705,142,41,143,419,373,992,13,617,518,148,624,292,293,459,640,59,644,23,176,109,381,43,142,36,542,61,990,153,414,969,190,255,554,767,523,74,259,501,118,735,874,261,643,629,478,483,32,2,729,440,431,258,669,708,679,559,336,384,487,400,510,910,700,704,346,686,953,944,617,935,448,263,935,77,915,74,441,870,110,28,878,962,180,203,776,773,609,6,405,235,168,80,848,211,782,282,716,656,956,360,886,94,469,941,188,673,968,298,843,892,363,710,400,378,477,71,656,610,427,635,946,521,363,873,144,176,939,11,58,150,564,31,717,480,300,58,722,848,176,89,760,589,428,232,345,89,114,487,655,584,174,802,543,178,778,811,925,457,322,19,358,8,664,192,674,381,107,947,911,338,804,908,510,710,190,16,581,804,747,615,408,32,570,261,523,998,181,725,396,920,18,541,661,670,407,124,243,513,419,336,935,965,684,691,299,142,711,209,33,826,788,798,818,765,900,730,261,6,907,751,630,334,473,346,846,184,432,276,921,908,553,781,771,148,295,613,967,801,39,375,36,836,386,601,486,26,153,699,768,631,653,471,537,758,747,652,476,768,612,259,861,398,548,157,35,332,27,896,514,736,453,561,463,958,21,598,333,843,906,837,250,916,81,325,891,145,790,621,70,577,219,858,240,911,675,450,774,538,126,126,14,258,50,909,486,560,706,254,906,653,320,758,310,195,663,85,801,444,861,193,108,288,307,959,796,215,4,731,332,14,895,604,178,401,389,38,787,684,902,638,104,562,570,942,864,352,878,5,251,824,828,8,801,595,321,232,454,41,435,898,904,233,121,130,333,713,483,452,663,449,671,832,207,86,72,305,743,46,953,542,458,196,204,795,714,772,417,72,29,191,553,423,285,461,937,404,92,690,979,994,65,671,146,97,767,510,451,768,73,385,740,738,750,618,518,815,40,402,955,619,107,643,608,126,628,431,727,993,807,985,651,724,361,772,444,159,782,965,407,517,721,815,159,157,169,280,577,838,249,328,600,859,980,975,975,686,920,434,538,465,727,125,671,646,368,712,625,630,921,607,760,481,863,288,260,848,850,384,303,219,337,58,895,806,116,307,505,770,484,881,135,325,893,365,675,255,958,552,614,389,352,225,533,683,581,444,260,786,5,542,582,5,308,25,327,226,693,452,890,620,926,850,669,825,259,254,163,989,707,164,332,649,514,424,719,447,257,246,252,400,820,497,172,307,4,326,542,846,547,733,647", "579,786,74,503,733,242,223,26,690,591,129,420,268,39,654,886,307,53,101,139,449,206,116,322,849,70,792,53,732,723,992,240,218,655,159,307,181,951,7,352,446,539,43,320,664,6,0,878,543,871,960,864,898,314,371,263,859,100,427,343,591,541,42,786,982,982,776,774,430,83,332,530,357,385,245,895,887,445,716,433,990,542,205,931,693,618,140,524,813,808,204,704,685,599,528,963,262,337,700,766,965,673,34,159,145,681,634,789,656,554,669,349,760,823,766,99,71,353,800,267,616,256,134,286,153,300,546,78,996,117,304,54,884,808,617,47,932,767,571,391,768,694,86,639,392,76,397,674,603,216,723,812,155,343,514,993,596,976,120,306,190,680,666,3,435,541,678,888,803,649,94,961,20,760,979,643,888,384,917,802,35,346,274,146,663,913,105,838,348,152,543,956,811,419,879,481,197,514,765,525,665,134,514,295,493,686,731,354,987,857,485,475,966,706,21,841,382,665,533,184,432,345,677,493,111,129,89,920,917,515,346,711,552,85,390,375,715,829,995,600,237,803,558,395,736,861,198,477,843,470,255,945,964,888,883,977,64,326,999,979,499,268,457,551,482,113,23,556,759,87,524,100,114,793,221,555,525,846,442,998,160,841,322,986,807,877,398,542,815,244,300,747,49,110,11,703,193,537,161,655,223,437,928,978,494,199,340,31,45,592,92,899,330,962,889,10,409,517,48,994,932,850,507,244,356,695,70,62,397,723,40,977,731,652,768,698,485,725,92,317,532,165,133,481,807,137,592,103,263,820,618,84,799,557,194,527,872,459,100,968,916,110,209,18,793,777,503,242,297,588,671,948,464,638,590,629,577,494,680,560,681,393,182,551,57,125,933,753,268,456,126,557,891,444,401,659,158,24,392,551,523,437,550,796,244,289,355,556,906,173,208,782,801,563,173,254,515,57,487,603,234,524,196,770,505,716,240,974,827,309,678,598,165,188,60,389,180,167,842,111,310,631,451,231,969,164,150,917,757,801,354,808,319,590,560,27,349,676,314,960,774,562,790,139,564,939,992,803,684,149,474,404,159,63,228,43,879,334,771,82,970,595,872,870,932,481,165,100,426,482,383,579,803,147,310,193,881,372,840,159,820,472,2,18,810,762,624,731,287,293,642,366,485,718,836,135,584,154,729,142,987,601,281,54,42,891,614,815,3,144,31,700,75,618,281,424,450,624,602,829,752,235,428,331,660,512,841,376,789,999,979,452,767,733,243,742,479,149,598,694,774,13,582,325,570,976,19,950,172,454,831,487,146,646,625,869,909,378,772,806,807,815,923,903,511,361,295,363,888,546,645,428,270,618,386,128,185,287,223,21,652,174,69,770,119,642,467,381,430,551,513,367,956,989,594,106,559,257,170,794,808,328,691,889,775,781,90,283,322,78,315,228,539,503,195,117,525,670,203,576,967,886,454,51,35,348,832,965,291,942,969,78,222,42,565,503,400,516,517,283,564,813,840,677,259,273,930,958,691,129,964,957,349,243,783,862,360,453,996,844,882,319,639,635,568,911,520,260,964,959,729,160,900,104,649,779,908,159,389,887,959,857,352,560,490,354,584,848,749,292,442,852,85,329,875,435,893,135,364,259,886,710,152,452,562,755,664,654,635,100,575,610,44,723,451,593,853,904,580,555,141,299,21,616,686,292,503,932,779,807,317,4,27,837,437,95,446,811,86,935,125,111,763,561,924,336,540,715,133,596,806,884,950,51,598,617,332,684,736,970,699,867,428,175,377,309,161,257,84,818,607,460,482,198,70,936,548,846,17,818,373,318,192,893,13,79,821,455,624,106,901,432,793,302,933,787,807,627,998,668,175,860,130,918,729,529,216,280,148,142,445,143,686,437,40,885,938,414,544,558,381,286,977,671,754,957,687,776,272,957,480,732,150,847,238,233,902,301,897,728,238,493,999,171,810,826,840,815,623,183,950,109,15,322,552,861,432,713,615,319,281,543,175,606,388,863,98,886,20,253,996,449,890,800,700,52,193,714,409,756,726,980,331,4,429,773,30,157,996,717,37,317,600,754,933,927,62,185,561,215,845,974,24,591,875,381,445,508,617,632,217,801,471,373,315,314,905,71,969,92,425,985,481,242,904,422,589,243,527,29,882,491,930,853,797,628,225,942,214,269,326,816,272,249,174,440,396,9,6,834,82,945,820,333,749,124,866,606,866,493,244,743,888,469,988,976,342,508,320,339,746,317,426,878,748,885,942,9,126,303", "58,101,324,775,396,248,988,520,491,875,72,952,486,184,65,340,636,749,841,906,469,212,597,603,703,102,470,659,470,779,30,860,473,534,602,816,496,740,279,534,885,283,24,297,268,724,878,0,954,597,947,566,935,507,285,939,574,729,932,68,722,984,385,833,142,311,526,407,612,932,686,867,36,634,818,58,877,334,932,151,520,315,194,554,915,579,450,146,852,833,731,701,168,826,204,450,367,998,372,548,419,242,148,83,378,378,656,215,764,816,245,342,684,289,397,792,411,968,855,884,684,279,183,459,105,226,422,140,800,934,827,590,63,814,438,398,407,4,420,889,479,727,952,261,61,826,742,536,995,996,737,952,156,899,126,664,732,947,223,986,931,385,412,749,734,237,299,512,992,876,89,160,518,446,556,430,775,431,407,672,150,882,260,972,854,416,83,692,305,396,578,85,196,939,384,506,310,381,901,980,350,10,368,520,98,518,761,690,462,476,982,979,752,821,358,712,791,998,415,221,26,613,23,1000,725,531,400,954,365,585,107,853,92,395,825,543,949,569,110,542,982,566,611,466,716,348,873,542,602,502,972,305,354,116,149,421,917,464,233,256,264,888,304,608,895,950,443,431,381,144,817,604,239,817,797,299,534,334,810,917,815,858,861,671,474,845,305,773,808,902,596,330,38,826,777,804,651,592,521,556,942,75,137,93,416,651,277,53,340,217,862,466,497,470,178,612,451,304,114,277,435,96,955,947,5,303,832,622,944,670,415,497,426,319,736,684,599,569,248,991,899,702,611,825,310,224,630,215,725,233,84,84,18,252,399,304,524,987,237,262,982,679,360,377,99,478,999,919,5,674,936,326,426,361,76,232,250,560,350,983,338,66,992,149,237,16,183,475,41,974,886,424,647,864,203,437,361,608,123,834,137,925,273,100,6,815,282,175,30,839,512,806,845,375,303,197,354,339,544,949,34,917,361,179,605,55,644,475,550,632,618,768,203,116,111,148,622,261,173,190,695,771,287,429,45,489,758,882,410,610,677,631,367,803,94,898,894,472,374,950,308,795,799,177,218,194,523,432,823,138,370,868,806,193,943,39,212,975,87,423,579,189,440,516,983,690,568,740,717,177,430,624,494,611,494,771,651,894,642,685,668,974,877,904,590,979,478,469,255,635,552,525,221,963,45,915,476,326,962,298,177,935,537,909,928,651,221,251,367,393,652,750,105,48,863,611,883,706,620,545,790,138,374,162,47,23,787,999,458,561,675,454,994,5,11,939,559,773,703,448,180,205,23,653,183,749,672,185,586,411,661,408,93,62,795,16,794,867,319,682,266,181,931,752,398,53,724,602,922,847,683,586,370,57,86,634,88,86,906,908,151,19,480,807,142,825,71,83,24,50,153,540,603,848,459,654,870,986,248,3,870,598,727,325,353,153,19,45,669,281,493,761,579,390,632,128,72,667,344,525,661,164,832,790,549,340,690,805,572,490,184,516,196,62,242,784,939,893,687,968,782,109,971,506,544,790,865,242,847,235,954,802,595,289,654,576,788,539,785,916,287,490,991,100,229,83,814,844,161,237,114,406,333,982,756,164,112,885,303,545,157,618,726,994,271,660,444,826,970,746,584,443,120,254,780,726,684,36,988,671,904,318,555,714,295,484,553,386,666,424,590,782,864,341,461,186,149,792,489,376,808,452,379,469,554,292,597,348,210,759,283,993,56,152,937,675,46,966,590,374,247,293,556,625,877,525,300,664,152,737,165,410,689,643,665,817,701,928,981,421,44,256,369,741,427,397,978,543,564,144,656,693,30,207,511,340,365,268,258,940,235,127,676,31,439,886,563,929,472,646,866,15,355,568,42,723,171,750,666,46,866,769,194,530,933,828,91,436,665,196,504,250,429,948,233,337,794,355,879,286,605,791,404,906,297,773,23,599,76,912,384,747,575,642,444,937,771,404,658,485,165,363,161,234,310,721,630,955,935,571,884,685,136,893,469,380,13,236,244,337,798,67,73,231,534,98,389,558,603,774,781,870,89,105,679,945,313,494,937,703,44,524,125,828,78,541,982,949,618,381,404,66,507,169,402,761,250,975,789,611,764,928,624,285,742,740,917,630,970,14,863,932,745,536,32,783,419,798,174,153,436,786,424,865,423,447,520,821,867,776,885,886,124,924,959,304,184,451,339,638,986,798,592,849,144,719,328,693,193,955,678,663,214,380,599,842,61,486,979,21,820,944,498,370,192,352,388,78,165,133,590,927,905,281,352,941,920,953,292,665", "145,888,59,396,915,794,808,62,962,15,529,8,9,807,908,312,277,512,59,787,118,1,499,543,763,425,65,525,156,511,398,740,398,857,29,240,790,713,299,649,211,405,58,213,830,543,543,954,0,120,144,121,842,607,660,504,730,305,31,626,434,987,994,786,590,488,994,505,801,246,509,266,241,253,644,804,462,110,628,505,939,917,615,522,916,142,64,692,7,564,438,636,305,23,157,310,414,264,472,536,140,26,562,135,169,18,185,569,721,704,898,581,825,663,58,9,535,55,964,816,134,606,246,403,87,782,754,184,906,604,751,336,486,51,707,915,94,202,505,370,381,289,748,509,34,584,372,906,718,155,204,894,159,771,714,320,299,540,518,93,458,639,715,140,556,79,558,551,220,544,269,290,976,111,624,591,566,760,742,832,63,553,889,431,831,258,557,70,150,803,700,571,636,126,294,112,88,141,825,321,789,272,838,926,308,400,825,180,751,665,81,165,100,602,429,488,853,977,133,732,598,203,826,753,878,940,763,989,427,656,660,44,230,999,754,928,751,504,772,613,176,893,745,410,886,589,86,285,384,257,129,242,495,412,988,699,378,991,360,767,492,160,396,227,996,350,984,165,560,329,957,790,458,140,571,730,568,628,259,978,126,421,240,713,818,649,800,443,993,594,601,841,134,705,564,154,849,331,417,3,266,592,920,340,124,989,707,840,288,104,737,945,843,605,352,239,469,269,609,449,107,817,568,439,440,509,196,224,229,189,424,448,27,308,242,409,212,109,462,954,453,670,253,152,159,629,630,912,989,578,349,299,65,976,58,69,262,641,999,484,981,255,424,745,432,161,823,965,843,987,577,133,498,203,730,555,170,266,137,937,278,303,359,116,657,231,618,343,645,923,469,63,701,83,197,379,140,656,599,368,109,14,46,453,825,69,892,414,112,815,101,837,15,52,955,935,885,534,404,659,909,748,131,756,494,836,448,474,459,46,332,522,813,827,38,719,990,699,97,89,88,369,926,530,618,268,900,283,575,250,256,346,46,875,177,132,31,898,478,849,469,259,207,770,705,782,581,702,250,521,6,784,18,893,249,653,95,464,34,287,128,531,379,160,579,408,51,598,52,535,251,748,71,910,669,586,401,353,182,912,47,759,296,208,212,414,739,835,713,23,407,73,529,101,852,655,786,49,838,352,257,148,887,105,10,346,286,162,305,440,989,564,392,447,100,626,777,874,280,185,508,193,659,245,212,723,397,735,475,558,742,432,768,196,557,435,801,139,630,217,608,993,825,73,243,429,827,481,319,43,561,835,672,109,661,344,307,437,839,61,618,739,215,792,836,108,894,634,793,402,653,756,44,683,696,346,82,233,73,510,378,917,67,257,733,359,110,269,803,854,801,967,880,225,847,355,182,662,84,407,338,789,269,830,30,755,875,828,697,22,723,403,73,729,888,60,556,347,316,173,667,145,94,650,491,307,674,941,760,510,255,716,754,518,228,416,781,643,844,447,709,942,590,691,53,513,109,658,802,847,409,782,262,741,797,826,525,863,431,75,441,703,669,318,917,762,502,887,171,422,888,572,76,304,796,607,718,784,852,341,251,580,233,390,833,976,521,411,667,618,237,796,521,494,23,618,479,343,751,778,299,382,393,458,390,368,83,200,467,363,302,356,309,839,276,804,111,870,734,670,143,455,899,13,974,30,726,706,68,455,962,738,768,149,131,206,616,729,533,686,323,489,454,381,221,386,991,256,595,683,767,10,318,772,789,354,655,491,574,179,870,70,952,32,435,798,213,87,742,291,555,154,773,428,201,621,398,769,412,398,827,534,359,729,142,202,852,783,624,543,261,333,215,871,782,448,860,191,783,380,7,453,608,729,477,60,284,642,28,13,384,472,176,414,496,360,166,816,667,305,864,851,244,592,982,120,278,365,860,646,843,39,576,825,843,207,325,317,489,655,365,450,724,496,959,655,513,659,214,721,865,827,369,282,13,441,115,514,622,204,746,867,896,416,799,631,868,329,923,828,503,428,572,33,160,631,952,909,793,763,387,463,940,388,590,360,736,877,542,431,406,126,660,399,770,355,132,608,492,387,836,656,834,112,50,937,516,30,186,965,893,699,137,400,331,144,439,102,309,246,591,239,705,2,973,454,320,62,348,690,332,183,121,469,676,104,318,960,332,500,476,636,293,804,660,657,642,763,273,712,16,489,139,103,547,703,217,953,192,522,152,7,779,96,191,695,413,562,641,722,642,717,325,382,535,137,924,388,888,776", "304,750,349,520,102,281,296,551,786,187,848,600,299,183,547,440,311,341,565,718,909,443,229,476,327,306,824,153,464,273,35,164,771,147,494,12,304,401,800,208,143,356,214,597,946,988,871,597,120,0,676,502,739,122,757,469,633,597,41,405,468,844,833,882,61,303,311,633,845,962,279,929,861,321,730,239,620,591,602,637,908,466,279,737,671,976,754,190,725,576,536,503,441,352,670,428,548,302,619,309,10,575,299,458,834,823,101,191,568,444,920,335,545,426,436,481,814,122,73,153,324,801,623,257,410,506,310,232,569,213,115,760,311,452,267,585,247,765,765,436,775,745,639,254,760,726,697,517,785,256,652,395,425,136,977,476,578,360,284,576,977,693,578,37,529,316,369,319,3,254,767,798,511,921,902,641,84,477,72,985,107,594,931,776,219,570,402,912,86,371,138,484,350,953,500,393,719,414,481,903,234,983,665,641,354,314,461,384,678,319,658,566,896,539,551,545,464,928,908,964,81,527,250,529,739,648,126,785,787,483,607,22,896,764,778,574,188,453,589,4,445,477,536,686,14,709,858,624,656,28,661,59,456,376,917,643,524,6,219,789,485,813,513,120,622,994,11,538,477,303,877,192,686,505,385,606,983,160,773,506,796,884,883,297,984,298,131,557,58,991,133,298,236,369,73,367,980,391,937,87,155,677,719,276,513,495,732,614,960,988,185,3,105,677,718,699,87,721,999,948,427,170,5,253,268,328,151,349,164,43,246,111,753,969,566,774,757,762,441,330,262,625,702,419,168,311,198,724,516,774,36,444,272,943,157,391,454,109,107,251,936,801,796,547,295,456,200,992,40,768,948,877,942,706,327,424,856,22,21,807,80,575,927,770,619,671,733,304,623,340,282,725,375,71,441,631,891,157,309,783,267,952,396,963,806,553,247,724,14,59,549,942,110,880,558,165,415,626,222,91,943,507,397,427,856,183,238,392,330,766,552,68,766,558,211,994,491,755,494,583,848,805,124,379,487,369,879,180,385,757,762,958,347,124,477,706,673,710,142,131,146,260,921,918,457,55,657,810,269,104,533,883,851,944,671,296,821,648,625,648,530,673,465,474,693,38,887,508,395,940,197,678,443,755,363,672,740,683,307,607,152,472,691,793,167,994,352,575,693,153,526,444,954,287,358,206,204,151,209,972,687,246,262,29,737,508,894,813,244,731,960,127,194,899,943,924,599,490,542,646,27,691,165,950,802,675,390,680,827,631,981,301,656,778,299,902,65,307,131,106,249,53,544,319,228,527,964,731,251,893,671,283,241,719,608,497,244,256,268,661,462,639,846,112,337,195,563,707,592,712,935,631,11,559,509,502,363,230,211,56,966,319,35,463,489,3,227,837,186,939,418,312,432,995,268,116,871,344,922,996,430,999,737,827,866,986,452,818,646,432,519,411,747,603,228,424,570,749,837,607,335,929,205,12,628,580,921,177,998,359,22,565,718,842,563,748,353,631,772,273,376,806,561,538,218,8,756,93,322,964,304,874,790,495,918,831,615,380,428,353,467,1000,352,309,698,359,766,260,480,545,97,358,115,623,249,907,868,809,1000,409,26,968,687,876,495,233,21,552,429,254,473,927,853,967,976,665,306,923,34,884,724,416,296,899,681,543,708,657,572,249,99,117,784,352,564,804,718,890,781,835,316,563,897,312,274,436,953,677,611,191,463,485,814,143,628,54,801,735,307,302,808,720,190,751,484,8,984,773,960,966,579,515,797,897,376,106,321,985,2,376,167,212,317,28,670,400,180,567,548,542,21,951,435,937,954,155,906,244,86,319,151,357,470,538,670,747,607,349,867,59,665,491,544,428,813,582,653,926,53,29,575,970,253,886,899,813,649,899,500,940,922,184,222,425,445,285,593,409,591,773,601,918,39,757,521,935,513,549,466,346,148,493,622,312,644,990,680,769,612,73,86,979,608,431,988,850,905,597,779,67,657,82,107,77,186,941,706,61,156,241,674,195,493,115,41,836,974,342,432,275,251,394,572,873,983,146,641,312,404,407,74,951,898,857,831,30,847,776,340,528,337,9,755,469,985,444,711,340,966,811,750,791,858,531,595,813,677,718,389,273,272,288,338,251,904,200,98,28,854,565,705,292,46,140,776,701,943,153,760,187,238,750,247,701,849,896,228,963,625,320,112,376,124,592,207,550,674,930,269,791,897,19,694,326,430,852,912,594,321,611,629,954,332,602,139,566,402,164,995,963,961,568,305,390,22,101,101,970,958,407", "133,550,120,652,122,805,3,559,155,802,167,243,597,471,131,30,413,949,609,463,631,810,688,937,234,970,547,516,66,761,59,145,379,130,890,690,743,891,601,203,367,594,419,810,536,115,960,947,144,676,0,62,384,383,596,12,461,343,664,102,343,365,762,658,710,988,143,26,323,707,419,205,413,312,821,385,819,908,427,461,358,398,746,348,821,91,491,707,481,765,919,488,5,641,215,755,240,300,833,932,391,724,911,519,703,768,78,257,926,504,237,979,530,521,793,444,684,486,812,16,956,229,834,673,1000,519,894,195,648,694,439,448,916,436,870,954,182,595,385,203,827,294,940,692,671,807,19,112,328,276,290,835,365,933,889,536,435,444,670,872,934,231,941,402,650,790,718,948,194,636,354,817,614,390,967,624,459,756,521,339,160,248,53,564,413,965,148,499,851,521,930,284,251,487,706,61,650,211,89,255,786,500,858,630,214,953,471,53,603,737,598,729,135,990,208,624,489,393,311,375,584,134,240,84,825,531,411,204,406,819,214,236,569,638,904,55,349,555,950,540,823,844,862,844,498,532,564,831,228,753,327,564,782,212,826,229,566,543,373,198,825,709,706,848,361,355,506,875,787,604,584,373,83,258,512,936,197,639,22,753,104,298,491,507,337,626,475,809,641,18,876,734,530,398,668,921,840,243,365,219,487,594,767,398,157,384,344,338,546,89,683,42,419,100,854,202,457,218,412,680,200,102,123,112,161,395,126,584,800,453,434,411,513,847,332,677,105,413,912,641,376,379,434,458,937,179,258,429,692,192,446,894,527,182,691,728,752,826,328,773,481,106,792,128,89,505,7,842,223,58,592,372,287,962,454,654,185,710,580,926,274,656,93,383,121,318,980,832,441,435,236,987,548,723,535,713,554,435,557,277,957,498,709,154,550,824,166,89,983,431,911,522,208,389,912,341,120,192,611,16,50,678,119,131,847,571,673,422,576,681,437,710,320,583,826,539,54,888,191,97,83,989,327,372,613,710,184,734,656,368,38,996,268,444,67,647,598,22,323,441,161,223,742,200,303,956,564,698,819,794,698,173,583,358,133,128,254,161,737,942,424,221,65,625,46,148,218,744,703,802,739,60,695,421,561,684,276,570,324,919,943,728,38,639,341,104,597,696,338,686,474,232,439,790,658,458,9,561,88,976,244,278,45,993,939,700,968,57,573,740,756,948,524,452,575,917,606,54,246,652,744,343,334,439,649,950,920,962,800,985,885,189,400,5,608,85,814,221,198,395,725,877,864,271,768,666,986,947,272,697,125,863,889,439,396,699,999,454,191,686,109,998,403,618,511,278,345,603,171,647,157,975,251,252,2,203,523,425,431,661,854,961,639,471,837,991,289,665,235,777,461,691,595,212,642,710,769,719,587,357,563,830,500,928,18,765,130,224,371,420,3,54,858,233,713,333,196,216,675,778,150,613,530,755,484,624,49,30,204,523,176,165,580,897,352,972,259,938,311,305,73,610,518,95,444,494,918,825,795,862,910,438,505,516,450,214,125,184,607,526,945,476,977,741,629,2,366,623,956,503,685,306,959,362,398,32,804,568,482,999,945,782,67,504,598,377,837,357,542,110,309,186,45,536,913,200,427,322,682,356,915,283,195,431,87,801,545,784,452,932,143,856,745,267,250,421,733,40,854,186,123,106,933,809,383,264,588,234,82,557,451,218,721,873,646,738,205,343,975,175,904,80,749,257,199,338,244,554,513,615,312,784,360,739,599,367,849,380,786,229,80,204,341,820,624,806,44,482,494,304,419,477,648,697,750,317,615,507,495,631,703,837,637,313,952,700,498,946,295,780,378,898,23,128,946,296,526,540,248,501,945,829,478,564,595,940,363,723,226,594,403,811,565,435,783,418,5,873,363,20,571,281,705,952,260,161,149,510,588,690,967,467,795,272,276,452,234,963,474,515,874,142,851,81,758,624,547,966,455,604,2,157,615,758,638,846,966,339,954,187,605,530,102,802,91,684,571,586,624,706,405,859,406,930,261,430,19,653,33,473,987,357,820,205,431,717,949,449,713,703,151,392,264,183,477,11,968,893,337,172,151,541,586,641,27,432,587,178,670,348,729,829,964,845,620,91,789,467,807,728,196,11,764,633,598,718,374,792,639,532,562,219,273,420,895,408,706,731,446,579,517,700,477,26,286,433,386,20,856,449,674,383,836,720,700,584,947,560,582,321,45,600,916,199,838,964,298,784,714,418,892,972,553,534,845,378,960,213,273,861", "440,293,555,572,905,595,216,991,695,769,509,323,386,522,166,811,744,115,600,818,847,940,965,625,107,951,889,88,480,417,817,473,679,932,905,244,367,908,318,99,99,265,195,563,541,77,864,566,121,502,62,0,442,871,933,416,80,303,135,927,358,213,286,258,314,313,386,345,142,532,224,538,322,841,542,253,292,85,628,878,200,769,758,255,889,867,25,982,191,359,8,707,712,178,607,46,647,932,91,135,844,952,158,516,993,183,812,275,606,919,118,822,187,124,274,333,454,82,494,372,879,364,363,408,547,884,164,152,363,644,879,307,114,915,520,470,281,476,915,780,651,321,426,268,180,415,712,408,429,201,238,389,936,144,993,833,150,150,846,518,566,714,633,221,763,42,622,555,125,298,460,24,192,11,352,743,369,864,227,716,241,107,384,700,748,36,192,145,908,207,718,845,694,909,240,897,104,989,25,822,584,219,629,899,11,135,564,899,496,23,609,724,675,602,97,251,182,324,932,262,770,835,29,73,557,600,240,944,84,570,871,137,840,465,621,171,559,741,253,831,777,447,825,961,978,88,952,530,159,50,932,16,213,113,496,252,496,48,426,435,159,670,752,2,245,553,371,238,718,896,713,412,38,581,109,370,753,538,950,710,32,880,367,920,758,311,291,63,503,296,260,588,494,647,42,254,629,800,52,531,879,869,797,687,759,347,113,144,352,842,711,150,807,959,53,426,45,819,844,83,523,892,217,748,466,10,654,932,73,790,543,88,751,233,515,798,633,887,50,67,590,315,191,611,599,495,52,655,52,774,997,469,134,92,666,516,470,589,680,906,32,522,704,133,238,531,394,327,198,477,320,980,635,11,506,481,954,822,212,215,828,333,636,344,782,119,80,491,360,651,183,270,103,869,485,622,545,594,561,599,830,143,976,120,844,326,720,365,529,93,900,601,413,611,203,158,782,969,782,838,173,162,549,89,118,683,468,946,427,110,672,336,130,135,466,814,864,259,996,579,420,855,902,481,497,562,331,422,773,240,606,95,594,208,290,742,364,122,338,266,127,816,721,31,778,340,463,689,748,587,899,816,666,986,709,285,397,528,936,408,190,122,977,822,379,289,145,99,682,833,729,113,346,499,577,488,402,290,305,356,651,530,56,373,125,673,499,737,985,394,65,287,417,814,928,334,505,811,515,656,600,876,112,730,11,895,830,711,400,749,160,685,529,121,339,876,789,558,127,331,820,114,827,150,832,559,149,47,322,272,606,921,884,195,985,617,513,431,788,609,769,537,768,214,42,415,293,641,390,830,161,517,319,753,115,675,186,53,350,648,583,194,180,307,283,920,605,130,467,436,781,948,94,605,592,78,285,759,873,839,321,619,294,462,97,296,121,815,190,642,220,989,113,314,39,965,771,103,836,31,976,443,425,846,306,47,406,589,67,579,232,266,393,322,799,767,968,768,472,703,533,567,232,778,387,742,111,6,453,733,559,930,560,860,596,385,430,454,143,577,374,241,582,505,537,58,262,731,806,323,964,747,653,835,2,908,791,619,904,906,447,129,734,411,178,7,554,774,461,650,208,517,837,868,770,152,568,238,143,457,931,464,363,29,601,915,674,485,409,185,721,630,438,251,31,138,165,850,573,317,931,75,249,1000,693,811,400,982,674,139,261,752,148,178,211,878,120,681,47,741,284,389,23,997,646,869,280,651,524,380,377,638,647,958,134,591,165,629,420,472,355,915,417,281,756,615,408,249,360,919,131,852,75,743,428,629,915,242,397,955,495,533,853,322,30,696,46,301,57,501,331,33,205,871,220,727,522,633,660,544,598,292,292,916,232,914,982,548,934,52,300,277,135,737,78,691,249,291,639,495,992,462,747,337,911,907,257,282,440,620,870,430,906,166,85,373,143,96,986,207,391,712,576,887,673,537,11,448,633,781,838,603,639,456,758,451,882,347,928,375,641,77,912,614,329,961,48,754,120,920,443,205,873,366,146,264,568,826,159,945,736,132,373,444,302,402,486,274,547,556,249,120,638,355,579,437,410,173,700,133,990,724,575,189,74,6,899,292,679,267,176,898,216,688,781,920,63,455,660,205,987,614,352,484,366,935,551,872,127,307,342,301,494,913,980,595,960,391,563,775,358,894,809,694,416,627,675,119,32,362,49,200,822,550,692,271,4,721,481,568,140,676,817,711,296,362,169,794,815,579,632,435,313,129,875,888,292,443,104,941,339,624,115,899,179,894,972,122,56,12,778,566,91,124,87,84,738,30,799,136", "159,584,62,404,891,59,197,725,926,214,840,748,352,274,475,652,988,55,483,851,359,799,829,980,613,945,90,746,332,813,89,502,342,814,937,765,765,530,951,308,258,179,449,743,953,57,898,935,842,739,384,442,0,805,491,400,320,458,926,37,841,201,449,112,87,780,969,761,667,22,215,841,437,264,337,332,611,854,102,911,569,467,657,663,370,524,753,228,668,354,939,477,394,828,808,285,999,993,305,439,222,138,98,421,19,816,28,657,449,717,880,445,896,366,534,247,565,334,375,372,734,723,188,809,72,896,447,560,117,172,75,350,945,334,738,495,44,115,538,12,953,45,613,321,790,295,762,274,309,541,51,993,438,683,949,169,414,981,438,385,851,284,904,981,344,92,547,68,413,952,730,897,592,480,212,407,758,996,166,423,337,865,421,229,167,580,653,349,405,622,650,337,361,352,784,846,14,996,23,234,269,328,994,622,697,77,134,364,993,859,922,713,939,786,952,392,882,176,426,295,37,103,969,86,251,247,492,815,802,825,88,447,726,566,270,493,77,45,690,709,514,405,66,737,522,247,692,265,633,504,386,81,65,606,733,278,395,453,781,804,854,66,762,734,317,393,90,213,735,305,179,820,764,338,775,74,496,623,906,405,329,792,76,900,634,67,180,569,240,612,329,657,148,513,51,794,743,850,484,388,49,141,81,513,998,567,269,485,710,695,538,491,205,325,151,542,983,674,589,760,476,569,860,972,882,725,778,997,339,694,658,392,420,354,58,896,336,224,297,714,894,959,56,233,658,67,113,562,154,708,696,743,44,898,414,87,412,492,356,19,614,215,843,734,804,105,479,94,445,726,552,367,44,99,667,530,95,392,611,163,785,212,334,808,798,723,456,114,153,966,788,436,786,236,802,749,950,79,879,936,294,934,803,963,887,849,127,288,565,456,92,112,757,642,533,139,522,669,128,647,905,633,491,797,149,106,429,560,416,252,199,135,996,691,34,576,960,39,719,953,524,311,287,460,714,335,173,57,969,753,370,632,939,784,88,274,429,187,737,974,687,576,968,528,375,119,895,635,371,165,7,31,805,51,587,65,657,732,620,267,604,797,894,877,717,937,528,728,796,450,968,814,538,980,506,526,337,631,63,961,743,890,697,62,290,834,821,390,122,148,540,217,655,462,187,911,980,510,641,904,256,247,831,645,966,55,234,656,363,350,64,790,760,999,736,258,943,713,134,529,227,773,151,2,352,801,676,236,421,904,128,930,829,681,658,991,773,785,207,458,747,77,939,663,173,425,887,64,57,76,201,303,488,794,151,483,416,685,818,380,487,794,12,377,436,522,173,222,576,219,262,371,8,542,193,771,169,749,31,115,510,802,761,36,942,40,427,511,554,305,226,522,503,380,832,811,993,211,377,647,305,405,450,644,171,322,808,147,708,802,8,638,152,458,953,568,685,265,189,568,545,121,371,109,603,475,4,750,840,31,840,928,536,719,261,365,336,199,72,308,312,286,964,583,351,404,453,437,543,566,786,907,560,361,33,48,907,165,868,290,483,491,795,912,244,520,949,247,192,308,124,767,428,628,100,579,874,177,988,677,412,531,45,606,659,776,742,347,714,186,160,646,159,137,62,787,545,978,531,95,176,598,569,142,325,463,404,409,908,376,30,684,817,631,814,712,704,870,738,563,903,47,292,368,582,509,12,626,993,683,238,756,135,67,655,475,150,389,540,678,180,181,717,966,868,245,96,243,819,414,713,875,513,915,277,192,16,900,473,709,368,538,205,473,159,110,589,603,1,896,884,501,291,575,527,744,187,624,823,751,90,541,29,761,902,877,762,220,170,222,446,318,940,956,662,729,324,528,804,756,506,475,475,63,287,836,857,913,776,477,358,741,593,656,840,642,127,798,660,322,89,214,538,336,252,592,870,511,481,8,469,683,98,340,67,682,2,352,649,159,258,756,193,392,335,980,972,824,660,920,538,52,659,874,511,894,197,771,683,813,184,36,140,231,663,470,839,60,115,402,12,515,482,275,242,892,487,532,884,847,659,69,12,995,371,783,527,846,52,50,42,361,973,80,702,569,832,794,355,864,506,538,218,724,154,774,497,736,570,834,364,800,776,363,567,812,660,384,331,734,882,778,25,407,94,809,662,487,592,954,533,347,914,516,250,158,962,433,470,940,642,521,418,123,654,397,582,126,295,605,363,168,235,755,42,313,244,829,205,918,941,766,117,635,686,460,958,237,13,529,652,711,109,889,90,635,992,279,287,956", "219,254,299,747,296,924,192,857,374,671,471,412,938,155,995,51,697,309,562,42,805,698,632,128,928,636,460,365,55,184,224,670,853,413,977,408,359,467,884,108,196,605,860,121,851,895,314,507,607,122,383,871,805,0,163,331,865,503,804,944,606,503,596,459,776,297,349,623,522,408,110,605,863,62,433,646,421,750,220,541,746,185,989,259,256,280,732,46,377,620,978,557,766,803,629,444,916,625,52,511,181,689,100,703,894,812,741,741,15,551,426,500,432,35,24,912,323,144,814,918,173,825,940,300,552,167,83,102,234,572,23,285,771,529,386,469,539,672,892,398,978,343,171,585,413,276,425,432,548,741,799,695,227,197,291,36,747,523,340,172,476,688,964,976,693,794,11,869,107,94,525,732,226,811,34,78,222,381,923,707,62,263,603,346,559,956,558,11,60,390,521,144,941,899,572,266,757,944,127,541,288,420,479,519,851,362,735,333,82,101,683,697,2,696,486,578,241,201,89,146,616,67,482,468,251,873,266,671,650,348,21,180,635,40,431,813,807,383,728,290,3,660,642,958,280,73,337,244,431,5,651,214,644,421,472,538,861,918,703,355,222,708,650,29,867,90,203,767,243,434,434,534,811,378,511,91,477,34,697,726,534,495,987,650,320,581,218,586,964,841,929,207,178,973,71,318,972,818,539,971,524,708,201,465,312,865,230,646,31,693,581,551,52,865,224,114,224,62,586,674,363,171,808,202,77,543,889,934,419,887,541,391,736,346,887,511,340,513,904,800,452,2,417,114,338,276,466,968,91,283,827,445,324,676,274,885,448,746,685,220,709,627,587,697,39,667,521,560,603,208,224,8,578,519,930,647,919,153,723,989,648,819,132,183,550,843,888,928,237,596,59,921,993,880,472,860,107,560,408,359,464,104,410,562,301,679,840,271,18,386,559,861,532,891,565,879,755,389,382,474,465,783,530,728,164,457,420,712,769,54,74,206,2,812,936,388,220,558,779,813,552,602,35,306,451,366,617,742,763,653,669,563,247,14,303,393,453,188,404,190,505,566,477,688,31,62,137,835,178,106,618,901,515,890,934,320,883,484,857,657,597,648,995,849,898,143,832,165,663,538,972,830,514,363,390,34,324,795,733,911,572,272,3,292,474,990,769,183,854,123,537,549,913,97,763,496,236,939,643,412,148,508,200,930,365,930,435,108,545,399,219,63,732,698,465,566,360,68,63,164,351,855,209,646,480,256,55,283,737,978,935,979,377,574,546,196,833,272,6,508,203,524,288,658,984,944,179,611,565,208,303,644,461,985,271,684,477,196,209,149,127,353,176,618,710,817,743,564,850,829,874,105,606,845,387,914,137,181,690,964,928,824,262,3,862,528,135,559,547,451,607,367,614,826,436,539,649,106,139,178,868,306,909,982,633,266,881,288,560,338,452,947,111,259,304,761,238,894,528,869,821,853,878,851,582,732,431,922,434,46,805,196,72,13,321,693,876,899,678,754,149,420,451,626,34,397,563,678,645,727,914,919,88,612,299,54,223,532,84,628,469,94,566,821,919,875,588,825,189,462,530,956,16,864,820,315,134,942,127,810,937,744,47,894,267,377,729,40,482,391,529,918,807,224,181,977,802,970,19,60,961,332,363,36,246,757,886,506,249,267,69,582,630,409,410,971,501,952,780,162,850,244,622,974,958,122,380,508,971,172,933,59,777,169,689,222,643,220,35,453,106,923,180,294,867,669,802,72,866,804,845,249,761,766,435,492,415,384,303,80,401,842,306,595,817,127,329,85,528,479,866,611,515,179,875,535,842,592,313,335,811,873,270,472,674,152,641,521,958,491,669,351,833,353,979,205,731,245,44,316,510,407,123,590,268,801,807,355,354,136,250,656,562,184,456,342,686,853,565,413,931,710,713,800,975,615,217,380,496,492,777,20,357,446,149,12,546,796,768,611,461,454,416,968,54,42,94,91,596,944,512,92,86,970,664,326,515,417,223,316,799,421,408,728,345,266,176,835,679,467,926,38,521,808,433,987,563,6,618,773,825,252,871,809,451,877,925,523,27,703,793,259,848,784,259,391,669,254,997,8,7,385,751,855,682,113,78,967,225,51,923,911,37,957,334,50,83,120,941,566,960,351,191,850,205,777,846,355,787,632,764,239,360,649,170,370,696,88,870,66,735,568,821,285,515,967,832,169,951,799,607,671,829,279,418,799,679,869,153,748,905,112,612,957,469,613,770,972,265,308,295,595,459,524,763,790,218,177,816,895", "300,732,840,304,198,109,807,542,383,331,851,46,893,496,10,758,463,951,234,296,622,861,71,910,57,924,677,255,412,955,157,332,453,613,346,961,16,603,884,1,77,753,328,71,468,461,371,285,660,757,596,933,491,163,0,150,664,288,651,186,9,900,286,411,567,180,129,469,148,152,858,30,862,57,327,264,807,795,478,700,724,145,811,360,138,870,301,672,109,702,864,175,15,782,801,999,828,740,342,527,334,931,775,504,897,339,744,323,703,988,920,807,743,674,780,295,983,25,575,424,496,669,414,71,50,652,776,781,804,494,628,856,664,315,163,399,551,16,105,936,178,778,287,305,412,222,4,602,637,568,820,754,257,474,817,618,573,563,11,771,78,587,430,987,392,602,14,829,554,981,945,545,569,437,385,431,134,941,39,985,247,402,735,473,505,278,266,668,186,263,520,417,898,267,715,126,730,585,972,732,232,115,996,636,379,285,278,892,932,116,617,739,98,581,17,81,243,190,405,995,787,399,566,291,216,792,673,503,385,205,185,491,535,191,43,370,628,544,83,915,726,42,392,241,934,907,739,888,720,429,512,872,954,188,619,632,51,851,765,535,379,432,170,444,161,463,525,623,4,4,316,414,423,120,498,766,630,605,499,108,953,255,494,853,283,403,568,162,261,888,918,416,2,90,990,963,84,399,915,272,117,762,979,304,63,19,618,833,670,438,373,333,956,3,138,644,295,442,130,310,539,568,925,176,110,957,377,521,506,688,462,690,786,897,55,993,650,174,993,402,543,422,930,263,482,316,182,234,262,138,86,760,528,744,443,565,845,939,176,289,532,883,476,424,321,976,688,935,76,644,670,102,51,498,691,290,132,167,970,130,627,532,194,732,101,385,425,564,511,413,689,466,681,426,474,271,793,794,420,934,922,382,345,970,320,771,342,961,300,954,709,213,727,824,434,431,47,63,281,217,146,578,943,401,412,326,416,758,809,971,898,385,155,958,831,393,618,833,405,737,340,917,563,903,859,688,541,431,160,559,92,648,146,652,533,407,859,17,260,628,59,580,804,504,612,524,417,664,53,597,606,624,549,645,753,387,638,116,777,831,366,163,840,10,700,997,825,688,631,427,171,403,201,101,406,487,751,155,769,400,122,956,171,834,176,119,682,552,508,913,615,3,955,124,281,273,895,647,325,832,432,886,693,857,192,362,629,773,355,320,459,232,476,563,740,645,766,794,704,160,523,246,267,265,345,674,584,51,274,91,112,894,946,231,760,908,163,201,924,121,976,43,354,876,809,597,117,393,858,628,363,413,654,781,720,494,432,50,243,752,426,801,624,641,521,803,262,81,406,325,389,884,789,416,803,643,275,111,520,688,275,588,223,311,307,3,261,914,106,975,758,847,946,621,961,503,703,120,879,192,321,466,532,652,822,265,840,681,287,388,83,166,969,452,160,389,263,337,479,331,108,240,56,921,210,211,410,127,808,380,670,404,130,274,509,564,687,76,288,371,584,20,129,629,271,902,245,19,824,220,834,40,60,515,930,206,878,729,11,498,253,403,46,390,230,979,881,260,23,19,989,169,408,974,187,993,919,912,220,324,762,461,573,420,779,688,193,658,873,845,730,834,224,738,860,17,183,863,797,133,170,603,659,26,719,681,929,324,896,565,851,345,869,16,935,682,753,853,680,428,963,641,479,684,719,108,561,643,592,562,522,431,839,462,389,939,700,136,664,351,164,308,325,466,172,114,238,789,166,266,334,120,701,972,132,438,642,590,61,729,837,664,552,304,104,14,838,41,812,714,70,856,982,822,970,702,664,141,430,306,719,474,145,359,303,420,343,163,67,285,868,402,896,506,414,61,48,202,817,37,813,614,473,943,597,434,96,486,707,844,942,138,648,850,494,541,801,361,81,686,310,585,897,663,706,670,724,144,920,201,582,512,327,706,686,118,686,173,275,880,778,604,112,726,603,704,351,753,653,966,71,687,714,17,826,791,200,846,779,263,52,543,941,315,662,838,165,319,490,735,491,664,235,703,385,921,733,203,846,261,691,825,439,599,691,127,146,414,862,355,315,444,469,804,652,509,817,547,198,857,18,853,358,809,196,598,508,972,376,116,745,477,84,365,927,232,869,411,747,544,735,887,298,169,408,178,102,526,443,393,74,2,508,916,355,101,382,482,639,66,55,425,472,861,204,344,208,546,165,395,296,804,857,798,635,424,78,982,815,394,700,630,313,336,154,119,859,628,382,539,161,423,636,259,143,62,791,574,199,714", "855,694,451,949,736,36,627,434,406,611,544,140,767,90,529,529,635,611,912,9,712,924,116,71,591,752,734,772,873,183,955,922,121,609,35,959,450,945,930,202,706,735,109,497,50,937,263,939,504,469,12,416,400,331,150,0,645,237,340,118,864,315,648,709,634,385,641,168,699,3,683,300,596,454,693,514,294,442,14,178,55,462,110,910,160,374,113,768,315,491,228,697,168,431,511,321,34,878,703,858,635,320,913,668,439,904,625,105,99,31,570,868,628,182,513,231,699,199,348,438,318,999,24,584,245,895,739,641,503,469,160,448,214,846,391,894,550,629,26,351,426,935,519,426,551,602,129,131,817,634,212,145,381,957,726,789,470,880,752,8,962,831,300,411,72,419,857,28,198,297,203,109,795,960,305,689,842,760,658,103,810,317,494,859,828,176,9,88,288,419,617,24,500,68,502,852,211,78,912,539,640,857,372,153,545,59,71,29,398,614,767,681,338,731,309,755,181,256,837,750,299,864,136,904,358,982,867,437,681,764,299,248,57,538,65,441,803,644,756,978,606,812,319,308,163,774,496,945,715,468,335,353,765,423,463,167,632,144,871,698,423,509,133,251,86,177,295,551,644,24,611,644,642,786,284,190,90,974,14,276,147,353,413,252,730,111,742,833,657,67,356,965,854,295,502,97,926,775,403,681,128,518,522,844,48,914,204,127,98,994,660,434,844,58,744,620,381,715,365,116,438,332,158,37,918,397,712,651,306,342,72,932,267,563,795,917,702,965,885,223,170,10,667,729,142,361,850,716,516,129,930,624,77,113,768,254,550,770,641,591,178,934,391,944,756,916,250,781,786,704,464,16,575,434,35,317,279,845,764,925,210,61,797,272,519,38,509,110,845,960,858,254,798,760,164,613,130,594,161,865,829,696,660,590,61,196,722,718,572,116,665,216,186,901,911,256,483,36,349,711,520,114,773,848,355,550,43,174,257,847,518,298,80,615,106,213,60,407,55,597,559,410,8,228,462,880,350,167,230,370,11,147,620,757,795,938,9,754,60,931,422,730,991,96,713,286,498,142,794,979,653,273,978,806,931,258,127,722,814,508,533,846,961,851,560,716,321,951,572,233,35,874,472,568,987,94,26,258,18,68,79,715,665,183,513,671,307,923,20,16,655,213,851,193,724,305,195,139,115,971,58,481,920,980,231,910,593,928,698,724,922,973,173,998,206,603,195,823,714,593,92,327,410,1000,112,417,816,688,379,155,774,552,474,256,916,299,37,224,948,8,470,661,559,140,558,54,463,574,967,869,640,370,273,633,77,966,540,162,831,567,67,679,167,965,942,225,79,860,757,7,14,755,520,636,762,485,458,253,31,340,918,415,381,315,378,234,97,880,412,168,179,283,498,887,153,145,358,536,190,747,558,285,70,76,658,711,348,941,951,204,778,906,884,395,312,480,439,603,580,440,104,463,818,125,126,268,894,203,106,729,109,412,258,906,15,869,413,233,219,865,385,991,979,479,931,960,442,317,336,305,36,70,543,97,413,445,421,344,626,353,853,173,555,399,105,989,450,231,409,69,771,157,564,672,482,4,662,83,254,100,312,266,848,606,640,364,135,276,161,477,700,727,9,239,734,663,198,504,585,745,428,878,672,588,125,448,349,139,39,953,953,320,120,907,857,686,994,10,527,247,412,524,268,517,293,291,141,483,325,972,844,532,658,670,443,896,208,353,6,901,503,769,309,501,310,882,262,773,405,907,376,460,511,356,888,186,308,234,6,93,456,444,187,10,607,709,847,288,769,189,871,287,183,206,618,756,835,458,989,729,87,190,161,21,648,24,517,250,469,846,557,672,428,77,288,294,818,626,907,595,706,182,676,863,734,193,276,376,363,959,821,442,183,535,835,694,684,192,497,90,622,458,595,230,293,377,796,682,359,538,707,741,947,683,570,403,857,832,536,522,98,359,224,431,509,446,665,583,391,657,343,516,829,414,618,727,260,315,429,814,727,421,86,791,71,639,579,737,72,837,244,847,42,118,241,471,267,97,843,667,498,33,63,138,831,625,275,49,11,253,595,812,261,270,721,26,1,229,770,268,966,938,858,592,605,209,380,82,228,146,902,722,715,23,686,266,379,624,59,841,895,772,345,47,314,830,504,360,889,614,488,939,16,376,887,664,594,327,608,722,495,225,493,229,58,234,743,166,885,61,648,229,200,911,679,472,751,78,421,83,59,435,407,229,9,426,530,51,222,367,306,715,686,504,997,869,336,152,415,816", "443,278,353,222,352,87,976,948,957,474,945,483,400,624,720,324,601,910,588,4,925,335,674,368,91,167,40,67,600,592,876,645,443,533,73,699,964,713,921,765,32,959,866,4,828,927,859,574,730,633,461,80,320,865,664,645,0,389,702,97,475,182,555,966,340,865,99,86,926,35,777,555,161,257,28,43,681,25,204,407,577,467,146,514,568,390,177,4,636,26,780,462,759,33,295,625,361,83,653,508,76,220,603,451,277,358,292,857,580,134,886,291,236,354,361,932,290,403,920,85,919,591,32,778,886,204,484,677,123,15,6,986,741,529,421,975,9,187,918,40,362,377,173,47,735,883,418,93,293,501,496,73,657,924,144,870,545,219,462,201,26,319,296,617,331,33,897,838,457,177,686,933,504,114,179,342,640,608,362,182,763,231,768,465,654,392,531,685,534,234,114,333,200,953,489,921,641,381,570,452,852,308,752,187,321,647,721,677,93,878,991,235,664,927,396,998,359,120,443,112,34,379,29,127,14,207,241,775,982,796,548,148,56,453,810,361,631,265,803,936,187,880,168,371,89,89,116,215,625,32,828,195,597,208,638,600,383,865,487,936,915,584,136,720,978,309,775,87,347,169,947,658,120,642,534,179,362,401,266,550,426,616,126,724,905,951,416,990,43,260,466,385,406,464,963,747,630,687,460,351,28,675,690,755,328,90,994,87,526,926,138,291,477,280,796,947,87,432,801,403,831,802,221,313,133,806,492,522,543,644,627,117,391,870,938,546,99,11,540,68,164,359,919,357,816,329,303,151,744,260,118,100,929,643,639,428,726,403,989,181,129,287,727,617,287,549,331,757,742,929,978,895,52,79,627,665,408,621,290,568,761,372,785,999,536,702,871,560,13,994,995,784,751,356,22,192,643,554,454,115,553,96,594,166,104,28,692,365,398,943,116,103,962,970,553,446,952,635,615,183,324,911,806,831,647,185,867,457,399,810,17,925,532,117,730,409,405,359,548,483,975,43,337,685,884,920,645,439,144,684,776,768,612,871,896,790,37,6,941,874,45,681,335,224,527,780,451,952,945,620,158,654,749,643,425,937,827,44,227,333,277,648,429,940,716,345,347,157,296,109,230,641,371,358,800,569,909,92,843,154,991,731,653,928,491,244,247,974,884,790,407,294,750,488,989,524,240,442,778,849,865,374,102,205,177,847,278,329,685,454,623,290,150,798,468,342,493,407,198,479,549,809,928,537,672,795,265,194,880,51,146,136,915,897,88,388,657,313,350,137,242,513,557,153,768,254,228,793,756,341,83,427,172,137,159,308,280,503,570,30,32,812,253,341,24,556,480,987,31,279,26,245,27,70,580,965,261,968,53,836,172,376,808,187,910,804,544,304,209,421,462,736,792,68,613,698,591,420,515,203,948,105,290,787,741,489,27,637,94,416,308,343,68,788,743,449,713,457,180,824,404,50,697,511,459,899,58,868,43,696,895,31,869,602,696,355,322,142,539,460,273,526,927,832,443,274,494,953,915,310,297,703,145,680,476,196,672,399,989,425,824,258,317,71,458,914,327,24,714,330,154,659,543,274,404,20,210,286,435,694,395,237,233,936,516,150,786,235,225,647,684,296,913,452,365,805,467,276,328,659,826,846,746,910,407,473,550,958,253,225,521,511,262,41,853,246,510,524,219,167,179,337,106,347,232,846,371,134,371,708,600,75,160,952,748,335,116,716,93,440,546,630,973,105,197,701,365,855,705,140,939,847,483,395,621,450,123,242,107,139,639,658,609,414,150,222,359,741,192,628,426,693,789,271,102,193,529,241,717,108,985,352,550,98,366,601,119,977,286,211,694,765,346,819,346,442,36,62,234,100,261,782,694,677,220,690,858,753,156,287,984,562,590,279,775,775,750,31,130,783,66,248,891,858,379,780,663,868,891,842,299,619,788,904,395,757,447,764,682,154,572,287,292,573,672,757,573,266,822,490,961,63,794,15,829,794,240,733,391,86,980,469,711,169,388,302,291,575,658,70,334,304,936,987,643,547,924,504,862,326,528,985,687,138,708,365,455,912,461,30,616,643,719,585,222,770,498,360,247,529,736,751,85,234,259,605,858,410,591,829,700,611,586,484,657,359,474,523,404,58,691,984,655,895,689,988,583,280,358,667,112,303,734,520,966,546,395,32,648,75,565,817,24,482,813,821,319,762,307,253,651,254,856,87,684,137,503,663,806,860,992,293,593,435,603,655,705,541,242,659,976,702,474,245,62,741,734,255,216,95", "385,971,402,7,527,931,46,381,187,305,328,755,262,931,343,113,20,245,224,335,802,630,382,12,323,867,640,175,123,912,736,981,371,574,12,532,328,693,2,370,895,145,403,551,534,240,100,729,305,597,343,303,458,503,288,237,389,0,785,532,196,233,290,69,745,181,16,761,876,976,558,752,870,715,742,412,660,396,401,161,814,690,303,193,580,100,968,782,520,223,241,438,148,434,612,319,5,970,559,14,338,577,801,775,119,537,537,940,698,918,231,4,369,465,278,114,41,630,266,460,845,710,947,883,194,737,680,289,655,466,716,767,50,353,158,529,927,231,74,912,29,546,949,826,282,424,201,63,28,360,937,218,699,972,478,1000,307,956,988,982,251,114,969,563,977,939,435,850,323,102,762,987,653,104,14,310,711,565,201,144,570,386,319,237,197,544,755,652,992,187,478,541,39,464,976,774,805,421,374,385,29,244,420,734,297,451,422,453,327,941,864,641,673,726,928,910,411,97,571,229,482,349,565,222,366,126,166,515,403,795,319,307,39,261,680,175,420,318,186,991,586,835,800,152,346,276,314,40,11,495,183,886,536,5,232,4,731,706,868,432,881,587,141,262,258,336,788,378,975,375,756,277,940,320,768,459,812,837,269,760,55,654,683,812,510,443,841,381,891,575,451,689,563,218,588,39,477,60,728,664,489,501,532,560,321,206,523,773,541,787,970,271,770,530,225,1000,697,714,579,625,167,716,775,63,717,951,480,279,425,222,189,191,832,121,295,666,161,365,804,502,904,299,502,872,854,918,32,905,754,963,418,291,75,940,845,524,865,161,479,342,27,324,777,206,844,883,915,270,208,392,119,496,450,465,513,952,722,889,576,34,741,703,282,48,846,627,141,327,833,951,640,80,931,628,901,519,86,481,72,63,582,592,389,835,428,127,183,186,716,645,96,693,413,167,19,804,690,473,694,434,598,488,433,710,18,740,124,207,726,180,980,952,659,930,624,151,269,600,101,205,659,151,95,616,330,696,377,225,254,640,527,917,662,703,117,927,951,625,770,189,445,721,368,417,345,946,346,459,87,379,404,787,650,334,551,964,361,11,680,737,360,866,882,165,845,96,385,273,702,164,676,940,191,690,37,265,362,607,812,589,832,277,535,661,573,625,170,24,917,139,592,908,855,152,481,615,773,582,103,512,145,371,594,129,446,615,533,194,660,694,446,907,330,282,681,508,720,802,401,987,27,40,875,177,717,99,541,739,691,513,887,771,327,500,300,761,569,469,872,259,86,17,449,734,342,887,348,968,767,675,667,468,215,503,304,996,6,289,417,526,923,665,181,160,411,912,735,779,620,856,919,978,580,394,430,220,436,167,474,801,902,233,145,109,229,607,852,891,942,723,66,38,723,806,218,623,722,508,264,399,806,112,285,582,881,460,208,405,103,617,388,303,238,442,259,480,442,182,874,996,36,963,517,601,574,325,210,671,18,541,384,927,49,70,788,193,723,441,434,262,842,685,765,407,305,217,442,967,134,651,829,976,651,300,924,772,120,433,985,842,410,447,598,387,257,322,653,433,357,40,468,183,542,617,869,824,635,380,4,581,592,213,658,974,92,605,740,702,686,432,581,549,848,814,272,512,202,36,691,94,623,71,73,845,425,462,667,210,877,613,709,588,474,520,463,928,177,526,300,647,745,295,703,408,890,855,481,513,364,863,505,104,268,793,819,74,21,772,14,555,365,695,965,905,7,972,128,924,641,832,918,688,17,297,643,599,957,961,465,710,495,959,415,176,156,825,413,428,367,598,636,64,726,269,364,844,242,711,120,959,317,139,538,584,791,801,550,870,816,767,749,381,250,444,675,397,816,245,323,594,207,765,731,678,348,172,343,517,148,904,530,590,156,890,357,390,624,373,498,798,804,21,360,561,883,942,484,724,457,659,16,669,3,730,841,632,273,872,424,123,117,24,637,133,690,150,112,833,901,752,111,462,319,849,329,836,377,703,863,919,282,274,852,131,916,644,532,269,135,683,815,379,129,582,377,985,765,470,427,339,412,235,244,180,270,163,20,363,166,833,284,800,71,61,656,596,357,362,13,904,902,712,561,22,976,238,963,745,912,961,978,643,956,746,531,725,459,531,144,741,532,230,605,944,79,459,531,542,348,271,405,960,322,295,825,825,893,866,921,234,371,109,889,583,171,361,522,74,726,495,176,703,618,741,455,998,765,671,777,923,325,874,938,876,981,268,677,83,988,484,289,896,32,950,867,743,280,501,923,248", "157,813,539,383,836,779,264,285,738,521,797,879,637,714,818,509,450,274,640,558,585,434,836,513,727,901,368,677,658,48,232,296,767,517,633,274,948,486,719,611,875,736,359,788,94,577,427,932,31,41,664,135,926,804,651,340,702,785,0,143,458,78,679,687,713,746,498,680,280,15,985,569,53,289,244,846,563,150,528,69,31,618,387,557,799,67,926,332,918,585,473,673,690,673,873,632,310,31,326,811,128,758,878,279,608,676,90,920,35,667,980,345,523,166,903,746,456,369,438,949,202,442,676,163,157,722,949,623,425,479,669,902,277,866,356,214,996,704,649,933,669,605,814,492,403,37,985,213,796,699,547,279,897,451,613,305,914,744,681,30,451,633,358,173,1000,824,160,187,770,720,510,373,629,818,486,526,803,556,424,880,303,925,880,353,166,948,910,6,627,541,797,308,103,708,910,423,208,46,606,399,671,864,233,218,812,753,765,815,516,521,779,843,640,515,157,43,564,251,732,151,641,271,816,689,352,964,229,172,579,894,756,763,25,18,241,621,344,899,391,412,770,860,543,209,185,116,377,703,702,403,387,845,285,113,349,41,380,48,779,558,678,266,987,139,953,255,564,850,29,103,319,807,180,57,256,935,71,830,766,360,81,890,44,48,988,19,951,209,925,815,465,680,463,171,443,413,909,940,135,698,759,82,96,884,447,638,773,337,618,978,964,502,947,143,526,805,615,315,701,146,610,806,511,147,485,6,699,213,343,28,184,827,692,415,608,673,978,725,104,107,821,169,120,432,147,101,373,688,848,697,993,106,502,332,399,699,258,208,464,710,499,983,986,683,547,17,486,41,544,812,903,212,286,999,608,905,135,59,652,650,118,177,524,580,441,682,165,378,882,517,961,94,388,844,68,179,780,412,50,21,872,430,109,948,505,973,918,437,14,982,566,196,697,749,857,669,49,470,132,456,920,319,153,740,940,404,363,193,493,11,198,950,505,367,534,464,130,736,145,487,270,248,323,77,11,827,62,749,428,828,547,878,169,28,221,384,652,32,469,966,677,952,656,548,140,441,808,420,558,18,415,906,194,365,883,94,674,721,956,354,92,126,707,154,986,301,238,961,463,303,946,492,716,681,276,383,99,24,3,682,469,569,587,221,856,527,379,905,998,971,71,909,803,527,721,952,239,70,339,230,933,450,142,788,937,571,14,91,571,794,164,425,311,34,726,876,938,896,653,94,336,331,376,517,46,983,699,93,290,52,127,872,552,874,720,311,913,912,393,921,94,550,397,536,364,227,1,777,442,527,334,106,361,895,876,101,78,337,531,255,679,67,107,27,135,272,208,941,150,296,951,821,13,855,347,348,475,515,617,187,453,484,838,822,112,75,786,152,955,918,765,404,948,912,874,392,771,162,740,566,704,71,923,852,305,397,407,928,608,150,289,947,786,918,302,814,308,417,379,878,166,625,560,17,846,259,342,551,137,452,295,137,315,291,888,680,761,726,723,960,632,860,993,236,86,831,676,359,899,406,477,983,89,386,929,295,713,473,640,220,670,726,826,716,320,419,136,436,867,357,557,512,887,843,441,130,81,672,711,609,754,387,162,494,958,475,651,502,537,814,202,499,299,393,590,961,773,483,27,28,10,716,313,653,514,569,701,16,893,855,213,342,499,280,833,59,920,182,554,195,836,125,956,730,354,36,166,64,240,701,271,66,555,322,861,724,10,831,305,797,550,782,941,807,257,804,645,643,460,156,368,233,44,49,68,4,372,476,134,470,423,280,610,255,382,825,328,722,91,338,766,777,286,968,952,175,265,926,877,152,15,832,645,823,587,431,881,830,380,987,234,955,33,825,88,400,502,645,940,994,400,932,10,466,811,696,312,235,348,342,34,592,288,637,49,275,243,295,210,324,114,562,472,920,227,966,409,78,135,146,462,128,482,480,91,266,658,287,278,706,789,925,81,234,868,851,719,124,238,787,926,135,974,980,758,734,120,869,30,551,974,484,827,482,111,611,918,379,676,660,511,458,563,914,364,611,253,307,288,986,133,830,932,640,916,303,536,914,953,452,908,724,810,354,549,917,529,18,318,806,722,977,233,157,624,597,958,20,775,331,43,276,612,791,134,749,203,657,660,884,1,462,508,606,851,858,124,969,13,500,334,224,172,850,605,927,469,70,489,292,839,759,956,405,424,30,151,757,820,626,83,601,683,789,202,789,726,48,834,220,116,2,54,465,842,240,251,866,319,340,869,566,604,518,645,344,942,898,67,232", "770,730,565,658,911,556,139,492,930,745,300,204,281,44,8,431,955,827,155,419,207,265,308,915,210,265,168,690,25,14,567,286,882,993,805,333,617,424,23,451,793,685,786,167,452,446,343,68,626,405,102,927,37,944,186,118,97,532,143,0,474,892,778,882,708,395,346,463,227,841,694,961,10,49,672,399,236,928,71,180,473,892,306,831,264,29,999,763,361,632,201,213,153,805,974,866,539,707,391,398,151,192,917,7,480,743,833,550,700,76,330,951,566,957,872,530,749,306,570,98,706,85,929,659,440,155,281,849,927,539,547,255,419,187,494,54,144,326,924,665,858,450,500,945,652,65,639,161,24,853,336,434,858,166,199,835,978,404,247,17,708,443,595,916,410,122,444,446,408,586,901,837,837,345,101,284,373,148,382,192,489,690,979,340,702,940,449,585,550,879,770,639,867,840,264,376,6,235,726,376,32,470,633,269,996,550,587,183,730,856,18,149,361,11,718,303,840,219,20,933,653,790,541,869,197,544,58,305,79,289,223,576,572,944,536,478,594,922,233,344,512,724,78,639,170,540,884,84,778,79,743,144,453,898,690,241,409,738,836,389,549,893,216,675,498,452,438,919,594,886,711,391,831,884,18,407,585,236,688,215,299,652,25,739,890,939,66,742,720,541,513,735,782,370,170,511,54,683,771,313,861,67,1,81,293,507,515,683,133,148,497,599,688,950,561,194,587,297,526,847,506,452,104,132,972,934,438,501,628,694,744,366,299,12,306,770,507,679,860,349,525,895,677,47,158,61,91,261,674,175,629,166,459,459,580,621,990,31,665,645,920,240,297,166,610,219,784,882,184,6,993,640,18,294,126,442,286,169,597,458,935,440,156,34,650,205,982,338,947,679,348,251,642,100,658,725,286,775,645,46,677,473,186,569,98,590,143,912,198,15,382,543,125,994,166,95,206,887,823,373,321,455,571,759,265,161,507,476,448,655,145,956,634,92,636,303,461,723,689,43,836,28,443,921,286,664,68,429,398,218,907,171,22,292,367,48,706,293,861,618,679,503,309,443,788,639,720,866,62,748,583,505,851,376,266,621,542,590,629,389,957,101,666,724,61,666,437,685,833,44,738,728,83,930,28,550,622,657,135,26,335,570,985,702,69,854,395,709,202,841,260,606,442,290,536,589,310,494,617,837,986,914,282,679,391,80,125,699,935,406,408,574,313,848,227,949,587,986,597,409,626,789,174,124,390,808,373,177,158,979,631,530,264,253,567,880,804,911,544,649,288,59,454,228,641,738,592,964,861,445,806,951,880,819,526,150,539,448,245,669,111,490,925,52,65,797,608,396,247,37,839,525,579,409,739,962,766,409,355,200,462,947,678,954,833,605,531,537,227,440,706,108,395,555,881,556,747,28,263,536,652,867,231,120,658,333,517,336,906,272,318,904,127,651,256,108,453,951,745,980,486,246,138,770,701,614,14,686,593,503,410,994,304,984,535,648,84,50,703,528,639,155,400,378,864,862,836,654,891,997,112,21,541,360,701,239,749,170,74,327,171,672,374,711,640,776,875,832,918,418,903,209,503,930,274,569,300,422,684,244,165,505,901,102,998,72,547,504,309,67,157,964,822,184,879,513,596,769,728,38,739,162,782,575,777,159,73,226,408,527,717,731,112,32,137,199,129,522,978,505,159,496,366,795,442,369,750,57,382,271,197,777,223,749,672,133,411,151,682,843,675,514,163,676,872,988,236,751,244,703,998,765,736,613,561,100,817,81,34,35,469,819,953,62,865,888,833,73,245,31,381,428,173,599,698,633,202,658,244,551,779,98,425,368,16,861,818,688,914,898,937,908,473,571,59,205,401,940,866,620,518,510,65,828,691,941,802,66,985,475,792,833,49,993,892,630,369,234,987,896,546,733,236,374,873,473,388,439,963,967,835,420,728,898,81,304,148,924,607,848,700,314,965,228,351,837,974,672,351,509,248,932,497,659,22,690,504,437,491,956,145,110,995,50,265,720,391,158,662,131,520,431,691,307,170,859,402,420,614,621,845,237,148,943,207,656,748,329,189,61,29,841,369,265,358,645,948,138,498,555,588,311,936,253,293,352,928,111,343,887,250,814,440,194,285,770,268,213,498,327,348,22,916,820,110,330,821,361,723,16,743,338,776,319,132,482,779,879,891,184,798,256,256,184,109,562,986,385,781,216,828,895,374,174,91,570,830,490,15,951,154,121,508,769,97,795,583,799,502,649,530,360,652,332,788,288,468,55,571,469", "29,589,562,89,443,782,974,768,945,991,43,434,979,118,865,992,448,124,46,182,301,90,277,810,537,581,156,544,157,777,492,786,808,519,541,241,440,981,701,992,422,678,574,73,300,911,591,722,434,468,343,358,841,606,9,864,475,196,458,474,0,791,289,974,149,803,336,442,841,606,101,621,223,780,507,550,948,226,847,820,671,305,898,191,253,860,864,652,188,85,573,33,521,341,275,682,697,830,840,928,603,740,311,26,8,40,154,952,387,712,211,645,321,749,128,313,142,513,590,839,453,376,659,954,989,346,859,269,978,470,738,815,818,264,490,418,411,939,842,240,849,430,735,475,377,300,149,830,710,577,574,535,923,772,253,902,306,657,561,137,842,603,358,40,282,102,813,684,227,268,595,387,453,75,798,379,404,226,268,525,553,79,92,153,310,797,36,523,495,88,353,521,370,545,778,318,504,946,428,707,711,612,85,81,571,91,818,344,916,724,356,520,863,77,633,446,606,867,312,884,805,358,243,22,888,986,405,332,989,912,80,274,441,727,416,7,783,925,398,65,885,763,419,660,373,769,768,452,887,414,301,202,34,240,984,800,192,44,178,743,112,576,988,924,597,684,681,146,778,612,342,667,336,842,797,943,943,191,739,897,815,269,166,4,108,87,992,781,186,279,121,534,291,10,942,855,140,347,280,316,908,826,125,374,308,116,899,527,913,524,25,965,164,702,362,778,159,859,728,494,473,893,400,916,668,409,57,437,426,570,914,894,468,66,673,391,297,913,149,158,118,514,866,280,105,495,594,718,732,849,99,398,393,240,575,14,447,94,513,359,615,602,633,578,152,828,19,965,623,212,301,199,849,257,306,786,241,434,982,311,795,947,249,764,4,835,48,563,574,611,951,370,769,877,750,87,181,601,638,703,474,905,808,116,450,676,873,258,575,687,404,277,693,924,187,725,334,854,210,579,339,884,282,336,653,432,627,906,13,791,542,494,688,298,887,132,103,611,905,246,406,254,696,418,921,310,395,674,978,776,777,374,982,395,523,149,933,657,400,559,842,29,525,162,867,872,383,738,32,37,814,833,489,788,15,927,979,932,170,249,323,994,46,208,376,890,322,241,181,874,855,475,97,246,816,99,407,996,759,477,293,264,428,438,904,16,260,600,944,452,330,68,645,180,151,93,115,811,962,375,113,456,634,320,119,679,3,327,678,589,410,347,477,17,138,351,108,240,770,65,327,704,126,552,470,887,304,505,885,850,250,400,354,464,500,150,647,971,496,98,289,450,182,167,76,604,434,225,875,790,192,457,896,932,558,250,893,982,941,47,738,512,300,745,684,634,264,265,632,676,730,880,187,142,704,383,255,101,195,363,900,235,549,524,259,835,961,983,97,771,253,50,662,880,309,582,308,493,216,166,194,889,610,899,799,735,506,482,103,373,711,71,503,744,765,229,9,74,154,304,130,563,271,938,449,669,431,569,957,53,541,879,446,351,283,531,752,578,332,527,513,593,996,137,637,603,308,839,341,850,797,43,803,96,635,111,549,481,108,865,649,878,191,707,352,214,43,883,430,917,316,230,580,944,65,875,503,358,665,92,528,29,731,252,87,586,462,730,475,484,208,91,552,144,528,272,364,328,440,848,909,163,329,681,259,122,34,291,311,570,860,521,187,685,566,201,882,761,293,722,434,883,597,538,173,369,725,760,604,350,552,944,464,8,280,188,59,182,308,345,675,284,891,54,368,938,166,600,15,968,389,364,718,286,946,223,307,183,387,571,996,448,183,411,263,497,405,784,196,576,211,526,853,657,287,115,262,114,785,860,254,674,95,245,494,134,390,748,430,830,941,768,590,118,477,278,896,500,737,490,303,528,968,648,415,624,552,79,143,241,591,746,681,455,361,759,197,15,59,336,663,515,736,407,964,503,854,549,863,693,323,798,648,948,479,51,740,384,917,685,955,953,560,385,787,443,790,623,366,120,911,598,181,919,42,147,6,691,915,874,669,110,499,632,271,464,717,672,945,320,937,631,20,645,8,546,957,392,269,73,986,98,49,843,84,181,401,567,338,959,860,860,459,731,392,333,546,307,413,458,784,859,735,924,567,415,786,779,985,406,966,17,830,358,102,527,831,892,353,711,834,557,534,654,465,78,101,619,888,662,802,609,605,431,92,525,662,841,461,744,619,516,824,268,959,560,511,286,960,489,991,341,850,307,181,915,545,831,104,881,536,930,317,579,250,923,301,296,574,979,576,931,440,165,448,186,299,796,128,342", "97,978,424,188,87,393,339,785,404,195,899,514,87,891,416,697,809,507,208,611,445,699,187,455,641,739,661,857,550,968,30,838,573,46,909,510,43,809,861,42,661,902,682,421,576,730,541,984,987,844,365,213,201,503,900,315,182,233,78,892,791,0,234,465,805,969,292,980,982,742,792,352,781,175,682,857,549,758,270,740,76,280,471,374,415,259,524,635,97,241,677,866,824,905,667,952,341,224,66,229,902,333,837,99,49,565,893,817,58,819,769,1000,273,136,478,373,948,908,807,788,722,477,588,432,56,8,245,347,926,80,734,78,553,238,860,248,653,229,852,873,110,123,267,781,621,949,368,667,36,339,692,374,513,388,14,383,918,908,462,80,877,144,111,306,692,334,357,239,873,901,691,97,783,815,688,208,842,25,583,574,92,284,724,62,836,946,834,400,761,37,119,272,647,442,814,679,765,712,348,756,299,758,110,968,570,518,504,998,682,297,339,487,53,107,629,562,856,450,122,64,48,768,190,332,131,562,450,484,834,318,63,245,745,884,963,714,688,83,901,181,848,957,894,561,253,119,113,105,498,262,223,787,191,971,153,9,534,112,247,964,702,542,694,997,11,575,896,230,345,76,341,714,375,104,341,201,914,653,155,71,709,604,658,575,739,382,359,582,538,691,547,468,588,300,106,519,775,277,517,160,480,118,945,363,249,989,539,997,132,264,515,605,741,578,213,675,202,63,868,998,534,143,229,55,340,687,460,410,468,251,804,124,93,529,491,667,69,174,48,671,58,878,182,848,720,671,327,606,453,832,768,926,196,928,889,463,558,248,92,338,243,13,626,990,482,456,621,772,863,476,245,19,645,843,92,614,99,959,904,51,763,753,864,159,412,322,543,812,990,336,822,626,69,654,63,513,806,575,613,350,368,349,133,352,184,583,543,936,145,71,698,966,271,212,638,544,84,406,349,532,348,898,687,382,954,926,477,5,34,313,460,119,112,563,554,458,329,371,247,316,938,668,102,690,46,363,258,600,159,38,219,167,282,159,13,393,304,590,770,375,958,977,284,921,576,406,209,734,727,987,425,846,131,253,393,682,609,838,450,312,795,385,865,73,714,256,464,280,469,181,824,323,729,405,494,667,451,168,323,743,305,439,593,21,886,702,820,764,806,469,993,584,124,294,408,59,290,267,451,530,589,753,613,497,631,652,832,648,645,33,476,665,715,613,446,548,57,746,326,118,903,358,377,44,105,165,24,779,660,609,691,635,265,87,304,373,60,256,437,134,199,349,704,890,710,534,985,602,870,305,846,423,771,603,893,252,596,339,566,348,712,518,842,759,11,947,437,250,510,410,823,552,181,357,911,546,366,225,179,669,268,479,230,24,700,426,887,536,990,935,816,471,908,681,304,915,793,220,837,654,588,721,248,801,571,258,853,772,164,322,474,314,80,750,264,945,884,485,428,29,920,889,826,322,512,735,90,834,5,206,723,526,592,921,903,531,809,636,441,726,640,507,656,138,305,58,152,410,454,423,4,429,86,669,151,181,746,888,293,969,983,977,696,643,155,992,721,994,557,291,71,791,638,304,366,518,687,929,530,656,86,863,314,383,713,134,720,110,90,594,276,421,908,819,607,431,300,547,340,904,273,799,426,70,911,951,365,171,644,576,210,370,214,143,408,892,555,35,921,76,367,900,72,998,602,821,952,410,503,63,856,47,902,70,671,74,546,869,891,577,508,358,817,827,37,298,542,372,237,80,761,329,420,590,87,132,23,36,314,800,290,296,271,316,553,2,445,256,918,873,877,954,746,473,980,346,47,976,350,441,186,526,26,171,730,208,645,380,550,7,348,277,247,384,375,931,270,608,592,860,901,505,388,353,41,539,848,804,559,990,32,818,191,181,578,350,692,23,88,277,802,417,269,121,743,625,924,513,953,564,76,464,601,892,679,805,266,850,4,689,70,277,779,92,645,848,11,81,676,527,634,713,538,4,105,840,814,82,906,499,165,372,858,816,695,876,407,651,912,866,158,323,248,898,524,574,190,38,956,208,427,745,984,899,138,876,427,22,488,777,260,149,976,555,765,561,399,25,35,476,965,745,924,982,513,900,493,424,967,194,881,293,341,246,566,469,338,635,353,565,725,222,401,382,367,322,188,320,593,633,953,940,347,786,613,42,175,976,976,374,414,905,652,332,688,353,857,366,226,579,212,754,298,6,962,789,75,138,20,7,435,148,899,795,644,755,85,2,378,423,68,616,992,164,721,948,766,82,111,863", "229,214,973,122,176,576,715,292,533,227,845,32,554,255,795,80,805,726,705,5,390,838,821,175,54,891,579,607,202,274,241,389,42,217,534,709,730,67,760,846,77,215,838,90,642,121,42,385,994,833,762,286,449,596,286,648,555,290,679,778,289,234,0,712,545,46,26,566,549,393,476,824,79,281,471,847,614,977,742,537,463,94,242,423,60,657,177,566,584,830,849,879,659,451,334,493,529,234,837,970,913,312,195,637,18,156,11,913,15,907,844,825,672,180,969,879,609,894,246,662,317,630,920,798,343,492,957,707,194,475,680,990,450,338,374,768,96,649,610,597,612,898,859,502,420,39,144,290,302,797,837,442,90,54,514,250,932,951,500,882,13,497,994,568,194,252,687,298,174,552,78,419,117,431,227,306,399,139,538,694,598,816,877,166,953,738,334,381,613,428,794,415,381,401,743,645,904,468,427,141,16,995,878,439,707,944,721,880,906,771,682,864,136,648,674,27,817,901,892,501,797,267,34,964,589,289,842,359,60,980,671,881,330,882,916,688,807,613,83,444,24,325,969,230,853,747,350,758,724,664,287,900,474,91,235,879,557,499,601,891,494,387,977,513,122,78,725,800,52,266,621,87,527,37,375,635,333,268,656,727,262,708,642,611,600,136,600,408,658,962,627,992,660,158,987,90,493,234,737,866,61,193,847,916,813,145,697,458,924,968,331,872,174,330,485,403,856,130,397,245,894,808,629,270,660,884,365,718,304,176,996,657,156,611,586,862,813,484,226,629,508,870,450,454,117,138,468,691,264,155,895,593,464,747,414,481,389,880,833,46,305,496,858,834,561,127,158,95,636,183,776,553,858,548,635,957,653,123,352,824,545,252,58,460,996,697,329,250,906,632,606,844,337,277,399,488,726,456,81,316,139,377,99,549,864,838,69,104,830,409,376,681,991,582,347,422,380,928,307,268,231,980,490,886,453,300,454,273,403,634,697,504,221,668,576,644,43,556,275,696,46,848,366,357,416,504,122,282,580,714,893,108,776,799,734,807,998,319,18,748,544,812,557,409,141,984,209,434,234,955,788,916,137,739,596,642,597,147,55,266,198,253,295,427,134,369,196,867,470,179,705,173,874,199,692,380,575,307,44,925,286,134,997,111,80,759,819,218,857,805,196,644,442,55,877,386,329,770,377,986,39,385,320,162,695,87,102,343,483,905,280,24,646,516,460,744,244,399,78,781,202,818,216,148,421,229,29,926,22,633,801,942,970,510,890,182,103,490,559,46,719,442,773,767,804,194,297,81,760,490,953,522,614,843,68,416,286,150,687,719,361,746,23,967,86,150,25,709,304,522,559,946,821,526,548,640,763,206,833,542,467,278,231,544,536,746,258,750,122,840,622,471,18,481,657,925,297,111,263,501,688,129,980,990,824,564,339,12,232,828,649,86,9,317,890,566,944,543,84,517,322,73,329,50,504,942,594,227,14,658,284,51,738,391,717,893,870,217,616,583,759,581,46,302,71,149,271,992,446,726,327,471,417,291,432,102,726,937,646,602,847,873,564,75,414,289,759,930,913,91,136,220,946,641,751,345,256,349,564,887,761,653,42,422,260,819,583,790,756,884,464,687,505,442,562,776,634,399,491,147,561,844,219,905,294,345,283,383,533,929,456,62,950,225,86,821,435,895,426,599,563,712,926,22,640,812,266,589,529,69,552,857,580,894,132,859,495,418,189,324,356,269,901,842,499,565,818,77,575,563,38,87,602,66,36,96,581,204,28,582,538,120,322,884,760,933,211,549,144,61,802,470,867,873,755,715,419,9,509,351,731,44,134,448,754,829,402,255,137,284,638,816,399,256,314,62,609,621,608,491,35,450,137,23,413,354,519,304,25,213,175,952,774,972,115,846,356,637,295,236,546,109,240,545,205,636,501,122,688,601,979,861,27,530,927,560,701,737,760,379,806,211,673,991,932,870,528,710,369,856,953,999,61,742,695,158,552,856,163,936,382,505,955,974,99,872,480,551,832,951,496,736,909,592,912,256,594,122,884,298,425,312,34,819,785,960,205,127,600,54,566,142,70,567,690,165,51,69,984,988,331,338,101,658,270,327,596,375,747,220,434,758,613,269,940,552,828,967,929,84,342,475,171,418,457,768,705,131,728,835,397,670,777,606,692,770,153,576,603,349,857,419,799,486,132,704,309,193,174,369,881,567,647,475,82,151,218,64,610,386,111,92,521,615,530,961,748,826,171,625,692,331,638,118,382,20,923,53,273,439", "734,629,187,919,376,675,810,660,218,791,307,906,476,22,542,283,954,978,846,695,678,363,18,3,493,25,260,617,615,799,888,175,862,328,304,631,703,431,289,387,655,835,848,402,695,10,786,833,786,882,658,258,112,459,411,709,966,69,687,882,974,465,712,0,739,89,31,583,342,766,330,753,614,371,646,418,50,260,811,127,182,446,71,913,538,225,789,357,728,51,758,732,22,89,820,376,600,610,91,6,163,365,546,569,448,195,574,259,557,91,44,2,916,523,369,321,783,24,670,699,985,414,959,751,196,538,556,593,310,321,361,985,620,479,283,681,436,8,585,383,948,417,492,906,218,533,332,878,185,603,400,543,798,232,325,45,391,833,27,314,471,276,403,659,87,496,644,697,154,878,141,711,822,924,27,944,106,620,809,530,92,899,632,955,22,856,599,254,38,98,787,58,132,737,374,310,612,550,802,240,121,314,682,618,473,911,395,733,139,599,424,986,358,308,593,969,167,560,82,322,386,513,9,696,923,549,992,827,670,756,439,203,312,566,170,848,911,387,238,484,707,553,554,457,860,981,452,597,299,262,587,796,114,553,808,530,171,204,914,333,462,440,569,742,825,170,860,593,318,784,386,918,649,145,327,279,97,478,528,510,819,78,563,151,724,143,549,67,646,323,700,87,139,460,716,123,926,801,638,652,955,129,143,542,327,336,196,464,432,952,556,129,199,137,555,499,612,612,846,316,665,64,825,118,448,106,945,864,32,753,155,5,810,449,761,374,925,712,578,314,339,612,296,878,861,213,260,419,369,75,304,460,952,273,519,290,311,429,733,202,875,867,918,236,483,345,38,572,272,864,425,486,186,938,295,579,574,866,356,169,897,809,167,289,383,68,236,96,552,701,710,97,461,8,402,866,880,642,920,707,889,208,260,749,563,590,361,142,601,256,811,567,679,58,404,981,23,659,28,815,386,855,131,261,787,197,254,827,572,666,575,365,305,361,280,440,659,732,615,66,511,494,120,248,678,504,476,956,910,924,742,90,49,890,434,537,327,90,579,886,228,377,606,18,136,798,138,747,857,925,683,465,529,739,32,334,487,241,904,6,744,700,851,5,874,865,515,45,186,154,326,206,214,668,354,732,468,563,862,512,182,272,787,90,726,891,637,875,959,388,691,318,541,191,888,23,602,624,929,866,300,426,638,415,379,826,226,671,794,980,624,459,900,495,42,844,359,543,109,137,100,429,480,928,545,858,369,707,526,809,700,968,149,853,778,425,345,938,581,889,330,484,377,86,671,970,728,726,548,558,97,798,34,834,934,787,890,557,680,12,773,489,878,384,614,623,333,152,675,746,776,3,417,751,803,531,684,45,196,537,295,641,425,570,677,194,658,449,351,241,660,893,631,91,92,330,296,488,754,713,989,144,247,34,673,277,386,415,310,787,930,592,450,652,486,664,970,701,317,230,704,397,162,496,579,460,133,348,826,980,112,993,69,387,328,28,972,67,469,970,242,29,62,959,269,378,606,967,443,329,607,357,947,486,201,653,305,445,461,887,630,462,944,118,211,337,587,333,736,913,505,340,781,163,658,547,146,702,243,688,19,196,587,719,241,77,66,582,30,669,853,382,962,255,348,351,890,310,201,897,346,169,595,596,281,80,67,65,441,319,450,282,695,422,620,610,181,602,927,947,450,388,949,223,357,605,182,250,440,102,790,472,123,516,174,159,317,366,596,81,855,11,861,61,14,512,340,986,842,676,900,112,22,847,574,645,329,593,503,899,149,130,173,109,312,262,863,88,593,915,857,778,647,987,130,85,138,422,755,199,934,894,149,686,63,250,635,670,135,479,846,724,732,75,11,743,254,350,498,240,543,712,245,652,565,862,48,185,643,561,667,100,812,961,753,984,945,667,910,147,410,165,116,245,297,236,937,615,421,183,983,380,957,179,711,50,228,609,190,828,336,990,259,913,289,214,303,943,445,868,261,29,265,705,568,865,330,679,904,686,575,618,868,473,643,110,815,970,558,877,332,882,191,11,615,66,664,446,15,585,252,172,665,728,64,719,576,663,364,399,328,495,437,898,495,318,672,895,152,669,707,632,976,311,101,882,825,117,906,271,365,65,190,399,367,235,434,402,881,901,879,638,517,500,747,410,783,4,953,372,367,821,245,79,568,642,59,522,235,140,201,279,797,169,879,643,716,874,329,86,124,748,378,134,486,345,399,102,715,491,863,925,985,83,64,279,762,551,181,998,724,337,782,546,13,190,272,163,607,446", "829,781,553,600,531,456,819,971,244,853,420,660,847,446,26,626,160,615,944,103,550,740,426,589,515,734,273,767,371,314,678,673,473,427,818,550,481,167,366,568,499,136,727,435,641,666,982,142,590,61,710,314,87,776,567,634,340,745,713,708,149,805,545,739,0,808,797,627,19,445,180,328,617,876,310,901,870,922,11,738,770,914,728,195,986,869,457,253,698,536,710,600,594,966,967,381,729,5,209,745,93,86,155,492,143,117,864,902,479,842,215,399,249,326,697,410,58,578,467,450,275,955,520,18,365,803,861,240,133,74,51,872,617,317,385,231,996,279,751,857,635,994,255,386,83,124,545,585,979,27,122,245,84,376,727,389,169,939,26,9,113,917,1,27,132,472,939,246,334,184,928,343,179,406,330,844,574,798,373,9,777,505,355,907,641,714,13,397,742,600,190,941,820,336,19,319,607,576,349,254,923,947,590,175,551,106,509,440,69,131,297,569,198,601,680,191,209,371,41,847,104,945,329,971,872,467,374,37,760,197,114,343,404,101,814,223,505,7,419,792,954,971,779,759,331,24,579,251,713,321,972,583,690,706,373,937,1000,678,413,242,4,941,625,204,884,372,985,696,4,15,983,551,984,632,352,745,122,667,957,13,769,35,539,288,396,707,7,775,365,410,2,351,127,998,415,108,954,693,523,877,640,63,383,354,71,772,772,607,120,398,765,82,590,170,650,441,238,995,993,717,610,564,350,246,850,815,181,230,554,392,685,450,180,129,92,86,914,91,298,352,462,111,182,116,802,59,139,68,62,504,603,8,931,549,663,886,730,789,818,938,556,301,83,208,692,896,331,46,553,722,687,756,990,504,723,6,906,879,877,32,772,154,39,321,111,227,67,366,462,212,29,986,741,976,209,115,992,136,478,637,757,930,57,505,784,213,735,707,910,915,163,896,710,7,651,870,637,151,967,712,248,791,47,364,453,359,865,303,979,450,901,884,759,10,863,260,235,119,454,134,681,771,520,369,580,770,163,516,58,44,194,842,923,987,425,306,210,114,387,345,283,632,406,769,676,143,457,75,890,192,73,548,574,815,612,365,717,779,191,984,747,313,709,55,917,409,852,858,210,78,904,757,943,278,488,386,930,926,472,3,528,157,245,766,754,326,747,907,35,624,841,188,345,251,911,901,799,618,955,437,382,233,9,679,129,519,859,348,350,625,415,175,6,6,330,468,163,618,555,327,971,498,494,948,320,239,745,278,103,509,945,773,828,313,309,984,845,128,764,506,625,255,865,797,323,196,995,390,36,308,24,258,690,542,759,461,719,170,347,253,590,79,349,783,249,693,589,222,802,679,23,90,704,361,450,118,194,391,27,517,375,461,527,562,50,783,792,286,23,406,183,386,980,908,379,558,415,764,950,580,692,330,325,83,461,66,655,509,129,818,571,439,598,269,344,848,275,456,332,402,228,853,769,354,73,381,915,774,133,360,783,670,101,411,794,951,149,280,113,555,507,515,193,39,447,488,787,980,589,643,703,383,106,803,969,401,982,773,848,768,865,683,939,793,155,743,673,970,168,533,106,70,743,641,348,665,389,585,70,583,469,104,129,117,991,843,834,310,235,66,597,300,82,809,322,662,233,857,441,466,70,625,20,177,418,380,919,856,65,269,554,495,808,584,724,631,952,407,870,773,388,706,809,374,846,502,769,356,802,720,579,52,910,918,58,468,575,85,806,868,199,848,879,767,76,451,681,476,176,146,606,942,441,233,548,536,68,352,445,908,234,244,906,948,624,284,399,218,442,441,104,572,526,138,397,344,501,604,168,166,579,213,808,139,227,238,813,755,297,363,18,37,142,207,554,930,262,601,812,654,621,637,699,825,972,137,811,576,962,40,428,569,725,481,596,476,394,555,887,188,623,433,851,323,310,467,467,417,946,445,294,612,8,704,537,554,727,985,263,158,362,114,181,564,339,190,753,103,794,11,11,993,507,31,253,764,235,199,965,638,483,96,637,933,382,896,92,764,127,295,843,82,649,384,302,687,694,783,382,744,571,527,954,113,409,209,219,920,375,973,306,344,303,297,217,243,193,259,988,916,404,851,547,205,408,326,819,490,590,363,263,831,973,982,474,176,484,98,886,380,921,120,591,221,573,240,522,569,822,280,952,383,710,813,111,860,450,828,687,157,920,923,280,146,931,891,737,538,915,718,571,277,632,377,845,609,77,6,773,213,17,522,473,770,803,376,396,559,826,487,239,482,130,258,219,554,335,355,584,5", "324,358,859,45,656,939,945,74,681,739,634,831,195,569,225,159,645,539,668,414,584,377,800,602,412,46,700,644,574,56,871,803,453,435,730,340,131,780,519,305,786,218,170,989,548,706,982,311,488,303,988,313,780,297,180,385,865,181,746,395,803,969,46,89,808,0,405,196,872,53,810,342,341,40,31,677,390,974,42,361,27,624,334,893,32,603,38,414,588,33,126,437,142,337,40,161,737,188,374,215,817,33,532,37,221,738,37,77,498,519,129,809,396,904,92,642,819,199,920,900,47,848,2,564,416,123,103,955,907,745,929,297,902,920,694,47,703,285,905,226,977,449,73,28,173,403,620,459,175,227,52,173,37,67,190,54,751,944,813,23,128,458,988,340,853,317,456,55,538,541,309,465,466,107,16,847,675,551,109,906,119,971,551,615,943,450,617,175,900,639,549,386,39,350,197,552,322,14,383,904,173,889,443,312,163,53,129,636,289,395,362,485,934,96,135,393,50,827,660,460,414,88,253,796,501,437,67,662,968,482,479,285,954,587,479,312,983,667,366,38,291,333,818,158,201,658,546,915,427,737,744,612,694,482,303,540,84,740,442,330,812,979,976,12,574,887,934,135,526,349,149,957,399,891,429,496,178,488,619,91,965,669,294,561,267,13,414,419,551,784,315,767,34,591,284,263,489,228,619,684,729,697,97,324,696,715,386,271,251,17,29,186,249,642,241,320,836,624,809,629,538,552,731,675,693,76,831,734,680,821,468,916,307,743,142,465,551,784,80,302,546,665,408,804,738,134,350,429,600,988,527,827,279,197,543,7,223,548,828,714,251,567,578,413,272,600,901,333,993,429,995,750,936,341,261,546,66,726,995,682,755,225,422,306,106,600,603,199,808,329,961,187,403,725,300,329,635,825,676,133,545,938,295,438,652,458,891,900,38,702,895,748,758,719,769,248,32,216,498,972,701,783,610,753,757,734,426,707,475,568,119,869,525,455,652,695,228,381,409,878,218,895,427,363,825,791,655,454,874,790,791,84,711,391,242,294,921,650,549,908,774,846,56,69,633,334,787,22,610,814,682,504,312,581,16,988,318,331,571,909,124,650,880,201,554,297,439,285,978,550,723,636,692,188,617,949,742,594,49,826,354,616,365,662,862,488,241,895,857,436,268,813,55,751,89,415,446,579,626,871,787,862,625,162,54,324,141,211,420,728,104,695,182,865,9,871,645,439,561,321,752,452,103,269,836,1000,644,307,625,403,747,434,725,6,608,744,568,895,505,856,917,300,166,280,978,393,153,556,769,254,125,842,62,333,171,455,282,422,750,274,218,130,170,900,989,917,154,308,104,279,816,606,597,430,41,598,642,483,190,827,224,273,897,862,769,772,198,55,989,974,129,747,491,822,822,80,833,604,152,127,870,33,783,237,822,678,523,444,653,53,317,630,756,955,378,1,492,655,22,30,247,649,906,257,516,128,723,574,480,546,406,429,529,896,894,221,151,494,998,482,655,86,366,536,644,222,904,767,186,436,80,756,129,436,536,405,94,479,513,753,302,486,396,453,649,444,324,613,395,663,293,775,679,340,693,69,476,638,382,274,947,948,221,998,214,148,451,64,186,620,441,29,778,246,94,894,41,417,519,845,734,302,703,375,906,390,871,733,313,967,606,832,656,71,752,692,873,596,468,529,708,893,365,170,171,705,520,187,920,715,395,569,763,148,621,321,323,49,783,797,442,541,403,590,589,589,171,595,971,999,964,708,198,282,296,280,158,428,210,393,996,127,336,805,723,842,656,380,597,164,372,308,770,901,50,221,117,728,466,150,294,533,515,823,719,755,306,788,249,888,83,369,662,79,710,102,823,577,921,91,298,352,234,919,297,263,789,626,855,964,941,649,774,353,817,92,847,794,527,591,115,420,860,536,651,979,328,567,973,525,725,226,396,452,818,606,120,808,206,259,985,362,990,851,102,666,523,691,486,530,251,607,142,122,31,38,250,101,272,449,929,871,993,786,646,50,996,199,836,357,210,430,390,825,149,752,507,877,442,162,967,111,241,324,922,453,150,56,821,740,224,699,998,954,342,904,771,426,588,77,434,233,801,290,396,194,422,459,411,425,939,850,290,20,733,429,830,363,958,156,259,819,44,25,923,232,545,829,212,58,893,528,129,289,758,289,478,2,408,299,170,123,838,233,47,508,603,552,244,2,249,287,213,157,526,828,555,178,653,347,344,106,57,16,670,204,235,654,296,48,912,710,911,552,522,873,872,22,903,597", "917,941,381,473,959,788,897,410,924,158,460,705,19,488,147,963,63,989,919,217,783,333,223,871,568,598,600,882,461,563,753,246,891,133,355,107,94,782,158,771,700,592,867,509,157,829,776,526,994,311,143,386,969,349,129,641,99,16,498,346,336,292,26,31,797,405,0,901,681,982,797,778,461,609,445,24,668,1000,786,31,410,833,203,120,723,521,677,28,567,924,439,754,263,437,888,956,152,439,258,274,845,682,987,559,160,779,729,819,155,609,967,641,706,669,285,115,458,522,55,249,966,667,122,267,518,546,563,401,291,993,535,876,294,254,691,616,284,114,706,585,921,743,739,139,732,215,276,420,388,226,346,586,186,560,598,54,648,802,956,273,165,350,929,391,109,121,570,560,745,388,323,461,635,561,989,519,69,349,22,348,725,181,447,115,579,854,818,700,972,305,445,253,163,243,904,595,850,814,174,379,627,401,552,42,171,766,664,132,853,426,633,258,933,225,101,686,715,984,257,343,987,755,704,732,392,271,513,777,275,501,852,93,32,652,873,314,247,212,690,439,786,89,297,502,375,534,722,826,224,764,302,198,660,726,805,186,589,801,158,89,564,432,437,624,589,181,916,11,601,415,692,290,893,347,810,607,917,529,344,531,879,443,606,676,252,993,244,994,971,843,22,946,801,157,658,899,731,416,340,802,742,278,606,241,428,846,110,584,269,921,470,125,203,849,406,957,663,995,980,112,342,783,828,448,605,956,439,564,439,976,32,198,109,310,648,985,627,995,572,574,560,385,166,239,671,481,431,193,95,684,546,507,116,370,301,831,780,847,747,651,410,904,184,193,861,661,921,761,828,821,676,61,980,917,729,324,42,952,516,321,8,600,941,245,376,663,186,320,318,886,723,291,986,480,126,492,77,198,787,820,672,95,353,967,792,456,924,364,951,619,973,205,434,194,131,228,114,965,57,33,876,259,965,674,806,876,461,191,880,405,20,747,453,13,415,946,919,496,946,357,982,507,392,697,558,913,442,254,109,973,7,495,657,675,846,578,447,726,954,711,652,815,444,187,890,744,165,660,112,910,713,96,832,409,417,312,222,832,227,57,364,751,43,194,680,120,712,703,655,597,930,259,755,478,829,373,294,548,490,765,376,122,167,328,363,863,351,502,801,627,100,779,498,939,590,486,185,407,260,315,723,871,108,593,290,373,253,826,791,355,409,143,957,806,381,866,246,563,49,847,606,201,957,502,976,128,463,223,797,203,785,446,444,627,731,379,892,119,727,423,877,426,968,767,854,365,125,138,593,635,436,503,318,618,38,421,988,852,294,864,311,624,724,281,310,262,9,908,193,633,630,467,20,523,100,520,896,149,120,576,791,392,81,640,90,722,9,400,875,561,508,98,968,106,76,980,979,720,788,634,77,314,107,231,601,479,872,478,316,54,893,984,219,143,196,323,641,382,992,134,47,940,604,800,488,498,98,431,787,335,339,233,898,251,953,321,78,696,617,770,393,8,3,42,160,982,142,264,257,263,908,894,299,963,778,244,565,523,693,652,395,740,788,3,986,597,565,422,418,887,569,842,421,587,324,4,781,922,523,411,73,380,968,232,869,675,108,239,456,650,678,694,151,388,431,286,880,264,646,701,867,214,220,602,746,782,325,484,756,426,927,14,456,958,152,967,890,248,564,814,706,312,516,775,269,309,798,777,528,555,976,419,29,397,591,556,415,810,514,847,915,295,364,45,481,484,173,208,761,621,675,246,217,629,332,666,526,951,348,152,505,166,310,167,11,603,426,694,379,918,623,485,111,654,361,725,88,756,272,491,699,365,538,515,73,937,588,685,331,926,418,57,760,825,471,308,868,317,481,75,327,73,633,496,299,175,195,537,305,341,820,209,424,743,25,755,889,789,472,340,105,943,855,252,478,191,431,732,600,416,233,801,16,322,381,776,873,528,88,76,758,419,350,105,767,538,432,21,819,713,226,975,894,239,301,491,900,316,516,793,387,642,942,193,59,140,364,940,510,453,269,90,848,772,660,230,992,336,878,784,481,603,54,878,77,198,779,978,229,98,755,214,89,199,716,45,145,961,80,75,779,917,661,657,531,531,742,593,347,365,660,79,182,574,727,777,530,248,374,663,369,496,405,43,176,193,900,679,857,742,659,859,196,237,229,529,317,22,193,40,864,854,391,735,282,519,766,761,17,147,61,754,801,871,314,294,143,123,82,563,686,781,224,901,570,316,910,753,139,65,389,624,517,1,597,717,207,795,919,578", "380,962,51,37,381,887,607,654,640,898,995,293,3,980,801,640,139,338,230,81,111,222,405,700,605,521,204,454,425,488,546,587,955,32,644,628,972,171,114,189,126,401,525,423,42,350,774,407,505,633,26,345,761,623,469,168,86,761,680,463,442,980,566,583,627,196,901,0,99,973,768,99,49,130,285,432,649,634,199,608,892,124,598,771,776,991,346,21,817,628,631,866,240,494,698,524,84,656,669,941,532,383,606,291,487,676,276,622,680,360,192,60,296,860,907,891,980,683,410,870,635,749,279,427,186,250,216,397,365,393,108,219,223,446,794,78,197,723,490,374,139,234,850,634,662,85,882,951,22,596,268,18,999,466,681,165,172,212,507,740,123,109,302,141,28,201,973,885,993,241,813,322,290,181,111,738,68,426,727,147,411,881,9,551,109,370,873,168,576,551,91,423,241,605,399,321,110,14,691,849,588,917,350,115,605,282,137,950,314,872,955,958,463,467,306,686,25,824,150,24,875,858,251,128,789,637,171,521,763,165,52,556,847,362,586,730,447,690,595,195,264,896,802,257,955,378,152,551,448,594,422,753,177,500,916,379,49,780,904,397,52,836,432,857,960,793,362,881,975,144,27,736,848,248,819,554,537,36,258,15,33,876,745,301,29,207,824,803,717,782,285,579,830,71,512,815,667,637,415,805,90,852,569,440,114,466,878,897,912,932,636,416,568,702,174,640,533,189,317,702,883,126,45,927,977,525,240,499,145,44,99,746,266,662,669,372,790,939,701,497,209,697,569,86,350,794,614,848,166,206,866,403,805,638,753,983,800,513,288,229,346,548,854,771,434,87,948,641,870,564,356,600,307,329,175,214,652,548,900,231,428,657,537,165,809,7,599,872,453,760,354,785,483,245,591,489,242,209,48,582,476,718,462,626,947,942,785,921,147,932,621,596,641,171,302,879,308,803,94,504,147,461,347,279,450,491,321,160,116,181,798,13,796,325,356,732,458,106,71,479,995,267,961,177,205,599,546,228,461,448,611,970,204,628,522,468,957,437,741,476,760,720,995,78,725,939,228,23,82,379,685,637,264,57,726,585,860,848,544,594,812,901,187,600,855,884,153,334,288,483,745,29,949,103,550,637,552,828,181,438,115,259,88,539,425,868,77,636,415,91,714,58,822,440,889,600,917,634,843,668,122,759,449,271,531,84,965,701,816,572,917,93,154,695,580,49,236,216,411,69,296,494,884,983,45,422,586,418,205,718,546,591,90,70,445,275,354,520,804,962,567,378,398,681,889,83,50,201,948,884,477,847,886,607,740,869,441,954,738,801,417,604,202,758,215,959,261,176,700,625,670,920,636,440,549,131,939,277,834,526,238,568,629,701,274,373,818,119,326,51,360,745,135,143,368,393,849,63,288,986,40,717,367,258,14,711,870,954,309,712,216,677,653,53,53,819,460,905,222,766,255,531,343,350,223,708,499,692,851,415,810,878,753,852,158,628,284,897,88,224,400,148,948,914,27,853,627,543,706,492,299,241,794,165,216,445,674,600,354,120,251,396,742,137,397,909,545,760,483,196,823,492,980,700,691,139,497,958,239,740,141,2,208,217,721,745,830,123,181,36,186,922,48,232,704,206,744,807,327,157,440,603,999,156,6,440,409,888,70,485,548,184,933,545,597,205,247,656,583,650,519,343,847,893,410,591,968,710,98,287,446,604,392,834,768,328,72,567,480,977,642,510,390,826,226,399,126,565,7,618,369,677,337,156,69,986,65,664,848,540,530,413,955,705,845,232,659,202,827,474,504,777,156,232,247,740,596,333,553,759,635,263,165,655,136,980,740,253,290,216,882,566,600,21,953,933,613,108,847,615,130,250,428,201,616,418,736,706,171,43,973,912,869,149,576,673,319,394,31,762,917,918,760,405,42,929,290,387,354,736,598,316,283,448,677,837,561,822,916,933,101,355,963,509,549,872,591,854,501,421,242,783,32,981,426,415,662,385,455,499,291,104,168,128,165,344,544,305,547,705,647,387,692,699,871,70,960,642,929,713,942,827,859,631,942,484,970,904,325,148,456,851,139,420,10,439,756,308,885,960,679,171,817,534,774,156,761,131,524,787,239,630,609,301,293,872,661,36,522,206,852,443,715,33,831,176,706,646,761,890,981,808,541,771,93,878,158,11,423,86,983,861,566,501,687,829,730,810,864,876,981,809,261,441,827,66,397,813,211,624,745,921,762,168,605,64,878,523,946,351,922,154,527,818,35,245,232,514,272,554", "817,144,696,105,929,922,144,894,849,390,662,929,745,299,708,734,986,870,828,545,805,86,95,319,121,348,844,293,659,650,449,725,227,973,826,666,304,630,203,985,53,512,171,285,105,574,430,612,801,845,323,142,667,522,148,699,926,876,280,227,841,982,549,342,19,872,681,99,0,748,373,915,594,615,822,710,140,285,686,590,99,311,556,166,61,351,269,859,142,860,475,325,86,393,89,160,515,331,154,529,216,379,314,6,458,323,227,961,113,624,392,583,254,411,107,182,991,492,793,382,239,354,602,803,676,250,62,252,832,979,322,16,276,681,575,624,191,399,823,47,126,63,886,575,347,855,181,534,44,845,679,64,540,917,551,815,207,765,238,88,852,849,793,161,827,437,427,17,8,11,488,851,841,172,628,747,645,461,346,664,734,849,567,117,71,591,278,193,20,811,760,408,875,396,401,303,664,843,868,296,992,648,104,948,829,37,15,544,44,854,58,147,945,50,990,969,734,258,776,616,881,240,355,196,661,554,267,621,570,924,843,478,413,971,743,688,317,699,676,236,301,171,614,845,679,790,473,458,677,628,755,38,657,309,647,855,973,826,221,299,458,745,910,171,258,640,854,424,170,739,426,31,129,377,399,138,205,196,64,957,172,375,689,343,234,631,196,658,402,883,919,497,872,701,499,835,694,469,775,326,194,995,866,840,369,95,189,709,848,449,462,320,316,314,881,675,226,92,390,585,189,897,747,697,928,553,834,822,28,144,762,325,40,244,773,335,919,27,243,897,856,367,732,820,565,513,875,206,837,322,264,400,498,500,558,218,221,440,963,472,218,888,377,999,615,93,438,726,382,7,103,998,411,503,99,857,41,594,531,835,900,694,44,139,585,217,750,179,799,934,886,980,255,299,722,716,848,694,167,542,440,439,291,444,835,364,447,719,305,833,59,620,432,126,445,979,138,879,45,585,737,331,172,97,818,898,798,198,248,390,83,263,343,118,106,990,379,906,795,462,226,219,282,831,197,640,318,278,248,68,529,32,106,698,302,23,757,828,69,720,299,571,658,835,680,407,351,763,650,177,282,413,516,159,487,175,800,909,16,975,347,239,744,763,729,189,880,935,750,785,420,986,838,572,511,410,658,84,954,627,541,435,957,384,633,74,250,258,442,901,726,891,325,155,300,187,456,893,926,778,559,181,646,446,309,792,304,457,26,767,150,460,543,224,300,371,921,377,677,149,550,955,653,812,394,961,523,478,802,323,571,579,909,526,888,998,219,901,238,725,264,759,577,509,94,281,17,525,911,686,386,557,730,788,879,325,701,970,379,740,401,507,974,366,843,68,113,733,954,633,191,10,713,343,447,655,715,38,525,145,955,43,783,844,928,201,794,832,803,706,561,885,782,900,743,249,596,74,408,561,874,482,609,791,27,618,378,715,889,415,276,841,1000,220,146,513,83,131,991,101,20,808,276,270,335,800,720,715,291,523,833,972,267,937,743,767,629,77,737,380,767,762,84,813,549,538,815,238,219,118,965,122,866,672,34,564,275,922,829,54,976,89,949,55,276,197,79,717,77,206,494,221,16,729,299,497,418,567,432,722,154,851,572,703,498,865,308,729,966,790,336,653,46,970,744,509,602,569,350,201,786,749,356,249,551,918,474,306,126,720,142,245,160,283,390,126,630,9,321,268,981,167,928,219,634,547,485,537,390,796,338,538,800,834,830,984,223,978,512,822,71,729,902,603,928,391,975,205,504,402,427,471,105,955,653,686,778,352,58,448,591,923,453,237,254,454,348,995,806,647,873,788,96,779,583,982,926,41,138,168,252,496,293,550,847,571,94,2,523,284,207,392,545,961,353,889,599,557,533,521,521,178,247,786,561,50,171,140,136,655,219,40,179,228,623,893,651,325,308,146,502,253,53,970,87,821,304,16,879,891,764,494,996,217,767,931,48,72,595,823,302,743,791,89,357,550,745,632,162,587,931,137,697,909,712,301,204,61,797,520,386,470,395,845,388,862,612,800,593,963,831,70,807,100,822,310,164,367,772,946,106,464,145,209,686,779,86,795,375,649,723,367,752,499,400,38,877,935,822,7,358,905,386,296,795,746,103,664,102,92,635,86,25,261,413,730,788,894,195,788,201,717,566,629,337,424,554,701,959,780,143,147,485,918,125,382,313,45,793,69,725,31,156,992,878,873,869,309,781,925,928,52,603,459,824,709,975,876,441,275,400,390,980,118,122,473,129,214,268,496,179,481,171,467,601,586,131,661,67,817", "597,609,343,517,609,858,862,494,880,180,779,793,892,928,703,917,676,1,211,573,122,171,286,567,540,95,449,696,412,887,666,687,958,925,153,492,414,686,857,806,775,660,636,285,384,223,83,932,246,962,707,532,22,408,152,3,35,976,15,841,606,742,393,766,445,53,982,973,748,0,625,620,237,89,87,711,953,431,764,479,692,108,145,651,190,146,838,706,813,169,118,565,684,374,720,519,68,546,941,459,408,419,979,660,413,225,390,777,563,281,770,140,716,977,68,721,712,100,627,219,810,794,526,213,423,669,994,947,977,485,883,825,487,612,593,900,267,142,461,712,176,825,123,684,392,250,245,321,769,251,204,226,48,510,978,754,890,282,992,726,699,344,344,603,785,659,409,697,441,513,308,343,659,339,349,780,947,357,786,318,222,89,606,327,208,388,747,153,490,288,762,497,844,760,53,218,32,759,516,870,816,571,915,712,820,361,2,182,425,252,598,750,172,856,478,590,120,954,283,182,663,956,749,284,824,850,180,73,962,152,783,449,532,977,741,678,842,45,621,548,245,595,516,963,362,742,726,704,441,112,236,964,301,678,640,240,428,808,645,516,48,410,896,401,590,723,14,829,358,656,902,75,899,240,650,894,757,565,196,172,217,477,138,528,863,195,913,91,466,792,174,426,711,788,71,119,830,221,258,47,252,812,119,904,484,331,169,650,260,45,91,391,308,832,223,96,530,187,104,74,95,940,859,382,802,818,50,65,101,240,227,67,751,20,625,966,91,973,241,2,20,317,348,178,34,493,810,608,668,359,739,857,965,886,335,912,247,702,359,585,718,81,804,225,89,587,659,726,230,765,686,418,397,902,889,146,537,24,780,822,816,560,81,248,438,172,787,27,903,332,594,50,221,499,506,899,175,228,137,437,28,26,690,827,401,236,251,691,886,987,497,993,727,813,581,920,537,252,228,747,348,815,35,911,855,90,838,100,322,559,599,673,918,152,311,818,831,809,887,786,304,51,983,437,702,957,156,895,40,6,898,587,294,982,592,697,105,128,515,40,958,705,780,440,616,438,920,841,317,717,464,184,808,290,50,591,328,357,276,2,906,872,611,869,272,555,749,896,926,410,873,962,864,613,70,406,546,144,910,813,463,555,712,649,506,467,115,70,460,907,667,311,338,37,153,985,505,985,938,426,311,579,683,710,198,157,500,704,528,338,943,829,378,384,265,415,166,128,912,54,152,940,960,683,603,947,1,872,48,686,362,157,847,155,86,443,322,265,688,868,526,899,466,459,328,716,557,443,175,237,899,95,601,289,381,289,465,845,350,603,856,543,809,751,748,126,789,354,227,736,510,412,776,335,632,820,468,433,765,447,267,203,404,468,327,509,951,9,107,777,71,897,57,196,356,143,137,486,256,571,7,979,822,250,190,66,484,191,980,902,552,988,414,275,171,754,258,113,929,997,505,138,710,145,854,953,314,271,548,799,323,722,405,608,644,31,70,697,672,332,293,234,175,64,495,269,199,570,567,13,837,813,566,409,182,8,877,782,940,87,949,934,365,316,601,709,920,650,512,876,971,423,996,12,697,93,113,304,248,587,908,843,265,240,414,792,292,426,26,780,426,123,623,959,450,301,436,952,46,134,925,426,357,336,158,421,650,890,80,299,895,54,748,228,104,816,247,227,579,756,453,240,56,350,229,299,566,156,733,478,482,135,498,491,665,400,5,204,186,744,497,621,726,123,263,15,668,311,819,391,965,244,250,302,345,726,307,481,979,718,508,601,53,353,996,680,356,182,437,151,500,550,552,387,710,721,587,984,894,602,22,183,566,590,224,940,321,827,15,95,638,77,764,443,164,658,142,252,336,398,693,303,892,88,612,18,897,264,823,305,467,998,294,607,824,569,895,610,675,960,242,391,421,801,744,472,324,821,359,395,381,558,196,696,216,555,254,77,834,265,396,288,214,916,350,156,814,131,268,775,504,611,838,929,997,732,58,155,499,13,129,541,834,518,404,525,106,185,311,278,298,230,242,23,269,463,587,330,414,454,989,854,788,509,904,207,592,499,885,121,718,524,644,488,191,636,913,812,974,115,815,205,919,975,852,210,708,967,858,119,975,183,836,445,621,960,523,616,112,295,307,886,825,562,991,130,910,337,65,820,605,692,97,8,858,283,149,561,659,648,910,681,600,793,573,3,253,258,155,333,447,898,36,932,572,969,932,506,636,347,83,569,547,372,881,36,225,173,927,483,158,537,953,474,900,998,86,537,610,694", "461,629,79,619,312,606,835,772,78,403,939,341,732,550,382,633,831,883,293,987,112,794,638,456,805,142,907,937,548,162,408,82,102,796,261,999,269,553,217,458,324,310,152,698,508,597,332,686,509,279,419,224,215,110,858,683,777,558,985,694,101,792,476,330,180,810,797,768,373,625,0,189,957,393,629,141,569,908,187,922,20,449,125,277,949,957,658,827,116,78,577,901,428,540,851,310,89,651,102,488,979,680,364,780,938,197,182,970,670,965,184,287,939,778,731,597,105,481,569,10,958,238,811,705,670,228,714,442,13,590,889,931,338,940,575,473,400,350,679,564,17,197,81,709,60,449,729,921,834,698,735,555,51,223,567,261,791,264,231,762,817,74,702,967,248,448,423,172,923,94,129,625,414,766,300,587,537,767,38,133,247,424,574,848,156,281,389,266,2,101,140,557,367,893,823,448,82,106,297,706,751,44,500,176,751,546,452,340,996,129,564,342,68,628,453,995,274,288,689,356,288,586,713,676,938,30,357,832,760,4,245,459,958,371,493,978,948,190,201,219,335,916,546,748,963,464,914,871,381,203,698,161,481,657,927,677,207,385,110,651,807,986,989,67,537,519,840,730,511,603,131,55,785,57,335,2,395,636,216,180,884,53,276,6,400,704,433,888,288,698,552,699,253,352,172,522,991,278,665,793,102,582,520,676,707,698,995,47,283,537,481,568,487,576,224,881,34,492,912,741,936,971,911,955,107,59,728,760,986,940,736,43,220,232,534,749,855,756,564,458,119,923,995,571,4,342,90,527,364,518,226,626,682,864,737,31,682,845,639,424,664,911,924,659,228,509,509,458,499,633,232,930,597,311,804,967,508,466,992,266,548,160,964,728,687,948,205,208,745,374,102,734,653,848,687,638,815,930,42,955,843,192,476,315,116,273,22,876,264,492,690,525,702,528,217,263,801,527,275,59,1000,747,519,136,526,431,148,12,151,777,678,489,97,253,706,870,658,536,367,458,329,229,965,989,718,468,971,911,401,454,813,453,932,185,977,5,196,534,897,898,82,193,153,857,976,714,131,756,148,793,621,753,921,100,247,359,491,320,676,139,821,217,640,918,431,482,182,875,385,664,708,604,659,65,138,920,182,448,186,999,666,903,791,647,323,984,166,311,34,961,274,8,552,214,952,834,50,216,395,78,568,348,565,280,965,570,529,10,588,175,380,624,880,532,354,353,172,466,29,404,598,967,508,43,680,282,521,224,47,805,108,533,201,197,908,856,104,833,772,492,232,651,646,345,382,115,575,271,312,501,827,935,144,569,284,389,555,377,805,331,254,136,501,441,903,735,771,295,276,669,18,301,485,255,673,7,683,24,334,396,946,798,667,797,754,596,320,726,719,536,313,418,753,685,998,610,242,428,638,552,289,253,88,606,137,776,621,182,240,924,250,536,554,925,748,906,892,973,624,846,59,190,356,727,35,271,639,951,329,618,93,173,863,564,145,170,62,627,452,82,870,241,398,918,501,690,86,560,107,41,990,752,104,781,695,739,697,849,49,931,901,165,40,969,166,258,837,597,355,470,564,560,175,26,743,252,359,610,917,421,622,936,632,145,669,387,330,955,679,153,734,704,319,365,380,490,229,845,34,451,978,183,79,693,679,144,697,373,475,940,846,515,616,170,242,693,349,529,744,88,300,280,119,617,245,144,2,157,551,590,862,69,419,339,67,888,201,771,152,544,381,345,917,479,31,749,161,120,454,725,655,946,623,334,294,476,862,648,312,831,17,408,962,683,408,461,17,961,693,541,734,142,706,349,720,87,154,521,858,50,879,748,416,407,157,639,882,426,24,510,536,530,445,875,407,292,892,709,176,255,809,630,329,393,892,678,375,901,273,714,286,879,510,731,303,700,809,139,250,150,994,403,984,596,866,511,617,859,672,477,994,180,632,690,306,402,344,614,892,292,833,925,402,430,332,980,90,434,921,187,844,295,971,358,205,257,670,232,982,940,407,209,452,475,253,9,397,599,82,480,950,926,939,669,211,514,445,574,492,144,908,690,820,820,278,804,886,706,783,814,443,989,621,944,455,221,636,130,979,338,540,464,754,907,530,561,488,119,901,363,423,345,892,833,18,500,855,6,699,475,457,928,278,468,937,59,779,386,253,882,856,984,246,518,616,656,546,978,394,913,34,686,986,239,379,452,670,111,371,60,479,864,884,553,575,110,905,263,134,811,398,218,250,250,32,148,736,887,706,327,766,122,924,206,223,285,177,48,989,280", "386,25,63,545,81,22,899,171,395,79,880,215,862,209,440,332,656,789,675,608,989,984,630,140,771,667,905,892,161,697,803,935,81,521,98,435,165,631,823,44,233,625,930,648,566,242,530,867,266,929,205,538,841,605,30,300,555,752,569,961,621,352,824,753,328,342,778,99,915,620,189,0,229,571,325,263,461,650,96,642,619,352,729,871,940,605,502,310,203,332,39,767,137,432,284,274,560,549,908,3,471,55,162,499,440,221,702,518,713,407,62,649,410,272,768,106,373,924,600,111,154,596,911,854,126,476,11,181,115,749,811,482,754,512,371,580,835,796,327,583,524,799,367,8,643,346,56,795,6,286,766,47,120,418,367,730,937,150,625,915,850,906,478,736,15,746,790,90,345,252,969,326,761,986,823,492,643,179,13,371,195,351,538,380,110,637,258,731,610,198,845,467,840,335,860,846,961,165,774,813,416,301,538,962,518,710,545,536,963,450,830,655,934,155,727,393,618,85,295,796,455,197,200,180,865,524,498,666,425,572,846,78,644,441,27,482,751,746,390,79,448,713,116,400,624,247,627,368,594,573,516,138,424,4,353,92,766,114,333,596,670,985,680,582,210,59,391,773,912,238,904,941,842,626,775,753,318,88,971,162,583,836,803,961,424,588,764,678,457,166,926,348,676,431,782,902,940,241,913,301,505,615,661,57,5,19,305,406,445,10,627,405,845,306,767,994,321,6,600,110,174,812,278,93,258,439,645,806,12,845,488,748,862,483,639,265,673,918,650,131,660,926,651,295,620,572,386,760,456,532,689,773,450,627,302,991,857,29,160,849,929,189,680,413,918,78,545,622,372,239,586,305,907,527,404,289,960,41,507,70,759,755,539,705,691,328,670,720,460,626,648,782,954,133,790,700,662,870,354,660,942,724,844,504,488,817,336,959,5,10,892,351,356,89,70,932,280,20,137,839,879,592,161,715,161,61,334,388,12,192,579,310,246,922,570,491,652,49,778,176,550,83,910,312,823,581,768,770,537,413,596,224,401,196,467,20,56,100,943,252,319,675,655,52,435,219,71,195,995,455,153,77,288,447,349,510,622,679,171,791,192,648,566,123,528,158,724,698,889,418,475,249,665,232,194,494,646,994,673,679,782,883,577,660,793,798,282,480,438,771,971,569,983,112,498,729,712,40,812,900,78,381,726,125,633,215,735,312,667,431,464,224,476,52,917,157,787,660,19,451,325,27,492,996,494,410,425,398,366,544,997,578,507,37,538,882,636,520,423,661,344,494,613,207,132,980,222,453,209,346,288,208,688,881,222,467,741,312,22,754,949,434,684,525,258,860,126,967,762,41,608,473,194,384,13,752,709,931,599,81,514,920,708,157,546,841,805,911,677,13,547,257,637,368,62,145,416,951,435,692,619,840,77,36,376,517,10,89,425,938,431,228,339,821,284,84,611,596,944,37,780,629,642,686,742,622,587,408,235,19,575,199,285,153,516,516,63,958,885,541,790,61,960,138,976,289,390,684,885,288,66,964,40,974,252,420,264,885,852,868,807,409,529,934,251,645,749,97,688,863,518,319,738,816,2,49,963,653,996,324,211,518,513,820,956,781,857,300,100,150,132,503,81,934,950,858,2,424,443,549,349,180,463,959,562,96,209,873,540,484,997,485,711,800,418,425,599,645,744,593,240,199,806,185,69,546,933,714,106,953,411,753,473,297,316,508,354,894,368,5,15,65,385,583,410,293,189,1000,962,77,370,532,124,185,773,721,2,79,544,918,436,786,608,180,165,278,824,120,818,257,378,900,778,482,748,150,164,689,226,841,193,651,642,831,42,664,690,705,785,354,211,63,870,217,461,111,868,422,581,818,814,618,875,754,806,521,48,638,378,25,90,44,610,747,348,610,762,412,288,183,47,30,561,782,546,754,382,532,364,564,230,599,580,593,342,400,235,805,521,716,735,431,993,442,410,712,917,586,780,626,204,379,577,5,873,434,979,710,516,446,396,849,562,242,816,697,676,68,24,97,345,244,546,790,654,777,462,45,814,604,26,570,599,566,240,572,847,321,708,335,372,366,258,570,84,63,582,347,900,320,476,512,760,563,839,841,653,356,570,616,691,653,321,367,744,980,832,820,566,84,386,516,121,6,391,316,82,470,258,710,875,479,78,262,790,503,846,964,175,444,613,32,186,931,523,291,476,886,234,49,919,717,700,785,82,135,832,102,791,366,323,150,676,896,948,250,84,158,756,297,762,749,6,222,15,945,61,403,582,785", "536,779,286,30,1000,943,562,721,920,812,64,442,901,256,35,458,920,220,498,545,711,907,998,54,506,357,134,183,161,487,937,486,139,262,855,386,66,529,727,833,156,936,705,871,880,84,357,36,241,861,413,322,437,863,862,596,161,870,53,10,223,781,79,614,617,341,461,49,594,237,957,229,0,797,260,378,75,345,635,745,625,589,222,699,202,107,479,392,570,575,530,3,128,717,293,742,923,351,79,902,417,755,571,303,878,680,687,692,678,610,611,574,336,34,921,66,325,3,38,975,135,330,507,471,831,242,905,866,736,810,667,822,176,375,282,556,289,828,992,278,744,63,637,62,673,275,957,745,29,202,592,464,668,705,665,617,147,197,711,885,337,87,749,692,911,270,265,755,497,463,683,7,43,328,504,69,197,862,55,677,445,269,352,529,786,331,239,492,596,739,646,602,532,436,285,251,415,753,528,426,127,636,170,244,821,569,557,965,977,754,371,499,40,500,182,135,485,207,650,345,49,8,587,631,796,725,472,30,833,700,988,665,537,77,114,794,938,150,242,238,365,914,160,427,267,38,912,288,599,745,858,416,227,149,231,977,151,201,209,720,72,892,553,819,323,641,564,258,248,28,78,618,512,280,592,149,431,972,33,639,937,374,503,358,446,939,531,77,789,9,237,838,367,818,104,57,279,139,979,590,895,935,78,972,350,85,561,272,512,580,777,872,283,699,514,269,414,894,250,457,44,987,674,165,767,44,544,126,200,829,3,911,829,932,921,768,67,764,703,783,814,303,380,966,56,979,849,169,117,35,736,702,841,111,114,302,102,650,726,277,146,998,887,940,63,313,47,870,570,104,903,113,202,348,561,836,93,294,605,394,213,861,602,596,664,295,555,729,258,673,923,233,356,600,828,530,698,950,545,272,883,493,334,81,67,462,615,869,763,597,408,99,535,379,454,93,480,446,928,903,594,929,655,227,570,754,756,78,614,199,169,751,179,66,533,710,739,61,330,233,718,964,453,703,685,860,553,986,828,355,786,34,792,213,70,914,126,729,176,798,314,195,726,9,917,378,817,653,805,273,585,650,53,604,51,716,372,510,860,661,4,241,720,469,683,619,65,486,633,651,593,392,169,487,428,729,78,224,348,243,631,964,404,373,154,888,570,872,782,729,828,33,294,368,286,764,89,151,805,888,163,906,436,112,760,173,151,515,702,329,551,580,180,560,177,920,514,21,519,140,87,764,747,522,395,907,783,727,858,663,399,741,441,752,644,374,831,578,631,654,145,603,457,28,851,99,393,69,913,999,261,677,991,868,340,690,727,670,725,294,413,921,576,123,611,493,730,904,862,143,882,808,50,771,663,981,531,39,101,270,425,710,826,627,12,332,199,682,370,994,722,720,805,771,544,775,843,250,834,579,524,949,271,97,278,676,645,246,710,912,981,160,963,280,573,561,555,718,445,720,679,666,198,45,832,325,834,768,335,30,975,640,520,98,365,195,556,303,20,911,648,965,126,358,197,855,526,558,710,973,68,480,67,974,272,237,172,66,691,624,315,891,363,971,697,817,52,690,394,62,573,408,415,289,962,459,926,907,937,130,979,627,354,85,701,788,612,376,393,384,405,318,306,134,605,724,116,901,196,997,377,81,147,837,850,511,438,713,620,233,879,86,220,837,336,308,63,422,107,913,376,948,672,886,631,975,643,546,215,314,259,734,327,353,424,658,635,824,161,252,173,170,932,733,848,143,318,975,24,506,595,35,995,649,845,53,347,866,322,85,233,165,855,770,431,170,191,116,917,976,479,569,232,500,128,391,721,110,39,785,6,83,932,996,361,99,692,752,773,276,317,629,483,338,232,837,59,566,455,380,785,264,183,697,780,762,35,515,397,84,554,326,826,456,71,138,911,36,866,552,636,372,258,580,247,374,335,891,758,231,300,830,734,348,98,20,187,86,717,914,73,424,327,595,49,862,135,822,398,770,712,406,542,529,344,980,897,702,935,80,196,978,386,579,156,146,559,88,918,688,947,943,909,398,761,616,169,570,448,711,93,209,665,314,868,225,916,736,283,3,777,611,235,664,821,278,316,179,634,733,610,49,775,719,99,824,991,835,191,807,937,397,744,549,601,695,678,238,378,394,191,908,526,103,42,426,552,327,449,373,16,524,55,724,232,76,394,661,52,970,233,722,535,963,665,872,314,782,12,742,535,888,574,640,283,54,828,338,875,681,22,782,57,922,69,821,318,765,512,959,256,624,611,851,117,667,676,583,765,433", "942,492,499,163,453,781,391,50,72,252,655,575,991,703,368,82,827,534,622,100,106,268,569,679,967,879,58,611,287,726,332,615,887,915,894,337,350,221,126,585,651,828,571,1000,729,744,385,634,253,321,312,841,264,62,57,454,257,715,289,49,780,175,281,371,876,40,609,130,615,89,393,571,797,0,236,370,876,626,717,36,212,608,694,400,760,67,752,403,455,793,63,950,911,677,315,894,258,74,42,826,740,211,968,448,444,726,251,21,763,460,293,541,437,642,877,960,589,602,805,500,752,158,390,648,131,809,519,209,440,874,521,937,629,871,504,561,900,754,630,159,759,444,606,11,292,183,612,818,109,680,765,737,440,406,19,3,133,943,783,431,36,831,880,896,285,643,160,735,289,840,682,339,198,117,497,247,202,572,325,490,865,211,43,503,170,869,879,489,499,278,102,937,279,620,913,96,35,551,759,17,547,437,346,274,686,217,911,86,309,268,559,564,346,411,7,81,889,533,585,673,576,975,434,550,349,197,597,817,738,778,711,814,29,204,417,189,280,53,327,72,90,524,234,262,604,490,261,944,13,20,609,126,270,86,925,511,514,739,99,787,452,47,853,138,438,313,341,16,849,365,465,535,544,695,85,553,351,31,356,203,638,643,84,366,995,646,579,815,262,91,953,211,156,648,82,918,826,822,10,776,651,126,511,396,58,942,993,481,815,98,458,183,925,925,842,695,161,274,917,421,318,688,215,841,233,744,289,442,721,55,900,367,858,370,851,265,298,736,247,60,248,25,245,385,788,374,98,587,758,709,1000,402,586,598,831,895,976,493,409,610,290,604,486,950,169,273,487,231,756,150,327,722,113,791,189,559,630,497,10,51,249,247,427,192,820,272,771,396,246,275,109,974,268,231,457,761,642,801,400,317,481,578,781,990,638,607,458,322,824,862,727,373,874,942,23,239,674,605,828,598,398,736,551,340,485,780,157,830,481,57,99,326,222,663,520,698,29,37,320,1,166,151,883,121,884,670,750,744,406,511,242,971,377,76,930,612,545,969,719,484,91,495,234,623,866,409,971,517,157,808,399,58,910,741,369,76,990,591,731,749,274,98,335,352,518,803,986,126,985,751,330,853,399,496,25,929,274,370,506,56,751,189,15,244,42,173,934,446,67,82,630,501,665,848,860,794,476,574,314,880,753,264,251,692,62,883,322,66,304,144,939,330,984,752,374,989,128,253,262,960,932,627,902,126,551,410,260,280,923,21,814,605,690,722,411,386,597,932,837,940,994,397,32,88,825,366,804,127,875,280,495,4,869,228,433,368,460,399,974,8,893,598,824,514,608,638,391,21,868,890,764,218,237,393,87,149,692,687,678,452,591,174,890,845,316,639,811,388,100,901,403,640,882,184,413,99,106,51,321,824,67,350,79,267,145,975,128,793,817,614,380,88,271,223,844,264,732,528,119,772,370,114,547,276,753,301,52,330,975,467,242,457,288,226,243,771,966,786,116,926,211,901,474,842,937,558,361,490,72,604,30,844,634,163,507,683,377,900,687,388,123,128,207,994,150,161,783,405,435,773,244,537,711,250,756,38,311,57,432,93,126,53,273,87,485,162,795,530,416,483,811,592,466,940,712,285,152,255,543,428,596,215,202,351,725,26,472,783,446,49,616,656,404,822,658,165,437,245,377,783,279,724,900,255,310,46,598,86,55,567,399,128,932,761,556,753,669,958,132,889,758,204,516,539,733,713,63,469,712,920,992,225,909,75,47,748,863,929,146,541,265,442,503,355,737,771,625,760,156,908,286,261,211,262,55,790,604,176,216,815,832,483,672,198,395,154,43,148,619,200,683,944,394,418,201,855,549,452,191,479,298,717,424,562,75,353,561,150,942,199,253,247,528,498,923,842,157,402,355,803,468,299,494,817,295,713,955,161,365,234,727,688,239,267,657,205,497,433,268,113,30,722,457,879,751,299,633,265,778,601,469,566,961,622,111,457,100,444,799,355,584,415,488,717,537,782,941,291,158,249,502,680,115,160,165,287,966,744,237,132,539,169,704,720,20,196,756,175,856,991,861,825,943,201,136,106,297,98,161,875,873,302,897,746,376,418,790,800,645,21,430,490,194,58,721,54,415,957,470,927,123,226,662,835,254,329,118,961,704,402,541,28,304,316,733,688,60,999,655,35,983,63,186,442,319,693,585,128,408,83,483,315,855,790,522,277,415,522,525,328,491,450,939,729,255,381,938,939,489,880,586,703,456,729,521,705,756,234,601,895", "533,412,302,866,659,129,157,30,272,187,936,543,990,953,104,736,776,777,456,559,168,979,967,382,376,30,955,575,160,431,314,778,666,817,863,618,577,534,677,442,39,67,804,896,329,143,245,818,644,730,821,542,337,433,327,693,28,742,244,672,507,682,471,646,310,31,445,285,822,87,629,325,260,236,0,465,641,299,197,778,426,24,692,716,22,1000,783,283,753,638,813,38,171,438,266,354,284,79,230,379,366,136,133,393,253,757,357,65,324,708,711,356,585,424,107,171,813,203,666,937,857,429,295,427,140,718,152,763,75,227,912,275,435,18,184,5,807,889,409,223,854,175,787,165,654,719,518,691,837,800,928,104,933,564,713,801,142,43,158,306,266,496,234,186,821,167,658,419,910,599,29,999,634,231,39,226,130,2,751,28,237,535,216,466,820,190,846,928,660,428,924,117,222,948,778,195,493,584,608,766,635,457,436,641,551,643,164,320,233,899,277,580,535,365,767,456,389,796,637,814,328,200,626,558,626,489,876,728,132,539,652,579,783,133,986,527,895,572,960,564,490,9,284,197,806,737,774,461,315,419,250,654,856,60,19,957,308,651,254,538,368,469,743,326,429,503,326,171,752,298,538,425,875,221,130,660,517,139,53,283,511,531,107,709,570,814,10,449,389,218,216,856,464,272,916,251,592,428,299,82,36,720,862,540,462,798,390,156,676,700,949,925,480,786,599,728,98,992,978,456,837,687,202,162,132,861,54,957,215,660,135,417,576,744,389,991,379,161,674,513,630,726,511,454,869,973,947,818,517,620,756,526,446,16,421,346,150,466,685,201,819,270,859,754,505,827,811,690,293,592,968,693,803,931,915,560,129,990,381,411,96,603,643,185,105,295,870,68,600,395,187,773,891,616,719,240,496,941,780,674,653,861,622,977,809,99,323,678,106,609,895,119,608,806,869,271,975,30,554,820,351,666,168,729,831,410,773,931,383,657,184,507,188,914,379,243,438,215,561,252,813,717,19,964,641,716,337,274,440,584,437,183,701,630,551,175,870,64,827,908,74,905,202,154,859,582,925,681,481,530,75,277,767,19,835,918,249,232,453,387,839,331,967,13,198,689,802,605,258,203,341,882,31,658,689,98,371,356,127,856,864,882,443,926,526,343,366,849,699,564,381,999,628,188,165,88,568,698,719,828,977,443,804,482,209,428,310,485,368,467,238,520,593,688,651,801,449,746,77,691,281,859,240,395,28,346,556,586,790,216,714,255,344,114,723,898,530,519,464,252,208,159,102,262,586,247,369,961,125,260,953,32,581,322,818,23,898,541,443,505,534,458,78,323,659,729,779,938,955,526,163,628,910,161,629,870,602,742,683,776,528,349,622,402,719,425,806,238,833,598,161,487,908,402,384,102,377,725,569,862,690,862,307,895,401,985,263,720,190,773,518,862,487,328,292,926,261,551,956,312,241,896,460,73,212,802,263,944,130,836,671,736,534,664,791,822,130,280,792,519,788,360,877,864,611,470,169,382,297,208,179,451,52,552,419,739,549,687,134,268,334,951,48,962,781,140,265,681,208,314,347,119,16,578,447,558,720,70,375,738,57,634,163,923,666,296,620,20,444,247,521,557,941,672,824,292,183,350,661,288,408,645,437,719,868,623,855,693,834,260,759,546,444,981,490,946,875,216,767,306,610,114,594,443,119,953,378,801,147,792,332,822,263,535,491,580,992,470,423,644,889,800,480,235,537,181,885,471,629,218,302,514,772,854,166,272,948,95,542,165,446,715,442,740,159,718,206,63,740,837,282,495,400,309,860,465,185,611,137,693,887,770,357,897,591,146,268,893,877,40,747,454,362,366,249,376,933,51,208,972,994,51,514,710,950,778,183,378,141,724,383,800,358,813,368,953,348,620,215,585,90,729,766,902,456,524,326,21,260,118,864,753,827,898,227,603,572,371,721,306,736,926,610,325,261,439,281,14,398,846,474,468,338,314,433,916,267,992,943,868,449,860,660,679,261,914,956,323,962,779,308,958,169,493,822,858,254,539,132,118,339,778,686,441,716,788,967,373,776,718,699,902,567,9,283,185,83,897,869,4,573,991,945,418,51,975,757,572,617,295,824,717,479,797,917,682,71,500,921,560,613,77,340,297,348,590,683,297,268,130,191,863,659,441,349,497,699,24,43,560,710,895,5,829,759,364,293,357,751,939,887,424,141,58,505,551,951,35,258,389,506,167,281,959,325,412,404,267,239,990,953,757,252,76,662,93,88,720,367,943", "774,778,842,785,936,203,933,345,622,260,602,913,135,165,866,793,465,976,910,274,343,16,425,793,534,609,818,839,969,332,213,216,6,572,419,992,165,823,667,455,229,433,990,534,454,320,895,58,804,239,385,253,332,646,264,514,43,412,846,399,550,857,847,418,901,677,24,432,710,711,141,263,378,370,465,0,587,908,169,38,629,538,271,824,624,405,65,622,827,786,978,835,338,595,929,545,804,517,119,485,480,953,299,416,368,411,175,399,470,348,425,61,99,506,953,507,11,774,82,422,966,637,573,314,101,900,104,888,790,456,590,945,588,303,588,99,413,712,78,443,196,739,231,27,873,7,902,211,16,12,544,311,794,113,835,67,416,30,980,293,875,203,283,398,152,339,659,698,763,836,196,333,664,396,258,778,852,274,238,50,243,292,579,901,264,202,964,752,555,237,709,268,638,894,235,291,705,434,140,340,213,973,748,715,540,163,874,35,434,328,161,742,355,911,814,7,187,745,185,477,508,112,561,634,182,371,280,901,103,140,819,318,739,676,354,400,162,933,749,745,583,352,560,510,511,589,967,103,719,993,533,605,652,750,397,565,626,798,155,864,635,525,148,913,153,744,20,876,504,684,339,396,62,68,556,110,82,93,192,431,982,156,882,118,309,344,506,726,659,620,872,690,926,712,999,976,4,848,51,404,21,277,628,527,965,842,509,344,853,222,57,532,135,835,343,678,646,130,292,403,163,195,81,135,133,111,175,930,329,485,499,579,612,529,731,400,485,522,292,685,33,399,813,677,536,131,277,639,529,815,852,552,946,487,368,440,707,734,166,377,968,706,187,726,875,491,154,727,404,961,131,171,717,722,697,459,891,95,838,323,83,723,663,476,944,858,611,169,871,782,687,354,800,190,392,308,272,754,823,467,580,719,971,42,650,994,26,374,752,2,447,452,904,388,915,776,315,678,271,76,589,107,73,269,728,202,935,437,339,66,716,650,501,940,181,642,127,878,360,362,878,417,457,43,902,258,677,931,718,170,94,861,581,819,729,722,328,59,559,209,362,353,748,685,260,387,273,658,745,353,632,196,729,903,891,135,675,498,80,615,507,713,22,358,647,893,650,313,715,835,765,397,681,512,657,275,62,130,59,869,724,231,770,298,598,367,488,280,473,398,576,510,117,417,289,865,94,385,601,540,893,811,392,627,566,275,515,120,177,936,615,930,570,787,210,886,478,666,399,954,163,51,789,726,894,291,89,111,168,200,22,985,8,670,649,32,67,529,926,437,949,153,515,75,596,200,497,704,905,135,429,117,684,634,285,849,56,920,365,463,712,285,866,601,618,495,271,320,681,921,805,487,437,465,936,218,675,187,89,838,581,512,941,17,290,220,558,678,868,55,870,631,800,417,491,838,824,795,549,183,738,159,412,944,590,500,323,867,176,758,27,687,615,594,608,776,296,705,614,986,62,62,537,42,25,885,831,168,4,972,989,552,566,161,332,629,372,211,892,71,137,48,171,95,394,289,237,363,691,819,542,271,418,579,857,37,914,584,651,178,906,439,32,389,691,152,347,737,543,981,21,288,461,670,782,676,210,629,31,589,628,821,993,106,497,515,211,446,847,39,473,981,625,733,381,410,486,431,388,439,854,939,209,557,466,991,500,446,777,947,916,151,816,305,229,92,426,839,625,418,689,670,755,423,770,162,982,715,624,881,727,530,727,692,914,926,448,178,453,696,455,406,170,15,160,840,378,860,554,429,780,309,840,868,261,327,665,500,606,491,20,948,670,236,830,217,492,66,635,702,723,394,593,564,705,668,816,871,799,630,245,209,470,627,637,958,449,584,478,550,872,212,245,615,279,662,190,819,29,545,186,931,224,891,35,33,389,238,531,187,30,878,716,780,337,163,604,601,240,301,655,257,342,756,136,912,904,466,280,540,10,879,163,654,648,596,309,958,634,318,588,865,866,646,24,404,4,60,245,93,918,893,453,46,94,802,224,468,978,734,783,579,735,706,748,474,653,670,142,259,916,874,692,353,890,454,124,146,357,518,523,637,567,644,842,659,275,31,889,167,571,655,366,151,816,98,589,720,452,451,995,625,458,920,611,836,45,8,485,465,93,454,621,612,15,38,833,278,571,712,437,45,905,415,533,793,931,591,816,375,853,615,917,684,960,27,151,619,191,974,302,179,221,790,238,61,188,195,729,87,641,867,171,562,474,985,586,888,729,671,719,214,752,916,808,393,885,341,308,43,745,798,525,129,740,784,202,348,376,111", "71,302,682,54,930,381,691,332,583,706,814,296,976,935,595,446,599,672,498,257,853,26,319,213,779,946,578,23,617,510,694,402,782,427,717,376,199,274,568,143,893,37,447,492,522,905,887,877,462,620,819,292,611,421,807,294,681,660,563,236,948,549,614,50,870,390,668,649,140,953,569,461,75,876,641,587,0,439,88,841,930,402,918,735,185,215,159,60,716,475,886,664,422,425,744,926,310,881,325,361,149,379,323,86,927,564,878,480,839,14,160,771,635,793,834,695,693,121,988,832,931,887,399,544,122,653,990,302,450,827,832,159,293,198,685,417,133,114,666,882,835,743,865,801,123,755,882,336,656,927,933,610,245,696,460,869,31,187,636,693,602,665,97,544,313,157,900,602,903,845,693,622,630,504,753,430,666,325,101,89,954,729,905,724,335,347,158,488,260,824,324,954,791,715,552,233,616,578,487,461,613,30,679,853,630,785,908,566,262,55,915,556,742,919,438,210,963,496,613,234,88,288,682,817,608,437,354,800,812,209,876,303,924,184,761,837,258,46,776,94,268,314,34,230,318,246,994,187,752,812,46,414,247,8,630,521,66,991,42,952,684,392,460,16,233,698,124,451,37,490,205,278,187,335,951,165,141,442,573,288,412,582,929,38,573,16,108,476,882,972,731,238,630,548,463,706,133,651,167,990,568,465,700,463,376,302,50,454,591,462,659,507,283,367,985,137,842,473,879,518,240,508,660,31,597,656,955,746,853,253,783,987,732,618,220,136,129,826,877,587,185,465,891,208,288,427,212,485,904,689,931,886,462,752,492,268,945,837,813,724,188,99,186,297,451,751,704,236,266,594,494,928,371,513,127,462,786,68,366,799,14,269,812,912,601,417,787,436,7,53,353,110,93,668,251,422,778,827,483,348,924,195,827,806,374,645,343,812,551,613,48,161,325,205,585,846,29,893,988,153,659,835,563,512,805,961,287,84,767,834,81,112,344,582,77,524,897,880,433,60,148,16,506,811,342,307,719,216,404,667,436,403,287,816,521,168,404,663,981,317,611,968,869,632,667,489,46,830,321,212,796,808,797,308,747,558,418,14,287,578,300,394,538,30,138,573,345,69,545,809,829,887,648,870,882,854,169,852,546,666,159,721,271,894,555,571,689,451,742,456,702,730,743,229,64,843,842,881,451,937,410,442,230,483,589,223,713,222,70,441,799,27,843,636,832,766,44,104,382,881,443,199,532,903,514,652,287,263,500,922,238,632,408,846,723,870,894,577,596,148,16,98,432,76,274,908,567,186,947,970,38,609,467,602,557,346,962,560,78,536,355,826,655,66,288,407,364,840,925,596,76,948,843,249,389,726,486,58,33,67,856,558,30,297,87,419,687,13,599,785,832,850,88,768,154,699,803,564,250,695,780,539,603,978,702,180,90,522,795,627,921,333,950,528,872,576,845,499,290,610,955,144,659,756,358,473,535,960,566,986,108,335,146,625,631,651,655,137,231,743,405,400,890,337,85,979,528,10,824,535,77,274,365,66,64,71,198,412,820,449,589,795,608,916,113,321,992,919,981,234,617,53,827,11,797,550,857,520,152,946,121,875,451,479,111,593,953,551,792,602,420,859,435,70,115,970,67,362,260,538,897,563,757,794,960,907,506,509,581,747,237,801,689,102,862,779,814,560,666,886,143,964,676,732,625,492,568,566,342,26,351,590,733,984,221,387,412,37,162,80,833,14,340,193,443,903,811,732,226,537,873,508,304,588,627,584,231,836,426,60,131,561,520,315,861,803,710,298,127,421,354,109,781,757,849,380,705,573,900,844,12,432,605,213,646,513,697,562,109,707,11,547,272,401,410,11,275,299,685,68,397,303,517,379,629,63,329,504,3,984,561,931,703,616,890,469,574,318,463,475,689,411,765,473,21,333,231,244,175,479,818,153,563,34,10,610,818,962,887,662,33,138,375,953,354,166,142,730,845,931,295,955,986,513,758,194,538,70,307,230,742,227,349,756,356,762,350,861,959,632,958,755,789,932,574,26,499,651,201,790,381,229,231,303,445,526,118,632,277,600,365,500,828,64,972,572,250,507,345,345,962,764,913,352,111,135,497,770,716,843,19,903,471,985,398,315,474,501,35,458,109,771,24,463,742,41,457,550,838,700,682,529,542,830,371,825,816,386,610,960,887,876,654,135,434,328,188,335,64,468,282,186,927,325,873,656,349,159,707,253,440,29,320,731,707,545,575,532,699,665,550,271,984,129,929,83,904,402,10,838", "996,220,896,219,252,316,918,991,278,2,436,33,17,415,94,626,199,700,713,452,231,111,599,730,19,53,195,150,516,412,594,237,837,768,379,845,649,171,882,507,487,868,128,148,408,56,445,334,110,591,908,85,854,750,795,442,25,396,150,928,226,758,977,260,922,974,1000,634,285,431,908,650,345,626,299,908,439,0,663,93,765,747,893,926,934,768,303,683,174,686,133,486,78,892,504,527,668,587,817,859,969,191,795,525,180,886,735,650,607,241,510,53,305,639,865,681,351,265,84,924,55,218,37,66,929,995,123,185,976,19,405,169,775,772,741,670,390,700,602,560,38,791,751,947,354,620,651,664,802,575,681,567,865,644,862,59,833,559,854,468,731,199,864,971,370,90,787,383,820,60,437,423,552,707,847,782,742,574,89,992,311,25,43,424,808,728,356,640,123,34,727,104,483,21,261,957,308,622,104,743,938,813,874,800,641,794,530,595,950,744,298,564,397,72,448,81,927,995,944,959,27,949,257,235,8,127,193,398,154,254,434,672,209,580,652,314,887,387,43,25,349,345,249,826,408,176,472,59,877,647,61,121,3,503,140,346,434,902,424,43,812,107,325,960,413,568,335,185,68,684,367,480,559,931,528,282,675,940,825,920,927,946,487,71,228,885,94,150,795,386,594,305,310,327,155,137,189,442,459,807,900,944,84,292,725,686,299,791,595,897,709,397,704,608,417,521,8,605,711,519,48,58,190,905,676,946,779,540,977,681,928,86,38,858,73,625,924,873,768,407,894,23,247,667,697,834,385,297,929,998,79,824,442,912,322,283,459,514,66,311,988,477,997,62,137,475,543,561,193,827,819,931,246,696,262,493,733,283,510,898,150,472,599,453,236,231,801,921,159,741,627,377,174,305,807,679,845,402,415,692,88,826,861,576,718,375,149,773,555,44,965,665,439,355,144,113,857,78,633,238,579,670,200,952,780,246,698,203,196,271,288,144,524,45,611,313,801,431,715,571,626,956,583,138,781,94,985,312,269,365,22,372,600,533,707,257,25,791,205,283,55,573,710,620,34,540,875,260,217,304,549,224,467,864,153,822,561,702,124,29,696,710,206,999,580,716,855,777,93,74,872,207,841,44,723,145,45,595,487,679,411,418,188,123,773,333,33,508,676,435,410,612,173,504,560,952,19,700,626,350,372,595,753,213,962,171,22,921,82,831,465,328,988,967,714,190,674,272,539,305,175,618,251,645,753,858,933,697,391,169,34,18,146,947,46,900,125,877,360,351,459,517,948,732,439,635,278,345,380,781,239,336,192,559,229,175,281,231,264,838,128,818,147,670,307,508,537,764,247,274,932,854,64,42,691,553,184,23,420,358,877,513,219,783,495,440,679,601,468,414,629,914,718,934,485,138,378,966,302,543,211,904,256,880,881,999,300,611,654,49,643,393,558,778,54,24,278,138,439,22,211,422,775,909,407,927,30,107,495,127,838,699,35,277,496,832,851,968,620,893,886,271,966,892,647,791,979,645,986,79,849,559,174,35,385,521,597,970,925,93,159,31,552,697,553,454,943,243,432,889,989,467,159,921,527,628,316,914,551,1000,143,718,86,993,127,652,205,276,654,706,712,823,154,765,546,394,565,697,240,267,45,583,58,891,321,747,182,216,113,656,341,969,962,39,814,639,882,826,146,691,318,671,3,965,129,311,95,279,275,576,615,680,798,26,673,188,602,977,75,529,168,695,266,885,30,726,656,770,704,205,360,728,460,902,66,485,810,369,513,24,782,139,402,336,74,172,204,708,752,497,469,336,419,339,886,804,708,50,217,833,604,701,353,459,273,277,538,521,369,691,267,999,330,340,94,342,717,557,911,180,713,339,3,412,930,501,479,242,523,359,988,59,914,485,370,843,740,928,371,765,572,17,49,186,21,795,63,551,301,446,725,379,326,269,702,835,314,545,461,731,478,619,817,349,562,524,524,974,556,804,30,106,445,683,435,571,74,622,330,951,178,842,952,820,796,528,14,35,130,457,797,428,803,944,204,620,793,615,452,310,975,822,384,525,173,461,593,891,698,700,692,887,826,55,705,910,101,344,335,715,760,393,273,839,352,960,610,314,752,997,115,334,561,205,493,570,5,351,526,842,65,714,818,115,224,312,615,461,165,300,304,63,507,769,617,215,587,825,144,511,666,422,203,39,234,694,929,106,646,753,204,662,572,299,772,169,846,581,727,269,227,28,361,387,643,638,77,770,708,176,944,235,514,16,788,722,14,869,68,776", "752,159,576,573,904,445,516,807,571,142,545,61,242,478,458,233,149,106,451,785,7,298,101,283,8,263,675,472,450,92,295,530,780,632,257,652,204,891,584,274,98,126,857,342,426,970,716,932,628,602,427,628,102,220,478,14,204,401,528,71,847,270,742,811,11,42,786,199,686,764,187,96,635,717,197,169,88,663,0,13,628,963,947,870,529,561,911,739,137,529,353,40,435,322,780,494,10,753,960,518,587,324,852,670,353,690,46,848,904,487,233,683,519,613,978,944,558,441,854,547,784,202,637,276,389,409,570,620,522,321,197,755,263,396,747,650,956,361,618,160,570,772,963,919,952,519,618,697,227,238,738,910,690,474,698,71,825,320,982,645,416,734,79,521,297,166,957,652,88,120,920,123,876,969,514,764,541,654,710,877,190,206,648,798,680,537,416,997,695,788,620,432,565,725,746,317,507,929,55,669,117,114,217,427,127,25,589,809,614,325,94,265,500,591,368,857,643,721,660,650,155,332,138,336,57,871,386,141,963,131,794,668,561,651,132,193,652,116,676,791,830,180,840,537,587,421,327,380,953,723,977,289,139,576,292,2,842,65,363,651,838,669,760,900,862,141,209,940,413,269,690,871,164,639,920,567,92,606,851,919,862,547,293,544,254,327,995,759,749,905,464,9,421,51,269,123,23,892,626,555,982,145,420,141,539,540,727,64,869,104,681,56,2,126,513,728,689,816,874,110,11,507,437,262,762,682,82,777,548,120,34,933,657,562,945,48,366,935,973,628,631,657,709,295,456,615,223,784,458,148,487,990,641,50,391,349,640,385,368,315,116,180,648,500,146,353,653,28,605,197,89,552,695,856,309,886,901,913,716,417,176,932,729,475,89,568,599,539,855,734,650,939,360,243,739,550,816,402,519,520,404,936,996,595,349,119,762,671,232,54,411,234,630,937,778,772,466,639,213,548,669,391,693,914,567,818,330,140,513,677,632,387,302,753,10,920,349,267,893,381,343,201,151,313,546,361,430,533,791,337,97,577,534,330,923,271,462,852,504,347,754,24,634,522,550,85,154,215,317,143,523,816,395,802,580,236,767,670,460,208,191,493,731,340,584,921,43,727,635,871,858,239,734,754,443,21,88,657,287,712,64,277,749,189,687,276,744,446,734,851,611,709,696,125,494,528,789,682,732,431,948,379,501,991,677,262,982,889,65,179,942,771,168,738,740,992,711,239,701,851,51,856,749,822,525,964,854,123,100,830,965,489,267,934,314,172,49,511,762,685,795,548,432,509,560,326,525,99,69,57,370,956,952,153,209,588,283,931,204,689,484,723,383,753,558,622,165,673,115,190,909,165,230,373,283,673,889,409,824,62,418,352,669,971,49,378,554,747,777,874,758,95,639,418,804,886,313,407,458,21,578,953,55,811,894,777,563,264,770,310,863,641,725,824,668,265,767,974,833,451,904,467,220,274,153,892,138,425,879,49,201,394,528,660,59,879,42,283,628,430,850,653,451,729,168,845,662,565,990,24,897,629,343,7,32,909,717,118,553,989,7,443,184,416,783,199,94,632,209,976,795,531,121,343,830,39,260,655,306,761,792,660,377,215,309,975,686,769,371,613,697,817,324,155,743,357,846,692,844,267,255,664,110,882,704,172,450,276,773,701,221,350,813,491,238,63,147,56,230,818,113,606,292,800,158,175,416,888,749,666,67,95,716,936,530,96,140,634,178,506,795,735,274,575,999,471,786,503,624,369,129,491,829,228,253,362,918,399,510,841,318,851,304,965,623,561,293,643,342,885,650,221,711,698,263,606,842,946,469,827,275,150,388,166,944,527,63,497,624,423,150,156,144,435,820,123,819,356,466,827,164,824,901,850,876,987,464,38,166,218,926,769,142,15,21,981,719,107,862,56,919,474,754,868,343,66,786,842,762,25,97,305,999,449,582,993,68,991,189,11,142,914,255,878,585,250,933,58,774,390,329,97,260,161,35,774,619,175,939,267,568,594,120,810,831,285,858,267,506,47,122,708,339,135,204,69,653,347,954,559,84,626,152,591,940,462,57,47,163,112,90,50,743,547,435,141,761,727,934,456,414,51,462,852,943,695,750,968,59,194,376,760,889,343,944,236,624,525,484,342,82,945,150,206,12,799,112,140,744,814,640,136,707,651,442,795,742,695,903,443,227,714,682,220,124,961,287,921,210,631,711,214,907,432,997,625,987,35,972,350,54,415,417,823,135,696,113,223,630,48,252,294,922,885,418,517,638,343,857,945", "6,617,942,636,894,851,169,406,10,852,729,1,402,737,87,69,553,711,566,833,109,878,383,920,495,766,417,123,605,215,294,570,548,986,814,713,865,556,996,717,771,352,950,385,831,226,433,151,505,637,461,878,911,541,700,178,407,161,69,180,820,740,537,127,738,361,31,608,590,479,922,642,745,36,778,38,841,93,13,0,898,967,850,312,20,836,922,975,359,111,299,743,767,422,839,718,779,636,138,965,983,741,979,911,725,443,822,520,24,803,100,999,195,851,149,94,901,179,486,950,685,330,703,857,106,277,883,39,510,238,516,839,783,605,77,660,655,200,168,42,321,794,870,157,260,540,357,706,542,899,424,164,153,177,320,541,109,486,227,811,467,192,24,974,442,594,654,795,548,316,496,292,342,717,345,14,542,753,30,938,179,198,93,873,516,494,542,63,942,565,639,202,426,142,197,562,898,855,984,946,20,214,704,585,466,731,443,356,852,78,278,480,409,666,317,779,268,865,367,357,349,337,198,658,953,270,29,316,449,458,516,274,776,258,591,789,36,282,94,950,473,473,547,763,840,228,294,131,451,424,284,427,124,479,212,615,217,788,932,767,859,641,780,419,489,964,27,830,646,606,620,421,85,245,934,694,231,306,904,865,920,493,510,169,890,829,635,765,52,195,972,922,140,966,864,727,564,120,601,119,73,771,549,180,74,680,367,3,204,815,210,736,229,623,444,63,889,835,658,462,369,618,561,132,430,717,447,104,126,29,439,356,934,335,901,115,41,771,500,427,642,197,466,268,797,989,770,330,264,406,66,562,451,806,500,84,225,282,624,375,188,604,655,528,683,195,429,156,675,269,695,631,324,524,258,742,117,171,414,882,808,826,619,957,787,984,413,977,459,390,305,533,887,908,962,987,936,709,30,348,127,654,356,714,543,116,193,390,121,219,207,635,829,522,5,851,448,627,86,71,877,277,502,790,764,196,718,310,820,566,362,568,780,706,116,943,575,153,534,27,843,756,822,218,378,224,253,160,923,836,374,108,868,494,977,960,129,676,338,327,858,604,323,722,412,264,902,370,902,69,533,653,454,655,96,110,407,624,191,441,442,107,77,58,460,418,42,994,206,476,162,965,568,527,717,104,316,763,902,339,953,18,559,756,129,832,830,555,330,896,382,118,630,907,28,486,247,364,991,301,677,258,263,906,718,133,977,175,723,958,558,87,24,882,770,557,136,898,750,29,305,51,783,523,705,210,81,238,384,233,609,722,995,942,624,765,647,545,984,660,674,200,271,807,792,704,857,375,506,400,522,218,841,759,686,359,370,247,64,687,726,108,837,438,810,122,301,521,5,307,599,142,991,594,563,696,419,502,408,822,359,471,950,746,484,784,499,268,841,499,131,518,822,270,434,712,615,878,692,783,550,525,277,605,825,486,313,68,416,667,727,166,160,665,237,108,180,309,27,175,583,84,97,438,24,375,579,942,513,227,155,654,174,93,879,571,110,168,738,888,811,981,437,545,316,340,769,942,488,259,999,197,737,684,360,495,707,992,644,396,553,557,237,962,867,868,136,584,407,35,51,871,883,521,439,54,300,232,419,242,364,774,899,334,666,942,964,921,216,466,688,889,6,247,582,371,943,87,605,924,372,250,299,651,74,896,511,594,149,103,369,935,953,274,604,921,862,330,462,208,768,234,953,841,826,533,724,403,751,209,585,207,229,807,522,22,129,781,336,559,973,263,503,61,416,480,324,641,576,844,230,511,120,793,948,14,139,665,799,487,708,908,672,564,879,526,845,622,372,130,75,697,796,324,685,968,433,950,359,171,249,683,610,580,584,521,670,669,106,212,58,204,829,23,589,206,321,872,183,689,860,694,315,893,922,438,509,488,904,816,285,575,804,346,205,233,16,317,886,452,228,568,362,870,477,32,557,901,854,898,922,373,119,906,51,668,569,41,629,734,493,821,428,819,447,729,378,80,166,320,106,88,233,217,561,648,685,597,161,506,653,847,739,432,442,483,142,777,311,605,839,973,129,216,590,181,576,932,45,326,826,340,780,106,213,170,320,345,962,692,5,431,370,448,409,386,696,643,953,946,251,250,190,441,360,784,205,89,167,240,205,174,110,104,339,847,119,332,142,942,970,330,576,288,780,858,317,639,923,726,918,275,953,436,475,377,674,940,54,351,734,345,255,680,513,136,51,441,21,698,437,368,676,125,584,406,31,894,235,600,965,666,17,341,608,927,355,583,494,709,579,785,932,762,496,416,775,81,259,718", "741,673,68,635,70,976,380,79,211,582,248,675,856,450,637,310,204,306,903,387,501,277,380,779,936,314,236,987,718,347,765,759,663,9,582,979,998,815,892,127,439,51,239,816,42,730,990,520,939,908,358,200,569,746,724,55,577,814,31,473,671,76,463,182,770,27,410,892,99,692,20,619,625,212,426,629,930,765,628,898,0,230,448,214,436,205,404,69,52,140,293,818,174,54,57,223,373,970,450,853,38,515,587,435,154,407,435,472,945,592,934,763,968,250,311,317,685,633,732,178,980,278,645,722,326,65,37,686,906,973,31,31,337,138,638,162,446,652,508,976,636,758,716,69,206,319,609,975,313,667,904,919,297,126,29,554,473,787,930,700,112,922,787,77,59,501,981,917,647,614,41,903,831,335,842,920,557,174,962,871,920,924,287,268,836,430,549,540,215,992,360,387,131,500,813,397,395,421,229,601,646,267,163,832,590,520,609,251,628,387,629,695,118,685,117,11,836,655,266,525,858,814,465,564,435,395,760,173,307,762,524,701,331,796,76,623,285,228,12,213,877,320,142,920,643,237,816,662,606,316,641,101,974,865,926,616,807,26,138,154,429,155,929,213,232,856,723,377,221,360,808,890,371,268,462,916,992,34,597,552,617,530,487,205,785,725,586,416,405,471,267,340,424,299,55,3,69,448,912,922,287,442,676,454,316,28,680,824,988,437,568,863,78,226,307,516,272,556,753,486,727,877,454,606,181,215,914,158,133,402,601,854,490,439,491,88,712,907,946,518,1000,6,59,1000,899,828,381,892,889,120,897,711,718,843,633,424,566,485,35,169,586,391,97,432,861,544,416,137,717,359,96,454,598,159,709,366,78,937,916,776,473,623,626,623,265,23,318,797,61,380,798,594,374,950,545,212,439,861,407,138,94,667,546,686,63,899,803,730,729,47,351,842,145,369,304,915,374,600,210,105,138,860,490,476,335,469,53,634,849,676,867,51,637,789,941,180,869,478,808,997,535,251,159,676,583,413,450,684,446,247,900,536,588,301,267,780,432,150,252,725,564,219,893,229,33,553,619,37,872,846,282,971,7,309,113,374,556,336,979,624,563,349,916,761,379,556,785,786,311,908,497,923,257,913,993,242,977,827,350,935,648,667,766,754,578,985,143,578,876,190,546,941,578,274,604,505,785,269,613,434,161,395,294,625,519,19,822,97,421,85,169,792,832,888,390,296,122,258,999,144,672,931,687,106,700,254,603,752,578,989,64,276,651,288,207,225,302,862,927,23,596,630,719,666,858,866,440,798,226,299,736,675,715,677,472,340,684,214,932,237,383,570,767,739,800,957,716,124,747,992,763,861,624,788,420,882,624,201,850,739,570,873,302,726,400,490,918,316,358,385,879,280,538,78,872,881,778,224,599,410,176,804,656,445,157,939,399,106,439,774,768,322,586,137,66,730,56,743,689,606,143,861,716,713,525,733,38,20,597,296,515,170,70,229,781,453,140,985,108,500,23,574,210,412,242,662,448,608,396,144,462,823,634,309,310,177,58,854,202,672,425,279,530,502,210,231,620,215,223,426,335,597,868,630,434,499,118,473,862,519,410,713,987,760,814,680,919,897,858,320,591,181,812,104,401,884,289,687,599,608,60,963,216,697,594,627,116,865,550,476,131,218,806,641,410,762,834,612,828,245,55,730,52,714,955,99,2,384,818,229,743,699,940,700,281,777,514,470,430,570,822,60,371,306,471,354,114,138,86,878,303,858,445,624,710,253,456,669,804,859,637,409,360,63,165,494,458,998,231,343,107,350,720,64,486,953,328,187,759,598,338,855,669,197,203,88,737,489,73,766,199,532,249,855,314,780,451,994,537,762,594,658,652,88,280,888,77,398,384,497,64,883,835,177,981,735,688,463,978,140,966,694,348,409,284,907,890,939,184,646,912,69,777,414,716,429,63,620,611,456,994,16,740,366,802,832,699,688,126,845,540,649,1,426,953,561,75,592,271,444,326,811,852,400,675,813,221,623,36,523,68,891,930,158,219,948,564,947,190,97,453,784,704,713,188,78,370,2,608,494,595,53,519,274,858,402,862,300,932,423,214,662,607,175,829,319,919,161,688,537,41,885,894,608,130,831,35,272,718,896,591,470,457,55,676,965,26,445,869,166,512,172,395,665,171,966,821,807,762,146,876,102,85,282,242,761,399,671,897,484,46,637,304,316,571,541,770,876,683,675,878,368,66,27,926,973,110,193,129,797,170,92,641,379,710,469,216,279,993,38", "644,703,454,557,352,223,484,962,329,265,617,259,4,369,278,933,956,160,793,649,733,858,246,726,27,539,192,735,571,858,436,474,337,979,557,824,953,211,952,365,972,923,389,986,622,847,542,315,917,466,398,769,467,185,145,462,467,690,618,892,305,280,94,446,914,624,833,124,311,108,449,352,589,608,24,538,402,747,963,967,230,0,339,598,207,37,779,627,70,531,607,536,148,572,148,317,651,421,194,436,892,602,229,654,510,833,609,549,789,481,378,204,337,396,989,361,103,237,125,501,810,715,225,58,399,499,384,883,551,601,706,37,152,79,574,497,538,492,266,455,260,555,910,686,440,736,276,860,918,520,380,659,122,674,457,423,917,354,24,175,21,969,975,880,902,773,715,198,361,816,373,132,691,25,38,545,161,504,491,180,389,812,751,557,711,143,353,974,953,625,564,210,187,110,517,182,460,910,310,969,484,963,339,950,9,560,829,352,903,851,778,998,454,588,650,818,887,311,829,88,868,673,511,640,587,92,868,858,5,613,934,121,228,664,180,782,163,403,696,881,528,770,736,920,65,265,68,363,442,846,919,616,649,907,797,674,507,269,275,840,424,591,616,984,902,291,511,979,483,767,6,348,485,37,499,921,422,53,289,732,435,194,511,188,300,121,188,310,574,803,932,370,687,566,483,566,968,372,263,632,212,640,306,305,279,540,235,287,787,215,727,891,508,995,979,444,994,31,620,75,386,7,659,281,650,112,462,4,111,947,812,298,346,254,527,145,176,186,355,830,247,615,707,626,230,492,299,496,962,47,974,728,201,522,268,550,576,344,185,570,903,405,627,165,137,759,949,614,362,861,868,529,531,507,320,738,410,852,712,680,150,788,995,277,933,43,942,862,754,634,294,363,153,123,666,464,845,205,71,409,546,745,912,422,379,318,396,442,899,696,39,9,875,638,424,24,353,302,768,929,522,182,913,799,162,230,719,462,686,296,401,690,167,769,642,366,824,317,433,506,207,830,565,794,281,350,631,581,715,467,691,248,362,339,862,306,489,624,736,170,705,818,245,922,192,718,169,944,852,786,92,33,861,85,313,354,792,337,444,877,139,958,499,723,22,939,799,783,162,461,629,117,616,563,122,310,627,111,70,296,467,105,675,228,103,972,652,473,290,266,232,554,909,877,136,584,914,264,221,141,259,952,597,658,29,824,268,154,449,606,764,475,593,681,799,161,850,194,122,24,633,153,112,861,702,354,183,119,697,944,631,248,126,287,885,189,243,818,476,478,895,188,917,315,450,790,759,273,222,830,495,455,884,620,951,656,331,14,27,898,484,523,291,170,131,827,314,630,333,112,248,878,443,884,998,671,2,738,333,770,623,951,677,887,346,493,735,783,933,528,332,483,899,471,595,631,355,461,424,12,555,355,414,566,959,617,788,695,253,48,706,277,559,119,577,657,751,869,582,232,43,430,1,349,688,814,566,120,184,351,768,257,811,985,863,580,912,29,32,219,148,351,306,11,477,603,117,434,196,643,774,66,929,906,973,759,448,161,796,694,416,36,239,173,156,178,307,405,157,133,582,308,936,532,478,762,366,377,607,425,247,645,558,317,604,913,226,127,508,119,98,358,2,486,854,80,672,326,592,288,938,487,326,351,90,179,907,667,366,894,252,882,324,204,727,565,908,101,783,876,922,280,219,111,13,701,410,113,632,797,843,725,900,266,908,587,502,451,473,613,730,107,892,357,7,328,469,628,201,854,943,809,490,218,613,371,530,232,243,276,501,91,256,740,264,861,785,546,474,777,338,650,691,194,343,989,69,626,143,649,172,1,411,370,73,961,546,189,767,161,164,571,463,572,990,833,365,714,717,583,872,359,5,920,929,397,68,438,652,484,335,571,29,557,454,164,642,335,88,907,948,490,310,685,820,625,11,879,550,720,18,391,338,623,227,870,426,679,534,809,247,998,888,494,279,961,874,900,251,842,141,356,12,220,850,415,698,20,880,293,498,705,197,903,246,990,487,222,350,771,230,585,715,174,110,913,380,226,754,358,955,66,872,628,688,973,299,121,50,505,489,433,953,227,653,906,239,333,58,895,891,283,25,35,936,9,442,713,632,152,62,513,510,971,819,701,782,253,714,334,931,614,93,60,297,314,68,283,342,75,180,858,844,494,824,864,626,255,762,593,58,24,167,809,119,852,83,792,697,45,457,26,77,261,356,174,252,252,789,337,914,747,725,272,141,477,833,505,278,963,962,901,362,68,172,393,815,604,469,592", "701,602,786,930,793,902,378,361,173,22,917,733,260,683,164,325,86,359,250,451,883,826,138,107,229,625,418,918,725,459,143,338,610,986,870,679,996,629,870,655,401,546,956,443,65,430,205,194,615,279,746,758,657,989,811,110,146,303,387,306,898,471,242,71,728,334,203,598,556,145,125,729,222,694,692,271,918,893,947,850,448,339,0,487,742,764,983,413,296,375,897,564,693,134,263,198,246,269,4,692,966,259,992,408,547,162,521,954,46,199,415,591,79,575,719,549,453,243,542,107,414,204,484,251,413,999,953,372,757,982,354,706,492,409,245,820,780,812,55,474,611,589,679,643,929,404,269,780,824,109,720,457,216,414,341,312,413,318,668,523,806,887,268,19,434,447,870,973,550,144,260,255,889,698,886,101,288,805,568,698,849,983,632,539,888,850,691,745,534,667,138,121,791,821,27,352,374,630,321,568,928,438,15,818,94,8,526,802,404,573,42,935,45,80,884,798,282,540,871,180,621,217,310,33,788,107,663,805,983,4,991,908,176,411,387,890,828,605,188,545,552,687,203,937,238,715,305,338,480,116,385,306,430,98,522,603,649,652,875,966,442,530,665,953,366,236,899,211,514,276,798,267,168,852,923,270,920,565,102,481,539,484,240,869,82,534,297,443,414,152,496,181,685,476,398,257,238,48,329,679,610,551,519,506,593,165,141,631,49,311,508,879,165,616,651,402,181,47,259,143,638,821,581,684,451,273,989,63,649,484,443,301,595,329,263,430,671,990,556,749,966,212,651,641,305,583,559,589,309,909,43,643,66,561,789,550,873,12,327,522,65,187,751,178,137,719,965,932,921,931,608,539,580,523,175,242,683,833,604,685,503,593,428,207,887,292,401,88,258,923,475,660,440,734,20,832,972,300,705,886,317,317,14,43,209,859,502,220,89,634,210,698,665,897,56,678,43,921,552,646,48,769,455,685,491,721,990,557,325,29,808,923,290,137,216,530,614,831,178,588,283,597,60,328,67,889,67,676,376,308,82,964,243,144,484,23,874,876,430,986,158,484,99,418,501,924,220,980,219,983,895,137,173,470,684,771,984,23,826,482,387,458,923,591,182,545,28,738,994,645,620,885,169,21,942,723,58,315,531,287,27,856,310,166,742,591,537,486,792,400,607,970,45,488,178,808,149,241,215,153,412,861,94,372,111,809,119,302,809,402,735,463,692,643,307,102,648,549,897,201,897,209,390,483,606,66,445,348,145,975,672,164,644,840,527,602,683,139,26,883,723,680,124,281,57,281,812,915,376,612,684,504,419,406,310,709,292,780,992,28,197,613,300,432,76,475,618,511,526,460,914,894,74,756,836,338,555,337,293,317,413,658,273,876,777,37,957,947,804,86,731,644,10,604,110,989,780,649,507,54,69,772,281,346,685,754,694,619,729,829,518,642,248,586,994,863,962,747,108,777,246,773,516,138,222,166,490,600,484,111,72,55,566,250,476,749,177,239,623,627,857,479,969,303,660,316,659,415,710,175,33,907,723,304,644,512,264,854,633,244,304,803,472,63,84,5,181,98,433,645,750,319,797,132,340,601,43,610,815,836,387,539,191,963,862,327,683,244,232,532,956,250,278,60,377,33,756,736,647,325,897,100,604,352,992,52,207,925,530,446,712,762,855,490,64,427,504,524,124,969,406,152,698,211,410,675,279,939,273,353,607,216,252,330,892,960,898,2,748,829,30,952,959,743,255,26,876,98,461,29,429,906,757,88,512,351,520,259,409,944,928,597,116,297,342,896,825,836,467,337,212,240,657,445,179,806,294,494,53,250,202,948,66,351,742,546,196,61,123,908,346,798,89,854,947,877,985,268,457,763,324,363,209,536,460,454,87,765,554,260,214,705,673,697,560,517,576,548,251,154,560,185,820,51,486,222,117,699,832,387,491,134,308,300,931,435,581,505,367,757,374,257,916,62,893,607,146,609,437,393,299,398,895,462,431,120,86,470,80,835,627,753,777,307,595,485,717,552,17,489,811,311,780,508,112,984,627,656,5,992,453,133,754,806,396,398,998,238,627,688,230,53,27,287,925,269,314,27,934,573,177,398,856,241,905,297,157,197,951,916,778,437,747,465,37,917,321,945,432,547,691,630,573,727,654,671,847,853,982,629,77,39,677,362,501,293,802,443,548,909,467,884,818,644,647,992,882,632,772,166,383,615,27,801,284,744,296,22,262,582,939,500,614,884,716,77,95,623,294,410,148,485,995,978,348,839,956,911,334,387", "782,256,497,80,354,231,977,385,393,190,301,932,205,385,524,244,616,687,285,627,707,659,664,369,799,877,659,18,322,169,496,513,557,351,364,210,244,863,490,510,737,496,670,449,313,181,931,554,522,737,348,255,663,259,360,910,514,193,557,831,191,374,423,913,195,893,120,771,166,651,277,871,699,400,716,824,735,926,870,312,214,598,487,0,814,347,391,248,410,804,476,679,394,518,637,471,786,664,574,413,591,524,910,156,244,18,389,925,21,641,157,652,281,758,607,664,289,395,807,193,722,420,84,185,704,221,429,307,677,593,506,372,403,115,408,392,778,11,378,796,515,973,314,703,377,830,50,767,426,8,225,12,123,68,208,385,9,136,575,398,527,425,956,649,765,781,118,549,370,725,396,173,354,749,744,793,834,57,468,740,433,668,537,871,123,164,373,384,869,184,219,833,781,911,509,147,959,223,821,381,649,233,998,413,873,214,656,518,792,998,803,851,423,121,24,387,290,512,681,131,134,480,726,188,778,379,804,391,102,351,737,996,942,872,865,422,116,302,942,619,114,129,407,390,288,611,876,654,340,86,18,767,873,152,812,135,646,857,744,401,178,522,41,860,650,839,687,819,754,213,462,550,772,785,857,897,470,65,988,871,824,706,466,373,986,559,629,360,822,171,294,908,992,277,232,247,783,174,387,658,560,330,748,951,130,486,434,692,849,42,498,667,976,764,383,521,683,79,853,40,900,310,775,680,192,972,40,551,718,169,666,147,186,664,527,29,924,426,634,580,530,343,469,194,858,409,160,369,710,863,966,12,838,493,89,369,360,379,942,174,486,316,49,783,96,793,991,853,442,810,114,609,540,281,7,9,638,363,368,763,191,341,546,552,452,60,63,29,540,694,273,816,609,618,830,81,568,712,648,153,213,778,961,920,147,537,804,842,280,646,502,982,225,54,124,429,834,635,600,803,814,149,324,353,578,279,919,160,527,295,419,707,820,594,958,9,566,564,909,64,243,851,497,786,46,200,893,314,104,205,953,590,184,326,562,618,91,930,934,3,30,353,104,83,941,575,342,821,687,809,522,143,422,726,23,809,800,983,987,719,52,413,640,687,683,189,505,382,535,555,500,431,361,939,838,230,545,236,587,271,192,459,857,149,84,524,348,775,754,661,204,730,881,464,800,714,818,458,415,340,793,432,335,801,204,213,989,419,372,960,200,688,179,383,410,985,164,288,230,679,732,989,99,10,738,285,91,671,39,279,611,414,43,212,661,271,740,24,973,478,976,256,919,465,190,173,667,422,449,248,224,820,1000,638,67,6,117,17,387,712,833,254,794,872,345,546,155,210,404,336,456,999,631,764,613,818,72,735,938,818,46,321,574,143,268,646,243,109,936,988,17,153,642,351,299,518,979,430,643,522,9,663,858,477,397,360,787,391,178,454,328,682,138,490,790,874,621,620,834,330,636,259,123,798,787,491,895,154,135,568,15,488,579,387,232,598,145,335,495,805,862,285,580,2,240,119,142,749,21,585,284,598,3,974,206,267,518,838,844,308,739,792,925,263,312,938,367,98,143,23,660,103,509,133,999,592,399,774,673,846,961,544,947,290,437,458,16,360,539,956,348,780,229,87,6,69,819,654,987,360,804,651,239,572,225,940,179,25,987,911,953,410,215,54,598,225,235,422,754,689,293,382,334,461,18,269,967,511,662,165,895,240,119,328,125,688,691,450,811,979,391,197,799,189,56,512,575,76,491,636,355,532,972,432,492,1,131,664,666,929,527,136,988,16,891,342,632,486,428,628,474,804,707,256,207,621,15,494,649,78,53,614,463,510,643,695,972,745,627,147,3,362,422,401,281,739,928,70,601,504,485,927,798,633,421,45,576,626,437,565,916,856,804,721,260,25,163,291,491,911,389,707,312,97,143,678,367,816,267,902,462,963,434,949,673,464,548,172,673,522,770,36,871,114,484,736,473,26,808,940,625,104,935,705,218,963,247,269,286,703,75,825,259,709,459,96,883,38,316,895,99,419,46,9,169,968,988,993,449,888,139,325,179,510,302,545,3,567,625,813,377,70,490,333,457,126,174,894,878,768,850,399,535,419,704,280,598,840,897,291,566,66,79,688,768,124,982,51,837,7,554,590,694,566,621,405,462,573,22,515,451,441,321,829,222,277,256,680,899,759,918,187,669,979,900,858,604,408,919,104,982,570,231,611,132,33,691,764,875,780,722,516,560,829,559,608,189,920,949,826,644,952,575,944,710,98,995,848,191,416", "870,997,517,595,862,910,227,671,793,134,305,89,751,492,254,45,803,576,666,727,20,272,836,208,819,111,238,369,222,208,495,217,69,4,557,388,239,411,564,463,425,508,67,219,472,909,693,915,916,671,821,889,370,256,138,160,568,580,799,264,253,415,60,538,986,32,723,776,61,190,949,940,202,760,22,624,185,934,529,20,436,207,742,814,0,557,41,734,603,383,164,529,579,951,610,703,153,651,264,727,585,487,127,223,634,205,293,725,464,241,225,809,461,968,992,639,31,686,155,147,447,276,306,952,53,490,554,460,187,840,849,356,270,386,380,309,12,582,616,847,271,493,953,28,446,520,630,114,343,309,366,305,489,724,736,317,488,107,219,94,34,500,625,333,628,951,436,494,317,457,813,536,320,540,729,849,654,889,210,56,275,677,997,620,403,612,363,813,942,620,434,762,361,974,828,695,873,253,827,493,227,404,637,237,53,7,478,69,276,284,886,635,171,672,783,396,582,303,486,506,928,612,875,334,513,313,649,510,742,368,337,948,576,329,691,238,511,686,673,370,366,992,432,810,133,524,20,741,150,275,937,380,78,876,692,509,277,367,779,454,797,775,439,965,715,534,748,390,801,540,549,53,350,480,183,4,893,404,84,689,582,930,19,980,433,740,666,104,56,472,610,992,340,756,962,8,53,58,351,518,698,511,912,696,85,411,174,645,374,733,97,539,29,994,702,879,754,789,387,80,303,165,927,770,413,147,900,320,831,254,166,692,258,499,459,778,416,694,24,611,477,143,68,16,225,474,871,933,687,347,611,118,894,830,122,459,865,267,560,628,986,947,700,110,686,636,367,501,420,635,581,228,954,624,694,329,240,741,807,549,619,74,93,125,435,358,456,815,985,589,390,760,371,142,308,531,453,216,754,912,736,696,746,517,191,271,388,689,370,1000,998,597,78,209,972,833,997,874,825,856,64,730,800,937,53,268,881,880,268,135,98,752,324,846,521,591,538,533,714,892,450,839,740,256,241,360,23,338,420,650,671,88,359,399,217,571,756,569,438,88,350,852,560,91,864,650,105,475,355,566,369,51,427,71,730,354,846,168,948,240,392,555,391,308,30,266,293,516,517,681,508,358,105,475,140,720,327,953,926,830,181,867,695,123,811,497,850,915,275,794,306,151,267,100,827,519,78,138,676,842,522,960,941,73,162,682,382,372,63,345,591,78,39,722,805,997,504,92,937,77,610,976,65,88,287,359,53,777,796,987,987,292,733,414,346,442,901,161,714,310,554,667,547,384,316,202,594,788,135,453,317,509,182,585,50,223,955,25,624,500,700,824,801,889,826,731,327,90,876,253,181,51,987,481,322,656,700,868,104,336,930,925,571,518,335,227,178,777,761,851,216,689,294,910,661,305,24,514,653,338,412,624,844,456,670,70,179,805,134,581,295,131,677,262,647,107,515,751,949,395,868,479,187,122,950,179,771,452,685,110,313,342,431,21,173,490,267,754,694,57,460,121,261,571,807,166,648,236,356,4,233,297,545,626,815,720,519,463,514,259,198,510,294,601,64,582,893,7,378,79,273,548,986,625,646,128,586,920,184,439,431,753,552,701,522,896,806,677,760,743,327,150,746,114,392,937,309,626,260,912,468,587,420,532,87,274,564,433,194,509,295,816,765,630,605,360,437,754,668,396,845,716,66,632,41,809,522,725,340,127,467,280,610,797,306,781,87,604,553,546,78,425,488,621,16,932,997,240,550,793,175,806,912,372,1,330,967,424,80,256,83,28,535,140,929,924,34,14,562,702,751,19,143,394,100,976,586,991,861,90,321,991,215,775,328,438,351,835,908,58,189,129,559,704,149,279,882,430,484,475,275,727,909,252,158,702,541,227,184,160,976,119,276,693,953,391,680,593,965,865,970,747,185,620,978,876,167,705,997,699,792,961,223,61,563,442,282,485,487,176,369,884,319,589,180,440,498,342,563,603,931,597,636,755,953,814,967,68,858,49,578,101,288,326,959,228,104,635,486,25,365,727,905,628,557,273,314,302,51,452,766,344,633,454,819,376,449,935,4,751,786,720,137,112,363,256,349,261,103,118,489,399,72,30,16,101,85,572,929,583,32,437,853,300,146,41,489,526,122,267,146,213,485,47,860,424,752,396,770,634,614,30,696,894,394,806,402,387,782,200,855,177,373,761,254,416,973,49,556,856,696,345,990,638,611,949,602,237,83,510,397,850,934,3,922,952,833,903,301,83,601,115,547,648,636,431,444,89,419,150", "947,805,255,94,234,48,914,639,509,824,250,250,300,491,56,196,55,905,433,694,726,260,680,116,946,59,928,51,250,899,683,949,129,264,881,107,866,924,739,481,70,709,640,69,942,747,618,579,142,976,91,867,524,280,870,374,390,100,67,29,860,259,657,225,869,603,521,991,351,146,957,605,107,67,1000,405,215,768,561,836,205,37,764,347,557,0,746,13,869,856,879,815,324,563,728,771,503,888,338,275,133,422,436,385,586,533,188,959,762,684,174,234,348,109,7,327,315,801,718,25,312,9,853,623,171,317,12,502,355,690,561,125,990,936,689,226,377,380,77,936,609,597,356,715,890,961,831,91,344,685,913,515,485,125,390,706,85,246,604,99,938,800,85,692,737,208,988,445,54,307,806,277,761,218,97,300,8,194,254,494,753,902,734,945,16,450,642,528,39,998,181,19,271,401,808,762,123,802,70,675,497,409,285,194,707,518,490,156,777,885,438,136,852,277,732,106,854,573,990,578,481,628,672,479,971,388,273,238,84,972,358,310,413,70,260,861,622,805,317,808,47,5,637,715,730,347,36,183,231,759,911,195,149,232,881,75,429,101,664,266,51,275,324,324,666,414,743,376,518,347,562,634,19,25,707,467,833,928,661,310,260,681,833,868,809,563,23,206,748,299,544,511,783,444,103,400,519,410,229,416,559,732,910,685,463,710,871,519,888,260,158,958,889,686,239,368,517,804,792,650,590,837,594,478,423,628,485,85,290,301,159,429,247,215,786,696,380,271,656,518,730,430,79,543,19,531,233,262,805,280,843,179,702,869,951,204,171,732,20,729,776,313,369,550,650,744,667,925,4,992,356,850,590,886,353,859,258,607,279,121,607,113,852,66,358,831,600,392,793,800,834,686,281,396,233,104,582,579,952,874,913,168,393,722,434,693,149,103,455,328,149,596,821,842,231,494,375,174,122,533,858,754,107,921,637,20,315,741,162,969,309,793,373,986,390,404,77,161,25,578,146,8,361,253,234,279,15,883,486,460,172,52,917,240,554,725,484,278,546,935,666,914,889,201,686,738,29,575,601,65,447,604,513,300,279,372,230,620,705,817,869,694,668,956,612,832,444,77,730,750,875,605,568,173,463,62,431,967,560,85,671,685,225,509,234,474,301,316,171,756,942,51,829,715,940,53,289,924,115,503,678,913,171,488,992,102,394,544,174,186,585,913,6,776,479,225,65,586,900,985,326,2,150,712,822,697,968,448,188,970,594,927,257,915,548,622,115,846,352,959,256,828,854,880,551,899,542,715,146,17,373,231,523,947,560,693,595,330,683,345,488,942,289,587,380,730,347,818,871,168,984,515,752,142,572,304,30,213,361,427,991,583,831,993,84,70,235,678,373,497,960,268,669,131,785,204,958,654,271,965,467,509,371,923,690,751,477,233,396,380,453,701,25,182,618,737,204,415,451,922,110,387,227,825,838,817,221,404,22,642,142,427,959,829,445,492,735,619,684,435,33,73,482,925,756,735,687,71,189,971,110,218,744,247,483,881,477,552,548,26,812,264,708,406,998,418,968,859,70,744,807,903,593,98,632,462,474,754,552,859,658,207,533,460,691,295,603,534,118,341,822,57,217,547,726,704,988,800,528,933,316,916,64,764,211,619,594,939,467,818,441,815,545,926,962,810,724,960,933,818,444,79,816,323,414,536,933,795,820,31,790,672,183,357,782,208,643,350,198,904,750,925,612,152,860,846,951,148,188,612,259,237,777,859,244,351,447,834,615,685,572,661,250,282,109,840,872,453,151,644,349,117,658,355,937,545,741,28,630,804,170,389,293,169,722,720,634,507,813,270,457,788,734,187,957,229,457,721,749,161,667,663,262,960,141,36,21,801,585,631,661,446,364,72,395,613,167,25,280,490,845,488,567,172,745,109,27,361,995,474,378,32,117,234,941,636,643,110,493,583,55,411,619,590,83,713,695,52,28,866,383,421,162,494,674,119,684,601,799,637,382,440,106,46,169,993,630,479,845,273,687,589,955,865,393,347,735,433,283,879,483,125,951,899,60,729,85,31,79,790,414,263,21,125,758,915,566,893,982,895,369,823,844,992,597,610,951,631,756,242,523,562,638,74,171,410,456,114,494,842,434,572,769,430,527,884,940,975,473,358,548,250,917,237,924,396,706,225,513,655,289,887,993,25,816,303,258,589,8,130,892,865,792,990,763,559,146,507,392,287,932,407,906,351,376,89,984,657,179,763,572,405,978,537,329,186,896,999,993,191", "159,922,417,675,644,531,681,703,839,608,368,531,780,299,414,69,462,598,188,916,39,606,607,113,537,637,360,589,787,615,463,914,488,190,950,151,203,11,891,928,901,892,751,990,656,484,140,450,64,754,491,25,753,732,301,113,177,968,926,999,864,524,177,789,457,38,677,346,269,838,658,502,479,752,783,65,159,303,911,922,404,779,983,391,41,746,0,1000,640,445,26,335,454,850,944,211,283,244,609,194,655,887,828,551,279,622,111,852,340,964,322,579,779,725,948,409,498,832,706,134,612,181,94,721,570,928,195,712,471,697,55,926,110,169,628,681,495,608,35,191,497,600,658,194,349,512,813,908,911,978,870,556,733,655,310,799,786,671,6,525,891,612,597,214,344,102,791,603,693,949,118,283,425,262,900,834,376,665,708,316,259,215,426,890,466,665,141,140,782,311,974,65,499,257,615,311,487,991,248,734,751,694,756,811,606,398,925,280,424,465,314,678,785,28,586,607,757,783,988,128,523,468,568,41,978,440,685,804,862,682,739,61,842,23,675,722,34,316,831,444,967,919,240,190,677,775,423,175,693,676,319,890,798,429,374,502,486,241,997,760,9,739,880,338,754,928,204,724,572,440,355,70,148,523,747,439,749,623,642,883,940,910,322,957,29,915,350,413,249,118,802,529,851,710,299,775,885,94,236,79,242,954,472,354,248,163,212,815,930,396,347,59,120,121,57,561,389,599,618,970,49,172,730,951,456,274,784,905,915,28,570,197,732,258,946,706,925,16,77,865,48,428,519,278,671,282,740,714,68,246,732,330,339,241,93,700,733,938,840,559,770,801,81,634,514,758,628,318,103,524,815,484,186,493,444,102,380,473,650,178,641,662,898,737,577,22,378,848,110,766,261,454,532,655,634,667,482,582,485,959,659,44,791,2,528,738,197,438,457,350,178,663,105,973,878,702,668,402,317,234,37,874,73,749,582,357,938,584,741,887,977,172,892,844,58,598,396,506,507,530,446,291,467,370,539,839,899,956,77,974,451,308,162,438,819,738,652,901,414,398,587,210,654,794,323,619,486,441,105,164,64,99,652,745,19,520,68,283,161,431,367,107,380,258,969,395,196,98,175,252,224,852,627,367,963,978,732,556,979,702,826,394,475,851,925,142,800,75,324,45,686,819,999,742,948,250,180,382,40,758,571,832,766,567,754,655,537,767,399,68,975,212,40,599,898,345,878,3,538,883,56,31,742,999,600,243,888,206,738,150,109,687,294,114,707,990,218,819,277,535,187,289,305,857,784,149,221,834,737,799,328,752,99,947,576,332,672,899,59,411,443,104,299,17,336,401,222,320,170,166,528,957,449,99,106,230,878,356,515,990,589,22,318,199,816,91,591,777,155,698,4,699,644,384,621,893,334,673,489,919,675,493,886,886,173,33,538,316,116,446,32,90,48,601,60,687,939,216,635,423,984,688,490,622,657,918,394,432,85,545,700,884,877,149,55,246,761,543,19,307,427,62,433,419,130,501,367,330,627,902,714,821,682,929,731,479,213,642,618,87,879,325,724,271,905,512,885,812,316,830,927,148,685,991,59,706,533,168,31,420,24,311,803,836,857,946,363,521,929,587,741,770,568,442,636,103,440,831,416,34,890,402,252,137,524,778,502,65,621,263,381,993,385,220,413,909,200,630,466,964,613,516,227,619,893,688,183,407,586,903,32,747,16,738,684,72,520,204,863,89,878,886,368,614,346,557,65,318,292,214,153,691,473,443,846,875,726,561,483,466,179,894,909,450,781,374,293,841,23,870,915,593,813,53,80,377,452,797,321,928,772,434,309,742,810,231,839,200,578,686,141,80,996,615,38,463,183,166,433,663,26,656,970,59,726,423,974,9,568,707,633,488,209,213,159,246,233,114,810,250,632,593,658,209,490,508,488,462,551,88,321,424,527,811,931,216,250,82,281,3,902,722,870,804,650,560,757,883,266,724,488,141,339,701,669,518,545,448,92,908,194,580,411,617,454,677,492,86,697,709,950,29,456,920,33,433,522,582,667,683,25,808,804,146,321,254,349,644,797,32,649,735,686,244,569,454,188,813,505,899,978,17,435,68,424,75,152,199,584,19,682,527,322,9,525,387,630,139,419,517,440,272,934,201,627,71,52,717,888,622,406,616,512,933,932,797,300,23,985,581,341,120,680,417,752,674,563,112,178,460,336,654,6,48,800,149,84,830,656,800,943,28,88,638,532,761,79,873,298,573,172,708,333,582,774,767,28,996,880,159", "464,332,518,781,180,336,70,192,152,952,491,728,861,906,615,374,526,694,760,473,590,627,124,877,504,929,824,281,600,522,49,682,336,12,382,436,723,314,50,350,151,44,59,606,175,314,524,146,692,190,707,982,228,46,672,768,4,782,332,763,652,635,566,357,253,414,28,21,859,706,827,310,392,403,283,622,60,683,739,975,69,627,413,248,734,13,1000,0,865,273,347,460,77,449,519,11,291,187,46,455,742,425,387,426,912,666,274,793,580,830,847,214,342,769,820,661,156,321,473,79,25,995,376,585,491,481,95,255,202,438,433,642,501,295,217,810,834,466,380,490,658,706,242,241,891,391,7,947,405,461,225,927,37,385,126,54,643,546,280,611,681,160,191,480,682,520,436,293,321,431,646,962,40,18,32,155,471,867,129,117,46,60,326,585,627,752,368,436,965,379,620,896,118,40,974,908,963,389,800,952,939,515,864,895,667,669,559,187,458,953,19,581,264,983,984,349,959,805,353,613,64,291,283,18,632,257,859,595,600,678,274,570,331,147,825,627,218,704,478,851,686,345,42,398,134,80,230,680,382,515,904,584,844,821,723,890,147,802,239,668,680,255,34,562,148,147,521,435,611,355,775,683,708,140,535,934,778,699,274,722,638,622,683,274,622,850,203,94,344,946,334,542,714,887,451,356,513,787,78,442,667,373,333,480,944,848,640,471,632,228,48,348,480,585,418,768,892,278,380,856,580,360,928,893,342,994,718,861,3,913,33,617,355,722,692,262,749,390,11,510,78,869,171,327,867,238,344,260,853,548,573,288,886,184,105,321,206,675,742,630,944,378,796,799,402,867,771,546,625,119,110,315,3,914,654,880,742,999,866,75,899,357,645,680,108,47,534,678,531,173,76,602,372,978,444,112,802,242,768,321,361,287,105,737,445,459,314,824,357,291,130,11,900,237,929,465,926,119,123,735,954,449,756,290,595,112,421,160,792,887,396,285,811,24,494,470,387,56,200,585,422,893,974,432,692,287,879,343,33,1,212,204,975,94,353,806,903,625,289,2,974,366,139,870,586,880,625,874,835,597,717,198,480,324,664,21,616,388,307,85,862,917,807,958,168,844,836,817,441,291,714,594,972,293,516,919,137,205,652,601,742,798,691,784,864,3,850,219,767,326,568,784,718,856,213,280,167,639,817,136,734,355,34,736,380,915,915,508,749,40,252,489,670,954,458,148,592,581,795,676,211,410,481,850,538,242,407,950,944,938,539,365,476,706,447,775,681,853,728,618,280,634,792,515,112,624,389,55,782,602,73,74,343,699,389,326,575,550,776,94,149,829,949,173,648,682,956,27,603,797,352,147,850,82,980,44,977,248,343,879,558,989,263,105,189,752,190,550,901,999,496,80,340,867,999,215,617,969,47,672,709,654,99,822,721,527,548,766,326,988,376,853,422,526,950,812,74,739,804,262,328,131,866,751,325,33,878,736,314,942,562,386,585,59,640,151,981,177,469,81,308,660,187,647,190,49,936,984,91,208,155,892,103,351,387,494,823,508,408,590,531,696,261,647,364,579,662,619,419,516,422,697,960,700,547,466,644,931,910,295,961,447,510,76,109,513,9,20,678,476,863,574,829,740,135,510,599,650,448,562,727,840,559,470,470,350,934,692,896,499,926,528,280,996,736,507,707,510,113,150,68,207,288,444,626,239,572,574,72,972,327,126,541,722,724,501,948,352,26,881,739,837,698,674,716,920,365,930,413,124,752,857,249,945,928,543,267,913,287,958,860,824,46,672,109,921,79,526,827,696,762,832,326,130,472,802,72,342,980,616,621,261,114,710,347,6,957,724,234,62,139,150,973,975,207,733,765,843,223,369,351,685,797,729,847,501,971,661,13,880,916,974,758,728,761,107,922,943,546,35,283,588,14,777,144,664,369,483,94,464,214,182,257,446,34,16,809,20,281,812,737,505,500,47,347,504,237,687,903,1,559,541,748,552,21,6,673,399,515,610,43,207,726,934,502,276,808,630,587,691,132,429,424,984,581,865,748,812,270,838,208,662,855,443,545,85,406,197,799,997,681,575,525,717,832,914,689,744,164,92,440,785,553,888,373,16,483,847,88,628,177,259,134,581,347,151,630,453,427,110,42,41,296,92,718,715,613,696,278,920,461,533,333,474,454,655,784,760,783,20,180,345,15,465,758,293,822,716,4,487,898,83,339,398,565,740,265,119,802,442,203,731,767,395,680,774,32,253,786,974,664,650,783,251,183,250,593,112,459,679", "412,116,417,143,361,936,970,930,287,465,354,444,242,31,330,264,701,529,297,544,303,532,624,36,789,336,133,357,606,322,574,736,920,482,499,977,649,622,532,52,837,666,810,903,217,293,813,852,7,725,481,191,668,377,109,315,636,520,918,361,188,97,584,728,698,588,567,817,142,813,116,203,570,455,753,827,716,174,137,359,52,70,296,410,603,869,640,865,0,67,85,37,385,208,26,633,138,113,817,670,650,808,663,434,194,448,614,770,258,273,209,807,214,345,767,773,167,876,887,790,317,432,456,387,43,974,629,652,105,532,479,197,101,126,989,324,523,180,588,644,202,666,102,156,536,833,246,618,58,490,216,719,673,841,974,981,77,874,306,390,840,189,696,535,84,341,723,849,142,957,270,509,404,699,395,309,587,218,520,857,173,744,99,23,415,648,232,904,455,204,922,329,919,631,917,474,881,575,150,843,102,544,154,927,98,893,92,684,738,589,766,680,422,137,277,192,362,51,249,212,909,272,843,44,539,944,93,832,740,933,483,501,316,10,863,380,798,641,925,354,298,181,533,566,366,333,290,448,590,287,650,545,685,198,252,555,952,175,622,704,379,623,86,179,356,783,284,123,177,829,666,396,814,775,611,544,913,550,775,191,1,96,322,956,334,469,906,465,85,659,119,333,673,31,27,959,590,505,171,663,319,306,764,9,84,647,760,33,392,359,942,790,42,640,622,99,897,919,197,384,996,181,20,351,429,554,925,348,514,149,540,393,786,221,969,157,533,711,380,48,665,765,48,468,166,352,506,204,730,383,35,575,326,123,576,318,174,544,901,619,32,3,948,890,206,520,319,902,278,733,155,895,392,904,847,276,740,127,333,157,624,154,273,865,76,837,689,796,74,869,16,436,792,584,486,278,563,888,683,804,856,717,993,509,736,50,783,562,81,921,743,636,116,781,19,905,328,600,420,414,255,226,165,106,495,36,831,560,414,837,710,729,798,229,580,62,169,538,934,40,201,718,977,741,142,990,423,394,162,634,205,31,755,478,885,110,580,642,61,165,234,755,370,587,843,993,49,387,708,626,146,30,89,617,771,122,38,692,388,881,621,70,212,189,272,977,510,625,485,768,806,832,894,781,354,277,277,913,768,230,798,758,213,885,523,459,511,985,665,427,88,972,751,279,786,277,55,461,798,103,916,989,420,926,999,859,631,843,450,519,774,460,479,538,277,541,214,266,173,388,337,701,864,868,544,886,272,629,683,288,787,863,354,560,72,968,943,962,1000,326,375,246,96,385,423,14,178,39,811,409,329,496,319,482,529,503,375,48,488,41,591,516,778,628,571,563,50,726,280,633,413,878,59,30,891,753,975,442,645,914,939,562,700,273,124,269,2,730,494,727,261,167,202,403,510,148,263,55,334,813,346,588,154,562,720,935,668,107,535,965,19,682,417,280,298,17,721,384,826,479,239,770,76,120,412,138,306,99,262,244,529,184,78,783,250,836,734,178,939,582,618,223,15,178,606,836,506,653,392,519,388,912,400,714,694,649,343,228,210,298,366,343,554,868,925,324,480,352,592,203,688,519,116,57,607,279,364,556,420,187,734,413,168,560,190,260,134,517,453,495,195,483,496,475,99,151,615,460,127,150,679,466,983,349,135,498,180,61,13,836,907,552,399,908,777,708,142,353,390,500,409,358,556,441,710,923,839,363,484,68,788,766,442,875,77,334,347,372,156,738,903,957,151,37,385,170,292,31,297,488,328,161,356,827,511,980,997,910,815,895,385,345,216,942,709,950,424,726,683,214,868,813,799,729,86,852,110,115,436,50,500,617,371,345,254,487,800,590,628,723,302,118,865,37,200,913,377,119,935,846,670,819,976,206,214,721,374,979,775,746,217,685,757,180,453,662,546,623,749,299,159,320,52,533,956,848,927,467,283,758,286,803,725,588,715,336,564,567,926,109,457,495,93,508,133,392,970,769,546,339,468,241,109,824,439,855,996,32,853,33,164,191,904,881,157,742,714,922,733,233,553,94,173,490,853,364,567,199,120,599,36,461,341,877,834,353,384,546,279,25,885,141,369,586,892,825,737,343,632,84,630,803,488,503,313,596,977,54,509,596,977,426,752,109,136,649,478,693,940,290,471,654,598,878,515,51,744,5,211,948,248,327,185,446,393,291,449,169,492,732,846,621,717,241,814,320,864,616,766,597,708,874,573,516,530,276,221,50,913,285,322,496,192,182,64,673,594,319,745,933,901,715,537,522,729,226,416,218,284,468", "807,639,523,384,702,64,789,605,549,637,760,924,36,551,50,613,599,391,268,67,516,654,19,63,534,844,127,637,51,9,516,813,66,571,578,379,281,566,857,800,763,464,1000,788,421,88,808,833,564,576,765,359,354,620,702,491,26,223,585,632,85,241,830,51,536,33,924,628,860,169,78,332,575,793,638,786,475,686,529,111,140,531,375,804,383,856,445,273,67,0,442,147,977,649,230,187,505,727,302,991,432,986,946,397,83,839,598,202,723,824,448,88,490,375,9,4,804,6,914,77,465,983,909,333,830,101,987,999,79,324,44,38,56,473,966,221,374,909,682,734,681,739,985,249,418,224,440,217,274,977,287,830,977,352,372,293,662,30,735,479,234,113,933,712,689,147,709,515,194,925,961,725,271,227,231,834,157,684,795,812,328,943,911,114,303,641,893,740,539,508,700,526,805,459,696,827,987,470,647,141,985,609,644,455,372,540,148,732,38,300,76,647,758,713,977,984,482,809,664,495,423,653,644,935,939,889,228,991,835,688,679,345,124,205,803,81,262,921,642,997,168,427,717,110,99,12,12,481,64,10,417,345,840,50,186,627,18,667,628,245,424,898,894,606,767,823,804,980,551,936,29,110,60,187,985,818,727,206,496,926,615,515,41,261,616,273,374,916,994,124,151,635,285,749,733,487,639,654,591,294,232,204,379,639,427,135,23,251,719,185,840,691,686,693,504,387,253,933,997,842,157,943,66,140,644,824,744,102,750,438,431,362,503,806,663,706,783,577,813,703,921,511,714,414,156,393,84,430,520,610,238,67,752,958,633,9,178,425,993,711,719,970,513,858,721,390,133,180,908,52,782,815,343,328,17,412,922,806,614,157,855,779,474,88,65,385,387,696,191,737,997,758,848,441,942,579,525,333,778,325,101,339,106,197,673,413,69,149,327,745,710,152,987,854,214,200,942,186,866,959,776,339,499,782,284,121,107,107,591,68,28,385,483,766,245,539,590,180,768,811,779,699,909,295,727,31,31,272,424,28,281,59,730,763,642,838,152,845,874,476,216,339,640,94,579,356,576,315,686,679,841,819,758,568,25,766,595,882,802,421,18,939,719,939,485,705,133,463,574,650,503,719,514,767,859,973,214,416,319,922,285,516,557,410,657,867,233,839,859,638,735,492,851,583,103,182,604,417,615,758,871,622,898,278,303,171,713,209,255,594,320,55,258,512,814,80,282,603,977,320,147,372,629,639,607,15,75,901,35,861,813,718,343,850,400,207,848,665,110,677,326,700,192,546,998,678,418,596,337,944,584,159,68,580,642,925,545,998,565,289,503,202,589,853,669,556,728,880,631,851,295,974,997,857,51,918,390,200,214,653,931,520,222,554,39,357,704,275,149,435,851,696,305,86,789,238,372,306,287,408,260,986,879,336,157,754,968,601,636,579,850,971,72,239,43,649,412,588,365,818,459,911,409,267,910,690,657,793,980,349,577,792,257,449,825,154,943,901,18,745,367,57,738,933,768,67,383,723,282,66,71,687,342,208,251,548,401,107,147,582,901,115,128,829,908,207,688,518,385,732,684,742,847,218,480,875,929,190,254,389,365,763,222,23,243,115,669,782,192,317,96,828,258,47,227,386,257,256,523,66,997,108,923,860,447,217,750,433,629,461,59,248,140,314,734,801,513,111,217,326,486,428,90,923,776,379,997,481,24,192,351,950,374,982,232,153,199,118,983,418,69,360,881,374,697,856,358,365,608,223,504,683,723,578,81,823,318,490,183,954,565,319,468,951,565,855,429,887,629,718,581,106,480,717,394,898,358,419,297,542,729,998,16,648,17,747,967,65,575,376,695,836,669,602,682,570,834,198,134,37,712,953,180,413,75,399,535,756,690,191,501,784,105,671,439,827,511,35,637,994,635,612,836,664,750,14,897,170,949,878,79,621,594,280,329,350,778,202,637,518,375,301,341,728,896,876,271,762,758,760,486,519,730,106,350,974,790,761,728,864,659,846,983,434,732,340,976,686,157,221,781,219,96,287,381,748,841,519,338,557,748,989,240,129,781,239,861,146,97,598,313,294,437,962,809,971,538,582,683,445,804,630,491,722,76,871,808,509,728,670,441,274,812,891,498,440,143,511,97,350,644,887,937,821,523,217,30,208,34,358,619,346,411,282,188,195,114,451,938,555,987,347,908,836,227,954,193,298,479,813,766,109,313,490,39,877,732,454,738,391,124,599,364,641,269,443,323,787,868,972,288,207,241,798,276,420,727,40,628,640", "765,333,896,363,792,421,910,515,202,875,119,356,508,157,373,748,883,686,318,930,457,119,911,136,434,653,584,359,898,663,610,467,463,183,939,701,749,267,342,134,490,693,851,753,684,145,204,731,438,536,919,8,939,978,864,228,780,241,473,201,573,677,849,758,710,126,439,631,475,118,577,39,530,63,813,978,886,133,353,299,293,607,897,476,164,879,26,347,85,442,0,929,376,392,925,13,438,150,507,742,513,151,798,81,984,197,578,445,393,945,658,896,841,904,145,64,179,211,351,665,704,643,147,560,761,639,63,46,981,298,463,24,374,567,135,903,831,485,662,711,686,194,809,979,301,87,500,673,719,660,177,498,469,718,124,987,138,322,780,663,664,743,968,663,954,654,704,367,905,883,106,915,953,990,589,641,289,479,58,248,592,267,239,469,390,769,769,288,825,550,674,352,246,237,218,989,897,991,500,95,840,886,142,781,976,486,666,308,622,48,3,77,479,881,779,409,707,462,886,806,261,216,166,295,257,883,402,301,204,17,157,369,162,905,457,115,70,891,563,905,767,235,226,639,381,188,961,886,335,911,289,963,240,611,152,593,178,32,634,253,281,97,47,611,407,634,340,63,29,349,318,832,704,456,573,806,507,732,917,670,249,376,813,824,378,998,74,956,578,981,403,983,466,553,34,190,458,92,631,366,908,703,703,200,925,814,81,500,873,549,935,792,134,336,207,865,314,866,842,843,868,328,551,462,702,206,28,133,859,697,447,391,504,835,729,374,689,86,114,366,214,492,561,733,599,981,248,728,190,334,504,504,934,991,780,934,667,972,291,522,73,215,807,837,464,684,285,961,808,771,249,36,607,861,465,43,7,523,404,840,948,978,169,306,873,304,96,81,463,104,168,549,498,847,406,888,39,969,338,277,883,530,723,394,100,152,610,132,517,428,588,770,650,88,29,491,306,611,448,616,456,636,282,691,470,947,116,813,384,209,396,434,618,29,271,240,71,108,577,300,231,372,853,8,416,831,120,564,412,829,734,44,602,655,842,664,125,754,944,56,96,235,226,121,439,410,663,456,175,112,934,977,717,844,341,158,589,275,75,89,540,976,677,184,188,256,460,728,480,964,408,215,178,309,631,977,208,24,69,821,125,715,924,968,347,829,505,581,129,290,177,852,440,388,140,440,738,354,6,42,882,706,2,393,348,128,706,721,620,912,518,839,938,650,689,853,33,468,436,568,53,787,648,427,897,319,506,728,826,242,131,246,51,454,305,982,383,356,155,699,394,707,198,468,546,114,673,798,858,34,244,486,70,696,455,258,444,451,27,715,33,397,698,108,734,15,565,345,512,134,637,947,271,238,265,249,42,294,9,90,827,388,567,490,559,481,280,422,938,370,803,732,140,763,300,659,927,766,524,497,970,823,109,350,967,490,224,378,85,913,295,282,981,320,588,968,40,513,699,788,886,359,529,39,585,202,978,163,504,61,226,578,945,926,732,140,572,487,679,398,233,346,540,415,618,523,254,373,721,907,91,507,861,511,796,539,117,793,576,926,74,963,622,302,716,295,530,270,221,76,372,567,848,138,872,5,771,732,593,910,501,947,637,524,239,636,408,205,27,383,252,431,37,311,628,433,28,624,943,119,722,968,166,106,954,656,393,655,939,946,691,602,971,845,846,92,118,137,967,995,589,542,973,165,982,877,68,398,497,908,149,204,408,652,61,700,713,13,984,330,557,445,123,398,620,594,54,730,948,902,831,429,831,196,325,159,984,287,142,58,84,155,342,998,836,737,476,962,612,921,402,377,807,543,806,731,328,993,100,733,549,413,930,108,889,323,902,322,774,838,539,131,408,653,114,324,60,815,758,60,815,550,857,638,602,464,704,614,302,821,76,357,587,919,855,60,577,706,460,79,429,724,940,634,344,599,613,582,802,80,327,465,913,128,373,998,866,428,360,814,152,691,426,79,285,308,9,567,609,901,549,136,546,330,242,842,964,560,875,397,367,289,459,91,826,230,638,217,515,903,142,543,821,731,844,64,417,410,59,641,842,378,977,19,401,144,327,932,17,255,464,770,88,487,121,140,2,312,945,54,204,738,861,466,467,803,419,402,361,902,300,48,734,656,295,158,876,959,404,788,339,158,113,175,175,564,297,721,666,356,130,393,118,229,484,744,574,484,734,169,668,323,484,709,356,938,33,746,509,71,479,310,626,854,129,328,398,311,244,90,436,712,347,857,370,751,509,51,119,7,37,115,459,426,214,880,506,711,498,82", "174,384,784,838,312,685,187,398,741,648,984,253,58,957,616,66,75,503,403,143,206,843,747,148,818,503,722,294,594,351,266,541,93,857,193,759,77,49,273,649,232,191,592,132,642,787,704,701,636,503,488,707,477,557,175,697,462,438,673,213,33,866,879,732,600,437,754,866,325,565,901,767,3,950,38,835,664,486,40,743,818,536,564,679,529,815,335,460,37,147,929,0,457,538,364,395,890,820,290,466,187,17,448,822,359,638,867,266,606,175,88,392,655,899,659,516,503,959,560,697,835,697,760,916,841,691,315,676,17,830,722,918,683,610,298,560,609,924,647,556,932,528,923,472,66,739,87,363,794,210,586,706,560,315,605,9,144,13,44,328,492,546,334,57,601,670,468,252,234,918,816,680,363,365,636,376,175,979,432,906,273,525,197,933,675,506,149,770,636,905,908,259,818,820,750,270,343,547,380,621,574,304,472,709,287,521,380,870,756,969,679,460,999,133,234,169,975,211,762,851,326,770,413,770,308,751,423,196,881,810,394,571,495,930,780,499,216,648,124,209,702,216,433,276,330,765,944,68,598,763,248,839,596,627,249,311,519,367,966,471,284,228,619,313,713,741,334,586,654,886,712,276,467,763,628,191,600,53,61,582,397,653,615,638,591,408,463,539,13,335,918,11,895,448,486,134,382,123,183,976,658,59,573,509,963,362,292,164,581,39,207,791,741,308,144,157,705,770,261,646,113,82,555,163,600,198,802,137,661,947,927,799,976,310,664,162,243,281,948,362,569,403,887,402,705,43,357,223,278,683,609,814,608,256,815,496,545,612,369,526,791,804,256,888,119,936,157,133,829,11,201,872,378,381,716,561,393,270,531,51,813,711,946,940,458,241,131,148,164,521,980,892,319,492,591,65,797,582,293,659,501,63,75,752,355,70,713,902,417,147,520,556,547,898,830,370,525,735,85,382,827,215,616,268,822,206,702,573,500,686,360,607,258,323,708,914,207,857,595,95,417,787,277,726,367,56,323,678,658,282,777,428,45,889,353,262,699,680,685,858,186,394,769,156,457,883,578,161,148,196,93,971,524,805,687,539,575,828,809,797,430,408,122,614,635,57,336,315,545,169,346,780,45,391,521,902,442,475,307,111,300,688,4,646,164,935,763,583,372,914,143,939,616,880,390,488,401,158,601,860,116,795,508,337,308,850,329,551,322,162,410,824,255,395,299,368,838,172,47,191,426,127,159,205,329,481,181,130,354,815,298,174,175,962,410,116,286,398,463,540,294,646,470,224,934,312,884,509,456,32,713,574,820,676,907,553,716,866,901,297,945,642,882,245,303,567,559,247,159,690,939,23,219,975,641,703,587,618,84,728,304,230,995,549,613,324,346,877,364,135,487,230,155,83,206,480,787,499,716,559,936,64,798,117,63,199,113,914,863,296,254,616,67,266,194,737,619,135,192,429,38,801,462,553,216,693,388,627,84,760,473,492,552,100,384,830,675,448,488,956,690,117,796,35,510,428,978,193,765,640,441,780,52,528,282,563,62,377,400,85,776,12,85,69,222,525,762,74,371,462,929,724,915,83,552,828,903,36,824,555,472,84,439,766,404,30,23,774,947,945,598,8,477,840,489,573,769,832,791,679,977,381,711,367,124,16,284,162,51,362,404,378,894,587,690,844,555,7,7,30,873,768,501,572,802,715,496,325,169,418,534,131,919,915,866,719,154,101,124,652,746,138,595,663,573,947,727,281,30,859,159,862,878,503,668,553,225,710,758,410,301,785,236,601,329,274,758,325,795,63,317,635,502,326,813,333,21,46,58,109,303,270,130,708,460,291,900,803,770,349,1000,477,48,754,527,336,74,217,637,126,879,414,939,366,476,204,824,200,969,248,720,439,46,771,647,426,56,954,126,716,311,308,306,592,640,437,294,194,288,67,983,299,409,199,448,713,59,302,594,546,139,326,515,693,323,211,175,254,169,859,352,767,299,222,334,177,758,356,703,656,450,194,882,935,410,504,686,305,766,688,716,639,225,311,919,800,256,655,400,573,986,457,534,943,734,111,624,311,947,223,496,549,622,506,778,112,825,615,67,620,736,478,197,972,848,66,211,923,578,754,322,776,708,159,399,359,890,313,848,19,177,501,565,23,589,654,42,67,490,125,639,264,474,141,455,57,98,869,349,544,352,435,78,489,606,768,135,106,7,808,701,877,100,849,780,744,546,272,410,124,68,45,626,370,546,560,598,426,132,29,414,239,623,849,755,47,929,800,131,205", "334,526,55,109,448,890,914,40,557,756,940,864,527,995,659,299,572,55,663,551,368,918,889,977,323,732,992,996,843,174,751,248,195,739,433,568,990,538,13,619,140,79,670,756,336,829,685,168,305,441,5,712,394,766,15,168,759,148,690,153,521,824,659,22,594,142,263,240,86,684,428,137,128,911,171,338,422,78,435,767,174,148,693,394,579,324,454,77,385,977,376,457,0,693,190,634,39,976,180,34,605,814,358,905,154,120,907,631,663,201,729,514,224,750,265,447,995,366,420,993,193,878,528,800,336,635,871,241,462,731,636,777,63,918,841,433,559,352,698,474,774,159,911,323,607,427,670,801,832,487,893,679,538,31,557,739,658,147,995,555,985,15,701,250,226,548,861,677,300,215,64,505,759,541,220,321,786,112,48,696,8,199,442,159,809,964,535,212,464,972,708,136,986,390,683,112,939,2,947,942,654,329,542,316,998,240,48,907,32,542,175,391,37,267,965,918,179,806,417,754,725,478,679,43,866,664,404,219,862,233,988,548,200,18,917,787,918,825,650,235,865,842,215,479,13,72,503,595,687,927,114,302,559,597,849,842,356,690,160,755,545,154,192,799,258,532,675,604,174,293,983,397,56,299,134,499,893,661,998,287,201,557,894,558,603,438,216,512,79,607,63,478,948,767,746,724,445,471,474,514,139,737,215,125,507,923,787,250,681,177,108,556,606,218,945,961,621,30,736,278,882,448,186,242,526,790,50,267,215,714,415,609,705,269,282,551,818,298,839,857,516,949,703,112,358,763,380,160,959,110,951,736,456,948,851,433,756,157,285,706,839,294,159,313,556,470,732,715,785,146,49,913,218,721,318,594,384,144,571,422,136,966,733,594,204,714,187,993,755,340,989,541,430,465,890,561,210,383,214,738,740,508,404,990,155,144,900,225,301,894,642,328,424,889,970,95,47,256,408,716,348,295,310,183,17,995,283,106,603,890,695,178,358,365,434,244,579,688,379,698,877,977,145,470,31,337,938,747,232,164,198,868,909,960,941,313,901,895,790,429,507,518,290,354,77,530,706,89,992,813,852,18,976,336,722,276,897,728,867,973,77,643,300,682,615,749,175,982,111,437,17,587,165,645,668,86,507,992,524,473,317,999,466,607,749,475,522,186,560,383,442,443,325,571,89,438,137,533,426,57,357,434,697,95,859,488,184,885,889,486,52,900,730,232,502,995,994,628,431,515,946,290,540,919,195,929,966,921,143,181,118,427,817,277,694,680,801,463,889,94,412,760,335,104,56,905,614,822,376,460,668,937,761,751,450,908,361,341,415,929,503,994,391,196,11,44,467,574,568,256,405,878,876,518,309,562,488,428,409,993,281,747,713,531,277,169,137,903,618,206,806,837,955,796,200,826,328,475,89,814,110,542,773,145,318,541,224,261,225,922,506,876,2,355,831,482,156,252,696,442,993,933,652,670,896,314,131,11,758,91,704,607,60,836,86,482,18,131,555,557,226,47,582,986,874,814,660,502,605,497,214,114,472,472,207,256,673,876,60,973,683,677,159,456,94,657,486,449,478,587,363,471,303,370,827,811,108,878,589,440,420,22,263,116,301,25,379,594,427,178,579,739,972,540,934,51,117,756,980,419,939,65,4,424,552,123,49,381,280,434,351,425,671,679,867,217,337,691,326,922,559,976,742,341,952,712,307,637,689,109,487,620,898,46,707,58,388,69,779,570,318,328,898,691,888,538,583,478,207,428,959,823,777,771,657,565,891,366,891,959,615,804,243,627,626,178,184,226,735,3,543,391,704,750,54,569,303,88,58,689,831,141,91,569,278,648,94,530,19,118,632,931,921,908,16,995,664,27,555,989,559,765,161,856,388,280,543,95,303,644,54,266,196,353,571,764,549,332,902,241,436,172,93,568,733,558,324,549,157,49,630,857,93,947,771,991,634,94,518,771,340,701,757,428,608,846,694,459,880,275,760,853,709,671,592,874,985,452,268,187,944,520,419,578,123,277,294,965,771,732,671,757,169,700,142,922,852,406,486,874,956,729,570,788,392,116,165,90,856,653,605,843,800,234,646,2,148,400,372,733,813,654,499,53,771,259,443,969,638,575,878,5,274,81,264,483,3,557,447,991,113,388,232,172,313,217,575,90,346,124,511,902,264,394,445,892,843,395,602,274,360,923,619,225,27,183,90,803,169,348,514,519,485,993,175,106,317,436,869,797,926,81,692,800,196,815,884,522,888,964,181,585,819,969,886,101,569,8,204,520", "77,980,673,41,312,581,381,15,931,91,302,245,966,608,986,484,571,934,268,906,152,462,747,282,600,866,108,953,917,547,672,29,681,527,187,457,905,922,282,981,518,536,790,582,912,321,599,826,23,352,641,178,828,803,782,431,33,434,673,805,341,905,451,89,966,337,437,494,393,374,540,432,717,677,438,595,425,892,322,422,54,572,134,518,951,563,850,449,208,649,392,538,693,0,197,186,781,479,786,953,220,763,356,880,847,695,518,473,803,202,120,692,461,701,957,39,311,31,597,366,127,331,880,761,183,238,600,919,682,254,11,112,965,294,586,541,94,627,988,992,868,195,574,996,175,949,867,287,76,976,773,269,507,986,420,508,756,869,275,499,562,344,62,353,124,285,440,304,455,573,674,52,64,692,373,340,766,198,764,574,525,785,648,688,453,551,265,665,739,832,915,715,281,278,804,472,822,45,176,431,717,314,276,3,984,173,449,741,890,368,324,901,458,345,462,919,513,575,496,827,526,413,382,378,971,392,16,79,194,246,214,256,217,89,965,124,57,717,215,63,225,261,307,487,953,414,715,206,667,526,803,366,212,539,177,607,297,944,29,78,641,895,193,917,825,824,264,902,292,839,379,624,872,949,487,253,838,411,938,722,109,242,613,63,313,739,526,341,236,851,428,534,562,124,537,369,650,313,165,152,873,684,27,984,367,695,233,562,185,307,540,938,945,32,201,482,948,67,352,896,395,667,809,125,22,572,794,711,71,678,291,469,939,262,125,147,773,527,263,649,743,2,576,125,173,830,241,912,948,95,208,652,86,227,552,685,299,216,732,678,789,219,973,379,123,457,40,488,387,307,222,430,253,503,68,605,141,862,311,701,740,163,982,325,911,257,198,537,416,12,815,193,921,736,273,173,551,76,129,844,793,291,811,70,123,16,630,503,474,698,851,19,76,96,977,222,461,181,249,291,379,153,423,360,265,762,424,596,862,710,109,404,858,410,666,486,670,75,529,167,556,349,562,150,274,907,365,612,555,666,936,134,282,955,504,570,26,679,200,845,668,512,580,270,958,32,399,124,383,986,412,959,930,220,669,510,237,456,764,363,173,180,280,248,271,385,271,336,948,454,842,372,332,45,163,265,706,941,706,526,462,522,7,363,802,791,615,477,352,641,816,120,397,55,846,374,426,747,935,822,431,658,75,236,122,846,844,669,29,813,627,320,387,55,350,487,721,938,427,706,147,932,775,34,418,12,963,97,277,905,435,337,775,956,760,700,358,230,169,547,368,276,845,576,560,311,978,688,965,337,806,385,415,615,994,867,526,635,698,446,197,743,566,382,789,533,653,817,638,805,413,236,66,73,531,322,337,967,304,130,413,400,836,248,462,818,491,514,266,323,916,445,355,665,686,464,28,643,110,641,727,640,8,409,572,797,791,995,329,233,119,531,908,836,34,784,343,108,928,864,954,802,138,636,436,823,834,333,812,568,616,41,329,419,371,439,47,804,336,88,929,101,288,218,914,434,274,192,445,761,108,107,856,856,498,243,444,463,84,798,704,757,565,771,859,578,286,138,784,590,917,822,498,919,61,844,944,729,934,894,731,433,956,814,228,117,656,114,514,528,573,226,195,378,86,746,565,83,432,801,879,344,492,18,223,163,995,315,124,498,25,433,710,736,477,500,558,628,981,263,797,962,76,788,944,531,842,316,431,531,324,345,750,25,500,425,360,889,479,495,76,912,205,660,514,558,123,506,968,455,869,512,950,793,691,243,518,142,932,748,100,161,845,708,885,826,338,683,932,31,563,697,269,726,527,693,706,662,15,808,927,295,970,777,865,339,352,548,567,151,288,507,443,996,748,843,54,591,326,79,275,614,328,754,128,854,136,782,726,18,184,590,44,998,793,275,669,235,17,308,782,237,300,219,917,962,546,566,550,862,110,443,115,365,219,698,181,710,103,166,385,221,834,218,101,411,824,69,120,951,870,591,834,131,863,62,676,16,560,474,957,106,727,200,462,77,149,711,975,591,825,258,959,152,244,32,908,703,447,566,310,577,568,248,415,860,656,865,402,686,407,591,860,624,435,316,724,191,675,674,12,176,743,413,725,665,565,760,80,209,583,236,693,213,756,434,449,884,298,932,677,406,770,151,433,432,416,634,40,629,570,13,600,300,58,985,879,109,629,320,174,444,284,176,168,540,386,387,66,660,573,61,440,438,835,974,724,444,875,760,881,861,28,110,922,631,822,424,655,381,806,65,212,148,295,936,239,533,29,91", "930,764,417,294,410,899,999,193,904,38,476,829,612,806,328,672,325,24,45,222,612,552,704,753,182,832,382,117,789,524,385,14,866,56,997,440,16,572,684,365,706,635,230,918,475,109,528,204,157,670,215,607,808,629,801,511,295,612,873,974,275,667,334,820,967,40,888,698,89,720,851,284,293,315,266,929,744,504,780,839,57,148,263,637,610,728,944,519,26,230,925,364,190,197,0,421,934,583,210,353,616,31,760,879,525,329,272,499,416,569,94,224,253,512,102,264,865,705,837,607,591,828,100,516,323,166,448,137,130,777,403,14,450,143,61,550,235,818,26,745,742,115,443,4,697,703,369,109,733,707,527,868,632,724,443,662,311,277,413,398,195,232,988,646,687,834,749,593,680,592,556,510,381,855,322,424,728,147,3,394,669,788,491,345,360,729,677,258,677,431,624,847,821,514,150,915,881,541,597,7,124,839,197,17,856,98,256,66,563,647,593,835,840,598,167,546,99,244,936,464,769,640,126,205,82,869,16,987,318,787,671,572,286,994,322,30,444,158,598,142,135,575,391,548,470,767,118,195,564,656,661,587,4,253,219,753,976,49,584,742,155,463,48,573,201,981,416,322,343,252,114,393,64,86,175,997,95,16,974,330,797,740,307,544,312,844,259,316,197,81,464,38,170,909,53,666,633,19,832,654,168,355,154,952,130,233,742,834,248,85,888,488,615,305,464,486,146,129,70,133,487,621,842,828,966,553,268,308,311,300,120,924,384,697,514,191,798,720,202,761,813,68,891,784,695,15,552,363,789,516,554,669,369,787,407,161,241,272,606,385,883,773,883,821,370,94,290,374,659,10,292,273,701,863,784,820,100,370,409,709,110,248,393,135,536,473,117,78,361,78,504,636,599,417,852,960,890,714,897,539,879,17,46,313,892,140,614,466,138,576,883,520,120,582,772,106,706,326,782,595,502,79,659,289,202,36,303,519,719,125,645,697,811,224,998,533,926,462,887,324,497,958,706,976,666,12,390,838,570,692,301,791,860,747,925,370,77,776,13,200,16,108,13,150,714,687,688,356,720,281,692,747,947,37,296,886,339,466,74,417,738,797,573,389,349,614,200,691,140,890,693,376,886,778,329,768,6,840,387,590,460,698,854,351,842,970,493,647,447,770,798,253,790,719,608,171,327,421,771,399,604,265,328,856,706,941,503,358,825,612,505,450,524,17,289,5,816,136,648,186,840,864,192,29,45,168,383,103,772,639,359,981,430,24,217,238,381,244,393,460,976,953,690,987,499,625,841,838,62,639,511,303,641,778,862,662,253,607,678,361,59,190,387,120,907,224,818,140,895,115,660,208,815,781,480,434,584,981,46,709,441,843,565,394,197,929,455,205,619,458,58,489,991,365,973,522,204,195,71,954,855,693,549,561,608,93,559,897,406,774,757,580,810,611,670,475,841,829,951,400,769,271,366,895,225,659,57,507,938,362,351,300,700,229,498,890,470,27,631,278,223,236,478,804,121,910,125,776,273,108,854,454,376,539,781,804,669,166,522,604,619,785,985,402,41,278,132,8,607,925,388,453,786,457,699,961,968,877,884,975,686,324,976,883,353,919,935,668,362,326,310,786,82,206,329,62,53,998,906,760,680,484,599,795,243,622,489,424,88,103,468,160,77,476,977,554,418,355,3,514,347,827,333,56,176,851,477,683,598,599,859,473,457,140,233,966,422,82,129,523,343,558,913,410,298,164,516,338,726,302,810,668,184,904,580,51,378,266,775,214,712,599,2,554,15,585,335,222,206,321,419,920,249,225,919,422,240,861,571,306,230,689,846,975,83,868,587,670,779,99,747,115,870,169,505,246,610,216,831,862,534,371,79,866,19,650,231,24,95,296,377,382,693,661,35,790,446,576,863,75,496,432,37,739,79,402,505,539,529,373,557,428,646,8,736,420,812,697,685,274,662,357,748,726,378,378,782,919,767,990,374,712,818,984,46,382,850,946,561,427,946,364,856,757,560,860,175,352,268,698,504,588,243,933,812,168,252,459,683,238,802,296,558,314,869,277,190,95,169,856,498,857,977,911,981,624,651,737,366,218,684,877,752,946,402,968,853,36,838,579,83,410,410,517,541,357,535,454,645,418,814,112,416,386,362,834,989,320,61,235,158,299,359,172,868,560,54,143,648,616,917,277,222,656,462,983,317,172,868,667,47,36,956,883,341,750,707,796,217,439,266,317,317,633,284,295,890,722,507,820,479,701,700,499,327,131,509,268,936,777", "536,929,665,160,924,792,749,759,155,732,19,293,88,928,671,515,666,774,149,144,452,310,317,58,193,657,987,664,174,774,367,794,349,326,673,516,751,198,878,151,934,232,549,980,987,713,963,450,310,428,755,46,285,444,999,321,625,319,632,866,682,952,493,376,381,161,956,524,160,519,310,274,742,894,354,545,926,527,494,718,223,317,198,471,703,771,211,11,633,187,13,395,634,186,421,0,508,44,737,836,718,50,584,397,145,27,249,965,637,668,699,624,631,614,983,135,428,352,184,668,91,656,370,845,911,475,459,487,885,690,564,841,910,522,432,671,626,663,193,536,317,421,321,859,879,628,310,944,157,712,315,84,839,487,916,237,606,569,248,995,90,905,151,160,847,483,978,20,973,291,34,517,652,671,255,726,6,372,829,872,638,387,978,837,414,164,746,120,430,474,640,893,57,234,427,571,969,389,178,290,756,641,976,532,230,306,547,501,696,299,341,526,40,213,268,538,732,95,922,923,123,5,280,354,789,553,144,42,657,121,69,851,952,316,521,276,55,681,736,982,24,137,797,114,279,628,752,426,530,142,798,546,192,196,201,12,645,236,637,363,653,683,973,182,418,178,249,265,81,236,539,146,647,341,263,229,48,777,321,260,469,238,322,221,105,31,846,294,146,329,303,201,634,556,89,295,994,274,864,526,773,894,15,615,33,173,755,13,639,288,437,617,459,642,234,434,889,944,456,653,757,440,725,438,753,496,952,440,414,975,207,459,217,588,565,826,60,457,603,646,827,993,901,620,368,893,345,316,668,946,698,481,520,43,531,311,666,156,454,971,126,899,533,34,600,729,306,931,175,373,156,58,148,518,120,120,284,718,538,570,917,250,357,603,738,812,198,735,759,838,740,877,140,366,88,965,643,174,175,30,824,894,61,163,676,839,37,989,643,779,728,881,3,101,961,90,336,185,807,851,536,121,529,55,834,413,967,168,920,220,626,877,333,368,871,827,77,277,59,960,147,443,255,76,980,468,185,779,893,643,434,904,178,378,68,70,755,48,510,948,425,12,901,18,351,522,796,397,510,823,36,207,223,971,397,896,817,68,244,123,603,966,996,736,329,371,758,616,606,829,525,781,227,49,695,245,206,856,909,661,686,105,146,798,204,762,84,409,951,773,901,394,345,281,746,835,287,245,252,88,360,636,769,498,253,19,392,5,187,744,493,217,278,169,186,946,346,557,748,722,620,940,422,69,47,258,400,732,644,483,92,999,513,623,228,975,876,785,119,218,360,436,433,14,343,615,909,125,166,527,75,261,877,366,890,718,794,130,780,841,644,469,572,207,467,808,619,786,53,823,250,184,19,187,490,759,695,364,874,848,81,338,245,692,147,993,533,17,375,857,699,720,793,258,668,916,893,991,197,161,926,50,653,23,46,155,525,717,12,769,128,842,43,61,548,330,521,809,346,754,29,21,57,809,554,956,95,484,374,980,545,937,61,932,755,164,994,464,464,908,497,748,747,816,509,760,391,230,598,578,550,879,261,525,121,710,766,210,280,748,192,413,55,64,565,795,985,808,180,939,298,923,667,564,462,751,356,562,991,561,119,866,633,135,69,4,600,59,212,780,1,84,300,409,641,458,517,564,337,290,774,571,981,666,242,618,323,241,329,126,705,853,792,618,553,93,879,290,627,474,831,402,849,649,107,161,794,739,981,928,573,501,617,347,897,334,23,910,539,634,580,340,898,85,815,206,868,691,586,866,388,103,472,412,482,997,958,665,749,618,425,669,405,753,832,275,844,542,769,668,588,734,773,326,156,876,371,561,7,762,826,870,184,169,381,310,98,689,794,101,483,29,473,291,370,108,411,567,691,938,903,831,194,638,986,286,43,487,561,649,129,677,944,328,535,214,410,837,973,892,514,114,804,576,84,832,583,445,324,75,824,855,381,31,229,674,511,93,259,358,916,528,422,360,26,131,197,148,577,174,971,710,474,537,965,142,283,910,316,797,96,526,224,370,83,612,284,426,447,509,57,123,159,149,486,839,232,759,720,794,963,698,845,163,665,503,941,763,957,987,969,157,194,583,363,958,357,756,817,917,256,827,739,397,288,437,165,194,598,310,917,328,338,831,743,893,201,687,429,54,260,850,666,540,965,311,979,635,851,274,510,250,898,507,632,189,814,395,236,580,53,357,958,253,947,513,321,278,425,375,105,367,443,634,495,993,27,135,926,883,22,770,867,307,801,503,523,830,527,548,42,951,637,142,547,309,22,649,430,692", "885,183,893,950,337,947,341,461,418,141,145,562,946,415,395,531,847,331,105,697,229,954,309,490,719,829,160,39,486,66,781,895,259,970,217,479,620,25,505,906,198,248,991,205,684,80,262,367,414,548,240,647,999,916,828,34,361,5,310,539,697,341,529,600,729,737,152,84,515,68,89,560,923,258,284,804,310,668,10,779,373,651,246,786,153,503,283,291,138,505,438,890,39,781,934,508,0,577,911,843,570,583,560,856,498,383,91,218,213,238,396,83,109,172,284,72,470,50,670,32,76,62,624,864,10,438,780,2,571,268,41,91,828,811,144,569,678,377,244,727,918,296,404,890,590,924,407,125,221,149,642,465,261,49,494,910,525,252,614,629,485,665,857,143,948,607,681,45,971,849,437,250,923,612,610,378,897,390,337,196,195,80,408,640,7,267,207,443,727,266,934,870,837,807,972,802,437,435,824,545,76,385,444,324,711,83,292,125,92,981,481,499,705,961,177,892,992,101,298,460,213,929,671,560,882,689,94,445,42,429,199,317,741,608,429,305,13,219,152,230,851,381,376,664,935,749,891,622,819,359,891,570,66,656,171,977,786,654,127,90,162,506,637,775,959,226,415,316,441,318,469,963,6,114,76,448,995,873,954,389,94,876,439,320,489,120,708,328,559,729,431,642,211,468,46,19,13,583,686,567,269,994,117,932,205,124,400,57,684,175,778,288,264,985,361,692,315,887,935,375,337,76,555,348,44,933,55,108,125,369,949,105,540,43,277,313,128,341,216,305,96,853,214,435,172,476,163,594,292,261,484,391,883,775,654,827,606,461,753,839,890,634,809,475,127,977,363,241,298,178,455,827,974,290,239,530,900,230,603,776,180,169,132,212,423,300,307,623,287,386,632,222,299,135,221,889,635,657,899,887,301,330,254,113,474,14,67,326,69,334,218,157,835,111,196,103,292,390,278,277,181,261,473,384,906,868,74,903,696,966,87,906,136,249,1,799,545,323,123,481,888,176,574,515,655,99,245,167,257,982,530,495,720,219,799,963,841,682,498,617,701,465,369,617,31,49,34,440,325,377,651,530,174,162,137,771,979,655,788,480,731,893,27,996,499,511,451,554,401,432,720,19,938,350,200,166,184,997,361,68,554,908,530,511,222,295,5,272,208,597,690,792,628,326,480,853,268,786,499,312,95,144,125,636,695,112,576,79,28,210,210,590,496,874,92,675,701,280,643,916,454,961,449,960,88,700,992,366,744,248,765,7,386,33,623,48,457,339,602,96,293,670,311,173,705,867,613,991,525,700,868,602,563,875,532,858,423,916,117,447,1,676,822,896,966,125,761,101,255,930,215,886,205,7,54,345,64,301,67,270,220,475,495,515,640,400,931,100,138,819,379,809,581,930,200,106,446,556,461,732,293,775,247,958,277,157,20,761,60,375,124,980,101,576,71,919,301,5,547,372,235,98,283,721,74,815,478,205,235,632,724,327,444,559,938,286,990,617,599,522,400,312,420,502,507,180,413,596,901,143,339,849,298,273,182,90,279,191,556,558,935,872,160,956,94,865,827,183,239,435,631,384,683,400,579,53,881,395,460,884,679,246,685,651,883,548,446,555,160,102,193,43,222,477,30,311,707,141,125,228,120,914,91,668,865,607,639,530,412,608,885,699,987,414,744,910,474,777,813,609,585,619,246,800,336,888,383,445,847,988,649,338,808,794,621,390,949,629,124,852,983,442,359,616,142,77,835,545,875,870,919,254,569,937,683,840,472,409,79,471,356,449,659,421,832,767,500,210,278,362,56,372,214,602,611,491,274,325,292,655,760,725,340,235,79,391,59,612,655,139,552,384,941,742,380,584,523,822,145,741,480,781,603,152,521,266,968,968,825,436,684,795,318,707,860,195,324,910,935,319,357,301,878,410,797,87,695,724,712,910,565,856,746,326,879,980,20,672,162,960,158,326,25,770,777,864,170,722,507,754,354,107,209,606,361,326,153,550,474,243,116,367,658,287,307,121,784,849,71,790,607,522,101,480,884,951,556,172,179,365,30,328,264,388,694,836,173,448,492,915,807,721,122,587,266,535,711,727,500,918,578,587,995,316,239,815,96,174,852,584,688,415,693,576,812,360,638,281,187,1000,785,516,427,599,458,851,14,644,97,989,940,883,612,641,737,938,430,170,162,813,970,903,772,444,351,965,407,524,344,581,177,306,38,109,533,86,965,452,326,943,914,654,961,859,436,917,299,117,883,969,457,31,801,910,621,778,316,313,52,275", "533,987,870,754,720,188,828,212,527,802,863,126,542,414,473,836,750,257,440,334,709,895,578,62,736,413,340,792,914,935,267,66,754,857,108,236,756,996,999,251,959,99,369,220,399,751,337,998,264,302,300,932,993,625,740,878,83,970,31,707,830,224,234,610,5,188,439,656,331,546,651,549,351,74,79,517,881,587,753,636,970,421,269,664,651,888,244,187,113,727,150,820,976,479,583,44,577,0,993,710,382,712,174,507,466,271,779,54,912,942,366,637,829,240,993,577,450,486,356,812,48,528,589,534,466,224,599,96,830,866,233,594,573,102,621,468,44,469,242,577,686,202,767,507,311,772,867,584,973,464,554,781,236,610,403,634,875,543,215,980,484,599,133,290,15,287,716,449,725,119,917,430,578,755,914,469,87,507,399,279,468,787,24,639,998,391,74,967,166,430,535,401,429,72,836,859,425,654,256,486,682,277,134,694,488,671,677,85,736,27,391,62,557,465,516,833,323,505,477,237,474,581,451,235,472,34,691,191,260,362,637,43,117,692,579,729,755,439,887,997,93,892,317,251,236,294,116,882,641,515,540,18,821,713,946,550,112,459,303,120,188,473,152,832,896,531,254,306,397,16,202,479,133,7,737,469,697,626,72,830,470,141,279,455,282,704,865,763,358,499,777,219,970,715,916,298,328,920,495,632,66,255,19,708,890,856,967,575,28,829,361,173,410,114,917,555,678,358,355,70,623,433,407,219,408,658,815,229,76,635,754,54,50,925,651,829,302,719,13,113,378,252,943,901,897,218,732,117,538,423,563,261,877,910,908,349,263,459,196,196,235,922,961,802,790,348,718,998,166,957,432,878,453,486,904,605,258,477,955,830,588,267,459,166,993,648,109,442,5,619,214,402,235,798,469,69,187,356,286,409,995,181,660,300,39,572,71,43,603,322,970,653,334,950,564,84,37,865,318,925,31,175,956,921,222,956,491,284,27,382,976,144,684,477,607,14,965,590,307,458,159,289,369,606,707,294,924,421,679,339,890,602,947,942,402,545,875,533,313,789,260,515,667,978,322,998,952,667,269,429,86,214,52,805,368,156,301,526,77,336,497,328,147,114,763,519,726,171,288,893,615,253,588,538,457,139,523,340,950,439,689,299,225,433,252,120,706,439,316,356,128,529,573,263,361,337,484,450,259,66,561,730,395,152,493,760,686,386,539,292,478,206,228,268,325,578,81,896,304,752,900,881,265,782,431,463,661,1,148,991,336,522,144,486,79,55,870,533,545,834,119,869,271,253,47,145,839,311,598,106,267,773,667,731,658,613,509,687,883,457,924,707,835,343,625,206,625,920,68,539,684,351,475,104,849,598,82,419,389,38,118,776,442,699,856,146,558,531,872,119,61,468,529,933,293,782,276,639,838,940,66,597,128,955,218,866,509,604,24,89,614,515,632,946,308,337,167,209,116,477,810,958,43,684,846,736,796,619,475,408,257,300,255,463,767,219,889,619,981,3,601,552,18,413,201,752,645,424,703,173,740,87,115,891,640,933,702,286,889,247,422,607,931,18,93,112,939,66,792,450,309,882,177,679,501,653,343,838,131,974,890,521,837,723,240,490,984,787,606,25,912,133,690,755,358,103,374,91,703,128,154,274,724,152,378,630,257,348,177,628,547,380,927,374,90,71,321,714,130,478,452,559,306,833,719,574,459,341,727,873,433,19,829,206,669,875,216,926,201,251,205,434,69,918,489,962,652,432,716,260,935,503,104,106,872,507,106,833,374,281,115,697,952,147,76,406,374,412,896,133,245,907,821,845,906,682,70,227,607,8,552,840,545,139,286,829,257,275,995,30,387,552,991,551,983,694,923,805,185,982,320,761,281,518,657,145,821,402,988,479,331,448,343,226,533,820,679,175,251,941,588,392,407,305,692,749,59,325,543,718,284,261,576,308,224,36,983,816,829,761,246,653,467,29,737,428,90,518,603,528,186,709,897,880,13,673,537,902,37,761,109,757,669,859,791,563,338,989,987,406,997,382,584,793,463,163,191,200,385,163,236,368,241,168,400,905,330,372,177,428,423,619,271,660,382,946,717,579,261,794,283,680,782,189,966,731,725,755,929,482,41,171,948,499,117,786,385,861,773,521,617,961,985,87,884,534,623,456,790,591,531,938,924,439,946,908,767,830,676,774,817,445,976,746,330,108,175,65,170,735,816,64,963,792,50,739,304,30,694,177,125,941,946,730,380,190,598,337,79,845,250,6,99,96,867,419,324,229,569,944", "202,806,4,224,907,981,857,870,881,664,675,657,398,584,566,420,26,348,737,527,470,890,799,174,367,245,478,786,698,563,425,34,100,851,396,520,142,101,515,184,106,996,500,484,958,677,700,372,472,619,833,91,305,52,342,703,653,559,326,391,840,66,837,91,209,374,258,669,154,941,102,908,79,42,230,119,325,817,960,138,450,194,4,574,264,338,609,46,817,302,507,290,180,786,210,737,911,993,0,701,224,422,111,754,310,509,908,865,478,422,924,147,32,972,500,125,921,4,316,624,452,246,758,650,335,626,62,874,638,383,431,294,921,770,42,847,888,671,803,278,369,860,71,564,66,486,475,521,128,244,885,968,408,640,151,289,701,538,279,240,321,162,299,885,463,531,15,526,177,68,716,360,732,973,439,983,834,170,723,867,393,854,214,457,716,798,612,652,850,77,788,637,491,319,384,116,18,676,629,595,593,250,522,718,163,286,571,473,56,620,585,971,354,289,512,12,305,195,335,453,364,596,245,457,302,82,460,431,934,528,877,306,748,623,659,539,666,59,824,763,777,938,878,120,328,665,24,810,2,561,272,881,872,428,72,337,142,618,862,985,496,423,978,608,939,409,487,23,795,355,276,362,723,15,850,255,542,56,437,189,726,627,923,914,974,286,87,31,426,927,741,806,211,124,533,95,598,443,149,129,114,739,246,224,305,406,194,2,172,652,393,464,64,437,338,413,289,377,139,197,743,171,882,945,427,231,988,564,813,799,465,899,273,158,747,986,216,819,694,645,889,929,824,886,142,84,387,280,598,964,265,234,963,557,202,815,83,165,598,292,294,433,61,844,661,773,793,264,255,160,858,950,534,128,965,120,298,963,102,797,518,144,654,60,805,673,335,545,448,46,471,51,466,230,741,3,322,812,569,611,929,63,157,263,550,522,542,545,149,598,108,827,186,557,347,322,860,98,609,528,365,178,30,322,574,652,795,753,384,925,985,888,215,388,223,794,838,220,585,502,916,363,590,14,836,551,863,722,695,710,383,255,600,217,833,532,449,82,507,658,237,396,134,148,31,433,109,947,251,629,558,521,94,219,331,157,516,269,165,288,473,811,235,363,567,585,359,401,814,596,168,523,898,725,350,410,293,289,837,864,583,383,265,448,368,65,861,76,967,247,219,668,355,371,987,504,871,813,302,584,317,635,358,211,641,303,986,315,789,34,517,855,963,746,511,353,805,838,518,453,790,63,556,667,414,193,533,143,942,825,595,618,763,545,945,968,829,391,145,298,173,545,896,159,124,595,914,294,624,924,681,81,686,842,943,88,552,822,329,786,750,141,759,974,925,89,871,611,113,437,184,841,357,210,653,193,439,392,920,357,681,199,821,528,917,393,206,151,329,812,115,315,999,476,186,710,397,651,660,659,274,859,590,463,808,439,372,736,966,763,365,410,199,988,955,321,860,682,599,825,65,136,671,519,165,485,621,847,639,302,432,338,909,922,232,919,677,157,976,450,266,81,841,881,674,138,231,952,498,498,230,129,782,988,900,212,429,884,24,844,595,824,499,282,131,288,932,862,57,972,297,955,760,240,802,635,381,35,919,772,846,543,482,231,463,167,710,394,937,630,754,764,58,421,395,519,431,630,486,116,342,138,149,676,423,382,892,330,803,10,572,343,107,532,422,749,790,832,94,116,77,241,817,795,975,778,937,518,676,265,335,515,749,302,950,978,983,743,375,416,338,209,565,287,877,943,179,463,488,799,649,489,520,61,31,180,784,725,333,676,611,399,414,514,859,327,420,232,26,58,306,766,186,984,43,905,495,514,249,821,749,645,278,801,995,840,243,592,92,293,122,674,651,697,837,823,355,835,424,594,767,996,562,284,79,75,706,816,98,123,355,79,527,758,413,73,129,660,860,982,820,994,914,950,163,334,207,824,740,508,190,465,962,700,465,829,229,453,709,691,553,793,648,611,611,321,426,850,315,413,665,356,11,756,676,796,958,275,327,207,614,541,746,66,663,297,953,276,891,363,646,832,394,819,109,527,248,261,549,788,786,136,194,748,185,19,804,550,25,342,650,726,149,209,4,67,69,653,518,117,606,44,174,676,867,982,149,602,200,276,799,910,429,315,659,380,11,278,53,140,457,556,342,442,60,565,311,922,115,115,737,937,647,804,45,581,840,349,93,653,642,276,732,19,388,535,116,60,557,909,681,330,381,748,662,252,814,272,654,778,246,821,773,129,772,576,768,701,739,284,32,968,217,452,519,293,490,520,559,185", "191,519,795,659,222,373,735,888,546,824,876,764,439,674,432,883,949,383,112,215,799,622,893,879,835,973,396,627,218,511,123,549,334,762,427,525,673,4,939,675,367,562,465,395,719,343,766,548,536,309,932,135,439,511,527,858,508,14,811,398,928,229,970,6,745,215,274,941,529,459,488,3,902,826,379,485,361,859,518,965,853,436,692,413,727,275,194,455,670,991,742,466,34,953,353,836,843,710,701,0,887,566,273,185,811,311,502,841,5,179,459,929,203,991,358,869,573,671,895,684,340,257,896,774,637,763,547,976,338,595,170,57,361,675,483,656,285,832,96,447,108,508,330,842,886,127,545,189,28,556,849,834,54,187,523,197,317,646,372,562,675,865,928,556,921,188,57,966,153,708,346,127,813,633,553,509,629,714,302,690,133,453,786,485,727,61,968,312,846,286,250,838,455,214,982,757,423,473,199,714,51,998,635,266,891,831,237,280,247,572,156,32,459,647,700,987,739,456,256,503,478,848,44,297,138,747,64,268,450,161,549,898,643,245,759,946,252,360,479,894,729,875,782,835,392,124,628,776,405,435,413,236,120,230,288,101,537,51,103,519,240,360,841,914,513,910,535,790,484,322,441,708,537,81,595,123,491,414,878,429,802,447,281,792,39,674,159,460,3,350,817,689,180,751,795,411,8,364,470,8,93,318,64,443,235,650,545,168,311,983,113,762,335,388,905,746,929,93,528,129,907,100,698,669,417,314,70,839,429,503,926,423,879,803,302,506,440,966,330,572,892,498,756,435,42,831,389,47,963,304,320,284,343,966,219,311,409,628,184,253,832,368,92,354,197,43,439,262,616,350,896,865,220,133,971,307,497,771,946,909,737,755,58,299,380,580,822,656,917,885,974,263,699,662,407,292,539,824,245,736,623,25,33,592,789,394,326,160,151,214,879,546,49,60,459,573,40,252,934,493,887,190,942,698,809,620,686,767,926,274,134,862,178,308,940,767,633,839,366,828,602,92,60,406,241,551,4,401,199,760,341,735,405,739,314,96,8,307,835,193,76,805,231,266,953,54,947,888,758,100,37,282,149,220,978,557,256,828,176,41,659,294,397,907,654,791,340,531,392,567,283,977,276,758,70,672,543,218,590,9,899,433,576,367,948,303,585,92,126,91,700,461,698,114,994,11,760,171,428,575,605,148,597,123,218,518,225,277,694,958,650,977,45,470,709,812,411,772,413,420,673,864,308,366,389,171,200,214,441,314,218,626,376,433,733,217,933,729,978,835,593,36,955,583,8,420,808,712,404,793,504,209,420,617,406,848,958,441,793,616,319,343,789,287,542,59,554,287,336,370,892,234,848,67,848,335,297,166,781,232,801,991,992,491,547,660,132,352,3,108,304,341,943,72,242,980,908,733,289,642,108,462,83,272,140,145,433,164,407,839,12,389,659,942,269,972,439,5,685,81,666,936,864,596,775,710,819,418,332,396,255,338,561,480,244,932,464,372,67,819,17,945,727,810,254,475,640,280,761,672,134,885,718,339,439,142,629,964,512,25,887,415,303,650,366,807,368,19,752,903,195,461,107,799,559,6,51,450,377,104,395,858,465,633,239,33,369,274,235,58,676,375,798,370,768,654,562,633,29,742,475,311,386,580,943,711,665,363,103,560,104,149,495,591,951,499,982,370,883,914,602,644,810,954,80,905,65,480,197,826,579,181,654,611,485,621,308,352,862,272,258,864,55,977,274,128,112,943,59,246,142,312,264,21,876,618,63,102,799,976,206,189,663,673,624,973,939,926,251,869,759,493,796,248,577,90,508,60,909,453,462,212,927,385,801,66,701,515,767,361,34,232,568,35,615,284,654,94,979,872,93,556,45,939,489,163,708,375,649,941,74,943,491,258,14,171,976,398,736,872,238,25,3,569,74,429,34,262,45,552,403,453,386,383,819,95,863,336,250,599,957,513,41,486,633,73,877,949,53,926,160,137,138,698,568,608,697,557,712,44,933,303,618,366,765,553,561,589,798,569,326,923,607,53,410,684,526,20,221,908,282,893,412,779,187,38,605,657,945,403,286,760,766,536,623,708,1,733,644,222,575,912,149,837,990,251,486,167,135,301,105,782,267,898,446,323,526,790,92,52,521,294,33,785,116,120,380,611,798,51,170,168,617,632,180,607,57,45,978,593,482,774,200,605,195,326,484,349,372,962,766,61,464,432,55,230,570,109,701,900,967,283,941,943,125,860,837,263,521,993,607,435,740,84,949,421,533,160,3,906", "825,293,396,377,319,819,438,208,216,107,400,376,223,887,162,621,367,315,30,677,404,179,894,995,176,781,849,720,315,532,737,523,815,200,46,221,532,709,392,609,958,90,173,473,73,149,965,419,140,10,391,844,222,181,334,635,76,338,128,151,603,902,913,163,93,817,845,532,216,408,979,471,417,740,366,480,149,969,587,983,38,892,966,591,585,133,655,742,650,432,513,187,605,220,616,718,570,382,224,887,0,245,334,398,718,57,632,534,465,827,989,513,226,895,73,893,204,347,983,826,904,208,302,533,745,66,746,527,775,389,528,165,771,138,303,675,645,250,78,221,562,589,736,308,638,481,326,481,880,198,630,994,112,894,678,224,487,911,104,18,159,890,945,498,76,76,432,317,151,962,87,964,171,232,860,800,687,972,844,721,31,581,471,42,103,836,728,755,537,921,975,1,52,30,338,672,437,995,724,848,734,387,209,460,214,640,339,985,673,378,311,316,929,981,2,438,978,851,732,285,609,365,287,889,807,132,114,178,623,246,447,572,867,78,26,866,946,383,751,998,419,752,911,244,668,105,659,371,690,186,453,782,406,552,160,174,551,205,710,192,61,974,565,579,551,166,550,957,904,3,424,237,135,93,823,425,535,409,789,443,887,306,424,402,376,348,866,827,774,930,84,854,506,90,435,148,309,695,663,571,266,867,81,388,801,131,32,577,442,960,606,521,723,958,416,706,361,768,100,591,206,113,319,578,811,507,663,818,16,714,393,571,645,764,498,392,919,535,697,672,163,242,946,657,526,871,838,184,636,898,218,81,446,956,897,443,160,711,280,197,526,834,166,748,903,628,94,361,260,34,342,113,172,238,422,87,755,300,328,843,566,947,407,928,551,827,849,596,430,590,439,718,449,771,482,724,677,391,453,2,835,857,319,995,193,554,829,95,165,296,968,102,192,521,421,666,229,228,290,654,768,604,148,982,723,140,108,297,541,465,45,382,147,992,327,155,637,485,743,64,814,895,925,150,840,165,836,206,404,31,743,289,768,667,946,473,317,687,247,49,588,366,882,347,185,155,886,366,930,417,631,424,185,240,886,449,704,957,218,844,204,63,765,398,548,892,111,161,935,629,740,806,125,136,513,878,758,409,17,622,829,348,792,247,584,281,235,595,117,615,107,553,315,193,920,363,232,815,463,493,954,485,775,102,575,884,158,938,666,820,308,697,380,193,842,384,286,37,753,449,443,718,312,948,377,172,155,139,810,87,439,527,760,562,739,22,303,444,635,622,560,885,120,648,547,342,413,164,678,877,644,598,658,668,29,673,418,820,952,400,434,272,430,98,649,607,875,218,69,855,352,212,669,411,339,170,237,690,454,320,939,281,954,854,456,200,506,139,696,964,841,294,324,328,392,939,474,521,394,448,32,883,783,943,103,863,186,788,94,392,172,265,556,98,73,901,860,607,745,23,284,573,13,36,551,252,707,881,947,7,591,988,98,280,235,757,886,975,825,137,273,311,900,245,519,704,443,162,377,157,336,484,831,558,429,38,572,217,99,52,848,893,112,190,57,597,718,97,26,216,428,147,900,468,108,283,727,250,854,138,949,301,309,833,863,251,58,522,616,673,53,891,14,245,814,839,63,338,335,910,890,862,112,357,622,106,565,225,291,888,593,905,290,739,848,455,635,140,971,235,7,382,87,504,815,643,141,986,428,198,979,351,607,307,687,798,463,988,273,236,383,365,356,18,778,252,886,493,470,914,65,498,928,177,67,875,625,767,222,122,739,505,650,86,706,527,715,52,531,36,449,9,350,822,923,834,609,490,358,924,514,231,446,594,998,388,550,495,844,347,2,667,631,379,901,974,747,721,873,809,427,693,639,379,196,160,430,378,770,624,285,576,850,270,113,497,91,881,394,542,456,544,28,719,84,669,600,300,50,263,10,567,966,855,640,692,95,867,791,206,339,575,408,235,580,808,13,277,1,314,612,178,658,873,659,588,554,492,467,292,763,719,567,115,955,853,99,21,927,259,642,749,781,996,91,548,276,662,668,375,625,298,500,886,608,964,97,772,462,478,39,557,47,533,584,780,330,704,264,24,492,516,884,450,787,437,979,531,957,894,794,887,616,498,52,309,865,275,25,905,812,911,740,917,180,106,275,222,110,399,538,276,675,321,741,516,697,88,970,395,19,582,421,699,384,989,448,55,889,517,616,607,595,466,600,363,439,985,231,444,820,415,821,929,139,158,824,873,407,613,741,630,60,494,246,543,941,914,860,451", "342,758,418,26,153,114,782,809,551,364,435,26,254,262,751,429,617,442,34,180,973,331,585,452,517,739,486,259,589,816,548,545,969,813,8,683,525,793,996,74,414,971,35,318,115,465,673,242,26,575,724,952,138,689,931,320,220,577,758,192,740,333,312,365,86,33,682,383,379,419,680,55,755,211,136,953,379,191,324,741,515,602,259,524,487,422,887,425,808,986,151,17,814,763,31,50,583,712,422,566,245,0,628,271,783,867,605,919,650,657,864,802,711,26,893,945,559,916,630,417,38,274,383,66,553,423,42,539,797,358,469,925,916,277,836,211,18,594,763,712,610,146,809,388,316,668,204,839,915,125,365,38,128,978,923,192,812,787,564,543,994,745,706,643,946,682,417,757,437,659,301,8,996,602,776,655,536,414,329,18,69,215,876,64,284,75,325,177,848,563,657,642,476,742,187,454,324,547,687,589,990,996,501,490,591,676,294,143,53,162,838,967,837,33,855,650,83,648,760,457,944,564,539,175,116,243,419,756,706,17,859,706,473,764,112,580,456,131,150,616,884,613,998,580,111,589,348,866,768,476,792,166,352,949,886,49,947,991,404,49,460,494,973,982,79,332,612,523,812,215,324,937,393,466,293,958,235,842,207,572,28,227,784,2,640,13,468,66,942,786,885,933,682,506,868,126,371,739,578,439,947,828,887,802,80,733,754,20,590,790,177,484,64,643,923,401,741,220,806,558,23,589,358,227,788,150,292,887,572,665,964,577,255,311,603,413,953,644,509,355,548,203,136,289,457,680,545,652,581,346,428,210,846,878,940,457,76,866,820,84,731,696,259,871,602,155,498,981,578,524,195,676,15,912,295,970,826,409,936,152,975,285,808,477,466,93,157,634,619,44,87,421,15,916,746,383,604,414,301,333,394,354,346,311,404,268,564,638,751,141,226,672,688,790,298,426,720,861,594,698,134,250,550,157,735,850,309,807,805,75,916,999,804,907,184,602,340,331,388,40,29,587,325,121,501,431,117,927,426,777,494,746,913,596,190,749,267,658,547,483,696,912,477,821,982,280,578,857,321,239,503,885,651,336,453,847,877,49,816,333,653,111,887,985,874,368,51,344,448,978,490,970,296,260,568,733,88,719,428,614,1000,746,873,878,285,270,408,51,221,111,27,11,657,171,906,940,104,882,302,743,622,255,556,215,108,750,963,358,117,909,515,669,210,796,167,390,792,394,316,568,785,803,6,307,248,474,272,942,322,134,914,204,159,752,903,16,177,842,991,249,436,888,614,175,126,675,430,970,265,895,152,519,802,373,703,484,585,465,171,674,350,798,892,846,241,663,963,241,549,279,715,886,474,670,471,680,795,309,996,518,643,498,73,287,709,935,308,780,663,727,426,248,294,100,193,316,735,354,573,465,334,902,44,836,238,255,576,306,430,306,499,565,531,545,134,417,71,474,23,264,191,345,439,212,762,47,753,530,619,94,767,367,82,332,453,339,148,686,544,969,647,499,907,382,642,756,16,63,957,371,685,988,202,990,961,815,798,407,489,646,601,154,667,757,499,697,70,208,731,749,297,981,999,597,642,409,203,995,270,988,840,210,953,199,620,710,430,755,554,530,478,980,970,871,747,522,494,302,190,49,126,12,9,351,670,755,205,309,428,248,712,168,789,713,11,928,506,878,108,288,786,241,504,897,453,304,944,15,829,513,979,845,478,102,196,966,634,725,433,400,651,175,225,696,795,437,40,30,246,811,602,214,831,482,35,605,889,701,535,283,683,668,388,252,796,651,712,744,733,829,15,777,725,206,217,646,873,678,372,289,64,573,763,667,296,616,334,141,431,484,166,292,417,964,460,353,262,59,668,500,258,976,30,209,189,62,743,912,551,966,543,398,133,866,710,444,691,767,358,3,923,790,242,987,571,839,801,11,684,229,291,878,577,396,774,976,66,29,368,323,571,208,484,514,579,70,102,336,515,15,938,699,944,464,305,999,314,327,114,676,373,429,158,159,554,691,680,731,422,214,245,874,346,223,770,636,955,419,300,362,695,312,943,168,487,576,796,730,967,440,528,356,840,233,285,282,532,586,627,385,838,5,998,71,276,656,403,248,91,257,503,695,495,765,777,537,197,487,829,608,104,494,391,947,343,74,251,568,24,285,693,498,77,415,681,189,494,13,850,5,548,292,302,359,792,613,229,110,327,350,651,374,393,520,251,775,86,56,635,273,188,257,952,308,265,876,33,793,625,639,40,321,629,703,280,934,70,448,360,254", "578,992,483,517,584,983,840,105,185,957,56,326,44,776,708,297,394,239,631,299,124,414,961,956,84,187,533,522,757,238,957,32,537,694,926,254,582,475,894,208,627,393,596,27,525,147,34,148,562,299,911,158,98,100,775,913,603,801,878,917,311,837,195,546,155,532,987,606,314,979,364,162,571,968,133,299,323,795,852,979,587,229,992,910,127,436,828,387,663,946,798,448,358,356,760,584,560,174,111,273,334,628,0,656,370,912,110,602,245,666,524,459,77,584,709,706,490,438,358,742,16,448,74,761,258,206,455,809,448,598,238,507,77,449,669,782,821,656,921,4,755,428,39,522,764,223,78,822,880,237,124,668,38,97,296,968,227,650,204,664,387,897,858,141,979,528,205,685,112,117,119,669,321,97,803,322,38,852,70,416,308,79,750,280,293,782,74,622,147,425,495,133,488,894,325,209,785,185,803,331,781,535,336,19,4,449,567,711,913,370,210,913,32,811,756,141,83,346,158,342,294,914,565,822,877,226,230,511,876,716,641,444,375,603,418,419,333,368,520,930,898,127,586,345,178,27,912,561,297,686,572,31,23,872,887,906,56,463,813,145,978,815,41,268,966,660,821,362,305,659,780,887,922,346,799,929,136,919,759,902,211,947,651,190,797,416,58,111,315,490,138,531,849,788,705,409,677,894,315,815,919,68,485,6,981,22,394,963,835,896,738,36,247,387,784,684,819,541,9,779,255,287,903,913,19,23,39,537,676,160,801,774,362,780,856,29,513,759,11,661,890,696,23,630,688,438,419,347,143,429,445,19,915,28,83,417,657,636,518,829,226,592,397,588,240,442,941,76,508,316,739,501,743,697,451,13,146,837,430,724,796,243,134,776,387,74,419,180,204,526,941,522,931,351,100,404,597,126,738,708,549,880,421,402,515,30,261,279,407,876,740,626,333,805,771,776,184,409,638,463,729,167,469,154,245,622,228,561,519,766,972,71,392,867,713,925,83,44,922,993,365,735,91,446,408,2,711,860,923,38,803,215,126,387,369,516,696,26,728,868,728,550,173,589,816,938,448,832,767,606,641,415,679,449,9,204,579,600,886,56,126,816,416,549,187,526,743,564,370,99,439,724,954,746,593,170,400,441,915,354,603,624,885,63,459,445,57,96,615,580,743,487,970,528,690,729,158,844,772,415,314,391,987,477,240,812,882,611,450,659,936,290,512,32,794,100,547,268,309,744,693,606,226,694,60,699,117,229,648,538,260,519,622,316,265,431,752,486,115,650,889,929,7,136,606,137,37,163,612,524,309,756,457,805,108,877,478,379,920,187,320,909,812,210,794,849,814,911,869,949,645,766,538,880,694,741,272,530,414,798,288,965,987,124,912,555,237,310,880,228,711,544,740,245,498,668,70,985,872,100,749,681,780,653,670,734,303,354,993,937,135,853,12,23,161,326,754,790,554,465,775,832,692,899,733,80,459,70,438,962,26,106,291,75,202,315,379,397,703,375,806,124,586,365,312,256,853,378,300,982,599,507,205,441,851,270,263,313,749,70,837,297,539,208,363,714,115,974,224,864,848,863,980,941,668,514,524,836,134,656,785,584,867,691,468,353,924,697,877,990,821,465,595,907,955,131,984,26,382,418,352,550,146,296,953,354,947,894,994,626,595,41,164,240,297,612,488,804,326,119,461,457,789,500,302,321,727,528,436,725,906,130,485,556,629,680,630,143,578,782,148,800,430,328,989,514,596,90,371,635,10,502,795,508,90,385,520,569,802,832,887,516,124,645,151,383,528,887,854,289,866,302,322,557,73,619,313,315,17,197,522,343,760,261,303,292,64,621,461,792,872,786,67,6,302,491,951,77,321,94,384,361,141,214,99,773,104,887,801,699,115,636,304,171,759,451,568,255,214,743,429,816,719,421,680,693,64,376,901,804,328,225,910,213,133,989,242,76,648,153,233,86,122,789,844,46,447,40,360,185,881,437,773,454,304,549,862,756,359,242,359,112,615,495,361,39,810,139,25,616,643,459,546,813,151,394,119,210,4,285,920,643,372,703,359,321,852,124,427,200,38,91,470,798,377,508,691,456,599,388,478,392,219,250,694,846,407,43,67,587,860,156,155,173,710,783,191,789,428,598,683,130,836,872,444,737,931,956,573,510,756,452,683,866,673,621,473,911,404,141,238,979,379,434,240,902,732,855,278,326,479,188,613,994,519,807,636,680,414,211,914,45,255,335,361,669,572,287,403,528,449,87,625,81,78,230,24,983,715,461", "76,261,566,74,855,410,517,879,918,216,906,613,520,668,574,175,710,828,609,982,446,32,592,528,236,50,802,994,961,297,24,3,934,950,627,436,944,259,603,997,484,687,698,914,35,230,159,83,135,458,519,516,421,703,504,668,451,775,279,7,26,99,637,569,492,37,559,291,6,660,780,499,303,448,393,416,86,525,670,911,435,654,408,156,223,385,551,426,434,397,81,822,905,880,879,397,856,507,754,185,398,271,656,0,247,880,501,218,154,799,619,900,78,579,533,480,248,184,733,219,739,888,61,31,824,327,195,171,986,36,744,724,58,575,292,922,614,899,805,157,15,234,864,356,640,999,413,858,248,423,9,705,743,252,393,433,372,292,480,390,984,286,352,323,385,303,911,124,501,232,360,195,536,464,6,220,501,931,551,667,280,508,696,324,775,892,46,645,576,560,765,756,732,905,397,290,751,816,885,887,312,107,377,903,624,31,480,928,209,470,366,342,723,655,838,594,733,516,763,554,528,671,992,91,290,23,34,826,701,804,912,353,999,905,117,644,524,664,977,451,362,918,583,336,486,159,276,907,721,564,313,810,876,129,757,270,743,46,8,732,876,220,820,796,70,960,204,720,394,904,389,573,645,180,201,609,725,316,836,317,605,615,235,562,482,212,556,494,162,163,614,998,235,393,952,836,427,62,193,436,827,220,486,548,534,205,517,288,598,466,522,894,522,731,510,855,693,405,901,954,625,2,751,911,204,493,606,178,134,645,799,44,848,5,498,575,664,157,554,875,765,144,633,611,251,2,503,431,506,263,210,81,43,214,364,183,51,473,505,478,260,395,926,75,458,67,267,410,167,692,242,94,464,109,596,762,982,683,903,75,810,471,879,291,487,767,252,950,856,730,679,184,810,399,49,76,539,701,31,585,426,461,187,438,100,627,280,361,970,989,875,119,835,733,65,52,980,693,793,415,654,151,390,842,381,739,993,751,624,705,23,154,888,243,800,866,406,410,878,100,896,589,558,376,340,276,627,687,573,903,199,569,398,165,192,550,941,452,974,324,517,663,978,120,939,907,455,493,97,515,801,236,474,5,773,985,57,726,934,490,460,994,568,735,580,607,835,752,338,303,961,658,726,665,564,807,875,23,269,181,275,692,34,240,76,459,158,951,461,495,781,380,585,879,62,507,988,28,996,2,167,346,575,469,688,756,825,150,158,398,996,228,263,94,341,904,252,884,251,885,64,501,937,89,553,591,87,247,821,260,29,308,198,961,232,756,992,636,428,626,358,511,551,876,846,661,654,902,903,396,948,13,143,290,395,141,44,23,740,769,632,381,634,789,917,709,390,477,917,134,471,196,948,475,290,117,216,58,195,483,51,886,642,108,869,308,777,338,865,20,928,513,178,112,910,169,579,434,703,412,27,480,51,157,900,475,711,934,957,417,622,181,515,288,149,300,599,195,251,501,41,728,918,866,159,732,411,759,236,347,199,678,824,138,296,529,691,900,20,934,269,903,622,670,98,720,9,64,725,223,830,350,531,774,122,988,395,369,895,21,505,712,737,154,552,16,190,834,196,842,41,823,262,29,607,371,908,590,899,990,518,118,45,847,85,668,686,692,272,224,912,120,984,341,258,190,94,225,844,330,986,836,548,33,681,595,723,798,975,50,326,750,494,667,70,106,712,652,600,966,5,719,895,983,164,662,894,158,602,202,140,648,989,761,319,343,178,26,659,521,824,182,65,279,53,681,873,471,171,236,369,762,376,436,494,131,611,257,234,27,505,137,592,814,322,579,675,270,656,206,340,47,111,849,226,571,305,474,512,655,142,643,807,959,225,196,633,600,443,729,26,46,938,688,288,212,356,147,396,268,281,271,501,486,828,437,864,457,485,244,304,569,914,404,355,991,183,888,836,531,662,923,759,746,254,676,324,963,643,784,695,359,113,501,77,209,167,371,986,409,871,781,411,2,175,339,130,517,84,963,703,157,180,491,549,409,94,580,812,132,671,395,988,871,626,55,988,495,414,437,841,445,839,575,644,512,548,285,435,749,809,220,744,268,131,32,849,733,655,280,387,33,794,42,998,403,431,707,258,379,502,881,331,708,961,146,82,708,275,700,561,796,538,264,208,64,452,704,845,950,259,7,286,892,837,2,237,304,625,868,560,370,589,650,389,648,825,314,844,601,34,325,501,837,812,973,783,912,635,821,736,138,426,516,241,138,988,111,46,361,386,621,155,633,566,229,484,735,145,515,117,731,963,632,471,778,996,454,124,770", "394,587,132,503,512,313,151,722,485,205,480,405,883,872,481,171,982,341,949,127,955,683,173,23,831,40,608,337,663,570,705,669,528,52,366,348,376,993,942,359,431,743,308,783,488,414,145,378,169,834,703,993,19,894,897,439,277,119,608,480,8,49,18,448,143,221,160,487,458,413,938,440,878,444,253,368,927,180,353,725,154,510,547,244,634,586,279,912,194,83,984,359,154,847,525,145,498,466,310,811,718,783,370,247,0,358,576,342,814,284,213,550,526,175,346,721,353,374,409,547,745,739,311,236,698,452,747,342,375,839,784,641,273,962,571,227,806,289,310,843,518,43,846,195,536,71,787,324,116,796,371,997,633,600,17,144,202,388,28,792,313,324,883,38,389,882,215,398,309,755,575,454,811,739,893,866,504,658,804,839,625,98,62,216,899,343,972,384,791,929,723,87,261,489,20,452,867,368,209,78,966,307,561,325,189,441,37,995,445,582,856,476,82,111,837,890,802,74,740,635,684,951,416,662,993,334,74,840,902,507,462,579,396,107,302,259,646,614,657,444,131,473,253,914,902,710,224,575,198,150,103,802,872,843,73,124,647,83,404,813,948,235,151,455,607,509,693,532,263,348,696,877,339,757,861,276,639,966,55,829,326,381,10,320,638,735,710,300,192,129,774,32,929,46,882,379,916,232,115,681,339,795,833,604,641,291,18,715,40,86,664,180,791,361,933,700,478,631,399,935,339,300,326,394,6,418,316,655,660,757,13,321,450,258,828,748,68,494,473,682,110,344,469,700,375,609,10,669,686,956,849,939,765,202,171,68,856,776,904,717,114,482,473,43,351,411,640,775,993,250,42,655,636,628,691,928,904,895,903,584,255,766,131,671,899,776,84,450,183,951,980,514,240,42,10,958,978,507,905,319,280,20,189,838,63,523,594,44,923,30,277,363,787,751,903,39,946,638,262,83,218,243,624,466,56,308,678,885,593,96,455,52,146,342,700,617,287,300,930,890,490,847,236,352,150,368,558,74,592,132,945,326,41,642,206,19,864,932,987,321,558,315,143,558,724,267,567,70,31,829,710,144,341,198,954,947,471,231,232,956,740,514,772,962,297,226,637,828,877,475,790,871,697,850,912,445,522,994,164,746,389,593,185,660,9,568,268,934,67,207,468,895,36,141,502,796,287,515,986,538,995,127,754,110,561,793,624,304,47,893,725,755,9,254,925,585,113,480,486,550,629,587,516,963,113,900,73,638,303,802,148,945,599,770,681,809,808,139,650,454,984,476,214,353,8,689,515,436,991,386,716,483,783,508,627,621,734,949,651,202,337,299,83,816,881,440,339,839,884,384,85,712,695,249,975,867,889,346,550,652,517,141,850,228,446,407,936,966,4,363,97,39,810,780,763,996,371,281,757,248,813,67,835,216,572,801,288,148,201,910,397,38,926,555,831,69,183,394,17,817,933,654,239,768,748,559,701,622,4,583,753,449,685,480,854,608,47,396,115,569,933,336,646,604,465,1,659,266,788,866,114,278,552,96,251,49,72,250,266,115,819,377,477,985,426,796,643,457,171,481,778,678,220,631,845,48,469,908,388,943,858,770,673,983,27,373,761,281,708,413,457,408,43,57,718,668,906,829,913,773,647,625,196,276,83,119,492,267,867,339,82,943,681,766,174,126,205,480,572,623,942,495,954,249,143,316,933,959,109,59,684,687,760,950,80,25,468,614,156,954,31,434,722,129,465,654,571,489,470,266,197,86,686,233,903,793,146,863,903,633,298,901,465,693,534,948,396,215,789,209,840,337,287,884,319,981,827,711,251,252,866,839,661,994,983,808,578,555,615,538,934,684,129,294,490,545,96,567,40,890,950,897,669,7,430,476,734,749,674,124,722,663,583,873,757,479,50,889,901,112,761,339,497,7,551,825,345,155,326,933,535,693,936,13,653,208,244,540,319,202,670,455,843,646,68,930,661,485,202,741,599,586,293,569,232,311,266,579,363,885,628,118,858,245,512,812,354,496,707,915,164,504,156,507,823,780,768,221,148,646,905,699,147,337,564,186,299,409,959,781,164,722,135,226,123,19,898,420,659,468,4,953,808,699,422,83,109,922,14,847,216,838,571,550,186,576,146,717,876,712,533,767,369,598,524,977,140,313,104,144,77,749,745,479,333,876,468,665,846,345,985,219,613,388,683,61,240,407,940,816,991,494,722,481,989,544,395,451,787,673,939,433,53,546,454,693,733,236,219,684,964,216,17,164,251,934,798,947,93,778", "432,366,985,784,917,752,305,693,259,78,543,70,533,272,253,239,566,228,101,552,614,795,370,778,126,589,827,159,875,455,750,157,28,199,462,60,463,442,959,620,462,951,651,912,511,359,681,378,18,823,768,183,816,812,339,904,358,537,676,743,40,565,156,195,117,738,779,676,323,225,197,221,680,726,757,411,564,886,690,443,407,833,162,18,205,533,622,666,448,839,197,638,120,695,329,27,383,271,509,311,57,867,912,880,358,0,625,924,453,69,537,112,830,548,136,943,863,861,137,928,831,670,682,316,251,846,960,979,189,62,819,128,884,245,504,513,567,650,247,472,928,457,308,738,210,954,374,449,792,616,253,658,538,550,129,998,659,648,9,547,537,931,590,296,732,4,536,922,37,919,791,348,481,449,16,695,73,257,94,72,439,376,506,370,277,43,789,913,658,856,853,700,897,808,513,110,618,258,315,294,563,4,441,854,726,47,802,509,856,965,786,13,195,166,245,646,453,335,646,966,884,335,427,513,45,679,937,859,178,466,270,378,262,784,780,766,460,550,107,480,211,303,712,753,830,776,174,619,192,713,678,976,617,488,200,500,312,296,133,673,215,21,795,533,814,260,776,483,395,16,888,787,619,905,345,685,380,645,304,868,206,211,47,608,995,198,270,545,390,817,113,288,921,586,252,511,737,715,354,388,407,377,701,271,214,379,580,703,676,685,534,632,39,630,715,103,113,281,155,439,222,302,228,199,967,677,328,621,931,204,445,729,148,692,311,978,938,660,232,964,795,855,465,944,410,889,989,216,779,363,463,72,427,211,871,483,62,645,163,733,639,115,2,168,764,656,820,915,608,306,195,205,352,738,275,218,24,257,181,57,964,346,768,36,957,279,406,857,57,517,549,187,991,394,76,444,921,34,402,805,729,832,132,993,401,322,279,376,166,589,431,545,794,248,529,101,619,416,107,679,330,112,586,923,117,821,351,497,383,52,388,547,287,689,785,155,815,365,345,760,525,37,662,629,782,16,43,54,589,707,468,223,16,881,539,203,873,954,437,658,778,606,772,134,998,964,936,703,468,807,491,411,840,269,613,3,341,236,679,992,414,786,720,283,514,754,656,598,134,411,80,768,90,203,175,414,11,289,512,936,887,600,451,380,567,951,840,302,616,999,18,433,150,292,197,22,733,435,755,533,283,592,764,384,227,10,198,669,678,414,672,641,372,806,438,560,949,383,851,821,94,823,986,519,694,919,776,656,604,447,806,488,865,84,754,315,968,154,736,957,372,164,552,629,157,963,181,554,966,496,126,77,416,837,150,110,538,31,491,799,335,373,769,518,152,315,619,428,174,607,447,265,922,368,107,451,821,85,162,33,269,473,309,559,940,658,830,417,724,178,448,942,326,88,737,611,224,108,284,758,242,468,991,427,191,378,668,955,100,153,347,476,80,93,258,190,423,17,445,374,275,636,297,972,806,459,51,438,721,68,819,548,359,847,933,299,914,421,452,616,694,665,773,255,946,152,571,419,790,563,233,317,776,321,122,131,705,164,337,801,358,837,232,851,818,683,65,510,368,623,793,752,340,78,128,520,972,889,316,383,191,244,367,825,171,306,698,194,211,991,840,326,655,259,282,17,754,971,834,637,118,464,458,698,690,223,594,860,445,45,361,681,477,132,375,357,292,410,819,463,202,729,476,845,884,765,211,941,245,980,738,742,974,14,514,526,490,854,682,829,513,815,596,594,109,344,874,913,175,185,565,576,917,233,468,911,664,98,152,725,713,765,437,729,903,388,808,692,774,742,761,971,753,403,200,585,749,602,27,206,957,142,305,946,960,902,806,577,263,68,649,312,991,752,856,532,39,321,848,599,663,143,75,7,20,269,109,692,435,595,799,180,353,891,67,992,945,878,820,667,422,102,668,218,516,894,574,884,615,751,378,832,375,374,244,760,699,854,956,160,679,130,595,244,982,661,145,840,592,59,710,216,19,539,364,480,93,748,121,471,844,404,975,656,434,500,993,32,769,611,401,331,164,869,433,993,700,285,17,523,619,666,516,569,54,996,685,383,142,993,638,365,100,684,162,729,582,716,454,860,432,372,957,124,179,100,94,310,499,572,131,837,514,421,472,29,83,255,230,255,475,260,755,308,572,345,720,386,838,795,386,279,55,65,638,73,769,677,692,165,276,614,801,613,992,723,827,908,504,143,637,952,96,732,685,866,386,810,570,295,588,622,129,568,14,89,684,321,668,732,723,72,87,941,215,638,835,191,846,253", "786,154,566,953,630,402,449,840,73,98,342,267,793,736,616,897,351,829,804,921,524,420,116,609,565,140,71,302,573,180,685,824,721,140,601,833,88,605,141,706,407,744,823,51,122,135,634,656,185,101,78,812,28,741,744,625,292,537,90,833,154,893,11,574,864,37,729,276,227,390,182,702,687,251,357,175,878,735,46,822,435,609,521,389,293,188,111,274,614,598,578,867,907,518,272,249,91,779,908,502,632,605,110,501,576,625,0,568,574,410,589,852,919,700,547,889,519,697,308,863,901,346,17,599,718,962,884,850,403,279,379,730,69,411,554,693,443,780,623,197,511,410,483,10,197,535,883,553,125,445,826,672,609,887,898,661,405,689,391,381,392,479,619,623,523,334,132,137,330,283,581,615,196,921,304,46,451,515,503,174,260,690,410,462,181,487,252,532,653,240,601,624,215,785,433,32,146,190,392,244,549,459,275,598,291,90,717,323,892,670,916,20,148,556,535,484,956,862,14,93,520,777,990,477,335,292,896,765,122,569,423,398,357,266,751,568,893,487,232,483,357,708,497,417,145,205,17,877,743,61,747,643,72,746,340,782,935,932,792,898,907,183,21,225,163,817,476,125,891,280,369,27,136,692,451,256,93,237,284,760,627,171,597,386,512,737,612,508,257,718,504,896,83,443,895,150,347,181,157,917,998,983,617,983,755,571,340,758,982,110,414,672,306,219,881,150,287,927,667,241,256,576,994,417,478,843,880,905,728,464,37,225,13,591,856,671,473,260,553,640,70,969,889,787,480,318,362,697,680,619,673,550,266,115,781,366,105,116,696,992,509,465,441,763,375,882,477,72,298,636,902,15,350,180,164,514,335,150,353,906,233,442,493,573,857,6,536,958,902,808,578,641,460,939,416,759,685,389,718,458,218,751,527,628,935,292,927,430,5,793,517,698,471,327,618,274,131,675,988,336,850,84,668,853,721,951,487,182,204,277,931,12,529,350,801,275,566,42,297,582,122,200,483,395,779,49,760,728,705,572,165,377,409,481,8,57,491,864,72,78,199,394,981,925,772,887,789,319,648,372,371,345,468,373,347,576,731,484,945,575,767,406,212,706,560,724,907,35,975,278,425,35,175,26,762,53,977,761,453,434,663,539,688,785,784,482,569,679,16,419,953,501,725,7,220,132,589,4,358,319,320,651,698,88,335,227,622,350,936,234,663,303,970,604,163,339,488,245,259,882,556,264,725,407,725,314,850,804,801,518,826,788,777,746,288,952,736,804,291,550,8,214,814,509,226,235,522,215,304,793,709,794,924,92,584,956,816,180,383,600,133,388,77,398,852,619,598,799,222,96,603,16,889,563,665,299,69,513,47,898,965,310,918,681,670,212,590,409,33,694,518,786,722,823,737,849,568,680,615,920,918,929,962,986,67,13,665,433,629,635,630,398,665,402,436,820,138,955,129,941,911,813,908,164,716,240,98,522,947,751,689,388,893,318,513,791,973,683,121,281,321,202,833,505,143,595,407,6,744,536,901,414,666,441,342,289,709,283,760,522,789,759,853,932,871,950,533,622,789,63,276,59,821,815,399,770,247,2,764,242,291,115,329,113,356,806,409,543,399,670,404,855,444,49,779,400,257,317,375,179,405,904,802,485,598,703,918,679,269,900,692,404,137,693,816,110,486,229,249,881,666,296,21,123,977,46,802,865,715,555,129,358,869,976,450,211,702,323,853,16,840,692,198,705,173,912,804,971,74,125,224,410,868,977,246,755,385,144,836,22,14,433,788,100,78,758,521,274,334,295,816,520,693,705,546,81,298,395,54,773,259,656,877,911,417,404,540,71,927,986,506,789,832,795,923,455,781,360,788,270,816,718,169,159,727,371,688,973,49,727,760,623,682,824,69,482,128,869,630,7,279,18,84,696,124,958,757,461,821,392,822,159,682,99,709,539,143,315,533,233,190,990,148,568,583,996,938,147,661,382,147,582,816,805,423,341,850,296,476,841,985,437,479,30,157,771,984,476,335,974,324,309,393,126,751,845,985,586,603,508,237,379,253,948,675,63,389,734,299,832,389,248,914,423,727,596,528,970,247,659,460,56,803,531,359,54,143,29,119,125,171,758,516,630,977,188,45,661,4,800,258,656,858,154,517,587,397,128,440,818,224,678,393,249,394,200,541,532,714,45,992,440,191,958,111,254,29,827,871,312,390,165,326,69,629,418,495,758,757,817,352,309,322,773,104,274,787,782,593,797,420,722,64,407,46,70,913,611,211,469", "313,544,605,482,916,350,120,129,953,510,408,388,287,764,700,489,51,684,103,74,435,210,513,878,864,390,385,746,665,596,267,271,574,882,621,140,253,516,716,473,368,70,119,620,228,152,789,215,569,191,257,275,657,741,323,105,857,940,920,550,952,817,913,259,902,77,819,622,961,777,970,518,692,21,65,399,480,650,848,520,472,549,954,925,725,959,852,793,770,202,445,266,631,473,499,965,218,54,865,841,534,919,602,218,342,924,568,0,598,15,965,81,22,997,580,389,417,558,67,124,461,641,290,651,990,579,564,710,252,37,835,334,186,994,877,255,866,805,763,656,16,989,266,713,402,394,870,357,174,453,657,843,427,909,87,772,981,674,236,204,998,584,856,332,798,808,327,769,987,433,936,61,309,996,474,901,811,524,257,677,404,969,427,451,765,76,312,702,994,658,8,732,768,957,239,927,209,328,742,844,912,840,125,671,38,406,328,606,402,830,518,635,792,433,497,124,17,652,315,474,699,294,966,4,837,437,82,551,724,569,553,820,359,947,403,715,317,31,878,280,621,117,820,556,365,692,9,915,204,347,241,616,732,781,619,684,953,738,815,113,193,544,396,135,774,35,707,611,596,27,815,271,76,645,980,965,989,961,937,326,781,846,507,271,719,360,70,264,696,13,21,223,738,976,569,786,873,228,953,847,363,469,503,782,646,763,493,313,533,746,740,338,321,57,470,583,225,58,605,708,500,48,156,100,911,617,953,494,483,913,738,525,964,229,699,48,504,420,735,314,180,120,608,878,43,199,320,691,419,659,762,190,17,6,772,849,903,577,597,146,411,674,656,18,501,670,40,678,705,514,997,514,33,152,822,672,173,450,475,986,826,519,349,342,75,207,136,802,813,826,972,463,644,986,703,602,81,816,594,51,573,245,837,798,926,851,446,7,615,546,509,469,620,441,554,540,573,770,527,231,318,873,518,405,518,38,329,540,68,415,48,197,500,554,578,460,200,246,267,434,651,925,267,591,588,165,68,933,431,233,655,431,708,376,871,517,116,627,305,210,511,915,128,82,248,350,261,141,702,184,611,701,876,190,320,429,3,120,795,946,756,520,540,894,469,19,806,675,978,816,517,412,368,259,270,125,696,745,50,913,442,408,565,61,23,397,207,971,596,301,40,791,206,22,813,786,246,926,686,318,42,900,875,748,23,864,1,330,6,207,144,437,537,293,114,607,547,808,845,135,577,819,86,158,329,691,451,441,79,270,884,963,800,861,847,577,648,692,403,421,66,192,934,428,468,274,447,828,912,253,628,547,529,239,627,14,708,931,14,707,592,998,202,893,342,84,183,414,339,484,225,982,812,565,848,49,893,60,473,181,56,996,792,395,470,22,533,584,562,844,644,109,246,354,863,459,39,866,383,117,73,462,36,806,881,968,571,876,720,216,895,187,205,166,959,69,370,350,241,28,692,303,166,885,875,497,406,885,729,681,538,223,737,77,1,597,453,927,303,135,238,598,850,524,285,480,602,84,404,127,843,969,722,893,679,337,629,379,671,634,621,666,363,875,721,548,70,997,722,220,970,778,898,541,185,326,661,690,62,730,944,346,143,861,843,505,867,179,351,718,671,761,501,748,698,516,488,760,57,977,622,589,564,949,756,341,55,873,306,839,774,321,117,745,300,603,212,628,125,661,357,123,441,770,385,423,498,202,91,342,309,973,981,219,824,499,410,313,106,539,257,468,422,105,26,650,753,578,349,953,436,324,986,362,730,1000,793,656,334,770,394,767,449,291,163,100,66,423,402,839,171,254,672,674,30,876,973,724,410,972,236,760,983,712,385,251,104,946,386,538,65,471,621,947,232,210,718,586,489,654,881,124,635,159,50,221,547,848,342,235,689,292,221,707,197,609,463,744,287,852,710,905,194,123,999,501,924,779,35,81,175,815,318,742,45,388,905,710,217,659,115,211,49,786,845,444,955,23,820,386,83,746,473,12,153,799,702,562,687,794,856,96,505,216,935,642,598,125,191,689,94,876,781,55,74,241,152,971,948,453,107,70,456,464,497,701,817,440,582,171,321,809,899,747,414,174,433,975,154,947,488,695,810,950,850,496,565,364,893,30,353,367,910,738,886,772,524,579,962,732,414,382,430,725,892,563,150,648,263,78,398,856,954,324,672,666,552,271,280,892,242,474,754,465,772,114,595,289,452,302,988,272,89,215,155,836,667,351,268,767,541,217,21,436,835,816,755,485,660,591,843,155,673,105,984,103,329,54,291,419", "693,480,837,526,484,142,631,647,402,295,906,239,467,135,446,48,430,218,980,629,668,161,706,237,898,967,471,35,556,541,550,192,947,539,455,116,161,305,709,770,129,989,288,538,764,210,656,764,721,568,926,606,449,15,703,99,580,698,35,700,387,58,15,557,479,498,155,680,113,563,670,713,678,763,324,470,839,607,904,24,945,789,46,21,464,762,340,580,258,723,393,606,663,803,416,637,213,912,478,5,465,650,245,154,814,453,574,598,0,792,176,44,491,467,855,18,726,457,887,925,242,201,502,352,386,906,612,573,908,36,801,153,136,972,815,181,934,439,757,117,692,317,935,103,719,698,475,444,413,771,597,954,511,467,308,910,461,562,915,22,354,919,72,555,158,922,453,191,417,378,32,217,812,523,151,880,72,881,200,56,44,335,491,488,40,314,406,508,730,500,152,82,992,1000,651,785,802,32,184,813,900,286,295,703,923,793,517,676,510,250,728,932,753,225,603,133,794,237,407,505,61,53,94,604,89,482,989,20,378,715,138,695,283,964,541,331,214,459,397,677,252,86,918,238,505,63,122,27,818,616,458,127,724,281,301,570,366,354,589,797,694,206,127,307,206,26,839,912,426,174,910,818,816,823,717,304,601,996,29,133,739,243,676,10,404,628,124,338,831,803,215,132,945,196,388,738,772,263,255,24,93,555,488,904,846,402,490,13,129,785,386,75,798,285,588,389,679,598,782,360,634,27,307,69,792,960,665,632,426,250,317,828,16,794,306,285,653,623,981,4,971,206,564,422,802,759,705,394,242,393,30,614,309,701,999,862,71,454,429,153,832,985,787,873,910,398,635,948,231,616,788,215,600,871,356,449,199,770,707,586,842,429,437,883,719,51,660,915,795,436,47,24,525,222,573,619,408,153,224,650,570,152,368,328,259,932,364,381,572,522,906,274,78,911,966,578,926,978,762,47,654,146,114,533,697,258,453,773,660,616,74,295,963,572,660,47,528,300,649,706,459,617,288,324,118,40,692,72,678,623,365,751,177,880,232,318,986,26,858,976,489,121,531,857,168,301,30,681,858,513,290,785,814,547,835,419,16,827,954,34,163,717,984,680,787,229,807,239,201,515,260,40,531,466,956,369,52,702,307,72,853,123,373,652,589,525,876,433,633,39,639,690,814,597,19,348,262,413,860,497,690,803,672,677,343,970,658,417,777,181,998,287,9,638,326,623,225,824,17,340,822,544,225,908,745,80,739,258,381,711,206,11,460,748,813,821,798,37,83,357,958,599,692,311,194,528,834,497,137,518,117,133,57,203,406,481,663,96,305,957,162,142,957,973,780,913,996,203,391,815,892,175,322,673,168,125,203,105,72,540,372,105,286,276,169,787,584,887,914,8,903,266,92,881,367,969,600,737,139,377,494,781,995,518,499,475,195,473,140,487,596,985,115,371,665,259,995,668,869,647,632,460,3,902,938,645,157,963,714,239,488,518,457,218,106,556,357,760,667,290,71,809,720,366,365,671,195,684,764,510,356,79,246,801,569,815,490,601,136,345,683,612,530,536,557,35,621,609,877,702,675,657,331,161,288,84,546,733,84,979,174,94,410,503,36,645,673,280,771,246,835,230,839,822,128,668,29,476,623,862,20,536,708,64,376,984,18,733,987,766,170,823,345,583,600,587,33,182,918,323,569,773,996,468,745,11,600,308,607,337,531,100,12,962,829,138,735,915,970,967,177,156,818,977,531,850,778,587,515,460,924,791,457,997,54,137,356,997,948,102,341,275,793,604,230,997,716,601,322,952,996,601,376,752,997,903,678,564,854,975,912,589,80,879,559,408,732,804,225,431,788,835,225,831,795,846,105,106,827,670,81,872,434,126,333,90,708,25,748,353,569,234,135,572,386,2,842,752,873,780,579,607,297,925,145,146,399,585,716,697,657,530,373,803,499,726,436,705,582,675,677,142,480,741,959,373,248,581,493,115,905,893,535,183,257,344,219,466,753,275,775,856,355,988,362,989,624,600,610,714,82,574,897,600,369,303,312,798,101,473,111,607,827,395,665,821,436,679,101,461,482,341,437,789,241,314,143,880,432,483,691,36,833,450,848,928,415,949,775,106,60,927,350,881,519,21,202,429,38,467,956,698,196,337,720,751,977,638,642,306,951,455,296,606,982,594,982,743,664,487,620,265,294,261,245,526,38,960,476,121,38,371,133,136,24,466,713,613,847,418,23,376,304,192,475,751,228,434,769,14,641,367,440,545,185,444,61,193,989,250", "587,983,448,469,362,295,278,159,701,359,639,405,423,252,405,262,142,38,490,258,159,62,498,651,985,787,370,642,212,629,933,210,459,825,269,243,507,513,821,871,251,380,453,16,343,493,554,816,704,444,504,919,717,551,988,31,134,918,667,76,712,819,907,91,842,519,609,360,624,281,965,407,610,460,708,348,14,241,487,803,592,481,199,641,241,684,964,830,273,824,945,175,201,202,569,668,238,942,422,179,827,657,666,799,284,69,410,15,792,0,565,760,261,134,90,559,562,183,927,753,166,827,862,772,128,882,161,345,527,975,659,568,952,706,307,204,389,46,525,202,927,780,919,468,678,265,651,653,514,236,332,602,74,349,623,746,818,564,184,966,521,608,449,725,262,777,569,788,548,718,462,940,930,834,211,535,600,102,396,728,203,532,242,225,695,28,737,556,849,620,868,294,375,558,292,335,421,520,693,49,188,972,683,510,132,975,184,95,96,513,580,234,482,395,825,545,620,989,884,325,5,251,838,800,622,895,74,335,456,952,94,797,94,900,254,523,390,963,320,277,902,301,511,269,375,417,659,391,7,508,228,712,146,359,846,274,271,602,170,596,898,268,11,851,719,677,560,217,266,297,52,167,171,450,239,90,951,92,549,273,819,534,821,648,410,662,971,687,425,384,68,531,350,95,403,671,408,810,120,254,783,767,999,202,982,867,937,589,941,592,143,896,37,520,683,474,697,131,904,321,156,352,625,706,490,502,930,776,524,846,311,45,231,603,994,157,551,264,759,119,610,224,504,149,966,640,310,426,40,713,873,185,636,349,76,234,903,476,898,164,881,705,503,402,187,911,408,923,334,477,11,548,667,318,330,120,798,786,710,948,976,664,26,617,140,590,770,266,320,90,15,53,399,348,113,691,391,677,558,325,695,680,391,398,358,95,636,815,366,659,508,110,98,800,832,858,223,697,762,573,685,629,321,747,112,572,167,613,865,731,970,103,384,714,743,746,132,971,979,980,996,541,111,52,997,377,887,30,279,982,454,96,857,384,669,702,417,527,929,425,891,941,642,472,981,743,38,241,177,554,613,370,674,322,480,721,89,932,949,738,947,997,843,821,4,380,939,966,335,64,477,307,206,362,284,938,813,108,561,922,784,415,339,146,156,755,810,338,403,622,667,476,76,201,991,774,886,267,675,500,71,616,292,347,790,647,307,336,426,329,697,211,166,912,59,530,910,332,888,582,21,749,344,94,325,813,689,398,942,655,100,27,984,182,354,737,798,362,254,148,946,7,190,965,80,816,13,802,87,49,928,638,92,843,708,257,655,761,526,970,16,664,740,861,96,816,493,330,924,583,445,315,201,66,895,435,735,533,852,256,861,555,299,437,69,893,970,309,237,903,252,863,1,444,172,209,315,559,368,507,860,783,681,852,460,244,137,469,782,115,413,529,294,62,425,32,126,592,974,519,650,686,648,61,424,243,554,595,30,956,178,328,504,806,331,742,809,973,767,164,680,690,808,254,18,535,228,603,846,568,678,245,200,68,496,866,665,100,382,400,305,328,276,984,648,160,110,208,148,189,635,978,166,513,799,104,432,799,444,642,693,923,59,82,472,735,451,166,246,628,26,52,494,606,841,900,491,642,878,805,886,366,797,773,725,987,735,145,708,47,179,891,745,664,829,562,459,859,991,536,136,521,242,50,305,706,732,317,989,587,193,595,494,626,147,129,607,939,211,776,347,471,801,538,188,784,873,728,293,924,799,4,500,689,653,128,898,379,334,446,859,289,814,404,888,536,534,894,757,371,60,637,157,530,308,748,588,448,61,581,285,507,812,772,8,863,594,760,509,723,150,986,974,952,192,869,81,630,94,901,344,894,523,707,731,174,141,363,290,844,703,230,665,690,258,97,486,636,961,610,232,374,341,592,685,204,635,129,885,856,577,499,858,164,146,519,339,546,146,785,757,95,31,715,734,733,45,405,556,679,231,867,152,194,566,41,829,698,606,287,715,988,333,273,701,275,765,695,825,590,874,368,688,724,864,455,160,146,478,505,605,151,530,380,696,195,874,409,570,321,6,966,966,149,312,615,206,617,589,462,75,570,922,53,951,231,93,727,161,509,357,801,264,587,848,803,238,398,683,568,333,181,23,780,189,721,212,12,893,623,501,383,309,327,480,504,194,3,964,255,528,287,290,447,857,37,417,352,804,291,118,214,656,983,110,315,983,250,23,439,457,104,554,974,127,381,13,440,138,211,228,517,710,502,925,879,271,378,560,439", "659,148,985,13,926,285,314,759,729,166,211,991,118,749,557,455,705,943,400,512,125,833,523,935,975,800,912,305,323,180,173,283,657,457,878,943,87,77,324,918,454,456,856,579,509,857,669,245,898,920,237,118,880,426,920,570,886,231,980,330,211,769,844,44,215,129,967,192,392,770,184,62,611,293,711,425,160,510,233,100,934,378,415,157,225,174,322,847,209,448,658,88,729,120,94,699,396,366,924,459,989,864,524,619,213,537,589,965,176,565,0,161,186,563,798,336,970,379,551,52,182,973,956,741,474,423,392,501,610,286,866,775,636,440,51,517,529,710,81,174,202,973,683,378,102,866,591,719,252,973,199,687,688,180,830,364,755,255,452,26,452,389,982,746,894,962,379,931,373,570,160,245,297,117,937,274,522,346,517,334,103,433,695,20,985,737,475,269,354,199,989,622,213,583,332,242,934,957,253,430,391,211,210,811,432,532,284,562,686,145,677,17,910,917,258,275,284,279,40,727,865,271,349,908,77,21,203,324,599,899,860,775,408,858,919,688,578,232,491,61,695,413,637,554,443,956,89,927,865,397,481,12,121,129,698,273,889,436,91,206,191,377,460,1000,703,483,757,605,565,9,570,367,659,787,139,582,466,604,863,987,309,999,643,622,249,4,206,269,749,620,78,958,285,434,792,142,412,692,432,211,955,817,758,898,344,310,864,137,880,19,84,501,664,735,449,523,809,178,159,948,358,375,493,118,857,99,122,63,652,375,899,693,450,201,882,532,101,461,802,21,82,204,303,855,64,976,122,336,731,244,800,433,387,658,717,8,227,110,182,343,172,36,512,101,553,163,205,752,147,560,873,166,768,506,222,215,575,990,694,546,696,890,91,409,287,413,190,925,59,337,416,926,821,153,323,904,878,193,614,88,583,859,489,5,886,775,471,226,363,609,558,919,881,860,157,366,300,154,662,626,505,693,632,672,316,513,278,840,572,774,782,856,528,621,800,282,31,404,513,292,610,427,767,37,111,18,725,75,975,20,630,211,43,81,931,537,971,907,30,324,995,930,256,123,803,13,817,993,496,635,373,939,83,845,248,574,362,629,549,954,289,610,749,847,514,433,254,774,402,648,642,36,531,461,161,451,982,205,120,774,126,815,785,329,650,989,824,321,928,983,623,756,721,122,470,671,715,151,437,94,230,401,722,914,671,433,30,71,315,909,226,265,996,107,923,549,418,557,206,234,408,753,386,870,222,494,308,850,297,88,80,673,695,318,332,575,901,693,483,688,887,717,446,617,858,289,828,889,337,326,806,485,455,854,493,655,784,284,133,268,951,46,715,848,499,281,899,401,912,134,929,106,241,862,836,491,801,783,990,707,329,249,54,298,754,529,44,538,318,548,412,864,318,256,657,651,349,819,262,322,885,5,75,261,146,411,452,573,470,136,726,91,393,25,355,862,513,377,465,637,766,402,731,874,95,655,465,801,314,838,528,910,809,475,309,660,964,63,337,896,826,631,16,113,32,381,500,726,465,496,132,331,459,894,80,538,77,150,664,402,671,647,421,802,389,220,309,403,997,760,961,575,187,697,903,349,323,957,748,381,137,144,499,850,660,380,773,756,836,647,922,405,159,528,214,726,188,989,871,402,661,827,455,228,291,836,253,826,237,69,878,984,900,622,950,490,996,125,440,105,921,726,852,283,420,13,876,202,435,798,948,976,198,945,750,2,469,549,729,936,963,892,692,642,569,923,516,151,346,697,335,788,203,817,758,259,498,779,326,581,616,17,642,603,23,743,807,662,160,248,399,493,46,487,522,982,645,689,609,445,880,88,818,425,768,452,767,106,693,947,89,399,161,550,426,948,827,434,118,360,402,25,405,511,665,166,655,258,198,20,935,140,93,117,671,378,800,922,376,460,872,585,359,543,414,285,648,557,75,38,218,145,235,431,560,327,59,418,415,200,127,695,711,82,875,886,28,328,898,701,19,247,927,482,793,828,910,203,72,512,952,833,133,302,263,220,870,797,103,126,916,305,577,214,662,257,145,80,302,586,255,252,129,561,52,302,716,578,120,61,346,534,608,903,535,37,679,567,957,21,137,652,96,540,781,213,41,65,370,623,847,370,89,958,136,167,236,698,395,828,549,898,63,328,70,124,827,530,789,386,524,478,409,708,456,664,911,926,172,890,403,547,62,423,687,753,246,279,969,217,593,173,486,901,409,514,235,167,746,138,346,684,458,756,266,141,348,154,151,777,765,195,69,297,46,369,527,32,309,573", "55,855,334,183,942,2,880,668,299,476,571,507,227,734,269,486,697,866,985,679,840,199,688,523,186,551,284,488,736,169,285,324,232,959,474,938,681,733,813,164,698,44,318,327,211,226,349,342,581,335,979,822,445,500,807,868,291,4,345,951,645,1000,825,2,399,809,641,60,583,140,287,649,574,541,356,61,771,53,683,999,763,204,591,652,809,234,579,214,807,88,896,392,514,692,224,624,83,637,147,929,513,802,459,900,550,112,852,81,44,760,161,0,252,200,751,959,901,473,351,332,92,357,574,269,106,82,916,476,556,793,697,565,822,782,267,875,521,860,686,273,268,582,24,878,339,791,330,115,607,169,884,305,69,965,877,945,120,694,490,750,659,211,21,859,925,702,323,321,573,353,547,659,853,485,675,373,242,662,952,979,283,223,473,992,84,196,227,358,575,175,666,368,726,819,733,331,775,180,161,385,960,708,810,120,6,527,268,230,54,823,481,237,804,423,929,729,278,962,408,18,368,907,165,692,764,680,952,273,276,108,697,94,925,184,821,782,257,372,798,846,140,454,311,384,694,357,338,844,206,387,669,891,542,747,255,257,850,56,22,832,874,420,444,199,373,414,654,471,205,462,231,774,142,473,255,800,288,139,166,463,483,291,468,429,534,548,750,601,40,341,662,289,194,754,670,334,109,644,408,450,697,384,445,572,489,690,719,177,417,559,349,708,540,19,15,978,699,928,821,390,867,541,146,519,168,273,287,287,216,196,652,164,77,952,155,732,802,920,323,296,519,27,944,304,633,842,586,320,740,234,742,504,555,780,509,677,386,524,72,866,457,853,363,311,362,397,624,779,639,420,356,703,158,269,369,185,845,454,348,125,2,856,11,615,86,761,126,920,184,835,504,34,15,613,73,73,749,318,91,177,331,204,51,647,703,376,348,898,700,755,358,735,69,125,44,766,790,796,458,123,630,996,133,960,532,886,886,213,809,94,848,651,238,35,148,970,314,984,351,739,921,90,461,615,809,756,786,738,466,314,443,259,498,845,65,468,989,668,611,251,616,9,292,70,740,243,491,507,354,935,75,993,993,719,789,479,239,563,730,681,862,330,897,408,664,893,873,612,902,412,483,257,982,357,408,16,884,692,937,626,575,152,644,348,464,510,967,620,317,403,301,640,23,614,199,759,215,886,850,870,975,670,607,882,153,885,293,830,534,823,971,127,593,631,956,176,365,752,934,870,803,273,856,349,528,81,48,531,492,86,413,563,385,687,546,584,581,796,312,807,590,304,641,874,79,610,274,787,35,701,707,765,385,299,66,480,323,915,482,811,674,493,212,54,278,442,888,613,411,110,643,671,528,164,351,826,107,471,614,758,156,600,765,777,312,926,984,214,469,319,200,127,428,809,503,965,730,152,275,503,348,483,303,591,503,912,384,12,27,427,461,621,251,283,900,953,703,871,915,113,472,918,380,41,578,655,998,423,700,995,778,543,385,658,294,648,95,696,539,762,970,313,3,178,921,347,486,382,383,371,715,339,805,730,984,691,699,230,119,731,144,246,482,879,846,555,899,966,399,705,383,468,983,324,260,943,483,49,366,502,732,32,245,750,361,663,367,73,314,716,135,431,658,812,76,912,217,668,340,696,797,952,318,169,901,43,833,548,56,171,74,481,117,552,409,829,454,392,943,832,357,395,649,64,36,776,770,527,84,736,255,380,464,328,662,530,893,164,402,974,59,148,661,960,373,872,90,236,14,678,761,602,741,959,593,447,57,207,520,30,756,210,83,573,186,72,908,543,350,867,951,785,686,303,553,377,685,570,612,19,948,430,815,480,878,249,175,890,488,232,881,724,405,352,260,561,296,908,956,885,208,443,389,182,867,328,51,574,543,615,898,534,535,936,273,102,999,319,470,688,444,15,754,730,72,986,207,107,837,817,780,755,301,344,974,624,885,876,368,287,723,757,224,415,696,907,900,192,180,78,559,716,127,8,98,615,830,809,726,583,164,682,854,369,212,901,865,472,388,143,396,88,274,501,477,249,359,670,732,258,529,519,98,894,591,681,795,295,171,908,848,373,287,687,98,521,579,242,935,119,111,130,975,604,707,169,957,969,374,86,437,438,243,972,191,391,564,255,198,478,911,827,186,608,847,680,936,918,794,80,503,334,22,725,237,865,624,215,843,292,82,637,47,708,129,130,718,657,222,226,625,622,781,378,131,867,618,581,640,4,286,560,784,349,2,946,203,239,592,757,290,14,50,755,354,151,147,256,730,600", "491,372,36,732,653,25,642,390,354,23,731,952,758,961,708,490,255,564,795,852,410,351,103,846,91,817,30,191,456,986,953,375,663,687,183,773,920,808,409,952,627,219,902,626,266,756,760,684,825,545,530,187,896,432,743,628,236,369,523,566,321,273,672,916,249,396,706,296,254,716,939,410,336,437,585,99,635,305,519,195,968,337,79,281,461,348,779,342,214,490,841,655,224,461,253,631,109,829,32,203,226,711,77,78,526,830,919,22,491,261,186,252,0,7,816,506,181,193,957,399,236,695,841,854,30,983,56,244,560,164,300,750,374,201,798,141,287,237,205,326,784,504,899,2,82,132,790,328,326,935,810,37,723,929,542,323,600,252,14,898,514,857,365,157,684,119,71,72,848,524,275,910,687,665,639,851,904,377,231,24,811,175,837,611,299,900,477,738,717,853,248,33,150,524,206,759,597,945,948,98,261,468,708,992,376,881,90,115,337,165,954,185,489,526,15,902,993,218,368,997,413,443,13,570,435,527,727,757,507,109,531,439,857,530,69,961,900,792,198,219,623,438,578,355,269,459,681,127,21,327,155,295,674,930,191,9,557,761,547,562,169,971,393,616,889,676,502,364,12,593,869,851,836,561,420,666,111,358,717,555,699,77,34,801,155,905,767,881,545,502,5,114,120,695,924,797,86,579,389,140,350,552,298,687,782,319,306,838,880,167,906,25,76,533,671,487,291,773,573,952,338,987,97,910,124,979,130,785,758,474,850,612,322,335,312,237,639,833,939,727,926,346,952,459,269,86,174,578,286,180,339,751,153,456,878,389,927,934,9,599,66,157,430,725,78,720,551,798,584,291,177,778,203,212,511,451,385,420,710,975,968,910,109,343,618,728,623,87,941,509,525,384,822,859,821,211,326,514,459,118,375,61,155,621,358,188,331,61,403,318,460,680,872,504,790,277,337,436,105,716,389,526,996,552,809,906,631,59,378,906,687,590,646,878,498,663,818,603,65,339,320,354,952,902,392,516,99,25,527,29,3,32,20,873,429,400,151,860,314,931,52,624,235,321,150,547,543,109,834,9,11,660,763,156,428,403,168,717,4,686,340,896,814,190,393,805,607,173,351,298,536,2,648,921,790,186,639,423,43,86,729,519,678,891,401,147,989,738,861,174,468,959,283,203,370,147,874,777,144,625,19,669,429,900,328,837,875,376,53,936,431,372,710,385,447,155,621,481,216,242,727,46,124,767,481,972,545,15,678,124,339,464,232,181,395,134,178,364,929,486,200,234,944,618,264,821,507,710,746,905,678,97,440,933,455,215,431,83,781,426,821,136,649,600,966,853,427,715,436,170,765,723,694,145,780,405,702,304,888,454,588,556,346,540,350,626,225,298,622,56,821,25,52,974,961,164,642,384,581,95,613,34,458,101,219,291,431,107,661,964,164,970,300,456,411,91,931,123,975,419,627,830,188,201,374,895,637,647,772,720,696,906,374,10,362,396,147,994,287,531,914,782,972,754,44,325,909,948,69,225,39,883,209,623,440,826,541,952,549,807,896,943,830,631,246,700,863,612,845,829,958,177,89,705,653,547,108,798,489,410,364,869,479,185,586,899,365,753,612,731,753,370,849,810,129,685,965,676,893,644,847,127,802,572,855,848,441,48,283,140,412,939,971,556,944,930,264,799,270,932,41,309,714,911,749,436,564,87,980,388,153,180,141,284,71,222,384,632,480,823,152,168,892,665,109,324,9,761,986,334,518,98,509,300,676,794,350,144,122,113,801,89,111,623,135,534,202,691,316,430,258,159,277,545,844,13,316,20,397,618,542,881,86,946,40,146,518,409,555,287,433,376,644,374,311,919,93,783,564,187,919,440,609,822,600,763,754,276,351,207,709,995,301,641,778,537,695,42,18,686,711,29,931,583,725,146,344,533,953,746,154,420,980,579,452,188,773,604,639,570,335,947,764,381,12,646,557,293,424,752,60,822,985,75,361,325,849,430,178,874,714,395,209,789,699,201,330,768,153,191,462,468,578,581,887,790,279,618,299,869,247,814,242,637,686,965,562,813,507,878,455,873,891,253,423,336,532,689,903,636,513,525,434,810,588,218,139,340,565,581,421,349,651,443,267,189,661,113,646,413,42,542,522,849,507,849,557,832,197,736,78,818,594,568,61,31,265,235,733,881,484,282,78,394,520,972,378,792,237,350,115,28,477,960,30,736,732,597,869,551,900,772,381,594,685,60,999,772,234,718,602,246,956,13,679,898,180,498,223,15", "467,746,409,180,37,319,84,542,681,533,354,270,547,373,132,358,436,80,955,100,238,334,128,732,450,906,306,534,566,749,269,724,672,168,315,370,83,155,745,170,101,607,452,946,645,687,823,289,663,426,521,124,366,35,674,182,354,465,166,957,749,136,180,523,326,904,669,860,411,977,778,272,34,642,424,506,793,639,613,851,250,396,575,758,968,109,725,769,345,375,904,899,750,701,512,614,172,240,972,991,895,26,584,579,175,548,700,997,467,134,563,200,7,0,734,714,754,525,439,820,122,158,840,487,72,499,655,605,493,691,106,661,357,336,702,583,201,684,56,576,710,783,420,794,716,86,978,540,645,975,238,567,399,613,851,387,276,193,814,554,70,266,58,265,880,176,305,399,155,32,945,326,777,510,856,173,412,943,711,872,23,222,774,966,498,384,856,784,804,873,714,37,764,81,800,690,161,550,708,763,361,616,966,389,134,533,535,472,345,78,581,681,586,923,943,1,734,833,954,11,223,220,852,66,391,673,810,137,920,590,404,747,6,618,55,118,725,855,226,110,458,37,105,536,936,981,912,471,63,73,982,116,216,303,722,180,810,181,40,381,514,43,413,907,197,671,283,997,859,945,590,45,560,961,755,346,677,495,542,546,962,19,930,109,917,198,465,612,427,530,307,359,946,235,354,150,797,156,673,241,162,134,316,743,662,132,696,822,99,839,477,408,58,868,750,12,75,91,521,455,747,695,826,600,545,170,372,783,985,467,926,568,643,972,341,782,497,284,542,280,724,980,609,308,783,630,805,884,60,206,311,606,889,967,712,906,55,533,351,758,545,633,858,87,752,400,438,228,374,54,632,812,522,570,566,512,370,399,587,430,723,228,574,637,798,662,218,277,355,935,894,16,911,693,547,373,44,310,213,422,374,119,366,269,872,635,591,929,347,628,139,92,411,193,186,796,495,301,345,602,109,400,312,60,184,887,701,881,132,753,492,10,527,669,505,662,806,382,508,196,975,266,373,456,592,983,37,585,968,710,484,64,403,972,91,134,897,123,398,598,208,512,885,45,605,772,525,456,102,946,950,794,76,917,248,395,173,359,542,636,501,87,219,70,86,714,3,778,612,994,455,548,549,593,518,457,784,800,96,28,142,476,913,243,892,488,902,972,422,927,529,134,188,446,186,400,285,756,20,245,116,247,88,312,181,668,531,371,451,895,691,410,573,568,169,835,501,701,622,276,439,639,872,5,264,17,984,840,566,124,955,94,308,697,665,433,574,998,547,795,611,386,857,138,165,415,465,75,152,129,733,815,199,547,403,202,381,274,731,773,912,475,122,168,954,902,218,335,639,622,858,478,48,646,965,474,916,843,220,952,227,518,183,965,557,772,773,982,844,388,362,271,65,259,540,478,831,940,988,541,164,401,170,106,769,470,700,147,518,830,872,234,738,102,474,785,188,510,854,812,14,500,283,531,41,212,381,404,736,631,920,8,26,174,119,935,764,489,8,730,917,228,511,362,919,796,759,937,688,83,693,84,937,764,269,326,366,114,246,180,911,694,362,561,365,357,639,981,200,144,757,919,274,202,202,779,783,698,42,876,429,745,9,134,483,641,223,482,394,501,382,183,26,725,416,64,438,476,729,964,82,585,589,709,891,252,682,531,379,512,908,496,26,771,27,542,75,382,651,169,104,405,909,145,491,768,122,879,687,868,472,363,415,554,860,842,865,763,506,264,504,249,136,98,281,417,426,259,285,541,727,108,569,700,573,544,939,226,604,424,100,928,781,141,758,932,763,3,608,482,368,380,517,364,154,772,562,104,853,127,783,718,790,276,928,722,322,68,810,349,717,44,957,268,763,109,960,374,209,145,19,353,729,100,255,621,607,271,822,147,438,715,578,372,737,594,511,441,139,170,696,460,570,18,4,577,773,977,520,399,223,785,902,524,3,959,921,73,454,753,846,567,68,580,609,863,527,941,9,997,273,75,780,358,174,839,574,333,698,662,400,695,878,804,580,266,362,928,279,530,293,560,93,877,799,444,177,577,662,467,581,558,524,63,985,170,312,965,439,296,279,530,262,914,746,115,480,969,343,845,776,732,427,235,827,39,270,578,982,408,669,751,295,657,853,890,281,847,338,534,353,463,309,304,221,553,854,52,167,961,635,831,440,71,810,956,381,780,425,625,711,94,257,599,478,526,633,320,747,52,25,514,772,884,767,556,392,29,117,708,622,414,412,381,637,418,246,502,238,508,963,917,682,538,883,307,925,193,294,197", "33,876,227,775,484,458,408,938,251,618,484,279,842,784,895,491,82,686,738,210,114,92,686,84,315,388,928,177,37,471,406,339,221,838,709,564,256,501,552,969,420,604,726,406,199,951,766,397,58,436,793,274,534,24,780,513,361,278,903,872,128,478,969,369,697,92,285,907,107,68,731,768,921,877,107,953,834,865,978,149,311,989,719,607,992,7,948,820,767,9,145,659,265,957,102,983,284,993,500,358,73,893,709,533,346,136,547,580,855,90,798,751,816,734,0,680,950,959,533,686,870,199,372,646,206,769,275,364,912,771,859,85,364,783,580,899,639,5,575,483,866,113,885,193,268,544,686,581,970,535,195,122,107,455,570,614,774,744,131,820,246,770,608,515,784,930,245,458,547,872,53,987,543,495,660,280,781,63,720,597,799,966,938,465,981,794,888,640,187,668,818,932,440,11,256,585,672,865,598,569,827,84,753,530,68,403,940,296,836,973,633,271,787,776,195,229,347,85,103,866,697,740,779,464,407,899,443,408,79,506,739,898,27,174,223,751,584,6,448,203,481,739,503,267,80,157,435,139,805,493,304,52,146,435,880,372,971,987,702,695,668,974,145,231,994,587,163,234,275,123,986,459,939,780,593,523,537,177,226,260,65,705,586,64,302,990,196,44,639,354,617,383,421,802,588,111,231,267,107,558,103,54,9,642,356,993,566,556,934,789,562,540,336,91,56,661,435,874,849,766,619,314,626,27,664,545,227,6,456,513,825,122,984,586,644,513,45,953,539,987,199,206,95,818,997,400,459,125,976,702,631,947,847,188,45,206,718,880,968,52,753,47,986,333,275,988,883,966,629,960,596,677,760,638,47,802,845,694,937,326,895,915,692,819,588,75,917,611,819,304,517,744,847,967,743,118,831,568,285,744,532,973,743,264,609,144,579,396,97,238,324,920,987,20,172,100,79,865,950,55,323,77,933,366,19,901,131,462,612,296,648,548,446,270,622,732,21,3,485,854,591,114,349,33,545,585,133,53,257,396,644,84,654,325,901,542,920,457,548,22,709,737,636,716,824,430,434,224,97,570,86,150,976,300,337,709,439,791,994,782,378,963,99,625,884,577,924,580,373,197,119,864,484,579,155,52,614,299,823,139,912,524,898,93,379,28,68,831,175,718,47,351,489,75,362,704,594,11,862,440,269,971,150,439,6,151,689,868,266,169,285,857,785,913,413,530,256,401,28,939,783,797,673,702,342,415,257,786,580,716,5,258,176,731,343,973,512,351,653,588,803,898,661,880,323,364,743,553,969,153,648,4,630,205,21,531,17,376,227,283,670,933,510,591,168,874,32,934,493,483,297,390,676,385,846,404,717,783,255,467,993,461,23,957,859,697,613,75,196,112,424,166,850,978,408,449,286,764,897,248,290,474,177,691,51,744,643,943,144,316,867,924,245,274,203,779,561,594,269,341,782,387,811,26,371,199,175,982,790,9,5,204,294,283,315,478,820,989,135,701,943,561,301,329,19,375,690,45,146,423,734,510,406,216,335,624,917,278,996,270,745,426,662,87,333,464,139,516,693,303,117,284,811,514,678,548,470,293,572,767,389,30,431,455,771,935,382,406,524,184,733,995,706,291,487,108,576,542,873,908,515,770,775,790,720,954,931,528,440,755,546,831,357,555,474,507,803,997,277,715,6,228,857,143,566,583,330,364,144,406,836,739,446,896,414,883,44,124,476,677,959,992,832,295,798,144,756,665,83,404,31,594,52,322,106,922,831,845,376,347,855,455,434,473,488,289,967,144,769,992,788,583,890,351,558,506,456,107,256,499,47,970,942,741,297,763,235,809,420,941,911,88,925,630,882,997,27,594,169,640,262,11,984,614,145,330,885,924,907,306,210,356,264,889,508,38,80,880,360,212,475,664,461,734,236,708,56,174,661,381,106,71,729,395,431,623,627,854,349,147,563,544,427,530,630,386,492,914,867,671,784,356,567,397,470,924,36,147,577,412,839,167,511,228,849,737,590,758,659,543,623,34,963,476,748,552,427,956,597,718,416,161,500,664,412,353,324,50,591,118,255,551,371,30,489,201,208,210,520,546,491,392,272,570,747,664,122,66,817,913,51,754,571,975,199,130,802,217,525,766,386,529,891,513,336,238,310,849,726,76,488,612,389,156,360,327,343,776,285,362,980,532,136,710,873,447,577,750,499,784,255,276,118,546,903,213,832,512,483,243,154,250,702,275,2,820,355,291,532,425,258,243,592,100,914,331,358,893,241,465", "955,207,428,752,416,666,693,186,359,951,964,784,612,490,182,917,706,965,549,700,416,657,789,937,995,381,144,709,723,423,218,96,44,505,942,869,359,836,623,549,364,7,929,223,735,319,99,792,9,481,444,333,247,912,295,231,932,114,746,530,313,373,879,321,410,642,115,891,182,721,597,106,66,960,171,507,695,681,944,94,317,361,549,664,639,327,409,661,773,4,64,516,447,39,264,135,72,577,125,869,893,945,706,480,721,943,889,389,18,559,336,959,506,714,680,0,359,219,153,117,569,584,600,387,533,868,299,377,929,278,591,566,756,79,577,38,682,125,857,746,811,464,261,904,913,923,845,832,411,368,89,940,971,920,581,319,223,800,268,593,646,249,992,758,431,637,591,76,35,893,857,859,667,324,347,824,115,202,853,20,955,750,2,969,132,928,808,898,306,826,42,612,722,711,841,564,366,786,831,209,71,739,916,26,229,872,236,191,635,419,222,522,689,1,499,998,978,707,523,410,667,57,460,936,899,752,682,502,100,21,775,530,681,130,265,541,586,936,872,126,503,174,604,257,314,34,728,614,812,218,187,163,949,100,997,977,832,310,15,847,370,878,278,721,127,345,4,815,483,167,631,198,939,201,457,278,291,662,585,159,217,605,989,661,537,347,94,74,702,974,226,245,140,58,540,789,624,918,25,132,904,308,211,398,856,193,986,317,288,581,122,866,919,315,528,759,524,940,637,55,989,642,827,994,738,301,733,204,887,671,351,196,651,595,890,544,655,129,845,991,905,547,202,956,369,561,502,132,121,480,410,296,596,336,917,816,919,852,787,895,569,307,810,382,732,226,920,339,368,503,529,983,203,793,283,569,554,123,725,134,231,310,361,812,925,855,126,840,43,299,301,515,516,161,837,364,694,431,602,70,304,636,871,907,237,554,33,126,262,762,405,979,678,246,570,371,438,846,577,361,654,536,423,359,47,299,656,520,53,992,574,229,249,61,773,164,252,277,75,666,207,563,853,502,96,556,911,352,189,526,179,307,612,884,797,125,87,65,137,214,150,85,786,864,950,402,122,563,668,465,890,176,289,554,836,812,781,929,235,854,489,74,278,184,877,805,320,784,949,655,33,173,176,694,845,306,463,86,867,93,758,612,180,831,999,636,781,519,32,401,548,72,517,486,80,188,140,487,742,523,774,350,192,182,728,39,314,174,375,351,117,971,36,193,631,323,68,222,291,176,182,316,747,765,639,689,412,482,365,496,117,406,943,53,311,505,739,43,872,411,787,56,21,194,499,90,7,626,207,675,164,24,771,767,743,668,977,868,484,455,975,523,305,735,516,78,727,910,775,867,846,902,694,650,685,177,159,459,989,252,700,590,746,625,308,934,689,357,909,844,599,587,266,265,752,686,964,325,686,884,924,422,793,851,590,209,444,600,517,995,444,974,22,568,939,154,542,670,270,346,328,718,467,457,297,968,428,449,93,767,100,155,417,959,909,712,308,153,954,218,555,316,906,805,680,861,292,611,472,550,217,716,728,20,308,442,647,748,323,918,852,345,599,234,577,931,685,56,343,540,725,23,801,595,610,936,522,761,773,135,7,243,805,407,527,835,669,729,39,253,474,910,119,212,79,338,50,662,649,346,240,647,556,161,327,747,360,222,887,575,449,168,173,182,369,862,211,455,204,556,707,508,323,11,637,598,369,28,683,780,84,126,799,421,100,50,515,90,979,523,519,182,965,548,155,615,75,29,596,300,420,800,630,303,848,117,503,768,253,485,265,205,62,261,802,86,785,893,732,429,665,115,819,58,370,997,62,543,470,904,598,317,237,982,73,65,918,649,866,205,70,892,557,661,865,527,749,154,787,690,154,19,245,412,100,321,562,283,116,312,864,888,855,256,147,521,834,161,258,765,494,430,204,276,752,266,783,252,954,630,969,787,96,28,799,297,990,676,325,422,208,201,516,732,948,239,837,381,173,612,918,643,71,480,684,3,449,527,713,409,719,48,814,164,949,503,424,649,181,258,438,809,513,445,626,911,685,806,607,448,892,662,86,949,29,25,107,863,958,288,713,989,947,347,46,977,920,427,49,559,58,674,46,774,856,391,669,467,619,556,597,757,429,620,447,64,735,498,809,343,607,635,253,779,568,691,592,894,953,796,405,517,770,711,283,853,187,571,402,73,603,923,380,345,578,551,686,453,111,53,565,610,497,223,632,407,53,212,12,158,883,10,703,325,487,343,309,500,711,34,248,964,407,595,344,370,711,945,827,187", "883,833,625,408,381,716,358,921,99,242,466,547,906,33,994,621,910,898,602,642,680,106,343,118,974,582,773,7,662,564,625,833,226,78,767,318,904,573,742,341,350,362,920,898,219,492,71,411,535,814,684,454,565,323,983,699,290,41,456,749,142,948,609,783,58,819,458,980,991,712,105,373,325,589,813,11,693,351,558,901,685,103,453,289,31,315,498,156,167,804,179,503,995,311,865,428,470,450,921,573,204,559,490,248,353,863,519,417,726,562,970,901,181,754,950,359,0,787,956,232,426,379,408,185,693,517,181,863,170,443,486,90,660,840,405,432,148,888,950,899,67,423,847,913,923,832,457,561,236,544,400,734,744,26,91,582,887,654,693,449,423,117,510,326,794,742,502,193,452,107,473,839,561,159,890,947,371,802,756,218,291,188,686,71,504,450,776,719,290,16,819,795,892,67,82,374,318,614,410,980,391,635,911,197,75,250,177,960,604,837,677,793,8,252,169,411,92,535,452,860,520,95,24,290,59,416,829,119,49,734,96,367,301,872,360,347,101,681,167,886,29,156,123,148,840,132,357,12,719,828,963,618,76,680,350,69,975,581,147,249,744,340,442,900,857,334,110,378,394,850,636,207,718,554,298,722,827,692,837,852,840,786,603,896,153,850,314,10,60,80,671,226,507,713,822,673,646,278,268,641,234,145,518,819,100,428,96,338,810,659,61,423,711,96,190,964,96,757,862,321,426,518,220,428,786,898,984,179,221,992,23,811,713,519,869,775,959,693,728,62,60,452,820,735,579,878,443,598,387,938,486,619,269,674,505,256,705,6,619,395,836,515,192,5,591,640,724,490,502,821,742,630,802,476,150,446,725,270,812,99,7,653,247,186,326,896,45,386,439,566,743,261,177,633,431,250,1000,721,218,235,432,298,502,633,377,342,151,547,120,253,760,860,358,393,340,593,803,61,806,815,981,949,614,543,444,607,870,64,961,860,971,575,263,861,698,372,634,868,338,591,30,908,481,998,165,411,813,375,67,338,322,49,586,122,16,921,432,328,344,730,232,36,595,268,799,225,97,650,957,125,735,411,810,115,687,5,956,630,284,237,747,728,395,673,359,913,175,105,668,121,641,255,405,330,319,158,143,986,881,299,761,931,359,553,521,429,677,40,883,427,895,912,142,254,717,562,185,994,356,333,405,963,960,489,1,187,6,94,706,296,47,943,121,921,832,294,274,984,510,136,825,354,549,624,966,901,253,699,819,32,912,658,622,370,287,464,608,193,747,381,310,723,166,127,389,79,504,52,66,674,735,455,494,351,891,425,847,946,943,845,549,21,82,840,910,703,781,556,902,181,306,891,838,461,333,908,817,675,665,529,755,623,824,834,633,362,431,851,587,99,977,213,608,41,423,651,775,708,175,299,15,165,582,959,567,492,713,284,294,163,219,493,994,212,94,704,883,54,579,554,335,593,513,597,36,423,43,43,845,891,221,740,587,61,639,432,299,320,891,729,702,761,37,629,159,66,609,605,622,180,510,151,632,816,465,550,378,814,485,585,250,97,553,530,81,410,619,822,533,436,416,607,766,663,984,530,952,292,225,103,945,908,623,167,83,474,658,251,474,224,577,525,148,532,534,648,989,646,297,941,738,124,562,646,857,209,705,170,684,63,261,322,102,285,582,138,781,435,473,547,987,781,404,78,9,734,172,195,549,183,840,575,774,250,581,866,541,442,159,466,515,875,173,951,784,723,972,623,49,358,189,960,730,362,869,768,858,728,937,910,351,696,209,445,894,662,657,985,935,200,399,673,977,955,378,466,785,598,114,922,398,274,174,707,33,296,272,948,385,597,336,639,40,308,138,909,323,278,339,842,907,358,850,314,987,141,947,979,490,253,342,361,498,127,735,892,493,137,367,676,92,353,398,344,360,618,58,424,273,377,694,988,476,751,200,478,699,687,484,861,397,305,126,595,760,7,615,456,429,725,763,786,3,536,713,549,499,519,884,793,719,659,415,871,513,749,249,698,760,48,336,18,163,6,997,833,767,46,342,56,833,238,653,338,264,867,699,358,259,12,924,437,348,77,274,129,982,80,45,647,697,81,684,790,321,15,608,444,733,694,549,33,173,52,599,203,315,997,439,72,870,461,186,72,730,636,162,751,529,571,433,170,898,156,643,371,906,990,913,367,966,347,655,87,471,784,489,759,355,3,927,420,574,214,375,971,853,738,913,101,329,129,327,725,135,272,440,32,893,385,690,216,476,27,958,450,81,200,912,269", "353,719,275,597,553,671,960,931,179,228,734,601,609,703,518,68,302,820,81,531,41,126,46,925,872,245,328,718,953,10,702,252,805,651,277,236,330,553,854,1,759,876,15,412,290,302,353,968,55,122,486,82,334,144,25,199,403,630,369,306,513,908,894,24,578,199,522,683,492,100,481,924,3,602,203,774,121,265,441,179,633,237,243,395,686,801,832,321,876,6,211,959,366,31,705,352,50,486,4,671,347,916,438,184,374,861,697,558,457,183,379,473,193,525,959,219,787,0,183,781,719,562,779,743,353,546,274,952,546,371,160,283,630,698,5,277,682,368,973,705,276,377,533,644,688,70,844,952,171,278,988,919,695,119,909,26,844,993,184,177,712,651,289,131,184,364,773,255,411,215,512,31,580,906,791,956,508,770,757,838,776,417,138,482,341,333,101,30,805,389,488,758,437,161,731,392,694,183,46,395,244,766,806,228,680,79,380,316,845,649,272,597,622,449,758,765,447,355,663,210,868,49,262,475,237,832,812,266,500,465,530,447,919,776,426,323,38,816,726,514,577,267,143,765,741,240,123,781,402,793,298,977,432,19,33,947,937,699,725,976,216,693,56,346,853,113,275,863,7,494,273,962,61,497,170,666,541,234,867,687,449,1,275,752,895,547,263,37,979,417,149,263,381,41,702,697,89,16,647,214,281,542,712,194,149,760,976,14,604,75,581,200,268,586,62,274,249,948,146,946,856,837,124,810,416,450,133,317,71,135,553,712,762,118,198,828,311,830,602,294,515,242,801,296,243,894,193,383,994,494,888,899,954,856,18,293,476,663,909,234,574,182,881,359,3,175,508,75,259,994,110,36,515,260,556,416,536,449,541,924,376,116,268,917,900,690,217,360,37,307,665,314,708,909,341,504,52,990,254,41,979,463,624,969,678,750,867,357,80,32,209,57,49,474,392,12,374,841,789,132,500,966,824,363,127,137,373,664,273,659,923,932,902,158,52,469,606,640,587,6,675,138,321,795,315,324,735,804,175,660,231,908,53,979,646,508,688,222,169,454,49,482,826,307,472,787,749,131,372,794,189,47,93,760,698,651,734,222,312,119,722,566,522,288,486,311,614,713,637,793,547,679,420,478,754,714,139,501,5,83,375,186,258,544,917,119,220,939,268,833,560,800,131,503,855,998,273,48,313,969,845,928,169,330,990,291,838,387,635,712,181,857,224,271,256,235,189,599,84,841,182,675,227,375,266,947,261,471,614,928,584,88,940,118,567,193,856,15,507,198,7,239,659,773,628,71,529,233,562,124,209,142,446,525,238,301,477,821,604,924,719,288,873,959,426,957,61,770,768,856,423,568,521,145,258,136,776,726,138,512,274,807,470,52,469,651,674,494,657,991,615,939,617,643,425,362,636,530,284,446,441,966,557,348,656,655,251,242,916,449,414,833,675,659,320,787,60,914,891,989,402,295,956,740,807,414,160,925,186,78,754,35,392,520,214,220,263,233,72,655,480,645,208,700,265,618,426,563,422,69,275,667,521,91,4,970,452,154,548,972,314,374,199,719,520,901,549,141,863,309,11,682,169,803,544,541,99,956,266,356,864,59,331,34,394,197,789,953,671,901,60,874,153,668,909,865,574,248,180,385,934,589,584,215,468,989,982,326,461,64,621,880,683,920,385,723,159,461,875,908,63,315,133,458,182,440,254,289,852,714,504,617,995,581,76,598,562,141,340,427,582,284,88,129,397,552,657,313,473,241,980,89,728,31,985,322,440,911,360,157,950,960,981,714,603,960,410,18,857,726,911,405,590,333,480,782,644,880,601,353,992,335,108,93,179,832,844,410,177,564,336,546,385,5,454,679,283,542,309,934,225,381,928,373,132,566,740,185,37,380,795,401,347,293,354,782,316,613,499,697,989,158,949,420,347,779,858,191,116,381,499,394,487,76,620,759,278,729,481,23,717,196,767,979,225,471,838,634,23,634,362,298,592,229,892,537,892,425,861,698,244,161,607,220,660,998,478,323,775,461,501,336,92,636,588,381,656,855,992,603,755,738,958,994,219,260,991,14,412,339,380,3,226,12,589,649,623,689,806,851,670,649,445,151,196,815,752,913,311,388,225,888,577,366,111,498,334,911,893,67,169,428,808,859,916,285,760,591,693,12,986,210,551,141,959,662,899,264,851,485,754,524,794,238,62,380,655,490,480,219,390,756,944,926,63,596,408,529,980,70,189,14,750,229,540,605,503,604,501,340,581,313,627,81,402,307,619,289,23,872", "452,607,207,866,441,842,799,876,420,42,815,9,671,725,499,359,52,698,464,578,630,249,735,814,463,543,959,443,613,117,726,15,953,860,967,340,606,460,256,695,154,613,6,360,502,645,800,855,964,73,812,494,375,814,575,348,920,266,438,570,590,807,246,670,467,920,55,410,793,627,569,600,38,805,666,82,988,84,854,486,732,125,542,807,155,718,706,473,887,914,351,560,420,597,837,184,670,356,316,895,983,630,358,733,409,137,308,67,887,927,551,351,957,439,533,153,956,183,0,667,459,600,223,840,142,263,315,93,953,535,498,515,813,481,538,374,153,376,220,128,756,144,629,718,111,977,688,179,291,489,634,494,535,330,561,355,651,511,951,827,209,83,701,729,893,974,339,657,459,21,234,238,482,490,619,566,721,820,534,359,272,579,849,315,467,947,560,290,646,931,752,34,578,810,388,56,468,136,905,389,281,507,713,507,998,747,944,313,380,445,916,222,918,509,320,46,87,62,603,158,567,70,407,289,55,379,16,81,89,459,395,937,250,282,537,242,988,412,320,808,609,966,978,530,184,647,427,6,136,866,107,593,850,231,425,424,166,96,288,867,584,77,523,612,844,256,892,58,837,970,42,550,885,240,568,258,364,802,733,45,245,735,586,698,505,535,333,476,876,723,171,955,796,778,536,948,974,500,18,972,424,513,84,687,107,518,358,796,477,111,98,790,72,138,600,645,987,662,178,885,953,662,326,300,770,250,506,939,872,344,816,505,185,347,220,542,559,413,295,111,135,318,246,636,372,68,317,278,775,676,542,666,75,60,260,962,910,593,146,43,689,875,84,656,157,593,165,139,944,519,921,484,598,391,730,314,203,918,795,86,523,436,232,251,35,654,340,378,614,333,390,117,975,808,8,231,394,412,784,127,373,526,428,193,848,935,770,566,716,410,273,84,888,1,816,627,408,556,144,600,289,183,640,728,233,184,106,569,355,502,772,200,543,118,100,648,452,580,536,200,233,137,602,913,365,642,612,9,931,509,536,997,133,85,34,457,910,504,11,674,385,624,276,449,175,445,537,460,328,703,55,36,515,115,548,924,472,442,133,219,882,343,439,778,62,822,412,418,138,381,779,309,216,429,490,111,115,482,736,36,200,534,31,643,214,352,554,807,930,476,762,725,130,886,123,517,913,73,16,114,538,450,434,806,503,210,510,883,624,800,346,302,128,328,177,884,989,189,774,931,299,127,605,748,638,165,124,750,84,824,492,830,754,755,816,103,695,772,935,985,391,623,971,565,56,372,670,985,744,349,628,428,355,794,581,61,69,344,195,700,488,18,104,241,833,148,952,515,224,283,698,137,944,12,657,153,86,612,157,741,335,959,126,697,873,622,153,856,708,355,826,101,45,471,173,28,220,142,442,629,327,268,509,192,73,312,454,613,908,180,499,356,131,398,2,49,546,665,829,896,798,848,815,553,937,181,117,96,491,57,756,818,323,302,211,152,986,3,987,885,65,403,342,556,18,823,673,518,221,277,662,762,886,384,430,333,124,569,441,669,641,295,354,997,518,55,218,583,168,688,565,134,428,329,720,926,460,715,217,214,514,187,476,966,877,330,442,974,514,819,503,70,973,950,363,593,170,692,969,999,570,181,481,518,764,830,800,121,585,918,707,652,469,721,297,82,164,972,746,167,287,756,353,507,549,838,600,62,299,999,421,179,870,740,256,348,556,815,971,24,949,820,623,397,51,35,597,898,349,180,784,616,913,489,690,870,247,941,140,290,32,720,920,367,677,760,909,22,117,23,419,572,866,325,41,548,27,191,992,838,543,664,138,939,711,796,170,785,947,666,645,833,277,7,676,114,493,234,743,360,912,592,711,552,560,623,258,443,291,516,755,409,358,803,283,875,628,141,360,194,275,523,75,964,852,441,924,586,334,356,325,999,62,295,302,965,236,86,399,206,612,391,952,2,909,677,531,594,239,818,22,855,448,875,490,150,681,737,211,425,439,823,856,919,326,948,964,22,711,89,974,70,371,679,989,5,532,631,329,713,941,12,50,680,639,605,109,862,463,338,199,972,230,85,525,681,842,322,298,595,601,892,937,624,264,719,434,441,745,937,56,884,447,24,147,655,293,937,411,876,358,635,523,14,75,434,756,579,648,645,768,245,208,69,649,98,111,647,984,802,780,975,591,76,109,896,334,83,788,354,896,735,612,920,669,244,387,660,90,299,709,559,109,881,849,351,683,585,491,383,54,708,31,757,788,391,444,98,183,433", "60,546,176,425,433,659,544,323,502,758,262,771,520,50,509,325,414,4,431,329,967,429,217,228,308,981,458,21,751,149,258,311,195,995,502,946,681,908,787,160,443,569,886,848,515,746,267,884,816,153,16,372,372,918,424,438,85,460,949,98,839,788,662,699,450,900,249,870,382,219,10,111,975,500,937,422,832,924,547,950,178,501,107,193,147,25,134,79,790,77,665,697,993,366,607,668,32,812,624,684,826,417,742,219,547,928,863,124,925,753,52,332,399,820,686,117,232,781,667,0,312,597,977,269,38,42,77,513,358,508,510,497,482,390,911,58,245,336,933,175,585,986,509,648,83,254,332,271,223,400,457,387,570,38,327,560,237,489,426,98,43,584,389,573,111,257,642,859,933,630,384,283,771,431,281,360,764,240,112,976,466,404,89,20,316,923,876,808,554,596,461,533,393,710,885,684,55,597,717,961,786,545,521,966,386,901,996,783,226,169,905,366,768,460,531,969,477,284,603,396,994,520,375,667,473,601,329,94,674,802,972,314,976,437,170,631,501,614,973,830,845,579,120,448,746,928,21,318,361,522,48,853,899,545,660,91,12,374,905,67,682,834,273,233,493,143,834,293,169,133,708,201,694,565,939,257,401,45,624,136,367,566,296,957,34,890,259,311,301,927,387,786,610,571,104,597,463,517,104,557,693,577,387,691,686,395,722,550,620,130,726,415,469,371,934,695,958,867,84,937,393,829,994,869,939,62,464,186,465,558,796,262,802,29,518,15,785,805,838,813,484,995,893,195,513,608,362,843,267,102,680,197,674,46,662,249,166,360,873,247,272,106,842,197,916,479,338,87,19,576,477,481,338,99,67,917,548,652,249,613,686,660,335,382,124,408,889,265,123,815,475,613,32,783,316,950,338,547,399,485,675,696,488,393,903,731,547,564,821,292,226,925,256,51,536,637,582,191,968,352,997,961,324,458,915,575,422,880,57,636,36,927,536,757,665,682,917,367,658,753,658,332,158,516,608,186,884,735,822,273,559,356,393,581,735,13,234,138,860,750,507,120,456,141,790,682,843,343,603,810,116,535,412,438,697,342,264,555,758,24,693,472,62,801,19,830,292,948,810,798,42,325,621,520,240,541,246,638,332,906,102,384,811,380,462,215,455,945,666,511,662,254,730,801,950,86,155,906,238,589,503,471,493,392,482,324,64,58,352,39,37,44,623,987,251,65,168,714,431,165,668,973,987,796,500,731,485,90,159,210,478,840,623,541,726,310,846,545,670,973,641,58,391,525,285,154,107,557,391,937,340,398,751,135,161,161,56,79,68,289,899,494,665,611,474,542,436,997,326,457,952,553,622,152,418,17,545,847,220,996,74,283,78,697,116,533,142,765,553,340,903,850,736,667,543,893,642,420,193,619,592,342,451,579,496,508,19,327,687,659,191,221,993,683,47,316,91,814,980,542,873,127,443,748,363,838,409,112,591,56,248,200,847,73,561,263,180,912,320,651,327,194,427,308,331,741,658,918,985,571,213,34,984,198,392,806,329,547,299,158,728,773,10,262,625,687,260,187,706,537,679,777,69,63,914,784,845,531,171,831,372,297,383,925,722,117,793,657,364,455,120,344,907,299,225,326,299,886,908,277,99,712,895,684,261,644,854,151,566,652,620,3,758,555,454,867,69,66,384,214,252,288,812,703,745,929,599,420,431,839,324,784,576,673,398,208,425,477,285,500,565,941,929,890,783,969,621,150,940,256,554,752,440,379,636,597,838,134,269,770,307,162,263,466,617,291,378,148,323,889,357,779,153,919,197,871,908,746,124,405,205,162,209,3,84,509,626,463,254,444,272,323,580,26,213,895,37,77,240,216,350,835,179,341,577,787,219,810,304,993,575,712,978,528,21,768,322,746,48,979,553,798,183,946,545,767,719,931,977,930,904,344,487,690,845,666,151,875,873,237,232,409,743,944,24,788,155,55,332,928,250,682,9,833,482,140,314,71,11,146,480,682,376,317,37,428,384,811,846,524,29,47,980,797,430,455,322,845,446,911,683,998,547,982,99,627,745,228,97,809,979,648,35,548,217,103,264,991,172,272,819,638,351,898,187,357,393,534,948,64,319,677,830,927,319,74,720,397,496,732,763,671,72,664,652,937,36,3,763,106,197,453,601,35,923,617,694,230,500,379,62,661,343,875,924,678,46,41,135,156,806,426,26,197,205,775,285,475,692,293,125,237,253,905,281,93,448,289,973,341,705,261,980,617,421,324,362,307,403,387", "588,124,190,684,689,288,434,98,390,301,678,828,52,816,225,958,824,113,306,172,818,978,305,708,855,2,356,734,162,858,854,587,672,598,698,633,744,702,946,119,210,155,947,981,497,643,616,684,134,324,956,879,734,173,496,318,919,845,202,706,453,722,317,985,275,47,966,635,239,810,958,154,135,752,857,966,931,55,784,685,980,810,414,722,447,312,612,25,317,465,704,835,193,127,591,91,76,48,452,340,904,38,16,739,745,831,901,461,242,166,182,92,236,122,870,569,426,719,459,312,0,723,393,838,654,968,431,402,678,605,56,110,64,492,615,27,187,135,42,207,8,848,785,751,838,49,179,504,884,110,481,559,697,740,69,146,130,54,469,978,282,845,96,847,216,844,30,398,196,35,576,494,833,368,541,463,585,480,636,243,925,821,452,663,618,973,320,446,900,198,290,56,379,363,901,928,604,741,633,982,691,968,410,997,381,160,85,882,521,603,630,860,381,2,233,885,242,352,518,315,688,992,604,590,5,859,493,328,467,596,815,274,265,326,154,360,675,577,727,661,471,176,775,952,142,597,885,576,492,517,424,218,694,110,439,565,791,212,856,654,710,793,38,533,959,716,483,478,235,123,21,668,200,636,134,300,756,929,884,185,701,903,60,626,803,811,841,280,382,621,399,5,922,866,725,880,712,22,108,424,221,412,591,59,857,792,885,858,629,318,488,706,426,29,105,273,665,691,259,413,37,969,333,958,946,370,394,2,448,781,709,871,179,195,356,859,293,348,448,323,325,259,645,545,255,716,746,631,216,304,947,727,304,869,263,63,671,238,259,133,589,268,964,831,822,189,479,913,935,2,537,29,708,783,628,140,23,426,924,885,350,816,380,52,60,566,765,626,405,135,211,453,659,853,654,431,607,679,597,770,828,760,626,861,77,659,667,41,194,14,905,932,856,997,677,37,140,922,677,890,171,636,475,757,596,156,33,950,617,349,227,338,2,278,89,916,931,728,51,532,741,87,856,893,850,993,924,3,993,860,743,440,225,462,431,369,155,846,651,246,614,435,148,929,176,951,366,176,572,504,747,132,354,359,794,52,897,339,921,566,735,47,72,336,14,178,358,805,576,188,48,188,928,861,973,579,727,183,834,815,954,236,200,298,873,198,587,750,11,973,209,553,848,565,609,858,210,823,578,636,247,123,213,911,629,21,275,890,214,19,217,555,672,123,752,107,138,426,934,696,584,56,220,568,868,283,739,154,430,343,337,964,998,111,889,305,901,694,446,509,207,574,758,389,415,503,403,377,681,849,826,864,637,936,642,559,79,632,819,400,722,733,612,716,274,608,359,240,389,392,410,700,82,662,255,745,99,492,70,612,645,585,270,255,769,870,520,139,259,808,656,663,699,915,524,252,899,479,400,556,982,499,303,199,548,645,887,655,508,483,103,590,693,66,30,255,716,774,677,190,519,419,180,3,740,342,79,695,315,203,866,685,348,998,637,704,462,425,56,441,461,873,803,449,633,826,757,156,208,588,781,528,683,40,699,153,483,446,378,370,779,641,718,636,936,424,103,925,336,608,754,682,936,142,770,722,227,701,479,363,44,811,799,256,391,346,493,55,364,991,680,700,418,844,737,676,981,771,28,786,745,732,16,86,900,936,998,507,493,221,927,409,725,870,659,611,111,891,161,352,227,706,157,181,716,26,551,576,865,888,331,839,185,698,138,505,125,895,171,185,7,426,108,78,766,834,109,242,944,88,514,25,489,4,794,336,286,420,467,88,303,117,985,717,159,503,402,975,473,800,354,376,389,617,363,642,917,571,631,899,445,373,887,166,96,820,50,263,185,433,277,616,651,159,222,910,928,185,121,356,253,631,619,592,917,453,609,194,846,550,821,305,206,215,292,968,503,985,638,989,63,161,965,816,411,476,584,596,77,418,891,918,890,502,226,740,571,210,827,707,101,828,166,992,467,353,658,493,872,822,979,152,579,966,323,341,196,140,235,718,210,135,384,8,846,584,164,375,446,312,207,317,546,382,85,202,827,142,667,864,899,639,809,129,714,103,699,332,730,732,152,179,770,956,134,828,526,285,768,409,80,572,306,621,260,158,111,549,400,467,127,672,353,754,827,24,397,60,405,126,941,226,39,889,687,276,680,477,46,820,842,924,255,964,469,777,616,692,380,122,537,709,638,721,50,474,202,327,250,919,598,748,812,523,286,785,774,463,371,133,417,251,951,24,216,735,707,639,517,251,447,906,940,869,300,23,163,74,517,560", "87,719,881,790,677,987,865,161,842,431,553,645,952,160,150,922,800,969,133,337,424,814,918,664,342,372,211,858,227,617,738,663,191,567,262,363,702,707,953,462,805,380,37,544,80,244,256,279,606,801,229,364,723,825,669,999,591,710,442,85,376,477,630,414,955,848,667,749,354,794,238,596,330,158,429,637,887,218,202,330,278,715,204,420,276,9,181,995,432,983,643,697,878,331,828,656,62,528,246,257,208,274,448,888,739,670,346,641,201,827,973,357,695,158,199,584,379,562,600,597,723,0,297,730,890,770,180,605,699,195,299,301,38,756,516,733,610,432,590,883,318,471,770,820,952,545,418,663,525,399,490,972,261,605,106,913,457,675,97,236,594,116,700,208,959,178,144,167,393,638,964,890,248,915,746,971,441,876,11,218,770,410,850,386,502,938,263,92,413,271,179,252,656,230,650,913,609,136,618,970,904,792,80,622,722,257,906,434,625,858,71,363,615,437,461,953,941,119,618,70,139,64,844,537,729,538,852,14,531,489,518,635,179,941,5,217,150,250,819,957,693,333,423,209,385,375,820,310,770,851,409,102,743,535,611,958,330,59,75,99,614,547,660,225,577,487,247,820,372,682,687,207,583,378,44,744,287,78,543,983,170,138,265,486,381,485,107,324,655,589,744,294,163,689,910,919,338,387,21,613,926,297,412,116,516,481,947,220,78,619,226,56,693,555,570,673,158,350,568,775,154,476,789,946,437,204,465,329,706,334,100,930,488,223,534,204,843,31,888,789,691,455,721,895,741,248,546,307,88,572,69,336,951,638,432,773,299,664,146,204,104,405,243,652,866,350,466,416,590,317,652,646,288,422,84,780,609,237,177,992,583,959,416,994,630,112,657,807,894,945,76,362,600,787,842,847,793,816,940,890,278,625,811,64,450,279,936,223,229,201,7,305,674,765,791,42,945,439,466,346,733,285,310,232,959,270,260,392,863,206,754,991,468,157,828,546,370,801,635,82,50,735,411,133,653,412,931,814,447,991,87,907,41,132,503,45,836,691,439,528,796,750,702,844,853,36,253,699,367,483,316,655,647,764,882,933,768,775,776,975,721,863,141,677,484,725,470,127,471,773,531,512,546,587,699,561,195,845,261,594,617,85,105,592,948,723,948,643,13,313,362,656,107,35,58,975,87,872,101,344,38,346,98,589,34,917,450,837,334,166,461,80,357,948,611,930,778,116,484,984,737,776,567,22,525,237,102,210,370,521,169,504,141,932,327,194,49,94,164,833,529,810,822,983,95,727,304,707,146,167,48,733,411,48,863,438,802,315,657,6,243,430,556,644,285,184,813,438,17,561,491,832,983,898,947,862,947,404,592,339,787,526,854,836,11,621,405,61,301,151,531,355,328,153,465,466,684,847,261,453,531,572,110,546,932,497,682,381,689,990,359,67,381,665,668,970,793,937,884,780,542,445,222,175,547,509,130,693,394,845,411,555,565,936,590,857,981,999,377,365,814,202,244,507,289,668,372,927,809,571,301,106,742,691,785,629,370,39,100,413,816,685,318,642,237,294,434,384,66,742,185,256,510,934,178,390,177,317,639,24,731,537,733,845,923,714,228,111,103,843,529,986,13,278,384,171,177,89,284,70,720,253,282,466,652,434,422,359,128,813,286,664,150,175,687,992,661,300,609,497,161,826,538,336,522,62,510,695,523,589,342,585,636,610,602,742,240,100,61,814,472,541,394,65,833,214,764,793,302,868,131,478,973,331,611,29,850,296,894,92,157,718,617,975,913,473,881,102,916,67,880,138,390,625,237,634,935,334,827,298,403,516,812,157,582,829,650,881,402,595,844,64,2,623,68,783,699,160,154,203,484,598,634,423,811,661,202,125,865,368,886,663,9,466,250,958,132,889,242,726,323,296,346,666,327,50,134,567,470,282,717,908,115,716,383,679,645,773,54,768,158,345,524,145,381,494,739,905,967,870,874,394,960,947,543,272,849,553,86,333,674,324,43,269,846,266,840,231,6,41,19,82,490,160,851,253,890,304,182,133,216,158,41,430,397,678,235,950,675,8,226,338,408,212,238,271,77,650,392,394,89,914,433,235,807,944,789,382,442,969,933,859,724,244,505,562,71,48,670,129,78,892,748,834,242,957,273,424,368,777,709,318,61,443,337,764,187,32,370,565,475,823,557,630,822,864,132,879,662,798,11,322,285,479,839,270,10,483,28,173,430,336,485,443,252,177,73,365,490,791,55,648,175,528,198,644,139,141,838,262", "109,555,447,475,393,558,975,612,589,961,703,421,506,609,547,438,383,362,576,815,474,474,288,236,277,612,153,543,431,681,383,328,493,167,332,712,713,778,811,297,254,962,423,83,938,891,134,183,246,623,834,363,188,940,414,24,32,947,676,929,659,588,920,959,520,2,122,279,602,526,811,911,507,390,295,573,399,37,637,703,645,225,484,84,306,853,94,376,456,909,147,760,528,880,100,370,624,589,758,896,302,383,74,61,311,682,17,290,502,862,956,574,841,840,372,600,408,779,223,977,393,297,0,984,986,109,878,308,384,926,192,425,187,55,993,393,374,862,550,241,372,922,641,301,468,440,844,72,577,847,938,547,10,406,868,329,223,919,991,90,733,16,694,119,651,436,817,257,639,173,831,885,51,938,303,626,936,942,233,522,425,327,491,916,238,671,977,976,785,274,451,785,240,691,939,501,905,101,698,96,402,359,730,291,622,392,783,189,27,771,12,528,681,115,726,728,936,841,476,41,339,143,464,619,699,604,359,878,370,406,211,287,661,521,553,463,363,326,128,895,200,68,347,164,947,379,784,23,857,712,395,579,720,340,514,214,23,880,645,261,333,707,64,175,234,325,20,927,82,164,266,564,851,54,681,2,535,468,573,861,709,709,981,794,123,781,704,869,240,893,687,447,897,120,893,419,168,280,582,749,519,880,382,670,618,347,933,275,342,840,544,425,687,958,804,182,176,366,787,747,76,903,934,31,737,56,208,398,618,961,926,394,911,876,851,772,684,504,690,972,996,633,736,991,491,780,654,259,161,456,345,369,700,608,694,829,165,538,665,515,618,853,333,399,665,108,399,964,989,108,469,793,454,256,483,635,185,577,1,780,314,333,738,691,424,821,537,263,414,556,860,347,517,769,375,500,845,694,293,871,531,191,382,176,746,801,105,716,163,820,291,360,334,778,890,716,141,584,745,996,831,48,387,678,670,232,455,700,668,303,227,728,16,927,68,599,551,996,858,468,713,917,983,999,686,264,249,105,87,361,914,494,554,802,931,634,84,581,160,896,103,293,16,113,250,277,980,550,462,823,86,840,799,714,669,890,636,366,702,440,50,951,807,8,830,751,793,816,681,44,335,640,919,579,944,765,89,224,764,322,346,566,216,538,100,835,118,167,303,657,670,975,805,540,104,422,893,844,32,464,105,257,192,137,471,663,708,496,803,187,581,49,265,966,73,406,535,502,136,429,899,394,700,677,982,840,156,769,216,216,725,389,474,693,100,417,970,731,272,107,476,756,21,35,784,189,446,316,970,135,779,104,647,443,813,624,552,779,985,264,17,831,318,283,169,99,334,136,322,970,980,146,827,94,337,202,343,955,254,212,470,28,73,356,533,331,785,479,689,524,366,511,27,555,285,708,400,459,796,631,627,60,392,666,364,862,914,529,32,559,774,712,435,584,917,965,97,713,674,938,969,972,894,829,77,724,517,436,337,541,356,126,166,540,351,578,810,896,214,567,362,200,636,356,7,512,421,213,91,704,890,99,475,640,999,201,492,743,830,328,134,955,854,70,220,329,45,481,917,389,674,465,426,492,530,313,857,133,912,846,680,417,872,499,811,390,674,497,952,951,78,746,501,300,168,358,345,386,893,631,413,740,15,655,534,21,92,164,887,903,933,892,550,608,730,30,928,54,923,855,244,278,662,609,318,236,111,118,706,829,275,395,562,809,497,51,82,278,104,49,796,334,751,616,495,793,96,473,522,355,340,620,183,494,873,585,927,882,446,269,195,683,698,802,78,961,531,426,623,778,400,616,789,711,840,948,256,477,496,980,89,806,32,777,717,322,660,640,487,628,791,633,133,965,811,947,107,496,23,334,133,62,416,568,681,103,282,822,921,616,355,33,60,205,657,993,934,289,181,352,135,302,674,566,787,212,126,821,752,480,313,248,28,181,168,173,159,117,738,433,96,92,606,894,12,197,993,203,765,793,926,159,492,575,132,687,648,169,183,100,165,950,352,55,900,910,301,425,527,797,805,384,256,295,893,430,793,747,252,483,458,468,349,385,61,628,801,146,874,230,961,686,701,22,583,30,148,995,80,120,573,842,368,679,81,538,290,737,446,100,80,184,36,141,733,472,606,170,296,679,689,921,791,5,732,991,321,165,512,710,920,481,770,292,278,650,918,996,894,596,632,121,723,210,399,429,26,118,250,919,827,282,758,491,630,542,93,229,943,360,519,683,586,929,662,252,282,33,55,226,553,172,649,723,993,404,353,583,643,280", "473,154,530,48,767,590,997,366,332,245,270,60,658,225,619,864,176,489,436,560,34,243,22,756,978,111,743,945,233,82,193,258,975,307,135,745,805,893,33,646,580,718,766,625,995,93,286,459,403,257,673,408,809,300,71,584,778,883,163,659,954,432,798,751,18,564,267,427,803,213,705,854,471,648,427,314,544,66,276,857,722,58,251,185,952,623,721,585,387,333,560,916,800,761,516,845,864,534,650,774,533,66,761,31,236,316,599,651,352,772,741,269,854,487,646,387,185,743,840,269,838,730,984,0,820,71,615,595,871,917,404,610,181,698,794,213,924,499,125,967,222,858,255,284,569,88,423,611,237,35,622,210,741,204,564,677,514,945,65,949,687,108,926,184,889,458,617,596,812,187,606,992,903,95,511,926,151,854,834,288,732,770,810,400,110,583,777,133,502,752,715,494,435,492,237,25,910,736,420,7,802,145,788,97,965,75,559,886,348,159,836,802,626,146,650,55,593,727,148,623,12,156,518,753,958,489,7,819,31,836,642,499,768,368,703,185,6,457,382,648,954,921,379,818,846,206,469,283,868,424,778,397,240,765,830,865,168,319,311,245,348,548,478,447,813,631,629,412,887,494,408,618,338,246,584,118,258,657,749,259,489,281,991,146,488,931,316,353,28,671,727,58,414,620,238,662,560,955,351,874,344,579,121,26,413,697,723,676,676,169,940,549,907,416,567,207,917,294,18,510,719,424,32,676,256,453,993,230,800,787,209,377,36,241,926,609,579,623,108,322,601,524,854,872,466,579,950,192,405,915,579,282,100,350,543,140,835,205,479,188,614,443,927,19,760,988,217,92,23,432,361,284,668,126,643,716,967,667,655,612,328,936,606,63,386,49,50,238,609,577,521,938,921,982,973,674,483,566,58,973,587,396,111,556,237,403,545,765,649,172,240,569,592,968,955,481,869,375,774,790,620,795,658,941,805,41,425,541,317,893,735,843,603,869,920,884,912,633,308,52,460,894,731,718,738,571,146,182,866,160,748,708,119,14,644,306,99,264,98,973,175,690,968,7,39,906,921,316,227,413,184,799,550,311,491,23,667,469,227,910,128,861,413,907,827,701,733,558,162,729,69,66,516,974,362,937,8,779,312,898,622,594,188,430,158,159,140,681,952,948,953,159,640,244,808,490,673,506,351,565,6,566,142,972,640,876,471,541,876,471,687,680,766,895,896,684,21,936,204,443,53,115,411,771,996,340,423,216,806,29,76,565,37,688,731,361,224,594,290,531,776,370,533,705,772,927,873,963,458,118,122,939,691,613,537,668,841,483,593,639,231,335,796,816,367,324,928,85,950,168,655,416,837,898,187,782,980,724,167,619,44,676,202,484,751,10,508,952,683,633,904,56,675,923,858,599,70,297,961,109,865,569,979,989,347,987,451,955,749,855,450,367,44,934,37,741,518,238,9,355,415,557,264,829,193,78,984,360,442,903,593,967,230,713,620,38,856,809,837,643,660,391,765,762,427,962,32,621,897,973,382,749,290,997,833,448,823,643,321,290,906,919,584,963,247,507,309,365,517,712,520,579,640,258,816,599,488,43,683,296,294,796,774,917,525,781,110,172,753,533,240,939,753,766,979,329,125,618,642,334,718,469,295,381,342,798,750,665,536,433,633,681,56,361,626,478,931,459,276,203,994,316,171,793,203,733,556,517,674,508,170,960,677,314,155,378,189,394,946,339,245,420,590,355,982,961,786,836,451,779,976,16,754,171,865,207,327,348,673,756,458,769,908,226,205,674,473,275,726,684,451,3,310,449,968,245,583,106,439,818,149,825,336,927,168,195,415,340,406,772,751,525,892,938,289,944,342,450,207,355,155,334,915,121,298,599,284,726,984,224,281,495,879,270,810,882,459,557,231,766,469,668,265,818,51,29,920,823,845,373,273,221,518,452,262,825,389,954,180,647,46,987,184,852,805,884,37,470,885,44,587,643,783,500,279,418,716,50,863,239,792,989,158,983,26,721,186,545,222,668,262,471,974,638,571,233,993,63,39,956,767,585,593,404,285,429,795,38,605,347,866,113,333,245,732,283,398,783,33,601,635,210,467,282,960,611,79,161,391,608,708,721,767,765,386,730,686,559,856,457,590,976,183,278,101,64,594,253,938,122,236,608,201,999,297,332,550,785,251,357,739,363,150,694,878,973,144,444,264,337,253,645,711,875,307,933,816,102,392,335,133,381,168,297,915,135,519,640,649,129,400,302,561,55,886,937,925,483,101,665", "66,264,458,839,8,853,6,943,80,778,455,617,506,428,820,471,913,124,121,18,894,653,68,535,960,950,702,661,863,534,523,236,262,42,385,39,780,600,260,396,759,84,88,335,168,65,153,105,87,410,1000,547,72,552,50,245,886,194,157,440,989,56,343,196,365,416,518,186,676,423,670,126,831,131,140,101,122,929,389,106,326,399,413,704,53,171,570,491,43,830,761,841,336,183,323,911,10,466,335,637,745,553,258,824,698,251,718,990,386,128,474,106,30,72,206,533,693,353,142,38,654,890,986,820,0,496,923,457,750,587,494,552,415,281,131,76,601,27,584,308,641,686,563,504,331,570,807,108,902,239,444,302,582,713,297,771,254,358,844,752,708,262,425,661,158,630,313,868,382,594,472,226,718,533,557,27,515,68,455,513,461,431,741,761,283,477,841,235,475,478,700,89,273,595,257,879,181,598,379,927,12,577,718,78,275,950,983,18,246,553,966,612,237,105,639,926,901,480,740,697,18,985,627,934,971,339,672,768,104,388,179,155,437,784,362,384,502,764,762,316,786,982,142,162,41,258,233,468,300,326,208,893,74,815,536,562,452,876,626,853,188,98,924,923,981,187,247,403,408,933,780,706,532,628,48,66,368,982,745,154,512,346,907,120,577,436,806,765,71,100,526,540,50,757,752,410,570,820,61,21,498,766,773,386,514,32,728,4,67,3,743,103,268,132,714,554,48,856,120,422,509,483,843,763,68,957,735,545,153,820,257,769,774,693,41,863,261,57,956,641,892,722,106,878,484,948,594,132,177,832,109,37,312,402,480,696,858,958,559,515,673,422,77,22,541,24,407,226,902,498,628,630,308,365,925,668,643,870,383,745,477,146,754,97,641,751,199,675,491,277,515,94,214,119,648,291,647,308,573,461,904,724,959,608,450,973,7,300,998,959,281,610,348,272,534,918,385,350,618,976,333,303,941,160,418,241,857,877,258,428,626,859,795,681,700,247,108,223,822,943,831,667,915,102,425,756,480,981,522,275,73,861,195,434,911,415,194,24,816,875,145,309,148,292,270,33,744,234,437,184,759,555,573,628,575,237,73,697,42,220,565,397,215,40,270,922,367,737,430,848,486,528,941,739,726,864,271,246,417,315,307,230,783,48,589,844,294,592,540,954,566,163,190,416,860,181,969,588,678,675,95,289,866,686,193,265,763,669,885,859,305,319,553,991,59,544,492,117,665,107,356,833,211,956,472,635,132,579,934,944,689,972,633,84,16,489,808,950,951,429,699,497,36,708,35,323,549,640,730,251,497,208,994,753,689,103,5,247,751,291,602,493,477,586,822,415,29,972,651,150,989,528,967,761,789,174,972,421,165,485,269,114,751,2,625,495,725,870,685,581,553,182,110,565,140,992,566,738,880,213,946,578,343,502,538,578,380,401,244,387,765,771,993,681,37,914,80,1000,548,730,766,940,362,9,20,362,166,652,706,72,362,671,792,499,260,406,589,522,658,407,475,9,338,546,759,519,60,935,312,48,721,329,896,671,324,111,557,341,651,596,693,383,181,735,232,942,23,491,420,269,367,272,596,559,698,737,131,506,71,771,131,890,557,472,196,609,974,582,748,155,710,69,956,972,840,962,325,748,781,244,451,941,329,856,519,694,363,427,356,331,200,710,870,895,473,671,107,449,955,88,837,542,591,504,817,762,188,614,381,377,809,270,503,807,332,933,764,513,926,435,845,373,566,13,522,649,883,686,42,464,98,118,913,598,704,890,924,838,887,766,340,524,542,755,940,142,432,695,733,588,924,827,477,171,625,313,861,832,988,378,617,529,108,254,440,609,624,24,956,526,589,85,554,442,62,14,271,440,548,774,481,91,143,177,271,614,758,844,129,296,107,539,258,570,246,173,908,111,742,309,601,120,379,57,883,346,565,870,283,359,603,844,168,871,819,471,315,315,317,857,369,230,711,779,414,164,650,201,357,378,654,472,712,493,365,910,330,594,329,194,675,336,537,214,748,794,636,698,982,766,931,227,872,528,682,30,669,428,141,699,682,711,488,499,246,741,919,702,518,421,470,708,234,881,500,918,833,939,486,182,187,602,905,915,90,706,280,614,274,41,617,232,608,650,529,832,314,945,660,244,982,824,49,839,34,135,246,810,619,472,428,729,511,393,963,521,16,378,197,327,937,759,501,695,635,215,257,523,907,827,515,372,652,910,373,162,443,23,540,565,673,796,329,104,849,579,267,232,686,593,370,848,260,626,753,959,634,925,383,741", "965,486,382,592,904,878,484,400,446,830,894,643,736,208,705,318,630,794,85,175,637,979,526,434,916,837,658,111,595,286,879,328,485,810,23,94,289,15,577,812,791,406,400,423,764,314,300,226,782,506,519,884,896,167,652,895,204,737,722,155,346,8,492,538,803,123,546,250,250,669,228,476,242,809,718,900,653,995,409,277,65,499,999,221,490,317,928,481,974,101,639,691,635,238,166,475,438,224,626,763,66,423,206,327,452,846,962,579,906,882,423,82,983,499,769,868,517,546,263,42,968,770,109,71,496,0,188,882,148,202,857,516,659,943,349,928,944,876,69,211,210,949,64,127,117,701,289,364,164,257,423,309,899,608,525,462,571,892,909,153,933,50,639,518,299,564,957,511,775,769,915,10,230,810,227,358,5,289,670,590,171,301,885,50,794,639,505,956,980,212,932,628,64,876,270,111,733,58,27,854,781,532,994,727,984,641,953,826,7,391,331,221,908,230,515,100,159,443,207,745,535,747,415,467,186,940,799,234,667,947,154,400,891,664,266,717,631,490,826,423,814,298,115,181,804,149,251,938,92,25,41,897,795,945,919,789,283,484,568,848,446,431,723,812,150,646,673,589,760,248,200,653,690,958,131,404,406,113,327,204,472,847,668,503,992,682,609,349,432,665,649,18,17,68,936,778,164,633,384,851,743,937,263,356,228,668,900,55,757,881,419,422,789,408,344,328,330,577,896,850,774,423,927,644,201,946,436,328,305,627,664,721,855,143,819,720,469,808,673,773,864,90,170,485,241,10,528,735,72,330,87,560,812,345,334,889,831,396,972,211,933,813,530,168,741,646,296,260,160,107,187,707,67,390,265,458,310,384,183,137,670,246,658,663,602,83,120,367,324,686,145,994,336,653,412,376,51,860,410,540,54,172,368,661,634,590,820,453,344,160,646,402,144,950,899,627,91,263,686,893,665,6,261,19,312,428,703,803,666,546,312,490,368,591,577,458,129,598,127,846,977,55,684,687,47,917,450,141,430,365,402,424,288,739,579,517,162,987,559,199,780,582,783,480,951,642,884,626,624,449,690,289,895,707,320,74,646,540,736,645,50,76,155,646,6,976,635,962,787,717,669,308,933,451,212,764,110,350,605,759,927,507,148,706,267,790,189,618,307,644,604,788,3,518,149,799,358,855,765,867,909,557,115,730,559,804,372,650,478,287,547,297,360,491,910,916,439,630,699,99,664,487,88,273,241,692,798,416,604,518,865,193,202,852,883,442,885,823,799,371,442,626,289,286,182,522,209,235,778,281,852,425,980,848,734,323,411,444,11,661,613,411,926,147,987,206,805,698,807,60,545,599,921,469,530,955,616,545,284,10,602,820,894,921,947,510,948,341,886,556,803,882,366,774,164,174,405,663,966,263,263,139,930,200,21,339,87,95,444,84,835,626,155,671,840,963,300,849,943,59,617,863,594,369,319,506,294,383,401,277,265,680,911,913,556,168,348,39,282,647,496,318,225,475,63,840,764,156,783,167,89,749,925,945,75,16,653,622,791,723,949,445,960,34,168,822,231,42,54,163,413,780,77,358,486,486,391,606,420,623,379,735,920,153,587,826,523,404,802,32,685,515,727,656,21,398,613,232,623,56,22,903,231,618,147,499,144,136,842,181,637,35,304,918,890,75,184,728,683,754,512,997,920,96,855,75,962,885,730,812,817,798,290,400,920,589,213,11,384,116,395,210,154,735,758,781,705,3,219,590,102,761,543,474,922,172,702,661,569,179,167,363,402,28,191,864,80,491,888,963,925,683,569,713,843,944,382,205,173,553,112,915,905,688,620,949,980,814,563,888,538,57,99,592,412,519,120,706,217,371,366,237,631,296,665,696,939,769,346,524,225,899,230,83,945,354,918,614,246,959,952,670,501,721,652,643,683,8,838,419,950,247,653,852,388,385,108,250,347,500,550,366,576,937,733,856,95,352,506,152,44,194,131,129,434,992,689,357,460,171,8,214,229,231,510,842,984,163,468,960,395,556,468,606,978,316,509,634,27,803,988,369,672,350,358,623,339,490,99,56,727,959,666,124,451,352,823,984,998,844,653,426,395,614,397,114,319,633,903,721,313,295,922,545,129,506,262,199,497,707,831,553,598,357,538,260,256,448,389,513,330,435,835,65,38,149,124,238,173,192,128,466,796,581,74,537,61,384,577,552,916,707,491,610,437,758,881,625,152,602,195,966,257,16,797,299,379,830,906,41,483,204,569,340,654,779,237,978,292,90", "973,643,466,379,387,812,873,117,572,396,302,832,465,796,884,771,806,684,1000,173,605,263,533,794,283,566,432,486,353,183,350,991,958,306,718,701,988,228,802,944,370,524,867,636,656,731,546,422,754,310,894,164,447,83,776,739,484,680,949,281,859,245,957,556,861,103,563,216,62,994,714,11,905,519,152,104,990,123,570,883,37,384,953,429,554,12,195,95,629,987,63,315,871,600,448,459,780,599,62,547,746,42,455,195,747,960,884,564,612,161,392,916,56,655,275,299,181,274,315,77,431,180,878,615,923,188,0,673,46,622,240,176,919,904,570,481,732,645,523,543,208,104,978,565,903,847,288,641,129,580,47,781,15,577,98,421,229,464,942,612,229,784,319,992,163,242,874,248,193,242,810,247,578,795,214,789,426,946,186,616,651,605,524,796,285,61,44,138,229,636,897,574,794,178,560,574,89,114,629,494,927,823,314,48,746,717,843,604,737,489,96,674,940,979,913,839,631,248,939,220,146,569,936,849,139,252,912,645,449,856,750,801,356,761,487,411,178,897,263,884,954,430,868,237,254,43,150,189,893,676,426,657,997,601,63,523,575,438,445,429,142,421,904,865,54,772,767,38,838,977,328,812,139,108,284,803,469,589,132,675,324,501,152,911,707,567,286,531,833,805,155,117,259,459,624,166,671,3,106,35,88,89,277,97,505,286,480,181,338,469,738,145,356,438,267,811,989,612,888,933,716,996,117,867,822,816,609,67,52,122,839,880,8,707,471,723,174,373,232,666,597,532,152,838,881,875,289,86,521,923,145,599,200,275,743,270,833,58,496,790,483,814,741,216,62,755,918,207,600,616,771,867,307,130,830,441,377,177,765,781,473,167,935,503,953,470,166,316,510,304,549,965,267,684,93,44,432,545,57,228,193,830,48,893,252,76,134,255,463,175,203,816,701,398,728,754,243,52,569,764,81,291,714,24,51,786,496,228,708,50,32,8,157,278,720,377,378,169,859,619,905,214,166,479,61,995,865,166,624,11,334,154,295,45,152,158,1000,671,263,478,452,13,797,876,308,542,672,601,152,853,953,403,63,451,217,897,100,612,810,192,250,290,187,793,505,288,9,975,715,700,268,310,80,209,990,783,598,232,422,96,19,575,829,283,174,214,297,662,712,957,904,936,338,345,238,450,583,647,44,160,165,542,54,138,950,342,838,839,952,925,62,291,539,980,399,433,785,983,208,45,360,742,32,500,474,932,354,20,924,167,813,109,353,120,101,900,430,485,177,430,50,672,636,781,469,858,582,796,869,818,912,803,626,417,156,734,860,305,783,111,929,652,844,922,46,795,248,413,719,114,892,471,107,709,81,906,440,417,595,998,496,275,802,756,213,375,437,699,123,929,821,740,738,237,412,411,752,422,114,361,499,64,541,618,409,159,990,37,780,349,418,173,282,581,412,429,296,373,873,757,911,778,705,173,228,156,931,269,359,303,94,12,853,690,948,870,361,220,400,62,658,732,7,504,330,354,176,811,53,821,447,315,841,980,329,163,986,101,509,167,94,898,237,353,541,985,691,803,480,154,41,841,813,121,619,690,901,327,652,802,69,158,863,929,431,439,953,375,856,790,432,889,51,281,743,272,592,532,266,879,285,431,654,819,984,782,389,319,173,336,383,72,334,657,598,182,997,673,458,50,528,112,945,971,232,75,383,367,754,270,716,294,73,104,631,406,68,196,779,286,228,372,585,288,122,164,826,328,793,66,530,469,491,2,658,737,693,664,156,443,336,143,502,18,13,554,809,237,929,667,920,873,44,535,509,119,143,121,364,288,127,524,810,232,668,878,290,522,224,642,200,230,420,658,570,980,152,314,455,395,123,876,500,985,781,754,419,72,231,493,364,599,83,298,536,212,25,415,167,412,151,726,601,425,252,988,139,718,638,308,339,919,929,868,245,746,988,747,806,520,37,820,219,823,53,654,502,832,453,158,593,726,822,117,496,706,29,418,104,882,82,550,90,436,94,545,914,982,537,240,773,125,281,790,906,793,440,167,866,596,279,683,281,80,14,739,47,296,530,298,928,304,156,3,22,536,228,983,937,497,853,387,686,629,675,859,236,252,509,164,9,389,166,645,219,325,868,662,259,500,747,852,666,121,304,697,918,255,797,750,387,244,577,387,423,183,613,567,893,103,761,867,654,709,925,576,414,42,983,842,505,666,965,105,105,976,287,725,662,155,501,530,722,598,424,159,829,45,937,957,302,39,794,441,613,101,730,311,366,735", "950,437,65,950,965,337,206,683,19,406,697,489,73,654,841,14,788,376,477,602,184,732,934,929,517,659,64,209,53,396,895,407,683,720,503,698,740,458,76,339,965,90,422,969,54,612,78,140,184,232,195,152,560,102,781,641,677,289,623,849,269,347,707,593,240,955,401,397,252,947,442,181,866,209,763,888,302,185,620,39,686,883,372,307,460,502,712,255,652,999,46,676,241,919,137,487,2,96,874,976,527,539,809,171,342,979,850,710,573,345,501,476,244,605,364,377,863,952,93,513,402,605,308,595,457,882,673,0,668,449,456,198,853,327,505,808,227,164,468,273,931,342,625,285,616,668,9,595,209,470,701,915,234,747,74,649,839,414,913,814,331,518,162,931,854,853,7,661,6,199,269,628,269,174,481,429,962,549,821,916,309,857,341,305,937,231,948,276,84,161,309,620,94,129,725,161,419,210,787,753,609,681,691,199,186,220,466,544,242,256,709,220,676,416,905,47,62,72,838,724,743,434,930,355,584,553,277,95,738,828,322,977,552,285,495,815,987,586,606,751,635,115,822,915,791,984,713,469,72,269,740,611,588,724,19,798,251,641,219,170,17,130,467,797,497,909,70,262,139,976,767,833,744,778,894,496,870,393,826,324,824,623,666,18,393,100,459,198,103,620,765,891,799,419,456,566,602,664,334,611,82,450,583,312,497,719,602,462,480,714,767,135,596,23,109,255,2,893,113,294,500,967,640,867,470,101,439,947,604,27,998,356,941,129,14,259,68,444,656,241,829,919,679,382,34,904,934,332,117,275,837,249,534,51,109,208,572,454,298,576,293,413,492,500,210,762,782,460,67,485,337,977,426,442,385,5,833,834,119,102,408,124,28,948,601,158,711,382,853,802,259,433,368,478,287,933,109,450,438,636,159,461,554,703,813,819,533,670,716,145,467,406,927,889,641,230,817,355,110,901,871,193,346,5,716,856,107,55,83,941,344,438,148,59,282,366,130,983,906,182,799,729,15,880,650,106,396,179,185,829,126,708,437,397,151,151,664,847,220,96,913,267,949,9,59,790,482,193,104,72,456,796,152,872,712,280,685,194,911,418,699,535,309,36,536,250,77,521,263,85,671,458,949,945,914,219,662,274,340,851,18,429,950,26,533,295,712,527,559,138,636,768,508,642,760,60,194,912,135,104,662,613,935,793,21,563,325,996,38,413,15,624,788,598,58,971,50,792,942,463,700,945,987,628,324,7,202,63,457,173,563,939,459,561,263,155,803,338,715,10,627,771,11,846,377,235,501,689,16,522,249,10,902,172,836,874,613,273,662,38,950,168,942,329,340,321,47,513,15,673,216,767,293,64,212,27,312,260,348,978,944,718,599,779,334,330,272,513,651,251,605,282,781,960,181,978,129,435,568,436,886,958,60,268,304,560,202,532,151,97,962,539,320,866,673,346,43,488,115,177,896,598,196,902,719,261,642,580,52,168,762,807,362,103,442,547,47,543,472,423,492,298,610,429,122,463,360,749,887,910,33,314,927,404,873,4,905,965,945,401,336,229,337,181,259,329,65,59,977,728,334,58,123,883,409,847,462,343,453,128,892,19,483,718,470,60,936,414,543,509,898,70,284,345,395,280,923,901,339,323,338,875,972,736,974,41,757,275,761,884,136,473,427,620,340,565,815,502,325,113,387,342,519,460,481,30,2,151,89,929,597,86,449,455,274,26,399,785,303,182,703,99,131,784,332,108,62,140,467,883,161,222,902,574,83,332,834,427,241,222,513,559,871,351,526,430,562,615,713,364,856,981,778,115,407,145,690,759,892,559,916,469,101,875,253,952,444,327,407,669,313,361,954,706,429,680,88,124,467,498,629,183,809,270,699,60,478,17,874,33,73,689,25,973,168,127,199,193,729,365,651,220,6,487,63,909,720,222,224,944,143,247,432,457,700,147,412,682,466,548,622,947,302,419,24,299,641,922,733,714,175,327,806,662,63,68,119,367,143,861,915,367,73,162,316,782,534,509,743,631,993,207,843,440,536,473,120,925,720,684,486,691,627,239,899,353,138,475,96,694,691,354,874,542,609,180,777,100,192,909,105,674,266,635,745,189,555,259,151,389,965,126,911,560,326,862,457,109,728,866,578,361,458,794,872,69,428,856,393,479,865,61,589,989,170,153,523,544,233,761,35,227,464,788,717,273,591,159,810,220,4,835,965,514,268,590,220,938,279,994,304,11,72,963,609,633,669,884,607,139,171,54,619,833,919,215,135,473,712,233", "952,828,16,990,540,210,860,948,331,618,499,455,739,70,302,724,267,808,79,66,616,864,201,188,545,23,251,496,908,404,550,19,395,862,671,464,714,223,176,6,916,82,458,945,18,946,996,800,906,569,648,363,117,234,804,503,123,655,425,927,978,926,194,310,133,907,291,365,832,977,13,115,736,440,75,790,450,976,522,510,906,551,757,677,187,355,471,202,105,79,981,17,462,682,130,885,571,830,638,338,775,797,448,986,375,189,403,252,908,527,610,556,560,493,912,929,170,546,953,358,678,699,384,871,750,148,46,668,0,158,337,173,601,624,124,539,513,133,320,77,748,916,520,56,465,905,124,842,97,221,369,151,316,4,371,616,765,236,376,559,115,508,925,135,774,885,266,644,648,299,977,805,454,553,243,671,25,892,862,757,817,629,932,248,62,206,265,800,233,996,765,140,301,90,950,246,88,112,836,883,128,709,699,787,244,92,41,624,536,359,244,440,893,562,857,708,20,459,290,153,642,533,223,951,795,464,817,345,25,952,894,295,811,662,333,819,76,543,95,741,844,845,163,123,662,448,457,439,226,188,267,339,227,379,18,232,886,940,814,433,847,225,812,896,353,881,755,482,483,278,273,350,180,311,206,536,765,181,371,820,961,168,770,571,204,707,396,146,26,364,546,642,291,590,629,390,77,452,656,267,572,682,262,48,839,288,920,536,284,107,757,582,115,661,638,924,591,432,629,277,237,590,181,948,603,851,57,547,866,492,990,591,371,230,768,399,212,319,369,934,954,859,948,371,824,922,527,382,218,401,425,751,953,673,36,659,30,779,357,104,930,278,246,200,423,413,681,583,689,18,776,176,891,664,449,782,193,741,251,655,345,52,102,881,606,344,901,741,297,778,555,822,246,9,970,446,614,778,750,503,87,246,467,242,644,543,686,341,480,983,51,840,628,956,845,510,257,915,22,640,255,279,749,248,712,90,711,514,174,237,259,774,923,38,687,25,213,619,652,701,973,126,714,995,54,328,815,6,714,851,382,266,430,221,737,75,942,398,658,993,261,388,579,798,557,934,73,26,937,38,9,214,360,55,443,801,558,875,702,483,716,350,684,800,370,348,601,219,386,393,12,196,542,655,503,84,657,634,731,675,547,568,260,171,12,72,967,935,788,528,755,724,274,677,49,859,516,611,758,604,836,811,601,728,954,606,121,412,375,629,82,782,533,97,708,32,345,758,697,310,686,746,361,98,139,85,527,655,212,160,609,227,889,541,657,678,316,413,501,282,660,566,942,864,868,834,272,211,152,945,402,102,221,249,477,659,415,82,455,48,217,531,962,403,650,689,685,475,287,662,171,421,899,474,633,373,545,317,994,484,554,12,821,651,569,288,262,255,577,550,387,795,970,189,512,739,747,352,721,459,8,413,372,292,90,180,969,677,371,973,636,421,385,188,501,104,531,979,111,319,115,379,833,754,910,500,621,228,615,175,204,176,914,377,727,628,952,507,3,404,461,55,72,836,946,939,732,367,151,456,375,600,701,829,63,901,856,244,831,65,761,750,802,239,772,913,279,605,718,768,999,483,875,569,664,260,387,552,293,501,306,681,738,956,978,451,697,617,898,495,584,258,664,292,389,358,766,742,189,345,20,207,67,894,633,735,494,150,383,588,359,776,814,947,747,148,996,665,398,276,287,270,173,881,908,165,876,283,421,216,541,95,575,113,309,902,995,124,891,223,426,600,989,205,804,491,193,48,466,11,977,82,458,253,240,935,966,316,675,643,949,48,307,853,171,397,141,609,730,617,222,135,569,240,560,662,366,54,290,912,997,101,84,359,991,576,341,971,534,876,72,517,84,272,824,947,879,477,548,548,604,746,515,489,629,129,519,562,441,954,962,632,86,311,674,682,426,916,194,919,329,877,652,133,612,181,654,943,527,833,31,698,273,655,689,635,313,560,519,677,374,519,703,416,119,176,954,728,498,338,122,475,25,559,387,342,432,883,842,74,450,79,312,629,306,262,415,22,763,529,356,517,944,718,162,310,978,829,671,323,909,99,458,896,572,665,713,119,436,421,976,411,258,663,880,813,68,706,555,591,136,950,456,920,685,499,637,562,962,836,142,870,476,165,401,854,908,158,309,258,800,554,214,856,918,247,531,960,258,688,967,316,77,774,655,396,604,148,766,484,180,928,81,958,476,584,326,311,100,945,384,611,418,448,107,75,149,43,961,288,202,866,86,585,7,16,155,649,107,687,377,412,67,64,959,49,509,959,313,103", "492,729,85,980,463,805,36,673,830,552,126,24,56,363,64,71,26,848,861,193,844,214,466,760,291,679,741,426,645,986,279,514,507,97,562,121,88,735,417,665,684,832,686,865,108,72,117,934,604,213,694,644,172,572,494,469,15,466,479,539,470,80,475,321,74,745,993,393,979,485,590,749,810,874,227,456,827,19,321,238,973,601,982,593,840,690,697,438,532,324,298,830,731,254,777,690,268,866,383,595,389,358,598,36,839,62,279,37,36,975,286,793,164,691,771,278,443,371,535,508,605,195,926,917,587,202,622,449,158,0,13,146,288,260,842,352,144,636,590,893,654,669,967,99,851,342,578,178,628,81,484,353,972,451,695,557,250,962,228,222,161,115,812,288,467,414,65,815,470,739,834,894,627,929,588,74,559,881,227,739,163,849,609,825,343,733,585,489,916,101,344,899,159,210,976,482,574,233,865,149,330,257,659,510,262,222,203,594,96,776,100,405,397,861,480,342,41,177,995,42,676,68,413,856,814,522,745,835,394,416,986,685,753,828,375,991,153,776,972,424,512,247,642,277,341,116,24,789,240,963,319,273,560,942,502,181,568,189,5,815,430,192,224,182,617,204,10,560,885,758,833,848,774,885,15,76,630,92,963,850,356,100,939,506,699,426,304,167,907,213,650,23,969,757,330,434,596,830,389,173,27,482,394,684,363,875,835,326,113,855,840,692,2,844,299,640,532,834,296,54,106,906,899,434,429,521,374,810,474,239,226,574,463,892,844,743,251,927,592,660,883,560,115,926,943,748,925,922,508,26,413,389,867,12,536,561,29,266,605,656,941,842,751,264,500,820,106,325,959,9,706,432,16,583,795,827,575,561,351,467,5,121,477,355,635,540,326,340,865,809,530,480,743,490,383,600,447,984,604,129,717,243,695,14,889,392,804,663,795,156,877,675,777,649,98,460,418,305,83,686,238,647,679,664,226,869,839,159,419,585,812,525,221,141,186,230,288,304,784,751,322,810,679,27,952,368,336,764,768,66,413,191,501,390,757,132,895,914,941,130,737,123,112,648,629,817,191,458,378,110,98,255,452,744,364,153,598,93,353,184,677,397,845,891,581,169,647,646,173,238,282,331,740,310,22,453,826,35,51,583,32,622,684,155,372,699,42,150,795,556,206,935,317,879,935,640,188,44,49,205,113,266,957,63,32,444,928,17,286,845,980,788,239,325,134,331,702,144,198,134,410,690,104,641,533,354,46,614,81,756,254,208,771,44,949,532,235,228,700,853,721,698,468,150,477,19,249,730,734,744,271,266,754,568,121,896,435,121,446,283,833,599,448,273,375,343,233,807,317,33,350,90,222,731,265,900,852,140,937,842,629,826,151,642,940,479,912,801,444,838,779,829,721,678,897,631,60,217,823,253,716,519,178,180,325,388,33,915,359,793,899,204,398,222,306,948,229,81,753,61,423,401,748,43,194,389,530,702,28,90,330,537,285,570,783,119,546,547,758,844,547,604,470,274,434,967,744,86,155,783,635,111,847,386,12,186,646,183,190,888,784,38,696,303,940,513,589,791,681,916,154,955,308,751,192,834,282,622,993,967,152,14,919,184,165,303,521,170,617,175,500,93,67,405,603,417,49,692,140,75,403,878,950,555,399,466,699,532,859,991,474,893,819,203,844,40,661,114,444,321,898,1000,544,234,131,478,119,524,600,584,94,639,354,161,657,16,933,899,426,958,349,358,512,40,984,652,673,785,572,696,49,993,531,925,570,679,632,384,338,606,809,519,69,844,778,672,316,729,634,901,807,42,139,715,788,380,857,781,455,853,316,812,695,515,122,179,757,338,241,494,342,349,476,584,156,446,142,798,667,830,286,430,725,920,767,369,790,633,270,589,496,195,306,989,881,242,271,361,459,946,963,503,985,429,19,916,974,929,497,333,97,982,319,493,424,75,988,905,594,808,774,720,247,3,813,137,908,652,699,714,393,757,701,44,554,534,962,330,402,598,115,208,561,16,870,614,174,417,882,623,853,925,767,467,415,232,799,720,279,478,58,960,142,942,59,451,708,329,589,303,688,53,771,168,482,622,510,892,792,999,206,740,125,366,571,763,252,582,192,521,935,929,725,154,119,136,520,731,300,746,382,572,965,68,622,372,940,760,365,392,369,679,193,84,399,708,332,958,785,738,255,485,687,6,559,597,366,356,866,726,577,185,996,570,951,555,475,182,156,912,408,187,638,531,31,768,885,871,753,345,638,586,856,892,307,487,612,530,805,641", "624,571,21,716,362,262,171,784,440,777,746,754,52,657,47,932,608,527,968,368,769,950,52,676,856,344,105,686,710,517,448,730,85,952,45,611,928,211,725,240,499,16,588,187,515,363,304,827,751,115,439,879,75,23,628,160,6,716,669,547,738,734,680,361,51,929,535,108,322,883,889,811,667,521,912,590,832,405,197,516,31,706,354,506,849,561,55,433,479,44,463,722,636,11,403,564,41,233,431,170,528,469,238,744,784,819,379,835,801,659,866,697,300,106,859,591,486,160,498,510,56,299,192,404,494,857,240,456,337,13,0,980,246,430,524,61,345,710,992,762,667,181,65,117,239,768,964,297,649,838,340,572,122,939,84,232,807,368,162,602,512,336,37,422,585,896,410,562,153,696,205,341,827,15,690,698,189,419,65,210,704,677,102,655,909,187,128,438,255,569,929,928,93,965,543,262,587,331,814,365,607,110,80,271,182,723,845,635,62,25,853,997,710,73,114,701,779,360,149,839,613,298,386,425,369,67,475,739,794,330,627,49,173,780,726,654,688,157,969,150,833,804,556,851,202,709,521,639,866,556,616,835,70,282,609,988,44,207,201,126,519,874,116,947,78,999,367,985,733,432,102,170,303,36,899,328,633,374,427,89,686,224,315,215,944,269,818,384,19,179,236,750,938,102,569,304,185,31,290,275,260,345,906,368,983,784,629,318,937,976,449,649,605,110,869,369,513,591,290,889,640,512,759,946,211,92,329,216,148,886,862,87,353,456,599,621,220,705,161,403,782,238,178,950,610,144,797,980,384,406,470,299,115,857,770,758,31,511,775,152,294,219,579,872,981,91,27,899,923,118,87,259,355,824,994,360,235,997,824,377,65,374,755,486,731,213,511,522,913,118,966,138,573,246,747,504,899,164,270,241,100,624,296,307,942,106,552,513,753,910,100,810,584,987,885,88,87,301,479,818,78,551,978,318,435,401,959,535,129,419,640,80,981,810,665,215,330,457,86,609,549,491,677,271,725,937,279,709,55,377,416,738,345,919,390,37,929,26,209,229,435,292,50,929,694,418,11,664,699,651,805,720,787,846,279,82,595,197,688,766,864,294,946,436,978,503,223,504,819,202,376,285,136,880,145,703,518,1,74,5,150,343,234,613,964,819,528,376,584,387,444,56,593,216,660,890,845,605,513,915,4,308,916,787,246,976,2,201,359,259,961,378,436,836,247,461,580,455,59,116,864,138,275,159,325,705,594,698,364,385,142,799,349,263,457,827,501,48,501,221,383,581,853,197,872,395,653,838,806,190,322,406,169,578,346,343,340,503,348,672,64,296,818,340,961,630,547,922,725,722,966,92,329,545,239,46,775,774,998,238,822,943,602,500,821,493,245,263,462,471,971,295,335,548,779,920,11,467,262,170,23,26,302,821,142,792,284,510,447,903,928,790,918,761,376,592,325,967,856,778,616,172,421,900,48,691,903,219,498,334,213,921,628,592,257,739,781,226,508,460,849,933,234,326,922,588,666,228,433,905,357,1,927,724,960,281,280,834,644,24,417,48,455,407,221,419,74,547,921,391,939,326,640,736,453,976,941,406,814,290,186,171,282,617,833,810,215,481,369,104,59,924,823,601,491,405,246,320,156,301,55,583,6,480,563,288,773,862,160,369,364,851,269,254,549,744,438,948,986,979,505,609,930,427,841,472,442,168,835,43,316,859,520,150,838,92,37,805,314,592,734,357,610,339,410,284,624,904,85,263,644,792,478,832,981,799,305,6,671,860,655,991,774,695,889,180,362,230,239,831,809,572,344,771,297,951,381,377,215,361,852,892,389,477,494,304,781,757,432,442,134,296,320,501,983,304,768,551,856,450,664,99,785,748,3,725,483,555,347,176,90,584,973,840,701,913,260,761,907,404,968,382,461,498,780,570,97,788,421,136,329,839,468,645,945,473,244,895,746,660,941,446,867,997,263,512,468,588,808,835,435,233,308,984,854,791,496,76,662,137,637,882,520,968,425,482,616,713,248,858,318,712,411,829,432,801,748,814,684,150,394,994,268,530,980,268,194,158,411,343,272,459,693,808,400,956,685,239,189,885,759,995,410,907,90,891,947,349,516,562,598,90,689,233,610,593,913,125,688,784,957,296,952,951,140,721,340,341,889,855,881,418,741,772,765,990,293,548,758,667,390,481,679,100,435,144,643,552,487,235,89,816,178,241,569,570,635,691,861,879,23,603,111,444,509,867,951,635,511,950,564,14,632,230,533,296,86,404,495,808", "810,950,223,332,112,360,814,636,585,542,585,444,258,29,376,259,719,102,54,223,503,763,814,505,770,654,54,140,241,112,194,871,477,543,712,694,493,401,730,906,760,679,502,890,153,993,54,590,336,760,448,307,350,285,856,448,986,767,902,255,815,78,990,985,872,297,876,219,16,825,931,482,822,937,275,945,159,169,755,839,31,37,706,372,356,125,926,642,197,38,24,918,777,112,14,841,91,594,294,57,165,925,507,724,641,128,730,334,153,568,775,565,750,661,85,566,90,283,515,497,110,301,425,610,552,516,176,198,173,146,980,0,600,714,530,944,641,687,502,725,140,31,842,557,928,211,112,379,169,714,459,803,919,840,240,945,894,972,668,579,28,233,889,151,412,207,470,216,105,31,972,755,823,82,34,816,536,896,395,844,955,154,42,432,318,759,240,411,132,197,821,255,172,736,192,145,212,796,457,336,772,678,620,556,50,621,883,595,816,396,176,935,993,138,880,613,331,197,582,798,165,737,607,778,686,730,972,719,258,10,893,417,136,841,505,397,918,270,381,425,63,217,260,838,925,923,439,435,538,72,858,379,461,351,522,905,719,967,773,821,839,598,144,981,425,815,93,740,297,876,608,160,331,971,657,247,362,889,416,393,742,356,256,351,921,965,100,769,969,71,373,696,632,825,163,163,204,398,325,105,187,905,432,713,488,793,611,173,336,380,542,147,33,417,886,997,556,209,322,363,986,466,729,953,596,269,45,656,590,192,464,39,175,809,836,296,490,434,426,687,142,270,651,975,148,420,749,572,845,34,492,550,950,355,944,554,92,687,907,249,468,363,592,983,378,552,460,25,349,405,448,824,806,261,326,87,18,263,270,946,233,749,829,474,297,320,339,59,467,260,328,937,201,355,725,724,870,880,555,180,759,202,762,441,855,389,867,874,349,923,405,808,660,21,185,805,755,12,909,630,209,631,791,326,187,532,900,631,965,578,188,341,315,65,606,811,290,561,450,222,595,14,364,837,118,634,860,321,250,454,766,478,932,617,264,477,277,692,254,256,249,682,654,106,515,380,12,395,984,323,850,479,847,621,865,688,145,148,35,406,806,409,842,177,18,151,730,243,189,437,27,141,763,988,420,171,438,763,239,706,52,295,248,872,281,426,174,201,952,703,137,95,810,694,739,127,845,995,727,48,498,609,365,615,327,133,463,632,129,603,25,415,3,514,724,931,920,436,751,294,418,417,280,779,336,330,567,499,880,293,384,456,740,838,45,457,964,908,95,815,670,661,460,907,993,798,145,601,353,327,132,529,990,717,985,730,189,189,226,666,440,850,439,996,868,127,296,753,334,462,40,239,928,751,562,536,329,619,743,312,981,642,676,457,443,95,107,438,545,521,905,675,32,91,248,283,423,52,873,723,208,712,274,886,67,962,105,634,690,417,863,135,577,442,773,305,562,72,643,599,461,157,960,19,318,926,902,574,196,193,75,896,702,323,885,621,642,513,520,624,860,272,691,760,445,114,740,763,758,413,280,603,478,997,856,479,827,441,370,322,125,752,415,349,583,689,774,952,286,799,42,561,562,775,899,735,146,566,637,348,694,848,926,909,119,590,203,6,213,624,690,547,455,284,494,71,833,336,11,679,870,86,877,328,181,504,548,99,490,157,918,442,688,224,569,107,48,17,196,943,188,140,447,72,485,919,888,20,695,550,833,981,444,92,846,889,377,507,842,629,569,888,163,31,745,107,505,874,543,314,894,612,203,825,360,21,785,433,38,163,656,378,110,264,288,167,813,494,391,7,53,726,150,287,354,595,102,488,576,837,738,369,552,844,970,705,319,608,4,891,951,853,577,516,267,647,292,89,106,484,381,160,737,847,154,282,531,442,278,745,144,782,741,274,64,976,221,770,188,498,924,53,997,727,561,264,60,837,438,528,785,99,989,488,142,629,410,320,849,863,419,771,958,648,795,725,639,605,465,157,934,739,599,325,625,499,951,419,402,402,857,787,479,926,474,621,98,570,482,395,711,844,785,36,855,679,725,264,123,509,656,495,637,626,154,66,673,52,934,269,721,631,193,358,650,421,425,517,433,945,240,695,258,698,805,335,734,500,619,812,449,592,909,881,197,522,492,370,747,537,390,784,869,656,727,354,776,326,604,590,98,975,317,769,418,161,466,685,907,691,869,389,514,632,17,101,333,866,372,153,246,105,657,852,64,980,649,792,987,363,414,307,644,491,850,149,43,75,695,758,487,849,515,316,462,629,269,970,936,457", "87,71,921,189,154,209,737,61,514,287,828,321,590,630,399,356,532,939,330,775,763,61,48,949,160,850,36,549,28,147,89,415,188,915,745,872,668,958,148,994,120,527,536,794,743,738,884,63,486,311,916,114,945,771,664,214,741,50,277,419,818,553,450,620,617,902,294,223,276,487,338,754,176,629,435,588,293,775,263,783,337,152,492,403,270,990,110,501,101,56,374,683,63,965,450,910,828,573,921,361,771,916,77,58,273,884,69,186,136,952,636,822,374,357,364,756,660,630,813,482,64,38,187,181,415,659,919,853,601,288,246,600,0,929,65,734,786,629,769,732,319,334,464,874,977,491,832,411,961,574,551,988,255,101,56,869,938,696,444,266,186,442,479,586,989,718,967,764,277,836,310,892,114,40,554,443,73,770,487,105,485,414,103,583,511,333,415,582,397,900,625,73,745,713,983,661,754,70,779,713,545,723,381,968,965,409,564,135,849,899,191,776,805,715,19,968,92,607,937,231,291,221,963,334,981,612,994,292,630,321,656,861,284,131,282,384,904,627,644,1000,124,841,668,586,10,282,582,151,489,702,304,182,584,173,548,819,781,592,997,311,332,226,29,872,334,118,451,5,265,19,618,673,518,107,440,492,784,73,494,77,492,979,723,409,598,512,238,926,81,686,513,490,309,142,235,146,752,224,630,2,847,46,116,718,779,656,547,929,956,902,420,852,337,793,271,289,380,600,824,758,976,25,717,204,960,329,366,509,124,317,528,604,745,379,199,286,692,588,469,273,634,919,726,12,57,144,809,849,802,621,868,399,359,698,346,155,847,509,911,297,845,667,122,575,84,149,852,163,906,666,564,175,846,906,96,426,632,459,955,83,139,341,980,411,782,368,862,979,104,685,615,458,895,623,468,531,565,332,764,798,256,181,854,490,258,15,142,840,974,211,782,135,367,637,167,743,821,195,94,966,289,265,269,698,725,579,635,670,640,844,309,879,267,979,247,122,842,141,361,155,275,195,686,532,407,994,699,576,978,104,222,624,261,126,684,913,343,865,687,995,559,850,881,127,350,495,808,762,661,177,241,963,480,211,820,9,419,167,649,720,385,409,541,163,628,435,794,472,511,664,671,127,209,709,313,833,355,927,560,691,493,374,716,757,117,614,723,481,619,823,280,269,809,840,241,115,52,162,846,71,152,375,903,166,684,874,906,673,845,325,939,567,895,12,780,232,117,332,209,815,573,799,302,323,528,985,453,997,104,345,274,134,665,136,17,975,536,938,456,634,409,480,619,593,727,875,990,764,748,431,129,929,399,885,91,789,162,538,782,350,799,463,163,298,262,950,731,56,545,789,592,448,354,324,984,365,640,150,395,712,116,572,127,384,636,275,369,748,580,52,891,614,571,185,551,802,58,219,589,118,217,181,187,257,966,693,46,484,429,641,278,496,351,108,904,178,758,279,700,416,607,867,649,474,444,644,608,281,874,926,323,376,964,860,260,960,182,850,376,283,517,93,598,298,467,729,382,204,12,817,712,439,28,584,743,741,708,678,323,480,948,346,639,223,482,387,161,720,170,478,724,7,609,591,495,940,154,113,551,744,92,344,390,981,198,76,513,451,309,565,246,447,844,306,417,764,773,971,196,546,254,34,713,610,262,271,79,150,512,997,831,290,17,475,502,357,64,28,25,734,844,272,763,376,698,678,543,726,392,865,775,535,323,67,631,436,221,121,563,221,415,667,834,204,771,138,950,192,88,968,325,481,620,876,877,686,335,531,365,931,770,974,929,976,348,831,531,328,807,629,848,233,647,496,425,871,361,516,671,987,1000,118,565,435,574,603,771,197,104,769,786,262,259,947,785,614,11,978,375,213,64,194,786,764,891,778,593,406,689,845,572,775,241,72,703,128,736,508,336,775,936,99,537,335,100,980,205,9,7,88,817,1,294,30,355,706,947,687,781,650,522,669,275,858,389,22,622,360,181,380,551,55,536,354,978,799,523,150,479,376,650,816,140,43,558,386,522,288,207,368,285,928,692,582,760,189,600,167,769,943,827,862,923,786,628,987,24,860,327,923,484,197,425,502,620,742,522,238,926,629,938,157,930,34,595,454,897,746,563,433,4,836,125,989,652,800,746,952,11,634,793,283,485,879,454,759,122,933,513,577,292,239,781,884,849,816,345,592,149,468,534,408,279,704,690,112,767,675,82,415,239,429,794,591,720,423,509,740,313,122,710,608,72,156,965,656,302,663,367,865,495,576,275,607,902,172,794,237,516,944", "62,908,353,908,430,461,834,936,601,627,929,709,651,903,926,383,365,359,872,357,630,276,463,981,811,491,969,197,681,874,391,631,455,349,470,815,600,285,393,598,584,474,635,538,974,322,808,814,51,452,436,915,334,529,315,846,529,353,866,187,264,238,338,479,317,920,254,446,681,612,940,512,375,871,18,303,198,772,396,605,138,79,409,115,386,936,169,295,126,473,567,610,918,294,143,522,811,102,770,675,138,277,449,575,962,245,411,994,972,706,440,782,201,336,783,79,840,698,481,390,492,756,55,698,281,943,904,327,624,260,430,714,929,0,215,503,244,422,354,230,943,706,431,135,997,814,814,108,402,165,866,195,798,151,541,445,495,661,298,921,606,537,555,880,356,528,99,312,18,554,874,720,557,159,733,101,497,965,900,910,777,879,277,924,29,593,849,183,295,23,87,354,201,487,189,937,636,89,515,356,641,587,831,309,567,495,298,838,507,57,736,546,787,330,438,982,632,23,353,248,775,785,754,593,612,21,852,22,562,862,64,276,824,313,740,314,156,856,486,181,979,352,106,512,264,706,235,238,69,702,474,923,176,474,637,738,425,317,178,349,349,835,84,745,379,336,933,541,799,272,979,404,431,438,162,754,116,269,167,814,465,329,981,266,596,657,214,411,444,931,660,19,615,735,101,128,742,570,593,982,889,647,278,147,473,47,54,945,871,710,518,867,568,519,457,532,737,144,907,120,192,510,211,731,368,413,303,70,591,72,746,171,655,980,539,918,490,680,781,604,823,884,438,862,934,682,702,393,653,365,719,777,157,898,217,346,381,926,776,973,207,782,814,960,383,86,897,564,754,352,203,331,128,585,719,771,539,994,304,960,287,147,367,37,658,207,230,108,976,725,775,893,339,734,799,719,213,367,50,576,896,360,983,373,94,197,337,566,644,470,741,362,731,498,966,594,391,450,799,959,976,239,638,494,704,269,180,370,620,824,157,950,345,225,855,440,315,232,40,822,385,513,2,528,609,954,983,880,610,66,251,188,467,885,795,260,729,899,769,904,486,733,648,367,881,400,498,59,189,700,914,217,544,869,215,522,428,877,175,298,281,522,19,11,551,860,345,305,110,889,854,771,516,232,739,776,188,212,153,434,542,642,816,303,457,280,580,593,879,771,323,439,695,664,656,103,617,752,223,979,953,952,25,435,464,572,820,478,45,80,631,365,231,924,498,392,581,277,360,99,548,49,265,221,557,199,105,131,422,564,290,527,923,684,9,286,873,23,963,367,240,894,272,215,46,206,860,96,570,477,898,439,332,40,750,417,756,49,622,876,991,231,367,513,58,497,478,427,331,575,100,558,143,988,48,813,978,150,199,830,474,446,598,687,972,864,889,970,459,856,707,539,404,15,43,994,296,204,11,342,83,753,191,737,282,36,360,273,705,829,989,968,771,179,775,599,272,336,781,313,789,205,135,692,213,105,372,626,478,535,156,972,286,919,962,309,825,821,114,7,71,809,29,207,470,306,676,344,489,259,819,986,831,362,562,756,784,445,242,722,218,642,588,6,497,781,261,641,589,728,361,311,942,257,994,577,363,584,777,327,962,962,179,398,234,236,10,245,416,141,579,778,860,716,787,770,747,378,696,505,553,808,688,479,193,589,540,802,941,364,761,130,287,357,432,840,569,630,337,928,509,888,736,63,905,323,224,365,214,878,476,844,771,973,276,898,658,107,394,914,944,319,689,329,450,483,638,304,518,484,69,568,874,893,23,376,848,298,92,808,447,83,662,752,199,998,705,281,854,787,147,627,452,832,158,318,492,315,697,701,659,955,345,946,626,642,768,621,94,166,978,416,501,738,162,207,12,984,806,424,578,937,774,649,790,455,512,920,828,619,366,645,957,745,274,594,505,803,224,916,597,884,46,327,973,231,719,544,856,369,766,306,366,483,463,721,150,204,740,662,132,567,646,708,592,785,476,787,698,269,69,778,362,535,359,798,848,995,170,157,959,146,411,119,519,695,635,692,282,314,114,408,347,766,567,444,924,580,582,702,813,98,725,213,789,978,437,107,468,711,884,681,377,587,192,119,874,76,864,295,234,586,207,494,714,624,656,32,442,79,419,325,584,696,23,124,570,600,549,97,79,736,217,978,24,326,370,849,14,865,471,933,521,610,894,22,672,625,167,296,186,370,133,706,123,765,431,830,804,390,516,752,18,350,926,98,196,566,146,284,449,13,235,999,927,145,304,414,906,409,180,444,686,422,157,185,684,456,674,853", "218,63,134,819,25,756,185,794,150,859,102,110,441,90,732,296,687,344,148,305,380,848,97,609,270,870,972,736,337,64,527,167,579,328,95,948,672,322,776,714,852,46,927,57,670,149,617,438,707,267,870,520,738,386,163,391,421,158,356,494,490,860,374,283,385,694,691,794,575,593,575,371,282,504,184,588,685,741,747,77,638,574,245,408,380,689,628,217,989,966,135,298,841,586,61,432,144,621,42,483,303,836,669,292,571,504,554,877,815,307,51,267,798,702,580,577,405,5,538,911,615,516,993,794,131,349,570,505,124,842,524,530,65,215,0,931,351,515,330,549,44,913,645,370,954,741,328,342,958,951,631,134,278,865,556,728,408,493,205,690,960,84,491,751,766,855,468,555,954,703,598,30,179,880,804,293,659,713,555,521,314,580,812,375,901,153,980,103,440,206,570,687,396,412,164,175,246,581,642,219,718,519,596,223,894,34,398,747,816,679,222,116,297,538,689,649,112,238,501,726,810,212,396,531,824,532,354,818,191,423,667,460,147,165,550,41,994,986,793,555,929,290,631,259,935,998,102,53,806,880,970,912,868,152,276,849,599,158,618,150,483,587,950,614,173,297,866,816,880,210,314,268,511,321,407,390,558,221,785,219,426,663,928,410,523,686,443,23,500,707,549,194,125,623,67,820,324,793,523,928,505,879,566,28,850,764,656,778,419,899,378,261,335,396,984,143,348,264,373,291,166,367,687,355,246,140,340,337,157,576,59,522,252,562,610,820,656,897,424,796,699,529,371,807,417,861,764,209,831,117,921,33,137,613,706,584,111,575,421,605,198,207,189,518,89,93,232,66,949,534,110,345,771,326,155,62,579,243,550,744,57,343,690,483,927,225,757,479,682,988,63,828,428,267,918,172,363,333,381,292,278,407,892,899,653,632,728,758,855,778,311,181,912,733,515,313,151,886,825,961,195,328,160,529,582,305,697,427,827,62,771,138,705,165,351,85,59,466,191,180,14,192,585,279,816,204,124,761,916,457,829,92,927,978,779,324,324,641,998,515,820,672,409,850,923,108,159,759,107,964,123,579,277,104,624,738,775,195,692,203,267,328,825,664,327,789,966,876,794,649,346,437,496,861,541,350,77,609,722,258,11,32,645,471,936,264,125,55,351,44,799,250,788,546,943,115,405,989,659,469,760,273,845,601,268,810,596,684,505,735,86,26,544,809,657,169,764,897,948,674,408,843,576,363,967,392,750,348,801,822,481,934,311,469,93,506,212,169,643,809,642,28,560,657,616,902,887,753,775,334,68,245,66,650,501,382,584,887,736,432,81,633,9,422,626,884,905,338,70,725,691,76,985,23,461,414,918,246,698,804,966,948,341,426,542,903,551,118,823,766,885,312,234,26,237,207,596,380,519,802,268,563,304,127,776,336,250,992,813,646,175,769,206,952,18,828,226,225,194,475,468,631,603,611,382,743,770,240,869,588,34,593,655,866,69,756,553,85,198,156,575,506,102,455,675,584,560,743,644,585,214,413,19,173,823,995,484,319,201,943,860,27,42,249,657,968,846,437,72,675,582,2,229,441,450,298,449,128,725,117,246,443,190,153,894,337,530,310,348,193,627,971,2,903,673,534,805,331,11,150,184,21,584,792,483,672,967,61,431,985,949,664,890,415,425,713,518,538,22,903,85,621,275,100,979,271,982,323,37,209,161,945,926,826,433,223,937,23,647,10,113,563,186,273,233,953,175,850,976,832,594,110,294,402,750,1000,926,39,640,977,208,631,840,318,621,748,366,225,174,455,636,984,822,289,237,274,427,527,100,386,571,880,15,99,376,194,864,928,564,496,570,864,176,776,143,713,101,86,412,210,190,909,478,645,120,335,207,872,459,451,521,123,563,658,727,527,312,270,411,380,51,911,943,437,132,227,126,59,453,716,786,837,316,218,512,657,821,672,711,876,987,509,566,318,814,452,546,594,991,880,614,82,787,739,470,469,911,948,453,98,11,14,109,634,282,844,898,935,967,732,810,616,436,376,349,773,566,726,887,84,461,135,413,451,46,535,787,172,475,514,313,398,581,591,19,164,649,575,472,727,296,95,847,803,549,736,144,877,996,424,323,169,52,516,841,766,976,689,974,988,363,715,497,847,240,969,126,276,342,334,727,474,755,894,289,330,61,449,183,951,975,572,855,453,92,302,671,948,329,33,234,499,866,555,24,16,689,255,302,992,840,941,58,317,464,6,928,483,297,66,893,811,762,23,829,197,138,835,383,496", "435,125,593,65,850,97,148,170,845,457,782,178,968,529,112,389,980,226,631,854,23,868,340,19,899,237,388,551,661,542,118,986,602,260,706,577,907,850,273,433,104,422,12,90,776,146,47,398,915,585,954,470,495,469,399,894,975,529,214,54,418,248,768,681,231,47,616,78,624,900,473,580,556,561,5,99,417,670,650,660,162,497,820,392,309,226,681,810,324,221,903,560,433,541,550,671,569,468,847,656,675,211,782,922,227,513,693,255,181,204,517,875,141,583,899,38,432,277,374,58,27,733,393,213,76,928,481,808,539,352,61,944,734,503,931,0,290,797,581,57,306,783,69,761,741,173,731,570,221,121,834,29,658,994,987,6,974,858,663,447,67,280,327,536,769,125,405,859,437,871,230,967,990,8,107,620,132,761,877,610,358,2,569,171,23,217,199,180,602,38,452,235,820,538,174,110,151,111,653,603,8,255,417,922,128,532,903,983,91,699,796,462,55,838,118,229,143,221,696,426,4,256,479,258,940,299,170,889,287,479,418,909,549,424,739,701,780,920,733,124,637,496,914,84,143,542,448,20,686,964,436,802,516,765,330,365,982,432,445,921,718,23,845,243,598,332,223,473,980,746,859,23,728,350,253,590,414,202,442,549,537,850,600,252,385,865,660,349,339,631,373,899,523,902,171,86,64,338,7,882,467,434,815,901,335,459,292,507,730,900,955,175,957,255,462,303,481,824,284,232,273,953,498,225,254,320,968,254,79,834,698,102,660,479,246,40,268,511,276,730,899,633,731,301,709,90,36,524,213,864,636,131,602,702,517,256,444,683,957,668,540,385,147,322,778,802,731,249,576,320,818,917,68,93,312,160,968,794,837,75,423,826,671,467,117,609,777,509,341,302,122,563,371,24,880,283,590,37,413,776,999,846,382,618,870,566,904,378,54,934,762,368,619,715,981,238,467,560,737,307,24,688,741,388,548,290,559,62,219,889,42,959,440,394,506,441,296,661,404,577,354,652,216,661,365,861,881,975,663,803,574,244,25,80,776,742,718,842,712,311,448,116,846,443,805,518,992,476,919,172,299,434,374,397,508,41,758,527,426,423,632,684,462,750,765,405,896,18,141,298,847,317,794,3,846,892,119,917,172,882,876,939,789,652,67,104,269,498,915,824,704,390,971,172,3,713,853,183,21,841,608,445,162,419,538,897,490,559,885,163,885,166,921,899,257,185,765,611,110,409,437,762,124,432,781,738,274,409,309,608,782,695,146,193,217,463,901,885,228,272,584,730,317,21,221,257,731,641,925,479,815,94,541,312,799,111,825,45,426,417,515,567,61,386,259,494,752,58,200,269,137,751,600,576,188,444,585,716,34,953,80,300,847,452,403,159,908,719,114,937,333,617,806,895,458,615,462,734,703,4,864,192,361,679,951,697,247,553,812,575,939,22,255,618,367,876,41,906,247,839,114,821,803,917,202,441,443,973,476,115,484,304,51,431,144,947,476,777,476,814,194,893,441,340,919,550,837,310,567,613,108,99,359,774,33,19,224,450,960,94,147,958,72,174,420,635,556,468,292,864,562,413,731,108,4,594,975,201,852,95,841,982,932,155,702,632,521,809,292,684,482,472,120,573,319,70,42,918,995,822,24,215,762,450,166,790,277,207,1,148,52,82,792,67,533,818,452,68,663,30,249,216,879,784,497,712,372,117,217,517,506,686,747,533,296,166,923,516,438,126,343,309,944,234,792,890,408,153,71,457,803,511,219,453,96,544,863,722,807,666,166,380,45,952,877,668,235,225,793,853,126,566,489,323,717,895,652,185,435,137,203,155,878,971,849,396,998,673,663,935,504,41,308,625,158,714,804,897,392,825,289,188,341,376,168,60,709,660,501,273,546,797,143,120,272,120,597,630,499,352,904,186,672,889,32,40,911,108,170,115,998,871,117,658,838,638,733,323,398,656,295,683,293,175,445,14,140,858,845,354,694,407,642,791,669,838,610,846,800,27,879,79,178,855,136,335,231,28,221,304,354,808,242,647,807,245,152,163,487,680,318,500,397,627,140,858,599,51,755,983,672,998,175,580,734,571,128,258,558,126,922,381,502,686,219,8,12,907,410,161,397,485,745,523,551,148,788,174,626,685,126,560,92,264,476,482,384,443,448,918,194,862,416,142,684,900,464,373,604,70,136,173,940,791,715,257,523,180,829,442,720,683,146,391,690,420,256,598,939,98,212,153,40,282,539,894,870,331,804,63,403,985,155,386,563,129,753,201,564,38", "559,560,511,555,374,523,472,167,943,90,766,788,711,456,225,651,278,613,773,682,671,499,976,147,145,203,874,308,356,323,51,812,732,888,550,110,841,236,776,448,556,122,252,255,316,57,932,407,94,247,182,281,44,539,551,550,9,927,996,144,411,653,96,436,996,703,284,197,191,267,400,835,289,900,807,413,133,390,956,655,446,538,780,778,12,377,495,834,523,374,831,609,559,94,235,626,678,44,888,285,645,18,821,614,806,567,443,866,934,389,529,521,287,201,639,682,148,682,153,245,187,610,374,924,601,944,732,227,513,144,345,641,786,244,351,290,0,176,575,629,986,230,976,364,720,474,837,698,508,369,431,734,504,626,141,85,861,569,301,319,670,817,32,156,619,998,893,255,156,938,209,272,328,968,561,640,388,765,457,359,181,210,331,412,510,300,795,399,298,881,620,702,872,326,317,126,262,219,110,143,562,814,290,10,353,222,619,743,857,364,701,733,954,543,802,493,20,816,13,49,348,405,123,876,237,731,60,552,832,564,121,274,99,309,631,912,23,444,994,7,333,241,38,896,146,504,614,378,953,685,104,111,135,790,758,240,763,429,565,178,321,12,283,36,711,399,679,330,801,36,709,799,123,773,786,192,960,983,122,779,152,131,987,440,191,637,292,946,936,106,204,664,355,275,566,375,328,444,264,212,617,550,691,880,573,229,677,652,71,309,693,727,947,249,652,654,152,32,980,593,24,366,489,994,588,403,624,73,718,814,138,288,420,204,745,258,193,746,940,502,740,563,889,765,360,712,908,551,488,713,722,443,477,615,129,912,281,533,994,687,133,768,465,928,63,755,537,86,170,248,125,301,436,652,863,883,552,282,418,470,633,158,970,840,336,182,547,380,240,345,516,867,854,190,75,662,930,987,330,53,757,143,281,158,779,119,407,51,616,959,34,912,406,511,592,567,750,633,128,910,584,365,607,705,984,168,900,756,719,324,46,164,908,229,852,410,717,672,193,600,622,14,138,311,536,820,346,651,666,131,455,345,503,20,495,625,536,658,407,199,630,351,951,389,835,327,202,273,818,60,403,106,962,892,625,733,710,682,280,283,425,615,903,527,712,89,611,757,400,152,120,264,525,551,694,521,516,96,975,226,809,361,278,473,157,201,877,631,60,376,777,355,352,448,352,114,390,235,137,921,532,740,360,713,963,361,350,444,668,22,366,104,452,151,833,114,53,624,1000,741,200,884,788,541,204,706,988,567,78,634,351,200,431,548,939,463,416,701,360,450,682,248,50,536,24,357,510,8,933,842,793,533,279,589,337,540,660,53,919,58,455,795,12,753,634,215,89,560,849,168,739,560,911,487,295,128,493,161,517,357,925,700,58,790,175,466,762,690,324,823,958,428,677,517,620,536,782,195,590,423,282,964,725,3,896,94,36,243,483,393,190,534,848,763,85,927,200,347,771,130,722,905,217,463,365,843,780,752,851,303,633,511,530,817,564,382,288,101,427,548,579,805,175,559,758,971,919,295,825,33,322,990,693,935,462,861,338,36,455,151,279,832,856,21,555,513,707,925,891,855,335,808,658,383,115,414,814,779,521,302,250,23,648,82,145,546,301,496,549,476,185,283,345,941,152,778,295,879,72,939,343,30,967,765,70,574,199,963,810,680,220,351,693,185,781,771,399,166,851,139,617,258,887,127,569,821,106,552,445,402,578,546,92,112,605,597,373,216,588,742,42,317,788,392,310,213,252,309,93,532,388,558,658,782,734,472,824,422,706,395,579,567,856,40,452,242,718,310,405,895,735,623,614,112,143,616,244,314,661,495,743,262,434,954,853,655,517,851,451,205,312,504,920,498,416,440,101,976,934,200,849,923,388,522,695,737,402,575,57,560,420,161,437,24,16,691,906,165,279,476,801,324,955,669,613,778,144,437,236,743,320,169,112,245,619,783,341,775,921,763,950,849,381,909,151,211,389,962,287,298,564,493,396,273,12,686,440,273,427,911,724,733,949,561,772,408,425,743,221,584,903,665,521,302,820,776,160,648,118,560,174,926,919,245,750,970,134,856,671,882,102,608,253,349,222,604,24,948,843,456,252,145,400,747,607,926,520,621,497,550,696,833,123,203,719,76,858,860,485,226,517,525,705,28,819,361,675,364,781,658,164,724,335,421,61,803,234,337,865,809,47,725,276,981,256,349,802,434,255,72,252,575,861,133,323,671,133,316,293,888,687,600,303,195,622,588,874,676,19,303,485,295,867,6,973,293,514,826,974,190", "283,335,430,158,206,220,479,509,520,342,478,787,451,379,176,275,191,390,247,582,17,396,652,647,116,850,833,368,348,661,644,450,388,448,386,168,819,91,773,652,536,735,241,919,274,563,767,4,202,765,595,476,115,672,16,629,187,231,704,326,939,229,649,8,279,285,114,723,399,142,350,796,828,754,889,712,114,700,361,200,652,492,812,11,582,380,608,466,180,909,485,924,352,627,818,663,377,469,671,832,250,594,656,899,289,650,780,805,439,46,710,860,237,684,5,125,888,368,376,336,135,432,862,499,27,876,645,164,133,636,710,687,629,422,515,797,176,0,160,435,672,292,756,320,383,674,250,210,786,444,447,977,479,258,403,868,102,245,475,615,791,701,60,986,862,958,915,52,164,208,26,734,929,54,935,756,539,989,394,683,743,672,503,105,304,896,27,850,142,425,148,499,482,922,87,184,920,834,855,125,271,439,546,928,610,527,963,437,728,340,827,165,368,169,539,890,73,19,455,819,564,275,978,946,657,708,415,982,131,271,75,995,976,569,50,938,863,845,975,495,463,591,629,602,544,190,200,521,352,694,542,209,625,44,392,682,297,312,236,956,18,260,256,976,399,29,398,843,632,442,898,845,912,779,248,8,965,142,232,599,49,60,740,529,147,122,362,192,294,586,815,616,607,410,35,52,395,53,846,968,969,744,921,618,429,27,489,545,951,828,726,568,208,777,230,113,703,553,933,257,515,895,725,682,303,215,207,597,180,844,523,141,198,286,970,515,869,49,376,258,905,536,468,587,259,22,505,636,795,224,672,443,992,615,6,107,523,476,281,880,836,289,487,975,817,559,216,427,893,363,459,457,476,961,145,256,685,691,154,156,766,484,727,942,669,977,746,756,149,331,613,913,281,670,540,752,967,941,736,148,621,4,987,324,854,118,896,600,613,55,146,415,617,949,58,43,822,717,584,818,316,80,115,783,606,821,651,756,232,824,369,363,338,514,589,642,918,718,946,83,41,768,680,597,955,806,42,225,979,91,754,757,439,900,71,998,880,245,764,456,54,749,960,559,593,685,193,806,40,143,719,956,71,359,437,382,102,418,160,988,939,813,409,699,678,247,491,352,70,485,398,562,714,760,742,663,806,554,796,395,123,345,882,629,533,204,866,952,395,265,889,99,797,803,128,576,460,736,219,219,576,70,113,88,527,506,508,39,369,971,360,555,728,577,160,913,227,394,752,922,504,941,902,331,361,800,132,409,192,860,481,750,956,877,562,478,570,557,590,291,323,521,584,526,553,20,830,366,36,311,645,222,6,976,553,229,962,328,552,955,282,136,24,520,215,157,819,663,924,836,986,168,694,443,332,377,356,105,344,469,264,310,339,997,379,823,536,989,750,12,602,918,712,235,233,344,507,388,902,25,617,44,137,435,367,957,262,863,247,40,570,626,56,877,659,29,606,926,25,266,593,193,627,950,296,296,855,739,788,895,607,610,847,924,823,892,779,977,841,536,159,304,534,226,148,749,708,502,733,784,594,829,451,822,198,204,527,986,822,920,228,346,412,803,67,53,927,213,858,590,81,38,571,347,98,933,148,979,448,743,463,725,355,928,397,955,865,136,305,447,443,826,488,16,556,614,639,85,398,977,180,329,315,76,361,583,150,468,714,982,881,308,119,693,56,945,280,574,572,19,344,700,227,832,629,712,661,336,823,558,675,209,413,378,196,446,474,295,795,160,304,967,722,491,859,578,11,850,3,805,254,258,332,603,543,597,300,324,899,700,682,643,288,368,881,621,690,179,702,384,304,447,426,586,173,300,458,199,156,3,99,492,454,7,454,319,273,185,35,469,382,16,990,931,192,724,659,322,70,763,256,586,411,621,322,554,807,72,144,468,806,463,983,201,506,926,329,267,94,515,785,61,443,445,884,659,34,528,976,657,864,798,555,389,28,903,81,112,258,110,127,327,97,219,472,51,793,602,794,909,623,980,426,619,959,337,559,969,350,564,104,742,823,506,731,976,124,267,890,767,524,203,728,765,130,746,940,116,884,343,85,497,398,850,795,901,869,423,838,161,993,650,204,735,557,902,460,268,443,274,773,899,268,26,547,404,964,458,850,805,129,344,740,61,479,637,316,846,900,203,320,137,999,883,767,567,320,560,33,106,402,720,661,80,647,93,141,396,367,691,33,360,366,188,531,103,213,930,914,61,686,882,927,535,766,874,904,336,687,457,120,458,40,456,94,679,349,100,605,838,742,72,85,881,894,449,937,919,658,623", "562,612,516,438,544,821,969,986,438,314,295,271,283,560,258,178,139,189,854,549,708,871,122,6,410,107,433,133,815,149,296,235,620,75,798,382,521,809,177,864,995,105,448,455,53,271,571,420,505,765,385,915,538,892,105,26,918,74,649,924,842,852,610,585,751,905,706,490,823,461,679,327,992,630,409,78,666,602,618,168,508,266,55,378,616,77,35,380,588,682,662,647,698,988,26,193,244,242,803,96,78,763,921,805,310,247,623,763,757,525,81,686,205,56,575,857,950,973,220,933,42,590,550,125,584,69,523,468,320,590,992,502,769,354,330,581,575,160,0,317,140,590,46,38,784,651,461,70,834,674,322,907,358,748,1,654,571,313,592,410,527,571,638,391,585,308,279,616,556,759,164,716,584,916,381,598,716,36,957,973,629,867,407,696,554,505,144,881,290,586,866,471,884,270,629,895,649,697,143,58,540,150,403,487,540,62,816,747,41,926,509,938,412,17,907,618,227,163,434,774,884,884,881,978,67,116,210,791,902,636,377,730,744,700,713,726,303,885,455,803,400,749,881,982,887,280,337,788,207,997,644,822,132,934,332,753,47,265,236,589,995,428,265,770,23,937,544,208,728,952,834,295,272,23,98,825,705,751,25,903,883,768,879,85,563,314,272,895,71,298,250,207,259,293,71,289,289,372,23,371,166,885,750,144,433,53,671,12,11,964,295,529,116,253,707,683,653,929,729,894,479,749,94,855,114,458,993,988,350,843,752,735,409,242,857,790,339,627,341,943,816,399,278,321,778,559,52,807,863,315,814,200,799,643,769,392,879,448,207,65,847,200,45,122,30,608,800,574,656,220,263,677,854,568,950,716,556,806,523,497,130,702,278,663,222,298,997,51,608,656,862,481,549,510,129,177,791,983,472,371,582,807,156,126,171,732,342,245,467,381,874,632,87,950,74,52,755,265,911,872,281,845,66,986,707,878,565,627,710,550,865,78,880,601,307,661,1,881,948,473,335,600,428,208,408,109,27,67,745,443,57,314,672,345,486,415,731,106,846,203,224,986,344,913,812,182,806,470,824,244,282,661,583,372,612,422,398,876,59,961,126,462,11,611,874,166,100,545,39,717,96,362,987,455,877,753,225,136,428,555,781,119,568,258,291,597,79,306,62,718,102,334,208,709,323,860,796,439,297,714,730,910,743,39,447,887,962,451,104,791,999,811,213,703,190,457,334,888,962,85,332,335,180,372,801,921,774,803,382,834,46,85,458,218,265,872,937,383,855,393,19,44,963,655,570,568,267,342,164,239,403,669,874,781,229,729,572,858,613,235,31,606,769,809,125,319,474,181,770,412,268,215,944,540,273,681,864,284,182,345,723,856,479,872,283,443,183,74,57,477,446,704,592,633,683,204,505,823,790,677,523,622,385,800,949,21,508,748,955,216,347,382,42,662,672,999,661,561,814,721,274,85,156,966,290,384,925,412,395,273,585,571,823,954,372,228,395,746,411,47,784,649,481,247,922,592,933,311,455,374,787,162,279,110,834,803,185,226,859,919,402,631,662,612,40,362,281,697,636,970,371,822,52,534,17,273,193,461,274,707,207,821,411,740,959,144,319,256,562,623,595,314,944,155,413,559,690,119,314,122,843,251,217,262,428,337,373,844,949,438,265,435,783,457,515,170,514,954,260,561,432,795,138,698,755,636,761,865,463,397,675,371,621,455,582,358,48,745,789,83,8,925,609,835,488,900,81,458,701,792,315,977,121,92,383,236,945,846,419,67,333,718,692,543,56,562,103,436,183,965,831,391,281,467,492,322,157,189,619,101,53,280,742,800,545,566,192,581,491,158,995,776,392,762,343,910,890,501,439,707,131,470,696,829,237,327,556,624,275,873,616,519,181,241,148,540,649,229,147,192,748,845,481,795,486,651,976,645,997,77,543,837,451,586,404,415,391,901,222,36,699,818,969,710,629,102,999,206,149,560,314,556,943,870,83,269,402,905,306,981,118,639,665,868,397,949,880,334,85,537,3,518,519,118,516,716,521,721,142,654,754,22,690,52,278,969,980,693,112,895,953,11,665,72,802,859,978,384,573,219,993,341,762,288,994,380,369,541,702,805,206,591,600,18,998,35,960,281,214,901,658,458,723,327,399,610,409,694,364,222,202,955,2,936,970,271,392,248,784,499,533,639,198,91,320,740,311,392,733,224,133,788,490,408,1000,830,144,352,126,372,396,742,527,808,62,324,967,995,402,441,103,427,940,311,188,901,161,551,339,124", "798,16,646,681,833,140,463,13,947,568,512,923,906,32,702,549,92,327,632,693,154,87,182,2,246,327,970,666,438,88,715,902,822,824,286,121,40,63,610,113,770,411,926,310,948,613,391,889,370,436,203,780,12,398,936,351,40,912,933,665,240,873,597,383,857,226,585,374,47,712,564,583,278,159,223,443,882,560,160,42,976,455,474,796,847,936,191,490,644,734,711,556,474,992,745,536,727,577,278,447,221,712,4,157,843,472,197,656,117,202,174,273,326,576,483,746,899,705,128,175,207,883,241,967,308,211,543,273,77,893,762,725,732,230,549,57,629,435,317,0,251,532,19,465,810,839,90,742,567,459,333,780,36,397,781,763,780,818,769,728,391,641,230,32,999,699,843,476,985,734,829,350,86,65,481,673,325,649,623,710,328,331,450,158,288,605,519,890,809,122,198,16,225,849,886,667,496,800,75,692,794,347,864,528,947,734,35,143,568,912,94,302,599,270,256,942,251,797,189,89,668,232,429,663,50,511,293,19,762,588,305,889,158,886,12,701,326,993,892,704,301,392,292,306,68,405,6,545,803,352,489,330,127,7,898,624,995,73,814,508,40,777,414,561,352,898,401,282,867,960,959,688,437,515,548,520,279,994,88,296,121,878,734,722,678,754,225,764,940,511,192,12,105,192,568,912,785,700,242,98,292,84,848,149,53,946,820,60,284,301,138,579,347,302,500,237,294,564,715,437,424,775,833,536,265,54,687,200,972,775,992,438,801,363,713,476,602,524,172,488,593,722,746,130,751,352,161,944,506,213,35,909,556,174,873,743,277,842,243,220,349,264,884,25,792,803,239,568,352,856,368,251,660,740,790,816,836,843,304,516,741,218,631,660,142,442,161,575,27,480,54,547,18,981,346,402,738,322,858,294,702,812,652,807,652,624,118,686,44,816,847,732,549,562,323,775,869,422,805,651,845,249,209,956,9,633,765,582,6,98,59,429,334,887,879,174,826,236,531,703,669,872,518,255,326,313,585,668,212,307,77,998,946,575,530,250,631,926,219,6,496,15,520,25,325,809,528,480,264,251,729,787,733,484,517,825,226,960,872,921,596,622,128,929,317,41,209,303,345,104,19,19,831,954,248,61,979,848,886,965,126,395,379,842,201,698,595,337,597,378,951,554,746,88,23,103,564,715,459,130,584,645,563,746,645,890,89,905,718,59,700,513,540,668,739,703,630,93,630,686,766,173,961,437,418,58,726,865,429,236,130,187,237,507,545,604,371,448,70,861,914,392,117,352,150,481,334,843,557,462,127,206,745,395,181,136,552,486,451,900,451,358,413,695,621,401,826,108,586,251,833,691,774,676,437,12,763,431,640,956,403,656,413,523,653,872,977,21,638,948,433,492,519,704,832,245,643,563,456,518,718,694,924,301,98,686,927,265,644,407,295,703,619,132,796,966,247,853,693,63,446,895,716,556,872,331,832,130,736,199,196,631,827,783,832,863,658,184,87,821,476,228,745,929,446,868,881,513,347,851,788,428,987,739,73,592,530,702,52,291,880,992,350,897,232,213,64,762,696,543,608,501,280,140,118,860,398,223,547,256,166,567,226,760,68,833,728,989,677,334,503,906,129,682,199,574,583,177,638,53,407,794,152,690,39,522,738,491,781,427,684,340,276,513,184,575,94,903,172,469,127,695,858,15,427,473,563,106,296,894,168,480,55,435,419,443,156,980,786,249,278,266,483,884,763,958,581,299,237,551,694,141,93,301,454,198,82,544,197,553,98,4,278,601,981,409,296,311,431,506,601,707,562,306,635,179,974,620,34,956,13,234,852,314,599,491,665,78,217,23,243,318,256,346,518,879,461,854,138,605,681,212,307,791,28,441,95,418,713,601,706,81,355,35,395,644,192,871,279,182,571,228,600,953,115,5,685,907,92,717,216,992,710,374,662,366,337,912,856,840,389,730,348,504,878,401,863,106,648,258,462,950,445,925,103,879,861,159,411,304,419,811,505,356,287,65,191,993,458,88,249,412,919,519,264,474,589,823,346,853,945,961,909,116,234,682,892,884,193,823,112,596,579,45,984,442,334,544,455,808,883,244,332,270,353,866,874,902,317,997,792,653,185,689,317,776,891,903,506,128,955,854,594,778,971,254,894,36,767,13,514,575,555,265,639,19,77,145,234,794,668,37,742,872,72,191,121,254,836,828,86,949,413,653,620,442,863,970,881,487,513,806,81,66,744,78,448,837,774,836,58,508,220,322,498,919,716,890,935,160", "349,296,640,78,198,285,751,375,309,326,484,880,890,748,647,624,852,413,999,373,427,15,203,568,271,586,263,48,444,520,523,804,788,971,634,790,941,12,671,383,834,810,884,539,669,419,768,479,381,775,827,651,953,978,178,426,362,29,669,858,849,110,612,948,635,977,921,139,126,176,17,524,744,759,854,196,835,38,570,321,636,260,611,515,271,609,497,658,202,681,686,932,774,868,742,317,918,686,369,108,562,610,755,15,518,928,511,16,692,927,202,268,784,710,866,811,67,276,756,585,8,318,372,222,641,210,208,931,748,654,667,140,319,943,44,306,986,672,140,251,0,63,630,532,985,622,807,872,708,650,242,242,119,813,133,869,692,178,439,756,728,444,711,274,855,130,897,882,922,10,341,450,974,359,230,587,332,547,771,499,157,985,167,397,72,398,31,491,153,860,257,976,432,764,582,764,712,807,76,617,581,947,631,250,184,115,95,518,669,43,232,58,101,582,534,363,834,720,527,849,679,574,679,482,968,838,807,449,4,886,932,457,760,194,148,80,675,292,333,945,605,353,209,549,576,772,907,122,170,221,216,464,703,278,114,985,120,578,238,432,392,339,153,939,342,695,684,358,115,592,321,26,614,604,896,202,306,639,287,287,5,937,214,159,83,87,368,118,975,165,876,577,765,118,550,223,100,624,37,486,26,584,273,246,79,370,758,376,159,662,248,261,17,228,345,502,90,547,530,189,115,535,524,217,981,679,11,499,694,651,352,875,612,766,431,655,936,894,368,204,73,615,540,390,29,774,538,417,104,344,313,249,107,946,598,509,656,161,422,714,478,4,240,664,678,462,448,586,344,177,724,225,350,472,18,922,162,852,474,171,928,213,253,767,485,447,975,910,243,684,351,748,699,451,467,726,961,846,389,555,807,368,258,467,309,89,786,906,227,157,652,898,797,217,732,625,371,685,542,608,458,183,899,480,374,861,460,937,817,614,124,248,556,437,598,560,452,182,61,453,965,491,357,89,744,59,171,158,100,387,699,945,575,293,442,465,844,602,974,32,890,552,832,494,645,254,428,592,191,883,692,856,72,952,686,198,885,863,947,701,35,54,961,257,777,817,112,901,256,949,804,709,989,366,420,413,616,812,853,865,681,656,453,75,706,641,708,621,271,484,761,470,384,896,586,391,44,580,159,670,253,551,986,572,666,635,899,843,416,888,998,330,145,991,548,697,596,481,735,652,518,39,633,946,113,416,775,609,942,964,359,604,129,43,393,693,294,457,245,782,915,601,979,105,118,429,322,429,714,175,871,392,760,648,891,627,446,450,882,244,241,989,192,617,988,288,630,809,385,514,285,593,549,981,766,825,634,380,61,438,717,897,985,687,725,22,483,824,178,479,157,556,725,870,275,118,198,621,79,275,341,632,169,753,589,26,704,980,883,889,457,950,180,950,318,300,747,235,227,732,629,574,180,747,125,230,963,50,438,20,518,426,290,345,73,471,514,384,439,599,808,837,250,249,632,86,433,743,71,744,789,223,831,50,83,17,900,496,678,656,528,124,883,672,984,672,71,362,173,482,871,437,155,444,218,450,141,637,528,302,181,71,874,819,877,278,887,922,434,797,929,932,402,545,284,768,979,510,653,157,323,927,707,149,211,583,358,623,757,648,951,49,55,234,208,581,585,691,535,611,421,5,780,192,747,507,171,860,466,305,522,546,910,23,295,618,898,267,812,127,505,913,486,880,957,94,705,825,366,547,289,330,319,84,510,499,262,666,860,122,750,74,591,301,638,803,191,813,919,498,298,709,361,630,21,724,195,882,705,379,1,252,646,225,743,347,684,378,292,162,882,202,549,554,145,606,785,399,769,801,841,48,152,845,406,261,595,592,916,342,652,480,319,319,48,815,753,656,315,998,946,319,50,368,894,70,420,435,671,417,129,124,367,365,671,124,644,951,895,933,467,908,122,448,150,36,881,982,983,83,15,815,942,60,843,541,539,190,880,883,562,709,634,861,104,271,856,619,244,997,620,759,667,31,592,141,965,402,345,473,934,944,885,778,668,943,141,109,83,340,238,49,762,3,267,139,473,469,374,401,669,244,33,986,488,182,581,482,918,335,817,615,839,552,870,508,920,210,974,838,539,412,954,36,949,662,171,782,157,807,9,720,70,279,28,764,156,296,699,442,870,288,76,720,605,249,374,902,495,374,271,189,995,798,274,832,955,324,692,389,706,881,974,803,91,487,779,465,560,46,710,825,786,273,223,33,171,168,153,152", "201,884,294,447,844,367,379,779,441,952,542,858,172,629,849,102,34,267,466,326,964,366,535,709,696,731,582,113,860,814,535,563,93,592,580,590,558,129,35,317,303,444,965,738,772,245,694,727,289,745,294,321,45,343,778,935,377,546,605,450,430,123,898,417,994,449,743,234,63,825,197,799,63,444,175,739,743,791,772,794,758,555,589,973,493,597,600,706,666,739,194,528,159,195,115,421,296,202,860,508,589,146,428,234,43,457,410,989,317,780,973,582,504,783,113,464,423,377,144,986,848,471,922,858,686,949,104,342,916,669,181,31,334,706,913,783,230,292,590,532,63,0,856,39,725,224,18,943,809,208,35,528,659,158,264,408,951,665,958,42,641,782,53,177,952,184,147,488,272,324,57,474,369,747,643,448,612,623,683,628,936,373,997,298,217,770,666,540,247,665,62,105,425,14,449,93,252,169,546,188,702,505,497,551,379,115,224,217,871,173,176,36,571,942,576,503,388,210,808,22,802,585,512,787,500,604,638,404,163,171,652,639,105,818,381,459,421,118,731,391,178,772,144,210,907,254,744,376,182,58,60,891,809,482,495,129,37,260,192,682,732,10,413,101,224,433,940,425,536,967,891,206,870,768,263,389,640,100,833,643,999,560,212,311,96,359,720,846,852,198,581,319,508,53,707,288,888,387,788,505,489,459,212,149,664,963,361,713,340,516,459,234,852,112,755,157,949,317,919,943,437,876,291,28,533,715,393,456,129,323,388,478,799,83,935,953,422,410,604,754,481,11,408,173,21,74,739,229,418,254,456,989,46,966,600,74,376,281,841,510,232,872,980,580,303,337,684,208,144,418,338,183,308,249,121,632,17,168,299,177,836,103,834,459,973,865,524,604,795,993,770,554,126,626,472,825,364,657,200,292,326,357,462,428,788,912,570,545,935,304,245,951,546,434,848,172,339,40,791,890,397,713,205,309,179,910,308,386,9,403,286,173,734,740,971,97,451,834,829,84,176,179,703,611,108,321,621,288,234,409,711,543,563,64,296,313,161,532,724,902,618,213,102,100,945,386,305,907,606,108,945,991,881,934,458,523,414,201,659,199,546,971,422,582,647,720,964,740,386,172,772,110,605,590,754,491,701,139,674,277,583,192,519,259,617,442,424,736,184,49,260,355,652,627,856,128,856,670,129,862,990,125,679,113,468,299,393,688,202,67,610,924,694,602,347,171,797,447,568,439,713,404,532,945,754,112,279,492,794,786,320,477,43,448,350,467,702,529,529,463,135,171,323,761,693,631,580,465,870,299,831,412,865,467,945,664,577,339,729,101,429,723,169,121,624,593,944,458,588,796,55,642,381,402,973,259,759,869,259,628,644,57,110,476,841,25,44,158,300,597,610,409,145,954,557,17,967,377,289,20,522,487,285,711,323,401,914,390,784,437,386,797,198,433,486,436,56,438,280,717,279,96,723,132,644,750,396,312,607,726,629,57,168,664,589,107,358,402,28,406,393,788,379,953,565,41,357,485,868,901,437,132,69,97,312,196,110,549,880,804,300,491,929,150,762,100,73,337,681,135,593,918,633,43,449,497,406,429,863,446,316,245,691,547,351,535,770,604,103,523,25,299,621,674,955,849,587,449,578,222,48,268,180,21,287,687,642,863,392,996,737,657,835,359,305,584,154,357,830,388,718,120,481,472,462,759,739,995,305,894,736,81,911,534,221,200,922,181,156,335,427,519,926,181,101,847,493,923,564,81,32,987,363,853,189,37,238,881,785,770,47,645,405,644,846,106,744,147,279,769,935,973,991,538,603,318,200,254,709,996,348,320,734,523,872,640,204,910,454,154,430,474,58,144,572,21,426,448,581,315,23,102,361,545,678,567,770,287,480,685,212,410,996,305,433,512,129,910,198,939,727,203,43,620,91,951,701,825,403,283,482,139,871,919,650,798,908,448,494,504,625,131,407,897,26,778,842,909,642,100,134,51,741,735,721,855,685,290,206,463,961,784,37,607,696,496,531,234,138,16,219,696,884,966,962,545,584,568,380,580,654,96,983,336,711,580,432,716,242,42,369,471,502,929,767,521,359,347,220,376,835,157,246,515,310,672,592,791,623,331,400,665,753,88,497,134,239,509,926,186,358,706,220,474,984,856,449,179,673,568,381,722,404,62,628,570,917,692,968,448,166,234,344,118,173,468,775,370,235,886,859,32,471,664,963,474,277,905,985,513,25,102,85,906,421,813,139,729,683,250,605,774,397,359,51,880,627,461,458,872", "383,446,623,931,658,287,202,478,43,541,210,213,416,629,288,291,768,669,589,337,446,261,808,661,231,452,365,317,570,621,731,620,593,958,584,779,137,170,338,977,239,357,307,787,43,753,86,952,748,639,940,426,613,171,287,519,173,949,814,500,735,267,859,492,255,73,739,850,886,123,81,367,637,606,787,231,865,751,963,870,716,910,679,314,953,356,658,242,102,985,809,923,911,574,443,321,404,767,71,330,736,809,39,864,846,308,483,266,935,919,683,24,899,420,885,261,847,533,629,509,785,770,641,255,563,64,978,625,520,967,65,842,464,431,645,69,976,756,46,19,630,856,0,667,592,355,429,3,166,141,25,659,435,371,389,179,540,711,358,381,803,46,795,467,587,740,523,41,381,831,641,815,301,225,476,690,578,162,264,390,518,134,218,552,248,720,940,486,453,578,15,517,702,507,499,868,785,245,261,495,85,391,133,434,892,986,384,125,914,148,176,274,444,718,597,865,252,246,728,607,275,877,379,123,420,958,787,85,593,829,336,822,142,256,233,135,412,461,372,571,771,641,102,174,757,90,450,313,65,660,500,875,349,825,121,926,670,898,844,87,794,368,425,888,842,567,868,662,250,234,829,475,536,613,294,165,367,974,99,297,911,866,531,197,653,852,285,353,31,52,997,361,980,433,961,957,241,766,604,323,337,933,270,73,251,374,67,877,511,718,182,742,829,188,41,650,345,422,140,15,324,358,730,374,255,9,144,206,148,539,896,132,967,512,835,811,97,254,83,77,846,716,593,394,412,889,291,334,321,531,453,234,861,90,375,729,578,5,423,635,313,620,983,863,956,786,438,348,284,917,801,382,759,703,867,82,570,375,717,362,463,743,896,194,793,314,708,803,558,771,765,27,481,149,33,115,622,460,248,819,907,658,948,303,824,816,202,701,495,530,705,495,20,224,812,362,429,747,472,877,975,985,941,423,798,932,994,197,632,207,942,205,445,166,590,699,970,111,90,616,105,543,932,876,552,201,120,187,311,13,790,604,597,394,89,744,558,38,464,492,19,528,998,809,739,853,740,784,290,527,506,451,974,87,944,645,27,841,31,399,826,415,859,520,689,100,839,714,744,379,964,944,696,517,534,910,426,185,201,618,246,346,289,404,7,342,458,459,476,618,336,699,675,605,898,799,576,214,501,984,117,673,807,783,540,584,457,839,14,855,507,646,63,905,766,296,993,883,398,462,958,118,338,156,217,676,948,154,55,149,298,755,908,254,656,320,13,318,568,380,937,783,35,645,220,400,276,810,39,560,923,153,244,583,8,463,425,905,497,572,599,802,961,317,580,58,920,945,345,280,551,250,13,249,251,321,412,545,826,83,880,70,828,905,348,995,324,838,642,575,206,388,109,987,547,348,154,42,504,923,80,272,501,614,277,341,266,632,450,844,412,23,318,58,739,199,69,278,40,443,105,452,124,21,37,348,936,212,260,787,6,915,171,518,541,800,52,590,8,186,510,82,239,384,488,914,841,616,660,837,502,813,598,849,832,487,499,852,759,366,200,977,767,554,47,464,508,570,414,695,787,384,50,965,174,766,986,180,532,372,71,507,840,952,575,670,515,985,238,887,731,875,435,846,846,413,307,712,973,470,390,380,415,469,20,523,124,989,905,356,936,642,878,939,766,771,486,848,853,925,190,995,481,167,878,334,710,913,778,549,251,815,103,105,97,826,347,773,425,460,651,919,835,962,202,898,909,454,963,125,674,57,909,17,462,936,718,941,691,723,55,86,210,794,292,876,678,430,91,366,630,549,311,643,800,969,506,465,471,508,454,419,839,53,638,872,26,120,879,752,505,807,486,713,386,221,312,886,763,303,585,677,407,886,539,208,270,49,272,405,247,143,948,287,979,308,359,491,892,72,563,820,22,37,234,908,449,488,230,476,635,880,526,989,92,482,249,447,255,699,439,88,981,669,819,753,660,388,955,498,698,318,124,928,811,545,713,733,554,460,980,683,411,808,697,877,689,695,338,326,892,259,52,582,838,452,386,396,906,947,189,831,898,368,28,833,32,526,175,260,33,154,710,233,748,523,242,492,494,920,424,5,609,71,100,362,877,180,187,444,828,342,823,862,878,498,211,816,472,735,217,294,737,185,613,207,445,820,500,470,573,999,693,602,552,768,735,442,351,783,795,901,441,519,80,602,855,251,350,339,890,84,213,69,222,98,46,476,105,919,519,603,154,155,619,153,40,305,367,181,146,157,935,430,691,574,145,932,595,214", "249,530,203,721,692,922,58,393,680,216,58,818,632,795,149,911,784,63,948,706,436,986,108,704,914,550,131,917,20,134,861,192,277,582,596,492,9,51,150,628,335,720,455,954,730,322,639,261,509,254,692,268,321,585,305,426,47,826,492,945,475,781,502,906,386,28,139,634,575,684,709,8,62,11,165,27,801,947,919,157,69,686,643,703,28,715,194,241,156,249,979,472,323,996,4,859,890,507,564,842,308,388,522,356,195,738,10,713,103,468,378,878,2,794,193,904,913,644,718,648,751,820,301,284,504,127,565,285,56,99,117,557,874,135,370,761,364,320,38,465,532,39,667,0,192,766,458,641,400,831,864,772,332,761,540,735,643,978,580,409,489,299,746,720,982,241,336,979,566,331,809,437,979,917,320,112,970,359,613,338,448,841,518,710,318,50,168,452,496,950,385,205,707,150,516,533,205,790,966,250,529,893,679,20,559,500,13,93,448,935,339,795,967,127,184,74,966,262,74,318,174,528,354,810,813,575,641,1000,786,299,774,400,989,577,111,875,890,467,118,488,697,838,497,127,233,464,22,935,93,960,837,49,503,559,75,930,601,977,726,498,458,739,807,363,827,810,917,468,516,756,425,811,393,404,293,448,828,550,766,571,410,210,313,445,985,115,124,606,748,152,619,724,635,485,683,285,917,673,970,203,795,43,144,144,748,131,246,351,606,520,200,174,877,617,794,548,610,43,907,485,546,325,205,514,720,840,614,165,466,621,278,705,803,263,753,59,453,657,960,620,646,832,98,768,257,967,346,39,694,600,328,38,122,634,634,828,344,184,13,868,728,644,723,129,223,207,644,421,22,754,713,423,921,196,961,837,195,664,478,76,768,684,316,616,697,182,305,535,287,437,789,667,807,909,461,294,511,531,54,413,398,901,814,426,120,530,172,64,707,256,980,631,186,116,759,641,535,559,702,419,985,489,692,30,520,564,583,930,583,876,610,861,521,894,279,382,331,637,121,119,447,546,289,203,558,992,417,876,684,830,460,333,270,465,703,985,60,72,294,958,618,265,497,973,366,345,7,588,734,408,631,395,888,615,518,995,746,60,280,547,241,445,151,401,899,341,577,654,379,991,844,999,364,826,644,215,154,340,775,463,989,669,825,795,798,615,637,39,879,977,538,687,603,62,407,147,254,408,441,869,371,60,144,962,292,451,567,19,99,934,573,831,462,921,209,269,927,175,177,359,43,781,25,646,61,899,259,522,526,804,589,800,438,582,387,896,98,442,19,569,161,491,923,697,770,831,200,57,505,958,133,447,123,647,39,116,547,517,620,718,580,20,484,492,439,821,936,658,587,459,764,513,945,992,707,123,335,788,721,35,606,103,62,746,241,127,157,807,535,546,449,804,699,910,306,776,495,490,10,769,434,813,207,153,685,949,679,580,949,761,26,233,38,428,416,699,9,160,461,665,993,751,473,352,598,663,292,352,856,203,447,625,594,122,974,107,405,711,977,653,254,164,909,163,90,7,4,885,682,943,505,201,319,680,964,885,414,871,535,979,254,374,610,250,136,248,710,709,941,176,125,53,231,421,976,617,648,205,361,176,309,332,642,986,978,603,661,192,342,191,49,227,518,856,789,201,689,238,218,633,875,33,8,474,787,70,284,723,569,363,653,399,266,49,209,424,236,943,463,368,15,81,677,674,632,136,367,935,539,151,562,165,919,996,883,179,18,962,447,222,479,205,738,326,252,410,428,955,945,767,732,639,445,511,906,982,565,657,533,337,625,692,595,450,573,909,434,566,171,225,974,261,177,759,230,585,193,7,420,286,303,340,293,720,671,459,257,501,497,255,803,843,266,496,22,416,920,457,918,941,117,82,994,296,251,233,778,808,320,754,479,549,596,593,475,238,850,992,861,736,698,592,633,238,216,854,392,94,832,711,55,826,61,325,696,410,707,777,421,838,547,407,156,734,141,942,851,274,108,625,792,906,227,376,134,160,534,325,925,977,677,564,153,789,434,459,510,456,837,678,925,855,513,478,459,984,610,574,737,957,331,842,596,900,433,338,997,178,614,848,18,186,653,192,450,52,835,985,711,402,623,514,579,490,656,304,751,710,169,462,427,817,503,655,24,931,338,576,307,987,858,438,429,816,640,196,778,503,9,131,433,646,293,577,857,550,40,699,183,898,180,149,618,262,438,878,143,832,939,211,498,584,139,227,724,543,222,516,105,542,965,183,893,141,773,276,826,796,116,910,628,183,594,950,864,552,124,877,275,844", "69,622,717,183,135,213,855,292,725,593,727,463,677,890,199,218,627,543,295,361,56,992,19,54,436,810,300,496,33,855,878,481,721,430,589,871,327,416,725,332,915,536,197,994,583,614,392,61,34,760,671,180,790,413,412,551,735,282,403,652,377,621,420,218,83,173,732,662,347,392,60,643,673,292,654,873,123,354,952,260,206,440,929,377,446,890,349,891,536,418,301,66,607,175,697,879,590,311,66,886,638,316,764,640,536,210,197,402,719,678,102,339,82,716,268,913,923,688,111,83,838,952,468,569,331,117,903,616,465,851,239,928,977,997,954,741,720,383,784,810,985,725,592,192,0,280,349,302,448,648,272,151,764,487,946,675,765,581,765,455,987,180,685,753,774,333,990,896,65,35,733,562,859,614,875,665,834,294,533,117,450,885,455,695,637,60,97,714,737,576,651,839,626,688,829,133,850,801,748,411,410,388,695,107,207,481,276,919,915,389,202,390,234,653,994,578,558,120,852,514,45,692,464,860,48,801,557,857,671,804,603,61,445,141,862,6,897,990,910,294,96,786,713,765,722,977,258,823,968,348,393,581,151,876,443,94,746,111,615,794,914,151,791,709,271,442,877,4,683,982,191,173,725,995,964,597,491,975,887,169,525,8,100,912,547,498,129,484,282,178,386,961,209,852,73,931,529,183,43,211,38,145,306,999,859,668,933,631,476,672,470,419,211,191,755,111,164,662,506,20,565,882,947,978,93,883,25,375,441,800,683,673,191,353,984,221,228,159,13,395,740,663,659,941,114,414,511,580,998,857,537,343,681,826,544,176,696,328,214,157,804,385,950,99,71,744,654,576,230,106,815,891,489,412,587,579,605,299,718,505,458,167,154,899,886,721,986,206,47,987,798,326,981,445,482,277,644,615,414,136,815,69,447,730,284,440,849,529,547,712,414,96,32,587,164,705,738,893,661,270,316,71,392,488,92,371,697,447,993,242,17,54,169,642,81,10,292,591,312,574,631,548,856,912,650,888,318,838,383,203,465,625,418,7,863,8,536,299,94,810,487,944,738,773,528,327,479,965,207,815,415,656,991,732,285,125,858,7,232,5,706,595,513,413,222,26,37,587,26,336,214,678,915,260,950,24,925,870,780,184,930,630,84,615,626,44,349,436,527,89,336,273,524,697,584,50,130,842,561,267,592,487,237,493,383,762,75,917,386,132,233,487,107,258,975,730,300,399,741,650,393,237,935,530,801,755,141,593,614,20,503,271,886,553,333,522,188,635,836,752,731,412,42,946,585,333,126,758,645,719,473,201,957,801,423,567,852,840,765,564,389,186,517,11,550,354,214,161,20,832,388,987,434,625,326,544,631,76,91,651,29,21,801,726,400,27,39,272,230,912,466,46,499,642,545,141,818,378,422,152,614,714,362,634,597,651,778,148,387,208,142,796,853,363,374,721,689,796,263,52,463,925,162,558,921,946,959,646,728,750,822,183,334,581,458,791,912,73,202,788,851,647,454,577,921,567,945,383,374,497,593,932,576,152,676,378,376,13,653,166,139,918,594,448,24,863,365,666,926,749,141,184,605,92,693,80,738,246,414,480,82,721,875,906,636,421,589,502,165,641,211,705,48,982,830,270,933,827,901,810,663,614,356,488,499,435,898,456,966,815,848,247,677,442,125,417,70,604,619,633,252,774,799,44,8,157,24,866,297,382,203,866,851,477,740,52,317,247,518,753,87,121,152,904,841,899,445,570,864,460,361,126,307,720,613,493,726,781,583,90,156,860,222,829,53,972,70,214,367,970,742,451,469,137,619,929,19,394,836,904,657,102,808,870,771,525,238,285,41,634,33,700,63,439,413,564,441,514,10,527,500,315,711,635,418,126,187,105,324,406,554,240,217,832,324,31,299,643,867,252,921,824,638,245,942,736,467,262,70,789,406,656,118,321,711,632,945,282,315,89,203,131,663,753,380,837,10,867,309,35,623,666,755,166,969,204,292,921,866,215,749,579,971,960,225,275,83,702,990,403,955,648,505,340,217,518,857,566,648,618,955,790,938,557,442,603,351,691,685,40,389,224,612,166,613,51,9,969,202,160,834,651,852,849,476,436,193,836,572,966,848,507,948,868,820,434,398,828,151,334,700,346,708,873,729,218,640,131,300,964,491,615,812,551,19,167,979,748,258,436,638,805,502,332,45,335,410,591,937,195,202,985,671,415,294,635,25,624,463,540,997,622,448,758,870,120,233,960,793,213,949,965,536,596,257,118,767,700,286,868", "263,121,762,377,85,359,233,552,146,909,292,238,774,766,493,471,691,301,626,85,554,650,356,775,140,451,222,11,638,29,356,528,878,383,421,51,309,486,834,611,776,495,511,851,614,785,76,826,584,726,807,415,295,276,222,602,883,424,37,65,300,949,39,533,124,403,215,85,855,250,449,346,275,183,719,7,755,620,519,540,319,736,404,830,520,961,512,391,833,224,87,739,427,949,703,628,924,772,486,127,481,668,223,999,71,954,535,394,698,265,866,791,132,86,544,923,832,70,977,254,49,545,440,88,570,701,847,668,905,342,768,211,491,814,741,173,474,674,651,839,622,224,355,766,280,0,895,884,467,577,178,929,230,93,436,301,576,353,539,912,254,239,264,398,220,704,278,942,233,621,649,220,447,809,874,910,638,903,706,14,994,170,385,135,330,308,99,242,555,434,477,766,635,815,193,166,268,854,266,749,837,302,925,484,683,789,987,762,704,850,582,316,195,938,170,801,553,6,370,9,183,341,99,133,207,460,444,551,722,645,181,920,906,716,311,440,383,846,350,487,661,396,489,836,951,115,992,442,717,927,647,604,58,63,575,849,722,524,630,657,306,389,496,619,787,254,46,213,621,380,788,436,424,883,472,212,188,811,777,582,540,224,262,570,779,348,662,238,452,839,335,833,565,561,867,678,391,365,457,698,858,930,905,732,130,996,904,571,751,897,790,86,760,476,956,141,769,872,420,343,221,224,304,451,27,295,332,918,303,45,287,695,694,179,843,375,688,764,354,655,667,272,651,559,328,357,305,990,968,821,771,268,554,510,311,117,349,161,913,298,368,830,752,776,951,320,189,485,24,94,708,154,501,215,455,367,189,7,853,286,749,298,21,509,233,148,997,56,598,542,838,149,32,815,917,755,71,878,459,656,991,591,801,157,971,130,410,141,1000,99,661,960,782,1000,892,1000,247,636,507,338,890,346,132,658,713,126,503,523,40,363,633,988,985,759,869,534,399,227,162,377,322,203,404,51,676,657,64,942,358,442,53,196,927,962,90,215,790,696,144,292,747,840,222,992,798,368,261,367,80,385,725,305,554,123,677,838,785,521,894,647,401,975,12,484,466,909,282,341,752,737,730,291,99,350,732,664,834,641,393,335,473,904,625,287,110,66,930,58,865,760,46,992,620,942,252,530,800,354,703,768,569,636,946,402,369,903,273,375,633,807,362,622,392,225,549,599,774,929,427,959,386,380,401,884,814,513,318,380,671,776,754,552,381,652,268,671,606,524,748,627,585,802,616,926,413,404,405,298,661,253,452,90,775,563,947,856,367,206,695,638,633,992,588,706,669,21,247,760,437,5,720,932,952,589,911,22,597,296,453,56,727,87,622,928,179,260,805,510,994,90,233,821,654,18,910,177,194,674,78,83,96,377,643,536,755,462,676,966,895,329,545,106,504,575,916,689,825,179,981,850,69,136,788,484,56,735,853,879,137,515,725,86,725,59,698,94,506,446,986,787,466,637,754,179,203,176,63,890,897,980,888,530,923,738,718,831,830,166,779,351,906,310,994,503,409,232,78,738,230,747,668,108,129,240,841,416,403,376,841,10,450,67,182,112,346,898,667,695,484,314,9,994,616,54,662,902,260,565,360,809,122,430,196,782,472,99,491,952,247,23,344,22,57,856,917,905,513,769,12,989,418,284,430,78,641,903,514,356,392,713,463,641,266,33,405,369,979,157,592,404,790,740,267,669,739,666,303,194,506,875,483,323,33,774,356,207,7,563,652,756,237,487,91,470,607,244,833,314,905,238,372,704,414,409,878,107,576,166,739,325,161,310,776,37,624,719,508,690,72,891,229,231,359,305,716,673,121,645,846,546,305,407,297,750,921,999,433,372,744,543,630,183,604,790,643,973,388,472,333,446,237,715,625,267,165,713,524,250,503,763,664,735,645,444,441,500,92,673,295,474,167,474,618,111,865,37,638,412,247,960,320,662,752,11,663,164,208,712,950,399,700,893,672,564,175,511,156,969,563,632,594,128,46,467,493,305,987,681,752,140,80,922,117,34,402,845,573,557,236,122,158,173,627,220,816,889,398,140,199,939,2,719,60,355,430,319,877,705,256,858,130,703,812,469,114,503,858,858,320,698,413,372,934,661,444,990,224,571,117,221,171,431,561,294,728,377,290,323,948,983,801,826,624,230,879,162,337,482,906,339,32,87,583,263,365,488,494,275,944,538,250,832,541,59,992,936,20,641,662,534,930,136,765,117,984,150,282,832,97,835", "415,742,715,333,377,961,826,119,201,164,704,241,433,557,908,841,447,230,680,130,746,515,898,311,805,167,15,736,322,429,171,470,758,770,815,506,302,27,274,740,781,546,132,803,853,24,397,742,372,697,19,712,762,425,4,129,418,201,985,639,149,368,144,332,545,620,276,882,181,245,729,56,957,612,518,902,882,651,618,357,609,276,269,50,630,831,813,7,246,440,500,87,670,867,369,310,407,867,475,545,326,204,78,413,787,374,883,870,475,651,591,330,790,978,686,845,457,844,688,332,179,418,844,423,807,289,288,9,124,578,964,112,832,814,328,731,837,250,461,90,807,18,429,458,349,895,0,175,750,29,983,188,116,316,807,870,591,444,992,889,661,255,328,437,612,137,461,95,195,892,296,960,917,928,256,942,355,680,931,409,881,424,797,629,172,589,384,29,33,28,207,577,731,486,669,485,986,158,798,649,540,132,806,574,337,485,951,837,243,988,346,370,128,938,959,895,135,717,502,930,666,430,389,446,488,316,804,822,133,303,515,646,512,786,67,260,50,479,873,466,517,478,21,177,502,870,462,105,609,802,749,79,843,209,133,538,174,907,179,890,317,81,315,914,757,251,618,849,425,497,179,442,632,155,514,4,921,516,773,403,765,847,855,386,300,342,248,301,304,199,172,906,541,430,652,609,273,319,227,18,722,301,757,362,544,214,421,212,373,876,181,375,992,549,844,361,699,388,70,412,150,965,543,387,975,127,264,106,853,470,549,285,687,278,278,604,944,741,718,900,683,382,708,60,976,901,505,369,680,962,879,594,528,295,389,889,272,299,327,886,130,990,995,752,918,467,658,74,495,966,566,45,750,548,175,95,948,835,910,931,57,529,341,512,286,929,592,745,968,287,723,74,168,468,379,694,742,358,567,755,443,142,807,677,126,536,538,530,222,141,688,80,76,760,50,640,786,325,125,26,335,651,258,167,899,160,760,264,290,630,365,880,204,292,290,685,546,434,965,826,472,564,148,860,69,418,123,782,515,86,650,82,191,625,550,609,139,242,330,4,215,789,413,491,611,112,58,818,711,658,922,351,477,422,409,640,940,817,884,150,410,270,372,77,123,626,862,20,710,317,487,613,296,62,52,271,18,539,43,563,752,44,63,325,904,915,898,481,163,76,653,728,962,539,769,510,257,10,788,985,774,888,576,760,675,9,670,9,842,691,467,153,825,903,696,73,159,405,177,215,749,5,99,881,771,322,4,859,606,624,29,948,992,796,348,357,320,170,60,136,408,142,741,500,838,79,334,305,301,190,175,17,893,696,564,420,468,677,16,918,889,618,238,484,862,690,349,488,132,975,454,706,54,246,205,817,400,426,230,981,561,157,343,929,551,869,375,811,82,98,81,477,588,215,824,16,387,891,812,595,56,952,909,292,613,453,561,983,991,516,43,766,727,659,625,724,934,934,582,542,979,713,569,33,797,816,466,112,361,534,764,654,864,186,512,687,290,700,726,348,959,227,142,785,197,320,376,521,81,745,573,570,813,414,906,986,538,498,628,400,414,693,294,146,711,384,951,335,564,714,583,236,418,864,775,551,541,112,190,994,406,772,138,667,207,994,204,570,419,410,209,80,252,718,519,59,933,432,123,639,762,702,125,498,742,212,570,230,767,796,427,296,680,488,978,200,445,663,152,395,661,998,116,470,204,113,866,533,119,310,872,477,991,852,735,250,84,730,890,899,305,864,779,368,570,814,984,587,820,868,912,805,241,930,510,647,951,144,595,121,610,609,22,961,538,625,71,854,779,838,443,580,329,76,769,458,337,642,614,185,397,327,762,373,901,362,180,283,875,286,591,378,98,49,557,95,114,851,819,873,664,738,506,369,683,241,329,28,216,378,257,468,719,445,406,748,76,195,167,398,115,142,93,358,162,163,175,64,926,693,227,336,42,424,43,579,631,366,458,10,240,688,978,557,862,580,58,95,248,529,347,701,191,104,243,828,591,344,85,221,537,496,818,453,850,36,730,62,695,945,475,366,642,493,332,615,759,440,228,205,507,948,277,304,364,317,775,175,208,242,196,177,382,239,384,977,49,861,163,83,881,263,45,847,993,811,98,599,38,372,922,109,524,255,362,958,404,1,667,933,585,855,682,913,324,509,577,167,893,570,433,727,636,557,400,396,277,449,404,118,334,393,881,860,652,199,188,771,627,264,759,395,676,339,664,529,424,372,35,587,609,32,503,353,768,909,920,187,792,794,312,478,348,206,732,7,629,111,126,99", "961,378,496,839,546,319,245,960,407,816,596,242,108,208,733,909,74,373,535,39,643,2,23,963,679,72,167,489,717,127,899,403,237,18,548,48,913,919,600,167,703,589,303,469,584,180,674,536,906,517,112,408,274,432,602,131,93,63,213,161,830,667,290,878,585,459,420,951,534,321,921,795,745,818,691,211,336,664,697,706,975,860,780,767,114,91,908,947,618,217,673,363,801,287,109,944,125,584,521,189,481,839,822,858,324,449,553,357,444,653,719,115,328,540,581,832,561,952,179,271,504,663,72,611,108,364,641,595,842,178,297,379,411,108,342,570,698,210,70,742,872,943,3,641,302,884,175,0,394,34,634,173,564,256,603,255,767,381,672,971,116,994,782,715,168,710,459,29,719,469,894,808,590,477,140,281,477,452,327,602,228,927,942,746,922,815,928,695,394,57,670,103,610,282,228,503,263,961,738,443,814,234,556,544,86,390,40,734,394,635,624,888,966,967,203,67,473,795,901,888,695,525,949,677,257,21,387,322,446,753,727,249,43,699,886,33,916,179,210,416,521,390,708,916,194,106,379,361,146,943,226,302,280,188,212,729,613,170,697,328,230,266,411,288,607,17,230,613,350,357,988,666,49,958,940,157,330,772,782,900,535,462,460,214,418,993,961,932,707,427,757,326,232,26,639,275,567,586,301,221,918,573,809,316,928,421,832,223,871,860,620,297,285,652,817,194,631,9,810,197,865,495,172,107,274,250,143,357,361,36,332,495,347,63,94,409,244,64,759,55,420,728,451,333,855,216,253,346,955,730,19,833,865,635,380,501,488,691,759,910,702,355,277,105,281,382,932,710,821,901,343,936,381,898,515,394,448,736,448,818,30,59,53,86,423,425,820,469,494,342,206,841,6,269,257,291,240,471,808,391,91,612,206,893,217,399,976,391,159,619,394,17,303,337,931,697,948,870,648,136,238,126,36,153,625,985,205,893,227,265,332,952,158,696,835,83,919,920,214,291,79,441,697,502,414,45,892,207,156,778,145,142,187,640,529,541,293,210,715,698,673,840,187,15,658,802,313,729,261,830,838,278,230,4,227,870,605,889,581,347,390,749,136,530,38,630,195,115,691,279,971,767,759,910,894,582,903,571,866,279,478,290,537,944,667,466,432,528,571,436,119,68,987,107,844,307,17,598,658,909,884,10,981,159,883,139,994,462,401,103,102,136,616,520,505,483,150,969,979,736,742,40,225,80,807,922,38,982,523,780,833,95,77,900,617,813,995,865,551,698,317,657,181,680,213,821,341,314,591,738,582,565,787,157,337,615,933,409,620,553,648,867,491,679,814,575,706,358,789,694,194,190,744,257,347,676,855,392,450,90,491,438,260,959,483,107,792,459,46,739,291,115,948,915,553,305,614,663,978,414,776,467,661,788,902,774,887,854,975,54,964,937,291,286,84,41,669,151,717,199,688,989,221,662,280,85,249,203,639,429,137,206,66,536,143,438,761,633,697,16,705,279,313,799,326,157,961,988,527,540,274,967,900,615,613,945,665,97,62,404,454,578,436,675,88,474,354,291,722,933,20,186,853,717,906,883,177,146,676,532,94,846,933,910,529,634,431,1000,29,941,368,896,633,115,863,787,309,916,7,156,359,619,977,831,568,842,203,324,302,263,369,118,639,186,428,976,359,628,140,827,707,122,568,490,709,655,436,819,683,518,339,448,197,676,917,65,572,531,88,991,597,553,493,845,840,269,619,626,405,505,852,702,580,164,348,118,123,599,359,439,263,987,341,777,190,699,263,905,44,548,560,458,280,979,296,353,760,891,674,596,93,297,998,913,12,336,466,235,346,157,390,493,607,561,796,455,633,788,77,628,156,73,633,114,278,17,113,730,70,738,759,574,104,706,942,693,174,219,831,785,264,71,229,860,469,700,971,395,826,142,228,150,229,681,997,433,485,954,618,61,725,352,5,565,295,119,443,387,641,567,251,375,753,932,870,639,942,783,457,771,507,721,261,522,356,15,578,674,352,231,145,690,800,534,910,343,807,780,233,504,367,49,302,521,130,804,98,629,599,22,800,766,248,766,810,559,262,878,252,183,120,284,594,281,570,420,118,67,608,515,372,361,778,390,646,213,915,928,991,72,129,172,488,268,324,365,896,983,26,698,185,146,751,931,271,343,256,217,169,756,577,957,421,292,719,538,741,970,992,731,933,563,54,762,606,353,744,344,735,789,631,346,976,925,25,820,515,898,264,325,725,938,942,696,580,265,449,917,172,147", "56,816,442,570,260,674,408,292,364,460,371,389,677,680,864,306,46,437,14,581,333,397,769,388,173,907,315,173,812,938,782,605,217,751,727,218,697,494,583,875,436,468,647,285,924,286,603,995,718,785,328,429,309,548,637,817,293,28,796,24,710,36,302,185,979,175,388,22,44,769,834,6,29,109,837,16,656,802,227,542,313,918,824,426,343,344,911,405,58,274,719,794,832,76,733,157,221,973,128,28,880,915,880,248,116,792,125,174,413,514,252,607,326,645,970,411,236,171,291,223,884,525,577,237,902,164,129,209,97,628,649,169,961,402,958,221,508,786,834,567,708,809,166,400,448,467,750,394,0,58,373,558,146,141,899,379,805,868,404,349,749,813,976,903,799,301,741,994,915,33,743,909,423,786,362,897,587,768,937,271,421,88,878,260,218,665,514,118,847,333,418,617,962,571,537,168,719,941,103,432,886,724,929,713,74,376,732,561,81,31,741,143,266,799,953,605,967,39,888,478,767,511,150,337,92,656,446,469,266,657,798,788,922,942,772,596,637,110,143,741,914,508,737,642,396,945,91,637,684,468,800,974,767,789,969,794,349,102,387,366,816,632,763,767,381,331,152,246,74,111,948,200,495,748,867,411,900,617,138,243,822,733,933,100,737,968,795,76,648,657,989,892,639,451,714,583,31,874,343,596,918,450,749,458,390,198,255,774,105,182,458,729,747,661,990,606,936,182,770,24,694,24,781,776,407,609,677,544,275,885,657,19,146,62,779,929,289,161,986,41,617,693,997,452,168,921,131,760,867,189,171,872,675,164,293,33,115,682,327,566,592,332,760,923,249,372,906,787,196,320,856,875,280,727,806,550,974,360,108,92,178,332,420,548,217,137,955,605,697,968,999,732,442,693,515,950,933,919,412,451,69,248,453,667,737,294,241,54,799,816,736,767,34,256,414,71,941,756,773,329,201,124,654,903,349,14,315,102,386,807,483,280,839,348,705,130,6,518,776,123,265,637,736,987,203,42,175,707,949,935,827,375,858,996,426,192,162,278,943,241,676,763,916,979,532,616,291,813,854,918,200,631,4,437,236,677,490,297,233,442,978,822,158,108,74,72,411,25,373,463,100,619,826,103,714,424,420,930,503,347,251,595,157,640,985,630,804,675,934,900,781,770,874,422,787,550,210,537,604,306,229,598,385,635,672,131,800,382,285,994,710,30,368,240,553,320,809,956,734,833,517,176,974,97,491,956,9,669,313,632,923,37,511,441,453,131,91,779,164,299,506,5,786,993,775,768,169,588,738,930,83,82,129,399,126,665,274,739,540,979,584,110,552,826,103,205,137,927,758,771,656,872,745,504,649,968,395,679,447,775,572,616,301,223,764,253,986,415,109,46,595,548,675,679,74,949,457,308,457,36,439,231,897,793,968,894,528,63,900,406,920,994,815,155,916,296,416,91,937,325,240,465,180,315,606,869,442,818,725,889,157,569,974,8,860,21,670,503,94,147,527,565,960,968,284,660,678,438,524,720,862,5,754,811,991,655,323,184,637,401,349,644,367,14,50,885,87,285,299,684,685,107,830,283,179,530,662,390,712,696,975,505,373,69,601,74,912,286,52,160,272,364,813,302,68,758,168,77,611,399,958,271,409,454,539,377,765,503,927,840,45,35,195,303,514,232,810,700,367,248,592,592,162,302,227,95,584,958,468,615,375,234,105,542,530,842,640,128,553,307,778,95,605,18,527,133,623,806,890,622,764,949,95,65,652,901,680,231,549,948,902,143,763,207,299,941,690,770,416,206,288,266,843,624,222,360,256,202,780,788,261,823,55,67,600,792,167,649,772,380,373,954,38,635,772,609,798,58,231,469,311,928,159,641,2,630,764,567,256,217,8,447,887,908,746,444,463,549,504,672,387,762,353,413,499,56,926,980,766,94,660,903,479,92,305,990,567,291,596,508,115,939,615,300,538,50,54,675,337,371,91,923,269,634,450,288,401,184,943,420,897,839,335,613,655,936,199,82,122,407,496,550,909,683,45,671,245,385,158,245,791,779,281,52,202,599,629,236,678,69,388,552,158,149,161,694,336,721,196,908,673,220,84,259,399,233,488,833,178,761,375,260,443,247,815,988,843,701,887,989,375,128,997,516,337,566,498,909,822,815,264,59,243,947,222,921,325,471,454,434,170,417,725,308,639,147,705,105,993,795,610,476,841,733,367,431,458,810,325,161,13,906,549,476,841,509,345,549,983,880,141,91,474,957,905,711,276,351,170,224", "755,616,11,636,736,229,345,334,388,891,828,35,398,979,180,185,598,17,267,475,448,983,409,678,582,497,733,399,351,920,944,897,361,115,276,753,22,798,59,997,557,965,83,307,581,790,216,996,155,256,276,201,541,741,568,634,501,360,699,853,577,339,797,603,27,227,226,596,845,251,698,286,202,680,800,12,927,575,238,899,667,520,109,8,309,685,978,461,490,977,660,210,487,976,707,712,149,464,244,556,198,125,237,423,796,616,445,453,771,236,973,169,935,975,535,368,544,278,489,400,110,399,847,35,239,257,580,470,221,81,838,714,574,165,951,121,369,444,674,459,650,208,141,831,648,577,29,34,58,0,570,306,342,369,497,748,914,766,767,883,184,458,652,530,497,156,820,900,545,348,527,180,164,684,541,841,434,56,512,407,853,999,745,246,634,19,571,627,691,541,814,419,950,360,457,448,965,50,757,113,836,76,324,660,516,346,239,363,354,51,895,607,891,325,113,258,668,92,910,498,136,196,17,521,497,544,864,572,235,251,808,928,41,547,483,575,558,542,891,163,555,687,995,139,897,146,695,940,679,881,208,98,732,495,891,129,796,289,682,388,901,521,719,153,114,404,59,690,509,855,419,496,12,444,39,228,410,366,443,205,4,523,367,867,747,79,534,172,603,235,934,396,487,208,968,619,148,241,110,148,821,836,176,249,397,429,30,834,865,54,143,523,368,26,31,568,374,607,617,44,319,288,441,319,81,486,906,217,469,439,195,922,799,965,80,232,126,120,12,388,334,304,930,748,545,647,329,170,664,374,173,880,616,693,48,882,610,573,586,981,342,261,928,330,729,855,17,813,865,829,894,932,467,402,802,952,712,962,847,548,379,824,955,376,840,740,489,296,807,513,973,50,138,629,973,793,431,183,798,598,950,332,583,536,444,220,891,393,720,111,823,113,676,955,870,708,539,77,266,350,970,451,300,821,250,684,538,562,268,150,244,898,426,336,712,764,303,86,267,663,299,227,261,591,827,290,699,784,185,101,621,677,779,427,591,202,221,565,615,367,536,809,672,968,524,207,738,576,374,21,610,439,590,983,522,254,665,507,995,62,882,214,605,266,241,862,32,879,589,993,382,454,240,987,924,695,735,100,871,63,630,764,895,839,285,142,161,900,775,226,28,134,909,485,503,192,568,895,407,650,406,371,105,848,759,441,426,365,446,220,607,954,279,290,947,379,828,811,227,992,645,425,852,640,525,112,35,107,970,654,429,649,582,957,797,478,194,120,878,477,167,587,237,2,427,604,743,814,564,84,473,195,967,688,700,17,258,962,182,198,276,342,219,770,44,163,266,397,625,386,675,444,123,264,56,646,907,351,737,185,340,152,913,390,75,165,315,14,903,645,232,465,606,280,880,615,192,464,497,305,493,487,255,450,569,874,366,735,841,64,80,300,671,556,262,46,484,420,929,836,573,632,287,749,629,782,86,682,777,399,25,498,715,146,932,560,629,379,163,779,707,31,535,101,225,266,780,142,309,717,180,17,271,435,453,969,338,228,16,467,831,47,802,394,396,666,71,267,771,949,413,312,314,856,368,790,81,370,144,896,923,42,316,242,223,121,860,497,398,809,2,723,322,968,312,437,657,508,273,293,938,581,879,110,807,468,808,946,85,679,317,231,517,103,319,292,782,550,28,447,12,967,27,520,232,24,125,728,314,804,178,345,376,901,254,792,227,517,358,959,243,886,264,910,86,781,620,87,251,462,405,45,422,388,387,413,586,491,784,796,178,508,806,48,908,425,643,562,748,512,140,633,901,437,361,741,525,698,122,183,72,993,151,38,56,447,324,518,710,156,475,616,604,905,502,621,735,671,392,750,525,282,64,136,261,333,839,674,221,420,327,497,100,136,680,84,227,367,967,588,966,4,716,496,27,830,377,768,234,197,624,609,810,586,160,261,848,581,184,796,244,939,892,834,861,403,215,23,102,800,953,401,570,174,790,363,451,145,832,779,89,455,822,809,779,303,920,901,581,171,995,555,258,173,69,419,743,325,443,638,917,73,414,975,558,823,464,623,299,7,743,993,49,950,119,139,608,48,456,954,395,761,951,477,916,4,145,535,168,7,324,880,138,527,137,638,641,124,99,128,243,801,926,263,254,163,510,980,615,573,563,480,362,35,105,441,602,601,616,197,853,211,71,12,744,294,248,172,252,574,831,849,299,605,274,599,896,210,273,156,10,705,76,729,559,31,415,111,826,222,748,925,178,641,999,93,524,509,503,600", "616,307,113,296,21,245,736,973,855,999,238,682,220,556,164,587,475,381,211,889,739,215,399,497,29,670,156,499,276,758,520,850,815,540,442,295,793,244,274,60,48,937,686,790,589,673,723,737,204,652,290,238,51,799,820,212,496,937,547,336,574,692,837,400,122,52,346,268,679,204,735,766,592,765,928,544,933,681,738,424,904,380,720,225,366,913,870,225,216,287,177,586,893,773,527,315,642,554,885,849,630,365,124,9,371,253,826,657,597,332,199,884,810,238,195,89,400,988,634,457,481,490,938,622,444,423,47,701,369,484,340,459,551,866,631,834,431,447,322,333,242,35,25,864,272,178,983,634,373,570,0,383,751,268,898,485,281,371,874,492,739,512,372,100,918,266,184,422,710,796,183,578,107,21,290,868,934,987,978,305,366,629,305,615,791,949,79,988,215,727,245,574,373,544,95,651,32,83,355,42,200,538,527,493,222,325,560,159,33,850,283,464,865,364,734,502,275,643,251,482,639,759,663,539,85,71,875,490,969,81,875,731,246,598,548,958,879,132,994,145,452,404,991,939,50,144,500,162,527,957,384,268,647,106,810,257,740,527,624,860,115,320,95,951,56,849,589,690,557,696,684,579,607,747,510,810,375,272,627,378,20,978,953,240,178,691,199,534,408,767,265,642,339,638,620,341,747,349,682,72,441,313,236,478,698,347,969,770,220,18,509,992,515,688,372,103,336,683,856,312,3,851,570,684,874,998,948,597,240,944,542,886,248,67,707,638,273,848,261,952,405,346,983,272,339,848,621,933,288,945,515,806,423,343,460,147,76,400,505,138,953,903,734,559,351,685,730,340,122,207,851,953,661,803,620,743,990,601,165,236,360,253,668,691,851,53,174,66,719,611,217,245,455,171,898,318,300,983,873,797,207,931,155,588,738,674,876,678,845,548,256,388,106,279,295,417,703,740,259,530,995,154,628,867,265,941,967,51,322,842,824,845,842,100,218,426,469,592,600,560,129,221,907,78,979,52,739,193,398,87,919,621,226,45,399,763,604,408,719,684,902,563,862,423,753,995,516,360,713,947,257,228,402,633,866,685,264,44,600,327,712,176,872,356,425,104,636,545,204,236,286,537,307,941,156,923,397,214,948,492,488,869,503,791,293,219,859,895,129,145,79,990,272,892,624,466,892,686,968,716,766,156,355,477,740,150,243,932,900,804,502,136,165,466,212,147,123,276,715,619,764,862,339,757,127,836,546,329,351,389,231,148,385,634,492,611,94,338,637,966,14,326,362,810,471,68,720,186,154,75,895,477,28,723,841,907,197,367,410,184,17,527,660,715,166,251,962,459,303,807,893,984,391,59,208,58,216,458,87,441,570,78,592,840,600,616,269,20,763,313,110,642,485,674,121,370,598,937,498,262,303,126,971,799,31,902,575,43,550,366,462,945,324,232,852,819,304,101,653,237,859,287,667,140,498,455,255,646,173,545,389,923,213,393,69,475,949,288,375,285,945,622,625,580,904,77,422,198,907,780,85,879,857,965,762,590,381,551,65,213,958,732,248,120,196,930,409,983,674,92,282,838,570,61,20,318,47,927,138,456,393,14,883,79,469,196,98,647,81,762,455,857,203,496,359,172,636,425,727,781,33,594,231,787,594,855,59,287,151,747,279,132,486,705,113,294,355,469,996,498,648,30,731,577,266,57,834,923,647,680,540,203,803,860,623,625,295,230,223,229,742,369,181,690,815,941,190,756,599,102,563,205,351,678,13,734,322,964,829,853,103,851,539,498,864,765,610,872,40,144,325,949,493,457,574,522,544,714,342,648,319,9,802,184,939,814,867,942,800,479,427,153,727,136,132,914,659,871,407,400,733,569,469,707,276,252,943,76,420,845,259,490,617,292,71,862,47,530,523,22,821,487,295,236,792,661,126,686,510,522,917,76,40,877,699,558,455,211,884,781,227,515,519,642,988,178,620,463,134,364,854,280,162,745,803,395,565,984,335,523,68,460,722,347,898,18,874,727,592,568,226,189,904,974,472,838,587,903,768,247,610,890,33,261,388,433,284,937,633,81,311,947,947,774,575,143,654,606,744,284,997,863,53,485,199,172,982,411,98,833,402,986,81,946,103,171,646,195,19,811,18,189,599,722,312,429,808,228,173,622,65,187,114,418,53,809,191,765,418,62,444,709,706,671,706,52,778,522,2,152,926,594,824,957,485,476,468,641,528,605,235,687,882,103,219,770,476,170,936,341,618,768,655,806,835,59,665,136,486,328", "27,115,751,301,40,848,303,949,747,294,415,165,984,753,932,609,183,273,999,658,558,159,616,446,752,26,181,643,920,980,879,649,825,947,868,134,154,93,801,217,252,975,152,998,775,665,812,952,894,395,835,389,993,695,754,145,73,218,279,434,535,374,442,543,245,173,586,18,64,226,555,47,464,737,104,311,610,567,910,164,919,659,457,12,305,515,556,927,719,830,498,706,679,269,868,84,465,781,968,834,994,38,668,705,997,658,672,843,954,602,687,305,37,567,122,940,734,919,494,387,559,972,547,210,302,309,781,915,151,353,572,803,988,195,134,29,734,977,907,780,242,528,659,772,151,929,188,173,558,306,383,0,516,490,109,547,469,445,852,514,696,87,305,780,471,514,219,823,918,345,968,771,782,333,269,754,934,301,101,866,110,18,988,780,136,364,207,816,478,465,183,760,912,964,85,738,79,903,662,751,232,736,422,714,836,610,77,144,864,17,891,63,944,293,412,437,487,862,842,300,116,534,726,895,371,617,961,440,149,838,84,570,706,4,756,557,785,121,6,861,378,502,686,616,507,356,715,983,1,997,667,99,869,109,402,846,978,437,954,302,337,898,301,76,695,626,70,162,635,300,164,303,755,310,62,426,298,232,643,300,419,254,200,305,862,628,946,862,787,471,924,752,296,718,366,856,675,145,283,282,563,966,765,409,768,927,863,673,621,58,910,355,323,246,368,774,610,766,850,981,769,465,776,461,433,794,466,798,922,62,170,681,649,933,210,558,171,887,421,231,663,799,490,867,55,915,958,646,849,97,130,836,697,733,619,126,207,224,438,738,272,724,442,244,45,82,426,61,729,370,570,434,936,537,519,357,906,367,805,814,557,229,660,968,70,530,184,845,473,78,559,839,71,637,500,173,506,824,399,969,764,551,654,679,109,847,257,366,392,159,267,110,46,662,571,833,786,475,758,353,696,424,696,615,61,878,328,685,255,529,58,94,804,785,96,53,747,409,41,284,330,391,187,24,843,359,593,862,377,988,348,968,818,571,455,57,894,439,262,65,194,407,538,344,186,593,93,737,234,299,97,608,947,182,204,504,603,394,911,614,137,977,666,975,768,146,438,412,774,203,499,640,862,585,228,636,938,892,607,337,721,353,998,186,20,639,51,446,641,747,425,819,574,228,801,889,888,145,270,217,381,247,844,176,323,249,494,516,431,969,324,173,50,302,826,99,603,633,352,585,394,535,410,377,562,13,212,669,948,33,85,131,758,619,249,375,153,351,260,348,26,290,288,437,64,718,283,548,435,190,989,104,388,895,749,961,490,97,927,656,830,204,854,165,489,810,510,530,269,142,765,34,70,400,409,878,949,65,1000,290,747,921,59,555,339,974,739,765,159,811,227,141,500,431,336,779,145,224,888,621,954,254,188,603,555,903,180,70,551,482,559,500,843,520,866,791,66,330,743,909,232,34,116,227,132,832,549,698,676,368,194,526,830,171,16,613,983,92,410,607,316,962,7,129,454,918,602,551,504,99,702,634,899,788,549,450,732,801,463,737,326,211,331,300,565,370,383,205,819,925,145,851,34,410,280,432,319,827,229,970,102,567,700,853,683,82,608,101,392,351,862,628,133,95,877,822,252,334,240,312,627,103,298,996,344,693,152,218,228,784,760,967,54,891,57,392,318,51,736,219,573,890,88,974,137,983,542,433,606,728,745,187,84,977,239,67,71,124,246,106,219,871,868,529,817,186,121,654,922,602,989,33,643,721,35,158,543,483,717,744,113,86,604,490,615,9,4,632,281,96,467,354,302,785,37,55,158,705,921,29,861,433,776,531,17,675,278,394,157,262,389,170,227,505,794,743,679,195,48,447,996,136,438,14,858,683,235,862,385,320,418,915,161,401,77,763,294,998,757,342,199,308,980,482,247,9,859,191,735,933,732,756,31,477,520,374,288,400,772,63,243,208,777,856,680,166,626,326,344,342,68,454,652,742,867,964,620,75,163,366,720,876,840,885,103,324,201,139,378,313,794,986,728,893,485,487,290,251,647,504,490,494,180,328,280,37,699,985,952,778,901,285,575,337,752,426,702,486,969,169,232,151,558,886,40,296,887,733,182,600,715,753,972,560,895,272,592,412,863,194,678,164,95,409,246,21,333,408,209,140,859,384,612,716,714,827,848,989,299,935,748,894,994,239,542,805,490,588,839,207,888,165,417,473,13,92,792,614,659,39,438,673,379,669,977,125,853,250,941,51,311,605,940,620,868,941,65,950,665,457", "186,492,888,947,309,181,16,25,933,884,730,872,888,93,363,154,584,792,598,193,711,491,160,71,740,554,757,448,717,985,739,213,378,373,760,349,909,879,337,332,480,150,979,121,168,709,155,156,159,425,365,936,438,227,257,381,657,699,897,858,923,513,90,798,84,37,186,999,540,48,51,120,668,440,933,794,245,865,690,153,297,122,216,123,489,485,733,37,673,977,469,560,538,507,632,839,261,236,408,54,112,128,38,743,633,538,609,427,511,74,688,69,723,399,107,971,744,695,535,570,697,261,10,741,582,899,15,234,316,972,122,919,255,798,278,658,504,479,358,36,119,659,435,332,764,230,116,564,146,342,751,516,0,110,771,723,429,472,584,883,934,724,997,793,527,939,577,482,995,318,888,110,188,75,493,537,679,365,902,42,957,987,153,835,218,772,291,565,568,294,331,696,461,31,231,491,220,518,602,656,740,594,222,355,484,637,66,535,867,891,615,701,267,478,218,309,218,942,269,592,294,137,268,277,903,123,906,278,193,759,834,243,136,903,44,485,888,418,170,736,197,958,171,475,729,43,162,292,917,127,382,335,170,740,836,196,787,840,994,241,486,23,93,687,183,673,208,328,224,63,122,490,516,51,627,105,290,46,861,295,399,456,179,153,810,921,408,554,876,512,461,10,289,521,427,94,837,506,385,693,583,850,60,175,512,865,59,791,229,724,151,163,991,685,826,1000,992,541,244,361,952,165,875,207,386,639,972,759,246,355,714,92,191,917,104,244,921,834,91,496,764,429,850,711,672,551,252,819,786,46,410,605,791,590,696,326,302,700,130,699,55,174,477,401,53,731,551,285,869,31,201,359,666,419,126,553,955,189,535,476,435,558,931,103,300,586,837,138,109,553,594,494,312,764,226,31,27,453,444,225,135,413,796,185,20,750,656,235,186,380,777,868,960,614,342,534,896,766,454,172,565,648,757,796,986,361,871,692,582,467,663,521,232,429,477,679,273,454,903,219,812,559,848,117,865,963,899,238,644,769,777,113,739,45,95,692,461,713,867,930,263,47,62,524,784,86,495,998,571,144,44,611,907,815,993,89,370,205,70,731,310,659,556,128,676,215,381,62,983,418,937,82,521,124,654,677,713,149,184,6,540,176,728,993,591,897,318,7,918,524,657,768,772,176,626,123,79,295,502,811,739,552,281,338,664,728,345,579,671,975,95,245,559,920,90,187,358,330,272,883,927,532,506,797,2,758,786,210,46,343,137,967,989,484,190,825,627,428,524,476,498,455,71,946,546,428,966,292,649,973,953,220,635,669,257,764,404,243,577,960,807,511,883,333,623,51,89,673,314,446,23,367,361,784,102,893,358,888,905,886,912,881,87,133,288,479,972,259,700,756,576,262,963,945,886,901,505,786,666,915,699,430,38,965,499,284,86,45,980,330,652,366,474,978,402,975,196,365,768,825,584,147,31,355,196,369,119,122,142,419,884,283,357,744,477,542,686,492,529,188,457,665,134,592,413,492,675,5,39,76,173,842,791,532,451,840,329,860,394,9,537,128,836,327,727,677,912,714,656,273,80,513,53,690,614,123,267,756,802,998,47,890,907,196,750,739,491,610,469,100,520,405,719,384,9,208,360,139,810,133,314,766,132,786,97,58,580,183,973,455,428,4,884,325,944,331,729,573,965,394,629,129,455,861,320,626,261,854,943,508,462,717,686,37,38,150,860,768,382,437,170,813,263,399,693,585,584,221,116,857,670,711,388,281,341,827,674,46,223,156,170,685,8,517,880,237,48,504,57,485,530,620,758,239,499,371,811,910,150,731,15,104,52,731,364,205,681,608,474,469,354,202,770,667,348,728,901,492,69,147,194,428,92,135,853,111,325,505,69,557,664,935,356,145,511,269,831,444,882,842,888,955,222,872,526,148,398,407,835,150,146,653,967,382,396,600,369,661,530,166,440,210,21,11,558,909,114,694,235,125,271,257,774,416,612,182,595,251,298,689,868,529,382,774,183,808,775,440,135,952,42,994,456,604,823,49,856,546,388,107,199,26,585,632,772,349,232,807,508,289,477,611,927,477,332,199,706,187,964,229,11,508,159,609,772,692,123,35,877,714,900,751,63,985,493,406,854,915,776,669,42,541,595,365,291,448,28,447,659,259,445,570,127,182,272,650,646,783,878,380,871,477,133,165,643,409,734,898,604,770,331,217,168,591,422,958,232,779,64,650,214,996,68,296,892,556,317,326,701,786,955,893,601,77,694,353,866,205,578,211", "63,646,803,552,74,394,576,417,882,228,183,22,47,468,9,477,339,586,403,73,219,289,32,675,130,396,221,62,746,236,626,694,109,96,993,94,879,520,696,319,451,609,611,535,642,70,343,899,771,136,933,144,683,197,474,957,924,972,451,166,772,388,54,232,376,67,560,466,917,510,223,418,705,406,564,113,696,644,474,177,126,674,414,68,724,125,655,385,841,352,718,315,31,986,724,487,49,610,640,187,894,978,97,252,600,550,887,909,467,349,180,965,929,613,455,920,26,119,330,38,740,605,406,204,713,608,577,747,4,451,939,840,101,151,865,994,626,258,748,397,813,158,371,761,487,93,316,256,141,369,268,490,110,0,473,618,329,340,703,856,217,716,692,697,104,182,422,927,706,320,542,412,786,536,657,428,875,810,759,253,145,88,244,960,928,247,867,134,819,842,113,196,482,10,682,84,877,48,203,245,77,973,840,425,357,844,100,605,838,175,722,680,206,873,979,972,166,152,593,271,538,108,451,991,267,232,590,608,152,171,528,39,442,657,251,404,864,694,756,635,170,337,610,684,758,382,367,19,72,824,701,55,922,293,820,494,308,351,234,755,494,640,240,513,417,856,597,423,408,955,48,475,444,223,727,382,464,667,830,363,805,439,949,208,973,574,326,670,116,150,373,577,772,457,426,79,514,554,482,494,727,274,412,648,481,111,630,869,681,17,992,233,763,752,8,424,839,477,866,943,569,954,126,209,364,48,859,474,205,637,911,907,939,962,502,36,51,305,347,623,116,144,996,705,582,379,132,843,98,23,540,468,420,797,107,847,105,702,92,990,544,767,979,775,674,716,852,493,382,823,298,539,16,57,284,317,11,67,824,680,562,483,594,932,388,297,892,127,915,584,589,993,527,128,712,570,630,353,448,96,131,388,872,138,214,725,454,169,693,607,355,772,560,508,90,903,60,546,69,470,74,912,579,157,587,480,36,34,839,796,695,355,12,446,387,804,756,747,633,971,967,687,866,947,376,756,522,411,92,163,903,7,657,877,544,209,35,86,327,456,209,353,271,789,255,712,561,323,248,987,593,765,536,489,942,619,954,644,756,891,64,395,917,757,350,90,249,219,51,265,353,462,940,416,378,381,931,245,212,590,547,798,542,258,739,259,115,910,304,280,667,652,22,730,785,134,922,709,588,65,408,30,581,864,721,895,880,934,77,811,640,846,94,859,92,190,729,188,676,94,848,506,283,380,542,752,510,937,6,14,46,283,366,540,861,234,605,696,133,199,198,134,326,198,968,363,922,84,888,202,963,608,413,553,41,234,838,473,455,414,492,619,793,290,521,793,35,3,359,257,679,224,281,639,23,541,864,215,19,150,366,222,918,543,958,492,899,672,389,742,783,448,203,198,800,888,773,808,3,680,400,196,888,428,626,26,613,674,513,102,604,811,763,833,941,598,942,464,737,482,36,270,98,680,800,604,492,989,649,642,244,907,995,24,259,412,224,825,853,971,189,126,167,875,486,11,537,227,227,493,831,267,428,238,299,661,616,823,405,752,822,636,727,44,609,727,246,177,376,740,614,131,707,281,138,919,571,42,328,411,792,311,787,803,765,598,388,208,468,352,122,600,602,190,855,417,19,371,275,819,644,619,361,194,915,16,543,818,453,400,758,475,263,860,774,410,782,561,134,918,860,365,73,550,22,337,569,454,273,583,90,643,680,659,987,167,724,357,122,918,253,631,216,626,749,894,674,954,508,837,159,892,448,790,559,956,460,161,908,183,412,158,371,774,570,640,533,811,926,487,283,225,855,269,958,559,136,42,611,473,270,760,459,943,408,795,801,992,840,356,517,724,250,704,373,953,931,871,275,290,522,23,437,236,825,755,305,712,243,552,11,150,601,564,238,349,848,959,56,735,55,867,196,229,466,162,844,925,23,713,690,420,38,243,995,5,41,733,441,768,731,664,488,982,491,788,899,763,518,3,826,346,59,126,522,729,89,611,505,16,994,918,23,317,720,723,256,355,277,33,712,174,313,740,122,929,497,86,279,109,384,179,632,421,194,629,892,544,584,701,782,763,604,512,358,939,583,460,914,227,42,869,361,229,895,82,227,988,68,37,73,196,562,927,622,854,640,902,496,662,800,728,843,646,353,866,874,661,92,865,752,454,334,998,746,104,327,882,40,281,908,897,154,446,829,633,774,592,243,735,919,577,805,606,961,309,398,949,286,490,886,292,224,119,475,450,681,397,871,304,838,115,370,914,629,387,47,564,917,453", "247,831,934,920,164,165,212,447,213,991,660,102,459,788,638,303,356,494,838,80,235,799,764,468,624,308,494,673,603,44,23,683,243,307,937,682,341,994,65,501,388,880,650,249,427,434,514,126,714,977,889,993,949,291,817,726,144,478,613,199,253,14,514,325,727,190,598,681,551,978,567,367,665,19,713,835,460,862,698,320,29,457,341,208,736,390,310,126,974,372,124,605,557,420,443,916,494,403,151,523,678,923,296,393,17,129,898,87,308,623,830,877,542,851,570,581,91,909,561,327,69,106,868,564,297,525,98,74,371,695,84,240,56,541,556,987,141,403,1,781,133,264,389,540,946,436,807,603,899,497,898,109,771,473,0,302,599,779,287,837,470,117,732,655,447,728,951,630,957,815,939,334,339,716,558,882,524,697,49,163,257,584,100,28,700,975,535,512,649,622,314,89,291,859,185,118,19,701,299,804,25,475,586,744,241,11,6,342,32,728,56,649,60,833,429,350,846,607,392,198,602,166,541,588,210,710,597,920,5,300,809,265,674,347,162,443,575,791,65,746,666,540,829,39,716,136,605,246,386,924,763,822,295,592,751,51,169,168,405,722,357,411,3,226,355,424,233,61,980,671,753,321,986,904,203,124,524,904,518,244,86,781,894,29,502,128,932,717,683,26,24,100,191,140,264,949,133,804,861,925,967,745,435,988,286,67,670,614,86,986,545,730,268,881,195,385,880,120,879,857,182,801,943,795,720,205,155,774,925,895,505,789,465,382,842,243,609,255,163,779,184,860,612,944,110,158,638,102,512,878,617,745,967,332,110,704,801,722,870,803,78,204,930,172,742,239,746,829,655,146,946,836,139,441,928,156,252,36,660,9,992,964,890,565,826,946,967,328,585,437,961,714,354,360,311,811,283,272,298,657,267,815,651,688,951,555,881,120,6,796,505,724,313,123,913,362,179,488,706,300,448,468,80,575,190,507,558,36,281,787,51,455,947,837,980,401,337,206,947,714,511,496,228,500,664,262,536,412,970,185,944,825,55,883,60,753,74,311,86,398,430,653,897,97,791,121,349,500,798,524,370,672,502,870,380,942,891,970,307,808,611,879,554,880,196,843,521,982,347,89,613,499,74,501,720,614,258,993,957,901,315,17,824,331,141,771,507,792,524,577,524,898,461,544,738,804,143,376,727,300,311,457,64,618,899,802,853,501,769,829,793,181,361,157,211,508,891,835,479,103,326,644,216,663,722,11,307,533,21,857,969,619,254,793,456,945,530,267,547,866,926,673,610,15,96,882,943,848,240,743,68,77,400,121,50,194,987,512,13,524,741,703,285,245,260,222,844,100,977,996,528,669,577,739,960,290,489,27,552,362,502,487,242,930,388,406,399,119,889,999,135,893,907,773,182,461,984,568,530,445,165,589,762,776,70,744,316,367,490,340,971,854,623,120,580,100,506,760,648,311,858,372,938,116,461,154,110,121,970,530,345,864,395,674,797,495,172,239,580,674,60,334,643,526,617,981,627,835,869,89,620,502,862,673,556,486,82,666,151,571,744,570,553,799,2,171,714,581,93,7,104,491,481,169,722,49,674,149,573,150,148,162,693,559,436,84,97,869,129,213,128,526,650,84,352,874,825,333,552,540,306,179,342,673,736,47,171,834,261,233,705,516,399,833,415,579,929,659,648,900,793,474,223,157,399,416,554,341,685,926,226,867,284,547,115,720,298,873,230,271,181,772,774,998,668,424,341,248,298,187,143,916,337,31,415,164,196,164,317,991,374,908,103,222,147,911,921,346,762,652,244,365,439,84,43,990,432,114,405,803,332,690,790,897,405,937,935,836,398,688,709,723,931,508,115,266,434,627,777,481,376,459,934,775,456,348,257,532,657,556,128,899,502,577,383,526,301,954,163,667,245,396,742,288,347,669,957,691,7,918,899,104,581,969,381,10,541,45,303,752,83,939,639,934,751,801,888,919,124,159,90,27,328,322,679,388,306,515,227,207,940,623,474,171,380,626,865,596,757,996,701,642,911,248,9,696,29,389,718,458,327,478,828,942,502,668,868,113,550,493,836,934,898,530,290,69,654,657,257,404,798,525,408,518,734,663,590,488,2,760,607,227,287,305,619,350,647,681,289,154,24,171,62,60,261,944,772,808,328,137,76,810,657,841,674,198,524,727,278,221,265,224,406,864,471,451,803,531,911,54,161,352,219,924,954,392,149,894,846,107,776,715,798,850,973,480,962,90,915,536,911,65,320,322,574,950,953,284,648,287", "800,308,210,443,250,388,586,821,828,978,372,508,716,141,989,657,226,596,616,97,163,952,311,462,667,720,933,496,79,748,656,350,874,40,296,100,581,997,755,609,290,862,642,38,461,178,993,664,320,476,536,833,169,36,618,789,870,1000,305,835,902,383,250,45,389,54,54,165,815,754,261,730,617,3,801,67,869,59,71,541,554,423,312,385,317,706,799,54,981,293,987,9,739,508,662,237,910,634,289,197,224,192,968,433,144,998,661,772,910,746,364,945,323,387,614,319,582,26,355,560,146,913,329,677,771,462,421,649,616,557,232,945,869,445,728,6,85,868,654,763,869,408,179,735,675,301,870,255,379,748,485,547,723,618,302,0,430,246,653,638,447,638,33,636,750,172,207,292,758,825,767,590,292,457,650,989,357,91,306,686,486,501,326,737,896,792,884,356,238,669,768,383,705,304,731,980,258,567,556,45,716,98,922,456,843,200,856,538,43,603,866,854,314,713,345,704,467,174,496,403,927,234,229,383,487,919,637,160,384,857,182,985,563,307,749,863,355,768,167,718,773,984,99,640,777,614,738,993,343,649,746,986,302,168,235,1000,502,560,98,794,56,144,473,171,114,341,743,135,774,460,208,96,260,865,286,220,207,462,195,493,16,760,609,818,415,863,73,799,964,552,680,433,652,676,615,151,642,283,241,781,225,991,804,3,349,581,35,455,518,606,626,288,740,156,624,770,241,212,271,526,588,97,286,1000,593,776,484,605,298,890,312,553,862,70,607,147,835,872,363,496,583,215,970,554,735,669,56,383,375,554,723,214,834,959,6,765,947,364,768,751,160,674,370,591,294,115,670,196,313,985,573,575,251,248,59,327,50,282,966,533,5,417,881,448,381,755,246,598,523,980,894,607,692,325,830,959,321,629,102,48,400,232,424,977,343,877,609,358,475,895,17,398,425,863,578,29,485,457,303,963,863,312,308,40,832,768,849,635,550,480,880,526,582,124,657,231,503,710,918,766,340,584,69,876,625,748,896,387,206,150,756,461,457,677,9,940,958,987,638,777,746,876,914,555,289,264,875,585,200,331,849,969,257,776,330,326,640,387,384,316,123,432,58,612,961,454,7,223,360,862,686,838,725,364,703,100,249,397,695,546,827,945,239,878,618,764,80,751,546,667,820,732,964,828,529,214,622,846,493,640,862,491,579,327,340,521,442,982,420,822,656,740,50,391,24,347,560,438,807,618,391,742,174,307,215,770,700,491,481,763,482,136,115,210,416,838,973,584,389,386,820,845,673,918,61,477,582,729,553,493,994,703,116,915,319,916,541,202,608,310,669,93,856,466,188,213,995,299,824,89,465,311,367,870,606,161,524,843,8,880,943,246,739,665,431,934,188,540,744,669,952,138,606,791,326,921,891,746,148,769,574,491,378,600,240,911,408,668,907,661,961,380,638,567,45,435,435,446,883,432,753,181,810,512,436,43,614,950,723,320,106,43,56,472,860,886,770,517,832,307,541,860,912,373,954,599,249,93,75,895,739,383,929,490,637,242,124,78,554,989,607,848,638,840,579,360,470,554,381,201,8,220,449,739,798,159,716,551,597,543,775,690,955,410,231,915,394,227,230,844,360,899,100,583,820,586,568,616,849,766,367,948,259,985,740,841,170,825,251,777,820,625,907,602,779,678,969,969,952,700,542,732,404,30,620,181,940,299,53,958,806,382,467,969,564,683,687,417,145,982,219,865,761,569,516,304,772,149,791,468,93,232,849,408,122,397,944,71,543,62,292,491,295,606,265,260,85,540,248,521,231,691,14,347,193,675,849,106,815,527,608,24,644,392,993,194,510,926,804,417,72,229,893,635,783,713,344,901,958,457,400,646,878,986,95,74,764,565,794,872,148,543,705,28,899,142,203,688,755,906,138,470,219,877,964,256,634,715,544,476,801,497,197,342,738,31,11,974,927,373,113,453,673,373,377,135,164,808,562,560,28,846,666,692,71,848,351,747,57,580,837,414,718,963,866,537,767,961,730,865,646,448,881,323,303,97,15,710,454,879,748,25,819,379,22,210,522,363,954,837,654,38,600,975,993,477,881,966,533,713,518,775,696,730,564,714,974,493,10,299,563,796,511,807,866,597,533,467,909,567,181,175,880,807,274,815,283,885,98,232,742,453,721,572,406,194,516,818,589,988,668,615,951,165,465,308,907,497,484,12,229,700,682,716,293,388,492,660,307,955,604,227,687,889,745,239,381,642,167,672,520,213,735,669,96,269,512,101,123,716", "503,254,870,592,183,319,909,398,769,487,459,436,683,686,563,544,73,997,282,446,554,668,244,233,115,307,32,205,274,730,643,630,804,324,929,707,955,507,931,557,354,813,609,180,176,251,596,732,299,578,435,150,414,747,573,470,545,307,914,978,306,918,932,391,169,751,648,172,207,890,791,937,147,133,142,416,31,833,825,109,473,917,413,9,488,85,786,643,77,662,138,144,658,756,311,606,525,875,701,317,487,812,227,372,202,659,405,981,461,818,755,120,600,276,774,223,887,844,651,237,130,457,223,514,254,571,229,839,765,250,807,894,938,495,408,974,861,102,571,780,692,951,540,643,765,576,591,767,805,914,281,469,429,329,599,430,0,986,519,970,36,608,406,929,997,46,186,643,123,282,914,507,972,81,3,740,39,207,769,157,751,641,243,264,63,965,949,217,655,290,488,429,915,332,416,598,355,304,790,630,679,227,728,20,698,899,214,220,278,108,581,182,424,890,194,225,65,567,432,430,72,367,699,798,538,351,184,445,43,377,542,266,489,281,113,583,658,989,301,653,144,949,716,456,496,811,336,937,885,588,382,234,139,343,994,642,147,313,11,858,850,41,494,572,556,471,392,362,594,902,355,812,755,387,412,959,182,550,396,463,573,16,867,15,514,450,407,136,52,820,399,642,302,77,924,902,651,281,261,862,597,343,194,289,351,172,110,906,992,202,689,19,478,702,616,935,220,310,922,336,604,290,864,786,168,13,85,785,767,301,554,453,17,610,904,147,699,151,342,794,657,112,212,753,226,684,732,985,808,260,221,523,827,528,478,736,322,429,313,853,102,191,52,804,557,329,253,377,54,806,422,834,836,998,372,516,742,882,197,481,94,705,983,161,875,922,492,783,458,711,486,426,531,955,255,858,879,940,688,112,702,203,682,587,22,689,62,699,463,978,482,977,88,333,446,363,570,426,86,314,228,936,277,985,405,142,902,902,199,945,729,263,962,549,729,310,232,393,220,749,465,167,295,696,841,792,824,167,285,28,700,27,745,48,849,713,832,850,70,675,509,694,394,548,969,487,466,842,151,439,2,242,904,180,325,512,843,470,877,923,122,620,411,966,926,404,946,303,309,438,424,128,56,855,861,529,315,430,406,987,597,752,380,936,944,624,941,854,235,303,97,518,133,646,706,695,39,799,985,234,416,908,512,447,866,294,806,242,361,305,412,155,227,742,458,533,457,144,881,515,104,573,844,638,379,338,558,856,54,385,398,177,192,676,739,770,460,63,910,177,38,915,540,667,526,720,190,540,289,599,893,441,908,758,953,511,597,251,226,448,102,780,811,343,515,245,981,732,812,46,388,774,986,990,446,285,684,640,752,768,977,56,845,187,452,32,546,563,259,412,41,880,619,224,666,650,276,465,33,920,680,270,28,488,634,892,351,443,884,91,137,937,623,898,405,417,711,590,500,204,641,983,333,56,565,263,557,791,746,243,909,595,658,9,486,495,859,980,710,384,720,965,904,781,916,237,67,208,465,298,582,544,603,536,625,338,634,562,113,216,175,262,844,76,661,379,187,893,711,736,337,152,436,247,123,118,169,595,238,542,78,704,17,620,497,171,956,950,504,833,687,331,237,800,751,520,66,38,278,912,957,965,910,167,701,45,538,780,885,268,639,111,229,470,539,395,919,826,624,591,734,555,760,320,300,264,338,543,486,64,241,82,746,353,165,263,306,360,60,920,720,529,160,557,810,994,759,328,823,625,80,528,698,7,591,530,459,250,372,999,505,744,737,981,251,985,661,558,245,294,890,420,306,614,857,895,552,128,851,432,274,835,622,921,405,756,774,975,682,553,610,52,153,455,36,364,258,109,524,76,446,316,716,715,388,129,34,92,221,109,865,969,720,341,390,247,919,893,512,731,432,975,892,461,828,537,916,710,861,556,925,381,879,75,170,79,885,191,280,189,683,502,286,893,865,732,196,857,498,823,917,826,625,28,842,228,280,117,925,202,371,829,45,145,130,12,902,525,308,806,583,642,768,220,926,588,69,360,931,540,37,585,943,672,144,827,533,807,148,349,318,427,40,481,824,753,784,742,898,241,585,940,588,691,613,332,704,559,592,713,521,240,442,251,269,423,381,112,103,357,589,946,803,639,186,539,983,521,788,278,300,821,828,623,518,605,446,86,355,213,444,686,577,314,112,621,323,785,342,817,51,581,411,877,777,619,904,462,532,963,930,793,46,679,790,832,282,810,349,896,130,787,769,252,129,389,761,787,589,216", "767,860,900,793,886,497,532,782,181,168,530,251,93,944,182,821,709,68,315,415,574,60,595,29,69,199,537,352,43,783,121,385,190,99,126,856,732,324,548,665,259,554,75,235,515,435,976,947,540,360,444,150,981,523,563,880,219,956,744,404,657,908,951,833,939,944,802,212,765,282,264,150,197,943,43,30,187,559,320,486,787,354,318,136,107,246,671,546,874,30,322,13,147,869,277,569,252,543,538,646,911,787,650,292,388,648,689,674,562,564,255,694,252,193,744,800,654,993,511,489,54,675,919,945,358,892,464,414,236,962,368,972,696,661,493,858,569,245,313,818,178,665,711,978,581,353,444,381,868,766,371,445,472,340,779,246,986,0,660,672,169,523,8,989,516,631,811,243,572,668,371,541,301,163,9,868,591,224,437,338,869,778,726,440,615,39,965,954,964,494,60,58,680,644,55,291,123,892,326,936,251,706,989,941,828,347,384,734,226,192,440,26,334,375,104,606,502,80,833,262,71,985,703,45,937,298,935,221,706,484,886,761,931,32,322,559,305,107,172,73,827,850,135,890,432,19,978,843,953,479,879,928,619,942,424,874,722,580,691,612,894,280,296,500,247,757,953,600,796,965,387,655,474,268,86,975,948,871,220,36,787,922,910,687,629,428,901,541,24,398,924,189,216,737,621,360,538,921,482,602,930,59,791,652,29,35,697,771,36,171,264,176,986,555,402,305,869,685,658,770,528,788,517,860,284,679,960,430,2,81,297,4,697,989,613,612,638,531,716,798,561,355,49,342,447,678,619,148,26,905,579,739,370,543,64,224,479,852,88,730,121,824,424,246,670,701,350,484,748,436,437,241,440,774,971,700,59,600,938,913,33,656,578,857,405,536,344,110,883,517,482,405,367,270,523,845,653,54,432,124,335,533,379,288,501,178,352,112,82,385,152,503,862,68,971,584,647,752,421,586,945,871,826,634,758,700,655,94,382,604,405,696,160,860,629,419,539,661,966,245,1,74,520,685,925,162,783,431,415,828,688,908,411,567,933,599,617,109,385,249,410,680,656,63,622,807,448,889,735,959,956,886,117,897,584,925,858,585,950,211,68,410,68,679,32,143,781,703,368,725,179,282,620,516,8,268,35,561,828,666,802,398,145,284,470,29,132,222,272,161,219,599,296,772,951,401,102,854,631,33,500,738,460,752,921,770,82,517,317,930,543,728,17,103,717,35,31,870,650,438,746,733,527,790,134,583,387,302,721,135,351,966,961,212,346,767,204,180,937,458,3,676,620,721,451,34,155,809,635,326,919,21,993,152,482,259,390,897,779,168,107,711,28,248,495,332,546,838,311,16,381,106,171,18,926,182,969,54,352,34,384,705,478,600,382,430,441,476,362,826,372,454,23,341,336,126,737,414,577,9,254,424,421,345,920,794,716,559,651,265,969,981,418,756,716,340,295,534,109,688,43,487,512,691,552,778,263,670,173,732,821,632,886,498,188,578,60,3,919,189,347,524,503,388,890,33,991,110,378,533,46,457,294,68,467,655,120,42,351,810,716,599,370,342,855,199,733,569,752,702,92,294,263,126,891,799,963,250,637,384,563,961,423,67,598,356,711,653,721,643,739,185,465,14,916,32,518,885,589,198,400,673,617,923,396,472,692,626,87,216,317,674,18,680,458,617,988,964,302,461,440,763,759,107,482,560,287,338,912,250,582,876,883,289,446,311,970,745,225,993,513,985,958,384,808,916,518,156,328,907,827,621,123,360,977,878,952,255,315,24,306,618,343,535,7,52,397,312,273,790,401,580,98,287,258,985,860,293,494,333,470,71,974,391,262,475,810,648,57,442,838,922,900,215,392,962,877,564,924,925,723,60,302,772,139,514,188,313,139,920,198,330,727,421,977,511,836,663,827,755,899,372,209,419,612,644,873,430,610,374,326,108,183,220,977,545,581,31,920,459,20,498,939,673,298,194,856,343,503,93,787,777,221,346,291,887,590,810,604,689,769,517,344,290,852,564,274,168,373,989,281,964,538,368,657,219,220,168,541,712,432,316,640,943,155,245,975,893,411,653,180,105,938,367,826,284,299,170,314,634,637,899,350,538,39,969,375,519,424,726,66,257,322,775,745,841,873,288,951,614,566,242,248,782,373,484,287,396,553,458,158,658,714,211,740,899,858,931,658,789,342,381,438,372,407,343,450,281,209,160,986,371,454,602,47,128,345,478,906,14,869,636,158,747,140,811,686,912,299,197,131,372,804,481,213,943,384,308,861,642", "869,338,656,781,464,690,443,166,777,649,857,254,360,305,88,302,953,843,903,668,166,676,84,798,303,654,61,949,3,915,318,311,232,655,256,993,584,867,808,68,936,642,834,899,136,978,120,223,518,284,670,846,438,340,11,752,462,988,681,247,561,462,500,27,26,813,956,507,238,992,231,625,711,783,158,980,636,854,982,227,930,24,668,575,219,604,6,280,306,735,780,44,995,275,413,248,614,215,279,372,104,564,204,480,28,9,391,236,915,184,452,490,14,814,131,268,693,184,951,426,469,97,991,65,844,909,942,913,376,228,162,668,444,298,205,663,301,475,592,769,439,958,358,580,765,539,992,672,404,767,874,852,584,703,287,653,519,660,0,760,391,188,157,221,86,893,928,185,128,907,435,536,526,919,479,103,613,45,340,58,394,453,654,825,718,297,598,25,2,156,522,986,628,16,675,14,719,188,764,429,195,421,930,67,227,129,52,475,599,956,798,628,500,787,856,785,641,35,467,647,992,984,792,553,200,238,346,391,554,471,895,843,41,591,474,452,196,223,608,24,235,407,851,884,111,468,245,14,507,514,812,921,940,553,12,899,568,461,564,645,866,158,886,759,489,105,460,757,640,948,359,269,14,954,377,982,818,324,376,166,482,526,704,144,173,96,789,47,908,195,104,641,339,276,745,504,210,857,877,145,400,313,866,142,904,209,65,949,340,500,59,678,762,949,876,406,357,622,298,890,552,278,78,907,332,975,251,218,669,771,810,151,779,378,490,784,134,390,449,196,153,221,882,197,266,228,220,284,289,408,757,377,102,885,211,642,696,280,444,439,956,398,653,828,623,592,593,579,121,496,455,595,669,134,716,585,158,264,941,112,201,134,302,401,99,303,189,428,583,135,681,142,29,803,43,501,271,116,841,854,452,536,285,582,548,564,862,461,950,71,657,552,117,895,488,463,387,707,218,509,228,6,974,330,828,421,104,243,466,440,961,57,768,444,67,51,372,16,509,359,944,282,794,941,331,280,189,572,508,873,78,595,888,472,873,703,303,354,156,693,678,534,762,677,268,99,257,122,738,832,350,161,665,600,597,324,877,36,518,927,76,465,212,393,383,514,566,445,83,272,998,515,402,389,18,931,635,175,483,108,349,966,353,485,839,174,765,298,833,35,547,360,162,781,895,3,206,505,587,120,136,986,587,18,189,157,95,186,760,896,860,380,853,594,364,901,766,245,810,736,934,766,58,596,376,749,83,341,216,607,495,492,174,930,695,33,267,713,348,295,439,510,66,238,935,737,619,94,707,950,839,362,93,839,555,487,930,433,343,958,412,186,521,434,446,714,729,38,265,820,850,405,387,847,575,541,237,976,163,509,917,539,448,324,964,225,961,769,142,116,646,476,869,357,454,171,332,693,26,715,93,804,555,784,741,957,313,294,275,689,401,692,858,802,862,250,585,902,870,106,493,324,205,591,643,841,371,848,146,815,535,725,225,153,97,339,372,314,538,132,623,396,258,936,108,683,907,76,494,903,993,34,74,843,577,734,723,333,96,810,275,646,783,654,889,177,85,345,667,946,982,744,766,211,329,994,279,123,665,188,835,722,356,137,919,43,938,768,787,343,755,147,588,308,755,676,270,721,786,580,653,720,255,608,478,207,476,830,207,856,317,674,44,619,767,986,326,160,467,433,190,286,11,358,917,76,928,175,552,271,991,171,475,990,116,773,960,744,731,756,79,63,543,461,702,349,435,923,741,955,656,86,733,550,801,837,800,94,613,325,215,533,843,383,125,204,434,712,839,606,404,925,521,585,267,123,809,355,551,146,484,242,394,473,775,298,968,314,347,566,673,915,335,293,907,896,592,104,150,651,648,481,800,87,673,890,380,207,346,120,246,377,443,396,499,451,737,42,290,558,350,322,585,416,810,838,893,880,908,717,677,645,49,345,750,626,119,295,714,461,765,22,321,794,376,534,635,126,770,991,397,543,108,264,28,737,54,625,486,750,660,656,436,746,648,856,553,406,100,110,308,772,330,638,794,119,416,899,194,928,735,134,416,150,563,930,913,906,869,517,162,270,191,22,826,891,394,73,362,102,771,868,295,135,28,845,231,972,862,330,958,288,608,773,447,874,888,196,419,688,53,323,635,959,59,427,132,226,643,152,701,602,801,395,290,984,290,245,342,34,47,21,544,433,473,537,307,730,736,534,496,819,50,125,768,706,298,324,296,318,45,562,250,539,762,437,210,907,417,201,969,642,726,364,89,656,272,782,968,327", "13,739,780,277,540,797,1000,274,96,868,541,252,919,220,858,270,913,946,701,284,95,676,554,779,349,721,53,209,201,654,457,220,467,68,275,481,8,274,266,53,47,556,721,757,809,154,306,986,93,576,872,518,385,172,771,8,201,982,30,17,137,80,882,314,9,23,273,740,88,726,762,915,885,431,306,293,693,468,645,811,700,175,523,398,94,99,525,611,390,479,663,328,555,499,398,995,629,980,240,562,18,543,664,390,792,547,381,204,22,966,26,750,898,554,820,593,449,177,827,98,978,236,90,949,752,153,612,814,559,222,602,579,266,921,690,447,319,615,410,728,756,42,381,409,455,912,889,971,349,883,492,514,883,856,837,638,970,672,760,0,102,533,624,509,277,227,849,445,304,402,264,488,940,858,679,724,846,14,777,431,376,661,671,42,54,767,421,659,462,334,589,655,876,874,823,960,118,617,644,236,876,400,200,395,370,898,467,100,665,656,943,475,675,320,295,130,228,84,735,394,743,486,841,975,999,119,174,306,897,333,311,261,923,296,337,429,460,294,623,989,55,828,5,63,39,594,718,475,853,425,172,239,699,996,723,233,285,562,567,837,113,495,968,313,720,284,704,490,560,53,828,569,352,693,318,804,310,85,758,11,710,532,67,716,766,209,711,500,996,584,322,941,616,475,641,355,663,237,418,382,925,634,483,172,327,506,884,38,976,379,57,237,387,310,721,510,347,871,252,161,265,595,473,822,930,662,105,616,469,275,425,689,532,711,954,637,198,40,974,777,897,712,369,27,874,113,450,682,97,263,629,927,332,260,382,190,120,272,943,954,813,866,211,816,970,102,482,24,428,160,271,540,999,554,484,339,154,262,781,649,796,641,874,237,171,786,920,263,256,222,759,684,530,434,478,3,141,910,323,455,249,35,94,113,839,149,508,763,462,379,518,656,591,905,623,283,964,836,850,395,947,715,31,685,386,132,842,147,814,450,108,665,478,755,64,906,111,193,680,146,569,812,496,710,320,196,478,397,643,909,472,648,622,915,908,259,608,582,375,776,592,431,825,585,487,752,710,854,684,878,201,122,847,960,448,531,460,288,859,691,438,51,166,65,589,401,976,73,371,418,272,426,655,503,915,880,3,446,307,630,475,5,11,599,436,293,46,629,47,913,796,978,161,751,63,15,874,194,402,502,711,663,690,68,200,646,691,374,679,203,453,233,140,92,446,730,756,830,110,70,148,229,344,782,333,300,500,179,172,948,492,436,729,465,702,825,685,103,634,12,393,26,310,389,613,179,306,139,453,558,930,657,732,830,679,782,512,495,389,516,442,932,236,473,435,481,819,637,112,54,380,313,240,536,390,512,411,464,890,377,923,823,616,342,266,852,422,446,857,318,527,11,420,649,628,289,545,415,731,744,48,378,3,532,613,86,229,140,798,241,678,189,681,571,854,335,438,415,31,287,567,922,442,162,419,293,886,680,150,320,951,710,117,279,248,436,85,252,847,328,752,908,433,162,131,338,215,321,885,852,625,284,565,115,21,155,60,960,697,951,600,878,60,383,475,511,206,98,942,183,291,153,592,697,262,593,666,646,568,243,564,575,457,195,175,398,203,31,809,346,859,419,818,811,824,708,887,457,415,5,542,579,199,768,747,499,816,773,290,790,612,63,765,343,796,994,469,85,476,524,710,569,612,526,910,826,17,163,950,620,978,686,769,767,65,883,656,133,796,358,729,678,880,188,585,960,40,748,500,799,145,972,726,766,410,819,880,525,767,428,390,230,577,597,782,939,39,24,96,978,571,64,606,87,667,440,575,874,778,20,640,236,657,523,583,805,462,526,236,7,720,956,924,880,758,840,61,224,194,88,995,933,627,930,159,490,285,409,338,726,543,751,30,623,954,172,433,84,382,809,715,781,921,661,241,534,476,562,795,537,609,103,502,268,259,206,649,794,252,103,292,738,701,672,949,444,233,611,593,367,926,227,27,636,715,328,930,533,122,837,98,806,238,811,595,681,625,106,543,777,654,150,886,872,980,615,684,101,570,314,649,198,815,722,513,148,780,366,512,451,657,465,693,573,604,960,42,225,868,84,550,682,190,503,89,461,920,546,665,895,332,735,258,466,124,595,56,623,650,850,65,469,712,367,8,755,128,666,79,619,974,9,901,796,507,512,180,448,910,451,931,377,487,210,945,521,459,569,125,863,855,202,78,865,945,996,851,461,292,543,80,481,335,292,560,301,173,506,373,692,294,679,118,694,981,182,511,166,742,47", "252,614,679,326,586,985,180,576,443,100,450,363,697,724,205,303,369,55,734,208,895,566,436,555,284,418,293,555,210,30,92,486,561,883,847,498,420,897,345,600,347,693,980,636,725,381,190,931,458,977,934,566,851,476,78,962,26,251,451,708,842,877,13,471,113,128,165,123,852,699,817,850,337,36,266,875,602,731,416,467,112,21,806,527,34,938,891,681,840,234,664,492,985,562,195,90,485,484,321,675,159,994,387,984,313,537,392,998,354,521,452,659,514,70,246,646,423,712,209,43,282,594,733,687,708,933,229,331,115,161,512,28,186,606,960,67,670,791,527,391,728,641,803,489,987,254,661,116,749,184,739,696,934,217,470,447,36,169,391,102,0,34,635,310,15,380,402,85,475,646,818,171,542,993,272,9,163,64,128,160,295,658,75,300,918,126,960,339,916,300,504,415,33,512,244,521,72,247,121,423,211,677,578,314,177,511,486,45,262,548,878,244,978,828,301,333,336,856,267,447,599,682,686,64,825,187,339,710,919,554,898,777,868,699,770,547,975,204,623,864,869,74,862,333,668,908,855,198,325,181,908,361,751,613,231,136,615,705,872,365,380,32,898,905,158,673,275,912,914,3,742,609,371,667,386,799,453,561,252,262,1000,526,167,376,971,949,821,602,398,729,514,39,930,69,34,36,731,970,343,852,500,996,754,531,35,521,139,890,978,575,766,436,642,193,356,760,618,260,909,41,65,223,683,945,4,338,444,927,284,813,977,842,346,493,904,152,218,995,130,828,980,746,701,51,643,118,143,524,334,460,991,251,54,636,973,655,309,36,108,938,578,705,333,92,976,929,217,131,111,211,122,165,41,324,946,771,674,721,3,314,624,931,502,791,567,919,173,309,531,992,466,424,783,398,626,248,793,429,991,739,724,760,376,986,968,428,664,79,898,979,991,996,809,524,643,278,156,420,24,211,200,107,545,60,587,646,721,960,147,668,744,755,679,515,264,150,517,470,833,515,399,405,81,71,262,885,443,998,480,700,686,348,398,565,223,702,951,898,662,534,998,97,593,955,69,560,625,427,23,290,47,621,41,592,775,886,629,22,92,94,941,999,323,803,779,178,607,681,235,17,168,725,268,240,281,643,502,618,993,305,356,505,784,7,584,327,57,208,676,675,133,504,81,743,476,983,944,142,329,170,578,316,990,624,212,550,533,321,485,630,332,524,56,805,368,748,297,105,625,468,132,43,399,987,360,171,753,659,971,667,760,725,235,474,835,570,161,120,713,852,49,522,779,659,512,449,650,38,978,969,963,329,355,628,325,378,115,366,877,532,607,366,248,157,999,779,560,401,420,691,193,784,474,576,352,437,143,767,861,91,551,5,829,114,405,904,561,390,164,820,158,50,150,771,488,435,330,175,271,288,174,484,857,934,251,469,598,472,239,491,573,393,939,490,615,556,189,467,824,763,815,621,54,373,937,894,14,440,653,613,989,92,210,237,923,216,975,351,141,486,227,271,667,474,332,631,552,826,786,403,811,268,824,991,17,897,576,150,839,72,938,485,624,719,139,246,14,513,216,841,14,104,276,62,183,109,461,954,304,785,209,855,511,180,223,165,219,782,813,895,159,557,29,834,756,217,48,674,605,413,580,113,293,840,197,847,15,387,589,768,188,5,183,449,670,541,545,182,628,860,137,302,485,992,61,858,436,634,57,862,547,900,125,972,835,424,775,279,344,681,48,942,630,993,438,578,871,509,403,672,223,872,958,925,446,856,841,555,459,58,529,309,141,895,306,900,889,712,961,407,78,339,162,981,786,534,573,625,948,594,346,569,831,334,224,499,740,875,854,186,189,353,359,182,704,272,446,964,757,679,613,747,927,590,747,127,756,637,162,920,832,12,684,396,989,943,68,62,365,10,554,738,816,466,82,31,733,683,410,577,21,836,362,841,929,524,44,407,599,79,33,529,279,728,122,52,919,417,318,124,6,78,849,793,471,633,280,563,575,905,442,66,878,279,742,633,859,551,393,531,182,247,887,311,52,733,139,694,433,692,365,858,492,136,111,426,33,12,614,453,928,918,766,943,747,771,97,746,499,375,472,605,368,939,712,884,152,799,464,26,514,965,284,622,594,979,181,896,543,107,177,13,888,941,682,500,66,973,542,653,259,397,886,210,701,63,482,105,475,382,676,828,683,500,268,882,340,246,488,143,666,236,98,702,969,974,91,784,151,31,592,376,459,563,700,772,23,497,498,548,776,980,46,13,929,698,744,115,283,738", "746,918,147,971,85,796,352,392,927,979,302,874,416,198,171,546,331,174,430,499,323,918,483,662,384,409,784,154,758,800,152,31,715,489,6,351,183,852,654,486,750,362,235,955,984,586,680,385,639,693,231,714,284,688,587,831,319,114,633,443,603,144,497,276,917,458,350,109,849,344,74,906,87,831,496,203,665,199,734,192,922,969,887,425,500,800,612,160,189,113,743,546,15,344,232,905,665,599,162,865,890,745,897,286,324,931,479,584,919,608,389,211,857,266,770,249,117,651,83,584,845,116,16,108,262,50,784,518,508,115,336,233,442,537,84,280,817,701,571,641,444,782,46,299,180,239,255,994,813,458,512,87,724,716,117,638,608,523,188,533,34,0,302,3,519,341,267,34,787,923,527,155,245,340,768,390,30,670,290,743,524,607,682,903,696,5,594,810,640,292,650,522,628,333,530,849,288,662,527,426,923,185,27,530,543,794,647,727,22,408,112,52,417,956,825,477,589,398,868,270,707,285,798,761,320,959,274,406,353,772,464,574,394,385,224,292,295,937,256,561,6,439,190,654,241,646,423,380,944,515,495,847,719,480,756,611,669,65,140,198,431,347,450,958,438,349,378,971,136,909,750,296,7,753,660,719,189,57,347,350,394,763,398,585,177,21,606,104,552,904,861,641,266,197,46,464,957,827,761,715,770,694,988,999,802,23,372,357,278,510,576,224,72,421,18,443,926,879,748,775,760,768,304,104,86,314,195,589,133,213,421,949,655,948,277,823,5,279,473,630,279,681,7,25,718,192,261,147,275,446,134,785,213,532,55,660,745,454,321,622,835,128,515,29,646,126,485,973,896,246,530,964,421,429,791,546,557,566,731,50,17,823,229,25,709,768,266,700,590,560,944,569,182,372,24,802,200,19,94,59,427,713,400,167,175,595,622,450,755,816,753,343,644,581,596,299,267,634,344,624,608,706,459,127,224,152,232,787,690,775,804,267,43,118,732,670,98,101,453,588,914,410,787,374,349,176,113,918,35,480,816,482,553,280,841,409,413,794,358,458,335,786,163,962,812,874,328,850,469,594,693,674,532,549,913,957,624,511,548,391,783,620,923,874,816,848,937,67,722,150,852,123,546,676,539,791,366,223,252,409,813,487,617,222,515,718,339,506,62,756,211,729,941,603,296,560,757,605,20,951,771,558,761,106,124,901,140,608,286,366,578,17,660,906,216,159,221,265,432,298,714,237,993,906,328,308,502,855,633,259,606,799,15,74,640,786,320,755,923,965,205,39,283,756,853,719,459,236,758,407,114,515,636,320,170,365,765,202,164,359,839,216,239,593,956,135,35,536,915,562,980,267,668,617,835,282,780,419,860,892,715,159,655,63,480,246,174,189,246,731,939,740,242,194,322,986,289,481,500,739,875,599,867,5,457,413,692,244,552,358,671,751,668,550,501,124,268,654,173,429,551,958,551,721,243,920,442,622,940,27,415,782,783,212,234,513,390,783,923,279,894,451,878,201,822,64,8,383,80,709,595,698,484,672,383,334,324,763,429,278,878,657,253,905,767,174,529,177,863,265,838,226,673,503,986,580,872,996,130,510,518,470,887,177,980,41,444,201,978,722,173,292,797,999,867,587,343,907,392,969,480,732,503,778,720,796,811,937,383,141,702,986,237,269,701,925,914,928,958,904,864,470,917,897,869,232,115,607,123,794,851,873,909,884,818,726,965,191,266,974,327,21,327,53,877,921,94,56,662,901,809,764,165,830,150,38,485,16,894,99,800,215,273,983,481,809,442,446,489,112,782,901,930,537,284,427,722,289,766,382,614,421,240,674,240,808,510,750,833,339,331,580,493,958,815,200,226,471,56,55,823,485,326,812,241,987,135,196,505,921,806,304,120,139,70,328,732,74,197,346,263,416,106,965,711,49,545,819,624,837,93,819,746,888,135,167,410,181,706,790,292,146,131,224,968,375,808,736,615,495,998,144,484,531,358,547,128,721,12,140,284,269,656,491,425,22,831,856,252,768,889,532,650,998,128,895,415,624,944,65,97,937,644,889,850,468,348,442,33,302,569,528,276,493,978,509,3,20,170,830,728,573,901,891,768,971,5,927,865,149,948,700,841,978,52,758,448,679,386,218,497,735,399,639,803,782,82,93,66,162,444,628,335,804,179,138,917,256,244,286,850,178,652,247,485,145,161,424,733,502,744,740,324,952,154,727,19,946,183,975,180,976,244,534,558,464,583,953,296,748,47,61,670,534,304,124,491,134,460,983", "6,21,201,673,769,96,740,929,478,942,879,2,372,262,21,429,737,651,311,376,257,86,95,992,126,826,234,958,436,768,794,477,234,571,247,245,193,965,507,656,858,889,694,498,818,216,666,412,715,578,941,633,904,964,430,300,296,969,358,595,358,111,994,403,1,988,929,302,793,344,702,478,749,880,234,283,97,864,79,24,787,975,268,956,625,85,597,191,696,933,968,334,701,62,988,151,857,133,299,928,945,706,858,352,883,590,619,856,72,449,982,21,365,58,608,992,510,289,701,389,96,700,694,926,425,639,319,162,925,812,37,889,479,555,491,327,32,60,638,230,711,53,795,746,685,264,328,782,976,652,372,305,997,692,732,33,406,8,157,624,635,302,0,682,559,170,179,793,801,913,629,503,538,884,480,439,249,700,769,644,517,31,358,480,272,87,45,384,945,264,68,806,395,974,922,984,640,451,124,382,199,886,612,79,145,748,999,963,28,564,900,279,199,587,829,989,897,358,528,299,551,637,413,382,174,175,146,876,602,426,892,385,4,918,237,649,401,37,286,698,37,91,325,314,230,956,795,374,948,150,488,986,408,724,609,353,727,536,676,100,547,666,641,650,51,755,874,259,206,718,723,810,883,635,963,407,150,247,137,222,862,494,922,372,240,528,768,970,79,292,600,459,451,914,725,615,102,140,145,263,858,271,190,331,901,209,646,856,822,601,123,998,107,413,453,772,817,608,215,261,716,499,775,263,144,864,271,468,732,729,821,715,450,206,953,913,811,892,687,772,920,442,447,626,645,930,614,44,781,81,922,419,277,736,289,456,734,959,310,727,218,522,104,627,354,406,169,787,171,70,315,280,738,562,864,323,638,507,374,162,540,275,19,192,762,862,763,945,658,499,262,40,17,385,163,676,512,890,131,902,526,825,987,489,350,745,270,659,384,410,631,943,92,397,570,571,220,509,923,374,563,865,337,188,941,452,485,562,675,926,163,104,763,813,938,968,178,805,941,999,864,710,829,817,586,668,271,103,746,757,354,107,360,588,320,957,76,294,332,748,358,27,533,561,943,501,979,958,553,180,805,299,65,25,770,653,52,580,471,953,358,640,991,18,883,871,835,816,523,872,359,910,471,148,68,501,596,608,96,369,167,87,553,5,792,541,517,779,726,427,564,874,5,987,674,135,580,665,38,494,711,382,172,481,406,847,612,405,754,922,587,224,899,581,789,365,730,343,340,519,715,428,177,719,123,657,512,78,103,934,767,356,448,881,434,17,798,598,670,469,953,989,862,1000,330,650,119,404,174,707,451,156,904,700,15,223,457,136,91,627,339,163,523,67,674,967,281,695,94,815,50,390,548,4,343,886,346,558,984,66,407,754,345,750,508,90,839,693,705,255,444,207,428,15,4,105,580,459,959,963,727,201,104,665,758,985,838,617,572,14,22,133,191,663,85,180,372,203,765,649,922,885,78,701,65,465,986,243,74,657,725,534,59,748,680,51,343,418,143,456,9,632,980,93,330,13,118,763,454,293,395,14,6,187,942,640,106,950,480,671,370,878,507,231,537,514,395,795,743,139,880,722,735,211,439,371,125,930,232,388,156,763,303,536,914,114,434,597,341,791,510,382,828,593,536,364,208,273,836,979,100,909,976,540,351,120,364,506,980,943,379,208,5,956,641,403,402,7,535,452,237,245,974,341,820,267,239,184,824,26,959,911,676,108,621,916,312,947,924,345,720,328,281,223,278,353,401,311,782,273,430,956,869,295,907,787,111,95,813,919,217,715,612,995,849,845,949,707,84,683,701,90,903,664,752,286,98,167,625,817,777,535,59,93,257,330,110,164,578,664,562,352,570,707,170,859,289,582,28,621,9,353,54,436,618,556,759,743,144,611,270,806,117,280,756,599,607,871,237,441,235,38,787,359,477,451,409,711,54,382,438,855,771,565,570,748,52,994,811,799,462,754,459,803,136,507,376,259,963,972,992,324,845,459,749,583,855,756,356,43,512,850,736,707,361,878,531,551,797,514,746,144,43,852,759,796,229,422,380,575,363,212,979,717,925,818,615,130,435,825,386,736,751,991,641,191,596,341,632,655,539,826,303,656,435,183,287,273,115,630,469,680,237,583,3,711,434,660,49,967,553,475,361,377,976,452,357,28,339,792,945,549,703,205,767,935,303,338,411,528,697,426,911,310,784,975,187,988,47,306,85,650,373,904,923,70,616,161,460,742,685,138,686,614,613,420,170,397,555,789,477,697,961,202,250,904,66,48,64,570", "436,493,135,208,967,484,341,16,364,304,922,925,851,741,76,549,283,469,6,498,323,951,209,172,456,962,365,761,141,27,422,535,339,954,85,383,955,614,723,772,901,247,456,757,357,602,3,749,140,37,402,221,981,976,987,411,617,563,173,916,40,306,568,659,27,340,391,141,161,603,967,736,692,896,186,398,544,971,521,974,77,880,19,649,333,692,214,480,535,712,663,57,250,353,646,160,143,290,885,556,498,643,141,323,38,296,623,332,555,725,746,859,157,265,515,758,326,131,729,573,847,208,119,184,661,518,992,931,135,288,422,151,586,880,751,536,156,986,391,32,274,177,467,720,753,398,437,715,903,530,100,780,793,697,655,636,929,989,221,509,310,3,682,0,900,967,760,768,517,819,224,238,489,864,363,496,368,675,357,661,971,157,642,47,474,973,966,222,917,157,193,29,995,725,737,930,611,226,868,20,949,910,190,501,825,874,366,177,698,573,825,59,701,453,173,337,869,247,955,783,189,441,896,692,49,751,834,750,611,506,889,903,142,225,653,486,49,87,426,452,111,35,913,918,875,795,526,127,447,303,618,67,650,726,737,321,705,379,106,886,37,994,314,950,487,498,885,990,197,518,863,95,430,898,491,395,183,128,150,446,610,488,689,422,173,860,132,468,496,387,941,708,798,940,870,534,347,684,557,352,521,319,188,417,444,35,572,460,506,931,318,931,471,806,317,382,105,736,943,78,147,276,914,718,120,398,40,108,326,677,579,595,380,29,911,553,787,201,359,126,269,528,649,883,262,849,121,661,696,960,274,203,441,164,293,492,794,965,353,739,673,450,849,584,999,203,682,430,221,878,279,991,153,923,776,102,92,190,986,427,120,791,563,173,796,411,17,152,878,580,833,381,549,130,145,159,74,979,640,622,125,53,409,59,592,303,737,362,419,14,416,946,1,446,100,355,996,108,246,280,501,821,172,848,808,219,706,56,671,326,900,680,896,689,110,212,628,866,793,315,815,615,136,196,631,605,728,962,160,165,856,105,813,21,786,870,104,969,152,438,836,682,302,234,214,622,235,67,467,934,478,604,557,111,508,924,230,270,134,772,674,845,622,577,575,800,758,928,420,408,653,501,697,657,687,202,580,582,434,880,791,11,609,683,487,303,634,709,69,145,687,898,839,209,139,534,87,674,290,828,643,41,658,105,689,601,758,239,895,851,694,9,522,787,142,759,973,131,355,369,823,815,3,748,466,474,422,313,964,628,965,720,817,552,143,264,240,114,531,531,156,980,303,310,604,745,404,587,775,918,506,344,35,56,326,270,367,875,608,700,45,947,739,563,683,698,29,382,139,284,260,848,908,866,564,488,395,19,615,246,20,423,282,130,819,655,684,65,158,880,562,898,488,595,841,735,597,283,907,93,930,984,892,994,902,649,123,530,269,472,920,666,931,832,281,384,344,613,624,173,722,373,398,974,466,75,578,858,497,693,656,65,861,168,886,571,110,340,925,145,654,432,772,436,486,607,851,70,446,57,494,685,792,458,772,107,34,241,278,37,354,6,391,783,796,354,840,823,294,773,308,974,219,251,525,934,598,65,342,273,913,186,770,548,247,453,441,532,28,788,505,732,531,81,827,609,842,279,745,520,446,418,808,619,623,862,208,283,256,649,527,298,998,948,459,960,488,295,59,822,71,578,201,335,438,853,75,249,608,268,491,897,991,554,484,690,922,457,784,741,127,68,852,420,375,42,246,495,995,635,421,90,940,850,399,535,561,753,628,774,668,761,270,682,148,762,476,805,910,905,238,648,639,182,449,135,361,888,613,366,506,636,979,703,649,697,55,290,307,854,152,641,150,946,460,147,549,221,255,266,918,911,553,65,466,976,659,283,567,9,353,958,89,803,688,993,700,813,348,710,841,454,430,412,412,704,839,885,499,915,30,789,882,851,215,958,828,454,509,961,801,602,420,832,514,824,837,182,928,28,14,984,35,853,754,57,689,775,510,170,346,700,825,681,733,905,932,657,783,365,515,906,22,229,681,430,87,445,636,845,997,787,304,68,928,439,227,456,398,281,682,308,457,151,631,558,334,483,199,232,739,202,408,678,881,311,472,13,35,129,968,532,827,969,706,762,825,706,444,695,8,344,225,187,368,244,57,197,749,45,94,453,993,875,875,603,320,61,340,165,614,472,630,749,649,961,386,578,609,977,225,676,694,415,601,96,656,277,819,891,533,430,656,388,739,614,298,624,974,718,669,278,119,276,637,112,400,570,596,503", "793,370,932,83,781,873,215,621,290,625,274,635,248,86,518,515,21,430,40,299,140,934,909,122,103,787,155,314,899,407,424,398,185,172,180,326,391,129,479,336,702,961,901,535,269,24,435,734,556,529,650,763,344,693,392,72,331,977,1000,410,282,692,194,87,132,853,109,28,827,785,248,15,911,285,821,152,313,370,297,442,59,902,434,765,628,737,344,682,84,689,954,601,226,124,687,847,948,15,463,921,76,946,979,385,389,732,523,798,158,262,894,925,684,880,784,431,794,184,893,111,216,959,651,889,158,299,163,854,774,467,585,412,989,356,766,769,619,862,585,999,855,952,587,982,774,220,612,168,799,497,918,471,527,104,447,750,997,516,86,277,15,519,559,900,0,920,614,201,389,800,48,367,610,540,845,948,891,237,721,11,563,543,668,942,938,669,157,391,591,194,660,899,49,409,87,623,831,588,420,613,406,157,750,392,999,352,23,363,738,953,772,686,763,776,800,199,587,670,731,398,769,46,621,701,445,423,253,248,914,284,891,837,810,467,412,600,446,57,944,607,250,21,786,338,530,276,960,228,262,981,788,443,477,179,391,668,302,543,691,485,525,494,214,297,497,682,908,894,289,376,89,900,8,973,232,260,723,130,262,475,297,276,209,957,416,722,170,249,81,731,728,55,249,607,821,992,571,259,789,511,637,907,516,818,112,26,899,158,173,787,801,486,675,807,783,740,226,616,383,367,761,965,80,913,512,231,684,354,489,213,272,261,584,274,656,30,380,341,629,566,975,475,372,818,423,722,191,269,409,830,936,634,27,677,565,982,963,529,978,449,537,1000,739,140,983,278,128,225,225,200,894,716,950,97,408,200,631,132,64,801,234,7,145,166,502,980,485,360,469,509,74,322,355,846,110,163,686,213,468,401,634,104,435,517,299,304,861,254,569,436,915,371,467,579,370,724,702,315,174,271,425,912,364,720,338,326,178,518,690,905,743,236,445,212,648,552,994,206,711,967,890,683,203,202,74,578,130,533,113,147,938,667,708,258,951,778,860,587,879,820,245,141,919,859,844,597,559,154,584,760,856,811,963,227,963,860,652,204,508,877,669,542,750,904,650,967,269,116,633,499,272,386,985,975,506,371,763,889,759,556,164,185,222,472,93,88,666,32,406,620,121,573,355,256,125,318,610,505,733,736,379,91,290,877,151,955,320,320,882,227,833,235,760,529,340,604,863,522,211,446,979,987,135,240,58,945,575,548,945,616,525,448,182,587,265,126,878,123,51,508,959,167,372,859,42,810,404,756,272,68,325,751,44,460,944,95,119,2,181,321,711,253,618,237,519,9,88,145,324,526,128,644,810,869,515,473,879,330,629,947,54,56,785,655,463,391,696,287,303,156,878,742,511,812,746,479,368,415,560,817,515,861,12,779,630,889,937,999,320,491,67,833,447,656,560,705,829,224,922,408,879,427,242,424,968,129,210,323,264,298,920,704,846,213,60,130,952,489,141,652,284,985,947,145,626,955,583,628,719,875,455,372,987,573,827,233,559,290,197,404,25,248,683,308,876,54,104,87,397,737,60,465,791,20,484,830,912,249,265,710,756,529,135,367,624,278,55,712,192,63,519,471,701,367,763,322,273,643,882,62,986,666,772,77,336,752,9,591,831,652,891,514,979,688,114,609,551,7,290,919,922,456,738,845,258,676,153,243,209,856,943,720,294,166,450,918,15,661,118,447,746,881,927,690,358,347,951,466,810,484,899,252,420,217,55,472,158,142,265,582,531,556,691,979,841,22,373,950,627,518,259,290,102,389,264,700,875,501,505,355,214,958,139,130,313,413,687,949,647,192,610,357,873,87,293,886,932,467,540,209,672,393,372,649,475,26,530,43,970,398,36,443,453,77,298,839,938,769,111,724,55,288,253,860,147,101,429,597,408,980,481,364,679,469,724,644,831,592,517,109,818,956,524,776,407,353,483,242,46,704,311,840,425,192,795,490,407,820,273,54,135,505,259,881,197,369,564,277,196,752,845,145,956,154,571,661,224,859,507,456,408,172,546,684,622,868,194,333,545,77,764,865,150,33,487,672,649,621,408,979,278,558,545,454,499,85,625,90,542,853,141,709,246,119,446,848,194,57,467,364,279,925,673,183,596,373,20,526,755,816,418,459,976,992,243,555,457,957,779,271,917,467,135,531,659,31,933,701,392,651,902,588,151,109,416,861,966,402,827,706,872,143,770,567,387,669,547,318,632,752,808,1000,349,897,705,601,857,838,789,554", "189,512,785,916,41,694,940,938,121,552,836,866,911,238,828,122,749,871,969,111,264,716,473,388,371,729,388,477,708,184,712,285,150,58,320,46,79,719,467,431,412,61,677,215,433,14,541,237,79,316,790,42,92,794,602,419,33,939,824,122,102,334,252,496,472,317,121,201,437,659,448,746,270,643,167,339,157,90,166,594,501,773,447,781,951,208,102,520,341,147,654,670,548,285,834,483,607,287,531,188,76,682,528,303,882,4,334,808,922,777,962,702,119,176,930,637,742,364,974,257,844,178,436,458,630,564,242,853,885,414,896,207,718,528,855,125,998,958,308,699,130,184,740,241,333,704,137,710,301,156,266,514,939,182,728,172,46,631,893,227,380,341,170,967,920,0,566,463,969,959,505,25,843,751,884,228,681,395,365,984,64,530,538,355,762,602,357,739,601,93,133,676,364,625,218,891,269,627,145,256,638,990,297,210,841,255,42,144,58,531,642,127,813,162,690,152,516,342,457,396,647,564,99,325,332,501,143,546,429,79,280,592,819,675,246,943,368,558,148,85,416,876,142,489,878,752,127,18,463,16,333,60,763,936,892,407,239,605,460,448,936,110,522,107,85,276,779,968,773,128,639,887,680,619,173,678,620,899,565,168,39,670,573,110,44,806,27,878,790,387,6,750,403,629,323,570,432,664,323,6,424,687,720,600,992,657,435,695,957,585,513,94,14,70,119,104,934,810,35,721,97,685,587,820,995,287,399,956,350,639,310,675,824,780,268,591,369,641,374,141,971,984,570,193,748,663,373,993,469,603,890,804,434,351,575,398,839,929,510,724,773,859,863,617,689,355,585,306,756,193,706,580,197,780,678,937,716,837,457,459,61,639,828,687,766,760,691,135,135,250,828,831,736,898,896,534,898,100,54,664,44,142,848,250,659,775,931,79,865,287,295,800,333,911,920,619,152,415,851,152,382,735,110,671,941,437,104,13,80,379,720,701,755,221,103,742,473,836,644,896,428,948,393,6,627,247,218,124,171,979,185,188,521,385,46,201,482,689,166,150,195,499,258,968,353,60,277,658,190,755,821,353,328,679,710,633,690,601,138,592,461,102,420,624,542,931,386,117,115,588,220,661,242,114,153,939,163,439,11,629,980,498,571,760,532,898,432,465,646,696,343,661,578,979,665,194,190,199,919,801,16,158,689,337,788,567,385,188,709,825,43,69,115,430,322,698,533,578,45,567,66,439,57,470,949,525,768,893,246,121,53,152,659,807,206,241,522,12,613,150,464,823,275,815,103,478,365,402,573,601,957,505,125,67,382,981,91,839,704,736,856,870,271,611,533,673,160,640,896,606,968,882,377,233,62,773,405,247,156,387,817,708,804,780,547,287,137,256,498,387,717,837,416,312,295,353,469,903,938,29,942,337,441,346,692,445,590,832,394,226,410,948,664,737,308,954,714,215,391,563,831,365,523,445,995,624,884,600,135,179,279,339,189,318,540,521,4,271,243,17,231,222,953,619,510,750,933,780,145,237,306,399,810,603,823,766,522,110,107,544,837,19,33,478,225,763,508,233,811,106,234,941,465,893,14,401,723,689,49,382,385,795,679,70,627,239,658,944,673,881,218,459,615,166,586,851,551,47,944,256,806,978,336,569,668,394,748,797,805,705,66,952,281,133,910,171,777,533,533,174,560,251,835,145,276,837,773,411,334,547,474,770,570,106,407,454,260,23,252,63,897,613,148,440,767,177,692,552,877,177,601,316,184,158,530,732,280,689,771,43,513,268,71,514,457,795,581,538,743,243,377,148,727,50,81,709,764,843,570,738,782,470,69,378,118,410,370,833,648,772,613,207,279,144,930,27,808,52,395,430,507,142,718,855,180,193,541,531,999,751,562,177,297,253,730,68,65,306,837,824,471,95,155,397,664,393,454,392,883,513,648,535,716,33,579,375,752,984,983,123,700,635,996,604,915,687,50,543,216,663,70,891,370,768,797,174,955,473,44,808,78,410,163,685,525,75,119,224,688,257,662,210,127,215,834,629,829,143,390,108,994,368,83,177,848,156,588,757,363,46,543,747,77,825,280,418,460,851,175,258,962,161,444,491,105,5,422,142,138,683,925,295,607,205,550,56,356,785,599,72,403,217,796,710,691,305,266,174,511,548,128,875,363,443,885,248,153,577,574,143,311,33,517,258,242,479,152,288,941,130,8,331,305,356,515,726,430,103,742,460,606,737,435,492,810,772,811,423,355,272,856,37,234,273,467,927,366,544,116,235", "926,817,923,373,271,607,618,983,831,300,203,371,958,844,597,199,500,815,578,476,48,990,713,677,936,702,439,278,979,641,858,688,739,523,545,522,970,958,222,27,187,195,505,330,177,203,678,299,558,369,718,622,547,11,14,857,897,435,160,444,813,357,687,644,939,456,570,973,427,409,423,790,265,160,658,659,900,787,957,654,981,715,870,118,436,988,791,436,723,709,704,468,861,440,749,978,681,716,15,57,432,417,205,911,215,536,132,327,453,569,379,323,71,305,245,591,502,773,339,642,30,144,817,617,313,957,874,7,266,65,410,470,967,99,468,405,893,915,279,843,897,147,523,336,990,278,461,459,741,820,184,219,577,422,951,207,186,811,928,849,402,267,179,760,614,566,0,576,135,254,969,926,409,386,329,276,349,849,756,294,801,691,618,48,993,177,619,347,526,303,188,150,944,494,436,916,586,389,112,326,358,943,107,342,770,993,679,472,767,629,163,564,729,977,33,127,745,922,628,76,204,370,111,126,129,424,187,285,102,891,129,782,318,493,595,217,690,885,648,243,137,890,731,327,7,397,200,569,580,159,481,201,874,520,280,562,756,329,8,18,655,777,453,944,661,997,493,618,793,341,773,214,578,882,623,832,515,113,143,204,542,948,197,446,76,264,682,339,155,733,225,140,927,701,136,566,903,972,697,905,627,769,622,820,49,269,432,80,496,246,659,449,450,904,402,992,772,993,345,73,887,419,270,27,788,106,848,23,352,418,19,206,147,326,57,237,774,979,558,356,282,593,146,425,717,630,958,476,940,460,603,681,24,695,696,124,799,458,250,254,115,777,337,593,547,752,773,820,873,404,843,636,512,985,244,989,683,671,529,938,91,929,461,201,281,936,967,620,693,62,171,331,749,118,167,46,438,474,819,423,685,91,263,12,496,57,498,739,705,261,732,438,510,233,339,175,936,30,160,854,345,452,482,578,660,914,588,786,336,482,357,46,271,934,854,691,759,69,732,578,421,934,179,945,437,915,382,691,663,989,894,696,225,271,571,405,46,739,300,866,299,267,796,559,434,16,238,977,637,861,40,667,434,92,166,326,642,242,417,905,432,702,423,263,915,689,511,659,320,985,461,214,379,459,628,780,849,296,605,389,688,811,462,171,774,182,657,850,179,782,64,818,257,763,831,884,555,132,792,302,449,45,150,577,869,809,765,126,464,969,488,634,805,944,697,2,769,662,9,874,879,487,525,67,474,340,954,793,138,956,204,55,185,730,311,117,510,732,536,594,254,783,275,877,722,349,656,610,703,71,988,400,56,712,542,785,102,366,673,270,836,787,160,190,118,984,554,654,337,199,302,942,259,237,241,328,12,968,684,933,427,845,619,822,859,147,328,658,741,324,509,221,126,269,259,783,61,72,524,328,757,913,938,804,948,216,141,194,712,582,979,154,20,655,875,578,99,583,532,515,330,998,745,408,84,162,638,324,689,507,987,685,467,166,145,790,233,287,591,892,985,743,107,550,857,753,798,71,870,651,764,280,935,535,712,182,927,170,947,528,48,839,138,506,629,760,419,246,478,183,201,329,909,773,65,663,588,752,844,141,663,194,756,262,53,897,640,944,73,758,481,368,597,990,95,584,632,173,516,81,792,387,985,3,983,461,758,947,671,564,89,945,470,696,589,732,213,31,296,748,785,324,474,110,135,769,221,851,330,170,150,553,187,344,775,907,475,185,963,548,653,83,775,514,729,654,299,897,575,775,41,449,298,708,774,327,171,898,257,634,459,891,584,831,714,36,87,561,262,928,572,563,11,50,235,137,591,788,524,279,361,858,640,787,61,72,180,848,203,926,382,671,806,855,536,232,943,850,488,196,698,655,164,79,860,270,666,694,388,783,963,669,578,543,530,155,667,550,387,427,238,54,455,309,689,322,405,422,627,848,951,882,454,659,326,66,88,624,849,268,883,232,176,218,244,398,604,474,929,288,479,16,437,673,324,339,484,244,728,691,883,479,14,770,12,878,630,364,20,598,509,720,737,956,663,490,284,836,38,586,143,185,874,569,424,401,943,223,363,462,487,802,703,332,37,380,109,93,879,447,690,647,292,964,620,491,476,116,202,913,184,1,546,202,843,61,599,354,759,79,527,928,519,68,274,829,842,780,198,136,604,182,484,852,616,396,662,55,790,71,428,212,13,29,437,62,624,226,530,799,969,539,779,486,745,902,387,650,691,729,643,657,39,833,850,528,616,461,722,605,894,482,47,717,821,83,981,42,173,52", "442,584,240,413,412,736,140,853,447,340,712,982,927,624,754,867,570,958,562,811,38,924,662,157,329,906,16,213,627,90,906,98,861,476,200,660,229,315,179,552,114,6,281,428,910,459,888,512,551,319,948,555,68,869,829,28,838,850,187,446,684,239,298,697,246,55,560,885,17,697,172,90,755,735,419,698,602,383,652,795,917,198,973,549,494,445,603,293,849,515,367,252,677,304,593,20,45,449,526,966,317,757,685,124,398,922,137,769,191,788,931,321,72,399,458,76,193,255,657,859,398,167,257,596,868,511,248,661,644,815,562,216,764,312,555,859,255,52,616,476,882,488,41,979,896,942,95,29,994,900,422,823,482,927,630,292,643,243,185,445,85,34,793,768,201,463,576,0,198,972,269,468,73,915,300,856,200,559,529,524,205,598,208,347,178,66,750,579,729,763,307,223,351,860,945,340,831,765,218,519,570,316,762,428,531,74,877,915,781,290,891,237,538,854,688,545,777,796,548,88,812,410,533,751,473,589,908,719,188,79,179,827,398,330,7,597,400,231,683,422,517,307,512,778,743,148,22,233,749,795,917,754,693,854,933,3,443,809,623,627,581,532,93,674,722,872,476,368,913,265,45,162,946,541,238,972,405,356,701,176,915,278,912,644,301,374,821,147,820,241,856,926,517,477,162,258,200,832,975,388,926,861,702,818,97,330,628,617,462,131,247,576,457,460,229,145,949,411,406,340,215,803,177,253,821,544,827,81,878,917,121,923,187,913,510,627,209,8,300,193,51,673,828,823,873,190,118,341,770,16,932,464,62,754,254,521,501,602,424,587,116,572,889,350,213,799,590,868,580,470,489,465,807,260,700,772,518,207,572,424,298,4,670,998,466,911,976,777,498,958,791,524,13,566,953,483,282,383,775,291,927,383,12,845,678,887,161,586,502,695,29,624,540,768,162,739,438,913,28,407,161,183,60,120,413,872,874,314,164,530,599,852,7,626,833,101,635,230,322,800,936,945,116,351,365,43,652,149,287,286,927,461,921,265,553,240,908,328,640,417,993,317,136,698,926,195,810,381,363,158,502,682,725,203,657,73,168,320,343,885,881,326,604,184,873,291,825,235,114,810,666,952,713,13,752,131,64,36,145,224,872,408,120,953,699,611,661,105,152,505,93,430,69,950,832,677,515,891,747,922,297,356,1000,230,319,463,881,68,546,47,496,562,922,302,324,623,418,867,336,368,192,615,299,127,115,931,733,860,347,209,874,220,440,87,219,380,179,972,948,746,257,969,390,123,917,443,462,89,284,907,572,143,81,25,37,432,876,291,521,142,554,254,515,21,388,618,842,664,830,818,930,631,358,30,447,746,202,200,323,675,37,917,462,76,2,454,476,875,569,196,794,626,678,383,894,898,685,958,260,355,55,637,710,402,626,231,491,437,960,108,148,253,366,365,737,104,536,124,718,793,319,680,533,631,831,570,594,3,351,14,851,752,297,91,868,948,265,787,645,742,795,686,8,303,869,915,887,449,438,440,289,775,796,116,787,558,886,160,321,325,464,795,381,48,13,808,583,998,399,862,734,823,753,156,169,427,820,137,506,975,382,702,918,943,155,175,266,269,125,144,656,593,474,722,442,680,970,899,421,854,845,419,458,270,566,682,40,247,279,255,764,533,18,620,995,127,304,471,593,730,513,931,916,947,937,155,50,314,755,262,451,742,928,487,71,696,75,567,259,686,220,563,59,101,973,466,772,577,433,342,336,982,389,784,930,719,661,331,496,953,354,302,473,124,56,356,14,946,815,351,650,444,275,767,690,414,209,762,757,671,235,74,324,290,363,177,521,801,673,273,939,144,880,515,737,206,731,694,999,966,292,86,695,969,742,307,526,929,984,18,22,655,315,570,398,954,968,591,481,170,801,392,492,48,674,255,777,237,595,725,376,411,275,543,161,496,428,924,918,193,718,80,81,176,173,483,505,730,803,507,189,214,175,798,453,974,92,608,408,733,389,808,932,99,485,864,637,123,211,544,133,944,163,410,919,771,242,421,820,610,731,741,826,965,898,823,127,983,170,585,76,395,879,264,38,659,865,880,157,598,886,367,988,532,434,598,718,920,505,930,168,897,438,672,244,837,683,228,801,860,229,606,221,524,93,738,878,178,696,281,990,813,845,593,312,523,397,464,286,290,693,56,968,192,325,717,195,26,834,753,934,66,644,200,127,149,292,848,308,638,263,715,953,432,420,952,257,583,936,938,191,22,1000,445,975,866,58,831,392,392", "465,872,390,642,854,713,760,129,54,275,257,618,471,344,817,262,703,754,77,985,335,530,326,318,666,600,15,435,280,637,65,407,406,507,90,303,928,57,227,865,433,895,109,608,110,250,803,992,220,3,194,125,413,107,554,198,457,323,770,408,227,873,174,154,334,538,745,993,8,441,923,345,497,289,910,763,903,820,88,548,647,361,550,370,317,54,693,321,142,194,905,234,300,455,680,973,971,725,177,153,151,437,112,501,309,37,330,987,417,548,373,573,848,155,547,35,452,411,459,933,196,393,639,812,382,775,193,6,648,470,153,105,277,18,954,437,156,164,556,985,922,272,381,566,65,233,195,719,915,545,710,918,995,706,957,758,123,572,128,304,475,787,801,517,389,969,135,198,0,64,153,270,883,818,408,696,590,317,834,745,465,29,91,346,233,87,47,641,88,890,730,292,536,840,421,646,362,133,50,341,346,470,304,989,60,55,924,859,528,341,237,530,106,495,358,598,370,722,813,710,594,179,805,50,540,372,622,797,296,306,544,62,920,823,783,895,149,815,211,783,27,499,777,951,826,848,161,738,722,501,354,685,700,34,561,764,273,313,301,26,651,364,121,624,480,607,972,199,282,955,778,358,583,891,385,319,548,854,90,533,800,480,701,49,431,76,622,15,11,786,966,227,905,701,113,110,474,67,978,397,642,507,789,139,533,546,76,507,899,707,906,447,638,12,812,618,752,639,740,262,133,158,374,798,532,555,542,80,494,616,18,627,396,454,913,473,952,655,159,211,928,925,294,215,748,991,320,562,608,869,656,270,216,793,14,366,576,456,303,990,19,97,476,454,554,499,601,635,317,430,683,18,88,484,558,773,658,282,483,82,272,794,986,99,40,30,121,922,276,833,638,99,459,274,148,983,758,5,937,687,399,750,281,100,982,106,637,894,344,221,179,528,766,347,629,244,490,572,453,629,921,761,293,619,702,636,573,33,501,995,220,698,114,423,964,151,387,432,14,161,109,471,670,910,79,654,323,880,993,17,670,62,695,349,591,908,635,850,798,239,634,704,874,699,122,546,380,906,709,984,461,296,822,595,778,531,395,680,64,356,115,335,377,502,674,206,901,638,556,393,622,674,552,432,781,693,963,704,117,156,692,280,420,149,408,694,838,386,893,683,186,509,484,636,840,580,811,458,152,156,411,863,12,870,507,506,823,645,305,290,448,542,175,769,291,504,530,10,737,875,720,960,156,820,980,80,244,100,726,286,634,224,809,752,581,280,973,461,761,586,696,839,109,417,995,424,307,913,412,142,236,447,537,164,395,818,552,709,493,450,903,211,788,56,499,344,121,790,436,223,430,873,1000,352,637,883,134,408,544,466,76,364,23,895,104,106,719,226,88,984,920,920,235,149,934,344,793,370,887,580,263,8,328,295,885,767,453,949,233,547,544,663,474,973,656,450,845,150,897,366,496,132,429,747,265,258,22,899,786,242,190,357,458,582,58,63,634,957,831,59,523,564,287,390,889,277,145,616,45,443,131,393,622,913,942,355,348,687,501,139,318,347,830,203,505,163,182,585,275,608,260,281,924,304,880,146,977,694,72,895,642,794,216,298,855,156,351,118,683,458,175,281,187,855,126,614,645,394,300,254,69,74,340,955,423,204,457,694,448,345,400,688,90,972,18,967,800,884,638,562,229,230,615,279,180,24,994,485,372,636,999,825,320,253,482,868,216,410,423,770,551,723,899,962,545,971,43,630,520,425,207,865,641,888,790,26,479,857,808,516,130,870,500,103,631,98,33,535,698,737,807,904,531,180,630,440,5,573,282,14,355,564,83,264,186,828,907,842,970,491,273,403,950,394,263,896,889,312,985,275,825,250,508,298,878,938,927,219,727,971,916,964,111,618,111,257,789,715,600,324,351,448,477,67,103,997,490,45,630,552,662,742,812,179,353,458,61,339,798,678,505,109,447,785,661,124,286,66,318,253,84,120,977,605,628,428,146,850,153,476,740,320,230,236,146,225,551,558,107,850,538,589,215,246,23,804,575,337,864,445,956,728,245,744,495,745,396,527,105,443,206,250,176,6,299,519,997,82,177,15,998,318,590,226,610,471,405,632,258,701,916,926,321,545,441,14,633,871,448,286,423,279,881,463,173,833,958,673,98,512,245,155,633,850,602,917,920,367,248,335,448,869,345,117,253,918,331,407,498,514,920,656,368,99,820,218,443,653,847,443,634,484,733,338,882,880,387,400,622,588,684,226,939,804,635,577,643,983,788,409", "225,221,636,157,961,371,427,116,76,986,866,354,818,283,721,296,271,652,279,132,333,124,509,482,348,679,217,600,645,653,813,710,895,247,84,37,217,675,619,545,472,414,478,139,848,873,649,876,544,254,636,298,952,94,981,297,177,102,720,586,268,901,552,878,184,541,388,241,11,513,94,252,463,840,599,836,845,60,120,316,614,816,144,725,457,307,949,431,957,925,883,918,215,573,592,291,849,119,68,708,962,659,117,232,755,919,283,433,378,718,570,353,524,32,872,893,107,215,21,630,35,638,173,187,594,769,242,199,299,739,696,31,836,554,703,871,938,208,759,734,10,324,831,331,35,621,892,469,33,348,796,345,318,320,815,825,282,668,907,402,646,923,913,819,800,959,254,972,64,0,327,944,277,707,5,885,775,158,501,181,734,532,787,186,528,83,696,875,230,690,318,45,349,650,211,844,735,173,482,811,370,538,724,17,86,333,116,12,677,847,220,261,373,912,931,506,910,999,621,17,124,729,557,186,224,234,532,427,901,747,138,897,730,129,933,419,741,352,176,202,641,416,259,668,162,377,606,573,87,824,530,282,835,635,654,146,309,218,340,314,522,998,65,2,399,348,437,969,461,839,700,499,247,480,865,771,899,99,885,560,260,893,535,14,622,535,638,909,430,487,662,371,849,27,349,361,151,620,97,732,419,162,95,352,792,434,96,689,542,392,653,774,292,527,10,86,982,331,302,158,383,260,762,253,612,30,875,535,214,296,474,178,973,582,637,817,227,474,730,361,781,428,100,825,523,844,802,60,832,790,51,19,325,995,811,772,13,624,176,269,941,454,967,272,927,863,879,799,230,852,222,233,484,646,341,215,53,707,657,372,255,381,855,900,157,725,690,313,836,937,621,337,961,75,152,797,583,420,931,855,800,685,997,47,598,863,548,72,44,60,903,103,422,212,605,294,591,280,251,21,105,499,730,433,509,579,567,769,144,800,642,889,481,944,636,523,302,670,964,340,501,599,129,86,738,694,775,770,436,886,37,421,138,998,33,385,136,200,981,625,528,857,852,486,321,171,207,62,949,81,515,893,239,708,169,176,26,571,563,796,636,625,7,738,335,700,393,515,445,253,714,722,180,153,32,198,639,200,670,127,245,952,779,289,858,994,303,552,173,839,76,560,702,77,202,188,81,656,938,926,635,575,539,546,807,176,434,9,87,535,644,121,840,690,381,133,697,757,34,710,547,704,25,327,537,653,635,12,708,577,978,494,813,698,149,54,518,514,153,899,527,907,998,577,763,563,902,183,558,966,741,36,449,510,293,527,148,871,64,931,296,280,601,913,964,194,785,666,417,758,134,32,382,914,740,850,879,710,694,114,241,243,321,958,16,126,450,733,973,199,15,327,152,111,636,79,443,498,18,334,623,632,837,562,35,473,26,354,343,526,667,691,685,101,115,171,609,641,194,187,968,157,427,510,23,444,693,388,348,71,935,253,247,377,900,660,811,717,567,884,844,175,238,610,615,605,838,134,680,589,504,998,762,580,796,194,388,278,54,198,491,470,902,729,235,788,491,478,579,161,175,443,162,177,368,344,508,949,968,647,266,338,141,69,144,670,45,932,455,124,678,712,380,145,179,966,928,211,856,170,760,846,513,322,789,978,10,47,965,759,802,551,977,841,23,980,926,210,64,215,182,150,989,789,668,85,379,869,775,383,646,569,340,358,528,762,575,903,180,482,573,568,368,350,533,165,66,494,129,493,610,41,599,410,200,252,58,681,530,599,578,255,611,56,519,571,610,379,391,493,989,664,216,342,580,220,632,299,919,943,272,877,393,729,378,684,903,70,32,79,972,756,761,664,793,405,196,763,534,587,40,317,131,675,747,985,699,57,526,665,138,55,648,250,466,932,658,28,333,242,145,662,576,887,121,325,384,115,171,3,928,816,493,553,615,74,331,412,941,848,442,741,21,275,327,166,523,892,793,265,711,555,788,697,678,96,939,604,144,892,643,152,713,989,572,827,316,799,681,635,6,623,537,272,265,781,474,67,159,449,810,178,880,99,84,982,739,893,144,433,160,727,760,533,10,362,170,335,977,74,100,538,536,109,401,874,950,946,425,913,164,698,234,500,14,35,700,422,120,606,460,959,171,506,201,90,961,556,73,153,467,563,239,534,328,724,104,815,13,662,910,760,519,354,46,441,36,252,504,374,907,989,450,804,234,548,325,366,828,453,777,30,106,929,526,301,871,676,483,183,846,11,915,79,793,679,401,525,907,532", "573,184,534,212,528,559,228,868,45,223,581,97,648,813,957,754,59,816,84,844,148,358,370,881,667,643,974,339,784,291,283,949,234,765,161,222,238,583,442,106,868,687,337,653,188,932,94,89,269,767,354,460,730,525,945,203,686,762,510,901,595,691,78,141,928,309,323,813,488,308,129,969,683,682,29,196,693,437,920,496,41,373,260,396,813,806,118,646,270,961,106,816,64,674,556,34,437,917,716,346,87,301,119,360,575,791,581,936,32,462,160,547,275,945,53,857,473,512,234,384,576,964,831,606,472,915,810,269,977,834,205,972,310,874,598,230,209,26,164,829,341,57,641,809,733,649,296,894,743,527,183,968,888,542,939,767,914,371,435,264,818,527,629,224,48,505,969,269,153,327,0,66,476,45,857,582,690,849,521,462,606,892,259,528,798,798,616,896,539,468,777,173,756,839,328,633,276,50,788,441,277,215,288,947,849,443,643,360,867,305,348,239,527,508,548,553,399,319,719,805,20,766,835,536,395,55,101,776,98,926,23,64,704,624,350,265,659,546,608,975,181,255,461,775,549,694,427,65,475,162,844,666,802,468,793,214,449,119,588,174,562,835,158,660,688,73,187,489,114,216,832,184,637,195,706,989,987,61,60,204,666,201,589,273,592,569,598,570,57,680,891,618,324,993,972,574,689,200,762,143,859,552,456,53,168,258,677,28,884,716,157,716,350,708,539,68,683,561,476,576,146,427,617,722,572,873,155,892,464,328,33,162,700,591,967,872,554,830,776,168,655,350,88,84,941,869,825,803,56,757,656,364,132,229,345,764,155,57,76,635,95,744,676,290,166,18,527,938,405,702,140,522,818,679,34,342,354,539,377,13,443,201,582,883,865,736,729,638,930,791,109,447,227,580,134,807,555,272,264,95,968,294,697,426,224,344,376,31,349,371,568,590,375,713,197,486,827,393,748,82,500,431,58,922,240,706,78,856,903,50,630,102,987,132,744,418,528,718,381,99,12,398,750,357,274,484,376,101,431,498,215,155,933,700,517,785,9,792,536,124,761,722,173,904,194,805,438,495,695,176,617,783,141,334,493,850,901,798,953,817,44,831,782,492,430,319,878,61,529,390,457,186,34,659,989,290,123,828,425,729,521,348,989,512,953,566,151,701,727,505,417,787,526,515,453,325,788,756,586,58,773,843,339,100,248,489,914,589,190,715,64,707,334,612,958,856,134,398,651,962,658,332,723,631,605,10,896,66,826,410,177,791,244,746,766,265,945,686,449,362,503,450,939,117,592,32,88,320,498,461,523,588,26,789,648,518,279,655,965,243,641,537,153,935,151,48,529,798,446,219,968,195,609,702,569,74,542,627,1000,979,604,227,547,240,998,330,617,298,91,937,101,3,278,169,403,208,833,409,740,901,330,165,692,149,950,991,546,476,416,136,869,513,221,150,287,231,319,90,788,447,223,190,574,972,380,574,664,170,212,204,938,67,184,817,336,75,964,689,296,853,503,516,60,995,28,416,629,610,802,369,424,453,583,230,781,209,222,614,76,365,719,823,110,106,437,569,982,916,275,603,841,127,910,359,321,367,898,788,662,513,705,910,335,765,337,579,592,250,604,942,55,905,920,117,44,487,99,950,173,691,598,697,508,603,836,750,648,652,202,966,963,860,701,752,187,540,826,184,623,439,733,853,472,559,142,204,102,435,32,721,448,274,727,698,297,459,613,142,317,274,416,615,298,819,463,910,362,333,805,673,572,915,81,952,586,374,196,773,7,984,198,237,857,823,844,857,319,202,429,319,324,286,57,493,554,77,372,231,341,635,359,616,543,748,999,773,291,285,737,660,502,697,899,781,736,166,266,222,767,974,445,800,680,835,263,352,606,976,826,978,19,444,643,207,820,873,708,519,127,72,804,13,486,790,947,349,785,700,919,99,694,784,801,22,69,556,226,358,415,617,745,992,578,299,780,441,822,438,590,251,128,984,908,58,7,929,97,482,744,352,632,981,572,494,117,390,708,607,79,379,992,521,586,343,549,447,565,925,867,527,968,301,213,249,768,646,860,503,195,378,161,45,107,941,318,826,701,864,175,416,882,426,186,846,83,966,150,70,817,537,651,68,659,378,751,67,851,212,336,727,636,771,54,804,63,175,602,276,615,114,848,597,192,581,326,62,742,139,85,34,949,377,216,848,924,888,145,935,96,53,925,192,447,949,351,826,572,386,7,908,142,695,427,134,193,24,274,277,88,262,401,788,851,502,581,831,595,201,330,155", "379,321,846,366,724,476,771,436,195,626,518,473,640,60,126,34,350,936,595,395,608,928,814,164,346,976,171,173,743,579,773,305,275,617,275,413,856,153,22,766,402,987,629,119,661,820,961,160,290,798,817,24,897,732,545,109,933,987,373,837,387,97,419,711,343,465,461,322,851,343,625,326,7,339,999,333,622,423,123,292,903,132,255,173,536,277,283,962,509,725,915,680,505,52,510,517,250,430,360,127,964,8,669,195,454,348,615,61,217,940,245,659,910,326,987,859,839,31,238,283,494,890,885,992,226,10,247,628,805,894,341,755,892,720,30,967,272,734,716,350,450,474,815,437,562,220,960,808,909,180,578,771,110,412,334,590,507,541,536,488,171,155,503,238,367,25,926,468,270,944,66,0,868,730,795,927,8,596,499,172,956,394,154,879,320,684,928,300,392,588,431,717,342,392,317,217,540,79,953,285,552,834,662,402,705,317,563,923,428,441,817,474,838,927,401,513,938,845,500,833,559,785,675,783,964,446,456,283,960,615,507,463,157,694,255,514,393,708,764,771,541,873,89,154,649,345,892,38,745,20,730,433,928,455,390,212,151,57,237,739,614,369,200,186,255,549,186,481,93,83,831,48,888,95,330,286,326,288,10,134,489,813,454,52,132,544,551,164,507,326,678,964,114,816,214,345,856,205,281,368,536,643,416,366,692,427,679,199,521,348,503,243,936,572,432,586,497,712,10,724,169,426,3,183,374,169,74,75,559,941,580,375,66,377,166,954,190,954,82,918,167,640,893,232,604,95,737,751,695,143,29,841,298,309,355,84,264,386,748,764,281,310,112,58,134,252,30,275,328,198,449,113,995,821,266,272,419,754,899,815,59,911,502,595,79,392,139,933,730,627,780,375,233,760,3,263,772,891,628,346,658,695,542,993,656,385,844,880,642,601,115,945,701,494,467,41,760,663,980,627,509,923,440,593,492,485,731,317,34,739,993,573,408,302,80,46,304,229,156,638,462,282,308,943,300,831,162,720,142,937,603,985,462,871,144,759,134,815,103,819,867,52,590,87,727,437,226,476,479,83,956,366,684,474,207,255,211,986,889,811,692,621,667,505,358,370,859,772,192,531,76,406,781,404,824,849,59,645,8,327,776,926,417,912,373,754,318,401,887,615,26,799,193,782,253,553,839,991,158,504,861,419,198,427,359,909,118,833,496,857,59,176,699,112,293,187,572,752,813,925,579,949,816,882,42,831,720,994,319,325,797,713,605,13,868,360,575,481,176,750,506,661,973,108,984,287,778,615,168,391,412,683,848,594,902,68,392,606,419,705,554,279,739,515,916,720,531,86,426,568,161,295,77,960,840,417,722,239,670,863,55,812,317,626,174,382,249,910,518,488,299,778,523,982,142,416,999,879,418,406,186,211,97,670,492,987,879,373,261,181,435,849,129,870,778,60,221,641,3,914,930,308,679,234,827,760,886,203,348,676,896,848,82,586,894,386,327,704,846,897,266,900,43,221,172,386,134,250,713,234,522,223,671,696,109,559,506,554,180,189,494,233,622,578,725,781,594,754,79,531,87,25,118,251,463,592,541,916,589,715,333,88,981,692,46,121,529,620,759,746,57,199,831,44,711,35,587,853,68,556,131,206,770,780,276,500,15,202,843,603,343,429,852,236,244,638,705,430,573,537,561,985,433,899,425,913,136,619,589,401,558,374,777,10,483,937,21,58,223,505,719,758,964,640,449,946,432,344,285,566,626,424,102,881,211,427,191,29,970,23,688,200,28,402,900,351,932,678,397,855,618,268,385,883,41,854,151,930,907,186,900,611,248,757,723,487,181,844,445,883,695,826,30,217,486,307,396,556,293,18,36,114,306,302,727,896,778,271,232,379,918,154,545,392,759,799,861,177,998,105,424,471,835,898,303,306,205,363,925,211,195,826,900,681,247,764,819,313,885,47,677,929,163,649,433,304,482,74,540,955,654,187,911,883,452,764,244,349,924,874,612,910,423,929,740,996,336,632,588,227,902,813,178,571,800,184,279,658,335,945,421,346,400,345,939,563,870,904,112,558,312,596,673,154,943,970,248,334,945,766,65,760,871,328,319,597,21,43,816,896,267,356,846,392,215,105,453,743,160,12,61,189,849,207,56,399,179,430,597,332,397,294,580,845,715,629,235,909,789,406,947,272,788,856,209,43,657,384,87,348,373,367,89,111,393,593,122,359,845,273,685,241,186,408,387,915,66,387,812,510,386,113,103,370,775,163,188,678,667,563", "875,218,415,680,947,446,698,86,375,801,280,293,460,483,819,214,252,572,910,73,777,739,427,395,848,756,282,84,492,372,790,879,341,360,425,70,491,511,728,862,445,847,322,126,929,282,20,518,976,511,614,192,592,226,569,795,504,653,629,837,453,783,117,822,179,466,635,290,841,659,414,761,43,198,634,664,630,552,876,342,831,691,889,354,320,761,425,40,404,271,953,363,759,64,381,652,923,578,732,813,171,996,321,536,811,481,196,309,812,930,297,853,687,777,543,667,561,580,482,771,833,248,51,903,718,230,578,269,454,627,827,823,114,557,179,990,328,929,584,86,974,369,301,979,859,447,917,590,423,164,107,782,188,786,339,292,972,301,526,940,542,245,538,489,610,843,409,73,883,277,476,868,0,108,957,740,669,187,756,453,31,960,430,395,450,904,544,449,798,124,387,703,670,50,540,395,935,518,948,253,683,608,231,950,586,650,16,962,82,59,757,586,11,842,119,91,160,599,566,758,904,401,264,220,809,626,801,414,195,272,993,968,226,784,53,325,337,846,969,783,994,160,484,430,40,9,924,487,633,732,796,512,929,44,76,146,436,190,356,691,466,339,602,946,126,279,146,228,455,374,170,165,159,220,429,115,276,449,528,978,508,529,309,188,90,208,846,352,586,997,931,410,258,624,170,123,205,518,212,977,632,171,864,603,66,382,762,111,532,609,535,741,602,635,866,500,544,14,201,284,832,656,669,397,268,977,679,273,756,695,460,335,62,578,987,337,254,605,277,550,625,449,266,592,58,73,696,75,228,710,772,445,365,993,733,85,240,318,337,149,589,376,115,593,109,285,890,297,457,38,636,766,202,579,447,125,466,498,101,336,239,367,192,219,300,163,643,379,774,370,107,786,17,258,35,87,760,595,719,319,506,691,570,14,358,930,117,2,304,853,432,373,192,241,219,307,515,37,176,237,68,860,795,886,577,103,563,3,773,326,870,138,973,355,724,627,4,939,784,645,89,66,40,181,249,671,941,972,850,73,496,849,296,585,811,486,297,875,26,101,389,678,669,416,139,660,347,767,687,561,11,363,223,489,624,639,817,705,59,189,174,43,358,611,860,652,870,681,45,884,515,7,471,14,810,319,95,616,291,385,448,798,406,538,981,785,692,842,676,662,94,365,494,508,695,449,640,718,630,81,798,39,80,453,334,953,252,532,525,902,563,54,857,671,722,511,594,861,83,467,88,324,268,79,278,764,295,68,20,14,396,260,2,936,244,76,349,953,947,340,589,98,800,53,45,724,865,611,697,660,754,646,357,499,230,95,850,258,335,268,205,331,35,764,963,179,39,98,885,456,622,217,254,160,222,447,976,968,965,240,634,422,320,822,882,783,133,467,642,561,266,278,440,326,371,963,374,314,376,23,803,636,695,917,912,612,67,527,351,926,524,370,321,106,275,851,604,886,957,229,427,766,638,825,655,298,35,749,268,381,455,816,841,603,327,737,974,5,901,855,135,213,998,137,371,665,571,762,253,967,401,432,532,752,92,375,226,103,748,496,560,862,263,304,15,861,815,876,622,782,428,441,627,737,792,669,198,994,402,47,723,76,534,440,22,931,446,916,649,913,458,735,942,151,303,856,191,619,22,705,175,838,971,723,274,100,301,709,355,514,383,681,551,469,499,760,251,485,862,903,352,31,14,485,235,359,544,863,130,651,102,501,745,201,35,901,804,405,776,222,156,15,882,131,762,299,498,698,418,176,590,769,329,491,276,723,947,651,893,440,160,95,884,921,515,172,531,574,939,410,930,998,177,603,105,244,994,214,864,368,590,248,356,376,98,887,656,564,185,215,286,431,36,307,348,805,594,947,714,44,251,848,329,450,216,644,846,28,993,320,103,575,326,146,563,705,984,753,378,557,592,124,542,508,100,857,127,137,244,634,113,443,387,182,332,664,954,805,431,352,945,993,780,187,104,56,84,213,247,724,28,695,575,636,721,529,280,652,504,181,763,234,621,52,895,534,158,619,983,340,422,765,77,38,114,766,904,124,994,596,369,302,56,180,655,65,382,864,556,870,643,698,79,950,246,794,317,60,799,165,492,73,791,235,656,87,537,644,837,744,167,319,466,632,416,296,855,961,956,398,110,417,864,741,44,90,897,136,173,534,244,154,599,464,972,870,120,443,577,991,704,517,20,743,163,688,505,751,356,486,774,485,646,496,496,11,784,439,392,346,650,523,802,894,900,191,19,414,274,551,608,226,648,571,535,374,530,385,726,142", "620,878,993,482,269,7,371,47,94,650,188,594,869,650,14,761,457,906,152,166,620,599,285,114,341,804,547,322,285,187,542,395,559,750,553,667,154,70,918,266,154,627,600,830,533,884,760,446,111,921,390,11,480,811,437,960,114,104,818,345,75,815,431,924,406,107,561,181,172,339,766,986,328,117,231,396,504,707,969,717,335,25,698,749,540,218,262,18,699,227,990,365,541,692,855,671,612,755,973,633,232,602,97,464,739,449,921,996,523,834,117,485,665,510,495,324,159,906,490,431,368,915,938,95,533,810,795,174,553,929,15,82,40,159,880,8,968,54,916,65,359,747,225,917,614,809,928,477,786,684,21,333,75,536,716,457,81,163,919,858,993,340,884,864,540,751,386,915,818,707,45,730,108,0,606,86,267,114,287,422,638,408,943,716,720,780,503,332,618,67,726,134,612,462,671,213,702,996,636,963,75,131,666,455,255,600,753,663,332,306,912,768,979,444,446,948,818,119,158,186,400,301,354,196,146,12,697,178,154,681,937,261,296,179,372,522,643,597,67,246,529,775,727,180,760,958,57,486,103,986,64,930,650,277,824,609,731,62,675,273,274,791,750,710,431,721,572,791,865,14,963,481,349,271,139,752,974,737,385,254,422,227,40,969,140,592,374,28,259,656,857,428,202,112,423,441,127,756,38,944,722,7,98,468,716,643,262,567,991,810,739,339,773,980,150,557,677,208,62,253,168,724,361,356,195,536,897,191,931,41,321,702,764,851,804,870,823,408,82,451,689,957,779,114,929,917,559,192,404,734,472,35,521,79,938,254,974,302,454,683,682,468,546,760,423,186,248,401,155,857,987,47,161,527,773,164,700,323,550,829,107,925,521,7,603,530,204,467,994,509,566,979,159,34,684,493,922,154,636,570,712,784,105,779,223,44,945,528,205,921,94,867,113,491,185,697,554,376,712,826,136,13,940,143,52,267,34,321,565,729,173,800,406,956,697,786,155,894,841,381,446,536,791,713,842,805,311,671,953,418,780,720,901,79,64,177,253,140,251,739,89,89,344,96,334,828,625,839,725,43,65,438,229,147,291,928,465,33,212,794,623,969,812,908,15,28,904,931,891,13,384,470,751,223,431,33,833,745,347,153,313,292,321,975,548,996,192,513,123,633,986,506,67,560,865,832,723,240,350,739,654,285,661,204,216,155,37,884,210,671,576,636,503,69,815,377,739,866,625,998,578,965,875,831,871,139,352,499,373,671,301,973,546,168,323,445,417,65,769,570,324,204,696,388,845,418,878,608,672,29,410,776,524,491,570,359,258,333,618,635,825,477,472,75,505,599,306,97,923,331,465,556,448,400,508,515,100,888,110,876,15,682,428,961,572,901,894,589,390,438,212,4,878,746,52,399,192,777,434,59,815,708,210,417,783,733,443,661,989,244,938,847,944,647,908,665,236,534,370,871,943,222,941,340,994,109,903,60,903,639,386,280,417,838,684,527,210,956,534,339,428,934,432,394,710,509,51,708,893,62,882,564,668,57,571,653,566,249,146,536,251,142,98,234,128,443,766,448,389,383,481,594,983,308,524,107,703,147,308,369,97,150,152,382,739,724,249,177,232,445,590,951,514,786,688,8,415,419,283,798,885,678,736,849,485,474,494,825,271,163,534,874,547,181,822,155,929,238,622,243,295,567,329,185,615,380,751,973,633,385,279,316,510,818,987,483,60,322,376,152,977,528,582,579,100,146,148,426,864,23,659,239,301,479,528,470,503,417,479,745,721,432,744,880,809,604,594,628,21,548,149,991,234,984,129,208,578,568,214,998,72,394,610,78,476,57,688,261,984,438,525,423,807,773,390,123,107,779,1,734,639,669,402,652,893,705,342,154,261,667,737,708,371,355,509,753,291,262,165,613,201,186,284,857,976,588,786,623,431,386,157,128,625,474,763,212,168,73,246,132,506,828,293,627,401,634,42,49,622,206,934,698,918,894,20,620,60,565,384,624,746,225,601,524,616,395,613,307,360,842,891,189,112,697,622,142,594,974,354,282,793,959,816,894,23,988,24,353,981,391,391,556,309,196,80,700,414,136,547,794,446,565,469,625,409,94,749,112,183,956,121,126,25,503,809,309,961,747,599,909,853,854,653,255,196,981,168,584,694,319,542,421,922,654,255,514,969,432,439,551,312,983,487,14,276,820,954,2,185,104,767,892,460,479,914,852,97,234,854,509,753,460,337,385,816,900,329,295,40,683,684,980,129,275,306,228,273,599,302,996", "294,919,977,876,7,431,882,806,57,714,924,643,473,935,573,210,638,641,289,162,336,903,808,98,194,197,884,623,95,731,531,559,265,390,718,818,195,350,31,806,769,323,4,688,116,361,979,556,624,902,967,352,212,34,385,305,179,14,486,101,798,688,227,27,330,16,989,111,628,349,300,823,504,497,39,258,753,847,514,345,842,38,886,744,729,97,900,32,395,231,589,636,220,373,322,255,610,914,439,553,860,776,803,6,893,16,304,474,151,211,937,675,639,856,660,347,890,791,619,281,541,746,303,511,557,227,214,481,243,588,690,34,554,733,804,107,561,935,381,481,230,643,476,320,875,874,256,140,362,541,290,269,493,657,558,650,3,9,479,679,272,768,480,363,845,884,329,300,408,5,857,795,957,606,0,963,612,518,99,450,661,446,272,803,836,863,715,373,354,651,541,911,200,50,139,219,949,793,659,849,760,444,78,424,966,877,47,244,459,626,612,551,655,357,329,308,835,520,527,865,604,588,980,659,375,143,38,315,363,251,182,364,835,187,673,148,753,370,926,653,809,374,361,754,210,876,265,697,788,713,303,138,207,744,88,347,700,583,448,996,999,739,747,907,610,350,317,50,930,241,374,583,602,915,409,15,744,143,818,523,98,383,472,518,304,578,5,363,102,648,892,832,734,707,496,218,995,625,395,986,930,128,328,543,106,979,621,843,464,276,938,632,906,266,422,204,378,172,535,622,919,20,432,960,678,41,438,217,266,925,53,962,486,986,654,88,191,696,209,590,899,680,518,502,579,317,105,322,320,79,195,269,62,65,786,559,633,633,65,630,704,971,165,439,460,617,538,39,140,577,96,101,330,581,516,2,958,242,846,264,129,179,129,728,306,956,604,93,42,929,443,124,529,443,273,54,291,121,168,190,28,191,539,950,523,960,372,777,410,703,194,409,282,950,96,636,115,336,616,280,697,705,135,909,922,815,814,135,952,403,27,310,98,316,524,299,97,254,711,229,271,764,860,786,564,796,315,259,897,151,510,494,892,981,822,295,381,670,822,73,349,378,146,923,138,216,197,615,205,863,862,95,744,552,148,371,147,252,361,369,960,723,94,636,341,431,25,855,884,799,634,820,29,333,358,547,784,925,489,873,872,394,697,805,522,334,802,422,419,547,337,621,968,448,396,514,572,409,92,123,737,930,84,753,108,975,157,293,370,713,737,135,827,328,378,885,930,788,811,721,960,551,792,253,397,911,67,992,55,771,922,450,543,364,602,33,566,157,526,41,764,586,24,167,756,966,296,622,517,135,226,567,23,2,922,597,523,394,21,47,390,54,802,507,584,933,873,830,725,448,637,244,145,918,774,412,616,164,913,119,584,887,321,15,54,342,482,302,415,543,122,439,322,45,142,473,415,596,2,468,366,626,903,967,47,69,917,120,148,299,15,645,739,9,223,743,619,818,432,642,615,221,901,398,364,976,859,164,82,580,62,29,967,360,509,408,144,611,772,435,235,143,335,491,631,170,401,747,399,792,293,570,274,523,662,433,686,314,955,756,919,692,409,983,5,794,880,847,52,118,92,948,344,538,88,515,590,291,623,112,964,431,665,290,952,990,950,818,338,315,546,408,104,153,788,579,117,71,250,218,561,191,730,464,997,121,335,253,485,194,565,676,103,940,590,198,759,647,866,647,696,956,343,893,231,112,171,103,535,252,323,885,437,714,644,904,853,655,308,707,894,344,258,44,643,803,927,275,858,381,114,595,313,673,34,45,82,74,257,465,724,814,773,254,485,601,30,88,60,239,135,857,943,45,129,752,752,497,280,94,897,990,10,599,439,896,880,122,306,353,149,695,834,541,757,121,572,518,310,737,488,512,355,639,164,406,765,397,882,881,221,634,421,346,881,416,91,264,808,962,38,273,819,839,644,141,479,223,236,505,506,495,84,850,427,778,122,269,586,464,361,565,349,811,594,886,205,772,468,204,758,263,62,428,523,697,152,809,297,557,872,931,337,583,861,411,859,501,797,650,111,398,839,362,375,281,132,52,289,294,883,198,179,659,951,871,759,715,220,129,654,195,762,269,369,102,295,868,827,503,293,657,450,201,948,219,218,64,704,639,426,292,643,396,60,366,986,146,839,7,572,551,532,679,835,7,328,535,550,131,737,716,861,359,404,560,939,183,630,850,653,120,652,215,266,760,106,404,408,397,848,515,613,295,10,890,231,113,719,658,419,888,202,746,318,40,98,68,868,30,73,320,637,272,167,891,380,755,554,683", "452,841,910,431,530,981,533,981,589,197,223,262,588,200,342,141,43,438,681,661,460,259,288,131,702,361,937,22,268,514,670,648,618,580,317,330,193,320,479,575,95,243,364,377,307,649,643,430,591,641,624,743,407,78,431,689,342,310,526,284,379,208,306,944,844,847,519,738,747,780,587,492,69,247,226,778,430,782,764,14,920,545,101,793,849,300,834,155,309,834,641,376,321,340,424,726,378,469,983,509,800,655,322,220,866,695,46,901,880,535,274,373,851,173,280,824,947,956,566,360,463,971,626,926,27,358,789,429,671,74,698,816,443,101,293,620,640,756,598,673,587,448,690,112,665,910,942,281,897,841,868,754,537,428,882,989,740,868,103,724,9,390,439,496,948,228,276,856,696,885,582,927,740,86,963,0,961,630,883,31,969,86,135,935,702,387,391,546,350,216,393,539,77,940,899,825,922,791,339,39,323,829,548,333,79,690,366,906,537,783,386,530,169,910,178,615,199,658,645,118,881,422,912,614,60,341,899,518,992,625,195,514,887,275,85,704,749,58,67,555,734,650,44,674,768,145,993,287,886,261,671,649,793,356,726,890,73,358,693,431,45,635,631,422,188,544,597,189,250,615,755,734,623,538,947,244,279,330,164,359,71,845,338,39,846,300,611,639,712,2,477,328,989,145,95,370,250,95,984,804,952,83,415,960,683,917,729,63,284,586,427,517,606,303,106,251,409,935,721,170,520,868,472,250,867,776,664,107,581,415,572,622,981,891,714,314,826,916,801,967,34,145,362,677,448,617,68,882,738,384,145,403,992,347,96,571,775,215,182,655,349,639,379,371,496,779,65,405,402,448,678,59,728,777,657,122,203,728,711,597,884,874,471,975,964,171,776,929,636,319,246,963,507,65,606,198,718,228,352,672,11,645,348,695,660,846,88,702,715,777,900,829,849,117,636,160,943,704,92,30,25,812,591,798,636,184,486,184,479,900,47,635,770,606,377,105,824,181,696,560,332,901,716,507,540,98,110,36,373,150,674,498,397,669,650,477,748,175,573,949,203,823,752,363,239,193,229,581,271,860,208,856,530,170,756,604,485,25,262,818,303,550,918,172,484,838,263,126,993,596,77,713,805,150,256,341,36,508,640,865,886,950,481,514,431,866,552,552,729,662,771,641,821,811,206,479,650,136,123,660,848,470,661,323,148,442,207,152,391,100,402,186,322,268,54,158,734,571,206,588,196,388,461,690,678,994,753,940,890,928,300,311,31,863,800,39,388,615,747,99,938,133,754,101,544,583,248,939,643,607,767,294,156,118,233,580,870,221,420,113,472,424,782,384,393,903,914,527,350,998,986,684,943,173,294,783,640,725,133,711,174,423,861,635,859,757,667,625,4,253,354,31,363,696,467,289,195,882,512,979,603,674,860,198,204,645,668,985,90,384,671,73,78,13,865,485,928,71,414,36,563,932,662,521,256,658,223,89,271,526,585,685,113,675,222,571,201,61,852,866,358,274,122,229,471,869,546,578,340,394,432,377,334,317,371,606,830,84,218,565,886,842,496,920,400,417,842,334,655,587,395,969,345,415,70,442,752,84,533,612,817,83,992,925,756,722,369,769,363,817,807,850,866,288,520,943,498,180,496,726,96,149,606,180,401,49,98,740,218,646,338,85,183,232,815,209,705,145,923,529,953,401,324,804,698,438,412,870,202,498,131,737,791,622,680,461,744,704,791,44,193,56,301,258,612,272,338,632,85,93,508,978,359,184,486,787,524,957,446,136,86,639,818,898,751,630,269,855,92,616,906,878,741,495,339,32,151,577,10,792,246,962,237,226,550,932,436,873,934,811,958,116,147,565,909,661,245,128,708,467,297,71,458,298,409,201,915,76,918,762,669,129,667,749,196,753,332,296,538,938,357,541,29,623,299,782,993,67,408,695,608,771,415,278,931,323,351,535,894,225,110,944,897,147,771,746,764,274,966,154,853,177,595,39,748,505,99,74,655,322,906,445,178,135,800,988,182,627,115,276,857,719,250,240,774,214,139,584,221,866,806,596,543,909,541,260,622,413,759,76,975,66,505,813,593,42,743,743,798,860,800,704,599,611,241,747,176,67,152,211,847,416,346,964,686,717,866,230,896,634,729,490,864,957,38,769,785,616,21,804,24,479,839,25,788,696,546,741,210,456,750,637,302,908,280,768,172,233,515,120,973,284,60,393,325,454,572,790,515,73,423,23,370,741,959,278,409,844,629,741,960,27,71,441,152,63,603,155,92,596", "832,327,132,961,363,181,728,197,889,186,425,253,539,613,789,746,989,940,342,414,952,842,695,921,168,504,902,708,990,201,555,780,189,999,700,349,128,730,524,285,858,986,117,479,671,824,888,775,566,84,459,369,758,222,134,842,640,711,803,373,404,842,399,106,574,675,69,68,645,947,537,643,197,202,130,852,666,742,541,542,557,161,288,834,654,8,376,471,587,157,289,175,786,766,728,6,897,87,834,629,687,536,38,501,504,73,451,811,72,600,522,242,904,412,781,115,371,508,721,764,585,441,936,151,515,5,426,962,25,559,189,536,73,497,659,132,388,539,716,325,332,612,578,970,834,638,355,477,587,434,934,934,679,875,524,357,39,591,613,846,163,30,249,368,891,681,349,200,590,775,690,8,669,267,612,961,0,364,178,759,124,142,113,577,614,291,132,400,508,552,142,221,353,203,431,656,326,901,414,239,985,355,58,512,219,542,159,461,856,107,759,326,117,339,968,627,229,832,912,476,704,316,704,51,345,90,859,369,399,739,477,887,881,728,430,548,125,224,766,931,604,367,448,230,646,980,668,939,83,574,619,652,920,742,29,981,282,915,493,82,368,974,545,769,547,600,814,455,552,848,367,772,90,754,825,196,812,700,964,683,326,202,234,75,771,831,297,328,466,266,347,900,444,88,319,810,618,946,51,469,467,727,370,108,55,511,556,584,542,482,568,139,371,729,29,150,525,285,693,892,208,437,450,444,647,5,988,958,244,864,102,302,190,671,331,569,457,609,669,728,859,548,818,535,134,654,645,288,439,526,792,290,674,259,167,432,616,956,580,143,580,595,357,600,256,708,885,914,430,551,634,214,726,34,118,549,977,363,663,549,71,424,218,439,422,466,784,417,454,273,321,864,781,596,340,733,818,181,137,302,744,702,316,517,332,957,943,732,388,398,310,728,741,660,397,483,441,749,293,141,689,116,655,986,454,305,42,995,638,576,515,389,46,136,773,307,232,884,834,28,457,349,356,809,475,932,800,465,886,658,919,309,677,288,684,979,52,477,410,693,878,563,998,768,560,206,627,386,811,395,486,624,217,303,747,838,65,681,44,955,949,780,68,36,865,257,866,32,12,866,220,39,314,479,621,203,754,589,880,360,156,736,724,888,670,709,297,149,21,220,138,431,11,911,623,662,233,562,955,466,372,817,9,751,432,263,784,736,534,215,539,491,206,497,834,476,760,497,878,67,47,125,127,748,800,476,65,547,388,663,184,275,283,12,651,326,129,235,292,879,286,682,309,208,730,304,706,100,123,671,188,698,468,956,837,537,927,507,12,602,374,636,619,839,663,766,565,370,516,591,179,908,762,660,16,270,379,724,610,381,699,592,681,37,655,84,387,745,177,125,41,163,296,456,557,447,144,40,635,877,9,384,584,768,355,933,88,558,975,459,105,77,766,940,408,215,930,239,670,679,144,359,851,727,113,763,467,705,53,817,475,35,580,546,691,128,887,965,9,476,403,162,303,831,934,690,92,765,393,670,143,943,477,427,868,337,406,557,453,407,361,513,737,737,76,792,23,245,786,759,818,967,298,838,410,364,480,825,220,721,702,363,942,687,100,206,311,357,679,130,310,32,356,862,595,643,326,465,299,941,920,621,731,3,409,841,990,845,402,575,438,352,271,88,928,709,610,169,82,809,463,669,74,413,747,835,523,168,462,928,547,812,865,930,176,77,494,798,564,394,461,357,306,418,716,215,375,263,472,513,357,605,453,151,707,479,432,760,986,44,925,113,28,456,486,38,226,875,959,729,968,274,293,933,646,582,463,393,3,235,263,919,276,822,647,980,729,142,302,123,896,604,355,853,706,826,221,453,764,257,595,371,866,889,799,845,198,629,169,553,240,971,297,254,400,669,762,247,67,640,272,2,427,956,522,31,134,195,98,234,549,575,541,556,598,738,451,212,57,58,334,73,426,743,914,606,663,993,140,213,483,849,448,751,996,909,46,365,874,90,942,394,900,43,993,456,26,854,326,205,879,161,8,369,729,796,416,116,30,203,969,179,621,763,272,151,958,455,136,224,177,238,841,593,775,726,222,942,616,642,273,597,779,852,786,780,63,544,876,579,610,738,347,93,542,686,861,556,791,764,821,665,473,315,137,837,95,564,89,33,595,986,634,239,453,469,181,260,700,720,511,960,539,265,906,915,505,195,966,909,570,657,677,608,262,506,557,890,703,710,966,631,706,325,297,684,512,966,177,202,370,744,352,913,401,274,716,859,234,14", "739,320,949,307,253,64,996,160,119,558,619,479,484,321,880,334,427,267,269,234,111,515,177,93,29,450,652,240,740,526,125,797,70,220,461,643,842,965,902,560,683,523,989,262,111,783,384,431,760,477,756,864,996,381,941,760,608,565,556,148,226,25,139,620,798,551,349,426,461,357,767,179,862,572,2,274,325,574,654,753,174,504,805,57,889,194,665,867,218,684,479,979,112,198,147,372,390,507,170,714,972,414,852,931,658,257,515,524,881,102,346,662,377,943,63,202,802,770,820,240,480,876,942,854,68,289,946,549,892,881,419,896,770,965,713,761,765,989,36,649,547,623,162,359,294,903,680,452,768,56,987,301,365,810,697,91,207,224,45,14,64,670,700,675,237,395,849,559,317,158,849,596,187,114,518,630,364,0,303,988,558,36,348,464,798,298,772,692,284,625,615,545,523,889,279,255,61,805,213,250,364,123,756,719,884,476,820,225,192,944,229,126,46,210,895,124,781,163,868,967,161,28,639,371,53,551,187,658,666,953,167,53,984,724,22,856,916,573,997,187,373,525,984,745,680,509,165,408,362,542,643,433,292,612,452,292,665,491,762,919,265,777,250,690,740,855,399,349,593,170,380,142,861,836,676,492,40,42,167,338,176,427,298,627,598,805,635,699,109,153,260,209,53,586,400,917,23,280,130,841,3,332,768,232,290,688,679,388,573,382,465,118,445,786,108,210,297,303,227,55,833,275,452,104,400,824,372,934,482,367,82,41,29,587,617,748,661,719,130,220,946,237,174,120,485,837,541,510,994,407,863,16,567,582,92,728,905,626,813,138,680,930,5,279,565,968,99,162,152,204,210,840,852,342,780,283,39,866,125,641,306,583,674,584,602,715,260,540,576,131,436,515,211,44,539,410,750,883,911,753,92,244,9,263,860,670,701,133,953,565,228,810,805,636,540,488,590,589,475,963,915,430,845,574,325,554,8,782,5,84,760,746,510,675,555,286,730,428,361,581,453,971,917,545,901,930,103,239,995,955,66,327,165,241,730,609,834,753,91,772,85,479,883,910,84,801,827,12,714,832,855,42,379,663,44,580,603,911,454,340,995,996,812,749,684,882,130,131,536,515,862,495,294,684,914,524,942,34,543,68,667,421,815,625,696,62,232,156,177,126,178,716,10,474,664,889,595,432,408,511,256,446,469,573,157,574,235,528,201,608,766,911,948,203,210,593,156,507,433,406,150,737,593,372,894,689,735,459,621,315,243,313,903,913,874,980,961,575,826,308,600,467,380,242,704,42,665,264,301,989,532,678,339,158,719,30,357,575,496,406,839,808,274,560,639,87,393,762,657,638,464,599,890,102,598,154,947,132,246,678,309,357,74,72,555,559,25,569,521,557,259,551,76,176,281,142,195,828,208,401,240,716,5,300,739,754,233,202,307,471,550,93,764,914,381,989,413,624,987,437,96,611,371,601,479,70,884,129,427,402,605,61,656,750,98,35,442,550,325,341,445,408,32,944,798,170,780,707,245,234,721,629,822,347,282,853,625,543,672,125,213,587,928,223,105,452,412,937,90,54,49,411,835,247,365,823,842,394,313,985,386,824,278,331,806,774,659,730,176,421,956,857,460,410,646,324,857,650,931,881,699,517,255,323,849,758,948,345,839,172,766,430,64,992,234,239,173,584,958,577,229,797,175,800,38,94,832,970,224,47,179,722,384,227,355,627,544,105,977,98,789,663,602,612,580,374,696,962,288,879,580,725,816,801,979,320,671,905,851,307,425,966,853,532,516,679,107,277,637,776,722,325,485,592,87,458,69,174,661,651,380,302,8,441,428,305,774,650,410,370,794,500,369,841,632,50,357,82,420,40,268,936,512,2,598,364,890,79,355,15,117,297,837,684,868,88,50,491,357,472,208,104,445,400,169,948,230,312,315,205,509,749,230,686,426,103,28,60,612,147,42,405,206,831,554,84,406,511,307,512,396,495,924,145,384,155,767,26,180,921,413,327,907,650,785,890,268,72,275,877,754,445,76,420,11,474,911,296,357,893,927,760,846,298,973,828,481,595,114,721,59,477,659,92,485,101,475,425,13,589,91,974,130,308,436,906,427,392,376,509,691,986,792,328,636,135,102,141,489,164,959,813,575,317,720,49,827,275,892,32,161,774,631,737,427,607,119,210,837,196,661,645,806,367,882,144,127,8,401,341,422,398,671,765,682,854,315,401,82,781,413,166,408,269,205,165,266,883,234,742,525,89,386,313,918,211,651,179,553,351", "354,949,7,10,495,237,572,320,143,811,149,868,126,737,88,404,63,449,390,473,13,932,771,823,316,758,173,570,721,254,76,323,857,503,339,400,303,498,26,899,342,495,904,138,255,740,917,407,742,72,521,227,166,923,39,658,362,201,424,382,268,583,538,809,373,109,22,727,346,786,38,13,55,325,751,238,101,89,710,30,962,491,568,468,210,254,708,129,520,795,58,432,48,764,3,829,337,399,723,302,844,329,70,551,804,94,503,257,200,396,517,952,231,711,720,853,756,757,534,112,636,11,233,834,455,670,186,821,862,227,65,395,487,900,555,877,457,394,957,623,771,683,264,613,533,706,931,327,937,512,978,101,902,759,49,306,769,437,340,777,128,290,769,357,721,365,756,529,834,501,521,499,756,287,99,883,178,303,0,912,598,682,64,985,494,741,660,691,380,67,613,191,415,173,68,138,744,329,649,482,596,249,296,226,667,780,713,140,22,683,280,140,723,331,799,702,180,751,672,720,448,93,15,711,456,453,20,253,361,442,470,110,464,571,159,255,497,477,133,59,169,212,935,628,521,710,308,576,903,106,282,484,494,772,204,567,876,132,540,740,106,912,645,42,714,193,671,765,34,467,329,56,577,646,836,541,58,688,99,268,989,93,75,85,597,738,89,450,670,520,893,756,131,104,364,290,44,666,708,200,457,214,263,771,750,197,115,272,280,818,504,522,113,359,26,229,845,389,450,529,830,770,425,251,726,498,187,876,745,857,837,370,362,753,654,232,688,206,849,757,784,864,326,886,431,938,898,943,386,156,595,109,46,396,750,388,446,57,266,2,913,56,886,44,807,750,709,259,902,714,589,578,414,55,131,701,209,570,976,808,237,897,603,392,115,73,824,967,922,852,407,111,35,229,258,876,349,534,802,74,685,500,147,45,837,659,882,814,462,34,695,87,597,440,609,315,452,732,310,374,815,945,788,999,242,317,886,107,510,729,992,180,458,645,876,131,430,903,205,817,863,113,925,697,922,963,757,320,138,741,54,875,78,456,677,740,149,129,48,707,60,451,9,542,287,602,127,52,965,663,298,521,742,378,412,549,836,700,570,980,162,170,190,907,60,481,649,514,234,971,232,292,302,301,260,425,482,754,817,629,944,100,340,225,100,811,633,125,4,952,746,643,75,800,378,802,715,537,445,31,350,792,377,110,891,368,278,197,369,345,963,258,380,925,381,45,192,660,742,367,488,222,240,388,438,978,877,352,134,267,116,164,938,755,128,401,562,678,229,360,648,668,351,752,102,765,165,246,118,488,417,754,52,736,312,735,802,723,854,84,5,112,650,905,674,577,75,146,416,960,76,642,262,571,901,44,964,361,410,339,943,365,938,500,194,484,65,142,161,268,26,397,750,786,233,888,570,210,439,435,224,574,880,623,970,75,805,205,395,735,999,207,515,314,240,136,429,385,341,80,761,667,530,836,764,820,381,155,282,118,714,733,282,937,460,670,838,630,296,645,826,90,410,681,366,261,418,753,667,928,759,833,724,378,715,874,612,963,40,577,690,417,732,749,307,708,523,108,560,478,513,800,40,91,206,773,718,120,301,753,262,463,460,989,302,540,920,34,593,60,960,55,124,231,87,546,33,931,894,499,585,905,509,782,645,651,390,341,405,228,748,91,880,613,471,374,845,409,194,514,575,77,354,264,698,319,94,520,69,633,898,451,43,901,379,733,812,325,982,299,692,220,395,495,866,423,157,403,535,732,642,647,739,295,902,957,746,790,7,94,53,181,503,614,280,661,446,177,276,319,817,906,822,841,201,786,675,496,242,643,908,537,973,598,470,364,830,309,17,398,523,601,495,395,284,426,861,881,299,903,320,555,155,551,126,16,539,118,666,228,699,920,360,208,477,529,652,50,943,570,55,737,958,907,381,411,410,838,484,157,140,471,276,333,438,707,217,396,227,845,832,626,949,925,41,744,439,83,422,234,763,338,394,534,306,334,71,491,597,752,906,932,455,639,34,354,325,632,596,557,457,201,58,445,739,937,433,957,55,131,334,67,922,702,409,29,611,714,984,929,669,427,60,504,33,16,812,260,6,25,997,451,819,73,182,974,51,451,319,959,768,25,770,67,986,405,747,71,914,485,39,982,273,643,46,302,519,317,692,346,111,376,293,413,852,21,375,552,78,143,529,213,92,65,762,974,192,307,765,959,472,684,383,437,363,316,423,573,704,284,86,903,695,217,380,65,443,133,333,87,235,775,710,120,882,332,15,792,108,778", "781,838,624,286,230,962,242,323,613,755,349,250,75,389,572,32,355,284,14,509,262,947,849,385,395,133,597,381,465,418,297,524,294,944,554,967,353,993,987,512,779,36,902,243,8,139,802,672,832,985,339,716,423,707,985,103,182,144,880,192,525,574,694,530,9,906,348,147,664,318,133,371,677,490,28,50,89,992,877,938,871,180,698,740,56,494,316,117,857,812,248,906,696,574,394,872,196,279,867,690,721,18,416,667,839,72,174,677,56,728,334,979,24,872,597,20,218,838,359,976,243,218,522,288,513,590,616,916,757,739,210,844,105,910,521,610,359,683,973,710,499,628,390,338,117,14,409,602,271,407,305,866,42,253,163,686,157,338,58,431,160,743,644,661,11,984,294,524,745,181,462,172,453,422,450,31,759,988,912,0,106,562,127,217,657,146,14,522,270,969,432,851,424,743,145,844,944,421,79,399,506,216,259,799,739,540,260,630,585,563,679,614,757,545,128,285,301,43,414,501,767,353,883,698,652,653,511,150,137,527,288,479,367,810,116,678,634,673,48,84,651,236,516,722,771,824,745,998,45,82,681,787,876,949,311,719,451,902,22,586,744,58,37,954,604,645,32,919,96,367,152,116,228,624,221,369,504,166,615,737,473,857,816,345,370,761,543,916,64,392,225,553,631,773,998,298,722,523,267,32,957,499,961,20,239,39,942,925,14,481,129,914,139,262,260,920,433,376,456,622,79,465,15,55,543,214,647,408,128,692,746,234,475,347,409,727,65,455,765,713,863,100,580,897,855,925,971,866,322,316,372,586,761,908,127,262,603,19,310,139,599,148,681,338,967,612,594,92,728,826,919,822,376,396,613,617,74,805,338,245,344,621,742,725,51,627,583,416,97,575,810,299,135,667,507,807,274,409,897,295,796,836,1000,85,155,144,339,833,147,189,43,666,425,88,600,294,71,63,44,720,632,325,192,390,33,428,19,880,512,217,143,785,305,766,125,332,200,844,839,470,31,441,68,805,301,379,954,468,704,128,759,399,174,393,337,203,114,641,290,783,902,703,192,192,523,210,24,86,688,808,601,851,133,615,974,237,278,732,160,687,104,938,38,757,803,377,139,338,229,160,980,184,41,414,264,673,866,838,127,802,614,994,432,800,466,783,220,549,933,25,29,204,462,384,396,460,338,751,289,406,297,53,281,185,544,715,122,392,42,533,366,962,230,484,943,148,598,342,212,449,469,374,618,554,561,907,530,24,80,273,200,382,585,251,754,150,616,136,685,287,282,873,593,816,353,380,226,186,525,495,279,984,176,474,492,970,334,412,237,834,324,609,158,195,328,621,398,548,246,779,320,649,185,517,54,640,799,372,119,798,457,867,672,380,757,941,373,311,188,485,232,150,667,886,358,688,880,257,155,613,432,200,703,904,335,577,446,727,826,469,587,701,416,88,427,902,760,908,821,291,868,187,206,591,870,188,519,583,899,650,388,536,527,836,878,287,945,175,628,649,215,620,539,122,844,885,292,685,463,531,906,685,595,796,183,786,145,190,836,244,594,758,625,714,352,565,648,497,150,453,55,669,391,793,105,165,809,371,10,929,195,913,586,613,512,248,554,789,152,878,933,2,585,766,200,358,715,77,925,756,3,20,12,373,286,308,272,688,390,635,484,15,590,183,678,447,459,217,945,309,29,361,426,78,401,210,932,455,886,682,681,71,703,182,82,381,958,329,11,886,764,297,393,611,525,324,207,840,944,666,910,240,165,509,488,807,734,582,700,981,673,783,174,530,894,9,465,521,296,892,352,532,728,770,816,65,786,659,612,526,278,707,582,817,836,815,407,423,477,74,262,790,860,302,805,522,937,725,951,72,274,317,293,314,456,863,435,998,294,418,781,28,856,196,658,444,220,681,542,464,459,854,863,372,827,782,491,161,582,420,342,293,460,306,209,39,611,90,876,715,553,634,871,859,810,451,658,572,856,181,717,861,828,213,834,636,322,87,811,533,116,752,851,307,353,654,686,119,741,631,177,182,547,316,423,954,932,721,26,100,173,306,571,452,981,996,123,382,422,651,518,813,966,688,299,360,43,552,912,475,499,786,739,208,453,383,259,730,445,699,129,143,812,784,59,829,914,902,740,773,161,79,574,775,3,452,648,852,11,413,190,341,84,104,859,42,146,698,637,927,355,229,721,307,479,473,936,226,334,35,509,603,651,126,651,952,146,527,326,692,668,248,184,561,759,314,678,322,15,558,882,104,594,764,695,786,106,437,110,821", "348,138,684,188,683,445,143,721,371,44,797,430,351,657,621,807,4,739,386,500,131,918,512,789,869,998,564,892,292,458,277,261,457,673,759,963,94,232,938,614,77,515,532,536,587,210,35,150,63,107,160,241,337,62,247,810,763,570,303,489,553,92,598,92,777,119,725,411,734,222,247,195,445,865,237,243,954,311,190,179,920,389,849,433,275,753,259,46,173,328,592,273,8,525,669,638,195,468,393,133,31,69,308,280,625,439,260,404,44,203,103,283,811,23,799,955,291,776,272,466,925,770,425,732,461,171,651,309,817,163,704,955,485,777,314,358,181,743,629,328,157,936,518,448,450,994,881,228,421,853,366,110,957,145,257,486,751,869,394,376,295,524,517,971,563,64,801,205,465,734,606,956,31,638,661,969,124,558,598,106,0,5,861,288,818,753,486,750,353,196,39,471,428,85,877,502,609,986,413,746,32,18,925,483,750,382,760,305,764,578,593,852,54,934,642,715,287,958,684,165,161,601,222,607,823,132,484,656,378,31,848,43,42,300,466,259,953,595,775,337,169,355,651,826,77,430,663,293,392,952,525,450,560,595,664,872,495,833,667,130,111,936,869,403,402,771,431,7,481,76,894,691,712,226,533,58,793,447,193,227,229,514,879,659,357,770,45,100,500,311,745,804,507,793,721,162,779,663,186,162,981,642,289,445,227,617,634,106,409,651,150,87,193,961,138,352,227,542,958,855,382,606,29,502,709,619,530,66,350,172,965,580,187,708,459,745,680,74,482,770,442,590,992,873,767,950,116,140,562,773,750,700,746,746,280,300,986,707,732,115,392,408,276,535,292,218,388,331,273,923,570,69,299,122,511,583,491,919,46,47,814,66,94,357,319,261,140,498,3,655,44,829,461,208,426,380,749,270,220,386,687,88,34,762,170,389,481,394,234,633,275,8,793,519,85,502,810,549,20,448,47,300,945,652,34,790,211,610,763,437,572,779,268,608,422,594,56,66,940,951,955,377,873,443,762,824,768,429,62,621,308,411,414,380,307,144,611,681,638,904,725,516,503,590,354,94,140,434,790,528,917,212,304,12,319,328,557,28,377,622,620,648,605,106,146,1000,842,555,52,955,937,244,405,19,398,253,341,344,156,613,461,486,333,80,982,262,464,458,671,707,412,779,67,81,361,481,286,650,691,145,455,394,40,183,544,898,377,452,706,756,385,152,997,879,719,109,261,794,788,378,909,952,700,90,889,943,617,145,773,370,714,3,628,552,272,266,433,877,168,475,248,379,590,967,647,206,932,238,289,435,754,964,634,15,486,786,752,36,733,191,226,722,922,540,350,591,384,375,13,911,850,340,184,80,745,518,889,280,462,773,179,755,997,187,962,725,488,463,990,14,631,623,366,211,936,717,839,983,432,680,758,886,385,517,371,401,853,152,292,227,683,184,144,704,532,215,177,420,673,819,858,938,607,410,359,245,43,801,911,646,822,179,699,805,409,54,301,959,188,657,655,114,959,845,873,125,371,68,723,516,23,405,438,762,132,818,57,397,488,135,112,729,596,303,836,741,562,220,929,823,740,296,933,50,517,195,963,15,109,62,944,110,889,786,428,753,94,258,417,92,529,89,541,48,160,997,410,400,455,764,198,726,406,776,157,95,842,9,894,563,675,779,100,633,379,262,18,706,138,668,2,80,308,841,964,420,11,4,479,967,534,571,198,864,169,575,142,645,744,597,936,15,555,604,578,928,295,396,368,332,195,746,908,294,538,613,350,976,863,553,679,109,869,308,196,862,345,137,646,352,843,76,331,848,503,384,614,162,31,305,574,779,695,672,845,136,232,477,761,977,998,323,444,899,657,224,928,780,833,172,391,677,454,213,409,52,376,936,175,563,565,40,787,339,821,851,829,482,191,553,210,19,3,524,728,84,271,474,98,565,161,302,256,986,996,398,765,864,957,360,633,460,918,765,556,665,263,742,403,96,732,77,694,770,186,789,252,419,582,422,783,154,283,564,503,930,482,594,101,785,5,17,854,353,479,391,32,181,681,125,975,823,828,49,337,195,76,991,640,458,468,283,882,978,788,689,48,24,458,928,718,971,373,532,608,384,88,181,803,828,776,447,152,229,142,181,875,366,144,627,518,84,191,353,426,312,570,917,988,629,502,325,616,924,841,571,297,297,643,43,763,342,982,763,504,776,316,997,349,604,532,633,271,900,777,397,894,938,509,767,872,226,798,477,519,694,52,973,433,62,157,681,542,306,150,401,81,348,963,564", "264,537,720,982,634,63,962,619,209,622,664,681,749,292,310,695,959,370,356,98,952,333,961,82,855,168,569,397,738,601,112,853,427,521,15,289,104,544,346,280,797,480,790,853,945,637,346,882,553,594,248,107,865,263,402,317,231,386,925,690,79,284,816,899,505,971,181,881,849,89,424,351,269,211,535,292,729,25,206,198,924,812,983,668,677,902,215,60,744,943,267,525,199,785,788,387,80,787,854,453,581,215,79,508,98,376,690,969,335,532,433,223,175,222,966,750,188,417,579,404,821,410,327,770,431,301,605,857,629,849,677,154,414,879,580,2,210,672,867,331,985,373,134,841,885,170,424,927,88,999,629,18,987,88,584,501,641,778,453,661,658,607,31,157,543,530,691,598,29,532,892,394,960,408,446,86,142,36,682,562,5,0,538,268,402,686,635,959,180,317,426,496,519,111,239,939,455,273,396,95,178,835,436,228,788,549,655,404,116,486,953,306,301,286,948,954,486,678,584,602,446,338,379,560,402,301,224,831,196,57,686,511,436,511,523,22,268,115,243,928,610,440,488,999,192,639,600,836,283,291,10,913,161,232,864,155,284,680,810,873,676,949,578,129,628,131,726,950,309,693,992,646,936,346,41,617,808,26,559,750,205,292,15,459,938,89,133,965,946,395,726,503,789,628,829,316,661,334,201,507,533,344,690,405,943,846,18,779,105,307,298,408,710,790,247,93,261,392,984,533,171,259,583,781,236,338,327,806,903,169,376,514,690,193,589,784,345,57,522,265,888,763,828,686,209,135,428,922,481,957,939,913,711,3,842,965,975,357,769,597,388,294,492,944,834,465,658,861,928,698,175,145,94,538,433,277,850,246,271,35,26,838,442,272,884,322,404,894,845,267,592,471,795,438,60,248,326,263,769,658,241,872,808,219,339,985,240,335,812,552,383,501,182,460,321,680,725,693,850,438,458,768,732,608,626,693,930,510,22,858,444,979,567,786,125,898,506,258,688,149,412,336,631,746,906,855,228,987,312,515,562,369,623,859,172,351,747,379,263,152,594,643,116,816,840,806,320,328,254,497,600,501,379,589,774,343,319,733,595,125,120,483,980,797,997,713,125,744,574,255,766,598,226,926,244,705,704,790,406,905,761,380,340,850,654,880,309,972,965,166,748,883,347,616,547,60,980,760,304,748,364,541,581,445,339,475,756,32,140,989,733,185,352,600,10,574,565,858,225,40,542,448,114,565,846,997,329,76,555,418,561,916,754,139,577,823,55,261,518,176,698,67,596,583,623,356,232,816,539,926,922,449,999,59,814,356,316,792,397,830,717,969,482,48,906,284,289,169,261,776,878,223,354,893,719,90,401,350,13,32,700,521,421,161,817,869,496,101,649,395,71,723,874,29,573,995,304,704,201,475,745,678,688,138,771,37,440,341,522,438,152,682,903,707,266,907,924,866,94,352,464,643,773,65,43,608,189,487,632,24,530,888,142,220,579,38,128,839,405,256,810,729,211,332,246,952,969,318,762,647,923,34,11,55,4,978,638,317,224,555,443,933,56,757,825,735,192,872,404,199,405,429,689,510,694,83,85,21,676,498,1,17,987,354,474,503,588,298,648,747,546,553,593,571,531,949,788,303,322,361,658,186,647,597,430,750,163,212,453,249,593,35,555,569,588,609,891,530,481,819,460,564,883,806,792,561,554,54,786,779,246,594,493,628,306,287,281,497,696,845,442,164,90,206,879,733,377,670,688,429,282,499,485,279,42,498,184,112,563,977,201,905,597,306,594,62,738,919,192,265,358,430,835,620,845,21,671,945,357,850,349,812,412,306,494,789,977,291,710,947,310,381,74,202,944,300,259,885,617,149,69,277,874,762,160,265,576,24,590,233,318,574,551,866,658,206,378,685,515,432,907,740,870,87,16,148,820,958,12,818,912,991,5,482,357,408,555,908,590,424,129,392,587,822,575,116,366,133,605,221,770,78,292,879,96,821,558,893,854,804,285,41,540,450,226,38,591,386,945,808,946,959,132,767,57,310,489,774,855,88,673,477,455,231,854,713,353,510,991,469,313,161,990,425,97,612,743,159,52,685,839,288,501,564,785,381,475,199,452,437,173,382,53,279,961,373,873,35,389,482,720,549,105,13,690,830,352,801,307,195,611,395,969,891,191,966,497,236,131,605,964,837,430,401,607,985,641,921,913,788,258,828,615,113,364,501,966,302,415,548,601,883,61,924,646,982,918,87,142,258,520,547,865,317,87,157,365,816,129,492", "790,868,651,970,851,561,133,998,57,15,629,359,262,152,501,306,680,539,822,256,753,279,512,631,391,881,493,127,621,31,630,233,921,927,972,201,138,915,4,499,641,256,490,73,438,573,274,260,889,931,53,384,421,603,735,494,768,319,880,979,92,724,877,632,355,551,447,9,567,606,574,538,352,43,216,579,905,43,648,93,287,751,632,537,997,734,426,326,99,911,239,197,442,648,491,978,408,24,214,786,471,876,750,696,62,506,410,427,491,242,695,473,837,774,938,2,686,138,849,89,452,850,491,810,741,885,524,341,932,609,102,42,103,277,812,569,331,503,407,450,167,997,218,518,455,385,797,942,878,745,305,988,153,244,100,326,243,726,654,671,75,682,358,642,668,538,618,208,91,787,259,154,430,943,272,135,113,348,64,127,861,538,0,558,215,949,756,139,242,491,941,745,315,424,370,260,34,466,693,562,920,490,707,239,94,565,245,730,369,414,810,334,418,189,194,199,709,818,299,731,701,799,806,741,3,224,629,65,220,203,756,260,688,461,508,319,641,88,819,922,98,52,763,108,883,819,906,626,803,263,13,795,596,438,491,432,377,121,131,516,328,324,294,753,679,490,366,874,742,977,185,51,212,739,36,660,718,387,459,845,780,306,555,278,585,452,129,442,935,157,329,783,499,249,600,514,322,62,214,462,712,719,464,376,758,825,46,783,675,334,494,983,409,498,983,507,824,326,170,235,194,576,742,983,197,177,645,776,625,704,107,374,170,341,575,887,384,248,181,601,808,109,790,671,791,404,178,750,409,517,429,158,444,129,194,308,579,49,704,274,712,209,251,93,518,57,597,847,820,580,290,473,712,78,119,595,13,139,920,770,894,158,671,143,601,668,199,619,295,533,757,218,585,328,969,772,469,871,384,341,32,620,903,793,975,696,568,658,75,634,263,854,493,956,348,566,835,529,977,366,13,972,504,842,379,634,475,29,657,760,480,316,508,409,897,36,378,934,216,90,648,194,899,787,852,170,479,554,546,689,495,765,31,963,702,745,689,37,674,580,532,170,43,62,573,659,916,36,121,53,619,154,692,564,151,932,962,226,904,79,312,678,659,286,47,511,256,467,898,141,347,30,611,386,527,988,575,875,602,937,644,649,298,529,888,329,512,861,629,370,181,774,244,514,886,605,828,694,139,414,327,770,120,282,80,408,219,706,819,180,849,252,131,319,528,158,64,288,217,168,552,474,190,646,270,990,883,754,131,246,458,368,772,190,906,504,209,525,478,863,451,691,679,595,929,173,840,984,900,496,994,536,647,952,971,410,25,812,874,471,599,559,344,741,640,88,845,45,266,528,721,791,417,451,623,560,330,958,716,28,565,363,712,95,647,199,866,908,318,345,227,774,949,781,366,70,908,561,741,995,834,360,911,242,843,540,127,333,819,611,15,328,616,756,498,551,227,448,123,677,672,881,160,220,916,462,204,395,470,189,775,298,179,957,834,49,993,74,68,327,429,82,200,937,479,344,270,69,421,361,111,339,5,428,404,910,36,806,321,827,362,424,341,853,209,200,205,132,431,828,573,860,256,738,917,970,986,586,304,983,608,57,388,32,38,130,758,475,587,74,258,870,2,719,306,463,41,904,746,801,299,375,62,897,935,889,668,415,528,609,302,321,846,677,805,203,799,99,378,479,597,723,519,265,360,474,293,875,694,893,291,577,154,520,990,744,495,699,319,509,31,849,933,767,417,908,668,401,440,552,615,123,940,658,742,635,817,97,405,424,667,829,861,423,312,852,903,902,258,835,6,329,25,769,938,998,133,168,41,238,347,438,834,940,953,549,633,715,880,214,306,820,304,633,311,698,16,989,259,393,913,547,453,129,438,876,503,263,664,76,783,447,589,340,198,392,328,150,139,957,365,251,341,619,804,941,263,298,224,332,282,567,205,109,532,8,20,837,106,733,731,456,852,961,302,780,858,242,15,119,727,666,375,690,380,791,304,376,675,217,835,188,370,889,683,749,625,271,141,971,297,998,781,246,336,884,139,828,851,22,140,852,402,119,776,982,314,864,841,231,863,201,951,26,448,980,312,483,951,823,280,348,29,499,953,928,757,719,630,300,794,238,977,410,477,715,246,237,294,502,619,982,541,352,944,127,339,576,980,569,481,951,936,880,809,671,855,788,638,307,795,764,556,163,423,329,828,647,864,849,38,5,384,446,204,752,571,521,682,748,653,874,695,561,2,95,612,275,669,189,741,65,301,310,618,81,559,561,796,48", "110,329,556,237,906,882,390,763,89,820,295,356,897,794,485,393,858,909,356,952,416,153,499,112,87,753,735,687,329,30,676,312,629,883,424,245,267,394,855,888,377,490,441,139,397,876,146,972,431,776,564,700,229,346,473,859,465,237,353,340,153,62,166,955,907,615,115,551,117,327,848,380,529,503,466,901,724,424,798,873,268,557,539,871,620,945,890,585,23,114,469,933,159,688,345,837,640,639,457,485,42,64,280,324,216,370,462,451,488,225,20,992,611,966,465,969,71,482,315,20,663,386,916,400,761,50,796,305,248,825,655,432,583,924,375,171,412,105,696,158,397,298,552,710,695,135,629,746,260,246,615,780,835,960,28,737,264,440,825,42,300,903,480,47,942,355,48,347,346,186,528,879,395,716,803,935,577,464,985,217,288,268,558,0,562,271,962,559,52,410,774,598,786,929,25,953,543,779,920,983,91,859,615,317,308,839,491,758,67,527,464,700,994,865,935,448,875,625,777,88,369,559,213,771,229,947,837,303,229,161,440,665,755,114,433,752,146,395,902,468,969,967,166,428,747,303,223,648,155,681,150,598,252,541,395,758,394,770,659,561,617,958,127,228,96,732,881,48,63,975,862,938,643,379,24,617,814,285,657,909,757,566,77,528,888,849,126,225,522,101,732,946,514,126,653,921,388,704,820,887,366,567,226,690,81,270,894,732,130,589,482,931,431,661,930,692,205,520,367,397,35,984,972,99,589,706,65,894,7,53,455,171,819,488,478,875,825,648,65,664,526,943,118,666,133,255,495,175,611,430,279,333,318,286,410,138,912,773,744,434,555,862,579,112,163,438,426,13,778,598,727,459,263,687,345,152,592,550,666,551,996,694,802,551,616,477,305,537,681,790,354,793,718,58,457,312,192,919,890,327,840,770,842,826,959,282,44,963,931,845,192,792,479,891,286,32,506,486,565,832,32,161,590,388,854,67,220,535,254,721,968,514,961,893,886,598,4,795,34,665,243,866,457,517,70,630,651,281,868,237,628,46,209,324,976,400,213,833,496,942,80,340,26,550,566,834,782,502,99,629,75,402,69,156,837,575,600,648,778,349,430,981,80,129,176,490,337,870,556,956,725,675,307,549,334,877,470,307,740,281,252,494,175,31,434,507,191,139,633,56,367,257,398,940,35,169,953,399,305,937,919,132,379,890,720,310,711,465,932,34,407,992,576,13,689,18,596,784,89,214,704,377,553,53,159,573,945,123,159,10,929,190,300,554,984,893,30,803,279,908,604,391,691,577,594,438,849,121,375,539,315,395,848,979,715,490,96,828,876,80,475,102,432,900,224,719,309,538,52,11,304,459,279,62,101,323,740,470,369,951,585,61,852,707,355,601,752,249,418,26,467,855,725,872,342,716,785,997,897,508,471,359,736,660,923,354,355,779,275,332,144,390,430,285,798,720,609,646,456,597,366,939,944,58,387,870,124,50,367,495,296,262,495,738,262,621,109,697,563,48,12,319,110,147,389,281,392,988,386,490,219,237,6,70,80,951,181,390,999,401,522,842,261,957,488,802,721,827,106,289,160,192,710,388,465,744,918,908,31,167,393,775,531,820,428,238,477,819,999,147,967,171,898,566,537,259,981,610,837,351,434,6,436,914,729,518,983,505,581,844,191,397,168,20,345,813,567,416,260,287,235,634,882,977,392,268,416,87,445,271,221,655,321,156,814,177,356,762,114,443,417,63,73,14,183,397,958,776,236,175,361,920,972,378,193,259,242,125,982,900,952,798,155,9,269,539,677,609,456,586,715,396,581,70,799,931,164,317,406,8,879,681,682,157,32,784,220,974,758,60,390,553,286,341,361,121,727,920,460,662,266,756,769,326,961,678,584,477,44,623,814,725,587,976,198,935,393,6,553,454,33,941,751,385,202,95,954,49,752,106,550,390,835,387,923,677,224,524,826,899,39,430,397,486,814,139,887,736,145,966,746,581,661,107,267,536,443,127,958,245,856,689,778,549,616,45,13,248,658,760,386,625,98,551,71,78,327,46,193,402,493,981,662,579,556,935,149,158,86,896,313,572,263,13,446,869,654,98,119,874,54,965,366,979,334,494,887,932,33,686,310,291,378,426,144,281,233,692,473,966,44,878,765,254,344,487,990,560,28,386,514,566,91,613,299,940,790,761,382,524,891,615,832,825,485,923,398,989,429,880,460,696,843,664,749,303,980,466,26,836,131,783,901,49,182,676,444,431,864,715,599,188,517,445,580,181,667,885,201,344", "369,759,534,614,983,980,664,152,326,55,188,818,271,800,382,134,500,249,314,626,386,918,803,82,92,17,47,584,389,194,411,896,460,108,693,748,313,226,911,820,304,731,876,711,840,580,663,854,831,219,413,748,167,559,505,828,654,197,166,702,310,836,953,22,641,943,579,109,71,208,156,110,786,170,820,264,335,808,680,516,836,711,888,123,403,16,466,627,415,303,390,675,809,453,360,414,7,998,716,727,103,284,293,775,899,277,181,765,40,695,985,84,299,498,981,132,504,341,467,316,618,502,238,110,283,794,285,937,62,343,909,318,511,29,901,23,510,304,554,288,72,217,248,318,637,330,172,922,218,634,791,136,218,928,700,896,63,615,718,54,918,696,272,474,938,762,993,178,233,528,798,320,450,720,836,702,614,798,494,657,818,402,215,562,0,535,598,471,828,895,121,62,944,171,388,87,996,263,755,459,175,987,144,911,536,876,58,208,549,372,840,188,912,729,160,986,904,70,632,345,393,549,911,224,7,830,704,437,609,489,221,120,24,355,92,482,177,82,544,7,396,692,732,686,96,963,85,104,228,720,55,519,34,891,887,213,822,804,494,137,786,768,292,639,27,42,261,295,772,195,183,991,951,486,792,392,957,397,253,448,239,859,915,176,5,177,766,404,551,337,455,86,201,986,948,631,63,934,631,940,408,467,986,565,726,622,633,737,107,91,783,236,166,632,28,899,965,710,198,638,67,144,686,58,631,584,821,805,147,114,400,471,338,430,536,122,868,491,332,298,234,231,193,769,514,462,352,28,550,675,216,776,763,795,982,762,637,677,890,29,380,813,820,470,89,988,296,61,719,750,288,920,426,53,270,213,604,335,978,760,918,187,523,19,269,817,556,716,640,834,952,931,498,200,258,146,674,49,839,181,130,894,944,942,200,490,282,791,447,594,143,219,270,562,337,821,794,618,902,828,117,899,212,858,530,664,766,96,440,810,521,828,167,787,434,12,420,538,99,952,437,468,991,391,206,346,917,3,724,22,475,195,31,602,423,51,846,249,333,447,779,332,625,372,33,168,189,932,383,782,523,728,517,774,274,529,540,636,861,87,121,73,59,864,19,758,307,385,903,845,360,228,14,262,450,332,945,921,527,406,895,379,641,711,403,741,500,716,422,800,619,207,411,602,823,814,960,579,239,709,515,198,947,218,447,350,585,700,516,734,967,100,558,437,410,989,120,322,968,902,406,553,644,400,842,19,274,77,539,104,430,327,831,313,203,131,733,604,124,433,866,131,499,318,629,746,595,271,602,14,963,759,481,270,708,657,766,142,701,764,379,81,39,348,155,2,23,494,663,673,377,597,175,42,89,543,69,537,609,146,462,788,591,224,909,37,482,606,199,816,129,542,907,716,166,790,19,584,504,793,938,797,298,475,309,762,988,688,752,317,180,377,952,100,692,89,549,261,370,309,926,721,908,271,842,571,780,853,785,263,55,624,334,205,819,419,365,363,135,487,799,200,908,658,840,483,540,433,56,22,698,93,925,477,354,180,295,197,668,788,988,966,140,759,932,539,843,124,258,863,195,459,592,950,752,137,805,699,678,307,730,304,119,955,682,455,971,239,898,276,947,447,726,818,922,27,42,918,588,415,359,267,576,827,968,889,849,609,778,926,290,139,681,494,544,198,385,775,331,740,12,257,217,242,635,984,162,304,63,594,848,154,803,579,708,102,133,858,737,87,365,856,157,220,317,129,884,672,931,863,243,858,144,887,954,585,40,669,521,520,289,447,292,137,122,337,308,492,256,923,43,395,827,85,995,762,288,649,681,252,798,264,186,95,394,54,536,203,397,144,326,64,421,15,196,772,709,171,477,590,675,764,112,334,215,843,927,608,538,901,199,752,413,99,236,55,277,319,930,953,571,755,69,56,249,71,311,712,789,549,78,66,655,797,816,219,789,895,272,900,736,284,265,93,595,969,589,860,68,29,626,886,357,315,698,198,445,602,307,414,322,67,455,860,317,681,318,931,367,768,132,697,430,632,91,651,606,189,97,460,242,335,397,83,413,279,719,44,404,801,678,266,966,175,243,989,889,604,554,91,889,117,357,298,76,691,175,304,882,257,677,217,461,472,769,867,447,520,411,738,602,457,831,167,173,67,77,839,272,229,607,441,470,568,443,896,840,791,706,663,48,214,245,829,918,391,913,18,211,154,495,187,829,510,615,671,572,476,721,984,113,818,665,327,268,684,761,619,98,402,884,883,53,446,271,338,912,412,576,967", "393,923,661,274,610,211,786,4,539,960,39,66,671,60,890,310,813,310,690,722,865,394,834,320,690,798,144,674,437,582,281,960,704,658,571,22,59,323,287,875,634,879,128,431,935,531,913,416,258,570,965,36,580,956,278,176,392,544,948,940,797,946,738,856,714,450,854,370,591,388,281,637,331,869,190,202,347,728,537,494,430,143,850,164,612,450,665,752,648,641,769,506,964,551,729,164,267,391,798,61,836,75,782,892,343,43,487,76,314,28,737,196,900,384,794,928,450,333,947,923,973,938,671,583,477,639,61,231,206,733,187,759,333,593,153,217,300,896,505,605,398,770,720,50,60,308,589,815,665,19,949,364,772,247,975,792,965,39,297,767,126,5,87,973,669,602,177,66,87,83,798,684,904,780,863,387,291,298,741,146,753,686,949,271,535,0,791,830,20,696,707,593,965,160,184,742,185,631,448,31,489,497,602,669,466,677,276,558,294,991,311,642,395,662,210,841,499,428,406,852,359,908,485,731,917,767,219,874,571,156,595,134,284,897,905,787,800,592,358,405,219,410,308,135,149,389,340,143,240,377,202,31,163,123,214,732,427,777,547,271,851,269,802,358,192,8,528,270,401,791,722,277,81,371,987,667,836,385,976,883,431,972,708,51,95,516,389,998,821,238,461,967,494,743,761,335,606,98,664,639,543,561,725,751,832,720,87,104,150,52,750,609,122,474,983,482,840,908,483,632,444,895,495,637,402,329,958,917,918,710,896,443,265,912,770,381,767,250,906,854,79,64,417,6,216,662,885,144,480,497,542,222,288,246,406,855,758,835,688,81,377,951,445,782,538,260,130,751,818,753,727,971,994,533,696,852,385,600,156,224,402,941,467,508,950,660,254,929,882,275,38,259,137,832,14,651,119,715,934,881,213,939,286,398,446,294,351,383,55,637,263,331,966,860,475,581,610,668,510,336,602,49,153,196,812,914,180,817,217,672,918,76,644,26,440,533,805,358,82,472,917,641,903,522,768,914,402,843,431,85,694,996,684,915,8,991,395,220,345,293,379,375,876,389,998,803,99,515,873,317,848,358,741,391,231,324,102,398,816,955,433,776,68,750,245,557,160,296,308,755,321,656,225,914,376,430,687,576,560,15,823,846,893,269,99,355,613,149,682,175,840,479,231,64,59,764,856,773,609,181,948,895,251,33,541,409,968,391,617,990,70,188,702,20,142,348,157,500,992,473,411,294,4,611,718,791,668,315,578,950,896,635,767,232,152,780,769,170,542,351,491,628,247,220,196,688,524,365,833,244,338,370,359,651,759,696,851,337,590,944,807,39,470,791,528,948,574,327,160,628,891,669,411,839,329,885,151,6,194,286,604,150,400,44,983,860,454,207,636,551,22,754,555,525,437,886,95,202,204,73,902,439,955,285,294,372,237,77,692,798,90,229,194,513,829,367,495,424,320,175,236,231,65,712,120,710,746,185,875,953,939,7,277,693,471,47,549,524,599,351,326,939,928,852,755,488,325,244,194,647,342,226,757,672,699,229,117,702,503,599,527,974,767,73,21,696,221,616,91,243,135,644,534,572,894,758,300,336,678,912,588,486,930,131,608,708,422,585,761,393,286,694,705,56,101,834,436,681,229,181,44,141,125,424,32,656,806,305,516,765,153,194,712,146,501,337,757,671,372,136,271,116,906,250,520,75,537,711,121,207,675,309,437,943,727,300,229,320,809,172,726,186,995,32,656,327,548,586,845,972,452,300,629,356,843,335,466,934,874,191,939,715,464,200,770,953,434,808,486,642,281,975,137,581,25,455,290,10,815,207,557,213,782,445,63,607,782,642,431,281,840,3,937,529,256,54,647,627,696,630,913,205,276,359,591,743,745,878,108,95,137,321,562,492,216,911,809,94,385,594,728,660,737,412,919,372,487,191,139,918,857,357,560,353,331,70,961,903,269,488,106,307,729,639,60,49,152,571,499,636,671,383,839,371,748,431,176,996,125,271,657,66,552,250,506,810,261,327,200,263,982,257,737,267,820,264,19,903,615,855,201,534,148,310,426,628,170,5,239,645,612,788,982,133,759,799,322,720,239,80,446,354,316,196,523,503,150,44,747,824,143,782,246,492,655,93,489,648,411,149,638,56,645,943,919,631,856,623,896,7,987,684,705,701,975,867,68,586,146,770,446,880,903,283,715,519,909,50,832,519,951,409,261,337,240,704,314,323,70,517,161,792,666,236,229,644,165,605,841,498,625,345,265,457,573,444,38,907,647,595", "678,496,852,50,966,458,580,591,207,518,786,626,168,22,360,137,281,235,752,544,459,37,395,959,874,608,474,259,837,539,869,693,621,895,53,177,702,943,35,224,237,192,761,760,140,725,105,83,557,402,148,192,653,558,266,9,531,755,910,449,36,834,334,599,13,617,818,873,278,747,389,258,239,879,846,964,158,356,416,542,549,353,691,373,363,642,141,368,232,893,769,149,535,265,677,746,207,74,612,968,728,325,74,46,972,789,252,312,406,737,475,227,477,856,888,808,776,101,560,876,320,263,977,777,841,505,44,948,265,585,128,240,415,849,980,199,795,27,144,519,31,666,940,168,97,99,384,928,514,571,79,207,291,867,535,884,949,965,598,421,960,594,45,966,157,357,619,750,47,696,616,928,544,503,715,391,132,772,660,14,486,635,756,962,598,791,0,74,66,682,746,305,516,405,275,97,495,480,826,275,463,685,977,451,945,325,727,548,233,730,840,157,195,447,412,864,517,577,35,802,751,258,572,853,706,693,609,649,853,480,786,945,625,461,587,743,771,362,722,920,36,654,29,775,705,283,510,895,785,776,448,683,188,164,816,788,335,485,216,864,839,185,857,892,809,9,465,745,58,942,483,598,180,372,177,724,579,990,573,121,986,479,617,309,406,643,646,287,61,685,962,813,476,222,628,543,802,370,276,598,111,857,218,442,605,126,40,249,399,153,80,382,667,749,841,990,251,187,319,85,57,887,597,924,469,213,329,99,151,581,172,682,305,996,373,592,160,222,939,950,408,398,235,117,446,279,563,704,73,424,493,103,989,146,5,281,159,155,963,150,298,588,431,189,743,211,121,762,356,722,283,619,347,484,257,634,666,247,632,368,329,860,818,438,209,899,999,324,799,407,515,100,121,896,85,683,758,428,910,816,424,796,756,819,578,219,311,98,360,434,375,578,490,589,558,902,231,893,540,190,895,294,25,375,537,503,788,691,285,859,621,825,391,404,338,452,630,361,493,78,535,37,461,503,412,274,126,751,187,248,365,46,60,825,961,262,846,15,430,408,453,471,11,955,344,26,447,930,482,612,148,842,902,937,657,681,179,339,629,618,405,295,964,38,245,799,950,57,952,122,560,757,649,342,387,68,84,914,446,710,51,991,113,29,635,334,492,217,141,610,841,213,425,29,556,591,660,710,866,756,52,969,763,694,511,190,13,867,978,22,436,507,351,402,123,749,108,743,839,155,133,164,539,522,827,380,43,712,769,634,242,267,296,959,736,900,437,80,285,3,44,885,737,32,202,122,50,326,935,77,229,698,664,39,684,795,322,634,955,230,421,243,248,196,257,758,383,593,964,45,839,541,388,794,475,478,550,902,202,467,121,316,333,854,597,165,473,947,513,652,821,883,290,34,273,861,501,678,484,397,515,633,857,339,592,957,607,92,794,580,450,277,992,108,964,542,773,247,79,993,953,626,865,502,71,607,121,452,282,844,40,933,360,921,733,125,360,514,29,32,886,692,805,720,19,817,749,626,516,951,873,4,43,432,994,91,28,606,550,806,760,551,431,941,302,409,741,648,69,353,419,12,619,262,720,922,946,639,93,733,918,110,387,716,717,282,835,329,770,672,130,529,507,290,715,5,132,344,99,416,304,462,425,767,694,223,744,988,574,889,13,316,866,475,301,683,949,811,680,460,853,851,761,151,647,46,423,511,377,326,689,298,800,832,718,696,581,530,137,688,311,292,44,28,267,161,272,215,599,990,436,671,917,190,642,420,917,223,794,539,168,606,872,501,104,791,796,202,11,758,976,397,157,183,722,966,222,763,412,811,340,79,469,278,186,401,70,896,761,661,994,894,585,325,149,281,677,230,614,947,205,628,806,461,941,717,951,130,429,782,52,623,249,919,120,571,906,634,695,783,506,163,501,584,831,724,951,26,802,541,656,582,927,72,406,527,819,135,64,771,257,431,173,170,538,594,780,402,195,573,164,661,428,446,875,262,89,87,593,750,906,905,469,198,395,933,546,834,967,377,633,278,3,474,911,806,975,382,865,361,237,931,594,351,7,879,981,964,557,23,289,393,765,538,891,620,99,932,929,434,759,45,47,332,606,52,569,461,646,415,971,329,623,847,143,650,820,109,252,707,841,251,185,733,319,629,259,99,668,4,332,264,25,283,742,949,943,701,286,189,214,657,780,825,328,719,328,839,348,224,755,280,788,405,905,320,769,816,391,399,393,867,596,510,289,986,308,644,695,37,57,244,774,527,825,458,738,799,751,861", "873,960,457,808,563,409,895,731,631,850,204,323,21,392,890,511,67,493,244,862,176,590,481,237,361,441,291,204,223,345,973,450,794,336,362,191,604,210,147,866,610,813,219,357,230,977,838,692,70,912,499,145,349,11,668,88,685,652,6,585,523,400,381,254,397,175,700,168,193,153,266,731,492,489,928,752,488,640,997,63,540,974,745,384,813,528,140,436,904,740,288,770,212,665,258,120,443,967,652,312,755,177,622,645,384,913,532,702,508,556,269,358,738,784,640,898,719,30,290,808,446,92,976,133,235,956,138,276,800,489,438,411,582,183,103,180,399,850,881,890,491,540,486,452,714,242,29,695,118,627,988,816,565,134,512,356,217,954,25,659,339,810,384,222,391,739,347,579,641,875,896,300,449,332,373,546,400,692,691,522,750,959,139,559,471,830,74,0,802,974,933,601,728,774,807,532,5,335,476,642,373,556,958,405,332,305,433,957,305,832,598,94,626,303,81,779,778,437,793,709,756,973,486,817,400,349,621,123,85,296,213,788,811,105,506,682,857,974,998,99,636,266,828,971,605,204,563,801,824,799,912,423,447,55,188,112,51,70,32,963,386,826,907,734,274,723,951,584,359,722,777,453,218,738,428,299,489,720,22,671,976,549,661,487,652,734,218,759,315,649,282,944,344,322,769,953,227,516,560,752,904,543,479,61,153,172,180,426,338,634,460,42,151,240,228,964,209,920,8,502,326,548,957,777,375,657,794,794,751,66,44,779,545,870,177,97,458,174,434,953,93,859,269,421,308,894,536,504,62,710,269,726,536,119,406,408,644,10,240,58,731,528,433,103,344,98,459,212,35,837,751,738,820,491,766,702,292,60,641,9,123,676,617,762,878,390,670,451,859,155,654,600,321,947,688,994,38,256,106,990,983,868,794,459,287,328,449,789,743,377,957,412,152,693,494,816,987,136,486,613,903,473,43,234,615,409,483,443,336,206,405,645,25,178,126,921,162,307,318,87,508,819,626,633,446,181,709,315,581,666,747,250,137,834,239,533,940,219,948,176,263,54,349,937,991,345,724,580,563,668,982,256,282,460,701,339,567,195,382,927,449,497,125,81,129,82,947,786,657,556,148,124,157,585,278,480,716,46,537,175,475,136,247,978,261,506,777,757,750,738,264,247,373,961,34,798,294,534,567,547,817,21,523,391,672,137,811,644,532,913,23,540,741,208,715,808,688,798,980,255,115,492,434,96,583,399,814,114,74,881,818,930,7,343,953,446,925,708,97,925,126,886,785,980,908,674,735,139,268,740,30,526,402,288,579,836,118,403,597,9,131,698,193,86,479,594,442,705,844,366,699,644,336,708,693,809,822,34,910,230,182,928,636,716,219,836,76,796,62,480,930,868,993,68,380,819,693,776,212,657,96,127,865,763,631,80,445,659,112,223,947,792,515,439,70,560,766,661,896,172,835,872,935,44,942,831,570,550,906,586,952,170,842,548,255,464,665,594,467,341,878,897,451,408,423,780,755,923,380,327,968,542,8,7,307,604,347,720,105,641,853,5,377,272,926,680,176,772,862,855,708,292,939,691,841,206,545,565,764,488,887,847,947,565,226,366,934,146,673,695,84,354,751,192,309,603,316,387,160,134,307,905,820,767,465,251,464,483,755,243,686,175,31,145,764,10,687,23,594,749,680,896,792,75,762,399,715,757,223,597,570,868,921,257,103,290,245,60,843,899,325,115,168,93,338,97,970,832,407,561,933,66,776,172,675,871,478,612,699,881,877,564,241,538,243,941,81,759,628,64,381,657,994,500,679,181,100,386,616,622,971,879,650,895,827,580,975,458,64,99,780,575,702,250,579,222,387,246,211,62,638,261,799,570,336,12,792,196,29,598,820,432,223,825,152,202,996,94,871,742,39,744,947,713,869,415,751,938,421,386,268,114,284,424,846,885,26,691,479,302,876,571,888,312,329,961,25,330,261,870,222,342,290,985,746,669,432,798,307,82,234,361,407,191,551,418,812,217,894,626,57,860,338,141,395,779,867,523,864,562,14,454,267,640,561,984,285,669,105,844,133,795,415,527,489,664,331,413,979,373,690,32,330,358,886,917,608,725,417,122,337,476,737,746,895,946,732,888,390,333,839,384,182,295,278,301,205,921,231,486,196,894,250,162,442,845,417,646,853,679,961,139,210,388,895,982,848,698,142,591,965,938,222,450,668,181,411,661,321,230,187,751,144,707,191,972,112,147,478,615,128,749,530,570,518,3,605,538,28,884", "8,488,259,973,165,222,212,795,658,870,897,817,927,784,774,494,235,166,920,238,926,598,421,653,395,296,454,785,178,759,548,144,186,935,988,699,372,974,787,540,235,356,220,900,181,958,348,305,150,86,851,908,405,60,186,288,534,992,627,550,495,761,613,38,742,900,972,576,20,490,2,610,596,499,660,555,260,123,695,942,215,953,534,869,942,39,782,965,455,539,825,636,464,739,677,430,727,166,850,846,537,848,147,576,791,658,653,994,730,849,354,575,717,804,187,306,290,805,646,554,900,413,785,502,475,980,229,84,233,916,255,132,397,295,440,602,298,142,290,809,153,247,453,496,737,555,33,394,847,691,215,478,568,819,649,238,655,964,2,462,916,640,945,917,591,601,526,729,88,230,539,392,798,618,354,350,508,284,380,270,353,180,242,52,828,20,66,802,0,458,815,870,397,298,404,829,650,961,811,926,795,629,425,313,930,96,875,555,514,747,465,73,744,364,458,565,76,572,207,607,969,379,791,180,825,684,429,423,132,638,404,550,237,761,597,520,648,326,860,391,617,865,614,93,51,454,525,396,310,471,349,385,318,576,591,132,197,38,162,456,830,891,47,632,108,968,297,163,792,717,344,118,746,500,24,389,529,644,313,861,251,916,753,576,365,729,133,773,28,948,789,998,137,66,642,778,351,174,672,265,329,225,987,540,751,318,94,258,870,726,394,988,572,510,106,24,195,859,236,795,977,599,122,857,48,95,336,39,280,538,703,989,196,522,284,681,962,285,281,851,955,462,481,747,661,110,165,979,288,147,538,891,498,742,232,288,900,625,842,56,812,654,967,462,935,826,493,955,399,775,287,686,96,42,860,256,425,561,785,823,191,965,963,604,718,814,290,934,656,25,755,435,35,59,434,617,346,111,597,968,455,417,472,157,30,829,788,226,55,580,575,327,135,94,893,757,226,295,801,934,992,588,45,791,948,949,810,229,498,852,191,709,372,606,762,80,192,634,869,358,926,162,201,470,238,686,748,341,702,278,745,835,950,257,809,357,756,870,931,448,186,464,554,829,359,95,913,661,410,529,586,767,468,438,215,736,582,943,324,286,43,534,907,36,975,258,86,618,670,878,135,978,920,802,281,552,622,303,386,351,332,781,73,438,314,311,72,517,3,499,548,672,285,992,759,859,116,88,868,324,520,614,812,352,777,615,724,477,833,945,587,360,54,582,20,446,967,604,731,390,407,851,205,186,988,8,576,314,520,273,641,285,887,453,793,326,754,69,491,825,120,210,950,469,986,784,762,685,17,373,184,875,839,367,300,661,894,483,873,121,774,655,902,450,938,337,991,380,974,349,547,265,108,184,206,246,230,483,182,22,198,292,841,712,213,884,748,142,474,604,555,484,835,917,672,637,377,626,395,153,162,82,830,879,84,473,97,811,131,272,120,247,583,702,309,950,863,704,803,255,133,154,540,587,133,167,23,854,711,186,341,290,980,60,581,163,494,45,817,571,566,403,529,46,904,941,453,865,632,312,275,326,451,233,737,520,586,820,150,614,759,427,993,521,387,204,9,640,420,158,398,616,649,355,536,311,41,720,24,642,877,136,599,2,978,594,46,949,328,763,19,933,177,10,97,733,139,63,155,881,277,298,981,57,242,307,257,583,151,647,504,620,744,603,927,512,328,404,2,172,974,821,849,736,414,126,767,56,343,264,182,455,423,530,450,875,31,142,234,56,206,707,227,175,191,413,140,937,520,39,505,979,661,699,787,413,220,858,575,998,605,559,484,692,501,737,938,959,299,930,17,279,867,125,754,571,38,484,268,550,797,440,882,756,121,476,56,275,328,12,417,788,14,123,958,405,553,837,116,393,55,134,747,588,890,609,551,426,553,539,751,322,747,44,963,28,551,32,67,689,889,139,474,487,178,959,200,670,968,45,709,778,500,927,256,511,141,853,365,631,759,143,118,877,828,557,64,849,778,644,296,317,662,734,387,851,468,264,351,936,922,623,83,199,621,588,562,872,366,530,494,856,835,250,607,800,821,756,473,521,697,601,847,857,416,4,338,587,240,569,869,97,93,120,54,308,372,661,932,378,271,234,819,399,30,124,36,145,854,527,271,486,655,378,783,874,92,816,351,397,968,219,278,186,29,427,915,822,613,495,701,156,657,459,38,284,485,62,237,593,153,105,906,35,201,647,6,996,613,353,620,735,856,739,114,537,698,420,887,561,802,573,274,834,571,267,886,251,158,212,549,437,420,205,600,743,559,621,892,472", "708,452,348,66,217,559,873,633,639,876,506,498,892,791,460,786,220,574,199,666,793,622,25,41,182,783,24,203,899,95,108,74,78,994,98,726,487,650,89,461,262,780,214,742,299,190,152,396,803,371,521,207,622,390,263,419,234,187,541,879,88,37,428,98,600,639,305,551,811,288,101,198,739,278,428,237,824,34,788,565,992,625,667,184,620,998,311,379,204,508,550,905,972,832,431,474,266,430,77,286,921,563,425,560,929,856,240,658,500,620,199,175,853,873,668,826,16,389,931,596,198,271,274,752,478,212,636,161,996,101,569,197,900,23,206,38,881,425,586,122,860,665,578,950,576,434,28,57,333,541,727,465,294,842,622,669,290,494,156,334,300,292,264,157,194,93,303,763,890,690,468,588,124,67,651,216,552,625,67,969,196,317,491,410,895,696,682,974,458,0,985,781,86,383,638,451,374,60,904,401,587,877,814,928,813,15,229,932,949,914,910,362,225,837,567,145,859,343,69,849,474,503,703,763,671,492,980,399,668,410,429,874,426,826,16,471,567,390,258,663,192,902,949,281,473,492,174,993,72,899,381,908,191,558,607,110,998,191,431,843,974,701,346,995,34,764,671,197,773,801,742,782,70,649,412,704,525,286,700,477,413,741,969,876,647,417,336,152,982,574,965,710,544,662,781,93,985,213,880,207,881,427,751,141,458,993,46,420,936,382,785,392,594,129,708,766,5,309,346,293,77,115,595,65,676,175,545,501,374,152,435,473,234,912,446,399,676,705,818,429,768,503,993,977,440,685,890,521,976,961,146,668,644,796,929,109,84,694,950,15,573,161,248,606,9,13,321,207,265,449,189,13,13,280,576,847,463,561,227,109,1,620,597,369,528,326,798,385,258,182,817,980,36,305,927,588,178,184,679,685,718,665,406,260,851,684,405,366,708,874,777,218,649,231,301,815,841,483,650,959,934,9,87,365,516,391,918,487,263,296,79,450,92,409,671,730,85,176,349,948,456,470,746,926,687,781,230,202,721,144,280,548,453,452,432,213,642,164,423,540,817,445,923,137,346,779,411,753,216,497,426,681,23,380,203,293,97,311,222,706,177,526,89,68,636,604,943,991,752,701,193,191,340,208,574,886,3,424,78,867,97,566,150,66,967,711,510,796,675,165,318,685,225,874,263,744,148,986,491,678,182,250,815,72,218,90,968,337,79,44,332,749,381,570,909,273,955,626,948,589,636,165,568,121,526,67,640,871,723,183,837,162,216,432,96,286,586,808,113,88,903,393,134,795,594,208,796,708,670,221,993,867,696,96,314,904,636,179,240,144,211,21,937,563,934,402,440,185,671,831,169,73,42,71,967,563,999,200,786,931,862,51,46,330,431,276,566,145,489,164,993,608,479,801,242,404,279,750,18,341,206,710,356,605,198,705,795,648,768,872,981,568,811,796,522,234,312,219,915,371,945,687,286,531,920,916,116,532,828,769,227,554,371,576,740,660,126,926,981,63,324,409,391,204,595,960,967,635,869,802,404,899,977,453,709,966,450,378,422,165,630,332,979,505,651,520,965,572,44,121,783,241,145,8,130,659,563,883,501,504,500,996,634,791,193,363,576,564,592,890,201,703,941,604,777,452,775,894,71,981,154,256,231,24,109,878,158,915,426,462,572,919,23,534,464,91,936,828,344,175,426,998,616,931,983,561,930,896,494,188,150,180,199,904,419,756,260,330,278,917,97,489,401,214,931,698,944,516,632,729,207,475,59,703,93,381,287,92,825,401,711,355,530,976,283,355,730,994,499,686,269,320,925,286,317,213,901,506,127,332,887,51,52,186,623,203,69,585,267,316,787,152,784,891,435,766,757,62,925,833,516,525,806,860,794,925,634,411,416,123,565,737,193,839,977,234,580,490,444,362,963,909,455,797,846,570,3,838,336,458,629,877,114,746,568,577,245,74,956,579,820,212,840,341,78,527,852,790,297,869,625,742,815,96,41,388,216,786,240,444,912,681,493,262,344,783,260,736,260,570,654,706,474,50,281,384,831,361,801,260,365,601,590,133,417,47,567,123,374,612,53,590,328,844,237,287,752,958,45,569,91,910,402,54,574,241,666,547,212,504,412,836,643,287,326,814,297,148,821,401,515,886,987,394,993,470,491,736,589,662,802,639,817,676,555,320,922,348,770,9,929,77,206,153,154,420,971,688,662,643,82,539,550,458,476,728,866,198,682,367,970,478,787,195,579,525,433,347,738,530,83,904,565,847,161,147,16,294,476,531", "268,407,990,918,116,641,589,419,993,109,84,670,512,25,506,913,452,972,6,842,482,648,297,151,810,735,619,529,708,563,549,739,331,680,130,296,231,309,348,815,500,266,636,761,603,547,543,578,700,138,930,718,650,521,520,617,114,478,797,770,353,119,794,787,190,549,445,91,760,762,140,845,646,102,924,709,324,727,620,639,360,564,138,219,434,181,974,620,922,700,674,908,708,915,624,640,934,535,788,250,975,657,495,765,723,853,601,8,152,868,989,666,248,714,818,42,819,488,752,461,290,179,451,715,700,932,897,309,765,344,929,821,625,87,570,452,620,148,866,198,257,62,15,385,651,477,207,670,418,814,245,183,331,113,314,768,488,60,522,589,504,650,68,193,660,133,188,307,730,318,777,431,387,726,541,393,142,615,613,432,39,426,941,774,121,707,746,933,815,985,0,626,305,965,764,631,227,597,297,114,869,367,709,588,607,842,222,858,36,48,484,940,654,759,220,359,173,52,580,773,638,749,348,952,510,597,123,188,879,773,397,310,815,395,288,799,322,442,827,48,895,911,837,280,195,664,682,720,750,464,292,410,632,369,550,916,838,909,348,730,141,82,601,588,50,860,757,532,206,680,751,821,949,8,629,840,617,155,330,80,519,284,63,466,171,203,804,815,57,367,515,461,687,838,255,546,205,201,281,451,180,737,708,935,883,25,735,62,888,239,238,662,713,586,134,877,639,910,631,521,131,379,803,712,443,106,23,452,804,857,41,618,776,422,313,555,106,975,905,449,984,204,649,82,517,142,604,503,193,650,874,609,432,288,621,601,716,150,535,486,411,743,539,640,290,871,948,774,135,650,285,984,514,935,291,164,959,346,633,750,980,786,763,263,723,358,210,92,747,21,405,263,760,653,203,558,405,102,616,234,535,488,218,701,51,308,68,341,840,605,271,841,646,259,482,370,906,405,515,715,872,401,791,533,856,60,866,553,369,605,276,946,135,593,245,62,230,863,172,895,562,169,462,835,53,518,900,447,867,930,758,757,600,419,759,55,598,741,138,298,910,735,228,691,938,365,407,493,171,45,944,513,807,803,434,420,194,370,702,504,557,671,597,839,302,156,819,295,427,92,248,907,46,621,64,798,819,593,394,706,719,677,959,211,394,671,668,510,282,27,406,375,387,931,832,594,512,511,844,123,501,778,789,576,937,370,182,207,427,629,894,778,171,485,411,239,745,452,163,205,168,473,43,267,403,265,779,859,114,466,793,294,932,273,79,392,768,308,477,912,367,582,671,857,650,996,66,76,110,359,274,338,913,687,982,250,441,350,146,683,920,627,111,390,853,502,111,359,409,803,708,667,161,826,815,368,247,504,548,791,674,199,515,928,455,266,916,676,358,830,562,926,928,612,873,637,934,970,668,740,925,224,480,704,913,874,951,685,905,677,691,422,740,409,278,503,784,354,816,344,846,304,860,502,28,300,696,457,631,922,842,551,739,619,699,728,559,448,926,367,691,357,314,194,889,651,271,123,579,669,395,337,357,999,183,948,971,85,692,621,414,822,735,419,775,130,953,667,766,912,42,466,588,291,255,286,168,309,437,500,428,946,848,286,639,316,128,352,991,681,28,660,873,760,195,640,302,886,95,530,117,592,60,461,717,299,405,295,568,585,521,480,919,315,545,304,74,320,505,962,906,89,811,806,160,83,191,159,919,385,764,777,70,187,711,930,55,231,204,326,417,611,339,652,338,687,39,8,511,832,770,555,72,396,163,990,18,87,130,764,314,362,142,104,609,220,130,685,594,701,888,864,190,279,901,635,67,385,266,486,284,901,483,575,819,26,639,954,630,53,295,998,15,355,362,793,130,853,820,890,43,384,571,200,887,476,727,527,904,434,215,166,830,887,718,206,733,526,675,916,14,316,55,517,979,232,859,81,761,366,221,278,278,265,622,217,169,178,705,861,101,29,943,572,657,548,769,542,975,938,540,549,435,323,891,120,571,187,916,938,285,220,386,841,34,121,842,323,320,649,588,42,170,144,866,454,352,547,741,86,314,973,57,552,245,924,31,861,476,516,24,698,708,614,753,893,338,195,185,605,594,339,262,722,175,781,595,113,884,312,968,264,915,151,691,416,871,946,246,421,594,243,683,733,300,171,597,421,867,518,579,96,426,548,666,127,190,388,668,132,391,141,680,859,687,784,228,742,374,760,574,662,503,143,638,884,74,791,788,917,546,246,593,409,293,465,424,344,672,299,200,385,708,651,165,392,360,298,749,503", "177,844,365,456,528,570,171,666,433,984,563,61,908,517,905,467,676,223,186,448,762,440,433,685,423,702,846,807,708,765,226,614,572,386,926,313,663,539,107,613,581,472,560,540,714,14,956,85,571,484,284,845,337,144,417,24,333,541,308,639,521,272,415,58,941,386,253,423,408,497,557,467,602,937,117,268,954,104,432,202,387,210,121,833,762,19,65,896,329,526,352,259,136,715,847,893,870,401,637,838,1,642,133,756,87,700,624,732,82,294,622,368,33,37,932,612,795,758,34,533,56,252,785,494,89,628,574,620,140,899,928,255,73,354,687,235,702,499,471,16,976,105,517,205,839,766,577,103,617,419,574,760,696,196,89,383,429,58,986,655,415,522,806,29,899,676,150,223,292,45,173,717,703,134,911,539,221,545,191,851,471,496,745,598,62,593,305,601,870,781,626,0,144,701,517,577,190,386,432,528,664,914,369,11,544,674,34,687,757,223,574,264,537,501,208,679,618,700,259,981,480,351,904,648,15,985,530,759,231,428,341,457,10,629,222,303,186,845,191,54,822,176,613,690,966,542,221,81,436,757,313,288,413,244,522,700,420,258,856,351,925,350,532,984,451,335,551,341,683,577,412,391,498,478,432,340,115,822,962,253,930,456,213,80,232,544,455,625,549,10,485,869,697,605,444,677,153,681,359,775,715,73,685,679,887,132,331,176,229,973,894,110,897,171,801,954,116,656,834,41,411,175,972,603,346,20,839,5,695,841,186,271,248,337,946,246,323,749,874,960,483,725,258,684,298,992,279,568,366,279,810,650,939,583,186,49,696,718,305,22,489,983,135,262,97,612,65,818,672,276,213,450,93,884,777,259,485,61,134,392,381,882,886,66,144,356,334,806,560,317,355,822,133,721,71,608,221,465,857,601,646,910,627,867,646,134,151,98,352,38,359,812,235,326,122,876,117,990,788,22,308,952,599,213,509,577,829,803,663,620,987,271,579,479,465,732,51,947,839,784,181,215,779,909,58,706,908,984,665,607,976,638,948,556,165,874,873,582,182,488,629,295,415,524,441,687,512,662,53,953,965,370,171,65,875,340,298,457,339,77,287,443,632,897,408,26,533,732,175,334,814,639,458,508,748,849,100,263,93,428,762,336,184,145,596,631,480,947,450,885,30,931,668,147,229,796,393,642,486,830,316,85,57,232,831,877,381,826,249,609,874,795,558,325,553,939,426,872,294,183,121,756,832,529,85,781,882,233,538,91,229,14,711,725,760,718,21,685,818,76,531,547,491,327,628,568,600,434,504,286,96,886,39,321,811,832,453,389,95,343,452,713,434,588,352,209,571,331,987,486,357,634,852,886,663,483,20,407,462,960,69,22,443,585,900,770,607,721,219,457,692,686,149,304,70,961,23,875,577,65,926,451,782,303,290,944,171,663,247,194,66,724,385,809,508,629,55,94,72,785,286,219,475,915,512,778,174,668,774,887,852,307,172,768,3,743,341,227,454,464,15,730,503,437,835,250,306,964,382,489,866,150,834,351,613,209,303,535,465,843,210,476,109,195,185,96,859,613,600,416,395,791,287,852,108,993,329,468,61,33,908,618,524,18,961,312,463,184,14,568,340,728,753,807,739,97,72,599,53,420,990,576,918,271,507,244,836,326,105,740,437,679,510,98,252,100,708,551,881,296,936,767,548,14,193,215,78,298,522,680,621,167,480,157,389,359,240,853,445,289,430,441,284,954,474,33,839,47,822,247,99,95,928,706,276,834,207,74,923,203,292,444,777,242,105,814,974,546,745,961,694,315,353,293,150,178,76,968,921,849,23,881,922,508,302,202,979,943,586,9,51,717,241,570,66,381,9,50,403,484,317,520,474,78,700,375,295,247,701,640,274,761,120,157,162,43,329,33,424,502,838,334,507,755,143,746,893,270,817,994,75,520,596,91,40,799,893,151,399,813,164,373,640,61,500,719,224,241,868,452,140,251,607,284,7,26,458,44,136,420,827,498,619,998,975,398,828,354,624,780,852,754,730,798,804,654,40,931,538,339,395,367,421,782,439,437,278,701,838,766,48,117,844,327,809,119,899,153,365,768,849,716,375,47,525,846,997,429,376,781,513,553,65,486,363,796,404,552,379,969,435,551,750,433,947,537,584,764,344,210,853,12,29,847,722,172,449,972,500,464,95,638,671,674,584,295,519,675,123,824,180,958,334,206,533,389,988,468,355,667,679,97,724,480,898,347,877,769,200,552,492,154,422,812,395,638,207,456,409,973", "722,390,284,370,285,185,625,491,715,273,739,545,721,115,286,697,32,418,808,591,885,791,486,240,345,991,257,618,511,416,185,318,794,325,766,526,525,615,810,391,253,345,410,240,486,329,811,196,636,350,251,694,361,941,898,500,200,39,103,867,370,647,381,132,820,39,163,241,875,844,367,840,532,279,222,638,791,483,565,426,131,187,791,781,361,271,499,118,919,805,246,818,986,281,821,57,837,429,491,455,52,476,488,732,261,897,215,768,992,375,213,726,150,764,440,722,892,437,578,393,379,656,240,435,273,64,794,94,301,159,93,172,745,201,396,820,872,482,884,225,432,425,702,707,626,635,731,610,962,950,373,912,461,482,291,705,915,680,628,876,33,628,395,995,49,364,944,351,536,349,756,342,670,612,200,77,353,523,415,424,428,519,315,786,944,965,516,728,397,86,305,144,0,641,310,951,324,847,137,484,150,320,951,695,93,881,62,315,213,63,665,426,119,470,781,585,866,727,636,640,387,959,617,89,339,269,10,327,468,766,409,713,447,493,146,361,332,910,491,928,685,537,242,700,651,469,154,195,216,668,785,340,708,67,930,149,278,427,113,536,225,306,872,343,67,61,50,569,219,438,818,813,268,263,893,678,99,620,855,516,93,22,762,414,863,301,924,161,129,246,969,776,494,319,57,191,169,953,982,355,263,429,588,69,964,12,399,150,688,55,412,511,431,574,873,329,501,69,487,228,149,377,491,900,404,687,443,154,292,818,814,959,377,605,151,623,412,882,34,689,66,109,915,435,568,446,603,151,244,309,29,845,954,760,707,879,287,791,622,868,290,675,979,453,173,499,559,649,367,708,99,456,783,20,205,72,780,483,677,692,473,196,137,880,23,827,76,305,468,646,898,459,465,487,19,104,222,667,402,574,520,812,845,319,74,998,771,590,951,967,99,548,523,753,983,203,73,430,704,349,674,888,522,41,68,287,478,512,238,667,578,981,950,341,135,430,769,346,320,607,408,144,372,50,781,964,438,469,428,5,42,345,809,482,507,227,727,605,207,488,970,562,34,546,319,841,263,315,224,932,19,136,972,816,499,808,628,182,744,476,549,420,6,29,644,542,348,873,921,617,153,845,328,691,489,39,488,520,758,821,246,633,951,395,322,650,259,427,741,838,517,595,40,714,731,499,547,306,870,539,289,812,709,918,591,800,173,376,948,320,797,599,375,944,69,442,193,663,847,149,637,561,778,153,372,511,338,374,321,387,225,528,622,98,150,434,783,284,37,550,384,571,634,65,187,893,599,631,8,584,38,541,967,272,246,445,769,943,333,658,864,586,346,226,74,871,505,972,769,229,547,331,82,863,408,137,256,313,756,221,915,392,658,613,609,885,358,226,352,413,240,339,278,654,883,441,824,779,754,493,982,389,792,175,158,225,528,419,59,717,59,757,510,317,362,174,344,88,726,930,805,754,443,631,962,799,166,956,25,862,23,80,851,508,836,434,334,729,389,383,775,275,255,796,187,891,166,397,334,578,490,805,176,809,46,214,901,414,868,272,773,752,784,720,57,369,108,315,256,947,78,679,414,603,357,459,573,388,670,592,94,154,194,691,112,418,939,554,489,851,300,97,497,767,926,706,488,928,674,42,883,266,495,88,7,184,690,446,695,962,109,779,482,985,661,52,394,539,926,987,51,713,105,210,983,334,522,36,514,346,901,602,286,723,926,385,877,122,322,220,302,274,94,585,759,644,778,106,266,811,862,481,214,680,386,628,902,729,352,15,578,704,231,968,852,551,888,767,211,414,392,551,921,384,971,678,401,250,35,509,390,89,934,384,567,526,598,224,969,812,646,394,114,368,521,954,400,807,736,689,441,785,634,334,552,909,708,448,390,641,128,678,874,257,149,516,920,671,94,490,980,964,88,58,228,175,130,157,503,105,238,597,405,73,782,205,242,544,893,638,403,658,251,547,771,42,55,224,847,731,732,461,874,471,848,348,253,59,714,513,635,230,872,94,840,626,862,256,445,409,370,505,251,542,205,964,679,64,583,394,341,98,681,678,879,742,73,615,240,53,702,553,262,22,118,744,122,166,316,764,508,775,523,599,476,18,397,697,318,831,598,439,102,383,505,876,614,536,769,966,854,110,378,502,78,599,578,856,313,406,277,143,974,763,43,897,273,679,267,332,429,677,149,171,805,136,543,626,366,403,72,346,114,54,264,438,192,537,20,588,151,698,11,368,946,191,421,631,406,923,653,565,779,48,637,777,421,253,944,116", "49,619,260,723,413,33,558,146,489,167,84,837,508,576,538,889,838,517,652,822,147,620,417,260,389,787,878,869,295,849,560,663,123,247,817,674,258,992,944,678,592,339,288,852,954,885,419,939,126,953,487,909,352,899,267,68,953,464,708,840,545,442,401,737,336,350,243,605,396,760,893,335,436,620,948,894,715,21,725,142,500,110,821,911,974,401,257,40,631,459,237,820,390,278,514,234,807,72,319,214,30,742,894,905,489,808,785,957,1000,558,583,819,524,81,11,711,67,161,810,710,363,230,691,492,595,876,178,129,90,210,965,736,713,487,412,538,326,922,270,849,764,14,507,150,688,815,486,282,571,360,544,964,31,10,859,304,332,644,16,874,512,333,974,725,409,625,494,860,840,650,839,392,50,462,50,940,203,889,173,743,85,111,424,929,171,160,405,774,298,383,965,701,641,0,834,959,886,542,142,240,469,722,959,583,773,447,624,340,352,853,222,488,680,131,191,90,344,307,448,899,640,40,760,188,880,466,606,138,835,155,179,372,348,842,334,930,313,186,189,690,346,548,464,532,709,7,543,989,925,660,425,82,700,395,695,517,269,705,528,784,561,833,51,498,958,378,61,549,389,226,415,573,876,658,903,160,586,903,897,476,202,808,376,744,473,888,75,785,98,660,527,588,611,946,488,18,932,891,623,625,498,132,547,196,773,787,165,535,734,777,362,290,273,102,563,513,579,916,317,799,740,717,884,198,207,262,209,866,82,331,494,800,685,950,908,411,988,878,698,748,931,810,404,747,611,286,334,925,495,467,969,506,811,61,799,240,144,459,413,378,229,807,871,273,626,80,533,806,760,82,416,148,954,211,734,475,666,581,516,76,47,359,515,962,99,760,358,647,913,956,178,621,508,926,838,937,414,725,358,497,312,103,416,190,783,506,155,779,123,854,198,860,897,79,54,170,831,219,258,694,890,56,233,89,800,434,398,436,590,182,515,421,266,476,652,824,491,235,868,217,714,857,16,111,752,195,520,770,52,83,425,266,626,269,93,494,901,618,68,612,927,987,666,739,578,181,278,711,374,95,883,409,151,210,300,391,220,363,984,252,489,641,283,173,827,494,107,993,226,364,430,136,981,493,553,938,313,703,534,471,665,678,99,944,468,329,532,840,947,262,24,353,992,837,987,464,871,465,874,94,856,907,133,492,20,884,729,738,164,629,770,536,240,707,294,685,397,535,617,62,402,730,402,313,288,597,254,780,810,211,665,163,260,658,868,672,150,317,684,797,646,47,644,4,822,865,516,655,459,54,414,96,514,225,380,909,706,637,713,499,555,519,862,604,196,968,992,943,24,624,257,908,267,126,351,816,637,638,19,842,948,904,345,459,895,102,766,926,670,186,919,994,412,609,852,100,384,695,352,189,903,343,286,953,364,194,561,962,36,126,100,737,891,589,899,16,583,731,293,44,38,707,692,905,772,22,796,175,766,193,896,304,418,474,356,752,781,320,935,68,725,594,797,341,119,325,452,416,190,755,119,117,692,803,731,568,871,482,512,724,761,15,570,153,514,388,721,92,810,675,576,253,217,922,808,106,911,247,411,558,401,186,920,887,396,337,541,727,8,925,353,552,880,624,540,371,289,983,59,80,511,782,952,345,864,714,416,670,159,399,199,215,341,279,606,595,959,80,107,371,848,294,333,36,516,262,819,327,874,73,485,748,865,440,679,944,375,868,180,642,550,493,261,484,629,789,905,905,127,936,332,61,944,887,746,249,718,150,659,385,403,501,737,548,396,657,48,587,118,509,784,765,139,823,791,16,331,600,933,722,449,221,848,928,194,72,212,735,878,610,154,718,871,915,996,857,974,454,87,9,390,794,855,430,99,32,297,846,384,853,480,432,333,32,772,192,442,927,115,910,974,611,354,541,660,699,745,835,950,839,592,353,933,713,740,78,463,139,760,883,202,714,986,883,29,499,993,111,35,254,661,447,200,825,855,289,693,598,268,902,334,640,487,438,649,15,409,85,156,939,957,679,19,112,87,95,829,456,240,784,730,935,326,506,683,863,894,877,680,121,243,471,608,560,531,71,247,974,738,985,476,687,787,369,438,125,713,218,248,541,909,156,220,121,815,427,873,338,264,933,49,780,86,198,104,683,800,412,399,661,908,976,266,751,328,75,284,827,522,543,953,207,967,342,713,300,794,859,668,574,612,525,572,97,651,242,897,641,175,682,193,159,566,329,913,605,266,787,822,206,720,121,30,102,937,959,314,486,541,849", "448,477,652,118,431,389,770,905,956,528,710,327,346,414,744,413,494,407,82,228,945,963,202,169,604,460,116,230,101,512,344,82,941,744,865,299,305,825,750,88,167,742,828,239,737,23,879,384,294,500,706,240,784,572,715,502,489,976,910,264,778,814,743,374,19,197,904,399,401,53,823,860,285,913,778,235,552,261,746,197,813,517,27,509,828,808,615,974,917,696,218,750,683,804,150,427,972,836,384,982,338,187,325,397,20,513,433,239,651,292,332,733,206,800,256,841,82,731,388,885,901,650,939,237,257,270,560,725,950,976,543,192,983,189,164,174,317,87,629,886,582,449,499,516,829,193,669,228,537,457,95,85,231,682,185,731,416,55,675,823,244,530,922,737,87,218,436,945,421,211,328,317,540,671,139,899,431,279,68,145,877,239,370,25,388,184,275,807,404,638,764,517,310,834,0,255,610,623,78,329,197,729,83,868,549,921,141,431,496,976,933,700,510,358,512,413,930,750,517,371,283,276,751,492,624,786,400,829,571,387,267,836,837,742,19,697,18,765,439,728,990,269,354,375,396,376,439,544,438,342,236,462,648,32,598,911,956,521,859,488,805,473,338,401,585,600,629,227,169,321,232,743,519,849,698,627,78,512,868,886,901,457,206,692,126,773,991,231,430,368,508,804,471,335,119,794,401,38,66,853,366,421,467,613,704,135,668,39,662,815,248,541,523,541,366,272,580,123,607,839,167,835,271,185,716,114,813,8,839,14,610,765,554,102,230,44,354,304,431,731,300,794,183,802,174,76,554,223,865,283,382,827,356,750,512,155,971,258,876,391,320,120,394,73,865,472,373,559,875,37,872,16,826,193,966,577,820,513,335,500,779,507,944,869,204,84,377,782,898,75,385,650,728,658,920,287,730,24,634,958,363,275,903,55,12,459,493,678,267,613,654,21,547,97,555,373,751,513,190,887,887,590,304,325,347,627,565,549,513,940,883,722,194,706,602,258,17,977,128,70,266,53,455,532,141,419,840,813,183,658,838,882,914,109,17,108,399,880,742,796,855,552,162,122,593,650,914,833,790,271,343,356,346,269,169,820,546,250,595,731,366,797,625,576,629,877,876,699,755,665,671,915,337,747,861,284,254,129,644,972,172,280,996,109,996,831,805,747,655,197,273,376,896,737,885,410,150,973,39,491,284,741,749,536,142,677,898,43,741,690,766,960,843,273,203,809,554,277,311,472,740,130,857,213,595,91,786,651,431,228,692,711,420,269,324,275,750,279,761,633,348,282,645,966,454,670,408,608,395,24,845,28,895,171,435,10,176,317,945,2,55,810,858,349,378,629,277,431,731,32,504,366,119,814,392,397,593,771,497,511,197,544,766,758,429,295,400,101,444,848,459,680,907,254,986,113,538,891,57,325,627,343,798,16,290,108,883,55,896,830,417,9,78,152,455,432,807,555,753,793,38,678,640,813,928,981,360,43,585,182,79,387,272,246,542,245,801,887,248,471,420,486,512,883,326,362,909,27,159,922,67,302,699,903,235,75,100,778,336,525,490,224,823,787,491,370,40,683,677,607,115,595,771,172,947,230,479,981,964,592,762,763,321,997,569,527,535,274,721,979,423,249,662,885,513,5,758,86,732,447,805,941,882,71,216,500,480,270,753,676,205,104,6,444,64,322,462,608,525,308,557,682,490,485,151,152,920,364,261,433,550,161,671,466,380,767,422,361,204,270,312,15,291,333,609,957,277,912,608,175,27,694,459,727,266,800,973,591,843,74,572,737,748,603,567,312,47,640,569,660,546,128,201,355,577,287,193,880,751,26,830,815,630,345,692,944,532,539,814,999,127,355,326,979,646,650,862,8,609,863,538,970,243,927,554,812,692,843,461,715,651,531,859,773,958,346,506,82,397,941,728,118,546,975,378,647,485,916,17,145,671,534,597,2,745,631,890,340,811,95,69,508,150,791,734,261,855,802,536,820,221,627,67,727,957,230,72,582,54,121,696,779,727,535,992,933,386,865,127,682,831,833,156,655,459,5,456,562,890,564,342,511,560,174,494,485,551,806,81,177,632,809,516,231,914,236,836,79,19,680,41,437,237,188,461,485,238,861,558,844,233,845,984,504,328,34,665,349,414,744,238,496,779,198,401,825,715,247,31,4,291,306,226,146,361,860,852,613,956,856,46,421,356,465,898,637,866,704,383,821,493,400,508,123,493,125,326,939,411,397,351,704,704,723,741,431,173,209,679,8,539,859,780,459,187,398,222,332,637,500", "849,822,788,301,736,435,356,454,860,279,906,532,279,831,307,105,375,721,808,692,86,244,606,823,306,720,512,337,580,864,760,781,728,880,148,123,723,645,898,782,122,463,733,91,747,282,481,506,112,393,61,897,846,266,126,852,921,774,423,376,318,679,645,310,319,552,595,321,303,218,448,846,251,96,195,291,233,957,317,562,397,182,352,147,695,762,311,908,474,827,989,270,112,472,915,571,802,859,116,757,672,454,209,290,452,110,32,927,785,335,242,331,759,690,585,564,374,392,56,684,928,913,501,25,879,111,574,161,246,482,262,145,661,937,175,110,126,184,895,667,764,93,868,533,133,166,485,503,168,448,651,738,491,84,118,980,598,291,14,960,521,849,984,930,623,891,916,340,646,844,633,217,395,213,219,825,656,255,138,844,502,939,260,953,87,742,97,532,829,451,631,577,951,959,255,0,852,654,988,722,437,98,881,954,366,958,448,123,908,81,799,183,792,697,500,719,878,658,299,605,13,352,458,324,722,937,286,913,932,782,36,969,528,803,65,649,489,119,561,533,813,697,439,480,679,685,291,965,184,804,132,348,325,5,763,366,952,197,407,100,846,950,169,145,517,671,464,118,755,350,58,541,979,502,800,925,922,591,82,181,540,211,92,793,657,288,263,855,530,793,386,467,658,188,263,48,60,540,881,823,929,919,579,684,699,66,869,645,411,991,99,236,327,251,508,384,126,498,992,598,120,743,290,840,548,14,664,928,643,716,438,912,900,157,54,711,166,897,397,756,805,899,84,73,374,36,761,501,84,817,280,578,984,458,682,93,280,490,644,154,45,569,449,563,83,250,743,525,763,334,212,18,677,560,904,246,846,406,719,416,360,807,620,769,998,385,725,493,207,648,735,806,262,601,780,904,767,193,200,288,101,364,730,825,444,367,634,187,157,324,947,2,506,127,89,964,985,266,429,868,804,518,64,328,9,635,257,17,936,526,954,698,313,385,537,749,419,662,326,121,771,509,178,490,737,52,261,689,953,31,666,825,85,264,726,290,500,807,609,749,334,459,295,884,170,523,790,844,882,886,782,304,154,740,118,420,284,204,559,582,202,92,533,410,639,905,291,17,165,421,641,896,891,408,418,3,731,418,91,540,981,489,815,631,463,403,974,83,24,798,150,376,945,146,514,112,251,629,208,59,35,670,798,930,857,620,949,24,219,267,78,64,554,179,996,832,770,421,882,393,932,386,767,227,378,634,555,969,298,65,54,849,512,34,443,728,217,647,60,18,121,164,911,84,513,768,439,337,183,919,434,630,925,837,199,555,834,618,23,663,337,967,645,243,533,912,359,281,961,285,71,116,210,636,754,793,641,202,711,168,766,823,510,111,701,654,603,390,591,642,764,266,128,393,720,290,703,96,768,69,227,940,131,744,511,857,209,308,901,105,229,497,280,89,778,916,47,337,744,424,759,927,776,709,996,375,222,872,591,67,986,24,888,707,966,705,330,275,829,738,29,332,797,167,80,548,139,965,403,898,496,35,934,257,312,109,340,173,500,420,481,66,892,886,841,217,32,940,596,545,98,367,637,132,419,287,421,612,713,530,585,881,436,498,789,533,104,291,343,981,309,659,20,231,624,112,323,467,279,214,901,138,647,323,219,956,16,919,874,444,442,608,862,679,763,512,599,125,209,808,327,358,484,221,450,902,487,191,493,351,561,754,421,798,345,712,722,111,67,664,640,452,288,853,992,676,952,398,585,728,660,530,163,672,890,583,954,511,711,603,412,876,820,141,790,326,122,516,405,248,716,767,116,359,431,761,411,770,708,668,725,676,351,206,501,787,766,745,648,190,471,887,919,585,713,656,283,971,800,448,547,668,182,534,338,231,269,578,44,90,12,320,347,548,619,18,454,787,264,877,476,606,139,44,881,825,896,633,243,251,289,984,846,863,473,990,165,840,937,860,684,928,935,25,282,202,972,59,450,419,309,673,685,622,845,227,443,369,578,956,760,472,125,381,698,515,331,736,73,126,1,370,942,910,26,413,60,361,820,498,600,608,595,873,806,879,594,497,724,57,776,835,245,843,997,254,171,372,505,74,474,867,530,213,592,941,130,924,519,893,746,473,407,331,485,627,636,829,271,888,650,466,291,61,90,254,475,450,421,157,40,406,197,787,124,642,577,666,73,575,679,231,723,221,620,976,788,170,603,300,235,594,603,883,708,361,357,783,985,531,804,652,954,773,298,546,278,307,723,159,332,411,143,115,588,537,673,942,291,944", "381,968,918,412,366,961,535,658,812,578,691,772,119,724,855,49,622,677,587,835,376,582,223,62,727,392,131,705,504,221,491,452,555,404,418,133,824,251,106,656,347,639,576,821,923,627,197,310,88,719,650,104,14,757,730,211,641,805,208,6,504,765,904,612,607,322,850,110,664,32,82,961,415,35,493,705,616,308,507,898,395,460,374,959,873,123,487,963,881,987,897,343,939,822,881,969,437,425,18,423,437,324,785,751,867,618,146,209,802,421,934,775,597,161,672,366,318,694,468,55,604,609,905,910,181,733,89,419,88,574,587,212,754,636,246,151,262,920,649,496,712,252,785,205,850,268,986,263,719,965,32,79,220,877,19,258,355,123,719,118,72,288,640,611,831,269,586,831,362,735,276,540,935,702,949,922,326,61,744,944,609,455,34,543,996,185,495,5,650,374,227,190,324,886,610,852,0,614,537,417,146,915,864,435,269,742,489,323,986,529,498,985,216,566,743,727,416,608,289,897,889,90,858,134,190,924,824,894,528,251,637,171,154,358,348,366,432,585,691,693,540,100,79,335,660,439,755,828,485,883,647,457,992,762,334,598,565,546,988,392,245,621,157,316,296,900,915,241,46,520,215,89,525,321,503,806,906,437,800,347,751,797,44,143,302,479,43,953,819,713,267,342,892,91,757,934,393,600,716,203,793,298,416,280,196,822,513,131,846,482,435,813,212,640,85,540,625,462,278,354,707,311,201,675,137,540,121,682,107,966,163,678,902,782,874,522,54,313,119,380,517,973,547,138,130,479,829,271,686,693,944,979,75,306,728,901,826,523,988,92,660,214,902,245,192,922,665,32,799,516,519,848,32,72,583,652,410,330,571,998,795,620,340,9,54,933,178,90,117,615,491,748,947,182,790,741,751,527,817,578,491,952,38,170,102,486,76,733,570,135,261,452,734,902,987,421,453,115,84,514,738,609,443,594,922,717,427,403,170,210,815,79,35,246,917,191,136,609,845,358,386,125,60,838,593,934,5,819,542,405,940,881,111,699,921,774,432,97,992,93,841,540,277,422,228,24,667,109,426,198,218,194,349,101,200,670,911,60,652,673,761,885,831,139,125,278,231,904,699,861,917,803,717,805,558,745,957,741,730,322,318,416,340,758,726,109,876,725,455,834,664,555,227,688,920,82,194,836,730,514,915,278,972,733,347,396,356,678,319,33,227,532,955,107,295,760,73,374,461,118,220,577,908,905,105,193,678,19,415,777,81,15,584,481,933,641,497,962,497,862,784,610,41,164,234,50,737,981,391,365,788,103,88,455,136,796,784,196,753,910,1000,566,81,723,280,212,691,216,65,385,137,970,48,429,942,60,951,961,341,581,84,266,417,617,273,572,962,267,94,687,529,342,538,687,574,459,428,437,380,610,628,457,487,542,10,107,552,932,367,939,203,11,140,949,658,517,541,954,679,703,412,254,711,317,583,530,704,501,635,822,148,969,172,815,592,754,699,119,239,47,33,514,259,25,822,873,861,695,686,863,174,854,869,643,995,974,829,803,613,391,941,345,279,536,986,775,7,756,790,474,580,443,715,370,960,116,64,779,330,336,334,89,987,453,579,908,715,790,559,280,31,206,462,232,368,868,844,458,608,643,31,827,327,149,661,731,28,293,407,658,575,538,85,197,506,699,379,301,787,607,857,952,105,463,222,941,260,223,19,677,993,842,438,352,347,849,497,171,512,695,427,541,54,893,448,365,658,338,766,890,478,437,782,728,450,424,324,278,204,119,642,315,67,482,667,546,214,94,916,801,831,446,412,290,638,887,866,509,642,426,348,254,773,540,211,789,847,247,546,964,974,565,621,331,936,433,601,514,56,157,851,680,700,920,535,313,699,87,718,888,779,944,761,397,562,711,778,507,297,455,217,819,929,767,818,708,248,664,598,90,721,845,116,314,995,866,956,24,818,625,696,249,960,158,358,905,564,67,54,323,745,310,141,696,243,953,992,540,820,143,148,942,198,482,5,256,513,881,556,333,298,675,576,961,861,607,219,716,302,690,854,973,514,814,700,48,456,257,370,938,852,20,803,820,33,426,176,710,883,755,984,290,963,541,650,429,210,897,255,421,169,531,974,356,773,73,36,120,383,62,244,929,161,313,901,348,923,765,459,200,980,757,695,9,295,166,80,585,882,370,736,522,633,319,993,125,830,40,112,388,70,901,835,447,380,469,581,508,692,157,148,445,257,161,436,459,684,536,467,577,903,837,421,979,500,864,31,885,973,757", "720,17,689,789,235,606,784,97,165,338,848,557,263,381,148,631,135,76,370,867,730,319,189,171,668,433,299,647,562,351,433,648,335,736,993,183,215,49,996,607,834,232,928,351,794,863,514,381,141,414,211,989,996,944,585,78,381,421,46,235,946,712,468,550,576,14,814,14,843,759,106,165,753,551,584,434,578,622,929,855,421,910,630,223,253,802,991,389,575,470,991,547,2,45,541,389,435,654,676,473,995,547,185,816,368,258,190,328,32,520,957,180,945,550,865,786,614,183,136,597,741,136,101,736,598,58,114,210,112,233,331,796,70,89,581,111,219,834,697,800,807,169,245,790,801,854,158,961,941,50,83,903,518,48,701,567,304,892,188,617,247,662,451,226,588,627,389,765,133,173,50,79,518,996,793,791,901,805,329,421,986,273,466,779,263,631,480,335,961,60,597,386,847,542,623,654,614,0,450,296,852,392,13,790,893,12,236,290,447,569,755,869,996,202,385,536,309,597,173,525,653,178,292,719,110,703,981,722,482,965,113,923,269,471,431,390,932,836,668,232,119,294,647,13,985,785,299,603,531,500,840,614,8,717,110,488,143,730,446,291,172,558,601,872,794,240,594,160,179,782,329,865,336,215,59,728,847,957,847,751,341,370,755,343,557,599,798,792,661,775,847,723,684,491,274,771,179,545,307,942,95,632,91,965,604,149,86,634,252,221,491,892,343,453,143,148,175,753,72,570,988,396,557,677,700,148,426,401,85,921,176,210,162,869,741,225,386,663,331,337,99,759,603,878,885,885,321,417,116,101,768,661,843,119,669,352,748,135,837,568,40,429,527,650,212,393,159,968,917,108,986,909,520,213,615,745,890,707,672,697,918,943,332,951,808,831,946,589,768,71,153,185,251,398,992,616,484,247,947,954,906,796,796,29,243,268,983,500,50,704,36,300,234,237,716,112,477,408,481,163,400,958,447,205,382,192,86,99,256,631,721,857,491,664,594,496,208,570,539,214,959,549,646,648,979,33,112,280,273,568,481,265,452,59,891,667,389,951,889,137,130,656,66,210,178,400,94,513,670,326,898,590,791,618,70,496,562,440,39,790,457,983,226,731,697,186,345,634,264,421,217,207,257,696,38,90,897,109,396,970,771,215,929,180,620,66,258,551,771,347,941,79,752,846,9,616,567,903,371,409,85,382,701,331,504,375,359,614,891,887,115,721,279,623,874,839,628,901,817,546,718,168,925,71,208,8,284,345,709,931,627,195,188,97,823,495,143,459,249,216,5,979,942,472,493,971,157,483,30,542,140,656,26,491,443,627,840,912,652,630,674,674,724,363,415,825,953,757,444,959,691,656,881,546,860,293,236,980,923,534,649,135,770,872,775,98,819,105,432,547,600,228,479,25,41,735,724,507,860,894,611,322,929,69,426,230,411,12,739,171,989,893,900,176,975,854,972,44,602,528,396,33,152,38,580,714,243,920,345,846,819,45,325,85,368,241,705,349,682,649,560,17,466,857,861,190,44,662,148,468,225,280,426,568,813,771,34,404,469,524,408,212,451,472,131,77,262,447,905,532,475,144,821,998,658,132,961,715,966,851,678,683,116,157,459,671,479,736,636,940,176,897,727,944,570,499,686,982,165,320,957,963,266,576,382,830,927,48,244,293,269,16,796,66,340,749,485,567,648,758,170,191,232,938,323,208,631,750,295,371,190,934,786,365,882,158,525,697,760,742,199,732,255,507,585,214,894,818,46,697,212,430,334,155,742,935,154,128,685,271,797,155,364,979,641,289,879,452,647,285,161,376,273,770,677,933,789,804,226,208,749,273,393,924,218,508,891,298,181,369,714,410,243,801,105,219,534,963,110,440,787,937,219,591,869,843,777,495,961,888,438,855,917,884,138,586,334,572,579,244,695,518,478,654,171,341,605,736,479,19,962,881,460,91,20,649,695,604,166,167,368,389,868,603,110,113,927,870,794,536,314,313,676,88,407,217,292,711,326,814,915,815,244,518,815,534,627,977,687,278,37,662,151,364,699,703,622,469,465,758,813,760,588,381,7,890,781,366,567,855,809,348,966,250,764,382,96,27,503,649,632,36,793,847,669,479,614,3,431,889,678,769,899,130,828,741,189,930,111,575,925,210,987,216,751,253,234,867,439,572,351,619,101,961,828,871,27,321,607,417,658,934,981,504,394,263,554,718,896,67,722,966,315,365,565,184,291,303,750,407,551,57,826,662,669,133,402,632,300,666,49,231,14,616,439,42,507,736,771,127", "166,632,104,988,90,170,930,210,634,938,873,269,7,143,235,639,585,534,105,440,732,536,662,504,367,678,776,484,168,194,776,304,474,279,309,321,248,769,347,300,892,418,454,558,828,816,765,901,825,481,89,25,23,127,972,912,570,374,606,726,428,348,427,802,349,383,174,691,868,516,297,774,528,759,608,140,487,104,55,984,229,310,321,821,827,70,248,800,150,647,500,380,947,176,597,178,824,256,629,199,724,687,803,885,209,315,392,742,184,693,253,161,948,708,598,831,410,46,905,717,633,618,698,420,379,27,629,787,836,865,814,457,779,515,642,653,110,855,143,75,76,546,261,966,748,266,798,738,103,757,355,662,602,203,299,556,790,326,764,644,121,527,124,868,420,145,112,218,50,482,788,953,948,636,659,339,414,213,649,79,413,396,693,920,755,448,826,476,811,904,297,432,137,142,78,988,537,450,0,788,577,789,894,950,944,738,32,866,979,815,416,87,982,435,714,953,344,31,765,959,770,720,636,773,318,826,483,393,731,518,137,377,792,996,553,424,613,751,229,548,337,589,784,505,252,702,28,53,405,420,325,545,792,681,965,502,602,969,489,739,965,575,588,644,441,993,593,647,534,247,551,148,584,462,808,663,276,486,77,859,991,560,36,869,199,79,666,45,865,293,53,139,372,194,117,904,471,603,63,109,694,317,437,614,177,722,356,31,480,390,217,440,682,114,882,438,380,626,479,772,785,106,73,571,449,995,653,472,810,9,761,923,498,263,753,824,604,597,556,45,647,893,718,718,598,139,486,959,889,852,473,531,198,822,788,370,224,136,461,799,251,928,9,120,57,2,272,73,701,41,477,696,743,726,392,120,388,421,91,634,108,850,36,42,409,330,915,843,317,778,591,282,926,373,374,458,571,411,314,182,874,450,459,401,225,495,603,310,895,627,204,239,18,13,567,661,908,175,123,543,776,83,203,550,697,392,313,816,327,422,69,526,200,443,383,265,166,140,73,669,420,723,941,962,83,740,42,910,394,280,606,504,568,761,863,321,324,887,871,189,471,876,501,928,182,778,21,414,187,151,163,73,964,449,254,121,825,899,254,845,689,769,775,445,3,92,403,20,493,28,177,94,741,860,722,147,160,410,580,720,735,806,319,798,297,49,778,876,588,745,247,83,189,585,12,590,540,368,449,940,187,523,612,401,498,834,423,594,886,529,793,818,293,440,532,734,660,778,469,931,724,200,950,588,436,465,545,163,184,690,488,100,108,530,899,227,886,896,474,882,854,192,255,58,130,147,631,485,960,493,498,796,25,126,418,910,453,540,776,393,416,738,106,100,745,999,42,882,4,874,607,831,576,91,598,797,693,854,59,497,112,397,415,481,825,210,677,269,322,57,433,707,402,510,781,755,694,700,466,414,731,712,224,156,975,941,511,758,451,306,801,997,478,732,189,472,835,531,536,788,574,664,325,379,606,759,680,897,939,397,735,652,139,831,354,675,768,857,707,43,937,712,972,371,502,97,138,888,755,117,304,800,603,447,232,43,72,607,35,284,993,429,520,571,165,934,636,899,417,890,960,727,664,810,660,566,633,826,729,491,581,834,843,887,874,212,880,718,193,144,432,896,377,299,197,98,804,891,560,540,832,465,358,659,247,436,338,430,750,803,854,753,423,636,661,677,677,945,848,242,908,326,199,10,469,464,387,728,498,744,453,42,325,514,41,87,143,917,329,830,731,527,416,642,8,641,843,362,732,794,93,384,304,79,823,728,831,598,48,500,356,683,37,998,578,313,959,284,179,972,703,356,778,249,68,915,259,250,363,570,48,493,88,92,900,593,35,416,410,182,756,387,968,166,483,224,636,40,943,522,676,830,271,678,137,174,111,712,255,68,481,371,639,969,278,426,241,740,486,87,972,720,940,567,498,425,949,253,546,694,991,646,389,508,812,387,807,797,512,41,440,245,615,894,606,591,15,535,837,255,721,565,139,90,241,141,948,128,57,245,774,18,352,569,27,804,669,443,376,34,35,500,345,836,274,462,777,864,565,152,414,418,557,38,217,471,713,789,365,265,553,484,198,739,125,925,777,475,888,506,706,384,450,855,996,345,52,451,742,146,529,253,795,248,451,79,557,441,140,497,622,249,427,455,853,130,464,960,493,958,920,151,456,868,326,69,931,472,827,214,298,950,297,866,726,81,39,551,756,35,746,394,713,504,400,530,208,871,280,206,940,209,581,674,14,863,770,125,472,621,105,526,320,830,298,568,173,304,386,67", "208,471,967,80,514,962,214,591,688,996,689,374,105,143,378,959,695,959,14,485,290,912,310,950,900,824,783,289,815,91,630,701,234,931,190,573,630,381,652,996,499,656,107,85,343,542,525,980,321,903,255,822,234,541,732,539,452,385,399,376,707,756,141,240,254,904,379,849,296,870,706,813,426,17,766,340,461,743,669,946,601,969,568,381,493,675,734,952,843,141,95,621,942,431,7,290,545,486,595,714,848,589,331,887,78,294,244,844,813,49,430,385,98,763,569,209,980,395,389,961,982,970,96,7,927,854,494,753,883,149,365,336,713,356,219,603,143,125,58,692,617,188,495,250,411,749,649,443,432,113,42,751,656,245,804,45,630,936,429,236,423,426,382,20,613,256,326,519,341,811,441,285,253,963,849,39,239,250,482,399,746,95,562,983,459,31,275,642,926,401,114,528,484,240,329,722,417,296,788,0,360,55,873,613,163,82,374,55,176,315,436,579,87,745,476,924,42,359,140,4,352,891,13,406,89,721,187,863,705,122,66,470,775,94,150,919,266,159,622,102,617,131,61,936,994,376,895,868,264,641,865,815,421,80,255,743,895,207,932,46,929,47,153,226,642,483,245,813,928,506,582,957,199,66,502,859,147,98,728,968,33,920,655,300,680,853,328,940,282,346,393,72,946,326,516,75,154,178,669,376,748,283,185,460,286,524,314,181,904,546,911,595,640,853,825,209,161,277,316,89,860,826,697,566,794,554,426,830,135,628,641,345,129,418,846,99,165,646,815,884,501,436,676,13,948,48,551,99,315,90,30,839,653,420,646,19,846,61,65,165,687,922,612,836,723,828,768,686,579,824,732,98,806,801,615,241,405,761,160,925,679,25,225,184,956,372,59,158,273,732,103,754,43,79,830,90,248,527,875,849,485,152,13,730,515,516,840,561,271,430,499,771,467,818,457,439,750,104,184,291,79,442,431,421,59,669,686,224,221,795,336,634,641,698,51,769,887,946,774,880,330,646,214,128,300,207,437,870,483,260,958,519,983,656,223,221,2,539,436,370,725,767,553,373,190,214,672,504,104,119,774,941,182,305,611,280,471,305,540,755,28,701,62,212,178,637,632,214,815,221,459,604,417,676,861,706,630,133,986,563,521,855,249,380,767,271,996,654,538,379,286,62,492,825,966,583,108,813,259,860,546,753,144,227,610,574,954,650,380,306,166,141,817,416,235,98,755,724,100,897,997,531,537,529,699,948,601,604,804,242,526,666,888,472,796,969,474,76,604,672,892,349,141,748,598,728,115,136,257,517,215,354,450,542,191,517,182,209,736,683,721,199,577,160,59,164,193,276,541,21,936,695,528,897,185,441,669,915,925,256,850,721,164,633,5,770,46,880,795,888,107,616,227,451,16,448,294,247,908,413,722,52,576,354,894,776,640,201,332,552,994,850,415,750,663,871,12,170,103,658,104,420,686,825,952,772,544,406,631,221,113,700,588,106,959,213,23,827,369,19,559,310,793,64,628,77,802,236,757,217,278,603,180,277,34,281,209,950,78,498,841,294,805,298,601,564,333,692,217,827,965,741,227,502,889,147,545,994,139,37,666,170,577,89,250,29,677,209,425,545,854,394,236,544,447,270,805,901,655,292,581,73,932,112,362,25,784,647,854,716,780,8,446,75,37,865,532,818,473,279,510,422,512,198,227,485,243,668,491,996,306,331,240,672,754,973,350,271,350,335,724,323,566,200,353,657,14,444,696,434,392,294,534,135,443,64,642,384,116,153,954,808,16,817,959,645,701,657,29,623,313,576,479,273,675,424,378,365,90,120,754,80,624,47,986,509,296,330,289,754,124,77,680,321,624,697,97,72,324,318,488,388,403,222,960,895,657,247,785,970,804,219,230,714,741,9,132,427,199,205,598,861,837,560,686,562,985,899,545,954,422,838,8,297,127,463,78,740,953,282,609,643,406,703,518,931,190,818,617,637,709,148,640,613,131,470,427,330,739,143,77,209,994,20,132,480,48,865,666,120,974,275,813,294,725,57,357,727,542,248,792,922,865,256,34,948,866,913,484,367,940,916,861,656,19,893,633,199,39,888,683,350,933,925,400,201,282,731,47,588,241,909,333,807,603,124,165,802,634,6,987,559,480,444,304,119,422,216,756,380,377,155,619,305,168,79,505,913,369,159,883,620,743,261,581,155,112,496,65,221,608,1000,639,970,767,553,953,901,332,636,712,760,396,290,838,256,498,239,156,286,389,471,249,765,451,222,483,438,561,48", "178,639,837,886,739,72,210,875,682,663,547,38,905,498,944,939,691,726,935,352,88,419,670,750,215,238,783,555,471,375,574,798,409,757,382,301,949,678,43,520,342,991,106,74,141,764,665,350,789,234,786,584,269,288,232,640,852,29,671,32,711,299,16,121,923,173,627,588,992,816,751,416,127,547,635,213,613,938,117,20,646,484,928,649,227,497,751,939,102,985,840,574,654,717,124,756,76,682,593,51,734,990,781,312,966,563,549,912,900,188,391,960,261,361,827,71,391,244,281,786,691,904,402,802,12,781,927,609,128,330,607,772,545,641,718,8,562,271,540,794,581,702,85,529,410,837,540,814,886,836,200,232,740,77,25,716,679,251,195,876,211,923,199,949,406,638,358,570,346,370,277,552,683,75,760,323,985,364,596,506,32,178,920,91,175,489,463,373,795,587,869,664,150,469,197,437,146,852,577,360,0,661,950,862,414,559,859,161,219,401,377,569,233,315,459,834,494,137,404,365,768,154,629,496,538,207,504,494,271,67,608,26,895,539,110,738,57,41,803,652,250,717,930,214,348,338,341,238,78,217,561,116,331,589,850,9,683,941,965,527,446,800,874,140,297,287,59,969,988,506,692,199,128,859,992,212,923,618,125,754,511,577,836,300,195,169,75,108,914,821,692,479,522,502,594,252,432,13,653,510,641,530,610,87,372,597,742,373,66,911,440,383,434,147,698,799,614,899,728,444,602,98,949,650,661,830,45,441,983,324,177,325,764,106,787,431,463,390,835,478,668,895,146,51,147,872,954,492,172,179,562,304,501,845,456,643,941,53,135,423,181,974,766,110,568,332,663,487,999,385,356,887,572,332,635,874,667,988,493,406,886,346,706,44,727,477,631,453,558,643,781,991,230,657,240,732,854,343,580,595,438,636,614,63,68,963,329,45,968,92,288,487,660,413,647,699,342,228,429,214,338,149,184,399,933,403,436,377,523,542,836,604,618,387,751,86,291,140,853,979,587,783,158,160,157,613,294,752,722,46,134,862,846,686,648,942,542,574,788,880,169,89,351,306,402,217,448,497,767,255,48,741,349,839,805,34,390,862,585,481,825,703,779,19,477,507,522,470,528,663,734,562,422,151,85,479,997,193,999,226,38,106,120,420,37,508,984,877,475,977,774,196,856,916,616,897,14,952,788,360,105,803,897,463,470,240,520,592,606,282,429,663,176,202,44,286,539,394,753,178,127,356,580,547,855,593,837,921,328,769,925,323,828,691,104,336,115,247,519,148,804,946,841,864,886,920,627,699,294,768,323,194,383,498,185,575,225,545,765,705,716,516,703,790,139,309,854,577,985,309,664,747,97,338,334,871,915,869,221,536,399,416,366,23,238,665,464,182,622,769,438,412,273,881,248,130,263,559,884,319,943,604,217,412,294,798,495,428,226,872,198,144,216,713,518,130,838,4,558,4,434,775,800,533,936,750,516,630,124,742,676,404,413,978,201,227,557,209,607,699,311,548,940,377,470,240,554,255,948,350,632,139,709,339,179,268,525,395,40,311,621,911,604,565,968,489,799,347,994,230,285,382,635,881,853,348,314,748,68,531,824,835,187,159,336,37,783,761,954,967,554,601,794,815,864,84,203,467,511,770,257,87,493,306,436,455,584,965,867,993,904,630,892,642,448,892,155,705,151,360,293,808,398,558,457,655,324,583,612,453,636,348,278,617,985,811,283,994,208,71,999,278,28,301,550,937,132,860,782,328,141,616,753,693,728,467,590,111,313,113,810,574,343,753,47,178,906,450,116,123,568,668,630,485,868,813,248,568,857,416,565,783,111,615,652,167,541,907,879,247,86,554,995,859,803,664,692,897,116,405,948,254,980,684,336,557,364,713,670,670,867,595,887,402,423,921,296,731,295,784,77,907,369,845,880,837,676,961,79,416,652,606,324,413,732,992,359,522,457,979,960,790,177,348,227,308,591,875,494,335,943,488,772,804,539,505,765,671,894,372,211,19,980,273,798,534,604,5,678,916,133,791,130,493,229,948,352,838,724,77,785,253,10,571,980,823,854,853,20,663,221,932,479,192,45,817,319,350,897,780,137,53,543,269,543,702,946,584,238,131,661,313,542,541,253,166,81,586,509,515,874,116,318,710,459,136,812,324,532,753,599,14,7,630,538,292,549,389,656,164,788,249,590,214,939,754,12,776,656,909,648,866,335,697,234,577,691,328,679,469,919,162,31,997,882,341,931,981,858,880,488,24,157,173,903,175,215,492,792,216", "634,273,653,457,357,777,51,959,306,465,480,735,122,710,1,628,642,319,1,407,866,73,459,577,240,91,307,867,841,228,287,610,339,677,445,709,831,640,378,831,628,99,424,195,429,504,134,10,272,983,500,219,328,420,115,857,308,244,864,470,612,758,995,314,947,889,401,917,648,571,44,301,636,437,457,973,30,813,114,214,267,963,438,233,404,409,694,515,544,609,886,304,329,314,839,641,385,277,250,998,387,996,535,107,307,4,459,840,286,972,211,708,468,616,84,739,635,766,507,545,968,792,359,145,577,532,823,681,709,257,110,678,723,587,519,255,814,439,150,347,947,505,391,893,388,302,132,234,724,76,538,736,594,973,475,98,227,706,421,400,677,185,886,910,157,990,943,316,470,538,215,834,608,131,444,829,355,123,249,216,18,835,490,859,987,497,685,556,629,877,367,914,320,722,729,98,915,392,789,55,661,0,973,386,208,432,20,809,860,287,431,921,941,842,689,956,69,856,373,968,131,174,179,160,340,966,636,592,28,410,150,580,40,109,130,181,844,1,46,617,379,212,862,29,42,823,553,399,452,567,797,950,797,832,352,393,745,230,830,866,759,472,470,53,643,454,166,833,701,318,928,617,996,615,624,739,214,403,559,892,817,27,65,301,423,70,173,416,793,5,576,225,17,881,721,644,616,77,434,290,643,944,769,152,448,243,744,292,440,774,545,105,406,205,685,709,148,157,755,682,268,238,268,377,845,202,99,852,900,94,792,400,395,481,10,916,650,578,656,427,707,809,6,100,844,126,747,517,527,76,751,477,301,925,262,772,941,158,542,602,117,715,199,654,56,172,379,120,346,857,348,466,572,123,722,3,152,126,472,466,419,649,503,846,417,540,431,237,347,434,209,55,364,620,342,925,577,558,161,542,143,905,729,873,859,423,726,831,183,54,318,624,14,392,189,112,482,672,890,165,520,517,255,247,960,873,304,545,858,839,464,212,785,735,205,208,985,843,184,567,75,159,629,665,596,937,64,359,252,646,610,520,173,612,646,362,53,456,246,279,84,216,401,573,754,860,329,416,168,623,77,775,101,727,202,73,659,313,935,799,396,454,451,881,333,620,976,667,455,818,626,891,131,203,844,728,710,398,861,577,181,798,852,369,644,888,805,575,398,523,310,464,420,349,577,732,896,168,212,450,91,547,776,977,543,287,583,435,246,880,464,993,83,966,975,350,327,197,945,820,146,263,634,794,418,345,603,529,884,605,478,763,337,100,273,108,989,691,222,920,488,434,280,246,832,867,475,745,480,709,579,57,937,668,567,268,680,131,482,487,278,639,62,187,852,829,490,956,859,253,843,524,949,74,414,914,818,707,870,441,506,777,113,192,798,641,510,544,528,886,136,773,558,284,480,460,620,721,146,219,360,647,957,754,906,99,311,990,995,967,582,462,131,550,118,361,731,780,725,370,34,221,840,457,714,80,769,5,811,319,223,388,428,589,602,813,566,104,155,262,24,948,196,696,293,406,379,451,291,400,598,830,137,719,676,314,184,127,867,823,293,528,749,451,442,141,840,50,741,72,590,970,322,402,565,223,59,795,238,587,809,721,549,835,6,132,866,337,823,929,967,685,369,808,14,362,894,836,551,976,183,671,159,321,981,699,685,475,308,611,657,717,647,276,729,229,986,268,123,652,783,846,569,710,420,845,371,298,735,667,217,500,986,433,338,602,73,969,954,231,444,304,141,439,390,212,272,952,779,539,482,350,837,392,244,182,610,155,189,232,409,186,273,292,611,578,336,841,252,550,291,963,806,221,341,641,798,70,121,697,623,525,281,888,447,345,26,976,815,677,79,185,578,478,9,213,33,679,512,488,723,708,809,538,640,539,704,241,344,471,755,680,765,591,551,78,427,559,883,894,289,617,643,400,663,51,808,392,501,193,347,117,981,457,813,792,593,19,987,785,505,645,105,895,159,776,737,712,706,919,786,395,747,540,702,771,315,101,357,512,420,52,190,341,445,946,352,709,508,346,408,415,235,341,340,287,840,784,664,246,44,720,707,490,284,311,610,307,372,480,338,238,194,424,522,390,539,435,155,966,360,643,817,865,748,35,768,749,355,227,133,85,462,14,40,674,664,684,921,78,339,817,149,556,705,657,385,225,676,166,401,625,895,457,572,578,227,553,645,137,847,173,38,683,374,930,299,52,487,138,683,862,137,332,718,519,735,448,641,252,429,329,574,194,304,240,668,98,463,813,233,392,103,882,883,279,203,602,270,361", "557,142,656,333,806,127,932,158,567,603,769,954,454,458,554,169,220,11,695,319,181,73,242,281,561,982,225,940,151,424,447,89,81,95,750,258,315,927,825,400,922,735,160,682,953,221,514,368,838,665,858,629,994,479,996,372,752,420,233,633,85,110,878,682,590,443,552,350,104,915,500,538,170,346,436,748,679,874,217,704,163,339,15,998,637,285,756,864,154,644,142,472,542,276,197,976,444,134,522,635,209,501,336,377,561,441,275,125,295,683,210,810,708,966,753,916,911,806,713,521,410,80,730,788,718,994,314,691,699,659,80,620,381,831,596,417,290,546,403,864,631,497,133,679,695,925,806,556,929,324,527,422,222,840,586,922,728,989,930,200,578,27,612,190,750,297,107,762,304,724,288,662,231,666,78,548,58,756,296,259,925,436,707,615,144,602,977,958,425,814,709,369,951,959,83,881,864,13,894,873,950,973,0,385,396,95,847,119,938,339,315,893,101,117,107,512,914,910,597,842,787,396,164,169,712,150,373,106,636,305,94,11,478,191,694,262,6,94,578,831,942,270,678,736,849,419,387,662,582,585,371,963,144,570,147,847,614,312,567,258,856,908,706,711,124,787,163,790,166,806,454,93,300,222,557,40,341,872,879,733,939,927,233,634,851,438,212,988,406,516,205,816,743,619,613,156,330,37,506,660,212,661,970,902,87,680,690,482,955,588,918,444,863,315,925,75,157,195,978,286,186,771,650,79,324,713,857,792,348,449,814,909,905,207,287,701,275,612,21,592,718,440,771,711,953,78,883,564,840,56,764,303,418,505,59,206,867,980,591,146,50,428,406,768,363,900,481,989,491,415,21,746,5,106,876,20,479,301,626,352,439,871,235,484,243,318,496,727,346,622,586,803,95,984,286,307,414,701,691,286,425,218,383,346,852,375,589,390,239,744,336,212,368,121,103,584,819,713,653,970,177,669,910,151,681,798,279,23,480,815,483,951,948,545,490,255,862,89,920,436,570,572,623,691,50,260,504,512,205,644,155,834,415,279,908,806,377,244,935,823,709,759,128,908,844,548,313,357,70,6,965,854,562,20,949,570,793,417,569,749,905,106,50,107,841,107,764,847,458,263,479,283,100,346,754,792,650,499,300,446,318,224,771,925,171,380,71,626,41,772,670,946,917,387,247,330,781,446,828,434,866,474,72,690,8,763,917,328,422,122,773,820,704,768,546,851,631,212,130,581,637,73,73,646,106,925,926,795,958,277,977,235,146,722,282,900,442,782,713,612,603,704,595,421,978,347,316,654,381,807,262,390,436,796,691,392,961,653,73,837,416,83,289,481,191,627,487,524,522,549,749,821,118,668,227,296,494,224,701,80,70,618,633,839,952,703,30,57,322,209,791,11,130,199,150,299,505,519,492,80,466,858,719,784,639,818,258,180,733,33,119,522,626,554,5,897,688,145,941,959,443,825,658,345,287,189,93,105,718,190,498,936,951,555,406,677,483,303,328,967,680,243,179,492,775,577,673,562,594,979,816,558,167,945,297,102,463,969,163,508,132,531,349,87,83,976,410,457,441,44,633,86,19,664,211,43,284,937,883,18,549,793,608,878,114,133,931,261,386,946,465,287,375,344,61,377,234,639,30,289,179,532,411,586,808,677,147,200,445,118,897,461,629,256,533,199,411,666,843,999,999,450,635,198,554,256,660,398,884,136,264,474,106,364,276,226,793,600,885,538,783,458,195,95,937,503,872,210,944,968,810,195,378,520,820,717,258,908,59,403,41,460,6,48,894,996,631,247,66,475,882,547,861,739,30,192,501,640,462,690,605,66,476,234,362,978,845,357,113,111,860,956,395,878,77,294,338,31,735,941,621,406,710,132,892,886,747,10,882,558,757,531,252,504,189,504,163,527,396,732,143,109,674,417,641,167,952,421,336,679,7,74,597,43,713,923,596,619,846,49,675,770,568,456,465,530,757,110,753,682,441,671,289,846,862,164,922,910,719,587,965,990,714,500,758,951,933,256,28,313,334,600,765,568,710,110,667,135,541,178,798,477,346,69,529,233,543,533,494,241,111,928,328,758,670,334,584,909,459,658,503,719,438,992,819,279,915,395,956,244,305,749,305,628,495,294,347,867,891,298,433,779,130,828,907,898,534,25,577,102,812,902,126,388,845,513,243,249,611,238,410,447,706,988,250,209,158,386,640,224,755,407,294,16,199,610,371,65,933,514,161,525,427,174,966,6,791,542,739,394,496,637,690,871,910,246,398,639,453,224", "595,763,465,603,963,261,163,278,447,70,287,340,331,409,368,732,671,963,414,955,887,53,382,887,30,872,187,676,337,983,674,347,620,139,295,469,331,612,968,749,211,228,158,873,311,711,295,520,926,641,630,899,622,519,636,153,187,734,218,269,81,968,439,618,175,312,42,115,948,712,176,962,244,274,641,715,853,800,427,585,832,950,818,413,237,194,811,895,927,455,781,709,316,3,17,532,324,694,718,266,460,490,19,903,325,854,598,671,703,510,811,120,992,389,530,26,197,228,507,966,997,622,291,97,78,727,48,199,787,510,271,556,968,309,223,922,10,928,487,528,250,551,434,20,107,484,574,544,713,660,493,714,355,425,744,456,20,941,67,395,314,530,79,501,392,210,342,428,989,17,947,402,950,455,424,333,512,719,226,799,483,228,239,317,911,669,451,405,313,928,588,11,695,583,868,954,435,790,950,613,862,386,385,0,545,543,777,614,564,616,341,976,426,969,700,157,892,165,269,147,975,821,253,602,583,112,981,823,956,218,122,450,126,143,446,439,891,462,366,68,717,215,899,420,555,197,11,602,371,856,345,375,988,289,321,527,82,815,845,985,323,98,36,875,89,108,365,502,490,98,169,981,830,873,945,9,334,382,707,383,429,991,368,651,860,810,243,43,808,239,702,68,470,105,746,561,445,401,9,309,608,764,744,962,600,541,547,780,391,156,503,721,15,607,916,131,842,383,645,462,677,546,128,685,65,675,977,985,93,910,185,996,474,591,810,299,257,319,264,906,899,696,497,355,11,464,666,405,837,906,216,348,887,14,164,83,171,79,74,439,666,345,712,665,126,194,860,986,264,181,402,73,138,920,373,138,507,732,204,747,779,751,795,3,517,988,427,300,612,634,842,36,94,210,409,847,85,715,709,447,872,179,467,20,644,682,95,993,417,300,577,433,552,84,211,16,383,195,205,992,981,141,165,429,475,769,646,850,105,142,707,325,778,759,291,124,720,563,872,515,652,927,226,304,302,974,303,84,232,734,226,463,678,419,705,445,797,771,124,903,423,108,87,530,823,649,295,177,778,398,916,105,287,710,770,952,395,237,223,60,345,433,585,894,669,702,233,780,400,93,649,683,985,124,846,299,439,814,786,850,745,979,200,253,530,924,223,439,742,905,703,268,420,981,226,18,154,767,437,19,917,534,74,75,434,111,277,594,504,591,744,974,183,250,992,765,261,332,540,887,460,884,606,80,488,178,662,762,461,820,676,875,408,347,950,203,148,357,824,591,256,915,207,390,696,196,237,800,685,134,55,135,770,703,124,715,824,942,383,957,78,687,728,75,335,467,552,641,655,208,787,693,707,890,508,278,212,471,526,57,110,940,922,259,743,926,875,487,487,47,399,372,10,9,466,736,871,66,879,537,880,933,977,402,284,368,670,288,799,199,841,423,252,336,401,102,359,833,93,91,894,484,11,90,149,998,275,539,979,174,640,935,446,792,162,734,139,970,529,522,356,573,257,431,858,215,319,577,268,299,866,95,226,480,67,457,994,865,549,234,167,742,494,788,94,835,205,981,100,252,827,532,572,34,816,357,74,438,522,713,62,590,956,985,2,16,719,984,8,733,559,937,380,455,350,792,962,677,34,391,718,121,988,668,116,573,160,729,428,264,624,544,787,731,465,684,362,396,691,57,269,851,455,484,712,54,501,436,819,916,289,754,257,531,595,958,171,557,526,716,147,358,605,508,656,591,32,959,331,205,421,114,655,63,353,96,451,957,222,291,463,517,979,201,30,981,959,51,420,713,290,182,371,253,179,434,78,971,26,54,76,109,429,289,592,371,757,118,747,48,570,299,780,266,128,169,779,208,679,42,142,889,677,631,607,883,776,146,750,745,356,222,842,400,433,271,580,131,951,342,832,814,763,453,405,778,363,211,731,160,751,623,248,188,861,467,679,490,727,926,530,459,890,180,355,562,768,445,304,987,728,839,305,488,851,118,580,422,733,59,35,627,695,946,500,449,965,75,992,955,631,107,691,631,25,519,761,143,507,929,454,480,834,852,283,781,883,416,942,673,618,832,532,531,597,401,640,27,450,195,606,875,924,750,297,872,386,707,815,599,843,144,381,497,224,632,325,145,710,657,686,308,828,333,368,323,533,978,883,882,214,708,422,523,758,41,506,78,603,552,947,377,840,996,126,56,299,582,5,927,336,260,70,68,337,355,413,629,804,334,560,270,656,914,19,862,979,972,929,168,792,537,975,913,43,476,516,682,691,444", "969,708,154,737,754,532,617,218,804,140,418,158,189,623,718,275,755,27,904,808,163,50,273,713,661,56,724,333,879,388,903,821,450,758,760,762,65,933,484,815,673,384,355,597,264,465,493,98,308,354,214,11,697,851,379,545,321,297,812,996,571,570,707,473,551,163,171,605,829,820,751,518,821,686,551,540,630,641,127,466,590,9,94,873,53,707,606,667,98,372,976,287,998,984,856,230,711,488,163,891,214,591,4,624,189,726,291,38,923,132,432,6,376,134,68,229,75,680,998,386,381,722,622,965,275,984,746,186,244,262,182,50,965,567,894,128,353,610,540,947,184,379,892,559,207,683,337,86,74,516,222,836,484,357,241,843,698,828,227,370,177,543,145,825,999,841,770,531,60,86,849,705,586,255,966,79,219,884,667,739,750,788,94,308,536,466,945,332,930,813,607,544,93,773,549,366,269,893,944,163,414,208,396,545,0,437,431,269,511,253,246,956,560,974,635,221,766,816,36,952,958,987,740,583,199,121,5,126,736,792,413,671,576,596,347,235,635,957,746,735,706,158,164,760,144,649,907,138,736,313,293,478,223,675,855,295,385,521,392,764,173,94,736,959,986,645,937,73,32,274,262,897,637,751,721,943,561,420,992,663,285,47,22,890,258,885,339,556,309,412,345,343,312,801,55,67,72,996,265,271,624,237,856,822,868,861,243,838,225,776,957,187,844,572,859,773,119,625,499,959,694,951,543,732,237,907,802,456,847,870,535,600,350,78,328,359,249,350,374,933,800,90,816,516,206,847,528,180,314,737,268,664,123,586,483,476,94,50,940,593,928,193,491,889,777,461,850,320,898,89,632,563,121,386,577,957,407,626,859,157,390,387,557,785,107,869,377,205,392,806,973,99,231,467,2,769,392,813,246,363,54,923,896,889,631,860,78,693,159,873,882,847,651,853,230,302,184,842,922,831,243,310,241,655,783,210,672,707,511,537,507,144,887,392,251,586,806,886,929,207,517,708,253,563,733,518,662,385,636,503,704,494,761,835,857,875,515,235,541,905,709,286,126,115,417,920,522,243,632,387,725,174,267,102,874,363,892,438,805,285,411,153,699,334,654,732,57,846,840,336,225,250,182,53,586,216,471,995,712,763,605,859,841,101,78,697,556,134,931,914,416,420,195,29,928,530,167,693,981,929,341,301,377,445,403,415,337,71,754,715,565,547,96,156,598,594,141,678,531,253,830,311,132,446,524,952,330,796,61,723,214,41,515,495,394,33,477,589,438,849,573,837,975,24,398,221,386,202,362,752,936,679,198,366,570,800,171,316,130,358,562,154,7,50,439,359,130,486,466,650,151,800,780,978,201,40,777,456,763,160,650,598,919,724,927,525,555,453,901,108,416,486,714,811,239,606,933,741,537,774,365,635,933,930,771,626,514,871,343,823,699,686,153,942,76,533,574,636,643,969,193,46,609,937,516,249,630,52,51,261,792,877,589,841,301,712,495,769,744,459,452,919,354,674,20,339,311,799,102,299,634,875,733,527,388,669,105,467,959,173,365,436,787,189,947,962,71,520,382,467,499,248,281,804,182,557,862,376,70,422,396,403,103,243,613,835,574,274,29,342,38,996,684,529,453,820,99,39,773,251,915,459,45,943,691,126,82,238,927,30,48,665,167,192,78,587,46,407,166,720,296,624,648,512,715,312,899,740,526,41,518,364,464,552,881,668,868,403,69,839,353,911,774,478,7,380,59,561,190,292,58,857,5,608,697,930,254,181,35,876,238,753,2,512,212,803,283,503,246,119,538,136,215,951,753,967,578,224,651,362,890,591,159,293,277,273,658,376,424,424,721,484,174,764,815,754,244,847,457,463,470,552,38,975,264,15,653,346,986,205,949,104,300,183,862,561,557,665,679,329,545,567,413,170,455,788,106,762,735,451,147,273,771,192,210,901,112,384,574,415,925,372,372,200,189,647,254,407,963,504,242,146,926,759,799,28,602,170,929,364,867,12,371,580,220,338,220,231,879,755,172,742,17,913,965,230,680,343,417,24,436,206,330,654,235,525,968,556,448,825,725,476,647,253,889,926,304,542,296,25,92,989,375,23,470,178,437,536,561,609,193,502,159,216,851,692,958,195,431,399,92,341,697,313,300,214,86,195,646,824,486,107,747,770,199,16,202,564,520,912,316,108,296,509,425,690,782,542,381,489,165,8,856,855,739,208,331,405,227,905,541,540,959,45,688,556,118,349,764,161,808,417,112,68,860,543,220,147,807,479", "968,694,321,985,213,979,662,106,698,509,185,99,635,637,69,248,236,20,912,426,771,140,883,454,119,832,827,552,442,807,381,538,674,125,32,976,978,908,7,615,46,443,273,107,146,898,686,518,400,314,953,135,77,362,285,59,647,451,753,550,91,518,944,911,106,53,766,282,37,361,546,710,569,217,643,163,785,794,25,731,520,560,8,214,7,518,398,669,893,540,486,521,240,173,98,306,83,671,286,831,640,676,449,31,441,47,90,406,793,975,532,527,881,533,403,872,250,79,747,901,160,257,392,75,950,641,717,220,92,222,723,621,409,495,34,532,222,527,62,734,115,115,986,500,481,789,485,390,376,346,325,610,637,844,11,200,899,347,129,898,511,794,748,874,352,255,993,74,55,333,443,317,650,600,877,690,542,476,780,540,382,549,565,839,876,677,325,305,96,15,842,674,881,447,921,958,742,12,738,82,559,432,95,543,437,0,491,269,650,228,111,175,380,157,12,322,280,462,838,991,457,500,812,600,434,812,525,773,450,75,76,885,857,901,848,435,947,313,703,207,824,967,379,845,86,312,812,278,940,421,196,547,845,765,578,414,606,7,808,128,499,546,666,57,201,915,401,212,164,732,65,910,574,723,135,948,356,210,493,504,195,446,494,740,233,37,401,392,928,637,739,402,815,577,340,5,220,282,93,475,837,687,488,508,584,337,319,96,877,45,659,647,157,254,558,501,372,825,34,768,28,527,667,703,520,737,525,841,689,371,174,566,363,363,402,812,340,493,12,536,958,460,240,691,54,198,240,685,875,730,318,690,736,827,783,958,887,88,289,644,774,804,209,283,34,532,476,994,260,972,279,12,14,862,859,611,622,588,279,964,305,16,278,722,490,823,485,830,126,516,951,891,942,352,880,558,772,432,510,25,624,694,773,665,346,821,489,145,817,901,68,437,805,5,532,266,18,603,622,855,507,418,349,795,832,495,912,415,267,167,620,912,355,276,937,714,378,15,954,630,478,267,267,516,550,98,384,197,906,268,249,43,899,428,332,713,839,889,775,210,942,421,278,608,523,402,559,212,134,164,654,358,977,440,730,330,86,653,298,18,147,410,197,611,250,66,739,659,493,354,73,48,650,784,794,155,524,608,423,581,704,74,548,944,643,791,61,799,734,179,499,913,960,529,961,861,982,397,519,601,669,980,55,403,333,281,204,457,271,198,131,480,572,997,416,920,8,496,705,184,979,548,890,389,734,279,115,672,672,281,587,444,26,482,428,36,414,728,673,474,966,974,843,582,426,293,316,663,920,126,936,634,51,367,833,340,828,307,163,297,819,270,423,450,833,310,835,18,905,963,795,772,769,9,181,116,148,990,224,911,774,73,609,191,457,127,158,962,390,508,452,737,337,213,426,903,356,834,777,663,660,268,887,116,691,475,559,130,815,907,478,269,278,92,582,243,611,173,716,817,409,782,65,138,195,905,187,52,985,129,586,19,636,75,906,334,954,71,501,48,172,354,271,421,333,890,770,758,716,820,901,712,499,591,859,704,364,413,356,764,985,857,197,954,935,207,913,32,545,642,268,261,807,10,913,822,781,219,145,48,619,152,898,826,557,169,111,819,898,130,170,516,793,946,685,830,481,346,245,826,360,308,829,914,456,160,990,317,892,183,744,595,63,886,3,664,377,408,173,491,740,372,915,443,605,775,561,426,910,211,226,217,982,330,182,251,494,124,563,313,834,72,504,448,647,520,928,471,671,89,350,609,970,971,237,108,626,790,213,29,730,43,25,136,390,19,321,258,237,172,788,796,213,102,704,649,181,742,233,515,133,886,311,666,958,393,759,7,28,129,555,41,770,861,596,755,812,402,227,144,753,216,921,683,215,150,709,124,979,967,876,665,859,793,385,914,841,171,696,97,69,419,520,542,241,793,230,870,649,758,380,285,796,500,852,595,987,186,888,236,978,377,28,872,922,379,150,482,119,65,736,749,734,182,213,937,91,324,939,966,893,83,346,732,513,914,597,810,487,932,245,5,608,204,965,902,100,401,308,982,685,798,398,565,733,15,584,425,279,324,859,619,469,598,149,141,96,493,553,481,901,858,676,593,510,888,520,10,957,943,560,589,389,590,820,188,828,353,528,359,707,346,316,799,624,166,152,232,240,702,251,473,736,704,566,636,240,402,769,784,567,98,445,286,799,76,532,898,127,461,950,981,134,869,457,586,422,172,637,823,663,788,389,954,289,466,508,879,768,755,848,844,796,9,291,955,68,672,808,733", "384,395,722,546,427,344,588,749,943,83,62,414,672,56,96,427,832,694,820,552,574,490,412,760,906,729,310,727,650,279,747,182,217,471,915,309,568,489,720,93,837,668,835,172,938,568,731,761,825,461,471,564,134,735,278,71,721,422,765,587,818,504,721,395,509,129,664,137,15,2,452,545,557,911,164,874,908,530,589,443,609,829,526,656,478,490,925,559,92,148,666,380,48,449,256,547,292,677,571,237,339,294,567,480,37,802,717,328,517,184,284,268,90,535,940,236,177,380,944,996,85,906,783,559,983,953,843,466,41,203,845,883,564,298,398,903,619,963,816,35,95,224,384,13,276,987,951,40,732,239,560,77,66,100,6,856,214,384,52,467,486,647,999,366,23,42,679,877,924,116,643,563,16,753,47,366,159,820,713,260,760,655,245,491,58,276,727,433,875,229,222,34,62,624,141,448,489,236,32,374,859,20,847,777,431,491,0,697,160,124,526,624,607,369,103,534,916,332,50,294,895,140,285,186,375,83,646,469,170,505,444,247,587,424,773,267,457,245,653,62,828,795,918,822,585,257,920,552,735,582,84,308,910,150,237,188,714,208,989,646,193,977,902,172,428,536,55,961,597,102,137,299,151,11,399,852,582,839,393,365,789,907,184,528,166,224,940,150,574,257,495,842,896,263,216,871,909,297,660,500,290,459,344,858,643,375,139,370,953,30,924,818,4,947,286,710,271,735,44,895,534,423,372,813,831,452,569,666,148,779,477,382,968,769,256,705,454,653,393,125,612,11,770,674,85,162,829,778,810,830,397,123,478,265,143,190,414,733,950,412,4,536,795,559,150,139,40,631,856,828,623,883,650,196,994,812,859,562,200,344,411,132,793,675,916,230,724,288,560,960,788,498,995,151,981,212,532,590,615,964,667,744,480,607,15,78,367,790,767,902,263,979,917,596,651,600,269,811,520,881,49,766,353,288,783,635,548,434,277,732,418,804,813,327,462,859,961,596,145,944,161,124,237,394,423,692,564,335,56,491,510,650,440,668,117,277,889,167,113,75,505,142,784,635,594,147,461,455,13,960,717,576,966,376,970,825,637,206,730,644,83,350,47,376,71,854,206,948,564,111,361,175,955,870,564,902,725,507,60,728,596,264,128,956,485,317,959,257,801,86,36,409,430,641,812,521,780,714,502,383,191,502,657,338,931,111,208,957,587,749,397,116,693,642,85,278,480,700,666,910,511,578,791,274,568,661,572,870,209,170,265,978,27,816,265,98,386,282,420,80,222,156,14,141,779,497,229,960,184,595,759,957,954,217,450,809,419,205,805,730,550,539,241,318,292,102,169,137,471,435,814,866,740,69,540,732,470,451,43,361,638,142,910,959,744,459,693,446,985,62,477,799,589,768,342,372,64,718,477,392,414,884,186,650,98,155,654,764,258,338,654,370,11,147,750,312,333,268,170,189,840,542,866,413,722,887,406,55,840,149,58,720,150,369,237,208,445,872,81,684,692,338,428,975,430,479,770,416,992,227,414,460,670,840,49,914,963,12,745,99,444,77,858,852,762,845,807,773,248,415,529,528,340,230,760,323,165,943,874,759,503,887,815,501,719,595,553,660,531,577,383,227,723,901,710,150,332,398,62,482,358,165,348,29,73,260,414,218,338,825,691,52,835,707,272,103,173,86,751,983,248,858,76,644,252,264,255,201,488,847,38,335,437,109,138,135,104,917,982,527,386,959,221,90,121,318,446,751,42,255,945,990,179,640,360,99,851,322,371,906,681,128,971,769,14,560,823,370,61,789,208,614,839,540,182,730,61,906,221,217,681,731,582,546,398,99,643,743,707,158,604,863,783,583,248,425,832,549,24,815,107,139,699,478,377,819,759,621,44,564,597,418,794,153,104,247,363,727,438,465,970,273,174,406,599,765,616,546,245,426,24,64,826,231,998,657,666,405,365,579,27,756,649,134,397,108,185,986,234,317,576,698,497,133,555,976,886,277,776,974,966,635,422,33,810,425,453,180,5,217,260,521,758,87,98,391,53,362,4,459,956,941,826,417,269,369,957,903,218,543,620,402,263,231,730,155,569,214,694,864,39,546,521,647,864,496,988,988,727,891,138,112,570,38,231,110,221,844,640,775,460,16,610,628,998,847,89,239,354,907,654,362,951,720,860,508,861,137,737,220,324,465,587,573,380,643,422,854,226,334,916,167,728,613,959,84,721,755,427,339,549,597,580,700,636,13,256,912,365,262,608,771,132,773,224,887,389,253,246,503", "682,53,553,479,819,263,139,847,273,122,9,601,219,732,452,593,486,15,662,722,903,319,132,113,202,903,341,17,949,521,187,102,751,719,148,719,978,341,551,382,822,337,850,561,416,459,354,690,180,384,53,899,364,333,892,29,677,453,815,183,344,998,880,733,440,636,132,950,544,182,340,536,965,86,320,35,566,595,809,356,251,352,802,518,69,156,280,187,684,732,308,870,907,741,66,501,125,85,473,280,985,143,711,928,995,509,323,606,676,95,562,230,115,472,296,191,960,316,313,783,882,434,189,886,18,826,604,544,624,594,635,595,135,838,747,983,743,437,747,143,518,217,125,93,919,762,837,734,561,363,159,144,535,605,342,538,220,734,475,100,45,727,963,177,363,144,472,915,859,12,360,923,962,663,244,906,461,225,140,630,305,404,730,758,208,558,548,957,555,932,858,687,315,340,431,123,323,290,866,55,161,809,119,614,269,269,697,0,328,415,304,305,870,745,836,77,393,364,899,890,90,613,634,242,925,41,604,462,461,811,948,373,330,225,343,105,441,941,308,791,285,576,481,636,219,142,120,322,289,221,867,913,386,838,529,6,887,676,736,76,653,282,298,110,445,12,244,521,59,153,225,470,599,245,186,776,627,901,989,551,870,523,421,950,554,469,155,557,219,543,832,798,106,873,105,734,553,280,445,598,938,948,353,174,582,69,58,620,140,153,456,824,95,756,233,101,431,695,82,599,255,132,100,623,840,245,825,604,497,388,733,354,800,185,718,250,752,229,826,414,512,205,222,66,556,250,420,684,455,802,809,555,111,416,902,408,596,996,363,967,779,736,688,275,582,934,990,480,539,676,894,859,963,293,25,407,682,669,545,378,650,957,233,597,856,444,400,322,274,968,325,584,166,396,169,411,137,669,15,286,308,645,833,59,899,623,456,527,897,215,954,635,516,540,19,616,956,269,812,764,183,971,607,803,347,272,306,530,881,754,231,826,473,627,100,339,509,16,686,714,138,605,86,186,288,357,292,24,882,104,979,345,97,418,533,577,771,959,44,733,458,834,483,786,492,885,194,512,302,221,359,34,396,957,336,314,582,714,57,565,27,865,584,699,933,410,356,403,21,500,763,56,97,656,99,843,943,921,22,742,575,938,859,494,113,26,130,367,585,954,362,78,594,921,426,166,609,433,287,812,563,643,301,585,102,345,707,320,457,981,998,303,478,761,682,327,562,846,624,487,95,872,740,523,402,745,388,189,720,52,801,813,830,718,234,940,416,349,957,496,283,636,319,491,575,992,696,437,8,100,235,907,109,89,630,562,787,514,601,920,651,51,801,709,768,521,968,480,278,844,379,618,217,298,592,522,863,562,485,992,792,778,152,884,939,821,213,834,785,8,601,395,550,849,735,861,257,512,825,23,118,660,727,600,242,937,735,117,1000,536,801,521,22,634,873,47,708,602,910,955,190,788,364,738,261,386,834,184,89,675,617,438,10,809,684,892,688,801,572,2,105,164,553,782,72,431,841,924,668,855,588,621,610,370,55,448,558,891,138,63,352,585,530,305,368,570,883,41,7,690,555,70,171,151,510,79,889,529,945,740,206,617,121,337,365,722,271,175,312,848,82,192,559,942,979,513,478,423,712,117,272,780,250,272,968,163,950,186,39,466,988,80,37,147,662,250,4,769,799,55,312,358,599,768,815,651,127,104,760,728,286,843,374,328,981,938,244,576,267,222,265,895,318,125,872,373,534,630,531,503,723,254,953,613,376,687,697,565,49,813,146,463,52,189,912,152,288,180,785,296,232,387,789,781,766,926,128,887,487,791,272,172,713,442,572,849,800,60,51,991,271,628,222,701,234,11,348,372,644,112,267,291,742,623,606,452,50,444,191,757,376,862,457,494,748,546,22,200,638,427,943,872,125,296,355,517,950,304,274,816,335,156,577,435,96,668,302,108,879,498,365,336,39,670,736,363,108,845,643,50,718,633,179,205,989,631,20,917,237,812,133,294,220,527,84,234,812,185,226,191,968,387,115,20,933,741,808,518,226,686,969,666,967,129,732,404,499,506,210,324,280,155,332,766,184,593,610,267,934,163,357,534,928,445,324,986,639,329,480,883,320,292,891,500,174,722,42,297,348,133,365,89,229,539,903,263,315,631,992,75,80,807,784,524,177,708,176,677,426,299,732,960,815,33,540,186,859,340,834,361,719,500,773,304,955,569,680,778,837,924,436,794,875,889,413,919,849,339,771,118,816,746,139,339,54,859,557,428,877,356", "558,976,402,222,981,451,152,63,255,85,606,618,199,322,398,256,206,137,780,389,146,836,35,141,830,445,21,424,271,318,811,544,90,153,367,195,626,153,635,778,877,33,824,908,351,392,987,462,751,678,603,496,993,82,932,398,93,327,516,730,916,682,906,139,69,289,853,314,44,425,996,963,977,309,233,434,262,950,614,852,628,903,404,792,276,777,424,458,738,38,622,756,32,890,563,696,92,736,56,247,673,53,913,209,445,856,892,402,510,96,686,54,337,345,836,635,604,845,380,226,521,625,27,348,246,7,737,242,536,96,62,816,849,507,816,91,857,728,41,568,669,871,914,448,915,704,243,394,81,354,33,864,867,838,32,43,278,226,599,665,262,22,28,698,738,58,767,781,528,677,867,428,82,332,459,537,856,192,22,585,764,116,369,67,549,294,233,305,514,949,36,757,213,352,496,908,986,447,979,176,219,860,938,564,511,650,160,328,0,381,665,153,486,30,330,560,124,216,809,86,593,867,596,948,589,167,40,906,51,134,600,78,404,570,597,577,750,782,488,145,69,925,271,581,344,884,817,765,988,285,928,129,310,777,337,889,116,786,831,708,111,75,523,305,778,468,334,437,392,214,830,772,837,829,160,881,188,118,472,914,816,336,404,311,56,194,615,84,747,897,823,15,92,431,218,999,103,135,266,249,97,922,121,647,548,277,381,565,181,646,843,906,475,709,251,940,797,941,330,246,970,822,806,75,352,173,549,142,60,292,110,376,532,11,351,956,53,377,871,815,464,548,243,502,751,462,675,372,659,877,723,298,842,669,710,635,905,253,279,162,644,38,911,108,629,69,83,701,269,811,102,130,183,302,574,884,259,320,537,621,283,716,583,594,531,298,118,55,288,382,293,550,570,31,950,28,337,776,566,855,611,763,533,606,328,642,994,831,631,688,597,35,492,553,572,250,363,786,62,290,339,93,66,617,962,507,559,907,789,702,361,570,73,357,488,248,5,150,973,354,301,925,429,971,533,175,401,641,736,247,348,461,299,42,777,147,947,705,78,361,749,668,528,873,258,732,933,975,932,446,466,165,693,279,471,265,682,941,158,61,403,530,419,883,270,42,334,51,230,150,505,447,59,682,340,895,686,234,833,40,253,890,554,866,585,950,745,232,398,520,607,309,977,772,577,870,594,946,528,164,919,381,732,983,343,249,975,666,65,336,590,516,569,58,703,257,371,619,875,978,156,963,305,724,807,595,359,250,150,638,510,732,441,63,54,94,643,376,593,36,254,773,329,794,294,350,206,172,646,867,698,368,64,871,536,837,542,2,617,403,32,851,935,407,804,650,917,4,840,311,794,937,644,719,850,589,305,993,100,624,260,317,493,552,814,787,645,225,354,625,88,775,682,718,421,894,332,478,103,330,839,849,365,702,502,617,601,815,802,895,479,539,300,435,293,235,174,18,796,23,718,349,240,759,211,248,421,47,959,250,879,759,792,479,424,796,71,219,21,692,851,245,447,174,408,516,734,75,581,776,647,503,691,619,506,236,804,790,807,841,159,903,988,803,536,508,734,12,75,554,52,313,530,220,88,818,205,246,835,858,541,979,228,572,885,83,642,104,568,890,800,815,202,317,244,44,638,683,529,493,123,173,150,73,592,137,324,685,201,131,468,862,610,220,330,647,826,200,131,552,776,582,560,420,731,843,446,668,175,571,248,372,613,327,564,55,851,450,479,75,436,673,48,299,283,384,576,267,880,883,220,883,166,460,846,753,143,227,183,759,247,706,140,183,611,80,150,180,312,616,583,465,238,970,385,497,534,409,454,270,775,693,180,453,81,232,822,611,309,519,865,409,657,786,508,860,373,554,949,795,509,285,257,80,828,104,418,211,655,992,328,606,761,40,698,400,47,978,355,424,711,898,224,254,88,162,18,326,433,682,739,310,613,348,204,214,731,311,870,195,193,499,173,713,342,105,149,298,406,918,107,961,348,413,139,542,191,276,251,899,168,538,78,767,444,328,430,483,241,379,640,621,518,670,797,607,764,450,648,794,20,871,209,327,585,381,36,324,650,405,963,163,403,192,240,927,590,970,999,197,293,317,695,626,383,194,57,366,437,503,257,791,183,920,457,347,470,938,346,962,587,252,992,515,85,261,671,763,822,17,691,350,309,385,537,295,69,792,958,628,569,906,815,512,535,933,730,922,37,14,628,285,931,391,908,805,712,559,172,837,389,949,307,674,581,285,663,620,567,118,638,935,318,591,340,979,768,529,448,159", "298,778,768,881,661,602,417,667,287,655,582,473,360,616,354,150,10,457,29,252,461,328,773,72,862,113,852,79,211,697,185,857,609,411,862,828,526,435,356,406,873,842,852,721,239,282,857,476,665,319,737,23,859,101,116,614,878,941,521,856,724,297,771,599,131,395,426,872,854,252,129,450,754,268,899,328,55,744,325,78,387,851,573,998,284,885,465,953,589,300,48,969,542,368,647,299,981,27,620,572,378,162,370,470,582,965,670,830,250,513,145,823,165,78,973,419,837,649,445,169,603,858,771,159,553,391,489,256,359,776,25,396,899,57,679,699,364,340,926,912,43,173,148,935,389,850,988,635,31,51,850,17,891,175,728,603,108,192,956,656,548,408,564,573,953,531,629,290,341,847,305,441,59,306,626,783,107,944,683,563,578,486,414,527,372,991,730,832,747,914,48,223,63,853,976,81,529,569,815,315,401,287,339,616,253,228,124,415,381,0,267,529,681,825,418,357,754,208,528,678,465,272,232,203,462,43,797,320,436,575,355,414,736,249,849,669,633,858,799,876,771,203,394,630,911,376,557,253,357,733,913,381,59,371,217,565,820,565,515,526,885,383,944,214,861,99,555,466,604,677,588,891,67,380,811,190,9,179,396,670,324,319,575,37,300,498,21,688,539,119,993,448,358,495,101,530,743,775,184,903,394,732,510,11,530,352,737,404,805,153,404,845,341,357,599,922,4,289,51,734,628,38,465,613,522,825,555,499,538,512,440,378,516,143,507,947,815,522,488,949,881,985,763,297,748,581,330,471,374,493,596,851,218,649,711,180,22,754,933,518,475,694,431,848,507,213,415,5,100,48,579,23,532,273,980,200,106,234,511,4,276,889,263,748,281,192,152,203,848,791,142,848,147,411,896,86,108,309,553,916,946,663,744,574,812,670,964,71,293,247,524,553,860,453,666,197,553,658,173,666,397,452,887,777,195,82,216,44,331,746,355,388,469,104,413,834,570,805,870,769,510,924,477,989,628,459,387,36,158,574,450,900,466,264,329,96,238,330,617,371,925,204,231,581,535,952,745,260,170,113,685,744,804,154,980,389,834,958,334,965,29,118,864,687,26,398,626,939,100,109,463,542,512,576,966,248,324,381,675,732,33,99,301,636,129,13,863,969,387,499,293,638,883,360,969,760,699,117,430,937,210,542,169,654,796,505,849,474,549,610,827,377,264,586,225,337,172,261,695,989,832,143,940,117,583,151,220,445,863,222,11,815,364,242,408,849,933,55,327,399,802,121,855,65,713,633,423,259,510,289,64,431,400,96,781,866,563,75,179,936,485,453,288,641,201,680,352,20,543,418,826,80,366,303,641,889,31,803,688,176,186,565,448,566,725,833,452,979,802,244,427,447,236,943,511,826,742,132,749,48,517,105,917,29,403,900,505,222,815,593,88,405,887,903,869,89,282,719,926,515,350,442,971,455,207,629,336,101,903,912,671,829,502,739,602,486,834,981,31,111,366,657,644,216,124,410,800,219,508,677,328,363,371,903,576,206,95,73,647,335,386,225,216,19,178,594,612,179,559,803,362,183,784,903,319,841,59,87,931,990,691,697,638,973,646,773,184,772,438,316,935,403,292,785,259,204,85,137,300,410,29,735,912,637,443,850,202,410,612,371,86,691,277,832,353,899,990,669,503,6,216,693,18,77,974,94,954,991,844,675,387,966,627,654,262,5,734,420,462,823,552,75,213,369,628,100,185,237,165,680,212,62,903,71,346,101,693,512,488,385,663,392,431,846,443,954,725,574,452,915,464,232,409,216,303,534,260,317,15,5,192,425,225,509,976,545,507,887,506,681,57,14,215,848,434,419,844,993,824,918,649,940,938,165,566,223,451,632,403,888,725,812,726,706,887,897,551,485,155,910,172,704,222,667,862,104,996,59,379,609,714,703,255,565,714,492,8,581,666,696,320,163,201,513,457,644,366,874,473,236,990,899,626,811,116,196,189,633,278,761,866,706,829,525,249,324,394,435,572,197,447,542,53,848,156,260,405,340,954,812,238,478,200,55,111,582,295,219,594,156,597,952,710,19,820,473,934,751,4,852,477,170,550,214,146,298,251,837,98,524,41,916,249,572,630,34,409,497,553,153,236,790,582,278,763,372,464,596,555,505,140,896,57,112,192,233,457,738,372,513,743,178,806,799,821,697,678,250,500,692,351,767,846,378,507,502,206,219,819,290,458,444,658,25,256,235,907,545,820,617,980,9,221,674,388,699,884,987,576,802", "726,842,262,247,158,48,852,580,147,328,451,248,362,476,191,117,776,66,348,153,369,843,880,774,140,486,941,377,593,625,985,634,888,955,658,762,935,877,768,231,748,437,53,865,510,952,485,982,81,658,598,609,922,683,617,767,991,864,779,18,356,339,682,424,297,362,633,955,58,598,564,830,371,559,277,161,915,298,94,278,629,778,42,803,886,438,314,19,766,76,3,679,175,324,593,341,481,391,585,156,311,838,210,366,856,786,916,518,728,580,677,481,954,581,633,222,677,272,916,905,630,71,12,836,966,331,96,709,244,100,853,176,191,736,222,796,701,827,509,94,232,176,176,339,202,582,346,624,741,895,283,891,615,722,56,866,581,440,798,943,878,112,900,825,772,642,163,891,237,220,348,817,757,912,612,386,759,229,280,679,593,953,810,464,840,311,840,598,465,910,484,574,665,222,933,799,498,755,416,436,377,431,315,341,246,111,526,304,665,267,0,621,692,913,633,514,557,54,267,517,710,544,951,101,432,401,24,108,202,84,452,819,134,588,751,922,159,7,411,796,554,619,171,181,56,540,354,277,737,745,79,873,257,4,175,697,326,266,79,40,970,112,516,208,476,817,793,991,166,71,885,79,264,926,771,635,235,566,975,98,636,447,570,148,165,301,389,73,801,165,541,581,148,545,252,220,236,740,456,656,56,474,797,556,28,895,591,12,379,361,5,166,361,495,640,745,248,140,643,215,544,22,884,959,534,608,459,250,359,440,914,697,604,973,735,73,360,43,290,204,252,686,689,488,314,368,184,175,846,771,869,232,877,134,404,510,447,953,494,859,868,962,800,832,894,790,913,440,46,443,954,879,777,833,526,517,34,150,372,861,618,725,385,257,659,640,149,524,799,101,448,859,927,304,642,256,368,446,967,885,409,516,416,745,82,368,155,202,212,155,415,487,169,668,271,172,448,619,462,827,140,922,789,471,605,220,76,38,712,437,994,367,49,334,691,194,160,694,336,951,334,262,688,109,817,909,879,122,485,128,509,984,141,714,270,394,378,187,14,314,913,177,564,666,492,92,886,720,866,67,635,532,109,590,587,708,203,595,575,405,540,386,198,427,4,459,552,824,892,588,550,146,228,91,965,560,451,825,286,623,870,903,317,739,506,669,365,740,939,883,261,514,720,417,384,143,378,876,588,783,303,65,52,644,250,341,76,92,613,346,398,197,998,274,529,83,776,922,573,428,312,196,639,443,283,446,678,258,197,409,870,349,93,762,362,208,60,400,242,159,642,774,363,366,859,498,595,678,101,278,216,990,281,363,36,339,938,213,636,377,403,749,462,928,219,215,561,711,886,270,806,275,541,904,747,749,967,39,635,333,693,85,566,14,912,712,631,536,383,749,922,190,337,979,576,673,833,483,745,248,962,209,184,563,82,268,455,291,608,300,591,699,722,539,213,735,578,707,412,94,230,564,825,338,271,396,752,850,546,90,794,945,884,386,923,903,653,186,967,498,630,668,679,387,232,712,541,288,680,666,349,95,89,52,830,504,403,670,829,771,97,147,902,353,312,417,703,21,669,41,665,454,216,300,297,335,442,709,383,947,61,605,644,991,870,12,310,312,622,303,18,433,818,244,439,796,674,424,90,206,469,315,78,147,84,373,831,471,725,919,641,545,467,320,452,123,638,753,267,41,144,254,861,789,831,559,643,552,375,192,85,54,76,642,261,390,762,52,240,596,202,329,170,428,534,656,363,527,45,524,485,966,747,588,495,225,436,925,336,638,183,762,965,993,116,981,784,933,88,117,5,232,999,249,752,942,542,287,760,115,757,485,229,329,14,416,646,745,580,793,410,458,613,562,196,788,648,813,378,812,481,563,269,163,823,201,993,241,695,410,887,258,213,184,473,747,216,972,24,62,104,701,320,645,414,765,165,672,203,909,100,222,687,841,742,21,629,397,249,774,489,251,19,329,878,313,384,565,987,547,143,872,590,206,840,248,653,717,422,161,890,681,453,612,326,278,531,409,492,541,355,731,891,258,894,679,816,772,340,329,335,3,113,822,152,60,204,873,983,473,513,959,731,324,703,383,40,214,286,495,987,87,247,636,97,40,432,391,387,648,332,707,775,799,474,598,464,105,344,499,754,273,847,75,598,903,995,929,251,20,308,855,20,407,378,126,839,913,923,814,643,251,169,778,163,507,934,759,833,637,762,912,30,566,60,723,908,126,477,750,87,997,831,400,939,685,930,201,593,525,904,451,844,209,477,109,623,334,190,964", "899,967,257,954,123,408,326,959,195,177,450,789,368,823,385,205,648,239,175,299,23,948,962,525,681,578,864,13,522,710,302,983,437,886,824,327,662,349,298,761,556,319,4,87,4,85,475,979,165,566,729,724,713,697,739,681,235,641,843,149,520,487,864,986,569,485,258,958,147,750,342,655,499,564,580,742,556,564,265,480,695,998,935,851,635,136,678,581,680,647,77,460,391,901,835,526,499,62,971,32,316,967,913,342,476,13,20,635,932,234,17,237,185,681,271,522,793,597,222,366,860,363,528,802,612,221,674,220,440,405,997,935,776,546,116,462,733,165,938,302,58,36,274,795,390,316,370,888,143,607,464,63,701,680,649,854,182,26,628,475,244,52,279,59,686,127,564,237,530,261,239,474,586,768,551,530,326,126,140,614,852,306,334,700,188,642,157,94,73,362,940,264,426,488,700,183,985,869,87,579,569,921,893,976,956,175,624,305,153,529,621,0,449,747,788,697,323,184,343,925,539,620,353,267,137,628,925,487,627,725,414,218,303,894,332,460,319,461,212,448,674,678,50,446,479,731,548,556,572,768,136,878,15,601,105,515,544,751,196,371,434,852,650,792,764,648,31,443,242,796,634,439,202,297,539,685,851,107,766,193,198,134,950,920,321,293,84,394,197,221,513,751,942,234,459,614,64,190,450,828,683,709,219,292,920,557,597,271,330,838,432,808,131,152,647,354,297,421,657,984,169,396,355,293,827,185,900,322,779,666,496,141,778,75,887,799,781,912,173,932,355,340,792,66,793,609,24,93,626,441,301,98,282,767,768,972,909,493,192,743,405,258,203,949,420,330,204,698,367,769,351,437,624,68,709,597,274,873,778,726,944,815,138,975,350,474,158,166,345,588,497,359,42,916,350,302,870,626,914,476,739,630,278,232,676,273,193,173,372,705,489,799,911,234,411,144,892,570,177,845,115,340,219,624,543,334,721,688,580,547,516,270,422,875,71,163,974,168,622,649,55,389,1000,519,254,433,50,969,132,834,633,55,18,499,820,512,167,371,617,336,596,249,957,362,277,596,814,402,993,123,287,298,216,782,665,815,797,500,644,188,724,879,359,305,482,216,448,223,543,158,51,413,150,397,954,820,377,190,537,285,792,848,904,98,44,595,932,839,462,699,807,827,280,539,342,761,449,746,479,582,951,723,621,419,320,3,753,650,232,160,546,332,900,197,801,861,32,592,647,650,757,205,866,152,592,570,611,968,750,572,217,533,960,307,258,879,340,548,464,872,372,29,620,374,912,339,554,357,973,632,813,207,830,551,625,820,354,753,163,285,369,539,451,163,224,65,927,888,118,880,222,966,691,651,621,606,932,575,500,603,920,445,136,51,924,635,927,152,371,860,690,444,763,780,18,192,272,680,353,6,703,485,416,42,219,532,52,387,950,149,362,918,5,814,654,610,741,844,480,21,742,89,641,53,767,61,288,367,366,946,621,443,647,973,650,653,986,722,703,310,216,531,905,439,164,193,236,999,718,124,551,122,730,221,265,342,512,868,377,48,950,517,958,834,957,945,162,823,579,713,404,181,717,129,998,908,342,182,978,546,556,774,149,974,287,327,860,65,908,769,293,515,919,717,467,795,906,326,416,568,887,901,367,278,192,337,805,419,824,312,555,939,648,28,364,553,499,862,264,795,991,278,660,788,24,75,829,860,901,27,346,284,544,579,247,183,208,554,51,329,602,819,667,856,13,404,918,378,837,632,741,751,574,919,330,748,666,800,343,809,642,181,724,927,813,99,732,661,662,379,167,81,224,460,88,856,519,679,422,364,95,140,9,878,389,439,176,635,381,184,381,751,573,493,338,661,527,444,227,765,850,818,976,976,796,912,686,890,297,79,767,666,331,570,262,3,860,949,554,526,232,1000,520,801,972,722,174,386,563,484,141,435,494,970,28,407,414,679,82,105,109,760,340,585,976,86,583,405,329,185,694,352,366,271,19,887,373,382,375,783,659,566,924,178,268,615,382,845,194,254,778,42,95,238,781,950,436,935,447,681,759,378,681,168,762,600,670,696,180,562,135,904,800,581,979,97,47,492,436,267,318,431,767,500,136,962,924,663,896,501,626,880,187,446,326,525,116,894,610,907,513,901,891,119,17,410,826,134,18,569,712,389,207,759,281,890,462,129,594,670,748,217,764,346,99,935,52,149,284,146,944,536,197,232,781,178,517,685,924,261,988,875,307,730,93,326,668,102,374,810,692,517,256,733,339,845,203,807,267,185", "444,875,941,128,21,122,445,648,163,197,475,754,711,651,742,323,169,552,724,914,535,441,339,400,790,287,447,374,37,937,70,967,440,476,364,783,790,573,564,30,314,535,701,193,298,994,966,752,100,896,135,675,939,2,98,338,664,673,640,361,863,53,136,358,198,934,933,463,945,172,68,934,40,346,535,355,742,397,500,409,118,454,45,423,171,852,785,264,422,758,479,999,37,458,840,40,705,557,354,459,929,837,32,723,82,195,148,792,753,482,910,804,489,586,787,689,8,622,918,768,381,615,681,626,237,908,940,676,893,397,710,993,805,787,297,55,954,368,412,599,101,571,444,967,234,195,128,966,266,891,865,944,267,206,60,314,424,334,500,675,978,417,199,701,763,813,729,538,106,373,527,838,11,979,655,169,117,46,723,757,54,301,418,994,912,395,195,626,744,225,654,537,119,680,510,792,216,996,982,87,233,941,101,426,560,380,607,870,486,681,692,449,0,205,914,184,337,391,685,429,467,846,649,720,85,802,878,665,20,260,718,970,205,307,32,75,597,127,844,996,305,366,976,706,65,82,903,462,341,779,582,496,201,105,58,733,66,856,575,365,917,187,6,839,448,770,340,954,26,483,382,963,207,5,32,707,815,112,581,216,63,480,571,894,293,353,90,54,435,667,981,680,44,835,954,710,818,729,378,537,495,354,75,237,833,473,685,779,468,59,880,584,369,413,695,644,327,608,121,212,986,471,361,90,219,223,382,928,452,16,411,359,780,897,962,694,735,696,187,351,889,970,341,932,170,527,160,649,972,186,965,31,918,243,393,590,597,480,585,921,615,5,649,915,825,888,789,621,189,281,427,780,573,731,438,592,589,405,584,882,118,277,812,970,626,440,587,756,775,135,273,922,966,410,286,351,291,869,934,363,16,310,990,576,455,511,862,708,49,551,629,409,471,727,502,252,155,104,510,906,155,376,916,135,677,708,300,937,481,330,606,844,88,993,862,148,422,978,755,527,248,784,451,730,209,700,146,287,717,493,432,500,371,160,742,95,207,49,755,155,831,651,347,655,164,862,857,946,186,395,164,220,183,332,266,203,21,70,360,303,57,369,465,653,191,439,89,644,541,361,299,592,927,6,175,222,814,198,400,508,59,978,187,55,595,80,569,116,375,280,352,283,928,679,824,664,348,724,31,850,8,904,246,620,408,127,531,671,465,196,234,455,546,105,817,265,773,586,673,882,624,190,885,559,57,901,758,760,131,741,305,410,659,584,452,695,445,568,282,376,717,954,622,650,989,610,234,635,17,314,107,770,758,911,395,179,389,548,827,400,223,928,997,894,932,247,755,916,236,610,765,209,355,119,286,747,7,413,414,924,377,979,618,178,852,798,89,587,970,641,340,518,947,598,172,941,157,734,19,260,999,899,559,778,299,902,487,869,487,622,462,467,464,493,410,539,924,369,21,974,619,237,17,706,436,149,110,583,389,402,438,922,626,475,780,717,251,520,462,708,549,509,280,849,883,376,712,598,859,878,332,73,387,798,40,563,622,471,869,192,870,430,907,394,531,604,62,832,9,967,930,698,866,290,968,631,79,983,315,25,73,716,958,400,289,407,236,916,511,647,165,186,727,264,26,557,310,143,292,165,608,458,209,823,97,39,523,645,362,406,394,436,852,270,266,942,590,255,417,82,419,349,3,7,728,826,598,275,754,684,758,456,498,579,200,381,147,919,822,478,967,142,632,878,697,599,543,858,105,626,886,327,677,590,989,879,16,403,852,547,738,568,813,124,9,28,618,560,837,279,71,379,600,956,302,68,366,470,944,314,267,216,880,501,824,43,651,69,273,646,336,377,244,825,321,777,712,722,128,340,229,218,884,309,392,45,595,311,595,862,58,729,808,924,384,732,614,942,770,972,835,955,171,517,243,553,269,34,781,517,631,427,66,857,264,83,855,666,749,494,324,613,296,651,303,672,834,367,831,812,932,293,502,180,387,968,25,283,170,861,307,463,912,701,951,648,294,110,141,827,304,275,180,784,65,168,827,224,572,716,74,612,931,977,658,648,53,734,654,303,453,718,788,311,596,944,828,66,228,319,861,126,282,569,111,352,311,258,682,739,647,136,834,816,925,307,615,299,318,134,786,936,103,800,443,475,235,178,319,299,623,11,898,883,988,173,660,160,580,640,543,414,71,877,811,962,916,289,229,853,315,62,951,160,292,626,633,321,888,140,472,532,309,615,555,149,479,140,954,339,619,492,122,717,645,189,627,543,691,200", "420,668,118,478,946,297,917,234,166,911,717,567,736,177,801,794,636,777,245,703,362,685,54,15,155,474,417,75,229,959,765,53,994,712,235,926,843,388,212,582,713,264,166,946,242,832,706,821,602,539,990,602,786,696,581,731,927,726,515,11,77,107,648,308,601,96,225,467,50,856,628,155,500,411,365,911,919,72,591,666,685,588,80,121,672,277,28,983,137,713,881,133,267,345,598,213,961,465,289,647,981,33,811,655,111,166,556,433,225,395,917,423,526,923,776,1,252,449,509,460,2,437,115,146,105,230,979,416,562,861,73,138,715,330,538,838,543,169,17,270,582,942,718,127,653,938,938,967,799,325,364,293,478,873,833,713,890,375,787,320,828,956,587,453,776,162,977,854,495,912,508,927,842,444,357,910,339,210,331,545,934,286,189,865,729,662,447,303,364,837,759,501,470,131,358,697,566,202,435,745,315,842,117,969,974,157,369,745,30,825,913,747,205,0,862,60,571,602,313,681,645,13,422,357,842,336,644,807,985,273,663,954,56,970,320,934,290,921,214,668,88,659,748,559,657,209,505,292,731,717,659,991,644,660,14,295,118,534,528,987,846,698,611,725,848,554,935,550,170,624,185,30,674,941,183,751,906,406,861,878,914,646,760,887,265,611,843,405,499,766,724,597,253,748,290,335,24,341,620,246,495,383,893,26,929,439,524,486,366,716,895,723,162,608,605,688,525,728,228,865,540,19,377,701,77,746,343,142,931,683,876,419,77,27,81,245,873,796,609,297,766,860,257,924,137,448,495,50,262,448,94,280,556,976,526,896,937,472,945,360,450,129,584,201,775,428,241,891,560,133,549,661,781,701,104,888,813,288,701,215,191,378,756,69,570,231,123,596,61,119,906,378,527,375,159,499,925,47,367,411,438,893,158,815,496,337,916,132,661,631,491,105,338,966,576,847,642,687,434,503,115,709,653,931,537,289,238,562,603,950,545,716,222,893,214,852,945,402,659,904,187,141,261,349,555,67,594,905,268,478,864,833,123,785,142,500,986,184,868,377,987,503,476,17,737,426,775,677,146,283,990,984,183,784,534,382,857,653,378,466,567,797,219,159,92,425,67,292,80,951,638,776,114,296,184,615,607,35,975,101,677,40,161,69,212,101,86,676,704,584,137,326,740,830,208,784,293,408,86,923,938,58,403,929,900,944,419,177,101,337,867,480,877,941,375,948,708,100,368,812,730,341,958,936,158,307,19,689,960,767,317,553,923,38,684,556,33,902,682,359,596,870,906,352,595,893,511,74,664,606,810,942,792,143,217,613,493,588,893,623,141,130,25,626,494,889,645,511,929,504,939,921,876,282,700,480,394,595,913,48,476,233,623,619,10,122,458,997,429,436,905,19,997,320,395,680,214,244,124,343,364,463,729,752,631,364,47,942,869,692,466,719,6,31,750,459,174,775,834,893,880,114,4,978,646,300,129,470,285,223,476,89,553,113,517,601,769,933,201,544,61,456,889,907,714,63,526,739,244,76,246,297,828,382,190,658,164,886,544,610,365,697,598,70,542,712,672,127,262,326,102,467,227,789,499,77,504,879,267,542,965,337,901,135,68,975,44,744,70,857,774,840,882,280,862,262,342,124,53,546,919,790,593,398,598,165,459,546,162,853,872,137,103,174,637,779,27,481,719,827,668,394,188,595,617,681,568,164,887,243,577,372,977,624,587,895,396,737,91,25,510,689,939,443,818,144,661,372,474,745,291,115,30,667,66,832,677,267,636,541,422,106,152,866,544,32,452,637,233,724,283,744,457,166,345,113,243,253,256,197,103,703,172,733,607,480,995,758,262,524,372,442,395,902,421,69,289,448,456,262,789,731,547,755,573,623,898,970,855,1,276,454,786,565,264,304,172,199,733,856,795,410,936,717,410,271,704,245,627,345,256,540,753,157,461,293,424,586,266,16,628,960,952,650,859,310,131,347,841,909,316,185,993,893,15,507,129,34,980,810,527,977,140,148,886,688,981,611,431,234,203,220,716,228,497,794,264,205,490,437,135,856,270,671,839,491,155,977,408,538,264,602,330,84,542,718,275,191,993,753,55,142,133,240,720,105,437,645,834,268,697,740,109,602,240,640,981,470,807,770,215,258,439,611,610,846,400,244,618,696,533,556,944,606,767,633,263,164,142,253,836,368,491,317,530,584,703,787,628,704,298,367,211,511,684,780,972,640,978,323,292,554,604,871,933,7,354,35,489,886,746,455,204,691,242,659,963,657,153,690", "481,980,51,249,140,161,924,62,594,890,851,381,232,177,431,59,65,226,246,564,18,479,810,344,263,338,410,873,765,58,261,108,817,687,446,230,547,530,122,168,762,930,777,977,1,846,21,358,429,551,208,97,952,486,17,309,396,928,157,718,633,629,674,593,680,135,101,306,990,478,453,727,182,7,767,814,438,448,368,317,117,650,884,24,783,732,586,984,277,977,779,234,965,462,167,268,177,516,512,700,2,855,756,838,837,245,535,497,603,825,258,929,15,943,195,499,169,758,320,531,233,461,726,650,639,515,913,905,857,480,114,880,19,438,689,118,802,539,907,256,534,576,597,184,994,170,959,203,953,113,734,412,218,979,429,345,194,104,856,295,301,825,829,173,800,690,33,688,358,931,548,401,119,446,329,178,968,895,799,128,642,948,194,935,160,210,412,81,458,567,220,208,781,191,512,500,743,385,714,476,459,689,107,700,635,12,103,836,330,418,633,788,914,862,0,205,734,427,730,989,314,513,586,962,837,65,55,101,374,463,355,370,303,598,771,990,794,835,293,624,968,242,692,791,698,660,38,823,681,372,916,831,808,292,413,70,485,297,949,584,585,791,265,765,985,683,808,472,980,521,490,143,739,412,256,606,848,360,903,926,617,737,299,667,116,219,747,963,365,815,458,697,981,534,502,55,350,76,166,10,774,279,722,602,426,32,131,108,771,539,125,817,484,355,182,888,415,769,196,890,7,617,775,328,863,714,718,713,654,799,481,539,304,163,406,125,859,30,196,579,998,914,63,178,312,533,331,519,350,158,31,461,900,643,828,183,455,460,603,164,110,12,831,75,972,516,12,78,661,503,738,885,472,170,255,59,596,614,651,906,223,844,990,376,884,565,854,726,377,885,856,845,323,854,840,173,210,355,570,984,707,467,851,708,47,78,577,437,207,295,432,868,346,645,204,822,326,407,787,480,809,745,634,357,158,281,428,672,427,410,309,196,849,633,911,828,81,885,650,950,890,830,575,848,736,391,878,854,354,57,465,615,475,864,742,824,974,696,403,412,81,497,598,836,431,333,625,821,29,25,412,586,319,519,970,557,935,944,763,701,708,762,175,32,45,609,946,727,136,968,717,998,890,93,900,69,185,786,945,293,762,176,772,848,42,764,688,403,9,540,85,623,95,937,333,590,604,521,158,178,127,126,907,379,384,737,190,541,482,391,920,217,37,752,412,326,745,724,248,430,435,634,657,629,511,313,880,365,449,784,221,780,821,29,106,21,327,936,500,971,954,377,997,147,333,948,963,541,4,40,177,791,225,953,170,836,578,954,545,728,557,676,780,15,413,572,868,157,448,236,421,698,722,138,388,523,648,691,365,526,511,843,933,197,871,730,228,628,262,667,282,557,453,646,513,761,406,948,321,859,922,894,817,909,930,462,635,741,821,873,594,58,909,845,450,17,582,27,87,826,190,953,499,933,525,724,80,559,468,601,131,476,642,843,680,968,16,821,452,750,821,300,734,283,706,106,107,698,358,203,548,269,823,260,43,395,2,884,756,925,743,99,120,142,667,111,622,915,655,144,239,737,834,145,585,548,496,583,780,999,831,561,216,540,208,964,325,720,859,968,118,88,26,644,905,11,834,445,274,709,676,256,459,404,532,620,590,192,727,272,355,220,381,629,931,540,419,206,597,559,764,569,16,118,262,905,680,86,578,17,730,348,570,395,112,450,728,703,718,86,341,642,692,526,422,95,402,206,291,143,205,843,68,147,601,297,324,572,161,786,119,659,252,82,553,129,548,38,593,174,690,294,240,484,253,479,606,930,526,71,917,883,710,654,274,9,22,987,488,264,612,910,800,922,299,151,544,817,831,199,371,140,875,558,309,174,182,897,685,863,678,855,676,417,9,696,458,413,296,167,145,49,880,635,400,839,948,634,667,276,264,163,326,193,172,103,635,690,432,434,716,301,891,256,576,208,914,943,476,627,404,212,712,502,924,757,780,94,343,284,350,813,360,275,535,999,522,906,635,179,700,366,739,583,770,179,228,776,692,432,484,116,277,853,585,416,481,758,867,951,40,611,383,929,412,643,38,599,409,877,436,222,222,269,905,141,944,105,141,60,678,220,293,33,926,690,875,643,986,116,395,306,828,541,62,57,155,714,643,198,264,589,724,111,798,101,770,183,403,730,650,71,928,600,255,395,893,910,524,679,728,65,861,522,637,59,718,693,557,139,175,440,317,445,598,9,20,779,107,482,586,753,60,154,221,72,188,413,592,456", "714,367,170,511,526,685,798,275,671,562,373,793,33,963,971,600,532,687,913,48,398,100,852,845,22,133,152,358,675,686,838,983,971,240,384,220,708,125,442,732,27,119,119,32,602,627,841,712,488,545,624,251,392,578,81,755,998,910,43,303,446,562,27,969,191,393,686,686,969,590,995,393,135,81,456,7,210,81,857,779,11,818,798,387,396,106,607,349,192,984,409,169,918,919,546,538,892,833,12,987,438,650,141,594,890,646,484,124,133,545,275,729,902,1,229,998,411,765,46,969,885,953,728,55,926,100,839,47,708,342,701,613,968,982,649,229,493,890,618,942,363,503,865,74,578,801,895,67,605,258,502,437,309,972,350,704,225,606,785,130,333,477,989,337,199,152,127,545,598,506,553,513,91,948,308,615,627,124,702,285,715,954,199,448,986,841,864,779,565,145,359,679,585,90,413,719,727,536,953,924,834,956,512,157,221,322,534,77,560,357,514,697,184,60,205,0,867,369,43,763,268,850,74,202,374,837,830,796,511,866,339,735,19,739,535,843,479,385,689,613,433,810,595,719,33,7,6,413,48,563,962,333,136,216,941,149,604,416,466,415,171,925,92,802,43,384,577,738,297,197,496,248,739,905,319,504,55,829,31,101,566,531,230,257,944,267,573,767,114,115,909,420,380,408,793,155,681,434,580,177,417,721,26,365,155,883,898,733,613,11,838,205,580,828,773,797,703,970,199,821,794,480,436,423,266,934,546,582,88,566,763,654,141,224,851,386,722,276,325,735,563,437,652,681,342,291,78,786,58,527,931,31,608,843,175,458,416,390,447,896,738,339,328,101,519,4,308,439,115,996,458,126,188,368,254,610,486,397,127,460,947,505,11,607,728,506,585,420,761,658,772,251,372,736,771,516,208,179,538,26,74,753,95,880,667,998,59,694,730,530,574,295,384,274,174,866,918,351,844,634,402,879,217,982,208,903,856,681,832,317,833,685,978,658,577,34,777,144,825,144,551,162,837,376,88,631,898,926,216,738,64,714,813,669,842,48,956,583,666,834,825,831,198,276,209,395,322,210,770,152,783,116,515,467,250,853,645,810,73,627,695,889,128,62,807,310,194,597,20,964,24,940,476,824,305,726,62,328,822,380,434,644,593,588,876,451,893,110,610,352,219,842,323,812,537,321,123,708,456,656,803,906,765,633,231,490,571,155,113,92,222,942,915,779,710,777,779,716,896,384,919,508,264,799,999,430,134,393,523,539,528,405,172,133,193,753,946,267,701,19,245,417,902,896,183,334,893,921,841,548,953,234,860,706,252,132,539,397,427,576,473,562,757,204,605,709,617,227,394,715,580,970,934,288,691,984,104,654,467,352,432,266,541,156,167,243,994,457,893,473,769,561,852,420,363,194,237,698,175,89,491,477,615,19,349,964,837,821,354,718,742,274,492,846,928,153,441,602,255,90,834,751,848,649,671,928,74,233,483,807,587,474,945,569,227,710,921,977,709,778,390,953,60,719,968,905,42,323,335,871,494,478,575,720,834,304,630,251,748,623,563,679,573,451,313,430,976,214,95,643,583,167,647,693,783,794,248,210,573,132,573,311,552,819,464,985,280,965,267,947,457,380,405,181,451,867,157,377,297,256,101,742,259,723,854,365,218,484,421,983,197,789,108,138,97,828,958,917,264,540,286,460,938,392,84,393,971,310,598,544,724,334,957,170,588,21,105,906,373,283,723,459,421,251,242,363,500,754,543,786,726,40,977,597,919,984,767,981,221,920,938,70,202,92,207,773,225,514,249,573,66,486,41,846,193,397,125,551,516,206,726,537,813,633,902,834,83,191,433,765,255,329,937,574,874,482,941,725,866,139,194,421,945,250,772,798,859,462,504,316,530,591,619,52,329,989,188,948,331,249,997,794,760,8,84,35,544,66,67,78,393,753,673,183,12,188,387,210,531,58,754,84,927,293,692,460,795,769,538,340,407,937,266,833,576,76,477,309,289,274,387,387,569,82,551,793,624,352,459,130,122,893,625,677,213,321,129,620,173,605,392,396,808,702,906,945,546,88,437,794,149,374,783,993,807,956,175,313,173,722,667,236,831,576,701,607,982,611,785,734,187,111,966,618,378,491,976,437,221,534,8,898,998,520,975,111,952,67,782,585,444,306,374,399,403,822,190,972,815,601,995,926,254,376,821,946,352,745,132,422,865,481,414,752,430,511,310,86,927,775,984,580,609,825,898,900,541,187,291,543,84,979,376,640,561,716,294,938,44,444", "524,48,229,378,149,422,425,765,903,659,989,563,812,532,906,32,116,799,731,939,648,797,368,779,715,933,194,152,26,387,133,512,261,348,118,474,607,784,221,608,949,61,801,375,813,951,382,791,853,464,489,182,882,241,243,181,359,411,564,840,606,856,817,167,209,50,715,25,734,120,274,618,485,889,389,187,963,927,643,268,836,887,282,290,582,854,757,959,362,482,707,975,179,513,99,732,992,323,305,739,978,83,83,733,802,453,956,17,794,620,284,278,993,734,347,978,92,447,87,477,242,941,936,593,901,159,631,62,20,41,779,331,92,632,112,143,20,73,227,251,834,388,252,966,558,553,135,473,967,668,275,487,218,166,846,467,65,502,641,228,336,589,897,869,587,516,745,777,370,910,399,938,160,818,835,199,229,781,180,301,287,486,709,875,904,499,517,778,76,859,173,618,866,344,930,878,416,309,344,42,494,69,914,892,766,280,916,393,124,754,557,323,337,571,734,867,0,865,443,276,817,299,525,474,593,570,383,136,727,19,602,256,601,504,160,744,185,886,388,71,202,554,557,992,131,285,205,657,258,664,209,111,176,916,24,511,8,710,944,255,104,127,128,167,848,460,9,430,762,21,787,558,308,921,729,544,570,685,166,267,775,794,619,395,677,975,319,517,847,117,91,161,356,864,157,520,555,591,172,907,422,100,569,645,739,924,725,961,302,800,617,448,636,964,898,863,353,928,826,614,514,661,258,942,164,6,115,476,10,795,758,588,959,753,511,818,384,21,146,640,605,713,658,344,619,170,921,746,661,542,475,387,874,6,672,536,226,248,134,487,748,567,48,461,321,695,636,641,808,672,374,760,224,997,213,236,610,193,220,107,70,990,222,785,137,676,260,808,526,244,247,875,614,873,442,750,222,647,740,756,273,351,886,476,441,262,578,417,318,443,520,43,499,265,282,568,215,726,683,745,242,331,379,88,737,73,332,239,333,50,318,467,955,928,219,681,225,738,484,647,154,762,693,860,649,114,92,39,258,48,415,945,826,618,385,166,189,904,778,725,198,559,205,224,988,803,155,667,283,523,913,670,361,256,920,30,496,761,209,465,940,816,821,748,363,670,873,241,623,900,114,594,592,617,815,929,914,878,186,861,138,950,98,328,313,206,835,218,549,928,559,394,449,536,112,271,944,879,78,994,610,806,844,575,777,689,161,656,510,863,844,775,725,439,98,743,548,361,405,50,529,744,678,808,560,426,439,767,904,442,647,478,319,140,822,791,760,315,615,404,111,4,790,268,30,849,789,313,751,730,720,132,698,293,16,63,283,94,939,204,563,817,749,375,610,372,836,358,848,483,491,960,21,611,85,627,343,787,911,549,820,846,53,300,323,48,274,76,394,634,763,60,88,966,200,225,861,55,318,24,417,458,690,390,660,804,463,156,43,784,653,555,620,147,731,64,421,127,745,873,464,989,784,808,194,359,909,470,117,613,967,685,773,283,739,679,442,642,172,899,509,189,71,251,640,707,97,318,291,917,278,443,284,777,264,499,630,137,498,880,972,810,294,863,989,111,593,383,619,179,235,305,79,254,506,131,42,840,136,854,877,291,900,995,368,716,475,434,909,248,972,699,994,82,304,461,964,827,988,876,866,82,872,821,852,924,534,487,475,21,959,384,542,203,119,840,28,252,809,655,602,158,889,885,140,20,178,284,880,544,664,114,666,711,972,659,377,88,235,866,342,917,168,380,872,228,607,144,804,591,142,870,237,413,916,20,92,435,623,200,308,556,31,171,687,451,590,742,137,492,409,527,690,891,399,623,129,803,102,19,336,536,878,759,783,283,70,701,965,323,661,713,77,49,107,954,878,90,624,741,518,878,528,304,144,646,624,41,351,725,414,132,972,973,207,786,850,41,803,509,520,280,570,914,335,467,561,169,104,172,238,847,3,69,502,870,13,295,379,841,698,906,216,209,606,925,24,370,903,845,16,47,141,758,244,906,22,354,225,67,153,399,508,699,561,722,800,867,838,29,699,952,964,260,32,322,333,380,437,640,800,565,141,246,428,259,951,758,424,662,493,793,984,443,600,785,987,686,983,57,937,791,232,750,607,751,446,762,6,987,430,336,499,936,306,912,360,703,419,111,779,404,839,605,956,138,410,763,1,990,865,580,290,162,894,171,864,766,504,105,617,261,972,774,979,604,441,741,699,922,618,962,532,98,504,410,373,133,480,609,119,700,613,80,922,298,27,90,509,315,488,503,860,256,662,698,230,142,969,447", "633,424,865,363,85,83,323,225,873,736,311,852,149,708,415,445,110,490,902,849,854,614,395,755,792,400,575,631,313,750,993,284,676,753,813,528,714,871,349,655,253,395,238,605,577,725,665,998,977,928,393,324,176,201,190,256,120,97,251,219,867,450,901,560,371,827,984,824,258,954,288,85,207,533,796,745,496,995,721,865,655,311,540,512,303,573,783,805,51,809,462,211,806,575,244,95,101,505,195,456,851,648,346,516,74,335,862,652,237,989,279,962,218,833,85,707,535,355,62,284,352,119,841,727,480,443,248,72,459,177,360,197,607,23,238,221,816,19,163,797,720,210,246,262,120,6,717,795,39,92,643,862,942,152,607,174,567,80,35,84,856,398,358,247,670,342,922,796,722,999,319,845,599,119,520,658,832,163,751,43,958,678,818,625,70,428,577,437,572,343,52,700,727,307,750,658,608,597,31,359,137,856,910,165,816,462,332,364,216,208,54,184,391,602,427,369,865,0,759,683,519,246,845,963,392,360,750,773,194,439,579,427,587,592,1,803,966,68,369,325,231,763,969,813,552,969,490,348,983,958,740,850,148,84,642,460,643,316,723,528,966,784,664,782,129,269,264,262,634,99,322,955,389,70,428,526,420,667,531,371,320,254,283,429,873,812,507,136,89,841,339,949,326,812,453,579,1,437,857,504,57,409,602,416,465,260,448,315,694,798,961,285,594,486,943,317,868,445,645,594,824,746,95,490,75,522,380,997,895,240,959,332,359,866,483,191,751,439,554,229,954,821,202,963,390,784,672,143,769,917,284,906,331,325,244,934,942,972,733,766,124,450,19,871,735,967,133,765,402,639,476,604,335,598,512,365,581,294,206,412,827,736,26,650,142,338,552,103,123,244,420,440,262,222,609,44,285,820,858,883,962,836,565,38,718,954,614,480,746,753,471,190,505,244,474,37,53,390,408,880,945,915,859,229,137,482,689,123,632,78,415,515,128,73,929,882,738,749,407,298,693,559,232,652,759,343,94,85,15,55,922,233,408,106,598,329,702,494,795,50,917,154,544,495,840,878,55,112,114,786,225,755,618,401,691,558,729,684,838,535,769,119,840,462,935,397,162,916,443,980,415,794,866,225,76,404,162,175,475,759,376,495,33,255,72,53,480,725,238,12,569,884,112,495,820,332,473,375,162,983,152,415,870,484,486,421,323,190,376,522,375,835,741,799,313,659,349,257,734,721,120,795,639,674,676,319,816,111,350,803,527,896,508,393,88,152,304,852,744,214,750,125,617,611,207,41,505,881,123,350,139,56,50,247,421,752,199,938,121,188,803,775,31,937,512,82,417,64,195,55,387,570,967,909,17,383,279,775,12,228,613,332,170,43,736,329,430,176,431,693,341,49,5,214,681,757,717,769,263,507,949,572,721,52,479,382,262,450,52,983,267,412,283,763,59,740,555,23,207,264,950,205,693,219,355,650,937,663,897,36,964,90,829,407,383,866,411,739,427,926,42,372,944,159,875,477,995,951,234,416,705,46,746,459,18,372,254,88,306,392,394,426,744,943,549,709,830,315,98,110,705,717,684,364,512,739,971,261,755,762,968,580,529,854,673,873,228,997,451,695,1000,656,819,418,202,430,135,8,903,86,429,536,663,634,68,798,236,433,937,12,767,672,213,674,379,28,693,627,644,386,262,770,329,718,825,626,538,850,740,363,211,156,311,686,947,708,754,36,517,252,654,510,929,499,619,956,922,283,963,725,693,405,281,706,610,209,185,122,719,616,852,708,191,470,679,471,244,885,561,319,56,329,651,827,311,64,962,366,446,608,175,737,720,872,537,643,476,815,256,290,580,116,139,150,343,195,55,728,86,108,957,590,706,522,461,633,792,350,958,246,529,136,188,614,871,475,685,256,76,466,533,881,637,633,366,963,93,998,843,585,955,539,594,953,300,380,844,782,396,634,62,420,786,547,55,148,312,808,965,351,685,164,428,937,825,399,156,274,986,395,986,206,497,682,898,857,840,576,396,976,46,433,20,430,366,837,800,831,934,909,775,638,247,994,914,670,828,381,183,895,334,481,627,448,840,564,664,108,236,548,809,392,316,300,501,747,893,35,66,850,429,881,809,566,427,310,643,327,550,896,170,370,510,405,454,390,513,944,998,557,453,140,474,257,204,29,760,804,608,4,428,240,440,160,993,506,16,255,831,660,141,378,62,520,885,849,373,791,277,196,587,558,388,91,535,351,738,522,469,501,535,347,514,41,102,367,866,543,980,123", "897,692,45,108,254,288,297,714,660,183,731,151,232,58,345,436,549,316,406,414,501,294,654,564,177,619,265,587,895,582,275,795,25,664,456,833,685,603,99,539,468,576,284,205,738,172,533,415,133,908,311,932,426,89,405,837,443,571,732,20,312,122,892,82,41,660,257,150,776,283,689,295,650,585,637,185,613,944,660,367,266,829,871,681,486,990,988,353,249,664,886,762,417,496,936,922,298,477,335,256,732,760,158,763,740,646,14,315,407,884,40,408,368,954,103,523,452,663,603,603,518,618,476,148,740,207,939,838,290,995,149,582,937,353,501,696,13,455,434,189,527,808,728,74,852,370,502,901,888,910,251,842,269,593,392,496,432,833,467,735,267,868,528,955,731,457,628,548,813,621,719,500,566,158,527,645,912,868,672,414,684,584,299,777,632,406,35,793,207,69,580,259,636,448,517,299,289,173,765,140,404,373,597,269,36,838,50,899,809,528,267,343,685,313,730,43,443,759,0,103,322,699,699,192,907,670,733,520,891,463,479,200,111,886,438,926,147,228,488,438,639,686,40,327,795,939,613,852,212,647,859,82,890,35,968,806,165,340,911,780,125,50,870,131,435,887,224,814,301,395,790,671,459,555,846,332,873,716,10,578,214,525,421,302,520,187,360,928,703,977,665,907,636,971,8,63,462,550,512,468,332,784,577,387,235,258,462,488,532,697,654,145,117,68,365,270,902,944,643,101,477,216,49,745,443,681,410,561,803,188,851,753,578,197,500,863,304,25,887,498,831,100,536,765,649,942,181,953,471,83,579,535,783,796,440,875,983,752,253,760,369,726,898,884,49,944,972,723,802,209,671,241,478,378,323,999,489,133,852,911,588,303,178,559,19,943,668,932,674,934,353,719,450,682,844,354,256,291,570,321,112,226,337,143,242,50,798,229,879,536,882,616,173,44,811,270,625,423,854,529,289,55,471,486,54,225,664,207,516,463,671,255,371,422,620,233,862,286,15,348,763,893,145,553,300,292,270,401,965,372,866,763,985,704,978,350,139,267,373,344,968,385,78,599,63,558,660,354,946,799,147,268,782,643,357,87,681,354,655,494,128,769,192,680,968,615,712,47,51,141,164,175,281,560,427,682,336,82,45,59,894,827,456,214,979,873,815,781,854,632,169,238,58,664,42,805,776,89,733,232,280,711,664,509,273,180,280,433,313,335,328,914,274,427,508,410,693,791,15,555,58,569,968,843,868,330,162,679,611,548,170,639,596,322,643,696,75,202,281,39,198,508,688,719,368,630,786,782,558,569,923,665,941,457,159,443,86,556,270,213,518,836,718,477,258,702,677,265,121,133,833,634,811,612,760,87,413,323,660,154,791,817,86,743,904,44,37,732,730,886,797,42,790,711,732,253,818,36,780,691,759,109,336,120,722,192,287,486,391,37,458,985,551,388,27,895,808,958,913,956,898,960,774,170,626,801,894,429,744,166,619,665,900,132,626,962,995,696,231,84,463,808,154,87,600,299,481,168,943,141,953,625,52,419,744,473,403,638,209,500,768,853,701,2,712,599,290,121,566,115,881,18,901,574,522,708,277,592,22,711,724,718,603,867,164,287,221,873,613,14,443,316,539,488,590,916,810,459,599,234,793,550,778,602,388,78,881,545,541,251,749,516,33,828,27,695,821,562,361,440,463,712,811,884,291,988,749,77,756,855,101,821,568,158,831,771,948,56,903,23,796,699,259,179,149,221,679,509,884,654,147,987,95,51,825,747,884,929,887,461,42,468,780,27,427,510,117,118,183,801,37,86,543,763,711,926,709,358,523,430,10,458,474,425,907,248,864,492,784,757,517,21,144,11,171,754,340,460,763,440,575,364,796,503,201,673,81,786,354,245,410,766,213,354,58,797,235,780,754,562,15,17,763,457,346,162,548,276,365,90,55,329,528,764,327,139,441,456,238,143,396,642,9,182,84,659,360,22,664,541,458,964,418,220,149,795,875,60,984,914,513,972,692,380,52,481,279,187,711,186,51,949,164,5,978,103,950,765,82,862,863,387,152,957,78,466,743,175,641,312,512,783,581,692,636,893,794,192,12,85,882,619,800,289,348,985,758,956,538,869,359,707,898,131,784,653,181,343,456,679,599,938,664,983,776,139,983,578,871,114,318,575,686,914,787,103,995,452,574,921,191,785,454,414,319,209,53,197,402,549,282,712,390,550,33,705,470,909,310,505,986,683,161,99,70,801,60,700,76,452,918,79,175,526,622,743,768,934,869,819", "279,958,982,577,710,284,389,273,948,903,911,66,900,356,560,272,370,72,635,573,436,137,756,36,732,809,747,875,293,532,286,128,251,919,993,292,983,334,539,264,502,639,687,739,626,456,184,221,732,964,375,262,295,146,995,750,112,229,151,933,884,64,501,322,847,460,343,24,616,182,356,796,345,673,814,477,234,959,650,357,525,88,180,131,506,578,128,613,212,495,806,851,754,827,464,923,460,237,453,503,285,457,342,554,635,966,93,474,505,325,727,18,997,11,866,410,860,210,158,396,315,70,41,623,697,745,220,724,153,42,839,798,231,248,726,426,49,819,774,89,849,22,607,318,514,9,930,888,478,498,482,300,592,271,198,403,430,262,647,394,447,270,299,783,398,396,76,88,710,17,805,833,758,186,865,118,476,967,720,501,165,602,731,88,345,852,802,709,607,849,773,981,640,899,371,605,897,525,959,4,365,968,842,147,952,991,294,890,86,678,517,925,429,681,989,763,276,683,103,0,5,491,538,443,848,849,402,411,348,806,950,199,914,187,86,343,770,846,893,5,987,623,603,854,62,430,203,359,504,342,693,773,252,583,541,432,823,157,231,610,72,282,75,823,887,412,858,479,253,203,347,371,315,900,926,982,537,15,971,25,744,234,203,610,896,276,829,18,477,45,211,538,910,454,748,116,401,477,231,402,334,543,241,775,840,235,846,750,876,40,336,133,921,440,766,251,736,26,409,774,140,351,983,15,816,877,556,953,379,631,812,907,474,708,878,88,322,957,945,699,91,773,210,186,962,601,52,861,684,652,956,355,68,760,410,939,356,268,902,609,134,200,356,744,475,625,682,6,20,781,334,116,660,131,6,365,140,882,949,128,997,78,268,649,331,442,733,856,325,443,458,94,893,275,142,732,900,129,45,211,973,310,793,729,706,836,646,4,132,520,302,936,713,552,463,894,229,485,864,626,27,315,31,570,584,478,372,12,856,355,78,121,629,158,621,129,293,231,76,959,955,414,445,928,706,501,212,410,314,429,356,852,741,872,590,903,470,273,140,335,815,253,241,360,316,107,233,809,776,461,939,800,828,671,959,267,837,440,568,178,178,804,112,386,610,354,631,252,674,242,799,472,187,100,758,631,759,967,246,282,865,915,776,772,3,655,722,787,338,285,983,565,933,211,584,806,474,457,998,450,429,343,917,95,960,750,691,930,309,602,344,481,400,645,494,382,866,303,498,273,487,748,187,425,242,277,27,173,942,881,46,816,671,821,478,808,663,392,213,359,936,117,728,827,459,403,712,767,460,780,903,164,957,670,411,80,496,744,955,446,382,765,106,74,648,765,987,540,334,177,623,619,583,894,860,718,801,787,968,213,16,399,204,460,422,581,461,873,178,533,436,645,929,163,901,437,517,783,910,247,983,330,54,308,124,415,251,855,174,741,810,49,561,427,138,213,292,384,789,131,629,189,235,585,217,247,145,894,215,64,545,100,159,863,764,900,213,190,404,765,2,498,750,228,664,938,929,163,667,232,119,71,642,614,246,656,543,438,689,598,671,99,640,358,686,299,462,661,344,718,124,920,607,697,604,796,611,71,445,801,594,921,532,188,852,171,658,661,96,505,515,650,794,388,53,77,603,208,842,836,762,628,362,399,622,146,268,173,771,666,265,61,344,703,560,509,551,585,66,462,34,805,336,341,398,375,576,835,298,705,770,406,96,198,805,620,398,911,2,734,219,798,636,56,480,898,934,491,764,744,483,989,895,566,418,718,741,283,207,185,150,518,186,605,695,338,587,757,779,53,663,790,311,589,358,345,499,304,98,316,475,612,139,521,910,609,398,300,913,866,845,777,756,552,66,155,314,716,203,758,974,541,118,607,573,467,58,945,320,579,593,205,421,257,251,295,688,672,273,558,17,469,62,259,742,349,275,969,360,541,95,227,540,689,991,450,51,12,343,380,121,379,948,510,443,710,716,136,426,689,513,639,220,814,894,299,366,636,581,495,145,156,245,811,391,443,347,120,943,109,206,854,926,74,716,358,641,930,538,990,764,209,894,802,660,372,612,951,121,994,82,15,247,488,709,986,116,329,549,532,985,623,359,993,739,696,627,646,643,516,251,229,672,114,834,144,139,638,970,232,339,431,819,258,778,722,987,52,489,554,899,530,642,545,521,771,151,283,293,218,329,319,988,867,971,759,809,273,156,986,872,771,886,485,764,976,363,149,290,798,922,13,392,754,117,726,884,926,567,603,630,582,537,58,33,614,170,805,99,784", "760,223,109,932,100,866,483,324,695,747,300,537,183,615,932,209,315,102,370,193,102,108,643,162,551,694,529,691,458,433,461,880,985,163,347,546,651,853,146,286,269,403,345,714,251,241,432,26,598,81,584,770,37,616,787,299,34,482,641,653,805,48,797,386,104,414,987,875,881,663,288,455,49,576,328,508,88,27,155,349,858,868,621,134,928,481,523,64,909,423,261,326,725,526,769,123,213,474,364,478,609,944,294,528,684,884,520,699,61,5,865,368,413,223,697,667,520,868,567,994,688,139,339,12,18,535,146,743,642,676,613,165,291,775,810,4,348,564,884,668,679,802,275,174,45,183,666,695,767,136,639,116,294,538,602,927,72,71,992,743,599,707,551,189,769,647,204,812,594,124,20,559,904,400,604,881,704,161,448,767,161,446,701,369,393,359,751,756,969,474,638,480,387,640,283,13,889,653,770,352,768,131,787,975,958,457,895,90,593,465,710,539,467,645,314,268,817,519,322,5,0,897,313,104,322,65,378,243,688,959,947,365,398,783,164,617,630,229,680,232,475,778,388,546,242,606,990,168,951,473,939,611,312,42,658,586,384,998,774,89,365,108,656,596,897,348,419,402,593,864,172,838,934,386,390,723,580,596,146,81,23,357,896,576,81,458,199,773,114,242,148,641,536,951,666,268,822,364,224,814,968,370,124,151,997,133,669,379,138,723,865,92,559,589,248,109,215,142,533,779,648,224,131,581,248,440,57,666,698,288,773,660,806,912,433,679,920,465,793,689,1000,679,841,341,307,848,738,892,456,711,817,990,685,185,789,729,331,801,441,157,588,217,829,803,89,503,842,200,550,798,841,339,937,923,961,881,810,444,587,581,106,675,258,480,633,546,692,580,757,212,531,435,504,12,935,771,104,552,14,232,946,182,834,252,16,164,729,454,650,538,432,937,957,547,797,261,727,998,351,4,25,852,755,520,17,916,2,297,350,355,152,923,474,925,147,710,744,729,278,514,15,586,91,290,24,922,576,653,776,853,534,444,898,428,841,931,14,511,816,157,469,506,947,277,616,370,433,637,953,418,979,797,139,374,83,762,212,897,891,311,413,855,714,942,338,929,364,579,165,944,362,943,233,71,242,768,677,981,896,959,114,419,686,372,76,466,513,434,16,649,937,359,332,760,259,482,506,945,61,428,442,524,203,888,949,684,655,595,964,633,558,938,557,24,1,518,153,744,742,457,273,127,582,51,113,766,723,117,673,877,382,525,105,298,547,160,456,479,315,356,663,35,588,735,111,556,749,469,433,879,102,343,956,250,589,3,236,474,918,616,436,97,76,771,386,283,828,633,921,341,561,323,95,347,549,635,829,392,57,342,427,306,379,617,692,438,667,371,90,42,527,675,610,567,762,769,569,457,605,619,775,641,588,511,421,298,510,596,489,677,450,876,79,931,162,825,65,649,671,543,168,722,106,108,780,13,557,32,769,612,585,451,610,319,650,304,556,863,258,929,381,121,859,509,628,369,214,188,94,647,753,98,985,880,669,179,542,335,919,423,775,762,47,819,529,341,644,236,738,171,510,823,803,997,356,751,458,584,93,79,493,471,700,742,806,8,389,222,730,799,470,420,403,716,26,849,518,794,470,340,424,704,688,193,760,575,107,412,243,256,594,633,565,588,221,652,866,591,915,384,566,942,481,700,937,727,355,360,714,318,63,526,909,148,452,275,313,275,684,773,177,652,373,193,765,893,336,651,885,781,617,428,428,661,937,147,928,573,987,877,71,323,12,277,905,835,49,857,131,428,577,733,389,503,644,380,774,979,725,464,927,855,592,862,504,465,778,360,842,983,580,357,255,852,39,262,256,598,80,4,978,397,435,727,820,279,647,388,349,489,350,915,685,55,279,407,641,72,616,389,601,515,185,651,494,109,215,732,946,536,297,594,375,262,189,381,827,498,3,680,542,3,608,433,941,578,122,481,290,719,409,790,291,346,268,902,332,813,970,819,553,323,733,260,284,544,495,674,722,39,415,991,186,566,94,977,833,647,816,761,911,232,918,225,537,188,83,159,445,705,71,179,198,324,514,250,926,539,208,369,202,895,350,347,290,321,12,127,422,393,663,320,992,609,106,475,816,218,971,721,540,498,918,83,332,219,703,365,938,507,521,756,68,91,151,332,344,769,586,158,28,224,278,322,72,22,474,168,768,26,377,305,401,506,56,714,161,936,709,626,642,312,295,589,51,720,514,860,160,174,380,846,662,809,116,312,326,708,283,461", "755,374,575,170,317,289,151,532,589,944,882,192,916,888,630,371,775,762,657,871,12,551,745,224,995,670,788,446,235,342,694,443,956,903,536,877,374,195,830,42,4,58,309,179,950,270,345,613,203,527,134,835,103,67,399,864,379,349,271,790,358,768,267,513,945,88,755,858,240,956,586,197,8,975,200,112,288,949,332,337,814,673,217,480,612,628,468,291,272,653,216,770,478,413,640,5,929,581,596,848,365,564,914,671,951,335,777,294,53,251,271,907,443,220,740,57,95,49,70,520,992,64,143,156,985,747,569,434,533,68,298,737,221,785,212,256,405,275,884,232,574,585,877,528,692,341,430,525,511,196,759,534,137,108,166,234,367,985,984,486,682,285,637,441,46,564,370,410,179,729,766,785,401,301,588,422,316,28,93,353,601,338,799,559,549,908,258,973,379,503,749,351,959,40,276,352,90,178,720,891,154,174,396,821,987,500,140,613,867,272,544,620,846,13,513,850,299,246,699,491,897,0,249,817,561,545,138,248,37,681,836,496,198,333,99,652,252,282,864,505,430,266,417,576,528,304,674,44,734,507,313,146,285,900,371,605,530,303,451,609,246,847,369,966,924,137,320,121,35,390,330,354,234,879,426,849,248,354,811,54,946,138,559,315,894,759,698,267,237,151,696,928,802,278,741,65,890,764,243,563,393,74,905,509,760,556,965,950,196,354,939,727,118,616,652,840,881,380,819,110,658,996,851,229,992,755,360,946,866,140,406,392,238,510,959,484,897,358,953,892,140,715,813,699,550,103,608,846,440,686,471,846,296,720,877,468,666,204,807,160,254,62,783,148,800,256,886,152,457,382,263,541,943,935,685,31,999,54,856,228,407,89,297,158,149,143,227,419,80,933,610,259,448,322,643,73,720,793,359,238,239,871,795,932,170,882,469,208,734,682,82,593,124,421,749,337,650,214,513,116,252,275,285,983,570,954,606,997,396,959,50,394,893,950,540,403,468,75,848,531,289,546,919,405,580,677,424,560,613,10,173,113,685,675,358,192,301,712,245,444,854,778,396,306,594,866,591,851,824,844,582,550,149,898,470,470,800,141,363,636,402,291,871,814,593,599,13,992,727,437,35,59,876,766,132,925,655,192,146,621,230,218,204,769,36,255,149,26,262,319,351,690,166,569,938,297,477,294,78,791,153,985,734,200,405,575,639,563,323,624,807,897,793,894,499,639,650,729,890,926,673,720,551,128,399,867,227,548,190,796,331,767,752,738,743,723,706,43,491,312,484,207,556,184,398,869,207,873,606,756,125,182,861,637,615,465,539,509,573,96,120,580,618,937,694,238,34,424,566,473,653,363,695,371,228,688,941,129,617,981,818,505,768,791,615,856,658,989,256,518,983,783,41,244,943,940,962,798,888,269,434,52,616,26,282,461,541,295,43,466,315,234,99,858,294,951,507,207,710,248,563,700,420,128,135,284,948,140,873,212,6,912,980,52,176,296,207,392,883,91,833,377,368,420,518,884,464,806,580,504,712,808,70,826,988,791,626,319,649,530,501,148,515,367,521,445,697,480,455,751,584,422,128,51,677,380,348,931,630,873,91,277,207,25,357,879,347,149,61,420,273,22,31,960,685,13,363,255,338,780,793,114,199,309,537,203,467,437,980,9,150,850,408,613,276,945,528,342,959,75,39,274,631,559,999,959,980,537,38,949,612,597,765,307,634,779,373,286,840,692,608,866,510,368,446,894,640,575,12,894,961,2,193,554,577,731,49,205,426,396,213,262,436,717,3,692,592,63,8,529,46,530,30,94,810,857,89,791,816,825,796,104,234,697,601,742,190,858,548,639,217,250,275,305,176,650,866,990,921,506,13,423,35,123,447,721,222,704,15,650,179,450,281,395,139,508,66,845,239,734,576,145,887,41,3,665,925,531,282,558,22,659,204,540,483,352,698,212,800,987,429,147,37,927,613,944,569,589,85,778,176,485,779,780,355,218,166,651,711,14,502,72,865,835,266,153,390,567,805,286,436,415,456,953,716,826,906,463,89,430,317,455,992,97,913,187,407,819,581,560,29,859,243,459,444,924,896,747,933,578,694,129,245,15,795,701,630,860,839,620,268,691,288,345,838,936,662,701,450,402,736,840,914,369,791,121,681,163,13,956,434,868,10,413,738,899,198,229,460,353,97,241,739,736,724,481,17,956,736,1,483,741,234,468,431,289,506,515,710,484,971,369,114,274,258,590,177,784,618,518,608,614,603,379,605,914,277,983,385,196", "101,929,320,241,239,828,569,228,81,880,402,881,943,120,189,361,99,762,138,940,683,411,668,805,604,818,563,764,414,269,562,334,366,775,61,742,258,440,766,645,172,632,125,339,811,277,677,23,826,250,240,29,969,482,566,136,29,565,816,541,243,190,34,9,329,253,704,251,355,749,713,200,587,434,626,561,682,257,138,198,465,511,310,726,875,672,568,283,843,644,166,413,679,382,126,280,671,451,245,44,287,539,565,992,416,427,990,966,94,838,349,165,13,852,779,460,24,262,407,375,604,844,464,518,627,415,936,930,223,413,386,607,963,754,396,479,123,978,881,429,679,512,379,354,464,99,389,949,150,17,663,726,268,451,541,229,699,703,792,841,686,798,413,896,621,99,111,533,805,557,835,675,264,354,980,912,704,639,15,883,222,379,806,213,911,485,572,486,791,703,348,904,617,760,751,458,858,292,636,13,629,179,164,253,740,812,285,634,596,232,951,353,649,422,586,74,525,845,699,538,313,249,0,232,372,60,78,417,703,400,789,454,930,798,727,451,474,169,984,417,772,33,806,72,860,154,821,473,644,316,242,767,963,858,734,85,960,311,288,327,967,650,862,332,138,121,234,160,758,851,909,10,793,377,174,433,654,407,51,704,573,941,12,744,853,404,831,654,392,650,986,946,156,505,537,86,901,992,541,204,84,402,273,973,850,8,136,506,912,154,574,639,430,794,395,26,13,41,265,103,880,592,232,97,62,635,237,149,833,784,197,695,11,802,225,399,486,828,716,862,628,93,320,515,25,442,724,268,190,631,499,858,290,690,252,160,705,787,360,539,324,422,988,968,489,133,848,121,789,362,974,789,512,92,423,853,205,243,584,971,315,39,458,292,176,398,780,321,922,804,225,197,202,390,465,73,188,508,232,274,911,52,332,688,112,996,862,910,610,404,702,227,701,779,484,75,818,584,629,273,478,630,607,571,318,713,928,355,946,922,53,881,760,287,126,612,504,792,683,419,647,998,533,102,969,476,758,611,684,542,958,54,871,877,363,985,434,449,820,272,434,922,799,231,519,774,73,139,677,70,312,254,878,390,700,854,52,73,830,582,786,55,184,500,459,365,611,181,268,224,809,999,31,989,477,865,348,226,370,902,237,412,550,993,60,595,681,225,121,984,588,624,706,112,413,839,932,415,243,522,40,216,990,259,54,809,292,327,142,555,471,196,534,260,563,516,93,511,997,877,81,592,622,405,265,682,366,495,270,941,881,934,497,745,377,513,636,961,198,907,887,212,594,138,259,624,786,22,706,377,456,388,152,257,542,801,483,997,370,679,250,663,554,5,993,998,510,108,355,909,414,447,191,231,51,294,578,983,572,31,106,287,869,476,964,591,573,297,270,511,898,159,962,366,650,419,969,846,120,987,955,699,618,806,725,376,293,344,126,973,608,540,141,933,158,542,701,231,882,127,243,106,574,811,538,20,385,102,143,536,403,508,161,187,768,188,337,484,362,425,512,161,129,315,46,682,664,859,7,438,990,263,321,715,617,821,889,233,216,386,436,564,870,690,454,63,109,623,655,611,43,193,189,650,779,340,37,892,163,926,562,41,195,101,810,841,541,932,972,937,823,128,474,881,43,55,551,380,476,829,849,732,436,974,592,752,241,449,377,607,445,791,379,810,216,300,172,560,252,231,384,667,325,911,964,573,122,214,320,257,361,432,791,499,347,424,671,860,354,579,179,772,102,790,182,896,726,875,347,795,94,41,517,139,606,799,653,818,510,675,988,914,442,891,572,303,484,882,32,94,799,468,30,172,662,332,227,656,975,578,740,439,101,930,429,410,50,617,404,924,770,634,686,957,460,267,835,874,491,538,135,159,639,927,850,564,10,250,458,81,962,191,220,211,477,169,672,54,894,522,259,206,320,963,971,70,277,455,550,543,239,15,351,174,288,73,689,596,613,911,312,535,876,229,635,348,271,963,934,227,758,269,827,333,704,337,525,517,332,907,785,653,643,500,705,566,213,705,946,384,668,540,394,345,673,851,650,328,50,938,414,960,122,278,918,839,463,658,464,819,69,638,812,743,804,995,233,996,919,336,874,809,765,263,300,910,89,236,160,584,658,519,603,694,188,558,606,838,659,955,234,974,606,205,98,177,631,175,565,590,589,276,889,458,49,432,46,101,956,659,630,462,194,200,620,106,794,101,652,38,991,991,512,600,315,242,393,316,863,643,123,49,938,77,154,288,894,529,761,609,424,332,638,667,108,685,197,6,917,430", "37,828,879,733,471,859,529,819,54,324,442,421,257,815,160,625,423,16,795,468,878,678,113,381,640,30,913,388,405,592,430,37,830,804,685,305,903,692,352,706,641,873,643,818,275,755,493,1000,753,529,84,73,86,468,291,904,127,222,689,869,22,332,964,696,971,796,732,128,196,284,676,180,631,550,558,634,817,235,336,658,564,640,33,188,334,479,41,18,44,935,295,770,43,378,205,354,560,235,457,297,889,175,822,91,662,513,477,4,604,800,908,692,570,66,464,936,290,475,289,667,590,537,619,753,934,467,849,355,951,856,425,778,334,593,531,258,876,946,978,663,482,787,123,810,860,133,446,677,337,521,539,895,277,991,588,383,798,45,553,975,64,761,382,692,701,325,126,751,50,186,536,783,220,196,659,614,51,371,711,698,607,560,741,771,224,731,853,817,180,763,952,648,89,188,492,324,134,719,773,406,496,160,169,602,583,600,186,242,948,203,101,267,720,357,962,202,474,963,192,443,104,817,232,0,420,462,801,385,335,176,146,668,367,652,931,650,645,740,430,702,308,186,453,492,326,721,20,264,473,663,882,778,416,357,244,800,936,98,221,677,145,994,598,599,4,107,413,887,127,711,80,599,898,181,704,77,549,667,867,734,639,779,388,575,878,431,181,443,949,939,236,33,878,13,176,627,259,188,722,216,951,263,704,258,911,41,347,814,272,255,678,770,851,396,774,838,667,631,994,906,628,819,354,432,414,334,795,169,229,972,985,814,305,406,586,117,576,598,888,476,118,208,477,375,306,672,18,490,748,41,2,26,934,407,409,869,135,384,396,235,986,326,920,492,80,376,328,543,767,399,546,750,296,912,639,157,59,166,48,549,104,303,960,367,583,373,888,560,505,382,177,109,956,794,354,465,73,339,941,82,783,353,300,314,853,987,677,958,653,931,439,542,125,723,91,964,309,896,875,712,767,747,729,538,944,688,197,519,580,159,482,210,109,954,869,657,487,319,482,785,852,63,853,35,679,589,505,126,521,222,264,767,864,265,593,617,714,298,762,87,309,773,334,574,877,178,272,69,678,215,996,307,469,26,175,224,656,869,527,338,509,878,653,898,369,75,498,887,644,97,161,925,585,567,224,252,417,482,309,303,696,636,898,454,880,76,979,330,403,201,298,807,479,114,127,74,907,880,634,196,277,477,177,670,218,840,994,121,560,884,840,240,96,383,859,65,233,249,536,694,366,103,850,315,110,770,782,269,338,860,246,496,806,394,142,331,887,373,412,36,776,415,420,912,798,129,316,209,399,261,276,820,130,607,194,169,22,120,766,964,828,517,725,919,752,412,456,755,657,825,857,253,990,235,322,771,816,876,427,84,239,481,527,491,497,829,449,524,72,819,750,273,4,712,303,969,322,88,627,677,67,599,303,346,899,190,372,811,884,304,640,492,347,395,15,134,263,577,718,929,830,130,666,139,882,126,945,550,797,894,902,737,165,349,432,990,836,24,394,595,191,390,461,642,796,430,721,234,524,77,817,163,118,636,265,723,220,33,820,61,190,217,174,231,727,662,29,352,701,466,892,153,589,400,419,294,71,25,872,660,731,792,695,77,421,205,309,783,6,847,968,160,414,80,202,719,577,339,816,437,56,977,994,769,863,848,278,970,434,231,368,790,821,448,894,461,907,579,383,471,411,774,677,659,271,932,509,234,52,777,649,692,501,502,902,530,807,573,18,628,994,865,962,762,763,291,687,756,17,851,515,151,832,736,273,509,818,185,397,749,159,804,919,62,342,221,834,539,591,142,599,321,729,673,27,21,505,544,129,99,885,822,817,269,624,216,104,568,643,123,79,237,965,370,232,222,650,700,847,876,271,122,603,670,383,434,619,485,969,180,755,122,924,982,241,724,892,168,867,289,365,333,459,235,618,515,296,711,242,294,249,162,689,571,130,236,148,556,977,858,196,772,863,367,555,120,113,829,622,479,627,114,32,864,347,896,550,373,559,301,61,665,382,973,405,582,578,8,502,759,331,457,718,879,638,508,619,67,452,308,367,35,205,232,99,610,322,338,723,40,362,302,712,217,553,475,1000,450,373,372,385,460,410,14,810,881,828,555,587,249,725,205,305,759,114,44,522,989,783,322,691,720,427,93,309,43,118,145,142,180,131,413,326,879,853,559,419,35,958,259,474,889,728,997,308,439,488,93,814,189,438,585,631,605,564,659,261,53,392,984,350,86,601,489,193,198,334,455,42,888,7,359,284,832,80,404,813,52,101,627", "769,450,331,500,217,732,292,588,718,820,805,920,953,324,393,559,812,11,520,404,655,37,29,34,771,184,614,396,501,612,632,172,679,697,558,86,620,68,131,207,497,865,413,714,476,743,111,725,878,739,825,557,251,251,216,358,14,366,352,197,888,131,589,923,872,501,392,789,661,824,938,865,796,349,626,182,608,8,57,953,435,587,788,778,513,971,978,632,539,939,257,308,866,971,82,789,882,472,302,138,807,116,877,290,993,45,335,837,89,622,77,764,435,391,407,899,59,237,55,473,5,729,699,958,971,186,139,584,795,814,369,686,981,612,824,940,237,657,67,50,968,500,420,813,48,207,488,257,92,497,85,371,903,267,210,487,538,937,200,999,825,320,174,49,445,332,129,473,540,224,395,964,809,146,375,60,345,53,456,652,823,402,3,229,7,917,706,400,825,671,510,15,339,880,624,722,190,110,318,89,538,340,712,583,199,434,375,925,589,462,432,137,85,842,837,374,593,392,907,848,322,561,372,420,0,94,513,348,251,634,236,367,384,337,467,259,499,140,813,40,751,887,781,191,17,703,386,476,586,690,36,570,603,917,223,749,467,91,310,864,694,985,424,516,952,991,571,241,349,520,731,280,992,313,907,959,26,918,246,471,683,932,136,590,518,251,426,559,454,699,364,646,8,675,495,730,59,390,147,469,436,32,349,361,277,475,649,456,599,53,805,33,937,314,741,651,851,300,955,617,404,24,825,825,734,500,615,1,659,114,454,264,619,9,708,872,125,265,26,465,833,6,114,569,661,316,405,595,184,798,26,229,910,461,525,187,686,777,512,554,883,874,969,345,511,383,50,556,6,670,934,543,213,767,626,201,483,838,386,465,788,109,539,664,753,493,278,613,894,80,104,908,349,191,183,829,7,330,691,121,574,691,176,115,195,601,204,611,84,111,400,465,202,740,393,81,895,8,693,16,588,227,778,707,924,894,282,4,828,139,151,308,193,948,993,418,953,245,42,798,708,572,193,868,610,235,991,761,846,86,373,692,524,361,41,49,757,970,654,291,740,687,167,434,925,130,830,944,425,636,755,154,186,754,256,610,280,958,865,908,301,795,922,131,701,527,493,100,325,184,578,705,839,389,34,438,888,628,529,25,843,806,920,148,148,33,817,837,236,199,346,967,244,160,924,114,638,696,564,122,584,336,614,186,75,278,859,4,682,580,529,1000,335,125,782,225,871,610,319,359,361,976,255,715,229,529,961,11,495,409,164,830,320,781,168,635,655,781,109,550,481,351,370,971,383,579,271,278,549,930,438,477,99,314,69,376,715,295,861,665,251,811,493,532,260,63,508,585,120,982,696,653,769,274,689,165,99,289,382,846,339,787,356,931,487,453,119,936,65,79,418,362,321,660,598,773,143,665,743,979,779,2,759,852,747,602,898,451,341,868,801,610,17,108,815,640,158,478,684,604,343,541,622,754,267,338,191,835,257,445,714,527,348,214,792,141,636,768,570,472,361,652,290,483,809,308,254,235,448,623,121,655,30,842,790,690,847,118,259,452,928,166,732,555,831,518,364,18,138,317,997,616,61,456,247,125,946,406,252,415,368,328,407,289,746,294,323,713,88,734,884,186,306,204,829,643,228,181,289,125,265,755,867,233,697,381,580,489,621,987,109,581,516,406,96,149,497,314,433,776,165,986,549,291,386,676,307,533,390,337,864,175,88,354,533,865,653,155,510,398,851,337,336,911,650,420,174,715,55,452,454,128,134,520,394,86,26,698,765,585,303,687,969,786,109,759,138,97,760,43,100,80,289,997,111,179,499,229,273,841,65,549,374,567,247,859,800,390,16,707,112,908,400,698,312,170,973,592,396,879,149,929,386,114,656,771,551,957,811,744,478,404,220,669,734,391,836,107,565,995,258,427,594,818,215,903,891,361,278,469,44,307,106,249,635,583,879,883,995,824,304,908,804,440,960,674,552,345,965,859,842,777,452,798,381,999,344,503,274,278,130,448,109,514,589,904,738,387,322,761,523,810,503,943,623,836,245,908,777,210,980,528,615,284,775,837,466,722,171,925,354,834,741,193,432,100,287,265,954,564,240,331,193,667,458,592,605,232,468,837,506,420,819,602,930,754,115,295,455,825,188,477,158,808,428,591,153,117,61,377,952,190,151,886,985,815,708,207,65,482,673,830,126,521,898,227,322,223,324,835,512,997,669,865,288,19,358,763,247,305,807,64,948,640,424,174,740,666,607,502,129,617,883,682,987,755,845,532,20,883", "460,465,990,357,966,853,298,784,408,773,102,487,108,718,933,62,864,639,629,567,324,51,129,873,232,136,94,712,528,84,848,197,913,603,930,445,565,268,394,58,365,112,320,334,945,73,129,531,940,648,531,600,247,873,792,982,207,126,964,544,986,562,289,549,467,437,271,637,554,850,30,524,725,197,489,371,437,127,871,270,395,92,107,379,313,388,440,257,944,889,883,751,664,392,869,553,689,34,82,747,132,243,226,23,334,679,292,437,482,895,21,680,527,673,899,752,416,832,379,601,859,538,604,489,339,940,252,553,464,522,67,730,612,21,532,299,731,708,116,511,838,604,958,575,801,460,316,21,656,544,71,617,123,232,710,919,351,298,238,119,187,959,175,751,423,501,424,589,372,234,55,446,626,12,143,341,90,551,453,653,132,301,224,947,830,767,693,349,684,492,597,985,269,466,786,937,924,703,826,721,207,966,150,112,121,812,83,41,167,43,401,628,802,336,65,837,570,360,670,849,65,545,60,462,94,0,641,918,470,870,352,375,458,867,675,303,270,407,350,578,746,530,678,198,588,349,334,122,532,325,340,724,729,705,994,157,211,45,980,466,26,992,538,120,710,319,585,108,919,539,158,23,948,904,627,165,306,102,774,493,706,679,871,73,769,563,586,934,188,616,508,924,675,424,761,195,957,329,619,965,208,425,894,50,2,438,508,882,137,404,35,264,473,126,37,151,212,758,108,575,706,563,727,735,360,439,161,291,969,619,104,123,849,144,816,283,24,241,901,848,612,466,975,883,784,164,530,590,282,253,508,815,875,868,7,18,626,18,716,739,910,352,314,9,409,292,219,428,230,671,287,3,818,840,246,162,270,720,594,132,656,231,139,854,975,400,501,210,30,279,259,982,814,189,349,191,972,268,397,528,955,420,248,214,786,720,788,685,33,276,358,229,195,100,151,982,281,95,111,591,841,747,855,133,481,258,893,627,671,437,639,412,214,264,477,377,490,963,343,834,97,391,63,917,225,936,248,617,893,361,784,509,884,733,532,277,110,304,184,704,207,453,381,230,324,888,20,670,110,827,636,316,529,187,29,490,215,711,341,9,591,177,550,35,818,444,988,898,141,305,503,218,481,259,923,772,244,131,240,362,583,672,469,788,32,138,995,881,499,732,601,529,442,889,863,748,760,89,530,38,274,134,275,505,123,767,393,934,29,947,821,441,464,141,272,237,691,359,115,42,186,907,139,640,374,475,639,840,548,45,984,59,743,973,820,246,674,919,137,57,824,30,272,857,303,484,316,205,193,296,505,205,42,33,241,208,706,231,772,989,910,524,416,674,659,898,447,674,205,474,219,18,455,647,31,985,198,7,61,406,566,543,281,791,529,634,850,751,625,730,544,77,124,44,185,272,758,761,165,463,893,266,636,236,296,531,772,377,238,705,204,247,975,978,285,397,582,106,748,627,785,25,703,408,159,83,761,24,170,232,535,959,602,29,393,723,689,965,434,645,468,444,525,452,320,389,145,18,672,641,820,808,849,135,586,630,637,717,866,216,603,557,167,701,313,64,753,569,142,898,816,191,485,861,834,8,232,620,479,825,797,599,991,89,887,949,198,147,683,947,191,789,57,802,220,245,693,615,567,77,138,405,352,90,434,743,496,329,324,609,384,328,441,311,336,703,889,210,540,740,915,2,801,365,543,743,833,950,711,642,412,798,140,838,766,185,369,750,312,664,847,199,941,272,793,896,787,844,43,871,375,992,32,543,100,309,441,85,59,287,867,51,871,946,966,590,97,565,491,10,677,12,498,727,273,699,785,53,331,217,829,592,160,430,561,765,97,847,554,263,874,846,41,308,785,921,733,154,581,282,635,365,549,778,581,32,627,574,237,933,366,207,528,614,682,390,248,468,84,263,222,302,124,261,754,536,96,699,551,744,824,126,218,704,908,337,552,969,86,948,122,739,454,370,670,223,525,289,502,209,388,804,103,104,523,968,822,54,365,319,156,302,203,72,215,653,18,851,783,838,860,524,568,844,109,981,791,930,464,991,926,846,549,670,39,24,983,672,224,688,934,937,586,953,865,431,587,679,869,134,424,787,369,134,388,4,37,922,219,252,988,977,821,338,349,871,544,984,204,429,103,120,259,160,900,907,527,777,778,208,890,94,692,43,27,958,160,618,93,786,124,290,501,980,526,583,860,131,801,668,511,562,52,151,435,32,944,973,384,423,22,825,728,887,957,246,219,278,195,133,79,48,426,128,71,958,36,867,954,260", "252,411,887,200,557,816,569,99,135,395,764,354,750,333,371,193,837,957,133,675,242,808,382,417,766,955,80,211,377,80,334,561,478,107,793,870,614,496,547,506,168,499,278,678,447,551,89,400,763,126,411,240,492,266,673,867,241,166,229,58,405,450,842,992,374,67,513,171,267,180,357,498,472,597,876,280,354,193,386,29,760,868,663,804,649,273,685,859,93,228,402,423,404,16,16,144,94,691,460,64,114,419,230,34,74,937,896,82,989,74,203,952,727,810,443,682,829,812,16,329,493,852,359,7,672,799,912,277,817,745,475,972,994,852,354,170,60,415,210,293,807,638,787,641,557,444,804,387,446,864,875,961,906,590,597,637,184,935,346,174,339,274,146,834,253,143,187,908,622,532,101,456,801,697,38,899,859,187,20,511,484,224,629,837,704,219,609,621,429,980,123,530,10,606,400,286,824,981,483,187,504,636,373,981,5,525,646,604,40,797,24,925,878,644,55,830,383,750,733,402,378,138,78,801,513,641,0,624,250,997,676,415,49,673,123,168,613,760,17,579,965,139,670,312,777,985,380,105,898,268,695,627,520,794,724,209,523,92,111,415,140,434,990,152,167,593,990,351,790,956,650,703,712,31,528,640,424,273,946,871,22,402,611,299,452,990,168,489,156,160,970,952,83,431,578,65,137,846,121,357,419,663,277,80,209,57,927,827,665,447,152,760,341,926,460,536,712,761,873,998,757,844,232,716,744,352,60,81,944,712,91,313,44,404,585,365,51,647,363,157,295,761,690,939,959,595,8,70,4,27,147,215,879,797,210,823,746,811,182,171,572,670,940,382,297,881,56,50,478,96,559,224,99,443,193,161,406,910,631,415,520,41,459,56,855,658,130,998,373,882,52,768,292,64,15,762,130,61,767,451,256,961,472,57,853,501,659,829,215,498,109,713,705,73,489,537,824,996,523,360,422,432,734,458,149,909,677,983,380,430,858,271,122,258,907,555,606,218,300,218,267,270,917,878,834,734,550,792,125,158,253,645,76,532,210,479,206,356,954,730,583,383,951,743,803,600,517,833,475,949,4,990,718,861,922,570,347,881,178,439,878,83,518,421,143,784,184,349,149,423,957,990,971,715,994,346,314,326,31,20,420,475,767,224,113,892,286,173,134,277,413,920,197,337,268,259,102,287,815,529,658,509,513,237,169,114,677,695,331,183,991,606,226,787,876,608,901,634,598,162,744,946,220,772,367,44,253,666,761,858,915,770,665,683,240,557,727,491,875,512,147,639,228,676,294,774,454,675,595,709,722,570,714,220,206,875,409,133,468,381,132,507,406,966,38,332,233,939,601,328,947,164,240,80,20,383,161,407,407,3,70,647,194,9,278,923,965,584,715,847,948,802,850,826,452,794,88,144,91,461,808,518,291,25,170,348,476,177,516,298,622,400,530,806,917,353,183,546,325,342,644,220,753,338,474,136,798,860,509,251,931,551,178,417,811,53,701,978,289,71,695,992,476,889,445,156,255,388,578,290,497,438,175,858,343,442,700,757,782,306,681,444,710,20,14,369,466,273,335,393,722,578,88,892,608,198,756,545,149,694,911,767,951,276,387,861,780,536,83,17,893,118,280,206,726,470,96,716,203,347,676,86,785,745,231,181,540,536,762,468,784,972,232,991,501,999,857,399,757,31,132,198,90,694,322,778,992,91,547,839,10,165,956,762,808,716,878,73,333,263,9,523,870,158,738,255,101,552,39,506,186,903,779,825,537,11,333,640,651,312,297,333,459,624,293,452,321,143,21,612,609,701,639,368,998,425,400,544,962,150,486,344,546,283,922,225,811,245,692,554,190,191,666,907,538,805,939,378,26,95,670,40,771,541,542,899,502,580,594,731,190,819,997,78,189,270,879,987,92,419,825,267,577,755,669,709,319,800,52,74,794,131,326,99,157,514,969,697,55,554,356,622,717,471,37,21,882,174,603,198,890,352,598,980,462,112,300,19,915,782,809,435,260,738,653,953,496,486,692,109,950,252,87,19,372,46,878,851,38,149,959,8,438,705,286,21,604,144,175,183,666,69,913,319,587,867,373,77,200,389,415,678,175,680,331,984,828,671,516,242,199,702,625,411,188,159,794,332,972,961,274,120,697,594,910,144,260,91,323,413,858,851,811,589,653,289,794,903,80,879,16,737,553,225,644,382,860,519,515,486,226,392,430,264,660,841,156,75,581,583,424,555,679,659,128,704,156,987,186,3,607,262,487,493,718,108,588,198,126,956", "869,75,921,713,263,481,270,727,697,676,89,240,326,44,856,825,582,36,864,711,660,828,424,500,649,632,148,23,257,683,163,663,410,962,500,917,43,947,387,606,648,835,208,294,702,300,920,954,989,785,204,944,815,671,503,437,775,515,172,305,332,484,359,827,37,662,777,521,621,73,832,666,30,817,728,901,800,398,141,316,173,858,805,391,510,238,804,595,832,991,301,196,219,79,987,42,445,191,431,268,178,756,511,826,840,859,765,551,20,335,324,273,757,137,408,502,119,266,81,94,328,14,878,819,768,234,645,95,345,835,739,719,292,22,818,889,552,982,791,19,449,404,85,1000,857,551,822,322,469,572,490,440,278,608,920,160,445,221,391,306,710,406,876,750,248,546,285,719,797,427,776,283,414,178,315,518,369,658,253,150,656,831,65,303,437,874,649,123,423,399,188,759,327,138,829,913,894,722,393,863,494,592,106,823,126,773,469,462,906,320,108,487,665,807,101,796,136,773,520,411,243,248,417,385,348,918,624,0,731,129,493,586,38,903,682,357,654,277,575,659,932,231,267,26,877,83,241,137,305,999,156,407,316,53,116,898,166,608,664,592,900,95,875,847,174,983,833,485,308,947,500,748,625,135,498,832,115,30,143,227,856,232,648,817,849,796,229,247,52,602,750,380,677,467,650,708,731,728,306,230,863,237,984,516,820,281,480,608,407,453,165,601,295,748,479,812,825,441,874,129,356,990,21,99,956,404,648,579,352,432,722,464,66,316,504,823,2,958,794,681,586,607,325,35,116,21,336,361,539,748,893,887,688,863,690,296,453,771,433,71,855,73,86,680,12,551,283,590,678,222,492,940,476,265,496,772,530,364,505,335,347,671,624,175,773,818,434,354,284,939,629,911,313,376,824,414,702,798,801,197,315,481,786,148,842,863,917,805,859,124,335,811,436,519,801,98,108,229,695,153,842,701,492,891,788,48,846,300,607,375,25,821,757,195,229,889,710,882,866,263,570,75,783,98,640,491,598,199,585,301,152,883,521,900,721,340,989,693,962,2,640,384,349,956,913,773,937,983,979,255,700,291,831,738,869,900,424,302,379,847,317,296,729,369,854,825,242,810,615,589,349,313,63,198,509,34,310,890,344,813,19,13,27,583,921,392,218,533,606,379,28,66,510,117,227,688,579,179,700,761,105,147,668,22,162,411,613,678,954,475,878,375,886,229,413,255,85,535,430,798,421,984,65,339,620,597,695,441,672,525,785,390,919,732,557,515,554,731,545,189,696,273,694,151,440,263,208,490,609,971,204,895,699,709,56,645,813,63,844,493,965,908,642,89,651,846,241,219,59,501,428,946,384,354,623,839,485,518,160,457,861,592,11,499,907,298,24,707,699,780,888,71,166,182,706,503,690,690,770,830,214,303,970,720,506,918,832,123,791,321,645,4,19,404,841,318,351,361,707,124,528,230,319,854,442,629,766,364,573,921,696,488,38,833,436,503,504,130,730,181,379,891,995,906,728,993,398,275,12,484,934,465,683,891,737,691,526,997,720,420,417,828,292,48,218,933,126,355,748,642,322,720,316,209,701,650,887,119,730,92,577,257,682,633,309,545,273,214,75,132,57,351,829,118,837,307,998,421,417,523,772,898,494,371,768,758,739,831,367,722,852,157,14,608,964,741,576,132,959,537,21,544,388,890,877,49,375,788,406,502,251,918,231,693,248,551,398,448,948,655,153,739,930,318,507,142,18,376,233,711,51,395,2,477,8,320,312,368,938,50,12,987,438,241,308,487,11,400,583,546,53,515,810,100,167,932,873,861,338,374,506,253,179,451,356,722,181,637,110,192,696,162,104,430,111,993,265,987,119,6,192,100,706,238,214,436,879,400,754,526,104,758,24,236,117,104,119,787,525,150,676,332,885,710,613,938,574,894,326,219,722,996,426,169,889,253,931,490,746,10,857,660,630,652,842,395,445,236,364,156,536,715,846,873,24,770,797,414,595,985,786,809,262,426,861,583,97,207,915,854,992,483,990,788,285,196,3,432,194,975,501,721,341,490,607,593,395,290,978,400,328,493,860,100,400,214,679,67,429,63,817,19,31,558,712,601,347,261,83,865,213,346,827,230,686,804,252,601,297,53,727,567,570,48,868,998,300,98,41,836,340,838,853,484,81,353,854,330,784,746,382,101,931,434,963,509,589,250,548,496,397,527,834,8,711,577,519,13,767,434,112,368,960,504,605,740,834,392,495,674,124,746,239,724,524,144,138,506,402,882", "700,199,368,503,433,776,942,574,926,435,91,58,454,996,909,813,44,326,237,464,72,19,858,482,596,996,629,187,952,745,262,26,878,218,269,75,408,373,885,177,778,491,20,320,53,755,917,365,427,787,406,84,802,650,385,681,982,403,579,79,989,834,60,670,760,968,275,763,570,962,760,425,833,738,132,103,812,154,963,449,307,5,983,102,742,84,862,600,740,835,204,881,862,194,318,657,42,260,934,450,623,706,876,701,902,178,122,724,378,456,599,276,507,920,79,100,49,500,89,674,467,531,370,31,104,667,449,738,25,394,794,258,630,562,191,287,832,131,902,762,4,163,593,786,671,722,133,446,266,235,969,149,193,152,5,384,43,706,554,897,919,353,602,611,914,429,102,188,296,901,98,960,195,154,363,992,399,666,361,137,378,196,220,229,609,571,853,85,132,668,879,231,468,835,571,932,528,482,731,705,271,28,636,956,736,450,170,461,51,436,202,627,20,985,374,511,727,194,891,348,688,37,703,335,251,470,250,731,0,210,33,138,699,281,980,750,801,782,87,452,700,407,619,947,307,662,90,46,694,644,474,149,963,336,195,639,80,737,432,364,267,664,513,406,825,202,151,881,593,530,712,485,328,58,245,952,614,692,467,650,840,666,986,592,780,186,417,287,979,786,884,776,755,308,206,961,947,102,519,796,741,739,743,653,791,32,343,128,215,502,950,960,325,61,285,838,28,193,508,583,977,697,486,838,854,114,25,228,176,96,743,822,597,389,49,853,940,77,26,96,580,594,282,529,222,306,478,260,721,313,884,230,415,316,580,646,781,605,196,132,268,180,668,521,111,174,501,994,118,552,906,932,474,457,852,7,555,193,984,364,231,856,577,218,280,805,882,299,730,380,975,340,915,71,395,489,889,818,628,342,715,402,759,646,539,640,891,287,41,372,361,968,94,226,816,217,937,739,643,660,401,714,162,290,660,911,404,512,456,585,285,640,35,452,994,11,960,613,396,467,86,55,44,295,43,372,633,894,50,167,565,27,376,387,149,285,522,285,490,792,303,431,569,78,846,731,557,980,203,917,379,568,385,388,330,989,831,918,847,901,83,191,109,839,699,796,493,937,100,767,604,577,866,628,813,555,963,422,335,152,378,458,17,959,756,760,947,774,429,720,457,642,779,993,877,440,528,568,771,342,844,588,818,151,455,961,833,538,364,108,776,689,25,244,639,842,90,676,321,964,740,496,766,931,332,858,151,632,583,885,784,871,223,968,616,632,417,902,929,41,551,188,569,125,286,605,563,101,291,707,19,83,101,910,165,224,302,597,495,993,388,266,780,223,543,4,223,233,316,255,885,118,120,632,549,797,757,184,268,971,232,67,773,951,72,979,765,94,796,773,979,582,960,680,254,349,497,166,574,797,393,697,175,72,949,538,332,675,494,976,927,508,130,867,250,481,869,371,889,386,700,758,216,307,234,230,827,970,485,695,808,16,665,761,890,36,265,985,308,392,54,683,9,702,592,615,936,850,835,22,213,464,392,400,949,722,866,329,760,368,559,860,63,884,902,153,288,713,685,884,724,434,157,565,497,909,445,361,802,634,241,653,921,115,219,876,481,706,222,711,497,550,265,782,992,725,623,594,252,252,65,993,251,125,813,71,973,360,226,772,685,124,840,259,516,397,892,978,738,407,209,124,993,135,126,651,810,112,729,855,385,870,766,695,100,443,547,920,259,739,394,558,149,940,667,925,470,199,756,217,834,591,830,475,499,130,440,222,597,408,741,501,366,342,668,862,598,64,108,409,886,151,715,363,330,601,747,394,132,158,876,163,883,606,298,597,171,658,289,701,555,344,433,207,469,294,156,639,108,924,372,490,13,427,394,376,300,411,556,535,608,941,973,756,835,377,869,460,170,730,260,987,336,346,293,945,62,290,961,285,238,526,540,860,686,198,492,969,452,763,422,837,727,306,86,265,378,703,709,443,125,491,91,710,406,831,183,546,91,52,211,377,362,727,685,603,988,815,167,511,426,490,969,92,506,67,480,995,946,431,713,722,700,285,559,637,182,670,874,109,581,741,210,511,809,957,315,998,107,804,42,539,947,87,582,370,509,908,789,947,743,562,772,426,507,32,974,862,768,838,751,902,797,64,6,528,954,716,299,494,841,897,192,868,164,339,711,311,317,974,112,676,330,42,629,236,33,404,885,415,372,794,295,517,405,967,421,876,147,865,88,867,696,369,12,681,261,269,94,917,313,94,359,553,58,828,978,817,141,747", "182,145,294,588,940,586,671,839,581,637,847,859,652,809,844,83,641,603,731,42,119,424,327,831,519,141,93,582,887,654,156,196,313,140,715,430,616,907,885,501,637,314,165,638,927,858,515,585,656,483,819,570,825,348,205,764,796,795,894,289,912,318,980,756,197,482,501,165,924,152,4,572,700,778,539,140,209,254,131,458,762,613,4,351,368,972,682,678,933,688,17,810,233,246,787,121,429,362,528,161,246,17,716,804,507,466,569,569,715,952,899,108,109,590,506,21,734,465,459,802,596,489,406,836,388,947,856,828,952,416,330,10,321,862,423,479,564,271,636,588,886,171,829,299,804,645,303,753,657,251,81,838,759,171,300,857,377,484,471,333,554,772,426,506,284,79,891,79,306,747,926,615,272,681,251,625,739,953,442,527,31,57,203,161,489,156,480,296,638,410,773,428,766,155,387,782,251,965,518,122,67,410,305,218,792,75,505,811,134,575,84,725,260,273,463,866,19,439,463,806,959,681,400,176,634,870,997,129,210,0,381,797,620,202,74,840,171,743,138,427,545,660,660,148,885,966,433,768,902,975,823,801,866,305,376,866,642,973,39,603,510,748,352,691,689,90,70,240,817,442,293,526,553,451,340,729,932,723,112,311,780,871,523,924,603,847,274,883,92,932,715,909,863,642,692,276,39,42,761,180,241,793,836,628,262,390,16,89,916,173,1000,786,5,898,538,27,1,818,660,785,639,99,711,601,694,631,717,234,289,275,296,647,26,624,430,999,145,591,794,575,73,631,559,999,468,640,570,495,608,999,754,274,936,950,370,901,140,257,599,15,969,302,468,19,833,276,4,819,678,719,94,363,357,138,998,180,269,375,707,350,9,304,671,647,599,239,693,851,428,758,478,388,468,27,664,45,978,685,951,587,212,295,730,572,532,291,779,848,880,897,828,190,392,269,778,104,563,89,158,763,648,64,742,917,694,120,434,435,210,531,938,86,767,814,473,89,677,585,253,220,530,637,276,884,541,208,13,145,895,434,478,161,135,397,399,328,236,81,485,225,57,325,887,228,935,578,815,122,961,322,577,201,550,162,576,774,139,849,642,581,734,808,618,311,912,580,224,491,835,713,521,467,450,249,727,724,754,607,246,860,246,439,177,868,296,224,513,364,217,784,149,713,386,231,82,480,178,792,314,122,722,230,108,891,267,662,352,600,163,972,768,639,419,386,725,324,998,491,740,513,538,445,322,897,791,335,568,816,306,931,69,463,1000,308,916,947,930,847,216,152,405,57,594,882,645,948,484,313,449,566,394,315,319,416,760,226,402,98,300,97,629,908,211,688,137,961,289,879,427,652,432,663,466,964,191,640,569,622,821,833,2,66,446,816,905,97,825,164,679,714,814,869,225,726,783,686,271,269,181,308,511,369,581,888,94,195,320,784,94,969,370,393,621,5,144,403,510,588,708,187,629,360,304,348,147,750,153,257,292,648,531,129,433,565,842,146,970,428,110,562,417,106,369,246,439,985,234,370,292,675,813,83,545,912,737,472,963,461,121,732,226,115,665,250,780,571,840,689,230,215,47,216,994,442,396,568,559,874,222,209,635,437,317,326,959,864,471,81,870,184,742,413,579,119,518,275,273,250,933,571,955,622,801,347,54,487,506,23,598,172,83,890,404,154,986,537,182,283,968,615,776,886,479,545,357,636,840,54,827,256,955,977,146,548,439,332,717,818,303,967,499,718,433,987,438,648,736,659,324,30,962,783,459,898,501,418,36,636,303,69,877,273,734,13,612,622,184,415,71,354,20,488,253,863,807,65,244,523,220,726,287,587,889,871,552,492,614,376,950,833,475,306,970,429,650,13,16,66,204,657,962,400,62,383,237,755,481,42,583,313,177,913,975,916,790,830,854,841,223,736,933,633,140,476,10,835,368,793,309,285,121,36,114,837,520,160,834,641,743,581,575,448,912,46,173,503,672,7,901,506,338,932,395,265,499,895,868,892,57,214,824,623,740,479,706,712,653,827,503,930,13,899,272,417,202,728,963,202,616,522,462,444,396,854,850,296,802,744,495,647,543,59,901,165,669,914,571,373,104,989,202,22,846,821,454,714,524,275,682,393,230,218,743,708,238,189,176,998,461,940,126,142,899,904,547,730,849,472,479,738,247,106,204,759,714,476,203,248,928,331,434,867,622,216,212,905,765,857,918,985,929,497,622,345,610,357,602,873,74,389,708,534,7,686,739,4,615,401,593,661,717,833,601,207,399,76,874,813,573,861", "507,705,743,513,597,175,785,948,527,505,808,61,382,145,423,955,812,107,806,905,418,178,110,537,26,434,72,774,908,253,146,911,532,59,327,796,60,826,976,176,53,629,356,901,442,909,346,107,660,607,214,871,88,21,185,299,548,319,756,223,80,63,671,439,114,479,852,52,843,783,245,846,988,711,652,819,876,434,794,516,524,934,991,737,337,358,739,274,483,679,157,394,988,214,671,69,199,637,877,549,447,859,641,912,462,270,423,553,138,94,860,697,531,404,739,775,96,530,395,972,815,518,211,642,179,154,750,322,894,986,627,893,656,64,667,418,121,75,377,305,932,652,336,774,603,181,515,727,798,808,875,84,834,528,809,182,542,886,895,311,898,464,892,889,891,280,129,179,544,138,23,507,993,937,182,195,477,167,470,288,848,686,756,440,221,595,786,213,404,429,397,341,409,179,267,36,637,113,137,66,608,150,94,122,413,76,444,948,600,355,452,414,718,663,355,339,602,579,479,950,947,836,789,146,236,352,676,493,33,381,0,139,23,833,745,359,455,482,615,745,849,766,486,237,399,786,956,528,637,660,914,318,397,204,711,576,658,845,215,634,839,285,615,142,210,504,963,140,191,432,299,21,923,74,701,711,796,40,826,775,27,991,22,886,268,817,674,89,183,166,566,176,1,140,798,320,159,238,464,248,734,47,72,805,594,708,447,644,959,688,294,968,204,950,685,792,875,46,415,470,823,947,742,778,108,716,153,66,143,563,366,996,227,655,57,371,926,703,850,279,202,750,609,273,812,569,734,394,905,676,71,40,423,73,563,176,538,926,400,414,953,980,390,60,280,841,103,939,657,751,399,139,618,932,438,137,232,821,876,931,887,4,362,451,225,529,771,665,438,406,759,94,72,681,393,771,810,112,796,390,586,206,653,436,984,273,873,334,889,611,865,626,411,579,795,296,860,456,222,170,961,801,37,961,889,989,118,33,303,111,225,437,722,755,381,190,32,744,976,561,64,721,939,774,408,174,32,149,962,341,340,627,579,183,894,706,10,7,8,110,416,881,237,627,257,981,852,911,699,629,844,336,516,935,510,108,73,984,733,81,498,268,473,508,882,253,794,201,724,195,497,772,418,33,284,121,858,728,891,830,921,473,27,287,898,758,161,493,587,4,638,799,741,364,350,154,766,97,806,914,685,777,452,559,370,988,57,784,712,8,339,534,101,168,214,717,149,155,21,857,510,109,937,241,297,551,866,17,350,759,973,131,685,223,712,334,980,327,112,420,639,613,55,452,53,510,270,966,152,432,287,528,810,783,456,943,194,628,656,853,33,998,127,667,65,554,26,135,208,940,614,178,463,385,497,282,764,87,304,84,203,936,869,209,654,302,578,602,349,952,968,314,764,882,233,561,231,751,711,859,329,954,545,904,596,869,29,77,989,705,164,371,405,471,117,337,598,29,893,910,34,695,521,260,315,887,873,245,157,884,686,480,5,286,525,453,556,877,868,876,944,163,390,359,989,684,333,872,785,119,442,195,63,533,342,924,285,822,527,56,253,641,978,938,410,623,325,785,869,829,689,66,219,234,243,817,38,345,853,79,55,36,575,87,267,7,389,707,507,545,684,14,779,223,851,50,172,416,31,291,59,712,175,2,895,983,952,176,37,401,190,540,724,378,940,632,759,389,848,173,948,370,900,614,685,646,654,305,884,472,717,833,325,91,463,568,6,159,904,377,262,365,141,93,781,167,639,258,256,318,901,51,789,830,977,353,348,384,867,890,416,681,485,468,931,543,757,252,930,871,93,43,618,879,486,677,227,261,404,978,84,28,79,963,691,816,299,971,81,74,663,446,383,970,744,536,75,381,940,80,36,811,811,176,500,383,893,872,481,25,629,22,347,931,991,392,395,153,430,477,994,667,348,679,491,810,934,243,771,617,50,758,310,55,848,935,932,632,812,680,926,327,612,22,858,378,135,562,174,412,421,599,834,734,551,976,277,364,834,886,429,4,955,797,111,355,814,97,147,12,905,351,758,670,526,829,218,629,923,594,321,146,130,795,120,637,583,755,542,896,2,500,765,851,71,280,776,634,174,619,716,789,153,785,683,761,829,940,832,572,912,835,696,718,523,495,335,815,485,455,811,528,983,29,164,689,547,517,678,311,251,736,859,952,223,757,34,357,546,179,127,790,540,668,329,734,170,637,110,647,978,845,831,451,806,18,839,922,6,113,358,827,398,474,277,435,673,617,524,549,112,932,657,349,946,237,913,378,919,452", "389,227,78,833,706,168,569,234,309,729,110,174,618,441,998,814,895,428,973,689,212,638,912,226,948,292,289,730,769,855,764,121,132,109,10,204,201,270,694,421,884,246,221,430,252,418,711,853,44,22,236,137,447,180,491,248,148,307,763,576,274,245,881,203,343,285,93,556,478,449,459,78,665,814,579,318,303,672,668,274,701,121,908,996,948,310,61,570,501,345,369,571,548,256,572,851,317,43,306,898,572,706,444,353,579,378,398,820,695,797,775,94,439,747,898,530,367,447,937,314,274,635,287,499,155,400,801,977,295,685,49,417,861,276,460,909,274,995,730,889,457,639,822,400,61,920,646,249,788,928,731,570,243,39,265,985,266,761,843,261,777,574,385,903,837,592,782,827,62,897,64,463,968,261,364,514,887,53,110,479,43,511,260,665,120,134,945,788,550,874,310,457,713,372,836,969,171,923,377,470,26,580,11,450,671,885,247,373,78,414,819,218,970,954,370,735,256,427,200,199,365,496,454,668,367,375,415,586,138,797,139,0,441,962,243,585,134,265,319,745,730,239,493,933,711,963,92,854,401,982,71,711,422,42,887,885,392,570,806,293,763,573,639,874,975,16,753,971,141,149,585,291,59,514,698,666,897,806,657,309,552,94,13,547,155,614,150,378,316,818,830,991,283,810,628,884,576,849,705,417,756,721,836,149,431,795,489,348,818,598,175,280,709,353,776,491,168,602,348,783,488,635,259,872,704,260,25,976,400,75,559,855,915,731,775,201,893,385,105,143,485,699,266,716,476,738,457,700,898,171,212,551,83,65,153,86,67,244,540,457,541,103,307,864,533,425,597,411,995,615,908,236,867,176,355,877,645,564,42,436,376,671,126,532,635,590,560,663,157,749,838,219,752,985,9,567,515,260,31,308,988,410,335,933,91,204,615,372,783,180,833,458,679,35,21,222,472,916,216,979,859,32,715,122,77,781,520,188,124,485,550,85,88,441,484,901,57,417,854,359,175,958,861,341,480,965,541,207,350,559,335,142,342,753,657,906,350,881,109,167,873,308,257,152,132,967,771,613,817,959,106,170,551,10,54,582,622,455,784,264,632,3,390,680,414,473,84,390,560,227,401,29,661,540,867,188,65,391,724,303,677,913,315,273,502,99,585,748,855,10,716,63,187,448,808,123,643,505,399,104,737,326,102,134,323,84,718,815,550,549,821,676,16,263,794,599,150,504,859,465,990,867,498,109,990,736,607,617,168,409,512,999,154,965,793,792,495,181,687,637,49,174,923,998,60,221,139,226,836,964,254,766,77,182,546,323,976,405,657,127,890,711,173,159,8,741,580,676,812,856,645,856,795,377,763,241,199,209,763,572,89,15,491,773,969,691,626,468,878,698,488,322,637,497,573,932,363,497,38,796,427,858,767,88,870,668,347,417,267,840,534,972,956,985,913,813,715,69,321,817,636,246,414,160,175,865,513,114,289,762,654,409,856,671,756,955,251,457,832,123,788,36,536,479,917,841,838,21,760,952,938,302,951,756,253,537,155,121,716,22,891,535,179,636,434,155,481,93,864,274,183,724,624,588,789,879,287,231,437,214,452,611,726,452,144,996,777,87,28,558,961,765,760,605,91,655,234,438,44,620,224,478,814,112,161,720,584,805,24,187,891,285,397,94,85,616,452,145,836,911,18,935,795,882,639,507,988,40,638,58,208,176,159,636,366,275,772,716,73,903,199,986,812,289,746,955,275,272,900,883,863,116,737,530,255,334,360,267,278,886,37,855,252,890,201,63,768,827,254,939,875,819,662,139,522,11,119,15,986,593,399,978,729,297,286,616,495,175,136,188,170,121,41,692,400,697,539,599,832,688,562,491,385,601,867,993,628,889,646,202,751,28,281,93,122,747,825,319,6,299,784,684,770,776,535,498,696,37,405,828,60,936,906,807,405,415,533,5,622,279,692,884,482,779,535,369,985,512,186,667,428,877,268,657,374,56,725,76,494,470,586,968,151,819,588,859,565,627,955,769,467,349,960,316,671,845,805,955,550,626,332,976,765,803,801,372,938,7,555,253,299,103,473,375,756,132,517,651,660,225,511,418,476,496,331,675,803,940,658,773,929,239,64,790,22,61,720,999,823,730,26,919,742,504,661,265,471,807,718,655,789,299,774,691,47,167,859,459,260,519,372,411,734,367,176,501,953,740,552,751,629,380,970,311,97,749,852,541,250,135,394,173,710,900,518,937,39,167,242,760,92,865,205,325,348,369,810,542,549,255", "263,66,415,440,38,591,805,389,884,232,311,385,136,106,301,429,853,845,478,580,132,438,592,159,255,69,694,916,206,427,631,768,142,473,649,165,510,771,59,539,157,74,339,331,681,729,552,92,230,896,569,840,726,635,535,57,56,39,25,572,441,745,330,312,404,954,32,847,413,532,958,644,537,29,783,739,924,209,561,776,331,228,176,942,576,413,842,331,316,124,162,495,200,217,286,952,741,117,748,643,867,473,375,999,396,262,357,359,283,94,408,925,857,6,27,681,301,919,250,976,265,179,661,768,437,891,356,552,811,753,173,136,284,824,147,549,99,976,744,158,760,105,142,989,445,906,512,43,922,41,246,706,136,442,674,563,489,931,41,923,868,394,4,142,810,819,318,398,920,730,704,157,226,296,835,887,881,984,464,367,42,436,688,755,24,284,625,811,237,426,815,10,447,348,837,528,154,269,792,775,895,40,478,126,576,857,587,330,404,736,134,303,205,56,303,19,601,587,111,914,398,198,930,367,384,458,49,38,699,620,23,441,0,842,620,236,927,994,102,53,801,579,238,433,344,854,7,429,891,736,841,996,330,461,579,999,902,854,996,71,464,599,289,178,93,502,300,956,8,153,320,451,968,609,623,875,637,826,149,317,598,30,794,861,176,607,29,280,739,745,710,169,598,216,513,245,848,839,454,142,41,673,76,525,246,851,602,510,542,458,915,847,692,418,968,234,422,284,483,650,573,522,249,315,668,575,587,696,295,833,684,634,393,825,749,512,98,995,724,596,504,928,489,779,685,291,304,314,587,716,555,675,359,153,890,858,225,221,925,277,238,148,178,580,244,695,212,789,763,334,913,243,120,399,71,21,248,74,752,432,662,533,311,3,845,963,978,109,344,631,700,688,149,592,837,796,574,611,145,885,124,945,148,625,894,481,162,819,796,619,858,868,347,597,84,64,225,444,179,898,25,115,19,123,583,197,854,52,416,95,432,574,987,21,322,646,863,870,312,351,558,71,816,374,343,995,379,29,23,352,740,478,839,105,943,569,259,175,104,917,122,655,195,266,54,412,152,449,19,897,32,98,891,939,406,851,308,222,288,735,419,113,902,385,295,491,759,178,877,648,449,558,801,783,575,497,729,505,338,934,803,381,902,349,54,819,134,339,100,263,909,695,613,697,494,653,436,317,229,490,518,881,640,289,21,402,302,111,268,256,456,483,226,13,385,3,66,850,970,426,192,638,762,21,446,785,568,554,359,399,929,319,47,404,272,97,582,433,622,6,122,364,950,61,971,108,985,258,760,536,263,113,822,501,923,581,19,815,415,999,510,272,375,140,769,4,844,630,967,522,712,244,63,200,134,628,880,541,507,885,83,282,197,239,625,173,727,414,604,925,610,803,842,132,666,387,347,599,831,627,164,91,145,642,173,917,527,612,314,439,13,592,221,782,547,406,447,339,673,611,727,296,47,763,199,590,256,949,583,123,703,507,804,133,994,684,157,871,568,537,947,935,309,187,249,523,669,151,78,591,723,347,498,579,665,359,288,63,181,559,72,460,228,946,464,203,292,475,916,840,819,674,536,891,538,597,287,90,545,72,23,546,769,301,22,440,250,397,418,93,209,627,329,314,443,515,414,33,371,891,113,798,842,518,230,126,145,261,940,88,620,823,492,265,97,340,493,775,855,744,949,406,941,199,141,940,870,839,910,117,923,948,164,945,132,181,259,230,652,623,805,563,607,409,691,850,848,637,830,889,198,664,289,485,965,378,727,953,516,898,54,535,662,457,146,101,62,955,460,356,69,234,729,405,669,340,369,945,626,64,723,844,515,347,131,469,940,27,894,767,489,15,543,393,803,713,390,890,110,132,89,422,786,826,39,758,516,859,994,979,837,172,89,293,46,238,659,981,246,152,538,766,906,428,666,378,754,42,762,498,203,869,600,902,376,267,511,905,455,345,555,949,666,420,942,146,336,586,71,261,405,470,73,952,882,826,131,651,383,662,569,995,985,763,668,889,761,136,266,492,169,954,87,216,152,610,44,39,795,826,912,583,830,837,338,301,87,852,251,317,74,4,478,694,285,475,5,322,540,528,83,249,407,484,18,539,353,532,376,394,888,49,959,209,106,632,942,73,748,902,413,993,580,597,780,518,263,217,73,916,155,104,577,640,551,613,997,519,363,760,990,899,872,457,423,487,463,160,653,196,138,452,599,445,351,295,913,157,90,359,62,342,406,312,737,95,994,669,727,897,432,342,44,842,508,429,544,626,482,324", "88,620,23,189,330,206,232,326,887,145,977,73,870,40,201,679,725,444,166,213,783,332,511,489,430,542,813,623,239,841,153,930,96,528,618,767,826,292,898,636,618,315,812,852,213,676,85,395,999,764,638,465,566,40,191,538,453,261,18,944,727,884,882,566,101,587,652,362,971,977,371,441,77,204,133,676,184,580,651,258,796,664,411,872,329,70,23,147,10,205,905,930,18,89,994,316,608,692,623,245,78,764,603,905,107,784,266,947,964,900,858,184,530,618,174,130,872,776,282,437,326,941,521,368,784,664,761,285,662,828,780,841,131,313,165,424,309,569,700,886,194,818,256,577,141,716,786,699,942,547,598,4,903,657,347,307,281,32,591,296,699,385,918,225,467,675,493,330,823,129,624,694,784,179,187,275,728,724,571,810,300,511,461,114,355,897,461,105,761,826,395,629,493,842,742,803,358,471,996,94,539,109,191,143,596,901,424,225,570,249,588,894,307,970,598,739,504,592,886,187,783,333,798,652,337,867,673,903,281,202,833,962,842,0,582,496,953,101,350,965,573,778,43,179,634,594,142,578,640,496,837,687,945,837,6,307,544,113,784,138,145,548,588,33,854,858,42,893,47,256,417,495,282,936,172,523,40,286,165,920,896,957,208,744,443,663,759,541,175,424,399,387,650,766,235,370,406,662,576,690,860,361,406,282,880,48,747,164,982,500,154,760,85,780,216,369,631,518,861,4,512,288,752,53,447,360,629,19,341,238,105,829,666,348,630,841,909,717,815,328,406,923,732,315,580,64,144,891,195,179,854,642,213,507,151,340,675,660,36,369,713,560,40,606,825,639,441,954,569,173,173,395,868,453,805,561,399,990,640,14,296,40,337,250,860,639,768,511,779,862,52,508,908,711,377,309,828,70,76,583,190,210,339,740,329,15,329,458,385,204,788,594,476,861,683,659,671,639,784,42,253,707,109,87,527,458,215,898,74,433,169,75,497,156,461,934,297,299,554,180,531,129,823,23,426,109,242,713,995,603,456,947,308,859,678,954,657,835,949,599,825,870,586,787,619,246,915,722,848,424,47,33,219,601,56,97,227,24,861,319,851,810,624,947,502,824,858,27,411,40,872,209,519,756,204,714,439,198,477,896,364,352,896,145,106,971,61,40,223,463,45,377,883,332,424,346,573,296,92,626,143,900,339,742,617,816,999,584,547,492,992,749,213,129,199,744,852,508,544,972,645,73,335,528,834,620,439,632,213,341,941,473,972,289,827,78,698,213,862,300,836,104,566,826,512,910,302,18,948,131,398,200,511,651,750,948,60,944,392,909,794,996,16,121,577,282,300,343,137,703,449,322,687,324,596,666,930,135,372,835,302,909,886,926,771,514,814,679,150,137,275,576,203,435,18,180,200,894,138,611,45,840,853,326,212,323,368,188,619,448,677,222,714,73,370,606,365,76,178,907,486,743,250,433,254,862,517,804,280,238,592,417,895,380,234,758,543,335,398,220,414,997,463,887,880,356,628,125,72,185,720,142,130,717,761,716,8,25,396,675,526,745,184,389,659,554,700,379,433,706,292,263,274,534,659,767,717,506,848,227,292,100,138,543,826,225,348,710,993,639,833,231,734,935,698,266,851,193,575,608,612,923,88,278,663,591,255,245,295,350,72,729,483,591,11,588,913,569,86,267,589,3,874,354,16,663,100,624,354,607,290,861,796,871,736,89,403,926,24,827,479,317,406,366,844,22,116,896,90,99,811,908,806,438,142,665,944,73,383,824,987,650,538,33,599,89,506,40,849,612,70,419,316,951,328,385,555,575,813,718,474,810,561,118,341,622,70,985,182,388,713,319,402,990,307,298,412,382,974,249,670,276,404,37,337,899,539,139,427,180,956,596,302,680,874,324,546,937,537,238,164,830,758,586,78,706,750,114,341,828,880,859,98,462,916,928,112,790,173,897,171,280,440,319,454,69,17,897,118,57,726,324,231,240,295,300,677,864,315,34,102,426,168,726,242,42,566,654,278,74,704,391,613,515,516,848,955,339,275,815,946,366,687,675,837,491,336,568,819,623,852,517,644,754,793,670,121,947,684,807,364,181,719,520,130,897,578,700,388,773,498,76,726,851,847,573,4,727,446,618,999,526,459,719,913,450,570,612,541,709,773,778,628,3,693,253,812,216,135,514,292,448,664,951,4,138,628,394,808,819,822,740,49,370,160,471,129,11,616,680,686,581,847,389,757,333,737,695,134,402,228,549,990,188,744,855,669,914,438,627", "291,982,434,241,856,784,328,594,512,282,927,644,184,451,319,570,276,836,932,387,266,149,65,219,80,565,811,721,883,527,146,856,359,990,597,745,23,219,823,35,477,464,817,4,403,529,390,825,754,778,904,621,270,431,43,65,810,680,241,536,416,963,916,170,814,479,873,586,743,741,493,27,114,417,986,354,761,652,132,591,76,180,387,865,691,260,675,825,863,803,457,780,917,965,322,521,429,579,659,759,26,112,418,117,302,780,751,403,541,254,919,821,69,55,223,265,360,426,537,170,154,5,553,703,362,266,487,495,333,375,726,505,282,740,550,739,631,50,713,12,148,381,233,111,862,311,67,886,772,483,548,756,44,251,162,749,113,322,474,337,770,224,237,653,412,246,595,7,783,933,350,255,53,372,673,85,430,22,159,116,466,523,508,433,92,905,587,506,597,16,288,222,146,334,19,65,348,431,553,150,110,130,694,446,347,848,773,343,597,849,751,332,32,320,771,535,160,1,438,86,164,99,727,931,467,675,123,682,980,74,745,243,620,582,0,490,99,101,331,138,681,223,977,56,967,747,895,699,319,673,992,217,745,320,643,296,904,528,400,35,619,482,10,473,594,531,895,450,457,122,424,829,370,778,562,475,925,62,799,292,947,786,53,868,390,223,679,529,571,694,749,400,477,592,678,977,568,771,145,888,687,761,72,521,209,683,606,616,380,600,235,586,220,492,56,929,975,646,999,862,823,619,84,708,386,179,168,959,558,866,468,742,853,636,971,567,697,211,802,438,523,872,814,280,379,886,148,461,267,712,281,279,157,615,536,266,331,838,614,151,7,258,25,698,4,219,532,835,498,425,341,249,393,640,293,41,67,111,945,27,142,299,961,873,561,745,312,53,937,406,595,89,102,595,508,183,672,477,828,700,188,846,994,645,11,16,385,649,218,419,648,245,376,13,718,295,130,309,872,376,174,343,176,843,503,403,414,975,152,828,982,653,960,913,297,561,396,441,967,55,233,225,190,461,809,624,386,102,4,743,175,897,650,447,921,563,444,208,629,181,174,562,112,746,643,702,919,745,561,955,741,825,414,271,108,852,882,171,529,311,303,918,433,20,123,895,918,54,293,420,373,61,392,357,883,464,523,992,519,320,449,862,657,703,651,282,647,269,80,740,779,658,813,930,806,729,105,428,308,554,148,345,784,466,729,544,152,461,644,928,216,926,917,651,731,999,679,448,53,597,873,392,579,857,439,577,885,54,341,788,53,357,373,35,785,131,106,377,63,844,779,637,902,762,453,877,308,909,383,967,317,917,594,241,221,951,225,115,916,94,535,278,852,763,420,607,492,785,985,824,717,260,76,325,783,90,985,36,876,893,162,176,867,102,449,507,65,708,238,859,32,13,398,762,711,839,378,78,924,779,744,191,974,199,634,58,58,503,910,82,894,65,725,930,43,804,728,524,378,719,503,537,903,432,120,659,802,734,185,431,233,34,581,651,923,957,154,419,803,432,215,999,792,198,538,944,671,865,565,481,695,645,144,505,715,343,924,807,160,314,488,901,266,449,611,92,525,667,339,266,806,330,992,16,879,970,933,18,262,454,42,720,438,329,794,217,572,824,133,489,946,192,30,221,153,383,799,992,751,651,496,197,883,420,336,3,57,426,785,853,8,599,973,932,862,730,727,487,874,186,15,780,271,485,397,829,903,702,237,470,737,831,719,665,3,993,709,76,566,529,210,569,361,970,852,653,350,581,471,656,582,304,432,139,785,301,949,643,825,308,384,892,775,126,956,651,763,749,35,124,83,319,789,874,108,885,216,702,999,651,559,729,652,846,296,103,645,44,837,951,319,937,228,384,395,317,877,857,369,657,720,812,419,861,536,463,106,777,714,628,328,213,516,785,575,787,305,575,634,979,643,480,44,165,260,627,434,37,165,192,535,261,44,796,408,756,100,990,411,622,80,916,323,878,67,768,811,8,132,551,462,29,504,615,160,307,382,376,434,198,15,875,165,353,374,554,254,566,15,67,709,16,15,329,308,311,144,313,261,82,363,401,453,543,122,830,670,216,623,141,369,358,790,533,138,332,394,793,244,686,636,37,158,347,74,12,493,904,850,314,906,999,862,83,81,157,417,682,998,872,24,488,30,58,692,456,34,731,767,345,748,49,449,39,141,487,437,579,475,643,656,432,5,968,11,342,184,357,242,855,731,167,118,143,869,925,304,94,889,10,95,385,488,687,156,760,597,572,293,396,703,746,259,986,866,901,617,30,657,644", "885,33,618,10,790,533,315,396,715,353,702,570,920,445,39,439,463,578,15,684,505,13,77,211,960,883,150,784,974,573,554,379,410,515,410,839,832,935,39,968,555,540,525,493,245,840,375,543,928,574,55,171,493,813,370,441,361,175,621,478,7,714,688,848,223,312,314,730,688,678,978,482,794,189,527,400,837,314,193,789,623,782,890,422,238,861,722,627,380,81,115,499,787,124,30,276,305,729,539,946,866,580,419,644,259,766,568,715,331,523,688,782,961,118,751,541,347,323,242,631,360,217,463,185,384,717,411,815,819,991,654,397,384,314,41,701,912,938,726,701,80,459,135,875,6,440,260,33,596,575,958,557,485,404,443,863,583,559,452,429,547,292,649,486,600,943,217,597,895,419,265,514,325,522,148,704,548,856,255,678,259,22,319,752,482,787,743,682,520,471,799,303,361,930,697,649,366,390,424,919,738,181,262,439,235,435,267,105,577,669,922,460,75,934,990,843,744,803,926,343,617,652,451,650,259,303,168,357,750,840,359,585,236,496,490,0,588,141,853,283,718,955,864,663,996,32,304,459,857,235,304,416,552,18,685,840,138,448,919,482,778,976,973,674,11,755,927,328,967,97,283,70,43,851,106,637,812,980,523,66,708,425,994,544,831,961,681,473,378,563,256,584,191,92,171,148,513,379,508,689,401,785,545,885,940,262,943,107,804,725,639,643,801,130,729,6,62,982,31,518,697,249,741,968,332,516,555,674,968,671,596,985,692,797,973,57,303,996,50,864,604,866,425,386,575,22,66,84,187,346,492,39,33,784,727,130,112,55,362,855,207,319,742,182,99,384,762,632,331,682,410,532,502,213,861,519,738,92,911,62,67,798,970,38,592,776,724,478,78,302,251,192,500,663,830,580,199,654,545,169,309,750,955,168,541,790,982,678,747,239,205,696,972,337,216,127,966,318,494,429,79,308,27,280,57,189,893,628,688,889,154,482,145,630,513,605,779,13,697,69,381,200,905,83,386,383,989,689,87,881,701,631,813,210,805,775,306,123,759,900,27,442,655,466,438,111,534,582,916,508,790,452,331,654,926,981,611,9,403,997,451,171,370,889,945,745,713,439,741,700,718,643,786,179,739,369,70,87,230,628,121,93,465,469,962,880,115,153,670,999,359,211,733,447,421,347,521,866,549,53,662,506,386,846,585,779,175,21,406,934,356,981,338,303,779,104,635,891,157,987,612,989,274,965,833,507,244,512,489,341,568,762,929,904,49,548,978,14,237,831,882,190,362,703,744,630,685,866,894,234,478,65,165,584,269,444,565,124,270,327,925,124,388,105,695,30,4,536,673,685,713,742,589,69,254,628,470,538,913,16,939,38,18,789,947,982,778,225,47,462,671,748,922,572,728,426,45,17,511,615,259,615,440,528,268,129,681,947,79,651,998,441,662,687,769,495,115,378,51,576,523,679,554,552,953,931,276,176,85,475,237,558,813,187,145,868,721,686,555,767,808,4,621,577,390,240,120,337,411,507,148,256,398,817,664,855,29,110,652,395,1,155,209,439,638,584,646,768,989,534,442,277,972,797,749,432,935,99,986,683,664,354,206,935,301,1,784,89,325,647,613,119,752,736,225,205,326,207,892,20,943,737,1000,102,520,374,831,85,669,641,87,620,946,549,862,798,521,297,287,273,94,913,348,199,100,293,567,661,112,314,607,103,787,932,422,732,913,986,907,824,80,744,828,303,791,907,434,84,282,535,79,143,430,699,227,169,885,304,665,343,94,666,109,507,848,851,917,372,204,501,683,138,861,9,348,132,687,392,812,163,473,188,694,103,772,179,863,760,533,192,869,253,466,88,726,208,208,826,134,172,249,371,130,498,927,682,279,266,381,378,909,722,47,232,731,778,986,257,373,745,703,678,845,74,625,505,512,255,881,381,403,283,19,67,439,440,628,685,312,886,349,980,252,11,155,516,887,680,211,881,469,372,444,435,927,206,176,421,619,666,415,128,723,939,104,845,156,792,787,186,250,635,471,642,808,672,743,834,253,595,113,16,557,10,289,461,731,768,848,977,574,486,270,795,269,827,242,365,641,786,586,306,586,911,764,452,496,769,704,476,815,794,121,507,330,405,305,653,39,154,78,767,676,150,677,286,287,160,874,204,698,873,367,274,381,13,382,490,949,254,224,75,785,761,258,911,839,87,304,956,737,940,500,784,630,605,775,592,738,512,402,571,676,31,643,59,911,275,411,326,487,605,528,835,233,365,746,563,267,642", "106,317,22,210,509,541,966,467,381,322,260,154,194,450,14,716,212,744,569,704,225,665,645,732,514,925,393,787,383,818,860,87,593,108,785,513,710,158,786,200,641,832,439,743,344,799,715,949,751,188,349,559,77,807,628,803,631,420,344,594,783,688,807,911,505,983,247,447,317,842,948,751,938,280,895,162,258,887,652,36,285,163,828,116,511,622,34,218,798,262,70,216,918,57,444,55,13,755,666,252,946,456,333,524,646,460,893,317,214,390,578,257,900,725,584,586,101,38,988,501,675,150,363,6,502,631,178,987,76,153,688,918,904,156,994,780,23,863,303,326,675,421,412,890,897,383,50,916,637,558,879,785,888,864,575,355,658,305,196,460,975,295,401,49,446,368,690,400,149,741,659,393,337,643,753,749,125,916,497,634,953,268,641,146,177,800,771,857,648,567,322,186,332,313,18,489,432,932,613,266,57,844,6,891,635,947,457,441,750,633,159,319,597,290,794,479,185,966,147,770,630,252,474,645,499,270,613,654,801,171,455,134,927,953,99,588,0,652,314,888,488,69,750,445,988,902,322,126,581,453,244,236,546,645,430,549,904,574,938,866,745,156,605,444,878,246,543,117,860,654,787,337,635,156,391,918,228,307,9,85,47,101,13,848,318,602,710,510,440,282,280,317,516,370,567,519,521,664,442,784,422,712,330,685,120,415,599,338,781,153,469,332,868,133,355,301,563,805,113,265,72,99,220,560,837,516,684,5,733,189,762,171,738,856,626,900,488,940,14,731,352,554,8,453,584,168,199,429,116,759,777,79,559,902,610,747,831,344,689,325,267,299,519,907,172,532,142,720,443,575,867,331,221,827,296,96,756,261,662,797,564,772,216,668,319,343,220,738,19,841,375,881,208,557,817,394,946,128,695,433,838,393,318,916,935,33,608,25,594,680,984,133,101,260,216,385,715,863,836,303,530,748,531,408,498,327,718,89,443,971,735,277,139,458,785,193,925,155,646,798,474,805,886,731,580,607,308,517,879,545,821,884,358,149,683,363,105,709,284,667,761,375,361,327,740,115,265,857,195,12,578,461,4,870,373,192,637,35,201,157,279,224,888,469,91,476,937,81,744,519,140,682,674,46,907,995,307,296,277,617,666,815,389,240,818,275,125,271,771,145,412,562,634,688,283,925,863,87,651,939,93,51,375,589,58,257,231,403,99,422,594,500,378,391,297,956,43,971,237,55,204,573,220,223,595,677,576,27,449,937,72,680,68,955,374,636,643,462,581,727,326,495,723,225,261,295,789,841,429,301,863,889,600,233,856,187,129,547,78,49,660,233,782,388,979,315,627,912,908,527,504,314,630,233,171,577,867,580,188,870,549,253,260,132,976,404,703,141,275,812,335,647,333,329,630,206,36,188,244,704,641,277,986,300,481,192,755,423,147,373,42,583,989,787,677,907,862,967,673,504,384,549,279,294,178,16,462,208,3,362,143,966,185,992,596,685,451,393,770,3,108,683,379,593,508,803,834,590,690,548,18,902,829,288,258,487,894,251,663,950,801,751,99,323,38,473,320,63,732,272,621,88,817,906,132,288,324,239,885,767,146,56,590,89,397,790,955,94,707,810,836,657,640,2,299,376,403,298,473,418,163,600,713,319,357,805,134,730,818,327,209,720,219,343,367,870,707,903,580,585,5,289,737,197,744,768,785,596,796,511,635,651,192,720,494,126,394,150,854,550,475,462,159,547,422,509,401,457,600,792,595,152,764,864,409,170,475,39,470,217,131,114,721,906,691,667,690,227,720,900,367,594,548,936,935,713,386,12,563,184,616,884,234,543,808,814,558,655,692,407,70,580,505,314,148,190,303,902,673,511,94,907,105,513,808,389,820,249,374,182,74,622,390,791,258,340,320,527,702,410,523,465,728,99,604,161,293,356,27,430,689,88,473,664,443,451,756,300,648,468,25,87,374,932,545,883,419,761,40,841,464,314,17,760,145,998,899,597,791,719,119,463,863,480,62,888,88,386,196,756,454,318,400,456,539,910,80,83,1,661,587,453,718,821,779,483,347,134,76,303,771,114,200,513,310,185,156,319,853,975,874,999,131,142,241,356,561,822,821,46,604,956,259,456,76,244,538,65,313,504,569,192,947,856,582,581,159,704,513,848,829,167,264,695,158,596,845,880,153,875,110,200,211,753,705,962,199,49,642,621,49,631,697,528,903,736,880,425,205,370,420,981,582,973,723,613,77,412,166,171,918,160,474,446,787,977,392,644,914,181", "638,925,574,56,460,381,65,750,960,285,517,570,204,204,815,83,295,769,160,814,670,3,292,328,462,46,13,705,497,1,110,866,747,188,703,495,36,992,396,91,500,907,265,435,789,718,829,569,504,453,555,741,45,383,544,644,265,318,899,922,925,83,613,387,7,667,212,690,699,45,190,746,150,53,572,933,46,387,116,282,228,403,605,302,686,805,316,704,641,921,891,648,825,717,158,681,219,439,59,360,383,131,368,664,614,550,487,31,459,963,232,372,792,855,6,936,681,816,412,614,577,250,326,457,764,490,897,586,543,776,157,270,627,856,986,920,444,845,885,993,292,118,461,467,990,846,479,179,110,542,132,121,418,694,791,768,989,107,223,294,204,937,37,87,57,558,885,231,815,352,546,708,846,597,370,58,224,573,477,673,595,115,88,395,82,592,362,974,326,390,442,845,910,186,765,119,585,836,751,159,41,1,94,462,957,313,245,941,782,858,7,461,127,921,835,385,886,68,228,846,229,282,169,740,140,407,760,277,782,743,482,265,994,101,101,141,652,0,810,578,14,257,582,40,696,14,172,574,968,681,459,564,728,244,851,62,583,511,486,158,301,52,12,318,850,21,302,387,929,798,717,351,241,971,803,208,199,745,728,473,443,988,970,226,856,295,600,620,697,739,425,235,204,568,181,733,730,155,291,714,314,22,999,527,128,300,866,76,644,440,693,426,744,34,829,162,679,701,866,294,211,347,723,68,894,236,606,762,337,97,792,261,954,61,83,826,520,384,280,765,486,696,657,106,98,220,984,710,619,351,169,928,94,958,211,456,243,350,714,75,588,141,221,616,193,702,797,6,603,353,555,26,308,28,903,21,256,590,796,586,320,87,377,564,512,666,669,591,228,652,156,909,289,863,678,588,921,62,578,352,928,420,164,234,27,535,913,751,484,666,866,343,65,164,173,745,359,314,26,994,22,198,157,230,469,819,870,807,480,95,571,579,668,702,192,171,112,284,474,731,34,554,568,287,508,363,630,534,230,525,902,770,546,110,577,877,626,34,78,999,217,58,627,838,517,959,125,77,984,107,966,380,434,806,396,947,747,132,805,887,238,331,620,708,190,153,476,634,162,30,577,70,167,65,989,342,514,389,313,248,92,361,454,516,473,606,577,713,214,851,650,407,120,916,723,63,137,943,632,630,909,757,809,265,812,695,844,301,839,310,255,427,714,702,872,230,100,249,780,269,368,326,133,971,835,693,243,34,663,537,578,590,185,988,944,626,733,771,334,776,773,109,925,292,211,45,78,234,549,79,119,887,505,817,316,955,905,826,202,29,684,868,439,436,807,233,552,827,614,127,927,528,325,59,198,109,825,411,507,180,243,45,52,247,879,805,663,159,887,81,141,637,760,671,515,181,396,355,16,788,415,960,829,486,979,387,955,823,79,903,764,351,605,603,797,139,851,401,501,696,407,103,670,442,934,78,298,118,289,942,612,80,15,311,288,714,604,908,266,470,328,411,467,533,543,509,613,509,832,402,271,975,674,729,159,951,586,583,737,880,323,876,640,70,101,4,94,70,153,780,472,418,69,974,242,963,380,437,443,127,406,449,25,423,504,595,453,42,103,293,565,644,593,803,427,433,150,389,203,655,417,101,86,454,793,445,242,989,11,525,935,253,434,365,562,579,828,668,601,771,908,655,4,921,297,55,510,929,456,161,983,569,751,97,721,436,649,338,120,204,263,44,865,332,458,486,993,181,107,279,594,185,556,623,945,473,853,319,935,739,443,885,66,847,937,552,259,824,455,542,781,790,967,325,332,131,724,611,897,934,966,131,959,932,471,590,772,962,479,863,10,729,385,286,689,172,438,681,8,81,317,624,881,931,412,580,218,128,864,699,139,845,434,145,859,691,724,187,719,649,855,311,695,357,562,852,145,949,409,510,515,286,809,618,270,376,412,521,867,214,625,962,501,457,462,261,18,970,252,989,338,32,274,279,837,304,670,535,586,836,279,85,925,25,521,637,250,371,11,857,152,561,992,102,645,303,227,53,534,754,408,907,90,142,441,264,698,909,444,111,758,426,509,278,184,469,941,482,176,447,821,702,87,457,245,447,707,126,971,172,177,659,397,47,479,50,604,98,435,921,241,360,979,746,402,157,1000,767,385,294,757,275,146,474,747,931,436,562,531,429,242,25,514,204,96,983,314,687,240,459,79,64,819,825,674,844,42,547,183,553,576,500,312,47,224,495,797,72,592,228,623,991,389,840,1,491,227,454,816,823", "375,780,692,331,143,423,852,366,181,771,71,199,774,698,505,493,64,237,803,223,928,195,855,651,88,207,467,880,907,122,128,831,716,410,433,204,916,418,81,27,160,515,795,390,735,130,995,110,772,589,950,253,690,728,83,756,803,186,391,233,398,901,83,238,419,366,690,595,676,621,201,390,242,327,960,749,776,43,676,94,12,696,188,942,673,317,831,478,925,642,563,124,650,215,598,736,152,887,824,479,751,150,520,977,657,107,232,878,397,320,491,798,198,226,448,872,167,726,320,973,727,819,128,382,762,826,263,606,95,972,969,381,644,486,793,733,994,975,455,892,333,731,372,118,910,350,873,210,143,891,994,6,170,756,65,167,301,172,608,623,623,256,286,426,944,148,648,683,211,176,608,764,969,67,926,67,766,997,133,48,775,243,819,902,544,358,722,998,860,258,827,191,491,189,439,561,691,668,229,622,803,46,578,366,746,703,653,308,488,799,411,212,844,214,293,689,388,369,488,893,680,864,984,430,813,350,17,575,87,138,615,319,102,350,331,853,314,810,0,134,366,741,749,164,507,209,881,257,112,803,764,759,935,531,259,222,717,38,518,296,321,677,335,687,542,491,292,589,336,208,489,393,570,453,490,700,329,464,352,875,538,634,298,219,864,372,647,226,810,368,77,651,178,209,730,329,923,730,702,52,612,808,32,684,214,665,961,746,414,8,367,118,539,213,296,426,283,34,480,129,955,274,717,658,715,966,537,551,975,284,253,29,808,217,517,698,292,291,379,830,887,331,922,753,356,904,657,392,648,204,868,574,106,249,857,537,585,837,19,943,861,768,696,806,95,172,432,687,157,787,78,41,810,481,319,380,89,896,817,944,217,90,258,874,355,6,847,177,241,709,767,998,79,249,869,544,952,676,134,24,358,647,634,565,241,420,347,518,888,473,814,508,763,568,111,289,695,117,507,464,782,37,821,113,698,662,256,538,624,371,583,154,685,94,195,796,901,360,292,782,848,763,990,222,869,56,942,585,447,768,351,609,393,44,590,131,43,944,571,516,76,870,31,389,927,84,977,877,509,523,251,481,909,301,686,961,681,102,683,163,935,48,475,788,650,137,433,966,557,945,515,798,588,923,694,983,236,302,656,383,423,58,946,101,214,306,159,52,252,883,253,667,908,762,874,507,645,738,190,159,647,116,787,862,420,665,966,836,532,249,322,554,302,538,578,284,402,155,237,522,346,256,668,790,120,976,716,511,891,7,28,417,268,52,253,815,712,59,629,742,799,74,742,10,711,729,512,791,473,987,91,217,7,708,649,134,649,665,354,909,677,474,756,856,511,538,629,815,10,791,662,638,701,198,604,45,937,153,211,675,323,631,880,519,249,579,484,938,308,873,831,18,35,442,479,443,333,736,632,247,593,24,785,824,746,169,754,128,213,128,48,753,181,138,930,608,757,611,598,418,82,477,5,382,295,271,571,161,960,195,216,417,566,577,701,697,155,278,376,824,991,820,458,98,816,577,823,518,632,954,261,706,421,787,944,308,345,326,183,340,213,437,679,428,371,87,587,951,785,54,995,736,290,645,443,803,669,771,559,499,510,120,878,577,245,442,385,545,800,194,997,128,622,652,561,955,169,175,980,277,467,186,513,28,985,960,96,111,566,364,773,307,215,131,810,830,572,327,526,20,204,145,459,920,22,966,738,943,766,470,149,370,560,918,393,136,109,49,621,233,334,69,787,128,573,347,104,450,284,166,85,634,17,11,582,637,295,715,457,307,941,218,233,361,154,631,165,243,823,181,35,656,65,979,948,561,531,801,453,558,463,359,575,692,338,928,216,669,921,127,555,399,365,313,396,742,157,237,718,613,238,76,249,783,223,103,81,175,130,367,729,886,543,384,833,51,941,320,349,638,333,914,482,784,848,837,883,787,344,69,86,459,892,234,965,260,61,245,559,686,151,670,184,644,436,800,822,307,354,743,970,145,233,144,316,759,326,208,495,196,413,589,529,496,471,307,28,497,515,437,779,405,346,910,511,391,875,191,998,601,454,339,372,60,525,896,160,478,110,388,33,739,777,428,538,77,393,714,269,498,649,890,976,615,844,234,715,115,385,439,159,856,276,156,797,943,361,486,843,445,243,664,465,194,795,60,610,985,173,307,812,63,905,597,443,783,165,733,897,423,660,725,261,479,409,410,537,782,801,496,314,925,950,653,26,562,154,894,75,108,974,148,832,55,410,864,628,217,110,415,124,133,10,606,824,759,860,290,551,801", "661,598,953,982,434,522,726,713,236,498,656,136,47,356,893,864,892,688,867,366,923,341,71,275,753,663,993,493,824,276,941,517,268,911,832,801,465,345,217,890,745,58,646,237,331,363,600,542,613,4,540,831,709,290,915,978,936,991,412,344,65,181,444,484,792,38,439,195,236,548,219,79,238,72,564,745,94,25,791,950,213,881,545,619,370,808,444,851,354,997,905,209,235,63,142,982,230,997,763,894,998,616,930,451,444,480,483,280,677,277,61,846,219,110,203,126,886,514,808,830,661,957,895,648,316,423,884,751,741,424,150,425,1000,181,555,124,7,495,803,704,945,391,571,488,294,487,466,416,741,163,145,861,736,635,746,718,653,73,24,989,864,561,698,452,607,85,243,422,783,202,975,771,783,246,653,555,931,187,59,84,337,928,922,468,7,405,920,99,391,663,48,54,928,690,728,533,693,232,548,102,652,617,831,68,735,207,62,791,145,876,796,448,996,668,624,613,71,325,438,5,232,505,417,702,40,578,579,659,452,427,745,745,53,965,138,283,888,578,134,0,144,180,22,805,671,861,413,634,238,523,184,688,977,168,283,81,3,487,657,208,82,167,621,760,890,486,508,139,165,601,655,430,149,491,500,47,729,319,719,488,474,73,892,992,371,217,496,244,909,802,208,683,17,981,932,333,14,38,301,247,325,282,170,675,215,282,280,584,966,775,235,178,676,478,607,350,258,485,618,520,743,230,210,900,224,452,531,771,587,861,186,213,437,441,156,423,800,463,225,30,805,217,596,22,391,258,892,482,231,420,542,96,95,54,690,228,274,610,62,899,891,495,226,508,42,646,629,222,557,949,262,210,842,731,246,225,686,136,570,135,194,679,663,751,155,118,159,637,818,685,312,191,185,968,56,623,73,900,910,400,36,405,272,471,295,679,899,586,932,744,133,410,506,842,179,209,662,295,484,665,238,382,972,90,48,812,661,237,124,861,430,560,365,853,205,356,765,418,407,183,534,472,783,481,586,309,150,227,670,760,891,51,474,153,11,64,477,102,440,559,704,782,670,84,380,863,916,796,627,396,61,943,160,865,557,369,590,74,430,975,108,530,409,575,792,623,994,405,297,464,292,375,2,922,31,742,830,23,710,785,673,610,603,708,936,238,354,517,608,962,800,874,685,526,270,239,165,616,537,46,195,466,243,707,104,123,208,605,324,948,28,493,225,370,382,398,95,81,80,313,361,797,236,677,904,519,828,484,66,957,718,612,501,726,714,369,39,654,71,449,745,878,19,892,910,957,490,575,580,506,195,283,773,814,397,159,582,434,690,864,548,594,465,382,177,180,91,184,805,670,217,25,546,783,228,350,591,161,406,885,134,707,209,607,207,88,382,534,246,348,803,795,109,603,946,585,250,813,845,486,927,129,667,240,378,909,721,511,706,152,146,373,630,334,628,299,963,197,266,159,845,98,553,916,403,944,353,844,39,566,284,839,18,391,265,959,830,37,305,27,497,421,836,6,466,624,149,392,906,21,922,130,839,290,991,529,624,127,354,123,808,178,167,583,834,732,860,922,6,53,254,956,593,191,981,143,581,908,735,112,264,666,475,11,657,652,613,207,629,389,656,769,548,734,497,95,492,413,452,582,986,217,376,908,562,545,283,912,371,431,270,889,611,656,377,250,54,28,499,126,448,146,91,212,368,57,309,602,387,218,544,527,933,123,972,457,141,663,394,584,659,494,801,534,108,846,370,869,573,449,914,884,291,346,250,435,893,975,240,499,216,137,318,548,605,452,846,448,818,460,932,274,862,905,110,245,775,416,439,794,966,655,641,157,977,63,333,598,396,871,717,50,804,693,451,213,175,111,634,126,128,386,586,924,566,922,593,623,32,407,895,648,248,634,19,443,395,738,71,892,972,944,351,513,588,125,473,166,295,450,610,21,79,26,335,215,191,887,497,535,527,652,685,908,38,540,257,306,435,984,721,882,250,59,344,865,510,659,339,863,110,41,42,49,485,937,368,189,534,743,897,33,836,275,435,940,990,69,410,544,271,488,509,693,314,2,60,885,640,477,197,852,431,21,575,363,696,257,593,79,407,770,181,338,125,152,842,992,483,708,578,626,874,762,85,763,962,880,683,419,723,961,241,781,726,196,793,701,399,49,894,671,731,68,60,640,569,855,700,855,597,995,924,725,560,275,118,951,299,330,660,242,517,859,572,758,105,597,565,126,241,544,337,803,919,797,861,132,682,355,548,48,842,161,183,485,514,535,321,167", "375,712,154,572,493,148,788,4,39,64,487,920,642,912,233,879,770,796,207,284,217,472,431,976,597,611,102,544,384,141,660,489,932,601,943,823,853,42,511,359,798,561,172,298,672,119,237,982,176,445,823,777,514,3,726,606,187,586,770,512,885,848,24,707,954,291,786,264,301,245,335,448,365,90,490,583,268,349,830,473,877,528,552,114,366,47,967,686,298,168,767,702,865,225,135,24,851,93,777,729,419,884,898,362,131,211,357,621,252,902,695,140,623,458,481,503,29,577,609,845,471,693,200,954,786,814,954,635,844,512,833,63,124,979,929,637,333,463,400,301,605,178,771,697,96,661,517,521,914,555,452,378,197,170,666,773,144,827,235,55,869,6,37,111,250,416,137,517,27,641,181,541,994,529,809,734,604,373,169,651,169,610,98,969,396,219,36,636,617,192,895,822,685,346,990,813,540,119,337,617,250,379,942,717,706,824,828,285,69,771,554,674,305,88,968,433,202,231,639,987,475,430,772,308,751,746,965,932,700,545,849,730,801,573,681,718,488,14,366,144,0,84,863,965,871,786,401,473,56,340,416,173,70,175,524,650,509,23,680,20,883,283,549,314,30,238,357,123,9,842,584,52,562,907,681,697,836,581,568,60,849,996,100,813,980,854,233,268,235,328,125,238,867,194,599,388,177,931,18,93,796,34,522,29,93,122,503,573,90,236,674,760,475,486,965,510,313,287,535,167,640,451,529,982,491,244,143,960,438,939,919,801,317,564,895,960,940,985,124,997,349,184,565,476,274,889,572,744,911,219,681,682,307,175,247,903,875,394,63,236,273,686,678,417,911,676,869,171,368,11,447,901,843,710,640,334,441,421,846,620,626,786,388,451,910,265,562,206,169,330,781,62,798,340,235,994,140,953,881,777,75,902,80,877,51,399,648,884,28,998,970,43,10,158,350,119,835,847,499,947,589,895,43,676,582,654,124,660,585,505,708,171,909,650,139,231,832,338,835,99,864,798,143,595,893,686,930,657,562,758,964,32,605,452,951,471,725,282,725,265,666,9,545,509,826,866,631,502,359,543,63,947,426,207,140,579,869,412,253,787,588,970,391,100,315,799,409,330,719,294,741,514,97,81,353,167,594,642,436,263,845,921,406,349,775,849,584,710,22,876,583,681,952,779,526,178,856,362,425,700,576,822,219,387,576,256,326,699,56,704,725,736,490,892,617,265,777,306,770,89,950,466,578,249,876,189,396,93,98,826,98,135,82,107,441,159,563,307,456,776,71,52,272,585,444,602,233,223,122,920,373,874,886,65,327,712,255,345,640,782,241,17,152,663,957,246,112,622,530,618,317,650,65,550,929,109,276,897,932,777,770,700,118,648,102,294,812,579,148,655,708,756,177,397,973,920,13,108,61,797,865,870,178,61,671,100,755,321,72,168,568,572,236,446,528,115,383,989,582,564,671,61,721,154,505,189,357,212,334,659,131,245,201,690,36,498,724,691,917,139,734,75,829,386,667,896,198,606,330,375,306,164,857,42,2,834,998,36,466,409,210,926,903,543,653,493,245,929,992,130,737,449,776,451,251,846,209,595,356,113,887,930,686,59,243,315,570,442,680,826,959,137,405,641,427,320,634,898,73,598,726,456,959,115,250,608,490,19,928,383,595,668,137,175,198,726,159,984,779,127,852,371,186,660,376,287,774,216,873,406,352,288,938,196,692,274,850,824,264,52,130,97,852,387,256,940,544,697,465,882,438,551,457,685,491,720,279,486,80,913,730,86,602,133,688,296,87,782,792,607,633,557,909,847,384,998,354,58,485,616,464,731,68,778,808,98,649,433,401,734,945,229,673,356,631,210,743,774,870,395,58,229,690,964,920,269,437,407,392,617,651,343,779,892,758,48,610,546,461,977,773,974,586,288,176,426,270,890,403,380,350,638,317,698,49,524,689,622,522,799,462,422,80,375,532,415,883,653,957,599,593,671,534,679,101,424,580,596,78,482,363,321,156,812,228,148,207,333,200,927,363,984,503,604,22,451,406,642,250,333,600,457,372,98,884,475,925,214,382,458,784,772,926,831,422,535,85,424,569,536,33,19,590,845,77,575,882,989,893,114,885,775,940,110,722,593,269,479,634,599,247,529,352,746,486,214,198,233,433,286,924,80,659,513,872,451,367,604,730,251,954,657,618,444,646,476,525,658,428,30,12,655,938,32,466,531,309,102,376,104,348,277,632,477,854,869,653,644,776,962,853,737,124,505,63,71,395,687,637,366", "941,29,656,675,332,569,349,265,358,112,158,70,203,827,930,374,693,70,650,118,784,993,759,432,557,381,885,768,966,377,109,332,303,722,281,969,24,884,149,658,892,790,696,202,470,937,803,566,893,477,844,447,405,660,42,812,880,835,860,724,763,957,325,553,971,333,89,896,171,595,916,713,914,524,9,352,314,345,180,473,320,770,687,129,992,5,919,345,181,427,235,216,842,261,575,137,381,892,938,875,752,613,127,918,473,303,708,117,86,301,413,454,438,37,739,174,156,267,966,579,176,333,68,921,982,298,430,115,845,247,804,217,841,352,290,496,241,591,749,392,353,772,641,838,786,396,478,390,508,687,404,502,958,337,540,984,949,850,407,828,74,439,91,35,21,876,890,307,499,416,255,873,160,775,374,650,367,525,212,236,355,440,52,967,692,410,654,266,865,902,911,176,537,548,269,697,100,294,589,131,717,212,270,215,158,967,795,576,925,203,619,678,366,659,242,810,554,763,686,623,778,266,33,186,887,530,139,231,407,660,766,239,579,778,223,955,69,257,741,180,84,0,58,952,424,534,493,747,463,699,431,247,888,286,972,916,182,49,1000,651,401,225,606,360,289,472,365,575,366,376,423,71,777,62,738,430,553,93,387,150,201,336,85,938,125,582,561,939,885,573,325,836,857,82,231,914,546,684,11,12,479,672,243,877,100,525,794,353,151,666,799,402,328,8,931,692,289,7,309,643,112,716,934,446,741,55,360,965,211,433,89,87,434,107,960,540,915,401,664,240,482,959,196,467,180,696,702,579,52,596,284,508,176,436,770,270,537,519,237,110,675,945,724,429,12,789,312,435,923,497,94,908,355,676,379,260,246,629,214,752,688,578,315,376,455,105,699,645,390,654,463,436,659,359,472,284,848,726,705,177,416,110,102,890,629,359,629,543,852,578,204,105,333,378,525,992,159,505,980,925,245,409,454,348,877,857,157,949,295,264,909,767,386,471,953,958,7,719,902,466,126,220,498,69,941,613,471,581,576,616,897,960,925,493,648,796,44,74,822,933,834,565,65,342,615,119,460,766,552,384,617,971,49,133,477,961,615,583,221,473,69,936,272,827,973,797,614,83,637,95,622,261,328,556,210,775,253,888,723,540,221,853,333,950,705,305,994,684,815,845,371,18,622,404,461,956,355,662,538,655,109,80,641,112,974,438,812,53,262,525,635,177,2,589,359,781,543,537,70,41,352,176,347,232,942,587,120,230,256,808,929,310,705,731,820,47,257,501,594,607,694,664,559,960,152,914,717,189,293,401,447,6,613,790,271,221,461,761,785,380,306,231,777,456,887,984,902,462,986,556,975,346,875,966,490,262,438,17,470,502,659,21,141,715,457,318,326,565,651,403,735,518,31,399,466,351,881,40,416,354,147,711,550,903,788,538,403,603,106,66,575,558,421,416,262,298,488,667,244,158,152,625,194,580,595,681,259,337,255,488,987,20,822,186,329,525,474,264,49,44,370,380,275,544,499,255,577,559,621,977,788,245,278,698,867,630,81,735,127,812,183,883,304,235,241,638,252,497,810,772,467,702,26,678,173,417,724,720,658,218,315,948,924,158,772,521,914,187,942,43,907,147,319,252,48,119,170,525,101,355,39,132,694,649,779,156,233,193,568,110,822,607,115,109,998,959,429,986,378,529,193,485,93,703,13,375,591,889,485,639,265,2,10,233,97,211,89,317,634,184,771,231,376,140,911,571,770,355,553,384,623,201,87,74,218,765,674,474,300,184,663,26,764,566,526,69,115,422,766,554,5,187,15,233,344,283,546,35,244,303,379,916,465,742,244,96,539,702,109,473,442,145,266,2,930,966,947,70,164,70,56,267,3,865,48,537,505,763,112,484,623,844,13,675,89,813,998,538,394,974,355,166,394,520,316,274,831,576,167,231,684,120,247,139,545,124,781,172,333,179,193,725,639,246,818,476,256,849,740,433,190,832,721,137,200,768,18,684,934,923,258,884,817,192,64,759,398,437,924,544,975,56,550,307,526,968,159,194,646,922,343,629,469,264,219,439,784,819,803,302,258,883,318,343,277,369,246,76,943,904,38,393,800,758,826,134,405,591,585,559,687,326,953,527,377,467,249,523,821,438,582,222,503,300,292,980,458,158,338,62,757,589,401,821,1,10,113,350,196,619,550,40,663,287,371,712,644,397,366,629,730,582,131,198,304,611,950,756,884,671,43,230,341,185,558,433,597,981,449,576,857,738,194,161,878,572,264,480,504,878", "487,191,121,525,536,995,169,870,579,157,191,917,113,438,42,159,848,910,268,126,914,371,156,472,985,394,908,619,477,225,676,301,727,542,518,666,623,1,64,974,289,423,572,941,510,484,558,611,745,536,862,825,66,642,392,319,168,800,543,78,419,894,969,554,779,818,297,802,614,516,546,116,160,234,284,560,34,249,840,547,142,736,203,407,432,637,240,42,533,717,226,433,215,307,391,797,376,317,878,782,911,998,586,583,253,712,497,820,918,511,637,311,578,105,503,604,123,143,978,120,775,423,347,379,142,115,868,822,163,642,556,260,668,106,631,914,38,629,881,292,209,144,102,497,713,489,21,708,737,995,991,686,171,610,829,99,716,135,851,5,862,190,325,913,786,142,731,512,777,259,461,89,484,727,361,44,448,984,935,516,651,488,763,166,732,308,29,828,614,949,837,613,242,464,354,439,79,647,784,61,930,862,678,899,164,379,918,481,271,394,171,50,976,748,692,595,557,969,40,603,388,417,806,453,781,678,670,267,619,660,486,493,238,43,977,864,750,582,749,22,863,58,0,575,502,372,103,386,511,440,806,122,343,301,498,706,798,902,730,452,72,271,996,876,157,760,833,472,23,905,430,829,760,578,618,934,249,768,789,570,846,477,233,505,816,133,140,298,662,26,833,684,755,111,239,896,662,657,144,201,593,235,564,509,507,556,630,297,189,504,200,881,442,456,328,791,8,651,166,60,282,938,39,142,364,871,33,539,260,624,332,700,734,590,102,842,702,818,220,292,341,829,382,427,37,339,280,335,616,468,518,292,739,327,459,654,749,491,244,309,160,877,430,67,101,246,217,913,352,22,428,3,210,173,753,459,17,302,127,751,54,953,568,742,899,685,783,260,567,945,296,211,441,782,649,586,269,259,522,627,209,242,639,697,165,966,459,646,551,613,952,539,957,452,990,400,18,368,392,368,465,164,109,265,761,573,727,921,498,605,834,994,552,422,867,609,943,977,66,345,258,607,281,13,447,309,546,487,344,27,440,584,630,171,94,222,859,568,917,550,154,547,739,19,203,250,718,902,966,53,552,633,365,913,839,27,820,371,747,983,314,82,626,126,452,408,257,523,713,749,516,460,538,824,297,367,90,825,315,209,304,431,626,950,62,348,867,550,737,759,222,715,88,376,69,664,979,262,781,777,246,876,56,142,540,290,902,427,803,531,554,3,621,766,401,502,700,308,995,921,742,148,662,718,880,311,700,605,226,648,795,775,546,195,709,190,907,183,841,155,993,985,336,260,243,461,968,954,305,244,145,31,511,668,158,384,880,545,858,803,336,660,127,786,591,491,731,543,78,534,905,532,84,390,307,662,145,572,444,872,9,392,374,652,866,86,346,313,380,622,22,501,590,595,431,885,790,72,969,120,936,765,652,147,75,936,428,173,764,899,98,759,507,437,797,417,894,796,325,251,49,743,365,656,422,110,756,12,355,947,795,328,277,378,213,777,514,332,459,353,609,512,135,817,174,703,610,477,31,31,204,795,566,830,491,336,10,236,430,671,820,909,545,399,131,622,610,436,354,182,732,445,133,549,24,436,908,438,928,615,932,94,983,488,272,472,456,359,308,104,449,738,283,91,333,226,809,565,386,576,817,883,789,775,973,999,935,948,338,893,221,991,527,507,316,222,617,421,829,519,985,516,20,692,403,180,770,553,508,716,508,989,327,153,877,349,362,755,605,516,488,201,786,614,835,208,427,856,688,360,563,70,81,969,705,493,687,155,170,390,548,387,811,502,193,243,664,286,349,944,232,471,648,764,715,130,54,375,336,689,758,554,100,750,532,151,179,884,315,390,271,491,772,889,282,285,412,253,415,421,377,366,75,918,949,967,819,733,46,382,491,321,453,218,98,112,416,566,571,130,687,895,127,266,439,839,964,595,258,261,876,628,733,679,77,195,82,387,943,635,203,131,832,154,603,461,138,786,126,98,878,729,141,126,422,138,264,857,542,19,205,545,15,835,514,285,533,82,359,405,259,290,204,164,583,712,86,966,221,726,228,338,679,982,947,502,604,385,829,454,56,855,732,808,943,254,396,977,956,930,387,797,941,381,192,892,91,541,300,5,249,464,672,537,753,323,29,366,128,779,91,119,573,402,492,205,788,212,107,883,667,757,530,149,783,508,126,459,879,193,686,863,819,427,157,476,214,740,726,792,560,820,408,407,680,705,66,673,162,197,524,560,84,394,169,158,935,777,89,60,252,754,590,638,586,325,606,7,172,369", "58,650,543,801,989,386,870,415,427,333,280,712,199,785,306,429,362,357,340,721,516,12,604,972,61,875,184,755,630,911,609,291,851,256,129,255,646,331,674,842,862,855,108,215,396,974,395,466,410,686,844,961,737,958,241,308,371,152,209,639,660,561,230,457,759,158,502,257,845,963,748,400,427,262,197,510,230,826,537,763,920,920,937,390,810,715,190,398,566,110,639,276,479,487,548,114,664,251,120,835,244,580,345,336,914,753,417,556,238,269,554,384,355,536,267,257,148,765,530,448,952,209,164,818,162,181,237,915,123,277,851,838,586,512,259,84,896,602,982,306,549,210,174,127,765,836,177,916,642,139,939,616,475,684,39,640,456,890,884,63,333,654,314,918,338,489,327,778,951,668,775,154,430,180,754,674,230,745,628,722,826,999,108,428,686,135,775,971,93,281,280,690,700,532,375,480,335,13,505,936,214,29,736,420,760,845,822,636,581,630,181,446,706,559,791,719,992,813,327,854,546,576,72,492,191,198,312,26,947,148,237,933,433,179,56,663,445,40,164,805,965,952,575,0,84,980,269,762,969,736,845,667,632,740,989,569,925,674,465,772,803,861,293,169,68,407,132,958,979,819,85,609,814,673,373,445,497,66,621,180,741,150,851,650,832,179,187,810,411,936,289,858,870,466,829,266,496,328,193,633,251,284,831,183,554,44,150,66,178,441,273,120,452,879,362,82,766,882,345,135,798,747,940,186,357,739,635,328,903,277,934,92,36,43,281,517,590,576,234,496,256,587,887,800,899,549,944,913,428,856,380,720,930,819,584,917,624,46,289,220,856,70,391,454,554,172,853,916,86,491,843,422,797,188,819,772,803,131,476,167,568,887,69,651,551,696,303,664,535,811,727,375,314,446,741,245,806,391,315,801,980,254,612,678,640,346,834,810,461,713,949,183,216,180,726,500,409,732,151,835,575,287,551,461,190,412,258,344,78,56,639,108,317,607,200,57,768,133,274,24,556,166,842,895,857,892,521,596,485,476,991,799,186,606,38,780,426,557,521,354,836,444,677,988,436,150,887,884,697,21,320,30,824,5,985,199,379,29,95,480,161,505,374,670,925,957,337,409,329,307,450,951,161,572,887,712,843,1,633,979,217,980,598,333,228,248,547,14,565,865,719,391,223,34,812,203,515,619,549,369,746,476,332,759,243,73,323,642,872,182,88,986,497,726,645,574,42,591,781,902,589,619,755,1,331,223,908,671,823,635,445,44,813,799,523,395,78,943,787,119,946,347,936,29,708,870,160,37,232,718,206,710,41,913,142,408,998,844,846,355,87,309,922,899,87,460,67,13,823,119,52,909,623,68,85,583,172,565,776,497,235,776,233,748,55,63,729,563,330,556,218,515,24,793,784,416,950,833,417,710,729,893,773,151,959,600,809,737,54,965,447,91,574,370,496,152,322,328,659,362,287,488,193,274,53,904,815,672,302,369,371,707,855,892,45,850,225,685,793,926,834,681,232,335,915,423,847,145,278,989,117,835,2,81,998,889,489,82,772,39,356,530,200,606,600,134,212,894,143,582,664,404,322,141,607,418,555,944,14,358,675,28,260,638,617,323,928,171,734,3,950,827,355,356,414,584,5,370,452,902,748,571,968,297,770,475,307,635,762,989,219,262,300,827,829,237,940,950,886,671,3,77,312,599,3,312,136,583,459,947,794,762,962,159,110,165,413,356,270,527,903,919,65,705,519,171,727,363,823,811,566,831,273,926,803,845,226,957,992,495,270,638,66,659,834,95,17,691,124,248,4,555,88,115,224,556,803,865,68,585,193,651,766,380,572,824,1000,144,653,621,463,367,614,808,299,801,929,697,322,71,148,369,760,540,396,926,324,154,286,697,316,452,367,585,965,134,864,122,428,62,53,702,953,780,726,292,786,575,263,352,704,94,919,505,938,429,186,558,8,737,853,545,159,240,175,71,112,732,332,416,97,754,761,805,829,440,160,769,171,930,15,746,799,286,248,839,244,518,457,351,19,238,954,745,426,309,254,571,680,442,994,362,785,476,860,299,798,137,810,187,388,829,663,325,489,248,566,372,929,160,76,504,478,677,273,421,297,201,410,523,67,93,544,596,95,843,111,421,456,164,747,66,114,374,947,475,854,175,113,662,956,595,793,21,517,621,366,759,237,937,703,324,169,823,647,716,832,874,714,532,110,55,400,633,305,171,704,94,262,529,173,513,448,433,754,16,627,608,866,767,718,669,609,17,991,341,260,588,716,792", "890,287,160,546,647,382,783,442,377,211,797,603,514,49,780,730,535,685,942,741,712,636,537,812,60,119,688,299,958,804,187,340,891,423,707,978,481,944,959,33,659,127,177,422,269,572,736,716,886,14,498,978,522,280,934,163,89,346,185,170,373,253,853,860,331,201,375,955,679,362,963,624,267,604,806,511,318,408,587,840,643,65,238,288,133,730,677,134,366,99,381,330,13,953,470,279,935,236,328,392,668,111,178,486,902,830,145,365,505,375,443,694,269,936,80,314,840,741,184,746,142,385,947,846,41,804,254,791,662,341,202,925,10,264,935,143,146,544,887,68,576,907,757,233,722,951,502,194,396,897,50,507,729,758,716,777,496,432,111,39,668,241,230,875,530,878,7,743,826,162,549,649,40,760,210,768,646,680,521,771,77,192,883,747,96,149,705,605,51,473,195,966,651,709,396,679,660,985,252,994,348,42,849,555,144,86,585,219,344,911,56,479,65,657,698,33,131,552,795,62,242,528,860,326,17,588,777,877,307,885,399,711,344,634,967,996,988,696,507,671,871,424,502,84,0,514,180,485,437,259,232,106,789,503,148,245,334,288,640,298,762,874,775,900,484,530,690,780,26,411,951,676,432,406,670,653,930,314,449,922,453,877,212,182,478,537,595,240,944,910,73,336,353,514,541,113,187,463,590,30,129,227,819,695,409,794,389,137,222,897,434,442,257,160,511,455,426,768,659,615,430,539,255,262,906,278,111,229,710,309,295,769,466,946,403,366,654,1000,313,156,511,419,214,964,457,687,687,119,993,754,469,355,908,399,86,875,490,673,447,147,949,801,317,374,668,469,809,143,487,241,595,609,476,246,860,955,582,675,500,328,632,107,970,948,271,371,178,451,238,375,573,681,145,839,666,648,691,909,968,27,883,875,717,453,374,921,855,606,896,590,878,407,58,371,306,638,730,953,373,775,885,963,541,3,625,167,64,96,585,399,966,119,132,206,934,609,831,952,734,92,28,697,473,914,473,406,606,107,771,771,822,595,70,349,886,861,121,681,193,273,56,980,363,411,217,320,48,57,338,728,219,550,892,854,535,764,903,63,172,673,82,590,747,67,935,91,183,916,841,246,129,541,506,11,505,993,416,512,644,60,974,733,279,97,511,986,848,621,422,451,190,807,61,674,485,108,415,269,346,743,785,911,243,784,656,753,723,52,442,919,93,512,3,49,500,668,179,344,966,902,662,840,820,779,506,119,484,731,349,728,575,528,834,806,1,940,840,631,274,547,168,182,935,561,987,369,708,632,883,75,659,735,481,727,667,854,320,509,597,909,455,246,781,950,182,516,252,688,324,556,292,799,304,146,188,78,898,420,290,280,313,882,579,186,815,361,597,556,635,120,886,9,222,755,419,434,244,169,168,957,734,166,719,951,896,819,251,937,904,924,626,809,388,234,170,756,185,433,121,93,419,372,470,888,65,65,390,814,514,566,779,128,927,720,173,859,351,702,191,47,495,190,589,175,931,407,200,348,600,693,544,441,161,899,450,696,496,558,874,889,799,34,586,248,349,143,996,637,159,698,326,104,822,854,65,122,986,707,530,656,427,387,10,741,580,609,312,614,530,909,420,192,538,890,153,714,864,10,426,726,608,221,585,290,740,678,420,647,796,148,342,940,124,662,833,310,794,223,187,701,263,905,208,535,810,299,889,370,867,668,354,467,741,765,3,555,284,109,436,86,439,435,794,420,833,940,55,613,184,188,994,172,3,987,637,92,927,857,744,658,181,525,816,816,251,259,155,279,477,849,905,882,624,446,713,142,279,49,446,4,179,70,603,317,21,20,633,361,767,748,108,991,274,327,834,731,489,358,583,618,845,122,433,46,851,879,344,302,903,463,279,497,805,90,814,778,30,174,207,219,973,780,542,818,531,694,582,901,972,276,808,670,700,248,665,786,878,822,189,671,367,311,592,957,853,548,380,826,988,563,232,710,946,724,560,383,600,606,25,880,660,669,82,853,848,735,544,669,76,139,970,785,633,631,874,322,723,603,87,286,112,945,511,579,134,464,80,577,359,34,264,602,17,641,677,378,678,44,832,694,166,827,570,777,663,852,278,66,209,275,805,200,425,24,612,579,466,698,453,541,866,582,585,99,360,984,832,537,926,152,706,234,62,413,559,64,449,420,500,56,657,842,374,715,859,823,720,24,281,408,830,364,534,241,335,60,208,471,600,193,232,669,954,940,814,343,530,603,324,40,610,48,318,295,831,624,416,510,111,451", "700,301,848,827,96,119,324,696,734,631,416,907,789,268,455,78,674,665,455,663,322,621,557,483,184,517,615,299,57,568,217,474,422,259,744,347,191,318,934,910,244,717,557,883,717,548,861,348,589,709,532,88,247,73,907,774,89,276,116,540,769,119,747,981,24,658,534,378,790,742,464,247,38,490,737,589,246,176,421,228,237,265,715,611,524,347,775,80,333,12,188,765,72,414,767,628,749,294,665,124,105,589,27,159,710,776,205,692,63,417,956,357,459,981,157,34,132,240,647,928,597,375,379,206,258,149,43,984,448,116,709,923,282,706,998,542,504,190,280,405,772,254,90,464,977,115,870,106,945,146,144,356,43,382,136,614,811,19,468,594,908,646,956,795,276,752,397,148,848,377,694,345,9,958,876,145,980,509,710,824,430,639,819,303,963,389,283,204,454,492,664,542,469,7,376,685,439,785,702,376,338,823,419,197,649,312,257,142,884,376,540,731,82,209,660,7,285,969,939,430,606,304,154,721,703,349,985,83,662,966,786,963,854,594,747,32,902,14,209,861,786,534,372,980,514,0,610,322,827,802,249,60,206,680,738,418,151,469,571,11,564,219,622,604,906,34,871,935,366,831,157,325,574,181,952,951,241,675,489,901,368,947,609,54,530,596,407,376,279,481,876,562,906,355,21,92,134,303,600,759,365,734,16,672,982,133,176,954,77,392,41,921,273,819,653,764,638,814,626,308,74,723,64,414,20,674,515,481,488,825,910,763,745,535,915,398,211,725,394,21,5,125,757,970,705,815,208,904,692,48,225,208,467,247,917,422,236,655,582,646,870,606,707,381,519,216,459,695,978,710,433,479,978,454,432,394,281,600,4,386,366,590,154,195,607,779,91,993,94,957,579,989,831,36,460,615,886,676,810,90,892,342,636,697,472,866,673,194,251,739,352,949,69,187,111,573,308,138,492,559,39,866,713,637,274,377,61,754,46,558,373,981,413,655,330,523,446,825,33,345,930,664,76,916,115,863,696,262,234,948,646,549,666,376,387,287,190,970,724,627,36,72,388,604,57,19,8,401,613,317,77,917,622,42,837,632,649,466,335,112,99,282,1000,117,621,700,299,431,844,93,527,827,939,41,846,468,822,745,4,465,815,127,178,506,365,978,288,280,879,922,445,515,476,622,945,695,632,98,259,52,48,875,838,267,632,786,955,899,459,123,676,767,4,743,900,258,208,216,714,433,334,956,311,674,726,630,275,338,312,164,59,576,262,57,936,613,774,560,285,803,636,332,856,517,8,848,724,565,679,645,689,127,316,63,577,60,267,734,830,512,831,860,146,47,439,914,566,548,552,959,533,490,407,926,409,6,202,932,649,308,676,200,707,533,709,573,354,118,987,348,981,454,754,556,194,849,70,185,709,878,31,119,472,600,238,869,370,113,875,89,948,852,290,369,364,276,934,980,100,861,542,9,38,301,637,119,486,965,766,539,312,91,656,463,483,971,72,464,583,733,364,408,111,57,254,183,117,352,200,451,281,806,455,4,37,407,215,153,854,761,79,666,377,337,697,10,503,87,737,683,175,557,695,743,751,97,483,897,140,644,340,70,291,160,720,895,516,985,945,698,593,254,471,383,927,939,409,788,46,448,728,289,262,227,112,302,951,542,827,493,320,116,845,285,231,422,412,273,166,64,995,663,378,90,442,437,131,209,345,76,879,196,637,251,47,608,815,643,177,923,466,365,250,164,322,997,157,655,101,696,891,523,623,704,701,144,752,247,988,245,91,245,62,712,787,334,638,922,763,959,741,204,261,103,623,31,373,27,328,536,140,395,200,60,388,253,356,671,46,960,345,641,589,397,865,264,627,399,624,695,119,568,882,943,947,999,348,278,727,505,72,288,978,381,8,767,279,279,591,594,498,974,310,379,859,529,929,685,155,520,5,696,444,871,916,489,335,158,338,521,254,321,755,282,607,655,465,775,270,306,614,460,337,405,26,959,56,345,455,255,349,221,990,764,255,273,568,811,950,566,8,767,708,984,302,990,813,359,714,184,207,157,805,656,600,889,316,232,186,67,937,691,991,969,165,885,471,962,350,120,559,357,818,495,748,449,412,49,516,847,208,104,878,997,58,958,800,399,804,601,166,527,402,367,805,914,759,289,920,96,455,965,577,442,215,62,184,620,701,386,585,559,672,274,608,82,441,208,902,545,473,343,313,144,936,994,86,567,347,267,841,433,811,739,803,486,531,244,353,424,11,769,308,106,125,401,184,197,322,561", "121,735,724,99,247,123,281,720,814,751,64,475,31,600,635,782,31,519,325,19,859,985,909,217,783,327,357,833,62,952,796,355,139,140,391,578,343,903,459,526,34,71,317,444,282,895,198,873,86,858,564,952,692,337,739,496,116,314,377,884,768,113,350,452,579,546,722,152,473,726,914,627,912,261,774,967,994,472,327,294,816,68,305,876,20,36,423,230,290,12,961,944,503,715,118,752,891,116,24,628,659,348,912,276,224,174,17,9,122,659,89,338,681,912,435,728,357,123,427,21,885,820,784,469,233,251,150,713,457,24,521,439,582,235,102,448,614,200,337,6,907,744,450,22,258,992,462,379,91,695,500,715,162,367,605,738,336,978,245,718,855,423,795,526,960,127,200,22,161,606,427,892,924,57,265,993,668,165,308,745,663,600,906,223,85,340,510,563,525,174,682,221,154,543,439,291,755,299,28,895,341,553,387,11,907,812,920,120,817,557,354,548,903,505,38,6,205,490,613,203,990,674,821,20,386,334,380,241,90,433,956,92,7,142,895,304,322,172,881,413,401,493,103,269,180,610,0,515,379,601,665,136,929,878,157,401,179,409,99,85,364,369,725,214,180,115,548,846,860,614,992,621,433,966,859,255,211,61,659,952,874,381,568,640,921,96,127,599,656,280,740,925,493,198,83,139,194,719,819,323,563,852,68,579,791,714,996,485,300,25,429,573,505,506,733,416,975,886,375,292,450,439,89,883,820,455,725,53,103,527,494,613,688,670,358,754,352,995,125,506,140,617,420,586,924,629,616,770,275,276,427,144,728,228,604,206,941,593,272,412,967,228,35,573,394,731,798,339,496,997,208,951,185,870,725,830,877,998,618,252,999,9,69,680,533,417,16,192,666,679,710,954,631,143,132,611,718,110,304,412,671,753,140,673,896,777,616,729,167,875,37,428,84,620,444,990,589,271,508,990,618,570,626,278,497,190,420,114,172,642,661,351,838,575,733,200,466,985,959,149,85,842,529,622,672,461,470,58,387,222,548,893,203,919,139,684,901,930,725,398,518,699,649,401,274,185,59,329,770,33,996,556,237,557,31,277,533,585,189,670,398,101,862,815,6,931,406,35,646,621,482,891,429,882,50,102,318,985,999,460,375,151,927,889,802,555,917,18,673,366,915,94,326,690,282,717,96,871,10,21,214,868,240,808,26,279,596,95,278,125,950,255,856,797,916,249,908,697,288,131,977,90,150,566,165,584,196,22,183,867,94,205,371,327,175,706,281,680,673,965,963,184,844,194,787,112,342,191,927,365,170,621,437,924,184,512,374,62,825,949,935,965,286,596,344,404,410,270,755,722,816,476,365,435,561,707,926,295,773,428,245,91,928,452,276,758,128,420,186,196,920,853,341,310,929,495,913,412,559,221,425,455,993,841,601,705,276,690,717,718,202,725,696,277,130,485,865,385,303,141,545,520,122,633,903,842,639,796,468,430,176,963,815,102,512,738,301,400,156,291,100,48,627,673,834,817,111,661,521,615,276,982,809,363,640,1000,216,366,441,280,384,121,394,67,336,137,506,492,874,619,562,818,666,507,900,514,290,628,606,642,811,646,609,218,448,750,185,910,615,706,109,831,979,288,27,513,797,38,562,498,439,376,79,912,725,803,333,984,371,752,339,810,254,631,996,703,767,665,420,456,756,443,911,329,389,81,237,961,11,595,669,808,988,246,858,328,252,711,875,201,78,318,386,589,456,902,345,257,729,300,22,455,643,461,528,401,19,168,836,752,27,892,968,841,183,921,48,720,911,895,823,157,614,315,643,629,504,410,225,309,524,765,657,439,671,688,263,793,66,261,883,89,827,454,679,701,969,470,473,719,273,644,166,226,363,224,727,629,196,765,562,551,973,971,924,67,721,733,833,47,878,559,165,211,151,298,276,106,834,184,101,578,756,844,50,134,895,796,202,110,368,695,382,848,156,270,812,45,628,559,618,820,517,662,44,452,392,79,165,673,738,621,193,932,236,670,212,36,196,547,241,5,88,189,664,490,226,226,332,343,946,172,832,441,177,123,376,547,82,516,677,325,729,903,388,326,447,453,709,963,83,115,843,569,315,296,418,619,552,724,771,821,492,985,956,543,890,223,579,259,116,429,162,222,962,78,633,581,931,16,188,406,597,94,240,396,281,758,620,324,67,95,844,862,643,888,862,359,874,948,654,367,318,460,546,269,790,307,489,5,471,834,872,465,185,376,427,415,177,365,705,734,53,732,914,466,565,999,764,244", "852,765,366,741,695,876,584,732,621,496,286,901,26,613,671,852,193,584,869,32,241,962,379,171,787,416,145,76,87,355,455,541,674,355,927,644,584,757,354,122,127,408,428,173,145,771,477,542,285,624,831,530,265,244,888,945,215,40,703,84,452,105,758,597,251,915,826,551,458,704,871,368,288,944,461,103,187,59,380,131,662,363,338,654,741,183,175,680,448,481,886,68,595,206,195,426,622,882,810,776,371,866,561,907,575,619,877,915,27,391,927,844,127,471,139,614,12,781,6,318,576,310,23,283,468,938,189,469,439,789,639,435,151,238,53,20,378,521,788,545,122,376,313,935,823,442,105,361,637,940,162,983,292,19,246,993,937,843,14,475,198,380,374,127,228,18,569,233,738,573,65,38,487,486,697,287,939,408,576,998,293,836,626,648,104,143,895,801,396,993,720,81,195,989,544,965,828,603,53,868,238,399,662,602,138,278,552,322,765,253,277,556,462,292,823,413,657,348,852,359,168,44,473,264,476,122,105,137,46,768,528,854,429,578,699,459,126,574,257,634,473,747,386,762,485,322,515,0,959,833,845,136,304,805,583,59,47,854,75,693,203,693,462,858,82,509,287,765,322,390,124,977,468,180,50,741,508,621,816,240,917,703,811,956,429,933,818,288,495,572,789,312,2,418,322,887,230,544,539,436,347,888,189,517,174,691,930,840,710,713,186,194,759,707,124,1,307,259,309,150,406,730,455,499,506,793,91,598,654,20,522,163,614,117,47,649,489,127,656,355,326,227,287,396,456,403,415,430,797,924,576,183,224,208,402,900,274,938,631,939,227,942,585,780,791,941,838,227,536,569,828,548,758,413,463,333,955,156,987,186,573,448,644,604,312,470,909,393,459,11,634,998,999,191,973,862,186,301,618,622,60,485,768,979,870,761,21,352,536,374,44,780,577,480,733,912,409,171,604,42,515,180,47,256,469,636,546,358,275,214,670,504,958,488,531,275,162,869,623,665,218,563,408,322,273,582,111,707,999,898,983,571,171,911,548,455,410,192,520,556,93,719,162,592,969,744,925,604,509,266,736,750,405,160,658,63,284,548,485,546,839,55,636,138,43,431,708,657,455,535,999,520,614,15,954,826,488,711,438,89,479,932,2,154,6,690,912,989,599,602,577,33,283,605,806,276,786,390,293,374,61,51,450,668,484,609,457,336,549,816,92,639,815,80,898,366,513,448,378,192,636,280,549,638,69,724,890,892,115,498,819,861,444,980,819,817,339,351,836,659,994,609,410,369,612,763,622,813,151,633,710,294,729,896,229,21,950,328,522,758,461,609,615,590,571,479,567,929,336,206,830,644,111,603,393,151,300,624,979,752,708,392,102,572,566,888,580,894,141,578,499,80,676,846,870,257,319,222,975,523,720,274,34,770,824,3,125,22,447,212,402,330,860,671,927,164,281,795,117,159,101,256,407,608,651,324,12,26,113,557,438,806,961,805,222,346,902,993,837,61,633,756,700,780,277,812,653,21,568,462,740,983,124,333,852,869,101,706,885,509,350,827,481,681,769,317,297,609,479,250,452,57,411,394,30,269,489,184,696,789,106,444,740,943,293,657,672,193,137,130,267,579,181,591,136,606,397,419,609,843,913,871,834,119,174,894,575,980,999,188,754,210,908,978,104,826,541,714,186,685,399,165,783,375,897,95,584,921,772,503,849,83,400,900,885,67,71,309,425,67,144,768,660,841,643,141,406,90,3,873,328,854,268,409,726,225,982,14,511,253,408,138,608,378,840,832,994,827,149,67,794,820,895,620,895,387,341,249,427,342,918,306,920,750,493,15,189,427,96,354,53,890,508,359,607,887,341,341,999,850,233,419,462,887,622,967,922,52,206,622,147,619,239,583,941,522,127,700,484,18,796,452,839,747,152,227,75,222,271,114,289,656,106,311,699,580,621,218,396,736,436,386,267,506,840,501,980,26,299,734,340,168,838,695,656,678,499,359,828,601,343,575,140,868,899,836,537,15,795,978,793,326,418,432,779,920,711,572,246,188,183,67,312,354,322,324,486,877,441,611,114,947,993,860,653,684,365,190,920,277,17,225,936,739,789,725,392,710,759,960,709,516,658,113,768,110,917,268,354,171,342,48,690,906,72,303,280,773,776,293,245,332,755,662,592,11,988,537,345,264,483,448,277,215,934,866,210,504,404,792,9,588,727,237,349,350,838,963,271,207,2,32,581,431,92,514,569,232,292,122,677,887,454,180,720,750,23,185,636,825", "700,117,765,130,888,440,278,153,370,404,23,368,708,827,116,374,605,16,3,475,515,316,949,78,861,460,102,906,274,844,115,59,911,918,489,951,782,249,510,487,545,410,310,456,884,477,843,602,384,656,228,159,633,431,720,715,625,11,702,778,887,498,724,299,713,427,224,448,677,441,381,594,599,13,315,719,752,877,953,451,606,442,480,340,150,231,693,382,590,64,335,598,687,667,564,530,819,641,2,405,690,768,297,721,198,192,743,204,818,7,865,206,21,63,805,812,719,402,136,361,492,770,857,868,300,92,893,72,226,240,866,538,489,69,806,686,953,352,207,803,170,182,65,93,968,717,609,146,684,679,527,1,917,72,386,343,885,953,507,853,325,944,948,447,262,463,580,749,722,87,475,745,633,103,788,886,83,362,903,45,392,283,803,155,228,240,785,824,310,72,750,436,216,925,438,184,485,531,405,264,78,452,582,371,736,940,735,289,988,357,737,572,341,731,681,48,258,983,212,504,951,734,644,473,586,532,898,305,694,902,637,401,891,640,319,857,581,968,112,238,56,463,511,969,437,827,379,959,0,427,33,146,383,567,38,851,99,175,744,540,382,682,675,348,434,807,1000,257,85,313,5,863,941,381,953,840,685,130,42,66,384,568,128,971,513,191,451,562,352,251,840,498,433,473,770,482,966,212,485,627,596,902,997,624,649,402,903,6,28,862,174,544,188,498,237,305,144,456,739,66,955,456,344,816,895,14,911,17,641,746,608,982,140,926,235,400,275,580,301,682,123,156,759,47,481,755,453,496,177,985,472,93,868,352,354,308,387,2,780,223,974,154,472,808,961,683,756,311,785,217,693,615,143,850,28,944,110,473,240,667,249,823,83,436,764,452,897,770,819,567,792,264,865,847,356,811,728,70,469,534,891,132,810,911,278,504,887,65,525,653,627,500,548,884,867,61,418,598,142,517,264,44,323,477,281,336,824,531,932,929,345,249,774,313,804,655,131,199,726,798,173,522,185,270,447,967,488,52,191,904,161,75,541,207,646,104,591,615,723,695,784,612,509,398,5,55,589,499,330,658,532,239,980,633,126,449,818,643,301,664,332,577,814,447,112,543,509,955,214,949,393,588,80,223,289,558,415,813,280,695,760,213,370,953,191,447,836,783,181,474,640,142,852,382,770,408,323,983,918,981,356,938,498,89,891,299,949,811,772,861,144,384,401,117,252,206,241,956,853,661,825,515,43,705,592,335,519,651,413,90,161,979,96,937,167,710,918,410,29,754,733,477,187,256,779,422,13,674,194,383,506,82,938,21,753,168,553,755,78,816,341,123,451,618,906,941,482,188,208,721,660,375,946,976,364,493,294,703,730,145,162,807,104,466,803,712,589,97,286,728,259,349,787,62,364,261,261,47,37,87,373,925,152,746,372,525,485,679,580,502,299,976,208,930,323,264,581,986,600,838,806,611,521,57,533,737,237,228,623,611,547,517,613,310,760,487,43,55,971,796,131,288,991,359,939,321,91,832,407,499,614,635,583,751,524,119,779,119,650,570,871,666,907,713,90,37,581,222,108,39,424,888,195,714,270,881,614,481,823,877,413,868,902,411,604,237,520,282,389,53,143,570,855,150,448,900,473,435,880,416,644,643,128,307,17,452,832,3,234,268,638,364,598,718,563,698,24,368,228,887,303,156,349,507,487,523,25,120,200,152,985,791,614,202,147,18,698,55,304,427,508,968,112,243,696,444,181,386,738,330,852,170,115,126,730,434,354,859,960,808,951,206,316,188,404,155,43,117,96,508,59,431,633,320,850,6,9,426,150,631,188,403,394,389,540,903,246,258,430,786,957,368,991,933,927,539,136,171,685,405,998,42,990,743,113,252,697,723,131,455,573,566,777,932,100,694,409,210,674,818,677,997,662,540,108,914,391,825,746,531,610,611,104,683,439,410,610,640,435,561,522,757,855,497,715,4,388,249,89,720,537,156,426,298,395,45,129,409,582,297,603,922,102,540,296,570,371,484,411,27,305,315,387,301,442,179,264,908,365,699,222,239,224,651,186,368,717,535,746,38,631,139,510,162,616,181,756,841,815,504,779,300,998,123,761,586,408,859,184,376,868,86,100,251,190,338,724,30,117,562,767,53,973,502,47,450,469,878,14,713,89,629,837,30,853,955,873,693,906,405,241,361,681,124,356,583,978,22,721,816,364,742,959,185,398,742,467,914,429,712,815,430,689,623,478,844,736,13,277,92,336,404,709,623,860,549,649,731,539,81", "888,501,598,337,276,695,219,578,279,917,26,40,46,643,194,237,18,574,35,4,312,226,444,440,768,766,64,372,550,937,707,974,312,41,711,918,737,797,399,237,346,144,509,828,561,444,470,502,257,28,753,50,504,5,429,468,32,495,403,79,414,262,664,262,321,737,764,594,628,112,203,573,745,20,419,993,812,647,723,424,316,846,116,86,275,759,676,515,287,10,911,763,927,526,656,142,359,515,561,435,186,476,686,564,150,713,61,347,616,508,397,387,327,73,493,218,828,793,866,522,517,851,712,424,326,25,676,269,188,963,556,72,702,702,880,964,685,694,997,352,221,58,660,960,348,927,802,943,468,881,957,997,127,824,924,649,588,479,514,425,181,515,150,303,981,16,159,795,501,824,162,20,732,986,713,261,574,542,106,82,952,291,263,681,720,377,776,799,471,899,464,757,668,660,342,804,883,500,420,641,217,567,585,856,313,421,582,221,285,733,745,768,779,717,372,563,664,958,647,342,473,507,316,663,690,325,268,999,644,975,660,982,736,496,673,235,453,681,803,523,340,699,440,736,259,802,601,833,427,0,252,343,286,849,186,310,234,689,140,797,599,484,667,316,331,246,933,590,590,610,385,979,260,924,245,260,809,175,921,669,838,456,849,766,957,684,304,386,514,936,270,437,813,624,904,1,184,726,405,830,222,703,904,507,798,643,51,654,891,325,114,242,285,189,449,908,548,745,940,545,408,677,988,177,342,912,837,291,671,496,790,9,933,773,789,902,806,859,930,855,185,86,152,428,658,915,861,787,634,438,985,586,375,761,812,746,450,595,711,478,396,180,4,708,278,211,781,338,450,553,870,780,670,396,131,403,364,939,804,751,331,453,530,216,725,292,545,534,263,203,7,49,605,414,67,26,997,961,739,903,189,697,757,916,841,60,530,807,719,999,670,450,884,519,161,756,81,355,60,549,452,144,782,590,191,800,593,720,76,315,507,832,584,402,847,466,249,713,780,540,702,387,442,387,102,492,141,588,884,61,975,345,78,681,430,157,946,939,448,903,917,200,526,762,113,735,110,944,910,277,51,545,419,185,314,782,327,972,161,208,46,642,123,338,821,371,95,148,366,977,885,424,954,498,795,32,805,281,30,962,265,747,388,745,474,701,694,4,492,590,102,445,524,924,193,358,657,883,254,176,798,414,449,989,370,970,920,841,149,700,271,556,681,671,261,390,622,582,602,376,204,173,894,20,133,789,704,169,143,910,448,59,709,742,899,734,600,485,386,123,908,149,945,590,497,176,177,59,966,404,319,814,935,413,248,297,909,810,260,70,141,635,105,667,1,10,456,676,181,657,304,67,519,150,20,381,907,242,312,433,965,792,95,80,532,329,159,104,155,938,654,233,423,724,110,322,975,842,681,667,391,491,355,884,711,240,970,995,880,920,602,761,481,46,908,58,926,322,265,119,762,383,69,770,342,562,739,85,544,849,902,897,883,861,454,424,284,483,327,854,589,488,187,87,146,923,7,816,956,771,940,511,949,254,499,341,455,443,523,3,222,137,692,319,184,316,34,177,807,806,13,443,336,69,910,42,204,684,496,394,537,763,402,663,772,139,854,730,948,535,149,399,226,752,202,554,131,678,896,442,117,733,190,904,27,330,637,683,892,514,411,904,856,94,48,443,828,325,664,397,789,479,790,649,619,600,577,305,298,256,568,884,119,974,60,649,999,380,167,404,701,22,254,956,132,836,285,538,946,291,986,39,827,606,282,17,564,317,953,477,978,76,134,26,474,981,803,661,690,426,357,478,289,191,882,443,708,582,184,720,769,213,940,565,449,432,925,852,441,805,654,599,66,174,372,904,543,164,901,398,198,328,596,71,921,343,194,685,185,792,369,857,950,256,898,94,285,169,398,490,255,918,671,672,936,193,498,301,730,874,81,591,346,736,317,436,280,205,794,197,646,698,271,388,795,558,84,576,338,835,9,635,182,380,602,19,919,671,507,89,591,511,406,649,672,180,685,576,153,375,96,192,580,477,69,351,667,823,167,333,858,990,389,457,589,272,664,465,487,157,137,829,32,973,423,17,387,814,339,40,508,841,815,255,581,308,611,332,490,689,304,6,212,346,918,97,202,225,897,305,703,3,300,281,100,383,663,360,982,453,440,157,843,262,383,322,827,92,919,61,875,714,16,857,934,155,682,448,111,694,642,491,929,658,648,718,981,894,762,476,89,532,664,637,769,526,366,678,487,610,306,662,373,903,158,910,606,210,185,905", "814,324,880,869,684,838,120,286,218,846,751,288,854,647,90,901,604,502,23,193,731,67,113,452,820,296,361,596,963,441,514,164,502,463,761,584,37,847,98,501,116,14,232,248,715,416,255,972,129,661,327,932,386,651,512,335,828,183,387,743,301,223,287,587,972,744,302,422,755,236,698,516,858,609,250,533,46,61,977,284,641,919,385,18,937,911,319,904,650,417,289,248,114,803,661,798,891,540,272,413,453,792,572,313,103,678,747,241,458,228,481,669,155,982,304,187,963,298,107,48,424,409,395,778,208,41,426,740,267,319,616,858,304,474,970,436,104,542,644,489,216,60,500,837,393,647,749,226,800,208,384,667,382,701,763,746,382,879,812,172,908,495,488,618,788,333,481,917,354,530,844,730,796,64,303,671,619,643,282,681,525,10,13,150,55,202,448,912,349,381,292,313,785,425,236,132,647,840,325,865,561,797,371,345,293,196,84,867,928,913,79,136,582,659,916,962,209,740,859,693,939,313,242,882,36,340,695,156,474,823,914,71,841,837,992,304,244,459,764,184,416,431,806,845,232,249,665,845,33,252,0,138,796,155,588,131,724,556,793,351,295,831,210,821,27,398,215,782,96,499,784,131,721,128,410,305,566,157,750,263,30,92,40,228,618,747,188,171,5,160,861,990,311,605,402,391,966,870,575,459,949,260,564,667,513,264,700,523,252,394,495,329,976,489,990,344,445,807,483,505,521,852,818,688,404,466,698,228,17,278,701,456,631,658,575,86,921,827,643,179,867,952,565,682,344,373,910,805,813,488,618,415,742,563,785,487,48,968,345,933,232,743,798,305,928,431,74,274,336,95,574,347,32,40,463,9,858,90,946,869,635,650,888,41,863,49,332,484,243,274,948,278,26,303,365,564,27,720,593,913,176,327,152,334,875,427,905,504,418,264,133,289,596,703,30,923,296,266,198,120,591,982,412,751,369,178,803,63,608,680,510,140,427,852,607,983,741,396,699,164,384,694,915,738,648,539,484,514,735,582,633,713,549,375,330,124,935,684,295,299,583,407,500,642,575,61,152,496,639,423,687,309,317,380,872,128,148,332,498,925,324,27,258,756,716,659,275,417,805,433,608,827,955,616,569,823,690,473,615,187,74,421,963,960,551,645,282,715,372,790,601,859,783,566,100,640,936,590,492,943,676,891,842,955,713,352,358,391,617,842,171,380,137,875,608,436,62,822,106,365,14,828,855,254,335,752,535,440,435,849,547,210,216,894,17,16,19,676,723,560,835,579,927,356,577,576,544,97,850,695,153,541,834,147,577,234,685,354,24,900,414,639,166,648,400,320,883,641,279,231,286,825,670,925,921,732,947,791,454,862,854,997,184,206,763,545,678,644,714,969,625,232,46,305,861,42,112,870,344,726,781,6,62,699,977,352,593,763,350,653,350,489,222,885,951,188,266,828,37,1,518,334,825,17,712,827,599,830,87,454,676,985,814,612,953,222,903,649,221,288,187,591,446,201,506,797,3,699,122,402,599,963,180,539,59,925,197,737,345,816,241,735,966,867,709,286,959,724,619,744,968,559,92,375,953,134,364,220,751,306,998,317,242,282,648,625,323,301,84,939,471,797,346,34,447,436,95,347,191,736,950,558,193,798,733,114,11,820,598,890,301,900,700,411,312,414,448,66,180,97,696,548,493,575,509,238,307,785,692,314,621,644,136,929,844,786,240,164,387,685,439,741,884,429,541,499,417,970,357,62,412,731,820,558,793,293,339,683,653,480,11,709,596,420,508,387,149,898,420,525,433,830,724,573,34,597,955,631,338,753,798,329,348,9,742,573,674,708,361,746,468,817,120,216,327,908,256,141,110,682,149,645,660,742,547,35,603,612,66,584,413,606,268,432,474,712,647,129,262,524,32,428,68,920,589,906,806,189,620,591,82,877,437,327,62,842,789,809,402,207,399,896,875,672,512,430,307,25,778,865,483,980,943,778,363,706,854,624,466,306,367,740,936,866,833,852,434,258,68,628,373,81,157,711,512,556,354,243,618,228,542,528,210,465,194,755,64,911,983,489,214,86,395,104,229,225,231,604,773,548,230,287,42,559,638,631,556,168,729,741,720,155,802,422,550,534,535,773,370,862,920,698,239,5,840,213,506,265,975,769,327,853,317,938,703,908,558,844,432,699,852,238,988,94,656,758,239,203,187,327,317,743,837,833,558,382,630,978,895,866,306,465,913,364,461,190,413,296,639,824,350,688,425,727,826,309,474,2,167,894", "546,264,5,743,916,940,909,636,107,328,700,313,492,267,292,587,928,38,211,288,939,381,117,939,732,287,316,289,993,678,199,991,898,354,698,75,992,74,571,742,761,464,672,750,248,548,945,305,242,59,564,16,81,214,872,353,195,886,845,144,202,787,900,796,583,612,198,753,38,964,161,138,416,126,654,605,414,121,289,427,101,616,306,767,380,195,890,584,545,345,963,839,302,366,587,546,570,18,881,236,782,166,31,810,802,976,643,616,127,712,12,891,295,116,52,163,618,977,593,853,218,102,579,397,893,897,657,611,339,273,835,379,182,923,912,802,111,209,822,330,464,891,875,49,581,604,79,302,974,98,268,99,335,55,822,986,234,928,921,239,361,847,986,67,443,60,201,754,685,282,666,433,512,930,138,649,652,433,484,787,450,913,795,598,519,31,683,423,385,908,410,288,340,82,462,348,457,614,545,815,116,950,963,375,478,547,308,913,129,381,873,878,496,991,831,333,111,850,82,773,611,146,767,778,570,724,627,407,149,801,318,711,996,687,217,416,236,564,759,688,173,247,122,667,106,60,136,136,146,343,138,0,375,145,248,372,887,401,463,791,409,194,289,200,223,259,937,496,353,153,234,239,838,951,582,346,871,497,858,840,887,323,558,248,522,997,604,35,787,61,937,509,630,276,690,808,335,564,448,988,564,540,811,280,426,319,548,621,863,131,682,880,516,261,881,319,348,92,708,666,521,267,268,119,224,520,782,560,580,383,177,466,794,258,460,595,955,366,771,835,881,529,565,252,868,952,240,456,239,164,252,493,248,343,15,58,829,556,736,677,444,922,450,457,310,290,956,838,149,674,893,89,395,791,590,323,797,986,308,12,756,394,389,335,496,595,467,351,154,204,476,76,569,639,343,604,769,873,624,556,133,891,646,730,774,884,662,457,560,433,958,304,602,527,671,694,284,334,698,574,509,280,610,38,435,813,630,891,397,35,11,359,879,622,368,934,58,270,685,16,501,441,99,170,147,308,270,975,982,967,641,223,506,584,790,482,494,320,128,97,587,308,399,868,542,808,130,780,552,432,840,23,514,483,830,75,928,47,159,839,71,314,327,217,122,826,370,931,917,960,610,55,34,879,501,409,852,932,82,236,797,62,435,994,802,391,917,996,27,679,969,37,169,747,828,513,49,519,976,148,667,731,125,801,361,12,612,395,156,531,753,511,817,73,922,252,786,830,568,224,812,955,675,823,511,69,621,363,174,861,783,183,34,920,311,638,363,624,11,699,418,576,170,368,898,98,125,284,690,822,10,263,133,911,495,311,552,615,603,544,758,437,131,206,172,672,85,364,963,173,645,660,497,854,341,259,573,301,49,818,524,55,381,557,752,589,396,74,920,835,617,860,690,697,39,276,104,273,575,554,483,465,484,819,806,647,596,968,892,955,642,144,704,12,387,739,494,873,843,966,599,300,435,287,9,613,794,19,295,777,166,357,304,891,829,221,465,443,490,968,669,696,79,169,331,964,18,690,596,828,146,580,551,137,954,300,24,54,882,188,518,964,107,589,555,794,759,682,706,462,117,545,416,403,138,783,216,440,604,346,159,979,234,691,645,201,423,416,742,388,277,13,716,223,132,635,398,639,428,45,423,268,52,239,471,76,507,209,753,982,392,985,615,452,526,432,659,153,748,312,110,299,989,673,920,989,246,47,864,723,743,300,255,356,983,705,94,758,470,869,791,223,406,290,938,123,234,235,128,795,918,613,623,88,883,33,689,199,322,496,928,583,547,112,173,966,231,292,98,70,809,568,15,380,679,13,642,650,689,593,844,874,634,860,582,789,960,15,94,694,927,599,319,621,4,844,703,927,733,193,376,71,274,33,827,91,641,790,7,329,685,114,462,388,718,259,367,585,212,958,545,544,640,359,655,256,313,57,65,750,397,482,916,635,143,614,765,162,556,551,38,610,499,576,454,407,836,782,639,296,806,751,230,480,288,633,439,704,707,645,309,766,540,965,136,935,889,236,908,645,444,138,917,559,607,580,719,16,521,688,515,993,436,235,623,619,552,112,271,747,853,98,851,303,783,324,57,434,619,535,281,469,363,99,884,235,85,639,332,355,301,209,187,736,831,921,866,798,835,204,11,595,356,9,947,480,36,206,666,678,410,458,635,598,542,667,279,135,42,820,749,605,741,430,683,140,895,430,489,720,753,822,445,542,646,671,865,593,950,214,142,354,263,974,805,633,738,445,178,966,766,260,34,489,310,971,293,565,474,612", "374,10,389,702,343,338,935,400,442,238,179,235,577,626,11,499,56,975,983,265,51,510,960,483,91,571,468,59,71,129,383,851,551,283,98,702,12,408,984,576,826,73,3,343,498,839,964,354,495,456,782,213,65,644,954,765,597,536,285,453,34,191,474,114,690,694,660,177,657,301,481,424,227,270,856,652,247,3,139,124,974,649,430,873,78,149,798,844,685,840,240,596,559,212,4,192,66,821,872,120,406,352,23,876,872,617,72,732,724,146,121,542,674,216,146,949,76,432,850,899,694,743,720,240,74,795,997,588,227,560,70,461,584,176,868,516,135,625,132,127,703,809,349,503,151,58,843,280,767,732,647,869,170,922,295,302,139,619,940,699,751,719,408,650,477,763,874,693,700,835,802,928,929,650,207,793,920,292,494,876,560,161,596,252,34,163,188,447,318,191,632,413,708,700,648,325,992,8,792,421,331,797,144,988,223,845,910,386,310,59,257,15,201,644,808,136,176,148,890,252,312,285,963,416,603,729,520,316,963,866,397,422,330,945,745,552,546,728,935,977,70,888,343,632,789,206,929,304,383,286,796,375,0,558,137,689,748,837,530,13,273,810,660,773,242,72,2,438,264,31,333,960,223,985,721,458,59,376,730,198,968,861,320,281,38,448,825,872,63,317,320,598,625,218,326,491,176,356,788,17,76,999,129,895,162,149,986,337,379,569,866,64,670,75,296,235,338,400,206,177,737,832,845,453,661,578,897,47,437,299,160,932,290,197,842,243,201,121,249,483,480,383,845,361,877,835,865,561,239,309,832,581,668,326,654,180,46,440,367,92,107,492,584,399,57,683,358,623,949,805,195,902,845,106,965,567,908,869,923,655,900,82,944,292,711,429,913,887,55,485,962,976,514,541,721,748,951,568,390,872,721,230,857,57,20,149,894,806,143,867,787,771,523,625,672,235,892,210,701,570,594,656,747,151,665,697,909,479,251,848,942,151,400,914,20,871,328,426,761,717,383,177,752,325,946,135,724,678,859,579,813,458,778,782,306,488,594,19,27,699,386,544,986,745,571,83,455,774,693,791,150,778,645,768,548,528,666,810,708,907,56,441,447,58,811,479,324,635,226,828,401,691,81,976,922,679,260,135,496,746,361,274,303,322,869,579,877,446,282,862,184,962,154,997,949,57,530,328,802,131,307,760,933,689,497,301,603,897,414,171,909,601,247,237,711,269,699,239,287,838,579,896,662,221,211,718,730,2,20,366,570,1,688,290,87,669,474,811,685,850,720,968,221,887,373,688,101,743,933,944,381,310,966,129,232,138,749,209,290,385,196,439,306,138,840,745,408,375,812,131,347,501,213,655,967,99,455,31,384,149,572,4,853,697,199,296,31,155,547,447,134,995,989,674,390,134,156,49,401,88,231,864,340,519,642,651,229,48,636,199,9,663,836,490,931,80,902,290,550,82,613,527,159,226,68,643,905,171,342,264,220,660,802,110,379,99,439,788,749,998,509,376,560,652,103,61,828,955,987,443,268,916,228,991,198,787,607,949,759,406,662,195,210,458,480,188,393,888,562,863,517,210,306,811,286,188,701,371,29,867,809,509,438,144,23,911,66,124,118,436,949,923,520,845,331,177,741,882,613,609,17,602,205,779,678,655,331,620,614,112,975,900,465,775,387,484,692,373,842,811,738,418,791,819,850,512,497,240,616,673,12,8,280,608,381,595,556,666,539,502,786,857,197,372,560,777,757,471,537,637,856,150,926,512,564,313,313,318,421,342,1,224,352,966,797,109,172,955,463,281,609,561,522,627,38,930,388,489,864,905,297,952,847,739,562,344,660,120,358,567,304,875,627,825,291,500,26,366,768,522,113,24,708,871,850,209,807,555,338,55,942,873,731,48,490,165,819,288,855,355,566,785,766,127,714,734,468,527,590,523,164,916,298,71,955,57,626,895,600,738,458,97,47,204,886,470,521,720,793,6,255,583,300,558,96,43,178,645,560,545,825,468,301,400,887,18,880,611,297,240,291,759,121,861,196,673,307,779,160,466,88,964,550,341,606,700,931,925,892,637,304,478,990,491,106,319,977,469,888,205,917,303,920,888,614,161,833,854,68,608,785,888,71,550,390,988,199,867,752,184,617,140,732,841,781,383,755,852,180,93,249,340,386,63,338,463,377,389,247,335,187,637,664,758,217,460,212,575,148,487,522,663,650,279,305,334,776,464,145,767,906,714,981,581,340,475,946,339,833,625,123,951,728,245,296,766,407,251,224,576", "771,538,660,585,55,791,557,68,525,740,956,770,582,616,418,225,626,705,45,37,219,554,45,679,471,461,408,627,970,128,769,599,629,634,798,125,427,107,342,322,202,191,349,810,439,866,888,116,412,376,212,113,606,421,188,423,208,5,113,898,240,971,91,553,706,482,726,500,309,678,657,4,149,86,60,750,8,503,576,479,865,907,98,152,876,232,429,821,198,50,611,627,597,539,253,196,656,713,428,230,552,949,872,129,843,488,746,781,281,359,129,747,930,303,435,100,680,19,231,545,110,535,340,765,815,945,601,724,379,942,282,351,173,474,152,765,790,44,934,7,278,482,825,559,876,63,209,188,789,495,106,109,740,293,592,168,343,942,553,996,613,480,724,726,179,936,520,854,34,635,468,455,44,277,744,356,742,612,772,949,595,232,438,541,891,123,164,55,576,558,369,244,67,395,32,5,762,717,681,80,589,832,570,289,675,765,150,838,777,371,4,601,105,660,292,216,916,84,35,583,42,900,858,357,917,705,794,53,336,305,204,42,461,837,320,18,645,244,531,168,175,286,301,740,503,680,878,805,567,849,155,145,558,0,262,561,162,196,123,45,205,876,263,162,342,258,47,748,279,620,875,132,133,443,21,155,975,649,988,72,369,382,567,429,718,418,161,191,484,237,754,190,322,43,993,783,581,224,566,296,496,574,231,440,79,381,125,892,531,17,338,983,423,382,102,670,746,14,322,541,386,239,752,545,797,824,332,960,229,693,340,355,939,278,809,816,152,512,604,190,670,742,943,427,527,234,786,194,816,103,225,985,863,207,860,308,229,145,80,698,735,685,263,425,956,213,16,912,653,172,783,72,714,276,355,511,642,570,331,382,982,887,846,431,472,248,43,142,921,635,936,327,94,87,585,296,249,866,984,604,687,732,786,705,30,456,596,704,371,963,648,986,150,762,102,971,594,204,767,277,924,932,836,722,986,22,963,541,696,681,273,671,628,442,420,964,559,848,494,169,244,49,490,166,725,535,806,421,651,104,193,208,88,629,937,894,642,682,371,256,233,563,562,373,176,473,759,204,302,377,332,370,44,18,233,686,235,421,115,678,753,213,520,949,795,783,128,414,404,986,865,161,209,310,532,126,429,171,781,612,672,205,868,861,364,777,891,489,733,532,239,359,241,47,75,236,272,300,947,835,820,523,649,766,644,719,790,794,791,462,337,781,415,69,933,314,393,823,315,712,319,950,40,312,486,740,18,111,902,60,508,50,896,434,884,344,564,760,680,321,657,572,876,423,882,860,398,416,228,861,596,409,604,215,242,44,746,418,853,670,999,426,93,221,613,656,272,902,996,617,956,324,980,943,766,292,461,699,284,216,981,944,944,20,820,421,861,23,484,773,969,221,939,181,279,425,75,902,258,231,642,658,356,57,444,909,365,629,390,563,165,291,100,282,267,911,6,382,435,520,546,136,675,530,378,535,679,591,987,918,75,454,587,609,304,876,358,150,174,234,686,388,914,489,653,503,657,122,986,780,448,10,520,722,927,497,869,696,337,957,528,646,375,568,369,408,47,887,16,371,114,404,253,146,483,737,955,627,372,807,903,565,704,105,970,379,828,897,538,595,35,320,791,162,913,11,778,934,431,672,124,363,537,972,775,893,42,229,318,220,809,766,852,408,325,337,167,595,335,502,33,566,423,426,428,305,48,263,707,897,62,400,720,591,489,892,187,50,105,487,860,768,160,911,430,472,693,812,735,59,932,363,6,150,762,750,384,464,28,110,200,940,987,134,928,973,835,193,11,453,386,891,190,413,708,937,192,260,554,418,32,585,751,747,83,3,187,371,446,544,255,252,226,230,932,110,996,737,770,231,660,104,585,370,361,472,483,446,476,793,827,264,235,217,646,609,486,33,357,56,75,840,569,162,612,993,291,189,899,892,161,884,529,161,239,678,138,241,618,583,139,590,945,194,693,634,810,548,153,223,16,94,413,799,196,40,94,367,647,996,416,77,177,47,241,53,875,952,542,758,303,331,719,333,818,71,968,680,791,380,300,609,389,751,147,173,538,61,723,599,950,190,764,971,978,314,915,768,108,735,36,892,43,433,442,796,787,544,906,145,559,943,974,416,90,636,717,740,710,121,588,895,247,785,643,499,888,649,57,690,825,410,8,377,110,297,212,130,127,945,392,247,972,533,167,330,95,102,604,594,947,297,476,791,167,435,572,674,339,627,155,238,528,414,102,293,83,629,887,910,338,80,922,740,691,507,568,509,707,432", "683,808,481,401,767,594,541,607,533,853,955,101,701,561,360,998,433,388,108,444,103,881,412,563,868,265,862,265,655,813,488,230,994,215,263,561,905,397,902,503,478,728,767,538,673,944,883,149,988,917,826,496,733,472,619,463,638,232,349,690,984,153,235,808,373,303,805,916,647,640,927,353,231,925,19,397,630,140,292,212,926,797,522,812,692,881,374,723,252,186,152,249,849,177,219,201,171,946,72,288,160,886,887,757,73,200,340,619,301,846,698,255,191,722,880,997,350,33,425,660,439,611,514,830,536,919,63,19,18,502,609,522,548,637,276,330,758,392,332,898,114,495,121,75,443,575,133,212,969,891,810,402,836,820,751,235,994,424,12,723,231,756,609,737,391,892,280,933,561,654,793,390,76,824,88,726,29,452,204,311,664,864,491,395,887,214,816,188,591,607,550,522,930,695,598,763,334,110,965,255,850,352,147,321,855,578,237,529,337,217,175,105,58,14,413,941,24,642,968,541,658,371,734,244,223,994,724,116,195,376,711,887,579,6,643,685,430,851,259,283,524,972,498,989,148,738,157,583,38,186,588,248,137,262,0,733,827,26,758,389,468,648,45,181,702,24,274,539,578,589,792,642,883,841,920,875,73,976,973,323,751,735,32,393,512,300,736,770,788,621,363,225,794,194,431,55,989,212,880,905,729,849,273,344,643,465,394,125,951,343,892,872,849,653,447,711,555,932,646,203,528,801,941,278,401,180,866,610,301,217,903,585,140,156,569,557,271,718,103,857,436,577,5,641,886,128,615,993,830,491,759,82,439,175,549,650,568,963,132,152,756,67,778,104,939,160,964,629,306,688,118,272,920,461,573,172,395,355,147,529,944,33,402,99,466,76,470,981,798,556,948,745,79,146,88,319,846,715,264,994,685,37,594,144,852,326,656,704,356,544,390,699,325,73,999,468,412,732,487,162,864,90,38,811,87,974,273,564,404,444,245,432,974,270,362,13,599,929,691,312,892,678,237,16,340,652,347,823,659,997,684,163,803,216,848,518,309,675,169,128,634,842,954,994,820,127,131,802,535,768,990,887,430,523,623,646,106,384,633,386,16,423,428,33,943,727,433,846,45,672,240,101,171,721,60,524,582,520,159,288,592,323,670,465,405,306,183,58,368,120,472,565,475,903,126,960,761,335,219,587,708,639,459,921,776,507,569,96,470,54,837,874,824,187,601,74,915,287,999,520,285,385,420,355,111,12,770,47,617,39,259,313,682,302,820,121,502,356,560,450,445,97,626,832,89,25,286,547,286,910,418,346,506,69,184,447,32,295,8,824,703,774,990,6,211,828,242,383,569,619,418,509,288,868,997,538,449,564,269,438,55,653,702,8,334,602,108,391,835,71,301,553,751,265,331,684,295,675,957,216,12,189,324,588,560,159,484,594,801,990,828,179,641,979,97,44,40,374,998,794,274,811,442,339,77,171,782,716,157,77,61,743,398,330,178,359,133,441,463,971,89,860,124,312,365,190,255,670,431,223,481,147,836,897,272,911,856,214,512,294,264,885,594,334,726,226,933,46,417,380,412,899,471,208,25,369,345,860,157,112,617,905,525,757,217,554,41,966,465,598,286,841,545,110,228,218,222,45,906,155,211,99,168,668,638,780,938,742,939,920,289,293,118,843,900,992,856,546,962,475,65,826,953,834,492,518,802,824,632,117,107,820,368,864,730,412,483,840,720,866,728,440,39,548,829,424,111,739,21,693,13,182,72,501,304,547,129,465,6,534,221,235,24,616,624,525,828,125,85,36,699,789,18,672,263,695,435,51,866,110,246,949,443,906,143,602,987,153,701,612,813,658,754,217,752,970,874,409,570,890,644,697,841,54,904,228,440,57,312,494,671,488,839,970,7,693,289,782,964,166,359,822,159,932,474,124,387,560,213,12,778,140,996,330,921,882,352,809,659,211,888,271,431,129,918,755,980,141,446,667,211,898,925,192,388,24,464,889,406,312,700,381,251,50,689,79,446,617,81,578,460,923,994,500,645,869,243,550,559,915,541,956,341,178,321,466,267,663,126,271,804,913,719,976,514,85,931,48,168,309,385,733,280,287,517,455,388,50,617,526,879,626,463,833,605,554,852,847,651,66,116,318,363,85,490,279,946,862,399,645,615,735,284,404,800,352,826,163,752,99,678,155,653,176,766,534,322,593,301,329,262,237,828,765,66,795,531,593,717,793,361,365,365,164,246,436,101,991,266,349,492,712,907,79,301,841,151,923,913,169", "730,114,221,725,754,427,706,755,416,596,732,496,357,860,293,418,382,729,421,108,57,75,406,544,790,655,975,909,724,688,440,285,328,675,843,408,986,120,443,444,521,570,589,273,59,507,977,421,699,643,229,252,278,538,632,167,600,4,41,241,800,9,879,530,937,540,186,379,855,240,677,92,977,511,957,565,521,346,2,615,616,674,603,135,509,75,502,890,555,627,593,311,842,607,753,12,977,550,337,101,174,49,906,270,124,500,782,684,570,274,273,257,9,180,372,977,69,947,424,91,565,958,214,865,562,789,523,798,232,181,988,905,819,738,849,365,240,682,753,624,985,129,926,930,94,849,538,729,794,129,257,846,196,494,51,1000,642,874,899,233,136,611,353,321,668,407,562,3,764,146,214,212,146,609,347,890,981,292,567,719,872,155,432,758,213,732,788,112,132,110,916,700,149,517,911,366,598,488,502,743,9,393,847,527,295,414,188,6,889,565,697,515,733,295,70,149,511,460,806,432,586,605,85,800,749,157,209,898,639,866,576,885,999,307,296,840,549,62,222,81,650,916,706,569,245,418,401,59,851,310,131,372,689,561,733,0,821,14,913,311,651,687,503,737,156,442,799,55,513,401,204,313,395,393,332,721,117,200,578,261,259,761,418,396,691,287,240,270,818,752,443,710,90,867,112,803,630,257,918,749,33,284,416,164,443,862,994,734,139,150,971,591,457,43,560,939,880,745,191,518,576,893,143,367,298,313,484,74,844,679,42,317,494,764,967,626,916,217,109,422,816,186,541,153,579,837,282,573,132,991,204,139,996,406,231,154,125,565,674,478,552,884,737,161,376,930,581,346,193,506,142,541,726,249,483,581,28,936,48,865,552,145,331,324,102,189,218,679,239,638,942,510,635,956,529,903,278,824,632,535,502,72,157,792,560,777,675,558,185,876,475,880,676,81,920,152,943,927,264,401,508,689,769,573,749,148,781,401,859,411,53,428,667,119,753,440,534,965,653,74,620,992,796,638,51,919,614,55,819,510,900,190,696,70,603,646,961,396,763,528,980,859,937,651,474,633,595,837,446,657,887,266,172,952,320,119,276,323,408,136,31,480,621,927,901,384,6,170,293,217,979,592,161,381,542,789,610,957,144,619,260,11,276,713,390,607,995,802,490,702,371,368,87,825,90,455,523,915,414,894,939,672,49,693,223,852,735,501,85,341,554,502,872,788,640,394,18,958,190,920,964,972,313,313,474,568,630,341,581,919,243,315,914,699,298,848,355,188,986,346,409,419,358,705,97,596,440,784,833,406,623,498,432,630,296,725,570,529,645,473,805,191,132,94,818,33,673,184,218,637,751,734,813,506,361,398,314,689,160,693,196,491,751,53,969,330,497,713,542,810,136,351,185,960,940,670,956,694,204,368,261,121,9,472,450,914,151,717,338,237,837,27,269,587,443,279,521,708,770,796,328,640,361,15,625,186,180,206,480,925,190,440,871,600,268,818,44,981,134,440,449,644,329,639,919,275,790,780,146,482,155,680,699,330,153,971,895,201,389,93,838,883,277,589,39,937,161,492,669,978,261,349,387,640,988,300,596,84,649,571,452,122,904,743,218,661,903,770,431,424,247,937,123,630,944,614,553,414,425,197,57,2,252,710,457,924,321,425,621,890,402,459,142,818,350,425,212,101,497,513,653,744,211,895,401,241,658,896,715,587,34,705,8,966,413,137,293,998,61,54,756,274,759,722,178,155,268,978,340,33,828,996,830,162,504,576,386,304,693,362,650,584,821,555,519,725,279,204,938,842,806,963,645,624,275,431,711,523,217,332,913,968,992,15,328,875,377,893,322,347,122,75,337,892,28,677,35,70,308,121,925,974,39,903,321,368,495,450,294,19,842,270,264,636,79,977,125,853,823,311,786,224,932,147,409,977,600,296,216,84,458,602,408,61,582,641,512,880,993,510,424,370,486,888,163,701,605,789,89,157,971,68,60,347,447,609,713,542,240,342,642,874,676,34,535,478,807,35,108,541,611,670,988,323,53,470,997,827,70,365,82,941,736,916,464,842,443,699,955,441,782,234,404,954,890,891,308,803,89,290,205,180,665,144,816,235,631,479,708,743,201,533,649,964,721,247,419,529,231,337,374,560,389,424,802,463,643,898,375,3,462,648,424,84,589,609,188,656,754,77,625,268,779,942,19,715,381,311,80,550,407,874,980,930,795,846,821,620,18,577,29,435,912,193,780,281,257,511,256,144,903,187,909,995,217,937,577,923,407,776", "478,389,771,478,289,825,587,853,212,377,322,492,398,764,966,113,179,701,254,696,882,432,156,981,220,752,211,552,769,697,440,992,708,934,124,916,865,151,541,165,174,883,829,442,776,960,64,917,378,524,566,496,395,861,51,632,383,731,380,409,192,534,557,171,1000,84,589,49,973,428,207,766,151,514,308,626,66,434,842,217,807,507,649,646,277,429,486,147,952,18,178,519,356,297,976,645,786,112,142,537,551,947,56,743,647,312,935,953,366,271,889,850,557,810,971,832,975,937,166,12,791,330,23,168,452,283,575,251,886,568,44,719,781,425,599,982,763,297,47,995,120,37,670,601,746,722,174,613,349,796,740,978,787,308,169,502,147,722,568,285,615,669,727,705,302,239,756,443,273,309,449,151,436,731,700,73,282,665,876,451,495,284,377,394,822,427,335,51,197,998,838,420,278,269,956,952,565,143,602,895,683,745,614,82,385,606,714,887,116,820,326,544,66,118,485,604,8,643,165,823,384,530,960,936,467,211,523,166,80,642,658,392,902,544,904,138,904,583,717,3,509,182,798,925,334,151,179,47,99,234,724,887,748,162,827,821,0,200,760,986,329,255,239,178,241,427,567,944,233,108,831,787,463,639,86,888,487,638,154,422,608,355,118,108,290,864,990,331,713,234,559,285,697,179,497,579,919,729,749,520,874,759,696,578,264,540,239,447,252,946,244,4,269,760,341,812,979,902,524,317,83,206,344,821,545,744,357,295,161,558,270,189,902,500,189,973,822,590,551,919,512,808,848,214,469,993,483,360,464,523,680,500,418,956,970,20,701,341,639,927,295,906,714,707,62,82,481,492,982,169,89,930,472,333,171,111,367,453,349,831,72,875,105,923,980,965,174,208,301,62,54,225,450,309,643,262,325,721,378,224,790,480,782,338,678,230,951,607,405,241,200,230,425,376,960,621,948,314,622,558,604,901,654,464,869,371,289,129,393,759,936,251,112,300,753,67,897,311,325,829,382,602,45,815,959,297,248,255,134,969,117,660,765,207,94,227,708,796,361,471,130,103,807,732,84,404,184,827,712,889,912,125,906,156,9,762,830,349,933,61,650,895,226,812,312,566,617,304,350,376,854,184,911,306,408,576,748,261,352,349,320,658,754,285,616,601,576,14,676,848,710,9,720,493,222,171,892,385,883,300,347,711,157,602,745,508,347,122,758,757,95,547,768,42,575,704,395,741,748,30,491,632,348,845,540,697,209,280,50,817,741,94,809,206,590,657,17,556,452,674,962,194,54,933,584,14,411,150,873,535,200,220,233,961,798,813,496,788,109,739,213,775,611,134,283,744,687,775,676,318,684,52,685,811,648,717,629,326,234,389,686,628,680,949,78,678,486,325,994,16,190,866,372,205,908,577,588,86,5,9,405,749,831,373,607,96,927,210,768,477,813,350,358,989,99,968,756,378,10,647,879,954,105,568,215,16,961,142,243,581,429,225,207,762,409,505,74,976,324,130,735,379,493,508,404,85,852,28,816,655,128,171,896,530,886,998,129,818,572,19,627,562,501,473,618,132,164,531,846,347,364,282,205,213,321,801,869,146,660,450,841,87,269,347,503,250,652,252,201,421,214,633,121,543,45,236,197,352,86,248,287,372,188,396,143,110,108,858,179,618,572,741,874,582,258,260,724,112,291,543,961,473,362,808,250,355,35,841,507,512,525,149,201,908,235,711,273,720,418,956,39,48,168,271,31,461,80,867,311,564,871,142,707,546,757,476,827,907,593,811,814,750,943,43,570,996,592,197,493,536,59,516,349,707,841,908,721,261,250,236,982,366,234,285,936,401,188,932,125,827,236,927,989,458,216,644,306,286,746,315,810,196,815,55,151,39,103,778,129,281,306,472,110,526,616,332,30,348,674,482,182,217,965,67,668,278,657,152,946,856,786,197,990,577,469,3,730,542,786,661,603,405,781,79,573,884,837,624,623,682,51,271,347,43,520,23,917,720,609,880,383,547,141,811,709,740,294,502,327,868,384,131,23,653,916,642,999,641,406,228,61,666,58,982,221,503,311,81,531,199,811,637,570,74,531,58,411,286,67,771,396,894,931,432,720,742,295,635,475,558,22,420,574,517,988,474,314,65,912,279,952,440,204,545,69,748,549,387,372,771,56,995,27,465,315,755,124,544,835,190,801,192,766,724,49,231,36,434,469,999,669,814,384,737,301,60,924,757,753,886,416,734,599,67,700,949,737,10,657,349,169,235,947,590,967,514,58,992,561,105", "446,563,398,889,190,688,419,301,222,188,865,7,928,38,373,211,458,76,540,496,461,219,899,381,395,716,117,131,247,438,5,158,347,700,800,843,737,254,65,695,217,699,671,502,307,391,326,464,991,6,543,48,453,918,851,144,865,706,48,738,44,112,499,204,678,740,801,780,826,808,385,114,201,739,651,798,991,902,65,788,26,269,652,857,367,101,241,802,175,667,32,367,690,944,49,236,654,459,618,51,205,991,463,46,83,296,932,738,354,602,436,56,761,181,987,310,581,699,96,374,212,59,880,319,876,484,438,641,940,189,207,967,592,317,158,432,429,312,265,73,578,260,898,977,111,524,907,170,102,289,527,437,840,351,168,560,313,580,461,562,705,65,536,379,543,605,329,809,313,218,119,57,190,62,583,358,915,491,132,902,833,680,121,770,804,777,485,70,38,191,909,258,427,705,521,197,546,730,969,207,941,230,312,815,521,7,208,676,786,565,266,751,856,534,297,416,710,316,340,157,998,303,311,98,91,45,92,608,737,973,845,570,854,113,528,448,574,511,38,487,23,49,902,674,288,469,409,854,175,689,556,401,837,196,26,14,200,0,927,900,446,980,911,143,822,336,526,99,129,885,446,621,432,317,196,175,672,124,301,539,523,977,924,118,171,341,448,187,81,87,798,541,947,398,872,754,758,414,761,842,985,920,141,542,351,388,657,284,503,968,436,87,76,651,10,573,617,656,268,512,761,850,55,748,799,376,74,771,144,189,265,544,84,772,862,438,544,387,435,647,770,182,245,732,564,758,824,264,416,420,9,484,457,894,923,90,787,571,624,388,233,637,995,150,435,581,565,180,642,990,835,1,532,265,464,411,722,654,606,880,207,406,962,27,877,601,956,807,546,57,879,139,897,443,883,390,936,160,724,387,112,651,722,469,623,345,519,324,988,39,416,981,188,782,230,124,645,497,391,37,816,559,742,368,788,74,323,107,378,110,17,205,103,456,352,628,983,244,712,577,325,502,181,829,624,288,541,751,893,40,430,963,903,601,391,609,932,989,353,803,203,313,135,159,95,999,353,97,843,940,998,505,857,197,144,90,309,947,485,469,721,388,895,651,834,49,847,40,808,379,280,841,656,6,709,990,782,189,572,641,905,429,86,921,130,561,40,965,251,197,377,650,192,407,842,118,825,226,156,228,451,409,356,862,711,54,861,922,120,589,339,824,832,660,703,772,391,981,991,100,466,129,497,185,629,996,321,884,983,64,675,833,14,542,286,770,865,905,657,675,577,569,11,836,426,448,354,820,949,288,32,270,180,11,741,319,535,152,648,33,696,807,233,492,151,458,308,479,291,614,666,608,109,560,692,101,242,437,687,194,203,411,529,508,352,689,83,592,191,394,379,319,768,281,636,857,447,425,773,853,429,575,291,902,787,553,538,641,465,143,928,140,339,633,702,836,616,757,850,700,384,569,551,946,638,830,9,760,376,768,680,25,252,210,967,691,231,849,104,967,675,730,138,216,663,652,642,607,300,236,266,243,78,295,22,964,709,249,719,569,689,228,959,247,285,555,246,665,132,346,87,665,905,588,253,554,702,752,239,203,404,972,541,557,17,711,182,525,43,438,134,229,740,486,80,137,27,120,418,120,667,1,912,742,64,298,226,273,811,427,547,456,960,822,630,646,793,319,48,125,382,189,629,888,919,739,514,115,78,317,654,724,106,882,936,832,941,142,112,550,609,331,708,832,473,698,363,273,612,259,107,486,604,277,98,72,898,660,974,279,297,65,173,597,879,958,152,461,87,231,947,95,99,838,919,702,735,359,88,661,168,401,796,905,791,296,817,367,773,164,603,845,350,113,112,234,908,879,67,464,456,668,617,909,353,910,40,896,534,315,72,878,476,746,468,47,276,988,605,340,679,241,929,511,785,594,908,764,286,708,742,962,311,167,565,903,588,471,10,569,442,471,475,981,105,616,791,273,728,407,268,908,108,822,385,934,426,358,26,472,934,26,846,953,681,559,388,403,26,507,823,792,460,278,809,78,739,242,362,982,946,728,806,841,67,685,648,66,400,452,38,647,681,3,705,29,853,346,824,627,607,635,105,960,17,715,96,960,397,119,868,505,376,216,87,456,161,911,676,326,875,787,810,687,716,751,181,463,982,601,390,922,513,339,892,424,809,615,526,35,379,688,854,576,819,287,958,129,979,907,866,243,226,256,474,889,359,776,852,579,783,139,460,893,987,243,553,644,416,832,746,418,167,566,435,730,463,919,413,184", "456,375,304,796,185,535,755,494,225,313,592,867,755,459,489,156,978,538,947,664,591,443,873,809,550,377,918,62,628,601,680,858,324,572,41,515,268,307,240,466,732,746,994,130,379,601,999,233,360,219,373,426,781,703,765,871,487,868,779,836,178,247,601,914,413,442,158,904,221,645,110,333,209,99,254,155,42,424,363,932,138,275,875,744,779,664,997,239,622,628,634,966,160,29,584,637,127,303,862,103,710,404,813,8,404,133,792,815,589,170,91,22,547,40,702,15,147,725,288,905,856,75,645,311,626,568,445,219,814,5,201,773,997,178,618,445,565,236,236,814,238,192,844,726,615,630,179,697,387,682,624,954,994,234,405,98,11,691,564,567,872,140,676,106,691,460,8,623,301,340,588,237,356,675,448,693,493,762,540,22,667,810,131,659,494,547,216,32,162,431,348,856,113,528,859,407,988,446,489,932,965,830,567,845,392,808,989,736,831,515,79,196,575,528,949,466,944,723,911,231,774,451,288,221,310,980,111,664,432,39,215,806,996,784,400,919,938,486,518,657,680,1000,730,465,640,571,99,75,744,140,793,463,530,123,758,913,760,927,0,757,414,540,762,48,408,602,628,891,110,82,27,463,573,521,644,255,721,972,95,13,261,383,893,279,378,213,27,296,241,807,363,240,532,447,56,7,782,367,504,930,70,340,520,974,712,164,386,462,262,672,930,491,774,604,150,984,541,234,144,296,951,953,513,680,556,7,622,936,433,871,946,537,698,78,408,690,751,178,743,981,628,627,986,756,926,935,551,80,883,89,453,906,64,505,544,425,148,996,413,2,67,66,553,274,149,890,482,660,29,391,512,725,244,644,536,348,384,903,316,702,865,997,473,276,809,275,818,677,911,871,932,32,600,546,215,569,424,621,880,290,745,258,505,6,456,897,868,450,367,342,767,280,525,980,421,593,925,135,753,791,336,290,951,124,140,877,167,918,995,420,403,280,801,401,602,731,25,3,760,19,627,27,248,404,827,900,297,540,705,465,170,916,350,793,157,637,638,768,834,835,507,323,18,865,882,391,907,646,201,500,312,93,94,596,739,762,877,21,853,999,476,804,776,687,81,441,15,345,916,561,160,172,986,682,322,326,951,347,640,602,383,714,418,785,982,15,282,275,54,764,518,652,743,341,512,218,748,39,264,443,972,679,788,794,227,256,921,827,777,701,604,386,735,44,954,42,897,273,704,178,298,217,982,438,971,32,271,56,300,807,106,214,707,528,502,864,976,797,145,312,798,23,115,697,988,545,856,866,72,328,862,959,890,525,401,865,712,257,505,909,767,555,403,514,624,673,594,172,240,826,532,819,463,238,76,792,685,392,408,227,831,451,622,359,93,92,522,473,235,169,715,611,690,87,276,521,31,231,198,526,959,808,342,452,212,474,859,133,860,916,487,859,235,725,562,260,893,223,442,699,604,909,664,108,909,55,566,867,718,888,68,154,504,953,873,450,553,2,969,959,419,165,499,358,911,603,653,326,108,299,674,286,949,784,691,848,975,17,101,2,756,216,447,492,993,374,226,22,455,634,210,482,519,278,888,460,142,858,312,992,141,362,992,180,850,972,243,380,287,202,417,345,678,260,513,14,342,256,233,699,102,566,539,51,107,947,866,40,253,925,632,990,937,401,162,710,814,527,270,242,301,766,376,184,898,659,167,240,68,554,619,999,795,223,14,739,543,674,419,25,32,634,859,481,939,720,663,409,856,876,982,784,343,893,173,264,144,243,613,581,414,134,317,780,170,34,523,18,67,453,311,669,767,620,187,241,90,804,311,347,591,717,744,739,642,482,239,349,805,920,929,433,57,113,889,858,763,305,246,198,509,587,713,660,816,986,227,29,710,168,684,204,847,1,348,369,997,238,875,921,511,55,191,385,751,322,128,208,214,641,79,159,802,752,567,862,537,239,816,515,6,917,111,263,942,518,428,765,129,814,39,202,107,278,77,925,112,662,234,283,388,246,400,117,89,699,146,924,285,52,230,228,641,776,847,543,524,946,681,603,833,521,342,766,424,353,593,772,461,288,981,585,168,78,138,749,354,511,949,746,716,898,505,934,597,712,78,413,307,206,600,173,836,777,239,724,733,165,944,579,526,643,997,186,62,325,349,457,167,77,784,219,477,381,595,445,446,658,497,608,821,358,782,453,643,159,414,626,314,246,453,487,280,444,450,360,771,236,410,446,502,175,191,963,785,198,804,559,937,950,274,364,414,613,750,26,818,679,185,181", "447,421,816,244,906,185,576,359,349,234,89,627,604,285,668,283,771,956,513,960,370,575,657,543,580,244,847,540,541,187,79,32,160,571,973,923,717,418,253,683,267,116,453,458,603,922,979,256,767,789,198,435,804,355,535,698,936,432,558,389,743,964,891,333,242,330,89,397,299,516,651,596,720,787,538,864,952,43,651,767,154,840,966,401,454,266,760,668,704,245,253,471,755,78,742,363,90,120,985,519,192,49,145,732,813,673,898,113,797,596,206,832,562,381,695,847,249,976,867,67,654,99,261,245,853,848,429,170,433,815,126,821,311,349,150,921,178,956,589,508,432,682,87,498,794,657,890,328,366,388,860,302,241,755,722,794,858,612,645,837,365,198,100,886,485,448,18,627,26,314,174,739,691,273,996,431,82,919,740,586,130,873,516,561,137,271,864,963,456,843,730,351,536,784,488,100,392,291,739,46,527,866,258,985,764,128,646,76,708,526,40,371,365,987,584,415,255,528,780,610,89,609,327,677,864,466,415,592,364,603,634,293,71,138,35,482,866,158,296,208,20,651,452,772,298,11,85,693,540,797,351,791,13,45,389,311,986,900,757,0,993,796,945,995,728,747,543,417,41,802,378,694,362,63,134,732,296,640,740,458,189,45,947,823,262,335,198,65,819,682,795,734,763,80,64,619,329,779,37,774,556,381,72,532,576,640,647,124,23,784,552,776,344,505,522,381,176,907,304,188,325,317,590,413,574,688,257,737,603,450,670,77,232,730,105,772,60,927,518,246,172,264,929,84,521,260,123,356,327,736,343,954,312,884,482,266,131,376,717,611,223,143,115,875,321,807,995,898,403,1000,374,29,109,31,788,29,676,655,542,35,885,906,102,795,848,240,338,845,952,412,102,947,363,827,464,328,898,55,219,943,459,270,783,395,858,719,885,863,319,594,893,610,457,808,520,192,97,379,800,75,944,857,396,978,463,799,870,56,61,400,301,689,19,793,286,444,467,620,316,867,591,548,319,393,862,882,684,607,97,736,278,869,348,463,378,98,916,868,190,499,527,898,386,689,112,614,896,686,361,438,80,323,699,312,385,341,497,223,16,155,101,995,615,566,852,97,166,884,318,20,902,50,73,626,264,120,565,653,346,77,888,303,323,799,471,904,460,146,146,407,230,440,267,414,700,379,952,905,103,707,584,949,15,179,123,409,452,885,474,878,846,642,463,964,378,629,235,690,909,885,69,613,365,137,547,685,725,182,7,963,339,501,238,140,208,217,934,68,959,148,420,963,908,890,567,265,207,680,95,701,868,79,597,274,101,100,276,914,231,994,849,532,389,425,601,666,402,260,299,263,971,315,878,62,211,164,266,539,594,659,657,458,217,545,648,390,26,365,916,914,855,527,555,124,627,29,260,959,790,394,796,515,957,447,642,89,754,322,137,318,819,809,909,206,652,656,314,489,889,108,637,930,107,382,732,2,308,33,463,681,776,230,507,94,847,380,733,713,99,945,945,889,581,524,464,390,976,796,145,944,208,925,207,48,201,391,708,244,275,722,616,874,747,686,627,903,269,164,741,450,546,652,925,114,313,352,747,731,273,669,49,233,887,614,144,926,423,189,317,186,336,519,837,794,208,345,258,39,374,149,703,945,697,739,733,172,995,549,670,630,853,104,614,462,363,990,362,36,932,96,449,286,286,874,30,137,147,591,127,943,974,691,835,982,509,809,262,372,922,206,792,696,383,522,465,180,730,419,887,391,116,802,8,380,896,334,801,888,261,810,746,580,946,207,907,331,509,522,950,892,978,89,366,406,252,631,679,559,562,985,415,489,322,242,876,437,194,31,312,499,106,200,430,97,484,598,641,386,781,851,72,507,182,916,54,916,192,170,345,91,999,19,630,274,148,550,341,348,866,820,679,367,388,256,546,374,507,872,814,297,579,568,34,144,64,745,865,696,283,439,221,571,527,984,570,573,959,416,386,903,265,765,715,853,984,252,700,603,107,940,454,220,502,125,859,431,174,310,918,65,386,679,476,775,349,76,673,383,669,145,235,80,494,120,259,838,112,804,650,857,164,827,943,968,990,517,980,907,879,131,202,438,716,573,277,228,42,370,907,261,90,662,137,288,227,201,454,396,356,292,472,182,454,868,962,133,126,563,499,445,879,930,318,50,717,866,994,900,365,493,390,303,144,308,950,557,729,992,556,309,393,928,314,538,654,336,452,908,303,685,129,343,580,359,22,556,585,989,880,1,464,260,336,564,744,856,547,448,297,572", "369,267,918,310,463,420,642,193,213,928,131,968,890,35,285,224,671,56,27,531,74,559,179,455,625,938,34,978,48,154,338,248,462,374,341,773,245,832,367,473,988,177,876,568,501,828,499,264,492,485,825,159,854,222,379,423,915,881,678,549,112,702,494,462,4,812,564,52,458,48,807,670,72,452,368,635,684,812,838,859,429,424,442,178,797,51,9,680,379,424,281,284,545,641,155,653,162,188,496,240,61,460,978,876,948,215,907,193,694,898,191,874,169,514,668,370,744,216,584,682,710,614,333,348,188,446,142,17,847,430,519,839,332,349,483,718,321,18,995,40,392,732,794,458,914,306,317,230,816,901,115,337,486,494,357,56,850,894,866,113,380,431,547,37,525,936,655,581,651,522,562,614,466,274,999,45,368,265,106,744,111,676,328,617,786,851,839,386,830,974,141,925,225,561,805,846,245,172,965,929,446,759,856,323,173,499,193,653,111,885,970,434,917,846,585,171,104,966,125,72,365,246,967,145,694,26,140,900,267,510,839,763,464,145,619,778,745,301,321,82,883,401,72,803,762,564,364,203,382,599,295,409,273,205,468,651,329,446,414,993,0,64,942,323,599,683,840,432,789,447,237,293,529,378,353,886,859,847,23,363,562,860,643,292,484,244,628,689,687,752,356,833,545,162,752,577,56,383,470,417,964,308,310,351,778,756,85,7,700,511,524,407,338,614,626,874,677,878,687,303,252,191,284,965,535,7,151,856,757,986,857,169,760,657,281,927,799,541,147,825,581,245,406,54,690,95,88,448,267,714,657,821,940,767,554,864,609,823,242,68,951,818,757,104,167,535,626,538,518,446,59,298,525,486,793,971,199,193,334,55,313,936,117,155,826,42,595,248,271,333,305,992,70,402,674,31,572,759,459,836,340,954,167,793,248,354,691,956,847,828,286,548,979,491,301,213,651,325,461,629,166,774,364,880,666,303,943,788,785,273,506,67,145,800,794,706,136,30,524,961,597,836,18,833,659,344,789,924,909,524,187,877,202,913,101,291,178,912,595,777,272,141,999,32,227,107,186,323,915,705,741,74,199,550,489,53,355,604,227,344,692,79,163,30,424,774,115,572,923,284,308,293,952,879,87,352,761,358,560,833,27,979,646,229,274,733,391,906,316,993,104,798,487,543,807,279,17,690,702,976,698,711,889,407,523,445,458,513,615,644,518,167,979,322,99,392,869,112,765,69,579,566,611,67,262,889,77,859,816,939,684,258,81,177,945,85,672,134,825,834,776,938,835,338,224,496,251,64,418,178,527,727,673,392,299,46,351,591,969,102,481,40,619,780,237,189,487,729,865,715,925,595,741,400,151,410,493,542,183,800,870,10,71,542,211,829,180,202,268,3,696,84,537,324,776,983,493,607,907,234,889,547,962,858,984,151,73,714,804,809,637,596,146,812,566,730,780,261,364,940,167,318,436,241,988,269,442,562,884,505,942,185,783,735,87,68,86,596,486,287,48,440,397,113,750,876,297,95,339,453,21,411,924,47,788,400,431,721,424,869,935,310,708,571,15,682,855,214,527,442,839,245,935,722,473,895,787,507,943,201,545,411,310,477,802,25,984,171,324,597,988,194,140,253,498,631,654,517,393,125,671,543,176,449,845,248,944,867,263,192,830,273,782,263,767,782,62,737,702,628,86,51,105,314,803,735,304,450,10,954,521,199,445,542,569,125,172,472,785,238,928,71,367,818,42,450,924,575,712,391,603,677,775,206,980,250,201,15,87,592,898,668,984,213,818,695,500,847,805,92,661,565,301,727,380,393,780,426,570,166,732,987,551,545,295,168,535,834,1,886,303,655,335,439,516,487,785,607,298,655,969,873,636,854,396,325,667,94,390,218,159,659,482,557,777,965,284,22,999,712,604,789,242,936,355,80,323,447,188,287,99,642,451,83,780,600,334,812,725,3,879,976,566,329,173,694,863,466,344,766,429,333,581,3,725,443,793,324,885,121,174,840,581,436,768,418,944,95,384,903,69,219,739,83,869,717,986,337,867,774,50,599,753,706,540,348,873,538,634,431,826,413,904,833,20,830,881,261,383,775,814,564,430,898,130,375,864,262,264,944,991,423,24,743,37,701,697,856,579,251,36,323,846,598,298,993,999,891,661,875,745,740,128,566,866,563,399,768,960,607,175,127,545,612,713,835,315,746,635,611,145,87,91,433,381,242,35,398,346,179,337,138,344,417,526,89,6,730,472,308,620,670,280,448,148,607,623,650,85,598", "727,265,372,251,10,307,363,11,352,472,242,424,723,225,671,672,749,207,487,80,225,892,933,305,11,404,210,697,275,819,161,793,870,382,396,262,712,407,778,104,502,647,312,779,552,419,268,888,160,813,709,670,66,708,432,509,584,587,266,893,576,542,387,440,941,979,432,836,745,410,986,985,892,47,469,525,392,107,669,641,155,591,530,522,775,275,739,255,623,898,97,228,154,895,463,683,506,473,423,360,974,494,815,220,235,21,183,544,206,268,377,420,971,43,974,878,340,693,77,834,793,547,707,548,98,431,421,130,225,192,874,598,226,835,587,23,12,260,428,777,339,10,368,739,151,389,81,266,632,521,320,898,23,640,411,144,41,280,158,495,32,347,666,994,494,110,777,532,364,998,835,369,339,791,739,635,974,777,912,58,936,949,324,958,768,269,185,826,891,701,82,350,306,833,473,950,621,558,575,47,800,472,908,98,94,546,977,282,75,383,112,852,187,698,791,925,127,784,50,282,108,847,650,994,985,992,434,95,664,748,285,573,599,548,482,976,156,52,677,167,283,225,271,861,874,219,369,693,682,484,831,194,810,876,648,687,255,980,540,796,64,0,65,338,847,373,913,767,231,340,237,251,387,735,693,981,356,809,780,741,999,33,463,765,267,160,87,734,549,781,257,130,94,20,950,393,983,4,630,555,893,701,124,970,208,175,561,925,908,621,898,796,635,42,194,197,639,386,667,665,520,447,457,137,315,10,811,804,705,570,562,764,470,513,908,206,659,306,735,966,500,173,401,952,434,886,776,444,226,595,740,11,580,340,472,482,793,293,805,873,869,342,453,190,313,518,738,550,369,705,585,908,620,37,54,143,458,430,317,160,294,683,411,59,970,925,691,738,482,542,92,38,556,115,897,741,617,489,900,933,221,827,520,983,899,649,468,172,110,543,177,669,529,541,782,418,660,938,246,54,186,464,724,73,164,995,539,132,884,125,419,257,799,989,99,755,113,822,637,787,125,671,835,71,240,988,403,97,40,590,640,594,959,419,651,780,468,904,180,520,525,363,789,772,114,883,102,929,726,509,715,319,800,251,259,952,652,340,556,854,557,28,81,603,631,174,370,636,941,878,555,904,717,738,442,781,210,105,132,969,810,7,704,16,901,896,406,79,133,304,895,258,99,611,245,283,778,796,280,88,497,990,97,670,306,659,721,428,962,379,226,70,509,783,941,384,310,110,96,715,851,911,217,395,925,933,585,274,271,446,278,52,344,32,902,13,724,162,128,413,42,683,350,831,219,628,815,414,327,588,926,950,574,137,837,967,77,155,300,398,929,6,929,560,128,508,630,792,294,430,870,517,228,220,171,976,669,286,343,452,147,391,960,587,652,227,869,520,676,698,405,463,404,973,103,247,406,797,228,193,428,54,678,246,737,597,812,982,388,795,773,986,875,575,542,746,256,68,695,178,438,764,45,440,83,732,61,292,881,416,342,862,624,607,677,127,298,530,916,151,448,707,652,709,278,896,57,962,290,179,398,300,746,500,926,103,538,714,675,919,417,903,677,826,681,951,964,278,517,221,628,395,346,56,528,312,672,646,916,33,982,719,560,536,13,788,938,421,517,966,889,825,783,638,439,600,509,279,353,832,96,400,304,196,985,847,174,148,193,848,433,880,933,50,275,620,830,821,667,303,909,195,173,32,195,985,848,933,450,1,960,443,572,420,528,879,816,157,15,860,286,990,180,995,470,198,893,784,166,394,262,928,48,750,771,985,877,487,996,668,919,716,69,378,486,129,874,661,27,473,151,33,48,314,848,254,924,405,542,19,127,819,859,692,15,269,448,871,275,858,931,511,329,298,739,801,501,622,928,510,287,832,171,413,333,79,968,279,767,237,521,13,459,615,785,728,252,238,577,254,908,475,285,546,513,843,802,735,325,833,593,941,271,451,931,174,191,283,176,241,384,776,890,341,765,808,527,557,572,256,566,351,599,536,351,993,786,906,164,665,224,783,697,366,449,527,986,169,804,341,953,481,755,29,56,778,279,603,576,40,31,93,729,844,805,358,256,637,435,817,163,608,519,89,502,585,93,105,305,61,395,862,142,328,546,952,973,272,557,562,119,40,942,995,756,574,573,984,923,256,78,469,148,269,64,153,75,900,188,549,731,726,621,890,360,353,888,464,506,1000,974,454,901,927,891,518,877,786,10,333,680,237,382,700,713,144,920,989,96,22,917,566,395,690,365,917,338,699,787,202,558,96,860,13,902,649,140,136,549,807", "258,554,353,484,235,834,387,664,213,832,656,60,30,932,95,408,109,950,75,420,832,880,804,935,229,47,776,958,357,718,809,91,910,15,189,683,221,533,432,920,509,121,481,188,977,384,457,304,396,513,706,752,762,650,170,133,136,141,987,216,988,694,977,569,625,976,437,432,910,896,989,680,553,853,743,148,460,325,760,780,929,616,665,41,439,324,880,34,86,894,47,619,192,193,48,973,637,152,978,841,565,973,41,820,151,795,21,396,127,11,460,444,393,413,145,278,442,56,523,273,38,660,64,478,924,723,904,467,812,224,116,144,29,84,950,845,283,256,265,414,153,413,425,807,791,496,315,411,763,719,95,301,93,240,3,473,494,296,886,968,898,450,641,314,214,522,453,93,121,65,158,200,602,750,747,631,545,250,645,37,869,578,294,127,292,802,857,907,47,346,601,532,872,51,338,169,157,601,588,153,874,470,706,36,736,666,902,298,523,944,516,650,6,611,265,92,128,664,870,75,656,369,862,598,424,538,990,875,513,352,615,639,289,588,10,973,605,12,335,621,549,606,996,293,775,622,725,462,675,667,210,289,660,263,45,503,239,911,762,945,942,65,0,641,92,113,625,707,625,702,632,490,65,167,472,293,825,550,45,59,339,238,456,874,722,115,922,372,414,898,374,374,76,797,787,841,80,182,687,908,138,334,127,361,592,859,721,267,21,185,557,823,969,669,97,556,418,553,29,160,351,883,564,760,22,609,817,813,593,135,425,485,859,624,789,670,652,484,514,236,187,208,959,447,220,435,467,783,202,747,992,449,583,773,760,64,571,606,657,955,202,224,869,103,187,939,371,634,640,935,79,389,986,642,550,42,635,931,463,675,433,129,194,566,262,643,860,346,595,181,633,951,77,756,601,750,813,797,307,629,568,844,665,198,748,15,164,984,777,631,809,248,903,158,671,619,614,65,719,971,221,385,320,412,774,808,374,529,236,303,127,515,926,76,887,675,453,293,162,959,563,852,20,303,299,495,933,647,168,752,346,243,893,985,692,660,464,140,859,69,194,613,409,62,577,796,360,823,737,77,729,448,407,152,662,448,198,861,389,702,849,487,79,943,166,837,678,896,558,117,906,666,273,524,925,924,890,550,333,457,11,541,909,972,957,926,183,251,285,945,84,701,113,141,887,375,855,715,744,453,338,680,171,102,600,837,91,839,883,626,100,668,503,424,453,756,796,882,238,939,333,830,795,919,468,795,203,722,43,652,72,816,29,685,718,50,880,394,140,536,668,111,271,93,845,53,158,10,308,687,345,859,468,314,920,749,522,751,393,723,38,167,472,248,309,674,284,904,344,176,38,654,435,782,40,597,647,800,422,873,172,420,65,143,766,31,197,33,495,125,169,823,75,639,840,387,864,19,495,343,654,745,763,384,262,644,494,129,322,880,816,664,308,71,432,829,772,934,133,648,995,228,992,603,485,130,230,335,184,233,647,110,736,849,128,413,621,494,919,349,320,237,661,697,763,557,438,301,301,947,932,861,772,291,25,860,613,118,969,120,95,91,390,495,382,914,81,360,872,689,61,765,199,683,309,354,698,410,77,936,344,361,22,645,623,413,217,646,786,165,272,210,404,532,56,953,77,547,576,757,947,204,307,13,874,364,189,701,185,495,680,212,983,47,723,33,171,38,307,658,235,684,411,202,221,622,410,465,135,672,233,458,344,340,195,242,376,199,613,645,924,958,249,724,222,401,710,847,207,878,331,366,84,232,560,187,738,661,1,654,151,244,319,498,165,811,446,736,271,629,429,181,504,663,569,369,212,957,380,146,10,64,28,656,697,592,606,630,566,135,835,393,795,44,640,949,837,58,879,186,933,608,460,656,92,582,40,414,520,235,134,396,215,865,12,275,132,24,328,178,932,348,11,232,408,773,656,770,100,145,381,9,876,52,991,508,190,397,404,432,645,215,700,669,997,305,401,867,992,213,949,827,784,970,417,126,171,510,971,91,672,784,439,223,547,407,819,847,934,270,54,749,533,154,740,420,403,588,758,672,663,99,497,64,91,193,711,611,485,534,920,697,441,740,189,295,601,335,236,985,810,771,75,345,144,390,970,138,450,950,358,306,967,527,7,172,232,107,644,158,895,216,217,183,780,530,795,427,505,401,897,86,422,612,395,800,894,171,912,164,555,528,756,887,705,421,54,42,115,84,819,601,928,685,979,696,399,674,766,751,91,169,834,422,121,949,526,356,316,985,932,42,494,67,783,397,493,492,951,415", "307,862,586,862,374,229,228,49,784,69,763,541,404,474,87,665,205,623,635,642,337,425,389,766,740,952,431,102,831,366,153,559,491,29,146,873,51,549,880,30,703,611,565,502,34,92,551,608,227,120,848,2,734,29,444,251,720,262,139,675,924,997,513,742,204,12,624,857,171,401,67,582,819,138,326,913,16,960,900,419,213,984,953,860,965,324,338,562,179,606,611,313,799,917,573,182,775,832,608,914,579,982,268,796,455,533,225,135,307,851,1000,199,616,907,231,721,900,346,612,233,533,225,175,447,923,812,865,797,896,182,947,981,872,745,614,243,36,976,770,561,939,101,888,363,709,619,914,288,767,153,951,76,687,513,226,171,572,500,759,313,905,958,650,950,297,107,944,674,624,2,660,186,946,710,907,422,769,690,42,954,403,129,753,228,639,358,892,734,632,995,588,984,343,498,401,145,316,872,644,226,140,53,711,875,959,57,172,110,305,214,208,792,839,725,765,802,167,782,131,823,596,966,332,599,516,120,152,847,406,691,142,874,178,33,473,674,444,318,687,760,314,360,876,169,900,604,214,858,348,316,821,200,773,162,181,737,178,143,48,995,323,338,641,0,301,240,369,681,332,486,608,817,744,871,759,721,45,234,579,975,118,284,70,856,143,323,525,367,647,136,789,999,267,893,782,217,628,512,663,85,485,289,74,987,393,307,540,171,105,967,601,579,28,22,999,675,389,822,556,650,392,280,967,236,915,792,289,458,542,116,177,840,693,30,967,31,308,211,501,270,182,329,491,149,101,669,314,521,832,765,916,526,566,934,858,147,991,595,655,149,604,712,764,991,292,194,847,979,276,237,506,495,718,267,198,693,83,892,570,662,303,304,815,374,325,575,278,29,319,692,282,656,626,64,33,243,697,133,349,175,7,451,778,595,954,454,997,280,938,198,477,436,186,250,73,872,77,852,968,586,964,765,46,15,975,214,553,903,225,243,726,242,458,212,192,465,706,672,592,31,877,457,413,554,268,811,439,472,436,467,686,248,627,875,259,918,168,835,188,140,510,146,746,1,689,487,687,254,868,801,126,726,525,494,53,114,919,101,42,710,744,164,525,871,359,544,873,824,880,341,662,640,97,535,801,818,833,325,377,656,287,943,658,96,471,343,581,104,395,236,30,689,261,67,469,694,529,627,680,34,15,745,601,901,826,224,1000,149,218,386,213,968,620,4,766,687,578,668,336,528,240,905,53,326,981,423,379,893,791,921,999,258,928,92,11,926,272,524,610,355,934,943,335,968,461,364,538,686,196,321,936,304,100,558,682,571,363,585,463,572,67,236,637,34,901,731,495,267,402,806,653,367,615,922,882,693,416,484,572,175,971,894,506,76,733,151,936,890,58,234,536,111,271,2,908,12,443,315,683,405,294,894,117,987,202,573,967,165,291,388,543,117,425,120,461,166,600,230,266,669,874,704,188,751,834,885,645,617,93,383,782,820,404,202,96,350,514,591,301,419,359,301,718,875,980,926,760,610,915,880,331,814,412,945,709,560,332,383,84,888,696,812,94,605,445,959,220,216,493,112,794,604,136,488,91,157,412,410,157,182,567,428,867,650,208,874,672,860,543,932,12,219,284,337,317,265,883,611,397,500,314,59,896,66,276,288,84,447,801,160,899,925,838,329,266,676,885,306,31,577,710,495,351,606,838,871,253,115,56,860,297,697,31,219,53,468,446,245,146,558,348,469,215,700,828,871,618,288,535,102,157,30,879,779,148,68,911,584,175,711,969,263,878,59,963,226,629,117,779,655,231,466,667,790,722,158,877,483,621,258,430,112,195,374,592,603,488,811,314,398,61,657,189,919,481,907,450,71,90,541,930,421,299,472,274,427,576,964,301,914,384,710,202,95,978,250,601,525,278,394,238,812,572,730,620,737,302,691,69,904,141,102,193,298,267,36,11,445,518,982,217,877,895,237,782,947,541,607,974,75,225,33,503,677,2,437,777,76,358,397,250,580,33,945,856,746,643,394,457,907,928,89,517,807,225,156,629,670,633,259,547,595,940,743,575,561,791,916,645,992,67,369,497,570,928,898,979,948,974,54,156,867,568,738,115,847,87,168,569,500,864,120,503,386,973,32,52,415,661,189,693,737,402,505,104,459,151,106,134,620,640,631,83,477,256,305,800,413,280,914,664,313,3,132,511,401,390,463,779,148,9,411,849,739,56,75,212,642,627,295,185,382,317,744,168,271,979,592,751,38,821,883,437,298,452,474,535,868,137,777", "794,609,487,94,696,508,385,972,397,551,26,306,154,511,420,343,93,31,335,507,542,374,484,596,251,460,121,875,135,604,940,294,994,615,460,162,907,560,468,265,586,326,270,920,551,976,482,895,996,622,361,245,317,867,161,86,978,258,953,498,597,11,122,825,884,574,589,960,258,590,537,210,323,438,429,153,233,413,862,489,232,902,366,650,715,666,754,148,356,767,407,713,258,825,201,418,959,896,939,513,551,79,966,70,607,814,163,774,206,719,703,373,889,197,994,127,857,853,844,493,959,577,234,813,981,150,54,497,353,617,78,425,334,379,173,598,711,399,23,352,342,224,842,827,271,787,757,607,381,114,56,695,183,417,355,114,556,247,489,720,158,438,51,487,497,85,661,722,480,399,688,255,126,431,610,188,547,740,714,604,402,628,679,96,27,192,809,274,108,34,50,451,67,958,585,517,296,794,441,642,297,643,124,89,986,201,428,445,778,861,476,764,448,848,985,43,848,129,435,887,897,924,138,4,952,710,167,174,825,689,210,975,93,854,594,11,878,850,542,890,30,289,157,68,484,906,180,82,434,331,27,223,242,342,702,156,241,822,408,728,599,847,92,301,0,611,458,503,343,972,201,118,964,194,339,48,403,775,739,717,499,899,455,950,584,868,835,883,194,889,271,27,71,586,853,586,366,666,964,49,394,950,105,29,139,259,156,691,300,266,352,959,507,132,815,784,853,42,981,822,639,854,205,465,399,157,682,141,16,33,819,901,205,754,920,626,844,756,795,331,513,36,670,811,752,121,497,631,734,988,152,380,138,796,979,796,681,702,988,598,1000,262,164,304,185,294,50,371,675,243,960,92,561,468,832,680,868,906,486,688,632,428,375,50,906,963,191,311,124,190,520,897,88,400,975,470,330,551,30,284,59,346,682,540,618,288,151,840,745,519,964,8,281,86,617,757,808,894,629,597,243,105,712,536,740,589,417,995,250,97,398,42,503,146,693,126,558,503,142,4,44,246,90,704,667,656,209,60,916,450,793,205,396,723,787,525,123,815,711,662,147,407,506,619,469,65,948,770,708,225,388,480,363,77,312,766,148,137,170,127,340,708,274,981,360,833,467,661,948,800,135,35,787,275,604,575,640,852,839,719,488,585,10,680,436,112,364,220,834,2,112,342,935,670,23,223,975,93,704,476,342,928,878,393,450,15,576,989,96,327,333,100,977,340,916,212,825,339,703,672,109,100,7,917,183,818,620,137,247,960,209,22,116,483,351,422,937,965,263,355,137,874,300,778,244,60,319,518,811,643,526,634,20,916,908,907,208,507,742,588,977,710,953,959,434,976,505,980,558,670,47,636,98,204,207,745,985,488,835,656,187,595,899,848,712,547,277,587,5,22,180,171,183,108,397,323,228,305,477,425,545,78,814,652,932,908,963,811,243,972,491,766,461,830,732,706,453,612,486,591,247,426,313,908,108,609,787,654,575,277,829,444,715,88,322,974,121,432,342,365,86,156,38,907,93,466,503,419,224,816,617,298,191,912,264,850,305,266,229,698,384,955,556,155,657,581,128,317,633,377,486,2,357,74,485,734,149,284,933,13,163,509,469,238,196,753,450,104,504,345,28,83,194,541,21,684,693,667,622,531,634,437,830,952,701,470,967,285,25,995,342,387,793,535,455,588,283,632,254,959,649,137,44,878,999,909,584,554,466,682,262,928,838,922,376,538,694,10,433,341,531,528,801,596,946,488,855,13,326,129,339,506,845,808,668,69,331,334,124,808,347,201,93,681,706,999,807,484,702,191,380,898,587,534,910,140,167,536,393,279,162,381,117,256,963,541,599,109,456,164,119,202,560,47,289,967,203,368,371,179,564,92,616,602,359,216,660,429,719,529,357,174,66,626,808,103,9,24,5,276,747,578,734,884,840,458,628,668,790,669,900,308,268,693,956,236,419,83,651,409,446,391,489,568,990,85,214,512,783,245,39,857,972,320,239,359,447,420,950,317,388,586,165,685,260,30,245,839,935,389,260,129,766,636,158,235,210,144,645,370,595,468,990,334,606,500,62,190,161,73,776,552,932,603,362,598,607,190,282,768,511,706,189,467,725,253,362,794,968,361,357,698,391,886,243,536,490,482,721,292,819,848,899,99,729,330,807,212,408,54,230,758,568,847,816,52,32,846,675,231,850,566,84,290,657,434,365,682,115,108,377,270,416,248,292,336,674,134,781,498,14,719,292,819,295,239,704,935,256,107,597,709,730,351,690,557,978,493,614,188", "669,244,698,179,742,748,632,444,824,786,494,792,321,864,807,858,232,584,198,711,304,49,126,417,439,338,598,71,797,189,125,126,372,839,324,14,687,418,561,624,23,743,28,786,304,986,113,950,350,994,355,553,393,90,463,177,309,336,255,452,684,575,78,170,372,887,181,793,640,723,519,59,641,313,503,744,698,568,141,964,856,291,236,839,534,414,928,147,783,823,634,741,532,824,981,178,226,531,409,910,166,332,660,960,509,260,817,35,26,677,483,414,676,671,587,345,334,113,256,143,716,487,325,631,187,646,772,909,881,204,999,815,118,336,297,332,399,29,937,898,695,433,567,810,442,254,251,17,331,404,849,626,673,856,424,341,471,757,105,284,673,349,755,498,682,276,997,872,607,348,73,549,279,721,350,544,600,855,193,645,771,131,490,732,42,8,9,723,968,764,860,335,61,378,600,671,900,240,993,483,287,454,787,108,645,915,536,12,468,99,817,648,770,554,683,384,460,269,887,412,348,137,121,107,991,319,593,983,202,90,504,16,502,858,531,755,246,21,491,486,238,472,760,407,530,34,115,509,807,246,398,259,72,258,24,442,427,336,602,747,683,373,113,240,611,0,755,265,373,309,695,268,625,348,496,787,882,105,362,904,996,457,279,811,651,809,913,221,904,158,125,921,341,230,866,47,651,86,937,513,244,341,498,277,417,967,489,860,379,867,169,778,116,894,114,772,796,299,6,197,873,730,149,466,541,850,227,408,94,298,333,376,133,186,481,693,913,216,888,340,143,561,687,86,938,722,764,871,266,55,192,785,866,344,102,856,506,427,878,32,706,406,244,286,382,438,974,494,551,545,530,923,192,936,549,840,954,188,587,567,305,979,87,324,186,554,194,13,492,436,90,965,523,312,994,914,361,87,674,789,673,189,877,553,943,421,522,80,335,592,435,227,259,256,599,45,829,61,649,224,72,661,705,250,685,116,550,986,294,184,365,791,66,262,496,490,42,878,346,630,593,164,275,836,624,169,337,464,186,535,612,969,323,119,598,829,694,323,45,990,154,207,153,607,75,557,623,170,715,771,930,265,585,722,936,995,9,752,83,687,579,565,428,935,370,738,761,979,103,622,365,516,683,796,475,306,238,485,950,14,137,815,135,368,528,862,247,598,249,923,94,239,667,848,826,223,407,381,531,188,504,348,119,394,998,198,315,596,694,872,64,768,471,427,564,936,705,570,29,307,99,314,955,718,149,195,736,304,857,544,25,559,936,329,769,427,375,928,377,985,491,580,770,605,844,617,310,275,334,781,5,566,870,213,744,57,294,588,241,601,89,928,987,781,203,523,864,480,365,760,266,207,642,901,232,835,636,236,840,814,234,915,702,599,642,113,30,490,823,326,417,830,818,635,152,143,400,169,798,938,863,403,17,654,875,569,323,788,564,958,75,809,680,697,305,608,98,467,74,832,187,100,883,175,751,728,899,450,439,272,641,771,866,825,840,813,516,197,411,532,332,463,858,675,875,496,117,335,568,852,694,588,113,360,198,53,730,636,138,613,292,411,299,467,822,403,569,526,837,836,689,397,810,294,912,451,736,540,29,406,167,331,296,253,942,9,773,529,135,587,117,585,719,796,796,188,165,966,684,63,656,292,840,375,72,970,181,994,969,551,344,200,492,462,224,364,876,444,19,855,636,609,503,352,431,874,333,482,180,809,22,977,120,943,669,228,63,405,507,867,404,23,925,153,381,385,445,278,847,607,849,218,358,266,799,855,762,25,752,673,799,802,547,943,428,426,263,161,474,940,453,15,740,985,859,762,464,841,848,129,916,675,479,318,244,475,653,930,136,175,225,282,813,933,966,155,190,519,7,905,683,755,386,951,337,775,320,352,705,706,752,188,868,968,25,348,801,454,565,2,787,435,455,752,493,881,855,603,986,341,310,227,632,707,603,682,798,364,376,314,970,102,543,118,179,206,344,506,105,248,889,744,263,230,843,304,305,79,163,122,639,493,966,32,148,364,751,716,730,469,433,163,983,196,332,514,806,473,475,153,431,716,328,979,754,686,439,408,959,531,912,129,563,761,148,132,650,137,444,88,412,995,78,574,378,733,531,707,89,662,409,673,157,452,719,95,88,771,734,192,654,710,407,716,640,345,629,549,912,871,261,786,47,460,717,74,598,593,181,343,711,314,948,83,879,547,841,373,854,711,611,517,36,733,81,470,465,956,794,424,452,820,402,696,991,680,700,219,151,794,943,446,98,340,531,470,619,351,769,358", "438,662,386,486,176,502,2,933,381,359,927,486,978,284,702,85,159,751,317,837,829,602,726,48,745,771,541,377,827,44,290,893,999,873,176,29,40,525,626,864,333,94,863,224,222,914,23,443,984,11,506,371,90,203,525,295,775,788,564,438,681,896,725,860,985,934,916,362,854,14,840,391,564,341,326,20,124,335,209,27,723,511,899,687,748,743,204,521,284,804,340,334,675,264,416,249,415,254,487,535,550,612,821,204,693,776,476,707,839,560,757,654,502,283,163,4,110,275,892,834,483,247,20,629,247,673,767,70,755,10,367,93,451,933,866,223,679,398,544,401,684,940,868,917,877,46,618,230,152,59,589,70,208,597,233,743,392,953,460,704,275,378,874,885,908,779,493,476,972,437,187,186,146,572,317,597,814,399,671,32,431,726,366,881,261,528,465,951,297,671,757,551,50,61,629,464,915,594,593,245,59,166,163,365,937,401,55,244,334,555,793,31,340,935,808,577,9,264,224,858,419,320,234,413,571,585,990,833,151,70,963,753,300,42,895,927,543,302,292,508,357,365,833,132,690,871,548,287,1000,933,215,937,2,47,274,799,567,526,628,543,840,913,625,369,458,755,0,142,430,734,631,731,373,180,766,211,597,62,996,142,766,633,242,251,218,29,648,626,12,59,338,70,674,141,742,393,733,144,262,632,199,583,155,806,927,466,175,877,953,450,589,853,508,111,901,37,253,727,934,203,178,974,77,112,390,632,617,655,72,911,932,134,501,438,253,8,784,996,204,137,846,304,988,682,211,840,348,36,823,952,990,466,206,830,663,410,871,173,774,40,974,803,933,292,940,462,871,70,155,34,723,100,582,102,740,252,712,471,622,519,607,198,25,961,460,771,418,782,876,340,842,879,12,822,81,575,485,65,334,922,66,954,20,768,957,609,26,240,607,326,941,553,563,573,188,748,918,742,208,731,732,633,542,992,851,118,438,796,369,665,989,982,864,217,490,267,549,953,655,227,471,937,152,359,226,324,767,556,878,106,365,652,717,205,550,336,311,46,823,460,398,124,497,577,410,937,791,60,981,100,815,332,409,63,843,123,442,710,907,89,30,377,507,127,905,789,836,10,881,929,354,63,571,11,236,511,763,869,906,206,470,687,497,447,303,613,713,990,519,127,211,120,864,856,775,642,758,982,272,134,602,742,367,545,306,94,244,384,750,769,687,372,333,686,474,439,395,532,704,102,572,841,30,458,935,182,896,588,153,965,124,254,781,754,545,356,84,810,288,676,380,526,897,574,532,828,893,308,394,787,985,43,176,540,273,108,55,836,407,21,302,666,65,513,90,542,549,42,972,592,517,754,641,169,418,284,428,621,84,481,570,335,751,768,902,712,36,496,611,677,420,371,976,48,681,940,227,602,667,284,368,819,311,965,581,168,205,26,607,251,917,426,239,204,783,354,125,66,574,9,198,693,951,259,194,579,676,734,743,469,790,639,217,761,96,415,301,744,684,675,812,998,945,475,22,877,281,28,63,411,649,379,723,788,82,99,61,674,685,530,684,443,560,643,864,850,804,763,902,751,66,735,261,224,112,982,199,83,952,910,730,646,266,666,83,566,979,708,781,665,879,635,893,306,152,719,787,25,21,708,977,735,885,354,890,285,396,533,127,151,556,563,185,935,343,192,209,885,920,665,742,989,436,814,895,601,399,933,615,358,507,811,475,941,726,40,501,189,866,736,22,171,467,418,260,551,245,10,829,493,432,746,602,991,602,528,533,886,46,299,877,906,964,220,851,460,18,63,884,421,678,425,30,59,381,884,524,949,531,692,79,246,536,662,293,792,836,974,892,531,484,586,204,546,523,716,955,831,582,208,451,345,270,98,265,880,632,259,580,313,679,393,236,710,837,89,425,518,51,121,779,176,145,512,377,39,954,586,441,450,599,488,638,645,134,149,612,413,537,296,524,829,980,216,54,326,106,942,126,309,696,37,518,186,281,930,83,938,63,264,521,705,344,422,35,552,980,294,517,305,286,468,21,69,635,553,939,154,464,821,218,494,614,747,822,407,69,86,866,825,363,852,426,766,664,135,293,424,405,820,571,485,655,492,154,644,372,118,604,818,540,611,443,173,862,899,773,99,534,765,214,21,261,978,256,949,865,530,992,320,978,70,562,579,68,587,377,406,414,381,941,157,927,471,87,155,274,100,323,414,992,909,189,295,733,437,394,661,151,19,903,21,984,232,974,323,487,912,874,406,289,25,543,375,267,925,966,477,888,587", "604,714,823,991,98,745,815,753,38,763,990,824,583,321,590,890,598,272,426,52,832,24,619,97,200,787,364,344,426,912,841,791,286,873,707,340,541,393,309,135,889,933,710,370,84,793,556,431,165,538,875,238,213,767,623,551,87,378,850,919,146,230,800,593,696,135,11,881,424,829,730,773,258,16,171,876,451,185,940,830,377,979,211,819,390,376,724,435,123,980,63,586,604,902,322,265,316,306,23,790,957,523,362,720,532,483,125,611,912,217,605,471,364,997,234,815,378,863,58,293,478,820,927,412,403,589,38,262,482,560,985,740,5,541,816,473,330,843,208,282,358,425,662,468,4,213,849,613,246,690,690,162,328,423,61,135,362,600,757,490,912,971,259,990,894,968,618,368,199,969,489,481,228,791,50,189,455,349,765,919,7,950,874,48,295,270,745,584,163,197,532,341,569,549,227,118,241,160,647,813,969,833,790,502,73,212,961,521,437,466,991,443,954,550,472,738,430,262,814,479,402,121,160,887,241,108,351,485,881,240,140,971,956,893,450,328,117,387,589,139,123,575,472,958,780,935,846,765,257,590,782,496,438,748,539,55,944,99,891,417,432,767,707,681,503,265,142,0,617,259,123,138,137,853,470,909,242,50,733,591,724,472,895,843,727,51,585,552,124,239,482,127,593,778,15,148,49,119,650,458,423,230,367,62,38,151,797,903,24,342,368,669,318,933,897,101,918,880,528,757,221,4,867,95,919,709,809,347,673,119,753,100,735,248,542,749,915,411,55,203,546,916,253,379,580,206,915,242,538,654,952,708,685,893,689,678,597,803,883,785,418,773,341,452,339,616,504,239,363,826,410,435,924,849,996,646,245,268,142,952,713,401,940,183,962,417,319,420,58,584,214,922,970,936,912,287,61,56,581,821,282,525,433,642,681,74,785,924,184,968,328,934,434,242,177,201,736,262,232,31,592,308,66,44,584,358,410,111,414,458,283,904,196,300,497,60,723,922,720,334,973,662,713,253,669,141,420,661,27,520,435,443,64,759,967,705,833,504,890,875,997,614,638,560,940,597,677,332,43,664,626,645,595,999,104,976,716,355,404,837,354,799,962,733,303,351,17,490,140,849,841,631,233,553,920,529,923,756,755,309,359,764,850,619,949,416,771,951,535,496,946,518,967,817,452,767,745,482,762,656,93,297,959,658,829,915,525,206,558,733,203,511,716,838,653,418,315,51,172,628,158,304,158,903,334,800,880,640,460,815,13,829,892,823,767,961,967,743,448,885,907,353,449,155,650,980,654,676,608,634,433,181,878,512,542,867,849,763,611,936,888,723,917,379,799,722,340,598,877,51,960,171,175,869,621,669,351,114,465,911,302,32,800,801,690,993,293,549,751,451,407,146,540,105,94,595,694,576,36,909,645,843,398,221,743,965,609,283,969,677,353,449,100,647,117,680,906,156,544,667,582,234,308,796,299,957,380,863,492,246,497,923,994,175,938,922,789,269,378,85,177,340,806,990,743,662,475,876,612,434,719,795,98,974,503,648,868,754,762,154,715,68,713,478,606,173,35,325,506,952,157,160,836,991,639,510,894,664,974,897,390,796,964,900,852,945,141,499,289,180,723,104,41,729,550,509,65,548,931,220,392,419,380,465,809,725,636,291,597,761,54,617,181,389,315,820,738,980,155,279,103,978,581,367,70,734,551,347,530,537,170,823,538,964,797,402,573,415,610,49,412,975,827,876,83,752,392,285,842,95,183,629,770,280,341,182,515,912,634,154,423,94,285,227,228,920,55,594,564,147,818,107,773,287,649,308,338,422,806,391,509,314,742,974,329,333,821,233,584,862,37,299,389,968,766,670,533,515,363,181,811,452,309,710,456,112,211,236,926,452,783,886,200,67,949,702,697,95,788,290,108,231,528,759,256,988,965,22,703,586,264,487,933,327,350,741,41,785,776,992,88,380,877,354,92,71,153,832,586,360,60,825,974,538,185,607,982,284,571,628,619,618,532,459,697,484,980,515,373,277,298,403,248,821,101,494,197,921,3,87,852,472,654,254,556,44,501,432,714,973,939,989,798,492,364,816,17,917,492,255,280,364,935,449,925,847,729,666,928,518,738,82,277,984,540,578,335,527,496,153,599,693,93,506,93,379,358,176,129,435,502,70,359,362,137,224,644,528,762,600,59,682,452,232,630,813,452,96,777,281,320,302,638,170,744,736,124,799,57,941,5,277,448,431,119,903,134,106,242,58,29,305,802,91,265,2,269,11,350,921", "549,194,849,626,799,643,899,543,642,50,85,923,520,385,591,339,110,818,692,15,357,923,789,336,514,815,928,237,334,956,505,74,529,451,985,835,679,280,423,181,666,207,861,469,561,277,759,381,560,477,787,718,735,243,4,644,347,975,29,594,778,345,52,318,4,526,601,975,170,358,511,912,248,849,752,504,37,68,413,646,221,483,514,754,801,518,572,611,177,551,29,654,174,292,343,81,441,397,795,484,904,812,305,394,263,395,891,596,426,266,565,205,12,859,275,483,394,7,837,169,235,372,82,887,408,760,838,139,483,885,733,297,265,799,880,980,801,632,728,867,115,536,250,516,683,621,425,350,74,509,557,635,224,408,980,774,594,796,640,560,914,136,206,197,289,773,793,913,282,461,114,93,455,865,930,250,552,593,34,96,481,309,742,63,772,401,58,359,792,773,206,683,219,389,169,755,46,179,534,928,988,701,166,490,32,164,597,59,392,604,166,242,26,170,980,297,762,634,301,253,593,35,758,127,349,919,790,308,593,817,191,141,8,47,457,967,860,929,336,165,9,366,23,979,26,366,860,322,85,590,96,353,264,279,578,513,233,129,110,41,789,231,625,332,343,373,430,617,0,671,286,997,861,816,600,15,782,339,135,134,838,518,307,624,971,311,749,993,743,108,982,270,924,929,73,73,175,167,149,833,474,591,291,174,40,850,402,11,727,452,694,555,232,875,649,727,924,724,637,736,872,15,826,928,801,232,318,725,587,662,275,471,473,125,866,335,339,150,727,369,622,129,749,871,162,420,194,674,910,758,765,428,188,824,133,992,483,626,503,199,351,162,218,809,300,237,759,798,613,647,799,353,110,279,107,873,594,198,520,458,210,983,980,696,447,882,204,344,314,68,495,509,582,925,353,473,65,409,734,813,878,663,349,352,500,736,892,220,991,69,232,499,762,739,251,785,968,939,601,840,153,550,985,995,39,880,657,81,826,888,271,634,840,448,634,610,106,546,955,857,370,704,323,434,882,652,525,765,188,380,326,496,579,656,917,51,688,85,336,123,255,658,803,420,981,506,284,118,721,540,970,602,941,944,80,321,962,866,792,941,774,14,112,943,214,880,859,201,344,309,315,26,310,573,316,876,156,481,900,3,66,453,396,428,944,152,801,284,906,413,224,433,845,784,937,332,551,451,319,420,874,236,99,412,124,922,624,288,224,40,300,681,580,184,768,744,950,970,142,280,453,678,258,610,354,224,469,231,834,70,551,771,456,461,582,739,315,10,224,599,339,753,188,722,724,26,893,568,775,804,43,184,150,522,811,174,979,652,905,284,177,960,956,185,592,309,585,549,678,770,180,621,534,546,154,249,859,313,920,863,383,577,730,139,224,651,377,420,260,452,125,963,296,92,756,926,47,549,88,392,996,196,336,632,511,613,632,92,879,136,264,635,685,671,84,304,807,787,564,158,323,956,150,653,897,839,881,152,433,880,584,430,635,334,526,9,171,502,784,210,349,254,495,292,928,891,379,748,303,763,206,27,338,43,287,354,632,366,70,692,56,479,374,810,870,766,247,397,638,359,670,551,749,123,953,467,180,837,272,830,983,481,3,254,322,742,600,688,442,438,968,349,423,391,441,925,822,186,919,275,414,530,754,632,626,558,471,409,604,678,900,341,151,796,183,671,707,292,540,640,927,314,800,143,365,462,844,811,356,205,979,356,900,353,930,640,370,174,286,150,248,35,489,192,832,582,409,918,527,145,60,953,747,580,475,27,176,754,747,605,579,848,657,510,965,13,324,907,109,151,977,755,226,835,95,519,706,417,288,442,192,154,102,479,142,957,669,329,577,618,274,788,359,838,194,114,125,730,616,831,203,602,685,928,521,933,358,415,581,382,158,866,606,166,555,5,307,26,204,413,825,397,118,671,367,716,168,11,286,348,610,308,514,964,179,199,235,602,812,221,508,450,632,915,507,470,341,142,531,717,957,154,393,479,827,15,512,787,678,312,356,623,734,671,767,59,149,810,223,413,379,795,62,549,747,38,332,762,571,255,656,214,555,955,66,878,728,39,681,519,837,559,982,525,45,162,680,613,27,962,770,636,290,381,57,656,712,892,623,59,523,332,463,403,119,21,259,896,18,814,892,157,494,849,406,717,385,789,486,542,390,359,397,994,830,939,654,989,974,272,681,350,455,685,482,722,525,34,247,428,148,155,481,387,725,430,907,960,726,350,686,924,712,499,602,788,715,590,445,472,833,716,60,844,474,309,831,704,938,402", "921,853,784,301,394,656,790,631,764,85,958,926,677,469,36,371,594,480,305,664,568,444,565,381,197,733,668,672,291,30,220,972,234,515,410,709,464,101,12,248,321,216,779,619,586,790,87,144,329,303,604,896,305,434,4,24,169,375,103,886,612,76,266,784,15,349,415,144,739,656,603,238,28,365,298,684,490,684,269,606,360,767,276,213,540,347,440,355,829,936,349,886,293,839,252,236,318,16,355,322,3,215,659,904,348,16,280,27,174,297,9,462,593,945,123,167,850,494,970,133,123,682,164,494,933,248,977,976,278,758,432,876,19,272,210,746,36,442,952,960,592,967,234,756,982,380,497,357,111,855,696,300,63,955,671,460,902,965,948,53,3,909,718,518,376,128,341,265,955,839,216,83,374,14,241,615,848,170,467,367,76,693,977,975,195,791,942,722,717,801,680,577,438,226,321,350,520,782,247,506,506,318,806,98,274,732,102,153,214,677,71,796,483,624,521,197,21,99,395,203,864,390,851,711,520,539,956,947,530,442,432,149,153,256,122,97,654,798,208,601,842,376,905,819,411,831,614,390,313,610,499,153,31,620,589,401,108,885,82,802,447,340,702,486,972,309,734,259,671,0,143,352,503,466,926,447,609,281,10,104,693,605,450,177,184,914,260,787,440,926,608,250,985,683,978,731,850,363,767,873,180,401,456,32,529,237,817,331,426,814,161,795,293,631,702,576,968,360,87,366,164,882,441,949,375,8,240,441,932,31,882,791,127,961,494,453,269,382,626,959,463,986,450,608,156,616,979,495,712,184,111,56,769,88,378,775,10,89,274,874,902,20,651,108,263,773,731,470,3,150,33,114,220,511,386,488,72,646,594,496,778,181,987,227,857,743,884,719,724,557,88,941,494,708,779,155,885,134,162,256,743,90,6,118,57,124,727,909,404,825,103,746,450,896,863,257,795,80,651,723,484,407,591,923,668,584,587,502,691,370,310,78,530,774,140,174,749,861,829,905,625,738,421,413,972,2,386,895,997,786,433,937,72,535,777,573,689,887,860,370,941,606,831,444,193,400,275,103,4,370,815,475,572,615,286,827,819,950,605,74,790,204,837,653,200,565,18,980,236,895,516,337,121,760,421,675,575,910,195,808,828,666,558,286,821,875,54,757,471,738,458,709,616,816,818,966,490,355,450,238,337,891,236,309,573,275,515,983,691,429,91,230,505,921,6,213,161,375,922,942,566,340,822,166,7,128,904,123,404,704,965,355,64,494,400,795,924,709,899,289,870,50,850,645,287,398,470,641,240,202,430,904,607,673,796,645,610,776,949,685,782,136,971,639,333,575,397,592,827,520,623,40,729,48,627,585,581,976,64,601,848,280,653,267,339,952,242,881,692,881,31,535,17,234,130,591,844,96,523,858,885,719,933,747,398,469,820,134,102,13,781,714,420,754,549,748,310,242,903,779,777,630,764,360,877,532,420,596,944,744,92,595,368,328,519,629,250,315,776,241,514,492,465,274,148,551,896,137,89,173,626,771,297,721,187,468,386,187,299,799,249,974,638,723,101,69,585,576,803,165,250,939,144,271,864,846,46,27,710,170,78,483,487,472,209,847,795,63,867,440,793,219,720,231,437,62,49,959,42,421,664,195,905,669,558,835,287,301,951,636,898,112,477,902,930,585,542,809,729,271,884,343,80,462,115,687,800,729,47,194,573,832,565,728,85,196,499,831,182,88,779,626,43,377,58,250,780,670,159,363,726,840,332,956,458,101,872,685,209,77,861,91,735,517,671,972,282,752,638,275,724,127,886,349,941,109,553,923,121,832,959,448,656,92,774,447,395,389,979,330,19,709,947,487,404,117,913,666,471,751,214,64,167,260,271,897,380,723,274,645,479,339,99,323,635,137,273,328,535,373,158,797,296,783,920,480,644,295,892,977,196,328,835,968,666,869,251,48,532,828,257,326,999,988,64,252,933,979,660,775,215,743,987,174,436,407,105,960,883,968,285,715,583,316,49,463,427,658,478,585,118,606,247,641,894,576,399,347,530,730,550,98,743,852,655,504,579,657,554,276,665,958,287,21,488,7,616,1,841,359,11,734,622,718,19,565,830,845,508,597,583,160,687,663,68,982,576,92,223,601,867,990,264,96,965,476,990,67,219,784,292,491,137,719,900,340,170,636,226,52,743,718,510,401,762,173,610,39,626,40,417,889,298,463,450,21,231,867,113,407,930,103,313,9,584,963,163,932,854,924,780,711,274,795,392,277,173,676,606,84", "848,788,78,855,334,122,587,801,616,365,282,644,503,244,377,674,946,390,556,798,406,39,177,834,993,453,483,953,621,661,913,379,26,515,358,59,242,842,420,141,590,860,944,603,79,936,524,817,957,877,584,713,179,434,316,611,947,756,319,711,342,341,621,386,983,149,692,27,426,902,131,904,78,465,538,339,205,367,690,620,808,6,798,462,549,562,355,775,666,29,318,712,983,379,114,539,469,202,276,441,424,324,780,389,696,888,369,815,910,52,570,231,869,590,986,631,636,273,42,708,21,687,266,408,780,200,328,767,273,833,102,608,618,979,314,859,709,898,834,959,321,891,829,425,191,788,179,988,948,419,684,164,122,48,753,208,355,387,359,828,742,750,723,863,89,639,773,45,778,700,832,831,170,963,374,755,367,380,329,152,894,992,185,862,183,722,483,777,344,742,751,412,818,415,232,58,215,329,551,582,692,928,454,169,262,65,137,225,830,588,885,634,382,185,490,496,787,322,790,347,172,330,909,80,731,158,650,500,712,293,299,585,320,417,424,283,787,717,489,655,584,423,430,85,951,157,992,124,5,385,784,234,333,875,792,204,831,446,27,378,237,237,632,608,201,695,631,123,286,143,0,547,596,409,514,971,283,449,371,731,669,44,7,712,380,965,824,804,628,984,890,215,820,702,724,435,539,189,653,346,509,835,332,167,654,277,748,512,265,575,546,784,568,840,693,601,774,79,665,30,774,676,562,538,651,477,184,12,86,170,556,109,396,388,496,449,701,163,735,400,241,386,620,146,310,472,994,493,954,930,641,230,190,643,263,930,577,967,656,50,565,928,231,118,882,848,39,157,471,925,18,325,325,383,632,68,599,227,558,663,703,288,510,746,680,36,728,982,723,27,540,902,563,364,489,543,892,613,869,739,863,750,881,463,570,803,903,922,218,490,427,282,671,159,743,921,994,979,265,111,718,753,840,790,212,375,249,425,214,852,464,657,318,584,40,583,699,759,79,69,87,431,457,80,301,989,474,689,529,399,989,228,309,764,983,848,388,687,702,251,246,86,794,428,564,204,581,847,630,844,416,435,406,626,93,857,998,437,440,433,403,914,160,990,915,236,428,148,378,291,338,80,478,136,211,823,935,564,148,951,923,479,159,254,66,779,429,263,828,58,965,256,42,863,289,21,599,468,398,22,400,101,907,650,155,599,774,240,255,284,319,909,330,579,503,306,962,555,930,799,785,231,598,415,296,388,693,138,589,7,284,570,822,271,826,277,189,880,822,484,468,834,969,901,801,520,308,545,493,13,171,758,505,105,412,579,857,16,507,663,564,602,443,607,837,993,378,523,111,386,763,804,292,55,912,764,37,648,966,579,825,257,603,890,610,549,106,51,246,556,818,22,110,487,533,126,87,550,702,178,260,478,669,678,211,79,82,41,403,181,689,525,758,293,888,248,5,197,445,536,261,277,663,398,103,861,805,573,515,401,931,865,499,319,149,643,921,612,123,308,64,437,355,826,311,402,685,70,634,603,294,22,63,271,61,542,988,298,736,952,730,953,605,17,623,7,247,623,369,145,567,447,271,201,576,424,898,479,160,568,153,931,438,336,538,813,770,772,537,166,730,4,75,962,163,23,371,380,677,620,10,281,710,681,859,234,311,379,879,341,183,907,778,959,279,469,964,715,816,718,954,613,742,175,172,600,553,389,906,377,757,208,888,461,55,875,147,738,988,164,868,119,864,459,338,263,150,679,485,645,797,704,388,953,701,681,620,477,523,382,977,568,82,892,333,606,889,963,689,741,646,915,118,10,655,907,173,929,881,831,684,943,811,419,909,385,574,353,492,408,518,914,300,550,722,932,341,288,681,847,263,302,294,409,116,402,735,341,934,718,235,786,928,912,16,69,320,350,245,198,602,774,402,672,329,469,266,767,220,352,546,335,302,357,204,367,85,799,902,227,563,346,221,227,86,325,702,794,632,159,272,395,320,796,20,533,66,121,116,850,473,324,8,159,943,161,426,762,553,847,751,809,643,23,246,384,151,177,867,450,22,969,807,395,150,419,290,259,884,544,546,723,63,578,256,633,632,280,306,111,127,919,384,656,939,834,43,386,564,260,891,162,196,603,62,142,734,177,914,186,424,686,416,958,395,296,655,21,38,873,980,326,81,823,989,545,40,478,63,162,405,282,662,597,266,564,803,401,352,197,335,998,649,700,433,875,737,276,34,666,940,269,239,350,704,418,329,419,599,440,944,334,662,575,104,364,712,637,550,784", "918,359,850,974,620,190,494,419,286,77,810,497,325,767,705,685,969,257,259,220,494,970,903,729,280,111,327,551,78,152,299,812,32,747,385,364,719,108,643,170,210,295,106,780,944,846,100,604,790,192,373,412,820,534,414,644,658,277,807,391,667,714,87,918,551,957,290,736,31,75,55,941,618,535,425,396,278,480,871,421,890,348,267,550,53,634,70,683,396,110,832,276,397,624,393,146,963,479,362,708,237,937,887,573,877,787,27,271,818,167,367,774,851,45,459,198,207,962,550,201,668,207,564,618,706,653,812,833,350,848,170,160,673,404,268,23,799,845,295,688,26,206,475,811,173,436,442,666,200,496,579,303,490,475,321,96,812,655,269,569,609,296,810,95,900,887,214,162,358,499,184,48,165,481,583,734,772,142,56,116,691,646,51,938,991,277,598,453,118,782,821,391,813,573,743,541,89,865,148,957,199,617,93,981,897,910,299,470,772,891,79,439,963,30,143,248,558,955,671,371,838,354,10,599,280,23,703,748,485,526,21,291,451,495,829,70,337,351,393,430,52,71,829,609,676,325,621,977,863,979,131,239,960,132,642,313,787,621,463,694,293,251,490,817,118,268,731,138,997,352,547,0,599,538,771,176,780,864,870,15,843,743,391,965,578,742,951,523,210,294,745,38,643,399,783,534,970,730,451,812,328,346,407,309,271,478,252,448,35,525,898,403,368,693,515,842,32,166,200,259,649,556,928,120,86,779,996,94,701,542,190,774,652,844,635,727,911,351,790,651,973,100,428,212,226,935,135,651,853,214,648,431,793,384,841,952,235,489,291,565,235,616,671,304,65,796,84,974,420,281,652,549,108,917,897,25,927,724,51,388,743,939,917,388,390,820,977,455,934,133,983,362,988,17,366,2,886,639,871,908,792,44,974,498,753,203,171,688,243,609,234,777,738,800,751,339,45,252,144,879,348,164,212,851,446,553,143,857,531,748,746,646,219,838,548,443,33,170,377,677,3,958,263,747,799,363,988,188,526,949,186,966,143,7,416,281,297,67,43,584,240,454,362,397,562,206,904,385,251,455,518,849,269,627,519,880,386,776,788,478,527,524,625,503,533,166,600,805,545,468,46,917,881,352,633,133,196,606,178,261,687,435,741,195,879,554,677,421,689,60,128,546,333,684,110,646,997,71,722,132,653,260,681,256,408,818,975,536,535,759,672,726,69,237,511,230,940,814,973,962,404,762,122,855,297,813,851,213,326,693,297,369,35,480,276,762,379,720,534,902,746,454,234,585,759,964,586,940,457,465,378,804,959,868,3,251,583,540,389,876,126,137,282,576,778,884,998,550,279,989,746,176,931,469,452,307,957,529,289,698,776,66,807,632,657,914,648,721,202,839,199,730,725,456,918,622,923,526,110,284,56,896,543,834,626,802,721,318,700,994,275,779,676,523,624,526,409,204,375,392,305,327,994,813,869,355,634,627,655,953,400,597,611,557,331,223,934,948,524,888,697,913,278,571,371,881,373,147,329,874,771,303,516,909,307,657,273,141,774,78,552,224,778,18,413,191,649,461,18,344,91,545,725,824,276,641,727,34,512,535,502,566,94,136,539,398,135,22,580,173,470,931,136,324,209,466,284,15,395,149,960,509,223,736,850,53,442,296,239,129,316,437,438,806,86,55,664,113,522,565,603,117,775,605,230,838,833,38,623,90,189,898,975,6,852,21,79,703,543,494,767,689,585,763,286,593,591,602,375,387,383,475,611,658,98,750,246,32,319,4,690,477,33,891,826,875,102,74,343,540,465,902,501,709,343,245,766,178,597,618,687,553,413,278,286,813,458,443,469,319,706,727,328,216,862,759,50,446,47,611,239,74,488,107,286,53,352,872,745,515,551,385,225,512,190,317,120,638,433,663,48,159,14,994,40,273,613,488,484,487,482,399,777,511,95,635,198,383,613,275,94,489,135,702,187,774,844,649,172,394,391,572,371,164,260,896,228,320,154,777,241,142,471,370,529,112,930,988,686,235,850,503,351,425,573,722,691,183,605,838,969,985,488,238,615,351,421,843,207,508,713,984,603,187,889,469,604,310,395,6,486,193,194,356,60,579,141,252,371,160,198,650,781,771,97,548,28,611,731,609,732,269,89,403,815,290,202,735,920,620,276,956,953,32,74,822,799,28,476,438,220,419,318,270,881,564,916,299,737,305,357,816,604,738,826,983,145,653,484,31,993,789,33,830,351,439,913,696,831,879,697,442,662,980,707,633,62,140,343,180", "694,355,855,793,956,543,813,164,278,821,146,194,244,950,380,664,862,661,827,379,343,803,808,820,880,895,704,983,635,346,349,328,47,394,237,850,89,366,860,962,910,748,322,73,243,947,114,239,458,686,83,38,764,811,423,642,120,940,180,831,336,375,527,649,984,399,893,848,129,899,785,842,512,544,875,62,187,559,164,85,371,485,168,772,350,19,148,708,814,60,704,467,56,872,64,647,6,133,723,537,135,393,922,645,339,619,136,76,816,171,659,142,836,560,939,939,718,61,885,694,200,583,851,338,532,690,139,744,180,774,303,331,518,431,511,728,123,912,272,437,614,870,536,393,725,424,632,49,495,12,607,755,516,444,986,260,755,474,14,352,371,7,883,430,8,680,578,946,583,247,637,888,159,349,602,623,90,861,577,228,712,936,212,643,951,81,180,218,746,70,949,498,268,876,519,979,525,336,584,199,128,996,300,830,637,574,151,599,837,67,264,202,207,674,739,739,308,389,459,315,934,234,793,898,992,948,712,625,328,553,923,59,968,282,370,43,635,241,570,149,562,777,760,814,432,574,433,468,941,260,721,838,223,133,883,395,463,432,573,362,529,387,65,744,964,625,373,137,861,503,596,599,0,101,816,66,689,747,211,322,993,932,157,247,626,364,920,294,763,439,512,594,443,204,135,769,689,249,881,589,50,798,246,420,734,943,141,2,219,626,68,742,370,596,528,817,475,365,727,442,706,989,203,118,287,866,705,644,561,588,807,677,885,195,970,615,453,782,432,313,281,857,522,960,865,75,379,732,926,795,352,633,100,197,882,87,666,543,734,980,531,618,4,116,395,686,202,68,554,228,627,513,473,314,226,735,100,408,108,128,614,409,502,727,989,6,978,50,833,774,16,5,595,720,729,603,352,663,934,164,215,857,588,243,599,292,9,542,505,501,683,857,334,884,610,896,599,124,303,172,864,946,919,114,36,563,968,202,956,982,587,368,827,912,319,224,385,794,614,101,394,207,701,334,563,909,47,202,113,657,355,400,677,1000,101,901,400,898,466,36,671,499,96,908,736,353,860,197,28,2,401,183,162,233,409,989,286,543,633,131,849,638,715,381,396,847,840,107,973,704,238,514,243,32,634,26,447,882,523,962,899,836,159,36,705,217,238,765,906,38,593,160,105,722,665,339,549,790,174,70,169,481,390,56,31,430,473,769,204,782,728,287,799,225,698,633,234,640,645,747,984,452,712,376,51,740,14,847,99,904,340,281,520,803,62,849,937,668,714,479,75,505,816,384,824,36,68,581,164,749,802,310,206,946,337,555,303,447,647,399,359,165,447,672,988,814,644,427,310,291,382,863,535,381,787,865,399,864,492,140,678,722,343,554,168,121,448,879,353,601,521,132,83,825,800,714,604,325,962,673,990,899,834,998,584,186,776,451,9,123,931,735,168,250,524,723,418,886,79,333,545,433,835,943,631,24,818,270,607,604,364,353,881,162,587,872,406,405,411,24,848,141,602,709,667,843,675,404,324,808,448,999,140,966,781,846,751,849,817,193,970,829,423,606,927,784,497,501,403,715,78,282,317,592,339,202,203,622,161,186,504,224,385,941,943,633,706,388,569,2,868,636,654,393,467,471,971,915,827,954,98,295,651,365,237,346,285,964,608,548,569,775,592,619,41,557,150,500,14,266,882,220,526,932,346,874,990,218,887,679,51,209,639,908,637,189,652,544,938,78,418,369,244,255,925,640,349,782,835,311,553,179,208,213,326,907,842,546,823,233,724,788,45,548,163,462,169,798,315,55,215,775,812,106,441,218,745,104,122,611,807,720,421,721,515,605,303,66,857,783,886,232,338,676,438,79,681,424,819,860,759,19,841,35,345,400,846,352,942,841,644,239,622,579,811,320,844,587,870,276,189,581,249,272,31,128,925,251,608,180,301,366,989,717,850,648,585,966,463,113,991,953,965,211,184,397,798,709,990,455,12,871,614,705,983,118,924,314,173,38,939,461,849,404,701,515,634,986,712,703,731,515,107,878,642,502,382,897,312,811,198,729,799,70,37,632,297,643,106,594,442,366,601,13,521,316,562,926,237,644,397,306,327,992,375,650,497,637,127,855,154,694,47,56,883,161,45,123,278,909,8,868,909,382,844,1000,716,802,297,305,880,209,554,853,121,690,410,834,856,257,142,646,656,516,654,128,150,160,248,80,446,307,827,680,652,541,564,764,892,772,939,856,408,665,127,872,11,917,634,914,275,683,694,940,141,827,794,758,154,491", "512,944,107,135,45,340,65,442,43,660,859,335,18,123,105,738,566,934,64,419,206,54,631,333,859,484,527,122,411,431,416,682,483,334,141,643,992,91,885,10,505,556,853,897,261,26,793,817,140,505,258,581,338,378,120,786,642,320,57,884,842,104,37,145,632,891,347,248,377,240,57,626,280,695,221,68,335,931,639,245,268,37,852,785,480,25,523,140,775,187,456,763,299,949,86,341,114,7,15,81,93,466,346,180,757,905,692,645,823,450,787,473,561,961,780,201,554,497,240,565,636,378,54,246,628,958,108,778,311,885,36,971,107,438,321,350,773,779,23,515,604,768,613,404,995,883,155,958,748,444,747,310,51,223,904,865,387,268,954,693,667,753,635,898,973,619,882,541,891,480,195,95,220,271,915,538,754,836,646,624,226,346,739,379,486,371,372,738,500,649,8,478,263,658,849,502,321,215,462,66,859,615,222,873,751,723,11,245,829,380,926,297,5,941,412,905,921,70,555,900,386,879,377,181,313,904,31,135,58,451,74,514,609,936,778,851,156,971,453,491,907,62,578,673,406,181,966,180,381,924,128,951,985,443,841,393,639,317,521,63,378,735,167,871,194,348,180,853,816,466,409,538,101,0,799,916,693,649,316,477,464,835,767,994,676,868,304,800,756,700,127,618,96,870,370,376,50,830,542,6,575,215,774,853,515,179,344,391,891,795,614,881,134,752,849,534,89,676,837,998,100,631,42,842,948,81,600,666,190,447,515,483,205,213,930,380,634,102,872,283,995,926,450,674,807,628,707,920,192,27,193,667,474,511,144,164,558,945,528,485,610,308,431,504,606,640,535,498,60,359,696,669,59,55,307,562,880,706,623,663,3,342,765,157,869,985,686,694,345,587,482,601,159,169,177,713,848,256,451,767,302,327,275,162,2,280,894,833,845,601,272,847,719,622,539,973,425,275,514,151,375,441,469,899,754,374,585,231,194,778,509,833,166,834,914,130,882,915,230,664,344,876,423,494,435,761,198,901,502,739,137,932,588,630,362,932,127,470,335,505,302,168,596,458,827,392,321,192,897,263,135,244,619,811,301,446,750,738,396,357,846,674,592,879,182,956,608,415,112,201,389,225,33,471,266,399,140,747,775,845,594,545,236,182,254,625,964,416,683,464,634,826,505,139,274,816,745,87,628,636,69,3,392,296,758,83,666,937,692,354,900,607,514,26,91,201,975,531,567,672,918,347,302,881,466,924,7,655,434,60,314,513,583,481,211,525,977,432,849,465,546,902,733,857,814,654,896,526,619,422,531,722,151,115,43,29,388,783,406,812,628,79,507,655,289,157,609,1000,827,956,580,133,578,369,934,529,585,864,470,957,912,39,359,533,530,461,204,399,190,184,879,276,931,485,396,557,557,910,140,557,936,651,817,199,726,97,672,883,62,963,602,347,933,305,793,176,632,9,809,895,138,558,629,769,727,24,117,932,569,607,498,942,911,119,815,755,809,297,632,278,98,960,924,98,862,342,758,533,739,708,431,184,304,783,868,486,682,608,535,797,280,634,549,962,948,175,216,91,624,320,309,295,435,172,156,38,593,842,142,584,995,107,983,755,785,447,301,382,287,786,510,304,976,526,2,621,847,635,853,510,416,455,105,854,768,305,318,115,430,898,645,627,115,484,365,668,338,378,229,874,787,545,776,598,721,524,69,961,28,525,909,909,476,977,176,831,745,405,529,602,85,830,745,397,451,357,366,316,807,814,607,482,173,308,820,119,708,912,17,862,679,496,741,427,76,860,354,98,180,818,755,852,272,782,635,503,414,771,711,633,634,108,802,482,93,792,418,885,930,136,251,72,174,354,952,574,139,276,949,279,527,908,215,538,343,685,616,901,729,680,388,680,262,65,38,830,987,440,829,466,650,676,867,486,847,748,55,52,631,376,13,187,265,9,637,713,265,648,664,289,787,479,560,124,868,791,175,182,430,996,451,102,734,191,644,348,701,159,724,546,860,154,829,545,570,331,832,793,650,90,123,918,549,400,17,238,286,44,194,769,480,535,70,900,191,12,128,955,271,6,896,695,765,82,866,135,793,478,396,754,377,899,548,264,516,468,762,409,270,483,350,873,144,847,143,510,763,566,798,186,916,675,493,590,201,178,894,112,64,324,481,238,162,684,708,793,574,546,302,132,814,214,874,532,577,589,228,163,801,699,664,330,762,848,584,287,90,982,110,760,438,971,44,700,418,132,962,741,916,822,829,812,242,693,696,95,537,856,840,220", "390,781,868,183,119,552,477,419,471,782,375,471,482,635,479,867,224,137,367,846,323,340,988,304,749,523,337,382,988,420,545,815,958,660,939,463,881,974,414,85,274,305,120,528,548,911,221,797,571,385,512,109,775,511,498,284,534,768,256,18,797,341,375,327,352,429,810,819,399,650,335,775,592,85,130,556,951,528,920,934,462,499,923,857,183,707,747,535,611,985,573,628,134,487,175,263,76,737,850,595,823,293,799,201,861,345,451,980,717,239,139,255,420,755,593,457,298,170,568,939,134,44,681,584,48,131,284,894,206,15,899,657,440,162,407,253,786,248,98,548,896,263,294,293,964,472,514,940,867,39,510,62,627,727,203,286,412,86,377,318,386,660,963,491,232,173,623,238,385,865,706,330,429,139,409,947,825,676,836,221,533,41,36,24,792,987,177,428,24,412,629,432,893,903,698,800,503,59,808,502,992,624,557,945,721,135,399,186,160,811,771,539,32,183,256,319,729,428,846,926,390,426,174,704,907,627,528,498,245,340,701,698,623,172,562,106,391,803,490,500,681,738,618,373,670,952,859,50,953,245,410,582,721,21,920,332,86,196,644,134,353,693,472,759,339,496,766,470,600,926,514,771,816,799,0,551,561,65,793,333,190,292,90,76,737,555,55,397,628,196,53,701,248,738,202,575,903,733,988,220,815,122,163,881,838,419,158,172,32,673,431,742,20,978,258,692,459,873,681,166,937,193,182,499,909,147,737,484,643,812,118,598,982,88,4,944,212,36,378,460,59,988,360,144,823,799,874,96,878,707,490,576,812,58,562,866,831,611,552,266,931,82,753,770,120,866,615,469,934,397,668,925,713,198,905,195,759,857,907,238,494,359,139,171,435,806,338,282,2,700,925,925,750,166,975,198,145,458,772,375,779,461,661,582,476,563,565,97,941,991,807,412,914,532,479,691,406,95,138,231,578,373,987,762,431,891,143,847,410,119,302,98,80,615,552,397,710,22,56,291,833,752,670,314,317,291,953,111,778,36,815,922,721,721,138,489,841,532,819,746,26,412,213,63,232,158,65,835,647,505,546,224,792,189,223,64,889,586,155,15,298,339,997,910,713,879,639,459,30,331,922,654,237,800,226,517,62,886,793,184,328,817,462,788,934,850,848,526,483,218,204,960,492,107,915,240,697,792,738,54,960,645,880,399,210,981,766,28,898,479,697,876,137,520,742,368,791,286,617,312,663,706,674,493,582,295,341,996,657,327,697,168,996,442,371,983,987,367,289,46,166,901,297,520,697,47,312,419,673,216,467,249,547,398,14,896,308,729,225,802,747,281,123,336,358,213,939,606,745,367,559,859,652,371,160,445,822,79,870,316,452,221,126,575,986,99,90,777,836,506,409,915,895,979,843,356,557,691,498,283,721,187,585,324,512,470,74,976,63,581,213,840,824,31,327,545,383,889,852,346,848,626,120,123,627,497,316,657,583,586,911,143,768,259,742,386,438,133,874,442,486,424,412,630,600,926,817,858,945,987,475,1,518,847,282,665,586,344,306,726,47,325,940,693,203,772,489,3,279,409,655,274,796,185,320,165,388,92,496,458,778,491,180,841,561,465,208,268,229,102,567,105,221,882,781,327,150,92,130,792,468,872,341,370,548,291,410,317,81,214,512,933,220,12,872,164,59,570,1000,105,876,228,576,181,425,992,722,194,919,170,480,36,286,96,720,547,562,454,164,343,374,661,277,284,601,378,522,37,446,751,419,749,886,508,812,331,210,878,909,114,384,500,697,425,389,243,69,532,382,6,491,69,406,374,816,487,118,285,301,641,306,945,916,860,804,111,574,588,183,76,750,610,208,385,892,770,284,678,345,660,722,923,509,743,147,825,812,64,108,214,161,72,902,267,263,707,465,677,925,904,613,996,109,518,358,835,400,653,951,525,478,648,200,149,935,569,316,121,871,959,419,532,514,203,827,606,992,903,21,738,816,801,608,425,123,407,962,116,268,36,317,514,217,941,22,885,767,71,303,302,945,786,229,272,138,716,856,261,809,940,847,672,167,721,926,76,614,158,757,445,642,980,805,700,250,44,549,16,199,740,789,762,181,112,187,640,486,646,150,203,354,168,96,744,986,704,692,222,62,728,355,893,930,482,468,557,498,144,5,797,555,778,719,402,696,276,980,440,987,453,453,140,991,734,925,525,936,749,898,51,520,121,662,86,687,536,510,626,929,240,941,46,161,687,215,411,681,123,297,570,834,212,198,73,653,269,590,888,652,957", "913,907,269,768,527,360,543,916,258,662,634,855,447,871,291,168,416,990,789,269,882,746,940,352,532,582,57,77,590,275,5,995,302,601,658,66,300,265,364,5,283,673,648,406,661,872,555,299,730,606,936,370,74,91,766,190,179,459,935,407,943,201,635,279,745,496,607,554,138,894,2,753,149,553,660,110,165,282,567,694,916,921,270,897,4,467,439,934,544,818,806,191,499,253,997,229,448,469,255,123,425,958,929,609,276,685,256,965,304,90,582,800,666,346,523,278,722,666,258,257,300,744,2,118,66,404,803,496,536,76,328,247,492,754,390,590,192,8,825,520,202,389,165,448,597,212,4,157,411,228,810,426,105,382,124,220,959,975,982,804,799,719,407,395,260,678,832,972,319,771,989,286,115,752,15,244,196,492,541,369,58,617,660,617,392,667,724,299,389,704,840,340,678,160,627,925,806,728,663,859,212,739,40,9,943,948,852,776,881,190,635,685,707,751,606,504,544,526,332,982,723,849,433,77,959,165,640,832,952,729,711,666,875,523,475,637,918,208,700,47,697,430,934,445,653,951,255,741,840,260,305,346,458,155,875,721,888,175,255,732,886,981,293,721,48,787,211,909,15,447,971,176,66,916,551,0,737,544,136,250,200,669,30,511,325,94,138,710,705,324,862,457,811,790,981,684,976,248,732,886,420,4,274,808,469,721,291,546,869,317,185,788,278,239,692,212,468,443,116,790,710,795,215,962,156,530,220,323,9,649,681,25,61,449,883,866,327,323,434,975,314,672,208,156,976,676,329,617,27,693,156,705,579,646,673,183,293,432,840,266,122,184,410,617,66,458,721,599,841,610,617,582,572,491,292,70,445,577,735,209,779,465,794,369,886,286,847,835,41,69,386,231,178,812,443,155,5,143,573,498,293,699,362,654,603,974,523,161,76,824,279,427,866,827,970,705,702,446,753,422,786,788,388,853,462,840,921,307,638,199,943,383,596,676,825,281,48,365,763,458,562,728,999,835,14,125,123,59,230,1,223,771,485,74,466,137,318,837,782,33,347,749,90,293,641,440,188,517,551,900,560,511,442,702,118,207,773,804,839,481,543,379,303,673,177,809,603,552,895,948,657,976,677,346,183,115,549,72,292,424,435,597,192,228,727,286,742,869,11,662,517,322,173,548,600,484,725,465,199,351,594,777,376,265,991,411,773,562,18,748,865,624,259,94,807,689,40,138,371,821,816,84,271,590,984,283,254,683,558,670,969,320,530,499,898,869,939,498,838,770,604,952,753,667,566,603,51,774,53,357,426,450,692,922,763,355,655,438,838,54,791,715,207,256,79,427,754,605,416,455,946,223,219,764,724,565,796,24,835,274,337,856,118,718,133,481,360,240,38,916,58,778,967,116,832,376,592,98,164,190,949,537,225,919,932,194,9,211,814,127,217,329,558,886,818,989,966,227,982,296,114,52,537,49,975,871,332,738,833,736,840,848,489,255,257,585,105,427,545,557,664,624,48,78,473,549,337,336,406,549,516,301,299,937,126,682,977,355,959,829,106,392,95,201,53,756,733,382,383,365,270,533,37,375,529,401,810,70,766,892,589,934,209,255,930,927,597,929,397,857,515,918,111,725,795,265,40,79,887,229,529,74,226,473,586,730,221,375,704,903,201,479,778,193,807,854,36,379,186,990,182,147,374,855,60,617,385,631,877,449,871,660,388,823,552,660,29,803,268,808,288,108,600,671,475,568,265,383,357,493,590,263,578,207,904,105,420,489,974,168,378,584,864,78,599,748,267,580,764,574,460,598,360,375,198,457,705,866,506,505,782,41,561,105,589,634,884,192,117,646,376,809,496,934,32,435,274,663,246,970,479,15,713,757,224,967,967,627,938,416,545,379,208,273,526,38,275,454,680,807,796,975,1,735,875,602,511,546,327,380,659,472,895,139,40,393,649,305,307,126,636,10,437,927,787,925,290,772,94,167,266,966,186,275,873,701,656,189,571,450,120,919,333,73,107,313,553,503,916,476,692,935,639,936,810,140,926,178,414,728,298,680,822,601,661,369,8,259,443,976,167,475,56,740,472,405,437,728,911,98,225,385,726,184,555,963,628,690,163,641,273,804,118,779,93,614,862,305,307,125,894,371,848,774,393,534,801,323,346,674,478,101,387,498,549,819,214,436,455,563,172,253,732,476,435,594,399,134,504,331,307,136,723,879,375,785,8,180,343,973,901,511,500,774,600,42,57,746,72,34,562,905,942,638,265,732,981,880,99,260", "118,520,162,746,444,441,874,736,732,468,189,326,694,405,745,819,385,647,280,463,945,187,326,445,433,692,400,573,445,670,3,484,12,775,145,584,474,982,649,531,271,961,675,579,801,39,525,534,568,983,197,753,496,477,630,90,362,812,71,585,943,914,333,97,122,178,917,537,205,757,395,318,431,351,517,82,141,675,92,231,992,422,920,470,893,833,749,778,913,727,507,600,893,838,95,48,995,697,542,491,535,235,136,725,639,380,93,989,601,951,466,288,111,677,537,291,827,541,364,401,756,287,535,258,368,406,469,870,765,630,633,362,784,116,558,414,960,965,705,279,306,640,367,828,491,188,921,330,900,410,375,298,290,464,524,207,182,948,818,310,453,189,150,183,723,620,515,405,548,899,987,326,276,974,744,279,812,40,58,504,793,808,718,814,957,836,579,489,529,525,617,115,99,586,78,922,906,847,276,147,923,214,341,334,561,356,582,627,188,9,235,851,815,906,848,55,570,420,873,537,580,248,654,549,26,306,424,115,614,932,796,897,637,40,925,812,228,199,329,729,836,553,249,497,930,241,211,508,685,809,566,871,59,975,73,117,487,672,721,296,859,356,825,45,403,882,597,242,782,609,283,780,689,693,561,737,0,220,994,17,903,207,123,755,357,28,630,134,977,592,584,556,478,873,382,156,626,599,480,958,354,760,517,331,239,735,803,412,556,237,391,768,296,343,994,971,804,527,582,573,905,620,919,79,563,882,508,506,168,533,904,649,192,765,751,498,986,827,937,220,645,624,618,308,353,733,749,542,648,155,323,377,212,57,562,778,708,913,403,876,449,234,494,922,749,453,810,561,988,377,615,407,701,84,37,296,998,483,508,846,236,376,620,388,415,210,808,345,344,732,270,853,917,927,121,117,971,74,693,14,341,192,587,925,919,645,853,110,817,837,169,556,889,235,647,735,277,230,550,460,254,56,956,942,143,28,281,588,150,407,83,212,577,132,707,376,468,486,637,609,664,123,772,371,541,343,672,309,588,122,596,212,478,29,161,394,447,835,43,855,549,213,995,980,412,650,613,484,604,320,988,564,621,831,99,419,278,897,57,491,242,233,869,815,714,983,890,243,559,403,31,798,628,37,694,680,622,328,770,397,909,434,908,326,329,421,804,162,631,306,712,865,625,915,114,735,444,716,719,462,261,57,779,194,142,500,751,970,239,858,736,581,31,179,189,75,938,34,560,748,588,403,18,260,937,35,550,690,248,467,879,496,263,795,895,977,326,445,682,974,139,806,161,382,502,771,919,438,404,604,208,25,801,914,713,618,26,134,403,370,287,706,805,282,43,49,222,550,105,566,753,611,608,149,215,536,710,163,765,917,766,318,326,822,360,492,122,589,425,200,964,565,310,405,918,916,75,736,237,37,187,786,207,359,379,129,192,262,630,743,509,140,846,402,62,899,548,686,619,166,190,324,850,174,657,42,63,562,305,242,118,900,454,218,629,901,290,464,59,720,442,656,624,545,106,164,347,786,605,836,905,662,360,104,204,401,440,444,297,101,878,165,218,635,955,523,721,266,98,128,149,921,613,665,593,149,125,685,254,982,759,491,587,90,932,115,971,892,784,484,206,562,746,948,147,244,471,426,525,782,687,670,758,51,357,96,774,976,3,884,172,724,475,364,953,377,968,998,990,856,657,973,82,197,779,796,192,549,976,780,756,912,996,363,650,791,624,641,450,342,297,910,77,849,381,169,712,200,106,261,117,345,835,866,72,358,730,504,773,919,683,241,143,698,341,221,116,750,799,143,641,274,405,714,514,81,602,739,587,571,246,682,485,273,961,25,837,147,132,942,335,206,228,705,738,50,149,878,917,342,754,630,634,793,303,66,325,370,534,840,456,286,159,990,515,776,242,180,763,690,876,707,979,473,179,923,4,675,23,897,408,992,284,546,181,832,73,922,728,56,953,877,43,633,348,502,802,127,282,946,708,4,343,590,836,469,710,608,297,640,581,419,400,962,278,736,170,968,636,624,360,532,98,827,609,993,496,653,995,724,454,918,649,121,580,643,949,562,152,503,519,511,796,455,412,85,163,280,824,871,597,341,281,35,62,110,270,434,310,808,185,513,244,482,752,813,219,519,410,103,222,130,338,649,253,796,633,812,742,231,441,950,382,329,730,564,704,806,316,473,772,52,838,876,231,25,979,926,91,842,856,642,633,563,269,359,433,540,411,181,806,405,330,775,433,989,561,242,370,33,116,421,473,16,884,502,904,669,133,207", "776,52,197,162,102,988,356,57,57,724,387,189,887,57,326,811,108,710,473,25,564,292,844,444,763,390,3,473,392,708,494,538,580,21,803,612,717,857,151,850,236,952,346,400,277,137,846,334,628,160,639,538,623,34,605,974,401,837,830,236,191,653,268,478,667,488,529,36,196,565,636,88,972,31,139,93,442,940,606,306,34,53,565,65,404,928,623,699,550,206,732,53,661,411,16,777,873,626,56,414,409,842,919,316,966,645,237,961,996,92,604,139,358,495,177,662,692,234,802,45,929,78,468,657,982,113,589,393,181,92,374,889,73,269,221,202,983,142,751,994,639,100,974,550,975,811,516,772,617,366,272,232,46,667,904,462,550,871,324,85,561,57,247,128,130,899,113,356,854,99,61,288,449,737,143,330,700,42,688,166,447,26,387,285,397,385,990,720,644,286,155,822,620,903,512,591,437,957,486,98,618,403,872,382,420,210,839,901,118,179,566,107,112,406,360,829,685,667,716,15,596,354,407,667,918,102,273,30,692,723,40,806,826,286,62,980,307,745,464,319,581,93,768,66,314,675,61,621,130,175,157,497,376,649,976,200,638,124,972,640,847,809,550,234,775,105,62,50,339,281,449,864,747,649,65,544,220,0,297,593,326,107,822,262,399,451,818,974,597,221,991,476,839,724,25,218,605,925,101,572,148,477,920,210,786,572,75,463,2,251,755,347,938,31,187,891,13,786,556,723,919,538,45,712,223,853,359,410,657,837,927,849,468,414,188,2,39,390,281,671,209,309,83,718,72,497,81,787,840,134,313,177,13,390,149,232,181,271,52,108,449,182,2,366,343,748,105,581,162,16,653,137,881,482,260,465,535,109,70,27,328,505,652,262,288,224,504,906,124,645,89,535,103,614,594,872,47,704,298,98,172,654,5,873,434,247,978,795,355,454,209,362,11,603,282,245,668,368,199,961,378,123,442,386,641,561,612,770,378,480,755,849,271,230,378,867,581,253,883,596,88,874,209,671,230,236,223,508,209,861,671,721,563,936,490,749,49,641,675,800,144,191,14,7,468,826,97,447,74,883,796,125,772,166,305,51,910,114,342,856,480,439,16,664,984,994,993,515,738,540,33,126,804,84,973,91,937,996,379,666,581,30,674,241,779,821,666,671,896,749,288,16,191,979,905,632,65,978,755,417,31,870,240,297,776,536,620,643,330,15,349,847,995,735,144,970,684,242,609,553,329,320,403,956,94,298,714,468,427,858,339,795,769,248,436,515,833,565,347,776,874,526,5,807,738,186,97,530,917,753,506,644,325,39,913,776,728,553,966,697,850,421,232,863,203,600,682,222,539,783,637,902,333,774,889,571,576,630,625,304,618,13,157,584,958,806,274,743,137,347,290,820,433,618,115,825,423,764,433,879,287,394,355,973,96,374,289,998,737,515,226,121,190,25,491,272,506,321,436,923,934,566,631,29,329,488,961,635,657,318,715,384,133,617,13,729,988,832,195,385,587,730,46,341,583,701,459,461,965,710,436,469,279,889,983,68,811,824,753,108,740,407,33,902,400,932,675,504,999,686,426,276,769,795,626,254,817,735,605,125,725,323,379,794,856,723,514,125,370,162,837,405,865,467,591,965,899,884,588,810,254,722,359,5,453,562,558,638,746,944,546,252,127,953,839,820,621,271,866,148,270,966,642,142,905,908,694,489,62,290,281,746,506,774,974,150,797,721,769,265,409,869,80,44,474,608,864,142,243,679,740,11,154,685,176,390,434,197,345,76,846,694,19,966,427,191,890,606,734,13,912,118,741,113,858,108,909,640,996,431,760,924,432,909,612,440,149,895,750,191,475,513,709,409,260,863,863,369,670,743,798,664,484,402,485,285,739,811,956,727,783,328,604,297,226,451,725,252,725,678,142,6,335,647,820,155,570,559,920,344,845,835,30,310,600,669,44,619,313,38,756,357,3,870,769,418,363,539,274,354,969,930,785,104,17,383,640,247,121,729,439,898,439,421,852,330,517,24,555,90,875,62,566,140,682,609,935,437,313,158,86,133,889,362,965,709,840,784,258,648,895,683,281,16,83,514,560,63,660,276,538,311,956,580,570,120,187,589,781,310,445,835,367,936,429,51,261,307,499,188,352,14,583,699,131,711,115,622,490,722,943,866,278,339,425,842,560,520,871,720,916,364,765,495,665,363,735,102,548,666,140,169,957,667,458,162,648,547,122,560,512,430,335,932,801,856,986,31,626,857,427,421,218,394,346,650,529,63,126,259", "441,669,338,3,62,911,33,504,651,52,557,369,529,596,698,819,118,786,895,785,220,102,314,963,844,219,868,626,431,977,628,292,956,33,781,37,492,234,827,301,96,913,779,871,663,827,442,810,259,773,22,950,906,697,499,14,266,269,766,688,739,155,656,528,957,619,344,258,64,196,216,971,33,356,53,192,573,825,851,904,597,289,102,988,84,661,642,274,775,496,917,61,998,938,974,321,954,72,437,878,789,207,759,836,55,304,284,937,29,549,863,166,717,542,226,585,837,867,733,624,884,543,573,749,745,327,132,826,371,963,427,416,494,167,785,442,122,232,25,88,287,833,99,766,887,777,773,782,138,443,627,643,861,830,518,195,396,220,376,758,252,347,137,150,262,565,143,701,90,885,60,10,528,385,818,164,964,167,99,615,193,559,459,657,253,976,573,22,313,700,330,962,855,897,868,82,800,847,77,728,125,559,879,707,992,493,393,989,472,396,975,766,581,861,903,31,166,531,10,971,146,811,51,867,246,774,946,143,467,112,826,657,149,165,799,523,9,728,352,719,568,387,789,621,449,489,659,816,42,921,750,858,730,988,973,578,154,301,95,740,23,780,45,579,739,362,996,733,135,10,371,870,211,316,793,136,994,297,0,45,911,816,531,948,127,569,709,377,345,873,978,580,101,769,250,96,709,863,991,496,797,664,464,776,32,432,141,315,44,38,418,824,875,127,192,424,122,534,895,654,148,216,261,280,392,899,901,105,393,538,392,150,875,994,68,523,876,410,153,200,774,821,374,505,747,796,504,754,415,171,689,684,429,423,541,398,856,274,767,6,930,913,475,191,530,825,544,564,313,972,223,717,48,595,855,492,780,771,489,927,956,950,980,954,683,669,874,443,599,906,60,380,869,187,452,367,53,505,597,79,358,234,88,292,461,520,396,298,166,458,172,823,51,627,349,702,191,534,244,451,781,678,345,274,793,493,428,338,766,935,730,399,494,331,941,387,806,479,53,810,142,852,923,377,279,277,541,93,296,154,948,873,549,737,447,463,798,372,424,640,451,162,262,423,520,414,573,634,118,583,614,263,715,264,672,904,288,313,919,450,336,141,483,49,878,696,777,955,636,386,128,675,120,68,194,350,97,192,995,393,494,413,919,197,487,140,159,464,596,864,812,852,753,102,763,54,858,114,330,764,78,152,308,218,729,621,627,953,951,89,378,784,600,771,219,634,528,776,116,810,756,54,570,127,701,623,264,616,23,447,191,158,193,933,183,186,371,925,396,30,738,211,952,101,107,591,790,24,233,331,178,995,526,472,58,612,470,490,821,860,474,174,606,976,322,109,664,350,851,368,320,217,172,754,908,731,933,762,698,204,306,370,158,70,333,810,156,195,170,308,175,737,654,849,290,480,460,660,726,35,989,344,720,466,110,355,881,90,345,740,877,257,142,527,178,624,688,112,892,350,178,628,839,59,155,76,260,606,223,966,956,658,405,583,465,304,132,332,262,649,293,28,259,364,879,54,545,665,417,2,247,393,123,943,333,104,532,93,941,263,304,71,932,811,713,216,292,349,96,774,827,17,528,692,960,348,878,401,981,85,718,60,666,412,926,30,557,438,475,247,24,668,542,227,510,298,291,360,2,816,355,205,214,920,566,704,974,413,913,447,508,135,249,382,6,40,266,345,533,96,469,298,155,417,962,59,491,596,491,814,202,727,475,325,433,172,161,248,925,583,613,915,33,11,732,186,144,419,62,45,126,248,833,837,309,719,120,637,283,232,151,234,722,61,998,94,262,817,948,933,941,489,480,222,20,848,675,751,964,606,937,389,544,374,990,256,300,2,255,959,504,818,22,112,110,547,350,787,445,134,995,989,361,468,925,586,835,177,59,673,510,430,881,808,24,491,846,491,639,48,657,339,346,914,389,76,355,777,275,750,651,3,461,922,320,490,661,998,664,24,328,311,316,415,947,28,722,307,710,269,145,889,50,315,409,481,784,20,504,940,164,155,281,438,562,31,752,259,955,716,267,512,567,528,225,637,459,248,225,519,107,361,362,443,800,630,796,311,761,87,754,433,937,748,840,449,884,449,378,705,266,489,299,537,908,6,512,395,430,589,754,237,793,922,292,103,78,919,118,27,579,898,534,376,592,704,117,833,641,739,446,356,707,728,313,815,897,424,252,282,800,294,619,887,573,389,762,144,730,306,679,731,762,127,783,37,358,740,306,359,309,534,530,829,965,307,87,991,845,481,924,363,296,435,703,209,452,224,68,3", "438,597,314,73,169,846,518,204,810,110,56,357,930,930,649,817,752,629,85,620,93,418,623,145,410,526,725,768,364,86,469,334,370,691,811,496,73,926,477,200,383,697,179,756,393,227,998,917,978,506,753,710,405,726,108,276,550,760,360,215,897,71,727,510,13,91,531,15,957,172,180,162,639,203,283,431,288,920,919,865,552,732,481,871,689,310,883,722,191,926,670,582,287,722,330,260,389,830,189,429,443,572,902,317,829,868,760,326,133,273,987,463,555,546,260,159,852,687,45,136,185,983,861,259,154,204,675,324,820,850,89,393,77,814,219,549,779,599,903,296,287,643,297,571,169,582,403,900,243,205,378,300,295,363,244,493,463,36,166,11,262,350,222,446,475,168,204,176,533,560,204,134,978,254,523,359,683,338,268,737,227,750,845,909,448,883,121,671,861,477,80,253,516,476,886,181,347,751,859,968,754,892,733,383,663,504,365,551,914,670,98,193,216,878,926,101,267,371,578,25,81,54,704,734,471,493,871,227,650,311,775,309,317,920,292,66,85,473,875,488,60,150,570,180,922,901,952,240,66,669,263,840,198,72,323,261,422,539,13,458,363,741,59,975,717,904,142,591,134,104,731,15,322,477,333,250,17,593,45,0,682,770,810,251,109,575,6,188,15,993,630,974,936,985,725,231,569,298,346,757,965,625,448,874,75,326,116,412,849,221,584,442,510,994,133,200,316,458,325,50,187,656,388,664,211,794,154,685,435,963,703,628,972,729,203,247,889,999,116,924,495,614,394,295,950,90,223,74,462,534,833,240,226,222,431,179,254,800,449,722,373,700,385,419,530,377,726,492,89,212,166,889,891,543,762,361,357,110,308,566,589,527,784,202,183,25,516,484,487,119,46,376,658,321,125,655,531,820,847,649,451,336,471,675,142,478,188,708,308,318,315,102,329,558,793,132,80,385,961,656,894,707,460,873,695,27,623,371,335,889,398,75,539,647,429,11,40,9,975,700,513,769,508,79,458,325,866,930,287,295,294,751,477,192,270,748,66,149,373,381,936,519,958,309,867,960,878,343,504,320,323,582,740,737,473,65,196,203,358,596,65,137,892,563,173,857,642,681,246,503,863,140,921,834,959,601,470,734,605,320,787,383,846,173,671,392,64,830,314,805,983,946,62,563,957,886,331,324,258,89,388,522,567,864,592,886,668,301,832,34,909,627,572,186,211,886,289,894,530,110,266,781,847,786,370,829,213,317,632,580,381,875,629,102,977,544,997,633,363,653,121,36,324,922,842,61,567,68,46,693,916,145,971,177,183,23,895,734,311,868,157,523,157,715,944,774,947,359,193,46,749,321,778,155,365,808,930,803,856,710,572,717,114,969,550,308,667,613,388,314,706,518,790,33,728,744,413,815,972,755,74,134,519,345,792,372,583,571,967,516,846,497,865,221,258,777,605,195,828,274,619,319,846,2,986,586,211,112,998,552,504,807,645,870,457,76,380,651,129,573,621,341,17,697,194,938,725,526,303,512,617,911,371,817,565,462,685,866,596,46,974,771,565,358,410,877,193,459,829,99,273,301,972,916,901,143,970,509,182,38,685,112,11,554,950,729,272,689,459,534,468,261,991,795,972,240,184,678,993,958,182,315,649,515,247,408,908,271,389,632,791,564,153,355,438,179,716,46,390,234,769,978,448,782,572,921,138,119,218,154,889,702,711,353,578,499,610,577,38,534,467,55,198,835,251,476,941,577,93,758,856,933,19,694,284,26,867,530,285,151,9,746,458,807,241,691,267,924,128,639,953,209,941,658,250,906,745,480,96,56,185,767,87,261,739,939,341,939,872,323,202,369,580,52,254,731,422,247,887,675,709,107,194,445,983,27,222,688,880,222,195,703,588,22,915,306,838,134,770,600,91,44,774,664,509,339,444,979,597,668,568,913,74,411,98,481,424,59,308,730,983,715,35,186,928,726,601,531,713,485,124,116,861,318,288,776,682,929,659,977,342,566,579,820,507,729,825,433,70,295,918,375,114,823,806,552,59,60,357,297,715,895,666,999,13,390,849,681,113,44,889,874,286,982,808,682,34,38,711,75,985,602,828,504,637,243,337,551,555,579,403,432,516,364,885,349,920,584,127,371,611,194,391,698,759,166,430,457,367,311,38,736,89,883,674,652,37,856,197,996,553,174,848,112,654,868,253,187,570,506,625,555,536,452,881,238,710,11,981,502,241,657,517,210,326,334,396,62,822,306,432,745,429,520,295,463,711,39,281,875", "488,292,996,810,396,39,998,868,559,936,324,598,618,517,794,882,353,702,264,293,6,228,114,873,978,830,537,462,987,375,948,681,809,437,495,687,601,560,129,296,881,491,388,354,291,82,160,815,126,796,104,32,329,534,953,147,426,55,81,299,815,709,262,819,769,965,879,33,172,217,884,583,937,638,511,982,412,927,862,920,617,435,539,824,582,260,940,638,1,615,249,397,201,109,797,469,94,470,726,802,887,28,211,605,326,206,627,781,739,819,309,483,699,962,65,217,840,449,245,367,701,170,709,489,512,472,324,824,961,356,686,742,492,465,426,537,152,49,883,121,5,999,911,410,525,540,765,535,822,4,20,419,399,805,86,16,573,787,482,710,1000,394,862,610,297,39,542,915,800,260,666,489,508,422,98,71,326,176,989,473,229,205,780,757,239,431,986,976,251,413,519,930,93,202,901,540,751,341,991,33,511,817,939,429,285,195,789,870,816,324,636,198,63,914,617,566,775,320,214,744,23,946,573,639,683,706,22,856,840,780,27,552,598,896,947,708,47,443,538,474,849,201,846,741,453,368,874,917,384,838,30,887,968,369,751,259,608,523,261,189,562,999,339,118,499,996,766,724,838,693,669,843,993,464,190,200,903,326,911,682,0,406,283,870,599,348,147,541,683,694,935,25,500,264,305,632,464,993,379,342,450,476,655,974,965,87,511,457,31,800,904,883,673,713,490,865,554,969,987,133,149,259,604,641,643,260,830,264,549,928,423,612,521,64,327,766,25,943,98,632,343,638,695,30,193,494,266,493,238,173,804,159,553,593,46,242,38,357,140,789,155,60,380,100,462,775,26,703,122,616,973,490,801,166,521,199,970,467,557,885,607,869,794,62,895,730,679,75,500,246,457,714,52,132,532,287,685,517,368,499,126,416,479,800,91,771,393,912,552,151,698,338,47,711,264,658,105,509,252,104,281,671,429,754,514,674,858,320,484,739,983,103,79,703,108,435,238,529,820,474,798,178,846,737,898,420,677,880,169,305,621,745,172,52,67,783,449,629,318,323,7,992,867,463,583,742,801,552,458,500,413,965,805,828,16,454,927,914,23,61,13,727,548,915,888,353,388,443,599,615,157,240,666,926,818,652,855,592,137,618,931,737,3,828,559,11,749,569,990,929,583,581,761,247,150,787,394,921,297,167,948,415,806,530,447,599,222,119,73,81,358,405,398,21,984,688,594,178,63,684,788,302,150,859,256,944,263,299,778,258,800,254,120,203,881,644,524,928,14,966,287,290,120,313,642,752,557,873,711,358,627,405,792,889,545,372,294,139,333,12,742,491,96,365,632,398,26,582,843,146,528,742,894,622,965,665,424,869,440,637,825,477,691,508,982,412,937,790,726,949,465,923,722,812,124,559,115,58,436,245,464,702,407,416,953,319,809,876,697,510,326,69,700,664,687,48,441,222,903,62,247,335,884,434,396,508,208,305,923,767,121,135,190,244,592,434,954,623,204,488,874,803,314,976,274,502,802,608,938,692,77,456,496,539,323,716,547,302,84,37,369,355,975,440,930,514,340,491,724,464,324,43,738,466,422,596,291,337,662,920,916,241,84,976,591,192,39,831,232,966,710,358,12,690,877,943,889,41,50,716,187,884,637,325,863,597,266,768,384,268,389,209,799,327,709,863,767,195,85,101,790,225,894,794,334,19,846,850,90,240,413,88,708,635,830,620,338,552,799,521,901,137,42,521,354,32,174,786,129,121,526,446,565,769,843,39,273,885,60,332,999,266,265,270,462,87,618,304,771,708,71,504,58,33,214,927,119,932,616,139,938,575,501,660,438,298,791,954,551,480,287,973,488,394,727,82,87,161,919,390,491,819,959,384,215,164,712,733,960,419,78,890,998,61,190,430,577,771,516,700,496,500,123,856,584,546,580,760,182,381,265,219,953,470,752,112,807,445,449,292,298,487,443,579,966,479,78,744,637,613,293,541,968,450,756,934,963,155,371,320,480,951,530,18,390,5,360,535,901,256,743,951,893,153,705,438,684,957,97,672,699,594,740,629,377,928,16,518,751,743,616,864,4,815,554,566,27,828,282,480,846,933,602,394,484,34,696,872,26,804,96,721,202,762,346,398,189,576,359,812,725,948,423,317,843,298,724,168,77,921,201,145,186,157,364,207,83,156,340,851,517,474,367,362,807,870,954,833,454,757,690,425,204,677,391,671,912,321,545,375,674,719,309,917,340,410,201,613,874,552,437,282,764,572,586,771,641,411,383,895", "187,269,294,559,806,154,110,692,307,392,285,119,981,297,94,715,225,650,616,112,946,334,228,557,814,227,687,32,338,749,741,381,329,111,613,319,136,188,41,590,293,397,934,412,472,664,841,858,421,884,298,880,792,495,255,353,616,654,890,652,269,604,708,78,35,669,443,876,375,477,53,836,374,643,531,156,582,946,547,493,530,194,484,706,930,681,910,622,96,515,376,653,557,242,740,238,876,141,627,447,306,227,947,615,381,211,171,846,243,534,999,291,77,19,705,605,786,1,735,566,903,138,709,281,346,847,501,623,168,100,224,356,979,329,663,850,131,60,768,878,937,560,866,210,8,224,847,462,733,523,978,254,456,439,781,760,16,922,526,532,526,763,494,488,276,670,948,278,480,893,201,813,529,227,383,845,202,427,93,857,514,292,306,566,859,972,479,549,916,741,284,456,22,808,457,211,797,370,560,920,577,27,927,991,47,446,907,523,336,319,447,134,480,646,737,531,794,254,525,234,357,138,941,779,932,679,402,232,666,871,991,94,30,957,786,425,101,988,634,73,996,336,477,150,877,947,381,703,568,456,92,323,861,382,735,761,355,977,383,45,860,33,238,284,899,457,633,472,518,605,44,743,932,835,292,669,207,107,816,770,406,0,98,44,299,473,19,134,524,823,192,565,195,659,885,772,682,85,565,141,944,725,973,216,570,753,922,487,479,146,241,785,522,130,773,631,484,437,273,270,414,32,37,293,348,724,273,224,136,479,575,504,153,863,516,661,295,127,696,219,98,254,76,639,873,574,164,312,694,829,721,606,395,767,215,398,402,683,590,517,836,842,738,719,348,1000,723,354,510,932,14,9,261,926,329,6,679,296,217,282,960,616,80,261,389,972,144,452,17,265,151,593,8,52,732,681,28,761,866,722,756,873,28,747,593,966,300,133,942,221,990,672,239,937,521,59,703,223,352,770,273,435,667,275,333,570,480,877,582,620,420,945,55,426,869,473,454,161,867,472,461,647,338,969,299,440,19,896,836,650,784,770,540,907,510,896,618,986,541,294,209,430,285,840,547,201,156,256,992,566,616,911,469,445,256,16,760,865,672,305,700,876,633,215,512,104,247,450,696,21,156,394,641,681,228,740,52,855,315,620,783,307,189,484,939,541,880,647,903,243,933,729,544,286,173,787,356,62,825,250,163,894,54,939,129,895,733,400,472,672,568,304,978,989,630,647,253,174,660,870,743,61,232,81,241,791,278,263,210,908,919,1000,483,921,747,933,185,918,131,185,840,343,467,714,757,59,297,160,35,288,74,183,299,12,316,56,542,22,925,853,672,907,244,434,835,75,512,349,882,57,291,907,694,463,352,5,974,132,185,762,335,575,551,384,218,873,871,552,705,790,132,117,399,269,486,691,598,95,280,790,567,936,968,81,609,155,792,736,89,712,744,546,980,354,631,856,149,760,978,177,228,522,720,2,487,24,69,529,70,683,498,359,824,588,656,324,24,971,336,781,673,917,376,348,169,956,631,401,971,839,468,972,613,150,909,591,759,676,53,346,134,398,221,901,549,216,873,841,420,834,643,514,109,162,796,966,738,845,811,564,222,82,365,671,496,891,28,477,840,19,635,584,915,717,638,148,266,736,792,80,861,410,785,281,541,944,714,176,658,165,587,181,215,935,649,49,712,742,119,426,474,578,113,819,50,522,687,612,159,30,812,876,23,286,442,749,215,536,770,799,262,881,253,373,47,562,790,237,572,432,2,749,481,718,148,612,414,72,839,940,64,806,110,730,813,707,957,660,556,847,47,185,329,627,144,241,191,575,621,789,365,809,762,385,299,362,74,130,309,975,71,559,173,535,65,465,696,594,377,870,865,944,685,166,433,665,156,123,774,494,499,813,187,277,257,815,912,623,663,784,993,666,374,449,999,837,191,909,309,110,175,615,307,758,112,273,328,655,509,408,315,821,246,778,794,815,607,29,383,47,757,123,368,175,718,771,683,125,686,183,912,821,817,565,235,294,248,374,232,862,174,371,589,430,720,999,659,911,778,99,505,486,146,161,153,215,833,309,6,803,350,499,930,869,226,985,735,865,298,771,929,90,873,744,728,590,818,616,935,356,262,20,771,444,961,387,705,941,708,348,857,92,932,86,985,295,559,389,127,303,509,374,593,58,978,687,372,78,163,915,680,401,142,236,597,56,526,585,56,479,298,91,472,452,647,607,528,167,644,862,859,847,419,952,661,378,475,469,444,818,183,448,345,747,595,111,273,507,211,910", "813,463,133,822,906,10,306,404,586,778,579,848,790,949,923,941,557,685,786,807,890,962,538,27,686,893,969,419,468,344,860,938,835,989,837,736,122,850,359,358,798,376,904,728,52,862,322,861,240,883,491,367,76,987,494,413,126,683,44,25,166,658,642,563,539,294,606,745,689,138,276,803,503,84,107,882,929,487,293,510,487,511,240,466,19,833,322,683,322,41,813,615,894,613,307,322,439,279,923,281,424,784,651,235,10,47,597,507,676,821,643,468,34,930,586,989,603,275,586,296,60,265,981,991,907,668,152,666,770,939,315,256,723,981,928,600,987,740,879,734,214,212,531,313,100,262,855,460,933,367,953,200,179,949,894,609,867,910,704,67,167,398,922,689,209,573,197,912,701,535,589,454,309,40,472,338,234,298,75,816,879,15,555,77,915,708,617,661,753,969,63,213,762,376,206,92,44,755,36,655,836,65,233,368,22,494,184,421,404,575,570,950,571,760,299,230,619,283,421,203,896,559,12,388,136,871,611,648,986,523,22,13,794,208,53,994,13,970,298,892,100,85,233,851,212,609,568,811,128,849,40,558,320,567,32,418,118,924,893,947,643,463,456,70,455,279,242,895,307,450,7,391,157,767,90,30,123,822,531,810,283,98,0,529,432,506,274,139,547,795,952,26,414,287,521,260,111,832,803,405,215,757,457,29,293,231,504,135,24,781,12,84,401,262,487,512,811,231,502,940,446,551,827,832,593,297,733,946,23,865,917,64,987,714,237,549,780,386,77,814,681,570,558,859,578,546,788,719,181,466,190,891,938,213,667,409,310,294,928,291,157,610,485,386,453,827,918,365,341,25,413,348,7,363,437,565,458,670,186,63,454,406,393,105,880,199,761,654,520,894,731,104,346,714,68,240,888,560,412,420,992,723,764,565,510,993,6,304,422,550,210,447,814,779,532,650,799,113,435,517,492,92,371,72,478,338,370,31,995,879,973,611,496,480,384,730,147,73,987,492,298,255,269,486,380,142,16,113,940,51,843,674,713,979,584,495,890,807,223,622,998,845,603,512,251,554,975,152,270,310,248,313,51,745,363,107,265,759,423,511,210,411,661,848,780,769,550,299,678,919,136,590,722,208,734,619,279,948,419,678,547,836,980,743,252,8,889,328,455,954,341,735,854,176,937,347,433,221,545,496,303,335,456,681,745,831,828,252,965,954,613,756,771,126,626,831,145,30,950,952,275,325,411,672,571,284,6,399,936,706,67,943,932,74,829,748,111,481,815,157,569,20,538,381,614,446,39,907,646,869,220,452,130,332,490,914,861,773,666,142,459,158,139,327,27,386,718,366,995,341,978,905,588,960,682,884,626,487,795,843,829,189,180,583,993,699,349,471,864,100,376,332,349,72,944,45,771,123,513,805,279,814,788,375,324,34,420,865,523,186,408,753,908,848,267,751,343,117,55,243,900,451,809,872,270,732,311,383,432,526,113,884,385,270,683,879,436,180,707,781,905,51,291,494,158,713,631,213,442,152,792,701,585,943,665,821,552,353,206,768,868,21,797,954,761,958,881,307,154,34,168,361,885,976,276,857,416,764,257,613,290,550,68,902,107,58,211,844,604,247,387,751,936,12,826,37,367,548,561,358,522,316,338,706,960,341,903,721,736,633,272,126,202,109,791,770,174,28,663,490,264,778,914,361,567,515,130,887,525,703,372,86,379,739,503,342,455,981,276,459,100,43,90,820,109,465,162,894,406,412,275,435,508,949,577,728,728,824,334,928,772,987,826,55,277,243,316,439,841,912,235,636,271,19,406,764,657,839,274,78,974,715,135,565,349,234,571,390,697,197,822,532,891,671,504,610,283,437,626,616,718,464,929,546,101,736,299,227,369,258,872,460,967,153,870,155,908,302,230,450,907,971,166,233,829,133,943,620,406,305,170,636,417,831,794,483,783,526,969,550,693,907,703,871,316,560,862,998,935,259,591,465,865,7,497,178,332,276,703,963,404,608,818,828,710,377,51,564,468,71,81,147,97,979,518,18,791,595,193,848,89,601,100,76,993,700,790,67,426,811,279,343,939,71,58,947,847,875,663,810,788,307,6,395,345,340,490,976,545,762,556,240,218,464,397,833,686,902,998,597,633,47,904,793,783,999,944,328,460,813,486,440,514,80,468,34,35,730,504,452,686,60,251,99,581,414,625,265,234,604,956,383,83,671,179,149,190,879,192,305,994,773,827,348,697,327,899,582,734,711,849,589,603,634,216,134,200,314,481,605", "668,378,874,836,889,577,25,680,80,750,696,553,196,388,798,429,522,460,207,637,448,968,491,583,329,881,355,639,173,544,170,460,167,314,713,337,261,770,957,713,889,702,754,608,707,470,986,671,713,297,507,920,900,650,853,252,724,812,48,739,4,575,611,151,288,561,676,301,343,528,6,961,358,366,709,118,38,71,544,169,205,188,869,373,980,868,957,274,956,261,824,638,558,63,544,221,320,455,914,792,402,2,190,562,320,608,386,271,10,648,622,429,801,109,64,661,896,752,698,957,626,486,794,146,120,503,911,18,571,506,215,351,409,266,410,252,440,529,85,722,159,311,197,445,912,570,386,214,100,867,240,305,153,208,29,818,15,687,144,716,376,585,372,422,957,110,446,644,49,14,273,52,188,969,518,39,75,627,85,345,659,459,278,528,176,51,309,487,576,876,466,80,414,744,692,793,143,343,869,300,300,301,634,651,890,740,528,950,311,37,148,920,894,887,667,257,395,429,302,610,576,315,744,575,590,73,299,817,592,924,886,547,861,744,868,544,848,226,219,992,813,938,505,650,182,54,640,956,971,766,228,248,281,429,393,396,108,118,279,823,292,765,874,856,950,811,251,843,624,177,712,965,247,994,76,511,755,262,948,251,870,44,529,0,337,752,259,452,332,840,825,467,700,795,123,411,996,818,99,839,482,560,170,329,359,510,602,861,388,359,771,297,131,804,981,859,581,124,789,368,145,561,178,192,844,518,868,446,62,410,409,410,682,381,319,339,943,636,636,424,156,234,152,956,1000,162,988,433,475,779,544,666,496,469,616,488,376,930,259,970,148,560,924,643,567,571,482,77,37,372,147,447,202,68,472,208,483,234,829,751,703,588,550,110,773,558,991,487,862,889,637,10,807,485,545,537,666,413,970,701,116,948,223,320,573,37,381,630,729,987,494,858,46,537,282,899,412,805,389,198,17,47,408,705,433,432,216,116,309,946,152,807,793,454,200,652,720,778,715,723,276,13,76,37,180,26,911,70,499,591,516,464,388,441,290,978,533,870,7,656,9,314,424,752,339,33,371,754,700,980,377,825,174,845,509,713,346,948,413,341,762,985,18,74,400,447,159,575,71,977,826,970,157,564,584,318,960,567,714,575,460,446,454,487,954,813,487,905,85,27,355,714,642,720,124,712,449,985,483,74,746,673,737,539,550,558,471,181,599,716,113,719,741,111,819,171,769,271,27,390,73,476,911,912,72,65,796,903,788,171,52,198,332,359,524,178,13,53,329,711,927,629,70,714,487,202,652,408,455,352,452,641,746,863,658,943,2,255,211,459,138,384,188,474,887,585,415,34,823,602,996,261,79,784,278,964,741,880,519,309,133,687,502,686,213,717,185,96,809,134,850,834,542,340,132,998,868,18,153,625,808,385,473,247,538,998,153,360,762,384,826,61,311,827,352,781,742,292,182,761,873,379,832,829,854,202,67,959,758,70,780,21,202,98,349,265,219,44,742,927,605,230,382,945,866,172,367,887,40,484,55,769,48,469,935,782,12,494,448,45,134,535,915,531,649,352,643,941,99,789,52,959,928,7,220,662,820,118,961,258,208,107,992,113,22,636,500,115,866,203,464,40,330,697,733,530,701,348,920,849,793,328,544,26,203,946,981,177,9,50,454,529,814,353,788,675,832,434,174,411,642,883,978,74,372,14,970,357,854,662,241,245,730,586,22,63,836,769,144,368,392,384,745,490,438,997,844,947,861,673,152,694,898,285,884,937,462,297,393,372,673,468,587,186,489,972,498,143,429,630,688,55,851,126,314,825,782,619,349,102,246,259,686,756,188,708,509,166,169,90,610,426,815,89,336,386,525,677,771,901,251,818,451,650,774,652,342,673,715,408,428,674,32,164,994,807,28,69,328,135,186,679,699,788,820,86,903,201,840,95,280,391,983,592,162,657,461,645,297,565,352,395,884,188,780,935,160,694,368,51,984,1,282,160,942,470,747,364,283,156,562,222,777,99,763,186,658,648,372,292,307,6,679,95,915,446,270,247,722,543,403,599,384,950,625,355,175,720,821,296,248,204,29,594,224,786,150,505,8,594,73,96,250,986,873,2,653,224,727,437,746,22,878,780,428,34,744,823,451,426,794,859,369,658,878,187,534,629,104,17,779,804,525,921,438,128,368,113,129,370,654,238,275,132,192,2,112,100,716,801,638,891,663,226,288,227,286,571,614,778,320,946,433,816,869,247,709,532,366,238,821,7,363,819,218,533,565,517,278,976", "373,64,638,74,931,874,965,681,625,872,111,387,925,28,491,410,644,982,162,913,102,161,528,843,611,246,141,417,237,452,126,728,227,447,981,87,203,777,177,898,703,256,499,484,244,578,807,474,818,984,337,758,634,320,283,730,905,510,988,890,108,739,600,724,396,267,252,29,234,863,400,424,446,995,570,309,573,228,254,890,785,300,82,986,433,809,29,622,334,616,378,591,603,313,312,105,489,282,974,39,376,640,797,482,638,995,512,719,404,410,249,534,155,917,302,537,153,895,505,34,803,381,123,488,577,992,707,393,204,699,944,921,598,596,523,385,191,147,563,678,83,96,653,985,547,779,300,418,737,747,178,862,810,973,502,415,514,629,173,766,971,177,240,173,416,44,76,301,431,622,592,132,90,140,304,846,771,598,597,370,357,938,585,888,5,95,406,652,365,647,171,232,863,473,126,657,302,557,199,680,195,423,851,860,258,233,166,554,56,300,165,321,293,265,116,944,677,873,520,896,81,894,853,878,518,769,452,849,780,603,268,155,176,443,390,831,318,856,864,371,980,125,816,832,478,530,921,429,513,957,618,522,38,718,512,691,290,171,378,262,484,267,722,143,584,651,218,727,971,184,380,578,626,676,737,325,357,399,127,109,599,299,432,337,0,902,311,12,856,483,592,539,782,941,725,141,512,329,101,222,391,342,353,453,82,824,242,948,425,98,791,73,425,350,435,683,715,593,373,2,824,99,503,604,627,244,982,964,298,967,170,656,531,55,732,986,898,857,533,525,657,649,138,19,953,759,445,487,633,47,782,931,431,420,474,103,537,867,823,33,460,422,512,629,365,549,232,122,31,199,326,407,200,892,1,136,488,380,693,717,304,427,465,341,260,502,779,57,316,845,606,150,448,68,136,108,77,446,673,139,177,288,892,606,269,630,374,230,306,558,177,335,329,498,21,644,564,632,17,236,489,421,280,144,561,740,101,279,364,53,84,807,348,541,733,938,478,736,109,536,837,215,771,792,365,856,302,747,911,306,344,890,826,765,812,452,474,411,366,380,498,411,140,782,667,104,385,385,98,594,923,502,397,122,489,70,993,922,930,638,463,532,801,291,105,510,858,330,173,823,936,213,528,839,888,417,222,319,367,805,164,90,963,193,517,397,262,499,975,15,267,595,997,665,406,723,911,363,848,540,746,227,957,707,25,252,583,927,66,319,814,667,391,303,195,418,737,124,147,334,347,748,942,231,764,312,517,123,925,339,373,830,386,119,1000,356,62,261,431,794,650,17,778,134,394,220,686,926,683,44,285,243,543,843,55,654,313,804,68,172,414,753,342,384,818,891,981,340,989,809,17,886,716,458,126,33,203,634,62,93,542,50,305,801,558,57,312,354,419,11,307,725,238,81,75,328,248,357,875,638,549,144,816,883,9,928,137,939,719,951,446,26,226,241,341,226,205,911,124,387,680,510,353,692,595,756,996,39,960,937,137,496,716,89,314,645,589,413,261,764,47,986,592,852,143,48,924,342,336,973,643,660,96,554,550,495,722,858,137,286,242,692,574,964,451,308,587,491,481,158,275,346,173,328,328,79,449,647,681,163,903,158,659,740,706,80,876,385,370,635,114,414,780,301,153,690,249,642,758,975,381,192,613,546,435,573,770,954,493,35,182,431,838,840,561,428,56,715,613,491,636,273,240,54,266,607,258,589,974,287,158,451,762,408,537,452,510,770,750,161,605,570,675,140,8,499,507,595,641,825,92,247,612,583,122,435,452,393,214,743,585,82,462,407,53,990,718,782,719,847,52,265,3,767,802,304,904,161,41,147,693,366,58,706,634,654,578,790,136,954,759,199,34,300,671,850,747,462,133,860,487,938,464,953,244,932,874,400,784,498,111,774,778,206,882,637,502,510,427,374,546,661,714,287,392,766,90,82,650,884,323,367,370,558,604,645,478,333,820,164,169,869,307,655,957,804,896,809,450,845,562,503,508,1000,618,68,880,626,192,195,598,829,126,30,375,274,575,243,54,675,369,76,239,872,806,396,183,731,598,870,582,518,288,993,492,891,944,356,473,70,907,108,667,477,964,507,473,178,220,473,877,825,184,866,483,393,404,518,561,794,256,164,381,577,579,86,590,135,680,539,840,349,891,734,898,267,641,172,395,698,776,192,59,683,378,914,297,315,3,442,387,124,648,987,749,739,843,253,875,108,40,170,997,912,857,875,432,843,459,550,550,335,838,221,414,759,911,723,287,913,629,230,479,142,538,955,681,346,628,72", "522,452,314,250,706,447,769,544,815,407,693,339,714,235,571,653,985,231,227,600,545,308,772,142,663,236,434,809,125,75,792,373,396,361,4,656,267,827,485,103,96,13,527,824,869,452,877,845,649,298,626,311,67,581,403,111,951,443,19,939,87,382,136,143,707,13,993,207,631,195,704,588,939,646,814,344,16,885,327,829,725,121,534,559,740,563,915,850,469,273,998,408,438,739,844,31,120,704,286,674,348,13,416,212,735,198,737,360,628,662,4,548,905,198,990,347,850,547,535,890,811,485,781,931,436,682,567,100,707,426,269,965,512,657,686,865,637,122,314,754,87,359,852,115,498,348,342,993,968,79,691,628,921,574,128,863,450,428,96,209,949,21,528,860,722,806,264,374,76,535,569,544,208,592,578,300,831,805,738,761,770,89,452,849,177,516,643,734,729,417,203,544,301,888,773,288,479,599,79,853,169,70,438,810,885,37,224,469,194,498,301,293,353,611,219,267,975,812,187,276,458,759,404,431,251,563,990,796,186,847,817,614,607,663,223,961,602,295,372,217,854,582,133,179,537,596,96,933,191,684,747,997,448,418,300,287,864,341,213,335,244,160,115,323,868,809,29,51,311,914,965,742,364,868,555,94,28,451,569,575,348,473,506,752,902,0,704,88,35,138,299,470,245,328,401,303,988,823,944,855,757,273,394,777,522,985,584,14,556,42,732,340,627,258,264,274,724,405,817,175,170,546,957,881,345,573,576,199,605,514,766,69,538,297,812,431,72,231,561,659,939,986,35,510,502,629,82,624,649,817,404,534,497,698,770,34,439,224,212,682,583,17,467,648,27,543,449,483,157,462,645,616,815,214,609,403,894,836,452,11,694,820,703,715,748,224,868,882,294,401,283,17,86,288,87,835,171,430,606,400,200,933,206,123,398,478,281,699,427,409,168,269,961,876,521,194,414,405,218,178,783,707,546,102,619,989,3,481,858,902,446,909,612,527,413,18,357,806,646,105,358,501,204,840,300,33,904,743,67,367,989,911,659,894,490,161,33,734,383,160,804,78,720,994,319,194,817,179,465,410,393,473,665,382,126,86,290,417,218,131,48,290,32,359,592,717,565,728,324,470,254,700,139,861,697,747,205,956,367,875,733,648,879,876,188,535,152,439,117,895,781,799,855,444,71,78,637,590,584,232,725,965,119,150,186,964,625,671,175,756,341,492,113,292,365,546,841,137,342,273,994,554,378,143,881,237,630,32,801,840,528,817,309,833,22,71,650,654,547,728,198,623,175,771,255,233,900,998,996,212,808,458,708,943,405,452,126,704,412,650,906,337,302,460,146,554,986,938,800,751,763,78,413,563,49,670,284,782,119,15,226,148,63,358,13,858,369,773,812,950,133,653,342,936,921,565,648,891,117,128,188,637,272,942,546,313,757,656,742,393,26,900,321,431,604,259,179,464,859,124,391,50,299,687,646,38,378,763,190,824,589,209,560,696,906,566,148,532,50,201,665,869,648,18,754,462,221,852,545,921,215,763,896,521,90,688,84,674,245,951,679,621,749,850,956,101,387,713,786,176,601,893,704,525,120,418,447,384,221,971,890,190,459,570,24,263,62,236,669,841,576,172,671,810,739,273,473,758,681,540,543,70,387,321,281,976,335,639,13,458,616,565,634,575,896,461,654,262,992,578,851,43,778,356,220,532,969,217,722,863,519,450,880,257,177,375,512,450,518,489,339,382,761,268,457,937,196,580,213,965,568,655,485,246,518,910,538,313,207,499,787,265,70,884,569,527,988,97,947,795,373,509,892,199,47,369,404,852,374,587,958,683,718,637,492,112,37,530,350,29,862,115,735,955,905,862,749,372,161,871,612,955,520,440,38,345,364,364,389,541,366,769,631,921,244,959,698,829,595,774,888,489,906,304,312,412,499,664,893,147,934,170,285,381,254,829,461,239,63,77,687,669,941,492,218,575,325,461,166,248,197,647,872,207,777,299,713,222,988,276,838,719,883,731,541,655,315,121,684,329,706,844,1,304,135,972,201,546,536,153,645,711,493,964,13,776,586,492,150,343,479,626,995,609,299,25,742,6,651,684,268,316,430,434,889,808,869,126,689,137,18,830,974,495,829,230,726,993,527,6,710,507,270,58,511,657,656,218,535,938,776,300,56,192,423,946,695,499,347,71,534,394,832,252,911,713,307,405,427,828,46,207,712,846,77,156,372,631,689,150,820,867,761,422,544,769,884,450,80,240,904,589,154,380,739,614,379,921,654,786", "411,672,711,739,303,240,226,553,379,562,55,136,441,526,786,937,171,600,445,820,569,532,39,817,5,167,198,203,557,394,383,547,419,126,987,262,445,609,390,844,779,788,603,606,327,784,398,305,800,131,475,291,180,218,568,742,416,841,951,66,992,359,600,549,7,414,244,824,196,913,433,764,531,579,10,506,108,94,995,635,586,188,297,629,666,23,350,203,906,374,74,463,216,526,259,846,708,865,87,159,866,468,58,556,710,270,612,70,124,971,206,750,767,465,196,94,314,263,333,259,841,107,704,316,806,609,286,459,396,304,818,100,238,214,443,660,292,362,272,225,368,720,285,124,129,662,248,961,795,534,199,946,408,326,932,73,407,901,789,711,821,606,768,132,170,27,682,821,622,638,598,551,846,374,5,611,297,635,89,543,45,133,129,126,766,389,646,218,133,336,804,455,924,75,991,263,43,798,666,328,75,173,212,243,339,401,940,155,615,21,389,84,90,843,747,573,319,507,360,829,199,698,831,181,426,586,168,229,417,274,674,150,29,759,679,681,710,600,647,496,233,561,140,187,595,407,127,818,451,304,188,604,825,161,736,240,990,448,27,198,628,87,922,525,835,913,648,585,749,260,824,951,920,304,55,138,630,818,709,6,147,19,274,259,311,704,0,197,168,700,374,652,738,483,689,581,873,737,928,26,604,120,128,326,569,41,356,858,476,813,651,145,210,653,517,570,927,295,437,422,492,750,258,178,479,237,401,322,8,286,708,212,224,580,420,663,267,797,819,538,968,61,793,295,993,750,502,115,983,978,771,341,309,506,238,324,114,774,260,495,989,909,919,768,845,285,507,240,919,480,534,563,2,216,58,925,784,441,273,214,684,259,222,960,946,474,874,860,719,644,34,700,246,965,688,34,338,519,773,638,671,407,93,699,521,662,760,298,898,499,97,306,604,652,835,351,341,66,306,672,444,601,219,507,638,698,143,339,278,601,346,812,246,960,996,470,656,712,949,669,58,711,25,841,702,656,852,610,741,179,193,442,827,679,854,839,612,38,340,13,822,851,184,107,563,638,692,136,847,164,918,972,347,955,542,16,625,811,6,231,806,58,780,326,60,934,974,365,288,452,868,265,801,469,660,398,823,664,776,893,413,232,84,119,308,145,548,501,985,627,638,432,556,957,87,140,461,383,777,612,470,54,338,318,818,987,324,944,957,794,407,991,53,6,778,618,493,642,50,449,867,107,308,990,392,554,863,866,855,536,839,511,886,52,523,564,845,806,581,765,344,804,625,209,485,72,797,450,842,407,28,709,765,455,37,785,754,9,340,254,890,412,617,442,483,892,531,587,854,922,883,184,615,454,397,701,893,443,9,382,802,631,70,33,939,268,738,185,146,763,724,251,136,64,576,430,759,24,727,342,692,949,190,346,303,500,757,246,583,360,198,368,803,882,585,501,958,805,495,42,711,565,127,26,86,565,84,103,938,315,578,554,612,320,403,316,744,180,221,63,509,60,689,658,272,575,111,452,302,934,760,114,667,877,285,290,952,51,212,654,56,410,50,454,219,931,880,143,391,915,894,936,971,864,847,266,488,658,674,457,281,510,936,185,922,260,733,426,314,894,285,537,167,521,90,844,656,497,140,649,28,729,264,795,582,497,424,65,817,404,690,601,867,226,82,501,108,432,715,897,569,561,268,173,552,849,436,104,785,56,65,503,192,162,817,917,35,915,135,671,474,388,776,88,185,231,585,686,777,433,184,654,112,174,277,611,479,476,963,583,959,797,540,358,166,982,580,510,627,900,822,715,498,400,305,852,449,683,889,114,240,598,835,494,143,451,234,951,258,97,613,324,602,770,958,725,505,263,626,534,771,542,721,701,819,409,367,453,219,311,791,464,437,930,58,797,344,292,206,947,904,902,428,132,303,306,292,73,283,216,583,693,358,462,546,355,889,273,494,866,342,410,606,325,870,182,215,664,73,995,635,669,335,908,147,265,869,395,388,260,23,923,97,298,809,708,368,489,510,912,953,999,791,455,120,287,590,696,263,923,770,399,468,607,896,826,322,601,651,551,690,647,985,934,606,879,909,387,766,638,279,12,687,573,338,916,28,973,201,381,159,53,209,968,561,227,196,141,347,735,93,184,73,743,681,764,119,962,185,676,174,810,443,362,63,835,640,164,239,133,833,733,423,510,295,804,136,85,498,726,776,638,228,409,500,212,451,512,33,116,615,673,723,889,418,131,526,735,671,334,931,103,200,569,877,787,736,542,973,275", "772,474,534,982,468,332,909,215,492,867,214,543,208,902,498,428,649,617,971,998,463,659,853,457,57,68,301,647,769,977,897,395,999,660,645,376,708,240,134,66,575,386,775,292,130,89,542,773,443,557,809,63,569,586,162,833,990,381,209,742,781,582,408,67,775,419,994,803,658,91,888,678,77,815,449,726,476,150,759,765,416,310,443,360,104,206,413,94,465,916,956,539,512,341,316,294,328,763,31,460,827,66,111,494,300,545,508,264,338,687,269,601,881,612,44,74,10,37,476,311,280,324,869,353,765,349,531,198,146,167,384,769,926,411,23,349,946,192,895,764,118,846,353,606,484,238,301,932,76,172,534,862,554,670,717,799,136,541,47,500,602,104,970,468,249,878,339,147,15,909,570,164,352,28,363,639,328,699,450,916,100,965,442,225,404,998,287,759,773,152,815,625,161,785,231,855,953,792,45,940,108,416,988,43,556,392,150,557,84,688,73,394,54,405,963,767,517,136,928,18,773,267,654,443,559,934,489,247,287,883,89,378,280,541,529,473,510,620,226,244,268,939,298,810,240,376,599,288,562,386,171,35,872,191,770,270,331,187,296,65,689,734,372,367,883,221,626,552,993,787,804,523,294,800,397,710,134,974,377,188,541,134,139,452,12,88,197,0,813,895,768,765,691,534,406,967,270,877,556,507,982,855,342,921,405,462,595,746,767,903,553,306,499,574,251,808,319,568,438,380,163,8,931,770,688,787,341,975,427,378,83,922,634,412,171,991,477,188,722,164,200,382,264,723,574,948,892,949,778,937,269,525,442,579,849,399,74,111,616,13,29,885,510,516,406,798,989,828,797,887,830,203,460,657,687,458,266,389,627,624,650,719,71,476,694,726,249,319,1,216,172,637,169,14,658,629,347,931,795,28,210,242,240,60,548,995,87,650,70,48,517,309,978,158,277,504,6,100,945,376,166,658,642,604,808,291,810,166,108,806,690,523,695,272,519,977,996,341,394,879,809,274,786,882,672,347,89,776,893,184,126,784,350,242,523,584,28,965,11,404,455,623,771,939,569,772,70,342,592,903,92,353,291,824,90,13,889,920,73,102,53,879,543,968,951,556,936,82,702,523,117,997,632,444,668,706,726,882,293,246,924,387,137,416,191,749,361,49,667,796,134,68,533,503,235,642,40,812,424,361,420,990,698,620,404,481,10,206,268,458,791,44,435,373,79,610,770,480,628,214,488,123,599,26,409,162,802,966,892,527,903,428,580,667,398,661,957,780,589,798,60,824,371,506,368,321,140,208,743,283,403,471,885,94,125,317,739,39,238,423,58,777,808,6,875,261,723,266,573,692,188,212,407,171,265,704,764,433,265,52,647,545,227,607,915,384,54,260,419,300,890,691,949,398,369,595,336,548,702,424,596,27,319,909,993,258,904,217,864,119,292,506,971,199,369,756,131,394,835,678,947,692,191,757,419,389,132,410,930,578,725,450,440,740,411,759,635,136,905,225,716,703,960,515,126,406,303,138,362,635,467,328,971,935,359,948,890,811,770,531,948,781,1000,443,993,281,508,641,893,56,945,918,723,871,464,822,355,532,202,300,953,230,722,690,429,983,688,294,375,57,457,38,239,411,195,955,599,147,98,445,274,385,264,495,703,967,155,125,965,467,967,402,904,288,958,919,927,80,829,224,732,932,219,930,756,816,585,185,461,463,467,705,79,706,735,314,456,905,573,388,173,934,596,508,85,866,844,897,328,949,206,24,465,101,911,584,470,712,430,488,536,995,45,968,436,494,30,881,511,360,115,950,11,123,309,558,186,520,30,264,843,385,979,874,543,252,832,484,732,51,855,621,630,844,108,739,99,923,969,292,41,714,461,833,863,652,650,263,754,838,360,482,587,732,387,610,577,334,711,375,202,280,31,807,489,166,442,646,170,598,505,155,468,430,700,926,160,505,176,830,942,990,911,734,390,331,618,203,208,104,643,479,179,313,447,498,148,606,139,743,534,67,669,41,165,373,606,237,370,542,63,336,738,768,771,134,36,585,196,45,310,325,725,954,736,269,436,229,961,243,394,64,998,808,442,176,671,691,225,772,385,260,578,187,887,668,423,175,110,697,88,909,463,412,235,866,53,300,182,742,790,677,563,99,192,610,660,35,980,105,155,490,582,168,557,635,535,993,443,156,864,521,26,825,245,330,351,930,584,149,766,517,981,250,437,314,815,29,562,21,125,521,276,678,644,999,186,767,557,831,63,982,285,873,70,805,532,953,779,350", "943,660,132,336,620,512,535,835,101,951,439,111,772,135,357,188,495,994,409,126,137,323,280,577,794,566,843,945,291,705,27,134,552,930,121,186,866,25,890,519,309,467,644,902,569,205,815,808,993,58,641,503,240,964,261,657,43,891,925,720,186,538,658,646,365,551,971,717,402,466,288,457,789,262,389,659,882,795,749,52,405,574,414,822,56,748,249,344,85,994,578,13,79,236,197,146,559,358,426,3,774,942,315,162,192,390,257,696,831,425,749,40,545,427,639,702,60,979,876,301,382,655,240,28,71,432,833,103,26,907,19,969,81,444,500,339,936,294,71,940,975,852,31,748,282,452,304,707,648,603,408,787,876,116,683,964,52,24,908,996,398,552,79,496,81,790,155,820,11,430,57,507,586,259,102,712,466,109,670,64,500,946,935,522,551,821,61,315,28,982,57,549,129,98,430,530,819,661,865,282,914,793,406,808,309,928,574,219,747,539,801,197,435,499,365,114,847,89,703,477,114,237,392,949,454,188,156,52,979,92,183,316,739,175,571,378,440,697,810,909,235,885,662,411,944,279,656,495,352,514,5,787,63,484,788,818,713,81,241,819,687,549,414,647,194,904,12,124,743,440,628,210,763,756,628,705,977,597,345,15,683,524,547,332,856,35,168,813,0,222,755,956,879,777,58,817,325,835,926,864,521,677,565,456,680,245,775,96,820,218,224,772,101,59,726,448,592,754,538,923,518,37,257,231,45,402,364,318,952,616,479,790,442,97,832,680,753,152,448,342,995,659,278,790,978,321,978,259,332,972,441,213,638,299,68,836,722,673,412,20,446,667,555,585,256,144,498,308,647,432,696,344,604,867,58,851,925,845,101,342,439,831,358,17,577,75,207,612,838,534,935,405,873,935,37,31,159,100,184,290,994,563,756,54,514,91,225,812,614,323,266,697,100,472,776,472,992,979,359,362,285,508,20,656,111,52,749,306,490,768,358,136,587,292,616,846,141,311,506,213,149,627,281,95,321,616,445,551,962,959,268,716,727,522,531,38,134,325,159,798,315,854,438,157,229,94,663,913,898,304,271,839,185,272,725,557,10,124,542,575,413,274,566,341,476,803,317,201,326,671,956,563,647,59,960,608,947,924,890,372,799,256,8,346,513,197,743,280,846,592,942,150,75,491,63,51,139,833,89,22,754,832,560,910,19,525,566,758,81,655,359,772,985,947,389,539,595,105,816,998,565,49,74,29,621,859,240,823,558,600,235,515,188,868,843,366,596,466,920,765,612,878,606,316,182,801,508,671,249,558,266,972,114,989,209,869,48,147,558,221,415,236,418,579,47,595,537,977,345,229,290,597,772,111,383,200,355,30,592,339,559,748,243,573,645,739,813,993,174,665,511,589,197,574,247,580,579,404,492,941,297,282,157,508,574,652,524,822,7,356,210,151,144,452,916,488,224,470,938,625,853,387,618,154,799,929,318,643,858,877,991,585,601,141,352,656,297,869,750,361,119,339,847,243,780,288,948,927,930,702,613,524,349,71,591,997,115,850,826,604,224,555,426,429,16,900,785,249,704,312,19,331,355,139,222,359,884,136,702,125,56,205,359,794,719,366,501,797,766,866,860,178,412,685,13,142,827,597,98,640,8,469,569,628,682,424,275,462,63,743,345,165,172,754,247,261,966,886,545,723,834,321,921,230,38,8,82,361,642,624,783,93,512,268,253,544,664,329,169,90,476,817,983,471,593,320,680,232,210,263,948,634,508,620,204,360,113,739,327,9,221,8,102,826,924,112,760,765,284,257,916,563,198,732,783,780,990,645,245,653,566,103,349,616,202,906,239,323,577,661,510,382,503,488,45,440,341,778,707,860,820,313,308,701,249,224,872,967,288,597,195,565,77,850,984,943,512,107,668,327,536,930,887,195,4,244,677,7,342,300,286,246,239,909,311,328,150,262,399,762,915,549,37,448,86,25,476,798,272,891,792,524,199,24,443,78,956,232,678,946,652,568,219,215,522,256,266,786,777,687,22,872,103,685,968,644,597,992,205,182,797,707,828,830,678,92,767,720,418,352,773,943,147,868,852,157,293,122,749,337,903,983,242,203,410,971,107,833,398,942,362,984,789,553,672,375,983,376,728,217,88,431,168,499,277,157,500,3,363,345,408,963,862,557,229,354,361,793,810,398,783,709,732,996,103,467,870,455,889,193,661,43,323,718,268,25,348,789,975,912,89,601,501,603,311,139,232,280,23,933,948,765,807,806,162,464,38,732,591,858", "183,455,564,284,208,112,597,276,148,404,339,352,568,336,129,822,555,915,769,760,29,208,336,406,946,194,918,716,231,329,497,300,202,782,584,64,339,740,966,272,23,299,335,47,302,896,244,902,594,991,18,296,612,841,888,67,260,575,815,541,279,691,962,323,410,784,843,782,883,792,698,166,9,91,218,620,972,386,905,195,471,803,152,171,472,299,118,946,659,124,981,335,607,851,81,329,729,499,927,350,930,786,490,163,129,817,718,13,803,384,620,341,502,530,354,974,80,417,723,927,621,589,893,671,100,665,805,620,364,213,179,71,686,931,707,631,106,586,298,511,165,198,52,152,178,839,199,427,657,235,767,471,512,150,26,552,820,398,195,584,729,904,292,387,731,387,733,241,786,487,680,326,997,656,648,2,266,153,520,392,311,395,157,101,337,238,685,649,948,574,367,10,246,660,368,793,713,775,293,346,821,5,516,239,412,637,257,543,897,119,165,221,667,766,815,115,117,841,977,45,242,151,650,939,699,616,160,602,786,932,166,818,745,424,694,563,282,739,368,802,328,573,26,936,910,481,280,572,251,936,160,61,317,237,621,752,234,87,807,682,752,781,898,136,889,158,59,239,108,926,984,294,439,700,196,324,592,221,873,993,694,823,795,840,483,138,700,895,222,0,864,522,319,559,518,92,683,267,205,311,610,593,259,837,679,874,828,972,58,932,261,779,297,18,586,449,404,296,5,185,622,787,789,871,943,37,403,537,893,659,931,767,129,43,132,182,166,594,626,881,311,426,703,955,453,946,365,454,1000,897,291,669,857,357,604,769,68,467,555,580,336,792,451,309,931,119,131,783,471,838,498,585,934,652,473,723,767,481,703,459,726,642,538,79,800,596,494,41,47,586,153,485,207,780,777,417,487,410,691,717,519,62,882,586,776,293,813,93,104,149,298,964,956,976,501,374,374,842,940,465,872,406,895,531,696,259,593,670,182,578,832,333,623,249,113,996,88,41,593,393,844,630,982,205,33,368,860,305,686,133,355,241,705,360,973,752,424,941,619,3,254,710,826,991,772,372,272,486,227,698,135,581,527,335,945,937,717,580,636,535,236,483,468,854,198,179,967,576,557,200,108,49,384,248,555,204,216,68,112,416,947,12,752,256,951,491,568,280,917,361,100,921,263,430,855,782,497,910,835,712,953,414,992,280,111,967,955,619,972,459,77,67,660,550,599,348,816,846,724,75,337,67,495,313,983,994,869,594,751,730,823,983,592,63,328,544,707,623,476,359,435,123,271,538,608,31,120,875,215,792,962,794,753,532,449,680,150,102,389,331,617,765,424,352,905,623,865,370,988,815,881,814,952,900,338,795,56,358,489,779,283,321,520,899,297,292,332,501,979,982,989,606,245,101,411,573,365,956,674,924,140,54,829,31,902,589,613,643,9,478,869,642,549,159,536,555,686,289,474,168,320,653,808,983,440,340,139,345,712,517,938,633,363,970,748,794,572,964,251,833,293,751,211,701,602,565,259,642,74,192,443,627,231,369,200,10,150,716,11,722,751,744,442,762,887,899,606,141,498,638,919,507,242,126,579,124,342,738,416,63,203,331,375,727,619,923,438,300,381,470,838,251,150,66,55,525,672,689,951,473,887,640,776,745,165,856,494,589,621,12,947,826,848,406,987,980,814,558,115,581,64,965,263,610,463,677,695,226,667,201,308,886,898,87,728,900,72,205,330,424,856,35,798,867,512,843,250,780,649,375,680,556,894,718,765,206,191,190,6,319,655,803,321,468,630,728,8,791,425,215,548,781,755,848,113,425,670,563,958,465,882,756,301,782,662,354,915,645,207,36,634,50,631,33,984,601,503,224,928,653,449,707,188,979,829,932,847,85,987,139,973,557,657,628,259,541,591,804,593,823,155,709,138,795,437,973,487,425,826,92,265,106,24,885,406,384,954,159,949,897,638,36,173,249,290,939,331,947,148,712,730,866,559,807,810,826,658,488,471,706,692,371,225,747,382,599,7,617,463,422,743,922,994,146,216,198,951,900,414,210,415,913,297,334,867,438,196,667,37,118,784,422,684,730,416,617,253,31,395,576,194,575,771,750,71,693,57,965,281,175,754,202,596,681,477,95,645,887,50,910,591,25,215,641,522,385,505,155,858,300,777,765,925,508,126,519,10,195,883,347,899,950,45,372,976,921,790,307,569,277,504,818,178,901,262,36,609,192,571,522,671,96,932,921,912,61,278,511,498,682,301,908,72,52,663,690,515,262,280,464", "6,32,482,604,428,357,878,581,593,277,329,659,673,105,412,501,148,672,834,172,859,942,412,648,351,687,288,292,866,881,152,560,474,98,164,708,807,167,33,229,938,699,934,463,920,911,300,596,601,133,876,260,329,929,918,356,466,451,465,513,121,547,627,700,2,315,22,285,919,174,552,926,237,953,216,872,731,594,464,972,267,932,496,294,610,544,802,334,119,151,403,918,63,428,464,303,431,777,741,817,84,885,138,614,774,113,504,21,215,68,78,662,5,307,617,226,671,149,171,387,399,744,687,727,526,649,155,765,546,650,236,373,513,660,549,373,204,815,250,192,876,581,997,619,386,335,172,757,989,934,265,924,461,373,24,680,399,924,104,322,514,861,600,941,728,6,225,856,966,662,891,678,931,857,892,477,347,260,893,225,745,726,329,732,455,461,962,282,789,965,515,485,969,527,508,386,267,847,53,393,692,576,205,702,345,739,495,832,823,993,541,513,981,724,458,909,91,339,665,211,148,696,986,236,364,508,970,750,884,715,566,830,710,399,749,256,280,425,77,208,125,325,833,289,73,876,740,789,840,270,861,937,320,754,363,443,559,798,363,795,356,257,374,789,271,125,338,482,982,608,890,745,512,127,53,862,584,991,978,630,935,192,952,825,592,299,374,768,755,864,0,388,260,904,904,234,851,565,750,553,375,776,48,960,363,329,242,52,854,535,110,875,92,363,679,616,843,321,734,233,532,100,565,688,955,803,871,503,826,161,253,416,292,981,961,809,581,658,595,533,655,579,663,453,582,56,236,43,458,523,295,367,254,690,666,264,998,191,247,937,316,381,998,154,124,831,31,748,502,33,276,469,294,798,490,188,602,693,374,476,820,132,509,143,771,897,404,586,399,367,36,974,685,997,304,571,991,275,293,240,796,121,367,124,94,492,404,332,226,814,110,713,857,546,588,386,983,526,124,110,437,26,820,371,227,475,352,256,712,228,244,938,778,167,787,858,807,987,794,272,636,654,359,798,236,455,946,323,546,652,486,894,320,768,165,47,481,816,649,671,488,712,175,35,287,167,712,633,41,670,701,938,929,75,637,686,692,109,683,658,493,484,517,137,457,550,842,992,912,411,351,334,532,349,113,122,639,745,634,290,164,3,218,628,390,592,952,539,256,311,705,749,990,151,927,127,542,345,427,803,724,369,100,875,776,464,504,655,212,131,237,425,472,228,204,808,649,63,192,707,613,426,117,787,11,988,746,889,962,909,865,918,859,497,663,968,459,122,245,951,653,108,898,113,248,993,500,362,700,846,693,52,871,826,865,402,728,67,51,522,134,207,895,612,913,208,877,517,269,493,766,783,875,778,431,588,797,743,364,724,405,814,362,623,57,694,156,534,447,12,576,542,893,824,22,361,262,198,582,133,813,290,669,563,881,891,425,25,759,992,740,217,997,285,274,919,596,932,83,900,43,307,360,872,721,224,223,99,267,173,855,28,96,842,28,964,714,519,222,355,323,456,373,504,800,98,208,663,918,989,661,469,272,933,458,320,222,733,461,895,754,332,901,483,78,661,928,348,256,55,390,368,205,202,509,989,276,502,170,333,806,819,833,767,265,777,991,376,561,580,128,399,379,81,509,40,755,101,47,550,253,129,773,671,187,339,512,827,112,357,143,70,126,810,534,767,109,671,124,555,708,112,14,183,190,247,146,378,166,164,41,564,197,724,446,773,637,153,627,823,57,163,785,834,625,989,384,708,420,729,690,746,939,232,735,608,766,393,89,500,690,551,333,137,683,704,291,764,27,961,364,749,611,121,687,775,386,149,529,599,585,771,166,448,804,805,196,76,419,961,758,471,669,461,606,646,117,342,842,435,876,501,681,958,641,685,244,56,574,846,950,30,900,521,627,667,27,749,455,247,490,905,980,627,329,682,516,407,696,414,65,500,205,416,294,405,48,246,281,24,684,882,947,169,11,525,887,484,737,915,980,808,512,938,661,481,301,120,605,201,532,105,920,193,755,284,671,528,88,473,735,783,898,82,284,319,748,225,278,999,317,601,297,407,884,159,902,332,466,123,736,692,97,212,718,634,780,445,311,102,403,524,515,690,485,270,916,468,544,746,245,352,288,758,78,85,549,310,252,933,354,461,253,381,37,222,314,383,572,144,601,689,675,167,726,92,776,562,459,591,897,678,667,111,834,924,657,496,732,396,856,347,405,383,470,694,972,647,265,989,338,742,579,801,684,353,441,141,100,89,413,962,733,936,839,701,958,825,608,655", "84,871,430,411,374,714,101,167,329,454,789,347,629,708,268,96,566,468,971,100,960,342,587,230,13,866,405,634,20,856,572,997,260,341,261,836,906,622,219,948,756,794,937,433,349,88,747,330,841,298,734,588,657,207,416,965,385,689,680,735,534,468,992,87,351,767,946,579,497,426,699,348,838,211,856,690,238,305,9,922,340,370,181,908,992,511,529,542,333,635,983,11,478,534,38,201,642,219,806,689,854,933,531,998,32,288,896,223,132,531,958,289,114,359,383,245,226,263,955,786,5,294,447,58,540,18,117,891,642,23,750,696,490,19,194,899,664,616,207,12,577,319,361,724,961,833,906,326,892,396,642,752,10,577,100,433,642,189,641,941,39,641,459,708,55,750,140,926,227,371,618,964,410,428,832,328,900,209,756,553,804,503,783,946,86,967,813,944,998,710,461,869,776,588,804,467,342,723,139,72,479,225,816,68,343,402,842,798,15,448,581,751,680,597,697,420,161,949,907,538,641,928,946,33,646,924,952,380,776,909,176,991,169,387,400,584,317,235,651,683,238,836,684,858,336,562,925,312,498,437,990,509,598,190,225,710,285,541,240,734,833,130,374,999,27,921,70,127,270,250,215,38,594,618,701,457,556,476,580,974,25,565,26,467,539,470,652,765,956,522,388,0,126,458,901,864,434,400,473,925,650,793,408,122,832,158,38,801,512,359,156,560,97,292,568,876,231,983,674,705,869,763,940,939,997,198,492,369,156,396,7,584,372,234,416,895,689,860,664,6,738,690,758,692,813,589,141,89,157,96,695,817,352,938,112,297,549,32,705,701,570,665,260,280,924,285,739,246,543,464,27,795,202,365,548,119,503,470,705,296,942,333,1,73,700,342,851,348,712,781,408,466,713,805,364,227,927,453,749,246,727,296,396,409,407,356,968,316,875,543,28,632,827,269,756,87,684,737,369,271,977,563,549,521,430,726,107,413,233,735,96,120,340,723,287,567,136,659,654,16,745,656,992,896,344,509,719,480,124,136,317,21,221,211,549,341,19,362,977,316,515,626,981,110,164,794,772,218,915,943,186,419,974,326,335,737,925,191,152,762,646,186,746,46,38,888,821,385,949,761,873,7,332,723,944,46,58,590,755,910,827,337,895,545,937,288,768,506,417,33,908,849,682,158,947,755,506,985,919,751,181,579,831,613,74,93,738,334,339,734,615,502,664,718,330,464,866,888,197,452,796,729,486,55,359,567,378,603,649,281,665,734,411,904,85,366,604,838,395,559,380,652,603,290,169,52,484,213,576,173,271,128,339,429,795,64,358,272,29,900,727,56,623,439,141,184,30,493,17,51,744,709,100,79,924,989,34,170,199,443,165,778,45,345,766,349,869,258,677,168,440,620,75,440,867,309,487,896,958,131,336,638,26,408,380,344,938,319,149,781,101,738,613,676,232,84,499,418,609,207,641,778,394,873,82,185,338,228,98,98,586,124,791,854,381,376,171,822,848,633,593,348,506,181,413,236,650,557,174,564,217,941,707,730,796,973,99,598,592,666,779,920,466,4,497,961,12,205,959,909,766,263,43,171,543,97,697,776,329,892,517,904,915,3,30,582,864,517,326,150,902,294,257,594,891,253,500,799,501,562,464,401,685,634,822,80,114,555,667,391,162,810,98,109,289,99,479,608,486,549,746,927,723,372,836,416,822,780,643,524,111,990,21,815,737,814,732,479,342,747,292,393,842,373,84,843,707,114,36,732,769,823,609,574,986,961,226,255,291,545,563,823,510,934,193,651,292,343,712,867,715,79,228,993,138,913,618,769,758,749,304,195,819,540,578,32,737,62,637,929,191,60,385,814,284,41,871,648,184,823,398,166,366,392,498,501,721,53,853,362,402,151,98,940,735,746,93,13,651,318,174,607,925,586,275,775,587,533,212,804,327,944,797,15,958,309,325,760,886,233,349,684,885,123,682,864,800,184,650,845,894,385,219,591,44,597,917,444,547,338,609,515,175,541,378,49,765,83,218,734,463,844,160,953,429,237,71,109,976,875,198,773,707,845,753,374,53,368,994,101,496,402,338,621,665,687,258,235,996,350,175,91,95,78,462,349,844,185,660,968,744,914,243,594,231,863,832,838,146,250,748,578,739,949,708,755,18,688,804,617,257,142,924,121,287,331,418,864,185,30,69,276,119,227,727,477,979,682,662,657,431,390,525,71,59,348,405,935,298,639,356,84,432,556,662,431,230,54,764,128,187,67,938,634,692,16,934,524,567,829", "984,305,564,974,89,536,87,624,630,202,270,542,299,119,816,964,163,206,438,318,467,223,722,927,704,439,275,646,808,495,86,110,975,209,356,877,956,655,317,315,586,796,726,526,220,506,49,38,134,236,530,494,148,178,2,854,406,563,463,782,291,588,660,139,127,34,801,830,872,711,253,676,367,156,464,926,630,310,421,140,424,687,685,992,340,783,851,714,673,285,466,895,948,562,170,634,211,970,211,180,506,682,849,235,929,921,83,738,945,350,285,194,120,946,421,140,507,381,796,610,922,163,897,414,50,17,259,799,291,969,938,632,309,615,125,523,355,607,259,105,765,508,980,635,209,565,541,232,639,487,339,296,289,772,191,652,302,216,339,616,930,266,451,798,249,403,927,517,905,849,324,114,258,202,734,989,444,53,131,631,507,789,499,514,201,494,476,344,137,544,687,697,494,611,471,658,892,684,372,946,522,17,743,470,312,815,896,106,92,358,148,942,44,253,981,380,356,326,636,910,536,802,156,878,8,675,83,677,755,863,1,283,598,650,477,191,516,204,178,17,867,857,755,870,353,906,493,2,433,813,311,630,625,322,794,90,697,947,532,763,545,94,76,267,71,341,674,593,924,985,820,643,443,96,248,811,478,839,101,936,500,195,414,700,782,245,738,691,879,319,260,126,0,363,203,79,400,606,810,276,780,201,808,785,598,860,703,193,915,370,420,448,246,259,148,817,97,358,951,163,76,863,905,898,412,36,394,613,128,5,515,713,431,209,291,227,402,633,283,867,526,249,327,385,34,842,885,407,190,45,873,239,887,25,128,331,755,306,629,953,891,454,398,88,112,581,835,446,995,147,591,646,967,231,928,984,801,604,537,579,801,174,913,948,905,975,456,609,47,624,655,682,932,410,922,361,580,717,667,797,62,581,480,255,59,142,500,716,376,265,501,445,696,676,634,835,506,48,70,91,22,525,836,475,195,888,590,950,382,506,265,639,334,795,48,646,327,455,763,271,898,881,920,473,108,702,665,312,211,368,39,563,829,690,975,722,365,61,493,199,337,903,177,824,615,438,132,767,651,464,428,993,769,77,240,504,663,500,503,190,638,331,232,757,338,63,260,650,970,432,275,155,484,361,239,846,295,122,973,771,388,99,140,303,726,931,322,121,6,677,644,902,421,431,797,431,72,173,131,954,308,514,716,314,264,298,917,612,928,730,903,223,637,384,907,579,407,365,941,111,57,636,614,618,261,991,628,747,637,500,716,223,226,320,224,389,399,106,814,180,182,712,749,355,164,356,854,832,580,36,256,935,106,28,174,595,697,23,798,560,371,247,662,612,672,152,437,362,406,471,569,54,920,387,92,607,725,288,604,38,615,61,113,226,500,186,85,835,908,207,666,879,116,455,787,167,73,393,259,814,1,517,716,94,828,986,806,639,972,615,174,107,986,834,624,23,914,588,377,349,587,789,329,587,581,564,64,76,83,804,341,613,910,942,175,845,771,195,495,505,638,809,617,913,738,857,639,274,767,223,430,989,558,55,769,500,431,505,14,608,459,552,14,384,931,714,480,879,779,215,188,385,838,195,960,419,160,47,629,784,950,967,896,799,272,545,658,454,999,455,686,191,296,212,41,183,656,630,738,651,7,250,65,716,953,437,591,688,987,239,643,856,865,748,415,975,804,628,383,182,532,671,67,46,697,377,655,166,252,928,679,171,970,981,748,996,68,100,339,967,621,76,816,271,255,959,223,586,213,860,285,976,534,123,153,390,167,248,161,866,846,519,208,374,86,565,174,214,360,872,36,429,242,857,268,961,573,427,515,473,759,554,629,822,440,276,451,338,243,902,712,796,140,440,914,704,344,857,916,651,328,909,492,920,305,8,797,252,423,722,448,974,842,80,948,271,78,694,796,342,647,693,835,514,338,54,814,557,962,470,434,967,940,579,37,44,80,914,345,118,204,586,727,155,69,735,134,914,287,10,29,382,206,892,275,38,803,13,854,612,451,802,279,82,537,300,846,329,534,518,367,880,127,252,112,485,344,432,694,688,787,129,77,791,975,918,721,291,885,744,988,49,883,235,366,67,261,36,143,846,625,977,884,101,109,304,491,908,613,652,267,777,570,844,101,362,16,201,296,406,724,492,452,43,885,552,573,753,141,58,879,939,461,592,889,403,298,817,356,359,893,855,312,251,600,92,37,805,148,335,270,760,483,511,264,436,509,178,908,110,953,176,919,53,732,406,876,895,45,153,115,688,55,45,409,646,116,301,706,145", "619,571,128,808,572,203,32,183,646,514,472,180,960,844,118,18,552,222,492,874,744,991,869,74,290,767,264,628,473,955,36,932,809,266,423,501,674,658,609,943,604,964,68,348,517,62,110,826,705,369,398,647,513,973,90,295,464,218,171,370,10,300,158,460,998,591,157,71,701,788,352,431,818,648,272,712,548,327,51,966,299,566,476,277,756,444,710,887,31,749,553,448,767,124,909,556,468,715,124,751,90,506,788,393,46,586,443,976,196,95,434,754,695,235,802,58,713,41,778,571,866,689,120,620,757,68,459,419,590,757,102,825,142,735,623,902,275,410,293,192,118,53,433,485,852,561,430,26,451,208,638,718,521,457,140,676,77,737,276,475,69,197,914,940,607,629,701,477,701,27,993,816,624,112,707,145,88,586,104,773,793,628,249,126,986,743,222,322,66,662,838,605,319,946,335,188,91,491,194,326,502,881,619,105,801,577,263,873,431,495,545,234,835,748,534,408,864,812,971,454,951,278,505,13,675,424,431,467,308,642,140,810,216,766,592,92,370,568,209,981,194,82,111,466,514,355,198,418,473,624,605,276,218,43,194,867,179,398,447,80,162,20,797,893,586,230,141,778,929,683,702,399,204,870,738,790,873,724,769,985,264,659,287,795,941,328,483,534,777,559,904,458,363,0,745,298,359,831,932,93,688,627,508,623,984,923,494,390,255,783,345,130,514,946,524,650,342,887,560,347,30,60,561,675,129,106,303,140,551,721,331,428,241,98,205,533,883,6,684,338,471,477,672,754,472,477,816,684,374,328,164,73,253,141,873,503,238,586,369,573,853,183,552,305,964,323,752,158,68,998,825,365,425,833,464,816,600,70,500,8,818,700,28,999,140,453,491,248,80,82,242,691,312,549,207,896,336,926,438,428,338,193,715,943,603,311,404,786,65,90,764,928,635,751,618,38,108,926,68,885,550,265,687,337,537,152,171,539,964,153,258,371,76,774,495,823,607,82,81,267,169,305,487,388,67,673,700,865,973,381,677,298,476,130,705,756,855,475,781,803,581,548,732,379,859,292,711,762,415,787,270,536,631,44,356,36,990,122,866,519,661,544,235,651,72,594,468,894,593,921,574,876,96,992,111,294,20,748,912,416,178,310,631,195,427,81,688,787,404,372,690,520,640,745,994,256,157,97,902,818,752,107,529,713,774,958,546,35,666,192,424,63,727,863,622,936,244,563,64,123,386,954,489,652,606,664,968,846,666,963,530,154,86,853,243,866,470,100,262,694,18,332,821,950,836,32,928,410,570,562,10,953,868,391,369,202,414,692,772,642,45,869,114,977,49,729,404,276,646,478,105,154,470,485,36,13,350,672,441,577,48,647,754,215,246,93,791,555,154,225,574,52,638,399,800,251,247,122,776,466,993,564,969,927,682,293,589,461,78,752,770,130,945,786,433,975,184,761,500,569,5,599,511,44,798,703,362,925,433,820,981,896,560,547,727,307,610,866,527,773,61,865,983,65,57,800,310,153,133,840,403,398,492,575,99,616,22,48,716,327,767,681,844,751,507,845,789,174,367,931,253,23,188,850,288,373,521,80,953,94,193,718,960,128,253,12,585,378,319,861,947,75,488,181,685,888,688,890,486,806,327,148,846,987,165,802,672,315,696,730,725,385,202,9,118,827,912,183,974,600,255,493,886,569,523,168,895,658,565,42,484,728,105,361,178,187,36,727,865,485,96,533,22,149,444,481,217,13,751,814,497,301,171,965,176,464,309,438,563,234,183,643,935,280,487,269,74,765,900,897,619,783,964,389,5,316,953,647,199,450,434,939,913,298,540,15,859,362,365,843,486,135,899,749,692,401,854,12,148,313,841,665,289,853,113,346,818,980,391,774,877,679,47,194,489,396,414,991,125,139,904,791,300,511,279,268,939,537,57,562,467,250,80,394,162,582,569,181,803,351,608,833,484,135,439,873,176,989,974,449,973,277,982,939,92,41,798,184,587,232,288,14,494,726,945,268,267,266,947,283,893,924,826,78,683,472,91,449,900,146,319,343,361,529,148,578,250,340,120,530,728,695,490,814,837,385,967,450,307,651,539,719,855,84,634,136,842,671,575,307,798,983,92,699,454,163,257,551,247,811,214,724,151,410,192,606,354,486,754,820,785,825,779,770,376,733,389,493,836,915,833,738,578,48,768,444,862,254,706,150,24,937,98,711,368,427,822,190,822,395,785,875,686,81,672,890,517,241,984,515,503,556,946,760,689,931,925,2,150,769", "453,646,996,349,288,95,404,953,343,458,485,502,54,440,890,315,643,748,387,152,84,389,300,395,732,373,674,631,726,744,631,611,852,911,247,101,721,241,924,39,634,361,723,563,586,626,11,777,564,73,668,42,51,71,990,502,963,588,443,170,942,106,987,716,415,284,658,512,499,71,172,782,104,82,916,999,463,155,269,864,55,483,398,232,962,103,299,451,27,733,34,486,746,537,53,89,46,916,533,795,435,868,705,952,882,252,895,569,388,403,792,670,924,354,588,540,822,702,536,104,725,910,893,238,752,936,624,456,629,330,569,163,235,101,67,171,566,35,71,568,550,707,961,683,73,867,652,639,714,968,620,366,427,426,264,615,924,621,745,641,34,46,725,870,821,323,136,162,113,349,972,214,170,423,496,95,319,400,364,998,721,829,600,653,948,761,628,769,642,781,255,444,57,488,119,263,757,274,117,516,594,721,613,746,55,340,216,105,218,101,252,459,954,290,502,793,157,453,8,748,666,741,537,176,495,761,578,650,206,692,798,628,513,235,678,171,567,181,730,932,599,231,239,829,541,21,83,322,770,904,402,690,326,993,431,112,497,872,56,64,752,950,787,782,853,866,742,15,73,978,724,783,135,370,202,981,382,25,250,725,305,885,521,123,725,401,689,406,58,518,904,901,203,745,0,804,804,632,856,888,882,684,947,361,982,693,585,550,283,824,803,709,2,165,529,71,580,195,347,724,79,316,486,263,35,251,346,498,151,170,709,34,547,805,885,394,171,776,379,93,83,937,296,60,985,308,238,584,240,97,522,55,585,751,955,4,936,81,896,549,563,329,45,319,43,857,332,611,237,853,702,457,704,613,650,224,839,960,379,802,630,188,135,375,956,184,172,947,583,16,290,316,944,345,793,646,407,560,993,6,193,134,515,720,360,220,23,770,104,746,764,830,852,552,726,931,475,295,424,603,434,79,128,153,850,161,671,761,640,892,814,840,383,278,846,403,818,592,116,268,764,191,470,855,683,955,1,897,220,501,121,919,46,513,319,981,185,465,128,317,176,171,934,170,772,241,99,430,476,839,746,731,169,519,450,499,487,12,772,588,416,903,86,276,413,331,355,958,522,441,510,115,899,366,73,447,219,820,350,502,367,922,941,845,268,734,736,856,265,674,132,172,401,743,913,237,53,259,734,411,575,140,870,59,391,902,125,675,782,610,82,307,813,267,394,477,36,808,146,280,973,158,703,127,905,769,500,467,609,232,785,548,291,258,132,228,574,201,797,168,360,666,665,64,218,664,159,250,661,907,780,285,531,960,972,125,568,526,589,297,31,946,982,211,211,388,779,557,802,217,732,400,405,158,270,531,3,818,576,258,508,741,796,553,410,629,701,568,545,822,224,360,745,217,60,109,863,733,702,232,746,478,422,10,589,385,615,773,80,174,454,324,249,949,637,62,414,568,509,559,382,619,695,156,506,998,967,385,503,527,509,669,368,796,218,16,405,548,636,318,328,514,405,934,797,279,614,943,213,581,896,338,716,611,561,52,361,645,524,318,929,717,214,997,793,340,102,593,821,570,741,160,653,316,6,80,408,906,749,325,623,391,133,774,94,954,938,172,90,5,657,676,850,645,982,769,154,43,251,83,53,769,476,213,821,466,349,502,227,991,958,325,996,104,578,504,659,431,257,129,407,441,277,67,827,813,363,748,984,99,87,39,604,532,244,270,410,83,911,743,490,793,452,807,295,199,397,994,217,201,784,129,308,582,627,909,661,240,265,153,362,558,190,193,467,783,450,281,230,283,513,143,324,245,428,864,542,375,723,143,832,261,417,365,570,64,554,490,786,589,750,791,650,699,907,735,642,505,382,526,769,606,103,878,699,799,96,630,733,405,715,974,738,456,187,616,76,480,623,411,764,61,18,419,390,383,613,600,901,338,672,937,153,145,627,207,666,124,165,616,390,288,85,538,451,963,478,41,861,979,605,908,735,440,592,205,379,201,924,470,55,635,554,358,992,190,441,643,18,50,212,181,618,136,767,417,201,483,205,8,574,950,81,954,75,19,285,249,950,979,555,70,24,338,802,925,181,552,895,394,311,574,785,342,975,702,880,16,171,232,511,753,215,720,285,823,527,135,593,626,664,235,187,499,980,554,1,721,594,466,560,984,515,618,102,260,304,574,271,200,893,932,818,102,19,404,97,132,279,571,488,312,918,387,986,369,44,33,769,691,516,951,806,218,977,153,417,187,293,809,691,420,607,617,75,32,851,713,310,725", "729,477,185,808,456,570,194,552,509,514,373,606,528,306,642,523,513,787,574,667,259,329,70,558,718,513,468,97,177,462,342,464,540,589,643,36,244,419,208,13,613,597,156,88,966,653,703,804,154,367,921,254,794,318,963,97,747,39,413,511,855,519,90,123,108,263,899,815,835,119,522,902,57,918,251,976,706,137,123,727,3,566,257,247,8,400,775,356,959,487,190,134,724,369,666,295,19,298,95,411,148,126,409,836,379,511,150,786,738,671,142,334,797,150,111,789,673,697,948,597,880,919,419,662,410,778,166,566,390,434,304,163,146,128,820,86,375,52,289,912,223,288,957,285,931,678,609,275,583,619,341,856,94,79,949,151,902,360,504,355,36,464,615,534,992,570,566,258,110,361,574,345,123,441,218,370,810,917,290,298,162,316,514,921,631,335,543,953,778,93,546,677,191,18,794,48,934,771,904,75,252,644,156,561,67,5,871,734,999,530,220,614,710,335,55,155,520,579,63,116,268,65,86,627,730,195,65,708,961,276,320,884,245,370,977,148,519,733,329,333,388,914,896,266,113,92,139,887,482,1,391,808,491,783,55,803,579,754,7,619,577,393,841,217,586,47,393,148,73,731,435,534,769,376,575,684,156,218,96,231,632,772,260,411,141,303,581,967,817,92,234,864,79,298,804,0,827,289,551,391,761,550,689,530,148,46,540,811,728,468,478,619,244,596,662,347,416,281,725,548,566,625,47,391,76,982,17,533,275,164,151,144,750,845,851,799,986,874,683,547,677,827,49,182,50,894,962,967,465,575,359,54,494,49,524,736,765,226,499,567,249,180,487,858,882,851,507,722,280,315,61,118,471,961,84,527,265,101,72,347,748,585,77,282,872,270,253,18,815,402,945,283,796,863,362,577,531,674,907,910,438,363,139,79,910,330,29,625,949,909,104,79,128,327,558,629,250,393,803,444,807,749,479,738,505,125,259,207,381,551,757,739,112,103,917,31,202,310,419,22,619,903,992,140,101,996,660,71,993,465,223,139,56,557,9,829,157,312,307,703,183,689,523,686,796,473,983,917,583,198,979,807,614,924,868,225,672,884,979,199,668,400,451,660,330,453,454,946,744,527,146,954,185,102,149,980,792,7,456,541,118,387,80,492,336,904,78,789,981,442,835,554,666,832,939,583,561,977,958,887,858,368,729,964,531,718,871,956,68,451,871,204,829,557,805,402,453,976,371,724,688,410,377,714,309,483,401,242,655,678,629,481,211,893,566,237,780,714,272,126,518,418,737,676,430,514,136,82,282,866,350,95,629,225,656,659,906,879,899,665,213,471,442,87,393,149,370,861,549,425,52,814,480,469,405,982,626,578,424,178,851,417,403,777,895,254,151,653,856,957,930,193,71,705,121,841,702,962,66,260,697,124,820,962,621,60,64,674,800,938,551,172,841,665,870,8,798,464,78,955,513,834,687,601,132,743,43,614,343,265,820,901,189,745,347,199,470,599,275,118,259,231,7,836,243,387,686,577,235,957,838,382,300,147,9,931,975,727,944,687,576,425,772,266,974,895,481,433,958,326,847,848,268,819,375,271,723,198,948,846,233,975,100,361,957,373,498,708,371,965,963,305,941,369,415,27,763,157,604,948,246,143,817,622,660,887,135,338,32,340,435,112,25,96,772,427,860,811,643,769,988,255,67,872,237,586,930,275,217,288,790,838,728,967,560,661,506,879,564,328,366,914,665,589,84,149,764,818,516,704,143,560,18,762,185,634,568,184,538,225,272,32,739,59,719,920,725,877,115,963,94,383,721,68,948,716,994,131,521,849,62,833,348,760,386,198,140,261,811,88,561,802,350,841,683,887,98,65,494,866,221,664,197,722,709,215,585,906,915,228,367,398,543,974,245,458,591,847,118,295,844,555,977,432,292,678,599,421,769,186,482,620,237,440,25,321,987,417,757,524,992,200,667,47,480,203,397,500,6,820,654,25,54,694,936,674,39,684,867,583,876,474,871,996,297,614,344,867,866,567,125,6,825,520,375,907,1000,460,576,804,123,990,569,211,894,594,594,257,661,573,439,919,838,59,685,143,311,909,286,876,864,964,162,291,221,890,539,318,916,597,320,446,874,714,692,946,769,501,452,308,379,535,791,450,84,307,295,209,964,873,994,799,522,19,630,930,856,265,51,313,372,468,278,793,249,298,614,551,178,867,574,6,124,671,965,482,577,301,360,431,720,894,407,561,514,357,348,589,895,264,640,118,503,459,799,333,500,801,682,362", "744,890,345,688,506,861,555,245,647,958,67,996,520,102,197,954,918,30,573,380,197,957,718,264,496,85,166,774,556,172,905,675,737,670,234,980,510,147,952,602,379,763,794,714,907,887,193,651,849,980,840,629,743,972,84,926,630,477,909,54,140,775,493,926,954,489,731,667,694,830,991,940,279,826,592,4,133,189,23,564,69,968,238,783,53,519,885,513,590,639,458,382,445,650,633,994,13,328,598,8,309,371,677,427,916,737,347,873,772,408,412,109,86,797,231,624,646,89,974,463,712,338,168,560,570,164,671,602,77,596,185,204,752,742,324,64,328,395,289,785,100,888,241,917,529,391,273,567,31,148,747,675,837,514,133,642,651,538,210,663,731,957,102,347,571,432,903,200,474,151,689,856,205,127,995,250,618,23,44,722,779,661,322,388,63,606,802,227,351,985,205,153,169,932,401,60,393,179,471,154,432,616,330,445,72,220,909,553,103,743,236,64,818,24,350,681,555,1,462,401,822,890,901,259,59,957,137,731,947,39,159,576,848,406,568,513,521,730,923,14,177,546,662,496,187,134,194,230,966,184,966,335,176,581,989,630,919,758,782,329,56,983,80,628,366,651,733,49,175,850,539,970,689,50,903,976,626,605,709,569,464,682,111,996,512,988,873,270,325,683,851,434,400,359,804,827,0,172,932,869,948,661,650,639,5,608,391,121,882,832,914,644,684,697,635,657,254,539,295,204,321,952,714,649,929,376,218,759,66,443,660,905,127,994,148,555,891,338,498,101,341,869,592,555,978,716,93,369,545,537,453,566,190,930,969,400,896,108,470,784,501,122,364,840,905,430,557,244,465,761,238,19,450,566,416,682,282,937,303,857,966,153,471,468,341,437,646,179,208,272,735,987,880,21,373,140,764,210,853,813,279,49,798,646,797,331,81,205,753,626,755,246,542,964,240,450,953,839,900,820,994,203,732,597,56,621,585,215,488,586,907,365,289,840,21,547,823,42,932,461,270,56,582,36,429,924,715,693,607,270,970,948,125,664,82,166,881,316,740,534,396,427,499,211,932,478,80,923,658,268,871,366,249,995,679,877,320,485,626,942,807,288,977,978,151,807,962,410,461,981,840,33,423,492,428,261,249,28,402,316,925,371,586,181,332,513,474,684,175,676,579,697,735,122,759,25,785,485,556,98,203,817,24,865,60,626,247,759,800,438,561,396,958,916,393,916,20,160,406,757,316,279,382,96,419,898,840,304,883,599,67,949,991,176,925,449,892,543,468,278,6,392,324,880,154,388,883,177,255,240,435,903,121,100,205,7,203,289,525,731,175,196,173,152,232,870,234,643,586,503,869,673,10,974,329,509,227,457,468,323,885,571,892,53,485,983,804,463,285,738,846,372,218,549,120,386,924,507,580,58,362,885,902,656,740,921,116,398,956,133,808,759,375,891,285,628,44,667,30,722,722,411,136,226,884,523,943,609,472,246,969,525,698,381,245,312,501,129,202,16,475,514,386,403,927,512,761,885,371,251,796,675,73,742,114,196,616,492,741,882,941,860,13,631,95,386,260,3,7,508,195,886,815,657,700,425,849,629,264,948,780,431,695,191,142,960,865,945,925,852,500,138,163,652,962,336,237,897,75,44,374,847,650,435,404,251,162,257,150,500,639,55,334,723,542,585,155,81,95,729,290,767,802,371,673,523,396,101,202,445,239,347,850,972,328,789,856,737,827,657,104,334,580,446,295,541,463,134,580,126,769,912,45,463,798,487,625,70,264,191,343,962,759,102,881,472,57,480,639,839,559,841,235,825,18,884,925,973,630,507,36,613,541,848,537,356,511,562,405,579,876,148,534,944,220,785,663,59,442,896,791,782,682,457,995,38,84,781,82,81,665,820,805,343,901,960,141,217,378,758,446,303,629,184,929,113,590,302,949,379,913,438,727,648,72,446,762,306,704,824,739,629,177,62,338,987,738,684,508,777,548,46,909,379,587,42,232,363,816,684,31,86,872,212,629,917,188,677,831,641,442,528,378,907,475,726,231,523,181,524,574,192,144,486,715,672,750,185,570,45,716,953,669,563,69,359,963,409,42,574,838,640,23,633,700,140,691,387,246,768,237,917,576,930,78,852,227,805,978,908,712,418,569,950,22,390,300,107,114,504,787,216,344,205,708,614,382,243,210,237,207,168,114,310,449,910,647,915,346,340,130,382,32,968,449,723,98,808,414,740,566,861,483,719,71,682,80,387,279,60,291,963,677,485,41,464,600,76,740,719", "166,624,714,280,667,815,544,760,892,770,4,320,413,914,471,520,666,146,939,796,385,554,141,490,906,303,327,556,349,34,536,117,561,163,150,733,400,441,34,338,21,173,32,465,225,498,537,592,331,391,243,800,850,818,399,775,687,60,940,683,347,277,234,801,693,228,416,637,469,221,278,241,139,822,428,848,651,442,892,120,448,372,48,174,58,410,94,787,505,654,92,123,471,313,19,274,583,920,443,364,695,739,894,62,232,715,181,228,263,810,692,644,579,156,267,918,278,16,500,517,22,387,280,955,820,633,3,664,452,830,31,398,224,570,793,338,444,53,372,700,624,387,766,673,183,365,319,586,874,241,349,145,506,554,804,283,281,921,857,237,970,827,140,684,259,664,972,832,67,620,200,205,518,756,625,95,946,280,666,523,663,334,62,704,934,98,370,516,174,213,201,681,953,891,38,540,600,545,603,178,13,77,37,401,996,282,297,280,135,775,740,190,729,341,76,434,591,437,550,477,364,764,992,188,390,329,846,728,102,42,238,849,839,662,771,379,664,155,730,38,931,684,657,328,463,303,719,544,212,726,870,564,356,224,212,257,729,414,367,779,383,4,182,512,666,86,144,119,167,363,189,730,249,830,733,248,599,925,863,298,993,85,832,818,329,823,737,877,835,267,565,400,606,831,632,289,172,0,687,121,424,12,961,830,90,915,508,479,351,502,463,969,774,426,927,647,170,50,342,809,926,26,836,179,837,375,669,20,442,764,635,110,929,853,863,240,186,417,798,980,839,917,635,257,229,298,152,26,856,211,462,875,712,676,558,960,637,462,393,159,433,61,109,889,3,90,367,148,803,660,321,503,866,325,311,129,194,392,992,691,514,36,386,225,140,672,188,641,227,464,484,503,131,52,884,976,746,740,224,833,8,723,814,897,177,597,361,299,167,936,214,912,410,123,338,86,589,596,201,146,852,284,866,276,125,207,609,465,473,903,709,379,822,110,484,618,659,675,316,355,484,249,684,328,379,152,867,421,422,174,372,380,385,887,835,499,23,475,471,771,310,873,842,281,135,563,672,660,209,906,950,3,826,689,988,464,638,824,981,379,623,28,435,360,136,918,783,860,606,845,943,574,511,963,383,27,772,124,151,23,300,271,74,559,927,264,566,539,655,276,299,711,552,786,806,414,284,787,423,120,884,527,583,207,783,89,441,425,190,596,56,646,177,284,711,110,98,409,816,651,52,712,146,369,58,981,221,412,641,91,839,823,129,388,483,130,303,976,959,20,417,904,18,98,779,589,226,599,234,250,114,863,132,933,324,358,998,261,142,724,755,373,680,844,974,581,419,345,588,735,997,894,866,856,749,278,809,451,736,862,570,865,425,913,668,523,320,195,642,776,979,20,371,542,677,274,203,881,834,33,874,536,857,818,728,359,878,630,480,428,599,404,809,720,309,144,103,725,704,91,401,239,748,964,778,292,217,742,757,919,911,924,166,43,990,184,814,756,353,672,132,686,713,369,118,425,964,581,657,57,535,100,892,400,915,755,503,25,465,627,194,27,122,312,853,868,786,836,196,32,635,415,819,819,694,993,984,955,992,772,613,971,504,370,155,194,900,59,919,10,997,856,389,795,377,95,721,427,195,400,990,301,41,272,166,331,179,222,165,922,917,703,883,224,129,397,839,840,271,817,216,872,412,348,505,13,803,277,99,255,82,969,901,792,513,812,726,845,456,520,657,21,625,807,799,902,20,812,48,720,564,354,444,176,780,534,280,316,759,424,661,934,73,204,583,768,256,832,332,56,871,257,167,241,641,445,747,810,593,185,766,193,677,750,128,834,680,906,766,655,808,228,815,186,834,333,136,187,895,922,522,170,862,406,963,979,32,516,315,386,456,897,166,655,610,143,900,549,97,727,239,272,619,609,516,845,98,206,71,117,108,749,837,612,902,105,203,503,485,768,80,896,331,52,963,165,170,724,560,16,456,386,720,55,212,870,577,197,127,61,481,362,515,90,953,803,749,558,189,813,770,810,359,141,244,110,862,204,6,39,106,894,819,746,201,180,788,510,509,202,922,893,533,811,638,93,866,855,19,678,707,663,746,366,390,619,71,267,254,93,880,894,616,359,816,583,126,900,744,52,18,347,277,749,473,119,525,16,516,708,759,629,846,402,906,287,369,948,164,722,329,574,486,74,87,168,752,331,910,134,917,570,218,36,877,356,106,97,451,317,295,423,197,481,269,437,989,346,635,14,896,10,128,639,495,277,614,841,618,880", "880,850,848,743,725,978,597,305,134,505,98,414,911,858,557,502,503,664,850,628,671,279,152,650,200,665,900,581,801,12,217,396,573,146,519,606,535,83,150,14,248,105,388,462,519,963,161,521,417,937,365,52,484,539,915,403,460,728,135,771,280,517,737,638,523,619,340,415,775,258,665,913,979,10,299,51,167,459,626,601,912,263,329,387,351,229,236,78,171,591,631,183,474,165,832,864,686,495,149,470,663,578,315,193,115,354,157,953,255,120,432,408,389,673,107,25,268,647,18,104,108,21,582,351,61,384,106,334,656,389,290,325,630,593,523,7,264,846,23,242,37,788,604,970,43,457,227,301,343,110,682,283,385,482,861,241,261,482,877,418,343,761,145,557,789,323,697,975,978,97,762,281,212,38,395,984,51,130,708,267,186,201,214,820,631,664,276,560,672,880,281,359,982,623,66,881,716,307,63,669,653,434,506,9,265,93,660,445,266,184,456,450,378,620,166,580,172,857,512,231,224,243,541,722,147,619,121,306,519,761,464,705,454,576,145,508,442,291,702,301,18,11,144,193,590,600,819,539,485,405,575,448,788,566,880,918,749,761,504,37,470,630,687,663,964,937,262,650,149,767,653,451,881,542,988,732,480,101,991,346,379,565,803,99,101,944,928,556,926,205,750,473,810,932,856,551,932,687,0,838,275,521,323,968,802,624,465,12,665,698,838,123,36,158,188,404,904,944,410,885,859,622,511,857,73,283,358,752,938,113,611,342,377,724,806,539,222,268,908,25,983,241,877,944,320,871,587,214,44,583,67,700,856,115,268,323,807,807,703,210,5,76,417,848,466,242,948,631,591,821,13,286,406,96,525,426,927,694,458,528,6,739,306,618,127,185,365,502,361,697,731,514,432,388,443,102,135,456,822,473,63,4,289,854,585,760,660,494,698,22,465,419,374,410,312,572,17,644,553,863,280,890,882,924,976,299,813,537,857,704,26,754,831,40,820,153,3,639,69,721,755,277,679,373,467,977,998,798,36,342,796,989,365,401,142,796,634,928,20,91,529,526,639,760,738,664,763,75,830,391,635,339,98,324,829,811,376,461,90,199,198,940,651,64,762,986,558,828,596,735,812,619,704,2,59,323,626,558,867,247,832,736,591,856,759,462,288,891,324,588,254,984,513,174,203,210,65,641,335,664,216,406,645,312,991,246,24,251,101,290,694,471,600,660,791,694,648,416,199,31,220,933,475,239,362,498,452,475,707,730,250,333,922,435,653,148,987,560,458,800,120,914,482,106,738,138,97,334,443,115,234,8,704,122,631,686,581,30,292,709,366,727,771,175,155,527,255,178,672,661,302,431,75,914,446,263,917,327,757,95,177,691,904,485,704,823,321,824,243,114,584,784,756,915,520,133,105,738,998,764,757,112,886,680,165,65,910,183,519,299,309,667,462,552,850,666,331,192,105,379,844,935,850,791,534,33,364,574,415,374,405,332,45,978,434,287,704,856,27,822,952,309,994,500,106,220,746,590,955,858,297,934,81,790,548,57,790,56,7,266,207,601,307,461,171,865,690,521,86,773,290,617,2,183,993,152,921,66,750,869,869,945,82,67,921,45,845,151,97,829,695,824,62,130,557,395,592,495,746,991,578,413,365,129,79,496,257,77,501,548,754,747,782,321,483,346,986,252,687,551,632,114,755,599,230,797,223,813,386,14,357,733,189,699,974,546,142,771,747,160,421,697,767,813,667,538,200,370,690,670,568,181,819,916,915,938,188,324,461,427,813,970,371,854,660,944,607,315,560,223,789,720,280,39,669,807,481,446,290,745,406,308,565,222,973,98,232,521,760,425,269,814,494,263,448,703,103,921,935,85,615,355,256,310,411,436,533,379,935,108,612,487,749,162,899,26,292,199,325,232,278,595,268,111,329,864,255,705,248,225,419,154,809,850,751,282,990,473,643,483,116,750,498,918,570,554,63,930,247,465,632,697,819,345,411,663,57,271,60,546,760,982,244,918,802,625,851,190,8,490,739,117,470,45,960,97,575,166,456,570,785,943,22,821,408,960,662,767,384,613,2,359,579,844,114,272,670,397,499,468,969,529,432,154,549,784,153,546,537,776,100,852,157,737,565,91,934,843,781,464,360,30,537,612,169,733,368,109,232,405,35,60,461,105,359,955,511,551,634,441,39,202,670,428,363,824,153,904,344,278,49,846,561,411,188,868,511,58,760,271,874,631,816,161,875,297,740,428,917,179,435,305,480,427,660,168,147,347,198,941", "800,69,217,824,392,287,886,58,194,709,868,974,314,564,835,992,778,249,923,94,899,596,935,814,850,58,83,204,770,296,474,171,989,714,627,332,668,229,438,919,676,757,63,91,921,44,655,556,3,87,219,531,388,971,272,681,351,664,698,313,316,160,866,652,877,684,802,805,326,47,793,301,590,776,82,404,990,807,555,119,922,632,679,658,518,416,79,442,663,294,366,976,514,152,654,526,567,632,129,8,571,439,815,436,681,388,917,847,24,254,211,450,140,241,558,132,641,214,972,557,424,613,749,874,21,851,35,611,267,173,275,105,2,982,928,882,212,968,371,98,486,505,323,203,211,698,18,221,596,148,72,282,693,494,925,781,862,602,145,382,852,715,263,352,511,6,905,388,397,732,143,368,977,944,986,804,469,841,200,32,162,507,462,887,940,639,598,752,265,207,451,775,355,625,853,823,203,942,109,376,510,290,660,309,271,475,500,598,249,903,656,828,537,246,10,177,907,504,468,402,814,563,204,216,469,965,357,230,796,180,248,417,142,690,888,689,784,714,52,247,93,12,201,633,30,759,323,436,627,830,459,988,17,296,905,749,520,842,930,774,417,555,908,85,49,513,632,458,833,873,346,812,589,6,220,886,958,572,496,757,342,141,405,839,222,855,26,507,864,311,553,925,276,93,888,391,869,121,838,0,109,141,119,717,566,881,564,920,378,444,231,278,924,950,197,908,135,101,482,98,262,961,696,939,962,118,740,257,958,63,203,691,286,579,724,541,133,301,745,275,230,503,975,228,298,180,81,685,560,509,16,87,773,593,345,497,662,865,223,29,650,770,336,335,373,701,677,286,677,417,474,264,361,62,925,394,214,607,768,307,136,246,392,937,847,79,858,726,529,930,102,233,35,202,396,444,858,530,241,384,827,803,314,751,470,352,83,38,917,12,805,201,991,843,328,739,626,886,671,557,796,904,547,783,322,672,74,489,965,584,482,528,114,565,147,176,863,875,168,699,737,538,958,41,902,286,344,928,254,615,442,576,319,478,177,529,692,948,587,926,250,18,734,385,569,921,953,468,727,949,395,5,613,758,55,793,271,174,251,997,17,337,78,672,124,30,614,574,440,644,509,814,61,112,147,280,804,519,107,944,663,499,953,453,63,401,272,753,893,390,318,229,952,455,189,887,536,623,614,133,826,410,69,864,592,636,149,466,111,967,545,943,431,374,722,159,851,986,368,831,896,97,279,651,300,871,780,557,992,665,27,755,975,307,607,789,145,15,293,214,915,212,780,679,201,427,519,461,892,623,727,523,668,812,230,738,137,207,582,993,241,999,128,245,80,946,643,632,739,133,240,525,312,820,284,642,914,79,218,638,493,556,542,100,41,471,739,530,257,151,131,664,237,154,172,447,859,912,869,481,771,39,109,239,159,30,363,591,373,741,146,634,17,577,31,230,624,143,65,21,224,574,933,901,940,952,194,241,730,983,978,693,759,955,715,788,312,630,976,124,163,579,850,756,37,45,440,939,716,742,150,31,657,879,840,306,920,920,549,722,629,537,621,677,749,451,606,629,213,268,960,769,805,211,222,904,940,553,823,921,742,73,365,197,766,198,582,813,594,662,696,132,182,781,195,586,650,86,620,963,856,323,912,150,829,265,851,471,912,418,340,553,251,307,967,183,332,6,485,484,163,609,635,275,863,280,827,789,623,565,727,462,881,284,412,366,310,440,361,991,565,586,415,435,801,242,629,805,794,614,855,499,518,941,466,238,653,262,66,491,110,670,443,431,29,851,386,529,162,841,74,228,101,127,52,242,945,586,184,937,610,329,326,511,355,201,398,455,153,694,379,76,261,701,884,46,135,850,343,265,341,983,495,28,223,446,52,754,987,589,242,465,354,355,413,207,491,365,670,729,438,275,233,920,901,272,829,3,451,13,777,46,386,685,277,20,74,796,933,455,873,588,330,418,556,807,937,400,957,688,436,590,768,877,875,596,349,796,873,856,824,996,752,525,734,331,153,33,107,851,159,587,957,146,625,202,116,229,377,145,519,846,196,490,950,374,315,682,327,766,870,554,870,418,787,783,301,847,611,948,365,97,641,590,932,417,790,485,756,681,290,153,454,109,890,678,483,769,493,767,509,659,853,590,236,101,250,503,838,93,912,614,997,783,962,603,368,391,503,131,409,99,378,18,298,444,444,707,280,363,11,47,890,867,27,514,800,49,755,879,96,205,403,249,62,337,193,144,458,763,755,467,152,717,45,518,817,17,845,521", "860,155,648,396,37,31,282,657,988,114,871,388,543,738,712,290,486,610,956,2,754,664,716,270,739,885,614,742,712,139,603,176,23,786,800,140,949,352,479,208,642,802,458,435,608,929,223,942,266,155,487,879,49,524,117,128,28,489,759,861,908,480,61,955,640,729,742,90,194,252,102,505,895,651,36,21,568,900,982,73,287,212,610,560,698,559,242,667,319,232,908,658,139,873,168,773,269,66,114,93,266,947,919,827,339,407,998,363,93,783,955,697,350,162,103,904,234,281,424,693,221,926,519,344,498,743,88,82,572,27,260,187,847,889,505,467,617,969,166,292,26,489,337,795,38,858,722,918,918,821,441,563,583,727,967,225,597,930,400,925,500,770,858,521,637,424,627,926,642,419,859,536,632,722,930,952,467,3,457,957,981,533,712,366,408,543,111,904,329,881,180,715,263,498,366,929,793,95,694,748,641,643,212,608,624,837,290,938,97,394,56,683,495,495,774,417,422,57,332,334,968,393,84,951,436,208,419,863,741,241,734,756,41,860,687,401,422,314,612,325,796,479,593,251,129,365,563,347,596,222,949,564,76,496,729,33,874,985,70,556,964,893,138,485,394,244,199,423,474,180,509,328,50,575,815,420,354,148,797,965,450,944,215,482,391,757,604,982,521,610,375,650,780,688,882,761,948,424,275,109,0,34,607,626,447,824,752,509,244,895,107,172,516,83,480,289,5,691,368,628,315,274,397,878,853,300,370,635,341,45,800,87,835,825,328,61,381,139,955,652,861,565,320,909,952,221,64,832,883,429,512,891,194,182,357,325,619,344,994,841,711,985,279,910,81,858,588,634,834,998,234,705,370,391,788,288,526,457,871,978,199,94,921,517,570,894,882,887,427,748,735,287,107,910,959,819,518,278,420,911,99,498,877,704,140,96,861,740,41,960,716,942,954,784,591,93,264,339,375,809,468,649,821,289,254,21,888,558,12,669,477,614,545,158,5,919,847,475,481,896,559,326,38,303,721,22,707,184,809,233,76,181,187,305,34,519,394,583,197,90,677,1000,459,907,990,780,806,546,280,853,973,642,222,336,405,373,302,205,67,538,398,699,138,635,590,705,615,770,850,784,31,354,592,401,513,195,879,590,364,327,320,926,159,269,832,719,564,839,812,116,462,459,582,372,80,297,893,293,63,480,373,935,438,864,849,246,15,7,580,41,250,884,99,56,124,776,745,269,494,196,725,962,41,95,262,725,364,779,951,209,416,817,609,575,736,762,893,367,933,447,531,98,113,877,439,266,625,150,230,534,955,392,959,663,269,511,993,756,181,698,286,749,759,438,641,779,795,251,136,230,227,544,438,263,443,711,590,281,801,258,872,381,982,892,128,929,686,733,505,205,53,646,381,416,809,415,814,997,103,297,816,231,594,597,456,232,512,612,133,980,525,135,857,38,754,348,168,904,62,748,154,134,299,505,809,712,762,115,497,397,26,478,885,998,876,891,685,982,874,104,524,601,338,865,139,289,64,325,121,337,761,194,94,756,785,910,386,585,614,77,704,746,12,181,416,687,112,225,841,980,26,618,828,391,942,929,768,214,414,28,649,871,738,242,570,586,880,98,405,406,651,581,393,55,481,295,679,692,736,440,681,960,21,653,266,439,795,946,850,691,522,819,362,928,12,526,913,954,80,446,707,221,512,601,145,111,343,854,946,466,722,976,461,488,961,649,539,822,543,947,223,757,585,515,249,137,646,615,628,59,206,816,736,23,783,430,981,293,402,890,845,675,972,452,136,871,377,133,565,161,484,334,305,976,906,866,646,295,53,54,683,818,957,569,988,681,483,177,160,315,20,725,565,285,487,816,464,161,387,670,416,225,540,539,156,594,518,216,454,306,41,534,874,989,726,521,748,400,318,299,729,136,414,180,175,27,687,55,34,854,107,539,142,719,274,910,907,461,316,963,181,658,530,541,168,543,586,44,37,880,764,669,220,918,574,669,984,486,844,901,959,369,892,844,430,524,276,211,188,649,401,919,427,296,22,127,513,406,811,936,703,196,684,965,425,885,771,451,532,580,795,470,140,426,108,716,617,844,423,37,547,880,811,369,905,802,461,944,773,9,541,435,434,151,492,65,949,313,198,496,615,793,493,202,907,126,84,168,9,837,884,442,152,156,789,99,508,109,505,923,970,234,9,168,731,231,63,799,930,734,601,405,796,483,401,802,810,579,873,761,663,675,862,39,949,38,871,379,486,993,649,862,335,573,907,299,846,831,481,595", "869,897,244,664,641,875,890,230,370,212,926,625,205,819,386,659,59,727,814,968,251,741,634,745,759,796,861,479,611,189,597,320,506,541,612,457,24,645,711,52,40,42,300,135,531,638,437,75,592,677,594,869,141,708,762,518,675,501,82,67,826,118,193,129,63,697,278,852,995,812,582,615,935,126,720,277,465,944,145,771,442,640,551,330,511,732,954,373,306,204,703,59,737,684,355,894,994,255,739,318,867,828,68,220,795,377,983,469,555,767,817,384,552,134,54,308,145,542,513,577,412,297,880,579,766,937,89,450,682,482,345,905,46,647,879,434,550,744,885,84,584,459,933,43,145,930,301,573,450,836,313,966,850,274,745,991,343,59,313,634,996,694,271,319,907,687,769,861,507,162,552,643,171,7,128,83,727,332,214,499,642,344,719,567,467,561,857,543,225,427,737,73,429,132,421,919,298,632,317,283,530,944,661,764,237,687,459,948,922,732,474,709,354,383,279,721,100,409,784,543,370,74,402,263,32,425,663,237,739,793,47,721,673,361,761,785,712,22,808,282,34,672,235,284,227,734,852,888,902,703,260,540,999,574,849,284,759,920,340,381,308,701,334,289,950,341,583,230,591,401,835,346,798,215,122,4,760,477,664,625,476,725,757,560,342,273,120,855,677,593,776,793,201,627,684,550,661,12,521,141,34,0,783,970,63,986,729,841,909,289,701,254,764,458,471,340,678,448,100,210,107,578,648,442,402,757,702,557,37,853,321,480,997,377,184,728,955,846,940,841,638,569,696,462,274,710,877,25,484,418,903,994,413,950,12,285,839,656,228,844,339,302,862,675,471,942,557,707,462,332,297,590,914,131,385,518,998,526,462,783,160,213,186,33,440,301,581,422,506,448,989,841,104,422,416,601,934,446,781,512,253,247,819,386,322,497,113,713,852,897,173,423,482,432,557,725,139,900,628,642,119,307,706,739,806,927,565,579,449,845,945,611,8,88,827,484,113,907,665,471,619,970,751,959,198,647,224,939,506,224,810,348,436,410,664,612,276,216,871,535,552,583,281,650,111,82,816,268,778,143,884,823,336,103,241,282,858,113,310,267,408,901,800,231,427,177,617,5,79,549,852,385,964,727,358,148,519,339,946,312,272,713,416,298,951,258,58,60,291,181,918,161,871,64,760,647,501,292,37,147,719,46,453,714,798,80,308,761,724,291,800,167,516,400,265,206,278,716,421,438,16,859,496,98,469,658,940,226,368,58,183,777,53,675,613,996,184,846,217,521,951,519,583,876,365,368,746,329,129,618,871,696,92,874,32,660,512,813,949,117,532,65,501,75,42,379,899,726,825,564,665,993,164,393,998,933,165,562,271,412,205,393,927,336,220,122,45,338,270,425,250,389,209,310,270,474,428,359,765,661,832,258,2,177,156,753,422,492,556,600,273,669,907,180,791,89,21,658,14,778,514,239,397,12,634,851,814,274,270,926,227,93,358,318,969,220,789,243,194,935,675,782,248,849,327,363,995,734,187,444,581,243,948,430,88,845,136,701,664,389,42,837,867,160,701,841,329,396,363,127,994,234,226,789,952,411,504,905,757,461,252,620,424,716,263,589,460,298,800,603,896,925,585,520,56,959,212,68,705,950,230,857,878,7,849,50,765,422,448,261,37,970,497,247,426,367,18,393,655,37,378,192,754,104,493,522,598,349,954,868,764,345,490,100,262,508,463,438,853,650,915,436,174,820,919,454,168,670,96,801,500,30,107,553,306,295,441,464,371,536,790,514,216,302,379,969,981,904,468,78,217,679,775,632,52,619,452,517,242,416,726,62,132,909,523,683,742,358,504,793,75,924,816,173,805,642,885,242,243,275,911,13,566,552,677,119,266,109,956,56,312,749,231,928,303,967,390,993,225,325,955,473,417,543,790,725,574,339,630,765,369,972,656,684,236,213,221,729,860,61,384,964,967,24,366,435,772,724,237,802,918,195,958,572,644,568,945,414,579,170,451,181,61,100,299,774,131,892,521,995,854,914,221,882,330,30,190,337,95,330,8,888,794,202,193,820,214,92,11,331,420,42,925,203,587,904,509,429,123,254,365,487,509,382,132,584,483,825,253,822,594,635,537,448,349,436,766,130,567,745,729,427,124,54,392,598,832,272,311,667,313,689,990,103,377,808,932,967,677,875,657,802,248,979,842,452,759,344,165,569,235,351,471,468,456,3,130,896,863,311,735,123,326,683,845,769,911,845,206,600,494,247,519,690,288,727,215,62,280,754", "805,498,67,467,545,428,215,43,770,20,70,396,128,886,144,91,46,197,562,870,59,502,270,453,294,209,534,448,274,92,371,52,676,674,998,484,499,83,698,311,275,773,228,565,25,867,928,137,920,719,767,797,81,201,979,522,690,532,96,1,125,945,847,143,383,97,606,569,866,119,520,661,78,511,862,628,700,84,420,549,676,306,519,748,912,910,472,333,764,379,703,573,215,27,154,15,117,19,246,64,81,887,485,486,833,701,617,503,488,999,758,445,298,316,9,211,518,712,84,387,591,412,382,121,773,263,277,583,262,394,906,432,116,278,566,815,691,921,750,848,273,212,270,144,306,905,757,809,749,176,236,765,60,412,435,804,194,791,866,483,754,988,190,188,516,720,622,702,789,95,456,416,864,98,328,415,370,768,263,961,289,690,464,226,986,725,218,479,987,751,708,685,588,547,467,579,416,91,437,185,610,769,970,744,856,488,344,353,121,510,797,219,75,893,722,26,569,602,577,241,124,905,273,704,349,894,277,984,743,836,72,836,76,406,72,545,330,999,32,170,522,243,564,831,819,16,68,189,997,904,564,811,129,231,273,416,696,141,520,72,310,124,127,74,105,498,155,367,291,456,332,407,246,774,163,274,517,920,464,448,655,973,457,170,353,394,128,342,565,259,48,408,808,508,947,689,650,961,323,119,607,783,0,770,997,410,187,398,749,258,461,552,402,134,413,833,52,467,884,264,528,392,863,120,6,379,783,987,494,915,679,862,616,487,708,23,353,804,71,234,311,154,280,654,314,679,626,655,862,495,154,433,325,429,805,239,829,344,498,666,669,830,515,333,579,547,918,932,584,647,548,866,965,319,788,37,681,452,724,474,69,369,635,892,419,754,361,965,261,971,542,873,48,742,929,671,128,313,804,922,691,492,504,269,209,992,531,494,306,4,873,54,114,117,766,99,663,350,433,773,580,859,514,287,976,918,261,842,786,851,20,306,119,366,809,789,259,172,790,602,797,553,857,56,854,504,694,556,907,596,548,102,450,992,383,995,443,308,356,972,230,696,47,206,223,649,754,513,492,540,296,436,121,773,548,319,984,549,485,63,164,366,947,425,694,493,741,871,615,35,827,131,618,223,672,109,902,646,433,467,627,733,928,511,367,310,674,205,790,906,370,347,334,439,67,718,50,688,481,373,343,675,705,453,86,939,375,258,432,385,924,484,23,393,185,343,563,433,56,735,797,981,630,85,147,928,247,857,870,2,733,107,791,68,879,296,887,380,88,822,19,798,706,647,967,348,93,591,972,160,761,843,934,585,810,472,248,615,269,602,905,249,744,342,264,584,949,753,308,584,395,557,100,885,791,696,41,768,295,924,574,317,281,717,336,991,602,102,271,797,551,469,16,315,125,93,481,535,999,911,79,669,155,216,313,478,416,634,301,370,663,223,495,408,546,597,84,661,430,338,616,630,677,586,50,590,555,267,63,112,786,505,73,505,352,118,775,531,491,912,751,336,567,402,738,857,750,178,730,21,490,781,494,441,204,349,681,333,805,296,184,343,75,293,236,276,17,340,517,681,287,865,969,467,836,718,920,898,427,542,679,853,601,709,855,319,665,882,787,301,666,309,908,443,904,576,853,38,52,144,525,516,332,383,908,954,587,312,305,580,740,229,421,198,833,628,593,378,288,333,956,947,436,89,848,451,790,685,477,47,200,978,809,2,296,609,508,542,608,330,472,712,357,912,218,828,26,619,428,544,359,977,863,773,519,72,323,656,53,990,511,307,811,685,248,605,877,131,941,385,39,733,985,103,515,460,520,760,672,325,887,96,280,819,904,940,393,229,487,525,629,891,622,155,38,270,410,706,459,830,361,449,28,238,499,609,452,281,715,797,573,739,42,249,405,489,136,45,955,312,335,506,682,990,328,660,995,22,472,51,535,242,833,281,558,927,499,940,890,974,143,634,281,97,214,117,180,809,831,762,556,584,750,505,161,63,354,111,57,767,725,499,786,556,234,106,735,872,906,246,374,546,64,664,725,774,829,668,786,962,937,947,721,78,431,951,249,36,572,734,323,841,608,683,355,559,854,472,54,952,766,262,202,62,427,858,853,395,148,542,713,401,202,399,3,215,241,777,236,275,284,116,273,540,314,631,669,579,94,903,990,412,489,658,881,117,302,69,648,546,202,412,683,296,333,879,94,506,340,164,815,535,927,943,27,210,529,438,878,741,462,484,279,189,673,865,170,985,183,210,152,169,181,464,607,177,381,921,671,565", "873,813,94,751,137,246,973,759,145,463,757,256,227,318,198,113,714,610,254,940,63,924,568,584,16,188,166,944,353,336,777,40,237,607,124,998,274,919,22,653,392,968,720,232,482,301,978,93,340,276,398,687,513,465,304,844,755,560,884,81,374,363,916,542,354,324,241,440,840,904,676,57,972,396,540,527,463,292,141,180,454,305,506,951,696,685,354,480,9,639,200,509,125,984,952,615,932,708,224,443,388,802,6,548,604,271,983,782,904,202,898,572,687,743,642,398,819,194,687,691,59,116,670,26,386,356,97,312,48,684,368,713,718,147,28,901,880,618,144,149,246,149,73,144,999,732,362,316,458,249,478,409,175,648,988,3,289,652,142,172,531,999,331,417,818,600,820,818,139,352,53,366,603,468,543,960,108,232,771,20,445,405,376,690,565,751,442,61,540,141,935,679,69,196,613,684,280,965,614,460,87,152,902,962,822,508,858,174,647,11,556,292,237,26,602,365,645,416,387,775,151,509,973,258,361,50,80,516,653,628,805,149,525,282,521,885,685,527,684,675,29,877,509,183,695,672,579,517,624,507,667,280,895,440,344,164,578,542,974,532,351,970,361,987,29,277,806,62,174,32,167,309,420,853,881,808,331,210,776,874,974,216,29,329,453,777,326,921,456,837,960,122,785,623,361,530,639,830,968,717,626,970,770,0,472,499,391,991,89,178,705,133,736,771,588,730,269,969,543,90,212,495,738,101,853,13,251,466,233,112,171,318,86,194,573,126,206,192,424,735,85,925,374,889,510,737,593,827,880,145,764,357,971,700,155,816,110,73,948,836,925,735,811,739,309,548,404,237,293,549,842,759,326,929,764,504,659,248,59,874,751,714,182,395,544,386,979,808,466,729,160,118,812,624,296,882,980,983,875,641,879,881,652,835,551,437,561,487,37,502,292,915,696,482,996,411,342,450,234,24,952,913,171,231,904,851,455,974,947,457,703,41,131,347,805,401,567,856,54,755,662,447,105,573,195,103,791,251,670,553,128,836,314,236,641,111,716,160,882,460,941,861,910,888,236,706,675,937,924,18,816,550,572,592,355,16,765,429,764,845,465,777,675,327,914,736,573,347,540,31,20,588,84,20,284,219,326,535,637,405,398,954,560,734,658,943,994,415,197,498,498,884,958,952,718,580,56,812,966,583,839,401,337,468,482,86,598,625,856,259,569,746,576,320,140,729,731,726,169,390,633,889,555,801,673,48,316,54,169,261,688,119,617,214,579,301,797,438,321,725,724,806,538,314,225,157,214,420,620,567,869,209,965,209,146,620,839,260,99,367,371,697,291,197,219,657,971,386,551,737,129,691,273,825,51,792,460,611,98,955,514,617,122,325,104,259,436,540,716,723,963,503,295,924,254,144,208,558,535,426,302,599,96,747,109,125,812,495,180,570,27,563,410,248,885,507,450,285,242,97,473,649,23,385,808,274,926,436,108,853,357,391,81,998,85,998,260,688,496,312,495,945,432,552,729,404,227,208,76,237,318,356,89,375,334,882,326,243,786,950,494,884,343,384,431,200,259,683,666,857,662,941,667,980,24,805,904,564,507,850,54,982,36,313,286,247,31,269,795,88,158,912,592,355,486,715,569,550,479,944,448,427,592,796,365,982,882,555,173,482,791,536,196,799,853,19,119,540,289,315,745,460,963,268,365,9,42,731,644,270,551,152,179,830,956,29,758,575,57,83,237,719,188,931,223,708,86,583,582,541,484,288,377,516,938,263,567,943,598,49,638,913,41,352,431,279,963,450,267,372,416,323,777,280,625,746,185,782,966,910,582,616,838,363,18,713,167,978,714,47,243,521,488,441,577,266,209,458,719,854,522,165,244,36,137,423,414,607,430,467,721,61,744,879,544,559,205,727,694,644,340,136,420,459,189,817,962,697,106,975,687,818,140,316,529,553,495,502,991,682,980,926,994,187,215,3,317,54,564,296,801,98,201,826,564,555,546,287,383,844,650,939,27,756,636,926,639,174,12,865,963,767,353,552,196,130,627,633,431,151,506,833,673,754,139,847,885,383,313,55,677,922,908,534,115,69,641,685,111,752,959,865,479,323,445,752,390,329,855,290,327,447,693,397,867,438,763,123,428,396,793,5,134,130,951,894,224,306,855,939,47,913,804,909,899,316,498,759,844,217,652,42,518,531,79,93,13,256,161,463,466,208,35,456,932,340,171,141,248,248,249,66,91,53,664,418,523,182,600,405,791,996,707,802,58,592,149,950,164,605", "296,295,26,156,495,888,211,770,941,105,489,863,287,218,266,885,636,501,902,270,676,115,477,911,357,54,528,514,560,531,399,854,246,478,505,182,325,474,383,622,110,619,566,769,557,268,494,416,124,513,157,759,998,312,63,48,328,321,447,293,308,249,813,327,71,696,428,114,369,484,707,5,350,58,462,965,376,725,539,74,316,279,593,130,85,463,248,944,84,427,925,963,507,367,130,33,205,890,305,235,801,80,981,534,641,214,755,646,846,982,344,489,782,662,356,856,100,149,107,686,857,516,618,413,514,228,505,497,839,363,983,488,779,473,850,335,573,429,433,53,79,664,251,748,859,130,544,928,390,397,698,768,512,481,286,349,351,29,904,327,35,802,901,444,112,992,49,97,533,792,168,692,66,716,106,683,55,290,750,239,227,943,758,81,726,832,605,153,751,458,883,887,964,773,704,699,196,604,177,286,372,448,87,600,868,584,643,582,548,530,28,920,833,929,426,155,739,465,235,840,997,760,850,911,277,2,209,820,791,262,594,431,246,880,209,940,120,128,214,215,93,100,507,554,409,982,791,174,649,798,513,426,162,79,643,443,264,351,712,576,778,208,592,393,139,417,927,38,40,529,654,271,734,515,838,469,239,786,32,75,965,570,293,359,82,522,569,405,680,679,363,832,598,984,982,148,5,90,802,566,447,63,997,472,0,102,701,399,901,415,722,597,740,115,783,644,820,907,246,244,837,509,976,656,813,826,166,886,960,961,186,114,914,474,809,930,811,824,165,909,152,368,626,614,240,765,666,232,698,998,802,207,916,203,284,393,213,96,592,751,634,159,884,656,644,493,962,519,402,728,220,500,437,602,775,488,96,175,860,482,730,804,959,114,753,888,798,618,2,503,262,778,370,526,707,577,766,83,593,401,503,349,706,721,245,596,3,647,158,800,733,802,917,361,260,30,126,223,13,112,811,873,556,35,310,823,229,368,849,767,228,696,784,633,781,220,503,399,15,32,40,429,90,969,31,998,746,150,5,884,803,918,398,139,658,303,850,427,311,114,801,759,108,963,143,238,502,415,610,15,361,549,782,214,666,872,518,718,197,658,400,353,486,764,118,439,859,448,652,697,106,388,693,36,357,912,821,336,805,767,474,134,891,504,57,385,212,629,925,186,600,277,9,792,563,399,932,548,442,569,114,708,204,526,15,98,919,136,294,578,180,22,94,892,920,895,191,444,122,373,70,181,143,3,439,683,254,40,226,525,856,109,350,195,463,84,835,816,606,299,889,235,260,651,477,113,157,569,930,922,681,793,776,795,93,340,310,853,200,149,263,402,564,779,321,9,690,433,966,222,988,635,294,993,871,696,289,644,574,677,523,672,857,148,109,797,995,71,622,905,927,386,41,982,549,543,205,6,519,965,337,376,968,397,565,621,321,355,163,370,965,929,204,173,131,56,609,116,933,669,97,482,706,797,233,781,594,642,858,417,18,636,120,735,75,94,401,37,808,892,227,732,492,450,477,589,589,718,385,84,509,937,939,894,645,216,936,364,398,582,729,623,85,811,374,944,789,139,144,919,147,262,360,290,96,450,209,967,748,695,792,905,118,319,388,42,359,678,823,505,918,712,572,856,603,783,724,485,228,486,886,452,539,654,710,311,342,215,679,200,121,35,490,672,94,486,36,998,103,818,19,268,525,468,443,253,754,83,114,67,665,764,504,699,940,275,677,379,349,73,859,475,568,968,948,32,676,425,155,735,271,264,970,945,288,586,440,180,603,923,535,876,739,100,265,663,92,846,96,461,255,653,402,434,407,491,715,917,241,849,662,379,530,71,592,860,965,497,244,962,228,337,909,132,798,914,277,239,691,348,335,117,168,262,477,115,101,646,242,90,766,733,440,338,769,94,549,492,426,823,895,841,891,491,608,817,874,214,856,73,198,917,926,388,401,39,215,882,276,585,699,851,448,325,781,304,637,112,17,599,216,540,428,533,358,48,207,249,161,396,289,433,345,892,644,830,303,432,590,347,808,280,509,204,859,860,251,524,70,545,626,434,519,632,824,642,256,706,671,293,410,711,774,810,665,884,261,832,494,802,166,326,107,545,361,208,592,472,630,449,979,754,782,309,619,218,308,987,271,416,262,327,301,702,91,104,423,105,583,853,242,368,345,485,240,543,586,392,140,982,234,711,425,879,322,790,450,142,652,142,125,859,694,167,610,591,671,133,494,379,677,272,627,201,903,735,736,816,382,523,495,118,523,23,194,940,471,151,958,371", "706,719,492,576,653,903,751,252,910,113,240,479,795,173,452,624,214,682,773,36,153,378,411,973,37,839,914,288,550,951,997,144,23,411,640,716,573,696,202,71,270,796,979,320,465,150,199,651,989,495,384,347,567,865,19,914,90,206,638,507,116,989,145,336,772,715,846,466,95,331,698,19,85,942,798,842,302,686,540,680,28,540,165,486,411,710,163,848,647,135,814,362,923,695,233,173,124,856,406,650,131,733,22,205,291,379,571,763,402,867,310,690,319,132,993,193,428,760,518,395,792,481,347,697,32,668,286,719,288,875,784,793,656,47,764,459,229,27,53,946,370,963,374,131,668,996,214,421,198,429,347,927,865,111,67,581,172,35,209,506,521,23,209,35,26,657,269,330,546,434,258,427,382,643,979,917,511,688,197,39,617,846,825,270,622,720,126,172,318,993,25,132,12,787,135,66,822,149,722,524,597,243,680,541,861,337,375,69,277,352,895,557,473,439,32,883,924,260,258,235,133,556,8,41,475,438,57,281,32,390,708,795,851,48,683,262,415,300,665,282,122,525,556,44,794,133,714,691,402,643,264,319,149,381,465,862,540,388,164,640,756,175,859,307,259,967,466,151,850,237,277,478,943,179,419,721,735,572,432,326,87,753,231,510,824,985,41,462,245,874,329,158,860,923,693,46,608,915,624,881,824,986,410,499,102,0,738,375,923,236,179,81,93,615,259,183,938,69,101,558,759,559,936,728,18,327,660,683,21,315,349,483,321,229,248,213,265,126,895,638,967,962,326,216,594,663,575,302,416,947,883,653,526,768,551,343,896,859,919,642,574,355,131,52,886,278,280,516,741,446,407,107,83,589,845,635,796,173,248,292,747,609,289,217,498,743,536,986,401,219,510,463,192,134,96,130,911,447,726,41,342,63,396,78,874,60,145,255,265,483,114,576,764,140,837,682,62,466,613,538,403,865,786,439,237,948,674,27,55,817,655,54,252,946,8,945,183,829,245,567,440,583,475,695,676,655,963,964,631,92,385,156,571,8,632,541,712,744,394,251,834,714,663,758,803,754,985,297,118,478,165,781,738,596,250,300,448,58,824,478,135,92,44,85,269,539,192,457,159,428,891,790,252,389,11,278,703,253,32,948,915,13,998,162,327,695,536,468,907,542,923,612,742,705,294,211,672,523,252,295,9,313,418,273,891,862,141,8,463,835,518,404,472,963,573,10,764,627,921,993,486,796,411,336,610,946,832,690,750,68,43,229,632,634,17,886,646,461,64,981,260,131,347,591,824,904,913,370,120,255,278,935,260,546,727,602,544,510,623,942,569,462,350,442,162,875,853,930,771,106,349,369,958,851,844,622,658,411,180,690,395,256,436,428,925,29,612,175,391,432,881,614,88,700,210,459,560,309,641,591,45,522,145,570,306,280,476,767,536,263,491,976,803,166,269,815,174,882,8,858,458,146,188,994,300,531,244,979,976,17,657,65,457,825,150,652,500,698,94,849,238,743,662,244,623,917,457,750,734,289,528,855,238,58,459,731,732,790,952,444,101,626,715,965,48,522,342,219,248,140,509,528,417,68,185,976,795,662,439,810,350,257,407,748,712,481,87,452,304,335,938,413,819,359,752,440,710,67,574,237,746,771,531,267,468,111,870,679,210,527,36,715,868,867,404,664,173,547,647,767,633,113,638,307,380,321,544,908,847,232,625,102,470,43,334,994,710,821,674,521,774,43,402,64,974,192,421,192,630,639,490,567,756,978,326,87,486,742,421,907,35,155,760,846,23,891,617,798,596,390,746,485,815,83,602,777,151,687,20,707,896,294,339,710,699,197,565,352,889,322,219,190,228,851,744,973,811,959,229,113,854,311,377,802,235,882,717,369,296,48,579,823,165,393,68,159,17,931,535,570,11,289,127,846,604,138,940,65,632,391,740,382,247,958,923,8,412,423,716,381,570,791,139,776,508,951,554,353,497,382,351,243,461,796,320,554,428,511,789,267,573,921,415,954,733,34,558,545,997,905,224,181,130,838,470,822,27,778,344,949,674,204,192,953,495,780,837,278,450,630,779,469,816,30,41,167,116,237,962,917,355,718,721,236,950,540,563,766,645,672,716,778,463,566,780,483,105,765,197,169,635,183,683,521,87,153,105,866,202,802,528,928,208,990,378,395,266,829,940,592,148,896,257,634,329,375,295,336,616,701,26,182,639,123,258,310,658,834,385,96,494,770,894,934,766,97,718,550,125,42,827,636,306,211,716,566,119,557,983,403", "901,696,982,183,317,710,527,321,526,674,180,711,386,317,915,310,122,327,280,594,761,745,114,510,544,363,528,385,98,485,70,792,62,889,974,479,112,668,523,392,266,485,770,913,97,723,340,277,707,732,344,113,269,230,618,204,994,523,773,515,899,539,697,196,772,386,110,878,189,169,995,305,561,993,390,509,50,299,727,367,680,235,141,434,174,871,212,640,760,23,81,292,787,233,742,755,400,967,194,545,32,754,394,517,18,580,340,493,490,937,864,719,306,696,566,986,96,976,358,722,885,947,933,723,728,900,480,602,920,835,629,611,547,54,656,292,677,489,671,820,758,361,67,246,933,904,421,832,255,30,969,863,59,630,670,35,110,697,65,884,139,372,646,572,899,435,432,628,76,96,677,679,762,262,621,729,556,679,115,942,634,18,46,894,633,87,40,180,94,46,735,331,399,165,668,869,513,86,356,314,742,744,690,547,243,319,139,58,381,737,591,597,685,524,131,898,725,448,462,846,669,965,136,347,649,508,927,480,343,16,447,489,602,747,606,943,599,866,961,280,503,794,630,150,389,176,996,930,903,51,700,548,986,125,394,994,239,657,386,647,85,561,721,540,156,489,175,797,402,817,748,252,141,344,158,291,803,75,141,116,511,922,504,602,242,584,356,595,775,828,242,38,703,494,585,540,391,508,465,564,752,729,187,391,701,738,0,119,368,631,553,26,999,552,551,986,381,40,308,70,374,648,508,770,11,800,43,28,741,690,97,294,76,298,683,27,540,737,200,154,671,305,943,511,678,176,552,40,246,339,673,879,822,339,487,161,41,117,648,841,606,135,105,191,747,424,374,728,535,672,718,178,250,308,219,778,832,696,123,260,473,317,595,469,837,645,474,683,445,755,123,817,983,421,332,99,279,708,486,698,441,114,607,748,412,653,283,269,198,104,320,668,726,204,187,811,619,964,267,248,335,138,665,707,888,399,506,272,489,900,562,69,469,892,793,218,943,799,414,106,976,66,903,204,809,6,799,948,14,322,939,740,724,206,23,658,529,866,955,173,120,989,168,379,718,513,343,970,998,631,214,61,198,838,366,851,971,13,931,572,324,758,605,146,936,270,205,15,276,211,241,542,171,895,520,430,949,465,246,391,695,170,222,207,938,913,729,389,431,559,703,618,883,641,341,365,947,773,474,841,997,894,114,875,413,863,202,641,52,31,105,714,38,217,344,356,623,12,270,778,141,937,372,53,106,533,634,272,832,326,628,676,569,665,801,61,424,409,683,186,94,211,605,23,490,666,726,858,119,978,828,973,124,474,680,63,338,887,218,480,247,391,643,538,402,598,577,699,280,65,247,264,107,373,523,183,766,849,394,395,150,517,823,548,264,96,781,435,334,656,977,890,65,334,408,790,502,228,329,950,20,789,154,496,310,471,688,303,177,358,120,882,568,432,796,519,672,329,522,173,281,656,870,236,854,70,108,859,449,917,499,51,622,855,299,476,790,975,506,894,903,585,73,247,6,261,688,345,672,845,278,364,794,958,531,495,354,233,412,879,267,589,95,214,144,784,302,909,916,987,948,670,778,370,30,589,989,246,614,242,101,156,769,144,288,415,670,295,21,918,551,42,235,337,192,858,262,749,471,789,297,606,479,519,275,770,11,886,727,130,332,402,714,690,780,919,699,387,256,214,811,591,186,245,890,979,41,940,501,868,602,84,762,532,533,69,816,13,842,344,245,734,651,12,732,949,220,502,348,230,513,588,628,262,416,729,353,477,400,684,911,128,703,862,984,861,469,70,250,112,400,504,595,226,988,441,157,545,95,307,551,876,951,490,684,83,503,528,752,513,727,315,362,882,119,330,20,256,596,596,714,516,426,142,496,867,750,761,590,539,194,371,808,70,840,67,483,790,325,516,603,652,293,930,469,759,597,857,496,808,889,251,828,304,345,613,806,723,128,651,643,119,846,474,712,685,580,597,592,988,76,780,330,343,194,101,86,275,942,217,638,255,286,484,482,91,392,52,390,698,485,800,103,369,532,618,239,115,547,851,34,415,105,844,368,146,850,138,754,527,166,305,573,185,442,460,323,38,726,747,702,367,394,909,315,112,266,352,287,138,46,756,949,203,413,310,59,751,706,665,662,171,50,39,151,250,708,750,968,384,907,698,464,1,423,566,4,65,690,151,775,474,161,917,664,743,235,626,194,241,275,567,112,151,469,689,504,990,439,803,66,634,589,555,122,659,327,279,232,359,639,838,395,682,636,527,230,476,73,459", "155,381,336,930,90,205,769,126,70,566,719,522,817,512,822,512,674,862,489,595,224,98,314,612,56,554,334,399,240,362,813,410,104,774,360,279,511,278,946,939,415,291,351,80,680,928,31,53,840,614,338,144,485,646,833,127,87,773,337,683,527,997,458,464,607,271,584,897,709,650,47,406,272,481,156,344,454,791,64,3,824,287,631,692,645,519,815,471,33,251,500,164,250,562,834,13,57,575,2,168,577,20,963,288,715,703,758,313,13,589,137,177,838,822,556,317,338,14,796,550,858,220,275,676,4,55,181,462,536,326,318,173,929,945,778,507,652,545,12,60,376,713,877,351,631,571,212,223,774,834,770,673,791,869,614,455,906,771,949,38,890,357,856,460,158,695,80,617,507,689,28,199,111,567,843,63,584,388,272,925,106,779,783,732,737,104,249,426,258,420,62,176,150,535,39,645,131,634,31,181,373,292,482,780,838,96,370,620,565,404,12,271,779,486,108,733,961,315,488,750,379,950,506,814,456,882,827,608,128,89,644,348,510,164,616,107,338,76,746,584,573,353,297,66,137,954,485,840,6,654,523,621,337,892,125,734,447,284,462,124,7,925,267,171,691,860,877,903,11,331,512,448,2,391,172,546,412,463,315,412,457,487,135,861,948,14,858,746,96,972,52,801,193,390,550,811,121,479,12,920,509,841,398,991,399,375,119,0,141,781,492,839,969,794,339,867,539,664,225,562,517,166,138,469,874,42,851,286,351,272,517,152,891,403,484,770,508,297,101,286,719,33,773,113,672,712,101,819,32,338,797,445,563,496,294,873,648,115,190,628,871,659,635,340,631,324,225,828,935,889,325,472,979,15,209,817,750,220,62,304,696,33,497,664,404,105,699,683,783,18,926,282,420,434,943,45,609,518,92,531,81,338,522,768,276,959,181,877,830,96,804,87,74,990,100,844,480,147,18,438,431,528,380,533,284,296,120,916,629,378,595,745,839,297,483,886,887,150,214,30,571,973,57,34,312,305,192,246,772,550,231,13,703,244,466,125,183,88,577,338,973,45,103,181,726,908,435,309,72,502,513,851,863,38,964,776,131,18,495,985,837,326,580,223,553,203,669,993,377,849,382,800,833,595,235,908,437,13,671,114,533,96,411,983,697,54,238,187,479,824,76,9,101,902,920,346,425,239,30,160,215,704,160,825,686,190,398,676,503,708,378,852,532,59,811,856,302,549,589,575,586,426,762,79,120,724,276,997,302,886,918,494,470,891,196,508,396,241,695,637,652,684,469,632,692,341,67,866,283,666,70,381,295,936,24,217,919,627,925,607,120,128,67,431,230,581,195,698,93,123,315,270,281,328,749,358,823,330,272,392,272,821,316,932,417,700,747,642,955,672,346,457,363,541,607,916,351,260,464,472,129,573,48,737,352,876,893,854,154,876,189,653,610,867,991,995,158,897,453,480,851,491,590,990,302,443,501,284,125,866,624,201,829,342,284,988,123,774,813,458,787,434,430,489,73,350,645,297,910,296,552,736,771,992,712,760,583,758,463,841,258,484,485,278,642,41,172,324,956,428,283,840,617,286,851,426,69,566,671,291,350,966,463,39,976,817,435,76,617,469,775,584,851,164,92,269,344,367,628,917,186,831,700,279,753,506,51,119,299,540,45,380,422,545,376,81,186,52,88,705,615,296,866,789,895,253,677,784,9,989,122,231,996,145,290,905,827,676,592,409,977,900,244,508,529,306,521,394,70,957,641,817,179,946,549,575,11,841,830,336,625,501,905,372,593,240,227,743,296,891,22,534,888,637,408,736,211,156,492,206,642,662,123,494,382,501,772,670,907,401,452,268,141,643,623,749,799,211,71,145,918,420,220,253,513,507,917,45,307,924,197,636,623,511,127,894,548,501,919,180,419,764,951,162,961,959,254,623,721,554,535,185,543,66,950,678,831,485,628,617,303,947,534,268,889,806,151,591,705,728,414,153,691,448,584,169,716,871,501,70,870,351,295,718,804,998,700,38,14,104,709,15,711,762,307,882,640,92,70,775,388,336,113,364,663,259,981,582,597,244,753,378,220,64,646,959,50,868,985,202,950,861,764,381,305,70,602,481,442,150,314,393,699,369,608,252,183,430,403,994,642,38,558,73,35,207,231,924,743,669,109,808,752,513,184,182,298,886,723,683,223,223,456,938,830,955,244,206,214,15,706,198,934,487,306,894,566,480,44,75,688,62,611,847,425,24,973,858,621,956,660,512,989,742,192,333,832,401,654,394", "111,341,300,471,734,946,887,333,937,6,210,356,471,504,348,751,647,285,392,685,530,827,20,270,88,585,515,787,177,436,869,122,774,414,675,719,733,882,900,593,270,259,696,196,64,922,45,340,288,960,546,352,710,31,670,98,526,541,618,133,913,132,924,432,120,251,269,912,848,260,283,445,512,815,676,853,591,595,869,204,988,787,49,849,374,888,930,632,392,719,873,581,681,185,248,639,684,28,172,311,442,590,835,598,40,676,982,533,129,941,880,417,880,99,934,288,810,604,477,620,629,78,342,676,67,757,338,480,284,113,937,336,956,871,419,730,71,951,11,284,159,340,511,606,476,751,373,871,105,865,220,621,229,681,86,518,992,36,340,976,978,278,822,506,173,957,496,462,899,542,884,521,532,991,464,284,542,573,280,14,409,105,675,130,107,150,399,338,870,936,888,229,688,734,662,411,846,252,480,904,66,440,955,391,225,877,953,140,181,805,379,330,468,366,771,613,302,694,532,876,138,196,912,272,599,137,665,407,215,916,959,818,542,982,380,804,781,644,414,966,90,151,189,178,222,77,300,710,28,891,252,863,379,531,951,139,252,503,262,23,700,908,21,105,300,379,953,24,727,426,265,35,219,891,32,869,556,2,44,849,31,479,24,388,425,556,476,767,820,58,854,512,915,255,283,728,882,351,665,378,244,909,749,89,901,923,368,141,0,390,426,727,617,300,854,470,2,212,939,415,752,436,104,922,247,582,785,229,418,724,985,942,441,433,232,461,763,165,534,813,632,536,791,510,478,944,179,656,102,117,520,875,248,355,439,772,830,96,630,258,459,784,803,164,935,148,624,669,234,77,621,958,159,110,941,167,963,961,911,484,605,484,901,924,703,458,806,16,616,263,788,739,353,964,939,555,140,300,450,487,534,154,536,280,929,476,761,205,798,513,849,674,402,384,897,754,795,556,965,952,161,945,120,460,374,364,612,318,268,949,957,506,82,60,889,650,558,92,403,235,556,777,97,346,23,414,687,697,27,872,89,420,267,92,113,473,824,134,833,746,927,653,971,368,439,471,965,792,227,914,82,299,56,589,265,221,296,684,778,438,15,23,42,149,552,681,689,947,15,522,30,738,470,993,795,194,869,464,87,41,869,671,779,898,135,277,375,979,410,42,155,970,756,707,656,667,919,776,755,877,336,309,568,575,574,644,894,659,227,775,576,448,78,121,920,247,374,868,843,329,844,706,263,53,494,425,731,938,281,631,291,623,776,330,311,47,123,648,385,654,132,180,353,856,824,972,6,814,682,547,862,308,997,388,518,427,866,127,936,18,477,818,795,233,951,461,359,564,755,889,599,153,388,544,282,374,861,405,147,66,799,646,20,800,50,507,758,717,854,612,226,236,158,34,749,506,196,75,391,232,550,291,867,393,159,292,276,131,521,711,336,334,14,856,33,500,201,748,198,252,499,446,250,231,689,952,903,773,590,71,467,268,937,584,472,641,618,991,931,273,312,471,953,874,859,501,125,447,716,244,519,377,433,881,729,211,61,83,971,376,622,126,841,714,156,498,266,931,934,423,180,30,214,671,993,902,14,805,215,651,672,499,436,386,150,107,510,456,923,51,177,731,466,330,744,282,586,223,831,420,37,253,426,202,449,376,434,773,814,806,698,891,857,646,233,203,854,372,431,224,107,306,634,988,505,239,155,720,944,670,602,961,81,663,243,231,668,753,758,905,406,855,953,155,508,202,276,680,120,241,993,142,142,614,779,201,607,792,857,682,720,262,293,244,424,82,460,952,695,161,54,702,87,370,143,773,754,223,511,306,815,100,467,267,77,25,882,459,266,919,230,236,841,259,323,964,978,876,622,824,400,483,337,859,475,591,482,273,179,126,812,596,390,49,939,76,365,500,126,612,643,425,950,971,743,301,602,921,154,836,160,881,558,85,903,693,820,873,743,202,4,637,270,711,275,165,720,126,67,763,719,45,55,473,650,957,639,592,391,961,266,333,937,808,887,558,574,821,162,880,800,900,345,377,190,353,928,137,264,290,416,688,308,939,89,198,134,975,845,611,938,207,507,864,317,362,241,41,746,239,33,250,737,121,465,707,158,725,58,891,50,786,935,540,386,763,669,406,598,695,933,959,72,969,315,154,224,562,431,455,876,49,169,136,965,966,79,352,775,142,744,441,514,725,446,891,898,2,938,180,388,86,616,440,597,124,854,188,419,689,510,42,893,491,675,861,227,468,962,327,874,141,586,648,354,274,282,590,40,33", "286,877,246,667,473,117,873,939,608,540,32,627,779,111,437,453,684,694,547,321,997,996,261,278,44,238,753,179,362,356,680,247,893,81,998,751,10,662,583,889,204,26,292,642,837,333,592,217,104,988,89,842,695,693,438,994,926,787,978,148,524,264,968,952,398,17,921,932,449,45,537,10,580,98,700,222,462,897,104,815,437,215,311,42,733,260,396,228,359,185,549,39,177,307,85,288,175,829,652,983,960,790,896,466,86,685,110,746,785,592,19,559,167,839,789,581,659,75,111,130,318,619,840,169,3,881,469,714,107,855,976,380,902,710,899,900,309,828,964,301,662,516,718,520,672,897,876,860,182,54,18,58,724,17,986,606,202,171,500,379,575,510,601,931,787,585,246,131,707,392,716,348,609,810,276,586,482,382,818,481,651,307,334,589,91,52,153,634,726,382,239,973,55,777,815,991,482,221,390,546,911,774,588,156,776,45,30,153,646,153,361,838,59,716,539,11,800,798,697,40,723,354,154,255,53,404,447,453,502,173,688,598,458,500,600,725,153,440,8,775,236,666,504,441,897,392,25,713,862,325,394,131,569,17,343,150,946,968,672,784,511,621,185,967,266,867,450,342,452,814,575,525,626,795,673,317,237,251,38,221,800,146,781,359,98,42,813,903,218,932,535,359,370,783,824,468,832,502,698,444,895,289,258,178,415,236,631,781,390,0,510,942,943,423,831,497,685,990,639,286,372,378,181,176,608,949,452,234,668,613,988,226,213,474,843,93,1000,333,862,174,392,674,783,539,896,961,110,9,908,959,714,128,531,844,214,589,948,320,755,246,811,836,938,633,95,187,808,570,832,393,527,310,908,747,718,142,406,813,283,877,7,331,644,362,110,69,727,611,906,161,471,973,361,252,329,163,23,365,594,724,389,525,448,539,144,926,518,159,581,449,451,71,220,915,544,950,510,809,404,250,279,281,849,931,705,575,923,746,178,879,72,441,240,28,276,10,155,670,102,936,880,530,17,977,875,675,716,228,518,990,744,92,875,852,930,541,125,407,486,459,478,939,15,407,40,797,426,555,29,699,924,239,295,601,236,255,896,494,711,955,578,355,189,58,372,612,662,3,866,664,421,373,490,517,149,689,708,321,943,356,253,235,745,335,39,214,297,323,590,474,18,747,206,758,335,678,233,388,373,102,690,826,840,801,438,817,803,701,405,602,582,498,629,572,31,665,110,716,560,897,938,355,19,342,500,824,418,789,625,473,430,564,121,214,99,875,785,436,687,663,722,843,689,906,428,827,753,848,325,252,942,576,342,299,871,528,306,947,835,623,862,230,136,172,718,541,935,499,37,956,31,327,812,430,778,372,418,845,176,32,800,45,998,27,294,326,847,357,859,621,794,922,832,188,754,594,654,51,272,413,834,31,67,110,541,854,964,998,115,69,712,976,287,630,712,710,93,535,307,952,3,54,171,17,381,319,613,340,473,952,703,926,820,345,832,482,399,191,883,487,15,788,932,227,559,609,51,812,942,756,740,850,633,695,505,388,606,147,537,769,246,803,134,749,250,914,612,723,569,394,446,132,668,180,833,512,947,413,438,449,354,372,672,3,379,144,357,953,859,625,163,81,637,918,587,819,377,221,356,237,139,765,240,870,403,363,616,463,975,183,183,244,624,856,542,253,709,639,420,487,321,975,149,878,79,260,592,938,334,291,80,942,831,845,66,668,792,239,97,511,742,919,358,719,135,621,404,464,966,400,260,316,316,395,819,594,223,902,546,712,604,522,817,856,79,135,134,929,109,864,291,645,603,742,493,135,242,925,530,214,800,148,465,926,268,622,296,160,302,221,191,597,629,796,120,210,166,437,765,865,983,704,902,67,257,777,593,148,703,164,19,168,733,410,72,244,762,41,126,355,226,493,734,255,944,981,500,762,955,102,134,231,16,677,434,826,171,896,13,330,861,464,85,54,43,581,926,609,250,348,941,358,647,820,812,836,987,84,425,768,617,423,220,923,808,454,799,404,16,813,793,903,564,852,269,276,129,708,99,857,776,647,555,914,952,560,723,171,292,323,170,204,292,941,524,529,943,371,60,575,729,640,617,260,503,181,888,868,777,15,458,996,23,498,137,44,407,305,285,576,791,358,443,184,644,746,508,438,669,391,724,908,579,635,430,284,76,202,904,515,617,782,819,880,248,458,945,774,607,545,46,64,58,662,344,879,407,97,907,332,594,600,838,699,248,932,217,658,113,412,130,211,273,392,132,715,398,59,998,763", "958,30,275,564,599,457,704,937,253,134,484,729,151,840,343,873,625,497,349,732,694,101,561,646,165,769,812,611,209,513,408,91,180,225,396,548,496,475,17,826,496,106,589,796,758,41,92,862,737,185,683,711,538,581,373,660,138,970,964,497,25,515,331,556,765,29,470,636,462,91,481,627,777,458,949,57,659,709,681,210,568,727,508,498,97,158,347,48,942,840,935,207,108,540,888,437,778,361,393,113,606,177,738,522,664,534,414,740,386,143,84,349,906,477,562,122,61,581,98,726,488,226,544,940,743,419,738,767,757,840,449,542,420,518,378,955,693,726,295,138,248,459,182,200,470,790,181,620,458,143,509,910,151,992,545,626,689,264,59,57,766,576,123,318,801,513,659,247,906,653,157,503,535,739,938,427,568,465,504,129,150,298,494,482,783,750,80,460,394,785,238,894,412,362,248,99,435,491,217,911,440,545,918,503,957,659,924,456,843,404,5,432,880,895,125,838,617,961,654,336,865,939,574,678,805,35,152,165,950,1000,294,175,915,154,235,639,469,693,367,235,674,799,200,273,434,41,429,186,174,114,495,682,866,338,892,971,244,436,930,552,524,898,557,601,352,169,589,368,694,161,546,898,68,614,431,185,391,755,418,584,904,241,12,771,791,732,651,553,224,261,110,156,420,345,803,478,914,463,838,231,107,701,461,705,722,179,553,492,426,510,0,453,351,569,885,519,963,699,557,835,349,46,943,649,390,379,897,926,380,271,30,753,445,823,111,130,880,668,720,830,843,267,775,933,564,583,30,96,291,463,311,750,698,334,907,218,216,292,447,564,688,116,750,965,385,153,817,383,557,132,363,985,684,982,637,302,462,597,876,434,32,991,316,506,271,465,712,356,197,477,166,310,918,465,162,153,32,937,406,8,339,865,530,389,462,583,572,811,804,594,309,696,620,768,433,11,899,343,998,803,150,477,827,429,892,986,155,279,941,712,569,595,77,216,496,650,436,436,408,62,337,580,621,693,927,320,534,165,215,988,697,607,610,328,64,744,540,574,701,364,536,688,359,201,252,172,787,499,284,601,64,128,918,283,478,677,345,223,740,846,975,113,821,91,755,929,581,418,387,504,963,315,815,152,534,849,877,98,279,432,200,496,387,143,655,835,957,522,84,776,892,724,307,661,704,545,511,650,344,914,254,577,590,89,408,282,238,643,24,945,543,904,668,898,262,777,542,665,12,665,82,506,768,119,668,242,283,854,618,148,488,884,105,13,842,950,100,437,231,586,786,524,417,276,864,737,913,989,468,944,30,253,823,988,614,56,792,264,806,677,559,812,261,990,687,920,551,189,265,856,206,541,635,86,144,553,327,306,719,636,503,701,561,631,327,445,839,508,454,842,880,949,529,918,867,82,723,18,937,891,745,600,147,457,675,926,906,393,131,126,98,766,312,174,736,166,276,994,430,607,985,805,228,51,702,98,630,312,905,393,78,719,344,874,732,90,208,32,175,55,324,820,586,954,419,787,54,916,202,73,127,66,924,862,517,493,158,196,680,127,883,947,870,724,418,145,215,732,663,969,671,264,399,245,394,664,861,598,249,351,37,40,423,74,931,432,451,263,595,323,869,35,876,588,957,490,146,612,950,440,852,795,831,851,683,831,476,370,254,110,25,170,709,44,881,639,660,259,834,359,818,487,188,440,338,157,882,601,331,805,136,530,185,844,287,629,254,572,753,818,391,404,768,735,959,991,985,712,949,348,551,960,934,606,539,199,175,495,240,238,31,755,222,156,734,71,671,572,758,169,203,59,72,627,335,74,561,176,366,716,122,318,900,138,756,815,925,925,86,447,747,503,161,551,802,525,148,532,461,309,741,90,323,497,232,133,910,349,653,179,702,599,831,120,283,367,643,732,468,866,791,164,259,810,968,730,368,357,542,48,660,345,604,376,711,149,767,895,378,107,90,562,678,21,284,626,147,105,688,618,726,548,289,455,967,722,776,667,387,449,678,538,771,988,459,672,70,64,893,672,123,951,29,888,475,521,787,316,654,735,350,910,289,210,987,597,555,952,256,732,222,122,316,244,288,208,366,901,416,462,266,584,573,548,126,161,341,344,853,946,265,597,135,730,723,101,922,396,782,551,639,541,337,161,520,572,318,562,467,132,432,424,556,501,676,172,843,558,322,902,358,62,821,153,484,783,27,701,746,881,88,426,436,52,355,201,244,619,45,987,421,766,766,887,943,510,423,935,40,125,114,413,572,393,922,350,315,566,362,856", "119,213,61,731,566,713,803,281,730,164,403,668,867,105,172,930,398,177,574,387,957,984,903,26,120,424,684,258,682,420,454,289,808,473,516,869,403,123,492,197,995,53,104,247,33,687,899,466,945,3,42,150,491,551,333,434,291,271,502,599,965,605,872,129,82,186,125,416,320,391,568,405,872,183,925,532,507,397,56,736,863,891,879,667,539,958,59,348,790,691,792,791,556,938,488,617,288,173,464,762,521,484,36,894,180,632,672,338,75,896,501,708,25,408,540,866,423,200,790,415,706,56,425,549,103,422,145,135,582,692,649,147,852,867,261,175,727,568,529,579,261,234,742,174,419,86,375,297,729,523,992,355,163,233,730,288,19,176,678,237,436,224,998,931,486,94,449,576,447,774,716,243,741,339,632,517,139,118,522,914,87,408,983,931,236,609,382,42,988,392,662,110,511,290,541,236,813,892,440,595,383,105,444,721,187,647,818,824,906,845,166,808,584,723,817,205,448,285,145,133,92,727,639,770,33,264,760,601,960,786,968,280,847,760,586,643,332,426,118,178,760,402,881,120,442,921,573,194,544,242,329,880,64,983,872,591,4,87,491,776,407,796,823,579,959,778,853,669,555,795,784,403,742,881,742,788,768,347,824,442,883,785,84,297,73,340,145,306,772,779,875,560,448,130,709,619,644,969,123,278,172,254,552,133,597,81,26,839,727,942,453,0,20,954,247,461,592,249,274,172,48,727,302,779,164,991,886,847,488,510,398,945,581,712,136,700,127,533,983,884,408,739,231,102,677,911,557,906,321,701,332,968,78,675,598,354,569,911,994,403,846,871,187,42,806,895,843,678,329,759,23,30,347,38,675,769,183,434,420,198,773,842,245,88,286,825,193,602,477,371,180,795,206,78,664,377,23,965,192,713,710,178,717,673,433,713,772,509,112,701,352,300,551,976,868,768,364,52,813,116,231,155,776,19,92,414,713,89,406,11,391,413,955,331,625,883,230,15,431,663,953,648,8,141,471,971,864,515,13,482,914,666,364,714,750,149,526,392,281,657,52,344,343,108,938,567,694,451,344,992,873,81,80,496,407,407,740,361,236,14,454,64,562,860,704,511,148,231,592,703,996,899,100,621,427,760,892,304,834,416,809,462,50,774,32,563,576,525,641,464,250,516,477,796,477,581,184,852,767,657,515,745,871,786,918,631,91,990,760,395,374,637,427,659,587,586,897,673,406,299,497,497,666,938,168,364,668,958,230,557,101,277,282,482,833,905,881,674,59,2,233,742,694,452,388,376,613,111,2,544,886,256,539,827,951,489,470,216,553,652,190,396,84,712,973,323,103,37,922,754,378,867,570,804,864,959,81,421,391,161,132,520,263,408,805,86,723,706,371,250,192,237,939,951,810,187,453,463,119,637,494,945,425,382,940,635,907,231,829,892,344,214,523,588,939,36,966,745,275,694,691,171,612,410,839,958,410,821,969,501,93,610,252,790,486,871,336,498,492,714,172,654,276,169,346,87,594,541,50,560,594,973,27,421,519,27,817,582,544,511,122,142,953,483,735,353,658,635,165,4,830,819,593,796,395,716,632,195,898,151,892,717,833,543,102,442,861,852,140,282,878,266,82,522,148,236,564,458,514,331,995,500,297,504,917,792,648,83,380,409,948,621,293,766,912,548,533,646,150,347,847,836,110,599,567,769,363,240,391,626,44,728,151,675,867,538,792,624,270,153,102,738,826,332,43,732,690,375,762,322,605,59,42,41,477,170,122,468,339,374,233,39,962,956,125,813,919,976,842,74,465,501,487,884,692,367,87,717,550,698,968,862,176,353,921,537,957,442,800,445,86,42,353,14,837,771,66,1,538,875,467,530,571,850,733,316,96,65,867,266,415,338,117,397,213,640,626,397,671,613,671,177,3,313,155,331,50,192,602,485,958,551,950,357,926,327,438,392,512,54,97,103,748,941,867,764,616,762,842,721,76,552,432,989,115,264,493,549,894,457,39,584,89,778,859,377,852,388,954,231,678,624,580,974,994,117,471,5,462,34,805,266,576,441,766,428,171,450,90,764,386,296,627,292,202,851,514,388,636,990,996,686,2,421,760,343,740,907,563,510,431,835,641,771,697,113,493,393,26,374,354,700,997,20,529,813,458,834,842,783,905,131,395,136,882,956,14,988,255,101,390,550,322,592,201,642,692,880,721,893,871,275,385,903,676,37,504,792,724,146,307,997,905,536,168,681,961,349,838,15,536,485,210,319,250,770,626,446,979,793", "652,227,888,900,508,368,864,864,227,106,29,458,632,424,388,748,34,359,739,601,661,715,27,391,204,271,275,481,305,285,58,824,96,947,118,911,661,326,511,89,427,289,136,176,396,161,330,497,843,105,419,807,205,52,956,844,477,770,947,688,164,741,174,199,590,249,203,568,316,308,487,845,283,925,480,135,283,704,2,229,78,508,165,976,29,889,120,480,42,686,134,741,606,945,615,459,264,410,64,335,723,64,247,522,791,39,306,321,798,37,664,540,76,58,336,919,711,268,72,469,426,693,687,907,268,789,356,596,115,2,605,33,337,568,335,957,947,208,116,347,17,852,829,877,211,760,992,285,747,368,515,323,991,763,268,740,478,986,762,387,642,72,107,471,675,14,450,457,638,292,350,936,602,773,906,606,371,445,113,139,193,710,409,431,166,122,667,151,572,594,713,897,431,273,523,327,212,343,682,640,434,406,863,15,844,157,4,95,475,341,361,131,369,162,484,580,636,594,117,921,559,118,430,851,937,473,341,295,325,5,204,709,692,85,220,801,868,744,539,676,475,328,442,452,257,273,505,759,188,285,976,516,670,423,849,457,269,76,774,344,338,635,969,28,507,116,508,318,232,293,568,368,370,134,20,278,296,938,875,510,673,522,401,131,425,627,210,499,101,297,92,97,246,514,2,244,684,774,36,924,516,764,402,736,740,93,999,969,617,943,351,20,0,543,863,474,565,995,723,895,128,736,985,430,396,89,58,574,858,134,497,309,400,214,814,309,751,103,441,361,23,692,502,252,148,631,851,106,969,400,888,275,753,106,165,437,304,141,874,979,45,664,137,999,73,528,866,802,82,424,225,152,256,193,404,805,828,876,475,418,187,978,766,859,78,133,394,726,838,800,19,103,729,538,523,574,538,286,72,12,190,569,506,68,974,189,182,320,527,395,151,680,50,374,233,419,298,610,8,989,31,574,670,770,237,233,492,926,61,21,467,943,923,602,996,525,904,912,7,899,916,920,658,75,587,151,286,317,488,727,950,81,144,990,788,464,913,740,25,716,551,943,886,868,839,89,567,603,253,4,71,293,845,245,261,938,620,809,204,491,878,874,460,500,761,283,106,632,999,212,414,306,308,777,437,393,200,719,618,369,724,247,126,36,210,325,404,897,309,690,22,836,849,149,901,266,355,819,540,121,862,279,777,619,303,619,853,630,867,499,565,806,803,329,211,659,547,505,898,437,445,635,66,764,400,647,574,910,665,426,73,742,957,102,23,808,830,955,732,678,144,797,523,988,543,920,282,401,652,123,747,981,896,117,643,242,857,173,274,167,392,142,89,556,596,993,302,573,347,582,682,895,273,517,449,183,10,856,458,159,678,598,597,347,606,732,947,395,685,446,296,4,88,35,639,10,654,726,805,893,908,430,325,125,259,400,620,570,316,267,260,511,228,674,527,213,816,366,645,157,57,182,385,246,384,664,562,151,16,631,6,244,138,461,45,740,955,963,4,755,863,979,160,390,256,479,395,631,888,984,812,927,494,354,540,565,197,244,959,409,119,704,80,552,24,537,809,736,545,690,110,305,244,125,526,643,384,305,810,917,920,275,543,916,251,817,479,239,68,823,776,980,445,834,182,392,395,318,192,798,207,966,43,256,609,936,63,142,287,284,264,793,861,382,925,185,530,587,956,644,177,195,537,324,940,391,590,425,996,385,502,620,449,695,811,22,32,152,535,861,211,377,707,736,307,89,647,541,625,230,463,603,78,844,337,414,743,546,565,332,810,310,95,822,674,666,235,364,594,353,135,827,427,26,895,150,124,281,17,823,708,716,507,82,89,54,869,292,300,979,53,379,844,996,823,421,508,148,707,682,797,117,568,758,44,668,675,609,940,749,319,248,462,509,815,20,121,78,733,456,816,853,783,273,878,264,909,539,689,650,164,925,468,973,571,236,866,103,497,295,493,131,414,204,145,578,940,298,750,245,266,954,345,407,349,799,342,787,259,89,703,218,169,654,555,187,338,1,969,160,612,954,742,656,636,355,559,988,802,330,895,826,278,557,150,994,427,775,500,883,326,481,521,715,484,297,607,560,598,736,929,166,444,208,562,653,435,862,807,620,782,792,816,178,266,968,118,451,360,913,823,753,809,741,214,207,728,263,404,456,38,126,456,488,343,935,14,479,793,506,902,516,873,775,806,307,392,289,581,987,498,887,111,695,846,616,192,135,29,540,312,460,444,28,173,518,553,850,107,310,257,724,266,896,319,206,913,489,690,356", "2,394,197,938,383,959,296,383,983,200,679,74,514,424,94,432,74,192,42,750,446,456,65,83,315,195,526,368,461,890,481,921,395,316,918,886,223,151,500,746,357,585,10,21,551,336,962,470,605,677,100,959,325,865,3,58,280,530,143,950,702,578,330,137,170,642,849,702,314,832,576,306,699,925,786,835,367,608,126,623,226,995,616,764,994,686,121,585,640,693,336,308,218,32,305,642,985,114,437,388,958,643,387,731,361,630,219,57,285,520,735,19,533,868,91,315,96,586,138,371,29,555,958,416,132,408,438,23,661,844,110,417,793,519,396,255,249,777,253,302,228,112,188,617,191,476,549,652,661,26,688,246,685,752,881,156,702,555,949,310,193,421,413,806,807,70,904,460,12,527,708,572,635,980,266,303,729,786,359,262,961,790,498,661,632,474,749,240,510,129,586,171,574,102,541,251,640,453,114,853,147,205,315,607,572,254,947,756,709,357,495,152,413,608,355,828,964,486,68,440,589,616,794,396,314,126,926,748,61,898,950,353,418,780,492,130,133,34,213,478,486,8,456,879,160,819,506,707,498,189,489,261,75,382,653,43,760,651,604,505,614,42,669,22,132,894,111,933,875,631,840,693,596,752,978,239,343,31,127,994,713,130,262,804,350,258,653,574,59,18,363,292,259,946,165,596,697,426,158,950,83,458,134,771,115,615,552,794,300,423,569,954,543,0,580,493,677,539,299,221,438,80,976,361,764,518,842,335,915,248,631,832,956,479,335,436,705,578,459,830,211,937,759,689,487,910,526,240,370,164,738,136,908,140,181,481,28,272,420,309,158,131,808,652,144,935,518,870,181,636,471,364,637,241,846,811,725,244,165,604,118,470,127,185,686,29,49,833,948,839,888,633,669,886,858,449,959,941,12,204,804,493,768,565,315,818,135,496,724,27,635,342,797,562,641,951,352,544,748,24,902,343,85,82,382,529,356,179,206,947,208,421,490,494,160,740,308,392,966,347,605,436,373,649,179,510,620,116,925,720,418,758,349,592,13,528,903,203,297,37,686,837,482,92,370,918,365,163,739,949,258,74,384,312,637,940,336,27,263,750,100,738,964,271,267,445,501,870,480,251,772,53,803,745,893,297,50,139,13,424,322,924,742,992,75,988,918,2,284,819,564,218,473,40,772,941,778,996,360,993,606,191,666,376,729,230,72,8,698,578,329,528,268,466,24,541,185,329,30,372,603,218,888,750,534,740,337,840,370,225,701,365,932,638,167,84,594,225,991,275,513,917,413,80,680,365,757,424,374,153,528,587,760,282,964,689,522,242,103,514,989,109,74,591,365,758,636,396,118,470,613,83,302,915,812,37,789,457,330,234,715,456,961,549,750,513,482,895,301,655,555,847,272,872,726,45,781,384,896,556,30,540,143,940,357,79,107,147,859,599,599,941,643,50,885,167,370,467,100,6,882,247,637,623,282,1,920,93,879,9,949,116,603,120,840,747,615,220,4,762,818,53,334,949,736,166,528,113,138,834,61,397,371,321,297,647,880,989,196,298,419,474,582,749,739,423,382,971,295,176,827,33,923,596,609,834,366,356,757,957,391,641,332,202,986,692,59,259,790,858,115,719,242,530,280,97,495,639,726,843,721,726,534,225,724,988,61,715,554,940,778,423,781,817,283,190,751,164,36,485,260,461,798,898,902,703,806,957,854,679,84,625,103,584,138,609,648,244,837,645,802,123,412,800,483,371,19,694,35,583,142,224,448,449,26,62,423,273,812,959,805,962,713,155,786,151,369,855,200,935,408,154,566,970,32,672,244,418,599,24,23,90,675,384,387,605,771,492,394,348,457,613,122,422,101,115,403,431,815,787,859,380,560,567,773,80,574,873,934,595,619,533,556,983,960,721,114,991,811,835,687,745,636,506,714,444,67,901,772,358,108,462,452,448,886,320,305,929,911,5,810,708,100,848,81,330,697,387,182,126,677,667,686,258,345,387,973,560,740,347,984,872,174,930,510,909,657,902,648,283,628,625,108,353,368,880,9,571,925,597,884,511,462,718,413,269,988,227,226,753,900,662,793,951,283,107,690,710,724,196,946,705,518,824,142,953,44,9,276,442,861,65,456,749,527,261,332,977,585,422,866,623,649,701,14,211,713,182,566,464,885,264,429,20,782,855,869,977,99,351,275,990,480,675,536,113,622,794,567,378,981,364,257,747,494,296,9,122,245,649,41,792,243,430,172,246,278,835,301,462,305,451,924,48,590,162,964,327,970,481", "140,332,978,249,727,930,609,720,527,639,450,245,667,340,319,905,248,336,738,10,218,974,751,194,881,687,677,756,495,268,810,579,261,587,546,72,363,595,413,125,598,811,843,446,218,672,889,178,352,718,854,53,151,224,138,744,796,225,526,561,362,213,485,555,650,241,406,174,881,223,224,767,514,842,599,343,985,417,513,444,307,979,651,383,702,239,57,418,622,504,207,144,945,201,464,234,361,917,338,905,416,923,784,510,933,715,881,470,588,683,449,15,671,750,56,528,190,62,600,934,105,570,804,567,714,344,267,109,638,299,869,886,271,457,984,462,652,230,707,500,345,755,41,794,755,956,844,817,990,31,372,368,826,8,195,624,616,402,876,721,356,18,453,317,783,119,402,229,812,10,539,432,866,150,422,106,29,108,26,260,138,247,983,930,28,983,841,228,106,708,134,801,873,563,366,508,85,143,882,825,698,685,925,916,859,558,286,233,251,599,640,647,695,605,182,773,898,943,365,766,248,652,395,774,741,37,460,479,285,538,685,776,968,216,56,729,355,829,296,607,965,931,328,362,511,653,733,124,237,449,990,881,296,102,447,560,341,10,150,522,626,194,97,999,815,114,901,897,649,702,693,515,528,849,258,692,994,187,192,133,490,773,487,981,435,264,517,251,726,586,679,568,148,524,529,662,635,927,188,197,480,471,413,588,783,259,551,339,854,831,885,247,863,580,0,30,452,26,312,660,224,41,760,299,388,299,928,759,932,716,683,398,744,687,964,942,857,772,151,227,407,685,702,296,451,971,364,417,657,356,502,852,313,711,293,105,510,344,391,27,51,691,3,231,44,798,891,293,677,445,691,137,166,269,388,355,503,866,373,383,303,175,851,368,470,462,803,684,186,578,433,419,200,697,892,967,495,464,183,473,418,647,945,761,66,459,470,688,219,532,131,802,3,810,769,414,325,165,603,787,346,325,458,228,425,896,498,812,450,216,17,574,539,963,850,109,872,495,39,222,654,427,993,39,478,900,472,207,135,796,639,492,190,449,574,525,345,271,666,904,67,641,950,943,92,483,32,976,784,423,881,763,237,142,640,119,304,108,898,557,540,107,386,879,948,549,18,417,701,128,739,181,965,561,620,61,905,949,47,866,294,124,905,700,763,994,45,124,941,41,462,878,373,333,226,524,919,506,865,344,711,106,841,181,800,706,658,670,611,515,823,669,679,600,778,203,725,469,158,160,438,585,716,376,77,280,991,365,986,569,101,950,106,950,93,915,116,405,492,307,30,924,779,166,921,231,483,811,313,259,225,939,346,140,750,356,479,693,30,82,49,625,818,652,70,833,701,675,632,532,527,987,898,341,99,19,224,173,900,602,500,911,723,24,99,64,772,609,327,576,399,385,934,220,236,312,41,171,513,690,435,454,865,118,371,262,203,371,844,753,827,873,595,335,60,478,463,221,140,39,688,223,249,196,546,229,606,739,149,600,760,120,873,731,868,50,59,910,320,944,925,205,33,523,877,808,412,680,4,721,92,714,802,830,975,787,76,950,471,610,355,306,353,670,483,341,252,814,220,430,660,592,365,942,391,13,749,150,352,392,291,436,277,722,812,433,894,923,150,834,482,218,517,266,983,917,37,820,878,513,810,783,371,803,615,415,532,740,281,475,36,82,962,594,759,71,87,924,346,793,486,878,364,334,848,199,283,877,543,192,608,853,700,506,51,457,468,57,544,685,780,750,215,93,41,256,812,538,607,906,274,509,836,396,486,870,427,200,889,633,489,106,52,909,913,272,574,888,440,872,524,696,183,253,365,867,40,923,35,314,933,218,200,644,405,445,976,201,670,382,469,352,379,276,376,408,880,442,482,136,437,577,849,872,973,315,837,856,495,309,895,100,691,825,299,557,593,379,767,727,208,99,7,2,706,252,915,583,105,987,33,872,810,971,234,684,488,985,157,37,926,748,396,809,306,762,435,62,734,658,245,478,433,99,773,708,958,933,458,372,179,786,856,236,166,437,849,856,633,146,815,136,606,102,614,721,628,497,902,635,814,972,816,178,158,974,63,949,588,434,76,329,349,193,879,763,143,851,409,792,241,248,285,359,573,113,514,174,653,83,776,125,998,518,966,921,587,747,468,634,112,687,180,730,298,570,355,55,279,875,141,618,906,597,926,14,110,782,758,316,566,84,103,94,545,847,589,1000,451,382,953,886,960,176,995,939,166,357,677,991,605,470,736,862,621,45,449,735,680,405,76,637,170,526,4,495,633,386,857,16", "248,421,191,300,957,361,396,204,889,839,658,311,356,847,56,132,555,568,126,410,143,452,393,310,333,854,279,381,921,947,735,532,602,191,511,497,519,620,983,365,855,219,833,610,715,688,10,612,239,699,202,426,542,114,644,620,947,1000,805,194,778,675,403,499,441,320,957,640,675,96,881,994,269,695,728,678,137,521,728,63,516,444,402,521,879,368,561,768,99,387,865,157,961,482,486,434,692,555,413,746,706,401,684,855,700,103,150,583,389,474,523,978,487,12,661,759,964,274,645,695,273,673,182,207,554,328,811,255,924,640,369,997,289,532,143,303,654,113,683,237,502,157,650,548,111,141,361,194,606,568,103,774,1000,424,385,770,935,305,406,510,760,443,772,382,740,104,992,145,618,86,68,586,500,557,204,251,150,210,229,920,352,93,507,692,899,482,990,964,24,766,877,954,329,513,272,384,540,148,438,209,799,709,75,131,773,501,710,101,940,922,745,354,644,688,888,797,863,317,270,251,109,840,26,838,651,151,536,812,838,27,792,491,234,369,929,6,301,162,426,350,510,692,791,82,455,764,416,1,305,908,344,319,235,670,711,939,812,573,984,381,874,197,556,675,784,772,37,101,727,576,601,842,817,534,692,212,971,891,424,200,865,631,512,859,683,274,570,808,448,449,616,876,817,650,71,347,657,647,404,908,289,340,833,730,644,183,986,867,470,497,519,461,474,493,30,0,360,510,992,816,192,293,77,336,691,481,495,522,54,154,371,851,415,448,629,200,87,270,596,756,353,867,178,96,368,837,537,84,692,744,99,849,791,681,365,436,982,173,290,946,243,35,711,312,341,358,683,494,655,578,68,804,421,393,102,348,234,805,243,578,64,320,391,742,563,409,726,507,835,698,596,807,131,276,683,278,964,235,598,24,773,824,456,696,95,878,558,866,949,745,94,622,577,835,563,795,450,650,294,702,275,815,767,639,79,488,278,733,595,857,925,649,29,999,802,513,278,227,638,270,967,989,694,862,333,284,790,764,989,610,298,457,819,811,491,107,433,864,767,935,761,936,521,882,984,430,19,621,827,275,231,190,409,417,874,683,657,205,114,719,243,483,866,785,944,686,535,177,946,130,525,194,103,803,648,991,671,603,353,392,381,215,850,39,637,203,282,984,115,221,511,969,137,527,503,240,190,441,357,938,834,212,714,227,851,60,858,509,511,727,545,80,663,558,993,117,249,677,945,312,930,237,715,815,725,688,943,676,234,486,786,94,479,267,858,568,301,122,940,480,381,12,494,574,658,476,665,368,740,943,276,745,381,850,446,99,15,561,937,830,85,574,484,906,130,599,85,632,729,343,590,988,724,374,59,126,810,441,802,80,850,941,28,664,939,103,654,979,811,611,515,312,656,175,384,992,578,741,788,425,405,640,333,636,348,889,231,733,436,846,102,75,98,630,636,306,169,887,826,759,935,579,122,326,562,15,41,897,191,782,24,539,907,299,130,919,996,462,460,24,541,658,775,953,602,419,976,722,785,800,88,959,621,450,344,431,477,662,724,980,299,319,645,354,235,628,916,346,839,312,604,98,726,929,461,289,283,107,948,223,229,577,334,967,663,994,95,657,162,621,506,582,202,285,450,678,562,251,975,534,395,679,575,582,770,674,561,712,402,991,272,844,511,308,921,850,817,533,405,238,952,454,528,379,543,597,590,887,36,171,113,539,57,550,45,891,85,528,768,628,234,600,144,481,949,345,348,50,534,186,921,846,73,916,543,416,56,823,934,476,568,167,636,802,126,712,902,304,89,941,240,366,319,18,414,405,323,431,732,128,561,817,681,542,394,513,704,9,433,575,747,782,921,529,936,166,828,587,904,150,134,732,172,668,179,569,856,863,49,852,409,379,711,457,922,908,37,215,32,268,571,447,626,856,234,270,71,950,634,787,316,509,866,339,99,767,597,747,649,779,191,495,359,81,319,45,654,707,593,1,950,956,623,611,176,446,299,340,34,351,633,322,423,298,72,709,437,893,668,371,893,729,34,86,431,132,113,75,790,487,380,487,344,65,224,438,806,379,756,523,313,473,364,481,617,104,331,488,947,508,313,455,293,329,368,339,664,966,102,869,233,558,847,270,912,572,512,813,925,956,445,154,719,789,986,639,736,63,803,508,231,400,170,460,484,49,142,321,495,801,763,699,693,239,958,297,766,857,500,702,957,849,655,300,56,808,429,756,604,766,46,774,115,277,384,678,734,466,401,731,456,836,807,61,119,820,732,103,821,297", "809,924,448,542,237,614,229,137,952,382,80,369,151,438,869,849,429,63,940,432,15,902,735,299,577,255,248,364,581,852,377,971,508,139,493,764,84,305,739,958,556,968,118,156,718,647,409,451,469,87,457,45,983,224,295,381,87,697,615,587,159,202,856,612,238,836,663,533,226,530,34,321,414,161,98,646,842,8,689,889,272,994,181,683,754,517,389,892,897,253,314,705,621,948,146,889,315,678,289,929,361,741,819,693,478,113,287,225,679,697,809,699,291,75,435,524,96,249,987,958,665,158,176,917,48,330,989,2,591,532,513,556,380,737,348,481,152,703,653,294,90,949,345,610,164,769,699,631,936,374,336,610,992,839,880,241,220,869,357,347,618,926,817,105,226,934,772,949,752,982,683,497,544,677,378,409,525,297,845,433,227,261,824,205,965,840,251,209,195,5,639,116,501,579,580,126,625,175,380,161,614,148,157,842,119,372,271,431,797,4,248,297,327,525,415,703,353,868,902,736,215,881,13,667,851,212,712,825,28,1,875,168,422,631,975,62,563,679,283,258,313,289,8,766,426,638,975,307,144,548,445,348,338,746,555,880,979,617,541,176,677,639,418,389,853,796,253,918,924,968,774,32,475,89,459,468,804,13,122,316,554,484,811,581,715,724,927,319,592,404,843,231,97,342,580,416,254,170,904,135,5,678,52,269,820,938,381,539,2,685,963,592,565,677,452,360,0,848,993,981,996,405,309,967,172,393,914,30,581,828,953,788,387,929,615,477,611,851,248,194,942,674,291,371,314,828,371,225,97,193,176,365,383,751,172,144,32,167,236,853,201,905,398,538,577,563,61,397,552,928,215,674,118,767,949,157,874,653,54,917,781,16,74,918,862,87,505,812,582,380,59,294,375,413,872,808,618,39,400,373,14,305,139,495,362,527,187,730,65,805,269,381,665,612,351,938,445,906,467,758,454,261,801,473,457,469,225,655,914,562,813,349,935,244,58,509,315,850,475,845,422,922,661,150,909,538,648,845,532,798,677,452,374,109,590,152,356,247,741,569,40,132,702,246,307,602,170,764,748,755,289,530,925,735,743,995,77,627,971,883,18,862,595,834,269,861,730,586,610,393,121,737,726,981,871,662,744,316,262,781,215,648,306,635,344,771,405,141,189,440,538,155,185,174,585,846,470,270,710,322,269,758,169,840,561,915,584,74,587,966,411,475,704,572,923,55,424,775,116,883,392,540,840,43,884,820,980,137,363,17,813,486,60,357,681,939,215,2,63,653,448,58,907,333,523,370,782,96,92,259,343,676,670,399,537,24,32,236,479,922,471,811,662,5,767,290,423,291,693,483,356,693,665,584,524,90,112,62,927,386,999,515,513,649,345,792,215,403,742,715,510,495,816,584,796,383,246,18,514,200,406,114,731,470,906,326,966,46,14,49,468,55,529,664,725,732,295,150,234,822,6,642,554,880,455,407,75,868,870,607,431,50,791,662,889,93,739,151,340,542,641,413,541,662,555,521,142,191,665,226,979,847,169,950,230,379,815,728,871,734,852,420,366,545,990,597,643,517,553,996,45,615,223,989,467,749,30,886,471,842,638,512,93,862,125,23,381,937,784,321,477,394,787,400,921,68,707,586,117,325,96,201,456,43,125,619,400,991,232,682,931,166,682,734,284,941,856,896,781,660,44,519,534,577,288,12,263,37,232,957,220,714,87,800,305,313,637,968,997,450,784,978,225,158,46,855,657,8,703,179,831,135,169,107,647,584,554,629,912,608,227,63,741,328,142,203,835,440,431,474,874,744,222,814,279,597,818,601,281,384,942,738,276,704,853,880,634,996,741,759,130,436,548,95,230,982,123,253,27,433,22,665,547,410,141,417,849,762,731,699,998,773,738,940,929,113,836,63,549,37,286,173,111,73,446,487,690,701,318,658,198,44,246,1,127,869,605,697,120,325,414,82,209,465,210,389,955,193,247,360,495,191,221,282,365,129,380,394,895,632,792,186,77,806,258,451,534,867,582,28,693,801,153,32,64,498,20,560,586,738,557,678,542,542,996,540,112,222,388,51,395,59,163,93,620,834,477,149,104,732,626,235,837,742,78,999,366,235,38,197,208,310,828,533,267,518,670,138,782,558,314,583,363,304,676,380,844,436,88,833,111,515,714,245,225,164,213,955,496,626,534,898,524,542,418,594,721,61,250,985,789,830,926,326,670,827,207,105,443,544,330,108,669,977,410,435,102,110,274,404,446,363,793,402,971,894,166,531,605,974", "475,385,747,745,607,446,670,198,220,227,891,780,152,403,596,674,577,293,601,792,421,862,572,164,663,490,853,425,61,555,813,379,643,512,64,572,579,241,188,4,395,572,679,8,547,973,517,304,269,721,218,819,674,62,442,715,432,714,315,297,859,63,130,612,995,624,995,189,92,187,492,6,894,274,992,130,473,605,816,835,556,31,47,79,789,804,599,278,919,933,866,770,30,67,129,944,887,358,377,93,768,220,541,405,631,281,927,58,598,131,178,928,773,91,874,940,757,948,662,867,691,350,366,294,856,577,612,893,432,834,591,209,600,144,264,824,32,553,929,564,547,317,422,43,662,872,388,9,182,607,683,766,541,477,120,212,310,685,622,871,260,879,608,736,616,810,993,411,639,331,561,712,14,208,172,935,285,303,389,376,542,392,326,520,710,908,187,920,859,309,910,656,69,916,123,498,462,753,626,277,899,157,195,383,625,825,735,695,941,289,140,421,608,728,769,970,928,445,944,26,142,380,41,631,300,758,761,441,193,818,46,602,284,518,646,982,805,701,34,485,287,7,651,882,768,814,886,259,456,745,807,92,400,14,932,745,902,656,234,907,878,386,553,822,42,299,727,880,724,360,79,166,365,676,873,443,527,786,534,458,969,437,231,124,593,405,295,568,754,296,321,983,358,887,195,281,539,50,944,101,691,448,467,969,907,69,40,664,212,990,699,249,995,539,26,510,848,0,700,333,670,44,430,69,869,645,455,667,707,883,246,307,778,585,192,885,316,40,501,212,744,383,135,386,44,9,348,139,686,741,326,45,628,395,278,566,406,514,953,674,56,437,434,200,804,94,572,669,483,355,898,656,390,792,134,598,134,920,83,415,418,563,448,635,74,726,301,205,554,141,462,735,567,750,99,110,456,103,104,530,481,336,364,546,853,189,980,601,642,986,701,569,975,489,387,598,360,153,739,493,997,493,51,723,67,313,973,988,852,338,500,20,237,462,389,162,476,653,219,700,15,127,804,128,772,929,102,692,83,19,436,370,447,406,433,409,574,610,1,314,690,712,562,353,732,219,889,117,271,719,354,885,432,726,542,52,873,543,345,937,223,96,676,455,228,42,210,333,225,896,753,788,923,997,50,256,560,926,619,78,594,331,870,218,298,285,987,394,336,860,914,53,707,194,426,244,12,887,876,988,734,975,29,554,49,892,129,503,751,247,297,159,618,208,504,450,944,24,444,715,281,174,854,971,150,385,834,263,461,615,864,545,936,581,785,162,46,426,368,554,684,713,999,927,821,384,765,894,332,336,592,748,85,147,579,946,966,286,734,497,576,85,424,589,716,364,86,36,809,901,571,631,28,850,157,936,212,181,388,649,741,281,194,88,108,44,321,358,188,505,96,820,108,529,427,401,841,870,480,508,84,801,124,991,699,660,424,284,359,667,700,282,282,101,230,321,109,465,950,933,290,245,410,676,477,3,530,828,664,486,59,104,919,695,271,669,406,749,32,855,491,94,591,226,864,318,142,603,875,514,659,449,417,306,961,886,229,433,994,88,908,395,803,885,407,372,323,721,225,383,735,839,497,999,489,47,405,230,365,364,868,151,407,217,30,913,717,873,393,939,492,575,982,625,835,415,103,308,239,927,368,178,676,298,204,618,622,852,374,852,424,321,955,835,197,753,543,254,119,245,420,159,847,517,236,232,540,876,45,117,623,488,449,800,802,242,453,352,949,875,708,45,476,692,68,277,419,181,763,77,154,296,980,337,878,61,718,200,328,707,129,608,539,698,414,190,113,350,705,603,578,444,34,259,308,981,418,932,462,478,139,687,984,946,658,694,306,351,541,877,229,138,935,794,788,478,996,849,226,451,913,516,345,627,313,811,333,393,970,129,337,218,395,350,713,712,226,989,534,493,591,372,550,950,419,366,993,81,241,287,348,25,786,858,422,508,591,707,67,943,852,316,103,444,23,191,259,190,464,317,778,951,558,732,676,848,29,209,436,695,753,228,307,906,831,541,130,669,722,732,241,611,49,463,841,691,303,515,315,847,599,231,876,828,606,673,36,881,464,252,491,199,737,456,999,757,98,913,393,374,543,368,846,414,840,86,484,657,234,69,195,441,169,187,267,180,856,140,969,164,409,782,891,537,676,122,902,80,472,95,715,411,589,823,382,136,278,141,387,911,850,374,969,856,312,620,59,238,602,169,933,812,867,499,219,20,37,221,800,254,757,517,578,914,739,824,140,41,206,185,966,162,718,961,652,842,155,976,623,188", "752,405,975,24,595,575,895,413,890,91,54,68,320,74,183,454,64,73,425,493,541,267,419,541,840,906,877,546,427,176,644,729,909,728,917,907,785,322,665,252,561,22,32,22,741,201,48,114,609,999,412,844,589,586,130,365,801,579,701,526,728,868,397,846,993,809,980,317,390,104,912,600,250,917,978,292,879,711,874,658,753,620,259,853,387,792,618,380,197,997,842,261,736,352,70,456,935,355,139,528,100,806,9,901,399,155,667,605,782,904,159,821,573,521,849,637,862,146,178,84,259,568,787,18,120,896,888,113,629,296,290,322,824,907,373,284,980,933,729,715,530,919,140,907,506,420,70,810,770,617,856,850,244,866,879,271,922,658,298,252,909,748,215,943,383,35,345,406,740,302,476,10,201,62,535,721,693,227,450,456,958,984,170,367,198,483,319,8,236,346,631,834,487,317,607,992,278,72,479,316,728,755,978,645,499,34,44,82,330,51,643,657,121,228,196,199,826,645,643,409,533,819,265,994,955,108,873,874,508,660,415,348,483,861,999,31,113,866,480,618,535,309,166,345,659,626,375,309,739,940,483,708,206,322,646,191,524,268,144,304,687,667,29,556,981,6,934,528,637,87,665,200,727,837,681,116,582,556,895,325,987,273,502,789,373,817,437,438,538,5,734,674,951,560,347,725,295,342,410,482,368,100,884,543,246,101,308,225,939,639,557,274,723,299,312,992,993,700,0,608,768,526,530,858,157,502,450,319,152,750,752,722,163,822,105,970,824,766,650,894,860,580,439,798,648,781,145,234,109,281,564,817,157,70,899,217,690,57,218,564,713,974,986,533,407,82,617,911,623,237,706,118,862,722,579,796,484,380,382,247,479,170,246,481,519,613,719,283,945,720,571,7,968,104,725,725,666,162,902,670,982,842,484,457,398,513,992,562,140,334,825,999,865,791,123,240,188,910,610,529,760,339,182,103,687,792,651,660,116,962,539,860,190,858,452,863,231,539,615,446,477,740,323,622,160,931,770,317,895,67,881,555,137,489,75,427,737,556,609,879,482,877,22,760,75,733,633,634,227,248,648,907,253,508,382,933,522,435,27,3,369,440,538,888,272,515,102,623,39,605,398,651,664,893,319,742,878,59,126,421,146,818,416,985,368,999,434,128,658,837,632,64,968,589,959,6,397,185,768,294,492,320,997,297,165,270,914,868,632,100,415,156,22,2,337,411,930,919,119,987,953,743,565,463,348,676,184,33,401,394,856,518,716,803,245,21,138,700,943,148,368,354,409,704,604,892,620,802,708,24,75,204,236,365,465,728,189,260,133,133,411,479,516,332,699,818,797,589,75,94,271,800,29,909,807,715,582,244,634,894,268,269,122,244,327,351,317,503,667,824,543,741,573,691,594,421,681,775,714,194,589,714,311,299,688,770,135,230,810,181,358,995,593,19,150,613,192,173,72,413,566,44,767,716,385,333,120,849,877,283,815,670,244,157,599,776,788,779,903,477,93,815,555,979,322,709,809,485,390,465,693,231,173,762,456,576,732,245,558,685,108,388,317,180,46,863,979,353,32,286,203,559,33,346,375,578,623,75,916,975,677,680,890,410,890,685,571,231,776,752,64,973,513,580,167,915,317,304,30,189,937,644,143,871,32,676,200,504,467,364,825,809,57,48,518,113,545,642,119,250,581,481,919,82,902,693,225,771,790,778,834,760,523,982,153,58,524,565,41,331,696,359,994,914,12,243,902,285,478,375,909,299,561,95,88,393,11,891,110,647,649,334,83,811,659,624,242,487,843,406,554,61,860,518,356,155,348,858,45,425,868,600,482,512,325,413,427,465,621,380,614,237,855,25,852,301,98,511,172,131,421,112,227,835,59,29,616,878,9,986,581,910,768,894,792,626,624,873,216,81,337,468,528,987,90,308,462,877,831,139,507,902,878,725,265,544,34,454,584,745,65,880,246,502,343,138,140,185,790,855,86,775,753,584,173,791,694,211,420,881,650,362,740,641,617,433,955,304,312,421,284,461,345,810,981,821,194,674,891,765,342,691,590,260,47,244,462,168,446,943,53,533,32,239,461,159,502,181,961,949,436,660,555,532,473,600,995,562,761,813,289,836,179,72,251,614,803,890,134,411,905,728,393,90,65,275,420,647,392,723,884,843,37,78,133,37,337,539,496,595,714,169,508,938,346,28,833,529,995,918,257,202,290,523,70,75,970,276,951,341,707,710,5,586,614,6,846,286,101,485,138,276,114,891,752,455,932,817,890,248", "368,407,182,119,683,234,222,911,762,934,654,689,631,124,333,874,650,776,112,43,640,214,742,328,574,524,341,885,770,593,760,941,185,112,442,124,889,4,438,362,897,275,212,654,70,692,994,277,449,948,680,83,760,674,310,116,403,625,146,847,494,998,245,316,717,629,112,702,585,74,741,110,457,421,456,403,518,519,110,462,486,75,143,40,80,650,970,856,384,842,843,646,278,896,133,653,375,70,197,129,591,558,779,954,935,439,241,708,360,321,948,390,952,455,766,55,321,946,885,937,413,775,747,510,422,850,933,294,277,54,889,363,758,120,291,232,593,257,894,437,189,943,15,485,20,343,412,197,24,44,312,981,361,943,857,526,336,770,890,161,41,775,261,78,367,721,73,340,262,158,576,724,284,253,622,170,892,55,529,622,855,533,235,397,638,632,85,502,795,293,521,41,228,799,839,598,354,570,772,89,444,682,286,462,959,768,895,599,246,734,215,984,212,865,890,821,614,594,101,774,779,110,103,906,617,575,998,129,583,785,470,783,650,4,862,518,265,294,129,520,167,643,60,135,615,308,292,150,66,545,505,666,177,541,203,518,317,512,296,188,303,665,160,650,822,197,203,757,736,366,30,259,442,998,166,790,573,723,654,50,133,270,940,368,2,175,422,380,923,185,233,705,163,347,724,548,204,809,885,98,628,210,264,90,244,558,70,562,415,286,835,172,895,221,660,816,981,333,608,0,982,708,138,74,628,102,716,398,601,704,12,118,693,38,835,52,855,811,958,698,392,397,443,705,539,806,782,236,579,652,565,770,569,615,700,972,473,358,364,964,303,326,828,712,799,384,964,255,355,645,65,468,623,317,403,982,802,807,725,16,635,140,143,107,111,216,14,493,549,24,840,608,120,720,92,641,57,894,519,958,86,46,733,375,904,436,567,427,99,341,534,838,238,200,998,296,425,868,880,217,307,941,612,465,551,123,920,707,854,172,662,480,76,993,842,467,793,855,686,633,322,409,936,879,675,788,224,987,416,304,356,810,745,74,126,591,319,891,956,865,729,163,7,326,519,901,547,385,722,59,235,535,518,802,976,553,929,427,143,176,664,732,663,573,133,837,423,656,453,108,980,672,166,183,247,270,104,842,929,958,774,411,624,281,81,268,690,221,370,902,306,614,147,298,936,193,572,305,326,934,579,902,722,721,136,294,725,863,281,150,488,558,1,890,778,33,577,589,732,210,127,464,56,846,211,615,174,628,172,348,820,52,77,63,865,44,901,798,183,560,426,414,753,457,678,311,113,333,702,527,750,500,543,832,122,626,795,498,819,574,611,639,517,508,361,949,370,810,890,939,468,513,612,721,568,93,422,366,927,788,90,602,48,538,800,577,62,228,222,106,561,7,682,426,831,374,824,587,194,625,319,706,481,664,273,35,103,585,675,960,75,471,287,943,880,174,786,708,249,670,840,314,311,505,58,985,233,531,497,752,202,655,547,474,501,806,190,353,266,398,817,87,814,268,725,146,806,253,592,626,262,621,507,521,327,622,367,208,475,722,613,767,582,591,65,837,472,486,518,559,575,321,185,229,358,537,569,144,211,32,571,68,555,992,346,666,87,754,980,978,162,938,417,852,450,642,795,22,7,113,497,197,199,290,233,484,378,401,451,159,875,261,10,491,97,938,353,696,693,171,561,311,535,289,152,501,696,904,802,149,818,741,324,265,430,102,243,953,208,80,963,703,485,577,523,216,968,628,355,763,28,900,467,523,129,141,108,130,158,743,185,719,386,861,451,492,764,502,685,80,92,483,780,207,758,547,557,671,208,975,321,725,266,875,377,542,876,200,474,342,691,575,258,933,291,945,703,769,695,916,280,545,749,122,109,858,951,116,193,757,747,101,456,443,433,592,146,433,310,187,418,597,788,350,612,701,800,996,863,295,560,50,867,264,529,971,645,687,404,71,199,40,464,350,852,6,458,564,574,864,11,516,935,568,519,554,444,586,454,25,314,447,241,482,699,328,880,37,520,758,832,401,110,309,104,7,983,755,563,584,166,249,760,260,888,736,813,893,656,590,525,984,390,821,730,218,632,797,918,712,794,114,203,430,482,223,292,55,859,763,984,963,734,462,650,566,428,677,36,932,390,723,559,573,932,781,498,255,705,190,442,489,918,209,245,901,339,529,740,309,600,69,785,693,819,247,440,149,966,308,494,297,143,68,165,174,54,540,709,272,294,336,466,760,925,235,812,18,484,778,739,213,504,67,646,904,449,21,90,960", "924,486,972,41,954,875,739,21,86,918,653,124,943,609,734,793,671,317,244,51,306,44,6,277,941,669,419,894,238,793,275,48,854,608,979,971,362,917,223,627,330,873,789,28,552,176,932,435,107,427,200,523,476,363,539,438,831,167,610,506,473,534,894,665,610,538,342,883,189,95,936,174,44,318,837,163,240,48,11,369,727,386,638,900,303,590,49,580,996,157,868,113,882,395,487,757,337,623,743,907,206,23,255,625,339,222,256,500,634,156,358,867,338,747,619,989,426,856,953,393,37,154,76,719,509,774,716,500,237,106,640,986,976,192,166,273,24,515,479,424,115,437,324,546,565,221,150,865,694,319,3,769,952,569,182,588,604,528,552,265,65,760,716,147,761,97,887,215,133,383,146,169,832,168,919,520,208,833,830,79,382,171,194,35,67,444,57,326,977,77,131,411,149,740,167,120,707,988,785,860,602,268,186,677,694,28,534,255,970,628,544,169,986,540,7,794,514,824,477,140,648,658,880,628,404,706,757,356,977,639,823,488,573,512,823,697,72,211,955,743,640,112,282,798,430,74,450,406,955,408,521,521,737,386,528,576,83,761,951,325,252,520,351,392,639,873,178,221,872,164,774,649,706,100,937,710,905,919,148,187,149,414,446,145,824,170,492,163,518,622,532,869,76,30,79,566,321,926,859,262,315,107,528,212,837,759,374,517,752,372,349,48,128,438,224,192,996,670,768,982,0,888,15,47,336,318,450,436,350,937,6,202,93,100,871,795,675,766,86,855,969,152,291,927,904,246,465,592,157,381,574,561,254,325,31,324,760,917,5,224,378,162,232,51,323,354,277,10,935,338,44,281,395,534,591,526,753,217,748,137,727,405,434,689,609,541,928,647,562,122,658,197,823,726,828,475,595,863,207,998,66,540,535,599,154,101,69,93,82,213,236,213,396,809,771,748,580,39,243,542,962,894,144,31,269,925,120,513,168,167,397,622,611,60,167,492,310,568,320,66,20,114,448,782,16,784,232,468,558,829,696,582,467,777,749,608,802,299,716,975,162,758,133,756,576,612,404,144,681,618,971,381,121,859,445,837,588,505,686,808,382,799,991,274,389,86,47,186,61,861,386,803,189,3,379,226,535,723,550,89,624,382,52,572,653,399,985,425,63,169,185,273,890,37,410,765,207,731,17,516,773,475,854,259,214,255,2,437,932,289,360,88,562,539,821,179,643,843,202,387,206,879,184,714,49,295,560,975,186,212,970,835,849,211,861,995,104,855,930,933,126,768,310,641,508,854,175,332,56,509,474,34,447,723,256,66,111,39,468,578,964,369,375,117,152,581,15,943,215,779,363,165,504,915,828,669,839,322,535,328,19,334,795,422,894,997,257,614,489,923,763,670,989,979,764,348,39,20,784,319,931,512,206,630,706,148,405,530,395,999,323,929,519,355,73,913,839,160,628,485,530,176,524,743,158,117,93,301,595,938,140,282,272,724,546,428,553,946,298,929,916,36,639,211,853,611,420,83,470,928,714,421,126,491,933,310,261,282,980,439,87,785,883,478,560,754,200,656,339,669,224,234,184,974,435,354,935,118,214,277,513,196,36,810,630,973,505,483,803,576,354,581,269,672,587,614,727,638,493,292,221,348,887,88,717,717,196,758,5,665,776,925,113,819,59,127,853,22,375,43,313,579,384,657,322,793,346,961,972,743,371,869,767,948,627,577,977,523,295,448,2,648,531,929,59,38,246,298,924,540,33,453,740,452,125,592,389,450,231,246,858,54,210,193,654,792,339,930,559,232,991,756,395,199,168,891,828,456,315,562,621,553,297,168,541,362,382,742,763,194,574,393,688,854,307,236,229,441,925,781,798,725,56,872,784,997,847,73,175,297,32,498,286,913,452,597,428,589,579,369,795,541,719,524,777,734,929,35,914,815,928,523,80,476,827,685,332,404,407,861,573,801,592,453,808,718,917,532,293,795,443,175,574,360,346,370,777,818,693,195,972,609,867,9,497,479,238,323,919,961,448,249,515,583,957,23,41,971,119,42,327,4,597,200,398,755,293,962,65,372,811,13,933,254,161,820,484,107,23,314,915,214,599,686,355,578,382,802,396,516,132,834,251,246,824,541,518,345,92,862,721,243,238,711,359,349,440,669,277,661,965,122,72,410,495,428,870,176,541,9,744,669,716,520,223,584,886,278,262,720,367,581,871,403,972,414,645,340,317,922,686,893,894,116,841,29,830,62,323,892,257,1000,482,942,308,111,774,819,537,639", "108,681,469,486,325,264,438,306,788,362,725,95,801,54,948,50,435,127,862,654,439,637,459,228,564,865,651,869,243,777,212,115,944,201,240,598,948,295,228,158,305,128,501,225,866,825,850,96,817,170,102,892,569,171,568,332,802,716,806,452,893,143,808,64,564,552,783,126,897,940,971,812,987,688,687,195,508,58,507,618,877,7,821,310,165,837,172,360,181,943,328,82,448,667,621,440,76,433,171,100,113,589,287,2,300,302,576,48,27,352,375,541,987,695,314,642,518,837,662,829,969,476,903,424,483,423,996,967,590,906,512,466,25,510,367,953,366,895,749,775,535,876,358,325,882,224,965,495,24,288,851,465,165,954,801,97,290,788,278,595,223,768,499,276,965,685,419,803,158,260,427,426,656,724,20,868,437,275,770,465,606,259,576,984,144,895,887,548,599,115,379,175,377,717,835,743,311,396,106,826,98,238,771,546,951,527,423,132,822,38,22,396,471,19,617,480,661,746,216,351,224,996,592,819,24,563,844,990,697,99,947,635,522,288,619,249,99,347,274,230,451,716,938,747,539,723,439,730,456,677,852,267,832,239,801,893,206,850,953,317,191,447,883,280,854,730,974,4,15,882,676,556,989,631,193,795,620,538,216,656,259,32,551,561,99,546,750,8,37,787,100,763,863,60,316,625,952,26,622,961,274,578,392,495,509,559,648,166,436,378,46,727,736,80,41,293,405,44,526,708,888,0,939,186,442,295,385,675,285,723,439,183,491,230,216,972,941,185,41,263,265,583,483,825,618,227,858,329,430,946,515,130,952,404,332,30,219,58,988,18,897,638,364,789,979,934,570,952,241,930,460,502,593,731,992,974,811,400,611,538,610,928,110,108,143,694,278,917,333,7,798,337,481,582,617,497,992,372,960,712,749,248,656,997,707,898,30,692,603,866,424,118,786,361,20,988,135,311,757,513,417,839,326,716,741,951,201,564,562,5,319,101,186,500,391,183,620,557,134,54,905,830,777,571,706,322,949,46,234,773,702,516,64,442,294,340,507,706,755,190,621,357,44,971,709,766,481,208,591,545,612,536,168,153,603,210,522,343,300,104,919,276,885,695,664,796,298,77,662,22,155,198,692,199,746,810,790,537,66,570,736,27,682,491,735,550,135,253,668,178,988,974,664,796,538,492,996,540,662,801,592,975,137,404,354,875,446,900,947,234,18,646,290,982,223,548,594,946,806,17,937,220,259,549,196,449,491,12,387,965,504,928,232,901,692,459,589,48,812,769,397,654,586,499,528,621,973,508,270,169,774,515,548,254,115,900,48,656,501,180,815,313,149,503,32,413,160,468,582,179,189,402,971,158,811,373,562,445,138,611,147,138,740,440,725,122,463,948,531,108,978,921,58,941,445,579,430,666,65,954,114,998,120,617,777,655,878,274,559,628,883,45,287,514,415,181,73,620,507,93,880,559,435,605,30,899,936,306,629,52,17,524,294,378,531,163,491,733,139,275,91,94,557,182,703,35,588,78,372,357,727,29,197,593,470,736,272,990,378,106,145,526,300,789,791,167,686,635,482,858,13,334,71,572,416,5,66,894,784,679,201,710,738,425,905,29,801,194,146,33,968,94,81,403,457,723,730,769,558,172,336,292,359,825,313,359,530,248,21,476,732,25,196,12,539,609,202,486,691,947,78,989,20,323,617,516,718,601,348,286,166,644,696,22,464,186,548,759,653,125,408,91,2,169,701,548,741,304,262,792,724,553,210,18,696,442,913,488,590,136,355,979,705,864,348,181,973,959,240,499,355,637,462,824,447,365,653,367,253,117,537,363,377,2,746,627,459,394,822,530,507,322,278,507,936,343,759,520,93,711,418,791,456,764,575,597,428,988,86,731,867,840,895,321,727,184,193,820,149,88,968,980,412,854,727,349,584,272,895,555,90,860,436,398,868,199,434,879,681,756,811,872,55,950,723,816,837,448,870,693,472,259,367,459,341,119,384,768,991,117,817,652,169,513,393,432,342,360,133,906,548,712,116,435,422,576,509,415,20,651,306,835,537,737,674,35,16,970,45,19,747,193,367,683,832,101,947,357,427,967,125,421,937,12,500,14,361,555,162,208,735,198,977,449,946,530,461,370,134,824,591,344,437,781,95,760,767,214,298,966,801,445,248,419,387,683,851,488,278,751,680,566,730,606,725,73,104,644,52,439,436,648,951,190,694,764,353,834,440,895,397,419,497,206,197,264,141,442,101,612,664,911,808,437,820,114,294,519,414,524", "276,293,986,869,619,620,40,600,359,35,385,512,687,846,47,454,583,6,733,700,39,422,245,688,626,231,363,959,719,636,943,548,532,205,860,352,130,791,724,363,939,57,326,632,472,270,507,955,568,5,123,217,860,808,925,158,221,775,511,104,400,229,629,825,350,731,828,45,747,859,911,278,674,215,202,81,660,190,437,561,454,659,581,775,927,594,730,928,20,66,551,555,186,809,842,725,555,407,882,698,319,358,903,751,326,228,994,156,307,625,493,146,97,826,626,827,220,124,326,994,333,789,934,32,843,927,117,640,181,899,759,729,717,211,687,498,489,725,94,833,524,291,730,205,947,304,543,172,781,441,570,776,875,126,943,286,864,517,78,473,683,304,775,914,80,587,270,177,374,762,617,3,669,361,432,472,450,452,425,15,29,583,742,972,686,495,597,957,122,595,803,972,491,884,271,290,201,557,73,697,949,268,650,128,543,667,372,100,806,465,884,355,361,377,775,436,258,95,49,983,131,851,232,354,825,727,232,21,486,711,742,259,249,752,84,741,220,723,717,210,529,934,39,940,255,64,89,455,344,988,818,268,845,752,941,143,344,55,513,590,284,457,564,967,205,149,77,867,826,441,562,928,203,42,182,215,919,45,261,388,604,37,827,178,503,957,258,931,257,789,565,940,905,561,486,47,714,836,511,696,397,648,863,738,976,936,508,138,104,181,943,302,985,976,760,77,309,430,530,138,15,939,0,193,327,808,279,821,160,356,455,465,489,63,773,525,836,960,19,546,142,626,28,935,927,665,75,244,81,574,225,307,221,689,527,678,44,740,259,268,630,336,382,350,619,234,838,299,807,82,6,428,474,485,132,104,958,327,863,839,595,82,206,20,594,296,428,583,686,224,792,752,892,857,647,535,466,619,985,292,214,179,405,154,216,446,895,259,199,131,597,615,764,831,985,370,388,625,697,968,920,341,544,508,849,255,614,550,410,12,583,641,137,980,269,440,577,846,82,512,721,876,946,405,95,653,260,220,989,565,927,46,822,9,576,123,448,811,943,425,701,583,639,870,672,582,871,81,190,418,142,976,545,963,664,954,510,385,717,403,862,67,847,908,75,93,821,533,771,608,575,442,598,108,716,52,407,532,87,35,558,447,359,441,643,219,452,682,548,687,887,391,412,12,968,567,878,886,916,633,810,723,847,75,216,685,946,4,88,530,482,733,418,164,925,656,480,400,551,494,103,13,626,993,626,685,931,606,63,472,589,176,558,502,871,870,236,940,492,462,825,729,731,234,173,716,922,612,721,304,396,930,388,621,692,335,627,699,757,811,920,766,127,415,919,235,121,385,660,308,739,848,243,174,496,297,405,555,465,65,321,90,799,81,686,944,437,833,877,79,581,891,636,317,182,520,921,315,562,945,938,268,132,251,194,940,917,914,146,317,241,799,52,780,609,281,838,465,136,738,249,722,339,192,481,870,211,193,979,623,427,962,417,602,251,422,574,585,962,968,487,340,721,610,150,809,33,413,90,388,402,554,371,840,565,971,714,241,894,301,220,76,877,639,289,60,894,248,147,645,224,528,906,476,830,972,59,14,648,871,643,664,875,829,545,634,830,490,344,501,623,213,112,327,943,402,397,545,595,959,410,91,138,654,67,409,173,852,982,472,665,368,887,786,698,502,824,393,528,505,797,510,370,721,206,160,318,693,594,321,174,857,413,746,253,690,992,355,209,776,741,34,965,775,897,655,294,646,3,129,672,370,774,87,266,933,998,839,482,659,925,118,896,218,737,949,566,27,891,935,235,201,557,172,236,620,951,692,723,198,217,813,291,281,433,489,425,632,540,158,400,52,21,951,18,783,329,359,666,382,40,623,683,701,680,206,472,127,865,435,354,238,523,209,651,475,925,45,840,297,479,62,305,891,884,979,867,931,836,947,715,331,713,456,934,745,975,77,382,369,805,679,687,173,544,538,68,774,254,13,244,903,477,204,419,66,577,409,733,417,741,805,940,696,675,763,191,958,325,492,515,10,917,535,543,77,346,378,343,883,122,462,971,308,2,339,222,555,637,562,92,134,747,9,486,50,312,904,572,54,425,668,526,516,231,127,142,105,8,380,392,185,766,616,807,747,375,827,102,716,177,72,293,562,851,809,579,805,376,966,693,606,587,639,456,691,965,355,843,599,916,671,653,664,780,143,741,418,111,322,352,908,553,283,796,14,500,322,960,580,601,833,655,886,118,145,114,772,390,581,271,645,195,556,376,529,900,784,512,876", "472,515,770,298,544,608,256,683,82,509,85,100,314,348,133,780,252,260,905,57,63,334,147,665,76,988,705,473,619,815,673,905,121,716,632,309,493,105,288,263,598,739,374,259,33,716,244,947,439,253,112,748,972,202,176,37,313,63,147,132,916,55,270,118,246,675,448,927,697,382,955,93,165,841,162,135,31,905,262,132,606,281,684,680,770,478,951,893,351,140,462,163,242,125,828,438,348,219,945,669,578,227,913,911,394,199,417,100,69,706,118,519,910,600,27,994,428,810,300,869,958,946,31,676,763,644,867,867,948,434,946,953,204,731,355,225,994,682,855,536,217,28,374,514,978,451,387,107,776,319,684,461,207,209,795,1000,786,860,907,822,945,104,263,718,913,820,27,253,798,253,722,183,397,356,960,250,444,104,251,55,502,781,983,99,58,637,924,777,857,65,712,603,900,198,185,840,675,677,571,566,650,377,79,685,732,703,813,623,75,613,959,293,90,701,328,423,942,490,745,15,581,229,97,432,825,735,716,99,838,601,778,872,315,53,708,968,560,68,658,900,982,446,142,186,262,414,883,499,816,177,688,119,453,545,278,367,821,748,680,413,965,137,760,236,465,466,112,95,928,949,538,120,118,842,499,962,79,712,280,664,641,293,832,192,604,881,178,770,231,871,688,939,898,675,263,391,649,179,857,939,878,442,120,101,656,728,770,469,922,176,649,779,430,361,299,336,967,69,858,74,47,186,193,0,63,796,469,753,449,934,549,720,558,272,428,253,212,380,808,304,560,678,978,668,777,386,678,465,890,242,624,629,328,562,459,952,203,695,621,482,771,230,84,361,255,598,926,864,159,122,21,278,639,970,153,180,854,255,813,44,843,951,81,536,364,727,854,203,92,702,653,683,828,950,547,771,892,947,693,668,95,688,218,994,17,302,226,207,996,941,184,131,637,958,793,159,154,187,351,228,978,356,231,145,166,269,754,122,219,709,620,473,856,976,820,407,628,221,350,126,436,612,529,822,848,83,781,147,257,734,77,11,373,544,355,114,599,379,273,155,56,440,601,373,164,304,301,174,240,198,634,543,74,319,112,821,550,963,638,851,42,220,43,516,843,659,795,260,485,882,857,594,887,339,801,979,221,108,353,139,7,371,447,308,195,319,57,215,978,318,165,859,284,866,524,551,171,428,918,190,640,470,811,279,316,204,685,958,826,565,205,658,432,751,939,275,961,889,447,71,401,18,270,713,160,668,727,883,878,228,881,825,660,622,782,698,440,786,987,815,271,491,449,386,567,591,843,278,463,515,864,402,921,821,825,7,832,739,362,201,651,794,20,352,609,998,198,358,156,422,854,953,563,254,457,537,337,349,785,683,754,716,229,439,815,740,106,228,952,476,357,79,79,790,776,791,76,768,370,369,101,243,153,593,842,351,903,112,160,78,92,96,364,3,530,442,237,512,351,65,83,588,393,739,81,567,896,977,230,709,568,827,445,917,326,773,189,735,157,310,786,782,236,3,326,490,848,905,231,535,9,170,31,679,481,22,278,175,46,278,619,138,39,466,102,280,231,890,160,325,138,501,939,424,751,946,182,410,337,348,249,849,127,17,393,285,715,638,285,306,321,366,221,464,629,452,914,661,674,191,342,849,979,318,733,436,732,941,310,379,68,8,189,989,23,899,280,862,590,721,692,298,403,126,466,499,674,163,514,652,556,685,870,460,801,545,369,209,212,517,20,450,582,669,186,470,77,218,328,199,276,445,85,716,565,702,615,628,415,312,624,498,535,186,383,116,285,456,938,155,239,603,321,385,34,60,609,516,864,564,779,611,638,394,702,491,934,549,354,108,269,230,371,123,430,574,896,637,192,332,840,157,265,297,236,677,994,16,980,449,98,721,714,556,374,89,866,558,510,975,631,394,322,138,386,504,550,45,406,2,979,134,852,528,640,424,294,562,608,588,960,551,376,419,901,409,618,969,525,187,978,635,309,54,700,975,480,359,26,676,18,93,319,673,561,87,690,69,449,922,880,615,1000,683,94,566,67,903,16,299,940,429,825,992,516,453,914,918,772,359,69,354,270,973,355,490,814,847,981,34,364,495,316,181,773,300,117,869,473,811,398,163,545,851,952,603,361,71,908,982,219,700,787,446,138,65,711,27,904,487,496,875,264,742,536,392,723,551,952,662,933,520,18,187,991,442,187,438,660,91,6,203,20,495,956,820,494,740,989,342,827,146,92,65,847,496,440,339,270,974,617,540,789,327,118,692,265,311,869,993", "469,590,12,149,66,952,939,155,499,326,119,672,692,389,333,958,809,476,315,255,299,296,72,145,40,607,170,499,597,936,167,568,406,371,620,1,443,674,632,399,56,201,934,478,715,643,356,5,440,268,161,466,882,77,110,918,133,717,485,972,668,340,660,448,850,693,605,977,928,802,107,258,767,233,132,133,597,676,762,430,181,650,451,192,413,423,456,342,429,644,702,600,526,22,966,753,44,408,427,417,811,788,19,204,6,967,478,911,792,490,857,168,124,545,664,738,786,416,770,939,946,437,737,256,68,201,822,470,603,429,211,596,960,368,246,254,588,303,114,265,981,533,255,720,93,27,975,274,407,81,874,433,386,364,720,593,168,284,332,930,4,86,144,120,512,995,788,821,532,612,572,374,268,195,678,867,647,400,726,543,709,236,197,589,631,402,469,375,48,676,443,346,404,207,716,548,137,700,449,794,661,845,324,65,237,520,831,840,352,522,534,827,219,77,863,266,164,75,443,816,248,992,62,414,734,360,744,956,854,694,108,704,668,447,386,332,837,894,715,224,491,741,364,357,906,20,820,506,895,342,404,224,661,797,401,298,545,799,556,574,535,315,22,915,399,541,390,919,801,375,651,86,287,948,909,156,563,223,392,211,643,348,593,844,627,345,479,688,45,943,955,997,412,129,35,76,929,837,73,962,853,402,6,853,813,18,11,874,247,608,390,164,396,764,388,691,172,869,157,628,336,442,327,63,0,975,825,652,194,391,773,609,595,744,127,204,663,944,917,486,376,549,740,295,832,414,163,842,13,399,960,868,558,61,600,803,542,512,177,864,330,214,421,514,501,780,859,761,357,548,476,299,248,691,100,26,260,125,800,47,919,803,137,520,139,97,454,533,837,755,957,784,81,779,465,494,937,28,290,985,292,405,630,362,245,797,527,673,85,546,702,505,696,103,605,802,430,149,422,220,498,654,803,764,926,969,577,762,766,478,123,872,569,559,6,817,126,623,994,85,295,135,544,845,754,230,984,101,632,114,718,906,21,307,491,553,288,444,842,124,962,424,743,512,322,374,359,955,284,194,383,257,418,164,955,868,496,826,919,893,855,55,454,713,274,86,972,601,227,55,369,490,886,490,266,756,559,65,886,727,61,700,147,87,915,783,795,295,831,123,208,981,423,26,550,921,804,92,904,14,527,920,413,676,855,423,972,452,675,566,961,991,554,26,758,799,93,739,736,881,824,393,334,957,873,453,647,356,157,220,112,519,316,972,884,38,849,30,266,267,228,278,681,919,511,451,210,794,445,262,900,664,801,863,386,416,162,623,171,856,812,36,864,710,151,924,508,234,795,496,497,814,503,195,347,792,11,681,698,330,715,962,285,249,222,279,302,551,914,160,495,579,102,868,29,462,148,456,254,727,13,65,521,697,114,736,163,645,444,316,17,438,299,775,567,77,218,911,614,287,107,431,266,908,574,714,408,215,118,938,177,448,733,634,555,945,718,909,349,436,120,673,263,36,773,541,30,519,683,376,670,443,490,433,944,154,62,915,437,735,678,974,86,333,487,188,508,567,179,520,681,500,448,382,791,303,728,717,320,432,642,309,251,410,154,936,541,228,968,594,845,306,288,722,259,152,549,842,341,157,514,923,559,343,901,456,72,599,85,853,769,558,416,467,318,703,568,409,313,706,982,259,279,71,333,513,708,593,508,503,40,159,15,858,978,394,655,955,154,631,407,708,706,506,280,84,893,584,809,443,65,666,387,807,924,677,485,789,94,39,322,60,880,70,527,229,988,354,761,601,71,692,461,264,911,648,887,986,962,816,396,153,959,915,131,121,862,319,486,682,44,155,138,605,444,832,342,222,965,781,841,573,842,750,546,624,699,890,751,977,181,668,958,981,445,770,907,170,599,20,409,826,543,154,151,567,285,571,5,349,580,474,384,771,557,579,128,985,527,223,73,331,470,965,911,23,723,681,599,671,994,153,844,721,456,820,384,694,704,195,210,642,544,963,245,537,378,241,805,203,867,405,1,215,337,939,596,414,758,747,754,461,780,597,961,273,483,354,905,500,253,890,65,38,355,82,542,160,268,348,408,886,825,648,782,229,561,722,56,790,845,763,748,293,342,425,96,821,54,393,147,112,873,814,597,840,139,958,789,181,646,657,388,366,502,568,139,888,668,702,723,647,620,989,62,836,62,850,332,908,520,269,480,18,800,190,891,835,763,81,539,930,983,408,363,707,236,478,5,307,537,394,200,755,563,635,423,678,974,791", "704,497,700,310,607,510,377,219,954,231,952,142,872,134,914,343,321,86,942,775,865,980,51,746,338,930,792,683,3,427,417,768,922,448,52,638,155,189,960,776,559,995,678,189,1000,71,695,303,509,328,395,10,725,543,957,397,806,951,6,934,409,687,884,106,815,76,956,525,553,818,59,439,44,744,861,111,656,946,682,717,215,112,273,972,147,628,274,994,554,824,206,198,790,572,553,496,933,658,231,314,507,150,23,493,418,677,843,617,960,502,99,273,979,170,545,301,898,450,250,62,370,204,56,453,957,946,816,101,851,521,92,269,329,413,140,320,403,215,458,54,679,715,9,840,883,295,127,250,609,486,998,794,639,48,205,776,13,679,975,662,338,314,864,398,231,287,106,544,555,30,873,169,977,536,41,776,5,824,498,214,619,338,177,706,584,329,213,657,95,175,106,20,687,262,114,14,540,148,995,554,830,202,713,675,907,737,452,245,173,825,608,185,223,746,714,934,6,522,681,877,440,755,635,334,500,439,352,404,114,631,716,260,575,360,179,516,516,236,966,452,244,55,871,739,278,674,455,793,14,912,466,520,578,824,180,313,744,376,7,688,7,10,609,792,157,850,632,709,232,8,477,779,866,81,147,530,882,853,899,794,260,724,297,518,244,573,237,787,402,37,803,198,36,106,251,982,376,375,283,118,300,757,379,13,826,327,800,42,582,949,379,991,89,518,299,481,393,645,502,102,318,295,808,796,975,0,70,172,92,519,640,398,759,674,133,701,729,781,413,792,280,334,710,451,87,734,130,203,719,30,393,107,147,936,822,754,857,187,701,377,244,742,274,697,294,324,442,561,404,950,232,420,841,107,479,572,888,328,824,920,850,824,338,349,869,273,607,78,823,607,553,642,601,494,253,766,215,623,251,240,336,908,258,818,618,894,647,977,239,719,528,791,752,903,56,88,427,918,318,89,626,34,992,357,740,491,214,210,78,480,420,447,666,26,25,729,425,893,368,624,463,530,411,707,962,879,532,242,874,347,303,681,353,352,871,51,914,658,35,674,487,235,391,21,939,867,773,400,244,186,391,582,727,746,737,309,52,883,588,414,16,950,359,962,212,198,481,963,983,876,284,21,321,322,486,412,15,383,525,756,228,577,533,411,669,859,144,750,440,583,587,47,919,645,53,448,171,572,826,608,167,144,473,352,426,793,912,995,958,88,15,404,694,64,349,494,535,246,570,839,497,889,104,162,942,197,431,896,951,242,630,869,599,155,192,380,647,341,887,155,158,200,498,517,696,916,718,472,39,596,933,378,955,952,562,966,48,252,978,170,327,946,77,323,105,174,755,473,400,98,211,571,622,663,216,603,516,610,985,613,630,418,375,300,586,246,990,22,200,434,266,41,535,763,410,30,104,930,269,877,811,676,821,687,661,826,550,939,646,804,738,101,705,973,273,21,731,188,742,674,515,4,38,482,371,167,280,243,214,891,788,943,72,389,222,59,344,769,490,330,768,403,5,989,459,551,352,808,956,284,886,323,185,423,933,601,135,45,483,368,742,276,739,40,560,360,258,242,383,457,370,605,368,829,852,495,953,723,886,689,743,285,698,278,247,330,894,749,55,191,774,866,128,600,87,509,327,203,808,661,368,840,789,956,470,502,187,486,950,563,332,703,499,980,894,517,845,565,977,730,36,662,257,101,980,545,751,99,483,323,143,1,338,681,546,83,418,502,327,154,778,986,727,843,392,542,281,975,400,871,48,881,379,758,392,974,971,267,189,473,440,213,168,290,493,63,329,954,314,271,964,899,996,368,285,57,258,96,687,230,609,969,512,542,558,920,66,438,128,709,149,578,5,456,72,43,286,979,566,814,214,557,735,934,713,881,818,440,428,81,794,873,877,541,176,947,226,702,760,641,654,55,112,897,226,635,924,880,975,735,117,61,366,878,904,262,919,781,597,930,977,457,449,2,651,932,852,286,232,15,759,938,611,318,583,820,51,774,91,928,426,3,308,63,978,178,406,329,586,689,744,377,55,617,951,446,294,436,56,238,16,525,69,237,905,78,777,559,247,351,226,960,453,826,25,216,658,308,288,964,722,516,148,290,942,969,901,748,123,397,863,770,304,781,348,337,800,793,360,871,174,467,59,325,305,838,423,131,418,502,340,334,882,822,181,39,999,441,853,366,571,118,659,489,843,142,353,555,914,460,291,345,269,10,454,111,502,417,201,784,955,39,767,412,706,112,922,621,729,725,98,504,516,46,817,236,541,536,956,460", "92,657,977,350,614,256,256,280,120,284,38,650,406,686,393,247,931,503,371,735,147,238,538,991,251,36,887,729,330,309,936,651,77,893,827,190,863,971,732,951,916,176,84,240,899,241,70,832,196,151,126,654,778,889,377,712,492,480,699,438,57,460,365,945,181,831,439,240,834,50,728,645,544,289,54,175,955,779,82,447,914,462,989,40,900,485,784,718,925,744,28,802,50,794,268,952,55,815,988,70,663,292,39,606,316,328,880,953,665,930,122,287,130,372,227,733,984,133,506,464,394,465,208,993,735,436,609,439,57,374,329,45,366,303,340,968,624,207,993,687,11,393,144,614,25,332,264,143,677,906,948,466,972,859,155,484,85,960,251,105,444,195,271,40,684,399,848,827,542,875,155,74,679,897,438,664,988,372,187,647,530,327,645,65,821,958,329,794,336,545,23,839,443,209,813,664,121,426,653,426,45,99,857,977,802,525,569,825,549,555,459,900,382,343,718,546,115,380,410,556,57,360,237,795,615,161,60,648,25,717,153,25,587,629,168,555,684,606,537,531,143,360,33,635,111,515,725,91,911,837,698,782,897,332,866,484,357,74,622,257,151,811,817,289,682,227,617,809,318,240,184,996,705,600,737,220,508,359,901,154,830,273,733,868,982,576,401,341,364,403,871,492,394,303,346,17,218,669,358,740,370,702,783,251,166,660,43,851,785,452,897,886,58,842,928,495,914,455,450,716,450,385,279,469,825,70,0,846,801,49,241,47,28,320,274,641,715,457,900,588,795,488,827,409,410,400,176,778,142,471,899,819,505,625,597,548,121,452,148,237,664,646,267,3,108,167,433,367,442,358,974,753,97,778,375,846,984,847,978,307,569,751,603,85,728,322,58,649,365,798,570,868,763,61,947,811,460,942,493,344,487,438,36,749,915,948,856,252,579,293,113,23,799,473,979,603,972,38,63,959,171,230,189,686,917,578,97,619,428,109,111,303,949,508,861,162,249,799,939,361,799,600,358,161,723,537,378,257,23,836,56,768,67,62,814,787,940,933,590,188,842,951,22,242,903,995,910,76,674,124,562,679,304,503,98,978,805,417,651,977,629,526,56,979,923,719,900,180,262,447,54,769,659,355,668,71,648,920,262,398,767,669,982,262,955,574,334,502,256,572,890,782,632,74,301,760,111,193,372,76,138,847,443,884,284,550,348,842,169,1,542,544,723,73,779,214,989,982,787,129,272,257,829,760,349,190,362,468,47,940,341,492,533,288,794,236,755,820,591,892,69,523,626,113,439,162,187,193,761,909,859,198,394,256,555,622,364,988,194,792,348,326,750,642,22,378,482,970,253,70,809,819,244,571,348,821,778,830,400,524,676,718,636,497,571,165,48,538,163,575,655,650,186,784,133,635,275,884,8,826,28,86,898,576,657,904,106,364,143,4,467,862,581,881,837,863,411,131,176,704,586,489,117,965,517,188,776,620,223,110,426,975,638,417,850,97,487,720,939,75,232,853,189,508,646,675,370,171,171,922,498,848,881,478,201,366,309,395,394,21,65,412,241,986,950,388,663,460,76,776,692,241,318,782,919,352,942,183,892,567,200,578,426,526,723,498,488,597,167,1000,889,297,381,819,642,412,199,820,325,75,203,472,376,630,58,846,381,297,342,411,721,222,629,42,767,381,157,556,605,436,307,611,132,889,93,153,89,201,767,662,289,531,233,894,456,969,778,625,873,187,950,639,729,516,324,693,646,917,846,688,32,109,455,375,932,396,895,280,854,183,153,419,7,739,807,242,566,905,690,999,833,121,853,771,920,808,242,33,788,828,482,702,228,240,402,161,30,190,751,129,159,611,587,296,842,744,138,278,677,823,61,728,375,551,29,415,121,256,872,849,303,89,470,214,811,437,430,298,291,221,101,12,202,21,981,927,922,613,100,15,480,348,662,935,188,576,851,96,202,682,206,288,514,834,564,180,439,658,480,622,800,525,760,491,220,707,508,701,150,215,315,678,912,5,992,328,372,922,614,710,827,940,974,70,459,101,416,302,491,886,74,942,429,38,331,522,730,919,489,870,411,388,706,839,776,86,186,692,955,881,488,917,721,869,129,808,482,975,365,646,562,875,178,307,188,339,721,53,253,46,761,267,54,412,461,636,112,132,243,386,933,341,178,399,376,977,706,896,869,865,140,360,145,637,6,934,803,271,430,48,841,260,16,503,287,276,907,245,33,917,798,15,867,261,632,766,420,499,674,992,999,63,625,465,698,761,204,79,719,136", "680,130,216,146,236,966,512,959,843,753,817,243,647,913,496,313,473,831,961,355,696,467,737,984,501,384,621,884,825,218,424,582,571,117,569,449,116,434,626,324,737,752,943,705,816,974,62,622,224,349,584,932,997,934,521,651,522,279,213,501,437,410,718,864,230,734,564,499,822,65,760,806,126,442,957,930,746,540,777,104,158,4,63,551,320,85,905,861,348,102,133,137,267,711,308,440,108,229,564,839,818,887,537,178,655,621,905,494,632,776,63,287,785,783,6,204,179,317,939,186,2,329,398,230,545,328,67,947,547,810,216,656,509,70,337,254,73,597,988,200,499,456,206,165,375,918,106,357,544,217,597,798,759,474,774,605,785,430,218,616,927,589,468,108,354,956,23,81,80,535,892,75,273,191,217,107,958,934,876,408,66,806,776,894,805,917,99,794,39,501,452,5,154,866,8,928,682,401,472,830,441,852,792,985,456,841,666,604,142,499,250,322,928,142,713,582,476,997,561,953,666,946,149,169,1,291,81,579,228,234,66,976,696,19,959,674,5,762,551,771,960,965,539,328,229,481,53,598,17,291,228,560,47,960,610,74,295,771,936,737,856,804,813,458,141,408,655,347,725,441,12,94,644,666,484,323,506,410,105,685,264,224,946,446,964,199,322,975,318,537,503,369,613,140,498,533,759,20,752,257,635,557,987,466,886,683,28,286,229,234,926,847,574,335,759,522,30,667,319,398,436,675,821,753,652,172,846,0,463,42,186,57,601,795,622,651,6,88,977,505,983,305,596,982,728,228,597,475,878,348,930,559,592,484,653,525,667,670,198,301,791,639,103,508,434,420,368,839,701,492,375,884,391,366,899,882,559,670,756,260,113,111,816,879,667,280,643,980,289,339,26,680,455,56,456,47,639,205,610,893,278,80,510,294,899,253,661,132,653,41,869,96,522,402,554,968,429,731,571,917,625,359,233,39,921,568,265,89,970,708,789,809,741,14,253,584,872,366,454,544,59,914,349,217,994,85,672,33,573,964,179,462,585,968,260,804,404,504,103,214,313,741,944,572,87,134,295,851,626,628,432,688,162,400,377,219,986,553,140,759,495,181,954,753,90,788,253,291,627,641,957,265,282,676,814,445,657,801,173,616,784,834,447,213,441,1,70,599,970,995,71,851,152,623,987,876,536,70,694,469,47,834,284,114,505,392,639,80,658,523,60,497,806,124,194,348,787,908,91,518,783,188,235,159,128,160,935,603,739,230,526,754,729,96,427,860,303,667,240,97,49,387,162,663,360,600,441,760,125,454,672,958,188,643,461,5,476,241,371,412,892,654,931,543,897,970,756,174,821,203,117,348,781,665,40,799,585,908,956,571,269,82,561,106,263,370,456,426,320,539,90,448,45,912,50,671,541,636,771,956,596,891,127,899,576,690,955,974,567,107,187,401,950,718,161,769,579,86,802,809,226,823,932,83,618,806,919,829,578,403,181,40,508,803,256,521,56,125,379,370,914,769,777,214,207,214,150,885,38,681,318,557,868,701,898,83,844,176,545,475,800,315,454,971,589,916,736,874,297,840,178,944,379,755,498,371,178,959,618,705,626,136,427,886,864,635,85,672,241,754,312,66,48,632,415,274,59,730,192,266,488,546,370,228,128,153,203,627,55,88,866,70,863,142,403,174,866,462,962,321,412,945,653,377,653,241,486,243,158,16,738,419,306,653,894,265,143,65,705,737,403,590,935,188,987,902,222,241,420,897,944,276,492,451,944,532,433,78,781,747,734,521,518,234,15,636,607,112,240,316,303,503,600,973,393,460,334,913,256,793,419,399,581,987,425,953,888,168,356,113,908,606,426,607,353,266,150,319,93,708,77,64,568,429,378,403,851,47,691,520,565,99,624,552,874,132,741,189,150,742,932,915,236,618,134,360,146,831,842,116,378,52,494,815,262,169,505,336,254,387,382,227,419,428,777,51,720,921,35,96,881,852,154,719,322,918,787,30,204,186,879,841,755,235,415,783,891,190,71,361,770,501,682,924,758,133,985,890,957,179,372,792,698,280,365,350,896,849,190,149,355,904,24,428,807,272,28,108,255,727,435,757,767,55,751,31,727,234,982,587,762,371,495,89,721,904,891,381,244,23,118,665,518,78,906,38,558,536,661,281,396,250,569,694,944,213,379,639,221,270,928,730,921,185,618,237,935,135,292,367,40,579,846,759,638,361,427,890,975,377,792,438,202,917,434,484,284,835,205,239,635,750,468,411,340,25,50,250,282,83", "374,680,324,568,324,191,335,67,213,833,466,104,143,262,894,567,881,271,881,200,917,290,674,629,410,247,743,902,232,149,391,808,113,704,388,534,966,930,379,775,484,863,38,768,371,881,397,944,229,164,800,73,339,419,506,306,543,425,343,628,426,468,304,32,554,680,439,145,28,101,986,12,200,721,215,329,853,977,548,126,133,111,649,718,831,290,915,3,514,750,859,661,215,71,311,414,125,76,813,429,16,572,676,134,660,931,728,483,426,524,652,216,758,985,456,887,221,71,872,465,448,706,618,800,153,305,52,604,866,474,148,590,124,591,157,79,718,180,350,972,694,129,148,466,441,303,853,361,275,469,240,922,246,205,925,298,767,2,669,469,284,133,732,326,489,350,352,878,494,214,464,559,756,931,266,581,244,482,745,128,350,903,625,7,147,918,151,751,280,374,804,695,292,82,839,643,107,85,810,135,983,900,348,93,847,689,148,497,60,538,359,779,452,931,654,88,10,895,803,379,698,866,833,229,659,969,944,352,176,289,143,400,295,341,558,968,733,337,975,587,438,211,260,903,710,488,103,654,641,671,17,580,437,229,301,844,161,144,433,603,757,705,593,542,16,94,72,673,587,932,86,701,561,190,643,9,168,657,393,435,549,136,23,62,298,605,8,427,952,893,826,156,128,551,151,275,66,442,938,958,341,37,494,233,960,21,741,351,418,668,380,488,858,915,932,54,581,707,152,601,350,285,160,449,194,92,801,463,0,893,782,197,133,26,969,803,636,13,927,975,112,802,801,9,435,832,845,267,158,535,766,600,649,392,528,428,857,697,290,244,609,752,346,100,348,986,712,367,152,824,327,767,191,895,858,705,388,520,688,122,999,934,137,535,373,166,52,457,779,904,776,202,866,979,199,115,998,836,309,633,341,814,917,664,549,548,662,492,157,32,633,152,4,928,90,594,294,597,688,656,774,650,123,738,803,884,129,801,819,233,480,462,694,441,292,497,44,451,419,790,742,147,421,595,671,137,934,686,308,6,112,537,242,30,437,710,986,974,789,784,566,875,873,44,824,444,121,966,369,896,916,640,245,451,734,514,636,632,467,291,194,376,859,925,271,274,915,185,84,395,465,67,191,837,332,622,152,438,601,932,348,744,252,20,106,39,769,3,255,340,616,643,828,142,297,268,602,241,295,670,525,919,58,135,920,377,521,621,333,987,446,503,988,222,504,178,371,69,956,601,611,637,938,391,660,427,936,387,246,393,824,91,811,72,837,20,406,787,620,116,690,150,236,945,880,84,349,239,846,746,647,839,582,584,333,647,681,659,644,598,178,401,428,277,966,719,156,485,821,635,404,584,542,640,996,46,907,498,940,458,223,530,654,337,924,943,930,3,727,984,136,104,10,535,124,761,955,869,566,403,844,664,809,877,651,441,738,648,588,850,255,981,639,564,593,43,339,803,877,167,873,424,391,440,710,908,253,630,952,575,921,143,775,584,451,206,571,967,117,291,417,24,589,246,931,463,457,920,542,930,716,844,581,868,266,659,939,157,58,17,312,551,840,817,321,510,469,117,677,899,890,147,151,250,670,131,708,203,23,326,620,829,55,858,570,889,554,888,358,727,703,350,964,164,679,337,23,151,717,146,159,618,223,325,859,912,529,330,483,588,692,660,392,413,355,870,301,553,160,469,221,431,310,521,141,728,494,165,834,360,11,236,478,81,448,662,400,332,358,755,834,259,76,619,697,223,611,474,943,693,546,128,100,822,874,808,95,423,634,995,1,841,410,178,155,353,462,617,406,763,948,14,135,270,686,238,967,684,623,124,787,345,677,465,600,335,879,646,872,304,528,920,232,474,897,910,458,493,343,567,276,943,212,353,680,490,224,889,691,828,616,987,89,170,662,804,162,453,11,778,467,485,295,65,452,198,435,331,298,192,55,528,909,10,343,481,881,219,32,419,776,134,992,117,969,971,550,574,555,784,377,360,146,828,987,558,561,576,985,523,516,981,642,705,835,167,881,109,860,483,482,933,727,651,785,282,530,17,758,889,180,467,813,691,412,161,727,218,486,852,561,138,438,135,524,737,9,168,995,93,835,310,893,244,226,696,985,761,580,987,75,943,887,134,337,325,800,894,232,943,208,81,751,359,22,930,643,362,866,415,82,940,734,965,960,207,203,906,652,324,65,851,926,778,615,67,301,737,388,101,357,857,139,659,575,195,438,681,990,565,641,805,951,173,566,491,540,56,730,34,559,796,780,934,66,229,465,628,308,783", "473,535,839,159,201,610,850,655,731,627,633,153,726,21,901,850,905,203,976,527,56,974,471,65,200,965,119,523,424,695,169,505,530,411,514,81,870,896,392,212,620,354,311,958,490,835,723,670,189,43,453,790,694,887,688,342,644,222,28,694,570,251,176,753,392,821,976,44,144,240,940,845,829,55,660,485,253,681,120,29,402,947,484,169,254,301,28,913,149,438,697,947,714,678,300,975,369,635,799,503,714,665,160,645,757,204,464,913,250,846,375,196,474,467,513,671,992,135,344,558,781,334,961,787,820,627,122,27,492,239,886,192,317,72,576,834,814,844,843,775,651,323,539,621,800,45,470,36,885,439,944,62,355,637,895,890,301,81,771,275,813,213,729,677,213,639,418,917,616,296,328,941,695,41,925,415,864,367,857,692,172,169,704,53,114,710,581,66,538,152,857,841,818,331,14,716,966,921,9,628,324,94,449,910,870,371,779,388,292,512,440,666,16,683,799,566,795,240,188,631,288,140,784,972,114,619,712,432,96,275,563,75,833,238,866,671,189,97,284,861,939,433,624,277,309,825,527,20,746,496,278,383,299,693,217,679,558,189,871,450,986,570,135,116,33,298,911,119,662,31,170,542,588,447,812,649,533,837,538,963,928,479,865,410,967,514,286,378,616,659,161,396,5,721,170,164,443,764,113,63,45,853,915,112,961,315,690,272,724,613,271,510,134,248,716,154,828,883,750,704,937,723,356,934,391,519,49,42,893,0,72,221,765,129,588,846,190,246,991,445,171,836,411,320,770,999,704,778,401,897,678,325,196,915,978,56,839,915,53,167,974,592,929,294,896,69,746,879,964,396,260,39,963,239,977,603,914,759,331,481,472,136,356,237,779,693,371,852,620,389,799,956,524,559,725,976,824,447,297,289,995,984,191,405,426,778,168,373,721,485,438,21,664,359,315,884,487,689,287,911,135,120,180,674,58,842,855,484,146,485,315,674,439,543,733,451,367,805,318,214,550,452,172,696,646,793,949,304,593,246,197,849,302,452,272,2,50,583,149,976,520,843,849,500,242,79,38,345,178,530,933,815,425,454,410,189,580,941,995,774,653,48,433,739,105,787,946,515,263,449,724,309,601,860,341,683,282,358,634,695,669,522,822,234,833,126,813,681,716,467,514,64,730,947,419,812,821,10,599,971,964,552,676,84,551,475,376,872,740,297,945,351,162,794,396,715,936,912,23,70,279,880,32,868,330,33,668,936,358,65,738,545,787,945,660,498,490,464,137,594,897,842,833,538,672,428,458,655,509,187,166,885,110,441,930,724,838,753,132,532,634,627,135,524,751,498,929,77,502,446,488,279,107,758,13,797,684,304,129,350,658,442,941,576,3,718,530,334,923,753,979,29,933,561,67,949,872,571,176,37,588,223,658,598,747,94,751,228,655,946,391,789,537,712,937,753,377,100,706,972,415,217,282,950,756,177,349,110,707,376,877,676,610,322,935,81,945,578,335,50,560,666,574,258,211,910,737,995,863,554,90,895,404,569,407,236,270,682,970,798,776,54,867,891,63,710,3,659,946,629,946,612,286,515,942,966,471,881,880,859,853,148,654,480,209,856,837,310,464,511,473,639,416,273,965,667,997,150,369,481,33,527,16,450,400,213,172,400,449,79,28,447,309,875,498,225,760,618,868,999,619,632,12,281,294,789,320,936,622,611,814,7,534,854,830,53,211,964,754,757,883,114,5,321,190,128,212,13,363,657,808,129,816,232,343,360,896,765,101,81,441,664,328,63,622,374,459,733,604,693,714,518,6,139,590,872,495,539,318,267,246,811,762,962,465,361,355,579,559,936,931,130,547,812,223,178,909,17,483,535,537,184,372,138,803,85,490,336,843,778,309,502,776,215,676,374,305,801,8,37,29,121,286,603,748,776,897,827,821,630,926,62,830,276,228,937,103,569,676,377,244,452,575,51,905,569,353,847,779,56,823,250,385,271,502,159,858,401,718,492,648,957,842,961,10,549,350,980,170,37,355,859,729,283,708,242,62,738,865,494,268,39,392,248,238,834,963,847,497,871,729,178,663,919,393,842,664,84,775,465,707,606,610,58,957,473,952,187,45,323,604,120,803,9,624,572,456,319,13,502,372,222,691,467,721,406,342,720,48,994,215,792,514,812,781,414,492,987,195,104,43,12,12,105,885,72,806,251,721,204,205,202,879,595,396,420,195,416,521,782,1000,492,963,458,494,435,765,731,760,992,725,374,5,68,717,152,554,171,835,834", "372,881,723,209,96,786,182,926,440,620,222,296,114,141,147,609,668,679,908,490,705,362,474,2,510,283,701,494,107,874,502,641,624,212,238,9,620,850,514,427,937,981,59,9,251,551,40,415,424,246,434,543,658,541,462,72,627,189,184,744,914,804,996,155,685,468,32,99,762,227,736,488,3,900,135,499,783,928,34,439,601,812,443,666,166,159,570,33,540,431,447,927,415,291,120,207,949,754,465,926,393,964,801,799,13,445,37,738,317,311,899,652,850,926,825,351,23,553,816,796,709,100,926,209,257,664,839,998,990,226,862,464,528,746,59,698,138,523,752,992,352,388,896,278,683,287,549,332,657,195,542,170,714,911,505,312,554,297,810,425,977,421,821,579,272,310,19,121,18,474,33,580,460,321,53,572,102,82,837,746,965,376,107,455,400,896,172,44,703,435,41,186,814,494,610,438,163,176,761,641,177,792,814,185,535,174,477,733,110,440,914,496,411,876,481,763,758,959,851,812,773,406,197,985,454,104,91,722,743,296,366,559,684,105,468,596,762,792,253,186,919,89,332,934,295,910,494,522,608,790,701,177,160,340,903,42,270,265,946,670,857,562,425,177,819,333,932,753,275,882,556,190,807,515,118,681,904,927,392,703,423,575,917,409,170,766,708,83,479,931,253,7,515,331,709,151,660,635,611,203,800,321,679,171,186,349,97,517,985,988,30,398,497,631,683,371,953,246,752,12,6,439,455,549,773,640,241,186,782,72,0,388,790,942,738,147,656,294,314,839,107,128,924,781,864,529,123,45,435,593,572,284,942,461,319,767,257,646,565,214,640,272,877,658,511,879,285,217,30,398,106,102,710,633,454,96,749,713,152,66,193,227,86,960,984,396,689,744,115,415,389,67,935,131,585,111,519,238,200,146,992,702,57,642,712,588,14,862,997,19,324,738,32,444,234,385,414,647,822,780,850,453,449,225,975,565,68,309,694,264,841,705,673,134,840,705,709,997,513,68,107,337,943,719,356,431,748,489,377,609,915,601,752,166,866,390,939,279,277,836,369,235,498,153,718,989,376,268,864,320,698,996,213,684,794,312,918,151,393,329,322,957,963,635,548,260,132,177,501,250,467,892,314,669,380,320,585,105,776,872,912,852,359,653,184,907,3,693,475,122,597,670,627,637,906,848,842,823,660,344,558,4,172,339,147,917,341,612,153,710,569,216,133,178,552,553,893,498,661,129,286,600,351,359,628,357,483,873,569,446,304,714,236,491,663,33,81,593,797,399,133,826,650,521,81,584,894,98,336,432,208,965,236,783,71,588,316,637,826,141,287,275,651,378,709,903,803,751,131,530,205,905,525,394,103,490,672,685,99,423,711,754,760,556,817,858,295,225,599,622,743,478,75,976,676,353,480,564,726,688,675,537,154,470,905,603,811,376,319,352,536,134,146,564,808,992,95,656,947,72,462,757,809,331,372,114,325,604,670,376,741,874,236,374,901,986,970,229,168,443,440,926,304,537,982,669,508,447,927,297,478,145,602,557,825,797,92,517,5,437,38,622,907,391,375,252,794,322,492,491,443,401,18,443,579,301,87,566,717,785,239,274,139,906,273,885,251,657,470,989,478,867,446,161,326,589,684,571,488,294,188,172,97,374,562,565,423,710,810,30,260,882,108,704,650,404,100,763,90,845,649,263,543,940,641,737,76,718,973,794,275,793,616,668,434,246,168,429,589,730,989,350,795,617,839,929,463,711,667,343,502,205,538,522,438,864,661,934,216,994,279,161,971,987,181,981,867,283,76,573,736,629,380,712,534,973,40,343,607,226,42,972,165,931,657,425,612,20,561,6,214,156,5,710,145,951,32,555,287,18,352,105,494,134,701,192,748,235,205,181,459,693,602,117,294,364,53,509,747,399,260,60,228,204,94,986,105,142,177,368,584,785,12,5,279,128,57,121,237,911,250,250,373,675,706,940,176,45,67,729,686,406,464,574,964,507,879,930,201,877,221,364,250,830,734,393,529,578,39,107,864,32,213,973,273,943,497,38,116,635,766,150,871,145,115,348,471,441,797,525,77,432,623,296,549,445,989,970,552,918,305,467,817,604,151,205,136,659,131,589,3,873,154,507,370,442,956,796,347,668,655,438,998,87,774,797,854,210,270,865,709,383,805,490,56,170,318,454,482,596,239,690,379,224,629,678,936,471,146,484,813,831,938,623,629,253,650,34,49,532,785,207,180,954,853,829,484,182,66,38,329,242,464,504,484,189,581,43,705,165", "607,478,259,243,373,661,404,355,107,407,661,149,183,764,755,254,984,271,415,123,64,48,742,123,348,422,275,482,799,585,230,205,868,199,678,506,533,358,114,480,229,954,190,929,208,747,977,497,448,111,411,88,392,391,690,932,117,191,827,366,894,124,657,5,450,916,198,746,325,67,43,748,911,367,417,579,987,86,933,356,854,298,301,147,692,429,197,617,393,362,391,799,609,469,924,459,105,54,899,423,571,577,774,44,321,729,225,525,828,45,693,164,612,568,122,196,811,712,505,262,871,930,394,377,769,721,880,356,591,574,87,39,604,171,522,102,288,141,735,438,875,478,132,705,673,695,285,495,19,922,886,681,92,907,789,553,453,4,151,689,842,949,715,595,261,675,206,923,627,178,162,375,335,702,962,622,302,41,370,234,580,514,374,171,471,443,682,779,989,473,618,271,959,800,765,912,678,210,923,345,325,400,909,996,600,566,382,354,376,378,697,141,359,419,539,654,588,332,753,907,660,392,695,814,264,123,313,464,822,647,996,855,634,829,742,985,171,261,29,213,801,87,700,92,769,763,613,163,982,9,456,466,932,355,585,317,189,544,537,77,169,764,485,840,901,376,134,100,471,791,109,774,677,483,598,25,649,849,150,628,612,504,64,410,656,69,212,922,790,767,416,584,713,428,34,144,905,110,342,691,87,480,862,318,114,483,294,152,942,226,753,945,309,832,398,851,788,307,722,118,202,183,465,720,609,398,47,57,197,221,388,0,544,916,714,431,471,936,479,774,291,560,954,907,709,577,110,682,132,798,713,335,479,304,321,57,889,58,730,708,332,506,826,799,795,423,193,882,381,797,246,579,692,696,115,706,413,509,201,645,40,409,431,5,537,734,184,96,981,173,130,299,891,666,58,177,596,123,119,450,730,548,257,531,227,235,287,56,312,487,155,27,364,389,810,400,509,725,925,915,719,919,56,107,355,884,729,673,525,885,786,675,633,569,366,570,772,920,732,849,160,100,299,106,562,291,504,946,66,293,790,347,793,896,696,170,945,503,400,833,197,630,311,224,589,935,662,331,592,888,157,343,28,942,906,600,798,78,195,704,452,691,259,141,570,995,372,51,641,323,899,688,190,309,122,238,611,67,949,311,953,396,40,254,527,870,399,343,721,387,989,539,143,642,214,99,353,7,22,833,963,744,753,11,886,930,498,570,696,169,235,604,523,806,171,117,522,529,823,679,285,766,234,232,377,671,502,78,832,825,861,170,468,450,184,630,803,205,182,28,175,821,275,876,266,26,814,809,302,293,236,675,488,270,449,802,745,395,389,937,126,410,110,117,823,936,554,697,81,365,295,498,866,750,702,156,184,803,99,736,594,512,962,984,147,34,789,684,943,651,560,887,357,593,714,282,701,31,938,252,695,255,278,73,342,729,864,757,749,816,926,197,19,499,232,795,110,996,796,516,314,273,408,97,412,33,278,298,328,859,747,352,447,864,855,209,486,192,307,277,526,883,929,877,767,297,969,581,51,187,688,335,242,2,871,652,667,973,871,860,461,69,954,4,357,175,527,690,51,182,453,274,617,6,326,815,407,992,235,317,264,493,681,788,637,520,906,234,235,323,415,641,433,397,397,449,189,129,957,891,612,210,742,699,858,178,101,293,147,875,142,615,801,349,244,443,790,511,865,353,393,787,154,846,677,756,198,123,596,647,40,830,328,194,154,76,584,224,973,203,590,876,278,678,629,429,223,533,616,802,105,165,303,430,288,767,427,532,585,301,277,828,761,207,685,653,653,897,129,322,333,300,505,722,257,526,203,448,465,541,289,215,698,622,236,68,202,314,239,868,246,818,98,473,815,655,419,93,645,514,166,898,603,433,209,437,548,930,797,474,466,994,285,77,598,751,273,722,619,187,562,200,519,44,587,277,810,800,222,253,339,764,352,499,795,617,151,503,793,527,683,501,23,392,709,490,383,360,944,835,964,131,236,337,454,715,225,180,262,956,376,666,779,920,687,898,472,406,921,762,75,807,614,335,671,206,875,643,746,951,723,276,207,482,530,854,106,829,555,187,471,62,675,446,390,688,37,239,218,473,792,356,451,793,205,675,239,42,908,951,638,275,468,197,262,760,606,286,464,542,662,612,75,717,410,492,344,643,523,645,231,959,293,605,881,405,445,615,498,132,792,439,163,483,249,373,343,889,575,530,702,834,721,486,402,280,627,628,875,286,869,245,994,773,353,812,726,405,352,319,216,591,274,458,385,585,210,838,715,358", "251,474,101,164,275,45,680,280,909,116,480,680,905,28,232,788,673,356,33,766,451,93,943,973,923,542,52,241,332,731,727,399,520,337,977,810,914,927,895,528,74,188,78,172,34,718,731,426,27,753,513,751,420,736,786,267,391,832,692,299,468,93,156,810,180,307,109,266,40,751,220,862,829,858,576,612,732,38,657,934,490,346,595,186,258,247,732,355,786,503,504,976,705,939,384,217,540,50,273,879,645,255,362,848,450,148,13,964,16,231,450,77,322,643,984,651,713,762,185,802,179,488,911,36,774,855,8,941,371,463,353,175,745,655,252,660,420,198,409,801,612,799,967,803,191,694,687,347,146,799,248,649,191,939,465,862,17,697,779,532,346,655,450,380,584,824,147,187,396,973,700,66,62,764,486,981,190,29,362,475,187,690,170,819,338,265,305,545,196,234,776,248,377,685,554,900,902,162,498,129,764,395,905,474,350,363,968,800,532,516,604,778,780,77,304,141,959,359,578,474,806,238,11,305,619,849,44,66,597,26,227,915,393,666,853,692,738,954,808,437,317,434,734,36,466,745,688,614,140,933,631,794,290,939,140,494,902,84,698,232,760,470,859,693,205,133,501,735,473,127,396,652,885,205,982,61,192,468,875,972,521,153,987,682,531,538,224,634,442,129,292,372,431,241,547,750,127,929,377,286,835,997,616,86,914,321,76,891,441,213,445,581,400,956,744,415,387,778,163,693,93,491,489,558,595,759,28,601,133,765,790,544,0,290,625,425,799,385,699,747,563,577,731,905,666,53,927,218,653,727,365,545,472,715,405,611,839,147,199,209,290,270,736,594,264,771,853,139,771,71,833,633,256,430,136,992,996,927,938,169,615,379,348,754,735,434,440,853,886,325,569,876,887,542,701,321,41,669,41,466,717,243,566,481,159,113,850,986,759,769,297,31,394,804,856,446,793,290,758,641,403,576,919,401,780,383,971,851,39,579,873,180,367,115,247,789,268,138,237,835,316,575,340,408,172,175,21,872,153,654,175,261,171,69,620,241,623,120,614,572,51,100,635,73,95,971,793,378,62,579,659,76,48,552,59,251,5,716,779,594,898,119,469,439,469,60,782,935,706,834,724,412,384,840,636,377,994,587,744,444,324,981,16,539,303,416,120,861,722,680,182,953,81,895,962,381,225,887,83,668,543,576,197,563,94,815,731,848,14,72,949,269,979,864,175,43,998,1,295,449,922,713,985,319,191,396,248,628,509,313,890,184,673,723,985,994,995,638,581,133,402,102,224,366,620,554,344,740,109,886,440,591,108,978,95,950,476,493,975,443,612,389,922,58,868,451,541,760,628,227,925,437,595,746,941,147,229,995,405,977,974,680,851,599,884,320,722,594,53,707,419,402,431,464,363,114,465,327,951,485,778,341,598,882,985,287,816,331,648,35,905,594,85,385,226,149,789,440,300,764,227,527,143,80,491,274,695,4,730,602,533,44,411,888,73,458,328,253,560,912,590,939,504,967,824,694,683,14,49,411,677,329,316,197,97,771,952,900,223,947,712,217,770,600,913,236,261,270,978,1000,770,131,993,312,281,731,959,434,189,129,75,519,456,295,689,739,268,365,93,460,381,375,68,277,401,24,585,531,270,156,248,463,377,450,29,165,57,758,875,730,283,830,487,675,388,25,463,957,57,557,306,61,803,398,797,654,465,216,504,946,767,136,823,748,481,213,689,959,148,197,606,680,51,483,552,528,857,637,731,279,480,717,109,657,979,839,570,8,706,17,951,642,729,380,395,655,175,647,838,175,51,276,830,671,560,477,466,677,396,442,395,31,973,671,870,696,763,567,609,162,39,401,944,988,524,683,658,291,504,249,381,858,394,737,275,846,550,639,658,920,947,181,626,883,875,57,237,817,34,481,571,856,578,390,671,736,698,700,390,189,701,582,113,794,564,741,285,718,520,560,273,221,575,374,537,534,145,661,441,815,763,622,829,735,176,73,482,690,687,847,199,358,25,675,324,667,818,688,786,138,3,166,429,661,737,620,644,150,653,685,116,282,606,325,212,211,722,895,400,837,860,881,626,578,647,649,544,514,921,604,776,872,478,62,586,825,151,832,702,561,288,44,249,303,26,84,51,580,615,428,424,605,436,287,592,601,299,217,387,591,9,528,484,305,988,789,214,136,259,548,207,857,749,334,611,855,189,800,154,344,171,803,571,343,556,666,16,65,335,53,764,881,409,15,191,836,894,763,891,82,628,637,358,65,551,512,928,461,736,377", "454,541,875,575,738,108,529,663,448,261,560,654,195,221,433,711,348,340,265,537,425,861,372,465,437,124,517,552,867,441,813,607,285,741,989,628,414,934,574,584,827,488,224,99,327,705,652,319,308,969,847,233,354,346,897,563,870,121,415,12,66,529,611,449,129,743,310,662,244,20,232,483,932,370,744,529,618,858,562,335,439,254,329,664,499,215,258,722,221,806,835,310,269,262,697,588,43,925,158,803,764,311,780,5,258,692,591,229,794,603,201,952,335,972,586,595,519,118,347,29,195,223,876,241,693,143,707,129,230,892,456,809,379,980,562,479,204,286,242,363,766,83,512,263,353,179,278,63,62,965,67,933,917,962,382,70,610,989,378,711,493,948,206,29,274,780,326,913,454,582,591,377,578,851,986,891,671,587,753,347,708,193,341,488,430,912,996,870,522,912,422,337,605,950,102,157,782,869,263,418,106,481,207,591,78,363,769,185,11,143,973,75,897,27,163,224,753,866,197,708,912,510,802,406,9,144,404,316,389,624,655,731,825,348,636,797,856,61,217,441,564,107,590,43,946,535,670,117,926,773,658,258,197,278,156,764,500,772,78,730,657,513,624,30,754,186,438,248,125,961,388,844,195,213,88,449,765,414,994,729,64,863,714,381,55,297,580,412,97,43,981,234,209,98,805,845,994,853,724,579,825,377,487,194,474,229,298,403,433,474,823,712,214,479,687,448,929,585,822,38,100,230,63,272,744,674,320,795,26,129,942,916,290,0,546,725,584,310,287,154,330,648,648,494,703,6,172,391,855,389,909,127,561,204,451,54,203,303,904,837,488,654,703,782,254,525,428,692,180,547,62,598,516,168,544,80,740,241,836,701,264,529,28,639,137,9,510,374,599,380,32,506,758,533,273,623,855,726,715,738,10,208,288,966,753,962,296,987,558,239,671,439,80,352,629,211,725,228,685,53,172,95,301,48,490,182,508,357,816,851,76,429,731,508,931,80,538,621,92,80,466,124,608,416,23,312,530,185,207,775,550,460,647,487,640,913,950,686,872,402,4,557,3,458,469,234,605,876,833,583,678,678,388,607,251,176,500,569,997,376,790,845,255,573,960,774,546,191,230,763,698,943,425,667,212,562,982,501,147,426,771,81,238,957,763,504,672,61,349,221,737,610,344,647,495,442,256,439,258,797,835,871,114,6,703,341,971,674,361,884,673,695,873,923,236,417,917,277,391,56,600,216,169,759,147,159,584,31,387,115,547,506,879,817,948,61,951,562,910,649,185,401,625,232,775,509,531,766,938,822,264,598,684,125,963,756,770,298,743,618,129,690,358,834,616,757,917,508,584,819,92,346,886,521,665,833,252,449,18,890,671,665,655,529,784,773,700,446,774,337,75,540,575,510,857,860,154,228,134,408,106,403,201,266,60,255,644,67,930,134,835,695,393,659,299,17,27,72,730,601,144,74,838,159,743,434,536,596,897,981,387,625,674,648,158,481,41,771,421,652,323,931,915,52,805,524,901,955,181,964,516,274,31,383,354,115,615,446,323,780,455,390,102,311,768,130,560,21,163,355,968,736,113,253,248,389,8,477,363,197,625,643,41,265,38,63,72,986,519,30,838,979,651,661,636,670,644,660,993,89,55,111,985,620,158,803,478,978,691,786,574,662,407,433,679,675,492,948,618,435,206,737,762,202,78,921,582,18,923,539,173,185,649,54,505,972,136,631,65,851,595,92,862,602,906,695,490,36,84,322,34,267,602,463,447,206,547,265,966,583,520,94,779,930,867,512,985,273,528,717,41,375,953,455,470,499,277,273,927,157,594,611,586,638,126,928,709,913,834,602,531,290,959,149,121,650,370,72,389,560,533,230,537,809,477,624,972,159,386,719,588,823,314,338,750,121,238,941,90,870,500,688,310,525,219,956,366,707,624,13,677,658,701,470,959,682,874,510,513,416,948,683,251,500,392,984,753,77,726,383,661,918,601,672,198,243,937,442,115,753,848,500,901,766,479,74,212,325,937,657,662,814,975,59,680,48,83,781,158,572,66,469,504,788,252,33,489,816,235,413,874,681,256,255,901,607,748,880,596,123,233,542,333,838,976,956,55,236,766,459,648,346,250,28,380,17,685,703,361,162,262,4,8,658,320,693,799,723,470,561,63,856,939,635,565,583,863,305,967,241,701,105,419,821,224,367,418,815,352,852,927,29,930,849,635,835,913,16,571,685,579,384,105,935,699,311,82,711,569,749,300,588,906,804,55,249,754,889,792,195", "718,522,823,305,567,333,297,80,105,421,181,304,554,963,258,811,917,756,542,109,115,158,17,916,939,88,618,410,424,458,745,439,478,942,499,304,989,105,15,79,35,144,544,163,176,917,768,736,242,566,332,515,58,887,55,795,938,295,608,306,673,491,586,761,92,142,648,669,773,625,534,639,921,851,389,731,220,73,945,901,491,527,263,527,459,786,946,692,969,663,729,664,282,125,514,565,277,651,747,302,498,603,856,498,828,311,856,699,306,994,882,155,312,341,644,890,869,198,220,518,356,534,851,926,41,819,471,14,768,844,599,836,199,539,610,246,745,970,857,713,431,935,835,753,984,843,278,94,779,80,707,210,104,502,842,607,904,613,490,954,904,277,953,911,656,268,57,510,913,637,967,166,987,804,654,714,331,617,654,409,459,589,575,478,536,770,373,177,284,446,313,946,151,908,230,54,874,741,753,846,787,10,287,810,328,402,256,718,351,507,735,887,962,81,406,851,511,483,500,878,433,959,225,586,708,816,585,504,49,430,57,775,749,630,971,973,626,83,517,156,895,960,102,281,403,915,358,47,235,789,575,460,842,809,569,967,189,862,408,105,281,908,789,967,920,481,253,542,866,494,496,635,970,930,4,883,751,188,68,203,327,516,237,319,732,812,420,171,832,132,961,416,291,205,885,851,148,863,806,724,328,184,708,573,809,248,683,484,232,843,111,136,814,335,964,629,615,192,105,835,871,216,773,428,127,133,274,622,969,588,738,714,625,546,0,359,86,334,27,808,551,387,715,509,200,695,948,270,561,23,215,210,16,865,133,815,544,791,190,623,146,616,897,373,401,111,810,699,11,733,706,410,831,499,518,725,39,577,534,831,537,244,455,618,313,632,641,136,280,641,573,968,473,323,963,843,211,331,421,456,488,717,482,483,696,826,942,357,869,633,563,781,64,32,711,957,688,52,690,185,914,661,83,936,251,148,215,300,989,664,661,747,547,215,121,566,599,303,154,188,546,76,587,888,485,244,526,624,399,501,359,950,206,591,216,109,313,713,72,521,384,636,903,399,981,841,786,394,834,187,438,36,629,722,365,249,212,333,160,45,656,526,266,490,783,590,887,324,667,67,947,754,74,223,296,779,305,169,562,194,111,566,502,987,831,870,347,824,313,784,26,630,356,70,847,23,264,178,886,728,472,636,176,532,576,138,420,693,142,805,870,291,997,74,459,434,975,841,3,702,669,158,397,542,792,293,400,779,400,925,835,863,691,143,249,814,290,580,100,955,473,239,474,955,531,917,453,448,192,547,858,43,326,595,225,758,732,437,115,844,510,592,33,791,537,699,269,874,752,909,399,368,692,95,557,244,690,722,638,390,855,666,306,946,123,749,295,70,216,155,365,314,289,960,480,494,364,18,754,227,316,161,749,288,65,112,361,290,25,456,605,249,657,557,592,936,448,212,533,441,215,550,591,276,658,252,908,788,795,470,534,947,473,109,637,870,714,870,788,916,585,885,475,374,954,594,50,868,259,373,127,256,491,181,643,435,931,204,587,144,283,716,739,427,124,792,457,280,731,317,765,728,806,903,187,323,61,539,574,805,668,847,64,384,580,634,479,681,596,716,417,132,871,662,682,218,273,879,431,725,786,237,610,511,205,351,303,298,89,67,846,464,877,612,222,147,755,944,508,182,72,116,944,420,688,863,411,364,851,613,970,270,379,352,10,386,865,136,710,972,842,326,409,609,810,477,439,624,584,984,998,256,821,940,357,336,843,829,88,63,346,779,92,408,321,144,901,844,676,67,969,478,838,864,271,809,566,446,111,343,447,470,829,489,480,772,964,819,739,353,659,3,231,46,40,662,464,75,559,345,769,148,934,861,92,179,193,310,390,63,24,59,801,534,326,687,784,457,654,938,268,691,974,215,242,537,784,884,244,7,262,696,688,82,877,2,74,80,477,814,584,411,410,88,707,543,882,285,457,536,633,73,452,988,704,837,733,9,314,469,14,298,59,883,328,353,750,439,845,556,514,675,244,231,398,132,499,302,274,704,147,314,474,522,513,676,135,512,561,701,431,360,627,819,662,970,608,329,654,452,470,357,632,439,165,885,544,637,617,69,316,749,926,343,904,953,91,485,807,110,146,176,662,124,158,924,692,239,631,398,904,715,296,415,355,599,530,934,76,749,496,640,468,436,193,487,927,273,520,491,850,60,774,768,393,192,248,209,244,927,452,308,871,943,775,855,339,626,57,824,599,92,6,577,364,382,766,161,758,873", "228,135,242,881,516,399,362,404,167,775,364,88,923,203,77,438,419,652,60,504,384,562,58,141,335,406,729,42,907,924,855,138,980,10,574,816,670,218,785,338,789,303,179,411,212,824,698,684,409,774,677,798,896,511,993,917,546,666,673,770,391,667,862,374,86,465,985,372,335,966,749,265,768,265,991,400,136,625,48,115,88,145,430,29,778,696,706,262,157,706,374,162,551,147,191,826,313,829,986,506,392,413,29,575,748,978,671,48,285,157,532,732,237,782,513,544,775,828,542,15,859,204,772,609,863,720,723,259,399,743,621,296,286,918,820,40,258,515,790,476,655,953,811,59,221,375,604,409,929,232,638,558,244,36,243,147,147,612,784,637,152,823,913,553,30,591,237,627,473,817,872,954,337,870,88,314,569,748,232,727,745,784,887,875,122,381,592,97,681,399,555,246,623,411,44,711,522,225,824,99,431,916,701,299,359,812,705,250,956,947,73,799,694,245,125,386,818,191,863,88,679,484,399,117,872,283,365,823,853,999,371,201,512,841,567,57,900,826,698,423,960,540,842,517,366,398,754,649,400,902,86,595,243,816,557,626,973,438,690,772,927,206,670,31,626,693,8,749,335,453,449,727,615,380,944,866,498,2,523,247,766,661,549,339,986,431,663,991,680,182,809,895,227,533,394,799,555,240,539,541,61,728,23,126,930,213,27,770,461,93,130,700,309,436,942,200,477,885,970,52,795,972,525,253,204,701,641,651,803,846,147,431,425,725,359,0,207,108,220,673,881,749,439,212,662,658,609,362,922,857,62,587,571,798,580,192,497,46,870,715,137,511,661,622,887,472,179,440,767,213,378,644,208,686,149,317,734,73,984,892,828,132,416,196,36,358,138,676,875,317,802,729,654,707,969,871,742,247,894,603,129,871,511,650,592,819,700,830,556,888,85,133,730,86,433,666,291,107,355,338,135,649,843,107,262,57,917,245,327,442,230,4,993,88,919,498,339,475,220,833,901,733,311,336,794,83,318,220,562,869,672,138,538,492,545,404,617,87,181,489,40,308,289,922,407,206,268,25,385,683,509,913,763,608,914,757,736,171,71,152,583,346,598,245,809,126,907,867,209,267,500,185,125,585,67,260,865,527,59,801,992,125,623,62,551,213,82,931,773,401,206,509,381,956,866,849,268,275,311,797,316,502,927,789,442,914,476,820,219,485,520,296,209,280,43,870,170,190,907,58,883,296,489,408,925,388,63,251,792,487,133,37,107,239,201,825,357,147,524,997,747,126,115,805,226,532,396,975,437,874,913,605,812,491,89,178,278,908,807,788,493,92,854,20,606,554,736,665,848,385,974,387,361,946,478,414,727,153,265,513,851,125,457,367,45,613,944,153,409,579,540,750,720,440,128,460,974,855,852,622,595,458,593,769,197,101,514,186,931,350,827,266,923,290,74,122,906,134,515,485,45,902,983,16,942,488,292,455,801,920,946,544,869,756,38,418,780,273,877,603,666,747,272,905,994,182,671,380,228,718,819,711,161,878,168,597,806,897,99,704,739,699,415,983,760,948,262,343,644,463,295,405,703,326,265,633,143,173,504,738,103,737,847,786,928,492,377,130,798,423,945,528,386,643,503,415,74,589,409,910,92,742,818,177,862,861,855,142,605,240,334,261,92,30,499,676,736,449,566,727,550,912,61,166,637,11,233,208,316,883,819,698,380,499,714,998,149,169,510,737,972,757,324,727,573,114,634,102,711,224,597,554,142,615,769,27,988,995,453,459,492,3,204,627,63,911,302,122,293,782,833,523,510,711,333,863,449,425,160,516,69,607,851,496,327,794,190,69,338,649,975,763,336,162,47,821,325,22,315,141,278,228,708,933,597,940,377,166,657,888,976,899,196,992,356,756,935,19,437,418,753,524,722,932,444,635,25,393,49,296,915,762,589,528,849,606,598,271,522,766,33,705,171,793,255,923,633,348,45,813,855,639,552,222,404,649,215,230,905,605,461,166,761,674,573,879,82,85,280,953,172,931,123,258,317,20,479,71,583,661,244,462,99,745,189,962,159,483,834,689,848,891,665,417,903,491,853,942,21,520,548,614,880,667,416,469,499,178,275,517,573,784,443,195,414,640,324,508,369,654,498,61,136,132,445,23,656,630,724,873,918,222,954,577,56,909,139,763,739,309,300,417,296,265,952,881,15,112,2,184,434,967,389,855,352,905,299,539,808,421,237,724,774,901,12,197,109,123,330,734,371,392,255,935,502,865,488,147,663,773", "252,163,809,528,698,371,801,474,971,292,52,529,626,50,772,183,322,323,148,947,932,223,611,534,672,255,777,645,274,606,109,354,276,63,336,563,149,673,373,425,581,599,984,619,578,908,485,599,212,757,105,633,336,340,650,702,99,161,978,507,297,69,813,925,914,551,627,790,919,91,855,673,67,298,379,485,129,924,366,41,712,176,671,924,416,380,925,749,533,783,689,243,818,773,798,60,128,302,216,440,919,953,513,664,68,938,473,504,653,551,101,802,639,497,45,655,959,311,559,785,293,843,684,579,261,469,174,68,212,251,220,490,692,490,656,268,193,869,339,602,936,422,97,453,228,688,944,244,289,126,273,171,921,51,609,835,699,638,134,198,218,5,811,787,380,369,774,209,952,227,554,190,254,823,191,826,457,661,688,65,680,345,384,825,868,767,160,458,962,676,106,323,412,988,354,166,54,386,604,165,463,650,275,257,249,340,454,752,53,815,360,781,735,873,859,722,384,751,304,322,920,897,486,576,125,24,51,2,940,145,926,893,98,909,697,303,488,520,292,800,940,915,702,590,654,211,352,489,275,806,921,955,201,152,271,916,822,544,751,60,799,659,652,308,844,913,784,915,339,269,701,911,453,634,212,327,986,39,876,889,25,295,780,943,898,72,267,477,753,166,581,689,402,883,171,986,891,186,222,133,381,955,353,206,811,265,540,508,763,1000,880,127,751,705,857,87,611,316,824,855,675,941,836,212,663,729,715,6,636,190,656,471,799,584,86,207,0,152,532,843,213,448,714,348,126,50,251,715,287,593,200,313,32,171,859,216,429,837,587,991,641,755,271,281,680,582,6,118,692,632,671,231,626,416,577,360,851,985,490,265,925,721,308,927,259,216,825,741,796,95,226,783,721,423,186,338,478,137,72,150,707,275,38,301,80,956,889,552,747,294,248,866,69,15,661,224,641,140,181,316,1000,673,985,935,639,606,750,238,552,96,484,717,135,333,102,244,23,875,204,110,901,331,712,558,40,808,264,566,455,355,99,243,714,433,413,14,131,191,861,243,72,179,49,545,884,775,973,751,79,923,157,951,189,700,344,289,341,534,592,480,459,145,886,241,809,964,555,76,556,141,658,626,672,826,791,457,597,155,760,418,748,141,605,621,973,909,370,955,292,275,867,905,173,116,266,698,112,347,60,395,9,791,939,627,982,6,486,243,561,905,505,54,661,443,98,675,899,638,135,31,208,730,781,730,996,438,143,767,105,948,350,802,688,557,291,252,36,698,180,204,793,232,911,903,933,397,419,949,3,350,450,865,823,193,453,947,916,808,155,949,79,845,861,858,253,278,810,599,625,751,31,854,399,248,944,658,886,730,374,312,856,378,753,431,703,757,735,850,103,882,202,204,336,759,724,696,444,899,940,630,565,861,246,901,429,786,860,713,637,451,785,890,130,360,721,760,658,976,466,395,559,217,278,40,937,169,183,208,595,528,474,383,14,969,768,459,647,883,318,906,960,425,283,428,603,933,924,566,741,629,811,204,499,558,349,833,675,557,244,350,335,699,923,195,166,348,139,517,302,632,57,517,470,788,932,637,930,595,538,504,992,843,857,5,360,830,260,457,4,327,188,211,246,147,172,652,74,947,41,808,269,61,154,633,488,967,868,250,510,741,787,242,232,485,205,438,143,671,800,277,937,207,257,731,554,723,785,460,192,482,871,809,882,43,603,29,781,334,206,21,817,645,137,32,513,678,199,41,347,374,27,886,325,193,905,867,46,396,881,252,784,246,862,682,423,466,788,877,315,280,433,800,908,45,460,681,68,542,801,171,879,597,502,586,480,500,320,147,325,877,567,604,29,189,957,526,475,921,453,875,27,358,511,210,11,707,899,936,177,299,20,604,511,113,304,204,921,534,660,16,156,154,34,411,768,539,160,290,74,446,700,308,677,44,681,863,238,150,685,265,636,695,867,756,695,443,993,624,71,258,31,920,862,892,444,969,997,932,260,816,41,367,966,35,82,350,717,724,665,347,885,493,169,503,712,987,852,649,229,476,355,381,799,63,697,888,40,855,18,80,571,983,372,361,482,484,499,588,509,750,22,491,176,310,730,488,327,636,739,989,18,855,495,377,493,297,519,941,161,187,435,511,392,354,738,470,758,728,639,674,910,320,16,868,111,187,37,140,174,488,6,128,470,166,17,586,520,510,466,35,201,958,142,747,752,907,486,362,137,354,622,794,60,683,180,673,891,255,86,602,237,329,602,257,436,117,241,714,613,242", "116,180,249,618,89,971,53,647,462,441,213,72,181,354,142,294,258,849,427,537,751,443,142,376,379,926,228,10,805,592,563,836,447,613,78,957,404,794,489,874,358,328,988,28,242,286,725,569,109,762,413,887,224,513,174,965,11,365,725,679,913,174,484,712,91,784,995,939,27,973,756,918,764,736,161,522,826,873,935,771,907,186,990,426,694,271,16,390,711,577,86,281,298,527,720,457,341,719,819,966,535,644,759,157,494,660,260,420,623,264,461,920,833,284,953,129,693,830,413,805,348,31,504,623,57,808,373,444,319,927,705,434,588,680,897,511,746,49,627,524,894,410,254,657,159,764,741,64,161,120,848,887,834,305,255,872,151,531,390,40,995,279,892,201,341,641,979,8,655,474,830,954,605,408,696,916,609,719,206,455,74,57,248,648,491,250,222,174,285,705,975,749,882,878,304,897,313,663,597,646,390,578,612,319,350,493,653,229,377,522,43,912,696,796,30,276,21,439,25,957,465,358,828,598,265,241,647,958,77,591,703,385,995,717,211,996,940,384,291,463,985,401,818,576,1000,725,995,127,580,859,827,366,121,512,718,217,590,387,178,927,541,306,484,211,756,216,996,411,150,382,163,351,782,102,36,323,827,390,410,999,943,127,386,636,857,231,797,188,152,594,658,860,633,6,776,874,338,417,268,301,139,846,804,192,824,126,737,297,165,333,668,533,103,578,772,270,851,40,766,811,766,185,960,380,944,781,457,88,13,246,294,936,385,310,334,108,152,0,223,33,721,860,662,819,522,63,641,875,789,600,472,636,533,361,984,642,857,352,457,477,169,371,145,348,435,899,179,291,858,437,681,477,825,75,450,443,366,694,139,435,861,854,114,333,524,742,850,449,829,827,739,314,917,773,90,682,315,529,344,601,404,815,77,212,364,901,117,498,92,667,237,749,741,745,77,906,34,274,257,421,260,966,424,291,133,923,452,970,904,152,893,825,518,714,163,255,538,2,411,886,417,891,579,770,563,131,274,19,89,8,107,889,227,604,853,224,963,716,286,247,497,683,435,487,230,961,372,403,954,874,409,56,858,68,303,57,83,670,834,997,974,885,625,775,613,340,39,725,770,648,410,374,796,391,45,590,28,479,452,107,24,755,594,292,298,484,568,629,313,583,346,930,768,990,786,542,317,621,179,236,155,68,917,61,379,594,794,48,910,652,45,638,604,676,522,702,324,891,910,902,987,433,4,534,407,100,548,120,900,28,832,466,29,825,197,859,536,713,654,875,166,375,127,962,944,812,766,445,103,352,750,222,456,733,740,415,532,596,106,831,107,356,370,326,616,358,844,363,466,872,861,296,606,770,189,157,551,612,354,31,419,21,890,447,771,535,742,189,198,55,594,100,380,304,77,24,483,5,705,372,358,916,101,711,641,180,392,428,126,813,278,935,754,835,825,168,382,641,797,905,506,51,613,662,83,483,219,160,130,927,717,85,171,707,282,716,194,104,233,900,737,913,408,101,877,778,799,791,40,618,392,562,321,766,146,161,669,992,322,456,739,324,7,660,794,382,229,640,836,361,65,125,724,959,269,589,139,741,512,541,866,704,18,70,650,128,174,410,771,903,684,486,58,460,427,678,307,314,86,76,861,483,443,70,138,921,547,746,379,210,39,316,483,946,149,230,879,32,614,440,662,539,948,869,218,288,984,730,128,39,742,31,838,786,636,301,78,354,601,995,860,329,548,616,847,90,26,80,465,550,769,446,4,453,72,379,800,34,341,558,949,958,82,255,993,180,433,954,723,388,546,19,802,518,881,85,765,729,912,622,828,352,879,730,455,335,928,989,805,669,854,21,170,209,927,939,644,525,970,607,700,764,824,137,889,304,174,766,402,88,521,537,624,467,78,72,994,734,360,179,216,837,271,355,450,419,158,946,26,734,821,287,562,986,592,776,735,18,136,861,906,345,429,917,34,785,874,356,316,104,613,406,387,436,528,551,818,19,318,614,449,809,398,622,491,706,822,940,812,591,737,603,818,843,634,747,619,268,476,2,996,112,686,576,452,248,601,590,749,779,953,551,159,375,423,237,899,204,954,310,212,415,585,284,903,22,38,754,483,84,838,537,105,965,268,441,377,752,503,657,974,248,75,536,49,204,941,567,438,116,496,623,813,964,592,940,158,826,265,133,781,645,547,903,498,169,523,997,162,162,826,413,474,318,95,429,674,111,984,380,230,151,119,498,646,992,982,730,500,152,302,701,606,45,845,826,977,685,964,297", "812,442,681,755,387,354,607,558,604,923,503,214,558,646,970,950,872,49,825,775,211,87,434,825,563,407,495,736,929,763,711,276,439,229,199,424,44,874,592,430,252,128,625,492,211,391,92,248,462,441,912,50,297,904,993,885,540,804,104,860,149,48,226,578,298,80,572,701,243,241,564,650,703,247,674,292,877,768,973,500,946,355,556,634,24,656,77,11,380,813,114,948,839,263,202,603,216,13,694,330,697,509,11,554,473,232,553,735,981,759,802,323,939,542,539,845,728,602,295,838,448,888,690,108,956,673,232,656,369,592,161,426,469,781,424,276,940,376,341,172,368,604,83,960,13,354,718,759,986,12,261,421,91,347,163,363,342,716,449,974,130,473,687,359,629,374,558,300,159,730,776,82,277,82,209,801,669,130,849,765,482,522,181,65,332,906,939,434,281,818,905,874,34,698,431,397,119,331,556,815,835,656,21,264,374,12,393,826,871,488,290,173,187,609,196,325,146,554,887,945,793,953,716,888,26,901,363,794,26,794,850,105,724,815,802,50,14,280,379,225,124,664,220,234,313,394,125,656,301,930,643,771,249,604,103,109,551,435,743,518,147,735,514,501,795,888,204,55,727,626,735,790,432,872,378,434,937,281,153,116,98,696,77,636,533,561,819,722,448,626,595,664,283,684,379,683,498,798,908,745,955,940,71,424,165,895,200,101,534,862,720,983,441,459,151,596,248,501,650,958,86,41,19,808,917,413,900,977,927,991,314,479,699,287,27,220,532,223,0,311,402,756,440,279,175,727,187,156,840,582,108,951,944,709,280,492,21,861,770,983,644,264,808,985,833,695,649,893,303,605,441,910,565,763,475,198,425,835,216,803,617,541,142,315,137,852,234,120,404,607,866,447,709,292,940,80,628,976,765,386,389,891,790,495,201,817,10,823,114,986,728,349,992,112,828,276,379,436,561,849,654,961,958,719,32,321,10,523,225,384,559,477,926,576,312,525,701,984,595,963,702,573,113,785,760,959,130,746,22,466,958,719,349,700,654,336,325,703,92,72,427,616,220,965,32,408,72,801,850,543,949,353,496,512,974,786,956,406,812,286,252,355,878,412,765,197,364,614,442,342,926,770,476,699,468,54,445,521,343,518,910,990,747,655,667,78,320,603,3,491,375,596,270,37,363,884,237,297,723,264,565,990,914,809,946,216,871,872,605,451,184,783,594,930,21,373,808,187,626,785,994,938,465,927,886,515,234,214,300,257,130,800,324,820,601,745,955,699,805,549,394,865,634,617,497,942,526,579,291,899,221,150,798,947,606,813,566,230,264,988,760,148,934,368,306,930,638,947,293,570,609,456,118,94,396,358,114,74,154,91,677,596,963,33,61,552,242,267,584,878,141,915,895,960,38,939,444,534,614,881,418,340,448,343,264,728,828,206,318,781,187,317,871,700,881,131,836,507,552,761,528,783,876,119,279,544,543,256,295,17,782,766,187,461,659,438,67,671,339,158,685,312,22,416,385,526,30,238,594,216,571,95,768,85,713,34,696,724,290,956,578,757,993,242,632,431,167,395,770,245,407,793,659,643,635,884,741,564,596,277,39,276,669,250,417,761,695,205,153,710,885,716,725,547,259,352,405,23,159,429,999,604,982,995,97,681,912,92,744,90,271,749,91,17,262,237,819,144,556,748,209,210,188,687,439,347,388,915,412,161,729,533,298,648,123,595,651,957,233,828,47,428,620,234,513,806,750,301,747,39,529,684,857,556,632,985,518,710,430,179,23,694,158,992,244,225,591,104,874,342,482,447,656,605,89,644,751,314,727,916,504,892,439,482,251,594,772,369,344,300,18,668,538,145,549,646,938,655,954,462,291,347,556,233,548,908,90,609,835,55,832,664,915,513,330,858,548,144,418,712,727,844,634,402,45,867,689,881,119,604,805,164,313,546,615,870,191,848,239,934,691,610,877,717,158,549,484,159,220,372,854,297,448,435,180,586,870,361,457,529,956,465,236,306,852,469,306,306,157,539,450,704,802,817,870,688,911,158,211,6,242,476,685,628,922,492,579,226,189,599,451,429,536,474,36,309,746,135,725,661,114,975,288,358,608,33,29,805,979,535,711,86,802,292,664,751,987,303,797,114,906,238,599,760,593,692,399,33,583,190,719,928,392,781,262,905,608,50,224,303,235,397,694,331,689,505,419,280,304,98,482,388,157,577,7,457,158,174,260,540,302,522,584,251,519,244,973,395,938,271,619,266,218,581,967,744,401,410,469,711", "561,380,417,484,14,102,385,732,806,764,431,49,300,924,621,273,781,539,27,572,251,8,94,296,764,586,751,7,534,653,33,6,918,445,673,408,923,580,802,342,947,192,953,818,100,905,317,991,954,330,641,67,714,800,402,223,68,502,107,349,158,671,629,314,352,302,574,497,897,2,458,131,783,60,513,685,587,407,628,427,518,830,749,580,611,518,865,510,48,703,366,362,857,649,761,646,305,113,645,572,672,355,661,875,682,964,640,314,4,119,21,296,727,280,987,991,62,294,111,813,323,789,972,322,641,773,666,241,934,660,403,687,273,604,796,730,502,258,943,488,204,754,77,620,395,655,900,55,41,388,952,231,496,623,779,496,794,798,196,777,828,630,772,126,566,141,356,193,211,361,168,918,550,451,590,967,728,220,757,713,770,265,601,664,298,854,950,953,851,429,449,960,689,748,731,756,380,337,45,884,478,427,592,906,933,536,125,414,815,949,204,932,351,297,579,735,640,229,498,699,689,892,862,476,465,848,157,681,96,575,279,143,596,328,438,864,731,765,830,30,997,240,292,496,156,21,506,355,682,855,179,835,483,190,857,422,919,647,981,246,825,966,236,270,331,340,137,203,369,959,400,651,313,283,460,975,220,671,200,924,632,219,814,424,525,659,538,164,342,881,533,6,867,338,93,547,101,980,25,275,652,841,234,735,909,638,154,286,813,174,830,884,361,830,227,756,194,212,894,698,855,263,546,304,486,792,588,505,975,445,839,774,747,154,808,673,843,33,311,0,117,713,969,430,196,204,940,494,578,948,616,608,802,10,244,630,954,720,564,946,649,709,724,361,941,261,48,107,670,95,345,115,640,685,795,139,629,742,241,821,101,736,626,790,984,908,590,629,739,673,140,394,721,268,396,107,262,886,469,513,942,708,471,202,118,586,585,607,612,416,724,762,833,188,284,82,225,961,233,820,652,365,701,139,741,999,692,933,212,691,309,136,50,515,580,961,706,205,410,251,298,909,376,119,799,100,10,286,133,551,454,596,42,627,184,505,631,769,640,742,456,623,708,414,428,216,304,198,263,164,740,118,553,79,32,117,769,889,771,760,827,641,365,394,243,867,599,160,545,411,691,21,414,130,369,526,484,440,466,126,958,178,131,456,694,716,696,58,422,754,749,342,114,308,559,840,621,114,283,646,483,389,288,972,14,570,115,699,941,650,522,612,665,901,332,190,420,338,326,965,967,470,739,30,847,492,142,237,37,314,747,551,537,368,378,446,626,893,980,184,178,442,839,702,975,130,645,778,946,564,514,744,709,945,878,222,980,715,618,442,347,817,314,528,301,254,417,980,238,529,992,363,309,26,997,274,986,297,187,8,587,348,228,76,641,60,883,627,804,551,872,901,828,970,949,764,288,892,898,256,518,597,563,342,805,392,5,422,836,48,380,658,330,865,109,533,628,445,182,15,17,757,35,701,261,919,636,183,889,729,856,511,791,321,895,107,680,619,914,655,775,670,966,568,650,674,500,462,946,348,560,334,236,852,210,53,284,611,666,979,847,611,516,194,654,895,471,539,557,126,312,479,400,182,135,582,332,870,637,190,944,158,738,228,309,867,318,423,14,744,599,220,386,400,559,112,945,241,320,534,402,223,42,172,204,268,253,694,781,330,466,173,268,821,634,434,940,797,329,926,187,789,504,34,886,979,488,36,888,242,544,187,483,149,269,549,86,250,141,914,64,298,284,196,430,551,964,633,171,794,163,831,656,549,320,577,620,783,702,280,640,137,647,155,162,751,386,866,776,360,850,576,45,171,12,947,338,914,611,447,279,187,744,76,719,494,404,284,610,625,441,558,274,637,504,666,479,315,396,726,904,392,954,723,449,610,114,783,935,258,971,208,531,861,91,858,798,233,913,733,564,379,270,217,969,980,628,997,882,354,509,406,674,116,47,413,757,257,420,864,886,812,661,795,740,426,534,520,189,170,132,372,370,489,813,79,486,811,902,226,492,985,213,556,645,762,408,910,457,831,269,817,548,802,158,377,315,700,439,221,812,544,314,133,716,932,65,596,767,581,344,897,33,897,17,425,590,8,723,558,87,27,359,643,143,600,957,859,452,919,968,9,375,770,407,997,458,604,672,601,323,398,900,456,60,248,795,233,908,540,440,701,929,670,577,812,665,971,278,557,349,171,433,336,196,39,529,445,194,478,666,91,759,467,87,276,821,416,155,995,182,840,114,821,989,620,414,23,790,416,921,758,467,763,949,801,655,720,911,232", "49,478,257,103,354,382,80,377,910,249,117,866,429,388,307,254,695,976,441,527,364,969,996,978,857,87,616,921,631,504,555,914,247,164,325,691,966,507,821,861,154,194,31,327,44,854,532,899,453,262,376,590,894,452,543,170,164,904,821,525,118,58,508,339,462,546,560,209,856,20,119,660,814,248,630,33,185,894,631,642,1000,247,966,530,477,730,48,78,665,921,214,569,516,743,813,827,96,378,889,892,163,548,890,765,110,795,70,180,971,610,82,519,926,724,199,905,60,515,135,484,325,691,996,601,892,864,597,829,954,883,782,142,634,823,699,899,740,905,816,593,73,481,846,646,740,667,683,420,617,334,405,663,764,116,184,583,657,561,153,897,980,279,920,269,975,971,282,51,928,781,655,167,625,689,899,34,859,946,784,863,442,888,808,526,234,79,408,93,955,768,984,483,66,931,300,805,517,99,647,501,668,707,718,899,800,958,612,512,464,881,252,355,889,766,998,563,605,954,831,91,1000,140,628,118,833,612,295,586,580,73,202,485,504,406,523,604,352,486,887,805,349,482,341,256,511,5,140,326,123,185,867,881,480,670,436,816,512,770,628,172,581,500,187,182,513,143,846,546,622,463,241,973,281,995,59,314,645,209,774,495,343,98,681,156,657,939,968,200,995,311,655,738,526,471,83,677,341,839,983,230,861,638,311,85,152,967,671,719,632,392,843,408,23,211,407,353,942,744,860,392,969,265,142,560,376,280,795,983,112,171,107,291,563,330,551,881,213,721,402,117,0,803,293,796,132,734,294,873,327,831,442,466,961,242,860,59,628,609,749,4,762,523,709,134,777,18,761,209,104,741,495,716,409,235,173,114,480,496,549,996,728,341,159,698,23,774,897,595,682,365,621,680,736,496,685,329,109,706,172,90,961,265,844,837,806,362,999,796,809,672,887,512,78,454,685,465,289,251,868,26,777,260,115,117,488,4,696,95,985,833,377,533,64,551,566,909,475,950,658,602,671,155,165,590,615,876,187,721,932,64,178,140,856,910,62,605,890,141,523,884,651,47,618,186,911,353,854,967,483,362,937,47,22,341,767,155,543,43,151,765,838,851,529,463,619,751,874,461,93,344,336,215,974,603,276,551,946,421,845,157,579,483,409,892,581,424,891,379,367,980,905,485,679,528,804,650,863,941,712,433,22,485,809,888,230,93,801,576,545,110,409,290,380,131,130,841,52,646,513,709,222,199,318,492,20,269,753,333,966,401,574,167,339,335,343,812,448,59,727,368,624,157,129,859,448,432,600,833,97,663,901,230,743,343,885,963,728,216,845,84,430,75,136,325,858,178,160,136,281,954,706,785,860,691,592,449,514,937,349,548,319,97,123,185,314,151,498,362,579,96,830,561,813,718,352,381,534,903,593,612,31,915,937,119,331,525,914,534,795,801,352,433,624,995,545,874,966,803,247,443,238,86,298,72,184,738,218,283,823,872,889,407,908,746,633,675,245,48,132,103,513,525,198,453,826,135,866,184,137,354,335,684,739,192,132,847,313,403,897,672,792,704,663,226,936,99,568,38,612,709,805,217,335,661,308,426,873,165,754,970,902,491,87,563,753,948,228,556,658,570,753,435,812,550,173,236,703,234,191,415,576,314,791,971,577,845,334,67,210,852,939,91,582,714,97,713,967,800,163,278,489,493,336,336,172,612,588,697,439,258,150,150,375,268,541,77,969,595,744,692,705,78,38,592,767,754,340,725,66,804,653,50,750,506,905,549,208,670,151,862,957,547,744,787,450,782,752,839,454,167,936,671,185,823,102,715,21,164,156,424,27,562,626,384,46,970,821,857,482,270,151,547,236,669,959,633,690,590,66,968,800,430,893,413,565,302,747,594,985,548,645,816,486,198,6,871,696,479,793,386,928,708,242,448,826,485,526,411,696,302,230,300,417,960,868,958,286,968,829,275,556,907,340,305,297,926,860,55,448,636,341,616,235,737,725,857,564,44,820,100,63,692,537,84,57,74,271,454,162,696,737,593,622,274,581,493,718,122,224,410,183,297,858,733,49,70,733,933,993,970,384,709,767,340,624,233,829,287,593,812,704,375,451,273,880,332,190,280,326,265,157,274,464,416,363,116,757,67,504,262,859,916,331,392,959,888,349,36,464,369,886,521,887,351,180,955,147,704,886,672,336,747,426,872,575,764,997,775,185,214,777,693,478,412,809,557,323,26,415,661,381,257,202,444,142,961,826,248,843,937,340,833,689,352,228,438,488,826,107,711", "248,682,492,720,780,937,880,821,349,734,206,885,354,955,621,976,520,420,441,193,15,946,801,102,880,906,786,939,159,318,651,995,131,317,728,302,365,211,351,441,96,149,987,342,562,697,165,702,670,625,379,315,959,2,422,10,359,299,169,895,514,878,870,612,111,665,385,697,367,317,923,926,303,25,726,399,465,23,657,197,6,615,212,343,143,430,428,869,765,511,492,403,949,2,68,993,853,252,929,498,242,203,696,144,344,855,969,120,206,224,204,27,346,980,206,547,452,242,318,995,259,455,633,524,722,90,532,919,859,560,238,270,919,884,529,633,563,536,399,722,615,11,716,832,663,272,382,728,693,304,346,799,429,144,860,215,112,355,221,712,746,681,442,528,475,984,593,673,925,428,350,640,449,957,680,145,548,237,864,100,590,763,109,943,231,64,398,859,462,503,204,725,109,810,794,899,973,759,893,436,895,809,440,696,90,460,11,205,548,985,686,340,970,860,914,437,713,821,100,773,679,715,93,208,6,466,761,607,594,631,750,699,928,923,872,866,554,696,331,217,184,959,829,587,419,125,617,227,156,86,952,529,383,742,577,186,808,182,627,264,245,173,208,329,36,561,304,916,129,986,386,100,857,926,988,672,624,309,821,614,638,254,570,234,649,986,61,382,659,426,579,690,249,477,937,827,869,917,241,503,565,569,154,925,368,962,305,33,536,674,267,739,692,937,685,867,674,383,580,397,152,583,626,678,549,334,488,305,802,836,128,560,577,648,387,749,448,860,756,713,803,0,333,936,619,544,877,927,734,309,927,157,124,428,942,6,277,799,239,802,218,774,109,786,152,566,742,317,476,227,190,122,557,408,458,949,908,368,454,197,62,342,11,471,553,983,543,726,952,142,417,110,590,380,737,629,832,437,289,297,656,502,620,278,819,990,795,491,577,178,215,597,221,728,399,288,508,863,863,747,228,387,562,711,71,205,19,933,776,352,561,779,660,409,828,734,216,45,774,626,361,910,125,387,844,73,206,516,866,103,78,407,96,916,588,719,978,651,346,648,603,815,350,162,528,279,920,743,260,878,128,442,720,821,665,341,113,800,386,156,307,85,403,645,438,670,685,147,194,433,563,507,876,212,724,282,425,804,176,995,914,248,260,646,536,33,764,427,219,256,208,301,989,719,822,84,449,736,794,39,574,934,982,532,571,963,694,238,38,953,585,581,522,147,255,20,92,951,890,500,533,678,361,687,624,741,763,384,697,362,474,424,278,668,697,620,305,897,339,167,185,205,152,983,364,12,787,106,86,105,466,817,658,700,731,459,340,381,458,542,522,970,829,740,231,856,316,844,908,972,199,517,263,828,168,543,143,689,547,372,110,772,31,249,218,940,978,262,726,973,536,123,137,309,608,466,769,798,933,343,43,923,177,198,884,705,762,786,459,110,825,9,720,857,499,875,855,171,429,114,353,741,404,924,753,203,112,918,711,570,535,541,41,402,729,465,560,680,686,237,567,319,686,285,908,687,958,52,77,706,412,651,803,415,560,802,613,483,538,967,698,46,326,262,678,59,998,424,168,39,345,126,582,784,889,99,123,79,371,177,346,972,329,470,751,153,792,140,942,507,808,164,429,876,986,117,647,827,469,528,863,865,943,704,485,965,502,659,870,956,468,191,890,662,300,446,858,538,328,497,870,366,408,506,246,470,326,968,109,75,300,295,436,162,542,727,617,678,306,381,888,914,202,193,284,491,624,319,503,901,881,945,44,942,653,664,778,604,738,213,944,52,874,309,375,938,975,994,627,727,334,770,674,467,151,290,226,147,111,296,889,341,198,200,698,111,564,895,231,44,315,629,20,402,316,820,290,329,146,115,927,935,691,121,908,676,968,973,199,298,307,567,614,938,247,426,467,205,478,846,698,147,923,426,423,473,335,208,653,875,659,772,587,780,193,671,988,402,223,17,645,545,230,150,940,955,72,80,861,551,802,531,34,728,612,672,148,946,810,818,485,194,441,243,925,570,831,947,759,563,905,152,216,391,389,483,810,902,801,775,677,808,129,498,847,868,72,199,153,916,706,169,289,985,234,817,96,235,963,30,7,945,939,336,730,4,728,800,468,409,432,682,436,551,57,10,892,850,922,450,697,166,703,972,603,44,164,929,249,227,706,697,945,996,76,362,977,823,376,491,965,617,411,715,960,739,500,86,629,595,197,596,685,2,489,615,378,699,35,63,616,27,320,354,623,853,163,816,420,700,917,527,456,846,653,349,342,360,653,208", "826,218,881,541,507,739,586,462,365,52,295,244,760,933,903,671,351,244,25,962,874,29,267,151,333,390,920,248,841,313,599,468,690,653,466,990,645,284,914,731,924,920,876,303,236,123,133,611,253,702,434,191,56,417,930,667,919,502,120,677,866,182,450,296,182,408,166,569,732,348,995,651,380,245,511,813,891,247,709,466,59,707,651,469,68,79,519,171,48,714,561,887,703,576,891,901,214,943,824,756,946,136,23,633,469,465,889,608,564,504,303,944,952,609,95,202,820,801,246,893,645,721,736,854,106,170,152,679,948,115,178,651,726,438,371,731,889,468,278,746,540,408,593,98,659,651,708,451,997,930,983,490,850,996,612,970,212,49,882,369,701,7,447,649,372,570,146,828,294,100,88,893,266,779,518,362,818,174,326,580,992,828,790,118,193,417,235,269,481,993,649,258,915,404,183,84,547,603,718,676,146,6,771,497,816,240,770,222,243,763,689,792,341,257,63,652,658,202,536,210,841,813,320,477,114,975,690,325,282,559,609,266,489,732,814,425,8,657,922,596,565,196,382,887,214,757,420,287,759,152,565,565,845,943,5,541,848,245,986,929,406,401,959,491,670,687,988,253,749,450,620,428,522,450,360,208,618,83,374,394,695,76,558,152,138,35,793,264,278,703,663,758,327,672,296,49,592,635,877,975,320,696,280,374,626,326,943,773,791,783,775,231,502,759,702,178,291,135,439,443,291,483,28,978,740,710,827,596,801,411,924,954,731,648,715,439,714,662,440,969,293,333,0,16,801,658,763,9,983,913,740,506,919,236,922,630,591,878,823,877,816,684,137,9,569,409,173,143,919,710,140,993,133,340,505,325,511,831,453,409,420,663,379,54,635,276,73,878,215,305,28,871,75,826,409,172,243,698,628,190,296,662,534,119,188,595,663,414,484,653,497,388,314,60,664,891,367,886,434,573,886,655,811,729,963,262,152,757,579,527,558,773,206,469,518,428,817,465,996,319,834,179,533,866,900,476,566,432,301,530,443,681,184,912,273,173,356,390,513,247,881,294,690,195,790,533,511,931,536,689,264,84,605,327,699,320,146,203,257,989,124,849,213,919,108,92,471,197,194,236,181,577,158,138,76,37,624,645,145,101,221,371,762,430,551,862,357,557,723,508,24,798,431,422,89,155,974,585,321,351,328,349,166,231,388,162,300,472,144,759,710,399,151,281,16,509,688,675,55,304,904,305,16,405,289,611,626,313,600,133,938,299,498,740,243,792,722,156,641,450,801,609,253,190,723,816,711,932,793,708,445,287,430,804,763,805,627,452,343,898,480,981,267,412,38,638,138,105,396,913,310,674,419,304,781,967,63,913,927,81,21,350,761,185,288,152,532,480,958,35,242,190,254,880,623,328,512,552,474,485,794,462,416,652,805,705,751,506,189,878,586,18,603,205,423,200,741,747,247,822,135,552,862,210,857,191,583,249,944,626,23,820,493,484,451,662,282,705,855,540,417,533,894,405,523,120,53,234,827,100,920,438,994,67,529,778,641,629,815,645,193,596,418,42,618,434,610,144,111,376,680,504,546,829,92,945,655,624,795,502,635,109,961,832,911,256,473,456,84,19,767,689,282,297,776,213,255,509,900,83,687,829,326,291,778,719,482,653,973,896,480,757,454,803,973,764,886,886,949,777,609,139,18,295,889,776,156,665,990,58,988,643,61,719,833,501,238,364,468,918,334,845,762,245,118,166,377,782,594,80,356,216,844,847,180,73,939,742,313,158,392,549,415,252,288,563,964,734,237,998,596,552,275,510,44,771,453,783,529,5,408,308,650,681,267,806,852,719,135,346,378,342,830,641,36,561,56,23,134,498,574,826,208,313,596,883,296,343,623,151,468,965,923,55,363,20,570,853,204,674,149,501,575,589,311,563,972,37,237,365,659,313,682,358,883,894,33,778,865,62,358,404,412,806,765,146,646,984,542,182,996,271,112,227,79,672,924,56,533,851,349,520,633,576,456,198,54,338,658,200,528,219,723,173,541,169,652,929,386,101,871,952,370,871,243,545,30,387,880,2,490,999,884,104,738,955,876,786,907,398,295,221,447,345,34,492,573,422,99,737,630,161,887,393,519,996,110,531,108,46,382,586,193,218,734,355,724,343,732,23,274,612,748,344,736,736,231,702,197,826,682,878,425,849,269,837,388,356,567,385,986,711,447,16,457,11,523,446,144,398,459,102,862,350,256,400,616,179,162,808,318,785,271,798,963,164,473,776,508,201", "682,350,511,355,305,149,930,46,911,37,637,411,809,773,917,937,158,243,579,295,138,147,775,264,905,971,129,141,762,438,866,721,564,137,684,253,337,759,592,87,965,741,239,241,635,46,481,825,152,419,458,611,233,114,263,729,357,872,432,47,280,848,454,878,116,804,239,86,820,178,571,295,966,385,454,677,208,667,295,268,1000,626,641,194,16,543,278,327,468,414,733,402,112,125,784,620,435,901,886,435,657,289,630,611,700,944,787,878,422,149,855,304,459,308,818,956,735,296,636,195,545,895,991,872,878,485,838,382,371,926,950,975,12,862,807,301,765,587,321,130,390,173,394,768,941,559,60,333,452,748,272,867,711,705,944,554,753,342,197,27,51,25,626,883,818,193,425,823,215,825,84,232,592,114,502,677,535,120,886,897,873,686,671,666,769,6,117,421,747,977,82,684,435,747,802,73,138,878,718,13,51,100,711,355,516,691,674,66,502,297,488,66,932,924,178,681,344,963,765,186,341,699,515,375,569,883,939,35,529,999,273,716,779,315,280,386,453,106,753,22,476,467,427,800,964,970,586,396,47,428,682,252,361,427,641,153,214,732,756,84,54,952,447,149,811,86,682,379,871,608,146,212,960,674,144,156,308,718,505,295,30,639,859,956,19,510,295,723,790,955,453,692,385,754,60,182,555,257,944,228,909,462,654,889,614,216,511,113,510,539,933,102,252,689,296,96,371,386,798,705,927,825,935,668,295,451,409,982,9,320,781,907,905,494,509,212,348,819,279,430,796,936,16,0,947,743,742,67,593,605,623,635,454,577,921,595,637,946,765,268,483,719,588,570,838,646,552,53,298,786,412,135,230,826,782,796,73,373,766,126,745,687,287,916,404,298,255,946,580,965,600,31,96,188,5,726,219,749,645,928,134,113,597,128,672,455,375,929,537,863,889,123,969,787,36,733,747,127,587,800,989,203,165,774,332,143,787,64,194,885,505,224,298,480,319,635,487,623,317,609,675,735,234,72,670,448,223,59,665,923,836,71,863,238,621,931,358,256,440,455,330,392,118,283,232,242,100,838,761,17,138,715,224,814,496,931,847,742,319,198,998,88,414,547,598,776,919,396,74,946,330,378,152,357,840,302,570,125,376,998,659,872,806,235,330,331,705,599,766,227,453,68,170,920,413,365,599,26,40,609,364,91,724,70,104,365,715,359,42,10,424,466,638,369,287,154,922,126,465,997,127,811,331,996,977,441,261,816,79,704,402,170,185,941,355,478,795,382,307,719,567,70,925,545,298,832,709,395,645,402,413,665,977,429,321,899,977,882,416,666,941,259,931,244,276,461,712,703,948,612,630,197,25,595,68,151,679,556,596,755,197,391,676,998,735,792,730,565,175,307,773,412,342,327,209,429,784,725,828,714,851,873,246,619,598,363,615,912,637,579,940,138,119,552,262,89,779,296,73,453,622,742,599,725,848,448,308,175,859,40,761,163,235,702,643,189,930,847,187,44,66,952,95,625,7,936,232,552,915,838,284,344,915,76,614,540,154,258,723,541,343,486,248,182,12,317,102,996,945,713,102,165,89,944,482,508,418,495,662,110,442,604,732,426,145,400,230,940,907,125,212,196,627,821,550,920,672,952,491,833,151,272,208,101,228,769,812,154,225,36,22,357,236,470,333,273,681,221,220,613,900,266,483,743,741,611,516,545,323,985,800,888,189,654,736,739,619,878,681,476,345,26,170,1000,58,259,660,512,205,902,213,491,220,764,668,293,237,332,284,235,388,614,560,184,626,608,236,813,419,221,566,656,148,758,622,570,74,287,302,259,729,387,530,499,241,619,81,885,763,48,772,658,542,736,90,41,218,339,425,501,867,943,915,940,497,30,725,730,548,747,442,989,390,893,586,851,448,858,564,667,272,71,157,102,846,443,878,89,654,480,156,23,688,240,241,327,526,391,472,783,648,293,482,138,403,11,268,686,243,978,776,363,954,899,53,371,102,393,562,282,559,173,722,315,965,548,874,782,276,723,585,237,776,631,368,838,612,510,443,72,112,367,238,956,148,309,89,816,164,293,175,714,391,451,735,349,922,6,163,912,490,811,744,971,5,934,530,652,553,875,229,959,995,561,651,640,800,539,121,818,826,649,294,106,200,127,479,629,774,243,195,18,624,749,284,678,15,195,390,961,24,452,842,921,690,117,212,366,210,685,850,660,889,128,368,341,700,274,244,742,477,118,963,179,557,306,849,953,504,776,681,131,305,799,267,942,371,963,680,18", "598,355,86,467,462,732,860,327,363,886,815,123,272,856,606,89,24,847,272,794,439,449,739,224,985,359,966,909,688,859,879,97,334,952,48,950,161,737,894,886,563,864,244,205,55,506,807,310,159,168,937,599,658,338,482,142,816,854,147,158,105,720,117,861,802,738,671,350,565,34,4,620,56,788,869,536,288,697,456,797,899,230,305,858,225,19,671,867,166,156,599,705,358,173,695,368,172,897,142,42,526,457,688,251,375,410,480,43,802,966,64,633,269,783,997,369,579,243,372,513,255,741,491,466,484,241,881,34,824,943,610,148,57,934,417,709,360,259,778,751,29,21,412,257,114,328,976,855,168,545,339,55,672,582,110,735,226,447,266,874,643,718,645,262,423,748,717,873,748,523,941,604,58,929,579,448,134,485,431,855,767,209,791,133,514,216,446,308,661,440,517,298,568,611,174,374,130,885,598,948,147,844,953,11,206,54,85,556,751,748,314,793,170,137,312,342,619,390,649,962,307,550,25,306,661,784,959,116,222,468,812,476,685,580,379,575,584,98,356,391,274,180,37,899,457,705,924,456,481,658,344,868,877,527,886,579,469,564,926,521,690,434,220,101,752,938,211,580,162,156,310,226,865,807,823,976,353,72,747,950,193,873,578,1000,953,502,993,574,978,453,582,813,34,472,985,50,978,229,320,298,952,274,314,510,240,594,678,672,478,896,564,677,148,487,451,368,314,44,648,539,904,618,927,777,832,87,410,728,435,770,864,709,666,703,200,662,126,522,175,196,132,619,801,947,0,620,111,197,137,359,422,53,34,690,138,856,998,458,70,99,142,75,672,175,711,991,890,767,26,640,216,988,550,611,688,739,531,217,788,311,214,630,220,427,352,745,225,151,504,84,812,687,505,689,225,223,955,889,963,205,259,673,398,608,636,256,544,194,895,900,793,349,595,412,566,268,902,144,815,515,174,41,310,485,71,879,209,68,984,732,537,166,625,383,586,715,172,885,323,964,888,305,936,346,640,52,129,886,645,222,415,506,17,298,486,352,125,279,465,156,640,269,179,934,570,775,442,803,716,963,793,32,623,991,112,797,84,620,296,76,115,737,372,788,150,862,610,38,382,823,725,400,989,462,746,372,334,226,347,72,678,331,407,5,630,933,415,729,68,287,883,90,963,751,828,72,718,257,300,839,513,386,846,350,977,467,708,435,267,448,812,856,833,716,754,961,786,766,726,444,528,449,927,844,946,573,915,654,262,823,19,608,499,895,683,501,445,190,257,512,639,256,447,591,86,868,658,945,351,902,190,882,12,299,543,30,91,454,370,311,921,527,602,153,363,924,71,434,738,750,177,646,395,94,399,379,176,13,405,129,19,326,920,653,6,115,168,727,458,850,980,198,448,4,737,771,112,596,496,533,468,93,559,222,753,968,899,857,150,913,295,169,105,899,616,438,134,688,679,460,595,256,979,622,159,373,617,866,486,295,2,284,524,720,384,244,195,194,872,569,955,659,887,617,400,660,207,674,769,38,52,280,237,755,50,915,297,763,588,954,381,912,493,347,650,742,471,927,439,73,67,128,694,645,796,647,227,620,636,433,213,507,167,28,318,533,962,944,150,536,945,840,375,278,966,330,111,127,984,138,205,697,33,965,398,636,399,726,546,618,447,205,949,605,619,263,945,354,125,412,776,675,944,825,125,682,126,269,169,668,240,169,843,272,177,405,110,832,702,788,910,152,150,609,436,126,946,296,375,605,266,505,553,426,228,114,315,914,517,938,960,104,551,373,225,876,775,749,879,374,521,412,318,410,671,306,937,532,341,258,222,533,489,571,749,111,837,901,218,697,150,535,547,258,30,975,367,265,718,719,292,609,911,422,284,615,295,28,479,158,410,496,948,251,959,569,407,141,543,209,336,326,205,527,797,891,625,928,292,290,820,888,211,198,475,908,677,804,731,823,316,992,320,185,198,98,487,894,334,58,633,41,501,771,708,609,297,534,869,18,716,527,594,768,588,21,242,857,76,135,257,278,149,602,324,219,505,125,350,604,879,248,677,987,19,556,683,928,32,203,505,264,816,491,33,451,861,87,328,845,146,385,852,452,424,10,867,356,579,593,550,614,141,382,438,269,376,173,707,784,444,599,743,157,640,515,903,618,800,310,829,424,827,884,926,207,482,895,957,666,465,640,975,784,301,319,691,54,524,177,256,671,584,758,932,941,410,729,679,913,616,478,943,276,351,318,212,57,36,22,917,285,567,343,430,421,751,653,591,154", "900,533,105,478,897,597,162,46,539,981,756,105,102,796,585,567,649,36,366,1,552,396,345,627,62,313,949,754,780,956,586,884,511,697,929,167,741,241,67,421,968,414,111,440,703,470,137,224,629,311,179,495,67,276,316,361,329,918,101,61,495,671,138,213,59,134,481,794,513,493,342,572,979,374,973,131,427,834,615,989,828,492,583,409,474,531,282,238,352,393,981,43,763,830,15,893,476,218,84,831,871,680,438,2,609,889,318,199,759,640,976,842,86,630,400,561,878,894,68,608,716,248,780,579,948,10,875,904,922,748,144,420,144,682,861,90,712,22,559,352,774,74,889,967,414,357,901,216,921,647,848,915,551,379,158,669,684,678,228,113,118,192,930,849,722,663,630,190,991,844,869,95,73,917,317,617,654,837,938,925,950,135,404,255,462,662,279,894,110,685,142,992,446,286,76,36,479,885,139,48,872,126,78,464,847,198,162,250,462,581,368,609,527,448,533,291,170,784,942,601,848,103,442,672,316,164,595,21,306,640,569,738,291,64,886,22,168,220,904,258,889,696,339,549,687,815,629,403,755,915,373,952,835,234,128,837,993,758,935,260,95,886,435,669,121,722,840,206,420,616,472,935,75,628,799,676,733,497,796,90,494,574,546,162,759,629,750,948,321,946,56,589,842,477,308,894,716,298,871,180,221,710,679,737,765,663,176,712,944,961,583,911,631,910,971,837,828,9,781,806,246,227,665,386,414,734,400,228,832,999,529,577,53,6,695,658,50,63,727,204,734,544,658,743,620,0,894,397,422,705,954,921,322,307,520,654,619,161,594,769,712,590,918,825,945,787,505,486,839,87,427,112,405,997,191,142,450,736,317,632,177,913,819,9,218,78,942,468,858,163,707,567,806,650,367,383,577,496,941,375,543,822,528,182,772,685,356,815,87,608,671,313,815,712,924,975,421,852,766,745,257,590,459,233,770,621,259,65,70,788,813,740,911,893,433,873,390,393,327,353,158,986,72,789,363,182,17,859,795,978,803,41,14,171,361,452,546,24,113,671,526,894,785,564,636,890,233,98,631,768,397,732,107,575,332,485,216,511,563,213,300,973,234,771,899,178,186,356,399,962,299,332,789,527,627,790,399,955,108,915,77,201,618,615,854,212,119,883,704,305,122,716,518,35,757,229,842,231,11,237,864,567,600,553,970,680,547,330,865,767,443,257,467,310,644,97,479,135,577,965,978,935,618,904,231,514,244,716,125,192,679,113,826,493,290,703,761,287,109,248,752,895,713,968,62,979,795,725,854,513,991,436,602,860,624,444,430,715,240,308,804,766,612,672,963,488,619,427,235,192,635,201,602,42,944,96,464,108,119,631,69,708,101,30,423,108,113,356,529,962,746,66,928,127,570,513,714,595,260,577,420,628,958,473,800,317,618,262,984,289,668,713,246,69,394,190,803,466,128,593,361,900,45,680,304,618,945,568,42,522,575,618,832,551,771,286,629,379,797,116,891,243,340,123,314,956,859,127,355,140,565,549,229,348,735,824,665,523,941,246,206,63,242,103,693,487,225,836,606,545,557,184,303,732,409,359,870,231,485,594,998,129,855,583,785,312,56,480,192,893,513,992,937,67,954,854,782,700,514,911,156,643,209,828,414,340,877,140,98,905,266,722,146,22,758,111,278,678,690,798,773,441,254,566,498,500,622,501,78,587,141,605,301,906,580,954,599,995,289,379,833,532,206,557,222,212,598,832,858,435,361,500,884,401,339,495,461,595,344,815,107,895,980,514,243,369,997,541,498,585,957,420,736,200,102,216,611,969,992,278,156,989,584,416,416,640,473,435,272,156,506,626,193,863,112,381,664,518,806,205,383,269,707,663,304,585,279,72,200,668,807,733,655,47,944,781,327,49,575,995,137,670,868,112,90,145,85,758,285,308,743,816,856,713,542,984,263,821,71,140,511,161,156,359,399,505,869,250,770,7,110,602,890,897,924,108,596,341,896,251,361,73,125,376,976,411,49,995,195,881,518,421,753,523,36,612,88,298,217,892,481,213,790,847,54,982,513,25,782,162,42,968,429,331,377,708,511,97,334,422,756,889,627,254,144,768,890,780,734,564,517,714,667,237,456,87,376,178,299,470,625,65,363,115,749,599,407,803,554,311,821,270,790,693,780,201,414,938,369,64,66,146,219,336,993,715,643,578,937,271,589,452,431,417,297,641,975,441,191,3,843,532,532,205,831,371,966,289,524,828,803,975,35,987,393,932,767,796,76,88", "239,870,262,787,623,236,509,1000,768,178,216,565,948,209,913,348,587,477,28,396,488,146,528,538,971,318,560,830,131,904,61,853,416,641,662,122,79,86,429,254,900,829,103,614,600,522,592,630,630,198,258,52,113,466,182,850,303,32,373,91,594,327,468,260,139,350,431,614,875,810,90,386,849,98,947,277,212,385,223,770,381,299,559,160,871,233,740,344,506,84,248,357,380,241,552,345,163,732,387,389,838,545,419,503,10,989,362,320,705,310,122,586,174,805,459,502,443,193,317,362,746,546,654,950,594,528,289,934,527,925,797,749,809,702,764,36,908,505,52,161,538,739,291,346,511,305,505,253,131,329,621,958,252,132,638,56,732,619,220,450,143,261,614,121,191,373,958,118,320,802,825,737,696,559,105,68,645,541,898,971,116,428,178,495,352,885,563,536,165,890,604,279,603,334,554,761,829,321,486,551,954,747,883,666,528,240,829,420,675,330,184,24,160,495,331,78,921,672,181,52,738,608,724,18,405,530,8,336,478,570,734,457,304,144,148,66,199,984,657,892,572,702,280,944,687,208,616,415,453,861,910,240,865,786,615,282,483,824,551,123,88,776,467,314,497,764,348,915,194,979,994,135,379,707,874,329,749,81,504,223,266,164,788,988,445,82,502,892,978,365,236,141,885,816,238,962,93,152,587,81,64,877,626,593,666,575,552,101,179,110,30,557,851,526,364,537,371,348,145,782,465,858,75,678,163,130,176,597,845,704,123,110,927,172,948,609,251,641,187,940,294,877,763,742,111,894,0,664,816,189,659,335,599,61,630,115,869,990,699,686,142,301,564,995,711,378,583,615,175,785,537,352,341,418,784,111,782,415,880,295,731,908,890,488,335,479,129,979,208,487,266,581,380,842,115,974,750,933,277,961,63,969,925,599,271,816,393,302,31,271,522,856,126,251,314,316,347,961,392,252,666,336,588,681,755,777,508,724,172,485,984,154,988,944,619,475,791,719,483,76,26,523,751,966,594,893,308,128,246,128,763,554,376,632,443,482,741,299,218,917,190,400,801,66,481,446,246,622,826,655,847,304,468,324,680,698,587,705,568,845,678,431,942,493,112,757,897,184,220,520,255,915,348,745,967,26,252,73,654,720,616,76,106,320,616,394,596,696,664,341,643,299,236,86,46,945,474,175,721,150,884,431,398,859,152,370,361,434,171,192,423,589,769,778,300,922,298,908,148,31,957,960,301,809,256,543,244,359,540,788,767,671,849,316,105,258,915,535,621,881,651,259,311,323,911,61,101,752,909,241,992,14,676,371,76,486,142,267,924,902,355,804,538,212,35,704,658,552,484,722,541,259,231,70,507,735,884,81,939,651,577,634,951,834,35,577,255,351,895,781,680,841,68,217,882,256,287,36,39,379,788,969,437,224,235,902,639,107,297,500,808,80,449,149,424,191,369,955,794,499,661,348,440,484,404,232,226,855,912,466,490,978,601,122,130,339,286,339,190,307,680,935,358,835,840,593,891,571,638,543,680,274,715,109,835,89,362,299,724,34,661,812,465,284,545,953,662,617,158,517,210,189,412,35,950,592,538,623,291,469,573,610,550,688,577,316,20,193,73,962,265,609,634,620,867,318,951,276,764,208,798,536,40,937,718,14,21,191,236,117,190,582,681,497,74,360,955,173,725,773,430,890,387,899,546,130,829,532,268,105,93,144,803,63,482,685,780,792,946,492,952,464,774,945,423,354,257,564,372,280,629,273,623,987,59,602,810,172,795,468,419,262,879,34,366,830,325,882,250,315,581,587,565,714,21,97,798,373,875,702,23,541,183,144,54,871,965,48,94,700,963,152,661,874,54,240,479,251,621,192,896,266,517,90,20,671,807,969,611,721,770,775,233,325,580,293,954,556,39,262,505,244,430,755,855,648,327,544,458,256,584,278,368,703,28,268,119,491,312,244,853,741,865,6,17,728,389,324,636,961,858,859,518,845,436,205,707,671,630,50,813,58,863,837,303,4,423,500,39,866,774,915,732,504,278,983,48,595,284,740,579,36,980,580,556,995,454,60,147,926,436,815,344,438,791,34,509,173,642,3,560,465,426,41,56,288,359,605,328,243,829,771,511,259,99,263,501,663,432,786,760,950,257,489,400,807,258,671,413,427,42,848,489,989,722,28,762,420,818,890,826,485,654,767,904,185,978,490,695,194,217,416,218,845,52,908,512,147,987,762,3,306,591,473,942,58,188,315,231,808,399,322,262,977,388,163,711,466,429,983", "652,515,641,937,397,703,899,936,415,845,965,701,52,839,78,251,172,578,650,118,346,584,380,151,214,155,98,708,725,258,269,603,825,955,425,302,642,482,260,77,938,384,281,55,533,883,103,215,912,724,429,655,562,968,234,716,151,905,688,261,718,606,691,419,68,429,193,848,206,608,527,760,169,587,818,639,485,297,784,330,892,496,589,369,933,262,714,260,204,430,728,223,160,912,363,316,594,117,280,47,184,652,347,431,669,216,697,691,394,426,336,320,578,884,125,132,598,383,278,843,631,307,259,192,132,735,86,332,382,922,980,572,849,393,209,524,551,636,807,944,417,229,334,39,580,990,369,346,760,170,933,646,819,843,102,383,985,148,284,682,524,147,44,661,269,993,476,341,562,60,803,751,75,192,322,882,288,510,943,866,140,922,750,175,28,144,704,504,979,521,503,568,151,925,223,501,271,417,959,99,492,517,564,405,180,685,778,684,372,471,175,93,649,50,519,786,746,143,953,861,892,846,268,490,595,590,70,361,260,495,394,700,314,891,461,84,429,710,392,482,744,579,335,913,119,904,770,430,496,787,805,456,561,194,993,573,360,264,80,356,448,444,783,521,631,871,36,242,674,495,493,651,732,920,96,617,542,787,754,74,493,312,719,433,487,624,115,949,259,454,43,89,407,684,584,967,369,26,214,685,832,25,655,827,232,302,40,819,656,9,96,906,106,240,417,84,225,139,234,236,592,329,244,465,842,203,778,475,267,778,45,682,218,391,270,362,715,875,156,494,873,927,9,67,197,397,664,0,267,905,469,660,50,750,618,323,615,696,528,158,615,545,398,128,484,98,879,959,944,619,529,931,637,416,578,320,793,135,89,538,930,440,560,969,344,778,862,566,346,493,341,233,631,789,224,100,560,997,342,335,83,898,220,175,435,375,116,529,789,500,946,892,307,36,578,460,159,713,690,755,600,938,172,382,354,1000,807,6,528,943,611,17,408,226,762,184,394,930,971,570,224,179,259,665,689,43,67,680,914,124,686,993,403,651,561,519,336,23,572,199,439,51,9,603,669,574,334,12,847,383,906,604,875,854,776,778,693,172,405,586,917,129,790,962,879,861,764,375,369,66,841,686,975,513,745,767,304,97,111,865,75,31,150,510,956,265,64,216,607,506,910,40,513,867,181,4,109,973,194,368,98,139,244,825,324,482,577,788,809,953,425,155,585,39,892,92,748,914,675,505,992,405,546,702,732,820,584,794,734,517,61,306,820,140,470,983,59,697,728,802,151,829,666,818,204,515,513,54,231,583,706,651,899,959,913,395,58,808,867,55,787,598,496,158,480,246,984,182,468,696,400,100,649,15,940,159,23,283,221,489,262,122,372,526,682,842,499,750,96,974,488,729,368,2,802,10,361,866,464,704,372,343,902,873,536,77,562,434,625,301,573,25,721,792,453,18,190,500,398,840,220,996,218,163,856,297,554,816,493,328,809,374,139,890,409,455,154,158,896,838,70,397,465,645,693,236,311,268,292,322,697,772,827,871,183,586,156,800,588,48,126,153,991,288,19,789,301,594,128,550,902,591,76,608,499,450,207,641,29,214,6,55,240,256,777,939,185,294,33,781,735,894,531,879,496,653,448,42,637,99,827,229,64,360,303,255,555,853,95,334,501,17,942,67,65,956,919,115,450,403,197,20,65,197,427,849,488,188,555,948,228,115,768,780,796,918,618,5,726,111,415,248,270,398,228,754,854,906,771,821,884,72,474,689,27,317,922,191,166,653,987,651,352,684,82,851,959,508,964,921,86,71,597,404,155,618,198,429,917,147,938,760,926,386,896,351,551,912,160,912,581,512,667,672,362,211,93,826,160,849,225,556,709,182,183,194,179,856,344,200,347,991,72,47,985,506,869,316,934,399,591,331,937,627,945,958,812,687,277,138,452,98,5,963,430,812,486,263,243,54,973,845,727,17,618,807,372,194,747,585,150,258,464,263,329,773,166,245,833,371,228,113,143,552,934,432,773,27,20,358,218,532,953,472,361,311,707,234,400,183,105,894,221,922,806,985,385,240,616,309,99,739,518,961,738,959,753,24,923,661,288,570,119,148,891,607,532,157,234,902,610,23,44,652,36,7,981,537,323,115,502,395,226,422,418,128,306,631,797,378,613,323,31,846,54,768,440,196,200,71,500,235,812,258,728,398,76,333,315,352,72,989,134,181,708,555,975,382,564,642,835,438,977,370,203,621,347,282,937,350,726,599,355,723,235,329,367,295,766,592", "367,757,977,241,247,633,464,412,102,796,396,256,325,188,516,360,110,211,613,371,451,740,628,169,530,102,81,795,798,917,926,295,150,221,96,487,227,99,989,631,774,535,858,713,699,70,263,725,989,516,692,52,154,91,262,516,744,754,848,674,732,453,264,369,62,600,95,166,837,668,364,456,117,758,517,529,904,929,458,264,889,962,309,710,687,805,68,853,730,520,190,278,959,948,789,668,292,538,598,963,636,581,143,506,686,779,680,419,242,40,731,740,286,60,976,121,387,994,775,267,216,88,161,405,177,72,521,117,218,508,384,845,802,653,831,213,488,795,863,506,104,418,321,694,998,968,680,955,867,664,288,849,786,98,512,375,808,26,289,97,334,275,781,696,409,469,940,770,608,832,56,695,228,404,320,738,439,994,386,322,562,481,409,611,550,480,73,62,288,976,193,366,244,495,865,84,686,116,889,315,172,527,840,837,314,875,810,455,659,374,846,626,972,262,350,58,661,769,471,684,456,440,190,748,184,282,4,539,721,608,905,898,587,195,267,187,116,619,648,231,911,52,616,428,993,692,275,797,177,634,813,239,239,816,830,132,464,416,883,327,267,226,202,832,734,266,823,538,910,712,954,853,926,192,878,27,648,840,415,462,238,694,181,475,633,649,983,778,332,1000,458,157,190,374,240,465,545,856,44,560,883,484,862,880,698,416,246,32,102,908,291,321,969,370,657,692,97,686,109,579,157,430,81,890,13,719,142,878,158,401,435,132,653,855,561,922,287,789,840,578,327,734,983,593,137,422,816,267,0,742,473,134,98,486,126,685,948,331,260,412,990,80,177,192,661,794,929,735,94,631,555,311,42,594,651,153,510,466,189,767,622,873,800,949,369,911,396,161,737,270,540,238,8,477,662,669,449,525,76,809,623,924,568,558,688,108,828,112,801,793,40,218,987,62,288,120,905,483,388,578,153,716,948,385,775,290,596,861,103,476,409,126,696,104,634,887,509,463,653,634,978,456,553,194,332,111,242,463,890,574,541,660,924,789,620,690,829,509,347,101,386,989,768,999,743,399,75,113,209,762,595,123,49,150,889,157,957,195,711,851,532,402,32,578,783,819,971,781,988,38,645,733,18,766,657,67,903,614,610,254,748,817,704,23,846,904,669,584,237,760,143,595,758,734,524,474,111,360,935,737,489,529,403,840,292,215,61,846,74,971,89,67,640,961,38,670,766,461,641,556,743,428,626,773,885,560,778,503,914,194,794,439,287,327,156,24,321,712,834,932,803,105,423,495,450,705,887,781,923,927,182,985,260,831,177,925,824,954,584,605,151,833,549,213,3,354,87,854,328,613,710,72,112,882,536,274,974,433,861,987,196,899,85,658,106,964,1000,2,481,210,433,32,789,239,129,907,214,921,499,118,74,788,686,794,172,974,566,478,61,373,113,986,486,192,561,684,577,219,486,542,195,664,814,502,357,296,850,805,9,781,661,148,888,540,592,374,706,21,946,146,597,608,515,252,735,968,199,254,466,197,243,872,793,136,296,678,658,987,519,48,713,112,748,55,680,100,333,448,653,897,984,261,504,520,102,905,638,628,825,135,221,617,628,678,720,166,217,286,775,378,386,26,655,530,727,864,349,851,89,657,77,871,724,458,907,449,674,870,998,644,576,24,803,181,673,512,89,519,570,87,13,393,562,472,436,970,974,788,534,650,380,56,132,431,460,914,13,379,487,545,893,598,957,749,411,628,613,445,544,150,227,817,720,145,659,324,123,473,850,996,500,294,502,987,451,305,322,792,233,847,635,473,496,93,425,986,171,657,348,769,434,980,890,623,533,60,308,159,491,56,898,653,681,750,762,369,260,162,25,749,509,858,349,645,444,426,545,209,87,430,355,229,332,465,930,41,993,477,992,653,826,960,462,206,403,546,591,414,333,906,258,949,407,598,130,183,163,522,523,837,998,273,817,560,920,18,11,718,320,25,882,325,622,175,953,506,626,596,212,119,952,89,244,506,486,947,865,189,333,727,1000,956,206,463,947,339,878,619,535,794,954,690,513,416,725,501,735,33,275,52,723,696,35,578,274,662,314,681,80,244,230,355,14,350,280,587,730,233,458,573,42,278,550,666,268,986,436,467,575,73,761,807,37,289,955,770,409,936,856,674,815,371,985,874,600,662,164,256,922,134,508,686,505,748,654,460,499,824,707,583,319,65,278,895,644,983,763,290,713,746,607,908,384,30,694,387,576,657,626,52,987,427,439,561,881,970,15,365,673,35", "293,740,257,812,241,191,917,585,508,670,748,382,171,679,365,823,252,681,770,114,666,449,853,783,717,517,883,862,287,192,260,519,551,760,953,797,918,505,846,331,56,149,659,517,791,615,820,233,578,774,192,774,708,283,138,129,260,963,697,175,849,832,155,75,504,988,684,206,322,359,518,532,35,709,620,815,689,998,148,406,120,47,909,863,347,280,246,548,383,610,334,683,110,95,516,946,261,423,964,304,898,346,429,263,956,363,619,659,393,713,244,234,180,206,702,480,938,494,676,102,304,572,456,915,832,330,923,275,401,26,406,34,621,365,117,864,713,224,315,213,344,254,531,600,857,821,962,730,189,374,945,97,46,23,878,554,260,905,408,263,460,446,81,960,830,603,460,16,869,790,757,143,710,734,79,384,526,407,156,316,773,957,517,430,675,497,424,710,147,961,650,279,309,467,283,817,693,101,852,90,179,76,56,906,737,730,830,802,877,493,771,441,186,448,158,527,542,917,83,652,711,686,631,41,798,253,27,748,313,999,676,171,716,179,712,346,759,351,204,420,219,596,468,856,754,48,276,924,985,438,488,164,309,103,491,991,523,420,89,736,714,595,747,765,988,55,952,654,758,184,930,214,795,27,707,693,155,134,171,534,173,829,466,779,47,817,978,937,972,897,523,96,45,328,97,575,537,211,583,509,429,418,495,145,998,947,339,338,117,959,463,701,400,164,356,744,193,741,281,652,381,946,574,242,399,30,471,348,535,897,593,798,727,389,23,857,593,600,582,948,831,309,913,605,359,705,189,905,742,0,993,910,915,842,554,65,106,500,341,848,490,599,612,116,140,739,923,890,213,602,405,182,559,164,336,739,104,266,873,483,164,964,15,180,427,707,594,710,118,462,566,417,535,583,811,44,66,807,654,601,390,622,228,841,802,857,106,810,825,111,547,395,229,81,320,184,43,85,41,837,385,60,143,718,798,380,276,600,150,650,879,454,348,205,226,339,275,929,184,479,636,303,718,429,903,668,839,192,848,1000,964,293,564,288,841,28,262,827,899,577,451,750,285,975,213,283,103,275,888,283,567,785,732,56,859,535,813,331,740,324,594,949,998,891,617,893,571,748,206,992,737,205,43,919,8,216,580,210,969,90,585,70,41,417,266,756,88,915,422,817,1000,429,569,810,147,590,450,961,803,520,620,754,232,505,859,616,978,894,634,251,879,821,167,215,462,95,878,621,320,534,363,730,574,251,490,646,985,588,945,885,913,448,357,575,79,771,144,512,761,118,244,624,100,804,292,542,274,887,439,722,137,972,110,78,247,555,128,340,658,320,664,308,511,793,200,35,602,301,880,997,865,619,464,681,835,116,283,655,4,362,349,277,704,337,924,773,58,4,147,84,488,214,128,463,924,640,476,229,237,169,607,935,372,628,795,89,137,139,210,665,992,443,506,928,913,60,295,116,746,99,149,231,996,564,529,37,382,140,785,18,777,679,648,436,820,615,562,619,625,162,854,937,171,527,542,585,698,410,265,695,259,271,230,387,632,478,424,892,943,708,946,199,337,78,12,943,129,974,814,113,726,594,524,926,32,583,226,778,226,380,318,26,597,9,836,54,251,694,896,447,656,861,266,832,292,501,982,419,340,675,391,91,179,230,281,533,759,799,524,687,148,191,775,859,286,471,310,979,442,864,300,870,419,724,8,321,141,883,717,644,722,12,738,32,824,118,355,95,782,201,802,510,212,53,614,823,203,27,467,576,580,443,290,921,752,682,690,809,265,593,818,656,583,21,250,629,574,235,83,468,102,367,568,433,177,393,837,439,852,375,271,714,612,736,68,876,884,546,110,55,575,294,686,380,140,430,812,812,455,747,138,75,335,901,455,614,380,868,601,558,459,786,766,391,799,152,263,658,804,12,898,384,645,558,977,45,540,679,920,501,847,920,614,975,192,339,381,703,700,151,728,110,55,313,116,392,110,432,170,106,188,624,155,575,187,734,379,238,969,465,299,632,794,438,108,102,860,437,566,74,739,392,123,910,211,528,864,929,20,42,118,549,180,562,687,998,250,822,994,805,317,344,618,751,218,430,192,545,450,972,853,383,444,220,472,806,252,861,520,77,157,898,379,359,607,619,437,197,740,709,758,849,618,97,951,606,863,191,118,452,588,656,135,54,17,107,924,91,660,912,365,630,936,651,161,293,697,288,596,528,834,715,655,119,510,912,454,549,405,306,206,39,489,334,228,466,533,8,585,949,873,697,599,732,633,108,181,997,630,102", "196,73,182,835,442,512,31,804,501,917,843,804,426,662,918,160,938,279,956,856,10,562,429,754,558,98,815,698,766,118,468,958,554,90,768,307,879,816,956,535,892,112,426,262,952,972,618,84,349,36,446,997,696,827,86,930,118,418,993,629,99,768,895,304,603,527,546,866,264,739,226,689,736,1000,756,852,931,79,487,66,897,974,43,966,611,843,732,573,35,238,504,609,951,208,554,698,484,563,265,320,218,428,445,210,849,463,673,762,30,873,800,742,339,311,631,410,486,888,542,680,947,69,345,579,109,87,145,837,425,413,470,492,868,719,921,636,722,672,814,35,313,456,453,328,537,771,879,19,171,173,515,130,410,540,617,723,221,579,757,629,991,134,922,274,936,890,603,932,656,51,656,29,772,472,195,145,792,863,595,372,750,939,429,279,216,542,493,269,538,146,874,810,29,969,382,280,944,768,473,30,562,751,764,216,268,318,397,809,723,596,869,301,965,94,31,931,475,284,579,956,817,471,499,2,26,508,147,893,884,754,71,212,555,854,281,492,777,169,868,542,681,284,518,380,469,225,427,576,472,985,618,252,832,225,759,204,680,9,453,343,657,740,992,916,152,192,990,952,765,111,641,648,352,193,490,156,323,313,689,833,804,721,190,544,782,404,771,269,441,291,295,695,873,164,522,359,453,462,67,16,512,903,154,764,802,883,673,797,520,714,311,332,888,738,502,99,176,326,564,565,574,515,225,624,960,393,899,930,766,678,572,713,365,909,215,62,200,472,108,616,442,927,740,623,422,954,659,469,473,993,0,841,306,390,97,777,25,255,121,30,230,808,668,881,969,909,889,65,441,367,362,745,804,715,929,255,346,379,126,650,498,53,986,153,207,876,875,751,101,326,860,730,241,966,558,799,256,691,511,563,989,844,802,248,642,265,44,266,598,517,256,22,398,716,245,990,34,282,822,742,891,42,606,260,14,222,895,33,578,144,983,981,979,951,751,747,21,157,35,286,699,855,783,935,404,875,578,301,943,940,841,714,914,806,274,46,693,79,787,189,41,461,154,885,479,788,126,492,845,223,262,453,594,217,837,729,597,2,108,435,885,251,654,235,919,569,129,699,831,341,101,895,642,612,327,231,22,269,684,399,476,279,14,956,829,325,661,443,747,852,529,849,423,626,813,85,804,738,393,365,889,750,268,444,909,17,427,800,779,319,44,852,340,582,696,715,996,370,916,721,882,718,176,889,398,781,776,425,499,226,646,52,523,21,587,622,263,40,644,574,558,102,977,806,930,473,256,121,986,456,526,653,218,636,728,383,236,72,419,911,688,970,731,368,375,874,864,910,216,766,938,514,845,167,272,219,255,327,464,616,867,425,56,532,964,707,763,44,866,590,453,515,962,43,442,541,811,370,272,896,232,832,65,705,905,279,490,330,417,447,412,500,530,579,387,788,811,343,875,886,237,759,703,606,205,50,959,761,408,716,292,315,952,995,62,563,29,594,236,878,306,432,798,311,548,621,921,951,677,202,628,709,803,979,438,652,951,613,563,772,9,49,310,860,895,510,103,11,872,698,233,972,530,87,439,29,618,297,973,614,855,135,445,469,966,855,806,914,644,27,689,725,531,679,877,311,893,431,660,323,18,731,764,518,380,5,88,217,793,717,275,629,934,678,251,967,952,857,230,372,939,958,560,90,21,32,636,832,488,731,472,662,60,386,86,345,973,927,617,960,30,742,328,770,862,421,876,201,874,720,547,435,230,972,518,117,317,624,235,783,55,898,738,62,326,761,797,829,141,158,93,523,859,510,340,439,96,862,448,527,791,91,103,260,798,884,390,645,94,861,565,793,297,719,558,766,562,727,978,288,691,594,101,680,944,443,83,244,113,464,891,245,715,382,774,550,378,123,356,4,68,315,525,833,62,529,689,602,560,545,365,502,61,282,540,960,667,74,191,536,146,30,840,168,893,601,319,582,414,484,631,32,667,280,10,641,40,816,192,941,351,579,439,198,6,749,317,677,457,438,875,360,110,162,979,606,638,95,424,32,518,509,966,412,980,999,305,650,942,108,72,733,671,263,409,598,488,531,299,758,181,887,511,626,157,346,57,326,103,482,961,974,839,870,980,720,966,32,181,49,943,790,915,283,355,747,982,831,176,608,473,437,560,371,497,296,874,851,327,502,563,329,169,774,835,789,596,307,393,570,373,615,236,150,57,287,770,276,361,265,230,815,778,889,947,393,296,612,440,246,629,616,276,187,312,412,276,585,599,83", "868,837,126,148,888,569,743,956,509,277,896,444,986,768,323,509,812,34,745,463,126,383,192,731,764,238,103,602,115,809,713,344,205,678,50,634,816,212,750,364,960,790,331,398,800,501,84,84,299,444,894,469,743,445,760,624,100,291,106,166,398,926,593,460,8,827,507,403,400,857,626,773,702,402,526,552,886,824,990,562,711,728,643,12,118,179,330,288,575,67,504,814,736,652,669,481,391,261,234,284,81,210,19,81,939,72,550,190,614,185,433,504,751,606,947,296,619,899,666,197,727,336,369,282,37,560,599,249,751,389,299,550,399,777,33,131,443,443,200,909,249,989,234,38,343,268,594,833,872,880,806,836,605,468,745,214,523,739,377,927,251,785,419,203,634,804,681,464,270,19,364,841,445,35,269,403,290,16,109,586,700,913,158,333,776,222,103,726,891,668,609,650,845,506,827,578,979,661,531,839,304,477,303,348,664,690,123,555,298,851,232,98,31,280,461,31,387,906,535,355,990,846,858,26,229,815,215,887,230,274,40,551,675,642,279,39,79,928,574,96,682,508,292,720,355,208,144,183,93,586,415,493,581,985,82,139,500,484,906,954,821,11,449,526,380,785,466,708,428,56,230,431,633,667,576,705,377,177,684,240,159,606,891,666,931,534,341,525,213,669,367,817,239,73,55,54,566,875,700,87,891,994,433,357,207,653,879,445,875,128,750,968,275,136,852,849,365,45,817,770,561,130,307,629,868,107,819,559,600,325,284,335,545,127,210,587,313,636,951,608,466,157,506,635,53,921,335,660,134,910,841,0,414,749,343,307,867,366,246,784,260,2,740,480,988,42,113,494,569,474,643,791,820,873,605,771,673,253,96,604,879,777,702,148,63,498,810,215,884,791,574,371,888,27,402,338,646,151,996,101,490,302,685,440,64,831,418,838,293,306,177,881,939,321,304,656,530,470,291,138,269,314,832,338,344,762,529,116,261,438,339,750,842,352,263,130,434,807,439,765,212,552,220,789,768,370,481,687,633,469,955,453,292,819,357,376,930,749,465,232,972,839,871,886,84,135,812,672,281,704,236,237,823,507,638,311,876,189,588,802,374,105,88,817,754,786,467,516,756,432,792,750,927,844,702,421,460,387,116,537,373,19,510,791,329,917,914,807,160,811,234,978,401,211,292,620,576,41,207,447,441,93,964,409,105,66,906,224,826,391,788,237,515,10,456,811,664,430,955,739,141,292,313,380,58,123,627,639,648,292,203,782,689,154,53,48,938,231,404,411,982,685,598,803,408,200,272,51,910,956,646,105,739,700,205,113,8,958,995,418,534,235,267,201,829,309,143,806,237,899,90,732,456,950,671,819,33,356,839,105,208,293,647,519,886,774,85,237,968,527,230,935,451,728,405,854,440,791,40,738,103,679,295,725,327,206,836,619,851,327,941,931,542,970,399,281,990,217,517,470,705,220,976,200,854,886,700,881,105,610,997,114,744,546,806,848,658,684,1000,755,730,467,397,1000,212,268,926,268,657,381,177,338,51,138,107,498,20,495,535,925,283,463,133,542,878,993,974,595,951,971,743,128,314,73,494,207,465,751,22,819,173,886,882,238,891,305,162,932,182,604,773,65,932,682,670,265,966,926,495,489,917,98,2,361,707,837,624,868,88,849,144,823,92,313,242,672,623,889,260,967,263,672,200,106,719,848,88,83,915,7,202,801,44,102,194,508,230,558,718,739,451,780,182,480,908,969,144,236,703,203,80,171,436,175,360,729,891,527,768,830,653,152,124,691,804,222,920,483,322,983,841,13,742,898,189,201,288,573,148,378,214,673,714,221,789,477,962,545,429,610,555,958,237,987,936,221,744,103,159,669,279,934,613,482,527,198,783,786,335,611,78,554,508,562,429,129,363,408,873,216,648,405,460,665,789,20,569,301,858,593,536,493,675,999,828,692,374,360,584,117,333,831,238,879,903,889,65,494,659,526,532,493,484,457,318,166,947,843,542,627,694,91,398,188,295,51,598,214,149,636,819,610,608,699,609,160,412,890,777,189,15,642,366,370,673,595,481,834,934,850,839,371,888,703,656,631,249,530,553,46,869,114,258,796,549,601,946,137,800,478,432,52,451,33,332,974,146,452,406,814,373,736,500,851,764,463,3,76,269,426,75,374,758,533,971,185,485,621,281,715,639,629,542,673,409,633,691,689,885,669,897,142,604,591,688,877,508,873,335,856,818,271,666,462,216,805,747,256,103,850,999,971,42,301,873,428,501,180,740,696", "18,600,672,453,513,328,275,239,624,905,953,503,253,161,623,618,137,303,353,70,341,940,291,63,955,888,493,616,46,524,845,625,891,421,600,310,210,143,138,285,807,466,234,974,945,869,799,18,65,272,527,134,44,324,528,77,929,75,502,459,393,196,464,952,931,279,116,805,498,965,682,450,841,586,446,946,462,442,641,451,718,201,66,838,894,702,339,886,326,752,934,608,456,86,369,520,883,877,963,343,446,846,915,43,765,427,266,17,309,636,387,555,153,889,847,596,269,954,75,674,304,951,700,100,312,812,200,534,953,867,115,950,359,157,137,602,477,992,799,556,107,46,861,122,681,554,528,865,675,616,423,697,791,420,967,834,827,370,102,332,54,213,277,441,27,434,24,62,216,325,132,298,365,521,62,992,674,567,46,761,746,711,444,318,763,288,989,536,498,644,432,939,954,811,356,984,75,843,198,653,501,301,418,887,123,736,478,111,842,218,877,282,918,556,900,608,874,331,783,68,685,296,290,934,910,875,879,688,415,936,423,83,359,213,157,33,559,94,106,95,307,176,739,930,908,467,728,224,868,375,742,248,668,863,439,996,418,457,64,312,940,580,583,566,138,866,206,685,188,769,190,793,100,474,812,579,212,13,429,226,553,395,938,496,431,497,309,442,638,857,254,352,887,253,585,494,190,712,856,773,194,413,325,971,916,526,822,563,248,531,698,78,753,908,313,791,383,628,157,569,254,952,221,328,558,147,505,592,649,196,942,479,472,561,16,571,32,533,944,802,961,124,919,454,34,322,599,50,98,915,306,414,0,631,157,172,955,710,109,159,480,652,266,151,664,155,940,750,627,228,937,287,52,107,184,311,443,240,631,245,81,327,81,492,81,706,19,477,702,715,167,545,93,910,933,469,569,273,510,757,200,862,671,546,320,36,938,459,559,613,442,618,839,919,153,232,492,904,964,900,633,13,871,74,573,550,209,57,117,394,153,553,995,105,177,752,860,630,772,735,860,948,242,239,641,382,404,542,126,222,160,479,436,665,194,632,261,460,562,264,69,801,183,454,351,876,634,740,78,6,652,605,964,258,480,952,190,986,914,186,865,922,475,108,191,249,355,873,619,439,999,961,431,216,865,326,24,849,101,575,749,126,648,456,949,848,106,190,332,673,625,293,26,995,158,989,59,347,928,468,262,7,428,426,721,70,886,126,515,659,272,862,480,91,497,10,834,780,218,801,696,266,688,29,734,586,32,351,343,671,778,739,753,870,278,178,588,915,343,985,905,36,180,917,706,571,864,902,181,326,486,977,928,941,48,84,847,800,236,211,139,22,411,946,732,794,785,32,675,685,942,687,851,161,225,243,421,766,78,13,768,885,382,549,608,332,550,602,842,135,569,760,122,736,627,285,427,690,316,482,513,10,780,282,784,668,354,66,557,363,905,726,576,981,98,179,186,316,282,733,591,241,834,165,421,16,234,868,995,458,37,172,404,436,936,480,659,945,448,869,148,392,103,461,228,160,884,130,378,401,464,251,659,657,961,638,441,396,626,453,784,280,512,915,137,546,325,330,611,632,419,299,508,959,98,902,312,177,869,134,391,879,673,817,715,594,904,171,208,924,838,83,276,709,413,621,925,581,242,934,782,465,653,634,323,205,694,112,916,978,192,678,915,422,812,377,236,632,403,492,698,516,770,233,919,640,509,890,562,82,548,322,882,472,661,736,100,549,559,700,447,473,523,958,891,962,751,9,655,339,675,240,480,544,980,644,190,831,290,252,290,467,281,622,305,305,469,559,136,13,390,497,539,878,466,499,648,415,989,346,751,92,581,284,610,768,486,964,846,272,636,177,504,463,495,928,925,41,795,33,475,373,847,633,870,949,735,953,66,402,751,806,637,746,575,714,32,183,251,116,404,838,807,748,964,357,437,381,660,650,283,117,515,878,991,671,294,509,677,719,455,841,794,607,667,396,544,371,581,507,118,223,484,367,442,763,982,189,856,560,548,358,842,346,629,426,384,538,791,208,812,917,122,480,634,573,966,848,500,519,149,868,892,901,359,122,579,440,754,877,148,655,905,668,308,301,719,530,312,269,114,918,584,572,482,609,649,67,265,685,255,393,188,18,661,414,696,907,3,820,147,799,525,424,365,477,352,472,453,752,976,526,968,394,802,351,125,900,680,514,928,634,867,537,484,35,180,67,784,670,65,61,448,861,709,767,58,436,518,352,359,538,838,101,276,866,393,541,116,304,449,505,833,280,633,467,411,712,244,522", "555,762,693,881,754,903,381,61,812,449,608,406,884,566,901,345,790,268,303,707,793,506,428,423,940,284,53,514,664,157,394,252,258,426,806,558,804,949,327,598,262,975,693,607,377,404,557,252,976,943,182,92,898,676,744,113,643,940,332,459,240,928,747,273,549,197,370,638,500,886,864,627,111,598,16,487,752,912,50,806,843,522,561,493,830,869,241,184,123,958,991,256,948,227,787,43,775,910,557,966,956,878,28,214,202,211,115,6,701,349,658,780,456,967,188,336,674,856,60,46,869,638,608,350,402,345,275,51,673,12,857,355,698,898,613,702,615,615,643,174,946,966,90,634,826,510,295,635,164,693,343,733,590,797,332,959,528,543,885,260,636,532,736,164,677,351,695,754,793,995,229,309,993,79,65,347,259,582,396,908,746,3,129,286,795,246,146,119,742,796,288,583,760,61,750,458,306,119,822,420,845,925,505,14,586,827,265,416,669,649,134,767,243,976,643,843,6,325,796,760,185,720,690,407,461,868,797,863,316,950,73,65,153,507,615,784,902,958,249,54,175,436,327,819,399,247,228,208,352,761,563,343,326,207,175,406,956,894,505,884,767,340,773,934,796,344,830,893,824,88,643,384,197,511,58,646,57,390,423,222,593,767,213,469,420,698,506,579,299,357,690,938,25,141,751,49,930,676,115,593,182,950,429,700,203,768,339,496,355,844,334,675,106,140,711,681,751,395,70,615,325,404,689,562,61,936,625,484,392,915,461,304,715,204,865,798,171,361,709,10,242,428,236,577,690,307,61,750,486,842,390,749,631,0,73,574,388,291,90,718,210,74,448,922,648,588,549,702,876,485,742,844,737,907,828,123,864,894,46,940,926,827,500,380,437,937,436,249,508,356,264,416,164,684,506,357,319,255,725,151,909,62,756,512,169,471,762,294,595,181,713,964,578,393,976,924,403,470,859,665,837,300,128,674,77,848,906,749,729,756,330,156,494,330,755,829,595,962,186,76,940,789,792,646,373,265,32,479,433,45,903,720,349,872,561,565,189,116,998,294,291,482,42,127,117,347,969,181,897,851,635,990,551,559,24,337,760,766,790,512,148,388,87,219,533,726,946,193,851,453,208,691,945,649,970,508,225,808,290,171,921,733,415,886,580,244,697,259,17,313,784,414,305,309,542,965,340,651,659,431,90,71,81,752,262,840,300,503,492,966,692,695,705,401,597,766,254,983,114,767,406,862,980,120,59,549,541,696,247,437,190,640,536,732,626,689,200,28,53,549,50,648,293,409,774,571,134,525,446,549,944,646,825,569,834,345,534,16,535,785,153,967,531,767,964,487,271,958,981,788,384,778,754,616,512,842,498,828,439,549,347,227,964,991,858,915,9,866,758,602,921,301,76,239,367,905,446,183,329,563,657,541,886,192,837,518,491,881,802,707,621,826,592,3,963,278,361,247,794,950,583,53,406,20,754,786,763,536,312,115,877,276,771,517,222,214,130,156,664,594,7,738,660,778,205,398,204,645,650,899,519,573,309,400,175,44,986,826,149,146,723,232,440,622,524,55,857,103,545,903,709,977,502,605,344,71,706,542,774,936,660,729,231,276,695,293,1000,609,408,948,104,642,433,15,972,62,729,256,744,46,6,17,157,675,992,25,552,337,527,905,267,86,833,541,837,622,97,166,335,443,869,784,76,535,137,151,182,860,595,106,887,97,338,10,435,886,643,847,980,547,735,270,757,115,611,943,175,658,581,780,917,300,519,664,73,168,236,521,262,263,881,58,109,883,112,442,4,954,80,661,181,546,118,685,183,81,671,339,718,382,347,882,738,642,929,35,923,249,553,743,96,835,887,644,304,892,206,36,427,241,26,292,717,703,488,938,770,799,745,641,268,638,508,998,69,158,92,613,970,145,868,939,924,71,981,177,273,676,725,392,624,918,48,422,508,684,449,674,173,563,465,734,979,811,731,431,49,155,57,661,936,100,587,982,309,670,420,832,343,64,449,538,423,278,398,913,15,878,50,877,411,636,483,972,284,550,142,746,959,640,759,895,421,611,949,108,446,994,671,687,606,646,238,444,348,831,304,511,610,133,123,620,432,398,498,631,388,192,547,157,652,32,91,664,689,191,540,209,900,617,255,268,947,177,31,964,616,132,956,188,762,823,17,998,807,849,798,906,99,73,267,245,740,229,594,739,424,615,145,560,474,860,252,311,675,458,175,711,845,251,899,542,632,619,655,407,879,692,852,644,144,93,989,196,713,397,597,547,645,215", "746,337,864,774,614,32,874,384,288,777,7,877,52,554,566,147,77,165,182,533,422,583,804,816,735,628,764,528,509,912,651,297,140,471,449,64,360,549,39,120,663,898,218,928,615,331,194,399,58,157,691,666,414,274,443,768,639,845,399,580,575,889,414,519,663,543,301,753,558,335,737,302,114,831,421,368,492,322,391,500,633,268,789,89,122,951,93,105,576,633,780,815,851,552,407,531,654,908,202,219,897,940,83,364,171,871,781,772,999,76,717,509,878,712,45,917,505,18,260,662,263,432,694,543,480,334,743,109,36,536,770,944,346,217,706,517,129,6,769,873,598,600,375,634,544,311,389,380,293,48,460,619,696,107,110,6,478,64,211,382,973,55,289,293,565,575,696,254,14,811,345,355,733,938,786,96,167,92,750,127,280,842,194,410,982,406,5,406,232,929,621,186,707,799,512,682,728,669,788,646,456,262,59,164,483,783,143,902,710,711,404,768,393,526,828,175,672,244,440,410,789,877,252,409,525,7,210,690,580,370,563,153,890,151,536,727,610,211,857,690,247,770,459,584,86,917,604,402,354,812,785,15,654,860,549,231,970,923,544,482,554,472,760,858,979,102,663,689,133,378,263,841,882,144,562,673,562,149,541,431,46,215,667,616,474,770,238,849,68,604,666,112,128,873,955,524,969,558,268,345,357,12,805,155,284,551,487,294,439,214,907,598,165,181,293,365,172,278,899,700,31,332,527,459,600,822,597,653,528,978,319,321,405,451,133,580,859,984,280,244,860,942,922,921,138,520,630,618,126,554,97,343,157,73,0,33,849,675,66,952,204,733,315,618,953,925,414,317,927,977,124,302,690,933,169,91,975,408,671,457,437,145,908,626,869,690,891,80,761,944,938,4,186,851,231,797,70,119,394,646,765,994,557,124,681,667,684,737,939,589,242,130,808,218,329,273,839,703,863,235,279,738,976,422,736,928,379,702,120,694,802,41,247,38,197,920,264,241,566,410,153,784,295,239,43,970,765,279,535,942,354,410,693,991,934,94,952,996,671,586,788,489,654,40,659,4,448,622,568,176,386,232,816,267,765,925,14,517,269,198,410,876,259,72,861,521,506,204,513,564,608,508,230,468,581,205,257,69,234,351,255,588,362,953,78,31,996,265,944,330,721,353,575,349,86,655,400,587,502,678,420,664,243,127,984,832,166,528,205,120,993,538,815,800,519,188,983,646,370,102,324,646,82,448,64,279,404,148,447,15,859,741,323,490,279,194,427,597,819,365,389,284,400,953,105,703,720,333,682,627,51,350,311,117,71,893,278,568,842,773,715,515,996,813,960,520,648,532,948,458,222,103,840,854,766,255,779,744,772,97,911,149,54,500,456,759,636,24,129,521,728,991,858,727,494,525,968,981,422,602,126,717,743,88,767,318,441,590,420,467,541,86,336,277,567,527,462,609,620,304,114,882,363,970,532,831,247,198,191,353,302,553,598,311,836,343,933,491,382,504,177,749,630,617,596,351,668,74,159,801,789,552,200,180,840,950,648,287,508,218,684,858,791,23,942,413,127,635,310,819,870,473,823,792,133,306,863,912,948,588,874,850,255,971,996,936,83,43,825,10,111,454,717,710,381,402,669,597,332,724,320,13,706,193,699,232,855,21,406,660,379,851,86,952,566,776,766,125,238,386,414,547,474,894,703,589,802,932,367,970,949,413,269,86,824,451,672,473,393,97,97,192,574,69,512,405,735,338,154,213,890,402,695,978,359,461,300,47,652,277,5,219,776,138,578,127,945,102,954,659,369,893,268,907,582,952,926,743,725,544,472,310,873,194,57,761,463,908,52,166,550,736,186,124,672,960,602,786,290,742,674,74,718,690,198,91,66,63,937,886,507,601,897,367,170,747,655,199,52,504,973,727,547,481,552,404,457,389,572,448,332,457,958,144,899,240,20,273,455,850,487,249,161,388,90,153,140,907,232,394,525,52,612,360,707,987,483,232,491,652,934,94,174,42,419,289,214,573,148,180,524,224,454,41,981,809,998,912,625,705,679,117,870,427,191,355,416,183,49,936,898,538,856,158,414,859,577,140,915,320,259,570,635,423,48,116,419,955,146,896,988,495,915,213,227,855,581,785,994,542,324,599,421,718,863,62,609,578,60,744,480,778,161,884,646,995,70,534,761,783,889,433,982,110,896,902,867,428,466,610,958,511,626,689,710,502,505,193,867,576,672,423,156,295,615,33,89,457,244,846,948,836,404,588,112,953,864,455,16,404", "142,555,252,126,277,657,906,489,262,206,311,729,651,647,953,788,499,867,874,213,994,362,561,616,337,212,188,624,882,268,806,619,545,996,974,621,986,42,756,612,172,855,873,755,740,689,527,304,69,391,728,516,87,885,565,254,428,524,699,621,14,463,481,290,886,7,831,983,218,912,31,991,302,895,346,440,268,283,349,84,424,550,550,369,459,204,700,321,318,9,934,496,433,685,161,311,827,349,815,311,443,457,417,183,68,483,366,849,862,234,8,677,389,906,206,816,256,293,962,249,63,773,829,140,696,889,270,208,659,561,758,554,155,346,584,256,912,107,392,743,509,74,729,828,176,117,889,501,33,882,147,126,326,847,704,765,736,224,642,190,655,660,456,492,982,398,124,521,366,772,764,84,85,254,559,571,432,728,388,262,300,965,308,138,762,855,281,408,288,109,601,49,879,240,155,93,901,352,370,19,643,772,206,83,476,958,190,408,635,180,510,972,590,896,183,458,536,934,875,939,729,468,160,869,187,18,823,296,646,901,176,86,858,340,266,130,747,456,537,228,903,270,654,917,875,422,206,900,308,746,487,58,180,308,650,154,20,90,425,266,864,482,64,147,796,856,410,678,992,775,930,952,87,164,866,183,778,232,398,179,242,398,409,488,103,34,324,399,836,769,264,297,331,503,4,736,400,960,323,497,325,285,239,816,393,343,161,873,772,589,218,354,437,481,105,436,144,566,217,972,324,30,678,952,803,754,548,525,428,56,767,57,611,54,815,192,216,642,492,630,59,6,630,595,856,654,115,323,685,65,777,307,172,574,33,0,494,168,816,590,708,379,714,560,630,662,473,743,120,357,770,959,156,693,545,489,67,452,787,796,116,96,336,141,915,190,525,73,404,472,280,741,728,460,53,938,764,563,803,600,514,206,312,471,959,886,50,849,14,985,872,584,131,619,620,464,492,827,524,524,199,38,60,441,695,341,975,686,706,588,576,693,896,314,883,916,772,814,73,208,352,886,894,889,766,702,410,505,457,987,256,635,762,574,273,493,818,450,762,447,790,618,916,792,339,203,489,205,999,39,416,397,492,649,398,284,245,250,592,261,516,272,873,919,472,223,567,390,420,571,196,140,981,789,177,177,419,106,409,929,286,444,109,298,814,566,496,870,813,976,546,486,442,680,60,924,532,988,809,326,187,787,649,50,296,344,920,703,476,647,789,780,153,135,104,708,905,655,605,344,217,581,679,633,950,657,124,812,531,123,899,585,348,232,38,562,86,701,225,106,942,217,330,727,891,283,315,216,762,522,642,282,62,477,59,240,894,994,128,928,8,404,309,661,718,323,716,784,125,468,213,796,859,117,935,835,687,583,623,398,640,155,633,405,213,129,639,813,215,64,940,145,151,934,403,560,790,570,3,613,973,138,71,331,921,240,151,429,439,529,265,846,502,722,412,146,416,509,969,309,938,400,821,343,790,843,719,53,57,883,396,917,573,428,998,704,989,662,144,148,730,561,855,562,672,70,68,457,464,179,244,71,262,474,251,373,114,917,327,709,505,180,257,454,963,67,18,11,586,386,97,224,440,524,632,633,793,693,454,721,68,88,242,906,344,94,567,318,459,703,631,382,297,146,261,662,629,244,733,561,842,329,622,91,457,544,591,898,362,191,261,417,675,301,209,651,533,382,976,909,685,563,69,690,524,307,169,918,286,293,338,793,427,628,902,263,52,259,970,37,794,137,664,174,504,88,617,131,723,354,989,21,615,67,729,462,322,232,733,607,963,628,270,551,644,344,860,979,753,726,175,640,906,573,334,284,65,35,863,14,749,114,149,210,727,686,220,469,763,120,165,375,373,231,808,122,264,867,859,877,551,348,995,653,944,42,42,282,62,588,184,625,555,820,276,982,900,146,849,758,897,609,975,6,210,930,928,438,710,364,876,832,10,184,558,737,843,148,6,144,809,306,524,536,998,527,137,384,231,152,405,703,96,981,162,113,852,750,360,816,243,166,957,584,667,163,629,960,704,819,664,482,481,958,556,932,303,35,172,254,458,63,921,277,65,697,824,569,478,241,343,787,711,489,719,47,496,185,632,932,359,289,728,698,331,149,773,828,92,24,1,206,408,882,553,971,166,181,889,537,701,789,203,184,872,502,49,754,690,413,987,35,952,533,295,891,428,661,633,538,884,913,996,527,551,557,167,659,906,804,635,290,972,338,149,673,208,392,902,35,568,729,579,877,625,764,450,172,872,1000,993,807,400,569,201,664,874,419,146,315", "170,950,424,782,764,890,921,226,73,819,690,542,725,267,59,767,26,503,824,964,782,837,797,963,205,860,935,480,310,627,552,412,402,570,935,113,177,611,643,782,888,179,341,628,849,719,872,524,262,454,752,470,412,448,845,550,726,865,258,990,447,558,389,311,730,223,780,800,221,247,682,857,102,976,150,707,945,459,640,225,566,576,873,360,865,171,733,206,174,178,667,545,756,299,241,666,606,263,83,409,160,76,657,51,856,62,105,903,71,903,227,386,927,55,718,919,705,476,910,166,671,299,165,835,858,831,833,572,30,29,31,92,847,381,111,444,281,523,879,277,656,376,578,344,696,349,272,488,115,610,76,207,302,105,801,947,322,479,696,120,309,745,734,794,963,839,799,501,576,13,155,264,240,974,633,775,616,905,446,603,986,975,579,912,637,758,159,644,900,84,716,696,287,144,971,280,826,748,224,846,941,941,867,171,94,887,414,596,905,22,447,909,597,937,455,416,226,942,983,356,331,666,705,135,686,626,746,453,781,140,538,67,225,675,331,112,831,243,585,274,875,537,749,624,490,236,941,274,387,450,48,829,46,229,568,125,701,787,148,131,609,793,571,991,681,506,871,597,483,10,577,235,666,558,831,293,708,181,856,254,38,402,310,376,537,439,114,74,722,68,998,549,755,238,936,765,896,637,807,662,619,839,829,110,213,896,41,648,830,948,216,569,304,28,510,982,32,406,690,473,760,219,44,203,542,857,121,667,857,839,257,889,839,203,544,497,429,857,21,954,628,277,591,637,998,619,869,615,948,106,25,867,955,388,849,494,0,937,585,495,201,557,920,347,213,476,756,489,171,853,933,839,739,750,898,766,916,702,656,685,83,872,562,582,35,822,26,684,673,529,623,273,358,7,60,167,133,502,458,222,284,565,791,587,288,549,400,124,117,712,895,549,975,58,904,428,354,733,315,925,909,598,831,279,145,232,154,360,181,447,611,748,208,731,829,534,498,845,613,864,606,799,179,796,744,595,205,206,549,695,976,698,710,628,187,946,847,94,719,80,658,527,720,655,80,759,165,17,372,609,465,559,134,122,505,457,258,247,406,902,170,748,110,93,121,292,999,500,991,416,592,216,530,871,826,277,39,460,206,945,107,926,911,100,26,242,247,982,76,864,679,377,969,666,307,592,66,356,251,167,446,966,128,265,285,362,694,445,768,417,991,57,154,633,112,937,427,551,131,386,157,619,348,258,386,303,498,309,855,259,545,156,169,94,185,400,461,60,349,931,405,161,499,804,361,593,24,876,663,391,992,768,960,522,445,185,840,460,619,248,96,43,926,625,643,926,640,610,545,909,773,812,632,583,380,756,399,443,326,477,147,126,861,678,856,373,397,531,209,80,632,648,636,221,14,276,820,594,606,284,63,527,966,80,525,281,984,862,114,70,240,232,453,397,933,132,345,331,441,508,197,487,522,157,956,181,698,792,280,531,976,377,827,570,911,429,232,255,385,407,43,349,524,829,934,928,29,91,728,320,853,498,561,929,319,128,709,304,804,462,35,637,929,860,533,377,429,633,943,701,211,816,223,791,576,52,714,409,259,569,101,324,815,679,779,136,358,710,822,540,861,998,714,15,463,552,212,763,408,128,565,563,71,620,269,306,454,163,165,801,538,5,627,816,959,644,449,746,181,195,218,422,456,27,363,361,992,988,182,338,337,14,971,12,303,883,414,367,514,821,312,151,301,847,654,115,847,457,212,616,265,547,665,227,170,610,662,117,684,381,447,665,362,816,914,230,4,819,681,384,699,636,696,122,961,402,783,36,499,286,73,689,845,986,815,254,897,190,570,120,153,698,717,517,746,675,772,445,447,281,334,281,500,833,117,96,225,421,257,90,690,912,427,916,110,856,480,554,237,838,806,276,987,911,660,295,578,283,431,341,885,701,630,934,974,544,507,997,391,645,794,285,452,935,958,490,535,935,362,480,524,385,488,644,64,995,747,801,757,558,864,357,534,688,650,213,352,851,485,957,580,657,833,189,228,211,861,522,912,448,182,452,364,59,522,223,207,857,784,436,201,589,301,234,97,626,509,302,881,626,182,101,39,124,173,48,901,167,222,230,560,581,923,870,421,659,725,235,37,980,196,616,42,945,628,532,403,269,962,205,675,733,678,365,43,233,899,21,602,299,62,407,105,161,2,27,48,184,435,810,658,557,817,454,376,782,880,786,63,49,904,768,586,665,141,333,148,82,2,74,43,64,105,606,242,78,883,200,45,66", "75,316,351,884,716,789,596,356,464,542,903,11,460,532,252,506,72,318,565,350,34,81,825,90,157,206,859,988,55,79,948,211,334,502,895,664,222,385,153,593,922,785,559,308,476,306,459,987,641,109,826,589,492,746,939,770,403,161,208,31,94,248,880,429,789,548,847,513,440,702,845,29,650,493,466,734,837,514,385,282,485,344,12,379,267,732,938,675,544,425,972,612,157,216,272,156,461,459,165,628,711,866,636,473,776,645,116,577,454,476,110,524,934,533,880,852,6,663,593,360,238,664,538,205,958,396,58,454,779,266,511,687,509,926,575,683,533,476,448,842,161,281,5,184,328,161,299,691,682,573,400,224,700,702,722,364,429,852,280,272,36,454,959,965,529,929,458,602,456,624,57,386,318,302,633,215,956,626,57,19,707,357,49,773,677,835,155,10,625,694,150,718,791,459,258,490,523,135,136,61,53,158,980,79,50,88,733,996,253,754,953,493,480,472,460,390,248,972,752,268,801,204,787,384,777,18,811,771,605,257,926,244,221,660,838,55,344,350,837,610,394,519,491,46,673,655,593,938,2,595,968,556,440,145,963,565,341,571,996,376,823,293,606,595,702,427,173,803,626,89,967,489,543,945,611,432,913,271,274,800,357,683,294,930,867,224,774,111,673,467,191,32,306,586,81,226,108,462,807,865,344,656,344,73,96,859,117,115,96,320,292,911,141,272,344,173,167,514,57,358,917,58,740,695,512,187,452,670,697,915,646,58,147,303,791,46,837,352,861,720,609,799,878,946,458,161,990,696,331,500,255,366,710,291,675,168,937,0,549,562,735,518,523,452,833,284,619,798,505,354,51,867,270,659,600,386,155,501,934,161,261,324,190,576,307,165,205,355,446,331,456,458,354,144,155,174,723,955,938,772,549,979,547,940,607,122,693,776,368,921,404,8,179,491,632,46,935,88,368,309,904,787,664,823,947,229,904,263,555,385,988,780,552,559,967,602,283,437,829,737,585,277,116,391,376,148,664,134,569,297,993,496,304,787,810,931,83,557,297,124,55,744,552,348,418,103,338,55,271,797,915,66,546,585,851,201,248,830,681,341,920,645,906,866,718,470,818,858,749,496,732,523,79,767,423,419,814,500,275,432,984,549,592,267,702,916,31,908,538,497,747,474,323,792,257,148,268,590,48,246,436,972,530,510,370,56,215,192,700,240,83,621,224,108,355,250,462,639,149,840,19,658,592,836,45,889,361,953,409,11,766,553,682,165,610,91,564,245,3,156,688,493,462,466,936,774,883,894,822,465,922,86,732,206,382,622,332,341,152,430,548,206,705,998,436,934,593,23,930,230,456,582,516,327,782,690,285,987,25,827,616,685,238,577,784,517,134,179,77,760,386,331,130,891,955,325,698,443,224,635,641,613,19,461,48,275,521,218,262,179,577,321,319,612,445,417,295,563,760,79,779,723,466,800,778,388,870,473,263,219,692,428,169,711,915,672,708,684,935,364,83,300,753,577,587,197,255,682,644,129,609,746,638,251,127,486,564,443,192,542,837,425,611,275,972,977,949,715,295,838,539,936,754,333,202,252,316,663,594,606,344,832,807,741,399,616,231,107,787,508,188,601,975,943,555,599,447,347,522,522,994,53,833,401,95,444,455,711,762,972,593,826,401,291,747,253,862,345,874,568,474,189,752,265,270,400,854,216,988,657,135,341,559,653,537,648,667,140,723,12,162,287,805,77,179,423,828,152,125,558,151,249,695,712,451,18,510,452,602,439,727,137,860,41,193,354,896,777,797,210,757,549,928,53,441,298,814,195,502,747,229,764,318,156,245,570,430,385,374,250,112,322,755,245,364,570,681,550,355,275,492,986,689,64,978,816,395,86,692,723,184,875,187,483,707,583,894,577,198,569,623,531,425,12,128,7,728,781,69,330,829,674,731,738,375,712,210,955,949,956,213,38,726,999,61,781,182,496,870,130,80,767,456,412,687,227,768,691,96,990,976,598,535,530,235,935,43,192,747,363,257,660,980,550,810,530,232,773,68,990,770,873,8,81,653,138,837,510,865,635,325,437,893,874,791,407,14,874,689,224,227,32,743,487,81,982,400,466,113,408,45,962,270,389,673,987,857,240,646,159,460,785,857,326,151,727,676,322,320,209,854,411,839,590,537,504,797,247,489,504,987,208,830,121,220,145,468,760,4,773,968,203,770,452,333,90,76,650,688,728,482,699,876,92,976,878,931,917,5,648,15,293,998,286,642,747,126,838,216,673", "788,235,634,518,100,873,405,638,930,236,664,212,707,122,599,486,631,75,184,480,248,998,497,137,218,461,758,433,670,49,899,532,556,912,105,804,746,303,316,834,835,150,913,396,444,861,100,237,999,107,328,680,356,685,176,641,989,479,464,665,513,92,833,733,818,828,747,288,963,359,639,160,726,409,685,166,813,66,368,624,35,185,327,942,560,20,840,742,901,993,291,369,285,732,606,454,753,196,598,184,280,820,518,505,904,163,696,597,429,898,182,72,9,351,968,787,619,909,146,873,259,146,665,479,559,972,496,298,357,605,775,907,911,776,421,957,994,281,207,243,422,841,423,13,214,913,327,759,327,586,505,438,130,92,870,768,313,88,444,943,108,321,310,353,978,510,250,424,303,176,76,748,337,454,65,182,580,813,266,310,732,769,704,744,890,688,963,240,842,950,535,305,622,413,876,644,988,837,461,65,135,542,591,74,940,289,950,363,279,933,494,192,585,945,603,447,134,733,253,902,441,807,360,396,512,716,182,433,196,599,400,540,925,36,614,362,689,714,19,62,63,237,244,289,447,582,272,631,780,711,345,736,367,80,132,674,639,624,413,717,242,805,657,655,988,878,774,883,503,274,656,291,734,528,552,840,403,52,767,449,140,590,928,259,823,212,260,616,412,555,247,705,629,369,896,499,470,393,703,223,994,228,498,948,592,919,648,190,630,755,447,994,874,420,391,290,236,953,218,364,5,988,259,621,177,701,148,198,290,53,565,730,199,904,190,870,587,457,770,564,749,239,823,765,70,594,699,528,260,341,121,246,109,90,66,816,585,549,0,740,432,444,270,385,241,553,924,244,964,142,365,537,6,224,243,201,663,303,569,717,88,221,87,266,657,540,765,656,910,134,514,923,947,361,602,570,602,779,343,622,214,469,385,952,79,966,446,484,829,938,714,618,115,227,893,445,686,837,244,528,733,601,246,491,378,333,801,161,532,21,928,112,88,448,374,613,643,109,891,209,659,791,685,282,736,629,612,345,687,387,204,71,377,267,311,784,695,258,842,146,749,796,174,747,434,560,829,654,835,81,608,772,330,732,225,857,977,440,94,372,60,764,822,488,683,347,476,616,560,416,587,415,233,480,525,928,533,7,867,654,932,844,864,353,318,63,378,318,858,947,280,716,563,346,555,862,504,206,223,354,570,914,657,213,149,148,32,883,773,891,118,505,949,565,96,370,467,887,528,98,600,678,66,378,817,499,994,529,852,461,999,740,421,540,802,986,404,703,417,507,271,45,748,874,828,645,927,4,719,870,690,166,720,616,30,109,975,522,423,365,34,657,1,820,458,258,861,924,732,54,452,240,82,189,35,557,636,729,7,976,73,573,657,84,516,261,241,288,355,985,524,990,188,269,700,206,449,49,645,251,393,600,423,26,958,785,229,62,290,429,915,497,706,333,680,859,254,955,301,984,843,996,559,903,225,177,353,56,604,776,593,390,437,421,171,739,628,494,408,368,149,445,491,926,298,339,943,828,284,971,116,25,59,442,767,473,416,372,820,901,551,583,16,781,681,435,15,951,542,341,196,388,493,392,59,411,26,287,427,984,742,66,584,569,567,581,316,969,199,658,406,102,134,430,226,918,948,975,797,694,237,427,871,916,399,300,255,606,943,216,742,333,10,70,999,210,817,581,584,5,137,699,569,844,948,970,628,866,236,115,151,899,639,436,474,495,975,771,561,543,515,687,280,729,859,173,597,427,707,101,674,254,972,363,311,964,977,223,666,887,871,447,735,838,6,502,857,587,72,896,627,381,877,554,417,628,593,464,460,751,893,374,973,700,555,307,754,207,719,343,110,926,478,137,527,378,256,103,692,373,876,775,913,104,602,802,420,587,85,285,365,81,243,671,993,355,498,448,880,22,312,422,210,902,877,846,521,92,517,324,656,729,278,182,30,900,321,55,829,660,130,208,681,945,825,51,284,256,928,132,247,488,666,764,854,306,331,36,411,527,397,730,520,208,658,969,50,584,359,988,384,192,514,991,987,123,598,372,677,527,231,178,236,338,905,131,847,758,506,148,600,156,743,628,651,910,794,479,135,592,735,28,266,504,839,941,323,174,328,480,665,704,319,202,148,146,781,653,959,352,254,799,918,272,62,457,167,947,322,759,450,184,792,941,722,777,301,248,76,155,125,751,838,580,905,854,588,653,345,771,309,516,402,232,107,805,595,49,339,302,607,838,152,599,808,494,297,640,654,467,239,583,996,229,514,831,652,26,641,651", "675,236,190,356,162,258,75,990,953,609,116,86,654,992,719,833,587,296,139,877,726,472,493,660,594,598,539,250,512,449,307,287,171,16,568,348,740,779,118,29,834,412,494,408,750,678,968,262,484,251,773,906,19,220,289,591,181,342,710,645,359,338,46,202,938,714,651,229,472,585,424,849,277,610,201,377,724,311,315,375,169,570,522,174,628,729,559,630,619,711,522,526,706,678,385,971,839,196,292,253,197,84,829,478,717,733,992,146,153,164,343,866,599,758,52,895,395,234,43,247,133,204,515,188,515,211,790,576,104,656,152,249,297,973,605,668,687,880,65,220,714,510,635,868,157,298,886,910,566,981,138,738,699,990,803,751,853,730,439,954,938,622,727,739,449,724,254,587,990,269,635,764,149,683,630,655,143,138,2,139,115,597,274,434,29,81,150,58,56,15,486,22,868,378,391,154,92,568,799,165,423,602,146,439,593,644,412,967,162,518,859,743,921,360,164,896,487,766,760,609,157,160,539,235,554,739,171,71,132,15,414,457,277,369,151,855,325,75,943,899,236,110,309,220,147,646,412,939,223,478,933,677,92,698,152,478,927,388,2,611,68,873,955,149,598,32,40,785,199,874,50,565,980,485,266,266,876,108,6,722,789,517,291,970,33,682,495,13,20,580,937,701,953,573,549,567,784,159,210,29,841,844,666,836,751,642,841,628,258,246,564,403,979,309,27,946,853,674,564,964,224,18,268,482,864,377,237,301,244,167,214,708,209,837,623,715,991,477,983,946,4,802,877,268,99,769,686,158,412,848,30,784,159,718,952,590,495,562,740,0,951,586,612,126,601,705,340,51,767,787,237,28,940,370,663,561,364,204,910,718,196,477,613,694,20,442,693,348,802,645,453,260,977,441,228,713,822,857,755,792,715,610,158,940,957,550,202,304,497,130,723,149,102,56,981,418,278,962,232,528,521,753,460,805,775,347,607,346,338,720,532,955,779,407,882,253,347,53,813,996,825,462,70,181,791,870,518,621,479,348,131,772,856,412,425,419,696,579,57,546,156,833,650,703,43,518,379,279,614,513,93,613,161,607,337,924,842,884,562,599,316,521,148,554,282,310,964,911,74,174,725,544,308,214,763,948,703,548,778,795,100,698,556,653,89,971,708,436,90,969,98,386,123,928,631,868,513,291,466,818,703,152,56,174,367,159,648,297,542,925,730,272,422,102,68,857,550,438,877,901,399,133,88,340,459,417,112,555,345,372,411,823,228,186,739,451,31,46,977,408,931,224,382,383,452,616,499,86,777,261,933,996,736,217,350,493,562,29,875,65,810,391,74,282,82,765,237,759,618,753,641,568,10,467,178,781,995,36,296,762,513,746,484,111,949,196,200,844,392,999,19,788,587,535,572,307,927,271,862,424,105,347,697,469,934,440,580,328,862,379,483,948,763,950,115,812,512,748,871,793,559,5,385,560,622,402,838,260,609,374,36,134,756,364,749,553,426,285,617,974,357,988,637,826,342,556,927,228,272,583,56,280,844,778,36,140,610,457,481,138,785,199,186,691,598,864,901,960,327,599,908,417,516,698,690,673,51,637,107,509,224,27,908,819,355,142,698,876,257,575,264,628,539,464,168,654,352,675,104,314,94,982,506,401,854,516,173,159,294,441,60,674,925,572,76,248,275,996,740,222,836,133,253,500,756,478,271,392,316,904,372,63,770,683,182,688,895,320,38,326,870,254,44,86,584,246,285,125,800,57,241,9,299,48,33,291,627,705,21,481,65,389,783,98,673,948,37,264,51,915,715,484,156,119,363,924,526,466,755,244,971,399,988,128,601,872,755,992,987,174,152,154,277,42,899,600,418,177,411,648,641,436,701,197,162,206,408,87,871,304,827,296,655,183,692,964,918,441,333,596,1,896,308,973,974,819,154,670,318,337,28,51,88,373,712,36,174,827,630,796,811,804,815,428,235,260,658,843,333,237,213,201,864,321,343,617,756,256,204,174,116,266,451,162,429,280,452,76,764,625,254,742,687,55,575,800,575,107,842,738,303,437,189,719,806,517,984,376,36,568,460,31,42,119,104,681,684,573,666,184,868,623,277,667,939,522,958,787,812,604,562,263,444,536,880,358,606,809,62,889,984,792,962,185,105,496,774,555,548,984,872,38,720,297,747,879,263,740,585,115,699,875,664,913,31,409,627,535,697,545,63,538,484,931,227,374,480,298,110,531,389,699,513,585,81,90,337,408,71,873,339,737,845,23,257,983,39,89,931,235", "661,786,90,981,636,187,522,527,798,518,340,766,316,263,473,365,67,866,148,284,895,418,1,926,254,320,659,540,464,840,698,829,330,899,894,518,587,930,617,287,879,84,923,723,445,27,916,982,981,936,481,32,614,709,532,178,129,27,499,920,615,243,305,875,556,251,410,346,218,718,664,929,146,290,819,968,188,988,116,188,586,903,65,486,986,776,770,944,32,719,73,791,839,789,883,126,890,235,294,832,526,731,226,260,114,639,509,411,832,881,172,457,66,545,753,569,836,574,689,272,589,104,618,614,673,933,483,293,930,941,294,468,845,207,198,540,133,836,847,349,478,232,313,728,804,368,130,702,592,342,953,272,55,544,78,160,102,121,956,813,578,835,218,673,537,773,115,116,19,941,95,281,589,682,704,349,580,680,913,599,392,388,712,555,380,377,298,731,812,573,411,489,290,229,320,45,660,40,251,687,181,117,50,666,928,774,4,779,644,475,868,405,615,450,110,738,748,124,369,134,588,254,324,986,883,910,572,855,268,969,953,541,238,713,7,207,267,588,861,891,273,675,160,856,949,870,967,227,974,396,232,444,107,735,756,552,295,233,67,223,951,869,202,604,1000,706,974,418,351,902,565,235,531,610,931,122,449,449,930,373,155,836,157,148,460,583,989,29,446,336,316,570,891,853,563,249,501,433,5,650,711,339,669,925,634,574,606,871,459,811,688,846,45,158,51,243,201,56,713,303,378,897,630,771,330,244,664,791,609,974,640,332,290,488,146,137,641,169,644,649,762,218,816,483,142,712,142,615,990,490,230,260,480,210,204,708,201,735,432,951,0,100,389,748,728,290,352,501,563,88,962,516,822,323,65,99,841,671,258,576,236,247,127,994,231,676,640,235,209,768,813,156,216,999,642,650,27,676,901,881,559,83,834,652,167,695,622,348,377,421,205,27,188,919,850,843,449,562,744,613,731,775,975,172,199,110,749,708,201,793,890,873,885,779,726,528,608,697,433,883,696,766,489,292,157,475,539,947,59,184,359,825,627,362,560,113,238,839,899,760,583,420,984,965,302,180,201,401,985,326,277,304,509,332,303,133,192,904,491,244,267,677,718,168,64,105,939,375,957,332,402,223,776,947,908,246,765,324,949,237,901,947,691,3,981,146,871,120,378,451,137,342,411,446,684,523,327,641,737,239,28,981,504,434,732,674,593,519,715,353,464,548,87,699,624,63,86,57,792,158,700,360,362,161,513,160,841,849,850,977,130,179,358,923,25,58,289,814,667,802,596,803,276,170,847,915,923,694,702,567,110,551,847,550,812,749,337,104,276,303,300,198,24,340,790,867,853,130,252,322,735,298,907,252,270,619,109,419,202,889,429,235,323,953,476,268,592,180,313,626,627,181,616,999,354,599,236,396,170,631,237,306,845,284,319,737,950,882,306,821,796,234,606,37,676,336,170,662,156,336,221,660,318,705,534,618,675,604,316,884,964,292,443,191,495,297,555,388,316,264,775,995,228,61,878,452,57,161,894,316,618,879,112,559,829,967,168,730,25,465,838,591,584,37,407,806,298,542,975,170,728,165,44,781,774,507,832,383,413,418,461,997,218,562,59,873,607,821,422,961,3,922,368,496,201,646,164,561,897,281,558,428,921,50,864,412,150,945,451,832,980,871,619,427,999,816,598,63,35,42,244,42,90,617,582,876,659,324,38,855,468,696,13,290,988,590,599,391,389,172,138,472,92,71,174,15,557,249,695,250,836,280,556,476,3,340,49,37,263,546,65,296,297,169,435,300,170,231,328,261,30,718,834,862,304,736,862,56,53,447,672,661,136,373,751,595,852,245,878,592,397,166,168,431,115,667,555,995,665,802,557,715,929,529,212,295,360,335,239,175,751,476,808,166,447,493,986,829,212,555,469,24,209,87,737,730,833,477,436,55,137,111,465,554,367,870,244,488,693,247,359,691,556,435,74,391,853,164,862,811,163,49,351,38,197,840,949,731,59,823,116,292,634,692,319,729,578,65,601,452,624,849,107,592,606,645,832,602,728,502,915,418,627,972,320,895,399,638,107,357,537,311,915,493,489,719,679,363,192,46,312,800,840,952,595,759,416,698,999,832,730,182,662,46,823,136,911,461,60,68,790,26,59,839,827,488,225,766,59,685,225,995,85,981,407,714,187,722,484,903,185,319,373,877,702,37,934,845,732,907,277,907,334,114,189,256,787,810,509,740,827,750,855,183,329,280,201,654,212,280,514,482,560,845,300,713,353,515,925,397", "697,502,507,248,592,634,322,670,736,117,956,903,922,149,21,206,26,245,84,421,403,220,414,864,264,147,38,804,951,727,718,847,222,404,613,842,989,105,54,71,92,461,213,264,425,942,110,679,255,801,106,522,215,627,883,934,287,324,983,240,602,13,496,867,301,567,904,548,888,81,911,189,998,604,270,706,99,477,180,604,391,405,187,316,947,313,801,378,3,970,215,804,294,219,773,899,634,922,433,368,834,696,592,395,482,115,465,674,985,705,36,853,157,633,47,307,515,182,875,106,268,405,853,443,422,813,814,413,278,842,219,363,667,782,207,385,768,289,200,264,4,872,620,644,385,830,990,355,332,261,903,724,174,767,204,674,191,824,398,866,705,128,522,450,1000,859,777,572,97,454,744,310,376,468,971,639,595,930,56,148,408,294,209,862,813,951,588,528,654,161,743,983,675,807,120,569,214,429,928,922,974,715,428,345,193,804,536,736,38,694,962,258,5,129,12,339,567,450,726,200,217,62,422,326,874,352,670,73,180,302,980,103,148,560,258,319,299,141,768,495,686,945,877,70,801,606,228,942,154,180,743,922,492,685,67,884,906,637,66,143,818,342,224,712,262,406,803,773,162,20,928,616,618,308,82,184,234,182,913,700,60,842,610,560,422,17,909,885,667,792,381,665,454,183,329,180,122,61,76,770,985,302,830,735,159,355,135,659,784,836,116,871,664,131,691,35,905,437,974,326,162,638,336,230,214,742,646,639,752,592,272,506,270,654,616,511,755,371,264,709,523,774,684,719,75,590,301,545,80,599,808,2,652,74,733,379,557,518,444,586,100,0,794,627,898,388,172,88,171,879,904,284,558,476,274,169,617,250,690,814,330,555,652,402,628,151,655,88,228,747,266,366,661,5,986,627,204,231,226,893,387,302,999,15,798,602,196,994,296,42,91,799,436,440,975,226,890,624,360,724,720,674,191,813,225,925,989,847,98,827,160,256,670,711,480,364,17,957,286,436,251,610,225,304,597,114,413,345,198,537,94,873,561,273,325,937,323,132,833,613,37,168,156,265,527,211,325,646,177,460,835,440,996,339,120,711,286,283,407,228,758,579,467,450,343,573,946,747,951,648,173,618,391,339,916,852,812,879,786,783,984,412,83,702,178,550,778,330,911,294,529,94,235,972,289,123,214,138,15,199,183,475,107,12,284,422,794,558,707,206,950,627,99,874,130,845,244,321,293,453,835,389,622,50,233,253,52,953,832,539,655,541,941,493,541,614,46,349,963,609,287,432,885,836,556,212,941,144,311,161,759,189,613,111,850,602,711,149,888,447,519,517,520,769,343,563,271,769,199,708,417,368,224,245,94,219,664,287,238,410,18,772,681,577,251,404,64,425,201,881,828,569,358,184,88,395,271,673,781,372,895,507,704,504,864,129,963,461,594,919,391,815,994,55,215,750,975,331,858,786,437,492,953,689,118,57,965,945,209,655,545,244,171,660,598,120,674,99,977,807,828,92,769,576,446,183,462,938,647,476,619,416,304,991,66,124,805,677,715,178,904,76,744,638,415,577,933,59,55,218,317,672,829,724,45,861,75,91,299,164,494,922,639,489,791,419,498,14,854,203,555,440,375,569,454,124,340,706,529,286,707,875,988,703,943,335,669,411,81,332,954,140,498,692,730,383,874,698,201,92,633,60,14,119,461,668,318,518,913,146,712,526,119,960,353,298,426,365,861,455,968,908,955,524,618,472,263,474,990,623,258,210,42,969,823,613,43,124,351,844,868,899,351,925,403,87,505,382,23,998,414,489,256,140,401,169,51,348,497,373,400,984,649,643,601,998,430,262,709,312,605,300,734,677,93,967,90,31,613,964,484,778,694,610,720,139,538,133,176,780,224,877,578,633,373,732,949,753,647,889,161,684,778,285,679,577,574,438,26,701,720,159,185,11,370,213,222,714,100,657,172,8,577,186,208,645,952,37,35,869,66,351,988,523,854,203,318,654,597,79,527,578,582,748,793,788,601,997,142,618,561,178,814,99,382,993,140,471,58,719,632,450,264,591,153,469,465,183,552,370,928,112,508,955,672,198,82,541,646,916,86,113,214,258,289,26,500,677,86,471,94,649,925,275,702,820,736,197,750,754,389,442,390,590,736,41,622,859,817,71,437,899,168,298,805,163,89,105,703,216,169,865,120,576,419,179,717,228,577,134,917,968,755,15,65,349,656,193,913,588,587,68,443,61,122,234,28,554,822,237,186,290,139,965,853,476,947,416,912,271", "632,476,122,862,792,205,838,763,960,1,819,311,996,387,919,471,498,490,45,485,963,725,626,880,501,383,220,185,4,781,595,452,781,663,653,327,21,329,524,255,415,96,280,883,66,66,209,360,424,796,792,704,843,587,476,391,727,777,986,297,633,626,858,918,83,578,184,854,377,804,924,680,887,486,859,187,186,997,648,655,97,627,751,49,700,369,81,796,948,513,807,256,159,973,883,533,809,961,61,92,166,259,397,926,473,2,441,656,787,503,512,363,430,858,986,810,192,881,84,842,964,243,333,927,77,530,741,492,246,751,579,592,122,814,189,147,465,487,45,884,240,980,983,723,950,752,995,277,760,928,734,442,477,979,930,370,52,424,653,211,333,515,104,849,739,863,337,889,476,967,676,112,115,546,165,379,357,5,886,681,276,492,251,579,820,445,431,433,967,248,539,135,979,871,394,449,902,527,9,612,766,199,406,712,491,209,795,688,911,431,800,203,649,584,831,328,48,19,898,356,829,783,988,920,969,314,940,86,668,468,390,307,178,40,25,742,519,221,696,226,678,724,430,391,317,707,35,585,472,4,798,450,584,263,778,737,714,995,553,115,757,453,869,764,164,244,933,341,218,651,231,671,4,431,753,410,494,2,475,385,380,738,485,924,512,467,919,510,555,451,998,260,398,552,45,487,364,109,417,336,279,862,515,811,884,131,105,635,803,938,750,187,137,808,3,711,398,434,986,828,232,364,382,84,421,274,267,103,346,929,877,826,736,703,897,661,271,145,808,724,709,109,137,588,672,918,564,398,177,612,668,740,266,448,315,714,920,523,270,612,389,794,0,333,256,616,150,165,822,748,720,735,920,161,430,475,536,553,824,408,524,250,947,279,743,499,99,249,242,679,870,150,886,328,421,906,7,331,929,168,143,211,952,912,535,644,90,510,244,890,940,76,903,138,550,170,601,721,323,334,71,843,392,96,283,161,621,227,39,701,887,87,464,199,458,312,560,583,152,916,358,277,633,237,874,192,889,204,721,265,499,314,96,534,438,268,899,755,443,636,400,340,150,495,22,712,473,246,247,106,138,35,310,40,86,227,304,35,992,249,520,141,371,879,947,952,638,817,886,876,239,173,482,372,668,796,257,872,499,491,494,237,922,353,926,487,763,15,453,294,197,550,747,156,829,503,158,485,400,91,697,71,348,287,421,235,249,884,401,87,407,378,339,203,600,798,714,488,410,118,95,159,5,809,26,398,744,98,250,275,835,202,39,817,381,946,167,621,653,536,391,923,242,186,125,550,176,639,323,481,376,83,745,294,805,613,338,543,309,421,475,189,839,500,639,340,77,274,974,573,124,322,274,168,224,164,356,643,910,526,640,659,221,94,642,494,136,517,162,750,1000,2,184,259,604,826,778,931,168,781,224,245,969,185,342,940,90,802,532,493,509,156,905,829,183,959,987,913,905,119,377,321,74,542,233,240,638,141,770,935,465,881,86,95,899,727,272,465,605,311,858,860,153,687,526,324,443,830,739,950,278,147,386,935,99,173,573,178,737,488,33,991,126,160,815,741,604,742,701,390,425,498,605,169,184,195,992,878,240,740,521,333,15,868,64,271,266,365,94,467,664,327,712,806,275,89,167,950,680,531,247,894,1000,716,915,310,399,164,2,930,840,889,668,327,902,755,128,72,670,361,122,359,941,875,223,520,52,518,847,548,463,749,455,71,563,699,219,565,101,787,328,981,471,480,677,430,474,125,907,179,647,519,485,135,256,540,315,877,712,115,358,392,54,887,510,873,29,852,148,993,162,280,468,126,68,150,211,621,886,706,734,418,458,529,170,698,155,882,752,959,975,647,40,693,946,393,811,693,570,666,507,204,115,595,798,991,860,640,455,874,298,333,426,247,784,133,747,814,48,646,817,913,406,925,623,873,555,43,89,65,293,353,320,841,796,906,804,893,384,379,273,189,968,881,915,495,725,240,547,479,97,126,888,454,858,77,772,412,153,691,259,85,923,965,417,714,706,345,373,39,941,474,954,895,480,263,181,665,956,324,843,794,62,128,264,937,264,617,575,58,672,947,651,590,185,936,65,921,312,633,445,705,85,348,860,819,571,611,707,877,126,112,926,980,182,329,918,386,145,81,49,471,532,564,471,241,484,35,34,732,73,759,886,291,595,63,850,478,179,472,245,568,275,206,664,183,104,158,218,377,535,652,441,73,154,732,819,712,350,970,383,661,525,44,517,161,646,737,706,552,403,404,635,684,996,736,586,370,384,588", "185,804,398,177,827,397,198,73,740,202,17,204,342,670,603,271,988,768,327,657,857,491,873,921,781,90,825,223,409,514,312,612,926,509,396,119,610,376,676,345,309,960,241,84,2,603,18,377,745,547,128,133,734,697,424,944,617,206,683,166,578,990,834,236,208,413,193,771,999,225,659,413,940,950,754,726,297,62,500,528,432,165,178,783,110,550,634,799,890,858,837,888,313,379,821,34,475,802,844,354,748,871,588,75,43,168,763,18,873,402,101,311,725,87,333,382,5,359,656,197,831,652,399,19,22,168,216,500,200,264,872,983,575,960,518,322,928,975,122,25,664,580,863,129,99,776,752,105,923,330,559,244,401,775,172,591,804,246,828,816,92,29,627,584,140,617,593,350,454,272,290,58,593,760,439,371,600,279,44,338,535,944,93,112,470,782,189,103,462,606,640,262,453,273,73,563,245,650,120,836,110,654,768,665,889,283,559,275,108,848,832,949,915,201,75,101,461,871,884,744,803,148,968,492,345,9,382,680,521,19,60,864,580,606,698,182,907,616,806,508,417,429,67,454,374,381,573,780,808,708,305,457,399,425,104,161,707,150,274,875,104,190,103,991,304,286,292,452,809,108,118,304,116,504,770,617,922,366,191,419,100,719,386,643,629,648,768,516,585,309,154,280,88,305,319,858,840,889,848,335,910,675,333,739,656,52,191,340,164,633,965,42,999,652,231,312,538,200,533,712,51,789,350,361,514,697,3,508,100,294,658,799,594,782,373,622,281,348,985,361,134,786,9,570,175,825,995,128,192,116,881,480,151,922,618,560,347,452,385,126,748,627,333,0,41,291,632,201,719,34,357,396,980,166,3,467,509,257,805,353,901,294,612,203,17,28,131,134,775,489,16,61,562,650,209,976,991,213,407,998,960,582,586,964,518,701,581,774,136,335,322,257,406,44,964,488,449,76,766,299,343,946,254,236,879,660,902,196,486,426,867,286,85,966,415,431,647,605,556,395,98,922,438,239,975,268,26,765,103,752,280,101,725,698,595,697,388,334,523,589,302,83,182,951,58,503,857,643,252,723,699,348,548,413,598,183,563,92,563,840,406,680,984,12,662,657,982,479,659,402,366,621,153,177,342,990,6,924,202,275,855,532,440,527,129,894,296,148,98,928,555,84,445,509,518,927,980,165,567,86,283,429,258,290,476,569,93,749,870,618,425,782,721,542,356,52,761,543,447,995,154,602,732,10,949,317,721,970,168,833,328,485,183,660,341,954,768,508,81,833,235,667,730,195,300,884,371,158,122,242,892,687,704,595,443,640,38,151,388,586,726,228,108,440,969,958,327,839,413,804,942,739,909,533,860,412,548,149,451,408,443,703,330,420,860,60,865,198,436,143,573,340,732,72,355,256,491,837,961,472,173,135,226,25,300,485,200,649,740,744,884,97,524,153,611,774,379,757,413,719,520,827,335,674,301,534,329,849,350,702,847,727,514,424,198,24,913,796,284,901,409,254,308,821,454,121,685,737,660,512,481,952,845,360,574,789,979,161,273,854,773,8,149,379,100,232,890,780,314,387,577,832,77,598,913,591,729,608,230,721,30,701,897,633,529,4,515,621,459,598,475,219,299,41,323,74,577,691,810,164,994,324,672,619,686,338,80,161,688,652,201,202,961,549,65,462,301,885,47,581,781,944,737,1000,894,33,16,26,1,476,342,153,214,830,871,165,23,986,324,779,297,921,494,632,942,3,761,335,362,190,95,629,705,112,947,302,877,183,879,964,55,247,95,480,449,42,983,624,18,833,606,292,516,159,896,146,536,627,412,132,262,152,187,897,33,449,883,93,192,93,939,741,433,370,23,427,853,879,928,440,374,539,38,46,148,745,44,818,879,415,611,386,556,98,954,226,724,748,312,751,698,380,610,966,869,409,680,62,440,300,570,839,222,8,833,616,109,219,435,604,188,224,898,271,674,699,641,677,873,377,807,500,430,667,117,96,764,702,628,497,46,104,122,824,528,296,702,255,709,306,701,897,382,806,788,509,962,476,828,142,973,183,826,446,531,758,568,254,381,946,405,725,297,574,860,527,628,465,430,903,139,587,264,905,343,34,235,180,407,336,746,919,509,302,710,107,48,135,147,424,260,647,329,735,559,391,98,53,4,521,81,230,517,746,224,102,303,687,710,767,897,118,798,265,76,681,591,414,331,857,35,424,373,904,897,231,78,625,818,280,609,129,989,168,833,951,113,91,618,667,5,574,1,878,436,73,65,574,863,54", "283,44,763,472,181,870,354,270,835,725,26,340,585,554,781,831,772,948,479,180,630,982,221,448,168,516,865,884,320,349,807,50,112,589,334,226,344,98,88,973,290,682,636,699,878,514,793,99,432,295,89,238,804,39,321,756,287,844,547,610,152,482,561,483,692,272,861,434,615,89,228,918,63,169,505,875,451,137,146,683,861,137,137,96,686,650,514,402,206,721,464,119,556,123,370,600,127,790,661,197,903,602,240,458,351,764,375,501,910,187,553,362,78,752,275,732,591,3,157,916,822,866,665,760,541,741,62,210,423,500,981,378,84,383,89,778,63,817,30,792,678,303,956,223,71,951,918,281,249,729,351,45,53,674,742,294,557,670,623,970,976,646,354,999,983,689,547,213,554,927,166,134,109,423,460,496,256,565,807,967,292,834,518,163,89,538,743,344,935,9,290,97,173,626,865,83,192,212,57,723,568,56,363,126,777,34,150,582,629,507,894,420,825,775,972,519,321,735,49,475,89,800,489,80,511,409,297,12,111,833,280,533,244,825,4,99,172,193,95,42,911,12,101,554,668,519,394,791,961,278,928,310,57,956,939,376,62,435,149,321,167,313,187,292,185,382,940,339,300,263,882,65,395,606,120,66,749,343,530,530,462,348,453,567,365,27,845,406,256,931,124,924,112,964,43,882,905,3,466,373,81,471,579,309,644,886,747,631,935,95,385,806,73,144,44,341,577,804,407,799,323,979,619,255,501,294,108,434,348,896,511,795,264,254,401,887,680,435,833,941,777,152,569,838,711,945,711,484,661,140,969,988,664,648,953,630,213,833,241,601,728,898,256,41,0,655,565,838,551,9,248,955,803,937,279,29,260,346,602,426,82,479,47,231,736,277,369,18,806,155,899,827,892,142,778,798,978,251,755,406,281,298,915,801,864,226,85,94,895,480,561,178,129,157,722,349,599,21,383,300,861,18,963,251,230,724,464,249,807,25,587,187,4,107,217,354,480,586,958,642,909,948,498,886,866,749,214,230,649,146,372,837,935,719,303,452,3,787,295,178,865,870,930,924,171,254,376,580,701,345,348,834,480,615,92,663,803,220,979,583,999,485,95,868,79,482,933,639,53,543,775,857,927,480,139,4,17,843,202,723,333,300,129,825,841,701,680,461,636,831,269,39,648,499,196,937,820,53,942,346,897,721,415,444,804,623,106,861,194,762,173,245,864,394,690,442,10,408,806,170,807,907,439,574,54,94,277,729,261,680,534,265,986,274,874,914,181,923,64,923,336,375,159,746,700,994,956,898,598,766,74,755,76,572,178,274,744,978,927,600,379,578,440,32,355,642,659,985,673,323,232,924,962,241,254,369,856,88,884,534,504,573,447,183,852,285,224,667,923,776,508,435,875,312,87,56,75,94,911,554,995,238,389,155,336,59,692,916,32,355,265,855,404,573,736,55,301,791,796,13,313,163,696,130,180,159,913,244,59,73,590,330,322,434,619,994,359,669,895,255,621,541,350,586,483,59,548,528,583,519,311,632,238,606,856,893,738,715,670,356,423,17,254,35,691,191,743,614,114,558,656,602,894,537,255,15,810,167,368,249,375,47,641,41,265,737,324,906,720,284,86,801,721,474,14,288,761,679,76,729,924,227,150,773,349,180,853,827,880,894,252,430,531,786,863,216,70,18,750,648,240,609,318,214,949,737,688,929,266,221,510,780,792,737,704,863,632,338,470,651,736,869,102,438,284,866,436,410,958,63,175,827,510,167,278,635,932,434,105,344,940,635,590,81,575,93,358,138,817,26,390,657,598,692,498,375,407,111,295,280,954,225,26,400,876,639,269,914,682,29,854,437,96,429,568,578,768,633,953,16,476,530,953,76,681,394,426,759,659,134,913,233,591,948,458,235,514,243,315,231,330,87,169,996,830,705,637,267,126,18,188,65,547,351,268,440,321,479,19,185,768,315,611,52,613,972,417,434,88,584,450,284,13,126,703,483,925,52,983,945,848,842,331,974,529,662,718,727,500,559,645,736,41,578,152,387,161,119,207,202,256,731,339,869,581,443,136,265,302,129,912,180,825,432,613,938,922,532,501,865,434,247,255,967,308,564,529,200,241,927,486,824,27,770,271,830,889,89,517,612,27,51,742,47,960,625,531,269,702,566,334,589,592,379,359,916,752,364,995,92,241,977,282,271,316,11,746,356,818,286,58,131,135,105,483,405,551,813,2,198,788,228,705,477,947,224,727,724,170,612,838,28,878,814,695,329,945,583,152,143", "838,717,207,490,620,895,885,807,891,710,846,354,843,98,454,279,250,718,81,953,75,506,686,990,893,660,466,42,742,25,849,729,473,684,226,971,127,29,912,98,862,936,308,231,495,645,777,478,161,456,505,531,105,667,976,916,549,883,17,219,828,456,127,345,896,600,661,87,93,587,509,78,313,273,827,491,751,475,353,195,544,759,719,793,636,744,758,867,520,390,684,936,470,457,94,729,977,348,773,43,628,155,442,67,411,656,882,670,398,911,163,397,720,400,988,226,640,175,593,479,189,350,108,988,24,646,755,762,413,820,91,552,149,86,93,802,755,559,608,803,462,337,786,207,744,320,467,382,372,855,685,82,731,716,239,115,329,701,592,102,929,126,406,203,278,355,752,799,499,863,18,252,285,186,617,779,708,968,750,612,218,465,57,438,988,260,211,98,826,13,871,612,499,80,472,250,922,393,2,828,332,172,900,194,461,532,139,934,69,213,790,330,888,428,516,4,695,967,944,625,503,256,133,376,383,292,881,551,174,276,841,425,695,639,219,384,532,702,172,646,676,789,246,172,469,216,731,941,683,211,431,290,683,213,160,930,82,581,890,807,535,518,939,194,294,438,462,616,237,773,848,796,686,640,866,458,453,748,825,377,775,1000,827,571,549,543,285,798,144,119,831,285,581,323,857,851,430,90,242,701,858,942,547,548,493,278,424,324,148,187,153,895,528,935,798,358,563,94,82,384,354,934,234,598,780,324,167,420,986,69,879,423,771,525,111,472,582,899,695,261,18,566,409,646,991,787,378,98,794,739,909,42,155,588,925,662,476,284,553,705,290,388,616,291,655,0,72,94,768,947,706,141,139,546,224,88,636,864,760,194,177,272,227,857,112,459,811,395,625,164,332,853,164,668,932,169,587,30,107,899,55,840,505,654,449,100,870,259,519,577,524,388,372,59,964,596,58,47,761,191,180,623,272,233,738,904,814,355,401,798,278,376,304,922,577,403,85,626,733,107,562,374,951,452,194,239,307,831,432,889,940,100,539,834,545,399,805,173,708,324,79,180,354,698,737,853,574,181,844,233,666,666,319,455,170,378,424,364,665,656,532,204,325,84,644,205,535,500,628,775,831,739,201,585,564,287,824,855,514,946,520,541,334,96,716,41,543,62,166,5,640,684,73,61,302,674,779,235,49,940,461,814,40,804,713,293,119,922,781,601,25,599,325,43,321,595,423,553,890,917,571,618,170,212,525,452,377,552,848,907,345,589,574,202,519,828,217,745,761,498,271,32,958,968,969,794,752,180,265,575,968,693,540,461,145,475,826,668,297,17,527,739,474,341,318,106,218,197,399,37,358,214,689,497,731,787,229,146,266,143,145,883,166,667,300,623,957,526,395,627,714,587,492,810,127,39,558,607,435,508,829,178,908,402,912,351,285,611,913,612,936,1000,79,379,20,954,102,531,724,373,782,527,242,384,911,835,271,546,946,92,484,882,493,190,384,950,785,413,463,83,426,252,168,819,354,138,26,727,366,702,671,748,432,289,13,920,531,936,599,945,58,327,681,134,24,244,71,484,364,110,630,52,766,954,649,153,794,953,296,361,161,450,22,471,340,529,554,112,522,166,742,227,633,627,267,509,443,907,746,10,265,505,611,431,751,145,537,389,330,678,689,659,457,543,374,209,106,962,775,755,352,818,412,54,249,867,652,767,365,143,875,462,626,757,826,193,979,222,584,174,423,213,382,402,661,766,844,512,926,976,18,615,238,964,602,187,804,380,612,301,423,970,120,693,310,397,592,73,326,671,335,997,30,33,347,203,24,793,79,525,776,904,522,772,826,84,137,953,650,486,473,50,934,270,725,432,966,407,305,645,315,303,649,905,531,160,20,853,342,861,147,96,165,337,736,493,581,62,908,718,924,289,252,970,983,343,697,103,175,831,191,456,907,646,804,644,268,167,238,143,782,325,764,810,471,366,611,261,934,830,180,814,942,483,77,870,259,171,232,303,73,91,648,911,135,204,740,843,728,580,939,155,34,378,389,409,177,157,824,235,623,387,607,499,522,664,665,365,774,314,952,314,720,839,426,382,218,212,967,183,695,470,68,432,614,973,631,158,660,329,731,400,610,400,883,483,559,769,780,54,763,657,823,529,667,693,365,337,611,326,676,78,99,742,230,226,766,816,272,784,673,738,671,589,653,642,143,896,793,926,159,862,896,584,780,915,60,639,731,647,781,162,782,893,813,193,866,169,960,387,143,789,826,106,105,821,22,764,457,940", "509,793,252,194,758,344,657,180,268,812,453,518,895,736,173,297,858,541,550,889,250,288,168,895,866,2,212,294,843,282,124,683,547,600,308,623,476,258,741,15,464,278,693,684,665,533,503,999,823,200,7,394,479,521,688,250,331,915,486,784,19,621,158,38,331,901,921,948,438,659,509,545,47,487,811,154,704,543,653,429,416,949,965,991,367,667,628,771,319,133,285,157,732,40,290,306,363,718,793,439,94,498,941,267,640,820,477,40,635,408,205,624,551,438,883,920,724,508,165,338,479,466,399,217,407,296,918,782,681,106,27,460,852,897,232,731,537,216,800,239,448,684,438,644,654,189,658,932,906,17,730,426,551,852,746,670,253,350,593,482,217,485,169,682,128,585,773,590,601,879,527,30,890,248,538,65,885,99,709,594,388,658,597,426,296,130,121,459,493,321,948,65,559,533,373,743,665,159,272,768,663,379,481,860,850,476,40,990,83,415,913,204,789,241,12,308,636,133,972,682,842,886,848,328,50,219,56,283,501,4,103,597,212,441,532,762,142,797,432,629,869,312,217,853,809,459,798,838,756,781,74,956,358,16,964,581,481,565,482,995,626,738,371,847,50,974,871,504,759,731,39,84,202,535,615,721,810,105,544,726,26,723,918,482,232,449,507,989,498,131,31,739,835,752,332,507,557,367,948,677,588,557,918,404,962,280,374,225,624,808,817,843,866,518,891,683,61,572,617,964,277,570,838,926,859,442,433,368,712,746,285,193,853,428,810,179,6,179,649,48,761,742,173,552,890,505,583,879,929,923,889,113,940,549,414,473,756,619,924,340,352,172,150,632,565,72,0,621,462,269,492,150,381,596,118,212,931,655,661,892,925,463,751,339,685,915,214,600,457,801,443,908,770,322,580,502,861,882,132,52,954,904,710,165,713,371,648,871,268,452,234,983,242,949,425,785,726,374,330,175,342,600,950,5,535,288,857,461,797,322,528,586,291,367,877,610,21,891,952,687,911,514,661,283,723,846,327,857,183,358,912,273,22,862,405,978,878,985,911,482,681,674,984,584,306,290,81,984,579,946,380,934,126,811,78,431,572,928,179,258,28,150,384,901,97,752,561,26,840,549,652,188,757,697,102,73,44,230,224,298,630,570,631,590,402,163,116,208,165,756,893,422,674,166,777,392,867,592,423,275,249,676,458,426,146,887,774,206,668,138,997,970,248,582,740,885,928,338,656,932,997,904,642,923,253,482,831,237,517,874,330,925,315,227,170,668,800,697,908,234,840,293,568,384,612,167,221,804,457,868,814,343,749,597,818,929,855,186,837,826,398,101,627,373,9,73,917,291,374,129,277,943,725,103,464,397,740,923,79,724,559,534,534,928,913,404,841,102,391,719,577,853,278,943,270,548,766,872,597,122,742,877,2,427,51,710,207,687,664,899,381,200,761,663,831,599,131,786,702,217,113,455,22,837,495,651,669,114,847,574,758,767,502,141,103,658,85,495,584,791,316,419,887,146,512,921,58,253,120,658,662,92,405,341,307,148,740,487,589,965,28,141,655,241,910,652,591,881,54,225,755,399,478,45,876,73,980,515,275,260,678,203,763,539,802,21,692,89,33,955,18,749,540,937,612,460,525,196,915,350,778,158,149,24,621,59,378,883,582,458,270,896,931,268,214,10,998,559,961,70,183,155,196,990,349,770,72,962,892,382,266,833,632,173,266,45,916,805,270,514,295,604,603,769,619,387,146,203,51,220,215,886,261,197,509,649,339,846,266,865,796,428,135,125,722,677,291,2,723,670,942,861,563,814,644,85,204,568,436,728,942,549,346,746,247,54,287,115,703,845,734,984,708,26,69,276,658,619,368,676,929,506,434,297,631,234,299,450,827,224,746,377,653,145,601,242,75,866,729,513,632,649,862,60,94,983,742,141,74,896,415,518,552,122,813,791,846,246,267,712,177,553,635,897,37,692,876,724,413,147,311,644,963,335,817,76,470,586,304,26,590,581,512,844,633,72,466,374,38,727,254,78,174,109,908,63,205,102,11,159,999,291,192,739,340,709,801,657,327,976,856,263,920,966,550,731,304,527,914,226,933,7,847,717,561,788,131,790,773,83,827,224,326,46,344,119,519,254,861,181,899,184,342,419,838,582,434,641,621,707,110,26,418,847,762,148,11,245,45,960,452,513,840,184,521,215,893,879,410,58,878,682,248,971,844,936,420,214,421,75,188,338,23,806,509,153,568,91,243,269,785,561,282,880,392,113,668,580,20,689", "843,688,209,179,118,448,580,821,438,678,259,180,8,617,660,116,282,112,542,249,118,586,11,449,40,934,892,104,919,764,860,995,816,975,364,173,9,248,884,82,525,326,417,975,638,337,242,919,965,992,842,327,94,560,935,781,757,270,41,882,965,772,95,572,46,333,761,641,726,726,458,622,870,231,690,727,236,561,28,156,137,614,932,853,501,925,318,546,902,180,961,133,715,488,374,931,241,998,264,262,361,981,76,410,775,915,72,678,948,923,752,779,798,228,966,339,490,75,139,87,913,416,964,92,226,260,207,460,583,325,899,25,163,564,66,249,86,427,574,568,586,208,348,421,576,485,74,710,787,813,340,61,285,493,829,196,377,484,579,24,131,973,787,430,225,306,820,868,635,799,938,275,297,401,39,405,914,162,259,92,331,861,847,13,61,751,762,212,955,207,774,818,649,806,559,525,32,968,73,686,487,120,989,986,320,994,631,480,701,5,440,698,621,891,78,439,641,765,723,6,200,152,121,543,556,428,50,590,994,819,939,411,789,954,835,632,720,6,687,222,171,435,913,916,143,695,339,227,311,338,274,838,623,912,629,346,492,180,660,898,538,550,634,979,371,494,70,239,798,470,157,974,68,498,469,599,561,581,564,492,703,354,365,77,122,483,240,828,308,783,748,246,446,158,611,722,244,148,631,286,634,707,932,237,519,516,728,828,669,570,383,678,802,870,293,494,397,669,911,255,10,952,299,864,761,561,367,839,367,879,217,882,139,692,699,440,118,291,893,107,209,317,143,53,767,486,615,959,735,890,65,494,750,702,317,743,489,798,244,51,501,88,165,201,838,94,621,0,137,687,716,740,48,780,271,847,816,333,958,501,531,295,928,663,24,364,366,41,829,311,79,676,667,471,975,244,755,265,114,123,988,166,964,932,255,791,618,991,631,844,715,723,689,774,827,915,890,875,316,779,303,180,500,163,759,387,994,830,575,80,214,75,933,954,855,216,122,88,172,414,106,254,591,621,411,102,236,253,514,563,824,173,374,542,7,701,405,654,315,575,921,74,657,347,794,996,963,818,634,735,893,315,585,992,202,97,21,111,66,80,143,148,404,868,731,183,903,170,523,268,148,175,734,543,428,259,175,832,453,762,517,305,119,58,378,686,156,739,701,708,887,143,359,301,1000,215,379,735,347,664,210,767,848,226,223,92,340,559,677,487,529,55,339,187,227,560,830,548,613,815,361,59,334,285,170,819,569,135,815,197,578,87,824,142,726,425,943,979,633,606,453,990,902,434,601,805,992,167,129,718,763,190,276,779,370,424,965,385,60,186,718,922,47,192,776,742,159,869,704,291,528,387,777,736,14,890,328,544,992,251,126,190,861,502,488,227,528,495,651,207,816,483,245,630,753,706,580,276,549,52,880,9,302,737,895,8,38,898,46,307,747,797,512,683,737,614,773,297,881,339,437,674,819,974,661,121,928,857,22,984,437,801,450,315,21,416,982,432,126,341,863,177,983,930,242,755,722,713,953,234,162,277,231,887,552,158,552,381,143,154,646,23,752,325,718,596,74,741,960,77,16,505,498,863,528,396,716,555,262,652,773,924,248,120,971,106,419,980,96,891,129,968,368,894,253,727,861,575,60,253,366,987,602,73,236,163,179,772,892,328,835,662,887,304,460,831,631,943,758,89,239,872,803,322,880,442,410,944,802,747,57,244,973,144,616,432,704,758,896,240,152,483,958,147,409,207,160,908,124,770,433,541,386,154,56,564,912,309,373,304,995,236,715,894,714,831,966,952,818,637,261,187,663,13,998,571,52,737,671,958,25,781,161,253,257,309,777,214,571,53,856,140,626,153,545,612,250,763,708,179,659,507,586,990,230,410,478,290,243,388,932,613,564,489,284,302,475,10,142,579,510,838,89,954,38,329,586,866,367,651,72,365,617,374,240,955,848,498,384,670,116,492,833,904,994,777,973,442,391,651,983,662,492,343,60,144,904,720,817,33,199,887,854,12,677,261,758,486,435,364,695,509,195,945,837,998,843,19,898,106,524,340,645,364,422,698,836,890,69,497,576,668,385,264,721,480,918,138,846,376,297,246,245,371,671,60,850,663,665,808,685,733,156,185,794,10,934,156,356,38,64,661,246,61,954,349,432,560,417,109,991,554,432,120,795,366,460,362,904,119,374,968,188,223,116,437,254,902,313,277,949,40,219,756,813,812,607,616,330,516,897,279,700,569,811,618,154,771,40,752,923,945,109,406,456,232,199,157,479,584", "222,246,561,788,311,910,519,786,611,179,905,854,291,550,431,335,594,619,340,772,325,546,349,703,89,640,322,983,13,971,788,875,166,62,240,11,586,600,340,4,232,932,653,765,383,44,297,5,843,40,223,198,445,603,76,786,742,208,544,184,623,863,636,272,553,993,828,870,382,230,499,372,570,756,293,404,266,193,605,675,717,362,921,442,420,4,103,625,278,908,808,829,785,387,659,175,298,166,255,616,260,578,508,167,993,608,298,705,231,334,147,639,584,374,629,368,502,259,944,19,935,590,989,23,902,160,600,67,689,959,923,349,906,754,949,576,170,893,656,352,344,144,284,22,230,24,495,821,196,865,122,729,869,382,655,313,54,748,121,428,111,896,171,221,225,756,873,580,317,230,405,328,457,155,140,402,430,152,902,728,273,928,820,778,719,818,356,35,399,265,135,672,367,760,875,763,799,917,701,579,999,346,491,264,898,260,856,539,269,100,46,367,189,560,661,115,808,402,802,20,550,457,789,767,6,230,478,678,118,678,657,995,763,569,498,331,443,603,157,557,368,923,352,86,487,978,496,536,785,450,336,149,949,653,306,193,982,642,29,403,518,369,640,276,675,551,155,363,613,3,471,420,554,60,934,841,988,162,313,89,122,510,341,37,31,157,919,797,647,471,502,543,995,68,237,280,465,803,591,677,834,462,584,293,402,741,535,935,234,832,557,329,82,181,677,655,552,483,623,355,935,241,807,159,357,404,442,701,152,964,30,381,771,180,11,767,692,858,303,670,104,476,919,298,26,839,175,944,94,213,441,569,627,876,927,120,171,505,964,767,563,171,822,719,551,768,462,137,0,183,166,526,222,63,867,175,773,698,360,405,855,401,306,566,526,996,13,168,520,103,637,66,103,125,218,255,481,770,672,625,101,816,50,259,370,441,744,671,44,822,856,946,329,163,861,786,863,891,185,94,885,894,586,77,811,708,506,20,919,797,170,878,23,130,197,272,458,331,734,767,962,284,447,12,791,721,756,501,837,527,847,979,803,552,8,312,227,127,427,460,828,381,284,246,855,829,260,24,970,534,85,765,391,468,801,823,151,817,232,958,276,614,626,551,707,290,288,686,536,707,388,531,41,422,811,123,481,286,793,607,946,676,172,348,816,383,716,190,638,755,383,925,992,158,630,93,510,588,876,700,511,420,446,447,538,29,86,993,808,38,997,8,421,868,903,28,965,876,850,876,948,150,32,699,473,400,56,651,560,528,873,830,72,57,956,403,742,784,635,727,743,411,884,952,519,365,573,268,256,642,940,76,518,739,666,765,2,253,798,400,461,857,870,755,608,652,926,932,861,36,415,759,181,939,710,200,385,996,319,271,123,964,276,884,285,701,43,951,472,652,986,133,958,747,749,489,288,659,167,929,458,828,665,282,167,284,776,88,942,440,431,953,306,719,296,301,934,106,999,52,141,82,454,855,553,296,531,866,32,368,407,463,111,620,905,824,216,215,39,284,281,996,287,328,877,22,681,508,649,781,697,333,468,846,613,910,369,489,570,803,880,870,699,233,351,858,263,87,858,873,889,205,634,26,210,662,259,667,194,170,983,642,610,631,628,443,257,481,247,229,576,761,419,221,974,483,604,941,909,479,752,615,793,329,418,139,273,631,961,971,400,321,272,172,947,341,694,679,774,701,537,89,677,47,654,178,271,622,415,828,130,753,443,681,968,903,151,867,594,793,275,647,358,4,546,748,624,559,39,546,819,717,133,477,206,555,953,187,792,429,755,296,117,372,149,919,897,216,486,281,53,296,362,693,323,349,654,347,504,18,159,580,915,49,564,94,960,597,811,55,291,615,480,68,158,811,173,723,49,344,755,777,87,887,986,557,84,270,823,867,39,42,5,287,66,660,337,480,676,841,317,480,15,368,737,16,399,988,6,200,249,990,790,928,105,708,167,745,979,898,352,765,188,931,393,992,884,503,334,62,588,263,104,967,619,247,499,634,811,317,985,346,460,105,932,369,522,104,613,997,226,466,31,39,721,579,715,120,192,133,959,748,454,595,607,930,122,717,742,279,22,684,536,959,751,898,776,839,995,173,215,546,650,535,131,584,168,165,587,643,90,232,508,589,293,487,695,730,609,153,536,430,886,62,101,526,50,458,657,999,726,410,709,524,59,33,126,809,290,720,2,936,450,212,634,141,722,450,184,852,153,749,933,166,994,59,503,103,401,679,364,482,880,68,820,144,503,396,413,110,951,395,161,238,973,676,600,337,980,573", "690,854,354,663,525,415,588,832,174,352,635,131,654,693,924,507,854,276,210,28,948,798,73,640,218,238,992,979,896,740,911,365,341,465,107,423,892,901,288,963,804,561,837,110,402,185,588,674,987,768,58,477,726,208,644,704,929,392,812,6,212,476,183,864,722,429,821,564,7,765,633,239,104,150,592,961,594,827,197,269,359,861,931,810,635,992,524,119,733,52,771,11,146,307,10,373,178,957,160,350,34,524,316,692,250,306,636,514,616,477,560,420,291,54,960,503,821,994,519,576,2,317,108,432,498,107,616,485,18,9,118,405,666,352,534,320,248,363,220,856,177,418,917,754,106,94,966,901,320,829,207,370,31,823,146,985,806,436,496,160,211,246,70,878,200,193,404,470,430,852,702,198,38,857,577,448,551,204,714,826,923,698,580,598,750,753,722,837,775,449,650,276,708,82,37,334,516,108,41,824,385,857,415,181,89,972,828,676,811,48,443,769,281,133,503,996,672,639,209,781,798,382,362,399,670,671,96,222,552,719,751,615,334,173,425,682,575,353,787,949,11,497,22,491,241,710,997,569,217,553,95,674,805,172,688,506,169,990,391,1000,446,705,935,237,243,545,34,826,647,150,925,281,228,359,397,610,377,16,972,212,616,932,25,372,199,462,480,887,432,838,33,464,147,998,853,315,761,660,821,417,998,332,647,549,728,446,672,889,77,393,132,759,424,636,445,578,928,355,237,645,338,930,82,122,548,950,358,492,824,396,398,797,71,547,733,213,632,437,605,95,741,227,710,786,640,87,785,619,631,602,367,474,228,485,977,357,853,354,142,787,88,879,748,34,9,947,269,687,183,0,590,223,139,39,728,693,568,923,34,732,965,33,337,297,894,200,511,204,502,697,295,453,6,432,47,471,105,278,800,192,174,912,615,831,156,594,25,553,852,677,236,11,109,914,109,313,531,893,186,966,894,57,126,39,558,329,263,52,139,426,289,815,492,808,538,941,763,389,357,255,13,398,591,927,297,234,631,117,799,778,267,678,193,900,495,674,547,358,240,944,981,770,921,396,545,437,430,366,384,428,604,870,365,944,647,493,592,462,672,460,180,786,870,564,47,146,239,482,334,974,337,404,698,844,116,995,436,171,666,887,767,538,244,179,130,414,362,256,124,65,342,22,623,680,951,177,195,911,82,451,87,215,793,970,673,496,214,355,817,152,394,865,281,391,510,340,846,498,429,172,273,457,141,204,83,234,558,429,53,8,101,906,402,74,700,326,948,835,394,971,879,234,569,694,474,803,393,744,994,807,305,270,199,568,440,952,875,762,92,904,371,539,574,250,251,192,947,499,47,778,439,63,349,9,985,67,680,654,99,895,162,274,794,841,276,390,405,756,128,616,3,123,32,730,632,166,516,256,965,857,632,185,942,438,66,32,984,107,989,160,669,890,861,583,171,776,389,128,59,196,941,820,812,103,607,656,994,425,148,415,958,588,216,331,820,822,27,878,610,147,104,705,298,58,831,473,250,521,219,925,883,894,341,590,550,537,287,914,257,160,798,965,999,5,771,187,966,616,831,333,20,339,877,888,576,594,382,835,596,245,580,130,601,295,796,158,24,767,80,369,883,634,380,124,130,234,362,785,756,474,97,545,615,390,902,129,964,725,96,159,674,762,837,465,619,744,693,516,88,597,983,355,450,683,287,73,432,363,506,221,200,533,252,41,934,69,565,573,921,518,820,964,674,697,628,613,127,475,57,71,206,335,457,430,175,417,813,101,902,792,850,807,618,65,162,461,346,179,140,855,918,393,947,507,247,890,339,874,371,438,337,840,733,431,782,263,160,511,219,767,395,636,477,133,913,591,169,937,4,781,359,385,197,189,25,309,10,722,441,241,18,216,84,604,633,986,161,152,753,489,809,214,483,120,959,675,666,450,432,470,743,206,3,833,355,976,301,722,908,531,311,786,173,623,870,84,801,599,976,279,420,238,630,809,761,555,455,919,981,655,977,894,912,852,694,644,251,911,698,195,124,46,830,457,850,961,305,714,873,156,670,358,255,165,686,126,560,824,498,779,218,925,599,950,134,548,749,943,792,228,145,343,572,121,949,50,875,256,121,393,688,855,924,217,876,561,122,280,243,221,595,770,166,877,749,224,635,586,645,869,142,842,898,751,724,68,265,944,283,487,571,980,686,240,478,444,822,419,88,855,59,505,755,44,519,31,504,666,559,311,471,699,856,319,641,347,530,412,123,867,899,737,507,897,953,721,899,771,836,505", "783,85,206,855,676,595,224,877,520,713,185,904,58,1000,737,778,769,988,878,361,503,622,988,907,624,315,334,69,646,351,742,882,746,780,331,61,830,109,406,931,893,136,685,513,73,681,671,936,577,948,592,320,552,224,670,464,978,119,903,993,301,245,776,425,687,995,676,356,103,686,232,586,903,327,968,131,494,819,89,695,96,868,608,114,581,356,815,110,155,782,249,201,49,222,292,156,455,432,858,896,342,195,739,242,42,195,902,997,788,11,873,356,177,632,596,529,742,110,921,477,537,652,469,361,628,187,771,337,776,706,87,448,564,203,110,818,125,459,263,368,724,338,801,713,815,708,566,343,856,894,851,570,201,298,946,573,422,437,455,271,122,530,315,279,894,706,843,489,683,222,140,449,636,987,96,678,634,210,589,919,570,175,290,727,288,727,283,751,287,189,285,213,99,416,872,212,519,986,477,732,356,348,21,402,632,279,623,894,102,579,954,351,427,549,738,458,374,476,671,334,841,263,974,546,934,287,559,492,906,94,399,908,913,173,341,410,867,555,78,262,447,94,428,843,595,433,208,828,693,870,574,893,195,783,118,142,89,835,512,374,59,585,79,506,960,530,723,410,799,33,18,652,627,696,668,617,615,653,223,166,973,14,413,147,326,645,534,830,696,498,276,27,591,825,702,61,238,321,13,474,234,297,548,842,220,407,718,325,621,527,363,23,225,471,691,68,215,898,706,65,44,460,6,21,476,232,974,375,327,260,106,246,833,62,706,378,671,681,441,345,495,190,140,412,216,427,537,529,555,405,362,643,937,742,124,770,933,51,365,237,962,904,720,357,248,706,492,716,166,590,0,429,432,34,99,503,861,33,69,45,947,631,542,410,55,171,135,311,865,799,278,147,528,804,157,144,964,380,595,204,679,862,242,297,75,66,746,730,363,291,86,883,674,182,302,459,591,576,450,476,801,846,967,866,466,81,47,11,371,220,799,841,256,796,943,75,571,658,573,472,318,575,992,204,956,864,675,353,900,845,532,241,962,407,646,336,652,780,989,24,608,455,150,594,571,991,578,510,57,868,921,568,893,114,704,654,652,782,831,980,250,176,457,945,339,672,408,888,114,561,765,765,677,759,573,473,413,16,152,256,784,185,576,106,925,912,236,704,216,654,484,296,739,546,675,614,391,212,402,259,705,74,202,948,279,751,54,216,136,757,253,405,269,715,324,136,630,923,459,846,76,746,258,493,134,967,346,240,17,151,459,2,185,595,438,316,377,385,667,865,169,544,215,908,762,791,508,533,472,289,966,800,777,50,889,1000,300,723,656,307,103,443,273,27,863,210,821,474,790,212,686,397,478,28,943,109,713,765,530,858,730,29,99,388,92,544,259,66,413,996,747,603,517,711,161,420,809,573,299,239,904,766,103,602,51,786,217,313,932,36,499,592,294,118,749,561,724,477,272,226,95,109,447,855,553,669,410,206,629,611,410,323,259,352,996,637,518,532,660,575,618,657,163,450,548,71,851,11,748,426,968,890,398,673,493,126,301,584,121,710,937,295,656,440,703,421,974,655,87,569,762,393,77,571,258,640,834,830,28,754,576,71,754,545,359,624,854,796,895,681,8,35,895,168,359,169,569,220,792,314,495,631,982,335,637,535,100,894,438,87,811,680,495,349,771,545,555,317,389,469,877,7,507,29,669,19,804,8,142,63,461,134,823,286,491,321,722,546,509,720,235,347,245,421,833,111,909,555,423,744,994,423,457,734,732,261,751,614,586,391,499,147,16,719,165,980,856,813,208,227,855,42,802,542,955,66,635,877,861,306,869,240,92,234,881,490,620,667,158,197,421,437,563,897,265,843,300,185,180,299,879,575,448,546,256,78,620,501,696,429,306,731,839,485,885,688,170,648,722,951,533,446,474,962,52,272,438,993,758,547,849,954,917,59,187,485,982,475,76,154,519,415,53,94,303,551,325,488,414,679,396,517,984,200,405,830,159,705,621,406,183,748,892,594,144,950,218,222,203,323,488,192,329,354,802,994,662,834,237,57,473,830,9,552,257,801,920,736,309,183,289,812,26,959,342,446,300,825,339,355,429,571,697,828,625,151,203,460,941,112,461,389,235,144,437,746,863,652,98,533,330,696,685,816,779,979,669,605,655,30,682,493,942,738,330,905,576,375,427,678,95,977,888,839,150,624,128,245,772,534,389,567,670,83,156,764,770,330,756,916,631,133,698,585,131,680,613,996,121,276,470,676,272,638,492,552,517,877,165,210", "963,476,829,673,765,81,156,433,824,136,368,615,99,768,425,646,6,324,857,139,863,180,86,155,239,187,648,32,958,307,703,886,495,881,696,428,689,510,695,818,755,628,18,53,420,156,948,326,133,877,372,980,367,8,102,16,895,496,212,640,199,19,553,486,756,750,61,600,998,418,930,305,113,722,693,171,928,931,552,631,454,529,539,609,228,850,484,315,895,815,36,872,913,430,273,58,827,878,950,865,113,676,501,94,655,205,15,514,215,548,166,703,778,812,677,983,630,36,484,481,29,646,793,284,630,707,867,977,176,432,259,824,175,331,345,917,301,457,677,251,225,183,382,423,891,154,45,936,875,932,953,434,359,539,836,575,834,241,595,540,165,964,280,991,716,580,636,465,18,233,522,113,766,47,101,59,214,840,578,822,69,145,473,459,920,971,619,738,686,13,984,450,456,148,16,18,848,909,696,98,887,466,746,73,563,12,883,859,130,23,879,437,780,661,885,126,760,604,241,116,339,541,789,750,543,3,224,940,932,363,139,236,243,395,249,532,331,26,41,210,901,908,3,422,609,479,951,548,615,780,347,89,902,72,272,541,930,1,725,29,298,908,389,495,92,923,100,435,353,114,325,549,513,669,925,582,407,137,717,889,490,9,348,447,407,616,563,203,344,585,469,795,646,365,457,118,19,503,286,264,705,590,866,759,500,107,178,472,958,310,985,30,152,364,137,804,674,656,118,468,281,502,428,278,299,420,753,884,767,39,102,579,633,598,410,644,231,477,910,115,716,122,993,135,988,112,352,931,311,182,745,791,287,844,302,959,839,867,537,28,516,284,735,396,955,141,150,740,526,223,429,0,553,859,464,269,76,176,164,743,161,112,630,224,382,558,235,747,805,821,803,194,864,670,376,445,629,222,538,338,209,832,459,748,117,280,280,848,751,787,726,237,504,115,417,397,727,91,925,974,197,636,889,216,996,983,361,640,717,122,360,170,185,899,36,193,887,212,494,852,1000,595,319,85,397,988,188,653,26,931,634,787,807,176,267,694,574,591,569,637,631,395,870,225,430,681,599,763,725,524,419,249,23,20,689,500,691,111,709,316,941,516,470,475,861,509,851,903,971,938,820,383,825,720,856,322,801,998,773,286,169,542,202,719,71,275,191,176,860,984,798,747,118,328,984,984,836,578,196,307,832,339,706,77,594,540,886,301,684,728,404,714,28,429,683,907,454,736,918,202,26,42,554,767,315,223,459,685,938,288,273,865,554,931,135,189,806,896,155,764,902,420,35,433,49,701,842,484,167,897,895,332,273,941,350,488,828,138,203,785,629,223,91,15,712,758,537,414,81,883,904,195,600,195,901,260,730,497,583,20,80,634,65,885,999,279,149,92,706,117,70,955,645,780,516,666,663,830,55,290,578,762,280,333,240,516,226,768,484,740,65,57,260,73,878,448,496,485,954,301,909,968,853,219,699,75,764,655,396,638,345,827,135,256,857,186,289,147,764,279,532,34,856,784,415,96,408,320,480,834,126,721,283,181,863,805,978,403,497,898,467,206,98,766,583,549,800,467,548,696,870,796,820,575,400,927,178,471,636,489,663,832,254,49,370,228,794,773,302,123,559,569,819,847,157,576,276,309,45,153,631,898,336,38,289,974,430,213,8,813,808,691,533,980,960,562,643,490,7,46,945,888,991,445,761,415,744,67,508,263,748,162,599,173,399,851,467,932,135,374,28,277,675,23,545,855,595,695,854,953,366,566,767,662,568,238,583,411,407,129,659,690,641,446,442,325,55,730,716,806,199,904,816,999,597,787,795,429,648,480,489,470,674,973,991,819,378,315,542,144,403,271,167,187,625,504,823,189,95,683,168,202,848,751,667,881,965,423,238,223,785,886,459,656,114,637,947,876,466,995,455,447,184,301,937,29,333,519,299,282,754,504,167,698,258,866,2,420,729,816,339,855,198,790,701,168,924,237,123,752,584,880,873,82,246,582,423,533,60,158,655,945,393,692,909,795,959,916,747,972,542,961,959,993,243,965,261,595,276,111,346,157,321,560,706,571,857,878,96,140,884,547,397,32,414,339,178,761,563,268,252,514,404,185,543,660,779,584,99,41,748,15,671,429,851,639,719,630,609,157,927,165,367,695,860,692,800,103,675,997,892,629,473,140,452,371,201,2,60,42,19,993,120,680,242,272,302,231,526,419,520,398,988,137,184,340,609,832,331,659,453,695,506,439,161,589,556,27,745,256,764,31,499,331,882,326,999,360,443,293", "550,243,537,728,933,977,745,468,452,383,174,956,536,159,428,887,896,596,72,31,525,132,144,247,8,586,727,907,260,315,828,919,168,407,44,402,866,351,728,616,320,823,16,399,451,292,464,426,498,942,287,635,44,578,51,575,52,450,286,18,849,645,858,186,990,936,980,307,411,397,597,907,202,113,803,717,371,246,695,324,598,531,580,540,954,590,186,3,392,343,607,378,218,253,701,148,974,453,534,220,172,15,743,464,636,352,350,33,600,667,768,158,203,522,760,203,802,515,598,338,708,288,454,668,308,67,307,426,891,16,355,806,846,128,771,68,436,476,854,660,350,308,759,921,489,501,750,381,280,467,661,936,666,16,139,251,836,440,669,999,41,421,738,153,950,197,512,807,88,484,818,995,202,161,330,728,726,852,414,376,299,94,712,263,426,994,347,820,96,13,514,93,783,954,826,677,32,520,743,806,572,572,5,138,121,14,650,963,183,532,777,624,573,781,472,188,224,335,478,660,937,943,512,296,213,818,99,476,474,357,618,867,120,868,393,502,221,308,810,842,843,355,210,797,476,978,185,758,143,670,32,395,845,714,920,726,472,532,244,109,525,620,986,718,561,192,582,924,110,220,325,108,473,59,713,572,701,881,48,891,801,261,7,202,200,815,2,460,604,934,294,202,967,425,704,471,450,866,406,361,370,914,965,326,437,83,250,979,159,908,684,347,256,637,166,421,118,390,862,623,395,593,474,639,248,841,97,391,191,963,710,692,256,516,831,208,626,825,565,640,409,557,133,230,550,405,341,637,42,559,804,820,52,737,690,156,739,270,6,940,822,558,920,980,803,139,381,48,222,139,432,553,0,189,779,510,327,598,116,383,91,433,4,642,430,817,567,978,688,176,253,823,69,185,994,337,235,421,488,871,172,685,923,98,458,579,619,813,417,999,71,285,917,439,255,54,158,816,919,610,263,345,595,762,612,799,247,181,80,495,456,750,469,961,198,319,878,863,967,640,2,936,83,637,595,355,569,43,291,268,906,630,525,275,643,168,946,588,47,799,317,632,449,785,953,259,48,836,395,974,979,375,550,559,336,758,855,636,130,762,959,468,808,330,765,466,600,404,372,403,564,625,40,10,876,126,597,924,766,392,818,910,562,295,73,870,384,865,896,838,636,770,888,844,225,993,479,518,528,56,18,182,664,363,245,912,895,666,661,498,520,556,711,700,628,884,118,556,421,60,47,204,875,866,145,532,340,616,885,885,77,634,848,46,748,336,736,996,455,338,98,393,457,725,703,140,10,857,876,620,227,44,402,883,570,93,453,896,308,398,533,348,861,944,53,580,147,912,321,195,764,114,797,648,525,870,763,725,115,749,913,480,277,313,812,154,162,132,727,553,758,101,924,367,138,706,659,533,817,684,807,999,574,956,845,473,498,26,167,880,301,307,591,372,76,759,943,83,626,782,270,479,533,858,360,617,573,373,925,707,913,208,871,997,274,793,992,318,668,383,507,339,73,204,927,549,698,394,981,13,441,61,765,70,944,564,891,260,235,746,142,486,25,517,398,249,151,264,638,340,492,937,243,715,560,9,811,353,138,856,62,853,243,333,334,556,670,936,728,49,959,585,946,308,152,608,324,709,464,527,243,812,153,268,993,320,849,789,33,25,706,759,409,342,804,886,243,213,862,717,712,586,425,711,757,812,299,585,61,28,129,216,546,315,483,341,995,973,101,562,967,733,824,457,831,79,947,943,257,617,396,835,246,957,14,494,245,352,802,704,109,581,891,17,51,481,967,622,645,588,682,643,290,466,836,360,278,128,795,183,355,423,944,47,774,538,896,637,820,580,394,748,575,391,545,725,792,301,747,686,865,47,910,876,61,46,454,336,6,201,731,178,467,841,123,848,153,272,278,642,908,734,126,235,162,575,648,177,144,145,636,499,85,489,980,698,44,961,688,43,186,998,988,348,161,964,777,778,743,258,70,938,559,885,690,411,486,269,630,500,945,906,124,398,644,210,646,997,114,48,733,312,606,730,526,965,707,685,890,170,943,367,816,44,76,930,432,666,956,415,930,20,341,654,527,643,957,401,495,410,718,299,591,793,600,873,926,652,623,730,989,311,506,618,170,666,609,783,453,761,347,308,800,790,903,479,672,101,804,17,703,873,778,347,418,927,369,684,937,316,639,437,129,283,510,448,678,60,463,127,266,172,108,935,84,885,912,607,352,686,370,796,806,77,482,601,769,129,980,121,446,835,824,200,925,459,860,579,212,418", "621,513,510,479,298,659,834,532,884,896,505,834,353,673,33,364,140,822,454,494,619,741,336,549,802,603,828,237,256,782,607,93,403,864,561,15,25,601,500,960,442,898,723,395,153,251,638,361,203,706,962,11,99,519,498,434,79,465,999,294,257,843,548,938,504,341,917,329,503,902,311,527,348,791,931,722,513,696,856,524,159,507,523,281,624,886,493,914,904,328,861,381,721,503,863,518,290,486,128,133,238,912,697,109,628,738,180,152,871,318,506,269,212,570,638,793,476,260,391,99,783,422,256,126,365,390,130,442,664,583,824,261,906,585,326,93,652,961,568,740,472,249,703,196,412,215,548,898,727,402,803,537,419,57,441,248,998,774,134,554,324,429,562,923,97,780,985,260,484,646,679,821,579,527,581,777,34,342,55,396,122,538,78,687,53,533,484,491,42,280,935,884,20,211,193,560,72,213,726,801,332,123,106,920,386,862,196,293,302,273,833,68,731,701,170,368,997,598,378,131,923,935,92,912,767,840,443,265,457,138,932,176,399,453,640,213,827,28,481,731,710,676,173,188,246,454,870,413,850,396,40,791,106,276,461,249,333,265,644,31,486,37,642,267,468,936,102,849,279,511,383,917,314,55,198,491,84,482,595,543,166,926,363,68,892,214,216,657,867,652,798,365,231,833,613,961,566,325,96,62,391,131,319,929,602,589,308,15,110,747,982,38,193,241,269,393,767,792,722,317,534,731,485,970,691,107,778,366,895,239,633,696,430,168,499,686,416,75,763,685,235,408,340,826,611,997,418,416,594,164,715,873,107,907,933,693,750,659,224,370,323,476,161,166,937,546,596,780,63,39,34,859,189,0,528,254,892,796,935,694,127,11,209,199,326,888,865,985,468,88,704,47,589,156,285,262,980,555,208,537,709,212,2,59,563,886,50,368,92,168,171,246,681,596,648,426,335,419,367,572,871,759,385,218,807,24,93,227,329,887,195,414,532,283,898,985,160,689,22,15,760,777,311,935,51,221,790,928,481,504,171,660,603,829,317,611,915,386,650,955,661,775,332,423,795,505,106,993,438,214,280,11,74,845,564,452,186,817,39,89,891,775,356,625,805,701,40,737,486,6,807,285,683,919,546,769,904,871,646,978,380,480,374,470,268,714,24,845,243,511,447,690,84,770,494,593,550,535,872,536,209,187,705,203,386,615,712,441,88,630,228,339,300,274,11,254,740,187,364,816,357,935,763,830,964,350,631,328,478,409,533,253,26,982,256,685,164,943,16,582,752,229,965,17,788,204,499,673,843,965,107,172,289,522,876,786,561,272,74,78,336,772,633,941,13,513,561,14,453,218,718,610,49,781,481,998,818,950,156,857,510,137,196,692,516,751,959,37,994,30,343,701,121,470,814,965,282,936,550,969,515,153,223,83,161,528,109,540,508,732,536,945,551,398,462,533,131,431,4,511,321,944,672,7,403,544,887,344,975,296,72,549,575,901,188,938,883,405,125,710,983,647,562,257,426,635,117,905,282,255,852,979,644,962,377,114,108,326,265,935,126,94,235,272,511,99,603,417,8,511,371,815,176,969,947,431,575,709,756,639,481,119,246,776,187,493,119,434,176,447,318,13,302,724,102,266,349,421,810,667,777,686,802,284,676,84,353,191,357,296,856,156,316,203,699,964,174,480,175,413,680,134,414,435,877,110,982,587,668,336,603,698,26,713,787,531,234,482,806,495,47,1000,57,438,70,676,288,420,932,761,844,258,776,128,336,920,791,727,541,88,448,289,702,655,357,577,465,261,926,310,425,930,327,484,438,338,237,861,358,955,761,587,690,887,649,486,960,925,929,288,788,634,573,355,224,485,353,583,683,121,83,468,978,65,212,619,713,984,398,209,112,850,425,17,910,828,114,979,838,210,331,355,171,454,42,253,620,954,59,876,185,393,197,156,920,754,346,349,175,347,997,874,26,340,877,403,185,813,468,439,711,553,461,41,301,28,472,773,346,181,150,472,526,519,679,185,689,55,311,262,496,662,596,322,10,437,786,670,276,497,289,157,719,689,440,654,337,519,923,365,931,514,267,98,679,33,305,855,523,999,953,614,421,8,44,610,403,137,359,600,15,183,782,199,31,545,124,160,796,808,861,503,212,505,171,463,145,718,862,146,210,595,18,502,604,249,71,877,538,130,529,844,25,168,242,127,602,84,548,514,553,926,855,315,345,776,472,973,737,337,749,955,279,223,291,848,386,128,201,281,941,667,989,942,718,187,720,381,346,471", "211,895,279,937,257,648,34,438,179,582,573,153,44,292,60,977,296,397,491,86,717,453,627,118,824,642,481,890,341,236,200,23,816,162,153,546,972,313,259,441,496,354,623,535,280,534,590,76,730,327,454,506,667,930,691,35,627,513,608,126,306,92,635,295,723,261,729,175,99,889,804,404,561,189,915,697,127,262,309,258,709,320,175,7,694,353,444,654,847,17,465,716,318,68,784,120,239,904,965,971,422,295,451,596,691,275,164,822,356,330,222,369,511,566,47,283,150,556,730,67,628,84,483,643,925,265,830,385,449,795,994,326,96,719,155,312,863,145,950,790,18,121,867,961,587,455,175,515,806,802,620,519,126,284,928,59,372,971,716,484,946,791,864,776,408,678,244,700,558,341,34,266,447,773,516,657,118,780,131,613,511,433,119,345,270,696,257,766,860,576,291,777,205,734,966,904,583,615,392,615,635,722,876,373,577,859,994,25,574,980,526,709,438,104,255,254,213,512,323,6,961,685,423,639,626,246,193,496,852,998,438,355,71,805,293,861,296,903,319,246,640,379,753,819,860,432,725,463,28,131,463,590,965,355,573,483,171,464,536,788,793,54,550,198,832,549,740,996,107,386,632,897,226,307,905,292,37,260,855,762,521,329,437,472,1,609,58,687,58,473,490,548,928,464,650,84,416,311,525,925,788,385,788,764,775,845,219,209,941,718,637,675,404,846,388,102,949,134,579,403,591,992,132,153,100,479,375,899,858,977,454,115,136,544,518,149,577,450,475,795,173,458,505,782,688,191,784,578,651,336,929,605,184,828,169,545,898,600,243,663,65,274,430,3,279,224,118,271,867,728,99,464,779,528,0,147,672,70,877,609,198,131,189,703,18,392,579,107,913,951,911,916,269,60,540,364,969,537,956,813,380,672,909,986,950,72,913,519,582,960,291,827,33,401,338,91,972,127,122,571,965,557,454,247,642,641,222,87,642,971,893,77,287,58,308,846,490,891,500,362,513,422,53,619,799,298,952,521,398,924,448,540,562,942,875,62,649,866,217,830,813,862,281,962,404,498,819,118,276,829,25,562,685,592,910,198,595,195,864,167,93,399,704,101,891,187,495,962,777,618,741,61,651,584,610,287,622,896,379,872,957,545,630,571,51,767,959,799,415,24,732,132,585,715,65,883,452,481,19,674,894,403,316,415,738,595,822,854,860,431,861,870,124,368,689,121,134,331,670,935,364,226,780,925,388,996,801,260,548,988,123,721,54,363,76,560,471,297,661,201,524,476,17,564,228,530,607,20,164,759,625,404,161,863,787,733,858,342,88,621,141,637,7,864,924,48,62,197,893,30,308,817,305,769,879,551,412,286,106,531,222,639,897,748,189,685,50,361,19,191,864,597,793,574,948,149,93,867,243,82,938,868,513,667,54,126,241,809,128,18,104,191,964,837,793,872,742,255,761,712,589,230,909,283,361,672,193,970,101,7,740,262,76,485,372,700,502,900,781,976,667,384,880,392,832,227,434,764,918,229,797,968,750,748,98,363,202,755,388,692,412,239,847,865,212,858,496,774,378,586,775,209,514,550,349,42,591,480,190,579,290,165,896,194,425,34,292,106,263,768,792,880,522,988,877,614,590,816,756,917,861,124,842,463,317,774,789,512,808,935,849,735,161,258,765,994,434,395,648,609,216,865,182,995,124,540,213,897,944,201,884,145,698,778,128,457,996,788,983,949,315,439,797,684,484,175,915,105,729,10,119,648,774,527,883,945,65,231,401,733,968,674,879,468,325,496,749,438,348,377,537,233,764,394,644,152,832,61,659,641,608,846,291,669,674,75,894,829,634,173,587,191,875,416,270,385,811,554,578,767,473,969,473,464,431,764,592,339,227,851,775,365,578,431,601,248,64,205,238,398,867,240,654,344,76,624,312,799,892,761,231,131,708,244,442,775,486,680,188,655,276,828,874,525,543,868,24,120,227,651,562,829,353,995,963,523,245,895,347,175,731,520,958,8,53,208,165,294,985,452,528,801,436,615,246,326,88,149,891,357,203,974,951,389,305,861,156,215,882,34,476,816,568,678,991,124,119,349,899,5,175,338,30,824,797,145,464,851,598,957,335,672,357,787,415,383,220,45,956,265,241,260,414,386,532,757,214,798,39,829,287,363,40,881,747,958,635,944,187,979,374,348,4,83,869,557,350,891,841,216,210,331,679,976,567,638,548,216,378,318,562,202,347,661,411,263,302,581,264,447,460,57,815,773,336,517,71,451,377,887", "276,569,277,890,668,742,768,276,255,749,423,54,999,163,264,784,221,586,649,739,642,857,149,15,688,511,556,613,772,742,870,141,395,8,757,569,822,49,85,303,979,564,74,712,489,834,629,232,555,424,654,481,530,647,290,317,665,952,905,442,786,614,957,579,6,546,324,214,857,146,967,289,836,559,560,459,462,493,886,742,366,738,242,9,329,859,102,880,276,412,43,561,594,605,820,120,530,605,120,307,87,970,13,762,928,218,514,672,449,120,215,185,451,512,802,569,446,416,314,917,140,780,635,716,668,458,441,5,782,827,360,87,426,771,62,160,883,256,716,816,922,632,82,837,579,367,95,394,550,952,743,357,553,317,156,327,516,700,585,339,771,546,323,102,200,937,989,772,773,215,342,272,125,164,2,122,549,283,701,617,583,277,595,152,213,852,634,702,256,847,164,259,72,475,577,246,652,745,120,241,874,3,20,138,957,611,812,407,884,200,517,597,592,888,59,610,236,365,999,365,881,31,853,157,201,162,161,772,7,180,137,877,21,561,41,519,96,21,380,225,334,260,459,772,955,394,830,333,944,403,9,323,567,511,172,581,111,411,348,29,971,143,42,693,680,840,252,646,873,488,68,25,735,562,195,70,296,465,492,361,199,6,565,208,136,403,925,458,851,723,188,119,984,816,224,527,682,129,426,394,288,518,37,504,488,635,778,817,167,142,302,769,805,811,355,348,157,598,796,982,526,974,104,180,26,572,846,882,705,603,96,706,992,80,725,317,360,443,198,139,114,949,325,796,739,142,111,320,153,739,255,771,311,123,91,489,766,386,201,561,99,169,475,467,29,88,212,847,175,693,503,269,510,254,147,0,364,277,672,212,814,167,685,806,36,695,319,747,687,775,366,592,684,968,891,446,462,874,485,556,602,449,611,686,955,993,594,571,245,705,9,217,382,795,975,149,579,871,892,224,259,210,440,834,973,479,935,139,887,890,693,230,639,201,379,320,417,677,153,775,766,754,776,190,222,234,533,176,603,753,958,571,975,90,745,701,459,554,294,419,158,517,712,614,218,406,64,829,216,245,267,738,772,248,405,638,676,665,507,997,638,666,469,134,837,327,315,45,783,873,464,707,13,367,729,84,405,764,969,132,104,267,100,184,142,229,407,685,116,461,592,239,345,717,43,382,90,247,181,52,489,811,337,185,705,928,767,221,813,731,905,17,28,613,825,698,986,143,446,761,224,933,618,522,382,6,259,763,817,867,673,965,846,210,180,829,314,148,44,64,173,274,944,687,721,115,952,498,181,351,119,123,66,496,718,169,427,65,483,782,487,792,526,114,477,94,993,898,324,794,225,600,761,900,788,141,387,274,290,246,162,799,580,62,521,169,428,80,706,645,851,624,640,685,655,76,115,917,201,921,861,244,715,406,97,776,919,477,914,567,594,910,97,730,495,783,864,960,712,575,784,668,757,273,18,123,301,917,579,38,240,659,241,496,204,27,111,901,164,181,869,774,272,447,391,63,162,459,865,456,211,288,214,348,806,64,719,944,499,478,49,444,242,5,297,293,257,98,576,258,299,899,573,3,534,203,194,386,327,524,137,644,743,563,97,255,484,322,870,128,873,928,74,639,325,644,978,648,785,483,198,620,211,788,79,574,767,436,683,483,223,669,392,56,79,22,487,159,68,77,45,13,195,625,809,749,162,213,814,512,26,264,785,958,604,521,273,493,971,929,795,624,84,665,656,300,730,294,547,798,450,378,359,744,364,814,894,377,873,542,64,31,245,913,455,68,724,884,697,163,473,534,887,572,678,183,759,569,425,768,782,63,262,828,832,387,228,592,301,489,369,223,801,637,907,672,190,32,763,612,358,948,331,869,156,40,196,383,181,102,388,515,690,394,284,512,672,856,869,125,579,664,689,942,374,635,614,642,370,804,99,166,850,916,867,929,159,901,639,125,866,458,702,23,685,59,841,317,29,210,113,212,881,675,69,210,807,327,15,723,893,608,749,447,555,511,140,523,625,598,594,358,18,186,294,492,527,238,576,882,559,853,296,745,995,694,146,963,490,83,737,682,412,482,861,274,907,826,87,702,816,419,193,232,611,781,437,197,645,221,341,168,446,210,775,237,849,42,143,144,638,466,259,714,247,476,708,2,83,363,98,760,419,798,390,535,946,537,475,887,530,879,77,481,801,39,269,927,763,415,997,65,429,200,371,101,128,314,143,855,245,877,696,988,196,792,593,272,358,760,872,512,198,185,737,833,917,868,494,961", "133,29,316,328,939,463,258,544,894,340,922,142,944,117,699,836,669,381,580,838,632,684,701,156,329,85,54,203,61,138,662,94,441,680,905,780,15,874,586,642,576,399,891,386,892,388,577,250,170,856,185,954,95,919,132,279,408,722,135,286,241,99,653,574,906,66,42,652,41,537,508,960,93,630,129,891,786,733,901,117,78,410,683,638,240,258,380,742,740,922,7,393,384,141,100,284,900,258,298,497,755,826,146,982,904,24,335,173,199,798,575,845,385,370,845,554,725,536,203,548,23,609,185,967,643,310,377,833,193,575,235,18,632,539,579,968,552,685,556,836,162,17,570,195,605,189,948,448,974,712,990,906,955,11,252,50,742,59,158,154,674,557,638,92,631,716,683,518,658,53,354,419,466,700,958,203,977,39,209,74,491,850,13,592,604,385,666,292,425,463,959,485,780,666,820,846,410,890,388,405,667,152,479,507,407,622,859,682,259,106,34,274,589,813,596,486,610,581,489,140,810,999,205,59,483,270,406,530,555,269,232,645,248,399,67,738,756,256,89,686,441,246,17,803,582,281,877,955,110,364,858,797,908,642,395,28,367,722,384,676,199,458,635,83,868,954,712,245,594,72,599,927,100,880,759,445,998,535,780,357,970,679,458,483,488,894,784,266,925,767,602,503,801,600,839,265,282,194,927,214,526,998,681,659,96,796,832,750,963,406,462,183,828,725,503,234,874,134,484,802,753,811,958,854,260,888,984,559,388,914,749,413,996,740,39,734,851,366,425,629,480,908,511,73,531,450,782,793,510,104,346,673,443,864,975,67,916,155,663,364,841,617,536,509,260,636,931,816,773,568,861,76,327,892,672,364,0,137,428,278,315,376,954,315,273,399,241,559,830,665,817,491,308,952,839,244,14,13,280,749,922,360,105,111,423,605,527,837,132,435,582,774,727,695,569,27,150,533,294,535,385,343,985,794,226,908,903,888,607,185,413,419,322,870,596,609,869,786,963,182,669,134,979,578,497,852,170,309,726,487,356,462,95,201,324,166,496,917,733,983,748,503,334,701,658,477,95,636,419,359,408,628,343,301,248,983,176,624,266,2,611,538,814,412,720,703,97,488,699,300,871,325,898,440,557,494,10,480,581,301,787,566,797,830,593,158,100,873,972,391,471,310,124,552,889,30,856,396,682,91,685,837,47,503,914,625,696,232,29,44,125,627,518,892,718,248,632,301,219,876,31,911,988,108,942,494,183,593,141,411,125,371,630,46,992,3,376,256,85,19,94,446,28,274,570,978,422,618,191,715,685,699,568,871,453,144,227,921,205,994,82,726,804,321,409,966,978,632,276,101,408,206,808,161,41,878,48,307,912,288,401,748,448,971,74,363,860,488,940,654,736,652,907,405,714,486,785,268,747,29,851,858,519,90,124,82,747,953,872,654,943,572,204,496,402,479,170,391,33,319,80,946,714,507,339,997,377,383,217,510,35,602,819,639,968,164,16,771,244,709,843,867,923,117,435,743,659,671,413,957,181,18,708,725,753,712,453,172,988,472,100,520,522,103,597,426,133,987,227,656,616,705,772,423,696,228,670,382,530,245,370,330,685,461,633,475,312,47,529,646,57,371,501,213,532,399,301,482,568,946,661,310,142,686,831,18,786,825,902,85,874,42,675,876,111,857,530,572,342,511,457,506,476,958,58,940,170,470,355,409,251,601,913,738,523,976,936,243,785,833,222,394,540,63,338,297,234,880,616,22,13,118,829,889,600,746,193,834,105,809,654,426,968,206,922,890,801,496,833,981,472,183,808,158,632,64,709,756,532,501,118,906,344,206,876,312,396,3,29,781,428,476,782,682,934,411,41,42,750,865,719,913,28,455,693,175,599,886,478,933,24,567,246,661,901,461,186,75,905,377,449,600,188,693,678,467,743,349,811,498,591,423,79,407,696,631,657,732,134,508,112,576,373,113,391,545,591,160,728,873,608,377,831,643,183,275,426,855,494,520,487,532,541,85,99,127,931,114,909,580,203,194,803,505,703,327,419,223,450,822,880,546,498,913,438,267,143,892,199,819,135,34,26,872,716,435,287,329,755,7,92,750,942,87,399,40,701,301,850,1000,882,713,509,821,896,719,661,530,369,519,893,846,622,933,567,566,713,691,762,802,678,740,302,459,374,446,516,89,435,911,867,618,320,715,140,568,633,512,891,948,469,107,440,789,74,396,526,530,477,338,820,435,655,789,703,7,195,714,325,232,796,160,729,406,47,952,614,715,57,185", "303,561,143,961,971,7,68,53,19,979,923,423,470,157,919,656,276,438,293,182,480,436,143,338,157,794,259,25,846,362,955,345,411,639,382,232,193,910,755,211,982,693,62,27,842,763,494,560,266,22,710,822,392,153,167,845,621,889,59,169,434,959,123,866,879,726,952,548,594,24,466,41,294,497,990,95,68,283,913,171,937,852,833,363,741,607,473,999,127,806,523,270,144,862,370,718,230,477,963,771,300,409,837,683,895,257,150,450,770,786,990,454,420,399,694,123,270,449,918,652,426,237,577,667,870,384,177,834,741,561,997,263,459,994,243,794,282,691,806,843,852,168,375,664,299,7,835,736,360,962,601,367,189,67,36,282,882,600,264,262,721,566,507,190,132,837,671,207,282,707,539,754,498,323,242,728,363,866,570,805,919,246,139,550,335,600,247,60,561,561,346,61,483,581,513,406,330,707,421,761,988,126,301,732,626,588,562,669,320,234,150,873,405,288,614,397,193,294,133,882,444,54,243,166,838,720,910,364,193,375,821,564,74,990,111,92,261,590,896,136,421,629,302,131,675,600,998,156,473,939,90,986,869,570,355,936,453,654,903,655,193,430,931,892,906,188,471,268,198,646,227,724,408,706,857,577,483,109,771,110,467,296,670,234,380,836,441,389,845,481,693,470,604,70,960,101,937,392,694,607,457,526,452,248,175,173,696,220,961,813,597,434,876,244,866,805,653,920,380,807,217,400,327,255,125,328,847,670,520,759,713,509,927,241,577,73,985,694,835,742,496,368,831,373,217,736,415,135,466,266,379,253,240,894,408,452,702,501,303,204,671,250,553,257,346,864,655,333,698,923,33,176,598,796,70,277,137,0,478,437,353,627,952,879,947,298,509,135,10,75,416,352,680,757,370,682,586,282,444,174,482,555,224,481,599,359,630,395,402,185,25,858,322,355,235,107,241,580,456,957,941,555,4,807,895,265,466,507,314,58,406,410,326,154,932,853,91,269,696,605,149,890,655,891,883,370,33,750,839,985,155,138,385,926,655,538,126,625,90,551,777,662,510,750,427,323,453,775,354,566,247,941,427,392,744,360,721,511,865,466,552,675,524,96,313,138,470,252,979,868,445,320,232,22,596,250,133,334,957,737,526,729,864,345,523,311,449,113,261,452,123,767,476,338,560,658,150,455,198,143,909,200,335,151,328,109,102,258,323,563,919,748,701,165,352,998,48,190,64,626,594,281,19,367,729,364,809,51,262,918,628,665,254,806,743,338,228,59,885,621,910,655,931,274,359,906,481,865,317,311,867,33,479,615,900,248,893,510,722,21,16,209,413,898,943,319,865,589,849,343,378,512,584,279,165,789,299,334,101,522,735,35,276,508,674,478,439,934,489,472,423,139,325,419,836,136,575,516,229,265,695,693,621,370,955,6,950,374,649,351,830,492,372,703,264,761,106,448,417,329,326,12,818,331,243,596,268,366,867,336,261,413,657,167,704,260,221,944,63,84,610,529,364,635,881,355,930,730,597,908,36,448,226,687,459,510,193,149,57,206,573,744,745,525,916,457,349,254,566,640,763,139,947,482,248,905,820,11,478,700,89,191,892,560,316,700,229,600,646,888,707,366,321,199,287,139,63,340,145,611,619,294,321,645,259,69,181,669,336,27,37,295,106,330,499,460,690,174,461,908,165,383,799,567,565,448,611,714,886,658,27,882,167,51,275,428,134,590,814,902,453,239,555,973,10,107,782,400,140,574,552,409,718,522,532,625,812,955,566,427,429,280,497,382,752,501,84,280,475,207,180,325,794,946,669,32,517,932,201,359,410,723,896,198,429,516,796,892,558,335,103,891,259,400,454,485,654,685,4,834,647,370,446,18,50,290,867,413,95,808,223,397,281,644,982,508,616,679,454,291,817,228,109,284,539,857,418,44,735,634,761,711,342,130,475,928,937,223,692,262,766,511,862,762,212,825,745,547,683,694,473,637,7,602,112,594,83,171,823,430,458,932,601,129,81,287,284,573,292,620,235,713,112,771,40,899,476,639,673,270,113,303,42,431,605,879,447,496,784,349,875,762,567,589,601,52,69,853,934,68,452,281,752,75,60,82,512,644,728,698,380,996,703,533,608,524,582,149,910,332,935,346,555,202,496,281,738,891,173,4,533,43,116,116,597,907,877,641,644,432,923,615,257,504,369,964,937,111,635,693,353,33,617,858,560,42,327,194,799,282,435,23,29,680,88,464,658,868,485,121,545,861,739,908,574,896,864,255,970,724", "695,528,32,91,661,65,722,47,553,70,425,861,197,893,369,129,262,67,805,684,9,214,352,818,250,58,461,463,186,516,93,428,122,350,908,425,366,39,261,91,591,678,614,977,973,890,680,350,137,21,580,212,611,723,970,764,290,576,652,597,982,904,352,356,877,995,516,900,531,780,992,507,605,10,381,838,366,510,716,414,916,712,604,368,807,279,650,866,333,614,404,531,571,311,409,538,603,955,102,946,328,936,430,903,903,181,353,475,707,710,694,348,710,587,937,725,812,541,795,249,924,177,1,655,383,183,765,119,251,351,824,270,955,304,550,837,418,154,523,304,474,299,717,478,718,853,910,448,108,847,165,805,535,824,660,966,197,938,941,781,3,731,374,986,64,457,529,572,483,657,377,899,101,550,846,711,663,125,976,338,46,271,920,666,978,156,632,641,785,227,633,134,677,516,335,719,571,672,91,160,493,472,626,204,859,279,200,545,537,511,372,778,584,701,651,127,220,206,852,949,587,856,584,48,386,594,631,505,984,707,876,42,752,640,945,911,662,796,817,570,846,214,127,476,500,4,618,987,240,804,946,308,923,331,147,48,349,606,316,542,334,317,463,570,486,587,622,142,520,594,558,51,108,623,907,735,508,70,489,308,557,217,186,829,693,452,273,627,101,703,374,705,537,500,379,72,303,992,458,768,871,462,724,59,860,248,123,62,911,283,876,420,475,165,373,243,54,83,382,725,748,611,863,813,800,824,978,756,688,331,152,201,938,836,534,984,490,139,216,241,549,454,453,766,788,317,880,89,189,873,126,96,631,46,671,787,656,934,569,910,258,690,824,805,602,760,661,958,360,34,69,164,116,935,877,672,428,478,0,991,832,802,225,667,552,577,913,497,564,945,318,877,832,140,785,431,802,162,735,559,176,483,824,211,131,250,303,719,617,843,59,693,176,973,184,701,610,349,379,464,340,281,212,317,71,331,683,914,100,784,735,200,177,459,18,556,819,247,866,627,54,303,8,400,788,179,254,572,220,668,406,101,920,661,708,58,800,769,850,706,364,4,844,873,377,747,125,975,722,705,168,505,767,58,448,456,633,570,860,187,767,50,919,509,693,54,68,682,603,233,414,828,523,490,499,249,132,653,417,454,592,134,38,605,926,591,857,945,642,476,888,949,376,205,867,958,389,703,518,356,678,93,615,576,473,479,577,634,847,598,714,231,712,813,672,702,997,582,266,446,268,85,869,405,308,547,970,180,477,572,722,694,254,369,289,966,891,599,956,69,196,143,467,872,834,440,116,930,135,563,363,341,774,140,619,242,637,10,275,700,405,669,66,776,486,571,331,228,597,706,431,639,538,501,526,27,284,543,370,72,726,278,153,97,348,665,67,185,793,688,33,611,984,415,528,758,251,801,646,53,983,784,945,690,103,566,895,185,366,115,174,393,903,726,953,106,909,373,99,832,546,691,667,938,625,287,304,189,431,990,204,80,780,418,417,474,822,493,248,800,629,774,675,91,563,889,750,777,936,472,163,967,833,572,656,535,556,118,571,337,782,512,914,896,636,172,677,403,18,5,121,85,121,931,467,259,404,815,476,514,299,692,834,368,324,674,63,321,10,896,90,128,433,174,579,232,714,522,291,730,184,146,737,77,593,591,98,763,403,601,992,889,516,408,108,959,198,697,13,977,814,540,289,175,418,837,353,165,358,26,489,25,313,592,692,836,604,339,531,780,288,807,238,271,694,448,754,818,233,420,148,997,464,575,374,290,663,371,819,834,397,683,948,381,260,802,413,775,45,238,815,992,981,162,775,442,516,103,247,675,514,512,351,300,977,396,531,523,637,150,44,43,171,479,588,914,185,20,850,436,961,150,78,335,254,15,486,432,231,564,949,63,623,515,419,315,487,66,843,774,495,345,170,546,317,862,974,710,668,550,827,90,179,960,744,5,741,13,215,990,110,809,802,85,94,957,87,717,239,225,737,25,380,878,991,268,666,292,886,271,833,490,522,790,570,45,831,615,554,554,673,654,451,559,373,324,936,316,107,480,443,299,104,851,995,760,33,509,558,309,720,336,184,857,644,540,957,523,199,457,979,278,868,75,649,315,783,857,775,7,663,383,148,271,450,384,991,601,764,875,9,872,71,373,243,450,634,739,351,599,224,921,53,81,57,658,562,340,181,29,620,623,376,157,598,537,548,303,318,503,358,718,768,392,576,173,600,710,476,5,990,246,723,719,107,963,102,421,670,31,805,206,336,316,924,900,863,940,323,361", "211,525,948,311,4,572,727,372,936,588,339,961,564,890,763,558,509,776,24,460,685,309,684,49,762,958,276,166,528,306,194,741,71,961,983,465,829,881,408,77,856,512,630,203,579,530,560,983,937,807,926,215,163,989,130,925,568,34,650,458,311,51,824,169,32,682,321,231,835,822,266,70,394,51,411,323,799,898,417,882,776,680,685,763,549,121,178,75,157,157,840,51,422,701,709,570,776,830,797,909,843,152,724,75,584,57,906,986,586,948,546,125,975,430,326,134,99,924,86,613,885,992,780,612,745,137,781,102,655,467,377,946,83,960,744,75,470,156,497,516,171,177,362,76,505,286,931,818,92,548,236,814,476,680,9,533,481,913,112,649,314,50,162,427,801,459,938,424,82,372,13,815,336,829,264,597,549,641,808,245,47,35,770,551,760,224,368,9,823,109,750,392,692,76,500,416,998,697,634,925,406,466,352,747,157,964,344,378,621,4,861,726,882,215,906,460,107,412,911,128,581,228,971,549,465,132,415,335,364,350,931,436,432,14,27,62,797,586,944,135,620,752,751,167,328,386,252,186,667,751,869,12,655,382,529,865,831,880,702,35,55,160,675,662,688,567,519,952,458,496,663,388,128,663,238,209,846,27,927,566,885,282,63,751,717,11,214,624,342,459,476,296,579,8,802,347,857,691,528,307,978,783,474,874,482,292,260,304,484,877,434,198,418,604,383,578,917,415,247,16,137,538,839,44,47,920,307,260,122,481,66,645,169,701,831,892,265,435,803,821,996,197,409,126,311,632,295,538,767,483,650,604,245,940,457,796,685,161,717,718,576,814,408,353,426,194,892,501,405,732,45,743,383,694,609,212,278,437,991,0,808,114,207,395,95,82,47,332,462,367,210,426,193,201,630,770,756,511,690,74,828,866,245,262,992,163,316,174,253,341,164,374,650,510,766,618,185,249,908,801,60,56,310,475,16,904,199,721,114,290,582,298,873,688,226,4,395,785,438,873,445,955,491,119,832,246,234,529,83,909,496,311,278,374,425,425,875,443,644,498,532,786,930,877,526,36,257,167,621,407,979,489,998,348,435,391,741,992,232,72,748,627,137,673,148,940,618,930,952,89,961,345,469,104,332,556,548,48,968,814,495,317,851,745,835,749,685,106,897,962,127,303,436,214,40,94,992,224,847,79,85,824,775,392,927,599,901,611,724,793,121,226,801,905,976,968,682,580,440,353,660,100,226,87,407,863,257,719,36,598,678,736,411,917,750,502,423,780,205,923,587,30,174,702,179,138,167,992,399,756,143,332,524,741,296,679,564,355,413,317,505,464,335,683,558,72,890,387,66,600,971,237,726,811,160,613,942,5,178,346,510,460,665,419,110,673,889,579,877,368,674,720,975,818,663,206,935,443,22,907,203,853,312,886,750,883,426,460,973,50,192,486,230,645,738,619,489,177,993,972,346,790,315,434,923,719,76,12,673,355,941,964,437,845,123,34,657,404,58,431,712,400,441,531,695,648,149,826,59,161,364,427,801,243,569,814,445,645,110,577,674,180,514,182,917,34,79,783,820,938,54,66,277,108,817,210,243,299,954,451,766,856,472,401,655,686,858,605,328,635,322,70,492,555,976,481,490,320,227,864,531,101,530,825,829,380,8,827,99,211,681,795,426,646,170,419,899,611,340,622,424,234,64,826,289,770,125,63,481,540,807,389,243,271,911,986,277,863,4,945,733,282,621,236,912,989,946,568,558,431,75,18,539,690,299,650,574,563,463,446,992,70,164,762,336,581,317,115,336,340,136,782,999,995,800,753,875,15,406,291,254,749,308,153,117,176,392,950,647,137,978,286,221,423,28,175,574,695,811,917,311,140,478,164,572,996,313,53,862,728,610,860,829,643,706,210,592,100,245,677,758,838,248,236,408,94,730,814,957,498,405,649,139,248,832,317,815,159,141,505,922,397,197,200,768,594,302,600,679,417,366,426,47,84,962,422,594,880,817,691,989,418,185,62,778,831,161,918,617,48,106,67,114,185,130,729,203,439,647,925,150,707,391,257,260,525,689,950,933,419,857,935,486,919,936,298,54,847,227,506,378,871,467,706,349,464,385,62,606,512,526,378,663,410,299,861,229,344,83,16,861,114,153,378,141,989,93,936,458,848,920,605,35,442,672,95,361,95,504,156,532,310,681,431,639,15,428,105,370,258,955,334,694,984,849,94,224,224,574,806,413,241,115,812,167,181,507,969,456,671,941,389,484,305,449,460,325,641,660,77", "957,333,772,494,853,807,255,257,616,389,481,231,525,558,863,169,66,289,69,166,609,774,373,85,789,520,273,48,391,588,559,530,955,597,488,387,85,576,250,320,537,509,300,694,625,617,681,338,278,80,274,828,785,648,627,210,761,741,118,935,795,763,545,897,772,755,8,428,900,816,548,759,213,249,96,83,14,150,176,808,473,150,503,191,619,607,641,899,624,855,948,813,136,740,110,917,180,588,518,737,566,975,796,810,255,964,233,826,842,976,696,2,968,723,895,231,7,376,523,686,350,583,314,328,477,670,473,408,345,5,65,233,139,287,57,423,633,766,130,741,928,836,463,768,458,749,57,30,178,379,360,557,435,562,992,5,94,33,201,796,624,17,540,120,234,61,91,298,272,255,443,59,239,107,129,884,71,306,237,344,814,26,894,996,918,402,329,123,191,1,980,381,473,47,779,360,795,918,108,679,886,419,439,779,390,305,411,650,283,276,618,944,118,191,223,947,70,827,588,997,106,407,315,104,788,656,520,347,231,9,887,376,662,296,142,67,564,320,217,194,626,688,54,568,632,366,999,573,249,331,635,756,900,982,944,552,72,207,865,885,313,294,433,303,632,305,607,713,210,778,703,743,614,3,494,779,236,328,956,589,607,960,454,703,304,694,684,650,439,726,820,942,801,818,630,748,966,514,6,136,199,160,69,751,730,747,473,696,605,7,32,773,187,118,303,64,781,418,479,635,727,610,595,843,919,850,569,113,999,472,193,40,615,264,537,828,925,861,617,101,728,62,420,745,214,177,731,930,622,164,498,879,81,926,437,116,83,261,88,196,236,330,524,901,82,177,925,531,855,965,947,161,91,127,198,814,315,353,832,808,0,708,164,420,409,99,253,631,750,630,177,22,740,669,288,277,915,804,817,980,278,625,49,374,777,572,488,667,108,224,142,871,111,332,741,801,16,574,412,48,704,382,33,951,789,584,576,226,172,933,525,341,638,694,167,280,606,888,529,916,915,576,126,609,335,226,50,828,166,105,670,116,657,839,822,921,628,84,540,705,611,242,754,486,896,796,515,590,30,647,333,711,259,219,804,465,206,162,668,739,152,197,863,784,727,194,719,211,99,955,339,551,312,136,654,706,725,120,272,828,236,404,412,821,321,600,374,687,469,769,99,672,352,725,256,168,653,376,963,342,423,533,948,139,497,702,345,750,285,282,332,667,514,960,854,254,23,840,766,787,634,223,216,892,47,166,200,728,997,187,800,548,121,718,527,10,613,976,975,212,877,862,485,650,727,175,427,11,373,527,147,438,490,383,441,296,397,620,485,636,2,681,387,401,241,734,761,545,555,782,591,729,34,663,616,263,636,382,295,394,20,672,402,53,762,366,299,364,468,430,78,551,785,510,788,52,424,128,931,637,592,896,573,25,888,271,90,220,598,670,937,929,583,646,655,475,920,431,701,136,981,68,822,708,816,668,693,220,561,297,352,402,739,613,35,604,35,154,738,229,443,404,821,163,506,956,611,207,798,450,873,93,829,347,860,752,190,595,978,339,557,496,973,113,889,381,624,292,262,884,191,678,828,187,93,362,829,592,203,885,542,376,4,942,836,724,190,21,776,409,24,9,223,935,252,634,653,532,170,908,869,940,856,11,135,690,742,897,742,754,726,48,837,222,133,782,599,287,4,857,346,998,331,30,318,128,824,857,24,262,204,976,915,932,304,26,956,414,622,288,123,114,314,294,539,516,342,642,280,68,569,710,685,203,449,856,508,794,709,661,378,317,469,778,547,34,788,235,659,392,706,485,61,728,296,417,797,108,759,96,424,82,861,648,443,903,53,411,664,266,553,835,380,845,684,482,649,992,493,568,431,403,770,874,373,926,402,530,568,999,549,660,171,319,973,505,274,60,36,691,183,420,807,294,24,630,44,956,33,447,392,916,611,209,431,484,334,574,224,935,158,705,101,981,225,357,660,767,844,301,975,204,211,222,525,42,114,443,2,117,6,159,134,636,365,455,591,164,275,95,126,234,885,798,95,860,610,389,640,237,729,433,699,617,515,368,22,456,821,959,657,899,914,683,447,270,318,203,461,795,721,571,410,556,100,957,9,404,666,105,421,842,297,291,398,858,683,458,571,824,359,959,446,249,742,519,710,923,401,661,217,280,493,119,876,630,609,258,395,931,29,443,846,263,848,738,452,373,821,337,829,156,985,948,833,275,783,560,512,931,129,988,715,607,194,857,214,774,253,748,87,283,686,840,888,908,886,110,444,587", "685,986,901,25,257,967,819,43,104,826,426,126,137,844,479,931,358,111,447,550,194,34,835,165,919,936,708,860,983,40,271,619,796,694,808,2,666,475,248,862,185,992,735,629,204,827,393,66,303,575,656,333,212,819,532,61,372,703,177,440,947,753,252,809,154,225,600,657,694,560,160,755,861,247,603,723,269,472,932,826,623,788,593,341,74,113,662,357,154,779,978,711,966,163,248,250,169,267,144,755,947,285,243,471,766,346,442,519,429,664,890,856,910,228,915,310,653,116,436,660,816,959,333,936,146,246,167,124,52,121,374,749,341,147,343,826,158,484,702,218,213,103,743,684,167,298,529,59,332,824,253,229,558,483,964,417,705,656,134,641,931,823,275,791,7,639,929,4,794,381,201,911,367,925,179,874,424,583,897,621,66,838,158,694,187,941,860,676,965,620,786,882,196,359,507,807,620,943,850,25,346,649,871,751,387,16,132,957,716,889,725,815,277,378,844,505,990,736,303,78,675,89,39,303,109,231,41,671,856,304,4,671,533,40,299,798,772,87,90,679,786,578,953,887,107,590,9,448,823,453,650,394,82,887,33,145,875,406,997,906,936,683,129,304,428,979,198,401,983,181,288,939,409,342,359,465,376,505,950,527,869,616,406,588,427,820,259,719,831,642,132,333,174,700,188,585,153,36,739,246,94,213,369,714,804,609,317,33,484,331,991,842,978,470,175,320,16,563,170,140,405,928,82,951,803,824,751,111,934,136,227,409,379,529,244,132,721,854,541,736,341,342,663,687,630,913,908,440,873,964,53,777,327,827,145,96,872,324,221,477,247,555,250,294,479,272,463,295,401,33,631,112,433,11,131,167,376,627,802,114,708,0,749,561,681,455,970,836,584,84,272,456,738,40,181,765,899,246,142,49,721,214,313,810,93,854,87,74,760,225,463,320,108,590,685,711,257,256,405,51,566,198,180,568,740,544,683,836,231,914,85,548,623,881,435,314,383,361,625,767,870,207,390,340,332,900,214,514,287,898,42,965,849,65,525,435,647,523,862,238,411,298,472,657,824,508,771,912,681,894,250,249,815,191,935,579,948,948,569,338,265,238,94,97,724,878,444,509,876,994,835,920,293,758,603,361,841,790,432,544,57,734,225,574,44,884,205,171,459,912,287,136,836,857,9,969,941,789,405,609,549,585,706,213,369,9,703,627,800,702,486,399,492,499,985,274,402,744,964,658,487,896,685,970,1000,163,536,53,438,376,587,531,807,915,446,747,721,894,20,157,125,719,20,199,237,620,568,503,235,707,631,71,490,42,965,907,552,328,484,530,653,333,409,260,855,243,37,562,153,277,297,938,340,467,89,718,561,81,469,586,168,773,211,676,285,6,703,523,903,427,251,430,379,469,213,829,540,479,53,793,82,675,338,308,674,92,768,636,50,551,539,802,285,600,697,867,162,462,91,376,258,734,674,432,348,550,154,994,432,759,523,490,206,634,460,790,674,149,13,392,52,409,591,85,113,623,198,278,141,571,271,933,709,399,124,69,137,169,296,999,645,147,16,484,527,259,754,356,775,787,60,989,968,762,530,912,717,126,204,609,230,546,734,645,449,878,922,643,682,660,768,266,531,370,268,75,440,335,498,303,511,77,428,369,568,190,591,863,448,464,771,559,939,290,86,237,775,771,153,571,541,531,907,722,13,511,613,836,787,220,744,583,361,328,928,197,226,550,810,195,316,738,773,416,372,529,805,453,17,286,84,796,989,869,624,359,98,650,651,773,467,762,657,942,628,505,363,986,41,814,608,453,509,968,404,352,594,903,442,953,34,112,545,12,653,475,837,166,216,688,243,452,20,751,609,390,14,941,312,315,165,197,775,553,625,707,248,654,495,101,522,208,996,531,156,812,505,408,832,814,459,52,112,887,460,735,248,606,694,229,644,494,95,173,601,91,581,770,360,53,796,194,847,450,302,601,298,83,503,385,191,67,952,511,589,536,374,427,278,322,994,666,890,751,303,301,245,652,23,434,724,438,447,5,685,654,25,92,785,37,20,823,656,676,180,789,50,450,562,609,729,278,462,196,36,171,193,995,13,279,826,841,422,508,195,526,159,971,704,621,772,454,463,452,695,583,108,84,987,418,312,962,684,781,494,157,449,240,806,972,987,223,286,54,534,255,417,36,360,572,816,88,5,706,576,672,326,345,897,357,290,116,757,713,736,690,590,305,925,468,201,615,139,424,375,851,646,614,87,345,20,580,631,796,237,561,223,935,78,699", "686,829,538,587,935,221,521,765,673,430,487,765,683,217,163,228,670,329,152,841,973,349,523,314,304,712,517,297,291,996,332,490,490,421,496,459,102,451,268,975,70,105,638,286,228,800,182,992,359,927,93,636,334,132,194,797,785,282,524,156,249,864,58,167,39,422,941,537,44,81,964,539,602,427,643,663,812,599,729,619,626,995,428,546,93,852,898,645,273,474,169,946,733,982,393,357,132,459,654,58,407,808,134,879,131,768,493,349,437,26,91,11,109,574,692,361,247,268,232,335,380,416,738,606,754,658,935,28,102,477,755,829,980,367,690,671,970,727,278,631,253,834,896,316,154,21,341,53,420,955,668,660,931,594,890,881,983,578,302,874,502,229,19,563,145,828,461,670,986,855,582,502,192,521,129,471,218,674,603,742,94,442,671,802,523,467,818,617,963,597,763,886,137,515,944,620,340,332,36,225,706,503,235,795,557,278,793,233,583,263,385,138,812,756,990,11,222,26,178,268,258,297,458,960,539,139,459,624,577,671,362,126,311,337,961,970,216,377,258,663,388,315,568,69,970,154,69,644,83,530,888,389,944,846,402,331,105,962,473,102,117,411,194,815,375,87,25,940,980,987,510,917,502,765,139,794,620,652,980,784,794,80,393,550,465,703,222,71,358,538,509,1,913,28,135,77,471,386,306,392,921,186,635,182,959,289,595,497,901,644,316,245,766,127,851,391,74,448,246,143,434,110,206,81,137,338,603,816,137,356,86,431,348,28,455,416,308,114,142,626,159,11,379,287,220,819,890,560,800,15,986,702,81,500,908,336,562,190,87,613,127,652,947,612,47,227,751,928,306,337,542,630,4,209,189,685,954,952,225,207,164,749,0,170,1,423,712,470,17,453,330,924,552,950,349,119,950,169,728,902,586,545,995,344,230,374,228,132,49,730,461,117,728,818,905,84,767,805,562,703,574,55,53,731,657,990,345,335,871,214,229,997,467,980,592,969,902,247,523,811,738,193,411,909,992,930,24,28,913,720,28,354,190,992,819,68,473,509,651,513,469,12,963,782,264,90,280,51,749,778,920,84,409,584,730,841,270,140,349,865,462,42,674,727,494,581,303,52,359,157,453,955,493,738,602,445,117,799,925,248,689,447,978,258,115,211,499,349,139,366,742,151,343,141,183,226,818,458,968,379,455,29,440,274,725,198,22,675,441,626,216,521,25,606,901,907,942,729,583,418,142,800,469,42,945,197,581,848,137,366,656,914,471,397,736,545,257,648,815,942,941,883,436,74,640,113,855,259,523,140,911,415,991,399,421,13,158,598,777,475,977,440,886,459,199,966,46,889,681,987,137,150,692,168,317,195,250,846,619,660,597,603,513,442,121,701,915,792,283,611,846,85,795,642,699,544,871,487,269,186,166,122,710,603,8,326,890,996,941,139,53,659,814,537,93,463,502,157,822,346,596,424,696,459,854,741,823,479,4,585,428,775,212,216,368,492,838,6,191,482,633,439,257,519,91,175,212,606,429,382,539,431,254,96,213,874,708,14,467,94,953,704,333,347,532,899,615,137,473,367,734,814,243,970,112,801,808,830,8,979,25,271,128,941,916,352,396,382,599,459,380,317,774,12,995,694,169,249,926,237,174,363,707,418,840,69,402,242,637,136,413,375,761,454,170,248,714,729,778,278,127,585,760,358,62,887,269,245,580,976,722,232,14,977,919,47,442,687,267,846,472,895,713,912,170,822,7,424,170,218,231,370,405,335,807,106,176,576,365,395,771,824,457,468,680,476,892,721,722,309,762,351,455,965,829,762,231,525,723,211,507,91,608,874,767,720,966,90,572,353,497,173,38,661,677,417,631,294,53,855,46,441,171,336,237,462,806,250,601,800,175,329,308,949,895,4,770,119,805,872,813,998,187,918,680,933,808,958,578,661,623,150,958,83,328,764,679,988,80,434,279,234,561,650,672,326,188,330,715,172,736,792,352,217,78,737,442,583,345,724,898,797,949,129,765,190,69,976,478,822,41,746,746,400,462,527,537,727,358,47,49,763,846,684,896,687,801,270,91,457,638,85,948,105,744,185,599,368,618,962,396,937,546,450,122,202,51,677,296,638,600,338,972,998,404,692,468,966,578,74,775,452,370,316,74,362,245,478,363,251,252,252,664,790,983,576,901,293,509,371,524,672,528,704,488,222,374,30,764,273,577,974,340,606,905,251,134,538,11,85,869,348,450,703,788,573,968,96,459,485,106,336,940,751,368,538,529,23,999,702", "98,680,930,780,245,16,605,652,92,288,26,160,450,152,73,133,409,895,629,386,865,945,826,695,919,345,69,714,16,835,303,12,912,100,215,88,160,130,915,238,584,250,883,772,170,151,551,149,116,770,383,344,808,183,732,272,999,48,580,34,764,159,460,289,321,306,245,165,139,248,728,705,596,192,185,476,912,453,475,957,623,277,207,552,125,66,737,680,865,88,306,940,594,325,135,603,212,166,60,299,928,477,776,291,671,36,573,342,883,617,409,615,343,637,819,812,186,917,251,382,52,994,691,63,97,663,503,948,881,355,486,474,411,37,483,467,840,942,663,660,767,459,194,616,899,509,512,86,548,376,691,968,103,932,565,448,161,857,401,237,791,25,192,173,166,687,201,998,99,900,883,595,219,7,728,975,439,584,392,725,357,272,143,551,19,508,438,762,604,369,263,66,880,962,869,769,9,951,42,184,44,846,484,3,785,722,675,597,594,748,257,975,970,69,376,607,785,650,559,649,480,158,292,367,664,854,56,175,218,647,451,532,3,250,873,38,668,564,874,751,451,376,742,651,948,195,680,604,436,216,41,335,292,431,99,324,923,27,276,795,155,59,566,374,50,324,961,183,696,227,746,388,727,157,171,369,388,262,954,202,62,261,105,110,341,715,960,476,17,79,143,73,948,999,375,282,468,225,618,937,517,33,892,395,114,217,469,664,924,362,506,88,859,185,368,742,918,635,481,107,689,108,20,536,520,349,85,879,535,237,960,5,754,639,618,196,927,333,315,790,698,471,54,916,427,9,488,969,949,180,153,148,492,380,626,141,582,576,266,694,994,402,279,203,231,857,339,663,566,297,410,224,642,199,703,806,315,879,667,395,420,561,170,0,695,201,204,129,339,659,329,857,417,996,830,713,219,31,939,853,348,941,93,782,303,293,333,79,921,41,228,486,78,673,643,366,308,682,497,574,954,788,617,532,273,701,269,900,860,871,340,128,20,347,22,137,419,412,919,493,46,786,263,21,313,352,38,23,638,562,565,748,685,310,952,932,869,251,352,475,918,739,213,868,523,18,997,920,949,150,333,236,84,41,952,479,630,266,607,638,89,297,367,268,815,928,655,342,809,338,620,743,888,82,407,880,525,403,396,958,997,792,850,881,299,905,331,969,970,487,197,494,367,23,248,562,105,61,617,308,745,218,212,514,8,763,196,438,280,49,411,782,829,848,727,839,976,16,277,824,793,685,578,772,647,953,45,25,113,3,533,898,7,902,909,392,488,399,640,249,443,117,601,505,126,653,784,169,613,229,1000,36,724,56,446,725,258,623,445,189,591,798,118,418,56,781,151,411,59,103,241,701,389,802,210,173,777,48,606,146,3,731,798,94,456,78,288,22,254,539,649,92,470,828,29,454,647,558,942,661,401,907,60,34,372,903,299,495,514,472,808,729,313,208,913,191,577,736,953,634,494,285,119,422,455,317,622,935,930,509,267,638,931,780,880,982,448,91,994,737,153,995,158,507,2,521,904,887,977,201,671,844,484,806,942,753,354,304,95,926,647,52,330,824,509,928,886,932,704,400,550,54,716,261,45,541,486,260,523,855,482,839,158,834,968,851,413,955,401,412,173,791,189,842,657,17,844,341,762,595,127,197,351,425,602,182,277,419,846,805,663,509,974,164,602,91,424,656,168,954,920,486,235,876,221,57,226,465,745,818,64,237,613,493,163,164,449,883,136,293,431,821,980,158,853,281,98,387,953,539,942,29,868,188,785,980,944,531,490,650,246,758,19,791,795,663,220,194,886,563,103,875,616,707,506,479,871,696,246,460,740,564,811,674,957,515,140,381,778,545,264,876,223,170,785,457,441,940,233,314,563,626,712,56,867,464,411,366,914,682,955,863,72,640,289,404,144,591,578,771,556,2,98,254,95,740,34,92,475,667,437,338,901,470,575,527,815,203,948,85,669,6,619,826,770,44,211,345,368,67,21,384,114,994,889,739,848,419,460,571,148,743,284,55,692,203,402,374,907,603,92,715,371,483,777,678,50,657,571,433,760,627,530,101,15,682,46,845,554,534,703,456,731,135,816,159,105,341,263,62,546,946,38,993,626,559,289,183,78,658,470,360,414,37,237,816,80,570,895,636,894,676,647,783,552,378,210,739,278,888,486,355,901,17,925,680,235,504,699,812,918,508,895,433,542,724,359,820,599,711,909,160,799,192,632,971,158,74,424,551,815,624,441,639,645,216,791,282,546,586,825,64,260,604,133,650,70,726,256,220", "902,587,299,924,552,131,886,81,234,898,374,710,148,464,322,632,287,621,771,440,313,265,582,13,373,763,224,799,776,153,320,545,744,196,446,943,8,314,37,397,812,78,917,740,611,226,57,237,657,619,121,782,798,550,101,519,536,846,441,650,4,412,996,383,111,106,376,809,585,438,687,691,664,820,105,944,601,236,89,787,265,933,887,452,435,358,577,108,76,65,873,458,204,911,536,738,423,993,805,380,551,466,387,487,899,957,857,75,719,140,287,86,618,798,588,925,326,900,35,124,60,630,424,386,641,602,953,601,606,635,731,297,782,658,927,117,336,669,222,142,485,973,793,697,886,233,286,423,217,840,851,70,300,388,826,381,875,405,99,171,567,709,762,796,502,766,281,466,40,157,865,79,300,603,306,964,422,602,115,51,319,884,601,616,269,950,209,878,718,528,723,144,23,99,204,998,54,808,409,956,727,417,243,517,107,490,916,856,531,281,659,350,626,570,884,728,137,142,19,331,633,149,176,583,753,975,855,773,280,599,225,635,845,860,561,592,319,512,355,155,910,455,899,551,271,607,533,312,764,725,863,496,711,472,466,102,980,877,809,848,826,970,262,325,906,186,460,962,447,857,680,390,989,869,435,886,415,288,683,183,895,389,880,773,260,748,946,694,577,800,771,700,905,140,956,872,341,140,127,847,570,440,419,544,753,498,837,404,703,110,271,286,78,686,470,563,862,74,519,111,609,143,594,364,139,869,728,667,373,779,984,537,735,137,313,36,259,524,137,984,23,553,635,404,352,218,335,344,369,427,207,63,81,437,869,915,35,307,657,20,231,628,743,17,736,112,685,24,526,894,55,382,430,326,18,36,273,947,552,95,409,681,1,695,0,490,706,683,184,435,357,267,60,471,612,324,612,627,842,459,594,610,381,362,20,672,547,573,642,473,31,572,432,474,260,827,54,398,487,766,437,836,819,215,599,964,90,685,750,833,698,850,302,831,168,668,974,198,363,538,694,225,320,36,698,500,614,972,115,659,545,127,664,653,595,504,829,221,378,82,956,202,241,249,858,979,237,726,90,497,755,351,358,902,329,992,813,486,432,784,162,899,493,432,842,566,872,347,630,126,375,627,803,465,898,405,352,699,254,838,663,413,906,959,922,821,646,566,79,241,909,531,268,941,863,772,653,243,901,609,134,97,61,906,681,426,344,97,158,43,775,311,397,801,561,757,795,413,719,444,484,947,59,455,405,309,830,347,909,259,994,235,526,358,97,400,40,711,789,485,540,315,148,826,682,748,47,418,679,619,911,687,524,64,406,903,896,868,810,574,971,745,920,162,226,495,18,228,695,423,337,779,102,816,519,610,29,835,503,200,743,51,878,892,112,166,355,465,174,413,106,671,236,874,64,736,322,661,620,612,98,394,611,244,686,240,47,895,859,971,342,824,378,865,893,219,725,253,845,256,385,953,590,46,629,25,852,810,30,116,125,83,792,54,91,957,702,813,447,208,283,851,643,262,200,551,963,861,293,475,262,208,741,644,543,709,138,513,967,372,437,244,280,595,787,550,507,83,570,545,960,862,499,391,20,277,131,396,254,116,254,616,313,838,946,101,403,474,863,714,14,428,391,26,354,367,267,639,553,95,337,872,308,445,799,983,795,935,591,541,58,693,927,232,684,159,125,252,82,511,990,704,633,682,350,919,471,797,592,605,692,111,222,730,975,864,766,199,959,395,193,197,565,739,824,441,195,682,286,142,348,915,396,478,831,263,519,204,451,530,28,865,817,869,400,757,507,818,406,787,460,320,44,466,184,465,274,405,936,804,850,833,263,681,499,56,912,237,347,392,933,795,392,925,349,682,5,446,629,832,755,845,384,157,472,126,343,382,214,763,973,841,875,89,767,164,3,217,531,801,329,409,813,161,729,827,186,304,387,940,771,838,345,977,972,130,556,845,208,478,268,684,188,154,430,103,789,499,313,967,976,487,80,968,888,970,499,363,27,605,238,648,735,748,435,519,917,137,691,833,832,334,964,621,768,429,347,544,30,115,88,266,851,156,232,405,774,686,871,881,408,666,156,494,448,582,378,755,40,157,75,566,897,544,918,135,698,941,799,652,602,279,545,656,78,315,342,814,574,680,914,394,333,737,850,927,538,182,400,915,667,340,379,798,110,517,792,517,936,609,557,651,506,779,27,157,98,686,278,176,315,92,18,492,457,981,719,727,775,576,851,157,756,49,369,218,442,423,816,927,683,140,323,859,853,817,302,393,696,394", "725,336,181,897,766,72,353,518,454,467,839,299,161,967,2,785,352,944,586,750,270,95,816,785,326,234,193,871,805,746,323,165,391,561,204,291,833,923,592,47,282,375,144,899,683,335,125,16,231,671,318,119,723,843,385,38,702,627,682,205,835,322,697,68,227,600,663,7,217,172,948,328,295,272,295,858,417,231,568,984,23,43,292,60,358,831,22,47,837,385,304,241,714,257,473,812,300,648,673,580,827,93,74,767,776,279,6,207,51,590,413,761,728,662,75,855,896,690,654,408,566,112,821,49,751,83,470,158,344,540,213,320,368,207,225,609,182,977,298,442,447,865,314,182,721,148,929,425,137,740,53,530,586,297,946,755,922,536,303,786,919,768,862,411,980,760,936,911,30,725,736,392,163,530,956,171,466,715,73,627,261,322,668,477,817,660,899,390,814,326,358,356,827,760,84,385,933,831,330,372,477,540,318,988,869,823,230,444,298,192,640,474,440,231,565,506,676,338,943,442,546,143,398,373,493,400,658,818,805,239,529,590,963,639,745,776,343,666,6,118,265,105,685,696,371,779,417,470,452,292,49,595,429,248,76,189,965,601,275,240,42,925,643,575,963,554,771,417,882,743,36,820,6,985,806,286,210,224,669,25,730,972,199,558,502,224,474,726,75,596,897,342,975,453,184,270,437,672,185,79,894,301,754,386,888,743,645,105,458,69,465,825,133,29,462,409,87,726,613,216,541,694,296,727,97,273,322,280,166,693,396,734,434,9,632,358,216,742,852,908,774,983,276,298,745,78,479,778,911,707,876,498,706,937,690,190,822,165,540,442,676,151,499,28,277,459,915,364,996,200,171,558,817,888,392,695,399,298,577,82,99,455,423,201,490,0,737,551,584,320,98,120,322,575,858,700,161,817,754,255,483,705,668,555,962,370,587,851,263,294,276,685,928,670,56,239,922,410,942,833,186,589,544,39,131,184,963,341,204,426,251,748,842,592,433,515,504,475,946,290,459,195,324,165,592,534,277,890,443,601,748,890,411,602,489,152,5,799,739,87,279,973,844,358,129,697,825,117,124,361,950,883,529,240,577,775,681,81,61,39,305,796,113,641,236,409,673,175,250,597,596,592,942,259,522,5,798,199,945,831,144,39,485,85,227,558,684,609,585,913,971,689,103,661,89,162,410,205,792,511,608,564,536,130,73,762,18,955,354,629,440,273,62,754,816,304,175,360,734,733,256,158,19,244,193,812,754,757,515,78,713,25,557,643,531,206,638,400,677,159,101,929,688,923,268,802,245,19,675,533,619,665,270,146,508,551,24,798,510,626,677,173,291,654,623,250,840,863,185,70,777,20,61,542,917,97,257,101,995,37,507,389,71,985,254,396,88,180,625,220,312,958,358,607,750,769,352,780,688,31,700,326,348,212,195,853,338,861,727,966,823,864,780,951,334,266,204,307,151,921,465,156,390,8,912,937,551,45,362,156,722,797,430,212,957,420,136,660,556,36,552,346,936,527,953,441,654,399,230,988,333,63,528,241,989,824,288,784,100,34,624,74,471,559,450,684,185,138,563,613,649,596,933,209,499,641,60,170,489,567,111,253,615,286,872,161,275,488,890,358,739,367,673,823,301,759,553,226,821,968,922,550,429,936,889,243,663,65,557,518,635,473,752,778,89,236,941,237,305,4,410,361,137,250,456,227,81,23,194,29,266,810,607,217,878,317,497,335,778,60,241,679,543,9,705,230,934,803,943,139,774,155,893,703,273,521,195,456,449,483,694,737,453,351,831,616,486,769,166,731,498,495,192,239,471,17,287,817,561,524,423,415,433,454,398,77,978,166,239,62,883,72,115,682,800,934,854,173,758,519,889,320,385,512,453,520,186,373,264,834,109,868,775,367,216,871,251,827,469,628,369,501,192,749,441,32,262,879,66,991,896,23,257,943,353,898,5,426,188,452,136,14,914,43,256,330,634,287,803,654,94,533,128,156,348,991,242,357,521,732,608,481,642,670,648,694,992,364,177,79,894,872,670,838,841,406,595,555,878,458,528,376,824,636,811,108,914,966,373,14,280,436,58,7,618,275,534,935,380,517,992,492,139,910,631,809,970,861,478,6,357,442,685,796,416,824,967,249,859,235,389,781,839,790,450,839,359,198,324,874,494,893,313,885,183,73,602,308,497,195,798,398,202,772,252,900,400,89,269,117,202,689,474,516,168,569,927,36,498,364,688,605,600,199,642,729,212,309,427,270,38,379,42,671,493,210,86,850,482,838", "707,182,886,532,465,635,937,314,653,637,319,41,608,55,176,648,482,125,353,517,570,235,981,294,845,345,625,621,49,713,813,42,248,36,532,774,792,657,510,422,510,811,515,676,510,884,933,183,618,733,980,80,456,888,425,509,871,141,165,982,48,543,329,236,67,603,186,599,750,787,205,670,555,771,870,611,787,801,599,413,318,942,401,63,456,600,378,534,689,387,96,131,187,198,117,198,307,109,335,822,849,157,419,252,84,406,536,136,660,770,190,126,623,218,917,126,45,217,340,889,765,657,537,50,199,120,166,711,901,326,511,339,862,230,757,777,547,746,997,161,975,524,708,305,986,997,592,820,955,489,174,184,837,892,967,246,492,344,189,920,173,266,763,17,485,691,967,976,121,690,729,139,643,204,604,776,784,260,824,583,140,404,199,305,556,254,999,670,290,798,210,334,76,358,377,725,178,946,915,59,631,431,496,427,377,485,724,400,118,152,149,158,587,123,854,585,260,552,668,733,692,227,780,888,278,501,130,434,882,693,771,560,978,768,312,724,220,669,847,159,562,699,783,303,178,91,16,909,897,545,332,467,913,43,470,218,174,956,818,338,595,691,860,278,191,194,418,319,204,884,728,977,978,686,338,847,808,504,874,516,679,144,761,991,779,868,874,249,207,494,404,851,456,491,172,253,646,188,365,858,882,581,361,979,798,536,474,699,806,727,712,193,394,49,803,726,505,301,719,14,928,278,428,854,454,607,58,643,52,371,689,184,440,510,641,138,825,850,234,590,897,543,73,255,225,942,129,862,396,594,875,810,19,436,891,525,26,205,765,693,640,655,99,131,369,811,214,366,13,511,135,235,567,865,579,319,241,509,913,47,253,970,712,204,706,737,0,960,852,701,593,538,927,491,27,396,951,111,406,870,806,929,937,16,161,151,82,339,671,657,350,617,243,910,863,741,129,293,395,33,460,291,387,620,226,350,284,605,534,617,656,422,419,467,830,993,866,39,321,727,130,725,776,140,8,654,828,67,650,42,936,96,570,976,461,926,18,376,303,469,130,166,17,45,883,719,711,525,317,928,203,641,855,498,957,578,269,690,113,858,306,707,301,281,516,690,910,320,424,791,452,290,910,931,572,327,785,689,581,557,554,779,366,600,692,760,916,587,733,113,737,123,894,977,442,389,993,249,457,557,29,800,416,612,571,467,50,269,309,686,31,573,558,918,185,351,43,140,846,333,67,656,38,161,924,407,535,955,185,154,408,855,853,836,278,490,296,760,9,419,809,786,439,303,101,117,449,16,310,841,678,858,47,645,925,620,812,565,454,64,659,122,142,495,597,963,483,518,462,880,222,201,671,502,510,237,602,665,392,309,621,199,647,800,996,772,594,56,675,611,641,284,197,754,203,827,354,64,334,424,273,417,429,327,330,540,750,819,731,232,831,970,192,445,551,564,951,861,347,238,227,487,510,989,313,258,414,9,181,296,364,641,950,566,73,967,28,940,124,935,745,939,895,34,421,80,228,414,293,112,113,748,2,284,709,998,677,470,430,866,814,855,519,666,365,568,964,400,158,24,314,906,581,220,711,111,401,928,661,972,775,618,504,534,105,966,617,483,144,492,787,266,557,11,978,221,551,666,773,454,889,363,706,997,617,813,921,677,726,214,121,865,110,675,94,672,824,122,791,289,253,902,400,490,109,170,123,490,298,993,197,139,445,22,586,982,678,77,847,390,614,118,30,858,42,902,24,980,220,398,867,728,402,926,391,88,912,106,2,528,874,981,865,949,618,634,934,228,500,4,413,680,474,537,771,769,732,732,231,681,167,265,487,685,508,867,687,352,564,53,241,956,624,786,596,935,530,85,17,942,736,353,11,467,433,692,954,473,259,258,949,92,993,203,609,943,109,779,635,95,697,311,658,853,899,928,91,407,851,451,505,613,649,152,436,392,285,81,181,859,201,728,515,907,270,254,989,324,6,333,749,660,94,311,568,616,275,546,18,700,672,938,28,739,60,182,217,644,947,817,948,893,832,959,49,789,296,48,247,146,847,91,773,465,664,916,56,72,282,292,716,180,352,808,623,753,563,727,798,731,583,753,858,888,158,982,859,683,768,308,595,484,457,37,883,561,636,898,501,693,514,659,707,605,572,800,928,675,83,28,755,270,63,852,223,498,9,420,400,586,576,743,514,569,816,31,927,709,938,837,508,731,738,978,827,549,844,313,218,700,498,947,849,87,478,397,853,58,383,760,597,666,839,844,773,7,356,342,607,526", "758,909,162,749,922,394,657,145,442,462,795,656,698,64,939,519,85,324,309,242,671,216,518,734,422,798,951,451,715,705,550,174,535,928,127,639,834,839,201,735,389,706,948,382,364,395,753,475,343,304,832,491,114,928,564,110,560,327,378,338,563,812,250,96,366,199,320,872,179,27,208,720,729,396,68,169,436,921,539,977,797,862,88,29,815,392,848,678,796,696,81,148,993,537,78,735,623,442,545,656,596,634,180,950,450,857,958,802,915,266,925,920,87,277,611,840,386,360,378,265,626,807,263,238,675,367,316,382,741,340,522,59,979,108,479,509,380,756,51,575,910,604,803,535,206,56,745,469,605,296,66,845,138,127,328,598,783,110,428,263,309,700,945,152,360,135,620,777,922,313,638,933,379,467,93,929,417,540,967,416,498,894,619,537,716,929,324,451,934,385,92,806,305,647,782,493,90,589,843,158,453,237,727,300,205,830,288,322,55,203,524,166,756,596,726,420,808,103,932,856,580,419,321,560,613,210,998,354,299,851,665,663,109,511,53,478,738,591,177,637,206,645,260,664,451,993,192,393,770,534,484,351,887,142,981,679,208,807,677,845,248,738,346,29,311,13,782,420,344,719,982,455,50,694,282,835,345,906,443,484,75,452,654,487,57,882,860,319,612,41,586,348,609,248,947,18,179,641,502,726,887,422,965,808,618,986,683,683,16,611,356,602,726,833,684,507,812,205,283,493,647,917,583,203,533,78,649,980,457,852,744,96,853,374,136,676,741,449,120,629,595,726,878,946,151,468,979,566,161,710,751,215,477,249,80,73,684,355,656,348,235,88,249,134,18,395,600,41,168,204,311,747,978,985,107,747,559,135,497,332,631,836,470,129,683,551,960,0,915,359,895,973,553,126,20,82,966,929,129,745,922,585,841,437,823,430,215,272,501,433,789,222,403,471,706,314,251,67,589,852,955,461,630,24,138,282,278,802,832,873,196,932,235,904,115,528,924,807,517,244,181,484,965,123,193,420,252,128,254,87,329,29,268,434,137,214,965,77,686,357,74,414,692,143,246,252,838,191,401,238,623,884,600,75,612,798,660,413,631,208,147,667,366,935,255,596,92,482,309,648,22,11,344,880,381,281,891,501,385,208,699,119,904,873,976,825,640,276,847,144,782,247,666,535,444,41,410,503,140,929,626,73,282,528,64,520,2,240,750,496,363,860,412,564,749,974,479,538,618,495,289,285,692,792,190,900,892,728,693,177,355,810,245,282,294,952,794,222,68,531,353,843,150,104,972,958,695,529,346,681,272,936,7,964,242,72,865,443,194,610,936,407,182,223,309,735,442,610,605,165,608,399,949,81,974,331,530,106,716,387,526,685,609,926,371,262,80,671,836,343,214,231,502,642,328,97,380,667,210,311,476,764,579,279,617,224,365,198,291,313,322,65,352,675,193,928,664,804,239,711,755,183,247,659,696,919,663,949,908,131,715,775,514,448,7,578,876,59,760,751,864,894,908,40,305,417,884,244,498,998,404,574,401,619,195,231,750,814,124,914,566,717,322,624,956,855,588,5,80,953,689,471,312,86,923,597,48,525,281,484,257,613,358,112,494,595,11,158,813,889,325,615,37,937,711,850,323,233,163,816,285,106,498,138,819,527,923,113,270,233,573,393,419,461,811,308,802,25,497,804,835,333,819,263,105,2,362,626,336,72,732,783,493,423,440,881,1,843,423,692,916,575,770,110,265,117,572,776,278,91,37,140,899,878,371,638,472,187,688,49,546,972,272,101,429,115,394,613,743,499,276,11,933,146,978,196,204,549,437,460,557,862,517,669,145,641,524,818,932,949,91,16,601,223,957,76,535,812,721,808,624,159,260,634,934,136,826,79,19,683,510,450,845,154,22,680,218,759,521,707,435,92,539,264,892,337,35,892,142,382,188,786,26,910,881,549,199,645,368,822,974,652,251,395,783,139,226,476,199,266,490,740,37,456,641,963,28,36,121,904,731,344,931,636,475,935,15,327,660,894,554,386,384,695,702,821,302,17,529,732,362,38,102,588,322,964,886,332,725,200,131,656,268,943,182,657,372,914,132,997,171,740,968,658,363,389,434,104,746,604,30,290,744,305,658,198,976,446,113,403,503,83,407,131,261,354,662,428,277,782,165,333,782,328,83,255,477,408,75,654,575,624,83,228,550,63,904,177,975,101,195,391,10,746,6,556,508,743,146,856,356,874,827,332,677,369,674,189,598,575,581,794,202,834,589,948,749,893,86,560", "194,196,473,460,650,389,340,923,939,179,63,592,61,537,292,330,328,370,421,716,352,447,548,579,864,194,54,937,639,855,234,67,864,462,642,914,503,580,432,51,663,200,643,495,637,86,268,41,645,623,441,360,153,237,511,845,13,833,882,947,574,990,906,552,462,808,318,453,799,903,745,460,258,246,600,871,7,159,855,459,61,754,258,540,985,793,110,531,74,191,463,164,755,416,361,759,287,5,448,917,430,619,204,856,183,57,902,813,795,320,59,184,941,355,819,43,439,37,614,123,405,894,414,609,491,324,510,853,297,865,913,467,104,976,682,341,240,149,608,27,243,795,558,287,47,598,968,494,697,807,719,473,109,915,585,523,458,883,583,256,531,590,658,878,469,135,693,498,276,836,930,730,774,994,42,636,454,576,922,97,3,845,295,681,640,882,799,859,656,258,747,560,468,913,898,207,117,768,317,273,558,347,346,612,392,126,560,274,288,848,799,345,775,61,377,761,526,123,674,325,757,80,922,505,894,30,373,284,730,428,438,157,344,779,937,78,19,228,241,818,169,390,567,535,238,94,666,459,819,263,243,154,55,921,798,239,301,546,911,952,271,482,595,319,124,492,876,58,314,724,723,934,833,345,2,41,344,124,599,487,500,17,520,862,316,294,719,1,838,47,399,712,47,80,583,815,208,227,361,529,427,506,261,466,2,401,445,783,616,906,197,477,838,948,186,835,582,554,945,549,562,333,686,92,837,823,365,289,779,620,115,981,886,599,280,875,796,829,404,739,682,952,215,580,504,858,208,346,737,118,101,884,702,508,761,404,673,446,910,802,209,228,242,775,806,625,457,829,520,502,865,805,688,468,913,687,830,10,564,462,750,584,17,339,184,584,852,915,0,965,819,308,25,120,838,40,182,317,258,686,767,103,897,400,229,291,899,630,40,133,590,546,459,405,735,574,645,241,507,873,50,449,390,54,307,701,763,251,931,447,125,512,403,646,288,886,902,208,370,944,60,750,42,723,370,835,635,123,144,983,659,743,132,179,636,659,789,148,833,557,968,77,124,441,766,784,276,74,320,655,436,113,785,2,169,490,641,160,383,867,924,618,333,804,933,165,346,274,741,953,177,240,949,167,62,878,377,974,89,818,677,256,860,354,772,155,740,849,244,565,389,473,841,870,112,570,129,537,830,862,669,397,335,374,923,155,350,853,432,249,482,126,678,597,816,758,687,851,815,397,760,943,8,110,575,752,338,902,547,346,808,853,428,343,74,460,275,466,53,333,377,25,710,14,769,538,816,166,503,145,90,276,735,517,999,137,333,743,108,684,568,779,104,425,219,561,462,719,483,784,274,646,950,163,22,490,502,35,782,787,844,949,390,64,894,460,827,771,298,11,741,380,262,624,171,905,669,341,411,797,208,891,583,109,297,483,11,880,705,728,836,336,87,832,248,229,827,490,527,539,838,203,20,603,739,864,863,135,551,77,608,402,538,249,954,249,235,57,68,610,31,847,791,615,448,847,874,415,117,321,521,596,782,527,586,197,146,138,531,821,689,636,856,389,560,757,855,481,227,386,174,334,279,283,123,737,668,46,506,896,460,281,442,627,494,680,325,597,637,46,273,673,551,200,307,57,401,763,170,609,506,881,242,150,690,399,380,418,802,796,542,235,420,171,539,4,442,163,105,919,79,252,855,199,289,847,231,986,797,713,437,755,363,442,933,223,62,102,769,909,379,688,718,838,683,818,574,537,40,446,959,14,89,229,856,342,564,582,235,112,100,787,750,17,251,28,412,75,794,119,559,868,844,131,720,343,598,424,902,567,352,867,175,893,973,560,736,902,317,786,176,671,812,569,152,12,331,223,103,914,65,778,727,20,473,97,628,403,193,192,796,701,378,29,769,46,518,548,53,402,374,810,961,660,664,689,189,106,152,231,542,783,222,857,794,728,420,570,295,27,193,800,646,112,631,584,523,442,162,491,267,863,53,233,176,747,990,8,412,388,80,984,41,699,685,935,620,93,903,381,69,989,219,405,600,228,812,443,650,503,984,368,845,144,822,488,567,2,355,405,144,157,81,866,689,66,166,99,385,107,498,224,994,232,296,924,480,125,326,172,206,935,765,412,354,951,626,563,342,561,328,399,704,13,770,390,172,899,406,821,590,663,481,449,319,420,335,717,385,398,254,224,871,375,581,926,527,530,854,646,942,151,465,942,413,297,980,129,75,307,677,711,331,470,856,165,633,879,571,7,784,4,440,688,220,379,943,148,351,286", "461,614,446,8,824,609,105,466,476,299,663,432,758,840,526,413,705,208,846,532,651,777,906,908,699,447,204,556,965,624,961,232,612,345,182,785,912,286,790,489,46,69,730,300,890,101,456,974,923,340,435,651,966,596,413,960,994,951,517,679,611,336,632,701,212,329,886,760,934,332,374,626,673,275,395,782,53,741,734,390,380,634,923,694,589,800,766,173,869,737,104,521,340,12,78,838,386,619,46,885,590,44,526,730,951,517,808,826,436,90,337,835,509,935,304,299,566,307,333,815,135,945,556,577,277,686,304,802,778,809,118,260,685,725,988,302,345,331,656,480,684,993,771,437,987,542,287,342,968,513,611,78,553,584,437,980,711,517,135,222,992,560,499,580,509,250,62,958,833,937,791,627,370,509,929,319,273,131,852,575,655,267,533,790,834,275,407,155,25,182,21,317,646,956,75,648,615,71,778,732,643,434,622,634,806,516,960,968,382,791,101,588,135,119,885,658,244,244,934,443,212,933,804,382,80,279,882,939,380,758,406,749,631,862,406,302,841,652,709,685,330,654,945,811,375,957,679,11,567,203,274,204,485,635,556,638,62,57,871,412,333,542,181,692,190,436,340,584,68,557,27,133,774,587,700,69,732,645,906,119,246,265,894,889,845,401,644,216,534,586,367,781,624,82,16,402,272,464,697,930,748,448,971,729,503,219,755,18,263,161,477,371,800,839,578,698,380,141,720,24,122,7,224,702,755,607,798,339,904,389,415,173,325,380,641,317,95,827,607,673,365,142,305,965,84,163,487,493,270,462,326,791,715,356,944,472,529,331,134,645,768,747,679,489,155,164,801,311,103,697,799,821,176,88,951,775,665,75,945,367,630,84,453,659,435,320,701,359,965,0,678,182,459,606,97,970,987,779,657,202,554,331,912,664,488,604,871,878,187,732,27,719,99,221,481,137,790,497,534,448,716,871,152,296,651,685,884,764,772,893,486,927,665,956,149,285,394,166,70,734,791,255,836,737,787,803,667,140,763,818,698,72,354,322,370,471,469,845,564,506,536,118,464,896,251,386,644,48,289,211,528,273,999,344,500,953,229,268,298,832,521,561,685,595,496,80,869,875,707,202,887,309,997,29,815,231,588,765,87,703,708,110,254,491,68,385,262,549,82,854,431,91,331,283,809,951,917,611,518,156,614,458,883,31,195,312,5,579,38,4,967,607,27,320,753,25,869,332,591,896,749,16,237,305,808,691,38,316,210,912,522,974,121,632,66,964,728,575,699,720,952,800,607,105,206,470,380,26,781,309,315,695,55,632,895,190,353,445,416,541,45,51,221,71,873,839,804,752,216,740,572,678,414,878,299,64,145,204,675,39,392,188,268,750,107,89,77,146,149,710,174,317,785,727,525,331,282,788,693,761,706,848,949,208,971,705,150,47,229,986,124,651,441,542,278,845,902,600,531,1000,284,751,381,111,596,576,49,197,807,143,9,209,226,845,151,241,490,927,474,483,13,777,192,253,727,29,949,159,964,577,583,130,153,988,925,322,471,152,920,333,782,607,364,321,28,372,511,76,928,651,108,687,146,90,230,712,569,599,527,615,411,711,190,510,608,54,886,393,158,617,48,822,18,47,34,713,279,357,751,151,980,164,975,470,414,669,591,820,412,992,510,891,984,466,248,711,970,123,80,55,483,498,425,263,229,829,136,412,264,418,566,245,971,663,836,772,707,619,802,193,703,97,218,997,178,265,755,365,696,712,220,757,305,698,94,819,611,278,321,99,262,380,194,722,176,358,58,709,414,60,900,63,340,294,270,475,110,707,914,520,971,236,898,647,379,209,37,279,733,846,98,896,8,765,611,655,63,36,874,822,588,188,586,883,776,818,263,531,414,491,237,89,364,11,914,574,143,661,618,384,357,311,476,821,720,676,594,594,948,885,950,45,254,223,264,52,503,234,376,858,353,861,476,525,378,75,301,64,140,504,476,713,159,671,463,373,580,553,489,311,726,4,496,341,986,571,33,118,983,890,426,792,418,687,724,478,722,17,391,471,990,247,899,627,453,409,62,636,974,152,477,745,327,297,536,517,143,155,662,144,426,589,215,630,48,441,196,515,546,35,425,749,499,180,821,333,328,889,734,964,613,153,264,173,827,674,782,341,935,152,428,813,30,821,170,813,638,958,21,755,387,479,118,445,607,243,925,56,644,430,929,448,551,102,476,423,240,351,371,459,802,200,968,509,804,254,889,722,951,408,285,211,886,444,803,567,940,399,145,325", "411,118,210,857,706,382,332,908,470,471,21,82,209,224,890,286,581,149,380,605,148,709,822,461,946,194,476,761,310,34,331,249,358,929,721,659,35,516,629,170,289,968,535,870,607,871,126,886,469,282,236,183,788,59,689,858,995,640,961,348,951,822,606,710,29,961,723,354,886,594,102,648,923,109,187,687,353,627,650,305,798,294,475,273,390,834,261,76,16,997,168,980,989,815,504,740,632,214,471,974,439,87,941,679,980,549,578,972,47,15,416,504,525,894,517,301,743,665,390,475,211,76,860,521,515,145,549,259,555,530,966,328,615,775,63,122,516,613,862,54,351,770,765,789,798,838,723,206,999,973,217,559,594,589,961,894,486,482,681,759,466,944,262,833,74,828,171,791,638,621,109,780,107,566,443,246,321,436,407,810,44,592,757,354,952,38,515,654,755,817,405,355,898,178,385,735,491,153,591,103,781,209,586,842,973,951,788,325,293,142,448,497,273,906,856,772,247,420,353,458,531,610,225,177,104,259,52,629,975,478,759,838,700,52,595,251,375,156,767,312,781,463,296,727,573,579,710,634,792,7,948,476,962,936,948,942,54,879,932,102,305,92,633,282,520,90,842,214,495,88,540,983,16,482,925,386,270,89,60,46,457,151,731,637,606,283,34,172,935,153,36,408,655,242,290,945,735,484,731,102,735,989,542,160,262,510,123,926,788,471,166,180,19,888,433,596,59,462,571,840,658,798,792,653,957,553,570,26,776,799,389,130,569,32,573,802,226,739,866,140,621,417,28,600,812,707,266,341,540,566,860,574,167,264,938,280,623,456,514,453,813,266,870,16,899,332,443,79,637,295,278,803,253,704,911,366,817,416,318,210,177,272,330,329,357,98,593,895,819,678,0,910,411,381,776,248,302,108,39,398,61,87,117,25,786,773,225,169,366,562,237,873,26,814,782,462,309,542,207,51,967,432,646,571,268,96,818,79,80,26,54,888,276,943,841,7,383,16,771,55,881,869,257,422,495,421,537,491,955,239,606,750,10,385,512,382,262,293,266,885,593,434,242,707,968,595,950,397,592,875,84,578,444,760,865,166,458,796,25,946,589,489,12,260,560,883,533,157,288,540,390,558,582,181,306,925,390,857,504,684,613,398,591,536,331,449,292,76,112,74,262,8,74,726,931,186,941,67,450,720,226,370,851,736,389,289,240,268,135,526,965,745,801,531,710,65,921,245,200,261,995,517,691,1000,684,439,222,70,247,388,205,242,231,787,830,97,444,561,814,810,689,224,851,728,772,310,602,73,806,444,980,518,402,793,861,921,115,471,942,178,3,805,322,735,451,357,771,260,93,271,971,470,332,836,724,617,529,103,165,53,856,26,347,81,111,265,482,197,707,54,878,417,751,727,588,787,309,339,845,606,775,340,126,789,833,708,481,561,38,640,372,477,400,627,385,186,890,623,563,490,671,509,504,595,54,15,541,329,567,617,942,609,475,163,965,486,895,405,999,78,411,467,971,207,914,279,767,697,784,942,350,435,635,752,978,605,755,162,148,938,831,853,222,758,30,310,715,999,823,473,370,18,72,175,429,329,298,377,54,609,940,330,389,818,586,153,20,369,421,60,454,353,589,59,208,600,967,41,402,898,277,823,417,257,695,542,622,9,808,496,995,853,818,6,891,582,69,794,672,452,264,825,140,636,391,523,358,498,853,299,814,278,923,401,884,196,485,17,489,399,996,772,943,683,581,367,760,370,291,856,142,775,574,41,727,302,5,498,611,566,900,794,755,149,115,920,277,395,788,500,217,719,705,265,195,97,721,420,501,905,28,131,239,347,710,276,521,837,296,302,715,185,448,939,548,910,860,478,190,717,957,371,227,413,512,534,637,326,358,721,598,6,581,512,945,967,689,18,609,309,16,657,607,83,95,295,273,812,621,420,478,97,40,619,485,743,926,588,70,63,979,7,197,986,51,359,132,510,220,269,16,322,541,176,398,368,513,355,101,647,894,339,680,692,307,902,987,658,262,288,393,649,696,51,562,708,169,376,739,54,397,586,310,746,323,400,413,901,785,554,240,529,320,813,657,902,554,897,181,898,457,407,915,243,674,289,293,158,223,297,799,906,81,451,181,693,610,291,670,306,498,972,845,706,53,599,929,75,688,603,88,20,788,515,454,309,704,985,40,318,596,435,780,303,464,597,198,909,38,454,535,189,367,192,249,154,566,431,406,419,489,960,561,980,82,37,330,86,90,899,122,836,542,112,950,274,864,657,471,612", "177,198,8,632,553,805,240,757,249,503,433,387,726,791,449,932,906,966,39,532,885,757,330,736,743,323,743,381,344,877,56,203,178,670,834,465,650,329,823,340,583,49,790,554,502,366,557,424,63,725,987,270,436,921,466,254,784,80,94,251,370,626,844,97,986,187,291,785,980,50,734,782,233,974,773,354,110,377,939,533,594,363,660,816,760,686,454,602,436,758,549,892,541,193,636,877,222,402,51,263,718,421,522,184,514,187,641,463,24,53,926,34,384,16,744,515,261,314,117,613,453,362,347,938,94,994,965,433,822,480,138,937,458,893,828,563,867,913,481,547,748,554,27,667,326,149,74,841,732,50,245,839,494,993,714,607,426,405,142,684,424,569,40,381,322,831,331,524,99,337,447,375,786,979,124,963,864,515,111,299,829,471,218,793,931,259,100,600,435,980,263,822,459,621,650,806,748,185,282,754,991,55,803,36,99,891,498,584,550,848,859,359,922,378,845,251,875,440,719,94,435,259,197,109,908,982,768,911,340,388,94,219,688,508,89,192,881,909,998,191,62,436,211,375,681,989,954,998,264,49,278,76,976,327,745,510,225,139,32,947,992,38,951,656,897,965,879,922,509,941,902,362,5,601,925,231,853,535,380,376,714,593,104,10,150,17,700,637,405,485,974,466,682,691,316,283,987,503,514,233,287,841,873,118,778,463,817,282,739,973,310,795,103,633,419,807,294,735,7,608,197,337,752,683,784,642,868,680,202,956,67,299,876,506,968,729,783,314,447,394,680,110,871,31,687,567,581,233,238,417,730,371,545,416,4,741,273,458,923,260,156,366,150,61,827,853,908,676,66,453,147,194,823,47,916,592,491,352,877,426,22,456,924,857,267,120,538,973,308,182,910,0,226,340,491,414,747,655,357,89,60,646,316,340,963,288,897,732,743,397,807,865,830,649,893,916,480,852,326,636,104,893,885,315,57,477,514,579,817,826,908,59,441,923,445,688,251,848,962,820,443,518,320,445,166,756,966,737,991,102,151,292,624,304,740,90,614,834,135,288,519,907,55,206,854,814,14,986,311,822,764,962,169,499,217,323,244,961,972,461,355,772,182,716,846,470,548,285,132,598,474,558,202,228,354,645,301,29,76,707,744,850,676,153,963,436,99,151,846,355,579,556,838,421,562,400,797,527,453,991,854,844,299,228,628,447,482,565,709,455,118,698,814,402,808,178,126,355,155,991,721,348,63,796,424,182,424,509,745,190,425,335,195,325,337,535,84,453,654,327,939,808,566,478,864,947,414,667,111,890,318,793,554,839,273,875,919,41,13,91,929,616,247,444,487,74,808,853,107,968,579,588,784,658,509,151,656,384,669,933,285,603,457,670,865,549,381,650,367,307,404,681,499,273,227,855,265,372,262,532,777,131,697,43,662,341,368,683,101,562,148,22,487,323,411,498,269,291,940,633,436,248,743,315,242,942,550,194,166,97,163,57,867,316,913,654,184,127,552,543,469,839,521,110,908,251,106,325,617,304,943,573,441,975,651,551,491,315,802,305,794,403,21,196,683,871,575,603,933,349,387,36,797,748,648,51,941,536,845,326,533,627,345,55,426,585,712,760,198,401,513,543,418,10,115,369,281,695,746,856,338,704,258,269,563,358,522,547,650,796,485,168,56,840,821,615,485,851,401,954,156,86,453,206,760,84,976,911,971,64,894,86,401,469,559,584,248,939,896,21,351,917,701,842,26,897,700,675,252,195,789,622,614,120,948,573,401,185,95,122,450,314,515,439,367,836,11,498,554,648,183,316,426,952,296,792,644,619,372,249,406,956,312,552,408,58,960,656,94,759,157,822,415,657,272,175,974,718,670,612,541,715,485,457,658,33,468,826,36,43,47,727,752,81,158,285,17,276,525,866,859,275,97,425,155,173,165,753,156,544,988,52,860,166,103,667,584,793,702,826,108,126,488,541,352,589,625,123,304,443,714,258,860,849,393,462,927,472,272,463,124,46,735,207,789,25,868,753,893,107,483,476,81,665,799,459,666,530,548,427,627,123,447,356,372,503,193,914,719,153,439,282,439,791,318,820,590,326,59,218,90,4,120,318,458,953,236,709,521,115,417,95,170,488,370,48,644,886,353,363,58,517,920,654,973,300,740,896,688,418,756,79,236,320,580,811,586,104,923,918,7,942,972,81,109,314,75,399,604,724,662,819,212,184,909,200,430,338,499,729,414,699,965,90,570,691,618,336,967,275,80,919,480,149,653,719,682,235,424,826", "912,700,431,316,75,632,945,846,130,301,777,69,580,530,596,351,680,437,82,825,996,665,350,307,841,920,687,206,358,251,594,33,613,627,31,519,764,688,67,623,851,559,308,734,3,23,891,647,701,375,548,103,786,993,681,798,751,931,388,642,769,69,337,461,741,403,986,483,255,221,653,954,356,268,891,800,93,174,360,887,374,153,440,609,371,281,532,372,792,848,498,319,430,921,599,140,299,235,466,699,449,15,931,810,240,991,460,644,525,399,821,15,822,911,847,516,177,708,975,32,659,600,517,921,214,336,267,368,246,743,573,201,895,339,428,371,854,281,549,18,699,126,481,807,981,32,168,6,442,138,455,71,312,527,354,692,531,367,29,530,783,182,17,549,355,736,749,13,459,961,227,233,17,159,529,507,781,211,35,135,461,795,585,718,498,137,121,321,35,36,760,133,465,508,728,262,947,251,926,43,230,364,95,94,231,942,995,166,570,147,927,42,966,527,323,372,614,262,450,893,504,448,202,956,349,814,292,313,915,468,72,752,149,908,102,500,208,289,79,185,798,659,441,314,145,831,631,999,865,605,26,569,514,94,79,635,450,897,600,363,70,556,77,626,88,523,12,970,582,494,563,988,595,159,750,178,917,103,869,658,52,8,346,807,448,86,246,169,873,207,685,713,932,312,944,796,880,131,432,35,107,104,48,812,370,192,983,420,353,361,918,206,729,669,200,131,375,567,968,120,823,481,892,828,81,601,763,455,866,524,935,891,887,758,473,654,721,917,709,721,736,590,75,96,505,806,380,631,8,535,241,888,93,164,186,728,358,354,947,977,216,661,886,562,892,164,770,667,103,6,528,864,69,589,269,684,308,680,832,193,740,738,552,417,60,322,927,553,25,459,411,226,0,294,879,726,251,952,687,630,536,750,226,364,692,299,33,227,730,867,733,977,958,524,662,25,338,47,585,757,531,67,611,578,12,87,967,524,734,428,949,32,794,195,355,508,14,579,215,657,577,863,557,865,197,927,18,921,459,321,285,542,841,654,291,520,937,875,939,257,72,977,566,466,968,632,349,342,508,647,45,210,388,217,187,109,862,531,277,582,270,826,233,138,556,281,999,802,863,491,866,420,522,188,939,468,193,760,358,667,496,847,906,849,575,163,724,625,912,831,226,301,797,172,87,718,875,59,306,315,685,329,936,844,694,946,461,730,142,649,268,766,441,447,255,467,773,713,215,759,69,415,616,57,614,182,358,382,133,605,253,384,987,319,514,161,920,3,418,359,461,996,667,392,924,266,863,455,669,415,763,113,30,491,75,872,772,425,407,188,391,160,642,92,960,960,756,398,830,163,197,687,906,423,790,560,329,985,499,276,747,4,390,222,533,629,37,269,279,866,912,994,49,625,273,444,637,127,443,215,273,773,399,455,741,748,549,850,387,995,840,389,678,767,753,376,513,85,129,280,435,64,172,492,589,25,966,332,959,185,785,871,988,638,990,629,520,747,405,628,590,938,639,984,820,52,477,203,493,925,20,126,434,777,431,444,63,585,242,696,379,742,616,161,677,1,587,732,302,994,216,921,604,61,689,37,431,347,557,209,662,53,330,295,305,35,803,865,770,415,333,586,169,455,30,973,110,426,804,654,400,186,546,918,59,964,13,860,509,247,134,898,961,363,769,646,918,877,493,750,200,254,236,985,16,55,865,175,2,560,863,178,580,482,823,991,83,870,313,515,937,836,978,114,414,771,547,608,245,688,504,471,64,88,58,617,135,802,359,461,355,750,972,99,16,271,184,42,611,887,673,806,981,172,340,485,610,768,792,308,187,953,822,70,99,333,345,576,547,342,526,679,776,770,209,208,11,947,724,317,566,751,437,702,576,18,985,479,111,21,423,183,798,356,935,244,574,587,221,947,856,639,440,551,329,945,984,30,130,710,609,905,247,686,750,450,697,53,767,667,796,658,246,603,519,896,946,388,172,565,798,824,819,31,199,441,106,895,970,136,70,472,153,517,936,523,803,552,89,792,776,771,62,740,58,856,966,642,157,747,329,387,606,445,371,39,64,36,202,739,806,463,942,146,380,991,288,916,965,911,864,189,687,386,477,158,187,163,960,47,162,226,721,730,906,195,809,270,270,436,804,278,411,605,42,827,366,322,9,157,594,939,923,585,678,39,294,51,274,527,224,373,877,160,81,789,409,604,896,868,245,625,992,80,64,797,384,493,311,391,762,640,35,15,942,31,116,188,525,717,310,359,253,636,782,897,756,774,245,280", "818,94,161,271,185,55,437,365,772,433,702,699,698,709,241,476,526,910,287,732,794,788,879,792,422,932,55,338,732,350,260,936,651,787,300,393,380,352,594,94,181,731,632,919,767,359,444,864,83,71,723,869,236,880,426,760,356,628,844,100,877,654,277,8,976,725,480,245,299,499,848,133,600,231,616,190,668,305,243,908,950,123,734,618,142,396,655,978,584,441,847,492,465,736,417,366,135,798,230,662,771,916,351,399,42,394,939,986,222,348,153,613,859,693,967,161,633,909,808,783,853,787,769,982,119,653,684,478,9,490,246,355,623,734,267,24,190,670,510,981,451,626,149,909,445,815,468,269,693,629,171,637,764,128,360,325,955,270,803,434,398,372,385,130,846,898,118,566,274,75,580,760,258,34,443,65,596,44,229,667,208,438,328,58,200,832,896,947,59,305,653,721,487,926,658,601,182,398,373,79,657,620,984,210,467,352,151,396,31,411,304,916,410,375,854,736,873,222,682,275,12,322,390,794,191,189,64,376,71,27,681,985,592,711,595,663,557,863,249,968,340,359,782,446,839,36,143,191,847,414,303,639,541,87,146,956,309,443,546,827,402,115,756,64,400,312,822,936,925,708,364,17,720,169,166,812,927,614,187,321,132,52,714,485,68,288,965,14,935,780,997,805,410,549,345,863,21,52,388,202,910,422,742,624,526,134,421,434,964,252,465,78,538,886,697,276,413,750,104,720,726,582,857,950,779,494,61,56,979,559,131,666,542,533,323,707,423,773,292,268,496,380,826,188,689,650,842,789,477,583,966,27,910,684,851,460,7,144,361,441,999,5,328,650,142,668,322,471,125,432,804,670,185,156,60,968,952,757,140,201,669,40,950,996,471,575,491,126,120,606,381,340,294,0,31,585,857,493,636,613,310,848,191,514,457,746,815,797,627,662,204,835,142,140,685,211,15,595,286,859,957,673,226,951,181,132,394,601,647,466,51,241,789,876,352,672,708,554,104,930,154,294,752,129,30,181,970,318,468,560,65,357,768,81,609,522,60,396,985,129,316,694,893,852,504,479,131,640,190,455,924,524,521,612,237,409,322,739,730,79,896,786,367,134,519,207,892,674,749,347,224,557,649,889,713,500,953,44,200,733,350,500,247,927,108,13,807,86,618,281,332,418,829,658,559,121,119,302,723,87,71,52,814,819,550,46,439,125,796,868,996,932,53,795,189,939,244,939,737,387,920,480,607,559,656,545,436,760,11,370,66,693,338,236,339,887,462,808,292,707,623,353,473,663,858,47,255,15,551,72,421,625,9,303,672,5,812,212,194,97,248,914,801,776,788,849,701,129,468,854,384,584,776,626,264,695,503,584,966,101,981,944,593,305,871,992,54,744,647,580,236,237,211,117,301,81,632,395,872,603,419,622,846,562,303,335,56,760,331,677,152,448,285,424,114,824,990,323,489,828,151,42,532,164,506,544,648,501,906,695,912,604,519,425,433,74,413,576,259,192,381,628,403,279,341,515,460,461,601,968,91,183,842,61,810,882,235,747,995,118,838,184,482,785,5,679,734,254,890,71,907,175,398,771,144,246,150,425,185,24,987,963,497,653,336,738,795,455,268,401,698,231,147,732,682,682,954,664,897,315,421,736,9,809,33,152,900,145,222,686,597,444,94,659,861,475,316,980,910,878,258,603,572,785,182,380,237,68,606,720,715,673,25,779,272,625,270,484,531,26,997,80,120,983,566,279,660,455,902,977,762,103,717,767,312,707,33,539,331,33,140,152,949,14,202,192,937,280,399,788,225,130,585,334,603,803,368,251,18,559,788,48,185,882,706,23,711,590,277,25,174,306,956,606,430,112,110,811,478,678,131,612,741,447,482,27,718,584,441,347,721,100,172,638,455,704,516,240,619,223,188,138,158,562,683,129,891,912,505,165,239,718,861,902,128,446,9,825,37,117,419,726,925,448,420,736,240,160,70,407,15,890,302,290,766,270,710,767,4,620,314,172,824,633,462,424,334,259,836,703,23,403,497,865,12,850,563,877,888,10,176,123,791,772,684,759,658,424,225,792,67,598,930,694,329,487,742,429,531,209,15,346,342,204,23,836,9,215,830,922,991,756,902,666,38,620,473,760,733,723,289,175,743,875,266,276,54,105,758,105,841,540,875,150,767,725,720,680,655,29,883,332,657,774,655,249,417,326,138,909,278,128,689,742,372,697,546,487,447,624,316,496,590,274,730,530,264,663,446,211,645,315,278,648,781,566,710,685,973,881", "92,100,747,872,901,538,260,626,156,701,414,697,668,18,922,455,835,113,249,399,771,420,962,509,109,988,507,939,190,261,658,489,646,918,590,763,44,606,109,652,804,110,114,98,646,757,401,203,197,441,535,485,802,472,474,164,22,901,68,658,750,63,399,402,209,300,126,591,722,506,687,790,828,457,719,392,251,807,739,962,545,666,20,830,308,233,634,444,486,942,406,591,890,273,852,88,221,469,741,407,482,746,100,49,10,76,416,703,573,113,323,73,821,547,743,837,431,341,8,316,654,842,375,973,648,412,93,287,970,383,747,725,468,799,918,880,75,540,129,346,467,472,33,461,482,917,379,257,515,973,898,500,226,712,311,830,255,523,43,478,626,24,163,145,110,896,167,953,148,152,134,3,35,684,273,606,340,539,258,507,426,60,969,457,258,14,85,688,434,927,203,71,19,838,920,780,790,992,374,830,240,342,286,409,2,880,981,169,950,896,642,350,286,159,840,771,442,609,844,142,935,643,465,354,183,349,15,824,395,664,393,9,837,377,508,830,817,678,869,56,235,472,649,741,666,460,132,973,356,67,365,343,721,585,88,529,643,883,215,464,674,897,601,33,975,994,81,912,353,779,489,366,729,177,975,443,121,594,452,125,532,732,68,545,136,87,688,658,37,777,304,364,922,207,793,362,373,884,443,396,959,416,929,296,707,96,332,943,939,329,162,664,523,858,892,683,872,99,725,92,828,617,647,547,465,253,947,456,199,725,585,58,701,273,963,969,186,90,940,396,685,737,409,5,225,367,115,224,662,811,558,402,933,506,231,53,60,155,602,228,642,986,421,209,778,932,580,975,218,47,157,376,994,285,540,891,839,370,785,630,288,181,349,830,612,858,27,20,838,97,776,491,879,31,0,888,33,730,656,521,745,155,894,941,174,842,982,631,576,617,837,575,926,273,175,911,525,437,838,572,415,967,652,830,13,700,99,625,302,522,160,858,631,787,564,896,763,628,953,813,406,256,591,104,282,109,612,591,671,593,497,917,876,70,773,76,714,898,309,677,514,608,821,694,555,526,540,226,965,300,53,554,721,652,760,805,657,826,751,382,691,996,304,389,304,329,87,109,716,495,510,420,32,883,799,913,157,721,717,818,241,72,862,598,846,707,498,350,223,393,410,183,921,178,295,935,133,747,964,807,982,423,855,72,115,538,371,367,274,820,415,541,148,584,66,911,241,784,126,738,945,642,285,574,730,352,92,311,379,534,142,472,880,23,372,566,690,552,322,525,293,706,246,884,942,464,827,782,227,952,193,449,476,370,973,865,17,375,122,870,472,499,776,616,742,901,288,338,744,177,486,782,41,367,994,2,657,16,360,438,718,828,129,221,623,852,478,812,975,252,983,515,57,135,965,417,917,152,592,469,519,44,580,441,35,486,554,346,129,392,416,848,28,988,336,805,936,210,480,230,241,448,199,750,867,411,369,647,474,951,647,620,913,596,13,721,675,282,837,463,748,392,936,501,442,271,647,186,129,199,289,802,159,553,540,213,698,594,13,45,971,452,539,54,412,353,487,246,625,27,606,882,296,107,969,385,923,33,384,621,312,910,257,797,621,549,953,269,578,158,36,666,519,51,267,911,451,134,339,640,375,390,301,977,626,753,803,462,104,873,419,94,392,797,421,843,315,997,533,303,341,835,101,720,564,334,311,435,865,629,443,498,273,299,919,286,633,589,791,229,55,553,283,52,977,643,461,229,829,647,499,718,261,751,513,370,933,484,443,309,7,339,683,735,219,609,285,40,465,658,954,68,194,258,214,382,870,762,97,953,994,373,345,21,907,848,17,612,18,689,80,232,158,735,220,763,634,687,432,680,333,662,678,764,234,595,383,670,917,550,195,927,225,920,770,852,140,253,523,697,918,678,94,180,9,288,432,43,508,952,319,105,152,177,730,814,818,179,219,839,234,640,661,987,619,344,522,6,944,310,751,344,606,407,805,189,289,881,398,224,585,653,874,348,761,809,114,840,630,753,581,76,870,167,205,924,340,553,578,279,624,733,997,668,631,29,878,510,968,487,529,110,654,951,220,706,178,231,413,246,183,702,270,100,205,327,439,764,490,505,72,332,347,728,898,741,169,917,418,313,443,936,303,248,237,56,456,786,605,130,494,10,521,656,670,357,374,634,380,274,957,107,768,585,968,361,257,3,1,250,607,132,592,131,995,594,420,319,197,950,653,879,809,289,844,573,989,831,953,953,16,526,158,651,827,103,122,899,853,80", "512,29,529,797,342,92,398,919,414,553,112,143,37,274,314,481,782,345,337,897,992,820,778,567,454,26,567,912,185,816,232,596,435,246,974,641,714,10,316,683,999,526,897,669,161,174,659,437,379,631,713,622,749,860,271,613,192,519,179,725,87,513,488,866,115,329,492,489,716,899,638,700,530,761,240,308,422,679,550,987,212,464,832,81,531,104,667,112,278,579,888,65,561,173,960,965,889,69,3,292,724,383,404,76,958,444,759,602,619,691,904,73,211,373,118,364,250,504,231,950,431,847,500,674,291,376,44,933,446,600,504,724,531,719,172,283,662,752,177,402,726,825,115,294,277,755,694,291,950,793,318,173,31,570,811,959,858,845,501,3,248,802,676,159,163,534,46,483,983,797,807,263,87,493,54,198,733,410,876,807,380,248,772,312,146,651,683,994,617,588,558,608,104,937,287,904,741,616,458,90,732,925,307,847,769,558,212,411,28,86,256,302,351,499,173,516,750,44,354,732,771,73,73,465,829,191,762,414,489,45,771,567,796,309,183,580,394,588,544,623,994,284,586,245,648,615,611,862,811,26,564,604,748,296,319,903,262,390,569,328,31,741,750,243,470,914,575,287,473,155,543,2,603,713,198,155,117,872,367,655,287,681,240,537,108,835,34,629,31,417,571,227,361,896,646,577,140,976,102,444,819,601,671,882,577,130,99,45,555,163,153,377,574,449,967,278,808,110,725,641,475,497,535,771,494,766,811,47,115,976,111,177,321,623,843,871,338,682,80,107,329,629,172,726,223,383,974,100,669,44,799,338,469,357,797,938,167,174,570,713,650,627,906,976,798,169,502,244,255,471,144,445,337,262,364,446,244,682,431,770,277,765,119,713,324,700,396,82,40,970,248,414,726,585,888,0,797,337,846,94,502,438,860,319,892,280,4,336,62,45,723,163,570,869,114,101,312,55,391,109,425,795,419,960,221,155,952,179,743,904,57,78,521,854,716,210,21,36,605,800,914,597,770,405,737,383,982,538,694,220,84,507,301,101,921,515,726,183,570,40,370,437,232,198,916,935,92,927,2,821,800,188,935,406,742,344,511,677,380,326,94,801,864,893,953,707,863,106,429,499,663,137,368,97,240,671,801,197,518,198,947,740,607,398,648,7,254,83,88,44,921,698,508,519,932,512,637,626,137,328,120,527,439,363,288,859,457,95,147,907,594,90,779,643,562,224,997,837,746,948,523,27,526,661,510,227,66,351,365,304,276,823,829,976,925,485,792,926,214,347,851,210,365,53,249,273,190,279,49,660,731,875,711,907,480,203,349,35,808,868,233,354,408,867,413,344,853,539,65,778,17,998,134,490,984,209,356,291,101,664,330,271,381,298,702,54,537,211,420,271,260,222,927,164,735,534,935,244,681,359,660,252,577,415,364,54,282,196,613,131,667,727,547,509,30,831,525,652,648,546,993,378,266,560,156,558,368,587,966,519,732,556,83,183,292,599,932,753,755,227,481,812,176,927,7,680,723,759,888,489,705,518,673,491,558,635,349,749,163,897,797,931,740,69,842,99,746,411,213,928,763,264,950,85,452,205,287,573,599,126,427,101,531,101,835,39,826,708,584,268,371,552,803,11,284,366,125,418,260,987,685,974,74,457,79,80,46,593,335,164,101,131,708,457,285,227,132,294,205,241,57,333,925,177,405,14,202,695,658,316,196,528,359,701,897,664,76,283,927,435,393,404,798,11,942,140,203,297,965,27,839,645,514,973,7,155,919,466,667,367,252,473,452,903,538,433,482,344,320,73,327,519,592,542,250,892,787,844,580,310,974,286,40,500,993,728,652,450,53,860,654,962,372,48,66,645,247,18,780,306,301,205,719,317,764,654,125,556,687,726,16,198,113,935,531,479,933,887,516,29,629,953,988,886,314,864,687,874,790,244,923,881,45,756,223,786,887,2,534,38,292,569,528,398,103,264,37,589,289,362,130,988,175,931,241,177,480,959,785,284,117,429,91,752,40,375,226,47,426,590,277,859,359,825,651,693,582,348,394,856,21,485,316,343,616,153,257,465,615,118,246,31,182,980,205,538,920,224,370,361,988,288,534,126,257,690,160,556,165,441,136,576,770,66,552,168,500,9,164,782,85,814,538,893,792,124,974,178,94,885,646,130,5,598,206,717,617,258,323,948,517,138,314,398,280,352,804,431,45,188,517,523,75,908,703,350,758,444,99,764,262,88,140,628,364,834,90,161,624,151,812,970,206,297,43,138,15,491,114,804", "480,381,206,99,892,696,945,875,695,759,381,935,820,298,195,608,611,63,433,261,471,47,390,241,953,122,222,675,75,486,856,139,479,765,107,893,831,358,71,901,988,472,148,457,260,811,158,361,140,891,554,545,950,107,793,130,643,86,780,286,181,806,726,880,992,635,77,242,848,175,815,662,698,642,496,272,778,845,816,936,439,845,972,568,453,582,482,802,563,525,39,797,210,551,890,643,635,187,322,539,677,604,597,539,978,921,685,81,408,391,878,749,326,44,831,694,1000,52,394,338,607,793,845,483,647,51,432,109,614,447,899,870,565,213,363,590,930,967,791,738,961,364,622,511,644,71,742,240,933,431,300,506,27,630,283,321,879,653,271,141,793,200,512,74,686,898,438,282,758,583,555,772,760,922,291,718,818,750,349,274,749,326,469,192,674,119,758,38,346,178,405,221,222,414,730,767,751,484,571,248,854,577,414,85,392,772,532,137,337,108,368,870,291,925,210,208,222,285,256,900,104,720,188,73,7,972,130,702,889,978,810,515,574,828,672,199,946,921,952,73,140,848,269,806,691,886,718,186,728,997,27,769,951,249,846,278,325,936,424,898,572,617,813,697,330,361,485,61,65,885,892,886,352,848,145,5,971,47,53,531,685,28,888,666,77,171,338,347,159,487,991,927,580,336,407,531,764,746,135,858,518,934,128,980,766,911,279,609,140,23,32,23,538,959,495,964,618,456,666,57,595,992,466,892,937,215,460,639,998,824,519,596,41,855,211,742,478,315,628,262,109,832,243,219,955,577,750,560,449,66,256,646,569,319,70,764,133,723,602,822,27,204,7,991,978,587,861,755,481,105,964,629,235,980,969,462,14,586,802,756,915,899,950,219,612,161,951,966,182,987,302,747,251,857,33,797,0,23,711,590,691,22,557,468,403,991,646,753,658,670,742,478,254,202,924,738,87,308,938,876,710,10,406,478,69,294,370,80,404,271,249,830,160,915,511,57,171,685,198,359,718,157,442,985,948,533,891,592,665,714,309,826,207,528,316,611,515,495,854,134,73,232,725,559,41,314,440,540,987,105,97,640,465,630,455,243,788,466,869,767,156,686,226,370,845,183,387,9,696,98,797,916,717,681,87,591,753,269,898,309,482,354,743,221,686,160,37,604,466,958,428,542,210,666,680,779,392,487,94,907,520,934,677,637,489,996,66,853,146,605,608,79,713,818,681,981,578,233,815,917,40,68,986,119,905,262,623,485,186,526,114,822,826,256,522,410,981,434,480,121,422,318,499,543,788,230,943,12,4,663,660,726,84,888,367,718,126,438,840,405,155,651,784,75,473,686,997,248,170,91,424,350,292,527,126,103,20,212,381,672,666,454,255,440,96,912,187,337,125,259,519,185,650,422,331,225,210,797,544,959,36,20,756,473,739,176,811,97,648,364,803,606,481,672,314,137,899,709,942,211,261,64,786,701,924,579,948,632,884,417,736,675,579,114,527,410,239,841,117,155,581,780,510,299,813,488,118,292,722,495,873,992,93,467,540,442,952,167,24,518,981,798,658,537,867,474,982,492,732,428,726,930,265,509,621,464,186,750,686,129,796,29,232,405,654,338,892,951,524,502,249,60,69,346,500,188,967,30,279,928,582,221,799,60,421,476,632,943,655,672,584,243,453,386,673,649,994,766,218,584,135,191,52,542,563,238,138,233,89,491,551,298,6,189,710,991,494,63,356,663,599,348,958,997,809,914,447,256,735,560,539,998,535,658,168,743,49,4,264,291,693,906,206,112,405,235,262,909,456,390,322,580,88,167,921,412,804,47,776,668,1000,120,351,972,705,616,141,422,468,571,597,234,219,792,212,397,902,952,655,532,750,368,875,190,506,382,767,112,955,809,516,949,301,107,938,916,985,120,314,507,170,302,41,567,127,397,310,49,39,61,914,719,453,337,487,676,110,654,182,836,618,939,139,243,203,163,942,133,796,872,678,462,571,177,361,862,102,860,217,725,226,528,907,693,847,740,391,450,548,993,756,573,509,399,796,329,7,942,902,840,225,872,894,801,414,483,725,701,892,225,518,448,342,479,775,967,863,240,246,169,566,108,469,719,887,175,669,108,491,963,893,889,316,887,757,27,335,265,731,685,46,750,720,988,781,947,878,532,469,102,638,949,239,991,43,416,168,740,746,303,95,28,454,28,150,775,460,359,204,110,409,190,758,493,34,528,138,133,44,511,967,900,636,318,989,697,483,994,608,961,515,791,782,187,4,571,685,103,260,184", "795,933,568,729,859,452,948,274,314,861,396,143,215,227,576,152,777,259,36,660,458,960,868,563,397,923,155,659,798,686,806,435,798,792,297,447,428,913,675,414,833,824,355,539,909,828,24,608,656,157,435,594,79,560,794,594,554,481,412,775,601,575,456,642,136,825,198,209,694,228,930,870,950,801,941,754,827,402,402,709,861,205,300,712,216,579,582,242,888,333,969,582,383,76,714,174,657,356,812,824,391,414,126,701,507,34,389,816,153,677,193,318,514,310,568,431,721,990,412,547,679,816,694,566,308,860,545,450,778,984,164,880,332,367,333,37,987,941,983,322,846,657,460,531,615,878,358,471,919,183,983,824,453,353,272,629,940,54,116,910,429,19,890,979,213,100,474,383,5,420,272,891,595,154,121,228,181,883,534,409,270,263,871,919,49,715,428,256,111,184,102,465,667,725,24,193,527,247,411,527,343,558,701,715,813,432,590,669,776,309,446,626,869,47,355,179,647,820,291,129,552,793,508,339,330,268,61,798,818,685,112,260,611,70,477,654,128,62,676,900,953,726,259,391,909,676,110,301,70,961,720,873,568,866,715,824,721,160,621,55,759,489,797,133,551,87,65,56,409,134,613,639,663,256,458,143,74,704,505,820,517,761,560,413,446,430,519,931,100,410,275,453,717,926,560,674,210,740,456,530,278,446,313,983,83,447,708,518,300,365,937,965,286,941,464,235,39,103,162,894,863,372,619,947,28,623,942,205,836,447,238,123,669,726,331,247,137,529,976,886,706,437,698,749,889,496,933,997,525,807,691,151,273,255,119,563,502,955,779,857,676,231,331,213,251,30,882,265,770,278,380,222,421,555,537,874,13,282,162,511,804,246,169,31,627,817,111,929,317,779,108,655,952,493,730,337,23,0,492,211,868,133,992,252,68,771,698,370,323,352,864,569,929,188,368,890,224,888,600,193,842,719,825,808,320,496,594,879,723,670,506,683,829,682,193,28,706,531,267,533,966,894,908,9,509,390,708,716,861,312,495,334,700,663,25,764,839,170,906,50,859,463,793,923,98,579,955,25,845,68,171,696,90,9,101,386,789,456,285,712,302,761,243,755,270,880,446,913,757,97,441,855,877,914,940,352,605,516,612,368,881,10,602,33,796,295,225,816,304,590,215,37,461,365,354,587,796,604,454,36,946,859,850,599,522,832,612,495,832,603,849,745,254,236,628,313,905,602,935,732,501,706,534,433,387,489,688,874,961,776,221,294,913,90,844,990,954,877,719,163,22,902,281,293,19,746,432,22,909,199,214,839,852,87,408,29,816,115,119,22,155,403,173,232,289,138,734,645,197,750,933,550,217,738,695,882,863,575,403,448,316,715,945,236,331,860,587,312,478,270,143,225,371,763,947,588,799,676,131,467,218,186,792,315,992,873,761,238,133,846,12,836,458,860,722,245,451,948,945,98,17,751,333,593,717,728,586,14,715,809,885,921,469,297,974,848,123,949,159,209,528,783,315,920,462,414,26,517,888,852,667,154,772,780,893,217,476,159,117,655,40,592,740,322,432,118,833,264,946,737,800,41,230,817,147,227,834,149,509,928,759,850,703,740,571,896,825,261,663,196,200,254,411,10,983,150,606,112,675,970,33,645,901,223,507,358,955,216,596,778,163,759,994,173,98,122,717,858,787,804,368,916,955,326,263,114,467,410,31,112,234,41,561,424,70,65,214,450,377,480,574,294,510,985,427,49,515,489,994,167,706,314,449,333,914,760,177,384,170,448,641,384,432,523,871,597,798,547,919,805,649,462,958,677,661,224,948,357,565,208,773,275,376,746,407,654,61,909,567,635,655,506,124,995,385,199,549,712,53,75,322,978,610,596,329,591,125,761,885,236,366,188,627,304,552,230,406,679,775,374,364,608,380,381,650,30,518,920,856,616,545,538,163,281,64,118,895,644,885,641,859,850,921,84,564,874,610,497,227,508,272,235,533,483,416,2,369,299,152,409,209,127,268,463,958,83,302,767,924,779,296,248,672,485,486,697,803,657,148,478,454,328,333,84,197,366,184,210,600,783,635,549,911,277,206,88,999,616,176,518,436,688,370,96,210,571,725,172,651,989,23,151,699,29,282,364,665,435,784,321,306,335,928,418,479,780,266,263,550,73,865,618,470,165,282,414,865,498,220,654,329,794,791,500,810,879,735,990,646,770,643,749,510,580,920,400,26,192,163,526,253,829,473,655,746,697,427,780,794,90,961,624,245,164,843,845,740,992,836,866", "586,46,758,76,356,703,762,927,152,224,791,736,276,504,857,674,594,757,589,805,1000,87,386,798,48,856,372,989,907,657,898,677,597,497,976,73,94,564,558,244,975,38,198,609,403,361,392,123,599,309,557,561,879,408,420,161,454,72,50,645,638,613,81,920,478,676,787,48,167,137,42,354,545,400,780,823,483,415,519,30,407,71,705,648,754,952,485,768,683,778,338,293,214,129,897,175,899,286,569,245,453,301,738,31,905,402,718,594,224,558,614,91,459,213,285,602,218,254,784,399,597,940,293,58,573,410,57,438,750,604,270,555,764,50,381,413,330,736,472,858,389,200,248,54,414,459,567,808,412,798,873,399,444,448,298,102,688,432,841,323,991,94,131,640,468,54,819,775,937,931,264,628,719,636,168,352,137,911,802,897,220,769,384,890,839,934,910,106,597,679,616,857,402,358,634,200,817,947,314,875,580,161,691,709,246,510,615,15,566,553,967,914,934,367,570,538,740,858,570,45,14,359,232,941,691,397,767,801,628,951,796,31,145,76,828,545,695,578,134,910,881,705,522,315,968,810,304,618,469,739,593,624,390,984,264,632,378,724,880,219,459,900,307,349,30,674,334,581,734,162,869,871,934,451,772,573,693,298,597,847,368,866,412,970,673,606,773,795,184,691,293,749,667,438,993,907,853,224,822,241,420,781,804,875,593,726,486,92,450,594,406,192,72,12,183,598,400,104,902,519,207,960,985,693,290,251,493,610,309,297,200,119,41,715,421,894,72,344,765,469,172,289,628,645,963,941,277,342,76,654,511,996,510,725,394,803,458,938,343,755,901,226,929,407,755,107,132,114,672,800,595,538,488,208,956,485,280,444,735,690,817,142,728,939,842,754,406,129,258,657,39,357,687,636,656,846,711,492,0,751,705,565,273,418,734,243,239,419,610,925,325,222,135,472,126,513,759,439,615,438,340,886,738,273,497,32,738,796,899,881,622,389,315,636,192,480,894,449,563,520,811,470,68,62,740,643,3,894,718,728,657,662,347,938,503,185,363,130,879,365,971,545,506,253,278,774,800,424,772,745,212,856,217,114,742,892,324,202,293,227,421,956,453,171,149,204,808,641,392,887,326,79,716,643,690,387,852,891,959,194,335,470,602,19,178,285,391,195,649,739,612,453,707,285,105,818,868,29,77,585,234,297,974,659,874,965,999,486,233,136,428,769,250,950,650,517,440,500,199,757,874,553,216,517,302,15,247,641,288,787,308,639,149,1000,23,211,874,791,637,315,148,71,683,517,351,630,233,973,201,810,715,299,280,515,483,649,927,631,96,380,953,522,234,99,878,806,747,892,456,744,976,240,491,694,270,261,286,986,6,599,859,424,814,862,29,8,918,886,516,633,994,279,34,487,676,445,162,763,726,142,695,942,678,973,278,946,78,15,119,303,711,841,951,701,503,540,677,108,160,336,295,4,289,713,839,327,830,735,314,34,783,922,984,375,892,584,718,993,981,457,778,58,187,538,422,727,124,282,97,991,488,586,157,919,71,916,675,142,954,798,735,502,89,905,723,717,680,29,638,194,30,326,128,893,600,85,408,980,934,788,363,592,137,939,481,139,724,925,231,782,556,469,6,358,266,633,567,394,404,135,559,247,64,984,609,743,418,58,185,475,505,434,328,691,718,225,192,487,189,817,849,989,429,600,86,212,68,311,49,596,954,387,345,860,233,454,561,485,64,174,211,110,977,149,825,971,259,12,549,912,737,47,280,620,80,648,528,409,117,642,92,931,85,268,560,498,137,777,516,403,934,636,844,184,161,336,748,190,569,121,553,590,120,353,451,86,482,239,854,855,763,978,979,389,793,168,51,859,472,424,177,547,904,172,568,931,81,737,773,364,248,675,396,988,146,601,980,225,748,13,807,747,228,357,821,118,254,527,96,126,527,398,982,328,672,766,756,437,36,557,661,105,846,842,323,349,464,874,288,586,902,184,382,817,98,162,550,558,23,458,397,604,216,811,804,820,549,877,48,926,189,736,578,647,328,428,859,702,789,566,775,236,320,5,470,605,911,837,850,26,139,663,935,1,362,817,238,960,939,560,433,816,208,355,480,569,569,70,115,674,435,157,922,832,842,572,699,382,974,253,91,142,253,537,656,526,106,327,796,181,524,668,894,955,942,240,271,333,581,327,255,946,575,209,944,979,276,488,696,832,502,5,517,756,82,367,734,564,267,80,37,25,897,173,365,945,786,12,499,740,75,759,502,453,210,407,489,792,115,403", "161,32,752,585,312,891,39,242,662,387,10,872,651,799,608,53,410,86,71,283,273,163,326,176,791,128,298,312,697,940,31,83,6,951,478,615,956,463,522,196,337,596,476,416,641,53,551,834,368,783,277,599,936,359,934,865,115,63,21,46,703,350,316,707,637,133,820,582,542,437,955,660,272,317,674,467,348,692,520,348,138,409,886,153,912,874,959,321,804,325,277,659,738,844,539,30,887,409,611,736,2,333,708,585,319,805,458,51,650,325,88,177,118,422,744,70,235,41,127,485,770,890,871,973,461,540,228,636,503,129,241,180,798,576,292,776,53,148,371,294,555,292,819,413,136,656,755,391,451,598,797,969,225,96,657,48,112,124,854,455,739,59,902,622,401,664,423,291,687,855,95,346,319,570,190,672,302,753,74,295,386,658,341,327,181,881,816,990,968,685,234,601,574,497,958,288,578,954,182,849,595,542,286,447,363,25,964,286,855,916,885,476,363,411,984,26,756,883,321,211,232,238,274,82,121,528,451,197,342,587,390,308,885,583,700,169,433,352,24,400,777,177,627,801,27,90,412,622,534,903,913,556,872,604,994,535,224,387,290,943,836,933,629,175,284,789,922,821,813,256,739,908,164,767,375,498,14,98,79,649,499,722,420,701,139,400,638,28,290,717,240,246,797,428,6,910,813,833,473,384,911,512,922,641,401,41,698,531,487,724,8,713,12,204,473,24,373,530,670,958,998,712,292,668,985,240,344,893,633,289,146,450,466,738,456,603,150,601,386,513,90,297,190,928,205,375,961,335,809,601,563,101,757,151,646,600,222,772,622,792,881,893,168,998,406,899,52,123,625,192,204,338,871,537,813,556,749,174,559,74,980,49,902,853,459,255,870,745,686,202,398,89,630,613,521,94,590,211,751,0,947,219,98,717,10,807,619,476,967,19,690,779,807,126,8,833,113,787,615,601,563,102,309,278,999,534,693,500,793,707,121,807,721,777,901,641,665,534,770,845,890,597,866,981,255,816,829,559,550,82,912,428,343,614,206,924,998,907,136,567,534,942,549,209,667,874,35,507,323,999,23,598,947,279,16,596,841,472,939,547,207,847,504,584,376,207,859,533,170,913,675,684,255,841,826,64,186,817,857,85,740,606,71,250,979,517,260,827,447,188,579,131,507,431,642,742,102,516,41,495,356,545,529,775,815,464,514,520,480,32,343,81,101,990,102,614,565,547,805,646,649,102,819,246,279,205,754,572,627,551,384,690,813,628,999,157,774,681,512,699,227,402,259,668,104,194,402,636,181,258,137,312,5,405,152,490,261,72,514,116,200,871,269,120,919,273,709,800,611,921,625,604,386,225,99,468,740,273,444,131,681,558,920,184,621,436,98,940,285,840,506,635,787,738,456,283,481,721,977,771,441,384,736,639,607,904,740,230,273,265,807,173,565,339,377,150,182,549,223,947,745,295,862,184,549,421,893,340,529,570,997,523,865,736,422,376,602,703,809,422,87,26,958,50,31,75,423,252,704,435,799,589,612,433,511,879,321,371,925,290,140,258,959,950,978,297,808,485,513,39,471,938,140,547,708,803,935,996,548,842,919,734,173,876,682,28,579,697,466,338,263,862,54,833,959,360,890,399,304,693,832,623,979,330,300,118,237,207,554,606,146,302,304,366,118,659,608,673,89,154,266,488,517,822,200,652,237,634,352,386,55,951,893,605,808,547,866,530,54,372,460,584,562,897,487,527,992,504,784,531,739,136,869,327,277,423,819,883,122,465,236,192,852,435,373,587,699,95,252,202,952,307,975,261,515,945,646,295,793,712,557,546,35,285,388,678,501,431,980,671,199,723,785,905,674,195,118,943,12,800,818,343,50,915,364,808,905,580,122,93,940,78,157,350,634,651,839,201,623,867,534,162,73,700,473,674,753,721,891,250,820,424,255,144,518,823,917,583,775,900,918,369,797,559,857,934,168,317,132,173,337,462,310,933,223,722,801,668,412,977,898,972,979,905,185,975,69,684,629,876,795,557,284,797,646,882,863,818,468,17,810,206,521,379,635,229,896,387,780,883,243,506,219,968,436,995,464,456,856,950,251,463,190,717,460,609,328,14,577,717,150,800,185,975,323,29,53,304,61,340,717,468,556,650,882,381,300,172,679,693,380,70,471,612,444,314,135,237,713,298,175,27,880,569,755,674,65,648,746,607,776,764,641,288,577,601,179,92,151,134,956,347,645,642,594,379,318,78,805,763,846,639,678,768,706,292,418,272,246,404", "962,920,346,832,803,218,474,716,621,451,780,11,161,684,80,567,245,357,940,238,784,299,188,841,507,908,592,106,577,466,394,612,638,110,346,484,759,574,693,292,755,103,148,62,342,21,523,137,109,267,957,830,294,464,922,829,553,582,872,677,474,368,139,889,757,545,672,476,440,28,843,942,883,481,653,580,924,88,404,127,94,546,317,213,736,913,659,361,856,101,883,501,740,793,879,824,301,995,929,623,835,394,549,426,280,729,218,573,570,695,583,331,375,374,532,304,432,979,373,675,828,278,531,587,904,54,193,159,87,717,100,759,256,896,278,999,757,621,582,702,807,326,907,398,815,991,443,91,69,950,207,764,135,131,267,400,702,335,452,249,724,427,526,125,634,44,685,927,399,800,968,658,506,712,28,11,744,92,685,796,687,241,32,840,130,213,424,983,455,718,535,646,520,312,363,101,491,906,874,485,438,143,425,872,54,624,667,308,611,946,409,739,16,438,707,74,273,962,112,973,946,239,911,783,574,955,256,315,715,212,586,988,124,190,188,309,838,928,358,36,75,416,209,980,883,892,671,60,891,189,176,133,721,687,685,502,790,112,745,459,340,221,568,7,59,673,66,282,878,743,863,792,215,302,779,293,341,172,358,451,126,756,992,116,177,200,671,210,994,519,796,727,62,338,193,438,279,8,63,827,99,253,691,879,503,342,441,81,534,389,339,710,190,804,418,773,14,481,982,86,66,749,214,95,292,336,487,278,341,995,992,730,717,10,488,129,707,404,389,942,961,656,296,134,259,543,63,83,623,390,989,490,200,909,765,514,284,549,214,715,559,387,143,960,281,55,954,988,101,174,679,209,172,709,380,602,922,482,176,828,278,721,586,348,594,483,806,922,767,554,61,60,536,310,745,502,691,868,705,947,0,113,154,48,186,457,305,71,888,299,637,877,904,663,503,522,47,497,109,626,14,890,793,412,774,229,82,718,380,108,574,86,803,10,539,535,907,270,568,574,467,764,570,926,652,866,808,115,781,23,322,876,890,628,723,247,625,418,635,540,956,29,822,983,551,120,290,938,421,226,487,959,293,679,837,507,313,586,107,582,257,875,132,345,932,399,395,129,289,740,512,825,364,219,817,221,646,657,265,658,16,927,940,756,306,975,143,943,971,586,561,990,380,511,386,705,390,196,590,318,410,224,970,541,589,617,600,389,889,486,35,953,506,567,933,29,495,2,652,854,860,512,547,47,369,381,606,770,553,991,444,826,979,209,546,766,321,429,151,982,643,667,67,391,515,585,37,102,611,616,45,222,656,172,283,514,201,394,583,41,551,697,841,163,443,192,868,826,886,719,947,680,597,967,761,838,955,672,553,661,159,504,950,321,193,769,235,264,941,172,996,433,799,8,762,948,33,845,127,746,837,574,372,773,28,248,149,261,711,144,231,762,309,70,919,718,901,581,279,43,113,306,731,145,733,294,351,924,530,886,339,287,189,707,618,297,854,965,51,285,718,223,807,711,123,260,616,602,252,698,196,685,566,949,422,896,988,55,568,901,536,186,144,696,550,599,682,104,743,921,218,955,194,900,579,416,70,957,387,919,306,231,585,666,680,231,560,807,141,338,799,112,183,544,178,381,369,70,629,916,456,129,447,975,350,46,609,256,88,883,846,650,322,215,108,775,775,986,406,842,8,931,999,926,493,764,707,226,717,36,751,792,81,675,628,744,657,643,393,850,628,568,874,292,280,543,430,866,106,692,705,668,763,918,160,946,782,965,659,693,564,904,547,80,401,761,481,245,871,169,216,230,935,194,694,812,116,576,460,333,203,666,203,279,750,629,893,867,457,924,618,93,248,923,47,177,991,238,977,285,467,970,84,634,526,394,226,363,775,746,28,884,850,593,95,304,503,577,663,652,707,332,146,430,597,310,961,383,570,306,175,206,796,484,534,945,707,408,713,614,787,923,609,969,859,168,684,356,238,271,236,712,614,279,434,192,450,877,587,793,863,963,986,358,39,773,271,408,633,914,387,526,461,214,580,29,77,978,169,82,426,638,244,884,193,203,274,877,237,38,482,909,622,797,759,960,897,881,476,471,277,913,990,348,168,539,502,615,178,126,75,89,437,587,26,203,113,470,824,890,647,956,913,403,944,604,335,925,644,692,461,56,634,466,23,766,714,96,124,947,243,336,459,315,992,350,498,758,459,673,975,59,941,490,772,829,684,315,695,918,386,495,809,766,795,548,644,708,634,640,194,427,273,972,49,497,331,872,213,250", "546,646,738,837,982,502,897,829,132,624,563,716,914,824,300,217,675,325,54,32,982,948,496,32,766,793,352,979,924,222,445,186,941,712,809,922,35,154,200,611,660,933,445,236,303,988,437,925,14,952,498,143,934,104,382,696,96,592,430,473,905,349,377,208,930,938,95,718,439,26,192,724,493,578,861,719,195,826,936,654,667,745,317,778,696,168,44,287,717,339,530,63,508,291,17,894,330,181,63,25,857,354,880,461,20,832,751,245,152,680,859,204,61,119,973,636,298,463,526,696,760,625,191,396,724,172,830,461,246,243,624,202,181,360,407,846,143,4,807,812,368,357,658,901,69,591,142,612,248,332,931,551,413,388,815,232,203,533,536,35,760,713,825,53,104,142,91,383,750,685,294,695,691,784,191,645,702,244,500,836,88,872,620,770,894,939,796,868,417,665,488,910,812,103,275,364,952,796,450,152,636,905,218,179,923,694,744,645,763,663,516,630,310,893,467,753,351,836,226,310,182,871,52,353,691,420,961,481,402,295,206,410,945,210,846,750,393,420,647,405,902,110,242,254,875,342,753,485,132,697,327,891,230,732,37,72,480,651,258,270,954,827,844,451,346,189,954,525,663,90,750,44,857,327,461,699,192,654,234,336,416,873,723,948,288,933,407,242,563,62,121,296,581,193,134,363,49,723,4,803,498,247,492,881,349,63,114,338,154,525,865,178,569,493,647,824,305,336,842,46,540,248,179,688,405,908,438,80,814,984,702,548,243,208,717,871,275,815,891,708,265,502,662,113,673,822,969,898,924,622,844,302,862,62,994,206,565,979,469,610,83,302,211,582,298,840,904,166,816,912,862,832,685,212,672,449,360,555,483,866,625,214,545,941,610,705,929,585,103,331,87,646,750,848,155,438,22,133,565,219,113,0,868,971,864,425,483,979,260,76,245,122,772,940,796,381,255,117,371,731,935,875,835,795,448,350,505,440,771,712,764,613,518,948,508,670,5,357,257,272,422,390,313,14,707,946,187,894,879,153,459,249,544,39,44,169,546,664,898,489,73,970,73,506,419,689,791,258,21,568,260,232,546,164,931,449,547,767,95,575,698,106,781,963,519,437,522,360,760,744,407,2,396,83,87,113,185,371,731,517,200,208,925,392,32,816,851,174,131,971,47,371,104,802,225,918,545,840,351,401,820,453,587,499,21,850,22,473,287,955,441,92,730,975,553,906,958,801,47,973,673,383,872,115,916,73,564,847,528,92,195,24,428,727,318,968,376,959,282,234,617,435,113,179,850,573,618,438,871,723,526,99,335,493,532,566,716,962,210,527,758,39,741,985,608,9,475,550,943,484,115,353,45,737,902,512,609,375,655,692,225,742,107,63,154,708,528,509,92,929,631,824,938,343,735,970,388,932,385,860,561,240,258,553,168,688,690,515,349,414,854,444,329,602,309,959,584,806,116,303,623,517,859,175,380,972,735,22,958,827,260,876,628,491,799,487,900,286,164,438,128,266,531,333,553,777,561,691,825,780,220,827,3,70,509,361,196,914,279,795,682,187,516,352,228,942,897,839,23,297,935,117,697,205,843,759,311,613,264,716,200,823,258,770,325,526,370,65,543,411,763,613,716,273,751,438,249,384,8,604,176,690,831,772,90,717,310,849,773,905,559,116,866,116,134,217,729,990,625,104,390,909,125,130,62,955,745,928,805,830,246,721,44,194,414,815,377,155,25,304,559,570,91,456,834,421,915,893,51,540,844,519,709,487,7,512,236,525,217,214,68,270,168,134,611,161,437,346,122,418,843,25,329,176,474,414,948,263,489,726,186,439,686,97,280,514,959,743,166,769,956,270,620,319,795,263,141,483,711,970,140,930,316,942,927,838,669,193,680,273,901,379,598,984,533,32,11,120,581,353,112,242,611,621,327,11,611,785,323,548,716,857,592,100,295,511,560,133,581,593,691,994,155,899,522,569,655,891,423,53,531,182,259,172,340,329,270,30,969,449,280,912,626,776,546,824,174,753,990,12,895,342,328,209,423,346,593,916,449,325,24,889,64,625,465,893,895,688,26,426,439,599,792,488,849,170,251,505,705,848,14,286,671,38,658,709,732,972,449,396,955,215,173,366,343,173,130,352,168,710,943,888,480,11,583,404,41,427,655,774,708,282,943,590,288,402,748,455,305,311,94,828,699,16,422,838,494,121,567,589,969,84,495,633,868,47,561,370,327,689,618,138,339,271,43,700,784,308,6,402,124,722,44,34,213,588,505,626,442,682", "891,46,131,838,221,645,604,145,970,833,851,975,587,204,880,375,884,149,626,710,153,654,653,949,85,394,767,125,460,255,462,188,559,312,368,41,270,977,591,735,62,219,483,627,641,910,550,273,46,396,709,976,803,410,345,660,594,389,109,186,808,133,99,260,57,295,353,462,291,690,476,844,334,781,622,971,827,861,996,356,546,912,14,961,746,393,791,105,993,106,723,75,404,811,46,61,254,660,157,33,319,346,421,187,189,132,527,837,368,391,489,51,155,366,743,871,502,624,428,488,626,811,382,111,959,368,48,554,467,695,296,762,854,983,892,382,281,987,156,652,258,462,948,814,447,801,807,206,453,583,155,654,796,872,651,424,682,379,285,94,376,400,987,409,435,848,263,12,281,997,697,542,570,105,539,348,316,9,147,1000,34,808,903,842,944,286,756,794,472,406,218,627,845,416,903,730,38,796,459,13,614,729,383,467,896,773,480,833,533,744,416,278,990,158,851,95,886,565,337,793,834,795,332,300,176,248,472,786,759,730,653,335,148,339,994,955,318,164,634,272,80,102,639,612,717,636,140,768,810,757,152,646,857,786,594,157,782,722,505,783,167,520,665,778,682,877,20,433,349,6,881,974,588,275,661,362,587,5,88,471,479,28,764,223,892,206,93,240,756,882,367,396,480,715,515,139,798,814,289,314,877,819,504,652,706,396,607,522,536,448,530,717,506,768,945,456,139,364,484,733,535,656,405,218,630,258,36,510,917,191,57,257,566,288,482,511,38,77,790,471,844,620,534,597,398,528,925,220,568,228,802,685,671,756,557,312,791,547,385,158,834,999,952,586,915,505,710,964,50,615,242,459,923,2,909,611,105,224,824,245,49,313,995,93,381,668,937,841,897,912,117,316,226,191,894,860,557,992,273,98,154,868,0,358,78,103,531,641,594,614,386,651,881,156,241,680,568,379,710,140,743,79,208,613,438,955,425,108,488,701,852,134,708,546,463,536,943,992,480,904,226,106,207,950,130,668,896,65,612,569,183,498,404,805,674,510,642,962,878,882,263,581,186,777,578,65,408,975,56,424,106,87,223,875,916,617,305,359,643,203,213,307,973,519,98,503,673,239,638,169,613,240,484,636,643,698,706,90,88,164,903,18,945,40,733,589,842,193,324,172,94,210,866,46,330,991,793,440,494,19,775,509,854,442,874,654,196,949,467,725,833,22,231,710,103,215,165,627,848,906,670,442,793,145,170,127,292,558,403,646,601,180,775,137,816,575,589,586,617,133,432,507,51,325,457,641,359,469,359,538,989,720,79,663,941,861,712,316,323,231,652,41,396,389,639,414,574,352,430,57,891,842,351,328,873,84,323,801,404,41,63,208,754,335,785,878,233,774,361,866,615,417,662,726,106,217,1,832,962,284,927,909,407,214,520,848,756,924,774,128,143,231,390,752,338,118,402,511,103,422,594,308,869,738,355,462,67,132,581,277,115,675,988,510,974,626,548,153,825,395,637,376,642,910,946,357,788,902,97,852,513,761,623,951,256,901,989,140,648,600,392,132,519,82,229,208,996,130,320,411,187,335,894,299,447,424,187,135,751,410,802,50,904,336,732,9,203,31,192,815,71,465,547,679,660,770,919,666,634,81,206,719,90,288,729,575,905,389,388,530,777,746,336,11,505,178,638,428,717,607,329,711,724,79,977,937,696,994,440,896,113,17,210,435,163,575,470,168,726,638,651,777,669,547,748,594,278,346,388,408,641,207,589,971,434,573,925,767,905,680,76,245,996,743,877,271,291,651,226,911,8,895,974,298,804,3,336,468,633,373,916,597,356,69,47,676,913,138,246,479,997,881,497,21,201,111,150,111,33,532,899,5,150,824,31,662,437,11,78,127,626,345,481,493,744,272,381,13,833,141,456,882,296,434,542,517,931,214,929,918,127,692,451,854,756,840,886,14,177,466,659,516,615,615,381,443,906,406,597,116,470,615,861,4,661,896,772,623,934,634,678,955,919,80,209,889,894,968,530,64,263,404,618,290,257,306,87,444,952,77,687,104,267,153,765,791,44,682,805,949,972,667,711,209,366,828,983,485,201,632,955,467,620,926,938,885,840,117,712,737,138,960,2,551,463,253,960,862,78,675,951,32,993,165,740,14,328,354,23,878,98,111,918,842,410,181,644,384,871,48,565,904,394,127,696,416,41,615,548,902,797,659,98,618,432,44,454,691,950,423,167,132,671,81,700,691,580,263,758,32,173,147,648,497,394,115,386,598,959,522", "223,482,601,4,565,815,11,68,341,83,835,987,155,114,65,929,783,884,712,603,933,264,803,567,402,593,383,399,446,419,491,450,775,276,320,962,509,833,750,939,17,648,273,168,63,802,796,100,453,963,154,120,963,562,970,590,166,835,948,569,116,352,549,749,505,438,967,626,444,827,315,504,81,990,977,42,806,576,595,714,686,422,43,920,517,722,2,737,509,197,394,752,990,70,313,163,113,300,263,592,995,311,402,438,838,993,628,798,328,398,5,647,621,269,264,907,633,969,193,393,861,64,176,556,608,661,893,703,242,14,307,441,490,373,899,618,158,324,126,807,467,428,303,426,730,157,677,893,667,536,588,679,185,138,688,977,587,288,582,113,986,167,489,59,517,250,12,845,100,47,426,993,14,779,950,695,517,263,45,85,762,219,793,826,942,398,819,459,157,260,701,867,319,190,55,825,170,29,401,730,63,873,346,20,889,665,607,59,606,574,745,232,576,815,708,880,476,38,143,729,252,932,688,314,115,214,57,148,646,572,436,933,625,740,645,168,916,234,565,471,877,890,697,678,453,697,673,979,911,916,334,730,57,705,144,792,338,469,6,395,793,983,198,595,540,553,768,642,352,118,463,498,243,162,582,654,925,873,292,675,800,747,565,320,606,123,699,60,54,586,124,409,255,943,720,79,646,897,854,751,704,386,269,835,721,78,748,768,280,539,389,673,68,565,761,696,495,546,457,375,599,997,154,994,362,818,749,294,664,405,642,531,481,966,483,650,301,212,495,202,837,278,119,128,608,182,599,175,558,841,248,440,546,512,124,471,587,940,952,940,652,15,912,964,801,654,165,932,259,831,297,748,98,59,986,686,111,481,211,262,374,810,344,782,362,555,16,437,400,664,25,340,364,514,941,319,468,252,418,717,48,971,358,0,457,60,891,658,957,358,743,474,913,296,690,870,795,995,416,920,592,298,774,592,907,344,911,324,201,914,828,490,636,557,567,509,107,492,144,630,88,375,576,785,508,302,359,855,682,917,8,989,303,857,838,758,148,674,827,104,950,535,664,768,672,113,900,338,72,444,964,655,40,637,424,339,55,957,733,345,354,624,982,845,552,99,274,225,348,67,793,460,304,309,622,845,984,119,173,668,727,90,936,935,3,676,162,79,517,932,505,575,312,809,78,859,668,647,594,249,298,720,186,6,639,267,452,904,637,276,533,95,596,785,881,602,141,496,16,220,663,629,595,608,223,725,201,149,120,22,711,262,336,178,334,103,342,415,469,602,348,419,272,296,314,561,558,871,189,98,6,890,777,897,242,878,736,271,50,736,877,63,511,649,504,38,122,83,777,286,333,809,14,962,204,438,926,594,726,481,917,785,855,373,108,751,336,571,503,257,377,870,117,4,783,450,529,211,233,369,902,885,677,878,627,784,363,215,362,481,638,846,474,153,50,221,827,591,611,316,251,418,917,813,727,932,532,155,206,67,338,148,344,357,53,261,848,459,800,224,570,470,780,719,92,723,594,10,546,701,308,519,668,841,615,645,71,926,76,377,558,579,37,138,588,207,840,294,939,25,809,961,964,552,69,384,520,893,169,680,430,426,655,898,707,935,89,527,303,955,994,112,940,17,60,960,467,520,602,905,483,387,202,208,7,663,3,838,309,879,140,591,442,937,467,530,888,299,88,158,29,238,32,750,344,37,598,691,775,833,398,213,180,866,51,914,228,323,135,643,629,960,185,97,936,210,544,600,346,850,911,245,64,566,444,209,839,20,727,400,808,927,471,521,262,975,983,905,252,418,727,853,297,304,251,595,650,311,407,241,988,324,825,717,60,727,78,796,826,821,667,67,815,301,636,38,46,939,82,259,135,469,973,811,927,188,946,8,617,348,221,423,928,613,598,690,110,604,757,204,195,730,785,701,985,195,250,141,823,194,587,83,975,628,742,257,484,731,972,491,842,579,450,41,631,66,51,227,277,290,353,690,236,371,259,789,750,107,283,467,237,62,66,246,650,327,950,339,180,75,841,769,909,51,102,654,470,242,484,98,526,82,347,101,118,311,478,153,196,200,280,789,924,847,690,519,872,728,902,266,929,895,586,948,984,538,967,759,340,562,352,659,741,880,551,669,825,196,923,988,12,160,6,120,493,152,884,956,959,301,529,187,128,524,675,811,386,331,762,471,667,300,245,680,773,245,173,401,262,171,120,923,880,488,379,810,233,651,874,649,492,986,798,231,750,801,248,225,214,818,753,427,11,982,964,77,246,403,593,953", "476,479,827,777,799,611,965,911,732,911,224,366,479,723,203,469,723,459,646,914,356,884,352,643,262,536,351,541,130,823,705,533,933,593,29,48,112,977,748,365,569,321,693,188,765,529,244,6,825,806,550,844,887,301,320,61,104,428,505,98,450,184,864,563,784,652,792,947,835,401,116,488,67,638,809,650,374,718,349,543,63,379,209,147,191,434,528,445,736,673,100,355,155,123,892,676,474,39,550,789,193,404,515,100,63,401,935,926,259,358,886,703,358,872,609,237,377,678,848,903,77,450,746,237,450,634,252,813,644,889,942,855,258,94,653,870,779,854,171,652,309,788,824,120,284,971,126,217,737,444,738,109,20,214,951,343,22,501,548,839,968,175,350,592,299,659,496,678,982,598,224,656,358,223,523,660,332,860,837,155,170,339,975,959,200,446,578,287,30,851,51,646,74,783,12,444,102,243,225,515,68,859,852,644,631,346,15,899,328,812,82,676,455,496,47,667,441,718,242,706,16,170,112,853,195,786,853,842,539,532,984,91,894,329,11,541,935,27,241,295,51,629,165,640,374,472,896,870,278,841,875,774,20,30,852,560,678,623,456,858,248,899,748,954,618,943,957,681,500,57,570,753,599,2,476,603,919,434,461,142,91,593,510,573,269,398,521,548,514,776,94,407,59,603,360,910,797,177,585,470,140,322,209,551,245,874,412,276,929,144,462,433,974,315,66,95,362,853,398,904,154,707,216,17,245,618,915,899,549,426,712,227,159,753,696,592,80,364,201,118,806,819,188,672,636,772,271,435,688,802,642,64,320,169,681,959,288,607,79,957,167,798,535,518,864,449,713,255,370,156,75,117,458,563,950,955,423,599,131,992,777,93,230,303,20,962,161,823,229,488,786,963,692,457,174,892,403,68,734,10,186,864,78,457,0,524,653,992,330,570,992,356,125,866,360,692,121,912,924,372,476,540,780,454,207,66,819,590,714,921,337,475,190,559,290,641,273,223,390,263,42,865,385,133,878,649,694,397,600,803,428,580,529,150,959,845,385,69,803,858,897,88,495,904,479,393,792,746,348,734,107,377,971,305,353,831,571,292,882,927,797,400,591,865,227,463,297,454,586,52,272,652,704,38,611,698,263,567,673,29,618,732,114,975,520,641,827,786,66,996,515,59,424,617,693,690,658,294,817,646,369,897,698,442,74,17,756,647,536,727,486,786,596,515,889,65,486,453,541,594,79,429,861,810,44,591,114,233,899,686,15,153,930,590,763,218,513,458,748,393,687,978,504,786,938,970,644,639,13,438,881,638,361,304,714,538,535,908,853,75,140,791,753,117,450,796,480,272,867,915,567,721,312,944,775,799,358,296,135,761,928,970,537,400,667,179,741,865,3,967,392,144,739,515,583,660,76,810,259,850,974,753,182,421,267,782,288,226,364,354,719,477,40,371,199,428,556,524,565,602,426,608,212,460,960,740,176,564,479,287,794,353,994,569,459,88,60,178,352,178,703,266,556,291,720,328,708,826,782,638,861,945,986,63,113,287,839,846,992,10,217,531,530,474,823,42,165,733,276,164,585,458,189,790,363,890,758,286,535,325,89,257,184,23,254,705,265,317,61,819,925,207,468,184,459,143,85,287,696,348,876,192,849,632,846,565,272,658,819,704,514,653,334,287,118,808,683,515,956,286,195,469,435,827,551,212,563,895,579,789,442,408,1,93,595,614,482,892,141,621,959,117,942,700,8,931,248,469,740,666,503,719,784,936,906,504,418,588,655,784,786,594,317,844,157,415,246,614,641,824,367,875,488,638,467,84,999,683,16,629,60,625,818,19,942,275,451,466,777,229,732,298,269,864,87,979,902,395,317,218,264,839,596,907,966,721,881,679,955,629,904,962,299,440,452,803,409,518,60,370,123,731,30,888,111,287,820,701,981,66,505,587,300,655,305,110,947,61,780,809,211,472,657,833,296,162,191,390,213,183,734,429,164,468,205,630,401,549,332,632,922,75,99,755,175,851,455,558,428,712,465,907,190,248,434,123,227,27,471,272,978,432,959,590,330,851,187,417,367,686,171,712,130,185,194,955,734,860,769,53,157,929,677,330,926,881,291,394,438,42,124,121,848,916,773,216,574,481,887,295,327,136,205,385,180,27,498,773,195,621,588,726,31,597,952,705,61,564,699,514,38,216,415,142,737,102,812,161,463,696,518,262,637,100,22,141,391,253,71,658,650,784,321,548,464,685,223,198,805,515,709,267,76,753,73,15,682,685,136,408", "937,588,22,300,161,696,945,884,562,305,150,742,670,863,902,709,540,802,59,629,460,225,38,87,535,591,102,887,107,944,113,194,469,616,921,447,347,973,211,474,741,415,331,246,167,834,289,815,69,553,824,326,849,679,771,196,28,127,973,590,676,583,838,590,213,458,456,942,364,236,273,817,462,607,99,994,645,375,119,116,899,318,859,537,271,693,738,459,50,413,152,70,144,16,140,839,14,572,522,394,554,268,30,627,523,322,292,851,932,95,775,376,188,635,144,554,342,750,935,731,659,279,801,403,973,590,76,819,543,392,106,389,15,197,632,566,119,118,732,624,89,912,816,530,440,130,536,399,294,220,674,847,750,725,555,877,689,178,564,149,428,595,745,303,304,775,57,887,106,863,344,385,930,44,960,846,957,670,659,144,389,985,696,282,490,294,219,328,829,684,308,134,998,506,459,367,486,268,495,516,963,423,375,682,860,821,78,623,642,670,368,273,511,337,78,998,262,954,50,836,164,882,996,987,601,720,501,863,640,291,273,204,481,15,16,790,33,535,420,679,399,359,966,346,921,866,777,761,504,60,427,884,149,456,326,777,230,345,897,719,354,649,15,454,288,421,609,74,736,124,803,203,292,280,563,974,645,247,520,478,771,966,993,37,630,478,662,995,91,293,492,356,142,311,220,330,331,597,760,352,96,497,992,437,596,60,653,959,476,926,583,713,189,818,459,878,527,189,513,436,101,898,446,302,797,894,948,253,548,778,588,235,113,962,826,819,956,901,817,586,362,990,595,455,256,685,816,375,108,857,265,831,36,471,667,886,549,122,966,550,695,602,644,701,226,100,371,791,441,594,66,280,579,886,72,993,605,359,250,163,572,854,374,293,672,370,151,430,291,604,773,288,299,746,842,280,991,771,243,807,457,425,103,60,524,0,486,199,405,424,571,9,128,198,124,346,421,795,859,395,248,462,247,889,805,790,263,401,38,326,824,450,910,78,273,16,594,846,583,709,802,542,485,201,950,802,862,642,428,772,648,626,850,306,427,779,102,961,608,559,320,237,298,974,113,454,280,533,109,419,524,947,644,279,286,197,22,349,497,649,512,20,984,247,331,698,850,205,714,192,691,148,652,706,250,650,361,927,285,540,742,201,93,418,790,726,876,469,618,416,312,276,778,261,410,441,137,854,965,624,736,73,110,656,604,857,652,999,858,908,997,367,890,806,828,605,228,521,460,297,486,961,65,276,662,520,214,555,737,929,611,638,44,699,509,124,65,801,419,298,808,889,368,175,956,58,357,728,927,295,790,639,803,996,196,640,569,109,381,37,279,70,732,44,612,15,703,107,876,357,772,10,300,905,547,977,123,288,7,552,799,611,41,655,133,509,40,414,939,152,809,534,743,138,931,646,988,392,829,245,883,907,254,170,482,861,749,889,316,812,538,405,195,620,859,177,216,34,950,471,409,579,319,516,55,377,182,356,798,203,191,236,494,863,473,790,111,816,486,988,849,106,968,391,478,1,480,294,577,960,655,695,581,255,674,185,319,214,147,157,526,687,66,104,957,108,266,853,152,583,832,808,647,823,89,227,324,660,667,297,44,292,724,177,518,786,896,486,542,736,57,474,286,871,939,609,475,680,526,536,914,566,510,776,205,930,726,422,418,501,397,184,189,548,901,539,446,571,762,98,966,439,706,826,630,149,108,993,993,323,616,455,835,803,465,103,683,295,183,337,642,48,671,39,274,294,270,487,164,690,206,461,390,660,238,69,944,15,685,249,710,404,755,865,17,392,486,598,110,199,767,630,676,899,397,336,491,69,198,797,81,528,494,253,196,461,628,317,527,590,753,411,551,305,921,695,428,590,880,239,169,188,741,182,476,824,137,967,541,339,319,974,957,666,573,638,230,106,23,8,717,362,248,960,278,145,133,854,968,271,934,597,281,985,409,567,82,481,110,18,416,244,417,286,514,858,811,608,5,301,260,5,384,784,21,296,453,676,323,149,770,871,353,164,600,47,429,388,99,366,466,850,371,651,314,415,464,883,210,173,988,550,327,819,726,411,918,191,336,968,341,909,133,975,267,125,682,514,900,514,938,921,778,765,608,799,385,668,971,396,859,356,207,985,450,994,508,114,594,986,138,815,132,924,780,877,359,274,81,654,321,828,809,52,754,575,513,133,763,899,78,810,868,862,18,309,936,103,763,700,110,467,392,981,292,565,130,79,586,604,428,989,987,148,742,617,677,475,918,422,656,28,387,578,16,302,439,295,896,199", "669,596,448,30,557,310,709,352,314,280,552,145,998,320,949,335,989,915,401,698,483,529,886,133,412,182,679,802,874,226,857,711,391,264,721,918,174,255,678,677,710,95,486,791,790,831,355,282,892,247,166,720,127,840,342,722,692,183,918,143,873,543,69,361,735,891,924,785,447,251,22,336,615,458,323,26,343,149,762,193,803,396,502,804,388,149,197,314,783,69,610,713,900,630,614,37,67,71,542,326,829,564,261,280,594,279,927,446,364,636,471,348,331,591,579,33,151,867,770,547,667,936,105,545,7,820,134,533,686,804,552,867,142,337,728,904,407,896,342,118,786,570,202,172,849,410,538,976,241,891,876,257,656,454,881,609,62,352,862,508,664,622,270,737,861,931,498,161,637,548,376,844,117,945,372,88,943,701,882,339,481,240,568,44,282,351,311,449,788,405,68,151,771,155,493,634,76,983,603,840,329,726,589,95,78,489,367,456,994,964,155,193,862,916,577,59,578,614,798,646,729,469,862,677,204,788,659,917,891,779,873,615,162,329,385,982,608,913,347,899,648,629,459,834,855,673,616,21,887,530,905,662,894,596,656,675,951,519,868,885,691,468,164,997,151,522,26,785,892,727,903,171,9,894,565,523,853,978,396,188,393,300,6,381,374,281,760,87,225,813,404,968,500,404,23,29,81,361,660,83,861,113,531,561,3,145,283,181,761,518,572,772,182,135,470,558,187,980,992,567,69,30,895,226,527,647,856,661,662,168,14,287,850,296,942,700,889,117,10,585,999,795,663,375,544,356,393,116,828,106,44,418,938,762,684,50,400,693,446,202,622,196,90,581,85,870,648,618,744,25,746,280,619,50,913,594,527,630,303,316,488,87,228,333,547,587,82,215,899,871,225,897,33,815,982,4,646,698,239,619,305,483,531,891,653,486,0,171,653,234,671,931,399,665,408,872,854,888,67,347,963,345,424,169,949,17,234,788,971,368,669,995,2,273,782,31,614,757,189,454,416,522,295,538,285,124,126,918,199,432,808,914,241,506,33,278,269,299,388,838,214,289,877,312,520,784,955,827,701,721,821,311,788,23,306,521,59,397,399,183,911,98,903,754,951,284,97,314,834,742,701,160,218,850,365,389,705,824,2,114,931,916,737,3,931,327,46,509,673,275,99,998,309,575,973,162,310,122,737,138,512,886,120,285,926,418,642,535,238,447,655,235,505,961,942,472,884,973,418,756,729,302,122,593,562,894,734,60,583,165,948,12,293,111,491,807,666,960,212,342,995,95,258,746,324,63,705,899,663,81,665,179,918,246,924,236,33,921,774,748,509,817,908,726,701,259,992,802,639,191,249,125,834,298,134,812,883,530,689,251,107,313,632,986,198,941,306,562,438,632,779,114,522,625,879,952,936,669,598,924,278,298,620,871,867,225,703,926,937,263,881,337,857,247,398,65,919,772,396,756,683,846,529,360,956,33,771,286,147,436,390,48,692,507,28,915,395,141,66,302,404,716,75,443,666,675,598,947,145,504,527,944,887,891,927,46,121,407,214,634,50,278,371,708,69,42,195,680,98,591,577,810,872,545,378,507,955,446,160,60,337,951,616,658,645,582,153,358,929,407,318,336,988,22,872,507,506,498,830,72,899,437,305,929,672,464,668,350,85,259,545,78,60,731,472,733,84,952,83,785,185,643,281,403,343,149,520,759,905,513,553,757,471,138,420,540,62,830,808,737,467,822,793,628,27,91,628,867,424,480,962,288,597,152,612,449,720,697,992,97,145,363,967,663,4,223,273,941,569,401,673,35,498,640,387,730,42,665,789,497,21,881,450,89,944,964,353,310,665,578,64,981,335,981,65,425,518,373,126,607,439,433,706,790,72,918,539,867,264,220,33,563,694,366,838,603,382,341,801,756,387,836,242,945,921,336,362,353,827,161,123,574,234,576,227,498,369,41,304,448,494,966,272,742,791,842,244,556,482,496,989,569,465,109,685,301,197,542,706,506,402,66,476,488,973,31,444,461,584,555,818,776,876,418,973,497,751,615,559,513,454,674,991,781,395,267,844,7,980,765,30,589,1000,500,732,196,895,873,884,842,487,936,851,661,808,83,899,100,752,221,195,148,537,948,360,918,408,742,967,888,906,268,186,309,965,805,657,139,992,82,40,191,702,294,27,864,790,896,681,111,508,484,793,163,901,192,537,499,280,223,787,701,939,980,956,252,76,811,320,179,230,447,436,405,302,447,735,56,423,581,241,813,279,931,681,895,365,234,326,189", "938,263,216,78,185,328,705,766,607,247,634,838,468,934,389,187,954,917,499,252,509,154,295,811,31,682,635,77,360,74,518,371,388,7,470,786,799,786,625,730,158,210,615,697,488,833,556,175,414,724,89,365,288,271,961,718,365,186,437,912,258,936,104,142,707,900,364,921,719,691,876,959,869,322,678,374,812,773,671,390,730,442,220,842,689,103,438,824,562,149,132,902,225,503,466,989,326,43,545,160,95,638,279,361,44,376,430,7,381,815,226,898,61,929,396,126,547,357,566,564,41,223,716,765,300,453,255,670,341,663,513,874,840,566,758,378,51,600,245,686,906,545,701,64,529,141,530,391,54,393,678,366,235,169,120,358,699,112,461,763,79,450,659,362,254,79,739,586,894,72,31,880,2,528,777,702,732,133,814,833,394,335,658,963,791,383,98,789,226,366,341,98,590,779,678,187,733,500,310,561,45,831,390,993,693,145,790,527,831,71,202,173,708,132,437,694,417,480,229,4,454,208,910,958,611,685,829,805,287,848,334,372,819,458,649,678,25,751,518,586,884,543,646,810,606,194,729,352,65,807,504,457,806,704,704,558,607,324,450,863,956,172,984,280,840,80,240,924,220,909,922,688,542,833,97,161,110,795,298,708,912,133,304,630,230,699,298,650,812,93,332,316,716,786,770,625,205,299,494,38,740,713,494,487,647,255,269,877,205,159,811,509,320,496,688,866,730,601,562,427,93,692,259,207,673,977,252,132,492,373,862,56,986,987,357,830,552,498,823,607,796,491,414,929,194,815,302,529,112,810,266,838,459,294,737,849,124,776,484,304,348,994,510,774,94,259,871,991,671,553,730,848,813,368,519,571,837,395,719,174,667,74,132,79,573,851,339,272,630,878,169,732,227,797,631,336,753,370,419,476,71,979,641,658,992,199,171,0,598,862,731,485,429,131,745,216,928,407,15,219,720,96,281,265,627,513,854,973,826,309,65,276,558,472,211,131,129,330,60,883,796,606,314,614,49,488,39,284,640,921,366,116,379,800,631,407,292,335,100,320,187,549,641,891,379,562,186,86,37,674,462,3,30,553,128,621,528,908,655,977,837,968,21,793,583,282,207,289,968,516,509,207,459,1,609,94,627,593,432,126,439,362,114,534,590,419,536,820,511,824,773,307,984,807,381,186,426,877,403,626,791,825,629,425,457,993,69,498,907,451,826,193,831,699,782,127,416,990,283,815,740,248,778,454,949,647,303,442,736,781,563,226,879,441,771,832,491,434,442,391,167,122,680,387,891,772,125,490,503,320,924,433,736,351,740,184,52,454,217,160,914,164,24,121,351,12,625,149,312,21,227,75,494,834,682,477,397,672,17,125,821,169,531,293,881,371,982,857,818,182,749,477,634,161,57,122,274,619,385,946,957,200,501,856,23,749,711,206,155,875,992,897,375,552,647,334,631,817,489,216,531,492,176,551,52,879,863,206,369,747,428,721,616,521,542,11,831,334,437,12,849,678,763,54,678,158,76,927,166,388,275,156,253,553,960,916,940,893,250,45,691,929,116,495,155,762,293,353,884,120,188,606,169,264,514,595,602,455,789,452,814,348,428,59,523,82,313,288,6,570,532,137,523,179,369,46,756,864,37,411,783,891,999,4,211,304,190,961,160,819,277,30,331,789,78,454,985,758,964,890,882,369,798,974,274,518,369,688,404,213,554,532,184,524,376,653,993,802,772,218,346,257,603,829,742,334,904,371,554,745,210,327,242,158,664,754,223,14,180,312,807,950,651,338,419,322,841,789,484,178,482,89,35,632,379,432,656,351,470,855,773,966,446,813,760,74,850,178,915,783,407,548,560,157,425,171,226,807,984,860,516,18,535,854,230,631,878,114,956,940,282,591,192,331,385,412,126,424,562,994,744,477,239,329,762,190,895,334,150,244,729,767,683,966,712,78,500,883,148,198,396,344,144,698,583,943,349,243,740,522,994,310,351,490,71,264,49,713,917,673,770,381,708,440,492,111,724,980,453,820,460,859,293,933,427,678,658,275,864,688,312,225,639,524,689,304,862,251,837,154,253,746,574,686,785,202,615,440,905,626,927,9,418,346,531,402,71,192,103,924,505,330,146,613,594,393,51,622,133,53,689,114,307,195,580,76,854,820,389,573,112,205,655,753,717,966,328,383,734,952,80,30,4,247,477,520,607,495,504,746,646,153,404,444,126,750,134,864,30,449,281,99,898,79,835,908,627,82,488,843,757,937,798,666,708,856,950,591,873,127", "516,550,892,656,453,129,151,704,845,796,864,686,167,53,567,460,20,191,879,635,61,97,430,412,684,562,841,322,912,916,862,341,950,105,810,928,930,425,291,108,969,303,490,283,276,108,906,30,112,14,983,529,565,18,300,572,398,716,14,198,575,145,830,601,910,38,951,147,305,886,264,5,763,824,106,752,551,555,232,121,729,899,89,280,370,455,457,357,81,327,517,417,301,474,138,643,69,603,149,151,165,751,407,970,923,166,5,615,572,366,363,700,403,347,97,262,120,80,716,821,194,229,163,649,998,344,463,716,480,795,753,349,974,644,855,54,616,613,467,44,227,935,495,707,547,1000,222,159,799,720,845,392,186,693,6,475,463,82,950,462,898,755,384,419,569,865,705,502,344,44,349,642,304,205,410,715,388,953,462,147,234,812,75,931,447,55,360,743,55,708,840,352,951,123,267,157,570,50,895,271,968,183,239,417,159,817,767,897,631,293,212,372,49,661,207,730,318,746,879,132,650,734,610,653,84,33,215,859,41,880,889,783,796,385,218,747,594,484,888,932,28,852,551,461,896,251,167,536,525,719,418,560,143,371,356,185,405,988,367,319,847,110,777,938,745,335,607,184,991,404,218,243,505,845,941,76,817,355,166,308,552,942,422,729,306,427,898,70,614,104,226,875,376,65,104,949,753,167,698,917,41,852,306,37,158,265,198,830,798,581,804,112,527,724,219,949,65,642,140,99,82,603,199,996,85,239,579,653,157,721,997,312,759,558,869,556,747,92,114,612,809,577,484,537,895,87,31,789,801,825,598,293,559,595,939,14,117,368,829,497,377,296,244,136,895,519,268,631,44,852,363,751,417,92,582,245,132,402,617,253,108,760,49,921,642,263,671,501,40,187,366,743,730,627,576,62,658,323,610,967,888,260,594,957,330,405,653,598,0,154,543,493,439,173,32,159,173,536,445,517,764,951,463,258,822,80,623,566,235,217,767,202,761,172,893,685,503,316,4,38,609,662,116,531,474,389,51,350,352,951,400,436,308,473,279,648,199,989,226,303,251,353,887,169,77,488,374,949,1000,739,636,170,739,476,478,540,556,820,67,709,289,434,968,11,773,454,105,966,432,386,857,277,212,414,28,109,273,872,564,894,950,528,852,457,185,165,764,112,839,473,502,99,118,848,349,50,864,536,309,848,153,731,535,125,514,756,969,977,419,893,924,986,282,120,363,202,272,907,879,265,589,399,199,243,950,990,62,298,1000,412,228,904,950,558,137,454,969,792,678,741,505,125,59,644,154,355,96,365,925,799,887,682,702,646,176,173,907,830,696,997,393,542,149,115,438,415,157,748,438,251,616,417,642,460,135,927,822,397,806,89,477,175,311,973,168,142,654,920,924,833,372,347,967,319,258,765,532,259,12,390,364,958,917,224,333,642,814,234,56,988,864,409,822,666,744,333,890,780,542,515,978,573,670,354,386,887,523,77,917,105,712,29,949,725,174,563,253,105,779,309,11,707,515,82,805,526,243,910,37,353,797,751,167,159,149,285,838,982,915,608,518,358,728,238,641,210,850,678,648,485,859,920,231,533,201,438,273,240,590,669,146,86,478,157,959,855,175,422,280,162,551,489,818,321,526,294,200,105,867,980,919,86,888,622,931,949,760,298,124,664,770,524,329,432,776,487,773,571,416,230,557,884,278,144,257,137,95,320,749,991,871,442,770,428,437,790,956,114,246,143,976,670,621,102,211,472,788,249,823,304,241,43,868,996,651,506,207,67,204,87,543,15,194,156,438,622,284,369,408,941,963,740,907,179,706,591,105,331,966,873,3,362,247,862,255,677,308,787,997,341,820,232,830,214,322,977,635,926,572,592,509,777,853,589,81,53,152,257,841,374,113,186,958,879,100,843,758,351,438,163,809,24,193,213,628,441,879,507,593,875,386,278,966,48,422,597,822,442,272,437,391,824,238,454,811,198,200,237,821,765,696,951,946,14,175,857,263,346,981,678,286,532,982,600,571,475,745,767,91,897,24,478,716,801,688,730,606,475,421,34,681,818,445,732,785,652,133,582,948,257,540,235,820,509,973,519,177,774,197,240,233,396,114,449,129,145,670,390,526,985,695,3,472,404,437,978,712,280,253,914,181,98,608,592,659,584,60,126,255,700,584,59,917,719,494,858,688,239,793,413,579,492,393,315,34,981,637,793,316,67,820,970,237,977,67,880,240,295,70,526,949,437,930,96,425,313,557,440,439,422,365,764,155,341,279,85,536,32,51,477", "247,902,617,867,164,186,240,419,84,112,437,651,486,455,438,52,481,113,893,852,969,880,155,330,982,769,199,601,84,916,349,715,924,844,240,451,62,946,819,639,863,552,508,945,414,560,173,839,815,59,431,93,456,386,954,116,943,645,982,15,687,71,409,256,915,702,619,932,833,987,492,10,597,862,609,2,613,44,54,219,47,696,634,646,1000,328,350,291,921,745,428,147,894,698,576,779,334,322,598,214,296,141,876,989,30,589,793,546,522,659,609,755,318,628,238,762,253,32,410,292,14,201,820,172,959,160,175,145,983,156,910,923,211,470,778,934,959,55,381,816,157,304,530,256,712,99,141,619,816,111,548,159,380,607,796,895,978,385,71,379,979,816,410,14,436,287,261,695,221,60,371,601,853,921,703,777,398,565,34,189,633,552,634,845,594,637,434,377,580,874,605,38,967,854,613,324,135,704,627,430,92,54,744,300,873,901,902,215,688,247,155,705,551,631,295,530,443,753,536,520,538,682,404,931,111,276,498,124,372,897,611,180,619,204,419,239,680,666,473,744,998,578,613,713,590,739,875,374,653,999,264,433,867,963,544,876,241,39,342,594,828,543,631,198,519,592,326,968,69,825,490,609,501,601,991,824,837,454,458,318,151,221,550,987,558,409,499,48,323,149,814,543,265,90,746,909,626,936,22,12,960,897,4,502,800,483,104,96,513,449,594,701,395,27,532,745,805,986,334,341,213,866,131,941,546,719,293,41,32,485,19,487,769,239,633,888,294,667,986,416,672,178,653,863,900,608,271,500,793,111,517,306,613,181,589,985,712,921,938,130,421,42,890,335,480,577,452,844,822,677,291,787,999,168,960,705,435,185,843,341,224,225,730,41,473,294,657,433,133,732,562,397,867,662,617,45,670,352,925,19,299,76,614,358,570,424,234,862,154,0,722,465,357,853,853,191,145,519,32,295,726,459,205,454,8,122,650,796,574,837,849,967,696,558,136,336,76,477,773,878,284,397,6,984,881,116,66,202,920,971,786,956,210,904,631,536,681,8,194,161,725,298,354,11,980,280,936,275,851,707,790,844,878,246,384,944,939,160,559,642,679,579,802,560,241,611,526,448,786,636,47,31,20,95,747,816,253,368,811,722,986,303,938,101,294,627,95,511,240,784,507,63,930,262,756,90,39,435,281,984,72,399,769,83,934,825,81,397,685,481,864,612,474,726,80,186,54,336,136,181,124,85,194,472,318,664,243,136,42,850,842,838,328,941,635,297,680,534,806,198,110,612,606,179,10,815,686,667,834,907,480,794,240,262,266,269,34,194,123,98,413,935,187,992,262,837,552,939,687,396,292,491,427,591,522,495,714,312,270,85,111,837,182,941,136,568,377,542,85,364,868,697,251,783,840,287,385,175,850,797,962,681,586,591,314,879,585,467,360,433,523,321,75,280,590,282,500,108,708,322,258,667,586,524,590,477,339,305,316,290,495,44,918,959,279,222,275,448,581,545,698,276,176,859,845,991,664,708,556,790,199,482,151,338,543,465,955,640,541,24,599,693,524,75,245,387,46,489,728,167,777,301,435,370,544,734,829,557,643,633,936,511,859,155,296,350,54,881,4,613,6,463,56,293,332,493,648,321,337,100,503,85,184,64,193,542,648,886,480,505,441,903,552,958,287,820,32,980,856,693,156,27,299,993,461,761,787,739,751,623,39,206,550,389,652,351,827,686,163,723,272,94,335,861,192,488,331,598,19,675,148,489,766,904,509,100,264,29,114,592,217,394,254,141,976,470,525,739,153,443,605,992,135,647,578,559,206,806,830,165,275,537,568,78,731,74,627,125,236,761,430,791,558,66,681,157,246,106,117,441,701,32,261,272,668,156,626,770,425,873,155,866,214,796,515,294,19,805,179,896,669,961,400,939,780,888,925,141,40,392,367,238,631,329,951,519,654,407,238,282,263,399,272,2,263,329,151,464,197,3,372,293,809,602,904,147,922,512,870,209,708,14,189,227,369,101,530,771,336,47,735,55,624,819,339,133,488,515,421,800,727,976,602,51,454,583,70,296,382,182,14,410,70,852,919,204,913,198,817,10,861,531,793,45,49,393,684,220,492,164,217,106,396,473,294,964,97,224,741,21,335,915,623,313,582,652,658,703,717,151,261,4,782,632,211,791,534,560,565,456,291,106,826,552,292,14,461,761,435,328,135,485,906,997,759,435,154,742,808,748,667,248,601,84,435,851,170,682,959,834,777,613,904,303,58,679,877,890,413,132", "668,261,622,583,931,275,772,589,235,742,954,383,40,505,268,500,303,208,101,137,992,129,826,525,673,886,677,550,286,343,328,927,763,959,944,630,963,432,892,944,979,215,607,285,873,317,208,512,101,549,911,900,92,559,709,665,116,96,566,382,404,698,376,811,163,895,973,621,59,497,690,892,408,727,895,447,48,965,411,207,351,39,210,502,998,149,178,130,743,710,588,520,642,851,883,728,218,970,108,879,968,226,740,875,277,431,517,509,906,508,558,358,460,139,324,405,760,209,273,226,905,7,291,240,281,646,203,467,51,877,100,405,782,741,311,762,34,146,874,847,652,245,705,980,414,661,688,394,736,823,256,267,777,355,505,17,482,152,657,518,991,753,631,416,915,295,732,29,179,903,568,115,432,94,194,900,310,228,695,43,275,383,263,192,143,263,375,957,575,777,271,359,99,198,654,947,261,36,204,499,288,318,336,577,882,68,263,954,597,524,415,489,629,491,432,574,520,471,882,302,432,82,702,439,400,358,109,335,361,828,865,833,858,788,648,205,984,866,814,133,970,204,952,949,878,352,37,44,627,670,133,958,787,648,390,475,200,416,767,893,286,177,809,477,964,435,941,328,232,103,427,234,683,272,807,279,169,209,172,315,698,990,210,494,177,168,97,517,266,298,110,28,501,764,764,104,755,214,465,805,716,173,873,292,733,114,320,804,849,451,309,352,151,635,131,94,269,701,825,534,236,424,597,184,702,528,113,869,633,438,324,155,297,671,563,85,248,237,728,724,887,215,497,889,793,671,522,946,40,547,256,177,442,713,242,872,895,404,714,723,205,91,940,322,561,524,234,715,856,236,86,726,71,171,291,9,582,25,59,164,142,463,461,228,31,276,350,789,590,27,237,807,733,204,837,723,742,864,325,690,637,245,386,743,992,571,671,731,543,722,0,928,65,615,117,52,798,82,413,389,722,301,771,363,880,118,393,342,993,49,400,232,978,199,387,156,886,12,186,291,908,371,830,951,729,741,32,617,213,461,585,818,474,237,26,136,145,639,589,420,363,94,527,629,879,894,326,646,642,491,112,599,733,108,58,86,919,215,410,788,306,942,461,494,867,90,680,770,197,420,258,799,61,840,982,942,432,689,430,373,918,704,898,357,425,376,67,788,365,501,359,95,382,196,175,439,802,249,477,78,621,921,635,216,372,465,113,884,400,889,123,858,51,512,278,920,832,2,538,786,143,634,460,900,97,606,608,551,909,624,238,853,637,116,824,619,785,711,256,946,758,706,774,487,190,638,299,692,625,384,261,946,155,927,1000,280,760,723,645,593,593,33,496,468,934,993,231,805,77,71,317,360,626,857,372,362,248,236,749,589,21,767,354,7,523,317,47,112,878,485,321,875,26,153,624,194,63,689,10,538,53,514,110,416,618,560,426,415,973,749,970,173,858,433,349,17,308,809,294,753,356,449,514,207,561,558,17,971,822,28,607,40,651,942,414,76,814,309,458,721,817,471,287,283,661,285,850,686,943,511,193,424,354,215,165,600,296,857,506,531,928,985,783,606,904,154,599,542,488,805,327,796,996,421,354,898,650,756,878,767,307,620,795,302,79,54,227,580,794,513,878,809,692,287,991,36,456,62,442,460,999,152,667,126,626,648,839,871,966,835,116,848,712,535,526,11,728,709,601,132,430,604,275,95,422,404,383,976,587,710,799,750,310,874,652,798,51,477,987,909,679,617,219,124,781,892,52,230,710,403,160,308,240,691,476,733,525,276,367,708,4,686,364,228,289,148,40,438,895,269,274,418,807,455,106,816,39,861,709,537,343,681,508,557,407,162,650,950,334,163,442,866,36,522,539,445,66,127,22,239,125,802,52,406,418,715,656,211,583,136,178,225,47,678,602,485,162,745,72,497,195,859,818,143,741,118,806,798,817,988,893,470,223,616,778,552,527,427,692,632,263,623,606,699,911,590,177,607,272,696,77,473,337,51,463,995,22,530,698,70,18,462,590,757,791,555,796,159,125,653,257,232,689,4,790,906,559,470,623,563,963,226,838,514,510,39,754,222,963,999,472,819,711,348,143,355,770,616,434,298,508,879,664,744,577,965,303,5,538,149,406,552,29,361,168,846,716,882,243,110,358,323,402,868,214,665,999,534,104,91,678,44,541,178,409,752,563,351,189,688,410,802,653,907,399,310,604,707,936,785,569,947,479,334,134,804,737,489,465,312,985,681,348,380,29,940,838,505,668,181,131,849,985,873,80,371,457,283,536,386", "751,326,39,57,35,164,682,351,645,398,164,400,974,933,946,895,625,488,434,352,315,543,594,137,78,953,882,81,33,118,550,767,283,106,232,483,558,169,797,833,315,991,254,472,389,917,782,806,837,942,522,601,112,861,213,216,103,693,196,543,277,966,681,567,896,748,205,596,620,993,525,351,99,373,119,452,161,665,234,635,842,9,698,982,597,596,663,11,636,152,770,556,328,19,520,881,157,653,827,546,102,672,626,119,363,545,698,469,274,110,919,735,680,92,920,979,860,57,84,925,932,305,360,569,610,402,816,406,840,675,810,808,135,362,181,368,912,415,632,732,898,951,495,631,96,960,80,17,767,113,388,110,868,772,724,398,977,503,552,656,996,343,943,946,371,800,438,624,528,103,590,945,373,867,409,829,728,810,87,666,8,501,854,792,219,331,578,412,327,218,841,812,548,860,21,2,452,300,239,771,487,624,212,433,847,437,979,635,35,553,487,799,409,105,868,295,43,190,616,936,937,593,227,542,465,229,713,811,968,190,626,458,868,594,245,696,133,343,508,410,43,105,539,183,407,949,428,780,500,450,289,304,771,986,699,880,230,981,280,610,548,669,248,436,8,227,553,934,499,746,282,777,857,847,412,427,556,362,823,102,338,672,447,858,335,269,306,309,697,964,713,632,445,928,830,79,246,912,419,201,942,423,54,915,802,576,668,87,674,71,696,300,680,342,802,622,381,569,999,838,213,118,615,131,505,791,23,96,152,21,738,27,31,439,781,133,866,749,349,762,512,597,388,123,349,313,856,892,218,395,22,881,618,964,130,584,549,8,618,149,27,799,76,257,178,388,983,723,946,11,883,237,285,246,827,217,774,858,693,374,871,320,117,486,572,685,617,222,546,719,873,865,977,835,575,163,478,569,222,779,877,122,651,474,356,9,931,485,493,465,928,0,917,662,304,900,677,307,183,742,570,952,284,63,7,885,830,474,550,768,662,802,451,505,865,853,961,210,242,775,831,820,366,762,952,445,600,152,551,365,239,385,302,431,456,604,222,543,273,222,236,80,75,672,177,591,484,913,633,715,659,804,950,194,889,318,523,543,842,276,424,882,41,256,765,703,146,801,627,993,883,132,554,460,318,346,524,723,479,90,431,831,892,851,993,392,937,631,314,571,471,173,403,584,322,41,388,132,543,180,547,825,12,999,622,270,786,693,192,49,889,234,120,741,51,997,86,522,390,444,73,717,740,704,992,616,981,217,240,160,106,877,691,153,424,323,371,392,544,696,319,141,723,670,464,87,673,256,972,997,346,159,630,688,486,90,765,95,222,277,724,732,959,362,630,468,246,61,775,959,743,404,43,242,882,215,731,741,469,591,805,52,160,828,266,310,656,497,128,997,619,248,655,402,454,73,928,798,338,274,917,334,173,320,281,360,160,905,360,382,279,739,813,553,809,284,508,833,374,507,24,458,145,980,466,481,95,63,807,403,427,928,220,573,512,448,810,478,949,137,313,71,788,226,170,110,232,227,868,693,347,28,724,308,144,39,9,994,882,504,718,462,781,781,876,858,35,583,869,897,794,371,128,161,259,167,76,335,973,239,717,442,710,517,302,894,980,267,261,383,912,446,725,131,438,222,251,547,368,452,932,116,465,203,178,892,124,930,244,531,799,464,989,577,467,721,744,988,717,309,145,65,829,466,135,271,217,457,950,893,360,473,332,838,512,557,331,743,676,24,667,475,505,637,665,486,791,372,820,203,214,718,922,708,141,817,124,220,468,63,117,760,762,740,891,455,104,395,41,828,752,866,211,125,790,694,602,445,347,729,676,114,342,640,593,132,326,560,415,218,739,705,357,574,680,565,192,103,816,610,651,331,893,378,842,839,766,758,151,815,722,220,907,602,458,65,501,98,145,362,391,534,224,807,641,672,989,469,933,951,755,593,965,236,473,268,650,999,790,462,313,516,59,841,933,886,758,271,704,508,106,429,843,264,525,322,408,69,190,287,852,879,81,250,988,888,823,265,546,64,426,840,915,105,119,461,75,595,898,246,399,458,191,963,706,996,729,69,621,106,638,868,580,484,533,608,714,186,136,538,134,594,571,647,205,722,602,804,362,677,612,472,636,879,806,847,73,911,688,259,212,485,520,832,340,404,322,169,63,13,283,968,931,934,596,303,265,859,428,913,987,52,846,204,927,12,640,260,677,448,176,485,822,525,295,538,340,135,334,471,536,798,506,460,664,120,263,794,426,325,254,391,418,939,638,308,885,734,781,648", "195,272,447,407,304,28,688,5,375,55,398,185,795,643,672,602,132,579,46,812,455,842,125,51,211,798,262,474,726,692,841,217,930,258,517,387,790,782,304,101,701,562,260,95,500,453,801,845,15,110,208,413,757,532,727,186,962,413,697,125,693,271,991,679,710,758,434,641,432,727,702,356,535,874,608,904,325,439,630,829,145,875,665,225,78,821,105,900,116,987,650,547,424,76,120,3,835,334,186,49,192,688,333,835,787,794,471,620,78,98,881,69,872,411,987,678,358,49,888,256,856,674,334,592,348,144,701,927,628,777,584,660,367,731,912,619,406,617,87,549,797,546,20,186,32,782,76,303,34,676,106,46,960,560,313,425,88,862,117,591,809,644,92,1,467,333,510,540,766,422,375,701,192,113,282,849,741,805,597,425,793,182,493,479,270,966,490,152,135,649,646,235,523,897,547,506,734,234,18,467,660,14,368,552,651,805,917,516,492,860,169,911,471,338,346,384,499,505,173,713,957,124,701,125,202,195,705,436,94,392,411,679,347,476,376,972,101,65,763,506,10,333,957,216,58,69,84,577,548,884,596,602,523,150,325,676,425,188,525,457,979,529,903,186,281,259,563,434,762,450,671,738,334,719,914,866,889,11,51,329,47,239,814,46,329,961,604,978,100,956,857,827,696,635,852,128,542,410,374,991,954,482,114,696,917,764,726,74,402,220,620,551,50,797,3,577,665,975,865,238,396,786,764,637,696,752,799,522,4,664,32,364,394,80,64,730,69,741,992,833,78,221,314,969,595,815,126,307,987,229,398,939,839,578,808,131,975,179,115,102,188,436,903,406,129,372,242,689,329,109,674,504,917,681,33,382,727,322,176,650,111,108,728,78,432,928,243,403,459,99,26,830,958,142,926,570,254,929,135,807,904,772,881,913,125,128,399,429,439,357,65,917,0,825,139,994,370,739,3,19,742,140,346,559,919,698,949,891,186,737,722,189,472,724,903,130,469,787,593,529,86,523,334,715,181,436,349,916,220,751,784,196,834,86,953,991,161,482,585,647,157,959,104,473,222,946,41,230,457,472,637,429,874,814,782,44,702,455,457,761,466,35,382,597,839,308,276,454,712,376,748,959,620,715,136,780,607,689,461,154,473,343,385,481,885,49,773,529,541,784,674,316,705,319,38,489,841,429,662,185,237,650,723,641,62,42,429,880,359,338,604,595,6,321,198,624,577,889,15,641,612,107,855,749,941,518,176,391,4,740,291,928,675,941,962,672,252,98,208,53,427,724,749,427,948,441,531,667,870,94,191,838,681,878,644,787,784,346,646,593,107,545,14,382,930,496,10,973,188,633,83,340,573,104,216,861,375,470,578,136,357,776,272,439,860,160,368,442,369,833,308,261,930,564,22,455,755,11,108,652,827,930,941,42,111,910,842,440,185,312,632,556,37,756,974,691,950,428,745,901,66,451,222,953,242,856,917,618,182,245,890,585,718,291,733,895,318,459,298,705,920,374,85,992,951,330,897,152,117,645,521,124,386,677,583,948,745,453,495,119,443,211,34,631,723,765,790,212,789,552,490,691,677,332,570,243,21,699,581,355,529,110,51,386,235,330,906,920,8,695,478,746,206,784,920,955,337,677,77,214,707,55,947,754,994,647,505,677,375,52,94,850,359,330,415,236,660,403,111,343,496,681,419,117,592,81,945,861,767,32,73,367,122,381,687,1000,506,767,970,343,733,751,697,376,826,539,55,37,465,30,982,483,339,413,745,421,768,664,136,163,322,687,674,993,910,470,624,333,612,384,487,410,27,308,775,611,54,710,676,541,857,328,637,408,384,546,889,73,216,550,285,26,71,777,111,808,454,170,523,749,279,580,618,443,594,342,939,68,778,463,174,329,582,105,589,816,448,303,997,961,995,171,739,239,207,847,765,261,773,115,730,635,950,992,190,176,636,152,830,770,909,445,264,119,722,469,472,61,396,597,781,308,43,7,692,819,63,768,462,194,3,457,376,198,49,576,427,113,237,441,641,754,549,782,182,49,460,561,526,758,488,307,606,280,227,627,953,567,916,192,616,98,729,614,150,861,955,835,988,545,724,961,976,960,743,429,470,529,164,825,43,764,823,780,911,316,920,171,506,201,795,384,995,926,764,208,345,483,856,518,595,493,745,813,428,816,618,40,49,771,525,500,451,55,911,926,235,773,121,120,301,107,993,372,591,859,89,750,505,210,164,118,614,774,505,328,207,102,197,185,451,918,991,197,780,286,830,586,398,404", "678,780,898,584,724,379,692,560,135,211,629,859,968,159,968,94,704,420,695,100,260,911,477,459,747,464,530,310,102,965,860,566,39,184,351,285,299,678,444,916,351,775,930,749,227,305,563,375,52,880,389,611,642,891,824,901,970,167,749,994,924,212,582,58,7,719,194,171,126,813,528,89,379,942,806,388,205,355,937,522,369,638,897,54,209,842,973,237,781,854,88,898,889,96,582,101,111,950,557,60,521,790,805,733,751,248,327,441,911,800,860,125,504,193,20,246,393,474,1,51,997,765,778,968,272,950,398,889,956,649,987,21,637,498,733,715,511,949,950,562,217,434,224,116,587,1000,760,337,256,955,279,662,614,508,123,863,333,68,895,905,524,581,397,446,579,911,233,768,347,212,713,494,241,491,950,117,660,636,440,88,519,460,956,891,562,860,589,693,94,231,259,326,753,79,97,127,902,237,13,818,413,392,121,84,853,5,596,540,553,453,668,234,727,966,645,274,265,244,44,552,547,421,779,723,740,100,73,519,226,269,579,35,597,861,13,337,260,164,568,842,158,378,452,180,371,187,620,480,884,519,703,527,625,762,73,81,376,782,980,808,491,541,158,250,86,256,573,242,739,896,159,800,884,622,532,827,235,603,627,558,711,937,779,537,498,876,652,158,472,976,546,269,676,751,552,327,964,123,410,843,784,432,117,482,361,140,204,990,384,915,768,976,374,562,810,835,612,489,791,200,809,361,831,958,103,903,473,402,928,359,444,389,804,352,32,86,15,745,112,188,454,728,60,787,412,712,251,36,62,81,716,321,919,393,218,619,58,491,227,56,919,440,138,44,157,59,949,774,163,914,182,115,439,596,401,795,695,355,973,510,332,590,818,673,474,670,910,471,405,221,814,649,524,140,273,869,202,188,472,126,663,940,156,296,866,198,665,131,173,853,615,662,825,0,241,803,64,363,199,60,650,868,480,70,207,37,348,690,595,601,276,864,267,616,458,555,9,16,401,910,275,585,744,265,593,672,404,653,183,426,89,727,500,814,468,397,243,576,87,938,509,794,486,958,251,497,2,668,69,137,323,807,178,847,887,402,632,289,58,789,794,70,265,268,705,190,735,446,769,573,395,807,749,957,559,780,906,458,811,313,203,524,938,235,600,205,371,648,209,700,291,374,196,901,741,122,795,858,499,709,224,853,142,976,477,506,20,188,463,138,405,597,763,641,294,923,869,560,137,698,681,99,39,884,813,680,824,269,766,624,270,723,118,608,859,156,311,423,887,877,587,927,395,255,35,613,679,445,443,958,362,181,606,855,252,956,236,860,150,790,225,210,862,171,709,976,462,688,31,786,525,541,616,973,632,899,89,190,593,138,457,359,261,724,391,428,89,563,505,221,598,27,385,398,494,688,505,118,702,879,231,996,388,752,913,740,209,190,877,779,899,888,860,478,250,554,185,144,174,491,330,925,656,165,395,273,901,749,402,658,363,96,621,343,646,252,671,719,315,920,285,657,578,478,824,977,531,95,421,323,924,632,953,170,836,172,272,741,896,342,720,632,729,260,345,677,529,568,462,46,690,836,95,961,724,462,653,717,79,508,806,932,464,922,647,457,424,868,707,48,967,474,579,737,601,112,346,533,720,393,703,249,527,311,743,338,200,459,434,980,506,786,380,492,373,409,775,186,624,256,841,266,691,12,77,538,929,931,194,146,492,525,811,128,359,667,256,895,621,718,548,537,522,521,198,828,196,59,873,216,602,807,83,349,10,657,121,189,291,883,427,137,918,877,292,700,596,342,377,460,598,421,223,837,243,800,57,628,565,620,716,257,332,511,668,437,555,353,60,714,861,552,111,231,782,448,274,19,117,215,953,173,322,157,85,598,377,188,654,856,465,576,453,755,450,244,150,888,879,113,161,206,297,264,365,318,924,13,593,990,921,245,597,461,71,517,148,481,347,180,64,723,506,966,373,585,205,98,655,333,75,191,915,103,353,590,652,888,657,43,99,198,106,968,101,558,669,244,167,894,387,979,119,716,24,457,662,163,368,174,119,133,692,73,930,536,289,559,224,434,376,867,756,945,673,340,361,436,221,721,509,972,239,118,896,744,874,313,37,76,485,875,223,336,926,117,34,886,328,946,819,306,637,943,724,93,220,865,143,493,450,561,863,251,967,601,480,955,146,274,92,405,705,781,586,332,349,42,171,761,682,755,950,476,593,253,433,772,960,1000,964,705,884,384,453,804,738,926,954,520,687,974,413,561,128,999,528,779,859,585", "848,568,759,442,451,136,676,146,284,326,624,801,514,360,366,252,669,545,471,153,997,886,457,631,396,492,412,345,919,501,618,750,847,763,754,280,654,383,433,326,296,991,169,97,746,148,173,303,955,558,912,203,533,565,434,911,553,19,857,166,187,638,347,404,651,769,131,302,445,581,217,70,454,23,869,915,585,144,778,5,304,424,56,124,972,231,878,929,19,214,29,830,970,977,772,961,196,564,347,459,421,298,771,65,903,529,618,554,966,832,157,44,790,186,172,570,340,392,816,536,677,791,890,955,534,899,728,641,845,98,885,185,167,966,515,981,592,58,74,323,732,848,812,759,164,892,50,931,414,870,295,571,342,90,913,578,446,971,488,623,643,596,570,100,370,920,339,162,629,605,197,467,219,185,96,636,397,540,609,600,85,321,348,286,337,475,558,494,893,301,482,122,983,54,555,89,987,716,567,457,647,189,103,211,230,532,651,19,572,666,271,411,502,576,204,174,282,474,811,463,797,749,484,91,393,151,489,801,816,778,795,21,84,683,718,216,216,173,111,179,350,525,990,726,306,111,444,733,867,161,30,671,672,102,999,920,960,230,421,520,301,782,671,73,617,599,188,177,251,863,743,751,610,539,479,970,647,282,349,793,264,521,532,282,21,521,835,277,776,501,588,756,634,618,726,558,240,338,312,328,591,557,766,996,260,837,187,100,897,544,433,868,233,641,769,563,351,387,123,998,771,20,985,793,605,56,979,554,90,315,234,810,856,629,711,433,661,77,828,284,685,399,664,36,566,924,314,578,288,320,245,304,153,976,329,620,904,632,893,981,850,975,550,964,722,964,425,827,861,109,302,417,255,648,338,975,569,235,184,766,741,685,905,643,260,56,863,706,735,481,782,893,662,685,175,114,924,368,126,8,503,796,241,690,360,124,408,745,32,853,117,304,139,241,0,495,316,761,389,297,22,454,851,316,241,594,645,579,716,8,922,398,919,444,545,356,682,27,952,525,185,278,901,822,818,266,148,297,509,485,272,197,681,703,335,163,153,869,107,725,859,972,282,329,702,527,88,196,423,34,613,537,46,683,288,147,560,755,607,966,653,403,786,792,456,511,315,933,114,589,309,697,80,402,903,360,754,991,184,993,793,541,968,180,200,12,756,539,427,630,420,836,739,757,60,909,86,129,864,36,220,764,598,658,202,796,951,938,837,862,718,163,387,32,742,709,498,48,282,979,394,707,440,755,496,777,139,516,859,358,161,773,897,212,588,145,741,28,597,261,636,340,110,896,590,382,170,121,199,13,757,729,841,363,375,776,66,342,800,182,219,753,122,803,575,590,951,124,36,103,968,162,497,644,691,786,890,741,292,364,840,201,402,991,659,695,89,371,959,604,369,360,907,192,568,357,787,320,451,87,628,446,735,944,409,751,371,650,766,266,655,50,745,397,441,881,901,975,907,535,627,66,777,330,638,595,575,414,726,533,35,676,439,713,557,312,975,839,48,740,148,146,104,94,92,286,81,316,582,173,745,850,402,282,614,811,670,710,7,68,23,101,915,267,140,455,850,419,265,195,182,61,99,660,446,539,71,718,500,553,633,375,170,85,989,83,697,197,379,524,502,582,806,948,647,441,479,167,244,722,388,603,336,7,15,636,80,748,776,161,826,224,708,664,68,169,83,797,442,674,804,492,637,575,192,504,651,518,411,673,396,485,467,80,696,955,661,143,320,664,360,806,816,950,739,498,197,555,63,845,898,718,520,947,266,91,870,423,976,595,819,656,533,251,68,169,87,533,975,823,162,428,631,788,922,726,785,14,333,616,850,82,722,797,274,854,189,244,659,236,182,127,902,40,12,283,57,215,833,772,272,465,935,301,542,172,573,724,112,278,608,210,5,459,233,963,553,884,194,883,356,405,254,845,141,765,734,846,297,658,478,246,714,784,331,408,277,936,157,871,440,467,265,865,100,183,268,827,53,14,386,557,302,869,439,102,952,12,241,990,725,622,461,483,726,233,40,24,514,664,770,550,843,986,897,735,587,579,359,522,342,592,425,104,116,879,190,863,441,60,882,466,181,814,992,474,19,373,976,384,667,6,856,896,152,605,337,148,746,352,311,204,740,913,771,951,455,312,625,301,158,509,128,942,857,675,936,765,950,607,365,400,291,249,394,833,148,292,538,467,65,190,213,595,414,524,965,786,127,74,420,857,720,2,45,60,622,269,797,121,530,67,231,392,399,958,978,151,477,618,904,715,735,517,926,595,872,242,606,177", "764,295,749,766,305,194,177,226,242,388,388,740,310,731,739,165,805,219,700,431,245,498,844,72,835,840,428,120,910,533,330,46,898,869,450,76,955,177,699,754,446,722,462,423,74,917,254,197,935,165,341,158,139,879,431,256,446,804,669,95,725,544,422,981,870,248,228,879,979,920,263,932,93,239,271,776,846,113,772,851,915,24,678,429,833,494,702,465,905,200,491,370,95,222,106,90,103,84,322,573,666,426,776,52,39,101,274,540,578,858,366,766,277,796,100,371,593,12,627,637,37,42,716,481,918,627,754,230,510,460,88,805,743,594,313,238,567,43,52,775,625,172,362,641,705,1000,640,697,71,708,417,833,534,903,362,29,363,584,463,283,278,299,571,355,724,619,175,739,244,294,486,41,307,697,636,160,483,488,315,294,502,680,566,32,821,581,902,816,757,815,370,876,203,170,373,964,421,112,661,439,699,112,584,16,302,266,600,616,250,197,172,144,252,847,822,866,568,37,270,894,261,337,75,964,81,982,537,98,217,104,296,222,64,659,295,127,385,745,289,209,119,992,400,500,638,573,990,912,61,756,923,694,235,971,468,152,621,124,593,192,213,418,619,872,757,45,748,201,785,257,921,339,896,973,691,705,735,245,702,132,658,59,650,899,644,194,351,504,472,374,386,87,835,38,931,629,450,86,572,739,93,725,99,411,30,682,811,844,754,950,11,768,419,951,414,795,938,598,240,296,748,988,370,159,802,88,603,968,594,884,385,400,446,211,957,666,224,906,276,82,465,288,891,733,268,975,316,460,120,184,990,656,232,924,273,464,428,46,445,418,843,226,170,488,349,596,785,915,786,313,459,397,54,426,91,149,27,107,701,618,801,711,84,366,827,239,741,314,574,137,462,916,25,211,911,101,738,890,513,833,522,381,680,870,692,346,872,216,159,191,52,900,994,803,495,0,740,412,815,242,8,838,861,942,545,349,195,888,683,216,934,851,16,650,178,280,562,396,261,627,538,550,559,102,21,551,526,757,433,436,142,241,558,866,300,86,628,503,529,432,483,542,261,443,174,869,845,195,794,268,778,625,471,504,792,639,860,362,961,300,143,540,163,729,252,147,655,394,630,503,95,249,549,939,129,135,592,52,760,292,584,642,345,517,130,896,835,679,640,565,827,892,325,666,991,698,94,767,798,443,829,706,62,22,146,836,484,952,791,112,392,227,377,389,620,835,703,896,681,53,223,833,926,419,284,338,154,390,847,794,346,174,557,201,732,824,450,702,128,204,468,651,483,863,458,859,69,728,606,164,483,452,301,450,146,782,753,751,781,284,635,910,112,266,732,850,317,626,804,281,789,194,750,523,214,35,556,701,536,824,697,754,859,724,470,765,550,478,820,276,658,702,22,664,728,286,236,575,315,239,569,57,988,718,881,868,768,221,244,70,120,618,581,783,336,556,864,216,873,283,194,694,492,111,584,745,582,799,771,716,751,228,614,934,979,539,383,678,891,275,785,897,251,11,378,48,620,19,171,914,191,687,445,644,539,47,518,663,860,997,171,651,994,448,855,685,671,450,66,512,778,863,627,751,719,609,61,63,346,786,720,520,95,17,221,284,385,696,817,447,895,107,350,729,222,366,738,701,543,643,565,527,52,547,23,722,394,744,82,845,305,88,731,865,416,452,690,618,938,798,523,449,594,625,303,495,926,599,54,710,637,315,533,82,434,42,722,817,106,16,105,523,43,359,915,127,727,11,60,320,861,923,384,665,842,948,837,404,200,810,234,503,811,782,229,9,653,958,955,60,30,365,491,626,822,813,793,48,46,359,909,67,480,850,303,737,822,794,743,920,719,959,172,840,715,664,41,868,918,934,214,437,237,244,770,930,562,882,74,148,382,1,519,127,236,996,341,873,222,778,140,218,126,938,480,47,821,914,849,459,562,98,283,149,404,999,486,422,462,883,714,72,70,38,610,104,943,64,956,204,623,612,928,282,928,924,823,695,113,123,748,968,232,442,829,467,905,247,16,510,117,246,255,173,225,701,688,796,562,399,827,661,657,324,524,904,227,198,335,973,856,507,8,493,757,244,196,206,36,240,760,672,932,118,182,535,238,996,450,531,51,81,886,233,146,892,106,938,402,600,256,431,732,478,748,550,915,674,764,648,507,166,764,717,182,997,782,473,244,678,550,171,251,431,907,473,650,63,316,90,636,554,236,983,738,852,731,656,195,553,414,515,55,203,27,452,700,806,149,650,511,202,211,598,873,513,128,660,532,356", "888,597,103,895,491,322,308,139,533,669,530,171,426,251,986,947,695,237,892,882,368,721,58,37,216,344,664,156,306,737,998,632,416,341,900,319,715,868,911,777,569,998,545,665,166,733,515,354,885,415,120,782,522,755,47,483,952,690,49,206,334,84,380,23,637,32,114,308,138,537,801,280,480,674,975,315,29,857,466,448,374,353,43,834,997,375,668,926,328,942,306,525,47,461,706,336,292,37,860,40,229,720,184,980,946,619,131,573,926,223,300,790,337,495,79,438,803,374,408,582,140,945,141,869,385,91,243,817,257,418,87,755,821,391,151,467,750,822,755,869,371,339,429,535,738,247,786,948,941,539,703,786,896,60,179,485,570,647,387,964,156,267,220,996,702,152,936,438,490,591,827,760,515,554,115,943,441,590,452,71,810,725,835,506,794,610,231,987,226,841,906,117,73,831,751,985,453,477,908,750,342,482,819,383,184,18,269,956,363,553,448,892,155,642,326,918,215,53,625,229,727,650,818,309,895,281,824,108,937,563,860,472,225,671,130,966,715,359,695,662,835,159,18,409,730,308,589,409,418,81,296,284,892,594,412,943,948,645,925,97,651,660,614,77,808,829,918,736,968,795,994,45,599,425,406,702,277,668,191,80,105,703,799,412,564,414,341,6,992,374,983,684,506,108,475,250,953,589,17,626,264,139,663,342,126,62,619,480,795,510,899,364,298,352,325,450,445,360,188,425,580,135,388,154,430,427,972,429,294,487,414,509,793,725,688,291,641,34,379,225,289,508,367,747,902,421,347,159,905,43,34,530,492,403,839,492,354,935,686,278,449,890,601,449,599,58,726,890,863,531,591,727,158,335,972,579,150,241,610,185,16,257,767,308,54,922,129,251,645,790,309,480,338,15,525,312,87,224,759,113,47,255,568,795,121,421,854,928,173,145,798,677,370,64,316,740,0,66,355,711,156,891,555,817,477,517,413,927,712,427,50,409,355,682,32,685,412,888,291,456,483,744,47,281,745,331,630,941,583,88,814,757,40,465,660,6,409,2,59,178,611,349,998,821,261,536,506,993,342,786,418,911,178,653,283,972,357,987,185,567,700,564,413,149,642,475,216,370,488,900,301,537,375,549,539,560,162,841,689,970,788,548,949,805,314,253,733,862,713,46,848,758,494,697,927,27,199,348,958,500,231,691,759,467,142,828,322,23,719,92,977,45,944,223,25,323,874,28,535,36,953,152,522,45,876,967,207,118,313,994,62,213,463,290,48,931,105,522,41,267,504,994,231,211,883,528,261,341,568,874,504,385,84,36,927,784,5,239,313,717,145,773,182,474,90,284,956,523,558,349,230,753,829,546,865,957,564,747,874,42,167,145,975,317,83,620,230,549,268,874,142,982,563,349,763,686,87,434,102,287,836,322,245,592,652,903,538,929,7,94,525,560,44,137,836,527,521,431,774,247,759,799,805,51,195,252,249,927,279,882,447,969,383,756,708,139,513,824,606,975,309,77,59,268,364,111,464,321,198,521,249,942,778,901,807,472,756,342,718,173,222,478,831,391,456,912,994,227,345,851,234,2,815,484,749,109,703,32,653,178,898,220,498,283,914,740,422,585,106,50,590,567,876,974,457,57,55,589,951,574,127,555,646,470,44,26,48,303,233,939,456,96,859,324,998,95,79,46,358,43,229,937,886,216,537,17,7,41,78,910,835,786,531,303,271,84,616,586,207,792,571,262,585,379,326,661,706,642,445,405,952,863,862,419,932,773,838,844,714,597,100,836,836,610,158,446,588,829,835,677,242,833,114,427,464,413,83,167,868,150,108,545,386,295,577,934,454,907,814,125,719,972,876,610,608,73,148,774,942,785,926,635,243,492,973,808,154,169,934,430,276,708,552,258,417,267,90,391,190,631,130,343,579,464,541,577,38,939,126,333,168,851,411,916,518,498,430,63,74,473,495,732,197,489,392,825,992,323,158,931,350,504,421,282,506,992,698,574,683,542,241,458,651,497,223,111,589,977,414,764,204,633,450,512,62,678,27,486,637,800,587,510,473,808,906,656,944,99,743,436,630,627,264,41,38,623,235,888,938,921,129,599,722,768,123,239,585,283,898,80,758,390,249,990,200,960,658,841,651,698,413,739,840,86,315,387,242,299,33,15,45,487,692,21,60,912,445,32,337,642,597,920,588,207,774,989,365,317,81,499,771,750,871,415,697,821,465,831,976,50,743,659,807,426,983,380,985,92,480,37,828,80,679,549,984,406,738,630,515,603", "40,704,341,420,572,483,504,8,184,331,579,975,439,782,160,205,592,325,140,246,792,572,905,800,882,838,233,917,815,32,414,113,37,793,519,769,521,988,311,431,475,361,711,321,966,36,57,339,534,626,192,969,669,389,63,36,635,473,470,887,854,406,928,659,151,216,965,803,879,252,527,20,446,605,30,678,893,78,639,627,600,302,921,635,874,174,402,119,600,186,611,735,256,181,326,185,390,865,98,252,228,861,409,693,638,416,675,770,978,697,154,796,436,301,865,846,61,841,556,191,922,439,584,375,350,263,52,355,915,305,301,12,195,450,886,560,633,717,265,422,685,40,747,559,893,636,325,870,756,77,740,475,766,546,488,457,426,752,707,836,420,634,509,108,315,415,30,913,572,280,393,663,37,376,336,704,749,589,732,63,549,693,529,486,618,668,893,136,295,483,405,990,430,219,513,266,115,408,175,104,228,672,713,195,842,603,811,269,786,658,619,570,104,687,407,351,726,390,423,485,998,214,584,896,8,95,996,229,739,89,456,916,444,639,309,318,863,314,117,295,847,505,368,732,953,138,271,171,598,355,266,334,210,204,732,927,314,497,135,379,325,938,65,852,894,61,742,262,939,80,979,252,124,275,95,446,230,368,534,385,509,223,113,805,632,405,66,100,979,842,526,737,48,926,295,393,839,596,644,886,339,900,350,450,223,466,964,147,556,809,343,52,610,544,165,650,906,153,910,868,39,311,625,187,149,918,38,731,597,689,647,725,290,228,52,107,140,274,436,961,251,863,886,127,144,852,961,713,483,85,282,470,904,470,703,827,733,88,837,962,562,624,721,76,21,47,374,875,891,893,576,91,816,419,127,871,533,580,349,249,574,256,805,682,398,410,293,67,241,497,542,852,47,595,437,55,308,888,439,787,497,117,379,995,912,795,888,407,536,519,82,307,739,363,761,412,66,0,748,693,712,258,425,617,923,505,490,846,516,626,182,778,601,251,417,126,360,432,80,725,672,373,377,121,539,542,256,309,795,826,372,9,661,317,68,216,73,202,616,854,500,402,321,457,534,856,283,804,261,379,332,545,881,533,816,574,465,284,145,727,816,958,710,930,851,967,127,205,521,606,451,162,3,280,722,400,440,696,349,85,220,869,826,561,44,603,532,751,998,233,714,792,965,891,277,479,545,82,652,412,935,518,406,922,863,404,357,532,257,969,162,170,862,625,362,726,907,899,728,734,458,864,123,248,997,899,509,307,829,82,181,784,930,264,244,858,564,647,845,980,707,612,236,799,576,963,961,563,834,557,349,550,346,311,334,568,369,733,957,420,395,701,288,959,154,41,30,867,559,355,123,588,217,938,937,443,119,908,463,718,403,704,102,468,735,614,41,692,828,895,884,692,623,516,511,954,520,12,792,454,342,426,754,932,15,985,973,481,166,718,200,884,167,968,872,536,661,735,835,592,322,672,623,768,747,135,952,695,817,88,223,121,598,429,98,406,102,128,943,153,952,604,237,758,360,971,151,996,448,686,163,517,407,456,613,201,271,855,189,494,964,460,312,36,970,795,635,665,805,458,591,465,743,267,740,384,480,204,404,389,190,85,728,629,167,344,543,762,884,521,515,516,92,91,539,747,327,418,352,68,410,927,852,843,113,812,46,637,489,918,718,146,238,118,492,976,651,190,367,357,131,471,264,104,112,456,423,619,152,963,178,695,902,375,112,125,402,876,472,106,845,219,773,439,470,455,498,47,43,587,742,558,836,535,892,526,371,267,513,121,280,336,91,124,460,449,994,262,421,788,341,535,315,67,53,257,487,463,934,635,487,321,960,123,606,530,56,269,512,747,587,552,66,242,846,833,208,22,658,287,902,238,258,467,140,414,773,273,740,62,731,135,870,476,339,36,427,671,995,562,505,221,845,652,379,789,80,398,875,656,284,986,272,31,972,955,332,520,549,143,587,609,735,759,678,378,798,657,539,915,985,479,800,202,635,200,845,191,174,10,16,564,949,784,922,242,739,120,894,965,242,230,789,53,419,476,584,116,146,846,165,85,533,415,335,778,867,262,477,209,276,845,207,698,912,804,291,319,493,442,74,171,857,611,235,429,530,457,527,147,399,291,236,671,680,589,499,462,973,398,238,871,492,508,514,140,674,606,575,503,869,630,994,875,36,197,541,503,588,990,294,817,31,258,532,859,420,636,531,727,298,56,826,845,27,423,635,514,939,382,143,55,782,321,939,507,817,350,623,360,231,230,458,207,492,465,716,87,551,523", "291,46,435,238,297,572,586,984,334,536,497,7,872,210,245,187,950,390,501,920,772,584,368,213,734,450,391,37,860,156,400,729,802,262,407,902,196,270,905,61,652,902,889,446,541,260,487,544,404,222,611,782,128,382,281,349,615,694,132,823,210,349,307,28,967,498,57,94,45,228,275,137,928,828,554,271,988,633,213,86,210,768,552,600,825,122,317,123,420,866,448,85,408,249,782,807,278,318,609,934,290,594,638,793,262,107,988,527,762,762,662,458,105,345,950,577,806,789,144,968,677,466,745,774,618,686,569,110,22,83,479,909,94,799,825,737,128,584,911,805,542,791,472,702,661,507,125,648,773,266,259,758,454,69,706,303,86,421,218,850,24,344,923,246,174,851,160,28,453,251,748,980,176,712,616,92,293,475,310,44,20,850,977,565,902,510,540,486,801,650,515,788,704,258,190,429,84,481,123,184,429,890,653,205,922,622,520,812,62,173,462,177,510,434,787,844,683,408,854,864,351,513,629,875,693,111,523,695,643,158,222,216,179,784,872,494,836,26,507,484,499,980,392,151,373,492,508,604,142,60,198,698,701,767,487,264,622,391,753,800,461,246,719,968,629,649,208,232,601,651,265,144,303,514,138,753,550,199,244,961,252,352,435,389,17,218,306,945,359,940,124,369,70,68,424,803,900,201,553,671,375,628,433,234,13,613,267,18,965,404,998,813,8,748,603,294,467,739,610,880,243,757,697,351,422,318,63,571,688,287,822,925,758,685,690,355,181,257,561,233,868,863,434,587,815,766,392,690,388,41,822,291,964,859,863,524,315,368,244,232,744,360,323,766,383,761,330,316,185,186,450,925,919,367,122,892,294,456,379,908,412,405,562,497,487,942,395,589,507,534,207,326,585,286,838,391,938,600,615,615,109,371,710,416,924,859,67,15,445,32,413,183,3,199,389,815,355,748,0,338,411,82,158,835,457,840,752,348,670,7,715,880,217,460,252,393,81,237,607,548,885,424,740,418,247,872,952,43,676,165,7,887,461,236,847,417,290,316,17,948,654,120,222,172,426,474,221,243,52,706,388,693,825,222,579,690,202,106,720,566,182,440,337,716,396,750,440,914,14,273,365,213,114,370,779,680,100,514,370,951,433,837,379,314,55,584,162,701,872,306,541,673,931,282,349,735,451,355,820,288,303,225,853,200,583,572,142,841,698,797,722,85,743,338,983,771,257,546,95,587,811,623,85,749,88,373,952,175,631,857,805,169,790,805,2,107,449,555,342,325,469,604,22,431,786,384,451,402,204,975,94,27,647,380,44,888,55,633,33,591,888,195,272,870,210,200,145,565,812,338,929,101,502,113,566,602,475,127,825,655,89,496,623,925,639,726,451,831,657,401,112,200,950,33,973,945,33,172,710,836,981,318,908,3,735,567,57,266,893,990,450,393,395,849,412,416,896,182,595,233,352,104,549,367,963,937,72,694,429,934,458,943,43,398,187,235,564,779,747,689,376,339,933,760,303,309,577,387,489,674,420,332,808,399,272,395,599,149,300,303,840,508,318,39,96,86,242,666,518,531,140,539,653,851,409,435,178,422,135,863,378,147,698,440,494,616,641,735,711,114,417,845,513,652,575,305,687,125,742,253,373,148,228,807,489,979,95,918,471,605,501,172,16,927,788,493,875,670,25,389,930,690,892,308,699,836,742,624,578,485,980,755,501,388,270,466,119,872,842,251,380,299,418,93,752,639,985,173,168,668,409,870,734,184,800,97,344,773,888,235,986,206,660,47,520,859,253,910,311,830,281,307,499,709,974,404,979,957,620,962,678,318,906,999,638,636,196,877,650,317,546,855,550,456,347,745,745,205,277,872,58,629,832,419,959,297,597,458,622,296,115,234,638,323,742,397,154,873,86,630,287,70,353,106,341,955,245,249,942,454,115,50,256,141,39,352,866,626,485,341,180,286,483,51,135,514,118,242,289,956,841,802,907,990,999,898,987,841,891,893,704,688,857,233,980,869,229,435,108,927,694,387,901,863,173,846,455,311,676,520,694,26,688,957,389,594,959,447,996,543,650,991,359,337,733,302,169,370,79,65,8,884,917,7,764,290,801,638,974,767,751,763,171,423,128,845,617,215,607,779,194,323,410,934,91,784,418,105,870,209,820,718,684,412,927,413,318,166,261,164,657,687,988,603,997,801,314,388,215,254,262,816,920,389,797,438,78,856,536,356,795,469,887,158,335,187,377,431,192,338,8,298,277,896,47,259,340,32,36,370", "456,768,900,492,716,630,118,354,573,181,945,124,339,339,339,787,914,4,586,407,50,523,4,707,419,499,490,238,942,671,939,983,971,912,847,47,924,776,934,223,49,495,291,497,331,498,603,949,659,91,16,838,647,474,217,711,183,434,456,373,579,532,268,815,712,972,33,504,585,747,59,839,903,598,820,76,153,238,548,71,105,929,646,803,856,533,234,735,414,959,616,382,716,291,595,851,277,925,528,493,654,698,463,415,83,679,336,231,47,573,626,123,716,602,55,361,815,132,600,352,890,346,996,790,976,893,764,901,640,686,818,630,966,959,961,307,910,818,872,651,608,890,877,419,270,338,26,136,329,350,530,353,172,470,300,963,314,586,509,395,211,624,374,280,271,152,854,407,629,21,82,627,237,826,280,30,141,963,374,720,448,438,366,832,828,336,190,613,934,959,715,22,349,694,887,868,514,163,543,291,214,165,970,992,831,855,881,764,290,666,827,845,906,503,480,634,745,880,529,626,4,116,273,712,16,591,360,153,660,763,170,979,898,42,376,429,303,994,464,665,947,925,368,835,775,559,990,42,517,549,120,574,570,277,162,401,558,37,791,75,629,54,971,586,597,224,731,31,840,723,111,879,172,151,231,422,460,961,451,656,104,770,517,198,236,178,672,376,362,465,110,271,91,885,603,444,820,146,863,557,809,642,773,24,112,538,248,438,952,250,803,116,989,24,787,702,758,493,529,217,542,513,968,228,220,89,959,917,656,911,780,915,641,53,185,338,316,421,849,820,26,747,573,800,515,745,252,755,578,837,742,138,900,665,235,524,925,309,528,528,613,724,334,299,300,191,175,779,94,966,476,974,610,572,571,224,535,957,464,801,48,51,703,574,766,833,33,852,873,448,51,636,757,859,572,109,876,193,438,601,626,731,140,920,372,395,347,219,517,295,389,742,19,60,297,242,711,693,338,0,360,767,467,582,599,92,678,916,373,940,784,561,36,329,193,643,40,63,341,813,679,319,646,191,164,706,585,613,25,984,314,994,562,195,416,318,458,348,13,778,476,369,819,119,861,657,719,264,733,148,732,447,943,837,626,204,959,704,10,487,694,886,872,450,324,381,260,834,594,981,366,617,619,302,85,855,280,29,92,925,71,408,892,11,607,17,177,799,148,740,219,113,952,230,726,498,947,619,728,396,273,211,368,850,177,2,890,837,852,485,836,849,638,316,974,167,697,358,444,478,80,173,944,35,196,86,94,906,712,312,390,547,950,399,780,276,967,512,918,509,78,877,292,414,443,824,127,215,672,517,995,813,42,810,620,884,441,481,37,746,581,366,142,537,12,683,418,922,856,476,101,192,425,533,961,268,244,823,735,61,825,242,45,686,822,938,266,764,314,6,829,385,504,381,902,581,127,174,971,427,20,998,639,934,515,256,898,770,296,405,945,59,123,439,875,565,132,153,544,210,650,205,920,246,2,717,721,573,248,428,86,621,539,86,866,626,176,170,979,741,198,886,689,474,951,390,742,353,303,90,947,517,334,421,456,60,45,396,423,381,620,409,781,97,5,78,991,860,977,159,560,621,113,760,574,761,421,750,851,446,747,915,752,282,306,447,663,749,586,637,642,577,618,737,521,972,266,207,629,651,702,267,316,261,996,840,2,749,1,669,492,491,7,437,939,198,313,738,318,651,219,981,629,156,382,777,301,372,46,648,231,457,717,227,310,281,434,489,198,518,314,92,185,241,880,52,950,91,382,857,178,207,994,760,742,274,694,362,696,712,132,817,729,362,835,900,804,809,903,149,805,139,513,361,320,699,431,895,469,143,452,327,346,411,996,507,207,208,500,950,865,977,168,98,155,611,406,182,648,504,569,267,477,697,898,97,492,297,463,654,47,619,818,877,580,298,998,703,890,991,187,878,714,581,581,55,627,163,710,806,724,398,555,626,950,966,733,859,132,991,874,554,786,118,775,315,633,84,427,769,450,99,356,44,514,324,36,100,817,56,920,990,207,72,781,789,154,349,928,639,29,420,337,488,239,534,601,342,690,637,958,462,916,476,585,469,155,890,247,123,179,306,246,856,910,497,491,345,51,624,260,989,828,310,234,229,465,791,605,90,406,675,483,834,384,449,679,697,865,148,361,334,359,457,955,987,9,138,458,822,719,310,217,426,213,364,97,152,502,252,820,954,231,695,654,686,142,7,56,854,147,666,30,453,263,284,967,217,840,102,835,668,366,228,276,534,447,184,110,910,546,934,435,754,724,56,644,188,424,555", "710,76,113,552,348,357,109,384,70,330,746,402,781,645,215,463,649,28,783,127,53,411,594,88,699,475,620,933,789,220,353,283,346,869,610,631,822,486,285,337,738,539,244,692,686,913,234,34,909,943,50,173,905,465,146,520,324,598,920,321,339,348,231,386,248,701,876,147,737,348,1000,879,594,398,351,589,659,579,669,877,138,522,48,814,64,858,37,954,255,776,456,827,348,379,502,536,181,31,365,887,768,134,729,654,218,330,850,318,654,685,505,630,389,109,323,654,981,500,289,997,171,733,831,620,333,665,81,871,255,238,78,209,289,976,195,24,584,316,281,845,458,397,975,985,316,890,335,238,201,970,995,696,565,74,448,863,228,945,228,947,200,608,563,501,425,382,345,161,921,105,500,509,68,136,697,25,689,915,815,632,47,458,13,32,117,602,895,903,992,934,872,308,674,890,887,804,738,400,776,79,338,520,177,981,243,507,49,183,339,397,140,115,155,115,809,402,242,945,289,27,25,252,478,767,588,841,422,842,401,648,961,859,25,253,174,79,530,22,782,238,589,245,465,575,885,39,618,515,264,452,591,509,594,924,864,508,604,816,336,944,166,186,221,964,243,72,732,592,153,484,718,348,864,375,578,786,254,378,781,894,281,273,492,17,489,783,444,166,285,872,437,977,22,550,434,807,994,852,280,796,468,119,580,952,811,403,335,431,161,279,150,231,31,902,346,275,454,997,760,307,962,417,920,978,498,626,171,625,774,135,850,719,403,172,914,135,1000,260,654,652,777,228,886,989,174,257,666,600,153,385,891,269,633,837,279,199,909,904,733,521,731,720,71,343,861,180,342,303,885,894,801,197,263,871,965,259,385,941,340,60,704,566,574,954,437,186,460,955,50,716,967,104,531,957,415,425,710,842,340,563,14,935,743,592,476,248,963,720,764,726,722,570,742,650,22,8,156,712,411,360,0,180,685,470,766,469,843,881,45,248,801,10,162,658,165,988,75,641,168,308,500,906,928,118,763,61,25,129,466,931,323,576,230,596,969,527,692,409,925,960,815,5,716,328,81,643,109,407,922,791,938,508,500,828,167,978,422,840,61,288,500,689,324,701,898,366,821,863,548,601,697,156,854,29,224,310,20,537,411,435,565,30,359,242,809,175,630,448,478,510,675,50,491,975,559,527,552,543,285,682,813,99,173,809,323,727,21,979,214,668,927,583,941,528,950,608,643,879,446,58,456,759,743,351,586,385,995,431,730,200,622,827,125,491,195,254,405,125,603,376,862,752,451,376,870,70,209,43,41,577,934,261,553,963,840,776,774,129,890,131,98,396,99,953,823,125,484,178,890,361,23,287,716,603,658,29,124,255,227,624,332,252,396,372,704,834,309,78,216,634,671,996,934,636,132,779,540,996,740,125,247,158,350,199,560,396,391,696,148,761,41,39,343,506,575,681,955,632,519,26,187,291,354,280,574,897,179,432,734,573,988,327,624,394,527,933,237,279,392,822,239,7,850,867,281,987,472,706,392,124,532,799,499,153,952,856,478,885,766,195,464,937,387,878,338,113,511,945,333,912,53,301,780,867,103,728,37,507,264,105,900,296,811,193,592,53,377,762,758,208,329,11,661,901,281,27,416,924,657,488,752,411,631,343,916,455,968,287,351,610,824,626,16,947,396,199,842,166,110,732,244,213,638,724,617,806,520,96,252,391,779,849,687,191,370,209,570,338,438,617,17,663,91,662,882,251,275,258,924,549,207,18,572,801,234,583,836,182,934,639,76,348,602,128,881,238,657,404,953,621,372,338,337,729,800,293,182,737,231,888,599,887,570,454,812,32,820,157,889,672,116,193,663,38,281,565,504,306,165,988,720,636,482,558,783,92,186,631,61,955,632,927,128,905,47,543,639,189,566,144,349,313,521,666,109,979,904,262,387,486,686,170,173,40,552,253,358,435,924,822,559,685,316,795,854,671,56,174,64,860,57,361,810,142,950,891,2,815,528,893,339,717,866,510,770,954,853,290,102,300,176,202,987,388,478,364,285,628,639,265,28,210,250,777,859,986,630,135,653,433,581,143,683,825,75,398,596,685,253,569,843,711,493,27,393,858,857,575,533,674,548,156,152,126,307,724,418,598,645,381,773,945,207,218,42,49,765,830,689,287,980,207,639,171,224,354,712,599,990,502,815,633,394,92,159,897,216,710,939,905,559,780,252,565,920,220,580,224,968,935,7,652,849,761,617,491,787,593,263,620,558,967,541,598,934,955,350,961,574,398", "685,731,994,379,606,673,445,369,659,645,770,916,979,921,43,994,394,597,982,4,381,226,862,9,384,874,626,108,710,666,994,559,896,817,755,969,245,848,522,91,275,766,104,893,447,757,524,917,748,507,678,162,633,783,578,114,911,488,319,455,884,898,980,855,791,783,259,461,331,815,747,592,929,736,666,107,835,670,391,277,860,182,769,149,730,754,874,449,226,339,636,215,295,153,79,121,261,175,178,190,604,250,167,151,243,112,84,873,146,629,693,996,526,400,77,536,949,966,183,961,636,285,48,795,303,6,291,193,279,647,551,631,265,239,328,688,365,80,845,249,183,713,985,489,71,346,651,126,124,451,154,424,648,912,468,312,936,871,6,715,107,706,865,821,912,735,452,183,761,499,431,923,860,13,705,812,116,430,945,325,300,768,972,161,899,49,294,473,588,9,401,952,888,56,590,518,609,958,83,442,149,517,669,141,310,418,766,971,93,452,922,340,376,709,745,879,331,915,55,315,852,275,630,747,227,747,432,701,714,64,801,32,115,707,343,308,748,198,37,382,895,409,164,287,963,866,570,180,44,144,982,280,656,932,90,689,901,559,290,857,774,464,385,765,105,661,633,308,550,407,753,164,946,441,373,788,56,123,678,707,671,435,92,47,421,707,601,658,508,406,26,563,525,265,79,749,203,284,890,904,649,307,859,913,873,865,138,528,945,281,477,155,574,343,325,815,261,493,339,941,894,839,341,356,654,34,230,359,650,120,453,919,576,95,661,649,673,966,961,365,260,387,655,203,41,590,336,938,716,60,42,314,13,300,738,38,598,787,601,753,775,674,843,946,18,623,600,180,894,57,846,636,345,759,557,210,343,555,281,56,382,198,55,788,836,589,291,461,449,871,432,893,67,673,967,795,10,719,886,102,890,875,79,298,540,462,345,96,951,459,301,952,140,868,454,838,891,258,82,767,180,0,644,621,350,104,76,34,380,733,309,145,535,532,516,815,85,616,369,952,246,634,639,646,849,969,548,960,36,639,117,597,629,88,831,618,952,42,799,152,152,262,410,552,356,209,238,491,410,506,845,129,898,489,711,825,935,998,596,814,525,602,490,980,582,20,641,33,738,484,296,978,864,172,189,625,680,774,695,20,906,729,134,36,959,453,179,128,464,760,967,598,973,269,821,26,37,424,673,413,960,853,848,597,268,53,358,629,329,670,508,347,45,517,539,950,984,415,725,208,355,347,941,817,481,732,211,618,326,663,604,70,790,185,266,270,533,786,202,331,768,88,841,919,419,547,780,839,539,881,85,887,958,220,283,137,555,345,577,383,183,265,746,233,709,557,50,356,506,376,943,471,828,671,920,826,92,336,277,998,744,212,173,490,349,858,665,825,234,224,577,685,568,796,818,933,145,511,535,54,423,784,781,879,737,454,172,191,195,999,156,984,374,959,61,226,228,887,29,365,531,467,263,124,456,842,113,598,845,491,558,845,864,130,751,239,973,923,592,568,83,992,47,330,376,349,945,883,214,882,551,507,190,682,351,348,907,135,762,769,650,104,517,449,223,732,561,429,982,43,165,933,749,325,907,452,369,150,897,487,889,137,797,334,113,718,509,748,654,384,792,465,711,960,309,493,436,731,289,202,89,966,80,536,837,82,81,735,138,684,728,819,236,836,33,107,728,38,559,370,881,362,945,168,363,274,471,125,488,234,304,903,147,612,684,486,619,829,472,808,676,445,247,286,850,893,876,643,301,40,936,720,688,575,296,306,729,321,114,323,632,208,860,871,275,5,841,533,54,542,788,654,220,120,411,123,509,43,751,514,20,656,907,450,865,504,109,835,999,406,677,270,271,636,801,498,116,709,263,67,346,803,185,628,495,514,743,741,551,71,34,593,109,548,928,603,744,264,841,224,872,210,16,561,780,977,619,28,544,562,798,765,831,253,139,725,615,113,666,704,449,378,398,572,492,503,963,968,724,579,756,112,33,755,209,665,619,393,657,313,649,166,871,857,340,65,614,616,111,905,873,915,270,237,698,162,417,322,811,935,48,793,535,463,790,944,458,446,51,840,140,875,476,785,862,277,10,528,210,252,581,901,959,389,700,716,889,621,625,444,502,699,779,372,203,287,813,810,441,545,796,196,396,684,80,972,5,111,669,635,327,617,128,48,683,150,330,552,554,654,493,42,697,502,868,589,90,791,652,50,92,481,594,303,770,771,554,161,111,777,159,170,318,372,44,852,555,918,487,516,268,822,874,468,140,101,954,85,558,670", "129,369,760,572,789,216,610,149,922,935,922,231,282,179,347,443,559,484,973,752,288,441,783,968,210,874,354,485,545,551,123,192,662,816,710,35,220,110,543,66,709,798,790,428,207,319,196,361,131,397,119,549,491,530,943,773,806,433,153,571,282,687,490,131,47,610,965,347,172,35,519,161,655,551,168,73,563,200,693,502,490,913,455,324,800,107,73,756,165,499,282,616,310,423,659,529,473,956,30,942,148,550,469,390,624,586,668,518,114,321,632,133,996,312,933,423,614,824,640,324,475,310,387,658,941,261,714,346,749,679,978,791,269,638,160,741,607,115,66,209,899,205,941,692,392,132,258,36,654,300,628,696,757,579,80,308,277,826,974,31,545,459,337,172,364,110,482,60,293,730,58,440,795,940,135,591,655,845,788,192,945,732,504,590,212,153,25,43,45,87,791,599,522,233,304,64,443,447,203,431,184,255,910,165,241,349,353,607,66,887,789,219,916,653,634,217,379,859,471,31,755,285,607,729,778,855,734,492,162,742,37,715,19,109,176,27,531,157,821,972,43,454,109,551,541,713,626,47,323,782,412,610,747,836,38,769,654,742,951,396,364,724,320,46,712,705,542,66,985,591,840,212,919,469,987,388,956,442,345,460,429,667,371,408,280,546,219,642,20,895,820,549,836,687,128,479,732,866,882,547,821,706,514,171,556,786,665,380,120,849,827,776,670,85,458,767,801,51,182,612,144,326,544,231,803,992,189,233,123,180,449,56,919,301,83,843,985,424,958,701,115,562,811,165,310,459,588,172,948,143,606,832,871,128,976,60,831,664,246,460,975,191,392,254,963,272,950,500,586,126,967,889,595,385,454,440,985,4,212,310,33,180,53,617,819,544,387,630,390,152,646,885,611,226,652,419,406,825,738,309,793,835,208,774,780,247,424,281,463,205,771,284,346,480,851,861,555,425,158,467,685,644,0,6,511,529,843,898,166,419,758,296,137,573,230,1,696,7,530,791,55,632,944,782,578,528,965,155,964,508,14,87,267,108,208,856,15,995,712,680,836,745,969,326,522,119,396,179,725,146,390,225,18,857,374,606,184,485,516,128,216,573,739,960,859,867,737,443,828,907,510,814,910,65,835,10,829,406,711,498,180,686,170,258,651,812,11,338,842,476,79,480,49,902,312,266,791,348,183,947,715,319,853,321,822,898,382,34,992,576,702,303,645,743,682,850,404,241,608,129,529,494,790,714,807,238,929,248,222,84,690,113,918,245,588,860,872,419,159,952,215,661,82,106,396,988,617,289,317,19,645,801,720,470,987,207,738,692,465,600,141,907,126,206,444,506,262,370,143,241,469,879,661,863,885,831,659,646,335,980,221,548,895,617,464,102,516,241,535,18,614,520,217,279,961,381,864,583,447,264,882,847,931,338,132,865,317,547,787,280,643,245,19,409,887,262,968,207,411,420,906,53,129,441,630,175,673,590,466,881,151,380,50,698,331,206,978,461,266,435,834,235,238,59,211,716,98,960,648,332,733,316,759,779,643,700,124,625,804,89,113,359,418,765,708,968,924,137,60,69,657,217,236,954,667,318,859,935,918,219,910,893,208,59,436,971,28,983,716,268,103,955,658,241,490,209,35,952,548,86,875,722,702,795,965,610,317,127,477,742,47,71,681,718,949,894,882,978,320,4,348,949,928,566,47,198,579,126,472,834,670,305,485,524,760,349,199,532,783,638,534,766,714,466,35,74,475,298,109,607,794,561,110,697,871,682,733,611,723,884,685,397,254,905,707,819,150,145,926,501,413,376,252,644,788,147,607,219,163,830,227,891,170,39,766,475,880,392,752,702,667,1000,308,657,342,61,364,560,837,623,758,711,868,9,215,380,452,920,279,967,664,541,76,931,668,703,917,28,861,903,135,874,746,396,420,517,60,975,492,251,114,797,432,566,404,431,518,237,884,618,814,152,620,857,409,474,218,371,937,781,544,959,64,48,119,400,263,464,724,226,440,232,103,181,6,222,233,568,409,712,549,466,657,472,806,511,490,858,540,105,63,683,464,296,430,200,856,123,631,497,730,614,249,214,936,271,463,74,281,140,769,754,949,668,478,134,219,425,469,517,495,105,519,202,326,595,75,178,728,636,824,50,559,146,734,556,867,986,431,451,496,213,825,716,158,634,36,121,16,785,606,902,788,644,657,964,956,211,447,919,496,134,473,242,847,631,555,613,359,956,405,304,598,219,506,955,345,761,6,331,183,606,582,480,306,780,811,954,291,832", "637,25,96,399,268,738,344,993,577,158,945,750,376,314,579,71,456,268,579,995,243,645,386,338,673,231,625,351,369,984,992,28,68,801,559,68,538,79,33,553,181,754,824,728,69,87,770,179,756,427,131,89,797,728,401,848,831,710,740,759,336,382,886,261,364,753,674,279,97,911,136,715,227,340,729,269,512,952,914,790,476,799,685,353,937,921,749,290,106,782,691,268,183,360,289,55,384,921,322,698,982,157,154,842,466,923,853,405,533,747,672,960,552,60,366,359,543,363,728,458,757,232,678,941,160,19,24,5,248,664,318,326,698,494,529,388,705,783,986,956,480,309,423,30,488,658,167,153,903,821,867,615,796,157,575,40,985,634,330,685,60,127,188,848,720,671,578,120,619,433,922,593,886,143,909,798,986,574,999,390,652,608,842,388,858,196,375,234,791,365,533,213,41,89,325,328,594,205,550,421,399,247,151,429,655,795,288,803,617,777,471,624,135,931,357,982,88,229,486,570,520,983,571,538,707,133,458,891,290,917,961,122,123,87,843,280,408,230,113,90,676,348,265,461,3,637,278,256,477,590,751,38,151,722,811,573,464,368,124,978,880,73,412,15,536,250,992,44,995,923,790,851,114,899,762,853,942,386,274,873,754,275,72,705,144,102,507,604,656,531,371,521,475,337,153,738,597,276,924,783,289,739,287,231,35,439,707,533,460,931,429,19,770,82,228,639,473,723,103,465,31,716,508,145,764,357,686,39,738,674,225,107,401,48,936,107,935,291,719,139,117,711,729,774,485,233,681,382,385,718,260,338,74,674,422,441,279,823,491,805,172,813,96,236,251,233,5,163,77,39,866,216,762,218,247,834,794,807,317,475,951,568,731,532,215,39,620,24,54,296,571,315,578,951,830,960,478,808,273,278,412,795,613,592,454,889,169,265,258,454,363,63,559,70,316,942,817,617,835,582,470,621,6,0,469,440,731,47,743,302,374,231,121,19,632,942,591,849,161,419,486,5,992,798,180,493,941,240,897,153,469,427,328,216,210,919,212,240,783,640,746,156,828,32,395,841,525,803,616,803,161,485,855,966,986,64,608,984,671,63,333,382,761,505,734,588,993,552,941,35,294,92,134,806,545,647,267,141,7,340,455,766,636,845,550,803,359,523,140,448,346,165,914,188,625,970,171,416,683,689,952,252,16,628,95,949,473,657,288,85,771,965,983,576,587,8,559,345,721,310,33,733,4,383,862,279,23,803,827,712,824,398,750,662,114,651,505,638,193,423,76,899,956,765,924,771,91,57,957,468,228,660,775,388,994,966,723,860,226,498,500,3,636,426,112,590,658,222,89,789,260,677,797,943,841,685,547,410,335,956,927,145,480,333,635,666,889,134,253,762,518,644,921,211,300,117,587,212,409,895,426,977,725,83,92,430,76,867,951,670,572,391,134,280,235,25,784,222,149,464,353,705,243,668,16,339,661,511,421,63,868,702,426,774,224,309,680,457,652,74,128,89,22,478,626,750,897,808,660,164,192,177,68,315,669,241,101,61,687,546,220,340,772,898,43,956,130,206,791,50,771,656,869,986,789,390,670,294,322,41,753,271,265,904,637,96,866,8,696,883,639,74,97,228,851,58,985,953,243,60,174,2,210,521,795,128,581,104,469,197,39,353,443,979,28,560,373,461,695,36,5,95,322,468,164,425,606,145,499,28,877,482,812,498,753,907,956,89,50,543,750,502,266,115,131,186,333,186,154,217,597,522,220,395,923,532,463,171,609,615,609,425,569,520,990,706,394,977,166,297,76,238,533,604,966,756,731,11,866,434,19,957,577,394,795,475,75,963,280,565,754,690,302,192,933,419,146,603,304,403,952,490,911,30,236,872,439,49,482,854,43,339,948,268,179,527,244,758,24,855,770,770,934,418,107,172,968,967,679,518,690,926,875,147,673,430,443,7,1,188,211,607,95,424,205,614,308,173,251,24,251,240,746,908,202,255,331,837,887,110,712,899,173,387,68,180,233,807,997,73,739,404,238,834,165,10,75,313,80,172,523,942,269,423,663,268,995,469,60,115,307,556,66,77,949,860,697,511,769,703,542,124,334,235,831,1000,542,95,81,468,151,291,199,989,901,254,393,390,196,696,473,839,174,48,182,199,795,388,959,973,254,480,522,696,223,567,134,65,116,895,685,311,218,211,821,796,315,865,684,867,381,234,797,731,370,872,40,680,160,416,533,621,772,761,151,301,133,257,24,270,367,459,735,69,632,49,480,898,493,533", "876,421,410,353,887,994,751,511,634,519,364,195,438,363,318,760,689,562,852,210,347,489,969,931,584,285,997,985,34,613,983,674,425,443,502,894,171,279,447,123,849,986,38,613,152,203,505,605,494,856,847,118,149,164,412,355,647,18,940,265,653,954,453,787,453,757,806,450,818,855,526,161,570,485,831,728,805,780,567,764,335,162,491,578,53,637,582,595,495,284,470,822,17,265,202,834,906,222,574,809,723,735,245,381,56,117,721,518,697,112,316,532,809,184,19,47,444,127,233,915,596,959,670,805,418,312,51,716,712,226,435,187,725,704,582,548,984,606,707,9,374,179,798,520,92,713,899,625,349,250,265,61,986,587,190,832,405,758,828,386,587,224,941,808,338,941,660,413,702,509,240,492,577,52,922,636,454,325,242,33,34,626,379,854,530,812,537,615,948,516,856,509,68,800,347,9,922,382,697,59,933,960,681,475,783,832,783,347,962,195,605,543,677,537,158,208,737,137,54,584,17,570,318,944,924,481,149,788,660,694,889,77,583,527,503,57,498,469,698,48,582,877,761,190,625,274,497,469,281,191,369,435,665,986,87,749,869,788,140,463,666,164,774,975,740,685,851,584,39,668,212,446,36,754,431,462,143,641,793,695,514,333,478,433,561,619,638,808,111,696,227,430,195,537,850,505,56,125,976,322,254,806,976,904,310,237,888,284,374,705,892,92,237,382,425,79,457,67,687,551,269,741,849,166,926,740,917,921,803,58,975,355,780,490,251,262,639,133,32,741,488,71,963,332,71,770,755,354,775,798,14,344,573,77,736,695,145,947,378,775,199,225,283,879,230,738,535,759,811,558,466,996,612,807,642,973,226,895,71,16,789,740,657,273,599,131,226,138,307,651,268,57,12,181,13,221,69,320,497,999,774,448,438,907,207,805,949,627,822,8,880,7,919,207,241,545,477,923,457,599,766,350,511,469,0,362,248,846,188,177,654,497,367,260,551,794,451,637,909,283,341,748,333,411,672,570,791,656,113,453,623,765,173,895,851,30,802,402,751,884,398,834,389,628,783,832,310,642,416,207,425,732,717,658,902,200,509,11,214,962,31,515,668,475,925,235,29,808,399,845,23,895,922,817,888,930,111,962,863,727,80,913,866,463,746,211,368,478,494,869,672,92,53,724,280,702,816,56,372,292,56,491,449,124,127,920,282,533,525,229,363,897,761,632,17,293,623,984,714,937,407,547,266,223,111,210,710,815,942,746,15,586,860,750,459,700,906,181,264,405,234,731,317,147,645,251,242,324,677,489,827,16,208,7,199,918,766,403,29,83,980,431,109,240,345,118,216,822,630,628,799,372,632,435,861,987,969,770,113,313,767,524,997,637,801,366,195,96,596,263,565,879,153,365,236,888,123,473,648,23,119,207,945,466,623,983,218,426,951,904,974,10,102,59,130,101,590,972,685,276,268,780,24,295,972,83,438,896,186,88,419,253,344,700,984,167,512,486,442,289,572,474,276,683,668,818,142,272,117,972,313,486,859,420,307,853,695,936,109,962,939,456,659,539,473,355,148,304,591,30,413,158,371,461,476,529,944,760,917,965,945,535,364,887,62,251,16,188,296,679,100,481,207,565,174,643,294,418,806,517,694,998,105,727,294,356,252,97,367,982,483,151,297,931,770,525,442,114,741,683,135,894,37,860,772,446,789,94,174,927,663,221,761,989,116,162,93,634,530,134,252,217,444,393,376,357,625,753,368,282,774,861,612,757,659,529,340,325,673,203,808,232,948,801,693,809,90,220,5,86,249,327,375,544,864,496,723,14,786,477,951,823,282,130,705,162,243,721,477,690,94,585,6,543,405,866,802,94,599,909,936,579,604,415,737,407,59,263,544,624,893,306,369,615,290,994,463,367,214,34,508,538,675,383,692,852,108,502,275,539,184,980,608,554,655,715,209,312,509,721,418,581,704,396,453,622,364,171,788,736,265,321,542,820,930,649,856,831,733,758,628,387,994,221,676,818,600,694,477,48,927,119,405,391,358,840,397,405,802,292,246,575,329,821,516,77,970,376,466,420,508,291,692,771,218,398,347,321,584,485,467,606,876,572,864,51,549,35,366,311,388,515,507,902,530,11,501,205,824,269,283,612,221,167,501,498,452,473,863,440,92,82,356,61,782,588,762,244,288,295,988,631,718,384,272,48,7,865,895,201,947,708,151,877,962,361,471,643,791,884,308,476,16,139,47,616,146,514,847,435,766,908,374,450,767,603,165,525,801,481", "293,622,175,828,224,171,510,918,401,881,507,347,168,959,85,65,189,740,98,52,157,219,829,610,803,874,105,113,659,308,906,955,714,909,796,669,76,221,785,325,306,556,663,490,396,304,716,55,836,183,571,683,106,457,326,550,185,740,404,161,432,926,300,197,359,734,876,491,898,90,431,61,754,780,410,202,961,246,818,196,469,230,721,279,268,20,357,112,36,121,947,206,995,762,36,413,868,956,652,620,140,850,622,739,308,821,951,38,258,572,513,886,906,887,901,299,607,137,184,575,156,270,232,41,241,428,786,856,90,869,401,532,579,269,305,290,168,821,878,633,861,910,932,564,371,126,160,985,14,684,941,878,361,480,507,768,142,700,421,132,646,152,452,219,326,437,914,872,636,579,706,485,103,267,815,184,305,554,317,428,790,693,634,67,664,914,503,409,949,391,60,577,287,434,627,635,717,192,392,669,403,873,798,769,210,495,635,272,507,82,220,334,708,289,281,903,73,482,225,478,916,954,713,688,894,258,909,48,911,120,989,781,197,458,403,189,327,819,662,812,654,857,573,412,167,377,190,636,336,800,178,813,697,22,974,148,371,74,877,799,303,995,808,214,589,116,118,358,880,584,375,553,563,374,891,840,28,561,493,27,674,570,338,432,740,989,698,291,52,259,475,726,888,152,161,125,621,207,299,672,21,927,918,851,823,948,399,296,364,575,986,414,233,529,896,488,469,313,792,123,925,951,255,269,969,491,578,568,884,842,565,884,383,182,148,57,606,923,321,999,4,205,262,143,879,621,777,1000,290,380,222,762,550,848,928,341,232,229,333,347,110,925,161,660,724,904,288,387,708,329,81,983,799,24,641,479,908,265,331,904,584,544,990,701,964,184,350,282,701,685,96,477,87,132,700,155,294,496,32,534,229,350,955,344,66,790,17,513,80,122,118,885,698,37,594,349,517,505,840,92,469,104,529,440,362,0,796,362,397,198,904,315,849,690,509,226,120,293,100,438,349,432,985,815,39,568,166,403,222,377,65,29,473,574,917,50,698,194,157,729,918,744,655,657,468,349,850,534,507,352,909,225,177,847,670,415,129,984,639,912,618,933,977,9,406,618,349,507,600,752,9,424,371,45,219,860,733,812,728,563,196,137,455,440,694,601,926,838,111,105,946,532,417,804,650,270,130,719,813,892,440,967,596,414,209,368,733,349,537,350,936,700,213,70,606,643,941,212,710,904,802,310,341,406,485,987,272,877,50,78,254,50,108,117,214,507,168,316,569,51,385,39,585,122,315,509,340,907,830,872,497,954,877,907,2,95,707,379,619,189,851,229,55,321,879,142,455,175,106,761,858,152,465,22,402,170,452,290,678,277,4,401,54,143,404,849,399,722,390,426,861,301,136,86,645,279,391,962,448,23,771,754,526,730,398,423,452,937,711,966,279,386,999,933,698,853,355,339,110,58,133,284,977,793,70,985,707,872,283,75,310,757,331,126,655,947,163,184,308,25,423,596,305,362,388,676,209,560,964,517,876,19,89,347,345,150,527,245,929,816,289,24,791,718,279,69,918,771,332,498,368,743,563,472,89,175,610,95,214,685,237,590,575,791,295,421,678,42,809,472,559,467,200,495,93,89,850,205,644,153,297,528,292,468,45,358,32,391,393,343,181,740,829,911,306,581,884,293,272,128,685,650,267,186,578,661,772,863,732,986,554,772,119,134,13,831,56,767,22,69,363,916,448,83,241,589,918,444,399,228,392,564,651,638,964,651,931,5,369,298,329,228,251,761,508,216,816,241,394,299,195,974,921,453,286,699,785,837,658,769,39,280,974,61,826,527,666,230,689,685,169,811,15,869,291,109,294,993,434,175,39,467,514,770,289,750,122,435,900,785,912,602,104,274,724,157,829,25,452,902,446,452,938,251,70,417,129,927,209,613,540,334,977,306,580,446,730,300,290,883,649,882,976,969,888,248,133,55,485,685,745,604,565,544,681,176,647,611,285,383,477,505,762,469,737,562,820,374,373,409,782,433,411,398,529,898,364,61,754,714,948,971,130,431,177,513,76,894,600,324,64,802,869,971,966,409,135,678,526,383,282,550,465,519,873,460,373,732,241,343,38,494,875,843,266,370,115,267,869,37,317,674,590,85,194,250,773,329,186,255,330,147,391,727,616,696,924,385,183,869,22,599,346,979,752,962,225,623,708,423,314,464,944,174,377,714,138,808,482,108,821,457,443,959,22,777,463,377,104,283,569,804,509,848,658,587,9,86,800,796", "194,846,731,763,574,174,120,356,917,517,932,194,75,641,86,523,414,571,81,831,767,409,420,825,205,90,326,804,893,306,631,315,855,601,846,527,567,83,204,7,608,715,464,75,958,311,240,644,448,238,673,468,429,420,416,43,867,124,363,507,627,477,454,254,865,426,461,321,798,838,148,334,756,157,773,935,287,698,330,718,53,719,990,919,881,315,938,421,831,107,116,702,283,424,303,967,74,491,795,686,108,309,228,993,678,351,487,329,453,167,278,886,631,701,131,656,870,373,106,422,33,260,455,425,857,703,496,107,711,839,959,900,635,180,697,559,900,651,565,765,460,308,994,583,697,503,760,205,315,538,967,328,871,36,558,849,902,655,104,842,721,232,485,706,178,104,588,874,573,567,78,731,563,34,814,486,42,8,886,19,211,930,475,220,766,180,788,483,810,918,866,829,478,398,565,257,427,86,313,686,436,304,279,646,672,912,548,306,559,216,76,721,300,238,428,856,332,689,664,372,2,606,928,197,282,893,677,846,404,434,118,520,854,215,414,893,718,870,256,661,124,157,727,258,64,61,420,546,824,593,803,630,909,963,273,781,289,323,167,870,943,539,374,553,417,550,438,410,657,587,249,143,968,585,143,921,281,612,428,623,858,480,370,216,101,3,143,810,749,593,352,107,590,171,671,259,585,609,813,74,888,565,261,455,229,674,506,120,612,923,155,713,492,356,498,278,225,973,651,920,120,201,614,754,577,214,97,265,129,855,68,729,971,508,215,917,750,452,10,692,696,19,152,787,209,259,508,807,596,276,895,529,209,906,379,975,154,904,801,607,749,989,621,902,464,814,857,994,506,263,47,361,247,93,222,935,903,466,683,199,576,683,345,269,90,963,284,278,763,884,818,514,967,394,99,952,370,594,738,693,82,505,425,911,819,263,234,854,623,650,393,830,949,348,645,195,413,490,752,678,843,76,843,731,248,796,0,519,118,846,874,842,487,752,700,144,661,380,15,236,215,872,742,786,943,160,739,508,535,522,720,854,94,590,852,77,535,45,76,277,218,730,863,386,962,484,259,745,914,474,565,155,196,328,395,792,888,343,404,253,916,308,602,40,738,320,246,257,456,869,279,709,254,14,631,678,220,136,890,841,450,294,743,562,662,408,685,966,967,463,44,932,678,61,507,754,299,854,79,89,410,398,28,844,109,443,132,489,686,613,874,108,157,512,537,622,615,364,200,56,819,283,697,121,605,241,205,15,126,897,269,922,858,401,373,368,560,354,33,472,357,891,7,360,209,724,599,585,221,278,182,546,540,665,748,517,814,434,540,229,431,266,26,896,49,211,62,627,90,677,708,969,756,568,488,188,983,185,667,596,257,234,269,913,303,118,679,571,516,647,11,650,214,19,937,520,40,336,233,914,352,215,588,304,406,206,274,397,781,632,432,530,796,16,611,738,31,288,431,337,390,586,521,799,236,905,694,901,765,109,68,852,569,887,396,786,506,957,811,207,938,490,395,977,59,452,937,205,694,780,239,155,102,946,657,192,106,492,272,623,618,732,677,674,290,902,248,541,940,697,875,123,468,899,892,720,958,218,755,507,454,595,714,237,549,466,734,68,626,538,441,306,879,146,922,835,554,114,40,733,524,462,545,848,3,622,709,547,357,388,529,138,331,114,62,687,747,566,731,657,23,693,294,597,401,1000,134,736,840,383,881,91,817,548,967,868,549,411,269,290,707,843,373,875,242,182,287,510,225,379,838,921,32,689,408,52,449,878,378,262,73,269,197,459,766,15,120,292,165,262,612,391,27,887,808,455,994,702,532,35,630,312,16,112,877,512,547,684,560,176,342,899,715,93,24,59,611,889,701,154,355,258,762,829,406,64,227,108,123,453,331,777,96,322,894,523,564,180,26,721,119,496,842,660,34,118,790,116,529,234,43,455,111,415,292,792,810,495,146,784,208,944,101,757,571,906,432,348,854,878,669,834,575,286,618,686,245,419,110,762,670,378,782,103,10,895,944,906,398,659,919,109,840,689,372,609,432,674,69,519,37,833,666,340,737,911,280,436,636,864,731,122,920,259,437,754,35,365,42,925,338,705,626,669,844,626,271,825,939,377,489,527,3,823,14,186,550,965,497,191,231,952,157,568,961,747,759,688,221,720,767,528,154,343,549,230,136,430,205,686,309,162,974,589,875,972,760,739,426,360,555,844,450,691,237,269,587,639,483,271,464,773,495,580,29,703,945,644,500,773,743,336,438,525,375,777,371,177,977,966", "102,756,591,588,308,216,104,447,341,629,164,552,439,231,951,667,558,176,971,492,88,80,295,864,110,359,479,109,797,308,971,285,698,538,708,248,917,848,490,603,561,911,676,627,3,955,974,475,474,392,422,946,560,712,758,174,457,207,193,476,906,5,273,827,303,707,191,160,198,100,12,388,78,830,931,437,84,203,140,310,634,462,557,160,880,741,584,160,560,107,813,573,106,596,519,168,903,284,753,767,297,807,561,751,885,497,182,540,773,613,840,213,59,881,462,520,64,664,569,880,950,392,700,541,877,803,228,55,514,159,535,631,670,370,427,62,756,756,627,582,937,386,197,930,447,523,264,893,102,562,51,685,692,34,36,635,902,94,243,147,960,787,562,56,518,13,786,314,33,769,856,317,3,321,135,184,995,782,107,880,610,510,29,535,96,817,691,443,229,487,553,803,512,436,549,17,403,99,816,224,377,545,23,850,707,415,434,530,907,44,38,688,937,562,672,681,239,123,207,12,297,997,355,519,4,627,983,300,512,435,33,188,52,898,975,628,89,807,538,237,660,949,921,344,96,754,114,358,531,720,63,891,479,541,564,401,129,107,918,56,788,132,529,903,995,986,796,111,81,502,425,857,202,231,847,307,588,770,338,371,320,877,31,116,279,481,339,166,306,670,256,413,950,539,761,207,215,465,537,489,558,579,842,974,368,27,272,916,318,746,279,89,926,179,812,733,655,988,660,707,513,564,550,122,762,210,619,89,801,484,309,673,851,357,300,245,238,970,523,933,95,933,757,64,68,65,724,6,861,600,33,116,57,749,702,686,360,263,161,346,708,847,227,196,249,355,461,830,20,52,11,640,181,227,87,139,888,507,914,721,226,836,335,900,685,341,605,802,251,764,79,579,524,601,625,179,80,879,796,500,718,440,108,324,590,401,788,973,566,796,342,474,891,690,579,888,927,846,348,916,881,34,898,47,846,362,519,0,100,50,292,828,163,884,179,374,949,357,268,812,536,797,856,357,745,984,879,482,556,91,507,492,643,878,715,565,759,729,167,623,447,56,128,856,221,367,724,527,435,217,747,26,304,224,178,900,50,758,870,620,521,944,422,766,208,60,161,105,661,748,676,617,698,498,599,674,247,519,937,497,71,436,356,684,86,923,465,189,123,780,526,707,370,672,312,309,297,368,416,924,580,45,786,629,335,543,765,165,558,387,253,22,901,395,313,688,83,558,529,530,813,929,24,216,287,254,672,554,706,319,424,159,84,486,439,744,455,714,22,378,834,294,239,674,717,730,132,597,841,438,967,806,48,345,202,800,237,690,63,527,477,844,564,285,135,42,608,771,64,389,281,308,828,603,711,555,582,500,486,122,423,912,284,669,806,718,524,65,900,866,139,615,880,628,754,420,671,68,213,732,843,751,244,75,777,729,374,633,517,462,408,109,167,842,861,826,525,16,108,405,704,593,866,807,779,746,220,402,633,386,334,65,82,470,517,330,347,841,21,846,672,777,323,453,516,449,669,494,766,391,971,331,948,363,165,557,601,239,966,49,616,41,529,508,377,956,118,657,894,965,487,316,877,851,603,542,128,764,397,54,225,640,898,464,677,845,528,573,57,411,861,206,960,794,364,817,796,619,534,563,705,88,588,779,642,812,250,369,388,21,3,197,92,881,296,682,670,595,118,730,401,779,905,644,244,948,686,232,979,420,239,56,787,206,135,513,359,334,967,519,371,84,475,692,761,927,418,967,121,470,589,116,663,6,830,368,313,574,26,757,943,115,338,296,208,790,898,402,243,106,537,383,780,511,101,375,688,401,964,891,532,794,851,229,772,940,313,297,76,450,116,423,406,137,43,100,263,130,846,570,594,126,269,116,322,991,996,531,849,612,325,621,170,32,859,721,618,586,684,176,469,21,611,9,923,681,612,925,390,887,404,48,74,306,400,628,30,604,762,634,176,366,26,122,573,667,162,216,323,615,630,468,530,574,490,891,137,176,814,122,721,809,327,946,291,248,634,109,60,242,265,252,773,705,654,326,975,519,638,292,59,651,100,532,418,248,907,863,257,505,748,218,987,714,245,511,328,886,790,945,399,275,310,40,395,854,551,306,78,199,952,237,830,991,332,254,618,393,726,167,459,682,832,82,12,705,957,779,342,499,73,254,799,513,848,829,284,666,206,492,845,734,512,423,523,997,147,517,131,124,100,855,592,924,599,860,334,287,472,498,553,150,782,256,490,211,757,35,588,444,589,214,403,350,810,313,304,455,627,30", "153,686,318,735,86,51,959,999,552,451,869,823,314,604,627,99,490,631,50,514,316,519,115,69,506,560,811,599,879,873,188,919,946,462,589,281,745,590,757,143,106,88,3,23,190,708,827,550,459,330,576,427,416,769,809,257,399,726,493,448,13,34,403,572,979,475,880,116,248,322,151,12,614,481,383,339,767,196,513,820,849,686,325,527,268,162,741,792,414,591,384,500,603,862,719,920,696,27,384,926,541,805,519,624,593,383,204,68,660,865,572,809,378,132,612,53,961,273,355,57,617,863,668,317,258,666,708,83,174,419,129,965,640,620,827,219,719,232,710,6,817,9,632,583,993,40,290,227,386,268,322,255,582,839,281,550,199,382,466,814,147,690,675,671,690,80,336,164,501,144,903,34,773,565,952,479,638,5,510,512,763,22,657,254,440,217,285,336,498,263,369,663,238,590,513,936,170,256,327,221,523,858,480,105,511,267,277,881,789,331,712,580,481,603,427,832,333,632,516,856,350,396,946,580,828,671,380,607,456,210,303,124,416,74,152,688,443,480,624,124,585,295,498,78,585,46,172,275,932,76,608,397,251,696,404,859,393,378,995,61,785,884,236,225,250,294,369,414,826,691,214,531,956,194,410,638,150,378,766,335,484,582,995,309,364,858,278,108,490,182,712,233,382,964,640,381,488,473,857,965,12,449,786,947,849,55,489,629,268,178,941,406,61,206,450,595,914,852,116,854,168,562,410,219,766,78,428,970,819,146,694,525,39,816,989,327,552,904,225,212,985,776,579,194,984,70,172,528,103,150,578,261,117,729,120,706,181,555,532,338,201,98,39,486,807,401,797,575,919,139,371,717,80,329,642,887,607,314,100,114,172,231,871,860,750,204,534,832,931,772,80,817,734,647,302,743,404,723,899,793,380,771,488,201,714,38,971,826,235,574,993,550,186,595,716,683,712,516,670,373,45,380,166,743,188,397,118,100,0,254,565,946,777,482,625,377,70,305,802,735,152,358,962,486,156,807,493,195,832,874,285,921,774,604,116,207,404,677,212,429,964,803,371,996,662,365,710,671,255,855,702,86,251,407,805,655,414,813,985,688,89,524,171,126,683,859,429,341,441,511,997,948,978,668,543,186,779,592,545,854,308,821,635,667,164,962,681,84,350,520,883,791,711,524,184,526,382,212,352,446,874,429,413,779,893,981,553,112,730,957,756,906,810,104,299,8,460,843,792,188,76,6,534,349,849,495,609,894,565,826,420,102,205,734,554,774,206,14,938,732,148,467,99,722,76,176,210,72,385,263,56,233,347,702,689,718,639,418,529,311,176,822,955,202,112,806,533,846,231,824,721,556,958,944,999,811,909,130,560,629,722,995,102,957,226,874,28,601,303,301,745,534,253,251,408,183,273,86,771,32,104,681,663,875,86,684,929,5,975,399,233,114,907,825,525,336,518,598,846,155,166,750,924,699,299,242,58,256,505,982,433,507,964,716,332,696,680,947,935,996,469,318,379,355,606,953,31,298,491,177,923,883,405,85,339,71,137,456,476,585,262,629,372,322,26,31,81,648,281,973,743,915,608,784,495,408,592,133,181,109,688,90,558,795,248,587,403,757,6,481,951,748,363,982,224,863,82,153,779,316,986,235,647,565,331,717,148,474,495,11,487,171,655,691,67,596,287,915,826,466,817,545,520,242,971,443,202,930,330,451,130,934,358,734,358,247,541,774,39,647,604,357,618,99,668,689,553,608,60,863,401,432,15,389,233,587,814,210,873,244,350,5,787,876,918,327,601,432,885,535,630,291,544,362,546,445,640,285,799,391,595,276,300,361,255,561,693,548,596,330,711,120,720,741,630,953,367,711,65,300,697,934,62,168,888,962,522,845,280,914,136,884,892,772,520,246,659,186,70,712,116,116,894,450,838,441,95,186,931,288,583,6,14,571,736,376,220,339,898,328,529,111,620,592,888,377,311,863,3,735,175,64,338,675,674,385,423,777,989,349,762,462,821,218,203,984,325,831,398,645,346,656,59,857,449,597,1,864,696,433,895,755,989,735,899,535,148,582,332,912,260,118,226,226,717,621,287,84,853,993,480,316,380,482,834,773,865,209,664,332,328,735,367,809,264,465,932,139,227,294,84,795,636,118,502,863,405,574,99,63,671,910,605,928,997,414,668,964,560,366,363,862,805,230,439,947,593,117,627,727,147,372,46,349,172,423,876,211,848,245,509,363,673,496,44,822,434,255,665,279,26,332,29,226,764,247,193,663,551,718", "903,176,731,331,348,175,131,173,404,427,183,598,507,131,479,818,601,377,457,213,639,904,490,283,419,382,465,901,517,274,875,980,564,42,582,199,305,3,59,434,315,953,91,991,17,388,309,632,46,766,681,110,252,54,971,847,810,180,11,655,791,313,634,666,450,568,405,181,390,559,777,192,199,57,657,66,834,271,677,566,676,296,29,295,135,969,887,887,837,68,209,686,890,710,125,220,966,382,925,274,465,75,766,705,96,52,277,415,616,731,774,94,906,753,296,992,860,659,502,636,349,206,303,893,428,546,50,941,237,585,419,578,844,824,62,889,324,824,550,98,614,403,207,876,242,363,630,265,807,150,842,529,467,796,787,480,945,604,440,450,668,775,926,326,905,379,482,530,995,800,50,739,326,729,403,900,576,84,729,217,437,858,760,721,810,672,859,206,852,296,605,620,667,182,940,526,210,631,422,795,542,839,815,142,537,167,732,754,702,746,437,547,330,950,410,317,50,78,463,355,355,959,922,159,139,437,430,375,585,531,111,485,95,433,828,889,971,95,371,861,505,264,605,56,399,558,642,214,929,315,680,35,848,681,444,411,759,110,420,400,273,125,303,243,97,184,665,458,888,370,852,748,982,778,119,199,407,480,935,889,739,620,879,946,53,902,601,806,768,578,228,735,506,153,892,551,586,903,704,584,669,845,851,457,767,817,900,378,949,879,712,11,21,947,216,857,562,338,962,172,167,5,12,709,478,480,109,708,233,485,264,885,579,851,664,442,96,152,384,691,833,352,527,885,732,788,485,943,476,650,144,438,394,756,694,588,447,385,21,720,793,827,701,426,25,798,322,80,797,426,220,122,495,887,971,890,185,58,784,290,933,914,214,871,833,426,617,873,447,893,26,826,428,466,522,904,271,670,881,707,108,712,701,914,921,326,368,309,217,837,49,768,737,601,8,216,427,626,7,940,248,733,419,302,177,198,846,50,254,0,123,8,27,437,594,126,14,469,462,171,792,792,990,68,816,382,535,760,929,285,509,41,33,579,452,868,664,974,652,835,788,467,39,58,900,380,85,798,162,588,712,204,409,136,81,118,831,840,132,59,539,878,431,802,44,792,200,950,92,354,263,763,634,410,938,450,416,904,595,89,313,833,60,65,479,700,868,958,836,638,165,393,368,215,652,434,893,850,22,941,563,432,327,643,488,863,59,432,210,245,930,468,733,139,521,523,283,727,428,752,224,294,251,678,251,474,200,318,773,793,291,773,828,496,845,582,759,145,339,557,33,663,137,71,422,663,835,981,826,287,96,636,819,301,949,784,814,705,458,236,834,503,545,355,409,41,903,431,786,348,981,226,220,646,417,532,631,595,308,538,428,186,513,820,380,917,700,626,648,208,670,360,995,116,601,854,890,793,379,394,166,682,374,918,411,422,789,492,218,158,881,603,451,246,112,487,241,468,814,716,703,928,602,521,664,803,280,510,906,910,174,889,782,925,849,288,476,602,201,61,968,701,867,406,791,172,545,694,47,52,238,275,588,70,427,156,121,246,253,357,763,686,21,540,652,594,392,41,251,6,880,763,237,74,101,321,750,985,864,254,30,292,741,759,32,345,45,103,732,213,929,323,519,318,945,800,336,459,409,523,949,599,332,399,864,292,758,467,415,196,500,803,367,469,288,119,854,838,328,286,305,716,661,710,262,612,273,628,701,755,556,740,327,503,443,385,714,793,820,985,210,79,942,612,703,995,646,360,309,668,605,525,512,255,591,21,592,39,764,685,926,338,922,261,271,50,972,769,104,536,312,654,113,191,637,961,453,290,474,609,805,118,318,133,146,742,678,930,365,647,116,99,478,673,923,291,342,469,749,799,810,269,841,927,311,24,498,483,792,895,919,560,881,155,392,882,501,731,691,95,883,955,128,264,380,763,947,286,830,801,24,529,147,364,458,687,499,903,293,852,854,715,933,538,426,131,213,649,58,244,707,837,574,194,144,200,199,477,866,431,344,624,422,660,647,307,796,233,183,920,996,744,830,424,449,903,674,469,462,958,817,848,121,741,780,469,221,325,147,602,561,841,759,577,911,49,595,826,635,924,839,473,841,738,858,149,623,502,728,209,422,908,510,864,287,35,546,338,48,77,711,670,570,74,519,429,443,388,15,499,60,347,921,679,475,819,5,670,112,998,617,153,617,382,26,101,978,339,3,648,512,613,941,176,157,155,901,811,293,242,420,419,849,863,807,387,899,90,128,998,601,986,531,843,268,22,398,976,409,178", "414,583,431,837,942,878,925,125,197,619,839,251,184,973,628,974,424,683,708,777,341,597,22,837,679,907,92,844,967,321,34,398,763,192,225,251,202,546,9,378,317,981,93,267,386,739,678,618,332,552,437,672,199,74,898,518,17,980,198,145,542,460,697,575,901,119,20,798,83,599,678,579,169,99,184,716,81,288,632,362,867,401,808,419,98,309,977,396,710,28,396,360,695,109,645,626,87,976,985,134,45,916,972,23,455,388,931,48,74,970,782,848,687,492,648,574,971,923,772,36,227,754,227,735,626,312,32,344,259,812,640,188,309,157,771,42,46,369,865,59,124,286,942,610,17,633,365,332,483,244,824,58,663,695,51,880,729,405,961,108,744,804,163,900,743,720,357,599,220,642,630,993,870,173,27,47,515,760,992,143,572,444,480,968,521,918,621,405,191,79,276,987,578,515,883,954,815,721,69,336,836,464,483,707,507,620,418,231,361,355,994,516,606,545,309,833,318,415,671,78,152,50,53,482,151,639,858,25,285,938,225,550,432,169,982,154,735,571,583,430,708,909,834,639,966,373,661,670,345,507,510,11,942,273,245,53,936,17,403,301,506,419,127,726,398,365,989,283,271,310,464,746,587,509,302,943,83,755,730,398,983,420,973,152,84,446,346,690,358,832,244,96,265,258,814,757,907,709,26,482,477,945,20,703,228,655,562,595,957,72,569,391,467,208,17,925,813,500,539,662,397,319,583,620,123,420,111,789,480,315,841,786,873,76,661,230,484,893,559,309,377,561,558,505,537,813,984,611,409,879,983,339,153,330,802,576,611,988,928,532,890,160,887,867,587,278,528,214,170,289,799,360,456,195,893,693,413,406,735,582,525,85,229,340,698,251,656,196,125,486,54,908,949,51,160,57,249,506,622,121,574,764,852,828,337,824,669,65,767,849,400,662,722,276,922,934,50,182,715,784,801,309,758,374,654,904,874,292,565,123,0,727,229,574,451,30,657,239,717,25,936,727,574,67,177,655,20,218,685,882,756,818,812,80,726,864,611,801,444,225,59,191,347,875,81,452,772,676,361,263,569,879,403,127,456,565,625,544,421,70,765,658,242,217,61,844,701,636,44,917,471,399,346,365,150,890,110,905,406,202,285,162,839,426,79,656,929,923,497,403,553,876,22,296,731,682,836,706,235,517,514,67,243,760,170,612,233,836,101,770,306,85,341,888,345,411,400,684,38,627,94,313,489,161,630,702,691,101,628,182,903,897,937,415,393,69,706,670,526,913,894,930,502,109,685,102,486,373,989,504,51,743,238,848,725,205,817,551,566,644,8,840,904,236,411,86,895,521,145,184,717,83,824,846,399,300,854,158,12,953,36,100,705,528,532,276,59,125,468,885,928,81,604,69,236,286,523,801,348,554,363,436,750,279,248,162,152,862,188,88,448,159,722,61,878,708,939,865,280,355,922,955,225,501,867,609,177,238,512,275,232,295,848,151,529,619,393,655,403,384,686,123,492,463,151,637,966,154,437,341,715,95,951,525,836,719,720,111,39,619,173,511,913,807,182,740,473,270,769,967,420,175,988,714,420,318,109,753,123,499,413,36,998,562,745,416,150,41,544,260,761,976,617,324,464,995,929,449,35,81,631,547,890,42,431,271,249,464,376,915,949,938,612,93,914,126,462,209,411,636,974,694,901,786,935,439,218,303,409,448,821,659,111,82,566,38,876,252,80,360,196,954,448,388,684,848,11,963,993,480,177,413,665,831,661,684,215,216,775,912,485,857,760,905,462,925,18,433,465,68,516,322,257,784,869,919,869,235,220,271,667,491,828,168,159,196,12,193,983,502,579,598,955,397,741,410,298,799,875,981,501,867,316,73,953,802,466,825,695,778,494,18,166,653,64,498,356,649,204,551,779,519,700,370,612,384,631,168,797,194,519,570,524,328,33,647,596,673,670,562,830,422,599,123,81,609,231,180,916,974,973,415,784,135,845,231,357,252,68,422,766,759,498,736,2,399,555,30,316,329,857,34,979,741,81,69,249,977,419,387,19,481,823,745,815,228,776,802,872,40,171,468,920,810,804,429,704,593,921,856,858,596,355,845,855,437,316,599,274,471,156,190,999,44,131,706,824,63,989,657,721,215,904,190,180,197,570,997,940,358,285,558,141,591,617,443,480,666,733,393,742,736,33,766,838,744,936,324,793,824,415,472,101,655,811,472,475,201,23,360,611,750,520,181,807,572,125,824,440,641,511,926,339,402,63,669,318,641,347,308", "766,435,338,551,839,821,680,654,67,771,943,666,117,433,302,661,500,280,450,265,445,486,507,852,253,266,526,540,13,532,717,518,435,64,864,344,999,972,848,740,734,769,263,474,205,641,598,768,522,68,710,336,135,206,385,298,925,952,950,956,494,119,504,365,884,869,747,13,263,673,489,310,751,326,507,650,112,144,387,568,51,690,923,707,752,793,172,285,729,385,434,607,178,404,697,877,906,144,888,862,382,999,71,154,52,547,12,197,295,103,856,651,590,10,548,229,575,932,200,927,338,991,728,843,859,490,8,438,774,525,80,341,879,950,138,959,164,363,78,429,248,173,205,861,54,988,880,952,280,898,845,94,521,355,455,526,263,696,57,665,755,267,104,680,236,701,46,852,698,889,102,573,138,800,310,635,389,746,180,785,779,979,316,514,828,76,825,645,709,450,946,271,981,421,722,698,79,857,526,634,604,212,951,325,144,912,804,826,570,388,367,270,844,716,196,685,467,515,255,121,923,394,881,210,308,412,271,821,640,86,437,85,574,75,653,482,277,579,154,560,171,767,994,108,119,981,351,504,249,832,140,359,151,671,432,428,251,205,280,689,67,257,515,242,42,791,982,904,634,78,657,646,368,833,98,383,212,849,399,75,103,945,611,807,807,909,812,523,136,333,938,120,639,371,840,739,365,379,754,528,614,611,306,41,696,54,69,745,506,441,595,413,943,421,574,649,349,20,860,480,622,101,641,473,872,447,303,809,462,674,705,675,180,429,747,4,717,825,477,136,533,779,773,224,166,740,154,17,126,454,981,750,553,156,41,693,748,780,112,955,873,256,87,286,187,376,586,75,878,815,841,170,750,414,77,230,419,410,200,298,341,548,997,128,850,748,422,932,512,927,888,59,32,241,858,78,830,683,389,807,86,613,134,490,475,450,995,276,202,967,232,802,189,864,398,851,409,778,880,561,10,145,296,231,497,315,842,828,946,8,727,0,633,718,61,454,338,50,719,432,194,675,478,89,79,115,623,283,178,397,63,706,760,219,828,289,774,948,590,614,835,660,727,286,584,969,868,564,899,893,43,455,301,735,864,550,78,14,83,362,234,764,47,50,298,908,423,819,979,830,803,937,734,375,285,971,704,149,830,261,999,860,225,480,55,279,518,870,38,654,79,292,810,3,806,599,295,185,168,615,66,910,640,796,83,771,640,607,616,816,295,158,455,676,241,490,581,962,993,421,246,186,417,589,657,215,491,348,715,290,93,413,412,180,123,538,563,492,24,494,296,685,673,356,903,961,251,941,844,903,128,635,233,736,428,720,268,516,259,648,57,558,723,785,276,57,621,885,317,706,263,849,673,493,784,42,554,755,494,769,400,596,566,954,59,915,188,126,194,856,472,568,960,830,651,632,973,69,132,59,275,445,208,455,300,924,973,783,743,837,755,80,958,214,271,347,932,273,221,416,504,546,430,754,517,354,502,693,856,935,7,738,956,168,823,585,589,136,523,408,624,571,660,285,160,612,73,23,348,932,180,186,405,363,673,817,721,957,677,442,638,46,985,257,795,277,661,383,42,230,142,63,698,184,324,15,13,250,686,106,78,348,861,1000,58,576,321,879,725,45,648,39,367,354,380,905,914,76,102,960,91,581,604,584,222,98,229,573,686,766,47,3,465,603,764,351,651,401,772,357,66,967,500,812,731,136,733,99,194,213,388,550,755,857,391,925,776,975,383,456,123,394,311,972,939,486,730,703,365,958,656,331,40,924,978,347,599,728,637,818,729,160,760,959,744,211,383,966,93,181,367,882,309,758,415,918,875,705,75,991,732,534,290,367,979,383,33,458,533,962,684,690,965,96,971,884,779,655,843,878,852,594,333,173,632,947,373,646,280,602,22,232,682,279,496,973,169,702,293,775,212,953,969,569,203,150,55,183,625,272,753,941,841,530,438,801,839,989,62,644,283,216,382,798,885,920,324,446,933,479,28,240,771,610,311,426,319,255,834,152,815,708,383,11,434,762,742,969,593,585,639,683,847,839,192,491,577,773,771,231,696,180,573,417,641,812,591,278,174,697,815,984,76,942,9,766,951,322,153,668,863,770,61,812,372,409,822,588,657,121,856,977,37,330,349,782,517,346,54,498,881,299,832,89,789,595,620,640,814,168,92,674,357,924,996,675,273,426,355,87,149,666,60,591,425,167,206,217,687,841,396,690,147,366,543,834,837,702,446,343,937,62,128,245,156,112,833,37,710,636,235,982,42,990,918,845,460,219,302,351", "368,364,476,855,86,883,736,494,713,557,467,440,90,927,938,774,890,988,337,848,608,789,602,966,635,918,601,883,946,919,77,159,102,288,681,457,414,871,631,668,306,487,263,83,744,126,165,203,813,766,320,130,996,2,155,80,532,659,505,634,688,112,221,305,759,525,453,796,343,918,97,246,179,222,188,501,344,524,302,780,637,167,290,820,324,373,892,811,798,483,618,258,358,858,811,333,136,684,215,178,147,804,392,888,146,287,529,500,963,384,528,238,646,527,446,249,263,902,543,536,2,468,16,603,795,368,157,148,923,221,981,315,267,345,705,440,908,338,880,334,556,734,445,521,169,985,204,158,839,426,842,804,232,12,947,582,962,160,768,478,679,43,763,896,445,755,271,7,114,481,987,408,973,406,98,770,46,510,458,305,268,567,508,961,167,644,391,25,372,92,135,579,950,266,194,313,35,491,200,641,618,785,948,778,887,355,813,473,73,469,49,422,88,222,849,978,955,128,371,629,474,893,760,109,193,214,122,757,35,767,722,88,987,497,960,145,139,668,685,365,909,386,552,317,132,413,838,958,774,584,427,879,400,628,974,667,112,103,801,19,145,799,926,458,503,66,864,196,840,530,318,219,827,166,80,596,577,271,494,539,79,55,496,793,348,612,246,695,587,623,778,340,334,76,383,112,289,822,831,114,545,8,119,131,784,252,469,839,82,240,77,955,923,490,539,29,935,237,190,76,611,186,137,856,569,666,949,741,694,439,673,633,367,731,547,993,135,518,926,50,64,660,206,298,625,911,988,408,696,348,979,842,995,494,247,896,208,552,88,779,885,670,464,85,4,304,291,933,23,492,256,185,469,532,287,639,322,326,177,873,638,623,467,20,302,842,419,235,403,665,276,441,794,789,631,521,160,829,315,721,803,518,708,636,190,910,2,558,761,696,978,451,472,267,919,16,355,601,217,36,162,535,137,121,367,849,487,163,777,27,229,633,0,78,28,988,169,859,996,715,462,898,609,101,425,972,5,891,250,357,593,976,459,293,486,857,714,420,962,530,487,757,453,519,785,774,510,644,921,463,373,309,80,797,462,739,584,473,113,376,847,796,414,539,680,436,210,492,967,584,143,583,387,979,79,370,994,699,817,836,845,486,597,75,205,893,895,399,481,534,548,742,733,480,95,487,41,889,6,711,248,81,548,54,999,708,936,542,848,481,489,99,379,996,657,485,348,615,614,806,318,506,995,912,233,792,585,530,205,877,110,553,284,272,661,779,62,417,587,553,976,557,764,232,999,261,232,588,246,442,311,716,582,782,838,719,956,383,444,990,184,348,909,851,540,893,646,737,978,729,457,583,528,550,467,795,153,663,264,902,590,178,680,343,565,996,658,565,711,585,95,513,269,799,697,3,223,141,966,311,123,121,562,676,131,669,826,266,975,766,922,21,530,123,902,598,138,432,915,981,412,836,454,728,429,831,240,640,596,40,736,864,801,477,855,113,952,537,398,992,363,161,564,977,120,305,884,988,419,596,996,544,78,726,959,969,215,366,799,102,259,479,614,289,156,922,44,236,206,397,25,742,757,692,660,316,717,565,531,120,291,454,30,677,71,284,224,724,796,726,97,242,639,437,989,162,733,278,646,970,944,30,452,506,50,150,584,172,231,522,966,615,795,398,755,586,112,86,220,17,945,90,32,384,558,372,888,47,818,470,565,42,932,443,752,939,470,293,936,674,151,517,130,274,580,9,453,124,533,150,593,562,993,38,453,83,375,740,908,23,475,377,539,373,555,466,745,742,570,213,579,966,180,477,78,712,761,127,146,306,504,714,488,604,986,46,614,270,847,997,102,516,551,862,565,966,827,686,336,745,955,427,927,758,288,842,981,515,20,182,606,697,4,342,805,863,981,56,887,769,918,604,137,118,50,129,250,893,145,278,139,636,199,585,655,271,319,383,182,161,587,61,211,275,543,180,690,857,988,590,469,836,354,56,976,845,757,166,38,672,675,819,759,907,673,834,985,947,180,785,886,845,591,959,668,10,878,224,744,106,290,325,189,607,910,906,695,157,831,811,897,183,102,237,249,730,609,954,744,963,628,87,356,122,451,565,716,819,848,756,763,688,828,502,895,339,409,549,838,80,288,427,908,543,527,601,421,254,439,374,685,841,854,180,183,66,621,805,905,139,582,472,637,910,685,166,676,310,117,642,284,297,35,850,151,41,315,548,809,347,649,111,433,392,277,40,406,365,649,689,7,592,809,730,283,198,351,465,905,863", "31,415,193,570,52,356,812,491,260,523,271,747,153,515,320,29,574,889,621,874,363,569,267,48,378,93,79,807,361,266,693,894,386,941,624,65,830,697,997,780,891,993,895,75,746,124,188,116,827,558,583,135,691,812,958,615,117,930,367,92,298,563,668,361,10,455,13,325,118,152,253,922,66,663,914,940,582,45,753,706,789,769,137,594,846,986,844,24,229,766,29,323,365,410,224,368,249,477,388,308,992,907,867,243,342,689,350,554,572,714,621,35,878,669,270,61,861,158,118,757,278,157,927,869,681,591,278,59,38,141,810,65,979,225,165,394,229,514,601,887,437,740,166,894,642,759,292,696,348,336,100,785,429,446,837,124,549,860,444,755,515,118,813,689,212,221,934,626,423,944,132,302,355,956,316,606,136,675,645,766,608,786,409,893,787,26,404,178,606,409,593,479,341,476,706,385,246,664,443,698,387,735,545,759,392,276,327,627,357,104,334,875,993,893,633,658,928,73,422,158,925,950,287,954,948,264,258,195,452,814,755,441,21,156,913,630,458,702,94,853,650,471,422,607,206,655,575,488,313,402,852,622,914,442,270,119,300,456,401,793,800,989,76,212,146,262,217,300,448,774,584,838,912,834,615,676,132,230,331,647,703,426,480,454,541,527,960,272,292,249,167,723,795,774,278,103,840,110,40,565,158,88,366,347,633,946,892,297,60,28,216,331,602,494,963,999,244,462,858,993,60,500,980,976,559,26,508,14,441,543,134,569,115,508,215,88,333,714,576,515,551,409,469,480,383,893,944,226,104,205,951,352,105,330,38,314,731,559,448,407,779,711,199,966,107,922,367,954,130,808,796,899,961,283,58,201,870,154,459,688,694,881,980,347,831,592,467,904,646,956,943,923,195,876,787,854,915,682,636,777,10,948,546,557,559,78,273,472,172,558,199,505,724,616,444,650,682,251,460,329,658,532,573,19,260,690,752,884,482,437,574,718,78,0,445,971,637,627,875,265,105,307,212,908,688,910,948,823,735,581,616,93,465,197,511,421,644,887,774,304,966,175,864,115,21,931,883,280,686,170,607,83,356,651,110,818,492,340,549,380,589,615,452,441,654,114,946,936,318,665,741,328,460,277,576,452,862,529,962,184,510,588,438,486,229,204,750,49,424,57,546,4,222,891,298,656,631,346,952,920,643,221,46,924,837,255,233,68,752,925,456,6,819,480,139,357,620,369,22,367,55,903,810,755,654,359,659,947,399,678,504,298,402,747,11,909,280,832,172,506,309,788,441,664,465,164,718,796,338,373,54,771,827,384,517,443,67,362,753,806,58,857,585,951,478,336,132,357,3,425,765,527,580,461,471,814,591,251,26,937,272,905,910,478,141,109,574,957,386,133,732,883,328,930,721,52,463,8,65,430,411,30,968,429,636,661,753,52,577,462,977,299,514,553,10,898,562,101,882,267,750,929,562,999,717,688,2,708,87,95,844,257,661,49,824,457,15,174,548,447,907,564,745,804,151,146,976,358,630,609,113,225,786,557,733,7,815,852,392,153,188,298,980,714,529,192,753,595,710,130,749,926,611,653,982,46,490,348,779,898,461,357,110,215,458,416,221,647,158,771,180,765,654,747,384,915,660,918,592,864,561,559,267,478,117,449,75,183,478,207,236,250,568,735,606,83,647,331,622,361,333,360,479,401,147,718,25,341,621,420,13,279,689,158,778,588,112,31,369,25,132,435,486,570,608,248,968,204,200,168,978,778,354,71,153,610,348,880,348,304,764,636,969,532,798,750,208,309,466,416,96,958,871,32,681,543,752,528,396,380,702,692,494,330,726,647,351,755,100,929,448,176,711,727,335,260,95,523,214,763,544,411,743,561,480,874,28,188,231,291,467,113,169,592,712,385,219,230,431,185,791,992,116,37,759,880,304,31,558,946,115,325,679,567,576,9,123,179,406,706,825,824,644,638,999,399,696,559,887,302,918,150,239,266,839,654,270,714,146,342,65,322,989,30,613,469,69,720,483,539,408,347,414,132,303,173,84,686,435,498,510,314,532,784,932,959,870,869,243,841,695,287,314,274,196,120,375,403,208,28,29,269,54,601,308,225,300,36,726,251,94,924,94,453,151,818,637,790,774,904,799,811,718,672,887,718,419,46,348,975,562,935,776,875,102,34,52,85,640,494,320,56,29,790,307,358,752,218,877,572,836,190,650,64,280,160,591,860,158,678,990,234,572,180,363,373,598,715,393,359,341,142,46,452,911,701,750,985,190,796", "561,614,735,15,523,825,763,878,556,353,948,400,956,741,643,45,787,589,301,445,933,502,975,238,995,70,249,934,652,311,559,358,94,736,8,439,723,387,673,347,530,44,335,637,517,16,60,111,38,211,826,466,34,936,831,106,730,624,534,636,887,554,576,280,863,652,415,356,106,311,706,570,533,520,379,181,77,611,10,116,941,642,216,958,521,390,58,494,580,245,271,708,434,666,998,871,1,607,223,940,327,184,713,800,700,785,801,578,660,743,800,148,498,505,622,773,698,52,100,665,89,828,68,920,700,577,720,282,687,186,665,606,247,855,351,506,852,589,307,879,598,971,590,279,81,869,290,835,705,712,218,96,477,387,980,657,729,629,67,64,264,732,938,110,648,103,854,833,964,636,744,80,724,697,524,377,773,555,876,125,422,125,897,886,434,440,338,126,762,671,245,465,135,652,602,537,917,594,383,51,751,205,490,291,251,937,462,100,488,413,691,71,862,214,911,577,219,929,620,621,147,540,126,869,993,477,907,229,994,473,381,484,322,461,297,513,785,192,195,205,139,953,867,200,934,330,733,531,804,847,607,368,20,420,362,753,753,352,602,286,794,99,887,192,693,496,490,497,634,140,40,548,319,914,552,825,707,378,941,429,108,869,384,200,733,413,996,519,616,113,787,287,48,495,846,917,21,484,820,147,5,827,809,805,781,8,793,483,889,276,496,625,996,160,850,802,58,389,452,842,167,391,269,820,6,25,861,253,292,733,840,366,247,931,121,919,102,163,312,580,566,828,518,319,586,433,619,762,634,226,751,263,177,755,197,883,829,967,374,882,726,480,458,415,217,577,877,855,197,538,943,36,198,898,308,379,596,932,18,226,167,435,592,22,168,433,830,115,288,149,841,445,355,352,564,716,511,193,192,901,539,508,463,567,290,273,782,211,893,136,387,865,903,458,545,178,32,417,252,193,165,516,230,632,551,509,700,179,625,594,451,61,28,445,0,869,873,714,695,82,510,566,91,289,791,994,455,220,27,96,129,348,546,638,785,807,404,274,780,604,159,660,840,327,463,849,996,624,179,42,71,418,923,217,791,369,466,913,746,476,756,837,798,544,969,87,974,790,763,969,242,605,247,219,753,767,58,23,110,945,134,327,709,69,911,831,791,79,152,973,608,622,617,281,571,58,124,602,665,50,11,698,874,815,258,790,585,953,509,734,454,843,153,129,653,160,617,494,931,440,351,691,340,950,858,442,929,648,806,503,781,254,97,922,462,655,42,636,447,988,280,576,338,161,713,716,862,777,755,101,50,579,758,780,448,245,366,106,736,768,726,463,729,881,280,666,164,806,703,936,262,459,17,98,55,184,909,925,588,146,274,604,819,685,556,522,398,844,528,92,431,911,425,153,907,689,701,71,832,16,550,255,403,4,81,914,346,207,485,369,326,403,95,145,949,179,893,616,146,581,605,718,831,503,571,639,261,226,752,988,600,753,573,821,919,508,111,134,688,986,109,250,19,429,648,146,882,506,389,525,132,253,58,739,844,989,571,938,870,162,862,285,968,894,556,26,172,940,841,952,365,463,169,172,342,471,274,129,233,268,310,701,904,142,821,733,148,764,534,152,33,104,853,996,216,334,853,894,357,215,552,881,840,625,972,191,888,782,922,780,945,33,609,595,380,381,289,151,747,43,893,206,409,168,60,204,64,815,967,957,783,705,440,207,453,459,886,950,756,911,389,57,561,715,934,167,413,523,485,431,464,886,841,855,462,95,392,894,107,229,287,50,797,458,273,770,640,770,29,924,434,38,681,21,369,121,834,266,895,931,342,736,769,616,202,678,541,791,97,392,408,809,911,934,209,640,702,752,957,141,363,234,469,365,970,782,35,845,620,662,30,879,686,709,938,938,29,594,658,256,474,209,478,417,494,592,714,719,169,174,909,180,678,584,181,949,498,984,512,777,293,387,390,92,424,941,653,222,439,458,78,631,611,523,166,73,12,656,378,112,100,177,240,462,601,669,88,162,812,587,195,562,319,671,331,910,910,765,905,816,210,448,367,845,297,503,621,596,749,127,366,177,698,41,500,626,204,657,280,636,300,870,149,894,103,409,429,613,259,994,306,358,555,141,163,890,877,440,787,980,681,402,682,132,390,309,966,270,61,40,20,520,93,296,268,636,684,15,141,834,107,853,522,36,773,284,383,338,720,400,577,714,28,4,23,863,117,65,702,520,916,175,532,774,126,976,539,958,541,489,514,570,812,491,60,318,739,989,778,188", "537,571,106,700,396,69,985,548,943,20,753,724,392,195,859,711,667,718,823,503,267,558,245,562,983,854,399,193,296,596,790,595,475,266,177,888,906,190,431,680,629,315,960,390,132,706,389,148,719,994,539,814,576,388,393,213,409,151,464,303,132,458,644,440,260,695,946,732,990,818,870,491,710,698,243,642,524,313,920,943,180,366,530,9,591,404,598,470,62,539,240,914,244,486,533,827,799,14,794,767,155,602,925,866,617,155,275,460,47,746,282,970,663,662,732,164,372,469,648,682,916,546,599,884,247,458,377,366,25,230,215,811,122,440,85,441,410,642,661,174,560,97,699,382,10,534,685,83,130,764,426,53,679,804,401,231,310,419,51,906,150,670,968,212,552,742,691,101,151,523,418,46,627,786,299,105,307,286,131,332,594,898,36,598,12,533,452,921,80,730,62,732,430,824,258,749,191,496,265,769,86,208,255,124,586,714,859,339,248,834,194,163,148,852,828,34,681,882,233,129,710,403,612,657,418,377,555,889,11,89,190,901,646,934,561,605,193,171,796,356,231,958,609,57,609,523,200,275,655,466,983,934,871,964,13,440,67,628,731,444,706,755,675,465,126,490,267,60,610,174,583,443,224,130,397,281,376,867,387,11,435,473,730,652,938,18,470,977,846,996,858,567,646,823,403,31,547,618,153,176,919,484,789,401,220,945,218,886,650,10,650,883,525,740,109,513,509,162,863,467,492,183,440,407,817,729,162,584,497,451,705,570,789,80,566,498,244,255,525,961,909,734,428,635,715,873,475,184,887,339,747,130,752,829,920,916,534,602,613,253,528,364,312,431,354,403,610,216,272,941,75,193,319,985,846,320,609,853,556,4,280,314,969,137,668,515,993,528,886,285,7,688,508,672,896,210,57,28,480,641,535,670,536,509,641,16,31,131,685,336,156,853,130,555,356,280,685,126,393,643,988,815,1,942,794,226,144,374,377,126,30,454,988,971,869,0,490,495,430,48,404,335,436,772,538,544,376,714,443,281,103,214,854,752,267,644,331,273,349,112,675,465,448,434,621,200,767,477,865,192,170,136,577,285,913,782,188,197,379,804,834,421,480,523,295,22,246,192,710,698,674,691,442,125,649,313,502,834,645,278,213,910,150,768,75,807,866,161,427,817,293,765,891,217,941,988,20,650,418,894,81,39,349,744,773,371,403,202,786,532,940,942,121,40,329,670,879,151,376,648,604,342,870,518,894,956,939,43,335,116,726,209,470,263,577,640,390,397,213,537,779,305,13,589,565,719,984,437,293,808,252,526,909,381,275,723,986,959,869,904,215,561,507,976,364,172,328,980,207,928,594,617,718,501,695,434,490,920,987,236,678,956,204,384,403,754,749,239,225,76,262,710,573,740,454,179,844,69,284,755,803,924,696,493,179,31,767,371,647,660,820,715,376,377,893,528,792,247,617,801,985,331,525,713,413,730,299,735,202,299,729,881,652,462,915,606,62,813,479,867,375,978,797,348,18,986,429,405,541,677,5,722,915,148,617,32,333,722,138,924,707,611,586,960,649,428,858,356,68,939,611,757,819,436,401,558,209,587,557,867,644,316,487,213,181,519,719,848,786,688,434,801,235,434,151,275,258,340,182,598,9,960,654,841,21,611,682,980,115,954,397,869,294,519,456,884,147,349,4,926,200,35,767,110,542,554,628,636,599,81,541,374,588,571,632,295,649,635,23,264,696,949,344,481,154,537,439,187,482,208,699,518,718,994,122,757,682,862,805,788,356,424,728,756,183,739,958,646,631,79,815,397,361,779,666,677,139,148,792,5,881,7,761,332,870,665,977,106,230,365,578,367,934,444,695,473,602,953,648,248,533,961,93,590,515,986,78,475,592,588,323,652,911,987,276,58,894,211,568,423,802,334,330,395,816,757,514,91,272,241,358,120,593,708,614,830,975,993,32,976,960,613,576,133,502,112,234,58,609,253,769,37,967,480,865,455,912,583,213,249,467,786,810,40,977,964,546,746,25,652,908,418,107,510,32,141,634,869,792,752,598,103,894,568,403,80,435,478,493,6,529,243,217,420,149,518,305,80,456,338,870,250,93,836,338,67,242,112,980,394,663,947,124,53,449,701,14,748,546,650,719,427,338,365,828,11,450,762,515,910,8,163,607,270,796,289,274,245,761,246,364,618,796,850,895,357,497,759,878,845,149,261,149,547,598,732,315,681,881,601,586,41,955,689,882,309,503,865,621,595,388,488,39,325,489,940,898,452,766,132", "962,145,716,400,839,512,268,653,617,368,334,922,710,680,995,372,220,338,717,944,474,395,190,898,831,406,11,515,738,171,725,539,586,124,770,801,477,819,929,845,16,765,35,130,381,582,180,622,990,491,54,864,960,220,618,60,405,269,130,461,103,329,43,659,235,228,919,458,379,831,658,652,739,29,438,127,897,801,349,575,869,824,614,566,538,77,396,387,169,590,71,207,579,670,926,77,545,965,838,633,637,340,83,406,287,815,566,200,528,132,31,314,818,806,21,252,634,606,452,917,931,370,551,912,108,129,378,130,213,288,330,290,842,315,59,296,717,918,1,826,452,451,970,331,292,399,546,919,6,303,469,747,273,756,337,503,232,539,372,111,517,98,178,628,994,473,759,635,387,302,528,304,4,155,97,824,232,730,430,200,56,506,378,4,420,805,630,162,192,85,230,51,769,491,17,419,136,208,166,887,291,985,862,720,806,378,961,509,5,570,160,974,422,945,81,777,225,738,862,293,744,468,504,487,953,490,606,710,960,677,32,57,863,297,396,779,925,112,901,765,832,7,943,768,831,446,466,162,131,249,741,58,328,559,599,534,897,983,25,467,136,113,453,706,558,42,549,723,106,749,699,33,385,882,710,48,468,581,806,40,238,454,147,720,478,357,656,996,141,88,807,136,327,607,818,202,823,659,3,863,847,113,259,567,503,183,943,887,558,155,436,230,904,308,872,278,315,476,231,793,310,620,577,628,126,425,249,872,44,367,709,772,268,538,599,339,23,538,701,706,475,216,817,487,172,390,791,394,509,275,21,434,860,595,264,772,498,283,643,347,608,17,560,647,480,85,21,122,458,763,571,887,878,160,490,417,869,91,819,395,606,383,902,419,974,504,866,924,902,394,383,251,14,708,763,21,171,706,894,665,907,5,943,107,273,594,614,129,503,76,886,961,469,9,682,562,412,360,81,40,75,85,696,591,451,120,661,949,70,14,657,338,169,637,873,490,0,343,898,655,389,556,98,607,926,415,216,665,68,275,478,925,149,10,907,783,734,963,155,290,836,75,245,708,676,341,608,541,181,471,662,925,131,705,526,811,84,564,134,786,309,273,745,58,787,717,910,316,619,61,442,342,560,659,269,157,814,705,234,105,244,28,76,780,898,487,503,899,75,329,691,554,241,277,986,111,563,670,364,661,820,564,131,255,770,654,153,205,747,894,858,249,929,48,646,325,353,552,318,622,60,403,659,300,669,813,561,443,848,670,588,419,611,404,136,234,966,136,463,525,539,615,837,663,369,832,474,650,241,710,1000,470,118,889,782,706,932,322,525,883,396,111,580,484,397,650,81,889,687,589,879,361,73,452,785,327,826,180,598,841,4,20,383,398,486,592,287,111,27,106,496,829,822,982,283,921,739,906,371,196,158,353,81,833,740,941,494,538,853,793,379,58,751,55,887,930,739,634,203,200,751,52,970,500,26,100,149,421,747,879,756,779,251,363,565,84,639,740,196,332,41,433,131,795,903,250,656,346,803,318,517,658,617,822,509,437,880,591,266,269,669,736,979,682,116,388,781,920,810,657,730,621,757,379,902,265,936,463,869,497,900,837,141,476,13,89,490,558,468,182,55,527,229,788,578,646,527,167,418,912,43,974,174,602,140,709,345,333,179,901,850,335,455,192,107,11,826,699,779,649,67,228,893,425,836,480,18,945,660,840,15,226,180,642,515,7,471,140,134,60,956,108,310,898,586,760,286,671,399,777,597,146,351,607,942,682,395,556,962,987,593,730,1,738,16,864,917,58,317,231,392,745,955,578,1000,244,24,72,806,621,269,993,57,586,52,12,890,933,732,907,968,631,650,418,367,818,453,135,583,813,216,795,946,986,588,254,290,802,899,301,837,137,212,852,446,804,916,752,224,650,555,604,164,362,659,36,485,498,918,563,312,110,692,571,994,823,403,266,434,211,770,892,353,499,886,106,708,665,995,778,129,244,136,549,350,725,262,836,350,482,112,456,603,649,695,303,374,677,733,87,49,911,255,331,526,568,625,731,818,512,233,171,154,981,251,628,703,995,516,806,682,43,428,575,646,636,712,851,103,272,48,326,921,425,961,50,993,802,3,675,530,751,53,654,452,842,961,630,918,482,816,48,420,673,800,391,493,574,354,449,573,921,597,903,402,57,313,97,187,365,503,307,768,807,620,359,91,522,228,387,255,725,5,830,554,846,771,85,825,266,296,265,584,947,199,979,776,387,418,721,73,528,795,217,176,439,535,948,564,289", "873,888,479,897,841,984,815,600,164,699,585,24,193,902,705,518,960,350,387,837,42,605,680,597,986,70,505,741,975,68,225,967,20,523,924,478,34,684,197,451,531,701,326,512,750,60,167,261,699,755,888,259,39,558,833,407,359,600,736,723,611,371,556,732,119,381,496,106,906,809,536,49,61,37,215,878,880,431,267,153,478,317,831,564,533,161,506,56,538,180,108,857,688,75,462,277,323,590,220,839,485,331,44,410,300,365,42,246,300,971,404,984,603,382,3,277,868,640,580,367,728,801,996,633,223,598,169,983,619,304,457,561,141,232,466,661,672,718,881,236,182,834,111,637,591,227,434,920,518,86,592,409,454,747,206,710,393,661,16,193,470,101,805,866,206,836,69,230,432,670,718,229,939,894,254,181,884,428,903,844,66,258,934,795,538,358,361,307,634,176,863,947,346,235,977,662,609,570,140,946,140,843,89,563,886,15,596,16,150,805,694,168,978,402,885,144,738,749,286,231,729,75,792,319,245,963,218,882,613,585,744,417,870,299,441,13,155,284,360,418,338,719,977,133,952,825,985,869,199,713,396,270,426,848,929,965,311,244,3,620,30,822,293,672,503,878,953,922,546,861,759,170,794,915,22,365,486,253,479,9,529,161,73,778,736,806,712,341,311,41,987,659,455,82,592,310,42,675,639,875,475,907,172,856,399,829,799,150,92,670,436,15,912,392,495,227,850,653,539,855,568,557,846,221,623,893,799,366,451,805,997,920,138,621,303,475,875,2,984,205,950,45,465,623,885,393,719,930,463,929,157,807,630,962,241,814,845,437,109,53,697,957,583,605,586,626,891,88,331,389,658,212,863,689,891,677,786,269,247,785,888,361,247,412,198,475,39,807,208,166,16,848,579,554,628,36,685,531,449,534,270,357,992,492,223,846,757,330,316,477,12,210,787,16,27,396,888,432,237,63,641,616,7,849,637,293,380,357,305,469,239,50,859,627,714,495,343,0,694,577,754,56,626,976,219,649,513,247,109,744,465,243,242,328,640,120,604,784,696,423,895,628,14,145,144,254,626,983,733,326,626,970,790,70,719,583,823,179,577,847,120,679,834,511,48,988,829,142,89,369,483,447,476,176,1,643,166,319,56,658,585,584,721,945,904,848,876,16,675,768,357,865,540,141,207,396,451,113,766,906,877,449,8,200,848,532,689,973,987,528,778,849,321,308,724,808,789,961,202,298,847,703,97,315,404,904,810,649,952,992,821,314,384,751,22,143,833,708,659,210,35,44,372,170,834,924,997,505,218,827,751,726,192,178,958,925,233,960,647,741,50,466,870,232,294,203,546,507,788,896,32,620,269,868,735,484,295,338,424,433,734,738,913,925,137,260,233,246,410,78,181,211,302,59,527,511,353,8,935,620,457,322,98,636,798,6,790,74,839,307,165,890,579,360,595,499,242,61,687,860,599,882,388,248,172,671,79,232,187,68,169,938,543,921,950,314,648,943,16,382,140,170,531,889,154,734,534,563,693,842,374,26,900,446,371,812,686,908,180,991,726,834,217,290,501,520,310,583,462,841,14,50,644,844,4,244,890,697,574,494,299,998,455,461,225,138,745,484,814,521,346,105,710,659,284,983,34,147,125,656,325,315,294,379,566,109,885,518,110,133,45,241,85,593,288,287,149,277,848,223,299,814,574,687,974,358,834,118,989,325,198,441,471,527,222,380,804,276,98,202,479,636,304,460,322,557,559,188,607,606,670,318,106,296,680,887,307,333,340,182,580,757,6,363,578,414,810,886,773,19,117,837,544,977,510,600,890,590,557,774,226,115,441,649,794,34,521,662,178,308,697,656,498,218,569,583,57,319,458,454,82,243,407,383,341,329,800,103,141,710,718,804,469,847,274,980,280,361,147,529,303,430,189,480,887,409,740,951,441,641,850,542,120,653,85,498,207,911,447,603,797,437,822,848,442,473,353,393,811,102,808,83,515,629,96,493,338,341,185,287,208,88,291,675,621,849,822,960,724,280,528,440,41,563,23,683,647,447,164,349,958,277,53,952,954,252,582,927,832,42,434,165,339,166,550,669,145,251,33,623,431,220,352,350,816,934,206,205,370,977,533,49,585,793,911,674,76,850,510,688,454,280,383,226,12,150,315,886,190,923,69,273,754,445,177,873,718,12,596,374,601,570,850,875,96,364,782,862,732,215,408,49,482,81,486,551,518,820,109,408,894,204,676,476,122,741,904,524,184,384,230,593,895,694,720,987,852,670,645,588", "902,999,344,800,707,694,64,912,336,795,97,760,713,547,319,700,613,753,276,139,84,413,260,170,674,277,886,515,512,757,499,828,660,187,524,293,256,864,453,193,139,478,877,133,412,24,842,173,97,494,191,996,719,779,405,55,548,101,145,689,905,247,275,615,454,409,946,71,795,887,367,778,330,320,561,360,433,715,893,534,808,433,178,909,714,25,507,200,934,768,577,595,379,529,887,59,123,307,585,366,743,388,922,878,930,345,297,267,649,979,513,351,65,508,485,75,338,587,536,658,51,635,858,308,822,127,859,906,652,784,86,450,361,40,191,404,193,946,948,531,61,829,90,121,312,162,965,214,776,267,600,41,903,633,947,918,220,966,509,680,833,453,941,793,711,644,732,322,14,964,381,156,784,841,711,696,834,361,205,839,940,688,216,34,99,82,493,318,869,349,172,839,320,868,128,326,845,539,73,774,853,184,920,872,929,954,145,686,973,870,336,622,755,659,650,825,484,407,15,76,278,848,683,482,42,343,300,866,396,253,976,854,312,554,967,697,646,474,292,407,835,902,66,274,734,33,959,623,726,780,699,685,761,494,691,653,325,712,760,316,524,637,162,592,142,346,655,720,955,829,79,377,614,230,56,763,637,883,53,975,820,867,987,715,109,646,949,394,506,593,794,654,763,81,116,419,932,316,69,168,481,665,790,54,15,245,414,214,403,102,408,431,7,966,39,638,475,219,615,686,320,134,82,350,994,368,939,454,419,318,513,732,237,92,154,220,204,411,595,410,658,774,996,317,323,327,483,971,653,184,35,439,772,186,566,73,613,829,891,813,433,286,152,556,958,733,952,172,734,357,573,494,967,22,500,153,963,696,866,438,529,625,523,919,363,946,321,517,370,70,771,962,215,104,953,605,198,267,563,770,568,257,480,144,390,583,189,60,4,773,186,242,593,401,952,261,291,80,607,341,168,369,530,161,909,100,15,268,802,462,717,719,996,875,695,430,898,694,0,396,468,449,24,220,31,701,784,748,197,659,637,397,486,323,829,593,376,793,77,988,443,572,381,201,637,457,510,514,180,586,593,967,580,856,720,725,613,8,508,75,523,149,126,805,834,751,381,988,571,898,946,403,600,994,985,310,477,702,706,477,876,25,372,950,108,964,410,276,567,405,61,63,40,550,176,425,505,401,469,441,199,553,659,40,825,446,649,492,298,368,157,603,948,201,781,878,956,455,25,8,863,350,529,545,222,933,791,844,563,404,471,365,331,99,217,943,685,821,527,427,539,389,582,69,735,348,701,75,616,985,985,636,679,382,640,433,283,606,341,469,636,570,282,350,401,509,547,293,271,451,296,147,152,439,758,44,893,481,355,359,57,398,799,801,819,366,104,610,506,26,486,496,823,76,459,395,444,788,993,97,506,78,844,521,530,381,901,588,296,698,310,643,511,662,48,374,700,750,867,552,470,238,83,100,492,745,881,628,948,188,772,201,105,829,142,531,18,606,61,726,484,708,330,486,752,566,574,526,815,386,355,559,852,488,490,313,68,341,56,775,738,536,256,241,688,196,349,847,605,95,34,589,687,869,822,772,49,495,914,265,451,118,371,840,608,426,475,366,264,290,435,457,304,129,389,242,78,955,364,531,340,312,426,357,41,549,482,154,960,30,674,522,29,821,758,253,966,673,152,510,47,750,911,601,339,466,259,159,585,687,417,655,507,198,574,527,192,222,947,46,447,768,685,126,225,151,838,634,405,751,952,735,974,221,653,78,75,509,565,121,354,221,484,603,83,546,289,37,588,741,809,477,649,865,148,809,639,114,999,891,692,873,5,298,76,735,819,405,527,959,711,421,176,169,809,718,200,31,743,102,603,138,84,815,705,38,125,887,219,260,92,958,99,797,814,202,149,259,248,5,176,659,873,8,120,153,232,510,453,588,624,771,27,433,758,982,62,494,484,904,954,526,394,913,208,688,43,574,827,969,102,184,309,830,401,774,294,811,213,610,60,502,737,796,16,113,471,815,883,101,754,602,757,375,454,129,594,147,232,363,59,374,347,952,214,541,622,521,881,772,103,791,226,233,912,763,776,928,73,27,164,844,874,311,444,667,24,586,236,168,896,573,831,493,119,503,77,724,170,137,12,935,936,146,410,555,198,803,447,61,352,912,992,83,193,119,352,814,416,628,527,758,191,971,174,795,277,425,46,787,519,131,112,351,770,90,246,46,227,60,39,762,101,143,499,171,55,915,766,12,6,121,156,539,909,573,706,654,324,713", "529,235,571,53,919,394,714,977,723,229,238,925,359,98,903,104,681,457,904,350,271,935,154,337,68,635,573,2,394,949,34,329,310,905,52,622,674,867,554,517,677,819,98,846,908,904,111,190,89,583,97,579,953,813,737,597,483,205,487,43,246,316,696,66,134,878,357,479,462,786,458,176,233,1,252,362,60,571,381,27,997,506,588,64,892,578,530,585,40,811,300,95,698,167,324,960,481,458,502,828,64,40,993,100,890,760,582,434,706,980,292,739,339,196,854,666,591,6,200,753,532,82,468,52,943,846,619,182,701,751,609,222,155,822,180,577,600,83,473,703,453,84,616,119,574,377,826,291,123,663,560,284,219,971,714,766,749,245,359,146,515,588,999,315,967,896,578,800,161,340,99,638,645,381,229,560,28,581,817,470,951,149,90,665,952,472,78,87,358,948,895,784,607,217,70,121,358,214,669,880,979,567,436,515,207,630,944,714,354,769,951,649,527,904,950,144,647,298,348,959,514,531,419,785,798,834,218,263,467,220,561,359,351,180,55,69,798,731,782,183,99,466,345,24,92,345,149,665,798,540,164,16,717,169,312,74,829,577,19,867,961,787,959,31,4,630,227,334,857,905,69,677,101,664,291,458,609,596,810,700,474,472,492,723,536,105,669,879,213,393,272,16,271,267,268,22,461,355,721,699,896,471,602,755,32,567,106,30,235,936,62,663,899,347,222,270,845,700,446,633,66,54,512,126,85,624,361,544,790,214,68,849,835,80,188,833,110,886,963,251,602,626,319,609,964,353,76,570,634,479,286,765,735,76,410,208,864,737,209,996,883,436,916,395,642,107,687,414,767,255,472,852,640,15,362,775,182,605,627,873,916,767,811,493,538,290,727,244,944,734,55,820,657,930,813,800,359,533,520,845,574,272,904,630,263,709,454,883,38,878,291,775,529,910,525,627,456,725,548,813,308,952,791,419,283,438,236,812,735,171,25,432,715,265,82,48,655,577,396,0,867,796,340,220,293,322,881,986,460,682,693,72,989,63,79,958,196,876,389,531,760,41,149,364,486,374,856,594,313,117,152,169,764,850,280,796,474,186,275,674,662,847,16,489,114,451,325,884,773,199,500,298,412,580,340,759,694,492,771,158,932,787,899,547,532,827,383,527,42,273,145,262,406,184,543,931,497,894,807,301,538,51,884,626,566,259,891,347,507,420,494,695,428,40,386,215,751,951,59,208,162,84,745,804,862,717,863,539,284,658,540,217,882,592,218,961,542,764,484,333,43,703,164,568,13,741,299,677,386,739,711,904,625,516,860,174,33,503,624,107,832,365,114,811,815,627,478,413,330,968,188,294,866,476,481,704,38,602,974,708,668,419,151,994,438,581,804,994,468,60,265,814,191,574,279,622,716,303,430,35,675,734,691,514,33,667,711,460,855,503,189,157,602,7,243,121,280,847,102,246,566,535,566,410,42,811,545,960,762,949,970,855,593,205,298,136,457,145,848,592,226,493,950,209,446,844,895,179,550,671,726,287,723,316,450,252,961,341,454,210,119,724,184,144,492,977,461,598,114,275,423,12,819,723,476,955,917,269,152,797,946,127,857,121,61,949,835,771,659,561,824,687,49,818,1,940,189,8,135,777,952,908,605,703,56,148,697,144,408,484,426,967,535,652,946,512,879,999,186,338,591,557,555,450,380,336,797,587,764,269,579,581,747,176,992,49,477,833,372,174,589,360,863,339,960,248,410,14,582,382,667,233,155,510,363,734,248,950,571,136,679,582,310,298,995,640,710,467,152,94,102,616,124,641,99,211,519,136,91,378,139,268,44,945,460,867,924,648,935,42,969,242,893,347,249,441,589,53,1000,36,685,838,279,531,787,288,856,954,880,531,306,376,892,443,715,84,836,693,59,236,2,273,211,984,151,820,712,479,453,560,810,858,784,139,390,141,157,541,562,931,837,897,868,469,575,33,199,703,406,79,255,853,212,466,344,50,520,394,521,367,709,899,708,235,551,348,7,111,254,5,163,108,621,499,621,996,752,502,94,303,485,253,8,855,576,666,616,556,272,364,448,370,829,978,621,744,685,554,206,559,394,825,772,881,104,529,160,13,133,514,725,123,189,42,161,848,649,919,374,289,26,618,590,512,781,620,951,307,485,705,218,781,218,695,343,257,84,515,597,713,682,737,229,126,879,15,873,559,444,993,178,823,892,402,451,717,121,427,362,511,297,658,945,627,487,669,226,663,502,57,987,138,824,400,146,633,226,657,455,47", "362,727,294,800,348,477,482,584,740,873,555,511,76,616,79,741,992,942,260,39,142,914,733,176,130,294,919,624,88,483,400,980,985,237,190,447,880,15,16,743,932,595,494,223,183,846,310,695,88,848,83,420,524,552,340,559,975,659,270,836,406,938,46,511,681,218,982,995,226,304,329,550,718,166,813,878,148,626,343,843,535,207,283,243,450,146,446,422,201,779,231,417,877,556,497,147,888,159,916,602,814,29,365,896,490,525,122,651,459,996,610,921,320,975,591,207,30,675,233,658,741,50,713,460,831,977,905,799,973,322,549,595,275,385,14,354,622,41,335,669,965,176,105,447,631,322,472,79,265,299,129,330,812,967,511,340,465,1,944,569,399,914,864,815,890,428,421,936,109,501,12,462,89,446,271,332,457,453,863,31,955,412,648,243,437,917,535,508,926,456,562,181,408,714,266,771,386,959,420,330,587,75,570,652,517,478,161,138,301,510,334,55,248,187,890,551,154,693,763,955,15,289,647,852,708,97,267,570,86,530,64,175,558,531,233,381,474,34,848,534,864,126,258,556,28,930,85,218,173,702,384,501,383,244,892,620,382,325,627,591,597,125,563,877,44,593,471,973,370,625,87,3,394,344,833,562,664,88,142,513,798,461,298,276,837,358,58,809,149,844,636,745,898,169,764,619,270,484,755,737,559,619,797,662,40,440,976,571,556,880,337,953,916,605,654,967,422,15,477,322,20,905,721,436,295,463,799,59,742,550,107,160,316,466,546,901,901,417,702,298,671,361,834,675,888,158,26,224,978,636,699,212,860,940,153,352,606,585,659,825,696,251,358,98,909,562,911,106,962,13,318,1000,2,760,513,766,669,149,54,445,915,870,738,46,694,459,130,181,60,791,881,443,577,154,406,914,718,966,811,890,467,422,226,88,42,802,416,796,609,284,908,831,86,275,185,538,483,672,885,679,500,246,55,486,341,349,215,536,152,792,936,194,462,105,510,404,389,754,468,867,0,194,43,801,13,718,210,541,234,577,762,32,681,343,57,713,659,355,468,563,765,387,362,955,436,258,532,837,837,391,150,702,218,215,17,76,952,499,127,554,108,495,186,268,811,201,847,80,36,233,588,699,897,80,842,89,868,790,416,529,326,522,301,605,410,585,283,442,602,567,198,287,764,996,623,718,512,708,463,400,703,100,936,215,55,689,137,669,9,367,318,368,925,479,991,781,84,84,732,710,488,166,407,212,82,294,699,873,808,904,953,154,416,730,292,331,864,903,110,795,391,531,122,998,603,729,396,658,843,988,319,550,829,932,672,369,600,795,897,182,230,554,754,914,152,795,906,415,540,728,802,280,261,525,50,108,414,897,514,76,47,90,622,342,137,58,143,998,424,29,998,569,413,780,30,638,152,457,488,660,278,660,291,794,936,602,322,782,752,984,141,748,104,393,332,416,199,600,855,32,100,458,450,359,917,464,643,670,231,712,730,420,662,845,322,74,820,925,835,38,470,61,730,303,268,409,142,558,426,423,121,432,931,411,955,416,49,470,84,730,297,493,780,560,161,867,186,281,151,856,769,23,146,945,158,523,25,701,858,790,360,862,72,782,277,472,52,543,833,247,772,599,816,801,82,502,24,354,868,324,135,382,759,621,201,210,457,704,856,181,569,225,249,217,203,616,160,678,725,355,700,46,818,822,486,872,557,80,539,60,360,893,829,124,524,820,384,476,364,397,130,340,618,710,902,523,215,24,351,652,578,512,687,25,317,24,748,853,718,863,7,640,631,909,171,214,520,831,213,194,179,302,861,447,428,640,485,487,517,715,961,306,149,78,947,638,537,596,347,269,721,895,785,914,110,579,929,124,663,382,693,388,955,757,162,18,277,131,914,294,344,983,964,410,234,602,491,659,665,223,910,546,939,333,201,432,862,502,516,818,350,515,223,751,656,974,759,190,387,65,73,822,387,118,209,531,801,127,254,434,723,209,836,32,279,675,428,730,165,638,41,773,920,950,288,907,619,894,552,169,78,347,206,593,575,253,619,980,585,831,720,633,454,582,57,185,723,609,27,619,147,533,611,923,986,352,715,220,842,206,20,907,469,419,697,761,573,173,566,97,177,683,494,668,924,165,621,75,611,175,490,919,927,522,226,450,228,542,620,902,711,363,306,187,127,399,934,691,809,248,21,52,31,379,225,792,428,64,943,892,752,18,659,362,259,469,927,936,394,177,329,517,334,713,371,676,891,336,981,879,363,533,499,186,892,23,946,159,932,140", "225,913,498,860,140,145,886,199,579,787,486,448,713,616,72,120,219,343,990,764,766,814,754,750,311,313,564,781,192,22,662,831,637,254,303,929,813,161,845,716,640,114,574,72,945,820,631,771,369,805,989,855,311,602,917,410,43,151,248,28,254,668,848,494,771,895,507,267,219,51,229,83,964,151,717,417,16,956,201,756,251,830,597,851,839,8,291,893,718,699,372,787,977,349,958,443,176,289,363,92,895,587,735,589,847,37,200,925,617,541,427,90,354,266,114,563,908,138,137,332,87,735,917,894,667,55,214,729,126,810,491,14,195,513,192,652,14,768,600,872,491,179,543,546,548,203,564,441,637,227,221,391,559,687,496,584,167,74,282,812,405,410,710,615,683,948,934,945,471,599,398,282,66,536,764,901,349,971,113,441,377,336,194,866,468,641,37,819,162,470,169,215,144,857,53,509,125,549,723,646,783,159,572,927,708,267,124,605,925,924,262,389,784,141,830,162,762,559,893,414,586,546,998,63,572,391,270,75,55,637,721,958,71,129,225,200,805,554,763,472,798,220,607,166,697,664,842,563,522,387,694,441,177,49,678,992,602,502,27,548,836,671,852,457,246,164,937,662,704,738,431,958,207,876,752,728,123,874,852,769,178,647,255,13,215,501,711,274,627,630,654,656,881,305,191,903,56,249,277,538,326,970,553,447,429,583,66,973,777,530,580,648,920,436,427,989,922,127,740,409,114,830,876,612,135,530,600,914,147,452,337,100,575,124,76,733,331,891,573,909,155,910,179,735,305,986,523,179,456,303,855,552,948,789,784,886,799,277,791,462,766,610,277,922,948,374,514,254,284,398,575,595,936,777,422,754,134,890,303,955,576,207,193,786,225,195,725,484,750,255,869,518,863,294,256,597,157,894,470,597,764,390,106,375,865,542,522,606,662,397,371,820,523,585,278,550,744,373,424,319,906,634,632,5,748,432,872,797,358,792,727,675,898,307,566,335,556,56,449,796,194,0,700,356,364,379,739,778,17,380,471,417,455,320,840,738,87,563,171,75,97,251,288,300,287,43,973,998,22,345,871,950,251,950,679,446,219,574,165,421,180,478,853,806,693,63,528,313,399,699,317,295,362,928,827,116,383,655,622,468,100,675,681,950,762,915,42,647,139,665,232,264,643,747,209,290,712,112,621,286,423,702,210,182,110,433,405,991,618,663,267,697,739,318,521,93,474,875,286,873,655,287,357,556,550,765,254,483,614,950,382,209,479,832,989,792,395,346,617,826,846,468,816,942,692,714,209,791,194,768,99,592,948,472,906,164,640,170,69,133,464,642,666,635,580,477,202,285,858,274,950,856,986,616,743,577,468,730,673,895,908,424,442,642,199,907,53,520,797,49,11,854,889,778,293,772,43,777,694,647,975,226,137,273,157,615,159,695,84,971,679,330,72,4,14,519,969,871,568,294,175,952,905,907,730,695,95,222,25,943,200,571,186,34,952,166,488,512,293,85,471,74,673,423,619,490,443,216,190,284,96,13,709,248,68,404,894,330,664,782,349,5,31,374,12,853,882,276,643,361,581,499,926,765,226,321,459,229,895,363,700,380,120,390,27,85,717,579,705,582,249,851,178,905,312,624,503,289,992,831,659,97,306,104,763,353,813,223,616,929,341,326,251,868,131,629,477,581,308,801,528,303,55,841,407,79,838,860,941,787,906,102,595,417,978,162,834,28,995,891,672,195,670,280,580,154,99,886,544,404,626,772,801,125,412,254,139,465,214,805,642,562,348,301,289,692,867,38,814,402,535,150,169,670,903,839,33,212,199,328,845,16,925,115,743,362,738,972,784,360,308,95,541,747,311,751,407,134,545,123,504,622,249,866,700,547,779,514,989,191,440,184,627,265,166,299,696,449,243,398,410,570,209,298,21,180,535,526,642,791,126,2,773,226,736,966,373,377,797,668,192,223,782,633,26,735,442,987,662,166,547,908,554,310,633,779,944,547,509,124,499,751,771,861,594,4,756,813,468,672,494,369,919,25,455,338,723,331,909,875,397,243,628,81,758,461,157,989,193,924,90,852,773,133,387,60,474,795,410,991,413,669,805,701,382,70,901,789,12,31,894,110,436,804,556,470,652,37,78,556,631,422,603,614,366,754,303,756,542,376,507,479,64,244,756,374,141,723,328,358,493,225,730,302,355,878,984,584,427,180,972,931,160,936,893,690,826,338,425,438,856,894,825,853,725,252,100,53,777,758,363,703,530,156,731,957,336,962,633,785", "936,128,719,105,44,115,439,75,975,984,813,858,275,622,214,558,594,322,447,721,715,413,385,749,437,363,295,138,61,446,845,117,470,207,787,855,403,927,156,105,295,568,801,448,813,606,451,287,926,124,327,902,287,35,563,8,337,95,323,443,696,102,366,120,520,427,392,961,282,983,965,910,453,883,19,457,506,583,151,822,159,565,60,497,740,361,467,974,977,909,853,277,145,562,706,255,574,369,590,60,925,325,91,558,236,662,483,267,288,111,767,461,952,373,349,853,481,321,602,158,856,411,983,731,915,684,166,15,714,679,677,364,686,2,585,216,138,680,428,518,357,703,932,289,856,404,148,697,736,261,907,187,848,866,228,69,295,520,794,496,81,787,829,136,203,393,179,116,670,129,750,308,40,791,860,716,356,917,925,68,873,631,899,457,991,903,461,626,201,746,462,779,372,16,455,178,60,646,941,214,158,629,623,226,253,267,237,86,429,477,688,1000,451,261,575,837,693,232,145,445,91,919,533,853,193,63,917,783,44,276,939,861,816,823,190,905,886,568,990,783,143,498,281,842,473,76,529,408,185,442,915,99,752,490,237,796,45,181,248,319,18,835,20,413,90,275,152,713,323,421,457,263,701,423,670,999,772,209,923,508,846,338,269,76,771,204,25,786,281,982,359,992,920,487,470,992,582,684,679,958,38,751,857,105,90,475,903,57,97,17,621,8,658,373,993,694,661,804,323,936,448,777,946,529,544,411,358,349,421,172,943,299,340,608,587,311,712,579,113,376,165,125,533,234,936,72,751,259,553,718,783,220,242,792,295,894,179,116,685,70,489,225,633,438,498,951,661,591,447,591,992,319,83,311,53,776,979,655,8,491,126,390,411,263,320,324,776,965,42,836,257,320,557,752,591,770,442,908,68,866,570,313,207,576,385,485,295,314,116,6,830,366,334,744,901,559,47,377,740,646,928,639,944,992,333,985,742,856,962,990,574,478,609,212,91,436,98,626,24,340,43,700,0,350,674,663,869,983,224,714,513,730,571,99,957,879,21,778,12,848,517,109,962,774,3,214,349,873,995,202,254,735,743,363,915,31,701,133,343,771,166,641,248,130,331,790,922,681,100,124,494,389,151,959,95,150,192,121,412,175,177,166,493,97,364,358,758,934,60,129,849,853,674,315,225,796,66,72,711,137,951,920,30,261,17,461,279,522,645,705,508,63,856,993,99,838,36,480,161,308,734,707,954,292,420,792,523,908,85,933,630,886,928,850,770,230,695,2,817,227,60,383,959,808,837,296,56,269,783,657,794,384,457,316,636,772,222,109,378,1000,859,311,491,518,373,345,895,454,424,392,709,905,26,253,826,512,384,939,652,179,151,932,390,966,599,9,483,759,826,695,778,479,103,232,707,977,674,680,502,866,713,639,465,66,436,593,869,948,41,222,604,119,538,735,721,630,525,985,804,309,43,694,884,994,106,631,100,848,391,569,649,977,207,285,411,697,502,365,411,55,795,94,244,156,726,31,87,146,928,116,866,715,903,629,97,370,624,317,899,491,900,607,559,752,871,82,977,431,33,47,944,962,824,943,383,977,776,171,171,443,262,288,738,587,478,95,621,400,70,667,770,175,595,254,654,166,116,914,51,765,517,205,63,313,761,286,133,873,992,614,292,942,232,153,574,816,12,105,705,408,65,689,878,840,721,651,363,979,175,505,645,640,374,545,71,927,936,466,573,811,589,276,953,243,538,439,641,520,330,461,582,201,580,586,869,24,444,254,720,424,542,986,985,126,634,834,370,131,224,219,612,504,280,893,218,238,615,113,928,488,618,62,926,741,732,239,135,354,286,264,890,476,443,850,698,644,277,406,236,291,363,205,408,671,9,789,25,292,483,39,112,43,908,389,984,882,619,647,52,853,610,547,711,491,729,604,902,207,659,548,70,202,948,645,621,167,657,849,895,938,762,597,882,736,265,483,172,263,353,762,926,132,373,253,794,20,781,73,396,632,450,729,784,192,363,98,273,269,18,773,353,520,456,946,106,650,283,701,384,271,595,31,199,990,938,102,86,891,873,383,595,160,259,525,672,341,878,655,905,120,764,375,409,405,797,107,736,308,369,199,884,477,728,957,117,71,657,147,292,107,562,805,954,233,2,535,902,370,463,127,558,259,294,452,446,729,417,934,332,846,324,580,585,925,896,131,460,380,486,314,771,400,917,194,151,931,663,905,769,187,678,273,306,786,723,801,306,461,884,343,283,455,471,393,63,240,764,37,372,829", "743,904,921,1,526,292,496,817,13,501,567,429,946,750,260,335,736,257,206,410,160,443,447,86,172,313,911,883,655,251,734,945,124,278,78,54,780,222,885,129,527,874,713,84,902,823,231,429,530,379,372,481,460,306,903,228,685,616,77,921,418,690,357,248,369,363,697,177,831,437,989,312,703,121,964,43,811,138,313,218,676,794,328,786,256,253,370,432,741,295,8,726,470,150,976,76,515,606,14,406,150,121,446,376,352,629,395,591,324,52,37,615,902,456,33,502,998,795,913,516,893,133,999,718,102,687,479,880,995,27,271,837,532,528,279,661,311,597,208,255,89,611,876,203,912,51,860,502,987,591,78,24,117,947,500,876,696,685,941,710,71,374,817,196,202,6,945,351,910,86,357,943,181,713,786,507,809,545,697,805,443,746,787,517,391,522,503,633,470,926,835,909,50,111,532,490,838,648,962,128,160,665,691,304,563,516,394,186,971,989,109,519,730,349,848,376,860,652,553,928,290,405,102,35,868,917,878,98,295,884,774,341,374,23,461,83,731,287,222,481,595,69,13,895,914,916,622,322,270,387,738,170,325,166,16,638,815,829,404,393,833,71,303,554,704,836,359,253,434,413,80,747,334,494,314,835,371,671,377,79,737,969,486,37,792,840,841,882,95,205,798,896,473,388,855,140,36,328,373,41,303,959,56,573,969,695,204,34,346,977,693,141,75,649,39,862,150,128,622,879,782,571,405,822,845,707,161,217,595,696,719,106,408,416,888,336,558,770,785,119,590,387,866,72,346,789,966,665,194,429,935,789,239,646,239,889,796,391,282,181,292,304,237,239,886,452,283,621,12,927,204,85,637,935,619,190,578,891,400,119,609,340,909,21,36,165,140,123,723,737,422,445,865,129,104,405,985,9,62,981,926,14,950,785,133,201,538,614,531,984,951,762,715,265,822,102,281,121,418,191,118,646,782,798,411,815,786,357,486,68,67,89,101,908,289,772,607,976,220,220,801,356,350,0,483,874,287,758,117,482,460,195,731,317,209,322,150,986,410,319,629,622,589,998,964,148,392,170,325,577,997,727,359,201,205,854,382,640,473,937,838,987,980,294,702,926,520,264,368,77,941,166,569,607,559,257,620,284,503,629,732,570,557,458,50,780,95,901,98,845,974,77,567,829,742,791,228,149,584,361,268,201,541,841,123,479,51,435,720,307,54,79,122,553,831,250,56,878,222,13,814,252,695,9,791,946,511,758,31,648,534,919,713,421,304,869,436,13,666,401,335,337,604,232,669,756,580,368,154,890,789,309,591,622,361,542,301,869,491,746,260,825,532,584,166,321,360,379,751,100,169,938,15,673,735,828,2,547,682,293,343,593,384,829,841,575,364,78,731,225,370,976,137,251,898,440,278,928,665,297,818,663,323,799,206,154,549,776,212,921,176,525,819,767,298,842,533,167,436,180,483,143,923,103,449,419,238,748,514,865,360,222,306,879,313,873,444,909,309,489,50,51,636,836,372,822,805,541,862,197,287,359,771,558,366,815,602,9,345,847,321,195,680,818,805,81,364,550,776,317,843,503,634,190,512,731,307,673,42,644,612,89,663,569,934,49,707,555,652,739,848,268,585,506,618,419,377,801,693,254,654,292,575,147,157,559,288,439,215,452,478,137,561,309,626,275,347,484,635,276,203,40,962,474,704,219,61,928,504,204,96,959,188,508,731,285,671,671,809,991,607,827,566,980,41,207,843,283,700,487,971,570,483,822,618,709,436,77,543,962,867,931,148,112,427,1,125,284,526,509,452,83,220,657,561,302,109,519,304,837,967,829,333,252,487,906,921,482,305,781,449,697,606,539,727,513,742,135,349,177,923,330,416,40,499,354,505,798,978,35,6,48,906,328,113,743,313,239,260,508,620,845,120,399,360,470,497,720,244,703,763,569,814,922,940,206,386,37,614,906,389,11,177,266,272,838,244,891,205,123,888,540,841,965,322,528,519,346,338,761,855,433,143,238,662,860,256,34,660,862,926,668,23,30,47,844,175,127,368,744,93,397,670,740,502,290,227,981,57,661,48,1000,460,198,594,3,543,447,41,454,216,690,967,277,911,284,813,801,10,55,996,251,502,113,281,682,915,104,18,776,423,461,890,146,689,127,994,103,717,955,228,540,12,104,887,528,313,711,453,986,845,915,765,565,400,300,600,121,415,977,734,925,968,540,400,311,609,171,692,453,659,242,808,763,588,287,317,310,792,450,290,441,53,7,630,96,975,704,773,719", "782,57,571,616,636,971,496,60,488,554,603,305,214,982,770,835,275,564,878,100,759,263,31,969,266,846,852,355,382,860,752,789,127,134,93,440,280,973,490,321,504,485,285,957,34,932,969,45,618,487,613,497,714,451,859,462,884,330,11,286,921,46,416,678,580,825,558,205,197,702,718,823,685,884,641,902,342,781,546,378,583,281,67,46,241,234,539,692,142,727,416,367,31,274,666,980,655,707,836,241,840,501,408,340,150,782,779,588,118,997,111,809,392,592,545,96,165,315,365,608,850,653,686,738,425,47,61,650,54,952,725,118,407,609,816,365,536,955,408,326,744,108,552,558,650,676,69,414,203,827,979,843,865,376,664,625,841,925,331,320,262,349,586,631,74,627,437,365,79,738,274,300,249,842,564,540,475,901,922,301,762,906,852,70,206,768,412,446,238,687,53,58,781,752,141,737,593,979,83,300,157,596,50,302,733,550,423,288,533,628,817,254,209,555,736,88,649,759,300,706,24,580,969,679,610,225,834,640,43,541,408,480,343,426,809,386,580,508,869,586,893,941,447,857,473,115,672,273,447,102,648,147,946,725,340,51,959,624,827,862,659,240,299,268,667,624,226,669,882,972,301,799,563,435,317,14,541,230,279,458,898,299,380,180,365,300,702,672,321,33,236,344,108,67,683,101,429,379,467,902,721,198,854,195,31,676,809,312,23,875,927,471,587,179,478,333,909,772,160,675,16,706,95,848,754,962,723,994,671,646,356,562,172,23,485,794,40,563,760,799,615,844,900,670,640,363,594,689,332,903,404,768,641,373,43,766,744,376,736,791,157,597,874,975,866,194,723,411,791,297,956,397,595,51,799,222,497,883,788,832,335,332,992,313,698,592,8,193,370,787,495,166,197,30,282,737,948,509,740,255,652,707,130,508,878,950,285,49,474,881,729,952,181,593,818,21,745,539,247,164,763,849,578,180,672,39,943,745,156,816,177,79,425,688,791,538,926,219,31,293,13,364,674,483,0,464,874,936,195,396,824,423,949,938,628,842,483,804,430,761,88,539,67,875,15,820,426,248,112,508,615,518,180,920,232,985,272,656,946,530,208,388,860,840,731,436,862,976,213,681,212,353,783,8,942,431,120,837,950,424,939,552,351,454,257,737,835,304,625,930,599,816,120,196,853,71,915,774,425,415,47,68,485,397,356,370,540,947,929,357,524,991,126,923,20,600,284,137,781,624,160,836,500,890,2,323,921,185,7,599,843,610,571,57,668,11,907,247,340,906,528,429,524,300,650,829,268,71,623,487,683,142,337,87,388,635,606,797,535,226,839,3,250,398,332,438,823,344,652,623,497,316,682,840,642,783,757,89,683,881,338,242,160,384,416,108,205,595,749,10,603,981,575,965,958,247,740,757,519,359,254,729,962,250,631,466,70,340,450,763,750,772,465,464,836,214,516,811,608,67,395,360,71,716,408,999,846,999,544,610,352,177,994,276,748,78,89,946,431,509,419,53,622,50,950,927,675,759,422,258,766,901,479,409,765,877,851,558,200,534,692,363,684,280,948,972,601,342,548,965,569,916,81,767,292,394,162,237,861,617,462,591,622,67,552,539,726,103,3,931,781,342,96,351,351,348,779,177,526,582,897,991,310,737,514,809,826,16,889,714,154,294,920,672,561,326,768,308,237,714,115,323,198,498,430,830,803,697,631,508,166,125,23,603,752,217,842,882,329,388,410,161,481,999,155,501,604,635,962,143,117,859,546,308,688,74,47,6,222,240,409,421,521,72,485,306,316,407,6,242,849,636,301,293,881,862,590,758,971,253,184,247,925,974,930,910,548,770,579,283,197,544,329,271,211,468,574,45,654,317,640,47,155,786,625,661,538,659,260,267,160,963,270,673,154,767,712,867,32,93,557,314,665,611,891,689,276,18,788,144,855,218,876,456,534,7,522,800,586,659,772,834,550,732,277,984,406,295,404,270,749,174,918,362,520,573,58,343,466,805,587,996,896,146,477,894,53,598,309,986,590,907,63,639,987,462,416,344,889,392,834,114,616,373,911,905,198,792,952,575,676,985,486,658,406,648,444,988,188,704,926,798,681,452,687,622,654,34,925,647,334,278,519,940,67,844,384,302,680,973,820,860,521,272,497,847,107,619,800,798,786,245,160,635,730,390,14,848,688,676,940,284,622,831,984,196,295,683,38,836,996,586,759,699,770,47,137,56,780,9,965,647,986,851,262,554,678,840,671,411,775,2,292,197,350,207,941,933,784,796", "307,300,881,56,479,911,11,55,468,308,219,249,615,754,616,795,889,20,601,184,557,107,376,54,117,943,934,373,885,519,537,194,534,83,119,136,315,851,915,88,180,460,332,401,357,6,164,489,268,369,710,562,335,366,688,880,920,696,827,664,310,363,504,504,770,791,913,599,640,957,468,581,860,670,716,258,307,94,361,224,413,350,889,200,360,279,839,287,990,31,831,56,337,907,12,468,99,294,551,551,165,431,2,276,368,16,49,165,40,377,18,756,516,983,585,556,411,324,642,186,993,412,264,571,756,917,995,106,328,368,937,634,994,954,204,861,820,806,109,313,59,321,201,992,888,657,418,45,42,290,52,359,963,756,262,748,792,162,280,196,885,176,668,605,578,247,915,43,654,694,484,831,671,805,796,98,932,930,963,379,824,855,170,630,346,914,274,181,686,781,518,706,964,195,419,52,934,33,740,207,613,937,260,974,518,98,692,357,175,459,909,433,700,67,391,631,114,343,292,501,922,677,476,589,235,936,734,491,372,208,174,965,995,109,624,383,607,363,56,309,686,613,309,892,406,863,461,582,967,492,539,308,135,535,652,919,297,288,900,882,344,988,495,811,656,169,324,141,652,2,989,363,909,761,291,125,343,236,277,325,420,440,142,26,856,33,656,347,616,368,455,509,702,673,955,996,924,152,977,286,22,647,504,103,998,655,6,305,414,675,320,971,151,510,900,284,538,929,931,788,784,322,653,83,230,879,537,85,137,793,431,291,175,312,244,83,808,131,959,100,876,73,476,448,52,182,893,43,111,668,875,370,382,265,970,702,595,148,629,870,475,114,192,268,749,239,846,102,721,234,864,988,355,221,298,234,852,370,179,246,226,900,930,352,500,534,654,420,835,803,421,756,927,181,109,383,533,390,643,816,866,946,668,302,649,802,124,488,389,116,741,445,436,672,266,551,331,542,872,706,61,969,528,493,570,568,160,984,807,382,655,115,972,910,994,544,415,649,701,322,718,379,663,874,464,0,644,851,595,711,827,319,936,265,974,986,23,529,566,549,777,870,833,552,691,169,900,342,189,387,33,116,410,180,679,726,862,893,643,284,904,82,140,395,332,734,784,222,772,848,777,878,100,222,805,593,84,664,31,500,942,531,714,761,899,461,811,146,776,470,551,21,600,128,201,840,532,132,9,226,460,233,287,925,762,58,749,459,336,484,561,651,357,912,887,300,911,168,420,352,467,907,520,636,494,385,745,613,561,897,651,558,13,681,224,595,675,498,780,577,909,333,337,128,308,854,594,285,23,55,824,389,604,391,4,146,644,300,647,778,290,909,832,255,424,987,618,771,372,794,869,882,995,35,989,707,877,767,243,155,524,807,342,534,710,706,716,188,393,856,639,680,495,980,592,392,393,290,230,925,591,970,237,896,745,641,665,285,138,885,802,532,945,336,751,854,278,506,227,961,495,2,884,691,997,337,229,518,896,17,261,235,44,220,888,458,257,15,962,109,93,247,530,634,625,162,764,814,390,941,241,114,12,67,564,349,620,945,230,889,529,767,261,354,414,310,807,866,585,665,299,940,117,587,275,296,119,568,950,169,179,368,759,874,242,922,112,938,286,551,750,270,10,269,580,668,393,595,553,254,173,890,503,961,319,741,177,287,169,404,920,485,762,681,379,473,781,161,927,409,958,85,15,538,200,465,430,650,167,391,26,301,781,64,401,869,627,958,252,776,802,763,804,438,693,825,336,105,377,747,535,786,471,383,278,306,752,494,54,353,844,777,185,699,171,577,472,561,54,804,491,11,440,289,146,390,316,814,409,964,399,482,21,242,895,753,733,191,273,794,71,849,518,569,230,662,769,20,373,354,374,534,136,201,619,513,628,975,45,923,485,300,980,23,984,608,963,952,436,138,933,515,446,252,833,919,501,27,800,633,282,856,989,1000,447,371,938,574,642,637,809,913,744,129,228,351,213,232,586,464,33,522,96,568,637,191,244,762,419,246,474,768,165,721,439,50,502,912,145,436,671,530,289,105,106,881,994,173,415,685,242,682,864,184,487,853,258,972,554,135,771,648,12,38,469,785,960,362,370,350,728,998,101,58,549,527,364,903,993,163,304,185,724,457,265,588,603,494,684,871,171,801,791,191,683,785,585,267,998,212,791,745,888,791,483,710,912,750,290,667,49,648,228,924,773,500,278,239,791,214,743,556,996,662,602,541,883,200,498,879,167,279,971,55,725,268,136,600,141,98,714,412,547,758,627,618,505,381,777,601", "217,25,136,840,5,75,736,644,882,765,116,866,806,830,285,476,782,282,181,760,90,810,337,190,569,782,587,63,355,992,269,17,111,776,559,573,45,618,233,411,579,646,652,497,341,935,150,758,900,879,184,331,173,617,541,350,645,377,62,68,395,258,122,476,163,655,442,546,318,156,971,768,553,750,337,677,719,985,430,253,450,631,67,893,23,15,899,879,423,31,120,323,938,365,390,185,245,924,863,4,836,117,711,627,558,43,760,68,692,887,725,786,99,37,133,911,813,735,612,884,924,931,249,146,480,450,865,396,815,336,279,860,699,983,124,881,346,42,27,585,171,621,120,417,318,64,123,892,175,699,739,593,899,522,536,896,824,783,189,478,443,113,271,728,130,218,382,652,323,775,376,162,941,311,315,110,800,103,757,954,768,228,479,651,917,402,126,709,748,230,900,908,438,520,840,261,5,112,42,437,294,64,504,303,662,384,564,292,401,387,879,50,146,594,878,898,92,94,270,212,576,424,758,505,991,248,550,598,633,13,32,541,379,242,386,989,308,630,942,150,930,471,546,521,606,696,470,111,488,141,484,270,724,806,347,614,248,541,297,684,789,403,933,439,209,337,767,420,525,386,474,988,47,198,953,123,672,223,541,866,677,19,16,911,302,904,852,89,445,860,946,719,665,700,1,660,715,867,998,344,707,224,694,791,746,963,799,192,687,716,534,864,286,620,472,790,648,102,770,224,232,949,260,781,984,532,378,672,934,949,748,504,21,530,526,318,264,274,130,10,187,206,566,223,129,17,308,67,242,839,578,481,404,32,765,410,205,664,612,518,539,413,889,26,214,307,327,236,756,631,675,188,569,790,952,533,170,33,254,234,50,214,24,38,614,277,828,252,635,667,537,966,18,970,612,982,891,708,3,829,808,187,896,359,694,862,126,39,51,66,32,600,349,404,148,526,630,256,952,585,25,548,965,941,791,166,739,879,493,535,20,623,5,948,455,376,216,513,784,881,210,739,869,287,874,644,0,243,887,707,355,670,883,133,106,303,488,887,246,440,460,976,831,439,118,5,623,562,499,427,683,869,77,583,919,219,653,75,801,108,423,457,166,239,755,95,575,153,356,817,770,25,869,58,628,299,124,824,823,277,410,392,296,136,944,136,5,501,248,895,549,57,724,957,920,88,74,363,428,990,65,832,291,372,902,447,646,240,852,468,879,737,20,346,45,955,484,457,994,357,860,704,134,11,354,714,103,414,915,661,409,85,706,752,286,40,928,46,545,417,454,115,619,872,218,61,592,148,929,915,382,762,793,914,52,977,278,365,291,677,457,6,491,488,826,662,586,305,703,259,842,211,815,586,179,541,555,797,680,913,997,283,154,996,134,194,44,574,50,110,862,989,575,888,181,851,948,21,897,446,986,52,853,810,937,189,183,127,749,348,107,979,104,666,616,274,588,554,11,8,480,59,812,919,36,870,143,186,335,246,517,357,455,169,657,636,480,284,815,455,523,945,939,961,757,816,391,906,358,615,792,103,960,894,626,132,582,87,515,628,590,295,664,940,559,486,784,845,750,833,621,460,272,287,982,162,831,988,468,393,921,183,267,742,350,177,787,485,332,437,599,43,271,989,358,613,744,880,730,670,67,502,697,314,61,925,108,805,949,964,960,985,325,49,388,604,548,153,84,901,775,731,454,67,807,824,85,623,156,727,990,888,391,428,103,385,914,225,857,753,915,624,935,211,745,136,251,697,702,906,713,546,444,293,859,93,245,826,835,382,518,509,939,924,184,799,957,57,757,470,140,582,500,309,595,818,64,113,287,383,818,339,526,381,484,375,189,863,139,797,484,276,218,80,484,625,116,53,352,537,684,191,546,170,555,192,903,596,550,419,664,372,314,638,59,574,976,149,705,97,234,117,790,52,986,548,347,575,471,834,586,709,332,695,953,867,583,846,360,88,627,150,850,729,992,150,98,75,598,248,580,164,706,560,614,630,194,782,449,353,596,226,900,34,224,435,576,500,245,884,130,582,822,570,415,976,962,243,538,372,713,218,566,533,265,953,969,386,64,878,207,610,45,680,345,57,93,683,826,948,849,900,469,78,890,380,857,423,34,337,689,274,55,732,582,614,881,451,496,224,724,240,544,404,828,80,50,158,868,342,312,201,319,805,621,294,162,510,250,369,828,866,871,907,284,406,299,456,988,881,393,396,324,60,783,8,520,28,143,286,923,451,75,154,956,375,799,383,729,157,709,193,935,16,529,701,757,938,113,487", "300,764,929,279,507,372,304,75,55,21,700,917,995,347,53,438,111,239,67,948,236,726,941,765,848,4,181,426,856,431,534,71,140,666,730,551,946,170,310,666,823,646,723,954,915,715,917,882,283,180,734,422,57,742,431,167,439,225,749,429,674,600,282,956,516,454,254,228,278,895,911,770,986,744,274,931,216,312,533,160,684,581,676,314,338,883,956,343,394,272,564,678,747,612,838,779,167,421,722,401,206,927,860,687,74,54,728,933,72,30,75,738,25,585,53,352,375,804,9,735,3,814,105,182,981,141,166,179,6,764,709,321,576,880,761,975,651,225,67,668,158,288,187,876,838,942,782,207,707,784,193,862,238,411,412,387,167,431,572,397,998,918,103,962,533,124,691,149,880,770,101,720,972,671,259,36,465,239,320,468,429,987,554,281,3,843,751,315,341,202,447,984,469,770,813,689,819,280,910,870,752,359,512,84,385,197,335,24,641,36,122,969,287,905,854,926,39,85,401,410,653,560,611,126,761,617,792,199,894,145,149,207,29,713,102,689,517,534,585,227,657,581,487,596,107,262,58,707,52,588,514,975,678,421,823,55,255,751,540,607,924,97,647,472,60,464,556,661,765,895,689,188,202,901,111,59,309,508,93,930,880,896,113,70,747,743,610,776,551,305,323,480,312,865,897,71,693,421,798,928,184,939,556,251,150,964,948,246,697,228,165,515,317,116,207,764,845,692,317,987,468,46,220,147,101,242,257,33,686,304,489,946,872,185,624,220,566,19,746,286,721,516,432,59,886,859,128,680,463,192,301,687,542,479,279,505,206,134,345,621,947,345,204,765,230,831,857,253,501,117,353,653,43,928,521,176,309,750,572,529,828,514,28,23,972,890,67,128,123,140,491,737,921,318,591,538,592,716,894,559,115,894,65,855,397,642,918,284,350,202,617,152,916,653,297,757,941,309,43,613,129,960,155,240,656,403,508,482,195,760,218,283,891,823,220,714,665,247,748,986,541,778,983,758,936,851,243,0,273,132,575,545,444,13,957,917,128,842,218,73,640,966,639,127,251,95,334,987,822,368,828,305,165,63,421,614,169,235,41,419,828,802,937,116,789,56,23,963,672,671,798,683,583,312,994,546,585,980,352,313,272,242,460,442,258,884,545,824,66,526,434,805,995,267,946,179,674,450,915,111,682,763,458,319,864,397,562,132,414,261,795,441,809,433,647,114,221,864,68,830,340,250,373,993,984,959,711,509,616,625,749,702,125,917,247,868,896,432,341,691,159,463,126,957,610,516,798,306,571,90,577,266,627,550,991,65,696,215,338,550,145,933,832,974,270,468,618,415,921,789,923,372,42,787,777,725,340,835,889,143,409,269,935,878,485,983,806,685,701,291,127,629,386,784,89,452,733,910,215,160,399,415,503,327,198,198,983,407,335,511,493,295,286,527,415,532,128,402,857,319,684,688,815,480,445,33,954,430,554,885,121,869,530,624,2,55,950,347,84,239,219,197,448,186,160,326,168,24,313,275,36,422,429,696,229,967,788,278,215,74,8,56,425,669,990,341,444,513,902,122,366,582,402,955,410,400,989,241,125,226,977,605,934,325,761,989,741,379,651,638,945,570,256,334,708,751,957,474,911,814,803,722,602,750,571,120,723,49,425,218,332,671,299,2,577,297,213,206,721,437,75,241,55,728,9,456,51,259,679,522,328,934,411,789,986,921,413,210,332,791,309,626,474,194,988,522,529,130,871,633,265,637,616,26,232,587,47,376,12,471,952,179,770,172,636,234,110,284,341,440,250,772,974,945,111,335,562,224,183,63,419,612,571,54,62,536,793,672,529,516,194,992,579,476,571,751,536,817,960,874,957,511,110,692,566,99,470,576,282,440,874,775,56,704,219,192,111,364,169,171,602,505,945,173,883,369,670,53,524,616,846,795,650,542,326,739,734,129,660,639,247,823,723,979,593,456,384,815,638,938,609,288,45,308,938,467,884,330,364,884,89,490,917,429,504,733,844,190,642,567,129,379,181,136,882,651,131,917,305,162,827,185,280,790,836,201,494,249,449,533,947,99,181,176,161,89,731,665,942,27,651,7,959,840,801,122,142,617,32,228,718,938,340,618,686,34,781,831,627,814,294,341,486,985,171,35,27,647,739,846,238,5,557,973,819,422,890,445,367,572,744,25,262,333,655,456,311,161,957,886,911,7,996,302,347,922,302,804,535,204,37,28,661,226,437,131,874,739,989,487,656,878,258,393,360,603,14,188,290,497", "921,822,603,360,903,893,833,828,957,90,81,643,342,307,328,863,513,124,392,417,31,401,164,333,29,9,150,759,482,249,749,346,94,238,577,512,498,822,207,622,552,736,774,711,969,705,757,410,575,385,656,773,969,763,160,230,144,254,428,398,978,159,580,910,58,874,109,461,248,40,401,537,828,406,440,718,404,269,791,923,446,715,376,104,420,486,77,33,162,424,412,658,232,555,570,893,257,679,695,199,404,426,923,573,592,589,705,431,678,279,975,466,527,968,257,189,67,175,931,822,993,447,87,866,522,430,624,185,714,768,55,250,978,610,916,663,666,979,745,212,100,234,311,684,383,358,515,156,949,185,398,377,644,92,970,206,285,415,508,643,480,35,746,160,113,171,663,287,993,436,431,142,850,953,897,373,886,995,138,704,62,312,546,868,724,431,187,581,702,721,867,665,428,52,183,953,542,273,394,483,722,252,205,232,636,906,56,882,736,158,485,132,717,268,354,216,258,15,965,314,776,613,684,521,846,893,125,585,50,895,962,350,23,995,4,87,879,230,447,670,562,576,344,485,771,234,387,999,191,884,735,982,859,651,659,819,134,893,705,97,909,40,168,436,916,186,878,27,188,997,529,526,113,502,778,230,588,209,296,287,169,836,940,499,911,67,741,893,962,686,546,124,211,973,220,993,607,422,36,254,809,506,907,670,5,631,14,772,27,518,215,13,488,925,135,989,532,83,895,416,558,234,989,257,632,874,23,573,308,593,377,66,153,207,399,562,455,89,22,133,932,866,301,665,645,795,246,914,890,848,943,633,126,433,535,457,549,569,687,479,59,198,721,103,649,432,183,514,837,799,900,26,291,481,398,603,726,839,220,83,166,287,913,638,115,443,650,254,144,763,955,991,459,468,671,694,665,861,718,550,781,879,612,682,600,428,199,640,352,920,213,551,220,183,509,433,583,795,676,25,466,36,964,897,113,222,535,556,832,929,685,178,250,735,27,443,68,109,197,460,234,17,224,117,195,595,887,273,0,640,113,257,734,359,849,616,392,167,369,181,754,28,812,886,493,24,693,302,884,690,225,480,750,30,180,657,392,484,368,809,599,561,207,857,634,367,371,796,82,688,980,720,150,584,308,854,723,249,703,370,116,758,948,28,448,635,880,494,901,324,465,283,176,735,887,236,245,314,913,807,771,922,533,257,674,692,631,759,395,599,447,588,365,572,744,746,983,698,515,124,396,260,163,34,142,855,995,406,786,688,983,109,986,968,986,7,812,501,503,129,948,383,620,968,325,723,398,818,454,395,824,859,368,107,439,522,741,585,931,983,186,785,586,190,857,955,562,256,969,593,439,467,813,111,979,279,771,712,62,952,356,690,757,295,840,821,459,694,174,8,361,479,68,583,789,652,345,93,561,471,433,95,93,475,694,172,629,625,40,430,369,330,66,459,189,887,230,187,489,134,808,175,905,467,265,965,742,242,874,42,428,146,636,929,141,370,515,8,122,85,777,489,762,122,894,186,588,371,207,120,3,234,473,629,443,472,532,171,648,294,786,803,293,679,573,115,511,880,711,98,976,739,499,434,486,472,550,268,961,538,575,864,740,128,791,877,46,599,376,787,357,962,911,60,354,916,932,84,665,675,621,631,989,735,672,122,662,951,300,408,532,655,948,286,855,864,977,872,61,664,32,663,816,521,474,407,760,930,197,679,137,711,813,71,9,488,617,997,789,935,935,533,796,802,508,953,788,127,148,518,126,939,28,225,803,898,252,63,3,242,665,252,886,417,474,992,577,721,203,943,68,123,293,771,255,909,329,864,355,841,431,695,913,693,23,508,120,464,795,568,977,30,472,271,495,74,134,608,701,19,678,306,803,315,863,196,686,48,233,468,499,816,930,290,845,737,438,478,439,188,436,901,515,683,574,473,142,456,766,903,454,322,28,609,827,870,814,270,906,700,491,948,151,577,900,729,953,794,654,516,712,646,806,811,200,380,558,744,170,814,386,104,96,972,718,20,372,716,404,849,647,970,134,778,656,66,894,4,89,291,246,410,69,422,868,203,512,159,227,396,327,503,255,575,453,378,816,808,157,688,438,484,120,216,138,501,531,802,886,517,746,424,507,28,183,175,175,289,251,717,753,250,868,581,806,146,104,284,820,822,594,507,33,607,572,640,63,811,100,623,214,424,617,787,446,636,701,34,503,722,687,829,494,348,812,552,867,97,15,504,399,977,421,78,171,498,468,384,134,804,785,845,666,199,639,671,75,236,199,605", "699,924,541,881,582,645,818,940,676,896,797,376,454,907,586,968,612,132,420,32,662,701,970,29,912,250,108,41,935,153,690,433,763,476,305,121,696,343,709,516,797,920,525,560,325,142,801,610,250,757,368,240,753,653,559,370,684,640,828,218,776,38,714,924,44,790,973,448,68,6,454,413,355,511,584,170,667,365,337,836,247,467,308,205,650,460,974,1,634,28,829,282,164,666,692,643,982,339,710,760,31,777,38,903,132,707,572,233,623,982,20,314,29,710,396,526,338,660,509,273,860,991,361,160,275,365,11,829,851,66,377,454,104,66,457,803,131,91,443,307,387,409,13,830,203,442,86,778,935,101,87,988,769,163,185,150,28,828,873,909,700,480,757,165,147,979,989,286,17,886,498,937,73,418,151,150,658,955,741,128,621,515,689,237,22,85,248,666,278,144,930,607,5,83,658,31,405,568,280,260,46,646,644,734,503,268,491,104,247,574,128,834,493,478,57,738,48,55,372,429,853,10,542,222,86,361,158,301,167,434,341,559,352,603,743,881,545,525,768,760,758,616,27,476,771,948,222,898,904,61,582,967,579,104,997,510,969,40,465,736,524,590,752,467,450,535,106,520,380,786,399,949,657,739,36,1,122,861,154,295,305,650,51,591,306,367,179,184,959,133,652,136,368,381,501,465,270,174,342,615,233,224,596,553,884,92,322,550,872,990,988,482,727,720,796,610,798,19,67,304,829,773,565,734,114,347,836,964,6,246,609,293,654,775,501,869,355,8,466,551,64,103,530,923,222,978,128,124,574,1000,940,469,222,45,942,987,695,297,387,348,184,537,265,752,146,889,358,563,527,778,845,931,268,504,924,753,487,985,668,909,105,898,720,562,659,601,42,87,983,818,239,102,321,560,593,220,714,312,728,82,23,153,569,917,803,772,432,921,951,971,461,365,751,426,485,436,88,826,165,984,931,639,508,153,453,377,522,91,874,285,882,397,357,581,96,281,275,744,659,682,577,380,714,482,396,711,707,132,640,0,644,651,491,933,168,845,866,419,93,555,108,127,957,795,804,576,632,933,72,205,952,678,383,621,825,249,426,159,911,558,133,783,346,664,169,143,466,436,930,2,508,64,369,520,176,421,148,537,679,68,787,292,784,38,845,367,811,802,480,728,219,999,376,978,115,881,529,91,567,218,583,794,341,12,392,569,854,168,976,425,274,39,296,852,570,936,889,554,17,464,675,955,30,764,405,278,219,517,168,492,394,453,817,220,943,480,873,943,997,156,179,769,563,233,424,402,734,547,512,36,24,547,787,22,887,199,120,727,160,670,965,324,235,302,895,899,55,947,840,214,139,970,177,627,576,902,342,969,611,141,789,88,808,389,780,224,621,529,409,400,292,441,525,60,707,345,741,116,438,785,113,290,984,793,341,988,712,449,629,147,491,932,165,793,209,799,107,616,649,434,959,555,634,699,354,881,847,288,309,886,507,270,273,168,987,874,190,97,210,407,464,266,485,510,12,661,548,523,6,434,570,171,88,377,773,800,38,471,649,782,847,939,952,444,604,824,125,473,667,398,118,62,67,924,614,633,15,375,866,547,48,765,377,499,451,246,956,130,966,494,759,884,200,69,23,172,175,816,266,781,35,396,674,163,624,372,978,876,524,989,321,36,378,94,1,90,387,111,283,974,600,918,954,331,981,507,738,438,11,528,140,521,690,106,374,457,226,27,850,598,939,453,676,563,751,458,176,885,496,927,747,382,884,928,896,750,650,454,725,534,820,617,215,944,957,428,158,370,346,148,496,428,977,498,144,196,341,773,863,406,751,151,667,468,717,434,783,250,712,430,242,648,439,798,932,518,636,984,513,576,248,902,725,821,510,158,931,545,616,565,439,498,601,690,601,973,61,936,751,896,803,395,694,17,753,271,724,108,314,629,614,760,388,672,572,780,319,726,28,816,569,479,754,142,653,765,786,488,121,746,385,132,162,993,435,81,610,390,841,4,86,380,973,500,822,590,106,909,696,730,67,277,232,436,562,909,108,829,717,285,724,234,36,919,606,875,822,222,676,891,42,340,949,940,868,752,730,697,712,14,795,812,368,734,495,619,482,846,764,47,93,348,571,792,205,234,221,761,734,810,145,711,889,321,343,656,654,63,245,241,300,22,135,868,641,469,649,281,467,833,343,15,986,226,63,301,774,278,745,957,895,583,745,700,827,698,228,425,824,230,675,510,926,483,516,207,510,49,624,469,108,473,220,389,633,437,625,878,452,474", "664,415,608,322,708,46,393,472,962,523,552,830,80,272,148,418,587,854,237,105,587,386,893,140,235,699,327,484,310,479,798,920,234,108,271,319,882,784,536,927,640,528,275,608,606,41,354,677,256,762,38,606,370,669,92,11,776,527,547,907,777,219,893,742,194,791,7,611,529,898,813,596,786,242,437,94,436,22,97,374,900,691,82,953,671,172,451,212,205,281,734,777,198,936,301,434,530,890,383,341,743,494,803,199,945,468,165,655,365,454,630,443,3,484,644,179,322,231,536,559,743,87,914,748,73,402,334,126,382,413,416,766,222,251,829,574,455,754,57,77,699,711,790,460,465,53,650,145,827,621,919,348,777,903,944,756,700,688,78,472,686,816,354,856,938,185,894,927,670,37,215,603,496,780,510,674,919,66,54,759,308,562,495,628,475,694,365,747,745,280,758,976,42,425,838,666,940,481,606,958,134,610,155,226,704,249,510,979,348,450,509,633,432,864,465,64,415,922,866,356,534,173,958,264,373,784,253,152,565,478,340,335,740,456,175,701,821,902,351,891,964,897,440,991,822,646,548,983,161,975,633,641,813,193,684,900,117,430,170,278,187,640,346,686,793,612,365,435,326,433,989,186,355,137,815,223,596,671,948,294,621,784,843,516,344,989,193,126,268,355,486,317,39,677,121,223,970,372,796,442,76,810,548,128,803,385,939,231,89,744,697,914,950,418,639,298,677,436,881,356,696,702,927,77,718,303,56,179,112,197,915,790,175,550,359,672,99,107,958,454,178,78,443,836,415,803,763,686,541,964,841,955,160,903,354,256,976,993,204,131,359,94,499,280,372,940,912,824,847,267,532,634,906,171,448,958,356,155,406,496,670,42,28,565,545,748,936,329,659,698,606,151,285,65,497,84,309,495,657,912,322,459,183,8,428,648,808,366,400,786,585,239,784,89,272,142,814,372,7,314,323,117,14,469,623,65,720,507,285,509,756,63,593,616,129,103,478,465,637,693,762,471,513,460,824,827,355,575,113,644,0,425,713,905,330,179,301,756,670,437,365,795,517,16,261,666,483,922,19,904,611,37,974,694,30,509,206,429,572,158,645,155,744,123,343,257,890,666,894,227,417,619,429,71,460,50,138,310,280,719,457,508,951,678,426,92,678,525,119,42,426,227,80,942,800,827,492,193,834,425,677,594,630,166,679,36,29,68,452,391,43,993,634,392,181,302,522,621,954,231,527,246,162,874,292,507,51,277,228,773,384,463,595,274,118,929,972,689,285,910,408,583,474,823,731,370,352,19,1000,652,891,748,670,457,946,44,486,797,501,420,536,359,93,88,248,161,16,798,191,744,521,171,470,808,113,270,957,344,127,729,104,968,8,289,248,289,265,224,825,569,429,851,715,305,869,306,50,466,461,112,733,205,758,128,484,540,267,971,943,71,929,323,659,345,63,923,264,514,556,757,632,649,23,310,420,467,532,419,240,90,138,988,613,207,514,467,84,682,716,438,306,928,324,80,486,433,160,865,779,752,212,862,179,299,413,159,374,132,853,711,635,985,150,771,549,192,652,636,572,623,950,109,419,40,813,554,839,337,280,900,222,483,30,962,771,403,515,861,52,441,936,389,510,641,740,821,82,286,484,426,479,704,727,699,308,111,871,605,51,710,348,403,810,789,753,542,343,436,599,229,112,507,685,551,599,178,94,425,371,574,499,167,480,58,107,704,574,617,196,676,129,781,556,363,373,956,382,636,352,779,295,655,238,7,740,259,583,796,379,576,348,984,141,608,637,528,759,864,673,220,855,824,68,535,614,373,31,396,509,463,136,912,358,792,608,413,275,150,281,235,391,261,152,925,331,429,917,494,805,755,362,5,390,675,204,480,414,727,879,658,713,81,638,7,449,620,663,865,315,48,50,161,475,80,160,458,507,968,672,409,542,50,599,494,776,179,356,626,782,622,211,180,106,848,329,244,557,798,876,562,960,629,906,970,747,950,670,259,666,181,237,47,753,953,121,524,625,337,664,731,242,981,596,403,950,223,275,610,578,553,127,766,382,303,266,507,153,70,664,439,803,77,850,387,256,381,720,710,238,994,929,843,287,949,904,257,325,890,401,30,327,414,874,438,147,259,150,20,802,186,803,138,386,222,53,699,933,794,426,488,516,523,570,778,564,862,123,450,863,842,695,90,214,554,438,427,517,65,703,574,137,700,301,355,730,788,557,466,387,495,767,569,655,69,884,704,783,152,750,596,175,479,816,53,838,334,613,280,621,298", "638,526,192,51,988,588,83,291,686,627,261,70,419,5,573,596,75,215,683,936,896,504,714,194,107,235,810,671,228,16,523,377,412,940,3,114,50,44,635,196,771,84,310,849,24,143,808,631,346,958,996,95,632,563,648,147,768,917,878,171,374,167,108,90,842,84,495,970,32,587,453,224,34,971,183,861,403,372,577,108,536,248,964,590,88,52,308,204,31,59,44,428,868,134,791,904,495,602,255,735,289,746,215,569,326,223,377,431,751,96,211,259,32,64,84,307,49,908,997,356,440,907,494,708,861,424,154,708,266,191,738,478,624,188,92,244,345,757,314,998,945,543,604,333,625,196,82,142,375,677,621,968,113,7,825,461,27,908,595,648,348,482,107,105,667,188,696,461,62,421,155,985,849,720,494,498,309,327,875,399,411,369,765,46,195,996,46,250,835,548,757,638,345,266,882,825,881,265,504,519,862,520,834,463,494,43,650,345,461,900,984,55,500,833,615,714,945,233,763,852,444,113,54,767,692,509,645,883,27,161,627,142,478,947,897,631,884,770,609,51,32,960,584,799,595,549,893,571,75,345,713,223,458,208,163,190,660,963,916,869,877,594,243,248,205,969,652,443,496,937,228,966,400,932,922,771,212,721,873,751,745,770,674,464,890,911,442,784,716,241,894,21,563,298,919,139,948,380,989,576,181,348,102,836,918,156,740,13,420,92,607,666,81,758,492,457,452,370,555,810,582,516,46,11,906,681,768,462,537,849,601,347,261,460,950,138,243,889,719,596,140,407,681,71,506,41,554,993,660,293,714,453,479,720,410,635,698,496,71,772,825,873,314,101,837,100,273,173,979,678,241,787,630,660,540,571,462,138,101,311,116,965,354,748,127,890,96,29,743,72,750,292,542,357,917,507,826,334,662,428,876,249,498,989,580,626,914,116,436,956,818,385,196,727,197,241,757,9,887,994,576,597,87,427,765,29,854,492,921,41,818,706,976,93,348,214,925,243,397,72,32,417,730,195,423,319,670,545,257,651,425,0,782,771,246,820,976,490,899,697,447,279,332,434,300,629,644,500,160,842,464,507,998,610,281,653,484,910,961,46,777,667,440,842,827,914,835,20,687,903,380,83,47,16,937,977,377,707,936,999,729,496,705,820,880,801,896,209,756,504,770,626,199,445,524,471,200,902,553,969,253,813,210,519,361,5,176,375,83,149,966,697,487,360,515,481,917,938,248,18,811,905,702,173,890,319,205,960,425,559,354,942,193,116,617,547,15,727,40,777,581,268,383,218,123,568,337,822,648,397,19,591,360,60,436,54,793,550,531,362,649,344,75,631,424,184,639,493,595,907,35,201,953,40,390,600,522,19,518,177,72,851,980,716,32,314,670,860,753,346,556,765,741,870,347,314,746,867,241,901,308,835,960,88,731,219,803,897,752,316,208,271,11,133,153,696,491,129,324,530,416,353,382,275,937,640,666,776,410,989,33,270,115,295,116,663,407,735,590,566,202,194,348,651,720,212,717,967,452,759,503,916,755,840,924,1,467,54,791,509,555,62,692,85,826,194,115,805,969,87,818,350,812,778,110,506,707,855,28,430,578,570,265,835,983,360,115,698,648,171,838,983,534,999,305,585,999,805,450,298,785,6,500,375,148,523,398,479,980,454,379,50,888,429,24,430,968,339,476,485,730,91,503,618,714,2,495,894,223,117,462,78,48,729,2,23,918,762,131,181,369,535,528,743,500,338,345,703,720,14,279,878,349,321,935,720,574,463,428,87,658,894,707,160,70,758,47,721,818,4,433,107,382,337,742,761,137,435,356,344,169,960,15,378,162,339,867,752,858,274,326,485,110,839,100,412,687,447,295,263,673,345,447,873,673,819,927,671,207,710,779,328,368,710,55,528,889,805,765,659,969,44,588,753,417,663,904,930,610,409,678,285,594,449,786,617,96,928,423,188,418,114,901,241,466,202,635,824,487,772,80,24,875,834,382,978,932,410,956,526,416,148,406,713,761,325,329,144,114,780,827,356,370,596,369,657,368,189,890,320,157,380,679,38,527,83,274,361,783,190,237,255,779,980,91,130,535,749,855,84,386,764,144,40,177,248,178,816,387,673,463,803,557,552,758,447,893,552,813,413,683,562,356,15,761,738,305,854,830,731,315,590,94,452,703,527,555,730,631,892,890,19,434,239,540,760,13,96,236,348,260,556,468,553,577,392,146,956,76,453,876,143,465,508,18,690,395,879,552,342,756,814,772,581,427,314,664,568,413,1000", "862,689,118,34,190,209,161,410,734,549,428,754,980,844,76,620,509,617,27,276,571,103,880,802,968,357,440,616,455,948,877,243,319,181,842,682,969,664,64,441,42,867,23,432,257,419,319,367,46,347,268,594,939,247,146,620,612,662,169,22,982,282,776,49,923,711,657,204,106,294,932,401,792,377,701,581,287,600,534,868,588,362,243,184,359,917,162,975,755,730,602,45,909,282,860,178,720,947,600,405,768,913,126,398,41,16,409,708,177,857,43,498,20,403,654,612,586,53,133,393,225,41,554,119,195,288,295,437,430,501,345,932,261,467,927,25,503,439,672,946,575,563,597,270,418,927,191,187,858,779,226,818,739,657,55,457,745,411,888,622,398,553,360,813,708,521,225,921,695,138,933,462,296,901,892,397,677,165,78,174,414,623,31,209,31,684,60,137,950,453,600,948,809,626,914,85,111,452,568,983,846,173,415,678,761,899,440,97,299,466,141,18,371,123,475,813,826,408,985,741,898,685,871,864,524,884,76,521,376,135,579,342,839,308,650,813,358,546,393,474,605,925,630,186,70,666,203,171,541,78,549,506,778,88,803,696,765,903,350,348,202,959,893,627,396,323,717,64,579,72,309,143,677,588,721,485,478,563,549,477,172,540,713,388,826,659,827,350,727,705,320,221,829,476,46,56,125,385,365,319,187,436,450,314,398,571,724,703,267,875,610,364,144,349,190,819,374,447,137,745,467,64,822,373,21,353,67,585,242,302,752,793,171,647,206,538,714,227,349,42,856,96,184,863,17,14,376,403,924,564,914,292,436,349,693,762,710,304,377,856,627,561,96,725,935,539,22,374,803,193,962,807,525,603,562,975,95,385,920,278,657,849,190,685,664,411,570,268,132,354,10,624,841,768,876,301,207,700,347,343,890,544,404,303,529,850,241,379,308,210,474,302,834,500,681,558,40,661,461,562,230,629,267,328,173,473,94,643,774,33,812,760,459,465,546,854,149,242,486,989,681,455,571,731,949,936,883,444,734,491,713,782,0,491,316,550,702,383,413,197,565,560,382,670,397,645,809,206,682,790,176,546,976,330,151,977,666,197,926,959,743,544,422,242,553,432,803,700,841,6,415,119,812,184,978,164,739,855,507,830,395,609,901,116,291,927,897,515,929,988,630,449,253,582,508,866,912,469,92,996,771,716,509,893,115,632,410,209,834,732,838,715,262,210,933,156,656,823,454,675,363,551,969,517,602,959,543,579,14,993,632,879,247,7,557,7,232,614,418,571,800,582,193,312,928,477,135,745,996,933,4,112,765,472,592,146,541,481,198,668,668,316,968,59,835,645,467,963,646,820,811,693,972,279,151,990,223,627,827,893,191,36,423,839,421,971,533,533,373,52,827,199,820,199,767,177,976,331,202,438,757,21,443,286,237,935,889,796,643,885,505,473,657,815,534,147,270,906,119,504,112,569,132,787,642,526,560,984,89,523,477,201,933,101,841,524,922,236,618,218,894,769,450,859,973,176,864,46,989,657,405,625,460,694,438,4,719,637,637,476,493,275,223,40,216,857,553,645,94,635,390,676,934,776,514,947,429,748,781,905,844,303,800,96,803,506,21,887,502,793,88,6,189,952,519,332,306,677,78,917,636,741,216,617,246,676,952,204,376,141,586,219,596,141,642,12,112,388,178,891,751,325,261,321,627,127,248,252,134,682,581,447,510,545,307,376,797,601,680,573,238,705,349,533,166,465,704,638,55,709,74,535,187,613,787,765,362,287,508,286,879,709,633,205,925,562,68,289,172,631,863,112,145,684,571,945,847,896,876,159,778,756,959,646,241,962,890,132,141,726,54,815,200,602,230,623,328,566,360,797,246,493,2,547,896,720,155,305,79,560,671,647,708,413,414,887,740,710,290,714,506,277,784,708,861,302,479,201,976,352,421,720,346,792,772,293,3,409,127,306,469,221,298,622,428,11,864,626,258,670,135,993,346,439,452,123,26,591,979,302,790,699,291,34,172,696,828,919,784,913,268,207,260,464,328,825,659,432,593,821,306,647,104,614,570,632,420,858,775,661,870,718,436,300,753,668,789,188,592,654,248,356,603,846,132,925,7,8,795,404,895,903,525,50,31,133,649,89,723,275,119,490,908,548,731,225,566,949,122,284,785,73,762,294,707,297,855,377,617,527,286,118,992,751,267,912,327,180,281,421,801,889,579,992,715,635,720,468,646,615,475,513,111,553,248,716,131,637,694,696,871,194,136,926,342,672,67,911,698,948", "170,858,36,810,983,681,51,912,491,854,759,951,771,213,600,669,178,730,591,696,647,281,498,274,266,954,692,187,288,542,712,644,61,651,960,131,282,491,620,735,432,598,322,352,858,373,590,803,875,124,444,208,784,14,652,757,871,703,28,292,395,159,799,890,987,391,675,628,698,982,185,196,213,76,630,819,816,533,330,494,301,339,144,326,399,240,438,94,478,763,655,889,960,955,747,378,219,942,217,739,667,596,387,165,642,881,481,376,880,384,81,845,873,972,325,884,122,979,85,581,462,132,802,14,434,739,45,397,221,390,919,617,126,885,978,80,20,900,345,575,293,64,394,465,7,962,625,640,996,427,45,571,45,877,883,677,48,567,472,915,565,280,588,21,258,385,271,265,349,998,700,871,585,79,981,669,288,241,456,393,380,859,963,324,602,915,825,834,257,452,419,556,482,269,109,264,699,59,761,656,686,612,279,419,835,428,668,418,42,264,714,499,160,785,864,669,618,106,704,872,428,675,877,265,361,733,532,900,387,397,183,753,105,859,447,210,149,110,44,153,452,493,171,606,349,376,919,911,207,681,375,584,782,629,216,70,207,601,793,463,913,419,985,875,723,119,205,759,656,535,764,7,1000,630,721,74,29,936,737,192,52,907,979,441,765,894,679,242,522,360,768,211,690,130,513,557,664,887,401,478,305,410,992,236,139,8,206,244,92,852,328,714,990,592,449,811,109,406,489,74,777,442,9,544,307,352,62,968,30,452,166,896,69,487,591,492,433,604,700,627,910,916,912,238,298,171,632,651,789,288,806,819,665,872,991,574,628,787,267,412,362,273,534,698,719,834,862,542,552,900,407,176,275,829,942,90,201,926,661,374,839,65,992,310,653,602,976,434,179,322,385,304,654,81,70,101,528,663,938,614,628,39,805,857,150,306,506,800,473,904,237,431,86,814,703,866,465,317,236,195,596,88,108,216,895,574,590,878,604,579,80,219,293,197,638,752,10,328,323,63,343,320,99,317,938,265,133,13,359,933,905,771,491,0,979,458,901,57,246,893,973,525,892,405,8,743,912,319,725,237,924,864,407,769,635,299,199,472,569,926,718,470,64,863,850,846,455,149,512,994,317,641,628,223,156,125,821,779,438,822,86,593,946,277,831,113,807,661,439,729,219,989,86,171,661,349,481,492,26,120,140,501,744,843,900,980,317,19,614,673,774,829,456,366,470,702,69,748,354,458,542,68,487,182,247,940,559,513,487,284,36,181,879,717,39,791,828,679,442,271,886,175,444,119,313,240,242,949,826,67,874,596,178,449,826,901,609,228,383,197,589,914,205,955,166,867,653,273,946,476,339,242,822,945,60,950,296,293,681,417,186,966,511,347,198,882,9,24,135,70,489,805,941,375,973,84,221,782,164,104,780,232,840,209,6,889,708,271,894,795,188,939,612,857,180,917,997,841,201,836,27,771,335,417,867,523,203,412,90,347,375,42,126,660,619,230,956,146,103,879,752,553,832,244,152,802,234,510,535,476,104,580,546,61,584,800,13,318,526,6,410,66,905,12,947,362,605,219,301,347,268,384,4,645,360,221,527,348,616,654,256,129,551,697,246,752,625,537,291,154,896,580,769,498,539,869,599,274,199,25,836,443,344,393,331,690,382,575,615,561,789,754,273,951,94,56,573,351,565,556,616,788,379,261,98,505,615,116,581,696,511,964,488,608,410,29,422,808,880,987,657,356,770,874,359,816,776,779,608,141,524,659,734,390,713,505,354,611,599,860,269,457,497,27,144,291,421,916,960,501,494,876,137,268,821,806,23,258,247,992,701,899,70,261,677,718,426,376,107,58,27,581,568,666,255,677,694,688,991,21,757,956,420,343,716,171,379,51,781,561,105,419,358,662,920,719,972,527,703,518,391,752,778,382,455,620,63,102,404,991,441,884,532,107,792,991,35,657,115,93,186,879,905,797,792,243,117,493,219,831,979,190,723,900,617,479,155,362,463,638,151,973,28,707,925,832,983,670,75,959,792,226,705,422,672,132,280,343,427,627,569,189,1000,597,359,441,673,934,78,96,345,196,735,222,32,26,510,616,329,253,941,249,654,824,247,264,651,226,966,388,44,252,499,962,846,840,925,896,511,932,947,137,914,915,628,959,89,833,152,932,501,262,311,198,672,285,632,524,545,208,801,700,162,762,167,488,773,362,13,838,33,583,342,284,674,445,594,398,157,660,251,769,613,298,786,421,29,585,838,289,413,556,197,129,372,898,562,184,507,417", "916,224,921,143,55,247,62,479,108,544,522,305,985,812,438,157,542,98,242,482,653,230,424,811,17,275,178,969,92,301,568,26,622,858,873,84,608,418,763,660,829,775,346,271,721,992,560,94,177,477,67,290,88,303,533,795,896,117,221,367,523,13,734,434,425,242,846,522,302,592,977,467,70,930,551,729,521,707,923,977,267,862,484,562,217,554,819,353,885,642,842,353,941,504,925,68,799,402,833,314,946,190,369,192,206,539,8,871,232,669,931,65,429,91,901,797,16,646,34,735,431,503,931,644,911,579,152,151,737,757,390,264,684,795,779,776,495,71,486,530,442,296,89,703,863,90,550,529,426,591,399,455,95,544,60,9,849,933,873,908,223,841,320,786,951,46,571,553,591,33,517,144,811,64,822,650,684,730,677,337,307,172,702,976,423,8,961,239,809,432,759,165,507,93,17,726,921,891,863,223,648,646,908,705,857,332,117,533,777,329,270,820,742,142,742,842,385,598,978,590,841,358,363,593,41,532,210,721,149,399,894,657,943,678,921,805,683,577,590,11,951,648,94,38,886,387,139,548,646,430,330,790,306,937,848,603,94,391,157,378,101,651,692,259,787,598,550,967,917,777,983,416,101,362,138,466,161,490,447,270,67,510,584,290,812,490,854,523,531,973,165,549,975,705,319,9,82,835,142,177,34,664,383,641,658,632,23,466,113,930,64,750,788,13,574,491,590,433,75,126,749,294,576,355,491,871,814,260,437,272,866,696,620,640,216,545,413,853,654,184,62,588,273,621,486,361,443,561,620,841,274,357,194,561,934,273,187,810,311,425,560,325,438,595,303,545,405,7,8,495,646,267,643,317,875,745,324,655,708,425,822,525,819,952,595,489,461,137,636,370,512,740,291,609,773,921,316,25,503,206,723,44,674,838,959,427,33,631,279,631,26,456,953,468,335,300,660,68,847,416,969,831,208,210,851,917,852,715,116,452,726,828,486,511,785,267,907,640,829,79,57,840,957,209,628,974,106,957,849,168,330,246,316,979,0,721,671,98,248,100,764,47,659,918,453,540,633,256,108,827,54,320,981,630,26,491,807,45,503,653,569,131,976,625,397,971,683,132,742,51,794,49,995,729,32,725,214,777,450,321,511,36,218,938,858,287,440,444,523,904,737,419,678,339,126,161,755,365,616,2,717,424,922,876,684,218,677,210,474,300,49,186,316,804,756,256,198,758,78,61,272,763,769,87,662,510,866,795,540,290,507,460,838,346,753,712,449,799,772,367,566,787,655,232,799,681,979,934,380,925,796,752,462,369,179,879,429,194,510,704,100,103,613,928,518,893,728,537,378,944,7,804,240,486,541,742,428,493,530,764,171,744,441,256,409,396,149,110,250,450,700,191,899,854,583,151,525,135,174,537,514,157,690,51,992,367,433,392,210,719,490,472,68,284,970,461,806,554,104,307,669,537,60,468,123,210,670,261,216,5,117,419,378,639,635,15,630,242,470,532,44,983,961,937,210,146,398,321,630,242,271,494,46,473,515,432,532,536,730,190,932,138,246,781,677,367,289,22,300,759,416,712,618,225,912,469,630,878,161,997,277,206,279,196,58,322,352,786,239,173,826,453,72,970,280,999,135,22,969,242,897,684,55,768,409,429,846,517,153,357,155,467,655,689,125,745,864,695,375,651,372,87,251,391,326,641,452,944,37,635,947,884,541,100,60,344,909,972,194,996,34,373,353,129,381,221,159,193,635,892,843,193,676,289,886,779,270,612,566,917,818,495,113,984,125,934,611,725,510,734,42,234,373,543,191,430,583,132,148,711,659,867,936,914,423,861,508,762,900,330,561,436,743,864,896,222,817,457,203,896,452,899,143,562,511,78,762,258,761,446,706,783,186,66,928,602,550,240,39,272,275,325,405,696,443,824,454,367,95,470,345,763,916,843,831,206,308,89,433,718,995,835,806,167,376,259,674,874,929,892,210,535,47,425,408,782,423,901,842,746,120,400,434,196,862,485,187,864,421,964,38,124,261,741,665,21,511,77,463,328,283,511,920,235,580,274,235,587,736,370,393,772,109,854,593,46,547,743,637,485,898,122,612,264,908,728,922,965,114,643,318,695,803,570,346,3,398,178,88,715,284,185,488,329,250,719,476,3,871,685,113,500,310,905,753,113,496,718,504,34,307,676,685,497,72,274,340,945,242,918,97,709,315,914,421,721,181,933,942,677,106,912,535,825,171,707,217,521,57,268,604,856,844,732,867,606,961,976,357,957", "806,381,715,908,243,154,419,684,990,896,373,431,972,192,195,331,836,61,469,292,620,803,219,687,420,797,707,408,721,326,635,38,516,330,171,880,339,37,28,169,855,950,194,916,145,13,27,898,132,706,647,742,274,393,407,938,790,927,384,48,149,393,807,537,306,294,578,468,23,697,5,20,914,612,175,722,168,257,271,960,780,306,23,618,571,725,738,806,110,838,664,262,313,570,370,70,963,545,532,96,473,749,516,550,19,203,57,517,318,702,537,468,400,134,542,125,921,508,457,13,369,45,634,306,415,517,158,151,75,132,37,477,913,260,324,742,625,998,415,250,465,313,744,985,8,215,609,541,192,202,763,57,692,209,753,940,713,599,703,259,702,409,957,870,778,201,405,240,908,385,785,759,486,177,295,477,979,609,740,203,144,351,745,400,51,991,262,533,357,213,55,874,227,494,108,290,774,667,321,221,942,362,806,445,875,713,277,577,147,96,394,512,95,500,824,48,166,329,350,903,931,192,985,617,49,277,479,340,285,328,706,906,569,954,563,775,363,877,131,64,471,796,222,780,861,287,684,455,104,157,124,482,488,894,518,646,227,609,637,98,291,780,660,918,525,829,336,705,51,573,848,281,901,932,489,137,394,749,463,748,783,896,495,978,452,161,839,584,38,752,47,341,722,756,981,829,166,499,796,529,519,612,995,111,303,541,658,125,473,541,744,149,464,528,525,107,152,409,427,591,608,340,123,114,553,51,787,804,710,2,390,170,241,913,109,404,14,224,336,505,605,719,173,931,352,452,482,519,690,28,46,376,632,565,94,493,946,931,784,419,113,937,268,697,452,399,978,701,312,674,336,694,168,611,62,701,166,538,58,425,921,435,68,932,504,152,926,214,659,471,382,90,520,522,76,515,611,764,185,924,247,169,510,758,845,779,278,407,648,536,136,604,991,397,163,86,6,216,417,318,527,618,856,919,30,50,77,565,207,868,864,289,857,421,807,644,783,120,593,958,713,738,879,322,842,986,303,917,616,845,179,820,550,458,721,0,850,666,101,883,860,41,361,94,577,772,163,166,673,532,925,879,37,411,913,800,206,145,936,902,902,247,584,452,357,89,752,970,13,131,339,944,851,44,962,251,687,674,734,179,212,512,321,472,6,617,780,987,729,399,538,560,517,45,481,318,21,612,790,945,105,719,936,82,166,572,419,781,961,162,759,966,55,277,558,163,747,887,773,835,466,987,411,298,86,776,945,915,563,909,407,991,96,697,729,375,25,898,756,819,39,729,476,369,945,231,180,352,111,36,738,530,988,312,315,579,866,984,849,700,201,534,505,482,678,481,77,119,729,994,365,904,132,723,21,510,242,509,8,534,290,909,430,978,208,282,494,59,213,614,610,965,300,941,178,497,570,875,473,622,520,574,712,136,141,320,725,732,628,202,284,915,491,633,941,248,198,8,113,280,846,360,624,904,251,480,222,483,175,957,753,104,985,994,872,376,625,828,981,660,861,98,713,677,828,673,163,777,895,14,844,55,565,78,51,372,849,209,572,503,126,931,346,638,613,713,431,749,491,503,967,239,562,926,586,792,704,713,655,787,494,51,750,255,424,713,485,621,306,613,715,346,13,545,777,640,30,136,277,624,195,842,628,670,546,452,706,701,492,614,321,84,630,615,111,689,557,636,346,514,260,291,612,95,583,106,798,447,34,12,32,903,734,789,844,668,3,271,493,832,948,146,416,877,106,696,302,791,828,259,21,832,8,990,990,920,174,350,705,89,277,642,216,970,549,486,963,568,603,855,656,110,20,555,455,612,244,600,412,920,67,209,596,715,191,498,534,283,58,171,438,265,498,21,42,22,306,909,965,41,957,845,92,874,984,418,784,516,68,200,465,806,392,428,791,363,199,756,899,199,711,304,380,62,932,100,277,697,684,522,811,681,845,362,393,588,382,270,308,956,981,338,71,23,779,328,806,722,713,880,288,723,445,670,956,363,329,636,192,235,571,505,160,959,908,929,327,285,735,411,746,174,913,849,204,125,270,157,726,350,672,722,670,377,590,164,885,195,925,392,591,670,337,23,798,760,94,578,43,230,762,327,675,200,632,132,984,781,931,708,616,964,322,478,512,957,16,635,19,57,348,982,44,45,929,90,577,411,837,512,236,130,106,223,778,115,612,997,699,280,537,573,2,671,105,47,819,418,452,483,496,147,986,754,758,987,656,90,62,605,700,53,124,318,919,331,347,497,340,710,795,497,416,945,114,662,430,625,822,463", "721,526,831,482,621,105,496,837,355,12,608,209,855,958,819,781,193,831,630,325,746,994,9,601,108,5,908,160,14,166,197,538,212,418,618,872,501,207,243,96,569,389,41,682,776,617,349,894,31,673,598,364,429,453,859,9,37,951,652,706,933,304,998,327,210,921,447,957,757,105,196,56,126,545,870,328,404,25,462,129,432,489,874,91,756,484,652,903,580,152,125,699,901,26,77,755,841,875,449,8,317,267,696,941,864,873,491,116,986,417,971,989,151,897,920,87,432,688,910,234,155,836,84,99,194,162,1000,664,942,895,929,277,343,729,324,718,536,880,731,631,844,161,558,60,536,790,139,293,162,221,604,894,461,35,74,958,832,617,303,608,951,413,76,104,860,482,46,908,635,136,9,134,297,253,381,748,52,834,149,114,611,747,689,213,846,395,846,940,756,642,598,873,727,901,399,500,432,389,324,2,542,53,377,797,515,839,889,771,947,238,378,167,207,986,974,956,189,702,139,470,14,301,434,714,757,110,206,989,522,236,10,350,259,657,444,306,105,626,43,477,725,44,859,426,121,190,901,410,591,946,935,494,594,642,309,961,708,932,638,916,178,468,464,168,123,694,311,833,688,689,388,297,400,127,841,318,447,49,798,66,449,618,890,533,474,33,612,28,134,424,481,19,365,855,185,157,881,23,634,692,394,276,443,716,850,712,529,183,824,125,540,526,913,903,345,433,356,574,737,319,802,507,448,599,288,914,940,404,986,50,939,945,623,950,313,617,131,963,325,631,890,978,356,358,125,546,741,336,829,262,693,930,261,189,952,818,847,83,695,696,238,323,899,388,3,805,878,405,227,547,652,574,946,915,649,459,496,126,800,875,628,647,473,869,829,5,18,965,789,469,262,614,937,60,714,726,515,839,363,998,625,546,642,148,385,102,269,292,199,681,145,222,161,243,153,628,409,73,290,458,692,952,15,212,802,698,535,759,404,664,611,774,714,644,404,331,734,604,376,196,659,87,21,150,483,23,488,128,392,866,301,976,702,901,671,850,0,109,63,537,332,616,105,132,860,50,271,848,235,266,123,297,1,798,527,85,595,535,308,206,222,723,69,144,725,626,753,461,448,65,858,403,922,908,184,648,286,296,775,471,970,780,367,9,574,307,705,478,781,48,447,760,440,615,914,364,553,780,856,1000,690,104,164,930,171,729,595,881,87,744,104,290,602,139,115,145,733,737,849,419,904,862,911,196,832,249,650,33,208,181,353,98,104,217,115,118,35,974,276,935,663,936,823,274,726,889,565,45,387,476,376,26,894,589,445,819,700,214,422,84,797,820,766,435,287,587,2,366,32,730,121,989,678,42,796,482,809,964,70,340,93,34,655,693,764,745,272,247,355,11,369,77,649,201,417,450,892,426,567,900,665,275,191,30,235,728,413,936,535,659,667,193,78,285,865,197,399,526,858,985,608,778,727,919,352,204,253,927,211,934,577,705,691,746,958,153,557,716,68,683,568,871,765,401,557,806,167,823,333,588,681,53,24,222,881,409,412,111,974,43,39,792,848,739,816,555,584,901,667,981,331,860,746,748,454,86,994,595,762,645,446,124,710,654,259,969,962,281,946,975,872,842,513,913,847,36,479,126,588,749,290,6,1,49,299,146,252,244,896,994,372,891,100,161,15,78,71,101,314,33,582,673,225,733,744,288,652,448,681,358,815,380,45,460,746,515,101,953,55,535,19,695,97,420,447,135,745,701,80,9,271,791,296,656,470,584,111,375,863,546,980,798,135,361,998,700,885,873,24,21,262,468,776,7,373,399,549,444,706,77,532,605,501,147,513,356,569,385,733,541,899,709,514,507,710,931,548,111,274,437,612,726,6,148,731,993,455,904,222,278,88,778,834,268,961,765,255,766,103,730,403,850,760,776,523,85,662,152,771,631,813,850,204,586,150,342,427,219,562,459,889,913,265,958,751,837,849,562,68,285,919,653,745,640,752,711,430,600,922,929,683,921,39,619,214,409,578,807,159,428,781,964,620,455,702,619,708,251,249,162,205,853,351,713,633,3,995,461,159,902,508,280,19,320,728,752,220,933,585,595,79,623,371,98,11,645,251,778,747,635,627,327,305,221,300,613,974,466,453,166,269,867,26,486,521,406,834,176,878,225,530,435,455,929,651,652,958,386,13,40,480,617,400,512,834,173,173,610,234,25,791,950,337,483,81,496,304,965,313,710,43,61,114,852,493,131,759,575,943,435,113,641,520,738,666,782,189,603,28,123", "100,607,958,932,141,619,372,639,658,168,847,352,710,659,685,552,569,264,347,93,728,9,3,804,286,933,999,790,329,685,789,546,393,882,981,85,875,932,433,792,432,936,635,810,449,518,676,472,898,710,22,122,187,188,17,754,6,625,32,293,657,590,319,90,114,650,726,437,828,128,534,100,729,969,64,59,663,791,852,676,150,624,876,930,569,278,901,625,642,845,754,680,895,679,776,48,682,533,82,307,687,658,26,452,932,954,864,627,26,527,907,668,860,123,457,65,328,222,504,138,846,691,581,264,24,987,671,847,398,914,26,692,865,899,641,842,658,245,106,926,602,532,38,72,299,696,242,210,278,565,408,439,713,86,311,987,850,109,354,582,898,794,294,969,587,689,739,328,850,200,792,815,875,140,670,175,477,753,129,641,681,379,37,833,249,220,15,219,870,164,741,582,605,618,880,807,97,951,887,539,574,456,244,771,235,889,167,959,705,330,187,371,49,184,696,583,904,494,267,273,511,712,449,298,970,304,356,693,285,81,7,881,175,835,208,123,709,34,944,102,282,74,568,557,681,970,930,192,615,939,684,320,19,682,675,396,796,989,768,868,912,904,140,835,815,323,46,504,85,887,687,67,898,470,532,837,835,641,372,149,629,986,807,870,411,734,38,965,325,941,816,362,61,475,465,312,316,475,928,948,583,216,308,160,427,744,866,88,134,407,574,392,740,203,271,864,247,610,556,891,299,706,811,379,444,658,933,504,974,583,279,503,120,686,713,87,191,716,703,769,141,651,390,256,279,24,299,23,509,827,79,749,460,116,996,450,94,557,258,579,839,132,755,334,787,173,985,654,127,358,780,591,588,386,866,554,917,625,769,443,84,523,509,251,221,799,376,77,148,845,293,834,875,396,898,183,495,170,130,907,418,664,962,674,69,961,299,335,989,8,639,543,482,576,869,503,2,202,316,348,409,42,995,240,402,194,45,729,677,974,801,948,420,887,274,273,963,784,793,876,355,563,778,986,804,529,887,842,167,419,756,490,383,57,98,666,109,0,760,282,627,81,555,988,681,471,985,660,925,16,590,380,183,977,920,823,288,58,547,406,693,422,3,97,583,303,243,575,122,25,993,108,675,709,111,955,626,234,603,536,309,75,567,666,864,537,551,553,598,438,213,641,476,918,53,815,997,512,832,794,408,594,970,271,124,582,864,614,518,505,11,726,723,525,981,91,841,628,308,913,323,987,320,485,424,875,985,155,294,249,145,175,360,340,555,495,394,954,626,105,879,43,525,692,412,802,555,938,346,765,96,820,803,16,584,393,831,40,430,724,272,387,278,806,36,570,930,743,649,438,165,261,637,941,370,379,631,414,419,173,751,167,787,622,94,294,211,378,745,332,336,692,151,467,890,151,174,879,575,256,588,428,649,203,444,548,49,192,797,352,595,918,442,610,432,925,537,685,122,309,773,320,148,432,798,155,931,138,654,775,994,126,353,300,491,726,481,258,566,9,73,420,659,934,385,347,347,286,419,242,166,130,538,696,644,913,340,979,148,709,961,943,250,566,123,973,512,215,407,33,23,238,635,665,901,427,252,240,265,842,205,869,713,952,391,632,835,734,849,143,366,568,660,470,56,593,936,587,370,596,907,3,836,396,441,963,498,713,631,89,793,549,676,681,634,540,348,424,397,799,872,759,683,214,361,229,2,447,654,313,939,390,510,443,82,115,739,583,804,10,951,513,856,230,914,882,141,669,900,628,870,646,410,635,493,616,989,619,258,772,459,473,70,800,570,710,795,987,415,617,154,476,70,226,409,331,851,457,793,802,765,212,34,580,440,337,16,547,986,81,596,154,455,307,624,600,178,217,854,26,101,801,934,308,159,617,104,951,32,439,975,151,666,89,562,117,426,335,830,902,993,469,139,189,448,574,167,349,427,345,692,892,747,820,99,305,710,529,534,711,414,798,880,674,528,335,444,823,665,328,383,37,662,948,948,604,561,495,12,701,367,610,753,376,226,930,723,141,851,838,87,380,847,214,848,83,870,720,800,514,902,107,761,690,20,114,670,169,574,32,340,553,191,188,169,451,857,903,299,20,925,656,600,797,341,281,43,578,862,124,815,435,293,50,764,670,131,321,319,928,247,690,183,440,904,403,246,755,401,743,357,879,181,451,358,189,515,492,782,702,843,307,363,246,469,546,600,821,774,501,642,672,948,54,376,874,713,417,531,458,177,175,984,709,755,327,886,212,315,775,614,74,567,608,592,183,321,511,208,411", "395,119,774,521,25,319,810,560,204,159,401,947,948,136,852,628,923,702,749,623,673,457,89,403,410,542,69,356,587,132,294,601,663,256,177,623,805,881,609,898,988,565,190,805,35,148,314,374,478,142,323,338,737,404,260,60,941,770,469,861,400,770,18,579,387,549,954,741,69,515,897,943,176,719,827,559,981,205,504,338,252,736,430,934,438,546,414,289,61,874,944,685,790,200,13,510,498,313,507,835,247,547,728,974,987,437,72,305,858,929,30,611,314,398,548,137,344,169,11,860,651,439,160,98,816,559,263,220,658,941,209,254,687,769,998,712,407,764,846,219,974,724,464,294,94,144,330,715,943,615,719,262,867,327,86,638,70,385,156,375,662,358,332,152,879,166,300,640,798,981,536,103,26,251,822,573,410,91,48,290,638,263,674,496,333,345,430,948,931,423,138,182,207,68,742,609,992,889,871,436,788,246,935,124,541,775,113,44,78,617,14,617,755,868,403,666,778,795,373,140,816,245,820,762,654,184,954,962,490,485,8,109,104,949,629,759,284,78,571,440,725,822,917,521,193,724,725,520,723,448,295,128,27,371,169,763,361,353,834,190,595,180,859,188,711,45,823,890,336,860,702,43,466,335,819,782,43,675,424,373,318,541,223,7,366,383,340,11,159,619,649,977,493,781,128,307,740,471,20,587,197,871,356,882,311,394,955,577,833,486,701,281,25,297,666,767,741,1,609,956,716,755,943,273,842,35,590,103,789,149,277,400,614,872,72,181,861,286,92,640,523,346,513,440,465,113,218,572,347,899,787,465,562,998,671,762,719,297,842,57,899,833,443,523,295,708,911,315,427,240,989,569,47,650,217,294,733,90,850,644,540,862,651,352,378,739,303,686,833,564,266,135,939,985,309,570,854,906,879,136,635,898,878,827,803,608,388,100,226,194,589,273,585,87,107,529,59,616,17,13,925,799,712,783,751,157,76,167,212,652,444,590,962,774,780,349,155,696,77,389,468,171,12,410,430,566,246,218,369,93,670,899,413,246,248,101,63,760,0,272,828,520,792,384,525,36,666,632,30,364,405,463,562,62,587,328,77,815,637,388,108,333,127,926,695,903,992,80,641,450,495,959,728,761,415,52,84,871,276,331,61,269,12,62,694,716,651,417,305,264,334,687,237,151,797,502,430,400,690,374,367,615,730,68,740,962,272,360,611,233,813,218,904,263,124,823,489,523,168,191,156,510,84,10,110,781,539,40,340,240,905,273,816,834,418,705,242,510,787,494,935,619,930,397,667,502,717,546,996,585,836,729,372,438,64,923,4,749,736,822,532,720,598,394,273,499,887,805,655,666,767,742,430,225,523,519,931,620,411,638,344,355,910,821,919,675,377,178,663,194,918,266,735,724,174,300,457,871,257,118,958,870,216,251,601,251,231,533,377,339,964,45,60,913,894,195,673,448,969,176,422,20,138,67,259,985,430,635,777,180,81,30,507,736,928,88,490,171,860,678,324,999,372,800,137,736,486,141,57,395,63,573,173,442,606,199,387,995,907,996,534,826,186,39,194,149,85,667,909,459,305,389,856,17,752,520,504,719,84,653,429,650,685,21,462,256,725,642,736,912,531,14,635,687,64,117,552,683,648,596,534,252,69,826,806,576,925,530,275,935,285,686,428,306,780,654,869,295,16,291,517,870,431,202,596,590,407,642,37,893,280,452,705,866,496,154,597,8,655,42,405,969,125,669,210,819,355,429,158,61,226,77,825,854,973,694,821,798,806,186,504,253,194,140,996,615,365,160,862,769,727,385,256,148,830,624,594,808,636,499,25,182,901,686,204,262,985,788,700,804,738,508,343,737,497,767,265,725,839,242,314,297,675,439,826,765,237,577,301,388,457,768,614,50,921,626,377,18,546,371,270,690,127,955,310,487,945,107,667,423,739,690,98,515,525,125,632,121,207,927,930,394,629,215,448,1000,176,468,393,607,552,214,731,818,881,746,66,733,190,120,218,657,103,897,88,900,989,525,517,464,669,498,483,621,870,871,435,634,237,929,663,175,471,587,739,956,614,835,558,415,122,658,512,391,297,978,225,725,938,435,961,148,718,980,496,946,852,480,392,547,739,191,11,542,977,575,720,993,883,737,754,228,346,62,166,727,227,339,221,304,706,997,66,58,339,396,838,390,267,508,306,216,264,200,880,122,821,472,724,650,559,701,117,409,464,842,602,437,454,755,620,890,6,486,783,476,578,673,598,969,422,381,613,649,993,676,207,526,379,636", "800,646,933,535,64,272,953,723,597,342,199,541,213,665,231,693,664,416,650,278,865,973,583,686,995,117,39,29,928,858,809,682,305,491,344,859,108,812,159,118,8,891,968,761,513,624,960,950,849,131,441,266,974,190,628,931,874,189,966,618,559,375,748,886,345,908,711,476,720,40,898,252,798,484,908,209,317,283,347,327,725,170,986,3,88,935,398,2,165,476,56,858,429,845,200,948,617,789,658,193,49,483,868,324,321,658,78,210,976,425,324,251,931,598,22,214,730,454,674,750,246,528,896,973,875,199,478,96,993,130,229,256,995,904,515,311,199,456,203,6,32,902,492,958,810,292,4,698,241,367,684,65,930,456,398,777,675,249,693,776,534,458,748,438,820,150,866,417,239,625,124,819,101,739,73,949,693,772,707,783,904,152,580,942,447,293,408,176,448,540,298,488,488,612,796,749,93,137,189,370,880,279,823,903,905,210,75,733,361,371,314,336,155,377,412,834,725,50,344,335,157,444,272,87,291,704,730,2,792,225,110,167,917,599,181,900,667,999,516,559,265,933,550,354,273,627,398,556,695,903,299,97,699,256,128,528,471,803,835,499,777,520,69,140,662,990,460,875,123,370,251,584,36,505,746,33,855,800,640,381,323,294,622,656,380,160,13,404,798,3,671,316,199,803,317,703,534,771,91,926,90,535,972,460,114,251,173,338,746,459,364,657,716,37,904,935,569,314,879,865,975,190,425,155,124,674,188,214,784,976,836,833,572,402,521,489,243,247,72,742,884,648,247,455,156,671,917,199,101,577,189,232,264,294,586,447,80,124,146,546,760,613,636,589,178,324,482,575,460,944,24,637,799,955,830,419,983,551,706,498,705,238,513,475,82,87,469,357,557,506,885,288,257,129,677,40,134,50,365,567,540,489,882,104,858,559,838,320,303,161,420,222,647,938,725,432,178,854,948,778,960,152,680,640,884,729,277,623,429,835,225,614,530,304,604,112,290,423,988,531,563,75,848,319,761,549,440,73,181,555,437,697,197,893,100,883,537,282,272,0,463,399,354,117,844,469,786,528,801,380,773,195,205,21,319,654,241,688,78,626,591,426,383,445,934,206,958,714,430,747,801,195,979,505,30,726,46,610,705,638,128,700,261,98,234,540,362,193,564,930,142,354,329,102,846,196,658,376,154,848,531,970,713,636,340,506,58,104,332,929,97,558,469,654,195,38,818,994,450,462,22,117,216,669,709,376,628,419,25,11,433,337,493,643,648,237,29,19,197,958,366,498,493,847,215,59,205,35,503,446,180,443,850,464,320,985,801,214,411,122,537,67,84,580,761,235,432,66,401,296,961,201,901,295,796,432,526,838,791,681,682,879,344,500,921,770,113,988,832,173,735,414,62,425,821,856,309,61,597,175,557,477,727,209,558,954,347,232,708,955,445,670,571,63,830,770,732,724,89,800,973,958,919,910,27,846,757,734,624,398,256,13,693,934,975,431,338,270,511,986,756,845,796,446,452,961,650,745,261,538,432,820,774,215,872,53,419,438,849,179,668,396,343,611,579,885,395,302,870,441,700,398,703,318,822,562,826,931,955,838,185,899,502,356,302,224,141,703,841,230,629,913,105,83,714,254,696,625,428,176,151,549,11,247,279,508,775,917,86,596,617,805,534,713,758,838,20,993,563,508,12,65,794,110,580,293,435,7,933,927,375,635,595,517,508,575,942,83,975,846,459,191,768,678,700,721,721,589,208,745,777,410,312,67,536,797,533,902,284,785,602,231,206,360,721,965,711,532,231,334,177,323,412,918,113,971,791,436,321,228,211,699,61,395,29,457,252,220,974,167,238,420,850,768,531,399,616,996,775,214,830,720,448,841,91,420,313,557,460,306,166,525,489,910,361,426,950,28,965,253,947,986,547,378,786,333,442,505,21,155,119,84,833,733,797,730,822,919,468,670,909,591,238,676,541,680,851,555,796,510,576,663,701,656,306,83,395,430,523,875,516,527,396,559,579,162,113,432,427,182,589,476,246,193,247,197,922,106,752,676,184,181,613,929,962,672,310,253,255,819,46,685,802,22,298,565,503,900,560,960,613,205,499,810,48,191,235,561,59,759,780,124,299,474,21,751,77,870,616,924,275,159,329,724,77,55,341,589,540,953,822,156,356,596,463,727,448,248,332,589,645,849,528,155,497,2,260,313,248,652,253,419,826,955,687,386,867,803,586,830,385,72,993,324,156,649,938,258,424,586,463,478,15,159,738,769,46,756,830,420", "244,544,473,174,537,501,368,704,733,133,675,28,896,156,608,639,93,678,793,289,853,572,57,112,510,687,340,650,78,635,710,986,113,466,361,882,584,274,839,53,924,382,597,330,65,292,774,308,469,146,161,127,687,505,59,422,45,445,677,679,842,958,544,228,283,774,652,760,299,958,82,319,314,91,74,362,611,55,754,858,564,705,158,30,350,666,587,974,234,216,96,186,507,668,16,425,701,260,237,76,588,696,728,517,558,778,199,511,489,891,995,616,52,208,709,150,232,49,385,507,614,796,103,175,145,780,452,913,261,737,435,249,559,486,820,448,630,54,224,496,890,618,19,618,487,747,215,673,676,536,902,194,263,209,430,746,509,410,678,592,998,335,358,836,245,195,299,993,634,528,761,867,389,89,349,203,878,85,60,902,725,594,532,80,779,379,453,263,186,817,910,629,970,927,855,334,841,130,471,725,169,84,709,423,709,942,505,458,749,925,913,596,831,987,81,825,198,917,968,815,469,854,434,309,740,207,583,640,303,57,416,873,122,825,174,27,761,217,76,704,666,834,154,836,56,36,518,93,784,917,583,587,386,233,634,980,130,203,507,527,272,525,194,510,147,154,398,997,255,941,246,240,671,302,26,347,549,144,451,936,7,209,998,9,498,804,822,455,315,254,488,515,337,581,176,183,396,310,529,250,677,552,230,941,801,834,120,973,927,478,536,52,551,686,67,761,40,690,482,729,162,621,701,56,962,487,842,313,566,520,369,197,51,4,384,40,72,497,427,456,651,603,881,330,640,526,190,439,386,451,41,972,69,291,788,790,658,55,749,156,583,37,400,302,865,79,681,921,828,981,608,631,317,661,813,158,748,777,364,532,611,411,469,918,956,279,130,74,968,536,593,519,72,316,514,370,73,859,971,534,956,73,263,950,897,320,214,187,251,725,363,236,157,509,859,483,611,500,654,476,815,152,836,746,398,918,218,447,964,788,59,835,487,966,159,675,836,895,443,760,765,97,517,629,88,777,460,640,754,108,365,447,565,973,764,860,332,627,828,463,0,469,711,191,793,386,466,766,825,756,546,173,533,543,491,82,308,60,929,404,801,89,123,925,5,949,400,104,274,547,669,455,201,257,478,286,363,964,270,244,658,387,873,614,681,987,951,667,982,746,662,890,939,133,780,392,426,835,580,710,528,448,93,10,644,731,17,543,437,415,788,746,972,747,338,634,288,815,316,498,309,991,871,485,477,820,651,835,130,223,969,209,718,514,833,373,856,141,522,367,135,91,412,629,930,310,876,14,113,641,534,980,977,202,895,674,526,540,525,581,475,82,341,856,106,766,279,457,798,595,392,237,199,27,989,577,863,315,955,819,54,640,763,119,878,96,676,286,880,954,96,449,916,682,387,857,131,45,458,813,161,206,148,965,972,432,879,983,591,621,257,580,141,285,356,438,240,62,868,61,729,350,396,583,763,160,967,119,530,407,783,344,678,194,721,447,695,622,708,786,310,362,986,461,211,763,417,526,231,854,532,557,15,124,232,908,285,667,475,676,804,441,469,129,668,311,379,439,502,191,525,64,604,219,221,838,69,670,671,520,519,880,507,982,176,27,857,117,398,345,588,99,838,445,1,319,958,459,438,262,428,253,615,397,374,822,290,839,847,954,972,520,238,480,244,474,596,767,951,487,106,851,536,966,863,307,332,314,298,792,754,404,823,75,824,183,37,143,728,580,605,54,124,791,997,474,342,341,853,578,784,245,444,417,881,305,313,479,935,689,748,115,940,303,582,679,156,367,133,299,991,952,103,376,679,293,45,2,558,350,974,685,614,671,94,644,789,455,891,677,876,271,708,742,158,656,153,59,368,716,859,115,519,482,425,628,499,47,612,559,444,798,582,982,587,527,802,288,748,565,609,584,874,559,497,480,660,399,314,837,952,492,19,189,297,469,614,76,278,142,561,92,217,326,374,784,586,877,654,856,761,782,359,166,952,970,745,573,266,325,29,249,761,321,436,468,607,382,505,536,539,865,282,516,828,212,3,253,443,129,988,78,714,579,11,180,777,395,522,805,612,297,940,453,958,953,544,713,234,565,762,592,922,246,943,412,829,986,760,599,606,909,185,99,473,876,872,555,161,580,242,825,99,824,533,445,712,192,631,192,536,972,199,91,76,566,839,136,46,457,453,36,683,507,468,183,940,720,426,359,981,413,417,421,539,884,702,232,116,690,742,897,677,160,106,733,920,463,621,416,608,990,696,190,905,492,796,136,482,379", "50,202,588,560,171,367,171,300,88,800,723,442,515,522,585,350,977,830,925,401,320,462,932,509,260,790,662,525,162,789,752,643,168,401,963,929,241,727,903,479,538,799,10,912,34,293,562,795,259,260,223,816,576,566,580,730,681,721,952,503,29,977,812,377,632,846,815,720,571,705,193,675,195,495,905,353,968,573,24,604,219,818,484,353,852,914,210,366,755,339,235,394,518,512,108,12,465,515,396,805,366,912,550,663,315,606,394,915,121,941,930,9,624,512,737,85,36,482,624,120,435,750,293,690,309,582,13,267,388,123,292,682,850,733,672,116,351,749,986,15,552,213,528,265,944,840,789,840,763,809,563,407,47,353,653,876,694,680,534,431,97,786,27,682,141,499,267,317,704,857,722,52,678,89,378,823,563,479,451,703,516,643,170,340,332,375,471,54,464,445,735,295,562,987,552,459,540,656,876,767,89,216,759,108,286,421,142,834,668,204,177,249,651,503,497,831,559,154,385,253,506,778,922,773,687,453,383,384,431,325,881,308,655,870,562,442,375,58,870,782,9,565,547,444,980,72,699,719,612,200,407,308,544,563,842,859,103,313,323,898,141,363,613,146,407,207,124,614,658,606,86,454,499,168,412,749,213,191,162,519,992,430,845,314,411,78,851,623,854,710,712,626,903,548,171,689,427,873,526,18,1000,583,696,861,759,714,989,45,653,939,688,344,943,837,641,936,132,712,877,163,758,357,583,440,424,235,951,741,875,843,235,630,100,557,636,308,179,683,616,623,47,815,294,392,269,894,400,51,989,750,461,839,801,482,489,618,527,744,796,833,420,168,340,83,870,180,674,74,381,770,455,395,632,775,862,517,503,662,4,786,242,298,12,739,202,973,166,414,77,118,434,907,977,694,608,437,232,463,545,942,29,970,581,535,88,237,289,549,353,298,94,80,959,794,972,542,349,402,120,369,5,262,745,156,834,744,730,56,803,467,191,660,757,175,660,465,75,628,572,41,387,251,109,622,539,870,976,966,28,127,795,279,560,525,47,41,616,81,520,399,469,0,39,747,211,339,627,904,519,59,284,727,59,821,368,687,890,189,975,283,695,546,20,50,170,864,608,291,426,676,271,227,83,77,580,111,568,891,259,822,291,447,277,134,273,131,405,355,139,808,253,733,252,198,505,346,859,205,197,749,301,371,547,904,880,680,682,842,596,138,834,497,435,826,218,64,740,3,939,941,411,671,727,47,647,599,416,524,525,846,498,478,677,954,348,936,293,48,439,200,748,86,18,92,743,583,669,616,129,391,628,834,891,353,459,124,876,556,603,968,690,148,862,878,443,607,226,864,114,181,543,731,720,228,448,365,844,114,35,767,882,370,526,186,156,870,804,520,362,57,921,309,155,447,426,290,171,659,693,711,391,254,118,189,405,587,923,519,990,61,695,593,291,724,311,923,920,834,827,645,163,79,900,909,520,936,604,586,190,771,444,649,975,267,961,5,657,340,460,887,830,623,948,476,487,106,850,49,973,4,218,113,212,681,329,823,179,270,18,753,639,454,721,424,832,735,221,794,250,328,349,792,836,600,326,48,154,56,505,645,297,193,847,488,843,701,178,234,435,597,531,553,44,512,170,321,730,195,817,375,655,542,389,226,327,751,180,897,565,453,105,900,193,940,131,973,515,873,771,517,696,472,761,645,863,8,391,200,378,979,17,578,894,720,398,386,16,374,617,269,419,311,723,600,515,766,987,863,39,211,57,202,359,944,407,692,337,239,783,48,369,807,927,18,344,7,966,52,249,619,109,713,61,151,24,886,888,299,350,933,524,631,942,417,153,423,839,532,8,463,995,870,278,94,461,285,846,875,93,93,790,353,442,216,746,794,741,475,443,40,991,620,317,574,84,402,784,149,644,322,190,207,746,738,577,655,263,353,509,160,984,317,790,93,506,781,418,593,869,333,765,642,43,96,16,36,385,753,660,306,826,830,363,108,556,571,628,348,846,690,121,854,976,274,980,859,943,753,14,293,166,141,600,7,389,642,390,438,382,104,553,562,798,376,214,837,74,820,890,10,495,500,87,561,155,121,923,896,628,747,900,634,495,398,924,764,25,144,661,309,505,491,661,269,483,183,885,530,665,179,922,929,852,289,803,361,637,377,348,47,896,195,303,383,746,337,924,4,301,626,836,915,173,627,305,92,991,125,159,663,100,715,571,299,501,260,947,863,938,289,388,341,958,865,262,166,483,834,47,768,333,170,339,920,183,386,511,842,166,666", "746,365,207,208,714,219,439,499,994,164,134,306,692,97,293,713,978,635,298,34,435,854,746,554,59,854,45,52,9,789,404,700,797,183,800,135,446,735,403,778,801,217,132,313,261,459,790,799,207,921,742,721,968,477,804,991,335,368,656,309,525,284,557,606,406,56,444,995,658,780,153,655,726,234,202,748,869,710,634,323,893,245,99,104,560,889,654,139,370,640,226,769,290,580,13,901,369,667,134,231,882,477,173,978,143,772,981,128,531,642,256,292,235,885,636,786,595,826,276,456,148,702,16,968,148,783,797,949,579,112,50,654,881,648,409,846,951,960,344,520,832,102,998,497,738,222,413,187,916,672,862,538,62,271,897,914,394,656,762,825,593,163,533,302,919,258,796,136,874,852,173,590,669,344,146,752,998,883,9,192,503,116,43,26,625,876,11,349,554,923,228,415,34,666,162,295,277,66,501,553,351,401,128,87,126,278,784,483,528,231,564,957,347,476,598,198,205,544,78,241,947,396,799,334,167,381,951,349,569,887,237,257,195,586,112,655,361,627,31,670,545,65,739,677,363,388,649,162,509,526,500,399,986,562,954,937,807,135,18,386,999,789,409,746,506,153,497,638,803,831,794,362,96,596,213,90,995,14,262,958,867,285,603,424,140,720,184,771,438,826,175,981,177,732,934,523,499,842,639,734,459,281,47,910,108,663,168,103,971,15,359,343,886,482,950,521,702,562,22,7,133,44,639,601,743,391,22,944,873,849,498,311,635,3,903,289,49,435,220,708,618,350,690,118,179,785,801,9,768,285,154,871,183,42,654,916,720,552,174,650,984,156,150,182,930,354,984,657,284,921,150,870,449,332,281,712,334,510,844,930,754,472,963,213,241,844,17,692,124,464,242,55,566,893,821,232,725,793,506,549,822,73,186,664,495,298,877,641,887,354,527,75,104,486,282,261,998,321,222,819,716,410,969,828,389,655,863,128,371,39,347,727,453,864,840,448,245,14,381,149,362,288,962,589,67,833,831,639,812,957,517,332,382,892,659,361,105,555,792,354,711,39,0,714,920,7,558,683,258,775,895,208,591,571,581,515,347,473,551,396,797,677,197,445,904,428,347,664,165,154,961,402,652,870,553,404,242,710,270,370,606,628,339,896,318,731,74,861,31,613,411,101,827,369,832,530,656,840,369,618,175,899,669,274,113,95,275,592,581,515,899,98,502,417,702,771,649,185,20,563,766,816,493,856,986,225,98,474,442,221,613,380,770,416,302,993,71,111,147,820,815,709,879,102,726,179,887,962,354,170,80,12,116,889,952,657,638,497,104,992,550,448,583,392,150,225,819,752,470,564,600,366,9,466,214,633,482,763,82,677,759,147,69,29,736,149,249,624,819,600,255,252,23,985,672,141,289,601,195,609,953,485,926,880,396,496,526,247,61,845,387,596,639,209,569,419,685,261,68,356,807,725,260,746,446,359,96,812,455,674,539,172,720,708,827,914,56,611,765,540,815,133,916,617,412,698,136,546,495,817,713,742,946,13,986,156,116,944,881,897,273,817,486,805,659,345,830,700,441,940,261,376,708,329,345,891,901,903,813,466,337,562,276,984,968,393,810,383,686,473,51,635,779,92,582,1,340,800,398,400,794,359,975,200,978,261,831,359,749,324,559,749,667,766,827,697,767,779,449,434,10,287,107,124,507,848,446,845,906,508,258,88,474,87,527,136,658,178,490,457,497,895,7,479,466,83,539,659,593,224,228,207,99,184,53,705,786,34,250,358,444,9,837,64,827,700,292,777,556,551,306,978,688,467,689,434,7,409,598,566,355,71,280,605,898,161,757,580,877,838,224,847,649,391,176,2,31,892,518,580,229,934,258,385,814,383,939,239,449,206,141,447,675,244,912,699,210,10,392,803,779,244,613,807,300,384,621,541,916,123,726,384,179,807,4,214,897,933,807,628,840,902,807,28,249,567,172,442,514,454,914,136,483,306,120,595,706,874,887,96,694,967,508,882,876,388,81,899,750,602,267,197,589,227,585,931,166,665,789,799,610,948,187,222,185,350,890,654,198,774,215,368,59,218,515,961,996,10,76,272,85,381,286,759,797,303,180,217,94,907,669,350,480,369,61,676,839,491,385,828,188,28,605,386,609,581,36,737,555,912,632,925,895,659,188,987,1000,712,574,603,201,320,484,534,291,106,609,346,427,169,713,396,328,941,532,296,670,981,739,978,662,586,250,419,756,928,555,592,422,825,784,810,321,342,409,561,668,545,803,804", "500,277,107,277,685,524,698,717,188,413,382,207,364,160,351,400,439,441,923,932,144,197,422,764,912,895,64,529,117,112,784,396,420,178,255,394,249,600,246,872,243,27,406,456,453,640,139,177,770,918,200,31,528,688,504,96,224,417,548,443,162,921,409,18,769,69,187,78,835,440,857,52,9,623,154,685,632,620,522,722,229,922,418,83,91,201,794,870,587,94,121,156,354,270,150,18,617,978,148,266,347,821,589,120,558,134,925,82,857,472,123,70,321,45,716,864,268,307,449,141,929,844,113,7,292,480,876,9,798,648,929,106,127,367,850,443,389,559,913,25,494,100,809,973,773,992,491,15,979,968,423,344,524,789,97,555,548,63,677,585,955,962,561,234,859,968,559,698,699,486,904,87,416,96,923,363,768,910,542,192,590,816,62,550,372,389,955,937,829,137,691,524,546,739,122,884,422,210,928,373,306,573,908,530,115,608,635,786,873,581,666,362,655,17,836,276,224,495,599,360,277,306,231,574,434,230,743,956,78,228,627,152,266,787,746,466,327,838,389,84,509,342,19,988,411,604,401,592,398,762,642,868,745,373,994,651,732,159,865,689,32,772,62,1,619,607,577,560,420,444,428,397,908,458,63,293,980,7,423,309,463,840,512,752,782,994,107,939,157,991,35,110,824,379,170,686,211,281,760,385,907,650,206,888,963,758,379,181,368,407,201,108,868,92,943,882,246,353,760,326,756,971,870,373,512,21,242,572,44,500,153,224,73,458,399,922,545,487,965,414,186,162,195,283,934,564,66,603,999,975,885,886,454,127,40,792,655,348,747,703,965,265,495,951,924,698,584,347,246,396,594,225,785,423,962,614,701,750,873,877,486,657,782,868,249,358,45,143,441,896,707,206,466,852,694,198,559,923,253,209,983,506,777,768,904,974,312,891,169,11,629,672,473,958,329,443,821,457,172,119,328,552,326,32,628,657,386,856,996,58,875,286,519,115,327,434,708,145,201,364,955,300,774,998,875,552,439,127,886,795,16,434,670,405,918,94,132,988,384,117,191,747,714,0,792,989,530,749,863,444,709,183,825,783,467,631,560,613,89,11,205,821,136,662,48,790,979,222,399,566,221,740,100,505,446,403,674,122,208,340,759,826,729,71,999,91,967,28,669,198,715,199,707,355,673,381,70,364,175,373,881,588,358,122,937,5,989,877,39,946,138,900,349,751,38,5,860,709,904,178,17,957,914,597,407,176,515,494,425,890,305,554,382,785,39,360,603,545,168,872,118,844,211,744,145,356,256,295,368,469,585,166,366,929,859,322,581,541,865,937,157,491,16,205,770,174,181,347,823,753,631,141,94,268,389,811,639,30,787,674,449,721,703,837,488,381,167,313,175,585,880,333,890,981,651,630,921,690,928,64,872,510,816,976,602,875,280,553,600,715,759,835,198,630,500,442,474,288,276,706,167,865,216,336,260,584,833,304,648,615,421,623,952,395,698,294,169,375,475,25,29,890,911,202,328,673,533,107,651,784,501,87,987,50,996,701,479,875,182,77,677,520,88,554,226,244,27,301,416,999,402,122,489,336,239,928,43,526,19,295,768,747,145,721,525,770,168,55,132,389,747,201,566,958,906,450,229,474,716,139,606,358,487,439,952,955,440,585,746,671,688,599,721,718,393,819,691,848,546,996,886,259,777,795,248,780,42,567,145,79,324,976,584,494,999,435,752,612,447,994,585,439,885,56,510,29,967,364,634,23,292,453,59,649,326,45,481,383,617,641,908,173,940,26,511,862,683,880,389,620,83,35,811,391,562,35,575,172,642,766,914,347,676,880,767,952,546,903,28,526,545,348,310,273,707,629,946,81,151,872,763,925,503,232,157,503,245,697,555,978,443,108,311,460,711,670,339,957,71,847,372,460,114,46,368,488,956,42,932,399,526,772,202,292,593,161,543,879,757,800,480,892,661,384,35,68,12,511,230,6,385,592,980,608,983,454,924,676,859,308,715,262,704,560,118,769,147,744,903,786,544,328,962,467,43,924,300,499,471,161,77,983,693,332,999,219,746,422,522,526,607,625,565,51,66,415,618,279,666,517,495,30,295,652,882,899,580,233,905,151,665,205,64,419,24,463,414,133,440,60,709,816,762,21,15,127,960,494,591,896,97,422,389,500,657,738,819,749,780,223,335,106,191,188,232,363,516,996,344,300,963,364,666,98,567,349,40,780,673,370,749,657,506,583,334,889,949,328,906,395,84,880,638,246,850,836,912,720,666,772", "962,556,864,693,820,797,939,614,879,634,672,631,527,951,888,112,471,927,476,152,404,925,584,914,629,686,526,7,948,884,461,510,358,897,569,333,448,288,122,178,198,248,116,894,571,59,564,218,705,457,303,778,375,31,612,713,527,345,140,788,867,576,141,136,676,633,890,725,680,616,976,435,917,866,859,260,667,34,550,412,33,192,501,941,864,686,323,586,843,579,439,457,77,958,714,351,31,322,31,953,185,982,816,939,724,998,772,248,168,981,803,740,150,605,824,950,799,472,175,790,176,853,250,39,270,951,308,59,557,629,694,515,350,881,923,805,835,593,812,325,645,945,739,366,528,798,611,658,532,524,753,186,784,255,791,289,969,622,268,487,69,812,943,214,844,353,434,926,122,321,194,727,139,334,138,239,560,84,287,523,354,840,573,566,33,998,344,991,359,346,938,441,319,578,593,170,228,178,182,190,402,754,844,823,417,523,594,492,258,535,492,277,164,737,431,209,988,840,63,316,616,594,519,877,925,324,803,913,846,935,257,132,54,619,643,438,740,517,927,380,826,615,203,436,217,57,274,969,5,113,575,542,571,176,820,474,84,95,882,112,227,114,577,689,469,75,410,940,981,193,564,562,736,827,232,641,412,468,520,867,583,547,251,339,667,319,563,569,229,772,287,164,615,859,772,796,932,135,738,569,990,111,223,236,143,803,718,726,439,40,252,938,839,370,92,984,307,732,75,519,576,709,672,164,322,939,903,87,824,242,718,589,95,469,981,407,884,230,32,428,911,528,790,232,570,636,481,669,743,213,479,84,351,117,659,339,80,418,434,43,302,527,22,58,171,737,306,794,855,545,571,430,953,795,404,218,658,427,377,526,896,824,264,523,858,129,883,246,766,251,968,854,968,504,555,916,41,98,278,667,551,419,578,672,479,113,520,379,77,980,879,177,222,251,702,174,261,534,426,861,81,356,522,395,783,468,962,221,662,900,81,584,785,21,463,621,676,144,637,486,436,287,3,964,15,691,118,251,493,804,261,300,397,8,453,577,860,681,525,844,793,211,920,792,0,116,10,925,656,766,845,54,895,275,185,59,511,883,491,510,546,79,960,297,20,277,80,947,102,270,224,722,954,499,876,225,814,232,607,999,531,630,782,291,568,537,172,331,609,281,835,553,65,821,760,536,753,427,682,728,349,331,249,205,335,275,243,446,53,896,221,418,10,548,888,935,125,571,24,277,571,648,622,542,533,950,624,195,638,919,679,375,305,686,800,83,967,282,673,735,111,456,794,103,16,215,263,304,164,459,927,94,691,222,464,616,135,166,197,483,911,295,230,204,13,101,930,765,986,313,760,679,184,109,378,501,791,562,41,396,164,202,476,885,922,308,698,869,90,419,327,215,993,892,496,927,45,95,518,344,530,839,311,702,528,407,20,86,650,575,776,41,967,534,130,218,629,286,156,358,299,786,207,168,686,965,639,861,522,254,292,852,525,205,603,996,481,815,99,966,650,544,256,207,437,978,629,154,149,478,785,126,39,617,688,564,449,515,740,360,175,980,245,572,176,504,678,812,323,532,987,666,161,301,649,368,601,426,726,363,451,506,644,61,463,486,4,204,89,417,264,659,11,935,750,314,705,812,811,916,362,225,225,556,168,95,164,484,870,579,365,269,679,196,816,220,353,363,768,419,597,53,243,159,408,63,287,212,175,174,286,613,633,496,662,79,927,53,508,855,553,990,121,115,459,432,857,599,719,824,975,651,632,911,964,40,90,752,428,892,350,793,580,418,322,265,547,488,996,756,371,415,365,178,234,526,920,158,485,817,260,233,472,221,722,761,996,797,447,749,259,572,778,544,162,571,38,244,749,914,894,915,930,151,965,670,695,205,744,416,69,269,760,632,56,236,558,641,234,37,138,993,756,1000,710,111,189,446,903,60,630,558,972,52,968,800,491,125,371,453,874,594,319,851,107,906,999,618,481,239,745,290,926,639,703,7,534,395,947,700,226,309,142,92,206,411,281,603,213,799,259,437,33,919,478,923,254,634,531,645,50,822,916,241,441,288,831,422,427,854,297,164,778,952,921,544,948,144,763,899,268,716,408,931,73,36,175,819,475,917,27,186,696,911,87,978,577,337,678,830,837,742,582,681,416,778,321,321,52,443,155,779,402,862,879,474,954,597,144,457,139,771,382,530,163,185,736,38,540,318,926,388,901,425,295,509,340,187,355,383,543,106,710,20,834,621,180,33,376,652,914,178,398,683,326,777,281,938,82,375", "753,681,34,95,43,253,370,535,432,517,915,274,415,395,129,318,389,38,953,822,987,338,70,372,209,482,967,196,526,340,443,524,764,885,360,397,744,708,387,641,262,521,220,583,922,644,939,194,782,55,956,340,119,62,524,286,780,946,441,639,872,406,984,798,143,334,744,939,407,438,714,219,378,409,582,387,489,540,85,264,553,718,924,575,650,738,619,880,993,356,410,883,530,32,687,522,49,998,433,54,155,280,938,907,267,964,887,350,301,743,13,243,547,772,430,402,225,787,445,682,951,36,277,906,33,642,542,790,934,817,418,380,495,400,108,518,327,685,182,809,254,386,853,345,327,368,112,802,616,207,995,593,86,712,121,264,487,807,99,752,560,874,501,622,597,60,16,195,546,171,805,437,660,828,216,193,206,801,602,210,94,806,659,834,168,803,26,345,95,779,365,687,841,181,650,523,24,400,778,214,217,860,548,649,920,402,147,885,732,952,92,596,862,426,333,395,803,878,558,107,370,866,774,178,130,888,600,773,731,578,981,967,412,246,702,111,115,959,84,863,866,119,250,150,320,19,185,744,55,735,61,808,83,473,127,633,404,999,391,614,107,883,796,487,65,557,937,597,506,400,204,206,353,392,158,440,650,826,414,960,742,201,554,33,104,194,638,772,94,372,167,794,438,292,241,473,478,563,664,921,780,82,649,706,238,754,513,908,471,797,172,567,89,918,483,430,602,219,733,901,612,766,582,304,374,867,995,134,444,79,989,935,971,234,841,206,775,961,408,216,353,279,533,242,775,890,446,574,399,283,788,135,876,347,4,203,759,103,560,518,180,211,712,503,254,853,290,996,829,437,991,681,259,505,498,406,477,323,747,36,796,508,90,18,979,697,719,252,784,386,595,814,632,479,526,935,314,579,774,874,120,689,65,113,393,454,784,562,488,280,894,591,946,497,527,869,536,856,474,657,643,209,119,841,832,349,484,367,365,380,452,969,774,931,849,200,341,254,457,374,258,43,214,148,820,169,5,95,24,576,666,629,645,743,540,772,50,471,36,469,386,339,7,989,116,0,859,526,768,16,714,44,478,780,981,805,815,951,542,928,487,350,238,206,153,111,406,86,812,267,18,799,466,942,579,530,159,128,144,684,989,398,38,782,530,862,919,104,89,702,772,449,347,930,887,539,816,482,494,607,691,141,893,11,440,334,738,496,822,593,63,379,201,984,600,805,594,114,282,953,10,674,63,248,487,269,478,822,693,560,456,950,137,719,265,487,334,234,299,825,657,43,486,254,821,91,848,386,219,729,803,692,919,379,722,327,904,564,647,952,863,614,431,576,321,13,827,701,847,348,694,988,256,146,619,39,462,206,274,186,225,124,247,112,260,770,128,411,685,851,765,854,691,376,541,386,586,309,234,100,104,102,388,258,291,123,592,688,189,759,118,722,507,220,569,485,37,309,518,400,650,500,400,716,519,597,390,469,414,832,328,986,900,250,629,203,787,473,178,796,609,267,495,515,922,161,329,234,189,575,311,867,255,891,993,797,776,652,642,783,329,512,106,840,326,949,731,243,932,544,890,287,172,156,333,413,1000,346,82,855,205,42,899,542,263,168,370,923,970,357,355,885,632,933,228,568,352,377,154,941,41,3,427,11,704,295,481,755,452,252,760,98,979,626,998,940,407,104,217,119,963,293,803,196,727,71,634,70,955,287,785,412,359,294,632,926,542,464,143,912,694,50,363,346,656,775,245,338,255,552,648,684,304,858,750,858,434,170,430,698,577,121,513,463,272,375,104,796,399,89,137,120,728,200,967,450,67,338,919,722,475,333,722,486,291,391,703,421,788,68,599,195,629,359,74,754,159,840,298,700,283,797,315,839,800,971,873,521,524,207,199,807,648,867,119,67,316,466,682,516,367,858,934,802,154,985,806,172,743,453,802,579,200,860,564,778,975,91,74,573,999,811,180,986,137,301,487,299,177,728,198,750,924,603,736,280,381,939,63,491,33,485,290,353,647,679,568,633,648,195,807,192,194,912,329,621,936,183,158,246,886,577,63,638,712,587,254,831,562,9,79,429,532,517,806,173,861,552,42,223,473,247,776,424,701,929,960,731,113,968,987,809,74,478,888,414,98,270,937,973,980,999,131,443,180,537,415,533,379,103,591,432,745,460,119,556,537,1,106,688,263,616,873,461,734,653,956,75,229,725,448,320,170,969,738,100,987,248,54,584,680,563,307,616,513,205,470,493,875,364,450,495,321,153,720,286,1,952,959,714", "547,668,556,928,323,589,711,190,637,524,721,337,155,629,948,692,221,809,666,406,606,777,926,842,943,794,446,461,348,637,894,601,23,803,467,963,985,606,368,577,632,254,845,725,1,23,992,523,581,657,564,463,895,137,417,498,451,346,808,720,383,209,209,138,457,787,165,228,351,920,131,71,817,971,925,273,46,875,154,902,619,169,220,342,105,29,486,625,49,576,663,578,706,399,688,796,34,952,109,947,886,578,448,455,567,936,789,261,30,38,817,491,543,525,434,122,97,749,537,843,366,253,980,921,744,884,672,482,73,191,11,12,808,498,159,992,202,193,806,528,428,305,740,7,479,261,58,313,291,738,516,93,495,561,349,875,466,448,257,710,625,328,979,235,559,277,238,810,380,207,438,226,347,625,197,229,627,827,127,24,140,320,916,782,189,99,447,724,913,411,407,512,263,278,914,790,667,94,21,672,448,329,313,295,522,559,461,194,933,745,886,814,857,775,625,322,155,55,660,233,433,591,73,272,830,20,517,937,557,815,852,771,152,915,919,534,265,125,977,916,631,460,718,887,48,8,59,925,589,110,152,130,455,759,131,595,184,353,907,896,186,102,360,687,948,623,791,677,284,275,581,904,860,321,65,188,613,97,573,878,801,156,975,371,385,817,692,70,663,272,712,772,132,711,99,983,80,672,763,953,806,816,754,675,502,985,343,435,965,426,787,694,567,365,32,19,170,889,633,547,404,481,871,301,359,773,910,295,121,38,376,662,793,605,786,268,973,372,72,304,854,920,511,100,442,233,246,334,75,103,126,812,634,969,448,489,165,338,829,379,201,325,473,857,376,574,81,963,260,430,578,599,48,106,819,64,95,453,125,257,515,771,280,997,237,825,711,838,276,644,950,14,349,131,540,92,440,955,800,35,290,791,408,900,792,280,955,186,374,936,326,484,41,2,88,845,506,283,221,719,109,238,396,525,310,850,259,724,710,85,772,868,510,883,996,767,608,626,510,856,532,973,349,392,426,900,623,334,693,632,483,644,809,912,633,163,271,985,666,786,466,627,558,530,10,859,0,577,478,76,268,269,377,982,383,699,418,231,263,107,505,336,260,177,555,428,973,270,901,911,90,82,252,553,366,155,647,44,492,966,59,221,331,838,335,713,226,431,720,131,97,650,476,15,335,454,553,251,370,202,928,801,337,875,454,80,5,707,746,346,844,642,107,893,42,42,507,714,273,398,232,274,819,633,617,423,164,839,774,344,81,890,249,783,396,903,12,794,103,867,424,11,76,296,432,566,704,297,230,676,872,720,408,606,759,89,32,23,113,524,868,912,317,464,94,639,560,102,375,388,675,578,833,434,857,599,88,779,602,611,746,224,28,434,525,890,632,832,397,399,811,660,431,6,723,257,47,277,222,178,488,860,895,948,619,372,317,675,384,753,56,750,212,9,527,780,268,656,105,490,92,613,907,569,286,280,233,886,862,109,121,982,402,252,24,799,501,387,127,122,526,988,584,250,692,497,294,726,974,806,809,997,813,254,326,22,328,297,538,656,352,867,265,385,638,877,204,353,743,541,208,394,274,656,810,111,987,105,152,34,892,72,296,911,595,375,891,140,250,941,307,156,963,827,781,243,105,965,700,292,659,361,164,87,8,710,397,553,994,986,941,980,666,663,275,418,474,375,468,996,794,215,81,21,35,925,873,380,476,231,128,296,432,679,918,408,509,328,823,287,142,836,933,741,988,484,503,444,96,397,366,484,235,407,88,228,88,842,362,140,820,576,880,185,429,233,126,939,581,472,543,369,209,428,299,543,828,454,627,428,440,652,828,752,273,242,294,41,303,187,252,204,696,137,891,481,71,775,560,771,946,415,60,62,324,22,813,604,283,433,561,149,358,280,586,52,793,783,954,590,407,104,26,787,411,654,35,11,812,628,492,324,251,955,302,752,800,604,358,374,911,790,306,607,714,678,527,342,171,850,292,326,965,711,283,209,478,723,561,949,436,690,967,645,726,387,61,491,50,582,347,386,405,717,945,67,620,899,132,745,761,560,23,878,164,639,623,433,663,298,586,517,253,820,828,366,419,114,543,187,454,70,800,704,986,744,3,347,387,945,171,226,121,389,921,155,518,667,166,478,885,884,262,185,882,893,309,236,622,843,638,399,678,959,91,184,175,902,724,873,488,159,352,39,38,753,331,219,205,271,478,390,415,300,515,497,106,669,40,919,201,507,401,483,768,897,485,849,901,569,85,751,183,506,944,377,874,226,925,64", "889,350,490,461,800,699,482,302,23,198,762,130,801,62,469,181,301,540,549,720,591,366,544,654,654,835,564,174,979,958,53,48,404,772,194,370,335,387,481,525,714,144,217,875,828,176,803,432,702,810,698,689,635,835,664,142,952,459,420,866,738,734,434,747,75,22,660,23,763,841,756,195,653,517,681,658,830,260,215,370,37,944,980,821,475,575,441,874,387,315,456,161,89,124,356,397,440,667,947,888,366,857,832,493,70,703,319,141,681,241,993,507,109,456,224,563,650,131,460,343,176,699,550,316,234,626,601,193,26,458,664,395,762,59,759,476,273,806,470,480,592,907,784,588,965,367,818,729,813,576,360,737,998,323,500,585,842,889,122,854,427,850,958,67,154,658,977,381,906,62,495,476,767,839,615,581,386,12,52,86,434,328,36,502,932,515,930,580,661,753,493,662,315,711,833,844,109,513,414,504,497,416,357,177,243,212,455,512,975,260,720,402,946,677,821,210,667,112,354,809,637,851,139,69,944,670,833,983,980,122,911,613,449,722,745,582,857,77,877,796,502,766,902,884,57,401,329,604,499,944,496,780,774,204,802,837,827,97,646,686,323,929,823,254,770,170,60,332,118,103,847,385,197,192,835,517,484,447,634,343,552,256,152,754,385,179,136,342,913,486,633,218,767,762,430,917,923,660,75,468,546,268,513,937,415,297,970,309,792,555,499,451,603,163,976,621,764,117,634,385,144,208,81,174,955,400,76,851,966,345,268,331,378,876,394,25,751,403,801,198,967,743,931,838,803,98,622,12,113,275,492,672,740,181,622,205,17,55,654,279,401,646,246,643,580,181,984,818,24,366,510,763,836,993,118,829,636,775,975,167,590,912,51,920,726,117,525,191,74,48,397,986,342,640,226,927,540,25,424,507,938,258,975,338,746,533,827,86,949,275,646,913,230,668,196,195,993,804,243,264,407,491,179,803,642,534,745,527,671,798,676,564,644,280,624,477,541,983,514,594,837,998,873,170,248,342,562,987,302,933,922,500,206,319,256,166,848,660,632,528,766,904,683,749,925,526,577,0,947,743,529,765,944,868,94,709,348,94,819,17,444,556,719,421,492,360,517,759,301,529,635,162,963,840,868,104,62,606,521,283,839,122,522,577,252,879,596,680,210,876,858,833,271,555,135,687,823,511,610,673,97,456,161,149,76,404,561,923,818,626,681,800,380,937,697,520,443,942,403,376,366,965,241,495,891,675,300,141,87,639,246,298,158,274,108,936,743,224,781,263,472,383,514,967,17,960,485,171,638,270,44,6,661,833,711,396,112,843,510,343,808,197,461,559,500,179,337,809,945,852,676,470,293,641,812,161,553,74,451,665,906,376,559,904,277,135,590,340,773,269,471,880,898,104,568,925,513,601,159,952,350,856,694,464,238,745,988,365,701,535,435,892,125,76,582,69,152,91,83,903,705,28,507,444,44,20,904,174,426,346,235,474,90,591,120,23,406,222,156,481,488,360,169,663,566,907,50,102,255,852,848,823,653,10,152,88,487,446,525,739,181,683,412,415,2,368,438,899,120,624,840,560,607,258,546,260,796,428,987,998,740,918,627,769,579,616,743,72,869,173,194,921,704,763,501,163,36,390,998,50,616,39,646,189,362,664,830,393,907,651,633,470,333,251,3,23,439,611,271,853,39,880,719,553,334,442,863,125,875,58,426,549,375,711,61,469,147,241,642,786,479,662,658,434,317,271,431,859,950,149,312,676,228,521,389,968,953,924,935,327,430,163,303,422,550,270,285,436,261,990,264,575,633,186,444,782,371,482,151,980,839,486,288,840,908,277,835,856,573,285,511,797,435,710,386,680,724,108,396,160,286,894,281,572,180,223,653,644,509,111,888,666,494,424,701,577,628,847,716,833,593,262,571,129,762,606,298,646,202,20,311,768,867,412,212,39,160,568,489,471,291,339,221,322,609,690,749,205,984,462,408,699,463,568,168,632,504,695,372,982,770,927,240,97,970,712,72,796,1000,205,321,835,377,275,47,215,331,890,972,190,776,858,211,994,659,831,32,801,630,594,191,282,715,761,69,677,968,106,245,451,307,208,352,154,101,26,101,346,509,1,751,902,753,42,168,392,320,426,877,920,819,854,797,722,355,364,868,828,250,827,895,901,703,467,725,622,494,159,348,515,560,642,349,531,630,683,142,526,615,830,979,612,829,767,836,818,700,819,659,766,161,392,45,384,365,126,312,420,333,655,102,898,572,111,233,562,126,135,990,75", "199,496,890,747,535,340,106,770,527,33,488,265,586,957,477,95,623,66,104,785,322,624,319,824,154,999,530,612,107,394,696,269,17,334,798,311,303,200,4,846,824,88,729,878,775,109,684,823,250,269,819,748,371,178,53,794,945,87,558,62,32,727,234,857,890,610,112,82,650,317,148,995,805,157,481,745,321,217,317,902,872,852,219,687,355,601,105,835,708,686,175,148,992,383,720,510,325,269,251,758,930,321,767,97,31,468,648,702,858,177,496,354,834,102,97,668,957,372,328,603,572,367,462,227,437,624,152,104,937,378,699,984,661,189,107,919,818,40,824,264,191,606,290,734,207,80,711,261,854,374,713,234,571,248,798,200,151,735,738,684,23,469,553,467,584,190,637,363,709,949,695,479,687,725,205,271,811,714,965,688,790,254,121,99,383,873,482,563,410,216,171,53,224,374,790,882,426,670,187,104,767,168,70,778,632,134,13,302,932,170,866,993,186,146,29,770,283,114,946,776,953,824,677,678,425,110,475,979,203,961,699,817,19,848,561,916,195,984,509,627,359,552,966,697,338,613,770,509,330,910,639,552,693,302,535,446,712,843,201,361,915,726,737,868,708,715,981,43,721,4,630,251,28,897,647,551,604,74,118,504,458,992,270,700,98,465,847,592,898,227,41,915,651,415,476,583,658,209,830,727,280,778,492,924,610,118,998,72,227,29,284,344,253,739,784,827,748,271,227,722,681,591,190,240,284,244,674,626,369,178,864,592,62,833,834,385,79,954,850,263,483,260,536,761,716,631,826,847,209,888,845,281,78,897,568,999,372,271,835,614,985,177,247,252,701,844,579,634,970,384,57,725,395,438,276,216,419,354,722,621,30,681,749,949,90,124,317,401,320,289,592,311,508,190,965,2,987,845,772,323,421,21,56,72,348,109,701,37,1000,851,642,633,457,69,423,794,342,261,52,733,922,410,725,616,416,507,914,435,255,162,361,899,921,686,179,865,181,733,180,313,837,22,995,325,112,189,499,822,884,72,19,160,682,725,108,673,235,925,30,801,825,519,258,863,656,768,478,947,0,343,506,891,981,618,911,48,682,195,440,72,421,813,331,208,410,209,280,995,265,285,58,331,908,137,304,45,422,763,32,852,473,492,924,371,706,212,518,72,950,536,531,24,608,832,541,572,742,748,377,93,796,889,31,107,487,7,180,376,981,33,873,329,678,99,269,401,476,888,328,667,629,26,921,413,825,512,127,800,79,849,717,281,957,169,679,889,142,421,280,601,900,537,340,243,978,156,952,556,267,124,728,866,824,493,187,994,140,109,135,784,854,869,257,203,561,886,34,849,474,377,852,244,368,393,81,829,178,7,817,453,286,505,667,303,153,936,548,203,630,430,375,157,146,324,715,259,597,614,929,339,112,7,155,423,789,366,491,435,205,484,321,832,978,754,41,91,979,75,883,377,676,720,666,816,770,828,332,504,910,134,737,459,400,455,829,945,434,791,125,14,570,128,660,341,986,592,630,916,392,860,428,829,333,373,570,347,847,208,855,785,716,867,561,66,523,26,406,918,409,922,158,347,429,565,715,527,614,239,126,92,41,189,261,138,859,927,104,126,13,701,466,473,839,896,736,532,589,211,97,52,361,274,619,201,634,233,646,640,718,404,218,43,844,494,366,356,109,991,613,861,884,488,457,291,190,628,604,176,809,378,824,602,454,569,800,944,854,718,779,662,181,460,641,72,146,705,834,651,684,815,70,59,492,336,954,650,489,653,414,936,359,539,729,512,772,579,389,812,411,643,637,518,629,647,858,526,278,723,794,290,894,72,143,830,352,549,982,291,698,678,607,147,128,304,365,135,260,425,902,700,744,463,506,597,302,259,4,772,982,463,782,323,969,222,71,202,829,650,751,997,411,342,601,168,886,974,672,582,86,750,844,689,700,411,983,608,672,635,192,267,814,808,733,775,733,518,509,981,519,90,990,634,553,780,383,182,729,625,148,279,656,703,396,640,424,977,568,764,625,91,712,268,42,565,656,797,429,90,887,341,103,585,380,519,900,266,105,567,726,547,592,813,845,957,846,647,44,932,699,638,313,417,599,184,110,947,23,669,423,152,311,371,731,929,718,376,355,516,70,855,116,210,548,444,520,886,71,704,45,157,113,239,662,164,175,622,318,299,914,8,953,130,364,135,490,650,397,898,672,97,254,259,406,985,709,765,769,281,349,312,387,11,828,194,597,891,430,297,982,909,994,493,630,14,7,135,966,51,646,905", "743,113,874,762,249,421,925,874,699,193,497,246,939,688,650,30,159,72,629,98,985,299,265,427,52,120,4,561,932,433,550,598,872,154,769,254,997,244,185,293,679,586,181,412,464,381,149,138,521,104,794,587,165,106,597,979,620,379,18,748,37,987,955,925,192,814,910,379,177,717,793,455,273,808,530,353,212,304,143,69,846,786,983,809,566,65,164,597,626,679,112,196,813,986,281,823,377,429,629,100,417,239,606,515,829,807,372,184,513,554,635,935,9,946,570,465,125,794,703,810,504,483,823,413,184,449,853,72,38,110,651,323,177,700,964,172,60,143,244,251,883,108,527,408,815,385,658,830,918,21,947,299,144,987,524,331,439,959,832,878,290,594,180,934,760,755,861,158,984,81,176,83,561,43,863,860,395,832,663,808,528,497,53,629,782,317,612,668,529,497,45,953,932,95,271,886,198,326,151,119,255,623,6,398,387,164,960,221,446,113,67,123,395,283,25,152,523,786,799,461,418,844,70,215,636,827,949,255,917,322,629,959,897,424,955,508,12,107,523,396,543,384,53,21,728,317,33,266,658,277,423,432,791,377,768,657,889,940,500,438,705,509,77,801,225,771,100,664,540,370,844,455,2,263,505,900,320,883,583,320,500,566,310,980,594,410,164,903,304,698,670,943,464,787,839,198,268,906,391,949,853,143,540,18,15,478,631,502,914,699,601,992,4,949,423,275,755,719,248,59,618,545,418,198,194,186,124,628,896,530,320,888,579,583,187,683,923,874,543,164,362,878,689,17,963,768,655,383,762,283,223,704,6,851,176,39,609,797,81,513,326,460,106,723,345,233,946,735,534,428,868,524,974,214,829,245,359,566,705,407,647,894,778,150,497,361,928,238,655,211,875,822,647,455,300,821,105,68,745,999,226,568,424,444,734,419,721,674,739,707,491,715,472,137,34,268,786,379,706,148,791,506,146,803,207,352,474,217,855,588,263,893,463,170,42,192,471,326,586,117,391,345,202,577,508,387,427,368,690,205,904,842,790,237,827,532,266,16,364,380,756,59,775,444,766,16,76,743,343,0,635,162,631,364,981,807,184,84,881,389,515,200,852,55,446,713,607,865,762,539,277,236,438,274,940,459,996,248,182,318,555,739,590,302,118,469,759,454,37,267,531,572,630,43,432,94,383,136,828,678,708,568,383,199,662,241,395,979,589,936,830,573,921,961,997,613,448,76,689,657,232,57,175,625,266,235,178,468,799,447,268,981,187,632,454,153,204,949,891,247,579,428,31,425,525,516,650,701,219,563,825,467,278,49,473,320,608,605,576,369,918,251,279,269,248,566,969,538,567,690,195,472,942,751,814,921,653,825,591,985,81,569,484,930,310,295,584,530,320,979,235,191,197,859,555,109,114,349,288,375,228,582,787,433,30,795,784,583,524,905,438,780,240,847,853,645,796,775,131,625,780,227,788,894,490,661,368,429,98,319,698,688,906,137,215,242,154,532,13,663,710,553,773,436,746,104,195,294,416,760,453,686,701,830,157,189,684,441,113,718,671,412,551,711,670,62,470,219,502,866,182,431,144,918,686,865,610,702,58,481,172,567,720,130,295,484,737,497,85,647,910,997,927,907,5,9,158,75,823,579,669,990,778,443,462,58,368,151,906,666,208,424,904,866,630,901,869,501,472,35,370,903,834,665,318,126,388,247,916,957,200,925,797,606,160,72,595,941,75,915,754,894,547,74,836,183,211,463,34,957,427,319,7,463,277,415,600,970,536,814,331,153,245,965,794,438,80,937,90,574,344,750,813,795,20,835,985,455,583,915,220,354,208,407,803,545,870,591,477,843,418,933,909,732,270,708,483,732,274,94,463,960,190,285,310,887,239,438,106,47,500,546,788,932,719,171,141,201,361,811,986,809,139,406,535,251,819,889,368,128,345,738,205,216,19,576,902,674,233,968,977,836,129,509,47,856,422,735,439,494,420,96,932,520,81,778,713,456,382,412,630,26,75,923,296,188,954,63,469,576,639,858,803,269,214,898,351,185,698,122,364,449,416,664,56,905,225,115,512,266,981,887,400,663,240,162,189,249,93,241,213,549,703,367,516,166,106,117,333,343,872,643,146,511,816,779,77,928,599,10,814,712,77,685,264,330,660,170,639,748,830,360,22,837,944,983,418,534,136,569,728,29,550,50,826,799,303,391,277,457,466,885,976,747,864,663,416,34,468,408,987,266,355,106,330,114,298,731,296,626,398,303,232,568,250,498,512,256,210,710", "611,14,642,718,92,192,562,740,195,514,103,287,529,78,898,620,423,236,185,476,74,708,498,625,351,18,552,1,406,184,835,445,874,355,957,271,173,484,535,37,898,544,825,54,68,43,474,370,6,533,698,899,7,618,606,653,158,404,415,583,814,425,788,683,73,682,713,685,282,464,621,153,585,399,75,632,796,549,523,533,282,92,895,522,369,447,64,717,146,841,934,93,852,412,692,36,651,86,558,37,631,503,641,801,710,491,371,611,290,613,373,75,11,950,86,890,735,189,55,116,747,316,86,184,759,690,953,456,9,98,805,850,241,914,123,299,403,719,282,729,692,945,506,631,415,725,922,838,200,610,257,97,44,593,370,849,2,956,350,201,47,693,805,478,856,821,40,502,461,515,617,956,11,65,862,208,486,855,298,601,917,600,619,75,523,848,148,982,586,426,944,965,19,883,343,782,218,898,163,774,48,77,965,916,725,654,717,359,466,685,635,287,164,990,412,783,913,225,147,939,979,582,312,996,755,636,4,700,379,577,844,106,32,47,741,790,578,966,251,61,63,617,552,320,219,77,996,736,532,51,687,840,150,332,990,887,912,998,312,80,741,715,729,126,388,930,815,626,970,815,416,518,401,135,546,560,988,796,614,323,413,616,248,377,923,393,918,92,271,135,701,186,428,270,746,979,871,950,635,395,973,884,296,816,361,165,214,513,82,924,64,873,71,258,881,231,289,354,648,235,971,612,142,634,383,391,562,432,916,933,698,157,659,678,438,509,157,409,949,740,937,128,264,138,793,397,847,906,595,567,262,236,652,635,386,416,465,915,608,93,277,835,138,699,348,666,380,893,85,604,921,419,979,280,25,267,408,247,168,979,333,250,920,333,755,950,203,623,436,528,84,764,45,924,53,800,97,171,212,23,487,260,106,964,107,524,821,462,636,790,112,659,637,323,613,778,418,332,388,732,938,845,390,161,425,909,565,747,702,712,569,43,373,607,71,170,662,626,593,152,150,871,254,997,615,33,683,828,225,952,611,464,176,924,54,925,123,590,405,773,546,284,895,709,845,714,268,529,506,635,0,616,765,740,224,285,898,13,80,845,991,309,21,683,851,547,371,642,93,958,146,727,638,874,760,888,1,374,926,569,407,369,102,617,785,928,604,969,58,26,472,207,761,151,513,251,139,763,350,612,136,597,14,746,22,851,657,835,303,985,334,613,314,326,404,809,38,243,522,620,919,873,544,402,747,655,406,595,263,484,816,603,64,116,680,630,112,979,845,274,727,600,9,537,601,496,147,449,245,813,636,859,819,747,353,404,843,34,898,68,847,798,56,636,664,377,303,338,320,715,99,887,800,421,61,604,530,771,49,638,766,148,302,649,130,273,558,129,967,787,192,617,986,771,727,588,85,901,13,862,344,939,161,527,856,244,51,439,402,646,450,117,484,987,532,363,750,171,933,514,523,73,316,643,984,611,78,219,803,735,352,49,93,87,987,823,462,850,791,39,123,489,77,247,601,421,446,761,906,605,854,321,13,763,147,892,182,338,751,782,913,611,87,372,421,244,429,564,633,172,325,270,6,238,885,715,682,591,808,459,223,44,714,178,299,140,93,216,283,387,665,338,145,342,392,465,863,768,589,359,914,444,503,33,956,124,920,132,554,586,91,973,933,90,937,453,876,163,54,644,921,276,533,821,824,967,358,889,512,574,189,619,255,669,397,884,502,6,384,782,151,663,254,555,766,22,708,613,1,411,847,587,436,41,254,718,986,383,641,26,2,122,433,663,753,9,792,524,275,260,371,885,848,859,611,774,54,560,338,870,550,254,789,412,243,623,271,349,289,529,825,248,511,587,724,656,349,742,914,209,911,789,94,691,952,480,257,283,93,612,790,773,629,288,886,217,343,422,989,38,926,132,37,584,696,356,831,99,813,50,188,971,452,910,59,701,383,499,10,325,858,770,705,273,628,833,848,121,443,587,162,541,149,619,696,91,42,524,881,447,878,933,560,295,953,178,704,891,625,403,404,520,863,148,573,74,556,186,116,628,780,401,797,233,536,862,364,854,888,569,832,470,857,612,283,292,934,496,417,44,266,753,480,210,488,217,145,915,799,958,884,310,353,149,269,706,723,224,282,3,909,511,410,559,231,822,80,622,667,541,994,250,903,26,698,79,23,750,228,325,255,726,97,606,939,923,749,718,11,838,606,836,729,238,324,433,561,312,55,744,67,284,352,321,569,510,674,21,531,388,794,334,737,907,266,709,780,316,630,621", "357,914,256,635,178,999,341,459,214,909,69,983,88,299,983,46,780,558,153,542,387,523,326,808,411,160,170,415,107,443,310,496,459,42,986,885,520,923,625,19,166,609,315,145,332,142,404,868,784,883,173,816,31,901,624,273,654,787,906,505,833,846,916,465,548,504,96,637,413,184,753,77,650,58,277,196,808,224,816,653,971,33,137,143,51,604,99,198,30,819,977,971,18,959,747,207,530,214,521,282,424,885,415,236,144,411,345,701,785,370,939,993,660,794,150,176,411,47,36,535,132,655,840,799,555,289,403,796,214,255,720,479,963,217,579,434,106,956,661,787,856,991,451,395,656,305,351,278,631,439,228,608,611,765,672,969,242,886,161,122,621,674,299,604,811,353,667,682,296,893,783,366,363,438,95,856,624,42,521,851,212,501,154,402,728,358,842,256,767,681,513,370,136,409,356,304,194,590,73,941,741,775,854,105,174,358,576,34,165,744,532,298,220,984,586,116,670,755,268,800,797,550,254,307,154,316,990,291,568,201,336,170,98,33,825,452,461,380,481,943,947,971,633,30,550,917,556,750,239,545,309,23,778,370,887,266,125,505,93,323,74,319,448,726,480,265,332,645,602,475,435,849,183,244,224,511,564,125,263,582,965,911,313,825,502,473,972,353,839,581,938,419,993,536,731,807,366,3,339,5,642,823,436,550,549,781,61,851,299,239,128,81,293,74,763,190,530,885,907,535,381,536,976,543,257,582,679,688,640,815,996,343,76,678,36,913,951,56,353,118,47,442,84,715,32,732,304,604,123,785,453,237,605,990,232,397,559,66,772,613,304,440,35,348,834,666,934,315,765,870,568,249,375,11,562,738,628,941,505,489,711,249,84,236,351,883,641,884,113,273,578,962,210,524,554,188,640,696,856,598,959,232,87,655,377,947,311,3,170,844,599,804,429,807,537,625,911,545,693,447,508,129,225,485,732,225,155,26,86,204,879,455,309,83,418,136,925,970,967,169,702,950,735,727,518,116,869,305,480,678,37,507,546,864,320,879,297,380,463,195,173,727,208,183,54,44,269,765,891,162,616,0,237,302,501,367,799,838,100,874,331,690,888,265,371,518,630,712,980,505,334,429,787,7,139,476,793,682,618,567,938,80,975,905,665,605,374,690,301,671,260,653,496,504,1000,486,618,927,161,391,352,609,646,409,216,248,451,704,983,215,995,821,342,249,98,372,997,321,614,291,495,442,948,284,409,477,159,26,227,743,263,967,763,638,889,595,647,574,333,903,621,923,731,684,734,620,562,88,515,276,861,450,376,17,468,783,664,484,814,866,534,318,13,701,12,38,711,72,144,995,628,18,906,473,638,369,8,367,92,348,419,593,128,449,700,247,974,864,461,506,622,179,532,892,865,476,816,338,376,490,906,228,557,218,893,402,918,657,329,351,182,111,517,864,726,109,694,384,836,978,548,233,484,139,80,742,52,433,628,893,57,408,372,691,877,192,903,540,149,437,759,429,787,407,649,110,881,993,904,694,378,998,94,877,215,537,138,97,994,926,156,706,278,257,231,662,86,641,304,776,467,174,866,261,872,726,572,105,949,331,174,602,728,702,515,827,958,466,910,518,262,295,514,999,878,282,663,532,74,451,690,523,734,308,822,499,663,451,8,302,552,88,912,72,384,994,100,753,331,51,693,102,407,586,946,256,611,491,176,50,557,489,57,960,793,714,777,561,983,5,128,36,413,683,831,557,78,875,154,382,74,239,747,644,287,220,510,340,481,731,321,723,606,245,94,722,104,416,571,831,975,51,798,460,890,979,100,980,853,633,803,788,841,204,635,264,751,223,744,424,426,484,245,332,883,425,698,728,291,114,982,842,817,439,796,147,606,156,909,757,183,897,730,934,800,113,715,420,315,636,346,689,940,865,38,823,761,878,353,231,138,185,702,371,214,697,545,548,487,991,838,939,765,870,91,602,684,470,859,384,974,860,465,581,380,390,885,768,772,934,674,950,284,709,26,136,224,328,236,992,773,923,268,556,448,63,409,634,611,572,743,31,330,313,538,825,595,989,118,356,153,124,834,8,782,748,17,369,289,467,543,621,114,773,57,101,970,337,251,784,792,181,569,287,980,628,816,50,460,719,29,601,986,976,713,150,722,680,555,49,938,74,528,827,184,348,712,412,1000,567,361,907,961,236,642,668,795,531,661,938,479,800,102,133,170,464,183,511,113,678,495,390,452,967,729,19,665,111,438,934,806,554,561,623,945,770,728,245,164,839", "952,813,945,225,146,53,529,430,941,285,325,457,612,668,178,124,892,893,355,830,939,754,449,231,660,274,169,182,59,901,291,37,499,231,759,520,10,732,827,351,705,552,937,826,874,36,159,806,18,851,583,666,805,515,549,978,749,650,194,851,489,131,137,529,574,312,832,264,516,808,921,288,53,910,767,729,797,467,395,454,7,861,173,422,427,513,652,480,89,758,717,524,976,930,947,223,174,52,94,149,185,651,679,474,341,840,468,876,814,674,83,993,763,76,976,289,810,93,515,412,354,647,799,550,573,895,63,152,360,452,787,847,480,544,277,374,962,71,583,733,72,881,974,888,991,554,477,230,4,590,402,947,907,536,502,257,904,117,665,847,41,532,65,557,963,328,434,725,822,239,141,684,223,229,744,530,217,379,742,133,304,379,692,69,517,741,902,282,468,23,807,171,972,151,346,154,349,791,964,182,349,101,562,287,267,977,966,396,693,804,109,216,183,183,319,515,361,618,782,828,139,149,878,469,186,529,718,831,385,550,516,551,891,219,414,331,4,434,909,160,426,49,365,824,892,622,237,405,980,419,317,514,645,44,430,172,906,857,94,699,199,800,407,525,363,585,409,595,941,572,406,269,162,619,792,442,621,772,715,740,805,469,51,174,397,665,347,291,185,527,929,974,769,631,169,614,249,826,98,613,222,336,121,572,782,738,198,863,56,295,918,80,845,384,237,409,925,432,253,518,121,168,545,74,418,727,304,162,245,425,213,28,48,388,629,763,189,858,496,553,22,720,605,224,623,107,468,875,49,732,594,823,964,551,816,492,134,546,330,161,509,996,310,548,480,319,126,585,391,365,893,23,550,74,685,772,343,427,767,998,259,815,409,84,358,529,855,600,785,999,444,169,388,521,721,935,465,90,217,947,293,546,223,40,971,644,788,30,739,878,733,950,874,178,46,471,178,881,825,943,500,898,18,855,717,177,196,304,251,409,403,301,80,356,923,577,131,790,580,764,218,251,743,359,180,410,77,165,750,383,974,998,976,407,981,37,1,183,562,205,533,59,591,825,895,478,377,944,981,631,765,237,0,418,214,446,129,919,203,104,9,99,705,75,687,476,184,184,46,513,254,460,609,82,70,293,526,596,109,55,98,377,273,557,311,111,84,316,763,862,729,886,748,789,340,133,979,541,68,94,281,838,98,500,60,343,416,219,666,38,58,211,879,138,479,23,563,290,735,40,162,826,898,333,294,432,612,751,476,103,354,920,709,871,57,411,399,228,11,147,73,854,574,692,237,239,553,632,94,977,906,101,392,726,246,218,957,553,478,820,302,200,411,377,901,433,330,861,417,165,115,883,893,674,17,227,961,168,908,973,786,621,512,935,527,607,501,722,777,862,722,120,410,655,183,925,255,571,616,446,76,922,98,401,727,115,968,272,138,486,100,570,187,947,107,897,168,229,959,277,51,570,961,177,778,284,978,942,419,232,24,818,992,675,538,783,585,148,968,12,680,386,477,275,170,847,927,532,684,756,869,857,805,613,737,14,456,960,2,278,347,72,171,264,722,630,170,972,541,909,122,274,574,818,891,734,134,892,764,458,799,95,97,922,894,182,872,818,63,527,800,894,873,545,78,266,94,996,405,384,488,165,129,194,779,878,468,765,587,922,385,212,328,906,400,934,770,208,665,196,661,350,919,465,194,809,399,223,267,686,572,152,84,7,843,336,973,114,687,464,880,242,368,791,13,623,994,562,240,186,971,783,426,822,519,933,810,454,172,896,583,291,488,253,241,117,341,713,479,679,414,247,571,126,359,374,745,811,773,920,224,298,254,175,607,199,797,644,805,386,577,651,31,303,715,191,85,522,203,700,613,193,838,232,656,95,414,568,277,662,36,234,288,51,499,500,372,465,556,916,642,471,448,589,757,913,260,997,667,559,29,20,906,938,374,34,8,808,642,556,498,269,657,783,705,70,344,752,999,401,503,598,277,861,642,664,706,975,98,968,376,433,676,806,450,234,353,866,770,979,228,157,460,55,501,277,34,241,43,587,735,594,900,592,856,153,34,599,211,83,334,16,984,869,659,733,950,713,913,847,130,500,738,335,396,299,924,62,990,15,283,689,30,399,82,592,618,77,712,762,136,91,358,361,957,121,198,573,474,307,455,786,943,348,81,275,738,707,85,615,183,582,881,354,837,792,807,690,951,683,854,275,792,434,461,497,722,166,463,857,914,517,830,860,952,997,370,891,716,472,578,727,988,327,267,555,722,96,842,758", "781,974,701,458,125,339,829,217,756,608,282,568,731,803,465,840,408,515,701,807,660,986,507,168,642,855,408,129,861,821,704,279,624,463,257,301,881,80,837,7,380,938,518,114,174,542,63,193,893,944,358,986,51,890,645,806,643,334,365,376,788,253,739,739,815,581,409,57,159,290,100,447,604,741,19,903,308,864,802,655,309,85,470,726,71,300,745,324,617,568,844,805,336,220,37,971,162,805,219,220,240,336,449,5,198,269,373,190,547,322,845,719,156,917,300,554,115,760,115,438,359,764,714,311,628,707,451,872,55,744,846,621,211,869,104,397,892,359,372,484,952,934,87,615,732,123,422,4,437,983,633,182,815,489,870,776,180,897,600,960,592,549,25,111,227,679,92,203,595,708,334,474,489,147,552,170,303,663,378,615,12,589,564,156,774,391,937,460,438,380,803,65,816,210,269,740,101,618,449,305,839,727,20,710,102,440,376,957,279,154,590,782,332,784,519,467,256,401,643,671,374,898,390,26,754,187,861,738,388,162,935,10,939,601,271,654,870,806,301,865,207,133,913,5,854,42,557,160,633,185,380,483,768,18,523,952,156,197,596,312,550,251,152,494,77,722,63,999,944,615,626,627,233,811,189,702,831,166,264,737,828,445,745,845,122,382,955,824,272,335,75,326,77,44,519,924,995,689,324,758,336,103,773,592,214,596,838,38,589,601,283,496,245,312,142,417,735,726,508,802,859,153,963,319,164,746,503,400,451,454,684,942,552,607,722,608,700,68,512,79,341,821,327,814,991,575,324,854,150,56,217,507,258,559,267,649,122,585,732,607,332,339,40,413,615,455,811,992,468,944,114,20,559,845,592,248,301,392,58,348,219,191,584,41,902,240,498,75,2,344,760,499,217,612,652,406,630,9,114,279,679,164,875,637,305,279,23,553,476,246,108,194,814,847,683,504,653,533,222,837,828,489,857,966,658,847,328,224,407,136,127,735,797,651,217,285,705,70,856,850,215,950,363,201,920,180,583,63,30,621,694,610,330,769,630,411,798,977,62,21,543,821,571,783,275,780,982,868,618,364,740,302,418,0,828,386,27,151,851,976,689,271,36,387,24,539,3,972,935,571,732,205,686,937,797,273,119,329,198,730,458,937,24,32,626,568,338,465,78,130,991,413,281,910,5,303,513,159,113,626,324,837,766,111,797,241,826,920,886,18,551,170,875,54,214,794,796,824,772,231,308,737,392,493,355,846,5,230,582,400,183,111,464,976,476,751,707,427,335,575,997,238,571,5,298,177,872,51,549,193,776,964,120,818,403,173,809,98,58,526,798,799,564,842,894,321,496,409,930,190,858,919,586,300,696,163,555,785,969,525,270,582,554,312,53,146,472,1,48,783,378,923,442,557,733,343,656,93,902,833,176,727,444,797,803,844,378,32,438,811,490,931,866,766,392,452,481,591,229,942,305,931,921,4,670,859,737,382,642,221,423,852,362,14,713,483,951,402,27,56,552,868,669,490,716,508,69,796,133,547,964,403,539,626,273,852,307,360,11,383,62,666,672,57,399,803,72,628,296,516,491,444,976,40,919,512,187,749,267,463,528,523,670,238,617,436,787,25,440,92,431,418,753,327,580,380,322,809,864,802,858,890,768,698,73,499,412,867,301,188,329,427,416,834,204,202,94,849,20,336,517,975,712,984,521,765,29,293,822,718,102,431,344,110,17,669,728,248,167,49,652,250,331,394,365,121,638,109,723,599,314,201,790,991,685,540,35,92,725,960,188,926,806,785,757,990,974,785,416,854,728,311,466,186,719,854,188,783,357,868,973,507,851,20,682,718,707,785,872,198,299,411,584,925,177,569,458,850,764,693,705,181,114,570,502,648,789,87,178,920,844,547,720,601,800,363,427,579,795,153,112,816,797,352,521,105,225,47,605,42,184,445,112,880,624,84,272,107,168,651,167,353,830,299,805,37,189,62,990,852,398,176,20,157,786,156,554,159,652,893,141,355,547,994,181,634,71,225,514,426,140,627,963,8,501,184,92,791,331,188,64,572,485,396,992,952,184,343,653,280,973,759,975,222,477,402,966,136,378,407,529,745,566,54,34,147,882,920,139,485,365,447,342,463,738,580,125,701,329,96,211,8,168,234,476,612,961,226,312,860,928,144,533,193,460,146,817,207,498,216,524,567,302,298,606,378,368,728,955,567,630,635,461,99,158,47,506,993,48,955,540,422,57,625,167,225,611,451,795,156,992,765,937,317,690,398,761,313,381,927", "899,528,214,617,77,250,260,242,230,755,550,370,246,426,947,961,656,978,403,146,84,346,291,792,739,119,482,876,793,699,560,210,718,912,31,240,488,613,232,229,664,205,539,574,474,61,228,943,249,671,133,709,587,934,753,931,425,551,883,266,15,393,596,32,612,16,417,726,487,50,247,349,51,369,835,891,747,153,580,96,113,313,684,23,730,279,19,664,771,25,341,687,722,669,296,397,137,368,331,978,886,453,9,773,954,613,347,320,835,480,248,789,428,248,337,836,687,698,548,697,794,882,669,491,575,320,217,712,443,364,279,865,820,215,624,508,625,437,612,517,686,458,944,518,285,677,409,227,236,522,866,204,993,942,380,330,325,584,597,448,775,913,770,508,963,710,166,657,778,169,493,207,624,291,148,756,747,44,412,974,319,774,151,837,274,231,657,701,215,203,434,875,499,300,169,118,200,70,254,611,805,202,949,770,874,730,970,336,471,980,587,665,266,534,970,250,920,691,357,959,83,470,700,175,256,29,922,869,330,576,510,54,406,56,108,926,373,396,686,557,140,477,839,985,535,837,31,658,126,314,872,830,548,233,623,320,9,144,739,385,489,259,662,53,312,936,843,104,80,286,93,519,409,301,223,118,99,305,672,473,16,256,363,509,489,126,542,90,725,945,637,335,240,356,450,868,679,988,829,55,405,241,548,355,666,250,366,964,265,236,478,407,261,637,640,874,743,542,382,976,445,603,664,112,955,737,98,377,734,410,794,906,59,251,365,914,344,303,974,32,767,665,699,496,112,332,680,776,889,859,837,638,480,24,765,398,505,851,225,337,303,120,86,598,92,170,78,202,801,647,704,689,336,564,910,405,248,744,448,435,804,935,730,952,329,577,957,612,169,500,865,217,187,237,760,742,455,101,742,16,837,931,916,424,353,286,306,128,478,384,58,889,782,887,288,792,283,816,579,626,167,711,374,986,902,670,395,178,805,81,456,864,462,110,791,913,526,719,720,280,17,679,915,205,232,679,919,421,180,825,30,281,151,635,26,913,527,920,587,319,491,368,581,467,185,981,383,94,911,981,224,501,214,828,0,161,708,143,796,802,662,875,680,508,243,827,73,930,993,924,717,696,261,716,229,13,987,872,508,861,909,752,491,585,119,165,857,321,505,124,362,545,629,391,613,726,261,225,484,324,39,560,415,280,872,324,351,414,435,58,862,209,410,214,95,967,374,178,514,340,85,652,21,598,113,427,208,214,424,807,152,755,396,281,669,593,401,698,193,219,788,844,350,481,814,63,34,30,77,594,413,299,758,400,39,39,332,722,181,924,465,175,83,704,206,210,960,861,365,250,32,950,959,600,361,692,587,807,661,252,63,810,639,758,690,48,312,806,188,898,14,283,593,134,218,959,249,675,445,455,152,609,413,427,561,86,410,326,502,469,602,569,517,851,411,859,919,387,206,370,627,484,72,441,139,243,277,223,986,46,710,687,233,467,423,26,449,504,930,913,920,40,715,214,850,855,684,401,58,118,860,749,935,595,334,92,532,174,81,53,518,345,778,953,860,425,868,738,532,20,311,230,263,796,877,706,828,36,18,376,534,430,639,728,841,831,679,145,33,457,50,765,65,973,2,800,21,75,636,620,610,371,940,873,907,590,547,953,900,174,88,674,480,960,96,330,949,752,182,980,124,929,744,410,612,667,842,386,950,846,336,660,805,797,187,708,469,729,59,632,913,501,435,719,960,395,48,282,787,934,133,900,596,954,384,540,77,247,809,280,507,154,607,210,224,642,694,567,383,274,399,525,750,851,291,174,815,341,920,157,269,834,430,27,955,642,958,126,91,30,348,317,523,694,324,236,785,184,34,783,895,698,678,668,380,360,34,502,325,805,272,487,911,695,752,517,165,712,403,93,49,922,295,672,490,641,582,869,346,799,29,387,147,975,361,465,455,261,107,536,665,561,353,536,143,117,116,213,298,109,166,502,992,781,345,421,324,532,364,794,968,272,686,380,343,375,100,528,38,450,310,552,95,544,175,572,904,898,97,457,345,165,148,625,485,659,111,422,191,642,393,395,614,787,786,281,686,705,211,193,506,59,910,372,999,411,301,600,892,99,636,194,1,237,630,394,620,96,350,498,720,107,614,912,379,395,549,849,399,180,875,741,74,649,713,52,79,344,37,655,854,70,980,518,295,882,596,231,36,927,750,325,723,155,3,301,572,22,736,583,993,341,306,73,272,512,537,955,22,964,722,902,461,114,830,476,812,243,320,97", "548,389,45,128,374,510,941,923,726,137,907,266,649,934,918,822,234,280,234,430,252,908,854,158,892,84,71,583,165,174,895,15,238,600,595,697,16,176,886,390,134,97,130,338,273,990,43,39,653,296,128,285,65,320,387,258,937,964,94,621,927,682,642,334,365,988,312,585,175,591,359,510,716,76,918,135,558,822,236,110,374,354,771,809,354,372,520,21,122,766,158,539,276,510,886,896,771,156,157,557,449,847,204,985,947,3,576,429,419,721,574,479,403,395,709,812,5,651,924,342,52,933,890,23,237,74,897,280,801,153,82,688,9,522,738,41,733,382,422,825,198,523,645,995,125,838,640,870,677,254,685,504,89,619,942,326,512,925,324,531,886,957,653,924,860,633,326,73,531,176,850,255,639,928,371,604,838,580,549,237,328,343,932,575,529,324,681,339,736,293,420,340,808,391,820,420,670,496,121,280,34,73,570,952,363,330,825,314,265,389,708,815,203,382,557,853,30,558,87,267,762,470,854,224,610,490,570,900,989,774,108,582,851,97,852,981,192,947,961,369,579,961,27,199,764,632,277,63,449,782,128,75,528,686,646,119,762,90,762,341,53,952,448,114,766,995,123,976,321,827,857,880,989,446,64,207,419,51,904,65,454,16,107,713,70,86,16,13,557,937,686,737,504,36,499,225,877,464,811,793,373,282,319,16,872,300,851,776,221,255,677,407,938,940,119,683,995,52,933,553,837,210,954,821,868,309,978,219,514,189,312,600,251,176,249,757,289,57,786,117,155,341,320,931,797,485,698,778,157,535,729,311,952,337,925,284,457,201,857,924,133,711,227,183,663,378,431,97,823,493,654,500,758,452,198,638,983,360,456,391,465,579,841,479,992,775,578,798,490,953,166,323,109,409,805,344,243,386,892,596,507,449,617,339,831,197,521,621,540,944,86,318,44,402,147,639,972,574,690,204,978,825,606,64,200,415,792,900,655,118,565,550,739,818,369,782,811,583,725,796,76,446,31,854,985,726,219,614,657,249,509,653,977,299,491,800,85,823,328,654,82,687,515,631,59,805,699,709,48,807,285,367,446,386,161,0,367,764,158,165,807,869,398,484,730,245,315,468,445,884,847,99,372,848,796,122,618,40,554,992,627,797,626,354,575,208,821,276,740,236,340,25,511,281,332,221,17,366,847,830,807,121,809,268,629,728,518,544,792,967,459,145,694,919,111,699,752,558,514,862,884,136,654,206,252,632,961,732,65,159,288,365,929,413,428,174,970,268,532,929,413,198,725,264,262,978,340,168,851,151,123,391,909,588,823,580,727,505,463,123,495,599,992,534,185,688,307,490,915,783,70,124,467,129,331,555,634,286,299,163,998,405,932,79,419,357,438,168,385,531,809,44,122,162,782,626,391,533,102,63,189,629,100,128,688,27,723,458,333,973,62,22,830,31,722,87,476,180,426,535,916,675,208,216,804,729,795,420,394,542,656,272,480,242,928,438,894,990,755,328,30,332,467,962,657,32,266,268,226,236,446,359,930,428,681,291,894,810,677,534,267,885,385,446,70,268,434,802,755,286,631,810,218,882,80,354,903,278,41,661,338,71,971,503,854,737,596,408,790,653,262,79,137,869,593,818,253,834,110,154,54,474,325,548,695,960,761,149,633,593,411,493,642,45,99,2,712,31,298,613,376,339,382,131,285,759,711,681,172,193,565,882,279,510,352,89,986,51,589,947,885,4,878,202,110,965,111,93,723,827,34,722,297,610,300,813,926,802,967,254,419,672,873,198,691,121,139,416,42,401,998,997,724,363,320,582,311,868,69,507,555,631,448,813,164,278,645,472,627,897,433,270,830,402,980,18,919,461,325,136,678,450,314,695,98,581,710,248,922,276,124,943,299,755,215,904,668,230,865,632,167,114,322,791,785,359,814,248,538,924,875,166,636,430,855,905,608,40,618,356,494,787,55,762,636,89,598,798,509,903,478,680,7,775,620,837,540,780,41,617,376,757,306,720,62,975,609,812,637,8,516,947,278,555,127,464,155,174,705,790,699,737,143,849,308,661,671,227,576,954,152,336,361,495,190,188,943,966,802,667,984,800,943,254,588,265,153,254,117,174,515,459,454,700,819,332,345,340,649,343,636,549,432,502,82,967,51,946,609,344,131,84,994,294,281,581,574,649,91,357,394,397,632,265,353,977,218,537,286,29,223,657,739,821,51,990,481,267,660,352,749,640,669,796,552,445,638,280,15,793,575,295,830,104,566,32,263,438,364,210", "507,490,937,272,432,284,279,541,559,931,718,152,829,877,768,321,454,746,829,907,665,264,591,875,10,519,641,697,811,596,36,446,994,439,52,162,297,458,591,397,959,579,436,389,18,153,879,212,95,821,254,397,657,883,638,127,827,361,674,542,979,609,597,487,717,318,222,860,800,328,491,622,372,990,249,675,418,561,767,407,556,792,984,800,846,230,68,616,38,595,589,575,897,237,339,817,979,301,516,256,704,877,579,57,471,341,731,3,16,89,362,239,168,173,439,781,956,734,472,264,897,768,636,667,73,646,100,685,558,598,595,145,419,428,775,758,710,102,398,226,885,414,27,746,858,785,940,605,490,665,264,603,370,954,891,640,843,858,877,460,629,624,52,230,652,690,642,168,395,26,901,211,817,465,147,485,65,603,836,278,557,319,962,600,540,102,179,567,582,97,194,298,628,220,546,284,911,562,825,471,390,659,793,395,892,86,637,582,682,834,203,797,21,857,935,645,496,729,681,837,212,800,52,656,280,215,347,424,831,139,73,622,308,227,882,611,637,747,681,590,869,615,820,379,903,649,533,284,818,327,148,928,666,235,106,276,830,309,877,497,355,652,198,919,148,9,442,716,962,819,998,386,286,750,889,773,278,910,288,196,927,760,265,346,993,290,625,889,10,717,692,925,663,990,487,672,320,638,376,271,302,858,984,765,518,448,971,131,296,896,345,740,620,336,304,657,77,873,522,929,588,522,510,550,496,52,805,986,636,580,918,798,5,500,212,736,341,83,956,769,543,113,146,847,84,216,587,693,957,813,597,876,190,760,14,245,258,248,977,842,192,286,304,563,803,424,572,21,151,592,652,691,855,186,595,676,176,721,633,741,206,948,270,630,813,681,269,660,641,229,458,244,862,322,657,511,788,789,324,841,313,547,305,55,571,22,59,528,556,939,919,523,702,632,560,860,357,465,202,959,422,935,184,608,509,129,888,50,414,831,625,78,584,492,466,188,84,823,613,474,952,219,701,382,272,862,653,169,392,426,206,484,666,199,807,206,595,288,77,241,308,890,347,560,511,815,418,348,682,184,898,799,129,27,708,367,0,35,433,854,338,514,482,998,193,205,876,160,897,805,651,319,115,899,288,642,60,455,239,233,505,795,537,918,652,636,301,815,259,690,832,268,316,905,947,519,194,956,864,407,973,696,599,115,297,38,325,608,876,4,715,468,587,496,3,41,466,389,961,966,500,19,19,767,599,686,772,217,943,65,249,8,186,626,850,26,198,715,994,559,597,741,652,300,663,268,33,183,41,953,446,246,802,913,669,359,223,217,700,711,43,477,59,333,909,742,856,150,495,702,333,520,552,464,727,549,577,980,478,537,963,596,521,694,489,32,700,597,49,540,573,784,403,307,959,954,581,46,251,353,887,240,745,69,637,311,826,79,697,799,796,88,182,522,416,797,344,526,402,597,669,209,858,951,907,68,404,363,449,386,882,175,777,529,911,495,905,913,479,982,528,19,141,458,814,479,536,61,640,231,610,792,345,624,999,22,926,174,754,791,341,88,431,605,958,487,155,838,324,319,492,412,804,631,62,288,276,35,243,556,163,671,531,177,371,961,140,850,23,450,835,987,67,261,636,614,245,250,963,39,982,658,598,994,349,527,13,741,977,239,892,87,412,683,691,848,730,454,75,587,825,642,24,752,279,750,31,788,957,5,900,840,542,721,508,601,521,227,776,176,800,848,250,849,562,723,357,223,938,505,384,581,824,886,35,20,113,41,494,330,74,891,811,643,532,388,437,539,406,831,485,879,136,231,834,688,544,834,829,142,509,554,52,319,378,829,866,231,488,280,603,276,447,122,984,929,761,446,232,250,565,100,386,323,664,435,107,494,369,897,697,295,847,679,863,689,919,61,75,924,334,456,39,507,575,595,509,166,895,216,533,465,418,307,693,553,941,511,250,556,135,176,129,715,700,127,678,727,62,556,648,341,515,80,853,497,905,93,793,885,887,241,710,178,463,915,890,494,204,373,520,534,95,911,694,826,649,883,528,680,774,672,832,13,713,528,958,472,346,607,142,476,325,219,202,408,803,426,666,348,409,747,344,125,993,583,206,601,520,156,120,45,633,579,735,597,322,341,569,769,994,258,990,701,351,518,933,790,962,981,48,880,986,834,852,189,972,471,695,666,284,585,137,951,250,119,286,237,607,468,174,761,428,346,246,577,353,209,235,949,63,715,626,721,599,987,223,287,285,283,110,448,941,694,302,765,860,849,411,543", "875,491,929,463,388,43,925,619,17,425,851,738,917,743,422,576,79,663,203,207,329,308,170,661,390,800,988,194,539,648,98,698,353,411,145,920,88,50,948,857,224,796,38,712,835,414,334,975,464,648,161,528,732,484,116,722,44,11,721,590,932,838,147,241,779,331,832,848,909,357,320,679,510,591,232,498,14,702,670,624,336,337,23,983,168,620,283,388,692,882,275,828,728,456,466,68,655,526,269,828,957,49,600,726,231,236,484,120,827,932,629,563,717,359,791,929,630,222,442,555,339,775,366,469,697,540,612,194,875,93,197,148,167,877,195,527,682,418,876,960,863,201,841,60,7,521,817,889,297,507,44,394,205,644,970,387,470,585,36,288,22,511,580,270,204,601,242,320,680,571,798,986,705,33,252,25,681,911,700,732,28,733,226,648,636,398,339,195,943,311,370,457,182,363,250,204,60,440,899,305,862,313,417,237,438,653,206,714,941,958,595,500,70,653,944,810,761,684,354,440,897,141,73,869,958,711,881,302,918,849,984,455,222,24,171,9,35,132,102,74,412,583,371,29,63,466,585,548,643,972,332,47,810,421,384,323,349,947,21,223,604,340,861,101,137,752,710,355,866,950,437,776,543,738,586,804,897,114,313,203,914,865,759,948,922,417,811,920,124,580,109,191,500,122,12,884,485,824,461,174,205,113,549,429,718,58,13,18,684,494,223,361,809,27,108,205,627,543,435,427,505,343,385,963,826,883,417,553,632,941,151,78,716,569,333,171,534,670,406,889,43,800,203,742,620,511,705,172,195,331,2,189,986,766,517,250,247,830,440,884,904,283,35,92,220,364,928,111,817,462,782,111,636,817,195,665,624,511,570,992,162,948,140,266,486,81,690,413,160,268,796,961,531,739,826,677,466,456,202,472,586,767,359,957,292,349,397,908,820,160,215,543,455,289,755,362,987,284,106,704,840,998,485,984,11,984,343,758,813,840,544,14,473,340,913,197,564,179,8,186,499,574,133,640,656,893,75,235,484,159,429,910,197,472,45,145,535,58,815,688,60,189,473,613,883,951,231,94,195,84,13,838,919,151,143,764,35,0,484,662,942,882,617,122,416,858,310,713,754,185,941,536,384,907,71,923,202,810,405,227,315,193,287,64,656,384,296,515,239,322,881,768,42,740,691,715,600,522,929,454,514,235,344,369,678,916,783,274,698,774,896,790,742,680,144,788,178,689,270,529,250,550,562,246,589,991,836,400,668,483,860,459,608,51,550,665,845,565,131,330,469,104,711,26,290,732,605,744,230,173,121,734,814,471,924,879,230,131,486,730,672,346,362,576,982,34,374,574,616,577,286,419,208,133,787,756,744,145,296,373,238,493,797,86,888,688,809,329,940,728,551,221,806,684,345,176,726,583,109,856,229,314,334,858,612,504,529,12,921,623,320,640,367,433,606,212,285,282,993,86,395,699,756,770,862,197,908,790,829,428,779,403,950,176,89,940,646,514,289,28,370,956,319,841,327,213,395,908,81,283,299,359,463,84,724,559,853,379,31,344,692,62,510,635,774,54,631,661,813,885,512,722,465,357,258,766,536,708,168,528,438,337,854,978,392,556,239,947,625,628,606,260,44,115,833,440,671,709,859,708,25,494,934,840,658,387,913,69,595,888,437,628,400,778,519,774,975,307,849,626,208,661,388,565,164,551,622,857,753,434,32,137,415,98,453,999,996,971,431,424,974,655,991,19,262,969,466,352,427,132,920,929,268,470,777,747,249,48,146,859,511,128,587,132,890,872,960,533,22,622,228,953,577,645,942,247,143,889,9,543,578,430,499,424,471,22,770,52,256,340,571,984,700,473,961,576,280,303,681,141,562,639,691,281,84,763,951,892,853,530,616,137,548,581,829,205,988,751,451,922,191,175,692,45,485,756,914,460,76,51,835,710,319,869,114,814,111,772,61,551,47,810,25,233,89,183,901,531,218,886,517,520,1000,98,164,142,790,659,20,805,890,280,209,754,791,427,899,559,241,822,741,145,8,117,206,924,951,412,833,565,831,754,738,661,807,328,239,106,380,245,224,579,645,353,842,441,476,156,988,489,432,217,111,17,807,469,876,38,458,480,347,686,489,757,766,219,868,736,916,369,365,301,958,326,862,62,914,810,446,311,761,594,938,813,64,122,605,207,182,469,257,34,585,198,372,161,99,431,244,432,446,541,496,942,397,297,489,713,449,695,219,615,201,295,182,157,953,864,962,427,798,207,113,286,997,93,846,172,959,57", "434,550,415,260,758,354,327,92,113,410,888,824,937,344,274,598,553,999,235,495,479,124,475,720,819,573,276,610,344,487,569,133,194,150,289,105,665,278,547,898,577,158,583,913,218,969,771,87,34,625,737,936,620,857,777,814,227,680,956,629,170,450,55,904,191,571,227,544,16,276,676,171,860,731,453,80,287,124,460,191,979,444,826,987,948,705,161,307,388,802,75,809,867,764,74,244,788,77,165,176,218,816,886,934,232,679,945,795,954,949,549,730,4,542,994,235,284,312,133,758,921,776,702,227,42,736,810,911,702,353,688,35,649,175,692,426,280,160,59,872,947,659,31,280,232,894,884,581,233,995,600,911,70,756,307,384,877,950,518,859,92,548,471,134,508,138,417,343,64,563,953,889,59,212,361,262,44,454,570,160,377,595,904,778,861,816,629,382,324,222,702,339,744,984,595,559,652,39,254,540,585,935,569,223,805,298,730,57,158,334,575,644,360,378,763,73,209,838,655,568,891,363,830,527,865,341,178,379,847,642,733,784,288,861,529,403,201,805,683,430,253,221,747,95,172,335,189,485,301,161,498,159,708,115,633,408,933,485,853,16,227,556,389,42,170,83,907,404,792,605,440,788,633,396,155,839,57,342,919,358,23,672,423,413,930,218,6,73,542,636,683,152,503,866,772,979,626,981,90,251,67,310,485,764,197,824,931,495,778,711,740,236,204,263,898,114,971,345,27,143,686,300,717,638,919,588,651,140,467,995,393,195,779,997,160,71,592,834,812,771,151,386,257,319,296,563,568,405,711,740,108,588,914,790,269,592,406,681,94,562,491,407,992,563,979,665,179,66,232,672,831,709,130,39,864,507,266,865,860,232,668,569,349,607,432,61,113,631,383,298,25,972,277,730,751,380,869,285,293,939,107,95,643,733,882,497,399,655,67,559,410,842,457,58,607,961,185,145,720,10,61,596,516,671,214,639,404,870,985,132,421,83,113,549,746,379,134,577,508,275,127,165,343,473,946,643,801,41,368,911,572,961,926,569,503,936,308,547,637,78,929,975,551,89,491,542,263,819,440,881,80,100,203,851,796,158,433,484,0,725,862,762,257,624,850,692,4,229,466,125,634,472,56,119,6,883,153,314,626,804,779,720,105,444,403,599,207,412,613,838,737,807,438,74,531,333,566,192,429,187,768,488,677,580,588,521,659,623,728,270,917,905,818,89,37,55,377,802,41,195,111,856,435,85,998,761,15,915,545,518,997,696,177,286,237,551,546,899,103,622,469,97,909,468,464,397,148,58,275,93,118,551,554,342,628,916,132,410,523,112,383,357,22,601,913,114,738,738,128,949,209,357,879,151,656,727,230,183,248,752,768,448,610,413,241,993,287,241,575,756,378,214,795,366,532,650,403,996,785,521,664,773,116,338,206,676,801,346,587,268,234,578,661,782,86,390,535,7,445,19,567,632,610,673,520,760,450,555,34,651,716,372,763,627,98,885,81,806,396,466,249,608,818,650,778,825,823,794,670,551,778,969,319,100,549,394,96,190,249,102,363,362,489,487,967,111,723,797,403,336,346,936,278,121,810,744,224,201,60,953,250,635,176,834,423,330,117,383,847,662,461,121,166,646,978,310,267,606,897,801,661,193,997,126,269,36,623,708,474,170,458,165,470,390,225,604,602,864,634,445,169,455,382,45,12,70,510,550,534,249,450,987,503,82,495,823,509,408,183,596,777,572,731,199,39,420,84,872,947,900,602,949,211,332,263,361,33,574,102,992,978,306,814,477,15,259,922,859,475,810,930,239,273,848,851,186,297,906,865,119,531,563,163,637,661,546,214,624,625,944,780,961,865,12,335,580,196,20,93,82,68,346,111,757,7,979,620,446,774,686,697,242,482,862,206,68,107,519,606,588,11,112,264,989,891,981,14,897,590,779,242,967,860,854,936,761,279,861,567,132,602,765,781,11,788,442,802,435,51,695,131,377,297,708,761,327,682,263,566,908,593,831,760,877,905,315,113,563,134,576,732,21,909,724,244,137,730,21,560,548,604,431,390,300,210,69,581,313,783,579,668,156,377,48,786,849,949,214,174,494,247,457,809,307,829,265,562,828,181,412,609,939,823,9,206,160,421,564,233,475,564,327,649,989,871,49,754,382,224,564,630,268,322,473,590,598,502,526,338,739,962,201,11,247,434,493,480,9,462,61,919,714,529,239,959,114,926,68,359,310,512,987,17,255,145,898,721,355,260,482,712,352,830,819,418,675,551,517,142,130", "702,983,221,74,158,49,901,105,670,805,424,383,302,918,489,797,182,39,319,629,684,293,269,976,950,207,463,346,377,977,542,4,454,565,391,14,628,198,671,210,157,576,428,208,562,190,82,423,287,648,942,408,267,657,831,508,333,737,354,389,249,312,266,6,984,909,57,594,975,2,139,791,661,749,387,615,578,29,208,441,624,877,482,719,240,817,431,85,881,421,89,797,973,363,417,123,480,336,288,41,844,333,56,490,956,992,575,946,34,738,954,681,686,636,782,854,237,119,219,24,566,975,440,910,220,645,192,418,483,184,766,406,720,298,203,423,283,988,961,921,701,199,399,547,5,647,150,347,442,62,327,614,731,891,808,316,923,211,927,691,94,391,953,772,877,592,905,885,356,796,817,811,189,794,369,818,955,340,980,687,622,125,79,349,87,955,618,927,286,706,504,77,476,252,731,582,673,790,845,755,481,799,749,60,285,18,644,565,61,965,405,188,303,466,701,627,465,535,494,178,311,636,582,338,908,9,439,847,901,581,81,264,735,319,311,997,157,887,163,975,787,473,983,480,673,112,670,546,664,208,925,839,907,678,386,136,61,469,999,155,344,854,702,710,127,687,89,837,941,74,433,478,131,357,15,481,491,856,450,596,61,305,511,341,638,131,231,102,575,535,658,762,190,519,588,199,942,379,199,997,538,267,63,845,658,478,572,985,438,955,846,14,491,750,557,719,883,937,3,176,808,104,403,851,893,414,977,759,291,774,329,704,594,376,45,152,480,997,286,760,765,156,989,198,76,213,845,586,851,324,435,802,186,512,198,261,902,341,372,599,244,228,249,840,583,656,258,80,958,460,980,316,762,89,167,997,2,466,187,72,739,338,865,638,784,39,858,208,867,832,946,461,582,79,382,326,767,712,227,547,582,575,203,345,927,649,183,977,709,642,788,276,761,789,966,300,567,727,566,487,288,814,128,63,962,912,253,620,688,59,70,362,376,380,476,804,786,847,75,674,554,421,771,937,530,284,108,419,809,558,158,46,959,926,653,902,206,406,388,626,404,283,396,11,510,928,107,17,72,389,845,874,104,976,802,165,854,662,725,0,164,484,953,819,498,779,76,634,843,217,798,930,616,863,230,811,105,552,476,101,381,444,327,510,238,132,727,305,956,841,211,778,205,361,869,684,285,962,843,232,493,975,891,193,268,411,846,143,288,897,74,895,126,517,37,789,711,926,879,584,808,244,334,269,405,835,411,521,660,965,676,322,505,865,875,46,88,535,77,649,593,849,347,438,553,363,594,126,401,774,212,834,118,915,404,709,461,353,250,248,336,416,830,695,30,496,490,400,769,714,500,187,846,98,437,157,161,366,805,210,634,198,262,856,571,429,197,63,476,122,943,772,55,405,876,183,876,156,847,369,417,913,635,259,762,858,250,884,275,217,493,826,405,510,639,19,910,534,928,882,452,282,289,169,992,571,349,141,47,704,390,457,409,118,997,361,738,646,81,232,975,847,777,598,465,823,713,769,175,246,352,285,679,642,368,332,786,662,658,749,567,100,268,734,928,567,850,279,312,613,435,933,61,439,495,982,705,873,349,684,772,318,424,842,893,614,193,688,343,494,185,782,148,140,210,702,398,368,74,57,995,970,719,124,154,389,723,222,337,551,29,783,338,512,627,17,540,139,806,363,102,188,619,594,464,781,12,960,363,272,8,220,927,454,4,233,157,355,249,370,688,381,804,619,622,860,450,305,418,902,298,769,617,153,615,321,698,663,291,915,172,278,80,200,232,71,535,791,461,38,926,571,27,420,414,360,749,641,913,83,662,124,583,806,966,328,604,317,317,424,272,736,112,40,12,591,747,762,231,200,481,196,706,564,707,626,18,696,287,344,354,674,962,970,299,744,757,555,831,144,343,338,325,581,310,759,744,293,332,216,356,668,457,555,634,887,129,21,247,179,209,222,640,909,25,920,218,100,395,917,878,231,122,952,363,288,920,411,953,55,440,878,768,128,969,183,214,15,338,569,737,523,512,663,843,404,112,168,750,417,286,872,839,134,952,173,770,841,554,940,501,143,339,881,594,663,977,65,389,933,879,738,964,604,178,230,976,133,996,849,393,535,132,668,660,164,936,753,500,219,714,296,132,780,327,681,777,718,392,427,750,313,473,169,206,935,95,10,809,782,328,759,265,729,307,997,950,384,182,20,125,498,754,243,869,639,327,76,788,540,860,568,594,216,733,12,745,344,508,320,60,655,582,487,518,604,733,203,199,917", "109,812,6,531,121,389,56,976,354,829,482,670,998,895,283,292,827,629,385,331,394,418,184,822,899,481,460,764,394,845,92,745,142,153,795,113,720,209,348,184,428,967,430,840,993,255,970,579,128,530,424,190,604,597,366,533,277,360,92,957,323,795,198,744,747,124,364,812,347,906,821,192,4,274,839,507,300,696,191,442,563,139,387,52,392,869,367,862,621,18,540,430,77,173,738,603,731,497,473,659,204,653,126,460,740,414,767,756,163,947,289,862,340,501,378,489,747,722,882,693,735,721,50,128,565,50,250,699,716,677,864,806,385,281,267,632,425,939,126,596,35,546,826,241,706,401,410,390,978,882,712,137,310,64,611,123,122,68,76,438,941,783,358,674,669,461,432,881,115,636,44,692,174,623,960,303,949,995,162,104,620,120,312,430,121,433,405,449,43,177,557,287,549,489,366,202,761,457,689,28,825,396,905,345,411,147,83,27,403,29,540,724,57,567,708,695,940,769,128,178,413,402,786,509,301,591,878,317,83,734,498,632,419,851,303,451,279,238,935,108,588,69,314,161,82,99,398,839,332,46,324,71,56,753,16,31,650,721,476,101,692,557,849,744,340,579,30,354,774,790,403,527,849,846,298,543,242,480,336,65,13,700,210,762,463,48,806,53,413,236,493,646,638,661,416,668,807,623,198,17,398,408,164,465,400,135,324,837,15,578,975,454,878,100,540,243,18,223,369,664,382,919,862,42,855,16,629,495,194,653,322,452,898,790,656,583,459,974,252,827,838,307,124,998,115,300,678,917,532,594,885,374,865,148,410,516,170,920,60,316,267,758,520,406,999,532,28,143,276,180,250,941,959,891,93,638,611,552,767,748,152,265,462,89,162,305,306,147,924,521,589,355,270,896,691,94,156,302,421,207,257,698,213,354,797,512,911,837,289,679,306,424,466,794,653,143,700,816,182,694,500,525,216,333,31,618,916,521,89,539,765,234,847,589,756,834,309,120,523,662,108,180,166,838,208,904,423,828,599,133,645,777,743,718,569,902,222,693,108,591,801,695,797,205,546,487,505,444,421,515,991,331,9,689,662,807,338,942,862,164,0,651,598,219,578,526,387,850,63,751,696,732,87,839,866,34,447,159,238,509,151,46,39,977,95,74,552,834,151,5,327,439,383,839,86,971,856,64,788,227,679,516,882,719,554,34,834,317,359,334,705,227,863,551,991,597,381,839,632,908,549,949,612,858,197,17,458,792,739,346,419,488,884,931,870,412,4,377,958,222,201,663,858,455,275,680,419,68,681,608,313,644,559,340,354,918,937,908,271,824,334,14,730,477,694,305,303,607,881,908,897,862,191,334,863,619,806,411,156,584,630,401,601,916,401,608,883,18,772,604,942,153,474,418,969,732,734,210,511,520,463,460,716,433,33,952,865,241,85,499,360,506,384,56,218,766,543,483,581,253,352,184,568,236,513,708,92,984,86,275,191,662,830,371,462,475,61,787,943,165,768,383,171,677,902,841,765,153,356,386,586,258,352,909,516,898,677,831,117,111,578,767,512,421,813,433,542,480,53,385,92,180,18,381,70,631,664,46,436,701,370,897,912,352,237,205,816,463,635,48,261,274,204,336,701,690,898,789,709,55,207,966,9,55,66,394,706,483,300,129,911,570,297,189,900,279,620,342,189,8,96,831,82,69,749,854,742,660,874,62,123,411,404,850,807,681,452,672,620,614,899,716,717,484,469,722,907,726,752,916,968,33,840,367,738,561,900,726,435,85,672,482,913,616,327,645,622,743,360,991,101,684,154,736,96,865,761,736,586,877,74,407,166,64,257,725,21,723,306,326,516,495,801,523,253,684,211,7,191,237,712,326,906,997,895,421,584,940,165,347,311,847,141,854,477,185,923,123,933,806,365,569,698,963,899,216,568,706,352,135,382,81,974,696,291,353,432,526,445,850,275,377,976,627,559,317,68,422,161,11,857,229,913,615,221,245,200,749,918,283,480,416,937,413,563,188,827,601,171,9,353,699,373,307,69,379,186,77,405,411,103,649,499,850,333,56,610,333,714,548,780,902,678,51,440,515,316,88,399,161,686,256,320,177,415,646,979,842,546,20,164,948,713,261,927,558,868,995,678,830,875,78,187,656,178,800,564,65,245,901,186,152,58,392,596,530,399,242,445,390,733,373,617,606,469,804,465,714,908,597,759,534,359,233,636,424,783,258,136,770,748,214,201,684,518,71,313,696,517,332,990,935,378,413,411,165,217,229,375,285", "32,652,666,726,868,606,528,429,685,990,735,201,954,12,610,816,290,427,527,877,966,839,332,942,374,68,428,14,439,781,399,457,6,76,891,25,850,949,779,272,453,68,173,159,267,554,595,189,531,673,221,122,797,648,163,846,648,866,126,101,994,385,253,700,313,650,751,901,239,872,217,648,241,98,331,713,394,710,493,107,349,958,458,413,555,694,107,917,70,939,976,408,643,180,797,966,893,328,811,294,63,111,816,994,514,786,406,520,717,997,610,330,896,87,963,74,728,566,343,472,47,863,951,861,397,76,290,535,350,397,294,409,409,522,328,684,615,813,462,622,54,971,415,445,595,975,270,749,822,214,176,977,659,395,879,432,620,410,465,51,999,620,640,845,542,102,702,326,335,625,831,621,43,969,723,550,780,996,170,938,648,483,678,981,73,776,295,497,534,526,671,443,420,641,797,92,885,983,769,701,703,454,106,433,153,410,350,865,530,118,386,879,369,797,762,889,816,119,769,804,855,291,55,878,795,177,83,296,191,808,268,3,113,810,918,171,224,331,48,530,970,936,82,505,590,282,101,55,577,642,27,314,441,213,423,480,895,388,804,995,79,28,487,164,708,565,377,799,14,204,914,524,638,674,339,379,233,439,141,137,727,876,411,985,532,290,58,879,274,483,484,186,331,544,903,400,288,28,940,337,699,901,366,777,353,92,758,326,23,355,113,64,874,738,107,483,862,96,440,732,799,276,67,220,55,950,526,181,376,48,957,691,119,845,526,346,145,885,355,641,851,85,849,88,737,973,431,129,402,949,251,105,922,388,876,272,748,645,764,521,677,579,141,680,485,204,150,148,614,786,176,516,468,775,399,666,538,675,50,627,197,238,42,297,899,796,707,667,618,561,489,772,826,786,996,801,686,761,956,847,875,106,307,624,400,20,98,968,434,579,942,882,35,70,403,540,564,958,440,886,689,602,573,382,515,933,308,944,524,878,658,764,796,615,837,421,273,679,149,847,495,478,641,987,388,82,457,802,561,783,155,667,544,470,131,247,723,422,333,426,89,546,677,821,79,350,336,556,813,200,309,690,99,271,875,869,514,882,762,484,651,0,683,27,33,475,531,561,702,316,53,393,643,389,246,448,823,636,265,108,429,656,935,77,956,881,709,605,884,809,667,244,53,938,598,89,857,401,784,367,471,40,636,203,369,727,95,677,169,634,770,209,346,224,435,40,77,777,106,920,380,73,646,121,554,594,717,149,585,361,609,468,182,853,62,668,677,726,370,790,483,49,882,205,59,479,760,512,747,939,820,522,371,794,577,367,86,687,159,340,659,276,465,886,827,642,835,650,714,611,444,488,126,680,686,133,795,801,673,524,298,132,510,141,856,463,993,143,197,931,549,629,980,186,372,193,255,917,967,785,1,135,438,822,458,197,603,298,311,280,464,780,34,708,696,874,99,460,369,464,513,444,860,552,265,118,274,375,616,840,752,25,717,31,959,642,313,381,135,51,775,858,911,479,930,509,788,298,374,577,509,323,884,34,960,266,785,806,843,707,249,793,895,552,282,894,983,441,753,558,68,116,974,518,136,819,448,747,513,474,104,83,351,650,392,396,319,386,726,150,403,544,518,945,493,433,714,602,733,54,117,500,464,670,586,290,346,118,600,883,599,727,322,912,753,336,721,65,198,333,532,313,153,312,296,389,688,432,228,166,419,768,920,535,421,524,231,357,467,188,212,208,362,928,630,824,416,386,48,213,201,810,619,127,540,585,71,256,309,47,765,120,610,764,46,966,894,836,64,612,98,252,797,671,444,496,764,826,597,95,533,577,575,19,755,615,478,161,736,569,413,494,586,902,597,186,309,980,624,552,716,898,424,674,741,118,931,999,564,174,149,208,531,33,787,430,876,373,186,721,247,809,956,842,304,11,200,994,113,236,914,883,566,801,157,393,819,266,454,672,643,715,543,306,594,1,201,209,899,620,419,509,717,462,623,289,697,507,558,189,435,195,733,353,379,412,135,508,521,311,226,332,806,181,129,233,760,346,61,381,847,963,639,767,846,811,487,248,866,957,190,976,305,734,225,515,340,263,643,760,530,149,433,860,12,479,266,810,971,185,243,950,253,879,747,297,869,641,972,76,366,998,251,100,287,504,359,603,808,174,954,124,12,994,184,277,334,927,565,230,727,871,756,374,571,984,393,15,269,158,975,676,478,213,689,190,698,571,551,657,516,678,70,638,67,934,407,3,941,795,102,804,852,69,795,657,624,487,741,456", "835,170,263,822,961,522,113,685,345,72,637,572,290,409,876,757,790,306,599,737,887,427,945,816,841,789,958,935,812,865,986,31,716,796,686,345,983,966,442,551,468,611,865,346,329,767,872,440,379,465,65,977,894,995,840,961,429,882,707,666,46,865,295,851,709,880,43,187,744,611,640,566,720,335,967,22,538,206,731,77,916,499,923,640,391,668,380,807,212,719,677,122,300,280,573,996,27,147,235,397,765,887,416,568,772,720,212,540,984,843,749,897,814,219,99,278,395,522,439,62,72,141,807,413,215,155,187,309,684,845,946,842,541,19,825,462,903,409,11,128,961,422,859,151,513,12,372,136,158,605,872,666,556,917,554,58,411,68,212,166,323,923,991,622,750,420,423,604,377,7,782,667,358,812,94,918,68,812,190,38,605,980,659,80,59,68,964,125,907,89,597,632,6,283,625,533,831,226,775,62,779,451,50,585,699,197,47,584,419,864,198,359,465,219,175,128,821,840,192,112,714,871,184,653,922,550,518,729,109,618,473,390,902,624,433,370,888,620,475,409,391,272,626,374,747,1000,862,636,814,123,258,327,447,520,428,621,226,895,776,615,163,81,79,525,274,428,507,962,112,837,160,625,715,592,997,303,869,16,483,892,548,633,661,18,801,32,780,543,566,468,517,746,232,235,86,451,977,435,651,78,138,800,947,675,486,44,605,580,42,189,821,562,460,964,386,866,595,676,538,663,991,885,847,43,454,359,56,954,859,433,963,259,469,255,266,598,886,625,878,365,529,403,213,414,372,234,942,790,32,998,654,88,475,87,259,873,110,906,822,148,718,467,371,984,95,325,384,404,626,870,457,470,808,356,704,469,814,524,919,137,863,94,674,367,493,113,301,366,333,685,12,182,233,367,304,864,226,243,453,504,132,781,973,982,591,984,903,21,968,802,461,41,382,265,786,163,413,710,337,872,324,490,739,761,668,977,602,422,171,431,242,47,414,452,798,480,745,834,126,16,186,853,248,980,860,140,166,937,207,346,744,440,422,64,976,584,69,3,127,383,123,20,197,136,960,238,260,719,331,852,21,888,705,36,680,398,482,617,257,953,598,683,0,999,824,378,716,784,647,49,687,564,8,301,995,309,991,884,413,869,962,582,820,201,251,815,404,179,580,400,774,157,235,187,409,719,638,615,135,758,383,392,211,284,696,407,913,840,868,445,799,110,650,186,271,742,403,302,335,129,972,509,298,831,805,550,809,421,135,613,156,954,80,669,413,840,730,950,396,299,732,89,570,440,750,449,736,472,403,684,995,419,929,10,18,764,201,544,390,317,502,356,772,27,844,663,41,24,333,274,669,497,785,150,835,333,657,754,624,820,494,460,764,807,980,557,337,132,488,436,61,850,967,165,489,42,2,818,904,983,442,864,713,377,556,818,429,469,416,122,746,642,428,245,672,201,839,988,228,210,756,757,657,512,847,579,923,892,393,843,312,785,189,94,748,726,913,632,586,221,570,834,483,985,392,284,857,880,288,361,635,670,909,347,585,598,453,312,370,873,366,379,106,760,491,363,280,309,277,73,268,70,744,699,561,818,767,845,582,771,105,270,459,8,475,590,533,379,249,152,870,635,551,111,921,549,987,871,58,749,471,734,996,74,731,427,374,400,590,380,310,515,785,171,249,473,726,792,85,993,209,177,331,831,731,605,875,882,111,343,656,980,919,292,344,339,618,737,745,513,22,867,294,601,833,803,817,962,155,636,959,392,195,271,242,113,920,258,727,514,647,611,974,823,744,466,240,442,48,965,287,641,376,894,431,773,321,389,646,640,344,925,676,455,200,276,781,573,542,141,495,908,316,528,472,175,230,604,694,59,664,361,7,758,935,748,669,758,201,671,193,499,14,811,170,437,336,517,497,823,353,686,744,897,201,942,598,579,521,879,249,838,809,362,118,434,483,784,433,632,448,702,222,959,828,285,963,865,831,478,379,18,229,255,145,94,728,588,815,303,311,818,470,964,414,62,13,506,229,809,756,105,57,615,798,514,10,941,348,542,122,707,564,751,347,549,107,153,928,155,211,759,151,312,101,42,975,689,630,749,483,903,278,54,418,506,773,695,415,610,633,887,188,402,89,995,670,140,749,515,518,922,207,704,150,329,824,605,780,854,649,172,968,656,697,594,505,797,761,981,156,817,826,381,242,270,914,476,159,992,771,69,220,591,344,341,431,170,203,900,486,558,533,201,931,804,652,655,792,732,985,89,379,428,423,184,734,320,732,36", "788,618,1,622,959,695,289,303,20,191,656,667,304,851,567,995,736,848,301,577,605,602,930,84,140,927,86,692,441,32,379,462,114,807,365,466,505,534,431,792,96,64,208,359,294,523,870,516,160,474,625,822,877,849,10,851,940,165,154,724,208,73,427,5,55,201,194,600,763,869,918,123,469,352,13,358,30,999,340,58,761,723,591,687,308,956,258,958,189,939,184,614,682,248,389,736,996,114,363,907,398,985,549,735,962,283,706,894,680,821,847,408,190,70,625,184,673,288,778,801,336,677,8,907,40,646,793,36,800,891,436,177,163,11,664,750,527,699,611,929,257,582,520,401,413,484,77,530,108,266,356,975,128,757,880,612,966,679,393,65,803,874,18,577,904,624,263,184,502,738,492,505,611,908,636,172,36,749,907,757,106,797,286,129,864,750,38,81,36,68,839,897,29,173,576,410,139,731,445,212,19,881,107,894,334,611,376,699,883,687,427,305,653,159,32,62,748,462,680,386,942,814,500,898,131,35,421,369,839,311,508,680,385,947,20,889,469,708,788,575,100,827,126,670,67,117,815,138,447,338,756,217,58,949,33,927,812,651,687,566,30,603,943,871,981,935,127,733,943,653,990,503,381,879,910,673,815,664,49,563,915,215,848,74,291,359,326,968,341,854,137,46,757,651,276,660,978,360,64,672,635,231,425,327,764,85,146,223,149,58,91,860,500,271,879,785,834,455,888,573,274,695,908,516,713,962,979,753,925,739,635,141,439,573,490,245,241,775,412,394,463,645,919,547,788,771,493,962,578,891,235,817,108,219,72,919,93,866,488,554,168,450,879,12,868,84,901,868,551,564,945,475,330,625,101,134,412,96,509,673,784,97,727,268,432,641,281,935,804,595,260,716,138,134,389,893,370,755,171,584,345,963,519,845,865,247,754,793,11,560,494,256,597,268,792,729,149,930,716,450,701,980,960,505,475,9,40,766,126,802,217,50,539,441,544,523,58,511,805,489,268,806,130,294,840,395,239,116,857,664,123,842,242,863,625,452,144,97,926,445,925,50,445,662,297,206,177,421,208,55,683,265,75,387,508,484,998,122,624,819,219,27,999,0,94,357,476,440,356,966,728,319,762,242,815,962,315,529,777,203,224,934,356,954,476,239,763,24,210,447,952,721,579,268,47,387,231,79,987,968,426,954,554,332,996,841,176,512,190,81,169,904,989,819,765,434,775,784,686,582,699,194,183,435,682,950,178,759,217,94,667,92,850,213,593,821,394,554,871,699,662,648,340,439,886,382,345,707,792,856,778,917,93,167,916,139,736,852,495,177,563,4,386,506,502,800,980,207,20,482,198,745,808,885,650,300,603,436,863,429,606,171,863,99,286,226,808,934,140,715,430,365,75,306,60,9,711,116,385,874,328,422,658,197,144,873,306,889,465,336,55,837,984,355,637,365,550,779,466,195,216,356,664,347,111,598,88,279,52,87,499,792,521,294,204,484,43,258,696,693,659,358,983,530,889,221,702,164,95,536,529,509,413,278,957,164,313,98,961,56,296,126,581,904,268,881,960,837,411,258,371,201,900,556,471,903,679,412,308,629,515,58,977,55,473,705,368,122,90,652,684,804,571,725,525,7,352,297,521,613,217,550,303,454,51,176,588,878,855,444,13,547,691,626,143,113,32,21,428,771,646,926,250,934,875,278,618,909,555,38,659,555,128,386,558,97,298,756,324,981,655,848,667,583,545,842,939,476,601,457,319,148,7,946,789,593,936,706,777,527,154,27,42,805,26,275,992,106,902,163,259,309,869,87,797,656,780,733,157,265,663,568,132,994,739,343,691,517,244,369,210,604,117,377,294,157,702,832,225,909,943,27,817,464,205,192,597,41,284,617,387,307,7,866,502,158,321,342,8,218,396,26,324,928,678,971,68,75,824,970,376,490,585,426,500,366,30,78,521,348,469,108,346,448,684,613,805,425,352,469,597,678,228,678,108,541,157,705,217,470,162,984,282,295,41,599,677,529,149,75,790,784,205,193,386,845,523,188,887,809,460,29,248,170,765,148,810,522,989,972,508,924,967,821,747,404,183,233,182,149,671,68,727,547,565,94,417,789,366,886,278,467,814,706,143,779,765,537,19,802,767,893,308,21,273,920,439,711,723,721,986,744,476,777,289,787,622,858,864,309,680,416,25,421,171,604,264,878,872,615,664,393,546,581,858,301,45,248,790,34,312,739,404,652,766,716,624,130,496,197,572,754,121,214,941,741,640,179,714,479", "108,665,314,831,641,531,780,453,78,607,43,809,473,271,960,525,740,669,980,184,298,819,430,901,303,670,100,867,992,343,596,146,710,287,206,803,753,198,423,276,801,938,967,892,940,74,932,983,579,693,46,379,717,898,700,560,716,845,986,61,376,714,134,874,917,554,680,855,729,272,431,528,683,518,198,647,138,580,584,460,379,22,182,683,30,612,969,168,272,485,188,635,615,271,349,329,499,763,567,654,548,874,187,580,297,514,560,469,787,4,514,664,393,86,884,877,359,486,62,19,14,484,830,827,270,6,505,536,370,581,978,18,628,551,327,765,712,678,874,317,777,647,689,899,222,466,123,38,74,241,425,768,676,350,196,961,926,32,383,589,779,816,883,575,650,542,915,873,674,335,430,358,860,15,341,484,865,684,60,803,146,997,47,176,19,245,245,129,975,636,302,408,644,827,629,639,125,697,3,178,477,333,841,669,654,250,71,933,270,26,4,482,191,92,45,807,363,935,968,610,338,593,459,369,701,818,143,854,699,912,882,414,295,502,123,945,91,190,650,792,315,973,452,925,935,621,6,43,112,821,716,122,811,795,943,901,312,834,81,852,424,631,166,359,360,370,905,303,214,200,915,533,396,182,713,177,714,984,878,173,888,512,780,400,105,592,60,951,476,198,457,38,338,72,413,330,151,136,762,124,590,427,694,914,118,269,936,553,552,372,755,704,761,267,948,944,269,228,272,133,389,664,75,843,274,212,923,90,271,105,548,570,469,960,783,809,809,613,765,243,619,438,108,598,150,899,112,879,783,617,919,754,191,533,861,472,121,718,683,282,64,343,947,662,79,644,97,731,707,47,339,861,765,805,891,837,720,313,693,148,727,724,494,815,842,236,516,255,933,496,560,846,556,519,304,953,845,270,149,376,932,519,98,552,227,331,951,583,773,241,867,765,839,705,456,252,642,851,396,324,898,582,859,734,925,406,738,208,683,44,61,298,680,654,969,295,787,48,834,114,811,693,331,702,731,332,755,789,634,169,343,827,553,850,397,357,725,583,695,934,5,170,904,48,20,153,555,492,410,446,851,371,687,24,243,730,193,416,850,498,578,33,824,94,0,604,921,347,428,598,728,657,950,224,576,631,926,429,986,153,638,49,996,66,53,179,441,461,175,905,988,501,385,823,47,150,955,393,449,59,345,400,684,745,660,720,471,689,451,341,733,695,415,197,804,169,771,666,570,274,108,587,492,165,351,35,5,506,337,839,662,681,453,514,261,276,65,252,111,702,220,947,884,940,390,407,703,972,979,645,225,509,38,877,528,894,696,411,232,851,920,881,174,511,671,464,570,884,545,395,226,487,582,987,324,371,133,590,906,75,605,754,320,981,889,34,253,590,451,273,542,717,149,373,496,312,17,147,743,112,764,993,92,841,776,158,143,275,243,834,298,852,20,442,988,189,855,860,541,3,969,159,978,572,658,895,568,911,309,717,885,675,918,208,937,584,470,880,969,227,22,835,555,634,822,33,158,576,465,257,508,644,286,544,404,368,876,595,775,144,673,60,671,34,142,970,931,598,339,166,967,530,14,829,695,529,821,807,8,476,451,839,59,613,358,577,611,585,644,798,791,725,244,15,790,152,410,512,475,113,176,400,571,744,32,743,855,89,70,836,133,972,519,579,552,266,496,293,51,695,917,205,556,635,697,157,949,413,759,574,147,835,878,945,814,233,750,156,295,822,451,861,360,390,963,936,41,242,486,182,929,229,387,781,29,426,569,503,396,800,604,116,513,789,394,887,518,157,713,505,524,369,254,265,810,612,212,794,596,334,718,971,503,253,696,72,21,558,259,337,912,635,886,79,235,457,944,804,484,10,355,380,320,361,101,198,200,859,102,876,459,915,142,239,857,823,905,351,382,639,133,165,135,923,378,127,373,634,485,621,483,296,931,88,389,178,970,396,643,846,436,235,992,775,455,323,539,468,848,158,378,858,767,964,295,599,230,307,874,361,645,440,469,13,123,71,593,567,81,695,838,412,229,27,662,57,739,535,246,949,192,524,917,977,718,569,493,650,215,250,971,475,419,625,473,820,637,782,43,669,29,448,105,854,542,287,768,180,399,53,30,414,571,79,356,31,203,645,673,211,249,780,668,642,403,756,808,493,544,634,709,654,859,191,743,427,229,251,205,322,124,30,664,205,286,900,262,902,739,247,627,712,192,580,929,639,835,207,485,691,382,596,672,428,379,155,450,30,928,565,50,411,598,490,75,862,194,494,159,789", "469,439,643,442,370,805,181,302,248,492,281,265,492,295,254,728,896,223,911,214,197,391,650,609,867,741,220,513,969,177,586,459,947,65,223,571,952,21,349,288,192,769,169,476,976,259,481,690,408,38,148,289,937,143,997,716,345,96,301,666,890,256,369,865,409,297,120,884,189,555,482,158,619,803,689,893,573,716,921,418,556,939,545,189,266,832,395,844,977,705,256,57,749,385,614,371,511,519,585,791,892,368,526,607,226,754,724,19,229,380,433,893,805,714,577,805,913,311,822,830,178,725,751,701,922,976,288,250,348,169,503,151,435,860,789,405,89,247,166,41,817,720,100,341,26,909,626,630,72,862,104,146,215,90,843,454,404,143,514,401,178,848,871,800,967,931,689,291,206,700,319,370,652,28,431,838,257,882,481,377,1000,713,511,490,758,557,799,82,258,604,156,26,542,494,877,905,278,186,92,637,507,620,107,702,732,66,854,410,42,398,459,216,439,425,609,310,670,397,615,354,929,599,365,75,527,444,784,825,796,580,253,473,491,824,895,745,476,153,137,623,799,797,408,957,91,700,931,431,543,371,659,826,479,783,727,384,566,49,441,97,774,174,837,544,833,738,789,351,880,565,236,166,847,956,879,809,983,994,696,857,353,104,769,447,510,717,934,556,803,179,550,888,63,594,331,453,807,918,986,30,705,177,493,736,439,539,270,203,681,612,929,511,283,445,549,686,861,42,515,837,86,796,93,659,86,198,719,788,274,787,260,995,60,774,590,126,964,340,197,867,751,670,92,776,862,178,757,861,819,893,569,786,249,726,521,223,292,470,347,310,105,573,952,657,482,205,752,183,290,146,672,509,466,701,187,327,703,138,54,940,194,878,581,928,566,409,690,596,165,80,883,470,281,207,329,707,183,880,204,207,399,437,503,99,463,698,284,282,454,611,90,703,308,190,511,147,475,967,750,381,366,20,867,588,235,618,320,60,859,792,844,908,436,114,87,22,717,988,751,451,201,63,790,926,436,734,95,56,367,143,257,914,432,846,971,89,626,303,903,206,949,864,428,790,277,111,428,360,209,713,547,518,476,539,827,245,205,858,692,779,526,475,378,357,604,0,629,87,673,282,287,505,507,440,363,718,785,369,883,544,944,626,167,579,175,390,130,537,515,16,734,121,308,683,478,482,526,716,767,499,56,18,77,659,168,294,531,542,689,823,843,966,831,347,341,350,808,519,963,62,855,397,569,209,556,778,619,364,637,219,180,572,960,276,657,908,389,6,235,840,321,288,439,863,425,778,80,516,427,222,986,622,702,913,391,138,213,667,597,279,409,794,75,509,959,992,903,641,987,19,857,298,678,748,715,126,760,538,192,810,470,581,389,798,355,664,154,776,489,121,965,644,691,419,769,676,105,973,721,550,235,178,809,904,355,830,978,913,41,23,910,643,787,776,199,658,67,530,871,371,305,796,61,411,73,464,808,978,631,809,390,717,167,429,780,254,872,444,86,136,979,129,309,254,847,940,172,852,165,167,361,685,381,666,27,490,363,461,770,922,299,245,824,526,917,888,202,528,389,542,56,232,471,251,372,573,432,155,740,65,43,173,887,678,214,750,858,812,945,726,164,288,109,145,127,283,350,449,341,157,915,757,289,376,709,432,319,598,399,250,896,16,225,82,902,384,991,216,949,949,761,373,443,760,196,177,108,126,678,512,960,953,458,236,172,558,407,478,785,792,124,58,123,41,258,414,875,399,17,208,704,135,351,886,981,151,524,127,832,687,104,804,887,445,383,360,532,312,243,211,795,558,981,36,959,21,608,695,34,569,592,556,209,880,339,438,846,465,294,645,346,228,402,316,430,812,349,714,175,29,551,386,110,433,416,924,814,905,781,994,169,163,736,937,385,791,501,576,696,113,350,670,333,805,236,733,696,312,119,390,464,153,604,998,875,568,502,516,297,490,445,530,751,428,554,389,443,716,283,653,117,664,538,765,792,16,586,708,339,888,383,217,974,209,275,312,187,390,17,844,765,158,182,49,760,468,921,271,28,800,975,188,323,557,12,995,303,301,182,331,345,643,314,189,446,328,162,928,811,908,624,748,534,383,903,289,67,211,725,116,61,435,485,746,367,281,545,119,239,311,881,866,63,701,612,185,11,884,187,663,430,162,803,33,528,464,377,669,222,805,90,606,68,299,92,68,875,38,898,760,655,369,609,483,482,449,768,912,160,328,524,525,564,53,231,732,445,789,994,757,491,48,230,6,235,385,647,978,712,144", "171,966,299,410,164,144,460,219,12,910,529,732,733,650,230,907,329,323,81,119,995,810,637,883,625,803,915,710,160,823,114,425,6,722,921,931,501,849,215,578,409,658,321,689,875,501,165,568,51,887,218,145,528,832,825,321,347,385,238,437,322,464,196,515,852,439,712,153,880,749,182,724,65,986,802,650,345,855,43,42,785,799,28,505,293,444,196,836,510,133,460,336,175,271,200,758,451,726,359,340,111,51,743,835,637,656,907,806,807,939,254,873,607,3,924,320,175,614,412,292,358,470,793,733,367,635,9,77,601,647,223,730,794,345,966,896,611,491,100,209,112,964,839,577,37,282,862,195,411,32,636,438,381,249,521,7,946,781,566,976,607,937,835,758,269,386,511,825,901,393,878,859,870,904,25,263,866,130,649,139,842,125,256,337,307,160,950,947,86,943,819,533,348,107,876,291,231,345,403,632,522,976,764,233,57,739,206,356,334,626,552,448,89,67,946,194,873,162,712,631,364,13,611,498,493,988,184,242,493,224,794,84,759,858,918,713,937,476,433,994,409,614,257,337,183,299,406,708,509,95,275,370,324,128,433,6,617,847,15,166,115,370,678,873,467,761,836,17,859,18,428,600,840,608,639,603,890,993,777,642,388,247,550,159,858,565,974,936,317,967,842,821,260,468,355,454,962,783,558,614,615,617,741,573,859,192,205,669,689,662,581,148,106,501,18,535,730,210,102,423,47,298,821,795,972,481,900,253,915,946,132,372,782,546,887,907,555,39,364,599,874,685,471,919,610,186,897,764,971,571,129,467,355,946,506,567,999,818,476,964,939,946,638,982,933,535,561,903,288,239,408,851,600,40,495,315,97,470,68,618,719,444,303,655,872,673,910,92,346,869,533,548,999,892,87,863,387,446,808,859,395,522,673,274,297,850,97,207,105,526,680,146,276,735,315,655,216,127,440,260,821,641,737,993,29,349,246,161,429,200,701,423,210,946,974,246,910,829,381,325,847,528,922,520,862,784,575,23,371,466,890,835,803,455,683,752,753,243,992,958,400,608,347,979,80,406,973,517,280,607,371,630,184,3,73,315,876,310,4,76,387,531,716,476,921,629,0,506,705,890,534,482,796,254,111,644,493,95,485,728,549,634,502,312,465,656,531,57,858,670,107,658,318,339,667,269,841,689,291,81,142,76,60,602,86,621,632,168,636,499,906,498,839,67,168,76,404,158,683,860,547,455,282,944,988,426,820,736,320,635,115,518,441,437,886,109,693,48,660,328,575,235,22,160,374,176,15,136,682,10,686,781,754,818,670,605,547,435,790,954,878,921,995,58,621,266,989,82,396,487,701,556,961,801,15,87,778,538,766,917,70,893,516,77,46,756,748,138,290,950,796,664,659,491,582,851,298,766,650,691,377,563,723,832,269,413,918,874,966,959,59,599,746,43,623,823,698,899,407,527,231,698,91,269,355,224,315,795,274,131,986,618,253,271,344,668,98,673,194,899,341,831,415,378,296,990,444,839,907,686,127,170,845,274,885,656,229,721,346,458,221,566,526,973,45,659,683,241,894,759,376,430,445,815,344,241,62,286,733,818,338,951,931,132,76,286,453,361,364,994,302,16,567,385,288,966,473,325,900,236,792,54,658,602,694,376,985,946,483,832,973,994,440,274,110,306,374,213,129,308,737,160,652,338,109,713,280,240,34,753,33,420,695,917,641,912,299,175,178,749,974,275,89,802,311,969,654,507,687,941,531,265,421,604,196,256,219,812,743,52,264,929,346,212,46,271,965,662,738,101,980,70,969,912,4,960,787,144,58,666,424,181,970,260,724,242,273,498,401,925,623,603,98,319,374,541,280,356,561,50,549,234,318,886,772,703,243,793,710,56,472,214,847,739,125,378,727,746,578,77,167,864,821,584,629,807,54,517,145,366,698,332,967,756,599,942,568,750,108,147,638,86,484,606,908,181,959,998,534,963,412,268,790,11,841,652,589,805,677,323,441,29,142,683,138,142,909,174,499,57,472,778,250,904,836,255,817,861,703,613,352,60,883,899,6,483,710,251,363,831,491,913,729,300,621,838,811,80,449,198,823,790,122,80,16,845,960,613,87,397,282,11,317,450,336,687,165,81,913,718,823,907,575,23,327,509,556,609,474,50,444,352,635,1,591,526,963,388,306,144,822,789,263,282,902,495,716,405,165,163,562,756,926,911,710,621,162,967,234,291,345,650,855,118,419,870,897,526,300,213,388,566,493,151,518,794,24,248,450,517", "993,386,857,74,925,140,640,812,455,410,839,313,921,790,324,334,929,842,319,277,408,814,301,274,776,47,797,726,562,115,946,962,215,403,540,104,602,161,311,913,321,410,814,264,499,118,100,740,598,508,744,99,728,165,688,951,157,273,961,685,241,280,867,45,858,285,703,334,935,896,875,698,486,126,605,313,69,777,727,994,786,783,738,382,516,77,98,817,625,463,728,315,982,336,691,616,554,171,401,531,161,344,564,752,828,598,35,675,239,966,774,612,173,778,580,784,105,713,418,948,805,127,816,558,737,962,975,521,219,646,504,243,472,305,876,18,757,352,545,303,901,740,714,654,587,341,20,115,25,879,545,412,62,219,982,223,303,703,445,73,681,67,816,928,116,117,659,235,638,515,61,772,681,931,855,126,32,131,514,338,555,744,467,870,385,296,57,786,618,991,295,732,873,993,699,17,904,634,20,214,470,667,847,780,846,659,948,403,51,939,824,223,644,292,727,597,241,916,47,252,579,992,181,887,100,898,349,810,937,491,201,390,178,27,54,439,81,634,966,405,330,83,523,409,916,431,35,657,955,148,417,931,635,414,846,170,304,40,345,884,572,636,896,824,661,979,10,490,201,980,148,805,107,415,459,552,243,515,955,681,443,450,299,575,330,728,365,82,201,576,992,385,650,894,958,946,410,860,828,574,770,5,871,347,448,457,15,993,947,3,418,231,632,870,417,177,586,333,623,656,186,77,533,260,601,963,180,291,185,515,177,51,935,191,324,867,76,725,614,160,461,147,197,396,38,356,184,375,781,748,699,516,873,193,204,390,500,858,616,911,375,747,817,479,639,500,26,170,686,482,888,903,404,737,962,45,488,252,682,930,211,509,52,342,347,175,320,482,274,875,157,285,802,674,109,106,9,913,641,533,129,360,239,225,454,205,314,289,966,448,770,801,454,446,933,394,370,205,914,834,863,33,443,552,808,507,257,105,341,950,636,819,492,936,790,192,316,142,988,884,80,313,681,264,976,222,153,963,796,436,666,20,700,149,132,970,461,575,80,714,104,291,664,222,947,86,270,759,995,865,642,712,184,972,930,468,160,713,229,634,850,561,784,440,347,87,506,0,855,994,148,573,199,288,440,333,38,60,324,873,640,83,142,774,530,603,474,100,117,112,486,16,563,890,976,444,188,929,933,574,107,835,871,960,745,346,180,5,931,307,378,523,94,614,460,541,592,805,935,994,538,829,512,18,489,258,702,915,935,322,135,862,808,505,489,205,241,285,984,77,262,677,952,611,406,980,547,52,280,545,911,877,839,839,972,504,158,591,765,139,148,115,945,784,618,105,802,688,23,975,270,251,394,696,812,732,208,565,561,141,544,964,608,490,861,750,670,755,823,645,863,974,225,624,240,706,742,763,165,847,164,834,936,454,428,47,721,85,117,342,80,140,676,354,684,986,639,325,515,939,772,772,588,624,918,869,709,266,520,190,990,42,754,451,779,925,514,345,58,772,191,722,715,512,743,985,716,505,28,448,190,44,232,166,617,225,372,844,712,955,228,132,914,231,946,257,860,41,23,262,436,201,5,470,964,829,585,3,562,534,983,381,136,852,921,816,98,802,263,671,396,547,359,240,454,759,294,649,127,591,964,977,440,758,22,486,660,535,106,206,579,973,144,667,736,783,803,926,11,849,632,672,210,606,797,749,713,633,247,83,862,852,398,205,149,156,718,509,527,301,150,384,870,64,142,194,431,850,247,316,57,795,397,793,884,210,651,652,711,620,349,168,288,647,432,683,436,539,284,275,900,367,687,288,952,511,229,854,682,786,152,186,86,683,731,462,120,624,82,892,911,627,848,431,711,561,808,309,770,136,28,172,953,2,207,892,663,932,360,745,252,427,874,322,31,284,215,842,707,334,813,67,97,411,238,865,262,687,226,825,85,786,673,947,256,287,29,723,389,962,407,226,215,37,456,17,869,13,359,569,207,908,852,370,267,803,485,268,23,134,877,35,986,568,400,692,156,360,912,932,755,709,446,730,598,658,169,368,752,600,542,181,394,608,181,483,143,821,752,674,5,231,138,412,410,174,483,252,801,472,377,842,715,552,19,549,192,241,150,859,213,832,909,573,132,652,281,783,691,306,555,21,291,746,348,798,796,677,544,794,826,519,90,37,290,998,526,175,855,444,889,761,149,271,811,830,353,875,365,196,46,304,117,869,901,335,601,780,813,511,60,882,469,670,938,632,825,655,875,50,982,370,928,947,342,548,500,85,290,730", "886,512,539,411,454,433,557,514,171,432,90,38,274,368,176,722,462,920,741,717,118,550,562,111,350,279,447,610,24,461,758,251,791,420,689,202,364,343,182,392,334,187,262,537,783,735,426,717,52,395,703,682,796,663,631,572,296,702,463,833,181,469,470,186,210,978,655,288,750,926,385,889,633,985,258,715,545,93,635,206,311,162,994,535,517,730,175,441,485,574,480,545,111,948,140,606,401,288,814,392,935,448,370,338,877,134,975,978,201,335,402,902,351,612,373,949,668,637,138,810,576,471,681,162,430,787,715,263,386,173,819,189,511,110,794,141,400,70,39,345,256,386,744,379,26,752,710,691,373,589,204,774,983,51,347,360,309,368,83,371,235,722,523,420,633,115,320,114,556,445,529,192,45,891,884,993,12,536,234,229,52,574,898,556,903,308,952,657,670,752,427,175,921,226,755,165,699,264,493,815,528,455,458,400,840,493,564,21,230,100,892,543,541,80,136,20,623,443,51,674,165,727,268,644,325,141,149,615,100,835,724,560,877,411,293,741,744,162,557,297,719,637,713,329,841,844,646,455,214,366,805,917,226,404,45,293,350,808,916,318,923,941,558,880,948,103,881,140,344,236,378,545,973,112,30,895,559,738,636,246,599,696,678,71,173,324,288,702,326,557,912,949,970,593,522,744,461,606,596,440,850,79,615,540,652,159,276,377,15,866,387,592,999,480,701,946,610,225,39,453,61,662,771,485,227,983,262,627,84,263,501,641,706,230,667,209,556,770,442,545,93,194,194,74,382,399,220,369,988,206,831,756,619,851,513,420,991,749,560,74,957,951,886,659,53,628,840,523,536,334,114,971,372,486,777,783,699,979,603,952,99,876,359,809,630,250,424,309,741,707,288,132,863,749,716,429,696,757,392,170,289,760,638,348,586,714,834,968,432,786,197,627,712,769,114,630,488,521,14,594,548,738,828,941,399,600,456,661,441,92,44,979,967,318,763,710,619,89,571,773,36,399,100,368,213,772,356,672,82,930,894,687,841,512,742,13,448,122,641,430,274,426,165,399,102,812,901,301,265,762,93,980,46,935,993,445,897,754,466,843,63,702,647,356,428,673,705,855,0,807,952,633,333,999,974,44,916,499,927,540,590,467,467,371,862,407,526,670,423,554,736,199,586,337,705,408,633,550,548,179,402,680,158,640,967,506,139,258,641,557,63,466,389,222,164,544,14,275,382,180,867,191,217,839,615,856,102,970,931,798,961,644,149,326,191,453,140,716,701,456,144,239,628,265,211,781,776,178,254,519,522,550,536,420,671,801,564,63,415,495,284,255,987,116,531,966,524,278,521,286,533,553,490,988,294,111,644,551,805,155,230,54,525,116,507,444,626,20,300,800,933,983,206,930,400,914,332,740,424,188,341,842,221,810,256,348,713,304,306,958,731,548,916,22,361,311,183,14,620,388,526,626,676,997,961,299,121,71,524,271,133,486,439,479,370,76,988,730,217,704,957,122,477,210,50,407,704,231,615,574,167,43,36,807,811,549,203,591,802,439,52,373,574,172,849,218,69,317,1,64,370,965,205,38,788,251,515,18,168,456,959,690,447,742,768,839,464,296,86,374,568,946,869,916,447,754,397,809,481,73,376,361,647,477,574,130,723,674,699,825,810,283,814,126,986,36,482,93,577,632,401,411,422,905,282,384,97,313,812,98,911,286,616,696,209,669,505,705,422,70,477,992,574,28,779,558,236,796,621,981,174,52,575,829,340,30,815,149,955,960,432,243,806,922,467,405,282,462,265,74,8,220,894,150,405,960,376,649,127,770,912,237,642,854,645,851,903,222,48,815,529,316,292,321,537,358,997,441,365,573,277,610,40,831,632,709,447,653,26,861,813,972,530,795,306,883,581,137,632,260,471,407,258,543,321,458,832,180,931,387,283,620,496,923,174,212,405,241,586,163,568,284,282,107,235,88,440,900,882,417,500,923,993,494,196,477,229,661,24,33,646,981,478,987,365,880,661,356,470,483,772,678,330,923,501,317,399,980,835,626,982,18,918,362,589,944,790,44,541,393,951,242,390,852,395,648,401,33,549,187,989,495,556,716,297,907,397,527,737,783,845,590,20,426,694,549,292,661,629,59,810,227,159,585,9,21,796,324,253,628,521,685,110,974,314,372,146,575,632,496,401,822,287,709,150,322,801,668,365,793,262,76,155,222,49,792,869,487,818,759,721,655,696,162,715,690,492,797,166,891,986,117,503,945,813,198,523,329,66,647", "130,521,210,459,333,396,566,256,23,339,670,963,280,859,738,565,104,200,516,845,931,72,898,661,165,216,827,520,386,780,613,452,151,204,87,946,564,474,896,608,55,28,266,986,101,874,482,177,535,940,802,833,450,538,427,233,109,164,303,44,874,181,179,154,78,550,597,483,785,410,664,418,651,751,203,835,809,74,871,476,908,461,645,555,681,750,252,291,768,650,964,169,437,454,890,829,432,893,596,567,629,978,99,303,475,411,278,816,515,64,648,412,298,994,197,655,121,793,381,798,188,773,44,729,848,717,700,85,393,238,202,437,664,889,649,298,152,485,717,104,949,172,379,991,336,737,317,279,463,993,236,203,418,265,89,862,438,725,272,418,17,150,872,408,499,588,985,810,393,253,390,531,884,13,799,596,866,515,971,160,955,255,141,956,845,755,122,556,878,701,92,334,617,364,665,421,861,421,28,221,663,818,263,93,336,354,111,500,150,109,588,158,361,951,968,964,900,980,141,242,944,437,224,97,184,305,423,589,767,713,195,227,648,40,420,700,519,30,945,464,294,95,749,307,246,93,621,535,949,977,433,960,828,986,672,217,376,379,561,20,284,878,117,341,800,622,929,849,309,895,291,468,704,201,331,948,403,540,386,503,615,21,919,977,823,470,452,523,671,200,411,761,432,921,441,527,981,845,735,644,784,549,35,31,697,428,211,849,522,664,504,703,212,251,128,130,393,896,605,108,861,22,608,882,55,876,447,641,395,449,250,323,834,763,67,267,141,648,342,411,344,433,236,946,823,962,520,66,38,992,341,432,439,453,564,571,416,496,416,174,332,648,876,402,543,775,549,268,707,974,561,938,403,6,618,873,300,868,233,89,955,994,157,338,126,597,791,648,953,202,540,598,491,347,495,499,98,97,887,913,740,744,169,67,52,192,742,516,386,636,420,993,376,573,589,503,900,606,273,981,601,484,907,35,845,752,869,748,511,354,917,830,584,665,969,698,61,369,898,199,233,699,124,77,681,848,817,671,688,2,227,903,6,994,51,131,65,25,450,747,547,676,154,566,270,267,911,529,285,539,958,505,513,571,924,884,805,185,125,217,751,316,49,966,598,282,890,994,807,0,761,662,969,35,332,598,50,674,910,873,904,21,287,656,143,923,89,244,326,84,127,55,968,299,285,304,34,662,491,934,978,790,361,650,270,822,926,97,232,182,618,988,619,107,761,971,299,942,863,273,773,525,862,591,894,12,435,675,117,396,528,970,970,142,230,771,510,623,347,171,34,820,921,639,716,832,16,88,356,212,190,159,742,901,232,966,717,888,820,227,884,507,708,322,216,812,672,204,122,773,577,411,135,145,366,986,783,618,365,292,381,931,585,605,342,91,539,213,8,195,855,916,397,723,955,610,306,479,869,265,192,116,626,494,504,104,213,760,423,452,665,236,340,819,780,609,741,704,937,207,603,400,24,31,646,971,81,887,573,157,329,296,101,173,60,243,913,461,851,484,320,454,24,448,872,465,389,847,208,628,257,823,634,957,511,94,689,379,758,96,161,597,735,444,739,824,739,474,951,53,122,690,95,973,244,506,417,294,642,196,876,190,290,324,326,163,785,709,966,757,171,197,371,254,593,690,428,276,701,886,476,760,964,684,212,612,426,145,387,952,821,17,634,90,633,815,263,826,19,169,25,954,919,120,967,89,449,27,291,457,912,366,139,662,334,785,235,706,214,192,965,82,109,885,672,678,220,359,505,818,10,290,311,560,91,592,652,904,591,113,798,751,495,910,995,137,726,693,311,1000,543,680,484,171,671,203,2,60,72,617,475,588,954,820,3,614,964,80,468,74,286,325,436,867,640,137,39,263,904,173,447,810,105,886,653,782,196,819,428,682,944,755,557,812,932,392,847,155,729,1,292,846,734,300,957,342,498,919,691,237,408,786,438,644,903,571,675,72,690,573,438,186,978,504,546,314,937,59,37,347,249,569,202,204,266,979,347,295,887,124,307,776,539,880,61,211,956,354,273,131,823,850,547,443,130,678,288,406,39,93,304,564,927,71,657,866,196,888,213,461,839,266,660,658,793,815,659,991,477,612,969,688,967,544,88,71,538,755,559,738,621,735,95,918,914,470,868,922,24,764,677,121,281,909,177,342,933,384,919,709,546,918,151,709,111,143,65,604,597,129,97,193,429,400,964,930,710,475,200,855,553,840,363,735,800,22,361,778,480,598,249,546,940,779,581,554,886,783,604,272,952,513,121,887,719,417,972,486,589,100", "871,589,559,89,458,516,9,41,770,627,442,361,796,246,720,18,230,735,940,197,894,76,669,778,393,493,681,78,911,548,303,910,428,795,933,168,26,373,523,320,247,156,33,249,809,261,383,430,251,197,739,729,968,972,171,35,230,676,946,738,855,824,705,326,904,723,930,745,420,873,708,475,593,330,341,765,829,872,858,162,497,629,620,500,508,875,224,714,806,503,408,346,17,842,693,525,720,615,168,283,740,490,439,961,790,80,425,517,260,477,642,483,536,455,119,33,641,547,779,42,48,531,335,69,486,669,268,671,12,282,376,27,671,854,346,847,120,398,96,19,804,772,964,844,214,730,487,971,100,382,286,499,937,353,613,686,424,179,998,272,168,852,359,653,272,220,461,666,622,714,457,76,515,384,634,77,220,862,232,980,937,766,347,725,360,321,560,148,135,193,248,814,153,430,671,641,917,217,177,459,734,626,479,649,225,73,361,763,505,463,550,51,299,638,717,24,114,415,164,799,362,35,809,161,578,503,957,349,604,521,497,401,449,872,373,718,140,577,515,292,741,622,516,450,129,527,482,999,393,885,608,610,401,865,240,979,854,280,160,902,308,555,906,662,135,365,354,841,315,516,338,46,238,389,922,657,31,33,128,863,157,156,136,826,936,254,868,117,956,108,351,873,275,574,510,146,840,943,812,509,31,852,827,20,106,891,241,382,30,421,963,996,414,772,739,525,121,753,398,980,386,155,575,857,369,284,54,957,465,724,467,899,724,698,947,500,658,410,926,691,336,563,181,330,725,299,255,841,645,737,101,792,999,208,608,196,592,732,587,725,402,173,239,366,775,831,652,148,388,337,765,820,564,807,741,464,871,445,414,961,339,835,453,620,375,596,452,22,177,887,390,474,866,224,510,663,797,441,326,675,512,407,613,793,272,691,701,509,857,47,258,883,748,395,309,95,301,451,365,366,697,296,510,294,23,9,279,676,997,263,471,803,143,741,242,674,442,483,946,500,588,317,494,941,212,777,770,798,980,508,417,380,415,317,794,339,858,993,495,801,669,271,961,221,224,18,90,635,58,277,146,334,254,732,717,847,651,941,634,798,696,53,687,728,728,287,534,148,952,761,0,515,999,694,134,280,882,746,15,294,56,448,451,650,616,6,391,524,456,124,473,963,348,686,216,592,901,178,715,890,354,46,691,173,840,798,512,512,898,305,319,553,845,28,138,668,16,361,31,424,644,825,565,597,485,147,927,293,551,660,911,154,105,584,636,299,51,420,559,411,607,577,414,271,653,635,247,941,56,349,443,727,920,787,559,424,460,164,972,835,220,19,702,533,540,84,798,233,521,562,310,481,491,428,614,345,753,474,554,993,529,917,167,414,603,585,123,873,175,647,899,203,757,840,284,124,184,599,14,501,896,841,903,831,537,343,86,424,655,233,837,336,961,74,121,787,87,397,484,589,53,630,667,994,32,822,433,268,67,961,431,599,285,351,385,136,513,767,97,171,717,826,479,785,450,712,838,334,603,963,465,27,384,518,403,652,901,675,869,520,816,985,776,589,881,272,396,853,571,319,161,602,251,494,708,618,903,689,216,162,816,648,14,632,261,244,908,179,179,548,589,71,921,919,986,406,929,243,862,201,452,34,219,440,359,20,672,144,839,131,659,469,987,257,5,246,236,780,652,523,411,556,91,664,227,376,321,476,355,251,16,686,684,372,898,110,64,561,668,978,338,592,241,665,903,756,199,575,599,557,50,544,548,421,387,669,105,635,949,970,834,70,614,324,791,9,480,790,168,314,550,969,779,791,972,669,30,723,829,348,908,98,277,580,602,927,509,537,452,149,397,424,843,776,879,613,448,669,567,941,734,591,11,630,828,205,906,624,937,582,985,291,979,249,717,383,480,232,824,796,960,746,895,599,534,902,469,158,312,236,349,161,707,818,339,361,689,527,435,917,638,128,344,485,394,327,173,368,227,504,841,128,149,72,859,494,66,285,237,924,263,544,659,876,783,213,26,679,328,20,249,214,191,845,426,118,112,189,304,49,515,268,237,520,135,693,396,402,402,102,1000,713,404,885,89,178,277,411,225,816,481,407,473,403,588,889,212,720,361,789,917,438,500,971,941,934,964,396,159,132,708,139,478,62,210,807,262,92,788,597,400,38,544,330,632,581,866,850,542,236,955,603,504,22,135,849,900,738,209,464,491,937,301,852,162,1000,757,161,104,558,561,314,148,477,624,171,814,679,978,970,500,992,844,72,504,537,19,601,986,889", "752,218,670,577,739,367,235,821,940,935,842,431,541,106,472,895,358,751,520,513,293,829,697,222,431,222,707,530,550,268,879,986,919,296,764,940,84,807,460,978,134,573,667,947,497,643,579,624,748,678,60,113,814,830,403,874,641,940,492,728,475,323,173,206,757,636,259,29,986,962,604,249,392,853,882,397,887,207,239,965,923,117,885,431,358,605,852,594,832,719,215,780,587,372,376,781,19,253,523,977,806,970,724,658,871,768,35,412,40,307,36,257,2,548,864,173,255,679,309,325,188,512,640,66,528,308,310,458,196,331,285,141,127,771,437,317,264,562,362,19,709,110,944,999,678,291,613,767,619,454,537,640,82,462,499,838,128,282,515,426,725,123,910,501,386,661,214,952,674,722,186,406,7,470,820,713,39,495,292,184,244,598,30,675,228,656,757,124,978,191,907,639,845,136,915,896,803,207,94,604,562,891,283,683,250,48,175,56,447,542,146,413,592,776,998,940,594,794,175,472,943,59,999,925,705,218,990,313,577,467,772,29,558,209,61,643,682,70,798,375,514,261,460,951,541,827,891,520,588,424,827,55,691,161,101,592,184,841,172,50,293,904,666,640,35,516,63,631,26,337,80,917,514,225,654,976,798,126,675,140,240,394,590,970,213,700,265,997,563,49,334,7,155,876,115,954,33,574,619,814,354,385,131,588,388,790,542,800,738,373,315,899,306,53,181,194,737,788,651,672,803,198,442,594,490,21,769,265,67,309,892,688,412,943,754,185,626,374,770,21,215,507,577,378,400,332,915,686,733,205,895,750,961,691,508,140,216,523,415,544,223,618,173,621,857,739,188,175,531,404,765,383,625,285,61,707,325,320,828,345,551,920,955,743,627,592,290,11,240,309,558,558,420,557,420,137,916,855,79,684,825,2,240,460,652,148,160,207,277,31,799,132,959,807,697,249,537,162,213,617,156,978,814,92,895,424,709,617,948,763,399,937,583,328,605,691,342,447,403,298,699,295,389,166,353,878,25,683,720,64,619,83,119,641,49,944,403,108,959,195,455,227,402,740,722,799,82,162,331,236,727,429,460,205,696,99,319,536,472,930,732,393,564,319,657,505,482,573,633,662,515,0,152,26,905,884,949,669,486,273,47,585,529,59,66,743,98,589,698,514,125,882,130,686,536,364,320,771,947,694,162,975,578,837,727,872,325,910,730,344,749,210,984,938,908,307,693,177,339,754,242,459,339,443,812,446,452,51,468,937,151,712,224,720,184,14,263,797,815,482,853,581,271,646,460,120,382,484,440,49,561,93,337,764,589,19,347,805,732,10,46,756,691,328,31,937,770,253,672,233,101,488,746,661,893,953,884,616,983,125,726,184,322,491,57,306,699,221,373,761,323,677,625,607,773,504,624,763,498,992,399,787,270,293,772,133,581,810,307,493,129,940,363,473,222,548,462,323,620,861,223,940,551,696,278,459,198,801,266,423,476,67,25,20,487,44,502,934,873,191,886,941,292,657,215,133,196,172,795,102,728,866,677,429,722,616,886,82,538,155,31,195,208,418,330,666,688,327,764,397,322,567,428,677,810,66,647,199,433,856,968,148,131,723,65,94,894,803,591,562,251,202,659,401,456,426,333,510,73,792,809,12,46,769,99,238,416,616,817,604,454,62,13,563,733,883,874,563,20,477,345,383,594,294,142,930,149,496,171,41,902,506,694,656,116,742,47,250,471,877,733,169,699,493,149,539,274,655,76,765,589,298,280,556,711,820,412,870,486,833,504,546,838,589,400,716,128,405,610,483,967,408,997,877,560,608,769,774,219,410,995,21,173,707,569,264,878,960,172,604,601,416,279,549,949,791,972,592,916,590,721,258,953,164,62,868,878,509,112,67,722,636,201,635,952,432,692,570,223,163,695,307,615,448,379,387,728,553,301,336,168,781,926,197,549,696,179,88,260,440,543,591,902,85,799,708,520,249,118,84,425,617,162,81,547,822,253,221,907,176,657,103,326,493,431,627,899,331,311,916,54,778,636,422,533,829,592,855,721,12,815,693,822,298,636,739,874,180,851,18,12,403,880,799,392,632,643,362,522,85,553,92,313,319,374,769,195,778,783,810,608,6,919,505,562,966,581,276,246,893,118,352,124,113,315,937,657,408,453,432,917,209,717,686,667,37,579,681,61,792,502,529,788,618,202,675,652,319,100,184,732,616,108,717,386,359,503,313,569,502,778,807,552,364,222,777,638,396,184,511,765,917,479,241,863,619,165,30,99,114", "217,481,477,969,15,764,410,398,972,499,65,537,402,15,523,851,485,438,758,892,65,69,560,674,915,238,923,684,299,83,753,451,539,447,262,466,576,225,422,695,618,746,89,947,703,629,803,494,71,443,695,346,538,514,201,472,371,191,716,83,97,729,874,214,943,692,755,949,838,864,659,665,169,399,31,681,648,841,734,568,257,616,169,361,105,568,627,972,894,514,178,45,165,332,886,227,938,588,898,276,125,296,954,726,697,90,175,368,531,206,531,982,648,549,484,176,405,420,216,621,928,546,919,516,941,933,80,949,542,740,136,763,209,516,496,794,525,714,987,831,989,605,696,364,915,99,296,759,826,240,307,862,521,940,74,725,56,620,402,655,268,546,471,697,985,242,379,713,552,180,34,781,471,751,29,805,314,294,302,41,405,226,611,307,14,225,649,157,920,340,46,458,328,981,337,891,717,257,741,417,422,131,100,985,182,650,955,97,59,512,228,150,927,114,890,476,592,866,281,187,233,876,31,585,839,481,971,63,866,450,418,661,801,519,392,786,674,167,588,2,97,328,538,161,506,939,429,614,80,954,955,34,81,209,171,161,911,656,986,73,952,717,273,97,787,683,571,233,310,121,478,881,243,33,237,677,628,804,120,921,666,641,722,157,528,139,801,632,647,384,532,332,484,96,899,185,423,511,704,61,592,964,618,84,693,252,171,833,470,490,815,100,308,803,965,103,726,923,664,166,189,692,598,887,886,321,659,282,191,601,314,190,384,425,74,125,672,796,476,414,974,876,158,152,989,789,348,975,18,43,642,927,431,945,230,981,530,79,233,308,776,391,482,153,927,201,757,734,41,698,677,825,40,683,651,13,898,232,523,469,312,293,493,888,803,942,910,344,949,997,582,202,522,649,32,368,717,877,716,255,364,396,484,304,704,652,218,459,212,20,61,554,620,749,80,549,375,3,114,619,854,864,910,134,922,371,254,698,978,634,346,734,387,460,247,442,560,476,600,412,897,362,151,569,783,100,869,583,150,369,429,47,812,628,995,851,922,675,728,979,201,83,652,100,954,466,252,963,908,438,638,787,609,686,261,372,115,384,56,616,87,643,8,762,950,507,796,199,333,969,999,152,0,398,432,353,692,948,729,813,649,679,1,615,25,946,173,833,6,186,175,948,735,360,952,507,247,18,539,885,888,760,924,895,783,859,119,143,260,471,262,462,900,31,390,910,619,640,440,185,631,862,413,159,985,348,773,236,590,34,882,738,271,729,549,379,499,658,146,289,198,19,367,675,279,848,299,218,930,412,928,559,12,967,834,868,790,342,156,405,601,265,746,474,967,370,111,810,584,684,583,950,274,772,498,936,25,659,474,706,473,678,691,588,768,84,854,989,93,771,102,636,858,525,722,511,813,944,501,692,388,304,727,199,360,724,209,875,413,175,419,782,358,641,458,177,376,22,461,593,500,191,872,629,841,544,567,948,979,66,730,116,795,393,16,920,265,55,350,859,441,358,33,931,372,222,957,179,725,242,242,356,898,550,256,878,821,619,372,263,781,314,381,916,280,588,592,55,610,460,989,109,395,974,104,106,8,63,86,671,836,277,549,261,655,503,536,529,281,873,138,855,573,138,720,423,121,200,606,317,804,53,43,646,565,233,141,117,898,46,341,823,225,800,395,808,748,268,870,251,522,647,104,536,42,467,971,595,425,382,767,699,564,310,755,34,965,976,764,989,350,701,327,783,344,771,197,768,154,824,68,86,535,466,81,94,154,844,612,664,997,257,46,23,978,718,414,507,468,312,461,546,721,870,10,899,363,354,344,212,36,337,64,120,220,883,386,958,24,263,931,501,311,79,355,670,869,53,55,481,759,806,137,987,836,651,958,813,162,361,309,459,416,277,910,988,211,481,585,247,878,900,160,32,722,317,381,547,345,726,414,633,390,62,623,385,510,442,642,698,839,266,650,180,239,633,296,376,867,260,313,72,587,968,157,701,280,345,75,808,294,956,220,110,45,207,329,7,854,526,597,547,183,11,276,145,359,594,937,572,373,915,134,389,977,928,317,919,874,201,923,992,744,42,870,836,775,826,124,14,646,800,420,397,141,774,682,291,484,993,721,91,577,717,309,167,4,554,763,910,767,21,310,922,502,306,186,994,462,164,499,545,590,334,809,384,682,586,352,108,929,303,873,97,224,592,303,864,490,314,381,235,189,958,21,671,37,614,316,650,610,367,884,674,792,720,878,675,795,647,681,973,569,279,717,917,22,49,180,922", "896,288,766,74,856,935,959,717,368,73,520,418,456,694,221,479,190,435,257,527,706,311,28,328,840,140,745,515,547,458,437,919,207,948,436,648,301,685,874,44,180,346,934,17,437,478,147,611,910,755,421,499,980,363,101,568,358,690,681,930,246,405,199,668,278,188,478,103,572,613,65,232,487,496,658,512,870,44,754,527,913,563,21,939,475,173,367,293,781,767,309,391,645,45,778,49,350,538,725,758,136,260,746,665,850,203,26,259,466,362,461,357,921,593,579,694,330,478,429,520,861,587,579,974,739,451,209,945,655,310,880,988,709,232,861,3,551,760,455,954,366,590,517,826,260,350,62,910,103,987,941,585,124,416,501,364,855,516,389,503,240,676,148,657,975,114,459,13,432,153,659,404,14,223,333,150,479,684,301,414,19,926,386,549,262,914,342,585,802,208,621,508,691,493,747,408,805,696,860,676,151,203,346,124,53,784,870,656,682,576,91,397,6,296,93,824,617,225,560,100,71,766,989,567,389,259,715,198,628,249,33,540,783,756,357,179,46,65,923,922,81,556,824,572,11,41,882,15,223,498,616,879,976,310,721,381,306,6,682,626,879,738,524,535,275,796,11,553,573,760,136,352,32,471,800,346,37,84,68,834,926,681,208,564,839,861,469,444,59,248,349,723,361,992,366,102,492,963,2,112,401,727,223,20,36,389,895,595,993,517,152,621,777,745,561,803,981,997,893,183,3,199,108,339,490,322,355,676,837,860,669,309,840,667,223,585,826,391,699,130,603,212,138,357,462,527,745,513,766,919,612,844,216,649,468,789,871,767,480,214,947,339,372,177,480,585,697,543,422,844,759,720,10,919,584,367,440,22,490,104,136,758,738,82,465,259,931,880,167,29,181,228,188,889,883,97,681,914,643,841,219,83,636,309,38,706,850,1,414,95,840,460,715,957,402,939,549,280,370,302,29,172,65,806,817,45,14,498,668,410,365,375,979,277,219,125,659,176,994,580,80,928,959,607,8,222,58,312,584,520,71,16,184,223,729,44,908,709,761,505,257,77,870,505,499,942,553,840,137,274,874,7,82,937,716,848,899,907,119,863,839,389,301,242,224,440,254,288,999,35,694,26,398,0,528,534,101,683,861,371,811,467,992,245,846,654,817,789,774,815,269,721,860,71,733,902,508,207,88,150,745,337,796,105,623,483,938,13,383,716,564,805,154,138,159,381,534,476,339,927,976,76,466,672,420,693,231,993,246,214,465,380,300,148,579,426,336,951,983,262,603,260,239,486,242,106,961,679,854,969,374,544,623,553,686,783,692,572,47,152,717,717,94,356,219,818,415,917,424,64,885,649,712,535,325,995,316,23,502,334,568,597,773,342,624,165,362,205,877,896,186,865,832,34,194,810,608,844,234,472,423,849,711,962,908,484,182,479,355,894,851,243,594,398,71,111,484,320,683,916,895,234,923,580,97,673,807,887,134,355,349,261,751,646,995,914,490,526,775,819,326,930,193,556,21,650,158,558,525,1,429,253,331,153,389,634,102,201,314,12,569,595,163,483,207,792,848,67,303,685,231,404,482,995,693,19,560,366,11,412,595,818,429,233,743,318,809,512,814,39,316,655,810,158,342,712,935,559,192,91,424,576,984,718,815,170,99,967,846,445,213,653,828,968,414,712,627,721,60,205,715,236,207,911,74,837,27,320,683,199,800,980,33,860,848,944,863,512,545,860,51,226,795,388,452,219,885,31,857,71,880,374,995,584,72,203,392,706,823,445,820,938,636,724,3,274,834,845,837,894,816,901,122,139,774,999,73,146,287,748,887,227,78,397,216,796,884,46,248,819,639,121,816,3,781,664,818,4,980,194,27,896,191,952,889,211,432,566,212,264,597,631,216,938,718,833,410,645,203,950,383,573,582,368,64,287,909,994,189,596,450,784,405,652,244,849,907,36,555,600,640,464,87,590,870,523,371,703,143,555,48,927,935,190,913,156,741,270,332,563,5,786,537,491,397,538,439,926,232,528,45,161,777,957,280,608,463,7,658,837,937,439,257,409,648,133,784,954,883,811,280,626,48,128,535,945,391,362,881,790,816,5,826,913,545,9,691,446,569,55,331,433,161,262,845,424,589,964,144,922,910,530,925,640,563,697,12,261,861,815,70,608,203,17,961,493,110,50,410,278,700,618,80,413,140,541,428,383,869,485,834,254,573,171,344,556,797,921,917,826,320,135,563,989,356,14,2,253,451,880,781,924,788,513,661,525,961,811,536,473", "446,995,400,672,35,892,527,885,53,507,320,275,110,233,609,225,164,788,316,20,99,31,841,499,351,447,897,761,189,468,631,429,910,562,585,199,786,310,523,130,603,42,864,634,539,483,310,494,669,363,561,577,506,390,406,987,800,37,276,28,816,494,692,354,488,617,829,550,511,70,138,194,428,25,689,657,882,723,443,717,993,122,942,838,140,463,963,516,354,859,631,521,668,163,329,695,200,457,350,70,513,568,593,564,912,175,762,270,956,284,161,408,790,518,155,845,319,754,490,240,973,699,944,362,726,212,990,914,503,22,145,420,313,739,541,846,694,742,877,248,420,754,534,644,950,732,52,894,714,924,156,228,654,378,720,703,861,8,18,915,281,539,68,687,506,153,628,752,781,32,989,824,810,431,358,256,621,914,260,264,398,244,527,334,450,376,387,278,281,574,64,748,489,553,861,418,558,38,722,861,85,844,754,846,586,794,564,99,340,966,965,954,175,184,900,305,815,76,427,758,242,132,477,224,34,923,994,509,813,727,284,867,575,204,883,739,907,989,694,31,353,210,297,887,505,846,50,954,289,795,569,501,922,532,60,542,408,709,322,264,87,442,925,801,604,475,236,920,316,421,211,633,634,266,226,183,694,973,194,959,818,228,734,584,888,697,660,668,960,555,113,944,239,111,73,149,428,383,59,147,513,358,672,284,357,11,520,235,795,149,534,427,437,893,620,648,871,50,319,247,379,746,716,801,266,486,668,814,332,341,380,122,636,212,296,67,791,45,468,369,276,724,76,840,746,627,967,745,657,8,327,702,865,970,581,177,826,423,525,763,908,916,668,342,139,564,102,428,811,116,573,856,876,546,610,729,557,596,499,332,654,603,602,407,898,522,572,381,62,815,306,354,939,713,799,240,87,940,690,826,817,87,643,622,611,250,365,609,28,747,982,318,136,559,903,129,539,722,779,85,224,189,835,545,888,219,631,599,543,938,150,285,79,576,753,649,269,1,985,340,842,827,95,559,942,805,628,994,308,176,460,937,978,156,32,962,184,111,415,30,478,580,553,446,876,579,366,868,304,940,760,139,70,797,229,796,288,71,6,230,866,246,995,815,576,363,111,440,974,332,134,905,432,528,0,471,930,18,631,955,144,507,121,277,884,450,516,370,834,693,856,237,676,241,730,903,264,755,610,697,974,523,798,172,992,63,608,262,615,187,424,173,512,960,779,746,890,434,438,602,984,923,950,618,178,948,724,73,358,584,283,671,46,78,637,234,381,848,885,627,50,10,17,795,997,595,716,419,832,562,927,71,635,912,615,506,246,439,855,782,443,843,504,99,463,852,37,323,221,28,92,878,396,424,576,245,618,827,296,447,852,914,468,576,983,238,627,458,116,381,381,344,362,168,793,933,211,771,707,241,945,331,427,235,46,500,837,648,89,903,656,134,343,965,743,888,961,525,800,598,806,936,254,558,129,406,164,148,975,571,675,663,860,743,119,139,615,616,388,121,674,89,522,432,675,406,128,576,442,284,566,590,195,50,794,725,93,464,710,129,424,393,10,394,125,62,465,644,444,765,723,903,113,117,636,998,9,827,542,272,898,173,180,9,156,961,876,501,493,143,393,503,275,910,206,842,717,476,18,743,215,972,617,738,122,731,873,903,754,648,439,537,676,327,617,812,409,326,629,411,922,94,528,734,201,28,794,767,677,774,165,381,230,149,782,898,644,611,255,376,258,366,132,926,288,706,654,472,750,671,736,110,950,520,618,130,928,9,466,808,704,289,694,693,128,136,655,225,547,139,19,6,532,557,582,341,468,955,767,383,661,97,71,669,595,258,891,796,790,209,771,538,501,767,294,960,521,657,292,768,103,526,940,409,232,495,606,914,143,119,153,620,986,126,742,349,45,265,399,746,868,766,841,81,69,471,46,861,294,937,380,635,785,162,416,74,737,903,24,706,254,148,143,740,417,234,677,225,609,357,856,46,863,696,409,362,173,358,558,895,970,302,359,996,404,991,663,787,191,559,641,564,709,32,480,335,742,296,289,524,101,242,523,572,257,297,326,861,501,893,738,125,887,798,555,141,816,219,18,121,864,760,546,895,939,68,100,190,213,511,549,4,243,691,363,150,162,548,937,881,225,760,583,625,416,871,121,275,921,949,592,604,455,550,904,57,486,600,673,46,519,508,392,831,32,548,448,948,791,952,445,449,993,689,764,353,618,681,204,780,706,946,128,461,793,164,951,282,417,511,924,210,919,357,318,353,711,356,482,140", "66,791,17,930,467,78,370,940,785,421,513,295,256,331,45,102,810,290,813,410,577,66,790,811,424,447,663,378,499,349,702,387,184,238,30,6,361,117,139,283,503,343,29,974,554,32,193,771,586,672,684,488,526,34,487,94,569,265,383,550,99,667,380,732,386,949,373,637,410,406,920,494,729,929,98,275,854,145,21,104,242,310,723,230,720,62,978,919,277,973,977,902,86,265,768,245,166,139,410,672,878,733,170,807,445,414,53,125,369,938,451,16,186,457,52,306,158,714,111,541,579,561,765,937,864,764,783,219,84,453,703,171,833,776,350,892,521,663,753,61,413,491,910,215,24,664,271,582,424,695,923,636,677,381,614,100,529,268,931,880,643,791,501,202,371,939,780,131,693,198,290,849,319,33,547,341,203,524,425,673,253,705,988,877,332,430,68,480,552,886,798,849,39,938,284,3,745,90,147,706,479,728,792,299,216,155,902,843,895,248,560,820,222,615,69,726,929,404,682,631,768,925,865,252,438,772,346,34,555,724,121,188,497,714,464,369,995,342,983,742,167,775,367,712,993,468,102,826,558,32,823,409,679,126,524,789,576,990,326,120,352,781,924,818,575,306,511,529,876,675,823,133,26,399,517,115,680,91,350,601,652,740,619,318,417,747,398,706,608,204,122,46,846,294,447,980,261,27,323,280,195,148,109,219,912,278,430,908,194,689,849,760,393,297,61,991,662,256,742,270,226,810,52,979,756,412,71,445,622,683,320,238,377,562,779,260,457,590,54,526,551,282,37,302,372,790,26,767,67,216,231,421,326,508,205,177,277,419,928,948,246,852,796,990,4,287,73,259,123,995,473,322,126,769,287,84,494,250,249,556,706,361,445,880,405,5,327,281,878,231,925,645,468,500,913,671,591,352,387,64,221,113,698,845,698,650,389,94,109,816,942,346,780,780,360,135,560,400,680,855,310,625,10,647,930,860,678,674,186,450,890,971,370,452,767,313,157,643,310,759,89,116,150,257,431,593,299,546,854,421,50,977,164,125,725,251,648,955,52,726,286,111,404,403,225,530,155,104,45,459,888,476,293,273,13,122,642,923,883,811,34,448,309,962,631,718,644,333,44,598,280,884,353,534,471,0,303,518,747,519,415,859,190,398,374,738,662,388,954,544,424,860,530,393,553,87,708,111,889,241,493,231,705,896,85,645,676,436,859,766,216,574,25,489,561,650,644,313,103,395,166,978,108,241,13,724,183,902,135,455,689,522,117,700,860,836,858,486,812,278,216,835,729,71,33,23,257,952,182,274,241,967,94,320,722,221,989,440,814,195,712,229,720,738,725,544,26,613,758,228,591,287,727,735,515,70,427,955,880,604,349,788,843,315,759,464,88,373,369,906,152,506,448,740,118,561,380,829,243,44,127,410,212,204,170,55,409,631,726,785,676,47,738,536,599,796,832,776,575,610,440,222,143,652,609,845,246,397,257,850,948,864,830,792,924,321,859,611,114,640,478,596,30,780,712,369,534,571,432,70,363,762,201,537,962,4,342,246,926,306,410,195,463,351,141,990,444,715,976,965,200,652,495,682,174,570,447,130,467,993,649,943,607,972,652,515,532,818,653,439,489,300,674,214,770,461,451,763,688,329,873,410,830,846,744,802,943,527,802,74,922,17,920,178,582,905,721,589,709,912,549,624,220,380,11,328,27,54,705,920,861,963,318,990,62,173,355,460,81,500,412,602,160,308,532,70,339,819,549,359,199,914,347,171,932,385,935,492,192,937,942,638,351,70,361,708,232,713,84,633,238,27,771,47,844,987,4,322,549,697,489,919,181,356,731,254,268,465,266,596,189,85,758,396,925,87,362,540,385,946,204,401,853,913,409,580,455,525,474,794,471,972,394,699,360,591,388,657,499,547,107,229,193,527,215,922,974,989,781,560,74,913,929,921,316,877,241,116,653,29,180,353,904,288,772,448,555,524,148,601,692,590,243,239,330,253,179,88,401,311,656,159,183,707,430,209,112,280,610,768,835,951,684,329,257,990,177,743,29,433,439,27,211,135,907,516,8,182,955,332,732,930,710,436,624,696,618,562,498,3,718,32,396,909,488,429,227,567,59,485,42,627,119,309,963,346,501,408,207,55,780,515,406,833,388,430,190,939,330,364,254,229,512,26,784,601,749,720,46,589,359,468,606,940,836,327,396,90,773,574,213,462,489,97,875,764,446,454,978,789,51,422,23,615,684,277,697,567,721,429,784,897,987,737,43,477,667,617,888,145", "223,791,869,663,465,8,646,801,928,693,663,836,983,590,958,368,583,714,569,938,355,298,909,618,951,995,645,859,412,591,779,151,366,121,37,878,68,701,19,524,960,800,870,225,605,2,881,651,401,740,276,402,337,324,751,26,909,362,99,622,407,451,575,468,930,742,294,552,658,546,182,646,78,274,371,62,169,45,88,316,977,627,58,545,327,431,732,137,277,214,208,442,507,706,6,206,184,523,293,543,758,88,400,875,522,11,977,696,52,813,982,884,639,784,614,463,143,139,115,246,727,195,89,8,271,110,598,662,657,826,518,438,355,188,77,119,516,806,225,979,616,701,426,154,925,834,18,903,420,735,397,938,713,931,258,249,315,35,635,3,502,366,596,580,763,163,849,64,963,639,123,59,95,833,784,36,754,942,482,866,341,704,575,470,945,687,84,716,622,3,819,100,488,313,254,731,957,897,160,630,997,710,650,439,471,524,725,943,686,324,451,377,814,607,185,62,914,162,336,759,677,655,348,417,888,244,314,310,963,754,858,65,729,439,523,70,307,514,236,830,594,253,90,843,416,822,318,488,415,805,690,852,260,429,582,610,748,782,951,565,761,210,890,833,640,238,763,923,156,575,935,196,447,140,62,549,622,937,97,470,855,52,279,960,222,205,823,726,947,216,639,58,295,20,219,792,249,772,626,804,879,519,902,326,821,703,949,437,869,708,877,892,200,50,905,671,744,560,878,104,535,790,407,221,559,15,648,657,152,282,585,611,994,982,305,865,597,28,445,484,946,425,624,570,334,399,252,304,903,580,22,460,24,225,257,419,39,814,533,703,765,812,257,6,17,824,44,175,481,436,413,801,597,904,622,405,10,133,132,548,725,841,117,525,352,798,785,891,377,588,390,301,193,953,157,801,753,605,852,186,646,185,706,984,263,361,705,627,273,253,432,524,607,906,754,592,162,440,100,280,20,680,829,267,111,733,220,247,779,416,110,704,994,862,58,502,814,166,477,694,868,383,192,620,120,84,124,585,723,148,138,377,739,821,214,687,286,626,84,46,363,568,242,674,814,159,647,62,422,996,1,793,526,119,987,618,60,202,153,105,447,823,991,315,926,785,493,38,916,50,882,949,692,101,930,303,0,657,823,937,238,616,157,702,982,827,537,36,103,953,527,953,192,248,237,104,447,480,686,479,730,159,664,597,789,45,278,181,818,74,381,527,186,927,52,622,511,315,972,352,284,599,416,371,235,281,856,1,783,355,728,975,26,252,151,105,3,62,427,635,772,630,862,515,211,663,372,270,305,471,713,386,73,412,172,34,182,125,763,206,448,761,861,459,7,636,396,777,377,317,264,528,435,463,498,693,142,491,237,673,907,865,361,795,28,389,601,90,16,976,237,453,52,200,256,773,127,961,55,417,55,990,737,431,415,771,529,975,196,710,905,550,439,878,865,950,48,293,128,955,884,392,219,527,864,469,812,713,451,777,484,229,890,655,783,723,999,249,150,150,46,462,872,918,772,473,114,283,523,582,332,329,969,633,475,384,46,71,92,934,498,793,194,45,685,291,813,565,60,17,528,967,878,397,456,974,331,307,125,808,963,255,816,433,351,642,397,37,649,727,255,513,759,741,653,226,8,571,752,350,878,841,646,792,560,443,365,723,498,29,257,131,279,10,85,568,269,874,282,340,754,823,733,11,448,114,974,736,609,272,632,995,913,542,744,973,881,706,183,238,468,538,62,960,105,98,440,92,499,431,683,424,965,58,826,332,474,703,487,535,717,136,175,234,923,551,407,999,133,411,874,795,371,912,702,360,438,748,264,406,777,162,168,645,197,275,271,305,59,965,141,548,118,102,751,175,798,561,679,756,936,669,461,93,258,617,321,535,315,780,440,563,144,92,183,428,932,452,953,932,62,290,638,530,847,511,300,466,427,12,629,636,53,127,879,125,775,464,746,485,350,586,576,862,547,925,692,925,214,166,331,997,99,28,880,155,137,445,750,724,230,872,685,400,742,619,27,775,4,185,955,938,323,742,323,681,956,910,412,72,369,459,335,601,913,618,642,618,824,316,461,297,873,115,434,5,41,462,566,952,237,206,988,710,343,884,443,439,558,726,174,897,734,450,510,808,451,118,328,891,176,957,807,202,651,216,581,68,438,28,186,459,293,548,804,921,457,276,663,352,296,205,201,547,682,84,569,129,306,302,414,151,899,429,52,92,558,19,10,538,807,550,405,4,423,105,330,983,717,54,208,694,495,187,351,386,670,138,972,699", "648,674,915,387,404,306,257,971,700,258,396,466,678,181,411,492,943,782,722,793,79,973,836,703,739,200,538,19,351,705,788,655,818,461,711,887,561,77,322,844,394,597,801,540,879,729,372,894,353,683,570,290,631,795,155,258,92,607,24,657,996,168,307,563,926,594,548,828,84,144,448,994,224,370,356,130,852,595,657,763,827,111,315,236,953,967,556,205,913,416,24,475,992,941,840,856,997,340,289,218,409,719,441,23,994,289,761,745,702,108,205,692,423,800,299,86,986,501,482,638,183,845,224,779,246,350,232,274,634,35,1,763,927,212,609,917,96,554,136,848,812,139,185,340,870,641,539,571,930,100,214,892,149,245,993,397,430,561,175,446,618,223,608,582,889,439,296,36,704,200,828,645,616,745,925,508,589,34,754,838,344,790,875,307,921,576,914,46,303,424,593,263,520,703,129,418,741,109,410,133,193,398,499,814,995,608,507,921,234,381,825,190,198,35,786,328,878,175,82,967,981,192,226,482,628,131,326,890,422,607,728,391,505,198,992,87,296,389,302,23,642,888,825,1,512,745,985,711,813,281,473,932,135,171,520,957,261,189,347,653,358,105,550,325,852,485,869,756,481,910,564,606,882,747,886,72,328,996,192,734,592,855,948,567,319,956,664,882,924,68,745,590,122,748,820,7,28,124,558,519,590,339,646,535,336,253,465,13,464,321,98,304,719,139,949,603,316,926,59,842,723,537,532,108,65,383,920,801,438,358,105,67,587,501,169,527,155,479,521,440,421,804,645,125,226,955,73,97,614,210,269,387,849,808,69,106,460,500,7,548,324,879,872,924,843,855,230,832,286,171,16,998,924,871,896,764,480,334,653,48,120,790,799,403,699,199,689,501,974,765,857,29,760,44,721,197,269,516,891,817,657,371,90,119,567,927,824,593,872,368,689,723,689,458,991,52,841,696,514,29,537,774,406,141,962,812,136,519,592,904,905,149,699,529,23,834,705,319,702,492,790,655,121,284,837,664,824,980,249,537,310,707,855,779,777,674,296,234,871,610,964,891,710,122,232,128,44,606,763,248,374,682,596,329,872,40,455,810,314,552,159,636,884,529,429,369,95,60,499,674,746,669,948,683,18,518,657,0,422,110,303,491,104,320,951,442,961,498,417,326,399,255,792,442,824,291,179,549,346,824,137,426,956,37,357,118,639,196,736,27,451,825,344,429,127,541,901,759,654,884,17,112,236,494,956,968,927,285,960,432,920,452,996,106,387,365,496,971,17,637,15,57,93,881,719,930,324,246,912,738,833,908,774,326,640,591,414,739,316,868,482,806,707,525,317,841,398,291,59,452,66,514,515,172,658,546,241,33,621,96,792,151,414,570,723,630,477,462,390,814,897,890,580,87,996,634,961,5,399,21,685,933,200,914,745,124,78,908,453,230,535,867,155,66,638,325,835,915,561,364,599,79,631,739,379,62,379,166,280,266,670,204,178,543,7,107,817,32,727,153,826,604,157,452,807,276,464,966,889,68,60,343,343,306,524,556,227,885,252,593,479,487,736,661,941,419,614,354,685,91,73,618,264,750,948,461,813,626,156,955,2,969,986,894,332,677,596,265,360,611,474,509,792,413,568,38,37,820,730,509,274,39,32,637,104,505,668,268,740,632,469,297,527,552,394,618,787,547,81,104,350,476,3,308,336,618,222,66,166,273,950,408,751,286,205,100,571,903,629,864,148,367,811,77,674,628,66,925,115,325,587,63,583,745,537,45,935,572,949,123,739,744,77,248,943,994,550,201,654,373,466,625,570,845,907,638,64,232,850,729,117,471,221,734,75,825,728,391,257,737,263,522,438,298,938,119,265,723,156,307,241,264,42,510,684,935,834,240,550,185,123,964,381,380,374,94,745,922,258,264,100,658,260,252,482,316,672,886,866,826,275,844,187,532,415,902,163,240,651,500,971,901,553,861,918,529,3,387,189,914,471,579,551,863,132,83,627,888,559,616,207,178,545,359,487,207,214,79,888,709,289,768,389,335,89,448,877,74,696,435,880,327,804,179,165,191,588,662,32,13,596,895,527,471,554,491,66,473,823,802,581,634,253,866,182,125,236,423,781,284,212,463,896,421,186,71,612,251,986,462,377,712,795,534,792,5,765,303,941,57,821,497,445,455,778,481,856,743,606,591,474,493,477,370,234,576,453,171,421,884,428,305,478,189,50,315,196,605,476,280,684,937,439,647,192,899,356,858,316,965,603,79,412,908,175,167,631,850,524,775", "352,582,361,973,29,72,43,791,666,899,949,365,392,694,265,405,399,725,314,992,293,440,664,420,504,253,208,856,921,689,712,323,445,40,347,219,850,950,585,415,165,94,96,441,992,440,840,642,182,307,324,305,63,733,769,18,843,812,3,135,759,323,44,862,472,49,490,181,954,910,186,673,348,506,127,59,546,487,287,902,350,70,531,587,926,560,979,652,768,319,69,307,524,706,387,909,361,950,837,590,17,428,915,269,164,512,453,50,307,561,120,937,43,96,823,867,881,5,736,332,834,261,764,312,417,605,422,340,731,51,74,239,560,153,722,172,975,796,428,886,853,674,201,775,780,393,43,866,503,871,948,607,184,212,957,695,406,828,483,307,993,252,96,434,759,11,605,145,117,670,425,8,291,347,489,640,880,543,817,127,156,406,602,740,527,560,446,537,386,78,394,93,758,534,644,91,730,396,580,986,999,861,300,786,712,423,60,22,833,675,286,537,400,975,945,822,186,475,45,246,896,146,370,309,529,240,31,344,335,246,891,724,338,477,519,230,277,313,656,710,436,723,315,633,644,4,999,438,280,30,615,82,496,781,159,144,352,572,640,346,560,132,333,377,839,950,906,755,900,195,148,178,523,775,793,292,770,379,995,605,137,315,419,714,367,367,776,293,890,112,634,755,973,912,350,456,402,151,867,107,364,946,433,637,805,32,246,671,87,943,279,834,618,13,47,353,262,619,126,929,550,66,87,353,886,525,262,173,601,634,776,949,744,147,562,59,760,452,343,466,845,176,145,376,347,108,654,111,610,969,684,116,101,290,234,409,206,275,867,778,949,786,499,202,202,514,224,453,793,666,152,773,766,646,379,969,581,957,417,968,272,432,925,396,254,945,581,385,89,87,504,76,358,200,717,518,898,612,959,857,265,731,88,173,673,285,2,432,564,811,430,479,461,811,184,760,689,349,370,92,411,695,711,7,863,728,890,937,545,595,406,830,817,962,110,645,234,56,706,771,416,622,412,503,950,31,823,352,703,679,280,936,507,438,450,734,775,603,276,705,270,259,270,208,607,144,492,521,32,182,926,618,109,198,508,554,239,405,626,476,238,265,413,777,986,883,485,324,927,910,15,486,729,861,631,747,823,422,0,505,724,179,433,363,689,917,555,581,234,385,915,673,810,787,125,427,288,865,728,23,856,139,90,6,842,197,331,44,687,437,478,643,467,41,207,743,472,58,871,560,398,557,688,821,470,617,511,564,164,998,59,685,111,731,92,401,454,180,731,921,554,223,583,328,128,456,82,92,271,755,113,33,608,729,325,83,544,80,167,259,716,566,431,427,983,528,192,115,363,84,784,433,682,317,98,368,132,508,813,569,103,379,231,146,29,489,576,355,809,423,481,984,234,570,22,305,405,750,801,204,499,836,879,36,419,536,185,892,339,84,83,554,319,627,658,828,78,960,400,401,48,314,404,823,720,736,336,441,493,108,579,109,217,327,550,186,172,552,935,683,929,6,498,384,760,670,627,903,166,706,772,351,593,910,164,906,812,385,363,447,10,121,937,658,427,260,466,546,304,312,856,789,153,690,349,908,406,919,726,4,49,754,294,623,969,621,113,940,220,34,387,280,769,3,91,178,207,413,779,2,340,668,807,897,787,217,269,361,84,778,873,669,592,435,265,481,392,172,784,556,57,516,818,924,194,163,411,634,639,319,397,239,906,869,138,15,559,675,391,31,267,270,656,166,225,874,122,788,687,715,809,649,981,187,931,85,64,613,566,74,187,911,739,872,797,107,320,589,176,894,360,321,474,701,388,409,523,84,332,370,808,680,136,149,177,91,917,804,433,106,701,738,833,961,398,598,109,211,467,987,456,740,229,405,885,150,190,788,956,612,971,611,774,60,489,173,431,712,182,656,739,647,578,574,669,885,676,130,792,309,996,130,441,684,366,874,271,25,665,528,47,525,212,20,298,622,897,907,420,578,20,482,675,549,635,69,815,515,149,710,402,63,632,872,903,85,5,865,684,827,59,617,36,685,748,614,657,908,490,998,103,463,358,178,638,326,438,931,685,322,477,134,586,651,782,46,79,753,673,481,33,160,516,46,945,287,726,987,258,442,827,982,137,120,97,211,410,551,13,267,120,420,171,245,419,427,852,655,501,792,473,771,729,336,288,231,254,356,675,284,19,922,945,453,533,905,591,826,901,172,409,563,692,981,245,182,367,850,122,79,324,382,887,391,162,937,546,102,431,608,71,135,256,862,225,207,173,622,900,338", "497,593,882,674,956,130,710,181,684,381,767,567,730,329,96,536,454,167,843,262,420,391,697,295,522,188,70,589,282,713,537,106,123,726,442,433,416,555,917,30,574,998,197,289,124,431,159,685,912,607,919,356,961,911,400,68,154,589,682,26,477,743,925,512,3,826,765,438,627,813,999,679,243,56,856,869,666,679,712,339,935,296,287,271,830,85,702,601,230,922,821,111,473,526,590,661,68,439,864,9,622,614,354,181,746,936,434,913,72,922,774,626,86,28,139,93,299,83,36,906,815,594,322,898,315,759,96,851,675,583,5,706,691,434,258,882,226,395,555,965,865,277,618,463,184,335,563,279,347,63,492,337,6,590,901,546,987,666,108,630,305,409,369,880,556,629,389,224,156,127,729,327,385,153,873,865,360,68,629,802,613,905,937,281,406,15,710,175,351,867,706,428,821,471,972,540,322,970,720,563,226,577,446,850,763,581,728,742,40,732,623,285,508,101,293,380,861,759,59,282,959,621,902,303,25,362,20,813,152,860,830,303,934,896,320,628,617,248,383,785,263,540,209,979,60,465,460,89,695,962,187,236,746,612,288,619,349,641,602,77,833,969,457,656,719,14,206,309,3,808,951,261,962,845,184,424,397,666,393,320,618,620,678,575,805,875,893,246,372,416,290,910,771,416,502,541,316,23,247,944,327,312,467,405,767,948,391,114,41,356,432,416,369,424,866,392,781,78,421,958,89,570,35,139,727,756,398,616,932,695,872,311,444,426,194,801,418,107,518,126,157,995,101,998,72,915,720,865,254,90,399,537,575,171,351,929,945,432,654,795,237,783,491,275,723,946,298,762,607,887,256,286,392,978,872,132,301,737,454,814,828,544,248,958,838,831,557,208,818,703,684,707,667,733,818,198,309,368,194,85,658,517,164,668,29,540,114,126,894,722,373,90,154,313,993,292,970,85,951,925,435,20,498,340,727,563,841,497,854,89,202,261,836,184,945,278,105,658,477,158,529,468,175,629,424,500,277,313,370,68,719,999,830,822,321,179,471,536,331,638,244,822,370,340,999,684,966,283,852,318,569,567,55,730,861,992,233,227,804,101,509,108,869,203,153,544,728,873,540,873,294,273,813,371,955,519,937,110,505,0,216,664,581,536,832,316,253,966,802,777,490,649,430,378,532,993,584,724,319,533,648,597,815,672,404,705,797,550,782,906,990,661,261,249,756,15,326,451,415,579,567,635,413,658,192,50,599,414,599,213,237,465,686,245,718,458,710,334,826,399,143,44,545,346,958,446,617,668,744,473,11,459,91,983,25,854,291,34,491,606,918,198,20,282,255,671,764,5,885,29,856,663,134,574,443,729,773,262,392,337,487,692,224,616,348,741,121,702,971,201,186,302,383,459,305,509,670,560,732,934,930,284,421,663,629,635,66,384,530,686,525,337,844,614,274,187,395,828,224,585,46,884,296,596,945,30,216,567,292,114,451,801,89,559,177,868,72,887,11,263,146,799,686,175,994,267,518,244,337,671,805,675,589,508,796,811,810,289,205,955,756,208,514,586,544,340,824,84,489,792,241,146,131,384,328,625,989,129,883,578,121,454,720,662,994,114,145,814,707,831,443,475,322,558,60,815,530,899,707,636,888,81,883,868,32,585,120,785,620,113,627,357,803,38,409,384,57,823,859,434,154,335,954,85,172,783,309,38,351,135,735,567,40,823,752,568,335,964,457,530,395,497,531,519,951,499,705,381,248,460,766,740,442,419,344,126,818,964,404,79,152,183,955,201,593,992,965,7,427,867,387,823,35,692,870,632,417,315,315,679,754,998,266,973,733,516,922,159,93,829,717,889,8,849,183,404,197,575,289,710,119,292,165,925,529,870,999,244,563,26,807,518,987,314,555,408,373,176,836,605,666,819,853,590,475,353,535,745,521,218,47,89,118,729,667,670,374,706,265,355,768,832,612,245,361,965,419,587,265,663,55,466,470,573,35,932,310,93,930,34,826,467,557,894,955,475,63,634,679,787,156,531,877,21,501,263,791,799,808,362,287,706,388,33,539,608,735,993,666,801,644,328,737,806,560,195,983,499,68,994,47,864,373,826,64,345,552,863,312,848,770,736,430,551,192,418,371,427,940,713,590,995,115,567,535,674,603,340,696,596,826,166,123,669,792,805,324,721,969,315,928,910,713,108,53,555,703,889,353,940,638,637,697,613,391,957,286,314,927,442,214,818,415,31,214,845,133,678,212,784,646,196,924,845,922,541,154,287,846,429", "782,29,934,275,215,215,408,38,803,276,15,396,542,414,573,839,365,718,650,931,334,233,149,632,364,964,124,143,497,603,997,833,640,368,608,242,56,973,229,500,207,347,407,202,978,258,820,668,47,152,943,651,743,572,122,79,991,832,469,335,293,305,286,182,528,354,376,115,541,463,666,782,631,751,864,724,159,411,64,953,648,467,27,192,181,671,826,742,798,285,125,300,317,462,460,686,554,689,583,899,829,1000,603,275,389,887,663,442,853,784,126,575,729,142,912,758,761,375,200,102,954,617,346,622,307,927,19,18,547,32,150,52,493,542,11,876,809,123,781,126,681,583,246,989,930,473,752,478,251,630,488,721,540,547,315,827,597,802,349,475,356,813,167,791,164,980,688,872,692,245,521,776,448,313,872,886,156,667,944,614,461,761,644,252,895,823,51,475,332,97,719,762,246,665,172,981,318,771,735,521,38,181,318,745,605,704,596,575,253,33,870,792,59,677,762,434,138,376,894,865,114,230,237,696,843,583,420,19,378,246,921,677,803,364,449,121,666,92,423,673,845,221,304,217,974,815,375,479,760,265,74,797,361,672,592,260,320,905,383,888,27,810,11,287,488,137,470,359,66,828,923,687,899,594,328,435,909,581,494,787,931,783,547,460,164,733,413,924,799,947,164,827,388,178,367,118,925,300,832,663,320,272,627,398,474,915,695,533,869,253,200,809,724,322,294,381,215,594,146,774,624,736,558,7,61,228,767,784,348,669,912,953,324,771,111,992,748,24,910,958,579,914,221,659,678,77,616,75,748,585,476,373,749,921,255,286,107,984,932,100,901,984,494,855,333,520,630,517,946,767,784,169,818,380,957,104,787,526,592,495,236,57,689,997,663,144,554,699,677,708,613,744,496,350,241,947,482,881,335,740,16,200,903,727,618,742,931,439,950,986,918,431,473,203,793,584,788,220,433,71,565,906,180,455,80,196,450,71,308,313,285,999,845,510,134,213,244,585,876,932,326,100,177,732,939,942,410,272,116,787,457,729,395,86,511,212,970,309,61,128,658,291,606,759,531,989,59,839,473,555,407,938,98,458,909,627,505,315,779,381,151,429,962,224,638,944,549,640,590,904,56,47,649,811,144,415,238,303,724,216,0,484,589,876,381,435,430,798,930,948,61,197,592,388,423,971,997,747,616,91,615,697,353,994,459,867,826,828,136,584,213,344,193,518,568,762,160,710,16,863,141,108,918,447,830,922,513,903,973,919,430,34,640,979,232,117,47,156,196,933,737,941,979,46,161,155,594,162,546,921,125,502,246,498,3,421,440,706,601,876,120,900,414,660,812,300,282,399,529,860,701,371,501,156,554,644,129,127,414,42,763,547,873,416,216,953,279,902,605,904,830,572,701,681,100,393,31,117,499,604,182,211,456,22,974,307,242,668,26,455,540,192,809,801,408,128,896,290,779,32,375,830,710,430,859,905,59,902,903,140,449,938,647,825,498,927,785,206,241,22,231,621,939,784,899,882,902,711,183,523,867,496,159,613,896,215,114,264,772,934,14,747,333,886,650,748,729,201,359,757,835,930,867,914,643,970,372,521,807,77,932,818,586,436,672,359,268,925,842,569,643,401,587,479,836,830,313,120,163,490,552,476,104,885,992,538,349,679,37,552,602,109,731,454,355,547,1,824,56,714,339,967,691,261,83,546,957,653,779,623,435,213,685,499,284,558,821,620,852,743,620,404,430,69,769,580,708,921,715,306,762,974,410,354,405,662,356,143,110,895,236,327,645,532,272,672,380,696,894,329,763,708,512,914,163,361,198,329,946,459,423,152,914,479,911,688,780,720,568,78,321,118,699,580,835,806,333,961,744,72,213,459,126,413,629,144,446,267,687,300,450,166,611,719,385,706,524,357,447,592,376,993,504,120,332,516,657,999,718,282,846,406,573,140,85,568,276,641,624,599,117,763,599,401,760,447,231,263,47,419,614,947,400,626,518,917,990,483,808,371,781,560,822,333,608,898,531,537,22,310,946,160,119,34,262,339,688,54,855,715,277,29,202,150,244,985,324,672,800,667,457,767,576,834,568,799,997,332,107,763,118,84,694,309,601,585,286,200,871,186,57,973,276,665,439,817,811,603,235,517,671,699,633,252,214,369,236,366,475,830,222,50,801,176,297,989,864,349,741,61,792,801,410,608,584,627,304,541,684,67,859,487,555,433,274,492,353,446,58,59,88,320,310,653,436,76,899,232,58,266,117,131,487,146,423,84,343,108,325,402", "182,787,471,791,265,210,205,460,738,995,366,949,569,959,82,180,105,890,896,344,883,157,965,263,977,296,715,306,357,37,917,276,486,828,80,693,719,990,236,781,133,573,577,519,553,669,472,974,759,472,728,530,890,272,956,715,731,277,569,570,264,439,134,272,157,616,122,259,435,555,903,883,964,189,882,231,721,418,277,18,667,105,856,459,867,685,394,798,758,516,715,688,999,522,698,105,908,299,383,433,348,746,624,692,593,600,539,408,123,415,815,152,519,476,524,612,931,186,534,384,236,85,566,594,230,507,575,429,568,622,343,295,374,642,32,939,361,345,119,395,656,192,346,669,630,904,44,290,595,764,869,353,176,798,17,945,752,398,966,5,505,487,87,11,185,498,811,408,280,952,348,926,798,292,394,950,736,421,100,994,486,380,649,494,379,846,991,136,781,566,677,336,633,678,280,489,416,215,806,855,106,798,224,979,859,74,264,938,890,99,903,848,978,40,176,644,950,495,827,915,419,218,412,636,806,672,475,13,458,439,473,913,381,352,862,93,815,361,58,610,921,853,431,980,733,127,151,932,213,747,421,62,274,205,323,11,658,429,714,303,979,7,541,943,585,815,687,764,453,666,479,435,836,545,817,597,434,30,413,383,737,307,836,446,90,648,232,387,256,12,3,337,99,310,922,387,371,271,736,499,926,713,733,954,134,13,170,96,671,235,496,462,247,924,124,215,648,331,818,411,382,27,447,371,700,577,669,834,744,522,852,396,981,81,566,125,141,755,990,178,483,248,371,872,331,201,76,31,817,70,279,19,126,733,588,444,926,549,844,698,947,412,237,532,300,541,570,305,676,538,185,542,910,480,545,267,566,729,134,317,404,734,447,792,413,39,779,119,256,110,398,850,847,500,72,740,354,10,470,606,927,208,18,90,732,201,916,362,528,303,704,831,343,524,541,642,548,869,837,408,30,729,686,766,913,137,294,436,821,833,162,860,486,588,327,910,28,584,25,787,522,675,166,570,552,531,392,242,758,292,508,496,609,593,36,512,780,75,269,700,387,447,628,826,630,398,221,122,492,739,369,80,377,937,752,797,795,193,720,444,46,656,582,934,49,626,634,83,467,21,448,585,679,467,507,859,616,491,179,664,484,0,448,302,672,978,468,106,219,261,887,234,927,363,143,139,603,355,633,2,169,724,14,751,257,387,755,659,70,536,519,383,913,292,16,569,947,493,189,748,276,61,565,467,857,893,395,919,675,861,664,494,689,808,577,439,429,823,547,306,240,992,834,752,695,548,630,560,426,35,903,424,68,15,578,15,37,865,645,371,699,27,754,65,731,495,641,190,343,454,322,495,575,698,768,632,451,606,964,650,178,73,114,232,187,220,123,265,328,855,553,393,742,33,563,241,10,708,724,530,487,497,701,718,278,151,709,660,240,633,332,272,876,229,968,868,866,618,21,188,474,857,863,750,848,441,1000,283,30,813,557,35,329,643,796,745,898,688,178,245,46,137,921,846,151,53,116,671,108,892,227,49,182,460,15,28,235,484,106,996,454,92,309,758,805,638,526,510,491,682,475,115,941,92,412,606,245,807,88,770,510,27,915,681,601,58,363,20,860,979,506,616,958,812,458,560,722,918,854,609,316,20,455,952,88,813,136,638,742,107,161,632,164,301,951,490,761,915,558,566,381,892,339,88,759,590,156,655,75,154,636,529,926,177,967,312,912,344,62,996,652,621,262,69,317,619,443,262,637,465,525,363,311,106,69,583,250,850,461,439,814,182,806,42,442,196,679,124,320,838,602,849,827,214,274,498,590,580,184,4,195,213,668,327,374,451,167,127,365,561,291,453,672,290,631,738,445,29,895,964,456,100,911,304,239,734,383,440,729,638,436,657,747,70,303,793,525,918,507,350,520,778,684,577,172,921,782,909,99,343,118,167,858,919,90,361,871,416,118,202,91,928,571,806,20,63,235,140,463,933,549,347,236,161,72,257,455,875,7,570,787,851,233,517,105,475,926,299,831,834,755,543,230,20,29,546,421,229,803,46,336,657,313,923,127,186,94,300,888,855,615,12,748,512,922,703,860,613,140,45,144,936,822,596,592,205,234,424,298,889,578,838,44,696,47,243,668,940,199,257,107,184,352,217,298,637,432,548,296,677,975,261,671,197,21,674,836,291,241,477,76,814,695,249,13,819,678,228,7,526,475,892,185,83,567,285,388,137,586,556,225,303,409,841,395,253,398,954,147,448,184,13,349,889,329,33,782,574,321,563", "463,687,397,723,533,312,74,713,861,86,975,529,286,801,493,677,605,116,722,805,200,336,751,770,108,598,535,733,173,764,716,145,369,944,3,131,990,639,149,137,504,56,919,356,679,708,2,877,296,691,38,56,697,3,171,665,653,535,587,985,428,593,997,787,245,365,167,88,957,712,791,577,404,15,443,770,271,188,749,559,766,675,310,857,695,225,475,691,213,557,924,4,466,7,854,146,530,225,265,576,792,873,885,34,185,451,688,565,373,339,785,644,678,913,898,180,359,258,31,811,200,105,216,188,783,148,829,950,260,684,234,248,716,816,645,789,278,882,568,379,453,519,289,825,84,625,63,537,157,895,503,998,728,542,824,239,380,145,353,11,784,617,553,609,222,571,462,120,420,779,989,417,406,321,697,481,724,815,340,432,333,340,298,175,641,893,113,247,73,150,959,184,951,99,996,815,340,929,319,249,120,852,771,200,841,548,128,859,554,301,317,904,187,161,772,593,98,33,456,776,686,204,550,898,920,469,767,27,17,177,27,315,902,896,657,465,389,454,946,603,406,333,626,598,279,178,927,2,370,388,963,435,303,868,670,276,754,86,418,323,646,704,909,658,10,135,497,850,396,558,159,741,159,236,462,192,908,674,919,846,3,189,980,454,963,879,84,137,8,752,218,895,140,631,941,80,586,74,591,953,159,416,928,560,891,998,222,411,779,745,387,50,126,742,905,850,306,870,416,624,52,682,359,447,147,533,982,447,252,822,359,40,16,238,502,623,605,594,747,131,409,260,762,806,407,618,106,150,704,41,14,510,648,415,362,109,911,592,864,556,691,83,922,440,129,334,631,119,172,244,576,202,562,374,630,100,797,864,38,851,412,225,978,850,906,485,366,904,860,254,591,676,906,247,862,607,743,602,602,71,940,925,945,936,114,93,737,114,852,938,898,892,385,938,968,345,949,826,379,892,359,134,170,636,866,455,743,356,635,60,839,225,597,438,709,150,76,721,372,899,301,681,493,557,351,714,296,460,948,784,951,705,901,946,218,321,367,567,12,261,873,277,339,729,782,38,331,522,924,590,102,975,273,24,491,626,537,287,105,327,39,935,820,356,996,167,502,142,467,287,451,529,1,992,121,190,157,104,433,581,589,448,0,941,758,202,38,492,206,350,432,990,800,46,97,418,327,45,759,304,640,734,63,712,456,426,740,676,662,806,987,546,422,490,770,409,868,137,161,279,760,134,360,889,996,449,703,745,636,362,571,809,360,429,452,426,381,207,792,631,856,115,685,174,589,565,747,322,558,491,468,74,947,808,410,280,674,639,121,562,350,587,947,736,299,847,509,152,655,681,444,562,197,23,259,951,343,633,332,524,949,416,150,308,271,568,304,600,302,724,361,857,514,674,252,10,406,57,610,523,467,4,794,245,398,537,70,710,244,414,309,444,215,207,134,554,643,450,11,107,942,665,978,594,841,588,841,829,446,245,838,874,388,563,214,532,386,261,816,20,888,761,885,882,723,347,390,1000,150,704,89,2,842,685,404,219,432,106,918,354,493,284,282,648,751,968,547,764,757,173,699,496,943,351,767,910,274,266,981,495,77,570,283,365,307,841,523,556,249,539,862,943,289,884,814,705,429,89,988,503,341,373,251,373,74,124,175,191,707,281,661,492,224,7,40,490,113,175,947,903,620,5,477,554,296,412,887,455,260,278,197,531,879,635,771,748,571,814,254,510,761,453,369,781,24,311,115,372,895,885,673,663,78,356,964,443,583,606,716,360,62,644,865,767,742,264,596,510,764,893,545,695,691,478,849,961,745,413,9,742,584,229,831,251,406,392,442,571,26,332,538,111,516,864,196,644,725,834,930,987,770,870,509,478,312,844,293,872,225,663,736,351,529,431,406,614,503,706,317,539,519,177,402,630,450,86,933,763,143,294,775,946,212,828,127,473,444,323,331,114,985,344,513,582,218,133,307,885,23,308,138,687,712,467,242,417,87,51,714,726,499,613,586,794,466,99,531,698,711,226,599,19,415,292,17,788,671,931,8,975,371,539,608,846,206,71,316,518,920,39,381,174,349,368,450,594,207,258,56,638,989,775,71,505,143,292,406,769,823,700,260,601,157,713,791,666,269,594,279,541,371,700,695,305,946,546,255,796,543,779,172,876,892,471,598,662,620,128,238,198,599,54,398,205,771,111,614,103,194,804,574,371,802,784,745,65,267,660,609,254,505,479,142,827,180,675,672,521,291,146,167,634,429,415,48,164,384,554,854,20", "557,878,92,360,307,635,150,75,263,969,497,181,795,128,323,462,96,664,22,778,478,778,439,148,337,924,95,419,548,913,684,251,684,256,919,938,101,185,413,973,76,121,865,974,66,679,18,904,208,793,639,373,62,292,834,183,928,661,221,702,438,21,111,90,766,662,328,539,384,649,647,660,373,244,926,298,894,123,189,756,754,228,166,149,123,509,851,784,885,410,968,646,607,363,351,798,511,433,448,367,247,878,63,240,660,380,785,61,652,146,329,348,891,243,93,831,553,544,643,380,298,592,538,430,48,706,283,26,171,155,613,872,757,303,471,652,473,629,258,842,75,259,404,795,615,287,325,944,640,839,791,186,993,258,331,878,936,284,485,599,7,222,5,683,472,760,171,953,149,289,512,912,538,975,805,514,888,625,225,800,80,850,529,31,711,269,29,978,438,66,211,145,395,944,109,631,758,180,798,380,420,369,925,253,101,944,956,494,866,636,739,98,55,69,848,588,328,255,214,772,372,769,993,454,148,788,224,583,959,868,287,273,349,145,703,469,240,516,101,708,349,950,950,333,97,506,889,154,953,745,960,994,322,861,465,713,285,921,785,799,229,16,972,96,680,368,447,619,428,286,254,195,36,182,788,228,326,241,197,173,828,484,743,487,193,876,119,416,346,256,628,545,303,195,845,492,181,559,856,453,269,298,511,734,504,162,207,983,898,335,143,774,36,992,700,39,635,218,985,281,572,491,441,308,87,411,262,213,20,234,653,254,539,957,987,62,621,292,655,456,892,646,430,235,5,615,320,510,23,417,956,791,456,886,953,298,100,267,353,653,3,702,353,527,825,96,590,58,348,179,106,719,295,470,571,184,830,345,605,745,821,574,258,881,959,85,600,873,354,491,536,153,849,927,598,398,221,33,19,250,756,392,40,935,975,418,3,534,457,101,357,851,481,235,180,517,805,561,314,11,242,36,258,845,463,440,562,684,667,65,426,480,75,486,69,768,780,945,950,547,605,950,97,458,454,761,136,442,28,38,678,820,116,277,938,472,9,666,62,98,614,134,896,71,291,782,838,577,371,302,617,905,557,32,585,354,918,64,444,510,977,77,201,954,66,579,312,774,371,656,650,59,615,245,277,398,702,320,363,536,876,302,941,0,314,400,799,831,24,745,317,699,992,233,419,28,758,673,604,412,642,527,75,683,215,172,603,609,948,551,373,323,273,364,910,23,75,549,547,176,246,172,121,659,737,548,996,167,16,896,404,483,680,753,423,988,994,580,183,618,260,946,70,414,302,315,877,578,734,883,605,517,816,570,627,654,813,797,896,556,553,999,326,76,20,844,706,439,833,946,711,292,874,304,509,622,534,887,70,826,933,426,670,525,409,583,382,121,81,822,163,649,858,244,101,605,668,887,142,90,376,944,471,402,466,887,238,850,772,236,514,881,809,586,804,752,546,933,982,384,493,821,673,636,186,444,388,245,386,358,789,480,258,813,732,919,45,764,17,4,764,982,988,102,702,210,152,370,72,986,343,395,346,948,278,388,944,240,431,130,745,51,348,724,22,576,88,294,97,468,848,22,592,156,858,466,919,623,212,620,111,978,231,19,500,214,495,716,541,814,703,987,465,498,135,727,104,900,494,524,861,826,769,956,656,600,605,250,28,400,901,888,344,774,22,534,27,771,627,235,459,107,369,179,177,263,569,410,490,472,503,841,111,134,446,916,270,929,325,632,105,985,467,859,630,582,134,428,530,352,721,676,470,865,199,746,341,815,164,320,349,607,68,17,947,776,815,987,41,303,709,56,753,334,210,860,399,404,309,903,100,776,934,674,707,57,938,835,597,325,901,412,109,105,310,98,798,262,728,615,361,219,116,238,471,424,210,393,765,64,803,82,573,256,77,247,88,743,902,10,432,550,192,790,612,650,715,917,874,152,195,612,593,596,905,671,511,288,806,438,603,730,397,133,256,648,840,18,492,831,29,643,595,613,732,705,123,434,909,41,242,76,62,201,116,311,987,737,636,989,31,290,739,218,285,260,416,394,188,365,447,168,347,434,265,340,472,924,634,687,4,310,946,871,434,168,846,232,677,229,125,117,688,121,823,33,366,317,998,183,684,891,920,464,276,325,410,198,998,59,856,545,775,698,671,747,407,505,304,965,212,501,772,195,109,960,117,858,935,474,196,967,996,281,680,501,663,551,467,387,947,167,214,124,297,77,140,134,167,909,28,254,947,605,292,849,2,779,492,43,968,526,571,432,311,945,531,709,458,413", "20,640,714,238,424,595,496,367,3,802,685,303,596,170,461,2,81,303,237,701,663,712,286,99,92,849,408,348,815,18,159,950,601,604,35,278,697,490,996,422,983,283,455,643,338,559,810,590,212,167,341,125,290,474,176,513,491,573,856,69,904,886,80,726,754,862,363,425,633,506,323,793,154,42,526,598,555,773,687,129,578,103,742,84,811,234,925,864,523,657,347,164,749,802,842,204,222,252,368,948,584,285,459,76,9,567,784,23,589,156,650,464,401,892,379,999,521,917,214,462,873,948,100,158,589,267,174,533,12,372,964,281,117,457,936,67,157,533,291,201,706,617,7,798,626,110,904,667,985,285,293,20,591,739,141,618,944,470,839,436,584,515,792,487,93,532,774,699,408,858,953,373,981,548,522,431,670,696,100,466,982,654,888,434,403,99,635,261,314,967,394,596,322,468,996,463,726,620,297,767,37,644,171,530,78,643,485,113,585,129,506,44,595,212,42,876,313,72,979,3,76,36,60,880,148,32,113,921,756,296,898,502,54,106,651,962,818,473,214,936,775,705,62,228,511,365,802,6,191,474,551,802,869,364,405,390,616,130,982,471,274,901,957,471,436,528,303,949,944,821,66,879,705,254,934,727,329,779,487,671,559,939,252,954,517,188,308,191,513,951,390,937,726,427,268,336,332,927,759,63,832,951,367,658,57,327,938,697,135,39,655,32,210,75,763,637,344,298,368,81,653,735,643,195,915,669,955,441,106,833,184,527,303,763,831,551,973,298,667,694,581,536,551,330,630,854,616,956,846,266,829,329,949,580,78,814,26,702,318,89,981,178,926,129,841,716,402,378,816,130,925,71,73,268,51,142,593,523,926,835,321,44,115,299,922,227,692,976,772,68,331,963,575,108,846,648,686,796,178,979,306,32,733,3,520,790,931,590,185,294,425,993,885,600,200,130,314,44,55,607,809,959,651,550,746,694,662,86,164,479,79,55,205,229,911,75,898,904,108,532,410,762,364,50,257,899,944,258,448,845,426,880,291,831,858,6,574,864,694,234,681,273,318,999,568,530,335,252,706,118,785,665,311,626,119,575,652,656,403,238,95,956,251,476,53,175,465,530,862,143,616,66,25,846,884,374,982,951,689,832,381,672,758,314,0,703,515,886,407,726,29,833,923,172,600,772,853,889,6,50,407,553,661,860,561,878,53,773,318,922,451,940,948,54,716,430,230,769,5,249,732,205,811,767,788,313,909,20,37,776,148,762,646,108,630,606,130,692,188,934,285,539,115,15,580,354,455,364,374,493,276,546,248,221,256,747,721,594,717,306,788,200,275,825,832,56,951,967,538,776,713,599,518,355,623,582,186,288,918,384,768,722,652,886,551,763,680,764,100,707,291,769,57,523,636,377,693,46,460,873,452,124,464,79,230,969,774,478,345,180,449,279,608,170,646,296,720,288,665,843,325,454,741,114,853,15,185,790,88,853,194,58,8,281,885,947,819,335,105,676,513,6,65,582,507,201,267,195,481,139,319,473,754,38,921,474,948,347,580,262,341,963,30,994,606,638,291,522,899,977,921,653,969,547,6,182,540,939,826,659,453,383,731,394,449,387,773,87,342,615,112,592,843,451,525,583,365,811,98,228,491,245,629,652,494,433,490,958,804,561,277,827,47,440,579,714,684,75,105,712,843,914,683,384,949,283,407,133,23,440,820,201,25,756,714,633,251,935,805,919,820,39,863,275,664,341,250,343,507,758,501,22,562,233,554,730,146,514,140,995,757,114,120,502,872,420,372,352,969,949,220,390,697,430,125,119,747,875,973,146,274,548,33,181,290,502,756,361,498,886,522,291,208,453,506,553,495,363,270,660,906,851,165,744,181,660,666,525,184,983,141,147,684,560,328,261,826,577,619,454,302,233,324,569,140,102,76,571,505,863,383,192,785,70,755,892,557,302,416,51,211,55,514,201,888,138,582,400,580,96,448,745,279,361,562,90,119,496,81,975,75,239,429,213,882,199,165,590,413,218,739,241,516,247,6,406,954,376,587,365,754,823,555,59,946,895,249,22,815,720,443,324,739,454,107,329,238,714,646,590,536,409,911,677,222,68,192,140,645,3,690,936,209,132,540,200,639,207,266,172,167,603,589,168,512,671,83,852,825,688,819,829,171,630,706,925,916,349,348,732,704,378,970,9,729,666,928,923,526,606,144,615,275,461,997,947,712,954,778,350,787,325,439,462,596,603,836,2,383,459,35,863,212,260,61,338,912,990,747,257", "849,11,569,270,501,79,805,249,893,410,160,627,11,390,942,494,746,521,768,373,469,450,223,702,80,303,578,39,778,698,748,884,394,438,161,511,699,990,42,338,851,795,185,253,463,336,762,979,414,994,104,673,834,990,119,671,244,625,527,854,16,702,759,891,326,488,863,868,74,467,984,798,888,173,343,367,571,333,276,832,985,972,591,524,497,474,142,3,459,867,829,935,475,791,970,762,295,120,65,303,281,270,445,459,568,951,482,397,525,755,989,510,147,488,28,636,429,119,352,215,198,723,835,159,844,790,214,295,72,699,819,426,614,280,264,104,201,204,597,698,641,442,342,615,44,66,915,466,630,142,219,639,897,259,771,764,624,29,174,293,327,718,541,303,88,898,182,611,694,994,566,754,785,996,334,866,709,62,811,783,262,880,329,507,741,355,334,506,311,711,671,631,650,329,831,403,109,66,49,271,508,888,380,924,697,791,317,26,950,13,669,595,80,101,764,451,206,53,873,655,466,255,595,76,33,138,892,392,760,224,758,99,819,971,282,880,275,606,306,238,849,305,348,248,986,978,555,690,447,701,645,391,579,777,306,607,601,561,15,904,733,896,926,343,112,862,613,416,152,875,779,554,217,625,850,286,421,821,140,392,11,541,8,813,397,535,145,749,197,491,592,288,931,81,734,904,513,264,462,401,719,258,310,943,385,695,913,54,277,214,835,563,325,988,994,203,771,285,999,268,399,550,219,319,783,859,574,1,39,126,907,870,416,504,870,213,909,484,78,716,424,33,862,331,933,212,394,265,904,756,325,917,848,244,31,566,242,916,63,971,146,550,487,894,701,41,163,686,383,414,912,275,870,714,767,229,158,311,591,749,600,884,211,905,821,558,760,825,155,385,449,436,163,13,707,7,160,295,285,517,975,816,589,676,641,726,327,419,165,627,376,392,49,205,12,896,253,603,584,17,175,453,812,803,211,601,408,923,962,700,656,279,893,204,831,807,487,848,964,827,585,915,358,780,737,461,136,884,635,367,92,801,927,113,287,617,307,537,716,540,987,131,731,91,537,862,713,879,212,469,928,605,111,568,165,208,636,384,599,132,74,881,815,239,179,390,656,603,407,923,6,743,946,654,450,738,827,442,917,316,435,978,202,400,703,0,687,976,967,484,894,2,264,813,843,89,291,591,127,499,490,564,376,668,871,835,720,467,64,619,342,886,365,422,588,518,25,124,625,784,724,989,974,573,99,487,787,617,427,357,477,465,120,759,81,251,651,412,156,738,599,509,836,623,459,721,449,871,546,371,606,141,704,204,17,268,351,906,436,826,651,739,290,609,237,247,212,289,397,158,306,785,851,915,705,116,751,507,103,862,745,408,865,156,951,496,506,985,479,353,548,86,178,374,716,954,598,954,610,680,958,404,47,309,267,318,571,919,916,852,373,948,433,946,63,765,121,543,545,53,8,147,240,672,442,251,323,816,921,67,934,305,472,207,217,54,381,71,702,390,263,737,165,575,958,305,560,884,599,267,44,621,707,335,143,261,927,176,192,761,100,189,2,974,297,488,30,757,634,900,883,250,475,994,609,85,584,476,190,663,746,36,912,25,820,661,489,909,755,108,78,821,48,113,163,286,692,931,877,329,474,445,150,377,876,207,505,782,520,478,238,324,85,742,322,303,419,977,189,580,967,797,745,331,639,700,370,384,784,636,425,6,145,777,816,609,23,797,914,646,328,855,755,232,602,562,875,813,40,226,450,706,574,850,234,803,552,251,630,139,179,427,617,894,92,401,302,203,363,161,448,29,403,561,65,149,14,377,506,972,83,793,310,969,323,62,838,966,475,986,77,656,742,144,427,738,720,97,76,896,153,679,238,185,566,473,292,540,39,522,994,68,667,394,200,797,130,704,666,823,645,158,362,440,440,695,676,263,83,60,159,912,611,325,51,523,54,600,392,488,725,306,33,257,746,122,968,770,663,355,437,589,883,532,377,62,879,801,547,230,893,146,984,676,411,290,387,458,537,657,357,50,319,353,544,235,319,31,243,727,260,55,821,148,721,620,126,774,536,624,726,969,406,975,465,542,696,118,538,541,422,693,302,629,821,68,858,540,213,127,568,77,486,952,590,622,606,394,243,96,211,995,934,341,798,324,723,294,919,224,535,462,38,660,513,883,73,102,981,973,26,829,429,818,955,858,607,716,76,353,87,777,937,286,992,741,476,832,603,728,433,475,432,557,371,688,167,859,284,477,420,664,896,371,786,71,525,61,649,214", "685,883,886,588,166,226,363,36,121,411,766,738,713,227,589,456,828,848,34,377,426,229,125,681,819,846,985,635,657,282,176,156,636,552,375,661,248,886,468,36,819,212,864,989,321,384,624,478,739,352,597,499,821,769,682,307,247,170,379,395,260,820,819,637,747,241,351,77,250,115,166,282,570,934,366,488,689,33,744,830,143,652,537,348,850,301,800,850,511,233,505,763,522,615,493,84,5,706,861,585,235,408,57,158,268,840,569,207,876,810,824,967,989,902,68,781,677,220,554,455,587,948,118,140,294,189,297,712,967,42,528,174,723,580,125,269,877,866,79,595,708,424,458,637,349,930,898,432,804,161,859,51,318,115,507,80,941,132,765,46,57,339,517,634,666,432,657,661,838,303,151,318,692,192,802,552,297,232,633,220,464,309,512,191,500,613,492,777,72,510,668,480,259,532,805,974,876,258,778,996,984,805,71,223,556,61,959,130,745,863,365,932,569,86,688,893,835,480,815,722,513,149,681,979,817,995,286,218,947,513,161,585,134,61,647,115,125,577,159,354,584,994,867,547,848,288,917,912,836,694,282,917,877,891,183,995,576,40,282,460,391,406,183,581,364,247,713,771,801,54,429,677,238,964,848,742,804,666,159,64,749,880,889,487,262,152,548,361,743,568,952,768,322,688,736,78,474,566,288,272,564,58,674,994,212,536,729,238,375,297,957,576,404,918,45,282,405,987,434,690,985,135,452,57,795,144,334,70,769,813,3,399,120,672,347,82,370,568,320,696,891,764,357,705,415,119,596,64,669,88,661,914,106,697,996,496,247,31,378,708,871,778,763,296,680,543,116,156,716,362,236,191,384,24,959,407,100,449,857,685,374,205,499,331,646,684,916,640,740,262,292,99,724,807,498,254,37,225,391,260,143,851,842,162,827,876,46,536,764,95,67,937,773,371,756,835,733,532,162,177,630,179,11,359,368,926,685,465,681,868,929,518,895,750,791,866,503,876,410,383,283,42,758,95,835,811,5,545,880,811,678,896,897,807,440,780,705,551,651,362,951,405,74,967,172,919,226,596,518,759,604,374,84,338,857,821,301,296,207,727,552,709,404,763,441,130,531,474,526,89,391,98,173,817,516,662,537,961,555,253,430,468,38,799,515,687,0,272,742,752,953,434,539,690,733,187,63,342,875,876,716,263,589,396,428,866,83,904,663,922,37,583,150,449,622,449,8,137,288,634,950,497,25,677,533,465,231,44,676,511,337,550,269,907,883,464,193,526,415,15,583,948,935,3,766,619,882,444,424,355,123,737,556,873,481,353,585,208,958,34,707,995,437,982,543,719,818,635,168,968,441,695,477,9,934,939,238,103,373,129,612,751,255,521,132,455,142,317,947,84,662,369,514,905,615,518,994,764,390,911,961,181,141,254,263,148,668,11,536,995,425,57,953,352,222,976,927,328,841,974,107,284,510,314,633,899,701,629,276,230,311,330,685,982,331,434,584,774,526,430,179,612,120,891,43,633,747,59,901,610,167,520,867,747,169,840,712,827,408,748,472,48,152,973,681,692,20,460,313,688,77,303,978,922,93,775,37,788,283,429,368,94,871,158,566,965,921,616,517,478,161,401,384,712,368,487,934,816,72,53,829,161,393,571,912,422,29,748,110,307,233,701,240,51,285,716,794,624,860,846,718,556,82,881,389,576,787,549,248,935,461,35,732,625,372,752,271,138,378,970,842,237,635,288,134,101,583,364,144,519,855,451,16,289,647,116,66,886,421,818,973,596,330,815,730,188,275,112,292,706,935,346,505,758,200,574,424,234,671,304,683,878,525,213,566,945,670,404,293,7,756,570,89,755,183,132,822,39,432,123,866,288,720,288,379,444,601,455,660,31,629,225,925,39,107,833,391,131,486,580,906,881,377,93,617,238,27,684,794,70,704,451,999,522,739,8,626,939,711,715,475,932,759,935,771,108,624,328,281,92,24,858,906,724,123,948,478,45,373,453,569,637,68,65,256,696,849,991,654,299,145,24,683,510,586,545,17,444,856,300,110,892,88,515,268,12,72,596,394,324,431,897,129,579,526,950,815,290,199,368,748,473,35,606,551,909,90,453,14,992,989,450,740,893,431,671,984,317,73,482,251,735,902,972,880,408,997,221,590,225,300,173,224,247,62,714,508,896,529,674,482,329,595,52,396,717,49,856,539,385,958,30,392,138,904,227,954,342,785,985,225,801,95,203,604,703,135,283,727,401,55,49,486,861,756,702,55,392,542,274", "956,827,133,401,501,990,333,64,402,77,906,486,601,191,453,835,962,809,401,837,838,728,669,995,639,943,557,824,720,10,151,25,807,296,253,246,45,377,610,406,904,25,747,422,494,487,731,469,835,575,696,737,390,183,552,923,974,24,905,709,600,764,218,875,907,895,502,636,258,70,311,480,872,446,849,280,451,508,446,555,578,473,486,775,915,316,75,219,985,839,581,583,186,477,647,409,272,439,76,92,595,51,96,951,934,302,679,971,433,338,321,620,738,972,831,519,40,939,807,945,750,643,167,681,592,618,662,527,935,150,376,201,481,593,55,498,631,952,306,337,621,736,459,39,436,58,481,528,675,900,895,446,7,910,792,751,854,222,298,629,208,506,779,709,32,465,850,105,386,552,701,401,842,513,422,552,149,156,125,549,458,972,861,139,716,149,217,757,517,796,510,947,427,840,747,83,725,551,876,654,877,575,626,439,134,799,257,367,232,969,740,839,116,676,403,110,218,725,781,787,434,26,225,330,837,881,173,533,774,364,493,748,339,40,269,153,271,713,52,517,710,684,550,14,621,280,18,989,783,4,715,996,446,489,58,802,14,965,275,146,906,79,251,104,220,598,990,951,284,757,263,421,765,416,526,869,162,671,464,830,569,647,328,905,499,439,501,49,280,280,539,506,121,787,856,789,684,539,891,753,839,60,205,415,629,468,389,187,979,323,522,525,897,2,124,984,141,394,128,221,425,253,682,215,295,750,502,599,3,681,693,343,861,61,824,931,955,629,603,58,379,427,557,599,729,883,696,216,584,915,443,807,190,259,265,870,982,908,318,436,120,330,15,148,461,62,208,739,190,256,704,176,865,845,799,685,873,113,945,106,687,171,349,969,566,609,587,276,849,549,76,151,625,86,350,83,604,816,195,827,943,174,193,79,786,469,509,820,112,511,788,631,529,648,539,679,862,751,701,799,448,128,338,523,478,838,966,189,84,958,923,870,399,49,79,161,899,16,276,527,442,647,934,901,304,146,501,824,494,802,525,209,515,661,444,987,478,553,417,193,667,355,861,28,331,104,431,680,72,454,969,690,316,465,321,276,815,515,412,305,834,605,179,24,461,537,57,100,670,244,524,589,833,789,370,388,36,498,581,966,798,106,492,831,886,976,272,0,68,408,565,311,29,364,697,890,50,692,215,115,856,194,574,331,693,818,226,948,634,813,681,249,134,141,878,473,228,857,370,340,946,363,19,740,850,645,251,714,68,57,614,327,520,823,7,250,348,549,915,272,283,569,879,575,403,520,430,613,682,327,9,550,421,800,558,93,322,139,525,116,220,883,623,474,100,429,392,916,652,641,664,613,850,106,499,527,981,628,355,678,294,904,916,889,128,682,905,64,983,383,115,790,28,783,693,378,891,697,470,409,693,588,995,62,215,129,815,940,954,308,365,273,640,55,747,71,180,788,329,501,986,130,471,251,168,585,72,124,405,370,208,158,865,742,684,230,434,767,891,293,606,182,888,145,594,3,266,166,260,73,531,257,29,668,733,112,976,35,294,264,445,292,27,347,718,909,218,568,242,644,470,885,294,43,456,979,312,233,319,815,564,286,66,380,871,806,459,4,190,691,375,552,498,829,186,206,419,275,716,487,115,607,681,892,551,401,505,121,793,524,776,329,658,938,469,933,110,183,146,929,633,603,879,14,521,258,862,192,424,463,675,642,38,62,650,438,165,923,112,924,218,817,83,51,49,140,165,588,510,387,45,224,815,774,829,355,475,304,984,607,289,774,177,13,319,228,523,133,810,25,857,53,132,820,116,569,670,529,743,565,885,836,468,479,609,923,628,368,664,683,927,297,523,474,730,274,892,975,189,742,222,259,860,826,390,239,541,142,938,779,195,685,294,734,12,587,175,421,791,759,897,972,898,612,926,567,968,378,172,714,687,674,200,581,462,334,396,862,208,142,568,586,111,346,645,95,312,981,585,119,764,259,272,414,365,529,31,701,789,981,243,569,338,587,620,789,908,356,763,815,315,284,201,990,426,666,299,577,249,651,654,141,734,851,16,620,762,585,325,691,790,642,137,877,701,541,839,867,802,330,864,362,187,191,162,693,773,912,851,681,137,787,469,38,621,55,82,227,194,241,878,800,673,347,542,50,474,514,644,489,903,533,855,411,789,444,720,866,571,893,814,74,954,512,305,759,469,92,222,298,255,676,62,220,425,454,472,517,536,283,384,276,387,142,715,831,361,874,456,102,898,490,139,415,362,193,903,388,672,151", "834,723,47,704,87,395,577,734,932,203,475,281,402,157,269,454,63,334,475,362,928,922,870,343,455,845,689,383,956,557,496,798,633,302,510,642,681,228,665,597,221,581,434,141,190,400,287,255,713,693,338,985,122,854,508,20,884,917,998,202,944,806,857,959,35,857,801,415,442,460,34,438,782,67,699,473,742,676,734,330,876,290,792,754,275,171,324,767,665,859,129,372,560,352,447,951,208,316,967,126,117,221,615,461,67,616,16,596,633,403,928,317,861,422,175,32,883,268,930,666,11,13,303,952,540,307,712,559,788,795,584,952,619,879,351,915,60,395,62,597,271,184,476,879,527,865,163,571,934,775,129,641,918,304,524,546,235,272,833,47,676,62,726,69,406,646,179,152,893,173,727,887,676,123,419,729,21,177,4,933,671,965,629,633,422,682,141,750,3,675,282,450,741,947,655,24,455,771,588,538,475,398,41,742,931,734,801,585,398,387,939,462,375,704,9,610,549,238,854,338,16,262,121,403,236,499,134,606,429,217,587,855,100,223,80,670,771,214,252,608,22,815,737,565,422,879,673,599,181,492,372,27,282,733,368,490,676,251,54,146,316,133,285,395,834,249,519,535,906,471,828,689,906,683,483,11,631,896,596,314,990,903,455,85,975,117,985,667,846,917,256,417,6,404,265,981,175,655,324,893,812,291,790,197,925,907,431,479,410,590,84,641,309,284,941,115,189,336,658,370,63,668,548,978,831,440,256,970,255,716,475,721,722,349,313,773,292,313,3,422,367,219,723,766,68,704,664,607,237,422,747,160,332,17,944,813,76,538,858,90,378,911,453,98,636,166,165,701,638,124,216,860,896,243,415,116,972,261,642,897,469,459,139,970,79,585,733,847,244,82,112,846,912,618,223,88,466,304,649,447,971,131,324,517,66,618,673,511,839,240,365,314,541,209,427,640,713,998,872,148,478,464,842,140,494,111,967,123,350,836,497,38,481,424,152,427,75,675,567,42,602,139,60,98,625,776,248,66,901,480,119,756,929,439,523,729,781,598,305,564,982,139,31,669,609,89,720,210,950,37,58,301,763,78,505,740,259,239,613,956,151,884,580,210,175,515,858,117,423,326,456,698,6,774,834,954,103,417,234,802,930,219,206,24,407,967,742,68,0,269,602,270,504,720,796,156,458,851,336,522,435,361,605,128,145,303,461,922,478,650,384,539,547,461,633,409,798,217,430,834,41,495,865,468,323,200,113,899,545,286,410,574,15,709,144,214,495,585,28,850,948,64,64,180,136,111,400,204,105,259,103,799,914,126,159,129,51,199,62,394,355,262,89,581,725,765,842,554,437,925,815,510,988,714,785,208,161,731,135,851,56,596,464,912,509,759,437,220,464,272,826,408,912,100,384,843,855,370,848,711,521,684,505,375,616,778,353,464,45,77,594,182,340,806,280,826,952,815,122,181,845,119,218,983,456,376,379,310,821,266,783,571,122,922,33,907,843,270,770,184,927,976,8,769,200,690,167,335,411,194,174,675,40,656,843,430,631,423,13,256,362,943,526,603,474,506,869,999,810,292,12,147,125,371,333,409,609,85,673,146,717,591,906,723,328,646,399,180,482,991,300,359,142,992,20,717,594,107,372,373,323,695,190,495,741,830,704,67,581,64,343,616,895,573,889,400,506,118,150,171,164,154,969,314,355,550,738,819,956,466,635,342,80,842,610,330,183,597,554,323,196,447,936,547,922,606,46,118,776,800,611,722,389,951,338,57,859,505,491,565,362,592,9,227,346,449,78,626,882,385,162,142,461,955,170,344,932,746,535,99,50,50,860,515,809,100,167,218,923,299,480,687,711,729,441,45,590,300,597,865,588,250,902,514,734,957,898,761,628,161,578,577,736,173,444,325,21,438,930,248,970,672,829,986,866,331,542,548,351,154,59,633,203,561,176,193,343,676,879,104,910,405,567,58,67,116,568,470,450,943,858,704,275,30,726,482,841,526,367,675,194,57,345,183,444,446,938,435,465,383,720,775,523,258,793,580,582,297,785,494,892,816,893,845,449,228,163,441,948,652,901,523,509,736,294,617,358,144,264,554,466,730,196,297,938,896,377,929,665,500,350,789,660,489,651,921,548,971,275,770,894,855,915,988,500,736,626,717,419,311,259,657,612,448,195,509,60,96,1,489,421,764,788,120,722,985,839,811,181,13,445,873,5,871,454,48,721,475,531,953,558,900,651,310,436,238,499,603,887,160,464,482,486,625,813,501,24,702,977,256", "676,884,370,258,268,307,154,534,644,991,725,897,589,208,158,190,61,87,511,468,57,360,674,66,413,701,219,234,57,932,90,302,189,690,732,527,575,255,188,48,728,678,923,621,209,510,293,635,23,153,686,394,148,123,913,16,790,139,971,841,452,469,805,388,624,436,627,91,901,907,961,771,729,82,564,398,456,435,851,896,190,266,400,661,794,756,45,326,427,638,290,914,383,641,770,773,597,356,247,91,615,111,580,495,207,999,419,301,39,622,983,403,174,927,718,401,427,833,476,511,973,313,657,948,954,644,957,138,528,556,387,703,823,771,44,824,376,265,718,378,484,49,618,977,89,760,76,436,900,226,145,747,524,280,577,667,303,161,35,913,675,756,427,145,620,696,782,505,683,839,505,615,662,633,547,662,220,126,952,25,707,166,370,56,800,175,610,738,499,165,27,885,838,262,197,798,834,347,745,379,977,523,772,905,914,179,86,954,520,499,883,699,280,584,540,352,928,12,632,285,649,319,984,201,199,732,277,379,720,784,4,10,263,463,740,999,145,851,883,962,876,845,759,865,451,922,366,602,474,590,790,679,862,532,120,702,848,197,764,407,993,304,945,236,2,923,127,496,413,738,58,60,38,464,218,662,306,749,864,805,929,243,954,27,15,895,627,796,592,361,311,33,677,372,674,442,676,276,588,390,116,181,906,498,186,542,559,824,42,474,776,464,690,819,41,221,440,860,837,902,169,178,687,318,123,583,572,995,340,467,122,387,680,221,784,401,275,583,491,754,980,256,508,227,287,305,341,506,760,817,852,811,673,313,330,976,864,497,947,969,451,294,294,928,831,5,756,708,755,65,654,984,838,511,24,461,391,452,476,962,769,912,366,487,241,913,113,144,565,854,74,355,831,281,393,44,958,590,739,188,586,971,172,932,996,416,275,824,473,784,501,571,784,700,630,565,46,233,306,740,510,760,476,448,869,105,463,780,520,638,403,654,534,57,973,817,329,768,405,273,567,665,129,845,930,470,895,526,324,728,42,504,988,729,904,399,48,438,264,930,746,808,613,198,281,702,131,876,536,267,26,671,862,130,124,236,690,322,838,841,5,809,400,447,905,16,670,112,554,84,124,514,186,815,693,544,953,326,385,777,948,261,350,745,726,484,752,408,269,0,481,242,134,219,871,278,87,484,251,607,826,268,82,654,355,487,380,912,216,743,160,887,391,114,693,447,510,698,910,532,178,678,626,506,99,751,645,991,432,414,159,728,188,212,961,323,395,704,558,113,53,625,709,450,368,487,117,175,729,25,675,790,928,769,462,495,829,215,995,337,206,794,392,623,220,454,305,367,522,257,827,624,744,697,538,806,131,585,995,702,334,596,678,366,109,433,455,627,55,170,390,148,884,50,940,943,441,550,606,206,273,22,275,465,475,810,390,643,394,844,66,518,848,792,820,55,362,11,390,603,35,351,45,125,465,174,163,452,153,462,944,658,563,923,732,825,193,528,886,65,228,110,9,6,706,19,742,453,328,190,17,680,878,596,865,561,529,802,723,957,976,602,686,593,864,95,141,848,413,154,443,200,254,321,640,986,643,593,331,849,389,433,904,960,83,362,721,738,536,844,941,630,906,460,580,914,769,994,432,370,459,340,367,822,925,170,629,945,777,708,699,854,247,288,690,544,686,962,935,48,87,777,623,444,194,252,414,39,220,198,809,603,542,397,225,23,920,549,100,724,235,140,262,938,968,406,342,489,637,165,442,405,771,669,264,183,378,378,921,478,670,330,741,114,284,244,597,625,602,458,417,278,189,613,101,161,857,586,349,983,234,594,658,56,146,575,555,636,364,29,201,733,129,108,216,843,987,902,104,188,111,968,983,543,272,866,958,35,76,462,694,939,328,928,246,403,942,117,664,408,819,229,560,144,335,1,615,213,349,58,145,946,436,914,246,354,261,980,555,407,79,567,649,741,198,672,844,940,203,632,201,579,195,800,143,784,221,812,976,817,912,747,77,457,811,98,335,397,736,64,890,106,322,942,797,154,336,823,393,292,547,356,721,591,391,868,51,723,242,55,801,346,414,615,950,310,189,811,234,445,435,223,194,402,993,956,69,547,566,304,398,946,751,973,178,285,985,550,921,175,55,113,227,735,457,246,341,675,769,511,822,606,28,935,104,582,939,272,685,170,544,193,812,502,631,738,732,72,418,190,120,836,660,294,733,372,61,354,940,272,325,812,784,797,628,435,636,730,939,818,165,489,657,446,779,545,158,990,266,226", "28,670,801,575,363,630,471,8,444,625,906,858,23,708,463,697,342,579,519,704,460,584,711,125,218,542,977,450,526,44,700,432,813,570,489,296,314,489,238,61,187,179,155,362,841,910,642,552,407,526,474,65,540,537,615,655,407,592,71,260,330,993,196,691,841,268,100,714,726,667,274,971,828,630,381,576,702,410,611,382,546,232,607,204,306,942,686,568,88,735,177,143,442,816,798,901,690,128,219,700,107,27,743,781,468,18,953,40,639,667,623,301,468,529,47,548,895,560,762,662,209,362,670,953,566,604,904,636,755,206,444,137,280,323,799,704,777,889,102,951,761,260,336,538,336,46,653,119,781,28,79,425,657,667,524,820,97,219,547,796,133,211,564,687,121,343,64,93,186,76,417,26,94,986,337,771,138,178,746,29,412,748,181,367,619,840,841,264,548,318,406,30,517,24,273,150,664,941,247,286,774,310,670,703,416,499,36,362,607,293,261,807,352,137,85,219,559,569,169,983,937,351,588,298,346,601,413,28,457,149,638,716,909,45,779,359,412,650,253,800,583,371,222,719,190,445,915,577,640,102,601,969,184,239,472,371,710,377,518,230,104,895,84,30,112,94,211,946,224,458,965,128,593,634,204,517,712,288,812,983,583,933,341,355,267,781,638,134,942,100,705,908,644,690,132,835,579,299,254,318,462,918,370,498,600,923,703,76,155,18,892,250,22,564,462,511,538,914,632,306,185,988,887,165,208,587,890,71,616,514,597,989,182,737,26,206,867,346,375,749,905,208,24,453,883,122,643,910,143,1000,529,234,625,784,721,546,679,747,280,98,137,529,197,555,269,640,893,887,383,342,484,798,636,447,732,592,471,123,888,127,99,287,742,197,909,971,737,782,389,431,262,579,226,332,410,921,428,215,612,579,561,47,94,505,515,312,99,773,502,507,359,471,674,291,420,827,848,714,541,219,675,967,79,346,672,946,44,526,883,165,553,79,548,546,608,293,691,357,61,145,198,232,849,974,599,551,549,434,465,219,426,770,630,219,737,538,447,213,334,142,662,253,411,715,835,772,97,858,531,531,472,260,729,991,362,340,832,881,737,211,327,667,774,952,988,734,107,486,736,127,473,125,175,269,856,424,527,399,915,490,61,887,432,317,29,894,953,565,602,481,0,937,294,871,547,228,784,998,421,639,760,589,68,401,27,674,28,779,242,160,936,1000,581,964,670,57,450,104,57,367,239,963,49,971,97,749,255,823,367,602,513,559,683,133,158,664,810,654,720,893,257,511,890,507,312,96,727,983,989,912,362,838,432,16,224,259,537,692,157,423,416,59,115,481,916,239,64,632,16,615,685,133,453,953,280,917,449,682,475,536,788,982,422,369,400,830,768,571,470,24,640,493,427,590,909,536,892,456,801,616,42,143,456,707,858,285,647,613,219,594,907,348,188,219,50,856,426,822,860,228,865,362,810,169,252,328,267,40,606,881,583,218,406,309,73,945,705,845,464,805,738,964,755,137,336,905,808,466,957,654,618,332,121,520,910,45,727,286,557,226,919,756,781,652,384,958,828,96,474,216,156,614,405,543,861,417,71,992,612,433,780,527,555,253,682,314,792,199,76,795,939,411,291,586,160,98,82,227,865,494,317,152,272,158,452,390,801,724,784,962,962,382,351,390,279,856,72,859,753,550,564,40,56,665,2,186,833,986,712,800,510,699,14,607,375,810,443,370,492,374,854,27,225,846,399,850,131,774,713,295,942,972,198,192,489,970,22,892,235,481,376,703,615,558,534,819,313,146,232,306,251,725,652,285,292,348,611,414,123,329,186,766,284,456,327,775,40,586,353,668,251,478,5,367,675,942,869,66,948,787,659,848,458,184,790,993,902,989,767,996,473,671,695,785,695,653,832,382,193,926,749,488,951,422,833,114,612,897,296,248,183,113,971,26,591,671,653,794,122,997,970,430,631,259,74,828,517,839,953,526,140,958,428,674,523,33,805,573,612,904,351,865,507,178,1,849,342,486,796,778,542,602,640,372,254,865,748,596,296,659,651,430,761,843,898,978,649,971,33,327,333,691,175,452,452,817,942,260,514,75,652,26,423,759,714,230,470,142,820,430,89,553,600,295,302,510,333,660,587,186,485,991,779,573,603,327,625,499,619,581,404,298,189,51,895,201,224,990,462,741,248,688,592,818,544,349,446,891,395,953,325,674,282,533,102,69,461,354,433,246,487,104,554,445,250,490,59,589,213,789,487,283,780,87,114,201,8,19,748,297", "533,129,455,407,134,279,906,291,352,843,948,566,810,670,987,473,837,245,644,59,408,107,976,131,132,670,765,382,264,763,437,640,588,927,298,886,405,42,395,925,297,858,642,707,413,700,366,525,73,444,232,287,217,549,3,213,294,908,909,606,68,584,644,318,188,813,779,58,891,311,8,569,33,501,999,510,730,612,709,118,941,554,970,730,151,51,819,784,972,492,852,939,443,120,253,394,792,529,668,461,553,11,487,380,895,433,501,791,690,476,756,640,959,134,351,72,912,800,725,254,553,656,975,159,163,788,936,768,724,935,56,95,269,439,250,390,355,99,334,554,470,355,699,687,273,992,728,68,770,134,990,819,768,652,898,732,518,599,360,978,504,729,874,898,573,661,818,430,509,560,787,799,365,506,621,641,431,716,643,204,779,883,774,257,207,479,213,247,672,685,375,931,595,353,376,376,555,79,83,62,196,464,946,268,420,913,409,78,309,638,514,827,283,326,623,842,394,884,238,565,359,690,624,807,967,529,920,66,642,713,799,63,695,377,658,211,562,407,667,874,681,18,715,391,807,515,94,33,142,445,859,37,962,359,565,368,9,650,652,440,798,258,701,689,342,239,120,518,433,709,256,546,160,826,960,322,865,16,852,946,581,729,735,714,595,799,432,68,150,921,749,849,902,520,172,554,697,711,984,229,459,161,347,884,277,612,618,9,970,747,724,516,836,218,878,969,155,53,64,614,273,974,391,859,981,47,782,851,643,64,670,539,953,610,630,509,905,930,596,342,485,301,798,68,90,716,299,40,595,429,849,978,293,414,353,486,377,474,716,386,342,94,550,84,39,684,422,143,925,22,296,747,770,690,132,239,310,767,949,303,672,136,151,494,531,689,123,247,473,91,8,556,301,418,183,698,542,37,453,131,990,371,210,575,59,276,998,307,99,63,95,173,316,374,836,892,758,792,673,113,50,598,480,165,92,532,932,707,791,393,876,292,742,4,622,765,554,865,63,262,287,264,853,77,816,21,57,805,283,999,227,626,449,989,419,560,760,641,687,354,890,733,101,199,553,449,650,833,24,572,207,653,886,413,545,25,268,768,807,778,439,244,157,721,501,121,658,16,199,55,963,882,948,721,237,860,953,255,673,649,197,234,990,699,833,2,434,311,270,242,937,0,995,176,681,577,43,983,117,832,629,252,582,880,619,994,331,909,879,893,729,721,993,591,326,852,501,698,164,898,938,853,284,694,566,460,412,393,317,8,290,822,636,826,526,888,565,229,80,795,297,696,969,184,340,112,171,564,976,543,357,202,716,858,645,428,339,443,974,154,832,237,952,761,158,829,13,97,762,640,268,913,249,555,125,555,130,229,566,359,929,515,341,649,250,495,265,68,27,540,846,598,844,537,578,276,57,399,945,107,886,722,486,925,892,312,668,863,283,911,522,787,265,352,569,942,155,840,814,365,488,380,759,240,431,517,30,865,67,16,268,438,116,785,342,33,56,448,967,922,308,841,782,338,217,69,57,321,316,721,48,365,308,489,856,826,742,300,705,82,12,106,932,650,539,509,512,352,298,2,10,71,189,430,340,595,845,101,762,443,778,565,319,343,319,460,419,606,766,524,625,571,474,892,405,267,989,818,428,942,407,14,284,2,12,37,279,194,607,679,186,609,20,142,296,557,933,602,99,703,640,673,149,266,702,477,407,911,850,755,64,65,939,458,681,72,108,144,785,24,555,169,467,791,949,884,996,184,183,802,529,256,690,935,682,91,591,223,691,94,592,556,906,135,146,246,49,262,216,107,969,124,147,731,806,24,323,125,876,33,46,26,998,235,467,628,411,339,461,223,729,264,424,225,380,285,434,977,699,300,147,761,442,844,923,434,319,239,232,347,581,330,657,40,974,635,327,522,79,540,528,692,160,384,475,616,150,896,601,330,722,735,666,130,33,405,707,909,602,966,259,712,549,312,895,547,611,973,718,236,352,920,288,515,960,852,456,839,663,985,59,601,194,604,985,706,371,115,679,14,470,66,291,268,197,219,320,976,389,787,569,700,763,1000,842,737,610,69,312,844,489,924,224,276,792,741,549,778,340,840,486,473,959,555,396,428,933,64,675,936,228,234,781,516,647,232,638,107,573,125,573,347,771,807,922,371,767,221,887,173,363,536,974,336,598,171,876,634,424,438,477,816,760,58,380,118,728,87,750,925,964,837,944,400,217,928,728,596,693,57,83,238,486,315,859,583,937,667,244,360,177,863,142,24,621,473,769,551,924,293", "256,831,849,823,415,938,921,254,652,538,145,569,440,742,353,499,586,2,443,136,403,425,507,263,13,765,189,684,925,326,723,914,842,586,120,414,478,709,152,839,979,362,153,940,269,704,485,221,529,954,439,417,655,913,955,851,750,855,803,442,645,124,442,541,345,55,498,822,325,338,552,983,294,665,628,117,743,173,696,630,578,909,45,881,267,829,999,718,751,851,440,616,325,397,790,345,628,573,355,698,315,657,970,585,36,150,725,206,814,76,721,23,283,188,489,517,142,131,130,730,848,107,805,640,190,3,338,508,274,317,593,810,809,695,788,971,352,797,208,746,384,652,675,603,524,620,962,987,874,909,272,574,772,22,461,964,133,296,162,161,81,941,5,839,355,578,257,69,484,702,526,193,494,67,968,821,11,10,75,462,67,347,244,398,411,231,425,373,285,225,387,668,40,992,896,945,227,752,189,492,856,420,917,420,195,960,430,594,977,883,720,280,928,740,95,323,449,112,58,933,332,166,706,479,244,442,197,510,779,386,741,187,613,883,813,733,634,120,908,685,952,622,88,223,61,476,326,283,852,524,783,169,154,241,475,87,720,192,743,267,487,99,113,261,935,667,864,967,845,616,42,333,105,505,492,173,625,191,753,62,761,544,854,642,997,855,556,533,75,263,990,682,421,640,401,666,735,552,513,952,582,871,334,958,9,742,883,101,756,206,307,477,849,473,373,137,185,707,968,147,890,664,412,284,423,919,632,152,828,730,627,143,81,344,356,381,173,768,270,114,679,989,431,170,963,518,236,513,758,569,423,401,26,305,575,442,969,323,563,123,411,235,747,445,648,73,674,359,992,623,739,118,888,84,585,345,124,476,376,436,352,836,343,367,268,103,894,666,841,331,74,838,797,829,921,508,210,461,707,507,380,104,866,312,424,778,309,984,118,930,382,403,705,196,739,325,494,965,931,952,491,973,49,914,53,417,678,370,711,368,22,810,733,222,617,891,241,540,40,406,764,643,674,567,120,600,724,995,176,376,80,199,253,86,678,517,440,476,237,329,939,252,827,707,65,347,476,271,608,630,761,496,748,281,629,511,316,42,438,205,383,53,235,579,385,308,318,563,586,968,348,130,735,860,676,530,192,792,810,430,592,927,800,992,923,264,539,29,504,134,294,995,0,767,572,993,931,420,17,439,709,538,586,284,529,540,828,716,866,792,535,863,475,257,122,268,576,14,813,539,595,709,524,78,895,879,915,264,174,314,361,724,426,416,71,60,225,489,857,962,284,217,665,46,617,62,943,259,669,836,378,589,929,185,723,950,292,449,707,910,478,956,786,553,8,772,387,978,779,761,144,670,325,212,800,644,828,756,874,66,18,64,586,106,546,730,883,45,267,107,694,490,231,614,905,381,649,282,312,983,823,583,566,492,377,751,65,865,797,313,430,197,713,445,178,691,962,669,399,328,788,605,764,10,666,61,668,221,788,990,158,735,102,494,837,898,649,120,776,220,998,488,40,910,273,202,673,656,659,793,506,647,336,470,831,681,221,291,810,152,497,118,336,697,668,682,330,34,979,562,790,869,448,810,216,652,730,918,517,397,337,340,352,921,764,296,615,867,664,802,172,149,731,448,375,466,261,14,248,793,806,156,540,806,487,276,540,228,904,472,474,645,342,79,886,796,922,225,562,168,968,632,441,637,750,690,973,591,386,261,524,375,274,43,764,607,215,62,760,347,598,532,698,962,147,679,13,207,594,578,291,183,987,9,95,253,131,639,166,39,309,464,692,755,505,581,826,856,867,770,261,299,810,453,199,151,929,761,729,234,694,368,102,533,978,276,894,955,191,673,199,740,356,853,881,865,824,715,646,307,702,230,408,942,650,902,532,436,110,363,793,131,792,542,912,351,256,913,928,395,668,434,131,959,761,844,530,291,834,248,883,634,646,830,985,521,458,499,97,984,221,990,731,454,21,459,448,874,456,833,237,702,742,602,213,865,533,593,913,404,214,343,642,936,130,794,521,695,745,617,192,403,780,304,604,388,130,346,760,548,915,871,399,12,551,876,756,194,340,307,683,664,985,49,494,372,458,784,27,166,353,287,774,868,379,819,172,34,551,845,266,664,419,850,658,132,677,505,254,297,817,422,555,81,614,89,955,183,798,700,237,447,223,189,405,885,358,691,803,99,311,354,483,137,454,105,733,410,779,606,198,314,211,837,906,324,861,836,761,908,989,212,507,232,76,959,163,575,506,514,559,744,890,488,28,893,158,51,752,920", "904,500,326,406,175,203,504,471,525,103,128,834,126,219,581,987,807,243,803,190,748,45,32,228,178,545,480,309,647,892,272,458,580,202,885,44,365,648,61,641,662,168,614,356,769,346,718,963,101,287,790,814,462,97,124,193,488,152,527,290,180,294,55,191,251,751,939,440,155,37,214,112,368,848,188,417,229,504,125,907,274,877,488,464,100,715,742,856,279,583,388,880,571,55,719,281,326,263,371,114,193,171,528,879,141,292,7,22,597,201,122,614,203,446,75,486,254,503,886,801,565,35,540,244,416,518,345,642,677,879,216,694,840,664,546,172,448,803,709,88,896,627,605,62,697,942,539,107,422,485,892,228,176,730,544,828,646,772,781,751,743,603,987,209,256,979,763,950,636,77,515,782,508,560,448,811,911,474,800,384,81,616,514,940,602,64,29,961,992,874,931,147,714,837,737,146,688,846,585,825,916,349,387,981,29,529,641,921,772,360,417,539,679,830,937,812,536,495,664,211,760,569,112,114,160,889,337,117,993,231,364,448,697,332,930,447,688,916,762,526,779,404,376,34,674,622,690,605,382,924,566,747,997,47,903,825,493,407,341,414,543,611,141,67,670,848,856,817,784,816,863,684,722,139,107,548,915,979,102,563,247,286,176,720,665,444,957,503,491,430,151,158,431,745,743,832,122,786,174,455,372,64,439,952,792,705,641,902,707,758,661,796,149,40,333,527,174,194,589,298,37,796,12,866,26,645,74,623,142,947,637,642,895,647,70,956,116,990,37,308,528,719,422,920,751,35,86,867,734,810,626,211,995,309,349,680,666,792,346,928,446,972,156,509,499,61,166,301,158,680,546,328,844,770,715,717,552,338,205,214,725,857,141,23,941,661,977,535,870,283,726,421,172,658,178,519,666,365,285,431,511,802,46,809,617,261,575,807,848,262,196,584,319,901,757,666,697,891,282,230,975,269,902,188,724,804,61,672,524,215,296,3,480,891,281,217,277,141,550,184,996,747,315,829,196,128,957,267,735,978,942,445,582,171,339,45,615,918,151,102,133,198,369,355,821,930,15,555,832,43,151,504,789,910,391,281,905,740,74,361,839,938,187,268,823,683,339,890,337,299,686,686,360,71,241,393,248,442,787,378,388,363,46,233,172,813,690,364,720,219,871,176,767,0,207,610,547,836,702,954,90,892,123,667,408,138,496,222,911,14,981,370,955,196,280,623,257,627,476,153,24,892,546,173,823,371,265,715,99,251,758,812,167,443,53,425,467,503,711,130,928,841,224,819,741,360,710,492,584,228,579,613,732,367,703,535,271,835,135,156,771,530,829,956,588,878,425,574,5,668,373,847,378,407,82,469,851,461,318,181,177,587,684,131,159,30,799,29,10,826,286,14,74,350,870,619,70,95,107,754,472,105,783,715,972,193,77,970,629,286,898,198,989,393,871,535,268,58,594,826,736,876,311,37,248,915,990,558,689,34,396,954,266,437,362,936,124,428,111,615,110,150,57,974,230,845,183,155,343,431,936,743,739,707,479,880,889,531,816,66,739,904,483,401,624,392,442,926,978,133,401,812,202,334,231,362,527,242,271,89,271,635,395,181,815,484,908,51,851,319,648,933,714,434,472,831,570,121,143,292,70,691,811,632,264,813,683,881,742,807,164,163,51,376,663,494,863,413,943,276,26,572,648,180,649,584,4,723,438,241,774,572,270,83,449,533,527,291,330,510,327,540,825,784,811,533,747,885,819,121,211,974,387,226,601,667,506,924,44,506,857,697,295,459,631,524,514,997,667,632,30,857,570,344,898,891,746,212,98,978,529,663,707,532,550,700,169,52,513,190,337,911,290,179,242,108,626,748,879,259,865,568,86,104,372,144,616,206,178,614,88,465,169,892,133,54,237,71,776,111,350,997,129,73,194,135,850,405,300,246,922,742,420,228,768,928,359,579,496,26,113,925,226,894,446,848,93,990,182,287,422,294,905,193,224,475,210,21,259,276,274,734,762,465,491,842,921,87,354,761,332,286,786,36,749,48,12,232,380,846,112,511,781,982,560,454,99,654,317,507,673,723,211,566,589,107,711,325,501,81,218,995,189,266,656,811,783,861,442,285,627,539,790,735,991,766,337,51,943,826,266,821,292,500,115,655,596,583,690,790,947,123,472,695,307,72,329,656,286,751,70,79,110,374,773,351,694,601,688,704,147,753,871,53,922,412,785,168,961,537,14,864,700,479,153,30,224,944,914,978,838,68,644,528,727,809,560,623,701,272", "606,422,32,50,483,728,752,879,215,736,281,860,430,755,448,704,190,306,359,843,715,243,339,148,815,716,811,622,612,557,943,172,332,28,481,649,291,267,97,108,460,504,316,929,158,686,836,45,852,358,658,928,187,763,281,724,989,481,721,536,151,408,877,888,911,89,590,889,300,153,952,498,286,860,165,289,64,560,494,28,604,136,178,800,827,940,948,213,786,103,140,390,89,846,608,746,480,361,987,994,920,906,690,62,502,197,220,813,19,991,470,199,370,186,362,80,717,855,123,950,609,58,104,808,860,149,238,760,49,935,660,739,241,656,943,3,352,128,323,23,586,856,898,407,584,252,769,844,787,503,624,801,626,785,738,529,706,951,895,63,476,296,674,139,125,665,831,832,840,202,453,253,695,865,396,206,623,664,378,396,361,547,886,35,823,59,556,34,759,263,832,229,731,987,885,514,920,9,12,966,616,577,247,226,928,961,812,426,577,969,384,342,824,208,333,537,112,820,42,584,259,938,413,127,924,863,268,227,877,82,350,808,494,424,806,421,283,723,874,270,526,461,69,812,485,945,282,806,770,193,100,828,949,75,126,90,222,842,512,700,807,245,887,469,23,826,775,452,937,818,289,110,665,274,915,600,114,905,763,957,150,173,937,124,406,71,87,235,63,855,927,947,797,994,913,939,759,806,203,189,80,760,67,718,563,294,341,920,656,335,704,477,901,772,226,503,585,426,959,936,410,538,968,524,550,53,301,987,297,419,906,214,962,495,847,866,266,786,363,559,804,822,89,413,828,757,46,181,524,147,813,292,158,542,86,60,307,257,555,631,684,289,829,518,196,302,777,1000,630,951,675,984,225,494,65,43,889,560,867,40,256,9,183,248,863,89,442,444,112,809,931,562,87,559,295,932,680,354,105,642,386,225,330,78,693,410,973,381,349,756,175,322,38,741,60,991,927,277,349,726,559,821,312,625,280,650,507,312,184,652,731,806,95,298,571,941,986,207,176,543,623,209,225,742,853,201,920,946,887,115,800,524,508,661,126,481,914,53,797,846,780,505,832,673,760,887,335,135,541,432,513,1000,340,5,613,332,947,691,531,869,86,598,409,47,47,478,667,976,705,285,216,536,952,733,730,553,237,824,125,532,423,143,97,419,600,843,733,697,796,871,547,681,572,207,0,333,392,947,883,662,738,790,663,556,119,217,310,295,91,119,962,307,89,752,311,334,222,687,929,650,237,999,559,529,539,660,502,218,693,148,144,121,238,427,437,441,505,229,935,70,295,871,441,304,344,807,682,280,746,915,669,262,107,870,327,965,440,57,709,550,359,885,528,166,852,450,494,234,154,468,843,874,414,12,895,178,301,526,993,225,708,381,679,800,206,99,630,611,878,505,189,466,100,768,854,168,698,230,975,555,283,531,733,252,82,443,587,821,799,889,14,662,934,230,593,332,572,92,982,272,755,940,696,812,105,27,518,482,868,916,202,346,444,155,344,773,34,894,819,204,567,259,852,826,727,919,888,196,133,583,858,424,783,988,672,433,650,147,456,974,288,13,85,18,611,233,479,629,769,682,351,515,342,132,626,163,198,178,682,118,666,195,92,875,991,793,588,819,935,410,895,133,899,328,286,780,854,615,211,963,50,558,550,11,168,393,626,641,388,339,821,79,246,168,146,208,145,69,885,503,708,210,171,564,206,744,191,836,466,582,78,149,243,232,852,902,961,574,320,885,265,51,947,797,388,251,15,383,843,118,872,101,525,686,692,21,479,69,657,880,183,75,779,373,862,666,765,95,569,904,708,85,360,304,424,528,87,684,602,179,784,493,148,652,551,264,651,448,69,689,498,800,189,353,53,979,899,891,814,626,744,974,865,875,668,788,304,287,244,488,522,974,305,973,756,162,705,930,980,941,834,286,295,928,174,87,845,772,367,720,244,318,699,273,883,929,785,215,913,763,692,573,336,812,598,6,270,631,165,917,332,981,876,874,953,96,793,552,599,31,340,74,199,674,603,620,514,562,721,701,232,557,500,13,139,616,633,896,858,110,741,124,678,161,248,985,200,369,911,179,389,430,429,718,803,17,18,49,6,394,351,312,96,348,125,83,303,807,738,646,617,396,292,657,480,577,584,489,52,116,810,310,830,21,260,436,581,832,370,867,420,801,172,435,312,41,922,677,266,120,421,443,41,447,223,995,578,60,159,179,587,946,911,1,144,960,63,994,611,707,312,650,325,831,179,275,973,12,211,435,663,799,557,747,384,918,595,953,69,366", "334,196,329,451,103,848,302,91,90,200,19,576,20,156,850,618,765,466,783,623,545,254,68,299,739,807,682,671,882,42,188,671,117,798,831,562,969,39,608,198,86,503,925,499,50,953,135,915,655,206,458,334,911,496,273,305,524,615,952,589,93,59,386,23,901,415,486,600,187,985,834,729,764,794,88,865,843,952,528,486,505,584,808,714,519,53,250,280,277,182,440,488,438,374,171,835,853,337,504,11,363,940,729,507,796,22,132,786,348,774,671,759,147,400,704,188,562,998,517,86,858,975,422,490,181,799,450,60,859,640,890,127,115,103,115,713,114,576,860,103,391,128,799,147,50,530,510,307,550,192,466,889,123,134,804,214,695,401,3,15,983,560,135,534,318,194,884,677,580,188,325,553,449,832,514,479,662,889,802,460,481,60,605,169,814,764,591,798,859,744,594,796,499,464,410,112,82,616,590,583,897,732,330,18,530,861,521,166,870,760,143,761,664,784,590,321,271,332,805,806,482,297,839,74,114,748,259,688,440,480,154,123,653,346,729,347,925,63,507,239,178,956,664,203,108,695,717,276,408,358,640,513,57,236,960,455,171,118,218,379,279,283,375,694,223,223,642,767,332,966,21,646,339,816,240,484,735,632,54,886,787,787,347,712,723,78,140,642,51,782,127,755,431,256,237,583,25,414,210,887,297,647,718,580,399,211,365,346,667,678,545,581,266,941,524,240,846,244,6,193,765,492,567,551,921,448,760,876,268,812,848,99,381,442,23,849,698,542,884,840,650,84,155,365,72,229,945,4,474,590,85,620,989,965,655,924,592,148,862,868,523,123,503,927,937,674,392,215,93,177,614,984,993,593,883,382,30,658,958,94,168,969,226,562,772,162,389,41,570,951,186,400,718,121,935,512,779,587,818,742,705,918,991,859,690,441,162,186,50,90,439,41,489,122,909,698,27,479,735,498,527,26,266,970,702,270,754,309,526,434,682,599,487,656,58,988,111,396,425,931,718,290,796,791,71,840,88,179,236,881,827,471,866,349,161,318,364,815,502,196,392,346,530,381,536,539,454,687,572,94,251,486,133,303,726,221,519,715,333,684,971,89,719,387,150,482,269,444,408,304,592,364,507,902,903,87,104,291,427,993,971,139,418,28,772,89,187,890,156,278,228,577,993,610,333,0,459,523,824,431,168,46,883,294,577,518,344,201,401,941,910,653,866,77,748,188,541,557,795,305,107,828,409,229,155,232,693,710,618,634,240,638,236,894,87,274,234,706,633,426,84,320,44,875,624,181,130,265,61,97,839,587,39,396,995,173,635,268,836,412,738,119,240,270,104,51,198,931,424,181,95,837,230,777,881,671,664,850,67,922,769,718,861,452,810,296,729,585,44,292,78,863,899,415,945,911,340,645,731,798,388,694,284,8,618,973,278,529,841,359,289,714,224,399,470,305,997,159,917,704,703,974,544,734,955,224,712,735,373,962,510,358,286,797,838,542,504,486,325,555,489,833,661,465,16,236,877,7,357,956,804,728,177,312,440,725,713,870,634,273,610,617,471,693,496,109,382,886,268,405,834,509,366,56,500,578,590,438,851,250,414,656,276,825,538,556,986,403,925,389,157,136,962,394,72,26,683,533,937,467,203,54,221,47,208,381,841,910,135,839,46,144,584,507,560,947,528,450,143,249,820,144,491,772,16,747,475,434,62,992,595,167,179,601,203,781,810,416,972,59,480,45,128,588,605,100,312,104,387,329,946,149,920,448,253,337,69,733,143,746,632,580,579,530,198,286,700,686,704,202,519,159,44,412,892,551,136,818,403,296,754,443,209,504,595,273,6,109,588,551,485,205,420,364,721,178,549,977,516,871,952,398,31,519,178,963,592,981,890,80,539,639,134,461,538,543,86,993,403,895,774,449,783,387,769,222,271,317,2,860,657,254,242,854,175,771,561,678,981,146,609,109,237,135,214,758,618,237,184,91,871,675,94,337,490,152,206,54,897,449,580,673,647,3,835,277,515,937,331,751,516,970,838,867,235,673,407,834,50,835,334,292,66,742,467,870,289,837,914,325,253,494,62,385,794,719,158,93,471,139,251,523,137,809,721,519,66,741,7,127,562,409,651,578,335,308,757,81,986,104,499,236,201,564,433,535,148,326,931,999,796,774,733,370,797,474,276,986,211,238,510,219,591,344,877,597,525,729,759,927,584,619,368,653,576,726,912,321,865,368,213,106,671,406,341,760,107,526,119,747,145,538,444,278,670,600,948,990,693,627", "472,936,750,566,983,258,415,435,757,601,434,244,858,252,215,420,575,455,698,580,504,905,753,239,375,434,579,68,470,863,670,459,169,346,283,614,748,706,945,271,693,127,266,193,825,944,584,476,786,204,9,505,980,236,895,195,240,773,239,310,115,290,329,602,799,446,185,917,456,505,50,712,89,476,568,94,842,19,789,247,785,914,149,818,78,289,180,167,55,604,738,401,137,426,327,287,268,484,871,760,232,104,158,988,287,733,589,246,262,886,715,215,874,285,594,140,185,273,913,155,210,87,893,673,969,358,583,194,516,188,845,845,52,617,405,853,390,460,796,564,44,856,576,254,130,800,257,17,210,568,892,888,79,922,143,622,39,102,206,874,944,757,580,87,610,190,555,515,811,81,788,839,640,723,572,650,233,595,715,338,286,980,828,953,960,856,660,294,116,148,512,393,547,871,150,251,194,567,540,108,14,896,781,154,167,982,780,609,594,699,378,449,348,293,604,123,944,473,776,474,506,477,932,907,638,760,102,579,528,178,766,643,436,573,105,521,863,137,645,165,856,355,979,515,415,632,96,786,323,657,936,49,530,272,761,523,892,825,748,952,17,778,855,529,975,407,758,745,551,490,599,997,549,745,697,725,444,65,858,331,394,356,433,449,911,637,461,40,139,497,542,506,72,157,53,561,785,284,65,536,893,501,50,56,932,672,947,425,919,233,511,184,355,778,919,190,470,12,397,572,207,996,878,171,804,171,111,536,602,821,842,353,225,256,264,268,112,317,237,621,863,449,974,599,718,842,474,109,111,450,804,576,59,340,400,532,66,268,504,513,327,214,158,980,820,779,867,379,510,195,391,836,479,550,452,90,856,150,389,992,653,941,818,105,653,410,993,410,129,917,941,797,875,119,133,637,392,796,868,102,390,545,793,668,658,137,310,426,864,39,802,388,841,795,86,94,199,545,451,947,552,37,791,171,816,130,299,297,382,893,836,295,41,631,124,20,563,451,505,497,512,712,66,228,915,532,74,674,245,529,492,200,912,481,755,21,553,997,430,658,426,859,656,70,753,816,553,823,742,383,139,618,979,513,261,17,194,600,566,285,856,857,638,231,955,526,841,188,633,34,901,320,247,508,264,708,447,179,288,584,997,603,327,758,853,291,63,50,458,87,784,43,931,547,392,459,0,508,452,920,989,977,328,51,613,476,517,681,773,289,3,999,282,928,118,588,803,202,657,792,595,972,23,779,729,539,210,542,703,834,207,288,230,909,438,859,761,344,219,672,491,368,787,495,166,15,627,637,488,465,18,156,804,322,25,617,317,488,556,211,393,523,35,431,65,992,635,199,481,169,987,425,349,222,421,135,869,236,869,916,92,196,641,489,141,157,838,563,502,334,799,972,683,416,162,267,865,582,659,898,525,3,999,188,94,237,914,963,554,909,460,69,223,449,65,872,251,597,506,411,373,323,418,492,831,283,158,660,671,646,711,560,516,97,978,317,181,44,13,164,475,986,248,340,484,405,652,91,414,574,249,186,450,756,453,92,464,114,710,879,7,346,134,613,574,941,573,263,935,971,776,410,760,50,608,393,872,461,183,747,308,163,572,966,738,232,821,303,856,678,267,106,584,323,618,244,161,362,727,633,879,420,451,119,665,957,508,548,942,967,832,405,888,252,405,473,14,565,200,228,208,780,883,595,223,936,267,179,969,938,167,136,541,743,216,838,190,738,840,108,418,221,989,574,695,701,498,514,545,791,567,747,360,159,761,649,902,295,215,243,275,205,418,999,134,122,267,282,594,63,882,296,189,129,502,528,829,764,916,603,212,498,587,226,128,256,156,104,864,601,408,14,55,150,607,437,277,180,135,894,784,372,756,475,668,156,822,701,393,416,413,345,775,954,492,790,33,818,904,949,518,873,584,811,385,851,943,530,564,973,545,512,492,945,847,764,671,609,559,77,876,950,976,294,586,899,125,950,205,783,625,329,89,266,123,668,512,72,349,613,910,507,970,29,819,873,794,56,274,9,47,800,770,965,113,6,333,255,380,795,547,634,296,94,44,612,347,111,572,86,525,647,606,557,605,584,104,276,104,675,706,977,357,112,467,504,903,370,493,677,369,458,186,627,561,146,115,77,584,8,165,900,63,903,622,585,443,358,976,438,561,179,839,39,200,790,767,688,618,673,568,455,605,924,168,995,646,882,304,449,282,291,759,206,536,248,561,389,706,77,482,232,995,591,596,310,228,334,756,987,124,696,855,953,561,952,992,430,535,587", "206,719,458,20,327,574,329,325,863,453,451,613,964,403,832,879,97,116,824,747,928,322,938,303,222,707,611,859,248,136,239,682,773,962,78,652,374,265,291,578,114,643,626,751,458,617,154,326,49,151,561,811,510,939,647,139,442,582,70,494,811,267,770,624,618,579,407,634,893,985,216,40,151,574,698,385,881,700,682,364,269,264,241,458,138,924,382,639,461,417,354,158,533,747,421,245,786,450,813,171,815,882,844,28,515,435,4,926,413,267,151,886,777,756,11,487,994,48,73,906,823,872,844,506,588,855,647,912,611,44,605,995,162,752,989,183,235,736,439,715,580,670,214,408,842,354,10,598,537,895,686,145,295,709,376,846,799,854,505,194,142,605,665,674,505,199,132,891,458,656,756,991,718,240,409,136,562,432,537,751,650,760,694,399,579,773,710,534,88,986,511,642,306,465,973,629,836,903,368,813,952,168,446,767,693,397,714,433,946,117,876,746,724,408,521,708,879,375,89,457,945,294,415,880,696,89,287,179,568,792,97,505,317,296,428,866,87,943,738,616,362,662,262,619,269,98,871,390,983,883,590,519,328,300,335,915,385,226,39,905,690,796,715,627,93,381,982,482,451,355,468,71,790,87,792,465,716,978,114,324,921,62,221,985,363,590,383,812,833,910,345,985,173,97,259,977,485,787,641,623,293,292,688,812,548,523,773,239,776,388,650,852,819,996,506,441,270,887,185,305,731,540,886,428,92,572,193,70,241,10,823,7,887,439,178,275,347,621,297,114,941,736,585,26,257,231,175,973,360,961,738,41,347,651,587,988,356,590,206,291,641,138,485,165,53,235,592,735,588,911,212,578,518,535,481,247,396,455,703,224,376,789,458,61,243,205,249,503,537,611,67,527,59,302,747,626,487,604,29,516,196,840,440,647,294,854,122,877,536,435,249,132,429,858,129,767,348,82,355,619,543,424,348,416,56,719,854,368,212,850,706,185,889,346,602,650,670,113,401,894,708,112,72,149,774,132,363,450,314,91,193,902,469,492,365,612,780,512,400,376,835,205,840,364,427,482,251,511,748,136,763,927,541,159,225,366,956,522,192,962,64,401,615,79,393,716,689,929,550,662,178,771,18,207,755,111,480,549,865,724,747,355,45,673,889,591,342,692,851,484,998,983,420,836,947,523,508,0,421,953,495,566,535,433,459,33,669,108,501,144,220,470,345,608,67,996,958,526,109,47,787,787,316,373,232,323,463,916,998,275,923,509,532,87,653,513,94,664,304,844,832,767,673,897,104,425,496,516,392,948,366,293,264,799,716,691,756,579,564,433,724,545,491,364,308,309,593,936,802,631,636,805,8,287,708,374,658,351,480,413,14,829,439,341,570,736,183,756,925,863,34,332,690,482,529,645,60,320,955,291,421,790,789,426,852,583,633,526,887,388,509,531,746,494,962,590,795,178,744,364,131,759,306,373,832,911,977,690,456,588,313,789,638,180,967,574,575,669,380,28,663,864,932,315,184,146,677,425,501,793,200,263,751,487,249,634,930,471,651,180,763,337,544,762,406,420,201,507,303,935,781,783,427,183,791,902,590,205,129,16,71,897,50,353,246,639,964,60,872,77,563,831,980,629,65,884,88,218,448,147,803,368,627,649,654,351,294,491,579,655,614,864,538,406,27,499,604,757,549,501,362,689,180,56,203,623,796,949,310,667,903,619,24,344,341,856,215,613,555,293,370,943,103,975,448,641,434,339,625,954,226,11,134,795,827,338,558,511,473,266,75,18,498,168,238,757,864,464,182,245,46,9,959,323,476,408,458,205,591,82,378,102,715,648,587,892,235,902,895,183,811,62,581,557,928,382,563,395,703,256,329,724,883,258,894,228,453,581,513,575,69,155,860,105,24,547,416,742,666,496,945,137,177,211,120,764,328,675,35,82,844,40,417,266,128,393,180,161,211,833,115,705,95,35,241,243,441,262,686,178,252,708,356,5,252,801,174,968,459,85,716,733,630,414,452,804,529,106,834,54,964,830,401,410,351,446,539,5,918,543,81,723,803,894,495,928,760,262,712,483,681,333,138,459,468,569,871,347,519,93,195,283,941,146,186,313,727,973,665,923,121,93,84,284,834,906,107,860,710,654,982,635,820,10,473,419,891,203,364,911,901,957,485,14,35,525,458,346,897,97,538,621,598,898,175,104,267,787,76,614,421,13,343,655,965,78,408,136,967,714,503,938,232,132,417,187,3,499,330,176,112,528,993,836,445,854,302,253,990,622", "942,10,445,547,45,425,592,501,604,834,809,746,379,367,968,746,725,189,266,412,192,499,450,396,36,247,200,39,628,680,294,767,477,602,575,291,217,988,31,863,205,329,12,506,281,935,729,962,838,209,88,515,641,643,325,115,778,103,339,617,962,451,377,929,955,626,260,843,926,938,395,812,805,314,719,601,451,626,732,991,613,221,215,415,676,115,40,817,798,615,6,601,426,935,771,252,499,259,302,428,463,302,772,996,986,755,358,686,860,675,437,850,144,20,862,742,356,313,16,238,578,101,32,351,678,765,44,135,758,49,513,727,846,223,659,21,137,219,297,459,159,129,501,441,561,703,788,658,604,407,968,270,502,588,727,493,985,631,587,402,329,20,38,290,733,919,792,747,152,938,586,158,630,350,92,123,955,408,445,289,691,304,139,305,239,609,866,567,868,491,844,486,870,874,39,208,730,371,449,259,788,212,828,437,981,519,502,287,528,430,588,479,31,86,158,456,78,162,733,998,61,78,243,634,564,530,815,700,771,314,806,399,229,92,308,549,651,632,190,537,425,538,781,549,346,259,10,293,918,254,492,976,802,947,219,414,883,156,264,103,702,280,744,680,704,531,272,762,319,450,398,722,174,628,738,199,719,755,330,258,297,825,545,483,848,584,777,424,89,835,427,919,131,902,734,958,556,423,335,614,63,37,481,966,442,252,474,30,755,373,344,767,540,360,865,357,710,876,768,326,17,662,916,918,904,826,372,694,295,599,660,22,83,258,886,311,60,179,723,283,712,794,321,40,300,11,721,194,935,803,393,207,928,659,502,809,251,48,223,466,737,15,400,567,942,49,423,347,876,82,402,196,528,872,19,181,682,198,518,847,963,405,968,617,901,792,457,140,830,518,450,453,306,723,964,137,94,454,77,41,590,351,494,594,817,965,737,403,309,281,477,543,662,499,864,798,958,652,820,728,285,673,183,683,372,813,79,416,352,22,235,168,6,952,665,418,364,766,469,807,463,621,711,584,425,9,428,915,913,567,834,553,92,26,616,790,856,832,690,154,580,197,369,175,682,494,370,610,377,828,350,161,68,113,484,847,864,929,429,843,788,784,135,987,449,767,291,933,548,491,715,947,539,88,610,889,686,346,728,319,616,633,759,604,6,127,875,215,336,251,421,117,17,702,883,824,452,421,0,880,450,309,323,977,204,65,562,262,574,288,661,576,640,884,558,476,678,348,359,99,6,609,403,962,561,303,438,254,193,513,340,757,837,61,919,248,781,668,284,625,592,585,164,295,508,198,567,824,298,902,535,325,373,788,928,971,569,174,17,91,434,171,326,817,427,893,438,251,32,388,368,782,486,861,592,499,820,238,814,620,255,26,480,775,778,501,775,252,495,528,50,984,373,876,666,200,492,100,55,958,980,453,580,200,953,5,509,772,237,607,753,525,476,9,220,157,537,694,802,110,43,375,376,807,656,310,925,921,280,603,340,280,909,831,34,363,624,504,374,772,213,469,645,854,478,56,507,230,157,5,111,63,364,733,368,379,319,939,16,674,364,238,209,150,425,625,633,28,525,791,644,957,325,83,912,203,590,705,24,217,294,228,464,442,415,562,62,892,628,747,287,529,980,632,299,236,487,350,827,233,629,91,632,718,351,876,451,390,319,253,944,166,639,512,181,840,524,122,481,76,319,727,649,447,673,287,447,417,119,417,154,402,576,872,902,206,765,615,50,218,285,174,751,139,108,303,91,461,53,37,80,284,400,852,241,150,500,200,92,783,173,184,212,367,932,155,872,479,140,26,807,786,164,44,288,819,888,584,298,185,303,685,57,559,524,209,953,300,412,436,621,704,268,58,890,86,885,9,32,476,471,240,75,56,94,546,278,89,829,177,627,957,852,150,294,400,773,516,767,562,332,264,420,544,249,73,817,674,572,20,339,143,473,595,515,500,226,743,480,391,940,342,15,152,951,592,228,291,380,705,9,280,492,29,502,368,665,421,738,105,915,734,240,877,109,64,446,639,558,905,703,901,179,746,493,479,110,844,894,129,955,709,92,578,919,206,81,909,734,43,606,710,908,850,737,859,207,169,611,685,602,204,390,819,820,66,286,535,331,474,386,728,425,932,784,628,228,378,93,990,740,549,374,683,646,112,588,260,455,373,698,931,353,336,446,500,908,778,406,535,692,740,619,437,367,918,358,812,924,881,6,788,844,534,193,445,201,485,729,562,883,410,801,194,146,217,550,215,569,446,222,241,768,599,983,573,571,50,568,542", "166,736,665,237,527,63,628,301,762,216,35,887,2,968,425,517,257,281,659,426,597,583,856,792,247,326,450,41,239,592,195,144,244,177,290,583,260,788,781,40,284,791,600,427,507,448,142,298,352,972,976,656,904,412,832,971,849,512,230,837,375,530,986,866,437,871,315,668,778,426,78,900,888,880,828,540,937,350,431,301,434,141,153,340,842,503,758,136,103,758,42,860,57,822,399,88,312,66,584,575,493,743,415,2,538,533,319,318,497,500,94,870,625,245,440,523,333,969,114,589,636,344,464,565,675,867,160,104,604,205,915,48,71,979,469,841,921,219,714,130,670,862,984,869,267,768,985,909,306,650,716,217,811,65,300,640,234,33,120,502,170,951,494,828,736,801,302,922,156,926,58,504,81,739,123,660,466,511,31,406,145,748,414,937,709,181,756,547,324,678,123,830,539,94,491,59,514,409,940,860,360,450,434,19,929,601,383,812,164,937,783,582,850,923,178,656,994,983,232,450,428,791,522,196,122,38,529,761,342,122,914,104,490,626,554,53,939,630,159,46,700,655,777,369,743,52,21,374,981,176,943,148,131,835,587,894,300,228,443,707,976,88,453,34,476,188,134,656,420,238,22,132,70,636,54,351,462,417,764,89,167,250,496,74,540,232,612,361,22,712,803,751,954,818,411,887,98,120,664,133,480,147,373,583,569,295,841,160,877,102,914,657,121,993,344,938,322,988,294,934,516,801,633,190,14,608,76,469,670,971,344,833,668,797,728,797,395,236,264,646,433,39,351,609,839,237,150,368,737,520,365,447,468,431,678,326,167,246,354,818,239,199,91,86,346,940,275,664,700,451,259,307,56,536,674,52,91,143,356,79,342,609,379,308,609,511,557,929,862,156,720,991,315,87,807,328,907,36,585,495,318,401,19,249,646,624,138,626,848,984,78,180,185,709,36,443,500,412,288,396,682,413,947,689,292,892,89,924,446,941,517,615,711,920,50,894,661,906,441,301,400,286,137,361,415,226,990,111,807,218,425,969,996,120,2,945,1000,794,374,848,710,749,618,373,728,607,202,673,93,678,612,391,94,626,324,830,407,454,187,232,227,367,758,968,59,499,81,574,179,934,890,694,885,150,697,241,479,824,23,533,91,2,304,412,50,499,876,115,522,607,639,832,439,954,662,431,920,953,880,0,920,96,520,32,281,254,504,8,917,297,712,258,686,922,192,734,43,229,570,935,949,209,167,277,150,856,986,720,788,244,466,679,209,567,860,642,3,586,813,773,92,445,758,867,792,998,242,674,115,729,489,21,948,371,21,158,328,462,364,604,858,532,430,539,554,604,924,159,292,720,577,941,173,767,47,414,445,705,647,465,301,283,969,724,742,99,462,821,794,338,20,601,762,221,70,726,106,917,307,973,608,218,119,357,450,828,673,7,5,935,853,956,38,572,665,35,968,123,823,953,78,370,675,325,650,421,444,393,867,506,956,700,105,461,168,765,800,993,148,57,455,195,957,378,819,48,716,902,690,993,682,18,129,679,701,191,792,706,114,939,404,589,693,816,153,418,889,230,237,620,413,19,580,713,785,970,851,939,129,36,392,393,635,127,421,882,337,683,477,978,344,300,778,348,583,642,970,640,873,287,992,962,218,610,183,546,298,846,609,361,445,988,823,816,340,721,477,690,217,623,169,341,541,142,33,375,847,517,243,802,20,500,436,47,935,833,136,183,892,962,224,917,410,437,20,920,163,304,882,286,28,174,386,662,715,380,948,340,802,606,435,459,719,428,120,270,30,271,253,848,795,950,457,54,647,833,593,367,607,532,440,988,661,362,730,487,341,115,100,971,840,159,322,729,319,924,369,453,986,753,22,346,909,59,944,218,403,178,188,286,131,707,985,490,120,938,257,748,165,936,542,629,913,842,734,268,663,285,298,145,360,494,542,540,173,359,927,171,331,631,944,616,323,328,461,209,82,139,392,305,997,395,164,269,650,298,555,473,832,674,634,231,881,724,18,581,883,240,620,981,109,451,348,426,964,207,186,29,350,884,437,131,272,568,812,685,112,518,909,962,356,581,796,951,861,465,342,751,862,741,879,952,861,291,550,156,461,397,54,734,57,229,448,857,653,134,436,892,295,201,378,813,731,494,981,463,321,152,64,330,768,976,722,417,176,646,590,857,18,237,422,90,122,72,763,595,122,854,842,418,106,979,419,807,755,228,569,530,568,128,219,161,188,390,486,380,560,146,297,827,533,713,701,393,358,845,697,752,170,910", "38,641,420,307,311,396,305,586,915,490,439,759,471,97,507,86,6,989,752,127,886,61,33,523,612,772,144,348,133,292,410,217,476,814,47,792,343,791,322,135,300,743,644,255,207,263,987,177,257,687,244,600,256,148,432,58,865,145,933,986,113,589,39,300,382,787,723,122,559,311,568,78,163,753,977,893,410,372,948,677,161,259,412,793,522,678,571,734,916,871,882,116,357,431,604,360,95,561,317,605,954,622,314,167,995,283,320,42,690,71,230,975,19,116,269,774,405,845,538,503,247,38,105,6,95,909,165,662,836,113,4,498,152,953,760,608,532,576,730,584,253,990,117,371,592,569,774,884,229,406,766,381,739,408,311,862,416,500,136,711,578,771,711,643,379,16,449,297,411,635,773,861,798,654,737,848,372,256,350,297,455,364,327,919,515,948,52,817,520,182,501,316,289,856,284,35,915,85,187,546,105,91,866,917,341,669,191,563,919,210,303,951,8,938,127,803,610,152,280,429,442,153,40,277,584,274,658,105,844,722,685,737,518,143,148,662,93,909,647,195,576,109,246,746,785,48,214,61,356,798,676,667,307,820,708,939,347,451,972,584,698,497,338,15,342,504,602,93,874,337,400,653,169,69,960,594,261,31,78,388,948,163,303,746,746,725,470,420,754,953,724,181,308,752,575,858,203,884,216,826,373,719,343,839,114,9,997,215,336,690,254,515,862,606,711,834,269,734,492,579,773,592,810,640,527,167,138,47,525,964,558,963,543,835,472,316,9,155,565,483,22,574,328,364,513,864,884,98,489,620,889,441,262,90,420,187,446,436,570,703,28,183,697,283,897,461,249,210,511,87,705,832,18,209,894,489,685,909,678,85,423,549,455,745,134,608,29,626,669,614,226,854,685,71,982,120,520,946,234,356,410,820,775,298,369,736,512,791,153,72,621,547,237,224,220,829,231,935,303,273,813,960,715,952,56,440,410,580,874,563,514,66,248,643,11,81,820,877,199,538,703,423,951,268,47,460,65,682,771,583,677,253,771,140,717,105,690,408,367,531,528,301,175,881,349,691,928,97,796,708,136,352,281,324,39,807,973,514,768,493,679,471,383,426,345,56,142,107,402,978,354,162,888,745,974,493,730,137,856,648,615,169,640,642,407,490,716,856,435,826,760,629,709,90,738,168,989,495,450,920,0,158,432,394,651,106,536,328,164,651,539,939,386,683,445,41,796,461,562,956,864,270,747,315,505,75,302,691,92,760,721,102,485,226,266,540,876,792,531,396,827,588,535,610,884,722,752,690,115,488,444,410,650,264,821,423,5,782,310,197,677,808,465,389,352,858,791,594,976,675,170,545,518,918,556,937,194,285,553,700,435,460,914,252,76,174,898,658,864,94,443,422,917,651,347,902,78,744,996,385,934,9,305,571,921,826,986,967,566,454,54,26,220,891,681,770,812,877,348,906,159,58,775,836,353,520,122,17,707,324,481,189,243,13,913,103,104,718,193,886,958,508,375,418,280,542,996,222,535,423,7,317,337,175,707,534,958,970,454,932,942,715,768,863,996,753,249,386,845,534,277,281,1000,832,486,551,579,575,312,530,762,719,871,120,305,965,874,153,368,801,155,366,385,731,967,386,260,647,578,701,519,274,39,864,829,544,447,517,550,524,574,800,685,505,217,57,107,329,159,867,429,213,912,200,790,583,971,15,765,259,773,195,13,89,229,203,163,914,645,189,734,379,106,455,142,521,852,311,311,881,802,333,672,976,470,211,874,281,877,115,387,108,186,406,460,410,56,704,401,817,376,175,133,548,539,808,428,767,925,334,741,517,90,292,623,719,208,395,202,600,827,958,505,952,314,192,977,525,481,106,700,842,565,219,153,85,585,413,870,593,505,329,138,132,892,263,215,660,128,898,928,600,669,144,102,463,175,113,316,486,586,140,254,433,402,156,59,573,539,681,288,341,391,156,863,774,563,490,855,524,599,941,776,526,563,58,414,213,882,424,896,199,584,565,402,713,655,556,986,385,776,337,929,972,42,174,552,359,688,314,29,959,509,993,279,937,750,544,480,995,911,757,561,992,817,409,76,533,150,895,958,93,737,346,358,925,375,786,655,558,882,528,212,588,110,634,640,568,939,579,470,352,890,546,900,960,877,267,381,986,578,149,833,874,163,354,653,870,391,359,127,849,329,410,106,453,461,35,762,116,479,192,683,871,632,437,610,315,164,58,428,96,430,691,11,466,355,568,938,190,231,646,943,609,597,102,732,527,78,23", "203,227,613,430,248,478,919,186,527,821,684,772,786,18,900,426,150,455,313,725,251,578,118,842,77,49,762,971,729,232,105,440,961,935,287,61,198,149,598,222,401,749,441,792,610,935,601,935,148,246,278,876,247,508,886,481,374,371,450,914,456,753,385,426,233,862,871,759,181,579,348,381,906,264,443,811,442,595,379,258,395,952,861,432,960,913,832,355,989,622,706,795,434,658,265,636,144,730,635,148,485,255,391,346,127,592,651,900,803,616,401,670,669,247,971,350,963,928,450,471,123,346,257,566,289,557,542,613,811,266,308,609,375,952,273,445,740,70,910,645,551,125,673,60,487,636,888,10,598,371,156,247,552,30,457,491,908,738,986,663,316,558,382,41,91,158,45,356,863,575,843,419,39,285,930,470,817,446,792,53,394,541,770,132,198,895,969,21,614,250,778,85,812,907,741,670,278,382,523,753,803,547,474,534,301,980,502,643,381,542,65,723,904,58,126,906,806,415,711,343,524,985,216,477,336,134,509,147,588,230,777,326,881,900,345,506,51,757,116,466,822,80,876,476,911,875,868,51,938,414,891,731,760,523,639,672,711,409,679,949,711,990,680,745,928,348,742,297,236,891,101,260,481,3,645,777,57,870,152,522,415,894,335,673,227,965,54,990,832,414,369,579,514,107,140,368,817,527,406,410,935,46,675,401,708,313,894,704,309,826,577,745,279,191,106,212,758,975,320,902,475,975,723,470,920,144,847,834,919,552,4,744,576,871,636,502,791,68,990,389,485,934,349,91,386,567,431,139,529,754,750,93,7,71,664,787,966,972,914,152,981,475,71,429,721,814,676,767,420,215,74,339,182,187,403,811,837,200,93,824,533,585,29,218,97,564,800,73,397,458,370,844,329,52,423,527,934,859,297,545,224,453,509,720,897,73,886,825,731,399,921,825,650,853,764,706,691,518,225,211,99,853,319,252,491,967,398,45,429,432,67,910,81,221,698,39,564,449,553,51,100,702,920,201,68,233,832,763,922,794,594,813,716,501,424,719,104,594,615,970,448,371,899,588,331,141,801,456,889,568,597,609,838,837,560,121,696,235,488,975,516,40,392,954,400,18,76,835,680,790,46,975,760,337,523,231,159,426,139,597,697,724,734,527,553,564,263,194,361,268,589,252,538,892,790,46,977,566,309,96,158,0,637,802,438,326,570,719,887,277,94,40,475,519,476,597,183,25,91,854,984,291,580,561,323,680,106,929,246,312,212,772,79,150,800,141,929,925,924,433,704,887,639,254,426,499,103,970,462,132,133,199,212,998,871,121,587,796,104,316,506,291,944,310,667,527,773,227,709,165,798,186,145,448,566,304,377,354,935,944,369,249,818,154,191,660,539,55,509,263,761,190,220,647,676,381,588,699,61,878,890,266,390,931,927,321,65,269,738,601,929,827,132,326,363,760,762,886,322,22,321,479,472,136,336,303,193,750,921,982,11,938,31,690,477,679,70,160,170,718,70,798,3,30,635,894,733,427,755,899,454,866,342,102,466,18,96,993,35,729,209,958,837,142,962,279,855,140,301,274,38,587,641,93,57,29,52,93,829,874,547,888,934,609,99,207,866,577,242,444,171,152,250,413,822,522,87,970,518,434,704,20,326,729,299,890,99,720,725,133,928,73,704,594,22,600,305,71,925,751,365,481,447,772,47,519,639,231,292,268,484,920,283,441,703,730,96,983,318,833,76,856,671,854,233,719,574,90,188,797,332,699,378,140,848,33,71,312,13,830,351,797,772,964,922,25,995,175,389,42,235,774,611,757,853,689,915,97,356,291,412,848,244,220,485,806,919,861,535,339,969,370,15,932,519,300,656,984,88,499,873,977,271,440,612,186,326,885,393,330,306,323,100,967,701,113,28,609,574,696,374,214,42,407,141,6,946,229,870,778,965,64,774,3,804,767,95,267,411,126,1,934,762,848,649,127,350,502,558,376,310,27,718,766,677,41,723,736,890,681,160,810,672,920,283,242,524,664,789,346,810,726,355,624,111,420,395,19,979,859,316,221,585,521,742,866,708,168,339,174,579,284,144,241,702,606,386,294,913,289,921,352,991,163,756,921,26,246,658,219,823,263,252,679,693,768,133,541,326,750,26,545,807,993,959,489,554,783,407,885,46,402,988,544,405,576,521,728,854,954,868,667,68,309,574,574,804,741,97,931,551,636,432,368,895,696,731,331,138,636,204,951,419,97,265,281,339,886,23,13,696,231,171,448,191,38,637,946,564,487", "953,538,596,331,973,171,521,747,478,323,251,712,759,933,227,169,771,791,159,339,211,979,398,385,461,679,238,251,281,65,784,397,866,621,829,960,768,613,146,962,72,417,198,283,504,77,281,537,887,262,45,112,831,200,693,920,102,594,142,282,634,613,320,638,9,625,108,449,646,683,565,726,436,251,804,392,230,753,501,263,294,597,94,335,941,171,766,34,420,898,2,508,697,75,328,769,125,395,358,597,775,556,987,575,754,764,698,875,672,292,722,607,429,88,150,192,960,169,434,493,213,98,192,142,866,115,54,935,601,957,916,365,903,25,845,162,360,113,743,563,986,679,807,144,237,946,576,981,385,105,355,844,281,581,64,579,512,460,587,690,990,761,172,658,290,689,150,1000,12,539,339,198,80,661,84,661,9,469,377,281,40,581,120,379,947,251,763,523,812,815,789,57,709,133,749,798,972,701,612,144,897,776,72,74,377,55,657,301,732,169,52,621,246,403,907,765,844,870,664,917,203,734,990,177,614,275,513,668,818,108,452,102,640,339,784,386,375,809,787,243,219,641,56,332,243,838,240,450,498,449,842,125,933,649,459,49,157,356,788,15,889,97,171,601,878,119,367,959,99,236,907,681,390,392,880,376,779,240,308,567,806,54,456,737,957,119,338,698,560,992,100,831,716,529,870,729,24,583,645,69,438,453,705,337,204,418,114,160,568,840,590,871,777,666,841,714,169,29,997,722,854,137,847,811,413,473,443,284,58,676,172,753,197,114,176,927,939,917,914,288,809,982,166,724,846,600,398,244,403,232,268,964,428,81,243,649,128,530,657,56,504,107,348,258,415,40,458,848,446,793,202,706,664,705,316,337,47,335,615,775,948,706,440,212,61,536,416,282,335,883,851,299,936,814,855,439,677,850,974,529,970,587,854,186,698,110,120,629,535,769,635,12,723,142,598,62,759,406,853,368,173,848,853,16,449,596,28,786,413,327,243,640,548,46,874,349,131,8,659,884,936,210,30,541,485,287,291,458,533,341,630,210,509,744,922,936,164,970,730,713,93,547,669,358,249,893,337,161,31,383,14,646,98,766,415,809,599,344,677,891,882,636,211,554,684,77,60,871,158,361,691,578,924,796,798,705,664,956,90,815,353,14,63,75,661,376,589,574,605,82,68,582,586,123,663,883,328,535,323,520,432,637,0,220,942,387,247,148,227,228,650,470,313,414,770,309,921,340,888,957,696,644,947,254,193,300,285,740,277,7,229,711,199,265,584,795,868,179,116,663,886,553,979,951,552,222,442,889,699,761,993,501,20,467,410,787,639,151,654,596,45,217,736,50,608,436,243,19,780,710,454,57,784,169,617,769,286,260,924,368,185,243,428,982,362,537,808,719,98,76,539,406,237,905,934,287,467,205,561,154,209,33,891,846,588,360,136,877,373,302,300,650,526,341,83,954,803,599,904,933,788,372,791,892,819,153,974,157,12,598,930,758,442,803,330,305,808,265,890,56,131,219,597,107,311,410,496,790,7,44,426,813,666,52,654,431,569,931,452,809,998,113,572,853,96,355,824,709,445,603,534,284,627,527,693,619,801,949,577,660,102,918,83,537,981,850,211,103,488,404,14,309,37,704,643,132,575,63,286,8,132,570,885,159,81,330,70,296,435,379,25,210,950,430,481,47,711,381,416,864,795,650,439,864,353,981,348,498,31,151,718,570,640,85,728,800,801,943,812,828,946,636,473,704,987,436,739,896,357,180,824,709,505,42,791,831,120,773,862,64,919,735,753,97,33,183,913,409,754,901,542,767,791,291,747,784,976,434,226,310,487,627,652,984,306,269,412,235,374,651,715,537,991,536,41,886,243,25,308,162,798,5,585,216,345,78,823,462,266,568,743,935,705,235,412,370,146,596,755,518,517,722,31,446,999,479,166,524,124,970,985,811,200,951,898,632,751,921,977,38,915,5,680,928,48,69,688,59,85,139,80,455,500,19,868,738,629,731,981,682,369,191,237,769,26,601,718,381,918,608,986,566,396,706,545,339,29,450,82,718,683,226,614,311,239,598,719,165,312,632,487,454,2,486,406,635,323,920,961,257,177,258,297,42,815,332,795,905,102,239,911,391,904,687,367,627,210,424,944,989,556,590,812,777,515,763,945,363,341,365,687,847,471,755,635,722,585,247,890,728,611,271,975,53,717,936,169,817,336,881,254,86,215,208,962,234,85,237,828,788,350,36,522,689,687,396,357,193,604,856,830,213,934,208,543,772,197,175,941,766", "201,609,755,176,862,348,285,745,960,760,242,463,810,516,126,861,923,37,505,922,101,660,228,418,459,785,125,57,530,788,402,185,768,123,332,102,905,690,748,807,222,609,37,414,120,915,54,909,105,29,993,730,645,930,857,980,205,129,788,679,320,497,162,415,679,162,593,271,446,710,280,125,112,692,482,627,483,213,991,906,625,658,372,801,73,488,567,736,926,278,393,337,95,236,856,498,636,152,211,123,102,215,477,469,110,384,88,748,677,347,914,882,900,312,439,182,489,330,806,392,911,589,137,972,686,730,138,793,728,63,787,615,166,435,601,419,713,88,39,746,572,113,783,962,493,402,760,159,635,848,477,176,338,864,618,327,447,752,18,68,624,106,481,105,877,337,577,230,870,546,100,427,453,204,753,323,751,573,110,185,183,445,282,890,218,33,694,391,352,72,576,232,918,492,536,930,733,331,401,227,463,977,690,75,445,403,338,585,983,654,644,419,620,929,379,633,575,484,509,95,888,200,259,670,186,505,237,22,151,891,559,134,289,742,466,846,589,265,862,707,387,112,142,759,784,267,808,668,89,989,955,801,689,766,921,693,602,862,794,179,407,670,102,901,393,394,545,658,412,309,650,256,56,296,399,265,194,297,218,864,530,939,681,539,707,150,318,620,910,280,875,613,314,713,59,964,865,207,312,864,864,714,453,468,526,273,875,825,575,801,89,786,619,376,181,227,840,554,297,721,259,404,75,279,676,352,884,114,135,84,339,11,563,6,532,789,627,61,809,972,888,532,231,70,350,553,859,825,840,505,444,409,426,752,127,50,265,510,213,174,434,12,287,290,444,804,426,226,447,970,948,77,363,203,415,185,503,151,576,392,139,213,274,514,906,130,612,528,374,31,736,228,844,819,72,363,637,599,659,775,541,499,442,6,442,656,285,425,125,83,216,999,641,976,658,22,467,922,200,850,809,597,321,628,124,414,844,629,779,643,760,796,54,924,815,744,255,200,40,626,215,182,261,841,397,925,372,319,257,12,166,519,893,843,876,82,930,271,68,636,10,904,274,122,205,11,875,149,107,199,746,409,500,111,280,268,115,369,580,193,719,203,284,332,745,659,602,960,640,650,173,837,895,105,172,896,597,37,6,672,994,751,712,683,860,668,396,331,128,654,401,880,284,667,556,294,51,433,977,32,394,802,220,0,204,366,167,466,707,469,335,936,752,224,137,430,835,989,321,268,920,691,595,89,710,377,635,714,686,965,928,585,682,573,714,455,602,767,227,971,740,425,352,559,565,974,986,247,242,564,789,543,403,471,603,293,475,311,691,843,226,81,846,122,452,396,138,606,647,480,383,433,802,498,822,322,230,682,599,134,44,828,482,612,971,883,359,477,29,103,430,775,765,879,158,604,438,752,57,597,185,350,571,636,840,393,63,234,491,31,989,922,361,544,224,8,274,67,444,302,23,941,522,800,432,957,192,371,108,247,586,872,766,140,263,158,362,633,347,224,5,855,421,235,947,509,873,749,131,54,523,333,305,866,361,557,975,896,88,964,722,808,959,230,86,562,414,465,901,750,342,383,418,706,536,586,355,430,524,272,884,952,524,704,508,186,654,564,332,640,354,246,317,583,714,28,43,343,562,84,757,664,36,347,265,552,772,697,344,738,920,494,454,33,991,295,986,157,645,716,873,889,164,34,364,577,923,195,126,511,273,630,974,61,493,997,390,749,448,159,216,569,802,81,748,859,395,694,247,224,273,577,581,535,620,683,442,422,190,659,766,736,448,794,16,287,123,845,44,401,516,383,912,341,525,471,975,854,188,876,858,172,597,425,76,970,344,918,327,763,277,501,730,968,468,895,10,796,31,880,644,320,916,853,275,135,79,854,586,244,281,599,292,822,681,901,972,272,590,729,154,593,501,477,650,198,839,238,768,107,569,775,164,929,844,494,987,558,672,751,85,614,619,478,615,456,228,144,159,63,822,38,48,253,541,446,632,594,152,462,41,896,781,318,369,620,978,748,457,846,736,752,112,209,392,546,574,297,405,463,407,316,760,999,697,242,632,530,826,787,669,659,905,57,696,119,138,701,549,10,812,595,211,273,440,16,381,135,99,388,612,83,298,50,517,623,447,865,330,38,747,573,283,158,141,208,521,849,895,140,936,866,361,560,284,212,897,413,767,848,986,168,818,944,757,971,751,82,168,121,760,5,40,168,820,870,52,719,596,234,226,439,907,903,363,56,777,674,963,996,959,269,913,659,163,912,514,957,278,340", "566,954,870,121,683,37,545,731,288,607,84,781,104,203,9,106,602,968,545,900,277,28,348,317,911,893,861,109,143,146,149,581,510,735,559,516,960,224,585,500,357,59,268,319,975,74,42,928,10,737,939,11,966,365,192,231,177,446,937,391,119,631,695,379,129,54,290,531,309,198,965,633,760,62,209,566,589,962,677,718,519,29,111,204,162,992,754,380,999,303,348,308,859,122,706,253,695,493,641,218,575,108,240,688,561,227,335,23,343,790,671,153,328,181,6,728,1,990,503,482,629,34,471,640,193,559,950,21,954,32,246,327,684,464,268,538,963,527,447,645,666,468,540,292,383,369,675,883,672,759,740,323,664,721,899,340,866,921,189,200,212,124,406,689,151,788,869,319,507,807,248,359,334,216,108,148,432,157,891,544,544,339,80,720,447,541,511,672,777,218,937,831,591,20,142,857,347,504,498,610,470,543,8,434,403,333,931,102,343,796,250,320,408,900,384,231,777,486,273,960,949,405,54,218,75,123,169,162,455,267,370,323,21,617,729,585,58,812,420,104,576,974,540,243,656,632,26,484,891,370,713,361,497,644,776,223,745,711,227,123,523,306,600,826,450,998,306,829,124,573,155,408,31,758,210,991,142,776,729,592,447,129,745,550,25,186,818,404,19,111,776,74,264,774,391,531,60,783,991,592,849,798,86,482,15,891,413,686,574,438,408,918,303,729,800,851,561,49,165,136,214,354,216,316,855,426,284,505,920,551,147,886,94,703,576,442,982,379,946,14,230,571,388,104,977,970,152,324,292,859,909,105,721,262,984,296,285,370,149,367,732,284,421,476,804,713,146,223,538,673,279,594,245,386,738,705,914,328,473,927,497,369,725,8,681,73,571,64,923,195,389,628,694,550,115,288,489,522,874,815,589,21,874,639,74,604,926,457,514,934,372,622,62,477,202,146,142,863,583,177,323,268,822,95,127,209,109,335,893,488,170,83,999,837,258,773,770,848,825,566,55,110,17,123,356,762,902,864,674,392,679,361,115,900,684,166,171,124,740,340,644,880,113,937,335,440,454,76,487,662,22,216,60,797,872,629,297,678,588,268,554,369,696,996,660,168,86,745,967,270,840,727,783,623,992,85,789,357,842,404,459,257,456,215,561,871,428,693,145,355,27,619,529,408,119,577,613,459,204,281,651,438,942,204,0,654,26,740,850,328,326,957,693,878,912,875,33,643,44,965,834,126,117,345,241,954,873,422,93,859,712,290,994,694,231,246,797,489,880,17,151,501,568,673,866,634,3,530,415,93,816,278,690,212,743,365,136,547,279,503,744,248,120,902,492,973,517,200,438,277,939,663,270,787,141,214,474,798,777,903,758,567,501,210,781,378,857,571,845,533,25,372,866,186,404,202,576,191,717,527,776,516,330,975,715,591,921,455,590,413,126,230,572,122,847,591,57,516,310,423,604,470,279,585,785,652,876,583,360,571,562,844,672,171,548,811,65,952,234,388,672,951,554,618,19,154,875,987,917,302,314,79,412,923,92,516,145,666,242,659,877,692,341,740,118,490,23,852,367,564,332,165,306,240,543,750,444,236,922,514,670,956,385,527,281,140,13,491,447,474,743,827,617,962,470,42,557,637,342,34,114,265,544,947,117,852,335,27,826,5,203,319,938,779,479,346,985,241,581,248,55,100,377,474,157,873,812,242,66,127,389,499,452,527,474,99,836,643,747,874,605,722,215,43,45,809,820,160,597,265,123,987,848,147,976,512,983,128,172,714,233,641,48,346,88,758,398,481,308,122,654,673,998,825,209,704,549,927,387,412,949,347,53,490,435,975,236,1000,631,537,497,879,11,121,884,831,411,514,966,316,398,352,714,672,808,962,20,351,446,592,96,327,371,98,666,924,601,387,964,570,103,785,726,792,62,989,675,624,226,415,132,173,24,258,588,291,94,6,942,425,773,287,660,847,223,254,546,972,255,829,800,126,149,761,578,383,6,742,960,694,123,663,421,59,216,648,454,144,594,779,412,901,357,70,433,848,842,517,966,710,981,403,628,236,205,714,964,59,985,641,286,65,32,964,901,676,679,944,45,626,821,160,521,733,212,565,723,350,855,446,884,361,313,835,944,549,446,65,810,549,870,341,712,94,406,530,266,147,16,622,688,10,831,982,675,384,180,711,151,520,610,554,501,185,348,91,277,346,477,521,263,232,382,68,903,739,378,51,777,16,561,453,575,184,98,395,461,462,408,757,51,254,697,698,814,428,66,804,446,918", "409,84,406,682,951,64,342,715,649,431,503,529,222,475,488,57,350,551,333,127,492,65,470,93,4,685,232,956,388,283,737,733,121,108,637,947,29,701,219,544,101,694,662,82,448,441,891,651,346,508,700,895,55,930,362,910,847,615,571,80,679,652,87,826,519,324,373,84,792,157,570,215,173,883,428,275,223,171,262,133,19,824,809,213,682,102,655,915,859,171,128,850,488,846,941,19,112,760,303,518,884,750,812,756,793,10,227,864,970,647,433,885,837,668,151,39,187,291,210,324,21,917,663,876,265,804,342,563,606,444,976,133,874,572,810,897,361,506,887,890,635,299,584,451,762,903,9,139,131,441,150,249,728,895,802,521,294,770,157,646,550,901,847,601,955,567,809,463,506,176,489,909,953,155,975,442,263,574,368,715,898,475,408,310,350,409,190,137,615,90,370,877,800,884,677,620,396,375,834,574,240,287,763,111,415,281,111,345,249,505,341,3,127,944,737,490,689,421,180,750,684,575,809,840,278,767,114,411,961,662,988,84,402,816,544,779,257,695,665,123,256,438,290,73,753,786,279,609,299,970,352,12,301,719,507,852,508,54,256,409,445,659,837,224,15,198,94,915,922,275,599,818,430,83,981,411,500,536,621,886,599,895,831,558,252,964,987,481,525,967,464,93,298,958,902,718,626,89,246,636,246,80,939,86,98,862,863,190,644,817,282,631,619,230,706,60,915,892,270,294,255,875,685,204,423,793,550,392,377,475,917,930,815,341,138,914,6,594,216,570,93,963,162,365,467,680,370,482,215,616,17,66,70,840,832,344,362,56,148,159,674,422,235,569,623,293,887,92,29,496,751,540,912,615,595,928,625,109,479,599,702,9,198,763,426,762,467,520,155,312,289,447,946,46,538,859,996,832,965,464,617,850,654,267,17,857,418,993,756,825,465,270,42,506,796,836,828,404,572,2,727,53,898,949,920,368,443,543,981,863,612,771,708,255,790,371,654,532,446,259,689,433,461,479,370,58,447,397,692,569,36,5,632,980,218,572,729,582,962,506,731,680,95,5,275,334,80,404,7,241,851,248,343,241,324,728,38,916,521,411,34,727,407,841,720,294,621,346,506,822,798,872,859,483,63,645,45,118,197,705,867,387,426,172,878,835,866,818,303,487,674,994,540,138,217,518,476,33,65,254,106,326,387,366,654,0,47,173,91,142,347,549,41,448,525,900,17,345,887,272,521,540,205,496,872,596,915,288,967,631,808,886,398,924,166,342,972,970,197,997,515,814,245,351,227,233,704,222,227,645,67,152,413,503,176,264,897,873,258,364,24,10,390,393,391,90,929,63,938,306,555,663,366,600,262,184,143,241,445,262,587,240,239,68,794,451,607,772,36,155,931,630,513,447,328,956,420,794,698,922,659,892,511,204,231,454,682,781,163,357,593,209,447,229,353,883,965,651,504,442,170,184,590,397,820,763,91,141,353,121,417,418,250,174,414,707,692,812,103,259,908,412,937,475,718,984,73,548,641,698,134,604,682,379,908,185,800,43,368,238,576,190,878,41,796,412,928,360,370,933,402,799,730,30,789,76,646,946,181,871,546,87,41,877,169,601,28,536,706,338,702,150,537,271,478,876,80,577,944,887,251,638,569,688,876,585,627,122,521,969,556,481,265,910,21,716,342,557,149,83,16,356,63,830,943,810,272,461,906,368,992,549,146,819,254,789,194,215,430,81,273,324,136,893,711,731,233,978,446,993,402,272,35,6,653,918,351,748,889,869,268,3,706,185,984,80,622,480,156,734,152,248,874,809,533,567,229,589,335,929,888,974,785,169,657,99,378,925,319,582,641,376,639,547,310,202,235,620,377,701,294,29,2,91,472,686,54,633,191,266,815,89,215,514,38,286,620,626,846,457,262,651,355,681,948,135,492,838,305,758,283,397,315,719,90,96,631,551,950,200,147,779,671,212,279,648,184,371,557,626,597,113,590,535,74,30,920,128,902,67,488,855,350,813,892,301,279,124,103,627,947,677,778,648,438,862,199,684,249,183,372,304,742,255,209,299,103,366,866,889,896,551,535,251,202,614,478,627,713,552,622,482,394,210,764,238,702,29,657,109,131,265,294,201,194,690,223,790,348,907,760,16,615,398,751,760,94,842,937,904,381,471,753,175,654,400,920,730,613,84,786,816,701,823,348,42,998,210,330,812,747,881,136,207,303,574,610,323,573,938,553,955,495,384,200,143,632,962,125,519,148,64,200,114,603,129,578,840,35,898", "64,304,727,696,91,461,934,762,899,439,513,397,127,112,335,412,810,392,286,435,552,230,676,724,487,261,753,127,433,331,29,15,701,333,308,991,283,954,225,390,265,637,779,446,193,870,614,221,286,894,968,830,234,435,629,593,278,533,14,125,3,832,102,226,859,141,253,965,304,500,529,735,151,322,310,515,713,22,982,977,822,268,119,989,382,394,537,915,631,713,706,329,184,844,503,392,576,686,986,225,158,963,882,825,624,198,622,1,658,307,30,293,875,531,689,314,6,838,510,64,275,450,708,471,763,372,838,325,121,928,2,463,906,820,596,490,350,508,962,89,899,393,457,567,75,273,670,994,800,426,243,494,345,880,853,442,806,82,95,691,533,140,612,758,320,385,765,881,823,434,914,118,252,37,157,207,784,235,278,122,377,756,219,711,585,968,13,811,724,968,182,381,173,729,898,949,356,359,423,954,520,583,917,277,337,204,208,707,975,849,76,753,531,419,190,571,161,323,280,691,655,639,292,994,859,393,677,613,833,352,57,718,302,999,152,175,231,844,966,208,326,812,902,323,723,955,596,457,949,920,358,612,603,790,569,735,347,861,921,452,458,721,91,1000,576,315,244,525,624,515,774,975,473,666,766,773,751,620,627,668,222,733,828,471,583,625,324,10,566,955,504,738,917,546,125,871,247,441,24,149,15,308,375,598,919,141,202,398,894,803,238,91,853,72,658,858,584,129,914,725,2,446,946,685,972,912,348,639,521,376,341,498,731,971,420,476,486,794,871,115,801,694,300,715,708,547,361,577,61,978,427,906,886,300,166,920,694,215,32,648,593,794,249,93,106,119,774,340,86,214,54,886,895,712,822,767,696,102,577,901,345,703,22,196,344,18,50,2,350,5,240,482,461,439,371,457,66,612,999,514,600,22,196,452,756,652,642,69,969,81,113,786,429,20,951,484,322,357,142,890,21,358,382,473,282,733,132,765,553,59,233,640,936,233,585,403,153,689,649,891,137,405,279,51,540,749,646,562,631,854,29,176,410,317,677,419,595,864,272,58,17,682,275,989,243,738,5,561,180,395,657,451,416,826,351,518,325,783,659,846,834,95,913,176,471,531,632,180,139,926,512,325,119,938,608,676,278,639,331,797,826,755,740,603,53,720,83,226,461,380,28,331,828,496,310,344,517,669,562,504,536,570,247,167,26,47,0,219,175,673,51,840,463,113,648,208,795,757,36,625,350,10,433,855,121,685,703,389,741,183,817,731,935,683,330,782,693,183,920,558,611,672,544,664,387,277,470,594,297,925,410,651,157,512,427,621,5,242,361,407,284,556,393,797,882,578,866,590,159,153,756,767,541,411,884,798,767,171,839,422,621,434,876,798,649,50,70,658,992,428,75,988,639,955,8,947,898,577,708,693,449,577,974,731,963,347,315,781,561,339,448,680,31,963,6,107,712,635,730,644,539,105,732,731,296,808,997,603,236,850,52,649,140,581,876,506,964,408,779,271,128,859,1000,628,960,815,733,583,748,958,297,342,270,654,778,549,899,897,381,576,954,423,871,103,297,312,177,394,282,187,319,335,848,782,396,412,458,863,273,337,546,649,299,329,991,307,235,900,454,182,551,50,665,299,934,41,85,344,535,473,706,483,9,414,896,834,354,647,120,997,684,401,218,131,31,987,630,561,539,585,685,220,237,70,238,830,863,326,32,946,399,805,136,765,468,549,240,528,104,893,932,631,710,961,343,113,483,585,268,16,424,605,717,762,555,457,531,961,380,832,582,301,541,397,985,147,708,269,454,982,669,286,229,120,164,974,716,873,901,238,207,393,140,368,413,543,828,897,786,593,217,216,205,833,109,330,388,135,610,914,86,822,127,11,335,459,953,844,529,187,928,746,343,120,677,734,993,843,822,102,943,646,588,788,476,822,505,625,702,581,825,634,152,577,292,387,746,593,751,478,11,367,246,877,655,354,178,631,459,233,116,1,286,674,10,604,529,8,931,299,442,983,46,744,589,891,269,310,696,179,701,753,18,748,633,430,366,24,250,387,95,141,532,659,281,253,517,675,967,661,796,750,858,177,896,728,548,986,907,773,830,523,498,640,588,685,362,321,758,569,697,512,601,385,76,549,184,733,853,177,517,950,503,849,884,447,404,310,759,700,439,170,183,818,177,604,774,405,237,86,909,209,238,380,50,321,241,289,5,471,767,241,690,492,374,742,109,840,332,681,92,248,194,604,55,379,424,460,249,639,414,948,199,648,641,469,551,859,214,703", "833,961,935,25,681,50,653,349,269,767,511,242,521,211,839,535,873,28,359,957,689,600,423,122,793,373,930,985,628,512,904,204,218,269,413,161,866,22,107,40,527,365,618,302,826,110,815,251,162,813,57,711,656,108,773,928,329,194,91,699,327,648,343,671,348,211,826,701,457,704,10,312,515,66,485,120,222,921,889,175,97,154,302,419,372,544,767,508,843,209,721,551,885,669,358,5,79,386,315,277,938,358,611,150,304,669,350,330,417,336,71,830,376,371,868,174,94,387,883,58,890,837,496,541,669,650,839,996,412,17,201,632,673,478,684,559,444,39,451,905,843,688,839,19,917,375,9,462,382,365,932,516,579,934,501,982,242,517,186,374,321,608,405,239,320,188,126,68,645,9,589,833,532,884,293,152,736,528,197,392,452,32,706,465,700,391,867,644,477,337,207,826,376,738,43,24,678,614,594,650,592,435,328,594,71,457,957,320,666,474,92,650,671,177,541,155,656,190,433,930,595,563,327,121,4,934,695,678,538,600,784,815,111,584,461,21,403,301,836,605,699,53,427,642,52,899,95,336,811,841,391,395,897,794,96,501,122,922,827,885,513,428,839,149,989,596,384,206,288,983,240,536,769,937,28,562,970,643,953,301,119,400,252,181,927,671,944,206,758,619,655,334,612,35,675,956,759,425,251,466,7,761,258,625,136,8,641,676,659,701,643,990,630,8,670,509,74,503,868,863,437,900,4,958,452,995,842,80,621,872,612,570,848,674,693,820,243,48,872,699,576,238,472,359,435,330,434,788,846,894,800,224,126,503,528,703,445,192,883,297,519,558,884,749,861,922,206,559,993,355,216,301,666,441,854,221,232,258,634,611,750,627,675,438,97,955,269,240,853,579,268,565,730,125,367,95,853,495,486,520,389,473,949,904,647,999,535,498,977,397,884,693,880,188,938,952,23,532,841,837,979,629,34,657,533,349,489,165,112,432,836,607,542,68,953,202,205,973,492,347,669,991,522,435,947,459,240,132,759,168,68,375,209,19,210,781,881,614,360,104,543,842,592,877,446,496,707,923,376,979,835,704,219,920,414,544,608,274,623,143,317,677,840,512,689,542,168,5,258,97,512,910,143,13,262,436,181,196,44,550,828,659,676,609,773,467,904,948,922,912,779,909,716,222,295,201,681,108,262,8,328,719,148,466,740,173,219,0,943,466,945,151,679,66,204,981,8,909,86,14,696,363,803,650,989,298,826,139,996,285,253,293,732,2,397,337,228,286,208,536,806,853,872,711,301,331,901,419,888,599,871,135,233,606,646,751,550,529,483,821,731,736,450,926,914,173,962,361,22,754,608,431,966,886,514,430,202,64,586,799,717,435,874,254,967,39,13,878,834,596,961,59,771,272,351,316,945,891,226,864,6,946,873,711,603,724,209,326,985,220,675,887,707,977,808,912,469,795,970,135,729,853,825,68,125,146,196,94,745,250,267,681,225,845,613,582,890,768,579,885,176,344,171,921,568,218,961,237,154,197,275,187,344,92,492,38,603,727,373,92,877,134,584,224,330,521,294,472,1,449,755,843,970,811,217,58,645,383,821,437,193,172,828,973,629,407,661,910,525,891,292,612,278,556,675,90,790,494,325,573,408,151,110,825,954,480,312,634,758,272,832,260,42,533,579,116,602,790,331,416,43,392,91,935,9,623,497,287,200,477,800,422,916,90,155,468,237,890,745,261,430,224,576,909,104,697,803,354,816,208,230,921,183,603,476,110,190,683,819,445,475,92,654,190,686,909,399,980,126,73,66,515,658,254,121,996,442,464,159,153,714,10,369,157,943,92,355,771,978,767,934,431,873,913,444,136,828,572,541,210,768,27,464,931,973,22,683,446,210,14,372,994,864,780,758,37,75,579,276,596,303,221,149,332,425,263,112,347,244,794,504,412,363,566,748,899,137,23,154,784,294,681,65,306,861,11,931,374,179,541,529,359,126,268,909,432,595,259,312,398,939,6,97,847,757,334,436,178,980,558,538,47,718,550,590,97,201,229,523,8,325,928,545,522,554,219,109,908,418,885,26,975,653,687,906,825,303,690,887,839,140,108,701,423,623,652,889,328,234,575,595,487,603,155,185,746,399,933,650,752,343,929,309,860,321,816,735,432,250,35,607,390,94,347,30,858,936,445,157,420,434,790,582,324,628,610,895,569,99,854,465,877,444,826,29,315,720,391,753,909,833,609,180,272,699,758,75,760,193,394,685,826,358,192,79,364,751,600,103,215", "958,667,530,379,381,753,696,608,961,210,728,302,897,518,724,479,81,34,467,681,951,825,812,869,994,960,35,560,768,291,593,253,405,602,585,560,863,795,464,391,715,973,537,671,978,28,3,367,305,244,573,400,363,545,355,698,685,660,571,935,678,645,483,794,350,420,791,816,26,528,588,667,702,304,368,177,70,82,65,723,421,449,809,372,63,174,399,749,450,255,620,322,889,29,825,187,28,539,789,694,666,117,450,158,47,678,936,6,777,426,315,534,53,451,266,375,706,635,624,352,214,334,803,876,885,478,952,38,375,286,359,129,845,45,505,885,668,369,104,718,416,202,14,99,386,633,842,401,285,446,900,431,671,77,769,420,361,317,760,679,485,286,754,895,882,709,464,546,305,87,190,496,525,210,370,391,534,201,369,42,706,140,819,932,516,617,978,532,833,79,427,249,948,164,741,219,319,891,886,380,606,246,422,504,754,271,587,457,65,549,613,232,465,101,482,113,510,376,313,309,964,323,142,560,682,29,331,954,364,163,712,550,268,547,644,406,99,839,532,324,56,262,803,872,442,459,278,549,772,149,617,156,414,791,470,85,758,120,777,474,615,962,883,218,96,694,750,558,224,691,255,535,204,692,898,18,239,330,951,832,73,472,965,599,66,175,957,268,81,972,212,339,928,666,782,68,800,190,101,111,580,724,432,856,294,463,52,503,227,405,24,760,867,698,611,511,587,751,632,281,932,947,88,826,675,958,169,658,333,740,153,696,14,361,142,219,561,910,605,941,545,38,144,42,267,865,171,809,74,634,779,826,515,492,205,476,768,700,773,542,715,707,401,870,194,781,668,677,808,817,136,684,661,88,860,813,29,323,847,724,285,800,441,280,158,354,309,750,432,38,135,709,142,796,274,147,146,832,233,480,889,287,467,637,536,858,238,907,419,685,400,192,359,463,837,791,719,257,698,852,214,329,992,288,525,537,686,558,730,210,101,616,848,752,509,786,747,987,298,507,9,618,645,720,929,336,852,414,395,976,452,83,834,614,474,961,87,518,611,332,437,596,581,39,53,822,746,818,981,589,303,983,666,886,435,792,876,698,728,288,359,169,868,190,451,689,636,931,641,232,898,730,260,383,615,859,818,736,687,782,136,70,662,948,318,64,663,634,478,216,242,879,866,911,91,401,773,501,574,917,164,887,227,707,850,91,175,943,0,615,794,96,351,251,572,362,679,452,384,448,839,335,867,646,231,139,863,926,98,304,822,737,233,614,239,159,942,252,378,475,524,279,9,722,308,193,110,480,410,763,167,213,727,354,486,984,75,772,451,5,307,342,106,646,5,72,698,329,632,876,383,600,620,84,115,269,551,132,780,33,839,127,638,402,26,316,186,226,707,422,889,409,560,593,20,774,143,534,515,861,671,750,136,161,969,275,185,172,155,766,327,179,9,103,448,534,445,880,725,231,365,566,621,739,29,553,607,484,438,12,342,135,729,538,145,456,996,567,226,817,320,295,976,724,359,274,410,646,28,974,118,719,88,265,494,554,858,387,450,407,84,382,298,365,104,98,15,285,702,773,513,926,329,89,289,925,375,82,987,918,990,981,649,778,980,460,630,390,452,50,581,483,282,288,468,805,829,768,270,181,38,214,853,49,209,47,309,336,669,339,599,221,651,540,692,66,90,696,640,246,88,185,123,10,133,242,267,457,632,151,667,862,329,226,318,976,838,61,864,774,17,976,317,199,804,41,301,91,506,5,988,132,537,737,534,491,241,433,588,349,440,342,486,884,374,399,143,247,267,395,754,316,581,896,732,739,283,723,398,520,685,578,769,970,624,412,47,330,963,495,12,72,42,822,509,913,331,792,807,810,665,6,275,914,964,689,182,272,948,892,266,39,756,497,337,780,221,33,982,637,181,549,224,2,462,38,172,700,835,759,281,271,677,102,350,585,163,45,373,17,328,343,3,593,142,871,706,340,872,993,42,150,606,226,737,518,231,434,410,525,241,620,335,314,304,834,641,385,234,159,66,156,775,65,960,73,452,129,370,372,981,575,783,101,921,732,951,484,623,446,326,666,837,724,522,215,709,987,433,231,552,667,608,445,202,592,421,135,324,876,999,590,961,383,680,183,594,644,5,779,540,490,196,208,498,975,343,245,114,134,918,444,336,617,161,431,806,204,919,755,237,57,421,989,446,47,821,671,198,810,861,188,699,65,89,326,76,515,734,581,629,77,201,744,483,82,239,583,331,905,71,82,8,182,199,394,67,634,136,182", "784,781,366,450,923,587,267,775,876,165,502,445,426,484,907,928,755,857,568,354,537,864,567,8,900,156,504,773,294,640,240,552,686,887,567,858,137,443,251,303,388,685,110,293,134,878,144,393,440,731,740,749,350,399,320,724,454,694,794,406,589,33,905,980,625,728,355,572,767,338,175,431,329,144,467,936,441,831,179,958,85,606,402,960,345,186,68,40,519,594,912,162,486,813,612,744,210,292,34,958,820,909,659,398,893,414,234,207,181,329,909,823,936,895,169,351,296,712,800,39,19,166,187,471,859,287,925,413,629,845,259,603,325,80,735,163,22,971,791,59,888,67,855,934,132,807,691,103,994,220,804,969,975,811,829,822,305,930,896,203,630,366,922,851,227,825,969,47,290,535,715,857,902,671,713,100,215,608,345,533,756,989,180,34,734,990,22,913,945,44,629,609,320,629,690,267,33,887,529,306,282,880,122,591,715,198,749,981,336,610,346,160,196,337,391,92,863,522,335,602,633,624,555,884,580,947,183,475,108,972,8,549,256,492,928,934,422,310,249,948,704,525,531,182,919,123,125,816,861,700,842,531,171,462,54,341,757,589,701,878,644,379,626,386,327,872,769,733,40,429,284,759,782,354,479,748,858,15,89,34,81,672,954,716,319,756,794,458,655,459,131,734,730,192,610,451,438,596,290,967,41,291,385,259,578,835,31,708,775,602,945,395,499,578,515,727,966,247,100,150,289,234,530,565,566,88,1,523,987,297,710,169,72,884,805,485,905,652,451,650,110,953,759,10,448,767,192,953,971,251,319,391,659,966,120,647,417,240,891,925,353,206,87,618,762,601,138,487,38,152,757,728,498,630,431,731,44,563,598,793,282,702,626,49,43,629,686,496,249,4,526,455,649,868,820,907,605,603,136,32,486,955,725,276,727,908,447,451,893,481,889,49,338,138,862,112,92,969,797,485,668,670,576,85,229,350,613,387,957,245,770,816,481,925,734,532,894,528,368,420,367,663,705,307,357,484,468,261,599,425,391,149,732,673,300,162,744,505,233,929,415,138,515,946,896,593,346,626,33,936,985,215,38,18,58,967,4,774,270,897,334,634,445,81,341,823,499,307,557,182,305,344,471,716,187,766,74,27,437,906,584,536,806,551,922,619,922,813,650,743,160,893,792,14,119,941,289,144,288,297,651,277,228,469,328,142,673,466,615,0,645,479,730,550,573,161,841,490,415,861,827,667,753,158,333,263,34,41,540,60,681,18,373,87,424,789,146,252,471,768,954,905,112,871,380,880,522,143,310,711,360,441,511,548,743,103,587,57,331,844,588,799,322,932,825,592,312,481,314,858,431,681,446,460,17,752,509,911,628,697,783,419,357,886,537,296,824,656,21,362,86,357,414,221,694,491,867,576,986,241,202,465,168,431,737,625,299,320,69,39,708,521,14,14,54,29,63,605,732,51,274,173,240,570,3,52,206,575,194,223,21,212,929,458,583,10,395,551,600,710,738,7,81,656,15,342,962,452,143,998,986,507,636,870,48,158,453,562,353,609,100,251,271,275,880,890,57,163,901,656,184,507,296,284,107,10,517,175,386,410,887,716,215,772,837,719,95,213,295,435,973,862,729,827,19,456,755,277,307,725,105,409,700,940,711,323,194,620,281,207,795,407,171,289,990,720,168,919,658,744,273,457,995,688,133,485,651,361,346,956,400,792,718,886,162,276,518,770,471,474,212,648,996,366,965,76,819,452,634,218,769,263,195,374,924,987,728,548,615,908,827,754,193,800,105,559,267,544,265,844,113,690,887,107,280,621,994,904,419,11,702,34,347,312,579,51,79,909,39,814,410,207,967,352,663,835,397,135,501,777,218,411,196,107,342,285,765,75,149,997,979,680,86,712,225,768,175,232,885,933,573,855,466,325,515,911,133,213,995,822,219,793,830,156,418,964,29,821,157,9,425,622,547,359,392,810,419,253,649,892,244,716,739,16,381,743,805,490,110,213,696,842,210,765,905,79,215,538,630,258,553,74,283,556,481,361,380,568,612,206,364,76,744,361,528,134,591,810,587,990,6,976,455,526,257,778,92,856,872,979,97,922,662,318,42,77,284,459,72,3,701,776,344,386,398,596,908,32,954,572,877,412,407,215,817,845,992,349,707,306,656,322,871,944,656,386,519,593,677,107,959,657,32,184,535,519,232,646,816,240,323,295,173,266,661,589,553,31,84,584,629,128,68,530,843,420,154,298,515,383,531,912,116,247,565,332,389,555,675,878", "852,137,822,458,869,751,167,367,862,664,794,175,222,331,442,227,33,853,13,604,567,347,134,244,677,325,572,651,724,613,679,543,573,586,324,923,860,741,79,620,354,509,77,346,687,962,31,652,989,960,756,160,64,219,459,922,623,446,164,408,410,476,280,624,415,104,409,917,150,943,380,464,551,939,238,615,799,465,942,558,169,764,735,200,591,585,975,252,774,320,518,410,52,627,505,493,210,478,517,650,308,515,936,996,725,672,663,144,998,697,226,971,431,691,285,117,47,181,346,37,217,461,581,687,305,547,62,15,82,980,961,25,939,631,86,885,366,360,999,700,998,610,507,573,233,362,467,102,710,607,502,324,95,640,793,656,412,543,860,453,332,578,587,694,833,43,488,496,448,644,64,59,563,576,737,402,539,766,963,366,385,733,849,407,967,70,436,23,587,332,894,874,797,770,766,78,227,115,793,166,429,464,773,744,565,131,397,998,590,827,398,546,234,867,920,222,844,375,328,344,558,807,471,840,529,821,991,878,776,768,339,821,456,992,216,356,594,255,322,28,725,635,554,88,93,676,950,92,144,271,171,753,909,337,837,554,95,339,604,846,518,226,100,213,333,64,687,203,300,91,319,672,728,900,697,865,736,349,378,909,358,568,613,113,814,341,407,791,359,77,237,615,903,424,82,871,561,56,694,545,250,800,924,569,180,518,105,378,576,582,543,374,565,329,823,545,411,297,415,488,360,18,482,205,961,15,542,60,446,945,569,235,949,673,870,520,505,45,184,522,409,585,710,424,812,443,423,425,89,879,44,788,272,692,993,789,991,83,118,730,464,950,407,425,173,25,997,529,997,394,253,404,520,228,861,905,125,919,714,121,332,486,216,411,775,440,31,363,482,967,965,118,268,996,415,594,608,849,428,343,35,441,833,533,486,997,655,826,924,864,123,889,604,405,718,392,977,162,722,836,927,508,702,771,363,936,874,253,756,930,306,295,489,456,454,940,858,778,157,494,318,267,508,54,524,561,879,795,447,274,43,966,838,774,49,759,104,11,813,97,788,834,899,138,221,63,844,681,873,830,334,995,58,551,862,459,715,896,917,74,705,770,799,169,733,843,906,378,63,618,319,749,262,564,424,216,381,451,478,990,213,519,987,373,451,342,37,681,384,160,936,729,535,981,962,910,3,220,661,712,539,94,650,335,326,347,51,945,794,645,0,872,446,196,137,175,1,451,576,18,965,900,104,723,394,660,942,634,606,927,668,739,444,468,481,918,786,997,796,415,724,748,636,665,164,721,789,361,746,3,876,455,885,764,231,208,107,375,501,226,739,455,233,94,557,386,399,509,740,300,943,483,707,90,773,790,305,921,749,658,865,556,335,896,871,735,909,78,568,817,155,774,677,424,911,745,405,733,462,447,220,348,625,14,348,364,394,448,291,11,496,661,107,954,478,454,385,660,593,469,908,695,469,508,71,297,236,572,127,316,205,264,483,750,897,222,671,574,726,967,515,913,407,500,284,97,579,19,251,875,926,978,508,336,161,987,994,519,851,202,426,820,236,841,820,387,486,760,190,745,742,170,894,608,447,187,704,913,606,594,983,67,377,49,290,453,415,410,659,691,65,400,686,451,150,992,424,764,642,186,23,855,158,643,501,982,367,117,791,355,272,246,925,882,571,143,856,490,691,628,787,152,987,593,70,13,484,664,258,894,117,714,116,312,746,889,71,424,333,527,895,168,582,679,387,816,861,379,933,959,469,141,503,481,884,528,208,926,262,233,522,126,50,491,19,258,697,800,195,801,746,882,638,761,35,447,49,2,764,429,251,21,769,479,153,746,633,221,775,497,329,593,747,528,455,336,325,694,62,715,306,730,217,852,764,941,873,880,886,149,693,422,953,832,187,396,36,714,187,713,353,94,326,604,373,34,620,647,548,524,554,5,343,952,9,172,912,994,698,61,438,137,338,184,635,724,358,983,973,933,50,364,398,490,507,887,324,436,868,777,882,894,805,484,755,640,66,292,640,385,96,558,670,583,260,557,973,234,107,76,648,656,343,102,530,563,763,534,68,245,661,399,900,723,599,584,967,104,361,244,366,111,894,423,247,204,931,986,847,690,669,450,834,682,110,872,504,938,201,417,19,749,151,744,103,469,435,22,65,842,864,721,940,38,338,852,65,989,969,222,903,556,156,937,816,543,595,157,736,686,154,719,264,409,766,650,118,181,266,67,718,332,4,327,771,218,763,873,137,950,238,29,806,661,413,407,457,364,282,273", "817,842,203,28,307,573,699,320,100,770,618,155,366,633,618,802,447,663,201,166,632,937,460,960,503,215,440,444,213,593,428,773,583,4,943,219,501,369,5,129,462,24,297,881,283,180,700,750,564,127,948,685,790,63,232,973,290,907,425,574,347,665,24,459,175,695,143,93,460,829,624,224,580,330,520,930,27,328,771,87,792,475,463,688,78,913,212,489,460,55,839,824,900,320,450,217,590,206,855,977,697,669,290,228,755,641,303,437,287,211,265,127,372,410,857,971,943,857,302,44,555,80,49,680,319,297,291,624,782,788,378,415,567,365,26,166,104,555,811,513,330,924,646,831,487,622,153,136,30,954,136,173,245,846,181,740,155,728,380,233,524,17,224,9,235,69,634,562,542,121,707,176,54,636,135,186,491,911,258,962,152,185,252,992,100,188,507,540,360,749,778,795,599,536,960,64,532,721,818,141,663,993,820,974,547,480,116,303,516,377,197,332,455,480,217,942,775,835,914,481,938,897,196,240,1000,441,606,375,689,639,534,676,483,749,926,981,500,427,554,493,736,177,3,986,512,767,255,639,384,556,380,511,601,781,874,502,547,824,386,642,167,70,668,968,100,768,372,511,681,230,909,726,287,607,876,624,581,847,784,627,405,304,756,719,667,492,991,44,772,67,425,502,223,63,307,204,396,646,471,943,884,167,484,746,22,404,714,852,448,498,904,637,806,528,669,80,475,159,156,558,88,646,733,658,991,404,544,497,503,351,216,604,269,695,291,296,54,638,783,612,290,581,399,466,856,257,589,155,67,821,852,237,862,695,538,780,57,621,505,272,548,627,378,782,245,599,970,55,8,865,405,714,556,339,870,17,627,748,231,226,667,399,521,782,311,273,573,860,126,607,745,698,766,932,541,90,79,745,769,81,953,92,22,95,786,367,235,193,986,612,858,234,595,597,163,227,45,170,85,849,583,347,303,965,897,700,108,22,906,468,85,158,99,6,843,942,249,849,603,695,368,697,63,79,991,651,737,441,588,39,993,697,715,829,186,966,290,726,218,558,746,497,98,900,418,379,642,800,329,573,613,821,211,170,209,145,468,790,905,895,227,209,110,904,695,966,498,523,466,988,553,210,462,805,173,574,527,825,643,661,344,383,546,323,940,886,583,249,539,887,1000,721,863,370,307,653,999,470,576,258,939,40,470,936,957,549,840,151,96,479,872,0,325,582,647,98,590,508,660,346,897,764,885,664,947,774,498,708,765,437,158,310,883,988,311,998,778,727,562,662,900,402,145,255,799,612,830,459,266,602,164,991,225,819,309,606,795,454,166,672,321,632,605,719,344,133,560,491,368,469,826,356,501,914,273,502,841,623,483,80,71,772,264,347,191,303,307,243,764,690,965,650,190,860,714,606,206,398,968,400,100,210,616,957,750,989,435,312,679,827,945,727,709,572,520,941,583,460,106,968,797,148,499,684,478,136,264,478,471,971,493,133,498,215,971,673,821,867,727,942,803,832,371,960,165,403,973,456,130,33,483,783,186,92,289,555,293,941,982,218,983,748,366,696,729,220,302,462,522,681,893,897,325,290,170,663,837,446,250,323,356,508,266,760,619,675,91,592,116,939,778,374,20,841,439,953,702,684,250,904,530,457,352,899,99,165,109,426,627,694,508,196,632,928,648,984,631,811,377,549,808,31,839,369,246,107,818,489,902,973,392,832,957,136,645,411,438,57,603,319,485,186,230,437,133,211,208,612,382,527,115,592,542,209,312,233,187,447,972,869,730,223,476,368,23,439,634,320,516,96,220,716,666,974,614,927,63,855,613,648,591,727,190,478,342,278,305,660,564,856,821,514,128,850,420,576,208,346,365,345,106,779,189,201,541,793,993,400,183,455,452,671,28,332,918,647,730,694,952,388,590,840,638,912,969,233,591,826,288,495,938,395,255,472,200,961,555,718,771,154,146,268,938,183,328,149,200,526,621,649,494,513,342,117,150,289,903,210,309,241,139,847,453,20,866,404,41,832,124,210,943,411,172,385,128,913,411,852,708,23,455,756,477,402,970,986,807,205,98,822,421,58,619,480,811,358,903,446,147,491,232,22,950,264,271,348,206,966,108,625,361,669,928,988,118,906,374,954,712,444,298,569,22,496,808,123,521,886,74,601,412,289,110,947,573,439,994,964,91,701,151,977,646,293,787,24,463,857,480,501,846,360,367,220,102,598,913,143,324,611,837,892,217,677,114,223,994,785,851,503,134,892,42,737,986,775,913,154,550,645", "835,79,704,899,21,947,775,980,417,60,915,588,49,920,311,604,575,936,581,286,690,378,857,367,399,958,733,748,945,845,335,718,657,130,239,118,839,188,711,459,268,929,889,557,740,203,75,105,392,194,524,529,760,732,476,173,150,330,311,313,477,715,646,900,6,182,957,154,543,378,880,476,180,984,593,570,843,988,168,24,832,593,692,179,39,6,40,670,479,258,938,255,730,387,524,278,496,228,963,45,380,210,512,263,9,372,970,537,9,166,996,593,710,573,785,36,121,224,128,623,672,357,265,766,553,360,539,788,533,239,436,3,895,231,544,921,452,728,213,540,145,694,63,462,107,392,825,616,368,279,165,50,559,94,361,50,227,17,853,140,56,660,899,522,760,115,805,922,175,840,334,699,857,503,827,322,206,948,380,230,997,352,131,576,558,702,351,741,54,381,171,558,375,240,843,554,955,279,293,817,176,83,704,183,96,572,693,478,569,264,998,900,546,877,37,915,725,741,274,400,557,793,534,96,335,464,226,886,25,419,101,16,226,213,917,338,378,714,302,225,490,2,621,497,3,4,856,815,401,681,137,817,247,415,824,872,768,832,735,463,979,509,503,620,977,471,333,716,580,505,330,69,799,514,137,259,31,995,600,572,398,978,771,741,391,113,53,435,985,660,472,664,637,727,813,829,958,177,600,431,99,516,23,576,94,472,38,532,78,629,668,427,803,268,679,663,704,618,22,1,562,290,418,432,554,694,723,806,988,162,133,523,979,873,997,209,661,604,594,665,380,522,151,638,833,467,769,585,640,167,340,515,480,705,815,153,154,224,949,422,87,99,339,721,864,325,248,339,421,281,269,28,711,300,124,28,518,701,712,801,514,492,25,829,397,62,558,412,678,27,801,814,441,53,148,779,713,254,250,101,506,730,231,596,596,890,505,831,282,474,51,120,6,763,387,377,944,862,743,638,941,45,645,983,761,213,157,901,810,733,341,455,379,819,153,121,929,321,948,428,925,739,856,122,126,357,20,809,365,296,634,487,262,456,316,55,602,723,904,469,972,435,502,349,10,201,107,380,678,921,314,342,879,875,410,694,587,742,818,126,863,346,650,989,415,831,839,94,389,619,845,984,900,154,512,25,186,344,467,261,193,913,422,273,948,365,150,134,547,391,581,993,475,955,89,866,282,345,640,686,386,475,313,752,693,41,463,679,351,730,446,325,0,298,614,702,376,468,14,553,744,586,465,383,522,582,532,653,744,184,183,199,246,295,65,338,705,348,793,632,989,295,726,598,901,584,633,754,375,343,927,431,924,426,586,552,177,213,929,947,62,203,957,713,964,212,129,561,773,277,450,865,231,87,937,275,682,708,351,672,893,397,28,76,805,484,517,151,280,888,697,400,746,420,546,163,932,1,180,742,331,928,845,426,817,599,125,3,725,926,959,218,467,583,796,147,125,484,77,482,57,558,563,878,615,836,897,449,634,179,710,259,617,623,133,529,642,96,7,726,4,694,525,41,995,398,104,31,727,408,800,990,762,555,148,897,854,421,857,212,75,430,286,655,629,369,161,352,122,439,681,369,914,39,346,874,789,33,36,431,966,848,230,151,320,617,976,610,34,170,561,36,130,459,456,853,717,163,286,125,583,838,153,623,325,475,205,99,198,310,773,496,557,477,552,721,181,209,85,205,493,179,929,705,366,970,148,805,546,462,53,614,380,48,140,961,80,404,595,578,13,980,351,396,705,8,685,980,245,525,725,989,528,50,960,67,39,485,647,990,623,520,639,561,698,904,306,54,742,5,528,403,561,717,756,460,651,226,280,168,623,369,715,974,226,386,924,484,214,457,742,196,92,789,776,138,436,17,507,730,713,550,489,322,125,619,151,967,240,423,312,51,259,848,227,922,845,543,223,43,725,629,885,376,475,470,564,530,417,508,398,384,538,111,364,422,847,726,732,485,727,359,948,949,771,690,766,734,590,268,191,201,298,42,661,331,609,364,249,476,501,406,897,643,492,804,938,273,248,189,884,358,465,571,841,553,326,142,283,808,34,179,490,614,834,233,714,482,427,325,116,781,339,447,52,281,348,35,386,970,541,287,444,976,565,864,259,44,726,750,858,163,877,348,20,620,629,739,781,490,545,278,475,281,19,971,238,164,343,908,398,831,488,177,33,131,906,55,635,45,154,936,202,32,899,898,364,76,771,838,896,367,191,324,943,805,76,3,975,157,927,330,876,350,204,163,283,472,811,848,265,829,311,415,913,229,458,398,690,126", "829,937,449,169,469,221,723,478,548,884,205,718,177,226,106,479,33,943,520,724,213,754,130,870,296,101,812,881,145,729,862,918,485,454,976,641,585,978,819,516,485,890,830,386,768,776,618,48,447,899,452,121,999,698,563,998,798,282,34,848,17,613,516,495,6,865,806,695,224,384,532,52,560,752,688,787,636,967,738,882,888,681,643,383,722,776,599,954,538,512,650,395,232,55,17,169,874,268,746,470,193,796,32,94,254,806,604,293,638,912,107,631,385,568,913,193,921,271,328,987,123,948,966,895,991,491,980,598,97,325,836,514,12,924,809,899,151,577,703,668,991,602,905,921,258,225,903,520,240,290,466,302,920,859,157,391,742,103,594,92,805,906,581,787,529,430,944,302,769,690,612,112,671,69,328,268,497,203,925,484,879,600,319,13,437,20,402,208,582,570,485,325,944,707,273,179,107,623,440,416,202,966,768,250,156,997,642,761,58,586,274,197,105,941,752,779,439,799,427,645,24,894,260,383,125,141,787,229,244,386,168,263,13,129,651,303,391,702,538,370,892,589,766,726,49,743,797,80,117,671,875,73,237,69,187,788,42,660,44,964,322,783,424,4,340,427,686,838,184,921,579,237,225,26,520,94,179,735,771,186,21,989,126,111,303,292,6,373,947,550,228,718,384,863,267,557,916,284,660,374,56,400,393,320,892,963,217,59,121,572,898,659,329,466,600,558,572,208,2,890,539,982,164,751,26,64,73,124,222,794,178,806,864,923,74,280,443,676,930,901,131,147,281,369,716,310,778,39,961,215,582,10,91,401,800,135,633,108,565,102,699,874,203,542,394,43,582,187,868,391,715,429,700,274,368,613,892,165,813,905,960,499,606,848,801,754,918,564,597,320,531,402,447,795,584,643,818,236,950,990,567,975,710,785,515,806,961,699,120,726,512,741,321,641,32,389,223,625,338,316,528,517,743,576,632,70,512,395,104,139,888,676,996,480,129,40,48,308,201,40,479,318,993,553,923,912,346,433,572,852,392,360,210,366,804,277,139,525,263,654,747,826,417,751,548,984,893,937,99,961,326,249,138,54,214,919,496,680,89,517,551,224,186,819,197,347,67,614,222,107,28,938,31,138,960,489,927,429,41,249,518,292,490,364,54,422,449,141,461,114,964,591,257,196,752,77,928,608,884,922,683,519,414,224,878,448,113,66,251,550,196,582,298,0,906,575,457,953,32,225,383,157,725,882,707,633,858,153,219,408,707,729,88,466,545,991,235,734,336,781,542,128,111,560,592,968,72,200,340,511,653,260,928,643,568,663,916,574,288,325,86,591,706,876,189,807,255,623,250,47,304,164,572,783,674,470,375,765,355,329,696,241,37,849,111,403,490,780,275,141,845,625,521,169,688,268,369,512,687,518,455,124,981,8,382,807,233,988,374,108,34,4,8,904,487,167,919,397,476,630,940,906,810,489,219,245,267,271,775,149,672,103,262,405,99,219,936,974,349,272,701,372,211,610,141,968,301,534,243,183,526,677,387,345,953,671,542,993,935,503,883,566,29,560,8,567,785,752,390,767,801,965,116,370,797,264,570,663,700,562,355,353,263,468,78,35,664,623,54,940,284,199,449,627,714,445,24,511,794,741,734,895,144,862,600,614,832,589,781,206,396,405,348,556,583,27,520,782,387,702,456,857,79,949,234,656,523,431,585,525,667,211,263,222,588,638,312,581,175,589,242,686,171,979,871,403,587,138,865,248,839,477,177,274,299,361,28,867,464,279,15,897,200,248,756,2,783,625,484,389,757,503,887,645,193,488,642,867,422,928,370,481,610,76,268,816,738,542,910,581,289,575,365,434,793,868,871,219,549,170,168,581,628,432,477,731,765,865,355,485,850,436,298,875,582,568,893,954,790,253,626,909,527,418,101,937,663,229,51,91,720,471,336,963,425,880,643,216,70,449,101,929,673,521,45,77,245,878,940,85,904,964,271,992,887,297,400,346,351,472,304,168,91,426,383,707,38,606,165,280,576,487,794,803,563,68,393,271,640,953,293,571,821,975,326,695,612,753,815,178,588,949,848,981,576,573,562,628,115,20,969,862,177,587,695,702,849,671,303,193,568,58,357,221,960,416,539,388,752,803,630,381,694,774,285,747,958,972,233,852,792,223,871,142,270,797,559,521,535,987,646,116,395,489,223,11,564,31,77,475,500,36,287,918,317,54,649,689,261,866,529,934,161,816,532,327,123,944,69,8,786,667,685,251,243,252,542,980,680,619", "911,810,665,627,992,624,274,217,423,394,675,803,177,766,321,222,422,410,811,206,675,475,818,755,255,385,832,704,885,272,126,713,886,403,121,852,125,576,411,879,875,335,980,961,835,773,281,863,100,943,575,339,736,465,740,206,468,681,726,227,138,446,460,42,330,9,381,580,300,265,354,917,177,374,651,210,832,714,740,770,390,799,307,410,805,479,898,458,277,814,689,299,502,350,289,186,92,325,511,709,842,167,794,341,925,438,163,114,326,59,923,956,447,169,413,631,832,256,177,251,752,611,73,896,59,910,399,58,708,134,247,724,780,498,657,257,833,160,190,739,548,347,766,209,975,549,696,505,553,947,212,826,90,92,211,24,458,717,364,446,368,216,789,142,340,322,697,324,291,381,958,293,722,815,378,54,834,210,381,943,719,10,528,689,410,142,123,715,20,909,411,553,69,294,203,996,295,874,532,235,44,975,546,992,598,416,85,682,703,225,529,801,817,375,412,710,98,313,508,494,1,499,563,859,782,272,876,413,639,725,214,794,385,199,731,779,297,872,578,382,617,359,401,645,500,900,916,898,252,261,608,922,711,933,601,640,575,703,954,378,99,941,453,766,916,564,474,653,768,6,503,511,698,91,742,807,189,144,219,211,984,630,626,819,195,365,778,79,389,599,204,330,907,622,394,805,393,711,791,722,124,265,185,140,920,573,344,811,920,31,262,587,211,24,778,993,923,504,337,778,821,223,925,939,758,349,779,194,504,396,552,171,175,236,459,43,98,522,21,332,130,255,16,287,754,644,300,892,38,462,696,456,497,597,519,104,112,355,96,68,624,130,600,356,690,321,740,227,903,510,324,683,628,11,689,825,718,352,672,976,854,985,901,727,561,816,185,749,816,753,710,808,255,189,66,562,681,628,650,102,933,553,103,881,889,828,942,782,363,80,278,51,198,294,742,620,25,362,983,974,950,539,682,587,17,606,537,313,299,521,345,241,657,139,653,329,646,724,781,386,991,521,99,831,20,887,45,647,744,570,181,515,933,470,756,558,115,981,124,195,338,218,702,38,888,600,42,697,269,997,404,98,479,214,95,111,3,144,37,37,991,435,271,765,804,341,168,460,164,761,138,908,390,159,779,561,52,127,207,756,568,16,770,910,716,588,622,878,633,693,670,326,122,280,311,748,118,67,558,192,445,476,770,137,912,525,648,204,572,573,137,647,614,906,0,370,984,879,702,29,931,78,991,190,832,402,398,647,64,289,47,96,185,907,383,487,251,504,410,350,44,686,1,765,471,767,770,188,355,383,871,519,934,56,795,661,616,711,507,625,252,980,613,36,741,784,603,921,181,779,552,627,424,960,102,581,168,608,34,626,143,8,790,847,267,813,702,153,789,800,498,992,139,150,530,332,598,41,445,351,73,280,812,573,9,652,570,352,411,18,76,782,741,643,687,976,572,838,187,386,831,527,840,257,317,821,144,84,307,400,746,400,937,911,604,374,119,379,215,424,244,63,433,647,715,193,729,870,898,497,542,918,552,698,388,902,375,320,732,546,627,642,56,491,223,469,373,756,596,932,427,7,676,122,869,853,189,978,278,183,174,207,354,336,860,838,377,768,117,246,104,35,535,953,585,208,535,254,701,588,690,336,446,703,153,645,106,964,926,389,168,238,214,74,868,651,437,853,801,980,365,12,299,545,917,125,791,893,466,485,971,710,874,381,806,756,922,647,309,273,36,874,377,547,450,999,560,310,621,440,943,87,553,370,83,997,397,26,781,526,331,509,584,205,136,659,964,882,989,228,619,354,238,175,482,23,619,526,960,810,136,638,216,123,232,935,615,895,831,846,402,813,605,453,432,327,928,615,268,341,799,593,737,862,882,178,508,605,949,509,221,675,117,237,575,205,616,137,798,861,739,95,266,726,535,716,302,450,151,626,404,898,372,188,627,694,239,608,858,866,994,505,717,555,489,845,236,120,335,21,611,863,371,582,791,292,111,901,908,759,260,495,371,490,483,351,4,770,589,359,296,16,143,882,395,258,234,169,408,716,193,713,595,806,274,37,930,190,258,256,950,431,58,581,396,333,649,726,668,661,289,330,279,482,413,782,1000,471,920,486,629,364,551,322,247,299,100,565,77,837,389,460,30,752,726,756,854,321,746,888,720,463,470,412,186,964,208,547,3,360,81,448,267,107,308,945,946,402,9,355,800,898,211,127,136,242,455,493,336,683,821,541,153,45,577,574,271,485,681,558,293,811,684,185,983,177,740,512,308,628", "254,56,158,879,196,363,910,344,462,127,682,615,907,981,849,758,915,480,100,173,76,130,230,146,806,530,11,951,239,870,921,122,271,260,263,753,170,577,893,752,650,472,191,933,810,609,424,611,626,924,917,876,258,566,645,603,342,508,876,949,351,548,744,844,468,871,866,49,371,415,353,157,920,989,801,886,766,190,992,557,296,161,102,985,997,225,345,148,541,80,853,368,995,487,5,946,675,578,353,812,384,390,100,904,585,560,339,607,623,530,549,176,155,835,530,323,294,235,884,65,107,930,406,684,544,916,433,971,32,331,461,931,232,392,169,185,114,913,457,703,697,171,296,269,730,599,73,483,320,379,147,99,187,190,508,347,533,35,901,730,748,159,365,759,604,698,2,623,504,133,856,187,511,377,885,158,476,593,45,148,109,574,158,18,989,348,749,808,446,273,239,939,442,685,809,832,760,839,734,98,286,350,851,765,594,920,278,327,257,337,83,861,265,948,326,777,743,659,410,382,518,639,516,65,225,237,608,255,842,324,717,599,3,744,999,104,956,230,284,398,265,781,502,574,668,258,249,366,206,390,436,252,269,314,74,394,704,772,42,629,392,384,756,687,212,936,439,418,744,213,306,230,633,201,368,689,75,970,634,886,688,647,831,171,418,546,618,610,539,348,808,464,579,936,477,402,916,110,694,159,776,206,343,729,895,10,356,856,247,665,777,586,659,541,203,117,55,450,411,33,179,548,656,275,799,494,214,348,178,715,553,117,43,417,434,870,675,702,373,190,841,20,509,154,961,97,922,92,670,95,715,811,10,766,188,708,937,250,370,857,63,845,798,52,442,595,885,560,28,340,136,907,884,254,121,698,248,998,702,968,254,274,907,839,757,304,351,974,758,25,65,178,467,939,911,224,981,313,517,614,29,906,215,602,65,605,472,127,202,186,920,997,624,923,709,835,323,726,771,167,608,950,850,8,293,643,622,688,8,523,411,490,485,357,160,670,325,808,878,215,781,93,838,250,600,300,955,114,746,936,302,481,156,702,256,163,145,91,823,38,634,64,771,5,935,805,42,520,401,613,809,372,23,794,967,699,41,788,55,789,597,40,742,434,169,350,76,541,544,971,668,307,910,381,746,650,622,541,743,15,762,569,409,23,430,518,449,473,409,447,57,852,268,623,334,188,588,996,476,734,41,597,309,430,875,900,208,981,362,161,175,98,702,575,370,0,706,986,332,592,894,705,252,715,406,936,735,120,674,106,231,850,25,145,435,160,923,776,568,143,628,33,429,790,859,144,918,782,610,923,506,463,460,765,371,523,393,363,747,493,436,50,948,972,372,129,477,942,655,808,243,968,437,374,643,930,292,305,710,722,934,17,387,78,499,44,547,608,487,460,314,539,856,185,373,589,583,372,608,289,631,558,416,505,420,56,763,966,199,426,566,857,970,890,431,50,506,189,276,285,645,347,519,992,559,867,362,598,94,879,764,901,45,10,836,932,987,405,336,539,90,390,717,485,398,411,949,743,881,203,655,713,145,119,498,728,663,843,502,887,972,188,462,907,343,852,206,862,412,849,553,410,400,18,368,206,419,303,55,457,860,436,5,992,14,435,714,36,836,684,702,455,948,347,26,747,570,854,896,581,880,960,453,498,406,532,884,377,764,852,560,611,729,447,227,397,29,112,717,237,898,712,745,926,959,132,114,463,34,756,979,393,602,815,510,106,64,188,907,866,857,990,435,359,206,223,466,159,939,955,949,635,775,826,737,222,500,262,334,793,772,879,758,519,157,370,682,596,275,567,167,476,931,571,961,39,704,894,222,466,487,410,183,248,641,458,934,7,218,956,624,328,19,77,682,356,214,197,896,939,820,906,412,225,140,230,287,277,772,387,728,163,236,703,125,309,955,318,421,250,272,547,739,885,155,8,538,741,621,498,125,918,519,906,797,858,703,974,364,638,980,610,937,749,398,291,406,926,822,95,889,72,578,93,112,466,235,937,428,680,926,685,106,797,359,812,121,796,302,89,81,520,670,131,864,64,129,627,523,721,654,593,543,184,17,739,316,546,460,396,734,66,272,210,542,354,752,982,186,296,577,634,746,231,656,474,683,196,279,429,440,54,690,534,274,691,568,194,247,725,643,675,789,71,317,698,275,767,944,316,422,534,112,428,800,206,694,372,708,124,51,695,142,198,347,293,213,800,97,168,773,149,904,260,330,707,364,168,965,449,242,224,279,626,805,39,844,875,272,957,953,800,126,450,117,759,720,81,68,35", "917,179,322,97,617,693,535,820,298,512,134,292,649,422,156,618,215,407,152,169,9,76,476,727,411,164,913,940,150,953,511,936,884,980,217,808,46,433,762,776,101,775,263,292,531,6,450,883,777,599,606,789,943,360,766,195,493,720,938,587,108,57,244,359,163,645,246,236,921,166,172,787,514,128,449,478,44,674,711,136,122,850,648,164,504,65,878,592,214,282,33,838,994,721,816,346,701,81,805,411,286,792,547,252,113,949,488,547,225,910,418,365,621,501,256,68,274,189,989,168,138,778,535,21,492,439,785,50,345,702,580,920,117,581,764,765,53,227,334,630,596,797,993,927,300,774,159,150,809,828,123,603,358,729,891,560,457,31,766,756,297,221,730,973,863,533,769,418,530,697,134,572,594,739,930,734,760,156,192,598,261,565,64,596,120,157,108,688,967,955,745,426,193,397,554,770,73,628,660,755,539,327,631,261,141,8,480,562,371,172,776,32,773,708,745,779,548,349,693,866,153,650,93,233,871,691,901,85,90,998,149,150,66,852,679,635,43,100,402,95,777,543,700,42,179,208,908,513,241,622,62,786,699,393,915,18,395,391,897,235,869,310,796,578,825,705,395,315,950,161,962,940,234,975,791,40,938,684,528,289,594,253,145,769,737,841,493,770,595,816,649,866,407,244,36,453,20,98,648,851,745,278,563,731,191,764,623,302,374,110,542,897,547,185,725,249,424,944,930,577,643,594,480,961,93,535,989,787,371,936,893,522,998,917,975,170,899,324,808,420,52,92,688,922,786,479,298,748,766,878,996,664,834,254,983,905,427,462,467,550,86,244,714,761,10,423,928,830,965,846,630,454,118,740,134,986,632,48,997,682,23,402,942,976,795,175,43,479,687,869,921,126,773,244,241,997,578,905,440,565,495,958,165,141,486,228,884,416,272,54,832,86,577,869,498,703,874,907,257,697,643,984,404,559,623,941,615,83,460,283,400,581,348,620,617,879,353,789,956,751,84,474,36,56,284,911,484,221,983,889,522,917,656,69,198,747,733,841,489,818,288,740,649,860,125,594,507,443,476,448,38,997,563,796,374,752,466,178,377,711,381,77,403,775,771,808,404,592,14,299,16,693,619,534,890,644,511,901,472,326,160,947,868,75,230,25,8,228,798,510,450,501,576,257,222,541,803,958,678,43,796,183,921,835,33,17,795,8,679,841,1,590,376,457,984,706,0,178,535,19,672,827,664,783,158,89,178,914,934,664,80,575,119,606,551,787,993,827,484,76,59,854,922,589,606,557,452,922,436,597,445,743,329,271,961,352,983,544,469,110,481,801,893,371,729,83,578,293,328,564,415,421,782,171,266,677,528,266,441,328,941,310,253,17,500,482,907,912,524,266,46,939,318,762,250,97,382,637,244,273,52,854,156,667,801,78,46,86,809,67,384,650,959,156,40,47,276,143,942,629,423,2,53,757,241,83,871,877,952,336,215,1,364,531,962,618,139,841,310,270,777,449,50,110,325,399,838,893,766,288,284,340,54,248,440,201,532,486,888,85,116,373,232,613,84,529,196,716,151,702,828,360,177,634,246,716,665,117,514,467,888,750,162,656,127,823,192,334,285,982,350,737,727,295,181,265,705,441,593,978,714,532,478,751,952,372,647,226,442,532,474,858,703,205,530,4,585,564,667,440,420,874,295,135,196,407,320,277,671,216,242,736,302,508,777,323,575,984,85,845,947,895,816,578,488,868,655,145,23,141,683,556,369,254,776,511,141,520,423,551,353,278,994,527,989,346,446,981,776,967,844,766,956,682,398,48,969,876,332,985,598,476,787,799,996,799,737,437,760,636,378,76,21,506,788,646,23,828,334,899,337,357,618,703,923,730,906,842,502,38,445,205,735,672,728,546,487,19,483,461,417,598,101,210,12,531,170,874,367,327,770,795,909,638,945,621,238,368,765,802,262,367,513,96,727,461,794,216,698,19,510,707,480,943,352,486,715,393,660,136,842,116,986,995,282,769,274,875,650,476,237,417,950,439,429,701,861,788,480,104,876,593,549,170,958,157,560,518,215,927,211,57,993,703,269,650,516,793,936,746,469,949,44,593,35,675,516,778,85,718,268,298,355,338,830,188,318,253,223,677,661,193,590,959,575,884,672,459,923,357,758,823,286,335,570,442,803,384,653,61,558,808,761,661,617,750,165,197,932,128,758,203,56,953,372,797,467,110,330,188,64,485,876,866,112,910,222,514,285,631,40,471,861,948,381,542,682,360,952,405", "706,335,293,84,598,442,893,636,834,403,82,686,653,821,307,20,331,296,797,759,169,148,79,867,991,236,675,30,305,298,293,35,669,7,283,303,277,906,885,647,224,455,42,22,652,405,624,706,874,490,54,558,713,68,794,823,407,802,896,986,240,746,399,543,618,439,563,216,377,128,466,660,21,253,746,666,104,272,239,898,258,194,549,288,92,586,3,581,266,603,468,172,628,938,136,557,280,896,838,772,37,394,268,884,480,383,245,808,824,332,557,752,481,701,401,222,984,599,189,714,426,116,502,936,117,630,983,792,758,144,455,436,332,277,897,611,624,394,888,93,481,447,883,175,399,929,405,969,956,811,276,633,330,188,835,438,144,870,245,830,105,265,343,131,522,578,662,867,10,757,398,752,861,866,788,571,497,507,660,342,794,858,288,784,322,500,743,798,604,626,452,872,663,535,277,421,374,901,778,724,394,197,212,332,678,496,700,846,619,261,922,592,586,100,724,716,361,257,791,303,744,729,511,249,610,359,634,535,676,491,155,504,850,508,448,891,971,249,155,81,306,537,308,591,344,216,697,448,956,582,822,830,239,823,287,958,741,981,273,690,112,110,882,668,339,570,532,51,970,375,555,814,640,531,286,138,34,242,776,894,178,174,30,271,124,137,642,480,105,846,63,888,365,563,808,976,160,409,416,986,269,716,433,726,444,627,12,549,868,716,665,673,505,329,469,677,775,24,919,589,843,946,400,889,739,246,982,908,69,912,498,529,1,277,841,190,638,891,187,338,646,951,675,126,766,135,908,914,461,621,370,430,780,983,646,655,551,639,887,438,57,321,488,543,408,553,338,548,876,498,923,736,556,187,331,143,301,190,582,580,840,744,729,16,413,360,140,538,851,332,245,355,713,939,784,837,233,602,500,547,2,801,627,496,453,521,973,990,907,336,2,522,889,560,48,896,28,899,546,358,879,415,241,345,984,212,364,558,843,727,684,962,615,369,494,151,552,961,455,951,84,875,480,878,137,168,457,864,698,554,621,938,823,748,758,887,737,628,523,994,815,3,185,709,571,114,714,942,888,76,243,321,290,824,178,558,389,689,802,926,839,777,302,784,666,519,158,805,275,942,361,177,640,476,434,313,315,759,58,451,710,493,137,549,769,124,137,857,217,698,104,698,14,627,687,557,202,526,348,229,461,25,340,989,643,345,757,909,452,490,451,508,468,953,879,986,178,0,501,570,791,120,644,646,281,842,489,621,670,320,759,150,752,929,456,740,727,158,546,38,32,460,196,981,297,745,297,233,183,163,302,221,695,799,511,757,438,989,627,931,827,280,264,459,152,56,155,502,803,243,660,511,398,458,658,719,954,183,90,110,49,98,275,856,649,587,468,275,376,739,559,726,549,460,430,992,958,80,987,28,54,366,455,96,822,38,720,652,583,502,507,773,555,134,561,614,894,815,866,286,484,526,479,54,66,693,490,305,877,169,83,463,147,673,832,902,498,448,610,2,554,593,179,720,653,46,21,514,84,648,992,587,730,346,987,702,688,883,687,344,393,182,260,495,414,180,816,678,808,669,534,250,484,717,580,617,475,262,826,875,872,464,52,45,433,797,759,853,486,580,395,567,833,367,402,13,471,852,775,224,141,334,827,605,771,446,758,52,613,430,877,172,31,742,532,685,150,929,751,107,621,156,698,200,325,445,807,338,820,559,216,769,403,925,780,89,178,663,274,300,999,507,614,561,583,324,572,308,621,439,843,871,970,245,449,943,432,970,885,178,207,277,47,172,178,923,494,663,625,509,344,59,530,732,588,512,832,525,559,988,387,838,757,99,93,331,794,515,27,622,306,32,556,946,539,107,805,876,910,201,820,782,967,840,750,722,595,606,116,947,85,481,970,454,336,553,540,200,519,144,152,722,193,528,548,434,853,99,199,698,284,997,732,900,506,712,699,629,297,600,4,487,369,813,961,586,101,90,307,482,375,308,803,306,739,682,665,189,638,855,772,719,305,183,988,443,35,202,104,463,530,600,933,425,213,724,204,990,55,734,670,920,986,506,259,196,29,914,371,192,603,56,819,309,270,404,573,954,3,893,966,724,42,286,471,879,945,99,706,693,233,849,102,961,911,113,365,468,446,952,391,781,947,157,318,477,324,250,163,43,57,843,347,214,327,592,62,469,594,895,9,988,650,99,788,948,964,376,110,48,129,796,621,825,670,611,747,274,29,748,932,683,701,301,156,986,946,34,37,403,993,493,740,552,562,21,156,216,938,846", "681,760,927,702,60,41,644,555,146,270,307,184,881,494,666,385,340,118,321,735,886,341,982,587,371,696,306,765,315,223,556,406,423,102,269,272,209,848,177,932,406,721,498,619,380,235,602,620,280,542,246,127,134,63,704,714,198,401,653,597,770,326,78,109,555,561,49,411,677,912,29,19,519,262,77,399,382,539,701,750,999,122,897,230,937,900,538,795,173,977,436,47,431,427,648,748,643,304,518,413,753,316,309,251,486,851,259,845,17,888,206,934,216,622,28,291,510,84,774,431,934,484,136,204,665,699,208,942,697,198,59,751,209,360,948,110,1000,752,962,630,735,568,398,177,741,427,177,979,734,227,715,352,272,676,479,807,881,650,810,110,625,432,340,355,211,45,9,336,737,34,651,813,83,625,811,206,878,433,742,212,788,225,217,89,968,992,839,980,731,948,163,294,847,617,311,882,461,817,469,100,753,945,130,540,531,705,666,624,875,695,573,647,673,368,248,896,405,734,15,498,742,890,997,536,319,115,598,430,321,740,21,859,970,544,53,157,237,780,237,80,770,70,995,781,966,714,288,378,853,602,106,568,287,315,999,190,748,991,704,909,765,96,238,336,703,29,704,172,142,922,930,973,645,567,617,371,560,609,116,530,63,660,950,27,147,342,50,628,816,724,192,197,941,64,146,371,406,816,199,368,494,421,56,169,122,921,270,589,843,560,12,406,898,30,158,945,116,444,119,732,202,806,551,447,736,570,787,91,956,23,661,823,295,391,3,907,135,910,626,326,513,890,55,465,726,577,148,675,641,320,916,955,218,114,370,605,131,149,528,877,792,293,410,447,806,890,656,613,850,429,459,918,421,364,670,446,219,64,266,440,766,964,583,277,719,734,846,618,815,591,200,155,215,737,126,746,815,935,199,805,652,47,848,16,541,460,418,283,879,136,538,390,15,137,282,681,535,728,95,444,446,725,608,721,714,710,200,529,792,428,38,993,614,22,931,376,318,202,25,59,732,286,161,222,781,420,994,68,515,17,954,248,454,354,78,773,849,308,168,450,316,939,20,904,24,282,273,403,328,689,522,614,735,772,514,514,961,270,41,879,632,106,335,686,570,963,683,935,382,863,31,339,440,339,438,103,972,654,871,415,16,189,161,547,5,625,288,370,430,910,57,164,813,476,929,795,657,109,359,570,562,91,888,321,44,887,36,86,384,415,576,660,14,32,702,332,535,501,0,706,432,563,906,977,161,183,264,250,15,582,91,451,221,108,179,463,501,18,227,47,364,658,220,843,954,658,614,276,87,306,614,857,70,960,353,491,763,49,254,667,777,279,644,243,517,437,794,837,363,894,595,314,26,775,633,830,154,593,406,62,617,405,40,192,756,902,563,965,126,211,535,197,901,542,557,580,402,938,248,230,545,119,230,35,542,527,989,910,444,431,635,663,760,859,870,979,887,412,742,342,514,366,969,822,117,557,453,360,818,811,548,532,222,698,438,617,183,4,876,956,347,917,795,831,720,399,794,789,182,117,86,719,583,767,870,545,441,81,882,551,461,107,983,570,526,872,360,101,592,786,882,411,144,367,380,724,530,555,453,41,49,688,195,834,657,230,889,908,719,414,489,670,112,190,629,924,370,370,614,297,238,463,412,164,864,59,808,456,482,504,809,978,414,152,769,189,286,1000,404,361,658,684,294,427,136,296,651,27,896,963,846,444,85,582,563,492,196,387,619,94,216,637,394,666,811,22,24,493,939,562,262,784,484,1,441,550,517,591,995,332,482,73,240,229,410,288,203,223,991,816,164,209,998,488,736,698,852,602,635,303,266,857,172,661,948,824,400,114,502,177,768,995,753,445,692,987,746,7,508,428,377,747,870,260,110,565,46,732,298,92,255,972,4,732,14,442,643,643,511,538,927,699,843,627,269,544,859,124,846,775,656,88,117,53,466,720,563,615,921,426,512,171,622,902,84,926,311,818,645,407,603,139,403,844,920,519,989,189,126,390,300,619,983,962,849,707,686,824,662,836,343,562,610,45,215,738,749,400,781,724,139,366,183,564,355,998,916,365,736,224,328,285,396,898,597,221,396,392,939,148,13,717,268,724,478,374,187,284,739,364,662,793,476,73,262,465,672,187,20,504,405,933,976,774,301,895,439,612,40,879,510,475,878,786,151,533,547,856,436,701,190,697,361,166,969,693,555,872,811,729,360,827,149,679,10,477,825,198,592,679,277,397,314,738,726,596,710,630,333,247,548,26,658,759,235,894,677,311,665,938", "35,197,98,720,70,858,818,611,935,641,695,896,894,408,315,207,503,985,884,694,274,385,437,835,578,178,101,88,932,351,191,931,756,398,471,836,346,81,334,764,467,908,21,313,383,168,829,545,185,646,652,331,529,164,160,593,479,987,94,409,65,118,781,137,327,321,847,69,149,54,404,451,140,960,691,954,881,305,851,29,144,24,201,679,77,985,883,676,388,320,568,191,515,706,186,722,916,752,453,420,449,568,744,885,550,821,882,135,340,582,234,870,242,276,939,176,136,841,931,165,696,984,429,443,107,99,45,463,310,134,116,294,815,99,674,409,741,922,85,686,652,439,462,359,650,959,215,736,833,992,619,585,883,94,103,618,515,438,736,70,468,298,519,369,446,567,874,368,875,710,962,925,467,998,721,588,67,406,367,449,378,40,168,214,902,473,155,255,390,589,205,183,149,62,472,393,118,546,931,897,178,820,581,887,253,184,910,487,978,989,428,650,882,812,430,384,50,721,555,273,457,926,877,694,359,42,162,798,964,513,857,465,426,972,597,987,55,269,522,313,89,41,921,902,902,433,131,192,661,376,365,224,838,712,520,920,30,100,178,885,69,715,939,528,672,307,102,628,280,942,799,962,747,672,312,821,748,553,810,110,684,870,952,390,334,273,449,214,998,75,707,452,111,123,280,724,757,651,31,831,196,438,735,390,373,993,778,575,329,897,665,299,437,372,160,312,883,715,987,210,387,17,494,71,881,839,129,518,601,70,129,679,449,56,702,58,31,902,785,965,709,500,304,997,444,965,31,505,556,534,721,739,801,767,102,344,386,840,98,901,158,453,118,995,170,917,932,815,876,172,846,202,60,816,935,761,876,626,446,353,787,658,418,824,444,733,333,495,397,896,261,991,759,387,738,948,917,732,757,646,854,973,906,220,594,297,756,815,265,181,786,444,641,698,979,53,36,734,587,478,58,208,129,310,937,904,56,530,188,752,627,421,806,367,440,648,622,298,8,208,710,873,308,13,624,352,357,830,124,464,231,18,675,458,61,835,419,913,191,462,498,941,563,178,277,953,398,376,667,657,620,291,40,231,340,862,966,529,195,584,908,920,129,582,274,62,860,994,180,273,424,754,185,927,602,395,352,884,560,579,863,748,279,176,249,784,634,340,834,532,367,898,539,153,650,305,792,47,99,935,956,854,957,268,965,272,625,14,448,861,18,346,553,225,29,592,19,570,706,0,250,244,479,991,860,492,526,435,590,619,447,912,389,278,190,456,914,137,99,322,267,928,43,464,682,705,95,437,163,681,451,626,914,738,378,497,499,311,422,40,829,510,168,466,302,766,573,945,596,548,23,361,212,325,15,62,34,229,200,875,779,978,579,325,764,312,15,383,49,67,375,94,212,45,98,84,193,449,441,493,432,678,801,205,875,809,80,111,862,99,663,256,160,155,18,974,179,927,796,550,147,246,96,628,396,74,708,230,948,963,846,254,501,258,441,427,857,372,465,349,678,97,629,153,497,747,746,434,53,160,756,229,215,943,581,625,983,687,155,958,132,345,63,394,427,221,916,256,742,979,387,542,483,341,129,745,128,915,188,222,375,469,110,51,140,525,667,405,569,889,622,896,844,255,344,422,306,382,808,859,884,152,59,557,816,762,75,901,889,419,456,769,372,922,210,183,225,391,187,675,214,876,408,795,223,219,959,882,990,992,984,6,345,192,717,62,951,158,363,463,516,385,106,613,792,762,703,227,575,507,858,690,392,411,383,222,227,172,915,714,314,694,419,834,682,19,89,815,947,416,183,534,445,428,456,248,483,567,240,525,131,224,190,123,616,139,965,647,419,30,229,809,264,281,255,466,305,220,926,693,920,948,200,954,261,776,114,779,432,926,661,783,626,172,257,796,922,963,885,57,63,44,877,174,453,167,169,568,284,710,8,3,719,413,400,738,587,860,818,905,194,275,476,266,70,829,777,409,109,971,443,862,189,143,456,883,666,548,805,675,809,985,920,332,155,294,823,818,677,466,465,625,442,126,567,582,14,913,515,579,384,311,278,222,908,471,630,695,299,85,302,36,657,372,281,864,29,56,922,491,301,137,800,899,719,451,89,240,164,773,710,143,82,634,659,540,744,311,203,683,768,186,682,72,914,251,132,115,906,881,616,695,139,197,394,7,822,521,723,242,180,44,224,288,34,232,638,433,180,267,677,507,969,871,872,235,204,423,497,691,633,736,475,895,115,542,859,562,18,726,669,838,365,447,647,600,571,560,499,200", "456,991,165,820,57,767,917,932,674,497,390,213,930,776,434,402,207,68,830,199,147,734,679,303,768,634,848,588,644,493,526,614,749,218,654,830,128,226,545,254,708,530,120,819,172,80,752,790,508,27,744,820,227,351,523,92,549,27,336,626,327,903,202,100,971,752,606,296,550,152,598,325,87,932,281,163,443,175,51,305,672,633,897,732,610,326,56,211,337,147,53,426,946,147,840,620,454,900,790,673,443,785,693,64,629,94,556,577,822,21,408,803,727,439,783,182,825,182,299,668,584,737,899,53,356,664,360,700,686,410,864,418,573,548,408,437,200,504,332,766,518,713,958,43,393,386,749,742,517,645,764,394,927,848,326,391,104,746,934,148,132,714,715,823,979,66,879,192,720,547,658,579,88,578,960,196,47,150,488,469,909,542,552,704,406,411,133,115,407,636,168,121,637,402,740,932,220,718,724,997,127,146,637,460,830,979,511,95,156,832,312,757,624,730,435,919,529,120,58,487,273,673,81,366,361,186,744,421,740,538,510,990,192,645,873,612,204,368,346,361,950,352,742,589,662,334,977,636,825,204,14,812,579,319,285,964,491,466,298,69,579,851,333,240,109,99,572,158,453,566,785,404,984,918,663,816,588,329,756,266,788,743,275,73,347,994,867,488,565,337,613,796,57,386,973,688,316,52,220,896,725,16,797,633,70,486,141,586,844,938,82,497,445,603,438,930,392,281,953,127,206,937,103,401,824,497,272,783,611,279,286,285,922,600,669,883,208,987,994,967,222,533,904,127,528,978,957,992,743,363,882,141,696,406,324,217,157,19,600,399,700,835,95,154,807,571,997,361,948,273,76,26,47,357,364,224,31,594,268,660,634,487,142,793,484,256,67,289,760,749,995,721,69,920,945,523,40,501,874,649,860,673,670,663,79,486,729,740,589,124,143,73,612,681,394,223,953,458,811,80,456,355,529,33,407,802,819,813,76,224,94,246,318,55,351,604,60,847,863,162,488,655,734,814,160,467,860,340,396,675,527,811,363,542,272,466,904,323,156,22,309,411,766,17,571,10,232,366,629,232,919,495,162,308,85,884,500,250,111,808,549,380,972,699,108,855,547,538,867,773,644,242,631,976,984,166,284,17,398,567,141,276,760,246,732,724,950,946,41,178,239,938,595,24,237,107,595,787,6,949,864,984,696,920,834,521,350,696,839,827,965,897,744,383,931,894,672,791,432,250,0,488,335,158,712,37,781,197,895,433,809,612,499,902,841,186,224,489,172,468,143,63,973,772,611,743,49,337,491,111,820,828,781,989,350,77,96,579,422,590,327,81,740,943,530,931,514,473,796,248,54,685,451,459,471,699,658,556,710,74,810,829,904,376,831,716,639,512,76,987,501,461,927,301,76,944,112,30,435,955,430,838,663,86,469,292,164,431,433,917,420,443,251,587,495,651,730,914,925,225,983,414,210,168,796,146,349,358,653,67,642,515,351,936,807,504,25,291,455,11,616,736,119,109,18,593,924,184,828,268,54,495,511,28,143,803,202,530,220,301,701,343,728,452,732,423,948,118,648,672,944,693,819,909,147,992,353,253,751,400,389,682,751,611,96,730,137,744,203,307,649,513,649,197,226,376,569,219,827,796,77,963,904,140,685,819,159,226,755,212,298,763,182,655,548,162,64,518,444,592,986,636,642,181,512,948,959,491,510,693,815,312,943,777,509,807,424,65,276,833,792,897,818,441,946,547,611,775,708,419,144,508,92,611,642,31,105,510,489,126,512,953,100,706,854,213,327,950,602,815,260,720,81,362,761,395,107,274,508,371,791,761,687,376,459,441,351,586,828,992,736,432,282,965,120,171,114,347,994,602,569,553,408,84,741,266,878,610,764,823,905,497,857,287,932,189,580,292,600,436,685,827,128,259,891,511,636,420,712,629,662,978,516,575,842,669,677,429,490,779,430,686,6,50,426,694,373,518,207,497,784,437,265,53,526,119,976,516,517,374,114,758,60,418,602,391,199,987,627,643,217,108,519,684,24,539,916,275,727,921,835,579,38,577,945,420,439,475,790,758,92,383,323,16,740,736,454,142,33,812,378,881,32,713,73,125,317,344,26,192,743,227,648,831,919,456,990,417,831,7,498,287,409,491,769,20,17,853,679,690,877,80,630,231,838,768,946,63,463,457,808,200,852,272,350,536,257,270,136,746,648,534,585,657,186,257,529,207,699,852,170,113,830,407,670,398,526,293,364,381,546,71,983,594,788,906,888,26,106,259", "795,995,409,766,62,632,306,505,536,654,385,558,890,625,966,862,705,42,556,604,656,306,185,288,436,12,978,720,726,762,215,884,38,323,658,479,234,19,982,918,947,438,148,231,171,848,235,138,193,691,343,114,773,855,246,327,809,40,331,789,704,358,818,429,498,452,201,494,955,940,967,27,764,627,859,51,199,618,856,51,931,153,209,989,976,2,31,410,701,372,787,127,290,932,864,940,961,881,63,864,718,803,606,501,587,823,264,819,544,749,753,273,46,639,797,316,354,675,127,973,56,776,394,115,833,487,742,945,746,690,138,417,799,49,843,762,884,941,335,173,39,404,118,781,237,380,5,40,176,425,862,535,532,506,644,742,573,733,766,229,43,237,428,815,987,439,487,615,960,704,332,949,324,965,551,388,125,737,222,374,952,448,474,377,553,294,164,492,851,165,473,756,561,730,130,386,577,168,200,531,356,263,73,884,311,548,578,872,963,143,196,205,190,341,634,508,744,795,569,748,127,720,592,103,976,907,946,984,496,445,109,867,638,73,392,989,573,326,256,797,466,176,148,619,840,956,90,280,515,173,828,955,896,950,385,972,632,129,217,613,566,911,830,905,100,314,841,304,678,340,231,762,452,347,706,84,403,320,54,781,302,61,325,476,748,554,107,123,49,67,426,729,636,954,158,410,279,712,933,97,962,859,981,889,181,796,937,426,706,355,506,497,635,218,585,237,540,174,743,464,879,220,13,18,393,889,257,188,637,880,600,766,713,216,158,296,730,433,938,470,199,678,305,811,449,935,960,405,428,730,718,292,266,862,646,581,619,658,678,133,360,389,159,602,907,618,904,59,150,457,746,42,204,935,226,933,911,281,85,100,223,896,800,685,947,158,656,285,943,16,517,348,415,480,642,27,68,706,553,102,512,383,442,629,429,961,302,248,399,85,634,717,107,99,707,833,152,864,623,173,759,347,494,733,547,310,283,929,6,294,313,186,506,903,691,342,403,703,350,84,166,287,707,252,836,907,704,250,260,955,246,905,551,68,763,987,862,987,510,117,991,671,816,957,648,674,274,965,26,57,873,442,826,737,652,136,19,550,856,244,949,73,509,194,587,397,455,829,191,525,825,459,862,76,923,978,599,112,557,635,108,61,134,172,205,989,497,363,495,678,963,853,709,892,999,828,972,787,609,209,270,291,644,691,126,540,10,363,335,667,900,764,586,157,78,705,827,120,563,244,488,0,208,312,161,360,128,782,129,806,777,423,819,445,123,954,881,627,419,771,941,913,177,215,177,690,484,651,563,451,824,580,664,381,534,774,979,974,54,215,774,824,477,258,73,123,93,447,998,492,794,196,206,139,693,69,720,83,49,246,147,145,118,369,818,755,333,247,773,769,144,539,104,283,654,655,787,707,285,655,685,335,237,534,172,878,565,322,988,434,852,577,463,306,32,25,616,251,479,394,322,595,723,160,55,133,302,416,165,975,806,530,270,49,374,459,958,747,520,854,720,529,716,378,909,884,500,778,262,250,653,601,562,375,345,935,985,337,212,366,597,475,847,673,757,878,293,262,635,449,653,644,144,394,316,211,622,909,212,178,18,98,6,826,444,332,306,786,686,960,440,89,410,15,576,389,349,307,930,316,848,290,778,219,7,512,490,197,561,417,572,32,484,933,151,945,979,22,153,318,306,100,857,793,52,682,917,264,276,19,493,999,482,685,464,88,654,127,737,977,664,374,145,131,522,2,587,96,418,298,127,766,120,26,189,111,556,672,307,384,723,5,235,942,614,718,425,187,721,339,58,588,927,103,584,654,731,146,574,567,277,736,606,884,984,243,546,364,681,976,543,795,98,366,507,773,997,425,77,542,42,117,541,47,735,602,744,629,652,882,461,511,844,724,212,941,830,565,386,826,848,727,588,707,267,682,354,634,970,116,191,494,83,743,396,955,746,904,566,411,615,352,624,618,710,616,729,559,589,904,753,917,902,61,359,656,15,395,531,90,629,571,523,493,267,942,624,182,328,701,560,317,678,940,265,37,258,698,431,79,424,377,959,90,469,620,774,628,634,611,778,887,644,826,334,319,513,597,604,150,568,786,96,46,453,184,813,494,582,140,754,417,521,394,19,221,454,725,395,341,57,157,633,830,392,952,299,273,29,638,823,222,338,80,821,857,614,797,299,861,387,338,277,84,890,284,218,756,940,414,592,93,562,537,977,893,581,849,629,225,245,816,865,150,742,29,419,147,139,264,679,79,833,500,986,705,512,458,524,282", "615,876,238,328,893,994,400,746,660,658,848,157,128,24,203,935,568,497,257,829,891,312,900,782,444,466,263,310,97,841,769,774,900,826,559,769,357,564,416,709,874,27,273,293,818,211,428,374,659,165,334,827,151,209,267,410,928,875,376,174,126,377,216,480,494,103,957,884,653,960,508,492,747,902,240,789,532,251,749,783,687,112,390,99,65,150,742,481,864,629,648,159,540,775,192,422,449,265,556,308,312,6,226,937,516,986,725,86,225,344,386,856,124,872,673,747,549,227,605,987,220,567,700,411,211,88,32,987,361,104,275,280,302,265,576,124,788,902,180,961,633,532,338,25,935,401,99,225,974,852,339,410,506,283,216,174,844,527,58,344,399,993,177,3,135,57,525,299,156,25,723,816,268,875,792,461,127,593,240,618,700,114,190,553,644,4,539,434,205,568,43,832,778,402,857,767,908,925,950,537,580,634,73,606,132,890,791,740,305,940,639,866,885,958,657,264,678,639,968,187,582,551,622,850,255,139,220,65,766,322,937,498,762,335,579,274,220,133,668,236,578,347,662,755,820,311,150,549,43,894,855,675,662,40,420,313,348,497,982,365,611,217,795,53,7,955,30,158,258,822,598,122,712,302,674,271,18,403,570,847,150,232,411,911,942,378,308,599,74,495,117,486,614,489,703,377,382,146,475,279,41,496,630,555,143,411,372,762,263,19,768,666,66,888,716,715,840,854,565,56,184,259,626,270,334,104,829,235,938,32,351,234,985,169,397,489,781,4,465,739,318,361,16,331,927,618,301,546,626,574,176,313,688,980,82,679,348,592,66,88,362,622,5,732,439,170,642,334,32,141,258,554,875,763,780,618,988,19,869,226,216,685,469,578,59,19,38,692,8,237,691,63,616,607,285,526,986,534,216,819,547,872,793,595,861,65,122,778,199,194,460,740,855,39,440,926,522,123,85,944,743,941,790,4,266,341,697,24,534,251,489,417,995,810,340,870,659,97,529,745,407,357,954,695,500,520,134,373,163,30,162,702,969,487,769,411,911,320,84,216,871,727,493,914,622,63,819,241,921,175,544,948,898,392,21,654,19,562,435,334,612,646,298,183,492,569,282,512,217,862,565,339,413,466,950,108,416,236,688,413,918,565,360,121,811,974,25,19,865,626,49,284,524,546,559,409,23,316,403,167,747,580,947,595,117,205,433,803,867,753,104,885,465,725,991,252,664,644,906,479,335,208,0,867,755,227,498,218,81,79,986,338,911,824,477,690,772,862,304,48,641,789,691,565,455,209,816,882,746,613,656,628,275,893,151,513,167,753,298,551,705,477,133,429,20,564,320,180,870,10,742,441,577,256,186,607,193,138,719,992,779,980,332,218,783,681,647,352,981,341,463,136,183,509,104,652,459,461,555,965,172,702,932,247,205,468,713,684,946,253,454,445,163,391,528,272,788,1000,655,288,119,389,462,889,561,924,933,217,402,529,793,155,582,9,603,190,928,797,614,381,323,695,150,296,250,712,468,233,35,557,899,602,485,36,346,546,627,528,259,525,567,75,129,720,843,755,486,850,389,797,126,214,712,56,711,674,946,914,479,161,534,970,910,598,582,128,727,914,705,678,976,618,65,619,694,523,529,708,994,646,171,686,77,657,836,870,19,504,358,832,465,664,99,998,850,936,905,389,35,637,327,113,883,684,764,490,454,47,662,607,598,819,394,500,34,875,985,92,962,197,592,932,9,95,417,85,907,187,739,298,907,273,817,485,577,604,866,564,590,645,42,931,395,444,306,67,287,40,652,731,325,304,861,631,595,572,511,345,864,120,104,753,450,904,448,524,426,309,297,231,188,18,898,979,654,954,893,85,893,917,88,356,517,78,934,632,966,186,34,708,122,129,662,751,100,909,435,625,696,29,278,257,651,445,913,30,648,965,695,538,133,272,89,790,184,259,627,82,548,463,403,526,862,682,808,619,675,515,585,346,134,674,726,548,872,692,420,224,111,585,275,770,841,540,186,388,136,196,590,846,718,876,633,282,431,942,848,801,258,157,395,633,314,874,803,611,82,384,553,351,259,104,606,984,161,425,573,343,942,120,263,84,840,337,985,591,20,519,727,695,461,749,124,594,691,110,94,476,257,500,221,355,973,446,836,178,790,542,731,824,314,209,228,758,957,872,722,250,873,965,437,320,885,614,321,309,101,750,119,500,745,266,898,170,886,218,83,878,450,884,70,608,259,84,924,282,398,221,414,267,427,684,26,675,277,460,558,626,70,839", "349,5,94,198,315,759,694,334,640,987,126,171,196,845,313,250,307,97,302,468,616,7,751,750,457,918,157,242,671,306,255,195,163,295,393,557,355,38,71,190,932,120,316,710,676,782,331,162,245,950,439,150,2,646,265,1000,537,177,517,124,552,44,148,928,948,269,502,983,812,683,43,996,522,126,395,726,903,645,822,523,106,861,483,10,88,712,999,850,868,639,427,205,919,34,29,69,960,782,667,366,948,307,694,89,963,519,407,158,908,94,870,349,767,5,702,765,624,375,748,796,568,22,677,771,956,273,500,628,98,641,159,779,323,221,363,432,541,331,372,437,946,945,156,646,530,884,881,80,97,640,757,377,797,380,663,307,638,790,596,782,987,906,719,748,240,470,67,127,820,327,631,882,79,831,253,690,748,372,388,554,90,565,646,53,400,611,522,96,186,121,267,529,153,313,213,227,905,71,588,529,547,794,646,80,446,389,274,523,724,117,443,152,559,936,629,799,808,674,843,425,51,128,405,315,715,640,772,339,931,897,241,109,21,528,857,965,223,971,790,677,249,232,718,1,779,674,566,638,705,20,254,823,221,312,355,313,845,185,438,137,67,395,919,326,917,718,458,903,610,166,415,855,376,881,493,590,260,956,127,786,859,81,672,912,231,143,990,26,29,313,787,55,618,652,127,714,96,369,239,651,95,98,85,801,3,336,53,79,53,342,119,938,764,750,376,815,43,971,463,846,714,549,993,713,957,162,760,159,391,868,359,232,319,759,542,408,730,534,927,30,492,687,405,996,844,904,809,702,773,251,889,380,29,120,448,633,258,836,378,340,161,50,809,10,574,212,923,285,699,204,493,767,866,830,925,522,108,367,405,87,892,970,42,772,455,244,161,792,110,305,1000,796,57,559,574,661,119,433,517,246,47,115,145,608,810,276,593,454,243,472,900,704,749,884,755,419,45,248,749,35,351,817,714,383,223,406,121,216,349,678,161,589,912,755,950,518,300,315,545,804,212,556,292,9,890,636,11,993,34,764,874,173,517,182,87,298,196,485,10,669,485,47,856,597,542,248,633,495,413,625,402,284,333,493,598,206,767,246,85,269,858,121,831,435,165,209,944,18,839,591,597,443,159,672,618,241,371,494,821,658,447,467,889,659,767,573,677,740,468,506,971,694,78,173,529,229,779,373,962,277,315,561,254,89,345,496,855,650,646,158,723,664,383,882,190,715,783,646,977,991,158,312,867,0,496,407,696,884,338,487,451,842,636,182,233,855,283,556,571,729,523,814,851,448,469,868,609,973,465,692,726,220,678,20,618,195,941,58,897,256,773,788,117,751,695,457,751,258,712,542,253,138,966,771,308,227,47,398,210,531,95,852,560,94,918,202,835,519,988,839,316,506,461,736,772,720,124,572,634,396,465,886,38,218,594,449,190,985,970,43,300,240,890,546,807,419,384,855,572,997,643,938,989,449,25,217,230,168,930,254,984,999,102,621,143,643,704,62,41,919,916,891,736,408,471,670,274,177,295,742,15,96,246,643,191,304,595,397,106,26,770,965,738,494,719,245,992,709,798,678,275,140,731,762,183,893,860,815,699,757,808,894,883,72,430,415,86,769,878,379,423,376,258,224,30,370,826,905,548,693,614,194,790,112,571,839,945,310,897,760,736,341,294,760,607,375,707,457,617,486,930,515,971,77,397,561,263,179,692,172,3,967,221,247,993,205,830,885,975,921,496,341,202,578,519,730,939,836,48,273,375,453,288,906,918,415,66,607,105,52,737,294,974,321,951,915,168,101,214,978,835,545,845,619,418,255,223,417,825,757,355,526,622,228,987,773,128,953,493,462,6,602,290,873,483,435,727,104,168,615,434,876,229,243,702,530,628,393,89,595,804,2,924,841,627,284,473,839,233,979,837,130,709,474,832,527,52,50,496,661,928,313,900,581,420,498,196,836,9,559,308,991,341,225,861,213,432,285,459,86,437,165,55,522,142,149,707,812,886,980,201,206,188,936,361,657,444,796,534,45,629,808,786,318,336,113,613,828,909,377,13,840,797,371,715,40,73,809,886,742,496,441,772,8,327,363,104,530,69,444,313,855,359,792,922,949,381,822,651,596,441,640,356,672,631,771,854,948,397,377,213,976,688,847,621,691,39,764,95,369,455,57,928,21,395,378,205,383,697,960,31,689,467,538,809,786,765,393,470,327,699,558,298,919,147,275,416,307,569,704,703,627,249,694,769,32,259,294,523,78,468,947,587,705,651,791,186,957,827,349", "597,342,442,794,76,462,43,864,843,812,265,583,55,930,835,621,922,430,546,174,664,966,96,964,592,606,693,896,381,925,421,94,268,341,600,331,24,9,822,241,630,603,427,47,578,282,660,47,212,802,649,832,352,480,345,112,672,717,46,390,470,105,421,545,320,836,976,45,394,603,680,494,395,551,28,894,514,753,525,705,700,702,606,738,287,822,600,538,544,607,897,329,195,418,45,47,88,431,414,389,377,248,60,553,113,694,725,329,745,325,222,528,481,264,342,639,966,266,638,500,868,525,982,996,472,241,474,324,139,533,325,336,528,557,967,781,204,361,801,418,113,754,217,61,801,814,771,807,491,525,127,562,2,542,722,215,379,134,376,333,360,328,123,466,58,949,474,115,980,537,605,42,278,871,397,678,800,894,438,561,889,846,270,159,842,718,827,583,988,526,403,85,372,288,595,378,105,208,436,699,855,418,106,488,524,734,568,402,807,583,283,592,57,158,511,999,560,676,868,242,113,399,265,110,229,374,367,620,332,791,297,990,446,834,439,833,595,835,120,904,876,942,880,331,506,726,165,69,592,133,335,511,211,486,111,474,540,629,971,547,262,925,468,981,183,149,935,334,354,7,296,297,51,466,582,984,937,94,701,370,256,241,571,72,764,881,392,409,621,983,11,359,261,606,905,309,419,58,362,300,262,469,147,673,439,610,106,120,494,500,668,168,400,534,77,725,884,150,348,211,49,196,626,160,873,942,349,128,660,330,628,377,191,147,792,925,996,407,886,847,20,624,289,977,946,231,256,732,885,490,398,58,734,59,64,950,386,45,817,459,513,233,26,949,54,525,253,170,473,83,134,315,145,964,388,382,942,729,308,407,47,1000,945,647,405,193,924,190,575,808,684,424,614,656,730,510,905,387,302,279,369,916,170,223,44,662,562,949,950,318,97,992,941,813,496,284,876,997,88,196,586,481,807,862,111,485,605,287,849,251,630,657,233,654,858,894,669,404,222,862,82,550,420,791,2,494,354,984,142,405,292,890,602,247,662,86,832,424,110,709,477,647,986,407,533,487,617,891,825,266,747,409,294,355,113,252,599,589,998,405,197,554,805,682,351,556,988,489,615,894,485,812,985,420,178,13,235,956,470,192,830,857,996,737,788,99,533,850,323,99,97,566,895,823,539,155,729,232,561,150,505,323,193,710,241,872,121,989,231,333,394,947,522,707,832,406,158,281,161,860,712,161,755,496,0,975,514,598,748,696,24,902,914,850,276,530,712,801,13,12,723,359,617,817,746,816,210,3,800,446,965,64,553,621,316,235,220,104,505,486,461,941,709,584,216,290,278,652,806,456,684,876,606,839,347,778,568,949,674,45,634,660,618,295,108,660,612,381,252,335,171,622,311,809,664,740,710,467,952,745,34,421,992,197,767,69,621,851,428,288,21,175,978,152,944,470,791,738,257,450,123,87,471,934,136,655,503,657,183,430,440,60,371,16,706,159,672,127,257,474,223,129,981,148,32,975,511,344,492,799,920,150,685,663,972,857,286,595,705,66,954,68,822,224,229,225,659,833,801,400,193,958,140,610,933,707,385,43,179,22,734,496,523,73,524,694,108,858,818,820,81,804,71,776,589,475,536,813,97,37,402,838,240,462,14,485,124,878,633,325,23,101,174,970,775,408,541,686,772,563,884,114,98,485,881,942,945,851,491,614,135,674,795,523,358,807,616,397,677,267,65,249,716,700,119,502,529,518,592,678,898,307,568,467,619,222,960,326,457,807,546,36,962,415,72,491,703,728,304,843,617,177,239,457,526,516,236,697,546,404,684,257,37,788,486,550,968,232,715,65,51,96,371,335,452,508,267,923,476,620,840,661,477,452,919,707,109,259,679,722,598,876,921,89,941,895,794,987,115,717,508,755,459,514,61,958,423,641,83,443,943,175,16,121,477,573,496,491,96,737,18,740,342,229,652,825,934,691,487,147,936,604,381,878,414,191,815,479,79,188,149,504,616,230,907,818,979,980,664,93,892,937,687,79,755,892,387,541,268,179,278,984,583,249,558,704,989,888,804,140,615,793,887,303,474,839,746,478,439,632,693,218,34,655,535,826,835,792,570,919,109,861,304,90,859,969,708,801,82,953,568,178,28,316,603,140,373,43,129,394,376,387,545,523,84,218,56,83,131,456,748,816,889,891,110,246,682,905,317,682,984,513,190,626,870,461,713,81,846,306,411,884,483,426,236,503,876,57,958,895,517,352,60,571,307,474,972,948,254,225", "198,379,877,41,635,559,679,711,880,875,341,437,870,893,948,260,537,780,736,289,267,73,460,881,427,280,829,607,431,16,337,854,741,980,558,832,451,726,673,827,81,397,725,311,207,716,512,23,723,675,950,559,801,256,674,417,795,99,983,808,887,165,229,858,239,1000,128,422,961,947,282,410,907,410,346,291,652,858,964,210,254,354,66,285,359,697,243,242,886,15,319,481,929,12,168,258,700,463,193,171,172,474,699,591,900,919,314,691,80,813,494,81,972,17,415,689,901,947,165,731,283,237,840,340,635,692,932,7,85,354,705,330,985,199,392,738,706,800,921,58,416,112,676,899,755,513,322,922,956,112,836,13,758,752,11,770,338,583,749,300,171,308,657,474,945,525,340,931,80,653,10,831,764,139,911,994,476,689,978,907,943,997,990,573,19,791,380,399,8,67,265,781,511,597,91,634,193,8,465,948,593,345,925,178,952,279,661,745,595,151,446,570,901,307,313,430,426,319,330,277,766,867,682,770,529,475,44,597,858,335,551,736,785,620,577,507,677,693,976,519,189,587,311,223,119,630,584,724,335,789,752,69,718,740,12,568,697,996,32,685,889,933,795,423,818,195,182,800,224,128,388,813,740,924,295,283,35,298,623,829,944,791,284,65,312,237,554,162,859,994,988,567,991,664,769,483,898,981,498,871,725,658,928,48,683,946,533,724,425,824,242,364,647,740,280,688,820,385,676,615,295,449,685,668,453,197,190,160,427,33,357,671,396,159,293,388,438,100,515,492,269,741,611,441,573,514,543,820,560,646,781,123,586,549,279,657,303,889,499,417,160,253,398,317,94,452,482,819,400,234,967,223,532,350,996,6,494,364,547,863,166,163,197,953,309,812,407,900,752,691,439,182,182,545,352,227,262,489,15,205,381,73,127,725,591,520,894,647,990,664,606,616,518,680,777,338,967,899,373,86,385,732,238,279,210,987,241,254,495,474,702,215,792,359,442,956,813,904,933,717,294,765,792,946,323,385,714,959,855,278,507,319,959,940,510,776,249,875,781,376,820,599,225,176,950,269,423,675,512,235,655,477,432,846,427,632,686,991,761,835,17,594,550,950,35,778,426,258,856,12,147,446,348,693,948,724,281,968,617,50,922,893,449,548,313,487,465,645,200,751,749,460,879,371,660,232,539,323,303,856,75,680,300,377,954,596,685,298,139,263,660,774,582,633,402,936,89,842,183,492,37,360,227,407,975,0,695,382,813,605,692,431,424,760,13,754,906,806,272,929,184,32,76,819,737,4,442,292,14,641,298,599,130,250,171,750,577,645,812,422,866,549,300,401,407,413,770,234,822,647,884,735,171,35,329,832,405,64,130,989,880,984,622,137,182,916,759,200,153,800,762,516,181,729,58,246,611,868,176,297,415,5,142,226,940,273,593,111,747,290,880,889,354,471,618,429,422,22,837,592,765,282,549,858,839,308,730,495,414,751,345,678,633,524,925,297,600,553,154,931,237,192,966,208,765,517,402,569,999,246,737,646,689,610,588,243,15,819,442,209,565,721,748,126,874,122,24,855,495,235,829,917,848,700,396,509,639,798,740,750,212,546,811,364,164,825,509,1000,696,36,889,167,318,113,824,676,245,659,942,966,530,869,651,867,227,115,763,392,468,675,971,408,810,438,419,715,974,698,485,427,340,106,40,645,973,168,69,964,433,27,720,538,443,18,35,21,641,567,218,454,749,79,204,586,109,317,377,975,371,899,49,728,896,565,457,599,537,190,562,882,973,792,168,64,407,977,706,933,979,289,323,859,698,706,485,780,5,400,870,761,470,570,955,728,400,561,656,189,289,614,223,416,207,899,591,724,636,438,836,883,496,808,912,753,239,403,31,431,744,810,650,265,740,462,358,911,843,162,396,372,430,146,788,37,856,26,708,509,879,768,548,252,426,896,28,778,162,606,343,440,242,530,969,77,495,611,826,530,461,384,420,221,525,708,91,298,221,564,514,480,586,5,252,988,147,929,98,259,189,95,769,84,863,285,830,468,837,354,347,72,448,124,321,975,106,145,135,578,739,898,952,68,430,442,681,192,436,239,735,360,458,36,675,900,888,497,802,70,81,934,920,180,892,272,790,199,523,295,437,137,429,24,586,951,418,724,807,981,713,861,240,268,977,229,763,343,601,903,257,399,682,633,390,35,426,744,321,428,441,536,394,151,222,117,38,84,375,606,526,507,275,326,295,592,905,587,985,473,686,54,882,361,221,645,14,372,644,594,159,397", "643,132,445,970,477,678,826,840,180,528,492,629,167,992,182,655,349,207,619,854,653,245,185,654,446,887,505,367,354,753,521,607,795,541,466,256,908,881,450,818,126,528,830,453,447,656,841,787,397,390,920,149,676,55,584,816,265,541,699,373,304,24,29,369,745,644,463,586,523,1,521,425,783,260,556,89,287,933,854,81,603,183,445,91,53,968,888,407,272,75,506,181,966,963,383,400,992,661,533,200,155,272,117,87,73,776,850,451,739,689,308,48,545,984,257,412,253,261,124,485,739,102,156,423,132,798,354,202,527,46,594,567,453,105,750,274,988,132,774,726,775,279,948,259,141,318,4,38,9,35,546,212,786,510,307,700,558,387,83,500,753,502,512,422,575,768,954,733,244,635,896,720,295,352,67,753,65,735,877,530,617,329,883,945,274,668,43,814,576,640,779,882,338,254,786,555,678,284,545,601,837,603,926,662,330,115,572,388,359,220,678,611,758,19,880,134,439,816,162,27,723,227,366,782,961,639,253,695,151,568,866,607,568,439,885,244,576,243,716,828,396,120,700,908,484,275,196,890,519,704,535,621,730,18,770,630,209,321,271,725,77,585,203,379,620,736,896,880,469,904,693,851,14,7,341,254,550,714,264,213,263,278,6,796,517,630,863,802,240,869,746,378,628,968,500,401,840,221,452,780,364,940,247,316,254,832,634,276,731,418,283,668,574,337,991,943,980,834,184,174,560,491,931,727,647,431,362,935,936,668,483,502,248,584,400,63,143,548,234,142,753,763,626,261,915,244,244,584,778,985,776,627,32,541,404,124,498,361,994,112,841,52,744,721,277,377,831,569,56,558,346,459,340,631,801,259,183,809,970,257,200,536,581,45,830,754,535,892,338,38,222,424,358,436,92,66,623,688,247,754,606,564,292,201,114,214,734,303,62,243,608,981,176,824,139,154,207,509,952,94,995,211,929,23,710,272,205,672,609,200,691,491,585,659,929,939,561,810,791,863,699,254,523,511,921,745,103,711,995,219,51,205,543,559,866,945,650,985,539,628,651,416,98,515,624,478,164,300,127,178,406,159,612,5,208,961,772,836,15,411,458,717,809,178,5,619,820,702,102,435,927,452,773,231,724,183,856,927,511,599,513,395,703,996,909,787,231,251,113,645,255,412,915,265,502,693,210,463,438,986,302,106,285,635,873,915,703,826,863,34,942,498,532,858,398,735,178,489,264,526,781,128,498,696,514,695,0,817,988,167,668,142,765,156,259,529,518,239,503,541,755,546,256,685,965,523,850,93,632,391,882,760,812,606,5,24,177,826,179,100,270,728,938,157,835,172,91,76,475,53,452,292,194,627,919,509,553,426,640,380,738,523,383,987,179,673,645,852,312,137,689,365,827,448,12,362,454,971,568,268,220,35,999,539,361,392,414,355,293,238,569,726,689,58,594,487,572,152,779,727,604,265,663,249,250,829,493,264,854,426,256,774,920,20,796,244,885,710,245,809,564,100,597,811,488,949,4,107,44,473,547,618,192,665,844,638,6,4,27,626,917,743,668,458,674,321,181,953,870,249,97,991,549,324,899,900,969,86,894,77,66,201,608,955,108,418,373,554,86,954,747,157,751,932,901,444,835,724,687,759,572,514,722,146,496,945,237,485,687,693,162,567,676,683,257,980,429,766,27,276,526,999,401,24,686,124,470,717,747,625,984,403,955,95,434,114,136,385,542,644,59,385,717,366,215,167,482,674,903,909,874,851,303,425,223,92,134,438,814,559,544,736,323,656,147,114,215,139,494,591,834,63,894,917,114,930,775,29,942,56,612,741,843,256,756,266,549,142,339,350,346,818,566,115,708,970,375,590,429,132,368,734,831,276,207,447,986,453,101,705,334,147,929,470,395,326,554,326,687,537,485,507,169,904,951,892,499,455,47,514,393,739,989,198,897,443,602,951,926,506,327,343,420,835,545,151,912,988,906,52,648,950,287,45,940,444,844,52,959,727,402,89,825,426,447,375,179,27,707,801,144,952,15,410,676,876,877,544,944,544,449,848,356,332,178,730,73,923,849,268,469,428,7,917,771,454,959,195,616,922,93,709,442,772,841,122,777,582,803,427,565,676,351,526,61,300,696,94,466,191,461,594,632,507,619,954,743,165,442,328,434,157,87,249,129,267,175,367,144,71,913,95,221,586,925,760,564,57,19,725,985,878,646,848,677,224,544,875,373,686,317,180,494,478,421,906,412,375,45,41,157,984,892,45,966,572,481,356,364,940", "18,231,266,978,538,625,866,680,466,948,686,184,669,331,395,196,556,142,894,691,628,607,84,379,462,148,492,894,17,271,368,840,236,378,825,255,182,152,618,366,217,615,937,678,469,956,376,999,735,680,962,47,236,283,51,688,194,739,93,177,505,779,926,707,278,307,223,418,478,872,224,398,727,280,586,111,263,697,123,238,752,119,348,671,777,448,206,950,629,901,728,130,921,97,103,732,366,1,143,214,139,942,229,247,638,656,804,441,258,398,850,531,15,840,786,482,699,471,750,90,154,210,769,216,579,416,20,63,655,614,698,499,997,131,348,409,567,409,803,865,609,492,154,522,593,380,859,982,669,107,329,669,210,937,533,491,856,302,341,179,659,855,78,313,548,893,793,860,100,12,66,994,68,499,992,940,547,459,352,24,145,76,754,123,77,315,712,114,314,871,859,233,374,780,651,969,19,345,163,604,921,529,795,762,796,672,870,189,250,445,258,968,760,689,365,393,767,111,679,173,117,548,495,269,11,840,666,441,632,816,17,617,554,632,54,512,27,34,511,484,93,230,605,671,731,338,22,892,651,169,440,363,2,111,47,341,280,884,56,182,859,274,722,893,137,304,588,640,231,123,138,213,847,655,996,683,690,468,616,317,299,263,399,903,123,32,866,966,823,594,889,603,747,846,467,242,304,412,475,557,779,226,857,54,40,690,272,997,938,789,854,958,910,840,365,676,137,263,33,628,975,12,606,883,356,896,468,603,387,936,873,78,628,31,779,251,767,120,214,237,333,384,313,816,654,716,359,794,503,588,425,639,351,696,148,812,309,953,529,555,849,953,98,970,729,552,237,135,651,429,240,685,616,328,260,763,593,51,180,719,728,53,848,25,347,757,955,728,902,316,70,509,382,760,311,351,485,874,641,572,770,847,558,149,233,555,60,442,298,136,551,217,391,269,516,390,118,307,175,906,431,618,248,803,815,877,15,554,894,318,101,348,530,947,648,43,443,649,844,539,873,483,908,758,185,613,414,509,406,517,277,960,579,513,795,915,33,155,40,419,835,524,474,494,195,822,839,141,800,468,595,26,751,230,214,732,217,400,915,521,792,149,421,759,506,364,736,915,970,675,293,51,236,993,73,902,1,285,564,414,903,919,745,167,20,617,44,714,899,991,823,393,264,715,218,710,542,916,254,720,691,929,740,714,422,288,389,139,926,41,634,708,653,153,647,120,914,621,250,435,197,782,218,884,598,382,817,0,140,963,850,444,325,560,361,950,301,433,117,784,381,114,674,925,573,115,85,772,335,651,198,424,289,628,164,575,269,240,483,702,381,863,323,177,315,862,674,745,369,630,320,830,614,861,197,477,662,541,901,254,292,755,656,931,192,13,611,451,700,379,278,934,845,69,56,266,403,907,281,898,942,25,316,686,591,271,154,720,914,589,932,951,150,602,189,24,34,979,324,115,109,609,489,232,887,537,986,824,682,409,221,102,728,982,307,916,555,532,634,344,387,571,394,862,869,222,190,724,998,647,973,389,371,929,532,506,302,467,159,129,758,558,856,676,56,64,282,652,592,577,130,339,693,945,886,21,493,463,471,714,372,314,220,25,713,460,246,393,673,109,940,76,770,603,742,776,3,179,273,861,269,625,566,213,896,901,12,946,998,233,374,427,232,248,595,373,875,553,803,217,85,950,320,245,680,112,828,953,872,567,743,127,562,966,540,255,926,360,541,684,116,432,120,109,465,490,257,78,573,63,444,509,165,799,994,794,613,379,790,136,37,483,245,327,475,659,491,595,588,987,435,550,608,208,68,28,782,660,598,904,479,645,886,77,910,200,817,78,958,637,144,479,693,365,206,26,775,832,759,948,252,7,469,913,923,250,195,82,213,119,515,327,382,95,696,162,485,753,458,890,48,925,240,410,671,825,668,716,389,645,433,194,200,236,22,973,154,570,289,90,357,694,244,196,799,111,964,400,897,263,183,688,518,289,545,400,188,420,390,796,946,776,123,181,887,800,747,422,948,526,749,355,645,889,791,38,92,499,849,64,614,354,500,936,329,567,825,721,350,779,54,51,312,108,403,388,977,857,158,353,543,794,628,845,646,152,556,607,137,966,928,711,616,877,526,920,118,413,306,433,669,244,720,115,867,771,217,864,480,951,320,668,277,386,107,861,998,463,439,287,929,149,301,83,79,414,468,895,420,37,779,736,729,891,417,910,198,861,547,459,635,532,45,590,143,824,86,629,917,165,228,433,140,304,693,770,651,954,960,177", "955,783,706,175,938,692,837,945,994,782,760,445,509,267,213,941,739,574,229,903,209,959,916,187,991,189,301,887,278,323,526,22,772,905,413,228,508,201,462,170,764,848,127,459,787,360,789,458,475,827,800,322,421,737,274,379,880,691,290,158,885,660,22,526,103,625,797,205,802,48,47,366,858,923,790,168,500,391,100,384,578,697,145,39,796,188,738,944,683,35,826,354,143,277,772,644,744,148,942,441,810,322,648,821,303,604,801,79,381,942,297,492,678,566,580,365,819,614,84,159,430,370,216,806,934,604,924,457,212,81,364,880,104,422,801,309,78,192,382,429,942,794,55,526,614,671,606,523,313,970,351,948,46,6,21,481,54,721,216,172,971,633,103,964,945,246,138,347,726,708,826,319,20,373,55,890,388,621,134,80,773,555,131,159,539,578,769,74,520,723,114,538,321,810,431,298,415,709,184,804,328,884,958,461,61,672,209,720,150,863,197,750,131,960,449,523,904,350,611,942,673,190,270,338,495,548,761,672,583,306,350,168,359,213,341,489,449,663,891,66,98,256,226,823,349,312,183,115,413,143,435,174,20,902,617,581,50,983,300,7,816,271,43,791,247,857,153,460,834,404,589,326,99,434,657,558,248,427,23,632,778,210,936,788,925,801,855,892,558,751,962,649,637,666,609,655,883,641,707,992,951,368,870,169,226,750,832,302,281,625,618,230,665,370,986,234,363,461,401,172,186,387,63,878,157,951,47,739,246,358,569,832,509,387,400,792,105,900,300,37,966,697,600,79,262,125,540,734,914,945,499,648,343,247,447,531,855,409,852,345,850,832,250,168,261,848,517,815,560,53,17,938,885,478,548,817,141,262,477,36,997,438,137,113,909,515,185,693,547,210,247,745,133,11,379,365,186,961,288,627,553,528,403,120,899,737,583,736,1000,42,909,240,4,766,859,847,313,829,631,712,730,326,222,827,942,50,126,706,565,773,628,715,205,399,806,335,848,952,563,284,808,614,85,31,7,561,915,616,786,168,228,425,14,487,540,563,208,294,340,25,130,525,442,425,638,693,774,87,79,799,263,227,476,582,424,65,943,668,545,660,739,585,135,217,337,637,320,935,931,117,551,468,590,246,358,135,783,960,164,599,973,675,636,16,37,427,676,68,545,432,367,317,174,99,693,618,703,998,193,788,92,246,277,686,93,967,741,996,98,540,606,765,744,219,64,674,934,670,15,590,895,129,81,338,748,813,988,140,0,600,305,793,940,783,502,283,390,581,584,689,342,872,714,584,692,378,983,247,284,803,895,512,653,807,505,331,926,550,155,716,849,9,533,456,505,862,157,630,919,337,707,306,222,344,67,99,553,212,289,779,16,86,229,664,522,129,207,367,191,502,528,959,867,618,361,195,81,678,155,454,110,379,941,545,652,712,311,268,246,346,661,724,849,512,331,662,495,880,921,494,153,357,533,585,970,641,684,958,367,962,672,225,796,79,365,924,64,557,477,988,695,774,654,116,379,357,379,812,492,342,714,943,600,92,997,339,724,775,415,91,392,586,326,663,832,836,244,320,626,767,92,139,994,766,94,825,510,217,985,613,786,381,732,758,260,485,458,235,302,881,296,625,335,770,917,596,206,994,479,783,660,13,363,60,69,37,305,96,550,535,710,11,460,810,804,964,84,69,563,704,225,230,905,749,709,608,816,433,49,7,106,49,764,417,926,651,284,396,822,892,586,619,276,278,637,27,139,852,465,819,872,692,95,548,685,68,628,365,187,494,455,560,423,222,714,308,470,651,965,406,169,802,397,398,88,658,971,194,736,571,293,381,390,588,54,997,62,479,708,541,806,784,164,348,370,570,170,194,572,79,526,854,683,180,787,719,896,327,368,41,179,849,512,362,670,585,738,145,344,192,785,70,632,514,69,488,90,925,612,208,731,21,990,657,78,117,85,520,754,59,576,809,60,340,961,23,45,129,55,50,294,495,668,190,473,975,489,904,171,908,349,717,837,424,208,392,485,535,546,911,966,402,266,686,801,621,800,188,332,843,720,949,580,770,993,974,584,762,793,883,717,403,549,629,328,15,963,817,960,25,64,813,60,752,330,340,388,896,947,934,930,867,463,966,886,457,965,506,713,212,228,489,725,525,604,686,26,160,192,14,703,376,629,756,416,835,735,761,713,215,285,34,914,348,206,448,91,643,301,894,129,636,204,760,587,617,470,244,710,405,982,860,383,395,365,933,350,312,621,489,479,698,912,897,912,846,750,591,565,212", "531,59,312,847,757,897,311,8,894,713,525,787,715,642,237,112,366,680,388,562,656,143,529,646,666,416,633,569,940,13,496,834,489,532,150,668,877,219,399,847,44,576,241,935,326,886,999,561,558,631,985,272,904,978,91,155,51,513,52,979,850,609,633,809,509,403,203,718,323,686,805,544,663,21,216,200,922,169,830,233,989,944,975,279,987,970,150,938,288,861,242,815,181,905,639,483,248,991,825,314,87,134,538,260,802,447,518,270,711,655,88,86,124,124,716,496,32,928,824,210,343,521,216,29,944,518,167,173,160,756,385,293,345,564,822,608,634,860,834,236,964,786,149,804,20,776,624,780,632,654,389,33,343,14,857,763,385,135,607,948,667,259,934,628,616,121,956,209,286,577,410,325,14,671,771,928,663,315,267,273,370,418,246,10,104,950,634,881,273,183,466,91,387,211,228,65,777,931,690,242,769,605,277,820,723,281,170,52,638,222,409,572,741,767,784,539,442,803,548,881,877,796,941,860,409,45,858,525,885,931,759,409,399,341,788,341,937,537,7,957,826,808,648,635,728,164,867,498,90,910,849,861,366,60,39,919,817,64,807,963,939,446,652,921,960,544,965,815,70,704,7,693,904,60,327,670,467,858,447,580,258,908,706,171,339,840,536,527,600,730,909,281,500,963,232,678,599,91,730,665,209,58,2,261,525,68,326,886,631,473,148,557,426,225,569,486,17,615,394,348,212,965,472,228,220,242,940,230,393,65,446,825,313,115,925,487,948,28,257,314,401,362,133,704,823,192,788,517,194,885,226,292,671,437,15,123,259,11,461,372,977,539,275,833,680,907,874,197,528,8,151,288,885,409,988,867,411,918,572,598,187,376,366,3,259,78,154,177,346,912,388,190,605,370,534,304,526,776,787,551,991,92,646,22,686,929,165,781,412,850,624,160,740,624,358,794,994,82,857,312,200,663,84,712,746,78,897,319,826,793,182,290,877,678,503,116,670,992,404,658,904,950,933,648,599,897,661,625,688,492,773,559,993,284,290,909,181,249,240,11,223,846,221,890,919,560,344,639,849,447,484,743,103,400,807,159,65,483,518,965,346,361,613,94,839,219,635,322,798,396,660,937,34,214,584,455,355,432,998,213,919,861,362,896,776,357,511,57,286,414,602,8,314,251,148,634,834,275,513,244,760,312,7,965,859,631,183,285,304,60,927,437,184,408,289,106,664,320,582,619,433,806,79,487,696,605,167,963,600,0,594,970,990,664,76,43,309,3,208,818,900,978,896,887,556,701,261,880,362,110,76,558,360,915,739,525,580,961,732,604,648,834,123,690,689,575,162,969,412,131,198,988,867,493,586,171,588,308,782,633,122,515,857,878,56,462,716,321,285,139,529,405,768,99,972,265,367,9,714,564,527,343,456,206,181,469,574,587,171,272,102,249,660,427,170,706,468,191,872,161,345,245,259,807,758,94,414,644,875,316,961,670,428,540,807,536,646,779,357,538,630,755,81,291,315,935,280,250,133,422,989,127,311,223,487,677,514,108,630,34,994,654,142,116,612,575,152,698,398,604,771,430,935,491,29,690,178,829,300,669,829,328,797,460,67,496,238,912,826,180,895,261,29,250,606,499,8,332,642,875,717,882,787,959,364,437,241,380,693,803,335,106,916,729,741,114,66,105,355,439,752,703,146,531,142,385,431,983,542,965,623,911,467,286,735,275,681,779,345,398,125,989,603,742,179,960,190,76,71,837,244,500,239,866,260,373,191,122,431,257,246,956,461,410,6,823,514,106,797,194,641,139,808,240,483,27,820,973,752,910,29,603,550,431,883,656,203,883,932,239,559,63,656,799,542,682,6,942,1000,183,622,631,36,344,642,936,240,164,326,963,502,306,124,269,559,34,460,825,624,688,563,590,436,260,433,860,23,682,26,191,764,485,136,810,548,242,636,289,267,814,720,591,902,458,434,832,916,378,423,246,317,220,840,160,350,92,301,154,786,355,834,181,985,614,915,657,945,986,416,177,51,509,379,553,876,413,882,224,856,245,834,571,164,659,119,498,7,276,725,85,402,498,814,693,679,171,193,246,271,159,449,20,887,74,895,89,218,401,467,484,777,898,393,997,829,52,873,995,292,503,801,947,282,438,189,742,623,634,913,79,317,979,120,17,86,13,108,380,913,772,887,24,5,952,438,967,994,896,257,896,482,801,100,623,572,774,458,6,586,654,574,231,437,167,104,875,285,764,567,206,47,166,662,851,38,284,977,268,839,571", "431,459,712,324,911,51,263,478,12,878,118,697,482,104,773,815,199,518,105,116,910,335,346,792,920,142,362,440,498,435,81,396,536,535,355,871,430,187,944,20,965,752,966,191,649,94,979,675,742,981,885,606,128,935,112,774,146,887,127,631,250,691,801,700,945,747,785,546,571,362,108,997,399,814,714,22,238,34,965,609,64,631,672,611,987,594,109,539,787,813,131,298,118,435,359,92,765,336,595,218,439,914,260,29,148,806,826,884,206,100,80,413,339,955,5,117,912,584,492,478,337,169,725,76,689,865,813,563,609,254,142,384,274,290,481,782,351,481,46,130,359,320,298,589,503,754,29,833,923,429,231,85,137,46,969,482,398,351,495,492,760,606,767,965,525,53,204,874,634,978,177,797,396,301,922,300,184,243,116,200,714,561,458,929,430,896,242,818,641,837,793,229,225,665,692,54,81,627,488,526,925,478,977,676,214,587,265,801,510,11,870,217,305,317,221,528,647,527,170,46,382,331,881,246,164,984,915,785,784,69,973,512,929,941,53,568,72,578,28,718,98,929,795,445,575,59,94,819,161,448,547,783,570,508,259,243,741,675,106,339,684,278,72,999,209,25,124,13,551,965,284,297,340,314,697,969,879,339,191,381,800,919,67,52,373,528,839,903,235,823,865,665,716,530,785,629,67,839,250,27,416,183,733,688,856,43,628,918,291,430,488,101,73,701,101,786,813,864,856,820,970,504,589,881,112,630,341,526,824,738,304,861,890,547,835,133,350,832,130,747,574,474,938,402,19,679,767,61,794,913,646,203,778,190,859,899,545,766,999,411,130,655,835,328,534,345,330,578,873,101,459,273,77,533,123,673,125,628,722,678,800,587,656,533,994,713,408,355,808,522,205,425,253,66,142,276,114,221,308,384,444,195,601,711,15,611,948,563,228,842,238,106,291,270,161,346,62,181,805,390,622,604,690,824,15,254,269,424,420,291,903,93,110,504,781,726,588,821,471,540,953,382,630,534,843,651,409,749,983,394,384,354,632,36,507,407,353,145,905,433,969,498,613,305,679,456,81,246,717,268,816,263,354,183,152,288,249,860,997,676,419,609,156,667,662,180,115,135,961,528,911,151,882,465,283,689,728,920,59,237,430,664,571,404,148,477,337,614,410,159,513,290,361,758,144,240,207,923,340,466,721,212,229,928,712,808,817,253,822,681,668,158,183,707,47,231,80,759,91,447,809,777,986,451,24,692,668,850,305,594,0,415,246,758,266,733,806,556,794,581,55,114,982,808,470,479,528,64,28,432,959,771,246,982,6,706,32,479,878,769,851,669,502,446,157,353,342,705,425,678,572,512,111,925,604,16,655,294,551,130,31,533,527,209,79,310,149,170,817,558,964,353,114,177,691,228,787,480,85,352,679,73,804,358,3,937,321,146,715,617,410,463,604,926,89,855,580,235,163,534,923,631,430,739,685,682,925,494,436,776,561,692,393,964,191,565,919,555,735,990,695,330,151,432,952,625,531,718,621,942,445,597,288,142,161,660,367,761,71,13,378,821,839,616,126,419,737,297,957,791,180,860,364,546,895,251,285,897,98,428,581,542,142,430,127,670,232,864,772,906,143,975,823,860,101,560,870,734,525,179,418,73,585,385,515,434,997,796,618,24,17,216,387,427,136,835,542,749,647,689,979,777,454,739,52,338,245,727,531,699,631,23,99,522,587,501,854,224,367,986,820,554,245,846,89,862,749,877,882,176,16,142,495,235,873,409,472,46,988,192,468,26,603,982,57,250,461,759,851,852,171,525,784,224,36,782,599,967,551,777,214,974,456,780,783,734,297,178,386,442,896,742,269,33,796,208,625,61,405,542,941,456,771,616,662,735,734,324,592,345,937,148,101,463,251,358,957,366,221,872,536,338,20,676,162,379,616,986,329,947,838,376,375,7,688,715,155,331,309,938,330,944,407,506,986,354,237,482,693,766,70,650,413,729,301,707,45,837,300,202,350,441,637,981,516,374,399,715,473,768,630,258,327,295,925,972,403,911,810,960,593,644,154,427,672,332,275,845,360,533,704,723,519,189,770,571,144,8,745,96,825,204,28,486,798,827,399,235,487,873,985,875,229,162,433,699,175,886,742,507,813,93,307,57,724,610,695,380,601,569,119,612,511,197,162,14,886,80,467,168,985,296,944,743,502,66,544,411,530,273,616,807,319,804,965,494,973,726,839,871,669,879,295,722,570,865,225,473,760,5,912,400,49,713,811,563,897,92,450,600", "49,932,321,706,414,425,568,40,388,184,32,248,891,444,29,79,642,382,594,241,701,436,645,66,509,418,810,333,460,622,747,917,216,877,575,417,195,337,884,26,138,353,96,230,348,469,452,454,432,301,189,921,930,979,894,552,136,771,872,530,400,635,942,968,773,434,446,591,579,157,533,578,741,605,255,985,632,18,489,722,276,248,164,414,292,927,687,365,863,718,246,174,427,337,981,999,7,522,618,626,527,204,519,308,945,488,788,963,11,27,673,563,464,94,258,406,658,88,830,840,964,504,389,565,972,193,109,939,227,208,799,456,134,527,934,695,200,750,85,187,604,477,755,800,271,552,948,95,37,649,148,131,967,283,619,136,177,966,492,436,725,799,356,720,448,152,55,220,224,494,791,713,260,973,450,311,275,313,164,382,3,916,368,190,327,635,267,930,285,162,294,14,528,163,711,849,15,195,100,666,323,763,235,875,41,444,978,813,732,815,349,533,410,553,780,405,478,896,639,816,525,767,934,496,830,59,770,390,871,463,131,999,319,473,357,762,680,590,417,612,135,310,775,44,528,576,205,861,979,59,210,183,1,50,313,315,94,833,214,501,258,52,816,258,22,559,254,829,771,355,570,369,281,513,168,320,496,795,158,875,254,1000,943,198,830,817,511,428,515,983,918,734,223,154,548,481,949,823,333,755,817,777,107,119,109,229,676,494,623,564,884,277,742,365,950,94,486,545,518,52,835,928,176,825,519,869,492,754,91,545,714,170,184,506,863,37,802,466,800,551,167,424,299,170,608,113,671,306,439,448,52,782,739,640,741,585,156,553,740,823,179,541,202,485,265,589,925,87,830,906,2,865,634,253,721,965,371,665,694,736,548,531,914,898,235,25,855,810,853,974,242,335,384,693,472,823,822,294,639,690,826,24,180,262,153,638,12,226,904,838,853,877,928,723,773,174,213,784,169,547,827,70,113,398,586,50,922,159,102,773,897,413,553,298,254,209,419,314,365,217,154,209,886,919,610,558,85,702,109,453,463,942,879,181,460,991,98,175,273,337,209,478,380,554,375,950,890,298,281,981,603,967,920,111,755,365,8,459,696,322,488,468,954,92,681,572,518,862,644,970,154,712,738,380,671,522,975,452,685,465,34,494,809,483,762,465,550,327,574,728,559,822,724,812,121,638,288,509,757,679,102,772,711,585,290,886,731,293,737,18,739,310,199,729,96,850,575,150,451,912,612,423,338,842,902,431,142,444,793,970,415,0,81,628,675,433,187,120,313,875,239,429,756,962,850,537,656,458,986,789,247,445,711,337,226,35,755,293,517,312,597,634,859,11,235,469,459,138,7,341,507,687,518,823,582,898,822,284,352,943,775,193,20,960,514,723,295,782,433,664,576,406,407,26,914,696,633,409,108,157,576,925,713,31,742,797,255,387,59,812,159,485,919,181,977,718,438,713,216,892,173,86,539,761,83,153,507,544,337,682,459,352,239,638,119,974,106,89,136,101,906,142,284,708,393,429,980,156,265,331,573,743,150,606,216,995,342,816,572,487,629,29,36,368,239,647,722,627,657,796,344,553,649,343,388,882,467,1,65,384,859,884,823,584,393,640,166,31,681,540,618,843,504,785,404,415,515,88,993,98,448,203,472,455,823,963,153,654,244,337,393,304,788,44,629,287,560,466,908,582,186,403,977,892,434,855,469,622,647,45,16,927,816,794,412,271,824,10,644,964,963,118,652,705,42,75,867,896,188,527,516,900,559,505,649,598,195,925,608,164,539,933,749,722,114,635,536,693,729,289,274,197,646,953,841,925,729,436,510,136,331,759,371,632,26,607,888,640,643,186,681,596,669,754,169,866,720,922,394,321,620,265,571,67,728,309,510,853,811,765,262,507,204,756,565,254,841,331,677,652,624,86,725,78,100,906,92,595,665,231,963,992,799,171,664,648,27,749,828,234,533,471,998,159,697,994,127,829,53,847,617,454,877,302,376,460,55,157,940,371,330,441,870,238,133,572,337,268,889,31,799,671,761,621,140,969,247,969,826,974,306,913,129,673,693,711,584,937,855,614,970,889,318,261,839,483,433,928,733,236,217,459,548,734,439,771,394,191,451,389,163,849,164,568,511,278,251,511,449,105,973,344,661,202,462,407,104,585,264,774,212,819,848,865,76,604,606,545,20,543,562,196,325,302,404,114,299,470,600,979,78,751,278,232,924,323,516,121,703,480,22,259,134,909,147,464,678,105,319,596,946,959,652,990,244,119,216,242,616,517", "80,907,65,885,700,119,957,823,51,588,35,440,536,89,876,973,366,873,4,284,618,931,215,290,57,748,857,239,56,392,457,315,596,839,33,370,96,250,373,831,506,145,153,220,138,941,767,994,768,656,400,884,829,377,946,474,915,327,552,264,354,265,970,149,828,725,444,90,909,847,201,507,441,690,344,8,408,146,267,995,651,126,644,43,733,257,294,476,354,343,51,175,817,775,430,513,386,144,763,376,760,159,622,198,599,865,777,800,460,984,695,385,232,308,176,943,622,940,754,623,998,141,474,37,633,202,353,459,889,771,349,740,665,923,311,146,431,956,458,237,129,43,908,438,886,381,992,77,511,582,385,758,989,366,254,115,192,961,174,729,235,15,448,817,182,659,185,440,809,813,244,605,2,546,543,31,283,903,938,585,628,754,772,300,831,767,296,7,887,216,932,711,622,260,420,512,584,188,108,888,828,337,146,408,515,26,27,830,441,364,93,960,659,923,821,172,319,508,596,671,105,752,497,806,320,743,665,919,223,1000,685,154,47,972,373,929,68,185,268,501,82,705,546,813,834,262,371,444,96,709,216,34,688,896,682,914,809,14,707,238,81,344,29,928,116,936,781,892,456,64,822,35,520,583,996,530,263,769,193,629,120,483,932,332,386,309,886,580,188,592,859,411,226,86,291,211,991,129,922,975,609,53,791,617,350,632,569,470,776,121,105,282,957,932,106,479,60,936,716,77,849,232,558,660,316,599,533,729,811,787,236,468,673,879,691,107,688,29,324,537,339,278,498,185,499,826,849,820,287,357,523,689,753,536,323,348,169,682,421,228,358,941,39,183,986,574,315,824,72,402,185,554,848,26,54,846,630,254,254,411,121,807,471,7,526,557,853,245,428,121,231,195,987,338,880,829,826,913,149,813,979,428,775,336,930,44,293,879,950,328,637,691,675,118,897,557,463,930,790,950,125,790,918,750,860,108,858,84,205,828,937,412,284,402,97,470,611,384,331,882,416,479,928,713,571,13,706,125,986,817,595,193,247,879,838,96,104,360,816,493,718,677,770,382,305,137,249,158,957,187,64,763,709,464,396,929,186,608,177,505,884,182,80,850,453,960,441,808,149,970,105,224,271,300,46,117,26,996,111,686,640,689,360,680,646,120,269,520,15,188,683,636,426,167,238,236,230,532,837,209,485,79,199,682,994,398,935,732,233,373,444,883,246,88,185,25,119,752,221,389,499,819,911,636,914,424,765,325,940,990,246,81,0,37,483,221,366,311,527,612,586,305,192,60,860,185,68,680,687,593,454,93,546,48,810,820,663,749,273,557,245,532,222,857,647,538,347,924,260,899,789,389,66,457,919,775,200,173,137,390,749,491,6,691,893,132,335,532,834,39,93,273,175,869,336,434,945,390,482,133,774,747,480,442,596,694,933,389,385,720,587,167,869,129,760,904,848,992,562,939,409,297,570,278,397,903,741,811,235,669,62,314,100,934,607,108,225,562,439,809,325,242,277,560,134,971,437,72,716,131,397,177,459,766,472,643,562,394,480,356,520,937,75,807,63,464,824,131,537,336,220,651,914,590,690,256,487,457,680,561,284,144,565,317,521,569,205,516,991,45,955,917,685,550,599,874,933,303,308,417,130,716,966,231,274,823,650,864,510,865,286,794,39,162,230,626,759,638,485,163,235,598,614,946,622,129,813,312,495,16,261,213,719,681,337,148,283,408,389,576,349,45,768,922,587,659,520,135,266,374,161,920,461,765,536,347,488,325,916,994,830,371,124,616,271,15,115,712,322,609,217,447,460,389,653,232,620,754,86,483,953,457,173,785,658,550,460,874,242,548,873,532,949,607,60,834,207,556,210,102,376,133,547,817,56,169,201,214,682,486,775,555,846,593,434,683,244,190,893,666,487,62,237,46,169,493,426,973,207,316,394,265,310,795,396,158,843,564,356,225,110,944,940,816,999,478,977,945,2,48,794,279,482,469,828,340,973,741,240,488,523,721,24,934,7,41,509,391,977,301,238,682,839,198,154,409,673,736,449,488,655,165,204,379,598,162,116,862,335,762,165,959,146,70,93,522,511,714,113,721,949,680,964,325,3,388,3,21,767,686,466,806,793,251,103,316,109,158,386,724,147,307,846,344,562,523,968,670,220,143,57,19,97,857,690,798,777,59,69,351,833,851,123,782,575,660,517,218,872,322,353,264,650,463,395,260,61,302,969,911,296,483,921,62,764,95,512,736,637,794,206,335,103,401,647,146,496,39,143,678", "699,612,914,931,648,567,63,823,106,193,990,908,934,46,195,423,166,826,840,430,126,885,830,933,595,619,272,825,919,477,488,536,810,849,599,441,368,854,129,820,717,41,509,464,116,188,733,5,196,778,5,195,681,574,231,256,897,500,874,253,464,87,510,853,313,6,627,70,526,155,197,37,752,722,114,670,846,947,934,942,288,287,840,212,414,915,114,706,560,850,454,962,277,956,24,623,33,486,545,433,562,752,316,961,770,84,746,861,748,182,318,687,181,697,731,53,370,118,755,541,111,932,693,688,84,852,120,561,541,44,263,838,136,684,469,193,548,877,218,507,43,448,254,582,553,652,796,900,441,957,634,619,484,540,793,210,676,212,930,465,474,74,881,552,587,807,730,87,752,698,746,13,936,168,364,863,12,913,755,251,552,139,190,554,313,232,959,343,453,432,273,725,98,658,269,34,481,97,530,472,691,100,722,347,495,482,816,718,63,242,762,307,584,38,29,133,140,393,322,821,298,738,745,394,781,973,683,732,968,308,223,965,404,289,35,904,955,988,52,726,107,731,195,799,806,57,327,980,937,742,894,920,290,434,302,699,206,542,528,140,177,32,685,92,483,329,754,823,461,494,271,480,803,481,442,499,795,248,933,102,203,921,74,359,119,833,52,667,868,63,497,904,320,853,258,893,176,388,435,307,575,675,68,214,195,634,665,891,330,214,13,482,102,638,950,267,357,581,803,63,211,901,502,622,972,155,288,96,72,945,491,450,723,817,143,239,557,825,820,368,335,668,740,941,895,493,316,140,327,575,21,154,870,732,490,232,94,165,540,186,923,493,817,660,274,202,227,142,57,74,595,931,46,982,363,210,46,806,369,917,718,915,397,902,358,643,836,282,343,632,787,325,319,236,23,976,256,90,1000,628,209,727,137,178,590,699,111,441,558,941,116,153,941,608,212,201,290,264,805,399,491,185,245,662,750,117,401,486,734,496,415,180,272,747,922,263,404,751,99,592,730,832,850,421,57,681,752,917,968,220,274,116,7,717,346,697,217,340,834,643,514,954,416,785,686,719,783,274,169,632,116,638,871,976,281,413,626,51,286,865,931,853,669,213,514,276,437,505,326,142,584,720,729,148,78,700,252,106,731,245,979,808,429,753,108,759,907,823,709,212,133,826,416,443,427,894,909,87,61,567,226,150,265,573,694,924,683,2,614,87,468,988,295,466,907,145,606,929,108,278,902,445,824,182,850,760,156,560,783,664,758,628,37,0,990,423,916,380,567,673,955,541,670,509,84,65,189,989,661,387,178,895,516,234,230,120,176,916,212,915,599,684,491,847,931,36,979,518,151,162,273,471,725,831,800,474,210,232,988,999,734,134,545,382,224,772,377,428,239,500,296,686,397,540,147,110,664,53,24,429,184,892,586,439,277,360,945,238,435,147,452,313,448,215,587,602,553,733,18,285,892,198,37,635,822,459,188,528,817,220,193,361,993,840,544,704,46,415,306,846,560,295,153,732,447,343,550,630,924,455,296,109,459,919,926,182,554,502,844,698,736,874,709,352,552,263,454,981,578,607,440,569,632,31,899,792,876,16,185,266,699,893,308,265,367,756,144,364,477,127,713,417,198,478,879,973,941,386,424,119,834,790,139,196,15,644,662,416,945,30,730,904,791,435,286,387,882,75,230,304,718,969,479,448,28,137,866,678,763,648,139,796,104,187,150,852,91,297,767,311,237,429,395,811,92,756,22,897,61,681,118,451,452,627,692,463,910,532,92,885,276,252,398,759,880,565,541,9,812,26,169,530,955,99,227,928,463,515,5,696,88,726,848,350,789,798,602,925,741,204,356,493,642,210,105,905,218,744,304,59,828,995,794,422,226,360,487,40,747,301,324,675,719,505,946,34,630,884,239,236,859,430,677,25,490,414,178,694,934,275,121,622,835,991,497,50,955,617,107,937,464,354,442,782,173,15,738,424,592,490,267,439,795,579,984,899,14,897,414,744,781,303,62,697,352,311,432,230,427,238,545,765,233,208,632,976,179,483,377,522,130,91,318,249,130,585,94,231,837,129,163,568,515,329,470,519,617,593,632,972,363,378,85,602,744,535,877,302,338,953,124,443,734,477,338,105,937,439,100,567,854,489,633,644,792,78,79,983,9,772,58,446,672,730,229,520,743,786,119,333,420,686,186,32,453,965,708,857,698,190,609,79,664,155,719,292,994,571,899,605,192,612,929,134,288,627,918,364,81,218,904,308,628,688,61,750,557,987,887,318", "35,40,962,724,266,895,260,141,569,129,752,327,483,416,86,852,547,157,736,271,561,532,999,270,823,638,764,794,455,835,912,371,941,1000,909,161,373,948,248,351,862,201,951,354,591,673,243,11,557,299,608,985,658,546,760,916,88,300,720,567,500,304,890,778,309,608,731,445,888,86,908,538,644,411,723,649,723,46,314,624,207,885,527,661,346,548,707,447,72,400,305,410,694,760,217,228,623,79,945,733,739,903,265,232,681,754,288,847,813,354,332,546,395,665,343,311,287,567,816,726,889,327,100,731,16,883,101,263,657,949,457,45,17,9,93,217,939,562,265,545,393,350,656,387,333,268,348,617,453,797,492,249,190,861,456,416,739,346,695,702,835,640,434,143,265,206,311,219,581,149,766,868,244,323,602,800,651,874,128,754,272,577,906,984,203,152,736,953,793,96,79,760,150,868,324,443,933,823,899,796,104,273,282,950,394,428,265,234,54,408,362,258,452,684,106,193,822,88,643,478,547,743,377,142,168,820,240,557,616,916,712,793,272,827,785,49,374,944,253,714,441,820,709,523,1,936,175,819,167,899,17,311,87,884,820,298,590,286,502,208,945,902,718,11,351,769,545,767,582,400,826,276,62,211,371,898,895,436,183,977,881,747,829,524,1000,22,523,398,843,328,663,85,224,243,132,566,925,483,653,607,736,613,879,579,463,17,801,196,311,99,842,833,23,167,93,858,681,785,245,865,861,692,871,782,884,192,794,427,837,660,663,184,985,948,249,201,291,197,601,378,343,697,243,355,683,290,105,470,156,79,587,53,278,626,279,38,185,610,802,739,25,541,381,341,874,519,170,726,956,700,438,135,748,256,76,180,992,743,289,750,527,446,736,909,97,531,278,294,74,66,830,337,514,339,372,925,522,844,23,999,546,318,816,334,763,509,491,771,137,635,824,424,962,859,588,732,48,244,2,780,195,266,588,114,459,214,373,439,554,845,393,123,661,11,462,577,136,22,217,218,292,989,770,304,668,224,286,247,986,943,118,617,557,39,753,729,115,555,418,648,833,348,302,39,800,265,396,108,679,454,680,889,57,476,669,428,850,550,237,875,870,62,413,593,261,657,886,489,191,230,636,184,549,579,637,860,151,387,92,718,232,577,452,423,630,81,883,7,144,961,158,526,71,53,437,87,438,653,919,860,266,800,584,714,231,166,330,397,239,424,481,311,65,545,383,435,551,456,179,190,841,123,477,233,276,13,259,361,502,76,266,675,483,990,0,722,888,250,324,489,938,476,536,32,251,740,598,458,962,56,716,972,343,550,461,251,978,806,455,937,734,63,799,330,916,553,110,162,979,668,844,715,511,379,793,520,149,446,989,524,909,242,984,912,994,174,796,327,336,383,850,569,162,23,668,609,665,943,422,422,732,328,324,843,506,263,231,695,277,125,180,568,448,348,971,947,415,38,657,170,111,166,273,134,369,911,19,937,563,943,329,920,871,194,823,570,193,139,535,142,987,88,949,765,230,791,709,279,804,389,587,985,309,38,678,398,478,195,53,448,941,942,411,308,257,777,817,628,671,807,660,692,54,206,78,980,626,906,621,283,157,987,535,744,633,538,85,277,729,313,959,300,159,775,248,166,262,146,856,166,736,650,352,40,885,673,752,735,537,406,772,39,577,343,58,527,658,839,569,667,952,556,823,938,418,874,644,499,528,800,670,841,756,437,555,9,60,63,860,507,389,9,778,897,894,897,398,233,974,183,11,169,437,673,741,743,755,470,425,850,765,609,632,84,7,493,763,56,52,962,12,161,76,713,634,225,478,294,29,369,445,572,54,483,35,211,23,230,204,805,801,435,528,884,965,4,375,985,165,275,551,403,279,848,358,308,651,665,777,107,179,524,151,988,401,15,363,597,103,982,942,493,734,640,478,715,863,8,502,824,813,499,687,844,299,663,506,663,273,483,802,912,858,646,414,65,771,394,679,462,510,470,729,428,236,722,449,763,968,675,977,315,501,387,302,311,598,323,633,20,881,346,109,398,278,763,565,846,328,749,791,297,642,950,169,503,777,308,986,984,100,949,942,495,623,27,426,574,733,686,429,648,109,388,850,204,230,448,149,139,339,940,828,205,817,815,203,345,778,447,920,768,603,685,289,841,406,101,753,151,728,764,882,185,349,240,871,961,333,745,369,792,60,493,490,601,612,23,494,866,771,687,482,974,291,444,188,643,228,30,36,932,562,286,650,277,460,947,712,864,383,998,972,818,85,609,50,270,894,494", "345,138,71,124,682,664,523,401,90,681,752,558,749,589,826,983,941,915,105,119,466,295,839,559,487,907,392,211,491,367,557,943,945,677,440,32,279,990,385,116,967,754,171,753,271,968,742,939,435,902,85,617,991,196,908,299,388,761,311,880,150,373,182,425,984,744,379,275,998,443,856,882,374,386,898,32,870,900,172,765,225,189,602,271,442,622,990,775,968,207,982,116,680,700,238,975,48,55,968,217,22,16,431,756,809,315,952,577,821,737,575,584,134,433,973,505,464,193,103,310,305,194,417,361,489,442,900,155,678,532,827,457,975,286,506,463,463,478,872,604,693,467,320,896,522,671,357,813,131,478,611,375,825,234,945,838,770,767,33,825,570,786,17,264,126,241,117,380,280,54,265,360,76,445,33,39,326,980,401,150,266,823,504,893,131,780,900,446,326,286,392,718,434,672,275,728,641,495,227,969,336,108,900,203,33,36,98,940,94,849,208,879,695,556,21,753,791,152,696,808,160,723,513,331,635,246,557,515,632,947,334,792,97,78,131,548,636,626,815,369,159,47,190,395,940,613,706,817,710,734,16,638,669,344,121,848,657,770,864,217,85,13,50,926,422,427,356,961,739,795,277,762,849,525,983,869,977,515,186,544,644,933,748,178,356,71,564,661,366,544,968,366,389,866,228,237,449,130,148,789,762,996,296,301,84,886,61,508,47,875,950,905,808,84,915,568,939,162,21,44,995,459,870,698,38,380,236,860,20,498,33,630,994,61,814,825,252,859,745,446,812,620,792,478,501,703,258,983,24,771,622,48,178,689,194,562,400,91,986,451,58,614,946,954,914,828,668,425,403,326,316,189,336,685,560,829,3,338,966,502,10,747,545,392,400,206,490,952,460,964,97,535,161,887,566,485,410,990,211,157,766,968,575,103,218,124,807,832,454,297,619,323,672,156,145,824,931,858,107,276,254,270,860,651,700,507,368,744,774,582,69,538,779,909,655,640,234,143,943,961,331,792,230,869,11,595,40,868,7,480,929,547,7,791,712,375,118,495,705,237,373,936,993,360,83,487,903,936,889,153,630,595,411,751,593,174,26,665,551,46,412,668,840,821,276,908,109,205,453,771,299,14,379,426,234,836,105,365,401,458,117,439,426,988,606,251,464,250,214,323,664,888,60,425,441,274,859,513,248,642,540,141,795,455,246,342,782,337,159,789,918,998,338,991,487,160,787,740,463,456,186,954,690,855,530,754,529,950,283,43,733,433,221,423,722,0,958,214,878,59,585,303,765,405,676,827,707,43,167,164,469,350,449,151,650,305,349,236,498,788,729,913,162,232,126,436,231,23,574,405,402,906,851,780,973,127,281,945,805,251,846,886,851,573,264,303,331,219,974,951,239,750,732,600,16,167,954,993,589,955,325,806,432,829,567,204,601,558,552,646,704,925,55,830,534,734,169,881,17,765,709,410,924,231,957,839,342,772,880,881,522,272,215,36,857,888,276,689,819,34,87,301,297,282,590,489,210,56,945,574,789,511,998,694,472,193,128,206,59,376,184,639,630,646,442,942,30,179,882,563,206,393,431,128,140,995,23,13,730,401,524,344,427,848,319,945,253,873,982,708,215,826,67,327,516,2,915,260,858,557,225,894,17,689,144,574,858,784,986,421,266,56,673,568,897,589,658,159,998,977,108,137,339,873,756,497,163,668,319,850,565,666,774,703,408,637,242,449,28,278,369,201,791,117,164,367,325,795,401,263,327,566,298,284,239,60,394,610,240,697,806,359,82,543,796,120,40,184,870,11,13,271,158,109,186,579,265,156,615,54,6,529,322,336,37,602,263,496,184,364,651,203,823,595,336,231,241,811,847,293,825,780,789,544,150,111,247,90,254,800,338,652,224,87,750,760,459,40,968,594,32,191,957,570,359,916,8,467,248,889,658,147,569,156,634,528,681,382,460,934,642,769,32,234,755,246,126,516,81,914,924,635,347,708,377,480,830,737,423,570,832,631,926,383,662,542,821,496,260,118,178,585,423,207,425,178,458,926,766,945,733,390,395,430,52,164,576,11,419,854,76,671,713,377,155,152,996,301,178,287,781,327,495,107,315,74,192,473,430,309,681,727,896,181,100,907,468,356,751,612,328,540,727,133,521,643,487,835,618,235,202,416,407,541,525,316,427,51,436,468,391,451,91,564,364,20,953,498,401,774,552,175,912,4,698,77,139,501,746,62,699,984,52,867,390,672,818,501,883,622,340,252,576,499,959,98,91,886,760,246", "830,857,172,423,578,536,834,352,572,980,690,310,466,278,335,101,176,51,10,206,650,774,131,293,308,911,741,569,1000,20,597,43,122,920,753,892,614,181,986,143,172,366,268,987,564,298,479,559,801,65,814,513,773,833,163,37,657,569,913,804,647,60,103,345,845,568,892,354,219,322,104,636,831,597,530,67,894,125,49,647,302,243,683,740,901,115,218,681,943,848,383,286,801,358,381,876,457,870,829,933,303,177,752,992,808,968,736,648,798,798,901,581,178,574,512,739,608,856,695,846,901,49,970,224,808,885,430,803,316,235,501,964,536,873,212,901,416,570,937,371,294,702,13,98,188,606,320,995,91,194,94,153,627,605,530,973,460,204,267,685,161,320,798,240,878,522,510,179,973,518,945,575,349,417,566,388,129,961,562,616,433,55,209,30,733,769,437,925,754,586,768,21,783,150,750,217,497,143,886,474,115,989,442,148,477,414,386,416,643,933,60,340,445,33,327,946,760,304,75,663,456,706,636,887,655,674,727,554,417,930,980,495,582,698,106,978,643,733,712,39,563,257,907,78,840,774,281,339,918,600,19,363,474,564,502,355,17,865,976,934,672,724,880,272,937,375,84,967,315,924,189,379,937,977,987,939,326,833,371,997,524,185,111,13,62,650,845,957,596,707,459,604,399,470,574,780,892,303,987,145,893,184,887,797,835,646,424,396,123,785,100,881,830,594,116,301,215,46,138,901,104,589,236,440,849,647,755,303,406,490,81,803,995,951,290,357,36,536,955,626,448,305,722,795,445,761,915,59,321,144,263,938,588,200,427,86,461,564,404,31,289,46,167,768,181,217,800,943,742,948,377,806,736,164,471,314,376,228,891,423,613,721,257,488,40,638,296,794,275,728,444,84,920,462,690,792,981,954,874,774,321,376,589,342,513,65,666,491,969,680,785,371,252,311,741,450,105,564,449,967,405,533,872,505,906,168,560,455,206,759,706,563,62,280,42,390,966,833,685,542,864,395,695,436,907,675,928,896,812,873,972,15,232,828,449,25,35,394,242,29,856,293,71,603,967,334,12,743,142,204,112,647,399,707,401,970,198,845,546,88,4,677,730,394,65,389,693,241,140,510,51,263,499,336,381,858,3,496,454,710,47,429,381,994,130,651,193,348,495,395,810,565,225,467,505,234,761,94,781,3,876,929,868,602,797,972,693,228,942,146,786,778,705,235,251,923,993,727,501,914,224,881,772,283,712,906,518,301,390,309,806,187,366,916,888,958,0,668,956,755,383,104,191,627,444,43,364,501,642,460,498,394,144,941,549,768,368,871,6,52,500,650,721,207,258,511,776,922,675,493,471,471,860,639,887,598,94,941,626,56,971,44,729,174,404,336,845,384,862,89,43,97,51,729,227,886,309,445,388,121,39,763,93,629,992,448,727,344,286,55,410,835,30,325,724,674,566,987,123,363,432,730,854,281,623,885,24,754,399,327,815,957,161,952,832,551,841,323,8,596,877,233,41,861,539,258,323,755,715,542,122,181,421,468,164,433,361,625,866,227,588,577,132,61,39,590,459,297,488,654,193,504,772,986,796,660,920,552,566,232,119,553,122,708,697,496,532,421,777,888,576,398,544,205,123,216,767,58,268,243,551,781,50,853,502,690,794,872,270,46,327,389,880,723,271,315,980,282,472,432,11,904,294,577,756,159,398,429,811,498,931,916,38,871,193,189,956,80,945,897,321,549,185,119,408,929,198,421,913,167,48,135,813,481,808,180,841,12,220,144,911,327,538,54,906,244,764,448,739,301,75,399,585,288,407,699,70,270,194,528,341,131,138,335,58,170,890,730,173,976,5,82,645,722,690,266,713,730,867,508,877,356,879,356,147,515,937,556,64,487,602,629,439,345,806,967,768,538,113,472,314,610,562,592,468,137,514,802,428,686,200,469,404,450,208,597,534,381,520,734,512,388,517,606,241,873,283,307,640,364,129,835,542,556,204,964,305,770,40,115,546,907,702,387,545,973,215,574,237,693,808,844,40,372,184,746,540,902,344,937,796,451,904,550,105,493,304,73,340,543,755,721,76,773,560,660,86,17,65,733,775,825,401,702,337,730,312,42,937,458,318,434,728,766,667,376,759,380,919,203,453,189,541,561,553,292,191,438,34,149,796,641,386,862,123,263,552,394,896,80,327,990,313,815,539,424,530,179,502,507,777,955,490,781,334,456,948,112,22,496,601,86,642,46,982,834,437,603,151,982,344,366,545,185,688,410,736,516,105,835", "687,958,795,731,597,207,747,426,66,786,13,806,521,230,679,62,338,582,207,64,141,634,90,19,453,366,18,774,744,293,277,496,662,946,400,672,260,622,786,459,390,233,188,689,397,843,149,773,139,307,221,431,785,272,201,224,313,469,912,911,971,256,490,938,128,895,119,520,901,265,833,520,578,932,519,529,577,877,511,545,862,818,139,24,161,846,819,853,962,665,356,398,463,230,244,785,339,533,391,729,444,842,486,636,139,154,804,692,37,362,693,796,364,998,351,43,193,15,772,545,694,94,731,594,950,823,485,338,413,228,48,908,938,23,169,885,701,557,383,448,457,529,318,442,635,524,170,865,779,120,338,351,428,696,267,584,63,180,713,103,120,755,598,114,123,12,732,972,461,514,686,481,953,65,157,615,235,575,678,136,877,261,525,803,604,170,80,708,69,808,308,685,284,317,279,647,962,459,896,76,247,691,782,357,589,728,282,349,376,55,400,548,568,902,936,267,315,852,202,392,479,43,961,373,781,919,491,731,902,847,327,181,433,213,377,14,462,771,59,654,307,501,183,943,631,560,680,351,410,485,676,624,811,760,356,188,556,905,797,68,134,162,394,524,965,928,810,743,10,709,880,720,668,432,367,498,445,565,925,633,928,918,481,53,261,654,806,780,466,623,122,838,106,100,201,714,543,976,560,15,367,846,380,438,816,461,409,241,648,436,437,674,955,225,405,122,2,426,700,798,855,48,940,786,30,341,820,667,787,464,593,205,638,562,580,147,698,713,699,893,59,897,156,382,190,287,535,697,712,512,40,231,915,28,597,701,60,245,703,46,814,349,621,508,923,745,697,979,784,835,385,896,996,943,297,148,256,59,599,780,976,894,648,399,711,400,760,222,466,575,561,453,3,808,552,926,434,877,791,681,429,959,586,415,458,801,960,434,792,534,711,392,98,423,28,702,522,647,555,512,125,786,419,638,181,316,354,714,14,145,670,492,417,832,636,397,136,708,821,764,903,346,2,13,247,498,46,432,501,943,689,727,614,679,799,898,974,954,510,19,141,48,111,545,282,234,794,224,421,949,979,574,228,427,698,268,715,565,899,535,377,726,950,554,252,6,48,285,716,623,420,797,658,951,848,486,62,971,180,334,156,823,207,580,692,412,526,549,585,704,654,229,489,503,229,706,344,664,668,586,792,925,179,767,489,970,183,286,252,252,997,727,348,734,504,776,827,158,18,137,489,627,862,556,801,806,239,433,581,3,556,120,311,380,250,214,668,0,882,69,887,921,992,387,436,709,238,704,730,179,760,68,304,91,493,10,993,856,512,545,884,800,266,111,688,728,651,638,875,293,745,41,176,203,751,85,289,779,691,902,891,434,609,78,865,589,830,495,831,876,576,996,335,731,804,36,200,994,624,301,887,945,46,841,808,397,867,825,110,13,414,702,140,136,900,622,978,291,192,170,118,195,703,338,251,422,957,169,609,209,523,466,874,853,599,429,2,291,947,854,390,241,411,712,375,140,694,787,428,939,977,169,126,52,692,65,617,232,64,236,112,444,26,696,990,106,730,963,457,77,787,633,9,903,733,394,300,798,634,42,208,193,203,76,443,813,280,933,818,637,606,499,588,992,896,732,288,142,144,251,682,270,33,774,20,696,288,690,229,166,619,243,246,314,348,853,58,562,160,169,453,174,425,752,891,493,731,267,123,580,714,324,158,333,620,81,518,420,680,331,917,512,396,35,48,720,999,992,680,201,663,511,968,928,368,755,724,538,405,840,652,154,401,163,356,705,80,254,505,62,768,384,425,379,598,415,546,305,980,98,235,115,445,995,276,905,71,825,502,387,745,906,102,423,968,865,634,380,891,147,617,706,543,890,564,18,757,495,391,608,511,917,885,440,822,83,89,526,837,178,602,471,32,858,467,755,489,184,462,750,862,328,527,555,920,326,282,745,32,861,463,802,437,118,601,787,829,392,700,550,625,508,566,238,470,21,948,797,42,85,490,552,164,285,234,208,472,436,841,333,985,377,716,637,691,551,861,920,834,879,669,272,175,336,499,321,615,443,258,804,311,949,801,80,114,521,170,153,268,46,29,522,308,313,51,642,441,720,54,333,923,391,855,398,992,101,830,988,207,222,575,359,691,875,337,74,668,953,193,439,206,541,442,377,228,693,460,199,575,40,884,842,239,42,18,459,587,955,481,993,328,417,738,482,244,713,29,461,522,433,390,398,721,74,52,776,922,821,241,758,540,707,265,863,133,653,661,388,386,382", "406,614,973,15,447,162,627,905,622,667,746,334,745,113,233,49,558,79,158,116,910,218,389,232,201,288,591,986,32,912,234,967,55,491,468,294,326,753,191,645,485,190,386,362,416,892,598,703,630,131,198,788,207,6,924,948,350,872,393,544,496,437,559,581,764,505,727,804,238,688,772,423,631,837,464,926,596,360,762,984,927,476,26,973,714,352,277,728,1000,110,155,463,889,169,393,119,602,545,145,978,635,991,115,428,650,736,291,403,83,254,483,312,929,547,653,872,747,507,935,670,446,164,272,290,951,799,177,715,501,700,501,95,456,963,643,228,360,590,855,70,245,529,568,19,836,748,60,551,164,878,637,260,524,133,547,389,910,937,348,634,713,923,670,531,51,613,536,948,761,153,449,176,947,769,526,747,292,826,229,685,168,518,478,279,124,542,285,97,491,113,477,818,37,684,761,60,497,249,474,604,519,222,713,824,438,673,420,957,593,327,242,464,282,682,500,701,615,744,281,213,315,491,198,412,109,137,875,545,929,216,112,687,622,862,63,237,581,334,629,71,456,594,841,787,274,285,673,836,29,386,723,11,685,680,560,986,452,657,145,959,825,128,140,610,263,377,288,448,224,899,822,534,714,849,289,838,682,347,396,363,14,131,815,329,431,547,581,589,920,476,245,395,814,262,797,272,468,959,458,293,933,217,88,321,606,64,683,695,385,687,231,59,732,991,492,940,63,368,943,183,930,812,492,987,266,887,591,240,620,137,797,182,581,910,100,524,180,654,805,980,727,339,641,307,257,109,621,728,834,761,644,404,343,53,819,225,349,3,417,977,667,963,653,81,64,761,908,633,635,394,667,155,455,16,661,44,85,885,956,205,975,20,815,640,789,677,9,68,53,699,814,654,418,292,322,214,480,719,637,512,151,282,617,469,748,419,212,442,678,806,256,544,208,887,597,128,41,845,342,918,603,202,159,193,264,569,33,22,938,339,526,24,587,172,447,213,463,659,527,484,110,617,817,666,340,780,545,341,503,997,285,40,418,442,772,756,276,626,787,197,522,439,147,168,673,299,103,781,280,891,845,333,11,335,193,532,994,131,103,77,958,370,396,871,111,235,660,984,701,347,559,815,146,983,885,812,427,17,731,826,196,547,792,183,188,156,415,915,28,558,720,80,857,711,935,633,219,304,284,813,531,924,116,227,880,197,920,208,378,471,796,562,793,336,410,568,484,546,227,99,172,419,304,571,13,272,503,117,584,208,794,313,527,567,324,878,956,882,0,136,377,151,77,385,321,651,94,681,69,827,642,455,808,651,41,340,347,315,807,369,987,519,69,140,21,628,525,357,649,260,459,259,795,700,26,880,176,512,819,424,483,506,158,324,475,655,661,827,496,632,265,50,216,616,581,662,410,54,437,356,513,574,836,480,217,872,290,582,599,209,382,305,149,914,304,848,639,704,323,87,808,86,690,16,662,432,255,173,888,432,17,286,945,187,159,169,123,946,509,871,206,95,430,780,532,619,24,606,937,813,314,701,344,419,325,294,414,374,979,437,27,519,227,261,443,757,11,725,333,607,425,787,296,485,916,701,438,581,92,730,573,233,721,305,960,191,488,837,903,434,477,7,373,441,439,632,821,280,502,101,71,817,435,159,584,906,800,633,558,984,138,569,697,848,973,68,110,614,221,178,967,261,505,20,348,49,410,244,394,337,959,947,232,209,7,413,245,900,283,32,757,425,387,725,815,907,739,661,725,816,210,326,888,769,247,124,428,359,85,411,24,632,330,817,267,287,28,999,127,913,914,294,352,126,795,56,589,98,442,23,74,984,47,958,274,340,137,913,866,866,299,971,71,724,220,2,316,492,916,279,123,883,728,853,598,234,700,668,187,591,281,639,639,231,16,272,43,191,815,16,192,226,190,688,548,38,979,109,175,719,725,154,382,49,898,132,236,16,839,663,95,586,695,272,763,676,803,796,664,391,715,347,107,825,625,632,747,916,619,898,612,101,313,717,237,514,89,802,891,37,558,619,47,282,324,420,66,533,765,969,206,460,118,970,21,88,484,355,585,506,356,79,589,831,629,929,428,862,646,34,627,250,905,293,348,268,407,965,915,382,965,377,52,658,652,703,732,416,690,658,394,401,901,857,921,451,75,473,788,169,838,601,683,589,757,406,709,826,552,881,652,663,448,276,572,875,610,468,562,895,884,332,506,648,547,779,237,47,806,744,779,872,674,178,83,704,838,641,19,610,972,436,159,13,319,564,333,266,974,245", "605,164,430,553,734,841,863,647,101,71,626,809,358,281,344,336,718,432,283,937,235,358,929,353,176,658,618,818,349,857,600,71,800,34,759,746,192,756,330,824,244,133,223,632,882,363,694,448,217,106,395,609,458,508,121,8,137,259,921,649,98,134,46,889,506,856,423,962,725,868,492,661,654,940,252,437,148,351,685,660,23,478,883,478,310,959,535,618,326,677,699,540,94,547,460,218,96,834,298,835,622,249,650,626,454,957,550,421,357,148,688,807,486,795,588,411,381,198,985,973,509,833,107,531,429,371,430,10,282,853,221,815,634,367,809,272,450,291,393,861,782,463,380,569,752,627,136,698,299,477,966,348,476,199,866,386,177,458,295,12,852,965,469,531,508,150,594,746,586,899,362,750,340,570,41,99,879,308,360,287,475,176,863,908,433,351,3,925,825,88,912,76,550,797,633,18,862,216,882,672,148,920,612,591,849,474,80,496,36,399,159,872,376,359,971,19,404,214,39,359,356,312,907,36,550,57,512,189,41,152,420,637,6,300,844,831,727,776,742,449,776,607,155,119,547,803,965,659,754,123,560,699,850,321,450,346,674,675,312,148,834,413,536,355,355,985,676,885,599,289,484,902,479,465,46,770,974,776,30,653,966,185,157,711,794,728,765,798,765,359,951,559,180,694,168,126,278,20,800,214,447,521,822,725,299,981,186,637,654,663,586,2,678,275,307,480,653,554,148,560,933,769,462,815,267,155,892,97,116,594,399,28,133,649,955,997,204,875,549,184,368,167,450,719,512,248,881,802,932,118,574,411,985,549,365,106,931,156,507,408,802,609,536,833,923,498,234,606,727,971,865,764,338,582,201,64,19,621,69,923,212,157,942,249,485,159,419,531,333,720,810,327,359,707,525,347,121,163,315,699,982,234,133,602,393,298,342,391,741,198,946,696,53,877,261,204,267,980,325,509,376,331,952,423,405,51,472,378,732,557,913,494,553,506,988,537,525,210,427,333,795,826,227,401,906,577,417,691,129,156,910,777,571,271,367,819,935,105,494,958,367,200,820,872,735,825,867,263,601,247,274,903,147,575,219,929,559,330,622,649,222,790,299,699,702,840,328,77,456,171,411,482,289,262,627,278,635,637,921,399,933,306,631,618,934,738,15,272,850,113,893,795,962,130,70,426,672,844,625,773,396,433,663,971,17,997,558,536,475,768,415,662,632,781,350,143,76,38,47,322,468,771,48,729,12,929,541,784,689,818,581,875,612,673,489,59,755,69,136,0,789,494,9,623,573,325,596,825,484,626,349,254,239,237,188,691,444,52,496,630,623,69,260,750,649,655,666,990,598,83,476,517,222,881,901,623,327,229,48,464,841,563,248,47,459,602,52,583,928,115,155,734,390,363,591,755,292,879,554,288,174,64,522,271,221,752,180,908,63,408,972,70,217,648,65,99,335,28,247,120,598,794,868,731,577,116,74,944,952,498,427,693,948,303,627,929,602,774,238,232,849,808,662,129,487,10,887,289,812,714,591,986,2,51,395,650,572,277,451,149,166,303,501,355,591,669,886,388,816,363,404,900,902,796,265,909,721,567,290,769,54,963,841,893,678,570,692,753,712,80,61,59,415,796,960,311,476,761,637,96,298,389,540,352,125,924,89,716,634,328,215,170,114,625,617,231,821,977,571,869,434,489,732,297,419,201,30,249,507,865,123,972,75,756,310,923,266,784,561,450,603,94,239,174,860,121,353,335,760,82,829,227,476,123,452,229,138,732,287,480,729,550,202,572,719,604,450,937,120,409,388,729,921,316,634,548,686,412,161,273,487,171,138,739,510,135,408,180,988,949,603,907,166,797,502,20,81,236,321,841,50,243,184,728,908,931,949,953,535,185,173,972,392,532,251,272,216,310,931,551,955,744,420,458,91,22,146,301,236,319,650,824,517,977,139,924,643,931,497,506,710,347,203,825,494,173,574,24,55,311,104,687,981,702,333,499,912,517,495,475,650,802,321,304,652,867,305,418,830,962,628,803,561,726,521,390,635,341,167,894,49,298,711,363,968,796,201,890,504,187,612,905,386,508,308,747,453,5,915,59,422,189,933,879,14,567,959,987,492,424,135,148,18,878,147,27,918,843,487,993,679,122,636,334,434,214,443,877,898,70,837,735,579,553,524,846,466,831,489,628,770,226,492,494,161,29,129,62,650,325,485,48,180,638,951,542,166,38,995,698,524,409,931,650,210,787,137,576,915,116,464,327,627,345,404,117,291,552,418,292", "872,338,355,949,570,227,691,757,335,666,492,494,538,107,808,613,53,84,238,663,548,387,211,796,27,528,809,262,529,761,390,971,918,73,824,106,551,267,398,562,743,704,150,867,938,710,774,180,608,249,725,769,747,203,976,470,242,86,94,288,289,199,719,330,625,917,877,567,264,526,232,344,145,994,208,949,16,459,795,674,596,895,723,976,554,256,187,280,375,326,394,294,412,368,976,360,293,119,173,593,560,436,889,358,984,372,8,66,958,946,887,590,200,611,803,787,310,7,391,641,207,529,476,776,699,442,50,627,660,721,383,670,409,240,642,584,682,323,19,914,915,135,937,161,731,585,408,317,506,167,14,26,498,198,926,820,38,3,439,393,49,205,953,156,959,464,254,257,696,527,503,506,589,324,764,938,286,600,648,282,248,698,451,604,866,491,44,126,120,903,367,531,384,646,348,121,784,5,854,892,804,488,603,256,573,966,222,283,254,802,642,372,717,596,954,245,111,750,198,936,663,484,887,776,481,824,147,696,551,405,639,49,122,836,779,882,326,773,799,745,71,694,993,946,168,636,963,994,733,908,835,418,720,657,445,409,962,577,798,420,776,42,668,934,137,491,380,907,339,870,468,746,75,546,166,604,139,874,738,121,287,840,569,927,650,198,344,60,612,435,653,380,182,18,360,518,6,417,120,915,531,951,19,724,889,260,94,652,132,722,786,233,144,513,30,381,448,684,368,426,126,397,825,271,228,158,69,49,690,897,133,175,402,185,473,747,793,166,394,178,624,185,801,567,639,752,651,151,803,244,558,982,905,50,389,942,405,688,271,931,596,287,391,235,336,271,840,453,743,879,169,902,98,752,524,173,94,910,196,587,877,125,941,443,540,101,809,353,377,952,689,939,461,623,293,851,422,22,148,227,643,617,432,348,687,808,995,167,505,110,758,319,427,587,636,468,504,707,469,78,862,768,215,76,234,385,357,834,148,33,894,296,976,309,280,779,539,35,539,43,391,846,60,335,528,909,454,159,948,179,408,581,800,886,566,39,663,879,935,366,135,748,815,118,111,657,424,472,900,579,727,621,73,997,788,413,597,469,469,593,201,483,732,662,220,321,575,262,144,34,607,853,198,603,50,216,772,15,554,143,737,240,856,260,285,599,583,283,948,53,257,297,284,928,295,84,491,832,592,92,827,704,886,740,151,515,611,806,524,954,724,900,989,542,44,628,59,32,364,267,143,941,641,523,723,184,755,381,342,900,55,239,586,955,938,585,383,887,377,789,0,665,350,405,16,221,70,153,35,905,464,424,200,572,795,592,344,417,323,864,418,864,409,69,722,187,586,518,315,287,557,280,912,827,237,284,395,390,717,850,83,808,444,616,119,792,937,199,937,250,292,701,396,244,937,265,265,508,502,697,77,600,865,110,87,584,171,97,121,801,666,854,933,963,124,830,749,317,150,841,553,449,388,321,586,154,46,743,162,50,407,348,500,119,905,277,967,350,796,248,533,30,55,133,87,645,322,73,899,879,423,321,693,738,395,587,4,291,969,779,838,855,534,837,521,80,899,266,641,307,116,999,67,50,768,995,473,452,966,696,60,472,465,670,295,76,243,512,485,852,117,993,86,26,568,802,437,385,124,572,468,509,272,582,629,170,267,545,796,551,236,728,913,216,922,167,960,186,838,655,130,576,30,96,325,303,796,711,594,978,266,636,642,304,214,549,90,812,985,566,388,967,8,858,952,145,861,47,610,652,493,461,731,305,927,804,738,923,664,145,599,704,147,267,158,384,173,181,153,305,394,887,698,811,869,391,208,470,153,347,982,831,646,690,116,693,697,945,478,587,183,235,186,247,655,496,863,746,91,372,749,873,848,415,685,870,793,246,793,128,747,850,382,246,316,151,80,530,913,343,852,578,497,12,788,484,715,413,910,300,762,651,104,17,142,512,686,284,940,524,830,623,417,178,204,145,834,162,961,194,727,691,352,729,79,156,849,498,327,671,834,816,417,131,37,882,48,528,234,472,401,153,891,534,563,405,30,953,780,868,3,229,773,390,790,9,941,538,491,772,474,202,502,568,539,204,141,244,708,473,883,252,741,845,740,720,977,128,13,295,394,572,882,289,450,867,870,977,789,611,951,481,93,720,401,733,668,939,263,305,437,870,695,318,219,690,748,441,506,776,671,344,696,188,888,484,250,823,927,167,895,390,317,572,808,37,757,961,311,172,725,865,371,449,98,232,187,250,446,972,331,540,617,191,73,547,455,600,199,24", "293,5,969,79,236,760,192,950,319,663,320,601,815,962,105,505,407,182,872,149,512,407,534,554,962,939,270,832,121,294,994,101,179,680,491,524,61,603,298,229,134,154,318,174,798,400,13,205,993,53,877,537,77,524,43,661,513,17,550,59,450,349,442,484,255,300,426,378,759,899,651,494,603,397,159,153,98,517,548,200,630,188,680,256,667,828,289,634,246,700,707,646,760,276,953,436,670,869,545,36,885,888,929,511,476,164,214,192,599,7,717,304,234,386,898,56,723,239,623,58,574,810,756,370,497,626,672,771,566,698,581,661,480,894,28,730,248,521,44,392,601,171,783,491,412,802,142,657,5,587,326,290,455,134,673,845,915,676,510,26,522,39,989,980,167,823,783,969,839,907,450,661,98,204,586,133,682,467,668,873,379,67,691,391,131,628,885,886,210,393,582,547,571,47,282,164,610,979,192,349,946,434,704,915,837,974,156,636,773,121,774,29,954,870,377,417,4,125,508,117,35,207,212,415,351,30,639,273,188,57,613,174,364,104,637,190,495,109,74,878,52,664,985,347,182,332,184,609,477,149,579,576,968,572,97,419,194,569,23,963,938,683,111,943,874,580,526,353,753,50,834,454,505,902,901,952,806,526,211,36,290,343,20,629,17,623,804,824,878,123,108,652,712,332,666,418,392,904,914,212,98,519,798,806,235,131,211,684,180,843,524,742,797,917,924,12,58,713,354,414,768,654,729,491,278,200,523,387,150,842,826,821,102,401,239,126,232,375,865,442,157,205,609,70,256,895,259,829,105,624,102,685,36,648,284,217,161,493,45,224,803,432,923,667,375,32,293,990,411,234,544,420,393,229,476,274,446,655,143,30,862,719,883,117,315,929,786,843,25,800,224,808,996,353,706,210,318,902,71,402,667,435,507,419,978,889,95,122,125,612,706,141,724,927,340,651,994,612,604,877,752,88,661,899,731,39,891,294,467,663,930,685,557,788,576,305,615,44,389,703,531,468,383,337,429,333,115,463,383,769,583,268,582,175,787,729,936,43,619,498,91,86,709,844,456,43,11,383,537,428,600,923,854,238,844,198,741,104,97,849,663,49,89,648,947,288,235,677,239,820,577,581,19,260,10,835,630,57,223,44,941,992,115,946,539,509,948,569,64,625,511,696,217,841,871,320,368,767,585,445,588,887,553,425,501,814,672,853,279,905,748,402,295,128,686,33,854,460,658,928,63,913,789,814,359,32,546,114,872,978,114,429,305,541,476,303,104,921,151,494,665,0,863,645,876,269,967,978,15,621,73,180,401,562,449,350,457,666,952,819,878,418,658,48,433,786,325,726,100,386,330,367,660,631,702,792,685,792,976,920,171,125,457,361,833,517,546,571,289,521,54,339,378,886,725,716,667,332,268,141,62,110,417,831,732,746,253,135,704,802,841,949,283,944,252,833,720,906,555,134,45,977,2,574,330,534,479,696,595,103,31,821,66,921,781,669,51,317,879,440,89,863,390,296,188,751,876,469,952,863,125,13,740,547,878,251,477,90,44,423,859,654,497,776,599,244,593,879,377,974,306,734,795,175,224,306,225,656,307,588,163,63,410,300,809,97,373,458,804,794,302,489,303,131,392,766,270,248,554,955,406,29,784,321,854,176,972,503,817,734,656,835,277,512,16,914,377,429,285,263,525,137,148,165,272,974,722,673,843,777,636,811,731,823,398,841,181,205,810,291,583,284,998,668,583,187,472,74,394,403,256,219,42,234,479,704,507,547,875,40,862,380,482,588,335,244,561,333,381,728,877,922,279,403,347,471,236,492,441,276,822,685,162,392,749,714,670,537,608,80,993,566,51,163,187,768,307,777,705,166,672,293,333,395,589,847,911,542,125,41,77,713,486,243,201,50,780,852,571,933,444,406,553,38,185,343,776,570,401,266,438,973,130,470,31,498,544,890,443,301,711,921,109,862,505,777,770,53,480,809,891,489,495,524,32,15,644,321,888,990,462,947,431,177,15,221,506,566,522,930,324,485,303,948,65,280,521,972,786,984,740,986,181,778,997,676,564,643,902,415,324,841,774,706,929,817,81,186,904,319,745,616,719,471,345,831,521,124,520,811,636,225,714,319,475,47,857,809,495,108,518,722,575,602,362,378,608,974,355,59,204,638,586,272,185,135,913,919,337,345,303,169,690,585,614,398,344,509,339,201,382,312,192,526,214,67,243,993,750,536,161,55,454,148,139,786,410,25,947,421,344,498,728,648,949,92,42,749,710,849", "697,467,510,979,559,143,189,351,528,909,526,503,396,560,482,617,250,444,8,612,707,298,568,170,981,243,950,466,238,302,438,271,611,618,926,246,933,892,495,301,931,839,747,919,491,378,582,23,825,544,864,768,939,288,354,559,557,449,397,454,182,704,773,377,865,166,968,398,577,466,646,613,457,32,102,515,432,948,432,271,719,917,124,919,547,854,305,792,96,192,198,470,335,845,690,433,311,271,896,955,120,614,7,551,214,552,814,934,692,190,446,641,944,857,661,21,166,659,971,391,758,822,21,533,36,289,636,11,942,468,853,460,619,272,560,317,50,584,963,117,979,323,35,923,42,616,741,181,786,237,362,288,71,326,610,673,540,620,66,310,779,283,862,303,372,275,275,390,109,998,939,973,800,696,24,754,309,380,351,593,590,596,679,691,499,247,737,785,950,134,671,491,634,644,645,911,41,942,255,141,841,280,595,207,975,843,14,319,329,855,363,620,622,906,997,902,790,617,688,728,588,556,594,420,370,272,228,694,569,594,55,923,950,566,902,362,723,925,742,19,272,559,336,936,935,856,844,410,187,945,927,170,221,876,626,358,54,11,115,908,835,350,271,335,300,770,897,449,188,850,969,234,816,733,297,753,161,5,952,324,120,467,538,70,778,175,625,371,606,271,898,603,749,821,665,737,324,18,482,780,113,583,706,538,260,347,605,469,353,689,417,694,523,413,779,494,907,999,409,753,310,586,731,449,681,498,626,162,236,833,650,275,224,625,474,115,911,127,634,839,129,152,253,925,447,713,311,666,423,100,977,598,180,293,400,330,499,462,748,382,276,885,242,730,159,958,568,902,884,569,215,35,457,965,17,944,28,931,467,174,485,20,436,601,148,688,439,150,710,607,851,566,667,473,246,365,499,281,683,259,67,113,51,272,504,368,258,680,59,606,774,723,749,395,110,483,231,236,22,292,451,841,82,956,317,585,7,239,99,137,502,673,764,441,338,13,837,372,582,164,122,816,959,604,524,337,619,126,620,563,474,383,193,444,655,476,823,525,930,493,412,18,879,211,794,486,76,514,340,31,9,731,574,571,350,725,652,711,909,347,858,882,570,340,884,439,22,952,628,921,414,271,367,239,17,729,862,93,583,545,979,834,685,70,115,836,935,879,64,709,890,969,665,224,441,44,787,673,164,758,535,639,979,352,568,245,544,872,9,112,636,145,726,111,1,429,922,196,220,43,973,177,691,851,617,76,256,674,714,896,982,756,192,670,536,765,191,992,77,9,350,863,0,117,652,697,443,55,905,214,198,425,937,103,804,28,828,537,140,891,658,513,628,270,522,535,667,936,124,973,257,524,434,430,201,716,503,351,54,176,70,584,636,530,152,359,23,990,785,31,478,361,504,615,747,17,223,850,953,889,981,41,830,728,741,375,484,453,685,47,465,196,80,110,380,127,57,954,763,727,371,796,885,223,62,628,336,943,879,463,234,132,267,220,851,45,981,313,420,445,316,573,188,54,981,480,89,877,599,558,717,546,585,453,415,352,476,503,999,811,701,3,198,715,379,55,553,413,316,184,92,561,590,720,242,985,296,737,636,46,77,681,14,120,696,481,631,259,21,372,887,855,512,236,520,749,488,121,715,415,262,428,105,370,24,997,200,489,298,935,3,707,880,992,988,534,636,831,683,931,312,797,529,918,373,550,369,97,464,213,496,140,783,218,581,607,594,157,439,691,79,446,250,77,58,486,841,634,683,530,837,469,77,18,5,402,565,359,248,402,978,894,95,467,447,111,88,835,19,74,189,896,822,226,544,580,500,148,63,863,131,522,468,27,525,964,111,581,849,39,719,370,604,299,607,811,557,221,308,993,675,505,476,88,263,233,225,341,247,25,252,880,407,428,981,711,714,439,298,772,83,336,320,417,969,373,957,167,440,331,733,595,185,272,598,194,904,605,973,724,418,138,242,635,975,146,993,779,102,321,647,929,193,937,862,908,450,929,973,452,436,191,610,280,462,185,119,138,911,667,378,416,150,330,593,416,124,777,975,465,954,323,879,411,480,931,808,328,948,43,274,54,830,919,397,713,499,321,675,729,992,513,218,218,280,884,117,958,472,775,180,987,862,676,31,6,347,432,434,155,803,658,248,954,804,929,564,830,301,237,104,46,375,766,915,57,591,498,985,112,246,280,16,887,44,364,702,479,458,513,166,139,614,968,449,862,24,151,24,255,685,811,779,827,988,766,156,235,912,161,161,379,527,76,19,353,151,611,928,446", "348,894,610,134,417,956,555,926,878,411,666,797,147,815,603,348,925,530,111,297,329,161,685,784,265,450,881,910,690,35,872,55,854,78,499,578,128,731,811,194,241,993,838,355,609,477,325,653,73,319,271,214,663,658,876,140,153,734,536,228,167,890,767,86,797,280,767,681,509,459,345,207,28,88,262,75,76,732,509,807,666,315,281,465,384,880,857,515,385,546,468,224,104,576,987,14,173,253,159,583,648,175,136,876,353,629,509,428,311,965,617,874,618,138,880,194,127,773,565,525,389,983,35,705,708,286,781,846,864,150,197,907,593,215,657,21,536,526,655,352,105,761,645,697,946,926,500,680,993,2,810,437,946,198,15,918,667,721,238,389,659,756,1000,310,859,815,877,123,417,577,117,108,53,388,167,101,208,242,752,816,967,583,595,577,318,220,32,980,469,795,857,327,65,4,966,84,164,472,58,748,864,246,421,390,24,582,141,491,794,65,366,374,650,352,147,896,268,611,719,827,735,184,138,912,971,857,676,151,125,882,452,998,61,826,762,703,225,292,10,892,585,960,260,29,561,517,194,369,256,590,356,368,887,423,832,705,933,836,697,890,338,831,93,968,778,605,574,155,722,645,901,585,384,857,520,667,382,807,101,922,313,714,381,714,134,771,209,506,316,538,113,290,355,950,64,676,880,98,106,679,877,876,647,314,651,591,23,632,856,906,276,452,988,80,166,574,333,927,704,457,641,499,234,386,919,517,113,663,945,538,521,876,366,232,955,805,903,962,617,702,859,983,190,545,591,968,323,818,495,804,806,803,917,409,953,727,804,466,874,383,170,836,186,195,746,968,384,434,952,694,908,433,725,17,564,687,274,274,872,702,650,199,74,505,826,923,303,104,14,105,728,478,392,663,884,53,543,293,517,668,391,179,325,296,786,175,746,387,644,179,487,670,427,255,896,863,211,799,431,414,376,919,106,765,147,122,360,674,722,71,109,356,232,664,161,589,663,170,69,568,998,942,808,232,300,128,872,957,968,233,823,218,312,119,232,369,274,692,397,847,629,92,102,744,103,254,296,967,243,425,537,684,692,5,481,264,300,26,468,438,455,205,440,439,940,863,160,611,265,639,271,646,675,486,795,71,515,881,328,346,46,752,174,414,15,623,3,575,180,450,507,184,46,819,304,875,495,897,295,867,610,254,951,559,673,351,664,711,722,871,665,255,598,560,765,790,589,981,843,464,772,215,565,448,817,819,685,925,584,887,808,962,60,509,32,405,627,387,385,623,405,645,117,0,896,203,883,544,286,954,764,382,231,34,576,827,839,835,151,442,768,934,818,905,89,831,646,66,25,191,67,835,447,705,554,798,182,568,312,938,446,778,425,481,92,174,630,856,371,564,799,116,477,33,260,208,60,25,281,826,108,319,916,211,536,423,728,158,563,143,419,18,943,115,633,46,840,136,653,362,937,561,243,827,793,798,682,838,181,355,360,818,974,926,739,302,102,834,251,393,285,144,265,945,836,321,754,358,318,999,971,486,960,940,463,583,750,204,346,627,989,494,907,898,262,508,411,327,568,653,892,379,970,200,271,793,887,983,380,606,417,10,590,206,400,781,550,471,679,638,41,586,966,914,887,188,116,690,724,195,307,785,716,804,33,57,143,409,757,5,776,863,748,204,262,545,628,997,882,127,758,522,794,126,525,404,719,152,240,536,846,541,237,756,587,560,582,414,204,785,66,950,413,95,419,636,710,698,203,133,51,103,143,59,548,531,432,993,573,567,555,693,595,253,496,197,490,650,603,650,408,762,315,405,438,183,362,469,420,31,660,513,352,997,728,445,995,219,873,254,715,886,857,359,263,20,617,64,103,60,456,470,999,265,557,410,930,73,664,974,994,369,761,50,358,589,153,485,3,506,770,359,986,503,273,782,670,305,286,862,245,630,387,26,998,328,439,153,811,845,378,162,593,448,698,244,866,775,440,469,610,701,115,379,323,509,155,287,934,490,7,355,668,909,187,742,369,557,849,434,356,523,998,207,590,531,20,159,973,76,983,824,957,289,941,130,109,374,71,589,209,906,757,852,833,896,36,740,960,150,606,885,657,139,566,931,637,201,645,384,449,702,525,107,147,577,236,95,325,529,820,847,883,906,432,229,366,626,822,622,685,259,950,814,30,537,500,412,207,834,349,630,267,212,677,731,808,507,934,202,141,222,783,32,288,965,433,703,669,633,926,692,135,867,215,43,721,559,414,735,317,117,829,208,729,158,5,943,277,972", "296,513,957,926,419,426,88,400,751,221,551,247,807,936,189,339,411,614,454,273,597,306,473,238,223,766,789,144,184,706,960,126,791,936,831,783,670,658,908,746,639,81,638,702,869,71,570,183,243,228,768,42,173,984,809,558,768,342,364,641,76,710,804,671,323,978,854,889,94,328,382,132,851,825,586,596,274,439,560,792,858,450,57,190,316,551,784,112,423,998,546,934,56,560,499,343,705,47,124,8,547,126,606,846,8,157,226,468,194,80,858,79,264,165,323,499,389,628,56,285,415,95,784,772,35,182,469,377,868,477,872,993,727,46,616,221,24,553,570,150,118,693,220,770,585,413,838,213,775,427,471,64,546,968,96,61,526,451,935,613,512,853,330,604,42,103,722,917,995,763,592,984,45,845,756,544,730,704,102,353,647,623,929,594,629,196,202,908,986,594,650,628,187,822,454,513,234,493,130,598,886,832,978,696,398,426,779,575,294,713,859,912,989,595,333,183,30,207,368,459,111,398,259,798,383,303,294,440,286,645,53,60,971,512,453,744,261,211,711,910,444,152,243,708,987,8,787,612,779,497,577,898,373,882,89,97,584,426,988,567,224,219,845,461,244,844,532,650,724,287,801,759,824,814,697,566,502,738,107,842,642,757,614,487,394,255,485,368,182,608,248,169,164,836,218,430,154,779,738,201,439,365,967,225,477,824,490,692,824,428,864,388,543,680,921,658,523,821,604,678,508,528,173,567,511,696,439,360,880,672,81,266,620,775,531,226,933,944,497,975,448,364,723,298,86,62,911,204,450,292,930,408,706,774,105,891,361,936,828,452,847,556,125,300,700,969,612,601,519,474,762,49,703,788,228,721,570,359,834,179,727,237,640,126,682,268,101,972,769,206,772,864,924,858,942,249,788,19,351,104,515,850,457,314,938,956,324,891,154,10,190,464,948,35,590,458,883,576,786,443,870,419,396,924,645,315,209,717,76,422,685,903,999,465,713,565,369,834,735,13,603,692,837,669,650,308,218,610,325,424,731,123,928,313,799,945,726,412,667,215,930,743,726,145,16,821,432,17,978,525,601,734,237,298,814,262,663,290,464,553,275,59,750,886,390,425,374,406,211,716,653,460,279,242,997,33,211,719,128,958,161,695,589,302,580,459,766,403,136,368,312,340,617,741,344,624,166,104,508,792,884,426,552,565,866,227,387,301,308,380,164,799,901,592,471,859,606,297,954,682,611,177,455,469,746,737,965,573,692,556,470,850,860,84,251,676,444,436,321,573,16,876,652,896,0,113,972,954,50,558,584,635,879,203,157,861,995,771,670,510,171,17,387,921,551,104,639,861,562,111,632,123,716,457,65,952,245,833,869,896,622,349,883,217,606,689,500,121,938,563,744,870,650,831,998,975,23,51,527,314,235,50,724,692,968,855,602,323,548,962,128,68,829,767,700,157,613,710,658,695,219,546,226,930,71,967,370,981,511,895,898,719,833,518,751,687,468,187,844,19,806,106,999,594,844,957,886,113,700,308,762,775,788,890,652,227,155,111,702,651,302,940,149,376,628,412,895,619,577,679,464,155,695,39,292,188,709,875,867,952,494,299,107,125,905,897,423,160,955,126,890,885,301,430,41,614,961,735,780,297,935,211,748,863,454,661,489,329,395,727,832,347,721,861,830,382,404,130,51,124,74,660,854,886,980,173,84,862,60,30,736,649,565,928,377,832,125,974,103,459,971,575,963,947,608,989,939,117,930,926,675,865,52,964,942,812,627,268,538,277,980,127,642,391,26,836,937,424,888,724,74,575,24,411,197,790,268,69,608,296,366,357,999,231,205,995,746,798,375,121,304,78,48,707,139,108,338,329,877,468,902,994,974,671,947,274,831,809,70,986,848,805,231,447,58,279,373,655,235,190,99,659,896,431,203,884,220,300,710,705,368,318,703,670,415,311,627,793,234,278,54,457,578,615,29,289,71,109,551,221,329,716,204,88,430,444,3,91,510,321,518,910,268,804,432,749,811,97,252,800,894,150,516,322,582,741,491,592,362,622,604,395,797,72,161,481,486,138,795,481,379,28,338,949,620,34,181,988,291,785,439,979,237,287,10,662,289,477,914,251,854,253,275,832,418,326,794,373,702,747,824,591,520,592,989,415,857,477,310,749,241,922,143,782,67,180,843,64,154,533,891,658,166,466,736,295,81,724,784,974,932,465,868,58,973,312,528,236,498,354,410,438,160,642,575,322,490,234,271,214,232,912,628,917,695,336,413,109,108,551", "472,352,696,103,971,241,41,169,825,23,158,352,230,460,487,469,920,208,476,733,724,831,48,248,598,23,820,655,611,520,168,426,102,480,942,511,546,875,116,14,300,670,790,499,21,656,976,749,429,527,666,415,425,944,597,54,254,887,227,738,604,534,194,970,196,393,365,83,281,716,115,980,99,366,247,200,908,635,326,704,866,790,281,173,202,899,149,624,14,678,114,312,905,311,625,615,867,145,595,420,342,675,137,661,689,963,235,274,528,816,289,610,821,415,364,90,79,71,372,154,503,727,189,927,323,522,858,235,834,19,395,798,875,206,902,257,357,20,568,481,429,631,400,831,333,404,79,821,768,604,68,718,428,363,882,477,720,34,737,179,449,719,650,745,810,478,349,443,424,563,32,287,724,418,966,583,304,42,765,380,206,356,173,438,746,688,122,674,784,208,996,568,893,865,670,768,50,971,147,728,920,867,347,196,221,293,497,992,350,633,498,339,610,893,948,334,849,41,630,403,556,869,624,129,579,484,774,263,605,948,510,221,108,910,877,630,295,45,729,957,602,914,461,870,369,848,112,763,422,176,576,98,688,860,25,596,14,448,545,265,496,628,53,364,60,617,828,980,26,398,520,964,36,654,47,603,771,186,591,61,752,59,446,202,220,233,72,321,801,31,993,52,356,32,664,514,388,589,138,427,266,368,348,157,113,904,666,341,972,827,737,376,920,365,231,476,370,384,892,311,854,621,716,591,451,916,162,600,84,428,584,26,554,509,917,532,397,812,942,130,432,12,816,832,868,979,61,515,705,542,473,200,571,571,703,283,593,774,645,616,915,212,550,884,994,794,167,805,365,803,791,701,140,204,530,115,978,906,440,138,175,620,113,653,748,802,117,958,538,470,310,947,266,47,464,273,230,746,630,194,585,573,641,561,970,58,63,772,355,815,638,87,441,613,382,859,528,963,384,824,70,547,988,771,251,509,724,730,176,663,102,961,261,164,716,719,832,924,348,741,729,714,296,756,829,854,61,516,723,402,370,568,477,240,681,231,889,802,502,59,310,583,179,356,215,91,566,960,156,516,496,620,239,177,63,978,268,732,397,363,680,479,449,382,407,778,176,980,781,832,635,120,848,106,595,23,663,930,456,446,155,548,565,315,354,721,619,520,111,487,96,112,62,360,807,181,15,425,198,998,722,499,222,974,634,233,277,331,193,880,721,612,584,968,767,144,557,745,658,705,743,690,209,868,816,4,523,115,378,701,479,537,185,65,740,827,43,709,651,325,221,269,697,203,113,0,264,58,864,442,855,756,308,941,567,604,633,109,973,583,259,591,12,496,365,608,518,614,672,381,763,782,372,914,697,319,228,271,114,524,124,374,92,534,242,80,832,867,893,356,477,115,442,62,910,944,931,873,354,735,364,942,421,995,281,3,77,26,729,219,621,841,73,661,428,810,314,334,253,131,4,830,285,93,169,108,924,789,921,318,17,942,138,925,526,651,860,664,517,629,615,913,695,283,699,579,372,250,74,802,418,783,592,95,934,709,712,730,822,64,904,521,442,102,631,274,692,640,331,714,962,704,241,50,1000,362,481,831,646,813,689,73,722,874,936,478,342,694,454,593,208,399,239,355,96,677,293,523,946,943,600,145,195,418,70,205,888,142,332,867,868,250,914,825,664,550,463,161,610,804,669,619,287,297,185,313,10,684,441,791,874,481,859,372,874,494,450,622,602,930,328,761,161,870,546,820,435,887,756,489,337,481,351,269,919,109,757,178,991,370,335,144,6,996,557,392,339,404,382,57,452,529,23,793,301,260,72,852,463,466,163,627,15,264,412,928,606,31,235,243,630,425,872,68,588,561,518,898,53,966,530,640,368,194,538,628,804,402,204,549,970,273,960,864,892,851,676,876,701,281,615,564,811,104,904,425,873,10,451,59,741,766,954,64,496,630,195,198,651,435,592,383,277,508,168,733,490,747,734,106,702,786,407,675,763,166,554,21,14,713,218,392,590,858,440,513,134,311,344,556,193,180,921,82,795,316,352,72,238,949,400,714,180,745,429,338,317,890,303,4,826,112,69,463,570,682,203,648,165,649,286,397,255,792,424,841,320,531,81,7,98,492,92,359,894,829,222,772,398,439,92,673,601,47,179,509,825,370,168,604,366,664,315,685,756,171,260,993,501,93,717,211,578,389,119,362,344,575,612,991,658,900,880,623,928,800,981,908,201,44,848,292,722,985,491,276,950,859,359,369,635,8,428,756,427,623,412,97,418,486", "951,630,505,578,269,20,663,612,756,829,72,651,875,313,510,458,674,823,201,132,591,386,891,108,249,793,165,415,386,574,349,82,504,436,994,699,646,259,852,236,164,918,164,140,483,610,19,672,827,964,986,293,887,179,117,463,228,348,1,592,434,985,297,728,995,153,125,50,17,557,575,222,393,804,369,497,567,278,525,857,440,759,812,667,594,542,221,389,178,418,673,884,614,978,841,909,613,839,914,808,413,430,37,654,515,181,522,447,834,13,828,274,507,465,743,7,504,529,670,107,403,304,446,873,549,209,582,501,272,249,653,145,990,860,887,731,510,830,267,334,322,580,276,200,126,405,334,341,169,743,720,283,966,922,943,582,190,155,619,306,650,459,119,404,404,365,656,462,307,902,88,778,865,878,296,248,706,665,165,226,932,232,840,849,595,524,50,735,762,796,66,600,599,516,408,439,737,157,631,115,627,475,316,237,386,316,229,696,206,423,595,554,234,511,963,893,789,505,786,712,749,207,786,316,271,316,454,208,563,484,270,139,985,302,308,685,789,78,512,490,233,717,968,160,708,724,342,622,13,177,544,125,101,398,286,440,411,354,856,207,251,815,158,538,319,310,893,654,893,470,308,586,68,896,312,51,919,97,790,567,557,297,39,652,686,900,797,140,508,120,500,484,854,928,159,136,883,226,97,519,625,746,93,214,157,913,726,67,6,753,913,613,282,757,483,665,782,765,620,113,175,973,922,843,210,718,187,441,349,458,894,814,344,531,453,396,419,766,526,645,600,787,711,709,658,795,101,513,887,274,256,272,864,134,720,315,24,883,927,499,923,941,176,371,956,752,221,992,573,393,508,842,10,499,607,952,422,481,116,167,427,568,855,784,47,245,449,695,816,380,602,414,863,255,827,190,943,432,233,402,37,618,359,558,644,357,705,125,96,686,299,673,531,679,170,69,261,961,451,127,209,780,617,91,242,340,599,132,210,835,486,251,232,718,862,984,474,997,701,299,396,209,56,580,268,594,592,798,398,734,352,337,135,242,979,180,565,555,717,205,876,669,887,256,263,848,704,485,952,650,147,562,553,872,34,340,33,605,148,594,419,760,736,345,703,80,15,547,776,16,247,382,299,961,716,257,372,324,82,617,594,630,747,877,455,449,882,430,400,117,727,171,943,710,682,130,627,496,567,242,752,103,442,986,3,704,470,901,110,522,789,830,633,72,770,918,452,297,614,95,49,484,816,609,210,442,850,85,983,261,528,656,68,189,598,707,364,238,94,596,70,967,443,883,972,264,0,93,76,850,220,96,750,521,393,618,268,500,39,335,943,656,71,703,362,806,858,212,848,573,602,248,105,987,630,528,124,693,693,24,566,148,425,314,775,606,233,425,926,516,62,301,883,945,456,73,536,707,240,470,254,160,926,703,825,122,581,792,425,798,102,227,387,157,941,332,154,526,978,836,355,600,151,893,744,621,628,460,670,562,248,34,965,550,529,69,724,164,252,244,288,345,866,655,957,741,85,945,815,334,603,887,839,375,489,628,580,280,949,437,733,353,411,783,467,506,73,487,886,204,802,462,382,833,912,697,144,838,444,47,212,245,760,760,760,38,444,401,676,936,285,444,610,387,830,930,301,116,753,120,40,463,308,57,341,726,266,283,55,804,639,580,898,693,544,526,579,99,849,61,285,923,634,340,6,182,612,716,184,114,175,795,29,396,671,621,380,795,134,214,128,498,877,686,122,680,691,402,251,536,640,183,667,176,754,511,921,793,523,765,11,580,372,205,405,112,511,126,262,377,430,440,289,208,662,581,746,950,59,438,807,544,21,120,240,55,185,178,815,515,977,856,934,796,773,113,818,540,939,103,364,389,912,210,18,976,600,885,862,644,633,691,208,546,436,653,931,766,362,125,841,318,529,37,662,696,514,606,327,40,847,454,79,320,777,307,421,256,907,422,569,335,310,223,770,322,309,852,687,168,453,439,298,908,589,407,721,605,34,356,983,772,342,211,206,619,738,950,191,236,709,288,438,48,714,199,751,381,75,389,670,99,94,368,667,235,933,318,802,519,376,249,850,863,112,914,768,325,783,266,684,694,907,679,688,107,228,395,923,365,109,850,780,821,488,450,146,967,996,806,185,89,413,274,673,9,615,244,859,752,87,500,575,497,141,793,762,507,508,326,903,13,601,291,633,821,824,316,543,541,325,936,677,121,678,68,202,800,132,507,973,824,765,470,61,77,772,415,595,29,947,825,374,339,531,456,108,76,287,13", "117,460,533,97,858,569,150,600,957,125,20,104,996,990,380,602,411,908,110,468,157,128,652,228,949,838,14,601,817,896,230,616,718,932,702,267,742,629,167,380,580,152,560,405,175,427,950,185,481,731,947,641,64,611,393,574,793,968,777,964,225,602,81,726,390,556,138,201,525,443,271,453,69,127,961,704,186,345,99,375,798,273,915,422,788,715,834,55,39,596,798,509,822,688,838,125,991,311,294,712,164,970,163,902,436,554,215,828,497,802,889,787,710,75,553,626,52,233,985,557,377,707,316,963,640,235,796,689,211,730,838,601,764,96,753,641,8,366,342,843,429,465,810,57,758,298,305,314,588,814,186,548,292,84,848,729,540,809,94,139,38,236,404,587,756,402,610,89,913,183,320,615,611,608,622,939,100,264,246,186,238,816,984,121,271,365,326,139,685,708,76,434,631,655,608,337,981,483,485,136,699,745,654,800,202,663,960,437,172,259,678,357,635,74,541,921,313,881,782,767,469,873,22,209,278,205,675,490,101,313,966,226,258,18,909,866,841,234,791,575,223,189,954,37,632,565,191,813,674,59,97,284,743,416,547,784,150,820,866,680,64,414,10,686,518,275,308,676,568,641,545,940,581,526,419,774,438,530,24,68,873,160,907,408,926,998,450,208,671,875,362,213,832,410,250,82,177,599,334,461,150,329,591,420,569,370,858,866,814,848,989,111,401,424,811,368,96,894,802,333,332,508,612,278,794,472,193,760,239,655,98,809,740,766,448,975,949,445,579,778,833,106,932,395,945,725,752,54,781,887,121,51,902,525,333,216,876,894,4,86,694,144,639,158,898,180,804,167,268,744,533,484,857,673,20,498,618,865,930,992,11,503,259,169,418,19,16,529,166,26,73,667,455,15,782,279,12,22,973,636,102,438,469,871,639,728,899,490,365,667,692,256,667,445,121,728,341,563,402,215,43,839,289,57,324,907,585,597,72,981,373,941,588,796,777,437,650,505,75,677,658,791,269,368,71,285,148,306,818,547,19,822,745,949,934,352,45,938,546,35,14,616,962,295,304,386,297,171,556,701,449,88,632,51,30,168,183,744,58,126,68,512,472,707,972,516,136,52,178,88,941,484,218,679,419,952,270,246,92,668,162,560,322,578,364,871,444,613,204,175,983,564,259,492,280,265,637,516,824,674,690,970,889,247,530,222,594,419,480,143,361,459,754,200,188,782,922,233,276,437,337,651,882,973,3,292,93,772,247,880,64,458,680,989,458,43,501,704,681,825,153,978,55,544,954,58,93,0,55,698,856,36,443,109,404,864,991,13,327,212,854,535,823,21,115,504,842,415,396,827,202,413,342,532,777,339,167,166,975,272,175,964,416,599,824,206,886,244,681,899,408,401,427,984,555,796,525,648,488,635,365,14,747,427,61,106,160,180,168,736,388,30,370,303,759,830,888,551,833,655,82,744,87,588,225,74,482,341,302,447,460,799,756,277,236,59,504,129,556,392,798,11,310,278,352,634,865,282,475,476,558,26,240,699,150,769,259,205,262,755,281,622,860,823,563,24,846,902,28,107,216,987,947,186,164,762,501,448,456,772,44,709,633,854,951,776,283,566,654,257,775,49,246,671,489,543,361,4,124,725,806,489,814,668,7,457,954,879,428,730,539,909,117,315,945,329,768,690,844,658,84,66,688,356,738,558,442,865,908,527,33,594,534,269,519,477,35,315,203,15,66,963,574,583,93,319,495,102,832,845,562,577,867,866,721,268,139,776,491,61,136,444,372,820,596,622,735,50,138,445,683,567,629,863,45,462,308,155,106,48,180,740,357,243,449,737,969,156,594,28,491,110,267,370,168,943,965,471,444,529,416,453,380,462,75,17,83,469,382,376,176,445,273,851,274,41,610,992,707,85,44,126,344,58,762,549,847,333,280,130,571,464,244,717,907,667,162,866,353,384,669,102,39,210,494,490,621,795,95,501,456,231,377,319,742,8,831,922,544,976,934,157,187,247,272,418,874,568,642,836,448,425,295,453,995,549,152,192,807,185,691,235,294,267,888,499,533,936,273,927,945,682,795,704,966,537,78,705,570,886,522,982,117,232,508,509,683,732,674,838,146,236,706,622,919,355,78,146,218,725,349,876,788,877,151,740,935,13,722,940,841,42,216,671,173,319,278,382,68,576,509,273,389,274,87,93,785,264,615,125,80,43,877,235,259,54,962,178,547,224,612,181,818,633,52,927,163,357,552,145,795,337,4,300,770,816,813,806,142,629", "464,511,884,905,28,828,13,322,821,549,631,462,189,157,658,340,169,547,299,710,445,163,412,498,436,862,198,118,209,259,946,61,392,323,441,596,320,757,859,892,92,955,476,273,944,635,172,586,319,251,272,390,57,565,858,967,756,767,442,861,875,870,760,548,36,769,593,948,911,175,312,209,913,875,125,905,947,380,69,506,226,222,376,449,135,146,737,782,811,337,858,456,376,965,62,166,525,598,624,404,678,265,612,903,991,966,304,912,137,87,337,35,746,152,969,207,66,562,744,391,681,146,970,458,730,778,869,16,152,734,806,353,748,570,775,925,933,36,164,557,714,870,39,505,645,661,301,591,738,564,154,435,649,888,240,553,289,635,707,453,978,758,174,775,272,573,703,284,412,558,498,168,697,672,517,643,123,301,118,525,289,539,900,375,602,833,935,268,17,670,110,504,8,459,395,183,391,30,960,257,294,480,381,685,362,920,184,8,646,510,101,973,17,664,4,841,751,123,558,460,433,606,706,399,549,193,595,609,291,449,152,836,760,948,383,894,429,549,473,580,122,293,305,232,883,679,927,151,194,966,850,690,933,228,286,833,873,949,72,95,418,327,308,196,811,334,394,608,775,240,493,457,164,619,673,53,404,917,233,46,711,35,646,455,683,996,842,743,249,215,700,576,580,570,661,282,255,234,443,892,230,129,972,620,930,120,119,283,682,325,468,2,652,374,313,740,92,332,708,702,56,270,721,463,445,39,761,125,846,509,336,302,109,938,192,437,3,103,291,946,97,86,793,645,351,854,909,231,923,439,986,910,181,446,682,762,663,822,719,777,702,311,323,122,598,265,457,129,256,994,472,167,876,843,164,181,191,317,135,399,373,235,523,613,679,675,310,346,503,781,806,111,669,551,227,49,4,909,201,181,611,871,359,189,13,927,663,503,925,834,625,972,870,443,199,606,568,834,204,672,41,539,317,957,677,830,221,841,385,826,989,844,246,338,755,293,241,218,616,386,843,194,783,154,623,23,929,571,454,512,1000,648,996,826,380,111,387,346,996,503,113,129,354,368,164,219,230,638,267,219,245,515,94,549,77,851,41,230,275,401,681,747,403,792,979,427,682,280,254,356,56,440,930,854,832,182,305,912,271,744,546,426,558,734,374,546,424,682,105,729,989,976,669,584,746,61,488,392,298,115,115,462,699,242,415,227,297,888,410,310,746,266,375,340,355,610,436,183,87,163,491,563,746,465,800,14,632,335,284,362,28,986,687,661,962,167,642,730,69,484,35,15,905,286,50,864,76,55,0,482,19,958,571,324,25,29,249,561,240,725,349,257,624,914,93,706,626,582,963,552,264,490,24,450,741,906,645,671,997,762,553,531,268,191,166,572,324,460,806,424,690,866,46,252,995,603,790,395,84,331,281,572,677,194,459,715,410,496,14,204,66,972,781,412,312,194,505,250,106,701,549,83,437,361,644,300,729,241,976,98,699,205,925,819,909,997,347,67,666,903,13,42,50,961,171,641,632,977,22,611,59,163,52,965,104,974,69,210,44,560,98,564,175,11,874,788,275,500,689,764,112,525,780,498,691,565,341,678,995,390,372,236,48,913,241,985,787,367,926,617,257,642,323,458,196,27,468,224,506,197,839,576,726,135,491,901,34,774,775,241,167,700,447,58,257,793,407,225,968,353,117,316,185,738,701,909,592,356,791,111,842,306,347,327,476,325,603,705,477,378,679,857,938,498,974,582,122,225,774,801,691,227,197,170,600,613,199,485,843,34,302,478,971,33,37,253,942,392,633,824,406,45,869,923,546,548,548,268,861,292,565,955,580,994,708,920,940,59,6,191,445,300,388,254,454,395,651,171,309,59,665,960,8,733,600,706,915,73,342,167,213,577,114,735,545,123,392,662,275,29,298,191,941,876,471,958,44,889,184,811,158,52,356,609,189,706,794,96,56,626,837,600,529,764,333,274,61,943,206,534,6,965,96,241,746,674,770,917,688,449,390,35,102,260,423,596,252,660,276,659,285,625,126,160,221,662,721,950,213,476,227,828,343,206,595,943,284,607,917,445,407,514,651,886,729,52,443,350,989,664,448,386,395,634,839,800,660,819,623,440,992,73,235,789,55,192,134,216,470,561,889,342,209,94,866,171,629,427,910,607,955,431,466,257,242,132,247,350,668,909,586,734,131,169,235,590,607,77,142,378,641,501,977,585,280,410,797,525,33,102,887,302,517,245,552,780,826,633,44,858,132,396,111,549,455,527,706,91,586,649", "843,179,754,866,151,373,367,451,500,323,751,920,557,398,387,538,633,116,913,80,470,471,144,337,759,322,405,119,114,367,945,263,651,306,811,914,410,78,439,395,412,464,69,426,591,946,454,411,43,893,697,830,76,208,628,869,341,675,527,445,790,305,490,558,308,254,635,884,686,237,501,346,999,280,260,135,970,781,57,400,299,830,612,248,453,17,799,602,409,944,34,32,460,337,639,527,700,106,924,793,877,895,524,396,386,496,793,253,518,49,326,701,905,129,153,675,674,124,349,937,849,167,135,118,251,281,818,522,945,744,190,327,431,477,334,479,842,311,239,462,175,299,560,958,719,253,190,738,930,84,75,190,973,202,743,493,599,326,950,558,969,407,707,918,68,601,71,907,142,966,461,391,660,29,135,607,671,989,488,495,435,926,496,539,14,244,77,740,373,221,359,286,584,54,24,919,365,542,493,517,768,709,807,134,752,126,595,100,867,289,278,632,314,606,40,548,730,350,569,780,879,756,377,261,930,296,709,971,707,566,432,964,536,131,967,234,301,79,987,506,920,401,244,718,75,645,365,633,383,404,695,822,944,861,910,406,535,288,328,701,178,588,687,321,643,781,787,634,804,202,13,465,749,422,216,357,604,753,331,693,358,288,869,352,44,212,407,283,558,792,846,173,36,562,907,866,240,250,115,623,534,618,160,567,922,255,978,666,547,252,944,544,123,153,259,943,259,336,24,527,509,169,304,515,262,596,909,454,746,187,432,293,886,822,547,874,350,352,899,564,663,105,708,402,902,513,241,583,927,722,456,956,326,549,627,522,391,465,870,261,567,161,481,242,766,575,868,718,642,807,289,897,620,965,759,351,715,311,563,756,527,707,140,229,619,533,841,681,145,309,444,890,415,72,952,660,663,199,810,258,616,723,538,98,438,295,81,320,799,907,384,997,94,958,13,164,874,557,975,517,577,881,19,468,489,872,278,438,263,287,504,903,442,373,101,808,710,827,985,739,988,768,657,890,487,55,915,90,395,36,652,397,933,67,925,36,476,765,585,446,641,391,170,469,459,729,676,270,124,563,813,276,977,193,594,151,953,173,93,774,608,939,684,856,645,222,10,545,519,212,349,49,412,969,562,274,471,738,755,473,921,35,491,883,493,371,355,327,259,25,912,543,836,228,915,97,465,948,902,729,488,132,761,564,93,645,925,599,763,711,3,602,343,511,383,923,597,163,306,681,111,451,613,692,446,641,391,651,803,110,432,789,593,387,56,164,460,179,827,626,905,621,214,954,558,442,850,698,482,0,989,42,987,341,757,112,143,220,800,624,536,355,325,630,168,635,702,873,577,617,881,224,949,834,152,249,336,847,386,866,278,265,493,585,851,946,256,21,746,182,131,587,901,743,375,472,489,705,989,909,757,338,491,466,538,53,773,961,544,411,397,657,790,736,143,868,336,765,288,383,504,926,820,152,811,804,104,640,757,884,732,944,318,323,253,958,761,807,734,759,59,788,436,448,9,244,284,977,641,748,562,274,484,58,368,814,406,752,711,677,29,285,501,292,46,57,846,167,241,454,512,245,894,802,436,638,352,970,270,913,8,987,64,431,513,468,95,534,158,382,291,334,630,344,504,820,290,360,267,910,372,397,167,436,307,429,963,457,69,977,79,679,816,713,327,130,78,992,507,353,482,146,543,941,188,794,814,47,878,865,876,694,973,118,892,484,411,204,962,780,810,649,992,607,592,398,394,448,560,968,384,815,875,2,261,88,221,828,404,707,988,849,789,251,904,478,109,347,84,626,85,893,157,901,666,223,932,153,966,3,370,549,335,437,665,44,787,626,244,694,185,476,259,547,452,799,385,615,890,567,928,71,834,662,493,30,56,235,430,397,960,247,616,402,591,226,448,153,422,204,547,529,695,800,510,302,199,523,175,720,565,999,507,971,932,167,702,34,591,803,91,34,647,694,148,292,367,831,465,686,922,816,426,351,913,77,688,31,974,923,432,802,601,818,726,873,56,961,685,78,206,821,228,474,814,948,789,134,267,149,633,184,586,400,515,324,848,201,974,372,280,827,224,743,766,299,525,587,215,340,401,207,817,630,68,970,10,587,148,908,289,465,728,997,361,850,512,1000,704,31,902,189,497,951,598,292,878,288,605,294,551,581,738,491,583,981,94,287,988,217,902,726,574,765,748,537,503,557,525,221,989,790,281,273,600,398,210,631,601,261,230,726,647,124,278,80,206,184,403,956,836,53,807,661,701,861,957,515,579,769", "96,419,968,443,504,843,747,321,192,190,43,821,149,678,774,551,900,922,395,408,648,525,371,609,498,454,968,470,104,527,874,498,838,117,71,227,70,873,736,785,187,108,121,337,765,521,831,661,561,671,125,161,201,303,363,640,83,667,334,806,192,846,953,97,24,125,436,477,386,899,827,288,261,495,953,429,38,239,370,522,736,495,684,224,317,373,328,73,329,584,244,713,668,806,511,75,868,267,681,504,644,152,309,948,716,126,709,628,117,928,806,707,678,733,648,164,735,209,628,340,826,48,779,122,497,852,912,249,402,271,322,132,129,898,68,815,793,645,403,127,871,831,923,133,473,452,175,582,83,473,895,989,953,963,68,994,893,919,839,930,963,114,451,506,325,957,988,572,236,741,523,412,754,410,226,767,188,532,417,279,754,922,994,315,963,338,229,30,184,993,274,96,38,414,845,434,788,140,498,215,323,579,262,55,936,936,759,235,698,64,216,813,107,810,177,953,720,139,923,903,102,125,456,276,438,505,722,204,19,394,287,254,263,398,317,478,863,119,91,195,373,447,145,206,659,689,170,710,506,319,153,10,381,596,418,623,200,32,862,868,527,926,345,936,526,5,985,433,43,430,171,378,802,531,467,426,208,506,178,916,627,74,220,452,285,808,28,403,266,962,693,271,256,10,780,350,435,114,234,727,955,871,761,869,681,278,828,70,862,942,30,886,747,528,225,276,343,592,75,750,474,774,396,864,900,933,859,672,647,166,208,236,440,264,858,913,450,750,221,514,901,466,445,413,190,991,992,706,182,137,526,646,486,944,51,642,992,922,690,933,110,759,376,892,74,968,814,763,940,305,966,895,227,107,625,119,685,867,363,143,147,631,911,1000,911,619,678,272,90,315,980,318,763,421,193,731,660,214,715,137,45,526,989,6,881,790,665,924,887,480,261,346,191,362,757,483,504,349,94,995,934,85,645,228,827,497,182,967,56,96,51,128,311,54,50,252,1000,751,985,711,319,99,794,789,683,824,382,577,824,24,891,19,4,874,796,738,376,96,836,180,534,628,80,585,927,803,872,44,728,825,636,861,906,776,413,123,446,121,118,212,313,820,995,778,225,986,686,911,522,190,443,561,928,374,927,241,713,833,113,11,125,903,468,605,276,606,123,9,103,675,362,357,378,579,669,839,18,366,535,489,444,133,993,789,816,67,410,871,167,360,876,164,927,653,871,506,445,302,614,451,820,824,656,726,965,298,882,198,895,76,959,247,454,178,716,469,498,760,642,349,464,73,198,764,584,855,220,856,19,989,0,449,969,248,763,642,153,981,88,784,257,296,426,362,193,49,952,113,935,509,535,950,811,530,432,62,120,948,702,943,471,878,956,576,399,984,231,366,952,269,226,248,653,802,738,977,325,532,990,183,321,444,38,225,508,191,246,608,99,73,296,325,373,996,598,39,111,401,441,289,249,837,466,457,386,430,569,360,792,383,829,406,308,735,846,539,836,466,964,361,297,977,614,432,829,570,377,22,363,73,814,32,728,720,338,264,176,439,61,253,931,469,462,585,685,623,152,47,843,804,96,989,680,427,668,189,545,256,329,737,35,105,724,140,39,385,550,927,10,428,554,457,32,325,294,301,954,282,199,103,963,79,484,7,237,492,560,720,976,737,416,149,325,679,900,7,177,141,274,13,779,721,878,331,99,788,10,845,943,955,986,466,801,751,776,322,164,421,44,426,55,841,462,543,640,827,687,238,386,684,796,155,489,69,356,463,12,29,638,953,359,251,672,950,925,188,888,14,248,610,712,228,922,459,47,68,575,507,307,716,725,80,434,834,681,781,714,162,469,314,606,499,934,842,673,673,713,681,623,367,48,263,556,310,450,863,981,758,515,637,474,936,595,649,543,9,652,829,416,211,109,714,153,357,32,932,574,515,727,973,256,824,710,15,374,616,60,986,202,616,699,560,96,379,297,816,339,652,784,621,556,702,8,617,275,924,262,82,659,674,998,710,47,44,916,598,839,60,428,470,75,155,662,477,536,36,959,806,183,29,601,610,164,250,671,566,649,414,305,948,90,78,473,825,724,860,83,511,448,515,773,691,704,598,764,728,960,388,855,563,656,411,420,246,854,140,70,52,577,926,794,509,921,787,794,889,462,501,686,663,472,860,261,529,677,676,491,490,532,285,316,99,705,494,624,832,156,660,684,123,200,78,171,962,544,751,384,22,741,564,890,306,469,333,408,979,88,954,110,719,781,73,391,661,732,339,113,897,670,60", "359,826,998,885,236,870,765,604,755,433,417,839,112,602,581,351,320,556,645,313,505,559,340,561,687,516,908,559,750,423,999,640,406,771,596,977,555,97,234,622,562,32,756,661,301,363,487,408,835,283,863,517,303,644,413,370,427,468,106,951,457,423,522,798,258,842,503,847,557,95,935,208,677,4,32,117,609,336,956,218,675,455,504,820,509,231,752,74,496,159,486,574,937,385,303,261,602,773,81,209,598,519,756,13,483,77,794,547,133,638,485,765,97,815,4,24,455,142,428,398,864,733,104,939,208,425,803,10,102,266,406,529,929,439,245,94,533,222,669,206,392,412,153,447,201,90,17,565,82,195,477,104,220,608,77,703,441,21,362,657,329,515,156,344,751,505,400,143,447,36,588,683,646,776,567,294,698,678,754,984,964,449,536,395,759,370,698,526,875,867,338,886,541,96,28,630,103,656,796,354,194,57,390,135,679,634,957,907,368,431,990,207,770,942,791,234,132,56,665,164,343,182,388,820,477,205,570,895,83,315,528,766,113,200,917,65,889,887,217,283,874,6,31,710,735,127,621,294,82,814,541,263,310,409,346,498,220,270,959,79,727,950,859,304,634,566,43,181,184,904,758,804,310,722,249,450,25,644,995,145,405,183,452,641,243,458,709,471,972,794,52,128,935,953,285,95,903,863,8,523,392,696,843,209,793,935,973,381,308,576,253,256,981,587,939,745,676,748,204,500,34,515,930,402,664,378,198,958,839,885,965,675,591,598,43,605,865,222,150,744,230,817,287,665,882,436,14,651,985,972,653,105,977,646,350,282,768,86,166,996,551,189,83,687,755,693,343,190,76,270,800,332,44,172,404,123,699,33,341,332,438,71,415,36,687,665,858,936,276,695,518,793,113,625,449,875,726,839,299,312,222,99,720,890,638,639,179,433,682,794,946,159,838,181,729,452,385,550,27,813,261,887,801,660,16,954,546,806,233,636,743,635,716,771,579,526,470,726,636,904,550,592,384,309,142,389,762,266,859,547,748,591,112,596,752,530,26,820,729,443,980,834,12,166,94,692,720,6,866,467,859,450,101,964,299,391,246,734,551,834,644,522,419,917,509,622,781,877,550,159,727,93,559,544,71,967,386,908,33,459,502,424,74,517,546,141,737,550,799,790,838,202,589,613,262,587,156,293,325,21,410,199,501,543,278,152,651,135,213,441,455,991,431,260,519,463,743,221,857,626,828,580,628,220,64,599,760,424,512,558,771,445,93,895,972,350,394,68,455,254,424,180,425,382,635,756,96,36,958,42,449,0,699,220,948,15,75,559,919,334,974,823,813,746,556,709,428,906,829,869,420,184,342,137,621,881,206,214,160,995,433,891,443,963,898,373,111,230,685,234,823,635,583,777,793,964,974,954,707,984,193,346,424,409,479,522,275,205,129,873,706,149,591,184,573,921,119,864,382,249,410,107,758,834,953,800,293,592,969,38,24,922,939,132,419,793,789,804,953,381,961,661,926,191,536,462,522,662,388,348,187,125,873,138,982,453,334,600,944,990,802,851,24,871,598,903,145,365,729,200,637,256,11,4,667,957,808,930,392,969,582,853,671,825,120,879,450,973,474,753,253,128,524,760,290,309,64,848,519,361,77,125,151,568,907,450,442,428,795,497,572,729,628,969,42,315,52,362,373,577,22,38,89,66,362,159,93,769,291,272,349,825,554,958,602,591,197,181,46,348,776,440,876,156,293,776,273,454,236,73,181,323,472,359,994,549,375,864,866,872,649,896,310,525,941,633,741,733,197,868,959,553,853,979,139,946,778,713,199,730,756,51,582,561,370,701,54,439,229,576,843,557,26,910,184,976,216,79,241,865,546,580,697,706,374,729,817,254,114,714,537,899,622,729,346,837,565,562,434,108,910,201,966,690,252,116,985,864,128,860,978,814,917,862,623,505,212,542,640,290,860,706,393,136,894,803,289,984,114,852,679,184,971,341,421,618,112,305,630,927,877,428,740,599,412,452,535,552,253,183,709,89,640,898,619,716,563,697,233,38,355,532,866,957,40,795,686,606,168,508,870,478,705,926,977,606,149,555,446,322,328,916,115,7,282,153,257,991,401,903,461,745,756,511,802,908,370,855,149,373,251,647,771,262,293,337,30,535,204,595,668,981,361,779,783,502,383,831,340,726,832,967,790,584,715,967,40,144,24,79,71,994,768,424,189,231,963,799,700,712,498,991,785,439,162,778,199,311,246,549,250,231,695,495,362,534,568,354,345,159", "945,155,994,11,19,284,810,201,582,957,60,926,359,814,252,450,953,811,329,768,820,730,384,604,749,90,921,500,810,781,22,987,764,400,95,995,689,37,936,200,509,60,53,551,737,873,146,93,672,241,889,319,488,461,654,273,172,215,361,880,896,771,614,34,690,62,318,886,730,601,144,688,991,869,581,684,467,192,952,841,715,884,419,1000,182,523,99,343,319,68,70,820,761,415,641,877,563,667,686,420,658,802,457,143,783,416,924,529,57,92,455,385,440,199,630,771,494,446,355,751,637,411,647,691,994,980,626,902,221,754,169,990,399,332,66,541,279,6,874,745,760,865,244,123,957,775,893,787,129,967,28,388,635,413,400,116,908,993,93,732,355,636,904,35,44,125,56,81,537,449,26,848,357,524,23,156,468,339,52,176,634,999,647,848,481,359,664,402,839,696,913,39,967,514,895,925,88,26,25,450,383,937,436,770,198,51,954,109,64,400,281,830,758,792,225,860,698,50,941,957,956,861,152,130,99,42,714,699,101,319,810,77,822,511,594,165,600,505,7,773,886,613,511,41,481,316,437,729,938,935,834,133,966,604,506,432,233,180,890,597,673,574,468,100,20,870,176,878,150,607,505,959,206,151,547,692,801,325,526,971,792,299,130,746,543,708,765,885,114,753,871,339,106,868,531,629,121,132,704,668,959,92,934,965,776,260,124,295,997,342,823,539,896,760,346,381,670,85,236,543,447,548,388,921,801,955,394,188,582,110,236,488,108,684,326,812,823,456,798,709,743,658,430,977,12,602,676,899,260,110,218,739,928,825,311,62,960,732,720,736,847,613,745,704,76,540,749,276,518,199,777,273,402,289,161,66,568,479,774,524,490,490,991,724,524,270,47,7,735,55,402,554,30,9,476,711,84,852,280,5,656,335,79,777,361,803,918,736,702,240,155,630,681,606,841,301,84,346,647,42,553,958,720,775,208,877,540,48,347,819,238,233,582,827,758,909,118,192,679,625,829,948,457,591,337,604,793,627,368,787,670,360,765,178,462,988,894,803,372,850,977,891,116,366,691,919,408,661,824,278,819,376,392,120,758,909,802,814,554,118,559,371,929,93,38,702,754,839,536,742,920,337,12,623,635,94,73,774,608,91,246,68,947,816,248,704,556,421,914,928,432,716,929,732,107,39,804,264,373,948,650,212,20,403,690,413,157,233,727,511,885,225,924,928,934,460,329,695,70,914,781,664,275,678,553,130,812,289,653,360,246,711,546,516,343,449,144,304,808,239,200,401,937,231,879,308,750,443,571,987,969,699,0,866,342,498,246,401,276,365,906,650,10,756,96,344,25,779,512,300,552,817,726,155,190,822,933,76,4,622,36,124,648,548,407,555,996,310,200,203,686,737,105,368,549,376,756,298,898,227,405,870,811,533,456,936,511,618,983,783,241,286,461,878,932,628,925,438,564,743,679,506,555,100,747,296,86,140,127,758,698,542,312,644,72,780,7,508,554,534,177,929,228,166,259,74,910,734,990,56,5,248,141,95,657,631,364,306,312,87,59,810,452,249,298,559,270,110,195,542,696,71,846,1,499,224,759,896,504,287,464,798,366,861,914,277,231,840,15,618,567,132,112,709,114,997,578,306,792,240,908,412,406,195,638,885,207,633,880,515,400,318,848,804,387,841,15,753,949,204,387,502,911,299,318,93,52,544,591,499,278,324,241,675,200,679,180,678,277,774,904,388,380,447,354,163,208,310,234,178,775,63,795,847,281,718,965,217,676,416,64,761,959,733,166,757,809,801,914,621,811,884,968,290,14,502,256,344,956,485,673,966,856,613,734,300,43,270,508,311,638,137,533,836,614,789,980,934,215,312,788,702,176,17,124,217,874,107,194,560,133,338,639,869,187,319,62,446,784,29,145,352,727,662,245,26,97,159,475,861,344,331,276,113,931,388,837,665,727,602,717,749,500,270,97,949,642,353,4,267,64,397,842,100,163,6,443,144,660,826,358,996,455,981,504,760,621,725,922,190,374,457,918,87,116,501,657,708,284,665,438,293,81,448,11,201,343,459,541,183,840,223,130,436,319,733,98,945,844,520,757,770,779,912,594,371,584,819,531,628,877,94,346,644,426,413,413,344,23,558,680,35,529,590,907,54,304,154,738,13,171,555,761,996,750,298,889,222,302,652,431,202,116,898,988,26,283,695,764,484,600,668,497,221,956,511,678,124,823,957,803,130,940,636,189,134,74,127,871,463,928,496,917,110,473,267,217,108,567,421", "388,584,214,984,941,246,952,733,653,530,954,871,521,881,192,417,777,866,580,384,454,179,759,176,51,960,869,161,599,387,914,630,28,187,586,513,298,817,457,19,790,243,385,794,252,144,646,62,109,719,439,753,794,985,781,633,137,503,895,819,932,603,843,834,542,333,618,607,788,289,569,881,868,228,322,634,602,559,153,759,677,620,406,638,585,947,947,699,482,580,696,676,751,615,778,366,875,731,842,617,668,373,805,290,508,837,92,239,203,843,854,299,933,547,205,767,351,525,794,135,936,48,443,613,753,848,417,172,249,568,578,717,885,40,650,312,589,976,781,395,648,467,583,647,801,563,696,157,399,688,723,895,669,553,121,915,758,152,839,830,628,320,700,56,460,67,712,25,164,510,789,594,499,491,2,118,956,158,736,474,15,59,952,979,270,651,39,288,367,96,687,321,272,225,171,837,455,491,126,542,498,668,796,703,366,367,217,89,871,96,363,551,911,143,953,706,293,247,457,670,250,637,257,607,314,33,220,709,910,416,783,182,501,651,241,584,233,817,708,814,65,790,668,913,727,63,924,896,21,413,147,911,129,215,69,630,961,11,525,274,392,137,314,558,916,213,540,512,522,673,105,868,946,115,398,922,914,39,472,177,889,12,332,863,843,943,455,94,989,532,826,429,28,391,960,225,100,933,122,812,663,874,585,209,795,546,474,936,388,299,988,827,117,282,140,850,399,147,365,832,723,254,621,821,863,952,256,643,584,441,783,270,978,125,595,491,193,733,947,945,343,700,804,429,299,860,371,959,831,78,636,700,941,569,117,477,522,206,616,217,550,111,294,595,572,461,597,779,739,568,50,941,883,522,863,496,871,615,140,741,383,42,399,56,64,146,645,964,517,632,793,839,491,303,370,907,888,87,515,405,172,493,663,897,304,996,246,351,646,262,927,688,878,855,363,450,36,311,380,810,963,220,470,388,7,907,665,345,702,301,848,736,782,384,780,381,889,178,382,516,932,472,316,622,87,391,914,550,107,22,457,60,472,449,369,312,589,16,438,464,202,353,889,929,222,379,606,833,493,49,747,17,726,818,400,588,913,471,342,915,340,794,10,167,877,913,818,839,420,901,787,764,967,553,912,320,412,326,729,983,498,15,808,570,221,204,873,800,126,769,16,858,185,367,870,396,322,799,788,371,264,998,467,471,212,503,512,606,354,548,764,819,426,643,56,765,271,799,960,738,989,381,893,20,621,250,606,628,807,915,982,337,48,234,550,151,941,91,651,237,572,562,103,34,203,941,521,109,324,341,248,220,866,0,788,477,767,731,705,795,813,918,886,608,344,450,381,81,494,255,647,800,706,639,515,940,725,697,967,772,811,314,636,922,396,982,363,17,749,648,488,839,519,390,432,871,993,795,710,40,637,334,86,399,147,54,919,240,454,229,833,534,983,811,360,590,762,100,976,950,309,392,357,553,545,682,815,478,716,456,318,304,33,953,961,349,549,449,582,483,894,91,827,396,303,290,578,769,614,140,468,357,533,161,731,280,542,118,393,373,120,933,937,427,630,605,207,116,316,939,206,945,840,856,587,318,676,750,115,603,67,139,21,41,855,585,362,652,834,846,286,230,806,432,349,156,855,506,296,554,263,144,836,461,145,898,545,346,676,448,982,933,130,797,515,294,844,836,926,794,379,323,95,743,213,117,166,687,135,866,932,83,711,431,452,639,974,114,357,983,148,953,181,348,928,882,304,622,698,830,678,368,298,754,23,590,733,265,690,265,544,630,923,395,628,531,84,211,873,439,29,673,276,671,917,457,556,22,31,349,575,846,515,383,731,960,216,124,407,378,628,437,273,80,55,470,190,87,232,145,348,483,947,602,219,887,853,515,299,768,815,280,215,128,705,5,673,862,289,298,309,12,39,114,683,963,596,788,390,169,413,285,158,596,981,634,510,561,908,297,63,222,611,828,637,910,463,131,559,261,61,699,511,643,168,283,547,116,972,753,715,852,624,318,804,930,116,510,147,629,253,542,393,30,911,876,227,399,115,503,81,748,866,395,953,376,206,770,571,82,158,637,542,59,976,221,566,48,512,644,796,143,528,461,951,296,930,619,502,424,531,850,4,773,413,712,400,940,325,309,457,784,808,433,817,537,916,44,719,288,136,908,670,382,432,351,840,792,453,779,640,101,229,94,935,923,213,729,655,205,987,796,221,689,689,573,222,671,898,755,668,365,533,672,484,636,316,607,22,125,255,50,913,952,357,904,683,315,542,574", "226,448,388,698,499,152,697,147,834,270,53,482,701,427,531,108,204,321,774,383,796,274,312,639,626,743,509,967,631,233,194,145,204,485,173,464,769,938,719,260,628,793,207,218,541,176,625,795,661,608,396,115,151,271,720,77,159,304,876,526,558,893,68,934,759,171,38,740,879,381,284,222,340,433,818,285,557,229,209,686,472,951,310,67,50,560,576,389,529,642,455,907,450,994,862,890,532,658,943,406,29,703,108,395,627,150,584,627,406,708,493,66,455,403,21,743,891,238,581,161,642,863,813,537,689,734,156,836,477,121,346,985,91,750,501,799,337,553,229,181,891,945,8,39,423,947,564,337,126,700,841,749,257,41,50,319,953,482,555,679,325,170,15,326,944,382,542,37,395,293,648,902,230,570,922,233,837,719,312,492,486,814,971,715,708,759,684,579,300,314,982,811,246,380,435,199,136,443,418,191,185,567,691,124,570,833,450,630,536,781,36,625,395,217,170,252,16,421,159,411,589,615,542,194,69,241,206,56,165,760,456,546,923,750,221,269,856,316,649,397,327,271,158,142,667,577,184,229,753,248,577,495,232,242,184,296,798,741,401,101,299,837,920,682,908,744,273,542,811,796,412,3,337,43,14,763,713,913,58,183,545,316,490,658,55,405,37,125,209,449,865,795,174,369,972,656,205,324,631,230,269,32,810,146,93,727,680,24,518,871,614,951,643,964,750,446,537,579,465,122,256,115,692,825,386,562,555,461,333,930,71,449,95,963,225,89,453,740,606,878,885,731,763,321,543,624,76,913,177,247,728,205,48,834,71,59,445,382,30,350,812,850,805,443,178,145,818,370,666,440,889,350,570,876,787,718,453,900,619,296,441,965,421,446,406,508,925,242,999,895,861,273,75,672,973,480,367,408,483,152,283,532,941,242,714,196,924,740,176,266,1000,486,644,252,375,146,927,334,44,620,840,283,987,994,199,2,748,202,689,949,725,428,838,517,448,275,782,958,640,860,672,906,636,361,388,4,52,991,439,887,946,436,592,826,179,315,445,584,64,320,895,459,952,859,464,722,759,711,187,473,353,468,246,403,39,823,669,924,628,404,354,577,18,916,528,391,670,972,671,232,559,589,834,686,615,722,172,640,325,25,3,578,410,627,256,17,481,558,159,462,224,645,723,703,327,995,25,716,928,21,821,871,410,603,743,176,427,646,486,743,231,309,586,568,795,371,961,511,353,378,350,534,151,618,316,171,5,164,505,739,6,226,810,230,461,650,549,493,41,188,795,449,804,576,157,567,393,404,25,757,763,948,342,788,0,993,216,449,73,831,90,26,240,398,879,766,761,835,6,100,362,89,456,81,293,576,640,619,503,125,248,674,596,436,607,39,869,256,456,470,284,139,321,412,550,296,38,265,770,657,299,934,170,931,375,842,581,310,439,433,961,829,448,496,399,395,480,200,678,630,86,434,949,350,582,723,395,68,973,12,603,868,80,1,496,693,334,130,572,489,805,140,483,948,23,712,220,45,44,662,191,763,221,613,520,617,406,333,226,268,132,81,575,597,58,554,780,30,738,673,278,870,976,125,24,158,650,129,686,35,687,709,628,728,270,318,742,463,791,568,189,416,274,450,532,553,715,107,566,530,283,519,979,7,299,171,126,425,861,485,239,214,327,617,385,665,902,391,429,720,52,517,230,161,209,649,768,574,608,146,404,236,460,156,392,650,896,625,69,702,526,198,836,82,388,984,954,889,888,187,812,546,789,948,229,716,781,389,911,827,282,673,803,980,524,875,494,502,259,707,605,735,794,261,270,283,229,268,304,477,53,198,61,706,307,17,191,135,170,103,934,505,858,778,366,280,520,996,211,94,57,733,427,862,658,748,610,441,354,826,480,654,910,660,248,275,898,728,507,670,18,964,830,675,555,955,122,579,446,882,68,828,289,522,434,35,32,725,815,52,27,532,851,523,119,423,164,493,64,17,807,567,321,19,448,373,462,903,494,43,354,316,777,937,807,22,88,78,502,281,334,173,573,21,889,278,394,929,969,950,235,125,116,877,387,215,402,363,563,39,546,716,405,7,727,943,567,496,820,799,733,253,282,910,42,726,604,982,176,793,904,546,972,190,595,354,841,981,157,810,245,556,616,534,318,548,313,560,936,864,797,463,69,255,238,784,299,342,142,471,919,957,921,787,607,88,340,114,961,205,105,474,780,708,61,225,689,147,566,659,862,866,692,936,899,296,799,576,407,215,522,59,698,545,834,256,339,416,849,95", "338,16,509,613,760,87,811,459,552,933,106,172,214,237,838,863,382,130,987,360,277,196,415,268,564,797,33,259,394,260,503,162,364,762,47,540,237,718,515,970,716,608,830,658,226,939,869,16,344,497,699,675,483,684,494,966,308,996,101,150,250,252,416,787,461,455,421,869,325,289,389,467,690,368,23,849,346,175,588,359,340,656,709,6,223,693,332,326,503,925,258,553,908,867,662,718,858,613,88,848,673,484,877,141,621,110,956,14,481,257,655,480,215,202,531,668,425,301,61,161,559,438,624,668,103,323,734,874,659,896,343,730,789,417,382,111,540,229,729,136,627,664,463,116,567,856,420,615,665,17,907,961,764,234,194,916,511,259,487,782,378,365,223,270,95,981,785,432,818,527,518,68,95,359,597,580,537,30,735,970,786,356,410,490,657,696,795,836,661,904,250,832,445,909,10,555,796,627,910,517,575,268,392,715,800,340,809,562,837,866,339,820,179,613,836,132,63,752,443,80,3,465,801,169,376,208,875,645,224,226,943,323,581,948,951,444,187,955,134,159,712,221,384,408,854,60,512,21,168,297,234,311,138,44,447,725,813,319,865,100,46,967,749,571,907,57,108,867,174,645,579,251,555,29,896,355,618,776,612,23,372,56,914,943,654,452,785,317,869,680,402,64,595,202,125,659,7,358,686,738,511,660,472,620,340,602,63,217,427,528,56,489,242,689,356,99,24,946,728,626,66,900,335,7,416,966,622,5,647,724,588,802,950,756,758,178,947,415,813,222,963,459,805,899,30,444,486,395,925,555,383,113,84,345,893,240,185,622,109,493,749,602,613,640,274,475,929,424,765,952,1000,488,93,786,733,169,144,248,242,679,296,907,13,725,903,551,620,72,137,190,921,875,872,5,865,203,718,29,649,490,514,566,861,878,538,640,236,184,173,269,280,90,787,956,776,782,784,568,888,884,776,137,207,966,918,95,517,800,718,784,205,720,719,443,245,723,706,925,433,174,369,164,772,542,635,146,977,65,522,199,44,54,146,901,879,579,819,393,923,985,674,124,657,322,616,327,89,396,994,320,404,783,218,173,39,580,359,879,916,709,918,367,764,139,894,138,605,504,801,966,424,19,868,783,506,221,34,591,83,854,421,15,280,654,747,268,353,93,129,495,259,428,950,535,965,173,617,691,971,158,423,121,787,293,365,264,621,751,984,103,208,606,552,663,661,523,352,757,491,497,77,774,513,195,235,750,24,575,331,525,706,35,820,120,251,305,768,10,340,691,592,350,28,827,861,604,618,864,29,112,642,15,498,477,993,0,316,111,989,632,36,318,222,283,52,521,859,183,94,768,298,427,894,606,238,187,203,204,226,752,154,773,162,59,253,484,861,163,36,327,671,893,775,759,432,281,733,495,348,541,116,545,457,664,994,859,976,606,432,624,356,330,872,471,108,329,104,76,212,357,414,771,777,679,96,283,339,702,724,343,754,759,598,923,165,156,248,562,670,772,631,657,853,985,128,973,457,122,225,634,97,398,512,232,408,149,87,80,836,266,461,881,33,859,318,859,175,862,309,161,50,802,540,797,79,492,664,556,909,901,42,3,876,418,8,104,19,976,329,116,522,264,405,792,846,741,292,929,318,79,618,952,433,876,988,688,594,930,13,631,631,960,394,404,240,994,767,485,561,193,919,799,445,605,51,835,259,455,563,210,910,779,757,910,715,337,910,64,204,410,166,488,134,451,946,731,614,494,544,169,886,910,60,946,835,455,135,873,988,933,34,831,213,226,757,443,784,141,378,5,547,100,147,941,965,513,834,163,960,566,673,228,411,196,476,605,840,222,955,714,869,742,520,70,456,10,721,90,160,829,719,555,452,655,682,258,312,773,656,334,121,973,186,505,562,453,812,499,238,400,602,388,585,452,532,555,748,643,127,28,205,96,799,402,158,727,587,6,910,370,448,53,342,304,753,497,432,687,738,43,10,528,37,601,446,756,881,899,186,451,331,981,523,205,408,380,826,390,727,6,55,33,452,370,474,701,838,974,834,692,117,247,373,357,291,297,713,355,276,925,448,952,490,836,388,473,645,259,67,866,133,94,348,542,460,271,741,105,986,960,685,213,689,343,575,956,276,416,307,532,934,601,540,412,814,620,386,998,584,474,753,603,434,69,621,37,426,611,457,823,709,116,455,670,472,913,928,85,962,781,642,1000,778,976,238,349,341,875,901,274,613,373,799,947,702,644,307,608,818,207,541,159,688,833,139,747,634,472,954,550", "41,82,980,689,963,106,909,106,272,601,133,571,503,741,762,226,478,867,96,536,332,531,921,583,236,841,793,34,774,727,808,811,614,900,945,274,703,840,208,841,276,162,533,973,442,11,909,794,307,244,999,186,416,477,432,540,280,6,78,539,893,596,286,890,719,282,988,441,701,465,555,741,727,460,898,56,962,281,283,370,684,331,292,117,955,595,672,575,375,545,444,716,361,526,253,794,423,509,552,958,418,585,478,44,734,538,816,708,663,655,784,323,431,381,17,977,847,477,69,56,79,802,552,841,5,411,860,613,415,435,340,189,162,756,584,825,660,962,572,552,446,577,425,547,852,367,468,933,274,258,197,490,404,838,987,541,597,390,930,512,115,765,457,367,119,91,102,876,552,148,279,392,850,258,523,870,927,357,802,334,752,316,25,96,766,851,322,118,894,636,441,453,769,706,176,834,784,840,453,182,225,680,961,824,171,828,419,787,542,563,938,354,389,493,578,539,283,199,86,496,236,539,483,22,715,706,409,813,302,402,194,976,19,60,225,565,129,905,649,582,255,461,880,998,320,267,374,950,553,909,685,552,749,746,32,570,496,535,712,276,351,77,522,363,208,294,55,849,979,610,857,583,303,388,308,655,26,728,470,895,294,542,861,2,313,126,754,739,48,150,728,358,697,414,568,906,203,998,581,137,993,512,248,839,310,544,338,919,866,306,792,470,857,522,479,15,32,966,189,795,111,48,627,832,162,48,364,476,681,838,316,745,476,770,732,278,916,532,566,980,728,340,627,977,91,430,142,58,824,128,236,8,847,534,278,894,840,332,975,562,337,711,338,38,744,826,855,965,2,875,300,828,453,561,858,427,227,893,637,564,397,552,158,258,896,24,812,865,333,353,115,919,772,812,17,349,126,816,927,261,201,716,712,736,535,569,33,52,907,34,760,765,784,236,66,753,5,369,55,441,774,555,738,723,766,707,814,237,639,814,817,268,956,67,366,986,932,233,283,33,600,640,222,301,606,644,278,696,741,120,486,793,541,609,429,866,700,831,4,801,526,876,638,581,135,904,32,112,140,608,843,664,957,809,332,727,223,230,132,461,937,86,201,736,696,213,547,158,564,717,460,347,790,692,246,989,182,414,544,291,440,37,674,813,721,351,585,322,51,829,537,339,292,271,440,635,317,756,569,328,5,587,639,475,136,897,5,550,75,587,107,795,177,916,616,393,983,438,763,499,96,979,167,941,220,577,177,269,926,580,32,755,663,176,978,349,368,993,347,444,344,457,828,839,995,633,268,991,249,143,153,75,246,767,216,316,0,390,770,182,857,251,337,839,823,1000,990,421,668,913,958,330,269,973,245,304,293,795,272,319,846,163,447,8,988,495,682,751,141,277,72,211,396,174,348,705,302,165,377,896,847,281,31,981,612,603,898,630,799,173,444,84,778,242,658,450,427,858,23,516,955,480,530,765,429,576,628,268,837,249,52,582,880,998,544,343,272,410,139,402,693,893,186,728,106,317,409,983,588,239,216,343,130,571,183,957,485,94,463,422,759,295,697,916,708,236,421,939,867,256,493,252,918,142,364,105,864,749,518,502,285,71,317,927,764,649,479,263,251,333,508,433,237,264,101,852,774,122,906,388,267,863,960,117,732,349,731,449,822,794,389,422,49,979,750,13,464,268,707,67,46,758,805,410,895,586,871,998,52,641,129,503,440,398,303,411,848,904,133,292,907,733,224,660,574,306,354,29,626,915,271,168,170,249,234,296,443,844,24,664,451,591,334,273,510,350,366,870,635,638,398,471,307,476,227,470,570,183,297,165,206,34,164,740,452,71,902,529,89,621,360,49,588,322,647,22,578,149,813,671,66,698,675,394,405,832,975,484,699,48,16,828,140,288,880,747,553,490,911,882,380,915,353,474,184,165,702,569,260,20,781,909,205,473,865,827,27,987,665,601,610,806,326,153,914,364,545,799,798,199,939,381,958,410,140,957,745,444,393,871,791,315,735,512,892,419,361,115,382,512,650,672,201,61,800,935,351,60,365,67,524,237,257,399,28,630,311,322,313,920,789,265,514,713,397,803,983,329,974,702,421,687,851,172,59,904,2,258,278,694,795,226,455,670,185,940,852,477,644,580,844,825,805,150,151,963,219,328,936,913,639,653,433,141,164,585,770,752,600,411,677,183,10,906,82,74,497,36,784,723,185,287,905,677,598,703,284,337,221,311,689,534,839,306,178,622,8,427,688,266,11,508,953,220,219,95,656,671,675,814", "429,909,622,931,163,801,895,271,661,243,261,164,807,270,913,67,870,937,200,586,172,787,516,479,400,407,384,141,44,224,755,472,430,182,996,595,608,464,291,482,323,377,250,800,286,58,378,867,437,256,454,53,685,196,50,162,503,289,337,448,982,339,150,557,170,422,852,954,970,845,377,312,670,399,541,920,560,231,931,247,214,14,780,17,25,330,899,550,48,998,451,866,341,635,607,130,916,687,822,441,820,465,379,23,949,31,180,931,96,761,284,915,83,274,376,868,946,821,344,79,632,315,779,483,247,444,305,273,82,121,503,189,538,49,887,45,53,328,858,486,450,339,905,517,840,206,677,409,739,962,367,97,243,473,512,202,251,897,433,495,366,202,136,875,2,839,366,291,709,871,655,606,258,333,394,221,507,575,723,412,36,792,812,828,142,337,634,403,483,179,350,389,943,637,317,618,196,912,540,209,545,131,653,942,316,307,205,514,2,75,213,753,548,588,954,397,94,938,556,744,474,509,997,120,295,231,133,63,597,98,628,405,815,944,115,124,547,826,665,434,345,761,545,844,509,734,62,328,755,810,354,615,209,418,295,529,788,152,257,914,591,155,751,585,507,588,836,763,652,776,16,540,447,783,729,438,134,553,490,734,139,22,773,255,804,704,9,39,147,102,67,272,23,692,526,879,289,261,30,207,756,813,615,260,853,510,887,627,127,947,264,216,173,242,693,561,236,286,260,498,39,656,699,739,623,252,988,241,659,753,637,395,493,298,437,908,808,596,230,715,216,381,452,882,454,715,267,808,954,340,72,958,800,16,568,994,460,341,522,29,104,149,543,151,978,668,186,385,253,762,723,138,896,272,342,65,921,510,10,355,620,328,598,623,868,798,565,443,743,445,471,41,425,212,375,35,438,115,631,72,394,962,316,271,908,109,921,454,830,194,723,95,346,860,342,751,239,733,633,481,129,345,692,860,403,379,434,690,418,705,551,516,383,362,106,959,322,960,606,503,795,170,109,869,797,300,365,215,585,727,797,550,481,228,194,984,214,40,749,214,540,556,497,541,166,564,23,843,109,605,34,484,553,98,722,505,217,131,410,353,908,687,544,852,411,667,435,591,63,888,164,805,342,572,439,440,125,739,80,34,706,865,639,797,594,906,208,139,199,215,692,443,449,835,57,268,488,579,174,462,782,796,151,311,547,873,242,529,772,57,375,454,213,574,711,363,544,989,49,311,579,974,753,58,104,645,826,240,550,961,479,293,749,916,806,236,871,856,315,52,417,666,537,835,771,109,500,13,561,220,981,559,401,731,449,111,390,0,351,691,67,231,933,950,42,428,261,121,543,755,6,873,477,692,607,47,263,223,397,986,223,274,769,866,178,518,74,572,216,50,394,613,842,902,918,442,192,246,796,576,435,241,226,978,194,708,849,428,600,965,852,784,141,836,277,529,808,370,5,933,320,28,966,793,263,926,241,836,159,183,298,572,613,165,125,518,361,518,824,204,700,691,116,14,409,533,640,704,32,120,745,724,440,114,693,763,491,408,764,93,806,62,644,792,101,913,19,174,726,164,254,360,412,641,932,435,275,393,514,298,615,479,895,106,432,118,25,80,705,16,618,946,355,489,764,821,545,650,761,969,270,668,891,345,577,50,249,766,452,205,544,134,555,73,643,359,961,79,564,8,775,226,623,551,643,313,270,114,927,816,829,12,677,614,333,497,687,655,829,787,82,673,513,505,751,855,855,476,836,565,205,934,202,203,372,574,955,137,214,737,252,782,886,747,673,226,83,918,279,81,893,798,997,58,346,511,943,353,262,721,206,517,400,472,310,359,128,848,169,28,607,623,371,490,52,967,648,620,496,734,410,193,939,249,258,28,824,96,926,628,742,544,358,701,502,574,354,515,172,15,180,878,649,669,90,61,556,384,999,340,275,559,644,751,115,269,198,846,670,633,580,143,561,964,894,470,715,181,601,17,31,283,210,208,57,419,425,564,890,206,92,297,106,871,967,579,429,534,527,260,87,228,510,398,237,783,80,275,696,521,454,879,129,806,980,110,444,359,903,896,423,737,223,474,197,994,421,965,426,915,712,789,860,471,368,413,738,783,221,433,937,671,536,449,57,828,9,873,401,467,160,903,872,371,300,154,350,557,819,199,455,537,202,323,380,115,977,967,812,922,391,425,828,438,807,935,438,265,57,914,199,604,865,443,764,588,364,445,327,586,778,190,419,419,306,448,666,458,744,613,411,511,274,65,791,939,78,411,591,910", "367,104,353,623,332,876,375,562,312,429,812,85,865,825,128,386,742,667,459,393,134,859,519,671,802,370,899,594,240,255,761,101,904,335,901,482,585,638,194,389,807,238,992,185,932,150,772,319,839,268,191,350,818,209,243,831,570,417,531,245,941,566,687,680,347,750,294,738,379,350,805,22,725,974,443,365,78,264,204,64,932,27,992,387,624,683,59,776,488,565,27,901,415,698,678,780,117,883,329,793,952,171,920,740,651,491,383,14,305,526,133,482,781,731,227,484,943,604,195,68,819,657,985,593,751,11,783,662,455,446,348,226,782,622,736,426,919,552,613,451,882,729,497,620,765,695,16,620,540,182,410,927,577,455,13,608,226,779,343,389,877,164,91,608,181,704,673,521,493,64,965,419,335,618,21,420,12,496,854,237,733,397,874,876,701,590,955,597,873,240,146,95,333,713,945,23,753,652,776,736,765,482,73,383,130,163,805,601,617,179,636,163,827,893,545,427,939,121,270,955,918,573,370,766,861,772,468,844,495,300,656,657,415,392,916,270,78,202,354,690,640,785,858,846,597,830,825,522,78,260,24,603,290,853,8,645,109,648,505,231,969,300,393,463,742,241,407,611,905,949,507,389,647,406,225,838,403,966,821,311,333,925,666,211,68,412,340,238,558,389,51,29,798,772,589,899,525,142,292,582,181,949,269,99,200,623,218,925,936,835,806,553,274,103,30,937,479,734,133,819,468,501,757,362,171,978,194,371,644,132,826,389,975,743,115,807,155,106,264,618,845,458,343,416,370,240,924,867,584,658,419,995,236,535,842,128,619,152,423,875,276,888,309,388,927,297,837,60,798,92,656,203,308,74,88,483,205,722,275,413,485,484,777,445,810,510,454,194,108,416,942,13,407,194,122,808,840,119,96,514,583,210,323,50,853,381,774,217,696,123,645,222,646,150,800,781,313,957,33,37,890,577,465,226,29,619,540,63,529,458,566,259,444,753,736,869,525,647,341,624,897,69,378,491,535,647,291,338,931,160,501,531,198,383,510,849,422,430,736,411,525,603,104,865,197,647,113,510,135,576,898,814,478,58,181,463,700,486,523,250,271,159,390,495,232,597,790,765,415,820,972,732,156,47,855,814,763,316,167,491,601,645,121,896,717,436,958,525,62,995,157,974,707,135,709,836,556,564,17,364,310,104,654,691,279,258,361,483,451,331,501,166,929,288,507,747,469,627,254,422,422,54,298,897,505,812,179,483,155,732,878,517,273,212,455,498,6,512,807,496,323,952,140,151,670,973,39,327,240,800,88,919,276,705,73,989,770,351,0,431,623,116,806,988,914,79,644,570,672,546,576,80,130,50,185,909,868,695,840,686,628,808,340,694,654,90,959,422,606,443,452,41,108,14,772,431,239,110,319,20,403,106,849,893,715,322,961,897,681,108,391,585,638,447,706,250,504,507,340,988,325,7,240,670,145,940,849,316,883,441,241,751,792,889,937,302,68,341,844,792,127,872,383,152,205,756,276,721,360,939,831,710,315,59,175,299,721,521,596,332,439,64,941,503,856,494,407,825,711,744,355,756,630,840,528,418,1000,823,945,161,942,528,710,565,283,223,428,21,682,417,194,385,938,136,885,103,482,681,481,792,676,10,43,598,170,172,271,922,660,28,396,723,198,192,371,931,987,453,754,354,783,956,359,771,898,578,576,669,767,948,416,982,385,313,909,105,12,799,213,573,374,891,314,990,40,481,563,430,206,962,139,26,197,301,781,526,613,309,761,924,33,430,252,832,36,49,913,906,478,961,602,711,606,378,813,62,630,14,415,688,897,745,698,54,737,179,971,752,946,784,913,236,3,588,116,155,250,87,992,657,197,853,828,344,986,619,786,638,995,406,997,918,432,864,224,380,190,589,301,849,602,749,184,212,26,700,250,332,258,508,297,744,471,537,148,120,24,688,873,221,524,534,123,826,517,299,618,226,664,308,23,661,627,657,817,636,519,660,57,14,711,848,498,37,385,886,897,453,606,496,348,983,291,348,778,575,749,431,534,579,704,869,788,494,142,862,139,915,160,740,565,664,777,803,346,132,167,662,229,21,632,587,434,275,539,732,707,613,525,154,350,151,700,861,553,860,924,876,941,257,425,920,521,271,392,178,104,3,458,880,392,984,711,153,876,128,51,825,652,329,673,408,372,414,865,426,558,667,239,287,865,323,857,151,606,597,406,963,583,565,392,284,818,512,56,404,465,171,207,660,844,750,108,635,558,469,299,127,453,383", "940,608,233,390,910,249,608,518,470,208,379,333,752,790,642,654,907,311,665,51,905,307,705,203,577,468,810,903,351,422,543,365,895,468,560,685,923,666,666,767,270,957,478,105,425,564,806,682,61,661,686,648,380,149,752,567,30,526,255,669,47,348,719,12,253,274,864,801,740,603,331,754,294,8,505,463,536,838,689,687,237,898,28,712,500,345,411,94,41,289,715,297,929,446,361,841,447,457,786,616,400,674,187,769,202,799,600,707,957,970,268,811,426,773,283,455,845,924,700,289,400,6,264,639,291,661,111,38,48,283,672,666,350,876,432,417,58,955,235,900,244,101,572,718,564,638,918,553,979,198,184,656,960,414,524,310,448,168,958,516,532,359,627,700,321,736,270,142,450,931,243,705,268,635,47,113,602,406,84,834,191,830,471,80,764,944,230,9,121,144,683,343,658,499,2,663,910,630,393,683,705,487,837,957,358,297,730,920,403,936,377,285,400,623,728,576,204,188,213,446,616,96,679,964,665,989,381,493,993,97,853,127,999,909,94,327,49,29,909,864,782,380,803,355,909,512,949,758,816,70,900,544,385,670,824,473,739,33,909,994,102,398,723,572,588,601,21,936,284,685,663,876,399,812,802,54,370,697,860,868,12,853,142,459,172,650,254,423,221,331,522,900,560,642,297,665,731,724,709,993,698,117,602,367,149,942,480,607,18,623,677,652,167,514,82,830,922,497,133,574,578,180,811,201,856,170,792,412,598,532,141,937,443,618,844,788,949,831,988,442,84,542,898,666,311,308,902,55,605,320,911,418,211,785,773,928,248,430,365,65,303,447,421,586,600,17,826,186,400,904,307,785,398,78,621,782,994,21,700,317,636,530,475,189,574,626,64,610,684,541,178,91,188,97,870,868,405,22,380,116,41,527,231,736,75,37,748,160,997,98,593,277,593,790,182,284,717,420,591,746,131,383,600,498,83,189,229,527,311,236,644,648,990,806,768,904,883,741,469,107,182,133,1000,746,226,778,677,550,983,670,420,362,668,197,704,700,84,724,822,122,581,968,992,937,483,952,524,343,784,369,68,866,820,526,924,123,711,730,112,248,824,340,317,177,851,279,954,139,495,227,835,10,405,152,782,195,206,868,259,606,876,371,562,556,306,826,34,116,394,337,423,154,910,156,550,412,211,433,91,604,197,316,596,843,503,364,407,821,5,844,226,672,947,325,625,493,110,931,667,40,590,215,551,256,486,422,100,702,716,604,769,312,557,915,937,788,52,545,369,630,864,819,891,442,510,583,335,212,725,624,784,334,365,795,831,632,182,691,431,0,395,79,129,319,650,9,300,394,754,738,681,505,681,675,235,99,751,701,453,402,817,13,989,398,920,708,860,717,577,400,475,280,803,49,802,546,509,181,29,586,472,425,368,640,919,817,820,513,333,197,902,506,654,702,945,72,816,549,653,262,171,315,320,867,917,592,913,53,622,638,623,375,453,816,607,711,187,381,365,455,751,358,777,217,749,577,647,865,167,769,6,198,986,129,174,630,430,622,660,103,871,536,190,939,154,45,306,379,925,271,680,154,495,828,209,369,96,936,813,771,355,724,396,246,334,814,177,41,128,20,236,704,962,559,789,533,758,294,690,509,316,250,36,761,855,621,553,221,336,513,270,637,138,124,612,114,203,218,771,543,976,940,814,660,713,989,960,95,83,456,663,222,984,762,680,498,764,834,577,290,447,763,917,769,500,922,844,840,579,457,41,665,701,196,170,892,399,173,864,68,665,573,380,15,241,538,161,375,679,835,7,340,392,211,725,464,917,158,832,532,737,705,309,886,431,115,478,859,764,888,450,646,861,648,802,496,275,373,858,675,904,942,278,603,553,255,9,101,712,351,627,258,473,803,174,160,677,325,14,892,406,170,429,942,434,79,181,814,736,226,805,571,373,201,666,740,105,47,932,823,5,658,968,559,797,766,521,309,116,683,153,89,692,96,802,703,478,181,17,71,60,10,863,716,519,763,698,564,766,752,631,296,762,241,92,861,971,323,781,632,37,279,933,865,764,896,440,716,557,722,80,798,778,904,698,432,944,104,461,129,283,664,560,132,609,208,635,621,706,182,537,15,172,353,559,847,586,40,401,97,697,746,974,875,376,345,974,317,122,195,370,618,730,583,445,51,656,975,553,892,947,32,898,233,71,948,932,1000,534,280,167,982,677,390,548,895,529,701,723,553,668,547,239,198,60,290,938,98,437,956,968,396,841,423,262,984,678,354,964,294", "474,900,496,532,877,802,664,443,488,877,808,983,386,74,36,78,84,218,526,65,896,357,294,764,910,9,238,379,380,655,384,688,795,811,496,697,899,772,236,576,624,7,210,592,570,31,807,266,618,462,109,583,487,127,426,67,32,923,679,111,738,712,361,773,590,218,311,417,401,856,254,949,413,893,534,712,355,128,484,726,383,484,197,833,700,488,443,149,591,503,33,945,503,197,59,644,1,924,750,319,434,350,320,632,337,335,133,592,162,16,951,674,821,912,670,975,549,719,488,899,722,243,17,231,602,613,929,950,217,833,64,440,799,991,81,515,455,282,31,451,241,429,599,580,389,633,889,648,584,276,17,830,807,492,741,669,102,107,412,442,607,839,339,45,711,856,836,554,903,296,641,554,205,825,390,472,374,839,5,324,226,717,599,475,379,807,421,131,774,211,920,452,864,555,55,337,1000,674,416,721,716,278,416,78,562,819,550,651,32,485,403,369,223,141,557,473,563,803,518,382,436,120,250,828,251,910,132,965,388,629,33,890,510,794,535,925,660,684,677,548,241,306,336,87,455,831,935,461,341,141,414,758,196,999,703,805,213,696,767,849,481,929,38,67,977,89,302,888,177,782,564,126,359,628,747,791,287,850,474,157,742,672,459,138,414,906,890,58,415,617,134,727,371,45,31,213,175,755,366,241,286,532,905,371,263,569,247,120,477,862,559,190,392,989,49,85,471,576,411,611,964,815,920,651,812,327,348,892,178,634,287,126,612,129,510,493,79,107,760,347,430,522,480,941,921,804,355,787,151,664,688,534,139,153,715,8,96,548,34,810,300,519,475,726,379,527,398,718,461,371,103,629,533,336,141,487,82,16,405,505,2,653,977,591,971,677,659,936,568,45,3,929,391,248,472,233,155,155,953,200,551,758,652,877,140,279,509,914,393,413,593,724,107,225,219,635,145,395,888,581,98,183,141,500,980,851,431,477,176,834,8,57,184,58,726,215,396,50,636,832,230,464,859,260,839,290,457,145,186,965,536,649,668,589,100,201,797,272,532,537,475,690,550,157,911,863,868,808,854,918,847,534,302,798,465,495,43,672,383,336,334,659,502,563,920,409,878,148,284,884,220,46,601,717,443,712,448,482,716,918,120,699,350,553,788,651,707,220,355,206,416,832,478,771,359,738,393,724,434,858,677,506,45,226,744,24,284,731,307,588,739,321,62,86,252,436,481,827,777,829,327,774,705,773,461,866,270,381,849,648,851,597,245,599,734,729,500,884,987,623,418,878,658,768,171,259,943,854,349,536,257,974,906,813,90,36,857,67,623,395,0,704,460,505,879,951,65,839,560,276,175,872,717,59,585,146,992,265,817,632,436,22,960,482,977,53,391,567,689,401,136,581,743,914,745,153,928,875,177,250,617,724,95,947,170,824,776,115,689,174,534,221,725,834,922,454,702,31,164,70,56,513,730,67,559,367,658,826,717,899,109,87,580,274,330,289,834,608,832,141,541,558,12,222,996,189,211,395,222,631,81,302,93,477,133,84,4,313,862,442,957,994,24,645,28,488,129,880,197,804,946,382,392,959,413,897,706,661,25,917,83,354,77,534,115,633,754,420,661,671,306,362,116,793,177,170,178,922,925,369,894,158,605,188,32,967,823,471,153,658,646,364,426,220,47,583,431,376,538,363,987,330,487,541,473,191,157,132,428,68,28,170,829,349,312,817,179,182,766,718,684,487,472,506,504,963,121,438,820,472,935,48,450,484,932,849,900,878,343,91,700,916,218,370,927,521,104,504,872,233,954,552,375,96,312,489,407,733,176,482,275,157,533,330,381,71,279,581,564,370,222,602,655,548,78,361,482,479,628,293,245,146,140,672,931,971,787,147,275,864,374,489,151,792,581,674,299,335,678,95,257,800,313,27,302,706,415,379,406,757,47,285,508,795,475,623,685,124,172,381,509,450,889,670,857,603,732,899,669,357,400,682,511,411,212,984,674,267,161,994,650,242,571,605,904,338,209,865,875,151,741,865,942,502,123,581,809,34,127,370,310,36,293,353,537,789,647,116,609,236,679,224,583,688,681,697,537,545,658,987,890,746,473,633,734,207,495,412,583,257,372,751,143,650,917,138,748,351,809,550,283,481,839,523,32,937,34,951,528,347,574,475,535,961,972,706,978,624,284,271,319,380,522,871,723,561,986,313,530,770,821,480,869,222,775,865,833,279,377,172,521,555,619,659,284,598,978,957,478,150,243,880,681,90,531,20,155,106,705,405", "477,971,178,752,116,529,496,953,109,786,600,343,397,222,61,181,154,88,639,280,906,164,935,883,762,176,77,529,493,126,530,931,753,991,682,873,282,299,800,318,547,986,947,708,575,717,815,181,739,639,998,194,794,353,801,679,812,665,67,490,512,518,746,489,79,130,624,604,507,543,136,434,921,598,458,285,826,818,723,108,570,523,613,254,824,942,104,829,516,202,397,642,994,743,190,469,676,707,141,343,272,798,909,381,299,373,388,998,142,664,46,493,136,475,933,523,21,288,18,494,733,430,831,335,493,411,652,168,531,599,296,850,463,231,633,567,795,136,606,358,989,723,802,20,186,992,618,867,110,342,527,204,511,619,703,93,780,711,186,932,366,216,163,947,253,870,787,254,211,280,537,279,331,477,54,424,636,808,112,609,722,969,559,102,81,39,243,698,655,21,627,713,586,519,810,967,566,674,738,199,516,639,83,687,154,270,539,51,851,453,749,539,928,130,676,562,817,775,836,765,97,580,663,517,811,524,507,908,266,908,998,711,272,996,278,124,233,868,474,594,17,231,660,309,246,860,965,609,123,635,639,437,439,426,774,191,775,807,555,532,40,6,167,236,710,928,666,723,960,136,602,137,165,79,281,715,706,421,174,523,491,907,158,384,753,337,412,777,236,765,207,56,247,869,946,471,196,373,727,999,749,65,249,697,402,462,391,128,818,230,812,396,142,109,625,574,811,85,479,639,369,313,766,794,36,946,326,654,401,627,275,410,389,690,592,92,845,356,148,817,75,970,981,259,527,766,804,598,833,308,970,235,22,967,515,404,43,206,657,391,198,517,189,228,578,739,101,922,857,539,443,223,348,772,637,792,726,209,669,464,681,333,440,798,745,173,122,407,779,51,805,616,160,914,499,354,651,403,522,871,697,39,41,63,791,70,817,164,542,935,33,732,545,210,753,910,773,701,195,366,396,265,907,3,431,229,266,844,822,503,840,558,348,857,463,561,111,466,570,365,554,642,311,825,3,909,6,933,785,324,359,344,316,914,103,534,820,387,720,67,82,148,448,491,295,614,912,197,869,251,798,318,200,799,175,599,477,346,357,416,14,276,356,4,881,794,921,115,255,507,19,756,265,717,843,229,761,806,566,198,900,27,587,999,200,739,995,883,262,794,59,237,956,530,885,119,523,545,171,532,808,291,217,81,248,10,556,736,342,799,455,632,203,591,980,50,801,280,279,510,81,824,477,788,941,549,728,863,9,834,669,634,532,684,63,913,650,800,519,69,864,418,513,934,17,591,656,535,257,355,296,823,650,918,26,318,251,231,116,79,704,0,707,971,80,873,775,450,140,605,922,690,149,265,683,915,885,46,929,420,776,780,735,103,264,475,199,82,14,541,458,920,880,604,910,563,885,462,369,679,519,707,552,586,552,896,855,220,569,655,616,745,126,845,266,592,478,560,580,145,835,177,603,125,424,521,583,290,932,329,745,984,923,352,637,764,294,479,400,368,813,23,154,9,491,752,37,232,816,742,728,391,732,691,81,715,885,947,59,565,810,96,230,386,583,452,887,998,976,635,311,116,657,779,510,290,241,907,336,926,580,632,396,23,612,18,124,190,353,663,233,788,16,996,36,740,267,534,488,211,218,668,125,207,56,764,164,398,657,981,411,777,204,901,636,744,862,974,494,912,635,509,587,508,990,755,625,663,743,659,648,955,210,972,934,207,607,364,374,675,794,256,600,909,927,52,610,445,711,417,209,9,834,35,409,887,39,76,705,806,233,720,318,948,143,734,594,889,51,176,875,941,744,189,516,238,61,486,561,324,881,329,153,620,534,10,768,643,303,31,544,938,108,201,574,82,504,542,609,3,594,880,868,422,103,721,140,898,219,736,505,167,423,581,590,86,298,41,585,94,297,79,412,714,469,317,440,663,681,356,919,912,124,694,897,292,483,843,784,451,942,1,33,496,658,491,4,188,189,612,434,232,280,337,84,593,395,132,782,786,452,944,163,601,90,774,154,787,73,243,268,115,819,413,145,195,884,369,272,170,172,713,296,179,895,901,420,500,540,450,268,212,393,599,780,539,721,236,196,692,803,703,273,388,294,853,888,909,352,772,667,719,240,413,927,968,112,120,274,532,310,380,203,236,845,988,944,804,881,375,547,280,331,283,821,229,432,467,385,569,101,199,802,35,647,841,228,530,700,470,450,850,289,187,558,532,445,457,882,982,802,529,876,321,384,815,766,166,818,663,42,439,596,89,601,426,943,777,701,556", "978,763,988,456,41,722,128,990,516,323,452,591,293,12,494,231,436,18,101,341,747,406,486,690,318,160,612,277,806,666,247,91,956,825,853,89,924,650,656,396,419,286,516,625,188,480,923,931,215,846,403,180,12,176,624,167,253,181,107,925,300,842,23,878,349,170,724,202,974,809,501,684,576,824,78,866,655,147,383,837,767,291,300,794,801,289,299,949,778,589,698,882,391,566,387,572,822,835,759,789,430,892,812,634,83,769,77,202,957,740,715,212,649,122,510,305,82,873,104,665,612,556,318,796,477,926,844,942,962,448,818,439,163,367,9,61,12,24,769,413,192,169,961,484,517,588,238,491,552,219,660,854,883,793,285,856,811,28,521,236,248,239,523,739,618,271,160,515,788,601,153,739,35,472,802,782,619,274,650,158,922,482,344,432,39,470,248,193,902,937,111,434,346,862,858,645,81,724,106,577,703,62,289,728,7,423,241,801,935,288,462,451,997,25,780,757,749,31,718,106,76,618,554,725,493,416,406,642,780,211,127,173,375,16,852,388,782,439,756,465,152,777,127,922,781,146,286,615,451,105,166,131,306,93,990,132,611,233,403,389,619,929,472,637,953,987,65,917,956,971,443,282,447,507,123,207,805,232,606,157,96,244,139,188,342,302,617,808,418,424,895,623,662,114,982,442,173,680,771,128,759,501,744,291,564,350,643,67,795,136,261,84,89,74,818,484,662,424,516,517,375,149,127,20,864,77,750,931,428,135,651,110,922,358,33,854,861,370,934,314,136,829,267,931,602,612,538,496,549,511,731,267,411,531,996,309,926,705,1,74,24,520,839,108,440,474,627,47,870,574,273,91,861,633,7,526,804,413,66,335,387,409,886,118,920,291,142,182,104,221,322,247,642,801,776,408,784,173,234,269,841,741,396,511,753,732,908,24,149,187,496,959,14,862,122,112,182,288,272,142,99,746,126,636,109,55,26,564,955,545,904,723,909,585,729,507,580,870,282,114,754,666,491,532,250,832,491,832,586,235,93,75,968,205,613,505,766,278,598,84,341,862,583,16,230,431,317,461,257,279,56,13,411,564,83,992,59,362,22,830,730,465,772,386,174,75,995,945,987,708,702,691,746,94,504,720,861,707,431,20,414,754,947,326,275,290,437,623,89,392,115,952,786,829,528,240,35,491,326,430,465,944,736,846,120,390,393,450,106,322,233,605,957,706,613,948,893,264,644,168,740,477,133,117,709,300,938,323,533,123,502,859,222,491,799,162,721,266,69,260,409,658,628,818,387,12,71,823,624,325,426,813,10,886,240,222,337,933,806,129,460,707,0,905,769,974,74,522,802,38,775,984,801,925,775,544,443,174,66,782,591,495,681,389,59,388,654,468,178,262,809,192,556,76,457,661,197,999,814,577,690,652,90,976,839,427,851,707,3,355,723,901,720,376,999,486,919,63,429,274,301,420,831,714,122,112,769,439,656,89,476,323,68,89,385,792,744,655,790,172,196,945,696,343,957,978,100,437,942,681,426,396,464,319,418,598,848,562,24,110,779,558,723,422,257,218,378,726,171,179,793,693,273,616,578,231,407,789,238,533,829,37,489,822,988,885,26,113,444,378,456,155,257,756,827,884,47,407,927,848,44,276,466,914,161,533,89,210,717,864,13,534,231,667,908,332,307,868,247,571,206,551,532,609,666,289,296,23,226,211,762,704,261,455,327,50,923,858,332,238,837,536,727,557,481,132,634,308,510,881,534,304,782,215,868,298,119,766,692,35,507,186,635,909,40,988,45,924,729,991,9,782,201,964,866,416,298,909,967,967,936,874,929,891,442,214,176,570,535,357,19,938,758,975,403,874,609,131,832,69,243,372,155,373,141,272,379,101,693,59,388,760,879,589,770,624,190,590,389,502,721,470,58,458,971,92,510,393,19,477,903,761,441,605,265,295,841,386,607,628,487,419,287,702,980,997,513,140,592,811,764,279,97,839,860,759,403,917,178,467,102,614,991,649,273,237,485,723,801,236,729,676,847,491,962,286,299,874,105,533,315,580,26,843,690,906,648,434,188,199,252,933,856,824,1000,287,823,912,482,149,544,611,612,745,333,145,694,320,915,366,85,392,337,5,503,739,377,966,919,616,494,386,184,581,844,1000,524,225,114,524,752,846,638,878,940,170,550,673,385,364,159,613,909,66,88,646,277,567,282,562,400,89,53,564,8,509,713,535,112,257,788,798,2,112,931,196,409,949,672,575,95,654,373,257,186,581,575,992,427,329", "867,98,344,497,128,154,100,485,770,11,899,287,268,29,38,587,516,880,935,691,130,964,733,606,115,568,223,407,897,465,225,195,643,438,622,742,853,349,440,421,361,862,808,201,493,300,903,752,792,112,618,307,377,618,641,965,341,160,27,52,745,759,967,384,783,900,281,758,366,751,441,525,123,514,323,601,66,670,753,438,739,170,432,872,889,587,17,173,628,853,108,245,196,382,120,207,896,343,974,287,98,846,210,789,816,518,398,893,973,861,848,54,600,168,591,735,840,959,241,611,716,644,283,816,586,147,922,329,403,273,340,996,298,513,422,386,753,520,809,695,617,121,317,492,11,706,484,679,826,770,715,165,333,290,245,466,343,248,434,473,157,593,67,563,237,611,190,21,56,913,935,515,764,75,507,384,839,560,905,195,540,48,741,900,348,791,196,86,450,563,390,588,226,604,349,243,723,363,100,160,790,187,481,75,50,450,318,709,407,641,928,163,894,626,15,204,375,937,477,74,771,937,5,919,532,674,966,89,223,688,667,159,140,121,763,105,388,436,856,382,663,456,786,899,950,47,596,590,618,667,648,206,138,221,6,94,134,492,514,425,780,560,248,34,959,781,513,379,185,639,607,576,672,655,336,256,282,863,976,715,365,434,327,474,384,460,442,6,579,352,612,439,612,977,211,87,152,844,175,245,438,75,342,197,779,442,538,431,233,172,990,712,556,591,652,906,5,589,332,508,117,503,415,352,710,323,642,543,277,524,378,117,58,834,791,20,858,326,368,528,325,740,412,244,153,672,212,158,213,793,368,201,946,767,813,661,625,998,820,282,340,769,500,440,32,341,373,192,755,250,27,15,944,941,864,114,321,898,776,683,401,260,459,418,162,654,495,223,425,71,735,444,92,776,616,867,75,232,99,120,163,985,389,649,117,44,726,121,115,992,468,362,382,171,803,266,474,959,870,537,953,233,206,426,240,321,896,285,202,355,236,785,851,951,881,976,484,232,350,811,914,635,518,584,398,255,488,974,190,302,88,631,59,955,928,482,435,806,394,580,856,878,392,205,204,576,464,559,203,269,636,701,377,842,704,534,333,576,601,695,477,886,27,506,511,509,58,784,116,322,533,328,474,356,99,738,459,525,427,282,660,65,736,76,825,609,982,474,581,623,481,761,553,956,166,270,431,364,817,539,389,310,50,122,902,393,797,926,646,932,94,719,713,876,36,972,371,459,243,466,943,258,429,751,584,401,157,177,456,690,446,11,857,847,330,232,207,111,140,750,69,48,270,905,921,496,703,21,914,630,362,746,756,608,398,283,839,950,988,319,505,971,905,0,832,633,583,515,310,323,29,610,424,912,268,793,567,240,904,905,200,273,745,866,969,137,203,715,300,672,108,799,567,770,856,68,80,931,915,570,280,100,16,664,663,241,154,644,480,411,185,163,843,185,518,582,113,680,946,913,330,739,389,504,484,870,748,436,696,96,481,440,433,919,493,462,658,650,169,495,351,919,442,92,248,488,285,746,728,840,896,203,207,490,298,48,172,3,951,632,893,701,213,723,889,219,503,679,171,875,883,575,370,420,891,130,949,75,547,24,571,423,387,557,169,101,747,89,770,563,797,128,489,38,425,264,535,172,122,226,786,625,570,144,562,156,928,453,702,544,70,627,373,783,998,528,442,902,516,471,652,54,921,328,499,385,805,391,123,411,595,522,421,811,611,785,975,158,127,860,514,180,404,368,418,282,293,831,538,426,405,784,812,976,218,416,905,657,235,536,648,635,157,740,33,978,364,269,969,909,558,312,741,825,152,173,744,892,858,393,259,734,237,88,86,834,671,526,155,276,560,703,605,361,606,309,467,197,673,806,223,803,143,503,26,837,335,463,804,106,783,116,12,59,276,326,468,376,928,530,350,729,766,733,792,218,743,631,472,520,969,448,396,53,499,901,390,795,606,969,124,458,220,986,384,51,161,576,408,690,414,812,127,307,153,554,835,891,823,499,241,671,209,273,863,843,32,827,629,48,58,787,7,749,638,96,546,245,939,886,246,281,962,7,894,206,913,668,691,426,935,884,885,566,985,646,722,660,760,784,424,119,269,230,956,991,498,86,116,804,139,640,419,590,992,67,892,179,357,619,569,853,972,116,852,955,472,616,120,237,832,106,751,982,834,878,494,519,836,974,323,165,610,325,932,984,806,941,338,114,153,207,278,220,32,295,580,689,853,81,234,141,751,337,68,621,6,711,22,694,745,744,244,442,80,745,882,495,46,983", "975,464,445,438,146,263,210,380,281,234,75,3,339,505,176,892,229,154,891,733,141,408,268,247,786,809,176,604,197,617,685,442,393,554,672,490,677,282,535,31,498,280,392,198,112,58,511,398,836,337,511,283,436,710,521,942,24,411,135,65,684,11,86,614,249,989,310,215,843,748,903,258,611,608,659,618,288,307,558,810,800,131,76,345,826,380,336,648,571,669,734,303,11,789,907,467,966,625,925,542,649,241,794,917,881,152,852,342,780,96,499,278,966,954,168,516,910,426,833,474,274,285,169,367,822,987,46,340,650,375,961,868,262,58,626,259,634,215,125,621,988,624,580,439,550,669,862,814,103,44,166,489,623,521,260,188,515,495,446,435,999,956,674,683,519,533,118,388,499,964,151,916,963,505,584,393,663,639,674,328,350,906,640,224,155,528,257,479,938,934,853,352,74,196,378,533,280,415,745,59,139,852,191,335,439,833,292,768,804,201,219,224,932,494,413,605,610,512,258,648,386,694,993,752,260,659,38,651,543,137,65,8,769,577,420,695,979,807,511,177,957,887,591,87,182,439,344,571,906,1,400,172,840,613,211,818,283,151,624,601,237,128,309,901,434,203,90,799,592,333,837,778,988,289,358,79,43,203,322,944,632,835,27,887,818,146,483,875,47,905,913,141,672,49,211,393,232,974,155,80,641,42,264,219,321,162,402,230,951,718,687,973,596,365,70,130,767,716,699,361,152,32,919,609,151,105,22,897,966,751,709,823,868,616,537,606,253,616,306,301,858,231,38,276,363,963,35,480,3,200,375,829,732,964,960,718,643,436,458,82,790,343,639,969,355,318,9,776,608,251,863,712,53,13,924,477,409,943,486,558,241,855,199,56,226,623,597,309,219,873,451,487,960,788,742,413,473,289,878,919,443,608,639,504,450,612,701,351,438,262,934,630,930,709,575,732,90,154,210,12,823,709,444,112,345,879,49,135,112,409,411,276,540,478,280,364,397,294,401,815,152,580,373,166,332,424,826,270,857,895,248,424,835,166,518,678,287,36,273,761,106,443,150,770,13,321,94,500,561,248,664,12,901,894,206,185,909,982,913,30,694,827,844,502,671,959,621,618,531,216,540,31,967,219,463,725,7,317,983,255,812,731,299,20,832,237,543,100,725,220,916,158,8,588,852,104,65,308,427,554,352,667,608,452,492,391,882,914,5,825,557,344,964,189,741,372,729,152,517,302,530,73,20,695,216,407,835,315,505,689,157,235,647,931,916,126,258,688,21,649,722,433,522,89,551,365,362,115,93,168,193,556,96,344,879,52,823,42,914,650,879,80,769,832,0,450,871,728,826,792,59,209,864,650,846,515,346,946,378,511,883,816,922,847,992,338,793,418,443,187,12,202,791,510,388,28,845,239,161,98,215,825,817,848,512,252,933,294,120,707,605,659,94,921,318,156,963,12,16,387,126,637,569,542,477,511,570,604,624,207,230,280,673,660,294,40,647,739,625,328,488,58,583,793,132,375,625,656,742,41,421,940,497,774,523,108,862,686,363,857,972,736,361,103,298,210,654,720,585,581,382,388,782,756,470,595,202,592,100,38,920,340,182,879,476,969,725,666,192,867,35,558,482,572,624,823,517,485,58,603,437,336,421,531,574,727,756,808,178,94,441,378,979,153,623,699,277,253,297,393,244,405,12,388,442,679,53,456,221,635,763,194,839,397,669,744,651,347,316,882,19,359,577,464,952,643,844,891,251,164,356,479,317,198,765,91,652,436,928,505,780,226,329,300,747,651,697,818,222,199,807,164,16,584,577,580,9,474,75,198,456,839,839,629,515,850,834,418,372,853,162,836,348,41,824,795,829,416,421,397,292,635,134,51,254,567,887,106,643,398,547,514,668,874,215,522,478,580,441,664,880,374,422,427,41,42,870,395,850,240,627,618,162,274,577,186,783,305,197,133,609,700,388,152,226,393,35,37,344,55,455,204,91,953,721,256,341,878,624,772,781,391,366,751,99,773,758,708,807,534,81,186,13,8,902,652,532,323,185,319,556,388,943,701,474,845,887,759,341,930,59,835,75,489,349,511,78,719,879,809,326,404,941,324,969,441,389,781,861,368,505,431,478,468,692,34,733,223,129,719,165,160,714,236,48,579,666,933,390,140,494,296,579,177,285,30,37,217,465,424,210,839,565,539,301,318,162,611,526,541,437,19,211,764,396,517,845,427,87,281,116,95,646,387,559,529,620,617,641,673,421,945,668,955,939,791,120,875,596,382", "632,955,890,363,582,891,631,723,224,71,474,652,351,311,278,95,525,335,925,290,852,43,731,555,401,752,442,198,708,554,674,994,904,298,660,511,978,743,817,31,177,791,911,600,806,722,361,53,108,195,278,920,522,817,803,225,556,912,272,797,634,947,150,623,693,917,262,959,68,126,735,860,493,638,729,495,407,508,622,122,957,827,475,546,731,730,401,682,563,556,15,567,44,533,224,808,125,206,89,59,607,663,849,709,440,315,619,84,913,816,281,442,853,902,874,78,703,957,148,542,608,184,99,324,415,206,795,321,689,343,630,127,950,497,884,494,215,157,319,401,288,593,58,821,354,21,690,575,205,163,251,810,51,793,222,213,245,332,714,481,779,135,967,698,9,673,984,618,344,194,48,720,179,599,933,903,766,87,577,621,591,284,88,719,2,948,758,594,337,402,502,209,871,968,629,912,212,825,999,164,309,829,627,467,359,310,102,521,650,680,215,65,247,889,572,709,372,82,702,765,283,238,998,412,63,898,332,846,4,961,554,741,4,282,607,30,315,233,538,180,246,984,491,460,516,914,404,479,941,10,320,672,745,656,828,33,744,458,673,666,189,508,674,731,976,523,542,722,309,575,993,884,814,157,213,427,49,600,109,774,398,75,386,585,891,554,892,261,595,623,208,184,152,729,388,149,870,581,527,946,779,379,584,657,9,875,598,581,461,541,920,323,993,758,833,599,290,364,818,949,581,413,235,998,924,174,378,970,719,498,903,936,451,757,699,554,278,358,930,254,178,856,638,461,924,488,704,246,354,35,874,309,794,487,520,323,926,934,258,765,867,563,340,958,642,106,73,742,652,192,210,758,580,513,48,94,966,319,571,72,734,243,966,781,495,250,963,735,561,839,357,74,960,849,901,344,686,138,806,273,192,9,414,38,796,15,259,12,415,837,993,468,496,976,590,850,284,41,200,683,125,557,506,590,118,142,211,42,806,41,86,57,893,336,666,172,650,203,509,627,795,477,345,321,438,987,662,468,955,899,161,184,645,867,893,481,587,570,499,235,766,607,225,174,101,13,639,179,886,566,377,38,433,321,210,688,742,34,114,496,305,642,663,800,464,992,266,105,966,812,84,937,370,818,852,544,636,841,528,671,300,495,847,844,56,247,719,429,765,454,239,829,772,878,450,51,992,309,893,604,858,527,436,396,973,90,578,173,72,592,386,133,212,807,784,129,83,56,437,766,931,123,564,457,290,413,172,862,862,575,353,469,538,36,553,436,511,728,628,655,187,786,535,831,104,608,806,504,706,635,49,709,344,450,766,521,1000,428,79,9,951,873,974,633,450,0,261,821,987,33,298,791,103,735,28,104,132,167,67,788,978,193,875,852,479,727,180,577,935,130,224,428,227,850,126,132,596,929,216,346,138,375,700,624,865,464,830,104,775,86,79,674,428,756,410,397,479,380,395,896,348,556,239,273,531,853,375,491,925,67,868,842,965,621,5,491,476,75,561,480,706,128,972,399,96,441,73,50,570,913,973,763,206,983,770,519,263,588,430,504,361,882,358,470,868,170,581,144,742,373,299,796,196,577,244,633,195,936,324,753,294,830,424,422,236,82,83,198,860,737,236,256,996,976,154,252,426,900,488,113,821,75,995,728,600,23,594,591,524,944,450,892,129,846,669,879,940,911,863,833,159,801,665,339,357,844,823,407,481,967,527,786,678,339,488,370,440,399,903,789,75,421,886,603,36,214,194,332,178,218,946,517,250,467,584,950,382,131,410,28,430,56,202,556,662,852,937,77,312,110,915,884,300,32,676,281,991,393,224,412,89,490,937,107,994,262,818,387,660,964,625,686,281,743,334,608,497,771,285,966,763,953,605,537,773,268,235,732,809,937,567,150,931,311,653,464,983,871,999,752,705,483,370,105,734,534,922,368,183,183,574,838,883,154,182,389,466,964,121,297,450,346,139,385,404,885,811,283,575,789,120,179,487,191,351,178,400,424,250,245,794,96,830,785,995,578,211,886,418,314,935,669,7,329,77,952,435,656,23,305,829,200,141,540,188,550,897,434,560,13,239,537,894,234,617,356,698,929,857,828,325,739,205,399,369,143,639,229,405,623,263,391,553,565,776,923,375,815,330,827,115,733,112,938,236,60,660,200,815,641,836,464,9,759,976,443,945,935,828,416,580,238,18,663,874,116,613,60,909,504,292,551,437,334,341,844,58,366,426,487,416,513,959,915,785,746,394,918,619,989,68,253,348,674,455,927,194,674,322,823", "388,314,50,701,11,703,702,618,746,861,766,167,891,333,763,604,262,718,714,78,329,433,198,499,410,471,33,594,325,420,321,219,795,770,928,663,938,808,167,44,224,146,139,19,869,848,295,724,894,563,345,605,173,743,262,79,480,735,208,608,264,437,25,333,589,154,9,261,113,789,771,126,730,391,779,271,364,537,165,301,716,314,618,155,327,347,222,956,50,728,565,559,467,653,818,619,761,625,871,554,875,963,814,390,339,619,598,183,996,493,899,888,427,218,32,727,781,61,952,436,359,813,334,928,29,805,248,47,685,233,547,296,731,478,905,752,89,819,474,826,630,944,920,936,214,247,349,706,137,266,962,510,89,35,844,995,981,546,729,819,560,35,281,29,88,160,554,842,121,785,529,531,39,306,873,914,565,393,75,398,384,289,845,309,23,574,383,442,991,440,111,571,505,992,277,359,691,953,42,193,854,490,487,552,130,835,169,968,917,352,561,927,755,645,868,617,836,417,677,987,828,34,510,456,508,447,233,241,223,289,26,580,844,300,492,4,627,552,629,91,112,902,731,67,252,566,410,567,482,456,883,85,408,272,242,673,687,308,594,402,487,630,284,495,505,864,549,340,585,397,378,998,644,609,939,754,222,682,664,947,26,512,718,415,981,986,531,723,537,865,877,30,437,404,779,370,234,419,255,643,795,899,949,971,690,853,577,195,359,935,551,103,302,636,701,85,423,86,797,370,15,160,121,198,508,755,482,756,156,929,803,554,541,917,269,736,810,844,638,417,160,316,138,712,71,619,658,984,87,602,864,143,785,271,648,716,640,593,861,237,853,271,77,327,659,218,917,159,926,947,821,537,147,561,62,993,978,865,331,890,761,37,46,151,18,840,483,442,462,804,771,808,756,701,288,853,997,734,747,709,868,475,574,122,480,703,992,625,157,552,231,246,10,462,951,317,956,30,145,418,484,50,262,658,216,455,62,608,533,903,895,621,646,132,164,328,81,546,547,478,906,202,895,360,823,618,586,618,562,55,16,639,467,653,728,77,2,930,887,432,279,226,819,181,930,827,560,337,34,969,303,711,330,496,960,307,856,374,738,490,303,835,41,980,570,903,989,802,524,672,798,770,111,415,37,26,396,398,192,764,282,641,509,706,951,212,818,392,842,305,64,13,387,425,494,198,635,593,438,924,791,773,243,138,517,929,866,962,698,312,399,560,129,255,603,477,578,155,794,573,514,93,320,751,278,770,91,674,157,162,342,459,347,979,110,231,776,651,525,666,586,325,667,646,639,518,858,842,626,702,952,428,25,381,761,859,990,261,644,300,65,775,74,583,871,261,0,741,714,458,24,272,394,989,494,990,550,608,226,750,978,864,424,675,724,910,14,619,88,476,790,162,546,245,879,756,819,676,694,933,586,478,630,91,536,260,566,116,568,458,343,381,201,482,976,506,614,127,604,181,682,981,731,949,93,463,704,383,965,859,9,261,105,681,148,384,204,203,200,801,322,250,2,648,717,700,991,171,417,10,948,951,595,929,62,217,311,154,691,961,759,131,504,190,576,478,236,419,505,152,655,568,978,172,744,662,818,687,342,352,703,605,774,578,727,117,722,595,243,451,709,872,220,82,654,522,975,282,204,886,31,898,900,730,176,771,938,535,657,83,13,528,200,200,556,160,255,21,21,123,904,320,286,71,689,154,476,776,292,796,379,22,45,307,73,120,243,890,665,594,27,749,27,991,801,863,963,48,513,596,727,928,681,127,761,998,371,433,971,151,2,309,110,852,790,154,59,595,625,383,390,829,277,671,377,384,627,653,569,802,11,460,934,945,902,58,824,22,771,261,895,54,552,641,931,839,102,613,554,829,889,29,965,637,911,570,823,521,260,518,380,358,159,678,103,547,387,827,564,36,269,18,18,896,277,887,23,344,278,362,180,504,273,904,937,829,10,502,648,390,610,880,998,497,494,688,589,140,886,608,146,815,231,160,889,361,620,655,193,264,650,785,736,811,859,752,834,814,751,981,871,404,397,198,327,346,456,975,460,202,954,890,793,470,828,272,311,55,837,175,132,560,709,555,776,704,803,817,920,632,597,678,704,340,905,783,335,759,14,900,750,762,819,98,970,842,84,984,46,603,880,179,948,794,585,975,95,68,412,962,39,537,532,911,19,897,821,662,669,302,693,468,262,67,870,929,32,173,374,984,955,302,412,414,684,143,25,950,882,870,48,744,962,323,587,786,313,312,601,395,647,185,275,767,478,928,464,617,11,958", "319,12,376,198,573,650,553,987,734,757,606,283,977,503,610,387,171,720,617,775,685,146,55,216,538,968,703,561,597,53,593,319,544,878,841,347,110,130,33,913,54,670,911,3,637,176,363,602,634,707,603,130,222,564,81,860,987,779,941,396,265,250,709,152,222,308,908,176,733,354,295,967,904,21,938,320,840,764,673,521,124,630,511,210,90,818,320,27,726,880,345,247,574,817,140,786,101,920,611,287,218,241,911,477,839,428,799,414,203,330,401,613,715,335,934,910,556,770,515,997,240,438,136,85,972,698,413,513,475,807,922,753,56,427,338,58,560,663,181,108,809,458,945,658,161,760,488,358,927,397,459,530,673,3,100,299,732,838,38,637,401,536,695,382,145,640,654,664,790,666,798,86,98,97,830,527,370,762,146,548,375,169,45,538,494,327,593,705,380,185,359,331,972,943,431,281,216,757,882,276,577,956,524,641,486,18,137,480,4,20,711,888,916,511,157,227,358,64,265,540,633,424,108,755,585,674,939,219,233,879,135,676,630,343,785,536,912,827,815,184,622,462,543,13,688,548,270,929,188,676,641,364,375,902,383,184,775,479,172,260,729,792,904,267,980,480,42,598,549,592,523,550,427,1000,606,605,550,222,350,359,582,349,366,34,340,938,587,266,977,370,517,493,362,276,557,861,643,345,178,632,251,726,753,386,433,930,699,698,564,499,189,37,573,396,675,632,291,36,589,810,943,468,385,358,234,473,970,174,485,77,751,697,760,508,874,665,599,363,947,980,136,844,105,703,434,427,552,182,854,301,910,806,32,958,532,784,610,23,924,759,130,769,274,839,985,197,291,869,932,499,474,414,912,14,197,898,632,589,228,387,545,562,889,411,228,863,518,610,719,752,260,853,398,129,338,539,248,645,892,800,826,550,352,83,272,107,802,149,748,939,805,61,973,688,124,626,523,867,565,922,178,356,370,222,822,175,627,771,846,431,521,885,737,357,806,980,889,507,293,413,415,285,454,379,344,771,305,415,256,947,798,493,963,273,537,119,366,743,805,66,457,864,752,347,765,701,102,809,849,538,338,72,861,409,861,490,150,574,738,400,607,650,24,207,884,641,82,688,278,204,233,253,810,917,323,613,777,291,115,5,399,190,152,439,967,289,635,916,554,367,632,97,978,574,234,931,199,936,251,159,594,227,19,606,200,63,590,361,329,481,509,491,561,623,921,942,293,502,837,945,473,447,180,258,652,234,76,745,630,969,705,138,924,518,162,23,922,638,357,990,518,726,936,66,861,614,212,415,582,873,113,906,779,81,835,183,421,121,570,394,839,450,522,515,728,821,741,0,707,377,861,264,34,509,929,817,684,699,958,510,361,60,965,360,660,501,529,198,5,676,848,325,484,332,320,545,671,403,947,386,459,889,928,400,615,441,386,642,896,776,91,721,665,147,823,240,369,882,887,358,480,930,233,441,39,633,838,938,286,909,64,734,446,920,89,228,802,29,393,494,409,397,930,824,773,559,170,494,366,566,479,801,599,418,536,752,142,571,327,183,185,60,538,28,327,577,621,213,846,781,431,413,177,503,662,432,766,227,157,551,154,901,954,184,595,671,800,709,179,777,943,112,4,853,812,809,240,994,272,720,161,516,504,331,742,243,891,839,791,362,687,285,496,415,801,737,598,754,297,128,430,146,454,17,536,123,512,97,432,260,398,361,458,60,166,878,379,732,419,760,113,751,320,836,264,473,659,190,408,700,737,512,813,64,35,62,243,846,760,193,22,277,323,385,960,681,145,289,512,443,611,738,194,71,147,71,960,747,138,428,938,611,177,176,619,638,904,608,221,426,976,158,651,963,78,649,579,684,108,81,20,801,856,736,744,94,645,57,560,725,209,166,539,445,299,582,13,45,647,329,367,48,544,682,360,748,236,39,769,577,478,234,330,614,228,573,974,292,855,689,6,755,745,436,779,164,67,698,683,203,483,687,865,222,603,206,582,874,57,790,245,356,704,127,3,151,160,396,83,610,549,183,416,581,556,937,467,616,863,349,67,797,46,343,150,595,359,545,600,836,652,494,434,415,482,464,819,739,465,863,857,435,998,575,528,779,131,62,609,570,616,59,111,384,987,191,255,400,508,683,274,397,260,277,758,527,598,447,196,270,216,319,67,830,201,117,776,99,456,305,435,675,91,775,440,519,3,113,988,288,820,61,759,784,248,900,236,959,242,343,893,816,823,118,835,551,99,599,730,685,458,121,830,573,169,458,24,507,633,271", "999,618,620,900,432,872,779,457,822,141,792,156,536,347,342,518,539,988,665,556,567,706,670,508,951,735,119,129,474,670,175,202,836,347,77,110,726,236,463,882,662,857,157,940,968,89,888,922,793,592,171,467,576,850,406,757,31,620,150,247,632,510,304,675,802,104,193,700,954,227,276,762,862,868,955,681,925,247,115,5,747,333,526,404,876,871,170,603,280,631,512,159,568,638,895,53,255,68,113,336,69,549,869,917,884,174,222,339,391,924,912,411,436,639,493,775,902,768,224,326,389,17,322,950,651,807,719,15,287,317,725,334,545,331,70,200,849,924,770,586,385,588,345,587,20,437,132,789,758,625,303,269,314,359,977,824,812,311,265,112,420,915,94,139,324,896,337,830,436,417,446,426,885,923,725,350,516,657,416,246,13,261,266,52,663,160,964,844,974,671,409,987,769,24,731,961,65,444,4,541,985,859,522,655,466,905,471,278,840,543,886,118,236,929,448,394,848,195,121,334,921,566,355,657,120,205,601,59,316,427,208,812,967,137,985,673,908,614,10,805,530,986,78,823,324,552,755,336,208,181,279,963,812,996,569,218,676,291,240,299,865,294,344,402,558,365,972,877,678,827,111,279,310,827,745,416,105,539,851,193,843,882,995,823,989,800,854,573,345,988,269,17,406,646,802,549,586,588,672,739,136,825,308,551,966,771,280,93,755,37,265,922,347,118,632,729,693,809,75,890,215,582,660,156,795,400,253,821,821,502,131,81,628,584,752,848,625,466,293,238,281,908,396,948,738,235,484,468,328,880,216,237,675,981,948,125,545,930,732,618,252,199,974,413,673,399,374,704,861,47,790,81,321,453,893,324,276,849,597,66,555,153,681,59,695,185,462,605,483,216,93,107,830,468,744,65,170,197,456,611,886,943,430,777,867,876,639,312,438,687,77,775,188,31,36,804,558,559,812,856,890,506,143,89,630,106,90,64,231,786,145,317,978,3,703,207,687,788,271,330,540,858,424,751,652,372,703,921,969,840,191,595,646,946,378,729,32,649,655,401,798,114,470,823,986,847,375,945,474,567,320,144,417,930,365,915,495,616,128,769,881,714,333,20,545,987,396,23,521,122,521,672,584,424,221,758,377,59,363,885,529,343,655,833,538,397,168,652,437,522,16,762,779,5,154,424,481,802,32,292,976,709,780,647,438,938,159,22,632,314,740,368,773,250,181,655,328,803,363,596,796,998,870,712,806,822,475,369,919,412,425,7,260,151,979,574,675,875,649,598,315,100,124,25,562,672,848,396,963,577,935,829,512,494,6,94,668,543,672,754,560,140,802,310,826,987,714,707,0,359,112,492,128,527,713,825,799,860,605,455,544,459,115,696,20,135,961,265,495,36,182,887,82,499,173,145,111,504,283,621,749,306,509,535,412,129,639,703,98,476,508,732,272,970,983,238,325,506,366,192,884,585,837,259,70,317,717,529,654,89,976,910,319,414,69,390,803,720,197,393,302,375,350,214,288,769,622,160,634,648,852,18,745,912,18,587,60,897,392,458,123,783,479,130,142,748,566,860,891,779,908,576,106,761,779,377,870,154,679,537,20,818,764,306,688,338,971,938,855,121,980,394,714,37,597,303,269,269,151,325,543,186,760,95,930,539,904,523,156,707,198,829,104,551,892,800,614,569,695,920,927,584,393,402,498,385,752,545,762,345,1000,792,118,170,862,412,277,49,6,763,102,412,107,509,213,422,374,368,547,520,206,468,992,470,619,514,943,444,528,14,301,368,873,303,766,379,479,440,742,483,685,244,429,536,895,432,189,74,906,828,36,244,18,657,671,639,448,926,978,312,829,678,377,34,792,508,661,205,137,789,193,882,746,577,795,204,661,130,660,539,172,917,712,359,837,86,64,813,598,82,26,878,861,137,214,947,243,324,263,182,508,842,204,921,914,829,335,855,561,395,807,624,661,86,56,386,486,875,506,171,876,243,436,542,671,592,231,673,577,948,612,28,97,209,148,885,837,157,624,444,333,621,152,140,681,165,162,806,220,4,316,620,924,80,100,349,585,841,833,610,866,355,791,446,923,493,548,406,194,390,288,394,82,419,828,898,373,591,617,598,495,789,116,180,350,534,203,341,498,315,516,829,797,182,811,573,687,890,608,314,671,325,292,115,933,287,897,556,512,672,397,993,859,170,602,158,153,463,401,135,669,611,529,397,913,960,617,301,752,282,502,700,336,141,683,5,928,258,430,176,904,15,214,549,712,630,931,620,952,882", "409,150,766,928,919,155,629,97,298,25,879,374,253,230,572,277,457,429,820,797,600,160,270,77,734,158,591,455,279,178,481,524,163,230,407,659,677,472,506,331,827,569,972,856,335,760,546,847,402,712,647,436,219,829,325,7,279,856,296,37,676,410,522,746,679,279,633,625,633,736,669,41,143,890,526,921,596,274,190,307,992,112,460,336,253,168,166,797,633,851,134,690,256,805,115,823,930,539,437,370,855,279,949,134,384,607,96,484,815,583,134,110,170,622,483,867,181,856,283,457,392,561,970,168,150,60,114,673,662,33,722,462,789,575,725,269,168,836,412,251,514,796,280,459,832,5,975,694,771,386,807,142,446,257,996,89,46,16,820,54,691,562,815,284,526,606,199,818,223,758,219,568,456,331,448,998,591,638,960,779,911,776,528,11,673,628,45,366,349,831,803,486,229,624,32,285,385,959,874,21,309,253,549,208,650,963,435,844,311,418,270,880,610,504,236,715,483,55,133,177,341,473,909,825,982,474,328,501,255,652,940,856,522,703,824,685,527,127,791,670,618,556,534,119,556,959,722,206,721,657,231,173,131,617,619,637,318,614,826,263,715,430,176,806,670,760,592,51,770,520,386,989,291,956,367,455,566,783,368,46,146,57,341,602,809,751,922,692,229,815,493,51,471,478,217,425,503,735,661,133,230,564,584,737,222,106,65,123,889,956,856,754,582,470,532,343,483,901,94,939,779,179,308,422,496,98,70,203,635,446,530,365,227,819,909,385,751,872,570,529,954,972,913,612,750,192,722,696,613,997,766,899,685,788,458,468,909,230,54,753,322,708,573,804,323,37,129,291,36,778,212,883,195,218,30,794,101,343,706,600,782,277,987,103,423,70,880,165,784,740,271,968,163,854,177,778,91,750,744,921,719,484,57,286,915,357,191,21,251,396,71,959,633,786,103,281,349,355,338,476,361,376,241,789,628,761,677,389,824,348,184,706,729,425,936,928,589,896,451,968,728,274,392,100,623,794,259,789,593,214,744,907,820,476,944,994,730,438,666,296,595,181,564,753,313,348,388,852,377,690,715,995,165,190,250,783,702,577,949,714,908,611,274,482,395,19,487,975,286,773,562,233,684,64,28,228,317,452,84,29,860,454,681,946,776,158,968,641,925,257,615,640,761,668,468,181,169,631,388,720,675,165,710,480,277,306,153,754,876,858,300,469,277,47,779,808,564,243,894,548,248,492,10,542,456,647,53,630,337,131,678,341,899,162,668,405,493,293,260,83,287,386,973,191,111,381,573,827,552,617,509,869,300,255,100,768,913,755,546,738,276,605,38,323,792,33,458,377,359,0,953,269,64,758,238,888,832,16,946,615,882,542,347,549,801,455,43,196,599,270,183,803,127,565,723,682,962,31,280,906,833,286,538,273,432,316,239,519,835,104,290,851,701,906,63,157,515,116,95,946,879,55,439,733,997,581,380,281,490,280,389,803,207,851,776,646,653,406,334,189,122,335,498,626,176,213,919,816,190,42,855,573,120,761,752,249,484,913,818,576,92,444,952,172,913,604,332,986,917,822,871,584,113,229,878,594,810,127,254,484,153,374,627,401,78,527,317,629,72,164,598,49,349,686,337,551,272,203,545,851,277,714,305,842,735,550,960,120,124,102,66,966,105,631,803,934,573,47,187,490,597,838,528,1,69,193,210,641,230,471,99,414,475,977,468,243,90,927,602,577,671,864,906,501,568,515,973,779,980,894,292,938,553,244,912,224,83,418,644,98,665,278,991,962,743,534,711,681,990,926,846,385,505,914,652,176,210,469,201,620,394,895,833,161,258,888,874,882,203,576,84,23,861,281,63,733,105,407,302,905,807,565,845,391,716,432,626,714,894,41,992,887,60,968,394,334,245,432,701,393,348,430,491,142,855,129,542,410,147,763,275,854,708,984,393,790,339,423,242,243,122,217,72,343,592,762,389,692,90,594,596,263,772,902,510,150,324,584,509,8,780,272,923,599,670,429,282,472,380,652,553,784,10,46,134,862,382,910,480,180,872,485,633,276,617,531,463,523,652,10,843,210,770,865,223,812,492,208,945,152,760,742,744,315,228,269,398,421,386,980,945,161,10,373,961,962,132,333,822,372,751,434,354,80,797,703,294,359,503,805,219,907,161,697,349,360,353,476,710,678,717,631,164,354,933,573,538,275,889,660,67,394,470,355,460,353,21,328,450,362,378,818,991,955,328,142,751,492,313,258,227,479,881,773,900,252,90,818,929,557", "145,252,552,344,207,196,532,926,854,239,499,976,610,480,664,467,947,26,388,144,524,752,165,81,53,368,255,809,924,210,556,141,892,28,878,108,329,881,929,742,504,525,274,311,874,589,645,683,653,935,157,781,262,874,389,14,26,919,951,839,730,823,559,776,23,816,630,670,191,510,18,608,882,764,163,805,76,932,909,599,763,248,914,456,181,984,528,352,413,295,637,939,405,413,660,250,215,684,184,892,352,715,645,471,85,447,603,225,892,445,929,643,765,858,297,846,306,423,698,952,410,491,980,655,989,545,892,216,171,350,966,40,592,100,691,137,739,986,268,833,285,55,551,764,388,720,454,194,656,675,893,765,23,679,528,465,388,381,850,380,193,980,50,260,128,968,302,930,430,134,968,161,622,465,637,986,179,464,76,320,850,878,721,304,377,891,839,699,547,169,708,357,547,257,504,71,137,691,607,936,664,843,749,787,151,795,814,379,794,826,806,222,765,939,421,580,491,387,833,623,561,653,414,857,696,219,947,428,885,432,614,645,712,449,717,713,504,927,662,217,317,975,905,52,292,533,816,830,660,304,286,645,347,956,418,751,684,666,532,971,925,870,38,653,47,266,517,960,180,623,763,746,382,580,559,946,753,637,320,749,528,291,978,996,17,763,883,188,290,881,766,744,569,105,732,52,869,997,302,240,227,665,395,129,988,349,247,315,599,31,206,378,682,613,527,590,356,571,271,468,363,189,739,854,497,211,809,117,404,488,205,295,925,92,399,974,31,861,609,992,706,199,310,630,177,635,541,400,710,865,938,90,942,384,222,213,773,456,452,641,735,417,124,942,232,358,277,528,415,439,686,904,764,718,308,225,408,378,431,971,591,297,137,241,337,777,222,608,274,572,971,579,197,384,486,17,424,933,976,625,947,115,891,333,567,772,249,227,616,292,317,743,83,525,968,789,230,123,929,101,23,943,469,260,799,858,708,281,721,981,717,263,457,765,262,594,879,32,296,188,802,950,709,169,497,869,842,923,439,139,521,35,811,339,7,365,121,165,767,961,392,543,600,631,760,694,675,676,852,195,99,628,115,858,32,70,333,286,209,500,897,444,669,198,226,857,701,270,533,577,310,101,583,885,92,591,264,66,784,856,701,322,444,711,713,306,441,664,815,827,685,268,144,373,843,95,987,636,368,577,170,798,454,383,939,555,756,608,383,431,943,826,450,304,552,243,415,660,595,23,54,794,742,253,684,884,452,320,707,198,572,507,789,273,844,402,471,745,459,476,557,330,257,67,632,763,602,202,264,881,535,420,552,647,362,298,958,6,576,681,175,922,775,29,59,298,24,861,112,953,0,597,526,44,829,995,485,604,67,769,716,464,878,27,502,254,889,332,97,550,877,878,511,201,169,844,202,937,862,294,623,397,155,103,472,857,750,237,446,355,260,548,995,400,874,703,507,144,847,212,870,898,733,135,922,438,19,356,467,208,280,433,927,278,430,328,515,527,35,108,913,15,254,254,881,577,853,29,27,666,444,466,136,220,643,151,827,342,752,535,759,564,126,274,397,244,609,607,213,239,740,877,871,13,586,81,742,699,525,385,555,661,418,662,247,72,417,682,860,12,920,976,838,190,737,113,931,711,999,173,980,458,855,713,4,655,637,879,89,943,426,351,845,419,347,690,44,514,860,176,575,824,283,352,128,60,749,162,232,70,831,975,812,812,216,349,242,160,14,830,406,144,530,152,389,13,128,972,762,57,638,527,563,489,977,138,634,646,174,284,703,959,313,831,282,311,706,438,91,345,984,829,256,516,245,242,852,886,866,233,247,570,969,943,308,74,414,351,902,120,870,209,136,568,980,270,146,420,816,606,595,620,824,588,625,150,37,300,97,455,524,504,866,607,151,63,220,771,258,705,997,946,232,221,10,182,439,278,375,44,712,819,218,48,859,309,851,933,668,872,909,775,51,829,20,727,162,770,520,912,937,645,495,457,432,128,392,945,824,598,352,47,91,397,490,538,269,387,274,825,967,636,957,587,573,560,849,533,664,312,585,205,980,628,705,36,561,302,82,708,669,791,879,45,734,737,196,373,741,83,517,75,250,317,409,778,788,566,548,738,165,108,374,382,716,890,223,547,44,635,257,891,457,687,497,56,359,590,393,855,525,456,914,698,608,27,338,102,517,543,949,276,453,351,971,382,846,512,414,223,6,101,902,751,996,114,984,688,513,253,94,186,801,415,917,32,151,677,802,929,593,194,868,712,112,184,11,608,196,601", "748,880,98,688,846,749,989,439,620,670,599,598,620,188,450,788,73,677,90,632,726,76,849,198,439,695,67,887,319,186,451,161,240,77,751,99,913,973,550,856,81,780,191,288,691,428,428,586,756,631,975,948,371,105,884,755,245,978,821,525,880,552,946,3,90,606,467,920,10,412,301,473,808,218,628,487,948,854,165,142,861,878,894,999,51,515,957,147,878,974,947,23,878,236,208,184,886,351,841,234,212,886,766,196,712,265,16,982,175,315,106,671,723,478,390,902,891,568,137,553,700,832,146,416,528,599,471,767,421,90,92,239,448,558,76,751,560,168,215,691,593,642,250,513,987,932,706,190,872,444,984,34,367,224,669,311,774,106,405,313,784,267,390,848,644,882,942,631,873,32,195,295,217,556,244,684,908,599,642,649,340,223,791,459,597,669,541,644,265,73,667,634,331,908,366,116,970,656,831,695,747,524,821,693,800,772,866,618,937,80,275,966,209,921,698,970,960,570,634,619,323,363,447,253,653,18,164,946,118,663,178,856,244,322,260,742,314,528,638,25,650,346,532,909,799,490,476,644,375,67,825,660,501,324,509,734,52,608,819,315,595,517,654,367,636,207,754,171,621,40,804,176,863,133,859,223,611,902,217,321,742,907,905,261,886,78,184,212,597,814,783,709,54,154,400,814,673,894,431,525,544,993,557,691,635,369,264,270,153,327,541,867,895,83,987,988,693,631,800,513,165,402,848,953,814,571,819,348,584,279,905,498,437,346,368,387,854,296,456,363,785,517,674,197,646,201,259,100,72,619,514,732,687,778,103,796,812,582,240,568,298,368,322,739,924,214,943,387,759,63,397,195,114,610,817,600,206,512,639,237,729,938,150,701,779,20,201,399,646,678,470,588,687,584,782,998,350,550,240,604,680,353,842,809,721,10,125,75,417,491,360,404,340,541,162,194,753,588,101,192,287,471,879,677,372,152,969,308,556,226,83,849,583,527,459,617,361,620,147,294,280,856,905,938,316,882,211,372,467,970,171,201,693,242,804,904,989,261,742,201,237,731,366,141,679,988,578,470,244,472,887,18,883,919,950,124,520,419,357,187,862,488,497,745,487,298,556,251,553,411,481,488,950,649,878,287,528,514,433,663,371,495,562,292,599,785,695,613,510,624,133,913,670,847,874,837,425,805,782,941,545,186,57,433,663,663,767,431,600,681,483,356,865,164,627,968,421,511,314,361,685,196,441,138,876,735,292,830,306,988,512,687,389,471,715,906,471,41,259,517,280,367,524,835,123,782,248,413,490,224,950,184,817,800,89,427,330,873,80,505,872,690,984,610,209,791,272,264,492,269,597,0,226,241,216,788,454,988,462,186,247,131,410,799,226,371,531,80,427,85,698,482,487,599,104,39,141,728,516,551,205,359,912,409,691,425,396,520,801,765,131,703,78,369,133,369,143,838,810,31,72,896,941,283,92,503,53,414,805,314,723,790,43,666,818,925,4,512,517,571,72,420,830,135,515,689,478,882,300,594,649,708,349,98,141,900,971,519,912,927,804,748,445,399,453,256,920,461,467,571,58,357,251,295,33,27,560,292,189,954,319,422,334,752,30,417,441,273,665,381,316,846,844,709,46,242,751,693,43,595,140,648,903,774,182,299,57,772,968,49,258,962,507,447,760,398,795,112,482,647,937,339,110,745,189,74,365,370,479,503,765,942,111,861,842,959,582,137,417,345,21,681,673,921,80,496,918,219,753,344,474,400,601,660,66,202,818,654,136,889,686,566,568,187,652,105,222,505,774,164,369,510,49,340,804,217,583,232,191,132,599,612,642,778,996,603,61,210,24,892,946,378,620,611,590,10,963,426,441,769,99,702,852,401,976,343,161,77,320,947,526,511,788,687,464,393,796,371,962,947,501,256,498,49,898,527,132,854,525,803,451,577,792,692,9,148,481,878,622,629,491,438,738,530,984,231,902,657,375,713,379,680,676,370,494,153,865,769,586,568,665,995,804,544,305,838,963,46,284,535,178,842,57,486,243,774,784,543,719,760,694,702,623,733,598,361,330,662,516,465,141,334,832,111,316,351,998,141,178,793,180,596,486,553,274,193,534,260,203,968,573,537,937,308,653,737,190,489,831,214,831,830,467,119,223,712,813,731,11,759,931,638,575,521,844,843,258,453,470,442,943,902,227,342,308,381,159,751,489,893,724,536,177,319,109,82,664,287,784,417,972,84,422,155,519,959,733,39,994,317,842,378,855,692,748,194,857,323,882,150", "136,429,392,842,584,154,160,14,471,315,627,920,748,347,226,297,992,525,185,973,678,815,357,184,61,703,997,939,871,597,955,45,870,182,696,536,466,130,765,208,462,753,185,895,377,232,270,370,44,11,251,94,8,606,789,520,27,580,13,579,187,181,821,417,704,597,20,636,713,776,485,194,50,237,910,437,843,64,230,991,624,443,74,631,987,752,449,850,59,997,271,219,876,66,815,19,205,475,357,848,669,474,538,948,695,922,889,812,322,201,241,528,694,48,676,694,838,521,944,622,82,983,827,837,967,921,107,293,899,222,329,928,354,143,985,600,911,694,944,774,549,381,13,945,434,952,54,744,745,123,391,70,361,281,577,367,986,171,387,240,474,668,548,908,810,377,259,358,1000,382,609,77,254,448,145,943,762,890,262,185,184,354,417,279,175,411,388,336,108,42,161,852,82,267,119,210,48,881,576,528,97,949,118,707,780,769,740,217,644,366,541,691,355,876,722,934,21,967,811,583,95,695,191,990,769,455,240,384,120,466,463,795,63,687,76,589,630,325,701,546,65,875,84,623,304,407,365,111,946,519,670,497,213,980,288,813,685,109,463,878,741,228,435,615,98,642,641,175,534,729,292,931,535,578,652,219,608,333,172,778,894,694,588,79,716,413,615,407,772,952,875,100,920,470,405,480,10,866,75,312,438,164,100,273,294,958,107,281,388,812,635,570,273,302,898,724,665,28,29,612,504,971,243,563,503,622,244,781,542,107,525,866,595,886,692,361,399,606,118,309,860,263,419,25,395,602,231,649,112,464,845,456,851,754,840,859,632,516,82,10,907,224,274,909,962,689,725,777,181,349,478,600,797,49,305,761,808,584,538,726,34,340,692,389,102,61,671,949,950,414,332,784,906,776,41,134,292,217,491,386,597,45,351,14,312,300,834,494,642,427,626,43,573,616,497,750,829,217,502,425,716,828,661,797,632,465,756,828,958,220,824,673,528,580,17,718,73,269,152,866,261,986,26,15,682,995,815,42,813,177,470,953,972,822,240,132,678,637,430,901,199,720,9,94,184,256,833,293,368,942,800,906,893,586,959,467,552,208,879,846,191,126,785,808,582,678,961,394,490,135,491,746,274,712,396,727,435,515,682,134,501,575,197,874,518,851,477,850,988,744,453,249,325,378,414,230,349,8,486,173,518,145,784,802,270,366,541,966,620,446,707,501,231,572,424,437,782,398,26,212,451,206,577,966,606,171,194,614,222,867,111,518,66,725,511,851,860,176,795,222,912,660,434,447,716,372,105,342,24,949,811,342,726,706,456,894,269,477,130,681,717,149,801,424,864,103,394,34,128,64,526,226,0,20,334,59,94,894,836,260,435,466,51,866,814,726,403,794,422,304,471,182,79,906,314,418,469,787,561,579,396,875,957,728,993,187,629,99,768,385,459,868,95,204,958,275,932,415,220,408,644,24,773,328,311,198,768,144,610,845,392,681,635,851,748,928,15,496,233,298,807,240,449,162,967,679,968,237,28,211,938,227,473,342,971,679,19,164,835,900,623,41,13,656,347,755,632,219,915,592,234,539,63,262,149,411,705,190,733,123,648,99,989,476,319,964,433,639,207,199,630,121,316,993,426,350,210,352,244,211,917,13,946,789,196,185,594,561,172,944,794,367,60,894,153,317,929,442,708,290,694,153,371,580,183,770,763,998,472,868,463,693,996,319,497,873,835,472,354,548,114,610,252,723,760,695,51,7,490,782,426,406,638,513,637,210,94,680,32,131,318,229,758,501,942,681,287,171,979,156,979,978,470,126,938,628,989,498,960,325,964,418,356,952,620,466,168,867,672,14,449,476,468,753,135,663,275,871,375,175,613,477,530,71,870,889,692,339,593,32,14,718,530,872,412,975,985,74,314,125,531,93,895,279,563,625,466,830,493,52,493,777,858,973,151,992,415,22,229,143,460,111,575,835,950,168,354,659,186,785,436,23,266,580,863,75,482,573,769,675,934,113,371,376,356,803,798,961,98,761,405,237,198,188,598,340,709,853,393,761,632,963,9,417,391,6,962,583,644,38,176,703,613,431,826,959,877,204,102,55,693,773,631,986,15,343,437,847,733,695,908,946,960,491,317,653,887,567,339,951,472,660,548,574,459,836,137,249,884,982,863,389,34,480,111,174,891,278,278,642,418,245,80,71,364,32,968,981,482,286,88,820,195,333,826,56,647,23,296,546,241,313,208,681,515,215,242,297,968,686,482,694,46,879,122,965,137,436,71,159", "226,309,700,506,704,16,198,653,312,445,991,966,379,631,67,7,980,852,179,558,743,707,211,304,532,570,154,705,57,186,570,862,803,54,236,757,878,565,984,466,12,772,265,749,610,345,618,57,683,559,252,605,542,845,416,636,70,394,855,409,142,357,526,751,361,430,523,440,343,335,255,384,771,393,161,465,249,42,373,594,788,884,756,764,481,142,99,82,30,857,238,975,518,73,781,187,7,104,210,67,411,670,880,475,249,368,563,565,673,66,862,164,145,646,385,650,461,145,12,152,662,898,94,898,761,469,709,64,474,731,545,751,324,988,23,576,487,443,540,676,981,402,249,992,625,589,246,257,504,264,59,400,784,639,739,870,990,18,847,536,576,617,4,866,869,233,237,30,352,914,702,960,160,400,918,173,660,102,571,517,80,893,451,62,42,839,794,708,184,71,826,886,863,126,814,636,429,546,91,897,338,74,668,890,978,9,69,298,719,303,904,651,119,282,138,288,611,909,612,894,347,371,231,235,274,647,80,354,632,964,385,377,200,324,325,69,233,59,198,783,550,966,390,68,146,926,435,603,976,150,925,854,655,943,868,506,811,560,238,62,400,220,782,922,204,901,169,869,546,48,55,469,381,369,371,764,149,774,754,155,622,463,960,784,458,563,454,171,111,900,778,79,387,485,158,469,974,856,914,820,263,393,885,825,993,851,373,328,544,430,86,804,517,915,341,374,584,850,909,721,915,158,174,254,195,663,571,665,640,758,394,750,746,521,95,946,248,770,94,26,691,828,304,595,94,42,70,15,882,681,167,950,161,616,854,117,583,327,189,467,252,245,168,533,241,497,103,736,939,9,28,195,648,781,769,900,161,279,501,811,663,467,168,802,816,542,502,81,163,878,836,658,423,626,367,490,527,738,694,225,967,737,328,962,944,905,298,834,460,591,857,242,104,973,644,523,546,938,113,533,603,671,863,943,435,22,568,603,944,646,846,493,550,461,98,501,452,868,439,476,525,616,253,673,840,35,586,787,111,627,808,40,279,945,486,723,42,941,225,295,27,228,466,268,109,146,434,641,393,751,421,473,674,300,600,129,464,133,151,98,334,680,150,885,987,748,801,696,988,145,428,661,772,535,424,735,463,172,317,574,156,698,23,304,355,915,9,106,714,697,953,555,212,407,12,777,222,287,861,767,918,448,169,498,787,600,411,886,84,460,90,914,87,783,960,374,171,458,775,325,459,139,256,771,839,35,627,861,344,493,925,823,457,831,379,780,639,203,700,881,827,631,430,705,457,914,987,532,450,834,530,137,155,639,81,606,973,692,50,675,59,265,925,912,650,735,989,509,527,758,44,241,20,0,581,597,504,7,641,722,567,373,745,952,593,768,614,142,373,284,968,298,422,355,563,534,807,769,425,915,874,100,251,952,961,797,816,200,408,710,23,11,191,807,30,257,167,674,412,138,385,719,67,420,668,244,527,234,280,627,498,38,908,195,882,800,303,964,886,267,112,96,540,835,20,942,322,803,429,104,573,313,368,559,762,436,29,466,18,296,352,678,655,240,367,402,620,499,744,320,509,710,703,866,102,355,941,874,323,111,297,784,756,521,472,455,333,493,653,344,780,675,583,603,695,293,403,377,482,298,835,432,500,104,929,809,151,590,34,354,4,774,525,555,160,608,494,255,593,713,939,297,84,470,767,176,851,321,474,548,192,699,8,391,379,605,309,454,506,992,829,4,805,59,393,648,574,206,486,192,390,747,1000,175,728,268,857,908,551,588,434,973,44,925,784,58,251,52,355,923,364,816,900,191,279,385,805,696,452,875,725,580,280,596,60,662,805,469,777,837,96,206,387,546,939,195,305,689,161,740,794,15,832,296,125,422,803,594,438,158,782,609,92,28,359,391,918,667,191,730,30,298,358,457,889,459,164,876,924,852,419,421,972,476,111,906,944,488,409,71,354,908,780,136,699,711,860,644,986,494,554,817,427,92,993,230,218,974,407,568,800,359,315,658,384,963,307,759,914,923,92,795,907,929,103,348,512,740,631,874,219,299,56,494,431,785,134,519,992,319,202,963,803,535,219,786,154,953,880,90,869,341,453,907,723,195,836,549,293,112,910,48,887,354,262,404,701,286,555,548,812,657,675,188,993,828,718,979,538,815,881,598,197,503,706,701,832,680,819,794,855,830,590,599,359,995,217,130,799,145,27,789,814,927,912,993,988,228,987,287,326,596,565,791,51,710,965,680,737,944,86,908,589,224,161,891,18,97,585,340", "853,539,723,946,118,648,455,477,524,578,450,35,66,44,419,126,442,421,111,287,404,965,708,339,667,420,129,998,773,983,264,162,533,871,423,180,884,232,307,456,449,117,387,30,134,89,386,86,696,509,2,592,193,387,803,762,580,430,347,739,704,911,548,803,450,41,100,549,447,632,673,13,663,87,629,936,389,691,283,563,420,998,836,613,322,572,106,980,891,51,265,641,309,531,480,490,54,849,653,848,339,471,694,290,975,107,665,848,168,895,836,351,780,965,846,685,333,258,657,418,255,947,337,187,789,530,81,212,633,265,239,562,984,48,461,188,295,332,273,437,766,973,251,707,326,911,205,347,649,56,208,409,102,23,960,606,446,926,575,390,352,835,343,564,515,62,241,447,637,740,569,840,222,508,774,294,16,598,901,54,745,719,623,101,89,329,475,693,206,967,815,663,408,351,392,754,942,860,598,185,334,414,227,508,201,181,540,592,850,641,747,621,286,700,388,691,85,17,760,860,549,228,51,322,689,31,20,623,549,191,497,763,134,596,783,254,171,198,604,228,929,490,307,85,188,409,561,393,364,20,921,341,967,766,997,361,648,692,76,211,151,171,40,882,207,232,418,621,154,627,912,452,787,934,160,724,215,889,908,365,965,352,682,278,126,49,397,265,383,338,431,924,92,36,270,405,329,749,446,284,443,998,791,51,871,844,523,749,282,778,144,864,449,812,99,59,524,157,807,568,828,811,496,457,347,216,348,40,996,13,103,702,941,665,557,478,944,189,396,997,592,168,781,68,399,944,507,940,536,835,272,671,225,512,766,935,380,782,35,178,270,94,224,860,254,731,464,14,710,985,943,901,525,481,879,788,41,165,526,160,616,89,317,210,519,917,510,974,22,299,724,509,790,264,994,984,126,695,270,99,761,902,873,204,775,547,134,682,135,522,372,882,216,632,691,214,865,937,566,961,658,920,885,841,861,402,488,711,999,417,399,784,467,471,55,695,785,735,758,481,50,743,826,735,642,989,179,777,979,576,113,390,151,60,541,21,796,370,523,796,989,448,214,389,378,619,857,812,81,814,61,638,17,696,361,331,727,787,656,437,863,686,835,650,324,715,15,812,294,366,614,893,498,325,576,515,498,658,98,443,554,768,259,509,623,705,934,499,785,538,280,125,800,82,895,881,421,708,592,47,556,566,617,822,141,262,884,514,115,17,773,273,937,674,102,643,266,658,633,15,471,693,186,308,347,329,919,197,67,586,604,582,919,800,793,973,887,751,26,901,237,702,201,554,65,697,630,777,741,152,432,621,190,515,293,238,245,607,185,235,585,683,775,268,846,28,494,929,713,238,829,216,334,581,0,172,837,804,582,595,472,837,427,742,788,381,769,382,808,460,796,283,785,383,707,700,107,157,943,291,255,299,314,960,602,142,518,218,60,543,886,40,381,130,928,307,359,430,303,153,148,856,903,475,742,494,762,969,404,883,671,17,573,289,713,938,910,812,693,291,524,11,659,72,268,266,352,579,698,424,516,512,821,344,170,976,730,391,637,50,870,762,356,537,743,771,103,318,762,193,680,623,913,646,390,515,870,552,282,560,986,962,502,280,802,797,307,693,843,394,556,656,133,653,715,929,388,883,692,590,239,105,843,485,189,736,147,949,780,46,273,675,193,966,198,171,684,141,944,216,938,984,877,104,5,638,144,862,342,902,709,742,834,208,234,324,351,813,746,788,165,183,121,492,319,114,358,393,835,190,945,637,465,419,934,599,432,567,429,512,490,265,581,622,681,5,634,399,807,705,739,336,483,697,806,984,792,360,26,404,48,233,841,245,898,420,558,677,521,250,392,391,462,328,978,663,864,666,864,956,548,219,275,511,358,179,987,580,394,253,601,647,108,202,237,590,23,462,39,384,203,33,93,514,928,297,905,637,312,345,751,382,959,692,285,867,734,51,473,809,987,451,898,986,863,554,291,481,931,514,608,403,167,692,109,926,777,873,853,2,22,855,479,775,547,816,810,348,297,747,702,11,666,457,194,316,174,183,39,144,350,505,549,28,879,748,511,554,585,849,723,438,557,695,861,696,361,44,638,458,736,873,283,124,926,825,135,731,402,481,881,903,459,571,270,95,610,589,444,304,877,567,72,262,879,391,826,56,943,125,743,140,218,159,397,978,397,159,631,680,907,102,546,840,591,856,411,747,33,455,470,612,430,9,783,689,470,155,764,805,177,394,173,667,836,815,766,603,571,102,652,501,338,204,353,588,487,926,513,610", "21,687,753,19,44,11,258,548,830,607,83,52,570,521,514,65,186,493,440,703,830,141,710,856,623,957,409,915,296,772,747,977,528,676,927,876,698,887,320,818,292,575,182,68,91,114,128,634,346,502,203,78,771,914,643,485,965,220,348,962,383,546,640,531,118,598,520,131,655,820,7,752,981,149,870,218,726,553,673,696,882,671,338,818,656,304,230,44,753,918,249,703,562,322,434,759,345,598,193,335,170,680,741,117,867,451,299,49,125,435,491,826,405,474,404,177,908,136,153,17,745,862,202,782,174,955,906,27,373,900,46,536,365,813,414,444,128,377,681,12,825,259,321,123,544,22,817,676,968,646,58,878,893,541,290,161,285,182,541,512,437,282,886,488,473,773,328,746,883,850,74,417,447,515,412,783,270,154,44,640,518,90,560,323,543,885,478,809,246,563,368,483,137,816,397,793,60,293,797,441,871,914,296,278,40,116,732,522,589,889,749,606,747,480,523,984,627,383,87,718,635,688,294,771,165,985,383,839,797,640,282,241,628,666,90,628,577,109,45,350,109,262,662,583,78,6,707,151,493,381,732,259,99,292,538,398,717,101,792,164,410,976,597,693,745,835,284,669,249,585,764,307,865,529,445,565,536,571,731,808,665,5,884,964,33,670,701,704,200,795,588,989,607,13,531,982,509,278,263,642,711,933,696,792,696,622,183,358,374,372,553,959,183,37,19,126,90,936,715,93,669,373,297,537,792,603,821,799,46,797,490,156,147,833,244,414,658,157,358,274,449,543,967,151,379,96,735,159,274,116,219,819,243,842,255,835,756,690,557,781,619,219,164,412,369,787,397,890,200,67,109,260,870,998,551,141,878,789,27,613,263,718,195,173,610,97,237,331,490,64,617,151,560,695,2,209,103,882,261,468,838,512,84,438,799,977,812,477,927,495,362,215,861,899,786,35,957,443,602,268,29,826,831,685,987,170,188,555,811,532,300,42,795,814,184,434,327,484,44,704,108,577,512,828,783,707,541,725,279,902,270,600,990,950,742,510,482,379,519,432,577,365,633,811,501,39,599,161,829,921,604,369,227,163,692,555,549,756,727,157,619,133,333,300,371,126,87,732,111,986,345,953,936,995,245,70,693,546,368,729,644,632,951,622,582,116,939,527,208,806,917,555,644,469,178,671,135,374,499,414,937,304,769,322,214,184,798,430,269,752,790,502,275,470,581,930,677,719,830,62,699,69,607,227,778,832,509,477,99,171,16,898,775,474,520,127,598,85,880,623,284,792,716,798,952,319,528,339,906,249,62,881,822,940,576,187,304,47,909,99,146,915,544,793,515,104,990,817,825,888,995,788,59,597,172,0,696,466,730,353,861,206,604,257,902,19,490,35,188,581,881,894,151,490,181,314,562,860,211,474,205,115,393,530,674,796,304,731,506,309,347,540,608,332,782,789,246,256,63,680,493,745,126,291,709,360,124,29,416,966,746,736,26,332,526,84,5,111,618,412,4,120,949,531,179,331,427,915,901,443,320,490,911,91,586,405,352,150,670,107,509,789,756,293,901,67,890,408,578,26,945,916,775,928,341,275,868,894,351,527,622,997,82,715,757,659,811,113,173,936,987,227,246,854,557,756,600,14,741,845,104,450,371,868,243,738,517,510,259,508,273,52,840,226,554,154,537,551,801,965,687,385,760,865,833,420,904,85,363,270,418,241,189,899,82,207,546,633,961,829,65,474,818,593,998,784,636,314,537,842,479,673,83,408,398,470,356,754,242,398,589,311,271,83,565,635,660,847,205,176,210,583,387,716,29,898,859,794,533,304,846,372,130,856,78,64,661,940,496,294,496,493,207,16,873,744,555,791,999,676,170,988,124,327,805,345,889,348,12,488,562,695,185,955,212,12,369,246,952,349,726,452,863,566,366,109,339,361,57,177,951,975,526,189,744,614,16,877,475,53,317,490,151,387,746,365,614,306,645,789,810,925,482,444,446,783,587,559,497,491,639,482,445,124,561,832,515,81,478,846,166,786,409,230,566,345,160,727,109,501,231,181,526,696,446,920,163,909,350,696,804,417,994,720,636,864,443,116,59,306,465,803,141,511,815,861,59,361,664,182,957,473,440,9,741,123,865,826,777,226,562,475,494,721,10,477,652,329,855,460,366,270,327,64,676,191,109,740,164,539,340,357,738,539,865,350,740,58,671,367,814,24,864,7,631,298,564,746,440,801,506,108,368,711,594,88,658,880,923,690,972,410,114,500,461,538,617,839,758,727", "620,681,83,933,731,383,144,290,339,104,236,324,141,785,377,339,871,425,137,276,856,247,39,275,651,512,492,839,888,474,98,999,811,647,398,245,86,452,677,14,959,576,151,83,784,487,185,88,82,363,523,285,169,137,275,458,261,436,475,766,255,366,763,684,194,642,896,939,715,468,683,709,531,692,602,675,486,184,889,419,624,2,555,72,700,30,878,977,975,390,42,587,488,337,584,695,64,82,439,297,237,795,272,216,889,821,69,893,203,735,801,107,702,916,717,159,817,776,86,545,99,947,343,980,972,616,440,312,545,852,775,329,640,978,918,585,493,356,864,763,634,759,412,335,631,597,400,855,395,907,216,949,358,864,489,524,684,969,237,411,143,780,346,395,879,405,12,202,134,879,542,722,976,100,616,640,379,947,964,799,889,401,330,740,69,151,550,822,230,999,247,20,256,637,593,641,951,236,693,669,915,818,494,212,777,148,470,863,305,31,967,932,7,394,648,104,343,279,413,801,829,941,578,816,99,198,161,485,757,569,764,199,880,930,985,470,867,825,937,591,276,438,145,172,898,202,926,300,294,907,947,573,455,461,449,314,629,242,685,266,493,669,647,416,985,636,428,351,859,581,37,957,399,585,822,796,710,576,933,930,424,974,626,741,203,284,893,764,355,56,797,34,725,350,3,626,227,809,917,914,590,165,41,460,289,658,766,823,861,418,327,81,10,789,224,810,112,212,582,422,839,562,405,337,11,516,778,585,907,684,672,184,229,252,690,727,886,551,114,986,514,143,63,679,176,464,884,23,974,283,255,33,421,498,779,687,399,285,636,995,109,664,356,548,856,229,740,328,385,680,713,730,763,818,412,387,48,299,284,942,636,561,250,777,29,257,602,530,502,145,529,656,329,503,657,356,20,863,286,740,955,609,323,926,358,123,883,397,822,714,248,731,375,89,890,556,564,119,475,244,124,92,659,547,969,452,983,582,909,631,854,554,153,591,909,490,826,295,893,38,414,468,384,2,757,877,555,340,771,342,957,522,223,296,428,242,809,631,931,526,863,844,482,639,791,462,88,553,178,653,530,8,961,555,587,634,577,744,230,161,806,795,657,603,133,760,778,208,644,783,753,884,25,316,618,427,142,241,132,773,129,451,343,534,186,751,238,981,161,131,449,130,828,851,301,664,869,658,820,445,194,377,286,230,474,143,767,202,551,509,305,841,682,375,168,292,528,954,154,34,658,720,193,47,568,405,553,662,553,588,655,822,200,210,149,281,94,289,176,327,395,685,503,182,245,228,124,167,645,336,120,206,933,725,640,203,293,263,868,751,992,885,443,567,346,132,550,684,799,832,485,454,94,504,837,696,0,660,886,754,210,560,909,422,525,306,528,980,657,288,31,774,535,799,504,808,741,496,839,204,546,277,557,564,912,259,206,318,253,896,695,236,846,41,70,414,142,343,735,831,966,602,477,881,865,761,595,769,868,346,438,829,172,173,967,472,296,36,151,443,653,239,702,557,113,19,595,452,689,167,848,685,327,613,870,252,924,188,119,267,261,310,341,393,963,401,781,650,235,624,766,669,531,585,702,523,370,44,846,666,944,516,560,208,790,450,527,370,882,160,356,1000,746,598,902,430,773,263,620,577,786,685,154,322,793,49,197,671,751,375,874,864,199,972,200,320,540,130,760,45,375,557,233,63,650,538,457,579,377,920,567,207,359,791,899,994,567,905,864,32,527,219,722,975,346,917,653,229,150,857,537,219,592,905,749,423,29,556,806,680,169,53,554,402,57,644,130,46,551,360,825,911,514,978,61,332,801,968,121,407,62,355,247,134,421,166,189,300,514,116,655,967,672,338,478,442,426,499,124,606,597,153,20,278,782,473,337,583,968,257,582,437,785,698,7,736,912,957,106,462,513,698,888,3,555,579,775,974,750,777,911,151,713,216,321,439,68,404,156,587,733,866,934,788,316,589,417,789,177,22,557,251,357,679,114,911,381,401,402,205,407,961,487,625,55,737,119,367,938,8,643,191,628,309,644,52,688,313,618,252,653,290,588,325,465,985,311,918,148,972,870,992,127,359,5,903,765,163,443,680,178,882,280,533,364,340,848,629,310,123,458,409,914,788,31,198,456,849,748,657,703,578,379,25,277,57,281,979,182,400,573,242,309,639,365,860,526,150,247,694,195,378,717,784,106,622,777,635,842,475,205,568,258,436,26,979,860,845,205,356,542,707,218,502,32,9,38,869,569,458,449,315,768,924,831,36,116,25,218,756", "89,883,245,650,780,482,518,458,453,109,868,884,53,376,364,430,218,713,894,686,201,352,584,981,635,854,252,794,438,690,470,941,122,50,710,310,862,667,307,873,991,398,531,404,830,655,287,86,233,230,425,759,749,181,111,253,968,167,515,409,101,225,206,45,391,483,149,277,38,433,24,931,39,687,742,187,58,23,409,502,201,738,337,735,868,213,356,248,442,200,294,618,428,967,981,364,301,419,392,166,690,309,530,58,346,85,513,60,105,533,783,471,304,843,783,459,675,726,612,847,492,404,955,724,421,545,417,260,317,140,774,619,150,150,246,716,161,105,284,431,380,869,545,788,76,296,426,392,679,351,458,65,888,215,27,843,640,54,976,464,767,419,558,19,330,247,968,200,408,710,627,239,968,888,164,725,724,132,361,372,280,350,958,470,537,6,902,34,483,200,504,407,313,638,771,202,961,980,854,915,869,707,224,471,456,990,451,562,993,803,39,575,413,595,691,654,787,775,323,787,392,129,983,876,289,7,407,518,184,622,87,209,541,135,36,538,580,411,153,161,897,17,572,565,420,932,295,624,703,242,791,301,31,699,564,689,326,437,392,539,542,286,800,484,488,236,621,114,313,976,648,529,864,864,79,24,163,630,762,803,869,132,487,880,634,782,443,433,30,358,743,170,288,672,818,578,457,451,327,79,281,562,768,611,644,411,849,330,405,845,306,421,856,457,173,441,62,181,244,366,322,445,555,349,681,610,830,908,498,304,685,803,995,449,722,153,730,612,74,297,937,689,913,556,13,108,81,283,433,655,327,356,766,828,744,583,443,987,729,36,419,287,643,149,88,146,923,544,996,654,765,497,725,950,286,274,307,334,543,5,382,81,846,48,835,101,665,106,35,204,103,384,985,584,16,291,212,575,986,273,672,375,801,594,296,288,530,672,397,312,236,741,470,190,741,701,747,908,127,823,255,336,646,410,770,290,185,500,130,595,158,755,663,251,925,920,180,338,481,602,897,730,939,547,89,767,797,835,712,969,344,19,627,293,493,509,964,414,620,838,315,114,763,30,562,206,779,74,7,825,771,367,168,785,807,286,980,145,183,366,411,801,754,436,590,538,538,565,551,618,474,616,659,23,827,955,491,33,508,262,127,606,633,887,288,507,103,628,731,585,682,229,756,461,526,850,236,351,238,705,285,354,260,682,798,241,171,64,132,911,921,623,708,765,608,305,266,183,593,229,556,83,138,398,949,64,426,541,212,308,294,284,173,232,446,945,941,779,512,229,390,792,351,568,833,271,693,166,671,847,948,214,76,697,619,204,795,223,695,701,265,46,174,240,946,167,608,699,860,16,604,988,894,7,804,466,660,0,453,687,537,577,723,421,675,87,770,60,981,806,239,158,685,380,515,450,781,608,896,311,988,91,685,70,791,906,130,981,688,522,808,909,722,16,808,650,789,83,356,266,534,157,406,325,755,72,155,609,13,703,27,832,474,464,91,604,860,661,62,153,674,229,962,281,710,123,512,352,241,647,516,721,456,556,156,351,253,873,519,802,711,750,248,144,394,172,277,331,280,347,125,627,958,217,988,151,512,234,936,504,833,289,72,835,436,806,674,479,531,367,574,191,970,308,94,36,8,393,180,736,814,218,999,231,100,554,753,15,43,419,165,277,958,239,309,668,918,278,291,683,353,701,471,51,158,389,856,493,607,87,944,882,849,599,438,544,303,274,78,940,147,245,863,627,484,626,868,442,830,798,96,603,501,677,660,680,963,786,662,278,494,650,278,466,329,432,708,484,533,549,492,377,391,220,757,249,95,865,131,698,591,300,962,424,84,964,199,701,313,330,944,287,380,427,410,879,675,872,605,779,580,663,571,475,626,985,356,531,413,563,942,825,455,897,472,157,637,249,531,862,207,511,608,837,110,83,667,140,914,135,271,282,231,92,628,30,552,165,620,1000,355,42,696,783,198,395,211,213,906,40,234,915,444,217,650,122,165,968,281,244,979,967,569,768,224,668,746,237,965,911,428,336,886,596,89,887,530,906,811,527,470,774,70,528,268,873,377,435,596,120,389,592,746,315,702,391,997,638,791,646,132,257,218,69,416,906,501,789,517,948,723,140,321,758,758,257,13,573,946,664,293,263,183,645,594,219,615,772,825,566,381,195,945,551,877,576,717,339,821,661,919,120,678,635,709,68,291,661,523,840,555,734,681,454,135,513,596,32,963,735,11,712,673,528,777,571,868,253,928,211,238,112,654,312,986,833,670,831,924,647", "319,888,967,97,416,235,979,762,510,824,375,702,681,694,212,420,939,923,405,588,401,118,174,403,385,819,300,280,760,583,56,153,635,762,28,696,962,389,630,371,253,429,290,604,45,584,223,906,73,211,431,873,31,690,520,31,53,474,617,355,195,179,833,196,27,190,120,834,525,765,334,599,101,678,683,89,33,420,824,408,850,333,293,938,104,361,515,343,645,214,9,84,409,304,46,874,67,389,920,781,454,996,414,195,550,162,47,473,72,852,990,614,888,220,255,989,665,138,157,220,70,592,254,167,165,284,595,348,994,937,998,743,395,199,698,34,517,344,182,640,61,259,826,721,91,453,230,450,447,737,87,1000,905,19,552,8,752,352,163,890,861,860,984,615,629,156,684,323,544,694,1000,670,965,110,913,133,610,246,410,119,462,13,716,369,609,194,202,910,182,786,548,462,756,19,497,711,341,923,59,925,221,870,701,526,763,224,43,485,100,688,635,500,414,913,365,467,911,12,660,968,57,617,572,427,382,61,407,160,268,821,304,763,507,372,876,913,188,507,211,406,932,470,444,776,290,649,773,979,730,312,454,49,384,284,269,160,234,687,408,594,183,343,422,572,835,840,84,465,920,64,966,289,492,470,870,835,765,625,698,856,440,185,795,519,62,119,9,265,592,489,364,199,604,441,576,424,468,736,757,218,801,271,295,98,574,180,394,272,147,176,719,391,458,330,900,802,927,388,634,927,535,138,465,785,698,985,400,956,940,129,99,99,405,18,638,265,374,354,154,187,349,547,927,596,405,119,939,221,861,4,464,839,78,439,772,623,326,25,7,296,202,238,910,451,884,266,79,992,319,99,530,583,115,156,106,290,912,101,370,178,295,469,619,606,503,995,392,716,782,675,165,669,499,966,360,101,381,403,6,444,553,655,404,726,135,7,689,17,806,270,749,469,578,593,292,536,874,463,825,735,227,277,335,335,113,678,667,486,560,308,12,494,264,26,588,987,598,424,355,974,514,673,652,682,683,243,680,889,62,611,127,518,827,681,530,8,70,419,411,791,955,35,82,787,41,274,602,451,817,591,49,92,908,969,661,299,478,296,248,805,156,673,624,863,906,192,766,561,805,365,554,983,474,502,296,880,237,621,813,392,414,964,332,70,918,103,373,355,135,995,475,566,874,318,993,67,869,480,814,647,553,935,924,599,777,445,839,586,780,628,749,483,351,355,34,710,441,90,406,200,710,49,719,210,674,130,640,901,289,782,551,352,137,988,989,805,626,691,819,48,717,976,54,312,869,114,693,975,997,386,702,160,4,967,503,226,272,397,840,453,817,929,66,904,378,67,226,958,605,946,67,462,836,641,582,730,886,453,0,30,645,452,144,695,182,368,42,13,572,393,742,284,837,146,206,308,329,60,355,815,512,718,790,852,130,386,492,795,73,361,619,949,448,422,133,593,322,161,265,580,571,965,882,490,829,731,966,439,725,371,327,486,803,153,919,991,502,438,656,75,929,4,253,718,103,624,810,7,802,343,289,961,285,560,79,959,543,758,181,385,132,797,225,53,51,976,593,791,525,342,283,633,553,898,833,749,194,149,401,131,935,744,150,474,447,53,525,439,112,820,121,815,553,50,698,492,736,499,440,391,243,851,779,712,447,516,924,865,630,350,375,959,641,454,56,228,356,190,45,242,874,672,296,940,170,926,713,116,630,92,866,885,122,883,655,150,810,795,378,988,40,92,995,189,478,408,508,497,677,571,303,866,687,219,527,951,475,915,125,242,909,112,992,604,613,571,901,922,396,150,542,406,844,40,87,246,586,854,407,561,200,853,207,665,468,219,321,730,652,909,921,28,144,522,86,931,756,714,449,484,823,496,974,122,986,753,545,41,725,425,427,143,216,366,661,981,347,431,972,165,106,790,914,783,72,889,705,413,493,922,142,845,950,297,65,685,55,80,337,489,90,129,647,676,942,590,977,290,637,925,769,164,205,414,643,634,737,306,331,558,786,64,444,325,63,514,114,809,668,90,343,589,666,564,941,865,948,889,153,742,965,535,1000,822,344,217,630,271,131,653,345,519,339,286,237,871,442,395,212,34,961,830,821,963,667,569,602,103,885,36,460,197,347,992,489,430,701,9,955,492,61,177,896,665,907,441,708,967,617,962,377,955,669,790,579,169,397,365,314,291,383,471,942,547,47,307,778,594,760,47,681,517,652,485,927,445,852,934,303,545,467,996,128,708,515,557,767,843,807,928,275,724,109,255,119,159,474,185,853,292", "557,13,253,166,806,373,486,361,86,523,52,264,855,912,820,553,80,568,87,71,356,203,529,470,680,167,205,819,860,802,829,420,617,312,540,405,254,980,469,319,865,34,424,359,714,174,21,908,510,56,661,839,115,964,688,340,836,801,187,200,363,669,542,537,517,827,576,526,145,447,396,81,270,452,776,838,67,358,62,822,739,770,317,818,336,427,990,879,914,653,90,728,993,130,709,848,270,38,357,232,320,518,798,483,652,33,898,181,540,256,707,758,454,952,467,252,529,512,741,996,612,339,212,619,485,10,998,978,484,842,238,312,712,830,804,953,357,469,345,956,438,628,83,35,651,56,981,90,775,185,441,290,886,150,362,880,768,34,509,377,91,892,66,246,947,387,933,675,466,114,979,863,240,876,119,711,381,678,339,798,773,32,28,951,146,286,467,230,22,931,791,960,221,842,511,168,581,534,497,256,536,441,80,57,160,911,361,992,624,176,333,603,924,48,526,352,549,228,154,213,342,981,31,84,846,406,3,457,971,833,84,572,885,835,893,16,870,180,675,885,777,502,872,497,280,308,428,752,145,433,862,818,149,216,438,693,389,194,227,659,800,452,873,175,656,814,481,911,863,601,579,698,140,957,316,274,917,304,204,710,637,762,843,309,93,15,382,52,339,779,724,443,38,577,258,178,323,862,95,638,258,412,924,955,677,690,395,392,66,32,636,161,159,234,602,80,386,649,894,788,328,611,65,683,330,613,524,571,458,350,423,736,977,890,390,513,312,31,91,8,548,372,81,755,129,631,651,489,987,362,616,105,13,549,97,398,477,827,976,762,889,410,526,408,534,143,724,251,271,895,858,20,749,857,531,246,288,522,72,346,394,586,660,146,200,37,309,387,787,39,53,933,276,101,438,664,672,448,599,131,661,692,41,481,761,552,251,125,89,85,589,591,136,138,364,824,42,718,655,61,624,998,980,956,313,277,596,122,629,538,953,769,902,937,146,236,841,433,359,708,76,895,179,293,881,155,913,143,952,141,729,177,893,417,764,534,340,173,638,681,819,767,677,674,396,186,611,665,453,985,638,348,973,525,252,163,537,373,752,210,584,524,820,429,75,810,917,141,155,292,993,125,706,334,447,604,673,96,569,337,42,650,524,826,384,862,129,678,851,702,536,359,66,181,225,922,916,413,620,465,700,944,368,134,903,262,422,799,33,697,658,80,672,329,626,722,328,110,62,875,74,246,992,531,45,989,380,254,779,633,130,943,390,999,524,251,56,902,424,464,850,920,176,938,896,524,24,272,762,866,943,995,622,772,125,752,319,986,686,402,632,420,782,905,511,788,750,510,455,615,769,186,260,722,595,353,754,687,30,0,790,62,966,786,136,278,343,629,778,861,844,915,460,459,844,929,925,341,655,977,110,639,724,665,761,342,41,496,111,739,990,747,682,670,308,749,385,828,368,208,796,983,859,340,533,900,718,235,132,219,753,555,50,560,663,129,125,611,959,258,230,571,692,291,654,140,7,733,173,934,252,814,815,857,999,446,112,161,228,640,340,916,119,371,708,70,956,568,322,614,813,913,204,530,585,684,679,792,825,401,525,209,606,7,735,302,454,75,453,330,669,896,109,261,409,883,260,678,298,243,379,333,532,291,520,565,512,562,393,678,973,719,517,391,596,990,478,323,738,904,280,141,748,571,881,747,204,969,886,805,937,685,522,9,687,949,191,1000,785,430,718,820,994,44,344,267,381,455,910,735,791,233,673,553,914,877,865,616,867,331,487,177,933,479,662,877,61,347,318,17,105,794,411,38,230,469,390,313,468,8,260,98,392,684,393,17,369,34,493,627,383,553,859,116,371,280,690,528,149,93,495,686,899,99,281,966,785,121,742,776,217,783,281,5,467,10,620,21,388,76,518,983,134,426,842,899,531,856,775,881,268,37,643,826,199,25,476,666,870,695,929,686,921,812,851,934,599,559,230,99,294,971,29,864,947,828,747,304,177,95,63,693,508,539,940,572,824,666,462,361,229,107,247,405,235,632,151,470,790,67,826,382,571,359,232,514,177,558,483,837,380,407,87,817,165,717,611,819,54,3,909,903,248,869,859,292,821,852,307,481,36,405,632,597,796,22,485,488,799,597,5,919,536,296,286,665,877,656,975,611,88,484,604,596,4,25,630,104,410,432,861,659,62,232,739,451,650,701,108,554,317,242,428,71,207,99,469,957,800,76,919,652,468,764,398,646,382,198,959,17,176,476,237,550,798,179,766,843,331,300", "602,931,563,439,885,648,159,102,936,462,19,995,506,179,530,219,64,946,5,402,546,364,855,250,128,894,729,927,264,290,957,203,274,233,812,359,846,84,404,348,877,661,700,699,563,802,652,151,378,966,854,321,510,928,275,918,172,902,453,462,900,268,467,295,375,224,791,238,955,267,946,514,425,591,528,581,856,877,418,359,570,623,413,46,930,991,589,558,939,931,827,304,281,413,441,81,220,118,681,801,939,643,288,51,517,269,965,56,372,861,329,156,588,227,993,700,755,274,335,74,645,787,470,44,269,602,496,944,554,629,822,981,116,474,966,80,925,264,723,403,717,644,880,606,29,727,561,491,572,340,570,747,912,366,502,943,977,384,917,923,551,715,407,20,54,817,427,37,76,241,604,55,634,15,584,174,699,309,943,457,179,700,565,585,462,604,121,182,198,862,674,69,915,948,197,766,84,649,112,850,399,506,70,110,650,774,638,792,260,186,693,920,377,476,511,432,820,613,791,16,427,818,106,239,339,566,70,861,232,2,203,89,83,302,162,939,549,243,323,134,770,659,9,235,313,676,245,708,162,965,854,524,572,981,55,196,686,203,831,657,870,147,172,971,187,234,570,302,383,848,825,776,678,912,452,337,766,618,306,572,825,335,829,133,542,226,802,647,559,283,405,165,615,48,508,851,885,570,177,493,872,205,574,514,523,395,150,272,799,800,503,132,678,715,500,850,999,741,268,90,19,147,321,754,715,630,676,269,223,658,711,594,974,671,855,851,856,419,677,587,319,110,21,197,19,69,577,262,196,349,867,208,768,347,911,640,147,616,73,513,429,18,640,443,504,145,559,126,123,162,730,80,913,510,222,162,401,735,726,510,20,168,597,3,743,507,621,526,844,392,856,285,747,981,718,330,666,316,859,681,159,225,63,917,928,799,107,821,477,111,21,805,357,457,840,697,167,403,89,825,332,744,221,927,767,4,257,423,722,428,36,400,590,272,274,678,4,734,57,668,47,908,151,343,338,524,997,409,356,789,104,72,191,186,171,290,93,751,344,682,54,882,759,449,164,225,746,906,286,81,766,419,786,270,63,998,963,238,768,634,630,298,494,606,605,470,70,544,230,381,529,726,473,568,852,349,907,792,103,487,763,178,949,933,768,745,612,294,56,334,788,929,18,177,708,769,92,14,255,301,435,369,185,44,758,587,621,717,839,783,865,71,893,696,143,934,941,49,617,779,810,147,779,95,634,880,738,292,16,122,31,775,749,734,909,846,971,891,483,841,83,171,70,446,622,124,566,175,553,278,471,433,36,811,248,154,846,223,628,817,436,776,591,200,883,978,978,361,544,882,716,247,435,567,472,861,210,537,645,790,0,205,811,100,263,280,835,547,744,438,336,410,467,534,908,662,974,824,524,691,758,697,303,276,545,193,707,37,732,51,976,251,150,745,859,764,918,396,394,426,502,342,143,796,408,738,275,288,397,733,579,339,457,483,397,253,75,735,147,960,808,31,94,464,421,754,300,590,536,788,764,786,842,671,543,459,139,816,906,214,503,872,826,249,703,342,100,427,439,24,792,683,81,131,261,525,707,215,247,468,516,219,108,13,979,886,387,563,81,850,317,666,899,693,205,450,488,463,322,759,599,230,994,196,495,724,377,992,492,450,489,623,45,324,987,331,721,716,232,859,237,172,838,77,975,61,960,82,795,402,225,857,609,153,739,589,473,83,242,442,27,461,779,609,156,793,118,277,410,935,483,985,970,646,653,282,20,107,43,497,476,10,870,354,157,435,69,146,426,101,791,478,383,460,146,408,880,168,834,343,248,986,421,574,719,420,998,944,956,49,588,282,468,946,787,391,218,86,306,248,168,895,968,776,582,398,444,798,36,771,489,767,930,575,228,143,731,992,678,1000,380,14,901,286,103,577,690,420,771,754,202,865,602,996,61,355,152,929,227,555,535,925,397,242,13,715,901,115,102,138,940,388,997,552,586,923,36,929,491,785,974,607,131,92,990,650,664,919,887,187,856,480,705,856,629,619,973,526,455,813,867,530,993,517,7,465,743,484,111,384,765,858,890,953,307,725,396,605,533,919,153,54,727,63,731,290,134,851,474,82,896,453,553,224,265,311,193,660,313,323,906,529,821,470,127,949,318,308,743,441,322,631,124,437,537,425,18,128,508,391,812,545,96,264,431,684,81,747,60,929,772,938,385,11,387,34,89,109,630,674,692,611,176,169,646,910,633,630,603,844,658,581,177,411,801,163,266,150,53,637", "206,804,736,746,332,206,89,840,575,792,495,898,410,624,428,722,193,776,888,836,127,424,990,869,34,215,341,343,889,49,678,192,742,777,589,871,92,799,240,421,898,756,116,603,664,543,174,19,917,319,961,619,802,824,588,415,376,233,484,947,235,479,278,641,461,273,392,568,43,203,798,920,710,174,349,512,558,513,352,471,873,951,658,321,925,583,22,989,562,520,388,230,747,400,843,338,475,776,199,991,281,498,965,886,141,473,310,996,105,555,249,600,556,518,461,590,623,807,959,283,585,526,28,676,114,820,275,718,12,826,943,642,572,446,948,300,700,310,856,656,897,57,70,103,21,87,157,438,616,152,78,921,881,222,487,246,56,705,539,823,5,159,754,423,56,708,845,917,364,243,227,812,422,682,887,423,592,357,365,867,755,521,363,61,788,150,316,928,292,51,199,22,392,904,544,823,266,135,397,721,416,777,618,940,598,73,142,778,317,565,85,445,979,233,843,266,846,332,817,399,306,505,287,481,787,543,647,592,67,66,936,15,282,909,176,38,253,45,631,707,700,21,392,776,882,200,91,392,807,792,997,55,4,944,653,491,628,411,451,458,10,391,420,894,595,915,335,32,577,280,257,66,722,39,221,856,318,13,370,717,477,575,189,687,50,148,631,545,748,321,814,778,61,647,741,417,571,865,691,556,381,393,317,617,672,256,517,821,646,45,701,520,598,456,911,941,515,281,269,602,334,138,90,716,962,418,718,82,530,442,754,512,680,665,666,125,378,21,596,348,97,772,350,391,326,708,634,122,899,277,425,293,885,227,149,155,126,685,573,746,235,772,659,703,573,883,534,190,964,274,29,634,480,137,639,799,748,35,278,460,672,773,603,731,51,389,199,685,949,188,26,603,4,944,828,271,454,715,424,558,504,742,208,785,970,611,313,169,175,837,767,52,776,359,201,754,145,704,496,242,252,212,548,145,524,401,234,912,995,186,100,596,178,905,604,956,20,738,398,419,90,424,932,593,242,807,283,269,690,88,968,851,36,966,744,909,34,167,355,879,640,370,147,721,202,124,224,376,505,569,148,593,621,582,810,405,596,493,448,198,401,132,460,171,754,581,893,964,54,931,917,184,678,597,914,788,865,151,379,692,547,73,416,426,722,408,751,904,596,596,982,515,64,587,381,718,196,829,26,283,460,249,243,828,567,240,434,435,127,419,556,772,397,241,8,17,310,98,405,978,829,145,980,852,660,984,523,755,86,515,533,193,491,134,242,886,44,434,506,563,808,125,584,778,349,374,148,964,531,265,878,891,124,314,674,773,163,274,808,13,22,780,495,273,816,193,864,60,459,542,464,131,466,373,837,206,560,577,452,62,205,0,441,217,98,295,178,986,709,755,837,736,521,888,313,912,367,672,261,366,237,513,918,466,376,103,856,116,974,676,690,617,948,527,853,341,877,444,231,572,414,457,308,287,394,943,943,70,811,449,654,990,779,119,327,195,362,247,881,866,452,576,360,778,306,413,22,23,753,758,3,501,609,346,984,413,635,58,389,688,216,414,713,796,996,117,510,975,442,646,792,485,297,49,43,990,519,637,66,253,207,502,366,918,464,600,979,245,599,845,567,775,375,128,340,54,475,105,34,405,526,392,456,568,400,328,735,673,522,110,275,142,411,604,594,26,940,188,517,993,942,40,853,134,856,147,120,6,631,469,515,616,831,103,138,138,771,166,84,243,912,140,266,927,139,621,28,868,454,186,499,784,909,82,454,879,771,701,260,814,595,857,717,970,727,710,689,136,808,255,400,825,144,232,302,209,369,417,571,707,898,836,244,675,582,804,909,283,914,407,510,62,170,705,117,948,891,544,643,814,733,56,3,492,664,798,129,662,602,124,487,617,857,271,773,50,859,346,415,77,626,406,818,725,174,737,302,95,721,16,432,974,306,744,268,745,950,287,695,218,919,16,543,526,330,148,892,991,217,215,210,734,666,604,380,186,692,68,789,569,991,725,253,829,882,595,173,333,537,918,11,406,128,336,18,505,272,210,37,161,419,822,470,171,223,362,361,451,975,759,626,235,825,190,657,359,125,757,625,738,450,811,208,50,283,255,454,398,374,520,233,660,732,9,792,140,470,145,312,28,649,668,928,499,700,596,108,149,805,481,535,97,427,270,425,624,937,84,879,879,628,596,360,453,870,971,826,428,976,602,11,44,773,648,616,674,654,943,471,898,741,656,382,199,871,820,280,445,185,625,939,184,973,922,309,286,642,909,151,299", "759,158,880,837,663,249,91,516,882,39,503,149,781,802,632,125,554,602,630,374,483,151,665,161,806,527,663,172,384,558,76,820,306,858,532,853,542,406,844,398,162,890,410,991,277,178,69,480,67,35,639,294,761,262,223,381,808,145,838,678,549,230,231,425,527,897,81,629,783,404,667,708,826,890,622,941,30,219,669,950,302,677,273,574,571,831,318,263,700,222,567,995,713,836,565,245,495,442,821,992,954,73,987,642,850,309,918,792,286,299,54,765,346,183,23,746,824,470,126,78,270,854,73,202,751,894,802,599,821,151,602,676,127,598,341,847,58,339,479,413,985,110,828,62,801,622,343,260,301,913,592,59,87,918,242,739,845,478,448,616,829,655,345,282,785,804,619,462,23,321,547,317,320,428,321,861,681,74,938,672,997,421,712,852,591,400,333,636,841,46,515,443,658,345,766,510,417,770,415,164,366,113,633,922,919,609,910,152,493,448,566,136,618,623,933,541,53,170,86,204,379,768,869,527,356,281,194,11,773,446,869,491,197,886,867,18,260,52,880,209,118,141,374,233,579,707,928,102,104,95,184,381,853,944,702,751,680,529,622,217,71,960,65,506,899,702,751,800,730,653,603,807,343,359,126,118,326,157,158,114,691,551,180,502,305,63,70,227,243,520,362,45,113,754,796,403,892,425,904,542,982,927,281,122,857,436,823,316,20,998,561,263,597,961,723,28,513,194,122,48,795,740,799,229,285,375,636,561,654,941,760,962,851,655,306,457,753,890,963,228,123,31,761,676,920,101,951,372,85,704,56,647,382,964,54,633,861,238,657,484,323,681,221,330,447,166,534,861,276,794,99,65,277,196,897,580,448,276,153,665,402,211,513,798,878,71,647,609,390,268,347,457,390,593,129,381,255,945,814,920,950,107,754,855,537,41,632,531,311,182,354,160,272,261,402,859,975,102,623,45,396,173,895,480,997,54,269,284,102,513,705,566,680,910,819,204,383,913,799,151,622,442,390,384,160,342,154,935,757,808,8,980,423,511,441,430,655,787,910,344,763,526,69,703,476,247,28,559,667,484,302,128,512,554,639,932,521,797,610,262,601,510,764,863,320,389,516,608,525,585,167,322,691,773,468,843,361,414,231,224,873,114,150,670,652,865,255,916,464,678,422,341,586,684,679,861,641,439,480,969,914,818,428,482,501,239,876,874,638,357,335,264,28,37,790,387,253,275,40,579,904,118,332,560,618,622,383,656,229,857,527,20,6,545,984,851,729,609,158,248,444,457,636,425,883,92,425,416,268,493,956,443,648,636,596,162,447,769,340,989,960,735,681,745,922,875,424,965,115,347,878,410,51,745,427,604,909,723,144,966,811,441,0,630,155,683,288,86,30,888,515,160,790,400,701,45,872,594,360,148,72,92,363,988,708,591,136,814,53,926,295,640,730,634,607,374,790,818,434,151,622,122,182,933,812,538,793,203,735,981,368,252,870,326,83,100,741,669,561,788,326,492,958,547,27,356,366,41,633,766,556,835,252,526,452,465,606,169,732,52,584,480,88,883,814,243,636,164,345,598,549,242,46,7,616,304,944,25,178,758,62,674,289,459,377,155,414,555,882,90,225,622,433,849,927,263,219,491,229,287,17,979,365,78,666,896,443,525,513,752,731,498,134,22,628,710,575,372,758,890,71,772,654,424,560,113,920,90,175,772,564,679,771,374,600,431,393,5,77,982,233,574,782,193,182,71,208,488,100,252,881,837,69,913,893,439,511,207,61,610,231,678,989,583,342,58,1000,506,745,638,764,636,631,454,860,682,344,432,51,649,958,354,550,812,493,722,189,906,273,154,503,694,562,331,683,104,646,386,419,102,744,774,732,964,950,184,38,691,583,143,61,765,843,577,628,477,443,418,909,189,262,858,228,164,994,275,540,689,159,22,967,771,838,307,210,912,185,315,280,434,378,914,840,949,46,884,377,535,271,881,773,183,854,556,338,452,353,861,214,483,841,745,572,770,166,198,889,829,888,44,271,135,603,590,537,244,643,919,34,657,534,694,856,630,645,276,511,897,723,797,50,456,589,233,129,454,777,178,356,775,88,292,256,491,487,438,725,999,684,411,176,874,424,354,626,85,251,277,121,749,340,350,856,714,38,43,554,239,322,401,737,77,462,534,386,360,406,462,986,530,257,292,249,986,907,126,848,335,309,667,414,129,213,902,969,49,496,43,563,793,901,26,52,793,80,499,37,654,156,857,330,972,860,570,100,606,171,415,23,87", "638,451,519,697,999,417,168,904,18,937,458,493,464,145,408,239,572,832,135,416,55,709,746,989,148,374,368,191,675,232,648,505,242,434,540,994,600,183,308,13,886,90,162,841,429,778,770,807,257,463,471,462,36,3,311,315,187,109,822,954,524,24,544,570,562,862,640,701,844,468,797,157,627,845,402,17,297,783,971,746,726,887,876,143,518,993,199,105,273,554,490,549,531,248,394,692,515,699,528,491,854,287,124,108,228,559,681,395,276,437,298,777,540,965,957,625,834,52,697,697,255,836,356,484,2,921,756,779,651,642,500,457,384,687,426,452,790,997,872,523,687,476,905,746,726,928,929,959,223,390,840,555,133,543,930,665,187,600,324,342,114,63,750,130,655,780,822,76,895,958,240,626,822,961,15,635,37,72,500,380,187,161,95,707,224,44,854,716,712,330,928,585,613,459,758,111,617,872,481,633,23,192,839,259,724,191,959,884,552,566,14,51,178,619,197,156,300,43,743,460,617,791,476,491,931,791,9,499,951,816,209,773,239,926,102,789,132,247,519,607,648,715,652,748,186,533,452,572,466,80,206,557,697,20,8,53,949,508,359,545,542,587,143,76,848,599,768,801,139,267,890,632,554,533,575,718,822,584,70,969,508,384,583,686,801,358,33,607,573,899,623,345,226,215,553,777,53,913,485,100,892,336,717,325,148,428,548,932,800,27,631,408,347,549,24,664,649,88,244,538,422,440,81,439,249,300,497,106,337,576,556,984,599,529,946,367,431,447,33,76,185,249,185,998,653,30,834,526,658,337,532,519,549,991,500,405,678,577,84,111,953,577,94,420,183,667,928,502,884,841,388,885,313,692,748,62,971,508,97,419,53,676,442,94,892,985,800,926,64,750,81,670,222,305,221,298,440,236,862,184,321,63,335,373,400,655,986,293,973,941,7,828,439,724,991,724,317,468,925,686,372,490,617,333,637,143,913,669,957,820,528,954,343,478,685,384,398,925,801,994,342,642,966,829,384,534,996,878,295,389,289,716,839,347,256,978,693,622,821,500,119,186,29,837,885,112,434,904,303,930,649,449,935,312,758,79,694,86,413,856,916,141,807,99,981,798,77,490,116,605,414,491,588,342,576,315,795,570,146,616,416,232,308,525,886,156,521,889,912,366,369,649,106,131,800,452,489,341,775,724,252,154,982,612,210,68,798,254,402,886,896,347,76,849,847,78,17,856,192,325,376,369,218,94,295,137,987,931,664,878,209,960,691,382,912,573,174,78,324,47,616,361,530,481,217,534,314,599,191,585,576,963,548,922,436,59,8,866,694,398,482,103,389,866,847,852,675,360,696,549,27,799,866,952,742,257,422,421,695,786,100,217,630,0,535,124,768,716,821,265,904,921,5,520,843,911,43,150,919,868,66,990,11,52,343,906,600,758,512,982,875,164,536,151,368,984,980,395,714,625,847,717,58,245,980,270,159,140,432,676,677,543,5,973,334,759,398,399,396,513,587,366,657,34,987,409,650,243,308,272,470,640,548,160,743,743,532,317,216,717,495,690,309,771,255,316,440,398,308,97,891,368,742,192,534,627,889,447,46,151,75,492,434,567,865,963,133,280,669,64,113,359,511,661,370,695,888,25,200,152,536,537,92,383,305,240,2,262,188,998,158,990,25,595,630,31,429,134,243,216,207,588,178,248,922,665,806,622,134,676,952,272,440,568,940,555,888,212,934,553,18,147,941,76,806,687,744,784,644,20,625,296,554,369,729,854,942,809,556,373,764,184,919,400,171,444,621,368,30,362,478,519,90,81,240,880,867,35,623,522,444,74,844,79,75,525,627,289,868,206,737,762,778,944,673,817,874,430,482,250,419,954,797,214,83,398,48,80,885,73,541,211,564,340,806,180,789,618,395,127,489,107,762,55,358,610,870,180,522,117,228,19,760,544,956,807,172,745,669,152,761,162,797,974,104,852,889,998,468,751,45,347,997,748,381,764,164,51,641,601,610,511,436,223,922,256,428,716,488,754,377,811,772,104,811,247,888,938,689,670,875,81,436,694,455,990,915,37,771,720,210,406,242,921,167,89,177,42,325,627,196,816,619,239,881,863,758,516,102,846,507,136,658,15,301,418,341,805,830,859,248,164,653,960,533,670,715,970,57,338,928,867,610,107,705,218,321,791,612,238,708,634,173,867,306,506,636,720,4,58,618,179,909,216,569,949,401,706,328,69,428,439,893,575,604,198,458,179,741,581,24,952,70,224,244,440,132,342,392,517", "977,768,76,444,915,712,178,344,572,991,400,454,463,808,16,953,690,73,813,332,898,888,629,597,243,337,606,881,286,260,627,792,319,337,914,737,95,297,522,235,214,540,42,613,89,811,119,142,733,489,837,97,942,862,307,378,910,229,112,833,259,700,536,677,50,769,90,274,928,327,754,546,12,316,719,290,87,495,49,484,400,346,777,268,335,84,816,189,124,39,559,613,277,462,197,147,640,856,917,547,456,709,912,869,446,940,670,470,169,69,754,312,350,557,859,308,633,469,873,116,769,11,533,751,625,947,213,334,569,940,821,443,636,972,542,403,175,379,283,653,725,841,348,241,400,179,551,483,764,75,600,339,288,958,388,431,452,382,964,266,405,480,508,819,463,547,859,2,104,16,998,174,882,572,54,859,655,555,194,757,962,817,647,355,909,983,597,219,213,431,455,900,609,895,429,701,273,775,825,5,238,798,952,743,927,457,744,939,814,725,912,924,852,10,871,167,323,736,904,422,692,615,964,497,487,529,278,907,72,905,654,969,625,771,449,947,976,879,249,207,102,457,866,55,815,709,276,566,803,532,763,752,199,820,334,969,78,352,93,648,211,652,766,733,712,642,902,690,224,339,610,657,168,530,986,133,360,958,333,550,982,218,993,213,558,13,939,915,645,297,57,766,500,246,410,895,485,668,704,41,128,220,336,104,109,925,264,417,50,294,327,805,606,750,99,939,345,108,327,800,894,725,686,815,222,586,571,263,924,3,817,147,884,784,123,45,703,771,61,641,314,218,288,735,6,423,35,682,106,924,964,886,608,858,456,213,856,784,516,949,476,251,642,860,852,300,913,488,285,276,92,999,812,516,189,521,74,674,348,110,762,285,121,456,112,254,996,371,894,107,111,865,533,871,623,702,96,331,29,621,193,154,785,108,667,133,198,881,168,136,523,266,860,391,659,470,83,735,639,822,704,349,464,635,801,404,303,806,226,380,532,59,565,141,556,403,486,137,819,438,137,199,599,841,416,710,134,485,840,780,248,32,421,198,409,208,764,94,919,921,878,156,736,488,922,260,525,277,153,310,130,700,527,53,690,419,489,888,241,571,401,856,980,286,889,355,46,861,507,342,603,57,768,624,983,759,28,723,29,348,216,187,271,409,551,951,132,128,509,109,400,250,546,159,206,810,141,570,778,742,76,191,362,971,781,794,649,967,26,537,871,191,805,111,267,499,500,649,756,764,831,818,783,918,108,182,179,192,522,56,79,514,893,224,994,264,404,865,475,459,119,833,152,92,606,242,775,824,166,851,399,898,407,396,607,253,988,178,654,920,977,264,59,969,992,479,724,660,20,801,502,226,814,593,788,902,525,675,182,136,263,98,155,535,0,17,367,146,452,937,273,892,300,992,453,591,403,712,799,521,455,753,304,835,986,569,943,358,497,409,96,737,443,993,928,489,268,530,521,103,703,182,364,343,158,291,525,207,385,20,570,670,384,571,177,298,907,803,385,145,389,111,993,517,948,108,310,791,905,12,363,581,735,626,210,346,971,585,106,626,44,37,77,528,539,802,776,370,16,844,616,685,325,623,388,455,236,595,82,199,303,72,925,526,519,380,79,360,689,512,608,300,783,128,605,797,627,349,369,887,392,630,645,132,779,729,588,705,239,539,710,331,470,930,269,893,172,834,28,482,651,954,722,640,490,99,243,560,850,582,618,815,720,686,202,670,159,654,648,445,512,468,561,65,932,683,354,146,932,44,327,33,415,787,266,509,231,42,446,140,915,441,953,504,531,919,232,210,371,496,298,99,563,134,14,309,115,89,801,444,772,931,362,890,239,355,494,452,43,497,627,501,905,767,30,692,92,71,826,96,901,699,176,407,611,289,224,761,327,577,677,48,195,179,87,200,992,879,705,681,119,143,566,474,436,600,215,187,484,911,773,781,265,608,750,77,968,271,365,576,109,872,312,711,283,45,145,125,235,165,757,731,785,608,906,733,762,137,948,768,670,153,488,586,148,988,871,836,444,928,582,515,969,785,407,745,709,248,49,987,545,10,700,516,942,102,125,774,833,849,25,430,646,525,91,178,589,733,955,87,981,366,8,289,773,728,829,940,863,35,245,906,932,38,530,161,119,670,669,477,639,869,471,638,941,516,325,716,180,78,752,724,592,929,305,573,960,413,925,459,45,903,815,123,565,447,561,853,656,780,504,401,291,76,160,260,471,500,25,838,240,339,344,401,191,737,446,259,935,505,189,190,437,636,716,81,196,33,519,677", "499,954,3,208,174,517,429,158,901,103,841,50,979,991,826,777,417,659,389,741,529,267,843,583,714,283,572,68,282,962,82,698,474,34,260,650,463,444,408,330,966,922,622,415,322,925,642,825,359,3,991,296,40,528,3,234,804,607,75,605,835,426,746,194,783,772,722,373,201,509,596,841,332,639,425,220,419,440,378,784,490,493,37,646,227,70,91,752,269,357,481,324,169,818,929,993,400,146,393,660,200,935,555,308,407,658,212,22,787,893,529,926,626,772,697,934,362,651,622,533,870,621,331,10,495,510,375,330,288,479,493,95,275,864,903,159,466,823,443,872,22,25,995,127,27,260,869,107,253,165,616,974,479,492,406,934,32,430,225,852,904,246,90,655,391,287,147,454,106,126,330,382,783,901,342,757,84,559,484,941,725,869,199,601,37,860,165,836,884,276,266,770,885,102,295,654,572,98,210,770,665,641,703,926,525,127,459,821,787,833,712,635,798,122,730,243,48,329,44,581,438,856,591,829,453,634,923,298,979,97,302,691,173,514,507,982,404,805,579,88,294,318,86,63,361,573,758,888,712,329,545,589,296,421,602,330,678,689,92,390,829,227,31,151,547,113,712,993,651,952,549,914,121,461,99,481,492,806,810,308,412,873,699,717,57,858,268,384,739,292,694,349,186,93,629,254,983,523,823,471,929,122,991,259,797,29,96,700,507,326,445,86,732,513,64,103,792,44,351,577,997,122,944,740,279,246,165,370,943,718,858,34,320,773,749,613,757,535,552,60,151,940,152,792,115,108,577,842,964,773,707,774,332,915,759,129,373,517,261,196,268,404,494,60,285,623,404,227,701,390,544,279,154,751,685,169,363,478,665,673,366,6,701,78,166,396,772,262,460,89,265,549,629,992,852,54,912,860,8,436,769,708,878,751,179,509,941,371,142,568,317,310,160,428,695,765,620,614,726,938,834,858,102,666,366,849,118,718,874,917,276,915,996,109,522,754,592,260,366,581,58,907,9,575,108,706,194,983,821,224,289,314,971,882,396,282,745,294,675,770,96,870,149,381,308,770,890,135,936,295,273,247,607,146,48,357,32,688,993,429,608,463,557,226,34,664,756,750,444,91,585,306,84,165,238,464,389,630,489,741,953,220,568,583,763,496,455,682,759,433,830,495,730,30,99,296,157,736,501,99,174,660,537,883,378,451,50,39,316,296,735,303,484,403,813,44,482,587,902,312,716,755,681,202,660,916,673,13,129,462,310,723,132,772,174,303,336,589,655,602,792,517,359,174,689,80,606,206,572,946,984,373,555,982,39,484,495,518,90,708,53,475,388,137,338,727,910,501,135,455,254,371,726,768,381,19,306,87,368,278,280,295,683,124,17,0,563,968,437,128,311,322,374,616,321,791,925,926,126,332,86,805,778,813,135,494,174,53,236,753,758,54,809,879,890,258,58,174,17,170,502,624,169,116,230,793,402,24,580,30,57,130,951,310,901,781,490,514,959,529,831,850,684,882,413,940,488,963,239,328,709,624,677,180,777,400,911,383,62,315,368,614,945,538,143,331,996,20,603,570,191,32,318,502,980,124,572,879,289,382,880,950,441,435,228,697,194,276,898,470,500,122,505,191,7,863,947,686,460,508,305,181,161,179,863,50,186,617,690,816,592,784,649,544,353,841,565,169,716,75,964,431,838,763,798,226,161,71,405,443,720,306,620,358,976,455,119,105,228,497,702,219,692,209,365,758,491,216,634,51,143,388,757,667,40,918,152,383,343,632,513,298,134,217,111,973,914,53,307,978,51,27,687,855,659,607,399,438,936,650,580,443,861,453,740,666,873,465,348,887,672,27,904,236,116,693,419,899,143,940,114,945,102,600,684,695,346,626,23,670,954,728,160,673,410,639,295,981,295,318,11,783,623,173,935,571,288,423,533,471,478,775,540,140,832,648,126,668,143,961,607,180,53,306,464,793,363,880,66,888,329,231,813,489,125,100,851,357,919,743,441,809,568,833,886,909,77,946,988,856,909,767,899,135,955,901,228,121,852,435,413,80,489,544,620,648,629,453,912,235,397,697,963,83,676,884,727,407,400,213,547,190,386,909,719,421,859,635,52,273,957,282,62,651,727,610,125,101,245,701,482,723,611,61,143,477,533,135,333,688,999,153,433,346,113,69,152,407,655,996,415,736,388,436,730,103,877,854,518,584,656,107,496,135,928,39,243,351,102,87,913,889,864,476,908,133,896,693,70,224,154,56,672,774,365,933,155,23,825,498", "723,695,624,346,549,492,621,27,252,134,679,697,729,427,788,569,762,425,990,797,166,429,279,30,788,539,807,578,783,195,654,548,404,635,21,431,516,380,371,402,641,132,557,671,207,457,467,71,110,227,289,121,427,135,261,97,544,852,786,531,961,887,258,658,792,198,9,818,794,951,320,805,199,811,806,558,687,679,554,499,918,735,957,243,178,235,591,190,2,704,280,346,137,491,455,533,931,558,206,132,506,308,237,777,936,830,590,533,584,970,44,984,225,773,613,689,431,674,153,142,520,405,785,508,725,948,437,272,262,912,245,107,369,889,551,908,762,536,183,977,483,44,324,157,39,805,375,792,986,315,269,739,972,899,399,188,546,441,961,422,561,174,839,684,696,137,328,476,719,450,617,249,133,894,482,667,387,25,65,373,488,496,866,752,482,454,473,76,748,566,916,607,358,766,400,603,962,819,677,46,464,510,30,875,555,158,693,213,645,452,631,927,89,458,228,994,274,430,37,461,667,658,573,449,119,850,965,24,765,825,578,626,727,814,65,778,703,663,484,382,812,326,346,729,597,354,128,580,589,159,678,396,31,861,108,497,486,83,522,26,180,869,197,936,277,30,36,293,377,242,106,648,448,204,90,360,122,274,156,667,937,871,349,185,312,369,738,54,813,332,156,869,85,791,701,151,804,320,321,739,686,45,602,436,995,612,781,747,758,847,839,723,947,482,772,654,215,321,317,62,257,463,437,106,302,990,48,456,930,530,295,789,722,700,295,944,735,742,242,883,498,978,532,730,168,113,255,499,1000,58,763,85,550,9,636,639,397,134,241,200,592,64,136,865,224,957,841,528,43,405,259,149,162,959,50,428,860,439,67,889,299,703,915,288,355,88,594,80,827,77,482,381,37,54,478,537,187,587,918,98,235,528,233,336,741,40,306,982,654,377,47,656,368,89,89,550,230,41,451,266,309,665,516,889,195,399,679,524,28,700,59,188,658,574,398,749,287,233,104,804,143,53,483,364,205,716,44,806,459,621,265,670,533,9,149,494,272,211,377,113,676,804,249,167,698,128,632,590,548,584,558,974,501,472,312,438,700,809,287,197,883,993,337,808,253,154,748,670,626,539,123,699,854,362,627,88,601,477,576,121,279,123,304,382,680,506,142,905,437,455,768,265,883,799,630,729,838,183,775,462,898,539,808,359,857,607,70,13,186,824,909,307,517,490,702,547,907,468,563,15,639,333,647,835,612,759,645,611,207,716,149,295,335,377,796,331,845,830,661,52,937,546,23,630,500,832,233,886,324,256,231,111,996,363,869,861,682,74,959,860,391,199,654,203,793,180,14,529,961,43,889,531,403,614,769,490,528,770,42,343,835,178,288,768,367,563,0,962,80,650,331,66,498,645,871,537,732,742,942,301,169,563,190,470,415,41,940,875,596,325,691,880,253,24,807,785,260,437,530,129,269,273,644,770,940,584,269,906,615,143,30,663,595,35,121,292,601,395,7,726,731,651,906,690,528,911,859,885,188,736,839,818,350,22,399,439,775,730,330,966,273,698,39,508,571,881,2,601,998,978,342,711,175,117,528,240,453,584,955,983,212,803,256,58,706,461,10,16,8,804,743,198,420,348,159,513,449,680,765,422,286,973,697,881,200,216,204,843,847,953,668,137,289,985,631,703,671,289,587,414,928,774,474,140,382,398,186,329,887,473,871,595,675,317,438,688,353,725,747,169,603,488,451,490,541,787,897,841,124,470,99,816,586,81,957,997,693,344,765,717,546,917,92,179,13,865,45,959,197,406,208,115,810,686,115,930,151,291,432,309,480,477,508,299,313,345,118,324,578,497,999,907,974,387,961,111,417,62,646,443,111,462,810,827,735,164,349,961,917,913,835,405,41,412,993,344,948,274,288,353,537,726,639,647,1000,83,35,703,686,165,180,490,151,344,562,890,840,606,702,876,775,86,313,456,796,124,316,947,149,92,343,62,24,466,573,258,326,560,796,906,446,254,578,374,679,422,729,241,918,119,619,233,712,196,86,864,474,310,382,731,854,725,445,172,144,670,274,489,812,551,798,577,652,729,350,572,262,530,824,186,646,287,112,769,818,474,551,108,867,29,120,787,696,574,941,324,671,373,492,130,216,549,1000,416,72,733,882,667,935,905,829,912,237,416,177,403,211,6,821,71,316,69,663,682,339,70,5,774,635,746,531,853,758,478,150,718,297,368,563,903,78,671,135,857,302,66,338,658,477,911,710,743,816,227,421,556,536,856,784,672", "381,751,102,711,545,251,286,158,131,271,147,117,968,645,766,394,572,254,98,650,98,157,728,587,634,52,801,850,781,615,721,17,746,577,177,243,373,404,870,561,902,731,979,841,605,322,381,83,269,837,665,815,511,559,914,880,304,891,152,537,983,536,750,449,286,55,400,119,832,9,726,911,682,388,238,678,13,601,747,268,316,783,947,109,777,678,777,550,730,275,422,877,903,514,205,17,100,531,151,352,139,780,310,338,966,417,409,584,887,309,538,214,298,982,75,357,851,494,856,765,139,61,479,952,870,341,699,513,255,801,263,438,748,970,118,719,690,989,74,21,824,158,838,807,272,510,811,459,415,14,20,765,259,672,119,540,563,476,769,446,390,189,693,65,287,256,658,875,226,733,298,910,467,589,302,625,745,569,142,311,463,101,908,249,606,207,947,796,142,145,676,721,226,926,101,390,267,105,269,880,182,544,57,487,453,962,446,834,225,979,536,152,587,997,628,457,76,176,732,873,371,989,297,524,936,751,584,707,94,164,602,468,414,679,708,225,141,159,938,534,579,565,313,563,556,118,420,894,97,104,644,74,155,23,391,713,325,592,473,365,202,520,33,890,587,490,496,549,420,881,51,721,879,399,777,240,589,743,195,613,790,552,471,96,354,773,185,260,993,501,534,258,835,555,568,653,463,195,824,530,733,338,102,540,71,175,435,642,717,357,508,706,395,895,609,979,403,358,503,228,614,948,833,228,551,22,538,426,3,334,225,684,594,446,70,153,850,189,267,627,362,262,480,565,727,356,351,750,2,4,44,237,602,866,24,813,531,179,288,844,180,425,517,198,667,526,102,495,951,756,66,92,132,37,361,80,488,934,185,579,364,523,792,22,465,180,56,671,771,146,197,650,269,744,812,211,337,312,886,940,264,509,774,571,865,414,562,857,920,542,112,497,442,563,371,478,549,692,831,764,78,825,241,134,96,722,571,65,601,626,125,126,565,957,844,239,111,246,610,994,998,520,759,78,595,188,574,685,694,529,224,860,533,24,110,59,247,378,178,988,286,520,624,313,869,411,832,340,203,530,129,864,722,1,806,168,597,329,241,63,18,143,132,934,590,776,138,755,20,213,873,221,989,205,458,373,90,462,355,702,902,265,600,121,764,985,317,64,220,627,571,68,45,29,611,585,563,756,252,821,658,55,719,477,571,772,658,878,226,656,78,243,151,780,153,608,912,275,965,383,512,247,352,519,381,200,852,451,367,321,170,782,532,428,327,219,384,495,827,583,199,571,990,856,121,867,425,244,460,21,366,230,310,17,256,163,751,572,422,717,567,82,468,715,418,577,619,198,265,196,332,80,794,142,382,35,980,60,13,629,547,986,86,716,146,968,962,0,117,749,253,767,636,850,62,290,434,474,586,244,225,470,82,334,136,990,854,751,257,858,833,12,281,980,673,411,619,412,571,248,966,140,371,258,289,708,490,454,259,523,850,719,375,504,875,214,996,8,794,925,283,476,977,905,294,241,459,797,794,932,608,792,356,783,162,922,805,140,274,669,947,949,417,183,85,3,543,853,392,901,507,950,994,27,804,46,633,318,596,590,316,152,660,894,394,781,282,610,122,960,826,849,999,851,136,847,495,112,994,493,431,887,889,940,697,219,902,173,81,160,947,277,736,302,116,538,259,394,139,673,675,40,256,818,522,318,581,140,815,641,222,735,642,68,889,506,446,98,627,42,781,114,470,33,329,401,92,212,580,702,758,348,169,949,505,716,361,590,884,163,199,955,794,232,514,312,521,139,150,317,279,849,313,22,449,665,137,440,753,82,133,302,155,936,320,830,416,452,618,452,203,750,441,833,996,208,466,976,302,844,562,855,103,57,297,565,808,273,32,306,785,895,583,869,416,449,712,560,738,293,762,91,452,212,938,488,678,970,268,551,530,244,966,957,246,426,772,501,929,129,652,269,382,955,96,899,132,102,95,940,744,156,527,671,624,683,988,502,301,540,665,15,529,834,143,536,154,307,990,724,187,250,356,159,519,380,552,230,581,530,88,429,304,937,122,802,819,300,510,232,934,624,723,694,355,544,719,586,96,456,351,255,813,776,143,774,281,35,524,638,683,676,868,849,136,463,343,922,577,682,730,946,621,670,910,959,93,41,496,615,328,958,567,783,968,261,675,825,723,272,885,215,598,103,908,636,976,391,108,902,759,174,143,432,268,283,889,290,289,174,416,427,470,223,459,787,457,10,358,12,832,545,33,914,611,994,559,23,978,697", "223,230,254,674,430,137,95,786,135,408,416,151,492,400,788,324,996,712,318,736,493,911,249,306,274,133,518,966,33,885,171,616,381,545,99,903,140,141,669,237,828,181,74,970,405,19,430,24,803,186,235,190,554,547,106,412,209,942,955,227,97,990,122,351,23,989,875,326,803,107,719,677,370,100,833,868,599,468,777,841,358,933,804,936,761,373,155,901,494,149,938,364,618,266,619,375,138,872,329,3,696,663,880,865,4,724,33,562,914,237,318,469,622,844,196,909,587,657,708,553,259,301,689,683,685,886,123,651,577,444,462,545,580,459,823,114,324,750,57,638,178,300,642,535,230,994,82,46,109,903,763,159,700,389,889,744,259,362,142,857,164,246,705,158,303,498,741,569,88,973,91,518,642,390,415,4,177,521,161,188,990,649,318,418,199,636,513,62,474,489,358,219,352,670,444,591,94,432,322,795,622,528,322,487,901,390,985,785,354,802,383,371,970,429,262,893,394,431,730,178,90,256,270,72,65,625,715,699,796,679,349,878,604,150,238,47,275,887,308,246,148,651,380,330,635,987,186,141,286,155,714,920,547,484,835,542,994,191,235,916,268,676,495,58,5,823,611,751,260,692,246,202,353,190,836,38,425,137,170,388,726,705,864,809,419,812,146,419,174,979,447,677,908,154,545,856,285,642,243,257,505,270,271,716,622,391,334,955,854,859,454,371,685,301,327,811,742,188,667,222,489,531,877,952,914,200,163,320,727,923,599,943,53,774,216,409,103,198,584,804,579,726,958,175,458,529,895,96,481,147,866,968,842,758,129,215,209,77,355,392,313,201,162,436,923,395,391,651,472,128,413,706,727,994,19,706,940,489,793,877,468,903,283,254,174,625,675,836,298,149,707,367,279,647,975,420,125,478,516,285,941,92,361,503,3,939,438,818,924,85,878,128,369,505,959,820,268,828,657,314,216,234,535,253,596,390,516,900,303,648,468,194,711,386,528,225,27,410,506,468,424,797,826,731,749,393,50,701,174,409,825,753,373,135,250,213,355,745,663,832,880,362,819,175,90,685,397,773,630,320,967,461,777,48,188,385,49,940,575,476,772,197,488,140,451,489,290,823,300,8,175,373,93,877,116,369,16,390,809,971,605,328,302,81,100,479,947,983,464,55,470,27,267,10,878,44,502,925,495,794,864,509,98,29,845,36,992,834,707,21,568,764,280,275,789,487,524,376,126,49,76,773,981,988,252,153,312,700,191,285,817,433,834,239,336,974,862,831,496,928,937,289,785,371,938,893,926,681,806,746,952,685,200,749,456,36,141,216,606,577,689,14,178,300,443,935,88,5,495,599,97,427,422,373,808,188,657,981,572,778,744,709,30,821,452,437,80,117,0,274,672,161,177,303,179,805,294,831,82,199,385,101,280,401,423,621,312,267,946,825,651,614,410,987,502,304,15,143,157,250,773,906,67,615,760,937,156,380,971,936,314,891,702,365,937,477,538,963,895,568,283,919,563,338,376,910,743,461,342,17,770,455,802,785,365,952,156,10,631,527,714,175,820,703,675,318,528,366,243,962,48,895,776,262,795,744,798,968,62,429,130,997,336,823,927,547,55,152,154,935,551,290,242,779,466,944,851,703,740,277,118,425,385,908,485,236,707,238,305,534,181,269,572,207,136,475,5,896,476,596,312,903,706,194,886,46,724,29,32,712,230,796,815,557,261,555,204,237,982,985,859,428,690,462,612,202,565,74,39,851,13,789,119,27,257,263,687,756,251,325,53,908,365,914,357,295,219,212,109,112,107,267,591,707,437,201,217,726,933,889,721,781,242,800,578,131,473,182,831,558,452,813,357,636,48,338,710,77,394,480,56,678,790,553,25,654,157,246,492,576,484,40,303,434,297,301,5,963,602,370,566,492,97,615,493,723,634,466,648,381,269,208,442,380,46,478,598,112,445,369,653,197,626,188,877,349,249,586,23,951,829,49,694,409,567,703,853,859,830,943,147,683,269,251,367,178,797,153,365,962,142,705,719,116,127,45,568,263,848,34,500,16,683,251,832,215,755,682,279,487,295,402,415,693,837,201,644,102,396,102,201,526,255,885,21,912,956,286,81,262,376,809,445,973,988,130,81,248,768,239,100,486,22,481,727,532,496,125,925,131,971,954,924,504,373,218,916,718,587,478,390,166,88,140,367,168,645,821,282,603,171,481,417,185,128,850,541,670,919,192,10,921,97,693,201,242,749,339,483,618,981,53,484,373,456,523,973,972,53,749", "299,61,8,198,738,559,574,24,146,120,610,868,669,702,280,784,427,563,358,152,305,944,131,484,265,715,135,399,237,799,46,647,853,469,811,964,103,330,629,608,446,142,705,851,307,358,551,50,854,939,777,642,305,451,975,168,421,723,918,440,771,935,840,241,406,974,561,51,706,777,536,13,994,901,598,55,785,414,874,499,385,528,86,988,851,497,698,999,727,435,370,135,206,323,458,857,819,119,812,108,964,727,228,20,363,178,694,844,8,903,548,319,56,388,112,844,99,991,355,340,808,151,524,633,581,556,929,251,550,838,471,521,52,856,766,937,823,12,477,948,479,597,575,546,912,90,98,739,46,645,313,811,756,742,999,669,412,826,116,318,820,731,255,880,156,387,324,196,984,199,937,488,561,438,543,253,125,557,268,485,14,395,345,26,816,551,652,480,604,164,830,457,413,186,848,642,687,547,57,888,769,886,209,47,108,508,62,8,625,244,749,860,641,436,667,473,634,693,886,533,42,518,511,819,79,730,847,780,773,714,952,698,925,137,859,462,812,81,873,348,655,403,622,556,120,348,196,578,728,938,969,835,447,773,71,810,16,394,169,914,3,698,125,234,22,326,677,451,452,881,556,839,601,184,506,916,200,347,308,314,949,790,100,134,11,950,763,300,665,982,12,168,207,225,822,957,738,776,114,151,205,425,797,723,905,432,656,672,612,621,842,250,446,655,576,611,715,505,824,106,923,108,79,476,160,434,575,539,984,753,622,651,707,337,155,579,882,55,878,551,96,973,35,307,850,962,781,974,210,84,590,527,135,602,521,64,80,760,985,999,626,881,750,143,776,627,719,207,652,616,996,117,553,30,191,645,654,472,688,368,430,427,611,539,413,220,611,343,11,710,54,307,866,580,252,271,259,270,633,840,172,929,866,257,967,152,632,182,833,364,485,997,833,221,604,276,874,895,401,6,634,224,18,762,263,426,647,866,301,208,885,856,585,133,92,76,106,78,26,60,29,49,695,225,10,856,110,291,8,400,569,346,52,70,450,614,11,332,194,173,954,57,600,585,419,851,399,269,430,979,787,506,862,783,898,531,540,728,756,122,604,931,436,715,273,121,950,645,800,195,647,761,771,896,381,906,976,814,423,201,904,855,724,822,707,353,84,383,272,170,24,540,107,826,505,292,334,863,528,338,94,263,76,103,533,155,428,596,422,362,817,690,888,141,800,460,266,739,211,67,987,769,341,839,335,800,137,379,502,139,558,664,39,500,383,951,89,876,632,115,250,521,31,564,563,356,516,899,424,182,269,234,203,648,470,327,277,50,443,400,401,541,262,672,187,130,476,676,36,270,550,85,304,284,460,581,288,806,393,861,438,755,888,265,937,128,650,749,274,0,882,459,580,148,483,330,848,316,775,874,137,145,708,466,89,910,425,685,220,584,428,327,180,224,307,718,261,579,543,238,180,67,907,358,446,416,68,437,330,931,536,925,332,307,860,381,583,313,557,731,782,789,520,992,168,314,727,115,505,54,592,115,834,234,212,829,186,537,853,264,925,574,859,322,955,957,565,575,299,700,137,625,592,299,370,726,461,17,907,39,2,359,76,863,534,68,277,239,618,707,656,859,150,653,352,55,70,332,107,922,647,227,781,338,295,268,749,103,804,668,211,201,578,791,365,868,942,261,852,671,654,554,5,469,519,219,390,325,86,125,911,940,691,972,945,352,638,893,374,969,500,66,742,419,548,3,664,882,586,533,419,21,67,508,33,565,870,752,91,740,62,295,266,470,101,627,749,121,124,75,661,157,431,390,187,122,392,333,439,946,239,231,207,730,602,317,437,414,62,18,435,763,816,814,556,302,903,956,528,894,425,568,164,216,133,607,318,323,183,764,360,810,939,110,581,438,971,515,501,618,302,17,459,596,410,893,567,582,253,532,437,366,886,67,477,395,932,216,541,265,647,676,495,469,288,217,584,296,987,395,858,980,373,752,836,620,970,620,27,112,758,370,455,179,656,89,578,976,979,581,584,25,652,266,162,93,644,63,265,314,816,86,384,614,155,217,795,9,640,516,353,144,955,173,60,261,191,584,258,468,828,656,145,202,85,857,282,8,434,744,270,944,298,907,889,235,324,560,990,717,282,547,419,130,147,612,341,756,883,404,282,875,297,260,736,12,155,382,681,798,862,779,691,754,136,442,695,372,751,707,553,175,402,843,60,582,870,963,513,826,41,524,499,112,968,605,291,617,726,930,859,725,290,684,821,261,128,127,566,659", "298,834,574,784,797,974,949,876,616,672,890,292,538,111,362,23,109,111,351,986,438,810,935,503,983,821,646,302,827,575,133,477,964,949,630,273,385,268,580,332,419,688,891,846,162,8,513,153,801,418,461,220,226,607,758,179,462,66,765,706,253,816,622,660,183,129,508,360,561,71,313,547,722,403,161,870,832,629,758,131,879,332,731,17,216,960,4,496,261,851,803,487,806,916,58,699,379,61,115,304,841,426,711,928,97,448,518,644,903,252,412,200,821,362,424,599,977,615,826,903,656,531,366,904,553,803,821,605,387,779,971,905,891,707,885,333,958,602,446,433,157,610,206,449,466,233,81,291,595,232,110,227,576,783,135,952,41,372,646,527,158,939,444,562,878,717,509,794,920,15,101,299,266,212,122,354,41,259,26,232,631,71,227,467,129,22,821,930,555,993,562,692,240,919,459,764,529,600,433,107,438,136,791,399,416,452,477,601,88,427,922,690,340,905,282,769,763,341,797,436,527,983,898,750,418,544,948,888,979,814,968,488,610,275,32,671,335,141,831,803,708,735,22,218,886,981,920,499,259,654,625,617,134,969,301,136,190,379,715,855,696,405,169,536,180,417,420,407,125,31,818,199,521,879,409,58,964,290,175,706,465,132,376,850,307,133,724,890,511,989,576,440,666,574,224,930,846,979,584,131,53,250,551,963,927,881,977,346,226,794,880,192,296,555,399,515,510,96,543,561,763,978,581,357,495,266,655,90,136,979,743,560,419,75,365,540,202,594,141,872,830,536,242,773,980,746,680,488,433,488,453,230,569,921,728,940,632,386,524,19,627,828,1000,573,508,714,577,816,986,3,747,70,758,343,864,851,736,423,33,674,78,251,846,649,106,312,641,214,741,174,878,404,912,236,983,260,519,143,994,506,996,631,615,377,392,809,779,749,372,868,321,619,308,598,369,658,142,884,112,829,671,577,614,518,565,861,11,139,745,670,928,472,95,732,431,262,496,181,486,265,998,11,778,370,603,639,862,127,361,292,429,556,827,489,700,610,369,336,918,735,96,921,255,880,327,765,811,471,375,235,192,622,722,378,14,809,573,551,378,943,942,549,61,430,542,965,796,863,933,855,899,323,102,186,381,152,237,897,481,186,830,553,361,163,291,548,662,115,826,390,640,846,694,286,189,78,799,34,50,20,443,761,539,430,25,931,75,961,889,86,155,965,697,845,498,314,46,559,535,375,501,144,463,316,171,762,689,278,528,529,964,576,93,296,850,239,43,576,265,155,292,54,478,799,744,477,62,408,690,131,226,823,686,488,284,671,72,394,452,475,136,458,809,108,12,224,790,848,182,183,877,698,471,968,796,881,31,239,742,844,336,837,515,904,273,311,331,253,672,882,0,510,575,121,810,782,216,208,954,131,365,643,511,327,720,905,559,263,796,26,628,340,523,764,549,28,573,979,470,937,812,533,857,290,874,777,144,335,980,719,929,623,775,457,206,232,468,28,495,622,86,274,233,549,156,353,209,219,881,485,170,373,554,70,53,220,539,198,180,955,56,632,744,124,9,390,590,537,604,784,337,831,213,696,494,854,390,361,37,862,774,91,407,373,809,661,103,766,552,388,970,981,688,761,500,195,210,225,714,461,68,710,947,70,859,669,273,363,468,387,183,295,585,831,166,771,359,868,99,207,79,35,910,327,357,117,548,768,805,455,583,323,7,259,619,331,996,346,604,219,547,771,691,313,13,687,759,757,561,945,979,237,96,399,125,646,547,628,171,735,595,429,985,206,414,362,905,313,690,129,447,5,460,905,626,422,2,984,501,48,127,758,918,579,865,906,74,860,394,434,217,847,26,119,796,510,486,762,946,231,495,858,181,799,153,123,81,745,676,157,486,707,465,869,408,893,404,474,119,386,502,256,568,195,256,747,389,813,51,377,397,5,738,525,281,778,224,205,313,808,623,118,772,355,73,277,537,289,843,198,506,65,956,248,117,991,77,418,975,898,91,22,16,861,817,173,452,842,647,959,706,671,388,351,395,181,766,146,773,744,342,896,93,964,381,757,491,558,239,185,447,705,432,742,802,966,909,730,568,263,621,457,957,373,859,57,270,241,769,262,348,787,972,764,692,500,847,354,448,551,290,896,389,763,221,550,913,78,565,722,895,695,800,823,270,171,297,456,459,769,888,940,264,970,746,171,85,883,663,705,712,513,912,630,144,723,267,792,608,569,642,936,903,549,134,663,591,739,965,538,542,950,891,199,481,986,421,981,306,94", "981,940,804,184,127,70,493,311,445,327,648,618,190,132,754,116,755,482,446,757,741,722,566,607,358,661,154,194,125,582,702,696,223,357,229,22,258,379,948,385,895,884,791,516,77,664,367,540,967,312,691,989,522,367,847,283,736,38,404,108,50,471,471,893,386,747,98,745,885,897,418,257,720,640,487,631,850,914,95,518,280,483,644,153,689,268,699,80,167,696,732,230,837,445,489,720,809,468,315,341,294,248,544,513,39,942,786,109,266,863,864,127,25,271,166,587,213,939,101,850,663,355,511,56,182,882,740,282,795,829,295,675,614,539,312,617,428,918,704,492,556,409,388,804,46,821,477,115,548,465,642,141,262,448,893,138,880,454,476,11,50,740,207,898,742,837,221,626,920,327,3,778,278,4,439,31,163,551,397,150,623,723,774,855,542,754,883,868,484,608,926,686,339,994,680,266,342,228,707,616,412,773,11,372,486,737,799,395,775,447,190,444,518,19,557,561,60,49,42,645,675,783,159,273,362,77,802,71,582,869,314,322,803,576,13,748,647,637,18,795,756,518,501,515,9,454,853,80,349,233,232,860,995,221,553,351,866,319,611,527,84,463,823,111,171,830,371,146,963,535,22,730,132,276,915,778,565,820,737,518,923,117,332,834,725,653,251,691,589,606,542,620,879,52,360,193,372,20,784,664,646,389,469,503,386,614,890,457,236,922,949,237,4,847,385,312,495,820,741,7,670,921,891,79,579,41,650,448,104,29,478,887,402,540,314,750,204,100,915,901,561,123,190,412,198,66,841,729,32,214,515,935,760,301,991,145,648,331,990,788,181,569,2,340,435,587,853,483,133,123,603,955,101,701,597,624,652,139,611,720,551,430,85,92,671,958,284,231,380,317,417,681,994,237,515,222,185,225,279,635,433,824,417,870,144,534,114,477,347,697,875,248,261,27,360,702,982,692,200,385,996,685,520,644,879,301,650,615,534,360,81,568,513,883,911,710,829,211,496,814,569,854,479,976,981,680,989,629,479,441,851,765,199,805,191,965,77,692,266,414,449,309,252,333,215,854,660,880,157,191,617,179,120,923,283,44,784,221,214,772,153,629,850,365,717,644,664,974,983,916,203,677,636,865,344,506,453,890,984,302,572,393,857,649,769,86,369,790,408,148,493,598,490,14,466,863,972,332,984,601,422,190,406,775,372,630,988,59,409,357,774,650,400,625,992,539,939,726,197,94,461,539,136,506,622,516,365,934,959,405,353,406,273,686,569,750,97,996,50,734,701,339,361,116,870,115,301,401,866,587,248,635,737,839,139,893,211,613,41,280,581,920,192,799,202,428,162,325,887,803,878,482,182,298,283,894,774,158,284,915,410,736,160,921,892,322,66,767,161,459,510,0,764,571,141,728,457,744,884,574,720,604,150,158,813,69,544,783,753,404,301,716,464,547,914,614,695,156,369,994,600,538,806,657,55,112,652,848,953,976,597,792,98,753,471,171,946,690,311,876,299,737,728,332,325,542,17,931,384,303,933,38,113,80,456,616,166,691,973,291,164,929,498,917,711,486,81,433,477,529,801,994,417,710,671,587,317,729,19,939,280,262,772,982,135,203,971,889,823,670,507,328,66,539,727,961,769,418,408,281,375,209,525,654,538,809,361,690,55,21,764,716,553,143,844,527,354,647,760,611,136,536,236,868,971,585,872,936,532,156,905,350,860,991,39,261,170,877,422,416,129,464,454,171,205,835,433,835,325,848,104,594,70,256,302,568,253,883,715,529,726,197,90,833,86,610,458,468,382,42,942,212,747,598,41,724,325,783,872,127,592,288,669,445,923,293,255,965,673,908,133,530,67,795,127,813,62,965,761,79,149,849,109,826,633,87,952,230,680,102,387,212,164,816,306,213,241,676,550,777,667,391,188,108,90,686,248,249,206,550,573,788,717,64,483,572,543,846,919,996,843,809,230,482,383,622,261,932,72,654,62,413,398,717,43,580,178,973,53,523,168,32,495,849,450,420,311,672,174,738,738,41,442,449,303,624,115,203,125,534,166,545,223,317,913,938,950,79,511,858,606,975,5,598,766,225,947,585,959,716,58,154,409,229,69,981,476,707,236,982,61,885,439,318,305,623,650,758,822,513,903,253,584,851,548,69,561,563,370,885,932,388,721,143,88,449,436,973,752,53,579,604,272,17,637,44,29,70,826,975,65,663,791,981,769,745,791,539,635,296,92,483,534,465,750,29,993,212,13,374,545,681,775,779,237,101,756,916,897,288", "642,156,798,159,576,306,175,54,725,455,28,642,97,856,691,738,18,264,834,50,697,530,104,837,716,384,767,815,660,190,955,168,154,401,83,505,226,374,134,342,480,225,978,694,452,192,956,603,880,432,595,113,503,614,946,498,792,723,948,395,662,908,18,631,980,491,968,135,782,57,753,637,805,882,908,800,88,718,639,822,538,899,10,642,294,669,644,340,202,305,140,155,955,355,991,793,581,529,999,943,324,294,740,178,810,326,722,246,92,1,318,428,52,65,850,266,608,617,45,736,699,328,27,675,110,366,738,781,970,721,335,32,571,404,234,806,677,712,592,519,725,145,109,699,499,654,588,948,675,606,485,500,963,203,907,606,619,23,869,420,150,242,428,488,511,416,126,678,235,152,278,523,440,878,322,363,296,76,750,667,366,874,949,725,907,555,290,993,835,479,928,149,278,412,907,128,538,479,402,227,273,558,130,10,714,337,589,550,682,236,337,763,947,997,453,852,88,5,790,929,610,41,962,4,321,124,850,166,960,225,764,637,842,203,398,922,333,760,35,109,177,31,590,24,222,754,341,676,787,423,46,690,989,939,751,185,372,768,690,555,537,404,75,271,183,818,976,540,296,17,110,725,83,931,895,967,310,433,654,790,722,399,349,542,238,342,136,949,197,245,893,75,116,638,745,71,218,371,756,237,381,209,16,295,41,88,65,363,158,832,529,939,88,272,934,656,816,108,573,682,989,58,636,79,102,535,186,45,10,933,75,357,431,575,289,720,336,380,895,828,813,137,254,342,448,928,68,368,789,128,962,451,122,76,858,151,636,130,188,587,616,358,184,732,875,492,278,245,958,32,517,645,924,121,793,640,907,325,984,975,785,379,795,470,236,358,197,502,262,785,751,499,49,211,57,927,650,371,34,787,799,938,662,117,739,743,522,634,967,251,26,655,930,385,907,22,563,623,950,504,934,568,217,921,153,136,214,880,253,995,604,960,269,328,425,573,822,302,823,191,413,889,103,137,575,495,575,386,68,525,715,741,820,941,899,300,649,151,735,62,916,155,23,890,993,691,431,898,146,197,986,532,410,442,593,122,403,806,795,55,474,980,967,75,149,691,659,225,206,397,757,625,858,832,362,448,52,580,234,383,701,742,514,858,57,178,514,28,912,884,427,844,231,74,100,899,683,690,373,762,917,220,237,765,866,513,639,771,560,414,677,190,746,521,139,856,318,549,901,212,927,104,183,461,311,181,827,845,867,768,114,407,175,397,162,732,51,335,216,390,396,378,504,477,650,442,883,427,46,901,653,583,105,519,321,775,396,842,108,803,743,880,556,567,791,227,546,484,82,127,511,487,79,422,785,151,535,685,837,460,467,521,790,5,300,374,498,636,177,580,575,764,0,26,806,250,833,237,251,26,747,169,982,901,442,903,442,122,10,46,830,467,133,81,515,354,374,11,210,51,720,440,607,918,787,61,395,657,631,238,961,834,808,271,461,14,392,463,807,130,1,271,541,192,280,387,609,146,855,493,367,256,217,501,257,537,112,551,543,267,857,573,340,558,846,125,78,898,524,467,179,175,671,200,399,569,519,504,17,740,658,801,120,414,76,792,185,412,533,165,859,678,718,353,82,900,852,808,243,242,781,269,781,305,301,24,900,923,443,371,614,804,418,607,314,455,79,332,419,150,341,820,739,278,46,102,174,207,444,950,645,586,896,431,933,388,383,683,305,354,659,819,526,414,283,717,803,609,644,767,102,746,152,144,975,883,221,34,498,798,518,338,239,805,369,893,361,256,309,812,984,283,448,602,279,59,152,414,130,58,837,742,695,203,487,237,741,286,577,681,412,188,35,382,942,375,638,338,868,441,824,296,545,914,904,116,738,953,939,526,856,293,290,474,793,335,138,32,773,18,168,801,781,550,588,756,971,85,271,785,673,942,631,513,236,424,781,982,495,740,665,58,768,803,549,412,201,58,841,504,751,317,220,209,909,361,703,349,193,87,935,643,831,926,625,468,4,194,94,480,117,139,648,920,890,377,89,854,742,655,322,505,828,864,427,258,496,137,536,217,232,2,7,395,762,197,432,369,463,62,347,730,787,319,195,465,452,369,721,992,772,974,698,612,655,487,927,456,492,843,638,33,3,522,267,556,136,955,582,485,83,167,481,141,221,270,361,418,277,791,157,733,988,265,400,841,671,797,433,878,660,205,667,924,673,236,934,134,442,731,375,270,927,942,887,706,209,462,694,43,150,627,881,817,883,551,586,441,213,209", "100,410,832,845,100,933,153,227,318,770,474,566,262,149,790,505,454,429,515,857,642,277,518,197,920,187,572,534,28,581,816,709,474,215,624,114,932,963,348,557,255,254,108,602,411,674,989,848,225,995,212,314,380,826,621,887,68,806,912,555,880,681,481,91,908,822,106,143,900,196,685,368,771,184,402,417,768,934,418,270,78,471,604,351,910,131,384,867,403,86,763,83,796,665,365,258,930,933,476,72,328,100,245,112,780,88,823,354,881,444,256,809,974,259,978,265,41,643,471,667,915,153,555,923,565,774,237,960,189,678,548,91,185,15,26,895,517,235,633,704,870,954,987,910,642,18,215,915,679,280,674,431,945,198,773,791,224,341,357,649,771,194,15,595,812,312,269,383,149,111,169,982,326,746,45,696,456,176,786,886,211,29,781,872,716,525,34,68,917,801,612,304,654,609,254,393,687,25,510,451,881,284,199,9,811,213,768,849,718,943,979,780,598,320,646,420,966,214,711,163,567,244,366,712,660,44,826,182,680,726,882,497,132,435,762,572,329,671,442,603,397,399,595,793,755,556,310,846,62,724,305,697,674,181,265,960,205,281,87,124,324,973,639,2,108,635,48,105,92,234,487,456,825,485,979,116,405,618,849,33,812,269,72,340,81,936,64,398,574,101,824,440,455,399,217,705,549,542,915,154,416,310,315,924,982,700,334,541,34,188,918,951,35,872,220,175,584,529,691,426,979,941,317,790,868,763,784,912,535,561,976,593,464,510,960,440,759,304,960,970,718,309,880,327,4,127,217,2,239,463,43,728,736,239,727,934,221,891,269,535,999,184,259,72,312,810,943,630,747,730,711,780,367,470,574,685,405,419,415,818,510,469,642,828,874,607,754,642,624,727,727,273,625,117,135,164,422,763,487,738,8,343,726,4,515,138,625,161,319,783,153,402,564,398,192,664,349,516,33,381,636,796,279,211,365,86,19,628,251,116,69,830,799,930,153,740,982,59,76,574,780,778,232,251,965,980,888,784,583,60,305,870,199,375,854,941,201,467,724,425,682,447,985,981,892,376,6,104,324,859,771,892,655,557,134,162,307,684,366,405,418,186,165,306,373,419,491,624,930,723,840,607,525,34,168,740,200,87,570,459,681,33,674,244,523,374,905,783,100,50,590,537,614,350,768,415,416,482,876,221,651,647,905,879,186,447,955,272,593,221,424,860,420,169,150,185,762,460,542,45,301,283,509,736,809,729,448,69,618,99,177,26,869,540,23,600,729,731,616,363,244,886,615,33,831,62,945,984,252,743,802,777,368,390,412,759,174,902,14,49,914,604,76,770,510,850,245,332,499,565,201,599,906,355,383,490,799,380,146,459,534,888,400,520,992,616,645,850,303,148,121,571,26,0,136,11,256,64,682,515,979,262,677,509,741,916,792,860,380,111,424,950,396,606,735,463,421,668,765,583,885,458,472,10,587,256,243,441,908,537,15,792,975,436,669,890,567,963,122,756,984,761,99,614,612,165,348,536,843,841,891,370,347,795,7,276,984,651,971,279,394,324,547,487,596,698,432,496,692,301,788,681,466,280,402,828,677,819,790,740,223,781,331,887,628,2,341,481,206,504,658,663,349,305,465,123,732,438,120,942,579,29,19,121,875,73,718,753,34,888,932,349,936,822,365,512,149,860,438,426,178,749,979,716,109,144,205,244,651,115,904,245,751,64,428,522,922,672,605,252,231,332,767,414,185,237,505,696,976,377,96,382,770,161,676,935,605,804,770,857,2,734,730,666,235,421,489,385,52,395,894,803,82,529,786,719,586,687,576,550,841,260,250,533,963,191,813,625,254,239,59,455,901,867,307,590,193,955,262,541,213,345,522,347,605,360,723,688,17,928,545,801,571,938,952,559,394,8,57,674,363,792,46,799,803,344,460,880,733,193,955,50,283,729,476,87,505,155,718,933,682,233,962,517,863,736,602,912,310,632,827,863,127,69,314,356,177,685,360,369,19,37,224,740,275,328,591,339,721,622,26,60,651,301,30,696,494,236,141,110,481,559,286,718,130,233,105,146,452,181,70,96,259,68,514,103,765,847,142,719,276,246,257,63,759,856,206,160,714,975,504,399,432,347,205,156,622,281,959,461,647,259,923,277,558,390,186,262,662,35,694,568,731,252,600,700,20,503,506,319,836,400,633,720,137,961,188,295,350,935,505,656,56,239,990,123,743,629,771,216,356,575,782,473,767,246,611,123,701,713,968,394,507,369,195,94,426,286,812,498", "95,734,883,876,980,457,273,577,562,134,394,973,598,449,115,463,227,200,820,325,631,660,609,691,922,914,64,968,539,556,294,949,480,850,684,314,384,204,992,693,793,106,728,454,995,381,594,459,847,268,642,39,832,436,961,153,613,218,874,881,309,304,657,92,379,822,76,368,743,356,998,62,544,413,384,491,154,485,804,434,872,595,110,299,661,785,621,999,510,789,300,206,200,686,973,668,200,293,186,242,392,193,498,910,763,737,737,863,367,172,657,503,961,540,408,752,423,425,173,543,524,465,285,858,140,164,412,181,512,897,779,248,551,43,237,458,620,233,683,832,275,557,547,306,545,910,824,553,74,880,121,336,886,800,182,326,666,336,454,628,488,322,4,841,746,295,259,894,934,636,403,142,371,52,142,467,557,281,233,358,936,573,366,342,166,437,273,380,672,242,873,70,883,852,986,720,574,41,781,16,248,480,150,466,239,426,342,735,421,511,576,18,172,395,513,363,200,681,732,901,762,943,650,303,598,185,452,706,254,783,233,573,666,18,711,728,630,515,479,946,973,466,431,784,419,194,929,870,364,110,861,39,390,279,331,940,908,636,276,627,776,103,840,908,397,152,681,94,756,130,533,918,800,396,843,832,918,115,290,728,124,486,944,132,75,921,576,369,247,411,22,867,787,800,60,121,120,677,520,172,809,270,125,254,549,210,408,607,749,754,867,810,639,726,236,384,796,427,594,831,764,445,182,776,29,410,133,50,124,67,676,714,363,857,480,128,724,77,38,949,352,608,623,209,737,570,882,802,129,924,442,405,627,367,494,403,14,955,700,572,354,88,604,355,87,127,270,753,749,632,161,516,138,814,948,655,714,836,528,663,788,213,699,29,64,750,203,328,171,525,588,227,273,301,965,735,331,947,676,456,762,735,106,783,583,931,879,57,258,840,624,454,22,494,568,728,763,511,973,902,132,818,961,300,236,645,937,754,408,601,236,651,697,721,907,454,283,527,459,279,30,293,707,898,958,592,181,89,789,707,869,347,767,973,583,178,417,890,174,821,387,426,672,651,496,541,723,568,715,555,727,865,183,733,218,782,959,345,532,876,969,372,489,60,496,769,582,240,400,955,284,773,722,194,793,118,256,996,22,305,100,563,252,101,636,716,615,693,384,940,909,578,905,870,854,945,162,529,666,70,347,676,934,158,404,328,8,351,20,694,911,714,546,688,530,373,250,430,557,98,76,654,104,772,664,58,12,56,361,972,691,914,336,147,668,16,227,804,581,591,937,725,747,260,998,910,456,555,995,375,738,793,549,432,550,432,348,918,772,802,745,910,457,856,388,126,879,320,173,723,169,104,314,563,707,181,504,515,206,844,908,313,701,843,453,321,871,62,179,483,810,141,806,136,0,582,351,295,998,346,662,837,39,327,855,765,519,601,776,682,416,111,845,15,683,80,867,548,105,593,192,936,49,995,457,679,733,132,77,222,761,759,161,276,191,638,952,800,659,157,57,523,149,730,632,401,78,751,792,626,892,262,288,5,863,959,684,185,707,302,593,299,73,925,615,738,165,593,117,369,515,345,463,238,515,422,161,154,981,235,550,189,842,49,498,460,764,535,849,60,94,265,279,209,392,157,30,580,5,450,422,63,454,680,670,931,140,3,849,910,75,607,20,151,766,527,848,91,283,266,501,692,917,135,471,342,963,583,992,889,161,171,872,437,252,877,336,332,884,16,70,743,628,144,609,655,148,171,168,322,613,567,990,890,239,111,756,583,992,284,874,845,359,401,574,585,240,890,549,692,302,431,860,622,588,879,149,259,64,252,253,113,205,69,82,911,446,946,258,880,422,830,348,722,980,382,900,228,517,500,310,365,160,234,478,285,242,759,302,350,335,483,278,287,155,799,379,736,613,107,103,523,959,728,242,166,243,925,25,25,937,694,520,545,810,410,834,698,879,3,689,396,912,631,642,724,923,574,539,435,850,663,526,779,76,231,563,493,90,85,266,209,691,304,167,280,684,75,542,374,207,6,796,533,485,933,702,154,28,232,276,818,71,589,416,138,972,588,708,407,16,288,157,356,290,786,331,961,90,428,429,818,139,351,865,941,634,417,496,833,955,575,591,966,486,293,229,423,630,153,798,903,611,627,856,927,105,277,152,812,380,456,759,104,181,23,266,627,636,792,544,431,102,327,275,156,128,945,292,127,814,700,319,153,150,809,561,441,735,3,220,975,11,505,25,339,629,829,730,282,767,39,785,28,978,166,588,488,371,865", "828,599,137,87,867,864,73,339,571,842,51,932,657,658,921,857,897,835,395,227,728,23,27,201,286,386,297,956,843,703,734,679,411,881,661,676,195,58,312,517,620,215,145,538,181,107,106,654,355,116,710,965,811,539,503,145,698,623,392,556,582,915,925,330,558,80,980,393,249,143,610,145,775,99,102,838,699,138,886,712,881,631,989,518,305,204,893,215,148,238,659,480,826,464,522,916,106,782,710,980,939,316,668,169,996,611,849,459,969,209,651,965,164,478,449,686,651,362,28,893,252,466,708,599,992,174,411,978,739,631,920,283,802,994,207,615,536,344,204,245,118,17,348,776,141,177,16,305,949,615,370,779,901,888,461,921,650,126,171,289,435,986,105,735,479,353,783,898,344,79,208,416,963,399,473,289,447,142,888,688,717,995,70,716,790,886,861,819,637,404,637,961,441,100,113,290,459,735,755,448,130,460,299,736,606,903,372,861,894,826,673,192,941,680,761,194,225,757,253,437,769,940,419,969,773,272,794,503,349,686,561,932,387,180,839,426,206,181,443,585,920,351,885,416,434,849,495,257,261,322,42,276,134,425,684,670,577,857,521,29,983,247,387,12,323,143,940,595,926,591,126,622,714,557,356,376,916,825,480,744,559,691,45,998,328,565,430,595,580,573,361,309,167,251,109,841,386,274,133,447,415,474,93,144,543,459,790,916,506,594,82,187,10,45,312,992,383,401,421,374,348,579,520,791,462,30,635,671,761,949,353,282,114,860,494,460,696,24,939,764,381,466,328,429,771,513,256,10,907,640,541,854,285,905,525,560,276,325,206,307,599,395,826,256,56,39,548,706,489,166,420,666,706,965,149,76,486,136,758,206,52,829,544,454,736,769,827,97,905,331,787,855,444,81,417,534,225,588,445,283,948,970,217,450,660,646,952,122,765,287,194,73,455,688,357,286,686,954,945,581,779,933,381,117,888,279,520,420,183,854,286,632,3,52,689,179,921,511,395,622,638,772,977,440,247,392,851,452,652,345,306,314,177,84,151,497,450,151,300,856,857,290,141,630,927,386,257,925,259,109,588,476,925,343,959,626,954,176,650,183,732,193,42,9,312,676,851,706,914,610,124,504,511,810,933,561,773,634,305,509,393,241,10,605,377,954,518,378,843,943,536,276,381,619,168,911,267,645,200,726,902,381,287,604,202,956,947,316,774,491,745,606,163,268,332,589,97,992,580,84,944,655,652,720,740,246,362,266,195,265,228,696,434,110,609,167,886,36,662,755,265,716,17,208,975,944,73,796,603,472,977,964,376,871,296,281,705,442,431,546,153,563,661,68,28,132,756,545,145,682,844,39,418,534,700,314,808,450,308,929,662,912,45,911,591,791,537,290,805,330,782,728,250,11,582,0,809,849,628,614,786,966,920,593,145,605,238,173,242,685,907,638,237,990,722,129,73,257,281,379,111,403,964,897,270,449,737,901,903,357,562,808,316,701,707,685,755,595,924,842,315,934,802,455,745,721,19,758,773,514,756,518,936,751,754,894,906,43,576,365,791,177,984,881,927,721,516,608,709,626,960,849,510,769,583,980,278,948,358,156,48,147,908,408,7,756,998,688,981,874,671,140,920,780,627,367,804,268,431,186,527,893,39,30,69,969,901,328,174,518,952,745,817,115,14,386,738,13,231,759,258,579,587,607,239,670,63,7,496,686,583,62,1,671,579,534,401,877,453,264,774,596,415,499,511,138,186,113,730,120,93,776,216,647,529,179,223,143,367,264,521,852,823,776,138,19,503,418,390,933,673,322,493,2,334,935,648,398,438,937,792,843,786,377,429,302,69,61,703,6,268,156,3,661,795,559,892,449,808,567,931,925,373,492,453,103,725,915,684,274,567,668,835,253,570,100,226,19,37,358,964,797,698,743,984,624,407,915,237,371,404,288,749,432,649,775,462,471,880,11,423,482,328,886,921,277,157,630,445,702,554,459,29,13,392,463,111,692,341,941,922,380,433,634,849,975,286,407,740,184,310,858,162,869,984,401,765,446,392,666,468,518,778,218,963,566,102,738,380,401,480,687,787,887,465,555,637,878,362,34,448,783,861,746,163,338,134,991,608,909,634,605,843,350,757,624,941,975,286,71,965,932,973,98,226,98,886,565,853,621,655,884,420,895,926,757,820,321,900,524,717,849,462,537,69,182,77,462,414,364,109,820,67,39,456,351,762,783,882,477,380,960,350,165,397,928,614,872,44,164,905,489,559,72,164,915,118,93,49,630", "794,444,694,817,204,437,276,537,801,329,926,51,916,151,508,663,626,815,281,254,294,756,674,192,982,484,346,607,415,52,952,681,356,942,912,247,343,486,556,287,490,718,795,534,386,947,559,870,182,871,769,771,993,649,703,358,591,722,771,747,308,793,297,296,415,833,979,849,596,137,242,416,843,106,377,824,803,378,313,615,778,355,780,979,24,958,334,617,263,372,927,787,328,28,204,893,446,276,397,908,474,735,70,579,371,224,568,39,600,315,349,730,642,831,286,964,775,636,220,642,899,684,400,70,566,405,752,129,747,60,11,423,58,296,596,462,782,507,505,643,198,967,154,495,818,194,387,614,457,192,598,145,505,773,984,891,276,737,332,545,330,289,580,597,368,469,61,685,793,443,833,999,374,192,415,195,144,195,570,880,839,304,908,785,19,95,501,693,377,279,934,23,824,384,538,703,428,724,694,294,263,620,505,871,933,356,64,257,332,742,833,272,157,214,406,237,861,717,818,517,569,962,969,322,143,758,88,690,497,271,231,363,347,200,378,45,36,396,333,250,13,881,790,950,244,70,913,319,261,975,112,104,156,75,295,956,588,447,31,260,493,406,864,443,228,400,227,694,47,844,87,923,604,557,557,592,75,423,460,413,115,598,771,868,248,648,759,336,579,365,262,487,73,247,863,702,924,203,105,859,814,428,481,208,205,560,502,351,196,654,723,453,654,781,41,578,246,841,681,824,39,430,921,76,148,104,275,541,955,872,480,701,465,154,364,974,444,483,444,288,534,769,512,784,112,714,287,361,214,476,811,440,427,446,968,790,820,698,449,927,236,271,778,491,75,558,766,580,288,516,809,663,659,282,93,115,785,575,251,935,424,540,871,647,322,352,354,380,669,282,309,265,637,632,917,935,210,799,162,481,33,388,1,529,76,988,936,274,532,385,63,928,755,505,787,236,87,520,33,127,540,145,864,587,123,391,40,671,273,890,523,973,223,463,701,844,739,353,444,716,152,43,674,278,740,393,948,733,345,741,50,746,976,221,525,570,892,174,457,309,131,171,289,921,45,586,47,513,597,114,85,816,255,656,249,391,581,726,403,876,734,255,2,711,17,105,298,742,332,306,184,624,813,608,211,380,127,961,405,670,31,10,406,668,693,598,994,891,855,441,892,57,649,70,698,340,865,60,492,106,78,588,467,438,576,420,898,945,143,867,405,206,932,369,598,583,382,958,402,193,112,787,459,124,710,611,454,403,81,367,787,633,945,664,665,954,309,200,410,292,265,667,223,60,23,931,536,525,790,489,325,974,756,993,38,733,302,192,239,509,928,885,197,80,845,596,819,671,111,962,202,141,469,807,107,562,741,781,329,925,974,367,872,43,403,925,732,434,294,848,216,457,833,256,351,809,0,860,112,803,200,634,816,822,552,957,476,381,927,225,957,842,622,70,136,474,17,73,619,943,505,192,645,184,353,602,327,922,735,715,879,474,426,733,732,981,303,518,859,372,622,144,838,267,637,534,631,992,362,322,484,53,299,242,180,373,337,236,455,645,456,366,725,757,772,491,539,699,68,902,936,475,447,59,249,810,810,810,658,549,913,937,406,932,652,311,706,61,690,820,657,323,544,528,711,893,953,879,943,682,361,132,424,598,869,354,720,411,880,890,495,366,876,656,309,850,519,134,926,757,943,837,762,902,718,211,71,651,15,11,304,931,753,96,267,138,939,252,368,663,468,637,638,645,826,224,206,539,94,106,330,464,368,225,467,280,63,858,671,523,652,692,860,213,698,441,727,753,632,45,665,28,472,60,675,733,50,713,668,211,607,158,233,151,697,337,354,563,748,273,427,32,373,596,730,840,521,208,82,314,11,527,375,591,198,656,559,891,680,75,965,700,195,861,119,900,625,584,608,188,799,500,66,170,774,556,38,825,267,592,67,106,42,622,88,333,796,529,185,898,403,380,643,41,995,49,617,739,466,453,749,755,845,459,683,60,749,424,324,242,33,200,349,750,322,22,433,6,812,819,200,720,692,147,143,420,648,85,23,666,78,493,317,676,465,919,412,350,753,135,911,586,952,435,260,827,206,211,52,274,298,389,882,122,141,586,427,149,192,24,582,802,232,981,498,451,853,961,817,255,99,823,252,366,466,966,468,953,434,442,397,799,198,747,692,150,416,697,180,561,761,275,655,428,488,620,605,453,388,83,788,243,243,453,263,715,192,433,82,512,405,37,886,131,333,513,901,845,476,596,664,972,112,688,747,385,102,862,104,322", "689,399,608,726,620,910,353,115,724,994,197,782,147,542,841,202,720,874,100,59,861,697,675,893,699,738,238,134,282,758,584,948,544,937,429,761,499,292,140,377,682,257,389,279,648,911,257,986,662,344,719,103,211,106,120,536,420,508,162,28,493,220,111,488,764,604,720,63,74,486,428,951,250,51,725,795,564,966,407,878,224,461,649,430,514,654,673,969,55,306,766,499,475,643,195,991,556,639,651,733,521,354,985,434,281,108,680,866,737,559,819,152,384,940,764,325,708,530,142,420,479,847,459,297,738,663,422,435,352,217,467,52,219,204,380,734,195,388,823,563,621,377,42,490,378,674,891,663,308,464,937,224,786,808,568,746,465,414,693,415,175,481,459,283,415,903,72,958,370,498,409,879,314,777,596,882,40,828,210,257,983,704,561,997,584,202,678,776,626,750,970,875,779,695,891,96,437,507,700,247,559,721,519,66,741,834,718,512,478,132,483,680,734,244,948,698,55,769,36,783,457,798,846,88,665,761,144,690,166,269,751,497,599,894,78,17,188,355,736,813,108,40,72,833,169,185,412,222,47,842,870,273,49,902,675,694,86,425,231,959,607,797,19,315,305,169,602,576,549,96,550,526,325,910,691,98,736,764,660,815,58,95,123,18,357,891,24,548,404,956,198,896,393,122,733,962,507,881,738,912,997,359,535,558,6,309,228,260,75,51,18,463,726,384,171,741,18,870,775,587,20,666,315,768,456,930,884,636,869,571,564,31,327,228,18,855,899,5,534,892,903,798,552,725,596,595,36,866,921,229,370,791,690,183,981,570,594,443,49,271,396,673,931,837,94,607,872,276,659,256,573,830,533,936,867,917,268,516,801,443,128,479,487,558,661,780,64,667,341,788,339,372,127,395,152,244,797,676,763,721,845,932,832,211,810,392,669,619,259,175,689,798,11,118,320,575,434,12,172,174,996,511,583,212,473,962,336,68,86,793,801,69,141,8,71,69,906,8,788,303,457,777,680,928,757,290,21,910,93,116,466,867,331,782,135,875,426,879,871,61,45,659,601,690,95,309,277,601,614,349,901,338,571,93,675,533,46,583,996,156,210,917,818,116,147,973,766,763,740,479,599,763,944,844,771,829,961,5,750,560,117,708,57,887,46,954,764,697,370,550,456,399,282,95,230,645,582,320,100,917,744,699,205,752,191,794,577,891,534,576,733,398,1,512,41,372,637,80,938,449,30,707,461,572,467,868,971,907,678,9,480,409,390,53,943,993,445,994,54,879,508,332,850,25,51,873,707,648,395,705,532,954,298,795,265,495,165,246,110,181,875,462,999,931,239,929,676,403,504,31,937,728,787,769,157,860,496,608,60,341,824,672,594,150,712,926,742,474,831,316,208,744,237,64,295,849,860,0,882,202,252,271,767,733,778,793,593,926,295,604,428,839,690,694,691,937,131,646,881,657,973,60,419,883,738,35,795,910,422,148,261,603,846,287,266,826,581,499,989,270,628,243,929,778,803,496,3,646,637,944,329,247,157,965,193,772,964,585,953,864,476,275,547,205,86,968,328,285,555,502,846,681,803,261,879,62,90,85,738,392,831,451,899,569,745,604,724,406,616,732,74,412,448,459,690,36,6,170,380,632,63,322,777,670,625,950,987,423,334,430,746,459,724,24,635,787,106,317,362,886,61,992,30,720,781,903,909,60,388,124,51,236,624,757,780,420,179,61,264,557,580,451,545,927,586,448,61,359,625,906,418,323,846,393,293,120,55,90,59,104,383,544,387,712,222,214,164,323,974,785,92,976,94,679,109,686,425,996,368,465,551,163,445,13,15,298,536,806,931,541,858,947,486,313,624,564,343,833,22,412,745,306,165,270,496,87,135,217,545,997,914,652,411,568,218,251,341,811,381,147,229,474,960,743,418,186,688,244,641,238,336,712,922,134,118,892,23,387,447,73,256,241,316,406,759,429,16,262,80,804,797,747,27,632,424,477,879,786,216,465,721,888,239,435,273,802,726,826,841,44,507,284,731,498,135,530,67,220,485,238,949,631,375,220,654,782,740,211,290,616,236,244,668,867,999,491,685,631,899,250,543,574,190,779,905,754,177,707,812,792,471,976,338,607,710,91,637,744,339,292,69,467,40,853,764,546,239,800,132,733,17,691,222,621,801,413,425,654,25,557,918,611,41,100,125,365,964,961,791,785,678,386,339,353,445,182,964,281,885,601,291,217,284,469,289,41,73,651,90,534,900,270,473,837,772,179,811,155,184,988", "778,956,28,301,287,834,224,226,916,902,56,355,669,523,665,665,392,389,25,820,684,357,315,247,593,995,997,557,834,967,106,248,562,865,830,759,127,337,420,79,149,403,602,433,983,338,170,248,84,922,587,836,377,139,879,190,515,264,740,263,216,837,263,754,950,152,788,288,408,256,638,435,834,321,569,549,250,302,458,692,599,424,507,643,653,271,489,47,334,287,524,716,89,110,71,197,461,838,660,289,394,573,872,703,757,284,615,383,139,368,262,275,581,988,897,686,175,284,442,193,400,261,796,961,880,966,114,568,721,823,262,873,589,11,519,703,590,902,790,456,79,289,504,10,422,78,812,978,457,497,498,888,666,3,530,148,33,577,26,731,271,500,959,907,560,938,524,260,887,18,740,418,376,434,2,512,635,208,439,155,432,201,741,897,504,204,484,212,395,18,668,577,754,352,57,768,380,860,466,908,884,146,492,879,537,777,477,825,103,749,745,353,19,124,321,175,318,263,780,910,605,888,120,627,743,165,91,770,574,181,711,38,831,138,924,511,244,16,632,845,61,416,969,417,168,709,559,975,37,681,344,575,401,258,957,204,5,773,198,790,907,228,495,683,477,798,667,36,88,523,702,110,962,140,498,164,237,433,726,972,436,280,513,153,875,117,727,702,492,674,582,958,259,776,702,66,580,834,998,869,103,765,999,535,519,641,329,464,391,272,937,119,805,896,513,788,514,480,714,194,784,65,562,370,254,269,8,771,566,176,726,938,951,134,754,852,940,705,614,898,593,933,474,828,496,260,39,464,499,237,272,40,316,329,422,3,606,224,645,862,170,781,168,961,911,435,597,549,167,965,299,55,817,550,243,201,747,229,646,22,931,53,269,942,620,688,334,210,411,693,845,262,443,872,592,681,544,131,726,977,127,385,962,233,259,829,598,385,12,850,10,338,108,702,451,315,102,792,710,971,740,535,447,409,648,448,233,213,771,379,348,132,966,65,832,284,371,935,993,430,488,694,502,665,519,230,897,215,561,438,461,241,202,164,174,473,567,575,257,597,458,693,195,928,518,234,222,159,929,288,13,376,616,902,445,102,251,109,785,847,511,967,904,385,743,721,650,165,424,869,14,498,501,234,707,243,55,399,801,732,499,724,610,142,460,610,390,470,848,606,801,945,312,107,975,731,659,955,55,307,996,61,561,57,717,698,708,226,515,986,462,968,180,687,445,608,244,987,248,441,435,285,555,634,952,176,568,281,155,714,85,108,482,24,422,589,388,624,437,554,502,268,953,281,527,354,240,488,84,989,990,707,898,710,770,348,377,796,319,29,177,369,814,915,161,216,694,947,283,280,862,516,561,425,943,211,839,896,355,655,524,261,360,919,799,126,942,586,82,775,954,884,251,682,998,628,112,882,0,183,204,572,358,838,779,128,330,387,560,979,853,595,201,598,672,65,721,38,771,338,699,586,413,770,162,638,13,191,417,161,520,432,525,407,84,806,209,93,748,825,571,767,875,611,769,550,598,940,803,74,317,812,961,405,401,922,790,543,568,641,22,100,98,67,48,194,636,800,932,473,420,714,976,477,749,651,671,185,606,210,494,453,191,290,115,468,322,528,407,793,939,730,92,274,564,622,451,870,501,819,42,391,454,41,304,189,123,395,329,887,258,754,975,541,102,15,150,672,781,821,738,607,387,348,691,900,530,225,350,756,303,870,768,28,405,210,203,430,477,837,625,889,781,491,287,816,754,70,258,376,682,916,574,14,793,652,849,181,935,192,616,444,759,633,875,281,252,807,351,125,732,552,442,616,805,311,699,13,746,644,650,725,334,976,538,454,947,763,256,534,716,415,373,414,245,171,677,272,966,927,28,974,362,63,86,276,340,392,970,796,861,567,74,392,302,579,584,511,444,49,309,313,854,933,488,19,427,631,389,906,456,82,139,362,615,997,99,777,208,634,240,825,860,19,326,927,497,637,936,255,786,35,377,195,383,284,754,297,779,77,783,865,337,593,271,354,855,835,983,608,505,781,495,194,990,930,486,205,745,628,724,577,875,99,989,535,527,367,304,897,370,187,416,993,678,460,312,810,171,214,993,10,79,21,700,114,945,29,745,909,235,731,873,983,980,147,292,423,956,961,470,369,721,242,327,981,729,970,481,809,505,321,43,473,502,107,263,571,567,213,386,974,134,615,503,840,690,580,584,610,958,31,268,319,361,461,961,259,896,578,702,407,98,265,965,475,128,80,150,84,427,939,540,752,703,245,326,843,173,46", "983,210,318,895,178,181,468,983,513,899,960,771,256,243,632,70,231,619,147,502,190,456,927,728,978,869,940,383,826,416,564,585,899,315,552,372,465,530,153,208,750,710,21,446,896,804,794,3,407,996,357,31,647,178,192,747,203,399,566,536,166,654,501,713,580,127,634,986,561,571,552,692,579,824,862,183,695,543,21,783,410,12,54,522,338,965,919,672,813,408,497,559,814,641,954,161,732,940,659,642,448,465,100,412,248,758,920,117,377,507,322,503,95,541,248,884,299,446,629,619,556,453,631,109,213,263,361,436,459,253,170,723,118,342,802,4,423,25,677,518,275,20,923,769,152,83,595,414,36,305,262,621,915,680,445,769,920,9,715,744,288,739,963,93,817,29,328,355,580,334,901,406,23,59,468,979,877,401,435,613,680,475,995,508,793,73,397,657,153,341,740,65,493,189,325,69,610,894,414,413,319,219,80,537,774,663,392,23,330,48,248,6,260,343,859,89,24,507,691,247,619,269,987,677,979,463,461,830,797,308,859,796,627,611,779,615,704,788,247,486,797,354,120,710,957,878,221,523,87,667,726,554,88,231,216,368,9,853,526,394,234,193,343,405,425,938,284,909,392,858,178,284,673,557,283,190,37,879,35,755,245,790,805,625,638,128,342,424,941,924,133,131,814,466,232,260,58,33,764,481,297,661,911,426,965,591,950,472,232,413,891,637,893,556,690,425,200,508,194,625,319,954,945,369,727,877,826,956,403,37,688,252,485,408,227,622,630,372,881,256,612,343,485,714,533,577,379,704,118,169,896,738,482,563,602,613,284,635,251,424,631,372,781,472,554,508,122,52,929,857,239,290,684,969,82,921,29,265,53,907,637,793,186,661,612,31,424,311,797,761,606,532,215,603,469,359,959,467,142,771,746,860,284,369,850,245,924,946,390,797,538,274,652,879,87,239,287,454,836,427,125,54,264,895,23,23,914,732,32,394,554,59,311,430,16,755,196,620,97,35,660,647,866,297,359,925,446,160,471,785,112,901,438,104,537,622,900,256,118,175,813,711,609,64,344,100,178,952,339,375,862,490,446,833,455,63,353,856,521,369,520,785,983,874,112,550,691,847,188,265,501,992,692,472,241,44,417,21,204,934,604,530,523,90,873,680,911,409,711,206,616,107,983,754,555,798,898,291,958,973,385,878,154,597,527,922,693,864,861,241,447,400,742,518,351,289,273,28,230,493,955,655,965,396,745,297,268,898,454,564,352,157,133,429,422,955,121,301,356,288,697,141,889,826,314,735,470,635,331,909,183,984,227,40,657,541,896,576,20,586,250,679,577,570,98,346,933,386,621,906,294,551,579,915,291,474,204,311,815,977,691,366,148,868,521,332,301,244,199,874,131,574,26,515,346,614,803,202,183,0,1000,927,187,639,416,761,795,317,894,32,79,640,896,461,90,309,768,631,59,598,817,643,215,18,98,509,546,504,98,28,137,83,323,321,51,310,724,86,255,334,534,338,52,512,748,499,608,164,357,382,552,438,770,834,299,991,795,72,932,532,372,446,475,139,619,653,659,362,362,303,824,237,305,989,371,739,355,583,47,815,105,700,755,709,577,973,766,975,654,457,180,962,460,15,615,576,771,296,977,187,179,925,339,65,756,263,702,919,704,275,110,821,102,473,158,292,368,767,287,847,370,102,918,830,870,645,797,853,798,569,569,614,760,937,51,560,648,162,811,590,562,782,454,704,441,670,16,899,612,607,745,280,747,499,823,481,902,679,233,196,622,326,340,747,551,131,147,826,108,7,656,870,652,902,591,582,837,291,712,628,817,672,621,224,262,815,908,607,764,977,938,953,169,881,886,247,968,327,644,639,720,443,429,831,907,49,411,460,931,455,874,398,82,142,908,5,119,615,213,621,924,271,887,143,883,655,730,15,698,254,584,81,54,736,932,255,587,140,103,279,304,807,201,766,655,199,4,680,72,585,234,975,961,89,12,880,601,936,244,475,297,672,475,918,230,252,267,774,402,47,509,302,174,515,655,408,21,580,930,81,471,451,811,532,514,245,573,614,683,60,992,117,830,721,252,762,182,164,790,49,737,595,924,555,791,492,671,681,352,423,897,653,911,847,680,831,405,44,989,487,84,563,131,223,50,145,180,730,282,977,462,194,522,37,128,166,704,807,692,698,323,670,219,839,34,795,698,743,7,987,721,529,914,236,383,947,890,495,248,634,99,370,680,387,598,386,859,774,87,32,351,657,695,963,134,119,750,795,858,266", "201,290,326,295,803,348,914,481,758,116,330,275,318,382,771,843,512,125,349,594,688,121,325,420,655,166,369,979,660,386,221,895,117,861,875,58,705,748,405,236,874,210,748,285,684,908,808,870,338,430,563,976,305,868,321,558,948,806,704,652,194,588,688,989,692,870,77,40,874,7,289,619,524,67,690,738,780,211,578,550,176,555,69,9,412,467,675,709,346,260,970,936,110,727,855,926,293,66,274,108,32,334,749,27,813,242,918,73,494,860,885,348,613,164,290,924,15,441,327,592,982,531,627,865,946,263,499,886,8,716,23,208,217,83,268,864,282,617,523,718,341,522,80,434,614,96,56,776,439,493,303,954,699,400,165,574,680,254,93,48,174,875,727,930,515,942,757,55,263,623,330,186,803,815,366,603,9,240,224,432,758,745,834,471,938,902,515,96,162,206,925,926,982,903,627,227,628,611,731,722,943,360,466,880,365,660,414,118,839,517,962,703,999,364,922,491,417,949,759,983,775,434,955,67,779,893,808,214,393,511,329,427,164,45,744,259,641,415,593,927,865,147,936,729,734,31,425,720,373,391,781,483,231,642,12,261,405,429,959,796,889,428,654,294,545,863,368,645,996,885,260,56,990,936,721,949,187,287,989,74,464,567,279,808,549,188,692,596,297,140,813,336,1,993,746,697,362,874,757,771,816,832,79,302,337,45,20,129,550,834,745,494,908,30,435,405,406,84,589,319,931,114,938,101,13,811,28,596,844,588,675,695,778,106,316,595,565,358,418,518,31,43,794,851,468,420,788,372,74,607,232,103,513,657,126,973,63,641,393,105,237,895,224,173,995,829,742,880,458,632,904,578,807,515,938,861,851,695,983,203,592,82,166,401,98,700,273,476,208,706,775,777,273,419,519,660,36,218,695,441,837,561,927,902,974,883,278,957,364,962,53,917,827,231,628,569,836,342,981,20,247,423,882,426,119,771,352,843,104,166,363,275,123,411,550,803,158,457,506,675,278,975,713,818,254,591,986,399,433,113,733,308,757,780,514,520,665,588,958,557,161,391,953,872,530,104,488,350,112,228,344,906,76,176,152,189,887,229,664,417,463,1,442,328,764,235,377,164,341,192,896,399,388,423,945,127,55,685,499,930,182,487,467,376,452,958,961,693,521,273,42,886,823,472,283,388,525,421,980,608,934,890,209,185,776,659,449,6,671,202,220,100,331,455,73,631,52,54,545,432,430,685,172,465,34,415,220,942,110,527,679,576,774,184,732,325,39,887,513,174,77,62,981,108,235,364,254,365,281,757,321,193,405,637,299,116,847,435,403,472,617,519,690,280,215,138,586,459,749,833,623,205,396,874,255,205,546,988,512,110,758,237,72,66,455,86,169,225,385,137,365,720,747,979,662,786,200,252,204,1000,0,442,742,866,407,951,589,720,73,402,840,746,965,787,444,615,276,212,436,153,730,95,770,644,442,322,172,892,623,797,296,313,195,907,284,113,70,446,129,679,801,480,524,709,588,789,108,996,740,793,896,539,397,271,661,844,697,70,135,410,548,607,236,223,405,609,8,590,592,861,859,623,718,800,949,169,781,128,846,696,688,360,899,257,237,676,497,486,362,744,828,484,757,562,407,675,599,597,818,598,139,104,71,664,770,970,612,390,335,342,663,664,893,585,159,655,890,60,921,979,286,258,729,389,150,612,218,419,840,387,247,560,114,645,36,626,44,536,447,269,415,864,695,387,259,794,618,134,936,499,543,877,986,812,574,668,657,530,590,184,152,174,93,730,390,700,962,972,831,583,752,590,627,476,330,599,737,706,510,54,17,62,658,999,507,809,380,627,728,943,127,659,582,61,4,797,397,380,282,124,83,38,873,371,501,141,697,421,122,837,491,259,563,184,799,923,453,209,821,771,328,607,320,985,418,641,201,327,652,821,25,660,35,889,264,921,985,791,809,888,371,96,713,739,652,645,710,970,28,618,324,898,790,38,232,886,914,219,313,265,918,107,577,85,835,931,841,562,283,846,449,29,637,476,108,917,701,505,75,796,91,90,114,125,4,326,491,413,118,896,907,77,303,409,84,287,116,505,809,57,820,146,538,463,798,909,430,328,707,950,814,484,129,666,115,579,59,181,148,338,462,309,552,47,804,602,967,150,321,549,992,130,852,275,802,89,710,414,368,651,117,713,971,679,958,517,941,137,703,860,745,408,542,295,487,876,717,64,248,600,587,876,500,288,360,911,603,637,21,975,986,987,494,910,266,234,586,640,438,53", "195,117,928,810,153,372,910,672,766,90,228,409,105,144,541,314,340,732,606,278,735,222,8,15,245,604,351,105,621,742,915,238,354,456,947,511,152,737,540,6,412,206,25,405,670,510,328,598,789,999,830,443,405,306,466,285,105,112,71,867,889,721,129,144,330,33,314,717,482,979,253,840,949,350,862,159,539,904,953,525,804,355,772,663,624,509,493,654,588,986,823,64,542,640,693,50,775,597,859,462,883,902,681,480,67,468,929,462,781,783,5,483,34,401,474,422,165,966,268,342,499,572,60,569,578,139,64,958,413,519,26,712,181,753,563,192,964,44,622,694,632,487,272,813,714,377,952,467,231,487,126,254,430,196,589,491,270,424,804,378,484,599,201,984,861,337,913,637,8,632,165,211,636,708,626,674,384,716,574,200,886,678,360,359,797,439,633,127,82,710,224,451,389,343,343,940,457,322,712,52,604,647,858,933,635,268,884,660,849,105,209,485,899,463,894,477,458,572,109,330,641,52,699,599,2,266,518,303,697,369,954,858,91,840,191,615,277,960,24,129,870,711,765,893,166,119,455,274,925,491,6,465,864,658,189,121,749,575,808,515,547,54,745,894,78,403,819,843,196,719,478,896,899,651,187,537,786,394,344,134,702,936,814,385,144,637,949,27,282,54,290,638,517,564,478,124,885,536,112,39,231,258,669,599,376,522,789,573,291,31,600,945,430,540,454,640,114,801,714,706,512,998,268,243,65,676,86,891,664,223,537,255,341,403,161,458,861,916,340,597,915,923,462,873,93,628,969,343,788,935,832,679,10,541,717,138,527,613,600,347,306,507,245,135,238,178,877,9,828,185,766,762,999,153,868,244,858,693,784,853,896,675,122,907,394,326,417,764,891,848,340,131,773,622,44,252,20,186,942,384,574,240,909,885,753,907,298,200,958,681,514,334,930,996,446,57,322,426,318,998,158,784,847,977,207,754,215,751,681,682,436,445,121,30,255,924,353,322,78,734,660,226,639,663,729,970,52,415,95,290,205,835,21,232,157,574,275,428,870,477,206,254,485,510,839,102,860,856,7,582,939,228,922,727,609,629,240,314,773,913,460,135,864,422,993,178,563,834,842,116,841,787,304,849,331,410,990,933,836,284,211,497,4,944,124,404,181,588,684,22,143,722,583,105,531,694,3,790,453,218,9,266,33,350,516,892,577,946,750,465,348,210,928,124,280,558,854,366,119,678,838,335,702,886,421,5,35,25,379,343,73,925,747,892,328,806,763,945,574,64,600,110,41,319,50,942,160,14,572,338,444,346,870,334,934,545,281,241,106,425,724,707,652,100,825,375,478,889,306,286,397,359,875,100,299,115,277,91,718,639,697,513,92,990,753,805,563,470,101,145,643,604,169,262,837,966,634,271,572,927,442,0,296,184,539,399,502,87,218,691,419,441,297,527,122,442,937,847,623,807,437,746,184,440,458,318,856,100,321,141,520,861,62,319,173,653,498,537,911,709,860,686,319,895,645,892,349,554,549,916,944,471,123,372,894,362,357,241,660,38,827,399,810,268,434,858,790,500,275,762,14,831,73,873,73,413,699,528,559,127,924,550,496,419,773,582,571,994,907,185,294,664,419,30,30,307,608,938,679,409,450,229,278,396,739,368,125,222,707,747,158,985,467,641,144,56,221,522,591,831,459,917,750,329,678,375,801,330,154,669,374,79,993,240,834,355,844,911,771,315,833,869,316,566,43,105,488,853,365,688,627,571,866,967,261,709,307,391,509,311,167,691,562,627,126,73,588,357,115,175,491,691,434,417,71,909,353,244,299,144,719,391,199,386,877,503,797,363,29,472,114,537,368,459,40,573,136,254,716,815,426,304,645,163,311,155,396,623,915,463,250,538,539,514,147,171,739,993,350,763,918,665,728,688,488,75,620,436,533,628,963,667,268,416,973,585,659,504,937,744,392,311,325,493,638,120,832,908,980,408,671,720,827,809,68,330,733,822,919,795,897,510,116,471,43,396,857,200,818,624,541,114,811,117,106,363,436,951,200,619,55,738,862,627,421,386,521,948,395,160,90,970,9,205,828,725,790,402,331,73,58,384,601,931,146,402,140,85,353,779,265,974,603,472,932,530,2,195,219,731,69,996,914,49,651,400,127,619,605,327,202,864,751,297,715,307,201,14,734,479,591,377,138,223,890,503,445,17,363,36,952,61,780,818,127,702,124,966,350,24,596,257,215,530,441,363,651,315,792,211,763,290,541,238,757,877,888,530,703,461", "905,878,330,239,696,213,885,120,894,543,556,723,214,975,746,103,132,902,865,793,517,964,209,594,919,662,655,522,577,801,760,743,626,816,272,302,511,44,266,811,967,182,410,898,559,710,691,727,269,737,500,425,450,909,532,70,290,285,923,231,610,248,980,247,325,783,107,367,609,822,88,77,271,79,307,412,603,256,55,277,656,414,281,858,844,371,886,99,154,879,109,798,773,8,549,653,247,128,590,83,783,44,780,51,835,991,962,36,995,681,75,303,458,170,177,793,582,557,509,451,303,110,392,979,343,930,541,60,372,178,302,274,187,191,304,361,725,137,385,924,169,285,501,207,362,643,909,661,897,255,971,188,38,888,762,378,28,421,555,3,857,867,104,892,12,441,938,710,328,837,692,97,695,210,903,860,584,5,880,703,385,688,911,736,298,955,857,865,830,356,480,782,792,286,798,131,487,929,224,576,217,957,719,977,933,887,186,727,365,917,184,416,559,729,817,615,690,721,336,54,588,616,618,303,759,636,291,970,175,581,545,767,145,853,974,440,986,829,785,667,178,550,652,773,719,472,993,34,152,355,62,484,340,356,324,9,831,291,342,957,962,678,763,117,814,17,311,398,336,933,669,543,834,817,585,225,207,355,720,519,407,968,788,473,816,272,190,319,157,829,669,26,716,969,422,820,902,857,886,109,594,2,155,96,968,145,154,48,867,67,147,425,325,143,865,333,731,124,311,481,206,120,132,153,521,821,898,127,809,658,154,278,598,201,749,593,246,101,448,563,937,177,416,246,559,958,437,902,686,372,65,295,780,886,743,71,966,19,423,697,845,704,969,226,389,908,2,302,665,942,103,280,574,223,513,715,519,621,945,312,573,338,710,60,611,348,429,579,583,949,126,697,399,846,580,577,756,792,678,736,372,258,407,677,182,254,620,501,917,586,110,173,941,388,735,988,245,754,908,639,350,781,931,725,945,526,588,244,663,374,750,208,562,968,403,696,81,98,844,691,291,137,465,323,962,237,853,503,93,984,758,960,443,840,690,712,191,649,216,727,148,118,926,816,311,388,895,694,155,787,161,557,98,444,413,100,745,334,116,635,716,438,713,658,92,809,723,936,221,626,903,270,727,711,427,212,737,200,879,421,456,701,794,471,464,47,141,995,505,275,456,486,566,783,733,284,999,789,580,119,305,390,891,571,330,511,974,873,136,168,625,616,845,981,812,416,156,455,230,801,663,237,932,38,992,142,999,316,941,456,804,713,480,586,324,432,93,46,836,522,865,417,830,916,724,421,926,747,677,491,38,424,811,86,170,457,31,226,849,368,95,552,90,16,817,700,630,928,509,538,155,912,957,251,314,393,557,685,790,724,303,918,363,11,304,778,190,82,280,708,511,150,982,677,39,920,816,767,358,187,742,296,0,825,856,142,334,333,459,733,391,855,190,54,400,834,956,517,653,452,508,417,853,948,563,49,782,529,594,976,311,520,924,57,39,512,957,502,246,608,164,360,872,734,221,283,491,420,415,206,836,578,952,348,868,624,168,872,492,415,518,13,963,624,455,9,529,481,991,482,216,268,281,210,563,569,703,422,396,67,940,377,886,73,306,90,860,300,150,217,199,641,414,129,409,968,840,785,618,826,79,760,667,22,425,629,95,122,436,159,602,404,83,277,651,23,640,144,788,360,598,293,858,344,430,725,943,102,146,180,861,480,93,398,681,692,830,604,701,27,436,533,257,214,603,626,730,819,677,757,288,802,62,703,428,553,627,501,890,933,798,125,533,948,271,167,208,897,659,358,135,481,864,29,333,225,974,180,998,511,100,257,488,402,405,197,721,367,367,298,197,794,773,36,449,99,323,401,413,549,348,147,589,676,37,241,720,456,203,358,439,193,222,715,882,536,583,947,62,482,351,386,40,176,301,228,979,890,578,696,714,636,634,87,411,188,230,655,639,455,412,700,152,823,36,843,160,780,139,484,232,50,870,166,211,843,235,950,883,840,194,420,330,353,728,608,921,334,350,421,396,579,158,512,783,583,293,139,931,238,512,208,654,400,22,315,555,787,336,222,109,821,500,296,335,807,738,636,737,846,795,381,617,236,87,604,331,27,681,465,265,445,100,237,865,761,804,731,838,718,96,346,828,774,660,706,110,350,559,44,306,103,419,326,215,724,903,123,781,581,761,486,458,774,588,986,638,13,214,584,154,149,609,496,337,416,74,961,405,189,445,423,954,317,718,318,13,591,725,781,941,324,107,923,129,803,830,271,798,829", "670,725,987,528,80,48,11,18,541,821,994,183,174,109,729,308,703,704,835,702,850,431,346,457,338,483,8,814,39,307,635,590,4,577,329,895,758,812,643,282,200,140,306,257,375,190,889,325,830,827,928,846,644,982,652,76,787,582,852,120,899,801,990,34,83,237,231,258,791,250,606,36,97,267,895,944,978,880,811,605,445,566,346,477,456,923,886,822,562,336,350,117,145,409,561,23,958,955,463,272,943,836,653,157,216,427,986,806,518,852,261,591,101,106,691,851,959,348,192,579,199,546,666,989,502,200,618,268,292,180,821,886,257,737,127,679,3,435,800,301,753,711,614,153,634,536,292,788,793,450,799,603,965,428,776,600,488,345,784,532,934,5,665,994,779,346,804,402,295,562,149,670,917,417,967,198,768,300,623,904,517,138,242,660,475,285,339,763,879,605,704,303,175,953,16,744,542,69,156,354,412,754,784,402,930,116,650,600,702,29,563,42,778,752,909,19,390,52,120,308,511,26,806,346,852,236,25,720,72,888,904,88,642,326,199,528,300,486,824,240,61,903,147,151,951,600,841,770,746,884,699,819,519,57,588,472,373,902,452,447,858,246,384,987,652,654,965,221,632,747,678,834,998,199,324,919,359,973,466,345,416,81,375,247,883,942,346,909,508,31,563,408,94,927,10,962,656,818,680,239,597,177,216,747,397,570,496,737,393,110,457,382,125,940,118,636,470,991,299,664,630,617,251,593,697,687,576,899,877,598,470,73,882,266,288,769,901,711,343,342,119,198,652,619,222,473,224,873,794,628,705,725,282,192,88,331,80,461,26,469,284,504,185,25,155,402,427,737,282,438,602,333,956,83,667,406,90,370,690,886,25,308,603,34,244,212,327,279,109,208,789,43,455,562,441,415,473,315,973,639,773,553,214,878,421,170,871,856,224,591,416,320,42,752,944,718,592,932,3,934,199,879,338,83,466,730,304,75,875,918,279,455,676,429,4,493,833,636,521,514,794,273,66,799,250,896,810,327,475,793,128,88,286,209,51,136,30,203,251,209,965,189,880,976,702,258,948,464,423,433,527,218,401,797,427,128,69,858,338,259,433,822,377,197,841,904,832,454,810,494,831,293,199,962,235,204,431,914,36,663,22,718,245,402,79,309,254,62,375,465,707,925,492,715,252,8,188,426,200,357,571,931,846,636,975,204,731,711,161,431,14,957,426,8,573,505,667,96,35,205,86,534,247,218,197,226,539,686,545,206,358,31,442,439,843,829,629,841,480,271,110,831,728,211,692,995,703,427,194,466,225,409,533,399,931,664,981,978,893,640,947,586,976,664,848,624,91,400,535,273,103,409,728,952,960,530,564,70,852,665,276,466,988,52,835,813,470,334,401,466,327,158,901,509,327,593,822,733,838,639,866,184,825,0,775,785,386,707,247,740,662,709,622,518,93,819,356,472,993,516,706,967,131,720,710,898,851,65,810,974,797,739,517,367,477,93,448,172,686,852,99,653,269,570,166,721,939,764,8,351,18,749,809,441,253,406,184,957,287,650,475,626,766,249,508,866,778,699,625,609,449,890,878,576,700,615,784,996,408,83,727,111,593,36,253,198,196,291,279,111,729,987,734,482,53,171,591,310,55,56,320,974,814,319,281,661,979,448,691,839,698,114,273,124,951,627,76,253,77,165,474,679,871,295,687,108,367,888,288,636,308,731,293,337,949,274,983,682,38,711,769,600,900,171,733,739,166,317,980,219,84,119,676,67,115,894,664,257,323,370,277,256,867,386,289,415,653,410,322,914,181,768,231,674,834,104,398,692,844,386,161,49,798,618,739,548,332,137,614,864,868,611,720,927,76,550,136,619,280,307,9,225,759,340,304,347,159,362,874,563,702,507,629,435,180,461,51,362,151,691,217,436,782,990,212,390,520,769,848,987,403,671,612,391,722,970,43,328,98,996,242,778,166,144,143,197,411,31,168,300,928,291,648,809,731,683,743,614,306,289,176,382,149,72,991,272,842,681,224,802,227,547,668,978,890,215,742,257,142,840,587,890,11,255,826,333,844,644,900,119,221,924,549,58,32,983,24,755,139,478,953,616,676,931,431,829,81,193,725,806,375,425,563,885,335,483,574,483,649,381,912,748,326,171,644,99,90,933,839,998,961,878,885,443,161,197,242,647,550,922,857,382,539,839,616,120,837,822,81,345,780,776,75,475,648,867,110,426,907,918,966,624,651,281,151,597,182,820,982,879,27,488,137,31,427,994,152,96,777,892", "313,758,173,531,791,903,85,750,793,211,211,481,381,919,590,67,350,344,885,357,457,503,848,678,270,416,21,551,283,936,35,822,898,934,571,104,395,65,486,893,797,422,600,846,156,16,775,353,30,866,18,306,171,633,822,658,741,881,305,658,799,571,824,673,461,822,601,14,27,190,137,376,278,145,401,590,702,881,894,825,157,959,685,397,670,690,173,721,720,157,967,63,318,572,608,46,277,218,808,140,103,238,670,900,572,191,67,881,499,460,146,503,219,769,51,590,567,656,73,496,548,932,364,347,538,21,409,304,90,325,142,67,966,282,776,951,896,367,949,98,589,323,277,685,597,755,613,902,968,569,31,555,499,626,70,240,634,920,741,613,251,457,758,902,630,692,948,626,885,35,950,492,912,783,47,204,355,739,970,335,371,771,843,923,309,294,592,631,84,198,913,290,158,364,290,511,10,426,975,894,294,906,639,284,771,691,98,242,502,403,82,219,299,631,930,349,660,479,722,124,421,282,725,899,747,296,170,506,949,94,596,870,173,212,634,268,481,979,746,378,671,788,75,959,896,238,601,824,372,711,977,806,642,444,560,450,607,787,212,642,984,737,262,202,932,875,581,743,511,398,211,626,584,726,512,932,379,96,110,792,953,609,324,538,9,546,303,993,574,902,881,380,828,682,589,621,740,728,165,159,456,156,313,109,565,306,310,352,159,541,675,940,259,357,371,348,906,699,688,273,706,777,194,842,114,661,657,576,651,747,905,342,985,60,65,197,429,641,264,805,331,884,805,598,753,800,235,536,172,795,905,327,784,837,767,921,525,48,958,934,319,864,342,300,336,912,51,895,167,66,51,240,845,161,54,97,124,955,103,750,888,674,8,372,686,195,330,617,297,971,833,662,741,303,35,364,739,992,278,607,28,168,520,627,267,482,867,23,333,314,618,281,111,913,409,881,652,15,735,515,560,737,132,92,623,398,406,777,86,411,248,300,131,636,81,179,740,798,530,33,936,157,436,206,631,745,937,198,694,341,484,731,237,6,992,141,235,444,601,558,972,405,396,602,528,291,619,238,789,30,856,893,727,803,561,688,637,612,206,762,33,458,556,144,776,355,269,428,256,504,537,772,360,908,46,170,415,745,419,629,974,278,398,466,230,267,263,215,616,475,858,892,377,972,82,618,94,852,953,450,921,927,588,840,715,231,963,603,969,737,348,750,817,382,9,420,801,822,542,875,469,172,205,594,767,940,361,591,652,181,3,742,596,277,506,567,992,808,217,221,87,732,741,536,968,281,825,61,459,538,508,479,456,147,375,994,612,194,715,919,170,552,839,663,512,865,536,615,412,432,472,691,993,961,602,674,912,791,130,761,545,376,708,343,986,135,415,136,423,89,720,813,442,741,855,145,552,778,779,416,407,539,856,775,0,288,160,61,486,996,929,475,663,351,944,819,351,285,848,704,708,959,743,736,845,490,48,908,65,369,121,720,317,242,262,302,498,623,554,837,880,915,679,36,631,971,403,856,603,42,81,579,969,833,322,879,626,291,654,422,278,623,630,420,999,300,729,932,763,599,972,790,247,752,662,617,296,395,989,157,868,138,681,816,595,645,254,67,102,82,122,952,858,504,706,264,671,952,228,360,331,945,579,151,906,667,177,525,241,912,829,544,646,238,616,523,221,771,467,84,46,411,954,460,206,366,706,887,206,299,416,143,346,265,251,636,418,382,24,678,373,576,491,469,75,287,701,312,126,243,117,892,939,668,638,118,565,864,37,447,461,265,438,975,790,688,610,772,457,635,143,339,624,799,838,595,258,248,514,63,105,379,421,11,967,658,925,646,191,219,646,354,150,628,698,854,156,733,276,197,304,334,493,327,427,320,848,835,30,879,197,106,722,120,746,758,199,549,558,788,752,5,342,951,234,261,282,717,176,897,137,137,752,446,477,948,340,807,288,637,405,500,935,436,352,499,78,794,941,63,92,520,418,59,679,146,761,762,918,994,519,772,311,286,709,322,414,635,735,810,189,699,355,371,883,202,985,573,999,390,691,437,64,516,858,289,7,496,864,375,752,505,738,932,123,156,709,872,849,55,975,319,261,408,392,694,905,196,244,136,915,530,901,860,258,824,357,19,249,91,66,450,664,742,231,187,807,11,754,545,76,796,806,758,131,219,30,208,638,844,244,626,850,835,181,663,959,891,805,405,996,131,454,573,782,963,182,518,372,935,364,656,432,124,159,165,711,148,900,532,127,142,761,730,325,881,592,513,667,761", "555,453,553,733,526,74,168,538,542,649,800,579,730,467,757,913,254,935,158,689,879,518,301,445,997,198,981,699,439,49,148,394,109,703,169,814,360,849,612,427,824,626,419,776,986,581,781,153,755,986,765,47,322,266,265,711,489,460,397,333,735,258,564,277,66,678,479,711,618,66,776,517,676,975,985,500,180,999,777,486,939,617,754,360,70,751,33,527,935,754,490,199,541,797,93,155,157,866,439,145,863,255,734,475,801,378,13,968,475,244,411,912,291,470,744,209,492,655,312,508,645,497,862,987,578,339,159,560,180,388,792,962,693,36,336,697,94,957,21,686,26,401,341,949,651,462,453,774,894,874,902,903,284,26,744,911,892,794,957,86,469,413,985,649,889,445,216,231,767,473,991,987,612,733,69,645,933,754,75,577,401,37,540,354,762,372,957,80,473,705,874,944,225,194,108,857,107,230,941,776,798,99,818,368,626,475,155,937,617,900,268,532,902,364,462,964,804,382,192,415,298,461,376,190,602,531,348,918,538,195,869,668,917,323,58,129,192,387,169,909,100,538,936,600,819,869,705,3,525,240,352,647,651,909,159,914,96,553,474,89,151,597,644,573,908,569,168,965,613,469,79,802,186,97,470,194,129,374,355,372,319,155,34,998,928,313,500,258,652,589,891,344,986,293,385,60,921,359,65,30,232,753,478,125,621,280,471,876,292,854,926,635,400,79,262,889,326,660,770,35,148,655,940,351,736,826,904,690,441,94,603,729,287,255,112,101,786,180,728,392,525,705,705,363,968,317,902,77,974,89,279,206,668,518,318,240,281,275,785,440,737,129,940,485,59,351,710,8,284,32,786,516,473,528,126,776,82,6,566,883,271,92,326,903,240,853,540,224,483,705,708,341,748,335,486,54,176,873,946,904,248,688,848,784,782,861,225,749,642,879,560,360,910,740,751,868,903,985,567,256,396,454,865,430,983,423,206,729,684,422,162,924,669,661,914,31,941,6,381,667,602,615,593,154,466,641,189,198,172,988,540,219,935,889,367,320,728,548,251,954,432,587,496,875,407,123,372,745,366,795,244,402,115,844,86,27,311,504,676,858,952,197,818,873,158,830,413,47,348,104,343,133,724,484,500,55,771,124,536,635,307,151,537,887,969,318,148,129,778,810,285,312,751,193,443,973,237,583,5,828,826,321,360,393,591,454,347,724,275,625,364,989,599,807,652,56,78,38,527,809,292,878,468,449,69,273,392,271,712,469,937,797,694,360,263,204,448,397,872,752,584,746,375,423,855,3,122,106,715,53,191,522,936,54,842,859,603,708,322,817,824,896,427,241,252,464,260,441,129,316,857,425,187,797,142,796,259,906,386,342,193,103,591,906,569,494,41,990,621,910,905,69,903,916,765,605,957,793,128,761,951,399,142,785,288,0,245,635,906,580,678,689,467,261,548,946,914,243,966,474,36,54,464,659,23,924,393,434,336,163,107,40,135,737,974,733,935,143,192,102,925,147,192,665,906,52,851,785,613,182,853,996,334,172,386,243,137,846,769,793,851,999,889,754,375,737,210,267,620,118,958,641,456,894,271,269,438,963,458,68,457,88,252,270,779,494,531,822,183,427,21,39,142,49,421,782,658,976,208,831,410,714,811,754,544,812,441,422,306,134,139,120,102,941,329,911,943,4,724,543,925,247,159,174,782,343,295,254,276,680,231,770,801,396,977,874,496,384,551,180,475,72,383,301,477,373,972,31,188,734,995,200,273,481,781,446,539,273,811,478,858,240,434,952,464,261,30,990,578,906,80,32,241,599,717,363,949,953,503,530,106,712,432,792,129,215,106,195,394,452,478,603,808,671,477,897,388,317,405,568,145,542,906,247,164,766,968,635,782,650,286,706,221,508,844,376,295,984,848,927,650,177,965,821,58,956,36,585,500,835,564,502,12,921,656,17,526,179,24,382,503,443,58,217,945,998,375,868,641,222,630,428,344,642,458,455,52,630,850,323,545,34,781,562,248,720,659,963,452,17,125,372,115,654,829,486,711,579,398,109,843,198,165,26,729,802,88,108,238,814,953,148,965,650,543,664,810,813,770,641,911,550,801,772,804,279,919,392,826,503,944,260,814,945,862,474,84,271,831,23,568,206,365,872,353,79,386,349,627,572,768,564,259,997,587,137,202,540,765,826,761,399,856,957,955,478,319,107,785,557,471,61,312,468,890,760,352,374,916,782,493,472,737,600,884,752,314,379,982,740,858,904,574,615,938,955,949,73,837,428", "762,652,181,988,923,969,3,756,433,562,573,966,542,435,63,96,832,736,895,959,614,651,624,206,186,971,280,979,380,33,672,644,943,220,894,50,437,196,617,297,631,937,919,535,463,804,90,19,875,452,130,406,808,881,840,348,27,208,407,517,506,853,339,386,655,523,872,870,378,484,621,10,645,128,263,323,90,300,563,313,399,788,694,787,179,477,538,548,668,968,224,113,224,791,559,525,20,509,372,433,186,576,303,711,288,668,665,571,195,137,452,384,431,700,643,444,713,251,454,19,887,682,914,451,380,87,990,202,969,33,284,105,46,360,250,247,36,262,508,927,704,914,266,679,778,676,561,887,528,366,575,180,86,613,316,408,351,716,313,229,598,692,838,123,937,590,141,491,453,26,546,879,67,443,917,668,88,233,805,446,853,440,127,355,988,237,607,445,97,795,951,171,528,561,883,209,552,411,511,640,495,311,258,670,514,559,654,735,601,505,455,52,487,47,635,837,463,262,287,251,510,541,293,372,898,772,476,832,332,320,29,347,527,368,58,681,755,955,754,721,755,403,428,809,251,370,276,125,485,970,593,596,229,365,484,151,927,538,859,754,73,812,494,967,963,323,205,609,632,820,82,721,776,672,74,9,192,289,881,583,809,792,420,153,137,757,757,904,524,613,425,938,806,589,615,64,116,878,910,363,512,422,416,812,321,476,688,893,276,964,906,907,620,107,203,231,966,424,135,103,405,878,917,903,163,550,106,955,738,751,811,864,816,644,361,514,860,392,828,5,914,762,751,615,899,618,639,562,566,137,490,836,354,491,441,151,984,521,229,580,950,963,90,200,692,285,207,38,776,984,217,226,498,109,241,919,747,950,895,426,90,768,890,299,47,338,750,365,11,150,481,368,549,56,554,282,811,761,78,740,149,690,756,363,288,749,703,711,814,585,426,160,842,209,371,768,538,973,57,898,391,172,317,76,218,452,274,374,929,789,152,973,826,753,346,767,494,790,901,711,322,159,869,549,70,665,183,983,629,712,267,803,889,708,433,725,413,49,231,347,879,923,526,280,20,592,317,988,491,784,51,918,968,378,410,723,826,529,801,250,865,603,429,306,143,978,918,721,713,213,86,581,209,182,837,409,529,78,185,66,242,709,70,238,774,571,668,815,353,390,647,668,65,77,587,278,914,633,509,673,986,65,136,63,921,682,315,209,185,299,394,435,125,233,570,763,46,720,989,80,164,565,713,190,621,593,414,154,311,574,321,255,933,945,231,601,727,867,290,180,171,253,484,728,602,77,581,160,410,773,246,275,511,919,581,976,898,849,961,820,776,855,851,154,933,830,566,386,639,239,750,396,629,816,518,304,206,130,492,41,707,856,136,600,943,174,940,854,312,425,559,544,442,792,519,238,476,593,330,795,589,502,334,386,160,245,0,124,434,644,493,55,721,44,922,35,948,115,933,107,429,983,600,462,161,644,875,428,678,518,744,74,783,649,356,135,721,356,574,688,557,711,367,567,358,955,973,266,991,737,628,441,143,685,342,436,159,173,41,300,123,401,60,997,429,789,165,329,30,70,301,597,600,329,496,722,17,220,96,261,60,560,625,116,661,202,108,68,940,119,117,72,513,197,382,666,785,891,602,356,533,777,270,920,581,792,321,945,549,546,748,727,902,762,329,329,408,176,680,856,344,421,231,689,232,794,729,927,130,93,20,824,846,651,657,522,675,154,542,103,960,274,155,715,590,336,404,199,111,295,696,367,509,980,872,710,33,545,369,158,545,835,531,886,480,708,891,691,232,11,548,47,825,675,848,38,134,950,885,254,959,397,299,428,803,950,52,381,706,773,677,296,649,753,757,836,791,697,645,642,299,429,615,405,816,524,705,314,512,297,384,985,386,158,93,177,238,895,831,569,7,703,884,863,847,252,801,877,17,120,481,61,569,644,780,156,276,621,934,637,614,444,9,586,17,344,959,207,868,638,94,222,904,985,220,556,530,237,348,685,561,977,423,943,411,217,110,811,453,760,116,430,225,114,175,317,454,345,468,896,680,245,926,300,752,580,901,81,892,530,735,543,802,260,272,923,807,674,932,546,743,568,52,210,670,543,106,120,321,839,251,336,86,797,560,964,278,804,205,656,648,488,547,7,257,750,552,392,291,819,244,430,537,35,956,264,238,659,824,441,861,537,587,276,506,22,198,808,735,37,25,686,272,144,218,920,598,253,71,567,355,701,207,983,633,267,672,796,182,318,559,829,105,407,934,587,144,680,867,478", "962,41,402,941,824,145,38,455,208,588,260,600,115,826,180,326,994,895,453,138,570,699,388,503,719,719,888,252,511,20,95,154,940,63,386,435,39,233,496,309,406,465,445,602,642,747,283,45,828,818,224,589,147,288,681,941,637,405,928,336,482,772,12,415,509,444,478,954,715,191,182,89,246,793,720,867,522,611,264,68,106,695,619,391,805,233,316,766,107,601,378,914,261,995,897,717,761,604,736,164,788,306,354,934,148,955,433,876,473,469,573,12,107,147,943,600,284,242,613,327,655,381,529,955,401,95,37,532,677,915,510,634,484,273,992,553,243,863,748,265,980,390,632,580,148,966,983,854,63,735,43,70,45,674,367,668,443,559,294,140,472,244,617,530,999,832,194,437,949,354,476,373,527,661,120,985,558,202,205,727,152,341,333,779,688,77,92,659,811,648,685,663,419,962,55,308,932,12,758,201,428,990,180,288,871,130,764,117,815,222,291,387,869,942,741,821,156,450,486,855,596,295,344,811,451,377,177,123,675,784,77,417,612,188,503,947,423,823,128,511,321,603,173,737,937,113,690,22,679,995,763,968,48,629,594,717,210,641,133,322,714,982,129,165,811,788,26,283,92,134,41,318,451,883,976,211,262,998,90,571,876,736,865,360,939,656,246,217,822,643,25,319,639,461,773,674,398,630,183,591,612,492,634,495,355,767,303,854,131,998,393,231,570,147,371,733,46,284,230,585,530,274,914,112,645,939,364,974,648,228,376,757,331,67,290,186,713,428,206,422,534,786,506,912,857,262,107,434,478,139,330,619,66,881,590,429,862,218,62,328,882,461,802,649,916,611,687,898,88,107,313,768,26,540,809,477,953,374,185,460,220,636,996,495,895,861,819,198,880,47,561,683,850,760,346,196,97,238,15,230,261,515,924,215,226,889,926,206,234,467,415,905,440,190,650,221,929,481,266,770,696,191,547,867,426,937,397,633,5,492,862,783,266,52,207,371,538,74,588,460,782,695,948,776,340,285,127,407,625,449,971,897,796,271,392,732,936,192,533,232,983,519,247,553,86,688,675,365,435,583,439,657,272,32,326,458,79,12,346,884,241,298,469,889,275,913,874,85,304,760,424,810,875,479,648,631,975,908,892,384,668,660,710,850,478,919,11,940,464,643,613,863,865,970,821,529,963,526,772,7,967,269,877,234,455,781,781,326,172,320,448,312,3,988,352,966,86,652,910,111,431,322,684,985,851,111,355,720,268,587,146,387,389,238,695,558,344,825,582,908,97,135,453,158,323,26,792,180,496,961,608,205,618,240,310,606,630,428,897,513,115,220,707,644,294,104,116,642,703,519,237,520,99,200,218,731,318,981,795,496,37,116,814,758,358,53,875,751,267,685,263,783,122,860,601,173,381,926,387,317,720,87,333,707,61,635,124,0,479,597,404,716,867,870,183,77,932,345,187,818,318,133,842,156,209,509,804,650,2,543,948,528,404,388,70,401,97,91,296,376,191,934,616,873,143,200,831,343,207,625,610,862,250,269,36,980,872,921,360,768,929,459,792,169,315,720,764,562,643,52,818,800,66,797,917,991,821,854,814,495,713,159,421,328,813,291,625,838,218,179,408,239,826,743,272,318,953,131,746,709,592,769,462,735,429,109,576,171,270,836,30,922,190,69,655,455,774,732,175,140,263,595,954,56,632,471,705,117,501,48,196,258,27,544,505,162,780,802,804,128,534,711,297,490,568,165,908,571,946,526,403,180,521,17,161,185,81,743,488,725,761,32,429,711,625,699,917,382,546,743,155,317,90,622,707,437,741,883,459,722,890,595,9,395,495,314,439,945,25,449,127,514,320,164,688,656,378,71,135,419,512,401,130,677,872,530,712,849,891,292,552,267,864,38,96,147,483,97,51,337,214,431,205,514,674,46,427,781,289,390,307,96,619,151,69,911,518,967,699,347,243,427,578,793,747,762,542,127,354,69,475,896,820,111,899,805,199,445,359,31,662,353,253,789,393,14,847,940,57,909,773,604,208,971,64,545,258,364,297,913,965,782,698,821,159,463,927,401,976,868,616,621,131,421,181,568,473,931,828,231,240,16,588,578,461,705,335,82,842,236,267,230,759,102,508,229,626,669,505,136,903,694,351,738,118,816,947,986,769,589,488,120,595,13,656,751,431,107,716,729,734,181,673,378,125,119,141,46,616,21,590,39,119,225,995,244,406,660,287,450,423,755,508,896,388,138,821,597,824,982,901,565,856,509,751,773,24,839,773,445", "212,207,156,654,658,406,823,860,479,773,853,165,406,730,546,854,708,59,707,231,631,779,87,360,170,311,266,737,756,842,851,348,707,955,921,781,426,107,50,292,182,273,905,567,143,615,322,669,697,646,371,67,708,560,287,951,94,103,608,906,103,164,232,310,129,653,316,309,889,980,240,425,710,817,190,176,795,654,770,416,439,253,729,178,134,396,116,326,535,636,85,863,225,329,406,12,60,24,966,407,94,430,993,957,201,100,629,720,140,782,470,27,661,518,144,517,294,916,908,687,508,689,32,749,244,444,780,151,371,359,447,690,429,705,813,812,483,247,955,644,883,784,450,949,387,895,991,975,900,841,550,551,980,513,490,907,884,651,275,798,239,552,572,269,320,394,712,960,233,343,416,261,351,989,148,90,975,307,395,826,292,522,819,275,752,692,794,112,131,768,905,247,59,36,896,901,367,739,451,332,226,995,733,799,343,815,258,1000,802,815,608,950,487,869,821,354,43,52,391,174,489,43,126,884,341,238,516,791,494,94,989,267,314,619,910,79,147,79,213,706,72,106,764,54,904,875,717,447,580,880,350,892,636,390,801,338,768,465,860,137,804,388,322,291,243,564,607,969,879,102,403,700,9,62,63,814,630,737,345,967,697,89,523,762,719,742,583,864,7,9,759,149,972,78,80,800,956,480,519,373,133,556,301,180,163,536,177,154,521,115,131,829,316,859,844,436,14,359,810,675,395,559,146,160,444,646,143,567,588,655,319,749,648,930,25,931,637,126,318,836,795,459,189,637,150,984,297,625,61,210,417,851,557,802,420,439,114,262,290,862,306,594,532,740,32,913,664,46,942,989,932,484,167,508,128,914,872,649,366,973,598,50,941,514,859,727,731,291,705,229,38,101,387,331,129,613,648,133,119,273,711,349,774,362,364,316,937,155,56,360,973,360,185,877,766,244,7,166,893,296,148,195,787,951,951,711,781,517,975,218,188,743,975,577,485,647,853,839,296,855,752,84,41,212,450,138,749,335,40,629,943,752,643,894,210,628,535,797,377,708,591,990,61,600,650,189,384,701,205,524,402,329,138,438,502,333,697,921,587,275,85,311,416,465,243,41,966,117,306,423,655,307,413,355,89,726,196,453,339,530,26,240,244,772,345,916,536,954,45,394,219,283,797,629,799,841,554,887,237,5,566,738,373,491,590,163,561,985,155,69,291,679,725,374,411,199,809,583,444,862,433,988,946,970,428,747,293,914,246,171,715,59,385,435,277,552,286,110,599,63,121,704,685,563,548,729,425,168,14,544,99,129,983,454,439,432,799,600,681,333,689,569,3,480,120,775,568,896,98,835,446,801,768,408,60,506,253,688,73,111,732,974,53,512,497,236,596,257,946,220,796,753,10,380,776,242,927,295,560,894,73,218,459,247,486,906,434,479,0,944,317,820,87,579,373,487,550,478,461,260,633,11,954,152,76,794,938,923,598,421,898,310,163,55,88,523,32,987,385,733,423,647,696,489,20,303,918,852,574,120,931,812,635,552,754,441,727,850,431,78,468,839,628,513,102,140,684,872,517,233,823,170,754,726,845,313,830,750,341,664,326,295,922,692,208,62,9,483,969,167,782,168,464,546,120,274,961,166,128,161,764,39,981,337,142,529,782,951,851,687,876,337,946,578,421,822,42,393,575,290,829,798,585,597,46,522,760,768,893,85,75,973,703,785,475,875,114,103,100,991,851,714,758,241,254,568,166,489,262,295,910,780,463,672,667,686,341,29,18,440,221,692,339,851,651,707,593,751,256,233,281,564,531,332,791,124,900,49,919,189,90,338,404,422,110,227,577,736,935,857,553,104,212,276,915,951,759,575,648,20,778,905,401,158,291,220,334,531,208,847,457,4,945,19,183,916,968,748,302,553,423,257,901,660,383,884,361,97,39,691,183,401,50,333,650,316,778,63,218,349,199,953,939,432,364,494,825,791,808,561,617,807,626,635,225,408,61,200,787,941,610,931,552,565,972,371,673,529,23,893,359,912,452,267,820,382,676,281,443,273,323,778,692,51,173,198,342,980,721,736,868,957,406,692,938,241,603,429,313,322,537,672,158,582,878,506,860,311,984,970,759,323,924,998,460,367,515,915,69,727,580,911,880,99,652,267,829,847,907,704,297,761,872,203,803,559,631,423,820,696,504,958,174,491,165,724,737,798,124,93,411,824,304,380,111,214,158,210,737,828,462,601,909,247,357,972,123,622,405,354,676,273,134,592,951,195,557,16,870,759", "311,144,163,334,602,485,572,98,441,349,513,876,813,142,734,224,841,258,658,585,197,531,480,989,593,972,338,42,856,935,807,454,610,91,16,30,89,810,959,552,202,127,900,306,433,408,78,281,22,432,420,579,802,338,388,204,416,617,150,272,373,322,828,787,818,53,54,712,415,902,924,938,912,614,773,758,627,49,310,667,774,48,829,454,581,380,446,988,965,579,913,296,922,233,774,769,375,89,763,839,392,306,937,417,910,153,635,216,487,115,136,427,964,830,316,995,163,449,180,659,483,990,559,855,387,84,349,97,973,793,903,417,641,829,646,575,393,40,216,407,889,437,844,761,208,329,516,54,406,64,366,482,330,102,340,661,91,265,689,241,491,358,14,472,491,226,582,108,547,526,136,181,926,244,299,384,459,471,735,469,227,438,611,332,317,798,580,223,272,872,677,194,717,126,830,105,939,171,306,552,872,967,33,199,823,907,338,536,895,593,300,149,622,692,873,718,784,983,37,741,677,466,973,304,868,705,298,321,976,969,705,840,439,448,82,651,373,903,128,152,168,66,899,965,924,89,718,212,502,920,653,955,199,563,990,237,477,143,916,318,809,795,880,388,972,958,251,677,136,13,181,994,123,963,581,127,743,515,740,516,510,712,186,384,951,393,360,119,356,478,992,781,615,752,174,938,133,428,299,741,980,600,370,570,370,263,358,876,711,69,126,892,267,599,753,846,49,667,181,960,999,628,317,78,316,804,4,107,850,946,352,816,35,134,456,350,451,813,781,48,801,110,878,579,913,289,500,301,373,665,447,327,363,707,467,529,70,179,429,379,821,919,493,744,355,612,899,307,440,160,36,740,880,732,18,567,654,351,115,50,670,551,139,472,971,966,232,313,728,986,640,562,995,677,392,131,364,846,303,265,144,414,128,481,354,812,263,875,988,433,749,382,312,779,266,70,94,718,990,405,761,999,280,670,904,966,632,462,399,158,88,837,766,462,369,660,793,307,698,503,984,971,222,921,763,885,348,511,430,147,71,316,885,795,719,202,659,352,339,955,621,61,845,715,575,759,753,535,484,905,646,351,486,811,469,973,799,623,268,217,499,280,122,336,834,23,959,342,958,452,233,493,175,894,903,785,710,230,84,686,455,633,414,236,180,852,995,308,77,844,594,911,313,286,889,359,909,388,607,935,454,601,302,31,413,357,339,220,766,39,11,827,926,108,18,426,67,502,431,99,917,434,253,43,288,290,238,589,346,272,617,812,720,147,125,646,55,13,209,408,801,802,47,143,962,219,798,736,204,411,73,873,783,229,433,624,173,965,108,197,174,655,355,411,707,86,458,776,476,104,355,765,385,710,543,309,896,522,361,739,51,676,926,982,409,753,325,858,825,584,26,404,46,111,682,685,225,604,979,32,402,691,733,740,996,580,644,597,944,0,264,589,983,43,887,919,142,170,775,727,320,338,882,427,496,818,217,330,609,446,347,789,93,524,644,312,651,376,990,359,1000,93,395,638,76,371,606,329,530,946,604,870,195,942,502,374,648,541,528,679,228,893,4,328,265,388,975,692,286,937,879,303,97,125,895,365,724,516,966,271,113,634,189,617,738,225,541,598,388,146,819,82,73,770,658,43,237,522,276,640,583,541,670,242,567,162,203,531,998,933,42,263,888,468,723,384,292,599,123,315,639,826,917,124,888,544,615,484,59,114,865,744,727,80,375,233,520,12,967,452,174,150,230,676,944,442,10,569,730,993,161,702,94,690,546,129,400,719,129,527,921,49,800,121,521,762,596,372,610,226,499,124,481,931,532,752,918,331,513,438,296,67,43,499,280,396,906,980,946,501,49,600,415,864,236,753,951,615,258,698,173,154,914,523,289,122,66,740,856,791,745,323,215,409,144,637,246,477,863,684,240,206,897,797,880,370,824,118,571,841,94,172,702,238,43,387,423,967,296,464,954,144,800,868,757,29,710,365,876,570,844,243,602,380,99,521,920,207,401,404,468,920,26,444,917,411,706,453,87,434,653,385,90,700,376,790,459,513,906,553,699,271,944,754,910,992,776,373,616,912,418,364,230,290,584,829,145,144,436,397,757,457,463,617,520,444,625,581,91,257,776,292,441,462,508,975,71,311,709,987,77,123,571,602,693,674,444,222,935,393,444,709,599,454,239,354,599,336,520,307,764,485,774,797,166,186,813,729,578,277,838,150,580,866,979,892,433,628,924,454,721,522,374,466,56,414,287,544,592,98,408,11,342,508,257,958,868,543,415,561", "572,162,331,9,86,253,915,431,256,388,520,667,47,796,233,542,734,216,120,754,974,588,798,695,500,166,320,395,374,570,579,173,780,610,469,831,53,690,232,986,135,136,526,551,13,32,315,493,723,519,3,232,8,452,83,778,308,388,289,318,711,474,649,930,571,317,893,216,276,552,250,431,981,380,518,27,921,643,863,727,768,706,518,328,295,453,32,376,19,850,295,254,506,119,757,128,124,614,365,12,172,499,135,622,397,347,630,895,596,413,726,461,164,872,867,444,219,414,499,191,103,359,774,450,765,835,418,962,636,899,928,863,278,989,175,939,190,570,347,295,457,386,412,26,142,545,43,964,920,80,462,559,652,604,971,961,137,969,401,678,573,671,22,920,67,410,979,148,544,667,869,435,524,938,15,671,105,550,999,587,683,152,15,144,180,90,450,947,120,981,691,66,59,100,417,229,203,989,801,994,198,582,119,841,699,478,654,801,479,88,591,362,462,466,594,742,653,267,458,810,450,315,608,640,801,204,622,645,927,370,164,534,13,677,894,998,42,764,48,146,568,575,98,447,626,948,202,402,299,602,350,642,9,165,828,837,813,928,487,819,637,773,816,543,491,75,917,353,264,781,689,275,931,602,213,217,509,226,877,846,326,744,408,826,446,26,198,292,210,869,740,101,174,770,454,551,808,599,309,146,525,273,663,27,965,491,120,189,336,712,98,344,260,599,827,102,468,700,358,75,323,883,241,92,17,738,467,187,255,391,536,926,905,835,605,827,785,278,187,380,352,825,586,940,295,668,808,573,113,992,412,941,905,621,541,265,240,577,915,483,796,391,509,884,265,936,381,747,431,669,499,65,301,536,104,594,943,830,174,192,937,539,53,808,342,823,831,322,836,124,372,148,840,152,416,667,803,12,711,807,231,854,143,638,719,538,881,992,864,523,970,279,632,899,655,120,525,200,450,945,41,156,643,572,974,279,432,408,233,881,448,755,922,977,326,820,379,165,310,189,141,679,604,176,750,802,107,493,369,491,929,208,505,188,490,284,667,595,964,445,257,695,387,759,776,118,56,435,321,438,450,182,100,490,602,62,796,320,234,493,360,464,746,55,298,910,59,80,731,665,837,129,419,851,656,676,905,535,83,525,540,332,309,514,449,373,425,365,594,66,907,522,430,898,14,289,460,509,753,853,54,929,300,989,126,593,448,675,327,708,496,945,959,34,76,566,384,507,635,663,420,852,454,300,21,880,569,932,661,102,410,159,587,452,180,704,410,414,382,972,666,841,465,419,128,621,102,388,66,397,296,706,241,833,961,356,444,852,391,902,534,616,723,185,605,79,343,91,508,290,260,131,459,23,886,347,695,808,619,990,976,690,295,875,96,758,691,833,651,428,628,301,830,424,416,907,957,428,853,79,840,419,391,662,929,678,493,404,317,264,0,339,521,2,495,2,45,550,34,5,959,497,850,760,395,743,459,763,150,332,247,163,149,524,14,223,601,377,532,244,314,645,181,832,77,522,639,766,439,844,725,562,586,59,129,594,233,19,882,281,642,958,91,813,47,104,993,777,932,974,681,526,779,986,831,459,354,229,604,696,473,112,906,618,242,919,676,337,708,175,644,434,490,459,658,9,848,831,753,770,139,318,331,706,352,730,588,956,339,552,895,468,608,466,864,991,411,901,783,930,899,57,492,242,249,501,671,458,626,928,370,267,262,869,869,848,395,885,665,182,574,963,913,830,66,136,554,373,914,592,869,854,453,567,936,798,106,702,26,107,100,358,7,869,16,469,16,274,477,35,951,696,230,716,529,238,850,663,788,392,316,226,948,362,607,306,878,97,490,631,929,586,727,386,787,490,555,553,265,524,657,114,529,428,121,109,378,102,443,741,346,220,515,368,900,207,761,702,784,763,415,221,796,292,61,703,567,300,230,369,113,947,625,718,516,409,617,924,606,613,594,118,847,795,962,678,436,539,138,358,290,741,470,401,350,61,116,754,510,289,772,574,341,859,241,581,681,396,17,866,817,63,339,79,226,237,986,331,190,447,255,277,549,107,4,984,275,919,466,529,141,805,690,808,773,382,193,423,408,438,486,671,967,58,974,241,150,218,475,2,840,181,169,707,91,957,999,283,768,577,309,913,934,954,18,383,310,577,14,396,796,76,81,797,778,748,978,907,989,717,563,986,400,669,741,360,930,402,621,16,501,444,560,743,623,97,78,954,995,808,77,191,664,323,902,565,324,885,968,408,834,913,424,439,340,296,274,611,526,82", "852,46,587,294,332,210,41,416,947,245,746,42,270,991,552,859,387,48,427,622,618,550,487,127,701,428,585,798,616,14,833,635,89,751,187,824,368,35,485,373,478,816,100,406,883,570,228,761,403,411,54,266,638,947,166,906,343,303,947,904,71,314,86,592,439,630,984,677,841,988,536,228,160,88,862,687,333,393,641,166,322,277,642,682,131,701,90,853,682,971,282,616,876,531,580,842,980,515,410,389,265,565,853,181,38,476,398,187,985,529,91,621,970,234,924,974,493,833,356,221,590,67,712,367,771,626,173,539,421,204,790,135,496,968,769,22,534,626,382,703,950,797,23,233,796,106,766,937,994,300,945,500,366,811,854,380,937,981,692,189,393,751,133,666,833,948,154,253,663,691,513,849,370,847,645,73,77,93,207,701,184,682,328,390,377,229,277,792,247,568,422,724,757,737,9,497,11,893,997,850,144,462,522,423,686,269,370,521,539,405,699,918,467,719,58,274,555,412,985,49,876,234,540,492,610,247,400,4,508,393,371,972,592,222,65,441,583,351,753,373,572,558,759,91,809,852,725,330,976,761,489,144,663,291,179,27,350,140,859,809,596,986,664,117,766,809,426,449,635,714,525,779,735,347,840,329,140,121,257,497,69,546,753,61,26,900,368,506,151,642,217,738,107,130,324,172,759,404,667,634,135,669,223,563,929,976,882,653,334,976,766,214,511,941,873,75,55,282,995,471,929,45,799,96,438,101,862,401,981,789,134,197,594,695,249,266,890,935,317,658,433,9,18,138,169,713,80,25,986,443,500,931,726,826,86,846,232,321,497,948,234,815,156,97,855,1000,200,797,953,890,592,57,307,945,191,910,572,492,393,486,929,802,659,729,824,864,970,65,336,651,477,22,389,448,848,727,606,836,841,173,762,444,231,846,477,405,337,897,409,321,173,739,556,888,50,618,560,884,393,59,39,984,245,391,10,386,530,109,114,603,159,80,21,299,403,715,58,890,643,157,748,330,119,525,772,532,979,295,330,932,323,271,473,939,472,915,193,918,45,670,580,593,596,835,41,722,750,892,832,780,117,111,570,931,569,22,88,640,578,826,506,780,642,837,852,643,599,140,548,236,336,940,782,243,134,47,550,867,554,337,192,272,444,881,279,948,57,273,182,518,348,787,197,198,662,714,69,531,525,956,26,827,650,922,230,209,680,887,179,521,661,727,218,4,782,857,650,773,663,256,443,577,445,240,175,889,726,951,724,249,463,485,167,313,568,925,835,702,305,70,854,949,196,18,68,841,227,30,972,657,325,149,286,534,829,330,84,784,585,506,221,745,901,163,659,674,381,721,732,851,548,703,868,11,40,540,236,909,949,747,251,617,640,164,737,54,880,12,614,327,340,716,467,950,111,638,842,839,595,640,746,441,855,709,475,689,55,716,820,589,339,0,349,801,783,821,561,891,342,754,648,960,680,635,584,119,684,465,695,994,164,93,401,10,599,412,475,657,947,176,449,789,39,495,640,64,806,822,921,520,416,46,16,230,291,79,37,775,268,713,17,901,493,112,160,672,289,465,660,133,816,136,248,299,847,311,156,224,609,72,99,419,867,873,902,460,8,878,541,928,524,20,71,280,241,937,894,867,541,313,156,560,529,620,913,754,144,216,504,991,679,157,853,229,445,545,275,96,517,691,318,476,881,581,759,658,212,67,670,328,810,216,265,432,48,1,605,719,141,690,876,416,24,436,688,135,423,759,49,138,188,446,274,687,70,7,267,230,407,954,901,236,481,595,16,712,855,348,519,81,514,526,122,574,893,817,941,425,772,290,523,755,692,177,693,97,285,497,281,29,232,774,788,262,398,160,471,923,700,123,460,39,37,597,905,146,805,485,818,713,401,922,234,505,650,690,223,150,274,148,826,2,768,885,870,458,980,133,319,358,741,401,423,808,587,272,193,234,379,942,807,128,376,74,369,959,928,13,985,728,493,142,69,34,984,246,386,2,985,676,792,543,540,303,108,186,803,562,721,356,687,716,784,322,598,77,73,665,201,538,203,555,714,607,393,142,767,594,820,699,84,802,502,475,480,183,27,391,325,656,288,839,245,125,806,575,671,795,105,915,31,929,269,989,803,205,632,421,40,587,901,607,529,775,481,788,319,749,871,380,977,248,50,620,858,832,770,433,657,765,310,376,592,820,309,657,736,525,375,782,642,775,841,252,567,11,373,281,767,744,584,278,184,377,842,574,719,310,212,430,932,695,85,172,623,192,79,816,677,196", "657,689,771,441,104,338,817,524,998,748,711,450,677,32,886,351,456,619,102,141,656,560,49,403,155,115,635,587,368,420,648,992,110,355,321,930,419,855,414,450,378,717,606,216,475,261,539,579,73,747,858,393,152,111,969,884,68,238,786,127,503,80,9,450,598,756,219,653,1000,414,554,339,963,271,487,615,950,558,725,160,586,559,248,138,677,25,48,422,417,72,981,67,2,908,810,43,101,632,199,659,556,531,12,515,926,80,665,205,115,294,393,251,300,738,245,22,994,675,131,993,693,381,435,44,993,155,282,320,385,398,918,577,351,771,206,255,848,56,42,619,180,198,318,38,853,504,727,291,815,671,324,843,474,763,623,638,623,418,858,681,939,668,191,931,447,664,20,366,474,685,221,129,321,944,739,78,766,764,515,416,144,903,616,430,952,194,992,515,583,811,740,385,510,891,78,280,140,900,478,415,216,131,626,252,153,278,11,22,300,887,722,5,464,6,909,492,620,283,551,561,79,99,141,347,17,975,530,19,130,621,405,956,221,714,725,662,989,605,181,630,236,421,507,574,388,290,696,860,208,481,222,704,836,100,641,269,358,339,235,909,146,875,308,425,461,680,239,100,685,420,758,676,168,933,824,558,846,190,142,865,700,980,908,311,226,321,803,971,144,549,997,613,986,945,249,841,375,809,462,17,857,907,495,410,204,803,568,610,14,287,312,523,228,643,595,98,529,282,593,287,519,287,52,364,299,705,581,950,639,537,146,19,85,393,657,923,130,754,871,330,624,720,603,119,105,246,449,721,486,506,530,542,576,592,336,502,453,319,706,763,606,994,905,524,404,79,761,512,306,861,294,260,591,551,964,97,204,372,903,230,583,285,814,313,378,780,192,352,87,441,400,487,678,285,28,547,481,458,951,565,309,329,390,474,40,195,857,375,822,75,858,813,37,860,745,581,44,167,395,123,343,374,19,134,102,999,796,167,907,451,722,958,530,514,95,376,751,579,511,602,104,72,538,819,465,945,104,286,66,165,659,11,657,612,68,491,78,442,60,571,141,291,639,198,967,507,212,125,978,240,484,517,187,866,517,830,182,367,661,405,384,34,428,984,20,787,746,676,916,340,961,363,358,594,343,738,439,155,319,844,809,876,215,809,608,433,953,640,340,848,188,265,713,989,934,224,223,746,476,38,220,132,526,361,572,447,31,707,9,14,107,709,467,8,741,970,959,555,760,160,251,463,163,890,978,354,689,150,849,660,604,919,869,448,448,55,30,140,149,217,933,283,80,943,829,73,387,370,781,790,373,591,461,983,448,872,778,141,638,654,725,126,720,843,94,428,201,665,272,701,995,78,95,191,381,608,846,722,448,682,150,948,730,536,443,809,253,281,410,180,523,464,133,396,845,237,622,690,201,896,965,297,190,622,663,467,721,867,87,983,521,349,0,194,658,669,20,851,985,654,923,112,444,393,106,7,557,715,783,849,913,359,33,158,613,370,945,905,523,751,632,948,481,150,740,154,865,89,338,589,504,962,686,27,608,397,564,448,875,303,420,120,1,736,824,695,565,609,411,935,240,173,522,967,352,474,408,690,236,924,778,494,751,350,880,629,916,213,744,809,227,997,936,46,612,917,781,49,874,227,462,68,33,871,903,957,508,23,691,765,300,371,954,938,971,550,971,836,530,882,617,269,498,572,16,995,247,161,242,965,635,744,835,521,825,932,121,619,202,83,387,169,896,582,80,540,203,255,254,98,487,94,864,438,214,793,387,111,840,693,677,735,625,810,287,551,950,215,905,274,563,430,742,863,981,870,634,603,925,19,911,352,277,250,281,66,490,569,881,952,971,656,416,922,908,785,133,477,660,142,297,393,538,46,589,601,655,490,525,96,490,788,92,26,774,623,793,587,217,43,304,971,340,616,475,677,584,233,128,762,397,637,973,324,683,816,859,457,553,824,540,758,265,190,203,753,625,534,463,792,348,799,970,429,333,257,324,523,235,735,192,401,426,689,616,579,955,916,518,104,259,857,901,449,978,81,903,879,813,610,274,99,729,310,998,913,647,231,328,953,431,173,15,92,908,84,45,686,173,519,447,504,83,291,688,81,39,318,621,196,747,651,881,463,412,15,277,258,613,14,692,886,735,174,180,626,740,229,788,474,181,566,893,966,554,495,626,777,70,674,689,885,54,339,835,766,60,153,897,932,165,375,442,923,660,176,677,909,887,326,808,747,719,931,160,871,500,270,193,966,225,858,858,887,718,404,810,424,795,280", "622,775,204,194,689,36,812,629,357,385,548,643,964,413,200,914,467,588,476,126,536,114,225,11,846,931,990,554,496,572,14,876,14,109,922,716,914,921,371,81,770,648,970,198,67,523,503,390,729,603,233,322,458,259,452,395,788,442,918,651,744,750,317,652,269,955,143,53,220,275,925,821,280,223,328,594,528,778,824,665,137,119,586,490,262,182,601,526,280,239,320,266,355,836,611,61,576,946,988,942,98,545,23,288,555,93,402,166,371,62,25,283,456,102,274,568,212,659,398,683,66,665,584,934,681,671,581,866,188,222,761,442,108,179,952,618,763,877,662,132,950,433,58,428,363,575,659,286,155,556,232,520,978,833,120,567,898,756,802,571,490,550,663,832,656,737,655,365,973,101,150,870,106,647,9,13,940,914,314,88,704,707,756,285,100,513,108,439,702,796,409,809,317,589,152,89,949,176,732,750,713,550,554,336,942,92,147,634,435,903,539,814,493,31,845,846,147,763,388,427,931,858,933,395,108,978,806,404,867,5,471,985,782,73,930,687,787,603,138,334,446,416,437,370,234,369,277,671,930,46,885,12,490,282,979,587,989,633,725,206,812,575,71,120,830,697,204,647,671,754,293,523,250,305,31,886,402,25,527,221,664,354,848,827,241,431,882,199,452,159,285,676,834,786,949,665,891,720,552,577,38,180,408,248,173,166,432,867,856,630,174,588,674,50,335,630,664,101,19,943,355,514,780,3,775,973,881,718,564,712,564,499,385,659,557,290,360,835,700,865,995,857,205,552,899,69,149,792,192,928,579,970,981,3,277,722,397,612,333,950,37,55,829,153,573,379,663,683,719,583,118,73,372,398,837,730,496,703,726,645,646,600,537,208,865,951,445,675,832,542,627,323,767,424,988,509,672,860,701,339,70,602,752,153,371,620,247,552,666,280,433,553,756,478,397,783,137,968,849,439,506,959,409,280,59,933,16,842,825,246,61,214,123,553,145,377,55,360,662,7,393,4,735,767,464,336,666,527,459,793,345,133,815,857,284,633,285,610,913,63,285,724,209,630,534,220,9,76,754,847,987,864,947,766,851,31,522,433,782,510,56,708,245,355,442,776,43,354,22,819,74,473,641,398,965,536,878,66,627,614,801,229,207,586,170,946,352,55,806,792,219,352,445,393,230,399,449,494,9,572,891,326,341,544,122,229,963,977,103,14,954,572,583,904,643,890,156,134,859,155,587,306,391,546,152,471,58,602,512,427,926,181,129,215,348,830,325,136,914,648,963,944,110,115,767,661,157,303,412,736,996,184,878,811,496,471,242,836,447,702,834,845,376,185,921,756,482,147,970,906,400,369,204,807,130,332,41,16,422,670,745,527,634,151,993,879,24,980,987,224,764,547,81,606,15,990,70,694,598,461,787,527,54,518,351,261,44,870,579,43,2,801,194,0,965,459,597,57,970,470,405,327,341,479,790,561,633,885,843,277,29,484,837,388,745,605,811,916,269,538,669,401,232,362,948,821,243,217,237,57,442,332,847,25,859,260,95,827,316,42,11,758,42,379,869,792,781,279,965,759,315,270,164,27,738,483,604,709,818,525,614,938,789,107,881,983,466,627,174,187,682,191,842,487,157,662,549,585,821,375,34,811,357,908,667,576,178,245,876,323,230,339,671,745,923,509,3,405,126,175,930,995,113,806,802,762,711,401,801,158,512,700,296,426,135,965,723,344,859,851,390,630,15,871,997,411,722,93,377,878,92,888,304,731,373,256,185,266,968,688,905,381,64,947,244,279,645,779,68,37,362,504,726,137,194,491,211,235,193,722,290,834,619,890,891,982,488,813,884,185,893,929,370,334,802,768,791,781,886,595,536,104,224,513,646,733,334,326,70,296,528,154,24,767,161,829,83,901,180,297,490,127,29,837,298,161,714,489,653,968,121,558,891,858,376,705,864,469,583,429,536,527,411,409,674,823,642,959,127,306,253,936,402,834,597,864,588,989,502,219,450,99,310,166,506,494,509,185,130,437,406,175,402,893,931,330,823,144,172,827,437,50,917,830,151,298,187,280,957,105,224,241,334,649,927,463,274,396,455,317,866,149,635,89,995,687,675,793,467,713,871,634,713,112,631,587,257,992,737,454,114,782,53,101,117,106,902,435,757,798,650,119,536,363,790,649,601,394,397,134,533,375,210,208,624,166,854,859,679,676,25,717,678,801,969,816,879,873,823,59,144,812,351,512,675,596,986,871,213,501,190,981,154,623,11,28,101,450,204,773", "461,318,607,902,959,277,61,405,184,339,552,538,549,552,91,725,631,653,244,459,870,414,170,522,177,431,571,71,888,254,541,91,953,203,161,762,826,951,773,88,661,662,860,972,384,998,195,632,888,228,713,799,953,304,160,312,743,259,302,256,765,264,890,486,344,378,196,53,146,171,748,284,573,844,292,608,872,54,668,237,66,577,994,790,647,618,60,950,298,43,588,194,831,34,670,548,71,308,955,269,73,134,161,149,831,258,436,959,665,425,355,900,411,474,203,939,94,320,2,47,30,668,917,37,37,840,412,673,501,306,376,773,904,775,18,367,85,659,672,796,318,486,739,416,374,916,625,84,916,262,852,866,402,941,580,45,405,716,862,854,615,501,85,281,560,308,875,737,656,115,287,778,275,908,223,865,408,381,240,427,532,266,498,798,692,829,964,70,309,522,278,508,362,899,455,778,658,975,189,663,518,118,5,401,76,582,750,873,293,869,213,654,410,750,450,928,731,59,27,138,162,294,158,15,815,285,917,841,250,144,117,913,547,370,43,769,677,797,930,628,528,262,797,496,170,364,130,927,323,908,951,387,931,267,97,443,99,702,562,652,566,542,432,461,732,305,783,117,84,549,888,624,524,793,327,818,62,491,178,258,687,631,267,352,341,604,585,369,916,536,274,232,624,433,637,870,285,309,850,31,754,791,546,885,131,269,796,991,33,712,736,939,527,885,60,636,725,230,150,880,73,415,609,530,567,273,837,161,593,937,808,232,226,299,592,74,721,825,881,109,545,499,423,262,616,394,424,453,561,913,387,399,98,963,567,412,933,445,680,115,676,215,183,611,736,20,831,737,296,171,749,878,76,462,793,495,402,264,953,738,655,697,93,913,893,334,551,193,248,278,385,411,753,114,336,30,314,722,503,377,919,309,338,50,199,859,398,647,744,590,349,809,974,250,441,336,836,872,412,875,575,61,887,235,130,698,611,861,525,112,878,271,902,10,949,893,887,595,48,243,332,14,721,298,836,751,616,415,189,209,63,153,534,180,970,941,865,432,894,830,356,311,569,500,130,569,527,582,41,853,532,726,107,392,411,722,416,606,86,639,218,696,672,637,988,199,623,684,361,780,121,222,458,71,743,599,865,638,658,274,408,968,134,804,646,63,222,747,280,820,50,569,178,871,593,470,65,962,220,665,681,363,83,224,847,353,6,808,448,54,478,520,796,487,687,431,40,561,870,18,495,32,528,807,944,618,594,189,331,170,89,977,760,587,971,534,724,900,304,65,124,252,380,633,700,428,941,759,312,143,598,573,932,360,399,108,658,277,706,945,922,266,999,518,318,410,976,823,983,63,874,133,958,30,928,782,70,808,133,308,859,853,607,368,928,890,807,673,502,307,549,914,515,735,683,722,136,691,672,90,444,122,400,93,944,548,922,183,373,887,495,783,658,965,0,416,835,560,256,172,76,143,75,278,933,872,332,610,18,805,5,913,943,776,94,473,675,550,156,614,537,836,451,694,621,194,578,563,697,642,606,505,164,264,234,241,276,983,1000,707,882,117,20,250,790,664,337,678,661,791,412,314,645,629,161,713,290,902,239,695,254,634,36,281,652,829,46,414,800,737,211,92,600,793,780,254,270,582,399,517,859,311,808,609,480,523,992,660,98,968,964,47,898,437,791,128,946,460,930,547,514,419,406,786,770,692,510,290,614,831,567,902,783,849,344,114,856,511,174,841,740,724,46,138,740,410,404,589,363,620,117,668,350,93,941,662,124,461,848,445,576,928,849,603,748,626,647,467,146,950,487,190,385,286,504,621,575,667,732,881,977,580,890,94,181,855,639,846,605,632,550,892,795,9,612,745,518,238,971,698,118,80,852,75,611,643,407,448,511,755,405,541,983,607,265,586,776,707,561,459,345,987,624,894,190,445,378,508,466,864,139,734,721,896,686,607,172,521,377,6,370,997,346,6,562,93,576,32,231,732,375,535,692,176,265,240,160,586,500,656,720,611,805,989,726,425,957,491,155,989,78,332,481,787,798,128,726,149,821,371,137,604,260,454,912,501,169,420,444,976,65,243,142,966,362,233,510,116,532,232,611,584,966,764,177,34,985,417,798,202,800,679,449,864,956,148,122,17,39,890,36,741,480,703,55,752,805,368,599,799,563,991,968,91,207,453,890,410,575,236,844,101,291,963,738,393,525,62,502,696,206,39,19,811,484,22,313,226,439,915,115,596,395,109,293,452,917,543,381,986,368,750,197,500,791,397,841,941,142,149", "101,311,979,117,217,533,730,827,771,940,964,230,884,785,87,144,783,159,145,112,96,201,324,595,883,339,944,529,884,307,58,676,126,272,335,462,149,821,696,755,229,650,918,643,932,181,117,128,60,424,333,767,568,761,389,480,449,480,814,108,229,945,566,664,848,1,323,819,513,754,906,84,561,264,926,776,576,24,265,108,730,657,863,874,107,737,687,812,17,649,968,737,482,784,475,330,919,337,321,972,901,417,326,300,69,190,820,69,259,32,862,953,91,785,779,154,704,787,49,316,255,970,965,741,914,963,429,346,104,948,592,305,178,599,828,876,927,29,999,966,300,436,199,699,721,689,724,41,296,46,819,791,975,598,100,435,417,340,250,335,556,124,180,384,705,954,578,104,450,171,231,60,851,665,743,485,215,989,136,902,215,907,551,720,89,367,542,560,950,234,503,629,174,16,432,916,517,854,472,871,130,361,897,102,533,243,312,47,235,89,735,610,539,459,17,153,64,740,895,213,825,951,542,134,640,397,353,318,481,403,337,813,406,606,804,495,907,139,608,299,115,298,417,152,756,276,485,164,264,58,188,739,80,911,44,279,968,836,260,656,730,746,829,166,706,608,354,680,304,748,248,526,723,176,545,989,899,272,624,777,48,856,751,781,226,259,501,756,488,555,919,84,23,975,62,8,628,144,666,230,348,89,597,507,56,815,519,995,500,710,166,36,213,167,478,306,732,321,613,174,913,181,281,442,77,21,863,769,43,753,992,795,149,17,936,122,760,168,131,533,874,875,200,89,438,190,191,18,684,60,788,281,179,278,527,146,132,417,859,812,336,750,959,774,55,954,599,614,301,776,561,448,759,533,872,783,479,761,106,619,475,867,463,191,219,266,564,928,229,845,186,498,376,824,805,831,137,245,540,150,718,959,118,221,428,177,65,334,333,282,17,284,691,554,881,556,527,536,416,565,681,226,262,25,101,853,738,826,336,487,708,347,598,898,179,528,930,499,374,121,416,519,630,842,214,854,274,532,887,799,923,696,147,917,461,248,197,925,195,770,438,923,419,442,218,485,780,69,91,645,363,109,897,452,859,87,797,212,390,19,766,874,201,365,189,658,823,986,311,609,787,548,177,111,888,796,950,325,828,187,128,868,554,752,296,765,976,71,826,55,856,942,691,535,332,305,872,590,157,35,770,760,954,8,591,883,107,912,534,29,454,941,147,167,976,50,47,614,979,974,651,25,272,419,470,429,487,24,662,706,855,718,904,602,947,734,674,622,848,99,830,833,127,46,157,810,332,830,194,868,39,921,628,590,395,329,450,529,250,72,454,592,486,582,156,397,506,240,238,157,703,369,275,257,307,789,414,650,593,749,764,341,374,984,489,258,785,411,304,718,28,614,354,463,80,129,474,937,65,309,615,442,834,819,819,946,35,77,487,919,2,821,669,459,416,0,120,28,43,469,283,927,147,956,966,63,687,458,34,348,606,931,380,286,101,243,428,727,937,252,731,601,820,404,540,67,407,338,130,395,563,928,774,86,523,509,473,989,302,566,119,809,838,650,419,236,417,586,147,817,591,836,113,394,178,577,221,779,516,603,626,309,790,508,33,45,517,515,748,917,936,920,54,120,343,744,1000,943,629,66,592,373,706,839,35,754,709,757,666,826,4,265,542,478,492,9,530,736,922,920,331,614,650,19,435,33,998,285,832,669,244,234,883,853,46,678,615,159,309,72,87,687,761,233,809,430,387,871,731,724,663,589,952,938,564,404,303,459,988,807,695,40,220,387,451,625,262,386,789,49,326,931,934,147,471,959,394,63,369,962,308,544,557,428,447,940,997,578,323,165,920,94,566,917,462,664,736,207,241,648,6,155,607,429,495,872,261,80,360,567,185,890,190,158,473,65,762,189,442,383,586,935,636,104,573,47,843,530,259,394,117,64,723,642,341,588,42,563,455,951,265,203,944,447,100,329,863,520,291,167,571,689,74,579,385,821,532,203,179,847,264,96,880,468,45,243,284,167,284,771,11,552,482,477,444,426,583,627,608,876,576,83,920,788,927,511,379,241,411,696,264,836,794,161,338,223,401,45,430,527,538,570,716,286,460,146,208,184,330,14,770,223,230,70,101,924,274,577,656,695,374,909,554,331,265,906,185,674,702,697,288,531,603,377,714,859,897,285,72,933,494,646,505,668,888,321,62,525,719,565,357,108,347,717,255,881,140,291,358,69,202,323,894,904,922,957,439,602,780,658,593,231,283,287,423,224,398,558,268,672", "771,247,404,969,466,632,597,836,130,8,395,391,412,121,785,44,960,621,808,620,200,562,610,268,559,55,378,797,584,99,665,951,136,73,358,358,695,483,998,520,847,284,709,591,96,725,525,72,556,570,196,968,685,238,263,439,713,442,308,453,9,884,944,970,275,492,641,460,83,258,892,611,555,732,261,296,845,278,767,180,56,751,962,621,515,204,939,74,721,412,40,619,156,343,841,521,301,167,860,439,860,71,754,599,183,423,138,370,995,126,513,703,931,188,561,542,883,60,546,91,716,793,97,518,80,300,296,43,531,229,325,562,758,272,226,41,200,606,661,247,747,56,69,9,689,825,934,669,416,484,304,66,196,942,506,435,711,295,585,438,189,268,372,344,829,714,99,536,845,609,319,221,604,236,619,928,930,413,429,760,177,924,227,609,549,495,773,766,863,312,784,55,344,583,807,47,541,972,835,12,838,731,688,359,574,611,333,708,174,282,578,741,924,174,582,441,421,555,808,292,65,507,701,263,158,582,183,351,869,510,598,715,447,365,728,115,862,851,757,963,383,488,894,322,185,934,865,281,581,926,266,494,902,6,40,521,756,616,893,314,780,256,772,600,453,98,125,906,807,310,5,409,418,632,383,966,548,506,688,605,441,149,343,742,205,179,958,131,224,686,596,499,914,184,414,798,44,103,331,624,168,21,84,450,609,174,672,158,201,93,276,966,816,370,463,169,295,109,192,786,839,73,838,237,218,731,411,579,339,377,95,110,789,27,448,906,658,382,836,628,966,855,741,779,134,803,369,190,577,295,811,990,186,361,462,416,345,295,254,512,170,975,987,379,301,102,131,773,934,389,724,496,943,131,742,864,170,106,909,489,920,162,502,577,725,204,951,664,827,902,890,269,513,990,936,525,899,451,677,182,901,584,402,827,556,216,919,631,890,500,308,508,950,185,901,864,521,661,896,132,955,228,968,784,590,355,31,525,518,241,939,932,138,562,893,792,739,242,700,280,199,969,525,533,516,278,588,128,230,107,264,491,270,997,806,198,399,537,673,732,240,920,685,474,629,37,268,152,979,796,750,694,168,481,919,476,344,285,535,910,543,99,839,550,855,67,698,639,183,741,87,462,376,484,961,832,48,835,78,395,896,866,643,546,720,121,927,180,952,362,426,155,962,268,572,997,251,795,537,968,812,762,803,274,57,965,712,469,445,63,385,583,125,919,572,506,276,894,887,179,730,616,788,384,791,422,572,34,495,468,580,438,848,553,415,169,566,978,639,335,749,720,57,840,613,314,154,888,505,336,111,119,925,762,480,104,427,808,504,816,702,478,919,113,963,479,614,369,325,515,507,143,932,167,359,246,142,789,322,385,918,877,790,980,268,58,260,619,15,261,573,695,374,421,867,73,17,131,721,768,276,937,956,356,351,914,948,932,550,142,45,561,20,597,835,120,0,2,813,963,542,491,533,958,773,883,472,355,592,640,305,65,263,639,495,948,826,320,959,983,310,41,514,108,437,933,680,703,702,233,793,964,478,405,547,270,161,818,944,160,678,296,191,340,926,68,966,927,963,613,594,538,311,704,679,58,866,162,248,926,82,862,230,908,58,757,244,713,799,833,949,597,470,916,691,586,611,766,452,14,499,404,885,76,134,150,593,892,454,556,126,22,658,870,312,235,490,479,982,764,693,927,56,142,359,211,422,731,71,555,694,317,515,799,363,722,200,746,620,681,661,137,165,213,316,274,697,679,435,181,211,354,632,235,927,936,350,3,611,711,650,479,280,469,136,888,319,751,344,781,83,180,160,499,969,385,583,675,751,368,854,958,644,218,494,707,636,278,442,12,976,406,421,664,112,185,783,954,476,199,911,75,334,96,19,765,709,805,408,469,491,58,994,339,146,333,210,619,392,947,840,176,261,147,88,934,593,672,164,767,638,154,516,777,315,722,788,930,702,382,113,934,491,232,627,194,996,579,111,641,157,792,211,34,991,118,332,534,740,514,589,73,100,107,157,344,648,791,788,879,312,62,483,939,251,919,820,878,832,431,484,287,655,909,415,957,68,223,140,863,59,930,767,876,370,572,361,842,732,409,84,897,320,408,38,168,351,693,497,252,291,220,944,768,188,774,619,215,896,95,87,650,977,368,104,892,1000,779,161,824,687,785,291,123,298,801,859,122,488,952,792,541,885,703,840,674,723,566,766,991,7,614,528,911,638,600,598,557,308,454,202,484,909,484,707,449,3,688,126,253,395,254,739,787,850,368,173,909,447,298", "644,748,137,201,184,420,543,795,663,126,132,306,750,952,657,919,911,909,55,474,422,813,921,296,525,839,448,761,80,730,80,880,940,466,306,755,727,893,160,21,448,30,928,549,36,396,670,667,347,749,216,768,265,894,337,603,457,182,417,951,74,485,543,701,456,655,382,905,131,113,973,596,718,528,551,705,499,138,974,309,743,869,747,620,751,415,216,739,384,588,513,135,252,108,829,809,5,209,682,5,607,474,790,195,394,17,955,350,668,592,377,871,123,510,594,670,54,914,665,814,774,937,713,238,1000,849,373,488,979,81,967,72,279,336,225,906,347,926,561,853,235,438,278,160,796,179,934,151,91,420,101,330,365,464,760,446,590,534,902,415,467,654,203,613,224,215,583,124,150,641,90,641,886,534,818,71,239,624,385,908,420,866,448,646,261,424,247,661,704,219,354,94,88,731,555,337,954,44,531,170,4,780,145,833,636,173,268,602,18,719,707,844,369,775,27,602,127,23,958,384,649,207,231,577,478,106,546,361,371,588,29,69,339,76,524,378,967,401,611,197,989,667,796,328,433,980,385,795,986,322,828,873,290,382,374,708,378,757,223,489,261,68,934,230,612,467,66,156,787,242,197,204,886,9,889,227,686,321,112,195,222,760,117,292,911,464,805,394,470,289,932,418,588,761,568,464,667,725,192,143,904,658,661,285,116,882,329,897,748,535,994,745,366,467,221,887,150,465,173,708,160,620,465,512,911,188,131,86,803,100,656,996,440,72,212,134,976,641,507,445,803,171,747,296,688,466,955,500,219,116,343,217,316,247,609,509,331,563,955,748,662,331,913,757,791,531,786,297,106,128,477,485,83,431,255,960,391,448,373,177,431,462,157,736,253,307,861,804,490,600,623,291,85,323,210,652,709,948,108,549,581,806,511,591,524,34,772,817,780,108,809,833,428,144,975,216,431,735,182,153,632,887,207,222,972,339,288,16,598,468,865,273,432,101,616,247,634,61,750,847,600,871,985,167,811,506,554,402,187,616,514,129,906,841,554,8,526,685,448,724,62,834,261,288,286,309,656,91,75,775,171,384,229,591,387,180,526,282,7,534,483,460,988,779,860,530,899,325,14,704,397,323,22,320,525,776,293,915,960,828,290,618,450,933,288,543,328,788,815,11,822,840,669,58,92,159,597,178,694,123,877,886,599,67,516,651,635,795,880,605,660,460,484,397,838,189,143,815,412,927,914,251,1000,855,738,22,152,979,880,191,235,713,992,733,38,881,987,291,704,28,317,906,954,136,710,334,526,551,250,765,401,864,438,100,200,76,858,370,507,549,31,560,63,680,12,380,127,882,506,116,144,838,415,674,430,256,343,83,161,828,396,444,818,395,530,174,437,412,143,579,979,156,11,668,548,257,73,646,38,631,212,847,517,472,285,243,115,345,478,170,550,891,851,57,560,28,2,0,157,992,949,225,337,989,594,294,660,688,345,913,834,401,454,813,470,325,130,377,462,451,115,664,628,165,601,437,411,215,430,436,677,505,817,595,378,13,953,544,349,332,488,654,281,827,581,177,647,942,647,692,489,436,94,952,831,457,919,245,104,883,507,619,793,137,827,265,236,137,390,785,976,584,984,484,523,7,490,587,809,193,914,618,156,901,548,203,735,897,81,83,510,317,787,508,932,920,705,916,391,995,266,424,493,990,83,536,230,818,60,401,378,728,161,59,94,963,863,589,83,781,655,929,400,731,714,578,502,527,962,772,602,129,649,811,860,756,705,491,297,253,407,379,757,947,20,762,438,132,931,76,42,888,763,886,571,384,371,939,997,539,667,825,726,873,775,590,322,800,346,720,670,423,248,783,575,167,312,612,563,403,250,92,563,267,33,233,147,410,896,562,376,401,895,217,463,869,271,333,506,129,382,504,764,674,197,624,757,493,691,202,207,882,32,34,818,884,519,3,687,22,75,171,857,607,838,848,302,720,686,62,116,989,705,567,547,798,664,298,310,745,460,883,10,861,529,351,807,428,52,935,279,402,780,636,990,178,889,510,208,153,515,337,728,781,909,642,190,478,149,410,204,318,398,544,575,492,664,367,885,518,116,491,857,123,18,697,557,665,358,506,74,119,917,650,895,56,288,32,537,293,62,124,986,554,149,540,731,46,195,399,269,328,296,724,538,927,317,904,589,874,377,862,753,340,873,492,702,537,901,879,855,610,415,573,948,574,725,368,899,886,88,560,817,547,418,990,728,471,581,165,159,964,961,37,890,644,909,872,351,188", "925,318,688,451,313,213,601,122,498,996,444,929,109,932,786,60,835,474,477,9,355,602,469,976,60,933,768,684,610,561,636,617,3,395,209,29,206,768,512,208,95,410,105,242,884,920,203,344,316,837,675,472,189,528,479,580,180,874,379,745,154,428,84,317,332,22,992,222,991,929,624,944,445,119,956,614,290,439,833,27,689,582,108,834,949,451,635,804,826,365,699,192,696,928,951,346,547,116,599,685,745,23,554,251,17,445,129,241,869,974,465,915,975,854,269,270,579,891,829,980,677,884,674,9,548,943,873,115,111,753,856,643,700,781,194,247,771,25,814,693,227,280,40,461,263,981,582,717,937,929,653,743,768,737,648,883,500,109,870,31,824,173,765,624,922,391,532,718,897,194,788,3,957,370,432,414,670,987,341,821,673,94,123,456,370,320,79,896,803,915,816,72,726,293,753,744,679,602,536,103,558,725,941,93,643,716,170,910,796,926,412,480,21,834,87,255,745,207,913,789,671,710,882,718,684,748,325,707,889,708,893,321,673,178,378,51,673,501,598,266,582,244,325,659,121,100,303,117,600,265,37,843,550,435,998,770,10,850,442,889,364,695,133,266,486,74,574,544,564,903,445,375,79,809,852,982,619,436,892,828,903,978,55,182,124,859,495,835,938,474,83,609,377,500,509,78,30,704,105,65,62,14,430,242,933,8,522,453,198,307,430,275,645,100,140,826,234,950,72,249,628,507,136,351,614,742,176,802,877,706,947,796,300,730,533,515,466,797,552,182,247,429,247,73,679,128,794,398,486,746,875,517,282,794,620,969,441,760,301,871,156,858,905,413,796,724,702,881,999,59,272,954,626,4,761,712,33,417,99,993,701,91,822,953,845,151,347,239,527,531,563,940,129,489,480,648,942,945,160,223,279,116,103,611,565,950,396,489,542,708,294,374,745,174,907,873,774,835,595,544,519,29,411,149,685,110,431,108,846,814,280,221,915,882,146,617,203,687,867,102,855,568,804,436,608,227,11,857,489,649,556,324,119,201,104,113,858,122,969,89,868,827,68,276,156,518,105,83,883,131,933,836,959,229,206,426,402,993,445,928,581,369,228,466,541,871,407,515,620,937,484,620,461,683,800,575,128,561,400,224,779,21,11,982,665,545,841,329,122,390,860,814,399,594,982,917,506,744,802,823,348,322,904,444,310,504,730,970,725,732,593,106,77,476,187,276,942,866,742,796,925,479,655,572,257,837,779,324,921,872,163,216,562,18,657,17,123,192,323,247,150,555,763,653,658,253,978,833,106,288,441,382,564,976,678,212,23,5,340,653,164,580,429,946,16,395,604,887,366,95,847,810,220,412,303,63,735,356,265,368,394,231,434,714,521,17,530,571,157,543,470,369,210,765,105,281,619,881,771,59,436,623,653,993,848,966,933,187,461,775,34,342,985,970,256,43,813,157,0,764,721,377,80,949,853,851,99,570,634,152,112,484,929,785,432,596,146,218,732,910,648,67,671,770,405,697,915,19,38,157,185,177,68,392,961,343,876,33,968,505,448,459,788,160,415,87,74,827,61,992,92,868,990,234,302,950,336,912,957,95,251,989,295,621,59,240,964,507,910,292,277,751,452,809,280,265,495,456,941,919,144,856,825,50,206,194,556,49,81,280,562,880,773,676,433,879,973,545,190,114,640,526,128,155,711,341,870,209,298,979,841,39,90,14,665,702,475,458,934,929,492,959,583,753,401,205,96,155,473,321,178,606,930,768,94,441,326,959,690,162,899,721,767,902,718,631,852,48,752,128,383,383,49,487,337,187,957,533,520,228,552,365,946,809,1000,110,68,166,315,842,815,863,656,747,519,790,302,69,774,589,771,565,271,990,595,536,880,872,694,341,450,573,640,391,89,482,772,493,946,649,467,216,500,918,835,31,947,637,680,666,119,280,888,248,323,174,527,2,703,877,154,296,475,340,864,873,267,309,749,99,235,630,633,59,229,47,326,139,317,250,441,762,973,418,818,521,657,195,115,980,930,479,842,356,397,642,67,631,858,333,899,752,424,1,302,752,131,231,129,254,329,114,448,126,574,322,481,818,191,385,670,81,870,625,712,313,378,248,245,985,693,103,232,41,119,528,981,370,859,462,300,915,425,837,617,651,840,689,628,860,249,985,247,718,254,429,347,327,67,966,290,705,726,447,51,247,90,99,796,651,382,955,588,738,133,853,230,494,625,227,219,95,854,319,798,292,968,60,305,102,301,409,662,471,656,183,387,725,313,156", "761,828,572,589,774,53,31,296,536,242,154,350,136,600,151,467,213,376,829,770,759,978,550,145,706,191,616,66,221,220,613,399,181,572,499,420,681,187,846,914,818,689,526,978,308,18,576,525,173,607,778,703,568,869,331,440,824,996,878,980,304,29,517,230,402,30,134,766,101,997,846,37,720,772,312,986,610,22,451,175,606,232,777,330,395,922,423,262,479,818,788,429,442,864,400,754,372,477,825,81,23,264,465,501,817,374,941,28,647,519,637,113,419,812,341,346,554,989,896,542,190,780,938,355,730,59,757,177,319,61,778,599,416,313,475,839,130,266,721,63,732,717,443,665,52,850,542,199,325,836,237,909,825,482,311,432,204,688,106,287,763,429,649,173,408,563,515,793,366,187,447,914,229,871,642,36,679,437,80,291,819,352,677,597,309,175,993,172,255,371,344,785,930,44,793,424,703,528,788,658,4,370,959,91,969,817,189,955,23,515,94,21,974,893,826,90,873,264,956,131,543,248,127,929,604,627,342,124,386,187,910,817,611,907,719,576,504,696,418,159,564,158,251,362,93,861,141,159,838,119,1,966,82,520,794,796,647,700,699,108,940,178,648,669,591,832,9,667,158,779,536,392,333,895,346,296,166,923,350,274,62,177,243,761,387,124,42,678,625,168,900,207,349,569,559,955,722,91,379,21,748,778,338,97,669,858,173,480,252,952,607,694,157,6,39,759,822,933,413,670,485,93,738,65,287,674,704,809,167,972,72,516,764,601,441,485,395,905,761,15,443,114,822,453,460,593,499,840,542,99,886,470,733,950,304,309,508,79,984,793,336,786,119,719,13,373,217,339,52,196,226,301,782,511,712,575,319,329,832,972,136,376,346,634,256,921,238,711,539,1000,490,633,280,828,230,546,211,98,336,947,43,303,422,316,602,471,756,216,515,322,753,507,901,491,535,283,247,592,233,210,26,365,420,464,276,58,337,405,155,716,355,416,981,267,581,801,200,860,552,246,32,294,309,180,67,961,8,319,134,434,757,530,504,836,307,280,985,309,176,800,61,645,356,706,358,400,490,903,377,625,514,978,277,942,370,535,597,86,19,882,253,464,210,195,3,371,527,939,388,207,589,861,593,916,598,610,955,364,401,585,32,188,107,384,843,53,974,501,181,603,228,365,328,826,272,704,411,364,110,953,906,22,933,302,423,442,644,135,231,51,469,968,482,630,386,285,629,286,342,550,225,394,288,997,450,592,727,115,494,161,534,892,939,285,170,765,363,170,87,120,841,134,727,362,695,131,836,655,701,383,289,249,743,950,630,357,516,933,988,262,70,145,274,913,387,896,181,358,192,946,212,31,408,138,153,680,831,266,580,208,426,572,151,625,103,170,129,248,250,238,937,994,51,583,593,379,943,657,338,598,153,807,452,516,704,474,107,818,260,727,5,754,654,470,172,469,963,992,764,0,283,628,859,464,747,825,67,366,825,708,538,6,280,92,346,900,471,373,241,473,707,371,843,120,881,470,669,986,450,320,332,360,486,99,741,203,711,229,808,916,51,75,491,268,157,422,308,61,831,588,155,450,957,70,386,105,9,828,241,737,449,112,658,216,288,674,679,888,199,640,998,419,407,453,406,295,88,1000,402,826,267,410,685,292,445,319,234,215,490,233,258,55,524,371,113,984,694,502,194,239,373,459,741,355,599,868,169,660,597,687,406,770,906,510,713,108,910,114,277,360,124,756,897,453,228,965,481,762,147,384,420,624,922,427,282,316,529,306,780,48,684,66,700,601,233,372,739,71,410,430,943,642,573,400,827,215,668,235,577,658,11,797,75,440,402,312,764,775,738,257,849,325,658,884,736,670,394,371,653,497,193,342,924,243,864,243,434,888,7,636,696,162,735,744,559,461,666,524,27,788,374,446,564,815,981,11,837,928,844,403,50,581,643,352,640,59,495,139,534,526,913,539,82,669,239,82,504,264,786,281,236,444,88,745,125,87,878,904,110,654,126,567,740,947,839,485,12,439,656,192,57,109,866,692,538,458,808,739,427,525,178,735,500,123,425,690,219,391,703,878,71,582,159,846,203,924,138,428,517,659,62,391,900,599,377,966,612,627,17,26,436,694,246,840,907,985,668,995,373,446,236,350,671,790,532,702,659,2,396,213,945,253,902,706,873,961,808,451,529,298,938,883,333,638,992,437,467,979,818,220,593,538,672,679,865,939,759,679,840,531,440,348,444,341,676,161,895,764,814,86,559,879,648,344,872,915,448,654,706,974", "286,500,967,106,735,823,163,953,855,984,203,778,21,147,141,384,302,66,640,149,936,273,306,925,852,378,77,520,899,204,115,763,536,701,285,411,568,350,358,617,398,147,138,82,929,541,967,661,667,335,150,533,545,821,108,104,404,36,166,486,130,920,322,704,228,247,47,255,20,505,59,780,679,370,241,62,955,211,904,583,143,43,246,636,868,110,984,328,239,459,886,38,993,954,769,29,235,810,65,666,284,191,775,41,933,275,911,692,632,650,766,472,627,14,782,328,335,402,798,873,519,542,969,415,766,617,911,896,115,423,616,461,607,789,468,114,722,593,274,446,629,279,105,993,463,69,979,688,240,573,859,232,584,36,858,753,641,43,493,567,815,551,922,722,879,831,330,319,496,968,223,930,427,943,615,563,144,96,761,868,858,464,672,366,926,236,953,835,133,945,846,286,805,38,38,759,412,396,574,104,434,34,443,894,193,409,840,190,718,350,230,742,619,880,190,834,464,950,898,629,168,563,243,830,343,785,644,528,700,629,34,636,727,486,503,523,384,407,82,845,671,152,49,287,419,542,545,101,806,762,518,599,613,546,274,328,879,384,604,637,167,438,995,874,247,187,198,582,323,777,261,305,545,138,848,114,190,934,178,619,247,228,900,873,680,391,711,947,853,320,43,641,587,5,382,513,722,401,844,224,154,514,616,473,97,458,281,851,499,3,985,691,57,882,688,935,6,290,566,840,530,880,249,83,107,515,586,226,873,415,462,314,227,144,215,45,559,506,528,17,238,353,135,622,595,361,661,220,195,149,237,705,591,583,114,938,197,779,843,559,221,437,377,520,313,782,113,437,141,941,95,909,270,321,589,784,80,326,546,346,981,258,596,494,385,465,227,755,838,284,671,436,435,151,241,993,261,17,295,745,113,623,594,251,426,409,683,531,978,258,356,24,66,330,627,194,759,322,352,650,187,531,906,353,268,133,390,704,166,703,922,504,412,750,605,985,751,599,470,566,100,175,43,483,395,495,480,684,808,959,632,416,112,27,669,846,608,773,422,973,729,163,807,167,299,650,92,705,676,780,523,548,51,305,627,916,669,395,567,452,352,513,756,216,969,305,231,772,526,603,53,223,500,895,806,440,884,599,48,46,375,474,942,493,325,8,107,986,845,35,865,488,788,736,755,703,373,131,43,78,159,321,788,23,604,170,539,729,365,274,908,797,57,940,831,645,423,484,514,147,983,322,119,643,123,765,604,109,153,345,923,173,409,892,111,709,432,118,808,598,553,45,371,937,219,4,355,82,549,504,249,410,679,309,86,414,955,320,325,171,56,835,301,330,126,348,682,480,884,879,870,72,644,385,148,493,966,534,571,796,502,414,622,847,703,502,269,966,773,180,812,600,720,885,192,111,505,973,699,817,730,437,508,706,708,36,429,318,633,320,959,648,923,405,76,283,542,949,721,283,0,664,657,471,953,270,401,461,390,23,974,733,727,828,899,952,406,286,362,677,650,247,88,159,573,772,531,392,500,63,679,43,694,801,225,198,497,84,999,48,24,493,170,467,518,426,720,938,576,370,491,863,90,261,684,491,414,927,717,323,305,740,926,712,90,245,705,931,105,307,619,136,464,708,752,646,233,507,681,132,147,913,582,154,740,799,511,979,69,610,418,290,716,92,532,85,913,883,781,344,919,174,858,737,533,614,560,85,100,863,348,162,877,292,454,698,529,914,77,144,7,382,402,861,537,503,240,339,578,515,482,150,394,280,296,462,813,843,931,771,217,958,184,162,457,585,552,120,532,857,730,376,74,503,609,541,671,232,401,70,684,513,715,19,774,13,570,370,307,59,958,735,231,700,859,607,9,589,172,336,468,358,260,756,611,272,344,5,764,57,481,5,567,125,172,127,38,538,439,634,569,254,106,115,244,594,690,820,887,7,511,81,740,883,824,907,854,882,300,74,892,306,60,445,359,78,926,547,184,57,765,95,170,856,308,630,189,703,263,826,513,345,712,274,129,597,849,844,671,129,647,193,169,673,614,904,150,181,135,800,285,921,235,923,923,433,680,506,687,473,214,315,206,439,194,739,645,555,281,418,612,760,318,454,935,316,44,425,263,564,442,340,625,60,806,103,551,668,435,146,98,863,820,21,50,167,667,519,351,509,169,380,182,89,38,358,57,429,969,227,971,90,687,199,325,134,744,873,165,833,595,690,112,217,279,895,30,108,344,758,211,693,937,905,414,872,466,200,299,704,309,435,701,460,985,614,503,299,260,883", "275,276,206,322,829,430,389,103,230,718,567,677,896,945,107,475,382,369,747,237,358,877,511,364,120,693,337,996,604,814,517,653,654,829,55,884,163,985,450,550,889,714,361,516,402,661,886,164,145,929,613,567,121,853,240,463,50,963,625,246,563,889,73,397,853,649,940,531,808,138,190,629,666,114,896,62,144,422,467,84,861,430,773,259,479,387,688,131,770,911,359,801,933,802,271,21,98,958,136,936,573,345,832,728,654,636,813,303,460,686,402,918,830,500,387,718,593,295,848,127,419,445,972,557,940,863,778,598,379,401,172,157,867,205,631,821,905,193,85,895,574,96,452,751,925,136,713,989,465,632,287,34,147,270,372,181,983,487,324,922,621,958,885,373,427,365,998,680,132,157,190,308,766,222,221,932,359,611,667,187,938,643,881,939,721,231,626,872,154,687,304,219,754,707,678,927,254,33,664,420,775,221,825,484,46,782,542,788,349,442,564,89,237,114,953,751,989,205,960,189,722,700,106,130,541,25,220,230,758,360,695,246,296,743,537,679,549,103,477,98,61,625,743,488,372,9,520,256,611,383,334,300,527,136,811,640,954,569,909,930,318,764,228,704,426,100,693,234,956,630,277,327,433,558,626,52,324,566,628,319,335,522,451,379,510,50,565,692,387,653,307,778,789,599,619,834,411,239,935,574,134,239,630,649,482,146,656,491,446,54,805,171,182,247,223,579,642,245,44,314,176,559,722,588,431,4,489,823,424,217,757,273,527,74,550,902,217,51,783,757,86,741,552,742,256,900,348,996,664,231,759,220,241,53,882,400,487,723,996,5,660,492,321,827,163,527,455,674,82,820,109,968,479,944,230,668,946,12,691,790,68,734,424,285,953,156,487,183,203,751,509,248,64,42,448,378,64,751,4,295,306,517,308,418,608,579,846,492,573,667,449,458,451,925,66,694,799,672,104,205,291,467,53,705,780,284,586,593,750,928,955,546,836,929,718,331,52,882,238,535,458,952,694,143,360,2,59,688,175,555,649,353,569,771,537,360,778,320,20,958,350,79,725,865,786,500,613,28,720,227,73,233,570,931,484,675,209,699,632,282,184,444,757,356,159,796,698,772,626,400,630,940,191,234,936,222,392,79,314,884,830,857,665,821,454,147,284,130,119,351,362,380,605,876,940,974,323,759,375,370,58,479,372,941,470,184,105,853,566,173,695,148,558,906,527,347,2,526,366,246,414,595,389,938,87,282,265,609,357,245,631,86,297,198,166,410,730,195,86,794,449,977,796,561,546,830,600,744,83,926,837,107,506,392,434,771,480,28,7,315,513,177,420,739,637,556,981,930,585,55,898,896,24,719,856,745,602,157,965,983,342,457,122,717,182,624,273,140,906,67,533,538,440,458,936,403,192,60,586,643,95,746,417,967,959,54,983,133,11,338,497,960,112,327,143,927,491,225,377,628,664,0,251,288,442,642,221,706,972,11,761,773,23,296,928,829,859,185,237,452,398,417,410,819,830,431,755,996,247,959,885,555,329,612,34,151,345,141,418,249,29,873,166,165,239,963,871,47,983,238,981,960,704,220,953,938,287,191,370,37,597,487,473,671,534,674,103,601,614,520,862,12,723,599,620,589,891,857,296,862,471,196,349,100,902,584,537,559,690,112,978,64,766,719,229,632,348,259,738,96,892,305,836,310,766,929,741,841,243,950,304,130,616,373,199,43,576,875,797,187,906,218,322,572,88,875,315,823,566,302,89,6,685,82,773,227,920,257,141,398,446,966,454,582,802,639,342,859,519,888,52,221,495,791,571,15,184,147,712,657,490,351,315,969,15,284,550,684,877,983,609,633,611,303,65,906,840,794,897,93,119,376,630,173,841,882,475,182,147,915,573,244,773,823,618,559,327,489,420,63,720,990,383,741,488,350,731,270,651,175,944,322,777,639,637,912,917,114,28,128,665,732,76,641,369,663,179,998,104,320,781,128,464,930,298,535,71,738,497,448,874,744,923,162,696,922,137,284,724,319,875,700,123,42,507,943,735,799,367,359,674,49,765,348,30,416,910,956,724,700,141,771,718,53,200,886,560,260,118,667,410,376,654,484,995,415,492,10,430,718,187,276,525,103,894,937,845,39,871,361,711,527,793,440,896,939,791,146,543,381,232,162,598,549,638,425,653,243,528,176,389,367,702,667,496,200,245,619,520,93,740,355,777,417,408,297,301,239,294,440,618,353,652,833,378,162,558,959,354,350,247,347,700,832,225,787,725,647,986,593", "297,191,595,482,644,75,26,928,680,795,907,102,200,380,685,122,496,967,489,289,741,967,370,323,330,673,287,302,25,793,48,848,42,823,602,573,891,52,705,517,496,914,181,679,889,670,454,832,94,205,530,232,371,878,56,818,697,517,560,138,271,826,329,162,769,906,604,343,276,710,356,642,198,547,460,537,659,775,220,97,716,1,516,123,187,227,490,866,76,409,529,462,652,138,366,57,283,43,671,864,13,439,692,918,239,297,908,166,3,648,731,380,188,283,811,467,513,956,815,443,180,222,894,264,362,594,705,196,833,748,421,960,649,135,603,803,217,627,156,716,180,723,124,473,162,788,569,221,180,287,667,116,31,98,938,810,333,512,205,442,54,551,78,398,242,523,745,533,429,427,574,679,638,941,901,662,851,371,530,206,607,773,160,944,908,65,865,935,540,286,860,475,443,692,640,776,711,152,325,686,800,840,658,11,609,65,866,364,240,971,825,641,17,4,499,848,784,693,774,235,106,420,574,666,622,703,753,319,216,304,521,414,47,250,903,554,279,670,5,553,721,194,365,193,470,38,122,407,521,69,825,435,159,675,442,361,105,551,664,107,436,45,992,188,313,883,951,308,150,764,663,994,835,629,120,537,850,631,839,846,884,720,809,832,353,299,127,191,618,808,360,394,329,511,695,687,136,748,850,933,299,397,677,23,706,188,870,590,250,171,228,612,385,637,249,122,554,410,767,311,524,435,339,393,266,38,117,932,391,282,809,408,143,838,591,983,278,613,876,35,298,404,862,599,979,45,440,218,814,996,703,976,834,406,363,821,522,466,559,385,318,953,74,335,696,242,22,819,454,812,447,853,533,672,909,757,714,818,667,315,822,674,696,119,590,390,510,247,20,381,504,743,172,532,199,266,786,333,289,862,731,859,869,917,212,319,529,176,670,586,514,145,222,656,777,492,805,623,549,920,354,263,129,243,24,977,521,866,924,602,225,430,454,562,831,525,970,388,83,566,450,905,884,923,71,884,812,815,905,634,23,382,132,335,60,624,727,148,138,919,396,900,260,216,207,400,907,507,666,788,316,484,961,921,72,208,858,756,610,289,568,860,657,664,978,61,91,588,676,24,667,551,872,923,254,143,219,631,404,296,710,863,978,673,741,240,510,471,218,45,810,759,764,311,696,544,418,306,376,675,775,472,791,522,279,590,732,825,621,240,469,499,563,810,840,519,53,479,969,96,210,723,462,989,471,549,663,489,533,259,430,539,570,37,273,924,854,703,690,868,388,2,885,243,226,285,151,87,437,820,466,758,555,357,949,777,530,966,240,320,730,603,831,389,569,239,731,233,837,439,733,941,773,67,903,126,477,406,882,859,143,308,182,58,364,169,644,371,67,907,857,806,607,472,49,964,645,419,413,215,770,184,853,131,743,464,600,842,954,882,850,680,444,341,75,147,533,337,80,859,657,251,0,446,559,783,318,430,505,753,114,970,341,959,915,433,413,759,228,282,395,915,717,654,591,437,436,855,896,102,653,316,698,118,119,186,823,173,665,870,831,648,599,75,393,914,766,957,944,392,931,402,995,597,97,675,349,820,655,506,689,957,824,901,797,413,382,263,768,229,122,613,276,803,256,356,819,617,138,667,761,504,518,672,187,240,255,592,132,369,118,226,222,137,822,941,44,317,550,166,916,27,888,404,289,778,167,12,947,889,760,498,127,453,483,566,441,873,535,426,160,306,628,807,705,139,251,199,75,808,330,586,719,209,741,558,269,936,608,539,988,681,409,874,637,535,393,679,878,457,535,881,981,260,387,635,557,986,962,152,916,149,259,869,623,865,41,877,224,340,276,858,585,193,892,204,762,896,741,472,992,243,670,932,189,276,838,507,237,150,181,303,135,604,63,25,309,485,953,809,51,667,614,240,588,606,83,277,625,967,38,556,844,166,314,300,314,147,53,640,579,926,885,931,973,984,256,953,617,261,847,227,465,581,567,603,220,665,834,179,155,200,886,152,336,883,573,426,187,452,975,289,571,853,712,59,588,145,367,352,149,955,973,974,64,979,895,811,499,569,334,640,535,75,987,173,834,838,428,818,788,230,743,555,509,20,707,318,168,628,586,423,222,99,121,100,38,605,163,869,842,877,506,765,228,564,50,896,467,704,781,505,946,819,65,54,173,757,295,37,811,24,134,639,436,27,2,137,306,830,216,941,211,672,498,339,835,537,832,202,186,697,298,828,755,389,139,163,226,986,843,933,774,56,940,627,749,644,51,271", "246,218,5,542,115,619,543,855,931,346,724,220,46,128,297,722,983,253,720,836,460,903,798,753,999,67,838,87,416,234,146,460,784,127,298,921,798,657,691,907,67,775,843,543,211,407,51,790,650,12,755,778,109,851,921,125,511,601,17,770,938,322,50,496,354,257,800,350,270,145,727,686,45,276,73,42,756,909,274,438,713,349,138,798,122,825,622,751,120,267,39,553,670,636,895,809,721,684,519,596,36,212,899,866,768,972,164,885,902,61,874,41,201,531,26,457,597,740,553,748,3,175,829,829,9,369,173,902,754,43,900,19,474,692,611,917,463,950,966,556,747,132,21,352,558,484,33,662,315,749,140,227,355,680,116,512,56,691,591,162,373,721,701,974,424,445,408,631,747,510,972,234,825,340,398,521,727,601,836,591,410,65,220,58,271,712,502,44,587,531,502,915,631,905,813,709,317,38,379,825,533,457,345,90,937,138,413,738,759,455,338,53,706,978,933,649,808,219,170,585,108,128,811,139,754,408,338,854,307,348,260,160,763,433,432,552,294,442,382,916,154,580,656,274,888,301,633,608,57,770,17,287,226,530,339,15,568,946,108,382,241,440,603,751,908,175,259,796,653,360,398,813,943,769,123,49,174,29,59,2,434,2,872,829,692,687,26,757,154,983,872,873,587,44,156,601,226,964,791,901,505,12,586,385,797,994,236,990,231,17,51,410,246,623,196,326,880,676,716,505,743,605,192,739,908,482,965,83,440,950,331,97,80,159,276,16,40,662,119,701,72,924,210,725,622,680,484,163,502,564,606,200,165,20,970,343,157,800,903,560,705,689,542,674,130,384,837,974,855,103,855,219,858,7,283,273,507,331,938,434,708,432,459,422,46,8,989,659,603,111,595,315,492,164,750,560,701,593,713,184,145,175,738,813,460,516,360,551,354,524,207,980,953,165,330,111,51,768,367,246,280,124,441,668,295,793,799,807,699,521,501,754,728,999,503,713,500,248,100,410,359,907,994,103,716,691,919,480,467,699,310,275,787,417,468,904,919,432,67,910,583,909,746,336,168,716,569,444,816,894,643,139,177,4,441,216,951,770,673,169,236,552,512,347,572,411,269,624,997,31,994,696,629,580,558,652,527,739,823,596,430,750,594,636,114,672,314,251,983,125,169,240,10,37,812,734,492,373,807,325,836,136,892,800,585,397,731,68,739,570,508,684,878,489,257,992,757,54,822,628,168,160,889,449,934,858,249,232,585,807,739,761,278,635,134,231,281,338,16,731,321,574,223,827,930,93,893,588,361,152,457,834,100,553,350,679,765,793,670,867,67,125,714,504,542,273,949,441,259,733,135,283,328,420,475,291,881,325,490,340,796,287,933,245,343,116,770,258,615,358,290,657,918,10,995,897,184,883,770,18,644,440,948,720,736,659,462,156,152,427,760,635,393,479,278,956,958,989,949,464,471,288,446,0,664,858,119,754,875,334,368,403,750,767,292,11,204,744,186,579,390,367,482,160,594,276,852,846,164,869,494,155,920,205,530,872,764,473,7,804,793,662,792,919,228,821,264,312,172,246,955,689,888,255,870,132,887,444,740,927,505,866,198,608,580,984,607,281,338,791,877,696,253,109,541,890,384,224,193,700,671,520,632,400,578,49,719,803,433,286,289,201,596,62,307,972,787,95,655,416,903,860,259,293,820,481,520,857,271,87,14,793,424,199,769,29,512,797,281,143,49,426,498,448,770,165,561,282,194,728,697,317,175,588,206,918,551,523,383,868,714,973,194,74,924,39,373,860,179,179,584,461,923,643,627,294,419,432,23,832,93,542,910,220,251,647,994,25,868,602,46,340,771,75,422,534,329,729,562,870,351,277,769,279,110,910,514,790,584,510,64,660,69,690,51,190,595,349,562,244,497,239,690,251,358,342,599,417,692,264,759,731,21,40,267,604,290,428,459,190,303,15,832,969,661,535,891,667,713,472,343,696,493,876,726,727,129,109,874,259,12,16,915,130,536,433,294,97,243,437,49,570,78,473,454,947,272,252,260,372,657,957,556,369,70,230,350,738,439,985,426,416,981,348,180,843,378,233,638,815,18,525,42,916,546,137,574,499,766,680,373,655,537,489,379,921,872,550,698,317,143,63,723,597,924,192,135,517,70,183,10,651,262,230,278,322,528,393,80,258,966,271,249,349,143,204,391,9,282,994,181,48,325,567,753,313,862,757,896,84,160,37,329,641,810,362,559,136,904,369,594,216,338,313,13,462,520,484,207,672", "904,503,895,746,935,463,593,883,594,773,602,511,535,334,353,690,238,717,504,116,348,770,518,805,576,25,695,762,476,293,524,527,753,524,499,914,167,507,55,830,520,347,11,849,474,124,35,549,491,628,484,387,603,582,210,126,459,574,846,701,449,512,504,579,73,516,488,223,335,854,35,742,832,753,212,25,358,407,153,24,525,688,222,787,950,838,657,325,412,910,585,216,896,436,225,554,74,846,165,775,551,762,733,159,748,806,716,875,938,424,95,578,374,41,371,297,36,807,937,363,740,547,77,193,20,319,228,719,910,194,48,318,444,213,382,202,365,296,290,872,125,644,37,598,921,56,797,280,606,629,498,132,196,800,461,436,565,552,643,419,937,243,65,466,968,995,84,831,265,23,380,827,655,994,364,256,113,479,764,870,359,43,916,387,842,120,71,942,133,920,28,512,962,772,928,996,583,580,606,952,936,714,287,149,516,195,722,261,211,207,271,767,436,646,525,671,194,355,626,217,780,135,538,882,267,159,474,442,234,147,315,175,199,254,120,953,178,934,295,403,505,595,422,53,65,637,903,651,533,342,712,9,68,378,77,625,215,638,909,732,988,83,485,834,108,751,194,299,897,877,103,869,631,727,627,975,657,329,155,986,396,487,270,854,595,646,86,419,799,440,721,82,581,798,506,132,884,778,534,940,809,634,50,808,233,300,854,302,689,381,702,839,384,282,546,562,455,477,385,58,158,30,481,81,574,371,517,618,710,756,372,412,491,743,658,942,937,83,279,261,184,753,857,848,159,304,404,856,357,529,205,854,421,754,532,790,956,778,225,622,534,118,233,301,180,911,495,661,553,607,553,699,360,403,361,18,339,243,625,923,816,348,854,455,629,912,313,696,739,596,54,242,589,506,867,156,924,717,839,549,733,380,355,727,960,55,956,52,386,590,561,466,242,395,638,584,195,747,963,2,574,456,630,16,972,70,236,779,299,664,867,517,429,717,571,413,26,172,492,42,917,730,106,449,408,997,36,445,265,354,420,937,642,867,123,251,352,798,259,27,763,520,446,260,686,519,286,44,770,490,984,80,778,670,139,804,907,862,520,992,513,265,847,111,658,73,355,918,961,646,32,278,841,97,129,609,864,379,720,945,859,848,841,186,853,442,633,168,456,465,252,431,666,248,105,955,831,832,656,650,353,336,819,432,785,820,296,125,29,3,71,478,615,219,317,559,241,66,117,396,796,55,561,25,136,839,250,887,970,758,685,83,397,822,369,957,623,251,662,577,586,330,62,793,71,169,744,225,644,811,386,953,747,545,582,96,429,263,145,917,559,424,122,484,477,531,93,39,70,997,922,92,311,668,742,709,865,755,829,533,408,394,812,980,158,230,940,289,760,446,874,55,787,587,457,270,353,738,162,98,442,458,563,710,845,23,161,209,76,496,395,584,106,790,933,966,773,594,853,747,953,442,559,664,0,97,986,905,337,344,463,499,723,698,486,582,845,713,448,318,615,773,920,397,785,805,655,836,234,146,338,827,711,135,791,741,60,970,225,223,220,862,529,268,185,370,664,327,583,990,521,983,451,376,996,502,118,793,120,356,362,754,509,820,265,245,14,39,459,914,377,778,577,842,201,625,934,800,660,524,977,535,779,985,11,609,469,476,2,739,823,488,469,810,656,17,403,596,364,795,574,9,515,165,902,816,356,781,480,190,752,32,35,553,209,673,635,679,459,657,70,147,617,625,682,962,478,216,20,534,965,963,625,364,96,455,851,490,141,730,208,955,336,110,742,396,787,496,114,269,514,448,645,974,345,750,773,382,745,345,549,381,314,501,737,727,666,911,537,42,787,433,396,545,540,465,599,596,298,188,703,704,728,934,694,597,225,154,179,235,588,205,730,72,140,597,171,34,453,588,298,66,616,463,182,443,881,722,204,348,869,489,430,76,65,894,357,913,833,30,372,627,865,444,714,881,141,304,992,538,997,583,974,896,452,936,296,400,860,369,617,132,140,595,681,725,480,828,965,781,271,886,556,221,506,100,939,354,152,907,662,668,96,909,335,548,123,103,410,762,160,15,761,963,860,395,415,539,361,948,384,923,366,673,385,975,314,988,308,540,104,157,199,169,424,623,730,282,289,785,84,576,731,302,190,823,431,663,696,105,483,64,61,338,107,324,106,130,637,302,722,11,582,877,861,448,628,761,784,841,293,493,930,77,158,858,896,320,109,545,581,403,942,737,669,937,678,33,839,64,751,148,49,305,367,732,426,24,14,385", "24,751,787,391,807,196,847,117,105,259,150,303,366,866,357,676,182,587,350,171,520,491,659,614,938,618,521,501,775,377,794,641,583,892,188,813,723,274,899,79,163,855,927,121,579,243,348,340,307,580,624,742,475,732,211,268,899,325,259,614,669,735,942,460,381,128,498,708,800,953,271,622,325,301,802,885,473,927,892,375,733,814,166,491,179,817,918,33,138,690,202,693,314,823,659,956,815,736,485,710,252,47,80,732,559,459,240,497,645,243,655,655,895,212,199,968,423,414,181,838,342,509,724,78,362,506,156,261,500,389,691,926,644,105,743,441,843,296,384,331,230,750,348,663,946,735,816,85,869,782,455,832,369,604,154,43,263,778,841,293,894,920,465,75,129,624,162,570,258,444,574,760,298,109,976,658,763,70,820,188,245,608,462,870,571,710,607,831,167,916,300,778,799,22,981,375,530,714,759,772,750,80,189,998,249,905,887,386,248,629,396,61,149,300,724,928,359,650,801,247,13,284,20,126,338,83,136,629,230,750,887,865,590,862,659,931,16,78,271,944,189,681,110,904,65,119,842,324,737,562,827,613,643,535,171,186,16,830,55,2,269,732,130,885,609,728,579,957,839,532,861,355,24,24,497,871,42,488,76,586,508,24,732,202,756,38,565,389,929,340,224,185,564,703,998,743,523,292,33,952,712,851,590,274,781,531,70,443,952,319,98,958,664,1,229,15,407,3,333,985,117,899,870,567,714,167,188,806,908,177,114,33,274,434,252,488,169,483,544,919,738,203,191,448,373,618,232,297,296,37,50,886,16,786,831,843,181,388,177,402,618,57,240,534,159,835,651,121,296,656,669,75,617,544,672,123,997,596,287,719,668,550,741,317,25,937,258,919,864,576,15,942,25,544,411,558,579,728,327,421,294,972,462,932,740,377,33,879,887,477,558,481,856,273,595,745,252,135,937,717,897,842,175,339,83,985,905,746,242,803,609,354,831,688,639,730,100,671,745,811,464,695,631,419,999,337,870,33,965,881,467,640,526,523,210,480,204,155,985,846,160,936,359,584,965,597,280,20,828,661,611,742,284,859,243,729,68,197,760,571,708,118,579,598,895,464,224,869,299,971,822,459,544,673,406,845,469,62,736,30,905,441,588,444,15,251,899,585,376,174,328,517,61,915,27,224,283,911,310,421,520,303,153,957,652,763,808,146,553,52,297,136,836,245,821,867,83,693,557,74,146,133,924,217,655,308,829,537,641,94,682,153,903,459,911,839,885,422,432,116,154,534,628,798,967,108,621,74,300,804,430,800,296,682,723,283,576,926,940,592,367,521,112,870,511,853,463,633,317,581,438,503,198,244,494,360,761,72,731,900,738,943,538,270,291,793,584,708,937,416,777,112,61,256,679,449,602,35,638,509,322,318,49,898,490,924,644,509,794,818,743,119,7,561,872,63,883,294,851,825,270,642,783,858,97,0,991,480,901,265,246,391,648,119,187,710,45,35,507,359,646,846,997,582,510,89,501,266,217,121,143,28,475,599,955,304,666,70,196,92,436,670,658,654,483,281,984,665,303,139,283,419,906,112,873,483,349,687,143,16,896,973,472,500,499,905,691,743,640,761,263,633,440,414,178,848,697,14,462,75,37,724,816,805,853,631,315,213,158,870,931,609,160,507,221,921,576,261,277,663,777,876,713,431,115,565,452,576,443,432,957,801,10,839,55,684,109,610,907,629,205,881,464,754,130,835,44,865,590,674,234,871,818,822,511,749,744,25,763,301,601,991,876,349,234,319,586,862,903,380,427,242,404,499,602,131,449,645,363,620,674,494,790,402,989,665,731,334,4,114,707,174,738,510,891,124,468,582,736,384,501,583,186,481,246,793,874,716,17,359,429,485,115,667,523,907,149,316,451,923,425,10,980,58,641,275,528,799,579,722,204,309,921,754,822,929,379,420,711,112,894,242,504,453,224,233,557,591,504,300,853,152,218,590,109,258,654,429,451,6,5,290,28,637,363,243,239,899,743,410,442,104,130,8,560,210,790,696,676,279,471,10,239,555,52,989,504,518,790,355,665,644,229,246,659,460,70,779,507,779,259,314,767,996,336,816,345,314,901,869,817,565,327,544,137,714,196,412,791,315,556,458,878,954,851,16,435,435,205,427,728,475,313,58,691,194,257,11,883,925,262,179,12,322,942,276,324,993,700,487,873,168,582,385,443,149,563,15,549,754,87,108,83,142,648,435,630,406,772,660,485,961,107,818,113,800,952,20,412,396", "327,994,47,529,283,760,648,45,617,546,442,585,258,16,159,805,303,582,154,757,947,579,195,138,56,81,479,892,613,643,185,529,438,536,831,408,205,686,999,529,352,130,22,300,910,513,832,690,674,921,49,111,4,431,410,894,58,210,342,14,431,90,594,133,915,723,98,499,720,314,639,587,834,52,263,831,535,30,138,579,38,566,490,895,771,221,394,878,306,657,978,388,131,834,57,95,478,796,621,819,707,753,459,411,701,51,98,406,157,554,465,998,637,381,175,428,43,160,117,409,79,130,517,984,166,294,931,642,621,530,903,902,608,372,770,443,780,855,925,832,963,396,936,292,959,853,466,249,442,86,255,549,119,492,110,614,557,263,371,886,14,442,986,578,210,884,638,594,22,693,664,886,35,903,859,223,467,884,381,519,43,189,204,124,780,746,121,570,23,116,696,174,166,796,360,222,704,243,680,544,516,769,93,275,630,187,406,834,421,336,752,288,110,129,80,74,909,937,894,145,557,948,385,945,191,761,798,766,827,153,873,513,256,517,802,276,462,298,571,353,357,259,756,815,390,486,639,12,237,739,599,794,905,679,782,180,961,9,566,308,442,61,230,645,787,899,676,380,881,420,805,634,818,117,316,332,63,961,260,211,208,69,311,67,996,378,84,132,318,139,223,338,64,362,967,43,943,217,364,194,762,814,555,926,594,244,108,501,903,613,630,410,562,920,606,41,75,530,120,233,93,936,211,896,408,280,776,919,253,349,325,278,695,536,908,292,183,219,543,636,218,112,583,308,617,945,226,554,850,382,959,700,234,763,247,719,698,870,353,838,675,965,638,329,913,271,669,928,531,994,410,764,573,887,193,301,377,268,304,76,693,154,823,622,852,551,414,663,863,49,541,550,966,648,369,368,948,586,830,893,351,735,67,532,176,182,771,863,523,339,17,95,917,901,575,582,249,952,72,721,179,113,673,661,438,707,694,220,58,280,177,502,240,2,261,299,149,79,881,545,643,95,100,238,846,229,143,954,742,847,532,666,560,203,670,222,253,931,430,757,967,604,96,833,639,390,233,904,332,368,78,52,978,737,277,795,404,908,450,349,92,274,923,88,568,808,315,709,121,81,433,198,567,807,164,246,812,379,336,216,59,1000,841,388,185,323,701,72,379,163,267,30,668,990,518,712,158,977,925,444,122,193,974,192,876,91,997,196,607,206,236,264,897,267,144,362,871,490,453,708,349,302,933,230,503,730,493,986,684,414,925,507,741,188,19,342,24,957,255,74,46,479,336,682,370,924,628,482,729,104,569,293,86,815,395,339,628,241,849,913,658,583,769,748,570,375,704,838,717,380,19,53,768,527,762,124,595,155,966,718,275,943,793,159,525,402,269,490,156,68,144,652,395,243,733,737,327,795,13,546,172,856,782,851,48,393,875,804,938,217,459,684,557,633,332,687,472,660,99,67,401,221,318,119,986,991,0,581,985,669,360,135,140,232,42,748,995,874,468,866,312,97,496,92,353,400,598,559,357,126,906,908,361,902,266,570,438,713,224,968,954,308,400,178,747,247,366,300,335,379,363,954,109,440,664,165,285,255,150,470,834,78,505,328,9,731,700,387,160,252,710,989,323,19,626,680,331,421,233,348,467,939,300,707,689,201,411,726,651,350,440,781,673,939,794,940,118,169,97,783,60,921,402,822,324,53,747,810,665,814,937,801,203,35,257,80,519,457,59,876,204,715,244,83,298,159,577,43,431,580,547,680,236,199,20,193,357,935,894,854,604,874,605,900,360,474,643,188,981,177,862,728,400,968,724,513,502,515,6,740,495,854,392,978,900,217,534,50,899,29,512,143,128,239,761,694,484,235,406,701,385,401,484,218,820,1000,988,407,388,949,652,132,305,230,734,95,183,83,124,220,429,441,889,611,726,658,303,954,493,353,100,56,570,327,197,705,259,265,761,107,608,677,756,838,987,188,751,985,976,10,765,73,474,709,68,163,972,729,486,48,473,4,930,538,381,852,528,404,473,956,11,452,604,117,675,784,503,379,74,979,7,172,209,570,72,111,526,565,861,695,128,57,660,140,192,870,33,358,327,643,792,330,421,897,184,210,611,669,767,45,25,663,657,891,595,337,569,628,682,853,455,100,833,441,55,458,857,836,455,278,848,234,635,563,975,421,123,281,845,734,90,713,297,243,270,920,424,433,261,689,57,429,606,594,814,735,457,802,4,329,2,745,219,232,666,65,26,746,309,410,347,651,716,431,419,131,667,628,153,362", "474,171,844,74,48,490,138,955,359,564,336,5,858,356,158,149,380,774,681,111,474,350,752,576,459,673,623,149,505,148,695,585,48,484,457,647,130,955,97,386,230,141,26,520,285,419,965,805,941,177,30,6,750,922,127,203,868,671,551,686,569,834,227,348,774,574,431,692,715,271,951,408,768,330,944,168,960,107,425,942,20,120,600,154,452,404,432,736,99,793,163,627,11,333,507,484,205,619,847,418,881,530,70,759,622,438,522,885,963,595,801,423,647,404,982,449,43,925,96,112,695,693,436,360,652,383,269,580,228,702,219,574,281,626,240,973,752,739,412,130,50,312,212,352,646,879,112,203,818,682,646,698,122,989,121,950,791,670,848,680,440,622,243,858,323,600,324,3,899,388,170,203,749,60,164,89,705,129,155,583,801,487,395,50,853,185,452,550,854,532,457,668,956,175,43,872,501,920,897,406,630,5,105,539,52,52,55,184,47,101,850,367,583,470,559,233,470,663,429,894,32,140,102,550,835,24,860,364,970,257,245,114,949,804,734,176,208,118,161,844,212,337,12,672,814,965,796,26,228,85,830,19,171,591,716,206,142,760,867,33,562,292,335,617,654,450,734,863,152,596,573,627,270,932,657,738,562,635,606,112,305,529,383,959,39,763,103,410,643,345,99,228,76,925,385,614,609,742,574,241,115,274,267,436,642,979,859,284,773,340,312,821,151,93,739,897,868,828,849,531,301,306,193,977,215,243,620,829,630,110,604,298,4,596,788,455,208,160,256,183,283,918,249,175,866,568,855,816,805,140,761,881,868,536,198,53,792,473,56,260,604,945,141,849,244,546,114,857,866,425,206,655,373,344,970,917,383,366,189,12,220,994,479,935,810,45,9,949,135,197,329,194,332,501,647,587,632,14,735,340,924,22,132,155,564,356,286,206,77,305,971,63,618,749,414,799,927,695,694,573,432,598,590,511,896,872,901,402,256,510,238,693,640,708,226,735,421,232,628,960,670,222,848,748,999,518,186,430,242,288,419,776,984,412,261,483,927,138,635,734,119,586,812,304,861,469,886,174,504,429,219,433,942,382,223,420,363,790,555,141,984,375,892,279,911,978,795,266,71,887,268,801,948,887,148,397,713,166,441,567,902,283,829,245,790,816,629,124,310,452,40,865,221,558,482,735,660,690,921,393,17,750,157,371,583,141,603,94,484,575,572,478,449,271,84,598,877,305,360,230,358,416,217,168,657,495,264,824,958,644,494,544,811,528,937,772,754,169,173,944,743,696,943,838,981,789,460,341,241,640,360,592,140,478,68,702,268,836,316,53,826,290,439,436,604,491,383,938,529,281,356,414,144,234,969,29,769,609,439,235,288,70,203,140,207,24,906,454,380,437,335,848,657,441,132,901,922,910,191,504,892,100,529,65,908,434,428,650,923,330,763,465,715,885,610,458,355,688,570,366,461,706,430,754,905,480,581,0,992,825,975,951,899,970,424,444,595,107,646,905,929,305,436,862,862,829,930,436,270,31,197,897,307,275,938,174,704,826,599,547,735,517,745,554,885,510,14,942,628,794,426,5,625,445,908,835,688,911,899,583,65,887,806,368,361,35,3,608,186,920,987,231,916,489,349,211,834,181,920,176,177,489,74,624,372,565,771,349,307,604,852,157,13,788,63,37,102,771,167,115,963,2,23,627,179,718,789,367,679,150,629,195,702,446,616,519,511,642,297,328,414,318,759,312,720,249,767,396,368,682,914,121,450,302,578,716,768,621,68,277,561,277,294,579,420,466,389,583,233,224,121,134,420,213,117,284,489,397,464,590,683,236,342,45,615,79,6,748,104,301,887,595,114,906,29,600,392,406,958,141,947,599,641,601,85,67,526,93,668,753,888,162,362,34,524,598,363,715,520,828,709,181,462,597,832,952,427,46,210,534,376,28,929,958,499,552,977,457,204,526,40,821,144,451,485,546,180,545,331,209,727,466,389,1000,480,603,347,424,386,839,209,451,910,732,366,805,739,716,755,86,731,176,52,679,413,27,883,193,304,669,433,366,198,6,983,897,919,870,236,492,529,977,190,375,816,461,405,951,433,518,33,94,129,344,33,531,140,792,381,362,45,639,420,581,227,558,565,80,558,862,127,165,761,80,98,749,450,576,820,885,975,612,830,331,261,634,279,732,138,117,301,153,994,187,247,655,542,217,173,424,196,649,525,479,323,695,223,855,224,817,812,268,2,641,671,520,252,979,128,284,46,205,33,55,445,428,853,462,612,94", "455,530,458,858,38,338,134,882,169,265,278,109,980,25,702,491,734,382,564,272,371,880,670,778,822,297,694,11,133,207,220,963,512,235,598,646,769,823,395,768,157,684,972,33,499,336,291,572,760,998,204,453,840,434,808,106,43,18,137,593,957,5,14,826,133,480,787,851,291,548,329,235,335,975,130,4,566,495,879,513,597,184,484,135,685,22,85,314,262,980,504,84,758,812,938,374,235,475,639,332,947,619,438,236,4,721,947,729,714,30,314,700,772,736,790,93,845,186,491,591,315,394,337,442,706,401,359,52,615,28,498,196,874,478,869,476,851,788,395,736,438,607,260,856,728,137,361,639,725,777,173,676,142,649,970,723,746,173,146,150,653,940,74,497,264,135,689,351,786,348,212,348,268,903,82,271,53,427,282,899,911,632,470,367,785,875,282,906,711,828,631,774,25,766,585,591,635,345,939,631,124,811,718,979,51,985,840,89,959,903,546,366,389,285,468,483,117,897,744,215,769,873,143,797,257,170,509,573,485,292,157,289,583,280,185,85,3,289,960,39,334,255,355,302,514,766,468,113,623,544,87,295,342,987,157,480,243,376,718,463,884,881,184,93,575,439,743,492,433,944,515,655,607,569,583,833,305,657,223,998,923,70,432,758,960,190,938,930,858,712,267,98,83,433,503,343,472,757,415,730,497,270,63,108,858,976,449,125,590,473,905,969,16,879,149,191,870,664,877,497,595,629,979,230,118,214,223,578,952,707,670,328,730,897,795,801,595,130,295,889,823,711,944,859,486,42,912,493,9,785,408,105,995,312,191,57,280,263,604,609,316,209,770,350,59,946,847,22,32,148,629,396,925,975,101,579,217,867,431,673,561,432,4,930,30,362,181,908,551,807,567,166,959,906,474,966,884,715,314,529,530,958,581,206,479,798,147,369,917,316,822,807,182,402,726,771,279,817,429,248,734,845,466,421,186,283,765,633,505,906,512,856,596,87,752,202,747,187,948,762,231,25,391,514,544,896,335,554,874,309,240,410,89,90,216,175,211,654,777,624,530,190,455,648,522,414,862,426,910,98,803,628,419,642,986,394,449,829,34,47,86,616,393,52,309,631,274,520,524,573,67,266,979,134,975,257,451,280,493,292,903,30,446,386,88,921,276,405,821,153,606,67,788,689,868,373,671,456,280,867,707,921,12,108,360,353,236,745,438,194,127,471,634,775,307,94,952,877,818,948,653,165,402,930,183,414,854,682,367,875,436,337,235,817,563,880,399,609,888,952,162,595,879,181,511,921,670,302,976,757,792,969,127,716,973,724,837,159,883,622,717,932,656,696,624,925,965,286,654,490,467,805,610,280,404,416,868,13,725,132,397,811,735,432,385,580,615,259,971,330,980,953,631,908,77,903,735,422,417,98,623,321,594,810,65,336,678,2,598,609,150,695,783,843,18,34,592,345,634,825,390,972,505,875,337,901,985,992,0,598,645,259,344,174,360,120,725,837,451,782,41,306,690,220,924,618,687,732,118,188,470,324,803,72,271,18,914,868,438,36,823,716,447,663,422,195,976,59,338,187,532,784,792,200,356,719,229,573,258,320,941,538,719,366,835,46,323,775,892,269,525,51,297,703,490,691,365,18,723,658,107,464,962,922,367,768,592,886,285,318,179,468,803,339,241,70,228,609,383,11,663,887,244,816,386,548,750,945,762,167,68,670,160,708,421,345,272,464,320,456,282,675,458,187,955,198,638,442,883,174,943,836,889,750,488,349,941,839,395,572,924,85,827,245,609,926,365,998,867,610,122,875,483,970,576,261,308,650,164,207,493,349,716,72,747,881,783,982,596,911,106,519,365,206,379,872,550,908,217,757,645,728,498,67,950,957,293,924,322,532,644,281,731,879,748,780,671,646,904,200,831,625,922,200,848,727,363,560,873,969,273,171,956,333,951,233,99,933,186,732,947,379,336,136,813,457,259,548,536,844,297,752,795,864,256,75,581,641,766,626,252,730,825,976,377,620,363,661,940,475,384,893,741,386,481,252,97,553,774,238,334,67,736,499,589,553,503,412,913,731,294,264,203,384,422,605,271,373,997,689,933,923,721,400,899,377,657,915,490,104,498,811,7,486,122,357,268,145,887,80,457,695,272,978,459,980,935,795,257,957,637,685,902,450,719,176,937,270,937,664,271,753,692,750,565,448,807,30,939,102,482,29,973,757,700,744,711,129,328,731,723,69,244,563,421,204,991,796,294,120,878,398,42,873,221,681,18,226,130,186", "395,884,451,355,796,757,430,877,649,928,813,189,761,366,42,613,349,154,143,479,60,406,763,897,817,243,716,2,40,415,391,347,186,460,440,687,321,903,197,739,492,149,326,19,419,935,942,490,510,359,523,733,31,46,380,729,696,541,452,503,53,206,658,980,360,546,335,415,523,799,618,19,30,467,836,972,986,127,49,227,296,351,111,568,110,642,545,942,244,349,61,760,91,568,362,980,632,408,302,396,7,94,962,347,583,68,751,681,239,956,838,995,720,631,9,767,891,78,57,56,203,845,541,903,72,277,303,168,175,90,334,193,926,535,588,115,303,895,273,199,20,726,787,203,750,515,534,429,889,399,545,368,419,642,530,320,243,732,815,320,613,27,657,693,298,179,507,14,242,71,204,676,381,639,580,526,817,402,118,650,646,24,189,495,263,953,844,586,186,769,922,887,862,193,182,67,822,846,397,221,742,319,190,174,261,129,149,675,250,912,90,946,402,223,601,807,613,36,166,64,612,212,536,894,445,232,251,921,695,648,884,762,123,238,431,475,362,942,195,566,659,488,947,369,566,539,430,557,611,849,454,777,264,918,77,925,581,768,888,681,505,416,233,383,277,272,469,246,880,744,401,953,604,607,586,736,242,318,966,552,767,683,526,70,937,824,315,578,877,517,173,98,804,820,527,265,246,919,374,983,397,926,112,853,417,17,917,866,71,952,393,501,631,9,600,782,607,486,283,752,938,52,623,709,938,891,110,403,575,376,376,859,602,981,470,920,528,927,17,729,872,570,626,40,295,522,466,328,781,18,716,610,458,115,353,883,531,219,776,374,884,655,935,702,73,92,574,984,368,415,611,638,707,296,7,38,510,336,990,355,297,759,585,509,116,156,296,131,77,143,617,97,185,695,951,519,417,809,34,570,886,827,277,67,287,203,436,747,105,290,28,403,245,658,533,716,882,88,934,428,573,491,881,63,88,75,109,386,982,910,275,935,40,95,988,299,879,68,188,949,712,943,569,865,610,17,246,885,42,886,90,989,523,347,5,957,934,775,180,398,407,771,674,615,254,832,109,346,134,319,735,893,232,221,46,542,386,428,651,704,275,840,843,87,717,809,131,190,271,157,961,423,66,355,571,850,777,266,108,114,140,813,245,358,853,67,230,370,266,462,881,16,990,34,916,962,646,588,603,506,324,982,598,247,571,121,850,250,12,223,316,971,179,149,400,879,336,169,811,963,67,975,529,254,430,751,426,409,962,316,776,682,669,220,943,881,327,209,432,498,50,103,463,355,895,318,562,447,98,884,383,38,758,456,12,343,249,183,441,638,899,329,89,96,207,67,859,909,89,280,208,314,845,627,883,966,346,703,371,219,733,449,981,676,20,30,143,523,936,931,719,976,238,537,222,357,715,148,161,28,797,141,976,974,369,163,518,543,421,446,332,994,849,277,805,348,640,913,152,708,23,11,753,334,344,265,669,825,598,0,452,785,665,467,912,705,662,638,355,431,597,296,316,591,675,499,596,615,833,709,118,86,877,669,902,130,37,245,938,536,261,580,219,451,146,135,451,698,416,573,241,297,593,624,980,91,502,240,276,157,363,6,688,83,182,478,695,700,30,188,61,850,334,228,491,64,401,507,222,432,307,151,613,708,581,865,748,299,44,514,266,607,137,235,547,987,248,232,133,103,150,357,267,838,459,595,992,587,301,807,601,82,953,36,236,543,772,79,185,671,658,488,578,657,757,178,19,649,234,344,945,276,351,342,85,798,385,145,115,167,132,523,696,213,151,915,467,546,725,159,927,982,716,706,280,936,18,835,577,668,54,422,746,315,231,383,13,253,494,220,391,318,803,639,654,537,489,865,612,287,471,624,535,548,984,1,209,284,52,781,382,751,827,88,932,428,532,13,721,808,429,874,566,177,102,899,213,232,436,679,319,652,742,222,725,479,430,566,632,309,973,902,829,379,18,119,234,900,760,140,267,321,190,518,33,607,701,663,487,17,714,203,155,200,926,103,811,482,329,342,57,802,746,66,154,245,957,315,993,696,556,73,980,32,641,923,206,827,527,164,460,77,316,413,141,78,430,996,745,588,183,657,521,75,180,874,90,920,587,693,789,258,505,477,681,718,930,133,673,462,459,933,319,130,590,575,307,206,572,961,612,717,958,934,116,831,514,881,906,331,561,292,782,190,455,884,168,359,859,260,192,155,382,505,606,485,910,167,374,429,556,539,184,941,657,891,724,912,460,713,241,771,636,59,950,2,415,130,718,835", "148,538,269,46,924,161,266,718,80,365,709,859,407,431,715,56,254,261,881,695,291,991,144,621,165,678,14,200,758,471,157,474,455,708,62,834,437,883,779,999,302,56,268,343,445,965,969,184,255,22,176,559,840,805,670,109,895,384,295,410,541,723,284,112,783,406,339,810,833,323,93,575,975,242,671,989,108,838,201,155,515,768,72,15,313,142,700,562,529,577,226,473,704,616,351,545,724,257,432,255,591,767,26,199,753,819,689,538,488,178,528,778,696,920,5,100,221,754,756,248,866,411,356,593,362,265,94,762,204,330,213,75,323,156,34,484,633,607,585,196,518,629,6,447,822,725,764,137,157,25,389,194,884,244,345,106,909,821,535,951,989,415,725,656,920,279,987,851,190,935,938,896,455,386,62,585,475,605,714,388,822,530,775,296,55,939,40,952,341,227,842,852,23,896,79,986,148,819,735,113,676,223,498,640,792,586,58,617,879,671,794,621,438,476,131,587,967,964,619,545,585,6,403,902,714,535,931,696,808,531,686,654,703,592,233,237,143,612,216,284,131,987,795,371,779,312,176,438,547,902,676,166,220,75,61,190,429,680,68,776,942,342,647,782,829,641,790,497,584,92,931,400,364,498,911,840,118,715,956,504,121,498,113,780,137,589,578,725,991,938,855,586,341,981,509,820,969,911,405,978,26,227,786,357,18,657,499,624,467,703,78,93,6,949,760,24,431,59,815,202,140,17,427,568,177,788,426,181,921,877,741,747,533,387,534,946,474,717,782,856,889,535,23,761,2,575,490,809,661,777,292,997,37,877,302,396,976,692,593,36,964,545,465,847,590,484,758,437,407,958,410,345,913,72,740,240,35,261,204,941,352,523,428,267,125,722,364,715,608,9,942,163,785,912,647,732,736,885,783,997,339,260,115,338,794,191,390,428,712,495,607,427,890,363,35,751,447,223,458,86,988,558,151,868,419,310,68,334,433,174,232,7,736,844,600,729,756,169,772,970,730,200,649,360,352,261,517,121,428,507,138,33,477,375,117,753,577,994,81,256,783,444,539,421,292,328,121,235,737,698,352,57,24,423,710,656,882,779,716,390,191,752,312,499,885,390,986,990,133,329,431,476,730,349,675,948,484,670,579,451,449,557,838,789,194,934,311,208,783,944,583,268,158,396,202,510,711,313,340,956,481,11,930,586,562,417,52,267,342,21,205,493,710,672,746,764,215,83,548,846,642,806,793,984,440,345,256,221,672,961,561,459,62,193,329,522,815,523,17,427,407,31,234,360,898,17,248,460,699,732,829,24,698,318,603,754,52,298,241,623,109,745,476,481,230,868,9,64,976,389,280,723,392,498,671,746,438,27,327,753,579,654,368,677,570,57,30,850,314,536,929,597,961,15,761,562,879,261,520,137,296,520,311,797,121,107,744,948,898,347,247,164,913,29,5,606,305,834,112,538,974,761,114,368,463,246,360,975,645,452,0,323,434,5,671,212,159,489,630,581,373,397,372,591,681,178,671,654,931,75,19,100,602,990,922,446,621,349,850,985,918,820,789,602,556,824,407,571,702,458,474,31,792,349,217,276,427,315,689,265,573,574,185,40,388,6,217,971,548,606,58,548,776,483,165,448,952,498,910,777,327,84,157,608,971,709,561,261,162,346,488,422,840,897,946,874,168,20,979,991,883,112,805,92,477,843,608,154,465,148,523,519,714,8,795,730,967,161,875,465,803,657,266,631,621,779,490,412,722,275,225,867,338,666,924,60,478,291,419,375,796,445,449,957,857,631,279,452,754,249,347,258,663,116,751,764,709,789,412,49,761,460,879,332,204,170,36,232,254,266,194,634,532,131,899,611,244,212,693,960,227,978,264,392,114,574,310,627,229,44,521,628,756,946,772,581,586,964,75,731,573,225,51,144,983,645,4,366,523,540,70,408,862,432,164,797,849,451,603,93,934,856,407,354,926,290,870,296,501,169,948,777,935,851,429,339,870,120,870,182,736,249,273,681,369,976,602,277,287,84,383,434,927,404,795,687,968,866,190,841,404,769,23,350,553,417,515,38,893,988,387,310,711,504,843,969,83,564,554,908,530,284,750,471,347,629,440,139,730,763,473,207,594,632,102,498,427,628,563,413,267,158,935,786,18,350,644,688,621,121,210,242,976,229,862,650,35,645,139,95,953,286,821,642,28,221,55,661,412,293,893,229,647,182,720,393,383,174,173,691,353,300,731,775,243,510,791,819,382,379,801,191,180,920,864,649,894,937,570,660", "330,653,716,530,559,64,439,174,20,612,766,250,951,587,917,281,965,897,130,7,60,568,884,796,798,272,607,266,363,398,808,747,980,991,621,968,985,63,293,214,440,808,10,964,996,684,78,516,716,565,165,930,928,196,404,412,31,927,137,994,879,526,51,993,670,429,233,878,972,722,173,199,640,457,736,552,335,699,394,654,170,257,55,488,342,427,884,386,184,792,578,492,607,41,300,937,327,300,338,338,988,367,106,678,449,548,388,223,518,328,910,543,906,8,204,155,740,35,818,200,685,555,126,967,671,680,12,807,176,537,921,896,376,972,593,304,511,610,571,631,426,57,915,625,183,86,654,206,569,498,923,526,283,907,864,43,595,632,725,710,92,782,534,65,704,339,685,752,357,253,67,848,816,280,29,685,35,61,733,536,179,888,298,262,624,7,933,170,290,554,551,307,80,304,387,24,969,45,652,700,404,388,936,935,877,19,720,438,759,829,945,443,922,89,476,474,685,90,665,100,451,912,508,737,527,959,551,488,16,129,480,409,507,417,34,558,966,80,417,839,245,20,328,707,128,91,963,806,517,897,985,357,660,454,743,440,225,25,154,230,185,862,110,820,444,771,639,923,430,595,865,597,353,942,143,848,900,384,658,807,135,359,884,21,496,209,554,450,585,633,28,124,613,896,669,901,525,924,332,693,478,93,505,391,636,65,51,201,268,926,719,610,244,116,120,539,50,104,670,655,282,524,962,827,448,943,975,40,143,676,874,352,44,625,947,544,383,85,766,511,407,541,820,163,284,618,978,374,148,679,315,114,172,276,553,917,377,428,390,134,292,244,881,727,330,882,767,801,463,588,323,827,208,549,262,659,602,413,80,964,402,490,775,638,83,797,641,775,402,209,609,57,871,604,620,556,675,921,922,523,287,876,675,148,353,236,48,721,29,44,40,928,585,96,676,228,969,121,943,621,327,845,380,702,253,757,852,65,507,889,295,738,864,257,753,881,779,938,201,855,420,571,977,222,177,235,357,869,146,270,988,270,201,42,419,104,705,126,30,13,344,649,172,623,852,986,982,474,459,688,49,408,818,852,687,272,175,403,372,457,662,25,785,792,675,717,618,42,486,296,599,67,116,261,663,864,229,204,109,801,938,35,874,480,58,305,330,158,571,658,218,438,735,954,346,358,560,789,280,700,189,938,758,872,844,418,649,681,135,212,264,133,259,103,400,901,1,463,532,254,515,530,155,999,60,678,774,102,225,670,692,352,314,361,920,272,957,466,286,693,348,821,132,818,719,942,34,799,205,944,406,922,542,304,868,759,582,572,751,375,87,984,323,440,280,842,261,734,910,803,433,790,681,38,17,736,829,832,486,555,339,990,252,543,670,130,663,719,891,925,623,792,834,792,759,808,474,603,432,83,313,861,520,739,720,40,74,528,310,789,163,93,359,484,913,931,65,401,484,6,733,773,970,403,499,391,135,951,259,785,323,0,892,537,726,931,916,80,609,332,905,250,118,363,955,233,777,267,89,405,645,436,525,971,644,255,451,640,326,872,371,756,82,930,689,716,732,264,721,631,353,168,925,389,128,392,26,918,903,563,159,881,428,40,60,425,615,135,519,286,959,39,611,223,141,980,410,694,672,193,646,590,181,764,200,292,485,820,779,928,77,989,115,995,91,254,819,247,737,29,40,253,758,868,996,348,968,957,865,207,780,846,617,327,88,895,665,286,619,463,822,199,32,823,931,38,201,232,536,516,699,232,983,898,684,696,344,700,374,51,582,190,805,607,231,790,464,526,708,287,179,995,284,962,917,42,83,52,111,341,73,557,224,569,103,195,48,957,91,407,230,277,933,723,35,195,744,861,340,359,361,891,933,806,421,286,126,900,603,381,927,950,943,684,109,924,895,686,192,776,362,257,913,986,830,839,836,882,966,512,654,158,474,277,994,572,735,796,846,289,262,60,494,645,516,584,668,522,699,456,336,491,426,967,442,310,278,387,431,32,539,535,834,463,169,586,499,887,489,698,335,349,92,337,584,936,647,827,463,912,615,897,449,508,646,51,928,91,558,703,386,10,53,324,244,958,270,283,907,769,151,97,418,574,273,933,647,813,494,513,398,999,392,382,583,613,878,727,555,282,778,958,593,105,406,431,645,489,775,246,73,98,137,997,220,510,657,758,785,93,381,175,106,937,626,905,601,248,272,3,636,996,312,890,727,241,272,273,923,102,167,978,499,789,248,733,675,178,231,574,587,761,406,891,82,395,222,868,327,735", "919,69,260,200,160,626,858,536,285,390,238,387,425,677,832,49,224,383,67,550,809,158,764,791,116,330,185,868,632,400,322,577,972,69,857,110,527,234,213,905,256,930,34,876,286,691,222,196,754,718,580,560,536,72,130,258,869,49,315,304,446,592,738,69,101,529,898,753,267,405,863,285,520,288,534,566,146,35,528,174,70,811,566,579,431,959,877,585,78,257,945,552,60,329,700,61,444,255,909,561,98,82,291,824,685,359,893,737,457,504,809,385,374,26,294,417,587,392,323,847,348,565,166,230,792,911,853,362,914,285,628,702,964,286,655,51,530,847,823,827,290,168,171,594,334,725,864,66,974,715,213,830,357,995,395,56,658,886,225,117,210,783,59,861,846,189,467,297,458,247,184,82,841,417,967,113,580,656,282,527,699,142,179,495,334,277,360,842,980,371,739,172,851,418,272,888,172,325,139,588,413,428,951,446,589,636,150,10,792,502,884,647,626,553,642,945,773,829,900,159,610,980,161,165,348,602,178,38,665,433,5,856,804,895,581,813,185,15,566,18,201,822,277,855,927,656,815,961,613,883,814,304,802,587,398,871,207,252,504,507,783,624,736,404,715,866,217,994,635,368,499,611,881,911,768,489,454,133,405,645,190,824,385,202,716,560,612,440,601,363,96,791,910,560,368,189,698,166,45,759,885,358,73,81,120,457,622,829,937,820,344,252,138,603,873,907,791,919,244,547,272,294,417,445,733,72,638,508,775,610,236,447,411,674,473,869,14,171,187,791,908,41,493,235,524,832,601,139,888,648,952,744,404,771,598,573,827,169,437,756,443,171,86,514,322,493,502,450,111,216,259,135,871,575,76,241,819,657,780,437,739,206,212,931,792,430,950,514,538,226,475,867,988,519,913,83,579,469,984,865,189,628,988,344,994,494,692,616,949,918,651,220,718,621,439,614,383,598,43,539,624,864,50,426,344,331,569,82,964,782,848,956,801,661,573,652,251,543,105,593,662,186,207,306,994,44,455,530,636,273,613,115,933,126,378,985,691,353,507,693,678,975,720,952,525,900,402,90,400,906,93,372,992,362,233,480,777,950,763,409,830,717,189,521,918,167,253,754,439,101,285,25,795,751,860,830,890,178,217,89,647,329,388,258,8,472,685,865,122,563,406,116,102,266,444,286,516,638,909,105,243,31,442,766,672,250,140,225,729,929,483,498,617,262,937,45,364,147,222,501,351,270,582,102,371,633,920,728,796,428,393,239,100,993,871,215,161,874,945,948,500,66,267,974,833,138,965,756,925,318,308,939,312,33,80,598,880,613,792,453,580,923,68,433,673,965,105,446,319,207,927,43,635,908,573,26,172,474,803,50,457,779,870,5,384,951,595,375,702,332,775,98,808,975,161,316,426,846,525,323,195,62,924,517,317,135,783,404,163,93,149,401,33,837,943,380,263,454,929,280,727,23,341,750,723,648,140,899,344,665,434,892,0,930,345,614,26,239,200,519,874,713,564,423,237,786,418,148,128,795,282,64,301,908,420,334,989,964,31,606,119,614,345,458,582,82,499,227,638,866,44,251,980,125,666,983,507,192,247,467,651,206,462,349,66,636,734,3,107,17,996,64,466,410,801,878,987,986,733,18,728,897,350,890,949,224,561,950,690,891,48,77,316,595,995,256,952,205,983,657,389,882,170,276,740,210,843,865,420,12,534,88,508,984,65,29,452,612,213,382,686,535,170,915,287,34,966,584,714,987,965,51,725,116,902,825,971,953,213,44,224,632,84,178,385,600,518,889,743,694,958,397,593,310,66,6,895,985,749,876,562,791,194,100,325,714,534,215,957,601,987,938,611,229,533,916,304,225,26,216,686,144,462,680,662,535,452,938,350,368,805,58,485,516,519,361,711,521,467,990,453,489,273,522,85,976,642,481,347,940,184,99,513,513,752,626,22,267,282,524,788,529,279,899,103,901,126,842,77,224,19,930,604,239,381,984,29,300,505,772,511,638,565,628,846,931,653,268,30,176,388,423,823,886,919,888,874,838,291,724,494,789,114,517,865,999,227,695,204,452,803,170,137,133,820,310,58,349,671,964,452,926,715,281,743,663,752,825,54,817,735,782,790,801,650,621,399,267,781,786,693,832,937,665,212,606,775,367,15,89,819,729,439,614,775,838,500,480,700,76,337,36,364,184,625,846,23,939,40,563,109,991,86,662,710,805,904,557,372,930,324,255,682,997,796,750,514,117,335,31,698,789,397,210,98,942,577,982,245,961", "710,728,849,344,206,395,20,461,548,795,895,921,622,11,59,419,237,639,239,860,822,141,427,617,718,958,675,568,109,963,717,501,756,633,915,531,289,398,970,576,204,24,262,503,897,299,42,62,518,842,897,860,719,13,274,906,602,70,291,984,351,921,391,387,411,896,251,852,937,608,564,153,98,226,664,161,625,277,660,93,229,985,250,387,21,829,149,59,783,449,926,100,836,419,229,932,559,463,922,480,280,332,75,138,480,847,318,77,218,806,475,658,10,174,283,959,61,520,302,73,998,936,540,713,499,913,690,103,377,570,592,323,860,919,866,431,817,924,954,783,345,664,518,122,581,59,186,536,8,146,393,171,744,24,674,472,9,498,153,279,237,212,748,168,213,318,166,91,582,377,817,586,603,838,360,675,546,750,937,836,805,220,957,738,205,693,921,548,60,576,619,768,508,474,246,707,815,85,831,106,978,589,555,792,841,75,369,809,479,739,386,973,475,113,843,569,283,407,132,863,319,52,187,349,214,29,417,833,761,565,286,671,133,380,651,187,992,311,577,391,690,186,378,892,720,463,102,805,310,861,612,891,110,609,330,600,762,210,953,94,735,607,849,202,88,825,761,175,334,328,319,557,162,119,259,255,218,617,583,870,244,588,270,98,89,696,320,740,141,970,842,854,942,547,796,745,381,43,978,955,998,318,505,998,735,825,855,342,584,345,874,790,461,120,731,299,662,695,157,474,724,378,602,917,634,389,417,803,584,322,374,864,888,648,109,756,969,707,461,321,746,402,484,702,720,551,122,890,540,436,995,546,436,517,311,428,570,711,421,364,191,660,95,424,434,190,141,315,620,331,352,256,997,901,485,496,639,167,418,845,613,634,216,780,54,212,566,448,249,845,163,316,638,425,596,183,114,297,375,736,707,491,510,357,569,863,507,521,725,959,942,573,291,343,713,934,756,429,398,86,394,130,698,774,700,126,887,470,716,925,151,168,477,49,821,462,363,921,829,205,845,34,285,879,276,220,169,624,929,168,207,295,101,660,639,994,746,300,736,934,194,267,708,395,205,250,252,591,455,137,87,691,675,14,467,242,529,176,627,118,371,31,94,294,208,429,271,451,479,173,351,20,393,646,743,792,655,543,327,559,825,643,563,813,281,207,982,742,922,923,309,785,494,437,155,797,97,180,831,461,13,690,803,140,171,174,581,845,538,458,750,215,623,405,911,10,531,673,698,258,936,49,9,621,16,524,20,982,79,540,964,638,934,840,194,36,952,853,187,303,119,921,220,926,518,925,550,277,819,323,735,132,644,953,1,923,998,165,889,816,274,352,89,919,660,621,681,920,414,851,278,666,851,195,289,332,173,464,153,560,483,119,326,973,571,310,35,504,365,307,457,753,271,436,276,701,733,287,407,321,907,319,57,367,242,737,649,388,55,524,524,10,158,388,776,286,639,813,785,92,828,296,959,767,698,119,232,970,174,467,5,537,930,0,867,565,127,291,638,1000,120,31,169,49,355,894,361,256,572,618,304,209,117,677,589,485,986,984,340,902,676,664,841,482,810,203,281,658,847,627,69,929,259,577,314,465,132,922,691,564,367,973,422,521,599,985,610,495,52,592,47,947,510,641,432,387,758,4,198,387,326,467,392,40,762,41,680,739,77,179,672,165,315,307,141,701,924,660,203,442,994,591,899,221,371,453,589,334,438,482,283,975,163,636,660,146,609,278,291,462,187,809,370,571,804,439,551,649,624,465,386,388,921,392,386,871,721,488,391,846,674,393,480,24,378,275,442,416,329,523,71,224,370,635,36,658,980,876,905,334,387,617,988,172,532,637,280,595,868,66,254,72,582,949,729,67,284,392,32,856,583,293,349,94,58,178,458,389,570,326,995,601,413,348,995,436,344,599,214,932,477,276,995,329,763,701,914,232,761,768,228,415,336,971,88,486,738,297,352,871,600,877,569,886,233,625,444,988,979,490,454,578,796,564,630,566,879,76,10,485,495,327,628,288,64,53,139,172,500,341,450,433,789,298,180,144,30,463,852,57,993,780,763,169,872,865,528,888,304,468,565,174,519,62,767,446,223,590,201,567,615,405,496,310,424,5,433,105,593,11,677,16,619,192,5,606,172,661,963,592,383,411,354,136,233,282,301,266,183,449,505,540,850,110,233,569,443,371,472,337,231,26,655,733,721,22,605,960,127,823,980,715,757,283,678,699,254,105,474,844,901,886,73,822,700,474,338,550,489,864,935,289,576,888,724,635,291,452,784,803", "485,14,592,955,490,717,186,461,725,687,704,982,532,138,11,962,712,777,111,253,12,327,101,834,51,617,491,497,2,484,734,376,737,71,536,46,450,43,715,351,564,19,963,283,910,142,565,242,228,563,352,596,261,321,509,15,696,788,888,535,283,903,717,328,794,894,953,158,743,644,145,516,365,243,791,332,631,496,59,879,781,863,476,232,173,445,55,640,250,825,732,384,86,371,498,755,938,767,232,244,235,453,202,296,854,933,513,1,106,331,309,294,362,119,315,909,639,214,211,561,637,590,351,620,260,556,948,442,727,783,257,885,260,962,69,144,564,823,372,832,73,589,541,974,458,698,512,143,860,932,69,16,477,259,797,860,486,188,97,248,923,234,680,886,60,540,145,868,58,900,336,894,327,684,509,222,691,98,460,878,409,579,834,262,819,471,733,255,581,740,699,3,836,356,542,966,592,368,354,959,201,602,406,162,301,906,237,684,424,602,923,650,780,517,680,227,739,383,626,764,650,176,768,432,792,393,811,436,890,842,525,756,994,234,923,145,596,288,701,265,36,329,213,45,173,483,512,222,760,454,953,829,379,304,178,268,409,967,873,847,87,677,128,96,322,840,96,938,526,519,149,331,587,815,742,257,629,13,465,457,592,656,683,349,314,906,403,411,352,748,28,381,175,727,218,347,245,990,434,715,876,969,352,85,75,150,299,284,472,832,732,486,45,840,868,130,889,271,599,501,546,531,251,326,555,222,850,256,451,935,901,855,73,158,637,38,768,282,659,895,633,729,451,643,384,771,130,409,592,820,62,806,936,222,836,998,911,915,171,749,495,598,899,198,619,384,103,21,905,820,996,857,274,188,372,204,968,704,417,123,35,460,368,880,91,957,73,7,954,151,965,913,990,433,13,292,527,974,892,422,618,799,974,53,459,473,28,542,174,279,414,512,733,646,557,979,708,98,187,866,527,751,331,224,984,655,396,517,332,849,529,823,855,824,919,915,565,950,142,298,322,952,411,313,748,888,657,2,141,987,514,116,841,619,635,872,958,491,928,975,721,961,827,698,603,629,24,120,829,215,987,877,538,713,423,928,911,89,98,997,462,959,748,204,937,780,344,779,370,60,385,487,16,995,119,924,783,7,550,177,498,796,214,732,885,217,331,684,33,732,73,342,837,362,344,838,978,967,34,168,913,477,330,263,548,414,876,613,145,583,897,971,133,99,604,836,962,832,438,441,807,374,603,143,706,925,796,307,365,807,191,119,607,544,823,857,832,599,159,627,905,781,851,739,751,526,529,236,909,253,846,419,72,961,496,165,544,125,937,607,330,637,385,493,294,5,148,89,69,776,430,818,748,882,713,526,967,91,919,663,397,327,83,334,177,901,121,875,937,860,206,471,461,669,191,707,732,266,84,51,284,173,39,477,262,974,356,70,88,644,14,599,613,745,94,101,495,470,432,346,899,928,915,292,486,187,42,424,360,912,671,726,345,867,0,187,296,543,234,28,966,375,893,802,996,531,908,303,79,491,466,309,575,550,386,979,857,379,240,448,726,858,702,718,220,746,400,603,138,203,65,388,52,567,377,342,715,970,687,129,50,783,438,243,869,959,17,65,773,602,953,616,166,585,324,842,830,530,81,572,161,640,495,985,616,969,846,212,372,971,433,140,55,885,943,753,193,410,11,380,93,335,868,644,17,90,639,236,884,474,75,516,746,1,828,75,501,721,534,298,315,385,699,162,852,61,855,317,411,158,892,963,608,526,514,991,621,455,837,506,11,790,754,554,590,401,631,620,656,716,179,207,17,287,612,279,16,568,595,496,589,951,312,148,585,655,995,168,183,204,436,361,532,181,244,957,167,280,175,750,139,444,672,659,352,690,349,347,558,7,332,699,848,628,39,275,99,215,222,340,571,384,881,950,903,696,789,839,351,616,930,769,751,63,507,995,552,363,482,81,637,602,625,108,180,26,623,622,442,863,786,792,269,568,109,385,801,353,621,613,692,881,516,883,940,548,560,256,36,436,321,350,783,331,257,387,39,301,272,860,541,957,599,900,649,52,197,563,765,148,902,8,267,106,187,896,692,213,164,679,654,427,685,801,42,371,596,333,71,65,69,915,417,628,782,886,447,226,326,510,101,903,343,368,412,72,205,817,549,982,657,92,719,545,27,438,627,826,783,918,406,880,322,240,522,220,179,682,145,344,832,553,96,147,118,273,693,33,156,965,174,326,700,897,474,183,919,200,14,570,319,660,938,728,214,235,136,789,111,451", "709,905,462,789,866,79,967,776,454,931,728,251,50,258,977,152,333,451,149,96,450,226,113,475,735,289,480,407,292,288,701,70,513,983,989,668,496,281,669,863,794,745,173,494,804,711,503,784,416,748,972,385,365,693,564,869,355,193,680,648,531,531,893,28,951,221,321,628,767,31,170,516,195,771,822,629,651,832,879,571,453,580,749,598,490,492,246,151,836,154,140,830,482,439,890,164,286,219,919,932,757,339,315,529,608,299,791,597,556,742,660,648,396,935,478,712,432,220,152,263,704,857,578,38,406,168,870,547,628,119,739,621,960,309,756,947,382,892,228,863,471,107,800,107,791,94,687,438,21,560,475,613,542,412,495,886,495,578,339,436,216,513,51,571,130,521,790,948,63,660,75,386,737,527,408,571,128,35,670,287,54,38,49,621,419,47,125,464,163,660,728,743,434,752,245,705,754,241,675,213,227,813,677,734,712,334,208,892,796,486,903,653,717,601,968,710,679,866,962,900,304,296,188,990,141,723,53,503,36,146,453,955,684,758,957,868,685,714,697,959,498,525,777,850,859,971,738,346,487,424,222,221,99,876,359,818,505,691,450,380,68,127,413,350,974,813,415,922,9,629,643,223,872,755,386,585,901,729,304,76,434,324,879,265,645,566,316,759,656,794,964,376,845,307,16,199,312,184,287,788,891,220,118,998,94,652,476,988,641,482,90,871,740,747,50,919,93,669,776,806,428,163,422,773,945,59,97,521,206,81,986,209,458,481,870,418,459,716,438,107,675,465,662,189,244,286,339,455,374,615,563,848,480,214,343,704,429,672,739,553,297,120,727,24,994,950,658,416,824,822,637,186,793,938,700,27,164,260,474,34,604,790,492,982,957,420,967,578,249,241,486,654,629,74,721,599,410,848,584,376,297,487,626,261,88,790,915,11,563,222,76,448,895,252,312,539,139,406,235,626,933,239,206,309,167,947,786,330,696,288,619,585,113,457,508,606,84,314,531,136,74,166,697,873,78,458,636,55,370,874,467,663,524,230,15,376,153,726,88,431,447,5,914,294,996,203,799,23,945,242,823,192,783,483,26,438,495,940,885,361,475,642,726,484,584,254,668,925,76,243,136,44,920,914,139,321,723,107,186,868,927,745,532,919,947,54,434,230,907,825,945,33,898,936,773,542,317,574,363,765,103,679,305,158,811,707,506,582,456,10,222,673,529,219,374,932,618,902,617,427,504,459,190,643,159,297,244,916,924,536,565,974,108,704,570,888,551,429,169,929,277,669,45,302,687,651,69,59,997,958,539,793,780,349,693,156,343,518,302,711,289,764,792,462,40,491,384,228,390,646,328,925,928,800,938,84,472,604,991,129,253,195,100,759,298,781,292,214,477,381,232,171,14,890,638,685,981,826,806,310,113,653,512,93,302,733,135,401,523,312,223,412,370,605,473,243,948,325,596,900,952,829,433,11,582,710,748,444,120,705,212,931,614,565,187,0,610,232,780,345,912,364,925,300,393,335,587,786,689,689,182,600,133,162,617,362,66,147,296,152,288,4,807,354,55,312,295,326,683,69,252,827,146,892,511,152,809,528,858,465,128,865,407,180,923,118,593,50,963,897,794,836,610,597,318,688,719,316,832,931,374,674,451,300,958,512,531,673,204,542,512,26,997,602,365,362,939,431,791,969,955,50,561,929,35,681,613,937,381,348,156,941,390,21,745,207,366,25,121,612,730,835,990,599,402,637,221,586,135,532,204,629,520,941,4,866,170,19,603,629,613,902,867,576,793,684,981,712,76,888,399,891,386,486,746,815,708,71,721,198,588,480,818,656,298,32,25,149,229,361,263,770,556,512,292,757,793,520,323,308,323,785,611,91,879,428,2,803,313,163,902,948,680,31,749,426,314,598,543,600,757,279,754,112,637,31,854,504,420,752,820,400,99,133,123,493,491,937,449,879,306,275,895,845,271,542,426,190,275,801,291,932,805,459,91,826,920,296,263,391,648,122,584,592,67,471,882,745,267,551,213,953,392,129,337,674,80,590,513,866,224,109,288,525,986,296,638,643,302,131,81,298,169,626,95,613,76,185,57,226,702,208,691,905,1000,175,338,336,450,611,260,120,987,680,461,785,367,156,664,484,937,33,816,507,151,52,131,372,685,555,640,57,19,348,990,855,182,747,666,66,13,324,974,737,371,863,885,281,696,245,676,91,766,330,466,62,212,606,6,789,417,77,455,670,192,347,771,228,477,747,939,975,812,387,543,240,433,156,649,387", "341,147,850,221,432,839,710,643,985,179,335,547,64,135,227,866,39,497,537,744,485,517,507,710,168,912,809,387,431,4,893,787,8,657,868,810,556,819,928,234,755,409,312,768,90,209,400,939,781,353,259,430,336,876,687,413,322,723,761,84,752,809,870,972,149,151,78,284,629,70,62,63,556,966,130,372,655,851,42,110,140,912,177,145,267,735,761,981,734,943,572,675,18,47,470,994,990,889,677,464,886,148,379,691,47,914,973,453,357,809,964,95,147,764,820,308,299,263,986,180,462,981,810,856,589,348,361,47,952,546,781,642,182,825,553,476,288,779,395,658,514,358,52,405,912,506,290,761,670,629,949,983,686,224,172,770,859,60,372,85,975,390,343,110,952,4,233,265,634,811,964,327,974,210,144,201,887,442,838,945,301,128,993,109,365,549,360,665,494,126,559,341,334,781,801,330,699,705,768,23,557,566,483,139,495,954,445,688,71,834,653,986,251,769,16,921,442,411,995,213,556,207,337,836,636,689,701,504,265,970,556,251,157,543,154,721,451,604,155,830,724,474,514,225,351,72,301,902,43,284,903,465,439,358,133,44,74,231,553,733,86,298,621,514,121,516,301,789,171,250,921,934,406,809,438,105,290,988,132,380,954,24,436,219,589,148,744,635,297,572,714,171,771,610,405,470,501,814,704,312,685,789,775,260,401,500,790,123,618,399,208,336,955,615,59,996,739,406,788,190,553,491,574,189,718,344,487,56,571,945,970,486,328,41,714,780,647,194,67,680,245,560,282,930,195,629,286,154,706,562,29,658,659,130,933,989,232,708,628,426,555,674,272,913,359,785,85,982,216,27,518,289,992,883,502,111,16,221,822,657,35,674,838,448,702,136,28,876,235,490,895,184,520,413,675,932,239,123,718,602,854,900,548,848,60,111,395,831,253,275,814,810,318,671,975,383,513,102,564,176,237,973,978,680,512,163,506,347,680,476,393,589,952,15,111,62,639,648,18,457,820,488,502,444,89,257,480,950,515,190,84,407,922,956,630,625,557,481,490,338,695,657,56,169,481,787,501,406,434,154,462,903,585,951,449,894,905,646,81,738,61,313,913,43,470,872,98,514,988,913,513,502,265,490,615,859,999,817,172,72,785,898,386,45,819,381,584,434,843,193,705,56,649,124,34,504,181,575,624,800,104,70,808,362,65,692,964,890,996,395,671,821,642,936,119,987,139,498,183,857,25,958,928,704,672,600,885,555,64,646,919,106,225,46,193,276,841,2,123,602,967,51,981,102,468,860,724,504,347,761,836,789,7,549,334,248,272,361,68,187,834,294,744,658,647,476,204,802,803,653,515,4,15,303,910,5,296,860,502,125,75,362,741,398,907,490,601,996,538,583,468,946,392,567,952,755,303,581,209,724,70,498,957,448,498,935,721,97,32,651,601,475,945,811,675,428,826,130,146,471,406,859,413,204,845,45,995,595,725,662,159,916,26,127,296,610,0,952,664,183,460,876,619,429,700,445,510,28,175,317,269,251,981,502,933,699,985,589,254,343,974,836,939,637,612,822,722,745,278,819,49,216,379,809,422,436,722,989,357,758,506,701,610,256,361,148,601,121,443,709,296,834,63,408,979,869,378,612,352,194,321,872,672,580,58,86,136,573,309,846,228,134,574,905,381,750,953,791,864,170,250,863,787,505,434,721,689,158,283,963,409,238,528,471,840,887,436,531,937,116,622,572,612,614,323,995,469,706,424,753,64,266,530,128,82,411,468,530,176,433,583,277,902,720,73,652,674,592,205,507,580,670,965,391,5,33,969,394,764,614,400,975,897,685,497,629,157,34,538,835,310,339,715,229,735,578,154,709,601,345,335,915,344,29,636,823,648,533,526,678,540,12,346,918,223,688,268,399,853,902,881,530,109,800,662,382,140,819,223,445,454,784,965,139,137,130,597,207,735,140,613,216,251,852,852,464,283,895,955,346,186,425,469,456,850,168,646,297,282,184,27,981,99,774,501,525,226,10,13,432,807,796,173,537,223,900,583,769,244,443,537,359,82,699,450,224,582,718,230,914,840,592,883,982,241,344,509,548,314,901,507,463,688,757,61,402,25,533,977,682,446,305,220,759,457,171,413,705,166,454,7,5,299,595,862,330,479,773,307,641,327,442,381,264,25,821,67,634,887,480,330,873,672,899,71,400,464,344,621,5,962,767,847,405,776,443,114,523,998,259,542,8,891,284,894,174,810,536,722,583,19,547,486,279,787,237,42,231,616,162", "871,88,840,131,511,274,264,762,321,767,867,555,974,354,879,508,86,329,554,875,872,806,598,291,712,775,942,95,754,295,740,383,331,685,506,866,567,756,721,616,650,625,422,742,764,33,516,893,643,631,938,454,199,899,76,233,142,441,726,50,578,636,217,67,280,494,696,897,77,697,627,958,303,786,280,211,137,968,283,168,985,29,239,335,754,619,543,177,178,901,487,448,131,804,27,464,617,619,157,372,975,686,397,900,396,421,683,927,760,973,63,696,994,489,989,153,320,233,3,912,425,999,896,809,522,39,220,543,507,547,226,513,850,821,85,777,101,977,746,184,384,402,590,711,73,446,700,633,503,379,288,92,492,825,239,517,980,3,314,252,351,783,418,340,489,271,287,787,957,717,689,704,5,956,611,61,965,550,630,175,959,839,74,697,363,524,514,594,45,926,448,227,729,320,887,275,119,349,857,827,209,104,303,970,769,71,872,801,219,981,186,722,520,933,821,977,642,739,696,190,863,392,484,24,768,965,978,130,985,428,877,457,871,335,419,686,393,908,278,37,691,264,332,685,702,464,400,993,55,483,649,443,788,150,441,981,976,849,2,713,596,530,494,591,432,197,744,269,502,315,612,948,405,297,133,427,464,832,332,651,623,971,180,44,413,532,180,136,869,964,519,822,195,866,548,599,129,756,856,630,982,243,531,688,37,698,975,774,991,191,32,498,963,220,910,462,151,749,779,353,946,733,585,735,909,769,720,125,967,578,229,192,253,771,870,273,883,104,671,619,48,680,705,847,194,379,339,158,21,619,594,684,945,156,491,662,255,684,494,285,388,99,465,796,669,413,495,432,215,878,532,147,318,405,900,901,771,944,493,404,154,149,6,91,813,660,940,59,57,927,405,127,747,576,282,753,841,949,993,703,965,286,153,459,178,816,141,334,105,448,309,478,459,719,839,678,824,128,779,170,279,923,461,457,486,184,957,841,947,602,655,136,537,174,134,813,740,943,606,145,925,512,365,909,946,15,284,347,8,97,682,735,236,146,242,828,716,258,171,270,622,340,611,375,815,473,387,222,791,532,850,540,148,402,504,990,913,514,806,646,787,381,632,258,880,444,673,345,730,461,767,934,55,526,616,611,249,32,552,887,206,688,261,764,335,71,774,767,270,528,845,448,120,428,894,486,44,669,504,993,718,160,265,633,952,812,408,768,567,551,574,867,96,974,379,405,841,448,4,372,291,747,797,62,127,553,710,532,557,779,555,89,562,415,139,689,323,291,946,774,350,317,313,834,187,664,164,129,67,807,466,804,508,449,130,562,410,518,341,381,608,479,655,650,739,75,203,29,720,406,527,512,496,964,812,111,36,661,438,611,735,247,669,399,803,514,395,8,963,313,28,690,463,963,800,595,518,499,93,86,446,537,502,172,623,143,356,91,987,376,377,657,905,916,550,727,320,377,218,373,286,185,759,744,713,35,874,107,837,638,489,80,239,291,543,232,952,0,631,259,884,468,839,17,673,569,321,610,969,12,539,476,233,62,857,541,412,683,69,451,18,630,838,128,57,768,712,672,474,352,253,222,341,540,64,290,932,557,134,216,674,105,404,86,754,172,693,86,689,714,721,152,792,335,833,617,407,540,767,913,263,450,747,788,936,881,247,814,873,881,227,895,818,457,270,666,617,56,746,817,753,461,114,343,941,473,428,156,356,16,119,504,822,659,647,130,665,295,648,139,296,210,262,498,271,362,229,143,578,818,906,527,944,765,172,382,724,652,904,136,552,513,268,439,342,768,928,755,933,105,289,190,70,948,178,476,418,882,963,70,944,388,870,394,498,763,666,410,119,326,358,330,436,277,63,75,532,517,670,671,607,505,469,534,843,847,321,629,328,507,670,425,603,80,877,258,779,167,781,435,129,164,267,780,772,477,461,77,447,765,887,49,640,975,918,573,476,826,493,691,689,669,22,620,293,407,990,3,912,927,720,367,511,517,718,643,786,901,700,773,63,787,676,28,111,758,762,835,135,65,2,356,590,95,876,571,358,490,201,224,266,572,459,855,419,32,313,100,790,995,299,277,850,699,401,510,136,911,3,104,977,369,215,728,658,372,788,373,276,451,256,785,381,87,254,564,256,292,151,57,69,144,984,538,741,745,191,156,572,919,966,743,704,961,14,838,869,912,537,296,39,632,300,999,608,937,649,770,403,18,220,87,693,948,704,921,448,856,120,654,636,876,734,837,888,590,496,62,592,30,442,404,743,78,279,71,701,907,798,513", "669,291,359,555,231,903,802,383,248,518,393,617,735,388,797,937,205,780,191,816,100,584,421,364,903,550,228,954,994,477,834,675,137,973,323,234,973,992,563,952,548,326,521,876,962,826,517,687,844,772,311,143,72,678,288,219,539,434,723,703,332,441,616,469,113,998,617,88,737,672,452,885,20,116,792,892,231,620,628,738,108,32,623,495,694,684,19,469,939,18,679,488,555,336,631,464,599,981,976,67,825,544,703,20,115,452,121,303,667,767,337,539,287,8,135,954,891,72,987,320,56,377,214,837,658,282,400,472,3,758,508,520,376,114,198,476,427,841,411,87,439,28,8,977,202,986,726,697,94,163,375,410,529,853,580,832,710,919,538,847,141,923,143,925,141,243,591,645,831,567,296,846,901,534,772,852,9,325,296,628,188,405,68,563,135,599,29,467,817,981,926,454,389,935,248,829,239,682,707,369,607,155,328,529,744,501,81,572,21,31,967,703,462,201,452,709,172,427,231,404,258,883,362,394,570,434,289,730,308,110,868,832,568,398,803,555,770,266,376,305,917,49,459,793,191,583,156,837,971,327,221,490,749,174,463,134,324,104,969,99,486,916,919,301,342,411,684,378,784,776,123,524,411,632,874,545,59,195,262,129,204,336,707,742,261,50,221,905,750,251,222,848,495,527,636,275,202,353,27,976,874,194,491,496,808,94,506,813,931,883,175,492,4,4,320,460,340,32,903,266,298,139,962,157,349,490,939,379,117,335,168,307,560,421,788,877,318,233,339,914,132,686,855,187,872,797,190,896,946,625,236,1000,448,664,382,144,385,935,408,617,316,977,605,284,895,463,584,126,39,610,660,764,668,125,781,164,244,63,248,58,738,13,191,994,447,556,124,760,68,474,999,552,405,259,837,755,117,159,981,809,51,164,825,800,352,486,66,437,779,581,458,949,298,315,48,891,606,943,747,979,392,592,266,652,442,308,811,21,935,201,403,523,398,548,688,479,196,16,61,848,835,293,411,309,431,962,815,84,122,210,716,590,618,103,470,981,68,566,860,511,708,460,765,475,99,178,127,156,125,13,791,149,968,27,930,755,479,289,396,81,943,135,586,696,969,86,194,58,217,851,97,873,350,775,388,114,150,727,935,11,241,178,816,17,105,702,526,891,770,886,464,967,776,111,819,325,13,380,374,148,193,170,890,347,234,103,779,579,226,600,726,727,7,349,215,336,310,610,876,465,455,520,614,41,257,154,245,634,477,357,735,136,439,306,535,819,8,947,509,238,796,879,420,251,844,517,252,556,666,734,964,953,554,582,572,670,139,824,844,365,832,400,790,169,625,561,200,393,197,334,35,517,233,886,693,618,151,62,656,959,147,881,561,396,385,959,7,794,895,557,495,311,807,122,659,924,859,989,748,255,129,911,246,686,554,192,574,296,385,990,532,947,523,269,156,937,959,462,732,241,362,237,228,186,448,507,468,646,451,355,630,609,200,638,234,780,664,631,0,391,830,954,299,134,662,964,949,877,664,415,86,704,39,320,142,403,385,58,865,507,45,221,546,392,900,505,424,96,693,934,19,630,726,324,314,73,959,728,987,386,975,874,839,841,761,168,149,60,510,705,787,600,584,770,262,742,675,251,306,220,559,553,835,993,868,487,306,273,833,416,341,734,264,724,341,779,522,952,442,430,66,257,123,687,586,876,916,659,952,970,76,203,109,275,223,804,124,52,692,401,733,66,462,615,616,637,276,234,512,967,195,259,272,966,750,927,607,466,365,619,783,226,403,973,378,771,586,34,861,252,515,286,397,634,991,774,573,509,161,53,640,738,166,663,161,673,145,384,182,384,216,602,279,633,747,354,814,230,818,658,146,505,157,447,831,998,51,455,128,790,795,753,871,553,792,334,299,487,706,14,808,309,367,238,707,845,838,482,196,59,222,816,25,738,779,628,207,540,451,291,731,253,237,445,743,696,207,188,848,269,321,70,255,508,817,940,647,183,454,920,21,470,17,269,596,259,428,462,12,592,269,142,341,632,781,338,870,930,835,19,614,677,200,239,780,462,658,155,604,832,131,821,750,934,850,683,391,91,31,197,918,22,343,788,63,569,5,854,181,800,571,769,932,889,45,595,499,432,151,360,40,194,878,218,584,586,40,640,651,257,586,346,377,959,19,337,12,238,800,448,600,532,248,589,186,49,513,553,174,432,158,69,904,491,654,106,366,497,712,781,435,998,901,43,765,23,416,404,129,754,624,718,590,563,486,373,963,701,214,421", "27,192,296,217,445,630,265,575,40,997,99,146,311,167,9,226,616,515,952,12,147,825,486,632,668,526,322,625,885,330,906,874,866,116,875,190,540,353,6,925,580,335,477,21,724,788,283,968,447,273,305,577,308,754,371,865,460,262,960,528,527,726,583,970,555,482,770,224,380,332,82,541,911,926,519,71,743,893,430,888,500,219,627,805,57,435,307,81,582,745,398,956,557,88,278,908,522,3,450,819,137,969,375,934,569,616,281,135,290,164,896,762,531,730,701,218,729,655,885,651,441,365,567,643,407,647,62,423,404,844,460,624,283,7,156,814,548,536,47,821,599,406,186,653,788,787,348,16,147,779,285,607,188,971,674,307,384,189,132,328,486,279,456,145,652,17,892,742,59,884,853,897,855,339,435,866,476,341,645,649,657,256,327,48,487,351,32,341,571,63,367,464,383,68,471,738,47,649,43,19,699,262,967,522,459,48,684,2,692,111,498,310,708,544,750,778,899,926,84,765,929,91,425,595,472,645,71,181,392,562,876,123,537,220,432,767,3,470,824,27,139,44,353,926,47,733,291,61,796,854,288,968,998,234,971,440,130,967,959,945,287,151,349,419,365,532,675,85,210,241,308,888,24,278,442,557,720,385,649,573,488,781,781,927,764,201,63,225,361,833,355,633,505,773,318,118,16,672,822,124,104,935,912,312,892,849,894,458,273,487,55,714,755,762,944,24,542,855,477,398,929,275,968,310,436,330,75,370,291,50,443,277,912,652,916,603,906,900,158,655,103,237,540,44,569,116,307,838,146,162,878,755,869,594,504,148,407,364,368,974,264,807,311,901,255,83,791,341,284,147,575,279,383,710,976,181,709,84,800,431,229,392,482,737,208,36,935,751,610,483,78,543,628,192,463,227,155,209,457,422,285,438,395,224,178,988,302,12,309,545,721,137,705,920,740,275,975,153,689,741,822,568,435,74,289,25,207,846,996,61,384,408,992,447,986,867,332,382,726,592,38,85,55,489,509,109,455,239,85,407,438,566,218,879,532,660,683,9,678,986,786,887,540,25,966,796,122,481,14,663,39,437,12,56,913,328,982,28,466,232,165,51,221,693,227,136,899,772,704,484,171,191,859,819,121,640,150,153,683,263,22,245,20,4,676,390,430,293,184,65,805,922,220,615,204,555,164,28,772,57,886,718,56,224,388,259,271,885,817,710,967,942,726,272,424,539,270,2,956,349,11,854,381,919,474,931,809,344,988,538,990,101,809,846,142,34,596,854,871,232,248,440,445,393,19,629,244,392,903,759,361,381,534,483,489,772,402,204,792,455,141,368,172,495,328,480,801,494,393,189,108,571,298,267,291,412,443,153,75,258,960,866,788,513,145,529,726,925,568,731,622,876,130,756,157,842,372,270,825,334,679,709,608,852,837,102,688,376,733,359,244,176,751,538,614,252,983,451,910,473,677,452,282,579,318,359,866,905,782,431,581,332,519,1000,28,345,183,259,391,0,948,769,346,313,839,140,325,356,795,65,355,381,924,497,532,811,962,556,494,526,401,813,765,489,523,412,901,78,515,815,794,139,263,683,465,84,646,869,532,356,932,722,2,388,445,916,615,440,437,816,519,470,220,152,987,250,836,652,469,827,762,321,876,717,51,709,625,621,458,152,425,797,908,42,698,336,638,600,829,933,300,308,998,301,833,340,508,691,162,916,791,681,468,402,855,986,850,267,977,290,517,28,670,629,593,183,198,931,663,710,808,500,944,367,265,367,250,395,732,668,670,479,420,633,472,620,825,384,87,143,373,977,901,178,792,1,641,950,980,191,651,887,702,950,788,384,825,656,638,927,363,40,710,74,736,300,799,196,284,763,945,92,909,50,492,223,357,254,827,864,39,614,308,288,637,996,195,948,627,55,235,162,346,709,431,888,198,720,859,323,688,109,271,349,419,20,391,508,33,948,810,181,66,493,894,816,178,21,303,9,878,306,318,343,927,41,114,766,629,89,790,91,439,644,324,219,844,927,798,311,976,903,117,93,274,544,570,419,564,408,825,413,142,936,32,912,440,140,666,518,745,707,147,330,887,109,457,248,895,876,762,821,521,268,282,435,36,501,636,200,104,336,256,8,733,968,475,521,862,411,803,496,783,143,409,505,915,611,172,317,777,683,933,248,336,453,688,21,835,556,626,906,153,679,418,460,444,911,800,373,762,861,128,150,676,211,2,964,387,426,392,704,960,514,858,645,400,690,236,617,248,771,254,869,764,745,72,63,324,687", "5,669,830,275,841,282,317,503,661,477,942,817,448,186,567,226,689,313,248,249,414,624,917,56,910,187,67,620,65,160,48,131,979,802,484,602,545,263,107,91,532,779,888,284,31,798,564,782,709,376,73,374,312,149,584,385,273,842,632,639,513,640,759,242,507,655,393,400,767,293,870,790,648,211,788,137,405,886,850,811,23,148,857,862,460,33,427,308,618,367,233,690,226,929,223,497,400,601,266,17,273,647,806,269,933,694,321,238,71,680,826,970,914,917,943,555,702,480,65,327,461,814,362,660,475,496,658,492,461,547,849,860,517,71,575,194,579,159,784,476,808,393,510,254,851,466,959,705,527,707,945,316,457,189,60,541,720,347,623,752,227,894,9,654,284,231,985,795,523,844,503,266,135,428,235,358,403,445,826,215,655,810,429,12,799,326,886,878,566,324,691,15,775,725,420,29,33,560,937,559,311,24,680,356,452,172,692,105,851,366,630,216,549,61,821,390,509,42,463,2,381,833,512,191,361,468,695,379,54,417,944,788,947,414,215,808,108,328,991,497,734,370,609,834,495,364,100,633,131,589,187,669,509,686,89,449,735,675,419,945,48,448,320,359,86,332,812,177,349,514,64,697,848,98,486,664,442,587,293,621,874,673,905,605,47,665,509,716,119,293,323,593,638,61,328,259,475,132,952,163,524,675,751,495,227,238,903,787,312,15,324,172,863,818,925,541,641,491,93,817,916,91,487,786,120,768,232,914,417,560,440,526,590,323,585,666,960,737,685,775,513,567,417,66,955,891,680,70,597,854,306,730,148,7,177,730,43,83,149,357,775,828,858,409,621,426,316,863,281,104,618,532,507,983,667,869,843,610,629,712,443,52,633,153,283,552,745,864,31,13,411,469,590,381,748,481,581,528,778,87,718,128,637,570,703,849,404,849,11,698,817,313,920,285,148,785,309,952,376,198,239,83,834,128,572,423,938,672,469,968,686,624,363,907,109,375,41,140,484,226,470,471,795,50,419,93,523,219,777,464,306,202,894,752,44,861,568,73,324,756,310,830,815,29,650,609,526,488,570,710,123,759,680,552,920,30,528,370,249,975,768,775,570,659,22,979,341,191,957,320,717,886,441,326,674,478,46,826,929,146,231,46,888,764,513,263,179,606,927,228,738,308,998,110,567,489,475,663,213,455,958,70,131,5,672,908,128,176,320,738,515,803,4,701,244,90,777,554,347,678,616,720,323,916,223,237,564,387,695,630,695,906,325,560,987,87,877,390,206,849,533,89,316,285,806,615,288,798,13,59,297,961,177,894,805,631,693,700,127,751,541,813,196,351,488,706,322,409,302,122,913,72,807,112,524,4,653,674,929,230,808,452,326,587,389,831,731,283,283,782,86,299,1,984,57,315,622,628,571,534,801,860,164,99,880,925,557,191,423,1000,314,449,632,669,537,731,310,115,648,707,650,398,395,390,615,646,312,929,41,597,373,905,874,120,966,912,460,884,830,948,0,577,919,989,320,158,353,73,586,907,340,681,398,746,71,737,775,439,864,547,833,959,287,784,285,211,322,681,374,931,654,447,164,315,529,192,155,503,510,660,199,819,987,577,424,286,452,370,928,473,648,716,87,995,750,206,147,615,631,19,163,631,797,839,821,863,40,393,66,917,643,139,134,722,536,584,556,288,284,848,413,41,704,36,949,343,456,750,43,985,279,381,853,284,571,557,615,526,379,145,911,850,581,253,47,223,347,445,761,334,835,726,2,175,255,99,282,348,119,521,37,713,11,933,817,829,945,54,59,270,323,212,903,358,644,291,136,44,871,843,927,41,429,935,568,645,883,450,86,545,363,96,763,941,166,467,798,24,411,648,340,99,383,970,116,83,904,449,55,193,57,633,813,727,218,334,996,804,657,989,301,371,403,212,146,960,284,734,764,416,150,175,220,105,100,392,933,632,630,638,962,983,676,401,790,995,925,333,444,575,432,536,595,535,467,513,46,751,316,806,723,57,824,359,399,633,314,634,850,22,668,818,268,12,834,264,881,272,805,340,113,475,865,513,231,94,673,415,69,415,822,212,922,841,240,713,823,60,413,777,474,177,263,980,329,15,838,914,314,605,511,996,295,592,289,320,943,876,409,452,278,200,57,952,861,660,97,660,447,12,878,430,714,515,294,15,73,713,399,740,946,644,735,9,547,573,757,620,12,63,266,701,920,258,173,382,280,213,67,347,828,229,725,896,183,984,516,820,514,300,372,191,636,176,919,421,532,241,52,355", "643,742,724,964,657,966,325,143,717,624,926,541,227,929,514,943,686,218,383,545,315,504,535,846,621,915,65,340,794,403,619,402,449,539,175,633,244,36,535,356,128,522,787,882,131,818,813,109,942,806,610,241,286,420,20,991,526,685,860,155,593,507,581,29,515,86,8,148,762,234,241,61,965,901,360,48,400,271,653,981,574,351,479,285,121,73,62,660,223,57,346,117,47,101,236,748,312,552,81,945,311,499,124,903,336,665,202,598,809,690,631,313,782,228,561,316,761,645,403,194,873,202,200,391,9,318,732,298,55,604,933,272,93,809,506,893,805,304,649,228,837,788,82,164,647,637,227,279,565,31,622,962,665,126,334,860,965,524,396,908,271,451,632,432,985,222,743,686,564,175,516,900,213,934,143,274,162,408,90,620,114,729,82,319,200,939,692,897,403,409,357,730,275,594,486,332,514,17,712,310,548,948,243,573,919,354,338,164,245,657,668,531,509,456,300,953,189,372,808,498,121,377,161,390,652,444,992,891,683,106,163,36,935,997,999,4,683,411,820,421,75,380,512,681,190,408,48,756,288,488,591,696,376,388,860,644,379,730,165,889,440,707,237,301,156,463,998,340,254,492,437,913,141,960,424,624,656,730,28,341,803,917,51,230,986,869,60,703,339,751,456,348,809,865,514,231,514,686,309,579,601,782,336,945,732,743,585,434,471,788,820,654,979,53,205,658,413,94,815,87,36,94,340,782,673,403,853,769,24,666,926,883,939,931,885,747,425,913,312,670,525,319,533,952,659,243,935,397,608,937,432,467,392,738,749,561,349,300,445,988,995,92,860,254,541,252,419,177,996,705,657,34,339,647,384,774,867,529,774,400,404,409,439,995,851,346,939,894,847,777,467,839,938,628,392,812,780,783,58,26,223,266,376,470,266,106,716,678,707,276,471,71,374,657,146,897,77,604,339,886,7,992,235,89,474,596,490,777,318,701,123,571,161,564,250,978,433,170,708,493,61,74,94,51,53,247,945,197,489,266,928,194,769,553,983,98,871,420,999,845,362,623,133,890,544,267,988,360,128,553,489,429,386,868,40,332,19,956,608,847,383,858,834,358,835,129,831,722,122,454,826,941,358,930,89,596,462,604,6,799,621,137,761,982,6,737,612,182,976,110,964,841,488,150,259,833,986,864,469,195,508,798,219,855,951,412,859,344,295,7,913,832,694,372,63,390,449,593,917,97,736,529,695,891,129,192,100,571,774,755,330,142,242,295,88,301,233,241,95,808,30,863,573,144,106,913,345,11,42,788,977,661,929,91,140,657,893,691,872,358,558,23,945,919,58,128,250,397,375,335,15,420,240,96,11,120,239,229,4,571,31,576,492,366,111,850,651,476,919,789,274,737,271,761,523,934,144,243,767,338,480,686,360,653,915,147,711,934,647,93,645,789,948,401,836,601,41,664,67,371,247,417,915,367,773,846,97,305,306,296,397,250,713,31,375,364,876,468,954,769,577,0,867,514,921,472,436,685,967,163,333,215,886,704,257,95,918,200,691,176,530,537,470,920,968,295,6,419,899,964,579,901,817,802,211,217,226,678,811,489,399,668,356,807,95,454,425,93,996,427,183,103,20,444,914,763,851,433,356,375,499,712,504,890,551,433,602,228,160,493,130,835,399,37,485,928,964,206,783,372,183,481,139,512,501,75,389,792,168,38,810,715,552,935,280,187,526,236,45,394,988,458,713,686,56,524,39,114,317,834,599,444,776,843,143,55,828,462,88,930,878,221,788,685,102,148,939,711,750,565,264,649,278,848,187,589,136,234,916,12,48,99,450,967,394,204,520,277,54,857,636,564,653,610,571,890,975,184,700,649,780,157,961,343,382,175,567,370,810,460,260,478,194,575,949,329,311,760,998,726,882,370,385,167,990,27,164,123,272,362,834,253,812,880,159,842,645,936,422,576,965,50,88,609,682,906,276,868,601,838,338,164,586,665,993,281,53,423,784,235,670,898,769,394,679,399,67,916,41,14,865,655,862,157,851,184,643,306,102,471,638,461,739,42,779,410,285,626,413,720,790,92,77,434,798,156,277,122,764,318,743,67,376,445,854,747,962,944,665,242,635,162,172,888,97,34,118,909,623,675,624,31,151,782,740,995,201,512,727,614,333,596,276,445,277,211,496,585,623,369,497,980,718,77,2,698,847,788,151,961,173,55,406,816,686,716,327,733,425,979,98,749,242,769,582,628,532,798,119,868,963,800,627,966,504,694,201,387,859,746", "840,260,101,137,468,337,453,421,626,616,591,32,920,55,412,745,759,127,926,823,823,630,740,518,184,106,266,151,328,776,56,865,273,127,297,287,559,599,823,656,194,144,973,872,134,765,840,971,590,561,518,582,964,451,129,979,927,765,993,400,996,656,46,62,193,366,3,948,84,175,398,960,126,474,877,171,890,966,451,437,210,306,969,580,261,482,433,187,15,738,540,796,582,288,478,747,420,18,841,727,900,907,586,622,646,773,833,850,720,808,16,3,972,511,301,906,37,208,342,427,803,244,636,765,338,225,7,610,72,470,234,691,598,29,102,441,175,534,481,745,250,379,239,909,454,754,142,313,960,535,625,7,134,167,643,912,904,503,258,433,667,878,980,772,947,953,107,8,287,238,60,43,998,432,335,122,303,32,410,539,959,211,200,110,908,928,805,451,529,391,314,503,255,797,512,797,259,466,972,793,940,196,179,257,354,271,428,553,447,644,679,905,280,889,734,60,71,944,154,750,859,368,129,461,290,525,476,995,9,369,390,536,309,463,792,621,379,467,458,836,829,275,135,232,589,111,627,700,991,187,446,79,560,914,124,329,493,138,499,581,397,652,661,718,38,858,945,806,495,465,355,278,602,924,412,48,624,46,259,17,314,376,291,382,592,648,689,960,847,211,373,506,617,983,405,7,386,713,994,850,338,248,567,432,492,662,73,430,953,932,586,276,160,334,33,775,541,591,555,814,639,557,721,236,263,5,189,777,589,574,304,929,504,915,475,272,283,408,22,966,198,686,894,95,887,340,358,465,515,171,798,397,103,660,630,855,524,753,491,637,228,769,153,308,350,168,887,983,287,298,163,856,73,562,880,272,923,364,675,441,821,591,257,158,643,936,895,908,791,192,971,521,639,403,936,176,510,315,187,958,807,531,642,780,556,968,75,763,515,176,287,788,85,578,104,251,59,237,933,689,850,47,238,22,276,305,395,323,379,867,492,660,564,745,19,797,131,531,330,950,730,673,244,636,622,530,939,448,762,485,324,348,450,832,961,713,765,659,372,796,986,948,916,911,256,495,584,169,660,773,77,787,477,669,715,467,141,319,818,777,171,911,483,983,555,309,415,715,477,24,479,292,33,193,522,30,872,157,498,686,939,921,885,988,65,165,120,888,8,9,755,782,40,57,852,661,248,932,645,957,375,3,597,421,554,937,1000,171,976,81,407,371,525,211,433,717,50,179,795,629,119,716,150,736,981,966,597,394,654,81,151,284,277,153,949,297,41,411,430,662,55,390,188,265,999,695,866,310,50,436,614,926,228,827,483,853,186,116,383,777,12,154,696,442,583,972,2,930,350,498,254,830,449,540,659,949,702,962,253,692,94,360,958,657,993,684,906,977,563,520,233,728,541,99,149,802,838,929,875,52,524,319,872,269,679,192,367,616,696,395,181,39,481,232,451,820,514,628,671,843,88,410,717,482,920,997,496,436,690,316,372,118,564,169,893,925,619,839,299,346,919,867,0,453,91,72,252,777,985,429,108,762,132,849,959,597,915,926,994,337,236,191,944,913,69,571,609,606,935,715,644,192,610,602,733,161,641,376,779,641,596,435,946,383,607,289,910,555,290,585,725,279,857,566,108,875,624,484,725,326,570,103,447,38,998,169,749,24,924,603,25,545,691,147,314,138,441,335,101,215,612,731,238,265,26,763,936,825,671,555,366,537,384,437,551,134,390,272,351,740,473,550,808,387,195,401,758,714,445,561,260,499,275,695,670,554,915,97,693,225,952,752,999,26,817,135,543,431,245,389,105,420,829,849,754,915,134,710,321,928,146,795,627,172,777,22,239,44,184,26,593,912,754,743,30,495,794,557,710,478,418,41,6,47,706,733,988,779,590,793,217,799,209,546,584,170,738,438,40,332,405,620,672,774,875,203,74,457,459,322,602,650,645,774,471,78,526,997,945,976,669,861,209,559,214,920,11,384,180,197,745,499,391,361,865,638,707,13,782,94,182,209,209,869,303,42,519,338,654,876,505,889,409,546,52,727,938,293,302,798,890,816,949,161,484,7,508,341,201,852,824,94,487,548,865,411,631,555,831,526,155,634,82,756,959,738,640,714,362,384,753,266,460,948,686,561,760,550,329,884,943,725,95,122,129,514,945,180,187,409,297,658,449,336,483,178,882,47,383,748,921,99,149,208,122,405,426,740,943,566,753,579,162,670,426,80,820,217,146,864,27,417,428,553,688,811,517,42,193,936,226,515,787,472,258,489,836,353,578,599", "999,206,730,204,723,290,549,152,203,270,929,541,685,408,979,85,401,269,617,994,591,866,337,300,692,983,323,704,787,537,279,480,817,943,409,437,182,155,782,131,408,554,265,639,741,900,677,506,691,538,95,505,583,626,629,479,832,407,236,378,137,138,302,959,39,536,42,914,813,64,918,138,358,842,864,95,337,892,729,545,412,11,303,2,571,925,419,647,178,933,415,35,986,218,804,816,502,413,881,810,245,382,365,670,604,255,505,524,366,254,113,178,754,362,329,805,629,700,556,308,449,507,356,762,546,475,504,429,836,274,326,760,298,207,455,340,559,226,247,929,249,953,384,163,577,179,785,799,968,101,580,129,592,875,526,373,781,388,936,162,474,201,93,436,145,619,550,303,390,610,995,221,137,394,491,229,831,944,681,122,845,332,937,147,658,852,720,408,46,204,194,437,796,341,883,167,25,857,371,64,377,696,492,431,674,421,975,782,174,216,387,439,849,907,283,719,251,159,87,228,509,420,315,642,483,452,889,906,702,246,359,479,187,887,198,577,593,533,98,6,386,544,817,335,175,57,673,780,359,87,201,169,652,489,312,639,508,216,358,524,113,709,697,875,907,675,475,990,292,274,826,571,709,98,630,78,545,341,364,697,976,348,494,945,852,18,658,515,243,701,504,181,913,65,934,836,403,369,500,756,865,849,402,552,450,244,247,489,874,227,954,169,390,949,523,953,662,226,979,268,211,182,610,3,36,989,508,214,246,258,537,877,967,52,374,905,428,101,416,568,453,285,405,625,617,123,835,645,252,527,311,1000,461,778,617,562,829,577,926,826,61,576,687,821,586,819,146,930,328,58,450,784,204,257,392,447,117,635,91,531,163,85,519,507,262,527,34,40,615,253,207,110,984,279,501,927,299,920,538,50,711,333,910,719,291,391,443,54,82,859,283,226,992,478,94,11,268,758,760,474,867,330,59,478,683,362,977,453,355,406,463,285,977,804,429,348,795,889,486,209,303,423,156,836,50,634,961,186,122,510,80,651,859,244,937,677,401,934,800,446,461,476,617,202,207,515,250,663,341,436,247,407,275,490,214,962,458,841,650,598,677,479,985,530,634,254,378,512,210,448,785,657,931,556,432,780,918,452,384,175,784,846,882,102,582,575,891,145,769,6,137,338,910,974,826,465,340,315,854,378,418,30,107,235,618,475,628,921,724,656,500,960,41,610,647,485,110,720,831,153,109,378,296,408,148,208,811,862,116,291,432,708,560,732,765,282,861,712,780,129,133,296,54,945,594,283,655,278,961,448,432,191,166,396,948,985,728,14,152,217,222,9,343,92,793,399,648,824,214,626,254,135,162,835,72,531,557,281,718,291,464,778,547,34,517,882,690,905,338,992,549,332,192,614,730,455,267,778,611,512,709,895,734,570,36,665,567,873,489,638,832,495,150,362,694,404,108,165,770,120,159,819,654,160,397,582,92,862,220,591,591,363,423,49,802,300,429,17,134,313,989,514,453,0,55,828,191,824,511,674,340,963,255,270,743,799,232,950,514,636,565,266,90,812,628,894,202,271,734,195,170,730,363,72,507,982,368,178,280,114,727,548,450,671,359,553,944,354,69,449,888,262,862,372,605,96,379,686,938,752,374,614,784,914,968,838,323,775,405,636,762,473,742,988,675,667,89,104,642,658,310,689,403,63,334,184,280,145,206,742,455,49,290,801,751,330,299,17,165,975,725,406,775,597,426,22,904,407,156,395,130,47,714,399,303,387,94,805,605,322,36,85,777,40,186,792,975,667,766,33,616,50,413,131,359,970,28,698,357,359,634,976,352,34,14,937,407,267,119,431,916,583,977,125,343,368,937,141,432,266,980,700,990,854,730,48,263,569,360,539,136,889,176,908,627,13,109,746,791,772,924,861,663,864,400,59,994,236,107,273,167,160,930,217,41,47,922,390,101,131,853,368,494,909,969,679,806,755,792,103,203,991,464,789,414,641,927,674,123,490,476,436,521,926,765,494,151,561,504,366,27,967,913,515,816,242,119,842,381,734,736,749,969,154,414,687,543,945,725,424,467,250,199,240,88,824,309,169,724,997,979,595,40,100,613,427,798,953,630,890,855,544,262,833,842,535,287,389,637,468,522,872,755,882,583,908,681,831,428,978,301,963,979,898,401,897,713,549,338,181,889,175,491,918,637,87,544,859,494,934,387,805,949,276,114,601,465,906,558,177,36,625,499,895,236,208,170,998,957,751,81,618,749,889,154,757,165,860,710,705", "940,152,795,388,124,656,104,508,709,448,344,397,194,256,872,239,837,238,69,570,571,846,290,559,714,604,530,671,960,813,556,919,509,577,364,347,390,646,375,194,924,405,382,460,701,730,259,544,53,218,444,537,351,34,271,931,443,305,86,864,637,305,71,269,447,644,160,27,549,495,501,976,197,937,611,394,85,647,168,316,242,477,660,240,807,756,130,190,606,768,618,510,874,914,121,509,507,201,674,254,519,642,312,98,465,946,143,285,365,18,32,921,44,919,19,680,159,265,18,331,633,289,7,427,759,63,330,122,946,434,922,445,467,470,675,919,758,148,922,446,632,565,488,90,921,203,197,326,284,225,904,454,413,486,617,954,916,890,108,131,332,822,330,486,626,510,857,869,889,615,28,172,371,710,631,471,934,798,366,844,873,246,479,389,840,755,19,423,904,595,889,835,187,119,326,80,822,861,502,628,470,293,775,858,20,333,430,72,408,124,232,164,883,714,706,968,640,875,600,664,628,518,46,796,809,320,445,728,592,439,989,917,249,880,538,390,508,543,816,466,667,499,174,915,931,254,834,277,939,146,506,331,103,653,365,919,404,663,911,464,750,278,763,980,93,875,22,743,928,148,311,371,667,862,600,473,106,583,879,194,274,169,158,866,143,754,272,126,780,602,800,413,738,57,797,243,927,118,106,37,139,327,738,729,477,623,6,73,859,559,419,346,256,736,877,602,555,864,322,725,853,703,150,326,773,459,646,207,931,211,982,767,824,805,954,994,603,877,385,650,826,908,523,7,400,314,840,693,735,542,548,212,228,205,596,672,934,587,298,342,878,446,526,454,483,354,512,242,877,831,548,415,927,426,832,391,435,881,563,695,506,113,91,2,200,953,421,305,448,727,914,908,820,341,442,7,813,462,422,31,123,553,946,92,720,478,666,678,805,845,661,170,951,824,92,378,364,360,303,951,281,376,211,626,668,388,59,516,606,791,151,160,120,151,648,18,903,154,752,446,268,619,726,372,950,625,757,160,894,12,486,720,973,152,210,828,557,385,137,452,211,487,412,328,437,922,692,566,986,746,601,649,170,716,850,657,814,327,778,465,902,930,392,889,822,847,296,743,50,872,450,215,372,21,675,712,772,807,760,994,899,151,723,702,507,958,43,594,200,706,336,217,273,230,727,16,484,184,478,819,280,635,311,947,19,718,960,568,359,15,284,165,995,141,715,398,325,653,720,497,18,909,250,471,32,765,488,869,379,315,952,393,134,447,230,590,539,375,532,487,87,188,981,836,844,699,957,352,171,9,829,536,259,303,23,128,106,409,205,749,996,491,957,248,132,96,717,773,288,176,881,515,967,20,268,179,113,710,103,654,421,306,27,987,948,413,528,294,376,168,156,325,280,612,632,745,637,803,769,748,588,645,221,166,631,906,358,143,20,76,77,640,740,948,621,540,437,601,405,881,573,830,591,594,785,510,353,862,924,675,681,955,237,355,996,393,700,673,662,839,320,921,91,55,0,494,380,836,151,378,952,205,549,275,938,108,131,11,621,828,243,983,760,974,504,736,343,118,88,164,899,426,35,76,831,158,969,564,611,210,441,165,791,145,955,735,479,376,119,687,582,861,554,77,871,872,645,708,186,301,922,967,857,288,260,764,954,83,395,96,752,327,915,919,716,896,119,999,69,99,94,916,594,27,403,126,70,488,481,891,253,416,998,437,526,395,637,961,340,256,652,160,342,849,438,572,573,875,532,768,857,567,156,97,935,60,533,793,860,273,213,799,64,998,3,385,586,110,888,119,671,36,957,683,981,239,487,508,799,98,979,142,242,750,826,757,793,451,151,178,699,763,329,744,134,105,45,578,763,377,989,40,65,529,553,424,613,579,905,413,9,31,340,952,589,277,938,632,602,120,640,986,919,294,407,275,431,8,369,464,505,907,976,526,860,692,889,58,913,310,47,479,721,720,353,687,594,742,552,895,237,675,221,356,161,912,386,396,484,655,718,377,870,447,42,71,381,342,721,33,240,779,352,59,6,426,980,396,778,586,795,528,23,809,167,300,943,615,925,131,727,816,72,339,451,630,514,41,569,817,802,497,897,13,257,607,979,25,676,718,87,568,301,200,122,865,631,949,43,925,545,874,29,203,96,855,981,708,95,32,25,340,15,989,1000,684,70,88,722,455,384,950,835,515,656,359,390,245,672,214,836,633,495,463,325,728,550,238,787,986,523,369,526,476,971,226,682,389,714,25,435,415,103,865,764,441,652,520,864,137", "489,419,997,96,940,166,412,839,679,468,523,839,467,194,579,422,417,508,939,767,391,347,452,421,624,768,38,724,780,569,161,258,219,53,10,958,357,865,486,848,710,551,519,527,291,261,273,790,513,8,494,58,404,397,902,960,274,217,831,862,603,58,149,378,488,222,982,853,538,269,690,289,855,558,470,289,979,791,845,340,662,603,316,119,166,735,501,49,836,67,523,428,814,434,910,760,180,752,138,475,704,756,256,720,1,152,595,480,671,535,381,347,325,796,375,861,66,618,823,741,826,668,512,962,519,840,354,463,939,967,588,114,729,306,584,550,971,749,592,868,86,41,914,7,567,176,320,157,660,266,77,918,492,11,981,599,237,33,683,338,631,64,13,607,955,750,753,915,277,605,416,386,665,509,170,869,690,170,261,885,125,952,344,281,483,488,817,780,941,960,651,250,891,325,362,548,873,190,97,77,240,406,577,215,339,890,479,431,516,410,712,193,376,63,106,905,707,477,299,938,369,884,682,430,308,389,156,993,615,985,684,841,523,356,944,240,803,509,577,624,896,255,703,423,407,183,817,812,321,923,797,964,61,503,190,275,85,652,603,390,876,896,557,926,466,496,877,662,891,551,402,881,843,342,926,549,164,701,54,938,502,956,713,172,48,462,575,406,288,565,98,236,857,800,279,387,512,425,220,45,289,363,857,404,589,917,261,350,501,609,787,87,479,166,808,419,521,318,709,146,611,35,809,490,541,551,675,214,463,910,669,297,694,524,594,182,933,778,526,674,135,687,120,936,660,956,593,236,968,585,621,268,160,398,351,70,928,197,339,556,452,183,324,121,59,138,921,755,22,473,71,96,549,635,227,63,743,355,889,648,956,623,175,521,551,441,80,417,847,29,279,251,52,515,271,680,488,414,727,75,260,777,357,723,328,1,675,158,526,991,285,110,330,977,286,48,111,971,309,390,987,349,716,750,818,676,452,449,953,172,637,612,305,146,146,986,250,734,566,844,409,490,31,822,927,162,816,326,186,661,433,212,176,802,146,673,806,347,736,961,763,106,698,673,978,161,497,907,592,104,421,110,847,508,855,32,479,213,825,823,841,509,284,221,33,940,990,985,407,465,712,133,222,650,406,369,473,276,670,267,882,53,347,210,201,305,633,3,690,19,905,69,202,845,919,236,405,146,56,48,542,894,410,509,154,984,815,218,274,342,97,403,398,968,193,411,399,46,399,747,593,884,712,670,975,517,949,222,357,935,625,429,971,343,791,489,258,140,619,10,645,751,480,321,957,579,741,634,641,244,570,462,74,290,712,973,317,533,756,577,189,752,978,488,375,441,700,559,769,213,577,689,679,942,266,331,19,123,624,140,754,413,356,409,108,940,911,241,910,314,353,542,387,165,401,721,534,496,550,499,789,892,283,721,971,52,955,200,303,371,522,64,154,821,194,67,933,437,697,470,772,431,437,276,805,89,400,829,618,499,178,233,786,894,531,335,445,569,964,140,158,472,72,828,494,0,25,206,48,729,11,16,597,323,704,898,300,91,504,908,249,9,612,972,332,926,848,986,592,192,215,836,237,72,624,552,255,18,363,569,393,53,253,921,977,887,265,623,592,365,772,427,626,53,303,386,460,876,991,695,58,9,258,935,177,850,264,557,709,555,300,26,549,206,93,86,567,291,276,919,58,211,345,998,783,614,331,228,243,550,993,12,409,746,476,76,438,318,373,811,406,533,362,845,833,212,211,342,342,597,751,90,460,359,656,406,551,3,953,496,855,861,940,990,967,170,381,330,465,50,652,120,140,256,492,708,379,409,913,299,534,685,155,177,58,136,913,607,698,273,887,113,613,886,696,430,999,84,904,713,243,470,587,596,490,906,143,532,512,256,87,44,993,334,231,708,95,131,90,843,176,434,198,286,780,655,311,380,891,966,130,34,336,609,194,237,868,484,488,724,395,886,460,872,667,534,365,543,936,729,429,96,177,124,394,219,367,800,737,301,530,614,530,279,873,168,750,608,798,234,350,683,287,525,82,925,500,844,260,560,145,711,38,650,626,558,771,376,186,379,205,124,661,162,251,987,395,894,131,686,448,914,264,729,967,178,978,656,666,273,395,751,375,727,159,689,974,601,421,764,810,484,98,312,36,795,3,322,963,923,21,859,356,275,487,372,755,373,17,303,348,74,150,321,953,28,195,859,211,845,782,978,565,444,448,905,219,918,40,348,572,925,29,856,624,590,988,269,268,476,705,671,133,704,339,668,323,831,276,55", "803,84,795,121,212,637,156,769,367,496,601,568,603,869,630,607,468,661,235,916,846,824,132,736,66,750,889,237,892,762,426,951,174,21,764,183,130,452,582,243,830,454,820,219,864,6,930,865,109,756,918,262,453,563,245,442,494,442,676,836,308,152,271,606,787,904,142,627,815,199,86,390,526,361,169,237,528,979,662,769,448,117,659,142,648,687,367,936,506,383,254,978,660,274,125,391,413,645,231,640,443,16,853,9,659,571,407,602,195,228,500,486,909,759,690,292,609,426,673,658,757,372,421,32,60,764,176,360,732,744,666,740,382,676,560,837,919,708,933,881,433,357,841,4,945,63,376,961,678,780,422,602,675,537,627,249,67,991,907,215,552,8,118,851,583,933,798,887,145,838,629,134,571,51,401,546,92,780,418,292,371,969,270,392,540,325,749,755,453,967,271,306,166,452,909,139,861,44,138,802,554,379,673,319,311,770,770,841,734,800,541,236,712,526,107,42,97,995,481,929,214,464,664,721,254,145,255,398,936,234,333,838,669,628,671,120,834,613,823,149,198,577,610,847,200,117,111,653,91,7,3,18,828,657,255,790,852,642,653,976,297,57,438,760,503,117,281,475,379,896,685,373,675,758,817,337,347,459,545,725,802,631,631,367,924,221,111,303,948,259,208,650,639,310,614,686,761,964,746,440,64,995,750,227,589,457,688,645,125,51,54,594,395,528,412,976,142,142,809,806,420,588,33,848,30,352,370,150,457,737,508,969,683,901,50,671,924,799,30,500,866,958,53,232,207,859,891,311,199,698,921,926,884,204,668,68,29,255,943,927,57,462,443,685,548,26,58,722,681,250,851,408,698,117,434,162,659,930,750,149,611,198,212,904,963,654,228,884,874,949,767,106,477,460,647,723,118,26,124,423,616,561,788,594,708,480,598,76,243,664,850,232,897,531,81,620,464,151,577,742,472,945,98,897,142,209,937,669,31,545,966,73,884,976,882,429,656,534,574,895,142,443,87,805,675,764,391,168,588,548,160,717,864,234,398,163,167,347,486,650,417,850,136,533,629,329,294,50,630,195,446,881,927,69,684,266,536,395,823,713,765,788,857,702,158,172,444,716,704,389,838,196,957,158,128,534,114,464,627,518,902,116,390,152,267,560,747,266,167,742,808,57,673,183,888,877,652,677,507,716,996,733,496,873,875,73,733,961,410,962,579,973,104,301,729,949,838,21,794,746,924,500,468,274,511,402,4,190,379,280,531,980,437,550,709,210,323,694,24,887,322,876,89,754,886,372,85,865,632,284,377,522,910,578,220,457,409,640,276,647,211,37,100,285,625,73,991,170,622,919,853,478,968,322,352,427,595,512,810,7,300,22,366,650,310,488,859,459,743,727,209,17,609,348,78,19,631,3,598,608,108,349,491,939,403,851,973,831,918,606,639,806,865,243,578,407,680,411,915,669,531,755,436,852,655,501,598,930,687,596,671,777,418,361,908,587,510,321,949,325,353,436,252,191,380,25,0,287,95,373,497,341,933,514,779,911,761,693,485,832,104,875,617,819,127,956,513,282,222,110,81,929,72,512,103,656,133,390,84,69,433,436,39,731,526,458,760,324,199,41,860,284,37,226,554,318,769,990,253,235,496,124,240,843,184,87,10,734,759,985,256,560,389,167,220,174,603,439,527,185,784,138,458,210,930,614,372,525,200,94,561,74,676,594,264,635,84,785,733,247,224,22,508,907,571,895,838,354,590,702,818,966,52,130,329,585,621,871,419,451,272,776,189,154,838,961,593,379,487,885,15,403,861,387,787,407,300,229,214,326,496,889,153,207,839,228,386,715,680,305,939,724,804,318,172,911,150,278,6,632,863,718,681,548,830,296,420,79,428,771,948,819,917,826,70,116,344,614,815,657,925,499,290,36,372,201,885,874,571,306,58,785,721,602,106,391,848,926,659,497,256,780,370,811,588,634,984,699,90,564,976,397,811,56,193,425,829,818,383,801,556,662,432,924,932,937,527,357,255,479,380,762,225,446,618,667,430,140,605,669,396,533,692,602,871,147,776,785,296,445,133,473,94,793,80,653,102,50,143,188,194,450,539,951,854,344,354,795,329,983,280,535,96,978,233,642,829,89,873,332,862,631,330,517,939,72,686,734,106,249,52,818,170,321,529,175,906,572,614,953,268,211,905,146,316,319,763,970,446,350,249,175,432,916,178,823,771,133,225,57,341,528,814,48,178,862,506,62,887,600,717,142,665,380,630,677,391,779,723,292", "164,814,415,329,387,967,54,581,492,102,363,900,838,16,201,799,183,13,663,754,264,633,198,786,746,633,703,463,834,77,81,136,844,738,953,776,668,797,328,828,721,698,656,84,372,907,958,242,658,93,825,731,437,678,19,317,953,967,359,654,839,410,992,967,980,767,264,543,238,570,560,684,558,490,382,363,10,645,565,942,608,434,415,749,236,71,330,984,653,723,373,193,502,192,776,230,596,424,952,280,162,63,378,64,266,419,6,84,684,603,726,382,948,937,45,611,605,563,518,918,156,927,213,621,935,156,811,749,367,86,228,763,204,344,743,310,295,502,311,513,743,485,616,885,383,890,521,988,438,142,198,551,5,227,835,93,208,110,76,321,826,383,763,70,628,780,71,449,616,134,610,250,762,708,747,578,765,707,753,685,68,318,69,988,433,244,626,923,865,635,123,964,397,416,27,965,695,662,888,236,255,451,562,577,799,758,416,924,75,219,288,999,598,739,698,323,318,951,168,163,188,806,859,234,235,18,388,275,850,370,872,21,151,125,865,337,590,509,518,392,606,559,477,145,348,352,661,21,832,816,699,690,955,122,670,780,28,607,326,796,95,962,301,610,419,335,28,876,748,137,70,147,404,533,858,336,786,461,665,526,608,401,213,887,342,852,452,138,927,642,663,557,274,153,943,577,885,581,590,939,325,734,178,208,718,750,345,297,447,812,916,541,631,113,680,722,191,603,485,253,83,78,413,905,519,808,171,885,920,995,447,581,14,955,868,380,566,791,238,462,184,52,234,552,674,127,571,268,254,410,951,268,130,645,74,457,91,682,828,228,161,938,830,737,528,727,253,713,508,521,11,320,394,905,764,459,671,730,777,826,207,278,606,887,861,399,414,244,415,159,697,325,203,461,186,759,292,517,282,252,602,691,902,10,826,294,947,927,910,708,686,227,152,95,316,19,321,996,387,353,706,883,960,808,272,560,205,494,298,694,154,23,988,358,506,405,346,563,526,179,558,216,146,541,759,814,906,24,371,523,865,967,46,510,321,777,823,286,141,745,526,49,546,107,154,234,726,102,916,294,761,993,532,796,401,268,61,908,794,769,153,298,880,164,576,852,839,505,231,847,334,172,179,558,576,571,283,966,903,244,711,671,1000,370,195,884,59,166,335,453,466,321,656,155,196,7,91,425,230,902,222,427,790,749,987,548,583,237,646,452,19,456,31,534,870,743,893,514,789,434,184,778,233,177,344,569,107,724,812,250,718,156,72,630,279,56,755,787,606,289,73,469,877,358,113,250,945,282,977,977,22,662,734,769,45,122,983,704,721,865,395,232,437,746,656,50,171,494,160,816,29,882,237,803,579,915,452,352,7,733,590,23,41,243,791,963,885,797,461,115,219,931,146,536,751,758,992,646,940,164,996,554,420,764,856,785,266,343,852,329,766,822,89,217,563,338,703,215,19,986,392,996,855,846,836,266,559,436,732,615,654,267,148,256,303,786,28,610,877,356,73,685,777,824,836,206,287,0,502,659,210,857,973,888,997,193,214,760,935,734,815,74,26,506,91,395,42,340,911,977,894,967,382,25,842,217,514,980,744,563,811,588,691,299,204,585,452,821,760,174,538,203,406,565,172,435,567,441,626,548,968,141,634,546,943,773,450,615,517,582,445,968,646,268,740,613,352,449,594,162,63,536,403,151,880,60,653,906,256,358,722,483,666,604,312,916,155,340,687,438,287,545,528,342,215,738,349,444,318,382,553,812,791,263,446,928,847,691,363,419,930,953,306,936,446,354,938,215,271,522,729,224,2,296,457,970,598,554,159,205,78,331,10,20,688,944,159,699,953,828,497,910,784,768,461,432,134,103,527,74,586,506,804,756,191,271,73,47,418,349,908,975,965,410,98,965,545,114,962,220,645,365,818,711,835,628,666,600,725,773,174,980,527,690,552,180,210,819,903,538,181,845,368,426,296,460,714,657,106,144,404,202,43,661,943,554,584,6,903,862,564,828,236,332,899,339,475,932,505,940,420,388,211,677,727,9,788,601,347,542,747,877,450,240,850,127,10,490,751,439,564,37,610,224,833,280,979,669,748,427,660,344,83,563,23,101,75,111,511,634,902,758,715,700,965,159,141,364,273,378,894,785,681,967,933,261,217,153,89,979,62,441,727,296,595,89,618,909,532,336,185,107,368,247,318,470,447,704,624,14,541,433,653,236,95,348,790,58,777,244,965,522,931,329,867,155,828,540,524,655,829,666,333,963,286,548,854,487,954,378", "806,656,475,156,855,735,103,627,964,330,284,639,672,734,903,400,138,101,853,291,556,946,973,918,648,136,859,600,209,985,90,729,76,327,888,464,905,680,365,175,914,408,765,600,662,751,691,847,802,322,795,806,543,645,824,336,915,134,899,891,341,454,446,443,589,186,257,706,219,567,107,885,710,72,297,691,824,986,990,488,396,196,710,21,356,189,627,91,392,282,721,765,605,445,273,598,901,703,498,761,377,957,300,725,788,790,744,404,764,846,465,383,69,688,146,472,622,422,221,985,208,809,91,897,312,783,53,887,151,155,433,758,12,489,644,567,825,733,455,347,71,868,660,682,374,897,81,527,524,309,907,504,39,227,869,75,465,378,494,885,786,80,454,446,719,145,870,438,45,680,802,713,253,893,399,340,393,245,667,463,723,762,421,386,56,194,516,380,632,869,579,382,334,190,159,403,686,148,755,757,948,291,594,268,102,716,992,668,581,508,680,718,859,244,358,335,291,234,943,667,94,580,7,524,448,672,578,12,835,292,785,760,78,72,565,411,690,832,632,906,330,621,31,278,600,200,521,568,407,956,122,596,987,986,431,146,816,300,108,145,339,290,301,915,224,568,63,612,303,89,634,329,324,739,945,406,605,965,417,303,938,971,442,40,336,545,302,362,930,74,918,174,767,133,213,235,371,657,955,716,121,187,730,76,385,734,672,910,716,942,202,50,888,138,4,785,665,875,390,592,470,372,90,231,683,956,171,38,542,863,927,51,49,181,259,228,741,40,594,946,137,77,827,915,769,355,638,292,466,265,677,657,378,650,159,464,728,644,284,272,894,647,739,660,583,366,120,953,649,219,748,480,981,282,918,865,413,597,936,59,798,141,429,977,293,230,293,498,117,964,784,617,493,601,129,888,722,888,97,704,252,825,97,546,782,577,145,166,37,556,943,868,117,421,582,171,198,448,489,303,392,214,648,660,117,964,694,766,491,47,437,348,419,630,389,541,803,693,815,550,426,190,928,862,422,390,358,313,207,6,779,452,989,535,630,895,333,419,57,261,231,973,495,651,149,189,974,255,392,416,906,904,684,133,58,226,640,81,670,175,356,374,288,95,465,165,907,28,615,208,603,795,725,525,442,432,523,889,166,337,183,108,150,72,481,599,901,260,411,328,957,316,659,343,133,357,414,501,157,690,535,755,7,131,917,641,748,154,28,143,251,130,727,243,898,881,766,84,182,53,828,262,35,295,492,999,44,998,492,133,621,265,716,924,804,945,715,428,937,812,899,952,599,318,700,74,815,475,22,641,363,388,990,614,44,225,588,32,360,167,222,816,942,728,742,570,417,366,634,190,27,300,28,429,698,901,689,241,802,173,536,753,633,308,905,239,188,794,342,505,881,384,855,843,792,773,362,637,803,357,740,549,415,8,603,613,991,207,574,530,439,921,338,237,697,130,702,430,38,450,500,247,896,164,234,217,357,270,118,833,931,89,128,572,79,689,175,969,664,795,586,967,985,511,151,48,95,502,0,802,114,887,91,137,577,76,866,32,442,827,569,849,138,32,266,928,244,970,589,610,952,724,973,327,646,615,377,560,570,614,807,473,681,899,941,908,43,398,516,302,190,16,435,507,656,822,819,440,712,780,762,841,22,849,179,459,118,993,330,930,161,974,520,412,806,872,753,92,755,94,71,892,786,215,338,886,620,986,963,982,989,961,658,350,273,917,903,532,736,212,897,65,261,202,788,52,99,292,171,184,809,78,738,950,38,777,399,5,955,748,578,324,305,424,445,673,367,414,170,889,98,64,830,413,934,102,424,72,965,874,466,447,4,695,185,184,59,85,480,104,941,406,841,733,452,684,186,583,865,589,671,781,753,518,883,653,1,45,491,518,226,307,41,104,231,731,977,257,502,604,106,232,438,870,682,906,495,616,271,842,362,604,342,927,856,348,873,475,591,978,919,771,732,385,167,982,957,821,7,869,969,29,449,295,665,264,819,892,369,854,982,25,248,274,18,257,143,476,252,593,482,343,887,797,78,871,137,999,869,283,537,149,542,599,897,226,257,316,295,56,323,894,926,53,548,125,924,628,816,647,204,103,360,199,143,341,736,87,636,211,688,938,692,762,524,669,857,592,249,872,58,459,852,164,364,501,436,366,74,382,33,766,708,141,211,747,602,612,982,90,239,51,101,118,606,221,269,651,941,896,233,987,491,32,868,184,165,155,932,68,280,435,730,692,165,834,864,533,587,935,628,155,728,429,645,993,959,242,515,833", "187,236,851,488,65,177,668,340,544,547,636,80,776,12,576,724,844,146,543,31,952,837,952,589,409,389,178,503,677,586,909,557,974,352,32,914,546,561,117,772,897,79,353,640,585,630,129,235,847,964,862,323,566,727,220,305,310,651,406,997,850,423,726,329,643,436,263,492,118,13,41,288,973,604,208,819,535,79,24,259,144,643,175,585,4,971,902,208,519,66,907,640,497,761,108,578,143,173,498,672,157,371,982,223,866,563,536,127,510,568,496,371,225,83,423,550,180,69,277,571,588,571,704,973,48,167,821,910,456,783,905,413,817,259,585,613,33,784,374,851,744,901,837,943,497,980,745,540,720,717,780,99,76,493,89,895,298,533,903,852,403,709,293,57,875,237,651,440,443,589,369,234,967,62,792,394,670,234,928,531,516,647,361,490,22,647,951,327,312,802,669,489,578,755,922,898,863,468,117,217,350,400,979,299,299,820,227,855,776,677,666,124,878,76,203,871,917,416,141,232,647,504,438,77,623,641,290,484,22,675,119,952,591,185,481,507,548,402,954,21,375,977,31,989,693,451,615,462,499,771,402,828,443,780,223,482,655,236,299,944,453,179,947,880,816,852,411,434,763,173,603,874,808,708,987,549,836,710,2,512,692,839,152,484,973,921,934,635,702,192,989,564,223,840,581,957,251,57,858,742,337,444,21,237,84,289,845,296,244,756,73,560,984,834,721,800,226,514,465,626,928,357,388,535,376,284,922,681,930,554,297,187,411,964,373,718,629,618,216,348,354,706,100,838,38,140,543,322,197,695,202,381,401,899,801,179,320,129,971,583,316,476,950,512,519,702,658,234,781,925,426,834,13,255,229,456,957,908,472,161,450,571,382,201,475,988,112,998,321,577,942,304,925,968,199,489,495,852,991,435,698,780,852,701,638,960,504,388,353,790,511,693,645,323,173,914,521,686,674,90,124,882,332,164,972,517,780,391,177,52,341,932,596,609,525,677,318,842,386,671,423,284,116,197,258,941,615,275,120,434,752,759,657,476,242,14,588,242,395,538,854,4,817,784,478,575,806,852,860,760,605,694,756,547,118,236,231,283,551,246,386,577,361,536,257,167,686,448,574,628,963,102,242,1,284,70,582,68,706,671,523,892,704,986,139,267,610,73,194,190,654,721,793,431,583,956,574,793,5,993,423,899,44,54,302,698,958,197,974,998,875,33,408,183,497,203,288,648,117,160,268,250,557,742,799,246,473,647,342,422,942,331,131,455,389,574,542,939,813,714,879,863,558,999,308,802,334,476,611,748,73,348,56,140,662,634,239,120,939,769,631,742,681,840,41,913,10,566,648,42,666,594,211,104,424,443,167,647,343,934,788,758,766,272,12,328,736,932,17,54,485,303,493,841,626,514,322,944,74,382,793,916,206,351,42,182,737,625,120,946,844,520,589,57,642,395,233,436,157,320,63,959,102,869,146,121,126,31,188,709,75,405,795,618,491,689,317,12,415,65,907,163,429,674,378,729,373,659,802,0,322,311,992,377,575,244,441,7,725,481,383,837,98,455,406,880,682,357,646,928,178,486,536,849,494,861,601,114,653,570,4,863,375,5,172,884,698,571,622,174,130,98,915,478,1000,17,775,331,91,283,207,522,425,284,981,26,311,244,36,896,69,847,945,517,503,146,116,442,739,198,542,68,301,132,151,672,336,734,487,614,935,393,97,159,157,679,319,784,267,33,12,25,293,709,605,653,724,487,555,355,126,525,87,579,695,444,384,56,134,844,927,748,446,393,843,640,868,555,945,909,176,474,435,232,739,822,663,879,943,897,871,674,321,938,338,515,320,582,880,270,786,149,955,576,849,286,644,322,168,602,767,553,119,905,535,695,702,292,836,374,144,419,279,635,514,338,244,22,955,165,877,209,38,901,411,693,794,900,576,204,848,343,888,682,603,910,660,527,573,551,280,854,227,759,552,902,466,743,838,163,627,288,345,283,102,748,794,223,921,93,944,280,94,388,974,497,609,970,276,878,723,816,562,868,184,471,869,677,356,659,475,77,190,619,133,185,288,796,767,241,3,994,539,529,600,306,427,727,673,141,952,347,79,479,594,731,831,293,544,149,482,658,795,769,460,643,508,183,737,873,467,488,98,498,926,728,443,466,691,874,440,633,966,665,217,803,94,522,511,869,565,526,168,603,116,401,574,481,251,130,782,40,484,99,107,802,516,805,636,884,610,726,52,957,836,539,857,875,845,452,379,524,397,381,342,862,887,67,646,63", "989,262,274,645,382,766,113,686,852,550,445,617,937,131,577,628,56,208,491,805,693,725,16,389,108,887,491,627,431,341,816,550,566,703,502,928,792,649,289,786,884,654,214,592,625,334,964,954,409,304,910,964,786,914,834,36,297,829,477,112,797,4,327,607,703,80,908,299,965,837,990,66,68,30,179,542,77,849,897,999,462,774,33,284,233,110,714,155,388,71,91,441,214,108,854,550,339,740,230,134,336,685,599,830,114,233,901,843,356,678,132,715,39,693,734,217,510,275,662,213,781,301,890,382,721,89,447,33,375,635,357,280,712,819,214,108,322,594,787,788,789,437,502,505,593,888,573,274,862,180,85,702,173,831,620,739,582,46,993,625,811,595,395,494,455,306,764,289,131,504,424,522,401,882,293,432,143,721,759,906,23,923,111,219,698,342,873,968,275,404,395,866,490,119,67,496,174,225,304,278,632,598,816,866,634,901,414,588,647,328,349,551,332,246,548,494,278,705,953,119,753,712,990,817,121,820,497,934,213,813,442,938,723,720,695,148,18,271,261,922,306,788,204,117,544,281,276,740,614,940,599,146,268,448,481,155,128,266,674,208,21,398,932,331,617,694,649,719,206,626,294,771,448,431,475,516,905,436,247,617,77,468,792,55,643,215,760,467,613,443,661,217,430,403,896,838,796,535,297,150,761,581,490,318,509,528,278,552,519,740,127,594,812,61,92,88,979,659,693,262,714,727,402,9,670,886,498,318,716,90,478,688,677,516,127,819,811,392,571,560,335,412,920,284,52,565,680,697,243,259,628,177,464,519,789,244,853,609,116,56,618,619,278,481,311,671,662,162,697,883,968,126,441,852,797,211,181,36,163,364,873,271,539,671,262,333,113,404,521,583,350,943,20,91,289,705,873,667,488,799,196,220,513,308,861,655,527,275,797,199,193,347,521,924,745,191,249,163,420,947,532,551,733,192,313,876,239,971,923,238,715,180,996,113,132,5,517,374,355,726,121,96,866,287,766,241,792,36,3,570,212,503,405,104,271,844,681,166,63,432,532,218,713,501,785,311,809,848,428,453,854,378,869,964,860,446,610,299,778,352,586,509,635,529,508,361,127,190,167,257,465,728,242,429,566,363,332,60,772,805,867,227,89,343,319,44,167,531,174,17,618,48,506,936,858,804,249,200,111,682,7,454,426,523,314,134,297,275,118,986,926,483,800,526,542,655,284,992,86,756,54,653,899,15,920,737,547,973,714,989,445,573,397,296,587,789,122,977,314,591,423,125,717,971,762,418,603,558,59,562,814,187,5,468,191,97,216,745,831,6,81,728,426,896,421,973,948,479,852,855,444,649,938,573,516,320,848,516,289,252,764,3,556,470,363,709,839,608,770,592,170,933,367,891,892,756,484,329,317,552,896,944,836,18,81,853,628,610,931,604,725,416,504,442,606,563,793,677,185,332,679,885,653,494,338,143,906,197,470,118,19,645,282,304,466,182,269,539,86,355,340,333,108,340,952,11,497,210,114,322,0,246,430,989,897,512,380,976,550,851,513,582,583,329,822,29,988,726,163,15,166,426,645,612,93,790,8,195,41,626,989,896,158,541,958,83,65,139,156,160,631,393,956,976,457,886,171,896,974,372,393,939,872,323,520,963,936,827,423,448,853,293,529,943,968,947,267,396,62,509,313,708,937,146,708,409,409,863,821,614,825,536,682,101,260,839,537,315,282,127,128,344,122,704,377,452,120,337,748,268,495,753,407,424,441,281,364,803,40,344,139,221,651,46,744,812,621,651,392,195,384,366,912,560,306,963,833,101,116,307,951,923,794,394,870,518,132,819,824,12,621,122,213,801,863,813,733,169,969,288,868,858,353,216,868,34,663,641,273,683,88,228,956,462,357,689,399,24,639,687,411,793,946,84,662,609,901,786,443,543,233,223,948,619,522,508,828,888,306,166,751,89,540,645,264,858,855,556,93,805,545,421,894,312,198,148,783,428,833,495,124,881,366,978,803,278,738,252,877,393,381,267,675,159,860,591,987,221,742,401,565,51,477,482,963,765,286,643,524,489,848,119,11,183,572,107,750,461,765,116,844,200,143,104,628,565,340,324,745,72,705,173,47,790,863,203,379,314,405,269,33,898,680,413,469,159,167,662,527,759,154,497,391,209,475,779,475,174,159,464,887,742,391,960,116,478,136,459,108,357,972,664,541,800,913,585,221,46,879,858,8,324,461,351,406,866,567,646,483,761,463,320,464,226,138,455,667,789,842,71", "178,476,953,398,504,349,700,690,961,336,850,774,989,794,245,969,336,962,791,537,847,391,265,591,285,301,439,851,359,884,802,127,636,250,334,931,68,500,822,528,389,73,91,200,70,473,957,802,782,874,438,747,907,919,40,70,703,976,983,21,43,429,471,357,383,756,894,241,122,813,752,964,480,844,451,271,274,559,629,197,823,66,907,598,297,218,821,892,912,687,507,780,114,107,454,879,849,87,129,885,484,988,507,350,278,317,414,969,79,245,331,339,883,84,510,716,151,667,762,34,528,106,99,749,329,749,315,314,600,111,1,603,439,986,413,99,990,829,162,428,223,132,813,201,932,530,570,967,5,17,879,634,842,267,502,383,544,457,34,284,268,698,14,685,372,399,280,775,393,998,453,223,432,564,570,377,943,629,833,685,405,34,339,237,93,226,4,542,326,899,337,150,805,117,302,35,854,280,800,603,139,830,558,95,875,712,460,621,503,363,95,122,73,297,269,478,443,46,625,71,98,808,263,163,655,808,438,465,464,83,195,302,347,142,645,256,902,975,706,130,164,245,795,835,441,806,982,983,635,511,963,580,916,10,147,680,171,243,286,925,411,300,861,814,298,588,379,795,27,771,22,303,999,184,1,301,662,469,393,911,456,972,701,769,660,763,114,328,524,627,469,941,989,398,338,382,675,100,934,31,194,243,781,356,937,855,364,736,377,850,66,973,927,397,714,959,847,449,231,621,421,29,554,170,443,323,848,557,844,895,145,335,329,274,256,711,204,562,95,334,684,651,438,344,280,549,274,772,872,271,709,338,251,573,552,71,498,746,25,280,879,416,147,952,632,748,92,277,333,894,890,721,61,979,968,288,18,448,967,427,93,933,431,844,208,63,748,574,596,130,435,573,126,183,802,518,992,154,586,589,685,827,761,519,945,695,944,156,751,482,424,28,124,632,850,687,942,517,332,517,799,507,316,177,486,19,155,331,883,275,95,186,544,225,253,722,658,26,559,287,432,13,715,359,901,114,103,422,234,171,862,916,625,580,494,55,53,130,573,820,557,113,742,87,126,867,997,823,829,686,321,998,857,403,749,359,792,359,969,285,258,323,670,509,644,685,170,44,43,823,27,866,356,253,590,762,329,343,351,675,496,49,2,395,473,621,520,257,675,680,332,365,647,743,424,728,186,263,63,18,317,866,813,333,79,604,342,187,719,507,978,783,990,677,918,713,340,587,719,229,495,601,602,96,150,646,618,389,943,127,597,743,177,109,985,511,181,169,701,986,321,13,546,486,775,783,887,26,163,274,32,125,248,357,763,398,343,724,710,198,302,391,396,203,940,763,951,801,18,573,466,708,227,313,512,490,685,721,961,814,786,501,835,640,581,624,818,792,455,115,373,38,256,370,262,518,53,247,812,438,539,471,578,749,579,996,441,862,812,870,562,46,962,332,505,928,964,505,177,360,43,555,316,155,827,28,908,897,324,86,100,436,64,209,309,600,251,476,704,381,681,215,762,963,205,16,341,857,887,311,246,0,327,831,912,280,418,605,140,510,686,125,38,226,614,705,969,378,326,158,902,259,759,442,444,484,78,410,22,653,880,469,868,65,929,677,83,768,35,401,378,743,434,833,894,948,560,623,888,844,709,106,46,468,409,100,665,26,558,114,3,876,744,138,333,324,650,473,648,591,783,199,900,440,431,456,802,139,475,155,324,273,789,829,44,362,237,337,152,24,557,24,204,905,391,171,961,626,445,601,428,903,101,442,834,587,773,184,455,329,571,894,815,748,472,564,443,931,402,433,799,505,645,916,646,259,834,991,232,770,991,146,64,411,873,164,428,109,147,574,547,899,709,168,516,9,920,139,279,646,127,554,278,783,736,520,608,426,523,783,8,954,588,749,770,478,318,723,420,272,61,921,497,532,764,281,637,932,772,718,817,283,888,590,300,95,98,399,346,218,675,351,77,518,866,443,726,581,217,128,563,675,717,600,253,942,861,684,298,241,795,290,806,587,290,498,927,62,548,223,405,264,16,698,589,292,736,68,694,722,609,121,28,782,721,861,660,330,243,602,671,718,282,493,530,733,628,682,417,187,760,773,996,661,348,879,569,635,716,452,431,963,432,293,443,657,559,130,107,19,536,257,880,217,967,706,802,252,24,911,808,25,955,777,262,807,369,451,725,245,174,627,991,124,671,353,887,147,676,608,530,689,16,496,470,4,602,680,706,693,24,116,230,139,712,329,475,116,439,978,792,919,728,379,453,879,145,710,499,555", "257,806,899,23,586,119,736,248,608,70,798,145,62,153,53,509,354,513,738,766,663,38,351,714,472,689,347,258,374,371,29,415,22,261,990,772,105,318,861,82,573,317,983,345,224,346,349,595,262,790,505,653,560,88,60,543,145,651,89,541,803,86,417,947,106,129,299,794,866,566,104,40,67,634,52,418,365,174,343,737,634,929,723,3,545,744,682,103,400,342,861,52,472,856,376,261,298,115,782,718,831,202,205,531,552,776,666,722,246,200,459,805,209,937,406,728,632,521,886,984,683,742,475,290,896,925,841,927,701,847,927,478,28,831,19,359,693,451,279,987,831,69,598,319,576,923,813,900,754,271,857,899,791,428,862,929,603,294,74,565,824,484,6,792,987,810,935,796,622,762,583,671,532,668,274,334,477,822,724,595,438,11,5,6,925,757,43,8,451,977,357,834,176,692,699,934,869,426,603,180,709,137,167,226,733,499,670,610,691,371,89,730,387,828,823,575,284,746,52,642,985,70,321,118,30,849,175,683,392,545,63,951,498,130,144,398,829,674,421,839,857,278,566,2,161,455,809,124,583,949,180,551,228,520,836,699,896,78,949,207,924,746,772,412,191,113,723,98,338,297,63,516,140,304,518,299,360,279,123,371,496,613,585,48,96,896,667,971,349,231,272,707,558,492,716,300,73,892,81,657,94,948,494,89,939,238,794,771,433,633,924,27,494,371,802,621,169,417,173,507,126,197,371,31,490,185,881,868,581,404,602,242,316,31,491,161,499,321,768,236,739,803,994,915,237,229,715,827,793,230,803,51,659,309,200,262,561,638,59,844,112,304,386,845,238,432,405,231,468,341,398,283,765,644,750,214,708,226,833,801,829,709,254,484,741,528,2,401,782,153,635,441,434,842,159,673,93,772,157,612,566,3,623,668,986,581,887,253,167,151,354,724,386,953,402,445,778,407,808,334,499,190,759,68,859,89,102,948,405,588,951,405,78,786,58,915,617,900,852,723,931,709,903,771,479,12,960,429,473,88,179,755,460,546,46,565,24,538,173,774,15,212,946,987,39,255,813,653,333,701,13,94,805,539,935,930,345,463,319,679,352,884,909,413,286,381,845,232,36,634,384,677,898,331,195,201,969,343,593,589,159,182,842,346,754,707,867,29,40,878,121,308,336,739,783,177,450,751,364,129,337,342,666,305,412,682,270,344,88,636,508,186,762,387,552,145,54,730,583,215,511,562,485,246,685,689,192,371,600,311,288,150,459,459,309,998,421,126,344,2,693,740,585,960,788,592,839,240,52,484,728,873,141,533,221,512,130,440,315,986,93,732,464,207,497,206,595,599,745,120,136,349,473,368,821,911,327,456,285,815,842,609,252,548,735,677,350,356,802,834,554,113,217,347,288,936,299,157,961,770,397,123,952,809,969,334,143,250,635,195,586,16,686,847,164,774,478,817,68,486,694,329,698,920,711,475,361,307,803,877,602,525,301,117,575,133,981,233,39,924,398,886,132,255,549,597,933,973,91,992,430,327,0,256,439,969,344,339,851,315,372,219,575,898,360,512,824,103,829,936,946,599,795,980,691,216,974,403,738,666,448,570,562,631,271,768,291,601,746,323,424,93,517,930,946,851,121,640,965,661,830,535,132,752,593,353,696,295,435,612,137,766,875,220,795,529,416,28,836,889,200,417,101,111,347,173,388,296,342,151,828,653,766,883,734,915,628,572,799,169,722,926,190,136,184,563,56,26,255,694,873,122,878,332,147,586,362,648,766,913,379,400,376,104,291,232,413,230,184,212,850,901,56,543,317,728,341,686,136,858,23,575,729,272,809,514,461,382,470,554,216,877,98,883,280,993,571,932,744,841,461,496,870,931,794,102,390,259,807,64,13,931,636,181,338,157,622,926,229,395,368,154,179,281,218,701,489,216,692,438,720,551,174,557,230,881,319,991,59,504,795,37,9,902,818,96,400,611,217,475,787,302,683,598,992,312,405,837,580,813,778,566,937,247,127,155,539,3,507,445,787,128,999,440,453,6,718,64,312,20,830,940,633,633,520,938,83,736,398,473,918,765,126,779,559,964,745,967,286,723,432,962,615,798,400,538,297,781,582,653,290,255,94,18,666,560,994,574,933,976,311,658,241,51,364,145,639,561,114,316,401,942,283,754,347,191,283,689,541,853,38,11,675,395,530,765,951,260,100,783,847,192,413,839,585,879,140,69,679,822,870,260,454,912,572,716,991,116,997,712,24,338,155,134,818,891,522,976,350,667", "835,589,29,214,70,493,399,880,115,555,516,633,850,315,764,761,963,566,757,543,171,712,308,825,470,586,168,496,694,381,514,282,345,93,382,932,912,667,12,576,772,478,739,35,24,846,243,289,741,495,516,835,361,612,515,97,680,300,386,360,96,669,291,486,803,436,963,165,672,409,781,974,974,163,552,579,66,35,7,684,309,906,304,974,626,247,929,351,714,208,511,528,472,856,539,525,273,891,988,339,558,990,441,774,96,321,441,893,801,68,894,730,623,764,216,20,816,91,384,198,40,691,640,997,671,945,980,404,829,386,724,997,584,362,173,774,935,822,110,739,50,97,849,680,152,738,414,615,811,435,965,788,532,238,673,490,536,68,843,115,991,672,187,458,573,603,535,116,913,580,230,696,752,57,523,317,427,347,378,796,762,55,428,70,477,672,432,7,233,453,999,351,809,803,903,257,643,568,447,277,339,719,945,480,527,591,840,370,619,903,52,221,798,382,260,720,777,459,419,614,880,826,715,636,842,135,858,891,400,912,533,756,579,717,505,817,288,729,787,290,42,698,830,81,899,4,363,333,751,254,539,137,991,722,897,330,530,295,784,48,47,500,291,945,912,360,788,974,43,721,271,909,966,783,847,937,104,889,943,817,539,150,943,469,554,521,877,935,71,369,933,730,55,575,611,147,742,400,790,879,756,430,441,375,894,58,958,992,881,695,862,421,354,321,830,450,950,306,762,521,491,593,840,679,433,423,478,701,868,569,557,2,197,383,181,878,558,766,85,852,192,415,67,76,755,348,109,871,136,387,979,138,657,400,180,474,929,251,442,778,559,991,935,360,606,289,341,887,846,590,673,181,70,962,748,348,725,687,572,243,347,399,96,806,644,241,284,619,527,988,752,975,777,61,553,491,467,780,919,433,949,70,951,841,63,255,891,553,159,338,215,308,677,170,282,644,901,456,399,421,153,682,779,315,420,347,946,363,85,70,525,363,726,557,739,148,822,446,488,316,411,248,629,558,409,67,894,696,629,377,299,840,694,61,473,78,222,696,442,215,124,681,13,50,617,891,254,10,373,830,763,877,613,626,595,428,624,84,100,642,909,34,347,278,544,666,274,166,807,957,518,429,550,153,50,537,633,306,910,508,613,460,685,948,38,335,747,668,656,596,520,489,470,707,988,312,756,487,733,679,175,102,52,866,923,379,654,92,265,870,336,92,555,345,698,119,248,346,767,943,28,375,36,643,663,610,665,929,92,223,142,606,766,919,38,694,468,52,419,51,738,547,453,940,890,95,375,699,965,58,720,138,95,161,613,232,571,114,59,129,477,691,319,490,774,983,929,418,912,761,220,98,342,559,344,91,613,556,560,857,671,346,526,160,626,180,22,783,785,234,70,80,501,795,5,751,242,965,405,834,271,372,348,441,833,172,685,269,552,942,59,230,27,25,264,86,405,595,392,99,801,612,118,205,135,599,902,275,72,669,990,971,908,677,550,162,502,62,320,497,746,704,849,270,275,323,514,888,137,377,989,831,256,0,583,194,627,199,452,10,780,664,353,660,314,507,29,971,96,743,13,991,577,441,399,951,505,643,357,434,885,336,734,433,21,310,500,784,618,714,419,612,398,841,720,853,255,426,229,189,735,329,270,48,453,71,82,471,485,23,68,613,811,536,635,656,291,619,201,668,772,465,808,429,542,318,71,727,209,636,607,580,345,237,661,156,691,124,666,140,479,769,785,77,672,350,710,478,498,774,256,472,440,727,229,633,814,280,515,429,289,278,435,349,851,614,655,143,479,766,325,474,614,951,207,20,989,352,172,242,436,55,248,799,50,46,624,245,383,346,627,382,377,515,580,181,115,599,74,338,912,560,920,544,974,911,618,927,132,584,992,868,186,853,476,291,581,904,147,203,123,829,643,983,33,552,474,253,504,577,453,103,472,990,312,961,79,498,566,249,177,790,429,622,674,465,169,153,679,843,990,726,232,289,749,158,638,529,854,116,889,166,181,584,558,538,787,717,711,963,114,968,983,347,29,299,926,152,167,65,888,527,12,401,113,519,981,603,3,374,533,40,554,178,657,762,2,407,112,175,829,173,130,215,95,459,73,732,798,900,868,328,419,409,253,228,56,929,867,573,110,747,479,861,784,302,207,110,723,525,500,968,824,357,691,187,609,320,441,178,502,937,437,546,508,792,806,236,902,956,851,739,501,600,791,456,860,677,530,29,750,77,257,385,963,675,266,903,691,112,691,38,315,302,390,464,132,204,793,343", "516,155,442,709,704,957,458,878,242,305,465,261,262,454,828,278,915,770,903,61,576,21,22,471,730,705,876,856,352,300,883,501,828,538,293,339,88,269,589,959,335,519,990,174,693,184,783,654,797,918,450,2,33,299,930,413,476,924,929,701,635,151,432,201,969,536,778,216,34,182,695,252,272,507,419,857,64,385,32,360,310,973,644,206,815,483,731,387,694,251,796,282,207,498,781,121,182,640,900,439,429,961,851,122,251,122,342,679,569,496,80,984,440,269,335,308,465,4,430,392,699,785,999,833,324,75,329,873,63,12,960,856,743,562,823,33,462,198,834,73,83,312,832,964,676,718,906,613,991,453,762,549,451,299,556,637,625,467,577,21,17,383,942,772,827,823,712,787,942,796,781,109,92,571,662,371,868,282,715,183,132,4,404,80,354,699,994,307,737,709,183,613,46,731,235,312,995,813,232,34,179,676,297,67,388,859,49,55,506,576,830,265,40,190,43,834,264,18,744,246,669,988,617,265,790,586,343,737,949,737,342,253,665,761,715,664,258,159,944,991,2,867,491,998,450,37,640,852,524,499,59,954,198,927,272,153,886,22,691,201,788,926,25,709,264,198,82,503,287,187,61,307,781,868,282,126,204,983,333,565,323,909,665,935,550,90,285,359,591,200,458,796,769,99,561,9,114,915,548,840,785,88,204,334,645,459,531,712,729,505,517,519,540,297,975,344,230,961,456,327,933,470,565,481,944,933,201,898,266,407,825,871,97,354,643,168,349,146,713,210,132,560,529,614,50,735,835,183,296,632,438,107,961,175,840,251,319,127,767,36,829,66,99,574,856,13,307,552,613,550,493,863,944,377,98,806,753,459,656,569,860,124,213,942,543,989,709,195,586,925,978,651,431,810,540,558,540,893,71,511,422,509,256,615,113,674,927,960,149,543,165,144,583,836,614,539,807,613,272,456,952,351,643,669,307,345,657,165,339,427,836,673,959,733,844,617,509,371,490,450,955,68,97,366,765,564,626,229,443,773,413,924,438,584,515,51,881,644,606,872,232,329,986,996,688,993,326,152,570,157,147,215,737,273,334,681,999,724,549,368,516,960,585,957,404,27,885,617,811,511,403,722,256,389,794,962,475,524,164,796,896,15,404,278,921,143,169,733,843,865,910,856,831,479,672,440,453,249,368,701,707,466,654,361,92,908,778,492,494,48,161,289,148,953,388,498,440,987,870,581,143,345,346,191,972,588,844,532,997,487,161,216,472,926,678,472,164,692,325,395,395,878,415,463,652,934,489,150,104,368,338,982,657,731,520,408,183,693,175,174,133,81,418,298,523,770,62,536,18,752,643,141,971,762,170,586,870,156,79,999,543,984,452,743,210,777,399,162,365,212,53,456,257,7,863,754,180,193,401,299,661,894,868,253,322,386,342,36,754,502,129,291,608,859,234,523,547,378,961,741,225,34,119,530,791,955,266,938,271,902,922,644,420,589,386,617,933,857,142,532,71,257,959,743,938,704,779,997,577,575,897,912,439,583,0,928,993,327,530,432,605,823,25,749,716,782,640,85,710,94,447,67,719,734,634,10,715,394,913,746,714,391,259,607,253,449,929,350,95,9,926,329,150,616,336,65,175,823,990,231,962,1000,136,312,313,157,508,789,315,356,447,8,509,724,926,767,357,640,534,408,234,276,132,572,812,216,28,998,437,234,983,121,292,266,624,934,201,208,227,400,66,647,792,996,421,74,154,91,9,835,136,58,833,460,518,63,63,975,657,720,863,504,579,405,784,269,574,359,930,667,589,61,884,342,768,245,818,973,268,398,74,558,557,892,176,438,567,177,164,526,91,514,833,983,584,91,408,801,508,268,356,567,453,99,160,538,367,726,468,715,615,431,35,887,780,247,623,272,725,90,41,546,18,608,547,316,778,807,399,832,90,4,832,967,876,596,465,521,377,695,81,694,319,816,484,418,647,508,764,758,905,948,269,316,989,740,546,504,184,68,264,718,867,24,694,775,284,547,575,437,179,142,870,963,897,761,571,973,861,392,975,94,68,521,312,232,478,738,879,153,665,927,369,454,202,893,264,165,452,171,781,97,164,982,239,258,166,165,993,31,861,301,607,208,438,774,906,294,396,464,396,582,312,637,57,728,623,958,811,123,40,322,463,608,211,858,230,414,117,617,195,701,810,310,620,882,499,500,804,844,828,443,126,160,229,61,233,221,46,302,134,489,83,180,70,383,900,571,256,656,584,874,723,448,71,820,739,353,468,327", "172,935,830,875,459,388,984,492,783,595,159,825,788,770,902,940,880,64,58,622,825,443,706,477,368,317,362,143,559,351,476,526,577,48,144,822,854,513,750,588,15,829,520,912,83,432,862,576,826,831,214,908,48,54,206,445,196,772,295,239,111,181,102,653,401,405,244,445,564,8,739,420,237,683,739,37,71,521,909,495,177,759,512,267,720,881,479,494,649,548,539,563,256,243,804,710,90,933,212,142,38,815,270,988,49,131,289,337,815,866,538,691,826,326,624,442,550,970,333,806,153,629,201,448,111,16,163,4,901,186,281,479,741,756,995,19,861,204,803,592,17,196,487,885,378,831,986,945,655,969,590,450,840,661,486,242,338,655,734,155,897,334,640,107,233,766,182,558,355,194,209,559,375,653,433,606,337,853,874,786,818,978,910,951,180,229,91,604,520,966,948,209,214,568,75,109,974,771,43,281,268,314,102,457,669,704,914,448,236,206,504,342,563,658,395,304,499,372,473,656,179,791,821,723,690,630,442,691,722,472,924,537,359,716,343,855,487,951,308,529,834,630,336,889,696,407,1000,869,119,341,925,300,787,497,911,971,998,964,848,391,400,103,860,560,850,53,99,648,354,468,542,657,846,486,665,682,401,68,104,462,716,591,821,782,495,688,290,948,997,10,320,973,500,616,52,931,196,755,57,306,910,845,349,882,216,731,495,760,211,388,493,27,565,647,787,431,379,886,576,622,310,736,971,22,154,601,366,83,659,236,797,652,771,115,435,597,833,161,34,53,847,802,778,540,915,824,89,586,678,478,652,498,638,44,950,373,128,486,473,140,967,124,173,789,893,920,148,158,910,537,126,805,564,114,363,64,712,510,535,814,752,69,874,753,709,824,998,231,197,322,605,551,444,882,213,635,442,217,916,879,896,361,901,645,287,185,46,916,285,465,600,39,948,172,811,47,472,201,395,60,856,348,700,241,853,150,192,557,71,156,719,817,969,7,989,32,437,812,313,252,416,404,370,815,877,349,132,967,472,800,159,1,4,800,432,372,409,913,199,53,908,823,156,701,564,797,22,88,347,189,892,537,14,852,92,291,22,559,394,332,898,266,598,164,368,490,656,225,549,94,652,616,878,634,725,4,384,556,906,811,215,28,219,388,474,261,840,112,430,561,45,826,681,880,433,725,92,634,379,191,534,18,431,557,516,185,549,38,554,158,987,555,897,671,902,728,201,702,545,625,803,935,546,304,857,243,638,506,339,677,660,995,643,182,398,193,433,65,294,650,587,251,352,583,227,709,628,769,974,814,264,453,631,280,617,149,957,763,299,630,84,715,598,48,108,519,217,752,587,249,151,900,679,436,976,405,252,351,959,446,459,413,465,743,346,400,439,922,952,829,220,616,537,276,959,894,373,772,922,991,844,362,624,406,879,243,436,980,441,374,594,79,397,260,241,509,270,13,343,203,198,151,186,872,741,304,570,174,18,130,446,255,334,485,979,362,699,541,403,811,737,95,597,799,108,898,911,193,76,244,512,280,969,194,928,0,961,944,494,94,469,721,644,896,841,923,647,553,708,957,752,895,302,787,572,856,281,980,982,951,894,853,300,77,592,815,468,751,82,120,927,744,806,482,784,618,893,864,384,803,330,991,211,964,77,537,160,300,75,515,234,114,7,784,243,875,596,341,392,909,53,589,156,95,72,354,487,457,154,330,197,384,292,227,498,510,963,235,41,521,544,542,444,324,994,879,177,621,766,177,820,8,664,295,712,701,935,257,142,952,559,891,488,590,69,407,597,126,553,978,898,415,100,820,382,700,558,119,406,734,422,239,280,79,439,342,572,182,80,306,954,920,607,729,481,317,141,717,517,150,627,973,192,469,545,722,514,712,924,78,665,593,823,385,258,67,372,940,352,282,425,66,807,713,601,966,261,477,358,765,869,770,26,996,304,552,935,231,314,156,705,547,405,544,316,860,884,895,15,469,868,382,55,532,746,963,741,342,686,822,165,82,860,279,33,716,110,866,731,707,933,582,558,757,633,981,371,286,772,198,280,872,140,312,988,150,593,603,459,862,302,111,246,593,961,423,175,857,794,840,724,4,416,851,955,210,286,212,448,350,348,781,875,435,885,134,444,585,906,766,858,888,257,364,56,212,264,687,754,519,357,603,233,901,571,6,634,915,789,454,217,110,391,162,955,952,426,301,160,769,290,897,440,763,713,709,135,482,78,945,462,316,350,347,23,568,275,201,718,273,431,183,270,505,394,324,804,821,77,253", "594,197,374,129,831,574,689,914,664,628,259,625,364,441,88,591,802,314,86,366,111,872,327,304,195,729,751,625,9,510,391,907,731,304,243,865,256,742,524,325,790,887,55,517,555,276,360,788,525,615,125,791,907,223,878,421,672,120,713,749,549,746,726,305,982,94,565,674,275,877,697,264,172,377,549,914,198,597,717,707,58,448,264,518,519,477,213,823,343,401,117,62,673,444,669,766,279,702,429,629,572,798,263,395,72,705,709,629,490,665,77,699,541,366,917,647,378,452,124,329,483,370,492,823,557,653,986,905,856,646,280,827,708,784,484,224,338,527,185,530,900,110,499,414,376,830,538,665,323,338,381,732,329,616,82,124,634,120,723,60,576,324,106,34,559,522,927,886,348,388,222,506,226,566,686,830,406,625,612,145,57,638,36,181,295,117,28,347,586,450,971,303,901,871,100,340,829,34,72,209,525,184,463,994,105,364,963,558,804,95,403,512,622,164,2,630,630,254,403,543,542,626,889,220,847,637,700,526,866,963,285,155,288,8,924,29,894,586,345,624,998,81,10,489,496,215,216,101,779,455,197,24,607,869,856,895,129,709,975,708,431,538,613,332,305,730,61,868,632,386,988,273,751,682,586,977,440,811,532,685,547,759,552,12,722,84,952,890,115,150,222,99,431,22,361,975,616,503,790,920,386,136,681,326,936,732,354,583,61,606,158,817,197,880,76,477,815,229,732,367,261,272,714,278,62,135,309,844,939,270,92,667,952,615,931,806,675,669,696,284,313,613,641,154,297,665,362,156,658,424,951,20,441,986,648,114,709,564,416,610,168,805,573,979,738,531,740,552,369,287,301,978,891,108,202,719,453,193,556,445,190,137,708,354,138,288,677,750,146,471,755,491,63,235,698,349,952,476,675,321,988,196,989,71,839,319,121,940,838,955,296,9,745,272,670,518,756,271,599,45,478,907,124,101,695,527,106,601,137,121,720,721,215,815,571,333,880,686,68,961,49,894,624,602,851,620,582,788,532,38,374,467,719,13,532,849,412,340,387,419,285,179,116,479,449,776,328,487,847,684,182,138,456,307,532,894,926,853,96,786,677,785,453,313,876,363,229,372,203,689,901,886,821,102,93,342,46,227,812,810,114,235,432,944,948,927,712,976,631,529,727,742,221,889,650,713,464,930,319,792,958,96,569,975,145,800,899,603,858,453,994,293,854,542,375,663,532,688,441,983,202,985,627,595,286,15,6,302,724,514,367,342,562,554,478,128,361,617,414,572,4,477,476,750,155,712,580,259,69,406,176,334,364,542,406,87,485,491,721,430,4,885,848,172,862,263,311,142,60,484,827,971,19,29,730,352,924,253,543,112,139,635,606,532,971,911,775,805,156,186,539,166,112,984,684,906,337,964,790,795,697,357,168,184,626,137,159,872,727,648,233,37,564,95,276,473,161,953,876,711,497,345,823,764,60,666,438,704,914,37,621,451,989,986,857,66,985,412,385,962,775,918,915,232,131,300,761,214,866,441,380,418,344,627,993,961,0,636,315,563,979,592,620,68,79,309,469,22,70,723,656,517,182,312,116,391,291,249,144,549,973,391,595,405,230,71,935,193,856,910,731,490,955,426,67,620,187,764,881,974,944,697,805,723,394,640,733,263,853,662,172,931,16,583,92,377,343,119,607,987,693,302,86,392,127,31,397,551,25,913,696,80,546,685,885,198,437,850,604,82,266,27,588,655,223,305,498,640,314,347,822,285,520,387,875,69,702,278,345,169,749,383,49,530,582,431,423,209,3,889,668,157,34,794,792,773,801,419,195,913,215,603,405,113,218,600,57,689,500,631,124,435,411,160,176,844,674,73,294,366,572,103,188,783,169,847,193,920,360,577,193,434,678,623,961,454,568,297,299,846,275,856,954,152,75,693,207,647,852,841,912,664,567,388,692,3,832,449,709,178,233,202,310,908,596,642,367,480,827,575,895,993,465,924,436,450,426,360,420,795,420,529,696,820,278,364,662,620,924,521,704,980,209,279,819,238,155,815,722,500,902,898,521,913,460,63,225,983,647,868,614,935,77,967,309,655,206,85,65,742,225,24,230,816,6,252,171,515,881,62,637,657,486,523,100,767,135,224,287,9,13,79,570,645,959,578,832,136,112,180,739,820,997,324,315,997,902,435,130,748,746,200,843,41,459,142,186,520,66,521,499,105,444,784,570,946,696,714,817,292,890,277,831,268,248,225,302,358,489,605,391,541,182,445,816,830,359,960,272,705", "661,623,754,491,492,422,85,889,917,115,551,821,290,791,631,482,672,836,591,820,908,988,49,448,679,656,831,414,246,902,233,466,164,6,411,206,46,963,234,740,597,441,543,298,878,921,453,539,863,380,184,619,165,532,729,344,399,433,473,170,481,888,937,445,773,479,523,600,922,782,849,885,66,900,687,584,412,970,118,992,854,161,854,838,463,552,642,508,228,107,793,377,876,463,166,210,191,286,884,964,217,407,313,369,250,164,283,379,601,100,150,230,952,114,278,748,814,154,569,547,446,39,743,643,341,622,101,965,244,183,834,441,678,445,319,450,36,986,226,702,496,549,852,871,13,166,498,97,184,228,551,801,860,823,666,78,562,42,333,960,150,763,950,241,290,110,170,160,687,278,614,554,103,249,314,84,557,543,963,190,397,317,806,390,197,702,606,720,820,378,85,535,414,482,778,173,803,404,607,950,395,127,969,865,467,413,12,891,790,73,670,868,471,886,884,251,137,88,638,438,335,319,233,33,118,717,757,997,329,461,822,121,63,25,807,110,251,583,326,127,36,735,236,82,558,153,366,706,119,443,737,54,949,696,214,201,818,249,17,244,721,714,118,383,266,636,674,754,366,187,298,141,849,608,344,355,444,824,93,866,302,676,353,494,858,674,51,811,850,716,733,598,505,48,645,727,492,25,56,920,585,701,333,243,364,790,233,758,83,147,196,582,244,989,950,662,728,433,245,208,282,990,241,175,915,45,395,176,157,682,517,973,900,446,204,897,557,992,724,611,403,483,629,258,763,523,299,800,987,892,613,495,396,826,287,917,304,443,372,457,730,677,178,161,715,936,487,381,489,914,584,403,260,326,755,944,172,149,118,645,595,169,14,304,513,784,470,814,138,152,162,315,585,747,594,749,167,159,142,371,55,914,140,926,846,214,407,893,982,640,857,994,453,741,710,663,342,855,149,396,885,135,625,61,936,245,492,239,456,246,111,957,366,852,938,722,591,908,341,341,470,330,317,9,558,945,87,278,171,471,132,54,637,318,536,209,111,979,995,438,667,270,944,875,515,652,297,446,208,441,338,97,960,360,174,810,174,379,190,662,831,806,312,98,595,461,721,844,591,379,675,82,619,201,464,246,71,885,385,289,264,484,106,240,347,176,827,35,423,802,286,300,291,531,147,870,114,471,939,706,970,993,931,896,666,43,897,727,387,562,519,941,421,993,320,843,486,883,81,687,530,337,528,397,595,819,4,467,775,108,761,816,394,502,195,206,625,232,374,277,291,90,503,204,111,730,280,205,210,752,439,600,306,118,333,80,94,408,521,622,313,947,562,3,686,588,154,571,897,913,342,519,164,466,391,150,188,873,758,161,816,58,169,317,585,383,730,140,10,537,198,691,551,651,185,43,236,585,543,72,70,241,872,957,291,846,173,921,850,541,19,775,448,827,983,989,818,544,33,229,84,141,173,473,970,70,713,826,868,245,349,640,964,984,379,147,589,683,58,556,439,200,926,950,11,91,693,760,32,7,976,605,339,199,327,944,636,0,158,113,573,413,295,163,494,656,488,626,329,145,530,221,392,224,687,110,259,508,901,595,821,282,267,313,852,328,498,110,482,949,276,724,739,656,260,494,39,857,455,912,528,569,272,762,578,583,934,19,148,697,645,75,151,193,328,846,258,6,71,126,485,272,512,231,940,688,533,615,58,907,592,10,888,261,694,794,523,31,623,427,432,674,952,563,863,485,595,913,826,936,808,458,419,755,327,172,124,882,662,598,943,223,843,126,496,571,232,572,663,972,805,314,324,272,272,230,121,661,996,257,3,931,295,684,582,303,436,214,197,991,349,843,71,250,982,663,575,472,524,338,344,483,370,377,589,166,433,764,587,145,911,78,544,736,352,347,798,730,745,208,511,663,759,515,955,904,712,642,928,743,343,935,135,307,302,989,674,789,979,114,531,515,58,818,321,195,434,962,469,924,945,4,790,923,733,92,999,214,304,312,637,202,556,57,742,121,620,684,924,624,491,457,42,264,597,856,51,732,559,379,48,639,182,584,90,837,35,849,157,259,771,376,246,380,186,975,158,877,984,945,728,295,804,233,291,747,895,823,63,675,505,923,96,254,298,672,60,563,835,942,829,698,538,374,730,861,816,468,264,430,16,193,872,291,504,528,637,403,78,460,462,313,218,516,816,955,674,130,995,566,351,989,177,333,258,296,55,498,518,579,432,638,311,585,883,799,337,960,85,2,910,961,678,828,915,332,90,181,363,242", "77,546,622,668,220,513,738,901,134,522,656,166,783,347,525,571,879,24,709,265,587,14,787,276,15,611,296,749,780,829,329,108,602,929,840,633,336,729,670,986,935,670,829,996,303,908,996,785,431,428,607,904,868,84,11,626,989,985,640,74,108,293,646,461,848,513,693,354,829,940,49,852,691,687,134,651,820,925,553,644,202,796,633,844,514,548,618,408,210,147,576,400,60,84,522,280,556,889,24,512,99,489,749,895,266,337,760,671,136,382,664,119,549,246,996,323,485,548,441,299,378,100,830,321,651,791,509,945,831,190,644,370,323,242,201,960,455,822,859,52,678,880,759,535,653,779,628,62,637,16,65,463,394,405,151,554,113,351,96,697,839,429,480,278,197,107,947,321,501,54,76,180,748,146,955,218,453,672,40,836,488,224,321,999,668,503,550,105,150,422,692,465,868,512,336,500,613,469,35,78,40,867,163,549,959,356,745,138,807,647,829,377,869,544,756,748,498,306,209,689,919,649,216,820,259,866,782,720,760,121,527,716,181,396,160,652,663,737,183,354,466,127,430,772,874,854,441,885,650,523,345,882,759,337,512,389,572,719,101,275,424,675,969,84,229,138,685,762,70,299,736,774,817,535,306,959,297,753,941,596,84,53,206,448,137,245,212,770,826,11,461,592,14,716,524,944,741,465,7,549,614,664,805,786,398,952,412,463,971,537,680,544,959,196,471,724,871,994,558,475,980,378,894,46,437,483,394,545,58,970,5,871,223,323,587,99,244,322,290,666,897,538,815,723,588,941,724,588,519,943,563,535,626,149,508,327,804,192,820,481,25,715,737,273,670,599,589,143,570,257,121,497,235,265,388,499,988,57,571,110,978,296,467,95,967,100,430,124,531,920,148,802,242,995,13,163,24,117,954,925,568,279,648,76,992,147,214,250,915,541,506,882,495,896,7,860,718,189,300,423,766,762,804,687,109,929,272,966,476,253,39,677,799,392,870,138,266,180,56,454,84,664,899,345,200,230,515,215,648,649,853,791,637,526,730,572,974,148,907,849,475,18,881,182,740,642,538,525,855,113,751,994,2,11,81,677,754,31,249,658,117,843,370,961,775,770,346,712,802,758,869,538,372,314,710,926,92,252,363,205,772,106,918,431,580,192,408,294,13,723,557,705,810,816,456,634,710,651,16,114,454,35,452,88,242,368,381,373,450,353,851,982,857,935,732,502,888,687,882,155,220,212,259,106,705,442,27,159,415,630,71,572,480,844,53,59,866,64,979,451,969,44,999,346,702,822,949,262,44,711,61,944,312,393,226,836,463,764,596,660,862,59,24,951,363,430,691,327,392,818,752,912,835,18,637,670,119,519,181,228,906,389,732,216,106,62,330,274,631,853,180,973,543,971,707,576,455,953,568,932,135,660,492,287,654,769,41,360,431,528,882,268,875,316,1000,302,944,349,968,808,999,418,665,7,225,196,224,599,438,938,850,326,31,340,240,296,254,69,865,494,864,691,994,514,621,504,485,935,442,725,550,140,851,452,530,494,315,158,0,888,754,461,74,812,60,643,102,584,59,567,148,290,14,604,926,204,219,799,585,180,166,242,695,757,206,530,344,317,292,853,221,744,80,908,855,921,295,526,474,388,784,349,18,807,49,836,868,144,122,312,237,54,789,534,408,626,282,586,648,144,354,168,547,27,801,213,480,206,191,359,482,891,615,319,498,561,747,914,688,977,716,301,401,538,68,650,429,384,427,791,993,204,281,40,855,217,615,274,666,295,797,21,738,811,951,553,278,698,318,42,972,475,999,157,559,558,776,776,723,947,921,836,619,166,754,421,235,959,119,318,500,685,627,484,571,369,58,273,480,260,534,84,478,881,526,814,726,757,410,504,913,737,239,799,327,224,197,342,117,451,562,485,768,477,684,830,903,763,466,766,424,974,882,451,147,280,453,839,835,520,449,261,367,326,27,700,603,515,28,615,802,480,30,146,537,564,272,678,111,641,984,335,67,234,286,426,409,900,58,283,844,298,38,500,396,861,16,998,429,90,542,56,924,560,20,984,955,530,611,583,441,198,12,882,531,270,430,42,532,266,619,995,388,674,486,702,733,150,61,572,536,433,340,680,979,743,134,897,575,902,252,703,237,117,758,442,181,963,466,346,104,584,765,600,143,575,334,580,529,270,427,610,683,214,456,718,564,737,297,832,620,741,10,399,106,94,211,73,624,827,685,844,189,482,499,13,26,724,646,739,914,988,759,881,993,712,531,114,110,209", "28,492,73,139,308,339,357,657,698,184,849,802,528,6,376,362,84,242,281,821,49,702,560,291,295,845,73,504,33,183,597,897,632,462,953,828,826,852,541,516,894,212,418,370,475,553,844,916,75,353,526,906,290,628,498,353,425,842,220,327,865,969,602,887,768,753,652,120,54,87,931,868,624,388,268,178,449,93,989,396,672,694,244,308,259,26,87,590,298,582,926,85,973,798,604,748,558,247,844,25,52,646,70,21,115,801,522,634,345,400,402,731,807,180,270,918,585,972,669,158,370,413,328,290,596,723,167,401,65,888,24,322,480,722,943,94,151,920,919,291,656,804,366,979,166,351,400,404,401,467,213,737,9,752,571,989,216,810,810,951,72,278,671,37,404,544,528,325,139,198,365,189,496,536,756,565,407,125,577,244,135,555,827,401,788,599,806,641,614,165,621,843,272,724,525,420,391,524,284,498,311,823,508,234,173,764,99,63,841,335,771,48,192,610,925,623,880,392,500,598,423,530,386,61,452,216,306,420,368,732,56,22,559,675,314,395,950,880,340,123,409,812,671,39,889,761,280,509,570,3,816,188,406,957,294,93,19,569,2,722,869,919,120,888,698,613,530,154,692,799,952,78,193,797,726,829,101,108,263,46,37,346,768,45,286,951,654,531,604,722,895,666,608,327,318,687,882,627,266,722,77,389,296,950,582,444,879,841,376,769,127,511,409,298,610,980,734,88,685,722,439,106,301,278,735,368,21,475,17,798,437,860,947,780,144,704,350,456,956,979,672,967,645,541,954,246,34,48,48,708,772,925,453,146,218,709,462,542,901,138,465,178,488,854,356,945,965,154,803,160,710,898,746,935,692,478,472,206,337,577,339,999,94,926,372,34,866,914,821,333,938,305,696,118,45,897,518,655,798,290,901,795,600,377,10,157,634,45,608,24,531,504,119,342,68,997,173,494,303,381,195,769,89,546,962,816,623,49,585,357,619,442,102,153,162,924,269,991,775,210,730,782,491,847,534,889,628,74,294,782,711,509,476,6,190,503,43,709,996,179,676,753,897,77,360,783,656,739,785,718,782,926,278,383,53,534,791,344,102,749,111,707,873,56,144,922,458,955,439,96,520,155,263,12,129,306,934,593,447,955,934,996,354,130,262,761,748,264,256,957,226,82,152,66,974,273,879,180,674,939,932,729,809,964,659,238,576,92,407,609,202,218,212,503,546,887,85,344,551,958,301,366,525,26,66,209,626,129,91,34,13,487,356,698,448,376,227,236,437,149,779,423,811,627,651,64,437,755,560,677,253,990,87,373,268,266,422,93,332,103,442,565,110,632,857,504,961,183,458,576,535,927,900,296,50,107,267,802,385,640,214,688,52,717,626,315,966,669,527,264,955,291,267,279,302,365,645,864,641,532,410,38,415,650,422,793,300,768,78,679,281,713,303,42,707,566,160,332,505,916,48,249,870,804,223,92,968,547,36,536,985,872,606,902,448,152,343,451,507,526,547,176,337,636,828,908,832,734,827,481,851,510,315,10,432,94,563,113,888,0,651,516,620,496,544,472,620,596,190,574,123,60,656,384,932,405,174,280,12,716,802,505,988,845,745,649,538,458,230,406,438,826,327,206,147,619,783,635,582,603,650,326,43,398,586,385,853,67,417,680,389,384,222,840,133,783,404,753,438,324,328,384,193,584,171,21,969,961,39,103,56,221,280,890,212,493,646,759,558,728,358,111,542,688,412,609,543,142,773,620,548,282,525,776,201,327,61,211,294,837,30,771,409,463,714,95,955,982,33,379,37,794,447,159,100,30,91,945,60,121,497,401,304,208,766,262,684,142,495,595,819,387,894,795,888,469,742,958,721,554,767,166,978,218,646,598,724,756,699,501,592,855,596,396,716,786,656,78,726,883,938,688,150,18,598,51,531,782,45,168,25,767,396,555,949,808,72,251,862,811,718,236,420,959,700,924,423,311,329,117,116,195,273,630,793,36,517,347,798,826,900,347,937,246,630,548,180,445,281,501,530,357,937,132,9,344,805,975,376,870,239,636,702,143,34,935,724,845,677,156,800,307,170,184,277,216,42,389,944,223,152,147,211,214,435,701,198,293,432,212,377,177,731,848,157,193,193,973,114,415,771,28,744,570,595,781,99,220,498,466,97,979,534,870,687,617,474,819,818,95,316,327,713,571,694,961,437,896,183,651,625,867,135,209,674,532,827,346,331,848,432,952,552,17,666,502,233,958,558,348,645,58,635,458,11,675,791,478,259,343", "961,794,622,276,770,453,148,257,672,166,903,766,473,958,504,908,342,552,454,566,696,745,494,32,95,454,994,320,119,374,3,731,597,462,176,895,320,169,136,381,592,24,323,740,827,781,882,287,441,467,945,447,483,469,253,853,824,410,670,171,649,983,847,630,865,302,395,251,976,949,901,807,315,123,334,906,589,159,7,553,425,416,304,739,198,812,879,531,366,901,74,776,683,704,619,192,935,422,595,887,848,601,837,505,819,358,789,621,683,305,671,144,896,911,745,852,250,314,641,728,779,816,134,906,693,949,94,336,761,784,417,125,948,218,860,147,279,228,402,880,528,300,200,254,139,906,414,454,349,831,958,326,537,822,744,607,175,716,275,600,938,878,370,354,25,837,48,464,318,491,719,494,560,251,919,886,361,213,690,594,112,443,362,522,988,527,760,853,759,630,414,210,773,761,490,481,941,408,993,841,621,293,132,167,365,985,444,352,159,386,97,950,870,365,743,563,972,394,768,671,775,501,436,190,928,603,681,417,559,226,253,891,72,526,488,1,801,323,213,808,210,183,820,356,799,79,384,350,871,222,241,518,662,528,264,838,627,689,756,616,935,417,95,696,384,292,684,715,56,249,730,552,970,280,47,106,878,740,304,974,369,134,868,134,242,679,56,948,224,751,754,779,459,767,929,576,941,194,207,629,704,42,184,494,729,101,267,258,622,246,883,122,119,419,355,299,852,908,108,613,87,145,220,619,678,742,65,800,312,776,38,461,712,455,283,739,335,739,578,847,792,698,193,343,381,206,661,126,713,946,9,283,784,723,684,505,35,837,551,785,838,904,33,773,423,58,28,646,880,798,937,467,142,126,412,49,100,573,782,674,557,645,953,647,437,624,814,566,689,782,831,794,379,838,971,797,981,40,735,140,536,682,392,558,217,526,50,691,518,599,928,718,443,720,23,171,222,964,840,620,464,650,113,220,939,289,618,616,262,763,173,638,259,188,862,707,669,726,738,119,297,349,900,321,692,529,590,8,786,847,635,555,493,410,932,126,39,961,534,668,804,639,273,677,175,329,352,181,716,671,913,156,347,62,518,267,341,692,363,567,578,249,366,296,673,299,221,228,52,161,816,31,781,569,424,410,498,479,10,756,14,454,493,745,341,100,472,445,362,976,919,12,497,739,288,610,7,763,364,404,942,209,998,722,877,576,954,877,84,100,426,983,75,883,627,972,116,393,461,132,701,597,567,770,954,565,917,758,392,994,378,629,520,736,941,184,588,112,27,166,838,859,701,989,302,904,733,281,98,29,931,802,59,120,132,461,759,806,439,871,957,810,779,893,972,361,759,185,123,92,759,804,623,352,870,509,261,711,132,340,503,216,584,495,44,368,273,947,714,925,56,164,857,394,593,791,456,476,22,372,548,827,518,475,278,851,123,929,468,228,642,17,420,11,882,119,678,488,448,51,24,29,831,793,220,436,954,735,823,261,918,371,119,676,726,288,974,18,45,401,833,530,236,565,243,249,104,815,569,383,513,686,372,780,605,469,979,573,754,651,0,741,166,399,176,827,875,268,714,261,484,983,984,165,243,574,246,900,831,957,815,271,538,953,664,937,608,230,679,914,341,440,161,244,800,859,864,462,969,307,957,124,243,10,854,317,678,341,12,517,990,567,251,739,255,79,959,880,393,439,109,9,812,464,580,805,528,893,458,594,160,559,444,578,718,44,457,515,364,917,273,197,410,751,808,643,585,178,905,90,995,11,449,593,101,476,834,338,440,617,140,972,422,309,241,356,114,815,600,766,929,367,710,299,690,825,150,510,918,605,350,825,530,590,646,711,122,123,640,729,786,489,664,718,242,807,997,96,527,642,657,225,771,364,293,205,798,902,881,365,333,170,918,844,771,484,529,728,546,914,26,622,163,139,597,43,654,38,769,206,268,609,946,775,513,220,658,99,132,380,27,458,934,304,503,616,570,910,660,733,945,698,271,339,154,469,31,161,154,690,687,103,904,797,947,236,283,571,110,594,968,99,56,925,493,244,944,320,638,838,691,870,153,65,299,306,66,576,366,466,941,642,629,378,712,507,177,984,94,463,273,394,117,152,891,911,162,899,890,863,123,916,735,381,618,546,94,680,990,306,107,102,882,744,366,995,476,235,155,508,769,123,720,786,848,250,679,785,655,899,890,942,673,798,951,132,810,396,386,768,479,314,536,147,940,362,922,869,767,162,301,774,286,69,52,259,341,683,3,665,428,80,886,454,517,364,825,224,417,964", "222,179,190,678,832,676,343,545,173,873,467,320,497,627,888,292,438,778,332,988,710,309,530,980,820,294,485,229,444,364,721,206,654,354,73,7,219,385,509,373,404,157,677,662,613,771,319,490,703,1000,476,129,491,94,403,173,258,447,726,672,878,977,873,462,683,486,740,396,89,934,165,409,891,128,951,439,795,31,443,557,279,36,803,792,510,264,325,696,343,115,963,12,677,757,785,413,872,607,824,415,893,154,297,712,377,837,759,666,612,328,647,246,943,694,426,345,97,374,295,773,641,685,955,919,383,445,898,229,750,38,48,752,346,642,27,958,832,346,631,992,124,491,977,374,918,310,693,578,644,47,732,211,128,636,570,848,262,599,646,878,485,657,878,6,248,19,839,795,347,470,823,233,862,142,692,842,513,587,417,758,729,933,424,842,966,974,551,5,427,332,822,476,752,15,224,66,345,212,429,294,911,528,531,742,436,857,77,585,903,225,147,517,430,697,99,679,810,426,853,99,762,148,564,217,166,557,444,828,860,115,641,535,460,745,901,155,751,876,437,178,926,883,909,530,34,666,121,827,666,137,735,964,195,646,885,883,562,228,216,874,310,903,91,812,955,411,443,68,479,974,953,224,829,634,325,392,165,407,71,771,355,398,21,535,692,621,410,781,555,744,332,920,552,681,717,425,860,27,601,537,746,837,343,884,623,626,589,484,126,803,947,142,704,474,306,319,420,395,388,767,785,526,76,138,974,276,412,315,551,54,622,69,217,390,716,699,699,324,757,611,704,46,596,486,912,63,812,153,112,199,49,463,280,232,858,180,637,425,583,199,591,76,991,8,17,327,141,23,870,965,295,206,486,94,239,444,520,744,512,180,496,147,704,52,244,74,855,717,636,607,853,403,742,184,452,931,798,592,502,258,186,187,132,579,531,687,278,929,358,693,985,462,211,632,101,651,478,460,508,409,937,104,359,340,456,24,732,41,629,686,511,46,479,298,285,611,736,834,536,724,493,5,607,195,363,767,295,56,803,939,985,62,275,66,138,931,792,943,826,396,441,454,817,520,980,512,867,683,867,412,611,706,72,666,345,885,88,62,362,100,767,793,379,126,60,245,566,132,373,597,985,195,314,595,393,195,793,487,121,208,747,92,284,51,963,189,48,292,943,602,756,106,118,904,13,617,346,337,238,589,715,958,113,808,692,190,423,134,382,251,820,748,430,566,642,188,373,182,107,345,343,475,75,965,68,721,743,558,586,654,821,29,937,874,942,639,577,444,519,303,855,654,3,494,940,521,353,622,564,285,469,851,810,933,81,881,295,62,64,536,994,96,558,701,736,882,131,60,783,444,564,748,41,678,762,789,310,750,797,916,872,414,480,690,37,614,698,949,175,574,632,929,573,324,299,177,366,275,100,446,607,399,13,626,623,999,401,459,839,893,958,901,120,758,117,809,296,654,459,75,493,873,648,662,862,670,308,517,716,580,820,756,614,664,858,4,836,630,221,813,959,537,191,266,983,9,875,74,849,837,582,125,219,664,823,721,592,413,461,516,741,0,660,127,33,35,173,815,839,711,513,806,628,933,427,293,984,208,195,118,90,625,636,933,604,104,231,493,442,791,211,484,740,668,133,399,997,242,164,949,276,520,827,290,514,175,62,154,190,36,647,622,453,729,407,120,863,744,476,410,591,927,935,498,605,808,754,97,499,266,956,873,798,309,515,354,442,97,833,409,197,956,340,960,716,890,12,341,137,251,480,293,81,899,700,874,898,763,222,823,742,862,281,354,541,459,239,449,270,652,376,171,507,778,126,496,426,88,306,180,473,819,554,239,537,78,808,139,159,69,133,992,839,639,466,935,437,217,450,515,258,671,612,100,518,202,858,450,456,382,982,367,921,551,149,243,633,427,230,733,132,10,797,549,383,29,450,89,429,850,272,82,545,542,749,936,348,778,721,173,285,595,889,314,239,172,676,948,733,243,715,626,785,462,264,88,142,734,653,401,558,365,484,81,537,960,534,114,221,262,837,631,689,593,461,350,279,765,25,182,679,593,845,868,485,524,90,75,805,644,204,5,152,658,982,652,712,883,756,578,969,400,942,874,378,917,7,473,701,200,560,287,276,122,506,911,198,689,712,593,351,966,435,946,782,993,992,449,548,718,255,923,931,700,283,455,782,191,534,531,148,632,163,291,137,978,718,738,282,629,963,986,445,850,57,602,839,946,825,436,728,784,847,649,55,547,854,855,195,998,661,1,153,875,181,682,772,138,516,929", "953,487,271,673,239,262,992,813,629,566,175,330,432,293,435,860,351,487,660,460,250,975,348,667,90,12,859,335,710,527,279,148,128,741,13,57,765,398,700,702,582,969,96,706,825,148,639,991,669,352,977,734,795,566,46,555,317,598,826,374,191,696,564,944,939,396,788,742,949,365,40,529,363,207,48,32,608,552,184,237,530,239,472,925,294,708,724,261,554,128,622,85,159,565,985,55,160,931,499,303,112,667,539,737,477,232,853,363,530,276,421,482,830,362,662,599,553,199,354,10,718,318,854,584,181,960,237,337,802,696,455,415,639,588,42,72,856,412,662,350,883,929,767,610,594,994,294,436,367,802,248,331,836,727,553,638,844,370,783,60,624,253,507,391,683,33,138,381,830,902,110,622,263,98,409,496,737,928,732,625,596,56,341,261,140,767,431,377,993,979,735,109,784,570,823,892,279,451,520,805,604,749,349,494,787,197,858,530,988,216,902,958,907,598,120,573,294,744,701,640,47,515,870,174,732,167,710,292,63,665,978,179,228,184,266,209,99,640,679,167,903,304,545,200,586,377,394,481,907,692,966,107,210,375,594,277,501,959,447,747,708,677,390,94,556,299,560,713,374,638,605,778,423,549,940,95,218,33,932,565,975,221,797,915,574,749,50,1000,426,442,901,466,14,844,214,772,13,122,307,621,12,867,75,343,85,715,95,485,841,134,870,953,80,582,353,645,366,803,317,582,883,300,877,39,86,739,241,454,840,867,907,954,770,102,739,415,923,7,993,516,663,326,418,248,493,242,465,991,748,337,310,133,512,440,791,257,929,611,16,186,584,744,126,149,254,681,655,752,699,999,656,98,25,235,847,242,522,745,914,514,973,16,333,330,280,471,519,322,856,364,222,21,616,482,539,740,658,740,89,959,144,516,519,37,530,66,371,116,728,524,783,781,34,729,915,994,831,312,318,781,387,517,418,772,659,791,677,529,372,21,913,985,614,980,968,586,979,217,256,184,780,31,559,680,684,261,664,425,293,952,150,692,223,905,246,346,848,250,186,343,469,721,486,88,245,106,265,412,561,551,87,278,171,672,778,385,431,510,489,268,512,895,106,581,671,824,526,914,574,735,776,208,381,163,10,463,194,736,937,514,333,309,282,348,30,2,152,27,526,686,781,932,336,483,85,471,134,544,209,693,768,837,572,959,341,878,871,584,298,271,236,366,286,29,56,462,232,260,983,63,728,847,129,738,822,748,668,856,326,142,839,36,75,709,411,630,132,26,227,501,534,497,198,907,149,442,411,860,175,501,462,24,452,937,575,33,697,644,941,190,24,230,723,213,361,358,504,538,479,952,126,445,13,655,356,756,341,248,225,119,826,713,88,309,77,945,39,417,820,859,744,498,340,547,73,984,725,547,98,475,236,810,963,766,630,889,60,792,628,4,91,493,1,42,20,838,191,281,788,491,170,166,599,792,529,658,400,745,447,219,789,82,345,841,702,807,939,838,546,765,287,470,944,90,760,612,617,26,138,98,583,38,575,353,25,644,620,295,74,620,166,660,0,354,394,679,163,130,341,415,736,942,465,768,388,711,892,413,127,158,797,185,89,736,588,803,190,898,94,96,683,618,470,264,612,649,244,821,441,708,208,588,891,758,723,927,949,20,23,597,704,339,298,338,161,378,217,660,956,517,210,709,251,882,874,551,823,254,859,262,203,689,374,909,257,590,219,418,695,120,38,169,349,814,81,939,71,676,314,584,355,743,951,51,281,464,738,562,58,169,29,552,318,173,657,338,602,156,117,758,44,544,602,543,974,908,317,865,544,806,342,342,505,477,387,596,811,496,84,819,758,4,258,912,70,383,889,305,159,240,739,699,331,756,35,596,594,493,483,437,668,528,36,864,59,146,38,21,949,359,945,313,138,821,552,415,458,232,172,991,157,800,706,859,113,292,929,658,637,337,482,832,656,243,150,949,397,693,273,711,94,94,636,253,862,915,616,49,981,931,341,625,49,212,925,636,963,875,984,332,284,734,404,515,626,943,251,478,853,477,263,488,181,502,143,977,654,181,190,240,18,865,737,974,614,689,451,547,835,581,115,986,140,386,26,225,247,820,324,645,277,729,1000,890,605,319,146,227,534,841,927,528,752,979,752,459,683,296,650,589,374,577,160,102,879,833,317,920,819,432,801,721,873,488,188,275,714,227,18,223,86,443,664,527,475,260,435,747,86,877,70,26,940,913,110,988,851,423,525,755,250,989,750,502,272,591,101,155,523,803", "604,555,412,94,828,313,903,949,359,122,883,449,853,17,612,577,217,22,947,84,303,6,120,485,68,393,654,234,610,80,397,448,820,621,74,957,28,120,375,551,471,20,516,736,564,295,635,100,318,309,741,411,912,821,390,399,71,387,716,711,707,643,75,118,793,453,3,137,55,316,969,934,971,994,962,389,916,697,416,962,502,173,63,263,601,406,271,647,868,829,302,69,456,771,402,64,956,18,282,650,190,757,208,154,985,851,932,875,536,984,802,879,631,561,87,234,530,719,997,262,636,642,70,963,735,34,353,181,239,303,407,349,223,6,249,174,21,803,612,897,672,150,554,250,448,503,146,675,14,394,120,300,327,44,799,840,76,342,654,383,719,905,231,783,308,478,506,48,203,729,106,578,304,234,983,920,737,223,749,714,303,757,853,957,759,73,941,272,521,505,419,195,720,153,787,886,536,472,571,298,565,451,87,788,189,954,852,305,803,19,353,834,394,70,142,451,863,943,2,358,819,367,690,231,555,701,20,48,884,250,938,636,946,389,449,439,323,70,428,583,543,235,399,606,248,337,67,681,713,319,867,589,458,568,334,589,473,247,492,686,571,826,495,605,155,467,643,478,810,723,17,18,606,962,693,201,635,902,811,358,440,901,954,531,964,850,454,443,429,762,483,4,384,751,997,266,631,312,461,677,181,160,293,384,811,965,214,278,714,749,724,483,552,749,670,354,545,885,180,591,478,789,639,466,333,40,986,971,817,891,391,4,600,311,427,983,195,660,242,194,226,262,42,182,347,103,284,288,55,78,860,542,915,622,23,454,860,275,781,691,37,638,160,379,35,134,241,325,233,5,440,766,517,272,865,5,103,525,896,182,113,484,347,824,595,559,666,624,389,321,758,196,161,785,54,69,537,322,905,950,696,352,82,138,474,104,708,495,238,75,606,781,631,260,267,448,391,36,39,97,878,449,765,898,539,718,674,508,322,540,807,257,289,714,894,960,682,290,241,144,560,374,752,818,280,354,940,669,679,444,771,85,40,12,781,638,739,566,39,611,129,424,805,554,572,840,385,415,66,711,372,257,264,57,953,446,605,635,487,734,421,552,760,904,34,526,973,231,172,444,589,418,916,483,394,351,45,661,658,586,886,758,648,724,994,974,973,347,603,593,652,650,697,401,18,693,613,762,150,816,863,142,853,230,740,41,103,224,365,275,841,696,655,560,491,907,613,495,570,394,452,673,720,494,224,126,458,676,663,116,616,368,807,352,308,646,61,696,261,355,837,776,715,898,376,102,783,823,11,292,585,871,249,427,597,859,916,792,503,939,645,386,422,723,103,470,190,28,130,172,274,399,656,240,537,293,393,144,53,371,249,796,883,771,528,538,508,183,703,322,124,917,558,487,925,881,757,205,67,139,223,268,624,249,420,754,997,169,513,328,813,112,736,379,250,650,340,827,160,268,467,165,75,919,268,654,178,554,663,451,602,930,458,482,718,354,637,128,392,489,784,920,913,812,974,972,819,506,32,455,329,226,898,660,749,896,68,163,812,496,399,127,354,0,871,732,190,651,707,374,543,991,165,613,875,352,20,365,295,416,241,468,689,48,244,642,847,991,243,512,128,863,611,417,163,237,348,186,910,594,531,164,372,120,739,997,644,180,166,866,840,362,614,30,429,697,200,494,918,782,29,218,458,478,846,688,558,133,713,343,161,134,873,806,585,357,782,130,108,489,788,223,305,690,316,803,58,821,435,993,693,22,978,761,49,484,419,299,961,242,85,497,568,57,425,341,91,7,457,599,810,136,730,268,233,986,994,808,988,950,658,879,239,981,739,12,268,617,657,154,238,908,488,719,507,435,731,109,324,243,128,34,912,785,882,417,16,506,510,273,736,865,247,457,592,500,788,589,571,394,882,164,573,18,900,820,626,332,400,796,792,647,864,176,169,483,411,259,617,345,19,309,411,667,592,268,594,607,721,739,280,73,184,705,512,241,814,344,578,107,28,756,490,247,320,379,732,210,462,6,394,655,103,482,992,591,513,822,44,242,585,27,997,654,605,661,287,155,38,451,151,880,198,351,748,107,852,988,806,69,240,918,862,401,178,426,250,685,82,237,605,232,947,764,113,318,513,655,244,372,149,559,191,315,867,25,724,785,562,528,141,572,526,532,384,539,719,877,948,356,45,441,843,839,565,849,923,67,698,832,584,760,585,355,220,720,134,197,951,798,722,880,652,330,46,289,746,942,889,857,680,282,903,229,636,5,254,469,507,292", "611,710,275,764,764,924,916,616,506,490,697,197,146,672,155,532,942,288,296,859,396,275,322,377,112,562,312,1,28,503,262,849,185,481,31,203,502,595,441,60,201,993,856,312,193,613,568,229,917,698,629,178,244,919,230,105,458,257,320,640,352,155,414,211,155,649,986,397,276,601,166,251,697,150,781,691,113,553,783,867,210,156,84,312,64,998,905,364,925,908,716,222,94,859,41,565,94,93,131,366,57,499,363,552,426,818,871,721,557,648,389,846,246,365,333,577,81,520,518,625,936,237,220,247,232,168,541,259,772,940,221,583,482,497,657,420,555,67,40,232,984,762,47,136,24,409,711,88,50,396,196,565,727,609,2,579,661,855,889,475,139,767,537,796,876,225,629,13,505,235,437,725,15,128,5,400,76,105,307,352,836,825,209,488,932,21,302,926,387,651,775,185,57,514,491,841,986,131,165,601,968,442,83,94,947,935,762,368,536,178,312,957,531,542,667,313,989,549,712,686,529,521,454,727,831,313,14,218,902,780,410,434,464,659,611,638,38,101,371,834,653,241,131,600,349,697,336,769,90,184,709,555,480,369,726,39,618,285,993,627,15,681,382,445,657,822,864,606,870,101,623,413,927,948,203,53,955,400,713,410,930,549,761,649,451,956,219,993,16,887,78,497,931,507,793,974,95,853,171,749,416,701,236,431,374,48,144,642,156,250,418,735,24,739,483,235,990,407,46,65,560,791,289,102,487,560,950,589,321,63,375,357,913,768,124,760,166,794,632,654,936,678,618,12,650,693,545,19,680,12,895,878,137,524,942,963,533,972,681,598,407,415,815,100,691,24,910,718,351,771,703,583,398,511,212,297,597,916,636,917,889,527,532,509,787,450,365,956,560,28,30,683,677,5,412,842,867,432,723,978,550,228,229,588,823,957,69,155,641,245,904,876,723,345,140,855,456,970,96,5,338,223,708,43,473,279,290,377,26,652,182,795,156,529,556,649,116,501,688,492,161,12,871,805,948,414,559,990,573,604,549,826,216,947,677,613,816,123,194,579,668,832,659,226,176,326,638,2,523,670,421,231,722,399,860,70,958,774,967,928,813,282,491,268,142,917,45,946,849,739,881,330,280,207,125,141,685,941,427,544,650,805,751,22,606,297,681,718,474,864,384,539,668,624,611,496,574,406,425,153,996,962,96,86,118,796,297,330,104,880,820,729,629,8,223,343,84,414,526,427,732,757,843,719,229,874,674,56,832,612,126,239,63,552,257,442,39,990,443,591,521,599,379,262,628,631,467,563,874,46,685,598,298,630,58,318,708,101,856,154,28,583,257,889,298,868,576,327,142,913,397,453,347,367,743,901,963,394,51,708,703,996,814,255,539,143,571,85,675,955,9,711,846,596,615,927,772,86,48,619,405,434,455,508,999,375,429,315,102,265,47,160,824,869,790,419,926,581,415,157,518,239,393,228,185,483,747,885,422,146,556,689,582,810,220,55,612,57,900,523,285,968,69,628,504,332,127,91,266,406,822,614,360,314,716,841,79,494,60,544,176,33,394,871,0,234,445,156,134,486,742,833,331,978,503,557,369,2,621,220,377,528,154,269,53,72,749,68,532,478,438,412,667,881,931,577,730,787,678,619,868,16,805,247,244,888,326,369,200,208,436,148,878,639,987,47,965,343,225,110,978,169,954,810,667,413,209,409,427,906,736,549,70,776,839,97,394,836,521,784,577,991,367,888,464,796,723,705,8,608,529,760,974,859,521,522,262,99,93,110,4,812,104,199,962,985,706,464,839,265,982,478,855,362,135,841,862,28,497,917,113,678,709,46,736,907,756,270,510,830,615,439,2,742,824,647,767,751,254,498,832,471,712,460,757,485,646,551,210,222,968,897,642,682,989,15,329,464,777,295,355,285,954,743,986,192,670,636,299,898,553,869,827,940,215,245,778,714,426,158,756,703,699,395,832,194,587,92,713,928,668,237,59,764,293,418,716,255,208,721,285,5,64,43,824,211,256,276,560,437,739,307,675,7,978,135,564,116,135,309,447,816,285,470,421,262,737,206,738,79,819,730,572,304,286,213,454,156,240,46,919,67,809,758,876,198,664,956,686,633,820,72,670,734,506,86,677,715,24,884,828,657,754,468,755,15,268,17,330,997,25,188,593,16,533,676,101,418,979,716,618,951,197,447,535,911,471,268,951,384,566,898,239,976,776,593,404,756,765,452,556,172,110,747,136,187,244,418,879,535,677,263,613,956,271,736,274,547,691,506", "111,215,427,731,273,444,982,465,410,64,274,832,909,771,147,685,273,773,17,345,40,706,961,884,246,117,414,850,366,938,438,507,737,902,911,321,260,408,622,167,786,29,46,728,60,967,911,83,762,359,2,7,520,875,979,989,914,322,419,776,214,992,289,337,743,444,597,909,197,709,258,645,817,161,140,152,321,454,199,868,231,178,5,938,582,418,512,579,324,207,295,525,657,578,278,795,865,112,288,807,597,697,714,16,796,683,950,548,35,160,220,555,700,357,464,931,410,901,55,687,424,294,329,507,942,822,985,329,913,513,419,689,387,781,968,635,513,53,362,213,672,100,464,248,863,232,384,474,885,666,930,370,677,727,171,360,379,199,177,511,246,174,514,354,54,763,760,808,163,788,569,781,861,443,794,417,792,452,708,565,741,735,200,802,539,696,409,680,204,520,130,96,369,388,370,217,775,77,934,564,489,141,976,835,962,207,845,570,508,594,417,945,604,712,111,430,111,709,599,299,341,445,63,662,518,64,369,933,153,571,623,155,203,554,92,584,473,4,87,732,493,638,622,134,143,10,137,317,37,316,286,794,188,408,226,937,132,555,374,903,682,951,914,959,581,403,850,173,766,69,7,191,784,175,772,756,523,932,216,877,514,216,958,352,308,101,931,281,900,899,661,961,714,845,340,895,386,868,865,451,687,841,276,200,944,522,784,41,498,914,145,353,537,423,341,628,597,372,863,837,754,167,60,280,188,360,388,916,510,710,252,175,236,130,792,948,348,382,431,895,99,59,434,317,742,487,953,789,100,943,510,993,546,55,413,67,377,977,435,864,806,577,741,232,191,244,652,596,858,187,421,549,249,99,858,293,426,457,172,34,381,259,899,928,550,684,568,855,757,372,310,871,1,679,353,99,474,118,717,297,599,942,208,207,42,108,42,762,210,387,154,858,765,677,455,685,912,795,86,78,113,732,968,956,355,69,902,956,31,594,740,277,922,192,26,428,388,520,196,977,867,853,82,81,972,310,486,341,115,824,192,194,857,362,367,713,555,973,149,885,311,735,345,244,504,949,877,368,26,62,244,662,630,803,425,268,487,54,111,567,433,894,363,881,970,888,659,257,218,824,272,666,588,792,62,990,291,419,260,340,748,638,968,576,638,488,692,909,506,95,958,509,682,392,233,109,941,420,625,418,753,279,355,562,490,412,312,521,98,890,387,220,369,567,469,852,529,180,872,221,423,878,755,245,225,122,321,64,836,575,419,647,464,263,777,942,590,106,757,669,80,244,55,508,412,274,506,24,788,57,623,903,559,605,554,859,236,913,494,45,488,452,218,219,210,170,478,577,748,604,244,256,755,402,771,67,401,172,976,70,342,117,243,316,802,331,881,3,318,957,390,486,125,698,738,721,491,968,194,653,609,858,9,866,300,737,789,720,140,388,104,672,695,792,664,236,68,177,87,422,426,963,914,821,370,281,247,510,195,135,824,716,82,203,746,312,822,768,505,412,211,295,571,894,736,926,956,395,928,880,29,705,512,507,782,923,309,656,643,472,827,35,679,732,234,0,722,648,156,771,224,300,317,801,960,117,791,921,383,833,283,221,641,979,796,469,396,475,595,808,202,546,702,99,157,735,597,244,484,554,361,478,1,519,386,834,191,561,269,442,230,166,248,971,788,469,388,234,505,222,509,150,856,719,457,583,130,147,504,298,810,473,757,42,760,819,437,180,974,540,830,776,149,283,42,106,491,821,203,383,249,809,593,482,625,65,729,198,861,59,855,365,416,377,47,125,351,480,855,676,800,873,158,995,461,338,172,918,849,855,775,809,761,371,813,947,554,260,720,387,78,431,39,358,428,16,114,511,792,121,73,525,172,572,46,310,366,967,157,665,490,378,851,936,864,443,14,859,123,133,361,871,262,80,629,857,364,924,273,741,281,363,63,967,583,72,374,749,531,930,401,220,850,113,856,325,877,602,591,790,281,989,82,36,653,206,858,139,87,440,784,240,373,359,885,952,281,514,680,306,547,916,252,713,217,316,218,6,818,105,571,221,192,4,674,347,902,260,298,975,105,130,20,193,785,50,299,668,627,506,544,129,888,511,398,753,84,987,871,482,93,130,996,240,627,238,946,91,556,288,794,398,875,665,791,361,470,525,592,916,624,898,522,788,606,311,695,501,396,108,292,945,216,521,69,843,710,250,743,198,702,652,29,365,596,978,595,437,382,437,528,429,630,746,842,359,980,677,596,755,793,785,751,652,322,335,876,948,728,117", "296,94,398,778,149,115,428,710,86,682,306,226,192,159,401,844,315,870,926,117,10,165,269,40,731,90,386,518,156,970,181,26,273,942,893,944,446,619,508,20,918,690,416,967,601,801,520,814,502,766,366,554,949,588,881,450,327,653,136,875,43,721,759,587,673,324,565,545,79,920,837,749,52,783,265,347,992,943,94,136,620,307,181,367,893,968,885,662,480,688,530,762,486,286,132,985,827,939,932,368,718,70,115,190,643,65,533,70,621,110,309,899,863,639,139,685,619,549,218,260,103,434,45,309,23,231,691,65,279,589,74,774,161,261,846,556,707,927,281,64,71,73,508,710,365,78,951,354,87,71,409,383,912,246,714,470,187,733,85,206,14,529,395,840,104,508,419,583,182,491,982,594,815,766,880,842,23,412,523,648,562,192,205,721,843,221,741,176,9,965,953,859,108,721,40,32,7,262,636,333,799,840,410,205,71,913,807,883,734,612,703,162,62,672,622,976,593,830,290,462,644,697,109,29,364,753,466,126,288,840,325,481,292,700,525,646,320,94,587,860,245,252,610,212,996,503,506,297,581,34,959,759,393,47,933,161,164,246,226,269,855,964,81,220,128,569,804,35,247,585,247,649,497,216,489,733,721,675,292,193,340,873,881,643,587,387,880,508,785,606,928,12,480,789,102,481,260,786,690,606,112,329,17,259,789,342,302,172,266,612,215,658,809,382,252,916,643,323,979,472,200,686,894,231,508,258,663,736,469,3,794,527,261,560,457,262,139,229,167,471,568,998,610,102,471,225,662,301,333,129,103,974,325,857,127,18,429,949,15,901,298,933,604,890,743,71,591,74,263,966,974,800,151,603,496,257,133,349,677,79,624,754,615,886,507,185,964,588,855,511,715,575,587,734,487,746,982,833,680,808,682,897,996,840,165,266,195,293,850,46,599,35,790,529,850,671,994,635,242,991,511,561,924,130,148,918,248,118,81,392,473,661,44,753,172,858,781,310,349,461,186,882,977,364,601,807,784,444,511,125,652,115,553,605,289,431,584,512,85,395,379,221,830,27,678,731,204,438,406,470,429,86,170,72,868,434,155,631,723,850,542,983,280,960,931,202,683,860,69,739,396,688,592,848,465,444,813,614,466,824,729,526,547,88,291,30,20,218,869,141,828,512,330,442,479,382,573,201,633,889,249,855,824,414,23,928,177,294,15,57,486,302,161,785,373,206,196,816,360,916,948,293,486,992,659,24,181,282,244,152,737,722,824,454,817,30,459,730,11,886,899,593,553,411,895,692,73,846,275,846,152,145,270,207,780,175,421,19,407,306,129,887,378,503,654,581,236,621,566,332,609,920,632,620,103,890,781,277,593,956,100,510,636,440,776,996,2,543,528,565,590,81,78,432,165,516,539,328,636,659,8,790,529,778,729,210,165,764,684,975,993,289,565,781,337,417,966,647,74,308,720,871,766,264,664,984,366,14,976,451,407,732,499,281,400,295,722,712,424,901,322,6,609,202,343,848,513,42,244,682,988,969,824,29,640,647,469,488,102,620,875,173,163,190,445,722,0,571,197,419,755,493,192,774,964,846,138,140,173,247,164,609,223,906,544,688,582,612,803,517,251,884,78,112,627,709,441,724,352,165,449,9,640,585,226,58,203,564,932,470,754,76,224,945,343,564,430,262,146,876,296,581,596,674,352,638,133,491,179,157,225,460,755,668,565,276,312,130,575,416,140,308,500,867,929,143,634,853,77,641,590,328,797,172,292,552,855,430,494,445,751,278,449,825,420,649,153,974,552,602,169,326,876,44,802,588,35,953,566,159,587,910,23,133,164,993,202,656,752,155,4,29,151,850,841,869,875,236,636,434,320,170,79,438,546,794,515,11,959,902,236,710,932,453,273,557,750,977,570,55,732,922,643,598,312,838,753,914,442,650,933,224,954,51,835,820,381,162,956,840,898,736,606,496,216,776,989,177,424,282,491,270,986,670,656,708,951,917,664,611,983,467,250,582,403,339,428,927,460,869,378,401,592,100,756,857,957,560,958,533,219,640,19,297,252,111,492,866,638,747,429,704,928,21,294,811,931,238,114,796,545,144,780,181,635,407,505,881,992,119,637,136,55,330,550,523,87,37,89,758,633,38,861,132,276,589,484,335,14,276,233,118,976,236,24,785,778,229,988,977,319,60,586,219,811,545,482,719,503,367,855,576,527,41,748,439,696,6,863,345,725,892,856,593,619,489,162,51,50,787,961,231,271,711,700,986,876,261,482,254", "784,707,206,196,191,895,271,828,648,794,415,377,965,788,993,409,128,339,182,890,933,461,437,896,598,258,226,286,391,149,218,656,726,941,521,720,518,471,146,279,951,553,335,567,644,39,260,844,887,260,623,774,247,825,260,231,24,433,436,832,883,994,930,333,970,613,422,760,717,650,597,97,690,405,681,737,919,243,632,584,215,405,98,98,7,859,812,619,352,518,270,74,449,138,8,808,183,66,862,19,97,208,974,834,457,510,622,997,609,208,403,966,612,981,516,56,822,141,583,187,925,384,481,365,491,42,803,59,605,791,547,952,720,641,437,468,925,213,697,762,362,337,570,709,666,738,335,291,285,267,983,205,714,177,581,554,893,569,345,98,513,177,795,823,87,233,246,998,585,478,916,754,876,448,847,334,245,937,108,497,220,872,132,827,124,616,648,772,640,572,667,613,315,92,683,940,756,447,899,692,347,50,457,981,520,32,773,41,12,179,21,823,832,127,915,214,383,315,121,661,236,480,623,352,18,569,273,355,713,689,785,93,475,379,667,768,63,70,951,922,929,497,436,894,637,87,492,609,222,177,724,682,888,887,46,492,531,665,22,164,214,278,360,216,317,526,763,325,397,576,623,461,501,91,3,382,266,504,349,459,491,841,307,941,491,713,143,641,249,141,348,205,879,174,593,433,3,836,521,629,225,396,340,683,139,219,909,324,931,723,732,635,736,971,814,346,517,721,353,486,656,635,248,890,567,242,460,874,117,659,322,690,270,21,280,343,517,640,395,539,38,424,144,996,927,836,617,594,448,974,11,595,330,103,635,11,633,715,951,960,542,59,742,780,614,484,881,741,87,616,655,467,264,417,774,98,987,254,403,783,292,356,137,932,83,138,400,5,481,76,999,603,732,254,246,411,492,264,29,485,104,839,130,294,733,853,680,353,678,489,542,583,212,568,419,450,227,665,666,860,945,429,137,206,304,771,541,657,648,41,270,383,236,595,940,356,920,583,847,598,281,276,431,550,342,866,845,513,880,473,636,805,645,219,22,749,901,215,667,302,439,794,700,301,812,243,353,899,918,219,564,641,972,628,738,802,838,661,797,279,480,441,309,837,598,528,241,41,317,474,853,327,55,67,644,715,565,354,546,84,201,510,764,294,522,757,460,568,999,848,96,352,34,926,629,886,263,507,28,230,386,140,709,465,852,360,394,472,285,163,760,462,352,752,756,862,716,678,101,256,118,262,850,709,833,855,953,652,320,698,297,627,131,981,628,179,297,963,725,388,266,879,413,327,619,640,487,902,500,167,47,365,110,116,30,862,939,174,825,379,880,998,726,679,720,144,419,213,860,986,607,461,219,499,318,408,650,331,791,568,427,975,164,398,370,20,601,853,366,575,537,433,898,496,593,608,699,285,800,362,590,500,481,699,932,267,329,562,872,692,777,465,609,279,678,586,927,942,827,61,938,47,957,312,327,665,300,942,59,698,571,264,227,658,603,326,745,672,96,78,681,419,606,271,118,986,282,340,970,357,726,378,103,971,85,553,22,626,584,596,268,815,130,651,156,648,571,0,75,889,357,845,729,982,678,301,522,383,276,657,164,535,509,477,235,649,366,824,872,808,590,61,871,81,441,74,715,977,663,386,750,633,184,785,239,912,729,424,836,561,606,591,951,545,840,400,506,931,917,774,543,526,325,933,889,643,747,196,560,804,56,460,10,961,315,167,557,74,951,715,751,149,907,537,540,186,552,667,696,12,295,795,7,48,812,125,62,788,19,685,673,868,79,616,722,705,500,148,644,725,51,87,328,657,920,634,553,827,215,515,884,11,810,630,76,245,504,557,314,87,224,787,908,444,165,839,405,727,120,137,120,180,823,595,197,181,262,583,573,171,243,684,214,864,720,380,740,571,303,567,786,651,125,774,915,764,739,33,55,486,940,612,849,201,501,690,566,599,304,187,925,641,763,96,738,474,991,901,826,296,166,138,876,589,425,793,24,734,483,940,516,701,386,286,379,716,123,934,615,208,804,749,411,4,789,192,789,668,913,323,424,582,279,331,758,659,495,745,889,332,269,416,316,547,105,674,188,855,143,836,639,888,808,562,818,334,832,618,821,291,511,647,229,299,46,421,300,21,192,623,399,931,473,75,298,223,795,379,458,122,224,49,745,834,880,763,469,443,310,656,813,304,303,31,760,710,779,797,418,778,101,201,982,722,639,23,845,118,876,107,371,167,407,361,896,477,403,911,307,557,122,164,554,912,705,3,228,878,979,844", "967,326,953,10,607,53,947,209,22,925,728,350,357,111,473,482,611,916,898,236,92,644,372,359,769,392,544,730,251,977,914,219,213,177,828,362,430,301,106,483,647,664,881,767,592,375,964,161,171,480,956,461,192,189,23,409,714,357,867,918,430,557,913,736,168,395,418,483,77,512,355,688,394,435,208,543,981,432,209,407,223,157,433,143,378,70,316,419,592,385,221,371,478,784,607,180,239,792,57,752,26,731,224,196,171,368,789,722,877,148,997,399,845,200,693,343,533,863,168,706,336,66,917,517,420,54,480,977,718,681,921,286,170,589,72,292,891,858,636,696,173,681,414,941,926,230,564,722,299,771,674,819,656,376,93,381,711,752,667,942,216,863,743,294,397,811,478,399,275,579,275,79,622,389,52,655,786,90,560,150,929,404,431,106,258,91,69,862,420,44,766,600,256,810,677,596,790,905,417,217,994,741,441,100,382,545,248,7,75,559,669,579,9,262,655,95,619,98,566,344,738,455,655,701,138,142,335,748,685,230,869,864,916,433,339,989,732,153,785,6,992,810,354,143,159,737,874,479,108,807,619,706,562,16,417,669,846,132,455,741,527,517,872,493,633,837,902,506,638,803,369,18,403,624,279,383,98,999,96,829,724,420,154,99,481,786,391,893,704,498,256,959,779,367,821,958,7,196,86,213,841,363,517,666,144,248,916,956,934,569,663,165,545,295,220,839,553,225,32,518,339,482,147,160,179,383,76,297,677,946,492,51,978,163,731,644,302,836,770,557,612,168,111,945,439,606,158,128,653,814,872,951,611,545,310,586,943,295,542,327,975,55,701,314,114,364,54,960,858,831,87,548,638,8,378,576,227,566,18,820,262,775,473,704,570,563,158,80,227,928,823,933,302,890,625,213,732,946,638,513,743,23,320,939,276,152,98,884,648,728,488,869,789,462,265,66,345,805,518,977,333,982,60,791,591,332,940,894,281,251,769,42,206,710,841,68,810,462,605,114,151,643,33,776,548,585,750,902,711,667,572,969,94,301,300,491,667,407,909,870,502,250,441,416,323,932,743,120,409,502,633,304,541,296,532,755,324,813,403,312,53,753,277,411,339,389,894,23,1,951,571,764,610,303,444,976,60,685,304,489,359,491,757,97,899,634,313,242,810,413,474,298,979,978,769,268,935,303,525,237,845,301,445,901,367,370,282,1,702,901,190,522,122,390,596,412,151,808,592,742,648,635,389,798,801,495,870,592,626,398,957,657,537,578,671,882,488,457,333,816,641,377,316,568,577,331,886,28,689,241,843,729,195,316,738,309,867,726,711,925,197,976,171,171,585,742,505,846,891,917,213,467,915,744,762,578,235,280,525,322,439,442,345,308,16,603,998,392,243,299,604,477,524,692,117,709,68,555,932,362,592,275,991,625,763,620,30,643,517,286,932,660,411,965,661,147,963,647,61,831,576,983,944,172,583,303,335,628,338,416,702,721,638,847,138,683,278,474,693,515,374,899,935,734,88,592,222,911,589,646,163,326,829,96,710,708,70,329,59,190,714,839,341,707,134,156,197,75,0,758,835,185,321,262,422,550,902,685,635,893,263,371,951,59,637,858,198,218,920,22,757,180,501,789,681,925,661,78,203,523,929,824,486,232,9,358,842,481,920,659,644,83,452,871,297,265,481,186,848,850,249,318,5,30,314,538,358,718,342,181,424,959,456,684,850,343,214,37,896,358,715,888,224,112,536,194,618,868,163,89,213,63,38,766,480,753,420,302,145,354,766,215,715,382,429,287,857,325,664,390,706,720,932,962,636,883,669,726,625,971,274,870,577,994,126,663,937,831,187,49,283,368,735,752,244,738,261,848,918,199,916,448,361,528,373,653,104,103,821,303,838,542,407,821,9,631,334,506,347,564,599,298,242,588,660,782,321,429,232,793,971,481,366,953,88,146,448,917,175,447,909,739,53,194,498,822,817,101,116,472,917,657,809,672,212,266,336,542,882,616,92,443,606,531,985,489,319,165,391,965,223,60,65,964,38,682,30,107,304,740,9,527,885,934,461,362,622,164,740,204,13,147,630,778,404,726,792,198,374,129,429,21,430,621,729,29,212,752,435,505,791,696,506,984,221,769,110,289,281,985,710,148,535,814,643,712,857,141,113,274,974,646,901,13,903,376,474,547,331,982,153,615,505,900,911,760,213,399,501,104,270,307,98,115,926,763,665,525,203,986,365,465,241,892,854,767,897,726,518,256,740,593,474,564,746,497,507,973,152,165", "175,469,138,87,382,405,383,539,560,557,344,273,529,342,157,860,416,56,144,166,405,560,307,528,969,96,462,803,259,453,4,115,286,36,306,974,156,862,828,245,217,989,911,855,796,36,959,237,422,545,503,650,308,462,19,69,330,40,357,418,917,291,91,913,533,663,887,196,206,876,470,863,62,773,314,981,234,889,976,35,426,133,645,23,79,744,830,516,203,732,76,462,587,590,925,939,435,450,972,903,216,749,864,842,481,623,63,220,702,189,760,705,829,144,303,540,436,309,688,537,608,742,389,712,269,163,154,728,768,916,391,799,478,728,675,864,855,590,970,543,482,135,695,176,749,747,714,933,684,949,92,925,273,740,7,201,736,702,946,183,841,265,139,773,737,106,183,862,608,161,603,531,782,383,118,587,759,54,478,453,823,199,828,289,863,243,353,855,158,121,912,416,947,675,607,545,474,532,890,827,230,72,44,252,467,642,415,690,554,803,41,713,967,326,144,643,179,110,115,718,171,751,611,466,317,898,393,642,884,215,829,274,840,706,266,534,272,780,54,53,130,772,182,582,698,683,619,250,39,806,744,462,863,371,380,978,347,346,634,450,442,221,689,112,377,836,751,952,359,165,145,344,715,320,409,365,128,686,774,99,464,834,34,789,158,176,915,56,312,638,55,909,215,931,570,326,508,32,773,268,980,127,681,857,919,140,987,428,423,394,969,4,690,176,430,312,996,383,286,559,669,858,645,325,520,457,776,840,899,629,491,182,1000,355,317,463,632,361,245,126,709,39,376,713,73,545,517,550,897,113,698,971,632,903,819,386,701,838,341,599,170,218,390,387,558,110,225,77,873,333,569,696,340,511,586,258,656,640,5,938,884,787,367,400,545,613,24,953,386,651,473,349,994,71,27,928,428,737,194,39,921,297,411,25,164,583,591,120,485,167,805,897,552,46,195,512,851,458,531,159,912,43,69,50,30,498,697,965,973,6,967,230,397,130,952,939,657,841,95,275,856,361,47,317,965,665,833,122,98,398,623,87,635,347,759,503,981,33,459,441,191,328,940,999,532,544,541,624,922,866,172,776,909,516,20,286,319,885,336,613,385,558,73,258,166,542,759,262,64,53,319,397,460,685,765,965,17,91,312,792,757,682,173,468,977,900,688,644,292,154,216,2,562,133,682,405,971,935,791,620,534,274,603,750,564,933,187,449,773,656,745,681,439,767,932,849,702,669,786,979,672,449,797,678,400,235,249,577,767,604,791,796,336,607,807,563,654,77,607,363,307,974,184,653,679,714,204,107,764,454,804,200,542,939,673,161,256,164,744,271,804,635,179,875,581,373,152,781,779,822,239,571,592,320,193,26,624,347,342,614,24,646,598,97,844,570,978,901,962,700,784,529,467,301,369,626,902,502,473,303,861,762,482,609,599,118,70,52,233,937,974,133,935,759,791,817,613,692,992,588,370,238,392,246,990,139,379,794,187,573,458,631,866,627,203,69,819,352,934,815,931,964,715,195,164,192,110,977,610,928,15,158,936,743,94,957,723,145,567,574,261,711,415,374,486,771,419,889,758,0,169,441,509,587,754,968,520,792,902,888,674,32,820,147,43,104,836,524,844,401,724,983,582,849,857,220,608,157,93,862,62,804,358,33,581,25,254,620,611,734,463,578,802,633,537,194,241,451,915,714,737,965,575,888,454,987,47,456,972,809,883,858,232,496,653,94,458,880,862,241,660,164,555,391,730,978,250,545,860,388,773,35,493,466,91,823,262,599,23,108,731,939,823,548,777,191,961,786,199,339,414,994,283,319,690,364,961,128,523,27,121,879,211,581,120,740,831,583,967,936,860,26,725,384,523,331,939,934,930,326,969,193,631,679,274,738,975,622,430,463,355,909,700,266,593,80,649,127,354,16,980,676,27,31,418,228,914,668,888,157,964,68,884,846,842,570,818,498,779,963,157,834,313,991,991,570,51,737,167,725,482,911,18,251,935,349,759,934,889,645,188,451,123,412,256,72,602,799,704,678,461,521,228,879,340,431,616,551,301,661,715,420,183,260,991,281,742,940,616,399,571,588,64,588,32,528,946,46,174,541,270,846,25,839,225,36,881,132,675,545,926,439,80,437,396,814,95,344,991,931,839,561,325,34,564,865,929,686,629,276,927,623,364,202,936,834,492,734,719,428,616,886,419,331,382,857,926,178,691,315,568,384,489,60,620,524,609,996,331,488,464,273,974,776,791,290,308,283,980,415,461,468,898,208,830,705,502,10,806,783", "448,456,198,3,895,463,605,227,793,305,806,446,630,820,655,143,45,861,445,939,865,204,334,173,979,114,644,2,18,576,275,673,138,972,648,381,721,846,502,219,91,634,814,946,830,836,729,114,888,97,685,208,124,530,989,771,154,468,557,903,316,71,136,505,106,293,569,823,494,971,564,518,573,244,347,21,617,989,795,51,335,582,750,660,273,807,927,422,688,684,372,929,363,917,388,298,631,309,297,195,428,297,848,41,778,793,276,970,675,635,961,383,958,757,117,725,416,11,565,679,754,185,674,520,367,413,41,334,999,154,939,42,724,361,582,562,335,81,371,608,871,593,787,125,141,668,583,20,685,413,282,145,80,614,104,8,337,92,982,291,14,838,880,308,60,234,201,734,260,175,841,87,428,481,92,395,818,49,513,55,740,405,573,160,195,135,419,708,398,783,42,395,78,576,115,98,580,475,960,965,285,590,633,827,499,268,529,555,52,362,665,404,930,102,239,583,235,705,881,124,510,584,43,892,997,816,722,322,724,47,689,183,819,292,806,442,621,472,995,254,737,467,732,664,326,175,562,452,424,13,968,117,517,114,412,261,364,87,210,546,839,628,61,794,486,689,66,157,670,250,567,91,78,309,655,270,149,426,827,273,324,643,168,52,275,601,894,945,19,919,390,766,188,253,741,847,195,635,290,960,26,994,287,662,147,509,948,283,180,446,671,830,110,827,660,604,45,735,203,575,224,13,224,138,681,370,692,178,890,946,443,453,770,968,765,295,57,65,407,312,805,345,680,102,67,557,210,902,984,726,233,743,419,709,870,97,211,539,196,908,728,317,425,577,656,630,755,16,889,20,762,870,492,371,775,299,616,763,121,54,191,60,734,550,960,649,314,689,174,108,370,387,216,907,606,763,726,800,30,471,218,935,187,809,585,832,577,188,859,777,327,794,490,690,182,778,234,591,140,560,53,165,657,771,413,368,875,487,743,880,420,142,25,749,365,611,730,14,34,423,769,581,944,843,569,299,621,366,976,118,950,818,390,268,416,967,331,23,305,700,525,349,261,402,987,890,208,840,158,182,325,467,122,491,311,631,492,512,346,435,92,68,268,371,967,56,376,436,370,122,161,322,989,231,723,200,528,73,856,241,835,475,699,848,921,883,77,470,12,443,156,10,790,401,351,834,776,781,644,413,277,38,534,342,332,402,319,755,513,184,742,893,681,801,427,553,828,534,882,387,944,653,126,275,193,829,97,130,92,771,180,344,220,440,660,206,193,787,425,404,116,306,92,892,464,962,802,216,112,512,96,637,696,206,278,50,493,254,355,680,946,311,793,883,382,299,655,431,908,871,740,58,234,509,680,945,766,125,283,813,792,792,549,891,616,191,342,507,48,137,337,801,179,788,515,960,936,846,420,824,859,14,216,449,972,958,301,818,823,879,681,816,240,315,412,591,594,489,92,155,491,981,931,955,521,283,363,426,532,241,474,353,44,69,65,252,49,253,19,794,654,579,644,170,899,215,81,894,952,178,166,902,946,13,447,752,656,530,148,123,484,513,736,543,742,224,755,357,835,169,0,871,97,809,399,530,852,342,132,712,992,384,484,364,862,488,577,550,677,682,41,572,918,904,704,975,473,970,863,623,320,172,365,701,804,807,301,879,409,419,51,710,143,695,761,594,803,65,857,446,417,2,81,530,884,779,798,18,859,782,546,590,259,888,461,129,374,429,218,358,367,973,771,782,948,853,489,877,40,742,880,36,964,771,793,984,560,780,984,396,60,387,691,618,640,23,400,19,468,656,456,914,43,701,795,321,192,686,514,554,618,674,714,636,167,537,571,583,166,326,440,82,204,984,518,971,29,555,400,740,588,635,164,180,145,980,334,554,167,59,638,738,563,496,147,755,45,212,336,925,97,926,800,301,681,285,439,165,763,575,650,626,4,81,604,769,906,308,941,634,351,64,349,467,600,875,227,282,628,246,598,466,129,915,369,245,172,319,431,807,894,983,792,490,803,614,73,756,181,408,757,275,602,730,85,106,162,293,210,795,834,169,338,556,183,61,133,719,223,438,131,592,345,201,756,117,360,403,959,857,220,646,806,436,979,128,738,638,521,607,911,381,144,180,344,340,12,658,547,924,641,946,666,337,422,856,96,218,18,699,606,592,498,417,444,224,777,964,533,891,849,55,217,398,748,799,775,831,943,226,950,321,715,1,908,493,480,484,433,602,584,912,732,316,243,737,413,510,365,330,658,852,701,456,154,272,336,475,335,523", "130,186,947,644,187,422,606,662,857,609,398,272,68,704,280,128,763,207,314,943,31,34,132,813,807,403,667,40,901,432,123,119,571,727,37,199,169,900,670,103,344,360,247,178,601,386,160,406,572,358,306,517,767,956,169,157,659,183,512,209,230,791,220,340,70,775,842,492,221,423,560,319,408,537,119,288,53,467,531,871,597,308,319,103,548,903,148,697,519,742,567,724,471,822,453,923,384,882,955,461,147,981,863,823,678,752,59,778,657,978,575,468,177,919,284,23,607,682,134,777,682,256,465,579,272,780,841,58,483,955,326,561,7,311,2,413,808,38,822,501,437,918,384,53,184,108,236,186,107,312,838,851,513,131,491,220,152,294,744,153,104,226,722,974,465,941,329,823,281,443,127,25,441,594,948,969,967,411,800,669,296,429,860,192,459,644,12,292,616,241,466,791,679,253,595,367,443,144,727,741,382,970,86,532,248,261,528,70,313,183,454,181,698,467,737,167,305,717,18,920,823,422,193,153,616,191,578,720,434,216,66,724,674,263,330,277,88,418,736,956,449,702,445,404,104,557,818,57,888,443,559,545,210,404,899,349,282,665,482,652,245,395,765,604,2,397,735,160,551,939,447,545,282,295,274,533,921,276,17,301,43,514,361,959,346,893,936,918,331,507,368,263,385,23,160,848,886,415,617,769,618,234,865,941,262,528,670,840,30,132,264,819,305,33,592,98,615,839,559,321,234,334,528,501,500,605,241,944,147,612,401,274,131,736,728,405,517,125,793,479,217,126,504,165,128,184,189,591,261,594,972,128,299,977,473,224,816,936,388,417,165,672,498,832,602,52,399,505,205,339,393,796,937,815,209,899,705,139,85,66,678,989,814,54,862,596,906,471,334,687,18,36,921,175,882,264,930,41,326,938,955,117,335,961,458,808,810,606,920,301,796,371,691,836,61,863,2,465,539,621,301,933,217,656,158,743,123,316,915,763,175,63,742,926,463,757,621,50,589,12,23,499,962,503,916,940,460,582,739,62,109,350,676,384,712,239,860,238,389,398,64,792,376,122,666,287,394,560,347,431,270,174,274,444,230,810,412,722,936,933,180,116,70,201,530,232,430,201,965,690,602,567,109,404,903,652,967,618,789,146,930,115,496,22,653,250,303,885,147,200,614,71,869,812,515,509,410,783,957,19,281,587,284,383,165,799,335,843,926,507,170,897,369,965,7,410,360,250,411,542,693,644,214,140,958,917,991,339,139,430,860,553,651,569,692,393,504,633,787,900,999,734,561,379,155,704,462,987,525,245,989,256,71,945,870,802,252,360,756,154,382,116,693,575,388,796,568,413,576,584,877,357,539,710,623,916,669,627,633,913,683,485,242,368,685,32,711,950,895,625,831,994,175,681,345,849,475,681,714,237,623,831,268,890,790,641,597,800,170,303,526,136,173,270,314,836,538,436,868,450,863,960,402,689,983,419,954,5,784,297,31,168,251,929,388,827,216,222,630,139,447,901,192,730,426,836,929,967,724,486,426,259,599,991,67,895,517,221,290,60,983,806,942,991,833,300,493,845,185,441,871,0,178,210,291,716,924,956,246,756,867,535,739,544,654,224,787,2,711,94,111,415,257,570,374,159,376,159,187,809,465,557,426,239,930,736,856,875,654,924,246,76,864,415,301,218,66,344,700,342,316,728,869,938,580,119,88,109,387,379,730,843,891,707,587,245,746,869,564,160,810,143,641,963,980,469,373,626,954,751,582,158,169,996,142,657,865,985,296,585,836,205,405,331,586,690,320,120,736,233,563,568,616,14,814,689,544,706,230,276,585,391,735,245,895,848,90,165,796,580,470,570,169,819,379,491,574,53,713,408,592,308,689,970,614,513,674,125,913,919,63,122,405,953,564,127,687,456,441,244,822,961,180,51,592,55,787,991,87,514,900,250,855,37,240,704,402,568,588,292,601,675,504,449,297,225,450,187,327,684,705,914,339,117,608,553,961,580,12,838,513,225,461,813,742,405,268,503,264,660,68,79,671,291,280,639,927,463,659,309,431,543,904,315,276,81,741,478,649,191,565,295,718,475,122,559,143,169,291,469,452,366,840,113,543,470,396,174,967,907,396,409,101,893,301,911,857,909,520,102,979,117,752,443,348,680,687,585,686,794,685,354,226,45,868,424,48,333,192,30,461,918,741,916,103,79,590,860,669,643,4,575,21,910,46,931,809,933,711,135,39,996,502,510,476,244,326,8,304,187,123,805,207,927,411,954,377,437,299,30", "611,82,234,914,513,575,553,925,260,812,342,335,436,353,769,649,220,234,939,515,860,260,797,863,346,222,704,458,114,414,384,814,125,575,722,34,291,930,246,865,717,547,82,266,969,601,900,333,76,115,959,837,428,16,408,564,543,542,887,503,580,638,946,781,743,679,421,980,16,996,175,738,415,711,16,461,827,159,121,883,868,936,797,509,986,593,685,960,116,847,848,915,303,498,786,667,683,177,760,107,900,999,980,262,220,340,821,898,331,166,187,983,89,274,811,801,766,169,428,69,936,510,426,640,596,77,813,123,875,308,640,562,609,942,229,731,658,571,52,280,155,633,50,231,605,129,418,853,830,314,570,34,53,707,481,449,436,263,766,592,276,673,735,219,791,465,909,753,924,162,910,118,627,983,344,345,298,835,40,391,933,689,256,710,592,534,619,939,649,145,588,287,414,217,771,637,715,821,664,227,635,322,19,572,281,807,340,171,530,784,216,717,866,227,834,647,79,684,901,607,803,128,189,589,61,485,88,316,157,994,219,624,536,274,992,972,817,69,290,593,776,26,133,322,822,695,666,411,195,336,92,416,306,253,471,387,205,905,519,925,935,346,199,136,357,810,261,836,749,144,271,725,317,435,796,37,613,769,528,972,738,109,885,928,173,704,971,723,355,242,205,43,838,188,653,268,815,819,2,805,828,226,969,667,360,417,778,617,214,668,399,593,244,923,365,726,223,497,33,185,184,71,906,939,448,368,318,379,151,286,18,617,993,113,806,703,470,724,659,400,335,582,546,89,694,303,412,76,504,524,530,314,508,502,823,440,223,754,493,516,44,829,605,77,894,766,478,498,634,877,77,820,243,176,514,573,772,947,121,277,828,968,243,716,499,933,581,312,279,146,72,797,604,398,296,950,265,230,128,140,194,697,894,964,189,647,872,169,231,435,996,128,677,95,99,627,815,743,653,113,780,749,236,869,371,563,468,877,608,237,988,698,757,611,169,819,757,644,687,819,146,926,824,634,81,117,272,402,499,67,419,812,934,4,618,562,746,635,856,703,604,836,708,489,161,172,274,607,429,144,6,866,574,976,263,218,804,465,278,61,18,974,744,900,14,471,445,5,205,95,251,428,395,482,113,495,878,264,153,131,867,941,943,592,969,475,978,294,125,254,405,189,448,202,342,366,760,427,325,580,1000,641,627,418,306,730,848,970,329,296,894,325,914,116,676,400,177,484,144,483,819,144,712,731,140,848,549,693,994,935,364,649,914,632,54,431,772,9,296,902,67,795,590,970,695,241,382,947,780,894,680,11,846,840,976,540,918,412,630,495,392,657,273,370,782,196,978,177,106,113,871,251,63,703,913,775,531,958,553,204,81,297,46,742,325,318,175,994,776,592,213,417,671,466,463,510,447,803,976,305,718,73,281,878,247,456,600,66,754,97,779,248,522,164,645,113,311,94,990,957,90,704,995,888,451,906,109,625,792,593,792,925,980,259,52,146,379,341,726,263,164,817,610,363,35,237,72,382,973,536,645,759,795,577,719,302,182,392,14,656,984,628,465,165,331,317,192,729,321,509,97,178,0,532,914,953,118,643,725,879,582,837,796,294,819,60,253,516,29,454,900,885,385,153,756,939,30,224,524,732,601,910,341,86,451,86,460,722,310,717,607,422,398,937,321,226,944,937,403,543,386,275,266,13,371,620,372,105,414,102,102,557,503,658,553,896,525,482,432,119,670,375,127,476,224,826,702,884,820,501,213,441,968,34,527,191,591,401,102,727,419,711,158,286,289,930,96,892,555,100,947,693,859,602,7,389,13,550,270,33,87,193,8,828,55,475,855,468,842,143,873,212,2,317,807,620,677,414,348,374,74,100,130,146,476,826,495,642,403,887,496,370,467,616,630,916,141,981,867,908,876,445,93,929,56,770,236,391,78,208,35,557,811,176,726,857,342,904,242,638,545,154,55,827,951,434,998,769,973,366,137,778,376,641,140,773,909,611,915,420,197,953,992,126,146,590,788,440,10,593,78,41,586,921,633,344,602,899,993,208,150,882,219,193,300,23,164,290,916,206,613,836,7,801,607,597,805,963,422,575,580,261,477,327,76,463,568,77,315,287,147,640,991,903,280,396,977,548,231,343,489,96,44,461,329,233,26,213,829,409,971,371,888,702,917,467,574,454,912,681,316,227,174,637,985,498,804,878,847,655,605,174,901,361,75,772,911,833,103,213,407,851,860,639,879,48,905,829,855,356,777,763,850,941,995,568,501,418,667,778", "998,830,745,500,554,2,287,69,703,675,750,883,958,995,828,239,745,994,95,688,673,719,650,20,820,3,346,457,83,756,950,693,195,893,471,825,384,242,569,950,640,500,128,518,960,486,104,982,304,623,362,868,628,864,974,672,274,617,843,930,944,304,641,163,641,340,587,700,729,12,26,816,289,250,578,670,11,921,343,521,630,532,132,133,625,98,991,700,57,218,138,83,370,919,457,564,400,679,240,799,468,597,941,29,631,78,815,541,161,513,697,324,705,202,514,595,663,803,329,63,142,934,492,258,559,358,121,883,569,751,736,775,591,257,441,108,383,347,534,140,444,43,965,421,92,240,864,717,283,856,61,410,690,281,169,739,247,126,211,697,62,503,211,251,20,893,773,156,304,177,359,251,737,308,538,415,838,247,91,793,50,510,738,388,950,572,262,691,355,8,291,852,603,922,172,132,370,998,810,502,881,402,664,34,804,10,230,151,220,903,300,129,290,789,145,693,254,364,574,697,997,51,650,400,456,861,892,209,565,442,234,588,891,534,16,797,906,974,645,191,451,678,549,141,854,743,507,394,714,69,375,403,811,146,208,640,213,588,278,114,722,56,683,488,74,294,224,991,123,271,201,824,592,172,185,375,665,795,692,916,466,162,976,7,328,525,864,871,139,126,202,171,195,850,316,819,657,819,183,211,391,789,467,980,290,68,370,286,671,180,245,796,125,596,942,929,989,999,346,229,974,572,476,424,382,829,782,755,250,515,443,6,312,253,903,326,788,959,643,182,661,784,829,944,645,732,35,608,520,926,87,73,959,605,792,524,791,333,392,698,781,724,169,598,537,954,45,863,26,888,571,575,715,969,550,3,423,482,931,108,187,762,970,261,391,209,220,86,283,90,175,748,61,771,107,85,509,817,893,547,900,205,299,552,790,823,545,264,533,370,421,161,332,961,660,751,484,267,851,760,867,325,954,986,461,472,899,851,784,74,714,184,692,653,172,436,379,844,869,723,945,765,943,190,767,587,287,955,434,924,40,778,776,645,225,926,748,665,17,318,219,600,329,336,301,156,656,258,565,918,238,261,818,40,796,882,631,357,121,439,381,518,699,556,829,251,815,470,38,973,494,677,974,995,117,682,397,750,690,384,914,92,351,156,547,994,922,43,371,321,543,430,810,334,132,56,50,183,83,713,832,93,527,706,240,30,782,811,89,284,608,290,39,370,122,18,634,717,367,341,909,394,56,762,610,700,324,945,766,491,546,343,590,31,206,128,986,903,485,796,50,175,720,200,39,50,833,186,498,802,427,4,1,856,125,797,142,641,840,828,959,779,616,420,756,577,172,503,761,229,13,295,262,866,646,928,585,217,898,530,131,49,7,192,623,502,117,27,262,299,696,710,200,280,238,769,59,261,477,989,800,873,210,576,752,894,329,797,726,125,986,299,967,27,629,394,704,952,234,70,261,220,597,255,376,112,440,445,200,624,349,389,125,577,567,892,809,540,324,683,315,802,602,72,76,72,512,25,327,849,612,442,980,441,734,787,312,224,604,384,165,933,768,613,978,801,774,982,262,587,809,210,532,0,140,941,242,770,550,313,789,37,262,544,737,246,672,477,431,946,106,288,495,956,932,108,932,914,662,342,809,443,148,597,636,709,661,383,342,158,11,369,205,663,668,722,61,525,60,895,18,281,57,901,175,350,512,272,300,549,454,973,141,627,389,795,713,28,727,727,956,457,675,215,58,250,831,423,72,789,715,574,548,781,333,401,507,500,434,342,154,484,949,677,871,964,72,696,273,567,956,466,487,551,653,269,893,477,821,65,724,765,223,79,180,571,459,767,338,880,270,974,757,819,184,341,326,387,730,271,230,553,390,171,662,646,285,245,910,58,415,439,519,320,172,938,530,131,872,805,847,889,588,684,790,548,573,472,235,199,96,270,531,679,200,176,424,155,869,759,464,758,500,470,17,116,81,201,922,67,970,293,458,398,288,824,835,494,155,899,781,218,239,745,6,103,166,300,303,262,500,843,976,698,235,89,578,67,130,809,138,390,695,558,662,787,619,875,119,232,728,854,746,429,59,416,338,955,823,918,534,667,579,166,113,172,657,238,976,251,693,247,138,268,723,403,248,360,984,361,797,951,718,776,716,166,755,493,327,410,38,675,427,996,387,421,453,329,136,26,576,52,973,783,403,876,721,228,39,839,505,801,225,511,739,826,308,386,145,137,966,605,137,198,975,198,915,929,804,192,526,535,396,607,394,928,189,424,51,284", "669,22,669,643,997,386,511,78,849,201,525,706,242,512,297,795,871,367,907,860,552,53,483,88,886,428,875,638,85,543,97,726,459,970,496,75,564,574,203,584,820,373,110,30,571,26,649,756,796,249,398,770,100,820,187,482,404,869,441,274,65,366,751,658,348,693,324,691,299,697,743,2,962,756,447,782,797,527,830,439,434,478,340,999,646,632,59,547,607,480,872,552,827,61,699,462,579,501,802,559,108,642,668,607,845,128,399,185,288,799,903,260,653,202,678,610,984,544,720,914,770,178,530,816,698,486,619,409,664,192,453,899,495,994,450,4,115,98,17,118,218,449,174,976,693,841,775,906,179,368,20,280,614,138,722,798,123,891,329,262,183,986,439,525,484,14,65,169,880,368,321,463,792,524,88,70,410,365,206,105,517,694,917,465,752,894,720,841,536,130,255,108,357,808,947,419,960,658,660,889,853,565,211,816,182,913,760,510,88,319,297,998,968,499,585,783,506,512,522,604,356,677,779,419,247,834,608,701,497,396,243,789,538,659,879,749,132,242,443,981,251,173,24,607,65,751,900,30,270,910,953,138,286,483,25,988,321,253,888,313,473,528,309,91,485,912,112,639,953,864,576,276,339,156,320,529,593,626,960,901,422,796,276,220,328,120,847,464,222,579,509,543,960,288,6,375,700,694,993,222,942,952,836,24,96,185,30,851,993,833,394,395,526,609,391,461,467,489,375,358,435,416,830,751,791,852,919,498,670,942,579,326,281,248,187,265,932,269,635,135,308,889,92,482,796,409,950,499,102,32,439,494,98,344,133,632,576,202,59,690,774,45,184,913,255,649,876,528,210,576,258,400,560,947,349,534,696,248,467,817,93,530,112,45,20,499,711,923,123,230,429,648,689,144,969,452,621,147,600,708,579,843,447,69,363,89,378,514,201,544,354,259,570,724,446,719,749,740,409,574,103,907,667,789,476,89,892,603,495,101,420,324,660,982,342,401,902,4,822,476,158,226,383,512,292,275,982,410,486,614,813,110,514,360,912,586,454,901,752,822,221,326,345,239,649,333,810,546,715,686,885,872,891,919,877,80,62,258,810,495,70,136,561,471,695,372,344,964,788,244,708,810,104,693,636,174,456,948,349,328,643,412,767,858,6,609,93,456,333,640,861,340,216,231,626,500,608,791,912,785,486,57,693,536,543,789,396,217,289,107,447,170,346,797,869,368,246,580,380,129,147,316,711,183,933,396,899,886,94,29,895,388,690,899,78,140,796,733,916,265,768,224,242,271,292,1000,912,164,691,436,668,667,499,587,24,79,364,932,528,209,413,510,578,891,470,244,744,662,779,878,586,33,149,102,390,341,702,988,833,585,261,43,616,534,388,980,528,804,795,370,494,671,399,402,515,583,249,879,749,371,949,73,563,700,662,271,496,917,845,895,831,847,352,738,161,178,679,831,302,386,684,953,97,870,996,873,664,908,356,980,217,128,666,314,377,511,422,64,314,465,529,211,733,507,831,624,103,842,646,494,93,444,691,399,634,572,116,687,926,932,243,427,388,875,503,960,964,678,422,754,399,291,914,140,0,438,43,500,82,456,757,382,242,120,814,730,388,508,34,49,173,820,357,592,423,117,582,664,403,57,822,12,112,890,692,755,401,874,596,838,314,251,773,668,525,792,903,152,45,909,122,602,675,128,784,607,190,891,576,415,899,442,619,694,550,799,799,358,315,854,900,282,155,493,513,584,909,551,51,832,241,857,103,540,532,309,134,77,844,49,307,774,819,209,473,509,915,605,746,811,72,605,521,809,240,973,10,147,944,803,766,903,880,10,291,5,506,882,869,342,78,623,316,131,474,874,175,801,184,346,425,194,621,199,603,265,210,588,950,882,294,80,909,909,323,401,558,624,727,372,299,298,976,387,973,534,65,419,333,927,528,997,304,409,390,951,874,734,152,882,713,955,13,967,193,135,246,143,445,986,540,575,729,165,946,706,867,37,936,227,29,789,940,300,363,200,747,716,331,805,584,632,689,938,421,511,877,454,735,376,243,432,685,768,713,32,753,108,308,511,954,617,642,941,296,988,797,448,769,809,689,208,331,590,33,393,623,935,691,967,615,394,230,481,24,28,407,152,357,184,372,203,199,549,403,565,431,527,335,377,589,397,258,308,86,235,471,769,818,244,617,247,551,828,499,875,301,434,616,674,133,741,766,793,665,203,135,848,496,303,138,721,300,935,112,210,499,292,482,373,887,676,726,730,858,667,605,144,802,248", "350,865,47,579,630,120,891,795,295,556,24,231,54,82,931,536,13,473,368,341,471,480,169,333,630,621,741,78,383,424,762,290,171,326,323,854,423,216,571,914,193,860,704,742,470,153,779,164,607,907,32,152,579,315,993,4,20,824,130,569,875,518,345,547,665,69,4,139,497,93,252,49,459,38,558,676,550,628,39,54,499,762,601,592,128,462,706,466,279,875,5,828,811,844,961,751,53,653,635,6,283,409,514,371,48,520,770,326,84,104,349,943,547,779,548,936,530,541,926,784,722,390,313,599,737,486,690,847,260,834,976,735,940,577,298,594,414,933,273,860,450,497,766,617,80,416,551,883,530,790,318,432,123,919,49,159,118,799,994,593,109,580,371,934,830,401,663,427,146,344,367,592,669,107,515,442,364,823,773,165,195,83,970,744,137,758,922,206,311,659,286,993,459,106,230,287,116,132,566,147,348,223,43,357,557,822,323,79,818,841,335,908,631,77,548,794,131,739,708,796,751,380,340,294,125,8,198,650,909,568,817,879,597,767,970,432,288,963,803,143,846,417,436,418,122,97,514,269,881,42,134,783,188,737,369,300,801,554,460,352,895,312,354,157,734,451,982,510,467,846,424,641,202,38,165,401,149,254,348,143,596,966,857,662,79,418,266,822,359,124,989,97,419,373,80,271,425,993,152,904,929,411,718,805,450,976,589,426,902,512,664,716,643,834,13,289,749,47,578,537,354,5,972,946,303,495,352,371,131,966,301,815,731,389,323,633,637,589,884,582,426,99,945,508,647,359,592,450,905,583,29,207,902,71,306,633,52,252,411,673,507,861,195,591,15,153,73,396,662,594,640,927,9,431,42,203,228,905,259,210,362,912,801,541,277,641,111,597,737,712,329,51,37,246,385,205,464,227,85,803,416,759,424,384,890,227,507,595,438,734,898,167,243,462,539,609,109,384,435,761,728,452,318,390,529,175,720,542,408,321,318,15,316,46,471,558,265,244,772,955,523,321,977,731,394,296,162,400,472,633,554,506,947,221,469,792,86,427,520,562,838,48,891,928,368,413,111,260,527,865,715,726,734,512,706,354,288,766,744,982,631,819,818,903,529,573,241,829,251,506,618,66,106,19,998,570,974,461,908,625,970,606,910,466,182,85,775,979,409,986,417,595,652,362,163,578,393,902,203,970,551,29,619,586,750,76,412,58,925,10,187,663,874,264,853,206,716,617,724,745,992,211,674,893,707,509,900,21,825,690,251,882,256,792,980,995,660,394,701,909,995,306,985,793,188,362,697,762,565,638,189,957,224,318,158,492,105,435,418,369,897,290,231,130,595,633,662,432,377,594,81,27,411,355,515,275,523,151,749,684,525,990,304,627,455,124,240,46,744,726,854,587,569,828,422,980,810,62,651,739,169,413,569,615,617,269,722,991,313,365,459,311,474,483,713,577,58,457,950,105,491,938,675,132,502,483,165,835,719,91,276,392,983,465,342,152,436,290,73,84,192,217,161,982,158,552,656,217,615,861,790,484,216,951,10,856,391,110,204,405,574,293,711,352,557,117,846,301,550,968,530,716,953,941,438,0,192,255,109,491,173,386,60,520,642,806,195,973,146,902,327,719,40,56,426,162,818,892,421,995,832,855,566,355,351,756,14,237,309,522,734,903,780,239,108,152,61,500,999,283,170,417,904,364,197,367,578,351,634,187,619,46,836,834,246,604,376,435,207,844,991,185,745,868,921,803,754,70,296,204,952,688,714,301,315,258,922,536,150,341,322,509,345,72,692,241,458,39,692,696,33,523,434,686,824,329,533,314,716,681,782,120,443,347,143,469,820,334,208,608,718,607,578,263,410,7,933,254,486,932,254,61,97,162,485,748,380,644,709,497,737,161,232,144,266,629,944,864,521,856,636,966,920,876,740,943,806,931,983,408,41,341,963,342,134,860,416,898,972,811,34,78,795,824,876,740,38,408,779,753,768,360,532,604,248,394,139,158,68,812,681,546,941,611,604,843,7,606,596,929,768,512,396,838,666,116,665,423,346,450,644,894,342,286,351,503,893,592,109,605,151,401,955,892,904,650,66,175,818,291,576,659,679,597,673,69,58,196,511,447,540,466,319,373,104,12,708,500,434,513,3,926,314,619,569,215,554,378,238,117,259,980,939,144,753,97,512,956,578,47,404,878,229,973,326,58,252,982,400,457,970,315,546,290,233,293,84,763,612,6,444,662,775,90,349,519,595,959,886,506,353,600,41,244,629,443,252,674,594,831", "234,589,270,508,52,896,537,821,308,970,147,75,873,226,819,76,933,960,563,742,726,686,383,966,358,353,167,670,960,217,198,653,27,459,797,792,386,425,238,118,48,616,954,217,507,699,908,112,718,868,804,568,874,134,919,662,210,635,81,300,503,687,256,146,389,476,781,497,418,113,359,963,926,311,720,210,857,316,260,300,118,366,43,399,586,474,533,644,364,929,771,903,108,944,968,356,881,343,381,51,727,203,524,908,469,972,247,661,546,432,323,483,108,783,470,522,952,99,460,845,227,177,857,488,131,391,901,462,387,282,941,146,154,363,449,975,814,148,193,398,141,406,986,648,738,403,541,177,662,81,47,319,267,571,674,716,169,963,279,666,461,872,125,598,912,723,588,820,977,508,898,541,198,703,590,752,480,842,718,809,963,85,986,918,805,300,946,545,41,563,168,329,573,911,479,421,64,961,633,545,314,59,284,74,862,781,165,889,205,59,442,342,79,504,496,248,42,971,277,611,458,348,37,71,946,232,756,887,445,559,38,287,287,717,933,935,324,380,669,581,209,724,908,555,986,483,290,489,614,204,364,216,701,955,345,596,869,702,142,747,787,672,698,412,149,736,199,894,180,46,898,727,203,593,388,810,125,817,878,970,291,738,416,820,449,447,488,355,884,342,276,697,160,521,408,723,849,984,921,940,768,504,920,904,209,795,989,69,14,947,861,632,384,366,749,283,30,405,623,569,935,66,59,182,728,953,942,178,708,471,87,407,959,8,61,143,930,139,741,332,873,123,655,418,227,870,538,207,638,226,618,465,312,706,863,793,714,316,26,51,832,75,992,729,810,794,980,716,259,382,834,178,811,575,591,194,670,820,404,243,829,717,808,486,131,60,401,48,668,569,298,941,431,150,923,287,186,834,408,935,70,311,187,520,758,324,955,602,273,829,650,76,21,653,71,61,703,480,178,421,37,369,859,670,944,610,958,128,592,750,109,13,717,490,274,209,936,890,49,917,25,459,776,307,162,119,831,989,550,15,839,707,429,527,630,704,994,252,504,826,69,154,901,43,601,1000,987,796,614,610,682,572,134,187,828,903,276,536,224,705,664,448,767,679,821,432,62,585,515,417,903,647,8,560,9,447,331,813,406,989,372,245,274,919,540,584,37,312,609,643,71,845,730,527,198,590,872,590,590,851,579,52,801,355,444,646,458,645,375,517,704,837,789,570,189,419,665,475,530,128,353,622,946,860,385,639,969,493,510,178,285,467,487,876,626,23,920,300,438,721,473,225,296,887,709,481,144,501,341,352,545,808,759,676,650,664,864,275,1000,96,706,241,407,949,202,195,818,766,870,810,742,560,705,941,870,868,370,512,194,679,707,519,944,889,236,572,453,633,798,461,390,317,519,677,161,278,810,90,671,355,781,699,703,784,296,438,17,821,830,724,354,156,408,604,290,221,866,919,336,9,414,287,349,887,118,349,285,688,229,502,427,26,507,132,715,809,722,932,959,646,155,226,641,368,969,255,133,514,377,601,8,78,974,505,715,281,291,259,219,174,246,984,892,20,369,791,138,522,902,520,852,924,118,242,43,192,0,81,519,220,715,6,836,256,781,398,472,781,988,849,908,154,735,181,841,111,627,562,790,484,6,891,790,459,527,69,472,194,60,533,596,755,823,746,624,105,441,627,771,215,600,616,978,608,444,921,324,352,366,841,653,828,874,828,526,19,157,598,517,964,729,441,807,952,5,835,971,759,951,162,47,793,696,631,979,780,132,532,155,394,408,146,906,32,550,518,668,10,744,68,323,421,499,809,499,525,68,968,370,595,767,519,165,111,215,993,78,606,872,711,178,701,115,855,974,938,8,484,752,722,584,252,278,930,7,159,114,433,40,568,171,618,353,846,32,346,984,257,425,955,11,88,49,913,813,407,23,289,869,832,552,601,188,947,994,678,142,492,628,86,401,323,829,621,270,282,836,268,198,198,434,122,976,995,792,130,627,865,241,92,312,150,224,15,496,556,179,637,478,160,34,198,467,332,667,45,154,782,582,930,165,721,329,405,684,995,957,261,745,612,878,757,316,209,426,13,727,925,746,21,492,888,862,715,731,710,86,669,138,723,767,944,535,723,492,685,118,436,228,507,35,877,466,661,931,162,997,388,939,731,174,668,697,294,63,800,514,304,210,388,41,504,610,838,336,421,942,714,284,177,295,950,597,762,946,827,528,403,205,896,911,322,701,570,259,407,490,207,815,312,955,47,524,601,106,250,405,635,572,477", "272,375,799,878,938,422,243,888,739,541,834,580,539,686,147,20,436,562,816,318,619,904,654,588,905,150,813,404,90,275,98,419,193,734,447,153,885,110,902,481,801,734,43,877,917,768,159,885,784,809,568,238,177,942,912,83,286,380,672,422,358,929,349,702,585,638,922,958,567,304,610,653,907,57,70,629,520,914,655,232,473,377,610,774,920,754,168,931,556,190,732,36,878,729,877,562,395,838,35,450,250,995,836,590,908,889,2,690,733,799,957,49,798,698,293,761,292,956,715,531,701,317,133,43,506,606,327,343,552,622,406,566,113,584,128,201,779,979,461,223,637,429,180,205,246,376,112,146,390,370,927,827,756,42,149,551,595,250,123,646,954,996,930,65,249,689,752,137,694,949,788,916,994,147,291,84,825,394,120,371,15,21,586,908,699,336,639,565,720,883,309,468,388,247,981,612,779,715,826,994,748,795,937,438,376,219,943,529,246,87,709,182,983,879,583,210,840,261,592,71,584,931,892,25,406,620,545,119,361,874,345,231,90,506,18,99,239,437,771,908,595,720,438,944,707,897,628,184,481,684,220,440,371,627,860,84,146,752,858,731,507,646,410,410,284,540,83,664,837,27,479,34,622,842,92,70,685,735,401,509,337,845,764,118,647,384,658,532,136,738,502,776,47,80,906,198,629,955,66,553,214,905,898,564,967,662,246,566,805,413,598,195,305,356,150,107,886,230,75,144,118,894,14,410,717,723,183,959,203,881,566,992,434,477,539,173,595,741,564,870,165,79,624,495,620,231,623,641,628,778,297,751,177,542,912,693,409,663,287,637,383,91,878,608,167,953,515,555,667,835,830,471,353,709,480,386,382,11,815,299,592,126,830,260,396,170,928,525,46,599,377,536,347,425,33,573,750,149,980,996,957,613,135,893,286,660,446,455,240,557,756,335,699,717,718,63,32,204,422,750,507,150,935,294,760,95,218,764,133,985,753,250,565,348,129,587,463,697,495,269,701,229,171,673,237,568,988,241,268,375,337,855,748,348,878,713,595,240,719,931,670,56,903,526,426,346,105,428,239,702,591,105,892,749,36,278,35,708,201,873,46,747,845,412,807,155,286,3,18,294,689,199,63,366,827,130,307,626,919,129,521,807,266,623,939,476,788,233,85,593,992,101,918,242,178,438,461,205,705,939,575,93,949,430,236,946,863,383,82,175,913,446,33,663,978,303,117,262,555,915,253,909,914,815,43,798,86,463,217,829,897,1,457,16,906,13,552,798,581,567,452,656,737,983,875,831,838,448,678,970,256,930,896,750,129,556,749,393,823,936,661,907,789,75,592,936,687,227,154,127,699,292,190,874,552,894,44,234,149,792,215,637,25,447,595,879,584,318,968,17,361,729,504,819,154,948,810,85,185,583,128,528,422,996,395,963,220,854,750,516,229,224,690,709,902,779,162,245,912,828,927,191,820,444,793,687,255,911,573,240,315,918,192,922,970,528,989,557,728,869,503,678,376,178,564,18,390,980,560,114,195,410,403,643,394,980,249,508,799,280,900,208,413,365,2,921,140,383,685,792,342,956,643,770,500,255,81,0,684,441,165,372,524,685,62,744,514,129,113,295,137,211,653,724,750,678,412,744,826,902,507,92,720,904,769,891,926,675,493,517,447,864,383,795,167,47,778,582,848,6,368,972,607,243,922,359,157,214,212,239,410,160,940,969,421,502,195,304,74,418,197,272,181,437,54,132,438,363,817,295,715,613,306,200,742,910,694,911,773,233,507,747,537,863,963,796,862,802,399,690,653,274,649,937,643,237,669,177,359,842,300,189,875,88,478,201,776,530,8,708,307,29,821,610,718,179,481,339,496,696,666,139,115,439,425,282,161,702,125,998,472,392,336,101,319,925,930,460,16,229,287,861,596,414,823,616,551,846,942,290,742,332,990,330,46,546,880,770,975,799,955,484,20,18,743,159,609,255,457,84,42,502,124,567,396,792,254,745,60,412,145,540,644,150,956,445,784,487,588,244,284,243,347,199,480,795,165,520,615,901,507,120,535,218,895,922,58,1,706,326,911,879,909,424,880,309,968,572,18,146,55,568,430,423,506,542,719,463,945,893,152,883,577,548,283,401,279,931,81,112,399,406,340,561,981,336,980,128,890,788,123,794,119,563,558,197,572,607,158,47,909,532,689,202,551,83,523,260,747,380,542,761,881,293,998,789,171,799,311,248,955,225,148,263,74,70,883,608,377,601,570,197,38,323,224,218,70,196,582,156", "149,312,300,52,264,569,101,297,534,530,174,380,740,79,123,447,464,393,949,71,730,266,496,174,463,496,184,461,577,460,557,58,6,215,149,103,591,112,148,210,172,949,846,535,631,631,389,303,852,1000,482,143,988,127,220,254,435,4,711,684,665,530,564,243,70,382,523,239,432,248,917,996,937,432,375,31,152,551,306,419,862,607,815,673,184,552,31,910,420,254,593,824,589,934,884,991,460,131,919,377,854,270,134,899,388,316,764,62,84,444,748,366,489,42,572,773,225,266,217,171,479,639,912,683,71,420,652,453,293,993,814,637,551,777,725,852,521,448,274,547,528,863,532,361,414,841,190,676,712,144,138,229,802,328,573,597,238,637,665,568,304,130,232,342,265,49,844,506,72,968,662,589,402,308,623,533,220,313,301,10,109,676,304,31,678,678,93,764,24,501,437,61,670,411,964,713,330,966,729,139,68,238,883,522,70,145,874,945,835,931,383,978,315,267,780,573,136,755,22,445,93,630,163,872,252,479,149,730,802,222,853,437,545,848,262,986,885,443,559,735,356,658,928,14,530,140,606,696,823,496,751,604,29,372,157,649,660,239,312,273,943,916,77,157,933,29,952,974,272,710,160,512,161,142,496,766,254,605,981,182,662,811,257,961,681,221,674,202,702,416,170,329,629,953,749,948,264,992,750,823,414,757,427,507,748,439,614,671,215,438,249,898,810,757,352,948,471,365,916,211,214,784,648,337,320,886,892,618,23,880,717,235,189,363,574,504,538,512,596,637,754,371,795,662,636,485,291,29,825,226,973,22,869,774,948,454,259,594,427,107,413,299,240,230,368,296,275,262,194,596,28,636,138,756,190,327,530,478,476,954,203,204,8,523,254,489,661,281,506,527,54,845,557,185,384,599,686,509,934,548,387,264,751,169,535,667,160,789,590,643,878,973,581,79,500,346,653,404,135,851,264,897,918,322,917,214,755,397,181,864,123,686,531,779,233,557,869,574,914,152,858,895,171,42,861,950,468,125,961,866,280,28,781,616,161,655,762,265,84,955,671,505,813,19,726,82,152,987,126,58,808,949,764,267,18,41,243,168,60,349,436,513,582,308,8,740,733,562,168,642,216,433,86,11,542,467,125,156,726,883,807,88,981,212,826,190,283,319,673,331,612,762,517,271,682,851,183,129,24,129,312,829,577,524,922,181,273,821,987,386,606,250,36,700,278,55,514,826,453,188,751,212,479,699,179,740,894,471,985,300,98,65,680,185,621,730,566,634,92,290,966,307,636,380,867,646,444,456,995,270,329,392,504,115,686,909,518,514,945,813,25,336,238,547,100,324,342,157,679,254,525,189,733,323,282,351,846,936,401,825,247,66,178,46,82,289,955,596,62,907,37,19,17,790,981,358,658,738,606,47,846,559,396,408,989,458,96,814,341,966,604,609,236,818,239,516,248,104,957,241,717,370,655,740,120,143,150,899,258,276,689,903,247,691,687,858,357,134,987,532,510,811,779,280,611,363,84,744,570,653,41,22,738,357,913,982,144,901,585,12,831,195,127,295,621,383,173,276,635,902,132,246,725,550,82,109,519,684,0,320,812,967,814,570,997,285,342,859,378,441,410,212,328,242,845,82,897,602,397,654,874,966,858,598,102,616,440,900,327,9,503,275,428,222,814,450,816,419,770,284,314,66,381,204,770,195,252,725,288,172,410,802,662,647,568,164,106,424,459,574,896,588,799,414,447,35,108,763,393,866,404,976,329,298,17,204,452,489,754,324,811,254,81,742,529,881,872,897,780,830,127,263,910,347,845,477,20,912,884,354,618,816,21,468,255,285,554,61,306,153,459,688,306,316,732,327,927,491,535,297,927,422,138,856,503,720,993,339,907,71,627,605,164,935,517,252,419,63,502,394,68,461,282,646,491,537,413,721,204,722,293,216,137,430,650,568,411,480,292,992,147,585,980,936,907,669,415,888,434,810,635,390,801,333,451,826,562,451,731,696,594,114,544,860,647,774,920,305,242,871,228,55,196,18,756,764,623,920,207,23,162,433,223,299,616,954,422,591,185,949,256,628,997,485,420,976,299,298,743,902,867,913,37,272,198,748,112,90,264,272,600,39,473,524,288,876,383,579,310,68,658,305,830,530,971,233,334,873,439,942,13,32,508,221,634,874,34,485,853,328,988,10,146,516,30,168,979,371,8,104,911,800,861,615,643,408,201,716,182,255,521,733,628,338,81,521,542,998,974,590,280,50,983,716,365,2,423,268,329,9", "714,626,67,830,872,189,532,479,559,354,439,835,864,511,723,182,457,705,501,675,263,979,620,506,948,940,549,242,910,280,284,823,603,936,846,827,98,144,211,664,885,944,709,270,613,653,887,545,341,409,999,457,677,810,324,100,694,581,609,244,92,656,887,688,583,274,411,740,722,587,421,324,130,93,738,589,946,1000,761,242,519,425,836,846,439,859,420,295,187,389,910,555,440,894,975,561,884,974,772,104,138,988,656,990,943,383,242,730,979,642,381,502,410,876,767,135,103,356,214,831,363,24,846,296,771,623,802,128,501,967,290,348,744,327,117,95,302,743,707,256,302,446,372,176,480,10,994,532,696,896,456,970,998,411,150,543,542,384,188,243,785,510,388,273,710,382,141,975,895,647,513,715,47,369,112,612,721,985,753,929,62,498,983,167,307,912,733,488,642,504,500,33,592,558,592,530,336,851,491,37,531,587,18,713,422,48,759,740,858,990,947,546,25,542,999,132,854,762,711,801,79,873,926,660,415,825,694,92,634,209,79,214,72,227,454,683,767,127,499,112,113,218,615,358,656,644,642,789,877,394,306,346,867,807,112,571,450,203,992,669,201,33,936,182,13,406,910,897,830,170,568,535,186,584,458,892,982,125,85,38,920,564,613,258,163,971,457,300,125,63,333,892,784,94,325,846,948,772,869,921,28,461,542,850,695,810,242,291,651,449,351,151,917,957,392,223,842,364,975,32,277,679,871,348,432,689,567,705,326,859,785,317,129,197,805,738,504,541,277,190,970,177,502,110,433,594,469,214,135,380,614,819,134,936,588,721,569,606,984,509,418,164,740,721,249,361,260,652,170,245,754,489,856,639,579,524,245,700,514,451,885,609,979,855,116,567,972,484,896,615,609,326,209,24,621,126,129,928,788,842,919,716,410,680,325,297,60,452,669,633,767,239,355,508,553,786,178,389,863,446,105,487,219,41,965,685,507,54,109,254,499,106,120,898,268,867,497,494,265,797,790,363,443,644,617,169,393,226,538,547,900,430,905,654,997,787,645,842,653,838,520,645,466,295,363,855,34,998,92,481,459,331,458,463,376,661,556,528,953,684,701,474,771,629,476,65,818,534,456,196,162,856,671,412,272,993,808,955,4,578,77,770,495,620,659,663,429,815,146,849,433,443,397,89,118,250,747,16,217,36,530,874,660,272,514,871,337,437,918,410,594,323,431,562,183,457,467,875,41,222,400,178,161,757,22,750,77,714,613,669,428,384,561,266,283,401,232,42,730,769,696,588,46,606,952,813,47,772,390,913,737,969,287,603,35,901,502,298,161,771,917,926,533,24,38,753,352,551,537,484,385,954,123,111,560,527,666,504,131,401,468,253,758,151,199,382,983,590,429,39,862,939,740,740,235,156,549,392,210,815,696,127,67,83,157,68,261,495,664,271,696,72,924,525,695,603,926,883,95,737,323,37,506,927,356,16,470,583,320,157,265,563,467,564,129,465,758,216,386,356,660,489,641,114,210,569,69,563,614,570,626,653,666,434,746,951,549,595,180,716,957,118,158,416,220,833,247,657,893,888,712,756,879,313,456,491,220,441,320,0,254,192,341,990,256,932,598,429,51,847,44,587,799,548,518,75,739,95,433,843,827,619,819,750,728,557,516,57,682,3,123,450,309,27,458,593,84,570,49,62,139,953,461,388,430,546,316,194,491,118,676,990,789,313,438,279,679,786,144,740,350,867,884,180,369,648,378,669,556,239,162,967,103,275,578,534,575,144,300,151,246,41,747,521,998,169,973,455,34,595,794,429,544,305,802,421,123,738,591,668,672,396,285,507,942,417,590,152,302,601,904,769,875,343,478,244,712,792,983,132,235,855,759,119,248,480,676,287,291,927,55,621,508,976,909,882,902,456,656,699,943,128,87,571,412,427,714,469,426,601,469,530,95,540,149,324,940,287,648,168,429,944,520,53,800,756,346,251,849,741,639,764,838,653,548,83,785,384,691,88,196,489,615,324,189,538,755,340,753,674,152,503,553,468,295,563,706,402,896,311,976,179,279,519,227,635,535,194,659,506,78,363,923,212,58,888,681,381,629,488,504,411,323,322,63,7,178,417,93,943,810,439,812,884,96,990,552,852,771,988,147,694,365,936,191,143,58,471,463,42,804,844,690,916,482,152,343,52,429,519,345,673,675,690,552,323,14,918,56,653,527,74,973,873,547,764,957,727,66,165,832,879,80,736,625,213,277,932,412,533,309,316,896,403,190,251,80,376,499,753", "942,550,102,363,260,414,262,612,298,509,238,735,938,76,693,367,870,816,467,11,242,607,492,425,586,59,628,881,441,122,927,593,179,510,83,151,542,851,514,151,928,717,228,566,234,471,959,157,251,26,945,931,412,937,762,312,395,592,754,165,528,86,761,19,469,947,73,141,154,908,622,211,979,126,57,628,121,143,792,364,410,247,387,961,431,658,24,961,734,365,501,472,420,731,686,119,679,890,846,395,949,840,785,518,858,191,291,944,174,693,137,732,364,429,389,7,945,864,514,372,44,731,680,294,131,379,69,892,306,152,186,694,92,962,246,841,250,463,207,166,181,316,71,309,82,450,406,94,975,923,393,102,47,792,148,775,78,563,835,564,209,518,156,913,756,385,663,382,642,266,705,333,723,97,964,817,702,386,262,195,944,1,608,393,730,588,918,887,877,500,428,908,94,401,762,585,334,678,581,666,824,809,549,62,396,619,503,206,541,691,61,556,73,965,831,573,877,968,724,594,493,91,562,731,368,797,911,577,241,635,55,452,23,292,42,664,146,406,510,264,887,315,932,675,427,340,811,106,413,537,998,159,809,903,617,452,841,404,141,49,545,982,344,567,163,167,730,390,983,78,153,502,504,995,778,589,759,725,718,685,916,222,290,208,903,890,281,953,56,203,806,517,950,193,623,233,780,613,869,742,649,252,679,54,792,350,101,350,672,354,37,892,920,391,291,229,638,868,677,571,513,201,643,249,642,743,200,626,620,853,239,264,75,625,668,103,992,866,39,944,902,346,635,442,213,998,573,6,221,318,855,173,391,660,874,68,101,344,742,224,461,494,521,30,375,161,678,773,983,580,576,663,62,481,290,137,370,89,299,766,542,230,25,482,254,111,775,257,460,411,940,533,662,987,312,427,796,759,363,919,306,200,802,430,89,44,337,814,146,936,307,717,529,806,633,720,898,190,378,747,900,889,910,753,945,237,454,225,688,30,413,78,291,461,310,644,900,299,451,946,360,700,262,612,462,179,921,977,575,48,222,578,844,256,277,494,446,205,429,185,519,297,337,768,451,205,892,740,41,172,223,174,799,528,534,338,163,438,250,772,370,104,105,515,451,43,338,983,959,876,816,968,836,595,898,649,963,2,49,121,932,510,77,111,453,746,368,564,717,389,780,778,337,271,666,414,308,71,294,392,762,547,102,884,670,546,546,193,990,887,983,356,966,355,174,860,888,872,49,375,389,18,534,808,734,212,66,372,786,829,581,859,284,699,157,524,119,208,573,54,60,163,77,417,494,689,212,44,372,8,35,582,464,67,687,42,285,615,942,355,83,580,829,571,920,294,703,154,20,153,555,319,648,297,986,622,944,833,935,525,516,207,62,75,303,880,212,316,130,2,774,280,658,223,550,48,913,831,494,105,688,924,940,727,868,457,60,713,326,113,473,99,778,614,254,626,82,507,251,449,305,597,689,505,362,896,834,65,941,363,573,159,651,367,50,128,506,674,975,932,199,399,596,727,441,393,433,811,807,4,989,880,448,885,714,894,973,821,166,802,815,90,797,241,377,283,164,164,263,674,992,867,582,789,757,173,715,165,812,254,0,402,877,566,625,859,227,282,467,142,467,495,734,159,304,775,429,240,970,456,7,299,468,926,854,778,593,533,318,842,898,284,10,340,325,472,366,893,140,251,907,779,468,939,653,128,242,7,963,897,570,338,752,371,72,831,520,914,180,444,249,6,408,949,510,639,114,179,975,967,671,690,563,121,715,503,259,939,670,938,29,534,325,674,15,222,202,271,827,777,268,162,208,986,163,321,235,917,662,134,402,749,644,105,541,587,797,926,77,34,108,695,346,758,601,653,6,27,300,772,528,299,500,694,72,213,431,987,465,288,227,394,582,778,573,117,314,737,350,12,854,800,979,242,406,993,94,333,526,439,922,277,517,770,954,829,908,929,289,832,91,684,675,826,942,882,954,478,598,495,42,486,601,188,350,368,308,496,514,271,935,855,273,457,860,643,900,822,439,541,107,978,214,826,788,193,838,607,489,519,412,834,726,85,111,537,91,93,219,966,812,36,507,186,201,1000,200,689,87,484,397,772,331,882,7,93,371,162,50,445,939,114,860,654,766,974,252,579,628,561,164,983,935,451,411,136,365,505,312,169,935,782,276,676,539,750,682,871,808,716,950,320,693,623,309,455,689,932,102,287,919,99,573,529,487,899,267,363,367,566,595,108,701,387,44,322,307,567,177,425,656,376,269,535,978,219,805,456,99,184", "501,221,566,921,187,596,223,716,623,949,478,161,301,183,781,39,176,133,83,843,862,601,118,737,816,730,714,20,575,227,205,241,198,724,586,544,692,180,328,158,973,64,792,739,814,537,857,618,580,968,782,464,531,744,461,266,237,213,387,505,29,863,653,196,104,948,380,2,851,843,936,518,627,53,634,821,875,718,660,774,713,645,539,544,753,207,311,447,413,763,947,84,22,433,324,866,246,521,543,858,301,210,584,118,770,244,115,346,94,923,144,32,869,745,30,243,908,59,187,297,811,537,417,796,890,735,158,19,681,14,171,848,344,962,443,982,23,725,821,567,71,245,507,332,721,67,772,846,505,42,14,567,890,311,162,690,704,961,722,575,855,470,763,186,529,795,194,702,794,338,910,88,76,150,431,83,363,824,463,913,110,17,57,775,304,486,110,847,136,996,946,618,154,186,763,881,89,683,834,170,835,721,793,590,403,152,887,617,979,697,605,774,716,337,561,311,291,580,718,921,471,277,41,792,328,599,767,257,653,437,36,611,546,100,720,354,56,449,120,666,930,948,94,28,387,70,646,444,868,763,317,979,509,565,905,122,87,972,362,233,411,719,361,428,509,331,646,796,481,483,931,566,224,107,491,934,491,323,60,112,241,82,550,107,158,190,510,230,205,331,819,904,967,718,391,975,431,971,945,73,871,620,853,982,905,257,156,966,499,372,40,717,275,641,436,577,512,151,680,68,196,710,664,849,309,285,578,136,829,148,274,493,519,643,847,737,843,704,276,158,491,972,109,604,507,129,610,55,617,26,135,886,879,729,850,88,324,832,66,27,997,922,333,701,47,450,203,924,642,130,71,832,853,119,165,644,330,191,692,856,376,546,271,839,616,253,618,613,281,711,330,627,53,963,910,101,29,850,592,734,231,823,50,426,257,292,951,348,86,511,620,442,110,932,375,520,220,85,147,915,296,137,893,271,535,590,595,640,90,292,36,348,454,357,701,316,837,998,118,127,862,380,288,89,591,368,183,605,864,765,483,570,303,129,206,51,124,869,650,899,880,193,562,747,506,42,72,918,189,567,44,602,95,523,430,71,671,337,635,318,897,83,270,58,839,173,951,381,690,190,648,148,277,818,173,943,255,969,754,454,818,27,570,978,383,36,94,286,591,433,527,565,340,635,195,656,163,897,228,393,719,888,918,952,956,87,649,172,981,716,67,508,848,353,207,436,750,464,688,469,682,98,970,894,496,546,201,314,381,328,542,884,144,893,987,344,553,193,233,963,472,63,681,10,299,73,245,709,236,987,105,853,798,139,709,3,71,479,528,724,354,632,37,423,340,830,605,901,818,374,661,422,99,784,962,997,516,289,744,209,219,502,674,492,72,950,803,152,997,359,91,262,801,781,189,147,937,451,453,700,360,550,377,111,138,88,560,159,295,634,112,419,494,938,634,309,862,619,989,112,740,487,957,866,754,973,78,887,538,6,574,881,206,973,783,865,701,105,874,722,819,668,435,548,165,53,436,588,473,863,896,469,570,336,391,853,391,282,242,505,271,625,185,468,528,221,609,535,371,32,384,535,837,37,382,386,6,372,967,192,402,0,318,890,402,164,565,344,813,410,527,848,498,423,47,915,363,494,433,381,536,920,337,48,764,50,690,511,230,455,460,339,685,491,454,503,747,88,534,241,115,202,930,175,394,822,547,13,69,549,8,215,187,14,963,77,568,338,925,34,193,330,619,461,598,618,675,430,675,774,242,481,406,290,170,333,69,275,944,286,256,780,972,542,237,946,722,844,642,37,975,243,130,149,524,447,464,824,258,992,206,988,250,724,575,562,242,597,842,91,526,12,124,417,552,394,553,887,367,501,248,429,102,261,828,266,824,927,681,692,704,564,851,626,388,748,464,683,582,244,562,772,558,561,871,648,552,67,198,907,742,990,411,347,112,426,753,163,583,703,154,19,694,508,700,424,705,338,167,98,995,705,86,705,619,711,297,679,516,82,551,65,273,670,64,967,896,446,626,792,53,223,498,327,917,526,316,15,385,634,486,298,787,759,474,530,879,433,658,295,435,292,77,181,418,870,49,871,900,92,805,871,938,309,726,406,107,366,474,844,985,73,552,339,211,2,157,704,74,765,471,492,607,428,230,980,24,751,13,181,713,439,282,942,243,481,936,561,211,133,96,523,872,460,51,374,703,992,436,856,523,737,122,55,440,780,623,544,678,498,246,760,280,302,817,841,401,312,438,212,661,561,285,272,876,717,529,370,372,104", "378,670,502,839,911,996,948,409,816,266,142,453,983,115,501,144,265,774,328,184,640,898,702,349,523,576,589,345,255,140,87,36,360,233,643,580,618,377,359,538,739,977,227,428,666,758,352,726,233,687,67,363,45,47,573,848,233,658,162,901,731,314,42,587,129,221,968,208,572,265,632,513,354,273,163,993,451,86,377,899,987,558,191,947,552,533,803,510,168,222,637,439,263,956,976,633,685,837,482,465,309,953,867,45,673,367,329,143,410,59,499,245,479,9,431,805,623,331,476,383,799,733,872,774,557,920,863,483,738,919,282,926,390,179,190,932,648,355,411,226,874,691,840,642,875,182,138,933,373,316,883,700,907,787,693,955,17,423,356,457,511,887,303,770,135,679,756,918,216,141,335,981,534,152,665,992,942,278,460,586,889,987,388,531,119,930,387,947,599,634,848,524,194,920,321,436,987,116,843,577,187,549,608,956,103,898,815,121,228,638,644,149,958,901,216,552,900,529,603,532,700,207,195,695,407,991,951,682,921,317,575,726,769,138,438,206,590,25,878,475,686,924,983,260,10,291,609,740,902,402,242,234,438,704,525,904,269,541,992,887,310,560,22,867,469,296,266,964,3,487,438,94,385,983,180,209,587,379,666,11,84,365,68,992,659,459,936,722,359,375,833,915,896,960,133,100,695,504,82,365,738,424,601,36,118,407,769,463,436,672,423,833,543,332,277,334,93,407,890,555,36,738,875,127,251,698,426,427,55,654,139,681,456,41,64,847,857,18,669,738,87,329,961,732,167,855,550,240,628,597,445,882,673,231,255,242,815,807,584,908,218,639,15,897,641,22,763,248,610,601,754,254,243,246,896,743,685,892,834,472,4,734,128,158,313,615,504,358,442,190,389,345,330,497,257,531,232,703,137,173,585,258,904,655,184,724,616,428,478,859,795,710,51,464,170,95,498,728,698,752,811,797,208,265,364,575,714,898,558,741,998,861,30,110,904,487,141,455,371,857,72,120,738,663,622,759,267,934,740,377,30,265,800,551,279,750,710,713,685,502,507,847,276,145,644,899,296,627,261,720,714,728,97,670,639,971,531,854,176,424,912,351,459,977,59,887,931,136,447,290,14,131,549,429,180,607,816,986,294,720,586,915,283,231,731,912,871,66,906,904,555,319,352,395,92,276,572,50,464,635,871,934,83,524,385,41,299,828,649,215,377,266,230,263,354,5,162,52,195,110,751,6,910,883,523,811,608,220,732,797,142,823,565,308,535,427,122,203,721,841,465,410,14,590,107,722,760,633,48,64,724,671,366,21,628,876,317,895,710,396,77,396,489,387,182,424,774,954,764,627,418,334,989,756,502,82,560,72,150,606,108,366,289,434,925,441,256,660,336,76,407,772,120,331,842,908,406,899,191,755,899,496,886,593,681,252,625,421,922,189,906,867,751,789,36,790,230,793,295,658,926,473,824,198,509,472,505,806,719,688,185,428,462,422,438,407,610,404,839,2,987,356,946,450,791,253,39,691,681,375,158,868,562,734,259,300,595,267,695,988,538,636,89,689,154,641,223,509,951,820,484,739,796,262,242,60,836,524,814,341,877,318,0,811,992,188,669,114,529,730,420,124,269,23,896,805,128,159,996,970,639,877,615,766,155,300,195,924,493,990,241,469,711,195,697,355,645,920,882,275,721,270,416,655,771,391,291,7,130,520,726,241,979,24,110,345,628,895,754,746,966,287,319,641,667,50,239,237,157,37,811,732,563,337,133,936,929,294,516,897,360,964,442,204,781,321,43,738,403,805,604,941,916,309,241,67,881,367,55,531,606,195,147,765,660,711,859,505,436,161,433,553,420,161,848,277,627,473,535,684,499,541,636,555,898,115,957,349,530,495,769,576,132,969,958,833,603,121,921,103,266,20,768,917,650,194,372,546,556,481,42,679,656,849,40,666,420,689,266,269,583,993,952,492,96,376,652,427,372,627,804,617,701,749,912,818,840,892,987,963,583,476,493,970,584,633,977,992,920,489,466,97,44,780,620,49,186,193,51,884,115,125,561,389,921,195,774,201,156,940,380,949,629,99,902,814,206,491,779,535,987,873,857,122,514,110,100,556,378,245,625,430,874,190,645,791,146,844,195,60,273,232,240,794,947,443,622,632,453,85,364,736,111,40,965,685,278,886,815,784,88,904,762,378,869,597,826,675,539,429,300,749,893,445,134,715,648,603,287,514,513,148,501,529,811,643,259,539,462,163,37,60,128,830,587,495,511,727,714,420", "192,295,796,113,918,4,859,362,200,468,983,545,294,514,35,135,545,347,592,611,25,808,4,200,122,45,785,199,901,64,432,293,909,307,476,395,880,300,798,986,963,642,337,113,174,747,560,994,390,876,504,29,606,894,420,606,936,974,494,102,252,383,422,719,117,998,232,217,703,240,145,820,85,87,923,106,479,993,215,334,760,317,963,290,701,460,836,76,560,23,524,766,116,814,883,135,651,723,231,633,833,199,691,847,983,825,113,861,503,82,850,750,185,134,455,407,167,34,966,925,256,845,499,917,472,153,929,718,956,184,617,909,981,398,153,155,82,928,740,760,819,547,952,986,906,112,667,910,69,242,79,853,196,803,559,410,620,67,137,195,180,177,536,548,367,70,262,943,298,69,765,692,440,382,290,925,687,331,989,613,786,354,32,820,955,131,716,565,2,791,286,18,691,887,997,498,453,157,887,89,159,835,878,985,243,826,501,337,572,973,991,974,400,135,540,819,995,854,867,188,742,25,101,77,289,89,276,633,115,326,87,452,301,543,329,935,89,423,577,11,59,158,488,638,741,160,218,943,411,663,282,691,144,105,757,743,347,557,180,614,477,536,645,650,238,253,666,900,254,472,336,136,941,755,841,255,90,794,412,554,976,671,902,113,740,570,185,690,794,727,767,3,799,128,774,361,191,370,67,197,242,716,709,313,319,748,144,39,386,3,74,543,916,202,722,967,862,217,410,992,810,425,829,17,410,278,526,886,858,480,906,788,295,265,384,786,5,70,250,228,563,470,832,426,28,583,688,256,678,9,469,238,817,276,971,906,679,741,569,819,562,489,868,633,41,471,539,120,631,295,545,49,333,776,194,563,461,560,368,401,942,645,941,834,838,286,534,112,627,510,818,55,295,653,797,101,405,740,939,876,666,770,336,898,23,177,658,59,157,155,302,517,386,922,85,17,283,629,440,282,193,334,59,904,887,791,237,464,795,759,562,1000,677,215,142,213,476,461,840,121,782,390,587,569,67,874,742,325,128,499,962,835,96,697,196,255,654,952,21,356,982,488,984,721,61,542,911,769,138,130,178,702,922,238,728,503,177,978,834,842,352,650,8,55,613,678,132,852,742,324,632,723,261,233,9,972,433,894,623,662,436,681,365,19,394,25,158,380,723,960,253,343,921,181,875,825,966,353,442,127,120,609,537,704,527,877,329,973,778,772,49,760,151,468,336,992,656,45,834,51,611,826,598,72,73,364,955,25,758,460,430,584,317,265,744,848,708,76,305,893,670,300,120,206,125,874,760,854,913,431,140,825,861,41,728,418,927,106,565,246,534,23,822,557,879,422,578,184,306,401,662,752,476,521,280,715,208,835,474,7,13,918,459,567,526,435,58,894,823,863,373,982,414,887,49,408,932,569,290,709,257,419,73,36,816,270,116,328,692,617,618,873,350,107,281,508,908,137,621,216,712,671,901,608,820,500,328,368,366,83,40,40,349,521,243,180,256,86,841,388,577,807,383,671,145,921,731,299,899,5,541,65,631,433,607,77,405,313,757,845,953,933,736,48,269,979,906,477,59,147,364,544,294,544,120,520,256,685,570,990,566,890,811,0,211,992,355,585,331,204,980,737,179,758,550,68,3,536,302,990,713,840,474,522,453,67,377,657,435,727,622,936,834,177,215,469,879,687,373,978,384,372,713,751,268,826,265,863,535,943,549,376,445,394,740,178,658,27,992,476,456,259,298,62,280,395,96,151,424,222,798,684,117,269,632,631,172,664,725,46,265,874,777,195,30,957,802,710,73,956,767,99,15,326,621,872,273,201,224,317,588,881,240,970,29,873,521,822,339,468,773,149,912,104,193,653,257,695,442,292,314,942,809,552,656,523,500,81,90,709,733,596,280,69,405,619,26,612,855,488,634,427,42,515,209,281,113,139,75,484,393,930,100,56,312,170,348,355,30,2,993,923,267,898,785,809,226,489,575,693,896,285,814,628,559,990,549,221,755,98,979,821,306,528,428,844,762,837,385,7,726,102,390,840,424,350,970,346,767,799,651,903,807,692,282,585,946,35,885,758,434,473,223,462,655,768,838,197,66,879,943,593,67,831,209,57,384,655,294,488,424,610,318,886,41,676,958,278,105,277,201,428,220,675,672,594,752,964,386,422,70,369,749,102,476,352,29,702,289,171,194,186,252,513,343,129,379,406,774,520,715,503,855,112,972,541,548,56,25,302,626,608,266,664,69,162,542,356,971,232,920,52,177,669,241,612,94,652,380,760", "28,353,11,129,541,697,463,543,793,392,25,345,118,844,240,150,909,762,952,707,181,121,457,79,876,981,270,777,991,691,981,724,631,885,978,777,400,132,733,920,365,616,373,418,704,652,490,271,833,495,598,601,659,267,779,640,516,92,958,998,87,713,260,241,991,214,869,721,498,414,669,956,701,485,666,497,111,127,309,666,814,604,862,437,522,691,857,109,190,243,239,404,301,228,353,69,883,240,463,239,863,620,468,85,27,171,356,843,36,472,660,361,586,483,771,527,83,394,877,722,391,923,811,525,196,587,431,470,978,165,833,119,198,234,894,702,145,397,959,68,877,351,575,978,636,346,207,529,601,223,469,683,750,765,436,231,497,598,919,175,223,980,914,247,624,627,53,155,855,144,337,46,22,739,952,756,100,806,302,512,428,474,38,428,682,608,717,226,978,193,639,961,112,396,569,789,579,459,874,250,336,6,114,2,613,557,719,365,885,646,870,287,289,68,208,464,368,673,164,852,806,357,810,421,746,887,387,309,219,959,267,144,22,826,794,301,397,504,245,657,243,772,272,617,580,720,448,293,604,772,648,645,23,970,217,218,503,17,850,144,802,13,623,208,196,942,83,852,322,209,538,539,943,785,561,930,932,856,926,950,591,496,107,22,706,24,922,429,719,619,265,30,272,253,94,957,142,155,921,766,570,263,855,286,388,712,288,976,150,379,931,102,251,986,812,663,125,30,890,346,630,905,545,393,154,247,723,864,570,209,273,637,689,38,580,928,360,650,417,309,753,751,911,145,318,785,577,777,720,836,966,891,715,695,996,344,779,399,567,355,59,791,64,529,265,340,802,971,628,796,359,370,334,187,425,97,633,316,324,655,836,449,916,968,946,872,105,494,494,608,586,426,305,336,621,835,654,571,481,682,680,325,732,707,254,518,645,523,959,296,79,302,235,647,989,221,914,167,494,306,592,113,436,637,62,295,549,677,248,32,745,58,71,458,821,181,13,225,608,61,277,27,478,934,552,242,350,761,791,451,771,983,803,246,58,424,259,391,462,302,176,843,968,525,463,263,595,579,859,295,299,515,894,617,841,854,371,392,423,893,237,392,475,473,358,214,76,921,768,326,261,65,655,743,156,652,351,332,969,994,672,601,307,500,449,820,566,871,328,83,682,319,764,815,991,538,738,246,415,421,305,99,981,508,281,169,991,629,980,837,290,619,320,78,860,14,127,433,657,140,96,444,582,430,524,164,108,713,260,67,127,393,521,367,633,319,697,443,960,678,295,809,696,400,905,936,760,951,241,513,39,120,914,855,270,8,764,432,283,334,115,612,988,169,476,236,727,595,688,78,247,30,319,472,802,757,790,436,447,735,979,464,377,865,519,228,706,394,927,534,809,135,76,628,498,7,652,745,115,577,237,773,306,253,595,779,661,813,208,738,242,902,880,881,652,33,58,827,59,288,90,534,797,580,265,499,9,361,835,182,388,60,66,599,869,923,361,754,761,445,424,95,607,359,955,977,526,204,941,172,958,929,271,21,253,592,230,852,206,745,664,604,588,244,53,796,544,235,637,43,862,654,819,737,814,642,781,62,997,256,625,402,992,211,0,422,838,711,8,602,118,305,63,307,794,712,651,23,919,131,653,353,338,170,671,69,684,380,607,675,92,927,535,186,117,340,498,207,160,953,563,643,2,799,896,134,566,337,732,383,768,250,318,992,907,881,639,804,360,392,420,348,771,264,439,943,425,186,348,914,402,715,593,543,585,317,308,915,684,217,478,510,655,186,901,795,201,695,570,995,86,513,138,652,39,780,167,355,694,880,81,700,203,593,350,79,588,137,972,779,202,390,686,942,482,462,768,950,518,106,199,341,536,144,159,536,634,728,937,597,255,324,74,999,808,461,328,318,553,837,629,335,825,282,633,536,31,622,930,478,896,411,411,267,298,999,429,129,540,875,491,975,574,499,664,918,910,410,828,59,924,484,58,420,49,826,754,160,229,768,588,829,871,311,742,379,104,777,841,176,240,498,229,380,725,204,790,57,325,296,929,614,747,983,741,730,342,957,800,411,419,400,943,855,946,756,716,359,37,244,488,168,631,920,902,53,198,12,282,764,757,712,413,40,853,832,301,80,569,129,203,851,630,926,474,43,268,798,361,441,454,632,532,584,47,591,125,717,493,252,214,558,458,671,971,709,593,315,347,847,755,679,476,423,156,621,399,903,605,283,671,713,174,844,638,216,392,503,500,215,590,228,372,38,981,966,345,931,352,771", "891,690,186,710,328,939,91,452,514,393,864,438,223,964,783,544,457,381,109,256,737,721,50,728,235,546,778,834,254,835,924,690,478,698,213,3,777,595,993,462,828,119,756,183,456,476,354,660,976,233,377,915,776,377,688,364,150,605,475,72,586,134,819,77,843,148,675,745,865,792,387,781,788,162,296,515,593,652,975,942,680,913,327,458,896,295,946,513,260,115,636,30,25,117,919,4,548,490,167,33,251,710,353,668,373,306,806,505,645,735,380,663,899,641,935,835,474,197,330,117,346,714,390,781,609,826,439,60,451,303,810,590,76,236,337,632,546,955,144,833,278,535,670,603,421,898,994,634,74,121,196,82,739,598,84,915,171,356,43,398,165,41,114,453,278,239,897,175,156,670,579,121,931,724,990,722,206,774,540,248,753,503,130,238,455,708,282,366,594,363,316,312,418,337,527,533,908,671,212,29,37,132,133,16,835,169,595,722,83,773,12,327,407,975,964,985,716,873,287,171,8,879,841,205,294,949,861,545,876,864,7,996,440,225,217,1,790,595,442,652,315,521,472,323,609,895,750,657,237,139,625,201,911,379,554,661,250,711,972,926,25,788,413,874,753,9,566,945,742,847,813,398,633,447,465,927,115,723,30,729,192,891,58,636,80,263,260,983,366,923,777,582,545,12,954,373,960,194,45,198,586,589,319,247,42,481,415,817,107,144,432,442,817,692,433,994,23,913,685,666,973,29,634,285,936,330,498,635,889,856,885,520,739,63,634,492,830,128,761,867,948,153,256,400,533,312,316,939,166,54,855,305,594,293,936,94,136,616,581,142,873,419,271,4,737,529,21,106,443,158,624,228,556,493,34,255,475,700,674,686,724,878,352,851,101,161,966,595,680,54,153,585,35,738,549,39,338,896,139,28,231,526,9,935,705,786,582,82,855,350,54,894,330,457,83,284,740,344,616,447,53,718,971,96,251,421,466,845,587,345,416,576,284,416,733,519,89,138,426,949,472,85,95,49,539,922,177,989,877,246,403,360,506,752,322,713,969,632,256,224,27,701,393,770,486,168,375,616,927,484,140,827,182,436,831,737,961,556,330,614,205,396,590,705,577,750,286,816,839,163,244,94,503,318,961,515,642,677,621,114,359,58,841,214,387,661,965,806,646,362,314,460,296,484,793,556,232,639,562,882,965,207,850,186,140,601,307,407,460,719,453,675,617,35,838,435,823,797,230,525,730,332,128,415,694,825,418,460,485,496,670,640,569,756,538,945,496,813,191,570,76,97,481,781,897,478,38,776,985,468,385,879,277,585,318,104,649,118,223,814,633,18,885,101,969,82,117,671,338,527,72,417,964,455,797,659,450,806,53,302,886,600,155,963,380,697,461,781,547,68,661,203,792,2,460,756,311,604,468,973,676,582,90,198,645,494,202,291,62,225,919,460,629,983,829,45,757,265,240,674,245,674,413,984,245,905,731,35,46,478,6,425,636,985,959,118,148,172,168,916,286,454,289,553,735,887,458,585,908,884,83,677,768,310,449,815,71,328,530,649,937,104,803,642,72,469,688,649,858,104,488,224,60,246,730,806,398,744,285,932,859,164,188,992,422,0,388,729,148,156,429,965,156,404,581,43,365,934,25,172,507,901,184,698,377,421,490,819,694,414,606,269,157,276,809,779,102,690,983,651,72,453,886,582,873,569,765,303,107,315,892,906,616,982,737,963,211,466,60,810,246,226,308,303,540,606,672,602,188,499,666,476,490,575,981,97,782,822,174,453,198,172,892,671,460,250,827,989,92,107,288,862,590,537,723,462,186,6,668,908,224,276,997,67,5,121,723,905,465,261,669,977,895,88,292,556,43,781,396,124,361,542,756,107,805,102,682,687,778,950,779,753,541,422,371,237,864,346,321,359,6,924,995,762,571,691,84,383,50,167,573,986,492,153,130,789,952,988,58,875,986,90,376,266,373,892,440,581,925,574,70,794,541,124,40,170,285,191,61,283,980,532,812,155,900,104,448,801,589,809,505,519,941,844,590,332,159,142,688,759,910,737,65,925,669,393,792,576,449,947,646,256,601,621,514,924,609,106,754,412,710,929,833,792,930,99,671,425,676,146,55,628,373,569,166,94,401,26,573,320,640,548,433,198,23,162,342,958,925,176,151,159,463,154,403,907,941,251,51,310,897,759,250,897,8,650,349,489,363,69,342,256,534,14,620,124,46,676,576,809,195,238,154,358,667,271,888,758,721,653,268,691,729,691,484,183,488,997,860,242", "694,167,127,623,517,246,700,994,228,567,757,308,174,230,638,40,762,350,269,148,397,539,529,823,68,332,212,284,247,478,137,77,646,85,744,245,885,497,427,201,81,449,7,341,198,768,584,444,521,21,837,674,742,729,193,135,786,740,651,547,462,720,583,66,834,451,108,830,308,292,330,857,612,795,620,211,953,205,686,964,919,226,683,16,806,603,363,9,134,669,408,23,379,656,935,600,446,984,710,369,58,430,924,686,761,698,409,867,673,451,773,367,365,223,382,669,658,789,442,793,493,228,674,110,974,523,953,936,697,521,215,203,513,10,530,521,301,865,319,728,887,770,515,661,589,667,204,431,912,860,98,608,491,388,97,394,956,711,938,203,219,444,434,441,55,658,640,266,351,45,592,529,446,249,950,369,311,659,920,554,94,588,758,477,971,422,835,934,46,576,128,463,939,541,535,104,715,479,880,677,783,866,931,719,574,111,553,271,642,184,310,860,236,44,325,280,475,228,221,658,389,347,541,309,323,198,780,273,481,471,389,777,250,348,572,784,955,453,385,613,570,914,456,928,312,516,185,672,520,854,323,423,66,828,41,903,652,182,243,423,984,938,217,672,450,773,979,141,600,795,770,135,706,301,208,597,971,514,557,272,39,28,211,500,876,62,733,688,501,438,991,864,658,585,938,498,865,900,845,582,880,460,665,31,359,87,670,435,510,357,451,861,479,59,894,95,381,717,571,87,505,801,830,715,541,894,488,85,554,837,251,906,268,72,479,377,260,174,695,318,228,792,473,230,962,56,20,185,217,251,806,162,904,1000,83,567,358,231,316,698,607,498,266,515,324,554,692,419,257,24,854,794,670,119,292,484,312,229,63,858,190,922,396,413,403,275,617,11,325,886,20,712,803,795,953,826,892,825,724,579,560,370,203,89,265,896,153,313,175,54,227,980,906,424,697,385,422,543,641,663,377,509,28,866,16,678,734,528,403,45,150,321,224,221,148,719,490,745,475,835,52,717,621,707,726,112,787,741,46,956,515,115,21,625,352,485,962,835,725,141,857,178,810,168,4,370,891,743,104,737,93,958,872,787,679,596,140,239,117,193,816,319,533,368,611,858,453,98,464,785,908,894,536,809,876,532,397,596,113,145,268,363,523,495,773,489,921,459,399,721,792,419,615,908,588,986,821,964,62,337,874,866,211,654,13,28,235,661,630,95,415,91,976,664,377,714,192,759,889,667,137,306,727,86,108,509,373,246,458,238,232,166,205,144,85,253,532,280,488,692,243,373,631,550,423,342,444,283,787,95,550,450,231,362,742,19,479,25,428,177,754,124,26,747,725,83,722,800,971,317,417,441,433,333,307,811,527,674,525,454,387,979,414,133,79,194,10,282,55,277,103,971,185,341,764,998,706,724,322,766,497,571,860,196,254,531,108,625,9,541,676,8,916,466,46,517,244,236,964,679,705,103,382,607,14,691,700,3,323,695,217,615,734,610,17,593,601,693,149,615,452,425,910,944,479,265,760,452,43,698,65,83,291,500,929,468,935,498,344,538,608,231,190,847,749,396,582,366,198,836,577,787,253,672,388,195,472,514,342,598,227,565,669,355,838,388,0,26,619,847,889,425,734,677,892,188,230,32,471,941,499,102,260,871,475,639,658,654,98,475,175,63,403,806,227,234,296,76,655,129,170,167,428,551,54,789,613,180,403,41,345,530,714,219,195,665,179,632,423,333,921,406,203,315,752,536,401,632,17,973,371,975,591,101,398,427,652,91,666,353,916,602,536,193,385,174,984,863,154,257,635,524,962,57,443,178,532,919,104,47,921,924,584,522,924,537,488,801,224,877,557,123,149,564,612,348,414,650,37,319,369,477,868,105,257,775,249,682,99,803,881,302,426,29,164,133,974,336,195,669,7,224,164,216,357,929,7,836,221,556,478,108,566,212,728,780,629,67,36,472,580,53,546,835,4,217,832,656,518,16,184,84,379,906,518,997,256,681,264,637,33,978,625,875,748,425,44,546,850,996,248,673,771,628,481,35,353,808,286,246,665,687,713,750,667,798,209,982,930,40,145,966,132,251,351,659,86,634,374,920,127,840,830,886,227,908,583,231,574,741,751,472,749,687,723,140,212,408,418,62,581,150,626,286,877,630,131,881,128,716,650,855,927,779,415,774,522,906,586,948,514,971,893,561,472,387,814,244,257,255,684,690,293,736,244,109,165,301,543,923,306,540,400,797,707,953,711,901,601,37,779,314,884,493,410,782,160,450,671,791", "37,99,426,992,743,41,195,374,687,383,810,381,333,914,103,411,448,170,5,906,970,685,374,582,23,110,606,863,577,117,14,438,604,577,342,723,59,955,7,496,484,655,605,123,162,612,848,826,411,552,357,485,347,40,658,276,235,702,502,504,730,110,790,582,310,64,239,123,729,426,955,300,376,530,20,446,551,276,769,921,897,127,244,360,677,534,521,20,517,782,205,774,594,114,668,59,555,787,394,274,522,755,697,692,281,194,543,179,280,166,756,73,753,482,406,729,251,953,974,657,55,111,497,172,582,404,375,414,617,170,481,6,451,245,310,809,496,136,256,989,922,604,985,192,502,695,570,1000,286,497,647,101,610,208,869,227,950,653,768,31,782,201,597,532,712,944,944,269,118,932,250,620,916,177,818,769,357,730,34,789,258,298,475,819,239,585,329,146,949,564,352,184,554,727,274,291,790,736,718,209,761,337,261,984,274,819,660,175,104,772,312,65,916,744,720,965,434,997,873,661,222,149,932,783,713,147,536,214,706,81,707,87,397,710,824,89,94,42,545,207,442,187,359,171,614,985,910,193,282,730,301,416,124,897,966,770,252,525,380,189,171,421,646,860,104,529,708,499,688,63,772,22,388,382,268,929,892,125,438,689,831,477,844,115,385,236,426,294,797,300,376,517,454,378,172,708,945,59,151,813,98,298,882,269,678,452,295,76,456,953,263,852,239,259,923,657,937,873,231,754,483,194,490,638,228,749,597,672,888,310,657,234,365,986,681,130,457,410,205,423,556,140,456,940,944,480,193,294,286,694,914,932,171,609,43,318,710,107,969,876,821,14,365,621,906,112,89,980,481,767,796,773,936,434,106,322,47,600,321,605,21,643,382,955,474,488,483,158,597,393,369,760,865,455,269,708,951,261,925,697,807,65,31,527,317,486,358,288,422,881,580,267,920,868,197,696,585,762,735,749,762,748,983,8,188,42,68,573,757,103,41,879,724,647,764,848,558,484,366,771,543,579,400,555,103,938,485,379,599,130,861,698,887,537,786,621,281,734,642,703,117,234,383,55,204,923,140,72,126,497,216,466,818,25,145,408,850,947,383,688,463,386,379,122,585,812,361,802,296,709,179,803,529,512,501,818,37,265,940,814,925,20,556,716,87,909,616,4,180,738,199,606,867,51,819,403,303,60,892,683,153,577,103,564,491,536,900,910,390,213,410,592,610,623,768,36,334,853,908,405,744,786,914,769,858,1000,554,393,235,912,864,31,516,364,277,873,421,933,837,753,512,458,259,471,160,694,401,566,367,534,927,973,840,652,463,976,263,80,21,41,420,190,113,89,666,198,595,709,938,629,682,273,639,493,693,113,370,479,439,75,563,245,555,280,360,276,16,610,152,239,766,889,412,481,535,688,61,406,528,975,486,994,300,291,67,822,68,838,483,598,337,878,213,627,414,515,713,137,507,888,931,601,263,281,39,743,387,608,775,700,971,135,3,495,65,50,121,86,60,440,370,93,555,354,376,623,324,821,398,571,139,768,601,784,350,751,193,110,317,458,230,493,898,991,68,475,612,824,218,524,550,2,516,477,508,973,781,129,859,429,282,344,114,585,711,729,26,0,373,430,665,277,591,470,740,530,946,255,98,297,776,733,701,569,597,379,823,562,717,37,778,100,15,830,654,605,902,49,270,244,637,878,147,620,785,335,291,11,886,616,656,799,845,534,3,431,458,189,777,224,400,555,661,290,204,625,382,1000,324,427,337,826,712,747,565,360,542,878,539,66,293,564,701,337,818,776,624,927,218,90,926,429,558,390,607,511,704,299,4,240,852,123,874,599,593,635,262,58,367,310,679,225,131,700,589,742,474,305,112,181,556,561,797,510,423,205,507,204,895,616,357,555,67,305,171,246,350,323,484,521,928,203,168,627,223,161,147,317,282,683,623,856,40,292,297,901,566,689,195,543,505,859,590,170,185,267,46,978,859,243,771,998,461,310,789,862,168,321,291,819,434,33,729,906,259,838,520,307,943,5,808,962,387,882,527,759,886,691,13,639,92,771,628,977,941,650,196,643,794,428,617,814,974,409,401,410,881,830,638,322,10,464,407,161,443,870,843,607,897,183,407,714,536,68,44,746,401,421,755,939,971,658,693,987,517,349,690,497,102,755,766,919,425,933,523,325,330,402,189,538,492,916,694,48,755,882,635,952,411,662,70,266,260,54,148,501,51,724,698,693,937,514,871,941,461,119,659,33,740,933,845,863,445,909,55,555,454,371,787,729", "788,370,656,97,975,657,364,961,745,978,295,80,213,592,343,766,146,126,767,882,523,380,169,666,784,471,495,420,97,943,33,283,826,40,435,911,589,758,97,638,888,490,311,232,196,259,749,970,667,429,542,409,714,482,873,161,225,686,537,309,475,90,756,30,235,186,456,181,966,26,679,100,393,416,444,847,792,654,371,216,858,508,232,539,760,118,929,678,453,192,27,947,427,514,362,212,160,606,937,235,616,554,877,272,708,211,399,351,771,246,836,314,612,394,524,39,474,671,514,364,364,103,952,753,748,802,856,543,898,617,369,213,309,416,348,292,549,305,562,677,434,103,238,342,165,484,419,29,52,398,81,392,469,468,129,230,504,721,787,809,813,978,341,28,192,673,73,125,683,455,604,759,649,232,338,363,679,176,593,152,417,648,587,999,898,761,770,673,328,592,991,14,489,8,721,343,559,636,193,425,954,823,386,8,29,898,531,312,568,438,622,908,511,70,859,267,909,451,613,96,730,61,972,6,88,683,83,75,222,870,507,28,418,993,133,325,707,103,800,629,680,942,308,734,530,945,615,137,389,948,84,742,118,538,465,431,201,43,287,317,324,517,786,543,504,135,781,289,442,867,537,580,569,287,229,397,784,370,475,459,232,840,604,866,370,669,314,375,766,381,561,326,999,319,90,371,925,919,97,594,405,800,787,795,823,304,21,617,923,859,595,140,68,790,150,162,784,393,776,980,803,146,344,285,968,55,167,241,358,464,470,235,93,519,596,798,4,771,153,14,658,942,84,907,150,192,73,33,775,896,644,182,208,408,825,459,822,787,199,257,422,854,94,459,720,522,33,96,247,80,895,302,728,176,263,870,529,646,10,328,776,682,599,401,863,890,144,813,637,158,421,198,770,268,578,584,524,663,231,466,141,543,192,303,61,542,929,6,280,4,794,261,8,707,379,817,106,884,711,586,758,654,716,696,296,809,626,57,6,732,544,725,796,158,534,786,468,814,264,659,833,705,70,652,3,286,332,651,376,966,52,648,502,291,239,306,946,849,736,841,398,435,686,132,89,970,250,869,13,85,283,910,63,440,33,790,23,625,847,343,635,726,249,90,644,945,364,263,86,966,179,591,281,814,493,653,649,360,220,707,842,860,249,541,342,755,517,190,482,536,76,766,664,851,935,925,856,872,628,477,368,242,488,332,447,706,454,525,452,295,659,116,34,54,117,836,285,486,719,569,203,686,705,878,818,696,86,673,302,826,772,681,991,477,729,982,777,818,903,712,485,804,21,679,955,454,676,654,926,158,10,474,15,834,791,329,251,705,682,128,661,353,444,770,192,860,243,179,855,72,860,665,207,653,843,173,882,531,112,453,81,599,882,669,689,898,8,122,154,618,552,823,533,206,849,981,690,616,407,654,362,907,150,279,102,183,940,218,969,388,708,541,744,174,800,748,799,390,910,199,105,614,768,338,459,640,160,186,892,30,548,519,107,52,773,963,443,689,510,437,928,996,290,69,119,592,199,760,516,622,156,35,746,618,95,82,856,482,292,230,679,442,94,243,532,595,803,872,920,844,677,711,29,431,34,146,988,113,378,51,467,813,529,331,8,148,619,373,0,875,697,996,730,257,549,609,814,636,821,722,293,469,139,281,21,117,312,286,708,321,163,517,736,824,208,18,324,299,202,12,749,272,32,615,928,12,781,573,995,12,890,751,978,834,457,716,468,444,851,882,400,260,929,992,766,565,858,967,965,592,614,410,857,551,72,199,351,814,414,418,476,820,468,456,116,679,192,617,817,461,36,681,258,828,661,115,472,505,152,777,516,288,968,526,396,942,221,714,991,691,293,430,888,589,876,245,568,417,44,326,581,825,596,785,290,600,61,777,450,424,678,11,835,888,730,493,457,428,659,750,62,802,858,649,157,561,319,444,254,96,362,864,553,797,906,757,365,789,854,400,946,630,228,847,582,753,438,987,717,932,422,227,633,659,188,338,587,810,626,469,147,825,579,122,584,563,175,611,394,424,146,728,956,407,207,946,905,499,958,482,125,690,276,648,408,823,217,94,76,268,893,214,938,29,208,739,778,829,121,692,813,138,720,919,707,766,892,957,657,542,384,284,356,663,249,556,318,99,269,695,962,618,677,437,190,479,900,468,974,579,873,565,212,747,952,448,563,22,62,870,265,788,572,184,801,201,12,611,737,359,283,858,656,445,519,498,147,345,399,356,811,930,207,796,635,945,69,419,623,523,946,623,10,672,918,867,104,496,228,658", "495,833,576,807,485,801,942,932,575,81,91,395,338,671,632,20,785,647,37,459,155,533,710,464,900,998,886,531,563,286,623,353,747,543,596,935,624,991,252,306,322,619,622,449,187,861,292,746,618,254,110,185,186,391,845,477,647,432,814,67,484,594,884,669,66,620,650,36,790,780,153,150,384,483,247,39,602,706,613,466,320,119,532,956,743,341,587,476,495,317,383,945,178,528,326,780,102,25,630,58,673,530,990,224,413,991,670,718,246,628,647,716,731,501,184,253,224,901,819,455,991,843,951,533,155,32,790,509,495,175,104,624,565,141,193,684,476,447,623,334,797,523,887,191,641,314,410,941,160,809,762,351,100,352,213,844,833,643,343,346,895,722,791,788,63,881,758,144,458,124,942,746,913,445,315,817,130,421,60,878,92,747,74,147,276,393,672,695,763,890,681,568,851,925,979,981,280,940,144,545,967,929,946,733,342,130,577,848,890,316,303,769,647,857,968,947,248,695,14,505,799,420,937,847,734,947,17,132,711,184,545,558,93,639,489,647,810,293,194,389,826,43,104,3,909,698,706,130,53,535,939,388,436,595,598,424,421,438,202,186,597,966,165,932,345,587,665,180,438,440,166,173,2,786,102,857,484,162,247,534,966,19,247,203,635,841,894,57,866,470,580,150,455,861,5,965,852,10,829,662,406,603,301,88,505,335,918,469,51,625,323,282,823,858,834,621,321,939,752,978,576,33,501,306,594,191,1000,754,727,511,989,323,460,30,716,423,327,903,710,744,570,507,19,125,536,893,962,781,378,447,27,604,924,948,10,703,540,508,658,575,961,203,467,598,284,166,955,891,229,369,681,123,49,447,768,128,646,888,896,635,409,660,459,412,714,358,492,889,46,617,60,401,415,401,158,268,502,196,782,338,338,411,815,955,819,736,407,570,162,613,513,383,695,48,524,447,50,521,114,637,208,384,268,883,679,472,538,411,481,213,260,45,726,771,152,688,182,521,290,561,247,582,667,739,931,551,437,638,787,494,441,171,793,154,173,613,975,143,912,230,345,597,473,389,417,357,941,173,701,647,387,518,527,92,457,653,450,628,662,494,48,150,152,652,798,726,994,671,374,757,548,562,873,39,143,439,727,611,34,831,569,979,539,814,615,108,478,691,991,844,795,524,802,319,410,389,678,77,747,978,801,444,404,640,474,338,182,891,50,435,691,939,170,940,246,684,982,580,414,889,307,960,678,379,820,36,954,109,881,180,906,540,45,127,313,708,888,637,434,80,852,794,372,638,126,593,936,257,617,382,428,753,618,846,568,116,333,16,417,20,671,663,378,563,867,737,451,777,121,164,12,381,199,344,394,936,160,367,820,330,850,845,90,64,512,470,804,960,935,707,388,670,165,504,60,874,820,732,793,457,744,185,217,111,82,427,119,179,167,146,175,928,809,187,737,917,833,785,292,640,307,520,229,791,914,761,252,920,269,188,606,286,17,592,602,897,709,714,705,816,473,427,585,449,687,365,41,174,302,174,160,401,323,714,9,120,910,949,853,406,914,791,96,512,478,808,517,808,22,401,682,94,454,946,49,902,849,295,441,847,142,410,730,204,602,156,847,430,875,0,29,304,907,968,714,895,504,642,320,163,522,283,767,728,783,34,966,437,398,760,774,26,474,257,832,536,845,277,293,71,210,333,898,968,681,982,237,613,37,728,17,49,305,924,705,986,132,458,116,456,348,491,127,610,76,867,182,321,292,664,27,490,868,191,640,915,879,503,796,150,449,54,976,774,287,345,347,427,968,252,132,682,464,66,740,34,880,672,555,506,520,21,217,733,670,441,180,643,300,990,91,893,635,248,892,999,548,221,162,381,776,527,913,478,81,514,190,102,556,353,264,797,496,121,173,92,615,462,436,432,985,686,150,627,717,88,889,361,968,991,976,604,560,581,104,552,37,455,193,931,63,739,371,940,273,438,537,985,992,435,942,771,250,126,598,812,857,400,978,12,345,330,183,500,589,481,902,303,784,523,651,443,955,66,303,167,808,980,391,763,670,26,79,665,451,809,448,490,711,63,886,949,804,356,109,302,386,655,653,954,704,426,179,401,508,860,203,840,27,806,425,234,631,348,18,497,414,831,423,741,772,987,49,433,572,207,336,12,832,450,10,295,620,85,366,575,115,37,838,751,879,824,328,978,412,108,45,669,720,437,308,766,21,950,310,362,261,280,418,161,421,110,662,747,440,343,697,157,553,25,27,345,9,342,287,687,328,180,766,984", "961,642,398,906,967,12,891,299,547,927,113,927,419,196,901,687,768,114,839,186,562,285,888,97,479,623,500,163,76,600,844,746,932,594,643,540,626,164,706,806,359,396,649,508,311,398,442,584,237,473,309,721,160,529,730,700,684,581,202,157,208,276,464,853,597,441,678,186,336,426,734,132,405,811,521,473,420,712,697,688,591,98,956,348,327,822,741,863,195,96,252,598,579,573,310,1,193,912,754,676,53,478,821,912,457,840,404,671,835,26,922,135,753,382,733,474,577,60,503,120,680,529,78,240,710,685,432,898,584,500,59,690,246,579,627,482,185,443,595,503,929,25,731,49,211,9,209,368,272,2,455,862,520,122,128,360,687,739,755,859,159,173,510,505,519,218,481,656,175,678,55,57,458,590,546,807,310,956,960,933,529,546,258,967,947,286,130,84,19,201,28,340,300,353,423,309,31,176,432,854,554,967,465,559,38,170,383,82,800,935,18,293,165,774,118,457,972,1000,443,515,470,273,823,968,884,191,893,57,497,742,684,961,209,833,946,613,836,565,997,656,959,907,449,950,420,593,109,267,143,149,471,277,949,35,286,247,214,134,417,336,988,889,272,12,28,117,879,723,968,793,730,470,868,510,567,515,206,837,24,468,710,635,387,464,114,576,285,457,860,838,128,902,686,947,657,963,500,997,695,696,651,896,666,158,918,938,551,775,177,163,869,878,776,115,482,506,477,492,64,162,354,968,623,321,845,774,889,312,703,473,478,415,381,838,417,945,188,684,885,599,753,808,767,212,945,513,265,735,386,656,689,773,838,104,111,631,861,188,406,264,3,555,664,475,86,742,18,129,576,883,8,559,959,318,792,873,57,707,90,322,24,768,380,173,14,739,787,325,273,48,454,513,333,698,36,371,249,200,556,263,799,763,71,994,925,57,318,532,551,6,878,912,478,967,502,895,590,515,417,642,329,792,103,639,100,559,441,861,951,929,761,648,97,180,33,434,55,346,435,824,772,249,770,848,781,750,599,945,357,759,936,838,88,896,826,715,872,366,531,629,588,531,51,747,264,355,307,194,466,910,665,262,800,431,50,262,835,606,461,185,261,403,870,684,791,164,302,396,568,171,589,251,138,316,393,489,255,474,387,443,643,506,862,703,112,78,161,375,300,941,939,625,172,648,895,157,267,563,287,344,155,171,14,354,743,702,551,292,581,973,65,778,561,284,104,702,350,395,489,622,649,440,976,423,81,889,747,940,296,895,143,618,955,713,959,215,576,606,477,61,117,302,887,41,890,208,285,775,257,291,554,253,567,286,189,522,508,618,194,236,306,233,456,797,35,236,709,943,980,598,920,316,630,780,556,987,356,574,121,669,317,567,225,113,608,500,743,826,551,656,970,507,859,658,94,671,657,74,939,180,828,294,199,729,122,21,117,408,782,819,644,524,227,682,211,936,949,976,277,998,619,862,122,877,377,263,710,987,525,61,58,959,996,47,953,794,296,721,787,519,648,183,725,888,582,772,860,538,190,130,631,378,424,419,926,927,731,276,221,438,341,211,683,128,438,202,251,590,757,724,41,111,900,106,173,327,908,137,410,44,467,527,420,980,118,429,889,665,697,29,0,401,315,879,334,84,368,310,1000,391,458,472,276,295,807,465,923,814,344,818,337,796,298,803,156,896,245,769,739,769,586,589,40,48,746,705,215,46,912,698,499,329,599,587,957,388,730,387,532,354,614,536,407,585,329,789,920,323,523,959,201,660,396,417,374,965,424,133,939,811,198,53,408,452,88,143,696,421,856,290,921,165,629,698,447,959,216,7,873,450,130,528,876,666,943,732,164,592,397,349,338,151,462,437,270,978,620,469,755,724,725,824,499,765,884,321,385,399,520,831,774,917,674,422,202,157,852,231,369,220,231,182,887,837,598,429,337,345,565,787,341,650,395,212,918,679,574,495,927,405,765,865,517,28,8,509,900,613,902,935,142,993,497,332,24,40,68,309,813,424,757,713,817,124,240,535,699,34,228,582,127,708,451,911,792,312,2,478,943,93,262,176,545,677,757,366,315,503,50,490,2,713,993,418,745,639,161,923,132,957,235,174,696,281,553,81,475,23,657,219,270,56,166,627,180,417,282,152,775,620,300,604,860,833,804,760,78,955,972,599,138,161,713,812,405,608,196,31,781,435,951,667,757,798,93,239,259,863,242,739,850,22,116,424,928,771,674,837,977,488,536,488,749,14,999,454,30,172,365,560,279,781,427,112,156,170,592,664,350,539", "770,437,723,592,608,28,411,864,772,817,812,41,732,794,548,867,533,986,482,408,814,947,763,982,592,187,63,985,854,458,471,70,156,779,789,219,621,649,129,638,331,737,863,859,984,548,852,443,796,927,186,630,646,918,834,727,296,549,499,964,91,421,687,382,300,29,694,922,653,123,704,503,318,592,557,981,859,823,817,889,181,358,250,780,150,57,770,574,483,828,431,8,739,226,786,84,43,133,764,375,891,980,465,120,408,326,855,761,230,52,405,431,370,183,995,910,525,874,70,344,700,986,746,939,69,515,889,70,258,93,924,547,447,778,971,472,283,826,314,906,932,299,875,227,705,994,80,896,364,723,857,628,405,600,526,899,331,185,147,419,557,292,382,732,471,459,368,593,281,712,905,199,735,951,408,850,32,857,55,2,89,553,870,171,447,694,529,354,933,703,660,728,97,552,249,659,206,897,896,394,601,685,287,937,996,516,227,192,815,403,433,515,186,840,88,380,699,656,316,650,420,22,128,160,186,789,118,351,550,413,14,765,627,231,192,119,657,644,128,769,137,147,738,827,192,254,831,579,570,399,797,13,923,320,841,937,633,229,345,519,194,825,210,219,83,585,635,104,349,219,4,931,636,304,105,918,562,405,668,261,358,584,751,40,414,172,537,38,178,251,399,294,191,75,676,305,138,856,824,132,581,925,309,912,712,413,42,584,731,81,35,266,980,719,218,582,394,575,973,938,581,94,213,366,306,866,297,66,350,639,867,641,375,979,132,528,211,486,716,220,435,164,689,196,840,992,609,894,26,861,725,65,83,642,454,382,998,601,102,628,922,440,327,219,801,227,749,968,761,634,35,569,585,13,880,928,371,366,128,70,9,266,317,791,428,367,266,615,673,822,353,543,586,231,666,552,60,254,469,862,112,613,465,112,207,474,336,137,489,463,809,446,746,474,582,107,567,516,845,577,11,465,955,74,481,467,306,206,748,323,976,39,242,765,104,801,527,105,457,687,599,851,175,268,342,270,43,570,962,884,389,983,6,580,453,346,842,568,14,913,99,553,635,201,659,885,156,921,473,997,338,295,894,418,765,79,987,260,121,782,274,544,635,804,725,288,16,547,946,197,71,202,855,655,503,300,513,509,280,475,401,616,943,987,592,821,401,552,359,630,411,571,149,933,133,136,106,831,529,300,366,152,309,246,827,150,50,612,483,862,400,374,36,199,35,455,737,567,670,896,513,89,618,376,804,167,157,76,625,261,975,843,917,417,300,826,398,499,7,59,993,489,855,586,885,399,444,49,642,334,457,128,132,230,416,264,433,946,385,704,362,788,155,128,558,256,872,112,394,49,976,846,121,675,656,227,1000,191,815,896,666,775,622,359,300,122,198,849,290,859,981,328,678,663,265,140,323,412,730,962,484,664,641,987,952,39,72,239,168,82,434,20,997,191,92,920,597,584,751,419,136,12,613,696,778,633,989,231,51,850,548,39,64,947,616,836,834,152,600,470,716,103,279,262,861,427,284,203,16,98,393,743,93,612,329,744,490,724,744,826,440,484,618,863,412,546,884,61,180,983,572,415,885,288,820,719,154,211,212,587,495,848,124,737,305,965,425,277,996,304,401,0,411,604,907,951,888,558,283,686,18,164,108,107,433,82,896,332,585,40,586,342,953,236,162,199,876,690,327,737,270,874,429,93,778,325,523,199,868,91,496,729,513,678,558,175,406,808,576,931,240,817,899,658,587,750,941,978,321,312,748,20,804,529,96,653,951,726,90,832,895,499,742,922,24,63,681,172,91,550,528,161,680,497,345,581,557,500,117,492,595,535,379,591,201,861,819,841,986,439,819,484,677,302,981,128,174,319,219,986,921,954,74,891,177,490,714,3,235,180,341,419,656,551,211,629,857,270,231,942,748,375,312,934,160,102,715,65,659,212,437,685,400,291,180,34,145,676,365,240,149,252,540,650,110,991,185,499,218,356,897,743,614,828,291,277,203,693,769,545,287,154,519,777,506,160,721,244,9,906,783,685,666,655,951,338,560,120,158,783,10,123,952,397,942,326,246,45,418,575,774,266,264,338,988,33,30,427,190,417,304,23,869,636,708,320,434,380,764,566,81,657,679,542,28,392,269,590,447,404,385,842,754,573,254,832,217,122,582,372,776,826,441,684,882,305,152,461,567,41,763,259,798,379,687,71,692,680,793,640,914,220,586,210,785,424,56,376,284,531,384,441,572,520,953,64,425,798,211,22,470,998,171,264,848,119,149,105,613,111", "736,746,266,985,24,206,202,24,980,162,506,683,897,297,874,920,954,774,353,342,736,521,527,665,690,487,224,197,554,491,271,485,728,369,82,956,517,354,753,950,544,585,789,255,778,157,85,120,521,853,45,438,159,807,224,9,913,848,299,822,552,908,505,962,82,778,151,48,46,623,319,81,306,466,941,625,435,154,324,6,812,2,278,229,746,217,568,829,496,258,37,477,972,195,82,300,222,690,58,798,14,970,595,984,43,655,444,501,839,494,159,658,849,26,706,119,148,153,973,907,418,13,501,753,956,727,51,284,664,67,823,455,844,860,2,120,345,488,944,129,402,621,435,518,48,616,252,633,813,322,203,133,719,602,650,100,237,465,588,818,29,797,828,531,701,615,597,474,187,380,920,831,942,514,104,866,356,460,124,585,541,593,2,898,726,705,507,751,177,941,873,753,497,880,662,20,462,727,377,236,794,369,375,380,684,793,723,559,202,292,818,919,727,882,26,405,994,819,539,794,403,31,474,414,306,57,280,829,265,579,779,760,329,734,30,752,640,593,622,548,405,319,283,355,538,471,979,181,855,226,346,716,520,791,545,123,121,740,678,837,140,783,404,284,194,719,893,41,423,720,75,136,654,976,221,111,746,865,542,991,12,915,936,330,780,671,167,239,412,150,379,257,296,488,850,941,163,389,62,182,393,585,908,592,572,819,235,851,466,637,876,82,445,242,517,202,787,982,513,417,269,81,112,221,288,128,381,48,964,416,446,433,68,651,871,386,246,58,725,386,812,429,282,627,375,937,634,531,655,266,531,932,276,433,717,297,714,975,134,539,368,375,712,299,721,633,540,368,419,380,895,819,946,302,522,74,501,321,433,492,223,531,774,189,391,673,557,37,551,18,589,418,169,147,519,803,69,411,6,54,183,716,547,940,468,286,988,523,818,56,692,725,206,579,806,350,876,92,513,618,661,711,658,97,207,200,879,960,363,519,617,367,639,654,853,235,229,710,304,49,816,178,595,585,96,10,271,256,911,200,510,534,189,769,72,13,513,660,635,105,838,44,779,566,11,632,963,704,839,927,145,514,873,753,65,137,67,44,166,148,204,518,551,571,244,109,567,359,869,371,921,659,573,810,275,674,759,792,769,322,587,958,289,465,843,48,384,498,142,906,291,474,731,714,899,962,584,980,980,778,385,250,37,317,617,537,665,278,282,729,686,20,130,449,535,948,727,833,112,844,649,410,65,258,71,318,751,770,335,29,823,504,685,198,159,67,544,588,373,415,86,303,512,966,301,239,610,246,323,630,32,524,112,806,274,405,237,355,938,962,116,16,257,489,482,996,220,4,714,349,838,844,316,583,133,246,746,970,553,109,899,375,433,511,783,505,420,999,242,150,688,66,718,349,279,920,544,448,92,460,757,419,414,734,858,142,513,826,464,73,490,71,936,842,600,54,470,984,452,407,464,723,276,253,577,440,323,916,297,334,776,611,466,510,166,610,63,792,584,220,87,20,857,862,554,626,37,406,435,915,956,434,517,398,150,806,955,739,80,327,161,740,470,611,667,702,78,871,501,582,918,257,385,495,357,40,735,653,328,799,734,498,269,179,63,156,734,591,730,907,315,411,0,645,753,85,219,51,151,932,785,82,534,402,415,532,687,597,662,82,448,302,122,408,921,556,96,644,339,84,611,807,906,806,757,591,271,140,216,527,406,732,441,84,265,571,36,497,39,67,611,261,393,883,982,308,576,354,220,509,255,431,602,179,842,360,898,226,9,966,237,276,676,594,665,533,169,933,192,425,126,367,653,366,945,33,655,632,425,119,869,853,169,620,865,590,765,550,825,293,173,359,918,94,350,227,497,99,699,378,661,3,192,347,510,339,238,612,291,552,468,488,146,937,238,118,167,10,32,529,983,215,500,326,236,757,841,501,882,391,927,605,661,598,511,450,891,755,371,679,292,561,366,525,142,640,701,790,534,456,354,659,764,106,463,352,984,46,337,525,893,503,346,528,392,938,641,174,282,280,815,705,321,364,48,376,942,301,79,29,893,352,811,654,950,899,112,913,916,281,99,292,272,701,510,828,184,626,854,421,804,968,378,889,905,964,113,613,47,840,284,977,321,183,993,546,747,700,245,323,794,610,371,158,430,246,763,175,661,307,22,877,760,152,980,181,408,437,901,461,619,310,675,285,858,2,504,837,159,597,600,52,406,392,120,194,492,637,146,86,237,893,811,329,427,380,496,666,987,943,781,313,161,803,187,269,499,854,639,521", "207,565,895,349,647,396,954,646,640,598,526,528,416,911,784,155,551,826,830,254,18,400,978,655,240,296,736,414,976,904,482,625,289,671,196,610,63,869,633,826,95,304,131,803,627,35,329,254,494,967,536,251,137,224,738,239,452,814,393,184,144,819,442,255,809,246,388,232,970,959,365,934,134,940,672,733,70,765,155,247,104,486,60,87,114,547,442,740,475,47,311,840,540,378,206,409,477,755,421,370,245,871,907,341,57,259,49,748,822,606,528,812,810,725,291,212,532,668,950,299,844,278,300,766,972,656,281,345,292,405,601,284,306,716,903,573,941,16,155,682,545,674,846,856,982,54,718,115,302,968,496,95,384,190,84,583,800,14,308,811,834,999,593,81,367,166,990,722,855,145,117,44,151,786,153,288,862,410,231,766,48,571,719,566,818,56,290,192,10,604,760,807,767,624,885,231,232,944,299,544,815,808,344,455,529,946,901,942,317,785,244,717,264,280,644,181,82,418,488,388,716,960,881,80,204,802,206,118,782,119,223,605,314,935,221,736,2,803,652,734,641,252,91,356,890,383,288,591,150,752,34,223,845,162,110,630,543,486,260,794,253,638,532,337,541,796,306,729,391,231,962,324,393,526,882,725,948,467,227,795,690,717,12,697,301,810,521,411,685,66,81,594,212,181,645,369,652,795,130,781,55,520,443,355,856,359,337,164,330,918,588,522,834,530,266,285,400,625,580,852,672,403,327,464,722,600,819,632,164,273,161,397,277,661,662,643,147,460,547,400,550,876,297,821,278,67,620,879,530,832,679,682,709,15,710,146,15,943,430,464,496,569,806,41,474,627,937,894,221,124,168,847,308,724,988,639,213,199,174,555,935,370,12,842,26,823,11,937,200,47,59,10,455,732,51,11,346,10,358,833,544,273,679,17,184,871,22,179,321,293,287,131,784,737,948,729,974,91,652,737,901,960,241,228,565,495,146,794,982,318,324,354,437,747,996,434,788,659,129,818,801,905,254,506,351,269,989,334,60,69,641,999,952,498,970,545,913,470,687,83,445,512,92,958,935,933,827,763,896,907,342,999,545,327,973,869,261,115,646,140,336,945,111,725,15,145,385,240,916,254,919,401,138,158,910,214,741,413,3,558,479,812,884,498,451,113,712,829,992,460,586,892,448,434,328,394,323,629,632,348,731,413,704,583,962,271,299,556,288,827,451,841,459,627,953,347,295,367,190,255,197,15,619,224,776,113,932,603,770,250,860,785,550,478,775,327,205,992,441,796,26,131,236,914,430,355,387,671,458,344,325,760,709,432,450,792,264,489,136,559,793,996,756,38,572,976,82,853,37,686,190,709,993,603,653,854,598,308,50,261,693,128,849,661,128,191,348,851,779,653,761,539,353,305,209,780,528,459,274,15,562,30,129,482,504,49,197,743,546,770,459,280,46,487,793,120,916,484,809,453,708,599,803,109,842,414,19,489,703,228,483,223,410,641,585,597,408,335,770,152,995,444,566,372,77,53,226,565,507,478,976,833,930,841,616,482,426,656,908,206,244,668,264,417,881,99,112,81,789,849,904,570,153,956,592,56,181,724,242,548,159,423,23,758,307,404,677,470,257,968,879,604,645,0,870,672,625,433,120,934,383,686,240,100,766,178,966,102,720,750,755,79,912,717,684,665,743,659,853,126,613,255,562,551,638,130,127,572,365,154,329,236,734,942,338,882,373,671,81,660,658,995,740,246,384,837,460,882,872,910,90,855,157,651,308,837,229,989,356,88,191,658,306,893,950,360,203,500,436,585,527,223,96,467,61,383,537,418,698,3,248,575,93,829,2,662,301,19,288,418,561,554,636,770,464,858,294,115,436,152,233,764,310,55,206,14,962,464,730,791,434,734,181,16,111,230,203,608,655,118,172,945,961,146,48,53,270,399,915,178,728,593,909,277,410,677,244,162,249,229,193,341,637,587,757,853,398,351,653,992,443,117,862,368,650,519,907,837,934,304,111,643,332,789,237,395,689,639,801,789,951,539,980,337,53,183,887,700,870,55,90,488,916,456,685,960,577,649,655,478,322,291,549,44,892,761,156,240,743,643,765,57,82,446,188,19,327,548,668,165,332,292,425,787,249,780,53,697,551,698,239,601,710,742,742,538,917,965,112,947,474,409,943,865,377,860,696,121,623,493,256,710,37,124,277,423,275,935,425,135,636,9,586,191,107,549,28,73,239,42,1000,653,296,163,52,573,805,836,634,437,264,632,447,938,102,638,16,462,966,488", "903,23,899,872,760,835,444,476,105,792,282,505,890,208,298,763,11,42,722,405,597,913,126,237,512,26,940,58,863,843,749,825,743,446,167,264,547,309,510,690,847,446,756,813,245,332,875,780,23,976,913,31,62,181,860,734,365,272,590,879,528,607,562,348,322,94,431,704,744,450,380,950,605,712,824,381,115,546,743,582,401,854,377,6,392,726,636,135,99,227,628,489,934,86,329,641,30,358,395,768,814,747,955,258,718,282,779,698,128,841,214,76,129,416,487,79,534,909,363,225,737,384,168,979,840,21,743,395,389,603,491,494,417,787,673,319,152,556,413,199,284,955,846,789,830,662,519,863,68,312,359,877,9,855,352,820,751,916,755,824,756,867,536,827,763,586,95,442,126,179,44,711,303,688,788,520,595,646,87,200,160,531,306,537,922,101,715,309,97,777,195,739,926,540,513,624,368,570,197,447,864,14,61,350,453,685,710,979,244,259,439,467,26,862,905,451,304,202,590,53,26,685,43,202,829,220,726,837,992,518,851,91,443,698,153,225,299,427,561,497,427,48,333,414,153,927,27,136,448,202,447,132,331,913,228,944,45,80,513,208,498,439,56,317,21,796,152,550,441,437,163,209,467,2,781,795,147,591,510,972,877,638,826,733,153,739,90,195,13,55,509,891,41,685,982,415,962,377,557,195,481,56,904,486,603,752,192,92,744,587,957,148,182,280,983,450,921,835,167,450,587,457,943,629,259,87,642,415,679,965,326,397,401,636,682,503,172,427,259,559,173,986,776,550,966,954,867,496,727,292,877,670,413,972,381,261,463,555,226,168,201,454,275,323,14,267,612,253,974,130,359,157,152,102,877,325,532,287,579,976,252,268,995,657,354,301,978,711,307,34,208,115,30,682,267,284,500,983,266,959,178,751,660,60,459,939,872,369,526,332,991,438,920,601,647,222,457,539,575,521,281,309,490,851,174,93,922,364,224,945,464,380,989,384,216,151,578,284,389,1,82,312,654,618,351,580,358,708,354,23,740,305,519,539,280,777,847,56,64,714,1,170,582,906,750,228,781,501,736,5,392,878,78,580,2,593,636,833,978,210,701,493,921,525,790,127,288,454,447,593,986,456,720,342,206,770,653,568,91,60,836,458,814,135,525,163,368,186,20,580,160,405,375,472,286,72,618,65,299,583,967,822,643,714,470,478,934,675,468,19,150,439,456,714,585,26,181,402,629,344,226,576,694,30,589,824,901,742,917,606,101,404,599,879,248,516,123,896,439,960,568,392,520,887,41,96,830,489,196,504,294,290,114,349,532,846,101,764,885,789,177,36,827,425,624,154,654,812,597,337,737,46,426,695,715,557,902,94,698,409,205,340,927,370,605,7,159,136,466,352,500,727,82,465,392,627,711,690,564,615,407,30,409,53,706,421,382,272,120,658,658,241,612,157,780,343,691,523,280,406,752,620,256,541,201,178,626,349,490,491,165,141,801,432,324,318,979,833,262,987,750,914,108,605,871,303,554,172,656,1000,457,894,946,720,336,784,67,260,855,147,800,133,612,163,931,157,627,441,681,857,704,374,756,932,423,426,841,750,845,518,304,47,896,550,794,581,892,740,549,714,334,907,753,870,0,442,857,211,221,871,734,932,488,687,176,997,662,168,557,575,190,477,680,914,934,472,784,201,100,350,89,582,551,508,41,888,788,108,157,682,322,52,226,219,767,216,273,372,355,316,292,128,344,796,156,253,976,760,236,988,712,669,86,847,814,301,774,964,635,760,97,215,895,149,697,971,498,2,631,607,384,551,832,621,564,206,681,102,271,220,387,289,949,851,296,424,96,476,528,670,816,626,979,548,156,689,271,878,723,825,90,247,581,707,324,733,730,255,762,798,911,487,778,87,596,95,799,331,52,698,432,187,564,107,618,297,999,851,265,96,878,81,313,547,499,531,471,714,282,354,308,669,789,313,27,528,831,256,384,110,247,86,400,180,79,638,885,472,845,786,679,769,800,731,454,391,976,732,511,719,306,250,614,583,594,506,256,504,724,454,300,994,260,508,329,803,490,299,544,733,775,800,182,674,9,549,732,44,557,431,633,231,133,852,970,141,37,586,123,224,749,166,981,267,52,779,520,776,736,643,12,223,903,787,496,146,422,768,244,50,824,167,656,523,316,770,748,667,216,449,145,706,117,685,516,666,443,217,713,181,293,271,872,516,252,26,901,92,336,806,773,444,723,889,265,304,201,939,686,768,424,653,150,938,571,388,500,407,78,367", "664,956,439,383,861,161,548,717,778,79,817,867,754,496,874,843,660,856,891,72,210,816,548,656,335,683,197,850,769,480,701,241,838,254,882,410,424,461,257,489,274,45,500,94,309,27,435,726,618,665,200,138,787,977,17,663,805,512,961,513,272,431,776,351,662,894,286,206,509,301,490,858,724,285,292,410,970,394,357,371,884,80,33,69,937,704,103,510,151,386,433,573,51,746,62,458,311,103,519,654,839,522,131,190,668,17,400,516,668,900,726,912,685,64,108,338,648,865,593,326,676,171,358,329,962,398,272,280,358,417,405,71,764,770,534,70,778,614,559,574,768,849,413,201,270,902,59,787,758,437,172,822,208,417,874,586,520,32,676,708,217,587,364,609,322,851,584,680,614,966,487,35,856,8,579,943,643,324,546,358,997,949,463,259,27,834,5,603,733,452,640,97,706,371,5,112,868,499,98,270,84,362,377,792,820,830,150,513,44,204,796,795,557,262,11,867,461,430,916,77,849,13,55,719,643,245,470,307,725,275,50,655,515,266,383,205,376,433,955,95,320,119,226,584,714,939,513,606,900,554,436,635,177,11,218,614,236,137,14,345,631,600,953,265,684,188,719,509,925,62,23,466,471,621,327,265,244,965,298,240,943,148,37,530,690,273,844,955,142,525,40,253,183,888,769,27,336,95,395,586,295,959,576,715,783,440,858,269,282,819,490,236,392,97,917,678,68,415,915,642,614,723,402,452,152,509,412,274,337,667,589,449,24,670,218,415,652,678,352,112,236,117,213,920,330,854,318,653,864,501,311,265,621,62,402,662,552,599,918,654,646,124,89,74,288,509,460,727,483,234,169,576,608,266,614,644,399,139,232,481,634,75,694,17,367,759,221,850,57,713,600,369,973,682,911,366,188,150,633,360,381,438,770,960,143,609,507,46,294,493,36,222,955,112,441,366,57,747,305,972,27,493,209,58,643,89,835,817,863,800,995,905,162,915,334,275,646,983,242,940,502,624,166,419,348,668,613,751,916,172,821,585,332,869,999,640,36,593,117,254,319,321,1,450,314,568,243,163,532,9,465,282,266,380,800,818,614,440,310,702,690,433,549,7,152,283,966,759,754,690,406,426,423,712,842,461,226,38,178,815,830,560,705,727,583,286,487,206,717,914,98,267,466,831,780,26,244,884,236,642,386,522,132,28,42,876,41,90,805,456,992,953,853,445,208,747,265,13,924,422,376,389,523,370,475,676,444,776,596,499,560,415,874,973,166,2,216,732,632,311,802,766,749,188,614,677,930,543,27,820,301,309,997,156,553,741,852,821,103,533,170,740,884,264,823,252,522,809,303,551,113,242,350,293,929,756,430,36,492,883,450,54,263,695,797,863,513,847,944,55,195,961,900,123,157,367,893,36,622,576,675,307,968,171,264,782,666,318,274,43,9,937,917,662,254,744,586,7,265,295,646,589,356,890,625,848,680,211,691,64,448,980,878,387,842,688,869,617,742,250,206,763,875,96,872,386,318,435,822,17,886,948,851,853,65,618,620,494,921,619,859,399,649,237,577,735,709,74,925,220,975,159,939,108,117,162,111,678,82,75,775,915,805,68,712,43,188,530,609,895,84,951,85,672,442,0,65,154,58,794,504,165,146,781,437,233,666,959,771,209,106,13,694,278,400,622,808,366,232,976,176,292,148,257,491,82,106,969,564,834,323,684,104,450,11,705,56,351,461,69,522,925,52,939,439,542,888,745,732,567,965,784,368,155,422,66,895,149,658,522,560,238,462,144,607,257,416,721,283,710,207,930,825,780,968,511,563,677,727,557,86,197,63,368,376,318,58,298,220,431,444,402,471,12,465,831,899,183,628,819,633,272,657,510,46,508,488,781,14,933,484,917,311,698,231,634,626,214,184,939,405,254,336,860,119,285,586,826,779,289,918,82,322,396,591,847,335,718,557,10,780,965,948,41,558,833,529,860,334,203,918,558,303,347,771,211,194,705,656,908,419,434,699,691,459,263,17,769,842,191,384,286,435,802,917,857,465,473,702,855,898,524,965,718,412,568,227,503,622,184,935,492,4,251,481,743,254,648,444,369,967,141,979,889,661,165,873,628,952,188,906,942,410,365,36,997,341,154,156,914,37,290,734,784,73,265,422,189,565,21,527,405,527,10,268,424,574,739,213,727,13,116,387,102,805,975,99,261,525,819,225,278,718,901,658,432,336,150,76,532,741,561,625,209,350,537,979,53,662,943,376,856,481,200,9,283,913,561,325,682", "21,830,509,83,226,359,581,856,623,736,237,235,151,483,39,472,257,505,847,423,443,502,252,53,84,280,650,897,157,893,464,968,193,222,900,607,523,629,742,283,369,489,988,815,346,896,893,684,479,306,427,165,545,802,183,198,467,202,773,596,364,300,634,890,233,41,880,744,602,436,229,2,116,152,183,486,67,565,846,943,289,672,756,819,309,988,440,599,615,257,28,769,117,565,53,517,707,374,431,562,63,494,984,94,906,754,257,488,29,491,188,217,965,438,576,50,989,574,170,299,981,177,345,125,325,613,592,923,766,49,246,833,773,747,805,42,295,639,690,583,979,587,307,689,933,260,933,309,168,657,636,252,360,19,825,568,66,518,270,887,48,343,208,842,273,551,632,970,645,928,99,587,191,415,117,498,326,857,33,715,410,788,41,981,42,436,132,316,139,775,302,72,488,289,758,323,844,686,804,805,203,894,234,962,99,481,332,478,638,85,674,906,310,342,834,157,964,135,810,603,518,363,551,577,228,693,96,998,623,273,172,234,414,851,799,326,403,150,169,492,634,170,809,5,864,409,797,397,473,131,95,398,741,778,222,553,197,27,342,258,654,509,77,883,693,165,787,65,822,49,371,284,971,847,150,40,471,899,291,184,889,266,367,701,249,473,656,599,827,672,755,500,656,688,154,763,237,721,592,650,679,212,853,569,724,710,262,344,586,377,146,564,395,495,37,562,707,103,317,795,727,730,397,914,549,327,199,59,23,997,684,189,585,644,273,74,74,307,405,945,703,647,255,672,111,782,951,448,349,982,893,966,925,729,669,629,212,447,948,352,164,340,167,577,761,443,525,861,604,362,569,276,324,349,590,978,301,63,714,490,653,440,169,844,267,553,551,323,401,279,967,281,110,954,451,125,967,606,567,890,369,249,919,467,85,475,506,756,200,648,456,251,337,346,479,738,55,327,687,266,416,436,35,985,294,850,554,796,82,336,929,914,733,660,853,258,527,34,78,189,24,503,116,377,779,393,744,957,932,175,82,999,306,599,135,30,479,936,552,696,958,730,340,229,705,352,105,36,589,158,863,663,94,322,21,253,245,671,267,398,898,714,987,352,410,350,473,294,397,428,929,333,121,935,717,451,8,37,207,530,313,722,429,104,365,692,934,419,594,769,82,989,261,570,854,683,161,88,487,970,260,87,575,43,557,80,85,790,829,755,424,702,717,24,535,570,705,471,370,306,569,349,529,826,536,245,835,3,206,8,870,515,933,941,262,915,767,288,821,476,437,270,488,116,961,293,301,361,468,290,954,64,578,855,715,292,774,545,482,758,178,267,47,535,517,426,975,240,269,272,931,751,210,403,388,600,773,8,736,260,488,475,219,888,627,947,449,495,851,70,210,769,852,732,30,804,953,6,451,771,599,608,840,591,671,658,785,953,961,237,848,894,781,549,270,1000,611,490,495,88,233,891,819,384,934,697,331,834,365,401,952,410,987,758,830,719,378,407,675,836,147,851,624,379,645,460,769,567,819,775,171,560,121,255,175,893,187,39,295,783,864,997,244,348,730,597,441,715,661,608,473,376,30,932,582,818,627,412,897,739,429,363,128,3,651,365,230,946,814,504,368,888,219,625,857,65,0,529,507,509,824,243,264,524,662,189,184,475,687,366,474,634,375,401,824,520,185,392,753,308,436,483,921,249,525,570,926,397,205,383,200,53,367,904,201,298,28,494,931,922,299,937,968,662,566,466,904,980,436,169,700,474,799,72,101,505,520,830,988,214,339,29,236,159,402,990,461,26,215,43,157,254,973,903,661,262,822,407,173,401,847,532,194,776,877,377,203,107,971,809,562,343,397,278,967,361,717,782,362,417,887,625,54,536,152,690,812,314,99,265,544,727,198,620,389,695,843,895,754,657,416,506,172,977,853,547,954,33,223,910,228,582,790,18,794,926,796,501,666,324,861,602,108,538,179,880,513,462,357,289,981,243,795,987,329,766,836,917,184,610,90,608,544,513,261,84,460,431,77,671,205,27,267,771,800,784,692,451,74,217,958,215,229,457,649,647,126,378,760,469,774,271,51,103,256,976,825,859,4,471,200,951,447,54,738,301,225,696,820,757,221,151,476,818,374,205,182,126,527,121,295,612,312,122,922,405,682,538,665,66,75,14,27,271,469,713,222,211,73,97,346,501,135,2,139,309,374,619,476,750,952,385,783,788,538,607,28,556,644,968,284,993,67,813,578,783,709,986,904,414,901,509,729,331,459,863,269,86,294,660", "345,266,1000,351,362,70,988,871,946,77,607,284,616,695,483,498,421,368,961,732,473,176,680,943,222,474,339,837,954,922,225,123,758,665,840,253,493,743,183,569,668,644,26,443,636,514,135,36,343,923,322,850,978,970,863,504,276,36,483,769,328,547,399,310,857,417,264,807,569,952,845,424,901,255,350,431,362,697,692,87,687,326,736,654,626,800,831,650,460,256,624,832,756,83,998,564,141,91,630,633,338,302,26,225,829,971,317,760,476,642,989,668,676,476,542,662,646,248,692,886,771,89,386,618,748,232,532,901,742,692,320,336,971,378,331,918,879,85,119,177,510,449,712,238,827,565,432,916,77,508,425,334,139,371,333,616,38,885,721,457,674,907,273,279,643,47,173,899,394,211,950,853,619,419,71,180,465,650,931,77,400,303,904,610,918,681,344,387,63,894,886,599,928,983,86,467,458,982,891,901,467,836,639,677,39,346,398,423,683,137,424,326,143,124,445,377,827,8,459,208,794,255,380,339,181,615,716,421,594,250,416,438,33,193,992,207,298,389,175,413,898,525,565,370,10,788,38,419,435,678,347,639,882,934,45,414,352,120,256,39,517,279,547,611,667,966,25,548,186,959,380,15,915,635,92,79,426,884,360,678,41,736,548,348,642,758,497,147,597,689,101,799,630,890,43,157,897,427,495,86,692,68,38,550,485,67,749,367,223,221,612,458,318,639,820,251,586,308,304,22,638,769,545,661,842,203,820,730,151,150,571,129,531,660,879,589,947,314,23,241,234,827,509,952,127,700,276,42,851,419,431,926,581,256,597,244,763,347,975,675,561,706,950,691,679,907,196,575,941,785,220,309,709,421,816,648,482,340,522,320,532,335,249,341,639,226,666,233,763,357,41,695,426,664,134,418,30,112,394,399,70,384,666,520,287,680,498,864,105,321,62,547,677,533,167,701,589,418,125,207,924,731,952,953,418,205,114,619,153,459,449,76,278,918,894,340,167,147,955,8,354,289,914,801,177,595,880,474,84,816,286,805,677,274,22,136,126,587,683,625,459,195,800,474,812,377,965,390,211,75,768,532,996,809,75,834,250,709,606,368,789,602,871,297,512,449,325,649,809,276,243,510,200,559,476,763,571,820,413,899,120,918,89,900,811,931,816,275,107,994,227,818,14,121,615,533,362,218,350,640,647,970,63,343,637,577,344,494,768,277,764,684,163,511,254,854,441,852,370,382,219,307,708,905,813,659,724,179,994,332,734,88,303,386,146,260,58,142,280,761,385,248,121,690,735,523,116,4,224,360,282,848,306,506,107,929,122,650,681,294,922,534,407,172,485,900,282,994,269,203,711,693,352,377,883,14,263,393,499,678,463,105,491,25,349,686,680,112,703,332,225,418,808,438,580,268,879,170,870,296,597,938,785,310,952,976,891,131,166,522,831,867,49,585,582,943,766,587,456,1000,507,857,617,224,800,14,421,181,18,507,498,694,986,4,530,316,612,540,251,652,615,433,484,686,708,876,990,441,440,331,896,623,640,426,823,864,764,857,526,635,462,242,821,186,787,244,724,977,78,157,970,159,224,914,664,892,562,744,602,95,240,494,159,536,23,934,32,255,636,642,310,558,51,433,211,154,529,0,74,16,621,717,790,327,850,379,468,976,961,144,421,274,898,102,641,104,371,257,506,741,376,488,497,944,806,155,859,644,293,537,349,315,325,167,120,465,845,539,592,906,110,503,838,485,874,592,706,264,838,666,487,437,101,126,846,287,798,294,550,953,469,345,176,428,879,577,623,763,148,784,557,838,305,273,786,464,546,31,97,997,383,507,245,561,663,514,895,824,709,294,143,164,697,176,391,400,141,242,707,4,183,771,499,523,755,458,798,209,888,800,182,597,219,676,158,639,281,735,420,810,854,672,450,838,154,6,230,105,61,135,761,314,196,717,896,572,532,299,965,101,396,200,829,444,229,214,898,488,360,655,810,548,174,150,592,549,785,850,811,135,900,282,280,369,646,709,405,308,120,145,327,236,78,904,851,277,352,745,346,526,551,508,103,912,651,277,722,867,863,520,382,867,437,101,866,511,203,10,625,901,558,406,810,640,774,297,489,812,98,663,904,692,54,981,933,68,326,932,753,611,225,89,340,58,441,449,892,298,82,310,282,73,338,756,751,703,18,673,47,155,907,649,750,11,846,695,727,716,637,472,781,924,344,330,676,884,694,282,751,37,91,223,249,883,461,119,47,241,631,759,514,476,891,410,201,604,527,110,440,964", "480,866,517,431,600,493,562,194,247,212,367,172,581,399,118,518,208,73,801,286,873,251,922,390,70,983,922,462,104,44,859,962,80,137,106,896,608,652,436,662,853,595,985,297,439,736,364,988,751,34,682,573,531,19,797,585,328,691,27,728,440,340,491,201,441,519,646,327,350,46,34,443,196,543,661,388,260,240,844,605,599,592,647,987,260,528,416,448,127,523,943,791,980,432,906,337,125,703,486,29,335,190,382,844,913,834,375,57,623,878,871,340,893,729,873,649,297,180,969,908,28,284,893,642,781,623,266,339,189,140,156,11,196,696,11,995,72,398,314,638,653,578,973,218,901,360,123,7,611,273,727,240,810,275,552,849,278,589,786,415,605,392,836,745,882,944,516,421,300,856,173,68,22,283,250,496,299,931,894,925,455,322,746,837,588,229,99,160,155,71,95,53,674,59,732,279,608,165,560,655,511,551,30,34,773,245,62,712,529,300,90,416,292,53,274,297,988,903,599,842,470,338,476,816,289,567,203,417,252,933,31,44,371,575,751,892,473,203,980,452,73,101,386,452,426,46,562,609,880,896,191,428,613,431,906,425,86,418,233,374,393,353,576,397,622,684,21,931,919,42,677,395,827,853,130,887,525,588,2,993,50,792,561,920,758,681,140,98,98,951,47,501,738,486,251,604,75,195,746,620,736,705,52,479,228,574,471,628,831,356,950,514,192,726,878,975,117,239,30,7,493,558,595,674,341,808,325,192,717,369,488,957,270,993,431,409,41,86,159,320,191,469,900,491,984,514,764,637,89,340,660,495,242,744,332,733,408,522,797,104,897,529,680,810,76,746,915,60,909,756,792,45,464,810,756,785,568,145,291,227,170,498,926,762,553,821,773,163,170,751,402,746,804,897,339,260,279,675,404,304,629,8,634,602,696,526,830,37,867,337,442,368,77,720,244,543,951,352,742,629,657,289,548,243,806,644,40,534,779,409,35,102,646,592,357,182,418,125,364,135,868,992,51,693,526,553,730,911,665,266,484,450,78,199,969,277,588,370,648,428,438,817,398,716,811,154,700,998,97,823,589,74,405,864,636,110,963,859,897,74,709,733,58,521,475,341,900,127,481,701,862,73,606,192,18,688,752,730,779,707,163,854,988,494,98,877,72,716,372,432,865,428,248,143,211,937,727,448,827,873,578,518,286,562,342,944,535,325,270,307,642,250,286,794,701,896,593,775,614,808,827,930,994,548,97,942,687,273,479,642,525,993,308,424,856,858,268,144,502,637,124,554,715,724,780,946,753,124,506,267,199,519,792,296,566,318,906,761,481,690,925,488,927,122,58,488,204,272,151,545,999,43,244,482,692,741,620,180,440,298,322,34,229,200,369,460,765,994,740,107,714,408,243,120,5,431,943,380,501,977,818,679,618,55,228,208,602,746,128,276,753,541,874,821,399,629,452,809,941,402,681,296,138,193,660,462,233,920,723,222,910,672,733,198,81,832,352,767,306,469,631,356,725,938,186,991,253,626,712,91,974,888,965,229,990,384,881,455,474,582,969,164,441,910,678,484,352,663,203,93,863,187,524,662,403,421,790,826,397,433,970,433,996,302,919,25,471,98,821,320,1000,283,151,120,221,58,507,74,0,989,280,62,23,850,211,398,927,34,695,661,496,774,839,192,647,344,804,46,603,612,251,117,289,34,274,686,755,748,936,511,759,706,179,822,533,222,163,769,508,160,348,555,696,809,772,700,791,566,250,50,409,447,565,653,595,922,151,735,368,239,639,349,823,558,369,842,218,279,68,905,284,830,307,756,634,378,843,606,6,261,742,331,336,956,373,890,139,78,405,335,384,457,742,698,894,757,806,363,742,456,689,641,344,255,257,126,809,202,451,453,547,611,911,455,259,855,447,327,704,303,630,353,202,458,575,489,52,426,113,70,98,86,519,568,269,544,467,3,559,168,433,204,965,856,59,571,824,820,410,504,672,630,268,936,776,597,45,751,845,836,486,885,486,363,604,825,17,628,309,425,334,412,907,512,135,323,149,752,340,312,320,24,818,152,983,435,206,790,950,548,701,200,137,212,517,402,257,384,599,646,934,109,401,496,584,587,874,992,686,520,615,90,950,378,163,156,253,120,408,250,989,831,521,387,534,229,945,167,188,89,408,418,688,945,330,345,552,982,70,202,863,283,942,555,153,794,892,86,712,210,372,850,562,125,21,217,408,601,535,951,375,878,846,753,222,348,886,171,368,525,420,812,716,445,76,852,609,320,504,585", "604,792,991,323,681,509,116,530,967,598,984,379,561,6,625,382,607,33,496,234,960,342,100,893,847,125,964,893,553,55,538,854,359,608,334,534,676,35,927,81,373,785,944,602,484,453,259,671,778,884,356,317,95,60,133,745,659,94,28,38,848,904,147,897,466,845,701,157,201,134,451,549,997,428,288,439,538,267,267,924,608,288,325,360,912,933,34,562,150,66,119,679,419,801,760,290,228,128,116,742,910,49,418,330,773,637,179,977,862,805,402,696,644,964,908,346,941,385,999,277,786,70,631,334,244,56,879,323,345,75,301,679,546,505,150,822,939,977,122,53,157,222,470,633,810,809,639,156,399,293,781,312,133,819,540,766,912,198,580,5,413,969,979,520,62,256,81,854,254,170,691,556,705,798,218,726,941,881,499,756,764,361,801,351,415,181,416,134,881,981,530,420,42,80,447,214,643,320,540,292,770,976,289,391,251,826,482,117,493,410,206,568,165,546,709,256,876,86,234,836,340,780,829,437,125,77,347,523,252,571,291,620,891,608,651,20,418,655,277,582,598,355,576,902,726,448,498,843,416,442,736,45,609,672,155,197,248,120,699,149,125,832,757,500,531,63,708,220,275,421,620,149,954,510,792,229,782,810,816,958,716,80,358,849,975,540,649,445,640,473,550,562,651,806,83,948,44,400,991,963,440,950,144,944,486,237,789,917,420,237,440,331,798,843,513,534,325,927,189,113,292,172,959,191,157,661,75,266,146,481,294,891,156,89,725,910,808,76,429,534,415,528,83,833,138,911,208,99,657,675,323,489,934,46,724,561,128,522,694,314,281,286,531,164,729,10,350,253,479,474,314,153,527,667,917,483,946,611,730,864,908,303,237,595,95,968,454,816,609,151,898,856,654,315,640,987,928,970,135,693,916,604,81,905,348,536,72,411,980,100,460,452,214,393,722,643,574,68,253,651,488,202,86,60,517,153,733,563,316,523,81,960,970,864,215,598,912,656,531,777,324,831,765,254,582,254,670,814,675,781,426,298,917,25,242,624,749,596,596,176,262,375,400,139,916,941,292,50,52,579,359,451,384,802,620,154,39,708,801,57,55,54,749,613,113,157,236,591,73,886,201,792,317,91,743,329,350,509,2,636,490,609,503,524,228,329,53,487,373,370,494,942,793,292,963,467,633,147,233,287,701,434,8,84,34,887,473,573,181,725,186,904,125,741,588,581,978,224,297,859,796,316,646,693,37,966,759,861,783,875,179,98,417,119,166,557,243,251,101,96,572,955,415,195,297,943,120,725,197,910,103,361,240,554,530,79,388,969,792,509,369,211,848,226,603,113,886,720,325,851,173,595,211,298,590,845,577,736,391,243,759,405,287,152,887,508,422,493,277,922,461,281,242,942,450,186,682,632,819,187,598,409,826,56,360,831,356,709,161,640,770,313,227,375,517,66,14,193,919,826,132,862,667,700,524,75,348,176,658,432,777,193,18,387,572,931,194,913,220,827,19,375,326,752,301,695,235,548,780,283,372,844,661,189,231,803,974,912,388,603,307,949,708,594,619,554,165,386,523,862,623,809,732,342,57,995,484,902,654,843,456,381,970,990,131,172,941,297,722,163,391,686,932,934,871,794,509,16,989,0,553,500,370,416,634,430,418,859,136,912,805,945,792,67,867,330,169,97,11,814,484,826,199,2,959,294,648,118,741,881,16,142,538,102,90,537,833,251,283,609,197,810,42,128,856,887,218,700,295,248,59,135,773,839,690,409,161,780,793,398,460,998,579,134,636,132,801,476,635,409,375,126,701,829,535,201,129,916,392,813,59,457,385,424,721,918,789,818,170,377,981,444,500,903,308,155,137,125,304,546,207,609,332,496,714,418,949,523,899,663,723,50,677,21,844,967,758,754,351,224,210,798,577,75,210,928,130,234,587,807,234,723,302,491,380,432,476,597,518,557,551,290,16,149,248,515,502,843,857,882,917,545,791,953,333,746,462,405,320,361,972,735,819,422,859,4,167,186,375,25,877,668,18,802,684,927,344,410,681,234,162,538,89,940,848,243,187,329,154,358,902,983,205,244,361,364,771,252,474,459,558,30,242,937,646,270,59,837,800,697,766,871,965,952,359,4,80,455,873,751,977,710,114,143,938,893,310,787,972,533,257,876,310,236,24,337,666,648,872,325,804,415,797,642,615,340,675,41,204,248,390,194,171,94,743,577,468,293,382,258,940,348,51,756,53,229,397,244,998,306,67,310,773,401,284,887,33,772,674,600", "451,56,77,391,528,365,400,145,406,555,399,571,259,127,875,471,406,899,634,505,62,449,619,141,333,455,160,713,485,516,750,146,967,388,354,64,584,22,398,555,306,712,154,913,188,561,886,904,299,724,915,931,176,961,170,428,826,623,10,739,909,273,561,346,70,734,867,440,786,925,978,349,377,596,408,854,897,45,255,372,60,938,897,804,468,316,890,727,679,997,722,977,939,879,680,774,120,154,342,475,890,126,352,986,647,118,405,622,20,886,661,797,847,82,515,240,738,934,570,99,745,720,413,718,451,22,285,338,20,403,55,870,254,553,184,24,343,180,843,407,323,48,390,875,663,122,762,359,958,938,33,627,314,644,306,367,957,400,653,542,580,480,100,446,986,806,792,845,69,760,598,131,175,885,561,96,920,699,585,3,198,658,299,434,359,44,304,307,277,154,117,990,883,511,805,901,31,957,832,581,257,183,179,718,915,360,358,272,123,29,469,887,608,919,676,101,866,429,793,762,424,793,849,56,265,138,676,772,65,955,59,224,113,612,496,943,163,417,467,986,726,39,817,748,608,728,439,913,644,117,950,423,17,124,211,57,287,667,102,703,671,96,947,314,634,656,977,392,414,664,10,960,98,416,468,529,687,254,355,182,187,861,522,793,381,543,28,274,8,887,253,464,7,327,53,246,374,990,578,856,681,230,525,448,886,746,297,186,37,139,852,995,207,721,810,395,96,368,937,497,221,336,410,342,514,368,203,488,159,33,188,612,248,55,786,92,269,861,999,402,576,863,687,151,205,156,798,827,77,391,18,917,782,6,320,842,565,994,237,94,558,707,247,994,924,265,778,366,752,97,495,631,243,777,861,198,661,619,184,531,869,511,174,127,337,922,889,285,506,980,277,338,400,421,375,685,582,33,559,832,456,176,206,483,876,914,899,783,919,503,999,932,707,703,388,565,127,410,373,702,752,89,875,174,694,297,524,705,986,949,631,91,944,561,552,9,43,325,340,952,135,659,517,654,897,173,67,803,621,35,479,785,636,836,897,195,290,907,534,151,428,655,794,606,362,41,659,616,361,669,914,690,488,858,610,54,982,25,661,995,207,117,471,217,176,915,792,964,376,476,452,809,804,424,215,873,878,274,340,888,552,316,341,861,491,474,829,115,323,459,317,407,806,70,50,203,879,803,629,992,519,704,132,757,114,251,706,408,38,105,23,530,583,734,690,880,714,141,238,884,77,848,171,614,402,530,572,269,660,717,418,448,130,834,736,225,551,682,71,298,468,406,262,307,935,600,40,806,839,372,963,77,908,263,283,618,267,270,676,316,894,218,44,786,437,821,31,161,543,277,980,140,917,835,239,104,786,814,243,379,599,526,17,536,392,305,286,431,118,647,68,375,781,579,422,527,361,63,42,179,139,450,79,320,331,410,533,592,764,583,139,156,462,34,859,592,499,914,144,267,147,471,761,671,977,37,467,177,107,307,327,646,728,326,161,374,321,263,559,762,163,499,570,374,922,58,496,968,762,207,393,709,830,735,962,330,944,528,784,650,957,276,208,531,868,361,449,750,929,62,320,465,601,809,822,832,6,507,874,827,7,536,639,713,653,507,499,776,293,522,458,18,785,383,734,504,824,621,280,553,0,178,6,999,349,974,991,505,179,920,213,331,156,139,639,317,55,855,954,797,69,174,388,716,814,419,654,417,670,939,89,567,409,361,802,360,928,974,528,309,964,693,653,466,29,533,116,240,678,68,353,159,956,602,844,579,983,435,810,656,436,48,946,466,307,497,426,381,244,607,735,917,353,600,633,161,111,781,965,502,670,683,391,989,706,466,365,54,697,235,810,855,261,964,682,360,99,517,177,505,553,300,204,44,287,560,147,412,73,629,694,563,94,379,744,229,483,909,821,231,190,572,843,884,613,258,486,746,391,844,288,142,848,526,29,658,348,208,159,243,577,145,124,133,42,682,193,637,412,896,435,335,190,588,636,799,504,305,140,322,194,812,642,374,303,267,89,503,445,716,149,101,542,575,878,297,76,311,311,652,654,136,606,595,547,598,972,969,674,258,518,251,867,271,969,459,138,307,740,524,554,844,108,165,616,896,715,865,166,104,935,586,822,839,402,750,310,922,505,815,63,269,168,88,900,56,144,663,978,616,738,736,823,688,620,581,272,610,555,489,963,269,910,916,51,515,85,874,311,905,814,400,320,688,534,923,346,288,342,252,981,73,264,643,580,552,381,641,572,279,162,269,872,609,580,811,258,27,185,539", "271,337,617,359,416,595,21,879,206,805,973,461,653,936,209,984,527,101,531,920,246,121,36,911,932,566,480,120,842,356,417,80,283,923,273,456,181,75,364,571,622,854,344,106,541,463,710,318,382,416,283,75,598,332,603,878,846,71,716,162,163,799,844,169,625,302,214,603,749,426,183,180,81,215,645,939,563,583,664,250,963,487,100,651,587,916,402,840,466,108,968,381,65,344,484,571,914,274,138,311,862,12,550,836,625,464,904,589,536,366,827,952,127,585,770,647,124,589,181,712,732,253,740,469,941,903,431,875,207,878,583,86,34,808,21,215,30,329,251,794,927,268,380,33,614,430,702,619,271,581,594,103,766,619,179,948,965,673,720,579,113,732,909,418,666,978,387,419,74,846,697,206,838,678,191,149,621,517,905,20,726,186,375,6,267,141,462,905,298,256,592,576,266,782,941,138,827,963,465,73,87,671,532,121,459,308,165,780,173,735,315,901,458,790,256,742,82,536,550,628,704,114,732,977,755,405,86,898,993,622,712,478,798,923,197,737,600,101,186,217,456,132,883,571,221,289,376,871,643,733,558,268,602,363,99,2,372,1,566,945,543,400,204,59,437,292,735,419,530,195,281,509,295,455,872,74,670,722,205,315,884,410,316,328,192,70,729,385,469,640,129,401,250,148,769,143,847,301,413,323,960,857,516,427,452,771,606,831,253,765,795,500,966,726,783,679,201,178,644,197,348,292,91,849,923,840,472,546,618,527,172,210,463,111,237,742,61,483,604,223,314,865,829,272,697,643,536,229,871,91,731,98,465,17,13,329,563,53,427,982,428,875,894,324,227,505,158,987,615,545,631,898,812,686,124,620,310,294,146,101,940,77,363,197,872,550,363,106,881,164,823,704,186,736,390,974,221,645,247,623,129,690,719,387,192,566,437,891,86,85,152,116,55,249,603,527,555,927,148,267,411,966,722,2,998,528,462,88,235,599,547,581,30,559,881,960,974,315,312,908,382,97,205,292,991,890,502,722,631,396,704,6,741,443,684,842,6,3,252,549,253,542,359,358,225,3,361,39,274,990,444,523,165,890,371,474,658,494,193,970,966,500,734,550,400,757,54,977,361,760,34,12,53,576,972,410,841,39,668,81,476,20,373,826,245,445,161,607,695,340,152,14,156,691,558,54,420,368,91,962,274,20,570,664,265,638,483,151,214,409,855,457,838,895,336,960,532,334,463,152,963,290,686,194,838,869,514,625,13,882,73,203,716,790,650,894,781,270,817,389,509,29,428,785,211,145,463,489,576,397,79,125,412,144,519,952,863,668,10,250,158,668,276,625,336,75,898,516,186,714,458,648,13,432,105,450,685,218,851,333,230,392,979,537,630,181,973,887,425,227,710,209,269,29,63,893,132,322,391,925,104,229,760,974,945,714,777,769,39,541,318,560,68,811,311,373,404,618,856,410,913,196,504,520,535,724,939,489,464,151,84,590,897,467,640,674,872,450,553,321,631,712,103,614,967,9,124,141,841,522,939,106,535,329,1000,991,697,569,349,326,124,520,588,164,16,478,9,633,824,804,172,557,910,443,12,855,891,92,966,619,299,920,877,840,353,901,102,733,469,283,472,164,82,686,932,165,243,717,62,500,178,0,797,584,621,148,726,386,380,532,473,184,540,237,917,659,647,879,682,864,685,356,275,986,719,32,562,647,575,397,801,724,64,380,1,215,979,792,519,392,693,15,6,876,723,40,492,219,164,604,200,590,860,223,385,273,914,394,847,870,48,760,47,834,268,161,815,688,510,957,770,184,960,657,463,291,944,15,493,918,268,68,732,381,816,435,914,783,748,939,142,895,559,594,844,315,76,689,898,920,121,541,128,20,516,86,251,849,899,742,545,110,170,662,755,203,547,485,228,38,678,125,167,62,503,916,53,74,370,800,137,207,554,217,569,112,351,724,705,456,804,77,758,658,608,42,929,562,864,453,105,471,40,805,484,473,94,362,535,590,623,38,886,367,832,806,893,670,336,837,561,441,157,640,448,80,850,949,762,798,541,610,418,875,69,523,672,568,640,839,358,662,57,133,553,376,751,520,453,992,953,140,812,974,852,638,462,684,679,398,636,135,216,995,100,958,362,23,79,758,168,336,904,528,290,919,238,993,477,249,596,42,300,677,116,159,985,932,632,25,485,719,330,264,630,192,185,448,158,797,910,518,900,738,32,31,621,62,365,755,363,940,650,177,957,113,648,410,289,83,280,597,355,65,758,622,184,197,277,320", "99,424,659,930,971,142,111,578,370,173,458,19,951,767,762,876,815,790,252,668,3,160,645,652,359,966,824,516,334,307,963,200,699,958,37,533,623,809,605,45,514,661,94,941,655,958,152,555,393,296,195,249,569,363,659,672,746,73,313,782,329,426,219,595,20,703,220,999,356,357,79,463,147,202,437,209,757,58,110,299,216,326,604,239,420,64,252,559,983,923,166,711,4,492,599,981,91,724,149,386,112,9,146,548,196,458,802,564,708,797,455,318,802,589,775,556,562,584,481,895,16,282,15,295,329,231,654,972,67,950,6,877,713,688,584,762,967,315,217,152,707,180,415,8,356,196,125,977,409,879,231,298,132,361,342,259,910,617,255,199,293,503,976,808,772,336,985,458,340,513,508,770,971,736,730,606,731,255,509,12,406,647,62,436,576,125,425,820,981,231,60,918,495,952,882,647,327,266,358,932,493,159,411,988,45,829,348,250,150,912,78,367,209,593,459,259,872,663,778,362,688,199,436,994,867,352,785,494,251,801,175,814,842,88,883,1000,713,86,513,376,959,694,789,968,585,262,79,834,128,190,193,52,205,537,168,252,188,912,539,697,176,304,307,896,830,840,885,380,754,905,710,223,651,105,341,226,758,359,214,649,637,785,338,544,613,387,264,264,569,776,773,685,65,846,476,817,650,41,365,912,21,878,332,592,539,531,479,700,426,240,831,297,43,534,371,575,456,676,143,199,887,359,138,979,559,789,376,370,223,16,97,742,377,985,610,818,154,443,982,42,791,943,326,208,33,209,40,64,724,179,764,2,653,157,706,622,71,833,871,506,921,988,1000,672,150,611,149,602,793,615,982,336,153,802,842,211,142,321,737,530,856,428,707,351,308,429,706,498,242,975,417,258,546,9,301,74,799,901,64,979,447,831,90,202,849,510,305,999,888,184,667,465,947,527,336,52,646,852,228,316,631,80,702,210,105,292,545,588,647,332,890,604,452,267,840,654,174,294,426,605,759,306,63,575,310,503,697,602,989,674,727,500,216,344,55,628,1,836,69,11,615,389,975,487,225,427,164,646,619,778,503,734,129,768,940,325,598,934,997,719,9,464,996,303,571,289,658,440,647,964,219,46,43,984,617,830,646,32,807,883,104,455,251,769,629,150,393,681,190,367,272,284,540,811,550,221,451,627,632,218,39,326,885,36,544,569,9,110,853,700,158,352,153,144,446,453,478,827,412,59,904,778,77,790,240,651,722,566,363,787,585,472,966,139,352,17,50,33,435,540,272,784,105,716,748,195,308,814,726,167,484,151,406,836,979,433,960,891,43,36,605,125,466,570,421,995,900,504,760,305,855,903,946,500,843,371,154,999,779,532,994,456,365,92,645,161,697,889,385,781,947,525,781,19,454,39,424,777,454,339,71,278,667,814,579,811,270,462,981,670,331,529,33,357,808,706,885,156,825,685,582,349,518,632,779,816,300,74,962,613,157,181,350,392,495,451,672,747,835,876,797,504,447,784,857,258,240,634,22,425,872,46,132,270,136,211,805,272,18,43,243,827,891,372,805,1,640,184,486,358,365,426,341,148,112,566,790,720,858,819,468,337,615,474,338,184,260,701,139,767,276,108,534,240,488,146,264,790,23,370,6,797,0,761,350,35,495,240,758,552,732,238,399,642,288,804,913,56,728,542,208,192,34,571,649,151,523,145,443,612,966,561,220,939,419,365,477,853,215,726,604,317,872,661,306,915,552,969,793,736,509,231,203,687,966,288,49,349,882,483,920,458,440,123,25,273,766,326,457,690,717,333,729,471,607,354,697,668,492,817,830,289,155,984,428,305,102,491,308,573,810,581,503,799,312,80,944,542,403,300,738,879,427,843,672,984,586,123,96,882,19,588,597,992,228,602,895,456,625,283,113,317,691,93,832,858,556,550,342,531,746,587,22,903,592,313,786,519,984,337,861,617,186,793,373,727,879,503,560,932,890,744,185,52,767,259,541,823,11,265,303,349,967,254,282,493,227,547,584,555,347,470,517,783,788,786,623,478,176,403,439,788,722,850,849,248,643,430,816,988,308,603,26,301,234,856,922,95,289,379,957,312,633,691,359,229,272,812,10,808,857,886,470,513,976,373,460,957,785,368,152,39,580,664,21,313,47,60,59,155,874,727,420,441,591,809,344,298,577,490,679,444,925,308,317,145,940,306,700,346,832,503,177,148,628,91,10,120,840,739,829,331,998,540,954,690,606,582,986,71,936,258,728,431,502,901,508,386,820,313", "81,136,695,967,781,234,369,52,568,312,931,506,485,509,182,446,100,551,553,324,986,488,728,681,508,371,347,454,808,463,459,55,962,280,382,112,675,199,96,244,313,428,586,268,444,21,452,714,458,899,431,1000,142,36,26,588,910,845,653,575,681,70,905,596,177,375,602,156,249,336,693,959,837,351,719,557,794,891,882,651,697,351,352,572,532,764,137,470,349,860,106,367,424,18,795,666,668,152,676,580,357,351,296,33,276,698,485,949,64,773,228,169,572,709,790,161,646,215,518,684,86,466,655,381,856,618,819,736,894,555,480,328,610,479,792,450,765,76,262,690,149,21,469,474,488,782,498,831,454,110,787,996,786,194,673,985,167,923,608,768,840,778,540,619,77,569,3,270,955,322,603,780,723,849,464,180,3,323,782,373,776,597,897,914,827,424,767,767,57,24,461,271,88,345,71,323,149,576,659,112,306,321,586,668,943,914,29,272,73,637,147,278,823,398,404,723,821,634,602,399,193,309,974,769,233,90,745,371,125,347,2,112,518,278,420,102,319,454,28,908,115,649,775,297,290,227,912,119,307,904,798,239,779,972,668,710,396,742,51,739,449,196,13,66,952,375,354,465,632,669,681,736,365,854,370,473,51,5,920,515,325,281,706,26,546,321,795,495,628,745,671,634,716,987,213,622,435,272,129,150,653,7,383,796,654,267,519,279,202,870,851,504,256,225,803,582,43,298,871,290,88,825,654,318,343,956,630,228,325,450,374,699,450,620,511,177,633,70,995,172,971,704,291,101,965,828,937,360,458,230,518,361,634,675,193,91,620,401,916,401,50,703,716,619,773,431,24,73,329,390,335,38,268,284,463,788,686,645,77,825,11,369,418,425,445,936,997,138,150,470,257,269,918,809,977,457,60,223,984,330,975,772,288,208,632,776,929,4,622,64,126,203,754,311,7,547,470,843,807,261,343,536,795,521,727,468,848,779,565,399,42,584,506,478,625,841,602,379,357,703,621,104,313,147,737,961,314,750,735,163,699,375,617,393,768,670,49,396,826,247,397,226,200,439,556,11,87,189,201,443,33,308,194,698,873,548,994,840,126,124,55,670,74,454,744,376,602,758,477,684,440,769,646,718,738,846,792,637,897,868,885,952,373,956,652,377,571,892,495,822,158,2,806,632,11,47,119,649,718,610,864,729,159,347,947,688,414,825,49,940,643,899,623,862,703,498,751,605,164,557,140,219,657,112,462,867,146,213,60,959,385,455,231,196,40,689,853,774,159,352,582,321,370,804,863,418,57,668,135,436,7,568,195,461,7,876,117,345,598,761,188,207,914,144,531,728,730,331,95,842,713,774,789,104,485,868,322,231,712,291,196,568,78,383,132,179,881,940,908,338,70,654,305,121,680,30,598,670,41,65,664,396,22,319,151,754,920,735,337,242,706,620,871,908,609,839,76,901,50,292,154,100,672,400,985,805,707,624,922,708,608,764,890,40,985,300,580,788,993,717,839,890,38,914,288,935,843,546,849,284,323,468,752,48,312,964,723,762,807,398,10,290,758,120,247,519,585,785,232,33,701,239,86,597,890,355,459,904,598,750,926,48,766,522,170,698,871,569,281,728,295,107,402,100,687,781,524,327,850,416,999,584,761,0,937,561,723,101,974,128,642,105,959,425,220,407,575,132,220,539,279,348,524,924,856,690,789,185,41,478,648,134,686,574,564,38,769,908,951,399,840,343,93,758,532,316,503,621,825,642,307,119,267,621,515,170,602,913,568,781,526,700,440,380,156,564,1,110,885,27,914,316,946,416,485,431,497,339,820,92,358,54,16,326,862,279,848,641,480,874,12,954,432,629,61,109,490,557,927,440,115,459,477,622,406,888,83,342,193,725,777,287,137,642,512,447,753,970,103,559,174,536,273,873,437,467,604,598,883,944,386,734,38,941,149,62,620,48,62,644,982,545,190,295,339,530,10,401,932,38,814,631,797,916,88,489,588,301,247,960,367,679,227,162,149,452,149,562,437,644,776,378,512,276,466,221,306,610,283,362,767,116,347,61,486,240,787,208,909,377,981,286,273,307,339,641,97,391,358,107,174,119,256,815,133,106,899,532,489,564,796,810,413,458,330,143,121,453,730,717,6,396,484,794,510,356,851,967,72,882,562,837,215,415,625,859,16,177,345,782,657,852,522,789,622,802,522,999,594,631,604,511,790,168,543,979,942,834,212,636,2,155,473,904,223,500,48,128,440,349,165,32,742,682,416,28,384,75,221,414", "131,669,334,986,46,819,898,733,80,377,500,892,469,459,504,32,632,769,591,959,749,494,472,910,786,502,158,284,371,196,643,978,664,608,632,823,722,307,722,245,235,625,917,440,568,598,562,295,390,681,87,693,325,246,719,125,407,425,514,777,259,911,294,281,418,906,746,6,551,158,679,562,850,725,868,466,960,321,704,74,594,90,992,225,87,211,524,470,135,447,954,124,552,223,243,242,865,378,423,943,622,670,953,681,83,690,598,756,376,725,291,901,855,891,720,327,857,468,764,261,900,652,534,342,519,147,984,974,633,399,563,181,262,193,483,166,70,361,428,39,211,287,20,787,499,472,742,568,539,807,594,344,97,915,736,740,701,396,478,747,197,720,351,623,336,668,983,566,423,789,836,276,274,485,997,401,409,849,645,286,157,430,935,729,968,32,694,465,242,109,717,507,7,864,216,219,661,382,247,362,436,981,808,116,691,456,73,968,592,443,84,192,97,598,532,854,852,68,388,622,760,537,592,863,697,434,231,768,813,54,895,161,230,663,336,520,357,793,985,562,250,779,973,770,740,112,725,174,17,27,733,471,678,775,638,457,143,64,107,733,845,985,874,276,701,72,890,809,626,558,859,850,237,768,548,586,357,453,566,247,863,541,960,203,435,281,582,703,682,165,187,822,953,165,821,660,404,166,79,829,266,849,908,365,710,468,275,753,449,403,683,917,609,724,615,770,125,204,32,233,717,313,67,733,901,470,58,128,859,400,562,858,29,158,205,862,488,138,97,204,577,485,778,228,398,414,718,303,907,281,380,707,323,992,699,457,269,95,399,854,864,943,915,686,349,751,621,236,418,902,637,289,993,676,317,79,831,259,593,829,135,568,840,602,799,889,617,819,690,414,695,563,59,33,626,79,421,507,609,300,350,90,729,7,846,205,672,211,931,193,626,178,994,743,15,23,44,113,489,996,916,837,965,795,294,45,3,642,331,864,431,222,50,117,972,21,140,566,41,56,201,763,761,157,514,319,61,571,672,624,308,148,246,331,409,546,299,441,806,279,374,327,978,952,168,704,8,362,634,462,956,822,779,73,907,695,349,658,269,154,66,586,731,51,32,709,694,22,574,212,359,99,565,815,122,744,560,104,787,32,992,88,74,656,494,876,912,551,741,925,452,12,487,264,168,208,665,654,351,183,829,299,81,265,117,876,896,954,209,711,501,99,325,600,153,406,952,771,864,816,685,7,836,571,14,227,496,896,69,364,515,823,274,15,885,144,502,20,584,125,629,854,24,33,454,70,341,7,491,307,237,907,638,145,299,988,732,577,170,855,32,56,161,562,574,600,176,742,930,735,4,182,196,929,189,243,793,100,447,520,495,400,666,305,779,863,200,697,485,295,859,538,301,875,670,69,869,625,304,756,770,739,425,281,906,544,581,429,142,567,352,913,903,667,480,35,134,548,206,445,740,902,187,578,11,853,689,372,367,581,971,200,949,762,616,958,58,936,868,51,821,551,998,968,260,177,184,943,179,981,520,409,593,453,313,77,394,578,49,586,854,514,723,739,244,386,226,239,9,581,804,930,451,636,692,351,527,769,102,728,854,764,155,453,671,377,475,597,21,783,807,433,415,766,176,437,662,850,211,634,349,621,350,937,0,501,967,795,909,662,159,444,815,681,939,476,731,69,570,903,919,260,21,323,897,864,478,89,583,275,911,104,898,581,861,506,339,161,230,912,398,988,162,964,388,896,29,973,18,351,671,404,348,157,142,172,306,332,811,158,35,535,442,327,921,1000,911,436,570,76,514,474,574,787,376,896,666,110,449,127,65,647,253,53,299,468,577,917,557,254,74,441,221,219,893,175,388,868,259,175,789,376,586,896,930,71,619,620,373,790,221,286,293,358,751,676,750,539,566,812,748,945,210,171,243,428,119,984,393,7,115,458,11,685,45,641,536,430,32,630,910,432,387,414,437,74,338,562,757,900,401,574,975,534,978,787,209,51,804,150,67,721,520,240,398,843,209,184,502,333,965,559,534,597,820,108,701,420,257,992,417,318,18,743,188,166,571,56,598,139,151,808,161,845,214,581,321,540,271,188,469,365,751,462,998,793,937,638,307,140,907,315,635,625,697,898,56,625,694,858,921,871,428,117,772,44,93,227,754,177,81,151,785,819,619,268,582,557,887,999,570,938,68,224,928,114,417,486,187,238,423,733,37,900,98,963,707,166,452,138,855,566,783,903,784,961,562,855,293,399,15,8,648,134,660,660,497,880,778,175", "902,2,797,306,230,305,20,158,790,278,355,978,195,894,185,556,964,38,746,410,66,126,468,822,982,835,643,721,726,364,104,830,684,763,365,833,525,298,121,208,202,218,522,680,935,333,755,484,368,543,801,811,463,757,681,448,473,462,569,159,122,951,345,80,380,390,782,440,918,421,144,96,511,26,623,991,907,747,172,896,627,179,52,940,274,619,778,350,498,217,656,16,123,163,622,618,607,630,382,711,106,755,354,595,119,223,703,341,984,987,836,43,848,252,954,747,209,989,830,644,936,434,21,798,694,499,782,41,735,466,288,504,271,589,672,790,574,583,337,522,583,687,523,70,435,99,212,842,377,468,855,693,58,16,47,841,45,472,207,499,847,796,120,862,752,394,461,682,204,978,750,500,100,474,121,49,841,758,651,308,95,750,889,518,889,656,223,251,307,878,299,244,184,714,500,956,731,830,436,25,455,699,677,573,126,160,260,163,137,850,373,337,39,165,620,365,924,798,78,146,575,203,752,848,381,743,181,758,71,487,983,720,126,591,3,374,805,445,960,545,608,156,999,475,678,302,803,894,452,330,114,76,655,893,780,924,110,298,947,172,248,847,364,288,470,970,285,725,558,835,234,53,346,305,291,730,96,562,704,408,597,944,341,946,573,976,497,967,424,856,339,80,437,802,466,887,251,331,496,265,439,50,954,982,311,111,770,506,376,363,831,792,936,988,415,674,619,618,676,484,717,359,409,436,456,502,846,153,912,213,565,178,165,803,351,861,967,921,681,268,845,965,719,769,636,340,14,255,449,533,5,837,205,25,232,544,306,444,300,516,412,335,310,338,180,145,59,163,139,129,535,974,320,84,774,574,18,69,591,380,690,190,69,182,983,243,813,527,399,669,542,358,964,152,753,80,476,358,743,118,46,717,575,663,565,930,464,304,949,542,648,892,647,338,636,722,26,812,979,840,455,82,610,128,356,358,622,812,717,292,271,98,150,449,191,611,709,109,549,148,210,353,286,559,809,741,925,120,122,372,111,523,676,690,429,452,146,963,576,508,822,751,261,955,95,295,710,664,233,58,124,499,878,499,590,960,527,387,36,389,394,290,427,176,743,432,376,486,130,612,20,238,233,170,731,802,443,505,217,585,538,813,124,600,433,207,422,401,830,170,390,37,276,813,393,381,957,351,876,546,544,890,330,552,852,585,834,480,47,323,982,165,475,614,645,532,372,446,59,762,819,512,870,839,485,115,945,901,37,437,434,963,823,644,673,574,690,696,906,924,170,176,997,57,661,205,726,457,901,429,492,450,885,898,171,688,349,50,172,621,967,764,533,156,727,23,771,243,539,550,655,299,185,809,736,738,49,554,516,565,724,328,896,240,729,50,216,219,236,268,669,809,24,73,931,969,354,950,189,263,970,368,629,661,667,812,792,109,529,162,730,754,957,576,523,754,150,203,194,319,799,584,240,49,609,631,201,565,768,865,709,292,224,41,969,512,86,881,487,709,863,433,169,838,764,850,87,773,459,26,963,100,353,71,157,537,640,583,836,385,317,175,927,997,888,834,58,912,358,25,807,736,86,709,755,756,69,891,616,557,778,50,300,67,69,421,639,379,117,34,465,82,532,178,997,233,189,379,398,430,974,148,35,561,501,0,255,63,776,647,685,703,364,449,530,506,210,382,743,8,675,260,551,833,795,554,701,15,271,849,802,277,24,856,742,458,818,65,311,227,388,644,622,680,803,670,690,651,636,764,691,255,764,528,776,885,924,379,250,949,675,78,431,421,41,31,54,733,770,426,596,60,734,380,195,18,82,809,744,211,102,729,973,311,107,875,250,566,441,364,450,984,474,850,854,754,801,708,465,842,308,471,321,657,905,791,994,331,714,691,358,164,215,213,511,768,599,372,851,792,24,322,105,693,500,665,13,267,96,943,377,155,190,834,724,500,290,881,60,292,34,346,418,438,62,941,175,138,843,567,848,899,41,884,465,806,568,373,574,438,79,927,805,666,716,512,855,968,608,391,539,775,271,97,856,239,332,173,768,918,211,845,586,929,783,921,874,177,442,235,687,758,319,199,249,453,523,512,701,90,680,257,894,841,784,849,870,294,801,442,77,229,638,845,945,671,753,694,357,324,403,614,608,141,15,893,211,877,730,957,202,204,399,743,866,583,411,831,501,476,434,124,516,660,69,767,459,619,415,609,792,942,243,434,495,104,519,4,929,622,886,226,727,867,379,235,800,718,770,741,970,232,166,868,639,758,748,958,123,703", "314,568,375,796,837,924,653,218,262,78,119,606,814,986,327,752,52,771,734,851,552,142,303,387,463,19,632,715,625,36,183,794,782,336,365,423,238,386,676,958,468,540,588,14,696,843,664,553,83,708,545,400,404,886,929,349,550,667,701,73,34,365,283,67,919,871,325,409,474,650,697,209,438,472,855,500,506,182,450,511,116,907,207,179,564,594,502,934,180,750,393,284,49,995,489,323,639,257,892,665,565,205,947,723,492,594,918,55,18,735,253,833,441,682,931,360,705,982,800,854,998,422,92,750,363,144,389,757,494,699,773,548,79,540,967,277,199,150,373,738,358,642,124,284,898,491,570,203,765,808,59,152,580,543,171,170,538,692,476,816,15,811,364,208,9,748,758,40,457,10,648,15,301,494,335,98,990,948,390,272,842,163,668,983,849,806,744,464,257,158,405,836,690,416,480,16,28,927,338,784,584,685,147,160,82,990,414,950,324,202,831,805,523,459,590,218,534,236,881,268,107,467,241,278,580,496,540,739,973,506,952,584,145,255,57,831,134,242,96,283,490,233,935,307,420,951,333,575,832,637,11,507,331,42,938,321,108,226,866,995,944,174,189,84,967,181,396,636,471,287,311,442,285,318,410,221,774,558,974,908,266,714,903,981,770,335,424,155,275,494,512,114,591,672,349,135,162,179,257,851,795,765,587,882,342,870,11,51,434,616,476,648,63,61,532,561,400,622,200,378,196,530,173,732,72,187,381,203,529,172,423,101,57,478,303,855,868,547,912,253,334,502,482,812,399,877,21,555,674,759,88,624,694,552,855,591,454,455,255,173,150,669,399,80,853,537,378,179,273,964,100,430,849,353,789,767,786,181,98,8,742,591,402,277,795,663,921,923,380,591,622,522,13,900,803,46,632,955,418,237,609,310,905,3,272,726,668,190,760,648,839,124,505,200,80,394,48,46,95,2,968,81,317,581,252,32,709,250,148,758,249,229,584,75,888,682,345,885,482,697,457,813,133,288,826,177,108,723,662,978,871,398,952,382,846,706,252,498,925,775,290,180,831,440,164,481,397,830,646,368,920,663,468,412,547,761,13,913,623,723,706,346,374,588,855,319,985,660,723,426,672,416,141,99,873,943,365,668,269,120,349,136,175,605,490,505,29,505,704,629,801,279,540,683,626,841,508,294,451,298,447,99,70,772,335,627,354,312,309,194,367,109,205,832,106,884,647,758,808,75,159,490,19,945,124,763,237,12,305,241,997,153,650,662,752,858,794,288,800,89,267,972,200,143,489,888,266,954,34,963,560,442,207,545,126,594,731,249,271,553,823,164,89,928,756,594,938,891,904,960,637,57,594,151,147,517,197,753,924,512,377,735,443,2,588,186,204,902,707,749,273,361,900,718,140,901,720,987,123,702,612,125,95,979,177,441,321,576,782,203,588,144,508,178,992,709,593,735,556,234,511,537,255,719,469,315,411,771,592,748,561,485,561,680,846,531,136,247,306,625,40,602,749,323,954,264,10,450,118,311,936,665,696,82,508,160,733,934,868,853,678,62,949,644,326,191,203,729,842,254,301,856,460,661,401,14,472,926,440,516,593,690,195,377,684,490,658,823,312,966,923,896,687,966,662,666,184,468,927,418,991,726,495,723,967,255,0,41,935,909,571,156,680,901,290,975,542,975,351,558,493,984,172,933,822,4,910,122,118,852,409,862,545,788,128,138,838,875,327,549,583,61,771,197,481,798,949,541,675,429,926,570,869,696,129,961,924,600,899,586,735,872,130,985,866,664,768,445,704,254,2,426,298,148,515,242,469,179,838,953,363,202,936,207,429,527,47,783,536,450,463,119,591,832,152,73,622,844,626,615,859,399,493,408,554,361,339,821,740,436,355,943,911,77,435,211,424,729,715,263,815,618,904,515,32,809,857,539,122,809,356,450,197,690,141,803,554,131,896,366,468,787,856,622,423,31,75,593,594,756,343,338,596,941,679,683,444,269,404,742,986,901,759,884,715,36,621,871,747,786,443,740,523,163,384,870,866,603,576,210,292,566,944,809,716,293,278,429,517,38,443,981,887,260,615,483,500,838,114,474,836,587,203,364,386,157,694,754,563,446,67,94,857,565,440,822,550,300,143,464,903,429,766,578,969,652,640,712,812,147,305,220,493,442,658,139,299,888,615,603,725,897,11,945,2,503,792,381,472,370,986,130,808,77,270,729,607,781,7,531,45,655,850,765,502,441,760,908,146,213,751,682,679,875,36,312,35,136,871,438", "436,584,721,625,541,312,498,976,773,33,801,285,112,87,232,39,828,890,87,471,351,598,907,959,380,706,528,137,465,291,459,143,598,376,70,779,629,479,440,111,821,891,498,982,464,906,654,386,200,657,784,982,409,506,324,139,958,210,16,226,291,171,383,65,856,733,484,888,306,890,373,873,713,783,693,446,509,216,276,594,865,667,925,25,433,939,65,692,61,433,655,162,381,315,424,241,530,348,330,363,225,309,894,798,267,860,679,873,733,145,826,548,48,531,528,222,170,326,121,151,507,359,164,665,427,136,319,275,150,532,862,99,150,802,61,207,963,468,844,491,623,863,989,723,456,952,230,324,503,946,287,218,183,818,834,825,780,626,830,773,387,937,506,283,591,797,947,247,694,47,652,202,709,825,253,740,845,345,341,688,9,212,415,505,609,305,988,483,583,915,295,326,446,670,270,919,293,48,430,647,965,475,200,729,238,317,218,186,685,410,471,419,645,546,192,484,487,433,545,173,412,437,449,970,489,329,536,831,360,23,176,805,261,245,426,85,730,989,111,912,19,193,948,635,647,542,984,980,3,683,820,209,620,229,742,425,858,273,40,549,867,148,701,447,285,994,533,291,409,301,379,296,964,115,317,375,976,638,413,271,768,176,721,177,954,639,65,125,462,589,827,555,688,315,502,338,257,222,77,471,946,422,312,555,215,679,886,119,773,463,370,83,142,715,740,712,991,852,504,401,758,248,852,941,599,486,297,627,330,400,710,293,758,978,298,142,250,746,92,694,67,659,653,154,726,140,191,853,870,799,217,868,112,337,21,898,163,711,606,159,945,411,164,161,827,389,883,772,631,725,894,213,789,191,512,436,825,669,763,827,897,863,242,419,935,65,677,113,418,820,9,547,860,145,462,593,943,216,58,207,256,849,389,838,658,422,350,961,298,886,871,930,677,459,748,744,303,637,918,749,287,735,127,104,97,391,547,369,474,467,464,573,172,183,782,980,333,518,154,144,704,223,873,439,16,287,805,49,951,876,605,479,204,575,517,701,244,713,530,917,839,897,359,585,484,755,553,393,640,151,132,451,765,867,953,149,741,69,708,222,483,118,400,878,89,598,946,535,674,145,144,616,117,967,903,527,723,268,361,785,679,638,191,250,958,782,748,121,67,945,724,194,228,881,641,910,548,491,390,846,517,720,296,697,27,122,647,634,336,620,117,426,99,589,964,377,226,52,456,901,226,197,504,310,878,392,485,946,96,380,796,654,864,416,735,784,872,690,633,716,545,503,489,409,329,142,283,879,774,457,720,428,633,346,425,930,449,766,922,221,471,398,210,453,808,591,535,839,523,120,879,772,561,590,949,510,671,15,865,562,992,673,525,262,705,617,843,173,238,103,363,690,923,753,3,328,411,423,395,919,390,222,122,448,525,422,945,171,951,531,956,216,23,245,660,757,892,897,49,215,979,559,592,803,476,213,726,349,886,299,261,820,950,739,212,673,573,814,273,621,393,228,24,775,83,557,734,615,993,244,827,26,295,471,789,300,263,19,144,67,341,154,20,180,369,561,564,424,481,620,879,875,722,383,874,237,194,675,900,57,533,511,924,657,380,819,654,562,286,437,814,332,597,102,168,959,475,976,34,859,505,386,240,101,795,63,41,0,5,696,262,580,105,97,732,754,413,378,586,228,741,152,484,314,171,474,918,79,826,91,869,189,56,114,906,171,893,456,229,124,12,904,602,87,257,408,263,670,715,588,994,377,316,817,83,863,671,727,166,998,218,632,23,426,60,884,931,607,216,569,123,427,115,895,498,933,83,364,410,408,411,972,866,513,756,782,574,67,622,98,815,932,429,191,448,430,501,629,55,232,102,758,548,522,374,468,605,14,317,672,515,598,961,272,323,523,586,324,481,679,532,885,400,247,214,565,112,843,285,471,393,584,603,168,413,282,108,773,33,809,664,128,438,459,578,178,549,22,716,858,82,893,737,656,508,632,179,892,378,946,996,54,79,262,633,447,74,213,551,357,540,601,254,629,610,708,528,920,912,225,807,323,844,298,71,838,105,520,8,271,296,389,54,621,920,767,521,619,150,508,202,706,158,896,60,726,35,232,621,573,660,817,402,617,799,900,605,587,154,252,879,288,745,936,615,979,237,967,535,970,404,386,782,243,787,43,420,860,616,330,518,787,209,141,54,786,395,17,671,315,574,216,689,229,992,569,568,649,896,417,501,996,7,364,700,579,839,791,49,761,327,826,763,719,545,555,397,475,29,484", "979,294,220,65,235,678,915,574,330,570,781,534,512,578,742,247,162,432,355,629,802,420,175,983,168,454,287,119,30,965,563,402,671,415,627,136,649,265,147,802,954,252,791,215,849,837,635,666,467,572,452,674,908,249,896,39,253,877,893,408,311,644,533,441,65,313,756,70,126,80,475,540,620,446,834,777,581,113,773,149,550,366,530,987,194,467,621,896,13,629,939,51,280,124,88,329,412,177,803,103,291,428,994,975,867,445,269,306,987,708,237,56,283,379,440,887,684,461,585,566,493,128,887,536,356,842,173,761,383,859,160,490,512,941,431,1,810,714,949,781,757,392,905,569,966,247,767,302,927,85,151,228,973,453,261,251,885,87,207,290,589,383,980,256,831,805,671,279,448,965,202,843,355,271,485,218,402,839,405,390,894,453,528,581,778,516,574,755,151,426,568,105,695,159,753,874,407,244,750,854,867,308,445,428,927,892,338,39,201,612,725,824,362,162,727,421,475,937,541,771,243,980,377,434,621,324,762,367,226,598,37,24,940,295,785,669,818,11,566,371,928,568,338,762,796,827,371,999,234,892,598,753,614,318,939,621,179,811,253,670,263,193,185,801,25,969,127,597,604,951,879,239,608,430,81,704,3,746,913,389,384,658,736,9,493,13,817,965,63,621,112,667,987,696,227,32,150,165,501,912,850,448,305,173,679,210,727,299,814,975,254,380,287,554,281,402,232,374,467,451,5,21,982,310,85,950,342,55,483,449,810,147,875,691,89,605,510,379,744,781,210,870,973,225,546,98,236,95,998,524,793,88,916,527,406,362,165,762,943,294,451,81,2,688,880,330,582,892,961,96,438,8,33,357,808,683,902,336,403,99,742,448,637,846,591,557,726,270,802,412,808,650,509,222,104,335,655,596,185,554,88,773,388,309,819,418,85,160,124,480,966,244,375,434,776,82,233,489,471,1,351,138,477,469,367,393,357,388,495,415,376,686,231,478,922,115,179,110,960,408,856,616,992,215,889,169,949,425,300,524,51,980,376,615,153,492,896,631,275,86,847,565,749,746,870,452,994,907,718,906,554,8,587,301,900,633,977,595,474,337,300,600,590,855,70,399,483,106,699,387,839,817,898,846,754,802,498,740,84,620,37,742,707,28,804,520,110,793,581,777,784,607,904,742,388,135,942,579,319,609,550,725,435,344,826,521,120,758,669,281,791,627,198,781,926,764,442,613,482,889,755,561,358,897,633,468,687,998,550,693,618,244,510,945,537,986,270,229,558,634,796,817,298,757,395,332,55,428,775,69,976,795,880,676,861,13,822,452,660,336,153,657,717,702,178,524,657,791,156,124,89,968,172,34,780,259,751,43,630,393,492,522,513,188,239,690,847,81,305,804,468,55,443,34,849,174,880,334,329,704,335,707,436,691,241,306,549,270,851,998,339,504,691,876,98,666,454,81,81,490,69,690,132,433,2,158,651,307,285,44,162,779,690,77,372,204,309,873,833,458,66,160,924,405,395,709,759,517,330,36,423,558,435,485,315,75,853,148,122,417,12,190,23,166,200,269,932,836,920,611,409,654,310,342,596,309,60,493,327,682,318,230,493,435,607,694,98,717,708,398,344,585,662,720,557,771,687,961,695,136,179,380,758,974,909,776,935,5,0,816,427,579,357,939,840,280,334,814,500,365,313,350,208,747,760,600,592,813,169,351,388,42,664,261,522,273,888,156,409,607,666,449,649,771,970,509,138,950,4,60,452,470,675,617,519,873,370,893,915,908,805,433,186,761,531,411,745,375,339,109,422,575,458,999,343,369,817,897,11,193,631,590,313,323,855,629,645,247,946,102,107,351,533,875,524,663,841,826,235,56,875,874,222,334,860,346,118,154,138,821,636,222,402,923,391,928,578,265,890,306,18,247,484,852,308,124,550,908,949,801,26,970,737,625,731,191,698,709,463,656,37,642,201,358,847,456,231,982,352,986,161,44,664,301,363,889,148,258,502,762,139,864,817,399,697,301,324,799,477,453,904,148,809,743,543,832,578,604,229,556,350,604,190,42,365,123,3,644,139,160,578,782,491,561,559,276,515,725,693,915,829,218,671,257,742,395,388,92,710,94,178,773,433,30,540,898,636,327,371,45,37,917,221,98,172,739,373,802,763,696,460,788,328,929,287,235,7,904,919,847,588,254,212,435,463,827,292,594,345,859,433,101,856,778,754,502,229,904,475,548,395,559,381,81,245,743,751,691,964,578,644,253,609,381,299,969,125,331,391,448", "634,362,739,379,391,123,933,134,839,440,571,717,280,674,702,742,171,513,260,352,515,614,258,278,1000,835,892,448,674,457,397,518,878,982,865,593,968,511,364,80,935,988,928,560,446,250,100,424,363,249,932,139,376,267,565,953,225,613,855,527,570,576,929,319,269,967,426,485,720,299,940,484,233,49,260,947,747,656,701,103,476,894,446,911,509,818,263,499,836,461,946,362,434,498,103,126,608,628,10,560,888,248,626,50,339,45,900,839,766,47,69,171,140,512,755,575,63,64,918,652,221,813,903,433,331,181,336,884,588,991,369,157,997,364,985,148,680,982,438,427,648,996,356,363,815,23,796,263,840,679,747,784,455,400,233,777,268,216,856,790,768,141,943,649,652,705,564,255,345,759,966,603,514,163,194,646,575,172,228,635,563,249,609,844,926,765,889,243,647,462,585,740,962,399,676,444,658,293,803,716,993,611,118,264,30,183,825,466,131,371,919,312,406,853,272,983,21,12,251,666,256,9,607,231,987,609,468,722,772,172,401,187,88,350,853,641,327,525,364,431,383,110,893,989,148,493,752,188,268,514,890,982,112,220,920,890,618,427,925,630,192,848,495,160,995,551,151,761,678,636,341,129,548,898,214,903,884,944,447,632,268,165,633,50,35,458,404,467,743,12,357,391,239,730,991,340,500,922,548,418,691,261,580,482,200,527,130,540,806,183,110,409,284,940,475,991,682,852,364,159,665,476,472,379,853,563,411,88,588,79,30,875,730,786,67,240,741,210,90,330,852,956,896,36,618,905,117,334,644,687,717,849,978,905,660,191,801,972,216,441,832,332,930,652,894,678,458,328,971,159,87,813,25,296,935,483,85,27,601,211,754,464,136,805,541,518,214,233,796,992,496,796,247,686,873,164,672,778,475,606,883,905,530,879,704,501,259,819,664,505,835,531,52,980,161,845,939,918,605,669,610,684,742,197,982,343,388,21,11,196,915,766,522,207,780,954,901,133,30,484,181,929,614,452,714,404,964,218,408,989,710,454,141,561,357,614,994,89,935,596,954,453,324,671,579,252,986,651,404,666,586,302,922,188,174,593,239,888,170,551,129,883,380,444,836,250,832,206,825,952,131,604,46,445,648,74,29,632,778,113,552,107,281,400,561,478,307,524,64,708,962,679,472,807,339,839,967,655,253,361,524,133,379,738,5,969,997,272,339,207,355,694,310,206,389,852,532,430,504,419,212,417,832,760,325,675,693,233,535,803,24,337,865,30,406,421,46,166,984,328,551,734,935,5,727,867,804,730,241,977,737,497,515,448,485,631,794,205,28,513,658,981,864,544,94,944,83,362,707,102,943,49,944,354,46,508,375,419,350,678,450,110,752,998,539,816,953,160,534,668,387,21,371,888,910,518,890,430,887,275,342,747,159,839,912,134,546,836,687,933,552,991,765,323,968,826,556,83,280,233,610,112,369,286,739,870,350,604,318,514,346,928,891,179,971,542,846,881,416,152,917,493,603,636,96,555,985,582,930,896,448,114,612,23,356,515,662,697,312,680,517,36,597,866,208,442,470,561,659,734,419,924,717,158,838,522,533,517,9,3,842,455,990,727,675,414,475,37,321,760,818,40,82,750,575,209,366,144,661,912,920,532,552,128,662,647,909,696,816,0,306,373,928,242,359,726,758,301,248,749,562,883,145,13,46,875,785,896,533,374,310,702,855,698,711,593,554,183,815,920,106,44,393,184,609,482,148,271,3,550,609,713,42,812,289,581,634,715,924,548,135,587,930,486,810,610,1,283,590,830,413,871,986,896,907,961,644,160,92,503,368,993,399,424,456,169,330,575,113,70,252,779,806,858,963,303,659,247,943,868,980,787,167,532,522,590,530,150,183,882,265,103,99,189,565,35,685,941,186,888,288,658,878,927,803,208,630,751,57,994,589,383,110,257,155,54,889,776,439,995,708,898,580,697,289,264,125,402,84,203,322,272,199,64,226,7,881,43,215,581,361,671,370,401,845,483,152,336,50,696,525,975,652,185,443,211,60,419,801,339,620,680,615,785,922,337,892,510,595,483,452,322,704,519,690,168,798,506,725,98,955,325,212,658,392,834,457,421,350,900,780,261,770,209,133,741,306,366,482,91,159,315,704,523,58,67,284,548,820,718,804,205,785,870,603,875,76,360,358,103,29,144,525,720,3,875,911,620,590,843,669,50,794,507,831,129,669,95,201,746,865,787,162,884,376,633,823,783,464,62,361,873,689,884,178,192,771,401,228,237", "63,421,464,201,594,445,398,895,508,609,800,737,94,972,373,931,234,368,989,873,580,302,568,129,658,588,133,193,538,22,452,451,777,218,949,385,860,911,381,415,813,244,550,649,408,916,575,590,302,99,143,261,30,69,851,953,521,709,213,717,860,210,456,450,554,606,927,548,142,895,846,997,879,616,759,916,237,341,221,369,131,252,712,953,295,441,381,926,907,59,691,404,351,25,468,705,885,547,572,104,593,712,595,326,82,361,692,774,170,179,878,74,412,908,546,449,261,621,707,620,927,286,933,633,200,637,383,136,359,474,364,918,831,761,949,52,220,881,265,684,951,737,936,653,848,344,427,369,45,317,279,760,428,758,705,820,639,317,317,612,188,702,379,527,891,66,89,764,400,802,963,343,383,534,565,338,438,766,748,484,675,593,302,191,290,153,13,686,504,572,521,437,109,199,205,442,575,269,854,780,904,657,897,624,48,744,691,988,468,86,641,555,394,872,355,197,959,767,749,265,594,150,445,368,109,384,784,852,685,83,190,891,620,72,8,87,209,935,773,270,595,822,221,219,342,320,339,754,638,411,301,392,975,809,289,402,572,547,632,853,830,433,680,899,342,344,556,54,900,898,183,316,569,645,512,201,172,546,508,791,389,587,272,454,182,616,690,967,345,947,143,162,643,725,958,435,639,917,754,340,522,37,740,791,121,36,332,45,698,183,25,948,264,778,36,272,931,424,825,875,776,732,665,68,769,332,721,866,692,28,260,142,283,574,846,334,787,39,271,466,939,468,480,22,447,266,190,501,576,148,275,144,192,267,379,261,538,593,742,60,980,954,840,201,252,689,270,835,400,674,811,808,706,856,849,223,874,37,992,681,726,771,413,663,58,635,121,573,542,510,995,485,134,597,419,101,584,163,505,146,846,559,777,140,514,397,545,277,770,441,116,799,94,506,826,305,456,718,501,492,824,728,47,39,483,181,529,3,487,500,949,47,966,236,945,397,850,45,674,426,569,341,292,478,154,920,960,332,532,321,348,379,586,789,155,321,372,793,285,617,972,105,559,688,365,760,941,633,218,208,91,552,385,329,88,411,892,437,458,29,911,599,310,13,133,896,973,579,810,821,659,454,341,213,439,922,257,469,873,627,602,161,661,901,277,238,233,776,343,699,962,186,474,164,821,46,832,614,944,445,574,928,25,920,203,556,684,832,599,795,272,508,773,396,168,560,474,877,809,456,298,572,465,736,23,971,162,374,710,335,17,393,286,730,772,266,327,619,138,215,236,656,3,776,832,868,639,539,167,79,416,572,400,982,239,631,389,544,396,270,646,411,13,70,441,450,13,687,198,66,426,258,794,4,273,273,874,165,375,973,489,275,731,158,710,592,668,947,181,211,183,764,614,932,75,952,495,746,258,110,663,158,602,698,829,139,748,30,876,42,895,679,300,230,964,4,126,510,562,258,418,978,118,289,823,931,440,852,179,266,488,77,48,672,433,512,228,227,341,425,643,130,25,762,752,300,256,445,161,69,853,3,137,68,447,234,172,645,237,389,990,647,704,840,436,230,754,606,644,463,51,246,607,11,314,734,596,447,503,123,898,460,241,622,92,606,175,778,163,774,337,586,448,755,190,106,474,421,496,805,213,473,732,642,159,685,571,262,427,306,0,97,940,927,274,649,74,737,157,817,585,106,801,981,79,652,720,524,140,374,875,558,815,4,39,343,182,91,463,570,549,459,927,323,885,764,795,983,802,225,238,209,500,555,794,887,707,350,446,45,895,843,41,912,498,248,879,854,13,616,753,476,176,111,579,244,881,930,137,831,460,697,332,573,917,448,662,662,264,605,988,693,522,679,20,754,675,952,632,557,461,657,64,867,425,41,175,155,116,569,35,982,750,833,552,137,723,354,220,988,899,588,768,877,574,152,649,604,651,464,503,568,189,706,875,172,371,104,656,603,541,97,415,579,682,755,966,352,709,24,529,157,950,78,948,929,699,291,389,988,971,231,888,186,431,557,807,836,146,574,738,446,387,214,287,150,393,670,931,29,639,372,815,984,691,3,87,288,471,841,898,411,727,573,45,547,179,533,607,61,295,816,327,635,666,389,827,416,17,938,510,786,638,482,909,83,42,465,43,166,20,248,237,89,758,832,570,905,961,833,457,25,94,884,298,556,326,907,383,614,582,114,117,754,761,704,110,591,215,948,177,744,688,461,279,838,427,256,790,918,407,734,259,511,458,656,300,438,993,607,59,771,6,551,854,903,585,816,243,566", "164,304,67,693,274,105,893,452,660,216,623,217,470,675,982,51,213,587,829,895,556,228,258,694,418,201,501,349,774,479,800,96,524,381,567,794,647,890,81,476,420,76,664,489,27,81,610,782,356,117,856,752,684,582,345,320,511,588,342,731,521,370,62,282,495,832,14,184,245,54,515,485,86,656,546,151,801,969,350,935,218,882,762,410,816,815,993,528,552,248,602,378,425,433,160,853,699,380,343,149,905,168,41,750,943,681,404,321,823,891,984,481,939,496,831,168,322,880,652,3,409,664,892,681,710,35,72,473,776,893,851,442,290,130,664,82,351,308,435,340,49,657,642,399,247,22,296,118,35,231,132,967,4,475,516,625,111,674,674,63,5,986,208,298,514,952,945,533,688,551,860,429,681,874,676,85,352,430,91,15,779,35,321,397,139,194,316,175,620,919,480,679,779,215,104,608,538,16,753,8,630,717,461,544,665,595,52,80,862,691,545,939,436,137,220,789,384,672,516,61,633,850,791,790,581,328,972,157,124,890,540,285,823,729,599,620,720,253,307,889,668,607,991,262,940,116,810,210,364,904,900,985,900,766,293,459,741,456,990,104,273,880,212,925,387,200,563,617,341,112,907,437,775,627,933,479,724,252,135,564,209,181,126,529,431,565,601,402,165,826,70,810,856,385,325,112,55,703,747,553,819,970,229,536,35,715,402,380,891,244,170,621,793,423,82,844,166,321,809,261,925,25,368,8,558,703,222,70,660,447,882,615,830,662,464,261,242,316,749,173,91,191,757,357,205,722,582,17,24,191,629,823,678,86,851,417,5,826,333,674,871,140,889,202,430,659,896,662,321,762,680,691,759,156,735,669,42,295,889,795,48,559,375,509,693,473,865,393,235,891,853,168,898,444,94,131,243,759,434,302,650,116,746,591,653,184,78,30,524,903,848,464,850,786,224,88,96,146,172,491,626,819,71,353,151,740,138,197,171,803,938,3,615,250,33,869,335,241,522,967,225,326,942,137,294,485,985,671,655,36,403,50,219,754,467,84,891,549,686,805,520,900,749,599,269,98,980,470,43,424,973,88,212,427,674,493,87,628,165,783,570,727,515,547,972,16,994,973,283,17,469,62,823,653,537,17,131,297,669,357,109,632,492,888,827,324,701,329,616,854,382,609,645,163,79,144,405,864,166,988,800,73,210,494,319,481,401,260,221,407,246,196,496,405,238,611,858,172,978,769,763,32,664,341,101,408,567,427,11,106,216,304,794,904,39,56,389,243,569,170,728,835,707,863,347,250,580,909,700,679,149,729,318,933,214,960,422,134,723,637,364,777,534,627,378,892,528,285,829,966,351,962,367,774,675,52,864,277,959,719,623,142,498,990,331,784,137,277,269,201,295,716,804,349,607,745,366,459,754,821,664,985,404,114,544,120,727,922,337,263,468,157,371,339,47,265,22,317,880,55,290,64,226,201,488,609,781,157,468,607,422,989,77,165,140,26,134,895,734,797,139,835,545,473,327,26,560,968,974,847,293,876,766,613,8,114,931,75,54,384,567,622,339,362,148,166,76,591,83,578,710,76,422,369,251,903,755,864,275,450,284,339,469,936,927,269,63,100,517,26,796,342,302,79,477,13,634,274,774,945,331,184,238,105,444,703,156,580,579,373,97,0,424,336,129,488,311,645,442,401,287,692,13,605,951,225,793,929,760,610,718,604,247,323,304,682,132,518,542,49,856,752,651,493,553,185,587,752,52,758,612,140,480,744,502,808,354,48,544,553,358,455,958,614,306,595,768,155,875,767,344,719,450,852,833,508,986,274,921,346,577,648,54,576,219,556,490,475,549,656,317,217,657,379,940,153,249,598,338,4,283,721,726,867,502,182,746,615,63,540,859,993,904,233,487,136,508,364,526,498,298,307,402,521,910,199,760,868,678,633,308,281,405,479,909,948,634,559,543,950,412,608,571,190,20,567,788,878,143,419,271,202,432,290,371,515,597,287,958,621,433,663,700,647,825,744,377,980,376,780,467,378,336,159,184,175,954,109,176,78,204,740,588,181,76,411,549,832,305,340,437,323,778,362,370,598,26,948,634,694,960,387,963,952,206,410,209,835,432,227,495,801,25,501,322,780,526,647,155,881,833,911,217,967,316,540,548,627,931,838,362,396,8,440,751,773,702,903,25,635,358,776,326,525,292,721,599,170,518,452,685,456,530,756,599,295,222,480,995,973,824,151,967,701,580,846,42,357,822,731,310,64,923,10,427,187,131,877,764,79", "849,621,62,135,263,454,140,801,484,533,681,264,748,589,78,616,130,190,725,277,593,869,673,70,241,324,264,544,872,248,574,689,15,400,325,855,926,393,423,535,190,563,354,230,571,325,44,864,309,784,745,148,817,630,869,120,262,474,499,112,187,214,950,695,808,656,456,933,160,748,616,711,220,404,444,816,689,962,813,953,806,324,855,215,765,545,385,280,399,140,971,894,671,710,77,792,987,927,107,495,290,789,164,494,681,477,137,117,345,745,900,117,971,26,357,173,102,683,469,758,725,150,550,56,870,304,334,427,814,819,269,688,17,287,890,792,693,119,783,276,55,835,878,266,677,57,680,639,195,517,486,54,884,263,399,907,229,18,44,765,183,237,5,998,979,281,470,18,90,977,701,852,551,547,103,183,271,64,880,590,100,555,846,168,681,712,866,31,744,23,919,510,482,341,6,862,85,796,423,446,892,647,629,787,167,63,835,37,610,277,467,648,852,103,381,108,542,213,33,344,565,408,379,821,516,441,232,14,840,404,724,397,492,483,973,946,219,434,215,611,137,115,527,300,124,845,254,908,598,856,700,615,465,852,118,142,874,960,937,614,782,933,983,838,793,492,185,181,151,477,778,438,592,115,220,778,475,127,249,153,799,215,202,814,838,634,867,904,172,848,126,98,865,202,996,25,334,883,782,251,362,497,421,196,490,868,714,422,857,624,709,293,861,781,962,511,682,955,57,10,113,196,887,189,416,499,629,863,392,309,108,801,487,407,877,92,232,483,91,268,582,890,454,236,949,146,681,942,803,775,934,92,915,833,86,675,627,401,10,925,619,498,668,961,531,457,931,887,272,837,495,533,409,316,161,392,675,106,516,426,837,939,761,974,927,752,110,419,420,984,818,56,961,94,392,708,453,994,328,304,322,866,336,442,334,189,60,331,329,552,712,989,359,380,708,731,859,238,16,7,16,236,681,443,297,829,331,92,655,367,612,465,795,568,609,294,455,85,29,535,249,251,232,561,920,762,325,299,948,378,810,888,596,273,655,630,100,676,428,534,238,193,667,721,679,979,666,333,844,904,933,912,328,416,480,642,412,400,470,338,297,322,785,691,519,225,440,144,814,634,987,13,225,828,676,920,279,527,592,803,731,164,224,344,47,85,240,658,895,247,351,20,342,51,246,584,888,538,639,823,685,704,950,454,938,265,218,42,651,171,925,632,557,348,214,729,703,31,414,372,182,484,99,294,174,810,676,232,460,916,387,788,39,791,577,673,880,246,697,114,913,277,880,748,721,914,898,117,447,816,325,628,848,130,327,394,49,555,198,138,426,204,231,373,979,129,200,496,104,105,845,507,60,525,193,840,199,958,641,517,45,411,134,25,470,649,289,736,572,578,585,553,418,936,20,817,876,724,975,102,893,467,83,273,646,102,902,190,946,888,608,853,954,671,898,542,658,787,773,524,716,766,222,596,469,160,673,13,803,137,840,115,316,315,55,997,574,818,264,908,134,399,691,742,915,549,389,646,520,945,529,744,875,811,509,7,16,151,789,222,251,453,298,614,878,248,224,951,452,802,143,864,398,205,773,780,823,383,428,309,10,685,711,834,535,157,403,15,736,474,298,953,122,912,680,694,375,898,839,792,156,540,399,959,815,364,680,105,357,928,940,424,0,809,715,452,980,398,724,819,810,647,7,426,945,909,36,376,15,784,778,761,688,126,298,119,984,231,95,580,828,455,580,814,52,447,811,193,598,523,515,304,211,151,632,762,279,251,594,903,998,89,955,608,298,568,904,463,820,132,506,539,748,690,15,24,380,929,405,596,774,715,945,796,232,816,157,271,642,996,915,389,676,609,462,940,701,958,485,432,391,103,239,591,523,589,466,676,788,65,96,155,595,891,110,156,700,890,401,500,236,610,807,619,577,379,849,943,828,377,977,262,855,864,204,214,889,841,171,411,216,387,617,894,564,409,703,978,302,264,200,652,371,74,99,292,955,456,774,805,284,278,699,919,772,271,677,664,924,890,606,827,512,648,555,466,447,293,35,899,54,944,556,882,758,228,755,342,120,828,790,158,309,919,373,714,845,958,877,32,724,505,703,156,128,756,675,288,707,861,321,774,612,573,165,112,729,985,801,422,481,94,248,327,328,540,394,312,794,725,276,980,215,669,785,379,746,333,234,591,638,306,491,431,424,624,264,867,439,905,715,790,529,736,972,188,319,151,581,165,17,832,381,210,214,651,450,48,83,466,472,911,750,554,989,623,322,690,974,243", "736,582,396,814,372,944,264,450,209,183,54,74,787,526,871,870,853,15,669,112,767,555,888,903,507,586,641,162,391,229,16,541,207,146,433,464,333,857,406,585,890,391,345,136,305,891,723,341,839,352,267,178,631,409,16,907,41,520,280,32,685,143,225,422,584,71,958,545,283,228,170,800,837,822,981,305,102,39,491,274,641,204,490,54,630,926,220,996,908,314,845,587,679,736,476,618,414,374,532,591,739,713,240,667,766,132,693,745,583,664,622,552,556,771,555,182,285,920,721,555,870,175,608,361,895,918,657,620,947,203,254,224,475,357,415,67,185,693,457,513,234,359,939,49,442,856,488,186,303,103,705,891,325,860,833,602,470,680,619,343,449,269,956,948,688,133,696,620,972,841,752,236,469,181,940,232,88,992,613,183,633,569,677,20,494,146,475,145,603,534,315,98,985,279,444,679,197,66,636,75,642,276,256,731,192,886,707,147,220,832,320,28,270,174,629,138,203,674,828,703,588,613,810,448,406,311,991,608,259,154,378,94,265,591,932,549,343,365,131,656,175,109,507,827,662,285,631,978,718,94,411,452,775,408,843,818,582,822,401,462,263,50,47,329,535,462,935,389,796,902,959,806,619,484,12,193,364,953,382,355,327,935,109,353,840,575,226,288,754,406,810,109,748,9,104,96,723,224,321,307,928,247,198,799,672,867,690,545,646,856,44,766,382,817,594,308,734,835,48,491,819,12,786,989,467,980,42,142,413,875,704,349,675,433,612,30,485,946,17,821,714,662,803,470,605,22,497,67,181,859,678,313,422,541,952,301,816,291,70,572,427,692,327,549,786,543,268,304,172,465,349,980,342,203,258,56,876,330,408,646,222,290,454,164,232,778,675,461,171,466,6,840,363,659,797,457,386,173,691,366,215,116,11,937,287,548,731,789,432,958,535,577,330,492,664,865,324,118,927,437,947,836,718,979,931,911,114,881,691,469,93,603,398,735,595,519,192,593,821,652,217,868,153,309,672,681,49,2,286,94,789,429,141,951,689,615,161,681,306,713,480,940,766,718,196,626,663,251,494,866,90,72,906,834,960,45,683,778,390,512,189,912,171,626,579,82,274,667,126,90,257,563,800,968,327,178,10,552,435,38,454,301,7,774,440,742,51,938,573,288,390,142,79,376,168,507,252,406,512,816,505,594,430,33,779,910,131,533,540,289,882,928,477,556,74,447,205,742,152,922,655,933,998,760,970,438,683,248,810,729,427,44,162,435,343,568,723,314,848,625,216,512,992,204,861,825,693,315,58,713,679,969,804,797,617,404,979,73,192,124,220,901,667,783,153,846,200,415,551,631,419,447,894,555,966,226,972,239,454,391,324,604,22,595,930,544,985,302,207,791,831,143,607,822,151,115,656,24,541,473,585,641,277,124,238,941,762,69,578,468,466,229,938,745,437,478,870,508,676,371,92,719,137,62,810,507,939,788,339,235,897,995,595,307,885,602,905,457,724,42,722,37,147,988,919,206,167,268,412,517,943,138,220,536,724,784,583,193,534,840,739,729,338,30,639,971,945,545,871,633,695,415,937,663,668,239,746,795,222,27,340,491,195,177,186,276,806,830,824,257,803,236,408,717,914,278,401,102,192,67,139,237,642,425,681,449,901,97,939,242,927,336,809,0,391,387,936,812,352,636,792,59,619,110,52,462,101,491,844,830,792,30,403,893,711,762,648,277,479,533,920,946,891,781,852,576,861,483,21,88,236,721,772,529,217,510,855,256,225,455,719,138,251,544,728,608,625,80,194,638,881,812,874,214,935,163,586,3,641,149,69,596,364,272,92,183,429,238,371,453,684,789,915,59,101,649,639,269,584,825,938,495,180,303,220,611,393,398,181,105,311,679,934,352,112,67,934,948,131,878,397,442,915,561,878,233,755,779,384,460,429,204,406,112,469,137,168,124,315,486,251,542,352,22,661,527,828,776,299,950,539,602,872,594,633,111,77,131,98,736,379,730,915,292,186,93,496,61,705,334,980,880,316,825,610,891,951,901,287,971,389,443,35,688,348,684,247,742,949,406,357,698,258,825,983,160,181,916,760,89,429,580,946,654,819,560,994,153,630,23,398,543,953,692,109,110,356,383,259,801,897,943,824,369,617,367,74,914,87,851,318,936,900,333,890,916,269,936,177,301,684,615,546,359,431,393,89,909,142,874,244,362,387,938,63,511,105,453,849,488,772,588,326,894,789,264,721,485,820,702,320,261,315,861,67,648,326,293,824,198", "283,439,530,498,648,221,674,650,615,313,818,141,839,831,815,371,720,531,420,52,678,613,120,169,577,504,961,501,950,742,647,834,323,410,848,697,659,991,797,637,159,456,668,837,801,145,451,461,276,564,250,211,814,410,935,857,853,463,833,137,566,408,86,620,724,752,152,597,390,104,242,418,336,658,490,229,862,814,238,604,410,727,64,598,605,962,413,736,777,734,846,690,867,477,977,553,744,90,422,951,848,11,297,70,174,375,816,300,600,829,950,409,944,27,474,369,582,385,297,454,659,687,730,626,473,890,598,340,747,844,549,569,502,432,425,533,781,56,515,184,208,305,766,209,125,917,978,428,514,319,113,57,944,774,415,779,539,458,767,796,670,701,641,459,114,910,589,995,18,23,187,244,499,822,590,815,928,234,471,678,379,588,805,345,544,501,301,764,927,464,545,252,661,606,64,763,506,340,661,37,448,729,533,465,78,3,272,662,330,353,452,364,266,637,931,97,119,379,27,560,221,276,216,894,96,336,501,964,516,986,940,85,97,11,862,862,367,562,810,377,198,998,316,829,833,231,996,104,563,48,312,526,387,325,900,350,258,630,162,363,767,275,723,266,455,224,343,315,183,930,279,86,41,365,872,807,953,839,6,438,709,649,791,788,561,896,82,958,247,987,534,289,415,118,578,772,542,129,483,967,12,426,833,853,94,404,780,376,233,542,881,912,925,283,759,921,284,197,518,97,59,539,698,23,318,894,767,403,355,498,650,244,388,679,222,499,205,149,262,634,97,300,973,333,619,758,74,65,673,286,251,242,812,837,566,209,959,747,999,76,999,730,902,65,863,374,214,460,947,619,771,960,804,699,765,79,111,499,108,170,133,86,170,602,684,89,94,811,539,248,891,821,769,861,421,285,673,98,718,118,108,134,505,467,118,901,472,78,776,287,526,467,415,373,68,416,998,492,788,939,396,33,949,28,770,306,62,296,67,288,914,764,755,606,380,456,107,288,758,946,203,131,574,626,561,379,388,577,855,1,753,24,642,94,125,111,15,634,780,758,244,131,827,393,816,998,275,3,366,630,937,384,400,204,96,99,691,519,225,627,900,753,249,143,552,902,110,736,986,633,5,733,395,414,617,582,85,394,265,409,355,951,40,22,579,322,285,469,889,690,279,296,886,663,146,560,405,27,181,340,217,22,481,991,479,21,31,579,692,990,571,648,552,583,868,227,530,532,769,210,548,151,850,607,775,419,257,595,804,741,136,629,230,286,58,897,271,348,973,617,922,16,988,262,830,664,544,945,257,327,900,42,387,515,385,240,750,643,371,612,47,636,908,998,623,669,556,801,892,803,347,760,153,160,198,554,200,309,56,596,987,594,628,630,269,353,631,116,136,365,166,844,314,365,766,14,309,635,102,158,159,144,651,951,616,329,329,655,421,723,864,445,971,923,791,492,312,932,433,113,532,229,822,307,656,221,794,63,241,547,946,91,995,141,943,365,381,270,341,698,536,485,314,675,716,93,220,740,806,503,968,333,795,635,926,243,92,328,408,133,255,407,161,429,987,788,343,840,297,537,761,301,321,668,525,108,624,167,814,458,325,454,697,215,117,809,227,654,208,832,156,162,921,684,934,400,824,641,647,867,639,917,288,220,939,530,290,732,840,359,274,129,715,391,0,910,461,373,533,669,732,25,314,624,128,366,273,152,431,442,892,898,870,213,763,495,18,455,602,511,520,634,113,649,468,754,671,425,945,264,259,464,905,106,55,950,826,708,878,400,438,549,931,759,222,56,100,75,850,452,205,281,550,38,362,590,404,454,844,224,194,23,477,854,337,603,647,418,798,918,985,187,840,130,267,995,275,566,725,783,340,318,410,791,904,948,391,64,965,502,279,306,468,112,993,719,666,392,435,247,947,200,312,848,695,117,741,1000,823,393,702,221,702,414,955,951,379,354,281,501,110,171,293,766,587,723,82,743,569,394,29,33,285,887,524,493,465,213,619,244,257,813,716,742,764,140,879,154,485,899,668,244,434,436,737,196,400,30,764,252,505,694,965,614,85,457,894,874,980,971,314,799,883,465,721,114,51,688,328,289,621,933,993,397,651,754,459,41,608,103,754,670,605,748,711,222,996,198,271,356,753,617,579,164,609,25,114,955,821,502,38,437,527,281,242,421,967,246,346,503,278,853,210,854,670,799,628,699,312,228,913,712,362,188,575,753,932,204,874,51,246,33,306,993,458,399,930,578,988,767,753,552,47,275,807,663,546,252,348,831", "210,825,888,358,593,249,221,953,649,400,365,954,117,542,48,140,811,971,896,805,268,712,282,849,112,173,187,501,53,79,611,978,137,727,737,626,78,155,514,767,191,582,734,970,96,790,593,186,804,804,421,878,712,971,682,686,246,928,59,199,201,892,821,610,631,692,967,205,126,816,693,425,308,165,946,92,779,639,63,921,762,565,427,225,360,810,909,507,708,801,92,844,217,500,554,93,910,71,749,499,455,928,612,106,126,357,110,603,587,562,490,829,930,542,507,862,138,723,82,867,611,992,30,478,671,75,182,565,148,40,744,107,357,840,713,818,771,945,170,575,581,584,771,424,417,905,200,976,232,292,294,392,331,410,579,678,395,617,986,994,541,925,403,960,609,171,732,127,967,980,540,638,760,155,198,209,709,239,374,447,262,609,203,813,198,337,683,10,512,91,304,100,52,595,322,512,699,749,677,865,892,229,199,684,587,664,103,250,647,899,123,553,942,779,540,828,840,28,695,509,652,945,300,461,149,703,999,741,397,537,632,616,340,588,730,798,870,579,830,250,726,959,222,237,310,422,703,826,698,443,414,432,484,337,992,425,260,646,710,990,782,620,33,676,588,364,192,820,671,585,469,55,557,668,164,854,377,820,40,179,863,49,770,675,428,461,501,919,261,980,767,99,975,827,504,427,585,397,346,183,526,367,628,19,486,664,919,81,203,253,639,548,185,190,71,850,941,753,113,938,127,609,502,899,703,517,381,174,870,225,404,443,25,675,147,676,438,230,237,434,713,446,764,273,263,111,360,956,512,471,967,672,377,622,776,651,644,253,210,248,816,383,755,462,216,209,10,831,341,744,545,562,886,964,994,22,857,460,959,419,782,237,248,91,159,236,672,308,4,711,582,615,646,475,843,227,649,122,225,659,775,217,178,530,808,539,733,454,487,820,11,721,236,409,169,452,95,976,493,198,199,107,894,560,525,581,687,682,596,119,126,351,586,83,381,884,11,287,253,512,616,629,816,275,326,473,604,297,864,90,542,430,12,56,745,689,78,540,654,838,474,973,697,819,220,940,418,23,356,901,453,994,934,202,330,2,848,774,604,17,279,336,473,113,266,384,306,783,36,815,246,883,808,712,812,905,568,618,481,384,547,490,490,534,714,303,716,933,400,544,856,557,796,494,208,947,473,499,840,721,57,600,47,295,346,716,987,116,66,720,143,984,721,27,651,397,4,685,189,183,162,945,936,375,408,715,980,373,964,114,835,287,626,387,527,589,315,853,68,231,167,914,534,545,382,550,526,329,793,130,7,315,841,294,665,994,13,359,931,114,583,744,332,528,699,879,160,737,800,934,690,398,317,608,171,154,320,668,228,990,331,26,710,31,893,841,703,538,475,868,771,527,455,512,527,386,850,787,15,292,655,56,23,627,523,911,329,455,822,384,991,545,550,509,128,9,235,920,879,984,85,632,941,972,17,921,940,37,70,987,874,254,256,701,753,362,750,666,779,336,584,928,138,667,896,86,174,613,872,146,947,324,529,656,767,875,377,846,626,783,79,120,378,697,47,469,564,400,265,194,594,218,226,722,792,152,105,47,450,593,472,503,355,469,340,779,234,605,18,536,896,199,556,665,472,622,520,104,344,330,317,659,804,407,476,506,975,754,280,726,649,488,452,387,910,0,281,157,635,504,853,384,882,791,135,427,123,232,204,66,812,867,522,621,155,757,269,700,151,410,398,889,407,862,978,899,374,488,132,942,120,257,234,388,67,328,248,211,861,120,371,830,712,849,122,383,773,585,664,783,564,153,796,901,597,272,359,317,806,8,788,480,260,530,118,990,413,684,362,708,836,149,971,998,353,656,548,529,185,745,94,47,949,393,110,50,756,375,747,756,873,494,414,573,908,437,234,797,165,293,203,936,575,726,556,879,103,690,11,363,198,778,358,284,142,35,40,987,389,665,628,940,536,550,712,454,632,931,775,889,678,724,969,392,729,971,778,307,235,514,413,524,219,742,355,388,330,671,313,865,634,231,307,805,825,43,674,80,64,670,687,997,396,672,269,124,401,654,982,714,280,425,311,344,231,85,10,185,903,100,967,529,885,95,881,805,653,466,248,503,302,942,617,831,315,726,633,623,742,91,369,127,569,648,221,934,315,305,231,566,760,464,623,147,349,633,931,401,230,995,793,901,217,321,945,797,290,909,591,282,518,966,777,119,673,769,552,213,966,821,313,239,515,596,710,31,244,984,843,328,956,235,412,846,846,3,263,28,404,761", "5,45,346,847,792,131,426,13,202,726,675,99,404,226,809,900,519,729,948,200,834,531,341,217,343,426,836,511,127,351,125,520,127,359,276,268,41,770,441,41,254,644,718,738,546,621,853,149,111,718,733,120,704,501,753,994,510,177,920,129,882,555,435,181,952,873,890,247,630,247,349,599,63,437,875,426,814,882,147,862,834,908,504,235,437,724,200,707,142,513,118,555,337,558,418,879,474,321,790,982,635,506,488,712,205,292,486,212,33,459,996,454,264,75,803,211,781,159,164,69,111,661,928,931,107,184,997,815,996,661,438,48,64,569,518,452,399,280,514,94,585,154,486,236,70,513,445,359,810,782,355,318,729,782,929,969,919,988,326,469,545,914,402,488,551,777,213,304,800,926,826,705,251,929,759,705,610,173,845,459,18,891,799,567,385,757,949,687,328,936,74,708,394,959,462,599,379,485,677,532,155,986,411,362,46,377,173,4,826,990,638,499,590,27,419,958,28,693,821,551,866,528,172,907,497,889,857,576,892,182,759,452,493,913,727,521,707,828,572,54,159,429,617,940,794,412,767,541,24,828,448,659,692,167,856,212,724,793,814,362,62,830,171,885,283,876,209,738,707,542,964,664,150,338,59,36,968,621,266,716,767,712,174,832,56,654,108,927,966,814,109,479,804,912,659,860,155,839,986,332,913,18,593,119,36,173,699,186,854,709,660,533,530,751,87,817,856,543,545,353,853,202,824,280,568,845,157,866,301,760,100,790,463,492,755,736,143,879,819,940,967,858,886,681,945,278,955,919,89,310,952,623,236,97,766,533,449,862,817,275,598,874,128,301,70,106,998,631,694,693,555,643,243,174,434,487,530,690,198,899,599,775,714,424,125,941,824,802,442,970,69,485,918,316,315,132,994,717,192,608,775,729,638,888,683,446,84,985,773,32,728,744,660,775,83,690,79,651,875,313,842,728,882,373,442,884,747,670,287,854,462,651,112,647,289,147,826,149,966,879,160,477,12,347,768,781,548,213,977,387,343,968,112,573,864,557,71,348,869,20,596,515,767,691,353,407,474,439,109,869,876,100,770,94,949,712,730,975,602,540,620,721,726,32,496,991,374,803,482,263,236,874,748,627,409,721,269,787,392,57,1,761,113,27,684,419,794,110,506,686,72,933,922,863,145,528,14,604,524,477,107,305,711,986,985,342,630,602,90,168,856,631,181,520,437,29,585,150,286,225,64,979,905,707,541,974,429,875,84,66,542,560,759,882,658,658,980,58,110,821,960,377,636,628,404,463,579,768,407,78,177,52,15,844,902,767,464,961,987,203,431,862,307,442,277,940,255,598,614,573,44,795,929,494,684,537,540,918,356,478,721,940,575,429,172,565,671,259,5,942,359,354,79,149,848,738,519,106,150,368,890,221,640,76,221,943,408,774,42,292,411,275,971,3,946,530,490,705,973,694,913,348,44,787,403,576,118,102,228,248,168,819,952,924,193,939,953,617,522,638,556,964,441,89,119,567,603,352,753,116,267,650,416,291,357,596,343,258,282,404,959,863,217,200,965,388,430,506,481,241,803,66,944,61,903,61,441,778,816,84,366,747,645,879,498,102,296,902,324,845,245,876,96,743,784,808,185,371,804,169,55,647,913,575,731,210,542,413,334,758,74,311,980,936,461,281,0,123,968,381,206,969,391,977,916,490,685,396,488,359,242,383,867,699,259,388,576,332,597,209,640,434,449,372,436,663,171,818,429,719,251,772,230,920,863,653,115,178,410,780,31,500,724,243,805,266,306,191,959,510,294,448,223,963,386,14,858,393,703,585,369,209,177,640,710,630,692,296,817,989,771,930,7,606,269,952,101,148,187,65,338,760,171,215,688,175,680,854,575,420,234,810,723,896,164,25,249,255,803,122,637,429,197,151,907,66,246,385,305,355,400,129,878,82,465,627,746,920,51,691,588,805,743,916,203,350,171,230,279,745,656,129,984,30,845,736,498,973,659,236,400,119,110,986,630,500,974,670,117,802,741,106,702,888,62,20,944,841,689,777,969,536,702,694,125,550,903,520,159,93,975,380,100,312,789,465,188,72,843,661,553,270,838,890,629,18,307,597,433,255,707,621,279,361,365,560,614,7,542,595,687,589,132,651,744,452,378,570,622,67,489,333,812,806,253,964,910,921,322,922,568,443,560,817,900,1000,681,809,372,63,304,774,910,662,399,62,399,66,151,316,34,395,329,954,473,109,426,312,656,317,51,400,659,481,814,116,462,987,437,494", "131,208,67,895,626,967,628,720,330,851,20,559,231,561,303,490,496,121,93,937,860,333,627,418,613,579,427,827,407,396,759,223,722,218,284,814,878,405,168,595,706,25,176,896,911,70,904,792,870,890,40,681,870,952,853,10,524,526,182,522,761,35,895,602,407,596,248,656,9,227,529,645,422,245,216,839,560,826,56,330,612,101,524,422,754,960,630,510,353,111,137,7,691,628,355,290,777,714,832,370,140,878,804,652,480,410,229,628,182,859,125,392,799,382,997,455,435,461,972,66,891,300,54,459,449,728,673,502,665,114,948,17,28,630,538,68,166,574,954,903,691,357,848,943,604,769,663,628,700,550,469,51,573,561,659,969,826,964,160,85,182,928,7,295,7,533,31,471,884,210,184,430,485,238,647,145,169,584,409,217,706,530,99,416,775,671,811,23,404,828,320,551,539,80,608,125,301,567,945,818,705,268,666,396,407,408,86,769,200,669,753,862,255,481,206,917,252,627,562,585,591,342,560,579,314,210,399,132,978,283,389,145,775,569,487,297,903,668,327,28,984,986,421,950,223,273,665,714,368,325,66,153,373,595,546,101,112,319,527,36,737,821,38,306,632,444,885,980,292,809,715,113,500,378,570,379,998,271,345,46,195,742,28,434,715,262,432,80,886,558,671,608,628,183,431,811,81,840,252,6,954,393,378,540,998,547,387,52,372,639,259,646,587,164,924,533,896,254,642,696,22,486,393,862,409,565,556,462,553,618,763,511,957,948,944,449,671,32,144,797,800,538,886,221,354,678,173,115,519,979,857,889,632,166,125,382,746,345,581,996,63,698,72,885,18,962,559,943,679,516,317,490,213,480,395,159,572,174,697,611,287,771,729,656,252,237,122,25,163,123,794,851,877,980,997,294,766,858,487,673,986,990,428,299,515,571,952,758,571,980,709,988,403,186,797,618,46,190,670,738,166,38,978,461,114,293,566,595,915,838,209,401,86,331,151,349,699,277,673,999,678,581,105,484,308,161,153,206,872,111,436,339,388,351,695,636,101,424,295,993,767,873,779,848,363,104,375,611,991,501,163,753,208,849,752,31,454,307,864,139,342,65,792,21,293,216,213,926,93,826,780,563,268,721,326,589,874,547,172,823,824,915,175,771,75,977,624,183,118,962,859,602,225,413,69,450,565,757,122,690,329,71,381,157,241,557,561,790,696,919,490,811,209,782,853,112,564,929,1000,391,518,22,389,457,686,698,766,553,69,105,749,466,638,75,839,159,282,562,614,977,186,429,831,997,130,161,99,690,225,992,141,362,753,836,391,485,268,79,453,218,376,974,868,902,253,911,21,754,569,47,514,112,442,255,141,551,130,278,190,323,716,188,372,134,834,169,289,394,896,261,868,647,332,860,91,13,134,317,672,767,60,522,144,253,771,4,176,732,393,599,901,96,836,405,460,736,479,916,545,502,883,259,317,95,596,261,169,771,609,232,20,247,205,660,410,431,791,56,952,600,288,206,335,104,999,291,439,449,92,442,396,473,28,619,640,341,119,6,586,753,880,744,660,494,343,234,262,931,186,451,65,344,937,525,152,500,627,582,419,570,893,88,920,687,207,690,76,49,299,277,769,690,644,659,201,366,392,257,46,97,855,879,56,132,69,382,975,378,814,301,737,645,398,812,373,157,123,0,807,406,263,205,826,509,393,724,621,312,164,183,3,350,168,532,122,765,522,519,190,2,665,533,804,282,6,291,271,998,461,957,498,663,371,712,819,242,178,226,983,583,718,498,633,829,77,101,807,916,186,632,384,211,429,698,659,957,734,581,172,408,832,46,755,261,118,466,330,734,42,174,313,373,184,961,181,476,311,710,966,481,340,882,458,421,903,684,459,751,742,805,82,821,46,660,556,754,704,926,884,408,383,686,220,853,104,366,711,70,385,831,404,125,218,557,62,972,950,185,579,747,479,252,963,488,174,872,266,57,64,61,675,752,791,796,703,465,622,585,932,738,395,514,695,866,198,678,704,400,238,272,797,158,583,566,303,87,475,559,572,586,422,240,938,655,304,296,389,480,228,692,707,522,411,903,896,733,457,276,557,521,986,306,577,27,766,636,769,470,291,538,573,548,574,457,228,89,701,176,121,60,164,297,504,639,742,724,831,328,382,320,243,691,776,842,211,702,281,51,726,449,584,106,176,380,651,759,547,361,837,536,626,640,765,431,986,620,795,875,384,764,415,155,986,954,708,197,570,541,883,417,973,890,233,355,2,189,345,113,172,12", "117,249,264,906,755,433,639,726,118,599,981,36,260,954,293,456,62,769,572,568,70,938,168,665,827,620,287,837,734,522,656,554,63,920,809,595,497,690,51,837,415,626,800,559,474,577,580,489,734,781,854,47,738,780,680,527,219,300,554,978,293,921,426,927,870,468,564,583,321,579,744,744,107,377,767,625,666,146,230,462,828,783,124,754,668,933,466,113,390,217,967,7,326,981,3,627,813,130,94,883,971,108,326,600,572,819,249,125,918,991,440,943,270,651,277,204,473,875,746,384,161,609,923,276,955,683,458,325,398,444,986,196,25,337,22,663,851,572,260,172,535,830,853,463,619,12,152,140,367,28,996,736,965,134,648,952,624,302,467,476,628,958,535,59,290,533,296,593,638,64,623,573,862,622,866,923,82,958,194,945,138,481,378,260,331,372,680,594,2,344,505,881,926,107,525,209,787,648,848,473,151,123,843,691,166,173,751,799,131,503,267,264,417,719,597,264,809,644,361,66,915,959,252,383,433,540,757,959,738,968,848,836,855,86,874,287,580,601,526,499,779,378,829,886,187,166,420,186,228,664,180,748,842,335,962,497,291,48,270,932,702,667,307,31,254,19,920,155,540,729,816,522,14,229,1000,186,990,866,533,390,85,119,663,174,613,992,715,829,545,115,124,486,383,974,257,643,95,271,687,485,80,655,288,289,103,647,256,88,431,420,834,150,956,36,346,405,781,119,119,693,375,691,528,590,313,977,605,962,160,868,90,865,57,618,508,566,800,614,556,329,163,328,949,220,125,690,725,450,570,442,230,260,403,335,238,976,181,874,584,740,35,201,670,47,750,775,961,758,774,88,389,7,862,175,648,68,342,461,13,340,4,153,778,168,82,305,791,497,105,80,672,401,493,910,533,205,218,787,189,89,406,625,717,88,956,762,83,964,416,856,601,717,111,624,442,938,358,367,25,318,110,559,320,695,741,272,731,118,826,328,411,772,220,622,747,4,779,848,152,186,725,308,705,635,237,927,84,721,61,283,599,476,178,565,375,346,314,397,16,563,951,771,449,546,768,217,468,271,613,472,54,331,665,20,182,298,75,849,634,806,189,198,85,428,51,949,129,11,577,19,652,20,870,60,629,709,282,81,784,859,56,558,947,627,105,189,860,146,150,935,753,99,562,943,885,143,200,549,481,217,159,925,416,645,581,149,539,331,640,658,691,377,85,387,801,717,667,751,404,187,444,153,35,617,772,485,27,803,563,355,647,908,485,230,569,998,472,160,221,571,838,285,683,882,51,610,849,844,968,507,274,373,949,926,429,561,707,564,754,771,538,494,247,516,297,863,21,297,695,187,860,482,708,593,944,801,760,291,45,738,232,517,758,243,28,716,587,139,476,852,99,760,419,438,283,231,926,362,781,287,921,591,788,77,467,724,680,175,575,123,783,517,530,126,930,922,982,391,190,194,781,738,550,655,364,277,97,167,383,133,979,737,983,203,11,791,864,746,442,829,284,783,101,642,69,276,527,594,755,739,62,648,836,201,534,392,607,71,648,438,393,476,956,918,225,505,146,917,848,915,857,700,403,60,45,999,771,848,770,49,140,534,882,373,160,983,655,270,202,293,739,327,339,853,100,232,753,506,603,11,954,682,728,220,570,743,351,586,500,248,157,442,724,352,533,635,968,807,0,17,724,356,336,602,119,170,145,191,247,382,973,400,570,80,122,267,436,300,128,747,96,263,145,368,233,631,592,359,834,942,572,551,503,216,137,833,527,171,945,834,683,209,374,78,941,49,519,850,238,864,913,440,23,200,987,824,125,464,951,808,758,82,680,989,518,885,804,272,448,919,738,899,47,274,410,260,127,992,442,762,123,545,150,621,943,147,782,197,668,866,789,155,615,473,390,606,813,587,48,287,354,318,71,59,306,732,16,469,528,320,824,649,771,564,282,731,195,215,710,167,128,238,859,808,709,253,219,201,694,605,45,39,752,732,580,297,562,606,318,362,489,345,954,277,24,532,36,394,351,272,570,661,410,966,825,763,371,126,686,869,813,259,851,800,241,392,454,107,357,201,466,583,302,939,530,805,268,210,687,786,396,381,455,203,333,899,104,884,246,838,831,556,388,768,86,68,450,730,869,902,126,748,255,623,122,908,267,225,264,632,420,396,752,902,984,323,346,514,162,652,816,355,50,771,199,377,276,921,906,692,675,793,776,160,709,805,930,493,882,828,516,626,343,84,351,659,219,536,785,210,624,739,627,854,388,303,278,273,798,62", "978,63,744,570,535,694,467,657,847,931,762,988,465,499,187,753,151,307,527,523,466,631,981,824,19,481,694,350,258,335,204,858,532,378,674,500,966,842,667,799,987,858,233,460,592,219,555,376,670,835,186,741,563,162,428,247,167,647,195,505,722,76,599,947,773,529,814,650,268,756,88,593,913,783,306,418,886,691,818,208,245,876,969,689,396,818,964,150,500,326,995,30,922,263,514,474,609,478,116,914,235,288,119,966,623,463,881,661,323,536,105,832,932,169,715,556,547,908,167,214,352,497,855,203,88,754,50,113,276,321,979,943,734,928,903,30,139,19,561,469,611,388,925,368,633,989,395,827,248,447,498,219,394,918,900,700,591,461,433,524,860,904,452,822,919,174,748,730,562,215,439,537,903,243,647,529,809,577,514,309,668,819,479,287,740,136,460,749,172,175,962,296,987,371,308,808,607,758,242,279,360,652,999,57,720,491,983,55,552,6,41,795,82,827,559,540,655,386,440,462,384,75,231,471,776,740,31,537,407,615,173,911,744,267,186,273,585,771,20,126,127,529,519,671,701,64,456,685,887,397,97,312,811,502,475,513,543,125,242,96,628,303,658,577,959,855,665,279,640,271,718,565,266,874,105,990,856,148,96,234,101,426,490,411,491,578,897,224,723,581,555,549,182,600,129,769,729,817,551,484,446,37,333,315,818,767,214,705,224,487,359,347,644,485,793,238,660,245,250,171,43,947,505,721,706,730,436,321,469,999,845,353,557,435,182,727,277,440,748,926,278,497,777,613,412,798,773,403,87,864,372,967,492,443,386,909,195,568,5,222,42,92,361,581,648,755,70,89,701,597,469,46,717,413,609,77,511,908,977,622,857,571,278,954,511,4,289,804,919,55,452,954,750,878,303,241,584,804,817,154,842,104,607,158,286,98,785,890,230,693,132,309,343,256,674,798,43,357,389,651,732,370,4,36,683,128,657,730,466,286,636,357,17,361,43,926,649,223,510,338,355,801,408,276,714,409,901,437,664,974,229,485,891,556,651,514,33,799,291,508,487,517,434,996,419,119,996,853,861,35,644,51,196,336,980,613,587,626,445,363,8,333,993,771,695,949,308,849,632,169,523,477,251,205,411,912,340,104,556,434,714,566,903,235,712,580,846,929,171,48,550,703,168,276,503,249,228,501,76,623,867,751,864,716,248,83,585,416,246,744,628,549,205,702,980,237,440,107,361,675,592,318,637,486,563,427,276,217,704,439,689,582,163,304,667,977,432,169,178,869,655,263,931,127,124,804,61,658,353,353,13,577,204,794,720,193,67,8,354,543,363,912,571,471,393,833,123,128,920,490,176,647,290,713,216,965,45,683,242,904,859,993,890,216,482,75,414,673,596,671,207,611,150,426,266,759,757,886,821,847,979,831,360,165,84,543,856,140,290,315,930,691,882,175,547,920,764,995,114,239,344,96,166,416,795,663,783,115,11,103,991,29,657,442,380,969,170,817,430,933,848,372,215,658,99,919,185,162,94,198,509,591,889,668,408,909,987,126,144,324,439,410,517,782,110,222,876,774,850,714,446,342,543,895,909,283,215,6,284,62,251,241,275,978,953,651,129,244,12,71,769,737,84,126,350,976,308,741,612,814,797,864,542,539,903,8,558,228,365,749,817,401,819,636,669,504,381,406,17,0,192,371,858,652,158,844,113,478,721,419,991,212,875,405,798,613,665,583,722,671,951,12,984,963,200,400,160,918,995,81,683,416,632,633,803,718,331,586,465,79,699,818,920,239,262,193,463,685,66,914,776,164,627,428,305,464,536,423,564,737,292,329,630,509,55,440,719,147,132,491,622,176,971,888,804,717,729,220,370,99,84,370,152,649,195,174,546,742,659,789,483,408,805,974,703,189,699,668,374,810,784,249,731,700,857,57,682,549,880,775,318,517,490,801,818,30,717,932,54,167,793,602,5,340,675,833,927,160,654,460,394,989,907,389,555,652,634,356,397,494,846,860,295,11,194,556,568,946,616,608,69,435,128,471,400,410,971,140,463,421,926,455,828,878,532,425,504,897,629,690,191,686,586,696,190,24,826,719,698,641,509,968,46,800,610,90,26,978,347,346,962,457,697,958,551,391,325,778,41,167,347,172,338,951,795,701,193,886,545,358,429,830,818,401,420,463,74,594,317,734,821,958,754,107,450,118,439,572,176,705,290,35,268,566,221,217,500,437,712,874,95,117,160,31,951,323,269,581,33,763,824,285,258,724,840,952,469,66,681,169", "379,468,772,936,235,240,614,950,346,269,557,550,128,269,894,896,841,964,742,945,267,967,7,759,37,969,390,347,913,716,433,632,139,716,690,594,869,49,173,931,587,392,610,140,32,858,141,808,143,316,123,284,903,850,963,412,179,745,836,159,434,367,563,450,388,708,706,519,981,453,300,240,376,279,610,689,143,318,113,768,55,922,406,293,845,444,613,68,409,486,589,873,559,797,347,831,585,452,77,602,7,786,461,5,942,202,666,357,569,136,921,357,41,104,6,707,987,63,287,252,227,161,244,994,837,512,528,387,287,898,505,188,844,509,85,249,617,344,432,127,421,718,190,15,252,418,661,707,592,12,648,573,629,860,793,542,734,440,190,710,137,864,237,71,922,560,785,513,229,182,733,561,352,295,696,953,463,229,575,29,2,460,597,235,12,271,853,680,974,426,906,936,51,848,557,327,857,170,908,510,293,783,999,269,296,740,248,312,776,216,144,991,419,668,764,286,602,262,463,34,566,39,384,411,165,915,132,21,209,776,948,18,949,589,15,94,5,908,204,448,852,193,985,3,263,995,756,399,303,789,696,110,738,33,65,653,961,382,301,449,86,909,235,710,649,636,742,103,927,884,954,603,882,787,876,182,657,270,469,769,790,474,264,642,636,851,569,732,834,64,708,746,532,255,407,988,290,216,632,163,707,378,956,745,19,633,811,615,107,321,818,847,177,260,486,952,44,420,581,561,313,78,797,692,982,36,307,412,221,619,649,393,306,206,72,550,937,662,209,187,489,870,609,900,776,773,430,197,13,300,939,263,698,869,414,685,218,474,137,836,244,633,122,781,240,352,183,239,537,983,877,945,712,680,216,45,457,165,814,424,346,541,127,920,990,410,253,835,79,483,264,156,200,258,341,57,135,368,849,266,8,390,329,29,195,966,185,882,557,156,430,145,496,841,804,523,229,131,930,219,244,881,348,5,135,685,23,401,817,305,974,66,945,333,893,200,67,299,47,591,700,528,65,203,115,958,775,75,32,600,112,730,751,616,372,260,582,872,517,12,106,696,10,886,597,963,794,39,884,370,921,693,661,517,124,376,825,208,169,102,96,532,209,646,917,761,737,632,401,25,411,345,522,715,922,549,754,350,57,154,339,381,620,459,843,967,718,633,164,87,564,640,968,26,708,820,208,362,319,169,429,365,795,873,55,16,685,43,88,273,787,808,493,456,365,898,420,621,658,214,986,306,327,930,884,340,526,85,225,752,979,186,235,718,952,108,11,453,967,434,130,525,312,758,74,669,285,84,117,482,779,22,387,379,52,919,46,775,783,976,987,635,206,652,244,159,904,430,927,597,575,937,694,939,938,687,375,353,874,280,237,942,71,207,651,964,928,675,312,654,79,136,341,178,501,258,943,61,738,370,286,459,598,474,46,925,344,263,829,639,899,318,617,930,514,331,693,266,640,373,919,892,916,903,574,777,60,963,663,150,883,40,389,994,93,955,250,753,66,300,413,183,612,310,94,58,784,63,71,542,313,783,200,772,234,53,693,485,354,328,109,591,210,29,978,509,296,543,249,737,417,316,386,18,122,170,600,368,314,139,907,115,721,384,563,72,170,637,749,210,586,270,611,613,89,176,436,376,251,484,69,685,208,279,919,675,493,741,313,562,585,287,810,792,732,853,206,263,724,192,0,904,9,643,139,76,794,738,905,430,909,683,645,250,888,721,638,80,838,147,371,171,420,879,328,948,251,80,26,738,866,768,873,562,270,167,189,693,419,908,580,289,263,810,239,48,323,246,909,561,559,431,733,300,178,197,228,58,110,816,550,138,605,762,888,244,710,969,173,885,72,530,722,367,920,498,779,137,608,48,351,77,992,391,551,416,766,999,672,722,747,403,953,863,50,448,343,621,983,748,70,926,484,658,161,173,225,86,231,940,165,464,751,539,439,606,439,597,819,304,216,652,309,172,459,823,673,618,263,142,886,196,826,671,172,520,503,876,517,97,654,37,426,517,921,558,627,105,565,384,330,539,548,598,977,424,34,425,850,354,311,480,82,549,423,752,480,213,517,312,65,545,535,860,394,444,631,890,548,702,850,715,251,941,469,651,661,776,926,445,814,836,668,312,252,279,665,490,115,362,839,573,356,281,163,855,738,739,212,26,636,339,388,672,526,676,140,163,708,420,235,737,275,678,673,184,364,670,60,611,796,644,450,5,718,796,97,615,681,739,795,709,173,389,998,991,236,494,716,224,826,654,555,400,684,640,503,53,871,395", "488,764,726,826,739,856,480,637,913,213,244,603,517,969,446,874,880,473,953,941,523,989,14,65,222,526,810,427,817,509,823,484,989,527,392,40,301,599,711,997,578,253,313,549,840,240,299,452,455,563,106,389,47,244,641,524,337,295,125,496,883,900,712,388,706,893,312,343,167,240,280,199,948,724,114,670,964,671,606,234,730,280,152,382,716,79,516,207,358,428,542,768,976,962,827,402,619,559,241,644,382,241,457,719,495,729,296,123,773,521,726,395,309,405,228,508,781,315,756,288,706,826,278,316,542,997,112,342,270,1000,609,140,272,888,621,216,258,700,795,695,5,120,995,81,774,284,998,122,592,967,30,890,129,365,474,732,555,763,286,569,302,470,245,578,456,251,324,931,230,150,853,985,31,567,956,401,669,797,77,361,80,564,723,634,257,116,851,896,821,998,89,767,713,294,682,358,952,191,326,422,808,846,450,851,624,372,858,358,582,693,254,278,349,394,569,460,158,770,712,805,942,274,667,774,986,2,198,544,124,886,370,935,406,3,780,913,289,655,145,146,371,485,516,77,905,663,443,165,156,479,548,299,418,566,826,744,473,189,766,286,51,195,684,495,137,609,989,978,314,343,613,117,220,545,228,147,973,966,298,978,225,578,778,883,273,43,561,932,321,965,112,927,671,493,441,255,767,872,114,609,221,192,947,460,268,113,591,296,306,975,487,836,195,461,878,454,519,159,481,311,579,989,510,298,259,662,611,945,431,632,263,787,61,737,116,912,207,539,210,789,493,366,139,266,675,441,890,20,393,870,958,672,516,784,547,563,422,189,699,133,42,60,359,944,609,818,155,872,89,355,7,888,586,134,865,13,506,383,540,234,998,531,585,486,704,361,902,333,252,498,825,86,254,603,835,333,191,916,989,488,931,909,711,238,469,439,643,369,884,27,604,65,681,266,492,449,937,471,690,981,213,362,949,95,894,650,693,779,545,716,694,967,90,360,206,35,228,814,750,557,46,303,689,40,323,85,731,241,663,918,507,91,325,788,87,291,673,759,870,65,851,472,287,259,53,293,215,880,488,903,276,102,350,975,929,339,642,661,455,188,831,313,177,926,205,373,160,672,411,954,556,383,647,236,94,624,823,476,516,335,967,892,5,107,914,797,556,603,154,777,40,673,632,572,210,144,780,689,727,341,213,481,650,889,100,356,220,392,185,457,152,31,179,857,12,712,874,156,684,876,636,100,113,515,114,106,999,950,230,703,777,403,598,969,556,137,904,174,261,489,576,137,797,522,660,619,923,66,316,146,721,38,502,323,517,799,758,226,956,940,330,509,551,54,405,801,320,146,584,838,824,339,153,297,984,385,557,701,672,141,172,40,772,588,954,431,774,40,903,554,35,536,820,749,692,579,837,992,607,102,258,917,293,679,411,247,421,595,798,826,57,476,269,995,419,614,927,424,526,459,174,305,27,860,9,876,921,2,887,357,112,253,882,591,335,50,863,461,257,308,41,481,731,689,916,211,138,536,892,68,708,199,417,465,276,589,302,272,168,384,9,927,709,218,169,150,581,526,318,965,2,728,275,281,602,417,616,972,66,953,779,202,270,372,643,453,167,878,272,333,589,874,807,255,582,292,483,488,117,826,174,356,192,348,260,260,984,152,350,883,106,692,647,59,25,384,969,205,356,371,904,0,970,457,205,774,60,826,819,140,949,879,388,870,390,103,234,430,755,51,10,972,568,878,728,137,422,333,104,633,359,419,962,324,596,888,225,511,792,675,307,201,529,148,302,943,475,750,189,651,255,922,688,584,445,838,122,120,617,882,885,491,776,73,734,151,63,590,650,332,836,586,391,450,907,102,914,142,770,905,570,107,786,423,369,460,277,514,179,371,926,855,508,734,381,703,165,66,161,746,115,623,20,628,52,200,627,914,481,912,473,410,189,950,476,490,580,221,299,262,325,986,682,442,172,871,728,858,394,833,114,202,697,447,298,603,66,78,151,129,430,702,157,133,311,571,639,590,33,653,860,78,531,768,748,377,710,945,407,822,905,743,667,805,757,909,850,458,129,480,35,547,457,739,967,767,468,552,575,774,402,517,560,152,666,519,513,818,832,931,4,72,966,670,993,726,502,727,928,376,27,138,576,967,417,187,259,605,134,774,106,275,82,934,895,809,781,748,29,192,311,187,336,691,525,56,942,282,4,899,562,483,344,691,801,460,979,120,777,564,713,446,846,661,847,463,191,69,519,351,472,787,600,394,340,987,964,947,888,501", "392,594,838,397,8,553,89,591,649,940,362,81,464,163,463,504,375,790,672,932,233,416,820,316,735,65,111,400,117,712,183,794,34,566,519,189,28,339,945,304,402,759,777,346,716,911,21,379,899,897,933,23,292,622,479,268,106,703,956,366,597,72,926,949,809,365,516,847,928,56,119,806,672,900,594,755,676,3,292,953,52,219,698,334,66,816,227,288,556,90,973,501,742,76,333,849,246,306,817,810,87,504,789,895,954,476,21,441,996,242,852,649,714,909,857,323,404,133,353,812,157,538,662,171,591,920,945,519,173,544,930,447,763,736,275,879,887,227,138,858,780,481,481,677,799,430,116,568,162,27,731,88,455,73,223,404,760,759,11,612,485,917,974,201,738,835,474,916,615,989,472,433,14,329,343,324,74,175,354,426,308,883,519,882,217,906,761,792,849,616,811,548,105,333,490,484,105,232,199,512,398,569,635,455,648,915,76,599,560,18,861,660,3,188,16,938,889,329,811,336,481,631,325,677,549,801,90,388,993,479,900,795,941,874,271,348,737,4,459,91,186,93,20,312,208,378,911,783,349,790,493,989,791,423,953,211,362,629,376,286,105,173,411,351,44,503,436,581,800,80,742,775,526,776,576,374,82,642,155,448,894,113,914,978,240,778,268,219,921,263,14,723,67,886,277,67,802,412,755,635,512,754,436,963,525,638,186,866,634,149,188,110,537,798,364,528,534,847,919,535,384,20,370,403,279,257,132,653,310,12,543,154,803,762,944,61,257,948,188,504,336,408,18,483,944,254,387,65,562,419,560,200,770,76,474,69,456,752,569,253,90,14,941,737,318,412,196,803,677,450,507,991,425,414,182,195,476,799,289,64,331,907,760,235,633,137,400,819,855,425,140,453,236,572,101,925,52,955,429,517,999,125,724,32,435,706,281,798,278,299,275,829,419,691,637,594,886,264,892,629,638,945,928,322,37,267,294,905,520,661,901,500,32,479,409,767,893,574,911,555,818,55,878,962,198,15,454,55,816,954,685,503,261,379,251,612,225,683,431,794,536,761,107,777,243,803,81,719,457,834,533,407,919,712,744,382,24,388,382,619,82,153,331,250,556,443,652,210,422,919,91,594,104,207,528,220,733,3,818,954,691,339,477,369,683,745,82,879,969,623,56,149,441,648,171,491,883,180,649,541,912,447,439,164,377,63,237,91,123,995,987,839,929,79,299,745,295,698,294,408,642,857,883,971,98,40,401,320,905,146,454,977,614,479,823,339,294,425,505,732,30,148,529,794,854,287,634,688,185,543,878,89,911,95,230,445,805,623,359,814,487,587,532,921,12,665,286,454,393,528,283,110,371,84,877,760,233,471,296,748,838,853,654,178,722,838,474,256,706,5,910,236,739,979,917,587,762,30,387,918,729,750,858,871,954,159,231,954,585,917,492,881,498,113,406,650,56,493,128,741,858,836,888,259,515,713,402,23,244,267,805,758,170,899,868,561,787,114,123,998,704,139,238,403,594,345,458,403,786,301,937,900,101,808,132,156,86,512,547,193,812,935,251,458,954,856,596,325,5,575,81,869,266,57,675,904,978,607,381,461,468,930,416,713,2,886,428,147,32,898,40,429,906,562,551,148,921,497,289,199,388,275,34,524,21,551,172,484,208,145,801,13,7,619,314,882,391,826,336,858,9,970,0,409,985,603,386,636,111,155,543,363,712,228,41,626,563,445,362,695,2,714,657,544,116,503,509,646,15,689,65,106,23,853,513,546,236,411,188,88,829,425,990,839,46,22,459,783,709,558,417,431,920,950,869,69,573,640,608,87,411,910,388,492,292,637,958,282,714,861,973,86,711,452,911,494,661,542,490,284,73,304,790,675,880,714,242,225,681,25,549,23,719,635,215,771,475,599,826,405,907,231,659,243,722,147,54,822,717,273,574,605,526,136,364,961,25,764,304,705,380,264,191,184,945,666,179,569,616,155,778,758,82,854,409,64,339,350,265,283,722,995,640,540,520,212,718,203,829,300,358,548,895,82,446,400,643,5,433,196,155,717,566,26,535,178,727,396,617,82,25,743,947,8,128,249,919,469,848,202,291,352,949,784,751,748,86,323,218,187,585,223,284,197,23,350,656,851,465,430,212,306,74,538,506,353,942,314,465,663,891,430,940,532,996,891,301,960,526,664,113,714,307,345,913,120,968,319,403,622,935,860,168,159,475,696,188,366,661,343,652,31,729,41,471,456,363,389,622,284,264,728,430,415,307,746,191,120,351,251", "649,90,590,333,808,22,777,669,780,984,998,497,783,133,364,445,881,746,625,612,760,700,596,262,199,958,781,230,969,648,237,152,862,387,654,182,483,674,113,693,944,512,332,762,427,675,616,469,13,312,809,997,368,974,684,517,347,408,730,795,538,998,22,223,374,170,775,893,219,350,617,185,886,255,443,423,732,965,800,841,714,111,211,461,632,323,619,444,441,923,165,572,341,788,56,649,800,833,795,954,504,897,500,983,249,845,123,770,468,50,283,64,911,145,143,11,78,458,507,703,181,336,609,793,504,96,971,460,881,234,427,72,376,63,100,784,127,832,698,15,192,472,167,674,44,78,470,490,302,520,577,974,861,550,157,30,320,107,358,526,992,897,341,335,845,145,110,947,279,789,559,899,485,185,893,804,413,800,264,78,841,806,265,977,242,250,151,75,736,931,806,14,210,36,485,221,463,938,10,198,558,710,198,484,512,443,644,768,420,77,789,788,7,595,118,392,885,718,884,341,700,559,911,659,291,365,694,890,135,545,614,882,199,354,485,199,197,921,920,212,660,703,692,599,535,90,329,375,507,649,575,673,819,426,834,895,808,888,184,874,314,32,202,606,878,352,814,367,143,462,175,605,932,598,181,855,197,142,417,782,794,819,361,74,54,356,173,930,230,610,183,372,46,569,67,872,371,348,599,275,601,104,89,268,468,307,245,789,988,878,440,599,324,898,334,379,577,517,82,289,657,323,721,126,71,101,889,377,521,281,940,846,398,202,420,166,731,869,687,34,336,506,295,743,825,566,899,197,472,724,90,106,233,535,894,690,27,265,844,500,617,119,875,1000,214,54,990,322,47,683,29,445,711,435,995,625,958,567,175,826,30,722,358,876,682,250,490,263,199,263,636,206,985,785,720,177,542,326,600,822,926,130,79,750,827,826,403,974,144,993,95,466,117,12,575,625,216,104,308,156,724,168,566,468,860,186,597,644,242,710,786,812,384,401,168,110,425,687,601,450,822,841,840,474,498,538,67,728,521,331,551,618,321,261,391,95,733,214,202,110,966,645,124,795,159,196,21,553,291,665,821,586,465,984,410,131,752,565,45,594,69,312,831,934,635,760,338,606,905,120,664,294,536,911,734,380,11,308,924,85,261,88,554,179,384,331,881,14,314,444,665,266,637,180,564,772,595,56,447,142,200,772,864,34,474,830,70,935,10,688,593,369,705,949,545,926,135,200,427,795,181,793,684,77,485,645,24,245,749,531,739,892,946,448,938,873,577,752,20,297,96,165,918,126,886,297,340,356,738,941,331,66,299,743,161,605,410,551,771,660,541,508,609,328,388,339,71,17,402,1,352,745,580,470,104,865,63,51,940,571,77,134,424,248,640,763,140,818,194,469,327,868,278,716,135,607,902,720,348,830,389,329,344,295,460,174,689,56,597,124,242,581,572,806,786,19,142,990,155,355,737,310,404,293,165,431,822,627,816,838,92,868,276,221,644,929,505,343,687,301,36,512,265,63,27,998,210,151,215,132,146,440,111,429,572,95,392,231,27,584,464,498,882,478,810,719,674,933,30,888,530,938,13,901,128,364,608,243,204,388,939,175,655,751,799,582,551,620,615,968,48,93,806,551,508,257,249,944,34,2,716,986,571,924,323,833,933,314,747,13,981,605,426,110,624,791,977,509,602,652,643,457,409,0,267,437,522,149,195,215,790,463,479,854,722,315,110,593,836,78,342,485,282,642,855,287,4,113,679,625,914,739,808,476,37,867,293,144,647,683,957,851,278,164,517,904,398,327,420,410,599,94,862,807,307,451,454,167,864,812,348,329,658,505,338,633,52,662,200,649,853,865,742,930,309,153,972,182,624,412,300,316,693,342,848,599,63,904,853,139,981,689,146,164,145,979,77,829,1000,743,722,79,475,600,647,864,26,618,694,272,522,726,117,450,314,835,923,36,48,561,263,703,683,298,103,652,782,952,382,631,178,728,368,137,641,932,434,561,447,128,977,657,959,454,29,174,684,956,230,455,662,702,998,78,145,463,304,945,504,755,652,969,342,575,333,910,53,379,114,66,26,345,200,62,769,861,478,13,62,863,435,723,254,154,273,230,622,689,150,820,250,349,834,17,910,672,584,306,902,101,740,521,157,699,102,117,348,561,394,195,147,660,429,572,563,564,826,819,877,296,968,872,48,410,681,927,845,261,335,281,680,121,659,957,253,100,935,910,512,288,150,759,40,825,179,79,787,862,327,967,234,899,772,46,11,614,628,440,752,627", "951,745,964,62,65,91,903,814,750,133,915,495,577,937,395,969,578,751,463,88,456,352,569,605,106,14,677,451,761,912,143,392,489,218,697,813,801,805,425,687,428,258,358,735,302,450,686,554,974,274,383,646,582,958,719,293,232,890,354,442,173,602,640,357,846,171,269,410,634,229,245,69,631,310,119,770,625,129,158,826,955,13,410,18,41,414,893,626,710,776,982,802,952,944,176,107,336,719,975,80,815,453,302,164,143,884,977,385,745,305,420,36,749,491,566,637,9,182,549,745,716,522,318,203,817,855,232,481,908,131,841,485,698,905,979,497,569,629,755,427,747,462,878,632,8,641,204,709,227,232,266,137,320,22,399,620,300,482,917,910,61,869,820,438,258,276,135,937,180,668,142,425,235,615,231,698,747,38,698,401,964,792,360,392,635,520,647,762,414,983,160,193,983,516,151,450,222,323,469,227,457,420,554,712,715,605,252,815,731,974,831,24,728,617,262,84,140,825,291,398,937,999,964,271,386,543,322,877,126,357,685,639,141,16,397,100,744,297,22,368,376,13,403,3,810,442,389,897,487,619,509,920,850,428,492,401,250,919,898,30,803,195,221,838,999,431,895,70,365,115,172,230,346,721,425,60,779,905,962,572,334,50,567,372,266,220,552,756,38,463,190,836,697,523,827,237,673,505,230,863,145,493,848,365,443,380,890,895,505,79,338,567,940,902,848,543,288,236,902,152,322,617,206,466,333,980,93,653,141,294,641,677,797,78,688,637,554,218,439,886,172,246,889,741,125,498,546,427,436,8,21,719,919,137,703,524,363,270,948,756,582,461,223,894,949,249,349,880,654,287,669,761,757,877,124,809,58,565,418,289,318,13,62,221,350,456,109,105,289,229,391,760,16,182,564,405,563,263,86,200,493,62,977,344,551,630,343,274,257,461,422,135,592,77,192,303,537,112,699,382,617,363,47,164,772,578,401,244,971,262,935,731,558,147,60,542,836,974,339,380,486,407,721,704,430,200,807,9,474,981,599,714,627,98,326,583,744,361,596,580,863,863,507,248,408,727,35,334,190,318,824,946,194,521,612,285,279,164,12,464,749,296,731,875,697,196,109,797,282,967,227,142,42,74,201,11,448,336,194,172,83,759,296,177,949,639,389,521,355,194,2,702,750,649,206,16,223,203,673,33,790,47,353,364,157,943,238,9,133,133,70,246,366,234,917,959,196,325,136,223,512,52,764,397,881,973,686,680,709,142,52,434,622,28,418,756,756,891,348,419,325,272,373,525,980,185,6,738,701,188,99,362,318,213,209,51,895,643,898,713,473,990,666,499,442,357,689,536,498,69,128,189,183,767,5,833,650,158,170,881,975,856,560,922,490,798,382,522,886,519,357,971,46,109,471,239,718,781,691,870,150,678,430,687,206,782,232,632,46,888,249,759,16,802,770,435,359,83,711,599,533,766,289,820,902,115,324,179,386,459,477,996,740,371,17,35,434,941,586,833,949,501,26,334,403,783,930,880,338,151,708,431,347,542,812,72,127,940,801,171,580,605,874,846,667,457,352,889,314,454,884,580,371,175,784,197,444,922,770,430,653,394,771,268,896,873,54,785,928,681,746,778,757,638,41,491,525,806,274,959,814,719,649,856,897,795,822,171,760,46,79,951,945,52,128,135,916,393,119,158,139,205,985,267,0,399,866,918,359,226,207,214,960,735,198,264,236,317,946,434,563,889,604,320,147,231,882,403,920,520,297,770,240,509,174,454,318,957,937,102,653,157,838,145,251,799,558,862,52,242,240,467,994,124,556,909,29,384,913,505,568,996,973,194,728,711,544,941,404,20,434,953,304,611,415,968,128,265,475,225,628,684,320,333,10,132,683,598,807,811,557,742,176,877,152,213,879,199,480,55,922,18,24,739,545,19,596,393,358,482,413,734,462,184,216,898,805,268,543,811,8,803,994,273,735,251,599,99,156,679,430,947,674,527,389,241,977,627,955,994,572,798,268,920,228,242,515,269,770,488,409,435,295,119,423,95,805,324,400,180,188,567,37,485,355,350,167,590,843,455,483,865,249,848,978,81,613,7,601,680,596,809,61,525,747,810,966,78,709,817,694,98,461,363,597,129,216,709,713,610,804,443,335,110,506,151,291,935,615,647,917,243,543,450,455,669,517,421,946,170,411,179,623,370,426,814,71,568,791,845,247,103,425,477,44,706,247,71,200,498,20,632,54,206,690,759,209,286,818,762,65,44,311,827,530,866,391,211,123,44", "927,7,760,296,759,684,861,827,454,838,243,342,739,939,791,529,545,484,353,599,652,193,104,541,17,582,867,678,935,428,530,80,777,935,978,239,869,810,599,802,926,333,650,165,472,774,292,292,30,436,264,869,509,122,108,291,846,855,36,369,369,821,812,605,502,705,309,591,547,299,144,546,975,46,953,162,492,311,175,533,99,701,675,269,809,536,688,239,923,379,877,715,712,531,851,161,888,574,778,905,643,304,321,662,316,765,46,423,11,706,13,776,436,768,583,598,734,440,838,929,26,62,236,733,762,75,75,30,165,478,472,919,678,323,271,712,821,712,636,473,507,759,334,136,157,903,113,655,95,24,57,983,626,337,416,181,264,560,76,826,858,232,267,853,676,837,769,155,24,85,204,913,359,380,112,438,835,94,319,210,420,561,474,268,984,75,46,399,126,561,83,215,334,262,152,902,941,208,464,485,655,845,256,54,312,775,264,651,843,94,559,75,826,681,905,393,20,626,988,375,727,959,573,932,676,743,778,49,651,636,646,507,940,663,829,293,768,55,966,57,287,375,180,312,299,437,81,95,523,600,238,989,512,305,518,241,355,739,659,137,735,985,622,871,909,874,601,734,462,687,600,838,874,524,992,617,796,908,59,921,19,522,515,14,607,532,849,816,8,677,247,416,377,168,813,586,523,13,797,280,111,522,451,9,253,321,979,253,239,260,157,769,391,703,199,597,12,232,693,501,793,516,160,499,513,545,153,241,728,789,737,756,654,921,863,11,723,288,347,979,612,470,776,611,682,500,130,849,970,321,32,848,640,151,589,307,361,400,970,478,876,668,520,33,737,867,770,442,178,73,19,415,812,110,540,749,940,448,837,770,128,511,887,57,919,227,170,2,847,829,523,84,55,380,334,14,238,114,212,652,764,955,937,37,212,149,149,518,137,761,404,271,81,538,504,495,17,456,836,777,806,274,198,425,446,661,1000,948,443,612,439,136,372,718,204,554,480,358,466,336,872,79,651,219,830,465,824,456,407,507,178,2,127,505,641,106,288,229,590,293,307,8,848,780,63,71,925,442,628,126,967,256,809,765,667,759,750,551,70,781,854,389,605,278,157,177,713,749,384,89,376,930,467,837,28,328,114,618,163,783,546,590,412,263,283,700,576,258,550,252,186,477,690,584,744,747,936,623,287,375,583,519,981,577,873,810,830,623,242,485,13,107,970,656,125,132,407,445,296,219,948,682,490,561,942,168,124,112,608,385,338,855,129,137,874,497,159,493,49,201,303,974,550,404,173,313,182,558,909,794,788,159,93,117,649,835,586,313,578,989,191,755,289,385,679,844,154,123,385,193,60,74,770,176,638,420,538,389,926,747,61,147,113,665,99,226,398,318,46,219,117,585,102,144,342,670,211,903,900,645,612,375,725,108,366,343,794,471,522,544,501,658,995,762,692,33,211,536,341,868,614,929,778,481,816,565,53,718,548,595,843,348,210,453,90,681,721,473,876,340,343,75,763,184,126,614,614,60,886,672,409,456,173,318,216,354,31,688,213,21,805,808,551,688,413,583,638,643,538,987,779,119,620,350,607,367,921,359,195,546,128,822,391,826,134,569,789,335,12,982,705,325,591,130,888,82,570,155,686,294,419,32,151,690,864,554,4,474,600,875,652,225,909,462,366,427,490,724,170,844,76,774,603,437,399,0,647,715,908,540,536,483,667,918,797,579,375,855,560,991,599,268,31,662,193,229,831,914,974,238,360,276,947,6,243,224,910,397,408,850,503,704,125,287,704,252,737,305,888,609,189,914,916,511,331,162,786,971,319,515,590,405,140,40,918,228,826,407,548,394,509,612,339,992,730,294,950,809,431,769,25,636,462,869,940,648,132,316,52,534,405,611,161,274,627,669,943,395,464,903,531,838,8,735,314,842,982,305,124,810,413,489,576,38,968,677,600,279,384,472,396,76,585,463,969,946,278,328,69,872,420,564,493,682,5,409,591,411,947,881,793,990,760,91,929,26,312,30,489,273,517,146,153,150,716,582,330,848,951,333,333,439,464,865,415,504,56,973,502,555,39,407,327,157,264,125,479,35,103,267,934,269,813,155,185,487,511,801,994,500,751,155,575,98,952,183,519,466,465,399,265,75,981,322,559,236,805,394,665,863,613,153,395,921,342,563,446,964,794,251,88,935,468,591,176,719,188,805,563,599,816,550,726,222,218,349,279,408,972,446,673,192,835,814,692,711,21,529,352,651,752,392,661,520,996,934,957,813,212,929", "757,24,201,431,13,191,457,582,705,320,509,392,675,488,222,623,244,128,432,273,567,620,281,765,928,145,14,279,685,601,799,389,855,315,96,928,160,716,915,671,993,590,109,361,600,538,503,597,726,953,588,280,12,380,561,141,371,481,166,750,725,952,266,182,769,520,798,968,485,566,2,933,643,598,378,982,568,95,416,724,2,410,279,967,522,933,183,572,839,997,68,496,307,842,477,794,383,459,937,65,141,944,727,894,933,211,802,498,600,732,876,770,564,122,330,369,172,254,600,599,551,510,111,556,188,962,383,2,876,119,442,888,543,224,982,372,106,661,761,563,171,739,710,367,24,514,866,436,584,125,834,542,261,569,554,940,338,287,928,17,436,115,239,75,153,773,221,50,994,379,102,136,544,751,171,412,523,832,94,932,11,554,293,416,162,537,423,715,767,930,191,78,522,819,920,487,260,631,387,243,324,371,660,501,899,561,255,127,446,954,643,829,598,568,680,971,178,538,749,576,355,980,122,509,307,833,992,375,810,840,654,988,870,100,903,567,785,510,738,309,774,591,770,136,889,131,237,584,25,577,307,246,497,48,802,658,35,514,167,147,304,848,410,253,584,333,399,551,844,800,553,833,990,69,722,385,192,694,491,138,846,687,130,970,258,969,436,585,82,695,146,822,655,895,363,930,396,803,223,827,343,598,790,42,754,544,41,677,155,592,882,363,590,806,283,590,263,540,225,696,346,718,318,674,708,751,89,486,494,320,76,198,465,582,411,233,785,984,388,488,588,326,156,516,126,622,829,488,974,141,636,88,509,182,802,169,992,854,628,271,659,318,52,16,688,652,72,410,271,432,804,744,299,982,213,162,170,611,353,125,824,613,269,226,471,81,123,362,231,136,358,976,865,237,311,202,138,467,68,237,707,745,696,598,563,108,520,369,95,787,383,217,945,929,651,926,7,423,742,301,520,471,579,606,789,772,134,686,202,273,218,733,888,25,64,628,18,834,259,797,557,838,363,61,803,430,85,51,760,738,94,495,248,615,452,798,652,2,407,435,332,391,446,42,287,634,873,863,604,388,358,611,399,29,842,711,31,622,510,12,742,688,875,618,949,108,280,713,97,449,321,149,971,27,794,27,974,222,411,309,957,156,887,569,407,370,787,862,738,414,833,407,973,4,191,475,267,796,447,847,971,639,348,923,812,272,863,497,267,651,484,818,148,523,791,114,320,807,651,959,959,917,454,263,945,69,470,828,816,431,245,469,813,866,644,163,398,731,410,30,796,722,369,719,84,10,612,442,592,814,10,93,52,166,768,259,871,270,576,960,157,625,296,805,53,823,476,512,752,210,749,365,763,851,144,904,457,856,713,204,960,120,920,806,243,161,186,581,724,390,548,872,174,205,963,63,71,909,530,797,218,801,943,367,706,295,729,705,760,615,671,212,247,711,510,998,422,230,870,169,560,741,167,520,356,452,747,789,750,992,608,968,843,589,639,613,689,428,916,508,456,389,936,280,70,331,372,653,620,336,409,802,388,71,28,487,397,533,480,969,528,754,823,558,209,130,133,747,358,47,798,88,372,512,190,578,324,157,252,316,242,547,291,265,566,765,613,291,781,237,215,523,271,127,788,106,926,859,755,648,654,562,523,789,478,701,910,918,592,785,720,793,36,101,273,123,685,621,145,113,794,60,386,522,866,647,0,463,958,71,17,838,122,395,522,237,904,480,773,646,399,180,698,36,455,701,765,710,685,482,379,216,205,882,765,755,265,198,833,437,266,534,232,79,305,68,469,612,919,684,191,194,780,922,592,549,146,575,708,931,758,779,33,447,414,718,123,387,675,279,90,622,247,44,552,543,298,233,653,710,653,202,946,976,715,770,351,714,429,48,938,485,461,778,90,905,49,750,443,273,351,603,904,396,567,532,84,579,20,877,788,710,575,572,119,619,840,94,243,660,739,334,65,242,958,81,710,268,734,551,229,219,801,225,399,530,394,711,742,100,448,510,346,71,495,884,203,549,115,307,643,898,643,725,409,469,826,687,354,48,497,609,916,340,130,608,332,779,379,866,68,342,809,452,56,495,378,465,664,669,880,753,696,244,893,423,182,72,630,982,42,440,93,223,710,978,529,68,473,498,569,170,920,432,581,220,180,718,328,939,691,756,166,689,792,74,85,170,39,706,335,288,433,593,157,87,922,428,916,975,83,515,48,508,225,521,614,3,62,910,805,62,862,220,100,126,155,845,244,852,189,47,341,754,513,356,459,265,710,531", "835,252,16,960,59,882,133,892,780,835,381,329,748,37,877,351,911,566,629,398,264,401,402,876,910,282,56,716,398,710,241,578,737,253,725,684,724,621,959,33,863,279,609,495,908,126,932,348,706,677,234,651,626,508,643,483,134,513,64,57,760,410,589,250,356,187,777,710,537,156,157,714,546,86,801,715,566,279,888,403,384,113,939,511,725,795,407,574,363,481,398,325,637,316,683,739,445,341,518,480,986,15,528,158,959,941,865,202,308,317,202,527,87,879,364,28,195,289,62,420,576,695,118,517,614,885,367,151,283,524,168,20,726,365,323,117,552,336,865,106,860,995,913,935,866,356,533,819,958,728,923,433,854,454,341,299,543,338,175,163,634,607,184,249,243,411,851,314,485,869,435,619,863,973,103,870,168,970,520,455,4,54,875,87,304,711,511,757,56,896,159,298,36,327,364,191,223,750,728,668,583,298,398,436,740,426,201,104,668,991,552,860,275,164,86,310,284,850,77,835,360,537,214,234,533,950,91,788,112,54,305,40,839,624,702,661,596,929,943,602,216,889,553,583,370,209,961,921,120,305,785,47,240,263,824,896,841,115,240,591,450,933,465,115,554,482,933,347,811,729,389,38,218,961,194,631,549,489,596,119,850,612,887,357,589,217,104,185,361,226,378,780,166,658,748,275,101,277,813,789,854,349,685,731,83,908,940,784,720,938,601,240,425,957,877,887,37,876,771,904,961,601,693,163,593,99,201,243,165,936,718,123,216,18,364,208,460,730,915,36,697,968,665,545,269,501,532,188,788,883,832,83,890,860,932,918,988,216,866,392,324,518,518,26,929,767,962,944,622,363,8,67,585,587,897,213,470,714,165,63,857,836,245,465,797,23,490,626,986,412,498,911,175,68,435,695,233,410,311,634,226,928,994,691,895,993,759,688,320,739,976,457,861,931,518,599,41,619,624,372,96,125,126,145,94,863,736,232,930,628,303,99,47,341,815,636,945,118,159,587,80,860,979,928,697,650,623,259,930,438,425,894,252,116,944,447,448,447,642,7,314,200,845,567,212,70,380,125,176,247,889,491,223,293,386,681,788,857,550,960,660,432,882,909,413,126,240,633,313,27,476,496,595,320,767,54,736,66,634,38,653,655,455,410,133,384,549,192,819,39,986,911,591,723,836,434,179,949,417,517,15,231,498,195,242,461,326,287,457,361,664,489,805,431,893,463,277,338,27,882,491,264,47,179,851,964,717,953,433,983,727,622,312,678,499,668,429,267,244,249,711,673,97,152,862,684,716,865,356,47,845,769,544,687,574,455,998,114,669,95,132,663,23,391,456,407,776,97,545,641,162,370,998,321,862,85,579,493,116,969,82,6,90,622,560,71,329,140,29,325,768,936,207,244,583,7,651,60,225,853,419,330,102,888,887,254,927,117,768,484,458,67,161,401,290,285,731,818,209,660,85,841,12,857,781,576,810,367,945,587,154,957,865,334,236,937,158,156,659,691,750,792,825,145,488,228,525,906,986,734,863,139,296,727,998,457,551,615,206,961,893,97,254,133,409,147,491,196,718,456,18,109,105,272,891,351,352,214,725,194,7,13,7,863,337,303,180,11,573,613,46,199,140,572,108,969,397,644,748,118,417,647,145,185,89,15,122,79,813,896,524,929,376,491,152,232,396,312,191,478,738,826,636,149,918,715,463,0,275,860,309,694,179,608,355,193,588,578,898,321,253,119,881,84,988,840,346,853,301,314,64,647,451,282,399,206,755,495,861,579,624,371,323,903,683,332,691,840,527,391,39,134,4,381,241,393,1,261,803,427,368,152,917,649,794,320,20,917,228,375,70,177,29,738,379,314,570,911,4,621,419,396,307,808,439,201,315,57,394,475,800,286,421,435,554,619,440,536,492,176,242,645,619,659,437,835,855,467,751,311,754,656,870,420,875,660,596,218,149,709,454,605,214,298,283,88,670,621,758,19,118,829,313,852,547,842,103,803,613,61,723,523,134,429,371,337,865,653,998,306,827,634,679,754,962,37,520,421,503,238,535,361,52,819,949,540,164,409,646,524,445,743,279,162,590,51,379,830,281,117,288,779,460,708,406,605,262,472,106,480,255,626,972,498,107,239,3,590,106,617,828,570,774,109,171,455,270,344,350,823,850,886,93,161,869,584,18,810,218,638,71,639,50,115,548,335,610,136,950,408,54,389,221,558,345,92,394,604,478,870,320,849,104,118,392,641,122,968,868,615,288,270,520,676,133,965,389,714,603,699", "567,528,9,424,364,530,711,200,998,760,237,404,729,929,786,773,723,761,494,280,477,775,486,919,754,343,431,821,111,210,584,397,494,741,232,490,411,329,329,963,81,507,257,130,619,126,779,210,68,611,82,524,993,971,592,325,371,364,240,382,604,503,529,440,802,920,528,98,390,733,551,106,215,55,147,624,342,275,749,751,818,632,273,662,340,820,586,72,484,24,497,169,689,431,598,981,847,727,676,197,428,829,436,602,109,245,715,91,607,989,435,84,980,687,144,683,549,852,299,431,865,523,706,674,381,730,754,89,421,600,835,695,392,214,37,217,445,823,463,296,466,305,778,539,297,392,119,683,468,314,647,606,943,273,685,53,486,912,552,950,57,123,824,608,209,334,330,755,372,775,32,589,130,633,535,202,462,224,69,886,479,786,694,445,63,121,377,223,343,494,919,522,514,874,261,493,19,295,498,491,612,735,884,819,526,910,488,760,175,844,375,901,754,887,578,598,880,740,756,298,714,38,320,52,390,711,547,406,729,827,884,638,910,354,237,112,796,456,766,387,873,485,508,459,867,345,11,772,200,298,692,864,616,707,632,715,507,78,68,127,10,450,135,56,466,180,615,530,356,47,906,623,887,28,919,877,976,62,491,218,90,159,525,854,974,722,785,461,642,667,166,643,252,565,984,217,202,99,386,623,946,954,477,644,114,847,501,9,944,334,331,391,996,854,543,36,232,45,790,802,972,348,594,514,508,483,767,158,834,622,973,596,504,923,851,316,192,128,412,888,439,109,990,323,169,78,268,555,534,717,488,915,562,595,367,286,182,988,236,316,38,913,847,1,266,365,892,802,415,506,142,508,61,668,944,814,355,886,358,481,24,787,580,745,592,194,298,336,797,264,853,971,2,606,865,658,89,31,49,352,717,805,440,775,579,993,905,404,749,751,587,950,767,194,411,54,78,152,578,46,252,488,472,499,174,732,840,979,330,701,409,194,818,621,967,599,660,989,585,764,539,941,175,504,631,167,156,679,197,11,371,223,134,581,37,34,681,654,37,933,298,378,906,145,175,955,476,875,809,916,512,176,267,822,950,172,957,753,534,363,874,228,111,555,759,678,34,247,812,291,355,171,425,683,677,705,609,166,639,351,779,75,260,490,23,784,248,424,956,220,712,850,386,438,466,62,969,310,119,243,765,292,31,126,66,906,32,200,632,346,258,902,546,585,466,34,671,820,896,990,510,276,662,692,491,433,747,872,49,542,531,647,495,763,528,319,811,123,394,507,594,843,464,240,60,441,184,908,791,878,943,291,591,135,608,563,52,927,767,83,428,743,226,123,221,481,292,432,762,230,232,479,472,474,342,363,377,607,630,886,795,631,175,134,850,405,887,815,32,86,805,532,444,651,992,496,15,388,350,798,840,154,146,288,206,276,130,501,893,59,626,670,242,801,614,832,71,60,298,597,100,243,947,271,480,443,665,679,762,301,465,865,420,438,884,381,283,356,952,162,43,168,671,206,481,243,200,256,963,487,821,475,342,209,437,154,25,58,191,39,458,499,859,713,427,504,179,560,342,972,859,387,414,300,576,634,366,212,288,491,963,69,130,535,732,107,403,886,995,37,912,868,216,365,157,564,205,293,936,741,670,575,443,41,583,271,118,826,169,533,140,760,15,844,431,204,488,164,247,721,905,819,111,195,359,908,958,275,0,205,540,920,552,803,163,669,332,727,4,986,103,277,520,294,219,280,184,20,766,587,655,218,301,266,163,478,434,21,597,740,885,388,83,203,369,344,513,11,904,10,275,449,793,171,277,980,764,36,434,70,934,539,945,842,665,770,745,9,772,221,664,389,331,211,110,845,714,563,764,261,662,746,88,379,34,866,516,153,417,979,660,339,194,449,446,897,396,515,543,406,423,701,919,245,589,672,61,530,964,691,112,784,658,216,460,7,298,760,89,475,263,158,832,115,526,901,113,55,159,958,469,134,486,208,202,604,206,617,663,512,252,977,297,149,937,544,839,521,376,7,631,738,60,534,64,544,992,677,538,569,971,817,4,156,739,57,349,941,764,320,296,321,683,794,535,424,958,490,68,723,905,92,628,321,197,720,879,609,276,82,396,609,550,538,482,269,659,152,78,478,488,195,116,837,101,745,232,618,548,898,988,16,234,10,603,43,693,127,361,649,64,213,544,923,591,598,439,97,992,538,479,494,129,164,985,575,395,792,58,709,446,512,655,956,247,344,178,291,74,501,794,398,705,835,736,253,956,775,264,38", "472,973,160,916,50,691,487,473,761,288,662,424,364,259,614,635,714,637,555,265,608,954,745,583,496,744,599,879,566,531,952,119,895,378,551,896,411,974,972,768,603,427,607,756,846,14,807,759,455,191,557,380,683,172,562,972,708,863,701,271,350,63,69,102,720,715,555,287,796,478,590,953,314,567,792,881,26,576,666,209,229,797,353,165,127,31,903,972,68,192,908,418,109,531,599,928,988,873,265,826,198,513,725,202,59,980,555,342,337,587,798,736,388,868,406,780,183,714,999,839,888,589,829,508,377,812,270,929,216,584,43,550,865,878,209,517,402,558,397,894,305,894,549,151,382,713,310,518,615,804,680,728,508,583,926,958,64,250,271,620,862,794,26,268,856,547,170,262,636,383,721,401,651,385,252,498,928,47,633,682,967,779,893,271,594,207,326,597,264,188,385,680,346,73,433,351,677,371,744,996,453,667,136,916,41,211,847,728,571,675,192,27,684,243,17,544,544,363,855,705,318,949,257,777,337,642,839,502,855,256,472,58,117,607,470,314,511,161,470,218,406,639,716,947,668,76,595,503,152,256,314,723,673,897,117,587,512,317,554,943,954,1,672,860,682,809,358,537,205,194,377,90,679,525,170,449,780,290,814,154,240,30,703,662,287,863,56,463,624,201,164,524,928,42,99,288,445,255,14,565,466,868,47,270,67,232,868,989,670,291,805,626,385,679,192,171,957,117,778,149,743,286,321,652,503,323,662,16,360,611,794,647,946,539,613,883,482,39,161,242,258,75,58,985,668,587,105,948,650,644,731,7,82,106,970,293,338,657,115,904,855,146,548,476,221,143,382,747,828,221,63,263,28,336,201,512,409,658,26,540,262,220,976,818,605,29,993,72,713,418,299,64,560,720,629,316,491,112,596,386,36,830,896,833,789,323,513,213,991,623,710,893,32,146,673,710,910,963,485,648,391,234,834,28,927,986,383,420,451,755,448,213,470,420,957,81,840,325,687,269,60,787,505,204,508,391,727,522,679,528,574,117,682,696,635,12,358,313,893,927,792,979,508,79,174,287,231,58,378,957,574,50,686,718,846,193,5,434,249,272,62,166,343,38,574,512,753,83,98,457,251,41,382,199,774,920,272,273,319,135,623,154,278,472,440,636,935,463,466,198,800,755,261,241,582,992,938,667,417,802,259,268,151,511,127,368,946,477,151,956,894,973,462,525,485,756,216,559,963,992,693,19,607,172,614,27,625,567,7,965,699,45,16,648,800,850,498,580,337,865,978,777,213,536,30,791,114,527,111,865,955,272,499,866,146,210,641,816,948,456,68,659,211,411,635,967,796,260,345,471,70,503,868,548,902,270,920,87,92,805,402,469,772,676,582,443,473,641,712,125,455,156,950,115,889,686,11,124,756,569,387,669,180,636,299,680,93,48,85,114,928,328,965,158,831,669,555,401,979,687,863,950,889,87,190,432,814,150,167,807,148,207,12,482,474,348,963,16,970,916,985,38,555,742,891,550,94,358,982,614,614,155,151,636,234,330,913,907,359,103,594,266,262,343,906,298,157,804,181,809,782,379,102,549,415,187,841,239,172,118,897,549,520,943,383,315,41,616,12,728,698,91,527,154,682,834,383,537,511,881,939,397,612,478,275,849,852,91,351,374,374,610,784,830,442,66,359,183,382,419,430,140,155,215,226,540,71,860,205,0,497,718,909,24,506,662,662,536,471,421,482,309,343,131,992,815,217,553,957,926,924,430,540,418,655,996,11,343,2,268,93,228,116,2,606,836,185,7,966,677,145,892,70,528,637,663,985,643,649,463,984,799,759,94,550,253,247,653,19,712,469,271,377,285,512,239,372,96,928,105,105,126,844,219,391,391,385,860,894,886,430,314,464,616,717,581,728,510,520,965,634,372,144,797,852,754,850,784,552,612,894,971,263,905,97,155,33,863,891,745,318,629,711,324,317,642,985,479,49,249,721,794,28,339,18,88,789,972,279,704,557,940,446,123,519,541,103,510,101,980,769,455,820,603,275,895,135,876,569,531,670,69,813,625,714,735,75,461,579,736,162,524,884,518,246,726,805,491,869,94,819,452,527,917,464,38,67,994,553,976,416,134,283,346,829,154,658,529,747,95,507,299,21,411,366,791,649,741,856,639,76,649,517,429,680,302,536,101,983,115,636,266,249,30,944,617,170,998,95,10,895,355,376,850,527,6,726,575,728,394,356,365,182,127,185,540,880,79,700,598,230,953,410,101,389,83,204,347,133,462", "530,117,868,47,485,712,708,946,392,775,818,309,625,598,348,906,940,251,354,785,772,167,49,692,257,570,115,908,172,2,591,397,63,411,387,128,351,130,399,610,746,830,48,876,420,258,317,283,962,463,451,377,238,933,522,844,600,505,271,197,552,856,552,790,579,395,976,446,338,482,862,411,259,399,332,727,351,615,67,585,743,843,607,895,467,790,32,327,788,351,149,534,487,324,859,573,649,433,335,579,979,979,906,140,684,738,129,309,531,193,948,255,153,472,836,84,840,504,421,324,331,342,275,170,809,817,716,597,541,94,316,833,775,476,161,506,578,675,675,168,522,736,251,562,203,463,872,339,375,178,540,745,462,90,226,806,241,582,991,978,547,851,959,491,943,474,150,451,999,646,448,558,102,279,323,131,547,179,898,681,534,246,291,221,848,675,689,570,182,150,764,621,901,485,550,561,993,190,453,306,636,217,264,289,518,226,38,286,248,387,85,346,758,577,730,724,664,211,101,770,63,612,361,649,864,412,10,251,385,955,717,208,923,290,737,607,635,983,149,544,352,265,508,794,354,879,669,849,985,568,621,743,12,62,107,34,525,654,619,974,521,960,233,297,262,22,507,170,979,573,757,189,51,909,480,871,756,281,202,889,413,812,372,241,158,519,65,467,783,308,41,111,679,484,87,790,239,82,357,727,722,764,200,551,665,625,602,122,602,80,136,44,502,84,608,113,220,623,834,818,371,166,174,556,40,143,289,738,11,814,275,40,767,173,970,819,871,742,729,544,150,300,988,800,240,141,93,228,380,722,472,202,548,887,949,338,337,135,151,372,468,712,463,342,510,875,266,57,130,200,461,748,129,603,884,26,251,27,489,807,204,744,722,64,692,266,197,732,437,566,814,894,863,715,443,196,551,234,954,55,751,246,113,398,442,616,553,554,871,39,799,360,73,492,396,637,835,178,980,231,779,304,670,877,663,554,881,239,130,556,821,388,565,13,783,541,15,198,417,579,360,906,645,96,166,26,990,328,137,140,499,462,581,511,947,32,815,939,280,375,754,17,258,324,286,785,128,426,824,200,189,557,572,102,336,565,900,32,450,8,123,419,656,659,147,960,33,862,911,912,16,902,767,800,165,861,632,950,397,735,435,636,197,503,820,425,461,675,635,809,510,64,524,774,78,595,167,903,154,20,773,484,718,273,389,992,399,800,667,400,117,392,53,667,971,979,242,216,846,984,815,493,598,3,135,720,984,743,106,623,631,16,261,139,670,565,931,714,959,123,266,636,496,846,736,874,175,33,842,876,986,349,278,932,404,910,129,829,416,663,28,648,762,595,763,527,379,398,1000,99,831,765,463,192,709,418,567,944,866,937,225,515,564,952,618,720,871,222,230,911,583,905,645,904,161,583,304,51,303,569,247,374,861,308,416,231,20,196,75,865,370,810,635,512,567,244,694,378,841,406,348,304,760,14,752,957,937,629,68,601,523,780,534,283,75,156,409,119,76,791,279,810,366,455,253,993,561,722,989,935,825,324,828,607,983,197,696,592,482,56,160,956,203,161,736,810,225,56,424,883,546,730,102,454,899,619,653,410,410,676,570,8,726,549,768,892,345,656,890,17,499,496,406,329,322,323,200,349,759,16,89,801,966,648,911,802,409,869,388,310,875,718,778,792,892,812,242,3,973,991,909,949,543,790,207,536,17,309,540,497,0,126,482,448,328,401,497,926,793,371,492,317,239,428,853,573,596,322,842,395,112,130,617,515,136,818,49,461,874,280,607,287,483,288,910,830,184,981,722,777,786,604,497,411,690,533,102,31,143,783,73,679,550,751,207,642,734,984,390,811,117,835,55,399,458,547,757,970,53,273,14,186,426,985,67,84,858,304,679,712,666,1,780,875,14,881,724,770,48,402,967,117,500,62,713,368,700,515,399,23,840,128,833,654,225,304,387,295,223,48,435,363,424,964,952,108,732,5,902,652,690,706,247,254,518,17,363,604,363,862,476,137,519,318,472,71,556,688,24,298,154,740,31,436,197,953,649,711,330,103,159,162,897,39,360,914,788,757,596,597,972,354,990,208,478,573,849,6,583,373,190,945,434,388,678,732,597,930,195,449,387,217,356,184,582,173,649,939,562,642,68,213,393,946,220,571,141,575,6,710,272,407,808,316,172,450,517,152,363,104,938,472,125,679,742,907,329,246,417,735,900,150,841,281,349,8,192,933,680,51,154,738,485,370,728,762,131,160,884,391,13,69,664,707,879,991,328,720,591,849", "589,290,124,52,393,446,677,765,96,52,814,3,568,775,7,910,659,734,631,678,522,63,787,171,638,299,341,773,873,992,989,490,833,765,221,287,575,257,643,228,269,883,557,508,77,50,4,993,738,485,218,638,756,59,431,532,75,104,66,777,944,47,857,472,52,569,419,604,538,135,69,753,734,128,822,530,590,680,95,207,699,725,216,240,280,672,747,126,766,950,204,131,620,345,473,501,338,19,515,181,351,845,130,648,687,742,358,973,100,595,976,380,180,363,739,126,575,617,179,784,839,585,395,960,270,798,294,86,95,639,859,981,535,844,945,686,546,209,371,480,546,81,815,165,866,641,477,448,234,345,203,187,717,643,867,382,82,876,171,686,900,873,911,897,720,770,553,742,825,569,274,374,501,316,885,737,812,722,451,71,571,594,577,655,154,309,298,868,455,180,777,167,602,748,161,754,842,934,42,331,348,500,474,754,364,217,335,843,372,966,54,284,456,372,348,334,114,156,821,406,526,597,432,692,175,798,165,918,870,977,833,176,948,861,831,103,651,569,370,527,288,2,989,762,467,196,808,83,791,884,644,300,8,400,820,705,149,724,999,691,199,443,458,697,928,977,811,823,356,832,208,898,209,909,36,660,912,746,727,702,88,876,86,245,451,450,503,705,93,886,564,990,171,728,39,838,347,969,733,462,976,345,978,152,764,102,84,231,961,942,530,728,620,625,853,539,714,488,760,741,869,644,857,685,159,1,531,419,236,7,793,830,136,185,270,698,809,31,533,187,150,295,643,888,169,605,144,115,56,12,662,801,322,97,413,793,14,341,899,63,696,526,749,153,780,462,833,244,753,533,134,162,216,698,145,264,601,882,25,389,976,583,232,237,111,810,139,783,755,245,278,86,178,673,498,528,298,41,387,951,792,721,17,213,408,455,757,532,442,206,750,473,367,525,485,315,786,695,755,457,849,903,305,482,221,772,91,56,934,740,659,550,42,279,705,374,226,441,655,581,893,102,640,959,125,301,888,934,711,521,167,78,447,964,884,903,380,390,452,635,404,578,88,976,613,412,296,549,602,925,619,489,152,431,660,882,840,137,987,220,411,768,980,555,835,953,420,852,286,366,686,506,699,980,381,963,995,408,239,567,213,529,531,841,201,6,35,642,342,603,699,65,375,572,149,167,136,619,402,500,195,920,570,630,499,549,805,422,862,792,714,832,614,211,710,393,736,769,444,6,312,999,819,967,674,538,403,127,49,911,23,927,213,796,841,666,916,324,947,972,636,811,140,541,649,481,795,594,306,694,466,825,324,83,236,779,503,12,982,222,170,955,704,522,194,786,22,361,792,414,975,942,693,699,742,241,207,882,885,685,857,616,679,272,815,306,595,735,796,940,323,350,586,245,171,62,931,236,870,614,560,79,480,731,143,770,824,258,973,744,267,216,744,700,902,234,317,728,39,770,162,130,498,793,32,801,801,195,670,82,519,846,88,975,516,941,238,504,203,681,381,715,537,49,416,12,74,483,961,393,536,273,653,580,121,384,80,10,891,221,559,873,689,134,549,473,460,460,959,858,590,843,557,973,442,46,828,160,802,990,338,215,241,376,250,906,530,799,751,49,329,729,732,236,52,684,53,315,706,142,567,724,561,134,104,277,862,189,42,702,558,604,761,30,898,867,383,350,400,212,683,879,363,463,214,483,838,694,920,718,126,0,103,517,164,891,156,903,120,877,289,238,757,88,112,221,375,142,62,863,984,120,910,714,836,904,970,243,849,532,830,265,703,425,416,902,129,153,904,310,84,551,882,79,810,214,479,710,371,833,220,194,924,347,225,311,786,652,196,517,594,500,83,79,185,22,433,939,744,689,825,185,599,86,61,892,652,151,551,503,591,312,278,351,295,757,125,993,377,420,785,443,338,120,787,402,340,498,178,728,314,451,901,772,842,156,322,829,363,167,256,751,216,979,118,564,50,378,882,198,686,884,495,425,31,246,984,432,948,959,566,722,40,878,854,485,536,173,686,738,332,349,744,405,413,101,362,30,113,746,483,301,391,740,767,683,512,831,300,204,524,449,100,131,274,721,660,397,261,905,887,699,831,614,737,680,237,10,941,446,307,817,512,601,315,31,203,808,394,578,209,240,34,751,160,602,417,975,783,988,421,868,603,513,195,641,93,257,772,869,642,503,336,156,103,592,519,534,813,953,197,251,51,829,880,221,496,922,503,388,900,262,881,209,88,753,346,17,868,834,737,975,830,593,168,363,107,781,711,383", "959,548,267,69,960,837,428,598,468,170,156,330,575,991,772,521,217,798,217,158,506,3,363,139,328,529,786,30,591,289,148,514,438,862,331,16,388,598,112,932,723,10,520,980,68,909,27,56,768,814,721,647,135,777,839,658,160,268,555,223,464,902,580,123,910,763,29,392,800,498,419,473,327,932,263,727,733,798,716,229,940,900,252,119,610,183,16,541,442,374,408,919,898,750,457,617,808,829,749,654,607,478,485,989,760,974,869,981,12,494,198,464,141,415,446,799,774,995,870,576,185,636,562,677,503,290,73,449,575,354,520,444,323,771,926,747,92,413,621,55,910,911,103,919,851,266,991,197,105,376,803,84,686,680,284,467,746,883,475,769,125,909,676,991,294,570,187,928,320,340,727,777,745,510,437,791,865,384,43,703,198,493,154,321,803,437,800,921,423,199,70,480,286,865,671,421,438,786,325,240,278,986,106,257,464,982,437,374,613,627,76,544,498,977,570,957,666,311,568,96,909,765,791,501,88,140,956,231,766,146,325,159,164,796,719,787,192,751,560,933,938,10,327,962,741,637,988,400,614,119,136,255,280,720,368,8,201,106,795,835,445,572,344,31,838,120,475,538,900,565,888,975,639,476,286,388,996,506,475,711,708,23,379,730,762,880,192,79,512,898,197,21,970,105,604,728,850,901,189,881,461,490,809,179,504,470,762,996,81,831,185,151,449,103,700,57,87,449,523,324,767,696,413,870,15,338,233,306,478,534,616,328,823,649,379,380,882,838,298,483,375,436,61,189,843,301,803,768,132,738,60,44,882,338,269,427,971,559,639,770,13,119,455,214,792,626,632,973,443,252,823,599,546,26,698,785,913,167,313,243,915,361,14,613,222,607,445,493,363,971,923,401,580,25,273,359,6,561,345,893,81,44,210,180,1,835,471,184,770,550,310,332,122,811,467,533,531,902,501,717,687,147,485,812,761,119,817,787,358,327,111,755,932,689,440,588,180,471,507,747,829,595,374,188,23,781,391,411,813,690,480,48,510,488,541,734,45,510,705,595,823,894,474,584,633,359,432,375,454,797,255,57,84,344,805,279,542,415,503,927,404,920,919,128,878,458,695,398,616,139,684,694,564,33,230,318,913,751,906,40,685,926,879,111,25,145,732,38,80,542,14,939,274,270,243,179,541,24,576,436,13,283,640,974,452,146,136,916,329,718,116,957,380,263,874,602,302,403,85,345,943,482,394,221,795,443,955,562,764,467,99,816,719,104,756,774,38,158,232,75,642,731,783,237,565,859,29,534,347,973,801,554,241,711,460,757,440,677,385,984,829,210,261,421,839,678,45,458,118,475,812,111,996,8,834,189,359,849,122,522,609,831,771,440,720,620,675,642,815,691,7,860,896,751,872,1,753,624,768,760,114,993,93,293,346,801,846,27,703,727,262,265,835,296,783,883,515,161,90,906,877,616,127,424,35,10,203,702,160,953,714,617,508,163,746,390,528,822,109,468,853,552,384,290,998,409,676,666,658,97,682,789,766,345,292,292,546,888,615,280,444,798,374,873,70,757,755,10,456,232,259,891,503,141,619,836,874,940,662,789,752,187,979,445,318,616,714,845,978,305,599,513,441,734,226,104,367,325,179,538,409,64,220,686,898,24,545,56,664,855,815,247,688,403,870,522,867,168,570,875,645,388,712,479,960,667,122,179,552,909,482,103,0,958,873,179,859,500,301,252,290,223,893,18,878,156,519,478,629,152,653,546,452,394,130,678,938,177,280,722,700,120,938,912,978,421,471,597,80,505,390,734,322,377,952,165,289,912,719,524,894,436,801,667,948,444,309,377,767,705,533,522,76,82,777,151,970,870,846,446,963,37,411,741,305,42,442,533,497,176,22,82,660,13,52,529,714,719,658,869,691,827,752,873,850,921,469,800,490,726,639,808,956,977,857,455,445,136,87,446,369,859,387,396,846,91,7,456,104,128,824,41,544,699,743,518,836,737,124,603,168,458,898,848,522,408,373,811,774,66,545,189,717,619,640,329,690,556,220,791,555,113,291,630,664,943,208,743,540,791,468,827,492,160,37,549,336,838,605,697,465,74,349,559,801,983,148,337,780,701,216,462,8,677,457,353,94,403,16,95,188,269,803,273,396,752,794,689,494,383,973,424,728,969,374,272,228,222,489,702,268,275,637,122,267,662,917,810,623,981,915,912,699,741,827,144,961,211,172,142,842,132,415,881,762,2,398,475,99,698,130,122,981,814,45,577,394,745,750,193", "213,202,460,164,972,726,159,555,305,422,923,828,473,797,229,365,923,929,888,509,359,572,18,110,461,989,990,268,407,246,955,535,985,474,559,233,232,807,709,762,697,138,54,765,430,486,837,152,149,143,873,958,67,169,462,670,952,793,322,749,8,70,894,516,918,148,397,834,834,491,339,297,353,761,535,692,984,26,936,807,700,266,330,328,797,357,738,722,875,982,652,915,46,25,140,347,794,206,302,611,307,102,556,761,950,14,976,219,962,626,945,328,284,554,896,421,250,581,740,673,698,610,809,314,807,400,104,455,113,161,150,92,67,973,826,533,112,378,455,435,23,534,105,996,477,33,852,676,542,901,860,977,37,659,547,969,353,289,990,767,972,884,108,554,166,106,344,487,253,358,698,10,201,818,714,622,930,227,901,182,864,628,520,156,579,943,832,257,530,904,187,157,723,440,466,798,352,365,514,672,617,433,364,531,552,330,109,328,327,654,642,579,579,624,395,170,711,686,158,198,148,307,499,502,354,838,762,693,695,548,91,636,945,871,665,932,720,97,918,123,196,233,153,159,765,251,246,900,202,974,929,356,608,591,864,966,908,882,223,982,542,420,340,219,922,943,941,964,353,728,461,6,908,977,96,823,363,774,325,353,635,286,739,586,408,257,162,706,268,87,724,815,981,361,532,967,972,792,699,284,488,100,2,830,699,43,532,145,663,845,844,675,695,584,506,550,800,800,982,265,948,22,746,460,858,681,894,653,81,854,668,194,748,54,352,499,43,786,648,149,268,162,719,654,272,906,63,780,431,32,386,102,472,10,86,628,12,653,436,683,290,960,71,830,737,757,173,144,681,41,286,173,315,713,778,958,738,51,592,271,932,328,977,493,730,217,22,423,442,663,401,469,482,779,299,701,189,424,860,605,675,194,435,866,93,803,138,524,428,389,874,838,381,128,80,82,303,375,388,227,191,612,524,498,989,134,548,206,734,503,82,857,443,158,207,571,642,527,198,176,124,417,545,508,603,64,428,789,71,106,58,729,545,608,100,789,460,443,866,517,75,720,87,494,496,294,679,711,569,606,669,960,7,110,797,510,721,98,82,454,850,535,292,386,945,236,917,205,696,662,372,656,310,860,149,990,542,286,869,823,499,177,635,134,756,777,625,62,842,397,607,458,43,83,232,601,743,344,872,47,89,441,85,61,527,819,765,90,226,886,312,136,48,222,381,815,508,925,582,192,777,685,500,247,523,18,95,966,417,286,522,794,681,187,437,703,871,333,209,756,304,823,218,756,928,372,396,269,327,118,751,958,675,431,156,910,398,614,313,762,349,972,455,811,397,339,307,60,170,977,812,861,319,391,208,899,791,599,883,9,153,103,374,568,686,358,317,68,557,972,259,991,431,64,437,671,96,757,28,937,645,240,398,337,265,396,651,544,785,80,869,432,521,426,849,853,799,59,14,510,292,373,453,199,553,839,35,446,708,36,8,327,984,636,1,21,471,659,275,402,284,935,437,801,437,746,594,604,350,159,101,829,883,237,266,227,685,261,319,890,578,309,909,806,776,42,668,961,684,496,888,707,658,627,694,834,828,969,647,313,371,14,24,394,992,982,219,534,834,924,587,678,84,942,219,450,904,167,822,102,361,380,939,574,581,856,788,114,261,698,4,323,126,893,213,621,699,532,80,405,250,870,228,854,735,918,395,608,803,24,448,517,958,0,923,454,292,728,667,713,222,38,798,451,457,780,272,543,487,831,77,178,619,521,142,710,465,899,833,379,783,925,923,287,72,338,569,724,388,653,257,959,457,397,975,155,66,944,661,28,73,352,686,942,316,127,476,213,433,586,232,408,182,437,479,579,497,911,659,833,659,90,515,100,204,324,46,457,135,267,251,725,634,356,5,66,984,820,883,300,374,729,893,246,945,16,887,164,584,784,599,289,999,34,616,133,676,109,144,285,733,100,638,676,133,739,173,95,189,137,343,320,447,12,21,63,597,71,257,298,488,791,238,858,379,847,998,558,7,34,812,536,340,769,167,360,405,3,633,570,366,725,164,422,263,154,487,850,946,787,271,597,870,650,131,87,855,766,491,22,238,855,149,480,946,109,783,412,430,373,510,105,270,519,765,57,28,118,648,24,275,353,474,347,473,569,857,903,955,651,95,893,738,658,25,532,602,547,166,899,473,958,797,859,202,245,829,102,37,466,80,142,733,665,431,623,753,381,457,770,123,535,368,864,35,553,626,358,955,644,566,568,266,723,382,51,700,929,683,902", "74,264,928,479,970,790,468,503,384,830,657,434,671,321,78,356,877,729,303,186,954,222,526,574,681,449,884,855,814,230,36,556,321,606,466,858,60,857,204,727,278,779,85,382,280,560,437,937,131,628,646,134,655,689,389,443,748,819,861,672,280,671,132,174,58,621,591,768,830,665,67,316,424,556,491,914,221,673,530,522,281,908,892,125,306,782,684,724,77,232,61,866,707,500,233,897,621,669,950,485,687,196,629,319,80,514,450,824,829,147,750,662,71,860,414,100,581,76,256,398,138,602,497,155,332,920,631,274,309,657,838,846,631,276,433,296,605,196,582,419,295,221,97,883,740,405,735,917,530,254,623,239,38,987,115,564,165,446,116,65,835,818,621,484,450,407,775,71,482,528,297,483,35,987,644,680,176,355,379,82,169,306,990,814,708,727,718,103,450,419,711,389,926,679,380,345,347,882,41,754,985,338,276,595,881,182,138,981,564,262,261,247,200,587,112,588,972,947,831,805,452,634,347,902,533,766,808,248,100,439,463,366,132,736,3,422,494,721,393,972,692,97,877,110,3,47,858,885,147,60,844,983,381,489,730,413,235,936,14,509,569,528,195,53,376,669,726,797,930,85,55,852,637,176,720,552,650,974,433,578,830,442,503,22,537,177,817,735,253,728,446,737,748,178,244,560,328,513,974,412,961,262,296,956,940,334,533,290,243,66,287,867,811,138,51,45,305,802,153,430,627,464,253,801,978,546,456,894,448,830,434,154,481,505,10,714,603,636,123,269,541,542,833,736,177,580,482,796,460,824,86,194,661,435,824,902,303,537,474,182,988,353,563,871,704,826,266,616,968,934,491,399,483,787,128,604,523,275,692,911,304,928,919,163,975,878,586,440,933,836,884,559,823,272,919,897,710,70,233,808,628,414,163,51,595,465,420,376,437,652,652,512,687,359,696,434,271,112,270,310,370,684,760,753,116,13,967,135,358,443,566,391,752,778,453,632,515,222,574,992,524,978,71,731,752,401,103,986,9,374,107,2,307,410,60,844,746,82,496,508,824,398,527,999,662,632,918,61,800,160,397,793,843,17,187,352,508,453,495,4,807,421,344,558,814,172,641,149,209,334,898,116,755,848,782,62,744,205,138,752,284,967,771,446,714,816,372,650,610,225,375,681,764,449,852,203,216,341,902,935,229,703,728,493,474,254,468,155,318,162,746,645,140,588,806,510,777,780,563,717,509,464,34,993,358,35,434,540,926,735,587,412,337,150,555,408,193,620,7,310,214,398,581,587,377,874,671,519,476,892,776,602,200,452,392,715,303,333,909,680,312,934,327,611,669,488,73,166,862,468,216,842,497,379,234,82,899,438,655,687,739,138,600,940,202,976,438,889,261,945,619,39,933,428,252,579,267,780,405,51,36,834,681,949,251,977,657,505,475,375,869,48,825,135,344,46,363,94,665,713,454,199,483,769,209,55,257,616,421,236,795,88,65,660,828,745,840,647,223,855,571,280,551,751,526,476,264,312,273,157,260,44,734,661,624,498,885,694,498,212,718,515,257,585,839,760,565,315,850,653,461,587,553,389,550,246,526,421,568,438,72,963,110,740,907,737,195,3,457,705,957,558,265,338,767,11,201,120,533,90,802,1,419,564,861,742,128,906,522,711,39,304,298,711,763,155,259,122,122,798,888,390,41,722,198,797,522,355,163,506,328,164,873,923,0,118,136,898,567,180,749,866,101,363,534,679,950,286,324,776,11,550,881,344,355,766,27,943,785,900,627,590,366,446,933,242,392,714,326,43,937,250,284,464,62,297,663,833,333,884,152,681,774,516,734,531,546,330,114,342,592,287,9,841,699,373,612,121,139,405,704,1000,815,187,900,482,537,899,128,224,239,616,371,231,52,985,552,363,809,342,936,331,834,468,307,609,593,812,142,125,226,122,921,336,423,495,446,479,981,97,348,659,408,640,75,380,862,240,555,16,379,342,622,33,631,91,309,444,421,400,494,273,208,854,115,260,435,965,162,711,136,981,332,121,983,968,915,361,104,55,772,793,991,836,72,190,250,774,950,889,256,43,571,814,622,365,159,634,170,866,290,682,727,530,8,956,108,581,92,768,941,184,638,514,798,136,201,944,196,959,551,29,601,992,479,354,628,667,79,285,737,224,62,521,19,554,25,843,563,781,447,34,222,179,479,869,837,833,87,929,513,525,931,981,932,208,228,784,408,235,464,600,202,181,375,317,693,947,682,816,673,502,182,353,602,181,157,950,756,599", "904,831,316,380,967,197,675,111,698,998,900,537,924,247,409,389,951,348,738,762,63,471,696,792,569,709,630,754,980,759,259,569,307,340,249,298,342,629,783,844,697,917,153,146,591,706,95,675,206,54,738,591,475,222,939,896,335,74,724,133,188,74,859,159,468,321,556,328,984,400,888,508,658,753,580,926,387,188,96,22,777,587,960,688,781,208,72,501,334,153,700,719,58,425,966,334,390,875,978,621,798,966,680,343,25,526,211,499,138,129,2,530,222,842,883,50,866,598,348,208,505,742,51,378,933,589,406,26,902,16,92,889,436,898,223,166,597,446,358,443,618,200,826,179,52,369,250,65,842,792,625,67,150,167,720,683,263,311,773,883,424,726,916,690,918,454,907,696,868,762,459,937,901,483,904,461,77,627,733,381,575,287,744,177,102,300,696,290,875,756,930,359,385,944,767,712,849,158,87,973,811,602,226,958,668,251,135,938,55,5,390,183,381,895,450,21,659,708,771,620,275,779,424,530,865,185,716,551,443,332,568,275,181,89,993,732,126,436,136,457,274,211,349,165,555,608,328,67,18,649,786,705,595,892,412,137,711,832,739,809,125,879,242,468,538,228,40,402,640,196,875,21,189,831,547,660,791,150,172,499,620,749,342,63,452,375,917,314,544,900,773,814,996,187,270,661,789,812,546,366,649,508,609,29,275,994,69,905,231,668,629,538,22,609,457,891,313,242,58,102,577,186,690,545,394,83,969,265,662,53,246,76,213,972,386,998,29,301,595,549,77,727,501,739,405,954,685,918,914,118,345,508,736,886,451,263,883,648,495,688,590,298,699,165,863,193,45,432,903,69,321,851,341,531,457,521,976,428,836,986,26,197,47,164,864,317,982,881,223,772,196,584,991,625,286,664,991,65,454,547,744,815,575,914,614,103,540,653,790,351,798,557,1000,667,955,42,84,125,466,281,209,486,349,907,162,831,868,513,247,385,38,925,939,588,459,295,7,380,527,49,820,162,927,285,217,869,385,921,488,457,704,23,376,29,344,668,515,115,154,575,183,386,136,435,79,926,408,469,944,72,884,714,336,669,708,89,601,999,823,233,681,524,339,97,233,558,912,156,669,785,110,742,34,944,898,173,973,100,15,568,558,312,748,916,633,609,752,438,330,23,810,72,607,533,902,781,838,856,206,833,203,730,800,997,99,789,549,468,976,276,889,411,961,638,756,106,323,89,492,62,807,88,875,205,807,21,114,255,651,275,501,271,148,852,9,637,189,81,413,923,549,841,607,560,832,494,621,477,325,484,322,591,679,639,650,337,411,497,105,498,817,207,50,785,744,370,120,878,412,243,349,959,873,605,324,207,994,544,150,949,589,138,431,555,670,455,688,506,555,352,331,261,388,522,877,534,138,420,210,560,626,355,692,274,636,874,522,162,875,233,848,1,932,965,114,678,722,963,702,108,698,43,566,29,673,684,80,519,345,543,730,895,29,146,75,207,887,130,804,986,557,187,134,330,395,76,635,916,917,679,839,362,915,156,934,510,198,794,561,493,44,354,590,357,97,819,276,167,343,94,129,245,896,795,799,604,19,502,164,279,831,77,345,178,881,963,665,431,716,986,388,175,571,882,216,705,298,465,222,537,360,215,365,38,506,458,138,171,273,593,343,682,119,762,495,757,388,765,267,613,721,103,626,315,264,579,237,193,669,662,401,891,179,454,118,0,684,412,100,163,777,819,815,268,580,114,617,49,838,241,919,458,526,369,35,831,114,625,152,516,518,871,237,45,3,147,639,724,823,21,519,324,519,737,530,944,179,259,351,889,573,558,365,806,999,419,895,120,442,680,793,911,322,380,208,914,440,989,434,275,616,531,116,715,287,489,369,76,784,193,27,111,595,468,595,489,269,263,773,258,614,15,126,811,349,796,699,675,568,423,962,816,376,817,62,593,894,839,224,429,256,14,695,121,351,789,55,555,580,204,734,385,105,991,352,82,494,812,100,870,324,918,100,668,125,358,490,736,579,665,52,383,697,68,141,208,539,275,874,253,974,928,5,312,38,329,709,99,611,430,540,875,16,498,630,477,867,352,929,289,381,471,876,729,272,98,681,983,320,623,861,252,937,626,668,837,980,682,532,660,477,962,415,919,237,241,404,21,773,486,784,436,798,709,218,833,230,784,238,784,70,670,438,267,779,328,470,423,837,786,413,317,182,153,653,813,80,962,227,995,835,81,794,238,725,867,488,247,499,628,253,721,262,464,698,988,356,43,715,521", "270,235,325,496,711,263,927,45,777,692,533,392,279,332,538,748,248,231,935,565,216,468,896,100,49,245,896,596,469,98,831,826,491,256,280,532,818,835,833,285,114,441,345,249,108,254,446,46,616,801,205,165,150,643,700,208,116,21,10,411,59,546,495,317,575,323,415,72,223,5,201,354,635,669,992,448,412,602,140,129,514,502,898,691,87,643,520,948,347,199,713,154,388,360,422,23,949,216,983,308,463,634,630,178,468,490,702,410,735,607,469,893,384,865,44,515,541,562,556,425,125,240,82,189,764,213,68,399,995,933,37,377,221,658,937,923,373,474,48,156,898,922,347,18,317,979,84,572,640,227,295,71,860,724,298,687,306,970,960,656,775,965,312,922,15,260,475,75,216,575,613,21,804,60,853,744,494,544,812,958,142,281,495,356,133,229,581,245,31,260,55,240,877,375,422,722,497,525,143,350,283,73,793,171,868,494,104,244,851,734,762,208,147,396,728,105,377,754,948,398,313,373,671,807,653,369,878,398,547,717,6,772,259,403,709,913,394,649,109,141,850,89,362,413,284,815,252,71,698,999,240,94,556,187,483,293,273,941,543,262,172,816,376,446,694,63,501,573,370,499,147,79,652,745,562,29,624,797,161,610,338,215,455,836,510,512,35,456,664,72,637,732,68,36,410,506,856,726,142,310,539,463,508,758,677,710,816,827,668,792,254,792,32,648,468,85,637,453,524,243,977,548,992,369,655,418,778,143,400,211,168,584,689,136,865,149,781,78,651,86,969,617,238,619,110,599,780,618,13,355,973,230,100,643,672,52,414,667,975,895,599,426,219,23,632,979,916,704,151,565,722,467,995,234,996,273,936,134,604,277,956,226,442,449,766,497,678,1,62,707,485,248,83,270,633,76,494,214,561,866,657,377,470,228,482,683,62,993,956,827,51,331,506,256,661,722,616,402,119,434,570,619,199,956,93,56,549,359,541,714,876,776,470,112,886,649,471,804,192,477,384,834,936,671,842,627,914,413,617,226,574,918,797,422,909,3,101,739,597,942,37,16,658,752,927,542,509,147,854,595,502,777,973,728,469,986,521,996,509,157,452,231,618,298,750,407,299,718,505,235,64,47,965,863,644,355,881,571,559,335,821,912,571,270,251,23,271,165,183,920,443,108,215,527,961,810,190,215,765,136,163,96,801,390,836,194,240,237,838,518,71,438,80,312,922,64,575,178,196,951,424,654,985,830,616,641,136,926,284,681,854,824,283,91,60,242,956,518,245,266,90,181,594,582,125,450,380,35,603,411,164,197,180,974,896,910,848,687,12,764,179,607,923,975,651,440,243,379,277,90,242,582,835,309,351,546,567,303,810,191,473,771,393,888,159,119,353,446,204,638,996,170,383,922,336,401,939,179,203,648,44,844,830,983,418,496,675,780,114,520,395,605,121,723,856,615,200,863,475,910,529,576,441,512,635,109,519,511,272,772,967,665,452,609,501,366,436,665,124,850,615,526,390,299,637,438,84,155,903,319,537,237,628,691,201,963,437,523,747,646,457,442,219,782,394,437,312,557,214,458,374,746,525,713,799,376,157,195,106,679,520,568,628,658,639,211,179,458,468,132,730,406,36,373,273,56,28,845,163,833,928,979,477,769,339,818,838,893,888,554,182,132,984,648,18,269,576,522,436,665,638,234,563,110,236,375,904,588,332,662,497,156,859,292,136,684,0,248,460,208,768,804,772,171,554,226,694,748,996,504,774,380,121,364,269,925,629,40,552,742,37,277,696,320,584,313,442,943,736,637,379,646,246,225,442,608,511,409,297,882,404,708,131,482,567,14,766,692,15,480,76,146,738,728,468,26,502,814,432,236,904,216,190,254,688,736,415,412,330,569,596,592,566,407,170,105,345,202,339,185,446,194,737,173,121,756,242,37,660,727,540,993,141,864,356,952,315,546,830,839,783,656,536,177,67,340,192,115,95,155,201,55,580,290,260,537,876,21,826,566,429,563,571,399,195,436,514,46,198,778,645,406,699,15,152,716,732,449,647,404,479,527,929,387,574,68,602,334,925,759,816,469,290,757,66,218,889,552,579,857,376,377,529,91,651,322,3,430,728,907,929,779,467,543,944,231,741,404,915,71,301,481,375,129,961,582,586,229,754,627,15,776,720,946,697,934,337,801,901,714,606,93,497,94,191,571,926,404,711,265,224,605,382,346,334,264,643,705,143,682,574,27,786,242,139,596,918,73,537,914,58,799,89,3,588,780,291,148,143,597", "677,162,173,455,876,511,897,553,635,788,32,273,950,302,924,268,481,842,85,457,103,968,732,992,31,807,20,701,239,438,896,208,1000,907,759,824,362,118,297,731,57,412,170,968,46,906,811,966,729,735,343,629,389,220,136,353,716,772,831,151,182,869,418,366,85,49,810,567,978,204,771,894,824,958,470,178,37,977,634,781,470,451,2,450,604,350,204,352,372,118,13,101,69,889,82,910,629,926,743,352,988,725,143,26,614,854,323,313,915,939,549,164,632,763,124,90,442,141,815,477,895,100,278,394,513,11,196,785,124,899,805,507,121,107,23,516,216,295,745,980,267,181,773,962,247,157,730,531,128,517,230,124,768,357,873,417,360,745,744,133,279,191,947,457,661,23,185,567,410,903,142,58,405,322,655,704,798,105,325,329,645,497,699,762,858,320,530,60,142,330,231,853,122,868,361,111,171,697,917,271,994,969,600,557,403,124,917,576,450,420,52,554,919,737,703,906,88,36,56,911,275,286,860,573,155,750,73,448,920,818,159,716,230,926,76,986,150,338,49,663,824,317,755,356,109,643,711,309,55,380,164,758,666,50,840,998,720,142,674,372,472,157,199,245,10,405,189,415,174,831,738,703,544,405,454,803,641,721,248,577,552,536,981,769,770,450,915,905,329,205,153,479,100,727,83,879,737,845,771,440,822,438,542,575,379,821,13,676,753,239,572,624,152,244,57,528,968,352,565,953,523,759,355,209,955,502,625,65,332,964,429,224,959,631,136,169,334,354,957,250,595,678,364,878,832,995,792,5,379,95,927,558,549,847,473,259,367,140,771,320,391,365,565,986,338,222,805,758,867,573,546,932,973,482,788,493,243,590,339,863,414,550,687,883,199,335,77,843,102,619,17,939,870,484,589,283,63,450,485,530,643,155,168,323,892,295,830,802,114,686,477,743,767,895,143,817,586,876,872,489,338,829,532,89,634,767,411,334,774,793,252,975,293,31,950,635,140,276,222,833,476,28,466,671,882,958,225,210,997,27,617,762,601,808,972,271,953,583,8,83,143,374,178,612,53,464,328,241,718,941,6,561,114,248,729,51,227,971,408,355,672,357,737,756,156,478,175,509,705,706,561,250,976,512,611,460,706,903,675,964,620,344,814,929,935,797,138,923,597,549,370,144,62,291,574,416,738,613,615,183,914,983,943,749,643,215,528,890,61,770,424,57,404,581,647,188,984,663,387,158,65,127,92,885,397,567,385,360,396,779,224,10,408,297,63,449,80,420,900,784,812,205,157,414,974,622,795,315,705,204,421,181,678,114,625,64,904,655,799,834,182,364,858,158,347,399,890,732,49,927,160,137,472,454,813,633,905,274,795,1000,83,166,5,212,654,105,725,98,237,893,346,877,683,672,332,877,252,61,430,162,536,911,604,682,382,384,154,802,103,12,885,719,619,344,511,159,746,589,458,114,914,875,873,797,679,610,457,642,464,79,161,286,612,278,721,25,531,295,52,267,526,236,272,17,961,318,785,340,532,784,315,337,572,124,208,235,850,31,914,759,515,97,418,130,836,180,130,74,37,880,429,869,482,28,358,435,598,304,424,786,914,338,895,27,804,466,632,189,444,458,387,808,497,671,372,351,494,539,769,251,974,792,853,908,161,65,875,456,156,183,91,518,231,277,455,700,332,519,300,583,80,430,445,593,317,855,480,578,727,536,926,903,500,728,898,412,248,0,488,845,71,653,857,366,915,231,8,333,294,7,637,182,982,314,847,581,942,661,6,408,114,748,158,896,560,794,178,880,442,537,928,43,870,216,436,495,998,230,756,209,974,605,727,986,619,397,151,202,866,805,976,226,973,377,671,174,614,377,319,580,588,766,249,636,300,161,705,844,64,708,960,950,136,40,394,820,508,960,479,345,52,682,490,99,583,715,159,588,764,759,671,337,107,172,507,2,782,486,546,400,81,74,395,47,759,749,134,605,678,571,715,948,347,309,424,28,570,304,525,182,38,644,719,587,460,848,820,267,309,421,647,567,223,756,997,485,262,978,185,991,549,937,675,941,727,703,937,368,16,473,576,170,723,981,513,869,717,712,992,834,342,916,735,130,801,544,256,521,337,229,712,154,755,548,160,803,824,970,685,30,46,537,903,727,505,657,240,42,917,815,831,273,70,901,930,773,700,184,885,467,964,9,778,863,533,903,681,815,315,528,442,288,505,440,959,448,203,96,915,434,673,742,853,539,674,908,742,12,674,230,172,250,572,614,194,524,953,558,106,176", "787,683,52,615,786,936,216,782,548,113,46,789,482,927,89,585,978,926,377,961,460,719,6,431,828,665,201,557,10,59,981,741,369,767,843,88,742,972,564,449,353,809,350,936,76,653,86,590,533,307,975,420,540,35,664,6,93,14,305,682,308,891,189,596,806,783,514,480,512,186,152,368,161,132,423,453,162,75,178,336,430,473,748,811,553,198,863,26,156,983,984,124,779,479,129,539,124,201,375,862,273,433,578,659,156,682,853,106,970,211,729,402,480,506,476,979,159,340,971,285,171,61,104,946,926,384,779,303,891,426,314,842,563,394,647,438,588,795,789,786,812,156,425,447,518,592,890,88,553,358,223,246,382,122,230,145,60,225,731,796,344,266,924,784,118,252,963,259,423,180,317,223,776,376,308,791,564,977,982,11,744,696,319,114,737,809,137,843,234,278,204,445,322,180,204,67,512,760,329,350,208,954,885,526,69,563,982,267,479,462,240,51,822,91,718,373,235,517,903,2,684,840,354,18,510,312,333,948,259,303,904,73,652,24,566,907,854,120,621,394,264,634,605,270,436,177,875,425,304,167,387,470,539,105,720,61,418,112,419,922,785,15,613,146,433,507,866,610,286,182,988,543,938,529,164,268,450,769,925,38,799,770,276,144,750,518,135,573,169,330,627,342,339,865,911,564,827,456,747,361,543,853,608,57,349,674,842,592,758,97,753,270,535,837,544,768,997,949,41,208,295,653,209,212,154,327,873,705,358,754,589,973,148,65,710,510,206,601,233,141,744,306,468,681,702,289,946,726,487,782,617,718,559,980,393,970,514,723,561,38,389,861,101,324,470,584,270,896,594,921,509,135,101,806,983,971,785,814,531,4,622,810,267,136,959,778,847,423,769,802,489,896,313,531,791,927,356,377,64,54,393,25,726,135,141,183,808,772,246,163,987,676,970,621,320,106,207,472,842,198,438,472,783,50,530,22,269,967,39,820,80,383,936,369,756,23,134,98,947,372,364,995,573,809,329,252,857,332,789,850,196,131,680,880,194,493,55,804,655,975,728,617,490,447,508,143,823,642,779,75,384,983,687,167,59,589,776,431,183,249,620,467,745,324,295,785,178,527,422,214,668,471,764,545,255,81,183,629,391,457,852,62,254,325,805,914,378,112,554,100,492,785,760,330,320,972,840,555,50,892,645,318,812,448,747,430,104,745,864,471,333,603,595,175,309,907,85,274,619,363,276,737,962,975,677,218,542,541,822,345,367,644,389,767,860,28,945,680,283,561,985,810,439,204,103,602,134,203,477,962,44,46,277,357,69,204,133,829,213,577,766,374,332,127,316,903,665,419,6,602,14,417,354,506,746,961,864,78,378,785,242,84,77,934,648,228,747,627,982,374,604,422,305,605,884,453,368,264,477,811,447,771,701,38,24,551,542,804,100,967,665,141,202,859,174,309,620,83,934,277,77,797,535,281,459,907,59,297,320,185,875,619,213,291,534,121,937,648,692,977,379,45,351,165,340,373,733,687,736,267,282,152,799,666,227,41,604,623,688,558,364,833,695,108,521,974,575,951,896,862,218,564,432,727,315,207,517,74,459,144,180,925,754,992,360,60,423,777,851,116,532,576,39,81,355,461,931,592,508,283,528,519,215,951,230,311,327,229,409,815,463,542,95,479,602,151,597,190,128,722,838,755,362,836,946,560,773,898,4,471,793,120,301,667,567,100,460,488,0,836,651,694,84,72,350,358,847,342,10,201,418,742,40,883,486,530,494,530,371,418,589,290,265,862,356,20,946,737,685,976,618,913,62,927,428,816,127,544,347,28,479,152,998,420,230,698,293,84,393,892,518,480,301,798,650,939,98,101,598,937,643,671,315,666,124,71,678,20,190,687,252,830,668,748,112,807,25,420,604,281,938,66,729,506,691,689,587,194,57,99,930,209,529,335,605,312,322,455,486,439,627,963,531,721,9,616,442,768,119,361,734,701,577,418,197,425,189,390,985,547,850,738,554,210,581,571,418,803,954,916,254,685,551,82,715,728,892,427,88,634,478,374,901,734,141,727,388,191,796,981,622,577,799,259,583,226,778,729,569,362,600,25,636,58,386,909,768,887,240,656,357,563,742,37,299,199,304,288,885,462,394,332,3,303,501,670,51,867,463,759,962,945,458,931,934,230,386,163,276,222,732,15,154,193,154,868,525,839,834,77,365,945,527,166,267,704,838,845,379,401,229,946,965,341,913,127,94,781,428,772,98,132,131,92,601,768,154,481,647,112", "884,648,820,750,423,938,734,755,783,410,190,263,725,556,600,119,408,261,766,107,335,352,66,787,438,279,295,713,635,113,436,276,419,644,142,252,102,277,533,470,629,611,908,821,993,320,935,374,686,302,175,472,678,453,351,901,440,555,797,843,345,577,324,81,868,797,847,977,822,744,544,5,252,889,644,696,80,529,506,559,570,613,829,979,546,904,89,881,738,418,330,652,570,495,523,634,852,251,416,272,236,400,782,521,954,829,16,539,967,776,936,974,823,264,677,523,466,427,24,500,185,814,49,339,435,116,286,182,223,958,592,629,221,914,10,126,742,160,83,249,127,335,460,222,753,404,899,991,307,959,229,106,437,918,271,982,920,993,756,358,681,974,345,741,447,63,548,686,770,482,274,505,222,152,707,44,394,98,299,886,597,845,509,443,87,172,688,899,56,917,326,289,220,642,270,664,695,742,830,335,71,231,538,716,839,313,527,222,75,823,596,329,478,25,86,283,866,252,23,734,773,692,579,628,398,664,263,655,739,967,377,903,623,827,529,824,550,204,233,584,52,184,516,527,86,923,201,67,427,404,685,869,502,487,866,54,956,550,25,206,238,860,645,558,341,867,736,49,150,88,164,494,78,602,343,808,342,265,583,534,521,799,459,368,161,489,671,388,90,424,823,747,967,485,743,328,657,520,160,991,947,650,330,83,73,521,344,409,905,511,818,153,861,645,685,628,450,875,331,80,448,125,776,517,631,154,187,737,755,757,730,203,197,851,972,737,21,995,828,914,692,381,918,476,788,379,492,111,545,201,960,739,700,547,97,37,821,12,543,326,172,455,787,779,651,174,514,240,793,518,720,374,562,495,949,929,833,902,780,945,288,195,846,293,395,60,390,692,909,193,399,21,515,26,229,435,663,480,174,372,850,304,638,643,621,337,737,218,143,723,909,24,343,718,664,16,792,106,251,518,617,808,638,543,134,69,290,519,647,985,360,456,674,25,911,264,60,202,46,174,397,891,811,991,388,776,753,791,935,598,676,181,573,987,996,832,535,10,42,846,580,269,457,994,855,912,287,786,662,915,782,5,464,49,632,947,176,424,596,370,614,188,513,981,822,792,749,301,70,192,978,877,989,860,376,500,238,864,31,530,743,996,510,632,919,646,970,924,323,724,374,24,347,510,885,59,108,293,218,962,189,833,828,159,874,81,893,261,774,474,527,319,578,589,273,866,845,300,94,463,833,977,197,921,267,454,644,684,892,398,986,964,576,311,507,278,897,331,32,450,566,291,691,785,459,930,214,15,378,780,426,348,774,983,702,410,292,787,573,290,718,675,238,860,882,789,594,760,763,577,830,345,548,992,788,829,32,940,988,430,442,243,982,553,445,497,169,42,985,969,219,416,354,252,16,264,663,557,837,590,269,315,27,711,678,180,103,128,991,452,182,690,83,851,841,72,681,781,929,360,144,187,426,143,657,629,876,328,456,671,465,463,382,462,298,612,116,139,401,290,145,394,740,975,256,811,247,438,212,33,127,24,169,140,400,521,82,427,977,728,917,409,120,489,784,540,416,715,358,241,358,160,119,727,854,844,964,418,574,740,444,34,746,476,392,810,333,224,882,456,354,931,67,660,316,69,922,906,160,609,309,392,726,399,912,227,549,124,607,920,570,49,580,533,511,410,209,2,747,671,147,51,695,78,434,991,646,321,986,421,371,877,252,713,180,163,208,845,836,0,760,274,486,45,726,791,227,240,602,452,880,123,166,44,840,749,259,651,238,215,313,510,438,77,434,849,769,53,461,999,170,587,635,251,994,284,414,793,312,202,773,648,685,838,55,140,511,78,259,924,291,179,720,679,80,250,331,445,559,345,750,158,799,426,724,56,830,528,781,639,714,843,123,583,481,288,143,368,398,586,634,868,703,40,363,847,99,25,493,324,298,163,56,633,97,295,420,802,504,873,748,652,293,780,653,939,629,845,509,426,635,510,236,649,554,388,847,995,167,100,895,488,462,251,222,398,677,950,632,604,836,817,284,43,838,406,315,836,460,869,223,233,569,902,881,126,358,773,566,345,505,195,258,71,493,326,701,350,949,884,690,546,52,508,628,487,838,428,651,417,542,319,816,983,314,216,798,934,931,137,932,212,88,152,611,85,735,634,51,195,919,622,977,916,488,21,292,335,574,273,780,192,84,498,647,513,449,543,945,72,80,983,927,295,984,734,692,550,966,251,398,165,674,382,911,747,136,535,486,575,443,866,320,120,619,252,385,60,525,469", "287,530,394,957,412,427,162,233,382,24,617,151,747,960,101,907,276,440,114,822,784,895,194,528,395,830,655,952,339,778,858,790,280,760,504,142,387,654,37,578,273,601,304,657,272,758,125,247,323,808,904,355,180,106,164,503,546,365,550,675,675,508,356,855,199,442,915,642,71,497,381,15,173,758,889,455,833,168,795,973,822,730,30,391,78,750,878,739,903,69,557,746,318,76,343,580,983,205,338,258,383,651,148,824,31,513,840,257,177,347,963,59,152,504,959,519,515,582,949,565,7,472,796,245,845,395,228,703,426,349,734,569,415,944,113,343,42,304,8,278,505,427,651,479,87,790,305,597,778,243,742,219,170,253,181,219,720,513,79,729,48,327,720,127,746,897,653,220,551,573,416,719,156,977,894,193,461,789,692,764,936,442,31,417,365,726,311,325,206,97,417,430,302,550,312,640,427,199,731,724,999,444,783,147,353,834,386,265,436,552,202,602,967,510,341,723,342,654,796,219,177,608,179,994,851,847,9,153,394,499,262,199,805,479,210,80,475,263,334,659,130,771,488,903,439,466,78,144,508,701,439,791,786,860,728,756,39,609,32,792,928,286,924,348,531,404,22,412,248,779,868,767,418,85,374,288,297,409,613,467,901,262,100,392,605,339,474,173,476,856,57,292,621,96,490,366,104,657,421,565,223,915,472,237,859,774,245,977,406,742,391,102,211,802,780,234,784,708,696,963,2,408,741,20,407,778,950,403,834,883,989,590,606,595,842,972,817,860,47,64,705,888,334,345,910,833,952,415,893,802,30,451,447,735,97,794,312,162,515,870,138,968,328,297,736,423,295,152,275,820,235,28,967,47,315,795,222,453,288,733,123,316,472,431,193,241,614,916,379,703,996,351,937,997,55,393,599,574,211,460,628,559,651,629,959,642,467,346,976,272,679,667,733,548,360,105,571,845,380,314,17,676,534,750,252,363,707,371,604,210,196,123,151,132,389,696,956,479,447,589,130,672,589,607,410,802,915,309,935,939,129,369,238,657,34,948,19,951,405,459,605,419,497,585,553,694,142,479,181,754,151,128,880,652,913,885,800,974,777,688,899,212,22,655,451,124,974,150,477,965,338,733,350,51,258,412,468,148,267,395,620,652,761,105,820,328,842,218,196,235,854,555,598,327,265,480,418,370,285,224,734,76,946,216,605,273,932,430,17,212,895,485,13,242,36,857,947,999,216,516,792,664,592,496,65,749,59,116,586,125,820,963,349,237,389,369,321,917,757,603,388,583,79,66,971,328,128,66,679,810,55,776,904,148,526,166,907,82,374,447,684,794,837,514,19,75,27,113,102,671,406,21,114,829,165,65,527,147,40,718,27,912,233,18,512,702,603,781,859,500,547,129,659,231,70,774,468,580,625,562,415,833,436,769,373,475,960,534,851,174,574,876,387,390,740,87,661,655,492,124,7,906,160,49,70,205,204,414,282,658,803,822,686,187,315,730,622,296,733,517,911,988,473,725,652,406,224,287,897,12,128,557,722,479,66,544,266,432,716,358,273,197,38,788,577,830,140,751,715,660,367,810,670,956,900,991,729,197,896,350,249,193,966,456,420,246,921,400,400,348,614,240,611,658,292,522,299,110,348,197,964,693,604,840,398,388,583,12,666,106,549,856,828,920,520,398,640,665,96,951,371,10,2,342,563,599,399,253,103,482,492,289,290,222,749,777,768,71,651,760,0,873,225,831,755,896,919,403,631,230,749,10,929,382,845,931,75,71,663,278,555,424,297,677,19,926,463,889,621,657,735,557,294,503,892,449,696,392,169,743,273,912,67,458,54,155,865,9,926,759,42,375,746,160,947,278,912,509,591,978,97,606,730,413,408,479,396,873,624,446,690,830,147,779,780,946,805,26,823,101,447,261,91,502,310,352,55,316,815,895,622,221,460,337,748,721,163,278,337,275,313,808,880,38,750,232,341,885,881,229,914,871,882,249,401,680,79,165,671,199,680,812,202,521,513,968,512,674,178,547,301,818,19,780,683,690,73,840,527,849,821,827,319,585,427,352,196,404,83,800,566,377,570,452,526,717,901,195,635,116,687,503,54,459,579,35,789,266,62,939,673,71,736,284,846,362,860,378,499,893,137,670,494,632,579,878,287,919,294,547,171,490,357,93,282,940,676,736,535,131,338,795,234,155,535,852,502,862,820,567,257,91,737,669,39,313,775,266,132,486,546,484,4,245,457,228,688,16,237,489,367,258,868,364,316,995,397,598,778,267", "569,873,410,397,254,718,769,493,713,303,775,513,700,264,773,598,404,145,966,19,440,859,639,321,484,450,253,932,245,760,117,291,522,238,265,327,855,904,980,644,993,720,874,492,107,310,111,293,489,720,80,915,181,923,308,769,630,695,782,514,284,358,269,11,848,541,295,510,729,621,345,65,170,204,800,406,14,695,735,263,60,107,952,197,425,925,886,837,957,360,445,138,328,912,558,340,442,434,209,864,365,175,800,182,434,815,692,468,156,471,892,148,168,249,992,182,875,284,820,941,426,541,334,420,373,210,372,99,600,358,357,888,667,319,563,309,317,967,925,266,913,519,919,205,121,740,864,553,95,886,369,871,813,631,772,865,529,985,63,678,942,21,328,68,881,613,83,563,723,568,615,758,15,528,344,56,357,663,220,297,15,164,849,63,856,186,292,115,707,489,611,441,274,493,15,452,541,732,527,323,278,304,458,358,911,72,959,895,673,75,329,819,142,689,642,459,917,510,699,798,652,866,772,865,337,199,523,739,558,718,365,986,563,317,569,744,462,44,69,494,97,231,201,919,435,365,318,768,968,22,741,223,857,768,440,274,48,331,634,696,71,990,958,469,528,23,171,975,35,626,119,689,369,830,661,108,910,869,915,55,137,881,43,384,570,382,388,934,817,35,163,393,76,533,793,914,334,21,697,586,757,436,712,719,475,43,734,900,855,919,404,738,377,123,750,600,978,45,359,703,648,91,34,450,708,986,639,590,259,114,350,876,680,92,326,757,645,329,428,298,78,914,845,26,152,532,464,248,598,510,742,780,473,270,192,137,151,287,687,254,472,908,981,921,869,213,604,483,647,964,347,277,733,1000,439,624,394,239,807,282,114,738,895,821,197,679,118,575,688,97,772,917,836,80,553,404,348,294,110,584,568,570,777,960,117,48,822,257,670,94,617,475,751,537,806,523,262,219,299,92,663,445,766,502,217,916,843,84,357,79,954,394,517,435,57,949,108,636,768,360,340,195,276,827,161,763,624,626,533,453,781,535,705,356,373,146,695,513,969,191,54,311,895,439,990,50,836,662,460,894,663,36,242,250,501,4,848,655,572,381,716,208,867,848,861,58,275,384,992,82,592,169,701,226,366,602,538,367,270,497,404,621,453,985,39,855,237,817,447,140,27,169,532,540,51,45,221,943,174,917,379,856,636,569,722,324,631,224,976,648,168,186,980,686,874,990,895,507,637,385,897,374,932,341,249,79,385,432,619,989,554,118,45,429,9,201,549,512,425,94,967,284,446,950,575,761,498,963,857,649,841,440,388,953,198,488,733,673,891,763,487,256,536,180,359,421,749,751,412,864,144,681,610,4,183,474,219,245,92,820,461,140,574,147,468,219,488,114,428,66,771,464,819,332,743,596,637,451,889,782,864,869,533,600,576,72,274,711,714,150,963,416,169,630,724,687,137,929,959,756,382,218,306,426,147,881,715,318,675,488,657,199,535,809,385,835,572,210,66,28,850,458,550,406,160,533,22,545,65,25,344,24,926,769,647,542,27,674,301,111,197,956,169,223,991,776,308,149,888,164,973,143,375,457,282,185,441,272,588,867,6,330,287,259,348,226,406,555,260,491,536,817,261,995,128,925,937,503,555,810,693,15,317,343,988,644,61,904,449,44,459,752,455,946,634,889,434,533,263,12,171,972,714,485,889,268,180,119,277,309,317,238,223,38,866,819,804,653,694,274,873,0,829,940,849,655,856,157,43,931,324,106,653,924,970,869,375,178,832,227,182,470,671,510,871,160,641,900,373,513,7,492,981,39,641,19,689,482,934,370,830,662,302,427,313,388,479,513,240,203,342,894,428,467,374,164,363,456,86,782,554,172,45,308,108,13,577,272,994,871,578,271,429,833,201,584,991,77,538,588,69,235,575,70,131,210,616,831,701,330,898,394,210,729,62,186,587,243,196,263,633,181,320,941,77,513,515,858,273,946,462,64,113,341,263,653,316,359,196,563,853,932,242,546,519,158,465,438,883,310,607,120,61,664,664,437,858,43,530,872,866,369,910,330,256,871,938,124,775,913,896,411,644,555,727,151,490,754,182,962,297,85,943,943,167,748,950,70,735,216,742,739,286,682,302,389,365,986,22,612,953,787,655,936,109,747,959,797,93,536,567,589,658,294,15,857,361,59,551,949,784,999,269,371,585,683,812,166,678,672,150,373,790,820,787,808,24,532,113,167,577,819,630,686,342,626,797,152,292,312,251,457,602,855,428,393,977,517,574,460", "182,286,759,293,107,186,996,939,672,616,959,605,732,756,834,879,892,354,575,773,390,733,16,122,641,319,281,386,892,622,941,78,496,278,397,132,712,497,448,799,456,401,699,436,868,195,763,556,454,190,749,417,717,180,325,309,973,965,941,163,891,817,901,861,879,403,364,390,902,726,917,385,932,516,480,170,340,266,274,503,371,892,959,799,488,612,368,698,151,881,123,595,898,205,913,898,359,69,565,55,356,225,430,65,722,596,198,422,818,801,692,661,892,136,832,965,173,88,623,929,108,394,751,590,566,154,585,131,989,512,610,163,834,689,186,944,788,722,609,483,486,926,835,738,152,267,779,493,605,264,181,868,263,216,774,761,160,958,543,880,630,327,281,852,927,148,775,59,899,368,298,964,882,582,258,301,306,602,395,393,555,90,933,73,157,995,44,168,227,401,339,284,94,261,291,288,54,255,416,566,28,141,195,605,774,504,221,318,48,213,170,667,632,939,692,421,168,929,259,636,373,510,102,962,336,941,870,930,149,433,141,812,607,406,361,828,159,865,787,801,852,376,786,65,794,250,386,660,112,254,884,406,197,160,39,759,168,708,859,383,367,180,249,215,801,925,467,827,489,43,864,585,244,745,277,600,77,80,33,198,42,253,90,745,675,761,776,596,983,798,785,842,816,22,452,665,580,625,767,415,585,174,357,188,568,402,651,244,953,358,768,826,707,412,215,144,225,476,994,485,531,2,965,582,706,727,729,935,76,5,795,278,51,862,409,324,137,548,620,284,38,202,762,170,150,206,774,270,957,212,328,182,523,757,574,664,301,805,280,44,92,955,471,494,102,382,603,958,358,674,245,675,824,57,797,84,540,555,238,621,314,773,713,980,565,543,30,770,718,218,943,701,978,120,283,798,958,510,977,562,874,91,669,185,942,671,793,603,621,335,219,505,697,522,816,43,585,773,418,185,91,247,714,266,444,448,373,475,618,942,448,311,130,486,561,344,310,304,685,863,618,670,953,566,481,804,935,474,796,676,556,528,349,770,353,416,97,856,125,768,124,723,7,885,121,363,933,658,641,547,254,413,368,331,435,878,250,991,731,804,717,362,294,667,360,123,89,870,574,109,241,699,327,795,132,160,62,811,656,531,430,262,369,467,863,755,635,83,936,262,225,467,698,825,947,128,989,103,751,410,106,671,473,802,215,136,710,576,317,996,582,230,351,171,377,435,816,614,394,106,818,145,9,202,716,204,717,120,276,603,245,652,768,395,778,791,185,396,387,239,8,998,250,413,963,161,877,574,938,992,462,876,380,181,836,134,224,513,314,917,472,600,727,404,577,886,27,320,107,906,530,673,252,805,121,818,722,863,995,994,779,266,782,941,561,692,451,470,690,742,691,454,526,767,628,415,638,545,781,454,695,316,257,900,491,383,155,297,758,230,913,24,896,15,46,761,165,400,583,897,402,322,628,498,617,464,244,759,458,578,266,32,170,370,699,990,612,262,462,670,581,713,808,775,342,362,508,528,261,293,122,204,190,785,792,444,588,952,401,542,410,340,349,305,367,149,500,907,224,555,771,641,127,675,155,745,807,181,799,884,408,619,319,298,771,308,203,661,929,127,407,899,393,740,344,52,968,838,696,42,653,6,872,93,162,622,771,602,649,393,927,651,580,891,113,407,449,804,145,984,420,568,657,282,604,31,698,881,520,343,239,757,893,798,101,815,772,857,84,486,225,829,0,365,955,84,986,196,977,739,120,613,84,789,928,61,855,368,178,879,903,873,641,864,747,943,451,296,637,396,756,83,457,648,580,849,237,262,204,137,664,755,636,981,932,606,443,421,519,110,587,570,706,893,478,519,326,467,580,775,797,785,518,726,689,826,230,791,917,415,612,262,752,656,875,396,330,497,794,555,11,169,984,852,255,477,951,675,47,855,476,436,103,378,574,12,822,305,736,699,600,863,823,460,181,939,978,239,700,598,674,263,933,445,582,174,685,362,611,575,56,348,101,899,520,53,999,488,378,881,153,967,482,859,801,948,319,166,996,311,696,829,559,648,158,118,870,523,754,90,767,73,790,945,478,861,147,627,984,145,181,417,139,958,137,936,383,781,609,523,138,269,112,251,787,542,324,791,762,828,482,337,156,327,330,641,75,765,350,250,866,76,716,905,126,341,906,454,178,764,748,83,963,471,261,779,633,917,795,412,474,254,624,841,220,826,458,930,683,267,704,664,182,756,149,544,539,663,153,23,229,327,438,633,467,394,33,667,31,374", "11,333,46,645,395,141,168,716,75,926,627,336,1,769,891,821,873,500,987,62,525,323,135,731,306,46,370,11,900,298,209,793,930,68,671,959,306,707,157,133,103,84,849,746,188,663,561,625,381,751,257,281,966,294,466,501,105,905,807,676,54,827,842,61,767,590,45,826,603,123,479,583,733,539,235,15,193,885,575,61,306,357,743,189,621,152,614,674,37,374,398,663,691,660,410,85,616,918,287,977,18,696,328,279,129,594,705,105,977,538,642,960,665,98,295,548,951,129,397,890,78,65,616,355,13,735,288,784,205,40,339,31,204,329,273,234,392,491,835,884,880,181,962,326,904,669,368,845,18,910,690,529,399,626,998,569,557,384,461,188,993,53,223,420,690,440,514,101,962,350,819,640,131,579,44,258,418,612,495,611,604,206,767,14,220,32,28,93,175,214,652,954,585,484,333,853,893,507,642,200,301,439,95,508,478,448,90,125,299,369,428,856,878,443,526,251,380,499,179,56,193,368,790,762,911,272,158,318,940,987,93,289,409,366,970,303,547,332,128,534,387,140,614,705,420,164,589,841,243,956,429,290,372,911,548,722,271,832,481,522,818,995,724,700,596,153,418,876,192,377,459,763,255,397,284,671,849,44,11,835,521,373,820,490,140,268,88,508,471,867,834,373,271,149,807,589,446,807,813,435,515,820,912,931,968,64,12,508,155,719,735,332,736,800,93,481,158,692,914,577,929,169,775,669,506,843,516,188,619,321,617,678,483,602,609,727,32,616,234,196,592,193,245,1000,609,557,945,398,749,53,770,480,958,115,69,174,847,77,729,86,71,524,480,632,438,402,769,147,4,697,421,23,457,438,684,665,63,973,271,236,294,416,912,158,739,9,858,110,838,997,683,842,114,983,52,11,997,985,149,897,292,456,547,97,700,39,628,829,102,861,124,637,376,521,950,359,379,439,93,241,662,286,466,115,393,83,875,692,99,612,388,972,274,570,715,481,898,460,126,339,710,280,243,980,999,438,211,194,802,563,363,743,533,874,129,877,420,230,669,678,791,600,479,56,115,346,741,434,72,74,555,683,791,394,719,202,849,19,199,619,484,928,601,583,390,41,802,64,28,885,665,493,783,388,926,308,960,77,166,519,69,69,781,859,275,232,288,51,547,938,846,791,962,784,797,588,574,975,139,437,455,854,704,81,43,893,961,909,199,366,679,437,396,979,547,359,578,561,666,613,441,131,95,578,700,586,366,109,278,742,846,705,922,811,897,117,119,35,725,174,858,668,77,95,947,870,686,583,498,607,543,156,447,348,82,451,660,505,990,769,506,909,557,368,464,603,991,836,509,501,152,921,723,59,492,593,975,627,189,44,609,927,193,76,65,209,490,33,462,419,313,171,414,414,144,499,645,927,491,704,387,566,214,171,469,301,715,490,241,676,830,436,582,871,138,233,213,731,753,453,861,572,807,448,625,754,83,312,187,657,631,823,915,571,162,599,614,498,615,629,253,686,387,597,849,845,907,342,202,709,704,905,136,77,996,324,655,563,538,688,751,960,814,690,888,283,867,537,112,391,782,963,476,215,493,868,952,437,414,180,949,461,641,62,264,303,315,290,992,610,585,658,883,246,796,939,662,485,809,128,466,876,661,758,964,680,197,87,771,184,323,493,814,781,649,862,372,282,368,963,879,878,544,642,320,662,36,84,294,131,428,88,18,451,363,268,171,366,72,45,831,940,365,0,66,228,213,691,718,657,528,412,756,143,316,321,544,780,356,790,523,4,980,775,249,347,366,710,49,829,472,161,169,935,265,299,253,306,308,348,653,381,806,249,296,248,557,576,32,640,353,30,382,198,500,417,350,617,168,467,521,924,483,680,641,664,862,482,413,80,261,798,500,802,688,711,387,619,376,888,933,238,874,504,368,819,306,799,577,933,159,800,943,960,600,967,512,122,53,339,770,551,484,798,3,322,858,809,687,892,696,139,35,951,668,925,729,822,104,831,965,265,297,211,564,366,600,158,671,420,699,550,182,173,637,510,740,598,180,463,782,161,582,787,88,679,86,890,160,363,796,505,616,111,375,579,309,945,911,34,48,814,355,960,43,432,824,188,392,428,439,115,567,501,432,85,530,491,293,194,31,588,382,497,74,64,160,90,547,999,952,31,910,255,285,604,460,915,172,18,679,30,455,103,559,898,48,103,127,672,305,523,264,163,862,436,909,590,563,198,436,264,436,766,234,299,531,958,101,519,788,354,855,248,84,18,193,940,348,613", "604,221,246,50,785,274,859,583,73,951,376,329,511,472,714,316,520,551,152,756,609,530,997,643,97,428,281,682,654,308,31,606,923,388,319,220,944,377,490,300,696,525,929,641,675,85,924,877,221,484,199,756,868,867,172,310,197,7,257,872,368,37,499,14,76,589,481,226,928,263,31,410,848,733,537,160,443,30,999,416,471,7,255,56,16,860,346,716,385,697,620,573,888,514,298,815,142,489,877,274,778,795,989,53,465,109,173,26,531,188,569,373,109,281,798,155,784,397,51,783,766,833,495,982,522,758,122,332,804,984,410,745,771,450,233,792,310,859,488,763,957,101,202,252,841,739,570,840,527,86,815,817,693,749,668,516,810,808,702,585,438,877,278,375,358,767,729,973,545,533,463,449,762,100,643,612,716,580,866,525,578,879,417,183,317,656,267,338,191,931,338,474,759,629,609,992,448,585,8,353,550,390,937,656,7,647,121,872,283,628,534,13,697,818,422,242,872,619,149,480,765,446,182,763,650,793,738,507,667,438,781,746,691,844,852,791,422,458,573,108,256,911,835,519,833,322,456,643,696,132,541,938,560,430,829,178,31,473,939,465,42,470,222,828,946,381,260,83,832,58,338,286,925,451,601,475,381,474,732,251,354,47,109,438,8,457,185,85,593,512,625,84,255,444,295,84,295,799,667,801,249,919,218,223,948,974,732,529,508,135,959,43,307,483,41,949,46,68,12,523,59,701,897,186,280,392,324,987,697,190,839,629,552,906,810,573,513,847,513,430,767,284,118,58,436,222,423,228,411,614,862,908,891,611,512,504,654,179,859,584,174,618,677,942,284,661,619,409,546,628,833,545,831,70,484,656,338,10,694,912,539,372,170,853,824,705,42,265,683,178,581,26,414,566,977,942,809,427,825,487,280,834,748,936,8,274,27,742,211,192,781,665,826,198,739,915,326,470,752,880,882,850,35,131,376,241,242,761,668,703,684,939,580,608,934,154,586,322,225,960,902,580,538,41,155,693,745,988,508,751,373,500,166,359,381,106,447,914,210,700,997,515,466,510,459,656,988,317,146,836,766,831,13,365,960,110,562,262,39,622,469,630,833,545,963,258,311,142,779,672,903,149,344,452,288,532,105,674,225,951,769,317,24,630,664,602,134,49,922,968,399,949,147,811,388,605,695,448,108,20,142,233,987,748,45,711,343,104,804,965,387,133,705,871,450,206,488,583,811,792,946,522,417,519,119,109,215,465,637,179,89,42,587,92,894,164,408,48,815,860,952,583,58,419,608,546,122,93,974,592,640,293,354,928,388,946,574,751,40,500,504,927,481,418,952,36,801,264,213,568,389,80,760,393,319,998,346,484,478,344,156,139,182,806,932,365,541,329,612,548,13,205,283,185,609,511,826,586,287,441,259,43,603,733,75,477,590,568,254,944,66,688,80,997,740,809,316,714,401,228,537,88,705,770,682,130,298,720,955,757,621,931,287,804,852,402,323,271,616,593,47,56,195,426,438,833,571,215,788,605,377,391,184,672,421,994,223,863,68,412,808,716,81,316,464,42,929,540,536,730,948,980,224,58,513,921,5,54,447,369,510,598,667,280,439,540,752,204,766,76,329,587,982,384,156,439,566,874,772,856,29,723,306,532,388,803,481,257,970,609,885,553,52,852,468,978,436,6,233,200,328,728,116,855,147,193,455,988,219,992,853,112,878,457,534,580,554,915,350,726,755,849,955,66,0,614,983,167,813,659,567,203,869,353,188,138,352,669,155,570,366,30,197,479,729,848,47,133,915,414,838,298,983,700,472,411,894,721,879,878,743,128,786,486,219,66,685,721,620,477,962,28,504,676,761,556,142,265,422,14,44,906,568,819,940,885,7,82,820,164,85,744,217,608,933,367,410,574,7,972,215,671,901,679,513,145,907,545,794,601,891,126,69,217,430,386,328,570,700,464,824,422,649,40,906,549,663,234,67,825,54,951,179,818,781,670,531,147,975,677,354,691,726,641,859,156,584,457,824,684,176,677,191,275,296,747,286,396,805,263,123,857,236,519,706,863,700,853,968,561,752,148,194,359,907,379,420,633,694,852,895,17,93,23,502,687,819,416,270,565,529,319,550,255,36,388,638,892,441,818,696,350,185,130,91,170,98,853,651,585,865,874,783,22,517,985,29,923,78,945,464,566,597,481,941,795,316,45,381,674,564,146,45,572,76,881,218,936,782,777,423,631,847,475,331,736,533,466,271,575,959,846,541,320,617,100,348,594,514,331", "384,223,275,469,784,981,901,922,597,760,440,6,369,270,123,835,500,933,629,270,734,981,20,138,115,840,988,919,313,996,904,72,144,156,925,758,486,434,442,159,987,994,223,418,704,801,336,525,386,8,338,615,245,669,114,882,701,972,804,988,938,298,565,512,451,589,484,399,391,15,749,293,143,713,181,840,903,726,471,480,354,328,26,512,932,846,557,920,170,856,594,947,538,558,164,206,77,962,943,128,252,437,514,681,654,344,912,650,850,784,923,872,324,417,144,615,723,552,35,969,834,214,793,961,649,781,164,108,491,652,284,107,138,483,953,890,213,578,900,958,94,847,898,410,899,666,814,269,133,781,941,186,585,894,424,304,994,916,349,960,578,921,353,42,347,177,654,466,971,165,910,946,299,146,803,272,215,374,423,324,928,733,908,397,129,327,161,97,413,698,687,33,644,789,957,676,365,214,641,657,937,212,503,591,380,520,318,373,384,100,656,404,599,144,95,363,228,956,221,898,893,894,896,291,420,896,255,142,925,648,167,955,850,22,653,907,509,486,347,846,940,571,208,171,940,997,902,141,444,836,499,123,777,472,424,155,461,698,720,180,450,198,401,871,488,385,551,752,582,250,263,593,640,357,378,568,169,608,186,476,32,562,465,997,499,937,231,866,320,843,989,843,959,481,199,149,541,902,538,242,137,454,828,708,32,192,949,306,202,621,991,732,89,371,256,345,855,277,243,216,38,548,655,470,84,542,693,902,223,128,929,429,528,695,477,114,678,90,806,551,754,491,166,259,126,212,354,754,628,823,421,969,962,943,405,88,115,423,173,246,15,472,430,3,866,766,387,207,748,613,111,855,79,676,175,300,297,107,448,989,516,529,822,281,441,230,902,117,818,265,367,897,771,279,643,140,914,49,971,527,543,421,594,210,931,294,91,334,472,488,892,486,539,828,498,127,661,455,639,52,251,893,74,186,357,589,182,927,689,995,848,486,9,248,167,537,760,557,151,248,523,154,439,207,501,825,136,522,953,458,956,338,465,816,221,696,135,882,819,721,474,766,83,29,432,775,484,271,705,183,22,557,623,121,395,965,723,969,420,860,722,824,803,842,936,414,969,194,558,678,756,539,771,219,706,70,98,628,874,499,580,619,311,582,341,562,101,140,606,406,850,884,679,533,251,100,701,641,303,920,521,719,436,859,809,731,113,697,41,76,816,211,8,403,999,223,868,324,22,762,547,2,85,730,502,317,167,490,27,960,862,75,659,756,897,367,929,720,907,121,145,187,486,636,989,820,680,319,582,398,827,776,163,882,984,731,306,855,481,922,963,52,132,282,643,214,863,473,422,515,13,496,695,648,114,784,917,626,408,267,793,621,71,687,683,758,787,401,202,3,687,835,717,237,655,138,224,448,816,670,794,105,626,739,287,373,336,165,568,442,136,135,540,411,410,430,274,578,205,965,503,875,139,165,962,835,159,249,198,178,779,38,34,439,61,637,995,362,637,183,223,524,401,22,572,212,895,738,52,653,452,171,563,350,74,879,305,485,650,609,643,890,939,803,796,106,143,186,194,978,853,469,826,250,584,803,835,132,35,648,639,618,50,395,943,606,536,625,565,867,789,750,308,837,253,542,466,592,700,887,533,40,915,316,896,670,798,408,509,482,764,185,447,576,754,899,663,291,631,400,948,137,503,287,231,229,701,840,280,815,573,221,156,780,679,114,226,231,358,791,896,655,84,228,614,0,788,530,780,861,698,234,666,471,165,679,982,311,225,85,758,5,494,44,437,30,455,360,458,692,81,139,526,54,653,275,522,879,404,72,21,154,139,986,56,879,511,91,503,200,115,686,601,608,826,222,167,870,867,466,286,677,430,123,683,717,17,787,627,206,929,8,607,230,881,949,206,169,724,174,689,431,299,176,178,239,998,68,602,392,630,382,344,926,634,616,623,513,914,698,428,185,12,881,301,93,774,228,444,982,93,365,686,973,606,973,305,916,668,912,910,710,417,685,910,167,303,657,93,393,621,586,111,185,431,498,984,363,952,73,755,853,915,117,26,532,961,718,430,531,857,573,197,929,268,911,732,186,493,339,866,983,918,181,256,793,269,226,616,151,886,71,593,767,556,494,78,898,207,504,483,187,586,93,587,423,885,442,373,526,181,852,900,685,836,795,178,607,410,771,646,928,62,559,506,490,296,104,708,493,115,47,352,768,739,986,764,196,841,848,355,76,624,900,132,231,314,359,265,600,972,95,625,765,599,843,162,283,269,823", "440,95,400,67,220,777,93,471,599,904,289,28,346,248,955,275,220,376,58,601,337,543,882,393,951,695,567,178,910,302,388,445,496,383,688,649,887,844,209,767,843,54,998,38,894,444,540,300,991,984,244,408,96,802,238,262,365,128,645,236,166,542,818,340,681,171,173,126,975,668,161,189,318,63,885,378,811,656,786,324,114,469,876,575,997,951,65,365,292,358,54,727,583,123,516,868,835,652,179,112,886,40,596,873,571,874,804,753,778,873,516,90,9,426,756,75,972,657,597,621,109,764,96,786,883,705,826,62,193,673,624,505,950,638,175,408,252,11,81,581,705,493,909,428,445,303,984,619,623,620,190,121,584,674,341,772,759,518,435,40,871,94,401,246,951,692,299,772,43,66,362,432,498,148,927,338,375,696,157,207,295,377,668,958,884,548,272,970,140,944,39,839,778,905,277,952,658,894,843,14,132,272,872,32,59,928,446,534,576,185,363,918,543,661,402,500,607,922,679,934,336,640,726,687,174,787,101,18,470,736,639,275,848,116,350,434,401,993,104,370,544,770,427,727,55,157,345,406,181,285,417,234,757,693,111,268,80,363,663,730,924,893,710,618,855,445,245,392,409,780,150,591,349,366,522,265,712,864,144,941,174,790,162,844,507,196,585,844,680,250,384,707,223,217,397,764,463,20,200,629,646,168,26,86,676,421,220,521,276,404,985,690,647,19,812,348,657,419,902,968,246,741,294,77,893,281,646,222,611,212,463,223,857,490,439,634,199,26,750,964,340,624,377,660,946,598,257,854,613,203,876,144,751,175,735,617,847,828,597,285,557,263,474,761,436,844,146,160,624,127,909,595,947,288,915,730,234,782,754,946,342,805,7,98,195,934,24,572,574,755,760,700,547,660,461,203,447,515,259,992,430,915,278,544,248,270,628,904,788,331,52,791,55,196,197,727,706,498,985,950,275,876,475,333,625,918,287,418,553,646,11,730,453,968,413,439,286,559,838,410,215,99,641,843,604,336,251,529,788,176,382,345,704,776,159,302,745,141,355,721,342,987,539,967,857,245,503,431,834,211,708,78,994,638,48,111,357,466,84,450,907,416,817,939,41,875,654,431,236,220,199,274,197,885,654,339,440,66,122,705,708,443,115,134,250,875,583,165,46,342,131,996,13,747,15,312,498,434,91,163,852,574,739,395,820,233,483,803,301,819,861,208,685,587,560,466,655,572,24,703,611,587,907,939,529,377,482,257,139,190,749,867,520,22,398,325,198,999,739,353,861,472,841,710,939,435,691,495,122,394,687,273,208,304,954,614,354,855,563,844,121,610,634,293,844,194,963,659,374,973,128,918,51,574,358,636,653,868,508,381,118,28,208,744,354,491,897,92,565,664,759,433,803,505,148,186,206,61,754,16,618,488,730,166,701,972,404,908,166,10,554,423,203,722,404,387,697,502,96,481,240,315,251,561,478,44,577,767,638,19,490,201,966,551,855,221,469,229,276,198,347,39,758,904,573,211,838,349,99,724,120,961,56,710,154,177,498,595,429,543,585,12,71,58,723,491,634,552,618,250,489,373,702,831,909,754,971,438,108,378,114,675,239,96,425,672,401,382,858,182,920,941,576,460,976,888,904,706,791,218,116,492,552,503,29,690,949,263,138,148,795,587,811,861,671,374,171,271,592,160,251,422,509,4,882,831,765,346,184,217,596,375,519,272,950,617,694,8,847,227,919,856,986,213,983,788,0,443,710,851,282,283,859,603,69,616,335,520,963,198,31,91,388,352,906,981,802,771,730,204,190,440,456,433,127,890,545,765,403,335,332,942,921,552,892,424,236,534,463,697,776,879,620,614,706,326,213,149,417,274,479,672,886,266,482,571,960,910,708,322,423,888,98,452,763,21,654,940,430,602,192,610,604,619,683,986,560,935,321,40,285,18,863,330,732,840,680,358,712,272,520,381,737,590,498,754,601,753,288,885,244,827,61,588,505,664,391,492,415,346,389,735,400,126,233,404,318,697,368,66,350,90,50,620,114,983,657,736,965,845,278,362,976,349,548,999,574,407,311,977,102,572,305,757,375,463,675,233,44,976,976,209,337,521,733,890,817,421,619,715,157,488,923,707,139,762,526,986,483,278,861,127,903,561,178,399,371,692,403,937,415,814,604,977,751,310,737,769,603,641,176,940,713,688,731,695,956,617,690,744,27,174,904,764,241,220,293,211,278,842,87,391,642,862,919,635,27,465,738,947,498,345,891,320,76,762,599,11,36,113", "914,665,664,923,876,558,630,365,951,408,173,906,444,216,852,625,182,235,31,71,213,671,713,130,937,710,629,535,602,17,782,200,365,529,141,68,735,886,86,954,893,977,896,168,291,861,715,664,256,773,554,249,243,72,789,773,855,924,643,751,600,372,77,986,476,595,208,565,205,311,120,1000,975,469,471,860,732,770,503,641,138,628,98,76,240,148,318,930,31,365,730,281,478,506,338,691,545,432,463,943,493,30,90,471,489,913,971,578,587,728,151,236,761,259,665,29,623,313,898,150,242,793,473,836,686,3,328,140,48,785,904,874,192,304,850,153,309,850,458,299,825,923,454,955,570,194,587,626,806,87,756,654,221,954,248,149,328,156,923,748,509,56,311,495,466,552,897,577,630,494,333,344,698,426,275,632,263,962,403,840,396,670,401,776,672,586,215,832,937,516,8,47,106,905,912,398,338,818,362,444,860,952,210,959,561,471,751,630,267,237,527,378,858,372,206,754,144,283,509,491,651,575,875,756,715,844,552,376,199,659,258,272,637,896,581,84,457,181,450,869,697,355,856,363,613,655,257,90,386,538,970,235,471,812,739,978,867,273,409,419,575,784,847,288,13,278,10,285,918,670,679,602,782,316,37,383,200,142,419,577,786,237,894,947,595,580,686,897,232,780,708,114,586,13,994,818,134,812,370,805,615,670,619,583,425,192,502,394,680,464,712,375,541,694,538,50,8,181,285,628,298,304,646,218,584,975,917,241,474,13,711,533,637,36,624,102,41,80,301,633,725,319,782,512,296,832,564,906,445,27,201,236,9,658,338,131,457,152,427,125,249,474,125,335,410,512,203,908,559,475,555,695,943,420,105,294,880,400,818,568,642,453,424,387,682,803,980,776,537,365,370,675,608,455,229,297,256,489,12,504,866,893,346,600,469,487,867,371,249,598,230,372,37,59,555,11,642,47,173,91,258,643,298,186,753,444,510,967,608,360,963,703,124,204,523,187,671,188,634,14,24,886,520,283,635,105,697,130,127,885,636,703,638,779,193,791,701,669,429,589,341,863,659,364,599,338,444,859,651,463,613,875,562,109,282,93,223,352,872,305,726,386,962,476,242,399,507,850,796,359,575,655,768,31,472,819,92,925,788,381,921,262,372,428,343,813,364,588,118,489,774,184,207,885,383,104,514,339,461,304,311,90,896,694,160,978,585,354,91,452,379,612,980,138,310,159,145,308,493,227,775,96,187,836,518,975,674,78,852,76,877,896,135,897,233,795,421,992,661,335,47,74,634,698,117,887,402,102,225,448,238,454,310,622,889,494,29,476,430,840,438,445,308,831,891,332,48,190,368,779,972,219,7,206,393,314,229,442,497,455,277,868,488,784,146,216,841,212,74,882,757,835,609,696,171,113,539,359,70,899,134,853,819,317,312,31,199,571,489,569,373,759,255,93,589,871,679,527,155,762,339,823,199,282,216,865,43,396,442,649,412,232,584,649,317,586,706,143,234,931,445,114,714,407,875,342,354,444,292,487,337,626,26,478,91,621,640,913,384,142,178,341,676,821,705,821,853,667,868,545,877,626,884,423,551,70,759,363,763,669,179,430,237,151,186,602,632,1000,967,321,323,978,354,882,760,745,980,264,566,700,240,219,969,621,973,651,541,670,950,271,983,752,193,483,425,488,818,998,359,918,80,333,646,113,403,914,710,853,20,553,322,142,478,543,286,49,748,333,342,240,403,157,196,691,167,530,443,0,114,148,993,745,979,132,149,74,117,84,435,844,37,267,853,19,945,140,555,696,618,64,951,69,424,444,569,791,721,239,59,627,68,140,791,169,407,344,63,88,790,395,949,702,51,651,493,321,899,791,796,529,993,712,242,245,880,330,554,250,850,721,988,652,160,337,38,638,494,750,650,162,599,198,120,658,467,528,76,188,745,523,902,295,615,106,269,458,766,81,297,726,488,836,43,415,148,920,258,588,793,543,165,249,225,413,716,334,984,466,941,622,478,978,828,309,711,536,304,220,10,159,335,266,14,912,71,446,170,307,16,155,387,491,305,154,236,837,733,913,720,76,263,835,926,443,519,4,159,171,691,931,381,226,462,497,339,539,682,131,836,396,181,185,149,102,98,706,487,66,429,924,563,766,545,149,171,837,600,89,706,46,941,224,125,297,496,181,49,639,749,376,425,787,315,527,54,575,87,398,436,151,113,446,339,435,526,115,800,721,371,929,740,241,66,495,887,370,390,862,846,538,613,103,61,667,873,323,853,185,181,10", "286,884,787,552,21,152,989,919,499,508,646,258,695,402,209,484,63,593,951,117,37,420,438,112,422,496,648,102,511,899,982,158,130,114,94,480,696,548,751,540,650,709,725,977,117,193,133,152,595,960,513,360,819,866,166,405,705,641,460,244,15,237,575,842,176,971,761,7,504,819,454,962,24,712,629,554,226,704,624,576,86,201,461,491,550,188,292,413,297,608,948,30,207,968,726,586,875,716,488,59,470,246,371,171,470,175,74,349,515,293,346,14,986,285,83,596,49,473,349,940,944,302,522,451,42,219,793,467,466,572,85,543,88,518,976,71,93,3,701,237,366,564,963,945,864,506,820,405,890,251,599,922,116,508,298,791,823,328,741,500,403,662,782,995,810,877,575,433,520,129,805,285,418,864,858,85,472,288,535,944,368,688,440,236,931,845,599,407,520,632,511,822,266,127,608,585,766,46,732,696,782,779,944,331,190,671,42,531,880,165,45,837,105,474,291,543,804,963,884,764,885,12,347,17,55,43,39,233,756,324,256,900,830,90,471,282,600,107,284,573,465,553,688,823,184,101,729,3,738,946,357,128,537,735,21,340,311,612,856,887,712,166,207,535,326,847,829,842,527,159,485,375,835,807,446,357,106,243,62,93,129,572,406,861,641,213,777,328,210,649,420,36,213,751,217,516,580,48,690,794,628,96,428,582,155,630,348,70,120,966,949,762,625,35,607,534,703,763,478,355,924,262,3,328,809,400,846,420,943,363,667,616,731,84,584,711,347,465,747,171,66,503,594,205,375,858,372,771,544,467,874,703,655,581,154,723,212,125,707,800,695,990,907,362,958,926,51,124,39,57,423,854,257,932,729,547,616,140,233,558,280,17,170,953,286,943,220,278,40,696,291,252,245,902,829,965,735,994,549,784,106,51,388,346,740,164,424,554,823,19,710,820,465,873,63,60,445,43,168,382,924,301,109,154,368,399,225,121,60,309,993,365,533,200,485,482,399,607,405,582,351,544,330,700,962,377,702,871,148,496,352,720,55,608,635,828,80,900,158,208,853,39,593,634,719,255,96,950,684,34,1,154,240,723,787,723,938,427,947,418,752,48,155,601,486,17,687,247,621,505,599,76,154,857,750,549,499,115,687,248,715,637,895,530,507,40,144,510,776,637,713,183,594,819,843,387,545,625,53,882,311,188,357,247,597,446,268,816,506,634,933,382,245,865,621,939,23,621,939,575,708,418,739,48,592,371,903,573,465,71,882,188,266,61,974,401,913,680,725,760,610,394,683,203,930,756,251,832,774,560,386,236,234,698,888,544,626,836,206,579,820,711,510,538,251,178,513,408,547,980,762,753,490,486,835,537,150,830,677,910,410,454,100,644,932,634,124,580,39,586,561,325,644,976,168,730,94,625,258,612,936,365,677,980,126,188,111,946,262,730,914,49,254,377,363,731,435,962,473,147,578,566,75,194,20,590,431,368,883,234,722,536,714,624,411,135,424,578,512,663,761,317,445,156,532,342,590,318,171,555,748,445,255,498,9,766,314,826,427,773,905,137,314,435,8,203,77,696,163,860,40,954,820,72,51,296,951,817,393,556,975,675,157,424,348,188,17,324,965,292,523,321,220,872,236,732,436,838,250,295,678,164,793,825,18,636,675,715,4,3,802,52,598,21,945,132,429,461,834,995,26,104,15,679,920,974,685,301,766,957,842,62,629,487,324,838,996,294,10,602,631,43,977,718,813,780,710,114,0,418,868,568,504,326,743,549,246,592,669,724,260,916,953,362,470,30,151,279,434,143,299,611,372,638,359,969,664,298,3,974,921,165,834,528,98,176,873,778,989,316,792,575,427,101,353,719,900,285,830,25,161,111,645,78,324,562,400,695,954,783,927,97,265,137,188,246,525,886,662,400,302,187,787,427,169,530,812,673,740,675,901,831,225,824,586,857,575,900,639,45,803,507,948,26,194,902,33,60,369,160,845,242,37,237,302,611,362,756,38,553,302,636,867,36,229,275,337,66,414,950,280,21,171,819,392,291,190,567,210,156,345,761,369,295,857,200,631,792,619,197,419,783,943,605,732,56,287,422,921,618,265,231,957,529,93,244,968,46,512,75,971,898,755,27,512,631,310,519,182,167,575,355,808,33,637,99,649,955,127,24,379,573,18,209,607,603,591,135,803,812,825,838,137,390,267,703,502,335,425,815,512,596,513,819,424,99,903,299,655,78,495,656,320,144,405,160,485,490,592,516,220,550,712,548,172,103,679,587,130,67", "110,235,817,198,6,635,343,736,649,516,976,75,742,197,946,251,931,560,76,220,393,904,770,185,97,445,430,827,483,541,365,997,878,439,829,953,318,495,806,446,731,347,101,575,485,108,596,737,683,966,615,919,414,804,266,907,140,832,156,703,968,80,563,676,146,999,621,618,402,391,725,77,506,920,218,429,537,205,369,844,878,854,29,636,793,612,214,124,488,223,902,859,428,455,302,866,870,260,799,246,914,811,635,236,266,185,125,953,460,924,697,678,334,541,404,300,358,241,180,256,88,868,355,779,464,590,66,883,11,696,263,314,968,484,832,457,532,805,792,551,547,81,125,767,460,875,868,505,622,462,102,602,857,837,187,468,625,907,955,799,672,901,273,635,484,177,775,342,425,493,673,566,176,23,381,93,513,879,732,666,332,429,552,175,863,972,990,561,39,729,832,247,811,936,175,728,890,697,794,434,328,539,968,205,292,89,255,503,883,680,524,632,626,745,143,786,591,725,654,744,781,894,795,851,452,871,506,711,217,30,318,883,889,99,656,535,792,279,166,449,882,384,360,811,188,696,300,873,330,291,62,795,637,59,693,33,564,259,876,391,391,394,878,102,129,607,493,95,145,363,645,387,311,814,751,493,261,679,45,758,121,432,412,673,825,965,433,949,263,375,729,732,860,814,201,704,126,720,670,614,59,801,544,541,735,639,230,957,241,400,348,322,230,583,906,186,179,77,375,763,540,792,129,199,443,871,688,897,693,657,343,802,279,322,984,224,374,550,39,794,804,901,80,902,605,435,280,821,150,576,720,203,339,780,213,354,616,558,101,57,250,623,179,190,63,976,220,770,546,71,744,953,617,761,10,798,22,574,420,431,68,286,218,539,142,139,398,91,446,712,856,195,688,977,647,27,560,167,912,531,692,540,408,850,666,690,480,745,304,675,403,203,30,216,845,320,405,587,668,857,549,40,607,217,282,228,379,470,863,668,480,958,150,168,431,208,777,606,751,382,652,404,461,487,143,747,906,633,518,927,779,14,709,141,892,259,9,628,61,745,578,211,224,23,824,552,397,149,815,957,411,382,186,599,934,827,505,132,900,902,916,213,636,457,182,208,941,316,981,818,557,765,824,71,671,359,431,325,715,460,306,465,885,352,758,226,519,387,800,165,295,802,578,121,118,329,791,954,37,286,881,797,180,224,265,993,16,208,5,218,959,527,525,248,440,955,141,439,562,507,419,298,298,273,678,899,909,63,819,837,176,527,374,681,183,263,167,201,816,82,652,403,530,133,926,489,536,845,801,968,684,73,178,830,187,169,915,565,962,457,472,417,881,426,164,218,596,700,520,894,57,344,782,192,190,842,857,798,571,735,935,186,252,20,44,51,470,702,851,533,945,848,767,377,322,120,106,906,376,607,499,688,757,219,243,734,295,526,295,993,592,138,98,878,620,724,181,772,321,384,515,302,808,728,534,674,580,682,174,344,275,516,987,465,158,532,753,818,967,710,334,834,561,395,768,597,702,382,184,355,268,601,694,774,835,177,347,936,791,620,90,251,584,993,608,383,641,12,89,388,742,751,501,789,832,204,162,295,866,239,967,774,37,222,914,499,973,427,592,664,959,312,509,910,988,567,169,666,50,248,68,604,736,642,351,764,429,588,60,550,225,758,523,88,264,942,719,957,942,81,738,633,689,625,520,238,482,314,587,926,395,863,152,831,776,241,504,7,201,452,230,931,739,657,659,861,851,148,418,0,107,9,953,737,790,642,66,35,642,884,164,355,317,521,64,274,400,560,868,331,556,894,581,519,402,987,79,308,849,33,891,450,889,480,637,789,143,263,186,663,303,727,18,918,684,235,184,604,755,776,538,603,928,745,656,212,936,950,996,661,359,573,447,386,381,35,279,491,113,969,569,932,94,874,390,978,160,413,737,64,245,33,816,771,202,802,269,340,624,505,194,569,527,999,209,607,850,706,957,671,698,411,565,414,696,40,663,777,344,541,545,722,721,772,887,811,764,871,830,601,17,506,616,824,549,184,839,931,949,499,810,667,893,176,420,546,140,263,387,252,574,702,96,972,570,463,61,505,987,653,791,843,956,938,464,548,358,122,226,785,293,416,611,399,18,853,4,590,294,625,981,172,444,314,721,873,240,747,435,916,608,431,495,295,245,801,745,858,292,834,212,762,970,199,809,989,200,461,987,813,503,428,650,578,655,706,541,288,756,310,183,321,650,964,241,973,403,446,694,185,921,976,963,935,798,424,976,876,789,333", "760,8,860,698,904,279,85,251,928,547,201,806,365,460,392,450,212,60,470,756,691,182,281,644,429,129,591,908,326,618,254,623,812,561,49,87,691,352,879,970,460,701,392,271,781,288,806,165,767,579,312,131,713,845,334,376,939,918,368,998,389,761,38,900,606,964,675,369,427,965,655,370,595,992,302,780,873,360,129,230,303,943,429,355,175,259,153,752,328,504,831,159,959,869,810,388,919,935,649,142,65,602,10,369,197,565,224,436,924,799,335,761,518,727,31,420,189,980,784,554,514,131,340,976,98,102,530,161,977,49,644,894,325,69,594,803,388,254,315,694,289,32,674,732,361,483,912,852,764,405,563,989,670,159,143,93,80,827,656,145,223,809,430,421,899,601,41,336,207,610,572,626,590,659,114,508,357,580,642,910,195,282,615,361,243,452,436,933,505,207,770,99,862,332,27,660,478,212,93,392,141,482,810,421,58,350,945,723,220,212,485,741,886,291,205,726,142,693,147,483,617,961,94,515,454,375,186,51,834,962,901,863,198,811,582,79,595,594,85,914,438,623,563,566,994,891,22,328,852,986,412,918,856,932,13,828,871,107,982,116,603,262,331,157,339,849,432,183,60,726,797,383,553,607,419,590,117,740,126,856,526,2,275,152,92,568,184,206,948,680,690,769,285,497,784,143,769,564,568,855,206,500,359,484,271,490,513,641,993,260,551,605,463,142,274,921,831,154,909,28,33,724,672,276,65,48,32,944,546,808,502,105,480,34,998,597,27,769,529,163,653,881,356,213,266,361,629,884,227,580,547,80,675,917,890,989,265,151,674,241,836,258,647,95,175,18,215,433,819,206,994,366,396,844,119,450,13,552,148,75,569,84,231,942,348,774,867,37,959,220,142,789,504,762,499,839,539,706,737,739,705,844,641,911,503,206,962,210,241,148,160,214,982,602,898,861,952,742,409,178,207,936,794,597,774,392,838,589,401,605,177,656,593,978,464,699,597,670,952,667,578,626,582,971,117,535,713,265,126,747,295,279,74,524,843,21,271,870,226,777,784,57,228,292,975,648,366,312,70,427,847,74,971,314,133,34,384,920,602,298,968,201,959,319,929,704,531,57,174,10,50,589,68,880,736,199,683,587,809,766,762,525,673,721,501,450,855,45,611,442,942,529,291,211,872,946,567,226,80,28,802,332,824,273,123,402,424,230,988,769,469,115,725,839,943,949,683,843,262,858,144,127,907,375,898,49,874,444,872,244,16,516,161,118,11,327,48,663,210,829,493,256,837,51,675,337,640,562,691,384,796,181,775,678,812,886,271,205,139,41,935,209,534,405,356,946,727,737,206,292,638,474,426,390,945,479,537,96,303,791,483,499,881,625,327,143,99,758,13,419,979,104,102,96,613,93,330,418,682,745,543,627,288,84,117,995,696,403,910,161,869,188,487,92,117,663,211,602,178,420,482,89,330,697,965,234,547,914,943,945,225,699,965,386,892,204,64,906,195,808,835,599,260,130,857,751,818,553,809,126,495,428,873,256,136,820,822,808,993,548,995,480,355,693,529,249,590,295,213,773,880,582,213,715,241,952,47,715,404,162,671,242,811,798,402,666,371,337,614,27,201,748,255,90,712,965,700,487,409,59,353,200,509,307,671,691,926,994,452,609,238,612,515,236,259,120,251,498,572,683,866,359,65,914,297,360,379,64,655,924,112,984,653,77,11,919,774,637,418,880,749,324,120,528,567,698,282,993,868,107,0,367,196,370,375,68,905,151,607,392,568,182,433,369,523,434,327,678,245,60,272,572,66,119,310,285,644,521,733,670,607,177,145,68,67,574,758,554,385,503,235,284,423,447,617,724,465,12,433,920,405,371,716,393,641,133,485,783,529,707,37,24,435,311,618,684,786,772,78,689,545,452,813,798,414,894,115,505,968,965,470,703,22,192,173,456,419,792,343,290,885,351,56,303,297,743,582,212,660,188,283,572,100,374,927,324,116,89,693,399,478,119,860,747,541,677,331,585,899,130,888,459,472,285,5,130,369,965,3,215,879,646,567,477,506,598,804,840,564,426,165,507,781,342,726,710,897,898,45,390,787,261,654,324,57,240,392,358,780,641,86,268,565,602,655,844,780,651,909,991,767,863,222,788,540,242,552,765,486,674,550,366,847,212,426,290,593,602,687,779,823,322,405,918,17,919,691,149,254,862,457,769,220,705,118,726,873,876,538,299,48,82,263,6,624,986,486,146,220,552,658,342,312,296,10,510,645,289,133,833", "639,839,333,698,304,862,575,655,252,458,856,145,121,468,151,982,507,281,44,333,438,196,447,997,148,343,624,988,778,43,394,249,261,673,630,846,258,754,222,902,900,765,887,288,145,307,884,410,10,515,784,852,875,249,120,460,847,688,233,765,364,329,87,112,942,708,246,677,471,244,946,532,35,225,514,309,508,728,491,511,858,809,906,532,806,237,691,857,161,683,429,862,823,512,668,103,254,503,489,312,498,214,502,762,86,576,410,324,791,4,788,602,98,108,594,800,960,89,616,752,25,478,620,16,118,761,469,222,82,993,792,612,481,568,110,511,558,258,977,141,330,987,57,639,126,323,805,702,949,45,205,33,711,892,916,232,528,621,86,972,872,764,956,90,252,316,449,982,865,41,915,424,769,239,595,978,605,725,647,240,746,499,123,920,858,300,671,66,979,475,555,95,481,61,694,530,437,430,384,294,616,350,195,114,857,609,990,254,883,62,966,751,327,115,843,40,870,405,987,989,428,2,41,151,128,992,903,395,591,783,51,116,664,908,304,143,152,185,634,884,551,201,70,831,172,523,455,854,170,39,731,613,150,363,182,996,142,486,784,802,677,928,366,30,506,218,746,629,953,840,704,475,179,482,749,263,345,11,248,933,446,749,435,694,247,655,654,24,634,556,746,823,976,301,129,560,912,354,181,499,816,30,977,288,264,567,588,817,142,316,960,59,603,224,509,846,135,296,299,900,453,553,370,445,666,881,109,276,128,129,205,165,717,267,256,554,886,446,684,831,50,945,216,491,505,500,273,72,817,443,435,171,240,300,402,21,547,249,254,9,280,210,519,629,827,615,886,541,717,335,423,566,835,258,648,378,118,409,997,18,710,796,370,29,915,155,728,140,14,757,775,622,471,103,718,645,998,314,47,136,668,519,207,245,719,461,288,327,43,489,308,718,483,807,718,923,863,558,870,207,18,720,561,522,861,564,921,116,432,525,413,331,562,778,886,518,146,318,735,233,512,772,201,570,859,786,546,637,939,382,655,878,535,659,193,832,791,646,77,410,245,202,207,453,651,684,484,676,59,319,587,239,783,201,900,722,581,929,949,769,33,810,392,148,229,135,265,795,52,290,544,298,86,374,110,914,424,63,649,740,974,363,663,676,22,706,451,224,722,405,972,256,183,974,101,149,747,11,284,174,333,699,709,577,987,272,605,921,132,263,141,592,989,477,87,635,556,871,784,690,508,766,273,453,307,728,851,509,692,500,142,900,920,451,169,566,135,511,326,227,461,219,469,103,865,481,183,577,227,815,155,323,63,368,546,910,168,934,26,665,48,9,304,784,479,517,928,512,468,938,527,400,406,747,637,673,219,603,866,233,985,784,837,296,33,388,816,348,789,21,237,594,746,382,567,776,464,323,916,280,877,571,802,119,892,200,367,180,780,702,854,446,94,888,668,589,354,129,606,624,150,6,586,317,963,871,680,121,836,276,867,232,51,388,963,629,266,527,259,500,726,444,499,47,567,90,966,812,78,525,753,903,122,472,58,8,285,458,204,282,11,293,743,22,760,809,328,795,63,35,36,158,441,574,857,688,793,613,976,967,690,481,732,684,715,476,975,826,410,490,660,20,431,855,669,784,474,437,447,135,159,590,231,119,404,255,570,377,470,713,209,140,304,721,464,257,772,663,551,416,768,419,106,739,770,276,216,647,218,430,130,120,546,178,550,458,380,182,742,123,10,106,613,412,203,234,283,745,568,9,367,0,385,342,488,690,752,784,609,972,418,99,494,367,674,863,847,176,120,23,734,859,617,605,624,868,761,389,975,174,396,507,174,757,10,646,905,635,435,948,526,780,677,890,624,817,926,224,911,166,193,344,431,21,751,56,609,63,743,645,849,627,521,319,31,401,386,428,17,909,775,414,651,968,440,421,987,79,319,397,921,57,956,187,125,447,527,866,714,902,809,918,9,413,681,942,375,963,436,597,682,160,397,934,11,886,938,866,53,27,612,213,259,982,997,480,390,974,918,656,953,915,500,966,851,371,365,585,363,734,410,809,6,806,893,133,522,389,252,106,800,142,92,748,702,62,849,14,150,8,52,919,375,205,398,166,411,686,567,567,588,653,724,488,2,744,588,69,117,85,992,191,62,260,623,62,837,529,385,648,142,160,203,944,507,728,168,197,128,525,627,301,884,884,692,73,402,736,699,979,705,185,81,38,985,307,174,378,736,32,988,415,957,586,347,415,141,868,447,352,515,855,509,253,202,92,534,175,784,280", "284,225,452,741,305,988,415,422,127,473,567,735,332,144,357,547,818,808,439,791,954,381,866,213,368,749,613,138,487,675,936,992,709,342,657,589,614,990,680,349,180,765,661,20,781,959,950,689,318,797,360,75,513,761,701,511,483,17,44,736,718,420,602,22,441,198,217,337,105,250,623,124,995,909,772,840,304,460,829,120,445,490,757,972,912,777,473,249,356,723,831,878,777,950,184,472,569,104,520,264,928,831,795,376,686,917,868,986,457,500,203,741,509,569,52,630,730,728,913,440,489,973,183,754,913,543,491,902,458,531,478,203,620,874,294,219,658,332,121,93,319,363,909,445,307,33,241,580,95,422,351,643,388,448,337,849,698,123,733,726,958,165,869,940,420,184,298,389,641,599,81,102,329,301,313,359,453,816,739,165,908,485,940,972,144,629,917,776,661,59,72,928,214,944,459,163,782,334,304,534,753,837,378,655,5,970,179,953,166,903,747,574,677,30,68,977,237,281,95,895,428,193,517,832,134,32,779,2,830,459,789,737,289,806,432,430,764,556,17,291,457,87,81,273,3,623,643,268,115,827,820,623,926,6,72,830,707,604,343,8,775,48,84,879,845,358,602,770,747,332,388,611,208,173,886,578,835,154,833,19,565,481,508,898,612,485,112,465,508,894,939,609,534,171,308,18,45,444,819,518,736,107,863,377,970,756,628,179,142,316,934,42,78,448,836,73,169,980,561,467,740,210,774,85,387,379,455,492,100,816,538,303,109,602,821,142,325,4,857,656,750,44,844,220,553,884,623,474,720,290,230,436,480,519,695,615,665,695,972,299,556,42,485,705,510,238,261,386,133,457,457,767,246,776,774,359,829,718,464,539,685,989,405,868,396,893,402,899,89,305,574,614,64,717,261,514,535,449,280,869,763,709,589,64,784,390,597,242,868,766,240,922,339,83,520,384,862,836,734,994,572,688,110,220,612,651,32,663,15,512,665,40,993,354,841,718,351,106,974,155,687,801,580,483,546,471,444,616,28,884,238,349,187,734,676,8,296,410,825,312,444,359,99,59,632,304,235,228,492,7,436,747,426,790,596,297,824,268,211,617,840,619,195,7,387,351,421,397,575,311,548,280,535,995,950,347,965,583,981,442,410,311,78,470,562,574,16,815,389,771,198,690,987,387,525,920,360,134,400,386,672,378,505,581,848,35,717,183,537,195,503,542,528,177,553,775,369,970,484,392,92,120,817,288,568,896,303,165,95,239,495,559,461,452,437,298,813,968,888,476,731,42,77,143,52,351,667,867,197,875,489,472,795,298,789,60,170,202,197,701,450,834,782,812,317,250,681,813,992,553,563,601,638,1000,465,83,592,501,687,673,970,909,69,554,415,757,586,169,119,67,96,70,152,770,990,216,368,846,574,747,986,866,62,676,939,273,509,521,463,94,453,274,864,304,350,952,632,649,930,922,394,685,719,175,625,818,236,450,889,351,338,983,725,921,608,520,530,944,272,944,2,776,275,714,156,460,52,791,738,87,407,101,878,440,833,664,520,419,281,525,449,81,951,978,974,593,797,7,38,493,964,169,968,548,103,714,696,306,329,103,563,406,563,117,593,490,591,712,857,868,396,804,602,157,86,368,799,101,565,773,956,860,203,267,348,764,869,316,675,42,500,480,211,772,905,234,230,371,503,632,873,962,23,808,240,947,205,451,301,540,617,910,452,619,881,526,121,982,40,166,929,653,84,756,869,666,859,979,504,953,196,385,0,636,107,735,823,947,627,677,332,86,767,542,746,711,831,586,901,31,912,831,164,381,830,683,957,388,312,728,522,934,829,29,335,975,359,609,484,864,107,443,327,4,334,944,395,884,263,394,998,479,380,953,946,928,42,628,157,697,364,376,145,419,785,69,627,420,21,679,575,421,799,523,828,792,307,390,634,944,850,689,658,957,421,765,3,915,122,246,28,279,413,94,997,51,402,898,96,355,290,228,418,173,554,532,935,400,398,316,14,996,289,656,617,143,730,665,268,684,25,524,593,498,698,804,72,801,856,682,485,849,218,88,645,118,420,481,758,17,890,855,793,313,420,789,589,324,815,927,865,853,138,296,164,851,558,603,661,176,824,67,492,578,127,694,32,109,496,724,430,513,503,510,317,297,512,918,993,470,797,627,18,30,929,253,757,770,270,227,679,242,496,293,828,771,61,193,332,893,894,304,722,539,221,953,607,796,133,916,998,67,416,178,41,346,408,935,120,986,615,304,511,674,229,198,656,940,13,779", "3,756,897,676,809,779,907,606,872,702,104,959,343,404,927,253,745,676,587,715,309,711,34,225,576,926,117,203,623,83,381,491,687,211,953,399,269,567,107,185,670,217,737,261,124,796,51,643,772,897,739,743,915,766,972,356,395,297,49,613,286,590,66,847,233,282,629,156,955,302,334,185,649,75,854,868,588,902,228,793,624,218,88,432,372,859,443,945,827,578,196,503,771,793,904,412,937,106,61,21,177,482,508,436,233,233,977,362,997,689,817,959,300,700,322,303,362,31,489,379,4,331,494,171,598,474,2,574,253,925,832,825,876,893,402,453,782,603,92,301,84,853,17,511,720,774,930,164,65,388,678,721,281,790,31,408,7,360,550,766,925,830,295,850,217,158,708,784,888,410,952,881,491,479,673,184,151,801,295,509,294,279,658,378,887,356,190,172,699,703,396,706,680,887,727,672,728,155,79,135,693,392,520,63,608,971,640,613,460,71,588,919,590,667,147,597,413,706,51,566,661,554,139,736,520,543,825,477,475,898,830,530,485,438,139,699,864,623,11,346,685,74,969,926,987,704,461,409,126,606,558,88,512,150,501,162,546,277,893,380,206,750,232,779,808,266,991,280,580,956,953,658,213,308,508,207,866,685,837,694,769,718,949,285,583,246,174,101,620,718,232,574,123,965,582,762,463,176,916,941,23,553,773,516,945,978,262,946,614,395,606,41,844,449,396,916,107,337,95,523,452,18,87,716,807,758,375,451,822,232,522,430,657,463,940,615,193,453,556,549,506,942,847,764,426,401,987,689,145,921,972,175,544,664,978,67,227,712,363,48,476,969,135,112,167,964,197,154,477,430,734,662,957,128,527,744,889,522,575,690,203,869,335,188,478,703,926,878,229,698,41,120,88,767,751,973,658,333,620,327,918,487,971,566,936,660,152,158,996,904,691,708,413,349,947,665,419,535,184,760,801,575,697,395,757,638,689,6,389,255,831,924,38,71,855,994,607,296,221,510,25,125,586,822,308,383,293,26,225,928,7,321,613,390,289,990,656,635,854,67,417,944,184,649,911,858,407,521,336,463,41,644,822,991,954,610,886,470,332,153,367,127,271,946,781,886,604,793,829,560,421,556,466,584,520,171,58,745,187,419,354,106,356,865,233,850,289,774,951,669,192,935,9,226,686,448,159,795,852,662,976,140,42,535,147,6,762,603,737,374,481,209,50,274,370,826,254,245,1,411,611,26,485,906,467,565,425,799,548,866,235,505,765,627,673,284,481,928,769,123,305,234,18,59,964,269,176,866,170,2,69,359,847,754,948,946,249,203,301,196,484,35,215,976,198,467,127,64,470,244,489,660,513,175,419,408,905,677,219,553,646,82,913,369,787,667,81,949,27,508,399,256,144,161,890,647,225,393,14,499,812,967,703,67,668,481,980,17,672,690,567,687,438,731,93,938,235,811,768,427,280,82,209,588,364,822,199,302,750,342,666,898,116,392,526,941,128,765,966,367,175,843,695,399,97,359,130,263,950,579,424,442,332,727,460,295,387,755,40,776,593,899,51,761,859,482,172,48,766,466,771,996,34,781,540,301,631,200,298,275,121,290,337,269,543,575,101,747,551,191,417,529,179,651,847,155,72,126,653,839,602,223,687,621,157,528,696,817,617,812,555,744,151,529,106,388,920,712,216,633,562,324,853,476,509,6,882,282,266,418,515,714,394,521,344,369,364,314,883,44,382,924,789,143,353,471,603,132,326,737,370,342,636,0,675,707,408,295,385,701,16,945,480,891,207,766,525,473,992,418,466,920,298,680,902,58,474,912,126,153,478,561,521,4,629,422,634,737,570,737,898,124,249,579,100,166,730,590,385,672,552,865,818,274,308,457,652,423,926,211,846,889,535,834,982,426,847,635,381,992,973,853,834,561,317,104,810,898,159,42,718,809,566,687,270,503,553,955,629,458,447,786,447,575,195,236,168,464,281,129,749,629,251,947,604,225,391,905,92,393,178,623,768,385,779,456,850,858,6,733,603,928,934,369,547,865,202,589,527,660,302,401,576,624,54,74,524,764,170,561,609,946,279,192,91,846,269,517,286,383,351,975,714,759,479,124,309,747,97,889,341,884,211,447,65,763,114,785,40,837,11,390,707,35,35,884,593,110,139,61,78,185,443,602,285,831,177,948,650,133,567,88,392,204,162,416,429,556,927,60,543,371,188,352,890,303,547,378,656,217,554,169,734,298,708,973,632,742,29,36,65,907,960,429,313,6,853,349,738,900", "523,840,618,831,359,683,24,133,913,850,40,754,245,77,847,425,614,741,789,433,294,152,459,70,256,31,479,267,448,191,581,967,766,989,417,430,133,696,192,615,665,798,740,526,287,215,598,665,789,376,599,428,277,435,132,888,621,643,68,561,946,87,36,574,548,296,332,69,653,345,294,773,845,47,166,261,627,66,253,948,710,613,512,492,1,244,846,928,511,81,325,668,657,691,580,482,683,872,31,876,67,35,90,494,903,468,246,730,54,653,758,593,676,573,106,848,869,985,690,636,794,611,873,865,704,922,658,83,240,570,981,360,877,23,750,96,734,543,383,454,510,189,462,906,613,356,510,348,652,387,13,35,341,559,415,122,591,977,801,410,446,150,907,399,55,530,774,930,790,200,586,211,276,528,34,486,707,979,902,488,538,42,742,193,954,843,642,675,787,93,163,276,386,746,266,890,450,742,823,443,728,244,820,353,697,237,360,376,846,346,495,330,989,66,601,919,916,610,825,418,937,577,606,273,394,100,537,8,499,501,977,255,965,142,785,227,409,945,582,250,491,218,705,803,637,701,528,726,730,282,793,883,564,762,304,504,757,98,173,896,980,771,560,148,668,799,602,341,475,458,701,98,326,820,812,904,72,176,309,284,843,148,577,884,122,518,277,911,204,765,735,986,153,176,627,185,798,780,915,466,783,306,519,938,288,326,416,549,779,819,539,477,337,26,486,543,647,878,88,129,125,696,266,565,924,392,932,944,874,343,438,288,979,447,357,769,905,72,632,320,905,653,180,668,228,339,59,27,659,752,518,360,980,73,359,729,170,451,311,33,3,823,256,947,278,602,509,56,206,175,732,568,14,336,883,364,600,532,374,299,449,624,807,785,831,273,391,371,856,94,727,948,58,312,513,7,168,914,80,277,160,7,434,444,906,238,612,664,651,509,476,141,745,10,266,842,932,892,800,742,234,296,871,923,659,964,408,830,233,591,661,978,453,153,462,122,942,680,653,363,317,412,869,618,688,278,859,232,803,896,740,935,787,713,886,990,470,493,973,536,881,407,53,326,964,750,88,389,954,277,254,287,519,685,384,300,35,777,263,615,738,540,242,789,29,981,196,884,340,91,387,711,81,72,618,932,826,537,931,344,405,69,964,199,554,234,647,829,338,264,489,682,95,601,692,253,761,827,241,715,470,848,791,620,976,653,555,476,534,924,884,312,960,299,83,737,776,449,441,383,642,189,577,918,619,457,223,994,685,260,873,649,536,692,741,239,808,368,247,452,927,479,5,548,942,919,754,721,600,261,356,994,281,23,229,835,234,372,781,170,932,409,868,218,765,584,761,35,619,912,977,66,637,728,934,398,749,660,527,914,653,454,893,729,266,40,957,505,257,33,125,302,975,676,239,529,467,293,793,823,574,261,428,115,638,781,872,161,667,546,936,70,214,373,941,564,927,860,94,282,296,773,741,206,96,511,20,578,488,85,924,684,902,386,514,4,82,172,750,265,255,143,670,303,935,656,329,446,38,695,441,834,147,229,518,712,875,327,855,201,101,700,281,49,521,625,292,812,480,91,793,142,527,333,532,315,979,742,17,578,715,170,133,632,585,981,398,565,72,640,374,96,842,308,814,422,101,846,595,690,844,385,966,515,142,776,129,83,519,289,794,502,632,217,55,67,863,819,137,803,270,596,513,37,174,243,765,399,163,655,136,836,130,142,355,35,269,847,486,840,845,970,928,316,188,165,69,149,743,790,375,488,107,675,0,784,560,336,845,376,656,301,870,540,63,541,380,540,267,975,388,263,374,346,979,183,122,768,668,286,176,536,764,60,894,766,97,278,298,391,296,349,946,134,359,837,805,97,209,206,138,603,245,919,165,482,467,735,781,504,590,771,454,488,777,490,522,894,911,73,627,984,820,906,399,884,993,865,269,811,585,441,955,565,165,954,589,860,588,745,999,964,428,763,822,376,725,760,840,622,995,59,478,536,368,656,259,447,203,948,726,690,45,251,21,609,470,7,619,5,886,307,952,283,720,988,67,426,616,771,776,90,798,447,803,802,240,375,142,384,60,882,1,897,205,931,259,675,671,570,602,959,829,245,331,526,782,621,888,399,363,50,665,652,167,499,480,485,127,706,823,761,584,264,315,695,927,517,177,626,273,503,316,382,222,809,250,461,355,549,797,196,64,811,698,4,484,790,949,695,129,803,545,574,86,442,168,469,954,311,139,205,553,363,369,309,674,816,786,505,879,593,506,380,557,787,708,833,139,428", "275,748,760,92,276,555,35,710,713,807,914,481,609,729,290,538,298,169,210,860,957,580,159,877,992,484,587,766,160,949,179,223,3,540,788,76,706,267,837,362,465,331,391,801,505,4,617,817,354,106,367,629,192,492,438,186,450,599,4,100,223,132,96,645,536,280,666,986,686,726,476,721,53,748,272,327,584,485,362,14,253,371,351,1,330,351,875,543,980,823,159,553,565,243,51,997,840,507,180,618,875,605,385,131,793,911,755,1000,137,128,259,447,794,544,922,117,768,322,870,597,336,29,585,207,890,172,737,332,935,679,799,21,686,376,1000,544,472,597,236,198,499,37,936,982,493,207,647,118,901,413,734,158,827,956,164,397,530,878,837,819,856,38,787,535,472,732,327,719,26,252,374,427,723,470,45,787,479,320,957,807,613,498,635,259,585,335,420,871,413,381,990,834,628,249,800,583,424,935,728,64,467,182,717,96,930,108,99,687,753,101,225,748,879,832,297,984,20,209,747,718,147,731,799,509,86,309,11,320,130,418,353,334,378,665,301,169,170,473,637,435,720,765,493,845,92,144,401,225,434,17,293,33,313,750,547,576,476,72,264,334,250,985,187,68,69,855,528,182,27,101,681,750,907,119,331,105,358,390,719,26,39,612,728,937,435,910,611,584,360,206,608,961,390,464,909,634,487,534,938,238,430,295,72,263,586,87,729,575,201,594,199,170,414,62,870,416,584,61,393,141,592,442,933,702,677,974,396,532,808,360,864,767,839,206,336,27,867,379,985,577,549,664,73,293,114,495,602,317,324,682,117,729,644,168,461,462,610,18,964,291,340,613,540,302,635,187,649,564,555,417,261,238,494,920,945,814,746,625,290,650,856,359,106,980,263,521,88,638,342,819,302,573,617,707,370,155,743,760,648,423,946,512,573,209,504,69,449,754,506,100,733,817,421,657,91,948,773,526,97,274,583,306,682,532,529,651,52,368,587,21,684,347,83,610,95,757,682,887,78,734,24,254,24,709,74,306,93,587,898,750,259,720,765,505,779,920,584,616,694,797,305,692,705,45,40,858,228,968,650,415,718,220,933,540,540,813,20,747,361,321,561,585,113,593,426,151,256,210,30,592,669,820,94,203,130,385,332,45,85,126,662,583,443,746,730,803,116,355,57,183,970,91,253,667,21,337,649,338,150,380,211,33,831,683,512,918,457,110,491,987,528,233,67,361,997,222,511,943,550,222,31,111,604,415,222,599,92,794,68,373,409,598,347,463,743,60,180,755,124,229,804,704,402,531,812,109,511,268,613,88,463,549,718,590,716,455,296,574,526,892,849,887,298,416,91,950,998,62,514,224,138,202,210,268,599,470,423,680,951,877,282,879,439,854,509,918,997,716,263,565,646,568,883,935,111,179,280,120,652,481,668,709,553,894,118,446,710,185,686,129,798,7,793,256,662,404,936,756,441,316,462,227,558,918,455,749,193,716,349,798,60,696,825,871,991,866,411,382,927,367,99,55,554,387,60,406,585,928,777,444,281,587,586,633,63,701,69,172,217,327,476,874,464,484,522,65,552,125,753,823,984,657,191,401,309,258,780,910,204,534,503,333,936,631,317,97,427,360,199,915,965,653,360,837,301,66,505,287,922,409,579,273,288,170,172,885,961,863,873,581,887,808,762,510,950,328,653,242,833,718,167,888,546,867,454,224,755,206,478,996,818,904,678,710,766,831,925,581,530,749,931,869,61,321,138,679,616,74,549,642,68,690,735,707,784,0,401,946,634,265,46,321,584,544,728,218,697,478,363,437,881,777,458,322,982,75,65,679,667,287,352,332,96,990,793,349,823,175,855,210,145,43,773,436,417,251,290,861,46,840,211,876,329,704,302,85,884,83,350,652,376,406,796,150,169,758,422,72,399,633,118,352,429,997,799,469,518,125,417,531,866,408,501,925,54,291,248,409,692,653,802,896,107,524,555,352,365,200,144,75,48,189,410,263,734,250,516,69,546,446,186,187,466,598,751,40,25,260,297,820,522,24,956,835,859,791,488,765,362,166,151,492,382,737,587,487,777,408,750,600,79,41,741,850,401,456,451,421,624,434,717,660,496,951,593,693,112,171,105,688,790,917,785,211,212,877,428,412,338,176,49,347,835,657,441,385,100,888,787,788,93,566,425,886,536,697,877,245,34,981,284,639,817,288,599,876,770,247,975,191,598,493,555,618,319,242,431,542,890,287,23,728,750,627,494,704,645,978,967,630,162,197,780,361,203,934,41,673,74,264", "968,901,943,846,533,710,537,763,304,79,983,890,918,585,718,733,792,701,827,994,279,406,796,882,258,676,876,994,229,946,105,994,777,985,630,785,65,522,729,43,359,895,764,364,981,731,332,701,655,321,849,915,16,415,642,308,123,957,372,817,307,23,581,329,68,158,526,65,778,307,862,2,347,863,948,665,231,810,918,139,456,530,520,131,967,447,726,267,997,318,984,225,891,518,378,958,472,106,784,63,625,889,520,611,146,664,385,793,356,898,498,57,350,939,831,503,858,440,247,838,286,850,927,327,924,702,693,834,966,632,305,785,335,848,926,863,824,300,945,82,262,238,718,565,726,7,951,123,680,586,322,543,674,460,196,944,459,952,800,880,841,485,111,561,158,280,171,661,479,58,196,191,947,503,82,524,432,671,746,734,350,184,817,242,40,466,917,478,220,287,18,207,902,718,973,954,324,154,831,642,590,610,258,451,254,626,851,697,143,693,436,666,16,677,324,767,92,185,884,741,928,49,653,818,26,441,333,312,440,36,348,360,727,944,949,885,475,853,295,893,279,674,687,226,927,752,19,982,354,564,339,689,313,384,129,386,827,898,144,801,201,877,738,911,331,762,533,515,176,872,620,246,842,708,210,420,730,434,120,867,273,414,728,462,452,538,479,470,113,191,766,226,167,309,661,568,625,280,188,653,981,441,323,567,440,486,353,11,607,223,175,122,743,423,427,56,554,718,11,108,389,913,998,615,485,971,895,433,95,896,661,427,570,547,843,988,46,800,518,620,208,778,939,237,315,461,810,922,123,690,317,891,190,236,300,322,662,510,977,627,49,43,315,877,932,804,339,912,953,813,751,583,245,791,65,894,193,812,663,574,508,98,176,944,519,195,912,472,564,611,5,401,135,33,933,919,49,177,528,819,782,236,925,839,418,944,720,223,207,264,525,124,768,121,870,837,838,371,344,694,836,729,733,463,340,931,449,313,814,592,215,599,375,348,392,682,395,307,75,248,748,139,444,436,47,752,245,47,252,650,583,574,362,354,270,174,111,989,821,533,313,337,786,481,90,434,88,953,489,600,986,510,810,35,77,926,113,249,33,698,900,71,920,936,569,524,219,651,815,652,105,412,154,392,928,935,474,935,64,818,356,250,583,341,146,552,66,475,859,378,22,591,131,506,479,69,902,558,500,948,874,71,120,442,983,351,531,190,241,728,208,187,39,28,397,500,141,432,517,227,105,556,866,66,960,537,134,613,628,191,472,195,488,910,755,394,841,724,428,138,738,507,565,432,627,757,921,139,199,221,12,375,965,733,781,135,443,955,613,399,900,39,119,905,652,382,371,243,943,83,634,818,94,857,432,356,29,963,475,865,20,771,511,942,231,152,693,361,687,870,547,253,221,605,756,223,63,55,849,902,657,307,627,664,565,539,33,81,341,400,106,267,387,185,124,303,350,705,326,529,813,920,269,551,851,744,357,768,941,385,478,344,971,721,621,170,468,724,607,250,282,828,915,94,533,551,621,847,399,384,364,773,362,814,63,935,702,124,615,61,834,898,738,419,262,729,855,62,420,262,560,865,591,507,134,922,132,694,452,575,259,69,929,172,308,782,652,542,351,879,424,951,898,229,774,895,520,798,151,161,983,914,49,602,306,924,924,671,370,634,707,354,279,855,826,248,115,178,527,331,189,225,236,293,318,910,265,755,434,11,49,970,938,465,27,114,629,942,494,259,75,375,855,544,352,982,335,117,246,66,905,752,823,408,560,401,0,589,411,925,807,370,702,826,46,561,277,157,348,978,472,517,893,906,917,588,706,953,581,786,623,53,235,414,543,430,239,582,947,969,138,407,513,463,51,671,482,379,189,972,563,638,612,59,588,500,451,841,859,328,478,594,271,618,970,714,409,775,259,424,151,569,154,883,16,312,941,397,348,890,693,395,419,963,554,880,483,396,486,300,565,626,420,774,931,500,719,479,223,200,522,133,493,553,105,966,130,625,125,751,304,754,193,826,912,213,122,117,18,796,754,648,358,468,360,223,335,578,785,734,741,35,427,249,140,238,245,819,454,675,365,718,833,40,906,657,170,136,956,160,564,47,366,304,682,816,397,497,319,971,342,314,147,388,699,839,142,617,69,457,458,532,150,315,913,191,60,294,378,831,846,234,714,371,64,511,989,517,534,723,353,166,471,492,670,217,104,127,460,446,620,107,773,773,318,285,964,45,335,558,680,152,490,589,972,916,505,59,891,325,885,309,108,281,901,34,177,462,880,501", "342,385,24,775,921,68,311,302,195,891,394,916,317,36,777,775,616,869,471,143,714,149,499,172,448,432,554,547,898,365,101,909,711,379,446,223,652,254,121,635,233,585,190,228,928,332,684,928,491,985,380,242,900,384,590,234,242,961,476,81,183,36,204,593,352,428,951,664,352,481,648,79,866,929,95,500,836,369,399,665,669,232,259,664,424,834,561,913,910,490,287,710,366,142,266,665,409,833,725,102,767,701,569,257,863,98,144,656,997,379,779,207,144,226,845,768,728,911,941,134,420,296,882,348,838,661,664,427,316,384,6,433,531,298,39,722,422,324,846,544,666,881,941,657,781,563,144,599,231,491,964,483,46,161,164,71,250,255,94,525,555,16,95,753,142,689,898,331,857,681,773,29,651,417,74,957,760,905,790,582,976,112,97,125,669,934,223,612,858,92,87,74,729,150,591,511,278,128,598,384,111,155,908,957,181,790,322,565,227,512,925,800,403,267,572,981,435,122,929,283,573,205,818,185,698,85,640,368,222,636,384,267,953,73,643,304,39,319,715,975,486,474,155,957,857,247,168,14,859,317,683,199,318,464,465,304,907,660,243,888,15,487,661,584,334,25,886,912,754,685,477,32,546,912,878,489,504,197,637,530,885,72,824,297,393,313,476,712,739,190,393,255,248,438,240,184,70,316,324,262,293,464,656,943,180,742,477,841,792,902,495,468,546,273,200,823,629,200,891,130,450,488,839,628,789,267,280,78,423,765,934,532,8,265,829,995,396,34,710,783,670,604,742,332,914,595,172,191,473,809,624,527,831,521,47,232,117,452,223,705,37,124,877,183,434,380,846,309,187,101,614,411,352,727,231,377,834,955,371,563,794,650,576,531,204,456,106,187,582,278,498,185,802,539,484,466,4,384,409,883,965,525,767,20,588,15,697,14,67,29,276,220,664,189,423,404,844,267,773,362,182,321,611,171,325,5,878,574,210,39,216,728,740,880,894,862,556,333,509,950,853,465,254,77,6,494,826,376,63,454,796,463,287,611,612,350,375,619,798,902,479,239,34,383,752,170,842,924,653,970,383,340,454,92,247,802,41,48,574,663,726,256,258,706,503,127,812,652,149,904,635,870,844,706,9,492,703,572,613,964,143,850,606,815,514,251,886,304,505,378,892,223,639,924,69,733,295,511,200,340,281,312,773,422,128,748,961,683,433,548,926,447,485,867,26,262,520,970,591,172,510,672,564,607,326,190,438,379,365,122,46,925,325,532,470,610,12,538,359,732,923,547,359,993,268,178,793,776,485,828,29,864,217,265,389,873,844,137,309,173,878,76,766,657,436,131,433,846,444,418,646,654,680,908,567,754,556,786,915,616,107,701,207,809,42,383,344,590,756,752,628,883,34,804,583,143,858,90,181,679,530,391,501,257,864,273,545,743,29,719,702,230,111,266,461,459,3,491,959,306,843,257,936,523,490,25,935,621,839,145,291,700,953,488,455,19,530,652,466,395,348,462,97,805,793,3,871,691,5,56,803,184,648,280,975,257,278,882,274,211,338,763,562,299,99,198,430,788,302,599,780,985,401,500,77,536,532,911,489,144,939,275,294,664,915,822,91,878,814,503,133,726,226,989,964,149,830,294,735,780,435,394,349,913,332,379,600,727,893,715,350,48,251,256,708,211,178,226,171,586,693,511,411,144,957,397,198,495,21,343,461,243,177,899,943,625,40,661,530,651,71,178,368,780,669,311,520,84,592,35,151,784,947,295,336,946,589,0,881,276,232,839,80,618,310,64,357,204,468,499,81,536,197,404,246,642,598,364,448,40,168,706,45,770,709,150,269,18,154,798,271,966,92,502,382,222,989,148,373,417,513,507,290,644,993,688,646,521,362,501,930,124,964,369,471,790,226,522,786,476,974,999,88,453,603,556,680,964,499,326,137,334,486,563,857,707,127,765,750,354,156,261,175,541,157,695,507,22,825,289,332,335,144,361,161,347,614,82,468,553,869,372,315,927,29,723,135,25,338,782,239,11,254,734,127,877,387,228,523,202,970,698,774,863,394,31,560,121,151,929,289,223,543,491,704,886,945,49,478,236,664,177,982,546,515,920,340,930,152,463,217,546,763,11,415,350,246,649,341,127,97,246,108,808,194,9,526,931,718,535,364,873,951,297,162,724,994,266,427,887,375,775,50,683,6,6,473,694,280,800,110,929,293,509,398,110,538,722,114,263,827,28,956,59,985,349,790,734,637,418,201,377,493,921,360,141,22,655,540,260", "759,514,834,142,150,186,783,548,235,683,939,648,355,546,714,857,755,274,946,741,886,731,448,942,66,961,219,699,343,756,270,303,382,248,319,305,693,874,584,150,895,877,75,229,29,14,736,981,574,2,786,397,473,303,61,6,107,465,134,34,387,314,28,503,445,210,348,848,58,979,312,544,322,146,542,606,426,513,510,799,804,243,409,666,80,615,483,287,815,183,142,758,891,932,775,749,79,374,333,799,222,535,802,234,903,152,836,334,948,334,326,520,122,604,376,253,937,360,140,269,467,894,446,673,887,569,156,241,675,338,671,38,365,92,640,807,706,899,419,197,860,785,691,533,583,652,595,359,549,784,829,717,223,908,317,543,372,315,613,767,459,894,813,628,265,771,257,496,808,530,7,970,893,479,257,446,986,851,7,700,863,563,405,982,521,874,794,699,575,825,130,923,352,659,843,711,204,685,48,116,313,189,59,222,35,213,371,49,183,488,336,343,852,636,161,221,623,719,887,207,987,426,510,397,765,59,651,938,597,303,867,278,516,383,825,665,470,935,457,240,80,300,170,992,744,988,836,511,960,953,653,322,421,28,6,693,593,974,613,261,87,996,1,175,124,752,46,634,747,209,523,319,823,17,909,974,773,345,283,285,60,839,334,393,214,207,963,430,327,6,89,291,161,563,265,538,264,759,461,66,402,371,53,598,603,421,400,830,857,546,240,339,565,812,889,934,912,328,110,158,231,590,482,415,94,189,854,781,634,101,216,585,706,966,88,453,881,341,430,702,151,738,313,284,517,344,795,166,850,265,235,768,290,262,652,733,684,602,666,21,263,351,712,879,105,612,266,373,792,902,586,407,802,541,401,873,105,566,819,463,709,651,365,490,451,449,2,688,235,321,611,95,359,331,443,667,264,170,117,122,659,217,905,727,655,685,992,180,204,114,367,468,136,291,976,200,714,513,888,696,934,114,723,609,673,369,378,26,873,764,775,637,908,348,107,805,962,340,565,571,718,214,720,543,222,54,835,12,3,725,379,428,508,599,566,705,863,258,806,284,935,783,250,617,428,430,362,935,414,536,641,481,172,725,809,967,494,146,102,291,435,309,727,777,396,832,743,711,955,591,949,486,612,823,466,192,487,949,566,404,110,461,716,164,140,630,421,984,491,921,235,691,166,44,657,143,215,473,92,802,877,13,862,190,172,889,380,819,588,615,262,972,647,464,781,334,423,885,995,915,489,307,590,105,457,562,814,790,187,431,988,608,916,92,425,240,220,405,85,287,664,875,248,573,538,991,523,491,843,404,638,866,676,690,911,988,24,214,761,864,343,705,692,235,928,410,971,760,528,644,174,136,32,551,429,242,806,662,125,867,43,260,61,556,446,343,765,884,251,91,171,715,498,770,992,367,671,59,935,233,590,509,890,323,37,811,369,488,18,129,26,407,840,968,848,988,611,297,690,780,931,141,608,383,141,763,894,68,395,115,419,374,213,391,837,603,176,904,365,732,119,88,693,605,860,953,419,363,955,134,40,455,766,515,657,142,345,662,666,294,440,222,58,961,93,861,494,19,145,23,984,296,102,434,844,150,155,773,754,300,670,944,516,725,684,174,666,539,414,796,939,90,9,356,635,658,988,550,368,793,810,847,882,568,811,250,899,166,915,924,446,544,594,225,878,861,410,983,945,465,419,792,188,647,937,408,833,861,597,2,874,849,280,833,785,152,552,6,371,238,663,832,178,356,155,225,963,435,669,642,607,609,627,385,845,634,411,881,0,411,475,716,354,563,855,856,496,999,949,672,22,714,265,530,880,321,792,44,435,922,436,620,2,291,501,58,710,975,13,463,557,974,897,282,648,4,163,67,774,343,629,232,903,322,619,915,371,677,695,395,667,18,720,422,106,582,194,501,293,321,694,220,789,115,633,590,265,830,527,758,585,169,345,594,162,231,49,132,284,165,528,994,78,756,781,650,997,531,171,771,579,548,88,418,723,808,207,640,769,83,227,704,511,839,326,382,548,482,815,539,863,905,612,848,652,686,474,995,728,459,147,556,754,12,657,705,950,201,453,247,815,3,245,466,637,261,999,98,571,600,212,668,503,950,852,215,575,769,796,268,662,733,794,603,546,484,904,797,897,854,501,440,535,286,479,763,352,980,156,553,548,654,256,551,83,803,330,301,11,148,317,185,261,657,272,765,769,820,542,350,806,164,490,88,604,241,166,350,309,633,206,110,128,105,35,402,473,756,76,359,620,512,282,336,935,488,527,276,446,813", "765,720,426,839,496,640,799,843,708,448,358,678,222,154,154,98,650,120,997,320,892,308,354,934,102,205,607,702,94,599,582,833,671,3,555,893,438,612,84,266,22,818,266,104,949,895,970,421,179,376,229,955,709,80,729,93,139,710,470,35,571,800,582,899,908,393,152,540,448,718,831,918,85,541,165,491,60,24,841,487,859,276,944,929,256,685,466,958,895,954,58,410,959,748,214,618,471,281,676,976,122,283,832,27,633,725,22,770,102,446,581,30,113,424,347,485,910,157,290,770,88,92,269,756,766,179,443,222,643,606,860,163,931,808,977,666,395,700,67,553,122,770,723,337,90,756,121,439,948,796,853,744,156,183,991,62,999,24,325,428,58,99,919,774,582,43,634,953,516,599,984,23,440,745,465,136,44,307,94,981,553,977,424,900,520,191,539,881,998,401,764,203,15,385,74,603,119,271,500,153,113,232,403,291,876,29,906,813,759,385,638,809,547,541,786,920,200,616,461,185,877,396,675,749,585,287,312,50,408,69,890,886,898,824,308,343,217,739,307,499,913,184,390,495,658,245,752,253,808,477,480,496,342,110,534,362,811,279,581,810,592,668,654,711,808,673,299,154,605,77,382,4,233,862,114,168,919,76,232,151,332,940,928,372,743,499,583,488,9,319,500,545,866,234,153,225,191,424,427,491,890,536,990,49,923,907,684,336,682,712,238,374,332,959,633,476,608,707,647,743,246,136,659,312,39,473,183,747,995,81,994,301,17,583,63,459,252,558,179,280,862,213,158,235,938,815,468,653,996,593,783,830,252,263,277,607,381,439,887,481,546,844,115,964,344,301,865,304,429,792,391,129,704,88,733,542,809,427,834,446,661,773,395,650,530,483,528,49,112,99,566,122,461,33,309,367,291,448,642,465,693,214,680,400,784,249,97,312,87,592,708,63,163,883,595,810,597,121,235,712,639,323,884,615,203,298,262,757,244,685,912,818,23,304,229,788,987,182,121,136,863,805,424,962,240,353,382,471,242,534,576,87,286,860,917,89,546,772,186,785,689,48,358,641,892,698,140,327,936,814,26,731,896,960,280,254,330,859,992,915,85,47,514,527,800,687,52,620,960,113,970,833,664,445,808,937,535,123,74,79,895,439,360,320,995,139,818,607,565,478,481,94,39,506,880,746,243,266,783,606,115,830,64,659,714,869,832,445,349,908,233,869,990,279,526,793,551,178,332,714,126,384,645,52,807,882,559,136,494,257,192,164,994,885,850,697,144,840,411,480,145,40,402,567,277,370,765,61,34,707,953,872,416,265,827,933,664,737,924,68,91,806,35,536,505,28,151,193,14,98,284,889,131,588,512,398,680,278,242,331,497,814,610,373,140,632,717,163,325,740,735,529,798,857,284,264,523,104,192,196,184,311,933,370,447,478,158,725,440,527,107,954,693,688,445,807,711,253,162,48,771,398,539,868,730,301,854,277,572,167,375,51,44,846,506,629,433,136,619,668,521,930,225,322,273,496,451,419,748,844,344,329,913,429,720,952,169,598,295,837,617,823,169,242,110,59,445,685,354,108,396,585,727,342,49,341,394,233,324,151,938,286,897,46,217,453,353,66,418,150,811,832,966,88,760,522,214,953,239,398,656,870,483,781,158,949,586,998,908,548,45,553,903,455,400,120,780,583,834,79,908,675,88,683,102,850,437,579,740,268,280,532,722,379,900,516,742,408,418,215,278,227,879,790,570,85,198,844,724,884,392,972,677,701,376,265,925,276,411,0,509,899,855,439,140,882,829,266,310,397,280,183,994,996,338,878,531,256,172,910,847,163,696,19,685,710,507,607,600,314,45,722,737,114,935,753,705,5,637,68,981,245,988,922,134,637,230,804,712,182,708,149,545,384,331,370,402,946,698,44,451,350,763,744,126,401,927,735,120,742,672,570,411,24,220,503,886,569,838,326,117,768,503,465,930,986,750,437,969,256,384,101,17,377,307,188,523,817,678,175,818,671,632,309,115,977,489,778,733,639,437,468,535,11,542,922,468,721,838,757,277,38,30,523,338,521,601,907,312,726,857,364,319,313,513,617,845,97,110,212,354,795,383,81,485,209,841,963,500,569,206,440,660,2,147,765,278,959,284,63,525,356,127,140,264,898,101,563,215,83,414,394,816,46,716,845,500,365,604,725,969,526,407,634,352,592,973,932,13,594,106,137,390,116,824,773,343,125,865,645,760,665,963,518,279,861,316,22,602,669,631,70,934,138,704,76,634,706,530,872", "907,113,894,268,606,200,657,55,176,559,665,152,572,983,628,12,655,37,228,625,9,71,566,288,100,547,348,266,474,479,995,868,344,824,31,44,44,228,444,398,248,663,720,132,835,604,699,44,870,167,80,495,368,401,837,456,639,495,423,469,996,290,538,149,234,996,505,530,591,508,17,436,233,265,446,20,131,782,318,708,637,501,928,527,83,572,179,860,385,565,84,301,615,100,712,425,356,115,611,206,739,683,887,505,298,713,14,394,341,859,616,756,801,100,855,265,351,950,32,307,303,157,195,458,340,167,336,513,949,809,655,656,770,447,208,166,579,682,333,98,750,47,55,625,156,237,610,263,902,178,103,113,170,412,374,292,505,306,215,390,529,800,217,668,531,513,459,354,130,578,198,688,160,721,724,86,925,425,53,673,679,201,667,952,289,939,168,877,605,711,314,292,578,403,572,412,642,797,356,954,810,409,41,463,238,730,681,146,247,663,183,642,738,422,119,938,308,852,42,150,71,213,988,159,303,867,297,12,741,877,416,37,54,987,384,94,131,443,941,216,730,663,548,270,181,91,27,408,951,978,11,928,1,200,221,650,814,297,414,746,898,919,151,969,347,799,877,423,579,861,977,690,724,679,384,378,683,846,151,9,999,64,772,673,585,787,959,536,221,655,690,563,846,183,362,272,343,661,813,110,845,790,511,638,535,35,911,625,720,604,31,233,810,805,489,568,227,129,649,185,858,355,925,624,322,440,153,734,1,441,279,277,951,520,346,492,784,949,23,640,957,944,392,388,960,107,419,987,500,818,55,653,290,881,5,963,447,727,871,65,65,868,358,55,940,423,796,995,755,850,499,659,109,448,968,64,654,429,397,992,378,467,771,246,28,694,874,546,100,262,900,450,355,140,7,252,693,641,92,236,564,68,76,808,786,710,145,807,543,217,4,117,322,427,819,234,100,280,986,132,76,632,685,609,808,329,73,943,350,926,485,729,475,764,287,356,593,580,354,679,7,642,542,867,409,844,518,952,665,820,348,658,879,269,818,277,980,459,504,602,748,369,444,908,350,577,820,430,359,331,2,321,583,188,507,419,74,511,978,172,672,765,647,154,604,104,264,349,432,798,834,504,997,820,704,942,717,739,187,152,236,814,62,349,757,179,973,289,362,670,376,592,309,857,183,632,275,75,173,435,387,351,919,766,233,268,582,475,440,827,522,730,623,15,331,772,353,207,482,314,512,723,42,737,546,973,544,37,455,246,468,539,830,276,765,806,911,652,24,729,599,862,978,555,980,335,11,136,302,988,359,649,64,544,282,34,451,252,33,665,700,233,507,648,780,430,2,22,301,665,703,686,318,434,490,589,169,494,909,487,476,595,231,764,915,513,546,199,53,62,595,726,518,2,874,521,652,383,616,622,152,167,798,277,461,858,545,761,221,921,100,901,677,905,576,695,650,407,899,684,217,446,988,714,208,601,604,561,924,132,796,582,224,674,11,613,583,552,783,670,37,878,952,36,213,855,272,930,578,927,139,571,379,289,863,559,749,943,797,30,140,742,29,85,4,855,751,673,766,731,60,836,419,154,307,322,408,507,811,246,29,256,360,265,478,198,916,293,476,449,198,895,237,191,97,560,339,469,639,460,436,48,920,526,35,675,735,218,805,135,895,358,998,719,438,371,31,718,683,699,580,307,829,957,653,503,266,624,885,93,607,830,700,783,627,518,37,114,589,313,555,182,903,523,366,758,31,37,260,164,568,418,332,16,656,46,807,232,475,509,0,170,397,926,292,766,59,81,706,440,38,598,460,705,773,859,637,211,451,975,643,562,609,509,356,837,344,60,154,727,891,229,582,769,889,350,492,204,377,42,752,95,639,8,699,952,165,466,395,547,975,646,20,4,78,16,829,588,887,231,809,137,82,660,282,817,745,254,930,378,455,546,220,239,961,860,142,920,7,443,675,428,940,809,976,858,202,637,380,970,856,826,136,162,546,449,4,113,929,710,822,358,776,488,861,392,682,12,851,89,955,634,847,183,311,136,987,410,469,233,254,729,759,708,113,890,87,758,974,706,682,989,553,657,398,918,776,590,372,619,874,610,746,659,110,799,607,635,194,734,627,839,285,360,21,341,880,998,913,460,663,594,141,441,227,605,601,761,563,622,187,439,601,420,500,764,118,907,514,346,340,488,259,482,928,604,115,210,691,160,743,986,479,806,797,178,977,670,852,411,787,78,187,670,204,92,305,382,454,949,337,461,919,8,107,684,729,428,991,796", "624,972,126,538,147,301,11,568,495,195,474,116,437,58,885,11,430,958,312,567,911,206,103,446,864,314,761,424,734,931,180,381,845,731,517,840,232,775,41,405,237,727,258,680,5,178,867,256,70,212,204,533,538,842,664,444,658,959,280,819,448,296,120,130,244,127,166,413,923,601,408,786,165,442,715,948,561,139,851,908,409,91,597,136,28,661,894,824,345,319,155,785,804,161,599,669,449,697,399,189,505,668,516,137,901,765,433,767,275,289,17,210,89,928,455,205,696,960,720,162,117,718,683,769,524,363,143,559,48,519,991,378,974,83,631,380,567,643,718,4,74,645,86,692,860,487,609,987,143,508,851,86,685,158,908,491,744,618,533,230,309,215,715,761,556,268,891,302,870,255,237,200,95,432,814,639,113,966,181,783,109,905,829,798,447,715,606,564,559,355,362,444,704,501,737,876,315,155,683,808,574,186,460,517,753,43,128,463,706,392,762,181,568,106,659,70,556,708,468,518,323,262,914,804,687,51,333,987,501,273,681,855,535,650,892,666,114,885,218,137,86,26,387,638,525,245,892,138,206,76,709,583,224,940,235,584,750,65,134,580,668,716,244,263,201,802,906,94,848,91,568,477,788,496,500,584,241,694,234,746,266,806,987,468,82,265,797,995,8,803,551,823,519,643,558,32,962,934,970,670,675,514,307,913,876,155,128,501,262,522,755,39,310,962,106,167,63,608,334,719,54,979,118,498,60,213,419,521,841,664,161,828,642,94,779,3,246,958,694,137,547,52,549,614,104,895,262,651,294,656,898,152,467,58,219,628,665,137,447,389,296,899,392,247,635,970,428,236,296,807,147,690,581,289,674,31,426,280,683,70,317,762,824,758,865,737,981,972,787,380,794,314,750,152,339,473,906,384,931,192,904,270,245,927,594,404,363,950,15,394,686,760,687,137,656,503,836,336,206,817,348,208,397,425,232,228,269,115,5,338,857,160,377,636,50,424,730,757,221,582,640,562,986,931,421,777,509,179,252,617,984,894,709,457,495,642,798,473,253,231,115,807,9,173,793,121,576,163,539,153,122,723,291,926,154,672,891,128,306,278,482,120,611,27,116,804,929,168,243,751,70,546,257,938,289,638,136,744,911,183,327,182,644,607,114,427,596,774,592,330,703,556,464,697,75,580,205,18,184,459,108,797,735,736,641,3,301,92,342,754,126,223,520,897,509,879,278,277,73,694,953,5,931,294,36,792,736,483,560,956,26,933,371,252,609,359,327,154,632,550,704,380,894,693,127,144,580,444,478,849,251,896,761,630,673,831,591,782,430,573,916,720,186,635,226,56,309,277,368,278,959,566,229,973,265,311,53,650,112,177,10,857,678,184,441,298,917,955,908,295,429,197,338,734,845,852,692,544,444,326,174,691,125,256,265,240,835,32,692,49,358,236,735,381,928,40,479,379,721,66,958,966,681,973,955,991,874,277,85,523,445,190,632,393,790,902,277,513,226,479,713,221,752,85,799,861,776,953,324,748,221,894,400,278,504,891,383,223,21,771,972,862,552,497,812,365,278,868,215,939,387,205,711,484,774,509,146,747,254,41,534,780,964,874,510,172,602,564,820,54,53,499,276,658,215,238,29,345,349,998,48,760,458,700,535,78,872,632,433,587,843,455,89,138,549,830,500,498,209,818,289,201,425,851,157,704,534,371,388,228,287,265,120,925,590,871,277,748,290,510,424,470,873,4,30,5,91,267,916,355,182,99,86,945,301,321,370,839,716,899,170,0,781,177,418,404,167,543,607,136,121,548,119,395,578,343,632,667,101,259,495,103,194,568,52,95,152,98,54,940,825,891,182,518,713,823,553,280,342,119,105,800,844,657,854,44,108,663,143,855,261,387,978,159,399,331,86,651,802,561,167,60,626,690,349,668,283,482,307,484,536,756,232,334,645,463,567,647,616,355,524,97,713,327,993,522,843,710,144,66,64,670,956,370,373,409,329,820,210,163,23,976,894,585,188,42,427,730,240,324,245,984,660,158,966,204,836,399,638,368,943,907,200,784,198,538,685,394,944,95,211,195,95,451,509,472,779,866,876,570,613,604,753,652,983,145,748,938,833,787,715,50,973,344,182,59,280,458,767,325,281,726,954,394,153,608,155,723,268,145,108,786,203,51,203,110,277,888,172,499,334,815,624,898,203,822,749,203,938,470,378,683,798,520,764,554,117,297,10,696,375,298,207,924,835,515,731,781,539,729,394,44,672,299,427,414,265,898,61,543", "468,196,413,803,111,599,792,560,552,184,512,432,188,329,360,688,514,970,12,574,423,995,986,848,696,171,396,206,916,682,44,336,529,685,717,324,30,364,439,371,226,719,916,833,16,401,428,369,952,317,341,853,205,306,552,187,609,415,610,953,183,271,322,173,906,336,310,955,453,53,962,608,855,503,442,670,520,402,304,672,360,256,116,988,535,250,909,46,216,468,342,236,243,845,2,405,659,952,414,663,650,388,124,592,465,437,788,449,793,814,642,83,111,781,434,62,209,981,920,263,985,617,698,908,542,402,502,871,307,69,774,110,929,662,840,45,856,288,692,278,591,405,210,595,222,91,22,341,763,806,539,604,8,371,103,295,737,343,843,577,141,273,612,270,691,71,584,473,500,611,857,28,884,744,773,818,28,853,503,174,869,597,861,155,292,464,872,241,484,530,142,777,231,737,748,820,67,364,37,16,343,273,6,979,2,25,971,52,140,431,965,724,813,152,252,202,31,191,780,186,12,436,442,919,969,871,459,438,366,734,485,252,662,538,775,109,721,66,233,318,602,764,811,66,816,62,968,608,316,134,596,547,352,987,24,821,943,173,317,946,984,69,319,878,93,547,964,285,657,735,82,33,45,741,697,864,143,19,722,458,265,110,826,587,462,70,540,45,102,321,333,510,208,935,190,739,759,73,371,443,972,216,811,41,739,760,703,905,293,817,222,962,95,713,52,636,741,539,83,386,210,705,896,535,880,168,7,518,410,328,971,761,729,779,92,204,862,82,158,647,744,874,415,560,551,980,879,352,502,583,738,124,281,109,776,270,362,860,735,783,297,351,54,95,590,120,135,715,117,618,16,641,891,702,879,245,968,497,948,164,469,657,457,19,817,453,865,272,750,194,755,515,972,949,683,452,206,432,85,852,547,168,996,471,317,755,967,651,194,254,364,762,674,918,533,811,836,91,660,729,602,860,254,569,948,251,197,338,787,922,760,760,539,969,797,728,1,6,484,310,631,348,985,148,521,185,939,770,886,215,141,707,633,497,113,216,135,70,194,206,940,927,837,940,580,513,880,303,729,245,433,606,488,806,607,873,811,587,814,80,913,610,974,42,513,887,346,288,806,495,614,838,46,636,694,351,175,77,739,955,645,806,865,68,120,617,330,177,9,741,615,906,692,295,779,579,418,498,212,719,186,772,753,448,48,706,541,654,486,193,50,476,639,200,584,758,994,47,240,419,100,235,395,974,962,168,323,245,423,461,603,749,124,398,632,82,538,401,330,202,147,482,95,595,642,6,372,372,971,789,672,310,959,923,803,213,334,886,252,380,218,318,635,157,329,202,110,323,873,991,313,568,758,44,581,271,554,278,992,933,870,717,989,919,953,134,92,794,365,266,985,90,239,730,359,823,860,387,759,340,93,562,533,867,438,434,531,429,339,800,7,481,625,64,849,220,280,757,767,700,184,454,409,194,336,876,605,294,827,696,449,805,84,480,754,867,902,268,403,420,11,788,999,777,64,940,189,306,305,446,651,815,376,435,579,488,49,843,738,409,422,281,318,568,104,416,449,79,715,823,691,405,158,949,819,345,906,537,81,747,325,972,442,777,655,892,536,701,468,976,408,742,676,306,895,462,236,176,823,579,946,47,440,440,442,431,130,23,186,930,41,958,955,251,931,712,724,633,374,920,263,529,990,278,838,125,232,323,83,116,483,703,938,923,366,237,696,158,265,438,297,671,641,980,197,494,388,853,953,317,433,494,767,480,870,584,702,80,354,855,397,781,0,955,551,720,549,171,844,769,199,758,266,485,139,69,909,399,215,228,167,8,529,467,819,469,389,480,257,449,731,789,721,837,966,861,919,169,246,879,434,474,144,106,636,112,118,243,989,142,484,987,112,390,431,29,92,138,386,119,329,361,963,273,121,79,136,525,600,278,447,420,342,882,971,658,540,588,442,272,98,601,524,391,807,61,843,149,841,274,318,78,917,712,61,794,576,419,713,170,509,556,614,339,819,367,66,141,260,159,725,728,632,282,263,349,528,216,976,929,30,442,275,606,455,246,51,376,22,964,843,596,630,767,429,325,525,122,730,519,31,408,514,124,316,573,45,138,700,730,102,460,421,21,846,498,228,619,81,885,926,21,251,265,539,904,649,159,849,9,244,493,468,963,113,271,257,66,927,344,296,936,227,684,178,507,800,444,108,179,106,393,129,984,58,464,530,536,698,717,479,846,781,46,579,579,59,457,875,899,77,788,947,967,937,767,940,832,115,855", "674,509,484,695,541,320,52,640,809,424,946,497,745,522,705,482,388,195,699,55,489,956,925,314,336,109,963,263,155,667,249,230,443,407,894,399,483,101,236,669,101,386,395,457,598,389,175,741,32,28,820,322,473,595,304,10,414,176,255,62,411,316,884,109,948,805,167,705,237,353,683,180,770,355,740,236,315,336,965,564,63,740,297,16,140,282,450,672,942,951,998,601,627,708,554,753,421,147,514,673,86,252,645,814,693,729,100,291,604,404,603,573,623,141,473,261,445,714,367,466,717,975,802,226,755,28,18,351,853,844,695,264,976,752,318,952,40,368,543,601,301,644,794,450,829,470,961,777,207,48,498,490,517,774,222,606,981,535,383,597,895,983,995,682,979,514,831,124,103,56,823,402,921,880,254,898,456,532,614,530,308,306,423,9,137,200,501,538,692,976,104,242,968,548,603,141,482,979,998,817,753,292,48,201,512,136,769,189,183,846,993,927,124,866,82,92,171,470,27,605,277,717,891,62,786,946,624,241,342,13,468,890,457,33,126,507,906,847,361,548,133,566,502,659,816,712,841,378,188,26,420,112,966,134,616,555,43,597,780,207,213,378,498,59,681,943,220,227,510,517,892,891,548,427,425,78,698,966,61,807,270,730,55,186,407,884,358,968,826,468,137,934,374,280,193,59,102,204,854,431,452,302,685,352,100,846,862,372,244,856,156,956,822,155,909,802,328,698,811,861,193,864,218,186,70,290,739,234,178,63,987,207,380,930,408,627,682,255,992,155,787,309,252,184,373,514,34,684,987,21,62,691,622,883,138,551,816,41,838,98,169,925,887,480,81,693,125,894,372,65,719,446,17,655,468,913,206,382,381,762,778,942,468,791,869,351,949,101,17,722,149,439,99,14,735,903,112,523,268,435,80,134,743,521,844,865,663,338,156,141,228,740,993,877,251,782,610,124,47,362,128,871,905,520,801,761,459,296,876,261,905,959,373,532,458,756,738,363,603,298,909,301,126,112,72,699,924,172,417,944,608,160,205,27,984,970,361,800,140,360,303,18,64,26,418,463,185,422,512,965,663,245,253,785,210,198,643,132,477,200,616,764,823,805,789,445,212,647,922,910,324,589,23,724,693,70,234,248,872,201,532,42,767,17,502,894,815,13,227,114,558,135,755,459,373,530,999,168,367,428,406,964,97,794,346,185,397,190,884,800,491,368,561,248,205,519,527,172,229,834,706,942,444,321,415,64,656,327,222,410,982,722,616,759,84,543,54,163,817,572,267,588,467,253,391,996,205,820,33,251,950,525,733,395,980,226,273,747,832,15,370,948,909,740,300,556,852,385,303,962,831,187,501,925,622,83,402,466,604,479,354,970,583,400,504,217,179,232,914,470,206,833,805,666,401,776,213,712,633,747,730,627,948,386,975,952,886,711,851,121,869,595,810,947,603,387,469,947,902,601,162,582,874,74,110,349,900,579,245,213,957,607,178,24,554,576,720,439,973,633,933,685,26,40,998,990,154,936,424,393,46,748,104,349,405,590,530,126,811,463,309,354,173,57,199,377,825,616,382,548,618,331,286,677,209,72,32,863,742,521,674,542,204,195,186,671,193,337,456,774,452,922,594,893,149,144,159,428,558,134,466,834,123,380,327,421,985,426,761,486,912,614,608,544,759,849,243,829,78,239,810,148,839,164,145,287,79,903,203,2,288,425,912,287,446,45,320,896,862,77,677,510,864,775,479,44,352,19,362,521,369,367,542,891,540,544,826,618,563,439,926,177,955,0,277,413,204,583,533,985,797,688,816,942,221,861,462,92,821,48,352,458,590,61,430,973,652,664,119,242,171,621,878,733,614,504,611,230,466,845,783,891,860,900,891,281,666,254,442,350,834,141,413,14,104,740,621,97,295,768,110,559,966,860,985,164,561,285,349,641,175,623,311,633,122,418,147,104,443,47,773,218,246,970,599,642,901,759,887,116,767,960,186,186,484,404,310,535,506,119,991,576,145,373,41,619,101,14,363,959,14,325,823,632,155,816,602,435,273,402,249,380,201,90,722,995,427,444,680,480,142,852,93,332,626,260,629,318,616,984,469,235,197,189,894,445,982,762,694,472,860,304,528,465,345,678,589,702,689,951,108,954,835,216,905,165,604,310,18,538,471,92,377,942,922,525,723,482,503,614,722,517,942,750,340,468,27,429,829,523,696,45,54,59,668,998,27,290,278,868,617,776,863,467,321,840,190,786,9,214,586,649,913,673,964,458,492,563,276,876", "891,601,412,765,85,466,935,778,188,857,936,580,371,833,656,43,797,1000,631,133,773,808,765,409,78,189,682,785,372,366,439,186,211,187,734,742,492,213,206,192,612,367,634,918,706,38,377,427,435,670,624,30,159,817,104,607,150,156,382,865,263,553,760,312,624,723,11,845,254,996,408,165,431,737,159,830,861,74,623,879,165,264,342,891,929,109,781,109,709,565,836,329,626,885,15,832,832,76,859,624,706,796,151,322,534,903,78,163,230,888,23,186,135,758,488,802,894,603,677,617,159,913,78,205,940,191,13,526,171,778,889,288,348,199,621,877,452,881,56,981,638,846,292,573,53,607,538,190,299,908,864,615,880,570,147,265,251,7,125,782,306,481,849,148,841,457,714,56,631,519,844,900,515,809,485,751,486,516,280,894,196,594,312,269,122,770,104,243,501,283,609,105,852,396,567,790,667,641,578,959,47,611,894,30,212,390,14,912,611,443,116,813,9,544,553,207,687,679,427,695,905,3,572,342,109,966,293,308,668,612,931,201,146,599,956,848,691,937,154,605,688,526,193,834,251,787,183,840,404,474,508,173,797,928,624,519,570,879,170,907,818,486,165,963,706,428,851,228,965,671,333,826,163,76,389,599,341,427,998,241,462,813,277,489,53,569,166,436,924,630,683,193,86,487,467,719,881,583,660,29,136,379,248,431,265,23,984,593,424,79,734,125,674,786,913,126,142,414,659,451,654,348,737,383,527,493,807,15,155,622,181,685,395,867,321,63,423,993,244,162,450,375,288,626,225,243,366,82,451,250,326,804,305,112,578,644,914,193,6,673,435,403,510,449,575,310,722,714,149,162,165,442,51,357,325,455,922,752,260,336,547,628,680,795,400,831,618,429,251,176,115,367,16,202,219,538,405,871,560,373,401,611,877,262,157,17,4,419,438,976,289,891,910,292,68,229,158,460,520,835,881,275,707,990,693,508,766,208,918,271,462,744,555,798,273,183,16,578,83,995,171,289,634,427,485,171,184,636,474,957,637,70,925,144,125,549,998,570,996,721,582,344,827,511,322,272,429,550,772,794,753,94,241,757,224,691,532,890,15,232,327,46,744,26,394,383,46,432,467,995,791,400,978,3,128,361,923,943,797,593,272,442,742,947,872,92,730,319,346,284,534,146,505,631,862,198,134,238,932,120,460,922,33,16,88,984,985,686,374,105,19,23,698,756,136,157,989,178,410,682,854,614,306,951,72,407,147,475,714,6,57,114,271,880,7,796,906,356,267,719,158,335,447,496,26,557,405,596,37,904,925,941,166,628,524,757,510,673,36,241,927,143,40,33,747,662,790,960,766,743,282,652,942,784,681,565,57,329,613,662,157,727,342,171,531,111,13,514,357,101,414,86,369,235,574,138,698,222,875,551,390,126,271,289,790,464,480,625,651,521,16,16,287,244,748,451,136,20,718,233,457,802,637,924,742,234,360,420,609,151,857,231,385,378,590,793,73,342,378,472,817,102,817,186,3,967,838,446,445,843,744,472,291,851,784,69,582,496,951,714,241,541,657,425,962,47,420,722,429,777,640,586,289,871,473,692,550,963,529,998,15,237,781,30,901,460,385,818,116,287,88,24,665,950,697,607,402,879,369,636,307,268,25,156,921,41,866,60,531,810,498,306,298,728,222,122,805,77,941,262,239,302,46,517,251,704,305,683,369,606,910,416,978,72,933,3,584,560,356,434,19,871,747,249,729,437,906,945,470,64,523,674,746,207,63,728,46,310,855,140,292,418,551,277,0,283,830,386,640,578,214,177,523,831,929,954,631,598,916,433,653,699,136,960,626,2,90,933,675,714,736,365,904,191,387,146,884,671,469,880,610,296,815,200,221,399,723,19,426,338,606,636,790,667,756,216,100,927,297,286,645,490,442,294,399,691,680,333,773,931,184,295,345,684,725,203,969,753,462,632,670,931,969,607,563,437,587,838,41,308,40,258,889,811,95,482,876,764,893,491,276,570,19,796,772,969,57,678,150,882,143,975,388,128,660,224,66,852,838,552,323,506,425,93,30,716,902,611,291,629,245,49,922,441,882,61,268,935,228,98,534,370,269,278,773,271,236,646,55,637,397,82,981,456,233,245,692,48,289,238,374,809,967,294,595,64,343,182,32,544,306,789,753,129,499,752,554,344,427,360,717,331,734,72,987,212,417,471,750,892,911,362,650,902,213,439,159,100,930,400,364,945,857,781,113,794,118,340,223,94,66,837,854,839,669,515,262,350,781,710", "81,160,769,125,646,344,669,249,428,108,313,301,737,822,72,583,834,130,578,861,399,645,423,169,755,766,184,316,978,644,833,289,249,622,757,891,979,241,506,50,884,913,347,939,735,787,309,397,798,400,806,696,110,127,14,709,222,825,825,888,497,2,933,262,284,842,603,232,454,680,461,278,170,771,718,217,803,172,561,526,494,861,896,342,924,840,374,921,950,855,737,274,178,826,585,275,767,406,327,973,527,651,383,579,948,388,758,100,997,536,743,72,534,932,289,86,662,960,760,291,503,473,961,674,142,864,554,430,397,672,180,167,831,998,748,668,242,621,562,409,803,106,876,909,972,244,625,699,941,425,765,9,237,640,911,260,985,52,204,939,900,809,845,762,22,795,36,356,98,571,857,351,172,604,601,630,38,679,661,9,862,62,852,539,337,953,791,941,737,355,220,814,551,657,312,326,546,289,313,645,178,578,996,981,803,19,560,152,80,954,981,99,28,32,129,773,451,471,510,338,835,692,303,221,759,590,452,487,862,622,543,63,101,89,651,851,667,552,631,452,296,69,243,95,259,334,921,832,155,981,387,966,109,973,525,725,996,958,34,331,695,129,811,226,999,426,460,920,13,972,606,875,462,860,243,748,221,191,94,691,87,707,243,972,990,527,982,494,112,728,704,651,565,269,783,920,472,768,944,851,871,969,605,279,663,891,861,240,82,135,71,813,666,151,272,712,203,190,624,492,792,181,949,116,229,63,242,636,353,374,981,653,655,512,144,911,466,180,225,751,782,938,563,608,876,369,830,851,305,629,761,222,305,442,127,344,230,354,502,948,300,87,873,42,93,397,677,831,919,461,980,325,481,577,496,68,890,501,802,581,34,505,476,663,757,616,634,115,28,358,920,836,271,192,609,433,235,597,498,587,761,161,271,975,415,392,223,322,622,470,148,455,470,700,169,9,446,449,859,900,238,5,819,706,809,216,15,790,327,50,925,211,466,750,770,739,864,414,546,640,214,692,834,1,306,577,799,234,992,428,528,758,562,291,934,486,700,710,615,965,679,7,700,862,265,375,233,270,579,438,9,722,117,990,642,121,388,872,259,71,645,966,466,275,887,360,271,683,405,137,9,716,718,274,136,708,551,994,107,992,672,196,264,776,420,401,188,228,449,244,819,246,581,524,666,286,122,757,155,270,410,25,183,287,758,80,147,909,399,559,258,439,904,2,659,370,346,923,288,19,213,718,67,915,491,977,114,659,308,823,250,635,15,565,493,120,244,705,287,604,384,244,111,197,836,392,112,622,253,478,188,633,757,531,875,443,350,226,49,538,521,734,988,978,651,852,154,681,379,534,311,105,681,58,5,635,644,432,571,877,435,710,58,444,919,973,865,312,295,627,362,610,893,421,585,19,441,214,281,131,700,73,167,415,688,261,708,699,707,762,469,712,551,279,626,625,888,762,631,372,585,639,535,39,396,319,474,466,926,915,631,790,600,275,401,684,652,768,771,620,829,148,135,792,385,170,961,354,673,640,812,564,232,614,269,407,431,571,553,95,356,459,338,341,985,125,649,705,287,191,23,690,930,964,509,241,518,796,881,169,222,946,321,957,795,250,174,776,679,345,143,63,533,360,971,257,990,577,842,132,497,161,273,564,1000,31,664,884,411,610,248,595,568,608,56,383,266,101,49,193,48,943,22,904,799,252,68,332,344,836,830,902,421,338,242,147,313,794,20,849,926,160,943,347,848,30,981,140,30,274,434,863,711,766,541,218,561,64,856,882,766,404,720,413,283,0,120,612,459,493,914,690,739,635,123,247,176,359,756,9,331,794,959,425,245,486,389,945,88,405,33,544,418,73,874,321,724,791,888,809,674,57,866,616,300,76,782,308,39,871,722,156,903,201,498,813,928,70,577,103,44,860,152,734,445,791,40,253,874,644,745,822,788,380,984,471,801,457,378,764,790,165,76,972,607,970,583,266,292,822,189,87,840,958,267,327,895,927,357,250,546,169,703,236,838,427,378,183,981,775,863,107,524,614,106,190,1000,578,270,25,662,414,15,876,377,375,766,8,500,48,89,313,232,854,785,247,340,694,19,81,585,105,729,125,46,402,944,812,10,416,163,947,939,97,253,466,639,459,331,68,572,28,136,548,331,716,463,961,523,890,731,75,607,878,883,62,248,347,92,753,696,26,666,740,607,945,891,806,873,990,921,385,905,299,327,649,815,653,534,785,736,164,310,866,712,33,467,635,33,34,17,864,68,607,329,547,305,12,94,282", "205,133,301,263,710,123,542,485,171,226,897,105,506,184,26,935,703,68,583,485,648,526,85,754,986,969,108,782,840,543,307,918,699,425,705,256,954,799,560,841,424,2,403,335,234,684,161,978,213,180,44,46,589,329,838,847,359,413,328,833,405,445,211,863,399,656,426,659,348,356,17,824,191,625,206,492,710,204,293,845,458,785,825,632,34,872,293,79,424,429,476,758,184,338,335,844,500,374,420,939,715,712,528,675,396,808,521,66,716,534,807,908,202,763,967,785,657,410,909,378,402,881,531,473,432,80,809,562,141,316,362,813,531,705,366,235,718,690,103,296,191,744,678,434,70,833,71,263,690,643,610,4,48,533,921,85,661,397,434,39,889,442,949,476,373,581,87,14,33,610,319,932,531,594,30,269,226,107,446,465,345,738,903,677,308,434,796,81,938,730,130,974,888,48,47,122,214,879,959,701,906,336,631,959,283,321,823,288,150,725,784,732,618,452,548,225,590,244,117,587,49,592,484,834,138,97,321,11,598,184,757,768,62,506,763,917,690,259,165,846,87,115,664,17,155,638,48,994,43,803,149,231,172,835,828,279,592,152,523,509,500,874,446,629,807,263,18,55,324,282,889,102,169,354,69,267,116,890,262,267,618,957,316,498,718,988,580,30,760,8,291,292,174,74,450,725,57,256,607,386,377,981,877,963,92,617,469,227,460,134,671,919,235,369,574,902,835,113,242,764,339,973,566,285,988,329,566,607,462,459,867,653,175,985,901,302,788,433,591,386,752,975,964,236,775,997,325,959,322,574,797,920,469,4,945,860,4,896,857,37,170,505,29,983,358,592,291,966,897,346,856,55,967,465,749,724,801,84,413,317,788,363,892,220,507,486,934,394,412,58,277,11,184,937,285,482,262,798,137,699,481,437,291,983,246,486,273,841,284,525,40,104,624,596,87,653,588,994,253,804,657,841,150,394,90,816,120,898,601,972,18,383,745,208,640,958,917,810,289,710,520,867,370,125,316,472,957,110,577,158,759,47,68,421,611,963,885,795,365,711,156,966,292,683,547,104,126,285,389,80,792,104,341,974,694,139,437,960,922,535,622,894,240,992,518,532,965,436,282,726,480,128,414,834,655,232,407,550,320,965,380,679,596,815,372,302,275,523,78,597,313,49,826,514,765,700,267,864,872,30,56,995,913,123,398,622,708,399,143,267,697,634,306,783,964,682,446,494,203,89,327,425,287,168,703,706,215,491,470,514,461,536,115,541,763,40,764,80,28,450,173,561,88,490,937,339,511,735,942,109,888,741,809,84,494,784,366,83,913,161,104,594,45,364,697,937,59,145,479,711,706,222,287,251,634,660,130,708,901,61,69,689,1000,621,232,914,45,521,219,749,905,458,361,489,240,503,727,164,252,147,962,588,208,653,610,30,891,917,593,596,16,855,950,645,647,262,319,438,852,739,552,342,393,373,787,586,643,389,365,467,279,464,518,442,631,981,674,928,586,825,945,939,543,975,586,381,593,938,367,868,621,443,413,655,574,597,423,232,278,955,114,239,602,91,706,351,153,500,857,961,400,320,96,72,915,458,668,862,872,973,202,722,43,802,201,827,984,624,192,347,696,681,169,203,498,416,461,623,218,801,426,815,766,1,911,54,768,931,745,1,879,768,904,625,100,773,306,807,519,463,323,475,459,398,558,737,469,691,513,185,184,129,471,569,392,639,442,178,946,769,463,641,451,366,47,455,802,555,151,400,327,847,831,525,380,697,277,357,496,829,59,167,549,204,830,120,0,288,538,585,736,960,543,697,114,240,933,733,142,71,603,511,252,319,169,559,917,500,446,912,345,50,692,771,923,823,304,430,989,907,459,576,318,921,591,271,475,228,697,271,123,36,470,870,332,383,431,581,903,326,834,690,627,46,518,327,27,645,583,176,193,200,561,661,386,480,690,398,984,540,612,568,99,76,890,252,466,465,109,746,50,901,764,994,419,437,710,948,261,652,174,270,275,145,965,516,8,635,898,680,182,760,865,416,448,316,221,847,158,202,113,171,185,909,658,237,348,610,738,376,994,562,68,464,193,932,402,784,45,190,201,52,97,311,330,822,66,843,553,963,196,494,423,632,526,901,737,674,541,317,734,600,987,302,488,520,424,812,463,193,527,373,114,528,381,772,421,192,392,901,162,715,751,455,238,625,385,564,974,610,288,722,199,449,886,916,501,767,883,21,864,533,495,424,519,617,201,912,304,818,2,536,477,264,958,784,215,680,775,654", "226,350,349,627,749,342,311,294,804,359,450,922,32,255,186,601,127,503,210,631,940,828,604,894,251,851,742,335,684,858,495,304,772,269,835,424,837,938,452,27,611,326,504,342,205,902,257,543,87,567,482,301,603,85,41,288,741,428,722,73,784,256,549,88,218,380,694,202,995,182,961,120,116,760,63,66,298,708,643,622,998,546,836,486,14,453,841,526,726,887,962,325,226,683,222,542,210,412,232,926,52,744,887,270,215,692,274,423,601,894,662,543,691,3,144,893,985,18,22,148,975,102,426,275,695,491,237,615,609,729,230,494,328,281,225,225,310,179,436,311,813,147,430,566,214,314,854,905,770,562,872,632,504,811,346,540,558,312,712,24,712,446,707,805,950,538,561,946,535,379,202,678,574,628,88,855,875,277,177,521,137,919,902,609,492,808,202,759,959,994,685,546,767,587,640,516,94,452,284,657,450,841,247,51,503,258,370,180,180,574,933,661,560,637,38,514,742,885,118,757,857,63,882,539,97,565,143,400,64,415,252,827,955,40,749,372,227,824,243,448,782,422,286,691,279,922,720,827,117,661,898,292,955,193,125,204,197,461,18,522,847,661,736,117,484,161,63,594,907,752,963,74,798,98,532,580,750,606,817,924,304,660,439,143,782,97,510,881,765,791,764,343,214,765,281,877,480,832,315,529,133,904,131,450,846,798,70,743,952,929,572,976,364,855,888,304,440,350,487,502,930,959,27,456,354,954,905,112,617,733,283,897,647,273,844,122,877,954,104,866,839,994,734,813,749,541,882,508,792,235,829,483,559,954,102,979,819,777,587,264,231,382,852,624,138,73,2,952,216,179,813,730,622,261,438,884,496,280,775,115,235,986,721,194,818,769,228,613,75,709,395,498,42,280,40,344,909,547,777,95,245,346,651,905,614,598,941,789,369,739,438,395,333,342,533,958,829,262,910,809,404,533,145,977,220,241,292,402,432,769,433,966,742,309,770,646,58,886,37,467,831,38,131,284,407,561,57,284,721,370,864,721,289,916,725,568,873,987,160,532,367,52,777,880,488,796,939,436,812,937,524,416,713,785,567,416,539,533,859,791,743,836,442,106,157,312,662,539,462,693,790,405,507,845,225,713,999,201,589,7,696,124,510,987,352,203,112,133,626,625,146,262,856,997,95,686,282,464,479,271,704,175,409,845,481,480,269,980,247,544,800,320,54,625,882,596,981,663,223,815,950,187,40,101,728,933,139,595,651,106,759,693,712,9,56,184,448,254,999,937,181,333,835,650,424,404,126,50,392,347,14,733,801,211,502,141,870,918,906,375,504,889,924,269,818,77,595,289,440,681,438,505,171,52,399,847,46,484,922,347,146,136,506,368,210,53,959,139,212,121,313,468,256,385,890,418,753,323,807,826,972,357,897,410,772,990,691,382,751,372,274,348,215,779,467,386,751,132,48,71,120,859,679,860,496,862,188,583,998,546,452,526,889,416,620,712,592,755,34,384,54,711,431,667,110,330,379,215,414,555,651,931,230,143,359,126,209,572,698,982,815,449,156,7,464,480,974,148,325,786,19,120,892,696,605,39,10,802,897,455,271,844,738,710,695,989,863,927,617,427,421,172,933,500,2,721,26,763,279,476,381,688,326,110,436,733,445,607,375,283,854,155,463,80,75,585,191,916,850,685,246,750,783,327,862,305,612,840,11,7,981,153,597,724,714,724,943,880,737,53,889,900,296,710,133,360,771,696,279,560,678,176,586,473,540,478,157,204,999,266,81,543,171,583,386,612,288,0,179,567,133,403,41,135,425,460,64,902,641,706,826,339,209,923,239,926,915,797,236,949,428,978,320,977,798,306,568,629,444,772,135,763,55,849,568,879,503,693,879,262,648,418,505,965,750,106,640,647,555,326,932,943,846,153,44,974,840,724,123,816,155,361,630,555,219,783,958,682,541,499,208,908,186,150,396,821,48,316,203,648,238,493,382,456,750,821,473,646,98,154,200,357,619,779,832,607,532,8,366,941,847,952,864,82,149,985,259,613,239,229,220,524,453,221,582,916,413,836,602,683,715,955,689,624,901,286,319,98,254,281,472,804,473,417,1000,873,569,846,354,457,364,909,946,874,119,411,401,970,595,650,744,483,787,265,296,582,62,169,101,885,326,960,768,411,281,556,111,857,53,620,89,439,227,323,972,310,261,50,664,904,260,562,781,152,901,538,648,461,149,38,683,727,261,262,437,357,717,817,736,530,648,932,247,84,918,508,26,865,337,734", "907,444,973,877,708,449,687,495,703,900,881,128,54,433,107,797,949,72,49,292,959,141,561,152,328,952,890,834,257,362,434,288,577,774,858,384,915,284,41,25,610,50,297,709,48,638,84,564,742,548,494,57,1,528,812,769,192,367,91,245,196,918,144,593,442,597,379,827,806,437,693,818,917,156,740,635,127,752,342,372,231,474,467,428,562,151,23,827,683,629,612,795,735,932,206,769,278,896,26,251,531,733,854,656,789,774,334,402,322,757,160,350,316,608,769,732,935,857,117,323,473,916,623,726,733,888,929,713,730,634,239,391,807,854,174,793,405,702,183,431,919,279,91,171,367,905,779,44,416,748,40,281,57,926,762,248,245,273,839,96,961,489,84,910,627,743,262,815,698,391,429,397,939,21,60,92,959,637,276,296,646,192,258,456,256,486,11,628,299,499,594,745,211,118,569,405,916,647,179,29,116,252,66,420,246,237,61,785,312,452,88,662,837,233,593,249,137,561,183,779,131,8,32,591,760,491,21,583,108,71,930,254,460,849,35,204,720,455,823,818,792,766,349,124,477,763,911,149,96,690,420,98,463,11,85,938,493,87,67,950,805,27,271,779,702,474,884,564,109,638,689,343,315,180,382,764,799,734,948,128,771,556,841,429,719,947,627,511,284,425,27,712,360,900,230,115,639,332,560,162,565,468,941,267,96,596,250,296,695,109,758,842,594,200,440,89,431,705,843,685,559,240,891,938,761,314,690,240,406,604,76,129,838,528,676,293,315,723,874,776,454,627,237,419,879,498,250,964,233,83,141,322,136,80,954,753,681,797,72,51,328,23,148,18,817,326,723,818,486,140,208,716,645,926,348,697,833,475,45,336,659,41,722,886,406,166,500,743,794,414,788,554,611,399,465,320,456,919,516,252,871,122,226,252,641,110,569,484,408,153,895,41,612,377,975,955,835,421,311,903,953,54,926,166,5,394,165,243,885,104,465,93,570,466,29,631,317,773,588,152,213,814,224,526,6,54,757,341,203,346,673,818,172,960,510,603,24,415,862,231,133,249,556,389,996,399,581,261,411,90,275,571,479,416,383,42,406,22,475,461,360,64,48,902,713,243,738,284,265,311,168,610,468,837,547,84,133,654,176,427,894,320,764,41,969,363,292,810,882,602,232,216,867,667,569,704,594,182,140,253,401,389,754,44,308,156,454,126,267,265,195,516,742,484,989,275,776,625,991,947,602,721,652,214,304,979,494,588,965,797,851,729,322,812,52,870,739,505,127,120,153,381,19,603,888,382,262,138,633,84,248,197,914,873,259,378,635,279,478,679,872,51,729,969,222,312,625,512,742,990,91,774,979,355,807,205,551,533,396,318,426,808,745,30,371,307,197,150,109,124,690,382,309,52,549,390,632,974,351,108,831,115,659,322,457,578,232,546,256,610,477,519,905,68,146,789,344,931,752,410,532,519,878,179,114,903,981,233,867,725,754,708,743,329,656,76,205,933,861,87,59,750,245,766,888,465,487,271,170,945,392,402,184,479,930,553,3,663,318,33,600,270,117,457,839,855,552,644,664,199,468,736,555,273,746,692,744,399,780,34,827,642,403,73,570,92,154,218,817,968,856,91,192,436,631,283,215,148,68,635,244,510,457,885,570,770,704,216,339,590,13,875,820,194,850,664,959,186,238,66,909,189,709,420,52,888,919,527,904,966,722,904,80,388,326,823,736,442,685,461,621,373,637,49,915,458,730,618,434,868,245,120,901,992,267,363,348,468,949,310,706,607,844,533,640,459,538,179,0,332,254,37,327,853,844,614,945,599,746,813,358,93,592,741,800,518,825,219,420,287,748,750,801,440,556,974,780,99,206,331,650,994,987,234,818,364,113,384,886,989,775,721,428,551,141,866,760,999,402,953,176,942,391,457,832,714,40,397,713,820,414,807,700,710,540,147,192,514,487,389,933,460,538,852,433,932,236,899,97,86,110,755,935,894,766,569,307,829,509,821,300,182,643,85,323,575,749,215,876,717,575,844,690,543,72,738,322,197,464,556,426,329,587,522,270,508,668,138,873,887,616,566,902,422,593,655,12,80,614,979,289,997,554,395,128,506,78,12,388,489,616,64,692,536,678,15,760,52,818,578,411,61,127,201,837,509,407,586,953,421,20,422,97,480,529,766,639,85,482,935,212,779,741,318,445,475,995,991,219,444,905,304,630,987,636,816,570,273,534,829,822,241,410,19,516,328,983,70,588,545,330,1000,684,147,648,438,786,168,286,156", "158,846,720,119,357,638,757,598,346,558,979,194,73,301,581,113,248,185,624,685,129,754,869,860,279,492,634,521,295,487,812,847,656,379,604,225,112,669,27,45,216,682,517,609,794,104,818,144,291,542,304,501,896,479,714,189,628,598,338,31,576,873,61,915,441,164,918,474,647,151,541,257,976,908,837,702,421,497,885,130,343,777,337,628,702,644,870,696,214,718,921,63,3,31,321,668,362,133,58,869,36,829,289,206,209,742,295,839,952,371,248,867,430,482,992,429,200,726,23,889,800,67,778,684,588,963,667,364,617,901,831,7,629,787,455,853,895,384,965,506,498,769,366,225,970,238,838,548,206,512,144,96,485,487,652,521,294,790,606,978,407,112,683,905,518,243,928,351,737,493,319,855,410,548,239,616,729,776,319,892,352,265,835,586,923,642,758,64,930,686,701,961,414,509,660,248,801,285,972,623,123,550,475,713,119,172,789,296,616,915,117,379,279,724,174,573,492,319,801,53,428,529,94,142,43,10,612,546,409,354,871,939,356,612,124,501,900,542,181,460,607,554,944,248,849,959,895,67,508,426,525,70,281,453,36,842,536,231,453,892,92,473,629,655,191,940,421,147,151,275,741,540,55,818,6,574,143,13,933,639,708,847,912,630,847,795,900,360,257,215,961,867,872,897,283,963,839,56,223,841,161,78,385,372,461,390,112,891,161,864,169,74,353,935,872,941,474,603,406,80,232,499,935,155,601,271,999,316,763,693,573,322,175,717,67,782,280,388,342,360,167,727,998,221,374,585,315,921,847,468,158,983,13,661,659,726,384,210,896,915,261,998,993,833,26,671,670,637,281,855,227,806,588,310,377,163,981,207,238,340,392,814,309,563,787,731,4,499,119,60,500,648,887,788,658,73,390,805,403,202,169,418,911,418,824,199,401,178,941,443,269,828,384,460,823,60,677,788,830,149,621,542,501,297,86,299,262,106,535,536,68,181,213,416,924,79,231,19,741,94,194,402,219,509,242,804,470,440,943,148,220,4,631,501,734,855,21,617,769,334,299,619,551,620,756,89,472,990,643,574,260,831,679,854,274,401,831,622,810,38,991,612,965,163,505,211,101,275,74,1000,314,483,312,894,139,633,411,373,894,867,329,838,893,303,949,161,706,25,385,458,306,107,770,632,904,202,63,245,26,848,817,42,901,401,122,734,982,73,395,844,801,96,5,389,228,567,967,509,816,416,815,339,731,978,843,289,591,987,406,194,852,289,609,26,962,11,301,62,913,409,305,728,74,650,724,57,377,445,824,626,610,868,621,439,707,5,638,81,961,835,233,176,991,909,199,110,383,443,483,926,345,164,156,923,705,176,360,549,150,17,101,255,638,362,496,978,406,317,112,75,129,42,812,395,692,933,45,785,125,7,583,175,358,914,635,906,11,743,233,226,35,81,274,37,950,49,781,76,128,430,857,888,457,179,269,380,177,224,610,159,249,287,694,523,716,888,507,105,252,143,270,565,389,33,119,50,885,522,889,909,195,433,212,766,667,978,889,972,42,379,766,652,758,599,265,676,602,725,390,339,656,233,100,567,811,696,68,690,830,595,777,37,805,956,995,107,257,90,461,252,290,550,425,585,607,710,43,784,905,409,607,957,690,27,76,426,254,569,109,830,616,767,132,638,452,783,510,632,864,914,561,651,558,410,242,609,684,391,10,677,777,310,505,653,43,21,637,537,976,999,657,513,396,829,414,692,204,64,143,331,60,23,31,418,975,437,978,499,672,397,440,136,769,985,578,493,585,567,332,0,247,508,576,375,89,458,277,881,865,291,569,987,158,78,247,814,13,710,416,712,450,845,824,896,770,979,261,572,707,739,113,142,256,573,752,661,628,198,846,921,913,547,827,126,318,643,939,921,355,690,840,876,932,309,216,525,834,467,920,101,717,905,108,124,407,242,238,796,141,767,380,551,693,214,275,849,142,254,88,912,512,70,49,73,518,572,238,123,770,567,361,122,227,699,138,502,41,427,875,875,14,312,882,510,117,369,9,658,298,850,769,21,980,126,293,765,769,877,176,424,607,53,166,506,474,470,248,520,316,429,566,160,715,619,146,823,222,658,779,10,589,458,92,257,884,848,825,419,386,507,846,37,883,346,199,112,131,752,670,603,854,858,247,826,734,455,528,509,606,471,728,378,101,515,696,726,56,382,61,281,858,636,700,220,848,945,772,903,230,525,838,343,888,865,691,894,616,796,156,986,927,97,636,592,793,955,232,135,582,114", "473,464,343,195,354,124,47,224,613,474,117,728,780,573,430,41,438,288,408,612,401,902,950,577,646,373,231,898,141,569,253,444,417,364,264,136,349,922,687,301,534,167,939,743,346,562,607,656,555,21,419,331,884,866,70,871,426,636,766,381,211,877,802,857,104,372,623,504,873,500,734,378,479,286,282,723,354,469,650,75,107,338,212,474,751,349,915,762,868,581,402,317,543,563,419,588,56,245,306,759,449,15,866,340,840,761,816,171,996,60,399,951,258,368,788,665,399,911,419,357,354,880,400,451,924,925,920,856,222,807,809,53,848,147,636,126,735,304,831,601,298,935,630,974,742,372,443,560,288,140,325,467,530,283,244,231,890,401,404,571,78,782,701,238,259,377,572,650,807,989,324,618,930,149,135,906,968,722,817,352,843,358,6,715,43,281,976,381,17,269,888,694,392,784,546,716,831,161,703,313,568,291,882,290,538,788,208,232,583,464,5,167,71,283,690,66,409,56,37,663,577,46,799,599,100,677,609,53,886,20,93,875,69,70,83,683,367,781,35,932,633,5,232,4,905,741,823,794,59,357,433,809,609,386,699,806,59,947,311,978,661,151,429,231,380,453,678,818,977,724,646,465,215,755,491,460,641,912,941,953,71,47,235,688,52,373,822,115,916,548,364,715,36,619,513,94,559,871,789,74,484,217,39,416,255,746,400,22,54,291,203,465,135,408,524,240,874,578,554,92,991,355,235,239,71,964,833,303,948,714,736,333,51,41,969,833,433,546,482,850,936,334,596,566,521,957,581,86,635,102,93,841,390,181,369,175,699,757,627,715,30,414,162,606,390,335,942,261,53,918,855,199,682,425,537,473,472,180,815,136,706,608,762,103,460,498,413,276,559,900,217,183,673,225,954,327,322,649,934,952,216,843,8,727,367,767,673,482,963,605,274,752,487,598,162,30,242,341,281,805,372,788,413,76,249,195,612,537,630,312,516,367,579,96,434,815,392,117,809,102,179,535,612,452,849,491,140,250,68,496,855,433,863,494,42,656,262,154,727,177,991,109,306,83,371,137,543,264,637,344,371,975,414,728,399,998,485,228,930,926,101,98,287,259,524,795,980,900,8,543,550,967,461,816,19,238,874,466,360,387,763,602,545,709,220,448,935,857,162,417,251,969,261,30,708,519,882,46,807,795,376,235,542,516,654,152,669,66,754,113,746,220,528,757,619,167,844,344,164,183,260,58,325,835,617,323,834,435,169,641,171,274,217,169,12,13,75,768,914,388,394,877,189,408,74,452,430,683,406,85,712,959,811,29,605,547,398,893,602,7,954,875,9,558,807,915,390,611,685,846,984,369,979,364,739,210,825,492,542,105,791,400,764,478,298,51,208,279,107,661,447,942,984,894,302,673,665,92,732,656,752,491,135,181,143,80,548,155,281,499,951,514,563,362,487,326,83,42,383,943,730,52,535,584,514,427,862,121,122,927,347,179,958,71,179,399,580,289,515,373,323,264,105,616,671,652,15,729,98,176,384,799,850,325,589,898,668,805,972,37,929,376,44,810,982,800,169,51,706,414,456,563,947,956,72,33,323,653,127,794,268,975,604,767,86,288,635,926,36,132,921,528,126,527,384,207,157,557,284,375,735,770,717,914,514,596,2,123,422,413,753,344,506,881,205,564,294,384,913,776,559,255,417,599,240,189,191,39,275,145,786,84,390,257,937,519,379,928,618,170,735,7,756,472,838,81,190,951,299,556,272,734,912,466,388,881,472,81,22,280,38,121,199,797,214,914,736,133,254,247,0,717,897,773,446,27,702,715,972,64,597,954,418,29,717,134,688,492,312,650,573,458,993,411,160,565,493,780,732,145,406,378,690,335,789,819,180,972,871,788,246,434,922,604,581,701,138,318,618,294,68,875,516,533,915,474,203,611,991,514,728,966,425,626,5,93,574,653,767,142,416,208,213,158,485,122,50,651,152,735,767,334,591,95,345,262,73,305,867,847,40,938,183,443,402,779,783,932,708,989,604,165,524,560,600,922,941,727,114,429,857,745,699,241,4,189,646,56,731,918,160,809,219,429,631,5,903,514,159,435,986,688,705,300,682,67,249,269,990,168,498,437,220,466,199,150,236,704,281,690,314,957,572,792,426,689,979,154,920,684,165,909,490,715,554,56,517,938,652,604,774,544,48,423,825,728,86,162,190,194,46,850,779,755,994,158,112,30,456,327,275,502,685,372,486,36,289,817,397,833,211,245,61,75,850,230,886,195,876,444", "622,507,210,596,33,667,551,178,160,496,506,440,712,341,722,416,631,448,297,725,660,775,226,771,658,843,954,442,964,935,868,7,192,937,694,936,97,988,754,361,108,404,569,370,7,570,460,693,154,951,477,33,501,611,856,287,693,64,777,428,526,954,470,778,572,308,485,777,788,550,142,900,569,261,495,394,109,336,221,697,350,650,240,804,19,117,593,832,813,106,377,635,391,697,920,734,372,907,766,493,9,777,302,47,337,971,520,254,601,637,493,785,159,380,583,115,673,405,572,779,376,138,616,3,827,683,873,981,135,42,572,726,233,627,984,566,623,447,391,707,709,973,549,261,451,704,580,458,266,633,949,354,620,225,365,691,420,580,925,64,339,901,90,648,290,148,563,444,904,664,286,268,998,991,857,878,274,325,906,532,76,430,329,396,395,975,397,657,279,320,864,315,551,765,128,767,446,376,356,576,668,963,547,182,136,796,614,387,465,232,232,81,379,744,294,486,527,329,86,790,733,530,468,321,80,12,701,515,151,488,43,819,234,419,319,138,594,790,656,274,557,187,471,555,882,204,157,820,431,478,830,568,561,891,789,963,516,95,669,89,565,33,181,466,898,15,425,107,755,127,915,902,775,852,69,598,274,118,489,209,504,185,636,55,265,509,715,950,563,781,749,79,429,783,143,383,841,257,720,228,334,679,733,323,653,485,504,534,702,645,59,501,827,154,696,366,744,444,61,483,756,637,201,603,692,899,121,503,14,518,629,300,276,375,478,523,800,19,447,576,671,770,552,656,412,420,587,71,473,367,523,13,497,546,893,640,636,549,381,484,718,489,280,292,657,997,861,187,296,393,42,904,643,930,233,534,183,325,992,782,485,453,351,875,320,495,680,11,868,63,719,316,806,130,68,519,580,462,636,307,230,25,895,853,875,630,35,89,740,992,418,866,410,421,428,365,833,535,307,139,338,654,376,238,327,974,391,383,291,654,322,882,966,958,38,397,745,837,477,616,302,150,504,83,636,11,582,772,123,428,824,107,112,876,234,110,468,476,385,323,952,713,978,35,415,120,369,575,518,750,885,51,247,311,525,997,879,953,239,571,684,252,641,309,369,558,70,367,220,680,969,408,546,901,6,27,795,625,321,823,708,849,695,56,390,29,346,53,142,278,725,124,299,857,85,159,296,9,786,950,175,774,767,383,673,248,286,515,316,690,882,716,403,503,354,476,766,59,209,534,720,588,304,545,177,859,63,550,802,139,525,197,447,530,161,271,399,384,294,729,887,922,896,762,575,529,440,567,45,893,228,553,884,673,735,100,471,798,711,340,552,941,782,312,164,884,829,738,244,385,829,510,978,816,336,583,911,377,406,794,478,825,636,519,99,27,115,849,267,157,5,212,283,803,431,322,28,976,552,870,590,691,481,768,339,32,47,317,564,124,696,526,430,504,190,931,180,888,383,642,376,221,881,461,448,242,728,134,875,982,258,995,397,224,207,891,670,190,286,977,212,649,420,50,36,120,403,224,64,474,366,505,901,474,61,415,157,314,475,794,367,171,544,136,478,873,326,87,720,994,914,568,693,466,605,523,421,274,263,429,162,243,941,99,513,862,524,429,681,682,165,161,367,223,551,930,254,838,830,126,917,184,333,316,474,60,426,427,575,871,476,719,539,812,281,153,448,211,440,164,431,922,431,94,467,914,194,134,449,892,604,551,734,959,250,324,646,43,913,587,557,492,83,161,298,139,440,69,611,894,572,859,831,920,263,777,517,536,714,183,598,548,758,688,177,690,960,403,37,508,717,0,152,629,446,153,422,572,518,45,389,766,982,68,72,195,665,910,936,999,837,276,671,573,261,633,891,419,998,298,160,783,797,128,349,946,118,981,488,533,616,697,186,249,167,78,751,915,491,226,809,453,904,817,997,766,517,618,8,930,368,172,922,660,885,878,848,100,421,928,322,923,814,66,392,456,370,62,600,916,481,414,545,194,711,614,64,903,448,557,305,228,101,324,793,457,981,285,65,93,505,914,722,907,123,760,912,755,477,723,819,268,554,312,726,880,114,36,58,755,735,865,316,910,602,733,470,607,301,475,13,615,454,579,610,254,95,923,40,641,207,983,63,86,846,686,783,43,369,815,293,374,994,118,88,654,895,382,830,210,365,802,27,766,968,510,892,219,828,826,62,563,520,669,720,909,896,385,989,399,426,394,829,582,973,195,837,197,951,713,171,89,549,43,871,454,726,186,348,651,845,961,768,462,111,491,766,242,797,930", "67,733,915,480,80,105,106,939,124,244,954,897,560,731,773,209,966,103,274,476,755,853,302,874,811,163,418,371,712,620,546,264,514,820,77,763,447,361,637,216,92,226,244,15,283,942,482,30,773,435,648,205,291,515,982,183,789,726,286,173,853,746,867,647,526,770,111,156,96,552,706,778,232,211,400,593,781,419,711,796,720,691,657,707,143,658,813,326,799,480,807,502,704,269,249,773,214,821,186,796,350,725,322,111,287,753,693,672,376,157,46,686,277,517,890,819,977,590,866,153,389,390,789,310,477,569,44,778,569,139,344,150,647,452,822,489,614,426,281,562,361,991,311,177,469,414,329,280,843,901,493,302,758,855,439,14,306,98,521,606,162,930,903,639,102,727,11,275,531,216,57,385,177,234,943,741,293,485,822,728,331,835,25,581,827,137,157,994,867,925,190,353,921,139,201,116,412,273,778,479,630,806,861,371,215,213,839,789,238,409,999,224,600,457,240,41,690,651,543,311,389,30,30,729,289,498,639,810,715,253,618,662,729,316,789,861,548,967,65,862,909,15,648,88,624,261,614,895,633,289,724,15,522,190,18,645,349,99,767,366,301,48,504,667,587,740,30,773,226,886,118,501,812,272,406,360,405,741,480,941,58,329,271,851,3,892,498,11,198,755,611,228,242,964,324,721,235,167,280,101,305,775,985,777,402,815,595,888,87,603,72,487,427,566,183,319,222,34,860,780,395,462,557,321,461,996,853,600,135,6,380,505,830,953,838,510,908,802,656,45,185,674,275,148,318,736,565,597,496,568,859,742,539,118,268,906,696,928,877,156,834,256,468,516,598,30,563,663,362,947,802,816,290,327,764,887,808,794,981,999,61,509,455,616,44,192,474,933,844,340,705,426,981,585,194,592,88,958,844,975,935,329,974,297,488,676,498,35,907,135,807,211,27,223,631,491,114,315,499,513,337,220,252,533,375,921,27,780,544,113,257,309,180,871,681,361,955,544,649,124,861,169,280,220,301,440,500,974,293,977,68,382,145,137,373,20,776,70,256,412,103,61,688,811,365,728,209,633,629,813,848,798,571,466,750,724,136,577,273,27,154,797,376,869,254,981,969,687,894,484,779,997,721,122,532,771,371,570,474,35,512,827,691,753,697,403,505,132,461,189,652,147,810,570,360,44,189,959,164,457,133,611,791,912,998,874,229,658,581,887,638,666,561,887,238,931,956,530,998,445,81,927,861,845,239,698,894,608,397,808,784,646,460,955,76,158,585,425,352,921,698,279,822,315,24,23,289,629,869,157,922,853,968,276,794,147,307,997,606,392,375,744,201,741,16,300,277,194,429,505,256,49,470,900,483,387,514,391,844,411,383,144,631,90,563,687,810,313,591,431,460,747,448,82,860,493,472,94,442,652,627,434,864,231,624,241,825,90,531,481,230,122,742,726,385,934,160,763,49,573,74,495,981,923,645,404,400,420,483,716,663,284,593,370,17,386,965,70,397,901,903,278,829,413,957,140,861,2,830,435,912,645,56,614,884,100,34,324,999,447,710,507,602,730,855,158,876,328,932,283,43,616,859,487,521,434,499,649,910,544,208,130,916,15,138,590,962,558,258,464,629,680,653,96,832,825,973,305,307,701,353,960,729,946,574,734,298,115,458,986,176,450,748,874,550,796,223,429,23,627,733,688,920,862,994,916,780,4,793,70,497,882,322,457,284,519,246,870,62,635,294,981,457,169,983,526,456,424,372,581,66,617,164,298,374,458,893,197,265,994,460,119,266,816,523,739,543,41,327,576,897,152,0,432,630,891,478,662,712,637,706,294,535,90,698,399,802,281,810,602,938,177,4,708,341,224,452,109,98,268,776,878,64,384,953,190,544,419,278,139,776,339,502,986,46,686,221,989,805,744,4,633,627,666,962,133,308,540,291,333,97,438,346,276,174,365,960,521,166,142,777,150,730,864,487,328,192,886,275,934,257,57,305,605,983,541,207,928,199,487,940,580,625,111,225,359,280,6,563,908,93,583,192,413,574,731,637,70,125,64,846,522,95,399,738,756,860,573,985,803,933,244,78,890,178,984,774,153,559,278,872,905,1,379,919,955,200,543,167,988,44,518,28,583,850,721,188,687,893,195,998,554,197,691,600,760,716,506,449,356,152,856,880,68,899,988,389,190,520,611,335,14,863,5,199,656,906,582,967,989,483,883,104,288,425,873,442,102,39,109,661,554,48,69,68,916,917,792,922,511,935,401,550,524,247,468,311,13,958,343", "981,303,640,138,28,180,87,526,98,437,861,278,532,379,253,25,630,558,302,860,101,976,214,936,20,493,138,437,26,692,429,228,633,770,218,166,500,992,659,335,506,723,813,601,217,864,198,207,428,937,697,871,575,179,822,206,271,269,968,599,657,473,873,987,138,901,654,232,779,387,349,482,500,262,309,564,757,339,698,324,64,194,445,256,394,355,53,130,729,717,543,326,750,726,225,326,602,845,984,248,822,206,557,849,884,403,705,674,752,530,487,303,545,364,351,58,955,333,325,919,617,625,711,449,171,713,535,115,240,715,771,287,496,832,289,323,112,586,467,306,630,538,643,759,137,409,76,979,624,437,457,785,239,269,84,347,614,287,585,87,981,537,664,182,389,50,50,767,180,342,493,883,603,984,45,495,933,592,841,770,848,620,769,70,85,581,183,500,125,286,279,293,384,823,355,359,290,770,249,273,485,221,739,253,951,102,540,781,970,216,249,460,956,166,484,846,891,827,763,589,503,94,172,673,997,727,368,100,363,863,879,139,405,951,874,9,936,325,979,905,847,233,764,115,446,103,315,620,320,191,573,380,627,413,672,624,707,838,620,406,727,314,663,790,534,985,59,287,835,349,10,709,106,782,374,375,714,113,222,658,33,627,19,126,767,199,400,123,732,848,121,993,857,389,245,68,825,241,39,127,976,632,103,280,434,83,226,637,370,742,627,884,26,970,253,18,814,259,518,207,199,824,172,385,264,368,771,973,270,139,712,722,671,455,864,711,45,518,605,171,823,467,510,758,410,200,714,404,93,433,510,898,878,685,907,573,122,53,554,119,862,140,126,159,692,33,814,13,693,507,542,999,466,484,394,572,158,946,162,995,728,968,965,707,466,239,537,146,131,294,265,952,172,334,258,542,167,677,184,261,194,176,298,304,638,899,640,632,179,647,455,125,308,837,788,626,427,67,709,361,729,120,644,604,544,453,887,511,362,191,784,758,477,32,21,779,578,977,865,641,447,670,893,657,293,289,309,945,771,498,535,337,684,268,543,555,7,226,148,918,376,151,467,391,178,200,428,186,647,795,859,460,126,186,851,363,231,645,848,420,736,671,894,87,265,36,912,288,150,171,791,877,870,139,557,47,912,845,701,692,914,214,478,334,430,561,758,820,955,613,285,731,453,344,304,412,129,323,44,54,548,757,291,341,825,809,120,254,896,107,761,974,717,645,175,571,682,732,488,428,362,103,631,619,457,706,917,208,398,240,224,953,389,99,713,109,288,379,126,316,811,403,226,405,411,793,208,863,923,901,459,979,290,671,261,941,476,58,378,211,96,189,964,825,584,32,671,71,536,914,516,340,126,191,697,716,978,220,40,38,460,232,454,81,134,855,686,22,707,390,905,598,602,529,622,2,60,679,616,902,476,417,29,674,799,599,675,622,332,931,716,574,863,137,286,147,499,886,487,400,503,791,260,643,974,499,968,213,970,706,116,962,310,635,287,486,391,948,634,178,358,848,849,131,683,256,387,296,413,232,560,916,543,951,342,820,794,272,157,159,299,778,543,268,362,995,44,657,962,319,701,14,602,551,809,686,809,937,347,305,986,149,309,326,652,537,57,390,828,66,698,497,366,467,621,780,903,273,756,829,600,657,471,416,787,380,148,895,999,896,111,852,690,214,38,901,963,698,200,428,300,584,950,807,124,511,922,381,171,528,411,79,377,397,464,737,225,216,927,251,503,39,648,935,700,54,433,444,638,519,119,605,381,680,346,322,906,404,530,996,705,395,485,942,831,635,697,135,853,375,773,629,432,0,600,755,767,487,43,979,419,914,282,107,412,45,661,644,34,632,655,528,423,117,247,302,546,452,205,509,923,128,374,262,559,655,409,549,442,150,846,670,846,332,527,262,743,710,355,845,401,354,439,217,715,308,949,661,717,270,434,581,395,417,679,77,137,472,819,471,403,59,132,980,551,357,341,570,254,387,258,565,901,112,424,120,954,242,163,440,605,222,572,811,336,285,434,441,350,640,388,952,432,251,603,128,291,579,979,356,448,65,313,209,354,890,384,825,600,568,532,583,181,323,831,601,861,831,436,230,682,329,408,646,944,114,797,762,170,447,929,839,350,16,556,651,914,659,609,10,611,901,162,43,562,13,359,869,200,418,63,844,649,997,945,692,847,224,631,948,762,81,410,222,886,277,415,973,154,474,941,143,977,386,651,983,595,884,176,645,190,604,769,287,810,974,404,275,172,225,927,589,922,892,753,974,956,389,296,769", "858,597,221,858,356,965,70,442,222,596,94,3,510,997,527,804,133,448,884,810,675,314,552,653,294,370,19,163,872,486,965,397,244,330,303,746,371,469,261,58,567,95,655,50,783,352,70,511,201,954,750,220,527,875,970,618,102,364,952,698,287,980,755,130,397,50,361,247,583,710,720,748,128,55,860,705,849,886,263,685,486,343,179,207,100,937,80,472,86,394,806,813,54,527,919,156,611,906,43,577,923,217,73,226,319,200,546,30,997,308,522,553,844,154,558,370,378,480,41,197,363,237,840,968,625,843,509,407,560,788,297,354,425,158,237,717,143,173,492,635,21,603,800,230,619,878,769,296,222,361,574,37,499,958,43,193,857,258,267,667,786,284,752,449,264,81,235,690,630,580,554,41,105,129,129,339,646,87,201,816,503,845,938,799,995,25,722,679,754,317,901,150,971,791,577,431,638,677,68,675,868,341,30,179,753,704,182,766,385,303,752,88,302,345,253,193,399,311,711,358,644,810,662,27,111,273,998,167,330,807,486,522,669,328,108,348,935,332,948,110,384,344,715,224,713,623,643,895,850,882,34,679,38,708,263,275,841,919,187,252,380,848,569,722,910,859,381,649,95,941,655,343,441,635,816,198,514,858,20,250,214,144,406,314,802,47,305,309,783,113,687,138,268,5,428,948,18,641,669,52,906,52,515,625,407,602,988,408,143,493,335,692,895,32,365,414,279,308,356,758,168,447,236,34,911,285,920,393,686,590,534,257,560,470,271,333,460,881,89,12,102,151,44,622,671,102,21,155,425,177,340,189,466,183,582,334,961,441,417,363,304,401,68,896,498,347,644,998,323,247,955,597,836,438,644,678,632,669,775,800,296,404,829,506,184,471,771,978,720,270,195,296,340,603,214,250,921,661,161,515,694,474,804,251,467,397,387,379,706,578,106,790,775,243,922,822,464,53,974,320,800,411,788,966,864,286,808,101,546,637,869,415,78,681,369,666,1000,510,148,99,428,903,218,561,881,146,595,111,255,144,614,742,571,821,191,455,373,409,830,113,679,24,689,562,234,967,299,444,858,20,611,890,359,719,291,320,834,942,851,414,96,444,431,797,810,959,4,952,405,671,972,560,10,774,582,844,702,907,388,870,163,274,849,210,125,65,200,116,170,101,292,806,199,898,424,892,502,476,288,647,539,853,747,525,209,533,164,121,732,280,35,614,756,193,482,961,398,588,736,456,761,584,595,418,526,485,114,68,88,483,36,841,653,227,634,186,407,598,795,634,869,347,544,438,197,301,662,45,546,666,47,139,14,917,270,965,227,346,813,725,312,516,866,152,577,676,377,147,895,652,245,804,938,279,806,29,61,757,87,230,146,302,860,240,14,659,115,449,437,187,626,41,279,786,588,334,675,109,805,591,330,71,333,834,838,717,848,707,791,532,529,893,981,194,504,471,969,571,337,827,609,571,387,627,345,602,724,117,576,280,751,917,66,36,612,746,5,178,991,792,644,187,754,359,981,492,787,457,934,739,306,646,317,207,768,382,792,272,559,100,690,126,974,233,135,461,802,920,636,690,795,814,7,653,240,824,499,643,845,802,163,524,241,621,39,723,443,607,661,740,447,345,945,61,564,968,661,786,634,535,633,463,607,485,376,195,515,498,343,907,579,833,15,935,362,597,386,659,987,305,178,445,869,307,556,331,592,241,277,637,690,810,952,975,62,530,442,436,428,994,892,641,580,265,472,653,127,569,359,402,310,624,830,902,979,982,917,246,880,338,773,578,139,221,929,123,114,425,844,89,446,446,630,600,0,772,809,985,47,287,630,992,659,262,897,932,574,521,930,802,241,884,416,558,135,131,624,670,196,803,605,140,277,252,701,943,173,689,301,282,829,459,929,963,166,412,58,381,752,499,829,301,212,527,228,96,242,272,232,105,444,112,904,203,378,717,768,901,404,638,33,197,615,200,247,210,90,498,317,670,658,653,697,157,664,868,237,117,488,6,46,773,645,315,536,252,629,351,40,398,708,325,496,811,137,573,711,730,78,466,996,510,706,54,965,6,788,774,63,288,804,926,508,24,101,472,11,5,217,408,4,648,568,63,718,764,951,577,879,824,751,13,142,993,524,260,183,770,952,526,692,483,719,548,289,457,289,23,97,291,213,748,271,474,559,778,352,945,610,452,238,563,339,958,812,163,516,306,864,499,408,966,968,429,702,122,333,586,338,220,784,81,138,296,536,799,881,995,770,456,17,101,360,991,655,811,782,101,258,369", "790,568,94,596,181,56,111,371,934,295,395,84,773,865,798,569,305,374,941,238,875,915,948,276,742,341,290,509,851,703,613,309,641,312,857,705,403,342,886,712,321,760,831,710,358,878,936,340,621,155,317,727,744,535,702,756,193,844,175,633,115,346,715,85,344,221,725,740,982,721,87,150,391,790,465,668,380,804,606,968,953,989,806,621,976,545,377,802,852,898,731,333,569,693,422,876,491,682,905,90,834,646,619,571,981,585,81,876,903,748,982,377,13,772,506,997,466,782,548,871,642,634,948,245,313,944,119,145,662,380,951,595,871,318,274,895,616,300,322,179,724,318,969,585,929,107,458,353,360,741,522,55,371,559,990,675,895,985,123,440,534,427,286,135,700,709,137,414,440,220,77,854,244,208,752,32,582,458,786,65,384,21,998,931,762,455,966,181,571,213,635,178,678,16,287,761,887,933,915,424,813,641,192,434,967,649,730,926,497,534,942,856,68,113,479,397,623,64,926,345,380,857,332,21,179,699,425,932,601,65,677,11,340,385,885,132,713,131,561,245,998,283,130,556,142,31,629,387,6,443,597,13,930,937,695,431,908,702,241,631,393,254,369,158,140,762,884,308,519,109,907,245,218,503,487,457,81,108,848,906,927,241,764,825,304,369,852,558,780,425,775,913,961,316,864,716,884,445,807,242,866,619,460,746,491,777,441,736,773,135,74,367,150,672,867,405,597,981,155,547,891,365,620,60,648,57,808,460,238,872,973,526,477,499,809,863,681,85,644,947,715,290,771,570,306,216,97,618,986,393,439,201,499,81,952,284,402,298,628,924,736,169,150,146,375,203,85,571,349,890,66,787,360,338,152,183,64,32,442,753,417,352,762,479,465,17,769,196,343,475,97,792,485,803,382,892,412,224,336,945,812,414,3,595,84,336,730,432,591,559,816,694,611,800,726,813,413,257,404,699,293,123,147,756,496,699,455,375,445,961,919,918,712,543,121,677,244,600,809,211,640,839,238,302,862,390,818,335,909,196,373,761,945,806,430,612,399,331,624,971,293,886,434,35,526,450,543,782,526,835,774,979,374,854,174,582,688,247,186,360,865,496,773,656,612,21,960,511,960,203,669,608,899,999,341,987,360,638,409,632,361,498,961,860,119,149,574,569,344,161,348,24,151,891,528,551,528,408,819,833,808,689,784,471,704,567,974,996,739,621,447,927,460,488,23,39,48,512,698,248,395,654,572,255,516,780,930,28,658,27,782,925,232,928,225,579,699,415,56,548,391,471,580,183,790,260,581,462,548,223,68,946,502,457,283,513,470,511,62,464,489,238,416,173,580,281,384,71,432,176,242,217,628,385,984,898,332,249,246,469,408,209,682,880,309,607,930,665,201,122,422,724,59,719,879,935,733,686,311,582,599,909,225,104,595,363,38,437,124,752,238,817,870,491,621,959,385,384,187,215,541,15,635,294,750,131,513,284,261,936,764,42,6,658,279,815,33,476,774,1,291,589,915,970,239,708,407,970,102,822,963,259,728,20,245,700,773,230,558,30,825,496,908,986,841,338,588,634,883,364,321,689,389,269,973,329,525,237,477,421,321,447,67,872,780,462,178,511,115,34,959,581,33,383,206,511,262,464,378,201,161,291,354,431,896,18,242,933,369,961,244,508,24,163,590,272,14,957,824,464,197,838,69,451,909,162,549,393,980,663,533,214,165,155,297,944,608,495,816,284,449,19,849,299,411,275,890,791,969,987,285,868,683,58,183,75,588,642,321,878,859,343,69,861,954,247,240,460,614,458,27,153,891,755,772,0,872,80,176,945,100,80,701,618,6,230,171,849,649,201,150,773,761,647,660,793,304,659,134,353,893,945,521,58,348,319,645,412,204,190,427,218,550,405,804,871,176,496,684,549,852,164,222,963,709,648,74,591,644,705,993,447,145,118,730,22,60,757,778,264,833,198,190,821,775,165,55,493,853,662,129,168,599,486,807,285,522,137,308,330,363,102,290,640,789,954,645,1000,472,235,79,490,177,76,314,920,304,523,240,432,292,204,508,722,439,212,167,466,129,777,638,741,170,233,882,486,452,782,281,463,100,196,113,966,728,286,881,493,550,4,774,15,195,342,617,981,792,277,282,834,545,119,110,412,293,659,658,806,300,243,467,945,448,524,491,834,435,336,662,348,728,701,976,328,178,183,414,500,631,704,8,617,770,427,518,459,173,690,260,960,724,316,737,741,370,151,988,83,921,869,953,343,193,916,581,20,3,50,799,366", "268,640,937,439,864,446,628,532,211,730,893,166,695,153,733,553,998,987,338,279,35,660,465,203,67,461,481,638,829,322,399,473,121,991,80,222,800,435,144,768,912,504,303,685,559,5,548,365,398,906,615,522,187,842,664,835,529,242,265,202,262,47,419,138,501,117,88,596,926,587,154,164,721,604,185,816,705,708,842,433,328,69,294,15,586,741,452,72,110,358,328,21,303,706,240,371,274,70,495,508,609,873,313,305,827,749,298,973,678,588,645,685,316,562,456,62,785,644,27,908,917,935,256,583,861,382,143,690,366,857,381,102,361,492,427,652,244,458,157,974,195,200,506,193,19,576,337,760,256,525,544,158,811,136,432,849,552,860,809,575,573,722,98,361,875,764,591,209,5,632,372,151,994,578,752,151,463,69,675,786,614,671,133,164,288,290,222,100,38,901,67,76,401,331,193,411,866,789,259,378,248,798,501,78,578,181,61,128,534,260,542,519,366,243,606,125,129,962,709,499,774,89,227,505,499,785,400,873,747,244,227,119,369,555,216,687,386,724,531,775,354,546,54,803,279,373,504,341,9,708,955,642,388,192,435,711,721,735,90,679,780,924,212,877,167,464,524,338,706,553,173,766,745,414,118,705,602,909,675,745,119,191,657,782,904,404,449,186,990,670,386,618,573,953,542,994,925,747,481,945,646,452,520,185,715,151,157,211,754,242,561,87,124,244,40,323,818,418,348,557,828,653,951,609,887,258,242,334,967,495,40,203,466,277,566,449,68,765,751,338,21,226,453,74,937,611,798,198,171,837,96,288,648,671,926,65,783,814,593,526,862,51,211,536,407,24,204,52,654,339,635,795,278,237,832,759,709,517,516,875,797,594,231,871,274,287,732,204,598,110,721,644,610,368,870,787,804,948,748,646,116,948,336,650,999,491,42,656,105,206,39,602,54,57,785,793,83,487,979,431,182,509,607,731,723,785,994,688,640,453,869,875,761,752,834,139,24,890,639,519,485,33,615,109,590,316,64,562,329,341,31,137,847,23,583,244,549,851,594,791,45,888,7,575,920,67,828,371,278,985,54,100,745,188,815,311,544,143,297,749,761,764,321,780,212,608,787,229,376,2,30,769,363,73,468,4,438,64,523,417,198,590,745,399,747,14,424,670,932,857,611,323,929,746,87,136,829,458,888,593,428,915,976,975,549,229,716,442,283,994,49,63,651,642,619,704,969,832,852,483,107,731,511,223,236,5,775,782,971,820,599,729,620,463,478,265,70,546,589,686,208,236,500,362,268,72,746,308,548,932,575,778,256,556,229,834,570,943,630,917,407,61,298,744,9,991,627,960,189,210,852,583,989,805,792,859,801,95,586,390,880,369,344,867,115,399,151,137,217,392,2,325,152,586,149,648,50,425,699,837,737,353,974,398,258,949,134,741,900,918,850,941,634,211,575,394,583,371,957,668,671,184,557,419,773,449,502,489,308,18,709,83,895,980,16,708,969,418,573,641,136,136,134,28,487,379,300,598,424,663,833,834,341,989,818,558,801,121,776,91,150,426,317,994,862,172,35,553,669,961,192,544,13,893,10,533,68,669,20,123,235,464,881,273,167,186,532,704,472,880,216,557,655,537,681,563,822,546,843,129,111,944,697,497,666,82,469,83,817,644,881,986,380,586,404,359,858,734,125,536,228,122,573,454,29,786,146,1,764,985,102,479,289,66,663,179,511,998,127,414,696,689,237,253,894,522,545,721,664,79,644,761,957,474,122,65,706,598,792,531,637,632,909,462,631,176,933,64,945,277,702,422,478,767,809,872,0,812,949,853,822,474,363,632,648,417,162,882,460,218,473,304,156,794,557,270,396,771,294,936,55,174,848,66,893,312,346,924,67,646,601,509,636,255,148,165,176,364,664,656,196,387,748,364,475,357,283,765,147,546,914,722,654,151,255,685,129,317,424,84,691,934,523,54,796,713,464,655,430,596,363,40,606,707,747,866,445,159,384,221,253,550,692,830,849,443,190,762,275,126,543,545,450,185,369,822,33,426,253,684,588,851,335,692,964,71,659,588,689,300,697,938,112,986,154,825,976,275,350,398,595,107,850,866,111,305,21,374,141,316,714,21,911,443,96,79,607,868,952,750,767,768,19,372,26,78,691,956,269,289,387,301,635,849,642,153,48,415,376,500,839,938,193,788,761,428,434,590,341,887,222,672,287,875,911,120,60,804,301,234,952,474,686,970,223,772,926,275,242,564,640,667,649,726,247,723,541,799,761,637", "176,328,576,930,889,9,694,871,423,969,280,566,695,161,798,726,437,402,749,799,865,355,662,638,786,210,460,858,553,566,411,394,434,895,878,258,123,515,246,722,668,935,81,267,289,251,846,268,769,244,507,633,624,592,141,458,241,711,926,658,114,976,9,422,604,728,756,333,41,984,521,689,110,176,611,871,573,50,946,950,187,626,494,494,991,28,797,342,115,419,993,46,88,662,861,561,325,227,514,60,490,678,315,474,711,602,395,724,564,448,689,570,20,104,107,543,598,880,191,746,571,334,477,106,832,205,121,759,54,781,377,488,516,315,527,185,314,199,189,620,882,254,465,7,394,166,642,891,202,698,714,705,910,42,114,106,128,293,355,874,625,289,167,888,501,843,788,762,573,299,231,930,214,568,497,577,393,174,496,659,162,945,168,317,649,10,763,386,484,506,385,968,250,600,880,770,509,804,250,365,568,70,640,971,224,742,906,887,409,317,287,679,470,253,930,551,803,366,358,304,979,791,656,544,229,53,544,861,394,523,261,15,945,575,702,392,12,611,801,416,58,35,375,865,49,27,410,249,426,582,631,650,489,260,51,523,261,359,804,559,426,405,957,483,536,841,949,422,417,923,929,178,104,771,285,866,739,640,751,480,932,575,839,619,161,852,683,520,645,563,149,769,427,647,375,131,973,810,446,586,295,517,760,782,917,687,545,156,223,925,176,717,281,418,923,431,601,932,858,671,456,367,692,516,986,96,33,913,684,539,343,448,677,273,446,425,542,729,314,914,164,147,783,287,532,969,373,429,657,439,862,573,415,339,743,35,36,195,464,466,56,348,621,627,111,793,568,737,347,874,877,429,128,861,61,569,756,932,103,15,108,903,525,696,405,817,732,549,424,707,420,619,768,251,762,844,47,357,190,295,576,263,468,311,683,69,665,351,331,806,861,445,710,628,14,48,167,463,957,895,737,43,219,11,14,837,702,401,285,290,235,705,127,528,266,148,72,590,114,136,487,212,113,519,758,814,113,224,864,773,396,435,896,258,132,600,444,457,808,436,2,299,409,172,158,338,454,482,723,455,560,980,811,783,341,868,834,889,906,641,736,826,389,733,794,695,144,854,649,60,723,774,354,146,955,322,748,232,84,315,329,580,413,404,875,377,234,529,746,586,414,125,761,212,684,818,764,205,584,367,767,97,434,854,927,589,873,464,723,904,2,855,226,867,526,894,876,525,602,567,274,146,345,417,697,400,29,660,194,973,967,436,754,515,294,156,270,305,98,412,470,492,148,469,69,852,950,155,268,153,507,713,344,22,268,163,183,353,14,158,733,486,909,892,474,393,653,747,74,469,886,232,498,696,360,794,968,865,854,313,168,417,432,35,89,438,291,440,726,333,984,783,414,687,259,398,713,996,13,291,706,244,180,692,248,953,950,883,49,331,663,425,603,235,667,63,675,939,533,235,232,147,986,432,382,645,515,397,650,835,789,52,985,876,568,71,394,882,509,950,44,234,710,698,508,409,229,554,72,879,101,991,686,352,973,119,419,661,776,945,510,88,865,808,28,918,953,827,726,128,686,706,550,477,147,314,968,177,912,738,917,824,367,201,355,6,919,299,505,672,7,500,632,418,102,677,407,31,606,916,781,15,668,339,110,809,179,364,897,160,930,274,929,3,454,317,393,581,464,423,58,120,640,167,384,971,575,261,36,643,31,710,912,944,833,259,409,230,544,793,392,482,262,306,721,879,765,239,298,308,521,389,388,912,768,679,953,364,44,256,211,667,399,92,598,359,733,902,599,881,715,572,662,487,985,80,812,0,488,908,543,964,981,126,258,753,405,892,225,657,442,903,663,974,796,535,977,673,63,440,450,472,35,192,820,290,906,254,484,146,415,836,113,849,107,673,706,983,40,901,862,576,499,759,892,522,571,784,447,318,420,263,199,52,551,646,395,632,353,382,779,234,827,64,440,123,955,167,622,447,822,810,37,11,134,258,86,520,900,188,342,117,545,796,416,927,789,234,184,215,914,968,119,211,209,432,832,977,244,760,37,335,311,891,383,913,776,586,223,72,455,186,651,938,654,700,251,773,868,605,176,43,699,500,990,446,579,276,300,570,632,512,729,907,371,775,970,254,622,685,777,349,211,199,84,785,497,340,366,498,726,911,81,716,538,54,233,775,925,631,242,185,86,864,464,885,572,67,36,491,388,700,813,321,965,966,75,6,760,189,615,277,599,527,993,632,960,65,947,202,238,419,848,911,259,349,500,684,603,377", "998,932,995,922,143,568,514,618,177,926,764,850,391,43,253,341,614,637,93,870,50,350,160,152,35,862,485,895,363,458,240,911,429,391,14,406,505,394,945,253,543,632,496,399,584,824,17,258,412,86,495,660,823,313,430,989,717,120,877,244,785,350,509,755,168,466,272,553,138,894,858,226,39,216,137,799,900,217,469,359,759,143,53,649,861,630,321,980,436,297,100,58,58,15,571,7,292,607,249,909,358,372,17,512,251,27,54,410,854,61,609,612,397,853,256,470,114,601,992,124,631,827,496,439,988,173,364,892,290,455,215,576,671,697,100,435,661,156,619,34,705,709,471,420,836,739,614,674,780,122,342,921,150,611,405,815,851,494,551,778,948,766,625,613,505,570,524,757,282,919,341,907,864,214,280,10,3,661,242,612,31,357,41,406,681,815,412,616,268,127,266,921,35,933,751,708,642,226,363,90,857,121,462,26,651,233,221,487,454,15,760,422,944,256,526,516,102,446,523,98,725,816,975,129,273,331,962,338,132,220,404,986,626,813,999,812,563,897,453,439,485,244,336,68,446,328,225,427,150,184,338,689,864,554,866,217,250,88,311,562,570,542,380,621,393,848,531,806,288,121,881,597,122,711,301,506,587,996,964,96,616,621,274,349,41,374,889,30,245,958,529,758,515,199,723,521,630,593,290,184,53,242,672,966,241,20,95,492,511,530,366,550,17,599,35,732,281,462,45,208,315,253,723,864,962,687,788,256,623,318,607,465,396,927,111,160,801,912,727,611,156,111,529,302,341,992,875,917,348,852,448,148,989,718,725,863,499,502,460,755,53,497,886,412,295,79,436,671,504,371,861,648,795,358,659,425,532,201,247,406,759,442,723,246,936,561,231,437,902,914,501,372,792,18,97,580,776,565,569,793,460,489,633,407,16,198,789,470,966,830,709,347,676,565,333,46,868,934,620,469,231,751,163,866,786,658,532,964,799,474,220,75,146,396,895,792,806,557,999,91,517,199,928,304,971,409,287,183,355,863,509,356,876,247,148,412,706,793,636,321,558,350,598,642,485,919,627,151,794,583,338,853,773,357,920,69,829,9,865,913,586,597,646,157,596,34,58,682,127,72,829,219,344,287,767,549,264,850,332,315,946,184,9,309,973,506,671,743,535,349,123,876,729,98,602,403,916,591,298,607,925,356,226,188,387,335,901,159,398,419,764,613,280,422,960,222,332,559,635,240,508,574,864,825,546,870,942,598,736,752,551,510,86,5,29,615,194,980,442,161,153,441,63,420,608,463,59,106,861,966,307,199,956,31,304,960,297,262,415,832,176,561,967,858,75,224,569,138,906,201,866,191,960,452,26,533,121,131,407,468,834,571,51,623,801,936,432,753,933,439,501,872,130,576,64,438,668,368,746,712,510,299,998,844,514,503,885,459,919,513,788,772,925,193,732,369,751,997,520,577,401,712,962,23,745,363,6,464,164,577,412,111,749,905,595,721,764,963,161,980,871,916,321,357,799,913,214,159,965,943,116,232,136,172,268,406,195,996,723,60,918,306,544,988,497,849,566,215,625,523,514,230,270,821,944,716,370,359,884,591,662,258,55,224,694,668,104,4,152,555,873,117,425,698,271,727,173,97,6,392,965,493,492,820,449,744,838,410,11,92,137,921,405,641,844,806,703,172,951,564,110,617,608,864,913,319,708,803,434,649,143,371,719,661,333,351,297,756,347,312,169,934,204,308,879,404,403,59,3,849,733,975,312,126,668,667,581,448,435,172,451,101,215,821,916,756,142,641,746,865,972,518,712,43,47,176,949,488,0,543,783,553,344,839,892,40,288,298,359,645,107,976,744,178,656,283,979,518,633,908,918,407,556,944,96,846,751,953,634,137,144,62,617,459,735,675,817,638,521,313,498,85,731,447,169,365,149,503,320,448,876,639,237,571,526,571,962,597,802,965,346,496,554,960,433,27,258,357,950,125,715,809,139,777,83,199,609,28,838,106,79,755,801,77,956,604,611,560,752,109,547,175,914,336,567,596,156,200,143,176,132,221,234,627,674,990,18,504,778,399,194,216,538,370,304,479,432,925,839,886,596,24,536,38,727,384,565,919,26,500,118,762,363,265,867,250,587,159,713,931,640,615,782,752,906,923,51,115,494,172,728,65,216,742,713,340,97,266,11,448,928,967,498,954,778,403,989,956,399,198,132,835,911,123,323,36,837,729,527,206,584,231,985,75,512,366,67,515,436,233,894,289,255,27,443,11,639,537,150,289", "811,520,751,316,916,837,117,852,423,313,231,713,891,573,327,378,602,698,809,420,127,805,733,515,265,332,107,463,572,470,646,780,144,716,728,884,258,795,636,116,307,663,202,332,472,828,818,940,398,319,631,544,751,335,306,729,108,959,152,551,860,441,351,199,166,150,491,759,168,602,50,841,785,815,693,630,844,833,827,171,598,649,250,78,90,804,928,616,50,542,733,109,689,808,306,762,655,8,821,453,924,289,197,655,252,206,773,972,975,581,445,19,618,127,499,904,922,353,838,405,899,298,980,818,378,553,288,559,912,853,361,837,987,701,386,137,495,3,101,956,379,996,508,286,904,325,185,596,788,183,648,29,731,473,803,527,432,333,146,20,594,382,817,366,355,738,279,671,14,943,635,186,368,998,94,792,235,651,643,526,305,850,238,8,252,207,811,622,550,332,486,849,509,722,26,668,426,208,570,120,416,697,690,54,362,515,217,791,270,5,115,364,314,197,71,206,19,608,430,316,464,825,578,99,841,217,150,374,158,726,978,593,64,718,651,163,184,934,558,794,616,303,689,585,4,536,309,342,631,720,753,593,905,418,110,332,236,661,347,985,166,19,146,258,279,129,692,391,442,832,831,618,611,633,641,505,571,431,606,56,139,789,78,102,147,587,114,264,653,465,599,749,473,450,143,849,507,185,745,937,54,416,325,910,849,707,307,206,306,214,716,698,823,24,314,128,384,478,425,975,562,117,198,564,816,230,828,793,124,267,226,541,442,157,343,516,171,622,916,447,424,296,5,259,258,278,702,147,769,375,527,378,346,382,544,14,286,747,751,244,447,373,706,132,280,525,728,958,18,438,306,480,183,955,641,768,501,359,675,291,96,953,211,460,804,524,681,460,567,520,905,249,308,559,953,310,668,208,121,712,333,726,373,241,629,797,497,855,873,165,537,729,541,620,616,359,150,635,962,143,888,514,830,434,477,769,35,891,391,609,271,991,306,380,931,5,621,774,891,378,715,328,488,837,253,964,383,63,841,406,463,344,159,992,711,920,77,802,499,228,350,933,566,766,817,722,428,980,290,915,870,633,920,868,157,507,142,543,119,83,877,95,640,265,334,569,666,786,770,617,348,410,212,748,383,697,406,729,370,679,459,4,742,903,146,972,304,565,99,983,329,33,234,978,179,296,603,82,185,532,334,291,310,876,412,929,238,153,520,11,429,648,168,928,810,466,985,988,303,525,371,567,120,757,404,761,56,904,571,910,777,136,483,696,369,54,528,98,23,273,347,276,863,31,296,466,438,48,292,3,716,730,485,349,477,566,165,721,688,532,482,324,967,393,198,412,802,428,828,620,233,132,325,875,404,304,407,698,561,8,343,707,649,522,444,650,309,82,889,946,48,127,58,550,252,937,211,465,644,628,54,144,511,386,63,530,254,722,189,438,392,290,19,722,881,962,368,539,228,658,70,657,152,832,345,620,740,590,207,668,49,341,876,334,496,198,614,70,53,191,843,12,928,359,98,299,326,205,874,897,307,770,858,242,398,734,913,257,947,121,605,180,806,950,917,855,159,515,971,27,554,276,33,65,803,681,595,842,354,668,134,992,531,317,880,908,47,240,777,506,450,492,119,3,220,557,401,997,261,813,502,918,817,92,127,211,953,408,193,503,831,346,596,149,224,8,585,408,808,737,816,882,87,812,505,515,931,427,70,463,783,833,524,28,884,889,882,209,28,202,743,370,137,348,878,72,335,627,974,33,670,174,728,153,286,287,786,40,922,910,975,259,228,48,433,9,71,706,813,291,64,45,637,979,287,945,853,908,543,0,915,757,102,954,566,244,61,677,829,572,936,194,581,281,386,353,990,459,228,374,502,154,200,600,872,129,327,388,332,695,164,838,847,489,887,990,22,211,972,7,973,512,119,151,824,669,290,232,242,193,767,459,82,776,777,637,975,573,427,803,419,547,334,298,218,233,529,204,979,251,294,99,90,967,899,631,440,105,528,382,437,322,319,995,978,2,399,782,850,840,682,310,236,755,650,846,297,407,586,419,212,869,220,506,830,309,556,472,979,49,845,855,240,752,849,789,727,512,377,493,810,613,207,603,957,151,932,902,49,824,642,607,903,994,654,20,459,226,15,228,406,677,133,702,755,557,164,330,28,602,565,10,397,567,271,61,871,208,645,491,39,50,101,952,83,393,389,190,113,639,701,627,623,853,731,239,266,465,64,419,916,924,936,719,198,338,742,728,883,601,957,366,713,342,934,80,953,76,889,768", "987,288,235,917,455,211,617,992,250,755,276,735,325,924,947,690,270,566,60,652,356,507,435,799,75,941,564,55,801,938,850,468,357,736,922,729,437,508,62,346,510,733,320,779,182,8,373,235,827,151,703,598,90,811,719,87,985,317,15,779,254,186,731,934,579,294,699,635,252,22,879,193,6,832,887,245,12,604,275,249,338,172,202,53,321,170,772,621,500,729,549,303,831,927,230,826,760,552,749,462,514,64,522,142,866,957,259,236,912,285,880,948,542,783,47,598,398,992,543,205,445,403,89,149,617,112,127,916,997,316,852,738,1000,659,571,203,743,99,53,13,1,348,454,303,657,161,397,93,261,72,319,861,15,270,332,608,274,470,484,640,346,614,777,506,214,782,361,235,355,272,359,900,590,72,897,246,263,380,908,278,574,349,347,879,798,557,340,971,797,887,284,23,390,449,830,725,348,749,48,754,565,623,605,76,890,133,681,272,775,192,757,95,267,103,917,726,336,175,10,475,927,796,740,885,65,829,486,506,876,287,84,399,723,474,559,473,616,966,463,966,464,379,758,193,179,140,524,918,188,769,798,844,297,32,246,913,982,168,591,415,732,127,10,430,162,916,79,509,192,959,684,687,807,634,306,782,246,760,937,185,938,365,974,246,693,958,240,843,566,882,585,304,759,434,832,62,36,766,406,610,683,726,887,582,662,896,551,642,815,800,122,968,708,23,933,561,942,139,868,321,621,537,217,779,396,609,482,419,787,246,42,289,395,594,447,69,879,828,504,279,27,889,408,729,222,156,23,938,434,271,791,214,751,347,472,749,73,229,893,971,672,400,734,262,954,776,942,25,159,337,869,489,355,761,608,782,118,410,514,254,424,34,507,740,850,423,167,557,352,971,28,406,187,788,994,974,1000,773,553,557,203,186,916,988,60,81,21,773,3,275,343,676,857,716,850,909,108,487,678,452,599,20,227,19,951,39,630,532,595,805,667,732,504,702,342,881,269,226,692,139,961,845,618,967,184,399,818,419,431,751,136,169,778,701,659,67,532,765,25,211,974,524,355,914,260,475,440,839,894,220,550,803,224,973,269,555,509,578,531,662,74,533,344,663,718,592,424,152,912,475,908,995,36,887,661,489,777,117,808,754,423,195,584,100,274,83,683,885,50,234,186,46,694,529,784,754,212,378,303,440,741,412,487,858,949,888,207,714,685,702,251,591,623,370,136,487,598,387,266,131,791,277,104,355,684,470,612,479,293,29,214,331,953,88,445,6,341,235,74,487,982,822,131,660,366,163,807,180,565,370,725,756,673,575,53,673,206,206,897,737,275,881,936,259,456,89,11,938,36,394,247,599,964,725,48,846,62,591,200,260,248,898,958,444,772,580,480,133,721,239,127,592,837,841,253,792,607,551,650,817,17,719,100,161,105,106,959,890,90,296,316,523,911,290,977,308,854,667,552,11,684,490,916,93,549,674,495,683,493,54,761,73,562,387,589,588,400,944,640,651,927,48,146,634,979,534,496,78,466,871,951,991,23,436,74,422,215,3,921,497,350,473,342,658,113,775,587,884,274,121,618,585,87,724,766,782,767,300,618,672,402,206,606,588,81,224,921,852,516,520,130,595,869,248,387,86,847,383,742,59,670,268,830,358,65,102,363,411,631,368,460,577,774,69,194,788,369,832,758,292,550,885,411,348,568,590,758,368,934,984,73,220,894,73,152,573,404,974,479,773,273,830,664,653,743,21,332,68,921,891,607,396,522,478,176,352,623,168,436,847,643,495,167,352,653,331,603,826,358,569,597,389,706,419,630,100,822,543,783,915,0,612,924,640,642,532,181,909,354,456,752,336,677,773,605,251,108,967,283,342,588,488,954,193,667,865,482,701,265,284,62,460,365,684,837,761,485,526,554,9,793,949,407,803,18,61,441,346,385,974,792,944,524,693,669,722,531,704,944,555,174,438,484,344,131,744,740,590,674,496,852,234,318,559,479,788,543,722,453,582,488,541,180,752,153,91,353,900,89,150,685,81,948,11,130,927,43,318,710,721,917,789,78,774,846,165,770,331,304,785,70,344,779,717,565,387,295,357,229,71,121,276,457,945,817,572,505,322,735,520,654,634,501,521,854,955,420,823,531,674,939,994,558,635,601,735,622,122,93,925,48,871,325,351,827,863,451,905,544,373,812,922,721,168,526,908,982,785,895,512,806,673,629,571,519,276,589,699,173,840,143,789,583,156,134,456,690,719,816,143,795,678,838,799,61,323,663,159,926,584", "130,663,914,751,731,865,239,84,523,791,637,63,714,692,595,231,470,702,509,678,400,200,460,359,926,613,719,813,972,748,586,887,441,661,881,486,330,599,138,217,334,768,522,594,139,801,318,127,534,357,837,292,541,873,474,190,352,139,832,98,674,526,44,894,213,533,365,263,496,183,748,651,83,483,770,209,432,701,150,683,855,1,948,614,991,389,434,261,617,998,413,270,141,295,689,870,725,840,645,212,231,573,343,643,839,142,656,760,589,507,88,430,881,718,970,317,274,335,664,162,373,516,806,825,529,915,524,469,101,812,892,369,118,955,880,155,262,492,280,234,252,320,419,340,102,310,327,297,823,993,9,433,104,760,690,24,835,71,242,236,569,421,535,636,958,470,858,74,564,877,616,611,248,394,990,962,919,302,537,707,779,812,438,681,264,213,79,879,440,51,901,881,89,221,815,676,254,273,493,80,783,525,66,109,591,886,731,172,693,425,485,140,216,703,883,537,536,737,458,612,855,104,439,822,549,592,344,253,163,587,28,978,844,810,729,188,884,131,359,655,731,916,554,651,70,395,765,306,403,213,329,874,952,585,949,968,366,401,717,489,987,819,64,112,381,675,246,314,154,448,943,553,720,108,945,41,682,924,389,767,575,809,715,259,366,683,598,385,103,756,771,195,554,939,261,833,613,193,308,329,818,62,96,616,379,294,876,662,100,148,318,862,716,90,218,817,738,687,600,725,553,363,813,611,153,969,702,399,345,811,972,215,31,611,470,607,597,352,892,187,562,341,308,387,533,989,541,760,980,714,91,673,92,882,310,114,689,764,374,399,661,984,418,152,225,904,549,781,580,840,240,470,423,587,846,63,906,723,512,749,82,112,91,564,833,415,265,862,867,236,131,956,953,48,373,286,120,275,590,546,666,439,597,324,625,528,881,966,362,537,681,114,328,257,82,67,545,321,318,327,887,656,891,957,823,280,312,794,276,118,491,534,714,692,736,7,993,115,873,268,306,16,62,829,247,482,339,612,695,151,912,960,756,899,867,209,605,212,182,699,685,631,71,347,233,333,652,486,72,354,254,788,298,507,834,631,554,430,563,124,407,577,925,568,971,556,181,186,237,588,98,21,337,227,97,919,162,471,680,998,152,213,229,776,548,793,878,836,50,594,766,26,368,663,493,443,498,102,685,988,517,848,627,172,347,974,393,10,578,34,21,727,369,481,638,410,476,838,857,224,761,736,753,526,257,570,741,645,381,603,974,759,457,726,572,529,131,115,984,171,831,685,522,513,357,627,544,740,955,549,80,51,966,846,198,228,34,517,745,705,157,329,874,734,839,490,460,611,244,895,570,612,418,580,233,372,355,300,853,98,986,836,354,74,931,443,477,302,781,231,758,288,742,260,113,843,158,163,725,672,62,391,257,49,379,712,397,595,338,67,226,755,352,834,580,544,958,825,365,797,513,351,149,542,381,494,854,236,349,422,460,557,791,617,951,480,975,388,738,887,41,99,795,976,142,685,889,331,447,674,923,146,575,55,558,239,603,931,836,401,825,819,342,879,678,809,910,11,870,879,674,391,193,765,903,120,519,189,816,396,749,988,195,881,700,276,924,123,288,21,528,535,853,575,289,197,532,507,331,457,683,68,289,54,647,729,202,972,590,993,697,648,715,596,23,480,209,46,82,329,138,491,910,329,996,405,779,152,539,799,679,194,436,352,681,558,708,605,152,648,912,662,755,381,128,154,942,140,165,450,177,507,934,561,536,332,53,706,620,163,562,103,8,458,699,794,511,339,93,987,954,766,294,914,992,80,474,964,553,757,612,0,741,779,31,989,230,588,876,161,26,683,653,154,770,140,331,622,392,752,755,7,174,28,587,504,658,370,181,189,616,373,750,119,110,780,932,326,150,34,513,752,738,516,391,87,891,101,368,672,236,354,867,215,835,749,284,320,86,590,30,28,757,744,520,158,827,725,949,546,789,390,127,371,157,714,535,643,445,111,172,125,515,3,338,238,430,459,671,666,844,511,709,607,43,309,744,149,617,511,777,745,710,638,452,587,394,264,504,401,75,783,748,569,150,753,111,233,569,972,533,691,530,371,350,555,705,861,208,92,866,380,646,517,211,226,179,357,64,341,875,206,580,646,727,425,139,531,337,898,90,576,889,789,488,976,125,516,795,816,633,558,598,555,522,317,484,861,320,851,144,552,36,482,15,31,12,277,286,752,66,521,238,147,123,15,467,110,259,780,994,195,587,224,8,82,440,922,524,783", "307,519,855,203,655,280,425,430,750,579,655,627,929,17,4,168,190,848,593,119,376,507,638,134,927,200,932,913,203,35,173,787,273,710,149,177,79,740,930,523,685,531,131,844,333,595,192,676,359,470,637,292,29,270,145,161,550,538,645,425,95,26,134,149,808,515,538,165,293,566,416,642,932,672,357,470,605,353,388,610,669,411,66,463,215,293,309,114,371,16,930,130,91,970,846,184,340,545,278,927,446,763,760,807,661,305,877,983,80,812,818,815,86,790,942,237,174,108,138,209,887,812,32,336,108,905,810,101,84,695,389,552,565,345,15,878,434,454,742,852,646,734,839,293,808,776,762,998,55,151,802,776,52,459,790,644,622,974,394,657,831,240,59,979,139,69,640,324,83,393,543,248,356,610,10,237,276,8,973,582,695,412,834,682,186,782,469,650,882,52,483,922,934,848,630,351,773,393,88,624,111,281,476,429,159,311,582,713,180,225,229,9,880,172,710,813,878,720,474,139,592,234,101,817,374,160,546,179,883,889,79,729,515,561,652,694,234,959,575,641,68,465,100,766,603,200,657,920,394,940,348,634,847,751,443,992,234,796,744,322,551,859,28,195,117,479,536,742,102,656,811,413,421,802,916,561,485,432,544,87,501,762,135,686,58,718,835,979,349,301,166,819,629,913,417,348,541,677,565,326,957,132,280,838,530,339,951,123,467,465,900,176,507,675,200,681,276,984,482,266,297,377,291,638,959,512,228,581,677,762,165,698,973,586,829,851,502,879,439,744,626,198,650,530,489,584,183,926,890,612,103,714,581,738,873,149,845,318,973,988,136,649,458,187,26,522,346,161,915,733,92,674,944,690,291,262,344,896,351,308,861,545,608,811,263,433,487,517,175,898,239,312,822,185,345,40,351,376,120,35,203,686,356,825,818,494,450,446,247,568,508,342,637,332,722,480,386,960,906,346,570,907,170,577,282,974,16,851,300,318,828,290,488,494,769,761,57,441,5,44,149,925,926,333,925,21,526,571,913,667,358,15,959,70,936,596,501,34,901,61,614,942,280,676,472,722,828,288,143,208,789,841,254,851,430,448,52,499,163,583,166,575,676,132,503,209,970,86,642,954,277,173,64,78,71,181,168,221,136,266,914,668,831,934,33,310,525,468,860,658,284,998,102,707,148,209,587,715,57,661,90,244,652,597,53,785,140,369,769,347,769,190,715,610,216,183,787,757,172,190,687,606,450,622,37,955,843,886,390,550,456,371,173,848,54,322,138,445,47,138,646,162,468,352,999,15,21,357,580,335,434,582,856,515,61,411,164,400,698,309,533,153,929,237,839,937,934,177,18,833,969,642,356,280,841,130,247,962,207,392,421,244,550,844,362,861,508,155,242,207,918,669,695,250,205,786,233,445,334,621,658,199,488,798,421,432,299,9,404,43,948,692,277,619,890,557,644,726,946,75,715,315,259,910,314,790,392,342,716,746,879,224,194,988,312,818,897,870,166,702,429,450,627,352,242,155,153,10,4,321,794,64,729,248,557,280,405,295,619,304,530,554,505,239,709,761,23,810,577,211,714,735,8,223,880,443,165,875,21,285,644,250,147,240,203,997,584,874,968,217,876,379,169,93,949,63,194,245,336,385,391,732,155,16,253,973,936,866,313,399,332,54,945,364,477,260,177,755,680,630,605,776,388,658,973,140,33,917,945,759,550,924,801,686,774,365,131,727,998,685,67,302,636,806,786,139,921,791,834,889,145,174,829,521,764,96,235,45,2,696,609,194,529,590,136,959,252,209,592,158,418,982,535,282,659,701,363,981,344,102,924,741,0,1000,144,191,675,661,59,86,698,918,937,796,367,175,666,97,981,116,776,21,611,354,634,409,5,926,378,200,530,337,567,889,911,933,455,982,864,97,518,277,731,433,703,716,240,585,986,98,101,96,656,350,872,786,152,964,32,138,373,108,223,864,544,30,84,513,997,556,960,64,223,34,354,551,829,647,183,51,151,56,271,929,251,714,660,867,206,761,847,633,665,697,678,556,522,455,73,626,329,114,276,273,569,745,61,542,56,539,73,813,10,117,103,17,264,675,387,866,374,45,63,205,763,374,325,359,521,739,117,775,870,799,315,974,119,666,459,298,731,365,499,66,485,382,787,598,253,230,788,606,727,388,690,300,114,322,732,704,714,772,215,452,261,729,859,844,680,299,100,877,664,310,240,633,225,384,631,713,883,460,541,793,176,764,695,100,460,570,944,845,177,968,821,616,129,859,62,819", "735,741,548,557,620,10,839,937,186,967,275,516,520,737,886,568,831,664,824,323,627,45,123,254,854,409,463,645,124,25,503,286,723,45,455,78,207,924,588,500,63,392,242,26,764,321,893,31,729,538,313,916,761,472,359,21,98,584,823,368,245,171,448,686,139,823,515,655,550,590,407,831,996,198,897,627,213,459,166,580,197,370,351,510,775,169,742,710,345,648,108,708,569,777,975,169,235,139,801,385,594,667,261,959,994,946,911,712,879,772,425,480,946,276,741,982,707,93,939,3,166,157,777,927,254,688,232,875,359,515,477,844,435,946,99,971,954,7,800,314,225,523,53,720,870,37,373,913,67,38,184,531,731,943,897,392,921,391,473,523,334,674,93,703,130,378,787,290,264,729,748,757,376,78,599,226,822,441,598,817,672,306,940,157,95,445,278,895,756,186,575,508,384,928,345,206,540,924,92,47,615,888,234,289,293,666,546,442,453,509,329,878,501,733,654,633,759,872,425,521,862,697,930,269,567,430,283,451,606,871,963,297,347,118,846,103,543,932,692,157,778,742,750,380,317,60,439,750,389,565,9,860,739,747,906,15,285,905,739,242,545,692,656,374,256,318,662,974,479,92,419,278,721,482,860,105,273,909,374,261,660,385,565,756,706,637,494,874,616,782,448,540,822,298,365,760,848,750,222,511,569,909,819,363,71,710,490,494,267,926,138,353,82,384,644,542,704,946,512,875,168,2,281,394,915,542,240,987,465,962,931,622,671,638,489,496,586,730,482,76,384,200,681,499,571,416,144,386,623,736,260,221,284,642,194,210,986,156,700,128,373,643,529,897,400,772,746,253,49,431,234,973,47,887,669,828,206,198,300,153,648,12,874,674,681,454,685,669,893,647,347,552,70,882,21,500,972,746,353,285,279,97,69,717,19,253,89,813,862,78,557,640,408,511,797,850,295,123,999,411,454,450,39,394,130,61,112,229,361,133,168,367,604,330,616,332,586,649,298,945,78,115,741,252,974,242,381,54,693,468,792,378,646,261,914,715,147,580,686,395,671,417,605,880,221,486,752,840,830,407,412,204,175,20,27,813,319,424,637,806,64,19,455,994,253,880,260,683,854,820,580,707,120,397,669,356,645,734,149,973,479,327,251,674,181,969,213,479,515,56,456,235,533,532,652,504,226,648,559,362,292,220,984,425,490,169,368,157,970,312,479,478,974,76,123,248,799,99,661,123,376,884,904,228,788,728,256,77,588,431,780,632,785,350,483,336,335,995,958,739,690,392,27,997,231,264,120,243,994,437,834,561,613,383,706,196,740,472,54,886,330,620,891,88,629,107,945,176,657,161,943,778,952,596,245,856,134,424,665,684,574,675,812,79,890,453,299,936,800,730,579,445,203,533,69,377,151,13,976,224,999,386,402,618,11,792,428,395,422,499,362,177,250,890,94,428,218,873,809,440,19,969,869,220,501,402,978,45,72,315,332,569,100,172,148,656,685,394,663,950,935,967,172,34,750,177,207,20,695,938,394,411,272,799,892,79,113,684,166,208,590,239,477,981,46,371,133,630,994,581,636,245,828,79,10,347,111,88,468,507,105,724,765,970,593,67,522,599,526,733,666,591,620,829,851,368,776,561,956,424,989,381,984,326,53,311,207,513,323,424,573,576,796,272,854,530,640,261,989,509,762,73,492,505,194,40,447,649,842,94,751,347,667,942,516,806,482,986,420,838,458,427,981,249,486,986,552,169,528,480,68,757,29,4,60,990,414,770,291,19,509,568,467,61,960,425,319,923,741,78,29,68,90,107,262,618,632,126,839,954,640,779,1000,0,295,125,777,776,406,413,691,957,278,963,749,629,801,801,481,770,751,891,756,327,700,999,843,668,141,99,240,168,859,10,234,528,14,963,387,604,743,386,872,92,201,690,309,581,356,193,78,205,909,980,711,241,870,722,882,824,972,924,458,994,853,220,258,766,720,641,661,697,116,434,212,35,59,321,675,41,274,868,69,798,978,739,415,670,995,295,666,967,978,121,617,951,169,379,395,757,180,77,252,495,178,157,103,947,713,239,101,316,729,345,647,502,757,251,141,121,554,33,523,698,988,903,821,541,854,203,49,1000,526,428,95,741,79,944,46,227,444,531,811,968,787,469,447,653,189,263,311,699,371,531,430,754,26,585,677,739,927,151,757,773,63,487,277,669,710,938,92,723,671,194,422,834,500,482,760,521,397,661,760,451,995,870,677,121,320,671,39,992,282,732,527,855,316,928,671,762", "414,115,434,26,704,144,960,566,537,855,789,19,219,563,288,683,538,121,938,360,383,362,335,20,338,973,890,887,247,874,686,658,201,229,772,622,297,437,528,702,182,274,57,756,74,232,13,439,142,670,952,232,902,674,303,648,366,791,587,16,494,730,754,63,227,719,73,136,847,224,157,42,361,395,591,637,646,273,944,584,203,73,742,643,328,722,810,347,254,17,889,460,278,865,83,381,79,286,995,801,998,296,303,225,983,960,417,385,559,8,768,878,40,928,297,73,33,179,711,84,96,582,717,168,440,620,668,253,991,122,494,970,574,626,376,849,853,454,545,599,743,872,638,671,771,624,901,12,600,56,939,17,364,408,405,993,405,262,775,583,224,240,257,649,313,118,61,363,186,378,999,723,98,476,439,550,647,428,470,836,845,494,953,32,394,63,186,827,121,623,819,302,567,194,692,501,211,218,900,986,652,447,362,592,277,958,398,572,81,976,14,389,824,607,274,902,783,537,907,910,504,601,429,624,247,561,922,356,298,552,691,286,131,341,296,772,808,471,338,977,808,244,532,572,21,388,671,493,540,449,742,582,562,83,143,328,936,791,642,876,295,15,697,592,963,244,293,329,142,774,909,286,515,93,804,589,961,612,990,739,438,299,349,188,634,492,143,543,202,662,804,578,440,540,570,386,537,128,973,355,988,523,904,18,592,699,684,382,77,268,756,921,89,387,405,394,853,658,325,377,541,746,433,702,131,558,402,425,600,465,657,236,870,126,480,327,480,455,251,719,46,698,267,241,749,416,54,896,533,68,798,789,610,929,57,727,815,245,555,601,751,601,170,33,876,826,247,257,564,782,881,991,774,649,674,832,876,429,977,117,443,653,767,957,499,398,508,145,973,379,710,408,99,706,907,993,705,407,451,388,750,280,47,60,942,196,944,760,255,731,407,593,384,668,274,303,577,606,638,996,812,865,766,795,705,826,877,772,255,146,159,979,986,726,202,870,52,794,76,460,947,743,732,487,930,895,484,62,23,717,608,162,241,677,423,191,513,440,204,29,94,153,898,767,722,291,273,908,352,803,243,635,607,682,955,164,378,471,661,966,257,755,200,739,696,339,724,731,645,3,602,569,220,216,595,731,197,75,177,733,911,374,406,707,290,323,566,609,809,146,327,467,978,550,551,595,128,587,524,730,623,485,306,76,435,657,413,943,624,579,153,342,226,268,232,641,996,93,948,616,459,984,448,987,486,400,756,910,54,883,783,26,658,789,35,37,58,276,274,510,116,749,525,728,205,412,240,449,708,665,681,370,734,731,307,476,452,310,737,431,381,534,442,86,515,994,902,619,671,258,308,996,620,60,898,78,421,84,468,393,719,582,493,75,239,740,313,320,578,602,865,923,487,963,82,429,697,15,538,262,507,877,405,739,967,129,803,495,110,280,607,693,281,891,181,447,494,775,1000,402,774,15,623,251,737,989,900,615,747,231,204,103,325,532,585,298,497,498,161,788,568,394,777,14,826,58,839,688,185,338,870,873,809,50,176,439,218,582,754,766,646,537,387,739,736,813,164,76,126,120,167,895,55,180,291,143,215,478,255,942,541,575,660,29,350,5,924,593,396,670,943,201,865,2,296,376,877,663,373,721,706,816,428,862,299,107,429,756,855,456,917,219,232,92,337,118,710,118,518,55,888,734,292,338,728,918,414,794,665,550,207,225,948,316,734,999,567,619,230,55,54,313,932,296,219,56,892,407,98,637,67,10,335,629,894,793,543,709,501,685,356,52,819,430,626,245,169,239,800,247,717,72,698,412,897,6,648,258,892,566,642,31,144,295,0,798,514,326,574,37,923,675,863,663,168,687,89,815,673,44,797,102,509,963,520,621,149,947,889,519,590,413,287,363,15,464,69,541,843,63,791,624,624,728,793,85,970,570,206,771,520,707,262,627,581,84,204,554,48,113,684,62,804,365,279,954,816,758,579,677,559,159,810,888,545,129,802,750,177,74,966,801,26,45,994,355,23,262,737,210,675,186,417,944,732,178,760,301,867,618,562,559,183,842,430,151,261,945,380,143,854,505,178,798,273,91,781,108,730,264,929,438,239,145,400,727,210,83,79,717,78,172,771,383,695,36,662,587,24,674,161,154,194,486,279,611,118,331,307,554,765,201,710,375,752,362,278,704,177,513,847,661,173,692,70,347,548,131,333,630,517,40,140,430,860,190,656,482,873,492,104,846,236,806,994,657,467,299,224,727,714,713,355,304,496,85,529,407,63,991", "822,152,415,735,544,488,52,711,209,424,636,975,296,943,525,906,302,314,389,400,142,470,919,83,930,902,331,860,993,654,150,537,817,625,762,282,91,601,153,808,563,490,919,878,993,454,79,886,202,747,700,914,877,152,420,24,601,801,431,861,134,208,829,250,238,755,937,980,571,940,639,664,99,154,146,958,513,277,527,521,88,961,546,695,438,720,231,6,487,747,323,291,648,339,868,310,391,829,840,66,388,616,292,196,808,902,404,251,408,863,452,249,146,722,763,65,296,832,796,509,820,829,322,195,609,949,878,952,576,179,304,705,603,642,194,396,655,319,566,491,347,640,872,459,525,719,362,336,792,447,814,675,205,795,937,194,756,475,298,805,499,808,330,697,413,410,72,177,828,684,773,487,887,57,896,932,980,305,364,815,136,789,549,784,54,607,401,580,476,203,26,202,526,72,944,787,789,508,593,509,167,345,978,371,273,393,99,849,232,545,416,439,43,480,9,834,283,643,248,609,465,742,410,216,859,765,225,722,597,492,816,616,469,622,103,179,814,590,928,63,98,96,151,824,20,253,688,15,903,432,573,789,344,3,602,875,401,296,482,437,168,269,592,603,541,475,792,333,957,447,385,813,605,792,111,634,25,440,256,939,298,362,234,708,654,112,451,252,906,354,805,32,276,15,64,198,356,834,98,201,681,683,940,713,860,197,83,501,25,622,815,537,54,605,445,513,880,694,413,542,362,627,489,491,121,920,161,953,335,361,425,68,696,928,772,794,500,335,594,494,970,111,806,619,111,640,871,351,60,876,884,477,768,35,761,686,254,570,307,872,595,998,698,449,639,84,54,309,94,263,490,819,538,486,75,387,312,516,396,176,903,475,720,515,56,77,867,641,560,209,276,58,333,23,848,728,616,654,86,678,629,514,676,727,275,461,964,74,677,74,162,132,546,437,854,737,934,530,636,507,32,504,475,475,162,527,512,940,561,742,196,383,46,647,678,665,12,34,735,867,638,362,239,906,910,753,375,536,508,434,413,339,962,718,861,498,356,337,262,457,644,423,161,952,761,391,242,277,549,545,623,264,199,718,642,278,829,22,546,328,725,615,276,343,72,438,242,462,851,614,927,264,883,796,258,254,275,825,91,516,688,451,392,57,502,62,945,923,100,575,775,628,276,700,264,273,256,892,209,487,719,806,269,970,975,99,543,92,412,51,746,278,386,816,935,458,799,331,824,139,441,243,524,773,550,561,266,200,997,656,734,607,550,798,211,602,170,905,340,135,693,714,964,445,995,928,55,737,920,44,781,701,300,960,17,605,71,359,179,115,71,10,214,834,850,262,58,638,639,888,74,603,466,662,420,64,166,964,219,17,420,804,722,525,355,666,345,830,131,317,906,293,237,191,911,302,337,298,454,815,809,503,197,548,658,215,950,314,227,396,306,97,66,982,855,940,707,590,110,312,13,284,865,647,727,665,217,79,881,383,170,195,714,637,655,32,629,763,673,384,645,204,22,937,757,136,228,944,184,515,518,164,514,46,438,342,600,303,421,262,711,78,596,12,907,947,993,245,663,740,537,848,475,571,5,469,993,201,285,417,587,562,711,873,79,121,537,635,942,441,732,861,590,662,424,318,377,514,890,918,466,435,305,279,468,875,527,782,629,169,448,556,816,183,603,990,630,466,885,440,244,151,637,633,711,228,718,320,770,253,642,311,444,127,531,419,14,397,698,140,155,388,606,248,66,879,424,344,176,789,574,646,975,422,766,349,430,150,58,710,837,95,469,973,2,486,559,926,518,814,134,195,399,45,932,230,417,753,40,244,532,989,191,125,798,0,293,840,86,659,968,162,795,844,954,443,93,233,703,169,593,410,150,623,783,600,490,24,677,786,552,899,447,609,586,968,432,117,306,712,964,179,591,343,931,46,458,444,544,176,726,268,516,535,724,245,543,741,973,58,512,949,136,602,471,829,948,493,820,34,55,968,804,384,899,504,528,14,362,244,805,984,284,413,420,50,119,656,564,361,182,379,523,889,727,764,805,726,177,275,939,486,269,953,125,914,632,119,35,352,749,230,165,986,909,106,936,299,8,812,59,980,916,125,240,909,232,116,838,223,293,296,310,864,505,135,817,807,552,820,293,990,797,344,66,500,759,311,939,557,126,761,208,278,372,583,983,766,788,458,517,490,331,892,931,982,902,543,587,11,112,82,180,199,798,103,229,996,178,66,645,422,668,957,134,333,588,745,426,946,163,502,276,168,554,781,553,737,155,515", "625,722,280,95,462,270,415,801,209,872,585,336,231,830,488,121,53,756,774,792,262,254,733,823,45,51,622,897,781,983,443,881,535,459,324,96,430,4,58,991,245,377,885,122,633,41,821,563,852,607,498,982,762,641,343,517,119,550,881,818,390,645,402,635,813,306,588,740,94,321,882,690,692,43,268,449,697,538,63,670,737,546,196,972,351,634,839,957,800,967,902,900,94,352,587,98,59,257,243,701,550,334,64,633,578,806,540,104,732,594,767,175,518,322,235,918,272,844,170,626,50,650,660,415,624,980,290,444,341,757,781,319,771,768,864,998,517,273,192,665,684,204,26,257,238,508,180,466,167,324,867,278,681,801,935,510,774,810,968,462,740,510,110,55,687,370,180,521,907,903,291,181,656,688,880,436,729,774,830,407,232,977,633,220,536,782,70,975,56,69,639,979,598,212,532,766,847,891,35,296,541,26,845,757,658,759,643,800,822,507,646,176,651,995,22,83,70,476,864,398,778,190,50,104,800,97,811,181,171,614,299,495,940,70,645,863,558,772,216,333,649,539,179,1000,633,356,263,189,246,925,674,960,660,187,987,377,188,817,239,194,535,448,606,488,599,653,836,821,669,395,574,458,303,418,574,884,837,149,300,341,791,74,571,509,578,37,234,832,239,915,196,737,451,859,554,140,511,680,232,398,483,742,393,167,965,565,503,772,882,296,925,957,869,771,976,704,634,306,427,876,382,459,425,934,862,66,30,888,879,355,612,202,763,709,964,190,320,928,772,404,821,564,852,81,837,473,965,551,308,884,390,962,486,923,463,220,897,430,754,755,852,430,155,883,269,137,287,777,960,160,620,378,896,960,894,228,396,796,531,392,53,837,966,140,912,978,687,524,736,37,521,960,345,711,17,652,141,61,482,501,893,959,913,78,451,628,353,850,308,627,650,326,889,555,189,822,454,56,196,207,820,109,880,75,243,666,547,313,693,678,12,33,614,351,541,977,890,521,819,924,537,738,135,921,548,733,189,793,120,783,275,867,890,426,508,534,569,16,985,252,789,839,757,546,996,703,294,835,982,870,271,751,797,707,958,645,866,770,214,604,21,478,781,691,21,846,273,120,903,964,509,878,386,884,891,268,271,728,917,922,780,167,442,938,756,838,670,628,167,555,40,411,894,169,651,6,156,235,953,341,208,919,412,344,236,378,828,355,47,79,633,305,924,738,615,934,737,794,400,965,351,546,426,128,968,656,549,817,62,203,297,888,460,602,23,263,890,71,137,408,697,670,111,995,746,606,185,969,940,787,714,54,43,216,191,840,902,128,971,478,279,768,176,671,834,818,824,904,448,874,414,61,168,805,558,661,189,199,321,369,998,909,189,627,494,873,118,416,473,437,74,255,741,813,446,69,354,536,947,908,380,797,721,332,925,106,52,439,577,906,878,285,490,488,639,997,636,322,68,764,570,550,41,994,666,731,534,6,783,13,36,48,534,280,995,25,157,666,145,825,883,520,239,407,793,913,386,159,59,320,132,428,461,624,567,572,57,436,235,684,122,808,811,268,756,554,202,504,937,831,571,90,855,459,506,820,78,776,554,590,797,242,859,521,588,723,488,262,221,180,164,819,765,301,96,58,203,895,139,789,365,914,102,848,577,250,47,574,645,330,662,490,157,429,647,413,692,330,804,719,710,63,958,52,544,826,123,20,745,247,734,786,309,476,546,895,766,151,293,511,865,479,443,557,685,511,236,63,873,143,758,905,359,634,97,823,239,269,710,507,344,152,389,652,90,389,917,915,825,13,688,665,802,661,574,171,162,405,288,61,181,230,675,777,514,293,0,458,595,844,942,978,740,595,266,459,678,681,26,708,210,575,403,525,593,436,703,90,659,589,937,460,24,713,414,34,656,858,822,851,474,710,276,45,921,680,888,569,59,446,917,858,763,405,459,295,889,280,257,637,661,904,391,77,86,494,958,64,710,517,257,567,850,454,48,256,799,862,699,774,611,708,210,564,493,751,146,718,276,365,665,834,459,194,914,891,317,613,289,689,79,246,834,27,979,751,291,534,260,258,876,253,495,789,222,983,885,888,29,190,917,184,264,35,774,348,471,298,573,513,109,452,41,737,622,874,60,489,400,508,600,937,598,234,145,574,712,98,510,873,600,143,244,823,650,18,613,451,723,975,647,929,913,708,485,265,407,588,376,706,254,402,417,539,286,984,617,134,470,511,29,961,867,454,332,611,508,684,933,647,538,967,643,846,491,769,870,774,732,887", "147,948,83,549,593,187,810,425,175,918,570,147,919,587,357,716,385,116,744,899,782,261,880,29,373,541,241,275,536,489,83,956,913,301,819,605,452,407,674,13,930,217,56,10,764,435,455,929,783,349,946,548,220,521,163,250,977,870,830,688,748,380,255,670,755,788,685,253,2,827,426,705,752,148,893,584,562,521,497,669,489,189,61,745,835,507,200,724,590,65,322,803,530,548,670,689,612,275,592,515,495,141,621,600,555,577,71,946,804,760,106,890,409,68,809,649,948,410,785,463,263,881,640,340,24,814,522,327,971,338,757,608,197,621,928,673,851,185,581,78,378,910,120,501,285,690,283,235,649,518,942,394,608,992,836,926,975,648,314,526,875,750,164,290,949,833,848,801,842,70,285,844,564,261,122,873,142,650,309,423,477,291,715,974,203,642,896,458,275,585,954,943,224,735,539,745,247,298,416,330,907,976,357,118,376,7,743,60,611,887,745,635,69,758,987,191,701,815,492,300,360,858,617,568,390,847,245,637,658,376,971,175,27,985,44,760,655,962,669,598,433,702,884,144,361,671,793,427,258,852,708,15,120,371,153,893,932,367,349,31,834,871,630,811,109,930,974,233,329,389,353,443,66,885,588,192,147,895,2,939,954,130,390,166,790,530,951,484,323,645,76,62,338,362,490,261,562,906,521,455,177,358,229,978,497,352,528,670,459,160,925,442,292,492,201,9,996,351,465,200,742,394,632,549,319,438,190,168,646,579,20,314,567,913,819,69,147,989,369,284,857,895,719,885,901,435,48,912,159,546,645,545,964,249,908,469,190,385,207,992,245,262,882,93,914,953,115,214,597,511,667,315,637,925,829,592,3,892,523,950,411,166,90,381,237,166,352,818,902,279,837,656,576,590,612,450,422,909,239,431,867,743,138,796,466,317,310,178,787,125,950,560,73,353,244,794,907,269,877,208,157,835,392,963,721,230,684,297,548,930,193,458,270,755,791,106,933,662,405,648,596,972,354,482,770,191,863,672,464,250,150,752,132,376,762,283,385,547,788,220,455,532,580,903,797,421,41,856,291,591,349,223,644,785,126,472,231,52,624,317,723,161,573,517,558,465,498,624,222,80,537,960,958,46,796,465,305,391,804,159,720,127,571,835,361,966,404,368,218,636,586,339,955,52,448,109,104,902,300,115,395,861,235,918,1000,925,897,771,330,909,221,660,484,542,895,7,437,515,114,647,586,364,309,953,232,189,142,78,479,883,178,640,874,925,230,496,730,825,913,180,945,537,581,219,798,31,178,156,59,626,162,439,270,124,135,222,529,848,752,859,581,643,570,526,418,387,22,608,926,882,351,210,867,469,677,940,300,701,730,34,944,283,906,289,452,465,324,452,182,414,860,965,286,625,946,61,563,806,763,607,627,363,367,137,646,195,381,945,736,980,97,497,569,813,846,578,278,800,166,775,370,684,877,25,911,334,50,748,982,253,232,957,215,595,168,149,34,410,384,656,450,277,44,267,451,607,715,699,85,582,819,109,382,245,177,182,689,214,959,142,123,139,496,617,270,260,656,557,831,583,583,165,468,767,882,334,606,530,61,152,926,597,505,822,137,905,801,58,714,643,592,841,550,19,476,298,107,824,78,818,54,783,491,641,917,566,783,67,247,575,662,475,271,238,418,684,296,734,272,147,969,590,282,662,941,407,387,917,9,653,984,652,377,213,330,120,692,202,84,78,9,513,421,576,721,91,534,88,778,263,554,635,609,737,278,175,582,18,975,607,60,98,480,664,933,945,500,797,219,710,492,910,281,644,521,849,882,892,298,677,909,588,661,776,326,840,458,0,481,535,565,511,69,3,146,978,488,883,138,131,717,363,219,214,515,873,627,76,490,999,209,754,273,257,17,741,739,599,134,794,96,374,858,107,391,877,236,522,348,374,181,73,624,814,494,211,15,552,31,152,644,106,275,853,723,995,556,323,70,590,295,461,330,721,604,131,300,275,410,383,954,127,46,799,402,167,893,362,922,122,290,370,103,714,6,57,403,188,924,717,44,261,751,967,23,279,413,615,504,421,254,111,651,469,59,473,855,416,616,673,900,988,628,670,267,251,283,428,318,647,763,951,272,769,693,604,622,751,792,39,103,487,966,813,807,212,868,166,399,696,799,724,517,550,869,988,45,556,63,770,686,618,787,159,630,562,930,724,156,822,262,490,468,985,872,220,310,300,197,955,450,290,226,281,790,798,793,551,651,916,893,29,679,752,185,682,432,847,292,891", "210,318,405,702,295,147,85,70,10,643,294,654,943,55,280,168,191,121,208,372,112,507,21,744,16,100,155,370,759,168,749,980,910,533,845,440,651,468,97,110,169,76,231,297,96,898,624,472,624,867,295,934,170,958,67,469,286,816,380,914,430,550,137,135,297,249,331,290,523,15,24,785,773,619,877,478,109,369,624,106,73,767,123,627,908,813,578,234,628,575,774,770,19,567,779,794,655,995,92,767,844,431,461,443,615,263,927,386,225,509,693,488,555,810,420,866,385,177,947,254,185,402,487,406,956,563,224,407,534,241,432,4,104,94,564,663,451,35,491,217,292,454,879,497,41,72,875,346,772,710,800,157,474,840,398,804,682,57,347,236,854,833,578,307,647,648,203,673,970,32,737,445,185,984,306,934,302,410,17,477,761,710,880,758,397,431,761,64,328,267,630,586,969,878,814,648,546,181,410,289,879,815,113,747,424,28,707,51,309,506,580,381,273,262,488,433,965,256,784,913,842,548,404,643,16,554,692,110,289,950,81,136,894,182,837,533,692,479,921,396,401,109,315,653,767,46,66,96,430,441,361,94,358,446,701,322,125,773,805,312,1,275,566,314,456,136,892,584,577,979,492,469,857,930,183,117,132,750,255,872,551,309,697,169,136,350,258,732,577,207,419,637,243,365,786,811,405,766,760,153,160,504,487,714,244,889,752,907,266,302,86,800,300,394,670,433,741,541,621,474,763,822,540,354,486,128,751,356,872,559,561,239,609,834,739,338,325,805,344,610,482,231,135,763,218,272,94,160,491,110,94,429,846,553,52,763,570,374,719,987,878,709,752,192,682,650,703,571,811,219,158,542,820,929,634,301,29,558,637,647,664,216,572,778,347,239,564,932,317,733,296,94,547,277,18,53,468,567,854,980,457,166,246,826,777,527,665,915,997,236,334,415,216,60,659,743,814,512,650,500,889,999,752,280,477,689,560,76,596,365,983,533,847,100,97,230,732,178,527,935,347,784,286,305,579,273,139,529,795,712,281,858,141,107,900,58,733,986,700,974,891,8,877,28,447,788,303,573,698,477,289,744,805,872,91,627,488,256,625,317,306,736,542,244,259,294,401,82,48,468,452,172,24,248,790,266,59,257,433,93,568,365,26,597,498,475,293,664,923,364,353,461,191,513,69,588,864,895,412,100,202,535,374,327,631,319,786,978,963,39,775,564,214,910,831,218,760,27,502,419,828,681,297,493,715,289,339,958,708,932,386,643,242,741,204,184,173,502,866,988,478,608,849,873,375,235,815,594,6,244,469,229,508,407,170,955,89,169,946,764,564,303,535,155,372,660,771,221,978,203,902,24,672,777,521,496,514,313,652,493,956,914,273,868,43,348,578,618,831,62,394,673,577,254,258,703,748,931,256,764,728,29,367,614,191,394,706,25,935,946,490,281,881,884,605,323,442,346,315,738,307,877,224,868,537,4,899,104,596,494,254,91,957,868,183,229,538,119,182,638,86,54,184,119,151,698,680,953,480,880,824,147,470,383,164,80,500,197,119,495,640,159,84,657,510,720,752,314,187,967,166,796,842,338,869,208,872,8,306,302,77,842,436,339,972,465,224,367,991,300,397,986,825,288,528,220,971,709,405,170,697,748,308,480,557,441,536,622,946,113,264,549,642,371,798,362,817,42,448,132,173,650,714,200,404,548,675,228,772,19,390,196,767,433,114,442,15,866,393,259,926,240,519,32,620,503,463,790,989,186,385,435,484,570,298,855,947,154,13,600,154,54,257,119,675,88,446,236,420,416,312,936,810,34,930,649,460,225,359,829,354,876,59,406,574,86,595,481,0,679,679,315,281,545,548,229,377,486,827,78,282,716,510,886,41,308,521,986,200,878,67,46,91,310,724,527,458,88,371,57,239,695,735,212,897,486,241,693,838,708,230,987,193,357,584,971,476,834,449,894,797,73,255,401,681,251,849,447,236,683,544,783,194,386,746,173,566,41,574,243,230,622,314,146,908,367,688,3,825,287,662,295,996,484,190,791,380,532,427,65,45,467,805,349,221,143,404,328,630,270,238,986,213,393,12,486,244,830,340,646,378,363,485,489,111,137,594,23,410,723,458,586,169,107,649,645,959,123,505,258,961,133,542,828,776,609,56,143,589,611,641,543,637,68,481,154,287,370,914,565,719,942,747,186,220,296,593,533,177,918,873,393,872,875,435,86,70,124,531,24,905,81,660,612,476,632,887,106,645,351,698,528,527,535,218,991,904,143,166,81", "875,60,104,424,507,263,178,50,997,808,174,895,860,334,137,708,718,779,113,925,316,265,483,68,645,147,105,990,538,602,424,380,801,612,435,597,708,304,187,740,230,385,693,62,478,904,106,646,543,59,780,52,222,491,285,846,211,767,987,898,830,7,284,479,363,888,926,216,284,95,510,354,276,200,40,550,707,691,423,212,766,161,908,147,58,270,686,62,723,376,838,349,118,151,99,101,139,30,293,361,347,484,792,729,538,68,986,538,431,723,947,232,287,349,941,205,597,564,666,444,433,595,628,772,526,888,642,669,876,494,442,891,769,166,496,935,205,469,158,23,162,154,752,255,634,891,286,157,380,156,479,262,469,356,688,417,553,442,566,7,186,339,664,854,192,772,926,273,491,79,660,883,215,438,353,811,123,370,398,74,977,947,214,60,144,281,661,99,12,316,53,9,812,610,999,190,964,369,182,754,247,677,111,48,424,129,158,991,519,681,793,184,646,524,264,765,323,290,757,866,983,639,924,123,707,263,554,192,701,833,74,188,767,388,951,192,407,863,127,871,734,473,390,621,748,960,261,354,786,805,746,694,567,544,612,347,827,164,920,499,886,858,135,398,164,175,531,862,618,330,408,319,783,136,76,646,942,191,959,323,480,975,197,90,954,29,97,51,661,36,961,929,902,843,589,88,579,655,425,694,315,793,525,47,962,322,513,401,919,221,447,445,979,348,382,575,759,877,380,342,194,530,158,108,682,709,129,113,304,936,6,868,162,602,353,649,877,669,300,625,270,44,346,48,697,156,700,912,56,55,861,610,272,743,166,120,120,250,343,174,592,312,959,93,29,486,845,53,55,767,197,144,580,288,173,489,781,335,150,137,266,688,353,545,392,62,53,949,786,846,302,759,342,25,689,860,571,635,855,671,924,769,479,821,229,590,578,783,341,761,163,218,550,714,236,920,125,747,317,950,672,406,702,565,690,685,176,450,330,647,502,962,997,929,392,365,907,308,959,42,269,360,264,781,283,794,797,516,568,430,235,274,726,58,330,171,541,81,804,167,677,463,838,526,749,68,187,285,678,843,529,424,386,198,30,897,280,340,944,424,326,569,141,369,337,645,925,892,815,74,149,604,263,819,209,596,965,737,106,829,78,561,332,325,886,986,7,683,299,29,668,223,673,190,689,551,601,183,436,971,600,339,651,763,537,582,593,767,495,814,497,856,457,581,846,956,636,622,177,30,992,976,231,462,65,614,350,637,541,239,442,186,548,204,805,364,976,387,866,949,587,80,39,254,121,243,515,28,191,694,314,576,311,378,103,714,621,28,784,888,370,31,357,276,853,964,261,426,312,576,120,892,14,837,250,294,116,330,909,627,49,407,154,206,497,887,497,452,558,18,434,908,681,239,880,6,273,541,534,977,943,472,298,864,219,452,773,449,857,501,631,29,952,185,632,165,12,720,842,257,59,983,340,602,42,114,29,301,911,220,266,407,601,66,204,361,835,326,384,927,545,857,26,431,178,273,305,828,104,270,12,574,554,346,526,306,631,991,318,595,729,69,819,154,830,387,155,87,49,936,326,580,143,880,342,608,711,708,153,601,34,91,161,468,779,261,877,310,691,990,349,439,293,418,670,431,809,294,335,377,235,939,573,874,254,364,450,98,102,70,605,656,996,453,918,708,989,174,919,491,885,332,861,649,20,394,279,375,221,712,811,517,705,586,342,680,480,805,892,924,759,203,110,640,477,200,697,395,316,663,503,948,864,737,391,210,969,798,463,314,727,940,449,242,714,405,912,949,287,712,650,999,602,632,802,201,218,657,645,572,456,161,86,413,37,659,844,535,679,0,771,453,693,31,182,762,56,473,421,81,684,840,365,392,107,787,369,919,966,932,291,515,827,502,37,813,171,370,369,686,159,866,24,948,5,462,286,695,94,785,306,421,450,287,663,875,465,846,356,249,584,628,595,711,469,984,20,999,39,108,583,393,810,230,84,930,282,557,371,13,66,681,981,659,589,880,992,479,540,796,496,675,951,72,961,635,525,33,599,2,562,255,968,760,169,291,38,35,705,968,121,795,588,222,594,207,686,437,43,287,944,764,200,658,57,382,173,92,44,590,167,957,102,14,291,87,329,810,655,129,953,782,568,131,288,234,253,952,963,192,874,960,367,187,275,262,851,960,130,622,813,545,15,628,714,458,312,804,864,227,64,952,187,103,891,548,107,267,285,817,290,939,503,808,817,455,751,537,480,258,55,632,584,306,308,207,706,118,848,104", "778,973,197,479,389,664,937,711,640,577,692,748,999,762,829,933,833,768,196,721,36,475,187,444,934,307,789,775,994,462,905,845,296,695,483,961,274,399,648,440,649,559,565,255,980,233,901,866,261,665,378,300,446,669,868,557,694,749,234,937,941,348,638,846,18,83,418,882,207,638,536,211,317,683,747,872,11,267,150,58,199,164,346,3,189,457,141,139,302,695,539,1000,632,288,747,483,552,387,122,34,2,166,872,26,934,649,506,65,788,150,89,881,433,717,911,70,336,336,645,272,277,844,791,751,589,538,200,313,72,342,134,951,786,978,570,504,312,382,995,243,882,430,505,803,33,229,591,390,373,475,427,389,354,517,709,72,610,838,673,720,189,331,562,152,610,613,382,939,273,972,502,695,286,525,149,958,896,794,523,262,998,310,306,390,326,840,994,780,417,787,295,51,646,154,127,471,974,714,756,124,86,79,860,570,721,555,604,271,865,57,410,381,336,372,612,255,661,580,517,845,580,217,770,79,112,874,190,696,555,475,663,170,489,713,319,869,70,10,555,717,945,442,271,463,108,345,883,53,957,654,468,927,304,255,813,122,236,603,929,106,303,931,835,61,119,225,484,37,274,19,518,706,886,251,750,376,335,475,504,202,287,71,822,610,759,862,613,855,510,634,758,191,712,486,750,561,876,808,269,379,20,75,629,243,228,219,727,452,230,191,747,86,53,457,469,747,130,229,614,691,574,507,400,269,44,149,159,908,528,931,214,246,39,531,659,975,567,854,18,441,151,315,378,772,150,506,963,581,898,575,565,555,636,96,550,165,153,112,110,152,397,605,975,939,854,473,734,856,291,395,421,403,394,788,587,369,428,103,44,978,553,243,497,264,933,883,241,91,176,98,715,157,526,174,80,654,597,655,763,199,618,956,997,667,732,753,64,407,820,430,442,739,285,861,182,719,719,587,546,865,116,677,667,754,94,169,342,116,711,116,579,684,102,448,408,578,968,697,711,969,721,308,890,449,197,71,484,194,977,242,391,326,54,27,561,438,899,596,738,238,876,995,224,545,259,599,252,511,607,418,825,426,577,299,348,433,603,571,780,272,516,413,495,210,912,346,623,911,529,286,397,601,931,639,771,189,141,263,701,717,321,291,538,901,522,77,756,927,480,201,251,729,199,337,498,485,408,811,621,840,827,969,715,277,497,641,217,934,12,410,329,821,742,289,402,624,378,306,768,229,736,543,188,6,51,223,346,144,806,559,896,681,873,356,801,651,5,745,299,603,183,993,719,715,304,630,977,491,445,185,606,843,638,628,934,869,360,607,913,450,222,544,19,560,162,625,895,976,829,84,870,946,449,96,392,496,655,944,921,383,588,510,503,737,627,672,999,203,452,435,217,133,412,59,422,268,427,858,716,938,127,114,197,868,646,478,677,127,553,49,929,232,971,893,550,920,976,670,815,849,958,609,276,46,787,707,512,887,106,391,194,230,987,254,436,263,310,358,216,363,363,636,593,916,699,887,939,497,941,786,621,547,216,627,91,954,124,349,500,819,786,133,758,238,615,78,4,224,283,860,440,470,873,270,78,718,178,307,459,904,108,526,433,773,202,669,557,679,293,91,338,819,173,561,816,444,562,143,384,981,810,142,810,12,74,450,463,815,107,252,988,317,915,684,985,836,771,313,738,622,72,836,973,853,434,509,90,70,664,469,117,594,533,232,592,793,76,976,518,291,42,342,587,353,962,115,776,949,792,303,235,526,107,898,296,145,138,271,557,45,891,825,731,171,736,33,345,428,748,450,573,837,938,655,241,150,473,442,107,936,752,26,698,691,923,968,942,565,679,771,0,184,922,612,389,439,682,140,666,488,55,756,907,23,832,580,272,293,579,333,860,50,694,699,158,697,922,136,324,762,672,788,752,363,790,293,706,272,141,233,661,328,710,509,725,182,101,616,822,950,754,574,525,570,259,956,228,223,210,97,478,442,845,952,298,294,926,825,238,655,866,237,4,630,670,109,993,497,60,755,145,761,497,40,856,440,536,206,553,60,941,843,23,675,57,617,835,187,411,265,912,598,167,202,681,500,599,887,645,659,196,442,944,401,487,800,675,719,434,491,542,665,243,607,842,654,564,427,653,588,614,136,886,339,46,203,876,329,700,770,260,474,784,438,453,50,701,817,92,248,430,653,278,999,94,354,409,292,33,555,358,53,86,797,582,21,770,928,515,866,203,6,249,506,534,397,329,369,164,719,833,419,218,647,548,516,952,293,350,50", "175,239,213,674,530,695,760,828,328,723,54,3,258,122,280,669,537,898,357,496,148,246,653,575,330,10,319,824,249,732,532,988,166,962,302,959,821,650,646,991,381,789,974,747,92,121,432,15,333,491,898,277,318,351,402,672,765,381,955,908,768,277,816,724,37,369,57,566,392,77,530,63,629,944,454,212,547,999,156,204,532,571,798,362,129,788,80,150,118,836,131,477,931,507,115,29,384,552,674,232,667,292,786,46,684,312,789,471,835,986,399,724,376,44,88,892,639,546,833,323,616,64,633,525,85,57,230,361,517,349,296,853,262,416,864,41,504,16,776,318,202,474,807,843,700,231,378,493,954,616,153,170,202,724,723,229,52,922,915,956,353,580,352,641,357,207,671,144,403,756,697,826,431,423,695,116,604,500,601,790,323,381,820,553,64,3,894,575,788,152,998,717,394,718,355,887,565,410,387,77,554,185,956,299,484,41,863,628,409,14,458,751,377,442,910,329,713,116,21,777,357,250,634,237,908,846,191,162,344,306,446,121,15,319,937,253,580,729,399,50,229,145,491,367,991,641,89,890,368,599,817,599,875,252,658,75,927,845,433,200,655,511,393,657,202,282,586,299,788,709,914,727,232,72,610,809,206,513,818,369,973,559,532,426,199,115,324,621,382,50,471,60,796,135,791,802,148,228,814,76,725,924,891,521,337,190,315,268,236,597,503,42,379,613,352,782,436,138,237,575,393,322,52,230,155,578,611,606,920,130,156,818,401,290,3,763,604,21,668,558,547,629,342,658,535,626,152,512,653,294,793,958,177,835,736,375,698,322,926,154,166,300,647,741,437,50,984,140,615,636,437,271,748,634,191,223,476,891,43,286,835,452,173,876,795,72,956,16,671,896,185,822,679,306,232,962,234,506,978,723,93,270,881,67,298,411,981,548,232,791,866,705,26,552,127,959,972,552,855,977,193,270,1000,690,585,811,899,423,120,99,598,690,516,176,809,367,631,656,421,242,895,95,476,697,544,849,276,992,30,648,261,485,815,581,436,265,709,154,508,420,271,870,847,348,572,195,204,797,147,933,248,484,651,411,317,270,276,984,961,736,495,494,908,604,635,228,603,627,316,325,424,416,501,121,538,85,548,522,738,889,118,453,111,412,291,656,570,297,687,733,478,264,740,911,800,205,14,62,704,159,958,370,537,501,879,376,216,431,72,207,593,514,196,575,813,328,76,32,995,809,432,795,18,602,96,416,818,479,784,63,742,596,532,493,435,203,82,906,971,907,235,566,370,886,78,425,856,110,300,476,499,557,137,437,505,742,49,623,236,646,602,938,938,703,836,686,54,158,678,23,209,378,476,206,391,493,967,287,28,553,282,62,694,762,501,27,907,750,813,763,847,530,188,455,830,156,32,947,415,953,659,537,794,611,354,603,296,514,104,600,586,774,656,929,892,94,406,423,863,325,735,633,858,340,433,174,143,595,519,318,634,277,938,72,361,770,339,330,602,40,96,564,912,583,763,113,724,910,406,149,122,899,877,382,514,920,435,843,685,387,489,992,4,908,439,431,29,787,368,26,82,570,212,974,623,607,701,29,688,769,695,12,553,149,390,977,123,225,430,893,151,484,359,554,626,402,343,164,457,444,855,895,581,954,441,984,119,932,351,779,693,217,389,789,187,149,930,373,899,176,530,586,86,865,953,612,622,177,389,271,835,500,522,408,287,911,146,226,480,179,375,894,570,30,28,686,879,702,575,727,284,780,443,124,349,43,407,966,974,722,229,891,789,621,365,544,50,978,750,845,458,276,177,528,884,773,304,903,976,194,336,683,918,957,675,162,978,511,315,453,184,0,542,835,918,528,113,448,163,116,710,825,428,606,714,566,619,886,454,188,524,565,908,873,752,498,733,895,919,844,453,370,932,897,99,761,581,2,302,945,432,411,988,139,845,241,25,105,909,279,767,577,793,870,501,25,747,962,139,884,190,610,160,475,186,443,142,313,986,575,614,571,707,910,480,262,171,215,999,142,525,522,214,775,193,304,662,466,913,942,565,549,149,624,609,526,134,590,916,421,825,242,453,578,343,817,762,897,483,376,390,168,197,475,849,654,475,568,199,503,234,567,470,504,442,899,528,843,686,93,11,901,42,318,969,407,458,475,51,313,505,873,973,437,755,771,967,529,221,686,366,133,62,334,654,233,980,419,595,590,544,102,449,867,544,401,429,348,107,619,419,869,992,306,134,492,784,426,35,600,530,56,89,619,133,869,185,48,764,325", "388,488,852,86,650,592,98,727,917,31,25,638,119,419,511,338,936,821,404,820,319,879,38,442,796,494,144,239,653,656,507,406,188,34,754,625,780,889,856,448,796,673,852,425,493,130,793,355,215,544,23,135,940,833,896,428,346,250,33,473,590,247,399,732,142,662,760,600,545,764,445,870,483,394,362,245,272,330,144,829,249,463,89,422,559,734,996,973,865,669,408,48,921,443,870,473,941,991,651,568,631,417,67,938,129,991,832,621,225,974,161,405,644,957,925,557,40,385,277,580,651,2,133,892,554,99,420,954,84,476,320,577,259,501,176,308,920,990,392,256,549,58,486,266,63,359,98,607,38,604,727,227,770,250,931,893,153,900,335,924,359,493,570,150,873,279,806,880,950,761,899,30,36,807,834,147,355,369,495,860,444,74,304,286,421,937,585,702,14,784,15,241,114,871,326,919,621,243,968,680,995,578,395,780,174,770,783,222,657,215,613,573,244,395,800,937,77,139,144,756,255,275,686,965,400,41,666,104,433,970,383,41,543,402,228,466,505,385,365,804,673,266,772,614,274,589,827,508,991,66,120,319,627,226,754,337,989,350,57,430,335,329,795,189,560,813,204,389,359,947,300,328,338,174,208,496,228,709,22,580,488,173,891,815,34,735,602,630,503,631,669,385,140,899,650,350,534,815,494,261,565,816,622,488,909,228,362,141,841,629,161,353,844,122,379,921,548,935,855,258,688,278,21,371,138,5,587,426,232,547,5,98,944,959,231,336,29,170,538,274,236,20,830,542,547,193,661,667,681,686,297,237,504,887,186,373,717,755,478,277,168,734,40,433,96,934,708,626,480,477,563,167,575,573,875,801,782,259,171,221,380,20,38,223,392,115,624,601,812,8,448,415,776,956,158,372,219,124,979,785,248,620,497,815,269,551,335,560,830,558,36,357,71,111,902,172,876,66,550,168,663,271,308,302,6,15,715,406,720,478,955,965,551,711,911,934,650,498,176,893,785,541,443,606,329,518,218,579,472,439,152,110,200,568,743,498,514,455,343,850,708,278,649,310,778,629,696,435,128,909,511,245,31,584,523,830,447,700,865,112,801,586,316,117,886,402,98,848,292,436,843,279,311,816,501,758,118,438,833,8,699,672,516,109,208,742,89,523,711,129,5,424,356,290,189,420,55,581,268,322,505,15,991,730,11,639,205,873,42,967,747,128,92,365,605,19,21,556,753,264,282,98,898,290,371,207,566,693,164,656,269,669,949,642,528,823,645,102,71,166,186,51,604,857,48,872,934,267,388,259,934,26,533,273,858,520,588,371,3,861,655,108,758,605,348,281,552,651,377,861,136,620,468,387,462,207,672,380,144,859,468,170,562,778,905,904,974,441,357,816,26,67,35,901,348,3,373,486,373,169,582,368,773,720,150,808,649,320,212,415,727,788,416,370,795,566,421,248,656,658,231,611,585,771,396,738,128,114,365,803,532,933,611,582,532,556,715,436,279,710,763,653,754,977,329,613,804,784,841,955,213,709,98,377,833,607,411,71,627,894,664,839,258,488,2,39,151,908,735,725,204,169,2,757,316,578,115,821,306,875,346,124,420,912,686,895,149,131,888,635,462,677,918,636,979,471,397,697,742,500,261,559,503,432,221,474,591,429,533,806,522,657,676,915,840,971,7,184,47,971,722,391,711,742,304,339,247,29,331,377,55,83,76,182,9,322,738,973,301,720,746,428,706,382,504,601,620,51,427,18,423,677,327,249,946,773,513,92,897,737,582,182,721,878,904,418,692,320,801,824,993,671,4,423,416,761,156,663,744,581,677,653,937,278,863,795,740,69,281,693,922,542,0,891,601,76,780,307,299,627,584,703,211,108,817,615,932,236,927,444,716,703,207,705,877,181,405,248,772,855,995,746,361,712,450,54,826,885,877,464,576,645,987,565,585,89,262,895,100,41,320,696,57,43,928,573,517,627,360,76,970,240,404,499,778,695,886,26,531,262,487,971,240,971,827,435,998,755,785,404,631,599,857,120,79,293,939,87,24,267,960,863,756,393,422,760,166,567,131,745,166,948,49,708,230,183,103,948,848,657,641,409,910,28,917,494,412,760,744,186,820,774,572,112,567,675,326,228,686,317,432,837,376,116,274,895,787,310,403,7,647,511,401,187,909,851,854,783,185,968,207,726,83,723,873,213,903,10,481,658,342,280,168,101,396,378,786,889,370,55,452,803,187,681,553,312,236,971,252,479,842,361,963,65,158,230,550,965,994,650", "671,813,907,978,938,990,193,395,698,871,298,648,88,574,436,236,56,443,530,173,266,306,33,25,250,651,690,775,353,401,174,494,178,566,82,706,673,228,555,584,56,377,603,824,262,333,302,568,871,428,128,737,956,353,506,77,819,444,825,571,118,384,256,75,207,79,825,21,961,443,875,217,338,418,366,615,401,340,435,23,855,572,854,401,704,187,615,975,37,602,653,754,908,996,169,291,742,551,697,35,379,964,6,688,294,752,795,947,831,952,550,352,374,268,630,661,308,5,7,26,159,623,965,938,442,592,658,706,272,584,501,516,947,738,776,625,498,931,762,346,554,144,713,496,439,305,49,561,635,905,136,505,667,704,508,635,455,215,293,880,182,958,707,946,87,144,855,515,394,664,781,217,307,773,541,565,853,841,395,302,899,202,633,341,15,529,325,250,123,891,355,570,368,915,979,585,331,801,166,321,859,478,878,266,764,861,583,701,786,848,562,493,825,902,922,574,49,150,11,552,852,305,957,370,698,308,907,430,207,429,970,692,393,990,384,88,314,286,313,693,356,2,889,808,327,397,454,359,933,174,216,621,825,230,217,892,458,113,113,97,439,298,44,919,47,933,546,968,838,487,550,216,676,354,385,934,705,409,112,52,394,535,671,89,300,955,770,844,488,33,461,814,440,749,699,841,944,186,263,701,285,173,155,441,132,851,882,643,259,796,551,14,996,422,276,529,95,794,25,933,854,507,951,123,605,456,296,607,474,812,710,473,988,149,46,162,189,209,145,637,669,402,641,736,258,863,874,672,750,380,719,987,463,644,124,231,517,245,137,42,431,677,693,370,429,270,26,153,68,133,897,187,391,355,416,637,682,400,479,423,845,751,661,170,925,682,786,223,569,765,939,657,770,606,735,48,792,995,389,905,923,319,21,301,864,305,981,157,214,66,522,574,777,231,40,840,610,242,456,98,38,636,657,192,543,869,93,137,741,673,397,96,862,727,934,444,418,218,169,347,914,747,850,539,271,569,80,476,271,798,925,839,602,666,864,21,507,307,737,768,742,94,391,273,544,359,137,710,304,732,587,332,303,925,694,402,122,473,12,40,523,902,528,377,79,316,319,431,321,867,776,549,79,3,767,396,102,298,961,849,580,290,864,105,453,144,755,474,729,108,367,225,853,179,353,364,150,557,58,729,952,932,536,968,121,547,833,913,822,352,528,850,789,434,453,77,506,946,445,281,965,366,979,873,335,899,115,365,348,799,33,754,607,210,884,595,722,423,724,797,247,163,299,359,707,68,796,370,254,547,842,910,836,80,778,70,322,490,588,648,548,201,975,361,41,743,641,963,34,281,568,611,753,546,328,16,338,427,522,116,946,705,331,944,767,236,387,833,636,814,119,795,382,867,722,661,596,313,414,881,61,459,36,927,628,671,753,164,276,864,386,262,922,334,9,917,664,783,747,884,700,303,193,75,545,510,239,906,206,639,131,723,229,949,181,512,229,277,633,74,941,610,743,125,744,886,318,768,733,576,801,168,883,515,983,729,160,250,484,795,718,639,912,719,742,358,850,444,752,384,984,819,317,819,131,263,855,610,316,343,758,417,161,104,942,88,564,700,589,248,437,302,94,770,548,12,278,176,698,903,964,594,799,629,219,850,832,191,875,858,679,379,609,59,130,998,606,961,274,888,367,450,452,930,611,992,44,738,211,285,399,79,82,437,841,380,728,377,798,679,160,467,893,198,676,608,614,651,101,918,447,890,4,579,134,436,463,502,282,114,769,518,837,733,191,73,771,977,440,896,411,573,708,117,558,647,794,974,178,281,773,154,796,963,663,844,595,3,545,31,612,835,891,0,180,713,60,292,861,211,875,367,83,467,224,585,974,953,817,55,655,978,547,436,559,72,881,602,166,588,885,997,698,921,438,756,982,719,160,125,214,143,535,338,50,754,207,920,63,21,567,942,818,686,242,609,316,569,178,145,226,165,61,35,381,680,732,272,361,702,68,111,881,450,655,664,119,192,435,592,828,665,325,952,991,98,158,872,660,441,718,507,659,882,29,466,633,641,894,898,544,314,658,880,277,601,151,710,676,788,985,486,357,158,831,340,708,821,702,565,857,495,970,372,969,789,201,429,876,493,436,265,630,901,840,447,292,272,363,119,2,272,628,953,124,451,838,478,127,245,675,693,732,483,553,792,946,259,211,227,788,906,613,902,220,411,966,198,962,721,112,989,719,974,693,288,38,245,205,670,381,858,988,993,485,899,281,977,470,806", "762,322,357,189,349,950,574,233,909,427,54,498,845,719,749,216,501,653,120,352,461,104,338,706,306,825,217,726,485,204,679,170,237,205,989,963,499,325,669,173,814,957,87,611,128,713,933,42,782,813,946,78,662,979,414,288,346,675,88,59,477,375,314,11,554,710,471,953,353,164,407,461,232,201,249,279,410,94,820,589,314,990,947,281,149,957,38,207,200,682,114,527,16,748,505,370,380,983,837,615,901,460,302,288,490,856,923,232,795,192,426,260,311,763,882,865,138,454,676,213,222,68,811,289,62,412,570,429,824,156,983,267,785,162,143,158,416,192,343,518,145,572,386,22,413,716,557,796,772,502,132,794,348,373,115,783,36,392,907,758,704,815,170,460,293,930,536,737,263,793,736,486,348,390,757,909,706,632,284,805,657,944,311,361,196,256,149,579,958,435,362,66,521,996,646,713,936,105,483,624,803,9,77,128,815,596,248,234,508,434,196,338,321,421,299,874,107,343,171,66,39,176,460,232,312,785,538,111,469,650,744,400,803,307,395,726,148,689,396,451,631,930,282,299,834,865,679,607,927,372,327,4,291,932,752,28,216,112,889,484,516,739,640,481,289,966,523,766,194,404,722,862,438,952,892,32,738,260,110,254,727,65,504,336,671,905,958,108,45,984,606,284,914,692,907,683,220,834,448,884,487,805,38,577,798,744,119,623,323,120,802,837,823,101,376,936,230,788,852,291,307,936,18,430,444,72,842,353,897,223,145,815,524,121,40,47,957,927,549,504,959,316,36,90,30,112,54,362,762,140,558,936,495,304,672,808,746,364,527,899,115,93,946,23,568,725,69,545,158,913,265,625,545,224,270,907,934,454,588,28,684,609,677,785,349,800,596,957,152,611,548,272,209,430,220,66,212,385,793,674,47,795,201,636,87,921,65,425,322,681,539,680,111,782,12,715,608,846,347,155,281,801,342,933,405,291,24,43,630,923,741,971,565,335,209,695,367,569,809,249,110,311,698,727,211,230,484,571,495,932,331,100,230,255,896,42,710,624,497,531,158,461,176,707,162,74,891,386,365,270,724,883,715,177,324,980,984,961,335,12,253,597,472,294,235,430,374,711,537,640,879,949,355,781,294,925,751,938,398,183,835,631,196,310,506,427,183,730,441,216,675,380,881,242,53,721,607,928,890,319,314,519,41,468,884,310,109,444,509,663,455,420,776,793,432,682,788,539,692,255,120,507,654,483,452,591,708,206,370,542,796,169,60,105,965,336,690,968,220,502,655,187,607,263,139,588,773,168,454,452,673,184,614,55,366,456,647,52,116,802,78,574,403,606,824,334,931,78,792,63,980,590,135,939,978,873,478,410,86,371,787,117,683,673,30,116,961,996,48,556,796,127,942,307,980,795,730,624,245,886,4,40,449,76,698,477,757,688,915,236,787,398,908,802,612,462,112,575,519,736,859,65,892,422,540,891,761,29,379,654,899,35,533,729,244,292,735,63,747,736,166,571,30,343,134,696,172,461,452,849,863,516,280,580,584,481,176,982,571,888,242,466,70,507,824,428,841,165,244,523,518,379,807,184,474,410,974,718,732,478,601,552,848,193,482,292,612,589,876,892,270,981,350,464,156,465,967,391,894,308,682,844,312,61,893,854,152,448,524,963,20,940,462,101,267,353,269,181,410,804,920,907,911,309,415,730,552,379,110,512,458,185,777,479,699,208,468,671,650,80,947,374,478,500,761,826,706,493,353,684,617,624,334,100,359,417,51,382,648,935,889,713,966,614,387,874,923,798,556,770,160,261,341,247,135,660,557,796,656,386,605,770,367,749,168,954,266,146,548,182,389,918,601,180,0,303,489,118,163,206,92,544,26,543,78,646,69,660,242,854,896,692,539,276,910,72,164,622,485,827,159,212,204,729,395,69,219,404,763,770,786,779,73,296,416,374,982,571,493,181,825,780,160,978,824,679,680,710,75,154,557,307,834,465,30,72,752,108,116,643,501,265,295,74,154,73,731,366,316,987,741,237,418,463,728,948,236,371,213,951,841,377,159,401,221,804,819,324,900,578,502,421,271,832,479,493,647,896,732,235,963,976,228,219,736,500,795,901,577,914,400,646,786,444,878,214,555,778,469,49,616,788,957,926,954,609,836,646,84,461,435,345,172,313,48,468,219,866,321,410,159,97,715,469,463,811,563,791,937,727,616,890,573,454,639,516,542,63,845,39,499,250,205,150,605,213,456,952,234,652,518,188,662,55,525,892,978,443,586,425", "352,616,4,763,42,790,301,692,565,86,905,718,319,479,218,679,143,884,110,605,32,424,436,515,788,399,271,979,575,93,699,556,722,44,574,969,159,44,269,437,832,517,573,14,635,483,787,723,448,582,296,691,729,205,61,294,442,397,400,205,278,931,62,743,930,102,308,933,889,658,292,111,837,855,376,662,11,342,123,206,780,833,877,739,279,229,463,733,913,570,324,336,995,843,246,108,584,694,823,284,974,353,491,212,545,532,455,210,846,869,948,561,919,109,997,527,909,679,114,895,910,783,947,944,14,519,980,680,947,446,304,647,614,207,713,714,440,724,910,879,606,21,221,416,564,673,95,455,609,621,914,743,728,953,266,713,364,962,896,840,272,200,859,147,886,27,232,206,896,405,166,307,805,123,121,661,826,50,426,522,224,300,698,121,772,54,281,222,405,766,793,381,954,857,650,656,433,219,224,697,664,213,294,169,754,755,425,11,860,419,788,661,777,69,151,482,954,195,754,155,262,650,267,222,170,921,805,993,294,13,536,697,713,298,317,208,190,172,742,213,210,966,285,801,731,264,701,887,539,904,908,844,500,110,970,677,644,234,858,598,487,801,949,907,967,155,716,670,114,117,932,759,79,574,770,435,50,863,547,731,82,465,610,386,850,862,725,739,440,601,646,41,704,401,735,887,785,333,703,46,816,642,270,266,914,973,330,749,964,210,525,771,421,115,408,166,982,478,301,945,236,343,783,574,832,43,744,266,910,178,951,655,683,650,662,821,526,939,646,666,633,820,561,41,975,381,240,211,369,430,766,221,928,892,960,122,675,570,378,600,667,967,393,427,578,432,276,612,811,591,843,504,725,485,385,672,411,485,914,175,482,390,417,457,682,934,935,76,12,655,910,175,208,112,763,645,397,199,168,195,177,263,111,38,979,695,425,171,977,157,445,565,808,448,283,664,73,833,745,611,565,498,61,419,866,109,59,100,953,291,410,884,966,260,640,473,818,583,718,441,579,751,644,513,468,662,625,751,74,518,429,412,623,677,222,22,931,600,767,399,656,285,2,629,571,754,481,680,135,708,656,425,191,569,236,18,929,576,580,591,684,186,175,157,457,812,541,561,358,137,613,791,670,664,960,87,175,119,598,404,806,738,644,98,553,738,132,274,45,843,942,285,865,108,979,178,437,382,86,924,192,300,886,895,831,202,330,136,913,835,336,576,138,868,327,356,646,107,987,466,171,773,954,435,508,724,970,26,570,682,208,866,834,905,4,231,266,865,2,20,496,768,811,20,108,561,113,943,395,799,673,976,789,470,280,10,22,967,155,496,361,82,874,309,795,608,839,649,508,733,270,10,663,195,663,744,442,879,931,280,391,948,104,817,692,693,111,208,338,302,510,813,375,590,382,559,840,564,171,247,797,573,99,550,854,897,836,656,951,753,490,160,785,768,745,664,185,167,790,670,607,906,204,534,465,124,694,600,872,537,611,195,916,67,957,757,578,75,354,300,467,890,495,368,105,430,911,432,684,286,813,9,993,181,91,317,844,663,369,469,807,935,383,435,647,16,869,839,738,331,971,491,620,341,874,7,938,179,327,244,653,394,277,653,462,556,348,742,245,999,978,128,227,858,689,831,361,400,757,155,360,315,80,109,175,754,73,430,663,303,754,153,940,649,995,656,952,476,260,717,498,102,494,153,968,294,543,314,845,239,547,22,151,579,373,914,26,174,939,250,278,164,519,417,556,222,326,321,719,235,724,817,944,166,837,251,671,222,4,753,350,823,861,504,146,321,823,306,974,979,565,633,224,302,131,793,270,535,283,353,251,140,175,629,687,443,459,978,229,762,439,528,76,713,303,0,862,310,968,94,694,474,906,89,310,39,567,37,181,315,996,375,105,141,954,870,149,771,159,538,322,41,370,621,394,511,536,462,592,575,337,491,325,48,113,981,482,503,799,791,461,391,592,334,257,322,489,219,157,659,856,490,684,921,649,347,58,784,738,121,79,731,571,429,781,45,207,238,607,17,678,309,467,550,563,290,345,184,939,103,580,701,333,799,192,722,471,957,697,141,39,432,867,534,617,151,409,747,171,667,798,600,414,548,283,830,718,571,343,222,753,512,164,692,564,197,151,250,381,320,243,121,249,377,499,461,727,53,369,683,372,20,611,543,119,517,983,236,656,934,313,720,707,519,969,159,746,710,669,382,622,641,947,954,725,913,977,162,561,647,38,372,722,758,973,571,677,954,130,864,315,446,223,63,90,510,247,525,906,259", "550,336,99,34,308,235,863,640,837,145,895,101,63,422,697,913,540,768,640,513,2,186,336,126,313,93,180,914,367,466,592,479,895,402,1,827,309,917,158,533,468,866,419,309,429,452,807,171,860,653,526,249,324,731,48,818,36,816,502,401,896,270,609,254,262,823,868,613,599,142,892,868,59,549,933,190,275,717,819,321,451,365,985,928,882,457,183,765,377,834,60,74,664,54,610,411,523,923,355,654,747,262,951,356,96,39,781,718,105,81,827,296,93,960,27,749,323,283,493,37,928,699,107,342,271,120,152,88,879,142,768,292,11,12,101,804,101,659,890,461,785,426,312,920,441,121,114,633,798,735,659,679,901,931,434,344,258,877,592,61,446,226,289,549,932,808,943,731,889,196,266,396,594,107,572,245,221,357,861,937,928,259,16,727,709,647,677,387,553,757,130,9,400,974,862,283,601,534,636,97,692,33,338,779,244,812,832,348,373,844,648,527,712,289,544,941,878,55,340,314,256,866,835,650,973,733,939,265,156,16,75,539,390,412,877,208,303,438,157,175,743,947,412,929,489,627,969,341,136,543,256,703,26,996,874,35,306,908,763,641,785,501,837,450,203,190,955,533,125,913,341,50,681,139,284,274,149,863,350,422,87,696,283,525,747,749,505,99,341,503,117,871,344,854,642,98,663,136,103,135,464,885,410,209,277,811,20,799,978,166,148,66,508,403,880,828,123,996,98,703,229,759,329,896,342,286,138,150,458,909,32,419,658,370,464,325,475,644,938,479,690,290,56,218,367,664,479,93,260,812,562,744,925,206,602,264,772,681,256,418,555,90,811,853,768,966,658,250,173,169,300,823,792,353,811,190,41,654,185,574,649,14,631,441,5,854,530,535,331,63,860,974,11,110,634,247,902,549,51,118,991,141,150,46,902,428,518,226,635,246,66,192,454,274,57,41,148,208,745,406,504,116,364,146,802,294,611,263,367,342,298,779,827,95,702,602,453,57,200,589,929,407,277,742,574,769,116,536,134,636,917,687,328,694,817,306,548,178,265,616,153,846,31,946,38,159,71,724,260,483,349,698,85,458,785,919,761,280,196,747,211,309,230,702,944,349,280,808,997,39,448,972,869,818,521,362,798,265,109,197,333,445,725,798,495,720,822,892,590,987,869,434,824,626,899,549,277,563,885,369,977,656,243,10,411,235,388,828,331,397,325,208,436,871,928,214,23,805,746,305,114,997,893,727,267,636,375,775,170,6,625,720,207,218,375,241,713,634,316,81,863,307,557,617,338,518,818,965,651,385,713,216,980,190,520,721,578,648,250,275,482,504,609,467,829,497,102,579,661,105,146,963,275,305,864,555,426,675,756,690,218,891,646,874,92,419,417,466,710,903,486,62,638,193,900,892,521,343,677,968,397,136,323,136,156,388,791,378,759,951,555,471,133,791,518,736,783,312,302,394,9,840,762,329,599,468,484,392,550,489,244,744,304,284,167,793,154,532,814,799,798,975,794,937,45,999,150,134,186,644,733,920,571,115,408,141,674,575,58,742,997,437,889,731,767,114,875,405,261,939,29,574,677,326,175,933,8,481,927,712,6,553,627,257,768,43,414,474,568,548,620,174,497,294,271,899,717,141,806,137,99,76,944,490,388,801,622,501,841,659,675,249,701,639,275,548,101,311,127,729,779,914,661,972,128,950,298,570,714,372,757,433,970,497,612,440,502,614,98,331,912,363,326,350,142,167,213,899,900,184,465,926,395,730,805,290,482,989,163,705,492,553,919,611,884,724,304,568,780,261,493,891,452,546,624,304,396,977,979,990,108,331,666,801,89,93,678,488,377,56,682,113,780,60,489,862,0,837,960,79,474,365,337,111,856,31,304,390,228,550,63,310,77,886,745,616,389,152,366,474,154,367,263,530,378,417,311,723,868,547,501,181,694,702,772,667,44,60,271,65,843,901,683,760,439,914,546,359,141,879,716,792,941,73,139,856,472,693,203,365,195,148,788,215,553,58,784,853,799,909,123,147,833,444,475,412,844,752,350,76,468,463,871,318,470,455,230,553,418,647,174,8,751,968,553,479,299,873,680,733,46,900,658,574,664,668,149,570,464,834,479,309,675,593,159,941,831,198,328,197,240,800,79,544,984,384,290,914,825,955,439,307,513,352,38,772,910,904,674,962,158,618,528,20,898,67,379,255,66,454,948,729,978,295,331,854,910,326,832,784,140,459,357,252,572,48,613,525,151,454,270,861,469,406,319,339,379,370,599,61", "496,241,969,950,910,528,431,934,908,468,926,546,235,194,401,311,971,58,514,804,235,240,603,46,161,124,732,890,268,14,630,482,15,828,811,488,701,416,933,180,196,544,750,961,517,663,627,750,191,926,540,291,528,245,202,626,62,245,645,940,500,608,621,350,601,577,317,108,557,252,709,422,566,452,51,819,299,557,356,872,994,714,268,70,430,721,166,843,119,198,815,217,27,591,216,567,822,805,835,94,721,59,77,147,567,321,360,586,106,630,434,908,783,374,594,154,278,542,234,77,185,160,496,450,440,706,314,124,477,798,551,89,978,984,86,897,976,322,501,854,399,448,886,457,514,645,851,788,58,671,871,195,492,871,627,901,109,564,104,224,964,471,582,221,467,52,850,694,312,763,222,556,947,779,518,128,453,82,881,725,780,885,989,920,171,627,230,246,837,62,853,50,807,454,8,971,514,963,40,72,897,679,31,208,847,402,549,372,554,993,813,444,722,448,817,725,90,728,460,716,598,990,874,700,592,154,378,987,639,66,381,599,890,382,857,826,902,681,237,111,774,70,253,697,358,399,470,341,171,164,141,927,366,737,409,70,286,879,305,386,607,622,58,71,368,519,831,515,730,666,288,446,424,276,678,663,878,369,787,247,161,594,437,677,462,372,263,923,778,224,342,648,857,12,505,65,59,187,921,850,161,242,706,458,239,959,256,211,876,437,532,1,148,431,442,587,253,849,511,769,441,520,359,637,222,979,278,319,493,17,555,93,291,72,75,22,921,525,655,315,590,329,23,339,265,518,251,826,162,812,727,103,41,36,786,867,445,550,103,177,995,31,693,879,633,407,619,763,723,937,185,189,301,583,554,32,42,685,20,695,992,941,294,940,446,173,85,812,223,36,478,718,947,811,687,18,952,712,859,943,238,483,111,939,395,590,373,807,926,106,127,103,170,19,215,868,774,22,205,182,306,709,560,603,94,993,889,130,711,469,799,655,686,523,752,953,135,319,31,53,124,134,406,135,45,20,53,817,608,984,494,447,566,688,457,909,111,217,725,996,59,875,892,81,244,840,775,108,425,732,742,728,522,850,184,461,446,303,20,762,7,980,604,832,804,714,356,309,441,263,669,592,53,4,657,540,561,723,211,575,961,29,834,262,363,97,39,975,300,902,66,977,715,748,891,977,180,395,9,453,525,984,25,796,514,620,135,572,792,135,694,346,17,219,615,197,828,876,7,220,347,425,85,104,923,438,590,832,194,942,61,922,556,744,985,811,730,380,492,236,746,777,221,64,329,898,540,471,171,615,681,79,934,87,996,90,149,620,87,373,479,542,131,197,416,771,613,684,205,407,420,426,871,689,666,791,499,872,714,528,86,544,386,430,71,899,62,976,77,956,762,965,338,955,228,449,208,833,272,327,380,254,401,619,733,317,697,71,575,615,553,923,477,781,238,207,954,612,69,371,589,794,896,729,596,582,235,406,908,865,212,861,225,392,280,520,709,517,230,196,24,184,557,141,578,84,278,103,583,322,169,139,932,599,801,717,73,472,273,958,96,217,305,109,751,511,236,727,848,934,555,53,414,387,801,254,484,339,491,792,27,887,473,695,950,781,650,305,417,221,469,319,99,115,878,183,782,242,363,125,517,689,542,557,868,708,844,629,826,247,952,598,958,269,566,529,148,710,992,220,137,142,542,182,265,809,233,911,563,96,970,939,870,911,121,989,814,377,101,445,509,456,467,617,265,870,149,791,285,604,12,224,884,590,97,861,379,148,67,5,204,280,169,230,671,791,430,629,99,572,780,419,109,452,670,659,771,673,518,459,967,622,97,801,815,233,681,883,486,473,140,448,307,292,118,310,837,0,680,532,879,631,861,242,314,239,866,26,81,196,991,67,895,558,644,817,603,216,488,354,496,996,234,349,353,551,229,579,536,460,559,666,918,106,49,473,491,293,8,727,259,943,390,716,133,792,510,838,623,768,43,345,605,432,20,476,869,525,179,86,220,508,680,318,614,649,902,260,39,608,800,621,813,321,650,167,484,735,807,170,844,302,993,905,472,847,410,675,381,523,140,643,199,826,162,225,535,915,755,96,946,687,514,255,586,299,631,87,858,403,571,989,285,525,727,838,632,927,558,178,416,485,959,676,942,990,445,649,929,613,285,434,553,505,477,877,312,627,275,144,377,249,359,885,404,192,945,636,506,207,25,179,770,348,367,299,64,957,363,236,28,868,755,282,166,276,102,295,599,120,478,251,199,822,186,22,38,48,29,274", "82,957,116,927,587,992,611,642,967,338,348,786,23,395,525,307,45,40,720,463,128,278,555,489,252,450,786,822,620,59,255,437,954,502,933,450,394,690,451,951,519,749,797,572,299,449,998,666,783,53,248,639,804,44,817,907,234,323,940,866,737,592,608,498,812,921,481,847,533,336,176,581,455,191,208,29,685,911,466,183,537,717,457,601,484,749,433,223,935,134,758,637,555,326,831,691,145,185,424,979,873,668,321,396,40,848,788,489,827,94,118,956,564,209,169,787,339,309,743,240,121,154,23,207,548,217,455,467,548,667,856,106,375,806,412,392,934,70,439,138,769,581,763,918,10,846,819,77,231,392,407,48,69,275,777,958,524,924,150,194,757,56,28,255,540,395,488,999,985,534,767,293,714,1,310,708,764,420,299,951,833,617,259,460,477,696,614,211,116,925,820,403,736,87,609,800,56,110,943,324,116,512,735,679,457,227,24,644,949,824,378,227,128,456,831,866,624,86,763,203,80,921,491,847,396,581,26,119,108,204,940,832,110,974,369,134,673,8,718,634,870,164,415,322,583,624,473,999,685,901,110,733,768,770,570,308,746,67,246,781,298,928,879,90,371,7,582,363,616,471,681,47,819,949,345,246,917,670,445,887,919,377,626,771,133,161,626,969,707,928,842,184,916,148,382,494,442,895,935,343,387,243,459,719,691,229,596,71,622,765,461,538,707,815,482,904,27,226,172,695,925,93,666,192,965,566,677,93,343,483,287,645,504,389,559,315,453,970,954,396,66,146,134,425,718,806,621,160,25,455,978,159,795,427,290,859,447,355,692,411,665,613,570,928,953,305,368,708,49,4,180,95,747,683,578,763,750,4,850,811,493,312,53,233,629,758,17,721,103,874,190,670,724,478,432,780,655,53,472,12,977,711,33,82,317,880,126,984,572,117,22,816,523,117,833,918,942,658,277,648,165,263,837,304,599,434,701,846,65,749,875,843,336,214,957,648,583,458,743,1000,663,545,236,349,654,373,352,960,701,513,805,295,360,991,203,965,274,854,839,775,368,93,518,151,749,298,560,396,902,274,914,291,203,764,34,325,232,681,93,231,191,624,694,225,484,175,561,770,365,904,567,916,55,980,292,385,679,156,467,289,744,895,930,728,270,76,432,189,597,104,948,699,646,879,814,516,135,703,32,986,481,88,308,31,966,377,610,541,807,501,62,365,507,549,268,896,334,910,508,926,994,77,893,168,476,836,429,759,572,1000,405,394,210,304,165,847,867,891,916,321,91,705,308,103,877,53,939,444,309,890,623,241,215,232,211,160,813,496,992,858,628,609,832,673,421,285,554,108,137,302,816,441,375,161,864,999,124,605,449,149,306,643,419,482,826,143,646,302,394,528,946,761,868,262,517,808,82,22,966,644,282,716,413,280,276,405,645,135,648,258,265,700,660,886,971,241,476,563,774,653,172,897,741,562,298,736,406,958,217,612,693,340,26,32,175,323,601,670,818,284,411,700,710,432,763,904,6,527,865,168,969,279,744,74,508,517,294,524,480,721,527,450,159,324,254,792,636,120,918,930,400,713,348,730,184,486,752,496,535,983,300,367,535,442,518,396,37,112,44,162,755,219,699,436,723,628,362,707,742,304,177,898,403,927,259,465,626,55,235,943,632,338,485,584,725,185,187,966,442,370,608,770,490,624,475,431,653,4,764,928,53,744,846,659,139,434,432,319,598,559,591,86,580,168,422,867,417,796,830,755,433,911,263,385,209,46,189,373,774,637,377,342,246,466,469,888,989,444,206,707,732,998,98,205,196,134,294,63,633,228,283,392,981,481,673,703,26,138,827,421,666,163,299,861,163,968,960,680,0,873,665,776,852,890,462,811,245,333,515,510,461,333,641,741,918,315,479,576,446,875,535,211,695,448,615,179,397,833,948,319,993,617,536,391,725,890,521,821,109,52,248,299,339,495,142,749,487,479,751,185,337,314,841,677,634,447,598,855,344,769,502,221,888,783,70,540,766,729,188,854,803,20,264,715,136,150,486,850,983,477,666,283,356,342,797,782,523,48,987,363,769,212,531,801,316,196,647,439,184,504,839,924,576,473,187,535,232,736,571,886,299,202,76,23,410,264,420,797,376,249,223,408,796,499,50,874,279,157,821,672,734,240,526,177,749,214,986,573,221,426,350,946,268,83,982,465,696,940,693,934,372,218,547,862,899,987,553,293,766,912,272,522,875,196,123,749,773,506,875,79,136,351,622,464,833,460,330,594,596,376", "985,892,474,895,124,108,1,14,83,593,189,801,648,369,19,651,925,629,173,83,896,648,711,881,925,417,886,883,777,339,722,773,397,165,326,701,998,652,249,695,923,783,624,226,924,671,668,46,380,29,501,495,756,316,37,595,100,594,994,620,490,860,491,240,654,91,75,615,521,398,255,818,380,479,972,545,68,180,827,689,762,583,763,504,475,161,663,369,846,37,60,126,989,79,862,938,741,982,594,872,809,500,94,268,890,599,270,654,670,901,360,885,187,145,640,690,842,934,360,216,356,203,334,355,774,371,395,498,548,830,450,484,213,424,210,825,200,763,707,605,801,315,303,941,527,546,873,628,469,750,400,447,147,290,481,457,76,925,651,88,679,55,621,266,209,430,196,966,275,587,974,18,44,734,737,467,257,40,903,72,172,149,393,662,590,630,947,62,393,833,890,484,689,9,863,448,157,440,522,318,405,488,941,42,463,144,815,112,795,918,812,765,340,262,199,139,741,108,440,758,4,506,538,876,879,282,95,6,924,657,80,688,132,249,657,172,511,81,613,126,395,70,421,71,618,695,719,850,405,398,682,193,522,231,890,121,315,464,198,851,655,510,186,541,179,905,208,181,831,751,847,611,860,279,660,970,342,743,134,675,390,870,616,901,860,871,534,292,860,653,435,823,651,313,526,866,896,922,85,265,670,275,830,854,348,113,596,145,824,865,309,875,682,787,136,150,433,451,131,916,781,711,382,332,781,814,823,708,567,535,18,514,249,560,345,141,875,607,462,726,968,115,498,501,719,205,192,849,749,747,288,669,33,241,742,877,281,275,373,648,802,964,666,440,16,645,676,179,344,781,299,683,686,121,767,612,865,834,436,917,568,315,855,314,832,519,942,808,914,822,717,612,317,678,680,306,532,75,424,800,285,970,532,259,218,239,607,860,592,441,239,610,749,215,772,934,785,287,872,504,988,67,623,403,909,175,154,570,300,799,981,878,745,763,141,248,813,454,102,36,382,123,291,177,317,354,537,874,19,576,755,263,797,21,896,41,437,26,242,214,716,93,580,872,914,700,771,160,700,94,209,114,700,693,783,136,250,141,82,200,237,552,59,909,10,29,50,136,573,173,941,590,481,194,768,946,756,307,987,710,72,964,987,615,660,896,123,742,865,188,787,300,307,259,626,871,894,256,476,753,106,499,162,880,316,701,914,210,810,777,715,345,730,170,341,939,899,201,428,693,602,542,917,615,620,883,132,948,79,183,542,321,102,59,275,293,508,147,279,841,372,166,993,60,468,966,103,529,59,567,367,865,312,145,94,829,671,734,657,675,293,3,69,806,397,966,829,81,789,905,606,769,175,740,956,676,606,779,484,93,248,814,102,250,96,940,443,844,480,894,231,79,441,541,500,567,314,412,927,639,124,815,549,307,197,568,642,419,20,698,524,123,142,595,698,648,199,403,589,497,336,93,472,870,188,384,701,141,757,287,960,359,216,856,750,308,345,671,658,763,648,649,478,266,377,713,632,74,589,602,288,646,841,338,268,150,366,338,260,554,642,515,240,243,498,121,434,137,199,326,740,408,374,271,346,932,722,696,297,132,772,501,684,292,106,124,319,181,326,381,724,986,378,152,825,819,417,4,456,546,505,920,300,440,175,842,615,232,56,868,557,4,432,825,783,745,65,481,762,99,48,905,284,412,225,769,710,621,261,105,273,689,446,833,405,275,236,580,937,345,978,782,775,467,14,466,274,529,25,776,920,166,394,672,206,840,972,417,343,68,42,119,879,845,880,809,907,772,331,739,145,298,268,509,803,353,936,440,908,374,342,752,116,770,44,169,708,131,78,81,488,116,627,211,206,94,79,532,873,0,315,1000,845,516,23,406,712,744,424,6,500,73,914,271,681,651,118,185,855,703,451,372,210,697,320,896,558,773,269,888,318,658,897,133,510,549,485,108,999,881,709,219,244,571,352,65,113,593,391,852,280,315,190,479,77,922,663,723,956,638,947,49,609,908,257,211,904,942,111,349,8,936,130,98,667,854,594,321,191,543,375,409,743,418,266,640,804,969,560,198,550,107,463,823,143,971,469,549,290,762,712,419,348,996,21,843,834,862,296,775,96,734,105,935,259,610,711,667,912,349,532,580,736,421,772,706,266,186,293,850,368,678,16,647,914,770,127,260,484,396,217,825,898,759,592,909,289,686,985,892,262,447,444,470,649,84,641,35,150,460,156,911,864,408,678,727,741,111,439,966,519,377,937,793,925,72,754,795,960,868", "340,196,421,947,492,543,193,455,800,796,611,156,965,591,732,499,625,804,466,459,102,692,983,636,463,165,879,616,647,542,397,252,24,20,310,882,877,761,872,266,578,215,421,526,120,832,175,866,7,575,945,992,506,510,813,706,261,207,400,518,303,901,35,543,621,298,327,130,521,693,809,814,785,298,994,186,397,713,164,860,594,872,324,485,275,667,26,351,670,712,815,879,559,275,534,903,480,320,767,93,427,258,384,281,950,663,816,881,81,344,402,208,919,19,262,154,907,225,912,350,253,484,133,155,481,366,123,629,604,286,664,381,64,578,190,289,849,256,131,681,841,23,585,117,500,305,664,156,311,525,733,996,194,522,376,400,446,723,648,995,613,823,9,918,672,507,698,292,825,40,445,36,251,639,488,297,595,268,320,274,391,69,913,266,675,913,205,638,55,516,43,317,441,390,538,547,851,787,676,488,948,723,621,142,470,753,107,267,509,649,481,850,229,789,371,194,518,957,575,974,978,13,135,271,149,635,670,192,372,962,36,562,89,670,720,249,94,317,238,128,58,56,377,148,845,119,273,233,998,198,149,376,113,660,644,925,810,456,509,72,969,287,933,930,564,683,451,811,203,214,263,239,759,527,722,479,754,798,995,709,491,865,718,251,487,612,771,41,820,449,876,398,328,841,769,221,791,522,615,341,416,911,361,522,335,854,714,918,400,983,741,467,797,859,437,134,22,913,421,280,798,418,40,840,841,214,61,77,276,537,352,166,381,533,769,278,27,700,291,904,800,927,574,867,292,383,896,225,509,138,691,279,475,26,674,551,334,492,876,641,557,484,507,374,476,315,929,659,755,359,879,168,865,83,473,358,719,647,961,311,431,165,46,563,755,889,736,624,65,588,957,541,566,131,333,301,750,322,177,818,467,140,899,135,264,169,439,516,509,701,125,651,279,953,272,214,926,902,58,569,720,346,758,952,936,39,355,594,697,810,501,852,955,544,363,533,216,82,603,685,693,504,363,923,640,374,684,957,678,248,362,673,246,757,452,957,612,101,314,830,859,790,229,763,894,283,946,286,744,463,911,982,613,705,895,678,565,562,68,481,712,716,664,943,355,551,549,28,277,447,734,721,759,27,103,204,936,241,456,119,213,456,770,361,906,153,866,222,588,111,659,147,702,865,744,952,784,329,471,22,700,873,798,644,398,294,86,768,665,218,306,106,713,168,799,820,337,820,377,920,569,42,88,434,840,496,368,252,526,622,941,620,376,828,551,825,877,617,123,50,749,672,675,456,902,530,364,416,665,928,48,546,788,348,57,719,66,410,197,904,245,594,243,223,292,763,889,20,193,807,595,99,613,794,548,170,597,580,823,495,168,733,744,419,901,114,111,562,56,425,495,149,824,213,310,931,11,745,28,720,83,426,348,9,304,145,299,512,778,173,657,460,297,536,118,6,911,250,771,193,468,119,992,351,703,501,385,947,645,471,227,361,686,583,139,323,335,607,146,945,340,780,418,980,989,243,863,586,671,767,868,127,461,912,356,627,572,344,534,767,657,258,739,128,832,73,320,120,916,969,588,592,74,230,425,254,584,666,927,235,528,248,499,314,199,361,369,556,581,776,725,921,661,233,90,633,887,183,689,207,553,121,738,115,789,308,859,102,875,980,461,283,391,938,340,94,338,340,123,84,351,570,73,300,628,25,653,419,662,105,14,825,963,659,704,616,904,588,643,750,97,554,797,521,44,286,479,993,161,538,405,193,998,552,138,211,563,513,629,981,752,105,434,783,610,674,459,135,650,113,406,160,776,923,605,893,55,450,918,502,588,755,776,751,797,593,210,717,282,684,55,710,584,875,92,694,474,879,665,315,0,329,882,805,970,231,791,238,557,194,667,311,355,852,978,475,166,157,991,409,863,741,190,276,327,182,699,585,549,697,362,47,405,572,252,98,639,684,470,543,949,354,237,215,86,365,752,578,308,137,675,539,486,205,294,616,555,479,102,524,717,922,423,831,920,214,438,42,387,740,792,747,86,954,439,919,550,750,611,629,956,356,598,467,318,310,852,807,695,913,858,163,995,768,759,283,357,568,69,306,394,450,61,295,469,476,818,324,855,997,166,716,483,484,368,672,633,610,460,413,930,972,253,573,362,433,900,311,35,649,379,914,861,312,845,664,826,28,277,920,196,367,621,251,198,511,764,274,302,832,591,171,743,777,808,369,233,353,419,786,13,79,411,473,879,374,508,577,259,49,727,148,602,51,137,690,131,640,746,643", "915,691,86,759,893,239,832,254,125,498,442,10,903,510,265,901,131,741,325,282,493,804,574,14,390,866,575,135,851,108,200,901,932,996,742,807,743,400,973,494,541,36,364,745,822,207,860,769,453,970,829,462,475,407,614,182,782,765,932,510,528,505,450,712,637,352,73,250,178,303,630,618,264,717,51,931,303,339,824,694,658,359,363,927,727,663,656,685,819,953,550,414,765,614,371,831,781,761,996,556,693,976,361,271,897,143,718,124,872,894,25,443,440,353,11,19,358,381,592,835,631,598,62,334,91,237,876,183,746,430,99,160,194,937,909,188,923,586,470,212,48,102,677,82,315,407,738,73,928,282,569,136,428,23,459,646,316,60,481,933,747,485,353,911,393,142,655,86,250,317,800,114,848,669,512,71,371,936,555,317,677,277,547,756,764,205,628,261,134,525,384,520,785,794,970,668,680,937,830,388,254,708,406,889,552,216,139,291,285,940,563,818,218,731,140,421,878,590,364,541,397,423,159,122,929,365,40,100,490,400,811,491,422,276,812,371,907,624,76,386,229,267,366,369,122,568,644,419,42,328,645,71,24,104,697,974,196,668,587,507,873,832,608,421,92,755,345,452,602,64,302,74,19,908,923,15,630,664,989,107,819,944,464,818,938,955,542,714,313,707,501,166,909,665,606,664,782,170,355,983,225,13,449,165,117,311,516,420,483,704,90,530,117,380,577,732,665,516,112,545,725,791,623,157,573,557,728,64,943,184,105,898,858,230,148,228,358,764,347,392,430,935,826,943,609,269,266,556,858,75,594,934,373,292,74,348,281,986,775,436,715,778,204,539,530,303,506,507,777,385,575,202,47,468,969,948,913,370,150,140,403,197,441,626,845,320,353,159,778,188,371,715,751,612,662,205,368,978,547,343,970,930,5,469,839,188,433,18,777,32,802,331,580,173,465,437,635,238,629,267,636,803,711,490,579,467,258,126,934,269,867,594,427,411,234,961,795,243,138,838,388,622,205,330,47,534,191,511,306,902,5,345,493,956,899,845,726,801,297,720,115,353,934,925,915,797,415,894,463,960,789,842,193,181,698,450,100,639,346,196,326,898,361,27,380,386,234,172,610,810,591,258,806,896,526,401,669,264,740,292,459,100,870,219,851,679,288,259,250,968,848,761,230,568,974,398,372,724,240,346,842,977,5,320,352,29,822,27,6,411,730,779,550,581,593,906,357,782,747,948,553,117,356,876,661,808,734,7,854,631,456,265,133,995,403,780,356,706,883,243,873,293,505,470,994,640,389,453,960,71,263,580,702,483,733,555,698,193,853,942,146,880,372,803,635,953,29,801,882,565,620,702,477,15,219,988,153,663,496,686,895,56,774,954,699,945,462,855,678,568,858,849,296,345,365,925,527,306,974,443,38,304,147,225,334,542,429,401,905,154,114,39,393,104,80,155,75,92,565,342,358,376,243,277,704,583,401,599,728,624,978,891,144,293,444,785,915,505,505,92,99,157,41,700,40,470,718,506,781,553,858,554,496,560,567,973,103,483,84,166,225,671,699,34,471,525,170,180,448,193,635,308,100,553,194,61,252,139,422,855,299,429,541,942,341,542,477,561,825,527,824,954,3,764,247,272,625,771,641,609,300,541,879,459,376,471,399,758,874,787,657,721,103,495,318,47,760,882,545,370,77,107,304,316,684,636,202,396,746,126,186,185,37,90,1000,531,216,766,671,158,606,172,785,924,906,677,672,712,111,603,371,344,479,865,603,876,638,507,232,245,95,800,474,891,296,57,576,763,994,142,378,783,878,128,140,945,174,472,407,154,488,7,21,891,102,410,575,363,716,840,756,825,703,367,544,474,365,631,776,1000,329,0,644,809,340,24,963,409,408,154,573,677,470,579,780,437,719,517,909,996,461,538,346,802,184,776,456,5,298,798,809,419,892,202,362,482,304,763,577,325,283,764,278,591,400,18,231,714,704,393,652,125,162,568,428,812,852,795,352,834,401,955,346,206,576,106,698,869,152,552,543,480,739,236,164,720,942,545,957,394,372,184,45,204,671,955,665,480,534,98,775,781,849,900,463,701,144,155,873,932,360,659,435,734,916,413,307,561,658,588,558,896,388,968,723,920,972,306,336,692,79,313,836,350,781,961,599,628,776,550,572,777,374,282,55,322,949,370,83,217,821,20,969,515,566,65,12,383,774,634,944,489,292,296,653,724,729,539,790,460,916,111,567,60,406,387,30,64,560,376,321,748,375,265,680,150,705,511,632,721", "946,424,950,83,574,161,447,998,901,512,995,413,155,564,261,787,79,427,81,596,609,932,786,951,942,108,375,524,802,439,343,490,191,57,995,782,333,502,648,740,98,163,301,59,317,86,130,194,608,253,478,747,475,123,473,676,694,731,10,65,968,388,137,245,699,234,633,428,247,892,329,875,183,424,514,224,517,3,901,315,652,5,209,798,909,262,970,797,976,180,857,939,161,328,79,194,603,281,562,45,639,30,141,501,669,75,169,635,434,523,405,389,609,729,984,245,850,928,711,179,619,634,416,915,143,631,500,809,515,725,785,737,786,774,478,341,388,411,696,307,152,361,407,994,711,297,506,633,159,64,469,438,92,437,934,878,716,302,800,627,927,326,54,553,372,718,164,695,508,131,680,306,329,402,355,458,866,512,155,293,454,874,453,769,112,276,806,799,747,806,571,474,634,855,243,182,700,219,271,403,980,809,710,677,38,921,699,742,257,938,269,976,884,547,875,945,528,706,796,118,435,35,639,603,386,549,771,706,13,62,811,385,786,404,419,130,105,881,249,586,690,3,75,760,433,882,166,462,990,596,660,274,708,585,841,39,815,617,713,182,636,171,460,299,616,386,270,309,685,167,294,488,841,215,509,713,634,484,361,194,959,685,929,451,464,520,721,461,308,188,681,366,492,289,103,197,682,862,256,495,540,566,28,244,168,377,426,220,337,902,323,571,568,560,849,172,547,345,227,749,56,456,683,265,842,735,375,568,212,372,494,603,394,537,934,708,511,824,556,954,893,691,208,915,911,707,517,709,349,335,101,613,847,717,718,995,500,689,913,701,929,694,115,38,953,649,434,586,87,197,448,848,910,978,473,331,28,446,78,478,770,775,171,712,384,385,11,260,727,586,227,485,437,741,678,719,875,610,904,50,84,316,150,973,596,741,706,535,853,261,52,893,618,322,935,237,243,258,832,477,482,185,868,911,604,514,762,269,62,841,316,333,927,743,469,93,946,407,84,279,955,249,408,416,155,136,546,110,803,725,390,447,2,420,143,92,6,934,675,448,519,442,258,503,930,315,60,281,506,190,94,817,838,114,678,314,386,691,111,706,906,424,7,817,320,110,318,953,40,105,11,953,137,191,940,853,461,42,229,165,126,911,509,116,165,238,720,860,902,983,458,442,408,86,865,31,756,883,75,909,565,271,585,916,714,2,127,464,275,196,217,189,489,628,737,412,618,967,870,200,408,541,517,229,477,912,831,469,683,36,771,571,547,794,279,789,879,543,728,184,848,333,476,999,974,368,912,380,8,834,556,697,176,947,427,452,675,939,828,278,140,868,155,143,134,605,965,856,746,845,824,852,530,832,275,124,20,571,974,899,968,3,732,797,176,102,810,103,790,164,181,109,545,522,160,373,375,165,362,429,873,645,589,759,493,906,615,130,401,914,529,37,538,224,852,607,334,563,271,924,260,630,670,769,728,186,484,641,498,535,264,933,462,349,672,611,344,469,157,909,383,961,6,990,65,587,681,804,753,119,353,278,870,920,453,192,188,370,478,978,771,612,331,912,712,172,79,823,361,631,164,689,130,390,621,97,278,115,138,759,500,102,636,809,536,756,868,797,596,913,499,74,192,310,581,657,54,499,344,332,204,128,427,477,586,321,493,548,222,167,64,726,239,180,410,949,171,458,150,152,992,786,790,693,320,462,946,307,88,844,426,599,411,515,815,116,190,249,315,799,730,45,518,483,568,430,886,242,645,928,716,431,380,818,245,329,612,290,903,988,639,844,144,860,815,866,318,55,987,256,690,797,64,374,277,521,848,35,556,200,954,174,611,756,509,150,403,219,510,365,907,428,211,83,26,906,337,861,852,845,882,644,0,234,489,902,670,290,723,466,193,671,9,714,277,572,53,109,526,960,191,325,995,383,99,373,547,243,659,790,161,144,187,605,751,619,99,202,246,20,236,214,451,296,772,643,79,68,832,717,887,240,651,354,795,539,673,876,73,439,505,961,856,386,844,665,634,286,925,651,135,834,158,16,955,103,19,201,981,318,726,894,71,723,844,90,589,483,171,966,744,724,109,368,329,264,314,637,447,935,658,169,758,220,607,146,253,348,230,552,508,62,819,38,516,385,666,194,952,86,526,964,439,81,472,511,172,695,558,797,708,784,94,680,782,942,250,460,323,606,684,411,301,86,446,658,921,687,953,935,126,117,39,602,998,587,555,868,185,509,796,616,418,515,377,169,370,622,508,857,45,336,381,606,590,225,348,539,117,931", "803,249,62,330,341,592,18,1,958,923,338,132,799,542,398,251,608,555,330,35,611,568,596,497,214,190,502,613,378,839,968,890,254,89,141,242,852,801,403,393,68,14,530,172,730,72,918,530,729,886,564,337,63,590,943,863,677,678,466,828,648,353,23,652,825,919,496,201,786,88,393,754,697,562,710,891,379,412,850,893,88,920,536,633,252,960,59,729,206,413,638,366,856,754,866,638,152,518,284,939,379,209,214,486,7,7,159,159,126,707,511,182,822,100,614,412,314,373,552,341,592,423,568,121,177,296,985,270,489,920,748,847,764,649,645,376,522,621,829,791,845,545,886,296,635,750,369,114,641,136,707,14,135,236,775,986,715,772,87,930,590,812,436,65,649,855,79,969,298,675,835,302,450,652,639,298,889,2,551,314,213,762,129,326,334,359,461,570,588,860,200,78,334,430,927,534,920,591,678,222,684,538,132,631,975,683,478,623,80,165,163,976,309,755,558,250,304,522,503,607,727,123,927,670,114,778,541,238,427,383,176,601,826,37,861,498,513,931,783,924,964,865,918,540,46,943,226,887,743,71,742,33,871,370,54,903,55,909,660,916,854,413,656,472,602,951,98,710,928,260,409,107,35,538,743,757,793,402,468,445,384,166,546,650,953,440,701,833,701,979,958,392,920,853,878,722,457,406,310,28,539,552,238,36,262,802,142,253,859,67,497,850,758,567,872,668,410,627,835,122,872,764,701,297,750,934,551,429,353,138,134,433,737,809,861,933,210,137,233,723,413,121,313,940,422,663,90,182,645,901,680,482,633,703,690,653,833,64,104,197,529,610,595,46,76,905,297,990,887,189,546,751,876,65,464,869,455,18,335,164,874,553,336,56,157,512,467,634,20,883,413,457,702,447,764,317,190,596,172,915,634,942,824,811,907,182,790,854,589,272,406,378,443,157,301,244,492,467,419,697,558,628,9,30,415,770,829,116,168,927,73,173,758,561,365,590,986,383,815,531,757,866,671,40,786,201,170,692,315,821,675,873,547,343,562,874,148,308,439,841,482,216,385,232,151,839,62,572,597,285,691,439,232,570,668,695,323,281,757,564,997,674,758,464,361,433,886,2,831,886,630,164,987,952,409,913,93,510,405,925,413,304,478,238,744,185,288,826,514,543,184,844,942,104,875,519,475,258,56,59,219,440,216,853,672,91,11,931,914,107,852,201,322,432,862,225,703,840,260,954,84,47,78,243,452,753,276,913,180,344,616,67,817,422,848,544,356,890,853,728,415,395,88,265,671,194,210,462,733,662,310,706,17,602,862,655,394,249,344,603,672,422,373,503,51,537,637,736,577,391,588,401,71,296,511,327,278,475,122,99,776,492,964,214,407,600,827,57,553,216,799,826,914,347,234,492,591,270,63,831,371,163,676,340,327,247,405,677,158,523,428,597,46,513,75,429,96,267,990,243,756,173,932,279,934,481,218,601,67,548,392,806,680,94,659,91,29,534,447,50,970,343,47,854,529,596,548,756,518,905,216,783,931,544,99,469,783,377,881,218,364,100,756,785,460,572,438,595,528,679,180,970,146,171,199,162,930,439,856,119,694,261,555,552,144,107,105,510,785,478,765,891,347,55,707,510,536,523,255,496,44,20,843,622,896,657,408,522,334,532,867,867,591,303,791,393,215,421,621,649,391,423,675,342,333,869,976,808,379,219,985,86,741,100,187,715,254,636,666,426,413,308,726,680,819,123,266,245,78,745,393,21,953,274,919,704,59,644,322,922,8,657,106,900,200,616,921,849,234,573,335,128,384,262,252,58,66,192,944,600,193,28,354,327,963,623,525,214,886,392,23,606,108,467,543,89,111,242,890,516,805,809,234,0,254,387,200,247,175,578,602,335,918,608,894,237,614,505,207,62,828,5,179,914,368,23,7,986,371,412,666,39,485,250,286,959,241,111,578,952,480,50,690,940,738,997,988,496,934,703,56,202,176,69,318,813,790,108,123,865,312,492,332,522,875,99,608,195,437,900,338,886,992,856,855,1000,790,560,730,508,664,316,88,6,853,112,896,359,959,365,972,56,313,42,965,616,747,944,67,522,608,333,86,515,150,492,929,19,331,432,969,179,255,226,807,385,627,150,983,679,617,98,357,555,219,947,928,886,368,553,8,729,206,65,724,26,75,152,601,364,872,83,980,17,708,879,111,156,134,60,630,856,59,362,387,241,854,209,227,875,346,317,362,271,316,397,254,634,62,610,512,171,647,994,537,154,553,464,292,732", "441,932,216,348,652,124,333,755,632,500,133,164,844,66,160,197,806,755,868,961,396,3,39,918,7,189,953,241,970,525,553,415,391,404,418,876,765,797,783,637,233,508,120,850,907,305,729,933,477,899,595,911,287,268,597,734,220,348,811,691,415,41,413,565,972,297,299,616,561,612,892,806,780,75,950,35,629,930,876,922,280,929,460,421,158,141,726,847,214,75,602,476,388,128,19,986,521,657,79,489,196,189,99,828,430,20,727,50,333,731,665,867,600,255,145,100,987,132,560,577,917,811,681,298,271,665,781,699,629,767,3,154,891,790,120,168,695,322,237,28,406,678,539,251,418,921,683,278,2,261,276,858,853,825,456,95,388,139,673,159,747,241,618,466,475,180,860,742,878,747,263,727,216,893,164,409,799,598,126,456,409,160,438,961,215,591,941,336,890,794,887,700,552,99,554,338,535,869,137,960,336,640,892,607,264,215,377,606,828,566,823,796,392,573,309,772,144,461,201,573,820,447,850,383,656,581,542,214,394,237,500,867,39,337,536,927,808,412,223,566,920,48,949,396,851,947,363,622,113,921,547,827,850,361,904,321,151,353,816,54,396,333,92,274,359,337,265,456,521,271,116,286,345,343,147,224,303,485,925,983,215,433,101,774,244,38,819,863,249,829,641,498,305,113,699,709,995,963,411,223,156,677,499,137,477,235,496,513,475,257,232,733,44,773,973,179,141,313,59,109,784,575,680,236,546,713,29,378,680,803,701,209,275,477,92,597,11,889,548,449,565,908,596,497,284,304,20,183,444,455,944,527,870,488,198,944,117,978,602,162,212,720,798,148,681,531,631,230,986,25,256,667,61,212,431,156,693,50,254,572,373,625,237,867,472,453,433,934,473,776,512,658,576,482,234,764,506,329,568,364,526,927,31,927,966,476,72,230,81,668,418,842,594,85,542,770,973,140,959,898,783,495,215,236,737,289,406,322,888,311,953,632,288,480,970,515,588,341,705,787,162,700,9,499,625,619,555,566,863,510,204,673,896,716,511,984,731,159,826,91,425,746,814,157,965,800,324,180,302,310,952,796,656,502,380,98,664,84,7,707,895,741,935,205,101,416,772,207,632,653,828,62,836,889,232,409,258,684,885,529,629,239,312,471,181,566,379,390,734,272,790,923,650,372,668,178,668,894,94,944,153,612,345,275,808,472,335,973,964,342,764,541,125,477,882,140,923,750,110,261,741,735,934,702,919,239,207,923,787,642,662,728,56,226,358,150,147,564,598,908,685,589,263,557,947,538,18,75,600,493,450,374,124,219,658,682,405,258,986,553,931,103,141,26,254,773,911,744,795,716,625,976,870,125,358,805,782,626,986,281,582,664,950,83,611,684,735,297,25,133,153,633,904,605,478,453,198,496,86,907,501,311,37,304,427,164,816,872,291,289,121,905,589,646,611,495,19,33,595,864,611,841,189,110,694,246,820,85,950,984,114,421,662,58,352,879,636,843,831,492,116,382,706,730,553,490,830,191,883,535,868,736,794,974,160,545,169,589,526,646,293,518,35,882,757,46,546,197,373,274,145,614,476,662,603,485,7,425,503,248,72,828,898,656,159,805,257,423,290,81,884,177,510,206,324,46,152,755,257,714,287,516,672,406,930,905,554,374,860,522,425,502,523,220,904,110,688,903,943,195,551,369,880,848,10,940,715,439,34,391,67,61,305,204,900,287,688,300,124,724,408,108,689,641,940,683,482,880,324,656,641,751,946,308,165,302,588,993,619,134,699,854,636,891,221,300,591,568,818,752,789,349,953,559,701,348,893,820,96,872,667,587,634,700,520,783,593,515,41,107,832,714,817,224,78,310,856,314,462,23,970,340,489,254,0,283,990,898,843,653,37,620,657,831,438,602,352,34,919,627,310,185,97,843,191,558,205,571,18,817,718,125,72,918,238,772,37,991,255,706,115,226,859,99,322,717,584,543,315,277,24,338,714,895,306,673,644,36,958,823,776,742,452,518,161,25,699,729,637,348,54,975,665,628,246,337,679,652,503,116,861,196,230,407,272,613,499,182,866,941,409,170,403,857,746,945,84,353,256,576,190,498,761,43,951,3,887,85,312,823,418,643,60,803,386,434,406,788,657,6,873,117,42,892,674,254,18,339,130,935,865,577,666,512,413,404,728,315,645,30,663,595,621,847,500,817,588,904,46,125,475,328,562,307,38,480,915,707,101,991,947,193,400,76,842,26,759,442,809,467,359,29,790,663,863,129,723,281,354,877", "822,603,409,651,447,348,493,565,998,865,900,923,513,18,828,337,862,953,345,343,437,811,325,391,928,808,937,370,830,775,751,697,804,492,688,277,710,140,406,437,441,374,729,286,120,743,529,828,60,813,940,907,836,801,434,193,690,172,696,941,624,539,354,862,137,263,175,418,50,18,678,521,762,353,778,33,63,501,987,438,888,397,454,45,702,36,423,501,721,399,464,204,280,854,650,286,266,145,75,163,160,62,773,437,476,269,371,221,90,174,166,328,763,621,330,321,141,566,623,787,453,661,103,599,614,696,754,60,129,369,725,282,778,455,335,60,737,554,327,441,261,567,208,233,126,999,241,17,630,333,252,683,111,755,348,74,129,514,890,490,127,987,556,976,26,193,270,307,938,985,352,896,644,705,406,201,845,364,16,863,52,265,876,678,843,743,717,12,609,925,476,375,909,32,812,231,313,843,174,895,557,539,886,883,15,150,819,452,104,223,201,912,45,623,174,798,646,633,673,467,279,721,564,434,771,32,899,436,376,755,383,993,758,899,463,682,389,580,103,922,269,537,967,926,879,999,224,967,252,343,35,91,209,472,228,368,39,910,986,916,325,79,582,427,216,775,880,112,933,897,402,53,400,685,825,967,66,285,586,27,164,665,736,652,932,345,409,652,224,932,685,501,8,346,799,215,38,979,436,446,594,119,609,423,115,882,867,507,591,777,133,316,668,80,315,569,417,811,29,858,997,597,206,677,624,881,415,403,490,85,192,437,846,624,179,940,707,304,908,610,302,676,883,30,615,585,671,194,426,614,443,198,949,938,91,42,96,816,802,206,295,139,991,745,394,160,234,410,557,309,78,881,46,619,764,40,175,290,15,996,926,707,462,464,126,520,692,136,97,818,534,33,18,27,595,654,382,591,931,808,394,838,662,188,721,824,918,631,53,156,715,839,342,598,172,930,808,414,297,97,92,514,380,872,407,750,64,991,962,24,802,947,842,874,782,986,254,329,38,288,18,547,789,354,661,513,192,99,196,158,480,819,720,171,78,418,993,617,765,420,628,794,383,503,670,971,22,223,259,887,480,147,95,648,360,581,435,763,979,626,421,118,748,192,198,924,703,892,709,782,205,868,651,211,495,580,617,935,150,870,144,734,844,424,660,473,444,239,957,866,993,434,902,144,788,963,156,228,546,218,85,186,78,135,962,686,459,22,689,285,941,793,619,731,178,230,730,722,565,776,266,602,632,530,707,403,447,250,719,936,735,309,169,360,308,111,515,18,234,931,870,847,233,410,274,628,976,17,706,30,863,729,217,887,748,258,832,28,619,255,971,721,272,837,567,268,570,94,204,432,150,343,889,422,179,345,473,985,753,966,398,798,184,398,289,695,164,565,654,607,123,87,116,360,285,103,656,87,276,49,141,155,241,347,320,766,524,530,220,122,109,146,601,733,643,872,765,233,536,243,272,882,276,910,597,793,1000,67,957,1,574,286,535,178,690,428,823,847,998,223,83,175,733,48,424,906,296,271,653,695,34,520,102,911,538,722,847,166,814,598,205,202,596,417,485,310,794,181,653,738,980,513,826,646,265,748,159,282,720,480,213,266,115,523,536,102,775,205,600,514,321,490,339,14,733,508,690,458,126,418,560,86,984,888,71,791,361,468,346,590,41,182,589,611,948,50,175,684,147,174,416,460,714,599,132,648,770,201,866,391,84,892,42,324,482,489,736,161,71,56,479,13,826,664,885,717,571,330,562,212,133,56,928,457,482,85,500,688,915,637,952,44,112,281,399,76,271,879,364,661,819,946,190,655,943,319,312,290,846,129,865,504,409,999,621,600,436,873,308,787,580,566,615,585,646,39,31,239,811,406,231,24,902,387,283,0,757,161,824,813,827,466,584,832,37,54,764,139,504,727,888,997,635,143,902,347,766,419,609,817,858,156,175,110,976,93,685,350,44,533,50,131,376,161,482,413,600,709,926,128,978,413,17,205,80,939,948,278,725,830,275,522,211,473,759,63,351,585,686,882,221,198,650,823,183,510,397,358,28,81,314,425,574,388,401,293,720,224,532,941,504,47,723,591,74,351,1,511,102,548,471,74,322,861,805,91,165,921,347,211,287,251,589,368,616,145,728,378,161,744,259,719,587,171,861,135,977,496,518,452,884,787,214,16,883,570,11,2,725,550,385,883,65,459,966,611,149,242,86,530,103,675,825,424,302,87,658,73,556,48,772,200,144,63,584,366,260,746,853,248,163,231,588,981,433,207,131,47,442,500", "142,677,559,773,701,117,773,161,959,303,990,252,388,62,382,179,869,242,441,395,23,216,688,52,5,394,593,519,753,737,558,760,905,694,623,521,502,582,698,898,864,519,804,934,33,46,216,91,284,649,363,257,857,807,96,276,858,343,312,802,552,848,519,48,811,789,195,736,171,897,375,48,35,561,183,389,329,479,464,509,77,68,87,576,541,21,974,971,374,535,704,824,543,136,231,43,968,821,706,708,430,743,104,864,734,109,688,547,708,141,655,51,754,607,885,562,947,740,258,219,609,202,282,284,758,939,419,478,519,790,483,531,593,512,207,709,402,807,556,95,595,770,270,778,187,433,329,113,764,839,943,235,325,305,257,764,34,188,380,285,756,135,759,659,530,541,666,526,927,699,606,778,846,342,765,915,198,890,539,435,376,576,503,584,927,745,951,792,551,634,727,295,708,297,692,269,699,777,111,657,364,704,747,776,653,709,759,50,418,451,993,686,595,898,182,859,624,792,81,58,647,222,10,619,551,627,502,879,300,481,893,628,516,539,106,279,820,218,81,593,437,505,819,324,344,348,727,922,697,194,603,641,807,483,440,495,103,40,227,192,667,968,40,576,660,320,632,211,358,380,735,352,846,616,812,967,325,739,835,222,712,156,299,342,874,364,367,650,872,847,244,721,797,818,96,585,84,32,533,52,518,266,452,414,101,717,750,917,482,593,910,96,675,574,837,856,849,333,616,951,847,428,472,994,699,818,121,851,224,490,748,548,550,972,193,377,899,174,90,114,747,968,296,725,295,279,807,179,545,380,83,783,735,770,66,42,225,395,420,408,360,538,860,44,426,20,299,478,84,10,620,965,454,713,592,196,599,867,486,313,402,248,806,411,343,186,954,826,628,263,637,468,985,718,383,125,767,125,81,905,226,669,437,946,881,137,539,878,152,626,656,766,939,377,573,562,154,773,597,492,186,743,452,439,59,122,227,996,522,498,466,373,981,28,35,78,290,800,125,856,277,779,25,505,538,628,903,470,686,931,414,927,155,379,762,784,455,104,237,313,499,741,939,245,695,873,813,653,4,239,257,606,414,789,34,710,107,951,620,18,584,931,669,597,200,814,243,663,447,196,906,878,958,432,606,455,321,834,190,999,446,383,293,210,666,292,601,541,898,958,902,319,532,616,304,592,822,453,278,403,585,326,823,79,20,54,953,683,182,765,873,993,151,765,508,287,906,595,46,114,878,744,966,628,109,31,986,195,896,240,734,510,201,487,651,247,937,757,700,949,793,911,225,930,831,804,600,83,915,56,981,817,874,853,610,312,975,824,786,9,787,140,379,335,887,235,823,645,661,626,37,161,692,803,987,889,337,356,545,785,444,129,38,48,224,346,349,808,157,318,81,952,738,723,242,725,559,135,340,411,697,396,720,159,848,968,705,712,334,66,378,805,655,334,407,261,709,147,880,434,344,475,838,514,225,874,988,526,293,209,310,126,452,458,349,2,648,321,51,357,904,567,988,263,613,143,420,73,1,702,663,608,390,618,367,514,193,433,726,724,798,858,594,16,646,366,515,262,104,975,334,674,495,285,210,380,114,161,993,676,431,824,957,500,634,682,249,507,61,190,385,714,238,962,730,488,812,798,809,949,147,251,586,83,619,994,339,605,118,530,175,746,466,393,391,756,680,459,782,546,766,277,242,63,683,132,351,315,516,385,858,652,442,46,537,369,415,705,678,830,396,577,230,862,7,17,960,554,400,936,485,609,42,652,467,884,451,646,371,230,165,108,118,666,723,782,475,503,113,628,180,118,544,409,173,645,346,906,751,327,482,658,5,843,149,490,703,627,521,369,272,619,932,974,69,567,304,866,245,712,791,963,670,200,990,757,0,499,938,348,447,503,26,147,360,775,588,178,379,591,251,715,928,633,195,508,270,291,49,868,622,220,652,659,218,673,42,685,807,397,381,910,852,39,518,227,870,250,432,636,463,846,361,953,488,540,527,156,693,999,484,525,869,673,825,647,383,240,980,234,590,361,554,714,397,875,292,319,54,133,338,772,32,212,871,894,589,360,633,25,975,14,903,489,399,714,627,406,853,891,866,962,928,656,474,666,634,335,168,187,146,47,66,485,987,284,313,317,225,350,858,746,462,699,54,53,579,43,433,690,630,843,654,672,201,886,653,282,816,250,178,645,678,534,492,810,133,84,715,693,289,818,68,101,887,212,335,782,497,182,457,690,585,823,832,599,718,549,603,455,989,402,676,655,433,473,316,654,485,140", "297,122,488,914,258,779,40,400,632,486,133,132,187,904,929,465,8,484,468,356,978,137,714,940,653,23,782,876,731,366,859,652,75,136,187,443,450,799,582,117,87,932,787,769,873,953,280,436,642,899,723,282,913,355,486,376,753,517,235,66,79,804,304,185,576,626,537,706,140,264,901,638,515,150,378,238,504,242,38,488,398,438,765,626,227,801,9,661,979,756,614,200,95,782,24,487,968,402,816,375,378,912,887,457,749,692,973,848,25,363,258,574,276,271,924,283,979,185,443,810,194,125,822,726,844,769,72,17,562,633,555,442,406,920,872,660,575,72,624,418,592,287,49,808,105,372,28,730,567,674,76,862,505,712,532,565,92,313,207,409,637,196,743,283,43,531,694,929,219,57,976,271,28,154,397,76,629,79,118,998,936,24,263,477,608,878,130,196,426,411,527,247,448,846,843,578,87,495,712,247,713,241,10,146,346,124,621,444,211,632,241,890,311,970,897,462,41,350,786,945,388,704,250,485,957,574,580,400,411,42,872,889,859,139,777,266,249,128,175,623,407,763,733,154,302,278,629,52,723,685,612,790,555,446,57,450,778,896,29,170,94,279,414,964,429,352,259,236,415,723,341,872,352,901,64,627,370,811,177,688,733,123,227,673,400,364,453,263,967,85,56,53,252,980,630,906,781,516,379,754,216,109,281,607,646,369,761,45,273,148,349,65,609,873,856,863,762,393,878,116,73,988,127,16,890,440,256,47,889,336,235,930,639,159,310,166,936,766,609,783,594,973,343,730,28,72,969,856,209,868,244,786,953,799,63,282,421,86,587,87,335,133,640,818,759,853,450,290,270,722,501,423,336,984,339,383,886,413,432,53,530,654,250,366,382,373,473,79,403,531,326,826,479,584,670,556,112,761,737,580,363,193,11,8,679,967,867,114,257,770,211,758,68,188,724,882,169,273,458,297,631,741,920,49,263,435,108,531,845,483,825,646,515,188,845,475,802,103,887,954,131,514,292,798,659,975,596,576,48,545,727,671,305,51,258,516,904,951,577,557,47,475,239,697,205,521,604,644,772,438,283,156,568,87,502,248,494,892,446,696,940,999,758,41,859,905,793,932,653,819,624,509,813,566,914,525,535,240,788,244,267,440,872,393,525,540,455,142,761,35,989,239,436,206,287,981,701,581,89,178,413,885,462,854,351,633,844,446,272,75,880,400,967,865,605,277,842,606,732,779,610,629,186,393,259,431,453,82,327,164,324,853,214,40,665,90,556,495,668,953,246,542,341,73,809,402,885,469,73,235,758,254,107,515,441,773,484,96,638,101,147,898,101,463,106,732,521,57,130,714,300,77,339,594,580,348,583,531,41,121,798,662,691,80,761,626,961,273,246,323,745,230,953,688,759,915,891,217,392,460,421,623,456,362,835,635,314,849,531,740,102,485,490,326,448,80,805,410,872,888,5,182,507,790,154,716,407,93,924,284,627,900,938,389,347,803,533,629,455,254,449,370,779,569,579,532,79,47,45,292,641,426,259,927,726,712,920,764,757,756,902,450,493,506,551,967,11,583,103,622,554,125,642,245,588,644,433,702,339,287,987,927,349,81,728,687,682,204,777,102,399,3,612,464,255,781,314,209,202,523,412,849,123,342,620,331,821,14,154,150,155,615,676,398,64,375,854,751,197,742,999,514,225,904,598,316,714,57,153,860,304,151,533,457,899,76,412,844,20,528,873,272,791,482,82,787,910,250,695,950,783,63,628,423,735,83,841,521,677,804,466,663,243,254,19,308,228,693,384,198,972,981,419,549,689,412,924,254,953,388,701,370,926,668,947,24,90,76,986,919,293,886,236,953,660,37,390,26,333,744,238,409,290,247,898,161,499,0,174,914,224,414,850,264,549,610,132,450,850,503,469,840,265,499,702,387,465,542,251,531,783,385,935,660,551,836,193,206,934,967,849,65,951,708,556,387,9,188,474,139,699,299,211,18,168,34,974,442,378,441,112,254,453,600,505,537,38,592,643,730,829,544,704,215,106,516,172,370,50,49,503,24,257,195,388,695,437,24,541,715,347,730,989,869,455,521,355,463,212,168,76,616,346,94,892,522,80,942,728,359,494,43,356,873,62,327,222,932,283,790,550,403,105,986,601,420,429,484,728,767,675,301,270,400,553,352,272,859,764,467,687,349,320,233,429,162,717,941,971,48,353,730,153,368,521,527,185,537,717,42,634,719,896,339,372,241,997,78,327,787,440,966,955,374,981,58,694,745,206,84", "409,731,511,494,565,827,129,423,45,87,261,857,724,989,255,196,30,237,862,439,884,950,159,383,77,399,38,662,622,40,495,101,194,369,786,395,193,153,36,778,807,866,836,858,982,542,148,665,28,500,226,440,776,354,707,363,156,148,348,985,143,559,25,643,962,855,305,171,136,823,273,378,397,942,141,531,3,523,166,904,384,652,554,437,184,585,568,13,775,690,302,969,303,726,95,561,825,988,98,649,770,551,801,485,674,435,49,342,748,290,198,543,351,822,907,116,490,37,291,304,846,865,921,984,129,346,231,874,441,270,347,278,689,828,459,501,57,144,275,713,916,480,272,320,324,744,216,70,256,221,420,385,69,243,657,794,221,139,346,338,162,505,144,567,970,999,388,984,727,526,826,232,993,261,882,918,169,355,666,294,175,590,664,44,538,108,429,29,553,416,904,701,390,384,461,44,718,961,255,785,670,344,882,750,986,979,44,191,655,403,695,297,595,855,685,504,351,958,354,320,349,15,458,969,811,237,594,754,556,583,481,646,994,427,714,381,374,864,130,32,392,112,46,286,903,727,196,206,131,185,66,7,338,476,312,294,129,534,710,345,390,767,520,301,719,705,580,926,581,274,934,745,942,729,108,938,534,956,59,880,960,774,369,715,784,389,219,754,288,987,574,853,423,391,733,915,82,315,935,987,454,956,715,430,242,296,590,307,179,703,653,867,940,934,495,49,731,970,9,193,175,86,865,980,751,428,872,691,691,843,205,797,658,386,390,657,177,402,835,935,985,199,623,548,479,200,611,344,87,601,113,335,66,745,937,62,257,692,85,871,239,176,455,879,659,342,827,243,823,441,696,238,6,398,227,181,478,95,231,862,568,495,601,914,214,264,259,19,193,414,358,36,111,441,917,687,955,885,773,122,775,680,78,617,955,541,264,956,841,425,583,151,778,654,112,74,934,740,622,463,61,551,279,482,544,900,123,849,280,792,695,280,20,231,620,592,899,141,219,880,914,989,483,978,260,45,550,282,233,616,879,207,79,781,761,68,222,32,301,460,612,443,449,555,744,524,283,509,982,106,93,909,277,178,325,922,369,853,774,287,165,564,201,284,102,781,710,360,26,428,937,112,162,212,143,474,315,550,956,563,687,729,225,765,184,39,660,938,628,76,767,232,110,178,244,890,393,513,829,188,870,393,266,586,446,191,529,210,948,149,886,183,240,355,949,772,502,116,298,432,764,652,34,89,679,744,101,213,368,326,592,811,682,747,777,254,64,391,187,535,793,125,247,664,70,204,862,382,342,430,515,114,194,299,354,656,699,926,995,712,275,219,693,804,643,809,260,560,660,894,97,320,593,438,394,12,968,413,725,742,36,602,583,885,327,23,917,32,492,183,676,680,939,17,302,684,680,545,970,931,122,915,203,874,30,782,512,891,208,856,443,818,525,70,511,360,408,896,694,7,764,147,237,584,179,17,388,668,322,52,229,603,350,570,558,313,526,328,128,827,55,810,590,360,905,512,428,418,491,836,273,523,807,132,468,924,360,587,410,699,881,456,483,510,210,157,959,573,821,430,167,913,403,910,950,709,40,125,907,291,465,681,530,90,937,778,99,895,450,556,520,235,291,730,762,14,99,888,451,899,73,899,96,193,373,714,740,317,138,183,116,63,788,181,965,747,575,742,668,659,672,179,681,853,807,52,429,394,417,894,679,551,497,135,128,784,330,64,190,781,624,994,917,413,820,627,708,850,954,996,529,743,157,926,781,350,859,362,695,712,395,143,989,442,426,39,697,879,886,846,871,488,278,442,301,204,67,484,634,332,265,181,378,141,889,677,659,490,200,966,579,454,927,817,242,181,228,81,515,424,557,408,723,175,843,824,938,174,0,644,977,172,545,114,611,888,586,617,153,277,284,829,203,383,552,323,282,900,883,463,392,443,837,238,804,81,551,204,328,382,734,303,92,646,583,328,493,177,943,890,316,907,752,447,985,928,473,591,712,10,124,86,367,688,19,686,289,258,507,479,171,309,463,213,280,314,282,522,946,613,227,291,12,538,703,299,751,681,973,408,457,749,286,173,176,826,150,796,707,190,667,366,789,63,676,957,562,673,196,917,681,114,634,541,393,225,866,901,300,948,446,468,578,969,813,452,218,555,288,701,64,416,797,285,80,694,785,352,741,249,903,67,474,802,477,344,614,980,814,180,131,836,905,194,536,743,161,77,434,296,835,302,415,733,773,576,284,409,823,500,249,797,924,267,437,968,664,876,212,487", "773,939,618,387,510,951,638,114,673,321,770,122,928,475,88,127,319,29,205,286,587,957,565,248,644,883,665,192,228,827,848,219,356,827,496,814,875,679,909,779,219,181,417,809,137,458,142,196,13,940,594,620,477,136,844,959,287,904,342,475,241,990,213,561,40,964,341,43,655,305,714,25,84,199,724,187,984,359,218,816,497,484,260,565,160,631,707,880,746,191,821,248,644,18,296,649,436,479,123,941,624,966,699,244,124,595,727,235,353,844,20,615,207,147,306,312,253,380,516,993,550,368,616,224,296,524,493,33,954,589,176,745,845,619,451,273,560,468,873,601,342,685,405,754,406,543,378,738,217,420,845,320,557,552,556,872,109,920,120,726,920,921,611,9,398,751,783,18,971,665,978,379,320,667,881,762,553,15,228,418,563,233,76,623,901,95,782,598,539,123,434,640,641,853,715,90,888,888,68,970,670,471,558,745,205,967,564,757,992,888,410,79,862,1,863,316,725,246,245,579,489,650,81,180,744,933,731,526,535,313,25,202,979,180,628,378,182,699,367,407,617,484,382,697,463,505,765,622,455,792,584,329,55,793,494,19,281,315,168,91,218,237,235,914,529,706,313,452,382,645,718,515,841,680,214,416,840,727,673,222,419,494,258,408,498,541,311,838,597,139,846,362,722,774,405,228,81,386,108,589,306,56,797,467,90,48,539,924,126,164,179,266,749,595,309,852,699,129,986,757,297,731,435,449,977,81,849,520,828,778,181,474,920,719,63,888,299,88,55,258,548,298,151,747,158,668,721,200,430,558,464,611,402,641,886,588,90,723,285,304,175,780,874,415,134,861,224,388,867,241,429,223,201,209,851,102,933,808,564,728,999,101,800,682,763,834,258,683,192,491,721,43,21,347,550,726,809,236,364,93,746,273,127,348,629,339,220,940,374,873,136,815,463,856,278,148,430,62,296,654,955,71,967,854,624,785,453,612,914,895,778,602,182,291,662,588,301,710,260,531,294,191,39,35,267,923,419,440,468,565,658,710,560,561,446,200,278,439,388,306,559,40,206,978,416,207,433,111,463,47,612,757,662,920,805,276,897,530,686,344,347,174,671,617,876,994,56,745,861,682,582,67,361,264,119,794,780,185,612,26,300,638,663,64,983,522,31,779,161,462,996,347,363,614,488,80,416,575,177,286,593,330,568,244,592,266,187,14,892,997,149,455,423,485,509,387,38,947,92,926,823,882,708,595,722,810,705,119,41,963,345,765,486,301,107,800,487,608,591,185,128,41,25,974,986,549,644,376,167,397,637,714,560,768,826,334,48,628,406,351,864,736,59,106,398,937,518,725,539,41,455,947,32,158,253,488,257,563,425,776,771,124,143,73,577,670,913,306,576,764,157,102,526,928,350,274,75,997,796,455,837,463,358,563,879,650,297,292,847,791,741,713,96,296,755,567,469,562,341,636,57,915,150,510,235,359,949,753,532,781,44,381,368,326,7,163,678,507,790,864,193,460,793,539,413,256,771,349,518,374,683,783,64,584,715,78,577,145,504,501,365,382,437,273,222,665,902,171,303,463,59,919,887,58,882,497,568,998,71,927,288,692,495,709,597,950,803,616,424,353,831,180,552,791,798,933,265,800,453,663,629,742,882,725,790,691,436,672,821,882,569,540,65,105,502,756,420,805,866,789,722,371,25,139,811,534,48,475,979,886,712,503,176,267,224,193,569,708,687,639,446,871,415,80,164,206,322,721,783,661,707,645,697,211,504,652,328,501,395,182,547,855,142,350,338,871,271,262,989,921,788,533,139,150,282,190,646,146,137,695,284,189,200,99,519,786,589,999,878,932,333,188,444,55,854,315,550,196,510,6,194,154,466,578,653,813,348,914,644,0,845,135,945,659,791,103,839,224,860,1000,553,895,107,451,439,960,183,215,72,71,570,194,458,215,433,319,408,840,733,821,174,540,64,886,91,268,109,837,889,473,48,953,374,832,982,682,442,185,787,722,912,959,23,153,501,918,47,705,207,219,268,978,647,749,305,548,680,829,814,531,259,315,933,280,275,360,198,203,373,392,344,220,375,937,175,775,926,847,378,913,356,745,968,651,754,98,813,831,813,142,75,407,73,424,341,906,765,96,967,868,230,274,711,832,440,242,84,868,532,625,799,713,84,962,835,757,918,144,593,962,59,465,93,648,755,191,221,484,228,966,450,5,704,729,704,778,977,77,21,412,728,777,433,455,257,326,306,587,938,701,347,905,817,309,712,151,402,7,671,316", "356,960,766,644,804,762,642,114,814,859,834,400,953,495,356,906,605,119,448,341,494,397,779,742,394,87,927,123,321,629,607,108,594,740,470,293,629,664,696,363,440,294,535,988,834,196,445,504,384,922,403,870,358,250,942,821,984,530,34,792,591,32,175,667,428,941,820,973,219,467,286,90,554,253,383,30,561,988,926,285,64,335,214,916,976,661,633,916,217,501,76,720,54,184,377,129,684,331,355,74,285,543,115,304,722,799,760,689,569,703,935,898,709,438,210,864,342,795,755,575,821,886,355,281,107,225,364,73,962,496,90,144,572,366,521,546,420,806,616,706,652,212,247,479,554,630,257,759,8,327,259,418,664,11,128,148,865,198,246,543,832,806,270,353,36,562,963,22,916,138,19,918,103,737,221,669,240,117,699,781,565,318,783,814,199,137,52,820,751,565,215,274,128,480,651,12,779,438,481,804,867,755,757,356,949,876,597,376,328,725,887,767,58,276,678,530,414,529,410,593,350,179,962,755,478,366,190,104,608,177,629,751,837,956,328,909,74,139,729,895,651,623,491,316,279,72,562,147,573,369,413,685,942,827,671,842,306,72,684,999,159,521,134,384,357,752,679,783,158,479,235,551,644,388,161,545,456,783,510,195,78,499,872,428,111,366,791,360,195,973,950,402,448,877,715,367,665,456,612,242,41,312,573,721,766,579,194,197,812,19,702,415,319,619,895,409,998,337,581,747,32,867,354,98,181,794,303,565,616,309,459,466,947,588,24,976,20,521,832,971,645,307,468,442,410,807,770,347,355,459,891,78,751,268,507,184,690,184,365,827,751,224,298,611,913,147,746,932,39,18,306,785,731,112,775,388,24,223,949,610,549,522,175,955,973,109,949,510,796,237,598,47,423,721,195,16,516,366,248,940,28,901,626,221,904,319,33,282,113,155,178,722,174,465,608,382,276,731,115,47,632,34,664,43,893,912,331,325,136,919,494,22,606,467,30,323,837,718,92,306,344,440,112,6,160,485,664,874,499,439,713,779,671,105,706,465,88,975,457,166,444,991,141,443,69,199,561,888,782,500,790,183,36,844,272,124,697,616,697,354,311,149,193,387,459,169,472,252,813,944,985,722,309,597,153,471,440,123,971,807,450,436,736,803,141,994,629,195,578,694,473,581,793,88,522,539,413,69,627,131,505,306,743,281,96,815,928,372,266,979,693,452,312,850,221,728,445,85,255,661,905,461,122,804,598,650,334,515,179,502,937,262,775,324,179,338,602,511,281,173,747,77,252,994,848,970,633,176,213,960,474,537,133,815,480,121,16,742,997,627,374,505,388,783,547,567,380,209,172,992,524,526,14,782,601,562,582,942,427,217,489,487,61,541,677,954,835,785,484,360,486,387,856,545,335,567,965,914,861,874,491,250,439,702,197,286,384,552,457,745,346,401,490,528,405,185,491,376,450,696,481,573,181,64,588,429,652,888,644,382,521,927,805,995,332,902,540,670,795,39,57,260,217,136,9,87,948,908,226,144,88,8,13,992,615,665,193,911,913,592,333,982,668,736,968,490,236,243,838,355,638,63,496,415,294,737,171,472,627,55,227,704,769,733,255,779,881,357,678,264,774,341,468,434,911,484,544,182,547,723,694,545,19,777,221,358,355,515,636,265,35,859,96,311,279,873,234,82,789,483,747,926,549,981,557,405,938,800,660,430,666,591,22,251,239,27,596,960,252,714,690,578,612,261,85,929,423,988,927,359,37,849,364,846,590,376,478,930,667,708,975,261,484,834,606,722,123,648,775,913,246,616,776,846,829,427,601,415,144,164,62,616,530,240,590,552,937,209,67,291,860,524,716,655,896,996,63,991,461,500,667,573,193,602,37,827,447,224,977,845,0,427,421,564,285,499,634,567,738,182,305,865,280,789,906,364,246,185,407,225,713,32,284,281,130,875,662,219,395,569,337,373,315,247,975,735,141,33,737,261,32,390,237,721,401,316,198,822,451,552,41,421,86,707,573,438,147,439,904,887,925,291,390,178,810,384,143,975,137,454,197,198,443,651,91,569,910,902,272,341,200,418,131,332,342,262,263,747,228,341,653,560,768,143,581,328,339,155,280,480,679,149,659,231,510,324,136,899,371,333,565,908,495,704,37,478,427,880,498,723,166,694,553,223,266,29,934,894,157,605,727,455,89,186,30,551,901,114,966,503,687,45,609,797,927,194,825,191,413,255,107,102,564,377,445,726,955,461,462,658,246,143,441,773,6,869,973,162,281,818", "890,571,232,66,90,679,914,875,924,363,318,608,555,47,153,654,631,598,107,563,71,43,451,203,352,883,110,841,579,435,402,773,220,119,629,419,731,38,569,635,673,752,278,861,544,204,143,250,472,184,811,430,741,656,138,442,562,590,592,833,746,818,952,100,569,649,209,912,40,998,879,44,326,247,800,878,931,59,769,575,883,571,705,856,119,446,488,974,685,784,357,439,266,590,382,677,795,448,79,943,576,398,636,569,663,180,623,292,234,230,140,534,995,715,356,888,361,401,409,712,305,663,33,495,539,899,599,689,632,195,584,782,775,645,123,797,161,463,519,81,480,410,143,549,240,183,468,574,447,497,490,915,935,150,899,543,969,330,377,751,12,304,806,958,443,177,669,655,964,55,444,154,575,708,634,129,971,297,920,28,40,574,447,725,752,321,623,432,322,737,166,761,678,432,531,320,944,855,371,219,595,680,531,222,104,665,418,862,606,812,258,666,729,454,855,591,132,136,766,205,915,450,191,122,404,207,819,758,941,913,22,28,172,596,213,722,622,845,886,648,343,844,321,452,497,288,551,619,566,857,606,114,873,264,488,270,472,878,204,19,659,13,396,710,174,188,393,886,866,339,786,385,239,680,72,379,286,328,430,703,890,813,460,674,774,769,464,482,565,557,30,151,974,679,974,398,820,897,487,465,534,749,739,61,733,823,371,636,596,168,599,338,248,533,100,379,773,218,910,101,498,840,238,721,668,873,89,99,987,502,693,994,181,823,59,899,604,537,664,208,816,567,965,989,496,733,775,991,229,786,245,554,806,638,601,625,912,875,81,296,476,877,333,386,233,96,377,613,42,216,731,886,178,850,365,515,567,397,63,860,660,208,329,863,841,868,92,450,701,89,6,727,183,100,927,198,949,188,675,78,884,379,345,423,962,974,563,591,186,866,225,220,329,576,210,1,708,135,234,619,927,593,541,339,306,602,777,621,884,560,18,232,697,113,879,652,137,804,958,376,983,184,43,48,963,300,372,775,816,498,81,328,647,419,783,806,778,151,768,525,798,620,447,108,269,807,149,666,323,546,773,897,234,547,487,943,295,137,242,674,847,208,499,307,915,163,214,427,972,755,291,636,459,631,620,972,563,964,611,518,166,657,351,82,147,68,225,685,577,939,671,330,131,465,974,639,345,155,957,707,329,323,935,599,327,89,746,994,39,680,422,671,51,436,675,163,205,481,972,783,497,511,129,2,876,265,147,327,849,306,148,507,555,675,524,652,629,917,639,972,850,713,880,369,805,273,691,445,577,247,936,899,338,280,654,973,828,544,918,258,489,167,760,116,514,150,358,166,917,887,504,511,718,609,647,695,437,825,143,783,767,617,765,211,48,728,405,895,40,810,707,212,293,801,483,668,700,652,567,398,259,538,193,507,106,706,985,267,4,323,220,922,788,154,541,890,58,401,573,162,5,244,303,660,205,485,132,162,281,751,628,950,58,601,699,948,12,425,753,614,633,478,799,889,31,44,819,975,307,419,228,954,931,868,431,593,434,78,737,855,170,367,528,865,897,378,710,684,542,909,738,122,370,439,80,161,618,392,605,621,394,564,576,596,324,753,302,555,11,797,917,419,488,734,487,917,727,597,611,50,563,110,588,287,286,164,943,598,222,103,982,993,155,679,306,494,810,821,155,408,403,855,23,689,742,611,485,286,339,314,1,312,82,725,616,111,592,950,830,843,830,271,262,798,744,8,888,652,97,573,24,627,376,889,771,406,594,124,18,149,646,387,987,141,636,156,36,418,721,547,434,697,339,670,459,218,509,836,62,838,460,373,337,168,413,899,460,754,46,515,50,565,703,978,692,375,310,67,333,73,311,677,671,335,620,466,503,414,172,135,427,0,616,998,885,816,677,94,870,131,138,831,989,552,837,703,296,171,57,161,654,610,192,867,24,846,923,47,342,28,707,733,930,707,745,714,622,768,68,358,456,65,527,252,163,921,908,598,265,989,783,838,492,820,946,461,101,72,517,884,342,823,388,183,271,553,524,68,916,529,530,637,929,152,496,153,605,509,986,115,25,529,950,97,927,615,964,752,2,278,384,199,826,500,313,50,38,668,593,924,850,32,706,724,794,181,235,777,815,369,8,724,358,889,417,10,774,997,142,752,504,307,977,841,54,890,19,419,343,758,106,817,978,424,807,188,984,800,468,745,804,538,911,935,429,270,514,527,344,651,676,349,543,935,435,432,171,11,978,450,235,819,225,209,94,429,399,991,690,608", "170,430,239,219,290,837,908,963,838,180,217,818,453,885,785,850,613,340,317,338,176,313,644,828,443,189,375,483,761,257,700,705,600,646,150,936,475,260,450,720,369,121,346,763,128,795,686,429,176,222,565,906,593,562,648,183,590,156,288,49,681,191,774,812,725,774,424,869,179,294,510,610,826,528,358,716,703,914,142,804,835,29,673,804,276,364,209,758,757,105,587,46,196,44,693,944,318,343,527,491,850,133,304,914,583,353,682,221,135,665,93,535,301,578,264,855,498,347,358,978,206,9,60,879,258,230,83,25,86,306,973,741,241,957,563,143,437,983,181,355,319,996,948,596,217,604,719,104,887,100,617,161,356,601,502,705,720,727,443,30,684,120,117,89,453,297,578,315,111,648,643,545,326,371,421,667,297,837,360,856,787,551,589,587,413,562,249,223,747,193,830,120,874,333,859,347,761,917,639,230,887,765,252,842,300,859,794,457,761,726,213,331,808,786,676,619,972,188,213,421,685,281,220,924,220,528,997,24,973,975,347,281,89,302,516,47,390,434,543,248,779,13,453,367,805,978,973,239,777,950,268,462,731,235,839,264,110,476,847,630,482,459,215,202,66,868,236,200,606,99,928,225,622,262,902,208,159,604,881,588,998,187,967,32,778,631,437,587,77,657,900,98,842,47,738,543,805,166,749,354,874,231,42,744,440,165,808,623,390,733,831,117,462,556,691,711,738,395,768,456,286,895,523,714,958,877,470,624,89,776,602,285,626,314,801,196,511,624,915,531,486,614,923,390,948,655,233,72,332,766,715,508,637,508,897,555,427,187,243,655,808,578,426,556,591,165,653,564,5,84,839,459,467,425,578,690,246,281,623,829,171,996,308,72,875,775,993,845,378,364,581,752,798,172,225,113,301,627,396,157,850,598,481,928,299,957,694,192,958,214,47,907,582,453,5,519,552,870,638,818,128,109,76,948,369,104,96,170,892,881,166,682,4,169,686,911,212,469,99,892,964,627,908,906,270,980,314,56,930,601,638,368,708,358,186,392,834,666,614,489,582,317,675,311,760,648,358,494,969,788,629,730,288,720,911,299,847,548,482,962,141,531,14,7,142,736,847,874,530,557,979,201,416,216,986,394,144,381,774,987,611,747,529,573,684,667,925,294,736,328,695,657,792,169,305,134,775,860,852,985,138,100,705,292,371,215,343,864,756,86,953,28,259,298,117,236,735,970,4,626,857,844,662,924,921,740,929,382,512,124,101,204,846,719,151,224,439,885,639,392,382,486,407,761,231,960,208,273,114,616,595,622,639,215,910,186,140,358,432,473,151,423,879,12,668,931,159,539,712,60,866,788,530,92,108,185,785,455,216,281,930,857,843,564,195,160,41,583,303,939,465,164,290,571,278,835,195,411,74,82,563,539,222,629,722,221,386,864,945,215,515,234,92,24,983,190,994,895,640,735,567,773,135,69,730,115,305,362,731,827,756,943,485,413,848,680,346,603,871,308,813,194,209,176,340,993,917,965,41,279,956,588,636,186,35,823,678,544,239,596,918,921,36,247,642,851,932,214,407,700,563,405,467,519,909,232,353,336,164,508,582,851,132,280,74,541,426,67,835,496,674,656,146,181,778,311,198,219,911,677,94,170,597,137,293,215,911,961,402,99,750,904,595,934,468,414,723,46,615,805,953,508,719,146,176,161,461,421,194,464,780,278,660,634,371,595,566,136,668,123,147,429,752,500,217,607,98,160,265,447,435,521,145,535,454,796,271,964,720,545,20,978,112,413,790,903,470,505,428,827,922,186,502,846,929,550,636,113,617,847,365,750,567,859,287,447,24,273,91,827,694,908,207,547,539,105,77,895,641,914,355,470,9,918,657,584,26,850,545,945,421,616,0,131,138,779,305,732,540,722,780,724,691,938,283,465,355,608,420,455,470,965,221,307,741,749,167,123,153,574,901,388,740,656,157,126,724,521,841,101,447,729,561,877,489,898,893,827,363,966,319,711,964,834,825,806,845,90,39,646,2,454,726,477,989,726,782,132,484,663,526,684,864,378,183,838,757,523,344,360,217,865,487,984,144,127,61,801,328,972,425,227,706,825,559,632,630,123,826,204,654,835,725,889,733,948,785,581,495,892,299,682,999,52,988,959,266,581,159,386,950,204,201,965,449,693,513,348,131,571,11,450,702,671,950,786,137,296,828,436,533,474,187,911,666,915,320,508,8,706,173,822,137,252,110,656,637,625,769,616,182,411,399,15,209,312,386,306,507,310", "201,280,591,333,221,892,880,88,324,204,435,644,604,878,402,426,605,402,485,65,748,902,360,72,669,432,422,165,637,140,615,283,153,155,582,599,633,597,682,222,582,143,445,982,550,714,437,948,414,425,435,166,656,184,850,535,279,890,637,993,455,181,972,961,481,353,743,149,228,607,731,747,456,498,813,780,616,485,15,346,177,557,697,721,693,72,213,728,180,671,919,771,353,998,661,328,707,226,758,258,270,866,171,404,873,891,824,707,572,690,117,936,641,372,889,256,127,293,803,528,215,466,205,270,570,83,298,973,311,989,840,274,72,745,658,120,24,201,241,35,319,305,287,593,832,790,445,706,908,136,292,401,145,564,577,28,341,421,396,623,396,139,280,803,77,253,543,570,618,250,207,392,146,355,346,749,254,684,208,196,339,866,340,976,99,492,919,825,44,839,887,157,257,32,773,548,397,884,969,714,402,591,504,400,183,793,153,494,40,706,184,570,924,565,417,52,973,614,354,257,55,395,211,982,669,614,78,236,756,916,931,93,293,680,785,232,791,145,384,634,892,675,218,585,90,381,971,583,932,256,432,388,48,217,970,636,526,746,1,274,557,615,865,95,626,968,710,67,166,323,912,512,579,65,267,273,990,297,808,22,61,277,153,164,206,921,930,732,850,628,521,940,80,194,456,974,343,655,162,355,989,928,249,879,338,393,70,511,49,410,120,397,509,983,825,457,940,350,894,443,913,321,209,556,981,541,214,552,170,215,117,77,883,338,534,992,113,467,513,861,198,938,55,893,251,47,325,47,465,391,382,562,746,998,367,820,916,483,671,183,166,633,247,98,948,337,145,489,287,604,485,656,841,17,431,394,661,644,515,643,319,531,949,640,89,367,203,154,29,11,512,81,356,638,920,935,107,304,988,350,593,984,493,613,440,666,366,331,879,796,678,602,105,755,459,127,258,476,323,877,905,548,931,268,615,274,322,32,772,155,653,279,342,592,709,987,852,847,797,443,410,265,389,328,673,23,638,704,290,690,7,710,413,662,66,428,268,89,50,910,982,574,244,460,632,867,280,424,222,932,288,934,51,601,695,755,679,581,862,970,854,33,811,866,239,937,739,322,795,812,249,635,277,938,126,699,92,380,60,314,719,70,431,256,560,394,39,734,173,928,785,40,542,892,973,461,954,105,150,490,132,967,235,822,98,514,120,780,497,712,832,332,848,875,237,703,672,454,732,172,287,724,751,841,89,462,470,95,362,269,463,756,593,505,988,87,345,440,231,532,246,243,428,50,447,864,546,851,735,402,649,729,869,128,660,505,288,701,864,803,792,581,589,59,874,311,678,445,359,968,607,687,872,28,202,955,698,897,366,5,575,271,577,340,179,673,412,869,434,110,869,816,474,938,287,253,861,568,392,142,184,514,715,435,120,508,158,38,19,409,368,505,26,767,607,158,339,217,391,744,125,823,604,690,72,667,230,34,879,88,946,684,516,348,628,31,918,80,553,288,727,575,546,908,952,334,826,410,104,635,462,749,181,853,887,385,623,736,799,396,844,551,864,457,682,936,453,864,821,266,496,953,616,320,909,144,846,101,935,976,778,626,969,69,999,422,29,305,888,121,422,551,937,16,87,698,620,676,455,21,379,662,992,642,358,213,77,272,923,189,833,233,891,352,112,573,896,660,473,974,863,734,635,164,877,274,778,435,449,616,875,351,13,356,231,468,407,40,748,583,779,833,656,802,608,230,452,337,137,386,311,319,419,834,488,150,618,369,422,384,4,159,390,14,667,201,870,965,551,126,604,249,986,332,963,405,255,849,459,489,684,119,889,10,363,609,713,257,310,502,699,873,705,436,276,141,886,558,741,271,852,579,714,608,831,832,147,264,114,659,564,998,131,0,2,338,778,621,543,113,527,452,327,13,387,937,802,931,781,677,132,751,613,922,966,831,314,860,715,919,551,492,541,704,918,471,959,674,298,951,743,601,977,86,411,265,62,609,191,108,334,505,258,301,52,725,169,604,518,276,812,692,455,436,781,683,507,536,592,904,43,117,789,375,775,827,366,790,109,418,359,594,64,966,128,272,808,267,966,318,974,397,917,346,920,765,792,515,926,764,47,373,889,581,18,559,387,102,449,116,461,228,72,242,177,467,517,173,989,171,125,138,191,644,833,947,85,258,909,838,214,261,341,293,59,774,740,201,486,647,253,262,277,31,949,515,535,826,153,486,616,423,244,835,827,903,636,649,270,179,239,760,849,59,415,242,74,458,603,789", "815,976,556,87,926,640,163,645,994,535,235,319,205,650,488,710,893,346,816,381,618,367,940,32,793,74,698,478,854,176,126,946,194,543,345,5,284,595,194,817,356,348,222,616,59,772,40,233,496,445,783,85,840,456,494,835,775,357,49,892,361,578,115,753,596,817,25,576,623,824,303,348,71,923,368,337,890,370,21,205,981,454,560,260,953,395,159,761,453,439,855,647,571,793,35,535,860,533,413,14,113,710,759,355,757,67,69,197,386,258,671,273,778,737,508,147,735,354,283,21,292,250,657,810,246,945,536,168,674,881,701,64,703,274,727,272,16,506,148,395,48,433,979,475,324,643,406,942,746,680,71,77,511,238,383,899,390,977,499,954,989,70,756,688,298,730,530,398,111,466,820,759,563,509,881,196,400,868,477,658,821,658,198,198,236,216,120,152,963,977,718,162,149,772,958,619,562,138,278,741,423,551,189,433,862,385,104,748,698,887,473,262,384,264,9,329,207,871,58,251,279,139,477,241,734,682,189,117,835,790,991,122,46,874,575,731,258,859,833,19,758,89,98,965,814,8,924,941,100,898,474,718,490,646,7,79,616,468,348,148,777,785,12,978,808,25,837,949,555,635,16,190,811,38,263,526,515,226,24,915,190,257,870,994,882,244,58,387,984,259,627,735,948,489,187,245,901,610,899,413,726,303,405,544,769,68,840,127,939,72,283,213,815,960,299,922,929,713,792,433,452,727,651,374,445,176,811,874,662,676,294,598,875,750,326,356,304,78,330,91,6,247,363,586,959,944,580,985,930,799,774,429,575,69,170,276,110,707,993,692,447,373,784,954,458,736,601,284,66,633,885,114,123,910,601,284,901,982,419,706,973,156,895,289,767,216,609,22,769,914,945,158,935,455,770,531,938,552,146,634,95,533,744,598,452,573,838,385,100,515,602,458,589,450,233,236,417,339,742,580,47,928,668,179,290,724,894,859,520,392,64,496,805,712,938,276,446,274,814,715,234,166,984,113,154,984,59,219,845,601,449,55,414,920,928,791,961,562,921,361,587,84,912,711,56,119,586,701,71,719,886,800,499,800,752,215,863,829,206,299,477,787,170,502,857,385,125,31,306,932,717,952,910,718,742,360,183,374,489,555,385,303,406,77,328,200,107,12,444,246,695,974,912,133,756,538,492,24,294,120,892,701,412,681,666,38,677,758,337,225,187,918,227,582,575,125,728,336,14,257,932,212,100,627,941,358,395,696,670,559,251,565,434,946,401,750,806,822,16,251,316,201,981,358,58,892,436,274,545,591,543,346,187,705,248,562,880,502,224,174,581,590,770,276,215,653,103,299,837,394,151,464,412,359,237,212,7,472,661,467,228,773,628,806,87,410,993,416,297,581,408,306,793,952,155,570,119,218,302,908,799,147,882,180,746,844,93,96,183,144,900,650,774,161,265,473,146,463,89,559,172,618,63,51,140,523,734,524,748,932,772,109,519,995,39,749,223,877,792,637,218,949,584,627,589,231,70,98,231,514,357,770,338,476,780,258,961,352,327,716,771,149,59,592,989,864,273,720,9,593,147,564,630,172,323,266,32,319,517,909,573,388,958,405,808,371,164,171,730,173,202,211,238,111,596,231,389,158,259,844,744,755,228,512,751,511,435,323,391,565,552,487,110,112,993,908,164,556,390,703,50,381,215,145,152,627,90,554,446,717,14,295,52,5,52,595,170,394,112,481,780,201,875,688,933,881,763,38,188,381,618,31,785,982,777,169,970,471,106,331,78,399,431,104,756,498,332,750,141,318,581,167,46,527,166,804,148,107,735,887,837,110,911,234,15,586,414,17,724,37,158,752,877,559,910,954,745,644,918,681,978,780,277,894,438,37,360,549,611,791,285,885,138,2,0,858,284,380,721,344,730,214,990,479,398,830,978,973,752,826,507,264,603,176,246,365,813,604,903,954,153,957,97,528,857,164,460,474,361,370,759,238,113,75,891,430,777,369,156,723,46,973,184,537,220,93,301,511,671,344,643,548,514,39,747,713,786,956,884,703,863,193,23,78,526,778,493,485,811,897,156,958,286,879,388,779,427,592,754,576,193,295,229,600,456,595,976,746,903,58,993,728,433,59,990,349,944,314,924,542,277,458,553,953,324,828,927,51,507,802,692,63,533,796,662,446,766,905,490,721,493,120,995,279,975,115,552,786,314,605,602,978,507,13,60,358,581,828,936,157,451,432,945,919,748,172,377,319,464,946,777,172,650,7,51,468,105,180,417,288", "931,144,351,427,273,722,240,482,837,931,185,198,397,296,137,33,652,914,31,971,787,537,678,949,217,703,291,945,928,426,825,813,892,817,915,283,514,664,977,637,733,546,613,919,567,417,885,337,360,285,418,373,642,342,541,694,775,390,275,630,759,350,846,984,476,92,755,673,893,569,700,610,138,842,953,163,469,843,981,233,735,164,517,25,391,613,246,107,662,827,60,426,764,275,790,214,195,820,73,171,497,444,451,991,479,992,482,609,2,97,378,102,537,594,38,521,892,782,875,768,968,958,993,882,173,354,212,127,682,242,913,976,128,594,527,120,691,926,540,644,815,512,308,238,31,973,748,693,444,84,862,763,269,349,526,142,247,511,451,172,943,328,599,993,839,68,155,954,257,932,873,799,705,753,416,753,669,88,529,444,851,206,392,935,55,911,571,202,28,234,206,43,516,192,346,18,711,586,426,9,921,78,504,271,561,914,247,546,400,897,747,3,732,304,696,989,786,475,797,295,407,508,169,724,391,390,270,104,377,830,392,747,238,324,787,778,340,691,51,443,48,813,112,134,778,767,67,522,694,94,712,259,165,609,693,977,332,47,369,550,965,728,275,250,103,348,89,702,5,137,69,317,320,830,707,38,776,451,491,306,430,815,155,807,637,959,797,610,943,541,667,746,271,396,616,458,960,143,26,207,521,967,489,559,94,159,67,894,76,244,367,640,20,721,557,908,113,712,626,592,597,184,475,89,770,947,437,132,804,374,364,751,57,121,687,756,204,72,858,858,871,426,20,851,569,781,293,506,41,152,550,129,714,158,747,982,856,583,355,964,493,732,133,226,235,493,242,302,660,986,688,637,848,828,248,512,461,508,315,210,505,812,4,404,164,871,943,680,46,574,967,285,244,704,852,479,916,230,601,651,304,32,272,690,803,638,603,412,843,294,485,65,816,244,963,996,267,36,397,298,543,603,703,527,994,157,523,721,246,882,498,973,863,385,938,58,804,980,202,84,602,299,882,743,767,608,574,192,737,973,620,528,887,719,602,363,765,117,626,426,527,402,699,670,236,67,52,577,202,171,217,113,500,363,517,904,689,205,68,744,185,430,437,158,823,791,378,284,883,392,383,432,988,833,349,591,428,94,173,408,706,793,614,247,261,797,833,587,325,403,653,635,351,54,162,543,790,547,400,938,263,113,370,901,924,286,734,37,780,768,396,647,922,568,205,309,546,553,442,796,189,941,909,284,895,911,326,162,585,34,358,254,683,34,15,760,967,83,272,272,151,50,711,589,279,851,653,41,123,226,9,837,319,5,275,453,747,574,380,160,674,86,624,326,522,464,547,582,86,334,63,393,975,391,590,12,736,157,981,10,143,50,477,180,200,639,344,449,301,438,893,213,335,559,799,100,900,251,579,5,923,171,536,461,758,376,177,147,916,637,207,690,623,829,586,65,333,869,482,461,127,559,25,190,597,907,95,598,780,428,581,924,361,436,275,426,688,258,334,996,334,329,170,13,277,708,116,965,731,338,689,478,157,291,247,67,454,347,224,786,484,243,146,500,15,443,557,380,631,80,755,127,916,938,401,629,346,925,252,882,117,748,833,619,461,237,133,246,493,92,157,629,118,230,95,634,695,639,855,967,229,203,602,447,676,768,211,523,928,35,137,136,156,67,719,437,25,754,606,189,448,703,771,979,213,669,905,619,897,581,881,757,529,66,985,489,105,820,807,288,946,584,396,711,367,949,21,638,246,35,684,401,69,426,490,758,714,790,582,370,16,331,29,740,216,813,383,106,866,643,701,78,686,262,412,871,165,673,675,990,761,780,933,528,464,968,34,741,527,813,697,498,181,72,72,870,616,817,315,651,475,437,572,237,602,54,775,610,888,103,499,816,779,338,858,0,323,768,674,730,174,480,974,259,600,296,231,963,531,642,192,788,5,505,737,585,817,446,665,56,935,110,878,304,612,428,245,361,719,229,708,67,956,413,51,376,117,180,550,856,883,58,491,94,148,916,336,260,637,814,708,16,199,115,136,353,981,647,133,506,691,466,67,54,475,251,629,580,683,163,107,300,377,87,845,808,206,546,183,616,592,154,931,393,18,427,148,658,900,501,825,532,208,462,644,152,12,661,761,677,527,717,215,581,910,74,844,676,51,869,664,846,897,88,692,346,485,779,794,317,810,432,712,685,614,866,91,860,128,40,129,395,495,795,369,354,184,291,10,985,798,327,315,850,358,159,966,392,161,251,960,942,357,590,524,332,326,5,308,818", "486,894,839,163,147,154,558,717,758,77,571,81,864,490,781,556,658,663,744,797,555,310,342,174,100,634,279,711,627,224,336,974,540,557,708,112,690,947,447,63,732,135,864,847,481,72,938,794,166,593,5,143,127,686,801,684,750,624,243,369,197,692,356,945,394,847,889,319,651,895,809,762,911,157,348,604,574,740,719,16,688,642,576,163,680,167,233,922,546,511,577,56,549,669,446,410,324,679,129,976,91,691,568,183,50,945,128,463,842,486,800,999,695,511,80,834,493,316,628,322,503,132,934,459,908,918,25,199,426,271,260,221,736,505,312,597,906,329,649,192,753,129,359,850,299,388,76,174,463,227,47,294,831,848,301,203,919,836,737,433,68,732,607,700,938,65,667,968,789,658,708,861,984,291,91,332,762,50,652,220,829,378,328,393,277,809,906,996,551,580,733,329,920,442,506,454,778,334,241,132,296,427,163,580,557,841,363,22,47,551,216,860,614,172,458,188,850,685,235,688,641,66,672,892,836,248,879,119,869,854,395,825,659,546,305,986,320,724,941,395,610,998,416,864,30,279,721,127,409,285,647,367,819,486,289,125,30,276,997,341,284,252,132,601,9,801,425,697,307,273,320,120,844,987,465,275,242,725,846,838,577,912,908,28,502,698,344,577,512,591,27,93,78,414,76,591,141,900,292,491,748,390,136,205,549,17,483,548,365,762,643,626,121,114,593,37,836,226,624,146,428,193,925,866,907,226,430,741,162,305,53,273,237,238,784,935,921,994,548,798,696,467,570,448,407,327,954,869,993,263,378,363,32,92,655,900,480,894,498,918,986,949,747,724,514,581,75,475,337,161,170,947,153,114,64,672,186,616,487,592,274,505,770,144,3,251,109,218,518,143,689,17,574,516,140,933,985,406,980,839,503,11,381,110,409,230,382,126,758,19,162,501,448,150,553,341,90,427,154,998,639,744,917,244,463,829,564,618,659,501,356,169,981,219,29,894,916,280,149,836,491,696,619,313,712,963,976,111,438,61,663,889,740,972,550,199,255,426,377,950,802,784,210,339,558,316,793,628,829,141,343,715,372,427,165,668,919,988,107,757,923,876,336,321,905,501,727,215,581,847,480,692,211,410,45,388,932,745,431,373,524,525,503,88,826,130,391,175,21,942,832,327,256,237,705,86,33,416,773,257,215,28,146,972,601,620,993,75,221,175,36,730,845,893,616,955,487,540,643,922,580,830,435,473,794,843,554,485,738,460,957,841,244,630,363,459,768,89,43,216,80,780,714,153,373,676,931,610,392,448,652,565,62,673,898,812,553,354,190,677,299,298,190,468,478,983,387,13,64,245,220,796,985,918,23,369,912,637,347,620,731,859,443,789,992,295,948,712,5,971,404,241,138,394,379,226,625,341,584,119,453,739,583,51,199,295,238,483,968,246,761,223,793,83,776,762,210,271,772,666,38,327,309,595,171,149,183,363,671,532,586,895,711,344,99,314,268,779,299,195,996,311,738,109,938,95,344,545,977,244,399,318,622,581,623,372,568,798,197,656,529,633,38,788,329,14,750,740,334,649,45,687,141,530,558,944,984,930,419,902,314,464,603,26,328,864,974,350,457,615,852,857,167,203,799,626,843,281,447,758,483,547,895,753,750,599,424,586,578,685,723,508,700,934,666,234,249,704,813,699,343,165,475,77,879,943,49,440,396,728,724,125,714,984,552,269,345,508,25,143,805,991,330,387,410,206,654,494,525,279,786,386,627,847,522,422,409,226,194,402,829,86,92,621,100,928,431,640,760,939,138,751,221,743,58,176,176,706,817,22,485,932,455,14,69,432,656,739,458,171,922,733,405,881,164,149,389,603,479,118,166,719,53,614,352,764,588,132,586,839,634,677,305,778,284,323,0,186,468,469,320,469,905,327,658,5,9,863,197,334,540,771,21,765,551,65,694,458,77,428,824,850,951,693,690,531,365,142,830,144,566,22,331,881,538,669,215,304,203,648,908,776,286,758,901,182,254,585,382,331,77,435,77,519,427,710,602,801,97,642,79,934,23,533,761,968,740,307,123,725,878,181,62,221,59,126,308,330,566,525,10,403,326,346,227,187,265,665,550,984,414,936,668,571,569,170,343,707,109,960,68,323,352,324,948,875,261,307,628,717,346,928,965,514,921,635,925,278,996,553,807,850,353,15,259,638,890,565,280,386,361,764,153,750,445,749,43,278,428,697,461,534,714,851,929,448,57,248,29,473,496,369,889,934,449,338,986,884,42,522", "626,356,689,279,725,730,485,975,915,981,798,473,356,435,30,174,292,616,648,886,440,717,662,961,476,512,27,146,722,378,422,631,445,699,43,2,295,784,445,315,869,536,784,988,140,29,414,355,816,409,873,96,798,853,361,192,31,373,295,234,15,23,637,667,555,794,789,394,325,610,139,412,36,402,620,601,318,928,107,317,463,335,548,291,593,25,114,943,623,35,706,954,332,235,576,837,910,175,660,398,881,767,255,888,889,878,869,744,752,636,922,319,42,441,880,161,137,613,141,746,985,889,289,557,111,614,415,193,916,361,761,770,508,803,270,630,165,267,229,871,656,910,491,992,643,472,195,219,549,367,530,998,444,959,954,688,893,663,42,84,62,74,871,813,769,306,550,591,715,28,519,177,753,262,264,296,247,491,50,681,482,685,150,6,319,94,634,94,32,490,526,33,671,927,82,787,507,572,740,427,731,559,527,131,665,171,727,200,978,485,972,949,942,199,413,948,41,256,780,672,72,845,54,168,107,468,987,787,460,841,153,319,981,937,575,257,527,187,320,738,546,538,566,122,174,279,733,700,210,169,129,585,288,33,782,853,348,988,238,348,22,238,24,525,24,454,518,95,26,328,350,638,587,440,677,454,180,252,491,134,771,623,302,69,510,829,292,334,107,804,749,13,694,991,480,847,217,549,199,365,400,993,45,727,492,931,790,501,500,41,732,397,78,991,379,215,63,989,873,433,589,820,45,558,170,702,298,189,453,801,509,722,817,941,457,19,534,734,144,233,479,205,853,858,141,49,556,316,477,658,123,408,183,613,199,146,554,577,448,441,829,753,814,748,243,62,866,10,480,152,648,876,272,979,205,856,75,679,66,100,60,408,119,591,217,827,779,759,548,661,18,276,587,240,253,887,120,679,225,201,577,120,13,604,518,106,341,424,351,805,745,98,303,888,884,873,391,671,873,703,189,264,28,758,367,25,180,586,186,731,649,702,56,230,594,211,752,361,259,693,659,449,647,239,867,952,149,364,478,936,865,805,710,527,240,756,766,335,18,28,288,149,10,957,641,466,783,847,650,201,422,420,465,579,712,230,61,751,519,555,123,373,517,342,351,576,746,842,137,155,232,570,481,645,265,657,452,922,712,176,357,918,706,743,577,704,131,421,438,117,382,522,913,71,930,993,818,742,516,748,660,609,596,272,387,626,843,579,33,232,714,694,543,954,137,318,19,200,643,963,292,565,625,839,987,162,326,753,145,825,366,331,190,884,597,40,538,526,191,310,530,852,439,485,655,876,766,992,662,153,829,562,446,862,728,499,490,515,589,325,335,41,590,376,580,871,827,45,813,432,771,371,74,667,462,246,957,249,431,21,992,346,418,618,879,981,274,560,963,515,474,676,32,8,736,19,584,811,511,615,209,993,947,362,549,984,895,97,748,477,702,150,587,901,707,189,619,333,493,524,538,489,485,349,34,316,83,715,646,13,964,686,521,599,215,598,399,167,487,948,804,760,438,746,632,131,614,114,257,22,24,723,926,904,272,940,297,730,342,78,728,427,21,589,464,859,977,571,506,127,212,456,981,131,624,864,257,460,63,456,737,683,121,612,318,346,336,323,428,462,231,270,10,608,331,214,895,735,327,754,909,485,456,970,539,372,729,324,265,941,354,364,890,948,392,797,255,926,587,668,621,66,599,829,199,395,750,536,515,510,770,993,719,820,363,263,202,960,420,368,26,77,497,619,574,169,940,750,886,491,772,428,420,635,894,72,775,522,501,946,588,651,138,97,927,70,581,647,999,921,318,915,989,710,381,496,364,983,638,211,526,326,982,963,541,117,858,599,88,370,136,895,248,602,622,771,152,216,576,185,157,517,109,505,34,139,178,450,617,224,567,94,732,621,380,768,186,0,268,557,819,585,485,195,873,856,546,315,504,614,984,650,562,421,249,395,727,400,209,901,310,702,433,387,306,575,214,382,470,958,520,101,379,135,776,881,432,125,175,37,263,922,773,81,583,953,266,918,698,328,675,417,410,784,426,245,467,844,371,691,92,454,309,324,343,728,472,731,882,123,782,779,918,568,51,646,508,297,402,673,301,477,395,14,121,701,663,970,208,153,72,19,274,741,778,68,275,284,419,676,862,741,790,129,9,921,762,597,244,554,447,767,209,273,465,683,723,605,965,646,105,608,140,218,528,347,263,579,369,226,386,662,984,29,772,112,679,100,402,203,755,264,580,115,944,859,124,971,741,264,319,272,284,429,416,712,657,518,481,513", "223,855,387,443,871,412,621,320,236,545,510,56,718,620,908,795,888,794,475,834,720,867,255,739,574,156,779,16,270,330,486,995,220,512,690,937,273,830,445,583,776,320,309,897,499,191,544,879,667,591,363,986,660,565,81,497,130,498,210,987,59,88,295,910,887,527,472,31,308,675,250,288,866,355,215,240,463,371,862,886,978,88,251,491,965,280,810,546,749,637,460,126,902,17,863,973,935,251,860,736,394,358,214,836,901,820,630,287,873,961,376,470,18,139,360,258,367,499,360,48,638,242,181,231,742,246,167,729,194,459,907,188,336,224,411,499,279,94,147,279,315,198,892,861,867,333,167,831,504,967,523,757,882,56,163,755,512,827,290,382,365,197,237,348,111,837,387,481,600,333,127,998,378,165,808,538,67,357,943,542,191,515,139,553,930,385,695,871,67,444,675,424,94,115,397,264,297,579,486,199,295,883,396,951,679,696,438,638,355,155,24,554,770,733,296,331,803,76,754,273,616,239,894,867,565,84,92,525,170,223,430,6,246,537,634,373,702,719,349,71,461,394,571,428,207,591,833,484,674,398,262,212,855,357,964,823,674,605,875,866,999,577,328,278,5,565,51,788,204,535,245,433,870,829,925,680,763,725,639,770,516,663,230,328,427,595,206,711,668,593,455,651,796,125,623,118,378,97,325,670,318,225,955,694,426,535,325,919,126,126,468,671,733,811,767,32,549,534,216,310,579,149,840,510,599,760,291,150,11,8,747,619,34,90,654,437,660,360,418,913,793,478,204,564,543,575,39,934,992,804,356,873,251,970,52,849,237,198,880,333,212,647,48,312,315,908,729,142,676,753,722,466,278,838,238,869,905,454,843,245,36,832,805,578,531,469,635,521,53,618,609,525,221,619,523,516,314,775,748,623,663,581,833,757,60,23,801,562,438,179,72,145,997,879,194,222,190,995,86,890,566,841,861,24,214,452,26,684,70,691,204,293,887,431,658,568,224,147,248,59,665,243,52,260,32,436,705,169,439,751,315,765,290,703,39,899,103,830,546,965,748,644,392,71,234,682,954,716,751,361,989,315,556,795,403,865,75,451,606,831,933,186,497,8,382,696,578,707,632,729,824,223,585,203,399,499,953,258,182,836,447,507,317,902,619,666,486,791,930,664,193,79,928,776,980,403,904,666,767,165,128,574,755,590,964,846,822,276,982,885,187,952,223,790,798,421,483,519,511,885,600,386,696,233,115,396,687,458,344,624,221,677,893,239,103,968,113,837,815,931,913,571,298,3,235,701,362,707,275,422,416,434,784,289,507,238,911,172,301,14,678,585,389,928,441,999,564,647,598,701,258,962,314,191,39,952,106,531,972,388,678,415,909,395,705,295,288,738,602,501,119,550,773,57,613,37,608,381,444,213,821,350,62,151,558,848,831,51,302,863,784,274,217,180,561,442,392,506,946,27,439,420,953,562,453,451,124,520,904,721,75,192,467,214,222,543,853,781,706,627,657,998,40,791,602,90,815,962,502,955,639,420,229,147,725,352,299,745,117,726,546,230,949,571,777,123,570,303,347,354,336,441,867,872,727,521,425,16,502,656,350,582,921,855,553,321,195,484,659,436,369,231,32,655,52,184,754,420,704,351,821,228,625,103,566,851,715,481,890,186,220,526,401,131,435,165,803,884,48,374,983,161,826,1000,480,464,443,492,543,520,48,377,658,883,809,773,339,479,604,398,823,538,794,376,7,724,430,650,662,113,78,17,21,381,911,399,259,786,293,698,887,802,386,295,297,577,903,555,402,355,618,491,805,355,752,684,664,40,521,972,554,150,864,387,843,306,822,134,371,369,324,919,772,166,485,159,366,488,446,855,991,909,526,207,919,504,379,850,153,860,738,870,540,543,721,674,468,268,0,228,72,639,222,762,684,100,69,581,989,319,599,419,153,185,268,23,442,37,323,474,439,226,586,40,88,209,72,964,944,448,331,450,553,968,83,854,267,206,871,104,750,693,896,532,343,441,427,378,674,49,406,132,577,368,316,713,465,501,403,761,585,380,363,761,645,941,816,998,137,75,371,228,717,378,960,101,201,481,610,51,386,607,679,938,751,658,177,272,889,91,9,127,186,470,460,227,835,442,251,960,952,409,462,701,291,816,140,516,991,806,637,563,706,906,524,748,642,774,831,604,149,250,740,577,227,588,866,449,273,923,845,607,595,319,384,644,461,16,220,999,402,90,563,241,119,885,734,261,432,458,503,147,121,956,4,614,773,892,156,297", "290,794,944,445,507,269,217,42,970,875,469,306,444,841,898,326,941,320,769,388,765,387,532,809,354,799,411,372,784,440,708,901,428,542,871,131,344,323,501,245,92,669,403,764,972,553,558,286,305,773,20,207,322,413,686,90,783,798,324,896,336,277,236,147,188,591,340,762,146,960,150,183,552,803,585,301,475,765,56,452,140,907,154,911,865,490,250,35,299,994,79,716,241,308,75,892,319,941,982,872,542,3,743,531,112,667,7,852,780,610,460,688,686,170,212,765,676,697,194,979,989,726,352,766,309,959,412,365,919,946,404,498,775,916,380,352,476,515,192,182,998,939,72,736,252,446,398,785,672,588,22,342,842,735,667,906,731,755,558,809,10,346,441,710,724,824,427,170,324,242,72,105,557,613,962,938,640,472,570,464,553,432,957,454,953,594,783,742,689,362,916,502,490,910,941,877,455,244,87,205,784,894,732,342,329,97,465,427,424,910,62,526,972,856,167,249,509,466,562,558,389,734,522,289,995,263,419,150,730,736,477,299,152,238,979,745,410,649,638,892,977,974,130,62,219,594,47,18,818,490,524,958,355,56,166,311,482,340,921,820,712,254,178,394,276,2,121,290,413,373,198,663,276,466,904,807,690,678,48,600,700,784,450,135,374,774,947,375,327,823,247,318,342,139,411,295,758,727,232,729,299,325,312,644,823,570,516,180,612,355,866,613,456,835,727,268,37,493,81,187,369,88,297,975,20,641,221,742,778,37,399,187,481,870,938,418,16,179,712,733,386,846,674,667,209,995,262,399,653,12,4,216,116,145,504,758,838,569,22,596,555,889,646,751,231,718,513,579,841,489,951,995,642,210,398,125,377,291,774,677,691,814,872,771,801,628,95,707,402,384,309,866,947,223,697,29,507,374,13,867,652,353,141,204,370,8,756,994,163,896,497,362,961,113,883,778,631,562,630,991,144,224,903,855,34,902,721,176,712,95,551,775,769,185,256,423,650,529,5,236,223,398,853,508,93,138,97,171,188,896,48,659,714,518,272,199,730,902,371,253,565,322,803,847,37,516,590,833,997,811,38,636,916,153,93,632,924,922,588,144,806,721,823,218,639,113,77,334,260,1,796,163,247,950,746,547,932,264,656,605,592,350,539,10,454,823,580,759,248,408,926,540,395,111,941,895,949,496,562,936,898,696,518,729,570,457,102,596,637,933,713,388,43,253,861,250,461,144,538,57,436,826,29,979,717,372,537,890,192,688,872,652,666,236,982,594,472,178,16,551,343,933,772,506,190,281,125,85,29,204,211,108,29,298,670,400,882,15,849,892,95,94,502,530,664,752,36,329,82,393,705,947,125,730,384,349,462,862,165,76,1000,77,189,127,681,318,353,293,370,618,386,777,18,674,107,358,188,147,49,621,771,763,482,691,788,927,569,337,553,684,763,148,43,297,459,383,947,129,649,788,634,63,809,244,588,923,220,828,200,808,731,776,990,932,340,600,902,435,14,55,989,726,332,772,120,843,657,220,604,165,687,272,395,203,90,282,846,208,451,883,914,733,359,394,295,133,55,567,564,16,925,244,908,805,372,856,955,229,394,699,12,244,103,488,837,359,669,521,750,432,220,942,529,118,698,939,657,810,303,224,231,38,283,559,812,792,263,679,306,888,988,498,500,878,247,293,122,408,287,810,748,746,405,743,55,903,273,176,406,965,402,420,869,300,342,258,185,345,281,586,101,588,555,888,972,174,602,162,400,969,689,909,679,992,73,633,424,476,321,44,231,561,119,768,286,103,326,326,953,690,294,226,744,845,499,549,656,901,313,7,9,34,97,604,63,712,851,794,57,686,762,844,855,588,827,538,474,354,875,703,409,996,960,62,627,727,591,503,277,1000,182,131,722,113,344,730,469,557,228,0,739,500,496,87,475,295,824,133,285,616,226,518,727,78,304,404,234,259,885,740,112,273,937,924,211,76,910,731,73,352,726,770,127,952,362,729,952,11,750,673,306,178,51,169,263,304,939,55,988,728,572,379,386,837,639,728,901,146,645,241,708,321,473,611,453,866,452,574,239,791,819,838,507,180,982,190,725,874,33,943,27,867,655,820,535,642,257,931,501,382,960,94,21,464,865,370,91,380,467,954,132,434,776,477,916,417,135,375,725,413,383,696,338,524,350,205,636,174,557,14,387,512,838,815,887,807,618,793,104,426,782,433,319,295,368,430,712,523,81,910,536,31,280,51,51,761,991,945,676,412,967,384,747,55,129,515,627,56,274,255", "722,830,336,189,777,81,825,761,350,941,926,981,102,921,504,536,386,70,569,224,594,102,407,154,615,1,350,508,693,760,838,267,159,190,707,544,921,929,681,925,859,141,439,404,297,423,381,605,864,601,571,391,89,931,310,622,66,804,114,546,663,802,546,410,623,115,105,917,502,242,994,47,636,468,90,655,689,572,919,228,966,948,560,389,970,845,632,283,159,635,429,311,436,782,496,514,357,588,820,238,456,923,429,662,761,422,279,710,579,232,872,444,711,696,475,494,92,989,275,553,63,323,135,469,601,952,151,651,329,963,968,924,936,597,51,904,801,785,748,571,946,727,563,698,921,237,115,264,387,966,821,199,888,55,245,138,432,899,350,715,554,263,235,841,55,471,238,801,351,145,804,424,592,201,38,357,272,208,55,459,210,907,365,33,571,728,506,39,889,963,14,838,980,974,728,476,217,695,972,598,77,289,143,832,545,69,970,943,711,172,104,232,835,795,145,997,520,533,15,17,601,576,259,365,258,222,825,676,260,933,994,784,538,164,643,703,523,855,333,972,773,355,687,53,973,498,878,796,677,255,32,545,566,75,359,786,182,679,511,679,604,908,932,238,747,787,779,108,825,158,602,48,189,650,613,796,876,142,657,91,496,993,907,186,546,888,904,202,536,155,490,174,647,904,764,844,446,239,278,438,729,955,335,340,895,11,603,419,643,226,791,671,816,687,208,571,286,591,337,418,795,968,479,631,409,654,101,932,467,29,260,562,571,500,268,753,156,216,727,564,928,698,149,272,336,137,505,591,826,898,68,648,404,868,973,897,806,623,312,1,469,161,817,698,330,924,632,510,317,809,533,455,908,331,867,579,449,817,495,758,183,459,813,556,329,369,697,435,374,357,16,859,856,188,918,629,170,364,807,534,707,112,456,195,123,717,387,744,809,669,195,391,995,161,356,140,130,505,287,187,349,872,135,770,508,446,119,469,116,883,779,212,918,791,474,802,555,303,176,2,910,410,610,620,557,933,234,602,436,803,50,969,506,391,275,711,403,993,270,947,609,190,779,372,138,367,407,593,411,986,926,346,642,112,49,167,334,191,11,343,365,247,353,396,133,350,167,813,471,292,960,695,878,383,868,107,62,100,739,666,376,520,519,432,302,645,906,897,970,819,749,528,668,350,834,774,518,945,332,542,928,374,517,154,103,262,943,303,181,573,353,590,725,626,739,272,417,152,927,63,685,848,278,837,508,430,485,48,785,563,536,624,487,859,942,32,314,602,192,955,852,444,83,770,99,615,841,44,298,547,109,910,145,309,18,602,380,180,602,406,257,297,721,350,880,705,269,367,26,348,997,501,531,30,203,726,513,207,106,518,380,626,262,489,119,11,537,762,566,302,502,667,168,363,103,964,799,229,309,924,328,918,351,217,752,650,7,214,423,240,415,826,304,490,345,586,840,382,467,374,569,720,51,497,298,425,429,709,831,429,573,362,453,477,571,757,881,129,808,235,301,882,405,924,640,176,925,645,106,877,411,61,368,123,41,425,275,511,562,938,26,132,945,882,355,361,732,786,599,980,97,822,876,847,299,636,11,287,68,943,854,562,266,634,629,6,7,928,62,985,231,748,983,172,432,405,416,854,630,210,190,678,113,174,748,24,815,532,18,288,899,298,236,397,947,203,637,383,354,784,70,115,907,722,922,531,351,242,423,634,967,785,691,374,936,614,446,52,938,634,447,69,11,933,215,689,192,599,302,569,545,775,575,973,627,118,151,974,694,451,809,167,329,110,645,44,834,932,176,840,68,809,4,401,829,852,196,862,498,973,793,513,518,743,791,964,474,96,239,159,672,453,995,885,159,322,154,496,535,451,863,461,191,828,310,888,251,469,284,553,305,138,780,527,730,174,320,819,72,739,0,32,912,32,789,188,953,775,696,510,637,770,856,487,327,328,917,873,774,294,464,326,14,762,304,129,215,76,961,779,585,514,720,955,937,738,975,459,796,922,137,7,905,11,38,427,466,748,77,977,84,480,579,837,103,113,525,349,567,639,755,255,206,643,835,16,508,234,541,381,13,473,213,379,382,26,263,919,898,590,100,408,346,287,538,329,688,293,686,302,571,271,672,450,31,578,901,607,568,271,562,112,509,330,606,988,711,82,442,376,775,199,116,366,792,5,150,700,303,745,344,360,793,402,751,161,715,81,249,390,164,827,831,35,786,722,955,653,570,179,813,494,782,928,374,443,672,703,24,33,748,691,592,293,600,191,916,166,768,467", "178,721,262,148,462,203,76,595,420,959,77,500,396,297,931,748,506,316,953,923,47,148,366,107,492,1,603,878,50,931,43,734,781,666,462,34,818,35,922,549,461,986,986,743,922,285,286,791,851,918,281,712,214,710,585,458,248,21,562,733,515,417,109,165,433,420,943,918,253,391,403,30,372,299,729,257,411,17,474,568,694,490,185,707,747,488,593,588,320,612,724,308,172,237,432,114,301,392,994,25,544,790,816,923,339,102,18,905,607,374,585,15,29,460,664,430,353,158,523,798,161,296,302,668,120,670,726,220,877,503,382,53,99,884,911,186,324,61,845,228,319,203,820,592,824,715,142,71,762,4,487,308,955,867,396,470,975,372,322,781,738,416,38,454,288,95,54,392,448,662,13,471,124,186,273,541,2,104,737,854,19,740,251,941,755,660,163,744,139,909,316,334,964,611,118,606,819,518,720,861,907,617,109,814,567,419,273,872,898,704,701,1000,955,410,49,794,280,881,17,469,515,145,206,333,427,302,267,332,987,633,667,684,766,830,480,678,465,311,914,944,974,166,895,702,780,974,559,452,997,918,428,544,785,840,822,224,217,241,55,367,789,475,348,812,578,435,176,231,397,797,774,159,581,676,996,975,707,6,339,44,500,666,971,679,661,489,902,280,930,709,905,607,693,791,61,555,303,272,595,275,136,473,506,136,841,289,652,764,425,493,164,177,853,745,99,447,173,372,468,597,541,980,62,394,826,55,12,915,485,121,60,200,856,688,691,524,154,837,844,379,708,147,501,71,326,670,244,331,960,384,315,405,838,939,727,609,276,531,422,896,24,684,913,380,87,289,649,838,480,214,446,447,734,355,240,664,600,228,345,838,420,52,998,2,409,501,311,92,810,311,657,275,639,138,678,953,302,608,747,162,332,242,882,730,731,362,836,477,24,961,859,534,171,206,405,218,343,221,70,878,313,210,874,770,538,452,496,21,116,955,519,953,604,992,209,334,604,430,659,273,546,570,547,845,314,515,117,505,901,395,161,44,277,752,325,304,850,469,690,986,584,207,244,460,993,858,104,262,342,809,132,689,471,816,922,114,456,175,112,338,569,809,686,26,165,670,864,67,407,846,746,307,900,573,766,229,290,658,647,819,993,778,177,550,233,158,881,972,672,229,488,692,434,997,286,449,873,137,264,629,600,214,722,593,785,651,646,221,549,855,94,840,629,909,95,547,598,722,699,44,827,727,257,130,755,146,507,925,70,590,338,86,62,430,493,191,610,471,226,744,578,406,336,359,659,564,318,126,191,529,714,201,352,12,964,388,915,878,749,170,800,79,470,729,374,483,18,48,878,430,946,256,93,298,33,452,698,511,790,983,14,406,858,107,143,783,726,91,492,17,256,391,801,792,523,797,500,474,313,271,607,665,386,436,5,177,703,431,257,206,221,2,971,127,987,935,176,504,216,446,254,990,667,239,66,10,441,181,625,874,225,257,489,276,384,279,530,164,309,162,371,370,620,861,986,434,499,365,232,209,793,921,154,829,546,66,856,663,485,688,622,10,313,164,285,871,922,651,298,676,926,961,445,889,298,966,88,861,461,128,800,772,20,427,335,924,224,203,802,686,182,375,215,945,187,254,506,672,353,798,572,125,317,536,945,322,618,885,247,658,588,307,610,442,200,936,429,686,318,249,926,623,231,79,18,838,603,645,701,372,117,443,827,729,331,15,194,682,66,868,261,235,169,238,671,431,610,198,187,932,452,414,421,853,984,352,569,999,220,350,137,60,361,559,490,860,690,943,942,876,875,453,633,354,301,164,387,576,85,512,949,752,277,386,624,179,710,374,695,866,788,370,746,997,212,41,367,996,211,372,741,538,325,5,185,997,715,840,829,895,865,831,724,452,214,480,469,585,639,500,32,0,784,517,1,157,860,544,41,289,189,32,45,205,4,198,23,974,302,998,951,860,190,82,493,852,995,941,796,50,503,456,588,106,885,767,780,17,564,201,639,931,224,616,51,58,598,240,299,214,743,702,255,637,898,742,651,33,287,68,731,38,745,379,965,254,807,435,126,302,452,867,441,376,777,808,761,988,908,780,33,169,884,35,856,457,76,218,595,106,6,1000,396,413,10,273,607,470,900,943,728,472,74,77,144,736,590,846,530,816,887,166,106,417,505,790,856,382,344,214,775,657,598,931,95,219,534,369,25,222,701,253,181,639,188,51,227,907,999,745,58,951,349,622,771,45,64,748,874,636,954,289,588,106,270,84,186,328,318,89", "39,988,156,665,209,201,898,12,309,367,100,394,154,155,648,925,782,941,947,763,65,638,580,490,987,131,895,427,607,75,66,44,930,878,521,304,935,112,117,294,870,947,643,75,415,461,977,404,244,39,705,576,538,713,897,595,891,360,472,236,736,269,240,116,851,860,855,760,53,421,984,561,258,494,766,342,765,49,754,362,348,310,820,312,185,567,658,14,52,836,940,306,93,300,37,804,878,407,914,3,28,242,719,759,497,668,84,194,297,341,359,754,931,570,461,204,398,949,75,183,965,346,674,265,379,501,601,6,652,985,461,997,537,46,943,672,955,443,481,600,50,43,22,633,638,625,93,229,353,716,295,980,222,196,742,219,892,209,585,921,816,106,787,430,253,155,455,492,477,576,486,835,542,284,819,29,427,445,958,863,3,870,341,751,69,737,501,947,474,455,55,507,88,354,546,139,929,478,940,837,369,643,674,763,413,520,174,125,224,222,320,520,171,936,880,760,570,637,763,62,185,887,320,459,594,124,577,885,336,140,348,770,906,758,44,845,728,695,482,351,586,394,127,953,542,310,165,839,662,671,68,640,766,569,159,932,965,929,191,388,242,285,11,572,734,455,145,528,118,296,402,14,249,867,109,1,979,335,346,774,123,374,166,699,714,906,428,31,887,138,980,925,835,300,18,977,629,619,268,233,414,417,682,420,891,127,293,951,950,734,259,3,783,636,7,626,111,550,528,788,719,412,305,322,543,112,202,236,295,286,228,519,578,310,974,722,34,271,634,270,242,923,575,157,205,868,430,937,462,645,525,460,807,924,547,975,987,425,210,308,209,778,406,610,169,252,862,89,15,483,474,184,126,171,654,689,188,109,170,248,807,112,187,98,813,192,658,539,961,476,607,97,440,158,94,988,41,380,228,73,146,611,296,785,30,248,242,239,193,400,818,224,739,297,254,126,579,845,353,714,521,16,746,934,675,938,842,611,894,128,700,969,137,116,478,330,164,189,873,211,939,209,711,120,665,446,790,945,515,694,475,588,784,778,405,380,760,139,127,547,874,746,613,114,756,934,26,571,601,139,37,940,448,797,295,322,39,692,264,325,698,956,744,324,135,333,821,97,258,734,895,615,160,582,841,193,638,260,578,853,504,684,402,192,324,362,377,898,829,560,951,160,131,129,295,783,584,177,420,913,669,42,31,501,726,355,588,149,224,466,326,638,885,527,266,739,101,193,843,877,128,588,651,709,459,788,169,240,632,436,20,725,237,677,734,957,562,32,190,420,497,553,320,986,896,811,529,344,941,695,153,966,727,39,830,585,353,649,184,429,313,412,58,766,422,370,18,544,861,491,232,498,895,358,93,863,888,608,914,134,901,818,228,762,566,623,639,452,97,459,568,188,781,46,959,698,66,960,854,887,320,728,40,782,342,965,884,205,901,897,796,768,340,29,624,636,261,764,500,564,106,383,614,690,616,980,889,462,922,566,51,913,273,995,881,754,109,267,367,346,403,385,672,663,919,198,290,818,438,38,946,497,179,643,18,807,954,759,768,150,163,797,138,573,954,262,643,125,242,27,800,180,93,588,976,920,49,596,282,87,979,558,768,42,825,995,164,168,858,150,887,312,500,961,564,336,172,450,202,577,843,167,691,273,210,105,904,400,484,878,768,402,807,915,312,575,197,220,71,731,484,20,659,475,24,8,904,619,919,144,500,338,752,893,834,126,737,490,729,703,91,575,984,874,901,299,604,120,787,94,813,651,799,834,820,429,154,88,789,763,82,626,963,966,442,152,627,846,391,932,516,904,627,439,212,222,748,499,731,119,407,738,731,872,624,591,276,858,735,24,752,932,361,698,204,370,263,234,695,210,190,346,995,179,97,635,928,265,203,107,280,989,691,327,990,974,905,485,222,496,912,784,0,798,32,583,563,735,409,755,180,11,25,656,367,399,84,877,725,351,998,225,193,955,713,191,287,58,129,468,131,340,710,56,330,699,588,234,237,349,935,710,29,272,999,221,970,859,205,494,979,989,920,180,258,641,872,176,253,69,3,887,342,335,232,308,859,205,306,935,786,841,142,292,711,48,914,913,575,380,526,254,127,225,91,164,869,603,496,644,69,450,849,325,956,683,321,201,853,56,295,621,995,501,80,147,796,129,995,723,548,691,102,53,307,352,822,107,661,36,945,543,43,262,740,87,19,722,455,420,225,2,253,47,864,836,190,639,499,361,605,580,70,425,458,409,488,235,851,846,558,387,894,566,846,380,941,166,432,768", "873,887,978,866,996,59,172,256,790,842,214,805,855,590,19,835,206,875,916,152,469,454,724,815,667,725,811,758,34,584,287,173,895,988,490,318,689,992,99,765,105,587,854,531,392,937,671,906,592,757,952,887,336,800,663,230,858,561,920,374,407,121,545,245,323,536,252,405,970,801,596,782,580,817,902,756,473,186,868,870,409,685,51,97,620,172,209,777,533,664,634,592,568,219,739,576,410,305,950,569,719,987,421,746,7,218,696,123,925,592,543,730,583,18,734,276,344,420,964,946,816,666,566,818,57,721,425,487,133,429,498,727,335,327,437,889,669,445,795,953,368,620,37,238,245,267,358,860,413,496,236,482,872,229,288,877,461,419,416,661,466,965,359,412,860,397,309,48,67,887,790,898,508,857,839,623,956,400,907,372,524,87,619,385,56,412,584,713,487,797,517,755,58,541,975,44,767,654,567,560,845,400,417,453,170,542,406,296,254,667,645,801,517,717,635,8,914,633,457,259,651,41,963,235,818,261,755,710,346,476,679,776,428,586,165,74,99,357,784,513,288,520,266,780,818,379,211,747,540,672,920,359,127,162,932,147,67,511,385,256,936,546,232,730,884,752,512,759,671,783,672,994,272,486,518,735,473,647,914,664,856,449,233,788,287,304,132,807,195,795,627,586,514,511,419,432,184,609,111,920,180,543,990,459,491,846,930,162,971,255,810,313,273,506,2,856,73,950,987,350,524,854,891,138,154,897,21,618,65,603,204,44,390,525,215,932,411,355,402,217,448,426,589,102,527,112,755,627,206,558,833,665,748,71,481,6,911,12,902,973,87,285,925,966,996,970,60,954,368,120,962,301,235,454,344,942,693,284,546,236,294,887,918,254,161,749,853,264,660,821,83,425,551,562,180,886,567,381,357,700,430,621,434,701,888,960,945,329,213,939,143,807,239,264,845,938,464,652,106,581,666,561,396,418,383,251,660,9,450,264,370,569,118,37,417,395,362,480,8,984,333,298,491,399,611,252,52,173,683,17,80,753,708,382,696,62,776,189,955,378,559,738,807,46,1000,802,787,129,168,406,584,865,589,352,672,791,507,45,989,581,963,842,897,928,923,805,584,411,543,300,599,448,32,368,81,527,530,252,574,590,120,577,630,790,569,440,93,612,986,144,422,384,959,73,928,387,811,211,544,842,144,407,446,477,792,681,788,332,2,325,604,912,376,418,726,885,210,528,627,174,259,707,445,474,514,37,904,410,514,260,676,78,46,25,640,570,592,858,688,458,12,38,417,503,431,104,37,58,876,800,357,690,662,114,675,452,474,669,212,942,27,714,458,733,427,105,896,682,137,142,221,49,279,457,514,566,3,837,783,426,286,725,164,55,474,173,647,212,615,596,195,108,550,799,728,743,170,743,933,143,985,688,176,990,951,821,863,514,660,797,292,885,616,837,894,104,147,674,918,815,115,741,240,251,463,58,611,597,200,177,144,986,522,329,950,112,800,780,238,709,212,167,774,864,294,286,36,711,870,901,84,532,281,983,608,713,152,515,477,18,139,549,821,18,743,80,598,774,588,31,301,51,929,684,387,876,913,414,646,571,242,561,917,515,282,762,216,627,649,627,837,934,326,146,107,860,977,838,458,75,884,62,93,873,171,693,515,247,852,927,877,521,619,561,848,726,151,853,59,700,658,628,243,600,739,735,396,659,245,797,62,120,873,246,468,811,173,99,506,40,502,70,852,504,679,176,619,658,427,874,798,968,523,561,906,997,883,453,115,744,660,690,273,860,294,734,46,153,457,309,533,817,666,217,527,963,364,759,447,151,803,516,433,92,728,343,45,107,212,948,363,897,712,921,729,621,530,349,448,697,276,802,383,914,843,143,633,499,383,451,789,552,938,13,479,259,327,195,762,87,32,517,798,0,54,514,215,26,481,848,317,929,399,835,603,238,901,865,169,894,229,52,683,967,115,443,90,812,793,433,668,896,69,956,833,950,849,493,919,347,311,224,694,587,527,341,325,249,106,924,916,693,50,989,872,532,11,684,351,989,862,102,916,966,585,63,949,876,941,44,148,596,823,866,746,701,306,174,10,382,989,378,953,744,954,663,424,667,466,397,76,440,449,889,204,250,70,843,111,415,75,675,433,469,899,735,97,532,336,177,396,440,418,850,868,423,847,299,312,2,528,722,485,814,696,331,881,758,453,112,445,256,623,100,295,584,544,374,765,266,68,209,222,554,357,796,832,351,91,879,687,578,154,729,194,983,77,438,462,331", "601,318,879,855,989,764,816,972,497,474,518,824,947,925,194,61,208,304,659,854,69,968,166,509,385,697,894,932,757,806,84,962,176,138,474,873,419,527,648,884,143,886,944,951,355,404,754,297,982,521,260,673,252,975,706,293,379,883,227,873,964,743,205,297,310,651,478,42,87,744,866,546,247,295,456,136,21,21,343,477,284,820,486,143,978,745,490,144,956,750,344,640,733,917,79,84,797,692,163,74,84,571,680,254,551,516,124,999,145,685,414,72,725,4,236,752,360,347,852,545,411,327,787,51,883,652,252,63,612,19,780,561,100,973,132,32,613,884,486,115,894,91,234,216,942,165,162,469,499,27,792,247,526,466,347,964,828,612,810,241,82,711,477,412,147,664,689,674,103,121,947,303,100,976,644,299,522,169,381,827,728,16,804,202,249,919,831,869,178,846,979,143,228,660,378,881,818,171,498,686,880,663,641,405,455,241,599,355,88,862,414,972,243,410,400,84,335,366,346,742,494,3,971,618,215,754,669,613,293,10,491,535,666,78,260,625,604,562,848,588,176,316,439,726,531,859,151,152,108,936,589,655,714,612,474,409,668,785,751,546,355,513,408,620,840,493,377,256,367,920,329,40,31,847,358,875,179,820,389,509,584,999,829,820,392,312,303,489,4,437,329,275,338,279,390,292,929,516,329,901,175,790,328,189,608,604,469,961,743,944,968,155,878,714,706,234,446,419,90,612,777,727,884,386,151,226,981,134,452,748,94,587,671,219,242,444,768,450,45,969,826,423,311,846,797,90,855,945,403,977,62,789,964,981,552,210,660,128,877,974,737,679,623,869,830,983,94,38,737,959,52,937,162,42,76,374,678,539,317,408,24,460,680,95,729,441,899,892,664,720,95,155,329,683,9,314,127,650,821,473,597,327,542,985,111,278,921,762,628,780,741,641,207,365,141,480,541,379,341,581,109,780,420,107,692,70,34,923,838,380,612,203,50,759,494,816,659,887,120,151,201,21,729,360,891,833,986,883,574,753,160,417,861,455,443,932,523,448,310,786,497,577,300,368,710,154,411,762,886,535,696,38,757,521,490,785,575,485,891,310,899,304,201,678,378,236,629,238,321,957,534,379,722,64,69,215,847,482,669,475,332,172,450,612,140,440,617,926,866,335,833,475,761,194,174,769,385,120,249,734,102,141,999,650,62,948,476,425,462,515,373,969,475,101,535,155,12,548,269,453,891,267,913,832,61,856,951,671,69,433,162,100,169,490,478,359,468,467,548,91,788,185,969,273,203,904,662,762,471,510,32,252,245,683,555,532,184,90,26,434,302,469,971,792,41,734,277,360,214,855,10,898,563,889,928,366,555,110,72,842,103,174,994,358,436,935,1000,938,493,410,256,90,588,803,242,984,774,418,488,883,418,488,301,212,234,58,847,674,383,880,61,870,475,298,190,573,88,197,835,981,244,488,588,358,182,641,726,832,848,102,983,830,85,763,903,637,662,772,707,431,146,990,875,400,407,780,372,835,682,411,662,764,218,33,547,601,75,955,684,598,597,383,552,900,986,629,312,915,660,418,681,592,56,790,973,740,813,823,491,412,406,871,650,209,633,571,357,223,157,717,598,160,236,48,618,119,853,154,575,210,613,503,832,437,243,500,32,214,308,803,574,910,577,878,695,556,907,104,306,857,161,52,722,647,545,314,567,437,589,852,713,787,850,945,307,349,121,583,691,363,310,131,255,368,513,178,683,467,169,390,414,440,828,317,399,799,16,603,633,126,282,349,121,985,399,445,518,44,832,216,915,997,962,715,228,709,475,892,169,824,18,391,703,201,793,931,921,391,897,5,790,99,450,438,395,394,378,353,615,320,327,184,99,368,191,902,195,702,552,439,906,837,283,387,398,600,658,873,684,475,789,1,32,54,0,4,921,640,594,614,801,330,436,227,744,630,283,488,28,884,468,859,672,196,291,98,865,521,410,191,978,791,365,347,647,309,617,586,146,211,166,30,642,113,660,284,563,16,178,484,289,263,92,243,540,46,62,319,316,190,759,111,295,311,220,746,625,777,108,910,404,21,162,740,945,198,209,235,789,950,778,886,227,605,275,225,847,968,64,874,156,715,38,318,315,125,646,549,140,935,661,288,534,916,898,14,184,523,822,373,450,419,84,407,256,990,921,29,349,595,724,982,344,337,92,246,743,15,541,468,893,384,92,963,178,180,869,43,519,727,988,526,450,741,742,68,446,38,469,930,687,417,396,504,292,338,867,844,997,778", "741,723,623,267,491,616,165,462,496,385,657,490,907,870,587,343,965,954,462,424,363,220,340,969,912,738,434,537,899,382,766,479,167,135,749,633,391,265,855,768,958,959,2,739,922,92,957,773,120,935,161,537,592,615,670,377,780,942,966,473,503,625,636,236,467,979,191,929,821,472,511,754,374,713,524,912,333,795,66,32,907,625,222,678,876,109,508,664,848,14,599,437,558,962,402,832,87,749,334,429,669,839,693,676,825,894,958,501,146,204,285,986,146,577,708,266,618,779,441,767,476,50,212,29,346,643,988,909,181,916,570,264,980,231,227,40,778,659,651,5,70,951,908,854,736,713,163,700,56,830,661,9,148,162,669,256,537,644,838,534,31,49,451,704,101,393,322,255,997,325,349,306,857,588,141,782,31,948,411,782,84,148,941,95,71,372,724,415,959,570,232,746,175,699,647,825,708,341,425,562,837,51,167,778,788,793,765,517,162,104,765,722,553,271,839,35,467,963,162,349,109,665,70,515,903,536,709,938,945,835,810,498,378,706,627,505,161,852,837,125,426,274,839,292,694,529,298,227,914,193,906,256,734,993,124,977,278,594,322,374,80,843,773,737,458,881,39,988,716,480,469,273,128,748,835,602,923,155,76,339,546,837,133,86,766,412,306,166,244,973,682,775,54,268,383,678,113,845,864,272,27,725,660,817,817,138,759,959,301,981,730,331,264,444,252,270,487,366,308,701,734,349,979,504,567,635,927,360,198,776,986,277,736,956,537,635,539,419,867,980,485,473,563,443,891,145,648,958,546,45,529,20,357,177,404,930,295,7,846,819,730,577,873,409,705,343,983,329,16,675,272,29,575,253,624,635,467,857,862,94,630,735,933,740,827,32,928,337,689,676,295,173,945,129,288,864,397,30,118,674,310,11,517,195,287,145,336,190,441,888,118,672,847,318,765,47,577,789,955,55,979,977,517,172,852,417,118,681,441,763,384,150,129,880,592,757,36,409,153,820,432,180,604,470,689,919,548,369,473,271,458,663,302,620,824,100,85,574,487,333,480,655,384,488,111,985,654,606,974,251,356,823,913,105,641,359,595,756,981,759,216,11,942,971,127,733,807,865,458,342,902,387,317,287,471,922,511,316,885,353,516,921,86,650,102,695,238,567,331,1,114,616,844,135,87,222,851,764,73,268,463,6,479,198,989,135,822,263,38,911,34,233,470,937,716,8,531,434,544,167,511,682,30,527,958,26,892,825,488,860,379,906,493,414,715,916,137,755,38,22,484,343,373,782,884,425,696,549,958,302,932,116,26,963,955,555,165,61,700,79,706,317,92,218,42,534,887,748,947,129,182,527,625,459,297,109,579,83,889,899,577,737,275,610,600,571,83,488,723,893,747,686,756,344,166,624,556,186,19,655,641,75,228,390,261,956,252,46,884,370,703,458,677,161,445,47,934,624,31,11,594,350,606,342,443,275,658,952,727,899,645,839,976,701,696,31,382,477,845,888,960,27,203,59,275,655,201,628,906,693,609,281,701,552,316,966,693,904,830,51,43,29,415,820,192,857,838,764,782,228,285,55,770,548,534,943,407,616,537,427,993,648,194,281,536,691,929,161,561,88,429,102,757,53,297,285,547,6,489,928,258,916,858,467,428,665,809,565,124,208,152,199,379,233,117,879,66,366,732,57,173,200,147,864,19,842,532,835,672,754,368,402,921,16,609,796,756,715,689,847,352,210,477,819,145,239,986,528,530,978,894,421,792,104,884,469,312,556,590,401,817,668,79,164,691,791,327,974,714,525,474,766,133,308,96,648,357,522,365,669,61,87,716,690,85,46,680,877,486,462,293,761,54,756,69,511,417,551,179,896,182,776,373,23,558,347,508,387,323,960,364,703,465,937,830,296,5,856,100,295,188,157,583,514,4,0,609,592,339,76,137,709,186,942,805,546,20,414,284,232,509,933,959,806,346,991,926,788,768,373,909,550,797,319,757,543,33,767,778,410,400,328,959,451,127,528,211,768,421,627,550,710,755,170,569,472,860,192,384,925,326,822,666,347,942,118,251,128,512,359,565,59,389,427,180,819,933,624,601,115,382,723,631,17,500,582,789,36,976,655,43,512,452,319,753,746,726,482,156,237,545,439,505,11,667,411,873,399,668,626,341,392,578,944,320,834,630,441,915,808,673,135,31,574,992,540,383,847,743,379,728,332,427,368,324,237,292,931,935,635,647,60,727,279,4,700,462,811,130,196,203,583,510,19,299,126,946,311,933,227", "88,560,634,417,232,170,36,173,291,76,476,40,725,788,318,9,497,870,61,248,19,606,677,74,778,984,234,627,232,769,138,398,189,727,743,107,468,640,664,983,775,213,522,303,318,690,687,23,278,513,149,11,870,217,724,796,663,484,409,388,854,924,501,937,467,328,431,290,304,324,617,382,335,955,326,904,231,63,786,557,890,11,117,367,167,27,488,369,927,897,613,294,324,546,505,583,695,59,207,34,600,801,64,324,345,574,757,924,399,635,648,207,344,773,56,783,58,858,924,719,584,134,126,920,565,683,139,720,654,974,97,60,205,719,126,911,144,34,976,685,420,701,449,392,467,524,175,971,926,377,126,859,398,844,957,634,916,873,893,476,733,545,409,839,429,454,405,777,490,384,785,205,127,786,479,993,134,230,410,491,271,820,263,954,311,487,951,751,200,3,859,893,130,745,485,896,248,605,949,985,676,808,952,363,106,230,616,950,18,996,165,174,269,704,948,544,561,93,548,275,215,925,277,296,891,96,319,574,62,368,934,696,754,750,434,512,293,145,883,473,270,831,964,786,582,929,276,75,391,498,806,313,468,291,387,600,657,908,128,507,323,802,656,302,628,855,954,965,168,644,266,613,925,55,400,511,4,570,355,444,580,191,943,903,90,499,292,442,677,487,516,587,814,939,613,599,590,98,255,829,687,574,995,962,874,940,597,254,602,500,368,50,909,67,915,71,690,993,462,800,929,584,867,550,285,924,922,146,435,897,105,810,698,366,784,25,160,158,689,628,526,335,972,878,625,85,327,812,591,540,689,569,437,273,457,928,578,728,521,154,833,574,555,680,637,697,742,586,399,666,438,333,648,620,312,614,743,418,974,730,44,248,808,34,186,262,91,35,189,594,273,165,984,891,432,687,310,518,254,753,961,611,931,250,820,133,362,895,879,925,806,989,765,924,734,821,38,80,245,627,904,619,60,968,108,129,790,612,95,947,631,55,250,304,714,514,485,740,232,712,862,535,902,497,276,501,347,670,142,724,507,904,479,63,454,277,662,167,945,442,660,263,621,956,189,806,35,298,672,819,831,761,260,225,582,814,509,914,14,744,568,200,598,68,373,696,54,262,832,498,469,728,381,909,46,974,300,672,676,535,657,782,933,715,76,676,27,968,542,615,612,150,530,850,845,271,943,328,817,663,175,946,166,839,675,492,505,112,172,133,620,591,564,663,302,538,170,853,859,169,636,354,648,52,423,708,499,668,90,23,616,92,426,178,863,8,514,489,979,146,715,776,957,670,220,873,514,847,44,199,574,985,97,596,122,748,702,556,250,181,415,440,510,743,870,922,23,236,243,542,439,132,466,164,905,339,775,667,705,531,690,302,540,870,215,288,35,678,634,567,389,248,971,460,243,407,38,688,427,730,201,620,979,520,282,36,801,427,361,824,567,980,584,714,378,843,593,757,947,837,690,731,83,599,881,528,303,427,363,213,4,836,642,914,789,854,140,461,838,198,284,164,74,994,431,311,885,666,495,794,901,637,489,474,778,261,207,712,903,531,654,450,458,626,670,364,753,739,321,914,439,787,236,573,65,806,23,551,413,714,94,552,372,113,31,84,7,147,319,889,337,715,841,270,999,586,954,230,52,130,486,53,556,604,119,13,857,112,550,630,649,760,849,755,741,103,246,711,16,682,225,627,54,26,596,982,84,855,61,850,700,340,469,887,593,699,242,159,587,99,55,616,951,306,907,998,560,76,812,160,115,987,307,810,993,518,941,680,265,927,745,283,136,561,680,40,27,840,40,834,203,517,308,949,242,74,283,571,149,290,441,891,240,309,970,458,888,236,241,286,706,581,826,982,219,536,311,229,397,558,699,456,547,7,205,766,270,465,282,183,246,296,355,802,978,231,9,546,69,824,953,860,563,215,921,609,0,219,138,470,528,998,324,564,232,867,308,646,146,210,270,32,839,668,398,26,665,236,776,209,522,188,463,433,426,13,191,394,362,196,768,690,194,550,899,991,40,860,774,883,194,713,986,403,388,945,929,917,780,966,504,39,28,786,53,448,390,935,748,367,224,303,42,958,674,229,440,940,316,382,148,190,139,467,426,330,896,563,677,462,818,721,56,584,282,725,837,508,77,223,282,44,114,65,33,691,108,111,440,607,174,421,741,958,814,491,66,262,927,995,160,692,78,567,361,275,258,109,913,960,409,924,143,680,930,505,897,527,64,801,920,953,187,898,265,231,974,303,762,465,393,26,610,744,840,646,876,724,74,890", "690,688,258,553,39,292,51,377,830,171,484,236,980,161,379,526,663,573,219,888,65,752,237,485,183,166,597,331,415,534,840,967,700,734,603,664,785,944,767,854,82,41,274,493,381,979,776,599,365,549,510,448,511,380,144,682,868,724,78,439,549,513,122,615,417,567,732,387,16,821,859,532,891,161,21,466,244,551,842,901,939,879,699,816,705,361,462,483,467,170,582,194,549,566,539,445,724,325,824,262,300,11,376,963,155,884,461,779,585,129,557,107,533,977,174,252,424,191,586,931,596,567,821,823,870,8,718,222,943,929,788,837,9,544,59,108,437,528,645,907,435,825,488,94,262,250,64,395,980,768,686,191,407,925,691,715,710,430,880,562,683,819,711,885,597,392,422,237,45,115,700,363,137,623,223,67,195,312,838,161,474,958,298,49,712,191,26,938,670,838,81,270,157,835,916,633,664,736,253,899,961,392,421,211,762,870,546,304,326,59,672,386,34,245,634,66,169,998,276,969,732,531,455,711,361,699,800,894,290,793,243,37,42,114,37,255,356,949,787,166,890,576,595,575,901,685,106,222,825,301,189,57,527,189,560,296,152,764,208,872,447,735,770,691,668,603,586,22,11,295,767,488,251,52,653,546,675,559,777,979,760,909,620,201,82,664,73,646,7,425,407,533,557,537,600,421,302,206,705,3,55,339,22,697,214,65,857,623,921,762,357,192,539,901,583,950,701,81,877,996,35,272,931,45,571,880,613,831,331,827,142,800,700,707,884,393,290,946,881,997,411,208,37,89,928,758,544,687,414,679,602,301,381,676,389,438,283,781,92,670,477,438,43,62,267,103,141,866,988,450,993,519,177,954,799,642,349,44,710,814,956,606,958,92,304,879,407,892,106,594,812,753,30,912,43,874,49,920,527,721,383,785,214,141,701,854,353,334,507,141,798,469,261,13,846,914,939,398,249,163,262,28,975,967,502,927,116,925,186,286,168,183,893,31,719,91,498,951,510,479,502,526,207,720,18,27,575,53,456,108,968,930,201,102,367,697,152,349,107,505,399,353,541,42,446,172,11,646,582,889,99,878,997,47,869,248,166,460,897,293,706,994,579,75,634,312,517,687,180,919,158,553,547,994,861,989,466,886,130,745,999,909,763,917,571,263,684,378,548,213,897,896,291,405,772,317,530,675,674,285,113,229,524,238,624,838,625,347,700,213,647,826,530,229,450,741,874,99,124,568,420,634,965,50,641,509,455,716,925,682,986,595,973,694,8,467,802,184,109,301,413,570,167,305,300,10,606,333,889,523,515,864,159,788,579,643,569,384,332,814,379,663,393,631,395,368,344,39,324,410,278,854,830,876,637,361,974,140,413,856,420,95,689,180,187,423,703,970,466,582,813,249,85,880,925,915,825,244,631,15,327,436,890,769,717,585,877,781,97,118,300,133,233,489,508,530,672,493,637,928,820,270,277,417,722,799,954,46,560,232,366,882,481,232,839,504,819,77,482,720,734,123,457,236,8,380,874,600,616,900,786,932,216,253,807,477,647,642,763,782,38,89,232,332,636,924,914,33,429,668,165,991,391,472,419,931,289,846,721,469,333,67,546,139,622,383,836,317,444,361,345,65,501,399,851,826,33,105,426,234,746,74,550,598,984,267,539,843,908,751,604,868,943,779,1000,690,385,70,469,549,86,914,822,618,393,305,579,467,530,784,515,498,800,164,812,675,37,588,194,25,316,831,675,799,545,68,935,188,673,413,505,79,390,898,865,125,397,964,830,735,254,482,525,285,333,253,645,724,397,467,611,618,540,661,272,591,765,784,503,232,346,101,585,581,570,444,569,522,693,695,272,2,885,719,404,462,723,579,833,773,585,5,243,986,571,419,291,542,900,215,185,171,608,931,973,963,863,315,581,133,775,544,735,26,640,592,219,0,266,106,565,151,334,592,182,811,492,825,987,854,143,572,352,13,318,289,515,92,468,65,967,159,325,963,580,925,778,14,24,449,816,55,862,632,789,643,67,983,261,459,861,307,522,574,477,100,538,512,106,247,135,905,935,457,826,65,419,822,341,194,871,524,157,116,196,971,539,826,535,75,859,563,146,774,524,770,802,269,939,162,630,939,189,109,957,390,967,463,432,673,831,518,35,234,199,20,553,307,524,358,74,68,750,172,339,249,195,84,620,57,423,988,619,25,736,13,540,333,125,933,705,909,920,490,114,48,251,644,320,853,229,204,797,986,281,819,330,163,933,866,512,130,180,77,808,272,277,747,527,11", "295,644,805,94,221,254,509,969,948,494,39,571,23,549,463,377,816,555,764,804,986,6,202,810,24,24,850,246,784,155,339,669,670,68,264,107,80,926,859,170,592,180,717,89,753,994,272,76,860,466,588,633,481,496,920,359,891,457,135,963,863,953,688,421,946,973,600,354,879,359,672,364,758,365,260,280,175,301,762,854,184,550,832,267,997,995,551,94,283,949,802,288,157,550,529,324,712,543,740,45,50,684,901,643,326,615,821,35,716,885,75,837,953,520,661,954,273,116,334,977,77,470,752,845,283,838,638,224,527,497,421,438,7,856,453,170,236,976,997,92,671,403,230,832,70,503,926,826,766,234,510,735,835,23,7,544,861,610,908,795,410,624,54,499,408,883,627,595,630,171,919,925,244,431,236,408,98,315,484,582,98,12,224,752,789,139,802,421,968,336,761,817,503,950,17,243,598,479,546,545,79,501,336,731,735,649,245,274,433,379,203,563,781,627,667,67,104,843,365,360,946,282,550,242,278,551,52,326,961,309,771,405,762,341,165,881,27,409,344,295,403,167,258,263,972,155,834,271,746,730,620,65,590,899,213,216,946,286,214,814,188,325,100,69,790,986,441,703,286,892,220,484,608,631,951,327,23,920,275,597,182,309,406,840,650,893,283,170,342,826,696,212,962,57,901,769,949,71,248,451,34,630,472,106,856,632,496,721,154,955,542,602,689,772,105,634,318,241,831,863,914,895,836,406,5,975,100,842,298,821,177,222,390,624,244,49,74,26,119,882,696,653,237,654,292,285,458,277,333,920,560,858,660,725,572,710,431,69,517,318,436,26,89,440,126,175,74,367,6,432,758,299,144,59,892,370,811,735,668,957,33,694,578,475,387,66,851,142,152,948,621,156,130,505,508,790,39,856,96,891,570,323,929,823,981,968,827,150,593,40,817,933,773,593,297,849,126,875,942,710,387,544,492,679,275,209,529,390,931,830,797,625,145,558,169,272,918,441,453,453,516,642,659,244,788,800,471,524,766,314,672,610,976,404,95,684,771,427,667,21,314,509,916,932,903,743,812,202,86,368,813,353,667,605,346,538,895,76,590,332,352,113,521,824,485,119,145,226,931,691,312,301,345,189,294,781,427,866,792,521,718,99,143,874,505,83,794,172,351,349,296,601,834,300,367,2,564,35,572,298,316,870,124,768,226,305,702,244,835,995,548,288,417,51,151,621,367,199,846,284,712,970,695,496,83,879,47,389,612,26,329,665,207,934,502,248,428,462,175,236,910,401,440,286,710,451,327,280,184,175,727,128,475,390,446,127,260,999,258,736,406,681,19,472,850,183,278,769,263,147,375,525,493,924,312,57,750,914,493,775,771,721,159,522,484,533,686,268,648,253,51,206,271,733,25,237,267,641,389,698,652,533,578,848,176,500,17,289,39,571,230,319,128,653,466,259,164,691,680,844,887,651,625,692,204,579,493,210,873,436,523,966,347,761,351,420,223,447,196,859,764,272,459,107,369,891,571,725,271,576,443,772,692,504,399,358,852,928,466,45,769,429,172,400,299,273,442,55,232,888,763,87,78,235,333,983,869,942,204,426,526,198,556,75,930,50,221,282,254,968,565,659,882,915,265,779,223,61,113,587,391,370,342,883,393,96,122,285,949,57,651,678,828,384,823,11,305,385,528,880,231,481,717,694,358,124,20,751,964,552,399,178,490,584,142,568,660,764,57,493,815,701,47,577,794,602,321,745,740,737,968,319,634,159,269,417,348,499,527,120,930,307,600,349,773,874,583,123,713,920,991,8,291,717,232,644,147,447,320,242,385,368,986,356,206,544,59,348,838,94,141,302,877,160,763,592,868,536,948,269,549,298,659,371,18,609,49,251,883,72,407,57,420,781,752,531,197,504,989,285,696,41,409,481,594,339,138,266,0,268,233,564,152,666,797,800,533,774,132,141,610,393,368,38,325,45,806,576,910,462,243,230,558,37,712,57,844,422,910,339,50,985,109,265,561,621,196,893,418,157,873,7,818,395,837,855,859,955,25,15,5,239,980,193,972,514,512,984,959,644,446,44,686,176,909,465,259,996,165,437,931,341,744,495,76,959,43,194,420,210,575,991,420,696,286,237,431,466,493,712,527,417,624,895,920,919,322,869,753,709,62,388,327,199,562,317,830,367,794,903,152,907,256,230,981,446,618,494,608,24,703,879,81,347,536,323,777,169,417,978,549,1000,130,499,710,442,48,311,11,506,363,905,486,293,377,301,486,403,84,213", "272,44,64,423,962,306,123,277,226,751,39,662,955,951,416,305,411,551,890,174,56,144,920,831,219,520,784,575,796,38,184,543,941,370,834,977,530,118,583,119,634,585,834,416,763,65,957,912,646,346,690,781,8,492,201,538,842,659,146,967,693,564,601,183,445,525,416,736,891,395,477,564,231,234,118,540,479,446,25,898,646,720,387,902,699,474,88,464,758,878,80,67,49,862,373,75,910,718,508,552,263,229,804,784,933,751,392,81,697,856,38,817,746,399,381,630,377,381,356,930,418,282,480,373,359,419,308,944,833,333,136,528,88,369,716,115,743,657,77,717,417,283,476,711,789,763,693,142,94,197,522,933,150,713,918,476,556,374,717,537,577,837,382,915,980,513,848,725,552,3,99,211,634,386,505,695,234,205,157,420,565,818,332,106,549,918,541,386,45,458,366,994,105,839,145,251,90,19,694,954,416,193,679,160,451,758,426,816,682,609,909,484,517,345,276,78,172,585,90,541,536,558,543,294,469,744,74,219,285,285,617,828,498,828,192,381,430,510,69,450,380,231,261,352,276,520,184,114,531,874,591,750,523,892,12,84,856,708,641,297,287,833,145,904,669,341,450,586,348,977,352,487,180,376,525,380,897,344,750,668,381,110,305,95,884,147,216,598,300,92,414,804,470,562,338,186,379,117,225,13,854,765,51,975,73,391,808,554,836,102,48,485,650,358,987,787,658,287,139,295,815,555,947,2,349,735,15,116,192,630,368,253,189,13,7,296,446,734,604,354,302,875,365,480,290,308,256,138,906,501,545,593,650,392,448,364,341,330,324,337,55,701,65,300,18,831,896,651,200,470,547,282,145,876,761,804,498,634,550,498,447,229,661,667,940,991,451,382,231,885,420,544,710,165,952,244,61,616,126,250,306,548,918,194,66,271,161,244,875,392,988,951,115,990,658,459,333,656,454,806,486,562,251,518,539,613,234,887,288,801,194,272,278,946,174,241,563,641,588,560,818,791,548,703,144,633,834,616,903,629,409,409,352,991,470,522,631,345,423,155,837,160,123,399,60,453,628,20,750,128,50,231,559,42,799,924,216,51,779,216,135,236,879,970,621,390,366,825,387,237,236,336,726,596,937,560,12,826,309,218,282,343,294,152,863,60,70,714,154,58,248,330,248,246,720,860,973,82,20,145,486,778,970,107,415,758,581,794,759,822,524,495,508,91,626,498,327,698,775,710,629,116,538,661,443,768,514,645,208,191,947,231,316,275,824,889,686,750,719,319,300,266,331,862,705,59,40,130,811,720,973,860,861,169,882,28,20,340,508,226,757,356,477,520,240,183,362,577,182,763,44,803,52,852,345,177,777,135,922,881,754,16,22,117,911,471,165,551,381,532,377,550,785,193,25,371,592,238,906,254,821,628,696,987,897,835,120,390,691,841,369,358,762,968,864,394,767,202,666,403,7,175,967,264,348,722,353,534,969,679,540,512,940,768,616,752,445,765,59,323,416,362,322,273,464,966,306,773,842,204,543,718,438,577,832,765,841,743,766,168,206,850,991,796,898,741,650,486,793,157,575,514,208,199,927,408,832,290,722,601,439,907,481,484,478,167,556,683,96,991,787,212,391,178,96,289,910,135,70,807,844,800,531,944,7,943,809,471,801,994,464,633,377,460,393,363,355,831,320,775,940,912,273,272,482,810,877,311,691,612,23,728,726,784,125,423,727,759,99,324,895,330,855,933,601,392,40,523,675,64,965,397,944,42,811,531,890,326,758,742,378,484,278,641,931,644,176,816,820,101,514,930,333,270,105,705,546,318,448,193,974,672,98,193,771,176,446,374,708,785,233,945,464,125,770,575,547,460,319,888,697,798,790,412,817,817,868,531,463,71,225,161,455,677,826,642,334,614,319,616,510,289,755,848,614,76,470,106,268,0,196,465,761,16,537,858,628,498,773,250,738,218,825,581,138,87,153,208,466,811,539,563,696,572,923,781,718,531,670,969,570,225,595,48,622,839,299,893,469,235,454,261,850,805,151,151,867,850,60,243,516,78,552,636,988,233,731,556,367,296,270,846,920,596,94,847,939,531,365,789,471,676,83,511,963,37,397,952,648,388,303,648,333,887,197,735,855,283,880,327,712,177,544,70,781,143,589,993,811,477,296,348,961,796,623,778,561,730,922,306,913,296,285,820,162,718,899,944,81,484,591,23,850,304,616,671,628,639,676,715,522,988,365,917,171,664,546,631,173,249,823,27,173,993,204,700,584,216,569,374", "189,946,603,992,152,43,198,295,136,248,172,880,200,204,586,356,939,429,769,148,562,601,193,146,836,562,722,262,299,185,638,115,488,2,555,294,376,317,251,292,820,959,215,583,371,671,480,384,843,148,967,838,469,777,582,707,299,16,462,835,323,76,979,983,294,725,233,598,764,381,994,230,300,727,864,10,818,725,97,922,912,18,491,462,792,378,321,214,286,79,327,983,630,110,557,824,565,284,190,403,10,291,328,695,535,378,822,175,657,577,218,780,154,223,106,969,694,499,325,904,891,717,313,273,603,950,339,143,31,97,329,785,817,766,786,998,320,864,543,216,129,482,635,55,406,664,227,228,660,624,917,732,146,690,899,801,925,326,677,609,21,93,438,30,481,648,951,376,662,928,694,195,113,157,506,608,549,509,140,342,161,912,282,550,78,857,656,268,709,629,221,75,238,592,671,289,721,962,991,422,652,347,7,751,147,380,24,335,739,714,100,141,631,256,264,393,238,955,55,95,297,22,239,249,44,824,794,722,238,121,50,60,203,880,535,403,689,515,86,610,350,684,876,704,808,5,101,289,610,81,82,397,164,161,778,458,786,742,79,579,99,593,381,141,900,310,599,264,610,196,546,482,301,13,478,659,408,845,651,568,265,175,170,280,323,934,583,505,286,265,65,327,434,467,672,482,913,108,419,777,107,369,535,687,198,740,889,535,160,134,660,958,164,108,33,316,198,348,507,560,928,90,715,979,580,117,480,378,55,926,584,339,701,677,262,915,700,821,805,509,230,659,659,156,820,743,584,452,258,847,365,536,283,624,332,876,885,829,656,28,137,720,293,570,188,191,415,72,249,743,849,754,636,185,231,99,591,761,827,405,392,644,623,437,771,896,505,188,542,950,478,988,609,239,319,923,914,545,527,820,175,716,127,587,505,934,123,729,386,367,893,755,730,921,478,562,168,284,115,724,686,798,114,690,184,540,43,404,583,24,519,753,139,115,909,358,312,850,624,810,350,126,70,763,855,282,586,846,454,614,542,678,421,441,345,811,813,692,739,119,952,984,726,526,630,802,492,311,844,345,188,138,29,184,29,875,533,835,242,356,382,914,249,376,483,464,698,85,283,408,349,168,414,450,380,74,629,275,996,47,846,118,775,195,383,159,704,687,59,145,183,722,883,922,244,657,545,844,339,360,586,965,985,569,132,283,825,504,281,219,554,938,398,720,404,125,770,284,656,8,662,191,133,928,943,548,393,433,731,764,838,963,394,121,813,658,200,862,725,650,762,438,733,245,368,741,847,571,158,565,256,978,344,413,68,205,781,275,297,805,47,919,903,969,627,574,180,478,508,275,712,451,493,419,751,951,911,271,142,268,202,432,967,228,773,478,180,530,269,437,397,573,673,955,937,404,67,336,456,584,25,963,714,403,137,564,481,307,183,94,113,741,397,121,139,117,638,207,119,50,511,944,38,759,869,204,100,376,273,319,70,654,184,228,930,820,454,887,222,688,150,834,602,167,505,130,58,174,362,848,233,817,720,453,90,869,912,343,424,25,268,272,157,792,553,281,933,940,971,964,650,900,35,96,528,41,552,742,293,469,922,742,42,393,896,573,478,623,362,976,341,437,927,728,878,918,228,761,98,234,288,137,746,386,115,377,356,393,26,589,503,308,977,429,702,198,400,404,824,318,165,473,574,522,413,413,788,754,112,894,840,314,639,599,226,962,540,671,930,298,622,898,476,159,891,630,285,902,901,245,470,921,850,718,585,866,693,137,585,672,455,536,447,175,184,745,193,155,414,717,728,368,97,434,444,993,914,420,876,767,792,236,101,78,520,726,917,181,230,306,661,432,576,214,786,337,501,559,993,318,362,809,161,666,718,858,622,783,392,570,713,654,470,132,507,192,540,984,599,226,637,189,180,317,801,137,528,565,233,196,0,249,414,23,707,56,339,492,165,33,601,431,465,721,536,711,124,375,581,960,576,486,136,698,516,628,182,702,212,120,414,80,294,901,969,471,357,303,91,520,601,736,648,124,715,510,707,15,185,844,918,397,40,103,672,630,360,733,848,768,568,392,891,533,689,461,579,153,62,78,633,852,732,927,582,957,986,48,805,761,708,117,181,293,665,24,550,969,176,798,801,415,961,49,131,863,343,591,925,865,872,739,531,154,135,833,68,218,445,557,10,4,579,639,638,252,486,996,647,329,373,339,272,437,608,769,363,609,83,379,670,43,677,336,692,459,67,184,150,375,833,921,558,428,707,188,951,651,916,274", "397,988,919,97,667,547,645,103,903,596,880,304,875,545,130,404,687,47,997,103,276,392,917,744,480,21,913,496,80,49,366,871,14,720,480,604,194,662,192,915,617,239,821,336,334,146,732,747,39,493,467,603,683,20,512,741,619,669,128,420,798,464,861,380,612,226,801,316,494,558,180,599,830,688,753,879,153,379,305,373,69,391,134,963,961,32,424,182,803,621,465,299,857,443,428,855,856,261,465,453,567,878,225,359,693,832,159,815,530,499,145,755,420,785,71,787,988,394,999,344,918,908,248,221,844,247,919,247,698,982,839,99,1,306,837,871,169,798,837,992,124,139,880,826,656,735,336,150,903,609,76,756,653,420,104,497,381,108,645,103,836,819,855,789,364,535,882,411,742,816,784,826,443,128,495,771,575,749,471,293,302,991,567,390,66,357,582,114,778,877,278,520,597,353,534,984,845,881,646,838,606,117,74,623,273,285,64,156,310,703,222,435,427,540,163,753,847,539,329,227,594,659,15,162,307,126,131,996,526,36,758,936,869,859,261,283,88,286,459,21,638,120,628,94,670,696,578,656,611,591,877,482,916,884,140,602,197,962,159,568,642,941,9,102,308,227,488,487,308,328,335,399,366,187,648,472,992,835,3,913,219,615,636,391,367,170,693,155,246,106,500,944,967,250,937,620,438,749,154,46,539,972,242,818,917,382,251,185,881,231,345,551,925,462,872,509,44,25,902,50,523,860,331,134,474,61,348,52,528,62,785,764,582,658,696,762,308,287,164,406,300,772,313,23,888,816,278,98,949,920,502,493,117,918,457,832,701,674,729,51,111,159,353,839,65,456,518,365,990,206,954,504,499,393,131,166,423,711,90,649,916,494,150,338,838,23,613,786,783,45,97,52,905,718,105,881,719,538,398,424,206,857,692,83,587,597,574,767,278,238,470,593,635,245,246,98,851,986,50,398,170,765,797,926,980,334,455,48,6,529,570,941,636,325,180,120,110,542,771,858,515,2,202,569,218,856,709,795,322,760,50,285,720,884,763,681,850,892,690,84,492,317,384,772,558,579,324,768,689,738,971,185,20,445,387,166,465,710,967,668,81,883,838,490,296,153,332,786,620,786,161,781,633,784,635,913,636,844,130,89,406,167,946,612,192,912,451,674,633,946,113,735,634,742,318,254,512,40,143,494,140,64,811,775,173,397,634,412,271,793,5,395,384,471,898,918,795,997,88,3,978,494,272,313,175,252,739,194,21,485,376,992,265,622,499,147,469,328,154,824,651,973,595,630,318,766,454,464,52,999,824,814,331,285,828,96,909,559,744,571,285,912,761,448,618,838,504,234,842,854,819,577,777,421,382,975,151,282,845,37,865,974,771,19,781,775,490,244,208,366,5,788,942,50,694,288,106,712,82,81,660,667,636,671,137,502,61,96,401,172,947,401,637,558,734,64,154,882,280,581,81,322,556,731,489,309,56,28,171,652,408,158,99,415,769,400,784,49,816,109,175,253,650,160,907,34,785,980,604,343,223,283,551,103,4,770,664,935,974,767,609,82,800,647,869,363,224,612,481,68,626,250,557,270,997,341,601,332,216,530,277,990,679,930,411,986,108,856,864,604,650,685,605,593,81,82,582,314,86,723,142,207,587,734,458,155,450,584,970,383,568,281,262,204,221,778,129,125,649,517,464,410,605,726,734,489,710,656,784,971,128,451,808,289,122,816,993,337,209,163,221,394,436,800,126,382,18,295,831,33,703,57,689,809,441,408,395,334,169,570,546,756,420,623,295,822,200,361,807,905,966,172,438,581,112,447,722,263,639,459,944,354,96,205,707,268,858,73,987,421,328,411,645,143,779,491,181,666,617,658,47,419,144,39,125,156,220,385,443,194,32,610,965,751,264,788,771,650,419,518,770,32,11,929,330,709,998,151,564,465,249,0,959,913,803,918,111,915,161,986,568,340,869,759,727,100,97,123,102,452,89,875,45,359,775,97,216,495,188,449,268,745,260,940,191,782,208,970,373,120,215,132,348,354,443,986,689,148,915,900,689,569,378,329,110,525,250,566,925,806,845,445,423,754,958,324,431,733,425,519,372,446,229,364,326,223,348,57,298,115,339,633,30,784,521,67,421,533,59,753,852,185,98,128,813,994,67,224,664,210,877,590,565,46,202,574,384,10,822,242,800,188,624,943,778,212,866,56,339,562,912,793,641,42,896,480,732,716,772,316,796,326,980,936,97,726,597,284,911,402,138,778,621,290,573,213,609,111,96,51", "631,512,87,737,200,950,880,708,924,509,209,279,95,205,797,774,228,724,927,548,153,546,748,538,291,535,518,471,193,970,885,114,760,492,586,751,259,333,960,505,303,413,936,155,506,97,150,575,576,622,795,639,98,357,327,947,788,3,482,728,648,601,27,957,8,396,16,283,996,196,632,580,734,239,827,163,563,326,999,119,777,338,308,434,223,117,527,257,725,594,913,409,93,115,646,381,746,576,962,386,966,577,910,113,936,375,682,318,373,858,235,301,980,902,729,96,476,487,62,487,890,115,28,518,168,653,929,432,273,319,468,989,294,366,316,117,112,555,451,710,367,871,526,61,118,645,42,229,479,810,40,31,967,38,581,197,879,183,49,502,362,746,771,882,679,716,454,275,812,493,801,900,387,625,84,415,541,230,276,460,256,5,205,835,655,560,927,284,500,114,278,596,405,933,597,846,116,460,389,8,324,981,597,248,771,796,826,577,613,255,687,494,66,753,326,673,3,594,528,540,375,204,351,689,106,218,326,426,540,114,310,906,600,98,44,19,473,809,892,79,317,247,733,919,700,444,756,106,104,346,437,916,298,529,996,408,990,311,802,34,451,271,876,193,268,632,638,933,514,835,302,777,989,265,200,895,284,30,461,74,953,307,417,983,370,285,358,468,239,24,205,797,940,80,153,237,727,837,809,386,142,656,833,140,926,247,828,543,558,16,604,950,468,452,810,866,246,786,878,867,80,436,713,852,384,366,662,494,909,830,12,352,113,701,688,589,677,562,313,674,417,587,682,688,211,856,368,5,407,614,61,675,515,48,958,10,630,731,278,88,465,185,320,222,547,907,552,617,790,3,917,167,85,197,708,850,79,342,179,139,611,95,958,901,345,257,649,26,222,254,40,860,247,861,152,45,453,163,982,255,796,592,451,975,300,281,234,683,966,631,223,965,950,597,714,283,411,272,256,555,173,831,432,875,608,977,111,74,14,147,524,841,199,679,678,593,692,120,27,784,223,773,948,814,876,989,332,650,28,388,599,594,346,532,916,845,204,747,98,833,19,790,179,202,972,200,251,867,700,205,452,702,906,112,147,636,418,319,860,457,974,566,809,585,931,604,967,673,496,438,707,926,390,405,785,929,53,187,441,118,573,858,212,593,785,611,999,200,203,436,971,666,646,420,699,242,492,417,473,542,254,774,200,164,24,315,152,363,677,830,343,255,538,336,372,519,909,732,117,719,516,83,89,900,16,426,989,200,990,136,375,799,310,835,687,569,404,527,382,517,104,130,185,387,703,954,79,244,356,507,710,917,276,158,289,799,205,644,471,373,508,124,441,396,162,883,273,330,204,708,218,792,858,972,959,526,713,231,950,643,602,306,838,760,265,540,151,966,442,886,738,717,631,283,520,749,42,922,139,54,35,268,634,612,752,12,569,619,50,702,625,423,973,891,721,723,516,32,888,643,740,777,844,21,430,921,570,929,956,742,862,474,513,336,751,99,965,640,25,271,220,812,645,930,976,336,721,527,342,888,948,888,174,472,832,26,567,135,882,396,946,545,706,864,827,63,954,849,366,884,4,855,811,531,304,963,188,990,137,95,517,411,656,100,411,492,566,40,553,560,395,400,661,909,313,322,790,196,519,302,848,554,22,38,11,190,197,603,737,110,189,405,855,406,702,358,878,218,771,490,751,189,526,117,462,576,575,870,658,263,833,901,956,999,921,376,141,107,529,56,460,210,103,943,69,344,863,615,225,816,22,956,658,566,955,501,419,486,345,411,220,232,342,311,345,788,561,630,700,108,425,922,346,395,904,145,654,199,237,82,524,867,656,909,262,516,763,624,193,450,710,988,987,535,73,325,694,918,536,897,405,892,187,485,72,175,652,935,837,458,284,192,221,613,603,5,21,562,153,727,856,45,25,399,436,186,324,334,152,761,414,959,0,169,790,159,518,437,622,199,352,845,558,413,932,610,761,25,274,378,549,198,400,790,285,841,788,1,656,902,25,823,935,914,131,466,950,288,15,889,789,237,364,246,277,392,442,177,428,107,818,295,606,21,645,831,588,787,93,931,937,470,592,215,786,854,264,735,913,260,208,120,829,527,988,74,570,336,49,945,612,778,394,805,973,380,370,188,582,93,744,394,672,506,958,751,834,958,154,238,961,478,167,384,467,499,155,947,862,699,86,8,222,763,921,469,218,794,764,420,859,874,615,86,22,574,304,372,785,225,923,301,637,457,429,247,138,99,466,294,440,250,502,408,21,146,999,82,246,616", "546,979,809,177,311,8,628,292,464,678,135,701,449,199,958,260,396,777,946,155,132,631,955,263,931,878,495,201,627,13,705,434,793,456,412,987,224,40,427,158,437,424,860,599,3,767,847,642,825,312,272,456,340,446,706,683,904,730,480,898,948,892,530,179,704,452,322,448,217,696,690,593,348,267,898,654,34,269,449,906,414,623,300,949,61,234,811,446,588,280,128,199,947,365,8,31,326,308,700,383,855,396,213,501,13,374,99,742,803,164,431,344,579,524,395,28,751,76,295,690,502,716,181,452,871,852,868,457,655,493,645,488,30,483,218,658,245,389,586,374,365,919,989,325,321,444,424,681,92,586,877,477,382,243,969,342,75,220,345,268,841,888,565,851,469,33,659,543,179,553,22,681,182,474,850,278,556,686,333,306,986,482,109,387,797,353,72,424,927,746,265,91,73,713,2,863,314,91,508,297,413,457,43,188,192,500,231,435,348,565,841,970,857,157,193,183,69,953,764,689,262,540,174,571,249,704,99,169,860,837,55,807,902,462,796,67,664,618,234,26,698,139,679,505,248,871,844,311,683,736,327,635,71,161,330,61,577,167,752,144,83,451,52,298,693,707,645,327,964,968,357,511,717,9,149,139,546,310,922,411,470,758,831,592,558,381,462,430,909,885,416,15,579,394,145,440,648,612,850,685,719,684,281,316,388,958,304,66,85,677,376,357,973,448,971,339,1,858,725,264,476,398,456,528,771,878,935,815,10,276,5,499,794,470,82,528,44,986,546,116,960,780,358,240,198,713,703,963,598,975,282,999,878,422,144,184,934,738,182,373,554,11,841,8,351,646,122,374,928,833,59,698,489,156,244,916,407,130,960,248,209,173,83,470,977,943,152,910,857,223,619,166,686,902,177,756,337,281,328,144,484,100,854,628,655,985,576,966,48,329,616,236,992,461,784,149,916,31,141,626,40,253,566,147,554,306,415,306,571,364,328,530,585,567,584,708,571,653,433,139,751,226,645,922,456,1000,695,542,609,672,494,449,792,107,843,362,586,820,515,733,189,93,807,292,52,860,955,412,411,216,910,371,938,880,975,430,307,869,854,555,696,801,362,426,88,998,756,947,923,644,818,197,62,652,162,921,127,532,684,729,140,919,828,596,70,325,522,581,561,914,26,130,830,228,273,854,945,266,595,540,433,3,951,929,258,719,577,566,102,156,952,472,111,963,188,906,638,900,53,413,575,743,790,581,121,896,198,236,657,810,7,171,795,991,844,156,450,555,49,977,17,470,272,26,670,64,320,717,609,971,15,862,113,596,522,402,473,751,537,201,795,694,605,53,274,154,904,614,921,984,48,692,973,476,692,189,216,92,297,826,996,744,307,544,608,140,344,957,380,67,525,64,513,729,545,432,622,134,362,736,889,416,87,391,446,921,644,151,333,238,718,808,324,858,896,642,777,34,248,352,883,639,166,40,76,754,327,958,333,222,432,277,513,971,63,133,139,975,738,349,105,880,774,217,526,609,602,690,927,682,619,590,557,990,967,996,388,307,451,555,775,542,859,176,940,967,51,201,953,846,81,37,176,679,409,342,947,330,430,540,770,347,849,56,267,153,212,292,797,581,212,291,598,277,547,396,18,717,568,491,526,217,903,941,685,834,690,168,625,257,706,479,864,112,414,284,82,557,564,801,539,950,136,450,184,38,572,420,216,905,654,772,977,34,336,817,864,172,335,633,337,729,378,960,217,926,330,106,824,771,192,187,957,687,565,925,963,563,594,24,239,334,882,633,684,380,661,555,710,124,626,660,276,417,203,118,151,52,571,776,693,215,350,980,627,535,405,814,357,287,509,139,565,338,296,48,702,106,391,133,572,202,605,250,918,110,659,660,238,215,281,867,307,922,176,505,765,421,185,78,487,205,656,835,227,942,564,592,666,16,23,913,169,0,109,298,84,696,894,33,845,24,755,31,957,256,477,372,7,899,883,731,696,695,186,939,462,257,514,90,498,833,402,807,764,951,717,497,450,718,570,468,684,953,484,400,902,863,868,871,370,797,432,833,945,288,397,916,292,943,135,476,854,980,509,221,919,95,100,376,349,296,618,154,651,997,20,674,14,800,238,139,702,543,724,508,34,560,998,710,954,805,111,915,618,1,529,736,648,448,630,531,191,550,579,607,833,995,656,575,923,113,10,968,916,649,44,66,516,452,415,170,238,150,757,677,767,887,910,427,97,83,122,679,260,119,611,734,371,844,469,673,26,505,937,506,908,975,723,181", "178,431,605,97,195,63,331,231,66,420,762,113,806,95,824,39,628,477,233,88,201,852,767,34,190,40,862,503,478,683,599,357,628,38,44,520,298,953,629,792,492,293,553,103,154,510,238,444,843,644,276,758,67,149,686,570,395,841,91,81,479,679,927,711,537,818,381,677,767,216,306,342,98,657,227,648,10,702,582,51,716,227,931,673,563,941,931,34,715,329,373,448,771,219,736,229,879,224,465,819,640,774,133,77,653,244,709,45,499,146,560,974,452,3,431,799,200,620,302,845,226,383,168,262,819,388,245,700,689,424,945,142,355,463,512,838,619,28,404,662,671,650,92,696,711,441,43,997,305,160,699,520,396,995,381,738,170,977,750,259,929,135,570,215,724,579,326,161,353,615,69,247,332,763,427,931,598,426,438,209,996,357,532,923,816,331,406,846,256,568,622,40,782,740,745,473,995,20,812,127,732,813,713,861,210,852,998,96,204,714,742,28,264,461,172,12,502,300,327,991,189,483,288,130,635,908,157,889,686,520,848,405,376,916,408,439,443,270,965,335,49,545,77,938,665,916,50,699,439,317,62,143,955,239,921,582,469,565,567,64,780,931,991,267,956,603,134,350,179,666,204,95,850,637,935,40,181,600,320,98,752,112,794,162,604,254,546,700,311,406,294,958,37,162,627,25,72,902,751,277,274,236,558,529,401,923,345,950,903,434,711,926,571,886,234,99,127,422,265,529,827,868,934,640,557,904,188,262,343,228,279,795,564,959,877,849,681,592,615,47,868,193,883,241,475,542,28,430,130,192,540,828,991,508,899,558,974,375,30,712,367,370,796,833,268,804,813,240,105,355,187,258,980,920,442,867,696,475,744,832,431,601,328,575,972,353,436,881,794,264,485,103,750,128,730,223,487,64,672,518,534,295,756,742,305,409,227,712,422,951,778,473,190,71,331,404,518,972,39,950,552,139,404,673,655,580,292,400,736,458,33,438,655,576,181,614,994,85,758,390,656,736,621,940,534,447,953,326,827,572,776,786,772,792,831,393,150,99,525,797,297,506,4,593,968,564,302,212,983,19,59,214,374,624,361,855,693,114,936,634,291,157,118,500,389,875,599,256,174,903,339,549,623,244,416,316,879,415,366,667,85,90,127,905,755,51,739,462,176,246,591,33,985,768,883,175,847,128,515,173,402,804,898,844,588,90,292,748,350,418,9,200,364,425,627,797,945,506,466,400,842,396,184,420,477,28,897,22,78,548,688,664,396,497,299,634,208,920,898,139,142,31,598,998,415,496,777,907,189,932,374,623,931,981,434,158,865,115,148,666,475,897,265,499,577,182,937,228,914,393,859,9,151,111,285,744,321,628,65,199,61,268,210,956,750,832,562,246,46,477,281,483,236,476,810,649,88,118,615,932,264,973,411,722,477,656,780,69,650,43,516,587,683,376,686,341,315,818,323,640,824,637,314,267,65,822,197,499,951,725,164,994,752,88,507,123,137,918,779,419,100,159,471,41,860,194,106,552,856,603,522,300,230,312,876,304,692,302,147,949,513,749,113,169,215,583,835,501,88,842,604,240,726,200,390,134,994,46,650,149,954,112,40,312,298,130,728,297,906,104,918,180,511,410,499,591,794,896,269,380,29,569,592,149,45,724,141,413,731,155,875,909,204,469,955,142,465,62,282,818,439,476,364,314,216,968,119,875,460,97,225,842,857,616,423,62,356,507,605,97,748,62,574,600,430,634,732,269,586,202,173,125,421,270,165,54,554,857,162,220,961,645,971,122,725,984,386,219,540,407,5,885,174,679,378,730,255,551,526,777,669,835,872,711,581,724,459,494,584,663,725,845,585,50,416,113,772,49,725,510,252,362,751,286,238,976,218,551,804,433,130,24,741,966,246,737,551,249,268,304,327,4,367,603,744,805,232,182,797,537,707,803,790,109,0,247,16,446,814,574,694,77,385,134,937,824,145,539,31,917,137,505,690,725,394,770,301,584,300,61,146,530,96,347,895,59,693,24,927,688,765,217,968,457,9,204,865,95,2,274,227,902,301,64,299,547,521,133,821,21,301,399,919,876,186,808,752,443,456,414,199,519,606,241,390,665,914,869,487,504,293,612,392,691,405,404,795,561,122,287,771,387,821,872,328,435,481,170,130,83,253,965,117,957,501,624,909,890,862,322,734,639,452,152,361,937,462,982,136,827,705,994,4,537,917,523,106,665,611,940,357,296,373,105,685,227,786,927,376,221,571,135,653,37,358,354,231,291,735,950", "718,640,36,858,652,73,591,356,249,213,351,834,349,833,664,121,845,93,866,371,932,790,876,332,319,86,942,824,402,918,782,797,186,432,269,906,555,731,911,725,40,509,845,455,805,451,233,937,207,990,452,451,682,12,118,403,757,632,266,304,51,805,560,50,554,606,776,837,931,555,402,400,20,205,603,596,610,835,993,668,429,870,435,464,442,636,216,16,336,350,998,713,991,698,420,674,980,36,829,95,692,976,989,209,208,760,539,388,726,519,327,624,188,959,623,297,478,759,965,666,740,679,173,825,471,385,746,147,635,75,473,629,706,721,657,638,783,903,415,366,124,798,482,410,632,500,579,433,990,261,558,374,600,5,10,31,79,545,626,206,524,167,748,958,644,375,66,496,458,74,556,764,664,212,778,323,738,103,707,39,398,408,8,677,219,70,527,885,511,577,217,799,205,78,631,990,866,649,387,463,992,792,923,467,901,595,657,668,214,492,21,407,83,293,103,188,870,380,139,450,381,352,73,236,583,337,514,253,198,160,935,415,267,928,756,440,451,376,260,215,524,124,195,429,786,489,134,580,410,436,842,614,57,678,882,641,3,903,862,745,600,174,508,36,236,682,149,741,199,869,367,635,648,713,569,393,832,669,490,481,112,273,483,657,645,829,355,926,328,384,405,309,44,582,207,321,446,105,282,20,910,213,927,553,39,8,613,678,693,826,149,327,236,320,684,767,869,508,544,971,685,199,745,424,579,262,576,169,481,937,128,617,741,682,2,606,863,776,870,413,958,671,894,327,908,984,268,812,183,339,960,692,671,684,240,737,544,712,900,36,870,213,906,616,440,644,791,955,708,976,485,866,698,754,775,929,631,928,5,317,484,91,764,527,130,898,392,549,728,52,743,667,450,446,814,786,676,118,766,823,945,511,840,257,110,567,498,78,597,519,552,268,176,517,408,999,498,955,352,966,253,725,431,430,715,446,792,628,376,687,647,801,271,9,949,830,823,498,982,141,974,966,167,206,7,371,867,739,870,780,179,617,293,991,206,588,342,305,125,730,469,781,214,161,800,778,752,39,608,576,701,697,34,84,465,905,553,814,761,887,353,393,434,366,178,568,942,287,212,571,361,696,385,849,74,877,125,902,874,670,568,361,473,671,892,523,8,334,193,354,671,405,521,928,929,771,764,393,500,359,156,767,632,494,291,96,387,899,585,964,172,961,422,880,694,858,621,712,720,738,669,955,259,498,573,778,443,973,117,242,715,648,158,50,663,528,597,326,132,924,512,498,194,328,311,630,307,667,706,167,616,505,388,634,35,727,827,269,120,740,623,292,295,901,186,389,829,573,829,790,309,148,992,906,867,614,439,30,685,25,355,745,912,807,77,648,890,426,478,395,778,572,424,87,410,775,333,892,997,255,921,585,188,970,948,17,156,911,316,387,409,272,816,705,607,588,722,884,174,59,907,912,300,604,894,929,705,552,233,479,797,572,626,486,995,493,130,573,628,20,392,842,78,47,692,237,391,180,348,910,508,95,881,961,596,552,3,989,280,808,220,936,292,483,245,72,820,690,146,570,769,704,857,176,951,860,678,546,568,324,829,426,666,170,999,789,780,901,757,552,679,34,450,677,531,847,926,572,544,432,658,112,313,62,641,500,803,282,191,54,172,948,214,137,951,35,627,972,731,30,606,490,961,835,898,677,619,660,7,155,304,156,455,133,495,593,952,2,312,295,721,186,12,967,386,616,840,458,857,802,456,447,765,503,954,291,880,707,231,503,860,463,658,418,203,471,480,783,147,242,93,878,365,77,717,22,685,646,571,637,722,749,786,241,84,245,295,211,971,875,182,241,89,754,374,981,667,473,890,549,98,482,619,959,772,93,673,836,81,319,875,846,749,831,365,585,65,395,23,404,328,198,399,238,630,546,867,811,800,858,56,918,159,298,247,0,578,536,40,698,17,609,509,403,155,797,25,807,25,146,937,479,95,378,361,5,753,240,629,351,718,900,894,538,26,252,313,348,952,281,456,446,990,444,643,299,18,661,895,821,322,767,709,423,727,184,335,230,514,374,378,92,106,466,606,981,426,914,297,348,14,391,754,140,642,890,404,971,722,370,362,160,114,885,456,400,710,614,465,498,954,864,339,893,456,821,851,978,597,644,405,324,27,886,86,735,353,11,420,562,595,947,603,749,641,111,658,997,150,800,875,555,203,62,323,397,803,390,727,948,984,361,847,773,571,301,826,481,65,185,16,101,117,986,538,419,593,110,805,39", "124,688,197,890,81,889,964,780,132,168,375,394,129,448,782,707,855,188,178,424,660,426,336,62,679,554,451,756,982,328,950,28,736,848,461,767,355,833,805,178,122,825,606,242,34,768,902,771,325,680,234,882,2,546,686,857,447,273,658,148,740,266,701,228,727,120,873,561,48,254,344,235,187,497,572,309,818,314,68,569,63,426,581,548,282,643,250,809,564,778,866,59,634,181,812,511,20,983,229,863,95,66,242,167,244,699,143,905,436,339,59,885,773,921,627,990,699,278,236,151,571,645,159,389,315,108,988,412,313,988,244,410,947,150,821,733,341,81,391,337,644,908,249,707,945,92,631,485,567,848,455,288,369,41,541,11,885,581,119,649,44,410,52,828,831,752,88,428,61,331,226,819,954,168,122,351,451,28,217,611,765,555,20,224,789,961,819,26,141,245,169,893,242,463,890,165,956,695,807,78,359,593,596,679,112,987,666,302,731,8,629,414,855,424,635,387,13,844,441,51,827,698,689,148,879,552,969,931,492,834,932,533,511,112,100,628,756,412,61,191,689,781,82,186,878,335,895,621,610,280,789,765,626,138,352,512,730,588,537,865,334,191,190,11,419,798,612,41,235,251,85,198,585,265,316,649,73,44,661,424,807,328,783,461,478,461,889,160,150,954,48,325,80,569,666,987,762,203,990,74,907,221,499,495,215,412,806,831,820,171,767,438,866,305,488,597,605,591,34,645,332,434,975,294,128,919,851,505,881,103,57,151,285,874,74,598,238,735,191,757,286,988,33,526,677,263,119,486,163,381,667,374,294,449,20,843,507,210,321,174,244,222,804,109,321,268,846,848,167,301,982,2,44,346,486,159,657,937,741,815,334,581,679,815,556,5,285,199,420,503,926,584,697,9,818,887,110,895,756,917,707,560,886,484,947,82,369,500,822,654,527,650,636,148,277,486,430,332,866,733,358,615,518,443,209,730,810,30,220,499,596,839,319,123,498,975,403,207,62,157,759,373,657,386,522,938,583,734,814,319,356,96,3,35,308,382,427,710,632,822,614,418,897,543,491,975,800,160,672,902,383,545,8,272,455,608,941,111,279,129,432,819,483,30,970,502,568,29,405,675,689,179,510,907,737,241,775,163,271,374,276,871,444,511,557,54,626,396,343,261,653,707,458,359,785,561,671,180,226,927,59,95,751,987,94,631,746,137,163,29,912,555,847,643,239,703,238,699,563,587,677,746,627,196,496,162,602,154,85,636,155,27,843,955,506,681,534,282,236,643,686,544,904,439,627,195,421,162,794,702,60,212,837,510,32,587,27,198,24,105,685,483,841,390,783,466,10,974,335,339,851,481,415,944,734,16,68,552,55,476,152,950,185,172,968,126,840,772,598,932,224,543,781,505,834,462,796,23,99,587,985,659,230,43,340,526,276,518,778,423,617,193,859,864,172,42,788,519,527,495,854,917,314,290,357,379,259,977,99,430,849,735,22,738,552,491,597,476,207,391,933,645,526,922,889,868,848,210,873,660,828,98,319,79,465,935,832,674,453,72,658,348,929,411,778,374,381,566,448,818,906,402,342,424,874,416,142,880,411,940,908,753,420,348,429,952,629,566,365,37,574,145,891,244,471,335,796,532,467,476,348,351,786,620,536,290,554,108,698,889,371,634,889,168,379,40,746,950,195,717,439,580,25,923,805,600,840,596,298,33,387,322,445,676,446,894,315,782,322,420,163,587,822,512,328,623,680,766,575,269,419,527,3,553,589,248,483,127,49,886,142,567,540,147,969,801,690,958,192,238,574,848,960,137,768,60,129,395,962,975,531,284,152,870,204,543,889,15,476,465,101,25,262,207,982,482,44,491,521,485,639,304,99,241,37,685,42,193,551,408,662,923,167,314,813,817,694,727,442,234,917,23,84,901,283,20,308,492,533,628,339,111,518,84,16,578,0,180,259,815,715,387,273,164,569,633,769,594,166,660,540,134,29,296,557,786,614,682,330,705,249,36,371,492,441,602,441,478,796,164,794,43,561,914,289,238,162,55,605,769,511,192,874,440,966,26,203,30,686,54,799,511,712,941,852,516,758,339,462,320,590,872,427,833,170,41,794,703,13,704,181,218,673,655,633,957,87,382,533,601,616,172,18,225,293,274,126,381,73,798,724,237,770,424,646,174,396,667,63,318,776,483,33,803,740,386,657,270,369,680,125,369,906,665,102,342,967,492,255,2,553,991,288,726,649,615,721,625,294,969,803,436,65,895,638,231,344,854,942,778", "397,805,183,591,95,91,91,5,882,606,856,319,921,773,243,487,416,26,192,563,843,95,642,826,121,255,44,350,990,343,618,549,124,244,912,631,473,273,257,581,166,886,556,55,826,73,301,404,317,769,963,347,352,796,173,832,764,872,287,924,384,850,737,609,985,808,528,822,72,77,614,805,86,433,371,958,962,545,991,41,620,679,505,172,485,110,82,20,567,202,428,302,94,710,697,93,672,816,453,336,867,29,76,371,540,854,315,710,705,546,418,876,604,73,854,676,687,729,86,875,210,773,117,954,315,250,747,682,560,905,895,320,687,204,672,323,775,112,901,912,951,448,447,777,282,673,366,954,291,581,211,400,661,733,45,974,191,31,295,794,407,181,994,454,592,984,624,924,339,412,358,313,805,73,269,535,212,60,396,90,864,908,837,524,895,903,135,691,853,74,178,151,544,139,340,840,24,604,797,740,522,19,619,490,384,186,405,108,311,581,397,679,666,586,690,210,295,782,456,12,498,212,596,556,883,969,697,490,969,641,632,5,905,790,990,685,300,521,245,887,622,172,387,558,822,158,796,218,640,205,809,162,895,241,809,880,542,471,239,696,812,283,397,445,83,364,413,785,602,48,799,383,966,648,121,305,922,619,998,59,445,655,526,645,333,239,273,505,262,159,246,760,914,181,124,417,306,503,473,796,461,729,940,502,882,423,723,485,873,896,895,392,103,929,985,747,697,707,454,687,404,879,77,562,985,781,96,336,219,569,121,503,718,510,80,271,150,18,848,257,968,402,778,391,804,821,491,263,522,703,74,360,509,674,273,148,997,955,55,827,488,714,893,219,479,167,246,498,745,722,475,420,961,349,680,901,732,223,13,159,574,770,988,203,845,426,81,645,570,234,588,793,53,825,179,2,654,644,437,583,408,133,14,731,61,481,41,883,442,407,427,999,152,481,936,422,63,520,626,859,435,113,237,7,312,300,495,604,339,903,673,989,383,179,984,993,266,911,494,541,190,377,849,37,800,574,846,129,270,726,626,928,409,657,89,270,219,529,121,919,76,593,933,879,125,91,604,568,635,674,499,548,808,107,261,40,511,772,861,21,526,266,784,78,396,516,750,723,241,72,527,88,442,36,903,116,464,240,25,706,641,416,323,288,302,600,939,862,676,980,794,909,499,579,215,678,609,161,743,171,573,267,921,558,6,551,593,23,45,821,994,718,726,216,608,974,368,629,615,860,429,904,82,836,491,606,951,570,520,289,331,749,564,617,663,382,381,745,16,931,284,890,605,153,793,198,256,866,96,34,986,542,665,561,725,6,987,846,688,47,124,843,386,795,305,964,502,292,855,423,933,878,22,488,51,877,404,165,80,666,929,287,315,745,271,668,606,501,112,216,205,846,982,155,698,471,529,387,777,140,791,504,655,328,807,179,621,967,63,967,924,234,457,469,521,563,930,3,2,139,882,114,147,428,913,420,265,457,933,566,451,796,267,297,363,937,207,826,540,508,632,936,997,390,58,484,926,819,475,527,888,399,991,498,521,231,449,789,839,251,99,778,658,259,714,749,162,599,917,498,308,568,904,155,734,898,492,770,480,287,929,163,689,355,129,988,67,689,789,455,495,676,755,162,714,718,501,299,3,597,208,724,519,48,430,881,131,773,709,776,104,559,841,124,354,987,920,185,215,932,597,221,764,36,268,279,94,218,760,863,295,829,136,109,479,839,546,486,455,802,278,243,305,122,570,513,358,81,900,340,792,866,915,955,860,409,396,765,132,569,920,647,588,104,753,457,398,682,514,796,653,100,521,472,901,757,317,632,597,573,704,320,964,722,554,741,280,552,834,846,616,105,895,920,571,503,60,293,821,108,684,763,202,111,991,350,685,206,204,840,219,47,123,860,604,446,458,400,37,259,873,974,877,865,488,414,646,825,774,498,492,915,437,696,446,536,180,0,674,427,610,449,92,530,892,965,152,979,462,972,46,351,880,913,476,254,785,536,562,348,860,194,603,151,978,948,221,140,72,928,879,862,293,131,363,877,176,913,537,149,699,397,241,386,717,397,370,830,940,428,63,114,185,352,86,363,302,3,582,727,369,159,546,324,322,309,589,232,515,358,180,994,224,378,842,921,556,955,606,162,231,270,516,113,414,80,593,246,102,963,30,408,667,957,966,960,808,957,990,632,409,998,418,850,488,276,951,755,400,927,861,796,447,615,53,869,357,429,901,715,984,478,658,663,292,450,125,78,269,823,848,853,132,943,149,920,266,271,657,495", "234,386,639,23,307,873,823,718,320,39,300,251,428,327,161,572,881,244,325,334,232,772,638,456,856,233,246,958,95,891,666,258,356,457,293,520,961,834,184,895,517,66,891,840,92,385,897,658,489,612,474,928,649,768,275,536,682,424,278,607,917,4,760,190,263,206,88,916,595,834,892,521,717,268,721,634,887,461,189,629,611,534,367,673,487,493,281,281,926,637,360,594,518,103,685,259,162,829,709,250,791,368,648,986,319,956,533,217,582,146,415,368,639,454,349,325,484,481,399,873,827,54,738,180,317,347,806,466,519,594,746,849,781,740,711,398,921,258,222,856,895,494,255,421,315,295,458,618,596,184,884,772,530,441,303,927,280,920,714,252,599,706,811,509,517,983,849,918,798,941,415,885,431,246,586,894,57,612,227,876,957,590,106,826,272,269,64,479,365,956,705,399,893,760,811,937,818,166,512,953,457,987,846,727,574,888,365,879,870,666,249,82,749,266,432,531,379,396,238,343,3,800,613,977,995,86,55,746,452,743,812,622,455,173,411,312,648,867,559,497,522,333,943,8,189,338,202,396,435,794,402,556,600,618,659,993,786,10,816,283,725,176,404,518,651,376,537,776,812,532,902,613,463,664,871,307,728,313,664,308,449,509,969,297,820,63,494,176,399,949,281,886,345,803,165,757,704,485,643,933,316,860,890,991,276,716,128,628,743,13,378,512,497,911,157,649,120,67,584,404,407,681,382,608,527,597,202,254,32,676,237,793,520,513,477,522,685,136,239,420,829,223,865,472,731,71,312,243,523,700,191,584,677,173,455,6,391,949,829,630,693,100,384,435,19,238,267,384,979,908,76,729,688,175,188,639,134,692,215,141,224,360,80,948,208,188,181,368,295,376,70,702,767,37,219,534,182,885,36,775,713,581,177,972,780,110,304,148,272,238,692,790,830,347,157,462,74,549,485,132,924,666,884,1,509,290,146,762,898,293,670,62,182,406,512,32,434,447,484,562,387,797,895,614,586,642,360,660,906,28,782,423,127,115,433,308,562,534,207,468,278,869,807,757,371,74,358,489,192,233,10,487,642,168,107,618,250,61,567,247,445,454,433,521,643,297,108,389,586,690,435,260,642,555,24,653,746,651,665,265,624,118,331,806,416,392,711,208,879,555,122,602,97,496,913,981,559,211,480,331,539,411,977,672,942,950,751,154,373,157,698,771,732,70,858,364,765,297,921,818,490,566,548,9,96,343,926,289,754,267,309,828,356,107,273,460,520,32,839,497,940,443,973,811,234,651,907,353,56,591,202,640,727,908,815,910,665,670,873,932,172,784,607,606,197,121,648,855,561,242,668,622,229,409,473,475,156,620,337,870,227,695,280,669,365,143,702,929,445,541,313,919,495,718,879,880,185,447,208,103,809,937,639,98,288,24,934,699,218,296,606,379,553,583,377,455,702,687,703,534,300,28,53,459,833,711,761,204,186,632,603,846,282,352,482,449,735,493,451,33,630,422,945,101,913,488,659,903,591,573,306,346,59,566,377,314,709,979,835,862,132,721,637,617,426,531,956,304,175,779,941,588,242,869,152,972,628,975,292,648,289,583,266,30,540,58,36,195,854,193,927,365,371,249,282,557,666,965,559,518,159,705,984,62,32,60,896,33,463,439,656,543,171,315,281,389,51,579,710,54,819,299,304,48,543,384,243,149,89,891,223,363,87,144,981,224,830,546,486,504,337,196,736,53,700,914,712,297,639,624,343,714,122,629,588,692,486,750,284,838,7,616,442,443,462,378,984,541,487,141,767,421,166,819,404,778,424,353,802,427,944,86,32,882,48,973,257,31,449,356,822,909,100,63,493,799,271,8,109,999,470,577,246,578,255,44,807,934,328,733,395,342,153,715,903,665,77,209,323,885,774,302,725,169,28,284,146,987,132,773,165,161,622,894,814,40,259,674,0,896,547,259,136,216,115,738,510,861,907,835,738,103,503,235,487,468,838,800,872,330,738,468,179,317,390,177,588,348,44,883,939,812,347,998,163,528,351,803,759,525,789,824,44,972,503,445,627,497,651,794,620,320,39,248,842,347,554,432,117,56,113,969,563,828,845,118,581,469,570,175,703,746,802,167,766,865,744,944,183,932,616,923,859,599,265,366,224,267,271,786,831,687,527,809,163,366,466,794,714,628,290,160,116,312,736,326,173,584,858,884,115,675,983,717,745,822,209,930,606,230,279,711,871,161,739,194,60,488,117,457,92,339,728,909,515,829,300,145,376,892", "251,809,333,84,739,829,41,752,215,836,833,534,881,973,238,524,196,138,521,992,134,433,451,643,763,932,22,540,308,219,542,558,80,796,545,744,306,872,428,915,95,312,167,881,109,740,728,485,655,73,515,375,159,611,880,522,154,123,706,848,685,689,379,828,158,259,76,933,823,265,292,716,914,113,306,318,662,731,11,734,456,809,757,522,176,583,3,812,109,518,814,546,771,166,274,358,960,761,691,599,206,323,153,409,202,160,233,659,675,785,200,287,570,753,147,422,861,23,206,237,707,768,433,647,857,500,520,548,677,808,660,863,650,662,876,656,763,110,36,840,933,504,699,838,89,474,10,61,508,796,781,63,166,768,752,373,189,459,461,103,79,790,799,961,109,123,268,193,678,848,617,47,352,132,464,225,58,147,845,715,360,424,733,899,900,488,771,302,631,579,861,813,638,883,95,860,625,167,41,282,979,785,49,926,415,236,579,498,195,696,774,105,494,16,434,58,841,634,143,380,680,987,911,858,824,948,554,10,763,581,680,279,345,897,622,886,468,214,686,535,799,179,635,737,671,521,110,736,561,197,207,551,738,583,211,510,661,569,515,439,3,241,432,982,409,314,296,992,221,828,227,275,113,289,959,126,56,38,24,730,292,408,550,565,164,77,866,830,762,897,24,233,118,351,616,524,824,768,483,455,963,61,974,682,585,381,651,617,202,330,107,54,295,5,37,779,325,943,745,71,861,756,369,588,223,930,682,387,419,377,911,527,560,416,814,766,265,861,934,864,275,17,62,783,823,140,244,54,837,151,536,117,719,563,850,144,645,956,660,796,247,657,379,604,185,143,712,670,898,531,154,816,43,347,655,125,508,262,990,505,935,53,434,85,478,452,859,822,27,858,63,826,667,117,839,38,836,641,557,900,614,593,466,491,809,18,448,198,437,282,632,462,770,180,871,883,473,143,341,991,822,704,618,188,721,883,784,634,328,852,562,644,161,706,777,976,211,603,904,931,65,668,938,906,659,637,88,639,700,816,622,188,306,93,718,956,459,711,927,670,142,333,628,800,453,573,374,471,267,968,325,991,556,651,536,356,556,551,132,179,850,672,632,348,846,490,147,962,163,573,917,440,698,600,706,29,485,500,528,355,599,202,114,438,51,488,715,142,104,407,997,966,984,26,763,146,77,833,391,631,681,126,38,751,425,200,478,784,17,9,61,154,485,449,866,638,802,600,426,905,779,411,463,559,737,440,506,90,59,814,938,234,225,937,483,934,734,861,663,506,524,301,724,845,278,435,422,384,626,803,616,290,602,297,52,370,601,633,221,823,381,451,628,969,133,297,390,689,395,243,872,629,143,71,809,53,587,1000,489,695,555,218,434,152,576,961,876,129,369,265,808,996,740,933,3,11,898,73,634,279,888,744,455,996,637,382,637,347,349,464,613,942,824,429,6,951,382,22,877,526,74,128,640,190,30,112,107,526,732,309,93,289,524,871,81,879,140,691,291,948,638,576,976,131,310,724,497,538,978,551,166,218,504,249,695,156,178,114,520,811,380,173,337,345,158,930,840,187,447,963,634,292,638,759,882,811,86,799,992,168,832,703,269,2,875,875,472,543,400,931,405,240,679,229,354,10,324,101,168,557,243,456,337,644,630,292,366,809,656,995,603,950,411,486,501,665,691,747,167,167,304,262,705,561,811,472,660,709,475,745,48,167,446,285,97,429,839,400,439,873,275,263,699,339,464,698,272,726,45,505,290,902,246,458,745,653,300,354,165,326,443,355,272,47,632,764,540,499,389,767,142,928,142,471,638,264,84,382,965,803,555,590,138,824,113,58,637,152,894,249,950,279,41,21,181,791,65,727,52,881,543,325,20,952,706,533,397,967,382,821,569,28,574,919,954,56,428,901,474,740,294,998,351,894,884,232,210,854,141,250,33,986,199,33,574,698,815,427,896,0,283,735,979,642,689,588,156,50,959,897,54,247,295,824,553,905,583,605,740,203,226,46,831,605,405,961,609,473,397,410,329,834,99,110,834,834,229,775,463,856,946,8,869,807,372,294,35,463,94,576,227,305,141,24,640,669,101,948,770,669,432,977,514,502,676,94,976,761,679,819,438,903,982,848,676,756,269,664,301,611,123,366,121,463,359,782,350,457,754,474,344,547,41,543,84,242,395,885,858,686,236,716,886,737,294,712,316,940,562,870,746,782,799,450,712,864,997,329,177,830,714,327,825,524,109,833,600,821,453,368,563,463,256,275,509,291,408,995,932,981", "503,863,991,945,685,512,843,608,351,27,588,247,201,853,325,689,801,246,32,908,654,84,847,675,68,478,526,146,149,92,873,223,109,877,982,494,987,927,558,534,964,580,10,326,503,738,238,165,365,86,874,641,258,461,778,98,572,117,789,700,955,70,806,336,362,985,758,101,302,396,833,735,73,30,736,588,33,478,142,493,994,247,374,770,369,55,902,737,457,375,152,139,340,385,662,916,158,246,553,957,339,571,233,871,670,679,190,115,677,757,127,723,335,846,563,208,397,717,612,232,101,158,96,46,369,550,37,622,374,774,941,419,522,132,987,295,950,127,699,389,467,625,439,547,203,167,240,725,115,244,227,243,440,731,83,113,683,20,765,292,33,292,462,801,818,700,883,718,505,442,745,677,945,506,361,110,334,42,832,553,633,129,731,39,736,106,257,876,759,820,101,164,403,202,69,684,696,368,440,609,960,505,675,530,925,978,27,365,193,320,489,109,324,628,716,754,698,62,396,121,542,429,312,196,304,122,356,857,422,575,926,692,555,171,80,349,25,625,151,527,462,193,203,853,367,254,368,436,522,646,399,38,458,139,888,424,603,442,6,221,879,384,645,217,446,970,524,88,508,257,563,94,991,787,419,636,953,756,328,983,298,315,693,352,169,687,342,942,915,638,684,349,204,608,390,992,739,80,116,873,181,384,143,980,699,570,643,303,4,861,90,97,493,810,926,191,414,852,65,199,573,811,805,960,73,977,206,382,776,244,250,683,273,948,584,33,636,906,691,886,556,645,358,648,316,511,853,973,998,728,146,333,455,465,487,809,794,213,130,811,359,172,273,188,768,782,177,116,352,311,519,339,186,997,276,866,112,766,110,922,158,796,279,669,268,136,201,974,193,353,979,108,796,419,234,292,618,859,661,918,787,691,659,842,211,416,494,396,391,263,263,313,909,64,440,714,495,587,180,874,559,449,814,211,418,649,208,176,529,854,830,283,587,825,293,960,770,797,954,837,73,192,762,389,772,809,627,247,491,569,211,418,469,186,995,981,889,414,930,909,561,765,840,480,874,999,911,291,814,977,858,838,498,167,665,494,135,47,602,209,275,643,448,469,436,445,638,407,568,438,638,543,839,640,254,180,350,971,47,768,117,91,985,603,211,725,475,568,910,79,970,259,221,113,692,609,876,115,940,944,288,1,915,85,773,147,11,294,328,425,438,146,727,101,994,980,262,4,512,194,430,615,403,308,18,242,327,357,576,720,330,533,110,464,802,642,512,463,95,710,830,711,418,378,54,592,569,669,837,91,699,860,717,63,27,448,610,580,524,5,509,942,487,124,609,450,610,6,807,122,909,491,460,354,987,317,733,355,90,929,535,919,378,761,109,607,775,652,653,647,623,843,665,682,689,423,403,256,240,304,371,392,412,242,405,503,614,243,199,954,594,807,540,536,370,265,113,75,154,913,892,665,579,303,372,894,608,40,947,973,934,262,788,600,637,306,613,689,731,810,962,965,669,853,47,395,256,181,919,280,751,675,795,177,81,705,233,531,449,718,27,285,482,19,756,401,898,925,909,157,351,601,545,464,713,34,401,955,147,429,91,154,583,993,491,986,580,505,946,63,765,149,292,193,308,780,861,396,433,551,577,804,861,982,910,34,468,664,37,708,541,412,216,251,110,628,588,479,128,793,216,325,380,263,8,396,739,454,263,318,435,256,369,733,348,256,783,81,627,748,313,633,600,770,824,428,520,488,803,194,885,809,28,447,999,802,565,156,528,117,675,524,98,773,670,790,612,208,933,380,416,322,777,403,33,833,691,779,346,419,174,30,373,972,684,512,661,644,797,584,754,767,320,567,825,461,843,259,248,709,949,283,236,480,115,50,381,849,734,174,337,707,901,551,153,935,824,310,439,112,464,951,998,229,468,509,270,143,610,738,601,568,352,845,694,17,715,610,547,283,0,362,104,420,857,79,307,301,131,441,134,449,323,469,679,87,58,224,532,819,472,781,414,103,189,961,477,354,215,607,467,799,429,845,307,556,132,921,78,830,615,863,728,746,286,388,397,871,429,638,65,966,118,76,822,366,922,694,268,316,908,453,483,715,836,605,13,918,52,682,447,363,695,710,431,767,878,299,534,774,115,417,374,772,966,21,202,789,964,42,914,126,550,778,530,448,246,92,66,919,838,365,78,269,220,606,888,782,403,701,740,16,870,652,609,129,504,873,39,393,256,542,831,602,199,3,323,127,408,430,761,711,678,572,383,863,623,545,767,142", "64,329,644,621,403,3,605,417,191,625,591,725,718,399,824,289,835,379,573,948,308,700,480,894,682,758,121,422,461,822,437,139,312,67,986,753,200,465,78,393,381,621,208,717,618,750,493,363,450,979,142,77,756,454,604,359,287,24,925,314,953,277,211,990,114,362,419,355,743,288,925,431,424,722,926,865,138,619,914,821,16,998,257,36,884,411,722,505,495,301,691,326,701,221,357,528,326,653,793,513,575,208,86,781,455,130,990,211,142,95,695,757,947,567,544,201,305,196,391,409,828,345,92,987,230,366,820,947,519,720,446,771,669,567,509,683,849,327,818,730,908,131,88,407,131,474,688,352,939,939,515,208,210,664,939,453,502,498,22,738,529,146,754,602,956,635,232,80,109,741,992,929,993,828,565,944,73,405,626,634,460,392,456,430,284,307,431,571,143,212,29,373,658,714,508,928,249,389,245,643,790,645,770,459,372,377,756,336,499,163,251,760,613,960,301,84,906,420,642,379,3,147,535,772,908,739,622,660,837,448,327,884,949,280,916,980,87,962,670,652,422,725,131,545,311,321,695,386,757,698,896,610,97,590,271,370,405,471,917,571,976,776,215,877,391,102,829,380,450,326,346,489,953,479,532,10,877,357,311,715,487,821,907,395,869,669,410,990,549,36,882,684,586,833,288,200,629,896,750,588,658,964,634,926,851,791,119,947,637,464,562,103,131,708,748,495,82,316,880,40,801,872,679,551,331,457,288,227,134,452,250,501,221,683,411,705,695,345,610,812,907,545,404,293,992,161,741,845,273,110,30,831,841,734,249,306,285,38,208,804,691,8,189,224,315,325,553,492,765,786,415,855,998,874,828,458,576,511,809,397,705,194,234,6,684,14,728,652,800,861,7,126,658,726,640,569,939,850,105,369,923,994,516,579,472,244,966,344,824,399,623,516,445,723,467,72,732,609,286,554,685,378,152,607,581,882,944,366,111,715,422,216,61,824,387,613,892,437,526,897,822,223,597,11,834,913,150,823,948,479,180,114,221,879,835,338,913,798,394,591,92,642,902,892,594,811,790,339,808,836,770,939,269,353,561,787,176,810,765,222,377,715,702,108,235,530,86,226,284,186,128,591,266,464,148,353,586,901,525,832,763,928,344,730,55,306,932,586,405,567,430,712,990,925,573,109,950,705,342,616,341,934,5,614,287,779,367,681,343,622,137,268,359,929,505,610,367,487,171,275,686,352,526,991,740,530,343,694,809,591,944,471,944,354,912,769,388,802,586,347,623,921,138,162,457,383,335,102,600,34,560,706,749,222,532,53,806,143,534,658,450,1,419,458,700,346,880,755,624,217,775,438,111,908,451,490,866,42,129,686,925,16,914,162,872,180,86,269,197,676,118,809,58,233,396,482,380,241,825,807,96,311,700,778,500,443,444,427,953,144,118,128,758,527,997,203,934,171,296,539,306,732,926,15,627,242,677,821,379,902,856,60,529,877,602,275,216,669,253,181,983,50,861,368,479,886,780,845,771,854,89,351,37,790,694,547,202,515,261,236,458,595,832,309,703,220,736,641,739,834,64,675,154,758,955,78,323,484,585,944,684,19,993,923,975,90,53,859,630,739,865,252,561,341,669,965,602,200,204,290,145,77,617,545,432,346,787,128,642,898,97,608,387,542,171,940,805,252,238,602,652,986,264,703,803,76,334,605,158,629,363,751,859,100,659,14,656,74,963,652,808,181,863,551,422,185,381,836,507,569,351,918,279,786,964,896,626,261,994,768,428,97,601,218,931,165,568,908,460,551,208,923,150,59,197,198,934,234,496,547,438,28,108,924,62,949,904,106,73,628,574,577,696,942,780,391,901,943,299,219,354,764,214,50,226,131,910,65,303,540,373,733,388,492,957,110,850,702,226,273,326,860,225,52,859,933,32,572,393,218,431,340,845,24,77,609,387,449,259,735,362,0,641,339,731,104,361,504,694,423,457,730,875,325,496,23,905,581,266,934,360,773,611,388,733,778,438,361,855,942,713,802,883,399,411,18,234,384,887,488,605,615,399,305,969,280,966,93,602,99,298,527,834,994,896,523,84,430,56,554,123,811,205,754,641,254,643,678,516,88,618,531,646,10,5,181,100,720,819,951,254,781,101,616,619,952,54,911,698,152,942,325,437,613,933,928,823,732,43,281,944,500,20,955,682,806,489,156,204,604,835,781,970,776,975,29,252,326,792,850,837,864,461,574,748,657,588,24,890,124,877,799,423,303,847,169,250,471,135,886", "990,152,570,755,955,769,449,928,265,777,563,882,895,179,653,220,895,251,352,421,458,435,348,462,923,448,854,175,576,179,215,155,978,78,328,187,639,908,404,971,727,963,924,839,315,618,999,161,724,608,851,912,193,416,112,224,292,637,81,965,560,779,673,259,181,990,350,963,791,214,402,993,327,457,610,866,375,817,255,428,740,888,916,871,319,619,870,500,93,341,426,515,757,834,748,422,25,467,648,41,408,484,122,411,843,595,148,49,480,31,711,224,764,68,427,516,126,767,952,743,166,524,606,184,711,576,219,302,703,247,867,958,275,646,566,293,381,97,969,348,122,407,981,156,663,618,978,5,615,892,519,777,21,488,639,673,286,939,321,701,279,131,459,420,524,996,176,81,447,21,578,163,780,293,349,897,426,206,949,871,918,587,852,397,265,729,173,888,118,840,943,640,251,986,150,935,960,868,615,406,177,105,568,890,372,28,649,39,173,201,19,340,296,952,891,927,216,786,9,948,608,37,876,863,804,454,717,630,727,912,612,482,666,440,323,252,374,501,184,685,80,639,832,159,592,755,382,267,855,271,875,499,47,945,431,486,781,475,111,527,566,890,700,895,489,543,980,877,632,999,221,135,965,560,514,437,43,3,316,35,443,246,703,884,307,941,606,911,37,173,947,885,727,484,85,667,177,331,498,330,530,967,281,994,448,139,846,534,270,85,678,748,414,100,396,359,209,103,246,464,592,55,687,376,470,449,514,419,992,575,373,23,575,251,410,171,867,429,877,661,340,230,412,482,320,156,865,727,817,55,840,238,794,979,161,524,452,726,681,815,556,577,968,898,611,764,635,833,188,173,53,198,988,26,874,702,373,862,802,197,101,847,561,619,188,914,515,251,646,476,197,488,246,925,661,528,139,921,846,797,609,155,615,450,657,417,272,144,238,272,606,59,264,506,265,70,197,735,483,786,316,398,620,95,704,976,101,26,620,933,599,382,211,644,390,576,353,822,394,868,387,782,882,177,550,744,850,723,151,754,106,901,298,905,806,71,265,880,629,238,217,43,807,661,319,180,306,221,733,129,705,765,657,830,353,55,129,25,781,640,976,543,222,346,992,751,484,215,282,978,344,902,650,87,143,904,576,553,212,612,599,571,513,397,514,33,759,111,567,649,631,549,731,226,336,237,976,95,15,323,391,762,680,619,660,671,246,65,3,547,338,938,948,673,717,937,513,369,622,476,6,624,862,341,342,969,420,244,60,902,407,998,940,442,858,32,517,437,695,203,417,109,242,593,578,277,310,39,529,647,96,393,500,611,851,342,326,561,123,968,889,33,287,220,388,139,998,745,661,72,51,738,575,780,898,151,934,696,647,921,397,543,840,797,312,53,313,382,626,495,772,230,768,962,912,328,643,316,860,201,713,325,152,166,935,58,9,578,939,800,847,376,265,411,346,944,491,857,475,82,60,76,885,832,865,504,756,144,336,829,407,494,279,569,625,895,251,22,237,66,676,88,209,494,721,460,370,368,732,227,540,77,9,429,319,405,310,58,367,420,934,889,656,411,699,850,606,763,53,313,349,504,55,500,13,795,829,20,980,520,675,694,952,267,574,376,546,590,228,371,517,540,366,637,789,948,108,829,965,16,124,758,186,190,387,418,856,438,201,580,415,571,617,352,293,536,743,963,859,5,309,682,191,683,994,585,65,214,832,711,424,216,387,638,408,695,536,395,531,293,880,320,823,484,649,12,737,43,948,527,56,9,413,447,428,107,420,175,78,503,940,713,524,246,969,76,99,186,538,693,213,814,730,132,615,190,523,827,554,334,484,757,223,458,804,136,391,275,255,595,525,793,57,818,160,592,683,390,339,244,237,278,451,690,859,376,852,951,92,64,315,930,740,541,97,878,951,433,586,937,14,190,193,683,672,959,839,352,368,825,465,869,558,755,385,509,273,92,136,979,104,641,0,707,424,890,554,881,46,936,755,730,564,62,936,537,21,285,885,531,655,317,476,600,784,129,927,198,316,620,6,831,102,440,315,180,976,468,572,759,659,10,774,500,212,757,347,181,457,641,107,81,940,269,60,328,58,285,109,297,307,572,468,94,956,674,153,244,762,702,117,55,722,733,800,687,884,525,445,284,577,927,991,652,290,539,830,461,524,991,903,463,37,353,35,501,165,616,830,777,111,837,465,706,542,42,746,659,247,738,384,826,838,178,639,656,864,296,234,143,717,312,51,340,578,163,278,434,915,265,364,363,191,529,397,91,839,804,13,484", "295,131,761,459,525,862,123,129,690,4,882,884,656,252,595,44,798,173,171,350,899,516,313,764,435,21,836,775,434,553,450,787,105,854,484,645,443,668,172,922,216,737,153,600,24,518,171,234,496,431,81,614,392,968,726,431,573,133,234,228,385,92,991,913,564,851,105,509,89,916,430,442,595,879,325,646,953,349,878,819,366,494,62,114,589,590,804,47,508,728,79,693,428,218,726,360,770,29,611,486,235,514,789,2,646,244,568,786,741,715,82,415,381,580,530,732,595,979,2,944,992,145,894,852,779,937,823,419,416,3,997,648,858,708,318,175,909,219,710,504,448,897,669,734,753,111,557,565,300,834,642,856,11,982,934,373,893,673,794,672,728,224,803,832,776,604,218,176,785,275,299,649,187,627,811,147,743,831,925,859,765,822,961,486,93,639,170,312,877,341,572,61,547,883,791,25,158,603,894,703,348,895,456,180,200,872,134,670,713,513,329,585,651,650,256,293,209,547,182,510,433,927,229,367,440,370,471,652,306,46,22,779,420,319,878,11,932,457,644,908,375,246,154,240,957,282,848,506,497,388,672,576,204,194,129,888,79,981,263,984,329,341,669,237,568,118,216,354,915,988,227,702,211,124,203,927,633,870,415,186,579,778,871,188,655,492,325,734,448,249,169,123,155,135,538,47,62,52,918,418,541,24,97,187,325,776,474,268,711,54,21,941,204,848,809,81,465,444,502,350,453,950,173,419,965,2,834,428,117,51,675,392,374,500,88,793,756,917,717,795,305,150,806,138,185,359,6,17,560,313,168,879,607,811,388,536,935,999,945,428,435,186,881,271,52,810,897,904,931,623,94,790,348,340,525,23,113,762,85,200,981,450,650,826,154,43,907,395,112,525,986,541,603,448,987,398,243,84,842,559,969,899,615,41,833,286,742,698,454,2,699,841,119,966,865,38,489,759,51,118,795,572,857,424,396,969,757,122,592,538,123,798,275,638,92,133,499,848,913,469,118,633,736,266,732,129,729,979,577,142,848,241,622,797,167,23,958,674,215,676,326,96,28,384,851,986,607,322,775,509,273,870,783,299,536,762,715,233,11,909,627,306,959,448,775,428,606,37,107,504,485,85,180,590,740,288,862,861,20,245,401,806,582,133,201,257,935,346,58,741,259,312,454,894,812,135,294,35,152,328,156,848,928,478,847,212,877,306,593,359,184,183,949,521,555,749,96,813,902,266,50,618,682,225,229,77,835,196,340,458,506,159,816,782,646,234,606,118,272,825,178,862,635,448,615,508,223,210,764,694,379,136,270,828,523,304,153,964,826,559,670,496,702,986,152,385,497,436,86,343,829,530,835,136,986,387,788,783,676,812,242,526,949,974,711,306,456,955,188,469,355,482,803,517,631,886,41,406,19,766,739,493,823,144,436,217,586,793,432,868,795,74,190,409,6,447,232,607,340,669,445,641,931,969,444,453,838,451,136,379,354,645,899,886,108,845,852,620,445,493,401,609,559,909,720,872,811,426,385,759,645,518,902,622,816,544,908,818,326,959,304,314,243,667,395,113,496,96,194,991,467,449,827,470,967,824,621,18,936,53,826,508,492,898,499,266,835,170,847,940,28,650,525,587,313,41,538,444,856,149,133,658,793,295,414,438,622,459,358,697,579,190,894,22,766,550,916,488,808,340,172,442,184,298,273,463,242,298,115,324,964,979,396,676,640,121,177,47,721,780,38,941,460,798,40,881,590,415,26,999,303,413,94,575,763,524,774,541,756,465,809,327,391,970,607,972,76,150,852,214,158,66,864,980,200,821,54,64,960,298,344,744,864,994,365,602,77,853,401,711,570,870,43,686,978,334,760,716,495,571,215,591,296,940,99,161,39,708,646,886,247,707,656,704,528,304,693,387,40,924,762,82,955,967,196,806,668,13,38,581,721,759,413,31,134,403,164,530,216,642,420,339,707,0,917,812,790,288,662,731,939,418,920,63,398,617,227,39,671,142,716,751,733,399,100,752,82,405,919,81,832,214,414,171,224,31,773,408,968,621,8,70,970,230,617,749,32,783,956,191,221,592,744,278,943,187,699,220,494,11,20,653,2,542,374,415,55,752,340,382,5,352,408,46,52,304,289,356,67,349,803,913,778,942,534,285,870,744,920,868,155,892,24,465,150,303,660,797,951,956,530,552,892,973,333,214,959,603,346,478,329,860,875,298,238,415,386,735,353,922,683,480,510,660,781,373,567,36,902,150,486,18,404,154,48,888,584,228,976,1000", "733,603,180,536,289,225,361,191,28,392,661,828,742,271,180,789,393,197,259,474,808,521,643,984,164,152,954,634,609,554,566,641,623,645,182,934,812,611,913,229,333,992,839,785,388,815,810,310,959,988,758,329,335,54,603,509,672,690,868,351,787,645,932,289,339,102,767,549,357,350,332,410,49,751,261,24,354,562,585,447,802,279,893,484,180,83,650,347,133,896,285,323,608,101,378,26,777,737,611,633,580,579,844,175,68,982,583,845,959,734,875,696,12,609,630,948,760,225,909,24,467,381,12,805,414,733,53,24,119,813,263,795,389,592,814,445,151,472,629,878,150,26,819,141,380,865,862,295,538,861,988,680,558,491,751,377,865,298,376,949,122,968,136,514,407,915,244,173,661,327,780,433,104,401,594,771,914,554,41,810,556,575,302,814,595,60,538,329,828,78,657,500,771,29,734,282,358,110,606,518,227,159,465,355,189,922,397,736,342,457,878,976,303,859,576,692,606,55,84,443,941,613,635,555,960,670,37,842,86,173,858,535,942,454,67,155,545,462,436,38,532,818,603,175,853,607,156,840,715,795,512,454,886,693,918,163,573,105,942,570,173,765,997,782,990,179,54,92,507,64,86,187,184,868,827,787,348,769,947,928,966,794,316,780,957,218,870,390,86,290,11,682,69,439,451,480,338,963,570,556,168,366,214,215,781,508,712,889,275,43,284,867,145,81,306,319,210,23,343,852,808,723,544,901,911,651,564,777,969,905,706,709,537,392,707,255,695,34,158,740,297,940,765,403,198,399,17,618,920,116,893,903,667,731,90,998,958,61,825,235,74,208,915,674,613,471,37,994,393,870,303,701,161,877,543,685,391,212,94,768,225,302,672,770,430,256,270,783,631,378,51,352,519,420,619,103,203,564,323,857,859,522,381,631,296,514,791,583,811,263,911,933,722,373,100,610,392,678,135,775,854,492,409,205,453,888,571,573,888,426,81,885,543,999,424,502,886,442,208,575,209,26,265,272,277,228,992,593,900,653,329,466,428,792,376,779,751,528,448,541,374,16,249,35,107,137,714,609,733,47,628,91,705,805,143,636,700,89,788,25,559,594,828,684,455,554,908,456,235,546,394,799,239,870,417,772,547,918,298,361,760,20,218,256,888,746,771,645,67,198,74,895,21,446,598,214,586,241,951,461,863,649,48,615,223,279,655,861,142,392,635,328,771,45,489,398,727,961,84,70,426,710,808,861,652,495,545,799,961,434,986,697,999,173,414,755,241,601,763,494,204,505,975,698,29,168,770,494,333,148,297,894,97,637,119,753,914,894,517,797,857,658,980,384,226,404,494,779,56,592,20,984,950,699,863,746,316,198,942,851,13,330,46,104,283,464,796,96,877,288,73,383,549,863,642,921,995,759,326,655,652,638,36,143,352,945,17,747,364,757,962,369,203,674,562,100,627,838,864,239,359,369,973,661,714,224,987,485,813,18,926,516,103,233,180,271,852,293,743,894,790,682,214,969,353,667,588,296,167,552,264,866,818,674,484,316,596,321,27,700,503,239,150,592,832,856,216,738,498,991,600,297,951,17,193,876,270,743,907,800,942,700,96,785,664,373,4,185,582,273,8,110,142,757,27,558,179,229,59,248,42,608,373,339,437,62,423,578,847,289,682,20,564,661,587,712,203,174,709,675,459,172,945,103,735,969,958,283,526,317,952,118,846,133,75,351,67,759,9,653,750,77,181,3,906,301,498,148,194,209,297,681,997,195,822,555,931,157,781,930,976,993,807,599,563,607,890,396,433,275,485,392,487,551,247,775,796,440,433,218,131,520,544,853,279,471,86,723,681,469,259,501,928,242,824,257,439,133,142,352,86,400,772,738,322,482,518,556,583,91,975,745,157,918,857,612,690,306,88,211,304,493,713,115,291,346,398,318,325,138,536,727,932,957,937,155,569,892,115,689,857,731,424,917,0,115,873,440,331,670,309,341,927,34,190,302,710,260,466,440,864,478,829,805,202,135,998,452,233,6,901,231,97,353,964,734,362,1000,19,429,439,224,989,14,588,248,997,273,812,852,8,342,647,585,463,252,993,308,558,674,105,378,184,377,324,154,774,554,386,781,509,614,172,969,524,164,619,368,149,341,223,778,291,691,75,884,837,547,207,267,117,353,593,945,230,435,39,479,316,641,442,528,262,239,97,720,251,327,93,515,313,555,402,395,371,340,762,385,724,579,915,454,189,916,739,319,560,488,538,61,399,342,926,793,80,999,98,125,572,205", "948,77,673,719,474,147,833,462,363,337,74,378,29,181,608,186,843,80,890,862,931,909,153,188,35,665,749,789,146,431,87,820,314,926,112,553,481,310,981,612,496,814,346,121,175,40,826,721,655,850,624,961,980,42,704,446,757,150,851,837,443,848,870,214,190,666,538,872,550,156,980,712,862,299,439,404,166,524,250,729,832,961,607,736,440,713,560,504,392,876,308,211,846,411,378,131,864,428,321,73,808,70,46,339,930,661,996,444,373,733,886,907,646,863,386,239,7,471,677,788,353,494,197,884,164,856,654,299,176,137,512,725,22,785,452,14,211,51,102,401,36,778,753,942,837,37,580,119,50,403,178,166,909,788,801,135,732,194,534,444,52,375,507,824,353,687,398,483,124,166,441,304,56,634,886,746,606,84,744,451,665,116,780,139,969,49,594,961,557,527,548,719,42,499,261,202,905,113,591,931,308,776,530,562,647,379,108,363,105,644,313,86,672,310,208,460,925,148,659,710,578,944,348,120,674,223,21,395,265,503,378,369,146,69,768,516,883,261,800,540,415,476,461,71,548,655,270,501,4,558,430,407,470,634,755,701,884,616,518,573,694,808,305,947,85,206,326,71,470,252,325,774,397,791,606,925,502,418,28,726,479,815,560,935,804,575,182,331,25,939,525,864,735,873,963,203,987,165,554,807,543,435,117,3,304,951,685,806,165,581,626,764,578,330,762,45,389,191,138,6,718,816,538,409,23,932,180,51,971,569,940,490,534,984,543,923,443,785,549,426,926,955,146,11,98,505,728,807,18,392,601,889,396,431,153,527,490,781,51,260,391,645,495,699,972,366,692,777,992,84,551,168,964,403,868,59,545,825,957,594,357,601,326,44,103,330,254,139,584,75,359,589,896,736,344,264,163,874,349,934,168,569,443,66,162,858,842,943,198,329,590,886,469,585,183,104,825,378,514,315,671,503,474,614,622,248,906,667,377,131,609,920,180,399,941,112,106,473,688,33,531,735,483,838,984,351,150,456,729,765,244,202,11,243,259,328,837,335,1000,680,784,36,567,68,906,301,678,690,518,856,833,602,70,37,117,89,127,183,442,920,317,1,285,613,323,389,181,17,88,314,327,708,633,523,234,448,925,529,622,965,447,63,133,648,138,122,108,95,116,672,828,547,459,848,6,758,899,243,592,209,774,127,69,456,254,648,354,11,871,810,724,149,690,77,845,291,461,586,926,829,694,616,619,213,825,611,151,111,23,832,354,994,478,15,65,246,873,787,676,173,145,777,146,244,289,733,322,490,274,292,816,803,949,910,423,497,364,470,299,766,603,491,997,51,393,885,688,164,386,762,727,231,168,711,554,365,589,395,590,934,715,148,884,852,45,793,124,899,349,217,277,622,412,736,724,277,49,429,927,199,645,120,843,197,499,998,344,762,494,29,678,959,753,823,93,329,194,848,873,82,78,663,984,535,881,233,188,546,457,119,290,584,901,625,26,542,464,407,696,816,995,906,920,679,687,534,634,460,982,902,858,443,96,465,418,860,642,195,700,924,616,172,949,268,194,325,776,474,822,570,875,225,434,116,135,740,282,159,669,756,882,424,376,809,918,892,217,267,753,438,509,991,640,853,528,833,880,214,571,515,682,42,727,530,74,941,31,178,456,264,755,567,409,527,723,454,350,872,253,833,823,871,666,652,251,946,81,88,901,642,108,564,91,739,380,789,340,749,616,939,232,513,939,322,549,93,754,920,902,607,743,942,51,236,376,352,500,695,650,986,858,522,61,642,437,970,252,821,932,849,122,456,328,357,210,165,713,123,27,233,744,158,30,220,954,829,494,995,251,984,956,25,573,609,679,322,914,792,749,65,365,18,643,997,717,413,227,387,328,268,735,714,126,471,164,428,531,575,209,76,129,852,191,443,98,991,26,289,45,87,711,100,610,256,824,797,633,965,738,588,79,104,890,812,115,0,598,776,977,578,357,704,890,150,738,950,607,44,412,942,775,797,484,405,83,823,449,422,857,624,180,240,264,532,530,421,590,727,943,432,38,290,713,468,185,308,640,976,123,227,837,674,428,216,547,557,77,258,915,527,667,266,925,346,417,873,228,973,922,828,944,330,552,543,165,130,752,857,139,574,430,768,464,245,846,124,184,972,610,245,426,606,104,539,262,334,411,642,929,519,858,256,550,463,425,188,453,999,98,134,969,172,119,985,924,435,144,12,592,189,701,865,218,304,921,151,854,784,814,580,386,522,642,184,138,879,382,11,852,498", "449,781,802,128,172,221,977,625,463,711,875,531,921,589,937,946,794,186,761,405,734,170,616,482,628,734,678,969,687,249,155,594,596,370,546,777,685,461,722,307,934,521,884,947,628,402,840,630,513,905,547,48,972,94,351,665,573,112,719,974,790,11,528,303,753,523,432,591,745,814,90,917,135,633,281,4,142,524,933,378,699,874,146,473,498,695,757,237,970,271,9,175,694,824,782,197,170,90,426,877,13,102,447,130,661,145,938,955,248,45,28,900,557,527,492,837,615,838,531,155,658,739,993,37,650,95,502,641,954,908,468,639,622,476,546,140,389,793,999,863,881,842,660,851,10,638,58,443,54,215,620,626,114,899,888,164,196,856,635,233,919,808,376,837,483,50,604,505,286,523,822,482,84,42,205,764,663,406,439,658,263,366,858,887,589,152,780,25,64,852,769,224,55,993,855,972,564,927,15,190,591,737,757,768,254,150,185,108,149,366,384,583,834,131,914,795,24,312,360,716,122,569,271,113,552,525,882,445,378,672,135,985,336,17,811,887,419,18,822,257,883,256,138,112,380,465,812,980,388,84,307,836,521,810,980,605,837,791,428,959,863,527,401,541,214,344,106,153,341,933,702,844,798,175,992,290,802,363,722,601,78,607,862,160,896,325,215,618,476,331,887,800,134,176,478,397,738,170,63,937,586,772,180,317,637,554,580,151,720,926,147,616,940,697,435,654,955,259,140,458,917,837,68,618,723,852,439,720,550,353,176,383,145,753,882,633,993,874,484,534,860,72,646,268,487,869,389,372,11,110,319,65,544,49,140,137,535,182,284,658,853,952,725,641,417,611,876,973,884,801,325,924,777,185,24,841,591,745,87,302,660,298,188,211,789,634,989,226,523,301,132,625,946,240,522,37,942,610,464,168,684,655,906,51,191,811,244,349,200,151,177,758,472,205,268,943,992,798,118,633,56,963,218,308,364,133,432,162,311,213,231,324,690,696,653,234,708,353,43,199,801,442,172,244,406,213,98,384,953,786,557,635,864,117,674,806,849,444,176,851,586,385,172,12,999,487,527,749,509,422,848,684,344,189,116,598,678,901,802,218,68,201,963,805,539,443,959,869,440,937,173,520,296,371,677,555,692,3,897,419,231,235,307,840,582,968,624,312,568,844,517,611,448,93,270,618,125,441,228,82,563,350,688,228,546,184,178,931,706,419,358,200,766,245,236,406,794,101,311,777,373,729,675,432,934,826,912,964,45,916,237,127,977,738,771,126,283,829,803,574,834,770,993,866,71,490,309,621,61,367,339,289,642,463,164,432,545,715,618,521,732,4,513,161,35,811,589,67,486,389,162,902,354,860,291,614,417,211,977,599,901,892,377,889,145,363,316,132,249,584,537,261,201,602,923,157,617,16,497,4,710,832,160,411,78,375,959,542,825,710,436,928,625,642,576,863,996,302,267,504,926,179,256,891,141,557,751,180,259,234,870,668,126,444,623,426,283,990,207,178,925,276,11,806,594,365,984,714,957,466,855,726,400,169,647,884,367,434,603,423,570,676,397,594,587,877,989,991,817,51,227,450,998,81,246,38,836,609,415,346,954,705,652,226,910,440,832,46,438,537,900,185,701,398,831,529,513,898,824,502,193,929,879,10,338,175,75,549,231,125,966,788,703,828,82,632,171,266,219,927,673,728,179,782,599,278,710,670,113,985,732,50,7,173,862,55,192,134,442,629,341,515,978,858,663,774,601,258,33,850,582,375,402,168,725,365,719,507,997,750,202,843,843,901,587,583,466,48,236,142,50,370,192,341,90,55,464,955,258,529,740,827,84,258,816,948,958,556,849,20,228,747,517,316,680,489,546,510,487,113,752,231,79,988,584,600,870,9,493,109,141,622,724,959,460,245,365,214,72,910,215,995,287,90,865,926,665,515,806,153,124,97,761,477,145,25,769,152,510,156,307,361,554,790,873,598,0,873,468,434,174,682,564,311,946,374,848,350,486,558,449,669,431,952,171,121,471,256,766,719,289,508,534,196,89,333,141,910,635,731,900,684,425,36,520,387,927,540,270,973,545,379,506,627,176,27,416,294,105,471,696,736,472,41,460,845,24,594,409,806,806,778,321,926,331,344,618,535,115,104,956,540,930,470,842,199,287,358,660,839,615,841,641,761,460,37,720,580,687,568,527,360,333,840,906,274,927,430,965,258,933,997,417,579,265,954,698,941,329,140,321,366,733,814,317,445,607,783,244,675,647,76,331,241,24,992,394,592,191,773", "540,325,137,992,634,373,39,216,671,157,788,869,30,671,121,114,940,560,747,924,609,786,132,304,76,509,195,944,2,405,710,429,936,177,495,872,293,274,357,634,979,297,361,211,772,955,815,955,659,597,966,754,824,91,753,583,266,833,124,672,623,81,710,943,103,691,21,854,632,131,434,586,822,265,14,60,730,974,58,80,688,900,609,26,342,52,883,687,769,762,567,254,459,69,919,148,722,518,850,949,277,336,40,517,485,840,147,23,581,405,328,192,293,941,914,381,456,634,594,55,493,905,203,470,201,352,832,922,728,652,588,605,360,787,594,858,962,602,206,106,982,909,388,274,867,412,95,387,675,23,463,326,694,763,919,808,857,343,126,611,417,736,259,182,242,543,474,730,66,892,438,74,213,49,772,274,993,511,83,572,742,133,242,736,860,571,402,330,849,790,542,241,224,111,802,59,67,870,535,818,875,712,110,445,407,482,986,845,298,874,565,405,367,347,943,769,370,808,22,136,481,589,963,829,345,289,174,236,703,7,562,512,586,897,8,680,761,970,307,306,653,849,786,732,826,775,45,26,249,576,25,782,720,548,141,789,624,273,765,416,466,557,867,607,512,506,942,832,142,979,794,649,709,182,903,772,127,539,307,531,744,29,998,694,809,461,664,203,798,947,484,184,914,989,41,500,684,724,930,400,44,724,809,54,112,353,597,591,126,609,105,762,298,387,62,707,193,190,185,564,532,448,774,969,681,286,658,921,574,847,45,360,661,77,285,348,624,356,159,520,55,80,984,686,894,250,324,194,718,432,582,494,371,155,907,384,935,496,256,843,164,37,240,677,434,261,724,442,503,599,488,237,778,813,120,317,160,547,717,600,767,83,330,345,499,287,324,476,442,64,510,123,388,160,6,589,133,497,874,317,356,891,406,227,390,608,556,243,237,464,607,271,61,98,827,64,323,657,242,84,174,968,371,173,171,55,348,216,863,649,180,446,857,559,222,58,665,393,574,703,127,987,263,891,295,232,75,815,794,488,798,824,626,493,874,722,562,823,468,555,877,753,442,511,618,299,342,205,981,735,121,470,752,62,213,798,727,531,435,100,422,209,865,425,468,716,998,13,900,59,368,249,376,703,225,524,925,387,907,587,263,140,885,18,400,770,328,981,470,940,839,973,874,990,631,237,950,262,291,139,490,502,59,144,972,371,631,374,340,253,983,526,734,878,120,926,216,90,818,409,518,559,515,285,691,530,988,400,129,378,482,829,945,424,394,516,307,392,796,24,162,53,779,775,109,747,852,795,943,831,652,984,353,131,493,687,799,181,226,309,899,188,140,576,37,283,140,698,875,692,770,657,659,644,481,306,789,213,290,559,115,991,535,998,125,880,947,102,586,296,289,932,58,912,574,630,739,262,637,680,970,908,780,31,794,868,207,127,791,365,539,13,534,959,32,520,579,720,309,264,547,998,953,667,304,591,985,545,548,900,296,522,842,988,622,190,895,3,188,21,333,868,384,755,742,543,699,657,821,743,556,581,611,153,508,895,480,962,515,311,910,948,693,607,92,602,177,901,101,737,282,187,769,201,143,408,268,255,888,251,478,338,427,489,410,581,656,978,987,985,613,499,790,351,256,860,462,488,820,843,637,562,503,401,562,138,593,22,982,402,352,878,978,776,743,931,230,57,201,160,618,858,569,952,99,328,268,621,55,479,5,378,456,95,240,555,115,605,768,845,885,858,239,809,234,228,753,588,60,706,212,963,898,464,760,200,479,22,531,437,637,710,149,759,838,266,465,316,899,254,651,62,886,570,498,493,655,167,357,204,590,725,513,766,758,493,64,323,447,999,223,962,627,569,710,219,359,838,479,593,578,714,68,496,543,709,250,188,177,837,33,768,521,674,474,361,142,382,964,731,76,941,58,812,521,788,236,92,576,208,375,123,25,372,539,807,594,979,861,50,301,504,881,288,440,776,873,0,170,610,60,441,301,419,340,531,9,67,924,426,429,968,524,865,693,110,728,624,900,580,711,894,807,416,895,974,440,20,531,209,841,609,642,308,93,169,927,35,633,659,888,946,902,28,840,559,44,319,6,765,190,134,971,39,12,576,83,266,245,136,59,793,663,854,546,554,970,749,211,118,167,883,288,619,185,998,831,156,232,518,281,466,798,516,715,334,913,257,244,251,814,950,735,692,658,185,861,352,357,721,155,86,989,461,251,875,768,261,111,865,784,321,929,719,138,808,272,984,387,828,368,577,975,575,297,623,805,244,439,209", "728,321,78,591,987,886,382,200,973,976,86,884,4,295,278,382,210,123,134,29,841,995,361,244,805,499,972,847,308,888,676,678,856,339,377,850,794,36,859,859,962,169,201,28,988,619,623,935,214,779,455,120,660,596,653,391,822,901,238,351,366,676,369,445,794,486,819,501,162,268,921,780,398,778,398,245,845,556,774,166,126,251,437,808,563,28,266,903,546,758,609,169,880,120,767,577,507,603,315,53,1,515,360,84,202,592,661,820,493,556,898,180,424,9,867,173,429,23,239,332,872,967,765,885,357,506,453,733,498,699,808,465,181,698,991,845,287,794,149,648,983,642,955,108,309,247,248,641,337,102,134,344,235,518,124,562,498,503,770,593,318,615,963,928,46,216,929,803,318,793,590,540,247,622,468,966,140,307,422,856,403,605,15,145,68,499,195,261,778,297,975,868,847,35,536,450,54,794,837,617,494,706,753,304,963,119,234,643,406,473,987,329,831,841,476,538,903,965,664,426,290,85,934,622,965,502,603,364,709,901,174,186,71,118,132,211,40,252,354,435,957,740,126,332,988,270,628,299,89,338,778,639,793,153,446,89,623,728,129,386,344,572,992,974,783,105,126,586,531,660,632,172,990,430,21,94,282,274,710,713,637,383,935,368,450,166,73,208,272,148,737,650,287,974,861,6,508,560,247,957,37,237,831,564,17,497,592,705,67,250,688,842,750,182,734,593,247,464,790,574,293,870,254,525,599,232,480,35,555,779,67,944,441,726,457,45,71,316,220,189,448,861,542,243,334,770,636,747,320,170,414,659,581,57,232,231,362,870,928,333,862,35,547,873,88,934,413,391,334,976,414,123,743,468,227,29,728,683,239,679,844,503,715,368,313,803,6,199,162,140,220,304,172,70,944,289,796,227,288,132,238,423,597,277,213,5,482,740,821,197,272,704,396,655,53,956,158,539,289,427,64,724,937,251,788,485,854,323,3,58,916,933,988,887,439,609,995,811,827,406,254,662,353,205,404,586,598,638,654,121,876,487,258,219,929,713,68,665,393,796,654,660,514,230,481,177,171,984,519,439,443,859,999,990,298,509,62,218,51,395,161,899,831,352,848,283,534,359,882,37,227,118,867,143,609,148,214,189,420,265,47,463,23,492,580,663,281,585,450,203,953,718,456,182,165,184,205,686,380,392,855,558,85,159,255,557,459,179,872,649,973,621,590,940,335,822,698,307,645,109,207,589,585,459,487,461,906,897,55,423,693,53,2,592,679,81,640,700,664,55,961,480,102,440,551,734,687,95,206,465,784,114,4,559,64,738,798,601,664,116,669,189,592,408,344,575,886,683,506,90,520,375,186,986,931,645,177,906,637,230,102,217,271,468,235,66,149,95,23,987,843,72,841,310,539,445,466,80,936,72,28,980,139,168,941,641,868,354,808,876,138,985,463,127,231,291,111,686,749,786,184,104,617,713,992,504,976,331,536,760,501,699,77,979,442,275,955,912,848,303,444,601,180,792,552,936,90,106,7,838,93,217,217,679,764,15,827,469,28,329,660,733,273,721,713,591,424,826,116,167,628,327,973,922,445,779,198,457,434,849,598,167,372,575,828,925,518,859,717,992,902,218,534,653,384,334,357,360,410,857,412,864,560,932,757,843,594,716,352,84,709,143,302,299,569,775,279,64,694,654,263,394,616,382,156,69,734,758,159,49,902,882,104,189,555,580,95,678,119,509,881,273,700,687,67,444,288,793,369,957,660,436,96,281,840,144,223,825,171,969,380,144,841,887,41,292,109,203,97,88,152,600,275,254,317,853,430,622,950,979,674,949,997,720,579,820,710,70,236,39,210,139,360,178,75,157,141,623,751,391,308,704,832,934,315,926,432,474,943,889,737,68,841,298,361,719,830,470,944,73,961,796,129,793,410,768,776,468,910,466,581,102,274,7,31,25,166,462,907,959,131,694,46,662,331,977,468,170,0,832,431,219,125,268,97,129,783,741,978,386,510,804,952,59,332,537,130,762,494,927,28,311,83,563,273,177,214,857,903,170,990,340,500,898,323,123,561,164,893,768,996,816,139,965,424,72,966,584,56,341,801,172,342,395,176,239,520,686,411,480,28,670,121,659,187,207,53,44,659,460,23,532,432,771,861,709,874,628,731,84,740,189,559,516,782,682,386,419,379,479,802,597,532,616,337,236,725,118,786,506,451,268,613,282,323,155,986,36,94,847,120,784,676,970,472,428,569,804,430,195,963,586,730,594,120,463,58,343,455,168", "801,501,680,861,30,830,466,968,836,138,753,873,724,600,785,657,952,732,810,312,927,892,421,317,797,963,201,261,209,284,644,97,427,752,661,314,253,509,668,619,880,451,476,993,790,107,183,571,721,67,604,920,920,944,966,657,490,752,787,509,120,527,856,868,11,530,713,421,587,775,187,626,770,601,846,93,931,804,390,320,845,842,393,940,603,866,724,1,339,760,901,859,275,951,990,174,754,528,413,926,314,15,185,963,741,59,382,386,115,679,701,78,752,997,671,612,725,634,818,928,822,870,793,44,378,152,158,714,338,714,835,157,380,269,880,354,298,909,560,258,83,100,498,625,35,960,529,567,371,800,364,342,125,3,159,560,823,93,991,367,124,495,972,28,704,663,288,507,253,265,251,955,724,206,204,154,213,512,234,181,96,221,119,966,29,636,573,870,644,869,938,452,731,254,820,419,323,536,255,637,335,919,682,987,504,65,317,50,918,236,547,185,812,909,627,340,845,351,541,689,719,778,227,479,859,209,198,156,443,506,412,667,261,57,551,881,841,989,743,984,599,433,98,416,563,306,559,734,720,835,865,296,6,223,667,157,682,407,814,903,766,256,213,75,245,248,309,360,717,775,159,394,455,996,738,167,946,354,269,485,613,47,259,51,845,248,995,104,891,712,915,845,10,449,979,820,777,16,465,688,880,802,762,296,599,382,988,728,763,348,618,721,245,126,658,1,360,317,855,864,795,693,13,187,671,15,622,96,784,56,729,835,815,383,536,813,258,104,372,170,636,551,182,978,58,7,961,585,25,106,484,526,507,661,394,152,480,130,132,237,811,869,479,377,584,830,147,651,62,279,679,752,258,439,651,210,873,694,225,417,301,385,172,67,967,654,333,266,491,504,269,443,565,407,310,362,872,508,586,173,271,53,116,290,183,301,496,522,765,3,696,508,597,333,14,204,931,915,956,769,860,579,781,24,736,685,878,615,735,244,974,479,590,302,458,253,778,102,969,79,434,166,762,123,270,464,248,938,516,746,562,772,670,831,892,880,285,328,607,510,856,306,454,6,239,728,850,462,90,494,587,384,401,852,109,903,556,886,695,917,11,620,478,469,158,653,963,569,417,347,504,84,260,555,357,601,166,914,578,663,419,933,308,831,96,355,92,119,943,632,526,236,833,287,917,91,783,178,705,305,524,376,139,63,829,626,233,541,993,892,933,649,268,85,21,95,19,482,407,971,497,904,346,86,147,384,52,263,50,246,766,847,48,490,462,914,364,550,391,311,194,809,321,469,221,106,168,501,534,686,621,852,267,261,17,43,199,17,308,683,357,612,811,690,55,789,608,203,171,594,912,713,785,494,514,789,22,40,925,99,138,215,881,751,165,888,92,940,951,395,198,654,504,632,435,702,453,804,255,585,618,408,484,300,63,222,638,69,561,570,358,728,792,306,732,167,641,62,99,281,57,320,261,472,538,300,10,209,844,140,169,456,224,490,863,801,346,927,269,9,575,838,197,103,895,729,564,144,869,163,805,128,475,843,758,469,575,924,615,117,733,243,711,739,928,790,282,296,472,725,246,684,366,67,986,753,198,84,810,741,495,98,627,693,59,574,16,243,932,435,935,356,456,992,110,203,289,655,504,882,896,453,932,38,900,567,756,858,986,203,24,419,264,950,394,889,745,61,605,460,142,833,155,631,679,872,551,19,958,249,652,198,128,137,16,204,155,571,361,426,229,946,598,892,825,982,885,543,160,671,188,597,355,129,622,75,200,289,771,256,970,66,274,116,308,822,746,648,86,912,735,916,934,387,670,662,596,447,125,251,496,546,556,641,677,34,517,590,683,108,97,884,76,145,154,659,879,768,185,852,137,393,717,703,277,128,636,139,890,473,261,358,101,951,370,229,144,958,448,352,779,50,468,433,191,373,209,65,462,811,960,452,378,899,917,146,660,972,835,897,441,423,936,731,670,578,434,610,832,0,197,942,742,322,437,330,906,327,774,338,890,412,258,60,570,948,203,552,261,615,378,141,84,561,850,337,158,473,129,54,534,781,391,857,299,537,362,748,780,545,239,98,398,297,189,150,717,449,746,678,779,647,784,430,643,198,170,733,756,594,590,104,287,256,506,384,130,569,795,399,137,54,967,995,957,825,100,879,446,496,337,206,837,352,171,943,702,801,707,469,993,293,255,12,943,63,402,694,391,349,153,950,998,576,795,611,51,748,371,315,607,342,680,335,432,203,183,451,343,65,212,906,972,863,817,125,530,949,677,929", "351,876,825,91,171,290,605,875,330,658,760,211,250,152,358,442,116,948,808,78,87,437,680,438,899,373,976,358,958,490,820,272,896,286,496,264,41,701,582,37,604,892,271,366,237,643,950,884,865,657,2,443,538,512,71,343,961,111,926,248,911,634,953,261,11,251,226,242,931,504,844,204,712,469,474,918,295,30,329,106,540,141,299,625,931,383,488,559,468,486,549,352,760,870,374,971,354,186,665,160,612,938,881,703,599,710,147,83,905,231,19,559,60,273,784,918,763,362,22,250,979,874,926,587,654,44,593,175,122,393,435,934,551,69,614,694,564,623,314,462,15,134,698,792,623,320,347,251,91,953,854,68,271,826,90,28,917,787,397,926,6,998,992,14,311,70,479,189,84,711,128,654,28,934,758,853,483,396,763,717,732,770,727,746,626,671,164,222,296,625,540,140,732,661,221,309,745,314,721,709,943,786,441,728,242,736,576,718,107,990,143,694,932,316,404,407,16,685,458,513,409,176,758,627,842,388,890,536,125,338,421,428,405,726,462,469,464,338,970,721,593,190,878,97,232,614,618,340,537,9,483,806,255,16,211,971,51,268,39,265,429,566,949,225,39,889,696,60,957,215,272,391,12,451,816,266,708,969,145,124,293,757,591,984,562,197,635,643,792,730,980,894,29,973,605,654,548,456,632,436,764,918,556,801,216,351,76,414,719,941,726,76,266,677,245,950,495,778,86,11,443,472,244,978,994,759,800,881,377,823,686,964,763,661,633,855,31,613,854,132,341,802,996,776,633,110,858,150,882,188,631,532,118,936,525,405,524,80,247,213,163,66,97,807,450,180,311,983,588,420,396,584,70,711,562,113,608,473,737,366,975,191,736,21,976,94,749,490,267,476,16,714,798,15,751,130,678,272,902,337,236,531,470,353,734,260,989,994,696,372,77,106,781,75,386,623,350,985,841,450,57,756,544,251,265,745,669,630,175,707,973,28,469,918,78,769,129,808,102,255,723,547,926,888,749,33,580,609,712,385,960,80,135,979,210,288,919,383,552,576,761,826,914,385,745,198,292,408,990,420,162,974,503,398,166,478,648,517,131,878,857,419,379,597,378,117,412,207,500,249,841,425,313,48,856,692,331,471,20,55,614,549,138,29,448,437,24,764,858,201,140,352,237,422,332,871,625,252,9,997,599,310,80,822,800,597,116,529,42,244,50,494,191,904,611,889,510,375,603,443,784,753,134,437,936,420,648,183,294,317,70,617,794,267,510,924,129,625,715,104,727,891,647,610,329,702,453,456,6,922,556,679,64,61,807,10,939,31,23,153,400,434,764,414,455,120,146,483,876,596,937,379,436,554,608,810,557,234,769,294,940,210,773,45,757,329,343,744,829,858,506,62,751,827,850,554,749,797,786,234,324,671,232,928,92,630,94,475,617,844,290,493,348,253,375,571,157,116,235,236,765,781,847,343,997,853,765,727,297,267,948,336,19,454,786,291,186,720,321,878,432,338,745,203,237,429,976,404,969,627,545,563,787,990,905,868,895,945,802,116,945,715,94,280,668,281,491,166,917,482,598,705,137,970,540,768,434,42,635,639,42,995,804,896,924,70,184,771,422,942,142,897,354,443,247,918,981,810,672,917,435,105,890,814,401,848,343,82,161,322,529,271,200,539,29,678,656,675,45,394,886,114,778,178,430,420,229,118,469,721,690,686,824,343,379,734,201,715,734,635,914,462,674,696,54,93,244,165,845,698,283,682,290,749,995,48,522,332,579,384,856,64,318,767,40,189,50,238,110,512,767,481,257,258,658,129,363,822,715,294,852,789,960,661,559,55,257,295,544,583,478,190,970,226,557,856,716,43,337,280,675,652,887,56,24,978,463,699,316,48,32,456,447,743,759,708,566,520,331,726,585,503,131,668,978,909,522,967,243,539,576,89,549,883,137,937,540,46,738,54,134,457,755,939,309,357,174,60,431,197,0,483,403,662,286,263,464,722,7,140,823,58,821,738,790,305,372,949,974,691,169,269,403,860,345,84,639,342,796,925,75,749,181,419,36,658,318,682,309,848,250,554,381,636,532,393,66,468,795,381,463,626,859,921,78,697,66,391,588,836,618,980,228,350,663,429,682,383,447,534,751,634,632,425,23,364,625,38,137,508,180,430,138,352,607,618,455,518,400,911,109,892,3,49,557,11,372,97,374,923,467,191,667,221,981,56,273,396,85,602,934,792,322,26,496,778,480,996,129,52,560,570,506,702,333,234,942,253,606,899", "2,240,283,261,900,344,22,425,595,146,749,401,425,838,170,611,453,710,998,830,804,480,131,348,104,626,794,806,440,901,535,861,627,593,173,188,163,36,608,11,78,156,37,715,131,608,109,685,827,82,157,205,52,92,687,516,63,462,135,932,598,713,999,29,993,607,975,783,137,611,295,379,406,566,468,893,955,106,97,88,649,356,398,104,597,421,141,541,241,519,136,767,853,591,712,710,107,709,356,137,178,699,437,157,586,216,582,746,893,867,247,716,822,75,356,643,786,298,855,682,152,394,159,643,472,194,726,327,475,757,233,739,55,778,82,407,493,980,556,950,815,51,318,906,666,662,701,375,923,401,280,454,257,346,27,846,826,777,543,227,78,144,324,984,840,891,16,214,120,555,984,187,695,698,263,177,849,495,338,861,77,78,666,581,886,383,661,342,317,742,549,251,461,447,627,673,310,313,565,148,488,395,671,839,146,749,698,633,961,899,872,352,293,185,212,937,47,164,964,639,790,485,269,114,777,804,352,715,491,932,599,877,470,324,29,372,314,32,145,882,671,832,729,754,710,460,820,168,156,635,980,751,583,94,898,68,271,908,202,765,333,351,827,33,857,744,37,825,154,743,395,572,871,102,801,966,4,930,889,116,541,123,465,1,503,647,669,479,524,866,808,385,382,277,908,25,46,386,697,590,669,195,584,98,540,243,780,153,45,358,548,552,954,667,478,956,191,951,775,516,175,259,903,635,153,938,525,852,360,250,406,131,622,918,73,639,920,406,297,372,616,531,271,363,41,602,859,258,325,624,32,493,223,100,52,703,385,767,488,201,49,351,126,500,284,814,644,662,263,238,517,880,938,553,829,212,377,637,25,426,204,67,792,384,487,533,660,740,863,713,322,258,824,890,344,988,462,235,184,462,712,182,615,690,429,5,569,310,951,293,473,429,308,191,557,612,504,479,802,99,361,112,959,240,321,604,834,468,64,837,415,240,836,150,631,37,244,83,184,853,209,908,132,540,174,522,164,288,646,132,629,24,993,190,535,723,653,37,214,663,782,830,136,592,290,750,326,699,634,96,541,860,598,176,502,680,341,520,377,231,229,509,18,678,858,664,268,908,923,569,128,617,72,927,46,590,997,579,482,466,947,347,687,643,745,589,858,259,704,579,958,920,702,294,981,675,329,708,280,395,941,27,455,38,126,113,1,359,150,716,364,513,201,964,863,72,707,308,139,862,437,917,674,165,604,221,950,688,495,220,650,454,279,439,470,635,835,508,347,687,691,489,929,701,716,786,439,231,965,816,702,184,397,699,567,528,381,283,661,89,682,232,279,812,204,179,815,687,243,263,645,680,23,817,403,925,251,915,164,971,388,734,183,347,731,231,62,156,49,980,65,413,317,863,663,459,755,747,35,975,898,720,50,291,520,428,222,896,807,243,741,142,799,936,535,689,792,989,630,444,95,128,227,696,583,152,73,466,752,321,777,491,930,578,792,932,425,367,70,306,536,164,499,991,675,96,397,202,29,288,421,675,302,726,948,382,993,4,480,195,698,626,94,73,237,989,270,138,657,911,466,914,778,293,575,360,122,502,390,764,486,705,617,285,484,794,84,998,227,771,993,743,659,117,86,558,243,548,630,545,335,471,744,631,574,899,338,893,44,272,157,202,652,602,33,724,129,752,39,989,196,202,758,728,947,564,219,829,134,794,706,884,41,320,342,385,55,948,701,510,871,64,263,139,951,365,827,249,242,411,572,160,228,629,59,189,133,335,548,101,826,670,78,960,258,87,901,493,755,70,334,414,57,565,653,168,40,810,809,99,234,390,64,697,159,968,567,461,783,393,442,610,240,165,307,490,792,345,314,315,539,125,240,202,338,413,846,299,907,953,390,65,729,601,238,67,22,101,450,770,514,456,340,896,791,550,188,159,230,563,486,875,198,731,505,479,134,351,103,247,449,730,730,418,341,704,682,441,219,942,483,0,870,796,66,1,503,317,914,116,227,200,386,651,758,181,962,128,613,553,85,710,280,569,525,586,375,533,906,655,793,649,129,767,812,624,648,914,378,662,284,921,688,740,166,778,548,198,702,380,430,292,572,138,232,645,990,307,721,648,358,975,914,912,926,627,616,350,713,198,688,57,498,550,92,774,864,227,603,845,174,569,228,504,538,494,930,971,454,554,618,389,867,149,511,693,789,384,531,499,187,587,399,34,84,861,518,911,903,505,491,138,134,254,987,643,109,644,175,459,342,380,743,49,499,517,714,745,974,38", "553,152,630,411,638,379,574,519,127,177,549,280,192,929,436,45,566,589,663,91,522,516,285,41,566,801,660,629,61,388,678,648,125,61,667,214,481,381,784,955,969,581,992,513,679,126,15,136,369,107,615,873,659,86,714,829,794,319,974,497,181,538,61,265,507,142,894,32,697,838,971,577,542,961,338,453,986,445,260,233,1,12,895,935,636,162,339,748,109,730,546,299,709,834,818,474,209,897,11,138,658,944,773,180,293,19,816,473,535,152,927,127,985,780,567,71,3,592,448,9,579,960,492,783,712,131,822,806,25,701,308,599,536,362,787,642,396,426,943,445,942,741,124,227,755,752,191,753,269,570,162,652,774,59,328,666,625,221,108,27,849,484,845,35,425,370,437,175,977,788,908,911,575,918,62,595,448,924,394,828,694,292,375,661,357,839,428,290,662,815,435,607,874,200,67,685,141,676,139,640,772,747,289,305,926,734,497,179,348,626,590,366,502,993,712,266,141,428,418,220,291,779,827,32,452,103,598,846,91,395,834,268,73,231,504,444,17,274,233,250,534,721,141,761,946,337,517,838,426,182,943,230,300,413,925,60,347,108,107,715,581,599,784,503,972,263,518,974,393,987,320,371,614,734,608,186,343,785,50,861,968,368,865,282,508,872,335,179,199,559,512,219,206,982,735,54,909,720,819,768,220,958,750,201,428,461,330,691,55,647,289,432,345,686,433,623,221,558,753,935,574,367,477,309,844,611,760,154,146,385,464,236,829,601,452,552,862,387,448,370,235,34,112,954,501,890,518,464,622,155,667,484,484,587,612,96,488,456,666,864,351,988,888,430,13,942,963,492,104,630,984,873,559,461,353,881,831,7,380,47,211,952,352,114,80,128,94,37,53,159,541,860,819,302,606,175,571,533,382,310,614,259,861,236,164,384,465,351,946,809,337,843,43,915,302,928,421,800,907,356,810,33,64,746,542,565,575,530,338,574,784,771,354,239,611,967,136,515,309,212,836,554,373,841,918,96,706,45,806,162,906,875,346,723,47,445,745,662,731,701,359,363,483,980,926,924,965,463,553,932,149,465,277,20,992,7,515,1000,297,122,913,717,229,228,767,538,790,852,993,202,149,162,587,935,863,243,99,551,675,470,400,236,712,595,279,883,906,272,275,195,428,288,742,905,876,94,89,356,492,164,776,718,500,48,149,590,286,126,606,739,398,342,298,271,371,578,480,803,403,189,265,902,726,55,381,525,287,518,668,840,413,877,482,795,729,347,542,566,107,981,352,495,193,115,204,407,298,377,96,426,8,971,842,511,321,37,958,210,627,692,511,280,97,127,91,487,231,865,436,772,495,676,266,427,167,482,357,444,205,29,997,666,854,997,785,813,24,527,694,373,956,398,220,127,526,29,845,27,377,961,790,827,870,648,418,344,904,820,626,602,470,69,970,402,692,74,211,705,633,88,170,464,465,493,974,218,474,389,795,190,935,426,604,796,269,805,469,511,255,318,595,586,391,464,221,177,811,43,449,345,894,717,683,232,269,55,465,790,30,273,271,785,636,184,59,82,986,876,809,18,129,339,376,458,729,532,976,124,801,838,601,86,701,814,58,541,379,461,633,250,497,614,764,862,400,303,795,174,268,791,190,40,185,797,975,41,596,737,664,199,950,432,371,872,285,969,984,791,752,907,826,697,82,368,674,493,801,313,486,28,247,495,544,447,622,105,580,347,577,236,882,113,933,35,179,686,61,225,37,565,100,397,418,251,478,410,493,144,88,17,136,956,917,186,889,840,764,382,935,49,591,545,305,901,697,599,606,37,139,90,318,127,223,116,810,804,850,330,194,810,845,160,404,61,834,684,941,605,841,190,486,162,651,176,714,17,361,211,752,374,237,527,561,977,113,956,331,379,553,127,720,588,710,69,365,797,463,325,558,696,136,45,400,696,690,95,29,880,503,295,323,875,564,920,927,890,564,301,125,742,403,870,0,606,151,800,313,735,47,22,594,985,133,157,419,829,518,949,270,781,740,343,477,260,700,473,179,800,361,719,731,808,109,372,691,110,318,682,959,867,370,936,807,325,241,633,971,406,993,727,627,875,78,281,624,835,858,746,527,353,416,229,719,829,112,352,498,448,630,683,220,992,769,798,463,398,776,348,687,579,828,835,513,147,771,923,980,592,778,23,337,512,794,562,205,296,312,971,242,692,333,543,396,458,304,519,184,446,526,224,697,121,809,424,366,908,82,123,662,168,558,899,871,319,103,302,19,50,324,421", "75,734,661,717,276,174,750,939,270,817,657,705,926,369,487,519,510,446,254,74,281,516,27,171,646,74,691,666,808,963,43,264,813,55,486,466,6,76,704,6,368,694,942,7,122,628,322,893,282,77,758,366,874,970,17,414,15,849,980,659,919,4,742,705,31,122,239,981,909,929,358,5,529,622,314,46,513,683,161,217,426,220,462,705,755,494,701,552,824,106,330,222,671,131,984,537,606,880,756,698,873,464,454,491,569,539,805,12,183,194,482,8,75,358,397,480,536,229,875,833,966,947,575,500,493,129,117,662,559,44,984,325,354,535,739,791,273,619,870,925,60,735,928,376,166,11,104,932,634,174,745,742,416,126,322,692,28,346,264,636,793,531,459,853,192,768,673,798,605,697,58,883,636,894,428,39,751,145,534,213,770,879,690,107,315,371,446,985,734,96,323,284,471,825,727,622,696,88,90,613,804,540,846,488,759,182,133,205,413,811,206,271,180,893,502,833,758,937,220,814,346,780,333,864,798,104,980,873,710,265,734,657,952,240,615,435,760,279,144,59,679,137,126,805,724,405,662,695,298,380,778,480,558,799,192,347,43,822,278,853,3,536,970,677,320,230,186,538,479,174,796,164,705,191,425,275,590,104,315,318,450,175,7,160,1000,207,908,313,24,807,938,591,892,939,440,694,379,55,345,877,918,572,505,826,533,796,343,448,473,820,455,989,407,258,99,611,282,732,584,568,360,459,204,54,721,318,491,719,828,271,574,337,735,672,988,222,892,436,435,489,737,728,227,899,771,897,845,263,175,575,280,457,367,982,360,981,644,412,764,321,38,523,454,667,126,483,335,343,967,809,200,82,885,41,995,675,643,602,878,84,222,511,217,994,968,156,311,456,233,671,176,849,31,290,407,931,177,483,817,933,279,172,4,371,468,784,109,490,14,602,51,264,7,103,869,282,282,202,990,44,142,755,48,908,820,544,286,574,675,194,135,610,56,266,523,480,549,629,830,466,32,310,253,965,362,568,560,308,811,993,970,834,439,900,425,670,640,948,818,656,166,108,306,608,639,603,711,568,780,520,619,581,861,157,781,775,80,98,708,952,615,462,255,678,964,765,11,370,494,204,72,81,968,190,696,239,28,863,549,573,626,161,467,613,361,532,724,414,30,800,674,515,602,193,874,337,266,5,29,269,526,766,19,253,761,535,674,268,226,16,490,117,42,992,582,93,943,306,844,143,53,61,548,522,878,708,45,289,190,160,729,302,469,579,428,708,556,238,825,702,729,524,937,379,88,675,908,319,241,351,617,341,100,643,19,601,410,208,657,96,411,337,839,307,953,191,160,222,542,902,457,370,580,92,692,444,679,217,414,864,552,604,556,748,608,489,466,671,409,752,248,717,209,69,779,13,459,632,195,89,38,809,166,809,59,642,985,111,635,380,401,34,429,834,176,579,34,567,59,745,856,930,581,876,896,590,709,1000,864,518,851,967,239,564,568,459,456,517,508,343,535,665,361,789,356,124,56,661,295,283,312,600,598,289,316,532,924,923,146,630,339,462,253,705,764,36,670,589,672,251,915,117,641,398,165,604,995,567,333,653,188,705,749,628,420,124,906,310,659,126,332,828,106,368,180,347,987,150,936,953,588,805,52,916,534,884,941,656,301,64,78,290,74,594,887,392,30,796,732,389,671,447,854,137,527,682,225,852,208,339,254,425,699,12,33,991,290,309,418,649,249,341,445,951,818,973,588,413,237,414,374,934,173,947,536,263,553,361,418,377,162,370,712,186,811,958,994,456,894,73,95,194,605,112,157,486,707,11,777,967,559,371,34,434,888,384,454,721,386,230,952,475,499,35,465,921,73,432,677,479,205,568,354,69,895,205,953,18,447,832,721,252,877,86,75,413,881,135,968,952,955,106,56,956,347,319,433,963,37,572,698,359,790,695,725,378,296,913,235,824,469,325,62,63,34,150,311,419,268,322,662,796,606,0,314,71,881,115,721,39,531,730,83,587,154,809,626,973,148,27,618,764,503,534,414,341,818,231,498,703,933,773,566,156,172,960,338,675,482,475,607,48,852,275,928,576,141,948,68,711,893,504,459,296,324,552,949,793,699,254,150,136,2,644,288,345,885,373,467,878,929,902,997,752,247,838,700,297,418,132,155,832,159,470,14,374,514,518,474,902,85,321,116,22,250,468,796,512,849,73,549,947,408,625,967,90,959,855,478,567,545,472,965,413,175,377,186,279,216,618,205,798,183,852,545,472,64,89,184,838", "595,13,843,702,703,273,443,924,968,204,207,815,488,942,968,755,80,476,253,292,60,863,640,665,922,688,203,96,141,838,583,829,585,90,447,967,166,945,327,663,201,527,918,476,274,431,552,469,13,186,638,146,511,664,826,618,829,329,758,22,42,105,695,568,253,31,301,426,712,997,205,873,344,111,433,94,758,435,35,561,953,850,431,218,953,674,669,21,439,350,242,334,592,863,46,965,361,13,676,568,659,305,304,549,232,364,423,153,257,566,793,98,361,174,470,684,713,892,490,482,323,543,132,279,365,434,496,63,387,554,854,625,978,359,470,669,12,959,83,103,843,721,811,134,969,663,243,870,450,790,803,867,612,522,679,71,842,291,28,715,471,358,749,754,795,797,324,453,628,678,7,452,721,20,523,748,996,384,306,834,186,96,380,267,698,748,875,746,387,41,891,7,848,855,957,845,243,407,241,131,539,702,862,851,799,213,555,989,139,116,840,19,387,15,924,576,244,825,149,894,268,355,704,347,381,523,462,24,406,499,551,374,882,295,160,927,145,837,316,344,101,200,422,829,560,26,44,656,395,602,363,288,96,196,388,447,520,385,77,984,725,351,417,2,239,843,281,185,827,436,20,260,983,644,123,873,836,17,409,288,756,718,497,942,618,777,147,447,443,810,661,44,275,92,592,936,587,212,411,875,574,644,161,564,358,320,194,584,650,812,967,115,349,345,773,176,365,676,173,519,346,341,419,700,456,583,220,322,987,502,964,454,176,198,704,404,444,528,180,813,725,612,79,53,708,924,436,329,953,187,10,318,442,309,707,162,64,687,854,343,197,854,858,117,703,77,817,60,619,761,405,246,690,301,963,69,183,112,991,962,525,589,78,889,888,348,568,641,176,463,398,393,199,766,805,241,361,416,98,223,434,340,661,259,205,21,685,71,175,904,463,525,692,353,439,928,506,635,999,514,950,209,119,202,930,681,618,490,674,144,845,311,976,839,166,865,350,96,401,344,279,633,794,322,520,637,614,938,200,435,747,382,452,617,408,956,752,948,881,306,952,556,120,983,703,736,283,168,383,81,696,380,642,786,345,620,853,164,761,363,221,623,145,108,295,792,841,267,196,266,859,547,157,913,409,330,880,132,635,35,518,72,242,732,562,377,123,365,726,143,523,960,213,224,953,490,123,252,502,650,563,677,868,541,578,74,10,909,737,381,507,150,661,887,791,112,352,739,920,456,526,359,872,142,414,91,940,545,473,350,301,376,828,984,236,377,204,470,625,333,79,32,862,323,430,763,589,742,746,913,275,421,163,168,448,446,140,57,817,802,212,84,860,153,721,351,889,603,671,510,432,494,863,993,109,446,114,650,643,947,586,380,338,381,906,125,573,624,567,836,117,43,909,314,76,392,683,424,383,12,232,68,211,731,679,458,220,899,225,99,350,984,333,597,265,385,991,547,229,125,308,298,567,726,452,109,68,480,256,33,429,442,381,630,109,91,850,718,817,927,467,993,865,414,161,394,193,943,665,102,198,253,992,749,989,746,436,733,537,793,154,264,862,512,293,653,656,425,212,935,369,608,140,288,946,248,792,396,451,548,350,619,912,559,49,40,518,789,188,598,24,291,463,650,79,771,329,592,776,333,636,484,767,88,978,465,679,508,363,226,948,371,99,633,524,729,845,703,580,555,172,298,409,641,389,5,399,547,202,18,518,31,743,21,631,352,260,424,197,554,401,263,582,668,781,606,505,716,302,696,927,11,554,604,368,734,105,161,723,307,546,373,61,484,95,267,419,750,766,518,345,711,983,424,664,807,747,134,83,899,479,157,354,212,545,899,48,604,746,84,298,186,778,381,30,649,139,20,634,77,294,428,795,318,306,80,488,168,985,982,401,163,489,411,891,51,538,776,83,362,937,885,330,833,647,757,426,580,712,923,516,775,285,186,394,361,557,476,487,553,679,496,936,398,190,738,946,340,97,437,286,66,151,314,0,785,53,921,327,202,421,772,994,970,851,177,937,386,363,350,794,769,739,350,661,12,333,369,709,837,556,136,876,604,155,181,46,221,998,992,402,20,181,285,891,82,322,401,905,420,21,390,347,979,616,677,121,975,966,960,187,633,391,36,419,348,732,824,481,829,307,523,245,3,784,858,622,776,739,427,45,985,473,563,698,152,754,374,544,364,784,987,645,561,337,532,821,439,280,548,608,566,879,952,193,445,76,63,284,453,278,423,154,206,491,476,520,195,396,67,134,551,959,854,487,346,659,65,156,199", "907,707,964,901,265,988,385,447,972,801,400,644,301,140,898,587,216,28,14,105,719,965,342,969,402,836,642,982,687,655,786,845,60,787,117,22,419,605,492,288,352,714,140,362,491,727,861,380,441,941,846,264,894,326,791,727,794,836,734,690,147,840,158,865,764,38,491,415,301,732,257,434,980,457,916,802,194,571,774,648,561,415,120,963,814,119,518,6,855,974,842,177,874,62,382,142,326,673,796,608,588,999,549,409,311,480,341,799,344,41,828,615,325,839,924,3,549,537,150,140,341,272,687,418,910,992,706,68,342,534,791,499,799,798,469,838,686,337,269,879,541,855,545,160,204,164,828,639,288,363,395,964,182,729,388,848,228,887,737,328,633,547,583,57,490,174,339,974,428,96,929,764,529,620,697,505,909,155,334,636,789,821,791,536,198,431,262,669,851,388,120,26,348,289,230,227,953,217,141,470,505,771,164,118,28,937,976,631,542,196,248,887,968,507,757,76,906,399,795,299,902,218,337,896,999,968,112,770,831,895,976,56,826,300,307,206,998,304,759,865,424,768,138,440,383,959,452,678,45,19,706,633,43,40,24,609,23,934,925,252,443,993,126,437,359,304,930,607,15,407,533,896,118,348,407,701,469,383,481,776,934,771,178,470,68,299,265,498,78,826,481,597,38,41,205,674,42,870,663,596,669,568,63,555,48,554,101,169,957,836,722,264,799,387,708,446,129,848,791,554,370,119,66,975,820,820,707,918,558,159,507,715,73,243,837,649,969,551,586,79,857,672,672,371,609,108,205,773,506,734,641,166,763,670,987,113,995,227,306,617,840,203,77,96,483,870,76,144,247,555,830,582,411,28,523,210,275,594,268,422,42,536,737,739,970,991,616,963,747,373,368,462,441,270,189,177,862,2,162,722,192,329,896,789,630,296,301,264,857,147,995,322,819,590,102,924,992,200,898,324,891,665,400,255,649,176,686,891,385,200,231,426,845,654,73,455,725,493,774,50,675,779,20,528,573,191,630,467,380,81,950,978,123,479,782,363,711,604,746,83,970,571,595,454,7,280,209,632,182,778,91,390,664,156,421,837,497,142,327,288,245,289,94,541,599,16,652,803,477,979,494,822,701,156,362,253,155,83,69,932,917,257,417,705,90,62,948,529,482,784,33,852,865,475,96,152,668,801,368,298,58,41,738,446,383,30,604,432,518,743,887,289,331,297,292,466,486,682,519,883,119,656,692,149,191,298,444,400,975,92,707,460,340,899,722,480,964,21,632,499,156,15,908,509,444,166,407,8,674,77,924,618,6,283,373,756,957,419,636,703,984,593,759,554,256,178,361,206,592,150,128,153,75,230,926,783,911,122,634,828,923,186,452,764,733,100,258,683,703,620,991,580,361,356,231,463,60,477,284,880,886,330,843,683,146,455,556,805,408,521,61,246,257,864,240,821,118,798,47,87,630,535,603,727,936,258,163,603,75,607,339,310,984,566,385,826,168,643,940,41,513,281,638,641,912,219,425,554,264,748,148,942,312,158,740,963,450,92,564,36,469,88,915,241,418,206,708,793,266,349,245,553,773,824,706,394,130,792,826,83,368,711,818,990,826,170,997,862,338,812,40,277,352,519,638,211,766,549,597,746,799,473,259,489,787,806,683,632,889,7,929,515,292,111,493,971,736,465,297,652,520,603,64,932,241,409,530,842,604,88,17,246,518,63,91,82,537,28,425,388,680,653,174,925,670,973,664,334,611,40,324,886,532,225,656,250,966,347,808,188,449,409,794,404,482,327,437,821,569,572,262,614,541,120,868,285,866,258,199,631,788,714,551,35,129,504,256,131,173,930,294,443,695,680,72,347,856,476,447,922,616,812,539,813,673,939,540,34,928,682,316,921,898,265,430,376,669,881,854,729,738,767,699,950,309,543,13,925,57,781,628,97,841,939,770,5,786,254,468,905,87,23,537,617,302,950,374,531,129,330,263,1,800,71,785,0,458,823,21,648,341,173,896,394,81,677,337,275,791,836,344,255,908,903,378,234,800,141,102,123,671,546,572,765,486,383,709,575,108,234,519,922,436,177,843,631,615,460,870,646,449,440,668,355,467,455,706,569,677,367,585,101,612,678,265,20,474,17,926,818,769,100,316,176,58,531,253,234,394,521,947,858,451,895,176,353,244,539,818,963,936,278,332,46,807,490,573,866,385,889,589,644,58,34,579,889,125,67,864,400,58,945,994,768,297,277,377,547,421,215,434,549,784,975,939,918,781,675,896,468", "299,607,443,488,664,561,172,356,718,600,129,923,306,231,623,2,722,524,475,690,263,660,777,106,776,185,301,270,385,618,337,696,133,739,997,9,654,813,428,879,654,307,895,108,134,993,432,13,115,706,966,568,197,515,200,260,240,377,120,504,6,814,552,330,235,250,900,662,204,58,670,979,897,100,267,224,538,74,619,685,75,698,86,247,967,684,545,673,996,790,964,758,985,676,850,283,153,537,958,697,554,314,862,94,266,93,850,702,219,829,910,830,849,574,36,449,499,892,681,314,196,849,648,716,330,689,29,119,432,962,496,951,523,848,911,610,440,559,402,861,539,685,713,534,292,208,591,942,401,451,565,620,595,89,306,351,280,590,54,930,280,128,855,689,407,955,484,92,146,939,97,244,280,60,152,99,46,767,71,322,252,558,304,443,445,176,89,432,468,216,571,458,253,693,72,443,992,292,948,427,765,315,922,580,602,91,886,20,191,189,653,373,25,129,780,477,22,156,875,366,332,166,525,550,344,822,300,797,183,868,277,725,131,677,382,176,899,670,326,510,580,18,264,160,600,56,392,499,129,919,854,439,178,94,464,713,917,426,112,700,793,786,171,777,447,305,83,982,512,105,66,228,924,701,962,656,710,640,784,682,963,683,332,747,880,713,869,148,956,658,301,917,803,798,379,39,232,577,57,349,984,945,354,546,207,428,86,716,639,987,776,493,342,973,958,299,380,29,694,444,777,384,577,480,384,51,508,787,561,858,879,225,482,937,733,215,997,818,870,486,564,148,924,102,297,596,707,166,626,379,40,947,982,420,483,852,747,768,331,756,949,318,772,764,925,259,470,904,499,455,159,423,486,472,245,807,426,83,666,594,114,374,442,848,499,242,275,28,990,580,513,927,106,710,289,480,102,369,550,801,450,270,772,750,401,453,197,49,263,922,22,408,63,652,952,823,698,845,987,36,2,619,263,331,856,647,245,137,423,199,357,319,757,270,12,912,262,338,294,520,428,944,781,519,58,244,194,884,558,610,670,932,26,155,423,329,430,561,66,395,745,628,706,924,534,381,478,504,729,713,42,885,706,554,324,540,905,790,682,920,200,697,728,157,230,586,589,485,229,347,66,253,280,741,173,179,137,627,815,310,990,455,87,123,119,879,478,31,841,221,805,456,533,210,793,206,512,174,665,555,414,723,629,632,6,920,529,595,231,805,324,903,609,400,111,235,715,665,989,666,976,15,420,707,815,221,844,188,489,301,45,55,973,14,449,830,305,948,747,912,849,644,450,155,3,554,721,831,770,688,262,112,443,547,462,881,745,425,519,478,674,395,403,835,341,400,620,582,231,324,392,865,482,218,777,587,381,165,737,747,36,692,353,164,762,851,326,988,853,970,77,178,703,177,563,111,749,879,754,601,914,733,235,743,761,52,530,199,61,920,116,386,324,588,160,532,332,664,326,878,189,71,220,129,296,654,972,347,581,701,870,278,29,879,801,920,646,786,647,114,46,53,707,927,386,367,829,584,819,794,783,861,405,638,546,741,426,999,272,517,31,142,616,814,716,858,951,24,336,759,172,961,909,835,867,139,627,254,562,785,308,297,840,549,754,285,256,168,587,857,68,203,984,907,885,194,836,785,45,462,504,94,541,588,209,568,444,179,148,881,699,597,955,77,465,778,498,622,562,634,503,66,339,434,977,591,394,103,206,789,363,984,836,597,309,494,876,570,189,847,79,316,685,729,531,305,391,984,362,663,116,938,935,391,259,516,130,614,207,523,4,329,576,310,876,895,710,473,307,238,73,64,207,954,237,522,445,86,609,440,543,535,829,59,802,528,799,300,566,282,926,142,886,732,752,58,472,869,598,663,555,852,673,790,644,948,527,974,473,442,198,908,893,62,777,117,215,432,267,952,975,780,588,849,617,33,191,778,844,718,182,216,788,462,301,753,614,785,838,583,58,905,21,227,710,607,848,9,783,906,464,503,313,881,53,458,0,245,418,201,633,920,919,276,201,124,681,255,395,199,453,895,58,454,937,163,550,107,142,777,110,979,817,835,838,777,849,418,232,77,536,453,366,423,843,106,292,338,28,939,170,806,953,478,801,641,339,554,519,798,42,33,73,173,487,440,695,754,628,789,509,898,911,570,277,433,105,283,231,51,537,324,369,69,970,646,212,177,716,377,851,150,2,146,198,945,671,204,357,742,703,371,73,240,167,510,40,596,96,761,934,353,865,692,215,268,761,648,46,125,357,953,258,551,136,564,699,323,607,967", "469,375,945,350,944,899,167,988,188,145,268,221,145,550,637,265,378,270,609,887,54,450,479,950,735,803,457,63,290,439,94,837,702,313,841,303,298,924,484,560,604,341,502,742,51,807,713,236,514,61,339,826,771,417,846,315,733,703,869,437,691,82,856,679,199,101,316,385,61,155,232,710,702,444,992,468,70,622,175,597,592,20,470,269,68,601,448,399,32,761,560,356,452,16,946,910,550,902,275,557,492,327,756,580,579,748,296,562,466,698,203,809,430,333,147,527,519,425,737,71,140,553,169,50,594,357,418,367,883,330,76,419,150,995,948,846,273,969,905,159,190,290,733,325,921,712,344,783,184,145,984,75,251,611,515,747,117,810,625,533,563,721,756,775,820,473,244,608,850,604,482,349,652,565,809,74,365,26,491,87,419,893,376,127,602,996,87,798,264,786,187,44,59,598,582,369,540,711,128,330,671,101,910,422,170,324,277,917,276,633,717,382,283,34,94,309,354,274,60,636,813,651,517,373,503,54,19,414,546,892,364,76,651,864,376,421,597,535,208,659,596,684,857,769,606,345,79,359,409,671,624,704,645,367,889,542,720,358,662,603,324,906,510,76,420,79,938,284,787,960,121,320,314,159,116,189,608,247,20,929,155,125,276,364,626,222,395,606,232,488,120,444,13,184,201,684,363,197,271,796,486,414,111,287,249,511,275,871,592,84,667,549,787,560,933,340,394,209,211,586,818,768,409,359,694,774,701,30,576,401,930,180,690,442,9,230,932,19,361,811,44,946,56,393,534,341,671,245,596,238,816,843,189,832,232,750,801,691,36,256,731,654,412,702,52,171,586,720,634,919,705,533,269,773,895,327,855,171,292,880,443,427,583,419,363,357,546,36,8,553,355,472,895,767,881,959,860,299,558,668,877,30,623,107,549,676,542,713,346,512,530,69,768,888,12,695,574,191,841,100,815,393,464,837,831,611,419,176,777,477,252,255,166,714,656,583,836,341,811,394,730,547,73,346,343,762,782,330,744,390,259,410,591,362,901,636,600,495,733,430,573,348,874,676,395,939,723,695,625,456,524,768,975,159,532,780,93,659,263,411,749,507,588,705,307,708,805,268,661,295,285,221,345,270,358,88,445,888,515,93,483,875,51,434,496,801,45,701,526,812,573,839,593,21,552,54,72,968,421,473,213,736,731,594,742,128,8,259,434,490,436,210,364,346,901,937,393,189,189,548,516,395,224,812,479,564,52,420,904,154,837,157,741,897,763,737,770,797,916,517,498,321,929,287,91,21,605,922,917,31,82,305,144,116,903,899,444,564,660,181,267,132,917,891,878,424,655,874,673,584,945,769,573,974,873,559,401,968,306,304,929,68,861,51,137,357,560,502,859,620,418,973,349,685,493,692,424,786,297,936,219,822,950,614,762,630,237,445,200,207,754,2,523,989,586,203,534,298,139,904,703,738,665,109,400,429,729,424,641,663,120,387,300,76,353,296,297,901,183,766,751,423,13,674,396,800,818,6,892,223,428,684,837,529,504,342,360,214,678,347,161,734,49,344,255,139,917,734,542,934,319,580,611,494,37,158,865,745,451,384,496,679,892,221,160,191,681,321,810,400,309,693,46,837,472,705,917,850,751,405,305,362,823,301,51,373,269,892,258,43,291,287,456,131,213,307,973,585,606,356,876,78,350,561,627,411,711,803,617,972,604,432,737,71,444,812,21,304,390,995,165,359,362,822,147,916,492,466,756,777,89,866,400,905,447,69,625,82,640,817,113,820,419,535,764,927,948,646,829,123,305,903,928,242,117,137,159,520,28,105,722,643,647,321,750,14,862,275,41,557,825,313,26,272,108,784,693,525,855,723,479,795,876,108,36,278,156,442,591,185,822,598,827,609,369,180,304,125,206,11,459,17,234,493,586,767,394,14,422,531,702,495,1,257,584,240,682,536,800,605,224,581,285,39,260,44,350,67,741,327,722,317,735,115,921,823,245,0,120,151,365,395,516,926,795,125,694,949,186,825,192,726,609,787,719,928,258,31,657,211,360,870,777,868,606,5,920,625,241,418,955,927,38,618,910,239,733,243,754,82,964,926,484,418,978,459,704,104,789,10,693,728,327,421,452,396,645,813,592,207,897,239,104,102,287,353,849,191,340,136,579,321,450,86,616,522,394,673,458,821,854,70,961,160,542,768,440,450,204,925,820,331,765,329,476,405,326,619,298,205,253,197,84,905,457,289,780,674,116,958,555,587,940,392,757,964,519,729,934,33", "258,159,868,620,563,397,470,725,214,904,58,642,527,846,833,28,383,951,148,907,54,131,20,497,559,185,923,939,735,282,32,715,921,411,753,24,939,170,982,137,232,344,306,906,812,985,615,244,622,156,954,159,683,223,779,429,391,863,30,491,915,906,163,904,965,272,516,455,797,499,982,516,935,799,943,978,307,330,939,161,271,880,80,286,858,799,92,515,853,728,875,703,268,560,561,316,474,37,327,712,467,114,359,812,363,121,476,687,753,606,72,726,178,698,577,713,884,861,211,11,235,86,183,863,329,460,104,143,842,402,662,402,479,170,453,800,427,350,306,411,880,206,554,925,866,950,85,457,943,832,335,163,298,505,227,57,925,604,486,122,575,12,356,510,273,44,728,408,153,144,744,924,504,384,297,655,874,180,597,811,582,854,675,958,307,125,593,307,351,240,916,136,714,268,54,578,820,326,57,739,894,357,719,733,929,939,776,237,251,278,422,375,170,980,343,289,225,986,984,581,970,711,332,559,274,365,915,595,91,57,834,494,383,315,434,619,791,586,495,339,78,934,542,171,25,455,165,828,582,507,466,707,560,647,406,240,609,26,234,107,885,164,971,358,950,163,63,571,678,883,116,154,173,724,268,571,297,121,504,659,371,686,703,283,192,988,388,139,678,471,605,547,854,587,924,867,816,127,60,873,844,579,57,383,161,789,942,501,391,425,387,894,259,740,458,34,895,436,420,454,693,991,733,26,704,91,150,204,985,718,201,262,687,115,314,905,260,318,457,902,820,810,533,562,869,896,630,833,212,969,192,542,856,343,491,360,757,96,411,204,59,597,153,628,983,232,304,817,811,981,621,60,630,346,347,15,494,823,886,817,2,278,345,460,27,521,18,121,412,489,101,272,970,4,398,785,217,152,23,412,587,969,934,283,332,323,706,917,981,870,698,190,462,657,241,113,683,174,891,817,528,657,724,887,733,285,110,814,989,866,68,834,38,146,378,213,350,185,213,521,165,509,396,338,466,419,449,364,170,841,666,956,979,463,842,192,922,12,190,523,266,846,887,859,947,63,561,372,148,382,881,772,98,652,364,41,793,20,566,953,918,558,815,217,874,339,677,23,24,887,237,907,75,332,558,401,750,559,149,930,808,7,714,909,81,547,373,789,367,976,612,663,913,259,599,897,349,459,738,832,882,890,981,152,960,902,931,312,410,110,868,309,249,351,908,428,660,638,126,805,517,531,111,886,79,514,959,390,171,786,300,940,240,414,968,423,40,42,619,495,327,888,973,934,510,14,34,544,688,974,659,630,660,972,494,186,393,890,57,17,161,782,178,823,624,250,193,57,577,509,824,586,769,407,853,497,402,281,331,177,491,789,214,641,948,919,796,301,830,27,975,53,193,360,90,341,324,216,779,244,313,919,883,306,918,850,348,359,787,401,510,985,235,502,500,179,740,310,317,110,263,497,834,874,860,451,486,386,766,487,870,431,505,10,621,263,282,700,454,629,316,784,782,123,484,737,383,903,369,921,833,298,580,854,184,686,420,304,111,798,154,653,981,578,208,87,664,483,882,889,431,12,915,155,936,68,241,60,731,691,514,516,987,755,229,61,264,291,626,978,813,769,337,934,845,656,184,811,845,320,140,535,11,247,804,574,404,378,502,215,389,958,774,98,619,235,659,932,318,397,517,151,265,447,955,947,742,613,663,279,363,948,124,257,421,100,826,525,985,167,671,196,611,104,975,668,415,941,38,344,693,53,398,92,203,546,125,468,769,678,929,210,713,506,893,357,261,98,509,770,867,448,199,163,488,308,384,900,838,528,453,445,183,675,177,362,699,410,574,371,238,986,531,361,116,738,203,179,344,956,102,352,73,123,958,725,693,378,712,787,451,265,363,191,156,550,203,175,871,750,796,564,237,919,146,778,362,24,910,670,212,188,656,514,300,629,330,562,872,740,532,266,885,671,466,412,486,924,978,774,7,914,47,721,327,21,418,120,0,734,899,430,71,59,948,382,72,644,12,521,508,759,576,850,790,288,116,163,73,792,858,8,753,729,310,164,770,200,346,70,797,937,611,929,95,294,94,704,246,710,841,396,110,563,405,235,502,781,502,952,951,794,849,472,711,105,694,399,970,168,456,962,840,908,307,558,998,62,256,953,238,834,59,430,237,371,478,433,878,331,525,285,310,670,509,506,373,750,296,346,402,379,584,275,711,899,859,937,560,45,283,826,999,691,154,709,615,690,640,294,779,318,860,78,83,868,214,430,740,751", "40,446,455,526,128,739,539,461,425,365,512,128,132,582,726,969,567,462,709,212,789,771,506,837,724,884,453,758,564,95,148,58,621,502,276,369,808,923,646,570,719,120,137,595,213,651,319,337,204,241,187,945,813,316,263,814,86,919,551,956,874,499,936,686,638,449,793,499,520,13,940,446,80,355,868,734,230,951,267,506,444,293,835,703,49,637,908,610,33,864,397,656,187,474,427,797,243,761,207,44,292,676,242,132,885,471,841,794,275,287,512,583,874,662,412,409,793,698,425,146,718,333,100,239,194,171,882,861,74,598,137,402,376,157,98,27,911,564,981,304,883,463,460,977,215,399,221,771,420,779,523,366,689,16,207,580,202,689,750,837,905,140,43,170,54,808,691,733,476,892,352,874,181,624,557,322,90,921,752,533,422,804,217,245,414,271,750,82,936,444,938,420,513,902,121,956,143,814,245,143,372,512,587,59,364,966,974,812,899,761,161,783,861,810,284,274,67,395,914,495,819,14,907,301,278,319,782,985,52,214,886,470,662,34,198,666,719,836,196,863,482,923,19,930,880,255,673,601,297,89,306,645,545,996,312,342,880,472,283,940,121,665,91,397,317,122,264,628,312,968,850,777,38,546,36,450,640,729,940,977,320,183,963,156,195,276,260,743,946,706,201,338,612,232,470,583,684,61,546,856,901,170,767,844,396,267,217,70,961,768,449,457,89,347,372,351,632,695,881,25,195,117,417,676,195,928,215,186,523,492,877,956,847,753,469,605,816,614,529,226,100,818,851,282,18,251,50,371,119,465,941,627,560,64,652,816,558,990,527,174,823,79,691,497,945,303,26,33,317,655,406,158,500,181,175,723,520,430,271,691,117,322,724,571,605,732,700,904,388,311,647,463,136,620,224,284,725,409,458,977,793,449,634,467,632,149,506,673,678,209,70,287,194,43,990,123,542,10,893,56,893,313,226,110,758,383,762,122,349,431,422,152,672,342,112,249,482,287,610,367,638,124,632,761,805,246,353,884,814,4,181,526,302,638,746,235,929,701,120,875,325,690,96,308,700,491,949,982,279,412,447,934,968,893,794,617,885,805,908,55,283,189,303,470,361,888,323,134,33,124,924,176,808,563,895,311,724,616,710,34,371,570,726,41,975,230,453,981,675,817,904,985,404,276,31,449,613,85,105,674,424,681,682,462,694,67,299,398,525,213,777,241,476,472,759,680,136,855,390,675,374,90,585,980,188,480,727,796,908,355,202,371,488,744,675,570,115,85,898,475,671,990,452,490,321,713,356,976,449,923,674,927,826,753,43,451,871,206,14,71,994,786,467,499,772,245,264,790,948,8,598,568,675,568,2,491,205,244,558,95,785,569,483,601,768,743,906,540,943,112,898,523,87,369,85,941,242,465,77,475,265,795,840,289,994,323,685,31,941,404,289,676,735,219,656,847,514,745,250,654,826,448,179,259,369,6,48,839,626,17,182,32,772,485,613,391,184,773,920,89,806,235,94,490,655,301,801,862,854,93,495,241,813,116,68,822,795,312,641,826,690,401,931,107,721,440,611,940,616,645,807,838,420,899,227,812,92,412,696,88,271,82,963,98,768,283,637,819,469,12,424,545,525,304,786,908,610,135,836,361,322,590,265,960,150,438,742,946,762,581,988,621,805,736,244,514,236,738,362,494,97,129,283,128,994,881,100,61,512,704,862,959,603,298,400,870,566,182,547,100,199,563,575,831,677,912,346,622,553,541,399,27,316,393,948,446,751,553,83,175,710,163,170,119,491,250,652,154,821,567,847,557,487,440,6,330,221,188,106,382,582,111,51,41,74,244,774,383,243,13,655,575,262,702,643,121,365,86,769,638,524,834,439,865,823,830,999,441,10,722,552,989,966,108,723,856,648,37,104,673,922,201,349,347,211,410,196,449,339,969,120,449,902,90,61,351,705,348,330,203,819,934,531,142,440,942,558,426,386,338,140,116,22,39,202,648,201,151,734,0,174,613,92,954,152,965,834,54,912,925,453,357,227,72,865,421,917,251,184,265,128,337,194,767,541,621,711,522,769,67,415,518,417,732,292,793,812,726,379,447,835,348,379,254,656,144,483,342,734,519,45,828,521,50,259,36,719,87,922,572,676,663,178,524,244,567,673,731,252,275,141,325,892,899,413,131,727,214,4,44,830,507,325,774,20,868,500,136,306,297,469,319,160,49,615,237,202,790,200,711,589,387,751,351,904,308,470,925,458,648,512,509,709,484,997,726,187,90,648,760", "524,415,470,733,263,169,881,17,585,76,281,162,952,279,423,453,642,331,566,802,667,281,491,548,92,788,826,515,629,206,777,981,532,434,943,671,637,52,356,82,151,486,983,810,887,724,281,798,746,674,605,736,184,799,52,727,980,282,974,145,669,165,382,575,483,929,387,291,386,129,407,396,196,584,449,783,742,178,568,653,326,498,627,75,578,382,194,43,164,659,367,450,944,957,946,96,116,109,614,933,763,373,359,671,628,844,985,856,775,715,952,164,714,400,839,719,719,244,439,480,210,674,165,792,675,8,82,915,450,115,637,857,650,959,11,879,724,104,118,419,562,961,980,677,749,700,537,507,897,89,68,720,868,994,940,837,371,769,660,98,442,284,512,346,135,78,883,389,740,643,632,612,763,746,872,906,942,413,906,116,783,285,835,856,322,657,906,234,922,912,285,827,635,334,696,760,148,915,774,77,211,420,965,35,867,893,966,133,168,866,890,659,307,527,350,387,153,986,513,145,553,502,785,61,130,156,809,786,211,824,429,586,569,102,15,415,119,279,413,110,363,258,205,15,660,349,738,343,603,591,367,309,825,416,700,642,383,934,388,454,174,224,672,250,388,639,521,619,356,285,473,241,939,860,317,120,581,439,164,342,480,912,404,562,598,838,23,534,652,692,532,609,451,288,55,876,31,481,760,824,959,451,725,650,289,573,638,870,266,617,678,39,703,984,179,633,792,753,650,314,972,817,741,18,210,426,315,879,516,648,221,376,199,848,14,461,41,449,956,492,63,485,349,559,716,361,813,228,952,299,351,694,548,449,934,243,864,976,397,116,116,527,259,46,848,73,590,199,985,977,183,655,945,150,731,893,487,458,833,989,6,994,898,148,238,608,672,731,80,726,894,124,70,314,585,117,226,209,397,898,863,280,678,237,922,770,402,770,286,708,18,852,3,99,725,748,241,16,704,920,339,649,440,712,628,477,670,721,762,344,766,815,675,65,100,467,112,208,60,709,41,499,450,855,587,474,596,89,386,86,237,416,790,151,120,571,683,367,218,516,29,121,694,715,226,33,436,770,656,630,878,674,376,141,968,376,887,890,593,440,480,435,311,162,645,383,441,877,646,307,263,657,294,5,970,656,230,207,402,826,781,787,499,242,75,893,569,243,194,912,351,59,214,274,340,580,910,716,915,634,896,160,369,41,123,488,442,939,241,696,882,139,501,304,260,926,842,772,300,809,114,629,275,201,149,586,402,946,349,834,350,330,523,781,977,832,546,490,612,650,834,462,436,7,518,218,983,934,390,432,998,877,358,715,354,331,791,92,711,60,650,452,102,241,781,794,650,245,612,780,352,665,934,800,22,639,407,979,786,63,974,991,841,610,670,441,446,665,147,758,91,168,935,19,266,922,33,721,783,297,918,897,194,176,519,545,561,662,610,468,772,792,192,450,720,264,589,460,441,126,513,874,155,12,617,5,473,209,252,714,736,539,511,495,692,648,27,63,21,790,723,670,182,476,718,530,556,564,982,944,124,795,778,889,264,165,420,637,984,900,687,558,341,28,285,784,983,516,92,188,894,513,197,781,29,681,312,145,594,196,935,551,583,979,588,980,33,434,147,345,757,287,893,111,679,419,90,900,486,972,194,623,303,367,67,79,986,996,139,361,971,433,284,379,257,413,400,395,489,846,654,430,722,977,572,793,448,723,252,557,476,566,168,488,494,324,429,38,850,895,680,853,56,965,354,910,389,478,302,545,478,612,14,178,726,186,304,869,227,818,822,23,509,991,276,546,174,200,300,361,40,305,940,605,46,363,253,342,79,437,488,172,151,274,966,805,611,954,230,66,866,614,487,68,501,79,195,220,502,947,717,401,505,312,776,275,484,112,124,912,41,783,319,334,46,883,908,263,750,306,137,639,935,311,166,400,768,816,50,570,414,268,25,498,146,718,249,860,738,226,472,360,655,716,864,775,449,429,510,890,823,227,594,531,421,341,633,365,899,174,0,944,735,309,62,325,963,79,538,939,51,300,619,193,719,16,408,233,411,76,121,407,853,995,24,122,49,481,960,549,797,744,423,603,518,672,715,590,853,520,276,964,303,988,662,717,314,557,913,742,21,725,449,270,227,957,707,908,690,21,917,431,5,875,47,109,399,350,245,202,195,106,7,703,81,595,786,986,899,926,749,658,816,717,407,875,209,856,541,510,303,386,620,582,905,571,415,977,382,812,852,226,810,966,324,250,785,615,138,941,448,504,638,273,52,95,149,648,231,480", "845,422,458,350,453,137,2,361,437,895,953,500,584,830,743,430,41,872,364,519,869,339,47,776,558,88,233,653,840,749,958,607,212,129,82,229,12,767,367,605,352,623,527,154,894,361,543,67,867,195,530,132,36,421,543,421,469,274,484,110,110,372,505,618,96,871,642,104,470,541,209,849,978,415,860,579,227,842,594,847,811,705,753,825,101,440,580,207,191,846,289,194,520,106,364,526,367,757,541,303,719,429,112,395,118,404,437,96,856,988,833,682,395,695,167,48,659,161,823,682,135,324,950,989,336,214,550,367,79,208,882,787,816,146,14,79,733,742,639,811,709,784,683,564,579,893,496,721,839,455,460,876,529,918,623,414,829,517,656,806,66,269,850,700,505,410,479,808,320,152,981,910,234,225,931,445,394,327,932,752,154,41,188,689,67,66,905,361,623,681,220,498,230,640,779,472,942,815,18,209,19,52,990,627,12,83,635,294,538,706,681,566,463,977,813,387,399,206,972,156,323,72,653,665,448,302,435,809,377,623,4,968,995,426,875,128,463,85,589,41,321,884,545,746,669,221,621,575,922,511,740,766,468,77,381,874,547,26,246,220,840,783,784,580,586,493,705,618,623,715,324,142,461,154,514,919,419,898,155,566,951,821,608,222,829,719,923,67,568,371,105,515,802,14,635,474,86,362,982,996,369,181,499,939,433,921,255,351,333,423,538,584,218,872,786,322,186,228,362,447,609,652,805,93,642,3,678,841,981,957,364,666,358,500,298,166,367,809,465,985,692,194,520,173,527,73,58,113,89,632,579,91,358,538,94,166,357,598,730,266,292,578,85,104,842,91,581,887,346,894,748,945,906,472,520,608,532,932,490,418,159,666,797,743,648,481,938,344,984,4,339,46,472,172,653,429,528,127,604,972,963,912,955,62,75,871,66,381,532,14,462,879,457,198,622,968,458,564,688,990,717,166,232,899,387,505,378,809,462,624,759,708,819,322,177,786,456,88,502,899,773,751,729,433,996,768,226,490,104,380,47,148,699,973,400,505,921,610,657,527,249,854,967,262,309,485,690,927,703,26,933,950,433,355,272,757,241,280,831,878,416,195,818,984,440,217,29,35,981,776,544,103,956,786,302,159,872,178,63,467,560,851,613,76,239,146,637,569,57,747,865,601,343,734,74,673,507,733,734,231,199,810,191,896,663,855,983,6,620,842,894,847,406,168,495,685,116,719,619,985,758,571,770,206,504,5,89,776,717,181,441,441,721,303,315,631,907,552,101,802,816,947,191,355,910,392,772,157,35,802,710,428,996,852,316,981,315,297,848,10,242,944,614,671,391,96,785,356,28,272,47,995,113,359,855,482,961,967,64,693,607,725,745,511,153,809,254,15,683,370,22,32,643,37,209,380,200,888,865,672,107,510,420,382,772,34,977,353,931,920,574,543,401,99,611,96,73,883,762,567,345,744,200,16,132,290,4,451,730,203,249,535,638,327,881,122,981,787,470,91,57,898,209,436,377,614,662,828,25,280,881,290,566,166,718,82,529,202,335,347,103,365,625,756,5,240,467,701,443,451,983,225,953,218,789,546,150,540,114,489,855,65,476,821,829,532,978,33,825,330,713,154,503,643,769,434,608,282,885,735,812,38,349,679,721,927,901,54,864,671,231,663,278,730,813,524,119,514,345,860,37,702,995,657,798,990,510,523,977,940,137,722,458,791,273,918,563,644,738,488,812,932,348,265,691,710,735,978,636,722,119,213,996,623,690,187,754,372,704,671,358,976,556,576,570,169,270,357,182,122,938,228,580,222,773,102,550,117,755,322,541,125,56,868,801,984,708,127,622,681,237,571,971,111,265,731,148,508,221,49,922,955,961,492,742,522,525,254,86,959,421,838,711,505,973,58,776,922,693,178,7,931,710,224,30,328,690,55,985,225,80,745,823,833,530,900,36,194,468,46,781,773,317,751,478,797,669,968,804,412,58,200,985,730,772,173,920,395,430,613,944,0,717,375,70,914,995,949,268,429,168,506,490,74,795,143,550,796,323,704,191,321,393,358,753,513,538,788,536,721,33,710,46,710,221,204,841,344,122,602,166,901,41,186,210,920,804,969,719,877,74,612,829,410,590,324,439,227,285,300,597,25,602,471,590,451,760,435,716,25,43,171,691,677,269,170,797,486,596,648,462,937,832,79,769,201,286,610,899,546,57,517,97,456,470,136,654,90,901,225,73,501,650,43,495,279,819,615,808,387,659,744,489,286,974,535,423,396,846,757", "281,808,710,364,400,866,760,52,249,886,539,830,433,942,995,379,464,22,932,99,986,360,180,322,162,17,701,840,852,276,409,807,849,499,714,255,403,773,117,103,62,298,553,512,841,772,175,73,896,493,102,373,140,408,941,86,711,852,827,995,499,858,955,868,637,993,942,168,395,834,452,562,386,488,660,735,349,952,120,739,852,197,777,259,288,106,411,726,904,983,459,882,419,727,856,224,658,669,746,618,567,158,615,988,858,975,479,505,355,333,133,854,209,878,511,814,415,607,856,376,384,43,352,158,537,229,90,73,312,561,520,479,140,411,109,178,949,823,665,505,634,37,411,153,971,672,818,261,335,822,722,840,382,23,474,718,45,344,436,238,878,656,736,825,259,163,14,932,230,713,572,423,621,601,337,178,900,907,455,851,283,540,370,778,455,552,469,407,83,493,386,619,872,487,727,125,198,244,352,994,980,190,714,695,371,346,422,220,78,829,453,924,912,140,360,569,508,497,692,245,733,865,643,382,109,203,260,262,362,740,955,151,985,168,165,723,863,925,529,42,156,817,15,799,82,990,193,140,102,406,936,540,301,177,251,676,141,846,400,502,581,697,439,33,165,966,344,532,734,583,8,471,849,829,217,333,400,439,281,579,530,817,818,777,126,883,97,669,219,225,920,175,279,494,554,871,872,515,244,752,892,61,786,27,345,415,286,295,937,220,771,89,169,174,856,423,77,307,740,241,867,169,940,319,544,308,912,755,642,842,250,779,25,901,59,761,966,398,236,213,537,441,633,722,594,125,863,143,244,794,439,398,842,423,174,957,534,535,520,451,634,582,923,122,331,648,512,854,460,912,892,393,124,526,958,749,541,601,522,185,134,890,949,284,735,642,28,931,41,496,680,735,153,824,874,91,907,268,216,979,986,626,919,66,99,353,476,708,982,189,590,81,376,106,461,232,651,949,857,207,866,871,103,173,994,762,782,327,821,422,498,383,759,989,240,810,603,291,737,708,920,771,784,143,896,165,900,917,96,973,753,406,291,28,434,160,39,753,103,396,761,976,508,704,142,290,967,240,396,75,560,284,676,547,686,306,710,209,760,768,937,733,470,282,469,974,142,986,478,539,659,326,220,537,359,183,685,545,632,557,822,233,586,62,429,984,68,338,345,77,507,194,642,762,199,647,970,630,240,881,584,672,237,781,421,350,46,97,335,210,805,453,897,91,371,106,986,305,983,920,60,523,841,188,616,252,825,123,837,985,637,870,24,62,501,926,702,164,313,321,417,431,610,668,268,590,342,187,102,601,47,740,455,624,777,523,735,106,498,863,571,163,991,209,366,830,736,704,97,923,91,804,371,315,479,445,487,569,444,508,131,253,572,436,488,568,578,529,269,455,16,495,831,224,691,433,349,239,337,475,577,116,330,149,311,781,423,253,552,26,341,540,426,310,805,880,100,10,973,740,712,923,886,915,140,28,930,910,825,155,273,834,565,628,516,584,99,676,17,439,824,769,209,521,870,530,432,236,248,94,366,806,937,181,867,860,696,556,67,937,904,484,49,490,64,373,250,386,606,123,792,461,992,239,940,941,224,644,544,615,273,273,493,306,871,812,625,729,579,183,817,519,346,332,800,699,544,280,486,819,642,886,967,227,520,805,759,79,817,370,888,700,699,915,716,219,110,695,954,295,426,157,640,959,268,760,346,134,297,446,519,40,898,238,208,100,571,719,554,462,202,242,101,297,726,417,400,828,867,721,860,259,289,768,45,466,193,315,511,632,776,894,614,145,19,703,275,619,643,227,183,101,625,572,645,290,692,545,801,319,180,515,271,69,26,284,210,46,314,981,4,707,240,881,295,571,788,680,888,609,423,346,856,332,452,211,869,453,367,23,86,492,964,258,184,491,286,773,896,51,905,224,29,694,642,959,194,862,109,595,294,260,935,402,96,894,371,603,179,831,414,611,476,733,829,484,431,524,952,258,821,386,133,83,994,896,919,516,71,92,735,717,0,845,667,15,986,266,549,637,886,243,937,16,305,877,396,827,5,349,535,239,728,696,959,910,388,187,208,636,400,26,689,584,356,733,450,886,935,814,963,991,548,373,461,674,20,71,739,864,60,556,627,736,335,888,283,797,127,182,697,436,828,531,105,583,489,557,583,976,945,655,421,58,557,500,415,944,982,773,554,673,982,419,775,270,553,269,655,982,665,867,310,5,635,928,50,948,935,167,201,491,249,286,991,986,279,724,574,637,363,155,54,670,86,200,198,835,772,242", "892,798,493,31,748,383,855,857,164,907,603,294,735,927,283,442,252,503,209,392,572,381,197,61,312,710,734,520,698,761,157,4,945,719,596,250,853,893,922,781,508,687,639,889,231,444,606,231,416,115,802,444,231,728,315,791,169,131,482,50,632,816,974,473,933,786,193,128,845,518,475,242,579,717,679,706,756,820,810,432,400,903,307,709,326,46,617,934,881,434,91,935,578,200,757,370,287,859,66,366,115,159,495,871,245,656,30,216,988,273,302,369,789,804,228,164,871,220,919,317,8,269,55,983,214,231,436,162,629,16,968,926,43,119,634,855,561,506,868,356,861,607,808,789,960,564,453,522,613,809,347,885,774,317,171,963,145,290,746,811,279,491,707,681,881,685,770,99,236,989,494,929,52,524,583,135,43,650,639,307,564,450,889,549,860,250,198,191,199,262,841,998,94,438,535,381,482,518,569,20,273,341,500,946,580,732,33,527,767,525,612,178,701,148,275,82,699,682,380,811,260,835,500,973,514,72,738,426,727,479,797,819,763,726,353,939,480,25,496,49,812,192,835,286,853,764,932,868,540,649,866,965,400,47,50,34,811,953,117,125,436,366,223,945,685,32,422,459,671,316,159,370,404,545,941,73,962,421,438,820,18,565,828,99,30,731,298,41,215,747,193,541,82,726,358,996,212,90,918,525,844,100,556,756,892,954,484,718,808,923,988,778,654,930,236,298,806,906,641,482,9,513,696,673,963,63,5,235,705,961,830,920,675,766,883,674,35,622,306,556,84,243,576,315,768,376,837,552,506,438,198,188,346,278,42,584,688,530,208,162,692,748,965,824,974,911,844,12,105,852,594,692,398,519,8,447,85,129,790,62,636,751,129,55,748,670,739,636,699,341,692,207,517,633,348,752,693,463,811,905,358,776,80,246,755,164,488,440,600,227,757,250,198,968,483,442,497,784,233,72,510,857,181,387,221,469,103,946,218,660,736,11,907,30,462,40,649,675,796,235,950,861,192,238,146,721,34,429,972,500,953,713,34,707,196,959,619,376,897,559,321,274,882,560,92,353,645,97,640,923,295,709,806,994,380,720,178,754,877,128,413,353,964,295,13,209,683,568,987,880,876,493,110,491,996,707,400,359,872,894,333,517,794,201,213,676,65,587,183,457,178,604,936,465,674,3,29,414,877,724,565,920,769,318,59,813,744,847,314,765,484,20,643,426,490,797,995,183,962,332,418,493,540,936,230,988,426,181,424,614,981,238,934,697,387,383,387,285,717,304,131,177,280,909,804,858,211,247,260,818,44,599,981,318,937,205,512,871,37,716,605,601,649,273,751,785,811,127,209,599,397,544,376,658,775,124,625,768,325,539,92,829,770,223,586,833,374,834,251,179,861,849,926,740,304,634,750,435,593,918,85,471,353,72,286,562,943,789,565,444,859,303,689,166,989,468,107,861,418,947,274,162,152,130,595,637,538,732,976,200,681,463,628,288,883,592,774,28,269,644,359,394,869,926,447,279,924,332,274,388,978,587,247,584,24,279,820,57,234,246,797,81,212,247,43,359,582,286,531,412,490,813,126,745,300,611,15,150,860,324,457,670,970,528,311,155,875,906,122,500,124,777,528,789,731,691,513,369,363,422,374,367,254,162,240,666,884,262,399,401,186,647,919,292,742,742,986,866,277,11,517,133,540,454,920,91,71,429,149,123,318,878,848,858,854,668,399,587,210,251,521,546,899,211,641,685,126,309,36,772,747,982,656,385,251,598,826,927,839,309,488,585,339,373,796,236,145,779,85,699,443,324,111,811,315,640,830,796,77,995,752,3,929,798,45,413,564,799,146,659,630,910,971,450,74,429,215,318,783,908,831,206,386,522,518,473,673,600,688,153,707,820,834,301,537,94,758,81,532,169,11,616,272,587,113,451,550,632,265,48,901,940,914,807,347,538,492,151,317,605,103,388,600,399,805,405,952,865,59,60,738,651,157,587,970,394,276,926,59,954,309,375,845,0,413,391,34,162,935,136,673,532,819,191,666,319,477,489,692,552,405,377,61,618,198,996,548,778,368,588,302,111,515,262,480,81,35,724,92,584,830,573,618,489,83,871,187,895,949,893,139,86,811,682,285,340,283,314,710,393,209,522,342,138,913,871,130,908,391,728,99,343,953,453,875,395,529,47,949,184,623,655,317,584,487,152,942,231,584,144,179,47,375,631,582,824,342,562,152,787,64,988,115,756,467,653,505,795,606,875,784,329,641,83,852,235,858,389,255,921", "64,299,378,590,515,219,126,637,304,254,697,348,348,767,517,516,154,668,768,633,347,327,690,746,82,111,331,440,981,876,412,812,631,655,436,558,405,700,985,648,795,809,672,683,384,159,388,534,799,41,91,302,663,345,662,71,388,916,111,265,271,695,99,643,382,646,59,165,388,404,253,816,156,537,261,748,356,796,831,442,675,246,595,459,959,169,454,502,157,732,826,410,123,462,560,83,307,791,663,765,955,554,361,626,512,434,157,935,362,701,263,212,699,580,849,949,513,660,326,37,846,846,900,26,748,510,94,316,306,870,425,474,558,519,282,136,772,731,397,287,104,696,697,434,225,175,850,356,655,779,898,103,183,720,380,866,130,852,648,595,742,425,361,733,197,525,12,485,146,572,117,740,895,616,861,800,993,785,34,353,503,226,683,616,317,506,395,551,621,344,34,975,840,649,992,698,5,815,27,132,798,445,758,500,220,513,810,84,444,249,326,268,951,886,535,551,561,898,52,391,284,266,705,405,589,215,653,861,685,706,111,588,668,242,374,104,62,521,471,485,228,64,514,248,848,255,236,899,296,672,833,136,887,241,689,535,709,681,89,859,768,449,547,856,260,148,35,697,767,49,943,529,701,570,22,107,278,852,562,507,390,235,710,763,375,541,809,165,522,382,755,378,537,945,992,297,629,953,802,734,430,299,234,636,644,733,482,804,887,808,459,859,555,510,166,72,258,831,617,699,497,393,675,561,245,978,992,415,835,10,734,687,324,479,328,573,82,491,852,645,57,925,456,965,588,976,303,934,486,108,6,295,629,398,419,667,650,235,658,429,319,793,417,528,529,135,633,677,932,694,144,909,644,679,53,555,99,81,570,778,365,303,765,692,435,648,60,475,685,986,307,789,936,462,761,40,847,958,804,185,39,546,209,650,175,600,973,492,571,369,791,988,49,101,726,829,223,922,980,781,770,340,6,68,676,737,10,291,203,647,2,434,673,613,601,977,695,621,16,551,288,594,363,662,477,439,224,504,718,822,121,761,172,925,862,908,214,226,88,579,436,980,876,118,206,647,726,970,424,296,953,26,450,181,343,62,463,791,905,969,563,379,414,41,123,275,138,400,365,61,783,431,45,397,404,430,742,487,903,955,608,105,466,116,882,411,256,620,444,811,1,985,130,491,603,835,819,452,109,18,402,283,26,369,216,892,589,757,304,905,755,866,492,383,483,359,282,988,849,155,602,267,186,361,907,147,447,887,208,915,516,133,7,352,302,662,545,234,237,652,37,15,462,187,432,440,206,272,423,726,916,412,504,804,807,408,892,967,385,519,904,90,273,863,99,995,859,3,148,670,490,305,356,384,547,561,55,224,63,940,990,882,166,922,148,886,679,143,367,656,817,450,625,275,167,849,322,273,271,230,835,43,728,991,709,248,411,393,972,917,241,108,616,506,726,45,157,529,818,839,129,696,336,536,681,363,381,366,377,926,369,169,846,64,940,67,501,111,596,324,399,679,303,765,42,873,932,899,18,974,803,290,127,558,694,33,278,742,286,630,947,537,925,320,824,885,403,379,985,256,803,742,146,6,363,604,496,956,647,189,860,64,584,428,742,900,748,259,584,589,240,506,392,237,454,459,261,646,604,859,303,832,282,149,398,716,715,633,697,845,431,825,772,186,764,355,630,198,24,194,921,311,520,29,228,929,495,371,937,519,472,854,522,379,115,125,195,460,581,222,513,519,520,564,859,910,233,711,229,887,541,997,617,779,21,751,912,29,326,115,861,188,819,41,772,838,965,832,323,138,402,793,225,336,536,789,849,416,956,978,153,338,251,978,994,420,493,402,908,589,670,480,827,655,154,781,553,614,70,257,920,576,844,875,161,759,825,505,19,501,573,946,825,52,220,148,901,583,343,263,38,51,999,527,660,127,899,789,561,622,969,191,131,764,895,26,441,978,390,405,189,733,784,100,202,83,171,693,332,570,790,758,419,154,851,81,201,795,948,152,62,70,667,413,0,467,74,23,711,747,965,877,530,279,46,397,313,434,201,45,124,394,498,768,409,143,313,822,79,299,837,909,205,222,68,702,933,430,809,51,976,534,984,69,791,274,87,968,386,870,598,689,856,62,933,523,696,649,930,488,176,31,127,752,501,677,206,225,146,824,440,701,734,616,506,436,506,278,492,501,799,128,931,627,445,67,431,420,222,40,67,269,649,606,130,549,425,666,503,277,483,938,686,375,412,666,610,58,549,737,911,766,854,777,22,274,812,740,608,826", "50,683,467,971,777,304,747,424,867,354,982,910,497,138,905,330,221,536,668,124,642,290,732,802,888,92,862,999,739,92,138,622,758,830,344,306,438,730,52,202,333,488,515,428,350,782,863,98,631,836,684,402,470,266,838,639,302,644,611,720,464,876,872,110,896,50,140,344,862,525,9,697,146,782,914,474,762,528,285,483,813,990,485,96,228,993,677,276,742,340,230,504,277,77,860,612,121,563,297,553,853,691,39,55,812,500,771,642,989,275,220,901,201,266,737,503,749,998,948,428,584,266,910,721,794,842,545,782,262,614,482,621,386,695,844,335,408,976,949,65,271,496,877,459,275,511,36,15,936,303,18,324,808,723,626,537,12,564,856,681,633,22,878,905,369,75,878,864,225,827,390,996,534,395,411,988,456,890,354,654,930,38,749,45,681,810,933,418,588,783,121,398,626,15,933,515,256,534,804,480,534,946,951,449,338,914,425,234,328,324,278,615,648,688,999,793,722,857,481,443,544,153,566,582,904,653,953,583,603,712,355,859,889,42,554,845,888,637,307,937,148,759,285,839,735,273,670,836,570,180,852,935,18,53,79,478,740,559,699,431,418,527,407,746,30,364,552,484,59,463,161,112,515,331,885,313,736,330,31,729,5,294,377,186,274,655,708,373,256,599,284,49,300,268,190,614,917,803,625,331,524,774,106,926,830,34,91,998,558,454,672,377,187,909,437,709,451,541,433,328,479,432,763,87,537,178,328,783,167,549,393,898,667,74,353,879,350,706,469,762,74,570,198,548,21,411,4,432,947,102,749,51,426,913,289,163,213,935,969,280,729,788,714,296,662,204,72,261,369,644,950,795,210,185,208,511,127,287,45,831,455,301,190,203,519,694,182,935,935,571,902,25,523,424,809,375,740,83,820,975,773,824,889,327,851,47,31,111,475,101,555,888,576,558,233,467,111,242,869,789,954,65,222,180,818,562,895,248,984,307,399,762,834,469,669,964,303,849,113,348,907,4,98,860,894,50,435,733,20,590,524,325,696,832,485,929,409,930,900,162,468,859,388,769,411,679,387,712,977,188,178,136,234,634,375,975,915,427,315,183,188,412,62,599,71,312,142,692,880,211,213,627,207,538,991,209,619,207,85,475,898,475,99,311,199,290,696,789,446,98,849,706,794,842,620,277,873,804,64,581,713,242,601,620,648,301,891,334,834,79,640,404,804,707,351,812,769,443,707,294,391,942,388,657,818,929,375,800,392,657,374,572,41,311,311,542,973,208,514,867,882,221,185,742,749,513,619,418,596,873,598,452,760,930,22,380,419,579,886,763,338,774,237,843,773,578,752,151,885,429,538,838,803,963,816,832,737,668,514,572,650,595,198,256,988,909,422,536,178,89,173,420,468,328,280,975,22,802,354,252,931,396,608,272,322,720,217,14,371,411,581,186,579,494,425,243,344,351,521,485,597,922,883,433,725,243,852,805,620,103,976,586,931,53,548,471,525,758,259,219,633,399,42,494,71,168,937,339,257,497,278,498,155,538,775,716,364,121,426,548,236,960,636,379,211,952,339,716,489,72,614,405,590,103,200,843,556,445,774,538,643,967,633,844,379,104,425,838,563,481,535,160,938,395,391,263,84,709,825,4,267,806,493,452,843,512,36,447,301,483,557,744,271,93,140,388,500,678,532,556,558,571,212,174,242,26,884,337,544,541,71,485,408,847,260,358,436,848,571,398,968,158,53,366,156,167,404,536,275,811,677,480,143,456,609,40,213,723,382,977,392,42,367,619,969,427,516,607,575,502,779,457,359,285,252,954,443,927,604,2,91,238,714,739,355,50,751,167,367,880,109,262,435,664,73,45,58,649,540,211,214,106,665,99,25,63,647,537,686,918,438,461,806,725,93,916,182,953,441,304,427,58,221,341,284,528,991,643,621,839,471,782,466,951,59,252,602,948,177,961,961,778,129,752,135,823,121,110,537,948,305,181,829,809,177,677,124,125,382,965,325,914,15,391,467,0,348,205,545,636,636,194,439,13,512,194,413,601,176,956,56,209,474,724,732,732,145,470,331,161,169,10,135,134,22,243,970,551,797,749,13,764,365,357,904,275,795,830,670,249,991,982,494,80,460,836,232,180,479,79,94,965,799,76,155,591,667,189,732,9,384,135,362,555,347,940,354,356,797,303,58,770,179,303,100,183,964,515,890,547,540,439,473,995,820,873,220,262,897,513,752,103,619,228,991,465,199,167,588,923,17,846,272,406,920,227,791,741,87,765", "994,47,194,381,114,546,839,587,500,219,271,203,743,775,6,652,177,751,183,632,393,321,966,352,886,518,923,584,230,32,668,355,263,29,718,953,838,156,784,869,775,66,628,932,779,965,98,389,868,974,571,486,839,176,165,579,291,532,918,391,717,407,480,815,92,996,364,544,612,106,397,676,559,941,956,653,350,14,858,142,221,487,717,883,104,630,492,808,714,976,638,686,294,149,175,284,784,338,953,561,99,680,810,988,354,993,984,598,624,765,870,865,330,362,590,424,249,478,964,384,164,840,301,186,636,984,914,534,415,174,616,98,522,635,898,231,425,124,880,191,856,531,689,510,83,156,730,578,199,920,874,201,775,256,865,767,902,274,553,625,859,831,531,932,564,119,630,637,551,316,708,336,158,613,859,182,26,268,325,686,482,591,625,13,318,261,546,812,562,260,842,828,862,409,386,331,513,627,669,48,604,352,933,965,220,597,453,812,430,394,531,382,294,981,522,624,800,840,279,347,495,390,213,578,738,18,496,97,988,653,814,565,761,566,254,156,88,250,28,368,207,398,533,244,544,568,212,537,371,685,434,889,880,875,446,807,294,388,146,174,944,986,819,643,245,751,980,980,149,427,426,930,634,832,767,553,170,517,752,825,360,248,51,658,575,315,368,606,266,7,671,765,846,267,441,344,188,749,851,153,276,131,735,639,303,558,392,700,574,799,70,852,338,657,849,437,534,130,955,880,238,342,191,690,378,406,372,891,881,350,529,472,818,212,750,82,717,822,306,408,271,831,54,874,242,49,423,773,865,860,317,598,384,15,214,629,352,43,50,452,578,601,706,702,718,740,466,758,522,251,218,959,646,689,165,140,931,284,831,161,591,245,69,402,917,992,217,15,620,33,987,868,803,334,114,226,391,302,549,69,271,174,894,950,455,429,444,724,745,530,796,823,427,669,40,905,589,739,229,154,853,614,233,233,600,820,944,634,325,796,555,742,985,69,88,546,374,822,471,7,619,756,273,256,53,502,576,844,372,106,625,329,828,983,187,327,578,723,989,113,607,943,81,147,281,568,61,72,568,954,704,224,353,71,100,609,890,899,113,214,827,135,13,677,593,187,909,156,661,956,26,899,329,439,663,112,27,214,5,63,531,926,531,987,165,387,849,908,938,335,342,371,521,921,514,515,794,529,446,883,655,524,718,978,454,279,269,436,641,215,66,41,938,38,4,121,274,35,686,823,199,624,136,444,979,98,179,747,485,945,399,337,509,432,598,821,215,472,89,305,48,506,119,369,811,134,738,874,252,56,839,535,621,116,88,826,361,429,897,698,209,154,485,32,758,211,834,160,837,282,269,963,798,307,810,515,119,746,114,824,664,173,889,428,871,77,729,154,797,578,452,311,4,591,684,286,433,726,855,267,841,857,921,842,414,659,110,847,673,706,681,803,955,509,957,284,648,807,657,12,849,137,573,294,480,239,528,739,363,811,602,499,653,139,560,882,226,762,428,844,314,67,519,151,381,750,527,475,143,609,738,927,539,787,284,110,662,620,409,180,283,534,963,732,256,281,428,123,319,602,73,268,788,166,747,7,179,784,920,755,900,896,977,762,104,448,44,520,175,902,699,721,641,689,976,17,460,405,17,167,89,893,227,149,209,855,621,74,324,152,807,377,677,496,879,330,974,704,36,568,627,639,718,684,515,312,203,865,839,103,556,536,373,998,435,490,514,820,418,677,512,465,999,600,584,303,318,304,337,764,331,390,730,850,470,25,122,135,548,489,682,427,66,101,57,378,8,532,749,41,783,981,280,434,629,645,190,789,611,399,353,430,660,415,23,119,146,893,688,992,993,171,998,119,731,207,784,902,766,904,438,698,634,608,699,351,383,38,289,47,147,101,845,169,301,336,254,266,427,939,466,598,970,325,563,211,40,67,196,299,357,208,950,717,693,313,441,221,588,609,477,438,927,82,998,449,471,728,130,203,372,962,518,626,937,337,681,694,72,834,963,995,986,34,74,348,0,244,394,302,638,965,73,680,372,771,900,767,445,663,481,295,744,693,371,183,881,608,376,142,767,409,782,539,818,875,190,6,267,557,50,339,358,648,847,494,660,311,213,415,93,270,163,903,712,450,731,823,355,517,663,306,517,564,774,100,227,163,157,970,404,70,38,824,749,989,325,898,77,208,671,314,320,830,517,143,10,235,33,325,855,512,77,745,27,692,549,327,867,945,648,260,123,660,522,620,365,738,765,894,292,312,751,984,874,995,14,444,134,160", "630,260,984,803,893,576,402,424,212,744,78,898,258,731,730,752,375,588,869,702,987,571,255,152,523,172,164,768,195,604,773,856,895,183,609,913,950,401,468,124,590,413,652,930,181,407,886,558,329,342,586,274,60,835,319,737,575,269,379,158,672,651,551,970,764,199,940,305,800,185,599,68,88,291,323,670,861,35,267,777,623,222,552,38,635,479,86,630,922,686,217,305,965,711,352,426,849,989,276,589,21,731,139,495,496,32,476,125,600,695,797,472,768,928,758,649,698,323,22,811,375,231,425,545,698,163,982,509,22,417,713,570,288,692,935,28,743,267,334,993,619,234,695,456,702,969,62,674,82,901,727,139,440,355,596,961,525,168,406,106,551,856,551,657,277,224,364,123,558,799,607,632,619,307,501,627,854,72,632,119,594,386,271,248,931,327,834,217,872,736,323,354,256,85,865,736,881,977,443,865,5,709,256,75,231,810,180,185,483,435,409,845,110,611,906,352,867,576,187,120,674,567,705,8,387,851,486,207,815,827,97,627,136,654,566,792,386,371,497,189,333,437,82,518,669,811,36,15,484,576,258,236,611,952,617,35,502,403,924,310,95,169,847,394,839,716,294,515,810,658,762,988,986,793,71,503,968,24,259,433,535,374,564,648,243,121,489,237,786,617,528,83,329,266,643,867,677,558,190,33,211,892,872,174,432,545,52,38,821,404,64,388,1,902,856,893,867,669,304,37,323,360,958,69,241,329,922,190,109,980,578,406,688,325,439,85,724,940,306,910,454,947,338,782,857,995,500,27,189,437,677,214,538,878,573,960,851,192,584,76,65,997,345,255,727,843,374,486,104,911,222,916,997,55,294,523,114,573,615,918,164,652,976,374,137,364,644,327,93,118,658,753,552,259,840,47,450,767,877,684,408,753,968,339,558,388,461,980,767,771,159,265,113,244,24,247,977,120,435,349,290,616,568,807,694,374,906,109,831,233,30,969,947,720,162,746,677,960,815,111,894,813,269,34,598,912,500,190,716,909,337,144,919,670,864,285,807,141,525,432,382,753,899,744,603,633,491,796,764,63,891,328,866,225,528,812,494,559,563,15,601,508,506,529,567,390,174,360,356,354,679,331,7,926,787,280,775,79,865,634,537,299,698,737,590,458,991,356,435,397,486,115,695,87,562,937,56,106,639,240,556,664,381,748,144,124,310,178,385,538,292,832,273,606,770,796,875,202,824,818,987,182,196,796,980,259,27,422,535,986,715,268,391,230,323,496,574,436,802,418,528,566,138,557,97,311,950,568,660,961,60,552,725,510,78,390,115,534,453,564,865,787,723,827,708,886,814,396,157,472,387,46,961,759,348,81,367,237,809,666,919,333,829,716,836,946,241,307,153,976,842,672,194,339,75,407,6,826,835,774,562,200,334,681,635,963,811,940,529,453,396,562,916,185,491,167,791,428,195,439,844,284,426,97,828,899,404,716,661,482,277,887,268,172,256,745,10,835,462,927,634,916,338,561,342,608,357,932,476,970,252,62,3,717,547,866,620,684,900,445,571,114,875,210,276,514,927,934,165,799,756,503,440,300,716,606,637,487,305,340,822,446,992,837,777,801,546,307,611,303,34,244,174,639,732,769,431,308,628,186,503,670,547,562,184,968,871,213,799,336,836,980,664,61,154,671,670,400,394,946,105,590,203,956,269,30,549,653,521,510,688,173,811,558,965,736,46,267,803,950,674,438,488,158,457,657,697,220,66,871,585,974,665,858,7,260,117,25,482,778,12,730,141,14,678,183,635,8,215,427,932,285,6,441,351,1000,762,234,560,782,900,459,867,670,262,656,718,362,3,479,497,215,755,192,366,238,853,260,729,942,42,869,286,195,729,585,240,592,258,705,439,72,90,604,511,260,585,918,378,55,748,240,859,249,16,768,860,983,893,893,303,970,288,497,24,348,478,140,348,473,354,361,198,405,452,422,256,624,762,552,949,128,949,973,386,275,255,949,644,54,79,949,266,162,23,205,244,0,912,848,789,253,699,933,543,87,936,323,69,774,272,600,195,524,321,131,921,791,854,862,832,414,160,104,184,177,64,259,153,271,304,412,103,845,896,145,597,392,874,513,969,366,319,390,181,118,340,508,613,266,400,654,666,320,173,358,442,497,486,67,109,812,286,182,917,241,451,874,925,117,80,180,170,322,258,996,143,162,389,359,580,857,122,69,821,643,618,900,479,999,44,553,257,827,50,896,400,668,370,916,583,195,325,845,674,667,398,117,864,604", "380,871,178,419,20,342,158,820,69,842,908,456,797,616,328,60,905,545,755,190,368,635,94,843,591,798,189,26,953,543,812,651,989,599,336,75,654,439,540,139,875,295,903,996,355,517,20,603,923,432,624,547,115,679,490,72,658,135,676,662,945,912,832,558,127,836,510,547,593,311,82,24,918,158,962,142,959,130,506,311,36,350,17,316,486,845,697,587,733,157,515,766,771,975,268,447,71,987,891,798,927,422,25,414,707,769,335,191,610,825,103,388,153,279,659,181,760,775,711,846,446,6,527,222,982,468,537,743,763,882,248,482,207,282,967,221,221,890,85,458,244,138,338,837,990,563,695,352,122,581,592,378,135,277,757,730,308,373,100,543,393,252,797,783,196,688,20,211,107,681,79,588,983,360,797,115,326,275,596,741,101,945,141,658,367,200,967,894,366,260,320,624,445,156,127,73,556,687,376,666,678,508,28,992,879,487,5,226,241,572,492,194,141,431,635,459,838,396,711,943,722,805,946,502,322,783,692,915,167,503,147,955,266,278,15,787,196,11,515,534,200,924,359,457,76,950,196,795,411,153,68,908,297,542,81,108,327,26,285,918,384,804,934,457,935,730,517,373,223,478,553,686,712,650,303,916,636,555,955,70,901,232,468,372,54,684,510,370,777,463,88,218,534,947,18,866,831,189,8,107,188,521,906,12,590,997,390,14,162,16,893,954,969,648,633,668,582,722,312,520,919,133,325,449,805,586,614,71,860,170,39,921,786,937,845,280,665,812,157,457,162,759,658,276,76,195,39,20,333,566,457,149,791,50,148,704,485,747,359,764,601,142,373,709,500,728,38,435,613,698,203,747,114,311,985,625,909,292,554,617,275,23,478,907,691,177,947,660,903,983,262,893,89,836,630,426,548,924,48,629,633,990,530,180,428,99,584,453,91,336,125,546,237,167,514,16,414,894,108,928,102,111,409,997,477,373,398,60,398,183,316,593,180,483,812,25,733,724,883,254,552,468,18,660,309,145,245,642,404,696,664,114,784,75,421,735,159,851,517,427,505,14,750,903,213,648,50,1000,625,469,625,236,770,514,38,637,204,241,134,338,171,521,229,149,81,17,499,912,470,273,328,311,854,232,191,610,4,888,684,679,22,831,711,636,413,537,654,763,465,736,796,679,745,354,721,331,274,834,558,620,986,789,918,457,594,103,696,980,234,630,640,124,248,165,589,302,650,104,662,677,627,328,590,534,664,189,707,948,546,416,473,889,977,427,633,260,237,841,891,830,234,522,911,849,252,344,191,642,276,685,428,253,922,147,502,727,382,527,606,766,875,73,801,629,807,418,751,83,624,380,274,284,98,914,297,478,938,965,668,462,887,537,888,488,444,988,918,990,365,979,647,174,94,721,542,740,812,841,983,402,283,818,350,224,735,452,453,57,23,87,17,721,518,130,155,284,788,52,115,656,671,724,187,243,965,743,473,755,940,329,287,489,30,500,36,267,13,135,12,798,850,41,654,504,721,798,255,505,252,276,877,548,507,711,575,731,924,924,58,281,110,221,984,462,560,680,460,615,391,704,181,264,10,303,331,596,478,588,242,753,439,626,920,385,841,589,850,943,394,784,228,9,282,801,511,842,77,120,309,375,445,336,584,437,502,608,747,551,477,50,146,376,924,705,485,313,117,238,351,616,565,33,829,230,770,489,115,998,376,101,24,686,774,7,162,579,198,309,954,632,178,883,378,671,824,93,368,10,414,830,899,918,268,6,619,297,18,338,815,733,851,240,260,363,150,981,898,366,876,875,708,65,563,350,40,472,275,184,752,850,89,671,206,995,737,564,276,922,825,540,60,999,785,435,316,607,799,39,188,111,387,152,925,437,637,686,980,643,507,207,904,517,39,518,671,637,382,698,674,988,77,299,205,106,178,421,774,261,418,469,91,373,15,450,927,952,796,72,44,397,215,855,316,919,233,857,766,900,494,261,974,613,270,148,363,791,395,186,12,912,538,268,549,935,711,545,394,912,0,411,789,904,748,931,647,67,724,229,229,398,394,755,420,799,594,880,436,321,762,182,983,299,915,340,705,291,857,336,286,741,852,275,692,468,242,101,825,386,825,475,473,365,249,853,484,361,435,383,508,172,911,347,356,499,268,301,606,2,273,510,755,703,179,161,610,522,539,128,298,189,593,160,219,331,606,993,758,745,426,445,229,36,461,944,701,912,607,933,600,825,239,252,681,973,673,313,295,311,777,170,344,496,951,51,999,302,122,596,624,184", "785,344,44,488,299,500,193,616,839,205,673,327,644,459,777,402,72,184,598,206,400,331,71,306,129,28,316,34,456,498,522,512,513,297,535,59,243,581,250,916,93,109,63,41,325,721,253,774,828,275,706,556,402,467,735,837,70,683,660,131,320,866,951,877,295,357,453,705,963,278,480,97,688,249,779,259,632,457,47,605,523,771,489,895,25,273,709,691,233,221,903,688,732,591,698,509,790,406,363,569,259,214,616,437,915,611,974,689,714,590,126,143,191,530,543,258,48,461,89,524,312,41,797,668,766,960,240,631,529,623,858,395,368,314,732,304,584,767,537,88,997,16,326,678,403,632,945,231,407,171,568,313,952,33,996,865,806,989,110,777,531,768,514,365,752,257,598,544,850,635,379,227,340,842,650,276,205,877,557,631,785,808,971,760,768,263,377,626,530,570,649,780,409,939,682,126,333,278,34,120,916,346,313,955,755,932,217,191,379,197,541,254,827,234,179,130,29,976,186,109,39,286,384,759,761,838,109,854,511,930,12,769,492,74,67,186,756,857,437,743,927,544,405,351,139,566,547,978,27,375,628,645,240,758,578,541,868,507,52,65,903,341,270,907,389,469,305,277,413,585,847,235,703,90,302,476,624,90,716,295,256,862,71,292,675,329,912,542,687,422,473,734,518,283,50,567,641,813,490,851,649,995,246,865,347,905,698,104,880,813,672,231,160,283,146,371,28,732,421,758,961,906,492,922,203,689,710,361,483,37,107,762,138,657,556,953,347,591,539,831,696,563,200,723,135,881,866,358,727,74,438,636,208,877,180,819,957,363,988,625,452,618,39,306,559,580,727,364,997,195,323,972,48,262,452,598,580,620,554,48,95,434,822,603,833,79,817,894,381,890,288,107,792,703,753,590,993,779,926,876,914,12,64,75,712,366,555,820,897,47,653,64,441,894,664,510,764,965,927,639,300,905,712,73,48,409,659,242,645,920,329,585,785,539,587,652,87,280,101,5,169,672,773,862,986,436,884,567,849,730,731,780,913,959,964,411,428,838,464,182,536,293,602,786,799,195,582,205,91,576,403,992,979,426,450,8,373,822,576,569,9,311,809,75,695,844,57,932,483,131,20,916,526,528,559,768,185,709,827,787,310,834,226,989,218,657,299,815,383,64,778,14,617,761,701,751,9,54,905,981,385,346,608,846,779,627,179,558,159,258,385,210,189,280,359,89,476,463,836,466,643,701,846,45,93,95,801,526,911,177,768,31,301,238,20,118,693,333,37,962,472,930,667,434,800,556,236,836,659,78,470,183,190,629,281,6,512,260,496,752,151,243,236,48,534,314,981,610,444,652,825,535,761,923,747,846,8,911,90,361,187,918,44,754,928,856,119,724,962,581,959,738,480,622,374,184,819,44,608,47,846,624,421,802,810,17,760,909,893,434,866,356,104,437,989,771,879,935,980,192,129,319,452,437,781,410,956,86,475,342,84,698,176,341,436,551,432,65,592,311,22,14,876,366,33,234,479,940,593,878,393,223,445,963,437,707,521,624,283,501,594,262,332,6,437,306,869,208,965,678,408,660,593,262,805,929,160,244,871,674,541,792,489,7,176,809,996,5,424,523,582,906,280,789,719,191,671,145,425,25,716,837,555,644,333,391,786,357,453,696,574,780,890,334,899,865,802,272,272,608,384,653,300,455,488,273,307,306,7,980,298,738,66,34,711,665,778,421,916,604,547,310,881,420,684,393,66,159,950,601,130,656,684,733,5,820,796,782,539,639,89,324,159,959,882,775,680,941,717,875,989,93,908,640,398,235,126,215,109,840,150,666,761,295,210,361,365,122,287,796,755,142,404,592,987,17,909,608,854,349,740,552,651,900,348,882,234,730,479,219,887,884,646,276,344,814,331,328,49,728,977,214,494,924,484,627,883,459,157,235,520,120,889,718,688,281,164,928,883,410,607,942,620,81,6,624,719,580,927,615,691,553,781,27,350,836,199,825,521,925,939,429,637,136,747,636,302,848,411,0,996,967,17,20,855,870,479,269,897,696,121,301,651,429,477,721,424,749,746,412,859,785,870,90,536,399,841,209,578,482,255,868,956,178,411,475,628,903,986,908,906,638,194,376,657,246,340,983,811,17,976,126,522,194,232,223,908,643,810,594,861,110,960,859,974,713,793,585,167,40,182,162,739,283,284,751,326,739,282,553,620,89,789,620,563,38,198,817,768,183,609,92,483,667,855,23,865,135,165,558,540,498,539,173,79,687,311,110,100,935", "60,638,765,319,530,682,933,400,938,307,214,138,52,752,290,719,284,782,770,920,243,846,22,793,863,474,844,767,81,63,98,659,203,903,915,843,870,874,245,811,89,889,896,661,386,815,996,781,503,251,405,249,12,926,491,244,334,815,511,520,937,158,496,332,843,210,269,647,831,298,950,345,947,502,308,916,958,797,122,839,68,230,811,99,365,687,950,132,553,781,142,716,671,825,504,57,607,997,646,326,642,245,643,841,164,401,324,94,82,874,916,396,462,293,623,438,336,501,974,29,207,19,805,262,931,395,773,993,356,853,318,711,285,114,810,354,903,524,3,249,620,219,892,925,955,594,475,145,496,995,226,794,42,712,701,646,583,281,308,654,182,889,746,515,845,662,509,133,538,6,992,902,422,891,111,857,879,754,457,177,5,946,297,386,132,982,633,57,494,654,588,852,370,957,831,1,298,37,35,974,133,408,334,631,172,245,260,968,640,447,355,778,304,203,700,122,699,46,51,206,415,436,668,331,523,860,950,992,426,13,905,467,169,704,709,250,454,152,779,897,363,975,259,19,970,8,241,793,305,96,373,444,291,303,460,611,384,823,230,386,69,953,54,928,260,433,286,298,379,118,751,850,731,123,945,692,360,875,267,918,743,174,81,307,369,706,953,63,22,743,735,463,367,893,212,125,442,770,739,159,401,854,374,963,808,224,485,709,800,793,123,678,612,628,815,893,693,241,284,832,448,548,515,880,867,744,827,770,482,355,864,75,3,662,514,172,885,737,450,269,737,905,528,585,257,518,774,218,1000,739,875,819,812,411,524,664,580,257,384,254,624,561,941,701,645,939,254,695,226,124,488,542,733,496,528,594,203,235,673,106,126,724,41,92,832,894,948,554,69,426,393,483,776,23,581,277,756,296,189,795,387,895,263,841,465,466,818,460,24,735,257,426,641,387,770,117,204,242,694,29,176,873,549,739,927,782,919,265,346,996,857,639,886,408,195,908,49,528,754,163,78,494,353,926,590,671,130,129,647,67,242,827,268,792,38,746,781,87,669,589,539,166,267,544,259,807,347,321,712,639,404,773,228,140,310,516,520,741,732,737,353,226,756,790,838,765,472,755,772,823,249,54,597,45,641,835,955,289,59,156,946,755,599,31,739,357,145,315,720,890,542,470,192,332,232,516,47,964,703,109,776,810,986,736,412,947,701,538,66,553,96,943,884,576,296,81,237,530,343,465,217,560,718,629,892,769,144,749,966,51,630,799,238,545,881,178,808,985,558,628,401,324,378,356,894,193,709,448,285,206,75,709,374,253,334,55,650,87,348,631,741,268,729,58,81,935,871,549,333,553,967,178,405,92,702,166,643,428,343,229,856,11,271,377,582,909,619,187,142,584,706,738,117,26,207,310,200,507,505,509,449,541,396,227,189,125,116,773,359,653,817,687,259,406,78,11,312,279,930,57,647,875,975,49,271,442,11,731,384,57,383,335,388,450,321,213,807,2,269,976,668,865,505,27,240,350,380,420,482,723,381,405,787,114,179,933,704,491,844,530,968,837,284,394,739,547,378,804,223,461,757,68,78,500,584,768,34,284,228,152,107,53,466,726,240,505,248,808,146,651,127,783,815,951,306,384,205,327,334,877,149,561,347,776,965,539,443,540,904,525,738,467,606,980,668,634,741,797,570,69,330,860,358,662,409,517,643,827,631,769,154,332,545,812,136,52,645,647,254,836,301,607,153,699,176,621,350,335,280,17,888,953,25,603,886,522,754,239,863,437,955,245,725,14,143,863,182,847,575,14,604,505,93,388,708,79,543,914,547,682,685,844,847,666,675,182,665,290,662,496,145,525,631,828,741,678,123,800,803,8,792,543,135,338,54,221,590,829,171,268,925,342,2,812,643,708,77,675,406,572,84,743,979,916,289,550,194,861,873,454,601,215,789,570,765,456,794,879,939,329,467,713,6,832,901,180,289,711,28,378,169,85,740,618,794,344,453,192,508,453,51,168,886,673,965,636,638,789,789,996,0,12,307,993,399,19,591,190,281,388,551,877,805,913,388,69,984,447,947,476,202,872,852,681,467,258,583,611,740,827,149,202,361,712,615,531,192,759,126,809,696,314,785,905,422,468,612,536,115,959,382,515,59,509,907,867,594,654,763,839,254,463,837,850,859,458,185,960,198,591,864,849,821,883,918,6,252,52,357,899,953,7,729,669,149,479,546,649,213,180,427,89,97,229,392,688,26,646,115,958,972,957,373,435,230,300,196,634,795,562", "341,799,755,131,472,873,445,126,689,277,78,492,94,168,708,75,758,995,218,421,788,186,863,161,712,983,214,601,637,887,732,291,840,537,694,523,925,871,359,556,584,545,150,711,130,159,449,870,428,394,859,120,515,38,664,847,304,379,458,431,631,323,736,882,82,430,90,387,70,230,926,244,943,680,958,874,755,428,708,973,891,585,311,419,727,589,29,429,94,219,543,639,757,258,588,123,522,382,832,923,749,874,459,445,504,331,309,876,574,368,305,88,468,560,34,809,18,336,70,47,317,82,384,471,227,556,125,207,517,925,712,844,928,408,616,808,665,203,518,412,759,696,259,855,648,128,366,690,550,555,189,986,994,174,642,448,642,964,772,150,247,532,144,906,145,210,720,944,589,623,521,813,765,189,398,719,161,445,201,182,17,959,998,625,697,257,278,860,856,706,42,754,505,679,833,370,675,662,500,275,791,415,600,107,742,5,521,387,621,542,731,42,275,220,366,893,952,433,949,854,991,415,540,457,810,524,252,483,490,899,351,349,954,391,16,635,318,561,405,33,984,56,290,238,785,767,5,326,315,192,81,138,759,331,923,670,131,792,228,679,219,481,749,89,129,163,468,403,795,606,809,503,515,918,786,935,532,62,512,375,951,371,147,6,76,844,999,336,872,922,783,844,880,924,181,6,528,810,117,587,919,914,546,767,280,181,800,15,900,903,951,624,954,625,136,729,801,611,461,401,249,712,10,615,405,377,940,501,933,859,32,807,166,814,675,931,493,603,704,817,593,152,219,237,278,421,915,532,956,392,360,610,917,636,224,482,657,660,192,742,849,178,474,897,736,155,78,509,466,46,192,961,312,662,801,358,194,713,654,67,234,438,746,715,334,872,893,386,989,792,649,476,771,403,76,859,573,248,736,557,526,342,404,769,907,850,776,859,478,55,232,840,754,979,550,246,633,230,387,420,202,915,466,404,119,433,109,252,656,744,34,683,845,347,562,418,911,440,602,108,347,369,520,668,907,530,582,379,970,277,981,356,207,226,124,174,964,380,498,476,865,141,197,328,437,192,386,835,268,858,520,923,157,627,552,947,534,145,21,523,699,332,105,784,412,158,778,709,678,850,214,778,547,161,564,951,938,768,617,531,160,543,19,290,241,50,24,284,775,106,602,66,403,286,557,970,800,830,901,451,337,726,566,752,901,677,753,47,156,74,558,411,358,487,16,520,417,600,562,625,108,317,876,808,937,84,952,355,402,509,258,671,682,765,346,585,844,377,619,803,153,485,416,523,150,180,288,425,625,821,155,89,457,542,173,33,672,228,983,296,865,115,676,787,186,669,404,183,621,784,636,842,237,795,11,786,191,336,589,107,480,406,135,811,515,767,233,250,705,25,671,41,139,60,6,858,720,284,781,302,29,114,579,547,699,372,430,604,912,385,63,716,857,175,332,552,62,402,479,109,193,700,289,570,886,104,452,176,893,802,434,349,423,433,350,953,796,356,142,903,818,655,889,967,779,683,762,388,343,816,267,264,128,968,142,582,980,457,298,357,99,631,734,655,307,916,401,749,60,521,275,79,41,843,632,512,198,243,55,503,978,223,97,102,498,519,673,962,728,443,708,685,705,539,250,286,27,236,412,668,101,441,470,378,559,775,740,601,148,975,446,378,827,880,244,231,106,158,661,435,539,78,548,702,435,146,898,634,738,455,740,349,189,536,981,383,406,567,685,817,818,120,967,550,677,586,90,266,21,506,459,915,524,928,307,24,648,11,905,468,634,984,728,325,975,107,760,952,844,312,165,914,583,952,325,490,545,968,175,310,81,511,633,967,186,379,834,370,295,675,761,522,599,665,237,309,147,621,20,936,747,480,834,886,975,198,361,544,309,978,291,823,454,692,548,16,435,417,132,379,480,702,989,693,263,710,713,307,7,261,736,132,237,468,217,446,43,862,812,834,799,802,831,214,231,240,508,894,311,141,269,710,343,764,769,255,895,726,759,357,300,506,243,532,877,194,965,253,904,967,12,0,861,636,138,820,905,173,501,691,573,423,993,959,160,321,714,918,454,747,764,479,630,119,439,495,453,780,496,229,709,880,851,532,840,588,477,466,334,200,491,670,939,430,770,101,902,799,436,796,816,344,312,896,937,929,88,872,959,280,915,404,281,640,383,682,885,611,803,588,521,145,896,454,709,254,247,106,206,845,497,529,822,402,414,572,379,730,452,901,125,146,673,841,900,977,262,95,275,584,457,573,786,797,946,75,491,625,665,618", "278,881,523,741,598,424,478,331,883,245,727,723,398,978,925,173,765,223,434,718,177,398,767,109,986,458,499,623,275,907,265,766,726,579,278,374,901,579,616,553,417,624,313,67,864,157,890,89,572,572,406,638,482,521,235,42,936,129,563,691,20,248,909,191,649,390,848,692,807,242,939,546,909,115,169,692,789,803,339,129,930,715,780,46,905,955,456,424,173,96,821,225,169,959,243,159,101,584,394,607,781,346,546,839,156,164,393,781,897,688,577,274,578,93,963,513,163,92,371,980,546,490,256,974,872,468,281,843,944,767,411,785,692,347,436,242,521,728,519,919,667,884,52,513,505,46,642,800,909,258,904,728,456,313,911,881,768,538,330,886,887,650,43,22,956,127,737,163,215,537,586,178,77,112,839,250,8,76,58,547,854,132,781,98,430,737,3,338,835,474,170,730,251,19,156,942,576,151,345,813,130,235,765,691,17,608,758,115,518,53,891,95,180,716,739,625,964,20,164,926,186,456,394,718,503,568,87,990,969,272,758,960,87,613,15,471,400,992,346,836,503,550,204,954,633,708,88,418,387,580,157,917,121,719,994,988,23,460,641,476,739,755,533,517,766,983,21,248,62,247,643,351,107,549,229,639,98,566,567,114,893,589,97,679,239,1,791,738,103,994,898,160,127,826,618,825,378,359,470,957,427,221,64,353,509,130,103,711,345,564,29,580,742,108,606,34,153,49,345,110,515,116,917,1000,1,55,974,682,727,729,213,614,429,975,244,123,169,818,802,548,622,216,723,776,149,753,732,953,206,123,110,608,122,483,454,481,833,980,514,687,107,814,954,382,41,34,174,195,31,830,329,959,606,596,436,18,803,112,451,114,885,447,746,371,964,670,832,384,219,418,696,81,62,497,870,359,509,672,578,284,461,328,618,909,190,371,876,293,716,624,689,915,549,119,843,255,450,789,901,337,987,270,657,238,405,411,840,773,59,830,979,847,591,414,319,107,255,41,757,621,206,919,456,23,63,289,822,181,134,232,596,370,260,705,261,913,620,847,483,246,282,600,589,962,33,194,405,377,42,803,863,268,460,963,95,278,95,8,909,512,373,806,57,205,229,182,250,446,330,547,191,636,183,777,709,684,323,389,36,877,119,230,415,739,516,319,683,201,523,322,640,291,780,786,500,838,770,401,179,348,929,355,396,112,357,778,18,718,775,283,670,172,465,794,143,670,950,933,610,442,519,678,633,786,687,863,15,645,266,379,327,761,839,233,109,423,40,716,47,561,891,303,150,998,516,921,438,295,126,228,662,640,918,393,573,452,201,510,291,762,942,819,847,7,13,7,397,416,152,10,957,57,198,907,666,409,628,886,666,247,705,128,603,772,969,899,712,356,719,652,388,442,648,651,796,162,692,731,495,174,637,811,158,668,355,115,225,208,452,90,339,784,901,402,481,482,483,780,842,866,169,123,571,78,556,130,604,52,741,746,927,92,823,789,783,392,173,590,341,117,268,862,409,913,352,287,225,211,887,562,675,16,999,983,870,558,209,42,38,937,56,689,404,103,675,252,592,411,65,228,602,671,586,976,689,396,467,347,196,553,214,498,44,390,229,941,771,387,956,955,451,666,321,980,614,435,267,78,907,18,542,157,517,512,534,271,523,254,809,652,387,336,512,316,434,307,702,583,410,128,548,531,895,998,295,153,643,679,60,820,31,744,717,340,332,697,699,223,551,284,19,61,482,182,191,111,50,14,171,616,472,500,593,934,952,956,358,254,612,535,847,660,632,823,388,524,865,864,690,882,524,722,192,432,496,177,450,119,914,236,948,709,665,978,417,523,459,103,996,951,497,214,857,325,418,467,833,813,264,130,86,739,158,992,665,650,554,704,463,647,390,388,726,455,514,199,77,410,577,386,579,255,920,50,92,755,986,522,818,850,648,348,364,684,968,990,561,293,347,99,429,883,102,414,97,264,534,807,83,84,403,280,477,503,739,908,58,609,576,227,619,490,937,819,530,439,73,699,748,17,307,861,0,773,58,865,223,852,941,905,867,909,773,585,6,995,395,313,159,73,363,745,241,936,881,78,75,991,446,814,280,727,545,338,31,637,416,822,788,495,734,780,41,913,195,127,767,886,172,689,986,822,620,916,45,805,489,184,978,604,371,350,321,145,197,485,25,869,627,301,909,757,688,431,718,654,938,838,448,381,638,507,236,686,5,909,923,506,185,404,371,340,437,470,922,570,658,505,112,480,786,797,136,552,856,72,975,445,69,829", "468,997,121,671,381,61,20,229,837,495,962,592,708,489,189,270,727,606,172,24,204,98,269,353,412,207,867,570,714,415,902,450,72,531,504,902,897,894,727,297,556,199,620,562,870,169,800,105,33,873,930,355,275,808,703,118,987,582,914,307,645,898,592,11,384,825,772,699,100,23,669,790,398,160,493,353,932,944,135,216,158,174,508,9,628,865,920,984,490,287,731,311,700,152,933,149,480,793,819,53,996,223,813,575,507,869,126,55,600,724,214,501,581,877,476,445,6,636,679,797,382,160,295,638,528,606,790,440,718,467,829,36,582,766,376,647,302,765,118,519,31,966,582,478,340,467,493,534,683,173,974,893,604,740,248,323,220,368,638,872,311,998,852,229,154,215,956,410,246,272,343,571,38,697,362,240,369,420,445,316,353,767,246,551,632,267,474,141,250,50,144,798,542,112,655,910,961,364,836,294,493,341,568,631,913,204,87,20,670,848,258,238,784,228,583,677,260,430,5,74,566,953,345,879,943,844,19,788,92,417,670,316,216,515,329,642,456,102,910,275,604,307,164,745,631,984,189,432,301,477,711,559,861,333,500,323,653,278,776,775,83,29,154,807,636,196,69,821,549,641,23,425,878,400,272,936,827,140,528,823,153,430,979,95,872,304,455,768,685,146,82,953,252,78,136,520,907,141,45,146,296,882,664,552,204,838,369,762,377,852,888,974,656,353,102,86,32,463,810,309,583,435,535,683,215,617,70,924,651,283,973,335,661,59,231,258,503,843,817,802,274,391,173,631,602,523,504,472,463,910,162,699,480,972,41,958,189,550,991,55,592,99,895,806,578,378,109,945,39,457,354,993,730,322,615,186,505,771,559,185,798,5,400,483,621,838,959,695,405,687,51,665,740,865,167,825,399,485,647,797,214,209,290,51,248,651,418,933,801,819,4,105,782,716,986,173,512,53,863,488,388,237,472,834,391,398,689,705,857,424,741,839,959,132,671,510,331,563,375,499,593,25,946,30,639,105,570,136,778,436,403,596,464,422,741,849,455,214,621,193,516,7,227,467,919,912,717,275,565,269,148,556,55,8,544,555,911,117,724,663,307,181,615,193,27,49,904,730,923,443,845,422,11,957,32,329,742,335,685,21,34,20,292,218,247,353,510,990,258,942,372,268,304,36,13,867,965,410,746,426,972,624,706,209,70,648,748,550,65,556,583,385,571,803,882,131,439,425,45,126,684,940,282,318,79,285,410,889,686,553,295,621,198,208,398,207,372,637,282,726,534,948,330,207,322,82,48,453,160,474,477,898,87,30,21,370,61,398,348,241,502,413,491,749,8,329,198,581,140,46,587,486,188,929,457,230,309,596,564,405,856,336,590,104,785,135,196,159,116,266,351,449,920,301,533,869,147,498,194,515,476,117,512,978,371,654,114,971,267,700,79,322,449,893,787,477,939,636,356,692,673,42,853,473,221,8,117,679,386,66,404,337,886,298,331,129,537,95,632,93,12,157,546,515,59,525,446,677,797,868,159,698,440,347,963,757,279,264,500,132,925,593,515,482,7,713,100,4,964,879,730,291,921,698,938,838,332,199,18,468,826,327,780,840,380,844,628,882,407,66,911,655,364,337,583,802,771,904,512,802,575,640,783,276,597,97,163,629,743,185,214,159,648,825,436,805,888,566,966,471,598,768,82,78,119,150,725,754,534,603,436,405,619,769,121,68,15,756,82,43,780,664,859,173,275,185,620,912,819,824,285,966,498,369,283,835,468,734,848,11,183,158,282,632,128,614,416,82,543,510,560,907,413,251,811,76,185,211,336,755,11,607,697,121,944,889,194,714,484,72,40,775,120,952,463,550,444,321,715,98,954,236,16,856,628,823,714,215,213,749,178,183,477,436,39,115,519,784,368,837,837,637,180,989,243,170,403,574,395,805,124,354,246,953,457,444,914,131,998,110,845,399,440,171,353,532,196,416,563,561,860,569,260,534,350,903,454,787,850,72,193,74,16,191,279,13,680,933,931,20,993,636,773,0,748,956,90,353,951,33,365,208,719,265,646,857,643,832,856,60,69,699,526,630,531,236,291,621,204,172,528,991,399,557,726,908,317,327,654,742,668,636,564,482,408,402,62,772,983,544,356,679,91,711,252,198,628,649,968,541,29,118,119,277,735,945,197,67,177,322,193,293,976,652,746,357,361,605,885,814,82,51,667,844,815,470,74,867,397,584,974,282,923,303,733,180,125,246,500,826,946,76,80,563,115,302,218,693,819,61", "828,342,834,756,288,156,311,968,411,265,605,401,364,891,493,218,591,630,752,365,492,134,961,407,383,890,822,995,951,534,937,474,272,393,685,739,619,857,350,344,186,40,603,851,954,280,700,679,160,983,261,579,242,433,385,241,643,377,364,170,8,524,912,615,302,149,660,871,822,269,211,654,761,165,822,890,574,204,204,590,219,110,112,169,557,393,33,581,853,381,844,919,142,244,812,486,884,463,109,410,91,770,151,644,823,433,751,74,369,864,662,477,887,799,748,626,997,588,989,430,85,851,893,571,682,978,906,536,162,415,432,855,760,567,349,807,820,130,516,264,592,962,838,459,217,493,332,910,45,69,472,485,823,122,9,303,926,657,794,980,52,128,759,681,571,834,663,919,23,265,549,800,114,622,375,774,729,11,739,423,479,57,336,71,91,820,911,395,607,281,866,804,205,87,459,26,861,699,274,725,229,340,710,25,965,965,98,933,797,156,894,781,65,497,770,213,32,366,978,716,94,716,673,638,623,109,372,285,506,202,526,671,152,516,308,808,539,645,511,435,22,526,583,426,874,302,664,779,442,69,512,607,196,818,645,53,916,809,847,349,869,56,740,225,158,332,635,101,747,894,246,573,642,17,138,810,609,682,225,806,705,720,518,915,806,135,120,771,968,216,284,429,112,683,767,375,475,244,960,625,22,330,725,196,859,470,532,307,190,269,475,994,636,368,614,431,64,841,981,104,957,422,543,94,337,951,459,758,785,708,273,671,737,680,398,317,712,634,870,158,581,389,541,368,324,36,278,361,947,211,979,609,634,284,981,556,228,810,987,575,606,382,480,788,152,389,908,837,721,850,802,243,526,10,246,294,703,40,373,130,95,685,462,777,768,841,49,702,600,724,562,799,58,12,205,651,796,486,328,646,580,423,257,102,434,314,973,427,688,339,790,119,182,24,897,225,62,419,173,239,478,698,806,165,358,529,372,654,449,449,81,192,668,303,331,32,526,23,454,621,575,455,106,47,987,106,415,882,656,562,950,369,328,672,665,204,702,848,870,247,828,389,585,43,478,329,945,47,656,214,573,448,501,501,175,127,694,206,244,843,69,129,798,386,662,760,836,598,501,130,426,533,276,280,480,257,323,89,748,501,262,29,17,285,6,544,586,426,793,797,254,197,604,749,139,235,113,351,493,964,42,111,545,392,433,438,633,590,960,481,260,128,841,563,395,864,429,213,215,567,24,265,431,336,755,830,676,791,801,876,925,140,154,632,278,425,184,691,324,521,563,65,593,590,582,795,714,995,221,814,536,619,116,911,889,474,800,237,778,92,123,145,962,638,902,77,327,556,681,134,573,243,598,103,194,566,644,89,941,235,629,18,537,811,407,955,86,519,127,162,395,303,890,30,485,984,143,135,990,655,108,106,783,890,883,829,175,64,820,376,226,598,978,931,798,444,251,990,397,538,614,507,712,454,506,560,675,413,481,154,795,584,919,180,257,337,223,876,781,274,834,851,52,816,6,82,618,727,78,184,860,589,453,29,897,633,819,597,396,9,493,461,626,992,978,217,756,789,38,340,85,280,633,235,421,666,667,480,756,295,788,917,620,424,725,590,481,527,207,303,792,951,48,53,594,917,800,851,135,684,878,448,788,466,820,856,384,610,543,443,287,184,555,610,737,825,62,303,825,400,977,748,446,145,423,716,409,962,64,275,197,413,640,167,983,141,152,997,715,838,683,664,801,637,296,431,114,71,392,549,5,851,698,547,720,859,360,127,652,542,311,966,263,155,660,106,448,149,72,117,600,123,574,603,137,314,369,209,567,650,130,43,678,617,732,727,914,6,190,961,856,193,79,991,728,563,475,650,136,667,439,164,955,855,246,183,397,106,280,305,810,271,989,781,747,136,427,426,316,639,103,898,258,872,540,569,388,477,837,151,715,443,277,484,9,643,289,363,163,834,307,411,315,224,964,530,89,895,273,850,345,525,700,414,661,378,937,719,790,865,719,795,305,666,46,512,372,543,647,855,399,138,58,748,0,101,548,114,485,773,55,464,516,685,503,538,846,182,107,242,437,929,10,728,245,279,159,956,630,775,43,946,308,920,274,596,578,97,432,454,115,839,374,926,174,804,474,148,811,9,87,902,362,232,772,533,189,333,285,649,93,514,195,722,571,969,513,705,356,642,65,181,552,742,609,237,54,952,779,502,262,520,692,999,132,473,19,741,166,695,66,752,534,638,683,346,201,368,106,139,644,262,880,815,753,333,334,564,832,824", "213,572,711,970,224,632,54,225,608,251,789,786,646,601,875,221,635,574,329,665,574,398,686,380,333,541,856,8,67,587,204,745,226,112,818,414,436,9,647,387,391,59,616,269,983,577,52,945,631,146,430,437,892,987,921,471,547,985,611,859,546,574,256,66,687,752,230,70,310,463,514,777,616,287,858,454,26,620,69,181,948,913,984,968,273,347,433,865,364,748,64,800,922,32,168,839,951,163,527,684,548,636,394,512,780,993,845,241,303,455,257,249,790,444,552,911,833,381,5,455,202,253,430,233,30,316,793,473,310,232,801,679,189,444,773,245,776,746,716,474,141,545,452,984,518,305,615,343,671,419,838,487,49,929,696,97,588,219,119,615,733,895,796,430,661,629,490,771,804,781,447,184,766,142,281,214,796,474,937,954,391,310,884,78,651,264,806,779,800,384,454,654,964,95,5,413,607,703,462,57,948,287,110,519,230,902,391,741,607,260,679,950,168,794,179,321,322,837,103,358,977,826,851,508,836,981,46,196,67,728,829,845,610,848,311,672,910,303,391,940,451,968,712,309,322,990,490,920,179,351,556,580,673,71,869,470,642,78,543,76,717,778,420,156,235,514,553,494,38,576,384,722,502,238,716,140,993,609,637,552,438,999,18,446,396,972,287,134,644,198,319,237,485,472,417,907,726,110,97,202,127,30,774,130,860,822,618,882,353,276,521,117,355,880,721,132,498,691,821,7,23,576,77,566,939,446,101,133,282,242,943,206,620,48,132,20,987,747,688,377,493,483,169,838,219,612,983,311,339,528,606,160,573,550,809,932,211,530,123,800,645,993,263,509,387,409,63,998,579,961,994,965,965,437,326,492,327,899,324,729,860,654,527,678,429,406,789,821,228,478,708,459,856,850,924,693,329,697,428,882,29,346,306,654,123,415,497,678,730,133,906,461,49,457,735,701,678,476,846,534,364,162,511,10,840,898,609,326,597,903,69,491,10,173,910,141,568,683,129,996,253,338,650,844,462,881,976,651,66,909,223,657,825,132,21,125,619,83,871,197,212,642,931,924,923,621,67,215,797,898,74,63,277,184,572,464,826,924,137,404,379,233,514,845,57,468,255,658,317,678,118,829,145,608,335,990,681,448,614,263,339,546,788,260,406,235,545,666,580,154,865,219,388,48,616,673,6,446,479,207,174,420,339,546,848,862,430,97,73,361,557,913,553,68,258,64,701,724,738,582,539,37,942,113,892,468,876,38,621,413,972,969,409,976,763,178,746,551,420,390,405,280,416,531,741,316,199,549,662,948,36,716,501,876,278,701,935,783,575,861,581,195,286,96,652,952,346,937,165,862,560,774,340,348,316,345,52,887,865,632,619,505,244,247,745,901,864,380,45,93,181,624,377,696,933,401,420,530,930,408,917,363,583,215,202,486,317,545,382,790,237,77,81,330,128,426,919,178,642,458,904,943,59,947,100,210,784,27,252,245,687,936,888,144,387,674,900,571,338,544,264,184,727,242,426,925,667,9,871,471,591,292,6,299,761,981,238,856,861,344,244,350,943,591,135,316,857,192,682,431,106,639,344,89,511,116,45,795,764,563,193,526,49,350,204,332,35,759,946,167,312,338,376,183,506,857,784,277,323,927,297,80,786,221,108,239,870,708,832,211,150,175,466,891,196,43,20,87,763,410,424,377,400,463,95,582,469,37,544,895,953,101,329,360,968,208,716,485,728,406,690,437,948,510,747,498,983,446,291,184,130,371,804,865,988,791,223,877,686,922,136,204,349,816,224,190,316,985,738,369,922,760,731,128,573,920,822,432,596,846,927,309,556,951,178,764,891,57,791,635,440,304,293,98,948,290,412,167,150,854,919,720,103,1000,337,510,875,516,314,548,384,553,726,683,713,353,710,245,713,728,113,742,641,532,46,472,945,100,855,151,510,986,392,400,204,299,238,877,528,834,556,18,180,31,734,421,333,974,177,337,84,586,473,341,12,234,163,928,288,421,16,143,877,319,397,194,771,87,67,870,19,820,865,956,101,0,525,252,507,717,448,101,201,917,909,673,586,919,27,522,163,791,646,467,849,235,668,495,8,735,551,568,121,127,902,85,685,627,418,54,193,683,878,913,186,676,567,968,725,516,911,891,320,657,917,925,453,536,865,137,719,796,942,988,938,975,396,72,294,633,569,652,252,878,733,997,453,774,444,462,229,720,27,657,198,880,103,750,32,565,325,862,383,513,722,673,518,6,843,400,826,420,977,776,252,286,952,134,844,939", "711,487,136,751,610,802,448,537,866,849,421,357,258,525,287,931,229,208,898,489,693,806,415,791,557,252,489,888,764,896,777,994,539,177,719,547,303,739,152,85,502,12,312,692,919,838,193,313,952,641,19,410,487,563,733,267,924,765,253,402,957,190,594,664,694,507,992,960,164,587,445,462,169,966,254,124,499,793,653,576,564,380,627,988,314,735,522,748,567,841,417,256,852,908,252,232,556,191,248,526,276,955,119,548,768,700,985,152,312,160,145,359,279,177,427,685,767,656,532,322,827,890,793,993,669,509,440,120,978,799,748,725,600,924,566,152,160,940,521,589,965,584,386,610,857,987,759,807,245,743,587,290,856,497,29,15,69,220,416,684,139,415,229,87,224,829,284,242,575,474,565,279,904,594,132,139,416,911,433,932,32,489,139,327,606,19,975,867,821,831,352,40,679,829,456,60,219,622,777,357,352,840,667,761,680,100,53,808,764,405,816,436,827,264,228,129,333,800,950,641,833,906,650,619,245,791,878,3,480,963,218,805,44,955,144,743,80,227,875,990,406,159,86,254,723,813,226,711,264,667,354,719,307,968,243,997,999,739,524,673,986,279,403,629,210,806,939,197,332,399,151,691,382,286,856,926,496,935,459,59,684,659,791,270,183,201,590,36,597,951,748,71,344,91,201,1000,231,862,575,116,513,190,829,627,251,27,239,640,928,129,787,471,559,9,628,113,20,303,194,983,41,509,346,67,596,294,416,985,530,62,497,875,644,83,499,479,852,619,911,315,718,810,652,612,505,88,48,707,878,864,638,412,966,142,998,303,861,232,598,575,832,140,181,962,161,177,205,843,715,305,662,261,707,786,88,527,419,476,936,203,610,25,537,50,347,595,296,302,812,722,169,666,966,563,340,582,7,803,859,863,77,593,87,470,227,464,751,658,606,488,559,75,460,662,587,688,27,584,455,601,285,417,490,75,397,364,432,975,1,674,249,577,878,84,910,634,625,647,594,752,619,723,283,175,416,994,962,131,894,108,275,368,659,280,511,270,708,870,435,922,3,390,166,300,254,936,620,331,429,351,556,409,34,92,904,155,649,951,730,112,186,760,10,523,739,921,817,169,399,288,112,592,359,463,742,177,956,877,657,791,688,421,671,416,954,319,17,299,582,336,748,320,130,12,633,407,333,539,110,186,552,395,29,574,842,199,366,201,452,380,973,411,326,393,234,129,861,204,749,14,916,258,848,613,387,837,877,92,800,882,403,247,673,179,565,458,540,861,66,635,30,521,124,20,491,352,751,152,721,789,959,563,657,227,394,838,351,80,749,971,809,884,299,546,532,435,456,467,162,382,849,784,709,512,174,160,688,530,948,151,973,272,643,888,709,228,474,552,568,644,766,115,89,494,702,765,648,67,486,21,701,436,293,742,985,711,454,258,676,459,986,73,903,823,726,583,820,889,67,808,150,735,588,272,939,790,503,883,97,957,968,647,874,30,39,80,583,358,870,570,881,643,938,119,980,500,430,788,137,869,987,736,718,926,571,371,155,51,16,805,944,279,251,513,564,218,957,789,30,616,162,927,602,578,877,665,154,165,623,706,838,316,186,970,790,159,353,886,905,808,2,560,942,887,256,465,692,352,149,344,76,850,623,306,701,332,866,528,578,60,393,954,447,951,400,674,944,475,371,971,34,710,643,304,805,330,826,520,992,135,649,362,690,405,915,539,732,262,892,315,73,858,319,740,286,984,657,170,190,839,369,365,72,202,67,488,335,387,474,468,987,836,528,602,66,1000,221,259,322,9,941,912,637,291,711,304,33,832,156,297,43,744,522,169,760,805,317,403,380,525,536,662,939,158,236,345,844,484,486,594,550,942,19,790,679,397,292,172,282,680,143,524,782,507,786,981,602,467,465,901,525,651,872,11,62,860,929,538,859,867,707,689,442,902,865,18,162,176,351,229,132,234,976,773,362,590,141,440,214,158,639,375,179,818,333,800,550,258,116,917,408,550,396,477,313,413,900,936,724,479,591,905,223,90,548,525,0,168,166,146,274,757,915,792,406,48,897,584,770,4,926,689,299,249,517,998,262,275,378,470,843,602,426,929,525,58,839,29,479,294,316,146,167,816,552,719,767,606,608,43,215,976,154,682,494,809,847,271,381,555,992,8,164,385,570,889,984,497,865,418,976,405,54,849,112,64,929,301,416,587,944,69,420,59,739,979,615,781,423,959,577,181,777,443,762,436,316,704,1,318,506,600,62,267,76,225,983,806,510,506", "17,984,668,675,115,549,144,182,638,29,430,428,15,991,371,769,59,577,123,734,846,901,498,541,966,319,768,211,445,714,21,638,268,257,476,597,112,980,711,998,208,243,289,400,937,249,714,494,909,312,653,173,532,6,203,97,504,470,307,420,392,38,122,446,783,877,336,642,367,330,574,45,570,744,539,146,651,615,347,932,947,226,656,993,302,433,582,812,199,519,410,655,406,703,459,759,172,200,261,20,662,419,210,285,221,285,586,971,798,146,80,670,618,577,956,806,46,855,631,845,142,304,747,63,428,634,167,925,829,720,814,264,167,580,726,163,648,116,721,823,402,568,396,574,566,681,440,780,385,325,903,251,546,86,389,710,360,168,899,101,694,624,422,445,859,143,836,421,337,67,925,658,124,974,52,584,116,296,957,721,181,774,828,46,189,903,382,523,756,361,547,931,64,456,562,361,716,469,864,727,838,784,135,143,343,401,362,518,450,340,772,935,224,205,776,620,380,831,765,930,647,463,328,67,908,930,851,432,995,202,629,955,39,339,313,834,83,53,191,69,642,194,966,571,603,359,226,572,908,823,243,16,779,680,550,827,641,242,946,383,337,603,588,670,144,473,154,921,762,347,177,183,897,44,261,178,653,437,248,60,957,911,595,247,731,546,696,585,992,900,225,109,432,449,483,460,523,204,166,229,406,337,668,633,524,778,115,92,137,708,316,5,988,571,497,75,560,515,674,755,971,415,378,903,414,436,302,890,17,738,38,643,150,781,302,71,649,268,158,700,122,902,929,510,125,298,595,234,619,929,95,890,848,746,912,35,522,773,372,107,602,471,665,476,119,157,102,19,120,714,834,595,685,670,149,238,223,639,316,439,389,92,727,657,544,555,48,17,443,17,376,530,642,877,553,348,942,657,702,818,978,916,444,242,27,883,615,275,475,515,470,595,561,163,579,796,486,116,311,342,628,322,858,313,405,61,674,519,864,469,977,773,224,686,765,869,731,447,147,502,980,331,701,127,344,173,243,917,4,829,610,189,432,343,77,157,251,720,634,106,253,438,665,499,634,183,899,890,90,185,186,634,241,791,898,174,883,412,21,168,77,346,941,188,535,271,861,368,980,406,189,855,594,7,296,743,910,74,908,799,54,229,931,394,376,31,444,577,297,823,596,976,346,232,896,834,255,5,844,29,359,19,450,297,517,684,24,229,129,568,234,852,142,271,169,627,788,990,400,913,275,698,801,828,541,354,544,499,188,224,911,969,736,483,846,926,902,920,533,341,953,972,777,159,592,72,381,192,950,134,806,697,708,399,929,974,60,275,431,323,34,369,874,245,323,656,975,616,806,910,533,543,853,740,183,727,313,906,889,470,526,210,919,938,248,121,310,230,263,63,146,203,854,236,154,446,85,220,205,580,505,951,139,257,573,579,345,364,281,513,331,665,879,144,149,627,878,510,631,739,181,799,145,252,354,696,379,193,553,315,866,827,838,463,301,590,769,490,930,419,272,306,293,842,396,844,140,601,999,677,221,68,64,152,973,286,815,732,998,975,320,765,478,822,116,6,560,668,107,551,293,463,899,67,454,423,782,520,920,402,607,15,193,346,57,142,808,691,499,980,478,120,301,700,504,473,451,745,752,410,311,949,478,610,420,173,603,920,604,419,670,109,293,901,30,80,841,559,126,140,425,945,5,945,324,848,687,421,677,876,711,30,556,3,361,275,449,978,427,836,840,43,166,598,396,363,736,307,567,931,965,585,801,589,426,765,578,228,995,721,410,399,216,435,852,578,847,613,197,658,727,755,70,579,730,523,426,977,200,407,318,149,455,379,301,726,613,188,532,33,206,466,87,872,371,184,752,735,850,321,750,545,201,560,652,358,319,370,522,829,975,68,132,536,956,647,801,844,501,146,349,33,176,684,319,192,917,512,955,850,15,148,177,863,95,661,55,913,803,775,921,384,468,408,1000,727,910,20,857,473,342,533,800,231,369,141,107,31,163,251,233,796,827,489,434,601,767,323,229,269,190,173,852,353,114,252,168,0,249,4,826,144,428,435,309,234,100,647,730,950,297,581,80,367,55,126,221,369,125,896,98,334,501,690,847,990,936,953,253,408,657,68,669,267,182,710,794,562,199,24,582,328,502,980,477,137,637,681,708,160,982,577,997,107,980,773,494,68,360,649,769,276,948,159,610,880,739,859,915,891,770,35,501,589,531,994,311,719,304,585,291,330,287,833,857,256,129,740,532,361,608,809,475,386,653,838,123,505,231,997", "190,96,888,855,941,15,272,852,464,632,856,883,791,862,740,886,747,807,795,858,196,302,81,382,242,710,723,775,783,884,874,853,557,503,769,529,897,757,498,581,101,884,343,613,474,328,409,937,793,404,33,700,884,618,846,843,862,427,288,614,269,956,884,15,382,442,878,929,772,414,492,814,448,237,132,357,201,452,954,45,190,754,5,449,51,283,667,270,120,338,59,400,486,447,683,720,179,385,549,221,668,300,4,435,148,17,603,948,101,478,302,732,299,662,597,607,342,992,329,446,667,182,252,39,141,27,866,720,671,279,684,123,769,582,887,487,118,884,142,346,345,380,906,737,648,752,228,233,158,443,768,647,388,279,718,454,931,541,194,570,433,944,380,636,507,390,38,820,864,159,867,335,994,354,289,221,30,357,55,26,681,855,851,193,97,615,865,864,473,801,741,538,583,240,890,820,302,465,565,542,724,664,541,507,417,308,4,226,648,954,340,447,572,490,692,173,437,934,82,538,816,89,50,452,777,464,38,194,946,616,923,550,795,275,261,253,1,534,998,410,250,646,221,680,87,714,332,246,365,167,618,521,160,791,559,70,406,362,681,669,867,576,758,633,645,475,464,3,571,530,867,605,312,194,809,414,995,313,225,357,97,778,193,722,598,536,263,196,205,414,278,976,694,900,205,576,181,6,456,377,811,95,786,431,70,344,547,70,264,99,654,462,802,925,902,790,586,315,891,563,119,20,343,16,758,56,491,957,758,865,116,746,653,158,274,583,229,476,211,439,224,801,386,443,350,217,284,400,535,20,424,777,500,959,625,172,912,68,677,842,728,58,956,828,207,824,11,898,192,873,237,276,890,276,891,576,450,673,107,647,640,785,358,571,30,878,247,529,650,391,739,548,157,888,578,394,902,148,789,468,169,449,952,484,471,210,559,864,421,421,623,898,526,368,359,562,637,146,676,690,639,811,540,80,802,754,69,638,696,462,419,771,744,435,905,792,818,164,232,94,585,909,384,368,889,415,538,305,89,717,578,890,593,427,463,726,249,800,237,752,443,382,789,471,531,158,132,972,887,698,116,611,43,331,97,705,528,833,560,750,405,61,348,887,246,28,703,752,835,39,304,721,937,658,289,29,412,696,490,808,855,803,8,188,587,243,856,249,785,393,296,389,760,380,858,50,380,918,894,350,688,979,82,405,966,249,250,523,370,612,107,708,283,640,408,523,480,55,781,515,727,431,258,909,268,347,944,849,332,856,810,826,449,377,328,766,344,834,765,167,780,786,975,973,362,238,75,807,213,267,183,233,284,115,969,834,365,696,534,781,127,272,105,939,185,23,460,863,220,480,664,719,393,631,39,109,618,811,153,790,455,37,34,689,49,852,382,581,848,265,773,125,742,141,28,392,23,485,745,930,75,200,931,142,999,398,468,297,443,906,190,201,813,172,821,608,832,208,858,427,135,367,367,260,152,676,74,304,774,993,190,463,291,852,272,513,244,201,835,564,805,102,302,381,778,260,605,347,869,356,742,694,312,167,861,772,722,559,429,376,638,25,853,44,135,818,958,913,304,301,210,659,993,130,735,346,582,615,207,896,489,385,51,767,325,688,286,13,958,391,943,158,79,870,724,702,74,346,340,681,311,762,176,283,257,768,576,912,229,801,931,176,35,287,764,64,689,572,686,463,850,407,433,504,400,951,354,503,538,569,330,113,220,633,104,874,647,185,88,460,527,530,996,180,805,952,965,16,210,949,3,363,856,527,616,362,785,523,728,838,469,638,976,273,838,270,158,239,464,298,114,477,125,979,78,240,253,244,143,586,710,617,73,395,867,177,289,924,427,599,553,913,24,660,213,939,350,807,983,191,611,957,981,730,503,28,54,50,946,814,137,916,484,592,884,133,97,371,403,645,567,287,253,351,316,384,780,106,25,60,185,915,428,868,2,895,605,537,759,463,78,887,572,968,19,943,635,531,903,129,796,906,361,498,709,102,142,657,73,184,411,323,5,692,201,176,445,69,229,897,281,501,941,951,485,507,166,249,0,95,420,149,772,403,930,420,872,976,256,78,200,813,675,893,245,619,131,595,335,875,340,824,621,628,377,10,992,243,835,223,672,272,981,594,793,92,446,714,852,633,258,262,569,344,484,826,629,747,697,351,662,629,166,485,452,815,652,433,501,799,552,795,34,339,268,533,147,802,249,130,334,203,373,679,7,459,141,321,487,934,310,452,716,630,997,556,91,111,43,166,683,923,528,523,907,276,261,79,458,201", "952,757,467,933,795,535,144,159,297,823,663,66,33,112,904,647,729,902,531,653,534,326,660,775,14,151,55,147,143,837,829,829,256,710,513,646,420,543,416,821,88,681,840,337,191,600,756,703,763,407,473,133,847,773,261,667,326,339,986,621,73,208,298,585,744,162,784,713,946,454,144,604,711,132,118,518,790,310,559,326,97,358,992,888,452,879,683,838,599,557,641,573,874,566,238,794,365,163,788,908,375,362,285,749,646,523,508,453,473,505,586,258,869,467,718,448,56,603,713,911,864,133,483,956,699,803,596,684,323,478,150,509,943,702,84,680,560,343,654,853,473,580,947,957,618,140,205,504,245,638,247,504,107,109,458,879,540,712,928,314,692,65,575,845,456,108,586,610,445,449,527,945,596,282,294,866,203,893,131,100,125,88,22,402,460,855,361,562,521,260,86,339,394,784,564,498,690,758,152,248,77,246,178,929,24,982,459,686,794,812,329,681,716,437,432,605,640,909,862,990,761,430,938,308,210,991,149,975,431,522,594,626,826,815,82,595,661,754,601,544,333,922,726,442,286,184,343,188,699,333,228,688,466,380,915,365,228,982,603,145,774,40,672,259,370,153,821,87,255,730,450,838,811,769,940,728,724,158,519,297,672,99,848,543,870,153,923,45,182,210,999,875,688,146,8,804,524,39,570,145,936,330,962,151,545,949,851,775,290,857,735,34,330,597,635,487,738,847,765,584,42,651,883,299,747,238,886,179,889,494,635,951,685,572,704,661,476,2,6,221,410,775,101,72,604,892,740,183,794,42,32,189,519,640,705,254,448,990,527,738,502,719,324,142,202,235,159,106,133,156,57,111,170,497,357,882,822,270,480,925,237,37,47,433,115,458,146,732,503,471,54,427,747,10,279,856,840,478,566,17,82,325,77,98,272,173,513,688,34,800,563,246,758,174,522,399,800,846,520,637,265,935,105,172,292,714,519,292,433,958,387,231,106,498,816,752,512,349,363,303,831,875,271,744,392,685,372,162,291,285,553,320,821,627,328,350,162,514,929,676,129,104,799,161,645,246,745,190,341,122,628,572,587,188,457,790,680,565,548,417,411,381,542,809,949,800,613,600,626,93,49,12,572,837,524,433,72,435,998,362,715,46,975,365,365,727,300,651,494,292,659,787,548,846,110,835,795,543,129,884,314,859,718,463,710,183,387,8,372,206,76,23,808,953,716,721,104,734,724,579,921,79,157,377,179,72,544,64,843,245,960,974,488,522,749,945,937,879,969,894,868,984,465,76,622,949,389,185,476,149,29,38,665,503,950,692,67,521,579,632,370,170,533,886,319,305,202,349,4,180,312,760,761,874,144,501,252,527,742,67,813,161,657,670,987,435,731,530,34,314,744,534,655,110,232,666,666,238,628,81,796,619,238,840,390,109,896,913,273,553,447,538,610,827,371,876,431,153,333,525,800,359,352,372,907,279,979,669,238,696,841,912,724,57,860,866,443,224,19,408,340,471,798,734,586,560,669,542,283,659,401,722,20,65,392,198,500,379,90,870,838,182,477,242,309,105,533,323,740,661,795,309,208,809,376,450,930,901,23,311,519,634,884,799,296,759,246,639,482,763,93,783,29,55,454,855,217,526,312,234,652,798,403,362,992,918,210,225,556,339,29,78,899,971,252,670,777,586,869,421,354,822,196,755,180,333,48,238,569,531,103,746,791,570,55,253,404,991,634,869,849,872,311,463,263,73,845,155,156,499,215,734,682,660,771,166,734,202,459,757,233,368,929,402,552,25,202,229,556,850,429,723,64,356,466,432,684,760,176,419,721,511,626,757,618,275,689,717,65,2,60,942,267,441,951,103,76,170,477,543,629,394,318,508,116,81,133,49,613,531,454,529,663,904,703,506,642,691,761,241,639,68,69,989,190,925,966,247,15,243,844,900,107,871,274,821,769,149,525,856,830,488,759,621,429,432,731,209,170,54,925,655,719,703,837,123,777,211,792,265,76,704,349,552,45,956,663,774,398,696,388,691,905,33,773,717,146,4,95,0,868,155,573,250,220,658,776,127,589,841,405,191,477,356,175,23,459,643,627,787,573,166,925,348,777,936,590,963,198,875,619,875,531,258,180,715,581,831,598,288,921,17,245,453,443,700,17,926,640,966,826,358,822,16,566,372,332,33,285,813,413,410,678,237,957,972,171,448,838,638,13,339,837,557,377,477,570,322,931,811,961,198,191,127,638,57,745,454,947,969,610,232,608,440,788,822,682,684,616,605", "370,77,799,133,565,981,895,225,72,196,139,282,461,577,100,196,716,742,255,921,839,922,719,504,378,140,776,437,972,215,171,803,870,435,854,370,109,811,328,440,619,786,986,524,156,859,726,44,387,74,987,990,659,825,691,498,528,412,133,845,986,427,425,252,571,967,481,942,106,989,908,26,93,539,339,523,381,975,84,826,453,955,453,139,766,483,25,208,36,748,842,986,956,310,802,963,30,236,786,282,625,695,920,809,905,619,237,107,111,605,255,529,247,581,416,892,833,755,941,683,899,216,458,767,682,988,279,486,909,58,394,656,827,813,461,318,174,85,754,945,934,654,189,331,955,80,507,367,791,917,610,490,199,384,327,748,37,432,735,649,365,97,363,997,408,994,143,731,956,810,968,421,369,793,883,806,969,927,334,173,975,673,140,493,242,201,237,14,697,365,314,395,341,730,342,600,854,813,414,792,785,44,798,454,436,685,956,969,20,238,335,759,74,135,484,392,800,775,863,764,911,317,414,367,980,926,959,501,713,462,321,332,912,946,363,113,587,408,454,271,600,343,228,994,112,207,946,183,222,858,542,515,88,300,541,82,61,946,833,235,50,31,663,547,595,431,218,852,656,550,22,969,198,480,847,298,454,86,107,715,699,505,89,403,582,645,770,310,797,415,317,198,787,319,574,123,574,106,785,519,703,8,937,506,626,674,34,388,416,776,350,805,895,884,814,380,557,599,342,166,327,306,122,940,754,16,74,372,180,268,766,723,116,66,147,244,355,996,242,812,183,677,871,112,879,481,579,105,954,118,518,15,149,759,679,458,182,770,231,303,915,632,843,973,256,623,999,524,959,670,473,346,943,289,203,559,880,113,443,150,729,20,49,760,88,528,847,362,984,990,397,627,329,176,624,21,225,454,775,810,426,24,687,526,978,988,454,312,681,727,963,399,488,119,342,827,587,165,694,958,28,48,63,523,246,948,37,59,895,817,19,696,290,510,210,598,233,958,59,485,720,397,595,93,834,242,713,827,246,724,127,157,306,569,283,672,205,902,663,184,988,553,610,77,50,886,761,776,103,364,780,743,735,64,345,699,774,831,604,286,103,847,122,460,192,975,352,542,982,304,515,815,373,937,101,439,369,880,103,287,277,336,371,447,754,260,110,654,892,547,651,569,915,112,741,334,547,81,955,437,29,316,683,407,981,372,95,325,981,364,648,455,34,293,193,654,876,670,139,384,835,424,395,13,278,448,449,614,720,834,593,306,655,130,791,733,796,669,206,49,3,740,954,983,604,400,670,691,227,633,601,355,438,81,235,117,524,454,704,37,310,172,315,246,556,829,954,67,316,872,585,694,632,219,350,231,653,470,965,826,867,419,534,875,545,413,854,88,500,816,342,166,322,481,276,468,78,949,724,471,91,55,512,587,691,843,680,965,323,699,255,203,274,437,137,576,484,515,899,178,285,674,149,657,662,471,7,433,334,556,404,615,494,993,541,224,537,266,614,825,113,638,890,736,795,145,396,747,537,475,565,609,830,888,975,280,902,48,542,239,691,679,263,585,447,571,219,424,9,715,834,431,150,138,243,644,165,507,162,976,412,486,115,651,929,910,665,92,125,670,262,10,893,90,300,898,958,551,320,162,654,541,439,767,417,211,292,807,350,620,639,204,54,389,505,687,969,422,813,926,311,905,155,652,188,333,497,535,971,670,159,483,555,366,772,974,479,549,478,223,821,866,696,782,123,755,278,387,345,810,879,410,485,302,776,151,741,970,147,277,254,943,30,249,323,662,113,220,426,769,857,819,846,448,996,292,588,37,132,212,917,777,329,180,562,939,79,44,45,562,941,565,960,718,841,580,468,844,666,375,956,372,726,664,861,314,338,503,227,259,197,530,526,43,863,691,79,92,585,708,755,731,3,862,759,326,504,135,5,516,918,689,818,370,227,322,511,699,789,946,615,605,659,8,439,38,900,841,990,534,75,793,731,933,556,671,110,360,858,128,121,191,535,405,124,56,481,272,394,121,551,573,867,365,55,448,274,826,420,868,0,418,169,935,533,616,169,985,798,417,693,836,45,350,438,444,83,850,864,327,89,128,635,736,270,820,232,641,805,491,475,676,473,862,86,74,700,325,412,485,990,633,627,894,296,177,568,122,681,872,653,994,59,51,611,238,927,413,906,564,508,370,956,364,487,559,899,958,488,617,475,74,796,195,812,515,834,135,102,708,926,746,706,373,301,63,954,692,336,548,183,513,394,294,31,34,242,39,91,265", "464,843,429,489,101,21,336,774,375,477,334,832,487,958,25,838,825,823,235,868,524,371,154,787,135,522,767,691,428,975,609,482,340,24,331,432,217,348,491,952,557,649,399,858,344,980,980,524,463,951,357,724,69,252,825,33,985,235,830,237,98,745,312,172,527,111,603,827,464,854,690,570,209,169,778,637,229,822,626,340,784,66,133,325,344,125,808,662,461,989,378,457,729,577,296,698,328,368,136,893,298,312,643,220,699,666,379,70,607,151,252,519,814,558,161,662,238,738,12,998,639,158,468,585,711,369,683,691,99,960,994,495,862,98,135,500,926,497,22,961,944,96,831,842,790,922,948,49,779,73,890,494,26,179,478,25,585,316,134,198,858,937,212,787,172,368,185,741,728,178,301,346,302,959,198,596,179,760,67,306,823,477,852,981,335,534,931,454,601,601,973,367,98,935,511,608,973,760,418,922,253,720,477,480,206,798,941,666,871,478,3,378,612,856,116,396,565,638,387,209,232,455,960,35,528,846,8,721,722,444,146,976,583,366,401,16,453,907,339,488,457,629,338,362,945,157,172,67,239,990,528,993,964,609,956,941,666,728,521,80,599,93,99,595,468,716,494,472,214,98,969,985,729,535,672,680,918,133,361,895,594,486,601,599,518,711,399,325,707,913,601,773,129,343,950,990,192,894,943,846,196,888,947,833,434,204,415,336,688,647,910,266,826,511,972,487,678,231,691,249,4,835,462,429,461,525,942,792,467,39,150,276,282,469,314,462,381,112,476,544,297,808,952,367,248,213,36,894,690,549,509,642,868,895,117,63,452,873,178,437,418,450,794,183,731,387,291,340,748,358,830,157,367,157,974,853,546,303,299,707,433,823,763,627,266,376,91,38,368,247,586,123,387,123,733,485,872,328,236,206,638,889,104,82,432,550,674,225,818,976,226,458,307,133,592,661,510,85,26,462,210,793,683,942,575,971,833,651,755,848,481,180,325,314,448,103,171,277,374,253,633,243,31,397,114,682,218,185,410,234,766,380,647,189,511,722,853,107,175,181,78,562,948,983,822,577,560,858,585,449,401,31,594,572,165,737,672,754,431,872,649,963,707,29,524,188,60,181,18,564,268,693,915,439,242,27,459,327,463,706,29,657,539,168,823,55,892,141,816,356,430,700,871,511,124,292,634,723,709,131,959,221,226,316,403,304,141,928,575,76,656,756,179,571,713,593,593,920,366,311,579,377,633,840,984,124,848,354,949,571,644,913,165,91,297,390,451,272,460,298,229,986,323,824,395,714,99,235,828,184,610,532,293,748,125,247,237,879,869,279,36,713,580,281,388,200,890,797,620,485,205,702,963,299,505,181,290,774,535,382,530,822,694,81,10,80,725,429,16,86,896,545,505,559,818,518,493,631,577,451,90,738,208,890,437,198,245,782,778,271,277,555,99,50,604,83,287,337,752,735,921,49,955,957,668,10,172,366,67,73,769,897,789,780,957,109,359,572,677,413,475,461,816,749,528,711,533,877,149,77,51,121,940,527,94,872,898,639,56,636,870,593,488,27,816,221,640,582,527,420,169,543,882,390,432,894,721,120,433,179,834,298,125,903,614,737,687,771,690,26,176,123,352,488,994,524,215,508,24,538,136,610,788,116,318,845,566,323,604,680,372,740,944,443,694,997,536,240,259,455,480,743,717,969,567,439,609,361,817,69,162,301,113,725,793,928,527,937,374,233,827,369,829,161,857,853,362,491,761,667,646,809,849,401,90,492,35,698,556,38,729,907,442,380,506,414,171,524,329,21,745,268,522,65,510,204,851,335,221,869,789,745,114,77,559,486,246,261,467,255,843,549,863,507,377,701,463,302,283,409,356,184,894,316,196,425,772,24,291,315,198,637,684,117,193,466,934,454,380,321,255,38,887,102,111,822,39,905,239,78,397,569,295,797,902,767,192,397,824,8,863,615,10,70,224,290,684,609,340,781,749,649,808,773,136,546,979,870,8,337,407,321,239,377,394,209,295,600,755,301,877,423,909,208,464,101,757,144,149,155,418,0,366,546,781,537,563,98,505,537,286,86,444,933,896,55,590,517,302,621,280,410,972,800,799,76,114,271,651,922,771,722,936,724,450,216,938,598,249,583,562,972,513,357,777,164,841,297,38,275,801,13,578,603,857,981,469,585,547,951,504,557,483,326,427,903,881,649,426,125,476,482,689,963,736,149,526,874,521,465,517,946,942,641,318,974,622,225,385,765,625,177,665,78,409,79,918,167,496,463", "291,367,25,195,837,921,630,929,203,122,548,563,94,338,77,211,237,25,634,796,781,177,586,367,767,601,928,633,120,848,331,86,461,394,41,743,404,389,275,885,87,804,161,378,82,975,331,125,940,898,820,575,12,871,439,63,687,244,932,148,49,984,34,665,954,241,54,859,145,788,820,599,665,704,686,567,231,384,152,780,704,872,754,179,633,951,804,855,341,240,977,534,570,568,558,845,264,241,194,412,500,943,372,744,147,516,253,456,827,530,129,98,242,524,500,86,653,958,50,547,809,41,349,593,488,672,281,627,458,142,268,637,923,725,413,397,919,398,690,909,885,983,898,596,938,117,277,302,281,414,33,180,585,632,828,819,943,640,416,815,492,644,979,304,546,83,874,826,245,880,213,400,56,816,179,543,621,846,922,571,828,455,402,662,397,148,594,267,847,590,57,421,681,326,560,595,514,588,557,865,10,707,346,834,330,398,826,967,209,200,113,681,931,270,277,808,141,247,152,894,918,992,122,205,615,549,438,341,700,396,130,765,830,687,453,557,718,90,372,509,372,469,679,785,511,805,832,312,224,389,210,436,550,389,341,736,58,806,342,494,753,729,497,940,990,328,614,654,555,743,807,488,799,70,167,822,649,889,362,666,740,146,100,384,288,493,468,725,828,297,297,707,77,361,81,569,144,819,22,196,684,794,721,673,519,192,105,113,308,555,289,576,278,462,816,344,542,876,590,760,597,537,971,825,780,69,429,698,813,392,871,207,606,504,474,99,799,686,685,314,858,129,370,238,677,790,980,221,513,180,966,366,892,421,870,921,364,8,236,189,627,264,62,826,339,607,192,645,454,255,9,321,816,719,951,296,498,42,104,391,699,656,846,530,851,824,773,102,845,899,310,447,606,791,997,316,894,333,320,521,244,64,267,347,959,327,991,639,445,602,838,191,606,692,425,657,473,533,688,916,250,535,464,269,329,130,666,100,989,121,823,573,189,532,367,894,154,53,347,8,454,628,199,670,616,864,566,280,69,36,382,679,104,1000,920,670,351,761,471,613,714,798,187,693,916,63,23,211,380,416,797,330,900,485,148,143,832,738,390,839,499,639,564,248,917,323,883,394,918,927,237,822,134,257,523,211,335,804,358,388,202,313,608,347,555,821,88,734,893,721,761,763,399,781,678,66,296,803,92,272,509,585,614,760,628,742,532,545,783,744,343,477,490,821,595,543,549,986,183,278,38,959,314,797,583,321,356,500,580,164,154,129,204,318,642,395,904,175,118,711,773,181,879,957,797,180,94,294,343,586,164,866,81,866,116,373,257,129,788,933,293,296,26,962,943,141,793,46,924,633,980,623,9,56,549,526,588,70,1000,571,993,470,856,436,700,489,445,304,683,384,93,223,828,286,71,778,317,375,875,811,114,862,654,11,64,165,926,698,692,944,549,714,729,917,260,920,655,728,424,500,235,765,973,556,96,239,209,198,736,980,23,449,114,763,599,288,82,459,200,142,865,739,949,969,23,38,692,450,542,190,477,28,633,12,68,140,521,182,924,702,153,845,181,997,285,192,19,279,885,183,338,904,219,695,685,342,329,535,223,279,726,787,561,807,747,65,713,628,276,79,545,952,811,916,260,965,229,103,818,89,606,418,722,347,18,586,944,844,190,615,815,588,556,35,965,396,702,938,851,828,82,667,566,342,37,464,916,52,4,813,897,391,291,164,991,5,929,675,901,569,319,910,559,582,236,915,976,305,369,893,567,6,218,576,798,382,427,774,754,30,759,200,275,201,425,15,185,453,587,980,699,554,95,313,706,508,335,311,234,220,78,710,276,252,183,269,834,751,805,968,23,149,756,659,159,333,871,993,356,743,598,45,71,88,230,574,32,257,12,933,443,929,864,789,23,67,23,309,363,473,206,745,342,916,295,666,28,935,980,552,40,378,606,432,301,709,874,241,44,869,728,399,774,970,989,713,425,642,500,391,181,129,109,566,876,572,817,777,753,194,853,393,728,61,498,474,744,195,420,651,805,993,773,719,516,201,915,428,772,573,169,366,0,616,890,273,395,383,911,367,913,430,523,57,503,358,687,679,901,904,675,538,900,451,977,294,564,760,300,25,388,923,899,297,942,377,874,230,619,274,822,743,972,543,47,80,130,856,750,234,738,332,668,733,336,205,252,8,488,929,358,884,969,975,698,478,752,156,234,598,197,280,686,696,767,64,384,404,586,516,992,257,428,187,906,838,48,384,184,551,289,901,912,145,652,872,509,560,976,499", "918,32,817,268,655,188,716,482,869,35,278,204,376,19,458,867,555,826,454,469,282,510,967,950,483,241,609,49,599,159,828,523,947,935,401,805,639,291,719,110,413,565,615,27,625,975,4,828,388,857,205,189,995,809,599,138,138,180,640,943,843,899,819,728,113,324,878,631,209,509,820,566,314,720,441,644,303,525,591,106,713,628,806,510,454,899,146,443,877,129,19,943,788,248,314,163,388,168,748,779,886,168,703,268,337,569,948,464,395,380,561,894,637,63,664,949,338,994,680,982,129,430,385,404,499,350,80,239,896,942,530,626,786,213,451,627,245,850,52,116,778,336,368,900,557,34,304,521,52,975,261,328,632,421,942,379,672,943,150,722,136,889,717,68,684,177,569,965,744,99,249,345,180,894,659,909,763,298,702,452,49,231,119,579,83,310,351,640,857,133,552,782,678,506,174,873,814,381,38,256,571,490,69,852,654,565,417,129,327,55,822,168,977,671,853,702,246,994,957,802,225,97,278,232,284,670,705,490,285,854,795,803,837,675,543,10,821,142,60,693,98,264,982,476,579,656,441,354,651,457,465,235,341,751,178,916,982,841,766,120,706,844,64,743,334,979,747,254,955,852,395,238,70,900,721,601,121,362,443,999,629,161,76,950,993,964,607,954,830,334,407,845,791,529,954,211,486,746,821,490,965,202,78,754,632,953,844,364,939,914,210,441,557,718,178,65,542,828,260,260,200,737,308,992,597,237,38,280,691,248,145,482,325,788,522,745,63,576,628,133,733,498,871,956,987,847,580,922,416,562,412,370,901,611,427,277,59,81,338,719,972,591,128,446,869,499,739,364,595,165,552,560,44,689,389,745,913,431,851,257,617,676,684,101,156,636,465,588,144,627,746,356,445,772,668,343,801,84,5,379,884,625,153,101,590,819,781,524,732,51,514,963,280,73,104,324,808,415,957,476,777,463,296,423,821,431,340,532,735,741,745,417,607,784,845,568,981,952,952,855,582,81,990,740,373,184,533,790,422,919,303,38,614,597,235,377,713,690,587,929,579,376,222,332,241,638,878,994,519,664,233,313,592,396,625,849,13,661,300,134,850,767,751,170,977,557,899,608,362,71,520,298,389,409,572,135,601,179,178,33,150,923,846,434,59,148,515,851,845,591,843,1000,12,982,161,742,94,894,578,568,993,521,311,999,236,255,659,522,101,361,102,402,614,975,806,184,170,506,564,222,577,90,874,371,249,975,332,936,770,659,427,673,379,249,950,430,550,336,970,363,390,778,411,289,72,745,368,267,206,400,250,957,448,395,877,357,399,806,494,865,353,179,843,7,701,540,470,343,80,276,628,733,417,494,28,696,325,528,822,359,517,171,630,694,516,544,172,937,251,614,964,317,864,718,589,218,676,220,99,532,125,627,400,255,516,26,300,821,51,754,107,607,310,830,454,788,909,781,1,123,923,348,974,369,909,555,570,6,499,32,350,508,517,169,900,525,699,855,239,936,513,42,161,154,809,650,602,240,599,619,482,782,633,401,521,312,913,584,560,143,65,868,502,654,470,4,297,331,934,260,556,315,193,558,768,286,405,218,299,519,85,759,389,692,983,925,750,977,648,665,677,397,654,456,508,718,457,912,152,940,595,875,850,61,743,929,809,298,42,785,984,181,882,688,614,672,694,655,800,878,549,805,26,575,485,865,340,819,156,625,39,740,630,422,836,312,387,941,734,902,585,330,648,787,519,117,349,154,295,176,477,806,88,624,447,737,249,863,12,523,708,784,606,90,93,876,909,221,522,126,241,312,399,209,54,722,692,891,627,506,774,638,273,495,842,953,27,967,349,760,675,624,393,882,401,799,318,905,342,418,467,204,723,6,407,388,212,195,538,280,651,152,378,375,78,54,533,324,761,611,643,379,335,966,311,347,786,457,193,636,103,329,21,833,64,423,440,386,972,807,746,305,500,230,14,468,36,308,898,857,419,767,372,156,604,765,835,868,729,767,995,358,696,618,768,724,693,524,799,429,913,959,585,265,685,917,792,435,403,250,935,546,616,0,954,20,404,546,907,71,709,532,95,717,986,622,534,806,601,491,520,980,788,625,156,804,264,129,183,371,221,920,749,221,671,70,254,465,757,571,391,739,223,278,171,111,262,574,656,552,821,963,971,655,142,661,943,538,380,284,343,350,435,694,677,319,256,291,397,163,515,104,56,741,20,490,386,517,910,528,40,295,861,19,906,674,751,4,743,317,956,984,124,785,284,186,560,680,208,862", "454,840,322,776,613,345,119,146,838,504,401,155,402,132,31,370,873,920,374,602,632,718,120,128,612,74,543,407,789,298,325,26,165,321,98,973,306,730,281,188,52,470,795,765,489,686,429,78,590,831,431,74,371,451,691,831,708,270,916,207,84,138,785,64,409,922,77,942,686,904,278,240,868,20,716,842,445,173,940,213,188,688,396,302,819,60,321,545,834,781,401,734,392,415,869,665,694,400,185,187,608,487,359,131,564,54,675,497,665,696,52,591,686,985,412,29,264,219,639,99,714,397,61,285,246,358,14,899,572,59,980,154,628,789,46,140,750,795,278,234,668,711,28,433,442,402,364,130,202,558,388,280,772,194,502,22,144,155,563,513,111,850,925,928,622,848,424,898,495,84,768,939,655,23,951,541,272,973,409,981,337,854,776,556,413,426,7,561,416,417,245,439,879,683,494,806,700,7,217,34,980,284,529,283,235,733,269,732,585,111,152,762,658,839,585,906,428,914,78,660,537,913,918,99,775,39,286,607,559,850,120,801,338,837,122,289,779,441,525,314,884,219,947,860,134,600,177,322,186,589,194,623,606,147,321,464,221,67,424,259,540,805,91,575,606,754,822,556,66,655,150,615,37,191,926,661,580,965,800,13,377,153,993,625,492,13,896,736,678,867,884,753,975,148,75,894,715,201,408,950,425,193,431,139,824,495,368,663,89,952,987,766,150,413,158,224,996,606,47,888,398,674,2,516,961,905,331,365,412,238,115,530,212,252,513,189,697,452,922,716,49,847,243,148,19,54,556,806,725,687,980,673,359,949,191,65,522,653,905,806,320,153,264,531,581,522,340,422,607,686,257,706,76,440,305,995,438,605,995,260,515,180,896,15,232,811,664,322,822,453,323,372,371,684,631,616,414,197,470,635,193,465,765,118,330,726,395,689,785,454,510,706,227,930,116,524,906,335,389,585,859,790,430,663,516,177,737,418,899,780,815,641,910,932,297,403,251,954,214,576,57,758,938,502,911,487,265,836,868,606,266,527,570,359,580,590,633,20,739,962,11,214,185,999,441,712,164,659,900,56,536,538,856,992,485,308,713,807,210,952,333,846,347,765,718,12,6,181,589,657,135,636,977,648,257,907,913,165,638,539,244,127,206,265,946,721,268,16,449,391,898,842,551,560,248,467,44,495,919,812,279,742,239,697,205,209,281,554,921,528,530,970,834,326,274,17,958,259,355,908,945,469,803,715,558,106,178,329,993,119,672,693,598,130,169,52,105,499,21,968,790,997,480,941,161,429,667,888,595,515,671,40,11,953,387,291,28,980,142,764,537,895,690,894,474,188,828,150,100,617,705,598,391,431,879,446,465,268,344,232,7,223,645,455,942,620,144,122,832,155,381,913,427,130,416,963,465,654,989,514,4,421,22,826,858,729,752,159,173,910,4,393,998,151,912,927,415,909,302,425,923,30,64,70,335,52,72,983,589,641,553,646,865,872,649,986,450,419,780,32,231,779,484,414,167,626,871,850,897,133,963,721,520,113,312,988,460,90,20,34,299,485,143,605,421,674,252,758,461,991,183,276,300,662,713,351,684,895,616,227,111,474,921,282,741,669,667,941,408,451,757,942,950,685,329,412,649,651,983,848,547,69,849,486,188,783,716,71,365,922,691,76,758,348,85,269,125,304,241,532,423,757,535,333,355,415,130,949,739,714,360,767,664,263,72,38,574,727,141,881,427,256,158,88,706,26,548,236,857,420,506,893,645,54,803,587,140,394,657,338,113,198,455,722,30,377,658,582,270,293,4,726,738,354,965,439,964,383,674,830,846,452,569,178,430,125,979,23,221,169,57,609,422,29,221,192,470,472,797,266,318,671,844,853,272,401,871,388,703,275,91,496,183,775,526,475,761,343,645,453,835,965,232,585,220,942,53,826,972,988,672,110,645,945,299,727,966,717,503,372,286,969,212,617,588,185,520,93,323,299,36,812,691,172,155,486,838,606,310,541,24,753,959,198,409,732,371,321,594,477,388,160,6,646,503,909,406,309,930,220,533,781,890,954,0,847,830,126,428,348,925,744,376,124,847,139,367,859,963,281,170,14,892,560,82,521,255,304,827,809,840,251,313,646,245,592,327,675,49,251,736,291,684,185,928,530,890,783,288,994,414,974,171,512,225,182,700,849,732,223,132,614,567,721,45,148,958,130,642,51,819,460,254,366,909,691,895,862,802,167,23,381,845,729,563,776,890,389,39,71,975,61,732,277,301,265,447,739,675,406", "239,777,339,634,991,152,529,103,115,698,840,662,68,554,211,318,723,445,737,735,431,347,260,990,372,426,175,716,271,662,635,856,49,742,707,796,202,999,556,661,542,130,640,702,173,920,773,541,360,30,717,6,783,877,127,625,365,163,303,656,181,876,960,719,209,453,198,484,779,207,804,572,225,196,788,659,526,461,462,170,78,973,398,545,376,729,254,85,353,239,144,111,116,860,277,503,836,905,19,38,964,576,321,32,186,996,63,701,821,195,302,681,965,170,353,25,867,260,605,627,103,678,628,429,741,623,739,353,665,451,268,66,987,978,535,858,970,901,969,682,943,580,833,338,603,845,317,804,599,823,433,37,349,629,668,210,827,245,930,148,426,468,818,439,868,156,401,823,745,982,646,563,65,988,871,260,151,828,29,996,195,713,982,935,279,628,879,984,4,47,924,437,742,863,485,879,48,890,471,948,823,311,233,781,525,15,369,404,381,582,60,600,648,491,416,945,259,670,466,372,188,187,839,610,837,24,21,593,637,296,637,372,301,491,830,461,483,264,896,2,475,439,502,299,464,889,123,324,368,272,755,619,700,173,466,842,503,685,353,838,348,358,193,561,500,686,407,44,878,504,419,351,632,12,76,369,643,709,630,390,928,215,700,355,891,776,826,269,92,438,159,374,918,578,19,594,672,180,960,374,885,820,951,847,642,780,146,259,198,560,597,428,994,269,974,438,540,673,244,736,755,35,339,453,273,78,522,350,161,834,348,854,211,33,676,962,888,248,492,932,70,868,545,309,556,982,995,985,501,998,999,595,122,108,355,697,223,138,131,517,895,469,937,758,443,664,709,698,930,126,801,571,930,654,861,694,267,879,760,525,368,789,687,682,405,108,916,964,488,409,400,503,39,759,29,153,483,366,605,229,203,893,791,311,851,411,267,304,652,583,39,996,627,536,879,904,656,778,594,469,986,944,200,268,77,513,911,248,535,469,228,812,906,959,503,80,628,252,541,666,185,461,102,290,905,853,953,201,203,875,507,83,632,441,274,164,3,114,956,672,180,837,350,219,288,587,639,831,266,905,862,825,153,952,659,661,528,328,69,173,56,811,549,148,569,995,483,483,944,866,693,739,928,133,297,516,618,191,326,608,985,186,71,340,895,620,12,620,228,868,978,737,876,454,985,870,612,928,206,685,937,866,598,242,714,299,253,219,732,134,563,986,233,695,37,739,157,196,998,471,420,620,611,40,704,145,730,567,974,498,332,711,162,585,503,164,493,321,88,796,9,676,931,130,481,338,235,499,943,324,566,795,201,376,215,297,630,110,862,896,789,901,906,206,845,550,272,595,349,531,36,361,6,785,748,920,985,873,217,514,465,362,276,990,102,648,670,802,215,217,757,938,258,233,138,566,919,782,535,245,326,386,315,333,289,802,580,463,198,992,984,142,913,298,501,511,957,642,752,690,433,416,979,230,548,989,111,897,553,923,417,51,999,865,52,296,224,32,462,912,94,410,7,687,300,558,147,127,226,185,765,861,938,519,232,150,63,837,984,935,306,524,977,661,262,347,111,659,362,281,61,81,23,787,32,503,995,922,954,635,537,530,195,585,730,393,798,650,823,809,366,326,899,960,803,568,647,277,435,243,598,523,248,240,166,921,293,838,123,337,3,411,228,684,457,124,550,296,392,425,752,909,178,910,350,504,608,540,57,735,914,683,943,154,190,329,68,703,727,126,352,871,118,679,863,532,999,837,200,546,598,133,118,74,802,487,238,31,705,521,890,538,246,995,716,375,237,916,508,765,189,880,756,890,6,212,71,913,990,309,165,587,745,157,151,914,751,279,143,291,617,526,760,466,804,722,455,847,782,640,310,955,90,112,613,293,894,695,299,360,569,153,838,827,778,251,968,728,941,866,16,254,308,63,746,118,448,65,514,233,630,525,831,288,547,184,26,397,445,294,388,280,757,749,248,308,387,169,123,537,658,624,110,960,181,383,777,5,164,621,122,513,910,996,143,732,183,131,880,721,69,321,995,857,538,673,48,234,420,658,616,537,273,20,847,0,421,977,485,367,369,78,956,617,797,116,719,496,527,915,20,911,440,521,876,742,359,609,748,343,752,879,379,854,261,820,37,318,167,771,746,514,429,241,654,366,812,827,231,83,888,105,574,703,432,220,635,929,695,955,47,336,65,408,147,933,803,31,583,592,798,912,288,2,668,729,600,319,426,639,182,536,310,686,298,50,925,270,184,437,710,541,485,471,439,200,197,545,144,232", "399,640,141,871,940,612,869,346,343,724,641,450,678,279,694,460,962,927,322,178,100,235,162,209,827,295,265,49,626,273,567,8,298,978,844,224,801,767,222,388,991,94,821,96,351,434,30,982,736,847,949,899,527,925,146,275,455,20,536,748,401,427,205,576,219,150,779,970,86,592,886,847,916,756,967,275,118,593,57,320,370,299,998,3,449,85,349,406,384,861,327,624,165,656,190,941,173,330,804,605,97,796,852,849,299,685,389,817,436,874,716,795,562,312,324,107,699,991,109,745,699,235,801,795,919,339,47,138,713,708,194,673,24,437,787,599,134,869,980,892,141,432,32,997,351,573,775,98,629,464,284,699,232,892,868,522,533,975,913,780,33,348,615,227,194,588,943,127,396,739,860,870,382,24,759,622,958,481,611,123,76,353,314,149,719,170,981,285,338,567,31,278,73,894,551,594,456,781,713,866,854,610,543,883,968,584,957,499,36,295,204,670,53,155,481,546,951,828,743,612,83,407,463,322,466,983,604,395,182,802,583,938,87,336,670,731,347,698,160,60,925,784,604,798,80,316,376,486,717,664,64,552,931,538,267,443,311,648,593,112,873,256,711,791,62,439,69,501,728,579,290,421,297,128,614,8,949,840,796,849,16,833,790,175,944,586,322,436,767,196,902,53,721,250,285,594,750,788,662,315,771,214,249,885,256,837,850,981,134,723,555,171,427,988,63,806,112,36,462,813,293,16,222,914,483,777,730,896,727,963,471,106,722,489,135,159,40,601,579,65,733,72,30,89,683,513,454,385,735,250,305,481,579,446,416,824,207,837,847,984,399,465,264,568,136,665,801,836,122,560,920,857,432,337,156,146,143,447,33,689,22,50,801,46,774,914,56,886,567,62,413,193,64,658,878,257,725,184,911,896,274,895,44,478,187,918,844,862,133,70,754,729,953,289,190,227,944,867,959,155,630,458,856,995,970,76,280,907,148,221,776,591,695,870,621,435,703,582,622,616,723,157,86,227,198,258,969,494,512,822,153,274,420,673,235,885,995,670,614,310,777,74,890,746,831,254,623,32,105,225,364,595,34,184,111,671,958,239,581,770,610,487,107,810,493,303,710,143,790,196,396,874,317,784,326,8,642,588,438,735,324,94,316,472,249,126,72,762,163,51,649,610,756,99,200,289,347,760,81,112,750,708,719,632,964,103,517,109,951,591,763,807,714,612,930,316,560,29,916,630,439,774,82,73,989,135,73,825,584,7,275,584,116,94,777,576,304,615,484,201,941,564,808,109,486,317,933,533,284,848,649,686,343,206,402,713,311,444,139,440,647,420,648,913,887,897,311,359,585,463,561,330,962,134,511,163,311,377,630,177,743,361,511,915,125,629,274,819,755,795,491,950,496,105,972,102,412,740,527,573,491,521,555,844,7,88,901,927,342,776,275,767,647,187,169,379,68,190,131,219,680,910,895,350,123,504,526,919,503,206,515,928,227,528,197,638,582,313,658,440,673,285,508,543,943,771,776,10,257,288,286,660,83,981,478,593,225,35,955,724,66,90,654,287,737,902,492,495,622,742,133,741,164,619,753,893,957,58,422,535,91,879,774,946,342,792,209,196,217,448,315,246,112,577,490,227,126,722,206,187,972,672,643,787,571,874,278,105,3,892,87,549,755,247,894,401,903,389,454,504,480,850,727,53,167,56,332,164,349,75,788,512,208,487,250,709,602,937,388,358,196,938,870,86,700,961,574,733,631,140,804,522,420,524,240,777,245,560,950,601,87,685,51,427,902,766,348,413,668,769,646,114,860,384,788,167,659,776,18,556,770,394,61,103,261,632,291,413,404,38,835,134,166,633,819,471,230,410,523,804,852,665,589,896,499,720,589,437,751,198,910,605,757,366,493,629,740,472,816,452,508,807,859,949,625,251,390,419,512,731,360,250,588,397,521,335,203,370,627,35,397,966,347,32,997,640,927,927,561,362,318,648,318,338,46,709,849,920,770,711,49,538,388,548,313,145,881,921,436,424,984,714,395,643,846,586,897,100,872,776,169,563,395,404,830,421,0,29,267,367,973,765,113,831,791,155,261,243,332,1000,845,372,748,968,708,377,1000,280,151,895,152,101,190,581,857,153,810,966,664,974,706,494,767,980,811,327,16,192,510,209,42,55,769,571,917,666,388,777,97,126,403,440,340,644,985,682,834,586,717,701,617,339,190,589,302,35,334,636,134,354,474,928,70,317,639,376,402,238,867,857,957,406,649,870,421,984,872,259,455,3", "914,38,662,454,305,888,350,260,492,445,195,248,199,710,881,593,365,381,285,595,825,322,550,857,224,371,754,387,253,314,611,819,731,880,215,527,835,201,805,650,352,611,985,696,244,538,157,949,877,776,449,292,846,523,414,49,912,363,914,329,567,22,127,663,920,56,978,904,795,499,706,321,736,175,373,31,632,891,47,345,2,121,238,567,935,31,644,197,546,146,932,311,90,865,95,763,448,372,550,657,772,730,124,733,409,383,734,440,679,409,578,295,813,965,50,863,358,14,862,228,332,950,146,38,702,490,296,475,119,329,158,52,860,107,172,51,856,423,693,884,109,716,526,178,691,557,175,629,236,623,937,985,807,544,113,363,807,893,906,366,12,442,130,456,333,757,223,983,527,893,503,904,864,353,715,413,455,595,714,382,991,510,864,158,44,5,964,669,587,123,861,701,615,877,806,497,257,366,789,913,853,307,533,416,556,425,903,506,324,219,873,696,734,977,758,88,758,381,175,951,159,819,658,338,722,672,144,290,670,744,755,7,852,568,216,768,134,909,478,885,214,819,385,137,577,232,547,877,535,465,911,112,925,61,663,699,81,66,772,804,538,637,611,916,190,408,86,432,39,657,259,843,643,955,158,259,562,784,311,681,518,309,67,720,356,492,601,229,720,667,332,368,291,340,249,257,185,510,767,682,451,92,36,383,706,278,138,582,975,171,952,450,775,227,949,379,222,881,168,893,962,970,555,918,354,559,919,849,218,847,441,829,895,816,512,483,855,590,226,596,933,199,387,816,928,25,60,240,33,822,650,834,440,994,183,569,857,510,758,376,638,183,617,254,265,365,657,890,717,824,736,878,666,519,215,963,892,496,509,950,456,450,270,845,686,966,72,332,2,636,901,914,36,424,510,465,701,210,837,387,877,688,682,153,417,191,7,251,582,296,222,69,567,559,863,198,99,262,447,890,135,446,123,469,376,894,436,863,582,325,802,278,157,869,596,478,995,927,521,556,609,989,891,981,792,972,386,249,159,222,70,361,858,934,587,195,461,169,835,253,395,820,654,422,422,831,433,801,567,115,854,989,599,343,422,227,472,106,313,841,333,248,153,522,650,301,251,821,44,888,402,180,919,954,861,182,618,662,931,993,672,300,518,924,22,774,596,585,441,723,971,69,194,654,369,837,111,262,909,518,544,168,165,530,59,366,675,908,484,810,534,205,482,753,190,546,518,914,365,695,475,628,384,809,888,578,923,721,762,276,845,937,862,231,308,11,73,443,355,890,538,643,328,374,138,890,318,936,607,201,414,606,459,770,363,355,322,359,915,716,116,500,434,668,759,434,55,545,841,523,302,662,583,519,554,909,918,435,271,558,484,451,897,37,774,453,489,300,682,9,558,79,137,146,588,738,350,211,367,614,413,948,787,644,496,108,81,401,980,373,919,594,231,280,420,241,223,478,231,391,506,956,811,738,103,518,565,870,412,827,38,91,695,888,563,643,718,100,155,140,415,626,341,945,615,376,785,490,316,796,643,330,736,603,738,603,983,849,530,845,576,75,181,155,206,260,866,745,164,940,719,478,290,875,108,592,261,1,591,194,93,433,201,35,957,576,982,643,94,490,503,45,913,649,299,503,378,867,790,329,969,568,430,208,56,177,429,520,644,510,288,832,342,742,874,654,520,480,107,897,213,458,396,379,590,973,779,409,941,461,757,831,743,850,774,99,334,368,191,773,404,124,523,890,853,718,407,913,792,263,840,389,481,764,375,408,819,121,201,907,758,394,376,444,611,8,610,836,138,877,56,36,573,825,774,466,588,586,504,472,331,264,542,947,945,119,534,615,328,35,187,590,567,641,324,957,553,675,48,969,807,480,483,359,182,224,360,24,681,203,902,509,523,790,485,580,307,731,998,574,234,435,205,876,777,128,935,822,984,556,733,566,787,916,133,230,30,830,497,463,871,93,181,783,273,976,540,35,164,748,682,914,682,675,221,575,418,625,200,522,481,788,187,778,822,470,608,791,321,749,447,918,313,832,182,919,584,647,976,127,985,98,383,546,126,977,29,0,625,132,571,839,58,773,586,583,928,218,283,458,694,382,497,542,35,895,570,594,145,395,791,687,552,11,491,146,941,165,355,924,659,658,522,312,980,112,281,495,331,641,257,953,684,395,759,172,384,473,1000,897,140,992,88,862,773,913,93,761,900,338,829,672,872,426,607,539,225,95,10,193,829,757,842,409,204,400,400,436,550,955,89,403,605,234,419,613,993,942,689,780", "451,541,560,976,438,224,462,114,122,628,596,775,26,565,220,874,273,970,75,41,988,874,493,427,967,474,856,220,170,909,988,995,970,663,909,343,942,872,994,197,91,746,465,801,445,465,996,618,542,340,713,679,52,27,862,11,461,166,953,189,338,488,600,364,375,821,229,325,375,885,783,708,283,856,776,889,277,698,163,962,608,50,627,625,4,79,797,799,279,97,17,947,856,402,169,957,492,177,25,945,462,967,427,655,959,142,299,582,101,570,120,171,507,439,591,958,259,412,463,97,730,675,874,605,518,99,530,96,436,589,411,934,327,468,475,755,671,838,112,193,83,242,175,614,685,236,208,599,678,299,633,952,508,584,550,954,148,411,869,512,614,33,435,398,545,363,363,170,105,144,195,112,556,981,220,759,136,114,984,422,640,991,841,86,404,239,557,105,240,374,476,838,240,680,81,724,370,567,365,484,20,372,494,942,448,279,218,210,650,594,983,180,654,408,867,437,424,183,641,121,445,581,464,723,171,224,175,978,874,495,542,555,251,819,623,848,76,444,110,640,382,803,829,810,359,186,82,441,746,487,983,271,892,723,126,955,531,400,461,650,634,435,485,645,161,959,866,714,681,554,884,207,106,271,757,443,152,258,761,113,751,6,426,821,473,150,651,961,418,37,466,994,885,120,950,661,570,509,384,327,532,11,572,313,671,450,754,597,845,292,256,90,500,226,588,756,388,464,446,656,65,45,637,772,905,247,489,190,486,497,797,555,400,235,561,834,18,749,189,767,993,153,880,164,32,782,147,616,275,994,942,934,754,671,49,478,784,865,506,36,107,552,575,381,302,774,327,69,742,498,309,96,956,923,882,490,199,784,558,933,821,562,91,554,871,373,282,725,355,974,785,719,202,225,968,615,892,600,850,780,237,26,805,196,367,336,980,837,948,382,963,621,916,224,441,335,743,477,996,247,653,51,631,60,466,600,636,257,332,147,872,174,831,243,749,493,516,832,881,272,27,193,873,57,952,554,64,449,227,676,664,783,775,78,736,925,159,574,558,255,522,890,198,522,427,562,663,630,726,512,888,118,211,653,191,576,346,380,783,554,714,866,928,989,215,182,363,752,541,213,402,851,874,883,501,955,824,32,685,666,800,888,920,634,815,536,394,325,948,242,33,312,340,317,911,914,572,712,734,909,480,339,312,826,985,866,967,418,623,587,68,98,427,815,258,460,215,371,736,299,790,634,553,886,804,739,849,350,793,725,360,855,335,837,986,419,340,258,585,504,491,902,948,71,795,303,802,273,917,974,305,168,541,571,563,276,313,903,160,557,609,540,188,691,341,560,837,600,833,652,82,516,644,992,585,350,148,596,131,483,111,975,723,771,833,912,812,510,279,640,239,511,536,452,708,380,753,290,304,683,118,395,336,900,864,238,892,976,721,616,466,820,328,957,444,411,140,149,129,703,687,724,499,439,410,790,861,236,913,527,893,558,204,304,765,302,230,790,604,666,69,413,201,725,925,186,296,751,295,767,524,243,398,3,879,459,647,157,611,677,366,805,190,38,738,298,638,889,740,616,223,649,916,119,308,109,745,706,185,659,219,658,156,885,800,449,930,794,76,711,50,418,916,655,544,622,760,863,950,154,674,640,816,909,598,442,517,8,139,595,471,305,120,949,980,982,159,228,357,629,517,129,617,114,843,502,379,646,764,579,596,300,540,946,950,611,925,16,796,566,83,775,754,160,968,430,311,720,619,387,564,252,758,170,142,750,454,151,453,312,974,944,22,680,291,500,738,602,873,176,731,58,985,600,63,129,689,223,778,979,304,504,56,713,380,35,260,504,630,705,411,916,131,894,900,697,418,381,987,560,695,534,171,959,866,532,633,541,973,373,272,986,344,109,811,683,123,882,137,239,541,126,306,941,108,512,748,341,959,367,848,925,93,292,821,514,686,940,651,94,429,602,457,956,812,123,270,633,893,780,309,378,959,482,998,108,232,241,346,769,960,536,208,368,79,331,376,854,762,746,947,454,159,856,107,27,770,730,256,589,798,505,911,907,428,485,267,625,0,945,857,21,829,917,158,23,213,384,312,400,128,572,182,522,259,606,267,6,358,479,742,782,729,714,268,307,165,300,118,366,875,796,204,185,257,484,323,992,121,853,944,853,810,477,174,797,674,554,317,817,489,7,534,983,308,755,745,161,963,732,675,353,361,930,506,97,327,666,798,606,667,341,271,566,994,498,917,29,268,514,367,569,271,209,271,90,93,56,417,625", "281,59,647,605,9,529,867,131,14,746,242,649,560,339,215,253,890,907,415,76,928,775,388,649,151,674,883,855,551,767,661,463,533,33,639,621,369,857,123,453,746,558,232,917,895,727,717,381,431,528,703,267,50,703,355,253,30,833,452,61,959,777,54,399,973,740,98,148,649,121,814,335,3,991,718,167,600,700,112,692,494,505,688,813,751,790,32,997,25,598,255,223,653,686,856,987,915,428,342,403,478,440,200,280,781,993,832,171,461,321,61,908,878,296,118,288,12,339,338,809,732,8,230,347,421,56,298,694,421,303,343,269,923,711,514,983,882,161,895,823,340,42,260,848,40,122,242,22,69,7,81,778,289,701,493,837,349,653,517,451,453,302,825,281,77,46,462,585,443,433,378,558,870,391,129,76,224,721,929,651,458,469,231,896,801,645,23,844,569,612,516,766,53,121,177,57,938,855,265,367,663,480,241,673,825,324,543,324,405,156,473,562,303,538,951,794,662,895,312,994,705,560,819,40,925,688,183,400,109,647,896,253,317,623,141,977,303,111,388,477,458,302,454,187,34,67,516,611,38,157,489,747,637,599,271,441,199,452,288,857,431,817,534,992,73,531,825,973,519,276,544,508,594,6,445,976,503,648,87,44,743,803,811,296,70,343,551,243,352,118,123,101,744,530,979,573,45,202,613,766,580,331,734,55,293,630,527,244,611,323,732,764,883,753,434,523,51,252,943,590,372,19,562,359,500,351,870,149,852,871,525,187,837,413,701,689,80,779,599,581,970,916,2,293,203,162,926,309,52,805,108,850,877,687,936,241,436,635,148,568,357,370,58,946,129,314,976,497,279,779,183,140,415,365,34,83,819,349,309,419,959,609,457,534,881,14,292,200,405,152,554,153,739,792,487,118,225,783,26,883,38,426,949,200,686,968,765,154,257,182,999,106,192,434,60,973,436,209,543,123,433,840,497,115,420,324,864,505,912,602,40,697,811,841,127,6,806,42,772,364,619,924,383,661,575,135,878,533,396,891,439,190,661,96,370,392,902,32,415,819,805,10,774,526,854,9,298,594,547,266,569,356,83,280,642,954,607,245,579,940,548,957,155,972,250,331,831,674,393,461,102,18,201,811,893,332,316,13,322,801,667,855,39,687,720,624,324,691,652,55,327,844,307,507,179,325,86,483,43,962,995,174,632,787,641,889,661,885,446,990,245,822,325,178,256,396,927,192,224,85,758,611,351,742,140,898,268,779,883,85,533,614,762,129,984,854,543,804,506,187,772,415,43,589,481,4,519,927,445,372,948,508,183,82,39,925,920,896,740,722,236,450,199,426,930,13,175,836,610,10,708,465,38,319,849,696,972,120,653,837,384,759,797,720,849,235,551,232,487,516,185,858,217,181,407,401,135,616,897,60,896,160,222,119,375,814,530,868,736,912,529,699,953,105,976,696,863,410,254,878,473,700,569,985,762,355,695,492,731,164,988,703,452,468,148,131,914,995,832,518,415,720,852,424,131,379,445,439,56,241,489,602,473,374,153,862,868,259,583,156,466,644,240,451,79,975,747,332,204,399,438,191,206,232,511,605,612,326,949,506,966,295,940,758,411,947,40,428,268,63,490,575,281,478,733,184,469,520,548,358,258,839,988,377,139,235,38,271,160,483,841,340,828,406,971,714,93,692,201,690,312,480,82,66,455,555,866,524,320,736,597,204,791,787,889,430,759,473,981,345,800,913,90,363,561,531,977,76,197,252,426,106,17,561,384,600,675,929,247,726,706,95,964,480,629,48,376,683,887,424,918,755,803,568,288,777,300,72,399,49,785,401,539,239,143,352,258,421,270,968,265,421,745,898,578,141,647,523,363,198,913,98,966,365,941,941,25,715,408,392,341,115,360,418,897,163,725,123,75,791,381,302,935,44,910,359,367,194,644,296,768,806,931,943,21,374,54,428,794,576,638,99,641,191,852,227,973,659,768,545,848,662,867,475,992,234,77,418,70,67,549,721,636,588,299,161,142,862,182,412,476,747,73,60,242,522,4,950,78,841,417,537,367,71,348,367,367,132,945,0,346,601,869,105,441,30,925,746,478,89,641,399,466,594,438,7,166,385,854,43,609,922,784,401,159,807,198,164,972,917,727,649,438,609,566,520,58,640,377,118,500,351,263,576,616,6,479,558,209,668,850,330,936,218,412,98,823,585,830,238,511,258,437,587,995,826,519,965,415,873,763,660,219,793,151,463,16,563,755,55,224,494,911,527,642,181,539,392,666,286", "720,160,840,380,902,445,382,981,815,987,530,51,946,286,335,924,535,411,158,895,171,928,852,330,459,130,110,789,699,885,453,305,253,257,839,573,507,469,320,999,302,885,397,761,84,125,37,404,406,337,151,176,42,793,315,595,616,284,908,29,860,260,566,328,306,224,755,456,723,718,443,372,777,861,699,571,365,692,90,5,595,489,230,377,786,414,649,681,885,313,464,496,605,407,498,969,807,423,650,286,39,528,38,387,164,638,389,321,482,6,346,848,455,279,255,713,924,380,199,979,152,226,961,866,470,727,928,691,976,688,272,721,484,884,313,672,102,993,953,112,238,369,33,18,389,158,196,800,388,743,311,901,477,782,836,654,318,180,162,657,928,569,386,682,764,543,487,76,206,160,161,312,643,391,654,975,177,59,669,518,468,313,863,313,678,612,289,133,869,53,24,48,702,243,632,776,852,809,553,940,221,338,111,618,725,859,620,280,963,597,513,135,453,264,40,149,493,334,512,82,71,29,69,362,354,934,666,328,581,543,2,299,74,852,369,574,771,758,33,197,784,258,56,388,264,937,677,114,631,137,214,853,304,950,804,782,811,38,981,164,826,163,920,67,776,912,363,939,837,665,546,713,442,896,642,167,519,895,754,889,616,350,279,248,907,479,690,394,773,784,736,496,988,728,555,439,716,922,2,870,795,420,323,677,410,779,166,753,938,170,222,386,326,900,76,313,395,491,53,525,811,747,92,69,253,226,411,355,561,729,77,471,860,874,431,848,571,953,451,344,384,706,490,175,505,42,436,99,723,317,72,839,148,606,898,343,201,325,600,460,537,928,672,405,912,952,856,576,22,218,289,884,930,931,476,737,135,875,720,857,657,729,638,703,408,280,716,131,144,477,240,439,806,67,529,246,518,635,139,243,482,439,972,280,171,341,30,253,540,14,472,638,616,376,882,856,630,276,650,179,581,140,730,307,508,64,731,748,260,561,171,815,897,695,366,529,682,434,103,448,147,90,595,48,676,771,207,947,327,42,803,237,870,345,393,591,508,340,122,46,612,495,215,607,297,79,586,191,592,981,832,153,334,973,393,152,142,224,668,501,780,190,211,508,971,345,491,5,951,839,1000,12,923,280,738,732,461,596,477,644,457,615,381,4,443,726,431,790,901,801,333,489,683,673,389,253,525,681,606,356,911,579,487,669,286,896,796,26,326,6,661,421,116,588,950,734,211,603,328,302,92,778,259,496,615,952,469,54,717,402,704,970,165,163,100,76,755,311,356,612,474,324,274,209,379,826,376,945,407,280,90,870,840,158,546,448,789,423,565,80,679,268,252,935,59,239,132,652,866,843,669,141,176,202,723,804,870,389,345,380,765,626,50,210,25,397,798,934,295,353,447,606,232,70,16,480,911,236,370,992,907,90,109,221,752,953,735,616,868,418,141,84,431,224,65,264,59,204,329,71,214,141,334,426,160,665,128,529,294,460,387,386,803,565,902,81,840,299,131,745,822,790,824,467,727,205,133,564,323,3,848,671,918,533,665,302,614,771,441,800,941,204,18,151,819,105,429,269,13,571,131,565,613,728,954,151,878,911,256,78,812,435,380,434,419,646,145,617,893,886,2,774,99,322,775,935,774,382,701,902,518,358,308,981,151,687,443,296,578,452,898,437,790,357,314,280,975,707,466,191,65,35,25,26,483,39,68,445,296,162,972,524,468,271,256,540,816,576,622,505,566,896,767,796,752,857,102,263,419,574,165,800,890,609,60,79,365,289,815,857,682,211,843,142,245,89,994,715,616,607,160,735,933,532,804,638,697,455,194,845,70,75,73,101,854,749,876,254,238,121,912,825,166,544,502,39,174,140,769,550,858,775,744,972,409,504,975,347,457,344,200,25,217,359,156,107,878,782,371,819,13,452,786,148,404,565,224,871,446,270,568,845,937,135,301,378,799,63,620,227,65,298,107,221,8,837,545,888,996,239,250,284,370,607,402,519,536,955,797,415,797,33,400,302,837,169,767,832,983,859,202,764,363,69,437,163,926,297,200,405,693,286,913,709,925,369,973,571,857,346,0,255,790,909,520,41,965,326,447,519,195,98,679,413,517,50,566,320,979,501,586,558,455,675,896,674,913,719,962,758,330,85,192,510,627,921,675,362,605,83,228,873,404,716,458,897,414,79,652,848,134,498,353,436,809,609,887,341,99,983,725,373,830,129,381,648,564,516,35,540,369,374,37,410,631,94,811,36,739,933,876,359,839,835,423,372,201,347,314,465", "215,765,462,868,863,486,686,380,258,528,557,205,370,429,229,360,261,568,616,311,173,284,721,392,675,691,489,258,608,314,93,510,680,873,883,498,105,307,534,515,562,40,698,814,580,671,317,66,126,9,392,898,361,259,444,812,643,800,724,841,860,149,142,495,344,699,214,851,367,524,989,366,611,825,902,655,500,887,50,431,53,433,53,70,720,263,735,575,141,294,770,549,843,591,857,157,721,619,726,760,557,356,91,33,722,365,248,809,341,966,534,373,873,530,551,989,437,3,972,648,179,338,686,113,708,959,304,354,411,53,459,631,197,681,398,998,608,650,11,596,49,471,154,186,224,173,177,766,552,993,947,285,611,763,934,38,427,105,270,465,918,528,736,308,865,747,802,395,250,727,45,596,698,556,195,66,238,477,427,813,283,161,201,572,266,788,393,795,97,590,698,117,553,471,809,835,20,348,484,916,932,238,928,832,476,619,402,155,163,952,959,904,718,602,611,374,793,481,783,15,179,859,638,302,834,937,69,493,741,59,500,103,4,517,358,486,114,426,739,852,772,883,855,829,602,691,325,947,139,829,86,98,478,190,913,234,637,647,585,827,413,608,697,369,552,129,852,989,559,958,723,984,366,695,980,475,511,683,433,874,864,499,343,204,108,626,647,64,943,422,692,402,49,695,70,919,953,893,359,554,470,42,841,922,711,469,305,378,207,204,122,296,481,662,329,473,59,199,533,984,13,193,134,354,890,960,388,904,138,178,432,62,881,681,360,891,983,551,429,897,709,169,999,714,264,968,815,739,696,344,733,371,655,646,538,787,589,437,156,31,311,112,947,725,180,314,263,668,684,925,812,547,20,514,816,682,34,762,336,935,899,278,85,456,666,436,180,656,157,745,529,282,463,598,110,31,448,549,663,506,909,599,667,789,712,909,589,746,235,410,819,868,98,867,466,507,627,845,991,306,143,875,614,556,291,802,122,218,118,841,468,984,183,287,177,243,43,165,791,370,533,852,160,1000,985,648,610,99,503,340,77,255,718,196,772,670,280,553,658,685,297,500,368,625,164,429,517,282,813,887,470,124,16,759,395,336,476,579,156,143,902,976,759,924,475,643,913,231,242,266,713,403,992,626,125,930,297,895,134,328,767,12,174,310,324,969,897,642,523,346,691,924,664,723,430,494,647,333,710,581,757,284,454,659,65,551,750,975,666,976,399,58,781,949,431,66,57,56,285,36,383,887,104,441,793,68,428,51,403,498,723,889,959,568,949,671,721,949,79,905,202,841,54,906,28,112,249,682,514,827,78,478,223,637,716,952,265,737,664,798,224,212,933,884,835,537,560,494,355,210,791,334,703,963,438,417,992,592,519,407,858,235,456,406,430,697,577,624,402,144,705,975,2,96,288,687,586,244,187,117,77,970,821,924,505,148,543,621,957,364,805,802,173,241,243,836,930,318,114,582,315,771,640,416,15,644,57,977,264,77,310,10,170,174,8,298,592,277,821,707,212,92,94,250,816,124,473,37,894,994,119,718,765,40,927,111,935,376,198,307,642,5,865,880,730,130,704,416,147,588,592,295,836,854,617,401,757,879,628,363,36,292,949,473,400,256,966,814,214,949,713,266,292,291,800,492,271,867,200,983,251,662,603,286,808,758,981,389,782,322,411,323,158,698,799,425,380,522,583,686,545,547,743,345,865,407,342,743,321,524,354,449,827,597,43,875,469,170,577,195,377,411,73,505,148,573,572,835,783,702,507,142,855,946,882,41,718,223,3,364,989,195,596,852,49,313,562,955,566,53,809,865,244,583,926,741,938,186,216,855,344,783,813,316,505,230,253,111,986,795,598,242,948,314,421,432,8,643,212,107,163,781,724,56,170,47,14,730,749,220,418,529,865,594,958,300,181,779,228,838,473,867,841,596,21,59,303,524,44,846,392,445,470,476,399,92,511,114,320,305,966,527,81,592,342,674,379,946,816,98,554,921,936,48,20,922,453,927,937,518,744,710,26,111,909,10,409,414,299,785,872,479,745,699,929,791,689,581,813,191,836,86,430,532,744,78,765,839,21,601,255,0,605,334,970,774,878,465,906,405,269,341,409,499,610,696,221,448,114,119,284,208,64,235,973,764,703,815,789,765,862,549,454,574,976,479,277,343,55,739,691,892,595,470,74,251,234,244,72,367,78,658,571,466,177,616,914,992,664,194,699,565,306,336,683,577,572,436,809,325,555,202,879,772,952,474,201,559,325,740,805,479,439,521,502,326,145,931,4,529", "62,92,761,472,58,727,65,927,606,315,196,640,722,350,822,119,9,412,90,531,841,366,870,655,319,29,352,821,152,347,708,625,816,42,876,975,676,773,772,145,92,365,544,286,856,646,600,507,660,755,264,216,973,848,469,261,719,71,810,369,459,976,70,437,303,998,89,139,752,644,621,258,235,943,567,366,828,826,743,370,519,953,27,490,137,21,686,525,369,437,88,622,800,860,977,194,122,271,149,766,47,840,470,794,135,100,914,899,437,966,608,287,891,262,371,947,348,226,230,35,770,408,701,333,234,666,156,874,258,771,693,193,425,377,581,175,253,204,665,579,762,502,710,653,612,627,382,248,158,49,947,575,927,604,898,600,40,938,191,693,766,276,751,457,150,77,703,879,176,760,107,673,79,309,762,505,841,659,60,966,882,990,951,263,966,982,765,415,93,328,708,844,262,608,516,245,803,966,198,861,479,194,328,532,647,469,263,332,403,710,731,800,788,330,383,783,984,627,581,247,198,243,812,712,741,586,913,860,210,901,765,473,478,644,790,270,200,509,777,431,926,318,732,663,17,991,729,993,510,32,395,851,990,764,719,404,570,681,168,943,904,519,441,497,932,563,426,798,982,287,63,603,601,765,805,56,796,281,937,286,4,930,939,29,667,995,985,998,147,684,97,338,883,490,24,838,669,533,579,870,140,925,608,908,774,816,573,220,507,292,316,627,521,793,349,364,163,737,32,390,933,367,747,270,65,453,706,24,438,663,623,675,626,256,627,665,372,159,536,33,767,289,884,391,816,429,344,518,35,618,671,888,905,238,856,711,301,893,743,42,915,508,651,297,825,720,920,385,536,599,26,397,341,267,568,412,26,567,184,486,914,462,948,731,156,58,352,268,81,327,320,439,942,930,654,182,342,911,935,219,622,792,711,924,130,133,1000,574,820,70,711,580,729,756,181,8,264,207,359,246,683,476,249,66,692,869,920,987,226,759,920,76,102,314,698,217,428,339,226,829,611,773,259,460,486,12,45,181,255,949,850,779,436,735,109,337,19,191,512,802,940,87,59,565,778,532,253,715,845,400,857,834,984,975,614,361,325,645,377,339,678,305,151,967,419,314,729,138,390,660,404,880,744,48,887,710,873,527,586,737,576,748,349,946,739,406,129,137,509,414,175,224,985,211,429,62,606,138,908,796,561,144,2,905,32,535,858,653,837,455,900,619,339,848,58,272,993,819,396,657,323,644,606,772,887,430,7,312,549,814,519,318,146,515,942,713,76,801,589,386,502,774,830,757,338,69,850,795,651,224,473,705,130,542,405,490,514,223,777,778,583,393,856,885,75,894,709,434,791,770,879,832,613,803,557,994,127,746,339,87,890,825,589,242,646,963,652,723,415,955,432,5,7,259,157,787,952,668,416,830,303,9,500,549,738,965,802,131,406,230,690,502,15,334,142,794,767,398,448,159,206,718,535,981,761,229,660,190,203,316,711,53,137,519,267,169,883,850,750,147,922,77,487,199,72,661,94,610,926,539,11,282,126,554,369,246,77,246,12,170,629,152,737,198,572,20,928,316,630,64,345,718,7,746,642,955,316,909,997,923,507,77,629,223,943,601,132,974,938,804,993,264,272,549,182,4,51,437,137,205,867,57,26,273,161,319,887,54,491,704,727,778,309,258,883,311,100,411,302,586,535,457,947,200,249,327,809,279,683,884,990,100,492,870,571,16,290,723,799,258,570,644,790,616,194,197,305,926,943,96,781,92,793,279,1,741,833,543,245,319,553,95,630,93,922,232,68,689,902,166,219,316,78,181,508,170,112,651,538,240,779,748,10,729,178,165,495,651,213,588,167,453,49,658,271,867,751,199,531,463,995,849,109,313,403,723,903,989,286,375,131,950,487,64,286,377,62,918,717,507,213,441,142,823,162,389,42,157,686,920,891,423,592,854,919,106,712,185,39,141,118,834,940,744,647,428,506,902,139,398,381,688,807,852,181,436,366,38,611,417,423,46,689,515,205,135,782,160,915,870,852,630,241,526,10,646,299,80,675,477,45,444,523,95,376,956,113,58,829,869,790,605,0,532,552,391,804,928,721,317,912,638,459,551,547,27,694,945,512,199,696,257,63,517,770,432,370,876,791,267,936,381,22,127,344,766,833,574,572,340,210,425,436,785,136,884,166,558,536,330,871,953,44,816,488,316,577,197,604,515,78,734,961,836,163,414,153,129,179,757,81,787,910,905,908,254,682,312,785,968,845,927,660,492,968,93,991,862,667,121", "962,32,410,410,951,165,561,238,127,531,480,87,527,486,23,417,613,489,767,617,69,436,208,213,342,180,266,148,430,442,603,111,224,293,1000,660,335,111,839,507,264,655,350,416,256,368,754,169,399,469,183,688,80,784,804,270,585,61,354,265,731,555,567,898,297,954,199,420,499,488,944,570,664,201,9,151,64,55,547,448,274,227,287,333,112,125,244,717,586,962,487,506,234,624,911,583,587,660,209,536,533,233,798,42,226,684,423,747,789,149,903,687,253,914,30,347,77,12,85,548,956,212,22,245,881,124,3,542,663,168,808,358,502,587,591,580,349,735,72,45,3,929,233,192,166,220,239,766,149,950,774,337,477,512,530,975,481,367,22,573,943,493,991,151,33,825,332,264,6,533,941,154,950,196,269,813,593,92,504,688,978,425,26,13,175,133,538,527,120,844,614,327,22,560,231,843,820,250,739,656,192,424,758,531,253,598,231,766,192,19,324,581,311,84,929,993,443,448,692,488,324,459,743,217,193,953,319,100,511,165,851,375,694,754,533,795,513,278,428,21,831,343,808,325,641,969,903,860,162,973,104,303,491,971,976,954,74,3,78,968,833,89,740,570,603,761,766,492,525,21,578,187,13,82,700,740,455,16,748,982,815,869,71,594,477,609,934,808,868,730,212,621,235,814,338,59,563,811,844,418,426,203,683,534,810,30,185,64,864,941,244,292,715,951,193,481,93,456,239,821,254,683,9,973,38,826,839,428,135,919,296,446,578,255,819,417,361,375,474,897,340,985,104,451,491,331,438,961,578,751,263,703,668,444,158,489,234,874,628,119,493,955,590,574,432,839,966,264,959,950,959,32,654,98,678,482,872,589,857,919,683,196,105,135,494,7,808,943,866,297,813,791,146,694,951,980,479,277,1,968,797,488,209,847,185,975,500,686,509,852,348,484,614,945,814,493,41,698,337,856,825,785,214,77,771,971,259,714,226,577,810,942,237,274,41,420,575,166,233,978,923,133,525,198,658,38,680,176,575,940,387,980,300,222,854,23,320,188,391,22,453,561,218,51,952,517,820,761,957,663,612,8,869,222,787,495,219,353,48,881,51,734,312,821,625,189,300,412,852,658,885,799,42,128,798,436,115,471,651,806,834,512,368,871,454,975,579,877,736,615,452,276,49,566,718,385,557,459,850,951,992,241,486,57,964,251,177,687,724,526,723,480,447,981,581,210,703,309,898,372,16,826,984,8,303,442,917,108,629,693,189,261,70,329,495,377,773,80,831,508,568,706,919,852,949,463,863,704,886,743,825,926,436,59,7,836,713,474,803,904,688,599,824,566,489,234,555,415,446,865,45,111,431,535,695,720,359,315,286,817,953,190,233,921,525,83,729,694,693,173,742,598,395,68,356,887,435,867,993,721,409,205,296,58,932,650,260,421,692,290,808,475,92,649,966,161,876,544,126,846,439,53,75,348,963,246,140,375,384,413,504,324,133,62,106,626,982,699,934,330,841,434,548,240,339,162,793,224,53,529,183,493,779,178,454,593,967,380,882,184,378,658,974,351,304,193,21,547,778,588,201,475,801,429,941,892,209,424,485,212,186,181,99,462,855,621,251,409,29,356,418,338,701,44,674,251,103,101,212,244,271,133,301,307,845,199,260,621,561,519,573,362,919,825,465,344,312,903,939,696,860,739,8,62,848,157,452,162,794,518,208,131,160,650,814,498,757,981,259,71,452,555,945,111,359,929,757,443,605,972,342,748,313,192,897,850,40,491,466,313,657,451,767,332,441,854,464,624,422,506,429,910,890,323,24,233,986,938,370,752,717,569,117,345,798,986,789,469,393,222,202,578,708,880,832,534,968,826,801,823,768,900,368,42,857,591,489,869,173,937,332,97,984,966,879,87,221,568,378,180,379,376,292,866,740,427,958,116,176,596,533,754,215,980,876,466,941,352,248,24,76,994,269,278,585,216,627,28,965,297,636,740,325,275,285,177,423,618,929,732,603,710,584,262,222,134,539,104,340,90,681,119,936,630,728,467,249,367,893,356,350,933,57,717,124,617,831,773,917,105,909,334,532,0,830,285,307,318,623,201,937,356,834,856,522,718,90,677,811,51,870,871,498,706,270,609,67,555,320,304,56,510,644,104,725,697,698,936,546,628,762,778,138,469,997,784,565,382,818,449,879,595,500,175,642,490,332,143,990,853,726,473,92,717,208,908,132,576,733,282,915,839,834,411,238,365,701,970,65,928,332,651,894,808,126,890,138,239,634,462", "8,56,764,549,266,94,989,594,39,374,301,729,133,594,914,946,516,191,97,537,963,622,128,636,988,156,747,684,693,72,629,306,690,337,263,204,356,556,914,765,588,471,426,742,805,712,933,402,770,985,477,781,702,259,652,721,222,656,549,358,392,765,690,495,217,342,716,10,400,191,455,84,821,136,283,816,972,705,435,409,858,653,925,457,363,758,569,832,892,809,121,778,646,435,981,363,266,382,4,623,584,285,377,998,123,162,727,414,241,312,535,98,423,746,489,46,274,589,525,217,134,238,583,732,500,451,22,609,880,482,400,650,620,192,19,734,222,557,802,984,267,767,748,450,613,816,384,810,161,119,575,752,332,358,290,993,824,826,826,604,747,978,641,631,487,280,37,38,299,10,318,943,246,80,369,593,775,485,33,299,788,97,448,446,243,759,891,489,54,237,753,809,118,531,914,997,33,764,125,19,45,522,670,597,889,149,730,184,240,820,703,979,596,542,412,807,600,840,636,709,514,444,804,553,432,865,587,400,809,669,71,756,285,793,138,269,310,184,538,575,422,277,943,489,677,165,388,653,616,423,229,783,106,978,514,890,531,705,138,990,20,502,189,928,362,148,664,364,45,488,256,889,521,866,250,472,412,83,840,808,554,226,58,224,964,299,606,442,852,416,718,665,366,837,802,685,69,638,114,787,108,587,355,115,665,41,442,646,317,524,288,202,484,283,879,617,620,999,461,730,161,832,486,355,355,25,776,807,524,393,549,390,647,901,662,903,482,423,36,17,624,234,738,735,33,377,791,738,274,218,409,656,308,348,414,719,97,791,651,104,489,672,185,860,613,426,550,721,751,134,342,414,527,679,991,861,716,601,644,936,447,36,744,816,448,618,623,182,689,536,657,318,380,329,220,205,775,206,362,436,759,849,366,690,194,267,732,785,973,919,143,533,150,673,992,757,38,912,733,910,75,862,936,949,218,966,437,245,717,911,804,9,249,196,500,149,646,550,912,621,986,387,672,594,406,469,345,161,453,868,256,91,753,32,593,798,728,169,297,298,958,155,515,66,921,806,828,69,846,240,283,782,659,477,786,190,202,842,786,594,440,225,101,747,473,446,621,410,395,793,89,392,870,535,555,624,434,554,782,560,568,922,450,434,107,465,526,701,294,950,452,792,494,589,803,794,605,468,737,861,817,702,406,696,901,202,896,906,522,257,599,811,52,576,396,542,269,270,597,281,740,334,161,327,474,681,771,403,328,679,770,839,93,470,623,155,560,114,629,308,539,929,397,833,620,570,112,966,729,766,724,977,319,976,727,388,397,197,346,698,681,780,1000,985,349,617,776,482,923,223,734,316,826,219,861,636,5,702,237,165,307,657,129,167,91,676,350,355,837,60,802,766,762,514,290,465,260,999,678,252,84,828,335,32,123,543,272,181,938,584,773,480,908,927,362,338,370,575,574,203,194,200,987,180,860,659,192,816,422,141,843,244,820,767,187,95,241,401,850,887,240,798,865,88,451,251,80,833,548,600,572,530,559,657,202,961,309,186,531,277,712,982,614,748,286,785,294,105,404,32,756,122,607,59,296,904,426,880,420,58,201,418,902,655,946,514,351,401,208,109,745,988,510,892,9,481,256,866,517,361,969,553,234,339,214,249,615,920,559,690,45,370,373,983,721,231,789,896,530,190,394,967,128,769,978,264,56,590,535,246,478,274,37,131,622,630,66,513,583,493,526,727,478,375,907,268,375,519,732,570,726,702,420,91,205,401,906,704,637,513,398,509,429,626,882,785,193,901,593,474,631,602,178,831,101,882,154,654,304,849,565,150,103,647,273,909,222,59,12,594,681,343,230,277,479,617,553,162,316,143,759,463,329,965,746,74,399,455,176,175,342,927,144,128,388,845,59,51,960,982,382,777,711,746,945,180,674,196,909,94,689,958,786,509,186,606,852,86,842,640,822,896,60,943,463,547,176,840,424,189,532,166,241,928,891,843,843,910,95,292,518,221,356,480,68,22,818,184,705,536,467,439,881,531,245,849,517,55,245,175,438,896,503,986,847,797,791,586,158,441,520,970,552,830,0,91,297,275,446,238,795,945,650,674,417,914,82,349,526,464,288,375,170,330,811,643,744,359,109,886,830,744,629,491,292,8,393,993,12,78,847,945,428,670,30,793,670,947,349,409,406,137,73,989,170,927,933,728,277,375,171,56,597,639,485,900,483,162,342,770,930,341,371,864,518,885,344,453,398,322,648,71,747,560,78,805,184,492,575,751", "208,662,177,277,135,23,337,5,868,428,528,538,821,73,968,660,597,27,263,737,552,998,56,51,434,875,11,797,509,959,904,331,659,377,137,194,510,999,570,815,507,755,972,690,436,625,927,761,355,444,11,920,569,391,509,26,770,596,917,645,333,561,165,318,243,904,45,439,38,636,221,63,278,106,185,98,572,910,141,386,402,906,269,126,256,915,454,914,825,971,140,112,2,316,624,958,535,946,67,708,780,282,508,403,19,729,596,174,314,615,37,521,336,115,201,977,129,649,681,103,828,271,30,283,918,352,536,180,813,622,956,421,742,119,164,571,604,902,859,442,139,521,523,52,51,889,977,559,694,139,143,426,199,939,69,477,753,284,891,960,771,509,191,558,672,418,380,659,519,362,826,970,794,700,102,42,726,101,16,360,689,612,980,869,989,799,620,664,308,287,893,119,744,71,236,254,426,382,925,893,817,390,334,401,926,141,155,593,927,473,383,97,944,718,643,956,785,564,893,986,250,924,995,475,100,431,867,214,957,914,280,132,475,670,332,827,185,469,77,363,535,369,254,248,378,885,326,684,181,17,225,324,319,314,85,891,58,29,749,517,830,585,295,898,598,132,135,816,162,7,633,469,316,135,44,405,85,514,449,682,566,985,947,786,507,25,879,176,157,617,634,687,67,385,925,143,359,93,272,783,716,904,559,69,884,167,460,959,362,529,208,851,297,107,763,104,834,757,159,218,820,101,50,490,82,216,86,272,737,842,445,688,649,607,970,491,484,237,309,425,233,817,955,349,451,708,34,959,662,430,598,631,301,831,859,47,626,407,910,681,719,198,936,527,938,382,731,480,898,548,446,339,643,33,124,274,435,52,540,298,270,171,185,159,582,275,753,657,66,517,902,820,991,487,706,538,967,88,817,995,960,170,828,519,955,125,196,202,519,204,355,608,861,340,474,244,623,804,302,497,398,277,271,860,398,409,754,511,621,49,429,766,730,120,626,518,636,669,763,744,352,60,341,3,648,785,57,89,378,752,381,130,668,26,46,760,752,451,978,565,953,121,961,415,544,173,366,677,647,162,292,748,733,402,281,188,408,441,849,663,515,515,42,404,820,328,838,174,648,815,178,632,836,945,141,696,5,491,46,195,799,703,594,168,329,542,950,541,617,310,817,741,372,107,17,719,584,569,859,465,409,606,635,119,676,614,728,825,215,778,584,358,281,573,333,354,650,404,221,864,736,319,425,363,839,192,454,388,15,171,571,483,522,519,27,152,660,521,929,747,204,817,713,896,34,682,914,537,52,299,860,606,733,221,943,473,803,994,132,432,697,539,287,646,511,356,704,464,493,812,737,351,959,786,696,864,903,391,871,717,725,359,454,89,178,884,572,544,201,261,966,225,197,103,786,555,827,491,460,762,287,725,807,983,156,664,923,568,241,829,382,183,84,463,233,223,572,492,322,924,739,886,173,843,395,460,870,461,605,78,969,958,310,446,896,613,344,510,683,109,713,156,411,824,630,987,653,280,125,306,107,733,964,762,893,423,655,975,270,216,507,652,689,107,213,50,811,674,726,528,117,559,597,416,988,650,13,309,976,888,1000,870,814,768,756,924,659,410,739,302,639,33,828,761,549,743,976,511,402,364,459,376,856,641,581,453,483,767,276,168,547,598,714,160,114,85,465,733,805,24,444,767,249,861,81,125,495,51,424,726,573,721,549,87,365,477,218,869,226,326,717,151,861,579,379,911,463,4,56,463,710,62,789,846,931,456,657,886,261,617,918,472,325,260,61,247,932,286,655,470,5,733,984,601,472,486,825,700,479,789,387,753,17,502,91,106,983,473,486,207,500,817,183,601,493,151,479,225,196,971,283,701,264,616,945,351,714,521,826,775,262,615,127,272,779,808,126,646,101,190,26,808,48,701,198,819,229,971,465,847,461,324,854,221,808,981,516,363,347,669,366,523,328,187,252,557,27,559,72,150,393,778,633,576,82,631,106,239,294,793,672,204,733,81,702,243,875,177,291,399,258,495,78,236,279,235,998,126,619,23,444,55,358,622,139,116,155,583,23,30,41,774,391,285,91,0,564,430,740,15,143,100,632,259,567,742,664,702,33,321,74,792,455,31,57,887,945,869,707,390,884,501,999,449,708,969,846,403,380,777,414,105,258,63,858,744,609,620,893,770,817,834,835,259,71,463,486,171,472,682,816,107,261,137,660,998,97,485,17,304,993,842,48,474,777,368,162,227,342,296,604,755,602,727,995,98,590,496,906,131", "617,451,39,392,131,53,754,9,750,942,438,295,546,25,13,446,626,888,552,877,649,763,64,212,857,778,293,444,188,793,964,75,596,708,436,245,879,128,403,832,924,518,644,498,915,630,62,250,132,711,968,63,832,669,817,1,498,357,529,948,546,399,51,672,193,771,145,756,877,913,636,582,316,297,83,589,250,101,761,696,862,239,314,174,349,566,188,689,737,538,2,825,148,724,651,357,711,717,69,1,330,532,691,431,898,582,528,433,143,206,679,579,532,480,208,920,982,623,842,264,526,77,148,398,833,823,228,777,68,510,685,425,522,874,649,128,24,460,978,334,473,359,242,835,9,398,49,262,336,608,654,702,706,583,654,881,784,299,394,42,97,3,596,334,649,460,109,865,997,170,701,248,317,414,295,743,222,475,812,43,48,743,312,654,889,322,99,331,372,752,338,899,122,247,836,171,176,96,777,633,319,539,584,640,304,96,569,610,590,934,40,47,828,275,38,175,987,664,794,116,926,896,233,1000,287,587,373,679,315,571,776,517,5,121,394,242,156,941,393,696,85,246,396,566,678,471,447,365,756,387,231,57,977,915,931,308,411,853,354,980,881,93,601,979,607,650,293,17,680,616,632,604,562,793,549,437,163,560,884,34,27,735,847,150,473,742,909,671,293,253,780,258,261,967,181,311,963,866,670,301,617,509,854,641,261,116,323,50,241,943,366,514,607,690,143,331,477,98,502,632,484,947,312,814,542,658,186,28,9,664,989,37,544,748,608,853,499,899,746,590,829,96,876,922,861,511,509,753,314,192,488,249,719,304,577,496,509,14,794,684,679,82,65,628,922,218,304,918,776,749,300,178,957,305,119,907,287,69,957,54,318,193,599,105,378,534,563,372,166,143,554,590,288,742,178,920,863,999,238,464,897,251,983,872,734,682,895,615,177,913,770,714,955,361,19,196,235,291,169,491,596,10,463,697,347,135,35,328,287,595,704,951,609,375,204,305,712,145,776,685,715,474,878,543,444,960,93,731,816,730,720,535,789,510,547,94,220,857,225,503,544,923,996,618,948,861,419,968,44,189,934,17,950,966,686,943,803,476,949,977,316,340,975,183,637,162,811,483,401,659,277,643,775,391,816,618,41,66,79,983,997,860,207,846,238,696,815,839,358,189,942,549,458,711,18,158,104,871,207,342,76,386,323,138,679,478,548,303,709,92,967,903,348,562,649,752,516,573,396,29,454,513,573,104,746,436,959,977,963,193,144,433,511,617,426,996,86,170,428,453,141,81,499,36,181,203,768,78,443,525,83,149,98,566,567,645,983,421,167,944,537,721,823,722,78,698,803,819,548,492,196,998,877,154,361,443,765,997,442,611,396,125,777,177,589,727,262,719,644,191,909,947,432,765,331,637,206,685,312,182,116,790,738,24,709,810,807,473,603,145,193,27,45,274,510,401,361,664,481,138,645,560,834,378,415,70,33,405,271,430,83,270,58,223,692,76,509,136,391,457,823,277,631,309,514,395,102,979,924,427,750,628,745,2,264,175,206,158,430,42,177,712,451,852,454,299,931,188,792,946,360,143,805,338,797,66,727,968,299,681,200,49,206,838,716,609,86,881,778,386,161,30,184,156,732,254,825,203,257,771,138,751,922,97,321,523,500,521,515,798,179,26,845,181,51,10,188,457,268,826,631,468,919,478,613,479,378,379,958,805,849,660,336,855,159,867,889,717,778,701,901,490,147,309,420,732,675,159,287,61,897,849,589,269,259,451,170,945,999,845,776,779,525,629,268,340,402,319,12,248,903,470,774,861,11,452,976,251,432,727,295,111,264,757,781,936,885,855,244,686,599,762,103,151,647,409,299,535,647,469,357,144,314,747,84,1,627,355,150,926,263,964,61,808,427,206,308,508,201,725,263,761,914,306,209,933,440,539,259,939,579,431,264,919,752,426,758,302,554,101,922,84,58,699,993,77,416,44,966,717,66,548,971,141,322,615,292,733,94,812,715,841,450,35,933,970,190,64,857,841,583,453,75,291,159,668,262,221,131,459,83,590,687,534,367,719,261,928,213,925,965,878,804,307,297,564,0,111,675,418,371,473,738,799,307,790,947,118,260,77,596,283,740,158,466,750,189,967,371,858,592,601,262,829,21,302,68,314,519,290,36,105,669,533,696,546,116,533,13,701,979,350,482,366,47,689,833,216,164,106,711,991,251,513,340,460,277,518,304,910,981,476,346,901,8,531,81,287,917,628,308,99,349,896,619,304,262,869,565,589", "285,449,138,907,44,415,901,877,36,806,492,166,213,987,814,484,974,55,870,823,203,257,274,605,569,247,273,629,319,316,759,851,217,49,112,854,217,667,371,248,148,466,3,840,703,921,185,975,608,340,893,455,794,254,547,229,360,362,18,138,307,25,69,895,259,426,961,308,935,812,130,347,179,98,897,720,507,344,727,643,300,333,27,894,261,893,813,744,343,582,312,615,400,191,737,756,727,579,653,733,704,586,456,707,420,716,970,975,880,617,567,242,689,969,210,427,80,689,322,991,285,650,995,783,939,984,983,100,706,892,239,517,238,76,575,258,948,268,384,544,469,347,492,985,969,140,861,878,721,48,606,486,187,460,657,966,742,170,73,225,746,20,341,483,621,851,93,880,82,335,864,334,60,136,868,743,942,425,260,552,24,159,483,98,604,720,932,413,661,958,195,153,166,974,79,372,710,27,475,199,350,435,909,27,542,493,214,267,970,751,214,492,66,191,599,313,686,108,192,329,539,747,996,450,265,679,77,67,998,373,634,651,322,947,793,365,319,482,714,257,424,76,977,372,44,962,453,190,841,814,604,434,469,768,48,803,286,346,511,907,261,105,335,948,190,137,424,917,613,1,280,310,926,478,16,728,280,63,449,38,828,865,875,505,178,6,387,691,122,31,445,235,36,450,552,909,409,855,397,847,844,429,472,685,832,237,38,868,41,371,901,388,560,710,851,488,149,913,181,797,107,357,904,847,160,308,692,108,168,84,970,239,514,880,329,942,588,204,135,8,287,235,786,6,87,97,173,24,681,545,531,530,530,511,140,185,302,874,479,573,363,541,921,465,532,212,527,138,839,943,825,761,401,855,349,826,329,853,523,847,203,995,368,341,755,935,727,914,99,155,897,326,916,429,231,224,240,616,960,456,881,505,485,728,860,514,873,440,774,198,616,186,835,436,373,206,888,319,370,345,685,528,74,511,321,678,365,886,84,826,593,322,954,403,657,80,851,251,928,554,220,795,655,447,988,362,683,665,808,697,710,749,188,616,743,578,933,903,725,900,713,896,10,279,144,552,114,106,932,249,496,369,713,136,705,966,426,156,214,65,88,263,689,233,782,928,80,252,33,991,411,362,826,362,219,562,462,473,753,499,332,613,258,232,714,118,290,867,144,811,260,778,784,325,49,93,276,347,169,751,533,294,920,701,944,627,986,690,987,856,104,446,35,628,726,982,793,954,392,56,142,597,343,530,478,239,195,857,817,246,8,928,714,593,574,301,17,153,862,5,244,186,321,740,988,648,325,705,350,587,511,555,945,48,496,259,329,965,662,104,545,236,912,660,719,929,817,739,406,208,373,141,204,953,44,116,163,638,395,819,605,757,178,42,733,407,530,586,102,584,730,585,369,847,961,878,211,631,810,164,505,402,636,755,872,813,674,931,429,144,423,391,686,396,116,45,842,367,818,428,555,260,838,233,539,779,358,951,373,996,564,283,349,590,213,185,548,911,91,248,60,122,555,169,41,894,50,669,628,727,461,682,967,407,165,857,85,877,42,389,984,883,547,988,156,668,238,855,198,46,403,169,963,955,448,175,925,572,298,381,689,871,491,197,359,106,634,830,829,655,923,427,626,240,44,648,859,10,384,252,307,520,95,391,540,512,838,619,725,506,533,948,958,916,688,185,72,276,210,719,890,552,469,13,7,35,465,830,490,491,6,397,838,766,634,352,552,712,729,350,195,754,627,945,633,186,233,171,422,505,898,14,324,517,675,421,136,49,98,97,590,866,122,318,935,694,784,98,80,520,514,607,153,831,5,782,275,773,925,512,357,233,675,251,108,299,888,416,830,437,887,897,948,710,896,747,873,915,439,549,568,155,637,944,353,511,406,463,796,847,747,752,801,267,592,546,330,297,481,874,919,988,913,174,235,624,940,826,996,531,153,733,735,95,443,914,339,3,432,948,694,430,285,220,308,258,294,319,584,449,468,198,406,948,401,460,338,243,704,726,590,344,886,724,430,551,6,259,336,209,611,780,991,621,956,495,275,369,595,643,850,517,679,806,859,496,243,218,384,746,326,465,928,318,275,430,111,0,230,142,730,943,338,501,197,225,891,353,192,617,892,858,188,540,678,871,975,865,294,100,280,460,796,566,752,29,602,334,138,809,120,343,840,853,888,584,253,735,799,122,864,15,588,9,745,371,94,481,971,876,276,832,664,248,878,489,145,215,980,304,50,977,158,697,458,839,966,95,955,194,381,189,628,869,960,977,211,502,577,587", "391,517,974,893,133,16,348,943,308,533,381,363,957,161,218,41,950,485,984,379,792,305,160,337,531,771,286,63,198,160,278,143,874,706,827,974,951,208,81,128,360,489,850,487,873,607,561,789,492,966,337,660,355,997,198,770,247,13,318,498,413,35,984,152,988,588,80,885,822,974,979,900,634,161,869,452,345,335,934,953,932,58,934,878,103,982,505,164,632,683,945,67,372,675,366,817,500,261,518,644,264,627,599,258,659,454,247,154,432,589,957,935,903,343,520,49,45,806,298,172,768,392,80,33,486,998,937,192,555,792,189,433,926,864,472,558,843,443,573,455,374,220,494,711,202,199,163,252,196,456,744,969,964,914,257,533,898,314,362,868,499,170,632,199,408,175,879,157,177,977,175,945,799,547,827,798,616,13,6,912,458,52,951,119,554,239,929,979,932,45,185,365,316,738,19,505,883,503,888,39,897,155,459,450,296,553,694,934,999,4,286,436,228,993,409,173,983,236,12,549,208,933,919,373,954,869,200,429,107,104,174,660,540,684,244,641,853,176,269,593,569,943,956,929,832,350,709,920,815,339,773,619,888,108,168,89,67,824,949,879,383,305,236,974,282,444,405,492,27,841,306,395,237,396,199,911,824,660,378,711,282,298,663,8,220,651,766,225,749,395,311,996,143,307,895,286,42,19,499,611,423,123,54,111,494,962,726,985,746,60,416,636,598,724,409,947,104,393,961,918,23,427,572,981,268,288,955,255,995,775,552,218,921,596,654,21,509,954,725,723,593,963,907,163,328,334,642,923,80,450,299,553,312,610,915,632,881,689,135,666,192,646,312,430,501,967,914,846,995,792,339,563,495,523,899,87,755,934,199,227,461,13,618,263,40,380,798,132,385,662,181,59,965,531,413,370,246,176,939,856,476,705,201,902,769,900,884,905,197,817,434,136,988,221,976,36,938,493,79,51,253,210,281,769,584,526,42,790,853,635,921,153,744,208,280,456,103,33,73,206,842,410,905,41,188,370,826,942,157,712,238,855,592,329,637,43,585,299,938,560,234,628,76,666,763,42,543,245,699,93,417,289,913,378,211,802,666,988,174,389,399,643,630,182,43,811,449,801,549,477,225,522,124,881,18,498,566,823,673,68,107,140,56,677,646,538,199,802,264,234,514,340,27,501,6,471,104,519,611,862,150,913,961,549,45,713,907,887,433,872,361,147,386,115,668,186,936,3,939,922,33,604,942,69,439,735,616,158,960,271,745,733,113,632,733,178,65,268,646,915,708,904,675,960,291,165,783,570,989,215,448,446,844,512,820,67,974,426,229,461,658,196,482,760,879,857,920,465,194,945,741,178,102,880,638,59,443,791,212,54,533,625,356,325,955,400,824,96,396,258,568,959,463,142,90,362,52,899,171,790,809,331,737,139,849,770,932,828,313,436,408,325,173,455,532,430,732,885,191,517,281,118,428,638,361,507,327,433,997,745,554,907,671,201,164,57,314,3,31,895,413,764,831,724,569,131,143,748,816,673,765,417,286,112,452,794,65,984,532,944,94,756,835,806,240,627,114,143,374,174,959,291,422,823,769,818,746,18,743,629,87,900,779,66,37,754,374,638,121,653,132,190,854,743,557,444,4,625,599,474,740,453,289,358,271,701,114,150,693,725,607,634,877,760,328,903,843,557,687,698,548,575,848,62,601,103,664,281,68,869,583,261,605,491,170,929,579,992,569,949,635,182,984,911,694,493,44,691,921,987,45,150,815,286,671,624,956,478,571,110,372,876,730,616,228,19,45,254,614,316,159,301,559,436,217,281,350,868,839,377,229,569,387,141,730,8,29,616,340,43,645,483,848,676,732,171,680,755,184,290,69,873,447,67,256,102,853,212,707,378,228,2,328,966,754,183,566,402,610,33,898,908,575,10,789,601,316,535,165,365,62,425,913,100,456,297,462,582,117,770,268,56,109,494,558,915,105,6,56,746,795,702,993,68,905,870,28,754,246,379,853,122,935,92,809,797,267,153,286,578,740,496,446,204,630,8,378,125,335,627,864,302,901,601,963,527,332,283,312,478,447,906,721,623,446,740,675,230,0,675,143,52,949,918,186,981,801,711,136,198,564,639,728,72,238,293,563,588,463,817,380,402,39,434,632,541,699,396,231,728,616,312,93,290,962,80,864,935,85,418,697,85,951,339,793,272,296,719,646,411,412,659,675,890,355,208,932,733,584,733,432,950,257,669,543,522,412,349,367,170,264,322,942,982,437,738,543,780,289,107", "544,476,919,987,411,109,599,539,603,646,352,996,708,99,303,893,343,492,520,804,416,384,306,490,983,358,757,776,847,735,252,346,58,691,798,44,63,543,340,192,836,27,506,911,447,760,215,611,387,811,172,205,864,8,857,268,529,904,806,555,458,476,988,669,916,77,75,960,7,115,338,320,733,875,4,451,345,715,456,946,423,895,573,768,118,895,899,92,84,445,54,620,733,674,218,917,918,794,117,222,24,385,388,379,468,860,659,947,483,462,21,119,636,845,546,559,647,851,595,272,409,394,120,601,182,844,497,909,591,999,885,945,629,295,727,126,456,274,219,808,401,376,920,402,160,939,83,183,908,954,284,169,229,227,404,713,241,634,102,84,375,830,655,232,979,258,447,598,15,74,416,766,165,794,503,860,642,589,25,475,928,685,823,874,91,80,434,373,378,569,605,768,764,985,680,74,755,649,506,888,780,966,658,195,25,481,864,163,197,852,495,267,319,753,877,722,57,548,85,532,369,578,336,372,564,134,389,63,804,989,619,225,528,807,686,786,975,447,498,79,536,904,930,160,694,120,963,277,504,40,548,535,205,735,309,290,771,627,746,131,775,61,985,54,768,88,820,255,962,359,111,6,644,754,740,98,871,276,705,75,480,771,810,594,473,684,638,772,337,576,102,350,846,651,394,876,574,678,468,948,37,254,952,752,802,917,747,202,239,575,462,990,736,196,792,508,732,374,949,712,314,967,54,34,348,964,881,727,93,465,918,473,604,123,452,520,750,310,661,558,812,30,398,912,845,422,3,661,244,972,758,46,269,133,320,932,626,224,592,184,46,916,633,903,865,183,226,376,173,228,355,268,410,999,5,702,7,68,457,506,795,279,962,62,157,517,731,997,107,144,898,218,911,209,246,361,169,518,560,950,471,848,632,266,53,514,842,626,240,10,298,538,545,721,384,240,921,442,65,624,569,252,140,703,485,383,925,945,993,924,856,668,963,28,636,338,272,623,27,559,206,991,120,454,704,350,948,27,688,14,994,84,654,253,485,230,595,20,435,960,565,747,272,517,899,223,187,451,638,241,44,467,847,407,193,667,348,489,494,933,161,760,749,149,669,908,198,472,187,612,816,85,14,790,121,3,952,802,481,994,763,45,638,229,590,541,368,330,554,445,75,840,166,81,394,139,675,93,685,741,895,289,257,10,626,552,773,839,231,979,244,491,970,20,661,296,746,893,148,491,812,150,120,444,632,360,922,353,25,159,96,236,721,972,686,287,733,46,34,59,473,319,729,150,785,649,266,886,664,340,515,322,520,644,799,866,702,915,21,129,987,692,149,784,809,828,632,863,390,152,83,793,55,90,458,306,680,646,34,3,919,738,775,627,87,213,186,456,102,468,263,716,62,719,428,34,274,250,214,49,57,73,846,478,55,641,546,231,322,397,438,656,519,317,232,527,409,518,385,659,418,667,818,815,948,779,643,518,689,588,908,769,964,567,679,226,901,104,197,876,777,318,526,997,817,686,188,427,647,141,116,187,723,175,171,840,742,945,266,223,463,578,581,69,46,506,796,836,129,541,857,469,575,918,809,291,21,146,902,488,484,92,535,879,244,412,920,322,692,954,957,417,421,643,431,369,471,901,646,459,524,992,379,107,188,90,474,508,915,98,61,694,32,89,289,100,661,521,786,641,702,774,202,863,680,267,669,117,723,94,373,905,697,22,866,289,857,834,362,884,116,962,145,34,852,339,976,931,618,653,390,8,927,383,570,434,160,236,600,212,619,570,519,984,98,81,190,281,979,429,435,475,278,230,408,463,398,605,886,493,71,972,866,121,264,812,190,673,646,287,659,376,657,788,235,667,733,96,504,762,306,932,935,522,576,548,891,168,190,913,341,278,972,318,576,616,525,673,51,943,590,780,380,382,950,115,382,75,437,789,78,519,260,376,414,348,320,727,56,669,316,554,297,11,674,527,471,765,341,678,381,380,727,711,420,646,939,82,710,447,520,602,814,584,51,749,557,271,741,482,827,229,814,172,775,735,470,896,875,787,327,621,904,491,281,915,1000,458,400,89,519,405,317,201,238,15,418,142,675,0,152,560,747,718,939,589,380,140,491,317,265,686,520,655,346,319,861,442,774,647,751,509,640,256,319,156,31,348,814,324,411,728,403,272,288,62,125,36,66,338,556,994,753,369,94,991,551,652,133,854,875,621,368,204,82,166,121,726,979,899,895,174,416,737,874,114,663,714,404,388,161,280,38,811,421,834,584,269,241,35", "521,672,138,408,77,392,209,538,933,167,737,788,726,680,976,401,953,275,76,994,581,640,962,393,270,569,820,894,536,735,832,704,410,143,48,633,947,319,242,668,931,766,293,92,41,481,845,764,836,750,151,987,506,7,18,966,736,902,722,588,784,965,331,707,404,434,779,679,358,815,540,476,610,873,573,995,962,760,414,251,214,891,177,850,489,369,978,440,630,804,204,736,813,12,684,256,578,283,606,575,492,838,478,502,4,432,460,488,691,75,137,111,513,776,491,58,697,670,601,819,80,89,573,635,187,653,853,105,136,206,759,240,938,234,296,922,252,773,993,883,669,835,424,623,834,2,881,120,673,395,997,232,11,42,798,518,585,637,771,550,472,728,539,739,278,962,690,886,998,100,882,65,492,446,293,800,273,91,997,499,718,839,280,54,889,446,759,690,271,91,594,849,508,476,41,474,984,632,706,683,137,360,503,606,92,901,39,357,293,477,987,318,861,55,436,667,937,809,882,985,202,694,874,385,240,424,415,817,42,202,716,511,83,364,636,586,874,821,649,407,33,38,387,76,166,559,83,17,779,508,230,281,917,36,385,205,396,607,716,202,814,395,810,156,511,412,571,280,770,11,127,486,397,377,789,225,597,538,266,985,846,929,788,73,877,268,279,385,903,194,403,175,625,539,311,864,838,707,969,365,547,365,766,959,166,355,702,950,33,729,266,996,929,946,241,313,626,543,436,794,915,125,425,364,408,722,488,435,835,707,305,792,776,233,470,548,22,212,114,87,704,7,295,490,146,756,560,288,230,853,181,869,114,123,259,359,182,227,735,868,312,86,445,139,434,695,933,297,215,145,429,252,718,953,175,816,92,452,979,378,721,826,396,546,75,992,583,171,498,426,457,90,864,15,183,988,566,436,433,251,277,14,955,929,157,938,487,927,233,861,508,134,724,509,667,760,129,74,8,260,843,581,769,542,467,282,338,399,480,839,858,863,628,29,300,870,48,431,164,394,20,413,764,216,926,728,849,651,438,795,929,386,248,941,898,762,79,925,961,613,762,900,85,495,268,473,454,307,313,213,266,543,130,529,506,984,409,432,247,879,686,530,483,671,29,624,823,377,989,969,481,553,646,816,864,718,237,581,33,47,118,144,989,125,536,422,748,864,466,435,652,486,353,218,351,251,706,195,602,879,958,921,177,812,821,622,830,140,552,97,366,232,541,969,289,577,469,966,13,301,378,568,263,313,693,458,93,543,64,449,825,217,949,363,429,781,775,29,627,422,883,745,992,606,439,286,684,522,448,401,773,328,757,796,733,133,421,712,632,283,890,803,544,424,326,325,597,857,288,760,517,180,693,869,736,465,178,132,961,909,153,450,88,196,981,547,646,351,201,828,621,58,347,276,429,448,298,543,993,737,820,58,795,953,975,911,743,240,537,757,486,288,447,866,611,538,84,116,670,62,612,410,788,18,384,259,792,33,933,183,530,151,452,615,654,702,507,977,918,762,474,743,155,979,802,448,194,660,204,952,844,760,432,829,781,724,225,728,619,152,273,969,115,240,919,544,545,639,429,270,220,452,580,534,689,576,492,55,867,504,397,805,987,943,488,710,127,10,813,704,235,304,804,765,633,967,200,558,934,558,554,953,957,174,469,680,836,202,829,955,295,960,724,429,621,967,553,986,396,509,850,402,291,435,596,934,880,288,905,819,190,887,465,238,290,381,376,342,600,690,687,297,181,48,895,866,976,381,265,791,787,52,865,351,602,717,564,664,212,354,874,613,31,469,534,585,201,472,289,566,986,13,872,682,4,100,595,176,596,810,121,533,374,554,929,59,917,900,378,944,196,390,641,985,963,798,46,946,839,712,394,360,658,608,190,471,866,76,667,356,653,384,425,974,193,592,10,301,386,27,100,33,526,989,778,382,148,859,931,471,633,372,208,349,199,14,590,369,113,432,908,123,307,20,105,667,696,190,801,779,463,430,627,893,21,449,170,964,841,835,276,166,963,830,976,13,50,304,852,255,149,709,280,528,43,551,843,98,340,573,89,280,675,520,170,20,845,694,128,641,195,269,912,937,795,143,371,730,143,152,0,72,375,366,779,611,316,397,194,939,453,338,347,301,273,224,494,718,492,61,651,935,618,901,602,761,496,924,720,596,353,435,113,39,388,333,965,288,982,929,700,473,994,281,789,422,23,867,834,471,731,100,881,700,390,582,177,843,993,827,975,372,599,263,267,909,251,290,408,566,857,916,691,351,129,549,114,220,529,972", "254,902,965,739,961,569,545,76,296,626,160,301,74,773,578,187,880,799,963,642,285,329,181,837,103,742,592,255,337,302,809,640,930,228,304,380,550,602,856,126,64,529,60,225,345,863,974,928,656,791,541,614,538,385,853,938,751,712,977,311,859,745,338,632,851,233,917,171,905,205,464,512,49,302,991,625,764,393,51,250,662,283,398,399,399,823,17,785,803,630,738,478,654,176,877,827,587,680,44,912,516,5,392,881,953,372,56,695,36,570,652,130,525,732,392,674,81,649,892,638,572,914,842,210,602,426,387,674,950,740,995,695,157,586,95,381,145,899,341,244,244,157,5,514,651,719,263,284,220,761,863,151,508,869,525,775,940,899,868,682,605,573,826,202,558,161,647,367,318,538,426,760,73,565,657,704,597,974,451,786,971,288,348,965,117,354,45,32,234,910,339,716,775,687,437,867,290,36,384,350,53,643,719,875,989,858,546,534,317,170,87,431,126,142,222,236,791,392,619,623,895,129,809,460,331,787,678,19,539,22,789,418,249,181,37,306,999,702,890,770,19,393,797,504,827,357,115,225,300,841,287,469,303,892,733,180,894,635,898,438,564,862,771,867,706,995,485,364,636,734,919,193,306,899,762,385,341,311,489,602,933,90,307,96,825,316,12,260,983,575,524,91,977,719,574,964,640,663,529,97,880,487,262,865,326,718,367,861,250,640,584,686,166,705,248,455,235,368,660,114,214,421,668,495,886,516,917,757,310,606,467,356,872,542,357,614,491,415,975,27,375,945,221,811,385,889,465,570,355,383,887,114,918,620,570,289,101,32,28,623,800,113,705,587,247,470,7,246,546,343,571,514,299,614,338,419,750,281,278,871,571,841,937,946,566,492,753,740,224,589,407,4,189,346,702,288,108,688,816,463,913,286,467,895,929,921,936,9,396,531,879,594,961,972,6,672,599,171,884,989,711,901,754,124,606,550,705,275,316,473,596,770,87,269,870,250,326,220,844,825,907,669,375,690,798,998,900,7,484,812,843,764,356,249,122,327,623,656,148,205,592,634,381,30,716,247,70,208,417,549,753,621,500,745,59,800,747,217,457,738,256,149,903,68,448,748,790,842,495,688,407,92,800,5,760,32,206,634,160,864,84,936,775,117,409,693,473,362,730,223,26,473,287,995,312,523,977,283,204,952,93,352,258,595,160,482,523,108,667,922,111,22,287,862,330,634,949,724,717,137,881,786,84,855,218,36,709,794,813,20,204,459,680,378,648,327,825,522,250,189,252,616,513,885,979,397,694,982,386,207,691,916,770,143,253,94,687,789,587,664,746,703,611,119,404,739,678,435,394,742,75,596,773,341,873,803,882,257,830,903,54,811,292,816,366,190,287,255,526,656,457,154,730,246,818,783,389,574,10,595,146,384,381,616,319,550,568,16,672,457,671,839,504,149,584,570,897,491,81,391,760,376,230,525,923,314,330,94,923,657,284,97,926,405,427,208,463,369,22,821,177,67,634,595,497,914,450,344,103,347,200,773,962,173,97,4,24,295,995,147,394,400,986,918,67,129,144,888,21,846,646,366,261,667,208,659,888,568,913,411,772,871,873,593,168,929,840,464,138,426,174,23,968,57,231,141,951,406,109,30,844,140,312,119,365,257,587,706,218,325,816,387,505,580,933,529,270,306,381,968,715,517,352,723,809,269,753,779,92,452,945,699,74,855,682,471,377,916,25,546,503,85,417,814,17,983,209,226,231,843,261,919,853,975,959,660,47,177,668,795,610,604,408,235,370,105,52,804,997,160,688,615,905,329,648,196,107,43,24,613,276,691,45,33,438,980,184,988,363,764,442,168,409,486,976,600,900,687,924,419,450,659,169,333,498,74,962,616,366,745,560,199,227,397,295,154,403,477,607,867,408,169,254,378,886,723,190,563,341,676,852,446,120,296,519,391,872,159,969,977,453,811,572,653,378,266,736,134,172,647,626,292,875,504,390,440,806,926,396,348,964,901,991,573,534,764,339,412,275,868,202,880,727,991,946,568,602,334,824,166,128,410,538,980,14,911,372,382,572,399,98,341,638,356,945,100,473,943,52,560,72,0,784,584,350,115,818,670,97,592,344,734,201,445,110,493,872,470,826,850,945,780,48,883,44,441,261,302,245,29,700,246,910,694,588,93,488,221,171,103,515,195,565,49,353,278,332,180,142,941,310,240,574,858,863,509,59,234,143,240,761,564,563,176,600,68,704,532,13,767,611,951,467,659,62,808,559,588,657,560", "215,22,727,799,778,650,229,257,878,436,374,947,441,809,449,757,231,159,785,374,476,504,881,52,401,638,563,445,575,838,776,129,272,979,333,834,939,266,707,210,844,912,684,484,386,288,24,624,834,858,586,352,218,751,358,858,85,561,233,936,735,924,101,976,547,801,661,817,386,919,754,760,775,897,945,458,913,273,462,190,607,25,856,535,72,844,435,553,488,491,861,197,499,743,752,739,995,782,174,149,884,998,219,331,808,957,803,810,833,922,96,975,434,427,272,46,684,445,937,351,306,433,368,467,905,395,686,266,456,125,410,258,930,207,847,502,400,268,762,332,33,246,609,579,852,60,45,594,84,951,53,558,159,361,408,696,588,350,295,190,368,901,303,408,545,444,292,988,590,536,186,871,791,469,450,599,779,130,819,739,373,501,29,366,357,316,47,330,819,402,262,375,523,787,237,530,963,793,450,933,543,817,438,924,375,676,521,928,695,550,247,767,282,133,222,831,232,316,800,359,350,245,765,410,193,369,175,31,947,846,153,476,407,719,158,586,131,87,976,181,590,800,941,478,570,818,843,936,998,815,42,363,920,43,280,665,931,105,505,716,430,142,75,568,189,78,655,935,290,622,384,194,327,548,181,726,281,956,299,828,602,873,6,250,184,430,687,578,242,771,515,95,884,855,785,162,23,746,432,641,811,509,202,479,107,721,394,764,737,617,573,2,444,518,285,293,837,846,555,203,599,937,526,316,825,148,721,767,893,610,817,451,478,333,632,880,176,585,288,359,451,939,447,744,852,627,426,119,14,444,511,258,584,432,635,728,39,743,266,277,840,214,85,264,255,68,847,245,650,572,697,404,591,421,30,193,942,752,868,467,410,422,546,38,897,139,858,968,994,215,915,120,687,342,270,534,469,370,208,190,990,671,620,586,677,778,851,418,114,793,664,571,976,239,856,932,722,857,917,828,493,959,949,334,876,465,626,310,380,841,355,61,356,54,149,93,921,352,874,772,469,805,409,967,681,101,469,959,120,368,287,144,603,654,612,675,371,600,718,499,922,495,286,295,408,776,800,352,599,703,480,114,738,566,910,943,344,111,809,964,320,433,278,727,105,534,122,715,556,967,473,313,420,826,546,396,988,253,516,373,694,822,71,688,911,302,35,187,196,194,423,959,774,189,96,137,357,941,390,861,737,991,297,211,521,394,498,701,608,662,894,950,444,177,279,746,44,42,268,800,32,96,840,359,34,675,442,628,60,887,28,548,964,85,109,495,401,308,905,933,741,719,218,657,237,255,907,117,395,817,704,115,779,528,282,348,851,860,434,560,473,273,612,269,941,205,704,998,82,744,250,486,631,453,283,141,280,218,821,248,727,208,256,619,8,386,112,813,255,145,957,409,787,257,139,861,882,190,79,924,538,601,617,676,261,801,52,588,158,463,967,245,83,635,966,716,320,857,870,900,318,654,743,42,366,767,421,129,721,521,750,418,715,496,685,691,688,215,343,521,263,376,82,40,897,264,539,83,360,79,143,996,615,130,164,416,230,804,388,211,117,942,140,862,809,888,780,808,430,25,806,840,477,579,331,679,862,430,37,323,331,938,857,67,631,833,830,407,720,179,696,869,378,82,133,979,447,810,401,242,108,812,633,256,751,894,203,158,671,212,327,963,703,946,993,885,838,577,455,46,251,560,949,254,61,813,696,460,628,527,434,831,349,149,727,876,529,735,636,52,54,943,139,355,93,918,337,462,957,956,654,375,138,714,829,496,366,982,503,383,746,753,514,197,269,729,97,473,554,715,705,454,1,408,568,113,850,699,536,207,457,530,63,523,239,916,264,628,485,200,944,197,910,357,228,414,658,514,576,348,61,435,758,86,761,322,928,346,789,968,768,826,706,917,229,931,326,395,679,655,346,884,127,953,227,631,139,146,744,83,732,229,829,618,606,754,427,546,563,514,483,205,468,2,184,925,472,971,342,784,859,572,78,459,347,668,953,484,110,379,303,41,548,618,984,365,358,103,692,956,361,851,545,399,308,121,426,501,621,925,635,972,900,788,892,440,748,497,182,466,679,409,459,834,650,632,738,338,949,747,375,784,0,993,670,515,770,902,38,973,708,267,667,419,762,966,116,647,780,94,615,722,174,619,768,256,366,951,147,982,329,512,755,413,958,566,748,395,368,583,336,75,789,653,131,667,108,675,492,692,2,328,829,345,193,547,136,116,797,701,221,886,802,764,257,877,533,41,362,262,288,192,987,376,40,474,492,744,702,297", "559,352,270,175,84,117,847,554,683,213,154,6,833,901,136,294,600,678,740,593,714,75,851,307,740,112,534,887,803,618,632,968,59,972,103,395,551,312,569,737,90,139,21,452,100,260,591,285,112,531,641,484,724,855,809,592,234,22,157,253,924,982,658,311,205,290,657,534,296,975,907,563,719,746,418,920,352,839,852,441,175,35,241,419,30,992,68,888,503,722,466,972,53,413,946,397,316,189,676,837,450,71,250,708,699,124,531,950,450,53,540,604,810,235,570,774,790,151,624,898,621,235,679,282,915,614,629,635,920,366,907,698,34,494,803,686,747,26,288,270,986,515,71,490,849,355,847,281,259,477,485,886,609,229,518,730,691,538,135,503,939,891,656,678,454,491,964,532,226,109,846,328,235,625,201,611,852,308,73,208,532,564,499,979,298,196,332,358,399,54,722,47,599,369,188,213,541,847,855,925,269,865,992,750,23,593,647,445,626,214,636,500,569,240,269,576,750,300,289,993,347,15,263,14,667,134,680,558,87,821,785,496,484,520,347,911,142,457,615,338,845,758,381,677,777,495,569,739,123,255,559,99,888,433,287,144,432,960,934,573,898,328,345,738,467,574,492,449,381,718,656,356,992,264,112,184,35,580,537,504,394,744,395,986,866,434,573,187,203,750,690,78,101,84,342,291,633,366,154,590,369,382,62,323,545,236,909,381,121,260,548,421,208,824,359,329,742,414,532,430,686,12,516,181,648,290,869,55,244,58,604,793,62,838,439,667,310,284,358,643,273,336,345,971,452,254,41,148,350,220,626,796,572,398,423,698,124,487,504,667,952,258,348,905,967,432,717,371,535,121,828,185,793,8,824,232,87,75,75,706,556,508,450,993,544,910,888,658,232,630,243,318,386,204,100,126,719,96,355,717,348,38,926,948,330,765,661,346,449,45,744,647,960,118,896,118,768,611,7,310,27,389,668,235,572,519,669,40,482,738,845,812,122,601,894,836,425,350,311,881,419,701,405,277,452,58,78,840,216,734,949,40,846,824,264,200,98,797,980,810,246,398,759,652,931,424,704,154,184,367,210,773,335,54,372,254,125,17,307,604,177,860,54,547,854,383,80,552,716,544,403,319,397,913,895,909,710,866,46,826,309,596,505,121,677,629,606,191,297,402,759,555,868,266,348,809,112,146,819,291,346,163,42,273,733,210,640,423,445,318,423,264,976,587,482,231,593,286,724,899,713,46,337,792,655,900,772,845,752,74,486,734,325,602,388,107,702,313,293,879,845,471,218,139,287,792,679,232,634,630,598,7,912,461,910,542,172,471,275,132,633,388,745,230,324,399,340,575,419,315,317,553,986,907,124,511,533,69,963,869,63,50,491,239,289,909,769,776,885,202,373,229,319,63,351,746,122,779,21,555,463,931,236,931,408,772,210,578,582,617,58,125,291,89,764,286,408,123,625,599,454,484,555,916,673,996,897,344,400,75,471,574,281,310,801,905,757,728,788,268,980,445,756,100,13,729,951,563,199,479,104,661,798,215,982,851,816,233,674,214,152,874,386,401,758,511,181,562,621,839,436,113,327,166,590,597,715,423,272,322,882,309,122,831,920,792,886,161,919,401,281,636,889,446,852,889,54,640,496,937,165,974,691,815,462,841,364,896,257,658,635,952,156,654,397,95,890,27,203,800,941,152,784,154,525,155,244,708,321,917,388,614,559,480,530,729,91,130,58,508,459,943,958,960,23,181,521,497,529,938,324,205,296,759,245,951,304,546,950,81,659,652,124,189,278,125,311,417,395,619,300,579,379,646,63,966,866,500,38,603,945,371,205,698,145,125,35,670,489,658,401,475,28,158,219,548,574,255,473,996,295,734,220,515,43,861,656,94,63,651,143,500,825,346,600,393,346,14,938,820,287,35,225,744,605,17,467,774,495,511,927,364,527,154,241,140,833,324,828,502,715,754,94,542,377,346,41,39,395,430,921,138,281,296,979,355,478,418,563,254,988,186,373,489,69,357,648,845,468,178,712,532,338,557,920,127,929,690,628,348,736,800,451,625,560,521,968,542,522,594,413,499,551,856,674,259,799,501,918,718,366,584,993,0,602,543,713,255,864,370,936,393,811,677,64,771,496,996,920,597,705,945,185,430,554,493,552,924,917,456,990,134,526,511,615,942,165,850,853,846,819,359,274,176,859,606,980,473,256,397,573,39,679,474,218,811,851,535,763,766,513,638,884,201,998,726,362,726,746,768,224,279,722,652,551,67,399,797,832,130", "184,970,191,752,857,589,542,170,909,460,921,945,296,116,685,968,36,227,137,445,724,306,892,353,332,511,304,51,375,43,860,489,142,809,997,655,224,103,71,217,668,560,463,895,703,848,875,742,50,595,27,366,154,682,196,605,259,976,624,293,567,513,270,101,408,396,531,774,795,852,530,839,99,376,51,611,111,352,943,360,829,936,905,704,16,597,424,373,313,76,467,848,771,725,402,288,239,966,867,990,787,276,694,961,422,179,359,850,848,951,781,707,588,827,747,856,321,196,264,187,260,807,81,960,90,397,675,745,685,571,90,805,595,714,549,219,607,547,994,353,488,310,100,656,476,430,993,570,399,916,199,40,772,895,734,564,613,39,28,89,712,768,435,881,499,105,620,434,610,401,83,319,656,409,948,241,786,436,182,453,608,785,953,334,76,523,606,886,30,574,175,525,476,438,461,592,650,669,996,400,543,748,819,297,470,510,864,324,383,146,97,136,111,720,905,701,607,501,348,739,290,795,300,810,458,388,331,712,582,454,683,331,18,130,74,764,241,245,844,125,77,826,192,273,663,748,315,789,761,581,638,884,614,442,517,816,720,17,597,277,130,546,144,115,725,378,154,925,57,19,939,60,375,516,187,555,62,570,908,637,484,728,345,873,483,889,338,887,410,71,485,462,109,634,975,221,700,390,549,932,905,132,427,445,361,950,315,305,465,503,126,760,562,142,573,368,78,840,473,482,355,500,231,773,782,942,129,751,226,957,151,205,586,976,165,416,730,903,608,143,880,730,34,5,424,144,56,891,280,472,157,549,482,498,48,331,173,81,839,939,595,289,860,343,308,614,561,671,131,949,625,543,600,44,797,611,399,60,649,349,100,195,122,626,918,631,158,363,296,48,674,458,477,23,205,257,887,210,480,460,168,658,938,984,926,608,808,531,129,49,577,205,743,896,152,182,123,235,764,234,393,700,478,831,864,873,844,395,834,858,855,372,451,308,103,338,961,816,444,104,697,382,797,911,687,549,890,801,138,495,904,177,132,247,908,632,11,341,496,48,943,924,797,882,73,701,986,101,110,516,488,57,396,34,999,588,993,807,829,178,415,12,418,565,542,903,16,19,297,88,588,374,141,545,939,488,343,182,945,64,601,592,143,823,222,821,551,162,938,993,714,396,379,656,125,721,467,186,820,550,358,756,815,440,212,764,588,623,202,42,247,271,565,695,413,656,35,471,478,719,73,453,985,922,535,888,841,646,330,895,798,439,3,744,850,315,337,51,348,14,740,345,280,566,10,424,688,508,839,68,764,282,594,951,42,460,59,368,539,609,734,294,333,956,969,369,905,528,828,228,409,274,15,723,926,815,364,416,667,859,731,283,487,881,773,719,818,143,21,85,859,69,195,759,865,163,141,905,700,791,798,146,87,431,392,804,670,461,878,520,974,806,688,995,177,460,38,18,712,377,935,995,509,546,385,336,184,33,899,180,347,273,743,424,42,1000,61,658,63,282,329,854,959,613,257,967,854,23,143,594,628,348,400,95,239,955,6,291,486,435,891,378,26,178,876,398,635,818,729,225,979,543,76,113,33,673,731,506,198,63,7,726,514,209,902,930,227,443,707,508,553,708,905,188,970,661,738,774,584,646,616,852,359,133,998,784,386,60,742,392,666,206,128,819,651,881,629,766,333,610,469,666,751,273,747,185,893,406,197,464,678,737,801,946,8,272,651,801,386,628,579,167,137,43,502,256,733,339,93,464,57,398,164,479,331,593,682,515,852,485,110,983,316,894,773,46,330,1000,128,146,682,610,919,944,718,728,111,990,727,957,817,350,763,988,400,240,774,267,111,57,487,849,917,831,736,283,664,586,187,21,469,916,607,150,951,805,474,892,676,754,581,313,559,920,456,18,227,121,751,535,538,856,91,954,275,500,426,524,76,963,582,326,988,651,390,642,170,322,845,676,836,641,956,374,324,417,460,12,176,643,78,232,624,324,616,467,801,978,405,656,662,210,461,83,791,904,847,896,242,411,615,840,31,726,274,902,525,847,377,777,270,799,977,156,82,876,708,35,259,438,517,610,547,522,417,567,307,197,186,939,779,350,670,602,0,599,368,887,919,733,446,795,514,534,515,534,103,706,85,428,347,109,906,365,715,418,901,148,973,935,957,278,74,624,355,55,557,441,813,187,575,541,377,445,514,706,801,632,466,101,692,103,31,678,520,781,379,256,680,447,634,153,543,457,766,221,958,382,523,514,399,290,942,145,113,136,586,245,64,947", "805,140,780,288,877,546,484,815,928,34,531,40,69,93,148,252,528,626,249,470,721,69,923,110,17,979,416,819,944,619,822,998,909,818,263,90,440,294,46,211,406,603,598,244,603,850,381,740,937,813,432,935,774,113,598,209,605,238,597,352,415,900,327,882,326,194,531,156,746,210,561,841,824,418,975,836,135,960,695,784,319,9,297,280,101,610,75,16,596,871,803,66,259,665,968,437,815,731,982,251,437,656,846,146,83,100,54,496,928,231,213,169,218,39,664,391,15,815,719,357,158,944,538,611,706,114,859,189,499,763,891,335,454,624,736,8,926,404,380,866,182,672,362,304,436,319,811,420,233,4,172,296,692,82,663,714,332,969,845,461,884,971,183,311,85,5,491,598,471,874,966,597,87,94,219,747,780,906,974,383,384,381,928,494,691,503,52,917,124,241,781,846,18,125,485,941,429,479,345,201,702,35,279,872,178,888,496,986,194,298,40,962,352,105,141,607,751,747,985,696,321,701,910,881,592,4,984,601,370,714,761,675,539,897,12,452,356,447,234,152,575,134,892,421,852,449,296,725,586,308,631,235,161,796,455,235,742,715,712,228,375,952,390,847,253,733,644,847,656,565,834,579,650,468,640,963,110,120,6,243,34,590,340,2,393,808,916,668,971,693,270,349,304,136,702,890,140,619,784,417,802,584,858,752,208,540,112,70,707,181,161,343,653,953,113,339,999,86,600,223,578,14,127,300,229,969,808,31,696,473,205,675,825,956,885,469,488,22,33,600,332,4,492,934,10,768,288,607,587,806,346,601,609,631,116,149,48,982,941,522,759,26,819,34,564,973,788,60,584,50,151,660,873,610,145,781,40,82,315,464,957,526,202,559,135,809,982,389,924,441,289,953,158,836,327,690,175,571,569,609,539,709,885,538,881,799,83,402,145,393,965,722,429,744,605,535,239,429,290,229,858,716,134,1000,51,460,626,854,773,149,437,409,565,225,409,67,50,934,667,529,761,70,107,284,622,527,380,122,501,619,257,248,925,264,728,132,645,281,946,191,412,764,303,899,36,929,744,26,947,166,217,101,299,147,411,265,583,469,265,230,646,479,506,94,287,289,845,549,907,71,889,769,774,9,68,429,884,125,287,345,585,205,292,33,68,68,909,693,896,956,230,428,819,811,83,519,504,313,66,156,925,921,332,16,565,238,685,652,592,77,204,348,864,702,782,474,675,879,374,451,125,184,591,949,826,497,122,152,340,89,827,771,388,535,204,74,730,642,268,567,720,831,884,931,662,841,107,509,800,970,728,153,371,296,726,271,904,413,732,208,207,853,145,991,441,143,783,779,898,269,778,193,343,195,825,861,340,906,569,292,290,255,438,863,728,421,474,774,912,857,57,981,465,856,941,338,586,754,114,492,909,402,604,829,694,279,543,705,506,444,241,575,81,687,34,146,168,697,313,966,316,415,20,137,975,816,210,531,377,874,629,933,663,5,371,175,402,372,569,435,15,747,738,427,607,178,344,101,341,731,565,879,538,459,258,210,252,747,702,701,911,917,225,426,198,753,407,334,29,36,128,470,463,172,393,69,710,542,748,7,93,406,110,57,53,99,908,870,766,860,81,320,964,19,141,165,301,297,587,270,896,638,229,106,793,849,157,726,395,834,389,410,756,560,754,805,18,636,899,90,651,519,748,230,810,487,423,605,720,38,732,680,983,109,956,98,322,544,909,487,35,748,936,432,687,793,890,539,244,548,240,166,851,124,526,693,816,920,215,209,799,145,573,445,271,402,822,873,506,823,67,254,955,114,764,286,305,446,384,151,572,555,374,903,727,909,348,251,137,382,800,654,494,340,500,830,668,299,535,843,476,413,146,492,3,91,666,522,957,98,328,50,632,765,595,427,187,701,658,642,329,457,164,663,225,582,330,770,959,37,957,223,74,997,665,890,41,309,118,94,605,254,674,415,154,873,845,576,239,198,697,645,835,552,677,455,641,459,235,144,717,920,674,871,274,275,494,145,101,475,531,588,637,908,596,85,58,990,10,936,820,76,294,804,521,742,377,895,606,7,50,696,27,718,914,742,790,225,981,589,611,115,515,543,599,0,274,560,252,622,217,169,975,471,589,816,970,581,876,138,798,759,202,673,422,242,149,881,835,521,862,654,14,117,614,706,141,266,134,864,54,807,112,41,691,980,621,61,956,203,445,267,513,472,384,227,252,309,923,961,944,508,331,283,486,478,200,284,924,355,378,780,796,372,491,532,669,629,774,814", "737,513,59,861,378,981,350,886,555,753,412,611,896,356,789,581,284,255,484,920,543,466,662,187,707,819,810,129,722,562,995,757,247,657,508,854,209,759,396,544,779,663,217,689,376,384,445,917,516,677,587,551,497,78,508,380,858,963,958,928,786,493,596,825,819,422,742,761,103,708,488,653,991,790,757,45,497,610,750,205,919,442,157,598,85,951,152,483,977,808,419,211,443,565,853,165,96,725,149,486,979,403,407,82,109,94,143,565,415,93,41,957,139,270,122,669,608,752,434,393,111,789,290,79,280,319,236,555,637,252,947,734,897,656,144,12,520,964,369,874,581,592,877,751,193,877,98,118,488,145,982,887,123,227,590,974,704,375,231,920,152,5,287,472,625,422,476,718,405,950,150,21,537,749,218,176,63,427,51,259,88,475,757,887,175,150,569,608,36,666,595,997,397,713,238,130,210,614,52,282,946,768,915,386,437,520,988,639,57,251,432,924,311,437,944,982,446,893,758,627,12,630,89,828,605,37,828,347,509,524,829,803,353,578,493,496,561,707,715,842,882,405,91,297,278,412,418,392,408,611,556,85,833,787,388,631,295,96,78,42,864,973,970,87,362,531,372,729,712,830,43,141,497,762,486,628,270,187,512,337,696,818,490,653,404,869,28,423,107,57,916,844,491,842,880,539,691,71,153,790,461,483,853,390,592,563,266,602,158,888,341,740,435,44,514,664,366,484,995,292,382,361,142,117,561,901,482,727,985,952,136,239,151,55,544,499,327,38,29,957,190,728,573,530,867,890,359,532,730,252,57,946,649,388,419,773,901,400,323,958,416,500,571,235,529,631,131,850,168,875,203,779,926,403,464,437,701,512,783,385,9,159,51,289,698,970,859,434,480,196,293,236,187,9,439,160,669,725,569,328,502,732,840,967,291,385,899,71,670,684,303,602,470,874,337,238,585,530,801,465,857,889,219,542,549,373,271,551,865,623,316,822,716,300,429,242,993,206,24,160,573,901,736,813,654,364,857,142,531,482,325,178,7,651,922,984,251,43,852,235,829,25,180,580,175,960,3,101,23,106,145,970,924,882,301,153,206,876,562,976,979,266,773,417,768,67,960,192,397,538,212,195,682,691,100,227,443,236,726,552,286,234,406,366,192,858,90,773,377,69,470,933,172,783,303,66,903,727,286,461,375,26,795,381,723,702,362,889,421,284,931,206,259,849,1000,683,516,945,187,89,317,813,20,381,835,802,777,556,388,218,399,394,3,877,230,192,312,441,407,959,977,521,117,637,289,320,228,683,660,10,960,257,584,930,604,741,2,738,707,635,495,888,694,498,389,639,335,131,373,398,788,534,437,836,135,59,848,501,602,821,134,454,725,758,829,859,551,281,956,282,270,476,452,206,634,134,427,177,945,671,430,140,331,81,905,919,106,335,860,625,150,671,39,675,985,208,351,557,378,612,44,492,707,574,314,345,611,140,657,90,440,647,752,433,596,338,25,788,5,36,838,962,640,798,979,978,354,75,736,831,340,569,297,73,166,286,171,895,733,198,162,7,247,250,664,84,505,832,212,881,738,396,568,657,623,58,86,719,112,178,371,107,100,384,198,671,583,843,892,203,475,434,113,327,37,873,225,489,874,59,715,462,272,899,937,870,694,35,388,457,827,209,675,994,459,653,307,769,104,26,661,513,86,622,966,511,182,262,879,67,597,237,148,783,108,681,3,256,768,838,789,950,383,824,819,269,817,682,968,358,392,411,558,309,782,112,397,340,575,841,607,748,45,982,236,944,66,569,78,222,249,95,200,797,951,881,21,579,565,932,505,705,325,821,210,232,471,283,594,173,675,475,412,708,795,718,149,631,232,834,818,307,253,929,887,165,634,80,562,813,339,38,630,792,976,148,265,663,177,257,688,76,869,424,847,789,896,802,43,397,986,348,570,20,914,404,794,589,581,976,13,643,153,55,774,228,24,83,520,170,66,990,858,949,121,706,339,704,502,483,314,804,20,187,87,795,660,597,825,628,192,477,416,317,578,685,839,936,992,590,232,114,564,264,255,359,1000,570,267,166,566,221,694,90,82,664,947,891,801,380,316,818,770,713,368,274,0,585,919,300,952,687,262,714,572,752,119,713,801,4,581,349,453,213,580,959,682,351,865,846,347,957,253,96,918,974,833,92,22,567,121,37,328,27,751,387,603,926,846,67,827,570,932,281,814,172,354,845,161,357,637,197,830,897,357,260,709,320,194,769,826,161,625,915,843,997,950,44,897,724", "774,198,213,39,987,572,678,334,662,14,878,907,595,155,974,759,785,159,89,356,342,719,956,617,675,569,471,476,101,961,173,573,527,471,134,307,44,721,556,382,7,380,782,370,121,303,508,630,30,718,178,872,736,967,972,82,410,745,20,111,779,424,375,117,490,459,593,131,664,967,119,356,835,800,572,8,770,314,968,89,161,713,197,840,572,631,199,847,54,509,402,923,969,760,36,194,174,755,602,167,531,248,43,708,922,310,29,364,949,727,65,969,340,578,66,467,444,913,441,534,549,382,737,161,614,633,252,259,562,582,349,500,746,32,877,907,621,458,541,902,482,791,180,710,836,705,599,67,833,535,411,733,35,988,488,493,559,519,972,546,799,927,273,13,90,142,116,920,632,946,70,43,644,112,64,67,544,392,451,730,181,199,719,932,304,44,461,725,145,547,113,429,697,218,861,924,897,3,451,731,584,749,395,707,536,10,988,329,366,837,391,663,258,645,105,611,762,35,956,646,127,860,236,555,232,922,671,261,908,275,940,940,532,700,904,769,822,126,115,992,989,591,541,201,66,49,619,710,859,332,168,639,854,544,50,479,635,960,413,370,262,272,138,168,794,707,118,666,892,845,386,252,637,409,646,690,434,589,395,551,872,616,976,224,518,126,973,175,833,965,468,185,908,671,16,318,387,267,546,485,944,825,395,329,472,766,352,481,725,868,344,907,862,9,174,966,235,657,562,55,802,555,105,869,722,748,975,234,761,187,659,42,832,236,637,178,636,754,805,859,280,800,422,652,356,780,605,157,233,861,326,137,67,192,955,828,167,466,174,787,698,677,611,180,200,158,790,663,165,256,460,584,652,137,851,197,301,644,857,62,404,971,677,183,941,861,683,104,125,515,158,709,163,215,764,556,108,172,70,14,615,972,117,759,394,668,100,192,390,220,5,804,529,313,148,996,283,457,638,791,575,621,425,95,35,732,825,306,209,502,599,588,819,36,613,112,802,205,586,13,173,789,308,801,34,903,423,617,802,846,890,816,8,226,965,781,778,578,480,561,986,144,217,233,819,731,347,346,669,117,915,337,62,920,600,254,601,38,828,133,842,810,695,789,180,211,613,241,527,755,720,778,291,446,190,567,439,423,987,863,200,424,769,317,140,540,453,912,929,547,142,64,34,861,807,741,370,973,535,397,786,246,905,135,350,29,321,328,135,459,986,966,44,671,471,196,778,99,284,240,344,494,519,822,792,70,582,607,896,401,235,191,21,302,448,473,42,720,965,987,128,124,958,201,477,531,395,732,819,587,388,991,819,619,982,105,258,783,613,621,412,909,320,86,781,229,759,62,591,421,566,260,847,549,731,361,629,789,103,852,851,398,999,516,940,635,108,35,286,8,241,707,369,160,417,991,149,707,29,681,328,85,27,193,196,392,120,82,311,581,218,795,318,793,417,184,693,665,248,627,425,10,318,499,988,314,669,792,915,920,139,813,825,105,333,336,533,373,854,501,914,944,714,953,25,656,795,111,87,293,324,635,781,732,165,212,515,823,150,293,899,473,820,685,956,987,881,618,752,132,638,174,77,238,935,196,669,463,90,417,162,366,556,655,12,425,231,607,957,840,23,380,613,548,586,628,696,812,992,837,865,684,812,532,638,294,754,232,92,421,416,835,288,153,41,466,597,470,884,978,776,818,323,689,78,801,72,472,609,994,930,10,337,412,581,983,430,521,887,428,266,70,781,188,416,226,421,131,46,122,358,686,603,747,621,171,497,930,769,963,635,938,138,762,646,812,843,846,12,658,269,923,543,762,577,493,374,276,919,902,322,861,359,541,83,116,298,428,23,92,719,568,760,821,901,571,570,87,736,862,324,561,348,19,85,921,335,942,673,831,155,668,123,515,746,658,665,970,272,931,293,218,603,667,968,36,563,269,194,952,48,57,336,674,869,971,703,232,469,761,918,678,244,752,554,973,594,266,686,733,391,307,746,793,975,569,554,104,781,342,557,969,71,895,968,830,311,392,386,903,759,466,822,327,97,627,29,953,243,963,641,271,760,129,304,609,280,594,6,385,320,448,945,677,349,702,118,353,711,140,397,670,902,255,887,560,585,0,824,596,585,443,140,114,37,705,131,272,29,945,649,809,824,962,980,177,519,933,919,400,559,934,130,224,780,9,279,786,834,697,763,492,49,783,626,153,371,845,442,647,262,875,871,673,905,285,970,626,574,339,725,283,254,903,541,381,500,859,529,632,911,351,940,152,774,61,118,616,766,519", "661,595,694,40,612,213,98,878,809,142,387,214,33,936,534,997,581,979,91,843,15,323,725,668,569,869,547,890,228,578,817,673,78,780,309,94,853,936,251,568,892,568,640,817,657,219,617,970,186,389,670,127,570,225,376,228,591,912,775,343,985,967,747,906,590,411,347,524,102,858,901,570,191,645,617,485,716,752,59,167,688,632,951,897,929,756,584,88,509,728,361,578,638,80,838,598,852,929,200,135,957,91,67,275,14,499,119,893,775,161,370,374,565,982,817,619,733,311,745,948,400,442,446,391,274,903,509,151,962,192,516,619,563,442,996,410,497,850,702,317,918,623,187,169,572,256,38,608,178,168,98,182,877,68,2,10,592,424,862,665,464,865,115,35,542,138,202,505,258,425,817,816,837,183,704,152,876,376,319,445,803,452,630,33,882,747,646,417,854,212,884,376,318,248,558,519,255,431,742,47,238,355,956,815,561,957,727,480,437,98,387,896,682,834,141,785,6,66,538,643,422,839,160,587,468,219,516,83,789,682,832,658,376,388,850,704,821,971,385,483,893,585,300,410,209,516,552,759,184,490,729,332,68,906,617,708,475,397,307,907,264,557,450,569,968,89,604,928,623,508,564,371,127,270,150,163,310,781,430,555,26,935,545,727,561,689,201,110,398,281,544,660,613,575,171,916,246,254,537,756,773,253,148,855,630,645,287,442,58,777,853,563,807,276,653,102,38,234,761,859,396,162,8,473,56,123,365,982,580,45,131,908,702,766,617,275,739,483,979,452,326,468,99,553,579,734,328,234,458,520,103,800,265,547,146,92,222,113,328,812,999,86,707,407,241,660,773,665,587,121,941,99,623,359,598,645,850,728,775,606,666,704,296,78,799,478,768,746,326,546,223,521,960,830,490,165,491,651,115,577,178,449,712,340,438,971,752,103,526,492,538,362,164,37,746,450,898,527,974,605,533,625,469,81,366,241,939,78,664,728,274,657,848,726,259,980,3,370,236,133,566,12,369,10,925,993,34,32,886,764,401,387,795,966,114,931,747,862,392,59,760,661,94,905,475,113,387,509,423,333,799,251,990,139,892,117,520,458,181,996,546,971,415,366,399,725,87,150,737,559,361,783,484,569,213,59,558,781,258,312,871,298,823,998,645,213,14,851,665,566,820,675,551,442,738,7,493,665,331,54,655,658,102,99,855,657,758,234,324,72,847,108,726,303,920,279,85,706,739,164,26,582,727,651,570,81,803,137,947,467,487,451,767,338,149,430,937,54,915,492,13,520,472,645,914,81,923,674,623,148,855,401,531,502,176,986,278,221,525,706,583,352,915,116,861,405,14,609,617,386,548,203,733,293,402,664,310,517,885,307,474,374,684,102,863,52,867,524,81,434,769,236,721,714,496,608,192,812,745,352,707,353,681,725,244,826,321,842,984,91,475,105,621,467,798,330,497,358,245,17,263,430,168,766,308,901,767,381,490,587,730,494,54,593,71,450,977,276,181,636,314,665,362,630,676,666,329,511,636,544,745,716,582,798,993,448,881,63,61,432,890,701,324,82,686,871,992,821,435,675,521,967,315,976,691,511,138,945,264,93,50,474,378,294,282,676,574,897,657,27,657,764,47,668,123,952,820,98,686,800,166,679,10,489,307,801,563,621,710,350,17,432,707,630,608,248,433,291,246,347,926,832,218,150,709,994,630,106,276,553,195,941,780,430,92,320,728,337,240,651,62,735,609,392,270,616,619,836,512,226,780,567,661,97,888,105,319,152,796,500,194,833,700,694,55,10,553,354,388,779,990,40,167,170,879,550,141,300,26,49,735,208,521,854,79,838,573,318,410,44,434,199,744,702,577,343,464,858,571,296,855,658,230,331,312,347,168,728,196,813,280,593,826,926,903,900,550,208,889,501,686,595,496,466,64,976,677,939,420,648,805,298,49,14,487,722,13,515,570,679,52,516,762,340,386,922,409,245,411,756,588,721,527,699,966,677,519,789,502,734,913,719,739,949,386,670,213,874,825,986,126,334,788,654,432,418,479,253,835,198,805,651,300,183,827,748,151,145,358,854,979,114,512,811,526,33,260,192,136,491,194,97,38,864,919,252,919,824,0,288,97,717,36,613,471,928,281,880,158,342,822,446,140,758,281,953,934,773,978,404,762,443,717,757,429,460,45,461,51,151,138,979,441,688,400,439,282,981,100,695,168,871,630,884,675,36,195,325,102,106,268,759,962,423,200,20,996,871,644,297,481,815,211,631,988,86,33,580,571,243", "784,85,381,346,313,572,302,421,410,362,444,218,880,168,697,495,481,364,170,110,430,401,849,570,589,719,572,540,161,225,952,339,151,137,853,758,96,940,619,409,828,23,138,260,701,337,632,14,965,273,348,307,834,51,116,146,829,961,331,887,406,194,220,271,363,425,365,787,92,119,363,616,807,21,295,465,843,997,194,240,537,152,916,291,583,242,19,628,596,670,902,754,575,209,579,310,584,482,276,301,894,257,587,700,847,572,125,30,106,509,623,86,581,408,913,556,694,388,937,64,467,969,100,608,41,721,164,389,836,521,562,812,433,79,424,161,550,805,805,997,335,331,444,462,966,858,372,515,761,7,833,600,714,37,760,299,713,726,330,895,26,149,630,129,853,683,913,930,701,913,537,896,744,956,639,211,579,509,959,699,828,437,300,686,257,824,415,122,527,504,312,781,831,541,844,893,421,889,146,588,131,227,244,599,609,943,891,883,503,524,648,501,739,268,60,734,987,850,869,516,393,620,584,249,837,252,242,865,947,393,572,773,394,773,314,476,46,172,439,708,114,559,5,523,275,847,724,960,376,689,741,355,608,145,526,743,558,119,206,261,944,562,950,500,361,662,818,518,59,597,260,160,855,483,203,641,808,310,589,579,804,356,762,437,794,137,381,697,942,175,746,968,652,307,232,597,768,93,776,681,9,822,542,290,449,672,138,150,891,15,946,510,620,442,83,869,197,69,813,763,516,208,380,811,790,397,646,587,987,323,589,951,561,459,69,517,989,84,535,919,265,409,737,875,593,564,243,902,573,77,482,478,685,157,896,24,230,408,480,604,832,471,877,336,927,329,83,808,643,393,112,41,730,600,957,221,1000,698,7,512,105,621,638,658,652,6,308,604,172,35,297,115,47,922,505,441,963,989,674,717,126,396,737,562,42,396,221,924,985,164,149,677,825,76,352,531,80,147,767,90,674,444,517,468,311,343,377,199,332,209,471,121,756,251,994,394,675,977,168,514,97,31,199,55,647,163,337,228,517,47,30,673,404,388,643,708,635,124,547,759,599,309,907,151,917,968,945,1,152,343,958,784,15,485,99,174,156,480,412,849,20,185,610,886,53,116,397,859,783,738,789,810,993,55,511,485,726,284,442,848,186,889,700,183,3,127,992,681,500,304,430,936,845,285,646,127,677,923,474,734,558,219,239,388,446,109,569,575,876,3,690,625,750,193,486,429,718,693,364,773,192,140,695,596,919,934,427,966,934,484,873,389,686,953,139,309,458,333,382,424,295,811,775,384,251,7,365,838,440,908,563,903,628,424,793,960,694,433,154,182,257,772,366,804,368,623,900,570,598,980,738,968,695,112,481,182,123,948,36,481,82,520,411,846,35,273,29,638,262,744,262,982,992,975,833,909,24,792,909,423,950,779,465,806,136,503,839,236,970,257,2,915,196,713,202,14,252,506,985,26,564,718,628,680,540,869,45,362,104,693,763,513,817,11,65,611,682,451,800,200,605,242,384,890,718,273,983,634,211,149,72,452,653,900,31,350,62,675,572,212,863,200,645,237,633,482,119,291,505,545,607,907,287,251,967,447,723,893,272,943,445,844,245,488,764,146,741,183,542,806,219,566,840,165,224,188,757,663,520,697,104,398,808,564,140,442,446,573,94,900,938,227,861,23,103,503,255,538,838,346,445,931,187,820,817,500,982,480,82,976,449,446,701,373,768,623,907,229,656,417,939,216,523,428,565,151,715,396,75,785,641,567,176,889,399,688,971,463,268,569,734,787,730,472,637,416,963,457,489,10,168,641,988,447,824,4,316,570,500,824,520,92,739,203,717,223,513,647,723,590,491,503,186,565,914,222,834,403,886,775,997,588,552,432,823,211,187,359,917,142,480,924,204,764,58,501,984,153,91,382,302,106,644,397,874,655,462,162,210,388,761,115,945,800,504,370,704,358,175,819,682,88,702,382,781,828,806,136,480,594,836,648,353,254,960,367,798,10,952,519,742,877,864,893,870,249,415,513,475,908,809,200,495,742,454,54,294,408,223,875,491,922,25,371,809,343,895,395,479,43,501,119,199,51,464,321,77,617,198,317,939,592,973,370,733,622,300,596,288,0,854,540,631,523,48,637,940,427,183,446,156,261,526,3,763,723,275,270,383,57,843,248,241,650,599,854,523,891,504,219,537,229,713,939,351,123,303,469,915,330,609,433,940,487,18,295,892,498,283,902,223,565,573,561,699,747,427,839,827,675,936,962,282,300,605,613,874,485,298,246", "206,601,534,963,8,239,503,543,121,412,129,853,3,191,963,21,783,280,299,647,254,657,521,69,501,344,932,732,746,948,519,137,766,805,134,246,243,495,544,502,103,589,295,175,383,58,217,863,893,272,729,342,364,923,745,902,700,978,43,250,966,881,434,365,263,939,660,239,635,975,423,691,937,430,824,93,19,115,376,205,41,62,778,566,32,523,682,177,977,441,300,322,878,583,83,917,688,41,799,105,794,503,860,561,216,131,171,353,60,357,847,437,421,669,51,597,549,225,56,319,127,933,80,708,617,313,9,965,142,935,598,449,4,419,323,397,696,129,206,792,817,400,828,427,848,130,922,372,375,324,402,715,900,73,607,563,521,66,958,332,514,948,469,968,141,925,184,168,916,164,651,267,167,121,426,847,610,691,768,129,776,173,794,310,677,143,971,337,271,412,968,513,598,909,233,746,169,678,529,241,661,133,305,843,193,560,138,320,257,41,332,626,647,697,678,187,430,429,359,251,663,268,658,725,506,988,199,213,743,230,912,929,888,498,906,815,604,177,159,578,885,687,249,67,805,208,771,709,868,304,720,301,785,559,879,201,22,868,600,90,991,119,358,864,357,409,540,738,523,583,891,198,154,350,354,273,185,445,754,403,96,262,556,746,256,18,159,88,362,754,245,744,267,798,511,320,237,880,100,290,541,594,713,327,979,716,46,314,50,458,265,431,782,861,776,233,208,195,289,984,132,735,392,398,845,863,562,762,75,604,3,638,288,648,316,573,18,838,711,968,157,432,630,229,550,517,829,610,42,157,961,432,255,652,988,1,560,45,665,562,730,94,126,746,486,731,827,685,90,688,461,748,989,15,335,341,882,380,663,526,421,772,600,470,602,357,595,30,206,425,799,417,162,991,72,136,893,23,435,150,75,955,138,352,124,859,195,505,695,217,406,612,43,485,311,51,758,399,751,406,548,502,495,151,388,38,489,952,328,422,156,856,763,94,306,663,530,533,896,725,177,894,884,996,334,304,689,718,746,93,327,463,895,44,318,616,627,815,739,780,606,505,669,665,27,987,171,751,311,872,884,792,283,365,636,515,120,347,609,393,164,243,633,278,30,61,282,213,845,621,917,608,721,331,549,42,174,212,827,770,57,578,260,684,690,568,989,137,350,398,89,228,266,627,617,562,369,121,386,57,882,823,911,612,884,131,697,595,999,701,669,361,858,568,629,440,268,233,662,710,743,754,461,441,109,920,565,928,930,777,985,163,466,124,339,681,318,923,965,135,394,636,180,449,854,98,109,146,992,289,656,461,877,531,904,685,795,937,350,537,372,667,85,139,505,263,750,616,495,945,165,573,908,910,881,957,458,723,460,36,896,233,176,507,245,957,120,683,376,270,348,61,772,504,955,634,582,471,235,897,814,265,265,375,915,944,251,267,759,776,840,31,747,871,800,770,291,74,693,436,442,187,586,373,104,817,25,45,498,789,473,398,735,677,69,260,446,256,571,104,511,635,753,855,87,395,280,902,688,482,705,431,290,868,861,348,637,505,536,377,123,560,277,605,820,93,637,511,791,926,911,396,147,693,615,540,767,152,600,810,939,985,625,424,757,55,751,407,384,425,270,81,284,332,749,906,221,904,615,766,935,636,857,796,907,77,67,660,178,780,510,495,321,398,754,302,707,573,831,962,814,4,585,250,694,751,42,255,396,416,387,307,216,510,941,861,929,712,357,542,673,742,138,439,529,886,157,181,971,293,86,588,824,341,363,790,342,217,662,206,627,715,102,860,397,163,196,364,616,589,498,207,44,929,751,774,714,632,118,642,654,866,117,49,78,293,109,763,458,167,542,234,820,857,400,753,479,571,299,96,166,558,508,969,418,287,146,494,681,75,679,850,654,47,993,825,414,72,9,960,571,6,69,76,156,43,818,630,575,303,708,339,612,238,293,362,181,180,703,438,447,618,117,5,509,944,806,59,28,590,618,358,416,150,187,585,42,693,951,45,21,74,60,139,598,991,93,969,473,906,696,491,734,668,115,193,316,657,672,619,475,771,388,221,840,752,152,791,742,609,586,284,696,870,288,74,596,892,564,265,453,344,708,936,446,217,952,585,97,854,0,547,487,861,868,444,105,243,803,651,563,427,245,956,574,906,95,553,28,778,563,737,700,211,361,433,801,367,484,992,39,51,537,519,605,585,144,17,960,149,735,996,740,447,314,853,130,539,196,816,743,200,999,937,484,380,202,625,691,394,436,357,393,799,922,675,807,550,479,422", "345,341,970,861,855,522,792,234,478,882,307,895,625,450,782,887,68,378,174,753,232,386,449,977,854,531,837,357,235,743,352,110,337,418,569,17,58,214,251,162,529,470,387,183,165,895,801,932,699,288,829,301,800,911,477,722,611,643,276,814,17,293,758,65,831,850,79,630,86,183,345,653,397,490,717,454,903,334,760,174,885,513,437,66,437,562,527,259,426,274,48,776,5,236,410,328,415,171,910,782,887,695,156,796,838,837,758,367,927,801,370,438,349,751,754,757,33,888,884,677,672,859,184,721,232,295,389,126,870,929,90,592,836,325,169,485,833,344,591,653,615,665,342,817,507,703,109,361,260,880,986,753,751,196,227,796,240,257,288,735,965,700,680,532,709,295,1,897,926,698,68,356,319,126,292,416,738,986,25,143,447,382,238,291,217,782,329,476,486,836,264,553,439,156,845,473,531,769,253,909,313,85,749,144,502,589,112,292,791,916,707,880,136,740,220,111,336,881,707,229,320,691,519,205,420,977,702,346,562,218,835,239,49,76,999,794,956,659,856,626,775,326,464,93,200,104,821,516,86,6,155,209,888,943,626,533,420,505,173,662,423,40,306,120,698,673,611,82,332,160,162,650,694,873,168,804,513,835,237,432,721,20,240,22,164,830,53,909,984,202,352,914,777,983,753,446,917,894,852,153,435,635,401,447,754,778,756,393,786,996,597,835,792,65,125,558,310,441,836,963,834,198,185,163,763,770,875,371,943,120,873,275,44,346,749,784,855,537,86,9,274,682,161,959,614,714,771,23,278,898,974,52,393,32,495,206,581,962,704,263,182,649,112,919,824,400,224,733,232,855,389,15,311,183,672,168,713,996,383,378,842,454,338,360,279,442,484,290,935,749,906,95,226,756,332,576,889,151,157,800,89,215,960,659,121,356,148,330,3,106,552,472,764,875,204,81,390,291,763,675,156,699,105,291,515,494,527,237,735,908,190,977,688,924,358,947,751,49,573,123,683,110,477,251,278,185,274,938,424,348,414,803,903,252,695,964,327,435,191,124,909,491,350,205,186,809,226,902,371,643,310,181,689,447,194,459,45,686,939,535,948,950,887,467,414,435,11,832,590,735,438,6,91,433,4,627,897,463,982,736,973,838,601,891,936,77,450,787,789,946,553,234,664,539,396,409,458,93,728,229,528,263,391,83,361,265,512,487,590,776,450,669,163,58,364,54,298,849,793,143,227,417,749,640,861,180,676,711,867,898,875,849,806,443,940,727,434,391,377,148,572,225,987,702,253,492,850,236,73,465,411,745,94,850,546,213,226,671,151,15,751,719,392,640,431,391,762,59,789,161,108,537,946,48,903,473,409,140,197,405,453,660,874,136,906,282,787,676,809,944,787,885,974,399,575,605,802,976,731,653,484,974,445,425,530,260,336,230,323,292,181,929,651,634,679,223,220,119,103,694,340,276,423,655,157,565,663,639,811,258,207,999,782,16,915,120,305,785,769,336,996,162,266,544,568,751,535,758,938,658,173,963,255,328,301,781,657,923,433,177,916,287,729,232,72,130,136,647,696,439,381,409,640,247,394,466,944,883,39,439,114,73,430,610,712,628,472,714,284,234,56,657,977,292,166,942,151,692,90,871,586,135,886,810,315,229,94,817,773,261,786,801,774,543,670,942,621,548,556,457,836,72,223,349,98,155,440,626,609,134,217,817,462,105,184,252,779,154,563,319,71,739,269,115,319,71,488,185,898,416,268,653,67,884,50,917,314,546,733,440,839,50,460,304,82,947,494,909,64,458,437,983,518,839,13,15,21,512,762,607,634,380,775,1000,172,296,452,951,586,957,665,567,774,495,646,512,309,989,202,734,716,896,62,179,643,251,47,43,114,407,149,32,835,373,728,532,936,19,127,94,271,1000,450,440,715,512,721,939,991,648,117,633,778,139,612,160,218,994,746,903,363,531,55,352,614,330,778,793,670,104,980,975,229,136,633,101,33,728,794,828,725,612,556,86,689,982,270,366,365,638,314,670,780,636,839,683,146,68,272,875,676,722,923,920,251,879,101,687,782,922,558,208,257,871,375,792,283,858,639,686,338,734,267,393,795,169,687,443,717,540,547,0,914,612,34,394,742,561,591,420,883,932,618,611,898,929,149,756,40,227,999,179,572,903,834,243,67,656,796,221,970,791,425,510,550,180,676,107,587,850,605,654,580,875,928,580,109,682,212,900,501,267,578,680,500,711,551,123,953,502,115,459,67,712,703,714,66,636,264,860", "994,719,20,481,543,559,528,231,514,727,921,692,933,467,218,366,600,682,696,381,886,40,798,818,667,783,427,526,123,235,764,667,805,987,656,790,960,258,265,16,335,52,690,845,716,806,471,745,137,338,964,494,776,37,84,715,586,956,612,440,830,341,613,190,973,290,182,609,25,836,892,321,744,194,479,621,471,561,889,110,894,510,747,79,853,638,322,134,752,812,734,708,274,693,410,338,693,948,429,267,616,495,155,538,571,514,516,910,350,264,89,243,651,295,571,429,173,577,447,830,353,724,36,767,608,922,166,911,476,725,689,909,125,584,52,745,123,740,600,185,839,753,823,503,948,812,524,778,443,138,81,972,63,562,287,511,442,322,608,258,284,841,237,827,246,607,546,438,321,234,659,846,466,25,643,346,347,792,770,812,152,53,977,378,461,246,623,737,655,643,915,65,102,220,984,407,974,899,795,333,542,462,305,381,159,389,570,891,183,249,775,187,834,109,293,966,499,809,898,672,992,288,603,305,819,821,625,827,772,743,696,64,959,726,862,121,259,397,276,874,940,953,672,544,425,878,492,658,100,212,802,187,71,974,463,649,574,376,836,137,24,942,967,503,391,157,443,277,463,687,196,781,47,144,96,118,244,367,793,516,202,771,218,878,381,974,209,463,789,596,288,243,570,92,215,874,576,616,157,454,434,537,202,693,782,463,949,699,935,23,135,641,816,456,998,847,828,169,179,734,251,977,766,545,748,304,178,495,887,803,154,468,249,250,926,443,495,105,802,375,464,436,887,995,141,667,511,44,550,379,839,451,188,91,915,408,923,270,319,444,662,925,926,509,27,610,326,156,508,924,235,671,506,782,357,446,509,703,148,663,297,463,972,414,545,685,457,744,765,499,81,170,721,902,347,770,316,699,922,185,437,173,2,741,848,207,537,146,472,396,29,636,823,223,740,886,249,236,171,483,152,779,519,199,507,875,3,830,367,510,999,37,828,94,555,124,53,585,831,189,494,436,728,502,519,724,55,340,507,571,874,557,525,499,803,322,305,293,11,299,185,661,480,64,696,74,121,753,731,146,353,569,30,342,1,454,633,489,823,132,713,253,188,814,571,485,317,909,20,95,500,919,577,161,243,119,734,896,137,430,276,44,157,920,209,486,740,469,660,751,600,781,419,790,292,651,186,84,425,448,212,252,904,298,313,294,601,603,961,344,834,928,877,357,551,690,355,102,476,82,648,521,124,356,304,892,351,616,463,393,229,164,793,734,828,896,728,855,52,18,882,714,862,525,275,92,780,706,235,728,420,756,346,4,972,689,455,536,700,172,143,240,337,419,478,553,819,111,116,10,374,937,960,887,459,440,914,321,347,632,553,732,424,658,932,62,696,868,445,298,972,439,698,432,591,843,232,338,873,911,129,603,100,563,901,814,86,759,924,441,169,269,881,713,449,230,944,917,232,246,625,525,222,537,199,327,657,420,7,505,594,392,790,619,417,987,220,381,932,256,295,172,460,262,301,375,96,715,692,795,47,432,94,419,607,875,486,96,340,731,735,276,1000,947,670,996,55,229,506,80,144,101,991,138,230,319,535,577,473,812,860,552,874,318,413,373,749,536,356,631,166,679,321,425,981,410,476,54,950,965,822,216,470,413,635,638,857,402,433,770,638,25,612,953,605,617,279,574,388,697,668,966,284,834,461,575,93,972,550,283,356,512,8,270,638,937,467,755,742,816,736,286,112,567,550,593,923,149,755,611,565,724,492,211,665,785,147,763,794,660,285,973,421,528,981,939,423,946,692,92,220,63,28,350,142,195,911,729,363,903,501,646,870,526,771,310,41,272,169,102,243,470,572,970,786,164,675,285,76,105,483,388,819,255,60,589,66,356,634,73,659,706,725,889,433,208,668,274,186,21,672,396,849,449,38,452,56,189,420,333,181,30,394,702,392,114,673,224,802,982,695,646,722,408,172,552,321,663,121,287,228,914,719,2,391,612,73,327,849,521,449,829,627,811,856,494,163,319,249,194,785,939,41,564,374,878,167,669,981,531,473,936,899,749,313,379,190,552,729,784,455,64,63,498,170,455,740,188,728,520,347,201,667,811,514,975,262,140,36,631,487,914,0,14,184,70,231,422,402,941,554,485,196,881,647,453,400,778,206,639,11,158,209,224,727,471,635,958,11,326,48,137,54,876,23,192,721,780,650,165,923,187,336,109,373,336,232,398,755,962,536,425,379,979,123,332,102,749,418,590,973,7,903,239,369,768,937,93,762,920", "238,608,39,800,461,932,681,687,791,698,414,351,433,490,317,252,876,346,298,31,449,173,353,717,803,752,859,670,652,874,852,939,748,365,70,630,162,531,516,184,90,934,209,167,527,116,373,536,400,251,845,913,363,957,365,23,484,746,791,194,358,246,269,399,982,20,574,301,261,445,833,367,549,58,797,612,985,205,343,104,608,971,465,688,300,74,9,581,109,891,656,159,81,213,517,831,576,499,315,898,498,765,173,264,550,421,630,738,881,587,958,972,443,657,975,620,52,366,24,927,754,244,141,765,650,545,645,560,165,154,233,881,989,696,516,523,203,61,18,689,552,88,862,655,868,469,255,390,247,527,946,560,985,927,305,807,251,775,773,466,622,978,583,969,119,205,202,672,545,500,378,392,632,503,396,964,93,328,67,784,229,279,410,426,472,492,847,746,378,287,151,486,383,121,504,331,356,130,248,807,541,14,628,497,216,590,38,500,920,572,799,446,816,602,33,618,936,566,131,114,609,345,694,759,602,338,411,230,426,708,718,790,209,851,83,507,456,47,156,762,110,527,537,596,24,997,985,113,251,346,422,736,550,416,833,964,517,216,777,288,743,995,527,386,886,452,173,984,403,663,603,771,56,847,744,779,482,936,922,364,762,444,464,780,577,495,968,412,553,681,758,594,844,699,720,714,930,359,737,109,151,448,399,397,309,566,203,369,540,498,730,771,178,749,518,270,533,187,72,462,246,449,616,851,293,781,307,89,134,9,507,197,303,28,343,195,377,965,292,770,416,551,393,561,382,237,259,652,666,359,870,33,18,664,213,882,870,389,202,536,46,275,980,302,770,400,46,185,589,217,144,429,618,199,787,210,821,533,271,410,291,452,998,37,656,796,37,305,412,180,451,488,730,666,728,66,887,29,832,975,587,366,551,880,916,985,948,613,404,473,361,879,780,336,913,233,990,671,423,834,126,372,202,989,902,843,823,991,809,864,44,330,502,453,141,53,654,793,493,42,668,804,957,113,940,457,732,618,28,792,438,552,50,962,570,478,221,50,542,474,99,269,369,419,911,478,389,42,929,511,149,287,399,463,237,700,579,757,9,668,261,879,402,706,79,746,450,573,426,918,971,505,717,262,691,309,450,421,120,551,665,696,713,464,132,952,893,38,489,973,295,516,850,735,657,578,627,284,932,857,588,679,687,50,835,201,385,155,383,386,682,988,348,221,322,534,338,961,73,634,831,394,594,672,90,272,526,877,966,997,162,568,251,477,205,181,766,398,658,878,289,319,676,107,832,359,821,622,789,997,246,511,644,773,190,343,670,449,861,353,650,413,5,590,468,565,98,384,180,373,382,308,491,354,571,9,788,758,992,597,224,9,354,15,38,651,574,849,973,907,764,318,612,347,966,350,981,607,983,847,666,472,237,885,860,945,797,102,998,462,707,989,463,112,864,70,768,650,41,840,60,103,99,489,169,544,891,581,486,477,632,382,801,192,628,680,759,87,889,8,592,888,948,833,200,727,978,700,762,769,790,293,18,409,208,435,523,254,680,848,381,122,890,764,734,240,330,299,984,437,180,893,903,268,481,373,723,548,524,884,654,339,190,886,40,569,687,68,663,348,627,542,183,787,267,365,818,981,378,952,839,995,513,458,625,845,565,617,30,209,482,501,573,692,748,831,361,457,768,958,312,670,197,17,363,98,223,498,538,346,184,601,677,519,514,626,543,548,37,983,284,682,251,501,255,767,707,102,27,399,602,488,578,447,652,211,388,11,603,2,360,344,21,465,456,97,632,874,536,257,466,86,583,16,993,342,443,907,265,994,521,517,799,428,383,864,737,769,107,14,607,504,112,372,444,692,593,525,23,935,484,968,38,226,803,368,485,873,541,424,231,724,889,581,59,462,571,741,470,464,450,413,325,889,318,319,584,109,696,887,293,784,805,543,691,885,655,378,167,848,710,10,733,46,969,543,926,854,659,256,350,912,829,644,36,678,173,421,472,50,270,410,736,682,62,80,903,390,853,376,905,430,913,482,926,913,816,267,594,258,862,724,297,221,646,854,581,11,714,401,675,235,517,706,330,31,158,540,72,655,301,445,419,677,534,471,714,114,613,523,861,612,14,0,990,810,872,598,182,96,295,588,664,12,802,804,519,601,249,785,905,608,704,227,943,128,397,193,60,34,629,673,532,288,137,166,70,693,243,224,462,714,716,396,73,542,167,54,724,637,808,451,596,785,575,590,80,795,602,908,987,107,910,593,222,188,997,617,508,916", "979,663,952,907,724,672,137,732,436,390,131,771,430,32,931,86,349,26,336,566,269,11,984,68,118,430,18,463,971,4,516,115,708,193,570,137,249,221,754,248,593,597,81,133,532,307,315,32,331,904,620,980,567,334,927,686,657,531,134,285,102,566,940,367,474,733,727,293,413,621,18,744,601,721,917,15,398,493,944,339,130,819,37,768,146,171,525,347,136,498,295,399,264,756,541,743,812,117,659,446,52,777,710,208,186,472,977,886,519,848,136,191,267,853,199,447,599,111,147,319,827,505,733,386,529,129,219,326,401,119,610,197,652,23,841,551,719,479,998,317,870,497,878,24,820,114,362,646,815,137,103,895,493,622,619,866,269,745,447,124,594,52,3,706,446,550,843,244,441,14,751,215,416,809,60,686,542,636,986,59,142,961,477,144,769,655,143,895,783,326,691,363,505,815,328,485,773,828,451,603,253,40,495,224,851,820,231,174,457,630,474,326,925,240,926,378,306,427,784,834,106,838,188,114,930,349,188,686,507,238,523,22,106,847,81,330,76,479,797,85,722,377,753,95,612,58,956,768,190,918,550,831,390,90,605,721,988,87,239,227,37,756,7,973,243,719,862,540,119,68,62,97,883,143,986,93,752,429,292,885,346,961,397,428,579,829,561,235,672,477,78,231,101,454,285,692,78,816,565,890,492,349,3,867,619,780,413,608,386,137,723,697,266,527,966,912,267,267,251,650,824,946,807,952,342,348,188,721,337,624,370,262,26,380,904,414,493,268,664,407,363,57,519,651,438,456,99,36,268,607,980,332,661,689,227,553,421,673,148,880,823,702,182,710,271,883,344,794,293,876,437,851,170,31,415,775,896,608,450,299,398,695,404,237,78,416,883,658,354,821,181,370,906,38,898,552,757,282,842,323,26,343,463,551,773,450,360,594,437,294,168,806,911,926,771,146,200,680,128,384,307,203,326,901,530,266,14,332,264,287,131,349,895,151,163,449,452,911,119,161,924,556,117,281,67,265,582,686,183,205,147,758,31,846,346,512,300,764,977,21,473,483,61,24,87,888,921,168,718,816,269,980,82,738,630,819,735,766,206,660,927,747,89,143,356,367,336,132,694,914,941,562,309,845,363,963,510,186,97,192,439,47,791,276,540,590,431,621,651,178,302,647,658,991,480,335,561,834,784,653,110,693,367,517,944,194,76,185,680,398,110,118,20,960,247,274,830,911,262,659,919,19,691,631,859,790,61,526,886,829,433,511,103,338,817,100,667,992,652,147,450,475,31,147,418,894,488,919,55,361,854,802,426,413,595,575,185,57,553,559,917,927,503,992,692,776,970,987,350,961,716,653,317,262,270,741,31,758,489,796,265,792,626,301,530,727,941,136,988,889,692,305,655,205,486,757,498,710,980,680,115,932,865,335,258,862,560,508,460,508,91,803,412,631,956,101,188,895,119,907,806,894,121,379,424,137,595,227,122,681,102,583,650,5,782,461,457,254,45,733,289,97,686,842,122,159,233,965,524,460,863,443,666,253,438,885,100,298,979,157,618,506,605,113,506,627,550,46,221,396,344,301,280,723,24,104,492,283,288,96,766,211,645,41,853,166,723,44,249,18,180,28,993,249,52,36,374,933,163,359,402,100,976,330,697,945,440,799,540,133,909,322,165,109,711,315,365,228,86,551,252,993,23,910,597,952,710,107,482,829,582,315,457,765,798,668,944,160,299,314,846,302,787,432,36,556,139,98,512,18,655,2,127,65,167,212,699,415,546,147,21,182,846,345,233,253,526,119,678,884,199,846,850,556,524,617,96,371,867,654,854,211,315,95,695,505,622,693,649,291,842,442,567,969,878,564,159,727,410,259,368,723,516,807,386,616,987,62,393,341,510,794,733,18,990,644,569,778,460,865,31,10,956,204,315,753,282,957,286,197,665,521,973,724,405,456,633,842,766,676,431,5,800,52,524,165,331,546,187,506,663,926,112,288,419,265,487,452,711,259,227,590,335,285,933,460,712,181,484,657,422,770,195,408,174,186,552,182,793,180,86,450,942,671,245,261,857,491,268,159,896,973,770,270,811,57,466,678,238,346,273,110,762,64,515,589,572,37,471,48,868,34,184,990,0,676,237,577,448,315,216,310,105,248,342,354,226,134,344,276,287,802,122,808,91,90,613,113,8,935,87,780,170,341,958,722,323,780,249,315,181,41,239,160,29,383,137,590,145,513,201,718,926,872,890,422,199,516,367,651,793,392,75,44,370,116,291,929,923,353", "394,861,195,122,511,394,733,578,918,713,509,494,876,609,159,256,736,394,22,578,765,767,775,883,355,843,626,42,857,952,481,653,154,755,584,552,458,2,751,822,941,19,937,58,693,505,314,783,144,200,91,595,812,50,232,266,359,725,749,770,527,469,552,235,176,429,777,872,730,960,500,980,695,54,682,38,315,570,236,847,831,701,917,124,41,410,387,151,649,440,158,359,483,434,357,893,360,786,380,323,309,537,783,64,576,29,188,772,21,803,167,391,189,890,130,64,203,498,655,74,24,562,472,730,832,506,325,862,854,136,593,522,800,124,766,148,76,637,35,776,508,134,498,931,434,503,958,213,988,638,171,272,406,854,350,597,423,841,874,595,979,758,711,762,848,56,61,837,14,35,67,105,296,309,366,717,686,135,405,829,181,373,715,281,867,93,650,946,874,814,416,796,876,427,34,627,73,741,79,124,166,674,294,632,692,188,110,722,347,34,598,525,307,640,690,491,912,310,653,144,475,936,558,44,754,871,159,804,32,189,495,61,632,573,157,405,244,50,943,763,593,467,323,843,579,958,543,110,338,97,534,921,988,636,554,247,474,456,724,201,701,574,172,32,536,95,899,578,21,982,142,548,161,510,704,614,813,51,103,349,398,387,833,34,86,230,227,866,375,95,85,863,362,163,823,946,852,583,91,678,65,436,215,438,218,483,310,252,763,44,101,113,968,261,921,572,518,180,614,566,541,530,747,603,425,337,339,904,325,572,442,760,84,17,953,640,297,441,751,997,116,10,996,640,269,87,263,7,986,619,720,974,414,191,855,971,659,987,146,358,136,820,329,107,830,483,119,10,487,561,746,639,666,545,383,237,719,524,384,861,858,583,692,816,315,824,561,198,951,333,693,48,195,620,741,168,27,364,572,29,203,173,253,669,216,994,918,393,978,964,846,847,316,117,951,892,960,589,845,449,724,287,595,254,11,370,186,254,465,35,706,782,339,818,890,701,842,674,503,848,165,470,71,682,844,588,614,34,175,234,259,447,133,840,3,957,613,670,575,751,876,183,676,463,978,414,155,392,376,779,706,628,592,580,394,332,597,219,160,164,558,297,995,779,31,281,687,652,549,470,934,966,167,424,150,346,808,71,211,418,817,243,666,325,200,622,671,55,921,285,510,232,132,766,577,308,146,906,628,134,634,768,627,623,549,690,549,746,183,596,872,906,620,416,299,691,188,113,465,540,456,221,110,771,969,199,300,920,457,52,699,278,316,105,815,907,376,101,703,27,867,47,6,577,326,829,450,355,192,850,140,908,413,712,354,956,940,828,860,847,138,968,739,67,34,923,842,191,534,962,890,737,653,404,95,123,198,257,430,22,311,140,85,418,161,610,324,463,130,235,500,623,487,156,293,624,451,91,147,831,579,530,761,483,824,474,964,229,367,975,957,205,15,587,148,924,774,56,528,985,103,937,100,921,623,714,337,558,357,718,498,613,621,606,886,785,171,564,595,968,320,34,561,535,865,689,642,159,669,643,203,657,560,228,774,134,767,672,743,193,546,911,319,318,86,238,523,421,769,814,340,911,396,403,28,12,685,401,876,990,974,2,791,676,832,94,140,746,556,497,417,392,546,780,779,997,205,68,156,4,750,958,373,143,898,671,822,900,898,741,83,780,112,110,222,726,560,89,68,391,279,726,350,672,129,183,978,239,269,154,173,31,353,57,136,837,231,803,199,216,362,389,542,85,388,494,762,706,631,853,844,744,694,763,499,877,839,350,484,765,341,59,498,678,245,466,901,411,15,848,150,686,721,651,260,981,79,775,250,20,955,226,974,741,36,135,874,604,645,87,654,899,675,789,214,197,941,838,264,610,672,920,385,385,434,145,284,327,225,906,324,181,948,559,349,152,170,68,227,370,578,273,683,250,125,746,725,390,237,735,24,67,380,508,404,400,957,921,865,756,767,181,687,304,164,130,344,554,207,384,429,627,352,345,348,20,440,396,105,36,957,324,888,340,523,836,450,118,361,246,468,101,127,402,804,676,719,710,92,715,74,216,377,70,592,820,153,146,307,807,674,764,432,609,643,887,750,871,293,319,224,493,966,771,534,816,752,705,928,637,444,394,70,810,676,0,37,322,21,991,594,29,641,506,448,398,348,461,30,834,746,110,478,302,760,774,548,714,835,14,754,483,345,559,383,2,550,159,185,720,398,675,301,409,751,972,905,838,349,110,379,646,596,933,941,831,144,279,522,655,172,770,335,350,800,99,271,925,580,639", "685,509,784,455,154,734,843,132,397,588,360,19,921,968,800,672,742,682,197,995,591,787,504,516,806,360,766,624,247,463,691,248,408,136,42,487,506,179,507,343,448,785,321,316,187,770,905,419,439,98,789,960,660,83,869,379,474,459,203,268,831,338,828,434,484,830,530,661,788,523,855,832,678,415,71,833,474,5,624,119,35,782,321,982,489,456,630,630,478,143,876,890,3,449,535,201,638,385,11,526,865,197,191,452,146,83,45,524,202,238,236,564,661,281,802,735,315,334,293,720,397,71,606,686,314,262,868,457,908,520,913,492,746,570,976,788,858,316,960,891,920,239,211,338,398,858,404,915,843,641,646,592,854,640,647,533,381,873,888,56,181,448,434,825,194,356,599,683,633,700,851,453,855,961,986,866,861,102,747,914,875,873,246,233,447,489,820,732,92,297,871,404,614,873,665,636,36,189,557,165,81,664,347,325,958,828,221,42,470,409,464,116,615,981,875,976,360,643,181,139,816,662,606,522,115,544,794,252,974,176,335,720,942,4,417,305,538,604,361,962,269,249,29,111,466,800,890,917,724,202,535,866,199,717,852,419,314,161,733,454,697,573,232,52,490,88,773,335,259,576,734,28,45,763,692,862,219,261,78,920,189,705,686,744,590,726,196,53,983,645,549,832,16,257,527,769,227,126,934,483,949,766,241,763,308,105,59,183,669,407,922,493,118,332,587,512,670,856,803,428,518,461,375,361,96,800,721,891,800,456,956,606,51,685,91,324,519,377,987,458,757,892,110,800,376,376,501,981,436,437,966,146,696,540,581,166,725,857,781,606,911,736,918,48,889,559,519,934,695,122,863,719,609,124,220,849,661,582,991,229,683,108,468,80,342,967,636,976,626,328,610,644,809,473,169,500,335,665,699,53,113,130,960,825,574,508,408,51,712,97,716,73,920,34,455,106,658,499,617,679,418,813,75,393,501,115,550,618,932,546,824,517,409,637,877,14,961,76,77,649,621,652,657,915,384,603,881,781,175,221,150,893,649,925,398,16,974,131,720,77,872,885,839,414,577,98,518,320,355,77,723,816,618,125,620,345,322,868,421,936,868,869,670,765,203,545,165,281,292,868,964,581,4,589,162,501,451,612,410,371,811,668,269,410,639,606,984,82,548,985,333,638,677,337,584,757,115,107,228,436,640,133,210,447,446,223,184,399,594,908,504,374,629,539,100,568,318,365,672,744,990,454,94,854,708,523,696,118,965,873,175,251,109,937,203,468,759,830,732,918,870,857,347,236,794,222,146,78,134,512,70,370,413,400,841,276,852,9,924,586,748,112,377,892,733,375,84,255,203,132,223,190,887,701,610,865,456,13,701,485,193,470,251,341,119,125,671,343,81,324,847,650,927,622,229,941,853,637,292,405,59,2,804,574,357,84,278,626,515,71,999,632,277,257,122,274,619,288,981,668,551,845,38,872,730,196,569,565,268,930,427,878,399,172,447,367,413,256,499,475,943,118,760,287,631,974,829,141,857,508,379,559,994,56,906,444,135,60,134,193,94,198,146,513,677,946,87,300,110,95,12,857,977,248,407,708,118,279,383,552,252,157,146,958,301,401,212,401,318,414,282,269,747,53,520,341,182,326,253,80,310,362,460,121,56,753,550,605,636,306,42,526,729,356,996,633,614,701,450,325,665,502,656,584,216,519,529,3,659,658,649,203,94,28,201,980,741,824,304,798,860,365,324,530,638,78,526,487,310,4,780,588,32,114,480,428,142,246,904,278,880,280,228,589,692,639,737,401,760,825,236,783,188,914,183,792,607,970,587,459,420,179,119,79,662,817,60,622,959,329,564,528,326,201,555,151,831,632,420,711,633,972,666,627,406,728,313,222,866,765,136,235,785,387,944,12,343,275,835,91,901,607,321,70,646,726,837,967,431,855,550,421,370,34,795,710,87,556,744,269,878,100,884,289,619,752,618,970,53,130,682,616,498,885,732,474,695,645,694,719,707,439,283,283,696,232,731,340,435,340,612,902,767,62,474,567,767,794,446,581,700,938,874,254,327,37,810,941,165,198,913,703,370,67,744,945,189,975,563,861,494,872,116,496,103,970,119,131,281,940,105,742,231,872,237,37,0,314,772,177,188,258,768,966,679,480,238,304,880,825,79,279,893,946,424,551,542,843,962,355,356,417,549,330,462,323,361,567,833,252,359,443,244,475,9,613,162,485,405,15,726,234,523,856,218,899,347,592,548,458,1,880,476,510,271,169,83,990,569,909", "131,621,683,8,900,883,101,379,907,773,626,454,391,247,606,967,338,699,690,352,554,64,319,934,404,89,859,137,971,240,429,2,991,24,910,653,453,460,665,19,200,693,706,855,379,484,71,798,102,28,467,391,384,120,411,624,523,531,657,213,892,635,967,402,98,363,248,36,894,616,6,820,238,957,500,278,501,351,525,332,272,253,945,51,526,114,139,453,693,511,959,313,557,884,454,687,281,861,278,790,275,487,789,704,717,255,661,579,429,398,698,255,113,847,217,498,997,911,937,397,60,48,170,559,945,199,662,109,158,731,125,370,952,600,689,174,860,846,281,903,210,509,816,576,828,858,1,928,701,124,195,412,915,902,681,467,112,288,196,623,896,679,660,706,57,785,354,228,871,422,212,743,961,747,146,230,556,141,71,902,366,35,237,692,520,648,109,888,816,148,946,552,536,338,349,829,120,930,441,802,586,684,867,145,195,353,844,297,938,497,105,894,299,470,643,437,703,327,343,638,218,701,838,989,295,984,332,601,862,998,815,999,73,727,682,653,65,98,486,880,479,523,366,421,698,399,223,268,30,225,773,798,867,740,847,529,65,911,165,396,856,984,107,415,482,771,99,527,896,92,177,611,123,566,222,305,519,307,919,584,576,941,902,823,135,993,141,300,376,887,310,838,201,551,135,501,805,900,843,769,313,130,777,123,987,765,751,430,406,305,396,393,451,977,747,813,138,140,890,677,345,370,827,71,821,793,53,381,894,319,796,286,580,703,485,508,941,752,303,604,67,850,531,539,173,178,663,537,467,197,32,452,907,209,785,181,235,240,653,809,461,197,386,135,89,769,254,156,730,280,652,630,783,160,45,42,530,149,601,344,458,84,966,570,814,249,898,446,563,889,291,886,270,760,917,9,265,435,382,304,470,352,862,196,481,114,742,622,280,224,882,911,171,886,312,938,841,462,215,697,598,810,178,390,205,267,965,393,139,338,63,346,549,790,440,748,630,850,724,919,75,37,147,104,302,494,451,831,289,761,20,552,89,896,178,635,466,321,993,870,555,530,491,133,337,270,667,426,516,928,224,50,77,701,96,340,341,736,564,753,995,641,140,537,645,119,81,783,661,922,396,276,554,964,548,408,118,251,551,427,603,940,594,198,207,394,317,227,971,550,660,107,505,51,489,81,77,860,378,892,568,541,424,865,65,790,733,933,644,32,938,954,739,388,565,194,253,468,187,311,417,725,476,948,801,295,94,413,506,995,886,511,158,439,345,356,380,988,416,843,977,809,432,95,373,772,967,146,216,1000,52,855,344,940,981,416,477,873,876,40,351,120,966,179,223,815,984,400,341,333,547,489,567,286,589,826,849,573,9,488,660,145,277,805,670,101,373,922,248,560,354,758,456,281,423,975,961,744,423,44,181,195,731,483,19,271,804,669,915,311,283,421,258,992,17,577,215,32,370,995,668,39,605,550,282,412,628,80,145,133,628,727,267,661,226,156,705,292,432,521,876,909,550,389,949,601,89,364,592,183,314,130,574,929,294,585,224,563,897,973,680,689,227,655,715,91,37,21,289,344,658,909,548,360,152,500,436,931,579,852,579,704,844,278,80,26,408,421,99,831,152,590,700,697,776,154,126,932,120,455,922,23,957,453,625,694,300,587,327,366,465,647,985,383,198,623,7,176,730,778,490,727,851,306,709,466,68,590,152,529,939,808,403,118,944,682,404,970,288,934,378,986,791,491,892,898,986,66,519,590,651,69,109,785,485,412,617,649,797,959,998,458,619,702,48,459,674,970,52,419,704,43,687,659,770,277,868,254,159,226,823,357,666,944,587,807,489,751,123,810,427,843,228,429,778,250,198,927,797,667,610,306,194,150,788,378,317,932,901,96,899,777,581,102,314,661,707,284,442,380,607,470,201,843,549,482,508,463,466,283,969,533,188,560,561,614,382,955,944,664,299,720,525,356,368,857,535,749,44,569,383,350,448,373,824,17,754,813,399,87,908,227,797,314,649,180,823,508,383,983,536,799,886,772,148,968,606,562,714,831,325,598,230,465,675,318,966,165,300,164,719,815,876,555,359,869,967,865,588,442,718,470,647,996,706,581,713,272,880,427,243,561,422,598,577,322,314,0,247,331,201,174,716,560,79,26,940,602,580,852,472,459,835,97,457,35,733,540,425,333,571,676,160,588,440,463,114,342,894,377,835,726,515,728,570,310,884,440,268,745,137,227,606,389,766,424,14,540,607,855,181,222,517,225,553,245,831,537,842,456", "822,813,218,770,464,703,754,23,156,621,436,916,252,891,593,195,119,399,624,396,246,856,499,109,415,852,809,727,947,532,471,666,996,624,458,763,787,949,154,620,406,706,556,926,883,881,969,174,309,854,807,563,331,941,747,59,404,144,660,498,353,353,929,881,886,958,374,522,195,112,699,566,378,470,921,571,35,526,484,142,718,714,432,837,122,494,419,427,940,97,404,848,447,298,645,429,187,773,53,92,25,829,428,845,876,230,4,962,38,683,395,198,646,338,525,809,439,893,411,496,405,670,296,856,660,497,259,728,309,300,688,747,11,549,974,626,485,900,214,506,974,926,472,307,151,320,667,991,887,99,19,863,776,496,289,909,103,951,419,650,543,386,49,444,467,599,759,801,448,120,336,160,956,599,839,896,791,489,914,740,144,389,294,473,411,411,252,390,351,821,246,379,769,264,414,271,383,111,140,634,509,921,891,710,431,528,640,348,346,553,344,610,318,807,986,221,419,550,456,970,971,450,659,783,455,204,972,297,768,461,485,823,748,446,998,39,313,435,843,683,634,821,128,456,453,804,579,354,117,897,370,835,752,710,651,231,912,676,944,356,579,923,644,661,721,734,534,496,18,223,914,731,278,798,62,307,410,499,118,127,359,708,998,451,680,527,347,182,728,50,252,146,296,247,593,452,978,744,781,493,198,567,236,428,271,197,706,403,598,285,782,26,360,585,468,925,782,969,134,36,92,134,102,908,54,360,253,244,232,13,347,464,615,361,807,369,161,503,797,672,504,922,108,121,707,299,432,323,575,740,181,406,3,900,994,889,37,646,959,62,60,750,145,147,517,780,861,356,609,243,98,609,453,796,956,143,369,910,764,83,571,987,578,895,574,859,501,113,342,734,670,353,270,733,418,164,731,784,974,61,824,168,78,923,887,594,967,133,253,741,243,688,506,328,625,402,651,973,607,865,645,441,728,196,824,869,497,726,227,48,989,54,838,774,787,546,918,510,170,374,611,78,292,18,680,684,496,627,251,734,802,813,723,511,88,19,453,319,883,616,161,665,385,440,678,937,166,877,70,599,282,460,712,329,350,649,569,916,233,500,678,972,749,19,673,239,913,691,629,24,159,246,763,144,937,207,328,986,13,940,235,199,279,998,266,243,73,194,275,921,587,573,254,943,52,986,584,710,93,295,939,326,944,330,810,348,853,650,5,954,201,712,781,752,77,247,223,446,20,203,831,395,257,397,82,437,466,306,713,292,742,449,386,100,778,751,919,207,690,487,789,495,434,325,702,398,996,218,470,704,577,149,23,325,157,307,644,401,941,401,809,274,919,357,129,330,46,508,498,822,44,831,339,555,444,777,748,946,955,799,313,312,121,830,669,245,492,577,768,990,448,822,492,959,630,286,817,339,956,989,148,219,838,649,249,831,205,505,69,709,768,40,613,737,39,656,896,537,859,373,435,871,163,698,289,791,682,558,887,673,563,555,781,963,326,664,166,151,151,862,409,623,329,637,43,421,873,273,249,737,405,107,933,867,396,906,287,835,575,114,990,712,534,244,24,556,89,192,281,991,547,520,231,984,357,434,228,81,310,771,628,74,195,105,569,573,418,755,269,423,775,447,245,551,736,156,527,753,408,873,505,79,785,730,694,357,143,154,371,482,43,155,801,259,271,742,542,121,869,41,115,928,465,902,713,465,473,106,78,747,562,394,16,648,196,532,915,685,885,931,499,22,762,293,441,207,483,429,182,294,909,117,496,40,127,338,69,341,897,284,913,767,81,689,289,331,541,595,818,386,281,369,893,609,952,282,952,622,713,15,531,64,459,46,24,552,400,792,505,655,653,686,686,876,469,381,328,558,376,912,460,336,952,983,657,161,225,283,300,967,371,815,495,449,924,761,109,419,251,467,568,900,853,111,140,156,77,432,493,880,176,59,582,998,122,465,533,606,183,301,534,819,445,67,149,139,115,211,659,795,447,713,630,467,481,926,628,592,970,922,690,285,127,710,930,479,355,613,508,811,115,436,172,983,811,725,608,199,852,598,412,249,619,757,49,167,664,355,118,972,962,789,791,320,109,707,371,294,463,774,492,826,780,920,85,876,801,29,158,183,803,591,402,182,448,21,772,247,0,722,986,437,938,615,722,481,888,119,680,751,223,994,177,247,738,900,635,971,484,81,178,881,729,210,52,155,418,226,360,413,428,589,353,133,643,92,732,604,930,968,239,949,421,236,230,677,239,492,166,743,250,248,634,981,818,520,620,393,666,510", "717,37,146,153,356,758,678,637,422,626,947,655,588,331,416,93,235,932,347,772,541,476,582,490,841,475,655,269,742,577,684,78,298,686,253,929,511,512,297,625,550,603,54,95,187,135,92,153,246,565,728,775,734,566,544,841,58,741,884,327,711,565,84,901,380,156,663,206,788,295,475,84,394,927,560,712,458,842,342,942,896,334,547,7,267,842,517,110,290,350,788,19,991,932,418,54,1000,521,140,52,905,608,598,950,712,255,800,732,467,568,828,478,413,534,766,343,72,67,876,732,126,129,679,457,244,707,500,866,258,746,784,537,634,97,988,685,226,203,901,128,838,186,735,987,334,698,933,72,989,128,811,194,669,662,154,567,357,614,688,850,107,218,967,695,364,72,79,860,286,606,727,12,398,909,7,634,764,164,485,773,627,482,502,966,738,149,707,333,397,401,421,969,966,933,744,888,62,575,497,6,515,78,298,657,399,359,775,133,962,153,499,907,134,770,116,534,111,896,679,232,721,402,955,322,825,429,961,53,838,940,455,730,902,618,872,154,504,921,445,419,599,438,779,164,541,601,259,171,562,305,862,204,184,121,66,337,279,326,579,292,251,256,158,189,292,192,765,153,814,601,186,609,909,186,728,125,103,188,27,371,812,348,597,426,539,6,735,742,217,910,933,250,406,811,626,308,908,52,464,767,496,745,275,396,416,169,665,994,695,576,551,374,913,422,634,956,558,164,411,932,862,824,716,982,393,871,46,23,943,502,668,542,428,162,110,654,187,657,114,601,262,450,46,818,784,470,786,115,73,709,49,814,820,617,542,537,980,159,352,889,68,754,81,424,612,54,181,38,153,221,533,157,761,808,265,144,519,332,875,16,824,418,74,636,680,235,693,403,561,964,306,363,436,723,313,782,685,321,253,340,890,710,675,988,295,986,888,53,914,21,110,259,201,946,301,600,698,398,779,148,381,545,636,696,269,37,191,167,294,77,657,498,80,904,980,650,482,688,137,289,175,556,107,776,973,871,224,814,717,810,186,413,275,932,715,57,166,928,737,924,580,179,828,60,830,973,478,920,855,10,3,719,762,96,498,343,769,369,475,219,830,76,515,802,211,311,718,306,59,764,132,893,910,922,881,55,891,462,267,713,517,257,541,59,172,96,482,241,770,175,186,125,297,826,116,104,8,654,990,201,579,750,989,38,549,907,177,752,779,572,417,444,490,803,837,725,677,952,504,683,7,341,500,377,953,137,191,433,212,503,507,105,724,567,447,612,203,222,658,993,611,108,155,529,747,439,806,725,561,31,926,373,558,309,810,532,580,467,257,97,550,532,616,619,719,827,603,683,315,372,635,214,951,548,304,226,657,664,492,597,323,28,749,859,477,701,130,682,239,717,551,513,843,461,153,71,255,292,961,487,338,731,718,381,91,23,656,136,727,987,577,587,14,454,890,695,95,293,462,446,146,361,869,317,785,315,853,862,80,462,413,282,786,592,510,484,454,57,360,411,452,675,884,468,925,764,332,378,872,873,269,19,976,573,464,766,9,942,902,415,306,593,841,372,884,288,758,623,985,931,924,102,343,361,184,513,507,112,68,988,561,765,60,277,129,320,62,939,695,741,620,404,323,698,643,914,121,611,250,751,815,758,368,717,858,324,464,252,45,91,166,881,422,801,356,91,595,60,902,167,362,376,430,101,610,399,498,617,478,95,642,578,95,24,959,660,71,30,462,137,893,612,828,194,818,504,278,924,167,625,991,85,724,837,706,176,457,127,854,63,460,325,885,951,238,68,317,650,578,507,690,815,195,10,526,834,750,685,931,228,674,341,298,227,674,820,508,39,258,129,588,93,317,493,49,320,197,178,249,349,413,692,86,679,6,744,350,790,948,868,333,369,892,116,542,677,960,676,960,954,271,943,56,415,935,237,223,673,712,327,798,753,93,710,287,498,601,162,932,611,774,951,284,349,341,574,104,118,460,399,534,198,683,878,829,818,789,207,168,572,21,300,182,393,488,79,517,266,172,17,959,796,689,544,9,516,43,24,633,288,485,583,274,571,251,771,974,924,366,917,758,765,267,304,886,390,858,100,817,647,61,850,94,597,428,138,4,945,342,446,651,420,941,96,315,991,177,331,722,0,482,951,580,286,144,487,708,387,664,716,790,245,510,15,429,606,710,953,364,852,221,755,534,406,789,22,748,220,967,414,145,37,176,880,385,239,909,495,848,856,431,579,522,646,830,984,600,421,895,217,918,845,257,253,342,647,472,124,906,577", "397,195,915,338,42,609,573,106,988,560,928,317,244,897,553,523,654,961,462,241,351,391,735,444,265,223,639,646,142,128,968,787,908,866,607,29,667,599,115,828,885,812,824,303,22,325,425,436,591,705,196,358,882,960,735,895,691,532,1,348,834,725,342,879,921,259,369,852,201,307,457,386,191,123,613,437,109,65,82,970,591,931,691,554,146,434,440,42,471,644,339,177,113,677,814,260,785,617,457,521,812,104,683,259,533,475,258,414,956,333,549,911,42,353,386,607,870,169,358,763,941,78,689,590,982,831,747,578,800,382,957,390,793,79,363,126,517,320,658,955,539,358,217,858,700,413,585,129,375,243,18,678,42,800,24,181,589,566,53,65,177,497,553,8,279,403,527,229,423,460,636,61,110,853,572,729,821,959,39,161,518,720,619,44,602,638,841,839,968,515,594,435,854,49,238,650,244,925,622,987,874,339,433,686,92,707,460,365,587,236,754,513,786,215,395,8,779,170,599,339,540,736,234,691,188,103,274,727,751,126,811,26,413,999,24,78,569,241,243,723,247,582,91,747,866,166,116,342,767,703,920,11,617,588,116,374,952,875,526,472,36,78,895,693,819,654,214,599,892,867,424,732,8,916,355,894,222,352,579,611,725,857,633,794,840,710,93,790,88,591,354,748,724,214,664,379,712,18,360,509,615,729,284,793,262,635,662,642,933,791,639,354,823,866,112,445,314,409,905,390,721,591,177,219,147,174,761,118,208,372,655,662,424,262,146,498,435,974,906,323,859,697,382,826,444,625,760,502,761,758,943,373,147,255,324,701,196,460,254,984,790,389,49,260,27,763,899,64,536,595,330,927,347,861,241,638,893,935,9,861,359,312,775,894,914,389,514,503,328,613,498,58,804,289,443,85,46,306,91,717,647,943,951,12,327,138,906,689,181,335,358,212,795,819,158,256,413,238,194,361,773,796,824,473,283,317,231,459,84,711,721,881,288,799,681,719,816,454,12,26,490,631,562,423,820,171,724,294,753,145,803,683,119,947,284,348,269,247,754,275,242,922,188,709,837,980,885,819,116,814,909,29,136,211,720,636,994,365,564,714,875,366,518,767,249,881,823,555,810,677,708,118,767,910,225,780,176,377,120,590,671,107,371,856,167,211,251,878,894,55,485,573,817,266,810,499,165,982,740,378,470,26,556,747,870,760,517,343,540,877,19,298,545,630,389,643,661,391,405,768,498,57,221,213,568,429,461,669,228,801,813,973,147,854,920,328,453,575,394,679,951,518,803,820,824,92,185,349,889,902,794,251,680,457,245,934,844,160,425,697,283,310,494,569,165,115,880,274,516,751,257,831,472,812,877,562,703,293,61,5,906,649,340,248,639,482,216,730,100,282,290,903,638,647,798,965,99,69,470,84,462,69,96,912,66,568,648,903,580,77,309,901,692,114,36,374,87,62,300,236,98,711,842,143,84,556,455,127,457,459,267,778,693,383,101,937,7,69,40,803,278,624,943,522,545,810,862,894,58,467,33,536,311,110,396,858,13,829,252,771,107,351,927,149,828,794,633,399,710,839,641,979,489,797,372,3,35,399,658,147,164,471,273,201,203,640,581,971,962,772,300,385,794,239,12,37,295,225,989,977,63,168,152,6,921,403,903,879,37,159,20,833,481,897,753,369,687,164,126,347,839,27,212,740,804,265,569,828,488,507,68,209,188,275,551,477,301,46,394,932,137,953,482,31,696,483,861,563,575,981,767,992,430,11,823,49,458,97,501,525,663,281,926,108,374,572,734,744,411,846,314,293,998,611,692,545,767,777,640,406,939,875,731,444,161,293,600,103,961,953,614,11,432,436,616,243,240,416,223,532,930,79,526,617,873,259,858,550,446,230,565,8,299,461,277,527,68,862,952,132,562,728,295,75,661,545,282,831,527,712,801,852,744,954,771,954,616,231,616,123,115,254,577,803,223,430,956,167,23,137,751,688,220,929,307,769,509,897,456,676,917,597,697,209,176,94,663,400,911,976,382,816,986,356,87,911,215,582,258,921,990,562,822,391,736,746,706,659,875,727,330,862,936,56,830,884,592,280,380,751,651,945,615,705,347,798,581,649,822,156,563,883,554,295,216,594,188,201,986,482,0,143,97,985,726,877,957,525,21,476,730,293,757,524,642,480,297,1,659,398,474,876,52,921,67,744,53,453,830,352,403,976,498,54,685,549,760,30,25,35,413,3,249,398,576,768,633,896,915,652,211,398,165,642,396,588,571,505,88,616", "715,915,520,773,972,942,221,478,279,90,717,992,160,939,604,400,715,199,583,879,252,540,211,592,815,907,109,300,598,276,767,541,514,302,201,172,145,539,407,298,788,986,220,426,742,893,985,786,239,292,11,894,778,351,887,772,984,230,462,22,557,222,475,638,120,819,496,443,717,886,928,516,908,226,77,45,771,714,945,330,470,614,630,590,213,572,272,41,654,887,158,501,388,406,112,850,516,961,556,294,911,494,130,7,767,260,656,382,698,181,898,827,542,463,529,635,461,428,635,671,226,892,921,976,824,553,852,361,554,572,296,784,283,736,715,560,525,137,458,854,412,706,294,438,346,372,855,172,128,801,189,164,541,728,171,175,946,242,323,469,13,735,475,344,925,217,928,606,279,959,771,189,417,854,551,490,665,813,982,79,84,549,982,878,457,56,251,384,219,886,243,551,110,780,496,466,929,210,249,559,116,817,779,308,341,346,16,89,252,790,273,901,936,258,306,898,404,370,938,431,498,840,974,720,477,120,120,567,902,142,528,919,993,526,488,767,192,360,664,961,529,222,119,66,582,527,429,48,53,3,698,595,140,895,318,560,440,787,643,182,323,469,216,737,848,710,21,693,157,990,686,269,868,675,893,371,130,14,898,194,948,92,47,859,349,507,184,677,431,25,461,578,492,724,235,535,418,347,30,659,793,427,116,5,327,183,171,38,959,358,541,700,753,623,687,154,583,782,728,723,243,344,72,700,112,467,267,665,81,222,438,612,605,4,176,61,511,248,238,398,916,166,586,649,599,65,950,395,807,849,790,736,799,268,599,789,616,785,799,792,26,442,471,647,51,657,184,661,430,770,696,165,308,503,260,466,846,346,872,114,959,962,452,676,394,781,659,83,399,153,972,517,278,175,936,814,750,335,142,468,956,888,32,160,136,815,268,114,98,915,323,485,384,306,509,431,739,871,323,334,945,196,50,839,612,674,952,682,795,670,215,299,427,811,402,427,48,280,935,618,919,422,805,461,860,801,240,341,250,711,138,562,490,137,185,982,867,690,228,159,825,929,28,816,742,999,884,854,210,712,511,601,91,8,107,549,258,301,327,296,78,998,922,893,780,866,907,21,227,121,139,352,21,530,760,515,957,712,420,995,699,184,700,545,603,995,735,800,855,113,991,347,422,821,310,236,900,635,549,813,352,545,590,573,341,16,950,929,490,412,749,569,278,381,460,675,193,781,933,186,287,157,355,976,178,24,594,244,489,947,93,344,307,489,768,540,189,359,401,122,481,722,658,847,591,673,89,876,342,189,509,647,35,784,556,601,825,903,920,746,481,380,386,853,160,733,179,397,829,434,891,830,660,657,567,475,578,263,177,919,529,668,350,164,869,723,549,946,486,547,896,253,33,259,903,932,823,467,369,563,309,996,346,748,450,206,488,694,911,123,913,607,886,782,741,909,650,124,915,350,863,527,877,63,576,458,100,165,695,933,158,958,832,411,903,33,5,144,194,496,200,31,725,872,874,484,631,785,459,488,898,257,658,747,582,888,79,698,703,28,102,966,528,559,657,398,38,931,148,561,946,117,96,951,203,926,877,406,305,694,983,492,232,428,851,548,150,658,618,987,604,842,610,601,223,290,612,89,831,710,269,336,39,396,871,614,429,288,917,315,248,911,94,943,617,127,589,297,748,172,573,138,306,521,443,75,170,570,195,299,213,240,269,353,29,962,481,537,332,212,670,787,337,588,350,187,127,766,355,172,863,191,513,390,761,347,532,246,440,356,594,726,21,954,809,28,600,483,61,37,957,374,554,901,483,119,768,349,615,677,994,206,365,531,154,990,937,487,133,782,136,901,837,265,788,121,800,485,408,580,972,313,964,98,117,719,746,403,468,274,908,724,682,228,458,717,323,741,409,434,112,472,621,675,288,439,44,518,417,177,415,185,394,805,387,864,172,270,923,366,417,781,927,913,778,768,540,883,532,54,634,57,992,902,523,100,898,239,962,663,431,25,436,522,31,965,306,654,347,126,515,344,822,679,902,891,976,328,262,17,633,972,743,739,291,514,494,658,796,649,85,549,381,510,744,501,601,460,402,509,935,780,722,945,109,759,349,809,446,261,427,932,485,588,310,29,258,174,437,951,143,0,92,222,566,88,327,830,173,885,616,593,532,146,645,258,502,79,341,117,628,182,409,943,835,667,568,479,483,574,602,989,826,33,491,993,4,651,962,897,43,1,478,12,603,250,867,620,531,684,265,849,828,942,727,353,249,898,456,566", "607,662,335,13,42,128,962,763,705,954,749,874,152,414,46,7,94,51,667,362,167,692,214,790,155,521,15,945,248,66,384,236,973,947,48,482,666,790,749,599,105,104,838,151,565,365,481,424,705,46,764,809,25,191,298,345,655,605,508,916,534,401,171,517,591,44,405,715,566,825,278,121,526,662,340,905,24,818,150,576,457,93,573,694,485,769,934,296,598,937,113,565,232,770,416,666,427,985,342,33,740,391,836,286,369,755,858,430,196,23,63,186,522,309,891,253,186,808,523,72,39,748,791,183,49,598,666,458,214,965,952,869,485,217,497,92,705,999,723,594,954,220,737,429,708,934,682,488,997,926,599,95,595,843,62,880,803,248,635,712,888,399,361,225,673,796,519,221,881,171,54,849,864,653,532,864,473,575,273,574,191,105,541,765,831,645,185,182,278,987,683,750,378,86,779,291,161,987,427,480,318,149,130,828,697,316,610,229,992,582,847,891,103,439,828,998,839,510,664,819,918,914,606,427,158,259,697,570,797,899,983,742,580,459,30,676,947,979,465,241,352,503,573,114,585,402,162,690,973,300,239,356,732,247,363,389,204,810,997,454,846,148,217,402,899,407,261,93,494,264,416,89,909,493,930,848,338,583,534,391,423,932,904,369,891,270,73,563,168,215,253,739,452,151,187,791,569,277,537,853,493,124,273,134,301,683,50,558,72,443,337,997,809,649,180,719,363,891,393,559,238,437,293,787,873,59,54,518,751,691,998,75,436,8,662,136,392,75,599,900,331,703,193,294,743,363,257,226,37,618,915,500,525,947,421,203,42,857,918,962,59,390,532,329,742,823,342,246,886,166,685,367,800,212,414,259,622,555,71,153,446,684,370,647,333,839,707,407,704,264,845,920,411,743,303,538,720,928,253,556,913,480,993,6,205,132,186,307,608,623,402,520,995,637,128,732,840,492,410,359,207,396,559,174,221,590,157,832,636,570,904,832,908,718,682,338,420,383,936,590,927,603,954,890,521,791,544,486,868,889,386,356,908,914,488,44,26,183,346,329,99,852,605,762,582,131,262,797,548,77,410,986,358,168,614,432,990,958,649,132,187,251,207,308,668,63,575,291,159,281,478,124,310,925,583,406,807,795,171,115,633,352,695,775,589,934,902,673,915,227,779,771,555,292,830,201,63,820,374,731,890,807,812,283,712,615,503,309,196,407,151,22,475,694,30,789,590,947,976,682,409,633,973,688,28,586,632,720,725,282,307,661,846,633,603,727,541,691,901,636,93,575,248,883,520,601,413,788,209,497,921,771,529,808,616,540,805,872,521,974,839,203,184,972,714,112,948,260,797,354,457,467,548,675,72,494,379,183,896,536,821,928,856,653,471,611,1000,621,22,419,389,584,3,923,611,973,252,40,721,131,552,914,828,326,664,365,547,351,880,571,934,529,735,53,480,554,977,986,425,671,820,793,506,723,731,878,833,761,272,319,935,593,937,354,343,816,299,984,878,783,57,151,95,755,29,98,330,681,852,98,680,880,241,479,312,257,570,538,237,744,882,435,752,191,754,875,861,473,535,325,666,752,44,718,199,314,466,340,830,365,935,607,240,220,630,433,626,693,677,49,860,754,371,710,903,734,312,340,521,114,168,904,580,484,428,608,766,745,221,704,237,217,248,824,579,569,132,504,255,338,356,576,74,157,335,981,920,774,116,21,393,34,803,474,601,415,375,903,3,88,494,655,156,382,185,586,903,545,808,444,222,62,503,707,584,835,150,108,535,127,141,954,251,835,967,136,987,787,127,883,572,994,197,162,719,110,19,211,782,133,558,580,499,811,194,797,598,966,542,568,886,42,376,630,957,249,79,959,796,736,253,836,439,357,42,587,462,105,578,711,495,358,999,72,553,215,352,790,462,776,509,74,995,433,534,505,114,35,624,544,961,98,672,111,821,339,18,516,859,121,374,101,991,778,291,464,930,288,432,967,632,498,769,997,245,316,911,104,840,178,5,602,828,342,127,799,517,666,356,522,59,312,620,91,362,320,154,502,569,245,627,513,972,223,684,429,767,522,204,438,192,454,22,644,629,999,262,796,39,640,618,48,174,185,906,202,453,824,140,526,245,618,196,664,105,641,768,716,938,580,97,92,0,993,504,971,854,121,56,236,73,165,580,101,120,957,391,387,375,829,766,979,67,660,962,858,680,198,86,6,548,534,61,827,654,194,401,902,220,292,591,797,410,27,884,723,949,977,534,371,372,397,670,226,765,292,304,418,8,973", "502,284,561,374,463,811,393,842,775,781,468,73,358,548,266,763,447,136,713,464,781,699,147,42,946,133,57,168,958,328,207,364,994,395,332,986,41,487,671,35,887,713,328,862,385,675,242,865,2,140,633,694,407,850,169,47,895,944,606,820,654,382,418,500,221,25,43,33,629,562,468,6,103,835,297,415,463,115,206,288,55,60,727,566,47,430,201,92,878,821,175,23,172,151,386,540,599,87,442,785,917,947,872,892,598,308,154,725,337,780,328,608,849,304,513,779,72,859,14,664,889,834,5,278,839,357,121,794,856,68,951,656,879,978,847,264,28,883,327,778,36,474,185,816,873,661,913,268,516,263,722,409,365,646,60,807,639,782,959,367,941,639,377,187,183,710,68,524,463,506,804,207,741,255,679,957,315,317,643,775,353,13,352,254,167,943,733,295,186,394,733,433,502,198,198,61,313,216,455,444,710,556,828,333,313,799,628,539,515,278,75,119,800,611,541,520,605,405,983,258,83,369,205,93,808,160,594,48,64,904,29,504,597,719,58,150,856,746,194,781,746,300,402,374,99,367,222,906,502,281,5,9,841,785,85,424,545,687,186,868,598,269,183,505,99,716,978,506,849,96,958,403,382,590,482,774,649,699,376,698,317,86,793,658,734,58,743,99,499,641,381,949,43,410,499,450,950,749,612,590,202,54,540,130,702,521,39,73,969,184,161,20,741,701,730,789,304,537,90,573,711,781,562,446,814,325,412,78,359,467,87,717,287,658,124,132,354,536,760,456,392,972,218,106,157,115,489,422,289,97,283,851,424,177,718,184,945,326,272,185,839,590,564,735,47,529,419,61,62,877,816,695,790,505,386,714,933,202,373,378,249,781,316,783,737,790,605,131,13,173,706,654,605,875,248,893,988,418,537,650,403,11,165,120,385,924,309,195,592,313,868,832,926,943,942,478,86,508,934,457,218,684,146,48,167,85,568,82,118,74,190,89,543,672,132,365,673,226,146,512,522,614,233,146,272,191,404,985,581,321,222,15,548,915,329,45,486,440,62,724,824,289,386,21,681,443,185,722,444,685,559,976,361,234,912,502,701,326,989,780,656,100,704,21,642,701,23,746,585,909,62,113,922,640,625,833,202,534,245,567,252,217,305,698,168,341,972,347,988,735,573,807,81,500,21,564,903,10,683,494,546,993,777,158,94,398,849,860,208,215,744,496,281,774,752,71,959,157,774,72,491,830,446,847,316,951,507,115,525,438,57,202,344,644,685,133,561,875,857,334,720,602,954,906,592,47,274,877,94,951,787,262,590,433,534,412,150,371,271,875,523,236,581,116,236,938,794,277,182,80,687,119,574,188,262,721,25,645,665,296,470,499,714,960,638,61,416,670,481,130,763,851,522,277,627,98,366,853,242,223,47,49,774,171,742,872,7,738,99,602,954,775,174,101,703,331,368,554,837,790,21,440,765,597,302,954,441,80,978,130,786,105,665,136,368,507,595,538,218,143,952,782,122,882,203,312,517,967,164,498,413,217,51,861,637,364,645,374,117,570,744,946,979,315,468,665,132,75,814,34,337,443,461,776,549,619,661,561,530,936,451,428,794,675,926,198,286,987,437,433,833,573,158,742,787,784,122,58,387,143,88,528,664,794,117,141,578,936,98,523,89,967,327,369,164,648,651,639,623,951,281,967,538,699,110,322,432,109,837,411,946,751,273,347,992,919,129,727,303,152,632,936,327,497,130,93,561,149,33,314,788,260,510,35,264,657,315,808,286,140,441,394,265,216,294,548,302,265,201,346,792,118,691,43,548,412,372,199,752,702,635,646,66,968,486,344,234,813,828,131,339,318,116,901,926,377,544,676,499,421,573,350,81,555,892,171,699,986,969,832,704,889,52,242,953,581,324,129,701,477,330,77,501,469,916,11,65,234,895,70,49,128,506,915,872,893,225,113,599,463,772,616,652,942,691,245,470,619,771,995,425,550,798,752,3,176,570,102,908,524,875,471,531,138,752,76,564,320,499,194,509,896,916,711,232,657,682,980,344,453,894,357,543,278,185,241,980,312,185,609,510,574,127,104,491,449,829,566,434,256,901,883,619,430,365,673,213,962,758,3,956,611,881,12,248,506,966,560,615,286,985,222,993,0,645,526,561,333,725,24,682,940,354,316,47,562,701,285,110,248,871,110,146,739,86,330,786,169,654,119,741,805,132,412,389,736,742,424,547,617,876,351,879,985,283,133,285,84,653,917,923,859,869,995,260,290,586,90,11,24", "400,749,873,709,353,998,64,479,980,841,259,547,759,918,676,869,732,251,268,590,737,20,769,310,692,77,592,122,679,68,286,85,107,93,204,318,484,635,814,813,943,600,432,493,823,255,904,423,973,776,598,416,94,205,408,314,689,79,851,110,465,367,457,747,573,923,176,831,337,991,937,391,42,254,348,533,742,224,12,780,676,297,654,621,860,527,627,718,515,523,175,589,313,433,362,965,458,884,60,116,180,343,444,837,524,572,517,892,720,189,70,847,507,221,336,568,730,916,75,652,687,242,732,101,34,538,304,872,918,622,140,727,454,24,240,476,819,767,399,971,949,984,613,640,729,444,324,324,337,254,312,246,291,353,261,274,186,373,59,8,682,803,976,368,596,691,274,93,173,201,63,56,44,196,835,38,137,720,46,3,426,690,944,344,173,919,319,278,29,993,300,947,78,104,401,90,901,751,853,304,459,705,907,368,300,624,998,903,85,763,598,17,443,610,62,975,956,454,776,778,332,791,98,309,428,900,910,868,6,547,164,661,780,913,692,677,582,402,795,726,486,292,492,947,360,805,962,72,47,100,840,947,781,643,490,802,69,716,62,962,298,64,780,104,729,640,256,93,406,965,395,815,844,201,468,393,253,131,592,759,843,985,783,878,898,511,681,192,277,522,37,708,885,192,980,84,22,473,169,236,907,392,314,951,91,87,151,35,315,644,520,529,214,14,298,986,676,676,65,932,359,95,851,138,597,305,461,906,22,721,774,410,592,320,158,445,738,49,593,60,959,603,734,200,640,749,400,418,955,951,355,764,365,31,863,872,628,151,62,105,827,736,471,559,960,667,838,954,101,749,779,860,903,171,532,247,567,496,243,141,742,494,74,552,850,450,572,261,770,827,53,973,42,266,237,792,781,479,656,882,944,583,740,493,180,780,965,580,659,582,214,340,764,724,857,748,315,514,91,955,42,80,734,182,501,194,961,12,502,519,180,789,527,887,390,828,800,12,410,781,226,366,2,689,497,683,828,171,806,343,53,761,731,628,250,929,521,904,166,77,533,803,609,15,416,180,882,355,520,264,231,713,957,476,379,82,351,862,871,327,178,287,150,273,403,612,327,348,9,177,210,315,502,563,416,388,651,792,419,535,214,298,946,671,512,798,880,542,500,457,603,922,614,115,260,433,622,473,646,981,900,959,515,141,406,751,884,321,498,817,103,808,19,285,726,317,575,318,301,914,769,392,836,621,603,418,619,867,604,189,724,462,562,792,289,521,553,337,921,434,401,362,804,432,989,179,673,151,866,598,794,293,907,817,318,814,151,300,392,376,32,845,844,852,48,236,585,758,811,797,497,223,459,993,879,10,277,594,907,286,127,700,38,533,941,143,72,910,727,147,221,548,267,558,856,226,466,764,327,50,804,651,660,644,231,353,257,118,652,693,18,481,180,117,55,265,104,149,617,532,50,896,228,924,190,851,55,98,459,590,18,406,212,233,412,151,862,741,584,409,861,740,129,583,96,36,939,933,364,926,469,967,364,784,57,56,959,730,758,595,366,782,752,867,755,791,276,298,643,564,422,348,329,716,403,569,931,981,971,191,411,230,947,672,474,23,877,517,190,572,804,254,430,742,496,73,922,441,534,938,900,290,21,510,772,15,969,615,172,58,758,316,328,617,609,221,744,742,122,795,163,417,506,102,506,559,581,171,101,366,220,160,396,473,479,237,961,505,501,611,579,109,330,74,91,587,178,171,637,721,540,623,317,35,315,441,913,194,479,264,227,153,539,905,595,331,488,296,837,199,426,88,600,562,289,293,26,84,906,755,601,727,485,787,279,66,145,807,776,288,46,969,274,840,954,499,984,942,50,772,362,781,472,219,674,861,54,601,813,440,37,417,988,177,324,910,948,9,291,916,606,144,80,899,898,667,33,199,920,781,131,813,958,618,328,456,293,414,265,359,966,619,290,534,75,846,842,185,861,957,23,92,463,247,784,58,277,287,307,244,47,590,105,913,501,155,774,173,268,232,907,937,45,252,772,917,494,477,484,443,296,777,47,171,928,654,811,980,257,566,627,976,344,725,292,708,21,752,632,319,602,44,768,554,715,422,580,980,281,763,574,898,647,802,342,448,679,79,722,144,726,566,504,645,0,523,39,72,644,772,887,985,955,473,308,455,624,549,142,23,516,292,418,984,699,363,793,586,103,62,332,876,433,325,12,577,490,350,412,25,475,624,471,529,779,333,712,208,740,128,445,490,252,671,819,321,289,233,908,661", "937,33,916,839,417,103,522,185,820,49,366,295,727,936,615,740,413,645,108,828,587,313,452,149,457,229,991,28,254,351,208,793,989,897,342,224,712,770,859,55,990,912,910,87,379,958,422,447,454,701,718,627,809,777,178,830,988,459,858,330,78,322,768,410,240,232,193,176,424,130,59,316,426,329,590,793,41,312,799,858,965,314,671,405,424,884,71,715,51,217,564,654,217,432,834,311,851,534,565,120,106,74,737,2,977,345,587,563,751,721,124,680,849,553,238,691,636,285,434,937,276,957,991,64,135,260,697,69,247,372,721,354,759,326,969,482,361,567,610,254,662,856,207,196,218,990,509,365,566,163,429,21,448,866,944,815,539,484,427,755,500,782,452,244,373,305,829,738,833,90,175,399,90,981,7,769,837,49,302,452,312,830,127,487,67,631,629,301,427,470,171,537,599,683,825,254,348,253,130,119,136,657,898,323,214,166,847,263,261,372,903,410,475,846,57,111,138,390,139,722,219,121,177,43,591,907,144,998,528,730,689,265,518,450,456,286,581,157,60,196,214,980,205,475,984,914,78,303,450,383,213,480,383,499,279,463,748,751,325,133,993,153,530,459,330,345,949,379,717,476,296,290,1000,178,557,534,796,711,704,166,298,295,999,187,267,657,764,610,157,385,222,755,552,606,554,307,390,119,733,101,126,598,631,894,104,153,250,207,154,746,572,813,207,211,570,639,380,122,275,781,349,760,809,65,840,838,636,38,930,406,797,492,601,693,924,23,470,204,692,248,888,44,355,127,515,599,807,128,770,606,747,463,477,964,62,502,532,727,457,496,488,41,241,391,625,693,582,349,526,224,979,692,479,463,757,476,566,281,450,989,519,157,362,378,927,839,800,354,390,674,599,300,827,276,56,124,947,780,526,381,604,404,14,152,27,877,805,76,584,652,665,404,208,93,675,550,387,140,784,987,49,972,556,199,498,250,747,705,863,429,197,595,601,718,309,11,391,150,555,620,450,754,535,127,847,785,80,35,146,656,699,738,225,959,719,90,406,403,727,55,445,361,581,127,778,537,893,364,886,330,822,150,121,612,395,967,518,62,49,681,800,504,329,920,756,185,509,798,21,342,807,937,306,697,871,430,216,5,427,674,369,637,546,747,671,324,408,50,736,246,327,371,89,655,436,535,585,419,112,463,960,489,763,208,530,760,447,816,975,845,469,123,971,747,756,698,884,477,895,251,20,952,178,691,140,724,954,771,686,742,610,407,523,78,841,643,292,74,451,214,733,378,929,229,415,509,9,740,171,292,889,337,54,537,548,620,963,154,178,345,937,988,1000,955,579,60,975,527,573,703,56,712,836,828,391,477,57,219,441,665,949,596,43,670,516,477,733,959,532,612,550,69,556,390,927,98,966,546,981,145,602,400,706,99,187,79,750,816,267,674,383,788,626,106,752,906,892,540,651,702,167,939,564,192,823,16,458,749,980,575,350,431,606,282,72,52,330,745,586,505,660,995,514,908,855,795,72,261,501,728,159,706,145,302,728,212,578,861,442,781,995,993,459,25,15,361,589,223,712,865,856,680,233,166,565,215,162,336,233,143,136,980,443,594,43,162,630,349,479,207,760,832,246,538,146,265,405,449,229,893,56,919,313,356,44,893,652,979,739,67,832,540,540,367,25,934,452,724,908,701,855,187,353,117,151,236,220,455,745,791,571,602,752,569,354,241,582,657,670,85,878,747,641,64,170,423,399,837,99,873,242,62,297,884,695,385,191,9,763,898,605,608,904,165,64,716,520,582,509,112,689,654,760,13,457,659,78,785,923,557,735,425,382,469,611,500,574,212,609,234,203,407,895,447,609,461,384,990,874,706,433,961,511,947,254,135,53,420,452,242,478,10,959,467,828,74,875,921,816,417,988,736,147,735,14,411,691,20,919,143,863,994,751,1,435,821,274,80,366,782,21,952,539,285,884,124,199,998,709,825,364,774,398,838,858,531,433,353,558,567,109,451,583,871,677,591,100,358,301,223,867,929,805,198,533,925,809,137,826,700,177,164,80,111,530,366,327,112,484,520,921,479,766,697,8,969,302,29,541,156,761,441,256,493,418,242,959,177,953,723,906,929,453,804,354,398,480,26,481,487,877,88,971,526,523,0,418,5,512,926,489,893,790,70,953,981,861,144,618,643,213,62,926,883,283,253,420,281,932,341,261,721,486,968,93,903,21,549,948,906,500,306,178,232,440,500,227,446,466,812,727,176,788,84,759,186,231,988,910,578", "653,812,478,956,733,821,277,97,673,876,427,776,755,159,956,15,501,466,425,182,62,273,513,5,543,548,176,826,77,768,950,266,630,84,417,503,389,650,885,435,833,328,628,845,35,552,589,520,320,943,374,675,662,846,102,504,583,531,124,821,101,188,705,783,522,545,900,706,554,910,779,82,552,118,683,931,457,615,112,317,26,68,847,462,752,940,52,613,744,30,297,42,575,416,989,979,14,623,311,380,275,251,931,237,140,720,397,150,977,212,827,936,557,854,310,592,162,760,756,36,680,273,321,594,246,256,918,428,531,940,340,776,122,370,126,384,675,320,409,894,171,449,445,778,640,224,577,896,498,510,808,333,28,874,772,283,983,287,132,128,66,82,357,57,20,266,842,878,958,961,602,179,897,168,328,785,95,827,519,648,570,352,339,990,77,856,259,205,915,491,597,584,578,800,715,475,923,234,464,422,812,385,534,533,86,152,89,315,671,464,995,826,235,400,155,952,410,513,983,987,703,681,631,118,153,527,260,300,954,849,547,471,263,570,34,287,159,1000,610,793,198,458,788,854,832,759,633,280,469,663,506,36,755,888,946,643,549,181,349,126,999,75,795,151,807,629,865,358,385,990,655,202,716,894,498,801,633,115,117,430,724,559,944,534,641,656,119,660,500,505,314,18,573,354,1,295,300,525,368,250,84,832,669,224,423,105,708,231,224,508,318,458,728,713,355,736,844,902,420,498,440,767,579,711,139,423,112,558,643,342,854,344,299,799,692,656,758,941,399,795,349,164,724,479,903,407,258,306,409,863,982,3,352,616,609,49,403,676,167,774,225,622,484,98,531,365,434,432,50,635,669,800,672,145,214,708,713,738,634,93,710,449,245,210,538,359,928,662,172,782,929,740,366,54,456,974,878,266,106,300,335,41,328,884,498,359,657,854,60,658,999,322,345,220,936,915,242,674,418,9,765,5,867,795,452,773,759,957,405,443,570,620,421,419,966,450,493,315,198,951,228,303,902,994,107,585,50,27,104,654,933,305,566,89,476,577,834,246,227,341,712,637,36,960,321,415,309,868,71,660,80,722,198,961,549,51,933,914,754,777,564,359,824,439,808,11,556,796,796,933,262,657,186,12,121,190,581,765,852,603,236,432,255,407,83,723,997,474,626,341,625,767,955,596,581,148,443,891,588,321,877,554,945,521,266,94,404,735,343,992,435,521,238,958,854,275,672,324,439,132,17,299,790,39,373,807,743,217,26,623,695,104,968,79,406,487,191,668,75,443,668,608,564,366,857,825,615,935,629,878,462,30,304,916,313,386,219,350,104,974,34,944,524,472,666,660,95,598,687,294,359,813,137,718,826,652,281,615,708,877,318,108,554,715,325,533,882,93,496,341,913,561,136,186,105,886,468,239,729,180,967,127,110,90,807,386,552,947,829,444,310,319,740,902,805,185,1000,731,840,659,667,791,50,135,431,435,857,450,935,307,644,645,775,301,205,131,479,191,40,915,97,201,945,681,981,3,686,217,436,443,167,802,639,207,623,264,832,816,181,99,476,992,683,724,268,470,484,795,857,929,96,687,26,755,431,554,997,980,334,58,365,24,622,752,268,342,131,690,900,336,78,217,763,917,422,422,682,892,945,310,144,238,47,851,93,211,640,237,373,284,570,548,394,74,114,315,378,831,267,193,738,259,942,348,291,805,180,270,232,649,141,417,794,857,628,404,586,240,51,735,287,959,75,160,98,885,371,600,649,240,552,837,512,593,927,100,60,526,352,101,601,155,649,604,343,463,424,62,407,131,979,895,716,359,289,658,691,497,51,164,622,139,787,447,118,759,712,868,56,253,876,458,787,292,836,727,290,445,279,266,900,599,172,928,18,977,579,429,218,84,427,774,266,517,927,844,261,762,140,135,711,590,796,97,184,873,108,553,322,589,343,67,834,529,481,851,126,593,224,350,202,54,830,870,837,184,287,831,874,100,625,864,776,700,622,253,105,849,998,673,399,760,489,130,206,667,227,442,606,908,594,88,489,628,189,453,847,637,629,17,568,841,130,262,890,812,16,281,323,58,675,277,833,698,393,846,68,602,699,31,496,261,366,552,901,149,682,519,934,275,95,149,400,519,226,348,238,940,888,708,957,327,854,561,39,418,0,46,302,693,80,940,473,69,779,258,562,926,832,529,72,633,361,753,493,953,438,902,873,268,31,106,874,515,832,435,265,670,515,123,90,979,883,985,883,223,344,891,931,700,291,831,558,138,704,144,858,816,135,481", "653,480,11,600,999,190,372,907,505,372,458,975,850,70,822,227,421,690,820,291,487,219,883,692,276,279,745,477,723,810,537,182,537,676,958,942,925,92,220,579,868,52,164,155,654,614,243,821,62,153,792,119,487,355,526,360,280,542,969,361,619,320,131,4,569,829,679,646,701,337,386,470,327,961,297,591,550,461,140,639,445,283,853,573,396,975,717,696,5,208,721,67,90,634,320,635,644,456,922,611,222,568,956,304,313,386,128,648,638,12,530,918,832,52,849,894,751,591,579,3,477,424,165,253,810,448,255,856,960,760,341,326,933,849,276,443,364,560,694,36,782,179,820,503,131,571,167,983,909,980,228,408,447,661,808,885,521,396,226,666,973,93,28,197,526,174,780,178,673,556,276,430,136,584,535,616,564,275,317,852,917,801,576,560,839,623,99,921,822,736,421,764,856,412,247,450,765,867,960,216,324,225,25,978,195,232,239,631,763,596,929,134,178,244,714,67,763,944,578,52,365,163,175,145,117,777,91,98,716,472,517,807,217,612,731,160,704,767,985,701,233,158,212,175,537,289,581,773,878,360,265,206,852,649,862,898,387,463,457,563,891,900,427,106,212,549,530,176,789,67,21,735,802,112,144,323,812,622,833,457,168,389,328,629,172,218,962,35,3,155,383,688,753,486,721,209,107,16,109,503,168,272,579,306,105,866,750,924,562,438,562,834,263,182,55,63,436,80,647,255,669,214,805,27,958,131,132,536,362,720,210,643,217,723,239,630,728,567,33,233,36,929,343,629,618,803,671,631,936,191,831,76,472,132,578,754,269,322,947,555,766,859,35,53,269,337,641,560,458,586,605,103,101,718,798,2,691,891,739,936,923,240,478,739,182,198,675,428,899,341,75,896,322,105,786,178,532,263,327,172,925,427,354,956,773,274,139,820,126,703,534,169,483,865,765,674,299,606,105,138,830,111,986,388,473,329,688,779,574,388,997,640,254,46,270,762,574,886,803,307,542,756,370,103,619,267,158,647,284,63,794,854,949,833,3,411,176,755,339,589,192,377,737,494,321,533,236,828,704,170,622,680,573,226,849,946,790,810,382,718,65,603,605,711,493,884,609,677,324,384,92,408,994,261,275,939,68,303,655,340,366,548,796,505,852,294,221,514,717,675,499,221,183,583,832,326,358,203,260,152,267,783,363,849,147,842,310,432,245,349,22,886,164,972,321,767,459,250,612,115,853,273,542,764,43,981,165,864,160,634,380,585,670,983,101,835,438,953,473,877,939,974,830,626,477,370,244,13,427,288,501,535,154,44,560,998,328,557,3,317,951,804,225,616,933,200,68,447,890,359,590,731,249,979,56,329,979,772,967,656,308,149,239,970,716,135,667,41,125,756,78,563,955,262,277,565,953,800,970,730,150,619,350,933,11,349,392,986,847,222,577,749,229,435,368,674,779,46,689,2,519,146,896,517,663,435,836,576,795,206,688,489,367,266,817,372,773,156,640,611,660,512,180,831,708,322,734,153,366,466,662,252,561,110,958,687,136,468,963,220,235,449,296,785,17,525,335,379,141,686,218,585,213,493,527,378,388,128,873,471,505,751,632,964,798,958,881,497,468,12,955,122,175,965,768,189,538,298,167,787,663,993,60,967,227,877,712,967,802,548,905,627,312,914,955,305,570,328,225,886,739,605,314,561,935,394,718,344,618,741,575,975,689,903,667,21,229,42,867,634,919,797,765,90,853,442,692,89,955,747,765,529,918,110,517,888,294,931,980,563,761,723,159,310,182,961,812,169,586,752,154,382,506,869,23,806,956,340,115,330,122,531,598,653,331,311,98,166,143,952,329,475,310,272,646,53,914,649,157,186,311,628,695,886,339,496,43,484,555,868,880,997,581,173,51,676,307,597,516,375,82,846,129,532,523,399,111,307,869,993,591,224,958,736,170,978,381,246,267,457,789,911,461,744,547,972,358,156,628,879,38,227,348,297,776,234,283,191,62,731,350,435,557,908,225,189,163,497,2,643,654,872,184,649,333,536,271,681,747,926,122,297,856,574,783,827,192,495,992,640,362,343,574,936,993,403,314,334,396,348,924,302,951,924,148,881,351,933,773,270,553,756,778,601,134,461,304,602,119,387,525,830,121,333,72,5,46,0,635,206,149,434,157,519,58,436,297,197,460,345,494,22,637,658,539,258,90,718,162,187,436,247,498,833,718,192,345,796,445,787,277,539,675,179,453,647,469,712,126,424,230,195,702,954,35,440,442,38,973,899", "352,949,470,429,854,73,660,373,679,873,908,291,676,312,879,741,75,188,626,143,328,212,975,752,414,961,930,523,999,970,133,156,958,324,583,580,415,512,468,369,898,46,98,876,338,389,527,867,348,760,639,32,592,787,443,889,358,348,13,723,888,593,728,953,822,212,857,761,959,65,253,258,449,704,268,816,838,165,744,923,869,342,982,22,770,473,888,278,211,34,666,490,346,40,61,851,97,790,115,798,110,24,573,625,104,838,440,263,642,893,789,794,197,167,726,953,529,693,648,763,46,368,512,938,619,389,797,393,258,365,889,604,513,14,342,448,781,33,364,767,157,673,500,9,300,117,893,26,822,615,173,209,659,92,328,98,788,553,643,79,542,66,339,749,755,511,198,696,98,73,615,597,173,694,550,21,89,892,692,11,988,307,980,28,272,896,668,231,613,589,867,344,313,399,31,421,459,439,493,756,532,676,577,883,646,240,354,992,822,555,251,18,319,618,643,782,1,998,871,489,938,13,565,142,61,778,323,41,299,479,678,718,73,541,767,874,513,385,173,399,433,338,107,113,926,920,931,776,14,982,975,666,180,57,399,375,372,982,167,499,661,188,505,134,408,912,992,129,486,219,38,920,297,64,5,346,742,490,641,367,77,127,460,104,395,535,185,980,363,858,572,804,141,754,594,964,114,516,232,838,9,311,94,855,583,202,968,743,431,669,467,842,404,566,279,803,88,472,392,705,277,298,376,904,789,418,243,661,866,48,270,523,387,470,631,724,639,438,583,908,464,249,732,774,800,554,413,797,856,118,176,269,453,956,60,690,962,320,322,548,59,817,34,4,702,611,621,417,657,645,655,675,804,862,39,83,762,173,351,458,401,806,363,278,400,324,83,277,406,935,688,688,9,758,605,94,469,550,796,679,644,655,23,959,195,81,992,389,255,717,104,63,856,143,950,764,33,575,870,458,689,669,431,959,863,186,221,342,99,15,940,814,439,348,61,515,354,190,447,485,620,542,463,717,800,998,868,739,820,245,426,830,122,152,871,837,878,401,221,540,631,348,555,591,52,379,622,250,45,639,667,555,474,312,399,609,962,446,224,392,245,808,780,723,544,187,474,544,253,919,788,453,462,861,921,330,438,941,501,696,475,296,543,304,825,919,590,644,419,769,619,887,798,690,370,931,976,364,455,64,381,407,341,895,16,937,759,250,114,707,65,74,343,233,746,944,923,163,40,906,679,29,731,95,129,713,442,480,192,913,601,264,220,9,753,618,34,193,788,898,263,355,301,822,310,168,859,722,910,605,686,204,738,719,936,584,936,819,458,122,528,881,114,120,390,815,412,196,608,503,393,11,884,538,943,855,182,825,617,975,743,805,322,57,180,333,935,496,925,883,565,370,582,662,152,853,434,132,481,282,321,605,559,839,754,627,291,769,907,935,14,871,788,757,599,702,161,195,628,396,351,543,467,70,696,205,455,820,257,572,621,775,15,183,549,685,307,572,651,172,447,727,187,428,95,963,106,89,74,691,527,24,114,723,811,754,112,264,466,498,155,548,650,562,330,592,14,458,113,629,18,686,829,327,335,238,939,890,439,463,312,13,453,386,361,925,128,102,974,832,972,582,661,112,244,565,665,82,188,972,978,477,59,72,754,730,812,535,763,820,961,931,794,87,821,231,622,382,264,545,212,134,465,394,615,665,328,350,548,856,6,783,494,955,79,773,754,917,463,51,294,93,350,547,651,373,403,706,127,435,486,385,993,139,177,787,378,718,156,215,563,268,849,18,32,523,463,101,953,670,920,830,449,200,97,300,269,366,494,28,93,337,253,189,307,939,510,399,589,963,700,51,403,363,84,369,825,929,821,293,35,776,558,368,130,518,433,728,288,532,498,142,159,989,507,51,628,244,991,725,442,530,995,336,822,668,440,524,753,811,925,664,154,648,130,597,73,102,271,754,964,698,524,920,207,610,660,232,731,446,137,603,687,418,739,394,231,340,256,252,245,716,583,391,146,732,157,486,273,810,763,959,978,968,285,865,381,708,697,640,681,38,750,656,288,231,510,331,121,377,605,55,572,546,12,380,519,138,231,814,720,245,147,917,973,835,865,919,978,383,28,40,206,249,344,30,880,580,680,664,21,173,56,725,644,512,302,635,0,769,877,552,216,212,635,847,259,485,514,736,491,122,912,22,532,490,497,682,978,769,186,650,206,951,533,392,356,860,672,817,948,843,89,940,718,522,987,645,450,542,763,113,779,133,338,268,189,79,994,798", "619,133,583,600,307,647,484,969,351,354,297,52,4,721,10,790,103,849,391,8,908,47,290,644,859,680,929,11,176,917,371,738,437,519,40,444,988,655,294,89,141,960,986,980,702,352,29,776,690,187,532,362,954,632,393,614,667,271,500,16,662,633,835,372,280,58,742,890,780,820,882,710,373,402,130,375,700,300,814,726,166,75,629,515,634,358,622,920,948,358,356,125,124,629,235,274,989,591,115,51,399,285,510,868,144,795,818,78,306,623,386,80,736,961,76,796,571,12,645,106,820,777,710,122,472,513,750,479,688,392,855,590,577,865,334,918,658,106,222,13,807,568,470,131,964,221,570,698,815,573,622,140,259,865,137,232,278,458,152,619,653,162,792,45,816,548,136,281,512,153,114,332,534,319,131,804,33,32,346,413,629,195,569,386,229,7,4,486,495,662,518,210,406,661,4,157,200,572,958,380,753,166,102,882,824,702,907,75,17,505,20,569,299,696,198,585,990,557,114,554,507,956,590,180,377,208,413,836,494,738,311,655,916,709,345,204,848,294,307,49,286,62,883,662,152,96,16,293,713,453,769,678,93,690,645,3,771,601,77,445,875,549,401,620,54,871,320,435,542,784,873,620,305,324,797,674,231,722,739,311,921,303,813,17,698,938,676,105,345,300,144,617,58,820,466,873,504,708,405,93,837,667,903,939,853,802,384,669,455,391,132,783,456,464,875,508,833,95,723,190,661,966,966,487,181,502,386,281,415,994,865,645,591,561,398,873,674,116,190,540,369,227,23,243,310,311,427,378,674,452,608,426,752,188,744,413,205,209,759,984,685,71,732,521,566,326,707,109,999,869,30,997,17,146,829,363,802,4,599,848,661,972,251,888,915,874,28,782,821,152,603,418,157,105,130,885,102,73,181,693,692,774,878,301,621,654,82,573,700,151,91,13,518,493,607,648,15,503,209,822,287,635,451,973,440,255,720,499,63,499,358,168,374,975,40,910,449,923,61,705,902,376,127,955,798,212,342,846,822,241,488,731,284,932,685,512,225,743,304,953,192,47,912,896,443,103,843,827,157,748,541,49,307,860,180,344,981,311,564,427,901,174,854,721,634,663,50,794,628,709,597,432,164,815,949,364,28,57,792,596,830,677,779,965,688,224,225,489,311,511,581,173,700,790,867,999,438,911,373,330,986,885,365,140,622,904,700,35,134,306,842,601,908,852,888,316,357,43,879,881,690,638,824,369,394,861,328,951,14,79,569,774,143,772,151,235,149,439,169,70,305,59,237,622,749,604,752,940,607,294,663,595,13,288,864,474,913,199,880,195,347,375,524,237,140,641,962,270,314,805,855,759,982,815,125,460,400,566,962,611,441,481,401,338,78,688,905,615,131,404,722,885,485,35,812,621,442,733,809,977,549,327,44,998,545,572,819,589,704,393,396,380,474,798,799,697,824,399,860,213,509,381,704,183,105,427,278,885,957,961,121,246,89,449,982,555,641,919,257,317,12,614,409,978,32,923,249,979,382,874,759,911,316,525,123,519,180,430,346,466,508,718,589,528,997,916,276,122,274,276,699,794,409,410,377,117,731,788,942,42,169,181,85,422,441,176,716,755,579,450,599,372,307,947,50,21,66,310,89,533,616,249,155,882,177,957,147,970,696,718,833,838,725,851,502,566,67,320,632,358,26,774,663,195,647,863,939,823,898,639,710,988,383,651,285,486,627,815,759,195,547,536,250,999,585,526,937,46,24,916,674,648,470,61,626,788,831,535,553,83,622,145,9,538,544,890,193,885,421,603,684,210,356,418,291,243,289,498,172,602,925,898,230,263,554,557,873,696,611,192,770,313,7,119,461,683,955,613,672,850,649,550,797,553,935,452,690,767,701,625,723,752,386,171,802,869,717,554,806,413,376,816,723,177,373,626,607,358,709,477,865,210,238,448,83,644,798,963,786,474,42,152,991,868,267,245,839,518,84,496,508,845,579,132,427,521,51,136,953,275,202,25,976,728,824,9,970,67,510,594,839,280,604,541,649,137,555,160,351,966,872,275,234,552,994,83,209,641,853,118,83,739,340,628,78,777,290,809,728,324,596,29,982,456,935,521,846,400,404,57,778,227,639,785,276,834,825,852,751,716,476,885,236,24,772,926,693,206,769,0,674,374,156,491,90,687,456,997,360,378,708,337,551,955,14,167,582,919,873,941,641,857,918,107,922,86,296,16,511,302,313,322,40,91,695,560,57,446,239,657,455,94,434,862,178,570,96,884,57,145", "733,947,601,92,510,715,5,19,31,78,67,57,250,883,351,5,473,285,927,866,772,932,153,612,743,612,320,800,589,157,573,581,409,375,630,827,545,754,657,438,293,55,239,350,831,225,882,885,332,238,562,49,533,764,74,488,112,405,334,743,802,953,397,367,952,893,659,981,143,605,856,875,16,541,191,853,682,304,640,918,512,180,77,451,614,548,406,461,248,619,130,639,511,570,158,510,940,531,737,170,538,693,756,560,77,386,224,398,951,501,524,503,78,635,488,405,433,986,768,197,842,709,920,236,428,330,387,865,967,369,881,98,292,471,727,194,164,402,202,514,9,381,573,433,491,171,433,185,264,563,65,859,445,752,76,742,300,158,701,974,259,444,945,94,418,128,604,990,245,467,848,397,244,542,737,24,595,161,111,190,502,611,481,514,607,987,332,196,701,802,579,853,277,908,291,40,980,351,920,377,599,401,812,214,486,251,654,80,691,140,308,712,623,533,264,444,865,453,318,899,521,434,589,131,952,890,858,340,841,247,251,789,155,773,748,698,829,757,812,894,924,757,667,956,706,455,188,245,89,440,327,410,249,825,615,462,56,390,784,879,745,731,897,640,230,261,978,502,390,292,980,276,880,481,555,478,441,943,446,38,201,509,486,779,776,776,174,155,408,777,601,257,879,785,560,994,787,759,35,912,884,313,990,47,242,528,907,109,876,724,432,905,38,885,141,231,111,715,884,442,965,801,693,496,646,340,933,396,82,215,709,231,9,63,904,918,910,496,719,440,886,706,274,195,829,821,42,613,815,588,473,75,976,762,480,987,675,854,450,872,225,437,73,81,334,676,110,991,726,142,682,892,703,210,287,98,678,533,224,920,217,987,252,486,667,494,755,165,590,428,88,756,594,841,494,646,638,865,524,380,461,708,98,529,588,321,40,112,584,261,678,283,595,450,365,507,45,869,820,719,980,327,496,254,92,330,767,73,671,60,285,92,685,562,20,8,573,69,352,218,711,507,558,228,786,791,312,238,594,300,516,315,785,501,113,236,530,357,706,822,536,896,632,97,155,591,638,895,113,830,994,938,455,928,875,131,48,761,630,750,186,954,649,986,709,430,444,826,521,546,400,917,499,70,592,254,186,821,473,826,222,975,172,212,819,535,300,903,259,822,404,363,237,947,420,796,561,901,698,768,578,46,687,936,688,381,439,607,918,656,864,412,398,792,720,422,758,57,510,616,877,823,314,455,376,240,434,320,703,317,119,212,57,58,728,202,796,206,838,837,437,204,104,685,241,366,87,841,955,551,472,668,171,136,797,753,639,455,392,370,574,547,752,832,494,836,39,216,671,219,525,931,863,881,743,366,573,381,377,88,322,535,737,928,752,999,829,328,971,282,895,932,83,694,380,655,397,17,505,462,992,202,306,961,76,768,244,488,297,444,796,977,181,650,563,288,687,269,249,945,169,232,781,10,483,728,848,975,637,612,210,73,819,505,657,640,327,966,586,777,878,333,297,301,25,21,52,62,33,440,154,808,401,500,40,357,739,16,104,97,769,255,374,141,25,624,233,224,974,927,606,685,971,38,589,259,174,123,13,804,935,713,364,70,454,151,650,766,873,10,138,776,22,474,824,527,75,282,408,257,738,596,874,562,81,202,305,404,460,804,457,362,276,318,38,760,489,243,420,429,636,106,891,147,917,613,691,850,988,76,272,421,973,95,737,784,15,831,962,919,171,567,866,952,865,181,415,941,379,608,550,142,797,78,273,93,846,364,548,414,187,108,244,471,306,731,527,326,20,854,165,365,152,63,213,467,387,726,728,565,48,90,788,311,765,126,600,799,641,874,260,505,647,2,435,372,439,285,734,368,379,572,708,8,865,884,630,675,64,799,166,504,950,125,692,664,346,447,637,383,775,887,548,396,450,341,174,74,62,296,872,877,961,630,253,405,724,30,831,344,914,942,903,155,117,426,615,281,740,337,180,174,828,155,45,947,537,579,238,141,195,43,945,99,440,384,404,109,755,861,254,915,371,29,93,719,992,982,662,826,653,801,738,821,414,888,42,257,944,500,228,691,210,762,847,414,36,120,616,411,353,700,329,990,957,862,347,559,762,843,563,999,11,905,287,746,79,472,223,790,730,616,73,682,887,489,80,149,877,674,0,311,172,602,140,20,599,787,575,471,289,388,606,786,839,543,634,720,514,945,984,604,796,189,406,925,228,549,374,315,221,465,947,961,264,414,452,867,650,410,243,625,750,762,565,387,150,746,378,225", "275,204,973,276,421,315,758,346,667,52,492,991,921,62,188,759,23,452,55,611,813,586,414,34,364,221,756,448,429,670,704,445,854,137,417,369,403,228,268,845,759,967,110,314,283,533,491,886,183,750,219,200,347,239,2,939,303,960,224,338,609,940,670,821,383,528,859,808,147,692,984,479,524,28,863,615,529,63,136,275,172,858,39,441,30,250,616,533,327,346,393,264,902,13,299,250,883,938,937,168,276,498,452,370,749,279,678,856,455,383,478,334,818,831,612,517,170,210,245,453,924,318,481,608,729,435,244,61,316,679,418,975,239,933,474,862,724,720,955,575,720,722,999,646,615,431,727,146,59,480,187,384,570,454,810,453,821,658,602,9,397,628,549,453,459,875,182,813,155,563,597,294,154,421,716,479,986,774,376,341,325,395,951,566,441,684,264,894,156,639,96,12,143,976,306,406,757,619,151,155,14,625,902,708,107,473,362,807,350,896,855,389,11,556,589,306,580,140,575,530,756,868,276,413,190,94,851,838,897,106,736,299,104,778,49,873,167,275,63,671,80,589,757,595,234,965,406,332,629,157,853,458,340,410,735,648,995,922,219,930,740,726,86,631,758,786,70,70,359,491,326,956,209,238,778,101,950,866,356,736,145,374,440,804,192,300,810,490,963,765,689,142,939,825,984,799,216,629,60,614,442,689,412,913,368,928,698,808,49,908,424,131,126,264,618,400,515,411,843,489,122,445,606,875,657,334,341,250,940,792,383,959,528,856,715,222,320,623,928,701,521,697,612,18,424,270,848,323,371,656,437,374,526,823,778,35,733,411,184,38,995,899,759,230,589,78,26,554,410,842,493,629,873,595,363,760,740,43,921,605,280,223,252,355,340,893,270,333,663,813,20,79,939,540,10,130,949,618,668,70,56,282,111,187,726,828,191,205,59,4,44,968,493,561,400,166,487,630,718,310,207,617,213,480,82,147,528,254,910,347,558,674,841,935,520,163,921,273,912,781,363,479,259,540,245,745,201,5,507,22,523,590,73,262,500,130,435,879,997,156,972,195,925,422,779,432,399,901,239,360,250,74,786,144,741,84,880,594,268,313,152,124,172,744,654,162,352,519,685,918,38,209,545,608,604,229,459,497,771,166,50,261,876,501,829,462,173,533,657,606,298,536,447,123,801,774,179,957,931,976,149,402,847,866,10,471,170,390,444,322,721,289,831,223,463,534,823,843,475,695,80,222,209,57,387,268,157,668,376,979,612,819,19,446,764,416,641,541,601,735,870,638,46,259,922,664,500,42,431,581,860,981,555,908,463,603,653,537,984,618,475,280,846,106,296,464,537,319,325,907,456,638,389,598,140,270,242,195,955,484,631,97,77,867,724,153,912,958,954,875,695,388,167,568,456,884,799,691,321,194,130,864,103,878,796,564,430,120,761,709,76,248,566,119,991,531,785,328,985,253,380,162,505,651,64,475,234,612,685,717,242,98,729,540,92,57,442,743,346,683,430,596,658,963,340,859,818,441,766,633,497,25,942,968,322,603,820,193,584,979,123,923,577,572,188,898,118,49,646,623,592,354,371,675,397,980,668,794,32,844,782,439,736,369,632,159,855,919,565,295,161,826,877,409,167,405,14,73,418,876,736,42,727,837,151,204,220,386,788,205,25,396,980,936,437,464,333,691,396,830,339,275,430,660,243,153,756,886,16,649,407,868,424,893,224,436,776,273,945,622,490,589,76,31,874,852,814,224,573,431,366,160,627,185,503,566,234,873,654,394,439,786,493,92,789,75,373,960,422,858,909,802,856,844,748,945,301,911,65,10,871,576,606,699,201,761,143,724,543,960,474,873,511,272,345,20,307,434,240,678,914,777,784,729,577,787,843,301,416,713,694,307,204,138,63,846,928,767,563,696,199,166,691,440,419,392,421,68,388,348,739,590,478,531,965,324,237,408,687,547,126,325,463,892,353,606,841,466,189,206,430,569,835,832,985,858,324,321,834,325,106,171,655,343,701,135,70,812,703,110,463,404,350,118,514,796,8,577,629,358,994,13,332,963,974,105,55,953,853,351,873,892,425,778,945,105,105,343,312,728,435,246,512,134,278,654,957,934,443,248,737,179,158,608,802,110,279,459,994,245,293,593,165,940,985,893,940,434,552,374,311,0,608,843,904,172,92,803,26,607,102,635,576,88,895,565,859,973,166,627,421,240,208,193,77,708,160,174,817,909,827,136,66,610,146,790,21,551,587,596,432,377,911,907,173,352,755,68,886,983", "753,246,266,650,702,877,35,504,103,980,983,281,413,997,125,122,954,81,854,620,174,14,393,831,554,782,634,181,523,385,585,523,564,58,786,17,320,441,847,578,470,143,1,667,814,683,930,124,121,247,273,822,914,360,508,16,734,322,172,776,605,347,777,245,710,129,196,541,485,97,246,78,55,304,659,917,542,507,707,953,395,844,677,321,696,917,512,333,185,411,118,474,264,600,359,898,612,924,647,617,675,77,683,589,745,55,393,954,296,309,409,22,594,440,389,770,898,551,208,601,255,61,770,201,511,835,577,589,77,193,741,317,781,521,755,416,335,661,2,555,70,404,693,293,812,561,636,751,243,362,114,612,127,334,657,721,828,714,801,901,886,335,703,993,976,363,484,845,633,239,192,580,599,922,861,839,634,631,293,84,616,969,936,91,470,705,25,250,657,817,426,29,974,266,226,197,695,101,456,619,7,895,126,422,747,736,951,784,309,57,20,207,898,944,724,374,290,474,686,642,68,10,889,326,151,692,811,853,192,204,859,774,577,628,449,367,264,146,905,731,659,401,530,793,62,577,597,755,837,843,317,635,386,8,284,424,27,513,477,318,128,621,422,83,568,47,562,359,397,137,81,953,554,162,719,387,382,278,707,89,186,593,514,525,59,56,443,582,862,925,675,924,461,779,515,522,344,846,461,997,152,990,489,804,345,208,464,752,169,579,556,395,456,429,906,170,714,589,37,918,72,248,587,264,388,882,178,569,734,514,805,293,484,939,296,954,16,813,392,929,887,945,748,624,827,790,489,31,985,135,560,758,968,17,161,952,678,839,792,720,85,168,886,517,592,99,418,432,709,898,942,473,778,18,40,419,302,116,53,35,493,286,664,901,379,313,63,782,481,30,788,236,923,875,521,5,239,470,894,471,634,943,918,128,31,809,702,655,917,782,541,931,745,863,291,764,692,994,684,217,639,128,825,522,356,391,154,799,605,921,141,357,854,776,93,607,597,754,992,218,306,64,294,12,160,888,319,557,33,135,570,94,762,311,310,106,455,181,66,356,199,303,895,389,402,745,678,703,662,22,903,528,943,533,74,994,986,938,322,473,58,12,968,476,859,803,635,90,110,151,544,717,590,203,455,512,293,445,729,123,801,671,892,772,171,38,224,855,612,28,189,974,223,472,172,733,839,485,353,722,833,988,471,361,831,753,183,94,336,871,940,110,488,871,470,112,286,347,878,139,630,338,228,928,545,977,87,277,629,120,511,848,97,672,882,407,386,442,683,579,695,586,375,950,143,315,575,216,466,738,261,361,761,670,69,434,433,202,711,730,535,331,638,751,579,9,532,67,292,161,914,575,34,197,218,327,309,945,669,604,124,427,462,610,592,433,237,567,924,297,800,721,481,731,759,420,198,222,43,522,852,751,419,885,806,259,537,595,872,599,81,50,893,536,968,603,291,296,247,902,182,598,946,262,61,313,635,830,902,958,976,137,439,850,719,19,381,704,377,933,714,276,449,979,15,356,170,727,708,966,391,955,283,824,463,233,997,872,765,534,720,931,160,526,593,522,976,745,901,364,498,226,888,427,258,939,697,119,508,690,276,282,111,749,532,463,927,425,212,620,713,441,760,943,656,527,27,338,688,310,823,300,420,215,785,399,493,782,328,785,94,8,215,900,527,623,812,776,752,818,388,82,940,429,543,395,166,93,234,517,808,603,728,738,62,798,720,70,458,977,357,658,716,910,783,900,604,125,18,495,847,203,18,443,316,425,714,951,256,816,601,203,468,377,753,607,114,768,97,247,490,27,880,649,271,448,635,81,216,397,325,889,727,371,710,208,244,517,637,367,784,973,401,628,172,611,513,553,526,16,861,374,94,206,666,214,654,270,797,84,553,977,201,191,533,897,965,209,706,338,116,106,102,418,84,578,741,750,327,961,531,565,167,191,117,27,770,667,527,41,550,437,37,24,593,104,641,798,559,837,138,228,513,159,473,451,369,450,59,892,7,691,421,953,734,362,38,286,179,960,837,281,321,119,195,942,164,997,166,822,59,578,668,971,171,574,769,684,810,263,404,595,436,138,428,258,669,840,93,403,113,910,755,526,74,14,253,130,717,241,700,572,209,704,122,478,893,835,177,510,757,532,580,354,955,790,473,157,216,156,172,608,0,118,772,562,167,574,15,841,696,520,98,647,712,238,886,289,478,627,99,69,193,220,745,662,685,145,220,13,63,484,999,458,943,617,384,995,662,353,604,895,562,502,631,722,662,688,45,251", "257,782,88,489,158,162,707,455,362,212,411,359,590,28,869,168,94,303,483,643,709,309,556,516,874,715,807,764,748,290,146,969,992,94,221,186,95,728,175,643,508,802,386,798,914,581,853,924,469,701,420,550,516,649,916,376,520,295,850,319,431,786,606,79,813,289,237,771,918,8,518,262,724,316,441,684,830,769,651,436,665,494,362,829,894,237,933,474,446,282,229,141,394,300,172,507,641,439,804,632,321,415,866,650,479,65,249,324,606,327,708,725,568,71,156,711,156,141,69,35,964,443,292,999,393,65,387,989,774,84,772,769,884,610,894,142,421,80,936,265,279,62,602,577,551,294,557,931,947,35,418,716,182,998,841,572,623,211,395,796,210,804,205,875,992,443,852,593,850,534,581,845,464,654,359,25,239,737,413,104,924,891,880,613,568,701,283,162,459,676,548,847,763,751,146,787,9,961,868,305,630,457,388,523,770,704,720,524,385,112,407,759,883,606,111,399,162,257,914,545,91,413,458,879,886,43,589,484,868,759,952,691,640,3,39,274,695,474,597,68,513,821,149,21,413,442,94,662,30,262,938,598,63,377,404,84,465,339,381,50,566,890,612,477,847,460,579,362,994,719,823,32,853,684,402,498,329,339,728,883,157,58,80,921,683,192,362,168,557,508,167,121,592,770,618,19,205,402,105,783,156,103,658,909,485,990,1,513,136,635,501,136,488,20,597,460,245,823,78,209,410,419,639,742,366,822,399,694,965,812,490,605,305,635,415,577,868,964,781,670,351,996,344,749,884,693,989,846,874,54,371,533,394,998,884,533,365,590,941,297,981,298,291,746,379,742,847,120,524,751,738,140,347,502,881,798,459,116,81,442,119,54,790,17,798,885,852,328,449,821,515,320,585,150,656,598,991,165,955,612,466,590,842,524,597,52,294,753,719,632,178,934,813,251,249,717,21,875,412,426,171,48,716,696,61,727,343,513,928,679,591,924,180,875,296,270,903,445,83,695,187,244,452,104,635,791,805,973,607,868,778,452,294,198,905,223,929,451,58,596,91,383,659,500,862,460,959,467,164,837,26,827,348,193,649,294,834,813,473,169,392,994,656,777,191,33,1,37,974,709,330,686,334,17,550,26,548,455,336,669,176,197,471,195,630,660,247,411,448,935,51,336,189,695,435,370,39,14,336,417,874,544,755,560,982,175,818,347,617,944,38,947,177,142,412,428,335,214,786,197,231,80,758,21,523,229,249,386,756,17,197,865,857,730,185,541,862,377,589,553,318,272,766,814,782,685,497,671,257,491,529,779,996,382,255,69,141,323,153,583,961,283,878,982,177,759,911,830,115,697,698,521,480,503,159,64,639,551,790,596,437,270,534,107,929,346,416,783,504,260,823,143,141,252,104,895,747,621,473,37,275,297,326,443,758,997,35,13,203,454,797,620,966,363,91,377,123,724,718,706,89,549,819,230,338,58,563,331,450,934,229,997,614,110,545,348,264,961,959,248,515,445,336,898,989,275,321,296,141,665,209,777,754,357,608,901,324,291,600,870,786,700,102,532,16,788,236,834,13,202,417,45,702,996,308,144,294,563,221,916,676,942,40,102,584,154,779,933,747,85,812,684,152,865,523,10,271,756,945,236,688,677,441,415,819,743,442,243,929,870,884,440,669,333,281,147,806,842,902,401,672,934,532,572,450,921,689,161,10,429,316,513,969,658,521,709,946,901,931,916,93,294,905,255,22,685,977,297,209,295,212,944,30,602,382,886,371,297,551,46,420,51,963,942,129,878,528,411,480,826,715,766,68,997,474,524,849,716,742,567,351,789,388,531,375,278,823,550,68,187,438,437,187,953,313,543,352,505,177,647,312,282,680,65,512,16,672,400,285,962,223,841,965,644,796,88,514,273,906,524,366,417,53,850,407,944,958,172,199,796,154,46,384,550,957,886,424,957,809,543,778,613,353,465,945,539,761,516,516,352,352,504,147,470,563,895,69,86,430,899,703,677,58,453,616,555,824,182,161,859,850,640,145,277,722,988,385,107,485,16,51,603,733,655,512,703,571,395,477,576,716,470,785,469,670,63,533,853,290,272,39,694,413,511,624,117,96,224,757,650,211,903,224,227,808,302,946,97,247,15,524,146,101,316,473,70,69,519,212,491,602,843,118,0,939,867,708,417,389,993,434,735,264,621,433,808,149,174,669,970,828,942,814,891,542,223,262,420,554,191,43,945,204,76,704,178,963,315,527,134,539,431,409,828,926,627,552,239,172,561", "766,244,141,804,19,417,982,941,311,943,6,819,278,187,910,139,759,303,105,793,796,643,621,959,623,904,115,871,398,920,745,587,421,996,798,373,477,259,172,217,289,530,501,899,520,444,797,959,676,849,895,692,250,170,355,887,966,825,605,132,92,613,692,568,111,758,229,93,125,858,616,790,232,733,349,960,371,617,442,475,171,824,501,222,394,924,932,454,393,188,484,455,445,58,868,632,737,946,45,180,741,681,673,389,333,638,394,672,982,480,456,237,61,810,360,283,643,959,649,923,469,337,278,297,963,38,423,170,655,399,765,418,849,894,289,684,61,647,970,639,28,628,552,857,19,728,400,271,222,105,53,714,272,746,674,406,518,740,290,507,701,179,767,875,243,885,616,312,602,328,326,715,972,255,404,788,453,427,852,859,841,191,809,299,443,975,742,442,38,555,666,722,43,328,361,124,295,828,326,168,538,572,845,758,199,566,860,177,537,192,378,281,988,767,798,403,894,204,787,521,151,738,49,853,985,27,653,81,164,714,223,47,551,693,141,381,158,747,443,60,872,1,783,517,559,215,240,592,853,383,703,542,338,110,800,589,315,892,595,717,866,360,395,256,816,717,68,137,830,900,989,74,121,708,696,549,730,425,313,674,364,978,468,438,378,423,63,557,229,126,726,287,889,376,102,630,708,906,359,962,789,377,881,899,240,378,423,184,965,430,676,882,343,782,926,484,225,382,133,245,495,387,456,536,502,181,376,944,960,781,56,881,988,565,355,56,111,592,262,577,180,76,736,284,926,780,722,54,600,17,497,971,802,807,646,295,43,537,722,747,407,805,595,224,359,230,762,795,59,724,330,452,418,604,747,390,374,597,57,672,876,534,983,925,110,183,223,83,319,170,454,580,678,767,670,206,43,282,942,444,23,288,410,675,952,754,27,717,494,211,409,596,428,967,394,182,60,36,927,213,224,683,158,223,782,616,549,848,997,475,617,996,183,102,268,796,402,177,193,343,127,756,446,887,730,483,621,819,572,641,564,703,707,672,753,778,651,358,339,463,76,746,188,657,879,119,91,725,175,944,698,184,81,460,713,281,852,64,590,206,596,184,697,289,743,528,591,290,314,111,632,667,809,961,904,784,804,778,288,792,297,21,598,109,706,513,62,789,195,104,895,598,405,307,312,797,200,35,446,176,163,405,635,284,675,654,177,30,161,656,338,573,33,270,186,800,570,327,151,394,838,821,957,395,84,763,129,107,416,86,162,76,690,229,349,525,123,228,757,524,219,185,915,30,67,756,141,173,242,583,677,783,750,432,238,621,164,380,876,445,972,821,940,834,285,976,19,201,933,349,608,844,111,706,397,676,365,877,579,4,537,425,386,705,305,113,177,968,373,736,270,88,221,600,181,926,692,801,502,128,802,715,215,161,131,587,956,656,803,239,778,858,554,790,207,714,298,538,254,873,38,638,65,278,107,691,975,261,719,116,862,220,775,233,27,990,25,14,19,336,294,277,483,401,1000,487,529,595,211,217,475,262,347,691,211,571,315,504,143,687,848,283,879,384,533,606,24,880,903,936,444,868,917,387,86,753,63,558,634,482,539,243,965,476,47,403,415,523,952,366,405,882,980,377,316,268,469,751,330,24,620,116,591,625,619,866,658,787,287,603,298,751,785,890,242,349,253,211,984,420,526,895,996,563,455,342,792,869,603,680,172,195,374,25,19,218,697,930,934,488,282,15,126,285,517,836,751,496,607,245,426,507,929,285,222,536,64,162,83,716,500,203,113,922,499,883,381,281,529,734,554,968,899,945,559,491,642,538,713,271,827,488,690,430,752,372,650,869,481,275,453,755,909,124,48,119,38,477,749,914,845,55,782,724,413,883,201,553,80,835,266,54,449,833,662,692,921,465,524,350,792,505,307,868,256,320,814,339,562,623,135,202,467,579,501,86,646,966,163,84,530,933,35,150,230,262,460,715,782,171,607,538,771,14,698,176,970,616,237,413,81,269,557,875,506,347,749,917,610,974,859,383,197,735,571,938,570,980,452,566,611,857,336,142,225,432,917,759,174,616,458,74,136,997,30,858,696,888,962,288,388,588,958,615,355,614,918,780,429,599,361,834,727,943,91,760,424,457,738,429,642,645,120,47,308,953,779,58,635,90,140,904,772,939,0,610,213,895,578,285,824,400,857,868,259,601,515,915,336,428,200,521,870,899,457,343,137,799,107,364,408,396,825,673,375,676,589,349,597,361,883,329,841,35,897,443,315,3,24,990", "839,810,299,157,960,608,780,844,27,275,276,288,862,817,619,602,880,457,631,455,248,367,760,4,614,7,738,178,618,446,949,647,90,785,286,839,383,468,388,522,698,591,829,973,2,260,628,304,104,896,408,271,158,370,101,664,546,825,927,482,525,42,770,642,860,289,529,878,382,283,656,503,76,688,497,27,825,215,795,377,966,864,293,277,806,396,797,655,291,195,744,57,892,985,560,189,938,908,581,607,516,189,621,648,876,73,200,666,594,504,664,865,31,956,327,853,371,662,98,617,777,764,650,332,521,149,183,153,396,708,990,161,816,22,330,900,803,93,271,19,764,570,768,550,167,377,396,343,921,441,809,827,650,104,198,194,605,899,984,512,63,138,935,603,555,248,396,523,917,724,62,629,870,514,560,696,469,607,21,42,571,966,671,940,896,867,949,845,284,320,127,172,897,75,860,642,166,871,69,79,292,578,513,41,16,636,508,708,295,233,126,890,173,633,101,822,171,29,103,771,332,899,432,559,815,958,289,353,339,476,757,167,613,253,487,13,596,931,783,640,451,10,508,621,64,62,396,11,955,322,908,667,463,297,352,609,755,424,445,866,563,353,800,305,52,74,587,224,939,340,545,822,690,793,276,819,564,842,815,652,207,687,34,128,914,946,835,635,354,519,92,331,403,733,260,930,614,287,955,603,99,808,117,316,543,395,566,182,966,284,172,956,935,855,14,49,164,136,37,901,428,683,691,392,568,39,977,213,207,414,170,405,789,583,599,909,187,940,905,812,955,362,736,678,207,201,28,768,662,107,296,185,351,849,995,891,233,504,777,879,714,163,63,102,916,226,148,366,33,68,905,371,927,249,958,535,446,907,658,95,630,255,576,680,517,73,498,255,420,813,309,811,39,725,357,717,416,414,240,314,766,402,181,811,705,575,864,966,858,791,752,303,816,601,833,997,912,197,413,364,354,150,634,567,588,696,230,829,414,819,443,675,66,34,636,289,57,873,119,257,399,374,729,528,390,710,294,422,640,469,862,527,297,285,113,115,652,189,396,727,566,337,987,738,474,556,184,622,622,983,79,348,275,146,52,581,189,122,598,935,530,277,594,787,427,464,526,998,372,143,581,37,384,493,57,601,921,481,231,805,989,674,662,960,925,883,714,444,509,582,201,171,885,72,41,474,790,525,500,646,354,576,722,212,384,400,604,858,431,386,852,439,131,797,964,206,442,592,533,7,768,857,872,378,218,343,267,861,835,13,14,604,798,520,240,316,263,693,406,846,690,135,57,537,180,171,793,319,132,981,676,502,298,351,784,37,585,115,128,51,706,229,170,878,30,443,897,117,287,360,27,843,174,701,978,191,860,576,169,25,425,624,360,218,573,69,403,261,218,12,171,449,270,700,23,757,150,413,107,166,89,307,724,197,219,137,264,751,559,354,748,832,495,649,453,859,801,927,429,961,358,425,54,322,324,194,421,634,176,831,650,510,838,569,438,855,821,838,337,453,15,211,178,897,684,372,175,89,747,803,779,807,191,187,858,6,997,528,575,617,250,455,833,539,676,311,785,763,376,834,224,424,467,421,235,97,800,197,874,152,750,481,685,352,591,907,774,325,448,575,608,305,181,860,770,424,713,703,345,337,581,159,809,859,268,583,139,43,235,875,556,773,379,916,421,633,964,702,323,463,676,809,891,564,669,563,74,584,43,302,450,641,272,532,554,833,934,773,230,21,940,857,341,604,985,795,310,181,603,801,290,728,253,831,809,697,511,724,803,845,764,110,271,525,752,62,772,556,766,455,56,510,988,692,778,834,153,54,340,61,863,976,300,754,362,583,18,988,154,262,50,771,851,451,468,517,772,877,214,770,664,322,942,26,404,570,886,352,694,757,29,890,693,947,446,346,635,683,748,205,5,790,352,423,990,834,491,249,317,778,833,574,499,607,624,735,174,960,366,242,448,928,501,303,435,334,37,334,682,943,618,494,923,374,152,353,646,522,371,131,595,170,500,395,436,940,989,241,522,713,458,682,485,945,969,975,889,773,815,372,238,981,205,661,182,220,666,172,797,6,897,251,884,784,793,744,546,584,80,62,333,93,566,942,55,706,974,9,460,854,433,243,471,128,90,774,551,35,900,606,480,258,957,562,455,981,258,436,847,687,20,172,562,867,610,0,450,222,635,808,640,556,324,300,55,366,914,674,694,926,341,775,278,759,647,745,609,876,474,419,822,889,320,388,179,705,410,420,55,894,613,992,361,635,747,150,711,22,403,773", "814,48,916,259,930,215,937,857,906,307,275,43,529,778,946,131,522,379,270,631,49,945,708,948,553,620,847,758,914,614,959,493,945,880,899,57,345,105,305,991,248,613,622,82,352,786,225,184,318,228,706,4,962,696,382,594,395,893,469,779,662,175,153,59,450,478,317,158,313,149,546,846,394,60,699,151,816,587,742,674,821,626,802,256,402,706,300,784,449,114,574,98,843,879,54,814,430,767,840,57,697,494,473,825,468,769,541,552,982,194,911,624,265,381,343,187,906,899,111,694,616,187,918,550,16,124,613,523,604,332,293,466,345,672,61,464,234,141,392,77,156,917,735,40,979,290,277,256,325,602,191,848,646,327,524,516,446,858,290,180,482,917,303,320,457,153,662,397,920,104,742,235,120,969,939,546,181,119,375,146,297,497,855,790,840,68,943,417,485,922,190,449,273,284,852,577,80,27,931,505,549,227,243,506,202,240,861,176,69,457,839,462,660,263,770,190,864,760,995,151,344,198,46,419,708,160,794,854,711,203,34,859,997,812,437,382,845,436,165,569,367,113,126,366,449,184,281,988,873,827,558,279,377,212,826,188,124,809,446,994,399,888,894,800,32,598,377,644,654,170,40,799,410,574,980,214,704,560,897,37,83,372,35,368,297,695,640,535,361,10,776,418,298,389,304,856,382,369,511,368,508,932,302,498,586,266,4,298,79,76,843,14,14,869,110,142,213,278,337,339,870,851,965,723,139,999,706,379,203,492,318,445,214,863,530,139,37,158,608,665,147,977,231,15,482,414,762,440,164,924,874,485,125,798,70,428,899,797,301,263,187,89,850,303,752,766,11,460,126,265,576,201,369,71,635,946,516,877,562,361,609,417,901,235,792,602,9,477,335,638,704,586,294,720,374,617,168,865,271,135,714,748,644,386,61,513,790,328,688,534,563,265,618,480,148,782,445,541,318,97,712,330,36,134,762,924,136,284,668,5,480,273,621,52,684,274,313,718,352,84,934,141,417,313,14,912,162,890,63,649,123,555,855,632,496,612,958,515,838,448,839,924,1000,819,954,537,175,494,318,418,23,712,738,817,79,574,972,605,502,95,399,334,505,622,229,377,963,526,146,65,866,579,682,110,486,749,457,856,254,324,864,836,620,117,916,73,508,720,60,939,224,876,358,329,922,276,767,458,908,590,653,521,585,897,180,920,774,936,806,519,65,994,906,559,208,694,803,62,547,822,946,614,722,205,56,601,175,998,735,108,886,606,777,743,871,427,552,460,709,466,748,913,591,500,843,260,762,278,247,94,491,383,889,840,299,426,770,977,51,656,978,432,550,494,37,945,821,776,897,353,338,258,891,832,397,109,526,717,397,630,18,937,406,321,960,152,211,675,916,155,297,436,361,20,266,820,416,425,263,704,710,201,903,242,30,202,238,431,631,599,978,770,626,601,890,897,859,317,347,808,57,653,173,528,106,257,123,279,937,514,35,657,500,443,627,182,67,869,12,688,73,496,882,713,70,755,906,618,602,94,475,369,283,609,230,634,902,637,334,474,679,782,317,719,101,695,778,469,474,492,777,48,574,453,471,512,514,572,34,343,682,936,278,29,125,941,522,330,563,115,196,152,408,696,748,574,222,18,552,666,272,985,344,16,582,411,299,420,7,76,326,702,746,269,967,931,910,281,346,74,140,781,301,826,517,446,85,18,693,536,517,93,228,602,25,230,337,700,386,292,676,361,906,460,29,178,737,49,591,745,593,168,757,177,250,877,989,994,330,500,118,277,257,723,554,248,421,111,639,528,517,892,389,847,352,435,48,233,97,871,451,125,114,26,278,983,613,45,287,851,701,967,854,838,219,983,910,312,986,127,826,949,250,75,728,11,653,272,785,918,934,19,513,85,766,485,925,723,642,636,150,856,822,847,921,630,66,195,830,561,68,384,155,833,909,353,396,808,466,395,246,823,165,660,39,411,720,913,386,702,455,930,980,514,754,244,212,394,478,727,786,797,415,529,506,354,325,451,539,793,185,885,25,197,513,396,984,494,652,332,927,469,252,943,700,635,388,384,674,479,414,234,166,565,670,609,116,253,864,125,965,488,748,165,557,141,833,279,45,523,801,67,635,397,613,548,542,733,635,710,297,502,391,701,624,861,562,297,259,456,599,92,167,708,213,450,0,281,391,372,494,596,251,335,704,779,844,752,864,341,955,570,715,959,733,998,11,443,435,631,16,376,929,566,813,571,748,510,851,13,90,511,661,40,311,878,987,263,579,555", "308,661,97,655,522,671,125,9,601,559,818,808,983,28,777,241,562,397,60,569,216,853,152,621,308,850,748,49,814,928,598,346,116,99,553,954,127,447,161,335,754,369,722,948,394,5,942,451,960,963,731,721,433,88,482,327,32,866,70,879,841,976,576,522,828,2,22,11,45,561,978,964,661,999,24,619,386,825,695,940,807,255,443,680,387,225,23,760,169,451,484,869,395,109,143,395,170,830,349,45,88,13,911,314,665,677,532,271,743,3,926,215,235,780,776,571,990,264,647,230,692,32,996,785,378,238,567,544,148,958,548,685,592,625,449,373,337,396,248,145,296,692,442,699,748,323,449,217,471,601,765,989,783,882,727,818,86,931,245,448,105,256,338,61,957,577,55,464,367,815,139,909,443,432,183,741,260,210,552,698,297,236,788,761,791,586,701,646,62,348,388,972,679,827,613,666,585,321,472,913,389,553,249,78,564,402,137,677,792,738,913,129,160,164,183,972,766,804,452,283,769,229,101,35,207,618,903,330,311,248,357,459,519,216,579,490,880,562,733,855,604,350,459,759,420,620,758,537,693,92,844,135,389,130,163,656,544,615,658,900,768,464,171,413,846,593,406,528,989,636,478,28,834,546,440,436,806,520,424,856,156,78,730,113,315,499,164,993,793,195,562,864,817,493,574,265,243,948,551,391,109,967,69,759,392,829,65,886,352,202,558,988,479,977,782,321,955,141,539,529,176,488,355,551,888,441,896,639,906,987,454,615,136,305,934,763,140,826,50,971,704,823,702,195,895,938,420,196,256,91,851,621,900,906,534,661,21,247,248,740,722,105,478,687,364,816,245,362,809,944,375,2,684,877,944,537,89,641,340,95,258,36,293,504,517,308,420,408,717,958,985,104,51,680,634,258,740,498,333,237,96,455,384,331,564,133,896,383,239,560,351,859,40,955,292,473,32,503,166,152,599,552,121,65,244,385,430,666,964,670,666,426,805,85,15,245,97,12,814,515,691,723,934,711,848,750,510,445,811,281,450,730,377,524,718,997,386,492,390,248,136,4,712,749,597,1,902,159,299,534,750,412,707,207,344,649,471,207,526,10,242,927,797,858,251,669,388,175,575,604,850,681,586,50,600,720,276,743,356,721,349,291,128,858,349,102,896,866,96,272,990,634,691,656,677,986,688,346,778,857,870,728,247,413,711,730,405,445,204,593,989,964,55,521,547,372,384,469,856,521,63,797,250,383,83,903,367,463,761,380,80,545,59,786,961,51,394,199,826,831,441,919,498,412,64,993,507,382,350,287,490,831,222,792,342,611,752,967,825,975,624,467,673,519,217,935,662,99,556,476,102,453,278,680,159,740,150,339,365,104,128,84,462,791,413,407,6,825,718,382,456,973,418,503,627,321,697,654,571,807,414,14,123,647,208,540,659,107,423,336,907,433,777,394,410,285,122,904,327,451,429,243,757,393,130,11,281,732,270,881,645,758,480,371,826,747,634,912,238,21,713,585,47,549,88,373,572,909,612,522,174,451,689,320,414,915,435,403,580,819,785,191,920,877,418,501,229,443,547,734,964,333,454,329,769,956,304,607,485,52,871,561,886,702,717,251,906,402,22,37,31,461,437,121,667,739,211,673,982,648,610,932,298,177,557,831,888,860,904,360,907,903,333,936,246,401,921,51,514,594,163,748,960,819,421,964,170,810,127,101,152,257,222,547,843,784,801,184,163,335,736,59,454,915,923,607,769,639,135,858,602,197,770,948,461,245,517,266,301,365,907,888,66,482,344,347,192,857,85,509,938,219,190,224,945,336,415,775,266,208,905,516,322,585,704,766,451,556,370,960,817,529,783,478,866,236,904,627,573,260,28,370,460,152,315,2,282,859,352,144,894,419,348,258,905,779,278,605,774,174,700,382,107,299,29,441,262,84,367,730,218,10,947,995,890,11,667,957,794,885,92,732,616,797,479,642,580,257,419,801,518,971,592,518,374,539,177,673,433,214,986,486,944,47,278,356,898,874,128,585,960,611,869,67,705,72,497,68,433,33,413,585,8,538,849,929,777,473,554,558,79,244,558,382,947,620,533,735,935,36,288,221,395,850,441,266,92,786,461,891,367,656,958,193,113,714,843,540,971,953,1,79,387,285,549,144,926,197,485,997,787,803,574,417,895,222,281,0,218,629,178,786,890,18,355,662,421,288,78,33,907,644,233,675,789,184,94,999,301,113,274,266,528,951,835,248,17,639,359,743,640,231,176,405,730,10,952,464,771,890", "402,585,951,193,360,160,775,792,928,378,268,69,315,694,900,390,578,887,861,284,161,582,392,300,59,639,29,901,749,532,345,214,585,923,8,200,614,432,352,987,756,584,195,833,299,542,214,339,332,625,446,481,470,870,639,608,648,921,489,891,461,976,603,235,687,408,193,423,793,659,394,175,52,655,43,191,610,144,903,54,762,762,548,899,782,513,985,783,492,938,734,349,602,629,648,236,162,676,93,978,970,850,404,844,846,692,714,280,664,964,172,843,733,425,285,402,913,851,984,500,380,370,894,251,197,173,893,233,766,785,758,907,149,167,183,604,865,367,784,234,699,968,351,183,258,948,404,169,454,616,418,299,878,40,278,589,355,658,342,910,475,244,411,340,779,574,790,286,248,13,85,789,577,439,630,210,700,837,78,637,643,131,638,382,706,146,286,853,237,770,668,500,267,522,956,73,882,607,827,369,656,645,611,603,520,769,737,426,958,372,923,594,580,142,403,815,504,608,574,293,586,460,956,958,65,93,80,784,317,928,546,260,363,135,475,949,153,531,897,700,730,196,879,237,500,701,620,345,906,919,432,42,247,127,752,754,835,526,497,365,960,506,912,280,675,181,414,762,974,226,63,476,856,302,987,455,316,871,252,197,340,163,504,129,3,347,239,443,810,883,459,185,356,836,271,51,210,164,634,503,505,677,648,844,140,940,690,723,775,904,322,255,793,99,758,495,496,387,496,740,541,278,843,952,668,853,869,221,652,195,482,498,259,967,76,739,174,265,224,278,886,376,197,390,957,369,818,200,922,660,327,281,680,99,761,633,602,489,76,585,484,703,179,710,995,272,45,904,290,283,427,60,937,538,187,475,435,644,181,504,395,360,509,699,936,497,400,75,385,21,40,923,274,655,380,323,746,220,581,713,124,305,871,762,699,763,681,734,793,565,189,428,49,146,538,244,337,588,261,502,990,554,16,116,288,183,205,206,560,112,733,355,905,640,141,761,187,596,416,597,809,328,332,453,688,290,250,367,100,467,863,631,617,545,504,699,13,782,267,332,46,301,574,780,144,106,724,348,914,136,228,1000,85,498,37,91,695,182,338,809,445,565,761,864,205,222,306,855,632,597,542,61,352,410,673,46,663,606,675,969,741,241,238,935,348,981,529,571,1,685,462,424,803,286,266,211,618,897,406,18,391,854,890,767,151,613,237,157,919,677,969,91,635,535,3,708,653,594,436,723,463,299,873,697,131,257,144,439,713,913,467,20,69,119,333,436,896,575,552,489,506,337,985,207,154,501,508,68,668,988,532,340,302,453,142,457,600,812,652,553,284,385,385,836,465,828,669,456,512,710,517,470,278,819,631,164,247,821,314,410,508,879,986,612,925,655,821,723,587,681,459,752,277,506,636,900,180,25,567,692,368,734,781,550,638,765,824,716,820,520,989,657,70,397,575,72,488,589,67,529,969,528,295,80,637,883,845,138,937,906,139,785,700,472,783,666,887,537,800,835,399,623,383,338,722,17,614,532,982,511,159,725,541,441,117,789,130,78,529,818,655,534,819,948,979,396,988,310,331,719,533,192,912,136,818,578,210,158,853,429,808,211,815,289,493,51,586,189,62,838,781,567,901,623,216,213,73,47,70,872,555,632,577,345,887,501,615,616,919,358,383,25,234,177,346,230,322,726,162,317,708,29,526,877,946,794,39,218,361,983,363,772,489,166,563,238,901,885,276,574,535,551,178,172,78,410,603,749,803,292,687,128,270,650,355,34,534,427,11,604,514,172,927,503,427,92,392,53,482,606,652,828,520,631,610,662,376,925,11,645,544,795,732,677,177,788,723,63,914,130,92,221,185,127,321,656,674,275,221,484,277,83,323,601,645,725,816,764,741,593,157,343,131,909,490,794,996,965,831,557,303,344,661,312,349,915,927,620,794,922,445,822,862,656,862,420,63,990,714,858,66,43,830,951,316,929,687,244,379,707,400,454,778,474,544,818,716,458,878,4,899,596,982,949,492,797,77,925,298,167,198,803,627,177,356,294,865,360,501,285,906,547,488,380,732,695,97,1000,317,209,652,72,536,818,349,893,13,799,85,66,982,171,368,853,813,134,22,834,51,504,484,796,11,60,8,835,962,425,484,364,659,341,375,110,142,618,832,460,514,360,575,26,15,389,578,635,391,218,0,969,906,849,980,520,575,430,306,634,92,496,410,218,427,691,777,372,334,208,771,71,117,880,388,278,849,501,614,827,879,965,867,356,542,407,959,455,182,971,673,581", "528,135,306,882,459,235,48,736,266,854,916,693,457,819,261,286,874,129,625,638,101,572,201,559,343,244,941,233,114,80,702,793,798,489,695,157,921,674,190,80,867,115,955,288,542,582,269,638,500,320,579,568,940,66,66,722,75,234,292,184,744,374,349,140,157,299,40,86,69,648,913,444,970,35,560,974,960,511,443,351,146,593,909,759,200,655,581,20,732,555,169,544,274,320,616,580,813,774,653,593,395,5,141,601,345,165,45,892,487,255,890,292,881,625,362,73,367,485,802,379,122,565,596,357,327,192,103,761,484,738,667,691,468,296,951,70,809,691,499,794,442,448,783,898,436,983,118,756,434,197,62,935,380,281,221,988,213,789,34,451,382,286,528,165,271,143,71,290,335,662,34,406,991,551,850,456,720,196,143,927,43,605,307,524,663,770,189,679,593,9,132,464,332,543,856,575,370,417,214,159,164,137,238,552,912,784,220,299,628,513,814,670,640,253,730,601,105,4,921,218,158,353,659,259,482,786,879,746,974,331,179,519,760,514,643,254,875,429,423,855,251,619,193,937,56,386,324,264,405,61,699,820,335,945,99,77,190,35,608,493,607,1000,164,914,231,343,381,600,272,52,162,438,257,132,453,563,473,720,282,996,851,915,452,370,442,71,133,156,398,347,591,30,359,915,200,313,237,722,441,131,923,875,546,217,982,592,151,683,142,515,902,101,506,351,316,801,626,911,595,309,9,751,599,662,702,366,865,270,324,104,596,132,548,241,749,309,488,133,303,557,672,491,826,961,666,64,890,71,134,912,502,715,514,73,783,538,299,504,155,115,903,216,472,767,92,784,960,119,720,487,678,42,316,130,979,887,911,432,29,156,931,572,371,812,609,195,586,654,398,755,318,918,527,29,274,948,303,654,327,298,947,311,48,471,514,899,111,952,413,456,688,913,771,274,467,678,642,990,164,252,502,654,785,895,295,869,686,492,366,998,393,87,139,494,834,246,365,374,628,713,248,358,846,986,676,667,369,572,623,833,842,892,527,208,34,280,40,702,508,589,457,626,603,223,457,688,873,515,8,569,325,567,615,216,655,357,666,469,739,782,390,230,981,309,322,805,144,444,496,129,236,792,108,278,46,589,352,591,284,315,61,477,198,474,732,973,674,893,489,170,741,438,99,751,120,238,673,97,535,237,359,954,728,848,520,84,86,420,755,107,222,701,45,987,360,124,61,895,701,242,457,861,965,960,456,399,71,287,215,772,168,543,351,333,745,468,80,40,881,628,776,345,112,834,533,93,326,576,909,217,285,726,652,779,471,823,411,922,329,892,271,569,364,974,424,416,302,305,672,678,543,442,642,794,680,539,694,661,291,432,391,879,530,238,459,996,71,272,478,798,769,53,791,319,792,524,561,557,213,698,651,479,581,922,844,826,441,729,696,307,717,765,674,134,236,933,952,874,966,298,227,176,37,258,302,925,734,117,664,331,95,93,76,337,918,66,480,296,448,556,740,369,748,181,455,303,953,336,90,869,464,245,853,178,617,454,748,460,270,95,899,531,432,356,716,108,977,656,982,428,891,30,681,26,244,47,388,47,328,519,716,133,784,171,252,310,948,538,870,751,435,41,461,493,449,727,97,155,202,325,489,25,490,782,999,476,603,330,847,103,614,635,591,301,503,995,922,449,652,734,420,192,664,296,170,251,706,638,649,115,104,869,702,899,781,784,714,467,222,273,131,949,764,18,945,771,641,376,812,834,779,525,227,133,549,981,723,887,148,725,346,499,344,614,360,753,901,620,935,471,604,826,611,948,452,348,500,631,448,491,373,816,704,739,513,458,975,770,565,622,248,686,968,245,410,934,962,144,426,396,920,217,606,364,30,550,250,467,249,962,605,758,571,838,721,317,553,646,604,14,745,214,36,2,595,808,995,57,903,306,557,242,699,575,322,562,318,632,628,686,919,281,777,956,641,519,568,251,479,469,911,554,23,902,364,963,377,821,331,44,926,648,773,184,501,303,208,117,189,40,591,588,301,322,642,633,418,649,799,813,564,951,929,284,223,955,126,897,817,668,848,367,330,449,409,770,701,122,418,338,929,103,583,846,187,864,567,697,151,219,992,221,326,34,935,14,355,333,81,852,398,117,829,248,23,643,529,345,736,378,471,607,841,993,285,808,372,629,969,0,695,986,365,205,858,142,378,180,61,547,395,89,588,612,493,137,720,986,5,216,982,718,254,884,214,217,751,343,129,110,572,473,562,826,674,920,917,744,743,632", "912,99,220,169,142,332,912,13,228,294,845,208,644,677,620,112,610,751,247,124,127,745,384,845,539,136,712,96,539,789,747,675,514,468,854,377,69,171,707,9,526,651,9,811,487,5,326,986,476,112,517,140,642,735,55,495,565,371,839,798,619,414,857,201,920,170,864,983,725,910,34,613,233,983,710,302,887,666,227,734,876,58,467,918,855,289,341,180,846,987,668,352,360,174,917,53,970,817,642,482,19,548,238,34,985,276,992,242,620,528,403,82,484,711,980,603,966,754,780,62,537,475,632,739,937,128,761,35,180,255,390,869,534,186,975,136,47,33,533,668,870,166,795,180,638,801,334,577,170,853,444,748,871,908,265,668,444,342,47,931,676,850,697,614,917,311,428,693,448,910,949,947,704,312,653,750,511,661,529,355,763,964,795,891,48,446,214,961,153,929,391,95,429,953,46,679,736,658,298,883,788,847,410,947,316,567,324,732,569,743,643,748,543,836,650,995,617,428,191,329,28,97,630,474,673,124,16,382,112,434,127,372,990,292,656,224,110,242,660,597,954,550,686,703,657,585,67,483,241,875,852,749,187,392,678,625,801,379,821,390,175,974,555,664,850,711,941,59,681,743,405,220,142,814,453,172,772,916,800,553,517,680,686,654,387,534,833,864,783,899,897,69,893,833,893,372,207,329,39,409,970,657,202,652,234,148,775,223,744,617,358,390,902,275,566,763,534,850,714,600,744,680,916,933,723,571,140,928,65,43,239,792,207,701,496,300,6,781,235,349,336,965,682,24,465,66,826,500,508,365,563,639,928,267,889,884,62,987,125,699,185,169,245,897,241,673,452,374,2,571,95,19,639,529,374,530,867,923,620,532,29,816,524,918,557,798,576,575,254,387,596,7,224,883,957,517,95,329,255,175,243,94,565,667,38,78,508,80,579,291,410,987,525,92,65,550,597,294,657,820,815,493,606,685,988,22,309,845,363,617,742,149,582,320,107,364,503,601,527,682,21,493,324,845,940,49,828,744,214,343,695,890,286,801,307,537,480,843,306,645,453,836,201,335,139,263,488,560,953,728,255,361,183,524,854,394,284,257,962,328,733,727,156,680,124,90,822,889,401,97,955,502,929,700,519,359,296,474,19,928,792,76,599,196,704,26,482,814,421,544,248,477,311,70,421,510,568,538,692,422,127,868,611,986,610,786,909,434,237,959,903,151,154,646,81,51,558,9,190,180,808,387,437,31,748,682,913,929,285,887,985,562,833,420,369,391,327,884,652,770,671,303,246,349,891,717,903,509,586,902,316,832,431,640,919,709,677,391,673,947,319,101,159,323,210,580,693,435,397,717,949,943,418,855,907,340,195,919,383,861,812,628,257,708,45,415,316,885,390,862,888,579,157,836,544,717,761,918,386,323,117,591,761,857,244,761,861,734,504,764,563,310,689,533,844,494,792,377,290,938,971,389,811,966,722,262,90,301,271,561,953,381,337,231,406,13,330,39,600,626,946,497,921,889,384,348,268,185,239,565,887,174,38,502,195,217,746,462,427,316,890,148,801,45,618,292,319,813,153,616,849,461,316,576,617,404,41,909,988,345,950,96,88,194,214,897,514,492,265,879,951,763,619,256,145,13,346,907,863,804,963,485,679,657,570,434,725,518,588,29,582,358,638,684,278,793,568,584,816,821,235,311,113,968,411,88,335,71,64,636,938,642,268,473,447,70,606,964,732,780,338,784,748,679,464,646,176,425,825,212,823,627,679,567,797,284,353,375,317,969,340,334,296,722,717,696,162,89,212,728,774,62,335,762,238,728,839,242,928,39,812,633,714,927,847,517,647,686,719,813,430,366,207,675,159,313,158,377,350,217,196,821,684,872,663,385,178,687,903,59,727,106,11,214,493,810,807,105,149,387,344,775,945,528,724,673,160,423,152,913,10,800,86,923,734,595,776,409,290,236,838,944,111,530,442,858,527,814,802,993,109,618,337,85,784,936,851,854,525,830,749,462,554,623,799,58,671,80,593,182,864,521,909,193,65,569,976,769,552,413,508,504,358,343,132,47,403,140,489,850,134,78,871,879,406,817,979,864,697,556,700,515,336,819,575,54,121,763,138,537,39,970,48,629,87,754,356,571,178,221,474,628,766,871,516,213,72,494,491,708,289,102,696,434,824,640,494,178,906,695,0,429,869,958,546,509,461,86,225,610,690,605,107,352,158,895,158,894,275,35,644,605,260,638,156,377,798,502,118,393,429,67,207,263,740,93,826,630,195,883", "260,321,434,220,19,30,516,397,148,998,821,488,403,115,973,676,232,383,222,296,508,866,613,41,294,448,723,213,955,604,32,447,854,802,554,554,173,267,422,979,550,887,154,491,282,308,816,798,636,376,700,676,521,568,425,225,817,109,759,256,516,905,419,279,923,123,854,861,31,681,686,32,722,63,895,179,876,422,714,345,102,24,884,187,177,887,120,345,621,347,323,435,923,444,277,357,903,445,276,774,582,292,979,325,219,614,440,474,265,287,547,637,282,94,532,923,347,524,975,661,709,823,121,363,759,466,867,227,928,485,481,389,408,370,572,173,725,360,639,37,288,234,901,149,805,826,393,957,417,211,709,894,477,897,224,615,686,381,21,377,828,178,426,472,467,33,212,56,869,760,377,272,517,983,120,637,960,645,213,229,342,837,764,615,214,880,657,139,105,77,141,638,677,207,421,231,522,934,950,620,249,173,447,377,108,98,465,960,906,178,251,217,414,368,71,926,261,240,785,319,224,241,462,889,830,290,737,101,676,867,790,411,899,448,432,75,200,25,725,995,657,40,863,324,842,559,95,448,361,714,238,605,637,247,155,268,192,688,358,303,127,454,528,313,566,314,157,682,350,718,282,419,646,214,140,253,52,364,294,174,474,401,60,238,124,394,733,521,709,950,678,276,855,738,932,468,168,574,202,99,234,802,412,42,711,896,474,223,441,782,62,550,516,990,84,699,898,374,169,69,669,566,671,520,647,118,360,730,851,12,690,439,857,105,640,417,128,645,397,171,747,617,878,452,640,146,485,235,686,630,329,629,634,245,433,913,407,208,751,875,319,865,568,118,977,738,513,968,936,980,977,993,437,844,348,879,618,615,623,310,443,88,672,508,651,398,743,624,224,479,435,942,373,332,107,138,28,794,946,27,336,828,904,300,216,810,484,30,492,106,802,52,500,405,190,171,920,817,687,954,633,42,902,311,631,599,162,734,862,153,736,666,472,56,853,618,307,570,758,737,52,225,580,915,284,648,866,25,424,15,90,19,118,700,676,573,617,307,216,849,36,915,320,106,771,616,159,642,130,29,726,907,582,567,70,397,585,34,201,759,373,871,817,416,30,606,789,761,822,193,603,529,303,618,508,468,205,493,922,910,801,814,54,967,378,829,329,74,764,193,688,816,354,79,443,219,455,621,740,90,849,667,271,168,554,816,209,790,57,657,556,977,936,116,448,695,808,988,697,44,200,338,320,689,816,633,95,149,34,24,296,196,851,686,792,451,990,842,663,226,344,169,280,630,658,211,13,273,734,726,99,967,202,101,957,116,183,425,408,32,380,199,613,165,839,238,468,675,993,631,276,902,245,830,102,357,378,120,471,659,545,596,292,634,903,736,69,215,166,779,940,604,733,400,431,849,275,611,974,670,713,377,486,382,626,399,537,181,958,485,986,376,885,375,101,646,541,862,705,883,90,367,24,271,11,179,713,153,753,292,286,175,36,26,880,324,873,632,532,906,644,980,99,175,950,74,211,107,51,526,742,627,11,937,701,110,200,313,610,327,942,632,721,441,951,945,60,304,615,886,55,918,227,52,247,878,504,532,10,673,320,523,904,186,558,759,971,916,788,824,667,259,310,710,706,116,501,649,283,415,269,719,444,852,938,124,897,787,254,144,114,776,306,615,853,901,443,106,355,958,737,187,714,872,179,935,288,639,213,266,472,503,275,958,34,670,93,9,15,192,795,999,83,30,566,928,940,787,838,762,322,301,242,88,196,639,166,775,185,526,488,815,936,517,331,26,715,439,779,378,544,563,14,81,563,701,938,185,967,50,922,558,772,151,661,490,929,618,942,545,653,133,726,693,97,720,618,249,946,825,367,20,411,83,595,883,645,349,67,465,455,817,450,261,120,432,850,608,250,512,360,657,543,722,982,135,692,988,907,296,4,188,8,113,639,947,483,998,160,716,365,500,837,552,528,256,360,950,597,293,892,389,512,321,987,278,150,70,285,507,658,937,673,655,128,770,314,180,160,162,849,145,757,293,181,652,405,276,795,410,370,557,884,350,614,336,440,992,7,330,498,658,953,595,137,834,350,15,85,994,473,195,75,359,541,807,37,492,979,229,51,791,137,673,780,483,417,676,881,755,876,182,979,110,292,62,633,22,122,337,388,635,520,735,400,556,596,786,849,986,429,0,403,985,671,320,823,676,167,631,754,408,491,57,126,581,171,115,226,256,681,60,550,258,65,368,628,459,349,158,69,619,871,964,997,52,308,776,927,992", "754,450,419,309,826,472,36,207,260,990,164,705,974,499,202,560,255,288,239,381,102,104,883,744,412,186,31,878,564,952,955,782,774,711,829,730,419,686,369,415,308,600,776,288,921,25,272,592,293,124,477,817,418,821,472,493,24,889,956,256,824,652,799,797,280,838,391,566,156,600,986,186,535,186,5,221,654,203,682,255,85,167,818,669,373,993,680,15,717,908,484,78,619,284,222,958,772,976,732,200,421,302,379,501,613,801,191,754,294,290,62,47,78,257,136,380,655,794,591,343,638,557,723,150,501,796,654,464,81,687,679,514,279,133,855,940,276,366,198,742,76,344,441,618,502,624,881,421,725,71,706,994,133,154,406,951,577,438,544,487,683,652,911,630,135,517,13,968,345,519,216,788,20,487,652,302,539,806,92,721,982,430,556,832,245,903,780,210,906,206,680,671,149,967,356,723,633,981,297,743,590,38,706,840,296,445,587,815,815,806,169,764,71,491,928,254,972,440,454,988,278,739,194,728,126,501,553,931,330,622,540,734,872,664,5,785,211,514,261,924,618,663,819,169,374,672,844,277,681,16,988,741,664,972,653,779,766,854,782,144,545,901,756,3,84,948,927,452,455,510,662,318,656,874,991,732,838,765,619,848,367,142,251,275,648,832,423,26,732,45,667,119,312,578,818,278,114,486,670,378,9,248,683,518,425,257,161,456,514,819,821,322,873,480,103,693,524,969,508,785,716,730,653,18,620,659,145,921,926,12,379,163,749,419,468,296,470,547,694,433,426,411,425,842,975,219,654,812,505,936,169,542,867,740,982,996,105,830,838,664,373,120,275,798,282,671,840,188,450,686,888,120,129,25,4,77,320,257,376,681,846,5,528,895,506,202,514,83,871,118,780,972,877,657,768,314,454,791,575,880,459,699,394,245,415,868,793,4,393,826,653,846,451,705,213,251,588,31,988,231,394,697,788,218,718,346,974,512,805,617,33,60,637,29,522,796,768,850,191,229,31,730,585,765,622,228,871,262,617,986,214,434,992,162,685,2,400,363,264,528,683,173,484,191,382,873,352,349,364,550,97,961,881,302,980,632,137,585,11,265,617,756,826,25,664,68,263,149,287,429,504,788,873,80,392,606,201,477,945,713,410,695,398,996,970,429,595,954,788,812,592,760,483,110,41,591,605,598,619,122,329,68,975,818,501,701,238,582,421,32,156,646,202,395,267,142,761,650,361,224,852,277,885,467,889,390,221,301,914,5,944,325,123,186,60,91,313,239,448,492,696,690,16,267,166,578,601,389,131,574,705,790,116,229,921,455,10,828,372,898,522,802,909,610,565,18,262,91,859,164,453,227,80,590,546,738,717,678,942,62,96,360,249,173,815,388,663,598,88,691,264,272,988,633,102,462,655,41,134,219,971,138,458,539,850,856,587,673,174,774,400,592,54,210,291,505,885,753,726,333,687,702,134,249,582,12,297,994,692,782,821,106,364,655,322,974,672,300,248,153,735,718,149,491,835,150,905,368,101,168,391,991,675,437,810,391,843,218,683,713,673,163,873,843,197,216,586,303,505,419,217,741,174,973,551,229,610,689,146,675,693,872,762,252,458,250,893,694,572,328,757,798,675,37,117,387,135,750,942,797,910,330,925,522,68,516,11,209,212,525,117,326,491,546,210,217,560,176,50,754,275,336,307,48,623,468,433,50,544,249,125,336,637,797,222,438,497,778,154,84,234,269,963,455,597,62,713,315,137,970,405,884,496,392,64,817,471,50,261,407,259,624,227,942,734,666,751,227,741,101,48,520,863,410,339,976,193,86,498,101,721,598,215,757,173,331,913,787,747,15,278,62,83,732,715,707,528,359,268,898,621,969,301,980,621,65,678,320,474,93,89,978,702,341,995,712,353,140,740,838,793,598,43,485,344,31,78,619,256,285,579,624,222,10,452,603,33,418,116,886,78,20,465,892,262,550,333,735,532,255,3,867,794,116,645,332,2,961,310,325,816,832,982,317,931,179,320,170,219,739,821,896,688,976,552,252,54,948,34,678,956,483,969,435,567,65,340,88,534,936,353,571,44,500,73,835,482,588,951,753,994,565,789,274,377,112,328,49,441,713,537,425,54,532,170,345,549,160,729,534,52,409,67,146,418,926,361,637,912,551,606,576,98,264,857,324,251,890,980,365,869,403,0,63,948,7,466,549,593,114,825,18,756,762,371,857,172,820,721,455,450,287,947,421,10,61,436,472,230,456,269,720,170,595,793,295,1,916,324,38", "367,513,183,887,580,905,409,848,199,145,599,406,667,498,798,539,977,651,272,607,694,532,674,411,101,747,88,306,511,584,55,431,256,836,41,795,538,745,324,565,263,677,111,198,587,327,249,849,804,592,26,711,123,285,861,229,482,583,405,184,268,332,486,169,146,233,735,501,992,793,239,931,963,442,829,790,135,39,220,680,282,809,644,979,761,25,417,465,241,836,709,489,225,176,656,253,444,746,19,605,699,359,434,837,388,613,958,465,261,447,423,708,394,599,710,345,87,238,76,875,721,630,210,694,695,581,709,788,958,6,100,632,704,706,453,791,981,188,91,872,720,118,519,262,332,230,860,292,308,12,671,239,165,446,864,165,314,372,433,210,500,247,310,749,531,258,29,192,117,354,848,856,743,14,215,908,265,367,65,307,763,401,163,825,829,283,825,388,35,153,859,674,171,342,465,221,319,504,866,261,214,683,988,996,509,286,573,33,512,799,778,346,877,317,600,376,774,160,414,867,322,736,200,997,521,980,225,434,42,216,668,367,457,951,968,761,753,204,479,725,444,287,427,823,715,274,862,215,124,857,94,430,758,533,176,942,724,576,453,308,612,927,887,132,290,83,471,232,685,401,597,270,516,532,734,476,876,495,887,112,362,236,99,132,987,252,510,825,996,372,111,227,251,48,102,793,310,74,428,18,168,979,296,531,879,634,917,938,725,880,153,592,775,675,94,239,542,856,938,693,520,606,664,187,989,489,637,185,778,105,224,483,334,821,436,265,166,903,331,336,872,715,849,921,784,336,767,258,748,651,774,673,537,229,110,527,161,121,580,913,877,576,206,265,271,589,184,223,212,240,839,680,283,168,83,481,715,504,157,431,263,706,704,433,779,772,569,228,375,445,303,81,160,774,585,398,28,500,209,569,315,16,127,680,142,862,163,247,315,552,907,204,55,781,595,431,207,258,603,695,92,502,644,211,384,979,589,423,230,382,766,591,910,790,36,850,807,875,971,126,379,302,925,565,831,924,907,333,787,226,554,239,751,762,497,671,512,246,200,155,507,627,534,188,530,461,39,531,135,50,606,236,354,298,518,265,951,198,247,729,606,374,381,421,205,299,282,271,709,400,22,618,97,413,831,940,547,370,453,108,608,249,205,281,9,818,52,512,120,502,818,58,137,374,447,344,924,898,437,72,410,309,53,944,185,823,380,324,989,184,937,293,32,489,107,198,661,99,166,288,272,84,614,538,891,35,586,83,348,952,743,302,782,32,493,564,815,42,276,494,188,585,887,212,466,389,291,274,169,765,494,584,898,94,787,670,906,438,414,233,871,35,66,325,539,663,67,775,170,354,351,342,71,599,840,539,784,635,547,232,264,453,986,867,123,436,682,103,140,754,970,17,265,720,327,537,428,100,615,839,679,223,774,839,835,957,276,378,491,797,669,820,339,208,963,668,703,340,447,638,199,667,639,349,877,322,243,187,750,190,642,937,184,733,240,737,899,999,589,679,9,77,208,918,515,321,146,247,118,603,960,124,395,546,310,162,41,516,214,571,798,291,488,839,447,521,219,31,900,331,398,916,637,783,828,973,838,202,516,690,623,460,378,513,671,897,561,48,184,978,798,379,285,124,685,102,2,11,555,642,916,264,308,789,224,660,945,141,435,720,754,525,431,359,854,321,817,380,771,107,678,691,345,410,370,591,593,115,923,30,679,156,122,859,179,267,94,863,193,498,155,371,471,103,481,559,688,527,390,199,918,884,293,204,811,288,492,683,657,634,482,898,684,750,72,740,455,323,318,515,423,669,5,222,958,328,788,864,954,952,168,555,452,773,692,892,708,159,186,628,999,334,723,483,469,519,20,885,83,759,251,515,86,17,847,459,534,233,802,648,186,424,671,293,279,685,15,218,577,815,402,931,262,814,337,574,567,25,230,820,639,943,763,968,152,749,803,850,312,737,269,955,706,973,239,463,840,692,616,12,49,149,562,22,561,46,146,160,670,774,717,79,419,584,627,303,830,322,331,283,883,454,431,652,742,878,849,159,339,237,364,326,975,694,721,408,644,862,983,218,436,466,816,175,989,259,366,9,339,369,281,49,653,176,445,41,27,783,688,939,519,510,876,288,341,559,330,588,210,406,921,943,660,739,984,883,753,658,22,955,786,88,647,621,868,300,335,18,520,205,958,985,63,0,630,701,805,185,560,214,532,584,53,676,591,248,488,531,466,282,943,718,922,270,557,156,676,960,413,83,408,647,283,697,472,5,259,336,974,67", "8,70,307,270,833,503,138,49,11,654,798,56,413,969,280,693,249,600,712,440,98,265,231,593,976,885,214,2,994,94,544,105,151,571,764,770,947,947,824,531,858,655,819,727,94,226,174,144,660,207,286,296,654,515,204,58,813,171,424,109,959,688,132,879,931,47,282,687,878,573,379,523,665,319,759,238,434,234,124,513,242,119,647,900,254,816,752,758,814,227,356,606,27,168,462,947,351,330,388,195,384,792,240,812,683,992,111,772,245,857,687,129,520,478,873,578,471,62,109,924,50,822,399,878,635,74,925,717,476,559,435,17,690,123,92,715,256,531,320,72,605,173,80,438,45,879,652,719,639,744,706,542,643,829,471,465,112,407,473,945,268,485,784,649,659,242,437,325,253,46,924,209,163,276,266,280,906,882,762,479,504,607,423,485,918,715,328,895,201,154,687,584,805,713,898,620,993,394,726,581,939,374,250,126,425,799,380,540,535,821,163,99,811,530,255,821,979,993,319,971,72,724,620,308,898,526,644,963,629,212,329,176,423,4,11,258,705,96,409,560,646,371,157,647,859,608,643,934,356,934,656,683,217,167,766,19,49,819,643,950,713,891,705,511,657,879,87,630,482,762,266,881,654,577,925,435,231,665,573,654,807,597,581,192,749,911,295,245,103,976,834,727,600,768,19,249,449,87,363,298,731,842,333,79,322,329,664,830,446,248,484,201,806,536,545,958,418,312,346,819,223,725,780,991,62,843,6,618,615,885,629,249,611,224,193,952,17,498,689,196,575,960,269,690,301,993,904,728,654,161,835,409,484,594,896,551,2,220,905,31,702,419,664,76,316,653,521,116,634,478,150,242,510,242,869,801,140,369,598,639,848,576,488,542,27,252,816,550,581,607,464,109,81,655,968,280,150,810,944,755,992,422,696,773,737,18,901,477,34,292,399,927,911,586,414,907,774,532,997,654,159,868,657,821,272,752,875,523,439,26,838,425,685,307,773,895,620,96,174,879,225,355,896,400,984,773,284,655,446,63,438,540,267,167,72,105,834,469,880,497,468,305,291,232,163,734,38,630,490,826,939,642,837,606,295,353,250,372,434,307,469,571,242,171,286,92,902,811,150,964,135,202,224,140,32,836,682,234,533,53,584,13,771,680,729,955,396,305,722,631,544,380,454,773,223,877,168,175,367,763,106,574,717,757,348,348,50,628,446,535,816,787,899,223,308,347,617,788,969,34,350,890,321,809,110,426,925,79,206,438,502,404,575,453,490,364,539,18,572,161,888,614,44,677,736,119,633,87,235,748,624,715,988,935,607,472,82,807,865,71,723,647,88,932,301,874,870,440,602,933,971,308,364,359,591,865,106,709,47,739,431,870,907,306,565,730,339,908,367,136,746,637,400,137,275,69,488,125,503,34,958,890,588,616,181,955,506,125,165,166,741,309,835,624,738,888,840,873,51,992,325,496,436,143,861,942,270,247,565,455,28,626,625,721,522,371,71,608,186,418,547,2,122,637,656,953,316,318,606,116,116,671,530,508,620,955,459,816,456,694,951,137,188,565,535,69,811,760,911,382,748,103,985,403,499,326,336,551,30,552,309,51,869,343,971,8,472,755,801,412,93,687,858,277,516,805,139,846,153,615,51,630,317,622,928,69,2,54,463,3,761,292,424,431,670,945,900,651,199,450,673,525,913,681,426,176,157,548,591,944,742,103,267,202,479,779,191,533,154,647,535,585,261,559,941,506,731,54,267,809,17,692,828,162,698,599,670,6,272,352,928,203,178,340,987,607,238,972,445,696,825,720,199,886,812,178,761,464,778,83,526,522,261,63,70,931,485,630,220,714,94,654,873,553,463,969,898,404,982,592,198,566,446,708,500,966,492,429,477,755,30,807,950,59,975,614,259,528,227,887,751,95,740,696,92,992,361,736,981,162,638,778,921,916,361,641,740,488,736,294,220,682,542,333,97,425,906,658,337,943,557,511,205,250,337,807,198,542,509,20,407,769,775,487,445,100,517,258,606,284,918,709,718,746,609,733,112,610,268,957,487,427,698,677,45,147,985,773,308,412,809,177,488,642,170,71,47,745,793,94,789,353,131,859,514,691,751,626,400,351,605,550,23,137,958,383,462,440,52,789,67,835,962,86,699,283,493,539,532,14,839,895,712,433,259,55,704,355,575,858,546,671,948,630,0,308,293,851,225,738,280,713,618,189,376,513,432,501,25,314,629,866,60,120,515,955,738,859,411,267,63,161,711,205,681,766,467,932,420,688", "301,896,287,963,483,385,140,962,219,829,484,663,189,38,742,885,416,814,857,765,530,554,945,314,387,560,64,537,59,449,25,351,402,762,287,981,278,541,505,201,648,705,857,141,907,693,440,719,657,550,433,362,397,967,344,234,821,361,30,562,560,353,704,643,891,508,519,829,873,3,452,291,872,693,364,61,328,694,961,136,761,852,992,858,416,303,674,293,320,954,938,768,183,540,983,513,965,108,535,326,989,613,902,973,61,723,254,114,526,37,753,130,972,526,447,551,784,380,896,678,474,864,429,973,215,537,576,273,584,597,144,101,112,765,302,257,349,103,740,191,249,468,602,878,335,162,199,538,147,294,52,805,409,633,451,308,621,343,537,521,882,145,975,961,31,479,62,717,918,441,888,43,688,820,760,768,915,144,974,473,776,985,329,923,391,519,719,982,647,420,784,295,136,300,637,976,125,263,81,155,754,930,209,56,690,76,643,186,933,697,507,935,962,584,395,946,604,506,209,759,22,481,106,439,227,583,382,509,236,905,734,501,487,138,342,911,962,983,410,275,476,712,476,716,823,82,888,866,583,155,758,140,460,330,534,715,231,287,159,557,835,518,421,401,434,547,155,813,722,173,564,564,128,589,525,594,25,363,389,868,870,56,414,2,739,713,804,330,467,921,924,477,92,444,404,298,910,168,824,444,231,452,879,93,790,375,743,955,891,458,783,642,307,113,847,297,594,620,28,247,584,73,143,442,836,142,934,237,67,72,678,373,855,367,487,881,586,169,505,39,764,739,837,117,319,715,185,398,460,293,789,633,35,739,902,557,27,145,854,409,37,179,183,681,11,642,215,437,141,444,624,272,448,127,557,39,568,964,537,15,738,672,222,724,157,900,31,63,926,243,597,314,789,249,361,352,775,879,979,674,350,838,416,245,102,309,192,520,981,14,310,12,926,332,524,473,989,859,801,686,897,589,964,796,48,962,972,997,947,101,744,167,166,358,284,357,359,364,795,15,792,878,131,300,196,500,406,456,636,301,427,760,912,488,274,47,173,546,122,2,183,92,106,363,185,653,753,683,650,799,923,668,792,378,882,977,119,161,493,997,804,984,270,604,900,68,495,830,322,930,849,675,592,541,548,327,84,576,905,555,627,819,111,501,666,858,717,759,985,738,349,118,105,351,995,597,995,104,918,595,453,574,936,971,91,42,321,610,47,519,543,24,898,11,945,293,750,948,693,232,536,284,309,786,246,744,760,414,448,967,66,114,660,965,601,20,424,459,875,29,484,398,364,731,295,362,821,93,590,537,832,967,26,923,88,913,74,935,426,948,561,841,646,984,318,116,929,519,158,573,382,381,32,995,856,350,622,68,307,451,684,971,126,506,447,103,70,636,168,442,171,44,841,961,156,182,620,365,840,795,517,503,986,120,663,478,22,119,724,186,360,657,766,166,393,321,674,492,247,437,134,200,27,204,448,276,920,655,448,884,221,905,846,22,220,863,400,937,49,460,573,698,405,87,359,28,319,470,221,401,478,353,765,792,882,952,142,955,718,961,132,978,275,849,911,843,545,710,760,857,799,79,498,876,875,58,421,83,168,323,455,374,597,129,709,650,387,882,201,108,239,71,2,423,666,975,309,695,794,340,515,192,145,802,114,767,503,786,827,875,704,721,624,393,799,797,1000,759,377,118,184,56,120,927,814,719,87,335,598,617,907,592,662,245,869,328,571,903,868,513,852,683,779,898,795,490,695,575,703,989,919,73,771,416,4,876,217,6,765,592,604,822,507,468,212,945,625,310,475,726,728,909,656,277,163,183,428,885,403,393,908,317,729,487,347,982,265,562,296,458,354,233,213,792,811,159,67,192,465,909,511,65,658,879,817,611,810,162,344,191,551,188,786,774,115,866,638,347,588,807,161,219,87,331,246,540,275,13,446,718,252,212,469,649,937,111,386,276,326,712,606,806,42,214,720,188,274,185,236,63,11,693,296,468,532,490,945,768,506,868,875,201,270,152,67,183,143,996,993,751,6,254,654,357,237,997,64,880,533,972,559,903,478,319,148,933,682,913,755,98,609,616,316,490,927,463,689,371,272,991,422,278,667,606,706,980,387,153,439,123,585,180,192,166,722,2,323,463,155,22,744,667,858,330,363,253,953,258,490,167,543,565,238,808,601,366,779,662,430,142,509,320,7,701,308,0,868,820,889,315,353,615,683,48,89,712,881,514,175,704,765,556,903,475,875,440,996,764,954,365,571,65,359,426,213,98,620,263,866,798", "917,564,216,648,779,772,70,893,609,815,124,598,503,709,940,809,690,680,769,937,562,200,549,470,238,414,274,899,859,683,422,363,104,760,353,128,877,615,301,336,475,823,395,973,134,452,396,328,642,674,386,169,582,832,208,743,319,522,151,986,511,857,309,716,737,603,766,730,869,253,670,476,314,585,293,188,188,929,287,51,399,83,882,604,973,258,563,822,864,193,33,135,90,386,317,321,407,175,116,484,448,229,732,783,240,827,29,595,38,417,246,718,378,633,577,686,489,655,334,46,202,132,26,144,257,61,414,591,326,366,643,333,767,431,671,523,802,213,311,121,374,775,855,143,410,337,188,741,705,248,778,490,734,774,803,907,323,450,307,459,340,161,187,386,933,152,624,195,331,36,145,657,505,954,106,172,505,127,192,936,316,641,828,398,913,909,328,848,6,971,228,519,543,794,866,788,830,554,39,112,12,299,158,299,782,532,422,859,730,678,934,52,916,703,893,352,441,16,53,809,474,17,794,488,322,860,860,589,33,765,170,953,463,628,184,839,199,314,537,118,525,644,214,832,720,441,862,210,978,682,239,895,212,95,322,381,36,958,414,729,315,877,54,390,365,841,274,452,525,610,803,916,150,228,936,399,979,735,762,253,954,526,625,112,843,307,136,351,870,790,657,979,37,862,97,614,647,752,153,444,63,759,94,13,450,295,235,244,898,945,27,692,392,622,589,766,721,59,833,440,886,104,741,187,62,353,803,935,301,806,936,343,189,418,927,15,520,523,419,529,997,500,388,212,691,643,978,76,499,697,596,691,180,424,867,167,48,468,588,627,934,717,104,591,746,143,893,254,722,822,128,302,678,602,350,269,633,937,548,428,452,326,374,359,98,400,927,904,527,925,198,75,409,417,257,804,460,735,276,65,498,494,41,173,812,936,537,607,637,461,604,640,235,349,965,650,365,420,314,142,216,90,956,315,7,225,760,147,593,978,936,206,676,752,383,497,91,782,277,873,428,984,460,600,295,278,299,311,701,774,517,13,327,773,340,819,173,600,821,260,940,991,609,516,736,956,331,142,397,303,749,795,807,368,596,218,286,99,480,950,465,393,914,264,262,875,716,353,801,710,900,652,303,428,448,396,569,453,591,703,304,678,614,663,928,607,49,469,839,732,446,728,733,694,578,525,646,267,358,122,461,804,169,751,277,998,241,895,821,232,595,463,364,564,946,213,165,964,555,638,257,218,101,765,682,321,564,468,91,994,544,299,517,708,612,953,530,587,610,129,250,344,702,808,81,344,824,785,607,503,156,40,283,213,340,928,497,438,558,932,986,228,277,806,162,613,32,3,153,538,846,159,968,217,411,740,777,291,778,650,81,826,848,636,561,877,5,976,645,695,85,29,671,188,128,77,605,964,690,698,941,445,638,837,959,319,198,141,737,813,930,736,60,854,525,62,723,702,90,467,744,245,2,391,628,324,424,542,807,168,55,601,23,605,179,885,464,649,513,444,757,847,426,544,390,195,763,447,269,574,136,887,951,806,499,426,186,674,564,437,810,718,714,923,471,710,482,779,213,926,775,590,804,721,301,252,942,523,979,14,689,703,826,379,593,349,814,635,12,45,259,692,504,275,443,99,374,727,892,675,85,185,940,522,417,459,792,395,292,911,110,599,264,89,628,290,681,547,276,439,364,942,968,845,71,188,922,610,439,170,329,519,917,829,837,470,926,681,525,449,502,812,633,48,316,296,956,87,502,200,691,402,61,429,484,770,104,473,769,973,115,749,800,27,417,891,385,261,995,56,86,896,906,415,516,414,434,572,989,389,982,484,859,277,548,902,407,930,593,312,409,980,903,946,563,746,379,945,696,289,764,12,921,111,588,149,133,717,614,221,901,984,137,740,552,91,890,263,866,618,715,534,19,881,743,383,258,540,618,899,486,866,218,44,462,658,657,951,173,316,888,489,746,959,251,453,927,861,725,402,372,789,312,796,821,573,671,440,373,500,209,286,553,942,431,964,10,143,758,326,252,247,938,361,54,453,929,739,147,171,899,881,752,256,958,803,834,93,745,823,887,914,577,332,933,486,833,94,296,551,23,332,108,980,801,621,603,371,282,303,144,676,721,70,323,550,361,114,418,748,53,568,680,786,793,420,438,90,497,582,634,859,886,149,515,914,844,421,306,378,461,823,466,805,293,868,0,378,702,357,614,211,308,911,237,672,839,141,759,497,348,53,722,313,393,123,904,241,499,179,723,680,264,978,314,482,348,634,783,721", "351,677,258,658,982,467,5,761,973,627,467,72,755,409,912,652,522,916,101,969,1000,3,860,428,354,906,716,393,441,470,102,571,400,593,725,861,618,411,175,98,593,414,766,384,336,890,9,693,763,930,20,794,126,169,546,166,762,74,757,385,286,366,193,874,538,552,761,810,309,258,111,886,782,128,357,195,335,106,921,441,671,792,632,408,49,589,112,716,616,298,746,106,803,387,172,278,524,65,60,349,55,110,855,912,407,908,827,289,960,352,279,657,792,320,750,453,759,490,83,41,327,879,118,444,523,384,42,159,311,356,552,866,675,830,948,180,434,930,392,254,902,370,251,832,591,482,771,970,105,172,522,588,898,592,531,497,785,281,730,569,246,424,988,578,701,288,226,26,407,252,935,384,751,2,404,233,195,8,307,226,997,921,647,989,18,50,839,698,996,688,742,675,626,859,704,170,40,718,551,496,776,52,386,582,542,898,854,340,922,250,759,149,289,787,910,745,741,255,197,273,168,956,101,93,223,131,519,250,404,857,637,740,160,394,357,87,49,687,782,951,658,397,740,874,24,208,359,504,22,448,203,430,575,102,593,311,434,129,626,992,746,786,42,463,682,373,100,96,34,39,401,299,160,163,749,134,926,102,144,187,833,585,265,100,253,405,85,930,455,307,496,682,805,254,132,551,915,331,904,707,799,344,506,256,142,336,626,206,2,774,701,880,289,794,1000,857,61,238,529,149,278,644,418,438,850,555,271,135,737,251,471,889,800,815,273,112,510,997,280,445,775,86,356,366,54,578,490,333,824,288,307,689,67,615,428,659,184,760,653,535,845,228,158,414,356,896,879,902,450,419,245,231,60,84,891,927,512,111,303,105,373,345,30,820,686,89,709,177,530,56,909,399,604,326,3,431,359,990,488,648,758,121,615,401,161,103,499,495,793,761,707,260,773,42,786,63,317,636,388,7,710,791,211,865,865,623,739,517,117,339,324,217,310,218,338,759,522,862,425,559,64,584,380,121,683,239,456,161,34,278,65,96,180,362,945,418,610,821,472,313,720,125,346,996,38,75,219,526,898,391,718,531,690,728,231,537,237,431,9,384,714,15,476,878,902,38,405,875,668,475,738,319,864,383,948,90,129,171,826,889,541,228,103,551,923,716,856,92,811,72,891,87,410,601,60,729,882,787,812,854,35,741,817,82,346,210,289,569,671,646,157,857,76,31,402,800,197,376,872,433,270,756,750,393,905,428,57,895,643,896,411,470,218,857,23,498,179,955,468,62,823,509,479,507,724,575,316,264,77,557,660,144,695,729,114,85,36,265,667,1000,313,530,567,941,611,60,173,113,463,275,512,751,981,130,747,58,635,661,594,701,747,428,335,720,853,854,774,391,821,372,883,70,797,295,945,462,453,961,580,743,137,17,13,822,891,107,808,46,798,729,402,525,153,859,62,525,566,537,99,979,873,619,137,9,761,993,433,217,30,359,661,248,939,960,682,281,344,770,553,911,620,788,740,859,245,859,970,704,651,481,459,147,260,236,500,301,520,130,737,896,396,738,227,67,268,250,719,797,399,178,831,860,878,228,434,982,714,260,371,918,932,992,675,406,315,489,244,952,611,669,863,680,837,935,217,261,619,716,86,41,874,448,306,999,486,619,381,17,594,620,591,170,867,909,699,909,809,361,921,572,670,282,319,261,568,805,428,136,97,998,246,534,810,102,833,423,404,815,839,543,862,166,917,103,45,104,617,398,335,461,149,736,193,556,790,247,127,694,820,932,210,203,444,429,471,806,564,50,991,382,162,385,582,973,306,500,590,67,956,190,785,861,844,669,131,543,588,724,533,804,292,419,10,259,791,710,255,636,940,686,274,383,687,156,904,242,84,941,980,484,114,800,296,201,786,860,565,579,449,793,81,369,722,758,15,847,109,333,494,944,996,56,794,66,982,997,270,755,584,940,782,156,659,603,327,999,430,352,118,694,97,384,971,512,439,866,204,450,750,136,856,610,269,231,420,515,235,162,745,739,52,106,838,605,952,774,301,859,802,448,958,649,156,291,130,31,586,761,161,585,341,992,197,143,728,171,216,481,719,652,867,180,675,473,632,61,926,845,981,469,17,107,780,693,780,159,567,342,226,220,453,479,198,169,586,281,902,718,682,919,720,973,289,174,915,674,752,288,634,180,86,676,549,185,851,820,378,0,372,332,497,92,731,885,190,104,974,482,810,511,954,267,886,686,722,671,68,664,445,802,294,136,347,618,369,785,751,442,459,247", "988,490,162,221,61,9,354,467,647,578,240,349,875,327,48,326,800,515,273,606,88,86,263,77,94,228,392,861,546,582,287,456,677,534,674,839,2,306,303,870,111,643,976,270,453,620,6,193,273,269,856,815,295,951,165,885,307,726,820,781,960,226,174,329,915,244,17,864,781,155,371,234,12,408,751,729,64,646,210,21,897,697,772,919,556,8,178,4,766,479,509,7,169,66,868,425,344,170,557,372,889,327,278,635,940,504,871,452,476,804,969,222,237,747,499,111,355,480,788,135,250,662,250,264,907,577,983,810,100,866,487,372,82,804,329,829,255,914,733,836,495,235,350,939,937,906,627,992,993,252,2,839,604,243,911,484,342,209,736,125,488,733,47,609,392,941,530,834,498,504,96,87,356,185,408,515,966,401,765,334,349,913,864,429,211,832,348,142,613,662,374,123,366,668,383,603,112,896,756,65,656,487,640,5,381,127,226,834,37,500,833,284,229,628,524,132,699,831,402,156,768,736,652,814,324,801,515,548,885,918,110,552,653,808,242,304,642,240,801,299,428,366,726,714,281,902,874,404,721,111,187,489,148,604,301,80,469,979,314,556,635,10,115,779,115,854,323,777,247,626,352,737,248,801,898,504,91,548,730,570,454,56,234,716,875,427,498,584,889,569,732,662,148,706,279,178,346,910,344,280,930,165,340,161,652,616,194,214,938,607,746,721,581,567,451,500,250,602,995,966,262,52,111,660,332,914,430,292,388,721,146,575,154,352,520,2,466,162,304,194,185,629,567,210,524,937,695,315,707,596,393,885,784,145,466,906,435,4,345,697,732,577,218,331,818,793,410,313,184,88,772,526,463,548,841,763,891,635,318,370,821,897,764,599,278,269,938,975,854,644,38,604,896,138,1,45,204,646,696,746,459,567,548,262,463,763,280,504,316,435,936,677,121,171,127,316,81,531,215,56,939,652,447,684,895,708,426,131,627,3,793,687,117,877,720,878,228,732,46,444,943,427,486,415,38,791,988,957,503,745,703,236,281,13,242,452,234,774,724,248,426,159,427,344,540,229,205,615,672,277,11,661,951,955,36,286,607,244,462,182,908,269,159,872,739,898,165,365,365,200,209,100,490,869,791,773,306,421,901,353,684,7,194,467,526,76,539,222,181,418,395,750,779,688,159,759,304,76,924,842,762,97,336,168,477,330,5,99,198,816,736,480,771,77,9,97,932,110,811,180,136,940,119,470,317,441,19,420,301,257,530,600,872,698,494,401,502,481,562,650,927,339,458,934,784,612,543,615,142,525,684,24,764,655,961,962,784,57,239,534,530,700,282,338,526,909,374,988,401,889,414,489,482,799,33,671,842,523,760,108,60,976,309,4,656,518,635,108,282,751,663,826,433,350,292,414,388,791,584,7,703,363,214,81,805,785,735,616,124,578,621,375,897,679,502,719,766,901,796,818,165,520,306,282,784,700,261,173,939,859,412,272,40,127,145,696,621,403,174,800,12,151,943,494,672,211,446,624,941,251,108,676,100,902,804,160,66,995,297,183,386,282,18,698,951,743,503,418,501,691,943,669,847,39,616,400,284,747,8,56,102,436,539,774,347,363,257,411,737,720,242,793,159,425,713,525,476,637,712,204,311,158,700,594,187,415,472,671,345,590,215,518,439,142,312,591,372,837,906,176,60,4,403,335,791,563,916,950,992,95,417,813,623,37,87,837,711,315,834,945,820,678,795,127,381,708,690,436,425,987,254,699,332,927,949,975,460,280,542,13,691,938,108,829,750,873,974,664,219,61,190,989,967,154,864,631,341,36,399,113,895,320,680,710,333,587,376,156,177,864,33,595,481,211,937,669,66,506,693,985,302,774,953,134,46,86,715,971,814,228,966,468,828,486,314,128,280,369,273,104,249,25,455,453,541,743,913,125,608,81,647,339,764,516,136,150,369,400,858,562,403,204,247,346,93,98,965,357,786,391,374,531,242,849,280,385,357,204,296,306,541,899,655,584,222,890,33,389,426,282,357,206,448,885,779,444,416,915,249,838,488,426,234,397,642,583,717,900,963,830,99,664,604,990,277,472,164,971,646,133,834,142,492,256,466,956,846,442,100,915,960,587,650,243,249,185,833,894,360,967,830,483,86,654,103,932,873,162,978,873,514,166,478,669,336,694,864,78,92,61,225,167,593,560,225,889,702,372,0,684,349,126,61,79,143,530,210,303,857,16,126,201,153,206,194,712,714,722,493,713,113,604,92,180,444,986,895,747,819,91", "696,703,249,396,449,739,319,112,418,142,778,515,903,974,769,924,955,334,753,655,413,246,828,137,494,667,486,533,549,84,842,832,434,681,751,917,98,251,679,809,662,758,655,793,755,926,834,955,712,791,449,579,605,799,395,61,253,495,626,216,489,579,369,86,718,2,147,876,925,333,60,49,742,83,939,87,468,753,631,698,484,45,166,104,856,130,460,487,597,813,71,808,348,660,667,375,581,735,909,962,517,350,326,821,816,143,312,302,121,291,217,226,350,52,784,53,3,219,354,156,919,798,919,337,827,552,842,220,945,726,235,153,415,390,33,442,72,61,224,828,374,886,339,211,195,339,264,731,795,574,152,207,770,735,54,12,817,160,534,863,143,502,306,977,651,130,799,753,514,374,53,348,486,104,397,120,909,341,959,35,604,788,849,880,154,519,224,591,353,643,760,824,403,574,821,300,388,67,35,221,909,138,224,927,489,461,334,361,14,692,637,146,853,704,679,422,922,660,549,986,26,1,38,189,835,668,486,496,415,985,647,751,196,819,855,956,621,459,496,330,30,629,792,532,408,545,948,792,816,694,327,720,487,594,329,550,999,907,246,309,611,333,84,148,108,711,414,281,428,40,197,305,80,699,51,331,842,666,306,506,757,479,604,801,108,828,726,149,193,277,396,657,335,150,571,867,340,134,278,363,734,569,164,463,142,701,241,15,180,545,881,893,987,378,382,702,985,169,918,308,720,439,322,91,908,460,48,367,101,204,484,530,344,852,491,184,35,162,98,478,214,595,385,685,177,271,194,352,583,528,570,669,670,560,610,804,810,773,771,545,907,134,377,857,286,926,58,277,852,855,534,419,127,514,216,415,948,693,503,258,337,357,273,711,176,117,837,101,646,430,454,724,868,909,250,188,110,770,832,607,673,589,902,171,696,700,223,746,67,328,785,448,120,761,74,90,499,727,254,854,905,50,919,867,201,423,360,124,727,648,824,841,642,572,400,845,387,215,787,993,892,180,314,977,836,214,881,886,722,957,574,348,421,838,918,483,25,501,650,652,359,663,169,300,318,725,271,830,97,457,838,938,683,567,927,29,468,432,61,20,597,158,992,615,247,760,163,196,793,855,464,184,314,485,952,574,302,884,172,940,67,526,804,387,606,353,385,298,13,190,953,925,606,704,179,927,449,614,881,418,116,931,881,121,521,812,471,854,810,240,686,501,838,475,355,168,128,48,729,267,746,414,500,327,682,536,725,37,894,896,273,979,322,190,866,774,507,993,895,325,167,201,513,202,974,991,541,125,378,221,123,79,484,205,205,781,723,914,287,280,770,470,562,114,541,504,984,288,135,660,223,893,286,145,455,367,475,840,47,554,929,602,667,58,780,584,746,902,603,707,705,975,878,935,127,364,83,785,610,987,860,36,584,345,405,557,37,21,93,277,16,782,932,676,696,565,991,879,651,220,833,93,830,994,841,487,689,424,102,260,293,3,563,823,344,245,5,18,432,373,63,961,566,934,214,845,350,14,896,130,357,608,783,956,844,769,521,566,832,651,768,629,223,832,384,198,367,778,104,315,226,643,655,839,674,457,177,380,104,653,287,856,429,520,847,69,255,662,359,437,739,640,597,135,181,819,750,472,210,248,905,797,346,631,238,609,370,315,859,843,948,452,905,874,228,282,63,536,692,705,611,899,622,281,845,599,975,408,538,10,735,953,981,466,929,786,265,528,77,72,567,672,412,672,674,493,744,151,815,813,862,979,893,60,695,191,446,800,350,594,160,470,179,523,892,990,610,904,444,281,194,399,989,474,499,704,887,491,198,639,512,851,299,938,630,11,706,822,918,227,555,590,658,227,727,382,454,207,934,892,832,634,935,60,125,530,693,48,180,966,503,745,436,647,605,40,386,226,923,426,390,222,420,112,468,379,960,933,24,484,329,562,420,452,827,800,680,927,884,870,701,604,738,478,515,134,258,721,506,349,923,499,692,73,548,889,742,925,346,297,510,546,982,144,40,547,325,359,445,553,899,845,381,814,502,462,587,891,130,638,617,125,598,163,51,592,701,338,732,238,983,194,515,853,375,682,106,876,411,854,471,941,692,397,101,203,67,647,695,330,149,850,165,224,315,720,252,377,413,414,352,574,6,119,62,341,268,187,769,941,945,627,627,970,428,926,341,33,496,547,610,631,114,214,738,315,357,332,684,0,371,710,378,641,707,174,840,154,662,930,107,420,815,696,264,813,864,368,255,681,209,280,463,182,539,411,487,106,196,756", "570,977,210,15,490,23,351,70,155,921,232,869,779,977,467,995,789,632,838,653,780,443,716,4,13,510,948,572,342,81,554,496,884,187,844,493,358,506,816,810,420,369,25,379,488,850,82,678,16,897,674,632,363,607,296,648,651,176,83,828,991,212,881,124,571,249,61,981,928,447,479,919,535,483,887,641,282,204,711,437,46,457,383,982,696,892,336,898,708,766,479,701,514,573,47,105,177,816,681,766,616,651,479,736,991,637,390,988,38,118,593,625,115,25,255,565,927,390,896,806,598,11,827,253,515,916,505,4,384,577,89,246,239,516,234,720,252,686,133,86,271,859,890,498,202,32,759,933,610,831,926,888,331,919,161,229,51,986,496,855,666,744,85,225,902,8,969,934,920,907,925,373,774,767,848,973,570,422,472,509,532,258,38,460,495,951,755,965,620,82,574,180,72,612,493,235,70,722,746,608,648,683,755,336,165,950,916,719,628,351,762,944,315,298,728,865,618,141,282,872,377,483,991,438,512,511,226,397,372,929,978,629,138,822,731,737,49,79,314,660,12,730,560,110,830,473,654,9,364,642,317,753,522,947,262,407,669,866,453,393,145,680,819,9,377,611,992,320,148,417,335,357,446,664,520,307,856,140,679,625,690,298,956,638,40,46,776,766,661,504,856,431,270,24,488,574,130,917,49,11,601,235,815,466,125,26,275,706,388,46,88,871,498,981,953,957,789,933,257,494,367,436,352,6,520,291,841,40,357,205,813,702,171,927,850,434,201,826,482,666,777,197,986,850,256,589,217,72,319,834,373,897,65,474,958,635,658,968,309,63,277,917,535,35,58,159,878,949,153,59,389,520,266,553,210,997,469,353,358,955,829,290,577,909,315,202,508,195,942,929,535,662,245,278,607,517,409,643,502,776,975,969,797,120,518,110,787,646,820,135,569,176,301,682,420,636,771,298,262,147,559,92,496,381,947,314,555,100,147,512,415,396,284,836,577,149,255,408,519,178,752,972,771,734,996,743,393,911,687,895,137,260,801,33,97,496,791,642,559,253,981,100,713,963,926,448,478,979,254,466,606,479,854,630,750,223,174,446,919,125,759,975,771,664,627,655,562,46,262,553,491,732,381,834,445,213,414,428,409,638,859,475,574,947,144,87,958,255,445,120,325,964,198,147,587,584,282,421,6,106,479,551,254,760,263,747,767,465,861,323,154,846,896,500,800,773,758,129,360,677,648,592,745,699,984,394,985,779,129,482,616,78,353,609,771,552,777,328,884,485,895,382,166,141,932,658,325,80,641,989,200,71,600,987,105,642,185,199,865,167,821,450,400,153,437,292,955,820,669,67,6,724,88,27,470,814,205,555,681,317,772,11,414,618,504,656,531,759,171,553,712,65,660,505,814,109,788,678,958,721,745,952,154,780,996,471,25,590,411,838,501,642,165,25,206,357,7,855,382,593,595,740,216,181,293,873,57,196,482,192,893,636,109,980,832,676,962,220,158,762,266,173,753,387,836,782,249,541,233,782,972,530,847,851,828,290,499,351,620,625,479,963,86,584,566,702,855,101,270,568,950,4,605,505,133,970,295,542,911,527,919,523,300,715,755,342,684,70,283,308,850,914,600,636,293,225,952,781,372,390,814,910,832,604,423,792,986,574,433,669,177,685,715,244,913,518,304,626,675,290,796,562,935,680,247,816,83,54,479,895,900,197,915,80,513,413,224,442,365,80,257,150,474,305,564,115,27,113,512,503,457,705,894,543,129,598,620,110,806,106,743,378,106,696,911,921,288,260,905,858,46,426,483,941,408,8,222,388,132,701,806,144,100,92,517,112,254,262,873,64,358,544,342,788,616,622,948,25,372,262,591,944,126,630,475,103,289,353,131,450,687,804,533,253,602,129,361,386,845,782,164,701,225,445,893,728,409,705,703,591,373,912,859,415,705,875,125,861,115,746,740,835,384,329,313,969,933,155,451,153,467,187,333,549,608,589,703,820,402,469,303,57,665,179,67,540,855,580,229,620,953,497,638,82,262,229,944,770,334,13,475,476,197,515,819,798,617,829,675,511,725,699,78,726,171,816,711,276,412,875,731,310,2,573,692,445,827,262,168,609,735,605,923,462,181,398,359,835,428,145,403,602,548,741,332,261,31,436,186,641,984,421,99,828,200,341,955,907,410,395,690,754,825,532,280,353,614,497,349,371,0,956,140,164,408,482,157,615,852,311,465,738,617,475,140,902,950,772,798,591,712,786,654,646,340,350,735,603,302,857", "416,243,135,324,271,814,811,763,998,255,867,299,213,568,284,699,974,220,638,934,120,432,470,203,204,228,419,504,401,603,108,509,181,190,234,952,384,798,225,234,719,530,224,9,731,669,945,663,489,19,383,435,168,671,804,229,254,703,601,895,341,754,567,748,277,287,754,809,52,898,864,717,888,315,424,867,186,662,214,368,637,26,615,570,345,865,654,83,874,109,310,877,519,61,36,367,306,64,330,61,607,374,188,138,494,952,165,272,371,214,173,622,28,514,276,610,420,756,735,426,748,322,282,645,372,707,666,835,611,185,816,105,429,752,499,683,575,882,788,949,189,32,84,584,985,87,395,563,476,849,594,165,217,577,352,700,581,371,819,202,236,740,650,676,588,331,539,66,656,989,192,367,485,892,515,284,657,398,684,603,633,828,5,696,187,409,280,938,735,539,662,958,346,525,400,594,901,966,394,1000,866,862,407,260,8,981,167,500,285,767,912,536,62,367,65,481,962,378,712,771,305,741,991,585,997,562,392,527,794,497,845,380,452,740,167,940,631,64,925,242,655,582,820,55,364,343,367,588,742,491,743,822,663,297,237,874,814,243,487,928,87,237,601,411,270,517,909,302,155,889,998,816,307,330,121,136,642,169,731,555,425,91,383,891,170,207,638,517,43,818,347,390,760,937,312,6,382,570,846,47,405,351,535,208,859,182,567,198,86,64,426,275,887,364,886,849,830,812,202,297,581,648,908,203,269,345,260,579,857,202,831,834,803,29,60,967,958,413,388,91,693,596,711,660,671,452,416,989,65,715,615,142,61,860,511,290,557,203,516,538,907,968,652,424,131,862,682,40,749,505,567,398,172,926,331,65,107,33,718,334,156,116,974,160,92,689,731,391,151,448,189,819,625,128,132,523,190,749,5,764,59,84,659,923,262,467,701,153,970,485,947,485,107,755,857,554,750,56,816,666,780,481,134,234,708,464,844,855,372,613,472,690,297,190,714,261,725,49,131,823,18,931,400,925,586,556,396,7,829,583,700,556,889,583,709,147,950,672,701,419,413,715,396,364,388,320,390,612,259,885,836,800,275,635,325,657,761,541,714,498,534,676,69,393,712,369,756,304,76,840,937,616,235,254,449,462,151,305,563,637,487,892,371,167,615,777,30,676,873,836,674,837,314,753,946,619,291,13,788,979,192,636,86,5,232,881,241,877,188,295,719,360,367,36,898,149,203,796,827,507,534,93,266,558,513,151,878,736,636,801,807,751,264,79,687,175,955,417,332,48,390,312,139,222,465,900,936,43,501,790,78,994,668,796,474,1000,287,604,323,982,480,850,89,207,19,551,302,61,611,394,101,536,820,789,612,24,568,734,517,242,938,44,129,179,401,107,853,174,481,175,513,663,205,656,700,820,243,386,31,529,408,61,149,776,131,61,686,39,824,150,444,775,375,717,39,108,614,610,955,538,690,355,941,48,493,168,429,649,29,155,229,996,991,715,553,91,767,87,69,861,701,55,579,805,633,978,175,433,987,40,664,689,192,739,443,897,105,989,741,867,314,986,443,760,898,652,576,201,307,384,321,575,174,801,741,315,950,761,800,74,99,737,749,503,679,256,690,266,858,766,22,220,52,9,271,278,385,924,850,194,400,518,503,511,733,942,130,216,101,50,744,456,790,362,712,966,774,640,793,35,644,483,860,121,103,550,515,389,494,355,150,251,912,142,525,317,605,288,945,983,91,373,254,523,146,47,174,446,596,428,769,185,304,371,803,493,107,929,164,137,986,683,393,45,362,385,722,562,304,636,850,394,883,143,966,617,672,700,835,627,673,552,877,723,40,82,402,490,393,952,53,102,280,906,890,641,729,179,218,447,171,489,117,856,328,675,818,730,836,5,45,538,474,262,978,395,764,662,607,433,827,253,2,256,384,332,924,909,879,23,339,793,874,170,994,555,369,796,675,782,16,781,826,860,555,172,997,86,268,950,191,587,543,947,566,644,371,331,379,319,386,517,867,47,269,439,512,857,36,89,7,529,507,51,520,720,69,35,203,339,74,482,280,104,460,912,339,672,353,258,373,565,734,473,56,107,991,832,659,621,100,240,328,39,103,267,570,875,871,433,996,654,187,714,41,675,443,726,589,37,976,989,534,805,876,721,106,247,650,857,604,240,69,942,521,775,570,644,218,89,605,408,18,584,713,615,211,92,126,710,956,0,174,775,491,631,256,258,117,65,878,344,503,200,409,283,320,333,185,946,887,322,200,327,169,806,171,308,205,873", "444,630,677,725,884,719,989,222,535,946,289,293,598,402,157,540,104,959,683,547,309,257,634,587,468,197,575,923,475,62,807,736,35,842,669,295,641,165,141,619,298,975,83,59,909,825,820,214,139,694,836,313,235,829,857,200,856,618,683,374,850,298,647,378,632,213,801,261,603,36,884,700,574,855,141,171,927,572,907,676,304,77,27,231,990,792,6,339,573,313,626,100,485,440,956,443,38,963,381,464,595,393,613,426,722,96,326,89,133,656,486,781,477,772,118,497,574,944,612,26,812,285,758,711,652,491,965,965,418,996,178,657,794,18,866,146,861,927,490,413,995,471,213,139,671,583,676,54,841,299,824,417,168,805,219,682,411,454,50,78,98,324,373,694,151,305,779,644,368,450,447,89,646,460,613,60,677,671,383,651,271,615,384,843,829,261,788,222,856,550,503,334,114,572,508,603,835,315,713,639,335,137,294,70,856,134,728,773,931,846,30,197,951,211,861,414,532,62,390,886,401,234,512,631,669,52,430,834,295,622,831,970,599,49,118,500,697,819,950,517,938,131,408,400,534,313,318,727,959,929,837,445,650,476,828,980,384,226,280,314,91,382,928,849,416,36,189,638,481,298,649,604,827,762,662,723,633,957,762,536,204,472,83,663,997,712,228,981,323,178,405,525,483,98,918,124,32,218,561,890,796,471,927,35,694,639,112,934,616,58,436,385,111,257,960,655,926,867,290,143,871,951,553,20,480,269,16,846,139,879,938,721,571,930,774,389,142,474,157,759,478,685,447,889,584,431,218,134,278,655,236,604,448,252,626,972,817,770,402,484,334,755,441,373,135,896,248,219,933,755,670,988,108,855,679,429,440,617,768,694,985,757,340,799,18,474,738,10,465,551,367,212,992,689,592,75,758,510,517,641,941,495,98,880,637,392,939,404,237,906,479,822,993,950,720,236,871,826,920,30,252,594,473,797,151,944,450,592,46,941,101,147,35,650,28,149,5,482,112,892,659,160,917,968,759,996,324,996,494,745,301,468,579,342,315,986,337,948,117,826,417,571,328,666,901,170,415,829,406,976,729,102,792,461,723,739,428,496,529,754,359,478,220,546,192,609,926,117,155,363,301,108,189,573,993,489,899,478,692,697,555,185,802,214,275,937,392,62,5,660,282,944,211,871,911,368,759,343,844,419,683,432,215,40,382,136,690,444,699,173,264,367,191,287,211,904,56,621,149,969,585,562,898,298,190,222,646,729,204,100,319,278,650,664,482,912,490,738,506,180,317,192,614,783,868,880,677,877,977,281,171,768,497,221,780,778,905,865,857,677,869,289,53,278,211,437,412,759,529,470,902,177,195,814,430,864,258,681,652,428,385,773,213,909,291,496,758,143,417,402,912,791,667,56,319,67,243,339,268,914,542,780,609,75,454,312,272,119,304,580,560,841,442,678,19,347,528,415,588,672,112,777,211,325,930,582,606,525,973,382,647,312,86,757,96,766,847,693,904,128,920,406,162,949,495,565,432,653,491,484,541,16,413,501,126,440,444,177,10,135,536,445,664,585,239,29,527,982,98,489,715,21,901,225,766,546,597,881,861,973,573,122,893,855,476,534,293,260,656,21,116,586,406,586,872,718,783,344,562,171,320,900,177,790,37,243,808,689,856,794,688,530,529,387,362,777,910,765,776,268,450,344,168,659,425,726,48,221,129,376,841,51,699,733,931,182,382,505,527,927,737,790,624,264,45,352,904,339,513,650,220,81,722,188,545,555,773,293,490,390,479,798,129,54,650,905,199,781,630,700,779,829,104,977,968,770,287,813,911,623,629,36,664,671,140,180,417,468,872,187,86,449,168,613,573,947,978,770,547,444,743,292,39,59,562,825,68,153,905,704,609,911,187,277,507,495,153,984,595,319,831,181,253,623,92,427,143,920,81,850,272,641,615,238,4,203,906,447,983,799,870,970,838,875,402,119,417,989,613,998,667,399,396,408,879,58,73,765,584,160,620,97,310,375,649,473,77,122,461,789,729,822,236,667,692,27,420,501,373,837,796,689,686,56,254,288,190,872,361,437,830,306,961,92,597,261,251,664,675,368,881,574,829,679,31,513,932,871,630,940,740,580,336,716,239,301,244,515,353,176,498,826,61,132,433,486,874,498,206,918,796,208,193,814,870,278,715,233,427,588,107,491,756,53,618,683,308,731,61,378,140,174,0,882,96,246,514,458,489,541,616,425,117,472,892,717,464,302,648,624,426,910,141,160,729,853,818,732,757,484", "784,613,290,825,416,862,151,757,751,86,135,167,981,983,52,176,552,304,139,934,119,597,242,574,599,563,482,713,836,940,905,440,623,686,671,87,81,817,718,95,482,451,735,286,77,259,333,380,103,326,720,129,755,279,798,911,87,741,789,174,307,6,475,134,377,157,871,441,459,932,553,785,640,790,58,562,325,299,432,125,316,261,801,611,638,990,48,398,516,490,854,849,993,438,883,634,109,792,748,432,466,520,994,516,481,732,69,215,136,983,901,378,960,884,546,223,214,926,920,197,523,479,491,875,910,610,105,514,448,570,241,852,591,350,555,391,133,535,408,653,798,664,69,227,415,263,339,762,733,605,957,473,591,606,924,716,877,602,125,865,702,952,904,415,109,356,486,200,99,804,949,111,496,479,295,393,608,765,437,126,900,113,446,664,510,337,405,450,739,458,143,206,54,97,123,883,447,365,504,970,697,332,16,68,855,869,613,304,391,378,566,232,160,511,522,752,98,520,550,485,506,468,600,605,865,151,264,8,517,345,451,311,445,370,143,784,528,825,653,859,32,198,407,633,241,144,460,237,185,658,833,542,279,791,765,930,737,256,444,538,433,700,685,739,248,733,295,170,387,463,700,738,680,848,86,879,563,667,127,452,677,452,671,226,912,846,409,250,718,901,383,71,511,711,387,671,968,36,411,867,483,468,943,456,167,123,151,487,440,662,52,903,695,747,176,300,326,499,523,68,403,190,283,495,18,10,503,759,659,595,623,486,343,849,768,855,747,318,577,467,412,2,16,128,758,417,845,181,895,119,150,591,861,311,689,338,454,452,232,931,114,15,73,904,105,584,971,756,166,44,83,137,935,315,976,200,789,858,392,984,948,713,606,192,492,516,978,746,942,102,192,184,80,742,131,908,493,580,756,288,490,633,618,488,100,981,980,444,977,997,334,525,372,476,2,983,415,845,389,453,565,303,242,731,877,174,691,924,349,176,655,366,850,64,4,547,830,81,351,402,362,936,194,540,699,662,60,302,348,700,355,553,992,284,914,754,483,54,409,955,421,299,941,98,425,969,300,767,985,747,238,133,434,99,155,821,346,942,239,243,233,213,591,581,580,483,911,869,222,735,852,717,958,171,689,97,429,189,981,613,433,83,784,124,461,286,138,220,871,294,533,400,837,53,1,653,206,655,534,807,871,368,208,168,68,207,492,826,65,266,409,220,324,918,127,260,953,825,679,871,657,537,170,919,626,117,848,891,760,623,804,232,463,155,974,4,781,482,648,638,572,526,968,32,58,623,121,235,585,273,962,424,221,689,708,976,677,443,151,390,222,187,564,220,764,334,414,784,397,355,751,319,333,927,9,7,436,454,485,71,11,648,902,216,76,135,478,432,185,843,630,981,924,239,153,39,453,353,319,236,295,818,496,475,573,468,144,225,380,866,743,252,923,801,811,717,911,573,738,679,217,417,672,567,77,385,594,479,757,505,182,890,662,283,147,330,405,948,491,150,258,816,670,276,463,444,916,236,32,99,800,496,839,600,160,763,784,333,399,209,147,850,527,355,976,365,41,722,115,60,1,910,361,511,793,290,762,293,615,873,529,55,445,112,423,14,736,54,445,950,424,210,392,191,516,901,788,330,125,94,688,738,148,168,900,434,77,229,778,507,461,756,736,938,188,119,662,431,160,566,5,691,159,957,477,222,508,558,164,850,281,829,741,665,981,153,346,440,166,295,669,820,841,163,572,768,764,435,819,578,705,38,539,352,574,618,773,509,88,116,806,520,984,59,902,299,449,152,987,220,755,582,288,386,429,427,875,321,123,853,571,482,310,194,430,199,539,985,875,103,797,867,101,902,454,954,295,348,862,470,777,296,602,362,307,424,101,368,194,729,797,935,911,31,13,795,750,29,319,295,35,639,47,100,963,368,680,490,347,304,437,42,86,150,537,62,665,615,717,450,652,776,178,298,395,985,579,461,282,576,221,34,458,625,952,34,240,329,275,49,582,456,5,631,606,995,745,69,944,620,669,402,686,844,999,657,59,589,679,557,195,963,696,741,366,2,589,426,930,587,129,336,836,717,639,137,513,248,890,204,700,858,345,474,678,472,281,673,884,487,447,875,109,396,160,409,475,728,133,880,54,33,827,412,325,968,515,833,951,107,189,193,220,891,899,759,959,675,691,612,352,57,762,676,189,48,911,885,79,641,164,775,882,0,773,929,542,187,765,736,900,501,466,389,754,564,326,200,331,30,333,70,727,161,334,636,815,36,346,813", "581,262,752,479,9,674,615,970,757,61,410,960,11,478,856,520,499,989,815,976,727,209,93,613,84,650,861,393,151,967,163,982,708,941,763,611,27,302,479,197,300,665,689,252,387,254,749,599,547,430,700,875,42,418,635,679,684,455,202,91,181,962,82,486,845,526,314,827,824,572,575,82,283,522,505,474,873,772,997,584,571,356,284,132,611,763,800,565,530,39,129,780,175,835,341,495,533,50,662,55,600,251,519,241,989,685,629,155,24,110,409,131,30,767,903,632,375,63,669,205,286,839,630,307,373,437,105,268,107,951,569,64,720,926,24,690,323,766,1000,620,274,963,222,724,294,365,664,606,367,274,485,13,422,961,954,293,777,47,768,945,969,154,923,601,416,515,745,127,820,234,351,393,496,914,10,325,262,682,363,651,777,364,204,749,615,240,905,668,114,476,638,533,264,651,493,708,380,565,400,767,234,718,199,337,739,457,959,955,908,507,60,781,292,684,637,430,504,885,33,764,56,431,315,564,288,435,660,711,405,610,806,97,351,160,869,630,903,674,26,572,466,304,680,305,335,936,546,349,398,648,558,646,305,167,66,795,301,474,450,654,381,713,979,56,292,81,733,744,725,450,433,826,652,584,687,375,269,458,783,881,391,647,179,288,857,77,500,437,268,262,470,59,264,368,986,965,449,877,188,27,401,456,27,932,610,258,469,306,597,344,355,676,846,494,995,56,670,219,70,165,972,694,796,956,800,454,287,638,575,396,629,402,556,635,393,352,752,95,7,87,809,489,457,368,932,297,52,708,644,510,57,688,709,675,710,149,376,333,107,227,189,65,154,897,483,780,844,813,994,519,156,184,84,345,567,371,74,560,576,849,833,736,905,632,457,168,827,6,413,476,249,909,64,372,995,703,34,920,82,577,772,868,432,379,22,292,956,126,67,759,134,295,591,593,45,738,697,27,797,263,920,770,847,370,962,377,237,599,172,157,811,543,151,280,23,598,554,486,770,451,259,893,151,400,770,602,783,347,812,827,730,577,715,674,421,758,81,376,464,687,539,501,532,567,295,738,515,836,709,864,324,170,461,158,3,51,246,397,959,869,636,689,344,858,929,482,710,901,49,800,162,386,21,344,764,875,52,50,245,391,274,567,745,297,997,992,904,425,454,733,102,217,906,922,144,576,536,965,193,755,632,895,962,820,903,303,374,29,89,661,766,102,943,317,136,330,372,670,10,872,186,977,886,147,870,38,677,417,587,572,965,924,395,719,291,698,334,244,547,951,808,214,449,288,973,928,678,259,280,600,544,189,956,689,61,238,598,764,606,548,775,558,8,32,396,341,684,248,913,460,996,109,826,912,783,631,26,135,927,207,387,616,969,569,160,928,150,268,128,60,144,769,673,990,150,456,263,445,361,383,487,127,337,648,782,890,218,995,111,979,623,567,660,969,484,255,638,948,133,865,279,408,498,753,158,443,814,323,700,606,720,727,710,678,118,466,776,704,654,676,173,686,426,114,325,448,178,95,868,107,913,470,585,791,229,713,570,258,106,674,940,57,475,220,776,596,748,639,926,620,908,46,75,739,665,233,946,998,643,547,487,440,134,972,156,620,244,148,519,310,928,785,120,107,252,658,538,676,21,743,534,32,628,543,98,495,270,992,754,831,279,599,972,63,575,673,399,986,709,221,718,801,475,253,44,218,225,345,985,527,349,880,827,431,932,653,334,959,267,984,39,787,220,862,76,739,241,526,424,655,118,985,221,890,86,319,318,398,604,824,797,764,58,668,213,327,886,901,636,848,994,973,425,651,702,518,911,965,323,731,519,15,240,422,860,798,286,872,435,891,582,544,396,220,639,725,331,367,899,649,808,653,998,387,38,302,887,521,536,704,927,429,666,949,60,369,445,772,384,368,786,188,864,295,178,324,930,114,536,616,608,896,22,757,917,323,102,53,745,712,609,975,639,238,371,924,265,251,323,795,981,84,304,967,193,579,167,476,711,615,905,470,635,582,130,820,27,821,701,563,149,414,5,815,132,198,739,531,7,377,812,736,767,20,909,668,302,607,506,995,381,683,163,208,485,660,340,878,355,82,390,863,193,218,520,384,814,905,675,18,314,928,373,73,29,751,9,570,643,385,685,491,654,389,12,93,832,718,533,922,406,77,745,542,457,647,733,789,777,493,158,126,371,591,376,89,237,190,143,707,408,491,96,773,0,171,134,96,520,687,692,122,205,766,22,814,60,767,478,484,563,160,308,904,699,734,350,895,850,710", "829,721,535,418,14,138,276,825,991,457,958,56,937,510,437,4,352,658,806,425,447,55,845,5,629,833,467,113,182,256,706,292,392,191,100,880,663,145,392,308,233,298,461,744,756,163,124,842,703,852,584,888,313,799,424,472,137,998,789,570,915,789,151,345,609,828,294,66,709,969,110,135,54,277,551,985,656,169,625,406,541,174,744,33,949,559,149,740,276,877,328,744,106,974,750,993,86,739,252,230,363,775,807,138,544,866,418,836,466,315,514,867,736,556,213,407,971,596,244,775,785,270,542,933,162,758,976,590,75,555,570,980,423,98,16,420,671,874,830,442,832,474,98,543,635,488,529,353,431,599,476,92,958,309,392,388,619,128,706,996,974,727,70,96,861,726,902,149,218,548,826,593,11,852,890,454,506,854,316,952,397,501,752,303,671,704,320,181,537,728,884,389,438,242,125,361,469,184,530,553,577,519,610,355,208,586,84,569,805,502,723,178,626,780,59,511,410,849,705,976,714,289,242,659,19,32,841,577,967,357,18,749,295,471,925,605,736,844,562,758,531,611,705,171,60,994,269,350,742,718,382,671,334,435,795,846,60,889,360,336,242,144,696,75,336,470,437,736,430,21,875,983,541,287,536,785,359,162,37,238,671,607,149,227,875,156,212,314,25,36,694,348,436,427,369,482,723,356,868,514,802,3,210,340,591,310,689,894,124,879,201,37,616,296,939,808,827,20,75,174,414,764,14,820,190,111,276,361,195,420,253,280,666,835,192,905,907,429,457,276,557,615,11,341,941,641,908,555,983,912,287,877,767,458,502,673,782,90,805,374,256,349,732,231,405,915,936,812,59,31,764,340,885,776,638,101,396,42,173,94,275,690,251,971,981,569,549,556,297,423,154,200,797,697,594,350,528,400,367,601,829,47,44,810,141,565,252,750,880,435,804,538,859,253,60,852,821,423,438,284,220,771,631,872,361,714,269,860,423,155,472,834,41,160,863,732,846,551,90,717,469,690,931,311,47,541,8,922,552,698,788,392,635,445,721,987,496,874,842,386,884,260,296,349,509,100,497,818,765,663,433,464,497,47,301,990,577,297,114,639,424,190,341,301,639,449,621,335,792,22,1000,359,671,556,353,764,92,315,182,957,492,285,65,77,947,741,227,454,48,372,69,928,324,412,960,726,248,78,445,228,437,696,234,870,739,574,742,315,326,589,650,598,805,54,242,707,797,611,477,235,257,893,218,275,461,84,224,910,617,774,494,323,260,292,444,77,456,713,779,542,37,67,862,965,312,800,68,54,410,398,751,231,511,573,225,349,703,588,597,895,865,532,509,295,517,844,143,900,960,353,114,82,56,993,689,298,979,513,445,99,34,674,49,949,260,39,718,283,850,582,723,745,236,123,809,351,715,182,461,947,876,702,416,867,963,760,920,244,214,892,97,11,176,816,22,881,600,574,853,939,895,297,339,313,858,149,735,695,744,485,393,241,805,699,273,62,443,921,106,211,382,716,80,601,728,905,823,348,184,802,585,4,879,456,61,709,946,296,94,532,362,602,260,720,593,978,439,23,763,524,493,931,772,826,203,293,827,789,408,764,899,780,715,541,621,124,109,501,498,362,771,424,194,549,26,432,607,884,217,577,923,31,91,979,963,104,729,569,502,129,838,295,188,511,753,769,62,620,805,217,796,460,696,100,706,349,521,92,575,6,8,221,144,623,208,813,264,448,704,734,313,808,826,436,881,986,220,115,99,706,726,307,953,303,442,242,285,110,241,773,178,554,464,998,439,649,916,538,816,945,158,195,873,983,122,459,120,966,36,239,276,31,633,834,190,103,984,220,86,548,21,401,378,411,516,913,854,299,987,84,369,724,587,241,480,87,212,527,743,778,194,270,915,515,358,354,749,112,644,430,722,51,836,584,180,237,505,48,323,671,769,480,574,677,523,397,342,869,822,864,129,29,656,415,340,435,954,875,155,611,56,861,519,90,445,889,510,405,899,237,571,136,928,824,549,873,692,643,912,38,479,572,909,470,473,880,979,994,459,477,515,149,64,490,691,729,35,539,97,826,648,577,414,908,900,998,460,489,208,166,582,509,547,811,781,227,172,285,36,295,853,580,336,542,383,972,613,310,92,239,549,993,194,736,577,903,435,192,392,86,925,708,662,223,343,745,998,184,372,137,895,581,857,248,513,712,672,104,530,174,482,631,246,929,171,0,498,336,285,632,158,224,57,817,97,44,130,792,806,236,901,124,863,392,28,663,484,443,734,100", "870,100,984,240,178,258,357,24,418,18,52,78,993,68,287,774,189,236,81,715,523,451,767,592,133,672,149,420,360,36,804,960,797,51,443,951,47,652,887,731,750,232,587,450,974,989,866,61,217,912,947,292,244,679,78,751,503,765,726,830,545,75,218,399,77,555,143,397,975,932,905,832,828,415,951,586,349,846,987,31,770,252,296,691,602,146,84,265,221,732,398,546,317,724,707,27,965,304,814,570,439,86,636,988,395,386,495,667,713,983,235,618,732,392,832,53,853,408,387,285,774,10,93,816,443,881,287,220,149,475,635,649,509,196,689,256,133,904,144,863,955,277,46,222,25,494,424,744,458,896,468,792,232,398,149,492,904,345,298,851,91,19,616,656,966,430,387,292,443,325,572,122,784,97,231,572,557,315,423,146,894,966,571,980,572,314,769,411,698,866,74,988,192,897,326,357,581,291,208,953,691,735,371,413,331,422,721,680,712,206,908,517,633,972,718,310,373,373,470,363,161,506,393,261,358,944,156,519,421,602,839,852,913,129,304,775,880,42,154,105,309,950,66,704,208,86,790,838,467,981,630,865,776,572,531,821,924,359,771,452,35,920,399,212,674,465,394,124,907,231,737,145,564,90,510,8,433,648,358,710,912,528,190,286,432,372,451,815,348,609,972,405,509,822,44,577,98,106,511,800,810,130,529,171,671,658,504,566,854,407,244,504,192,9,166,429,207,37,970,54,645,353,500,494,891,502,907,427,438,195,650,627,16,913,248,299,486,674,158,821,323,378,523,700,410,975,512,975,763,454,770,508,58,175,505,208,880,76,595,480,787,656,819,78,551,60,420,607,503,504,770,609,912,472,548,128,526,327,600,224,783,590,134,158,719,927,844,508,980,240,566,430,384,546,420,758,138,26,734,179,684,561,454,233,391,130,76,134,240,154,737,340,89,433,622,731,465,635,78,967,580,554,555,40,471,138,587,334,876,901,475,837,315,591,117,315,771,518,246,121,927,826,663,609,137,883,520,302,867,228,557,146,720,594,181,656,304,713,602,867,702,947,670,40,340,987,106,700,769,416,561,183,722,506,572,481,353,489,926,327,783,698,431,45,835,768,162,601,869,361,757,503,37,797,618,446,558,196,367,286,353,388,267,140,712,476,954,472,721,61,461,728,861,785,63,912,561,408,201,569,610,731,85,52,378,610,109,720,76,553,118,913,76,649,455,364,467,747,825,204,529,581,83,416,713,375,544,198,470,458,973,516,61,994,188,139,948,29,237,166,757,243,24,433,528,981,202,962,797,210,384,963,678,222,689,341,284,364,406,529,833,445,713,580,845,58,25,236,617,21,984,664,647,988,470,564,860,596,852,469,89,654,496,401,471,243,297,889,541,870,267,791,934,743,561,762,192,964,961,890,717,124,74,110,182,352,598,406,158,433,78,373,677,879,313,140,598,725,230,759,30,301,835,862,896,563,457,223,711,910,383,272,904,254,693,212,114,448,366,2,280,327,820,465,550,219,771,790,165,516,221,602,140,860,233,135,696,55,211,827,922,839,435,134,404,595,696,845,665,609,480,809,911,308,135,84,528,171,201,957,267,623,648,548,399,46,165,51,147,261,674,56,492,28,901,336,28,694,408,468,346,621,10,942,707,519,607,568,229,669,427,222,319,105,932,552,399,795,930,500,97,979,188,935,247,279,614,394,395,726,192,496,961,753,228,80,643,203,838,692,775,24,458,909,218,764,293,800,903,541,873,174,607,547,168,431,964,538,166,343,977,117,530,27,159,815,501,648,570,772,112,837,442,595,333,173,60,75,837,266,589,12,225,500,656,229,617,310,70,107,770,429,786,966,542,977,910,64,553,641,233,729,555,854,915,658,335,185,161,977,825,514,320,535,581,184,43,679,461,712,955,227,190,544,869,292,897,251,777,628,363,732,304,767,106,803,967,357,209,997,504,252,864,386,762,144,698,768,986,51,273,518,184,959,76,125,40,326,859,202,415,654,50,342,425,220,549,618,607,198,546,379,923,74,19,103,615,311,141,570,834,526,384,386,895,600,334,225,327,519,564,572,153,132,483,97,277,145,932,121,177,59,136,851,379,252,354,970,195,892,130,109,232,167,137,905,162,884,732,909,760,4,401,742,490,21,265,345,356,296,228,160,685,262,137,609,11,94,334,720,158,171,172,488,432,881,839,974,210,840,157,256,514,542,134,498,0,371,6,827,571,193,787,277,368,261,563,178,521,333,90,132,569,839,250,251,119,773,189,29", "378,807,861,353,92,562,364,737,474,142,975,930,523,490,253,92,676,740,362,104,861,316,75,591,734,333,106,767,999,965,144,319,981,679,843,50,522,351,723,204,110,592,180,231,803,707,606,486,953,594,560,443,829,869,982,78,663,671,48,490,831,138,64,102,6,178,123,813,876,506,263,102,338,522,35,888,159,581,35,894,876,252,22,764,237,507,830,119,50,454,311,272,436,444,796,135,452,30,272,109,985,56,680,111,451,810,758,351,613,250,167,581,597,29,512,212,738,529,660,475,463,483,229,102,23,625,725,938,43,182,691,792,740,566,255,598,316,336,352,970,324,905,476,516,624,275,372,344,810,210,641,614,779,949,894,660,462,478,324,461,784,946,161,277,402,103,650,848,653,366,386,359,439,234,113,790,890,401,573,527,938,302,521,466,476,323,816,661,420,198,791,468,537,641,939,783,508,303,871,901,328,448,65,629,405,172,755,778,559,219,126,685,321,640,693,86,133,791,909,149,936,515,316,53,763,973,75,13,876,873,922,541,157,11,94,592,425,547,894,597,102,756,673,94,471,567,307,963,914,894,978,593,464,674,593,620,757,776,236,908,398,989,674,642,134,956,661,799,960,867,276,653,764,982,626,180,540,547,740,11,321,167,879,571,843,631,512,29,789,192,647,935,178,190,33,301,808,97,58,49,579,896,438,141,133,834,990,480,188,97,619,792,135,122,357,756,105,221,276,540,340,834,322,740,835,417,245,890,681,416,34,628,65,16,209,539,362,111,174,416,26,699,446,274,729,441,147,382,290,549,276,873,436,711,193,392,786,650,49,298,810,193,712,625,813,639,214,616,103,666,330,832,607,973,216,314,530,194,710,224,560,305,538,74,727,36,313,743,129,351,431,338,493,487,319,444,133,192,564,92,315,370,691,651,253,79,811,864,295,742,489,135,750,772,269,656,831,514,856,217,224,161,613,680,643,808,639,287,211,811,201,702,548,860,65,681,85,820,46,427,936,338,905,171,56,200,28,804,97,425,466,956,468,398,933,90,965,417,437,803,232,863,981,780,187,248,669,819,281,34,312,511,166,993,22,267,209,713,68,76,258,571,170,248,207,912,967,780,487,778,161,313,614,921,681,454,19,605,850,314,446,137,660,134,954,832,342,517,475,354,354,596,836,168,994,321,389,136,485,530,315,331,237,719,51,323,840,391,515,31,181,143,3,689,493,168,110,274,198,423,207,849,878,307,81,606,875,861,244,6,726,121,302,571,643,501,112,461,47,38,961,993,151,703,236,908,800,178,525,631,22,799,124,671,147,875,337,445,963,701,279,457,535,689,427,366,950,959,301,328,688,287,23,228,155,746,845,32,934,957,109,943,43,706,500,351,368,290,670,963,792,539,134,629,441,783,433,281,259,495,64,966,961,426,518,374,253,660,210,628,954,281,909,873,226,291,557,368,494,679,108,239,537,757,320,15,802,855,129,167,174,273,557,105,33,606,523,856,497,964,213,733,217,906,238,918,133,58,155,805,46,680,69,677,221,482,714,498,73,346,869,946,747,197,756,437,6,118,525,996,484,933,833,386,848,763,403,799,716,727,363,544,603,56,903,676,301,724,345,280,837,376,637,73,92,150,556,282,601,293,288,62,120,834,166,4,781,649,904,95,256,480,151,453,204,213,66,875,493,437,615,120,366,910,71,408,3,604,792,575,933,922,211,381,784,962,705,96,845,550,266,532,930,590,936,196,211,721,299,288,876,378,796,378,469,542,45,722,350,125,670,297,536,290,100,653,767,461,273,903,30,197,102,884,586,690,804,6,729,465,699,277,384,482,482,996,134,300,124,267,928,348,889,198,63,162,326,957,293,35,353,539,868,209,707,73,782,537,77,77,191,527,508,826,828,291,278,100,16,523,653,907,639,374,43,931,527,644,169,639,609,716,372,887,665,390,492,429,930,329,873,326,296,735,385,12,941,261,36,748,396,911,446,855,63,67,596,619,937,790,977,90,948,562,666,262,327,900,933,817,649,730,506,867,741,750,781,719,321,322,135,874,404,517,862,319,636,95,666,965,516,436,129,576,162,485,518,215,733,726,843,234,116,535,256,309,845,626,325,498,539,682,398,54,590,838,485,440,604,495,30,651,902,424,350,549,670,796,860,16,549,174,145,420,799,876,443,999,208,986,894,115,820,531,501,514,141,482,303,154,615,258,458,187,96,336,371,0,911,470,921,855,377,289,834,497,650,269,254,961,6,272,188,305,186,352,162,957,406,235", "368,17,840,110,142,714,656,670,396,18,168,685,679,140,601,945,625,371,109,803,140,935,320,815,560,763,468,832,676,204,76,444,671,751,556,908,773,260,773,17,309,216,840,313,259,164,866,979,192,321,582,104,205,153,815,421,806,777,834,15,104,20,610,715,773,653,82,211,441,636,134,791,875,525,258,729,707,727,972,235,683,789,262,875,83,392,656,802,913,738,244,410,869,875,217,926,326,694,654,701,231,635,414,46,787,570,757,268,847,23,746,640,869,117,483,12,913,980,90,692,371,28,943,392,540,152,662,279,961,156,861,987,313,146,302,939,293,687,126,881,692,985,105,105,463,944,35,735,325,273,528,659,64,286,846,307,532,906,296,292,151,183,460,819,827,742,691,308,847,828,7,845,392,854,719,515,703,82,704,326,509,415,682,26,721,70,391,321,887,682,788,355,20,175,411,985,692,750,280,332,679,641,933,804,227,637,427,837,172,819,477,924,888,978,557,927,480,277,310,290,709,710,863,392,247,384,581,767,147,74,6,250,90,616,889,738,205,183,75,565,376,884,162,262,600,347,489,271,429,762,895,950,145,339,717,18,753,852,410,303,346,96,766,627,781,794,151,57,726,113,34,484,892,110,929,343,411,122,306,981,545,644,192,614,459,689,33,562,975,571,265,298,908,822,769,360,414,451,760,755,873,863,878,248,494,385,439,44,419,907,45,724,29,245,677,604,443,800,951,709,317,440,960,989,763,201,33,975,990,521,49,875,335,571,244,808,137,984,260,155,415,35,144,244,679,191,987,564,713,405,361,335,518,845,867,902,63,688,339,110,509,913,350,818,2,731,421,330,401,559,756,331,352,737,378,143,477,799,476,574,512,925,11,424,775,498,218,146,75,371,406,499,311,447,197,99,44,163,267,151,695,327,950,874,71,586,320,30,70,808,465,334,505,960,797,195,976,939,536,840,968,111,359,160,791,482,483,472,848,293,23,446,809,158,702,881,825,109,227,362,394,425,769,692,780,498,143,535,15,824,387,76,646,157,942,62,313,531,454,586,116,938,739,673,355,54,40,659,349,468,55,113,463,48,736,660,235,449,359,788,136,551,203,790,485,160,234,813,818,480,104,569,316,917,204,978,10,476,122,927,58,586,609,167,778,603,785,536,531,940,433,693,761,961,611,865,706,967,729,568,164,138,828,596,777,573,332,753,734,84,266,324,975,261,336,965,330,29,592,497,699,629,450,569,846,526,373,547,710,586,839,703,969,899,228,746,22,522,806,995,311,750,24,669,498,201,132,547,33,601,741,700,823,898,566,901,221,327,583,723,377,882,112,853,87,426,882,242,752,450,513,784,296,987,764,440,205,963,303,800,630,471,563,328,25,102,563,289,919,513,608,635,442,771,735,882,82,885,896,248,248,350,405,907,372,916,71,287,737,924,995,767,887,823,439,358,308,899,625,840,344,294,832,896,109,549,4,224,328,374,173,923,372,474,156,6,998,120,712,387,67,425,146,558,787,40,225,777,932,636,879,706,679,530,46,78,817,518,624,331,767,825,86,951,765,382,863,876,203,331,433,711,103,145,496,612,205,311,182,66,367,678,287,25,605,576,543,698,399,418,977,284,146,239,336,76,644,751,535,382,342,365,840,212,452,929,7,896,475,201,790,995,581,849,874,966,151,384,882,712,681,777,661,512,200,972,62,478,58,728,680,503,172,457,408,227,143,915,379,966,132,113,683,563,782,841,278,371,655,756,538,736,133,656,954,890,335,114,309,865,852,10,698,278,930,534,883,149,534,230,456,951,39,176,338,260,301,760,527,64,173,286,631,760,873,178,470,197,531,285,515,107,370,962,845,561,832,363,766,150,419,790,185,227,101,556,497,717,434,21,413,344,8,153,936,10,428,402,220,81,570,999,499,765,519,935,64,320,417,676,83,772,785,910,611,727,255,901,606,177,39,792,234,353,724,592,329,111,94,371,85,903,526,478,284,864,96,298,560,200,382,901,935,152,503,897,867,479,600,768,213,452,185,397,166,32,423,304,487,931,102,521,586,910,802,426,134,10,798,415,35,809,179,733,342,17,304,980,584,979,993,143,797,763,680,923,161,574,102,283,196,212,755,724,145,349,405,268,930,848,25,962,220,547,412,948,515,445,672,511,374,817,220,554,107,474,435,301,771,5,275,226,721,466,25,175,759,810,857,662,852,117,489,765,520,285,6,911,0,769,412,787,702,242,841,264,730,680,16,962,793,954,729,276,385,487,284,323,423,687", "224,24,436,219,576,67,256,493,202,54,642,562,479,441,902,139,742,303,377,933,229,971,931,330,684,548,562,181,750,487,463,772,944,157,66,162,995,790,920,367,433,707,197,674,715,332,493,21,522,611,321,941,918,748,394,83,860,923,220,951,881,7,386,491,213,347,563,624,275,347,811,366,681,328,389,671,253,269,350,600,675,337,582,780,510,287,800,442,285,391,90,124,797,760,439,883,943,177,778,900,444,273,211,361,673,295,817,767,418,439,138,4,551,708,243,158,101,70,299,293,133,173,360,335,565,602,155,994,288,912,879,363,122,284,992,98,888,457,372,487,389,513,919,542,540,538,587,789,161,156,605,39,650,490,107,955,963,14,318,543,31,975,742,891,706,460,729,638,443,453,908,273,346,509,658,73,710,781,284,692,767,548,748,836,984,517,399,230,561,367,917,667,588,682,397,531,157,407,206,636,469,252,514,334,905,823,339,924,837,290,750,261,140,323,139,775,609,196,505,798,626,484,643,984,305,423,583,434,865,389,113,135,359,680,10,512,370,553,108,126,104,671,197,529,193,267,5,207,712,476,866,214,767,627,793,577,886,579,446,685,179,22,751,295,498,424,19,941,350,407,666,31,772,760,240,973,181,560,359,502,375,862,305,778,550,150,116,21,912,522,989,639,110,395,691,431,740,317,271,879,761,311,741,248,379,96,803,75,689,332,987,146,540,649,991,766,544,254,341,272,922,895,580,342,81,784,917,377,565,782,532,286,53,685,927,421,354,380,540,995,661,63,398,742,913,3,762,642,746,306,265,856,352,251,576,35,49,728,302,531,740,588,970,280,198,647,75,516,679,311,916,659,686,337,318,855,338,282,5,806,931,468,85,551,576,364,700,856,307,459,419,729,391,624,950,764,511,526,80,134,918,689,423,649,658,604,179,449,526,748,312,471,210,1000,121,553,50,382,356,102,935,777,956,416,884,108,271,498,245,242,360,343,347,678,520,601,266,408,60,511,177,438,187,453,9,879,286,204,504,230,495,453,615,660,677,605,710,458,755,830,690,289,978,370,383,584,919,766,312,408,744,678,857,955,583,352,949,695,310,540,770,657,900,34,691,328,291,511,759,598,558,502,650,826,780,789,538,280,79,442,59,556,254,909,350,728,985,283,953,272,246,57,908,537,707,368,77,714,562,128,58,636,788,234,16,938,681,909,581,584,67,611,157,866,683,449,188,748,679,691,852,225,884,704,306,507,686,459,405,654,871,480,911,605,30,62,496,433,744,698,172,536,255,633,354,44,507,224,102,261,564,712,957,755,659,274,311,586,565,553,172,982,257,81,281,487,870,343,282,362,253,417,546,287,805,801,356,735,545,76,674,898,793,69,838,87,903,174,192,826,569,296,731,216,3,477,512,601,578,634,600,24,189,918,935,782,567,450,828,454,808,744,326,59,915,69,454,886,227,531,758,440,202,84,545,754,329,817,731,429,691,102,930,844,965,789,259,654,781,426,347,979,864,177,986,348,57,244,68,884,858,693,822,29,302,945,292,579,827,848,162,436,877,798,452,437,345,107,986,488,602,135,213,137,303,6,896,248,255,165,566,498,514,302,283,809,923,693,356,161,488,531,86,42,806,532,968,37,951,258,252,755,739,636,138,622,531,417,548,746,918,973,165,488,51,821,316,764,828,874,739,564,343,288,498,446,910,870,709,394,51,388,142,770,235,995,682,434,401,251,486,167,267,198,777,848,842,929,78,310,299,32,916,217,311,287,558,263,633,645,411,696,717,868,400,785,21,38,829,525,327,713,109,645,220,960,234,189,206,419,840,752,713,521,492,66,511,955,24,817,866,619,55,721,39,647,784,236,912,460,786,460,509,875,991,48,182,42,296,412,255,651,706,486,157,985,697,203,999,910,179,745,361,266,727,635,801,853,978,715,379,316,225,427,940,948,2,715,230,830,393,850,143,922,579,189,140,865,847,315,602,505,224,567,453,400,761,205,45,711,812,225,167,787,277,513,945,999,825,183,180,901,404,584,695,565,959,585,934,811,708,465,516,528,167,639,354,193,606,873,540,325,757,282,770,304,910,304,733,899,827,240,701,766,447,961,357,339,106,902,816,900,962,637,513,110,15,745,968,856,35,897,292,617,25,906,123,787,817,302,315,909,13,191,364,419,631,113,71,216,35,256,455,282,314,704,497,511,16,930,311,65,541,736,687,632,827,470,769,0,223,369,910,291,27,397,546,751,443,894,755,207,720,686,418,513,167,391,41,526", "956,534,14,78,113,423,629,191,326,808,60,654,753,314,950,221,465,668,319,838,568,693,572,478,39,872,566,5,297,667,641,16,571,260,639,989,976,493,516,260,769,451,636,374,72,649,244,820,152,629,45,339,941,905,700,59,992,325,116,154,536,435,111,863,17,344,686,745,400,83,398,323,22,491,506,719,440,227,54,965,878,914,939,722,397,932,943,203,322,124,436,68,926,881,266,22,914,125,246,967,820,188,914,386,939,588,352,541,23,457,346,286,900,622,154,883,329,189,709,125,417,430,519,133,673,195,501,304,202,408,23,414,710,449,840,212,687,120,396,513,706,25,519,965,997,250,609,631,13,10,235,438,214,886,776,604,930,869,45,80,592,180,685,533,872,606,643,263,634,777,142,685,650,753,419,423,966,413,86,668,872,601,653,131,113,161,393,187,802,970,546,679,151,193,351,804,148,551,940,712,919,429,161,560,541,663,549,436,389,458,87,988,472,292,175,984,119,587,986,922,642,971,123,350,807,22,424,112,88,708,358,394,62,686,95,402,420,576,974,241,348,43,524,173,232,841,471,2,815,89,306,142,906,155,361,29,416,783,502,129,337,917,91,185,14,452,903,5,686,930,940,993,939,438,941,901,806,512,309,241,674,859,994,320,550,820,615,125,89,671,338,356,953,785,516,720,566,295,874,96,663,735,462,249,677,494,66,688,510,594,421,307,312,41,605,46,330,757,707,294,686,397,601,827,539,955,798,792,641,1000,785,869,764,579,452,237,622,230,302,182,381,616,459,477,616,843,3,835,607,206,230,818,359,899,672,568,904,482,607,389,827,587,383,609,788,781,188,897,364,471,631,453,370,749,562,245,820,435,990,413,129,201,869,815,851,688,498,356,677,802,489,414,762,316,653,262,967,253,37,956,386,618,167,492,650,428,230,281,949,667,985,536,164,964,530,414,743,143,795,835,7,159,405,533,308,821,464,553,509,420,611,937,649,990,916,586,296,894,39,297,329,856,678,659,965,167,923,37,399,675,767,876,475,251,106,700,43,177,620,385,742,388,662,749,543,680,201,161,387,987,67,495,914,540,993,749,63,219,512,860,748,516,486,312,382,524,345,60,721,249,561,778,610,320,706,51,807,684,324,214,88,225,505,28,787,433,225,384,558,325,487,83,989,14,312,213,482,503,883,219,428,204,350,226,561,553,92,833,629,629,718,837,927,529,821,242,64,932,277,633,170,245,70,703,411,275,317,635,982,574,669,22,296,192,36,699,601,390,779,524,725,161,685,926,410,848,973,612,887,230,890,498,803,668,862,613,689,778,392,668,521,802,788,234,116,416,48,893,502,378,94,972,241,326,177,506,542,11,467,919,692,741,901,428,240,913,78,416,10,41,642,92,375,356,220,380,405,291,702,99,587,596,445,966,364,493,355,423,462,721,77,584,808,144,115,202,202,88,219,440,211,618,186,160,581,87,2,812,723,556,353,167,324,901,174,417,542,636,435,392,828,98,27,36,523,572,341,965,280,610,8,24,870,750,134,462,890,432,685,432,301,728,70,722,556,528,725,371,365,464,584,39,407,966,138,444,911,955,521,832,595,246,513,626,671,195,306,937,811,421,536,384,237,1000,773,741,284,91,375,940,981,363,829,2,855,886,45,501,395,865,407,824,17,772,246,313,34,415,516,95,795,713,652,150,20,673,805,320,446,356,154,900,842,123,464,835,574,673,229,398,546,577,704,436,423,355,87,740,495,183,48,988,998,554,139,23,680,827,206,760,787,375,479,617,364,736,864,683,822,838,275,171,661,190,784,724,952,615,584,916,143,66,883,397,104,645,29,450,905,290,203,419,452,112,499,38,140,28,272,156,13,916,796,346,947,772,457,634,835,728,107,676,173,616,451,798,461,755,402,536,813,58,605,68,988,647,920,229,549,522,670,796,923,97,357,984,553,984,279,714,256,837,717,683,915,701,321,784,120,607,934,491,697,545,278,58,934,253,283,589,852,73,201,64,483,752,648,44,239,609,427,125,371,974,66,325,577,291,310,961,926,517,992,40,23,182,474,829,667,763,369,555,81,915,930,993,981,50,432,895,975,761,221,513,634,944,637,725,268,223,743,501,536,808,201,379,726,137,239,431,413,43,591,876,475,500,90,277,948,313,221,827,63,43,408,822,16,274,117,982,644,681,450,943,629,765,348,954,126,107,465,878,616,900,692,158,571,921,412,223,0,11,106,319,863,161,775,405,781,283,333,210,917,515,426,643,518,150,101,714", "237,892,529,229,56,220,151,806,726,306,578,736,19,698,568,825,941,47,296,562,412,16,647,889,730,400,798,833,154,842,642,922,703,232,242,851,190,261,553,903,527,754,537,308,43,514,743,944,7,954,600,624,766,112,630,435,293,874,2,121,930,148,92,925,522,106,781,921,390,569,218,150,782,450,167,214,29,28,415,666,368,747,500,516,850,407,28,731,496,599,712,45,81,861,317,770,654,941,821,283,415,257,45,621,433,622,309,217,376,104,684,560,772,414,250,10,129,14,559,237,251,336,683,381,796,966,530,11,866,187,603,307,608,13,941,153,600,458,742,806,881,102,603,183,622,832,32,346,906,705,687,673,996,292,715,227,793,636,562,481,376,976,138,430,143,737,657,715,484,30,695,241,523,460,888,23,631,166,903,248,226,883,874,783,818,792,867,751,573,478,246,97,698,159,704,652,445,57,209,760,162,329,525,270,540,788,597,794,949,444,997,875,532,554,440,580,700,558,683,13,312,369,49,86,64,825,555,368,867,534,827,173,342,581,385,571,981,500,148,544,277,230,560,513,669,433,834,32,430,532,465,354,714,238,365,435,734,139,175,343,138,566,169,382,719,820,21,277,924,103,269,789,856,971,46,511,405,430,534,657,719,847,773,946,335,867,673,521,601,96,742,84,176,875,951,894,861,423,631,205,675,123,484,66,272,770,634,62,42,600,766,997,460,792,470,774,108,517,710,336,893,419,833,146,930,39,15,438,805,492,207,245,881,384,308,724,794,151,522,840,257,27,102,118,478,532,306,438,908,39,815,271,538,542,423,729,768,699,838,699,750,68,661,129,228,162,338,279,482,699,133,695,796,955,202,877,435,23,246,241,988,615,348,624,157,605,947,874,711,200,960,699,640,496,879,88,900,829,25,347,495,138,132,986,784,989,447,99,437,248,681,798,118,705,67,515,659,55,469,668,652,170,304,621,476,457,773,150,363,419,750,62,111,234,175,41,265,204,762,658,517,894,273,242,647,279,451,28,977,510,569,143,513,769,912,53,61,175,890,72,897,341,586,657,106,563,507,392,11,266,284,390,517,422,341,640,715,615,987,568,214,678,558,739,596,525,650,882,655,546,314,807,367,135,946,422,550,937,382,818,320,303,479,254,325,475,801,276,900,812,104,238,212,864,650,106,232,938,410,161,96,951,36,439,453,955,248,609,77,128,332,892,330,934,541,224,485,683,397,736,113,816,608,627,884,326,180,532,860,231,879,259,483,612,932,984,86,398,872,409,865,55,811,692,438,292,824,181,302,726,306,991,130,365,866,373,534,190,284,547,555,529,798,141,95,513,744,816,700,818,186,84,313,596,394,108,707,712,996,652,611,656,26,439,339,889,671,427,921,524,936,483,270,575,975,960,37,217,407,370,876,257,423,624,656,472,701,755,601,522,191,278,747,812,596,323,484,560,95,348,693,353,697,37,403,108,745,268,69,539,300,978,255,886,326,77,8,876,998,704,229,749,417,625,369,925,528,522,435,726,324,116,260,77,489,316,277,638,844,952,774,784,26,880,172,429,892,167,465,273,912,996,851,605,721,662,322,225,733,879,108,760,148,608,713,238,540,514,930,110,488,441,893,653,444,561,993,223,878,348,73,940,331,155,566,226,655,996,559,787,734,151,832,588,33,239,395,155,626,117,709,446,31,759,632,192,62,849,512,365,738,262,132,535,600,81,27,742,946,165,484,819,664,264,631,76,391,241,656,321,82,415,67,169,205,728,152,28,110,665,78,298,846,776,945,164,533,727,241,343,502,89,554,604,81,316,474,277,231,924,789,521,460,661,846,422,961,290,81,939,6,869,803,989,250,372,459,868,522,911,79,111,616,317,193,200,690,719,302,777,102,349,822,423,432,327,534,264,90,31,494,951,580,209,526,60,953,204,1000,988,43,326,301,83,296,361,991,478,711,327,542,864,312,480,454,865,366,321,784,342,792,138,121,472,423,945,353,197,826,387,226,501,491,988,938,103,260,553,252,92,89,146,340,282,752,862,181,330,452,198,746,946,257,295,381,536,928,757,341,660,374,202,787,839,341,842,476,977,950,174,372,564,886,638,153,508,197,283,759,565,200,267,425,451,718,646,234,227,949,579,3,1,797,351,624,306,979,539,843,322,465,136,484,945,396,889,376,266,880,718,605,60,287,718,866,556,53,267,201,420,738,344,425,501,122,224,193,855,787,369,11,0,670,759,75,864,741,907,611,700,991,537,68,769,174,659,974,422,769,853", "86,626,762,348,15,485,36,119,45,550,705,739,248,339,105,104,522,770,830,506,449,745,779,900,563,699,31,995,374,431,591,851,630,952,640,474,777,774,916,317,819,634,653,253,65,424,888,498,779,332,916,115,117,612,313,407,593,938,54,508,317,899,521,985,473,57,224,762,980,547,250,676,57,939,281,752,320,361,417,17,66,725,614,560,934,906,88,767,192,364,347,626,692,28,317,867,961,946,773,941,821,952,255,155,53,129,322,21,304,554,458,784,381,412,702,703,327,750,109,253,951,485,586,168,329,257,722,72,86,638,111,644,72,235,58,40,303,40,527,81,974,85,154,893,448,541,503,976,549,76,882,379,68,224,798,687,46,158,250,335,459,244,686,656,770,435,39,953,733,106,427,186,802,337,202,370,706,408,695,184,798,61,695,901,665,666,596,144,274,787,593,724,11,566,704,954,257,826,581,396,31,574,427,656,959,389,580,875,307,658,831,307,309,604,317,609,613,388,161,392,295,114,938,601,948,728,679,960,696,7,398,710,406,847,488,676,582,312,832,337,632,341,84,448,954,811,872,581,689,664,913,263,981,528,365,912,599,460,191,580,344,395,834,317,292,402,984,448,712,313,239,33,408,44,161,500,330,335,530,517,309,419,827,433,838,761,723,276,501,932,579,432,919,686,806,407,483,197,816,403,862,326,279,91,627,894,589,611,893,838,766,905,444,243,736,115,669,578,5,466,894,497,655,92,983,767,867,202,951,963,180,994,409,105,871,774,60,119,584,114,202,320,862,963,943,532,591,977,384,489,778,666,838,632,156,579,586,876,152,513,855,443,525,989,705,782,23,700,880,856,698,506,806,279,347,696,655,29,723,115,715,139,450,441,756,600,849,827,331,968,561,965,35,590,809,140,636,473,897,645,809,339,671,798,321,987,436,898,930,601,348,506,614,884,231,55,807,782,887,366,849,318,598,772,16,443,495,782,673,849,520,128,433,572,532,955,584,676,101,945,334,825,306,808,986,971,75,661,421,926,655,465,111,613,535,124,114,984,6,993,677,958,250,506,710,307,401,45,828,355,352,452,830,57,306,669,626,201,17,594,201,70,533,404,672,564,855,469,696,940,148,552,884,563,128,23,405,439,887,415,310,409,142,947,439,432,95,387,651,784,554,486,507,700,325,671,995,232,801,188,430,419,522,907,575,495,194,180,201,68,4,217,876,161,153,279,876,701,314,475,830,865,259,249,483,295,494,45,383,437,295,134,921,929,562,52,642,721,674,931,371,454,779,135,160,722,765,818,517,647,469,785,940,533,692,799,839,419,818,239,619,876,2,751,646,959,962,823,336,991,801,422,208,565,173,368,218,673,128,468,176,382,52,893,344,864,135,470,97,499,903,534,927,782,11,350,886,284,98,680,500,215,954,651,432,737,207,508,909,374,664,184,719,351,395,894,909,817,854,444,937,652,298,329,942,83,219,2,244,184,731,499,682,73,700,455,891,734,901,960,725,242,428,499,526,29,814,931,730,52,461,230,454,257,83,350,831,311,189,552,286,847,940,652,110,630,856,407,241,974,732,502,860,137,300,775,701,148,628,80,701,280,501,266,174,154,400,871,207,662,749,572,811,296,723,625,67,249,846,51,264,650,998,473,783,727,850,7,381,162,259,967,381,326,306,515,329,986,343,160,173,846,729,40,54,835,862,104,655,182,485,881,415,368,202,794,786,853,965,674,4,630,182,436,847,624,642,66,320,650,263,957,416,734,553,750,490,956,128,963,187,207,781,863,857,310,495,261,410,888,685,549,48,769,138,737,686,599,985,936,583,238,541,760,236,668,867,226,660,503,249,992,187,719,205,722,357,755,875,864,411,567,418,362,400,144,585,896,415,433,564,543,137,244,945,315,714,580,563,280,782,349,70,222,450,727,187,797,130,365,677,980,637,122,373,847,288,658,871,825,831,461,51,510,189,218,733,929,676,680,322,134,809,965,154,994,865,84,999,751,810,650,249,115,686,619,123,257,681,483,97,673,437,923,534,383,777,287,716,191,706,942,428,861,845,310,70,842,271,219,37,879,910,834,371,48,346,158,257,416,599,563,802,884,543,331,830,254,962,573,999,578,379,596,926,596,523,606,421,522,249,478,410,879,471,178,883,675,89,40,947,66,999,204,825,320,929,528,388,254,260,550,947,922,60,903,722,886,153,815,617,503,117,466,205,57,787,377,702,910,106,670,0,488,663,747,484,747,709,270,733,486,232,71,668,858,141,230,29,365", "648,618,746,141,400,699,31,118,190,691,41,978,616,19,707,518,417,83,846,802,525,623,564,231,97,948,373,657,558,552,980,405,802,60,844,304,264,830,379,302,727,224,361,974,399,719,469,370,96,602,199,899,635,957,336,229,435,876,465,769,579,795,615,83,770,16,901,168,118,372,250,896,922,729,959,916,731,387,823,341,27,272,884,829,3,351,638,395,182,641,857,370,800,110,633,307,859,730,129,943,929,308,335,633,546,568,773,436,192,974,756,349,594,381,275,325,725,229,881,905,24,443,929,297,104,16,598,963,585,531,444,491,156,999,317,282,195,456,808,66,803,906,155,141,758,59,353,925,476,729,103,669,296,119,850,889,679,747,539,292,563,534,614,388,567,492,833,432,338,929,134,408,894,385,746,741,325,269,217,561,477,924,561,49,327,236,510,707,834,195,409,480,368,329,723,773,161,662,674,290,997,194,174,914,45,954,700,889,674,25,400,730,615,871,445,825,80,91,99,754,589,274,77,489,640,887,659,504,369,686,474,900,312,389,687,31,973,47,55,803,477,185,394,433,940,739,465,431,623,637,364,974,581,414,164,193,67,893,963,359,417,690,422,744,819,696,232,431,499,9,350,830,665,700,687,774,775,932,829,210,917,952,348,816,221,422,889,678,603,921,801,556,53,81,218,561,719,481,161,249,39,683,189,53,201,934,555,847,491,699,887,536,28,430,862,277,977,914,586,760,116,206,886,65,408,412,261,917,173,458,954,773,15,935,943,901,683,498,251,821,444,354,350,179,276,205,473,370,30,334,889,462,101,619,295,877,665,92,599,585,183,61,44,168,477,893,806,569,68,319,585,439,77,223,661,988,789,680,719,812,607,424,703,639,49,199,87,332,470,509,980,90,15,274,289,628,318,655,173,642,766,271,81,231,548,148,405,79,96,84,380,460,774,384,392,203,426,321,158,228,761,372,219,761,139,959,580,256,496,863,181,245,392,180,774,689,947,476,143,627,713,853,786,763,851,55,154,226,78,483,69,508,553,298,825,318,852,709,486,324,160,865,419,583,20,616,483,384,194,106,321,967,860,625,73,796,721,295,255,216,684,638,201,652,428,53,118,670,162,779,477,364,674,989,461,615,4,647,391,31,653,841,827,605,462,557,203,142,310,797,445,315,232,479,831,406,591,132,194,390,691,97,689,903,184,384,604,272,744,530,327,677,350,816,45,626,866,301,738,895,407,150,84,694,426,592,478,590,395,167,722,909,62,134,286,867,46,74,178,650,449,148,827,867,642,985,470,633,245,124,333,439,636,672,936,947,306,419,512,198,659,321,112,337,387,915,323,118,141,955,415,155,681,791,667,711,502,528,708,764,169,199,793,575,401,476,857,223,693,112,549,465,942,473,505,165,131,469,265,387,288,530,317,281,124,600,983,896,247,466,323,377,931,512,109,904,484,547,319,341,905,833,828,641,737,142,232,641,563,941,775,789,997,822,897,670,284,837,43,514,896,769,553,895,476,856,48,329,692,957,351,139,912,385,180,347,268,585,482,17,69,649,913,330,747,746,593,361,892,776,316,510,639,198,935,90,570,263,338,736,387,302,529,664,844,358,797,941,796,747,14,520,329,163,889,209,813,883,753,756,643,177,540,904,903,867,765,364,81,884,511,701,210,894,993,596,954,954,84,31,389,661,41,825,206,814,220,118,956,127,370,209,881,864,181,238,242,539,341,382,245,686,756,766,475,900,862,495,144,964,6,586,178,298,363,627,589,59,105,518,670,924,46,467,781,866,424,262,19,865,372,43,69,287,296,741,970,527,75,719,156,147,793,451,806,957,454,281,612,808,506,306,681,974,150,758,252,282,196,408,473,60,515,271,76,63,823,339,733,455,377,935,252,835,919,850,851,115,241,51,928,622,425,554,741,279,898,986,499,917,336,936,457,679,105,773,726,663,161,524,602,574,340,660,916,304,814,719,970,335,26,254,424,413,206,768,692,905,691,351,966,43,286,756,375,228,660,827,973,667,229,841,470,303,638,513,443,833,630,127,373,641,187,19,729,686,317,409,566,793,410,772,905,411,864,474,901,697,669,737,263,176,764,201,457,283,897,903,423,561,937,680,979,785,872,933,856,389,236,646,398,12,27,985,529,232,985,179,940,91,961,610,458,76,673,388,566,951,278,884,638,258,421,270,120,475,313,686,206,696,475,200,472,389,766,817,277,289,242,291,319,759,488,0,914,623,107,709,539,283,723,509,416,629,760,565,360,936,719,181", "448,59,944,223,212,427,529,591,658,122,560,526,758,152,976,534,298,697,53,515,904,62,303,136,218,917,325,845,206,601,922,502,539,612,382,986,655,60,334,318,826,302,796,56,404,447,988,192,191,139,838,179,686,469,154,9,603,981,842,97,250,644,530,64,803,670,570,605,122,881,32,948,69,255,325,808,707,643,135,608,926,141,716,559,922,376,532,680,64,269,370,546,196,922,284,801,436,380,772,125,139,265,361,566,454,14,104,835,475,127,266,2,685,637,2,487,135,540,849,281,216,252,662,915,849,797,424,609,7,31,509,850,965,927,464,539,622,94,62,744,91,421,619,773,870,992,768,25,841,559,219,977,892,475,973,745,790,140,762,560,700,558,613,739,387,810,850,420,882,526,193,387,900,816,318,959,297,205,380,759,519,646,2,182,268,229,289,191,571,579,293,898,946,913,741,298,436,669,14,838,882,304,966,19,688,289,636,413,581,256,939,93,555,933,598,898,922,535,70,117,51,258,154,193,424,957,128,605,12,739,277,518,737,757,156,643,723,224,410,919,854,558,169,754,814,803,185,92,478,769,461,805,340,102,246,780,700,987,785,22,526,365,121,168,295,991,974,119,602,584,704,351,127,418,215,600,433,801,965,326,340,661,697,869,414,544,418,644,311,912,684,662,732,672,977,514,71,269,875,62,949,845,673,664,903,766,122,425,675,248,943,168,173,172,621,384,410,739,614,925,841,197,118,847,363,706,632,434,566,494,853,353,191,699,775,12,180,646,519,989,142,623,256,557,351,831,942,203,694,228,947,216,276,655,615,625,141,976,808,81,329,122,517,833,947,813,509,811,820,641,131,161,482,291,411,196,703,88,107,167,194,375,788,645,369,642,478,677,856,804,82,570,942,730,844,364,989,746,365,594,795,43,700,750,464,742,302,835,425,435,29,664,505,453,399,27,983,939,335,276,617,44,506,151,47,22,29,490,44,807,807,156,277,363,126,882,199,122,499,487,371,725,723,588,262,725,956,437,171,516,884,18,248,786,171,919,493,755,783,156,106,262,756,334,834,513,768,365,597,330,569,729,952,167,272,552,599,182,145,733,518,67,931,766,379,231,419,938,715,581,624,222,792,356,793,684,423,192,162,214,436,395,180,292,596,371,604,715,436,628,250,859,76,153,179,341,596,417,146,486,11,265,687,363,98,200,55,699,483,843,771,114,204,532,577,805,112,156,726,115,670,742,924,769,236,905,421,143,365,104,570,147,764,288,650,390,982,52,83,210,98,139,988,215,575,491,61,52,552,278,408,162,189,484,899,702,178,306,56,60,284,384,931,68,559,785,587,835,683,328,917,519,515,51,836,594,32,777,515,398,646,871,80,604,191,908,302,459,201,968,134,750,887,767,25,397,333,289,965,598,360,441,718,151,159,884,633,388,357,56,902,842,160,675,293,922,707,418,798,676,414,378,755,810,669,648,666,671,421,657,243,248,796,700,474,192,894,888,765,858,183,582,688,236,971,624,178,867,165,836,406,712,572,963,70,23,248,883,499,666,52,55,110,46,136,842,619,896,854,791,243,476,879,975,112,349,259,74,81,625,44,817,811,69,638,667,707,461,635,440,999,953,427,52,265,350,578,461,222,53,580,957,954,223,784,379,502,700,245,376,458,580,214,789,458,710,473,708,351,951,998,847,471,179,690,692,100,392,247,185,728,88,762,35,375,725,139,674,913,911,457,342,149,234,331,132,919,887,405,241,624,347,41,708,369,494,972,985,35,279,204,835,579,321,113,712,519,437,516,691,486,871,68,810,536,370,223,993,512,198,134,123,176,995,994,134,332,790,476,817,534,134,553,693,605,973,572,166,123,678,879,406,377,316,842,584,832,372,773,257,445,435,110,827,748,358,929,944,119,51,374,771,458,357,742,4,265,281,710,171,692,97,429,260,685,571,649,292,739,109,199,748,578,781,739,921,317,138,472,432,496,987,366,175,491,297,215,457,154,904,324,495,991,467,412,991,522,50,673,855,392,900,922,733,683,722,762,857,997,638,301,318,906,906,563,298,639,204,994,151,631,952,908,238,518,777,8,458,543,874,267,600,257,998,766,486,357,541,200,699,484,500,123,575,890,941,218,766,230,830,576,603,884,283,779,440,883,453,718,695,264,146,943,704,375,179,813,835,849,214,156,65,10,557,515,875,393,722,194,264,140,409,892,754,22,97,368,834,841,27,863,75,663,914,0,142,471,503,811,68,429,989,129,61,750,648,97,39,57,929", "10,640,873,37,935,752,864,153,609,143,54,481,112,925,93,59,714,787,514,512,313,357,10,995,512,61,492,565,425,768,764,940,529,590,898,525,748,787,157,912,754,356,225,568,226,257,976,352,695,566,964,894,460,613,119,426,655,268,240,795,923,755,961,279,376,204,316,64,473,36,148,250,821,381,412,393,545,638,696,927,973,477,77,608,952,89,761,774,673,443,751,560,815,631,295,503,917,190,576,860,158,876,669,229,693,89,274,816,751,381,141,946,60,418,820,343,272,605,351,93,735,177,252,135,579,299,159,633,16,768,867,149,656,145,6,894,588,679,324,78,487,813,153,276,120,936,909,820,509,31,770,125,556,450,480,239,832,811,437,301,772,464,420,614,669,772,528,952,880,301,24,915,191,900,40,278,684,165,65,314,694,982,95,676,684,644,986,972,267,525,465,347,191,605,431,546,459,133,863,256,341,240,6,862,556,466,13,919,285,235,685,326,149,7,9,900,298,351,801,726,720,590,288,198,174,246,704,740,681,4,435,937,95,333,760,59,613,495,864,797,869,433,158,16,343,486,376,514,844,526,190,633,475,293,436,281,949,243,198,556,89,917,949,271,239,680,323,903,788,963,418,439,872,132,411,42,989,856,307,334,410,378,327,247,759,769,131,999,139,61,353,431,406,890,153,357,682,437,297,337,38,769,865,418,735,97,659,24,861,932,510,681,518,246,45,678,435,824,6,235,29,264,145,496,707,112,766,484,491,435,829,812,836,311,855,197,673,992,244,620,961,853,400,306,318,371,58,621,387,466,393,805,866,407,33,764,333,878,494,90,280,234,161,951,224,193,153,618,144,347,680,589,601,848,263,792,7,464,963,181,857,851,573,216,218,729,397,369,165,254,37,691,31,530,573,834,697,697,945,379,548,700,691,801,685,617,447,908,313,851,940,120,328,804,958,452,380,507,187,534,491,852,955,301,616,777,703,211,822,387,572,112,40,373,976,309,979,741,171,669,676,252,801,287,554,268,375,131,498,207,704,690,716,421,707,331,131,327,476,649,733,166,928,889,621,205,897,126,891,114,510,19,997,225,512,445,987,157,898,12,71,934,804,716,155,732,870,632,690,554,171,777,720,14,164,277,105,899,937,845,76,253,675,849,603,688,703,831,238,435,490,583,959,30,275,760,310,187,217,380,466,281,396,56,395,143,379,758,82,420,218,223,163,327,574,39,910,986,596,542,398,29,282,32,503,587,906,824,933,875,865,464,95,627,277,672,834,776,704,787,232,786,766,43,322,276,77,927,780,80,979,778,134,636,296,644,622,448,404,290,598,815,196,621,529,746,786,551,5,142,32,959,215,710,815,88,9,571,557,646,910,820,499,198,737,133,66,787,242,605,663,29,706,246,339,928,513,41,475,386,911,363,318,597,165,752,267,138,972,414,565,574,871,596,452,957,449,990,292,161,872,162,389,362,937,435,65,520,204,891,510,733,750,474,183,347,174,590,23,645,984,628,811,208,226,590,862,155,834,539,866,329,716,675,383,568,225,799,13,502,259,547,988,289,187,359,489,477,767,290,737,244,48,198,210,519,407,70,521,213,322,841,643,162,216,271,953,119,945,343,454,64,380,573,304,537,783,119,348,229,552,113,690,500,961,235,441,579,743,633,656,846,651,264,399,31,109,197,659,323,991,463,456,79,759,711,126,641,344,540,762,753,2,553,317,867,596,908,127,747,228,626,544,299,736,231,635,370,160,973,986,415,346,973,309,704,916,349,402,861,92,515,579,840,794,33,617,357,328,894,36,454,916,974,799,151,772,632,366,338,456,15,764,870,657,333,611,798,632,455,397,492,312,288,213,571,48,276,749,727,374,387,169,397,26,366,599,241,576,326,726,432,656,903,172,159,448,859,885,761,443,45,409,796,68,700,231,819,442,664,459,726,247,119,227,301,615,450,194,833,3,657,163,373,319,151,445,808,428,203,778,643,908,377,476,277,268,289,709,308,250,279,986,653,666,465,620,896,313,23,688,977,570,180,346,673,436,256,556,57,63,974,838,674,776,50,376,400,498,463,94,474,254,365,885,368,531,839,522,114,909,68,877,726,221,478,260,381,20,747,380,711,332,590,422,831,899,424,677,984,768,250,723,133,333,500,223,647,522,560,414,790,617,178,676,705,571,248,501,217,377,368,61,156,955,440,123,671,712,813,902,283,717,564,814,44,261,497,264,397,161,864,747,623,142,0,899,597,609,345,990,957,803,177,97,286,390,316,144,502", "856,908,838,50,668,873,676,787,912,837,774,88,687,76,172,404,112,46,779,798,219,476,245,668,525,814,30,615,315,332,875,149,313,607,284,211,424,359,847,792,540,205,415,602,342,246,342,388,413,402,298,972,958,770,859,530,705,677,251,583,301,85,748,762,396,235,910,878,129,225,736,84,318,938,404,885,575,77,113,355,110,833,95,189,833,984,79,32,594,323,509,598,884,822,890,523,299,598,768,837,824,33,572,484,733,684,787,755,228,13,348,203,999,246,355,309,440,503,683,448,707,73,282,519,267,379,829,669,155,885,951,43,302,304,928,870,874,349,967,448,779,139,40,826,233,20,920,515,345,415,476,853,317,681,962,381,282,686,210,173,23,583,170,298,547,811,616,257,387,871,274,66,19,329,98,409,512,266,443,678,52,918,612,444,761,165,308,112,886,433,424,877,421,266,173,278,684,402,770,498,931,668,791,979,118,508,256,849,663,907,930,668,479,354,20,541,27,738,60,884,514,177,894,334,740,219,156,834,261,615,673,39,994,737,597,911,77,797,628,861,653,597,935,627,530,531,427,569,736,366,413,738,946,83,101,257,737,553,804,585,6,338,526,979,704,700,487,134,715,163,329,913,11,962,681,57,561,986,87,396,201,475,899,709,911,884,526,186,232,278,441,230,876,517,417,348,80,989,740,193,871,911,170,523,736,718,327,973,227,217,423,961,553,278,449,734,102,140,846,812,830,141,114,440,236,922,420,284,540,765,484,726,894,82,339,109,891,982,973,414,826,163,616,849,212,966,188,347,576,533,296,747,393,879,89,450,148,931,297,337,201,28,646,113,727,866,568,154,503,530,613,556,769,386,302,593,195,658,102,507,214,646,968,791,442,212,853,674,633,889,330,618,116,264,989,90,483,427,786,318,644,784,580,248,223,677,735,627,557,170,838,263,207,738,978,700,985,817,377,447,787,555,345,133,146,463,945,757,434,899,125,833,406,598,539,503,776,904,55,226,891,100,306,317,678,136,799,874,468,510,783,395,131,29,217,347,759,886,578,938,920,483,555,949,180,470,485,312,430,298,674,665,370,611,537,638,223,953,721,745,313,407,652,624,450,445,897,825,492,886,814,638,878,2,951,697,330,356,546,133,899,398,672,2,836,167,135,361,499,636,59,937,163,224,973,107,228,3,550,560,355,339,357,777,461,632,424,75,239,154,763,994,283,123,271,844,222,946,710,859,526,419,398,259,876,985,412,86,350,285,225,678,512,918,460,818,437,922,838,137,187,410,156,721,490,950,772,163,826,206,88,199,74,316,799,307,8,666,465,938,978,766,409,6,620,394,313,99,928,751,151,733,242,965,766,658,38,868,767,382,633,280,37,458,446,896,338,457,749,291,591,993,209,611,629,614,901,73,128,859,603,651,13,182,711,314,672,821,123,287,324,719,500,986,917,439,3,728,968,895,466,558,139,559,678,630,26,252,991,724,791,675,514,338,919,771,810,496,416,400,516,532,517,170,682,988,506,828,864,857,567,475,991,266,900,275,302,337,26,233,341,854,851,746,244,980,162,403,897,308,413,326,905,915,499,595,490,883,542,277,307,401,259,542,392,888,711,659,69,697,30,425,496,805,201,979,709,47,886,397,381,648,606,48,562,800,760,839,751,823,300,42,450,721,930,244,426,570,219,269,236,191,363,787,209,21,155,122,178,880,131,346,398,626,693,488,918,742,94,136,688,797,539,531,533,314,27,390,485,403,486,141,408,632,674,645,505,790,473,316,305,731,59,190,118,467,201,717,983,616,289,726,917,404,881,988,926,960,67,742,690,467,695,677,467,588,508,793,887,751,329,784,236,38,456,677,613,102,773,741,508,30,370,254,759,260,718,997,284,306,955,171,637,636,377,966,57,124,734,991,672,64,488,832,446,462,974,330,48,546,67,597,138,611,786,826,721,125,60,600,323,588,278,567,560,854,607,272,569,183,480,109,82,186,520,377,761,780,615,470,785,819,279,505,610,199,365,400,295,865,26,262,658,125,201,518,316,129,91,745,954,622,48,751,890,925,402,400,917,16,811,201,682,701,344,162,81,966,412,663,251,704,533,362,958,200,709,500,996,427,202,551,102,80,199,144,347,14,239,600,633,867,949,285,712,227,344,469,987,57,452,21,384,963,589,410,748,17,614,751,798,628,436,676,738,996,904,68,714,864,950,320,464,326,60,130,563,650,730,546,775,741,484,107,471,899,0,904,128,454,911,169,787,433,506,779,37,169,778,235", "196,996,795,312,332,174,620,944,157,306,940,493,903,681,471,795,508,735,353,349,650,133,904,843,915,222,338,398,817,27,968,252,635,646,968,353,83,121,783,338,50,159,27,79,146,252,508,78,562,164,784,122,237,972,628,51,541,83,866,799,296,2,826,551,559,654,753,523,214,173,887,158,765,939,267,341,532,770,223,583,193,505,623,920,903,657,873,253,319,787,51,426,522,424,722,830,117,337,701,263,873,793,287,735,236,321,782,485,434,440,154,239,772,502,291,500,32,604,585,289,639,365,33,640,232,830,45,884,649,871,635,75,663,414,483,331,676,100,995,837,465,729,305,796,960,641,187,898,549,111,170,250,326,397,90,642,810,912,907,506,497,953,397,624,318,423,461,583,400,676,277,387,414,295,68,844,966,883,133,322,973,87,275,431,619,605,644,147,251,347,344,769,631,787,209,307,536,632,125,239,981,98,542,972,349,879,912,339,620,545,201,102,140,35,779,187,90,522,700,926,860,784,529,455,666,278,987,392,269,401,617,167,669,695,572,275,412,72,217,132,644,981,777,608,603,244,415,232,13,678,296,445,339,629,991,511,10,644,559,989,730,699,356,592,935,219,912,106,590,932,419,696,917,741,123,746,242,31,991,62,613,469,582,532,723,450,735,767,280,511,141,54,895,241,187,589,387,346,428,144,379,845,985,182,816,550,279,858,468,658,935,349,850,835,735,466,110,41,286,18,62,442,772,339,478,621,499,835,56,731,182,405,763,711,626,123,255,730,395,23,248,816,179,953,57,289,315,282,657,8,612,256,541,692,457,172,82,917,640,408,654,554,737,91,724,169,91,771,396,412,996,27,129,128,581,272,714,868,421,969,774,614,96,282,423,309,58,189,879,722,86,336,188,663,831,161,994,780,12,78,708,308,263,225,198,475,56,82,440,682,505,794,102,926,151,806,92,350,431,184,593,918,761,257,514,377,644,35,255,90,824,37,365,715,958,865,387,524,915,663,336,53,461,310,840,600,383,739,384,49,152,879,637,585,521,497,575,212,673,258,463,834,592,328,33,493,849,420,297,731,21,111,891,451,955,280,287,864,355,344,696,3,655,130,30,789,526,655,797,783,679,396,675,253,282,567,983,858,102,678,232,954,521,779,2,859,283,874,603,730,589,667,575,944,12,526,334,499,215,146,568,886,193,674,462,962,460,760,583,298,873,785,472,944,485,875,514,34,630,562,293,147,221,294,57,473,375,629,312,764,473,105,736,364,947,501,603,821,641,576,250,25,235,559,234,859,415,357,633,184,954,311,127,607,576,608,427,458,171,98,957,166,949,711,617,918,312,599,258,492,677,39,297,680,603,880,869,253,843,198,630,445,654,179,259,693,658,10,339,617,739,212,462,123,829,872,845,651,80,774,637,315,591,820,148,379,796,597,622,544,885,310,270,871,543,602,688,471,60,764,200,959,163,136,33,406,746,979,796,912,819,178,117,550,200,228,536,62,404,690,820,798,42,998,389,269,62,540,533,875,646,116,116,903,571,201,358,960,724,958,683,855,423,942,418,677,51,911,726,283,510,8,829,929,292,959,207,608,998,932,567,312,539,356,503,758,901,33,419,157,172,798,666,836,939,53,986,241,171,244,641,410,582,128,855,718,908,791,691,783,438,357,48,485,578,984,312,541,536,581,494,69,389,862,286,529,845,968,291,79,160,17,475,358,947,247,73,12,781,535,16,152,663,958,466,359,465,862,490,446,146,868,935,742,816,978,59,734,756,22,382,781,457,786,340,635,912,817,70,796,817,186,792,275,995,83,275,65,515,728,719,110,100,121,299,745,684,551,106,537,369,426,971,245,952,954,525,295,506,111,577,64,622,634,442,746,549,78,409,587,461,11,625,649,319,392,248,971,261,945,703,748,235,351,38,811,303,163,311,631,184,284,99,734,927,481,625,78,488,821,127,24,434,36,488,784,783,984,804,451,996,644,123,279,195,547,648,674,690,925,615,615,724,795,58,167,738,668,311,135,646,95,505,246,368,6,704,740,111,454,692,225,384,4,389,270,238,436,29,563,36,559,312,970,453,227,287,95,349,714,290,532,41,726,382,284,320,859,871,839,625,123,749,795,516,279,592,540,492,421,896,620,977,84,208,446,891,712,645,446,867,551,995,315,349,420,510,639,827,343,502,459,472,960,859,764,241,664,722,368,772,333,302,200,767,792,178,269,680,751,405,907,747,709,503,597,904,0,718,144,522,929,562,966,848,984,858,268,945,317", "146,874,296,367,465,771,901,919,875,561,501,422,380,694,11,700,417,558,386,396,157,689,801,366,52,49,519,787,474,563,154,529,315,92,873,128,88,885,198,801,888,665,427,1,191,400,320,165,641,995,714,56,13,265,382,222,242,988,319,502,574,378,171,181,826,296,139,946,268,927,706,756,512,489,239,308,699,708,630,494,129,278,294,949,301,179,298,786,745,868,119,132,888,655,507,527,883,79,739,521,407,625,403,145,219,668,593,660,769,138,151,592,234,238,532,711,893,501,491,973,517,490,55,649,686,906,937,607,107,753,511,695,367,906,297,804,19,605,402,774,560,683,367,116,793,662,792,264,983,826,936,941,701,871,915,167,349,299,417,373,498,296,555,974,632,355,722,936,622,483,88,812,274,40,868,629,177,234,333,15,433,142,669,864,98,841,695,478,158,738,672,200,406,822,679,723,467,300,472,156,858,463,739,929,764,768,365,771,567,820,593,374,954,489,107,291,509,469,76,567,160,618,761,42,607,195,186,495,94,593,524,242,727,134,293,411,166,592,110,682,776,449,89,866,324,353,177,292,277,487,639,178,833,887,266,256,657,416,937,880,472,787,316,751,256,151,874,242,445,854,599,831,634,916,297,72,370,626,845,822,874,444,734,366,287,80,671,557,23,498,100,764,45,984,293,895,279,635,917,458,486,206,183,600,382,125,232,621,962,113,40,838,107,301,680,401,274,206,101,484,323,101,390,270,5,729,674,205,730,760,66,352,891,569,57,330,86,500,938,790,843,420,162,504,36,524,231,937,626,585,440,103,116,852,244,872,2,5,654,71,212,822,706,618,170,960,243,40,413,123,121,745,980,201,264,358,325,485,670,456,253,87,459,546,816,427,383,598,571,951,90,967,525,446,953,624,608,794,499,805,634,6,758,214,805,918,423,488,439,959,668,426,197,954,477,149,480,623,192,110,263,487,6,24,847,104,500,588,665,128,440,710,649,393,541,621,418,184,766,502,981,777,884,792,671,141,729,989,134,624,750,552,694,838,57,340,943,315,598,424,621,47,422,906,376,875,901,333,982,296,531,438,716,795,22,15,285,962,260,508,517,941,792,496,928,994,300,875,166,604,978,184,795,451,417,721,717,316,431,212,58,147,291,492,383,284,727,456,887,939,213,244,506,914,211,119,756,330,569,297,938,23,604,963,408,125,249,193,331,515,137,851,811,69,681,272,285,37,333,18,364,139,414,523,958,686,45,917,621,567,760,319,637,81,712,883,151,241,19,915,446,947,912,414,271,359,595,552,44,403,110,246,871,22,407,818,688,744,207,437,478,818,672,22,641,619,601,730,430,313,802,994,968,737,571,923,569,928,807,959,603,185,156,741,935,70,477,358,483,726,965,13,694,701,730,44,476,90,150,87,21,792,725,982,900,982,182,824,405,592,968,212,193,213,381,780,126,581,305,814,299,354,226,904,839,772,309,128,294,460,382,231,335,489,14,477,722,592,129,236,514,119,193,957,714,268,887,524,587,845,483,439,997,691,256,718,489,85,646,558,3,195,525,889,879,596,50,307,518,980,365,304,855,804,482,886,815,377,974,412,177,438,462,971,500,721,601,740,623,553,365,211,987,634,686,662,904,631,368,998,572,289,986,440,293,770,146,49,964,464,993,822,83,820,988,843,656,883,785,33,716,519,622,327,818,352,244,868,74,700,884,868,99,955,682,499,537,674,428,486,237,292,153,101,271,265,738,846,592,694,220,447,120,29,786,967,891,637,76,602,454,539,875,9,223,33,304,736,588,156,397,348,922,172,770,921,242,947,436,883,816,259,460,320,224,426,933,651,645,480,164,35,252,205,234,130,151,599,875,439,259,560,508,62,809,853,603,327,823,938,462,978,769,270,464,161,29,741,432,676,24,874,851,91,469,130,762,933,11,173,150,911,466,371,376,65,294,269,117,453,408,890,915,902,538,814,244,387,430,343,129,175,662,216,396,421,46,116,640,458,138,808,574,606,549,588,765,370,777,165,115,275,112,500,106,843,1,532,43,947,336,385,184,743,39,184,867,550,268,755,739,325,785,65,398,342,917,955,367,404,408,13,362,746,523,924,194,529,644,827,691,953,418,602,367,522,548,607,166,895,915,531,534,653,740,466,931,126,450,239,650,587,662,527,597,55,851,359,879,129,118,349,230,413,411,954,499,445,493,255,798,185,648,331,478,806,521,254,16,443,781,611,709,539,811,609,128,718,0,304,763,861,915,954,383,375,470,836,512,405", "484,212,199,307,78,921,788,638,272,793,457,604,224,119,477,100,523,492,707,9,426,824,291,931,172,558,296,288,999,642,768,402,969,752,260,824,690,237,322,523,21,688,97,5,576,820,339,133,722,963,418,12,529,308,539,367,659,484,340,649,979,423,625,998,487,48,65,351,496,483,327,297,959,880,990,43,665,176,48,709,797,963,410,826,83,763,573,974,933,972,7,29,964,381,820,548,969,845,284,993,613,639,528,515,684,732,797,591,14,211,777,757,718,508,425,34,385,340,383,341,251,791,226,129,593,41,957,139,687,345,950,758,865,409,66,63,303,838,441,836,46,250,181,910,213,534,794,325,880,222,341,51,786,304,536,672,896,197,201,692,548,748,789,718,752,272,605,938,588,183,262,510,551,683,30,741,202,742,87,558,62,258,189,715,402,498,37,615,212,530,299,552,923,206,8,159,577,666,621,286,880,813,394,168,161,755,262,118,118,617,525,810,339,886,482,543,315,501,452,603,174,518,609,888,502,133,3,674,917,661,549,760,897,402,396,326,171,228,415,355,962,576,60,767,40,424,365,122,92,610,824,966,625,910,349,144,349,832,950,1,308,202,985,38,107,794,406,58,472,924,440,879,914,822,570,34,33,857,481,306,552,818,711,238,913,240,334,831,933,682,89,128,153,515,809,264,60,14,179,763,993,600,210,405,523,42,359,956,327,412,125,15,310,462,405,731,404,185,485,778,892,612,581,974,307,725,992,239,34,992,38,319,82,749,824,734,602,152,271,416,937,700,808,776,22,828,808,350,52,949,246,850,304,644,846,1000,74,648,467,873,280,237,552,667,612,387,269,752,110,867,276,256,121,281,447,760,232,121,31,671,748,345,485,586,927,270,760,575,7,408,899,275,717,211,953,151,961,90,740,763,640,402,32,818,515,422,581,843,422,834,181,325,185,520,618,650,37,360,338,910,620,516,331,270,435,283,773,444,279,998,641,636,689,359,489,595,721,384,12,57,879,758,343,450,411,98,157,487,804,469,596,342,696,289,268,710,435,775,969,586,416,768,825,395,652,364,569,655,909,626,388,934,472,156,964,793,283,427,482,320,332,795,732,197,565,757,213,50,891,272,970,511,647,880,511,429,54,965,608,784,266,448,146,43,459,477,401,102,160,818,789,360,514,978,435,747,987,176,446,827,190,13,856,996,757,519,639,394,905,383,950,503,848,8,558,957,631,403,247,726,381,264,267,78,895,54,41,165,489,206,5,596,794,218,864,622,982,758,610,116,972,421,161,735,214,369,29,145,858,956,719,549,463,125,215,207,266,613,660,956,150,663,575,694,673,989,395,685,176,258,929,317,686,944,102,690,458,211,928,17,844,625,857,581,505,224,911,12,618,930,538,374,43,713,282,164,596,534,84,32,975,211,781,879,532,740,318,982,354,98,408,430,966,501,986,658,253,165,102,86,704,350,986,369,64,660,410,284,120,713,379,574,31,864,570,747,583,30,754,617,300,868,936,751,25,476,600,655,935,452,761,978,712,112,656,273,605,2,739,348,665,998,755,857,535,755,787,557,256,415,330,187,356,192,373,506,312,601,590,533,425,212,163,232,215,653,37,933,523,25,560,22,943,437,768,943,414,759,525,306,279,83,71,349,399,741,213,761,578,62,607,731,466,702,767,328,317,417,210,763,224,351,284,967,762,651,852,615,501,598,391,834,698,644,816,628,914,230,772,575,489,312,23,519,575,600,947,538,516,185,552,352,986,36,505,630,325,418,359,669,949,729,899,214,94,34,818,530,545,986,833,651,511,225,456,869,564,202,233,601,143,780,570,671,727,946,647,916,351,258,719,600,479,670,652,864,454,120,79,966,49,376,857,610,467,248,455,787,500,701,658,450,616,179,946,251,473,264,458,412,33,636,846,879,930,196,465,866,506,249,375,402,294,844,221,185,969,823,457,368,430,124,265,150,61,580,675,828,195,65,52,459,168,618,67,215,125,958,294,648,941,387,637,875,737,923,894,916,170,558,958,584,480,826,139,400,318,361,166,969,548,765,551,317,71,437,857,955,514,55,933,740,968,928,322,296,628,194,170,388,566,767,262,768,514,355,769,632,297,675,394,502,590,908,651,655,458,855,743,217,652,684,371,917,128,812,700,424,542,657,410,596,353,134,361,894,13,743,965,110,393,158,456,83,267,365,179,802,713,681,591,946,624,30,484,236,333,961,962,894,283,700,270,283,68,345,454,144,304,0,363,296,465,366,886,101,554,676,72,890", "229,342,149,885,957,89,450,579,354,838,773,806,259,340,810,803,684,267,798,485,416,227,723,664,689,944,755,659,375,996,925,960,182,103,105,599,645,91,847,585,935,517,866,141,723,497,746,590,642,961,892,778,652,295,161,306,976,289,869,530,576,68,692,724,239,912,389,922,179,158,766,762,256,586,953,745,550,944,252,579,170,962,148,644,601,572,172,664,901,288,37,414,181,806,479,42,457,250,32,607,741,40,449,117,964,723,420,843,641,228,765,290,602,963,258,248,690,581,54,705,447,55,553,400,370,483,302,171,377,638,564,487,495,180,893,403,485,742,103,58,710,605,146,628,949,930,312,725,141,748,618,311,955,838,911,520,130,131,969,294,776,47,477,669,808,856,894,191,684,846,401,386,608,684,73,960,370,525,235,882,157,520,741,599,884,625,57,128,549,83,200,492,653,720,539,332,903,49,105,389,488,233,496,792,808,848,608,816,638,980,904,692,619,746,586,84,488,535,918,630,380,608,424,7,129,79,607,124,313,717,112,92,432,228,703,487,918,623,124,548,853,857,252,718,610,11,705,677,336,306,350,766,123,338,492,903,169,746,274,464,620,558,932,821,597,943,289,29,833,780,944,697,275,829,834,562,116,427,924,432,437,183,849,821,629,904,931,63,948,301,413,187,115,503,691,640,291,896,435,755,649,494,152,791,495,827,639,660,874,130,114,536,257,305,76,456,446,966,138,739,257,664,271,617,537,98,999,635,559,725,329,216,628,300,599,371,237,302,619,921,340,917,318,681,917,803,399,726,987,873,629,999,449,144,948,993,43,15,239,339,514,186,403,5,838,143,785,923,951,899,470,764,446,941,460,872,796,545,805,941,87,20,106,825,683,38,597,581,784,285,122,80,310,645,16,812,515,961,75,846,194,124,173,753,709,656,241,757,365,777,131,254,451,687,904,511,828,231,8,546,558,268,183,367,766,569,743,589,26,601,511,235,7,341,514,388,73,230,6,987,363,363,283,290,775,714,709,656,785,108,175,756,871,413,604,795,113,614,422,463,608,333,784,84,914,450,85,102,994,398,794,806,578,992,722,575,110,798,712,60,990,102,985,572,50,491,388,982,986,952,500,765,681,781,924,784,208,603,71,646,117,184,167,968,35,420,55,898,464,165,487,177,559,838,663,145,124,112,222,533,231,696,830,959,51,148,414,685,71,531,238,134,265,786,293,953,40,993,548,669,546,679,427,468,517,882,157,228,479,47,912,946,206,904,383,340,344,540,972,464,331,344,161,317,232,635,947,795,132,836,781,250,928,255,522,541,11,411,844,968,243,42,95,745,421,68,647,458,904,227,593,842,482,86,652,972,449,238,275,176,658,939,330,24,189,154,710,832,981,859,542,545,150,968,767,905,664,900,427,351,986,763,941,27,127,858,559,901,676,408,834,932,225,190,368,593,395,159,301,559,309,247,843,594,751,485,347,46,878,241,801,587,698,935,319,939,19,442,624,248,372,963,226,81,435,705,717,829,628,379,463,792,24,691,584,431,391,910,914,645,428,661,250,680,677,793,961,122,740,461,658,123,777,526,887,353,955,570,280,309,656,661,37,920,590,268,779,845,946,27,279,470,781,264,424,376,901,514,420,67,162,280,936,165,15,970,751,327,644,361,59,310,472,320,753,956,51,973,624,824,826,472,264,234,65,752,189,288,794,230,13,737,130,566,673,253,58,172,98,443,367,251,229,788,959,972,498,613,220,921,658,515,615,65,879,162,885,201,620,631,337,394,77,586,66,17,2,648,330,927,211,845,935,927,17,953,640,238,894,957,795,994,944,39,714,163,538,893,698,55,833,530,842,381,518,315,270,478,136,519,727,321,45,512,359,163,989,440,249,347,246,235,182,239,777,960,496,319,503,967,748,954,558,687,687,203,393,512,363,823,833,138,440,469,571,16,803,848,92,563,761,877,364,486,399,386,647,368,963,212,560,342,558,205,134,434,357,555,779,512,448,659,363,784,911,17,292,583,344,540,972,457,786,946,644,826,506,608,683,610,183,625,289,956,975,710,957,89,367,224,876,805,845,332,648,604,308,381,264,161,857,611,288,224,399,378,826,911,481,936,436,115,973,987,793,172,1,181,250,918,211,265,372,923,445,727,291,230,763,455,243,432,604,539,883,613,90,640,867,572,429,69,269,408,63,571,723,294,113,209,712,887,426,333,563,901,90,6,793,755,333,991,733,723,429,990,911,522,763,363,0,329,820,653,851,673,292,869,264,19", "344,778,675,215,826,607,981,758,480,805,153,624,908,936,282,313,301,368,648,43,60,858,723,51,511,67,175,179,765,198,205,323,143,914,699,220,31,440,250,388,369,235,650,815,305,172,317,927,717,568,972,566,711,595,423,715,702,896,566,360,931,616,331,337,482,710,624,154,481,537,122,749,624,703,757,798,271,235,294,785,92,901,485,952,115,405,708,650,715,207,115,239,585,65,701,951,31,6,968,435,630,321,87,731,216,72,722,155,367,517,195,14,246,917,243,964,216,313,708,261,906,648,172,302,848,204,39,54,412,586,14,849,576,444,811,985,295,72,427,508,825,774,157,183,965,136,478,938,91,925,768,605,893,115,65,213,787,372,642,679,980,61,697,278,1000,37,482,22,226,11,788,113,226,980,320,27,744,89,775,104,681,547,65,188,883,345,244,749,437,904,385,154,565,121,859,411,837,231,526,471,24,392,637,537,417,844,771,746,935,9,451,517,492,455,753,979,503,347,79,582,846,614,332,359,617,48,262,746,94,833,932,865,342,549,746,605,160,991,133,48,737,738,754,669,48,769,734,887,404,662,688,260,951,80,712,187,235,418,364,260,670,96,42,883,709,446,25,305,716,711,334,442,683,812,212,905,421,421,363,745,282,448,589,7,230,589,103,982,765,908,962,67,688,556,420,118,963,10,305,467,862,247,169,996,118,636,838,512,141,211,413,485,724,451,637,836,363,162,276,213,1000,911,645,540,394,504,63,750,796,374,242,591,637,588,92,392,329,701,266,758,833,527,785,131,285,975,322,599,427,697,616,971,505,93,836,807,64,293,583,737,482,290,404,574,28,789,561,945,395,737,676,31,835,667,57,512,160,861,206,389,283,580,336,64,140,379,666,794,4,211,836,919,359,315,526,970,791,624,759,639,427,722,147,427,267,28,813,937,764,613,849,391,918,974,715,202,80,230,298,934,967,822,606,459,908,804,336,214,332,986,926,982,592,142,570,488,528,593,121,138,533,703,455,441,2,412,193,878,845,473,479,814,194,556,856,497,641,74,381,478,990,170,810,880,178,495,751,898,493,303,334,554,727,765,902,295,448,207,352,655,935,804,89,754,411,48,566,370,117,513,992,917,973,924,210,897,694,79,135,196,131,13,634,526,863,664,49,490,482,489,283,863,744,68,799,538,696,528,241,713,646,231,213,269,254,64,948,826,82,912,29,892,829,667,811,800,471,493,26,838,71,79,684,947,352,361,984,433,698,166,400,959,335,308,998,252,366,707,436,327,540,498,379,117,912,8,825,337,396,53,73,231,496,50,59,159,508,511,750,396,880,439,654,744,945,253,185,121,15,479,194,378,694,908,501,410,315,112,724,476,581,184,972,952,190,56,743,545,53,725,950,681,627,394,39,489,972,270,939,657,987,290,324,488,142,904,829,565,273,11,913,695,858,981,750,231,254,964,409,879,435,347,933,216,148,961,651,205,398,771,191,761,789,289,660,975,547,404,718,771,191,800,515,618,415,671,142,666,155,524,320,919,338,38,874,183,541,961,988,58,80,1,989,282,263,785,231,164,593,468,852,805,763,535,676,600,47,197,50,316,376,561,60,52,228,691,314,863,623,345,781,998,313,632,653,856,509,476,812,310,269,597,258,32,8,232,682,826,253,873,771,64,911,261,552,235,400,890,739,285,654,787,728,899,44,392,47,270,398,953,69,975,122,568,502,721,799,250,132,866,258,457,327,354,846,95,345,103,550,976,342,855,304,907,593,197,309,377,512,70,461,44,788,649,837,864,536,932,1000,97,245,961,401,589,101,343,667,419,289,366,678,195,845,992,713,502,967,29,528,632,419,56,361,858,188,446,861,251,351,377,148,748,336,171,29,231,402,966,797,905,143,819,411,760,172,942,369,272,147,384,691,289,387,578,417,583,26,130,905,27,921,778,250,673,135,101,436,853,339,463,711,799,363,18,342,522,76,577,586,906,570,380,899,798,551,549,953,587,318,509,504,744,155,329,766,846,312,195,496,498,957,573,797,76,262,420,600,809,923,232,513,177,901,984,61,541,406,403,569,494,359,479,927,651,71,755,99,189,322,280,916,951,192,279,290,780,161,351,815,962,357,459,7,107,392,770,880,222,248,845,398,849,397,859,490,176,831,195,113,94,625,377,895,431,329,992,511,231,356,473,67,619,720,647,161,65,680,136,604,280,786,322,910,70,160,124,132,272,954,207,210,537,486,509,989,957,169,929,861,296,329,0,733,760,213,714,470,259,629,120", "870,657,941,565,559,196,210,75,128,229,171,840,843,567,609,202,33,548,992,934,676,549,881,467,394,664,875,626,354,319,156,739,404,842,899,164,60,95,318,179,617,805,824,371,125,307,426,905,325,305,553,91,109,459,636,686,474,32,604,652,440,992,638,782,130,911,517,527,171,953,924,6,611,456,252,525,984,514,922,932,641,362,995,575,547,978,333,783,537,241,459,623,819,212,700,637,801,99,217,740,60,629,625,963,17,87,64,673,440,710,69,50,956,682,592,407,476,627,31,980,940,175,649,561,260,569,794,619,67,856,632,515,275,686,762,155,867,85,940,220,786,397,935,594,536,765,348,942,474,178,655,940,601,370,320,735,769,804,726,118,46,670,961,119,349,234,47,1000,939,915,851,103,648,129,637,71,352,386,710,594,542,865,301,517,53,265,774,530,420,565,708,422,779,30,780,143,421,14,320,249,157,103,690,975,112,796,132,139,318,221,844,256,122,204,60,376,860,514,175,537,662,603,638,284,883,426,487,239,359,601,657,205,44,990,259,528,474,389,10,842,124,194,590,609,318,308,53,454,709,373,425,34,728,922,907,909,947,167,414,336,280,860,494,437,730,98,543,802,60,274,662,662,694,242,198,942,473,218,296,429,764,345,603,363,479,154,200,285,807,72,733,938,55,946,607,503,677,128,480,152,335,519,181,707,523,306,395,989,586,273,572,210,266,924,170,807,793,718,114,504,482,808,195,789,200,516,625,468,780,5,464,274,358,906,6,255,602,606,218,467,689,456,271,305,567,35,262,355,439,599,276,42,833,989,404,400,105,998,996,845,560,139,635,1,878,826,282,109,161,507,272,499,824,989,815,198,729,739,336,484,686,631,940,260,323,42,839,202,440,886,542,480,253,278,158,206,782,245,502,678,273,44,648,11,76,387,279,798,155,904,985,418,991,413,735,211,679,458,277,435,541,874,582,735,374,509,438,403,29,531,339,42,809,46,812,39,795,895,156,824,499,530,471,53,292,547,935,258,666,220,816,772,136,197,844,416,520,567,613,15,696,339,321,638,398,321,183,572,630,232,737,561,988,937,461,830,941,113,830,582,378,852,379,121,598,230,493,928,503,121,844,479,569,788,919,987,495,412,256,924,487,349,429,571,212,896,486,139,486,657,780,142,890,644,557,444,855,993,768,701,943,171,934,913,697,200,199,358,8,116,806,42,311,685,684,126,861,740,658,365,983,833,26,587,60,221,892,140,912,662,49,652,103,628,972,576,545,265,159,627,617,728,527,829,628,428,374,4,111,807,391,695,917,913,698,688,953,274,108,841,681,596,373,244,668,348,275,830,214,881,868,855,46,589,338,114,768,654,109,237,177,973,860,70,437,672,816,33,484,290,891,775,881,507,785,559,112,473,540,695,494,541,107,137,761,574,105,856,134,342,424,85,858,154,197,283,739,961,662,648,701,700,774,338,49,107,716,33,42,636,180,406,397,576,938,812,486,743,590,254,636,627,787,749,103,133,665,333,728,397,464,728,155,315,723,270,182,678,759,635,886,153,750,903,613,751,271,554,474,898,701,207,850,396,726,41,524,38,983,896,269,285,128,177,372,729,884,445,10,9,427,171,161,447,150,481,729,891,716,773,872,355,728,742,648,166,679,763,609,689,6,923,750,315,47,412,659,233,627,258,555,600,430,772,311,661,341,520,705,410,664,830,981,266,182,262,89,572,131,320,868,602,438,855,541,625,891,61,712,963,312,509,511,960,506,780,108,493,282,934,919,672,947,913,854,68,477,247,684,636,61,768,550,922,360,193,649,848,255,713,838,587,177,282,355,276,643,679,527,584,218,89,963,988,662,223,469,199,622,937,602,375,381,647,790,588,676,955,924,817,441,225,399,849,650,357,889,284,121,747,592,588,894,154,396,510,610,180,486,173,558,621,502,26,653,117,65,132,728,256,678,423,191,404,926,642,331,975,730,972,506,743,871,183,959,784,258,940,860,709,638,489,54,641,854,272,751,325,951,539,373,786,136,80,880,977,62,475,528,608,394,665,912,124,732,485,649,605,271,911,839,439,660,894,747,602,349,628,942,38,691,467,987,722,942,796,625,940,211,282,393,67,903,910,75,335,476,517,634,257,165,828,670,869,252,788,558,702,779,434,750,911,562,409,841,361,661,176,542,562,207,871,170,283,711,359,264,347,92,463,654,200,141,727,308,863,569,188,729,720,917,68,232,416,129,803,787,562,915,465,820,733,0,536,220,501,595,482,893,939", "673,755,533,658,501,535,594,191,192,418,405,598,909,700,956,319,895,544,935,861,299,415,696,952,472,857,740,723,615,425,984,542,646,553,381,802,872,355,779,511,137,526,478,459,831,4,878,281,382,390,534,124,889,524,259,504,245,950,518,332,165,164,118,546,258,552,1,818,467,474,206,222,851,729,76,129,129,16,885,762,379,68,978,944,648,537,582,251,522,798,426,849,969,148,499,142,910,96,452,84,494,703,81,632,164,941,407,105,545,502,297,755,13,538,100,595,27,81,757,617,869,528,723,55,626,340,441,833,64,892,230,316,607,422,23,386,6,881,311,322,273,359,430,950,596,117,206,696,957,641,806,620,77,914,322,669,252,481,364,694,13,534,202,276,897,273,717,445,804,79,502,370,571,275,272,441,913,313,120,764,306,317,310,445,446,457,527,570,205,847,651,812,48,102,459,115,979,616,830,765,173,882,871,913,68,9,773,339,591,674,209,733,717,691,154,640,256,41,526,58,809,379,667,832,682,128,493,724,553,207,349,325,842,188,986,835,446,840,606,161,505,161,638,17,295,106,732,180,623,903,727,489,245,740,79,995,590,566,613,564,448,13,67,298,351,340,375,91,844,795,575,980,940,693,73,638,16,394,435,520,572,747,634,819,142,380,569,873,806,52,936,634,45,760,617,459,485,639,427,717,573,690,464,802,23,211,682,742,648,392,393,319,896,48,526,61,402,961,891,67,942,437,556,327,755,46,465,411,934,68,504,458,65,804,577,935,257,45,581,763,352,846,798,799,343,987,977,723,561,732,187,301,280,196,588,569,606,286,229,23,845,965,684,878,814,106,880,406,238,897,638,331,200,942,773,185,406,908,316,305,840,796,751,604,859,671,844,834,688,444,112,149,636,648,651,297,187,164,453,768,972,34,497,982,753,578,931,666,341,303,873,939,197,561,517,598,549,207,896,754,598,468,480,69,450,848,525,350,226,843,402,990,730,452,491,325,217,694,539,400,186,156,393,7,197,758,16,393,199,389,53,581,926,129,732,945,738,608,649,159,190,920,342,246,683,153,506,111,14,568,907,623,327,317,114,104,694,286,819,487,413,69,428,214,490,6,151,947,945,887,72,241,279,513,357,737,187,908,862,845,146,889,415,432,260,371,861,415,625,446,87,24,488,528,747,278,953,836,599,393,609,448,208,659,698,114,648,192,182,247,661,737,415,251,185,450,948,552,759,447,594,500,675,705,571,645,45,304,897,851,713,990,401,688,818,499,185,863,13,345,191,648,76,208,917,756,339,300,549,661,661,495,110,952,545,833,220,65,635,423,90,89,257,442,955,674,767,573,549,773,712,692,879,224,204,500,924,312,255,550,411,922,570,224,636,774,227,914,373,684,199,779,817,369,28,72,688,837,752,963,910,238,923,31,730,615,407,509,592,508,439,172,887,623,500,287,787,37,471,344,460,832,56,313,305,818,431,55,873,59,920,891,210,888,728,387,279,78,563,869,176,966,472,889,865,704,380,963,429,381,226,379,134,302,448,505,445,828,881,458,454,875,502,229,956,652,711,912,564,208,456,927,941,607,730,244,601,323,716,403,535,272,830,669,38,691,493,909,672,342,112,264,803,938,938,200,331,410,445,401,609,65,431,682,134,868,875,719,381,884,551,10,554,861,275,846,481,355,854,724,400,394,415,46,827,520,754,676,835,101,707,593,814,723,353,464,3,614,92,120,364,855,633,248,320,765,320,667,548,935,296,253,674,429,380,361,281,921,336,138,8,299,967,673,839,607,264,84,147,592,75,462,524,892,991,916,726,911,27,342,799,224,968,732,304,168,846,752,535,306,647,619,65,993,55,63,406,822,464,793,51,265,606,994,663,981,655,374,267,309,773,209,15,59,7,590,934,429,956,55,293,106,566,729,504,19,744,77,293,993,428,290,408,505,37,986,895,943,909,275,572,303,529,154,793,184,241,575,594,863,702,49,319,852,854,975,551,392,78,484,273,286,670,83,777,406,984,845,51,173,435,797,552,563,815,776,267,386,523,440,294,78,145,785,277,471,870,234,209,527,835,521,492,808,560,727,896,869,982,811,351,659,376,652,145,372,915,152,631,300,799,712,239,593,44,350,510,225,981,253,642,942,226,995,671,84,138,954,133,862,762,907,502,828,35,635,40,405,407,826,263,964,595,697,205,426,978,618,180,182,646,327,160,161,904,392,839,305,276,686,515,769,71,629,61,177,433,966,954,366,653,760,536,0,306,869,543,70,739,138", "738,777,422,738,195,191,198,543,279,373,94,59,500,346,414,137,529,755,59,212,313,53,138,259,79,71,570,142,824,99,474,466,542,30,407,441,996,215,257,281,359,420,142,23,447,326,748,352,535,22,845,87,90,763,143,997,62,867,645,788,448,721,382,13,219,522,597,35,601,900,223,15,117,521,662,740,929,788,418,496,710,172,348,710,636,329,774,183,729,276,214,755,886,295,327,547,621,867,519,949,246,280,78,471,251,215,46,984,185,925,46,354,679,883,914,344,958,402,788,421,300,198,993,886,753,654,613,919,959,307,533,462,902,157,829,563,973,894,188,498,223,51,691,864,257,984,732,580,905,999,835,868,694,629,574,96,129,213,89,981,929,304,250,637,705,467,821,975,635,793,581,775,535,306,167,152,401,918,882,695,150,87,618,580,271,573,825,518,600,161,165,395,637,937,187,588,500,439,298,451,903,883,910,43,860,291,224,54,340,388,477,339,645,242,221,561,662,102,622,33,116,605,108,80,987,71,718,524,58,399,946,348,508,744,866,233,787,1,824,183,63,878,586,991,831,125,914,720,860,158,826,310,296,691,301,217,967,435,750,744,148,902,783,452,690,531,267,265,474,392,104,707,141,696,653,265,884,346,703,295,586,595,216,218,538,739,877,70,162,663,839,692,409,689,75,799,41,495,660,45,907,288,607,58,194,716,636,192,354,132,922,250,319,590,4,119,971,652,752,646,308,820,376,118,563,817,698,340,66,717,484,385,551,55,364,502,436,845,967,949,228,653,963,267,430,393,388,235,881,633,312,873,633,713,112,201,242,642,514,257,300,853,996,436,695,105,392,456,973,953,492,882,925,718,336,737,47,574,924,449,888,237,368,133,853,493,773,589,220,803,950,653,782,781,827,43,4,843,210,706,49,213,394,964,73,16,681,708,279,58,80,638,780,128,926,873,984,492,47,724,934,140,306,632,767,658,375,810,764,268,63,918,283,911,60,489,176,720,909,146,892,731,63,630,350,627,529,360,639,633,838,427,342,372,867,114,666,592,993,738,905,183,409,850,326,720,944,233,7,250,266,945,267,690,830,566,302,997,418,518,411,795,423,941,75,235,518,342,813,719,504,863,717,661,318,43,351,175,225,922,423,329,48,311,61,786,756,362,813,779,114,621,28,727,384,670,561,445,983,358,597,191,543,163,814,603,641,79,199,565,413,986,913,243,983,117,381,562,235,647,788,986,277,651,307,14,966,693,912,38,811,244,647,61,85,959,688,133,319,404,73,949,19,729,695,427,531,770,455,701,732,362,473,357,834,139,219,791,558,262,531,601,186,80,939,455,478,169,712,900,112,748,122,161,353,461,831,986,119,798,801,309,100,244,716,365,421,611,456,821,481,237,883,195,978,164,747,772,703,134,266,757,129,427,325,938,934,751,951,257,340,623,718,11,791,423,850,890,656,872,985,225,940,13,367,113,419,445,221,950,864,82,98,724,214,543,787,279,486,764,919,504,258,154,764,339,630,286,645,342,138,453,818,390,71,394,816,915,993,11,517,181,272,636,271,322,700,705,746,830,154,411,995,394,858,629,106,224,365,190,978,876,587,241,981,484,410,55,918,287,156,848,187,102,571,9,459,201,76,284,580,758,502,416,660,639,36,545,299,178,854,427,989,67,807,846,814,2,388,840,684,340,307,11,530,996,513,133,736,389,879,168,45,382,602,698,588,194,601,619,316,428,467,84,617,599,76,873,172,798,10,202,229,313,557,203,901,360,935,704,107,427,937,964,669,329,958,918,648,793,850,111,247,753,655,581,247,259,443,934,61,8,821,527,496,554,491,185,218,308,548,133,158,485,525,90,319,186,833,925,137,680,590,537,863,433,433,981,437,712,6,94,209,415,51,524,449,416,4,129,600,270,846,194,292,299,840,808,377,204,707,573,21,937,358,538,638,149,515,509,383,847,397,48,80,138,24,297,120,817,333,499,103,545,487,939,136,757,83,997,52,974,86,852,22,920,874,674,999,79,230,946,856,115,753,252,76,653,907,788,31,409,652,284,301,439,421,419,271,642,423,502,968,126,78,995,619,960,437,421,129,62,40,551,113,491,843,774,988,605,922,703,369,222,370,800,271,553,818,342,396,727,765,260,819,759,704,35,338,178,565,173,631,926,897,747,311,730,959,674,740,997,793,472,681,213,314,369,444,539,340,169,729,334,699,28,250,186,385,418,426,174,668,760,750,97,506,848,383,886,851,213,220,306,0,594,607,823,46,234", "250,470,227,191,588,89,834,926,878,295,105,286,311,353,349,796,570,250,847,148,317,366,632,852,412,722,945,972,510,541,227,972,102,317,947,142,250,188,342,220,14,151,20,997,465,542,885,941,137,101,378,84,635,790,62,869,741,743,344,288,186,948,20,190,554,873,717,245,586,998,285,945,667,705,93,784,83,722,517,416,469,393,839,98,431,186,767,250,226,420,880,47,101,936,131,309,778,419,293,421,543,934,230,778,934,638,70,103,444,879,369,151,898,307,331,370,450,307,391,324,23,644,404,937,959,779,101,215,49,487,296,629,172,185,197,129,293,449,901,919,33,880,574,552,118,150,7,265,711,93,59,941,353,387,950,269,389,943,656,182,698,124,904,112,601,927,83,866,577,679,831,163,374,228,891,63,274,211,332,786,401,157,81,181,338,444,458,3,743,147,392,638,777,959,398,537,864,42,568,222,175,279,246,476,543,955,887,859,979,699,109,845,189,659,72,716,698,367,743,614,312,914,685,404,755,958,108,144,828,76,237,369,429,855,901,365,977,491,759,485,71,572,325,341,624,401,466,750,549,910,309,971,766,507,841,937,514,730,26,856,607,649,397,474,557,470,925,2,309,277,364,633,827,95,269,732,502,650,209,463,771,111,134,533,955,614,787,805,464,690,701,16,646,931,32,333,464,277,168,518,299,727,177,592,940,566,527,333,274,715,350,770,206,162,495,820,894,842,455,904,111,114,529,692,635,236,761,25,229,152,189,585,512,249,382,865,117,826,744,801,438,349,164,942,421,932,163,329,970,108,412,428,467,397,953,664,78,747,831,983,713,476,736,73,329,821,113,232,676,721,552,326,459,187,517,833,952,896,900,460,908,561,538,650,817,210,7,948,379,567,274,719,897,566,103,138,571,845,407,292,497,588,115,77,15,302,895,856,85,679,371,308,286,999,595,513,406,465,259,56,955,101,780,49,603,587,777,313,247,22,669,845,198,701,318,940,439,987,573,633,23,957,240,96,207,618,701,603,671,437,334,314,672,898,606,662,782,183,676,769,492,386,561,836,777,286,377,562,135,498,709,770,555,398,476,32,765,93,675,604,165,657,184,741,862,385,794,548,198,417,537,619,917,525,353,477,386,167,207,541,84,33,164,945,338,71,702,193,501,545,201,473,893,809,918,600,952,854,573,845,102,38,772,912,428,129,469,364,394,332,407,775,229,252,177,759,542,21,894,600,906,705,460,791,474,372,572,770,846,284,563,119,146,750,609,98,410,653,564,117,547,92,353,158,336,623,456,816,527,861,339,534,267,904,256,747,95,939,469,984,20,426,581,745,791,927,928,458,630,252,184,194,965,891,588,538,36,833,159,179,163,286,606,440,81,933,556,994,523,261,986,101,551,94,166,915,385,179,245,119,234,877,803,994,881,955,587,773,195,958,296,192,404,28,397,224,368,644,183,915,614,787,627,462,732,800,131,428,681,2,649,395,942,635,235,240,237,71,373,745,421,694,489,757,441,668,677,548,993,862,455,879,891,464,820,324,830,332,712,675,364,682,591,5,736,335,986,3,497,705,272,954,568,928,667,443,250,218,2,251,219,717,495,612,966,183,782,555,867,687,170,119,269,638,388,283,863,604,852,887,811,622,901,28,660,758,312,555,969,192,903,187,623,648,663,3,116,189,303,952,640,987,746,614,866,934,356,965,253,83,991,363,577,51,181,988,780,524,768,252,995,393,394,18,100,843,762,323,103,424,510,92,198,6,787,934,34,141,488,76,684,414,767,458,515,547,784,508,438,955,230,491,468,974,811,20,723,349,11,80,323,82,616,855,85,781,769,682,991,207,516,869,230,899,892,510,339,22,460,72,690,150,225,154,129,207,473,58,968,151,869,429,312,242,468,332,338,712,614,515,191,84,380,983,338,126,646,272,301,700,188,213,146,506,354,419,231,920,829,291,863,169,91,888,999,879,992,623,463,125,234,517,302,472,346,918,564,964,868,726,95,535,200,235,274,227,995,667,302,687,300,75,72,302,333,286,225,838,276,822,34,79,872,186,265,200,984,613,90,181,372,326,93,890,805,98,304,977,738,834,549,808,474,67,136,532,997,61,86,613,675,714,768,188,116,99,169,245,520,647,588,353,292,290,321,186,144,440,268,570,387,352,722,627,443,150,878,10,455,920,93,52,295,5,766,98,482,785,986,411,350,806,853,636,734,663,251,352,487,513,643,659,858,565,648,286,779,984,375,101,673,714,501,869,594,0,718,226,115,140", "949,233,581,136,558,761,984,692,552,501,113,889,890,938,545,278,443,44,425,11,400,208,795,559,556,894,753,722,200,396,499,390,929,756,739,826,984,750,915,154,45,476,675,387,811,846,942,920,924,101,960,738,992,218,791,336,734,280,942,468,299,766,923,272,335,872,207,232,131,86,177,61,676,756,88,202,904,14,638,775,216,815,956,995,444,896,28,593,416,727,506,929,569,239,509,22,316,324,490,533,941,70,24,996,798,835,913,329,61,271,527,147,180,925,358,711,81,619,444,362,163,139,353,925,634,237,730,135,509,612,86,269,794,684,138,753,514,937,161,716,171,627,145,124,767,282,629,449,276,524,665,65,866,47,953,512,761,384,272,511,744,491,66,400,857,366,981,58,643,401,595,188,530,273,380,603,716,651,15,106,81,365,559,667,912,38,738,605,559,16,360,207,421,314,222,673,31,507,173,483,215,203,398,516,220,68,389,557,768,884,623,203,627,963,188,294,230,866,768,170,326,277,197,813,845,36,588,138,978,874,913,810,544,669,617,746,392,227,860,514,395,264,606,260,416,184,565,23,649,606,474,293,407,568,151,577,58,463,818,547,623,140,493,535,978,619,966,269,831,173,712,62,794,537,590,981,904,529,452,711,641,273,200,565,681,379,736,532,38,515,958,934,116,925,851,500,600,614,147,817,846,215,381,149,471,119,230,832,282,398,315,626,913,964,633,732,166,155,932,449,774,294,900,265,423,541,204,50,465,554,581,210,928,754,766,488,241,977,401,655,488,342,473,371,751,767,711,367,15,181,276,501,411,597,864,874,883,126,652,39,353,947,586,65,945,22,668,199,600,899,517,999,860,720,71,917,614,864,863,325,886,223,529,70,302,86,356,749,943,940,864,682,756,710,122,15,685,740,489,418,331,505,386,246,682,439,365,950,536,877,457,885,830,528,872,128,738,716,340,644,350,954,811,480,165,9,371,304,193,398,318,460,351,750,739,898,535,852,706,226,946,336,764,975,941,505,757,14,75,625,613,664,67,562,961,430,189,321,207,46,796,511,668,912,281,1,874,126,966,512,780,728,722,761,812,263,860,846,551,733,217,624,734,640,194,647,24,500,523,972,19,165,22,961,711,667,670,631,173,154,343,782,384,531,912,525,55,903,24,158,8,769,158,560,595,948,992,302,571,697,732,637,197,514,66,578,551,751,67,389,457,913,458,542,740,720,682,156,677,571,888,512,558,186,972,644,481,651,750,977,897,216,496,557,50,91,736,661,333,291,455,42,151,5,413,412,108,813,706,957,113,568,217,683,339,634,656,78,299,678,155,943,575,882,120,194,464,24,931,90,11,857,137,18,487,617,116,670,474,766,266,642,171,132,196,155,536,559,973,128,421,756,586,426,588,118,102,811,326,750,586,888,830,152,592,949,144,24,557,868,274,79,810,101,841,398,173,909,387,448,503,725,749,520,426,952,667,853,18,415,894,222,577,291,136,433,42,701,963,72,532,201,836,165,652,323,391,854,959,887,667,145,522,132,739,804,359,90,531,791,825,772,101,254,274,876,876,228,507,502,336,377,501,189,605,252,405,70,423,80,805,529,511,94,345,488,160,454,104,328,592,149,499,16,500,913,269,527,609,33,258,184,508,384,497,748,35,397,125,771,585,131,322,326,546,263,462,345,278,469,503,964,191,628,391,957,459,389,956,204,328,107,394,700,157,356,291,953,154,385,397,977,33,193,348,162,599,853,679,976,645,534,656,853,708,41,177,22,527,634,729,265,940,492,262,305,215,26,786,232,886,766,311,956,782,3,541,500,639,953,663,440,129,316,529,553,870,432,904,706,952,185,550,281,978,247,379,38,330,754,131,705,348,553,723,131,316,694,664,402,973,399,386,74,105,326,986,657,773,627,916,186,941,77,867,946,876,277,486,584,951,609,999,908,231,593,344,266,300,408,623,250,839,584,98,382,394,805,58,530,942,714,19,64,659,781,699,519,214,187,149,423,198,858,812,791,14,398,122,311,196,491,975,218,334,952,983,123,261,682,242,918,509,560,447,197,872,993,93,539,201,145,991,138,184,590,262,211,543,584,114,559,492,399,586,669,950,118,33,874,807,66,937,997,291,271,83,831,620,472,571,249,304,586,289,231,858,442,189,96,150,755,662,552,315,711,987,952,182,917,826,308,1,259,467,620,348,751,895,487,735,171,818,815,350,484,119,162,284,167,518,974,141,360,97,390,37,858,470,554,292,470,595,543,607,718,0,111,148,996", "264,547,470,994,952,182,953,111,249,346,50,744,142,415,824,7,314,258,998,943,54,865,664,243,623,213,250,844,475,347,518,668,488,635,102,696,757,537,995,887,687,415,715,259,474,547,9,953,388,970,213,30,279,177,574,152,255,501,898,55,796,82,53,163,355,22,795,514,661,537,48,403,583,234,720,348,402,869,343,81,279,604,911,848,89,999,996,112,218,40,711,800,8,533,268,649,313,229,520,160,914,448,983,454,947,191,611,54,193,378,32,256,498,193,893,945,200,289,98,307,74,141,583,483,925,978,311,473,959,530,404,970,237,456,835,201,826,919,551,890,168,461,932,877,700,832,111,917,351,509,136,950,205,564,284,101,787,308,782,166,115,134,48,570,838,544,42,831,983,525,201,678,385,599,755,155,859,179,792,437,348,816,561,885,412,907,799,538,621,294,298,456,253,486,332,942,885,736,304,438,492,602,639,682,147,672,253,428,529,987,334,807,543,657,413,938,142,543,934,805,708,983,6,52,532,867,198,506,817,813,378,542,626,914,30,563,644,454,290,535,687,480,7,588,510,197,999,185,731,210,2,565,251,509,923,923,992,919,679,448,650,136,492,868,493,351,477,11,704,676,637,140,758,856,888,880,669,63,224,39,411,507,314,517,346,921,542,953,732,262,825,524,301,2,713,801,76,841,347,17,831,62,921,950,151,557,476,401,590,59,566,446,489,327,386,103,531,976,817,21,819,519,784,311,678,536,79,250,628,171,43,838,461,889,161,147,714,685,410,720,826,360,776,963,653,796,466,295,365,997,585,180,712,547,455,419,200,838,26,89,515,416,370,574,583,764,580,157,337,771,877,360,579,381,451,868,715,255,940,641,110,935,23,726,393,850,342,893,148,399,657,235,774,685,899,491,103,992,792,272,872,626,598,403,685,295,234,591,32,890,283,734,586,779,242,660,630,87,32,188,961,85,954,898,525,86,177,455,663,976,641,219,465,985,989,452,948,670,654,657,159,962,37,704,933,381,938,188,236,878,280,568,911,184,976,625,603,511,526,756,136,842,545,720,938,952,226,135,51,256,316,245,96,313,243,438,849,172,517,203,229,487,320,179,494,978,248,85,329,486,601,30,49,811,356,617,138,850,622,287,108,574,554,709,990,61,392,388,702,990,19,551,51,623,953,990,430,253,50,752,527,946,175,957,804,840,859,600,634,555,364,154,398,980,512,81,360,216,311,560,26,458,626,957,948,594,356,954,591,268,92,242,39,987,270,886,516,388,266,552,600,749,611,943,109,97,76,806,91,515,897,354,108,315,416,472,671,411,127,354,106,777,992,495,875,674,617,507,620,818,608,323,436,97,926,839,25,831,185,843,150,909,415,342,33,23,856,23,972,127,981,916,441,286,488,93,862,155,843,795,640,530,271,96,513,73,680,839,16,543,611,816,424,450,941,558,909,872,725,654,299,647,644,484,24,20,628,462,226,130,937,868,982,452,789,156,231,907,701,63,241,387,353,860,520,831,779,487,242,67,789,710,976,204,353,821,960,181,114,478,224,138,155,469,547,948,261,878,973,10,475,437,418,424,144,674,635,196,268,376,456,370,727,652,931,997,450,371,496,180,664,105,854,462,407,561,86,110,320,772,27,197,386,75,880,958,136,475,331,401,816,877,690,293,252,28,987,113,273,66,53,947,120,440,211,813,265,714,775,347,720,781,745,929,950,43,148,558,481,60,598,517,667,940,594,283,11,185,587,876,289,175,940,349,833,673,462,655,276,706,428,898,832,563,350,12,680,865,168,135,195,242,13,389,101,50,799,684,537,76,159,922,859,928,407,737,774,847,143,118,293,48,965,977,443,525,370,48,594,795,640,511,539,464,281,47,654,745,876,7,162,991,306,458,180,5,884,518,892,56,166,328,166,438,844,311,724,747,403,216,651,111,82,975,291,110,854,271,145,995,545,471,804,228,125,11,592,244,343,949,253,745,50,89,65,675,323,729,430,90,648,396,835,389,740,741,444,117,596,110,634,625,445,693,564,134,806,505,79,684,39,167,560,680,739,545,259,942,56,392,347,931,862,239,492,496,869,502,780,269,220,588,744,797,245,629,44,616,580,485,550,636,93,617,929,925,990,537,393,124,505,898,418,90,233,988,816,38,79,884,746,68,688,239,3,22,263,464,971,744,630,776,916,336,932,263,634,442,747,106,603,308,732,36,895,443,773,957,323,391,150,422,230,936,39,316,169,268,836,676,869,259,482,70,823,226,111,0,125,756", "995,913,328,706,887,869,356,754,407,12,632,711,346,732,765,696,937,478,201,838,888,341,490,17,78,9,919,469,860,216,946,38,507,69,937,229,512,763,985,587,111,224,595,91,714,733,126,292,888,958,273,799,287,816,199,415,216,923,67,571,128,111,273,607,584,903,919,272,67,610,989,582,765,601,367,376,10,68,857,259,993,469,334,191,419,993,880,459,284,628,498,131,204,29,936,430,52,569,559,3,860,360,715,124,93,846,211,291,989,560,309,730,223,294,241,827,912,23,183,403,517,838,643,101,383,292,366,712,313,805,495,936,516,674,383,564,974,658,339,935,153,458,595,275,286,97,126,172,170,503,486,665,578,917,648,123,589,861,968,742,283,460,64,596,789,116,173,392,788,907,330,667,726,302,554,92,234,553,108,110,963,129,796,201,576,647,751,28,892,476,749,409,944,541,637,291,973,771,386,561,792,270,453,691,807,808,246,877,448,576,190,267,691,153,592,44,969,980,869,99,283,385,917,101,20,954,126,402,141,573,919,549,482,438,657,267,914,816,551,321,637,504,172,716,111,322,764,636,539,185,167,474,224,707,913,407,561,413,185,297,85,549,951,137,614,769,888,350,938,606,550,343,154,840,652,99,133,126,68,281,383,211,481,278,628,654,973,779,591,280,608,567,706,150,310,682,740,618,198,845,481,280,671,164,958,983,73,654,40,998,362,979,690,970,857,821,605,623,890,90,537,414,512,869,974,956,719,282,308,835,705,715,736,792,758,663,613,964,469,911,107,653,508,680,591,76,429,766,673,630,599,740,244,645,16,146,45,216,641,931,925,912,384,863,152,457,20,479,980,836,165,443,212,346,377,494,57,970,323,660,444,78,999,256,696,482,607,86,351,145,471,424,245,973,853,114,260,836,115,246,213,442,959,593,136,896,326,873,51,413,536,781,398,859,606,532,515,551,36,424,574,558,291,493,801,800,977,627,551,409,347,302,905,190,778,766,564,645,324,455,932,633,372,773,784,777,113,290,199,452,621,413,698,507,357,822,28,208,379,830,482,166,803,666,82,959,925,990,646,210,630,164,842,381,320,364,411,959,142,199,375,741,732,714,159,712,450,290,66,589,986,99,180,536,482,888,972,524,900,846,325,321,854,458,747,649,542,672,977,266,748,924,752,701,69,693,535,990,568,170,78,564,941,278,446,35,214,103,136,675,282,550,690,680,308,68,952,938,665,499,106,524,70,827,254,159,364,960,565,839,450,616,143,887,894,760,105,386,974,418,199,710,928,277,108,418,287,142,586,579,670,345,567,542,849,954,675,591,453,964,705,701,427,46,596,322,11,633,952,929,196,882,71,585,513,758,218,924,853,331,53,151,23,392,519,825,784,978,53,566,306,897,213,812,371,49,104,184,173,858,438,703,798,777,667,837,867,773,870,415,526,677,795,204,142,268,447,351,313,706,260,986,51,207,14,412,153,612,130,718,570,327,245,784,111,649,616,798,214,324,52,859,578,710,864,276,723,954,515,646,842,499,350,793,468,77,272,363,110,259,417,516,523,507,691,728,482,979,152,806,335,299,667,51,802,594,572,582,329,499,99,372,714,380,352,860,671,787,228,766,350,613,639,966,78,325,294,440,504,674,185,277,820,221,778,123,871,29,391,228,243,764,974,824,348,404,437,172,798,681,871,888,351,752,123,212,710,603,264,133,591,711,750,683,756,715,143,106,647,525,778,574,31,348,514,269,36,181,130,789,133,784,13,738,139,74,880,540,446,530,991,61,115,276,781,94,775,337,286,582,876,797,958,296,258,799,761,603,150,889,926,524,62,671,63,155,732,292,166,848,350,764,994,470,586,906,599,29,596,960,746,632,117,292,354,442,485,206,212,671,281,690,507,603,417,308,42,481,156,274,768,318,432,462,997,933,74,527,84,569,916,96,246,723,735,805,942,657,376,932,767,135,13,976,572,852,191,439,455,677,606,974,324,184,156,896,607,934,740,648,231,846,772,255,608,87,134,864,624,100,795,665,69,819,832,844,510,231,458,616,91,496,976,208,675,144,455,689,417,666,314,4,667,634,575,906,565,577,289,241,529,657,702,832,64,774,897,766,571,298,479,264,762,508,923,580,569,842,666,906,88,456,8,11,908,910,135,973,994,57,378,886,45,172,24,403,579,771,673,743,195,927,324,974,420,866,783,459,819,196,302,205,757,346,850,734,189,406,423,41,101,769,29,719,57,144,778,945,512,72,264,629,893,739,46,115,148,125,0,178", "873,804,976,299,90,282,615,299,823,509,738,437,999,899,501,303,758,899,69,148,774,947,127,83,684,438,756,264,851,423,653,22,979,697,938,476,835,349,915,966,543,921,590,967,536,647,303,665,776,407,861,136,956,895,714,816,95,248,232,469,342,863,439,446,5,597,578,554,817,694,280,785,433,895,943,111,838,776,945,718,38,592,387,416,150,191,159,679,468,640,82,205,520,91,777,692,275,944,185,906,451,254,461,770,778,253,469,419,250,439,573,600,15,197,465,187,269,872,433,387,560,262,280,665,741,90,735,233,103,641,808,457,944,853,496,38,190,623,124,160,152,872,214,844,868,835,99,147,224,600,328,457,211,453,287,716,216,642,327,47,738,983,570,503,554,235,52,392,409,532,155,563,142,996,683,596,14,351,778,821,564,492,48,344,967,595,861,884,472,531,503,973,116,849,500,944,757,127,67,48,216,361,224,444,479,733,503,356,159,802,964,185,200,690,456,444,447,123,819,784,461,196,430,627,883,260,956,882,747,861,452,255,324,627,644,642,181,823,801,167,366,878,369,792,451,561,244,825,81,905,894,612,576,432,169,776,105,184,181,572,598,807,415,777,188,358,587,921,402,84,784,180,491,220,957,260,207,259,3,875,895,910,605,976,72,786,275,350,858,464,655,829,145,769,725,362,719,880,941,521,595,754,565,605,371,403,459,394,33,763,856,793,356,481,16,297,974,188,248,960,639,524,876,993,791,460,136,83,783,834,165,358,377,195,873,773,242,297,711,232,711,208,201,18,154,88,983,592,35,102,83,696,522,215,404,315,66,673,651,235,397,271,588,54,143,940,689,584,573,505,210,293,418,471,887,961,185,724,361,77,587,699,702,220,394,838,526,560,286,325,612,826,280,881,80,804,184,866,403,404,250,682,522,953,408,199,189,127,477,132,386,648,404,585,177,356,603,523,370,555,398,670,832,533,481,796,966,30,718,178,308,351,863,796,188,132,289,588,713,47,140,785,829,719,796,601,487,497,605,474,298,1000,948,417,957,463,123,411,636,420,379,666,804,772,375,714,64,75,905,710,621,839,758,927,97,210,543,57,130,917,285,456,36,479,789,144,517,730,647,100,889,114,922,473,140,145,699,775,338,429,402,563,20,413,257,214,274,151,256,226,297,293,920,272,366,627,587,622,542,910,23,487,766,340,918,898,703,215,182,878,273,645,126,619,628,35,405,846,938,200,259,282,839,349,225,397,940,177,212,571,600,517,678,318,494,246,835,382,245,292,24,849,446,972,551,486,13,629,649,769,60,159,421,574,95,550,814,910,383,294,405,556,329,983,382,823,958,271,882,557,601,150,159,340,610,727,756,647,292,300,637,299,87,517,677,498,672,697,749,659,94,288,209,498,865,630,322,988,46,266,53,461,829,892,761,428,478,445,759,561,82,196,280,773,149,672,298,188,156,974,883,593,271,672,385,396,362,94,186,835,660,735,961,803,451,387,162,513,421,687,355,746,599,705,137,55,292,378,833,63,71,555,667,343,327,253,705,242,209,343,964,929,803,292,506,117,254,844,165,783,523,30,778,284,248,831,477,156,9,753,184,104,420,760,771,242,791,729,658,984,539,111,521,488,367,682,660,964,585,600,539,320,313,414,175,703,438,484,448,237,566,79,243,198,831,761,494,12,62,169,395,501,251,627,44,929,531,699,38,462,849,383,193,902,599,521,597,176,112,469,267,460,374,613,331,823,113,10,67,333,833,280,779,900,428,264,501,260,813,872,796,543,855,876,710,282,654,734,156,114,444,930,343,769,369,366,637,377,289,768,584,783,819,762,991,515,887,891,81,104,50,325,650,806,425,259,61,274,376,868,643,721,931,732,877,500,140,84,487,316,818,608,310,789,288,818,522,513,297,255,467,89,768,331,778,227,890,11,213,374,274,51,616,181,950,39,778,495,892,981,142,886,484,1000,205,498,773,209,168,929,899,38,421,838,199,468,967,33,751,760,480,757,242,921,826,765,160,604,184,935,562,618,829,61,824,939,506,997,201,605,265,463,499,862,406,232,3,780,625,286,465,529,121,462,751,131,589,587,107,35,972,560,297,130,947,814,724,519,243,246,422,860,920,916,353,639,909,456,510,577,616,566,973,24,661,578,481,899,798,145,225,983,251,561,990,773,555,890,581,632,883,992,38,67,688,798,721,247,91,756,857,873,484,813,710,100,29,235,687,526,714,853,365,181,929,502,235,317,405,890,19,120,939,138,234,140,996,756,178,0") val graph = parseData(content) fun solve() { Greedy(graph).solve() } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/InheritanceBenchmark.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.ring private const val RUNS = 1_000_000 open class InheritanceBenchmark { open class A() { fun a(): Int = 0 fun a1(): Int = 1 fun a2(): Int = 2 fun a3(): Int = 3 fun a4(): Int = 4 fun a5(): Int = 5 fun a6(): Int = 6 fun a7(): Int = 7 fun a8(): Int = 8 open fun a9(): Int = 9 open fun a10(): Int = 10 open fun a11(): Int = 11 open fun a12(): Int = 12 open fun a13(): Int = 13 open fun a14(): Int = 14 open fun a15(): Int = 15 open fun a16(): Int = 16 open fun a17(): Int = 17 open fun a18(): Int = 18 open fun a19(): Int = 19 open fun a20(): Int = 20 open fun a21(): Int = 21 open fun a22(): Int = 22 open fun a23(): Int = 23 open fun a24(): Int = 24 open fun a25(): Int = 25 open fun a26(): Int = 26 open fun a27(): Int = 27 open fun a28(): Int = 28 open fun a29(): Int = 29 open fun a30(): Int = 30 open fun a31(): Int = 31 open fun a32(): Int = 32 open fun a33(): Int = 33 open fun a34(): Int = 34 open fun a35(): Int = 35 open fun a36(): Int = 36 open fun a37(): Int = 37 open fun a38(): Int = 38 open fun a39(): Int = 39 open fun a40(): Int = 40 open fun a41(): Int = 41 open fun a42(): Int = 42 open fun a43(): Int = 43 open fun a44(): Int = 44 open fun a45(): Int = 45 open fun a46(): Int = 46 open fun a47(): Int = 47 open fun a48(): Int = 48 open fun a49(): Int = 49 open fun a50(): Int = 50 open fun a51(): Int = 51 open fun a52(): Int = 52 open fun a53(): Int = 53 open fun a54(): Int = 54 open fun a55(): Int = 55 open fun a56(): Int = 56 open fun a57(): Int = 57 open fun a58(): Int = 58 open fun a59(): Int = 59 open fun a60(): Int = 60 open fun a61(): Int = 61 open fun a62(): Int = 62 open fun a63(): Int = 63 open fun a64(): Int = 64 open fun a65(): Int = 65 open fun a66(): Int = 66 open fun a67(): Int = 67 open fun a68(): Int = 68 open fun a69(): Int = 69 open fun a70(): Int = 70 open fun a71(): Int = 71 open fun a72(): Int = 72 open fun a73(): Int = 73 open fun a74(): Int = 74 open fun a75(): Int = 75 open fun a76(): Int = 76 open fun a77(): Int = 77 open fun a78(): Int = 78 open fun a79(): Int = 79 open fun a80(): Int = 80 open fun a81(): Int = 81 open fun a82(): Int = 82 open fun a83(): Int = 83 open fun a84(): Int = 84 open fun a85(): Int = 85 open fun a86(): Int = 86 open fun a87(): Int = 87 open fun a88(): Int = 88 open fun a89(): Int = 89 open fun a90(): Int = 90 open fun a91(): Int = 91 open fun a92(): Int = 92 open fun a93(): Int = 93 open fun a94(): Int = 94 open fun a95(): Int = 95 open fun a96(): Int = 96 open fun a97(): Int = 97 open fun a98(): Int = 98 open fun a99(): Int = 99 } open class B() : A() { override fun a10(): Int = 0 fun b1(): Int = 1 fun b2(): Int = 2 fun b3(): Int = 3 fun b4(): Int = 4 fun b5(): Int = 5 open fun b6(): Int = 6 open fun b7(): Int = 7 open fun b8(): Int = 8 open fun b9(): Int = 9 open fun b10(): Int = 10 open fun b11(): Int = 11 open fun b12(): Int = 12 open fun b13(): Int = 13 open fun b14(): Int = 14 open fun b15(): Int = 15 open fun b16(): Int = 16 open fun b17(): Int = 17 open fun b18(): Int = 18 open fun b19(): Int = 19 open fun b20(): Int = 20 open fun b21(): Int = 21 open fun b22(): Int = 22 open fun b23(): Int = 23 open fun b24(): Int = 24 open fun b25(): Int = 25 open fun b26(): Int = 26 open fun b27(): Int = 27 open fun b28(): Int = 28 open fun b29(): Int = 29 open fun b30(): Int = 30 open fun b31(): Int = 31 open fun b32(): Int = 32 open fun b33(): Int = 33 open fun b34(): Int = 34 open fun b35(): Int = 35 open fun b36(): Int = 36 open fun b37(): Int = 37 open fun b38(): Int = 38 open fun b39(): Int = 39 open fun b40(): Int = 40 open fun b41(): Int = 41 open fun b42(): Int = 42 open fun b43(): Int = 43 open fun b44(): Int = 44 open fun b45(): Int = 45 open fun b46(): Int = 46 open fun b47(): Int = 47 open fun b48(): Int = 48 open fun b49(): Int = 49 open fun b50(): Int = 50 open fun b51(): Int = 51 open fun b52(): Int = 52 open fun b53(): Int = 53 open fun b54(): Int = 54 open fun b55(): Int = 55 open fun b56(): Int = 56 open fun b57(): Int = 57 open fun b58(): Int = 58 open fun b59(): Int = 59 open fun b60(): Int = 60 open fun b61(): Int = 61 open fun b62(): Int = 62 open fun b63(): Int = 63 open fun b64(): Int = 64 open fun b65(): Int = 65 open fun b66(): Int = 66 open fun b67(): Int = 67 open fun b68(): Int = 68 open fun b69(): Int = 69 open fun b70(): Int = 70 open fun b71(): Int = 71 open fun b72(): Int = 72 open fun b73(): Int = 73 open fun b74(): Int = 74 open fun b75(): Int = 75 open fun b76(): Int = 76 open fun b77(): Int = 77 open fun b78(): Int = 78 open fun b79(): Int = 79 open fun b80(): Int = 80 open fun b81(): Int = 81 open fun b82(): Int = 82 open fun b83(): Int = 83 open fun b84(): Int = 84 open fun b85(): Int = 85 open fun b86(): Int = 86 open fun b87(): Int = 87 open fun b88(): Int = 88 open fun b89(): Int = 89 open fun b90(): Int = 90 open fun b91(): Int = 91 open fun b92(): Int = 92 open fun b93(): Int = 93 open fun b94(): Int = 94 open fun b95(): Int = 95 open fun b96(): Int = 96 open fun b97(): Int = 97 open fun b98(): Int = 98 open fun b99(): Int = 99 } open class C() : B() { fun c(): Int = 0 override fun a10(): Int = 100 fun c1(): Int = 1 fun c2(): Int = 2 fun c3(): Int = 3 fun c4(): Int = 4 fun c5(): Int = 5 fun c6(): Int = 6 fun c7(): Int = 7 fun c8(): Int = 8 open fun c9(): Int = 9 open fun c10(): Int = 10 open fun c11(): Int = 11 open fun c12(): Int = 12 open fun c13(): Int = 13 open fun c14(): Int = 14 open fun c15(): Int = 15 open fun c16(): Int = 16 open fun c17(): Int = 17 open fun c18(): Int = 18 open fun c19(): Int = 19 open fun c20(): Int = 20 open fun c21(): Int = 21 open fun c22(): Int = 22 open fun c23(): Int = 23 open fun c24(): Int = 24 open fun c25(): Int = 25 open fun c26(): Int = 26 open fun c27(): Int = 27 open fun c28(): Int = 28 open fun c29(): Int = 29 open fun c30(): Int = 30 open fun c31(): Int = 31 open fun c32(): Int = 32 open fun c33(): Int = 33 open fun c34(): Int = 34 open fun c35(): Int = 35 open fun c36(): Int = 36 open fun c37(): Int = 37 open fun c38(): Int = 38 open fun c39(): Int = 39 open fun c40(): Int = 40 open fun c41(): Int = 41 open fun c42(): Int = 42 open fun c43(): Int = 43 open fun c44(): Int = 44 open fun c45(): Int = 45 open fun c46(): Int = 46 open fun c47(): Int = 47 open fun c48(): Int = 48 open fun c49(): Int = 49 open fun c50(): Int = 50 open fun c51(): Int = 51 open fun c52(): Int = 52 open fun c53(): Int = 53 open fun c54(): Int = 54 open fun c55(): Int = 55 open fun c56(): Int = 56 open fun c57(): Int = 57 open fun c58(): Int = 58 open fun c59(): Int = 59 open fun c60(): Int = 60 open fun c61(): Int = 61 open fun c62(): Int = 62 open fun c63(): Int = 63 open fun c64(): Int = 64 open fun c65(): Int = 65 open fun c66(): Int = 66 open fun c67(): Int = 67 open fun c68(): Int = 68 open fun c69(): Int = 69 open fun c70(): Int = 70 open fun c71(): Int = 71 open fun c72(): Int = 72 open fun c73(): Int = 73 open fun c74(): Int = 74 open fun c75(): Int = 75 open fun c76(): Int = 76 open fun c77(): Int = 77 open fun c78(): Int = 78 open fun c79(): Int = 79 open fun c80(): Int = 80 open fun c81(): Int = 81 open fun c82(): Int = 82 open fun c83(): Int = 83 open fun c84(): Int = 84 open fun c85(): Int = 85 open fun c86(): Int = 86 open fun c87(): Int = 87 open fun c88(): Int = 88 open fun c89(): Int = 89 open fun c90(): Int = 90 open fun c91(): Int = 91 open fun c92(): Int = 92 open fun c93(): Int = 93 open fun c94(): Int = 94 open fun c95(): Int = 95 open fun c96(): Int = 96 open fun c97(): Int = 97 open fun c98(): Int = 98 open fun c99(): Int = 99 } open class D() : C() { override fun a10(): Int = 1000 fun d(): Int = 0 fun d1(): Int = 1 fun d2(): Int = 2 fun d3(): Int = 3 fun d4(): Int = 4 fun d5(): Int = 5 fun d6(): Int = 6 fun d7(): Int = 7 fun d8(): Int = 8 open fun d9(): Int = 9 open fun d10(): Int = 10 open fun d11(): Int = 11 open fun d12(): Int = 12 open fun d13(): Int = 13 open fun d14(): Int = 14 open fun d15(): Int = 15 open fun d16(): Int = 16 open fun d17(): Int = 17 open fun d18(): Int = 18 open fun d19(): Int = 19 open fun d20(): Int = 20 open fun d21(): Int = 21 open fun d22(): Int = 22 open fun d23(): Int = 23 open fun d24(): Int = 24 open fun d25(): Int = 25 open fun d26(): Int = 26 open fun d27(): Int = 27 open fun d28(): Int = 28 open fun d29(): Int = 29 open fun d30(): Int = 30 open fun d31(): Int = 31 open fun d32(): Int = 32 open fun d33(): Int = 33 open fun d34(): Int = 34 open fun d35(): Int = 35 open fun d36(): Int = 36 open fun d37(): Int = 37 open fun d38(): Int = 38 open fun d39(): Int = 39 open fun d40(): Int = 40 open fun d41(): Int = 41 open fun d42(): Int = 42 open fun d43(): Int = 43 open fun d44(): Int = 44 open fun d45(): Int = 45 open fun d46(): Int = 46 open fun d47(): Int = 47 open fun d48(): Int = 48 open fun d49(): Int = 49 open fun d50(): Int = 50 open fun d51(): Int = 51 open fun d52(): Int = 52 open fun d53(): Int = 53 open fun d54(): Int = 54 open fun d55(): Int = 55 open fun d56(): Int = 56 open fun d57(): Int = 57 open fun d58(): Int = 58 open fun d59(): Int = 59 open fun d60(): Int = 60 open fun d61(): Int = 61 open fun d62(): Int = 62 open fun d63(): Int = 63 open fun d64(): Int = 64 open fun d65(): Int = 65 open fun d66(): Int = 66 open fun d67(): Int = 67 open fun d68(): Int = 68 open fun d69(): Int = 69 open fun d70(): Int = 70 open fun d71(): Int = 71 open fun d72(): Int = 72 open fun d73(): Int = 73 open fun d74(): Int = 74 open fun d75(): Int = 75 open fun d76(): Int = 76 open fun d77(): Int = 77 open fun d78(): Int = 78 open fun d79(): Int = 79 open fun d80(): Int = 80 open fun d81(): Int = 81 open fun d82(): Int = 82 open fun d83(): Int = 83 open fun d84(): Int = 84 open fun d85(): Int = 85 open fun d86(): Int = 86 open fun d87(): Int = 87 open fun d88(): Int = 88 open fun d89(): Int = 89 open fun d90(): Int = 90 open fun d91(): Int = 91 open fun d92(): Int = 92 open fun d93(): Int = 93 open fun d94(): Int = 94 open fun d95(): Int = 95 open fun d96(): Int = 96 open fun d97(): Int = 97 open fun d98(): Int = 98 open fun d99(): Int = 99 } open class E() : D() { override fun a10(): Int = 200 open fun e1(): Int = 1 open fun e2(): Int = 2 open fun e3(): Int = 3 open fun e4(): Int = 4 open fun e5(): Int = 5 open fun e6(): Int = 6 open fun e7(): Int = 7 open fun e8(): Int = 8 open fun e9(): Int = 9 open fun e10(): Int = 10 open fun e11(): Int = 11 open fun e12(): Int = 12 open fun e13(): Int = 13 open fun e14(): Int = 14 open fun e15(): Int = 15 } open class F() : E() { open fun f1(): Int = 1 open fun f2(): Int = 2 open fun f3(): Int = 3 open fun f4(): Int = 4 open fun f5(): Int = 5 open fun f6(): Int = 6 open fun f7(): Int = 7 open fun f8(): Int = 8 open fun f9(): Int = 9 open fun f10(): Int = 10 open fun f11(): Int = 11 open fun f12(): Int = 12 open fun f13(): Int = 13 open fun f14(): Int = 14 open fun f15(): Int = 15 } open class G() : F() { open fun g1(): Int = 1 open fun g2(): Int = 2 open fun g3(): Int = 3 open fun g4(): Int = 4 open fun g5(): Int = 5 open fun g6(): Int = 6 open fun g7(): Int = 7 open fun g8(): Int = 8 open fun g9(): Int = 9 open fun g10(): Int = 10 open fun g11(): Int = 11 open fun g12(): Int = 12 open fun g13(): Int = 13 open fun g14(): Int = 14 open fun g15(): Int = 15 } val a = A() val b = B() val c = C() val d = D() val e = E() val f = F() val g = G() fun baseCalls(): Int { var x = 0 for (i in 0 until RUNS) { x += a.a() x += b.a10() x += c.b20() x += d.c20() x += e.d10() x += f.e10() x += g.f10() x += g.g3() } return x } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/InlineBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring fun load(value: Int, size: Int): Int { var acc = 0 for (i in 0..size) { acc = acc xor value.hashCode() } return acc } inline fun loadInline(value: Int, size: Int): Int { var acc = 0 for (i in 0..size) { acc = acc xor value.hashCode() } return acc } fun loadGeneric(value: T, size: Int): Int { var acc = 0 for (i in 0..size) { acc = acc xor value.hashCode() } return acc } inline fun loadGenericInline(value: T, size: Int): Int { var acc = 0 for (i in 0..size) { acc = acc xor value.hashCode() } return acc } open class InlineBenchmark { private var value = 2138476523 //Benchmark fun calculate(): Int { return load(value, BENCHMARK_SIZE) } //Benchmark fun calculateInline(): Int { return loadInline(value, BENCHMARK_SIZE) } //Benchmark fun calculateGeneric(): Int { return loadGeneric(value, BENCHMARK_SIZE) } //Benchmark fun calculateGenericInline(): Int { return loadGenericInline(value, BENCHMARK_SIZE) } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/IntArrayBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring open class IntArrayBenchmark { private var _data: IntArray? = null val data: IntArray get() = _data!! init { val list = IntArray(BENCHMARK_SIZE) var index = 0 for (n in intValues(BENCHMARK_SIZE)) list[index++] = n _data = list } //Benchmark fun copy(): List { return data.toList() } //Benchmark fun copyManual(): ArrayList { val list = ArrayList(data.size) for (item in data) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.filter { filterLoad(it) }.count() } //Benchmark fun filterSomeAndCount(): Int { return data.filter { filterSome(it) }.count() } //Benchmark fun filterAndMap(): List { return data.filter { filterLoad(it) }.map { mapLoad(it) } } //Benchmark fun filterAndMapManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterLoad(it)) { val value = mapLoad(it) list.add(value) } } return list } //Benchmark fun filter(): List { return data.filter { filterLoad(it) } } //Benchmark fun filterSome(): List { return data.filter { filterSome(it) } } //Benchmark fun filterPrime(): List { return data.filter { filterPrime(it) } } //Benchmark fun filterManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterLoad(it)) list.add(it) } return list } //Benchmark fun filterSomeManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterSome(it)) list.add(it) } return list } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFilteredSomeManual(): Int { var count = 0 for (it in data) { if (filterSome(it)) count++ } return count } //Benchmark fun countFilteredPrimeManual(): Int { var count = 0 for (it in data) { if (filterPrime(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.count { filterLoad(it) } } //Benchmark fun countFilteredSome(): Int { return data.count { filterSome(it) } } //Benchmark fun countFilteredPrime(): Int { val res = data.count { filterPrime(it) } //println(res) return res } //Benchmark fun countFilteredLocal(): Int { return data.cnt { filterLoad(it) } } //Benchmark fun countFilteredSomeLocal(): Int { return data.cnt { filterSome(it) } } //Benchmark fun reduce(): Int { return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/IntBaselineBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class IntBaselineBenchmark { //Benchmark fun consume() { for (item in 1..BENCHMARK_SIZE) { Blackhole.consume(item) } } //Benchmark fun allocateList(): List { val list = ArrayList(BENCHMARK_SIZE) return list } //Benchmark fun allocateArray(): IntArray { val list = IntArray(BENCHMARK_SIZE) return list } //Benchmark fun allocateListAndFill(): List { val list = ArrayList(BENCHMARK_SIZE) for (item in 1..BENCHMARK_SIZE) { list.add(item) } return list } //Benchmark fun allocateArrayAndFill(): IntArray { var index = 0 val list = IntArray(BENCHMARK_SIZE) for (item in 1..BENCHMARK_SIZE) { list[index++] = item } return list } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/IntListBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring open class IntListBenchmark { private var _data: List? = null val data: List get() = _data!! init { val list = ArrayList(BENCHMARK_SIZE) for (n in intValues(BENCHMARK_SIZE)) list.add(n) _data = list } //Benchmark fun copy(): List { return data.toList() } //Benchmark fun copyManual(): List { val list = ArrayList(data.size) for (item in data) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.filter { filterLoad(it) }.count() } //Benchmark fun filterAndMap(): List { return data.filter { filterLoad(it) }.map { mapLoad(it) } } //Benchmark fun filterAndMapManual(): ArrayList { val list = ArrayList() for (it in data) { if (filterLoad(it)) { val value = mapLoad(it) list.add(value) } } return list } //Benchmark fun filter(): List { return data.filter { filterLoad(it) } } //Benchmark fun filterManual(): List { val list = ArrayList() for (it in data) { if (filterLoad(it)) list.add(it) } return list } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.count { filterLoad(it) } } //Benchmark fun countFilteredLocal(): Int { return data.cnt { filterLoad(it) } } //Benchmark fun reduce(): Int { return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/IntStreamBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class IntStreamBenchmark { private var _data: Iterable? = null val data: Iterable get() = _data!! init { _data = intValues(BENCHMARK_SIZE) } //Benchmark fun copy(): List { return data.asSequence().toList() } //Benchmark fun copyManual(): List { val list = ArrayList() for (item in data.asSequence()) { list.add(item) } return list } //Benchmark fun filterAndCount(): Int { return data.asSequence().filter { filterLoad(it) }.count() } //Benchmark fun filterAndMap() { for (item in data.asSequence().filter { filterLoad(it) }.map { mapLoad(it) }) Blackhole.consume(item) } //Benchmark fun filterAndMapManual() { for (it in data.asSequence()) { if (filterLoad(it)) { val item = mapLoad(it) Blackhole.consume(item) } } } //Benchmark fun filter() { for (item in data.asSequence().filter { filterLoad(it) }) Blackhole.consume(item) } //Benchmark fun filterManual(){ for (it in data.asSequence()) { if (filterLoad(it)) Blackhole.consume(it) } } //Benchmark fun countFilteredManual(): Int { var count = 0 for (it in data.asSequence()) { if (filterLoad(it)) count++ } return count } //Benchmark fun countFiltered(): Int { return data.asSequence().count { filterLoad(it) } } //Benchmark fun countFilteredLocal(): Int { return data.asSequence().cnt { filterLoad(it) } } //Benchmark fun reduce(): Int { return data.asSequence().fold(0) {acc, it -> if (filterLoad(it)) acc + 1 else acc } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/LambdaBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Random var globalAddendum = 0 open class LambdaBenchmark { private inline fun runLambda(x: () -> T): T = x() private fun runLambdaNoInline(x: () -> T): T = x() init { globalAddendum = Random.nextInt(20) } //Benchmark fun noncapturingLambda(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambda { globalAddendum } } return x } //Benchmark fun noncapturingLambdaNoInline(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambdaNoInline { globalAddendum } } return x } //Benchmark fun capturingLambda(): Int { val addendum = globalAddendum + 1 var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambda { addendum } } return x } //Benchmark fun capturingLambdaNoInline(): Int { val addendum = globalAddendum + 1 var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambdaNoInline { addendum } } return x } //Benchmark fun mutatingLambda(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { runLambda { x += globalAddendum } } return x } //Benchmark fun mutatingLambdaNoInline(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { runLambdaNoInline { x += globalAddendum } } return x } //Benchmark fun methodReference(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambda(::referenced) } return x } //Benchmark fun methodReferenceNoInline(): Int { var x: Int = 0 for (i in 0..BENCHMARK_SIZE) { x += runLambdaNoInline(::referenced) } return x } } private fun referenced(): Int { return globalAddendum } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/LinkedListWithAtomicsBenchmark.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Random class ChunkBuffer(var readPosition: Int, var writePosition: Int = readPosition + Random.nextInt(50)) { private val nextRef: AtomicRef = atomic(null) /** * Reference to next buffer view. Useful to chain multiple views. * @see appendNext * @see cleanNext */ var next: ChunkBuffer? get() = nextRef.value set(newValue) { if (newValue == null) { cleanNext() } else { appendNext(newValue) } } fun cleanNext(): ChunkBuffer? { return nextRef.getAndSet(null) } private fun appendNext(chunk: ChunkBuffer) { if (!nextRef.compareAndSet(null, chunk)) { throw IllegalStateException("This chunk has already a next chunk.") } } inline val readRemaining: Int get() = writePosition - readPosition } fun ChunkBuffer.remainingAll(): Long = remainingAll(0L) private tailrec fun ChunkBuffer.remainingAll(n: Long): Long { val rem = readRemaining.toLong() + n val next = this.next ?: return rem return next.remainingAll(rem) } class LinkedListOfBuffers(var head: ChunkBuffer = ChunkBuffer(0,0), var remaining: Long = head.remainingAll()) { var tailRemaining: Long = remaining - head.readRemaining set(newValue) { if (newValue < 0) { error("tailRemaining is negative: $newValue") } val tailSize = head.next?.remainingAll() ?: 0L if (newValue == 0L) { if (tailSize != 0L) { error("tailRemaining is set 0 while there is a tail of size $tailSize") } } field = newValue } } open class LinkedListWithAtomicsBenchmark { val list: LinkedListOfBuffers init { val chunks: MutableList = ArrayList() (0..BENCHMARK_SIZE/2).forEachIndexed { index, i -> val chunk = ChunkBuffer(Random.nextInt()) chunks.add(chunk) if (i > 0) chunks[i - 1].next = chunk } list = LinkedListOfBuffers(chunks[0]) } tailrec fun ensureNext(current: ChunkBuffer = list.head): ChunkBuffer? { val next = current.next return when { next == null -> null else -> { list.tailRemaining = Random.nextInt().toLong() + 1 ensureNext(next) } } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/LocalObjectsBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class LocalObjectsBenchmark { //Benchmark fun localArray(): Int { val size = 48 val array = IntArray(size) for (i in 1..size) { array[i - 1] = i * 2 } var result = 0 for (i in 0 until size) { result += array[i] } if (result > 10) { return 1 } return 2 } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/LoopBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class LoopBenchmark { lateinit var arrayList: List lateinit var array: Array init { val list = ArrayList(BENCHMARK_SIZE) for (n in classValues(BENCHMARK_SIZE)) list.add(n) arrayList = list array = list.toTypedArray() } //Benchmark fun arrayLoop() { for (x in array) { Blackhole.consume(x) } } //Benchmark fun arrayIndexLoop() { for (i in array.indices) { Blackhole.consume(array[i]) } } //Benchmark fun rangeLoop() { for (i in 0..BENCHMARK_SIZE) { Blackhole.consume(i) } } //Benchmark fun arrayListLoop() { for (x in arrayList) { Blackhole.consume(x) } } //Benchmark fun arrayWhileLoop() { var i = 0 val s = array.size while (i < s) { Blackhole.consume(array[i]) i++ } } //Benchmark fun arrayForeachLoop() { array.forEach { Blackhole.consume(it) } } //Benchmark fun arrayListForeachLoop() { arrayList.forEach { Blackhole.consume(it) } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/MatrixMapBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole import org.jetbrains.benchmarksLauncher.Random /** * This class emulates matrix behaviour using a hash map as its implementation */ class KMatrix internal constructor(val rows: Int, val columns: Int) { private val matrix: MutableMap, Double> = HashMap(); init { for (row in 0..rows-1) { for (col in 0..columns-1) { matrix.put(Pair(row, col), Random.nextDouble()) } } } fun get(row: Int, col: Int): Double { return get(Pair(row, col)) } fun get(pair: Pair): Double { return matrix.getOrElse(pair, { 0.0 }) } fun put(pair: Pair, elem: Double) { matrix.put(pair, elem) } operator fun plusAssign(other: KMatrix) { for (entry in matrix.entries) { put(entry.key, entry.value + other.get(entry.key)) } } } /** * This class tests hash map performance */ open class MatrixMapBenchmark { //Benchmark fun add(): KMatrix { var rows = BENCHMARK_SIZE var cols = 1 while (rows > cols) { rows /= 2 cols *= 2 } val a = KMatrix(rows, cols) val b = KMatrix(rows, cols) a += b return a } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/OctoTest/basicTest.kt ================================================ /** * Created by semoro on 07.07.17. */ import org.jetbrains.benchmarksLauncher.assert fun octoTest() { val tree = OctoTree(4) val to = (2 shl tree.depth) var x = 0 var y = 0 var z = 0 while (x < to) { y = 0 while (y < to) { z = 0 while (z < to) { val c = (z + to * y + to * to * x) % 2 == 0 tree.set(x, y, z, c) z++ } y++ } x++ } x = 0 y = 0 z = 0 while (x < to) { y = 0 while (y < to) { z = 0 while (z < to) { val c = (z + to * y + to * to * x) % 2 == 0 val res = tree.get(x, y, z) assert(res == c) z++ } y++ } x++ } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/OctoTest/ocTree.kt ================================================ open class OctoTree(val depth: Int) { private var root: Node? = null private var actual = false //-------------------------------------------------------------------------// fun get(x: Int, y: Int, z: Int): T? { var dep = depth var iter = root while (true) { if (iter == null) return null else if (iter is Node.Leaf) return iter.value iter = (iter as Node.Branch).nodes[number(x, y, z, --dep)] } } //-------------------------------------------------------------------------// fun set(x: Int, y: Int, z: Int, value: T) { if (root == null) root = Node.Branch() if (root!!.set(x, y, z, value, depth - 1)) { root = Node.Leaf(value) } actual = false } //-------------------------------------------------------------------------// override fun toString(): String = root.toString() //-------------------------------------------------------------------------// sealed class Node { abstract fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean //---------------------------------------------------------------------// class Leaf(var value: T) : Node() { override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean { throw UnsupportedOperationException("set on Leaf element") } override fun toString(): String = "L{$value}" } //---------------------------------------------------------------------// class Branch() : Node() { constructor(value: T, exclude: Int) : this() { var i = 0 while (i < 8) { if (i != exclude) { nodes[i] = Leaf(value) } i++ } } private fun canClusterize(value: T): Boolean { var i = 0 while (i < 8) { val w = nodes[i] if (w == null || w !is Leaf || value != w.value) { return false } i++ } return true } override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean { val branchIndex = number(x, y, z, depth) val node = nodes[branchIndex] when (node) { null -> { if (depth == 0) { nodes[branchIndex] = Leaf(value) return canClusterize(value) } else { nodes[branchIndex] = Branch() } } is Leaf -> { if (node.value == value) { return false } else if (depth == 0) { node.value = value return canClusterize(value) } nodes[branchIndex] = Branch(node.value, number(x, y, z, depth - 1)) } } if (nodes[branchIndex]!!.set(x, y, z, value, depth - 1)) { nodes[branchIndex] = Leaf(value) return canClusterize(value) } return false } val nodes = arrayOfNulls>(8) override fun toString(): String = nodes.joinToString(prefix = "[", postfix = "]") } } //-------------------------------------------------------------------------// companion object { fun number(x: Int, y: Int, z: Int, depth: Int): Int { val mask = 1 shl depth if (x and mask != 0) { if (y and mask != 0) { if (z and mask != 0) return 7 return 6 } if (z and mask != 0) return 5 return 4 } if (y and mask != 0) { if (z and mask != 0) return 3 return 2 } if (z and mask != 0) return 1 return 0 } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/ParameterNotNullAssertionBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring val OBJ = Any() open class ParameterNotNullAssertionBenchmark { fun methodWithOneNotnullParameter(p: Any): Any { return p } private fun privateMethodWithOneNotnullParameter(p: Any): Any { return p } fun methodWithTwoNotnullParameters(p: Any, p2: Any): Any { return p } private fun privateMethodWithTwoNotnullParameters(p: Any, p2: Any): Any { return p } fun methodWithEightNotnullParameters(p: Any, p2: Any, p3: Any, p4: Any, p5: Any, p6: Any, p7: Any, p8: Any): Any { return p } private fun privateMethodWithEightNotnullParameters(p: Any, p2: Any, p3: Any, p4: Any, p5: Any, p6: Any, p7: Any, p8: Any): Any { return p } //Benchmark fun invokeOneArgWithNullCheck(): Any { return methodWithOneNotnullParameter(OBJ) } //Benchmark fun invokeOneArgWithoutNullCheck(): Any { return privateMethodWithOneNotnullParameter(OBJ) } //Benchmark fun invokeTwoArgsWithNullCheck(): Any { return methodWithTwoNotnullParameters(OBJ, OBJ) } //Benchmark fun invokeTwoArgsWithoutNullCheck(): Any { return privateMethodWithTwoNotnullParameters(OBJ, OBJ) } //Benchmark fun invokeEightArgsWithNullCheck(): Any { return methodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) } //Benchmark fun invokeEightArgsWithoutNullCheck(): Any { return privateMethodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/PrimeListBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring /** * This class tests linked list performance * using prime number calculation algorithms * * @author Mikhail Glukhikh */ open class PrimeListBenchmark { private var primes: MutableList = mutableListOf() //Benchmark fun calcDirect() { primes.clear() primes.add(2) var i = 3 while (i <= BENCHMARK_SIZE) { var simple = true for (prime in primes) { if (prime * prime > i) break if (i % prime == 0) { simple = false break } } if (simple) primes.add(i) i += 2 } } //Benchmark fun calcEratosthenes() { primes.clear() primes.addAll(2..BENCHMARK_SIZE) var i = 0 while (i < primes.size) { val divisor = primes[i] primes.removeAll { it -> it > divisor && it % divisor == 0 } i++ } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/SingletonBenchmark.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole import org.jetbrains.benchmarksLauncher.Random private object A { val a = Random.nextInt(100) } open class SingletonBenchmark { init { // Make sure A is initialized. Blackhole.consume(A.a) } // Benchmark fun access() { for (i in 0 until BENCHMARK_SIZE) { Blackhole.consume(A.a) } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/StringBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Random open class StringBenchmark { private var _data: ArrayList? = null val data: ArrayList get() = _data!! var csv: String = "" init { val list = ArrayList(BENCHMARK_SIZE) for (n in stringValues(BENCHMARK_SIZE)) list.add(n) _data = list csv = "" for (i in 1..BENCHMARK_SIZE-1) { val elem = Random.nextDouble() csv += elem csv += "," } csv += 0.0 } //Benchmark open fun stringConcat(): String? { var string: String = "" for (it in data) string += it return string } //Benchmark open fun stringConcatNullable(): String? { var string: String? = "" for (it in data) string += it return string } //Benchmark open fun stringBuilderConcat(): String { var string : StringBuilder = StringBuilder("") for (it in data) string.append(it) return string.toString() } //Benchmark open fun stringBuilderConcatNullable(): String { var string : StringBuilder? = StringBuilder("") for (it in data) string?.append(it) return string.toString() } //Benchmark open fun summarizeSplittedCsv(): Double { val fields = csv.split(",") var sum = 0.0 for (field in fields) { sum += field.toDouble() } return sum } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/SwitchBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole import org.jetbrains.benchmarksLauncher.Random val SPARSE_SWITCH_CASES = intArrayOf(11, 29, 47, 71, 103, 149, 175, 227, 263, 307, 361, 487, 563, 617, 677, 751, 823, 883, 967, 1031) const val V1 = 1 const val V2 = 2 const val V3 = 3 const val V4 = 4 const val V5 = 5 const val V6 = 6 const val V7 = 7 const val V8 = 8 const val V9 = 9 const val V10 = 10 const val V11 = 11 const val V12 = 12 const val V13 = 13 const val V14 = 14 const val V15 = 15 const val V16 = 16 const val V17 = 17 const val V18 = 18 const val V19 = 19 const val V20 = 20 object Numbers { const val V1 = 1 const val V2 = 2 const val V3 = 3 const val V4 = 4 const val V5 = 5 const val V6 = 6 const val V7 = 7 const val V8 = 8 const val V9 = 9 const val V10 = 10 const val V11 = 11 const val V12 = 12 const val V13 = 13 const val V14 = 14 const val V15 = 15 const val V16 = 16 const val V17 = 17 const val V18 = 18 const val V19 = 19 const val V20 = 20 } var VV1 = 1 var VV2 = 2 var VV3 = 3 var VV4 = 4 var VV5 = 5 var VV6 = 6 var VV7 = 7 var VV8 = 8 var VV9 = 9 var VV10 = 10 var VV11 = 11 var VV12 = 12 var VV13 = 13 var VV14 = 14 var VV15 = 15 var VV16 = 16 var VV17 = 17 var VV18 = 18 var VV19 = 19 var VV20 = 20 open class SwitchBenchmark { fun sparseIntSwitch(u : Int) : Int { var t : Int when (u) { 11 -> { t = 1 } 29 -> { t = 2 } 47 -> { t = 3 } 71 -> { t = 4 } 103 -> { t = 5 } 149 -> { t = 6 } 175 -> { t = 7 } 227 -> { t = 1 } 263 -> { t = 9 } 307 -> { t = 1 } 361 -> { t = 2 } 487 -> { t = 3 } 563 -> { t = 4 } 617 -> { t = 4 } 677 -> { t = 4 } 751 -> { t = 435 } 823 -> { t = 31 } 883 -> { t = 1 } 967 -> { t = 1 } 1031 -> { t = 1 } 20 -> { t = 1 } else -> { t = 5 } } return t } fun denseIntSwitch(u : Int) : Int { var t : Int when (u) { 1 -> { t = 1 } -1 -> { t = 2 } 2 -> { t = 3 } 3 -> { t = 4 } 4 -> { t = 5 } 5 -> { t = 6 } 6 -> { t = 7 } 7 -> { t = 1 } 8 -> { t = 9 } 9 -> { t = 1 } 10 -> { t = 2 } 11 -> { t = 3 } 12 -> { t = 4 } 13 -> { t = 4 } 14 -> { t = 4 } 15 -> { t = 435 } 16 -> { t = 31 } 17 -> { t = 1 } 18 -> { t = 1 } 19 -> { t = 1 } 20 -> { t = 1 } else -> { t = 5 } } return t } fun constSwitch(u : Int) : Int { var t : Int when (u) { V1 -> { t = 1 } V2 -> { t = 3 } V3 -> { t = 4 } V4 -> { t = 5 } V5 -> { t = 6 } V6 -> { t = 7 } V7 -> { t = 1 } V8 -> { t = 9 } V9 -> { t = 1 } V10 -> { t = 2 } V11 -> { t = 3 } V12 -> { t = 4 } V13 -> { t = 4 } V14 -> { t = 4 } V15 -> { t = 435 } V16 -> { t = 31 } V17 -> { t = 1 } V18 -> { t = 1 } V19 -> { t = 1 } V20 -> { t = 1 } else -> { t = 5 } } return t } fun objConstSwitch(u : Int) : Int { var t : Int when (u) { Numbers.V1 -> { t = 1 } Numbers.V2 -> { t = 3 } Numbers.V3 -> { t = 4 } Numbers.V4 -> { t = 5 } Numbers.V5 -> { t = 6 } Numbers.V6 -> { t = 7 } Numbers.V7 -> { t = 1 } Numbers.V8 -> { t = 9 } Numbers.V9 -> { t = 1 } Numbers.V10 -> { t = 2 } Numbers.V11 -> { t = 3 } Numbers.V12 -> { t = 4 } Numbers.V13 -> { t = 4 } Numbers.V14 -> { t = 4 } Numbers.V15 -> { t = 435 } Numbers.V16 -> { t = 31 } Numbers.V17 -> { t = 1 } Numbers.V18 -> { t = 1 } Numbers.V19 -> { t = 1 } Numbers.V20 -> { t = 1 } else -> { t = 5 } } return t } fun varSwitch(u : Int) : Int { var t : Int when (u) { VV1 -> { t = 1 } VV2 -> { t = 3 } VV3 -> { t = 4 } VV4 -> { t = 5 } VV5 -> { t = 6 } VV6 -> { t = 7 } VV7 -> { t = 1 } VV8 -> { t = 9 } VV9 -> { t = 1 } VV10 -> { t = 2 } VV11 -> { t = 3 } VV12 -> { t = 4 } VV13 -> { t = 4 } VV14 -> { t = 4 } VV15 -> { t = 435 } VV16 -> { t = 31 } VV17 -> { t = 1 } VV18 -> { t = 1 } VV19 -> { t = 1 } VV20 -> { t = 1 } else -> { t = 5 } } return t } private fun stringSwitch(s: String) : Int { when(s) { "ABCDEFG1" -> return 1 "ABCDEFG2" -> return 2 "ABCDEFG2" -> return 3 "ABCDEFG3" -> return 4 "ABCDEFG4" -> return 5 "ABCDEFG5" -> return 6 "ABCDEFG6" -> return 7 "ABCDEFG7" -> return 8 "ABCDEFG8" -> return 9 "ABCDEFG9" -> return 10 "ABCDEFG10" -> return 11 "ABCDEFG11" -> return 12 "ABCDEFG12" -> return 1 "ABCDEFG13" -> return 2 "ABCDEFG14" -> return 3 "ABCDEFG15" -> return 4 "ABCDEFG16" -> return 5 "ABCDEFG17" -> return 6 "ABCDEFG18" -> return 7 "ABCDEFG19" -> return 8 "ABCDEFG20" -> return 9 else -> return -1 } } lateinit var denseIntData: IntArray lateinit var sparseIntData: IntArray //Benchmark fun testSparseIntSwitch() { for (i in sparseIntData) { Blackhole.consume(sparseIntSwitch(i)) } } //Benchmark fun testDenseIntSwitch() { for (i in denseIntData) { Blackhole.consume(denseIntSwitch(i)) } } //Benchmark fun testConstSwitch() { for (i in denseIntData) { Blackhole.consume(constSwitch(i)) } } //Benchmark fun testObjConstSwitch() { for (i in denseIntData) { Blackhole.consume(objConstSwitch(i)) } } //Benchmark fun testVarSwitch() { for (i in denseIntData) { Blackhole.consume(varSwitch(i)) } } var data : Array = arrayOf() //Benchmark fun testStringsSwitch() { val n = data.size for (s in data) { Blackhole.consume(stringSwitch(s)) } } enum class MyEnum { ITEM1, ITEM2, ITEM3, ITEM4, ITEM5, ITEM6, ITEM7, ITEM8, ITEM9, ITEM10, ITEM11, ITEM12, ITEM13, ITEM14, ITEM15, ITEM16, ITEM17, ITEM18, ITEM19, ITEM20, ITEM21, ITEM22, ITEM23, ITEM24, ITEM25, ITEM26, ITEM27, ITEM28, ITEM29, ITEM30, ITEM31, ITEM32, ITEM33, ITEM34, ITEM35, ITEM36, ITEM37, ITEM38, ITEM39, ITEM40, ITEM41, ITEM42, ITEM43, ITEM44, ITEM45, ITEM46, ITEM47, ITEM48, ITEM49, ITEM50, ITEM51, ITEM52, ITEM53, ITEM54, ITEM55, ITEM56, ITEM57, ITEM58, ITEM59, ITEM60, ITEM61, ITEM62, ITEM63, ITEM64, ITEM65, ITEM66, ITEM67, ITEM68, ITEM69, ITEM70, ITEM71, ITEM72, ITEM73, ITEM74, ITEM75, ITEM76, ITEM77, ITEM78, ITEM79, ITEM80, ITEM81, ITEM82, ITEM83, ITEM84, ITEM85, ITEM86, ITEM87, ITEM88, ITEM89, ITEM90, ITEM91, ITEM92, ITEM93, ITEM94, ITEM95, ITEM96, ITEM97, ITEM98, ITEM99, ITEM100 } private fun enumSwitch(x: MyEnum) : Int { when (x) { MyEnum.ITEM5 -> return 1 MyEnum.ITEM10 -> return 2 MyEnum.ITEM15 -> return 3 MyEnum.ITEM20 -> return 4 MyEnum.ITEM25 -> return 5 MyEnum.ITEM30 -> return 6 MyEnum.ITEM35 -> return 7 MyEnum.ITEM40 -> return 8 MyEnum.ITEM45 -> return 9 MyEnum.ITEM50 -> return 10 MyEnum.ITEM55 -> return 11 MyEnum.ITEM60 -> return 12 MyEnum.ITEM65 -> return 13 MyEnum.ITEM70 -> return 14 MyEnum.ITEM75 -> return 15 MyEnum.ITEM80 -> return 16 MyEnum.ITEM85 -> return 17 MyEnum.ITEM90 -> return 18 MyEnum.ITEM95 -> return 19 MyEnum.ITEM100 -> return 20 else -> return -1 } } private fun denseEnumSwitch(x: MyEnum) : Int { when (x) { MyEnum.ITEM1 -> return 1 MyEnum.ITEM2 -> return 2 MyEnum.ITEM3 -> return 3 MyEnum.ITEM4 -> return 4 MyEnum.ITEM5 -> return 5 MyEnum.ITEM6 -> return 6 MyEnum.ITEM7 -> return 7 MyEnum.ITEM8 -> return 8 MyEnum.ITEM9 -> return 9 MyEnum.ITEM10 -> return 10 MyEnum.ITEM11 -> return 11 MyEnum.ITEM12 -> return 12 MyEnum.ITEM13 -> return 13 MyEnum.ITEM14 -> return 14 MyEnum.ITEM15 -> return 15 MyEnum.ITEM16 -> return 16 MyEnum.ITEM17 -> return 17 MyEnum.ITEM18 -> return 18 MyEnum.ITEM19 -> return 19 MyEnum.ITEM20 -> return 20 else -> return -1 } } lateinit var enumData : Array lateinit var denseEnumData : Array //Benchmark fun testEnumsSwitch() { val n = enumData.size -1 val data = enumData for (i in 0..n) { Blackhole.consume(enumSwitch(data[i])) } } //Benchmark fun testDenseEnumsSwitch() { val n = denseEnumData.size -1 val data = denseEnumData for (i in 0..n) { Blackhole.consume(denseEnumSwitch(data[i])) } } sealed class MySealedClass { class MySealedClass1: MySealedClass() class MySealedClass2: MySealedClass() class MySealedClass3: MySealedClass() class MySealedClass4: MySealedClass() class MySealedClass5: MySealedClass() class MySealedClass6: MySealedClass() class MySealedClass7: MySealedClass() class MySealedClass8: MySealedClass() class MySealedClass9: MySealedClass() class MySealedClass10: MySealedClass() } lateinit var sealedClassData: Array init { data = Array(BENCHMARK_SIZE) { "ABCDEFG" + Random.nextInt(22) } enumData = Array(BENCHMARK_SIZE) { MyEnum.values()[it % MyEnum.values().size] } denseEnumData = Array(BENCHMARK_SIZE) { MyEnum.values()[it % 20] } denseIntData = IntArray(BENCHMARK_SIZE) { Random.nextInt(25) - 1 } sparseIntData = IntArray(BENCHMARK_SIZE) { SPARSE_SWITCH_CASES[Random.nextInt(20)] } sealedClassData = Array(BENCHMARK_SIZE) { when(Random.nextInt(10)) { 0 -> MySealedClass.MySealedClass1() 1 -> MySealedClass.MySealedClass2() 2 -> MySealedClass.MySealedClass3() 3 -> MySealedClass.MySealedClass4() 4 -> MySealedClass.MySealedClass5() 5 -> MySealedClass.MySealedClass6() 6 -> MySealedClass.MySealedClass7() 7 -> MySealedClass.MySealedClass8() 8 -> MySealedClass.MySealedClass9() 9 -> MySealedClass.MySealedClass10() else -> throw IllegalStateException() } } } private fun sealedWhenSwitch(x: MySealedClass) : Int = when (x) { is MySealedClass.MySealedClass1 -> 1 is MySealedClass.MySealedClass2 -> 2 is MySealedClass.MySealedClass3 -> 3 is MySealedClass.MySealedClass4 -> 4 is MySealedClass.MySealedClass5 -> 5 is MySealedClass.MySealedClass6 -> 6 is MySealedClass.MySealedClass7 -> 7 is MySealedClass.MySealedClass8 -> 8 is MySealedClass.MySealedClass9 -> 9 is MySealedClass.MySealedClass10 -> 10 } //Benchmark fun testSealedWhenSwitch() { val n = sealedClassData.size -1 for (i in 0..n) { Blackhole.consume(sealedWhenSwitch(sealedClassData[i])) } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/Utils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring const val BENCHMARK_SIZE = 10000 expect class AtomicRef { /** * Reading/writing this property maps to read/write of volatile variable. */ public var value: T /** * Maps to [AtomicReferenceFieldUpdater.lazySet]. */ public fun lazySet(value: T) /** * Maps to [AtomicReferenceFieldUpdater.compareAndSet]. */ public fun compareAndSet(expect: T, update: T): Boolean /** * Maps to [AtomicReferenceFieldUpdater.getAndSet]. */ public fun getAndSet(value: T): T } public expect fun atomic(initial: T): AtomicRef ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/WithIndiciesBenchmark.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import org.jetbrains.benchmarksLauncher.Blackhole open class WithIndiciesBenchmark { private var _data: ArrayList? = null val data: ArrayList get() = _data!! init { val list = ArrayList(BENCHMARK_SIZE) for (n in classValues(BENCHMARK_SIZE)) list.add(n) _data = list } //Benchmark fun withIndicies() { for ((index, value) in data.withIndex()) { if (filterLoad(value)) { Blackhole.consume(index) Blackhole.consume(value) } } } //Benchmark fun withIndiciesManual() { var index = 0 for (value in data) { if (filterLoad(value)) { Blackhole.consume(index) Blackhole.consume(value) } index++ } } } ================================================ FILE: performance/ring/src/main/kotlin/org/jetbrains/ring/zdf-win.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring val zdf_win = listOf( "-де", "-ка", "-либо", "-нибудь", "-с", "-таки", "-то", "а", "а-конто", "а-ля", "аба", "абажур", "абажурный", "абаз", "абазин", "абазинец", "абазинка", "абазинский", "абак", "абака", "аббат", "аббатиса", "аббатский", "аббатство", "аббревиатура", "аббревиатурный", "аббревиация", "абдикация", "абдомен", "абдоминальный", "абдуктор", "абдукторный", "абдукция", "абелит", "аберрационный", "аберрация", "абзац", "абзацный", "абиетин", "абиетиновый", "абиссальный", "абиссинец", "абиссинский", "абитуриент", "абитуриентка", "абитуриентский", "аблактировать", "аблактировка", "аблятив", "абляут", "абляция", "аболиционизм", "аболиционист", "аболиционистский", "аболиция", "абонемент", "абонементный", "абонент", "абонентка", "абонентный", "абонентский", "абонирование", "абонировать", "абонироваться", "абордаж", "абордажный", "абордировать", "абориген", "аборигенный", "аборт", "абортарий", "абортивный", "абортировать", "абразив", "абразивный", "абразионный", "абразия", "абракадабра", "абреже", "абрек", "абрикос", "абрикосный", "абрикосовка", "абрикосовый", "абрикотин", "абрис", "абрисный", "абсент", "абсентеизм", "абсентеист", "абсолют", "абсолютивный", "абсолютизирование", "абсолютизировать", "абсолютизм", "абсолютист", "абсолютистский", "абсолютность", "абсолютный", "абсолюция", "абсорбент", "абсорбер", "абсорбировать", "абсорбционный", "абсорбция", "абстинент", "абстрагирование", "абстрагировать", "абстрагироваться", "абстракт", "абстрактность", "абстрактный", "абстракционизм", "абстракционист", "абстракционистский", "абстракция", "абсурд", "абсурдность", "абсурдный", "абсцесс", "абсцисса", "абулия", "абхаз", "абхазец", "абхазка", "абхазский", "абцуг", "абштрих", "абъюрация", "абы", "авалист", "аваль", "авангард", "авангардизм", "авангардист", "авангардистский", "авангардный", "аванзал", "аванзальный", "аванкамера", "аванложа", "аванпорт", "аванпост", "аванпостный", "аванс", "авансирование", "авансировать", "авансовый", "авансом", "авансцена", "авантаж", "авантажный", "авантюра", "авантюризм", "авантюрин", "авантюриновый", "авантюрист", "авантюристический", "авантюристичный", "авантюристка", "авантюристский", "авантюрность", "авантюрный", "авар", "аварец", "аварийность", "аварийный", "аварийщик", "авария", "аварка", "аварский", "авгиев", "авгит", "авгур", "август", "августейший", "августинец", "августовский", "авдотка", "авеню", "аверс", "авестийский", "авиабаза", "авиабензин", "авиагоризонт", "авиадвигатель", "авиадесант", "авиадесантный", "авиазавод", "авиаконструктор", "авиалиния", "авиаматка", "авиамоделизм", "авиамоделист", "авиамодель", "авиамодельный", "авиамотор", "авиамоторный", "авианосец", "авиапочта", "авиаприбор", "авиапромышленность", "авиапромышленный", "авиаразведка", "авиастроение", "авиастроитель", "авиастроительный", "авиастроительство", "авиасъёмка", "авиатехник", "авиатор", "авиаторский", "авиатранспорт", "авиатранспортный", "авиатрасса", "авиационный", "авиация", "авиачасть", "авиашкола", "авиетка", "авизировать", "авизный", "авизо", "авитаминоз", "авитаминозный", "авифауна", "авокадо", "авось", "авоська", "аврал", "авралить", "авральный", "авран", "аврора", "австралиец", "австралийка", "австралийский", "австралопитек", "австриец", "австрийка", "австрийский", "австрияк", "австриячка", "австро-венгерский", "автаркический", "автаркия", "авто", "автобаза", "автобиографический", "автобиографичность", "автобиографичный", "автобиография", "автоблокировка", "автоблокировочный", "автобус", "автобусник", "автобусный", "автовакцина", "автовесы", "автовокзал", "автогамия", "автоген", "автогенез", "автогенератор", "автогенный", "автогенщик", "автогипноз", "автогонки", "автогравюра", "автограф", "автографический", "автография", "автогужевой", "автодидакт", "автодоение", "автодорожник", "автодорожный", "автодрезина", "автодром", "автожир", "автозавод", "автозаводец", "автозаводский", "автозаводской", "автозаправочный", "автозаправщик", "автоинспектор", "автоинспекция", "автокар", "автокара", "автокатализ", "автокефалия", "автокефальный", "автоклав", "автоклуб", "автоколонна", "автокомбинат", "автокран", "автократ", "автократический", "автократия", "автокружок", "автол", "автолавка", "автолиз", "автолитография", "автолюбитель", "автолюбительство", "автомагистраль", "автомат", "автоматизация", "автоматизирование", "автоматизировать", "автоматизироваться", "автоматизм", "автоматика", "автоматический", "автоматичность", "автоматичный", "автоматный", "автоматчик", "автоматчица", "автомашина", "автомашинист", "автомеханик", "автомобилестроение", "автомобилестроитель", "автомобилестроительный", "автомобилизация", "автомобилизм", "автомобилист", "автомобилистка", "автомобиль", "автомобильный", "автомобильчик", "автоморфизм", "автомотоклуб", "автомоторный", "автомотошкола", "автомотриса", "автономист", "автономистский", "автономический", "автономия", "автономность", "автономный", "автопарк", "автоперевозка", "автопилот", "автопластика", "автоплуг", "автопогрузчик", "автоподъёмник", "автопоезд", "автопоилка", "автопокрышка", "автопортрет", "автопробег", "автопромышленность", "автор", "авторалли", "авторегулятор", "авторемонтник", "авторемонтный", "автореферат", "авторефрижератор", "авторизация", "авторизованный", "авторизовать", "авторитарность", "авторитарный", "авторитет", "авторитетность", "авторитетный", "авторота", "авторские", "авторский", "авторство", "авторулевой", "авторучка", "автосани", "автосборка", "автосварщик", "автоспорт", "автостанция", "автостоп", "автострада", "автостроение", "автостроитель", "автосцепка", "автотележка", "автотип", "автотипический", "автотипия", "автотипный", "автотомия", "автотормоз", "автотормозной", "автотракторный", "автотранспорт", "автотранспортный", "автотрансформатор", "автотрасса", "автотуризм", "автотурист", "автоукладчик", "автофургон", "автохозяйство", "автохром", "автохромный", "автохтон", "автохтонный", "автоцистерна", "авточасть", "автошкола", "автоштурман", "авуары", "ага", "ага-хан", "агава", "агалит", "агальматолит", "агама", "агами", "агамия", "агамогония", "агар-агар", "агарный", "агаровый", "агарянин", "агат", "агатный", "агатовый", "агглютинативность", "агглютинативный", "агглютинация", "агглютинин", "агглютинирующий", "аггравация", "агент", "агентский", "агентство", "агентура", "агентурный", "агиографический", "агиография", "агиология", "агитатор", "агитаторский", "агитаторша", "агитационный", "агитация", "агитбригада", "агитировать", "агитка", "агиткампания", "агитмассовый", "агитпоезд", "агитпроп", "агитпункт", "аглицкий", "агломерат", "агломератчик", "агломерационный", "агломерация", "агломерировать", "агломерироваться", "агнат", "агнец", "агнозия", "агностик", "агностицизм", "агностический", "агонизировать", "агонический", "агония", "агорафобия", "аграмант", "аграмантовый", "аграрий", "аграрник", "аграрный", "аграф", "аграфия", "агрегат", "агрегатный", "агреман", "агрессивность", "агрессивный", "агрессия", "агрессор", "агрикультура", "агрикультурный", "агробаза", "агробиолог", "агробиологический", "агробиология", "агроботаника", "агрозоотехника", "агромелиорация" ) ================================================ FILE: performance/ring/src/main/kotlin-jvm/FakeKonanNamespace.kt ================================================ package org.jetbrains.ring class konan { annotation class ThreadLocal } ================================================ FILE: performance/ring/src/main/kotlin-jvm/cleanup.kt ================================================ package org.jetbrains.ring actual fun cleanup() { } ================================================ FILE: performance/ring/src/main/kotlin-jvm/org/jetbrains/ring/UtilsJVM.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import java.util.concurrent.atomic.AtomicReferenceFieldUpdater import java.util.concurrent.locks.ReentrantLock internal var interceptor: AtomicOperationInterceptor = DefaultInterceptor private set private val interceptorLock = ReentrantLock() internal fun lockAndSetInterceptor(impl: AtomicOperationInterceptor) { if (!interceptorLock.tryLock() || interceptor !== DefaultInterceptor) { error("Interceptor is locked by another test: $interceptor") } interceptor = impl } internal fun unlockAndResetInterceptor(impl: AtomicOperationInterceptor) { check(interceptor === impl) { "Unexpected interceptor found: $interceptor" } interceptor = DefaultInterceptor interceptorLock.unlock() } /** * Interceptor for modifications of atomic variables. */ internal open class AtomicOperationInterceptor { open fun beforeUpdate(ref: AtomicRef) {} open fun afterSet(ref: AtomicRef, newValue: T) {} open fun afterRMW(ref: AtomicRef, oldValue: T, newValue: T) {} } private object DefaultInterceptor : AtomicOperationInterceptor() { override fun toString(): String = "DefaultInterceptor" } @Suppress("UNCHECKED_CAST") public actual class AtomicRef internal constructor(value: T) { /** * Reading/writing this property maps to read/write of volatile variable. */ @Volatile public actual var value: T = value set(value) { interceptor.beforeUpdate(this) field = value interceptor.afterSet(this, value) } /** * Maps to [AtomicReferenceFieldUpdater.lazySet]. */ public actual fun lazySet(value: T) { interceptor.beforeUpdate(this) FU.lazySet(this, value) interceptor.afterSet(this, value) } /** * Maps to [AtomicReferenceFieldUpdater.compareAndSet]. */ public actual fun compareAndSet(expect: T, update: T): Boolean { interceptor.beforeUpdate(this) val result = FU.compareAndSet(this, expect, update) if (result) interceptor.afterRMW(this, expect, update) return result } /** * Maps to [AtomicReferenceFieldUpdater.getAndSet]. */ public actual fun getAndSet(value: T): T { interceptor.beforeUpdate(this) val oldValue = FU.getAndSet(this, value) as T interceptor.afterRMW(this, oldValue, value) return oldValue } override fun toString(): String = value.toString() private companion object { private val FU = AtomicReferenceFieldUpdater.newUpdater(AtomicRef::class.java, Any::class.java, "value") } } public actual fun atomic(initial: T): AtomicRef = AtomicRef(initial) ================================================ FILE: performance/ring/src/main/kotlin-native/cleanup.kt ================================================ package org.jetbrains.ring import kotlin.native.internal.GC actual fun cleanup() { GC.collect() } ================================================ FILE: performance/ring/src/main/kotlin-native/org/jetbrains/ring/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.ring import kotlin.native.concurrent.FreezableAtomicReference as KAtomicRef import kotlin.native.concurrent.isFrozen import kotlin.native.concurrent.freeze public actual class AtomicRef constructor(@PublishedApi internal val a: KAtomicRef) { public actual inline var value: T get() = a.value set(value) { if (a.isFrozen) value.freeze() a.value = value } public actual inline fun lazySet(value: T) { if (a.isFrozen) value.freeze() a.value = value } public actual inline fun compareAndSet(expect: T, update: T): Boolean { if (a.isFrozen) update.freeze() return a.compareAndSet(expect, update) } public actual fun getAndSet(value: T): T { if (a.isFrozen) value.freeze() while (true) { val cur = a.value if (cur === value) return cur if (a.compareAndSwap(cur, value) === cur) return cur } } override fun toString(): String = value.toString() } public actual fun atomic(initial: T): AtomicRef = AtomicRef(KAtomicRef(initial)) ================================================ FILE: performance/scripts/linux_services.list ================================================ cups.service cups.socket cups.path cups-browsed avahi-daemon.socket avahi-daemon.service whoopsie.service upower.service snapd.socket snapd.service bluetooth.target bluetooth.service ================================================ FILE: performance/scripts/services.sh ================================================ #!/usr/bin/env bash # Command services.sh -mode [on|off] -gui file_with_servers_list. MODE=ON CHANGE_GUI_MODE=0 if [ "$1" = "-mode" ]; then shift if [ "$1" = "off" ]; then MODE=OFF fi shift fi if [ "$1" = "-gui" ]; then CHANGE_GUI_MODE=1 shift fi INPUT_FILE=$1 if [ ! -f $INPUT_FILE ]; then echo "File $INPUT_FILE doesn't exist." exit 1 fi if [ $CHANGE_GUI_MODE = 1 ]; then # Turn on/off GUI mode. if [ "$MODE" = ON ]; then systemctl enable graphical.target --force systemctl set-default graphical.target else systemctl enable multi-user.target --force systemctl set-default multi-user.target fi fi while IFS=$'\r' read -r line || [[ -n "$line" ]]; do if [ "$MODE" = ON ]; then systemctl enable $line systemctl start $line else systemctl disable $line systemctl stop $line fi done < "$INPUT_FILE" ================================================ FILE: performance/settings.gradle ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ include ':ring' include ':cinterop' include ':helloworld' include ':numerical' include ':videoplayer' include ':framework' include ':startup' if (System.getProperty("os.name") == "Mac OS X") { include ':objcinterop' include ':swiftinterop' if (hasProperty("runExcludedBenchmarks")) { include ':KotlinVsSwift' include ':KotlinVsSwift:ring' } } includeBuild '../build-tools' ================================================ FILE: performance/shared/src/main/kotlin/org/jetbrains/benchmarksLauncher/BenchmarksCollection.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import org.jetbrains.report.BenchmarkResult interface AbstractBenchmarkEntry { open val useAutoEvaluatedNumberOfMeasure: Boolean } class BenchmarkEntryWithInit(val ctor: ()->Any, val lambda: (Any) -> Any?): AbstractBenchmarkEntry { companion object { inline fun create(noinline ctor: ()->T, crossinline lambda: T.() -> Any?) = BenchmarkEntryWithInit(ctor) { (it as T).lambda() } } override val useAutoEvaluatedNumberOfMeasure: Boolean = true } open class BenchmarkEntry(val lambda: () -> Any?) : AbstractBenchmarkEntry { override val useAutoEvaluatedNumberOfMeasure: Boolean = true } class BenchmarkEntryManual(lambda: () -> Any?) : BenchmarkEntry(lambda) { override val useAutoEvaluatedNumberOfMeasure: Boolean = false } class BenchmarksCollection(private val benchmarks: MutableMap = mutableMapOf()) : MutableMap by benchmarks ================================================ FILE: performance/shared/src/main/kotlin/org/jetbrains/benchmarksLauncher/JsonReportCreator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import org.jetbrains.report.BenchmarkResult class JsonReportCreator(val data: Iterable) { fun printJsonReport(jsonReport: String?): Unit { val reportText = data.joinToString(prefix = "[", postfix = "]") { it.toJson() } jsonReport?.let { writeToFile(it, reportText) } ?: print(reportText) } } ================================================ FILE: performance/shared/src/main/kotlin/org/jetbrains/benchmarksLauncher/SwiftLauncher.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.benchmarksLauncher.* import kotlinx.cli.* class SwiftLauncher: Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( ) ) } ================================================ FILE: performance/shared/src/main/kotlin/org/jetbrains/benchmarksLauncher/Utils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher expect fun writeToFile(fileName: String, text: String) expect fun assert(value: Boolean) expect inline fun measureNanoTime(block: () -> Unit): Long expect fun cleanup() expect fun printStderr(message: String) expect fun currentTime(): String expect fun nanoTime(): Long expect class Blackhole { companion object { var consumer: Int fun consume(value: Any) } } expect class Random() { companion object { var seedInt: Int fun nextInt(boundary: Int = 100): Int var seedDouble: Double fun nextDouble(boundary: Double = 100.0): Double } } ================================================ FILE: performance/shared/src/main/kotlin/org/jetbrains/benchmarksLauncher/launcher.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:OptIn(ExperimentalCli::class) package org.jetbrains.benchmarksLauncher import org.jetbrains.report.BenchmarkResult import kotlinx.cli.* data class RecordTimeMeasurement( val status: BenchmarkResult.Status, val iteration: Int, val warmupCount: Int, val durationNs: Double) abstract class Launcher { abstract val benchmarks: BenchmarksCollection fun add(name: String, benchmark: AbstractBenchmarkEntry) { benchmarks[name] = benchmark } fun runBenchmark(benchmarkInstance: Any?, benchmark: AbstractBenchmarkEntry, repeatNumber: Int): Long { var i = repeatNumber return if (benchmark is BenchmarkEntryWithInit) { cleanup() measureNanoTime { while (i-- > 0) benchmark.lambda(benchmarkInstance!!) cleanup() } } else if (benchmark is BenchmarkEntry) { cleanup() measureNanoTime { while (i-- > 0) benchmark.lambda() cleanup() } } else if (benchmark is BenchmarkEntryManual) { error("runBenchmark cannot run manual benchmark") } else { error("Unknown benchmark type $benchmark") } } enum class LogLevel { DEBUG, OFF } class Logger(val level: LogLevel = LogLevel.OFF) { fun log(message: String, messageLevel: LogLevel = LogLevel.DEBUG, usePrefix: Boolean = true) { if (messageLevel == level) { if (usePrefix) { printStderr("[$level][${currentTime()}] $message") } else { printStderr("$message") } } } } fun runBenchmark(logger: Logger, numWarmIterations: Int, numberOfAttempts: Int, name: String, recordMeasurement: (RecordTimeMeasurement) -> Unit, benchmark: AbstractBenchmarkEntry) { val benchmarkInstance = (benchmark as? BenchmarkEntryWithInit)?.ctor?.invoke() logger.log("Warm up iterations for benchmark $name\n") runBenchmark(benchmarkInstance, benchmark, numWarmIterations) val expectedDuration = 1000L * 1_000_000 // 1s var autoEvaluatedNumberOfMeasureIteration = 1 if (benchmark.useAutoEvaluatedNumberOfMeasure) { val time = runBenchmark(benchmarkInstance, benchmark, 1) if (time < expectedDuration) // Made auto evaluated number of measurements to be a multiple of 4. // Loops which iteration number is a multiple of 4 execute optimally, // because of different optimizations on processor (e.g. LSD) autoEvaluatedNumberOfMeasureIteration = ((expectedDuration / time).toInt() / 4 + 1) * 4 } logger.log("Running benchmark $name ") for (k in 0.until(numberOfAttempts)) { logger.log(".", usePrefix = false) var i = autoEvaluatedNumberOfMeasureIteration val time = runBenchmark(benchmarkInstance, benchmark, i) val scaledTime = time * 1.0 / autoEvaluatedNumberOfMeasureIteration // Save benchmark object recordMeasurement(RecordTimeMeasurement(BenchmarkResult.Status.PASSED, k, numWarmIterations, scaledTime)) } logger.log("\n", usePrefix = false) } fun launch(numWarmIterations: Int, numberOfAttempts: Int, prefix: String = "", filters: Collection? = null, filterRegexes: Collection? = null, verbose: Boolean): List { val logger = if (verbose) Logger(LogLevel.DEBUG) else Logger() val regexes = filterRegexes?.map { it.toRegex() } ?: listOf() val filterSet = filters?.toHashSet() ?: hashSetOf() // Filter benchmarks using given filters, or run all benchmarks if none were given. val runningBenchmarks = if (filterSet.isNotEmpty() || regexes.isNotEmpty()) { benchmarks.filterKeys { benchmark -> benchmark in filterSet || regexes.any { it.matches(benchmark) } } } else benchmarks if (runningBenchmarks.isEmpty()) { printStderr("No matching benchmarks found\n") error("No matching benchmarks found") } val benchmarkResults = mutableListOf() for ((name, benchmark) in runningBenchmarks) { val recordMeasurement : (RecordTimeMeasurement) -> Unit = { benchmarkResults.add(BenchmarkResult( "$prefix$name", it.status, it.durationNs / 1000, BenchmarkResult.Metric.EXECUTION_TIME, it.durationNs / 1000, it.iteration + 1, it.warmupCount)) } try { runBenchmark(logger, numWarmIterations, numberOfAttempts, name, recordMeasurement, benchmark) } catch (e: Throwable) { printStderr("Failure while running benchmark $name: $e\n") benchmarkResults.add(BenchmarkResult( "$prefix$name", BenchmarkResult.Status.FAILED, 0.0, BenchmarkResult.Metric.EXECUTION_TIME, 0.0, numberOfAttempts, numWarmIterations) ) } } return benchmarkResults } fun benchmarksListAction() { benchmarks.keys.forEach { println(it) } } } abstract class BenchmarkArguments(argParser: ArgParser) class BaseBenchmarkArguments(argParser: ArgParser): BenchmarkArguments(argParser) { val warmup by argParser.option(ArgType.Int, shortName = "w", description = "Number of warm up iterations") .default(20) val repeat by argParser.option(ArgType.Int, shortName = "r", description = "Number of each benchmark run"). default(60) val prefix by argParser.option(ArgType.String, shortName = "p", description = "Prefix added to benchmark name") .default("") val output by argParser.option(ArgType.String, shortName = "o", description = "Output file") val filter by argParser.option(ArgType.String, shortName = "f", description = "Benchmark to run").multiple() val filterRegex by argParser.option(ArgType.String, shortName = "fr", description = "Benchmark to run, described by a regular expression").multiple() val verbose by argParser.option(ArgType.Boolean, shortName = "v", description = "Verbose mode of running") .default(false) } object BenchmarksRunner { fun parse(args: Array, benchmarksListAction: ()->Unit): BenchmarkArguments? { class List: Subcommand("list", "Show list of benchmarks") { override fun execute() { benchmarksListAction() } } // Parse args. val argParser = ArgParser("benchmark") argParser.subcommands(List()) val argumentsValues = BaseBenchmarkArguments(argParser) return if (argParser.parse(args).commandName == "benchmark") argumentsValues else null } fun collect(results: List, arguments: BenchmarkArguments) { if (arguments is BaseBenchmarkArguments) { JsonReportCreator(results).printJsonReport(arguments.output) } } fun runBenchmarks(args: Array, run: (parser: BenchmarkArguments) -> List, parseArgs: (args: Array, benchmarksListAction: ()->Unit) -> BenchmarkArguments? = this::parse, collect: (results: List, arguments: BenchmarkArguments) -> Unit = this::collect, benchmarksListAction: ()->Unit) { val arguments = parseArgs(args, benchmarksListAction) arguments?.let { val results = run(arguments) collect(results, arguments) } } } ================================================ FILE: performance/shared/src/main/kotlin-jvm/org/jetbrains/benchmarksLauncher/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import java.io.File import java.text.SimpleDateFormat import java.util.Date actual fun writeToFile(fileName: String, text: String) { File(fileName).printWriter().use { out -> out.println(text) } } // Wrapper for assert funtion in stdlib. actual fun assert(value: Boolean) { kotlin.assert(value) } // Wrapper for measureNanoTime funtion in stdlib. actual inline fun measureNanoTime(block: () -> Unit): Long { return kotlin.system.measureNanoTime(block) } actual fun cleanup() {} actual fun printStderr(message: String) { System.err.print(message) } actual fun currentTime(): String = SimpleDateFormat("HH:mm:ss").format(Date()) actual fun nanoTime(): Long = System.nanoTime() actual class Blackhole { actual companion object { actual var consumer = 0 actual fun consume(value: Any) { consumer += value.hashCode() } } } actual class Random actual constructor() { actual companion object { actual var seedInt = 0 actual fun nextInt(boundary: Int): Int { seedInt = (3 * seedInt + 11) % boundary return seedInt } actual var seedDouble: Double = 0.1 actual fun nextDouble(boundary: Double): Double { seedDouble = (7.0 * seedDouble + 7.0) % boundary return seedDouble } } } ================================================ FILE: performance/shared/src/main/kotlin-native/common/org/jetbrains/benchmarksLauncher/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import kotlin.native.internal.GC import platform.posix.* import kotlinx.cinterop.* actual fun writeToFile(fileName: String, text: String) { val file = fopen(fileName, "wt") ?: error("Cannot write file '$fileName'") try { if (fputs(text, file) == EOF) throw Error("File write error") } finally { fclose(file) } } // Wrapper for assert funtion in stdlib actual fun assert(value: Boolean) { kotlin.assert(value) } // Wrapper for measureNanoTime funtion in stdlib actual inline fun measureNanoTime(block: () -> Unit): Long { return kotlin.system.measureNanoTime(block) } actual fun cleanup() { GC.collect() } actual fun printStderr(message: String) { val STDERR = fdopen(2, "w") fprintf(STDERR, message) fflush(STDERR) } actual fun nanoTime(): Long = kotlin.system.getTimeNanos() actual class Blackhole { @kotlin.native.ThreadLocal actual companion object { actual var consumer = 0 actual fun consume(value: Any) { consumer += value.hashCode() } } } actual class Random actual constructor() { @kotlin.native.ThreadLocal actual companion object { actual var seedInt = 0 actual fun nextInt(boundary: Int): Int { seedInt = (3 * seedInt + 11) % boundary return seedInt } actual var seedDouble: Double = 0.1 actual fun nextDouble(boundary: Double): Double { seedDouble = (7.0 * seedDouble + 7.0) % boundary return seedDouble } } } ================================================ FILE: performance/shared/src/main/kotlin-native/mingw/org/jetbrains/benchmarksLauncher/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import platform.posix.* import platform.windows.* import kotlinx.cinterop.* actual fun currentTime() = memScoped { val timeVal = alloc() mingw_gettimeofday(timeVal.ptr, null) val sec = alloc() sec.value = timeVal.tv_sec.convert() val nowtm = localtime(sec.ptr) var timeBuffer = ByteArray(1024) strftime(timeBuffer.refTo(0), timeBuffer.size.toULong(), "%H:%M:%S", nowtm) timeBuffer.toKString() } ================================================ FILE: performance/shared/src/main/kotlin-native/posix/org/jetbrains/benchmarksLauncher/Utils.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.benchmarksLauncher import platform.posix.* import kotlinx.cinterop.* actual fun currentTime() = memScoped { val timeVal = alloc() gettimeofday(timeVal.ptr, null) val sec = alloc() sec.value = timeVal.tv_sec val nowtm = localtime(sec.ptr) var timeBuffer = ByteArray(1024) strftime(timeBuffer.refTo(0), timeBuffer.size.toULong(), "%H:%M:%S", nowtm) timeBuffer.toKString() } ================================================ FILE: performance/startup/build.gradle.kts ================================================ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.RunKotlinNativeTask import org.jetbrains.kotlin.BenchmarkRepeatingType /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ plugins { id("benchmarking") } val defaultBuildType = NativeBuildType.RELEASE benchmark { applicationName = "Startup" commonSrcDirs = listOf("../../tools/benchmarks/shared/src/main/kotlin/report", "src/main/kotlin", "../shared/src/main/kotlin") jvmSrcDirs = listOf("../shared/src/main/kotlin-jvm") nativeSrcDirs = listOf("../shared/src/main/kotlin-native/common") mingwSrcDirs = listOf("../shared/src/main/kotlin-native/mingw") posixSrcDirs = listOf("../shared/src/main/kotlin-native/posix") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType repeatingType = BenchmarkRepeatingType.EXTERNAL } ================================================ FILE: performance/startup/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/startup/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.startup.* import org.jetbrains.benchmarksLauncher.* import kotlinx.cli.* class StartupLauncher : Launcher() { override val benchmarks = BenchmarksCollection( mutableMapOf( "Singleton.initialize" to BenchmarkEntryManual(::singletonInitialize), "Singleton.initializeNested" to BenchmarkEntryManual(::singletonInitializeNested), ) ) } fun main(args: Array) { val launcher = StartupLauncher() BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> if (arguments is BaseBenchmarkArguments) { launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, arguments.filter, arguments.filterRegex, arguments.verbose) } else emptyList() }, benchmarksListAction = launcher::benchmarksListAction) } ================================================ FILE: performance/startup/src/main/kotlin/org/jetbrains/startup/SingletonInitBenchmark.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.startup import org.jetbrains.benchmarksLauncher.measureNanoTime import org.jetbrains.benchmarksLauncher.Random import org.jetbrains.report.BenchmarkResult private object A0 { val a = Random.nextInt(100) } private object A1 { val a = Random.nextInt(100) } private object A2 { val a = Random.nextInt(100) } private object A3 { val a = Random.nextInt(100) } private object A4 { val a = Random.nextInt(100) } private object A5 { val a = Random.nextInt(100) } private object A6 { val a = Random.nextInt(100) } private object A7 { val a = Random.nextInt(100) } private object A8 { val a = Random.nextInt(100) } private object A9 { val a = Random.nextInt(100) } private object A10 { val a = Random.nextInt(100) } private object A11 { val a = Random.nextInt(100) } private object A12 { val a = Random.nextInt(100) } private object A13 { val a = Random.nextInt(100) } private object A14 { val a = Random.nextInt(100) } private object A15 { val a = Random.nextInt(100) } private object A16 { val a = Random.nextInt(100) } private object A17 { val a = Random.nextInt(100) } private object A18 { val a = Random.nextInt(100) } private object A19 { val a = Random.nextInt(100) } private object A20 { val a = Random.nextInt(100) } private object A21 { val a = Random.nextInt(100) } private object A22 { val a = Random.nextInt(100) } private object A23 { val a = Random.nextInt(100) } private object A24 { val a = Random.nextInt(100) } private object A25 { val a = Random.nextInt(100) } private object A26 { val a = Random.nextInt(100) } private object A27 { val a = Random.nextInt(100) } private object A28 { val a = Random.nextInt(100) } private object A29 { val a = Random.nextInt(100) } private object A30 { val a = Random.nextInt(100) } private object A31 { val a = Random.nextInt(100) } private object A32 { val a = Random.nextInt(100) } private object A33 { val a = Random.nextInt(100) } private object A34 { val a = Random.nextInt(100) } private object A35 { val a = Random.nextInt(100) } private object A36 { val a = Random.nextInt(100) } private object A37 { val a = Random.nextInt(100) } private object A38 { val a = Random.nextInt(100) } private object A39 { val a = Random.nextInt(100) } private object A40 { val a = Random.nextInt(100) } private object A41 { val a = Random.nextInt(100) } private object A42 { val a = Random.nextInt(100) } private object A43 { val a = Random.nextInt(100) } private object A44 { val a = Random.nextInt(100) } private object A45 { val a = Random.nextInt(100) } private object A46 { val a = Random.nextInt(100) } private object A47 { val a = Random.nextInt(100) } private object A48 { val a = Random.nextInt(100) } private object A49 { val a = Random.nextInt(100) } private object A50 { val a = Random.nextInt(100) } private object A51 { val a = Random.nextInt(100) } private object A52 { val a = Random.nextInt(100) } private object A53 { val a = Random.nextInt(100) } private object A54 { val a = Random.nextInt(100) } private object A55 { val a = Random.nextInt(100) } private object A56 { val a = Random.nextInt(100) } private object A57 { val a = Random.nextInt(100) } private object A58 { val a = Random.nextInt(100) } private object A59 { val a = Random.nextInt(100) } private object A60 { val a = Random.nextInt(100) } private object A61 { val a = Random.nextInt(100) } private object A62 { val a = Random.nextInt(100) } private object A63 { val a = Random.nextInt(100) } private object A64 { val a = Random.nextInt(100) } private object A65 { val a = Random.nextInt(100) } private object A66 { val a = Random.nextInt(100) } private object A67 { val a = Random.nextInt(100) } private object A68 { val a = Random.nextInt(100) } private object A69 { val a = Random.nextInt(100) } private object A70 { val a = Random.nextInt(100) } private object A71 { val a = Random.nextInt(100) } private object A72 { val a = Random.nextInt(100) } private object A73 { val a = Random.nextInt(100) } private object A74 { val a = Random.nextInt(100) } private object A75 { val a = Random.nextInt(100) } private object A76 { val a = Random.nextInt(100) } private object A77 { val a = Random.nextInt(100) } private object A78 { val a = Random.nextInt(100) } private object A79 { val a = Random.nextInt(100) } private object A80 { val a = Random.nextInt(100) } private object A81 { val a = Random.nextInt(100) } private object A82 { val a = Random.nextInt(100) } private object A83 { val a = Random.nextInt(100) } private object A84 { val a = Random.nextInt(100) } private object A85 { val a = Random.nextInt(100) } private object A86 { val a = Random.nextInt(100) } private object A87 { val a = Random.nextInt(100) } private object A88 { val a = Random.nextInt(100) } private object A89 { val a = Random.nextInt(100) } private object A90 { val a = Random.nextInt(100) } private object A91 { val a = Random.nextInt(100) } private object A92 { val a = Random.nextInt(100) } private object A93 { val a = Random.nextInt(100) } private object A94 { val a = Random.nextInt(100) } private object A95 { val a = Random.nextInt(100) } private object A96 { val a = Random.nextInt(100) } private object A97 { val a = Random.nextInt(100) } private object A98 { val a = Random.nextInt(100) } private object A99 { val a = Random.nextInt(100) } private object A100 { val a = Random.nextInt(100) } private object A101 { val a = Random.nextInt(100) } private object A102 { val a = Random.nextInt(100) } private object A103 { val a = Random.nextInt(100) } private object A104 { val a = Random.nextInt(100) } private object A105 { val a = Random.nextInt(100) } private object A106 { val a = Random.nextInt(100) } private object A107 { val a = Random.nextInt(100) } private object A108 { val a = Random.nextInt(100) } private object A109 { val a = Random.nextInt(100) } private object A110 { val a = Random.nextInt(100) } private object A111 { val a = Random.nextInt(100) } private object A112 { val a = Random.nextInt(100) } private object A113 { val a = Random.nextInt(100) } private object A114 { val a = Random.nextInt(100) } private object A115 { val a = Random.nextInt(100) } private object A116 { val a = Random.nextInt(100) } private object A117 { val a = Random.nextInt(100) } private object A118 { val a = Random.nextInt(100) } private object A119 { val a = Random.nextInt(100) } private object A120 { val a = Random.nextInt(100) } private object A121 { val a = Random.nextInt(100) } private object A122 { val a = Random.nextInt(100) } private object A123 { val a = Random.nextInt(100) } private object A124 { val a = Random.nextInt(100) } private object A125 { val a = Random.nextInt(100) } private object A126 { val a = Random.nextInt(100) } private object A127 { val a = Random.nextInt(100) } private object A128 { val a = Random.nextInt(100) } private object A129 { val a = Random.nextInt(100) } private object A130 { val a = Random.nextInt(100) } private object A131 { val a = Random.nextInt(100) } private object A132 { val a = Random.nextInt(100) } private object A133 { val a = Random.nextInt(100) } private object A134 { val a = Random.nextInt(100) } private object A135 { val a = Random.nextInt(100) } private object A136 { val a = Random.nextInt(100) } private object A137 { val a = Random.nextInt(100) } private object A138 { val a = Random.nextInt(100) } private object A139 { val a = Random.nextInt(100) } private object A140 { val a = Random.nextInt(100) } private object A141 { val a = Random.nextInt(100) } private object A142 { val a = Random.nextInt(100) } private object A143 { val a = Random.nextInt(100) } private object A144 { val a = Random.nextInt(100) } private object A145 { val a = Random.nextInt(100) } private object A146 { val a = Random.nextInt(100) } private object A147 { val a = Random.nextInt(100) } private object A148 { val a = Random.nextInt(100) } private object A149 { val a = Random.nextInt(100) } private object A150 { val a = Random.nextInt(100) } private object A151 { val a = Random.nextInt(100) } private object A152 { val a = Random.nextInt(100) } private object A153 { val a = Random.nextInt(100) } private object A154 { val a = Random.nextInt(100) } private object A155 { val a = Random.nextInt(100) } private object A156 { val a = Random.nextInt(100) } private object A157 { val a = Random.nextInt(100) } private object A158 { val a = Random.nextInt(100) } private object A159 { val a = Random.nextInt(100) } private object A160 { val a = Random.nextInt(100) } private object A161 { val a = Random.nextInt(100) } private object A162 { val a = Random.nextInt(100) } private object A163 { val a = Random.nextInt(100) } private object A164 { val a = Random.nextInt(100) } private object A165 { val a = Random.nextInt(100) } private object A166 { val a = Random.nextInt(100) } private object A167 { val a = Random.nextInt(100) } private object A168 { val a = Random.nextInt(100) } private object A169 { val a = Random.nextInt(100) } private object A170 { val a = Random.nextInt(100) } private object A171 { val a = Random.nextInt(100) } private object A172 { val a = Random.nextInt(100) } private object A173 { val a = Random.nextInt(100) } private object A174 { val a = Random.nextInt(100) } private object A175 { val a = Random.nextInt(100) } private object A176 { val a = Random.nextInt(100) } private object A177 { val a = Random.nextInt(100) } private object A178 { val a = Random.nextInt(100) } private object A179 { val a = Random.nextInt(100) } private object A180 { val a = Random.nextInt(100) } private object A181 { val a = Random.nextInt(100) } private object A182 { val a = Random.nextInt(100) } private object A183 { val a = Random.nextInt(100) } private object A184 { val a = Random.nextInt(100) } private object A185 { val a = Random.nextInt(100) } private object A186 { val a = Random.nextInt(100) } private object A187 { val a = Random.nextInt(100) } private object A188 { val a = Random.nextInt(100) } private object A189 { val a = Random.nextInt(100) } private object A190 { val a = Random.nextInt(100) } private object A191 { val a = Random.nextInt(100) } private object A192 { val a = Random.nextInt(100) } private object A193 { val a = Random.nextInt(100) } private object A194 { val a = Random.nextInt(100) } private object A195 { val a = Random.nextInt(100) } private object A196 { val a = Random.nextInt(100) } private object A197 { val a = Random.nextInt(100) } private object A198 { val a = Random.nextInt(100) } private object A199 { val a = Random.nextInt(100) } private object A200 { val a = Random.nextInt(100) } private object A201 { val a = Random.nextInt(100) } private object A202 { val a = Random.nextInt(100) } private object A203 { val a = Random.nextInt(100) } private object A204 { val a = Random.nextInt(100) } private object A205 { val a = Random.nextInt(100) } private object A206 { val a = Random.nextInt(100) } private object A207 { val a = Random.nextInt(100) } private object A208 { val a = Random.nextInt(100) } private object A209 { val a = Random.nextInt(100) } private object A210 { val a = Random.nextInt(100) } private object A211 { val a = Random.nextInt(100) } private object A212 { val a = Random.nextInt(100) } private object A213 { val a = Random.nextInt(100) } private object A214 { val a = Random.nextInt(100) } private object A215 { val a = Random.nextInt(100) } private object A216 { val a = Random.nextInt(100) } private object A217 { val a = Random.nextInt(100) } private object A218 { val a = Random.nextInt(100) } private object A219 { val a = Random.nextInt(100) } private object A220 { val a = Random.nextInt(100) } private object A221 { val a = Random.nextInt(100) } private object A222 { val a = Random.nextInt(100) } private object A223 { val a = Random.nextInt(100) } private object A224 { val a = Random.nextInt(100) } private object A225 { val a = Random.nextInt(100) } private object A226 { val a = Random.nextInt(100) } private object A227 { val a = Random.nextInt(100) } private object A228 { val a = Random.nextInt(100) } private object A229 { val a = Random.nextInt(100) } private object A230 { val a = Random.nextInt(100) } private object A231 { val a = Random.nextInt(100) } private object A232 { val a = Random.nextInt(100) } private object A233 { val a = Random.nextInt(100) } private object A234 { val a = Random.nextInt(100) } private object A235 { val a = Random.nextInt(100) } private object A236 { val a = Random.nextInt(100) } private object A237 { val a = Random.nextInt(100) } private object A238 { val a = Random.nextInt(100) } private object A239 { val a = Random.nextInt(100) } private object A240 { val a = Random.nextInt(100) } private object A241 { val a = Random.nextInt(100) } private object A242 { val a = Random.nextInt(100) } private object A243 { val a = Random.nextInt(100) } private object A244 { val a = Random.nextInt(100) } private object A245 { val a = Random.nextInt(100) } private object A246 { val a = Random.nextInt(100) } private object A247 { val a = Random.nextInt(100) } private object A248 { val a = Random.nextInt(100) } private object A249 { val a = Random.nextInt(100) } private object A250 { val a = Random.nextInt(100) } private object A251 { val a = Random.nextInt(100) } private object A252 { val a = Random.nextInt(100) } private object A253 { val a = Random.nextInt(100) } private object A254 { val a = Random.nextInt(100) } private object A255 { val a = Random.nextInt(100) } private object A256 { val a = Random.nextInt(100) } private object A257 { val a = Random.nextInt(100) } private object A258 { val a = Random.nextInt(100) } private object A259 { val a = Random.nextInt(100) } private object A260 { val a = Random.nextInt(100) } private object A261 { val a = Random.nextInt(100) } private object A262 { val a = Random.nextInt(100) } private object A263 { val a = Random.nextInt(100) } private object A264 { val a = Random.nextInt(100) } private object A265 { val a = Random.nextInt(100) } private object A266 { val a = Random.nextInt(100) } private object A267 { val a = Random.nextInt(100) } private object A268 { val a = Random.nextInt(100) } private object A269 { val a = Random.nextInt(100) } private object A270 { val a = Random.nextInt(100) } private object A271 { val a = Random.nextInt(100) } private object A272 { val a = Random.nextInt(100) } private object A273 { val a = Random.nextInt(100) } private object A274 { val a = Random.nextInt(100) } private object A275 { val a = Random.nextInt(100) } private object A276 { val a = Random.nextInt(100) } private object A277 { val a = Random.nextInt(100) } private object A278 { val a = Random.nextInt(100) } private object A279 { val a = Random.nextInt(100) } private object A280 { val a = Random.nextInt(100) } private object A281 { val a = Random.nextInt(100) } private object A282 { val a = Random.nextInt(100) } private object A283 { val a = Random.nextInt(100) } private object A284 { val a = Random.nextInt(100) } private object A285 { val a = Random.nextInt(100) } private object A286 { val a = Random.nextInt(100) } private object A287 { val a = Random.nextInt(100) } private object A288 { val a = Random.nextInt(100) } private object A289 { val a = Random.nextInt(100) } private object A290 { val a = Random.nextInt(100) } private object A291 { val a = Random.nextInt(100) } private object A292 { val a = Random.nextInt(100) } private object A293 { val a = Random.nextInt(100) } private object A294 { val a = Random.nextInt(100) } private object A295 { val a = Random.nextInt(100) } private object A296 { val a = Random.nextInt(100) } private object A297 { val a = Random.nextInt(100) } private object A298 { val a = Random.nextInt(100) } private object A299 { val a = Random.nextInt(100) } private object A300 { val a = Random.nextInt(100) } private object A301 { val a = Random.nextInt(100) } private object A302 { val a = Random.nextInt(100) } private object A303 { val a = Random.nextInt(100) } private object A304 { val a = Random.nextInt(100) } private object A305 { val a = Random.nextInt(100) } private object A306 { val a = Random.nextInt(100) } private object A307 { val a = Random.nextInt(100) } private object A308 { val a = Random.nextInt(100) } private object A309 { val a = Random.nextInt(100) } private object A310 { val a = Random.nextInt(100) } private object A311 { val a = Random.nextInt(100) } private object A312 { val a = Random.nextInt(100) } private object A313 { val a = Random.nextInt(100) } private object A314 { val a = Random.nextInt(100) } private object A315 { val a = Random.nextInt(100) } private object A316 { val a = Random.nextInt(100) } private object A317 { val a = Random.nextInt(100) } private object A318 { val a = Random.nextInt(100) } private object A319 { val a = Random.nextInt(100) } private object A320 { val a = Random.nextInt(100) } private object A321 { val a = Random.nextInt(100) } private object A322 { val a = Random.nextInt(100) } private object A323 { val a = Random.nextInt(100) } private object A324 { val a = Random.nextInt(100) } private object A325 { val a = Random.nextInt(100) } private object A326 { val a = Random.nextInt(100) } private object A327 { val a = Random.nextInt(100) } private object A328 { val a = Random.nextInt(100) } private object A329 { val a = Random.nextInt(100) } private object A330 { val a = Random.nextInt(100) } private object A331 { val a = Random.nextInt(100) } private object A332 { val a = Random.nextInt(100) } private object A333 { val a = Random.nextInt(100) } private object A334 { val a = Random.nextInt(100) } private object A335 { val a = Random.nextInt(100) } private object A336 { val a = Random.nextInt(100) } private object A337 { val a = Random.nextInt(100) } private object A338 { val a = Random.nextInt(100) } private object A339 { val a = Random.nextInt(100) } private object A340 { val a = Random.nextInt(100) } private object A341 { val a = Random.nextInt(100) } private object A342 { val a = Random.nextInt(100) } private object A343 { val a = Random.nextInt(100) } private object A344 { val a = Random.nextInt(100) } private object A345 { val a = Random.nextInt(100) } private object A346 { val a = Random.nextInt(100) } private object A347 { val a = Random.nextInt(100) } private object A348 { val a = Random.nextInt(100) } private object A349 { val a = Random.nextInt(100) } private object A350 { val a = Random.nextInt(100) } private object A351 { val a = Random.nextInt(100) } private object A352 { val a = Random.nextInt(100) } private object A353 { val a = Random.nextInt(100) } private object A354 { val a = Random.nextInt(100) } private object A355 { val a = Random.nextInt(100) } private object A356 { val a = Random.nextInt(100) } private object A357 { val a = Random.nextInt(100) } private object A358 { val a = Random.nextInt(100) } private object A359 { val a = Random.nextInt(100) } private object A360 { val a = Random.nextInt(100) } private object A361 { val a = Random.nextInt(100) } private object A362 { val a = Random.nextInt(100) } private object A363 { val a = Random.nextInt(100) } private object A364 { val a = Random.nextInt(100) } private object A365 { val a = Random.nextInt(100) } private object A366 { val a = Random.nextInt(100) } private object A367 { val a = Random.nextInt(100) } private object A368 { val a = Random.nextInt(100) } private object A369 { val a = Random.nextInt(100) } private object A370 { val a = Random.nextInt(100) } private object A371 { val a = Random.nextInt(100) } private object A372 { val a = Random.nextInt(100) } private object A373 { val a = Random.nextInt(100) } private object A374 { val a = Random.nextInt(100) } private object A375 { val a = Random.nextInt(100) } private object A376 { val a = Random.nextInt(100) } private object A377 { val a = Random.nextInt(100) } private object A378 { val a = Random.nextInt(100) } private object A379 { val a = Random.nextInt(100) } private object A380 { val a = Random.nextInt(100) } private object A381 { val a = Random.nextInt(100) } private object A382 { val a = Random.nextInt(100) } private object A383 { val a = Random.nextInt(100) } private object A384 { val a = Random.nextInt(100) } private object A385 { val a = Random.nextInt(100) } private object A386 { val a = Random.nextInt(100) } private object A387 { val a = Random.nextInt(100) } private object A388 { val a = Random.nextInt(100) } private object A389 { val a = Random.nextInt(100) } private object A390 { val a = Random.nextInt(100) } private object A391 { val a = Random.nextInt(100) } private object A392 { val a = Random.nextInt(100) } private object A393 { val a = Random.nextInt(100) } private object A394 { val a = Random.nextInt(100) } private object A395 { val a = Random.nextInt(100) } private object A396 { val a = Random.nextInt(100) } private object A397 { val a = Random.nextInt(100) } private object A398 { val a = Random.nextInt(100) } private object A399 { val a = Random.nextInt(100) } private object A400 { val a = Random.nextInt(100) } private object A401 { val a = Random.nextInt(100) } private object A402 { val a = Random.nextInt(100) } private object A403 { val a = Random.nextInt(100) } private object A404 { val a = Random.nextInt(100) } private object A405 { val a = Random.nextInt(100) } private object A406 { val a = Random.nextInt(100) } private object A407 { val a = Random.nextInt(100) } private object A408 { val a = Random.nextInt(100) } private object A409 { val a = Random.nextInt(100) } private object A410 { val a = Random.nextInt(100) } private object A411 { val a = Random.nextInt(100) } private object A412 { val a = Random.nextInt(100) } private object A413 { val a = Random.nextInt(100) } private object A414 { val a = Random.nextInt(100) } private object A415 { val a = Random.nextInt(100) } private object A416 { val a = Random.nextInt(100) } private object A417 { val a = Random.nextInt(100) } private object A418 { val a = Random.nextInt(100) } private object A419 { val a = Random.nextInt(100) } private object A420 { val a = Random.nextInt(100) } private object A421 { val a = Random.nextInt(100) } private object A422 { val a = Random.nextInt(100) } private object A423 { val a = Random.nextInt(100) } private object A424 { val a = Random.nextInt(100) } private object A425 { val a = Random.nextInt(100) } private object A426 { val a = Random.nextInt(100) } private object A427 { val a = Random.nextInt(100) } private object A428 { val a = Random.nextInt(100) } private object A429 { val a = Random.nextInt(100) } private object A430 { val a = Random.nextInt(100) } private object A431 { val a = Random.nextInt(100) } private object A432 { val a = Random.nextInt(100) } private object A433 { val a = Random.nextInt(100) } private object A434 { val a = Random.nextInt(100) } private object A435 { val a = Random.nextInt(100) } private object A436 { val a = Random.nextInt(100) } private object A437 { val a = Random.nextInt(100) } private object A438 { val a = Random.nextInt(100) } private object A439 { val a = Random.nextInt(100) } private object A440 { val a = Random.nextInt(100) } private object A441 { val a = Random.nextInt(100) } private object A442 { val a = Random.nextInt(100) } private object A443 { val a = Random.nextInt(100) } private object A444 { val a = Random.nextInt(100) } private object A445 { val a = Random.nextInt(100) } private object A446 { val a = Random.nextInt(100) } private object A447 { val a = Random.nextInt(100) } private object A448 { val a = Random.nextInt(100) } private object A449 { val a = Random.nextInt(100) } private object A450 { val a = Random.nextInt(100) } private object A451 { val a = Random.nextInt(100) } private object A452 { val a = Random.nextInt(100) } private object A453 { val a = Random.nextInt(100) } private object A454 { val a = Random.nextInt(100) } private object A455 { val a = Random.nextInt(100) } private object A456 { val a = Random.nextInt(100) } private object A457 { val a = Random.nextInt(100) } private object A458 { val a = Random.nextInt(100) } private object A459 { val a = Random.nextInt(100) } private object A460 { val a = Random.nextInt(100) } private object A461 { val a = Random.nextInt(100) } private object A462 { val a = Random.nextInt(100) } private object A463 { val a = Random.nextInt(100) } private object A464 { val a = Random.nextInt(100) } private object A465 { val a = Random.nextInt(100) } private object A466 { val a = Random.nextInt(100) } private object A467 { val a = Random.nextInt(100) } private object A468 { val a = Random.nextInt(100) } private object A469 { val a = Random.nextInt(100) } private object A470 { val a = Random.nextInt(100) } private object A471 { val a = Random.nextInt(100) } private object A472 { val a = Random.nextInt(100) } private object A473 { val a = Random.nextInt(100) } private object A474 { val a = Random.nextInt(100) } private object A475 { val a = Random.nextInt(100) } private object A476 { val a = Random.nextInt(100) } private object A477 { val a = Random.nextInt(100) } private object A478 { val a = Random.nextInt(100) } private object A479 { val a = Random.nextInt(100) } private object A480 { val a = Random.nextInt(100) } private object A481 { val a = Random.nextInt(100) } private object A482 { val a = Random.nextInt(100) } private object A483 { val a = Random.nextInt(100) } private object A484 { val a = Random.nextInt(100) } private object A485 { val a = Random.nextInt(100) } private object A486 { val a = Random.nextInt(100) } private object A487 { val a = Random.nextInt(100) } private object A488 { val a = Random.nextInt(100) } private object A489 { val a = Random.nextInt(100) } private object A490 { val a = Random.nextInt(100) } private object A491 { val a = Random.nextInt(100) } private object A492 { val a = Random.nextInt(100) } private object A493 { val a = Random.nextInt(100) } private object A494 { val a = Random.nextInt(100) } private object A495 { val a = Random.nextInt(100) } private object A496 { val a = Random.nextInt(100) } private object A497 { val a = Random.nextInt(100) } private object A498 { val a = Random.nextInt(100) } private object A499 { val a = Random.nextInt(100) } private var singletonInitializeRun = false // Benchmark fun singletonInitialize(): Int { if (singletonInitializeRun) { error("Function singletonInitialize can be called only once.") } singletonInitializeRun = true var total = 0 total += A0.a total += A1.a total += A2.a total += A3.a total += A4.a total += A5.a total += A6.a total += A7.a total += A8.a total += A9.a total += A10.a total += A11.a total += A12.a total += A13.a total += A14.a total += A15.a total += A16.a total += A17.a total += A18.a total += A19.a total += A20.a total += A21.a total += A22.a total += A23.a total += A24.a total += A25.a total += A26.a total += A27.a total += A28.a total += A29.a total += A30.a total += A31.a total += A32.a total += A33.a total += A34.a total += A35.a total += A36.a total += A37.a total += A38.a total += A39.a total += A40.a total += A41.a total += A42.a total += A43.a total += A44.a total += A45.a total += A46.a total += A47.a total += A48.a total += A49.a total += A50.a total += A51.a total += A52.a total += A53.a total += A54.a total += A55.a total += A56.a total += A57.a total += A58.a total += A59.a total += A60.a total += A61.a total += A62.a total += A63.a total += A64.a total += A65.a total += A66.a total += A67.a total += A68.a total += A69.a total += A70.a total += A71.a total += A72.a total += A73.a total += A74.a total += A75.a total += A76.a total += A77.a total += A78.a total += A79.a total += A80.a total += A81.a total += A82.a total += A83.a total += A84.a total += A85.a total += A86.a total += A87.a total += A88.a total += A89.a total += A90.a total += A91.a total += A92.a total += A93.a total += A94.a total += A95.a total += A96.a total += A97.a total += A98.a total += A99.a total += A100.a total += A101.a total += A102.a total += A103.a total += A104.a total += A105.a total += A106.a total += A107.a total += A108.a total += A109.a total += A110.a total += A111.a total += A112.a total += A113.a total += A114.a total += A115.a total += A116.a total += A117.a total += A118.a total += A119.a total += A120.a total += A121.a total += A122.a total += A123.a total += A124.a total += A125.a total += A126.a total += A127.a total += A128.a total += A129.a total += A130.a total += A131.a total += A132.a total += A133.a total += A134.a total += A135.a total += A136.a total += A137.a total += A138.a total += A139.a total += A140.a total += A141.a total += A142.a total += A143.a total += A144.a total += A145.a total += A146.a total += A147.a total += A148.a total += A149.a total += A150.a total += A151.a total += A152.a total += A153.a total += A154.a total += A155.a total += A156.a total += A157.a total += A158.a total += A159.a total += A160.a total += A161.a total += A162.a total += A163.a total += A164.a total += A165.a total += A166.a total += A167.a total += A168.a total += A169.a total += A170.a total += A171.a total += A172.a total += A173.a total += A174.a total += A175.a total += A176.a total += A177.a total += A178.a total += A179.a total += A180.a total += A181.a total += A182.a total += A183.a total += A184.a total += A185.a total += A186.a total += A187.a total += A188.a total += A189.a total += A190.a total += A191.a total += A192.a total += A193.a total += A194.a total += A195.a total += A196.a total += A197.a total += A198.a total += A199.a total += A200.a total += A201.a total += A202.a total += A203.a total += A204.a total += A205.a total += A206.a total += A207.a total += A208.a total += A209.a total += A210.a total += A211.a total += A212.a total += A213.a total += A214.a total += A215.a total += A216.a total += A217.a total += A218.a total += A219.a total += A220.a total += A221.a total += A222.a total += A223.a total += A224.a total += A225.a total += A226.a total += A227.a total += A228.a total += A229.a total += A230.a total += A231.a total += A232.a total += A233.a total += A234.a total += A235.a total += A236.a total += A237.a total += A238.a total += A239.a total += A240.a total += A241.a total += A242.a total += A243.a total += A244.a total += A245.a total += A246.a total += A247.a total += A248.a total += A249.a total += A250.a total += A251.a total += A252.a total += A253.a total += A254.a total += A255.a total += A256.a total += A257.a total += A258.a total += A259.a total += A260.a total += A261.a total += A262.a total += A263.a total += A264.a total += A265.a total += A266.a total += A267.a total += A268.a total += A269.a total += A270.a total += A271.a total += A272.a total += A273.a total += A274.a total += A275.a total += A276.a total += A277.a total += A278.a total += A279.a total += A280.a total += A281.a total += A282.a total += A283.a total += A284.a total += A285.a total += A286.a total += A287.a total += A288.a total += A289.a total += A290.a total += A291.a total += A292.a total += A293.a total += A294.a total += A295.a total += A296.a total += A297.a total += A298.a total += A299.a total += A300.a total += A301.a total += A302.a total += A303.a total += A304.a total += A305.a total += A306.a total += A307.a total += A308.a total += A309.a total += A310.a total += A311.a total += A312.a total += A313.a total += A314.a total += A315.a total += A316.a total += A317.a total += A318.a total += A319.a total += A320.a total += A321.a total += A322.a total += A323.a total += A324.a total += A325.a total += A326.a total += A327.a total += A328.a total += A329.a total += A330.a total += A331.a total += A332.a total += A333.a total += A334.a total += A335.a total += A336.a total += A337.a total += A338.a total += A339.a total += A340.a total += A341.a total += A342.a total += A343.a total += A344.a total += A345.a total += A346.a total += A347.a total += A348.a total += A349.a total += A350.a total += A351.a total += A352.a total += A353.a total += A354.a total += A355.a total += A356.a total += A357.a total += A358.a total += A359.a total += A360.a total += A361.a total += A362.a total += A363.a total += A364.a total += A365.a total += A366.a total += A367.a total += A368.a total += A369.a total += A370.a total += A371.a total += A372.a total += A373.a total += A374.a total += A375.a total += A376.a total += A377.a total += A378.a total += A379.a total += A380.a total += A381.a total += A382.a total += A383.a total += A384.a total += A385.a total += A386.a total += A387.a total += A388.a total += A389.a total += A390.a total += A391.a total += A392.a total += A393.a total += A394.a total += A395.a total += A396.a total += A397.a total += A398.a total += A399.a total += A400.a total += A401.a total += A402.a total += A403.a total += A404.a total += A405.a total += A406.a total += A407.a total += A408.a total += A409.a total += A410.a total += A411.a total += A412.a total += A413.a total += A414.a total += A415.a total += A416.a total += A417.a total += A418.a total += A419.a total += A420.a total += A421.a total += A422.a total += A423.a total += A424.a total += A425.a total += A426.a total += A427.a total += A428.a total += A429.a total += A430.a total += A431.a total += A432.a total += A433.a total += A434.a total += A435.a total += A436.a total += A437.a total += A438.a total += A439.a total += A440.a total += A441.a total += A442.a total += A443.a total += A444.a total += A445.a total += A446.a total += A447.a total += A448.a total += A449.a total += A450.a total += A451.a total += A452.a total += A453.a total += A454.a total += A455.a total += A456.a total += A457.a total += A458.a total += A459.a total += A460.a total += A461.a total += A462.a total += A463.a total += A464.a total += A465.a total += A466.a total += A467.a total += A468.a total += A469.a total += A470.a total += A471.a total += A472.a total += A473.a total += A474.a total += A475.a total += A476.a total += A477.a total += A478.a total += A479.a total += A480.a total += A481.a total += A482.a total += A483.a total += A484.a total += A485.a total += A486.a total += A487.a total += A488.a total += A489.a total += A490.a total += A491.a total += A492.a total += A493.a total += A494.a total += A495.a total += A496.a total += A497.a total += A498.a total += A499.a return total } private object B0 { val a = Random.nextInt(100) } private object B1 { val a = B0.a + Random.nextInt(100) } private object B2 { val a = B1.a + Random.nextInt(100) } private object B3 { val a = B2.a + Random.nextInt(100) } private object B4 { val a = B3.a + Random.nextInt(100) } private object B5 { val a = B4.a + Random.nextInt(100) } private object B6 { val a = B5.a + Random.nextInt(100) } private object B7 { val a = B6.a + Random.nextInt(100) } private object B8 { val a = B7.a + Random.nextInt(100) } private object B9 { val a = B8.a + Random.nextInt(100) } private object B10 { val a = B9.a + Random.nextInt(100) } private object B11 { val a = B10.a + Random.nextInt(100) } private object B12 { val a = B11.a + Random.nextInt(100) } private object B13 { val a = B12.a + Random.nextInt(100) } private object B14 { val a = B13.a + Random.nextInt(100) } private object B15 { val a = B14.a + Random.nextInt(100) } private object B16 { val a = B15.a + Random.nextInt(100) } private object B17 { val a = B16.a + Random.nextInt(100) } private object B18 { val a = B17.a + Random.nextInt(100) } private object B19 { val a = B18.a + Random.nextInt(100) } private object B20 { val a = B19.a + Random.nextInt(100) } private object B21 { val a = B20.a + Random.nextInt(100) } private object B22 { val a = B21.a + Random.nextInt(100) } private object B23 { val a = B22.a + Random.nextInt(100) } private object B24 { val a = B23.a + Random.nextInt(100) } private object B25 { val a = B24.a + Random.nextInt(100) } private object B26 { val a = B25.a + Random.nextInt(100) } private object B27 { val a = B26.a + Random.nextInt(100) } private object B28 { val a = B27.a + Random.nextInt(100) } private object B29 { val a = B28.a + Random.nextInt(100) } private object B30 { val a = B29.a + Random.nextInt(100) } private object B31 { val a = B30.a + Random.nextInt(100) } private object B32 { val a = B31.a + Random.nextInt(100) } private object B33 { val a = B32.a + Random.nextInt(100) } private object B34 { val a = B33.a + Random.nextInt(100) } private object B35 { val a = B34.a + Random.nextInt(100) } private object B36 { val a = B35.a + Random.nextInt(100) } private object B37 { val a = B36.a + Random.nextInt(100) } private object B38 { val a = B37.a + Random.nextInt(100) } private object B39 { val a = B38.a + Random.nextInt(100) } private object B40 { val a = B39.a + Random.nextInt(100) } private object B41 { val a = B40.a + Random.nextInt(100) } private object B42 { val a = B41.a + Random.nextInt(100) } private object B43 { val a = B42.a + Random.nextInt(100) } private object B44 { val a = B43.a + Random.nextInt(100) } private object B45 { val a = B44.a + Random.nextInt(100) } private object B46 { val a = B45.a + Random.nextInt(100) } private object B47 { val a = B46.a + Random.nextInt(100) } private object B48 { val a = B47.a + Random.nextInt(100) } private object B49 { val a = B48.a + Random.nextInt(100) } private object B50 { val a = B49.a + Random.nextInt(100) } private object B51 { val a = B50.a + Random.nextInt(100) } private object B52 { val a = B51.a + Random.nextInt(100) } private object B53 { val a = B52.a + Random.nextInt(100) } private object B54 { val a = B53.a + Random.nextInt(100) } private object B55 { val a = B54.a + Random.nextInt(100) } private object B56 { val a = B55.a + Random.nextInt(100) } private object B57 { val a = B56.a + Random.nextInt(100) } private object B58 { val a = B57.a + Random.nextInt(100) } private object B59 { val a = B58.a + Random.nextInt(100) } private object B60 { val a = B59.a + Random.nextInt(100) } private object B61 { val a = B60.a + Random.nextInt(100) } private object B62 { val a = B61.a + Random.nextInt(100) } private object B63 { val a = B62.a + Random.nextInt(100) } private object B64 { val a = B63.a + Random.nextInt(100) } private object B65 { val a = B64.a + Random.nextInt(100) } private object B66 { val a = B65.a + Random.nextInt(100) } private object B67 { val a = B66.a + Random.nextInt(100) } private object B68 { val a = B67.a + Random.nextInt(100) } private object B69 { val a = B68.a + Random.nextInt(100) } private object B70 { val a = B69.a + Random.nextInt(100) } private object B71 { val a = B70.a + Random.nextInt(100) } private object B72 { val a = B71.a + Random.nextInt(100) } private object B73 { val a = B72.a + Random.nextInt(100) } private object B74 { val a = B73.a + Random.nextInt(100) } private object B75 { val a = B74.a + Random.nextInt(100) } private object B76 { val a = B75.a + Random.nextInt(100) } private object B77 { val a = B76.a + Random.nextInt(100) } private object B78 { val a = B77.a + Random.nextInt(100) } private object B79 { val a = B78.a + Random.nextInt(100) } private object B80 { val a = B79.a + Random.nextInt(100) } private object B81 { val a = B80.a + Random.nextInt(100) } private object B82 { val a = B81.a + Random.nextInt(100) } private object B83 { val a = B82.a + Random.nextInt(100) } private object B84 { val a = B83.a + Random.nextInt(100) } private object B85 { val a = B84.a + Random.nextInt(100) } private object B86 { val a = B85.a + Random.nextInt(100) } private object B87 { val a = B86.a + Random.nextInt(100) } private object B88 { val a = B87.a + Random.nextInt(100) } private object B89 { val a = B88.a + Random.nextInt(100) } private object B90 { val a = B89.a + Random.nextInt(100) } private object B91 { val a = B90.a + Random.nextInt(100) } private object B92 { val a = B91.a + Random.nextInt(100) } private object B93 { val a = B92.a + Random.nextInt(100) } private object B94 { val a = B93.a + Random.nextInt(100) } private object B95 { val a = B94.a + Random.nextInt(100) } private object B96 { val a = B95.a + Random.nextInt(100) } private object B97 { val a = B96.a + Random.nextInt(100) } private object B98 { val a = B97.a + Random.nextInt(100) } private object B99 { val a = B98.a + Random.nextInt(100) } private object B100 { val a = B99.a + Random.nextInt(100) } private object B101 { val a = B100.a + Random.nextInt(100) } private object B102 { val a = B101.a + Random.nextInt(100) } private object B103 { val a = B102.a + Random.nextInt(100) } private object B104 { val a = B103.a + Random.nextInt(100) } private object B105 { val a = B104.a + Random.nextInt(100) } private object B106 { val a = B105.a + Random.nextInt(100) } private object B107 { val a = B106.a + Random.nextInt(100) } private object B108 { val a = B107.a + Random.nextInt(100) } private object B109 { val a = B108.a + Random.nextInt(100) } private object B110 { val a = B109.a + Random.nextInt(100) } private object B111 { val a = B110.a + Random.nextInt(100) } private object B112 { val a = B111.a + Random.nextInt(100) } private object B113 { val a = B112.a + Random.nextInt(100) } private object B114 { val a = B113.a + Random.nextInt(100) } private object B115 { val a = B114.a + Random.nextInt(100) } private object B116 { val a = B115.a + Random.nextInt(100) } private object B117 { val a = B116.a + Random.nextInt(100) } private object B118 { val a = B117.a + Random.nextInt(100) } private object B119 { val a = B118.a + Random.nextInt(100) } private object B120 { val a = B119.a + Random.nextInt(100) } private object B121 { val a = B120.a + Random.nextInt(100) } private object B122 { val a = B121.a + Random.nextInt(100) } private object B123 { val a = B122.a + Random.nextInt(100) } private object B124 { val a = B123.a + Random.nextInt(100) } private object B125 { val a = B124.a + Random.nextInt(100) } private object B126 { val a = B125.a + Random.nextInt(100) } private object B127 { val a = B126.a + Random.nextInt(100) } private object B128 { val a = B127.a + Random.nextInt(100) } private object B129 { val a = B128.a + Random.nextInt(100) } private object B130 { val a = B129.a + Random.nextInt(100) } private object B131 { val a = B130.a + Random.nextInt(100) } private object B132 { val a = B131.a + Random.nextInt(100) } private object B133 { val a = B132.a + Random.nextInt(100) } private object B134 { val a = B133.a + Random.nextInt(100) } private object B135 { val a = B134.a + Random.nextInt(100) } private object B136 { val a = B135.a + Random.nextInt(100) } private object B137 { val a = B136.a + Random.nextInt(100) } private object B138 { val a = B137.a + Random.nextInt(100) } private object B139 { val a = B138.a + Random.nextInt(100) } private object B140 { val a = B139.a + Random.nextInt(100) } private object B141 { val a = B140.a + Random.nextInt(100) } private object B142 { val a = B141.a + Random.nextInt(100) } private object B143 { val a = B142.a + Random.nextInt(100) } private object B144 { val a = B143.a + Random.nextInt(100) } private object B145 { val a = B144.a + Random.nextInt(100) } private object B146 { val a = B145.a + Random.nextInt(100) } private object B147 { val a = B146.a + Random.nextInt(100) } private object B148 { val a = B147.a + Random.nextInt(100) } private object B149 { val a = B148.a + Random.nextInt(100) } private object B150 { val a = B149.a + Random.nextInt(100) } private object B151 { val a = B150.a + Random.nextInt(100) } private object B152 { val a = B151.a + Random.nextInt(100) } private object B153 { val a = B152.a + Random.nextInt(100) } private object B154 { val a = B153.a + Random.nextInt(100) } private object B155 { val a = B154.a + Random.nextInt(100) } private object B156 { val a = B155.a + Random.nextInt(100) } private object B157 { val a = B156.a + Random.nextInt(100) } private object B158 { val a = B157.a + Random.nextInt(100) } private object B159 { val a = B158.a + Random.nextInt(100) } private object B160 { val a = B159.a + Random.nextInt(100) } private object B161 { val a = B160.a + Random.nextInt(100) } private object B162 { val a = B161.a + Random.nextInt(100) } private object B163 { val a = B162.a + Random.nextInt(100) } private object B164 { val a = B163.a + Random.nextInt(100) } private object B165 { val a = B164.a + Random.nextInt(100) } private object B166 { val a = B165.a + Random.nextInt(100) } private object B167 { val a = B166.a + Random.nextInt(100) } private object B168 { val a = B167.a + Random.nextInt(100) } private object B169 { val a = B168.a + Random.nextInt(100) } private object B170 { val a = B169.a + Random.nextInt(100) } private object B171 { val a = B170.a + Random.nextInt(100) } private object B172 { val a = B171.a + Random.nextInt(100) } private object B173 { val a = B172.a + Random.nextInt(100) } private object B174 { val a = B173.a + Random.nextInt(100) } private object B175 { val a = B174.a + Random.nextInt(100) } private object B176 { val a = B175.a + Random.nextInt(100) } private object B177 { val a = B176.a + Random.nextInt(100) } private object B178 { val a = B177.a + Random.nextInt(100) } private object B179 { val a = B178.a + Random.nextInt(100) } private object B180 { val a = B179.a + Random.nextInt(100) } private object B181 { val a = B180.a + Random.nextInt(100) } private object B182 { val a = B181.a + Random.nextInt(100) } private object B183 { val a = B182.a + Random.nextInt(100) } private object B184 { val a = B183.a + Random.nextInt(100) } private object B185 { val a = B184.a + Random.nextInt(100) } private object B186 { val a = B185.a + Random.nextInt(100) } private object B187 { val a = B186.a + Random.nextInt(100) } private object B188 { val a = B187.a + Random.nextInt(100) } private object B189 { val a = B188.a + Random.nextInt(100) } private object B190 { val a = B189.a + Random.nextInt(100) } private object B191 { val a = B190.a + Random.nextInt(100) } private object B192 { val a = B191.a + Random.nextInt(100) } private object B193 { val a = B192.a + Random.nextInt(100) } private object B194 { val a = B193.a + Random.nextInt(100) } private object B195 { val a = B194.a + Random.nextInt(100) } private object B196 { val a = B195.a + Random.nextInt(100) } private object B197 { val a = B196.a + Random.nextInt(100) } private object B198 { val a = B197.a + Random.nextInt(100) } private object B199 { val a = B198.a + Random.nextInt(100) } private object B200 { val a = B199.a + Random.nextInt(100) } private object B201 { val a = B200.a + Random.nextInt(100) } private object B202 { val a = B201.a + Random.nextInt(100) } private object B203 { val a = B202.a + Random.nextInt(100) } private object B204 { val a = B203.a + Random.nextInt(100) } private object B205 { val a = B204.a + Random.nextInt(100) } private object B206 { val a = B205.a + Random.nextInt(100) } private object B207 { val a = B206.a + Random.nextInt(100) } private object B208 { val a = B207.a + Random.nextInt(100) } private object B209 { val a = B208.a + Random.nextInt(100) } private object B210 { val a = B209.a + Random.nextInt(100) } private object B211 { val a = B210.a + Random.nextInt(100) } private object B212 { val a = B211.a + Random.nextInt(100) } private object B213 { val a = B212.a + Random.nextInt(100) } private object B214 { val a = B213.a + Random.nextInt(100) } private object B215 { val a = B214.a + Random.nextInt(100) } private object B216 { val a = B215.a + Random.nextInt(100) } private object B217 { val a = B216.a + Random.nextInt(100) } private object B218 { val a = B217.a + Random.nextInt(100) } private object B219 { val a = B218.a + Random.nextInt(100) } private object B220 { val a = B219.a + Random.nextInt(100) } private object B221 { val a = B220.a + Random.nextInt(100) } private object B222 { val a = B221.a + Random.nextInt(100) } private object B223 { val a = B222.a + Random.nextInt(100) } private object B224 { val a = B223.a + Random.nextInt(100) } private object B225 { val a = B224.a + Random.nextInt(100) } private object B226 { val a = B225.a + Random.nextInt(100) } private object B227 { val a = B226.a + Random.nextInt(100) } private object B228 { val a = B227.a + Random.nextInt(100) } private object B229 { val a = B228.a + Random.nextInt(100) } private object B230 { val a = B229.a + Random.nextInt(100) } private object B231 { val a = B230.a + Random.nextInt(100) } private object B232 { val a = B231.a + Random.nextInt(100) } private object B233 { val a = B232.a + Random.nextInt(100) } private object B234 { val a = B233.a + Random.nextInt(100) } private object B235 { val a = B234.a + Random.nextInt(100) } private object B236 { val a = B235.a + Random.nextInt(100) } private object B237 { val a = B236.a + Random.nextInt(100) } private object B238 { val a = B237.a + Random.nextInt(100) } private object B239 { val a = B238.a + Random.nextInt(100) } private object B240 { val a = B239.a + Random.nextInt(100) } private object B241 { val a = B240.a + Random.nextInt(100) } private object B242 { val a = B241.a + Random.nextInt(100) } private object B243 { val a = B242.a + Random.nextInt(100) } private object B244 { val a = B243.a + Random.nextInt(100) } private object B245 { val a = B244.a + Random.nextInt(100) } private object B246 { val a = B245.a + Random.nextInt(100) } private object B247 { val a = B246.a + Random.nextInt(100) } private object B248 { val a = B247.a + Random.nextInt(100) } private object B249 { val a = B248.a + Random.nextInt(100) } private object B250 { val a = B249.a + Random.nextInt(100) } private object B251 { val a = B250.a + Random.nextInt(100) } private object B252 { val a = B251.a + Random.nextInt(100) } private object B253 { val a = B252.a + Random.nextInt(100) } private object B254 { val a = B253.a + Random.nextInt(100) } private object B255 { val a = B254.a + Random.nextInt(100) } private object B256 { val a = B255.a + Random.nextInt(100) } private object B257 { val a = B256.a + Random.nextInt(100) } private object B258 { val a = B257.a + Random.nextInt(100) } private object B259 { val a = B258.a + Random.nextInt(100) } private object B260 { val a = B259.a + Random.nextInt(100) } private object B261 { val a = B260.a + Random.nextInt(100) } private object B262 { val a = B261.a + Random.nextInt(100) } private object B263 { val a = B262.a + Random.nextInt(100) } private object B264 { val a = B263.a + Random.nextInt(100) } private object B265 { val a = B264.a + Random.nextInt(100) } private object B266 { val a = B265.a + Random.nextInt(100) } private object B267 { val a = B266.a + Random.nextInt(100) } private object B268 { val a = B267.a + Random.nextInt(100) } private object B269 { val a = B268.a + Random.nextInt(100) } private object B270 { val a = B269.a + Random.nextInt(100) } private object B271 { val a = B270.a + Random.nextInt(100) } private object B272 { val a = B271.a + Random.nextInt(100) } private object B273 { val a = B272.a + Random.nextInt(100) } private object B274 { val a = B273.a + Random.nextInt(100) } private object B275 { val a = B274.a + Random.nextInt(100) } private object B276 { val a = B275.a + Random.nextInt(100) } private object B277 { val a = B276.a + Random.nextInt(100) } private object B278 { val a = B277.a + Random.nextInt(100) } private object B279 { val a = B278.a + Random.nextInt(100) } private object B280 { val a = B279.a + Random.nextInt(100) } private object B281 { val a = B280.a + Random.nextInt(100) } private object B282 { val a = B281.a + Random.nextInt(100) } private object B283 { val a = B282.a + Random.nextInt(100) } private object B284 { val a = B283.a + Random.nextInt(100) } private object B285 { val a = B284.a + Random.nextInt(100) } private object B286 { val a = B285.a + Random.nextInt(100) } private object B287 { val a = B286.a + Random.nextInt(100) } private object B288 { val a = B287.a + Random.nextInt(100) } private object B289 { val a = B288.a + Random.nextInt(100) } private object B290 { val a = B289.a + Random.nextInt(100) } private object B291 { val a = B290.a + Random.nextInt(100) } private object B292 { val a = B291.a + Random.nextInt(100) } private object B293 { val a = B292.a + Random.nextInt(100) } private object B294 { val a = B293.a + Random.nextInt(100) } private object B295 { val a = B294.a + Random.nextInt(100) } private object B296 { val a = B295.a + Random.nextInt(100) } private object B297 { val a = B296.a + Random.nextInt(100) } private object B298 { val a = B297.a + Random.nextInt(100) } private object B299 { val a = B298.a + Random.nextInt(100) } private object B300 { val a = B299.a + Random.nextInt(100) } private object B301 { val a = B300.a + Random.nextInt(100) } private object B302 { val a = B301.a + Random.nextInt(100) } private object B303 { val a = B302.a + Random.nextInt(100) } private object B304 { val a = B303.a + Random.nextInt(100) } private object B305 { val a = B304.a + Random.nextInt(100) } private object B306 { val a = B305.a + Random.nextInt(100) } private object B307 { val a = B306.a + Random.nextInt(100) } private object B308 { val a = B307.a + Random.nextInt(100) } private object B309 { val a = B308.a + Random.nextInt(100) } private object B310 { val a = B309.a + Random.nextInt(100) } private object B311 { val a = B310.a + Random.nextInt(100) } private object B312 { val a = B311.a + Random.nextInt(100) } private object B313 { val a = B312.a + Random.nextInt(100) } private object B314 { val a = B313.a + Random.nextInt(100) } private object B315 { val a = B314.a + Random.nextInt(100) } private object B316 { val a = B315.a + Random.nextInt(100) } private object B317 { val a = B316.a + Random.nextInt(100) } private object B318 { val a = B317.a + Random.nextInt(100) } private object B319 { val a = B318.a + Random.nextInt(100) } private object B320 { val a = B319.a + Random.nextInt(100) } private object B321 { val a = B320.a + Random.nextInt(100) } private object B322 { val a = B321.a + Random.nextInt(100) } private object B323 { val a = B322.a + Random.nextInt(100) } private object B324 { val a = B323.a + Random.nextInt(100) } private object B325 { val a = B324.a + Random.nextInt(100) } private object B326 { val a = B325.a + Random.nextInt(100) } private object B327 { val a = B326.a + Random.nextInt(100) } private object B328 { val a = B327.a + Random.nextInt(100) } private object B329 { val a = B328.a + Random.nextInt(100) } private object B330 { val a = B329.a + Random.nextInt(100) } private object B331 { val a = B330.a + Random.nextInt(100) } private object B332 { val a = B331.a + Random.nextInt(100) } private object B333 { val a = B332.a + Random.nextInt(100) } private object B334 { val a = B333.a + Random.nextInt(100) } private object B335 { val a = B334.a + Random.nextInt(100) } private object B336 { val a = B335.a + Random.nextInt(100) } private object B337 { val a = B336.a + Random.nextInt(100) } private object B338 { val a = B337.a + Random.nextInt(100) } private object B339 { val a = B338.a + Random.nextInt(100) } private object B340 { val a = B339.a + Random.nextInt(100) } private object B341 { val a = B340.a + Random.nextInt(100) } private object B342 { val a = B341.a + Random.nextInt(100) } private object B343 { val a = B342.a + Random.nextInt(100) } private object B344 { val a = B343.a + Random.nextInt(100) } private object B345 { val a = B344.a + Random.nextInt(100) } private object B346 { val a = B345.a + Random.nextInt(100) } private object B347 { val a = B346.a + Random.nextInt(100) } private object B348 { val a = B347.a + Random.nextInt(100) } private object B349 { val a = B348.a + Random.nextInt(100) } private object B350 { val a = B349.a + Random.nextInt(100) } private object B351 { val a = B350.a + Random.nextInt(100) } private object B352 { val a = B351.a + Random.nextInt(100) } private object B353 { val a = B352.a + Random.nextInt(100) } private object B354 { val a = B353.a + Random.nextInt(100) } private object B355 { val a = B354.a + Random.nextInt(100) } private object B356 { val a = B355.a + Random.nextInt(100) } private object B357 { val a = B356.a + Random.nextInt(100) } private object B358 { val a = B357.a + Random.nextInt(100) } private object B359 { val a = B358.a + Random.nextInt(100) } private object B360 { val a = B359.a + Random.nextInt(100) } private object B361 { val a = B360.a + Random.nextInt(100) } private object B362 { val a = B361.a + Random.nextInt(100) } private object B363 { val a = B362.a + Random.nextInt(100) } private object B364 { val a = B363.a + Random.nextInt(100) } private object B365 { val a = B364.a + Random.nextInt(100) } private object B366 { val a = B365.a + Random.nextInt(100) } private object B367 { val a = B366.a + Random.nextInt(100) } private object B368 { val a = B367.a + Random.nextInt(100) } private object B369 { val a = B368.a + Random.nextInt(100) } private object B370 { val a = B369.a + Random.nextInt(100) } private object B371 { val a = B370.a + Random.nextInt(100) } private object B372 { val a = B371.a + Random.nextInt(100) } private object B373 { val a = B372.a + Random.nextInt(100) } private object B374 { val a = B373.a + Random.nextInt(100) } private object B375 { val a = B374.a + Random.nextInt(100) } private object B376 { val a = B375.a + Random.nextInt(100) } private object B377 { val a = B376.a + Random.nextInt(100) } private object B378 { val a = B377.a + Random.nextInt(100) } private object B379 { val a = B378.a + Random.nextInt(100) } private object B380 { val a = B379.a + Random.nextInt(100) } private object B381 { val a = B380.a + Random.nextInt(100) } private object B382 { val a = B381.a + Random.nextInt(100) } private object B383 { val a = B382.a + Random.nextInt(100) } private object B384 { val a = B383.a + Random.nextInt(100) } private object B385 { val a = B384.a + Random.nextInt(100) } private object B386 { val a = B385.a + Random.nextInt(100) } private object B387 { val a = B386.a + Random.nextInt(100) } private object B388 { val a = B387.a + Random.nextInt(100) } private object B389 { val a = B388.a + Random.nextInt(100) } private object B390 { val a = B389.a + Random.nextInt(100) } private object B391 { val a = B390.a + Random.nextInt(100) } private object B392 { val a = B391.a + Random.nextInt(100) } private object B393 { val a = B392.a + Random.nextInt(100) } private object B394 { val a = B393.a + Random.nextInt(100) } private object B395 { val a = B394.a + Random.nextInt(100) } private object B396 { val a = B395.a + Random.nextInt(100) } private object B397 { val a = B396.a + Random.nextInt(100) } private object B398 { val a = B397.a + Random.nextInt(100) } private object B399 { val a = B398.a + Random.nextInt(100) } private object B400 { val a = B399.a + Random.nextInt(100) } private object B401 { val a = B400.a + Random.nextInt(100) } private object B402 { val a = B401.a + Random.nextInt(100) } private object B403 { val a = B402.a + Random.nextInt(100) } private object B404 { val a = B403.a + Random.nextInt(100) } private object B405 { val a = B404.a + Random.nextInt(100) } private object B406 { val a = B405.a + Random.nextInt(100) } private object B407 { val a = B406.a + Random.nextInt(100) } private object B408 { val a = B407.a + Random.nextInt(100) } private object B409 { val a = B408.a + Random.nextInt(100) } private object B410 { val a = B409.a + Random.nextInt(100) } private object B411 { val a = B410.a + Random.nextInt(100) } private object B412 { val a = B411.a + Random.nextInt(100) } private object B413 { val a = B412.a + Random.nextInt(100) } private object B414 { val a = B413.a + Random.nextInt(100) } private object B415 { val a = B414.a + Random.nextInt(100) } private object B416 { val a = B415.a + Random.nextInt(100) } private object B417 { val a = B416.a + Random.nextInt(100) } private object B418 { val a = B417.a + Random.nextInt(100) } private object B419 { val a = B418.a + Random.nextInt(100) } private object B420 { val a = B419.a + Random.nextInt(100) } private object B421 { val a = B420.a + Random.nextInt(100) } private object B422 { val a = B421.a + Random.nextInt(100) } private object B423 { val a = B422.a + Random.nextInt(100) } private object B424 { val a = B423.a + Random.nextInt(100) } private object B425 { val a = B424.a + Random.nextInt(100) } private object B426 { val a = B425.a + Random.nextInt(100) } private object B427 { val a = B426.a + Random.nextInt(100) } private object B428 { val a = B427.a + Random.nextInt(100) } private object B429 { val a = B428.a + Random.nextInt(100) } private object B430 { val a = B429.a + Random.nextInt(100) } private object B431 { val a = B430.a + Random.nextInt(100) } private object B432 { val a = B431.a + Random.nextInt(100) } private object B433 { val a = B432.a + Random.nextInt(100) } private object B434 { val a = B433.a + Random.nextInt(100) } private object B435 { val a = B434.a + Random.nextInt(100) } private object B436 { val a = B435.a + Random.nextInt(100) } private object B437 { val a = B436.a + Random.nextInt(100) } private object B438 { val a = B437.a + Random.nextInt(100) } private object B439 { val a = B438.a + Random.nextInt(100) } private object B440 { val a = B439.a + Random.nextInt(100) } private object B441 { val a = B440.a + Random.nextInt(100) } private object B442 { val a = B441.a + Random.nextInt(100) } private object B443 { val a = B442.a + Random.nextInt(100) } private object B444 { val a = B443.a + Random.nextInt(100) } private object B445 { val a = B444.a + Random.nextInt(100) } private object B446 { val a = B445.a + Random.nextInt(100) } private object B447 { val a = B446.a + Random.nextInt(100) } private object B448 { val a = B447.a + Random.nextInt(100) } private object B449 { val a = B448.a + Random.nextInt(100) } private object B450 { val a = B449.a + Random.nextInt(100) } private object B451 { val a = B450.a + Random.nextInt(100) } private object B452 { val a = B451.a + Random.nextInt(100) } private object B453 { val a = B452.a + Random.nextInt(100) } private object B454 { val a = B453.a + Random.nextInt(100) } private object B455 { val a = B454.a + Random.nextInt(100) } private object B456 { val a = B455.a + Random.nextInt(100) } private object B457 { val a = B456.a + Random.nextInt(100) } private object B458 { val a = B457.a + Random.nextInt(100) } private object B459 { val a = B458.a + Random.nextInt(100) } private object B460 { val a = B459.a + Random.nextInt(100) } private object B461 { val a = B460.a + Random.nextInt(100) } private object B462 { val a = B461.a + Random.nextInt(100) } private object B463 { val a = B462.a + Random.nextInt(100) } private object B464 { val a = B463.a + Random.nextInt(100) } private object B465 { val a = B464.a + Random.nextInt(100) } private object B466 { val a = B465.a + Random.nextInt(100) } private object B467 { val a = B466.a + Random.nextInt(100) } private object B468 { val a = B467.a + Random.nextInt(100) } private object B469 { val a = B468.a + Random.nextInt(100) } private object B470 { val a = B469.a + Random.nextInt(100) } private object B471 { val a = B470.a + Random.nextInt(100) } private object B472 { val a = B471.a + Random.nextInt(100) } private object B473 { val a = B472.a + Random.nextInt(100) } private object B474 { val a = B473.a + Random.nextInt(100) } private object B475 { val a = B474.a + Random.nextInt(100) } private object B476 { val a = B475.a + Random.nextInt(100) } private object B477 { val a = B476.a + Random.nextInt(100) } private object B478 { val a = B477.a + Random.nextInt(100) } private object B479 { val a = B478.a + Random.nextInt(100) } private object B480 { val a = B479.a + Random.nextInt(100) } private object B481 { val a = B480.a + Random.nextInt(100) } private object B482 { val a = B481.a + Random.nextInt(100) } private object B483 { val a = B482.a + Random.nextInt(100) } private object B484 { val a = B483.a + Random.nextInt(100) } private object B485 { val a = B484.a + Random.nextInt(100) } private object B486 { val a = B485.a + Random.nextInt(100) } private object B487 { val a = B486.a + Random.nextInt(100) } private object B488 { val a = B487.a + Random.nextInt(100) } private object B489 { val a = B488.a + Random.nextInt(100) } private object B490 { val a = B489.a + Random.nextInt(100) } private object B491 { val a = B490.a + Random.nextInt(100) } private object B492 { val a = B491.a + Random.nextInt(100) } private object B493 { val a = B492.a + Random.nextInt(100) } private object B494 { val a = B493.a + Random.nextInt(100) } private object B495 { val a = B494.a + Random.nextInt(100) } private object B496 { val a = B495.a + Random.nextInt(100) } private object B497 { val a = B496.a + Random.nextInt(100) } private object B498 { val a = B497.a + Random.nextInt(100) } private object B499 { val a = B498.a + Random.nextInt(100) } private var singletonInitializeNestedRun = false // Benchmark fun singletonInitializeNested(): Int { if (singletonInitializeNestedRun) { error("Function singletonInitializeNested can be called only once.") } singletonInitializeNestedRun = true var total = B499.a return total } ================================================ FILE: performance/swiftinterop/build.gradle.kts ================================================ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.konan.target.* /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ plugins { id("swift-benchmarking") } val toolsPath = "../../tools" val targetExtension = "Macos" val defaultBuildType = NativeBuildType.RELEASE project.extra["platformManager"] = PlatformManager(projectDir.parentFile.parentFile.absolutePath, false) swiftBenchmark { applicationName = "swiftInterop" commonSrcDirs = listOf("$toolsPath/benchmarks/shared/src/main/kotlin/report", "src", "../shared/src/main/kotlin") nativeSrcDirs = listOf("../shared/src/main/kotlin-native/common", "../shared/src/main/kotlin-native/posix") swiftSources = listOf("$projectDir/swiftSrc/benchmarks.swift", "$projectDir/swiftSrc/main.swift") compileTasks = listOf("compileKotlinNative", "linkBenchmarkReleaseFrameworkNative") buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType cleanBeforeRunTask = "compileKotlinNative" } ================================================ FILE: performance/swiftinterop/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: performance/swiftinterop/src/main/kotlin/org/jetbrains/model/CityMap.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.model import org.jetbrains.multigraph.* import kotlin.comparisons.compareBy enum class Transport { CAR, UNDERGROUND, BUS, TROLLEYBUS, TRAM, TAXI, FOOT } enum class Interest { SIGHT, CULTURE, PARK, ENTERTAINMENT } class PlaceAbsenceException(message: String): Exception(message) {} data class RouteCost(val moneyCost: Double, val timeCost: Double, val interests: Set, val transport: Set): Cost { private val comparator = compareBy({ it.moneyCost }, { it.timeCost }, { it.interests.size }, { it.transport.size }) override operator fun plus(other: Cost) = if (other is RouteCost) { RouteCost(moneyCost + other.moneyCost, timeCost + other.timeCost, interests.union(other.interests), transport.union(other.transport)) } else { error("Expected type is RouteCost") } override operator fun minus(other: Cost) = if (other is RouteCost) { RouteCost(if (moneyCost > other.moneyCost) moneyCost - other.moneyCost else 0.0, if (timeCost > other.timeCost) timeCost - other.timeCost else 0.0, interests.subtract(other.interests), transport.subtract(other.transport)) } else { error("Expected type is RouteCost") } override operator fun compareTo(other: Cost) = if (other is RouteCost) { comparator.compare(this, other) } else { error("Expected type is RouteCost") } } internal var placeCounter = 0u data class Place(val geoCoordinateX: Double, val geoCoordinateY: Double, val name: String, val interestCategory: Interest) { private val comparator = compareBy({ it.geoCoordinateX }, { it.geoCoordinateY }) val id: UInt init { id = placeCounter placeCounter++ } val fullDescription: String get() = "Place $name($geoCoordinateX;$geoCoordinateY)" fun compareTo(other: Place) = comparator.compare(this, other) } data class Path(val from: Place, val to: Place, val cost: RouteCost) class CityMap { data class RouteId(val id: UInt, val from: UInt, val to: UInt) private val graph = Multigraph() val allPlaces: Set get() = graph.allVertexes val allRoutes: List get() { val edges = graph.allEdges val result = mutableListOf() edges.forEach { result.add(RouteId(it, graph.getFrom(it).id, graph.getTo(it).id)) } return result } fun addRoute(from: Place, to: Place, cost: RouteCost): UInt { return graph.addEdge(from, to, cost) } fun getPlaceById(id: UInt): Place { graph.allVertexes.forEach { if (it.id == id) { return it } } throw PlaceAbsenceException("Place with id $id wasn't found.") } fun removePlaceById(id: UInt) { graph.allVertexes.forEach { if (it.id == id) { graph.removeVertex(it) return } } } fun removeRouteById(id: UInt) { graph.removeEdge(id) } fun getRoutes(start: Place, finish: Place, limits: RouteCost): List> { val result = graph.searchRoutesWithLimits(start, finish, limits) return result.map { it.map { Path(graph.getFrom(it), graph.getTo(it), graph.getCost(it) as RouteCost) } } } fun getRouteById(id: UInt) = graph.getEdgeById(id) fun getAllStraightRoutesFrom(place: Place) = graph.getEdgesFrom(place).map { Path(graph.getFrom(it.id), graph.getTo(it.id), graph.getCost(it.id) as RouteCost) } fun isEmpty() = graph.isEmpty() } ================================================ FILE: performance/swiftinterop/src/main/kotlin/org/jetbrains/multigraph/Multigraph.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.multigraph import kotlin.math.pow interface Cost { operator fun plus(other: Cost): Cost operator fun minus(other: Cost): Cost override operator fun equals(other: Any?): Boolean operator fun compareTo(other: Cost): Int } data class Edge(val id: UInt, val from: T, val to: T, val cost: Cost) { override operator fun equals(other: Any?): Boolean { return if (other is Edge<*>) (from == other.from && to == other.to && cost == other.cost) else false } override fun hashCode(): Int = from.hashCode() * 31.0.pow(2.0).toInt() + to.hashCode() * 31 + cost.hashCode() } class EdgeAbsenceMultigraphException(message: String): Exception(message) {} class VertexAbsenceMultigraphException(message: String): Exception(message) {} class Multigraph() { private var edges = mutableMapOf>>() private var idCounter = 0u val allVertexes: Set get() { val outerVertexes = edges.keys val innerVertexes = edges.map { (_, values) -> values.map { it.to }.filter { it !in outerVertexes } }.flatten() return outerVertexes.union(innerVertexes) } val allEdges: List get() = edges.values.flatten().map { it.id } fun getEdgeById(id: UInt): Edge { edges.forEach { (_, value) -> value.forEach { if (it.id == id) return it } } throw EdgeAbsenceMultigraphException("Edge with id $id wasn't found.") } fun copyMultigraph(): Multigraph { val newInstance = Multigraph() edges.forEach { (vertex, edges) -> edges.forEach { edge -> newInstance.addEdge(vertex, edge.to, edge.cost) } } return newInstance } fun addEdge(from: T, to: T, cost: Cost): UInt { val edge = Edge(idCounter, from, to, cost) edges.getOrPut(from) { mutableListOf() }.add(edge) idCounter++ return edge.id } fun removeEdge(id: UInt) { try { val edge = getEdgeById(id) edges[edge.from]?.remove(edge) } catch (exception: EdgeAbsenceMultigraphException) { println("WARNING: no edge with id $id was found.") } } fun removeVertex(vertex: T) { edges.remove(vertex) val edgesToRemove = edges.map { (_, values) -> values.filter { it.to == vertex } }.flatten() edgesToRemove.forEach { removeEdge(it.id) } } fun checkVertexExistance(vertex: T): Boolean { return vertex in allVertexes } fun getTo(edgeId: UInt) = getEdgeById(edgeId).to fun getFrom(edgeId: UInt) = getEdgeById(edgeId).from fun getCost(edgeId: UInt) = getEdgeById(edgeId).cost fun getEdgesFrom(vertex: T) = edges[vertex] ?: listOf>() fun isEmpty() = edges.isEmpty() fun searchRoutesWithLimits(start: T, finish: T, limits: Cost): List> { data class WaveStep(val costs: MutableList = mutableListOf(), val routes: MutableList> = mutableListOf(), val vertexes: MutableList> = mutableListOf()) val currentStepsState = mutableMapOf() var oldFront = mutableSetOf(start) val newFront = mutableSetOf() if (!checkVertexExistance(start)) { throw(VertexAbsenceMultigraphException("Start vertex wasn't found in graph.")) } if (!checkVertexExistance(finish)) { throw(VertexAbsenceMultigraphException("Finish vertex wasn't found in graph.")) } allVertexes.forEach { currentStepsState[it] = WaveStep() } while (!oldFront.isEmpty()) { oldFront.forEach { val currentStepState = currentStepsState[it] ?: WaveStep() // Lookup all edges from vertex. val values = edges.get(it) ?: mutableListOf>() values.forEach { edge -> val newRoutes = mutableListOf() val toStep = currentStepsState[edge.to] ?: WaveStep() // Create new pathes and count their costs. if (currentStepState.routes.isEmpty()) { val newVertexes = mutableListOf(edge.from, edge.to) val newCost = edge.cost if (newCost <= limits && edge.from != edge.to) { newRoutes.add(edge.id) toStep.routes.add(newRoutes) toStep.costs.add(edge.cost) toStep.vertexes.add(newVertexes) currentStepsState[edge.to] = toStep // Add new wave front. if (edge.to != finish && edge.to !in oldFront) { newFront.add(edge.to) } } } else { currentStepState.routes.forEachIndexed { index, it -> val newRoutes = it.toMutableList() val oldCost = currentStepState.costs.get(index) val newCost = edge.cost + oldCost val newVertexes = currentStepState.vertexes.get(index).toMutableList() if (newCost <= limits && edge.to !in currentStepState.vertexes.get(index)) { newRoutes.add(edge.id) newVertexes.add(edge.to) var addNewSequence = true if (newRoutes !in toStep.routes) { toStep.routes.add(newRoutes) toStep.costs.add(newCost) toStep.vertexes.add(newVertexes) currentStepsState[edge.to] = toStep if (edge.to != finish && edge.to !in oldFront) { newFront.add(edge.to) } } } } } } } oldFront = newFront.toMutableSet() newFront.clear() } return currentStepsState[finish]?.routes ?: listOf>() } } ================================================ FILE: performance/swiftinterop/swiftSrc/benchmarks.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation import benchmark class SimpleCost: Cost { let value: Int init(cost: Int) { value = cost } func plus(other: Cost) -> Cost { let otherInstance = other as! SimpleCost return SimpleCost(cost: value + otherInstance.value) } func minus(other: Cost) -> Cost { let otherInstance = other as! SimpleCost return SimpleCost(cost: value - otherInstance.value) } func compareTo(other: Cost) -> Int32 { let otherInstance = other as! SimpleCost if (value < otherInstance.value) { return -1 } if (value == otherInstance.value) { return 0 } return 1 } } class SwiftInteropBenchmarks { let BENCHMARK_SIZE = 10000 let SMALL_BENCHMARK_SIZE = 50 let MEDIUM_BENCHMARK_SIZE = 100 var multigraph = Multigraph() var cityMap = CityMap() func randomInt(border: Int) -> Int { return Int.random(in: 1 ..< border) } func randomDouble(border: Double) -> Double { return Double.random(in: 0 ..< border) } func randomString(length: Int) -> String { let letters = "abcdefghijklmnopqrst" return String((0.. Transport { let allValues = [Transport.car, Transport.underground, Transport.bus, Transport.trolleybus, Transport.tram, Transport.taxi, Transport.foot] return allValues.randomElement()! } func randomInterest() -> Interest { let allValues = [Interest.sight, Interest.culture, Interest.park, Interest.entertainment] return allValues.randomElement()! } func randomPlace() -> Place { return Place(geoCoordinateX: randomDouble(border: 180), geoCoordinateY: randomDouble(border: 90), name: randomString(length: 5), interestCategory: randomInterest()) } func randomRouteCost() -> RouteCost { let transportCount = randomInt(border: 7) let interestCount = randomInt(border: 4) var transports = Set() var interests = Set() for _ in 0...transportCount { transports.insert(randomTransport()) } for _ in 0...interestCount { interests.insert(randomInterest()) } return RouteCost(moneyCost: randomDouble(border: 10000), timeCost: randomDouble(border: 24), interests: interests, transport: transports) } func initMultigraph(size: Int) { multigraph = Multigraph() for i in 1...size { multigraph.addEdge(from: NSNumber(value: i), to: NSNumber(value: i + 1), cost: SimpleCost(cost: (i + 1) % i )) multigraph.addEdge(from: NSNumber(value: i), to: NSNumber(value: i * 2), cost: SimpleCost(cost: (i * 2) % i)) multigraph.addEdge(from: NSNumber(value: i + 5), to: NSNumber(value: i), cost: SimpleCost(cost: (i + 5) % i)) } } func createMultigraphOfInt() { initMultigraph(size: BENCHMARK_SIZE) } func fillCityMap() { cityMap = CityMap() for _ in 0...BENCHMARK_SIZE { cityMap.addRoute(from: randomPlace(), to: randomPlace(), cost: randomRouteCost()) } } func initCityMap(size: Int) { cityMap = CityMap() let allValuesInterests = [Interest.sight, Interest.culture, Interest.park, Interest.entertainment] let allValuesTransport = [Transport.car, Transport.underground, Transport.bus, Transport.trolleybus, Transport.tram, Transport.taxi, Transport.foot] for i in 1...size { let from = Place(geoCoordinateX: Double(i % 180), geoCoordinateY: Double(i % 90 + 90 % i), name: randomString(length: 5), interestCategory: allValuesInterests[i % allValuesInterests.count]) let to = Place(geoCoordinateX: Double(i % 180 + 180 % i), geoCoordinateY: Double(i % 90), name: randomString(length: 5), interestCategory: allValuesInterests[(i + 5) % allValuesInterests.count]) var transports = Set() var interests = Set() for j in 0...i % 2 + 1 { interests.insert(allValuesInterests[(i + j) % allValuesInterests.count]) } for j in 0...i % 2 + 1 { transports.insert(allValuesTransport[i % allValuesTransport.count]) } let cost = RouteCost(moneyCost: Double((i * 2) % 10000), timeCost: Double((i + 3) % 24), interests: interests, transport: transports) cityMap.addRoute(from: from, to: to, cost: cost) } } func searchRoutesInSwiftMultigraph() { initMultigraph(size: SMALL_BENCHMARK_SIZE) for _ in 0...SMALL_BENCHMARK_SIZE { var vertexes = Array(multigraph.allVertexes) var result = multigraph.searchRoutesWithLimits(start: 1, finish: NSNumber(value: SMALL_BENCHMARK_SIZE / 2 + SMALL_BENCHMARK_SIZE / 4), limits: SimpleCost(cost: SMALL_BENCHMARK_SIZE / 5)) var count = result.map{ $0.count }.reduce(0, +) } } func searchTravelRoutes() { cityMap = CityMap() initCityMap(size: BENCHMARK_SIZE) let transports: Set = [Transport.car, Transport.underground] let interests: Set = [Interest.sight, Interest.culture] let cost = RouteCost(moneyCost: 500, timeCost: 6, interests: interests, transport: transports) for _ in 0...SMALL_BENCHMARK_SIZE { var result = cityMap.getRoutes(start: Array(cityMap.allPlaces).first!, finish: Array(cityMap.allPlaces).last!, limits: cost) var totalCost = result.flatMap{ $0 }.map { $0.cost.moneyCost }.reduce(0, +) } } func availableTransportOnMap() { cityMap = CityMap() initCityMap(size: MEDIUM_BENCHMARK_SIZE) Set(cityMap.allRoutes.map { (cityMap.getRouteById(id: $0.id).cost as! RouteCost).transport }) } func allPlacesMapedByInterests() { cityMap = CityMap() initCityMap(size: MEDIUM_BENCHMARK_SIZE) let placesByInterests = cityMap.allPlaces.reduce([Interest: Array]()) { (dict, place) -> [Interest: Array] in var dict = dict if (dict[place.interestCategory] != nil) { dict[place.interestCategory]?.append(place) } else { dict[place.interestCategory] = [place] } return dict } } func getAllPlacesWithStraightRoutesTo() { cityMap = CityMap() initCityMap(size: MEDIUM_BENCHMARK_SIZE) for _ in 0...SMALL_BENCHMARK_SIZE { let start = cityMap.allPlaces.randomElement()! let availableRoutes = cityMap.getAllStraightRoutesFrom(place: start) var _ = availableRoutes.map { $0.to } } } func goToAllAvailablePlaces() { cityMap = CityMap() initCityMap(size: MEDIUM_BENCHMARK_SIZE) for _ in 0...SMALL_BENCHMARK_SIZE { let start = cityMap.allPlaces.randomElement()! let availableRoutes = cityMap.getAllStraightRoutesFrom(place: start) availableRoutes.map { 2 * $0.cost.moneyCost } } } func removeVertexAndEdgesSwiftMultigraph() { initMultigraph(size: SMALL_BENCHMARK_SIZE) let multigraphCopy = multigraph.doCopyMultigraph() var edges = multigraphCopy.allEdges while (!edges.isEmpty) { multigraphCopy.removeEdge(id: UInt32(edges.randomElement()!)) let vertexes = multigraphCopy.allVertexes as! Set multigraphCopy.removeVertex(vertex: vertexes.randomElement()!) edges = multigraphCopy.allEdges } } func stringInterop() { cityMap = CityMap() fillCityMap() let place = cityMap.allPlaces.first! for _ in 0...BENCHMARK_SIZE { let _ = place.fullDescription } } func simpleFunction() { cityMap = CityMap() fillCityMap() let place = cityMap.allPlaces.first! for _ in 0...BENCHMARK_SIZE { let _ = place.compareTo(other:place) } } } ================================================ FILE: performance/swiftinterop/swiftSrc/main.swift ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import Foundation import benchmark var runner = BenchmarksRunner() let args = KotlinArray(size: Int32(CommandLine.arguments.count - 1), init: {index in CommandLine.arguments[Int(truncating: index) + 1] as NSString }) let companion = BenchmarkEntryWithInit.Companion() var swiftLauncher = SwiftLauncher() swiftLauncher.add(name: "createMultigraphOfInt", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).createMultigraphOfInt() })) swiftLauncher.add(name: "fillCityMap", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).fillCityMap() })) swiftLauncher.add(name: "searchRoutesInSwiftMultigraph", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).searchRoutesInSwiftMultigraph () })) swiftLauncher.add(name: "searchTravelRoutes", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).searchTravelRoutes() })) swiftLauncher.add(name: "availableTransportOnMap", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).availableTransportOnMap() })) swiftLauncher.add(name: "allPlacesMapedByInterests", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).allPlacesMapedByInterests() })) swiftLauncher.add(name: "getAllPlacesWithStraightRoutesTo", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).getAllPlacesWithStraightRoutesTo() })) swiftLauncher.add(name: "goToAllAvailablePlaces", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).goToAllAvailablePlaces() })) swiftLauncher.add(name: "removeVertexAndEdgesSwiftMultigraph", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).removeVertexAndEdgesSwiftMultigraph() })) swiftLauncher.add(name: "stringInterop", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).stringInterop() })) swiftLauncher.add(name: "simpleFunction", benchmark: companion.create(ctor: { return SwiftInteropBenchmarks() }, lambda: { ($0 as! SwiftInteropBenchmarks).simpleFunction() })) runner.runBenchmarks(args: args, run: { (arguments: BenchmarkArguments) -> [BenchmarkResult] in if arguments is BaseBenchmarkArguments { let argumentsList: BaseBenchmarkArguments = arguments as! BaseBenchmarkArguments return swiftLauncher.launch(numWarmIterations: argumentsList.warmup, numberOfAttempts: argumentsList.repeat, prefix: argumentsList.prefix, filters: argumentsList.filter, filterRegexes: argumentsList.filterRegex, verbose: argumentsList.verbose) } return [BenchmarkResult]() }, parseArgs: { (args: KotlinArray, benchmarksListAction: (() -> KotlinUnit)) -> BenchmarkArguments? in return runner.parse(args: args, benchmarksListAction: swiftLauncher.benchmarksListAction) }, collect: { (benchmarks: [BenchmarkResult], arguments: BenchmarkArguments) -> Void in runner.collect(results: benchmarks, arguments: arguments) }, benchmarksListAction: swiftLauncher.benchmarksListAction) ================================================ FILE: performance/videoplayer/build.gradle.kts ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.PlatformInfo import org.jetbrains.kotlin.getCompileOnlyBenchmarksOpts import org.jetbrains.kotlin.getNativeProgramExtension import org.jetbrains.kotlin.mingwPath plugins { id("compile-benchmarking") } val dist = file(findProperty("kotlin.native.home") ?: "dist") val toolSuffix = if (System.getProperty("os.name").startsWith("Windows")) ".bat" else "" val binarySuffix = getNativeProgramExtension() val linkerOpts = when { PlatformInfo.isMac() -> listOf("-linker-options","-L/opt/local/lib", "-linker-options", "-L/usr/local/lib") PlatformInfo.isLinux() -> listOf("-linker-options", "-L/usr/lib/x86_64-linux-gnu", "-linker-options", "-L/usr/lib64") PlatformInfo.isWindows() -> listOf("-linker-options", "-L$mingwPath/lib") else -> error("Unsupported platform") } var includeDirsFfmpeg = emptyList() var filterDirsFfmpeg = emptyList() when { PlatformInfo.isMac() -> filterDirsFfmpeg = listOf( "-headerFilterAdditionalSearchPrefix", "/opt/local/include", "-headerFilterAdditionalSearchPrefix", "/usr/local/include" ) PlatformInfo.isLinux() -> filterDirsFfmpeg = listOf( "-headerFilterAdditionalSearchPrefix", "/usr/include", "-headerFilterAdditionalSearchPrefix", "/usr/include/x86_64-linux-gnu", "-headerFilterAdditionalSearchPrefix", "/usr/include/ffmpeg" ) PlatformInfo.isWindows() -> includeDirsFfmpeg = listOf("-compiler-option", "-I$mingwPath/include") } var includeDirsSdl = when { PlatformInfo.isMac() -> listOf( "-compiler-option", "-I/opt/local/include/SDL2", "-compiler-option", "-I/usr/local/include/SDL2" ) PlatformInfo.isLinux() -> listOf("-compiler-option", "-I/usr/include/SDL2") PlatformInfo.isWindows() -> listOf("-compiler-option", "-I$mingwPath/include/SDL2") else -> error("Unsupported platform") } val defaultCompilerOpts = listOf("-g") val buildOpts = getCompileOnlyBenchmarksOpts(project, defaultCompilerOpts) compileBenchmark { applicationName = "Videoplayer" repeatNumber = 10 compilerOpts = buildOpts buildSteps { step("runCinteropFfmpeg") { command = listOf( "$dist/bin/cinterop$toolSuffix", "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/ffmpeg.def" ) + filterDirsFfmpeg + includeDirsFfmpeg } step("runCinteropSdl") { command = listOf( "$dist/bin/cinterop$toolSuffix", "-o", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", "-def", "$dist/../samples/videoplayer/src/nativeInterop/cinterop/sdl.def" ) + includeDirsSdl } step("runKonanProgram") { command = listOf( "$dist/bin/konanc$toolSuffix", "-ea", "-p", "program", "-o", "${buildDir.absolutePath}/program$binarySuffix", "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-ffmpeg.klib", "-l", "$dist/../samples/videoplayer/build/classes/kotlin/videoPlayer/main/videoplayer-cinterop-sdl.klib", "-Xmulti-platform", "$dist/../samples/videoplayer/src/videoPlayerMain/kotlin", "-entry", "sample.videoplayer.main" ) + buildOpts + linkerOpts } } } ================================================ FILE: performance/videoplayer/gradle.properties ================================================ kotlin.native.home=../../dist ================================================ FILE: platformLibs/build.gradle ================================================ import org.jetbrains.kotlin.gradle.plugin.konan.tasks.KonanCacheTask import org.jetbrains.kotlin.KlibInstall import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.* import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.getVisibleName buildscript { repositories { maven { url 'https://cache-redirector.jetbrains.com/maven-central' } mavenCentral() maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } maven { url "https://kotlin.bintray.com/kotlinx" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:$gradlePluginVersion" classpath "org.jetbrains.kotlin:kotlin-native-build-tools:$konanVersion" } } // These properties are used by the 'konan' plugin, thus we set them before applying it. ext.konanHome = distDir.absolutePath def jvmArguments = [project.findProperty("platformLibsJvmArgs") ?: "-Xmx6G", *HostManager.defaultJvmArgs] ext.jvmArgs = jvmArguments.join(" ") ext.setProperty("org.jetbrains.kotlin.native.home", konanHome) ext.setProperty("konan.jvmArgs", jvmArgs) apply plugin: 'konan' //#region Util functions. private ArrayList targetDefFiles(KonanTarget target) { file("src/platform/${getVisibleName(target.family)}") .listFiles() .findAll { it.name.endsWith(".def") } // The libz.a/libz.so and zlib.h are missing in MIPS sysroots. // Just workaround it until we have sysroots corrected. .findAll { ! ((target in targetsWithoutZlib) && it.name == 'zlib.def') } .collect { DefFileKt.DefFile(it, target) } } private String defFileToLibName(String target, String name) { return "$target-$name".toString() } //#endregion // TODO: I think most for the non-DSL language below can either be incorporated into DSL // or moved out of .gradle file. project.rootProject.ext.platformManager.enabled.each { target -> def targetName = target.visibleName ArrayList installTasks = [] ArrayList cacheTasks = [] if (target in cacheableTargets) { tasks.register("${targetName}StdlibCache", KonanCacheTask) { it.target = targetName it.originalKlib = file("$konanHome/klib/common/stdlib") it.cacheRoot = file("$konanHome/klib/cache") it.dependsOn ":${targetName}CrossDistRuntime" } } targetDefFiles(target).each { df -> def libName = defFileToLibName(targetName, df.name) def fileNamePrefix = PlatformLibsInfo.namePrefix konanArtifacts { interop(libName, targets: [targetName]) { defFile df.file artifactName "${fileNamePrefix}${df.name}" noDefaultLibs true noEndorsedLibs true libraries { klibs df.config.depends.collect { "${fileNamePrefix}${it}".toString() } } extraOpts '-Xpurge-user-libs', "-Xshort-module-name", df.name compilerOpts "-fmodules-cache-path=${project.buildDir}/clangModulesCache" } } def libTask = konanArtifacts."$libName"."$targetName" libTask.configure { it.dependsOn df.config.depends.collect { defFileToLibName(targetName, it) } it.dependsOn ":${targetName}CrossDist" it.enableParallel = true } def klibInstallTask = tasks.register("$libName", KlibInstall) { it.klib = project.provider { libTask.get().artifact } it.repo = file("$konanHome/klib/platform/$targetName") it.target = targetName it.dependsOn libTask } installTasks.add(klibInstallTask) if (target in cacheableTargets) { def cacheTask = tasks.register("${libName}Cache", KonanCacheTask) { it.target = targetName it.originalKlib = tasks[libName].installDir.get() it.cacheRoot = file("$konanHome/klib/cache") it.dependsOn ":${targetName}StdlibCache" it.dependsOn tasks[libName] it.dependsOn df.config.depends.collect { def depName = defFileToLibName(targetName, it) "${depName}Cache" } } cacheTasks.add(cacheTask) } } tasks.register("${targetName}Install") { it.dependsOn installTasks } if (target in cacheableTargets) { tasks.register("${targetName}Cache") { it.dependsOn cacheTasks it.group = BasePlugin.BUILD_GROUP it.description = "Builds the compilation cache for platform: ${targetName}" } } } // TODO: Don't install libraries here - copy them in the distPlatformLibs task task hostInstall { dependsOn tasks.withType(KlibInstall.class).matching { it.target == HostManager.hostName } } task hostCache { dependsOn tasks.withType(KonanCacheTask.class).matching { it.target == HostManager.hostName } } task install { dependsOn tasks.withType(KlibInstall.class) } task cache { dependsOn tasks.withType(KonanCacheTask.class) group = BasePlugin.BUILD_GROUP description = "Builds all the compilation caches" } ================================================ FILE: platformLibs/src/platform/android/android.def ================================================ depends = posix package = platform.android headers = jni.h stdbool.h \ android/NeuralNetworks.h \ android/api-level.h android/asset_manager.h android/asset_manager_jni.h \ android/bitmap.h \ android/choreographer.h android/configuration.h \ android/data_space.h android/dlext.h \ android/fdsan.h android/font.h android/font_matcher.h \ android/hardware_buffer.h android/hardware_buffer_jni.h \ android/input.h \ android/keycodes.h \ android/log.h android/looper.h \ android/multinetwork.h \ android/native_activity.h android/native_window.h android/native_window_jni.h android/ndk-version.h \ android/obb.h \ android/rect.h \ android/sensor.h android/set_abort_message.h android/sharedmem.h android/sharedmem_jni.h \ android/storage_manager.h android/surface_texture.h android/surface_texture_jni.h \ android/sync.h android/system_fonts.h \ android/trace.h \ android/versioning.h \ android/window.h headerFilter = ** linkerOpts = -landroid -llog -ljnigraphics --- struct NativeActivityState { struct ANativeActivity* activity; void* savedState; size_t savedStateSize; struct ALooper* looper; }; void getNativeActivityState(struct NativeActivityState* state); void notifySysEventProcessed(); #define LOOPER_ID_SYS 1 typedef enum NativeActivityEventKind { UNKNOWN, DESTROY, START, RESUME, SAVE_INSTANCE_STATE, PAUSE, STOP, CONFIGURATION_CHANGED, LOW_MEMORY, WINDOW_GAINED_FOCUS, WINDOW_LOST_FOCUS, NATIVE_WINDOW_CREATED, NATIVE_WINDOW_DESTROYED, INPUT_QUEUE_CREATED, INPUT_QUEUE_DESTROYED } NativeActivityEventKind; struct NativeActivityEvent { NativeActivityEventKind eventKind; }; struct NativeActivitySaveStateEvent { NativeActivityEventKind eventKind; void* savedState; size_t savedStateSize; }; struct NativeActivityWindowEvent { NativeActivityEventKind eventKind; struct ANativeWindow* window; }; struct NativeActivityQueueEvent { NativeActivityEventKind eventKind; struct AInputQueue* queue; }; ================================================ FILE: platformLibs/src/platform/android/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = language = C --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/android/egl.def ================================================ depends = glesCommon posix package = platform.egl headers = EGL/egl.h EGL/eglext.h EGL/eglplatform.h headerFilter = EGL/** linkerOpts = -lEGL ================================================ FILE: platformLibs/src/platform/android/gles.def ================================================ depends = glesCommon posix package = platform.gles headers = GLES/gl.h GLES/glext.h GLES/glplatform.h headerFilter = GLES/** linkerOpts = -lGLESv1_CM ================================================ FILE: platformLibs/src/platform/android/gles2.def ================================================ depends = glesCommon posix package = platform.gles2 headers = GLES2/gl2.h GLES2/gl2ext.h GLES2/gl2platform.h headerFilter = GLES2/** linkerOpts = -lGLESv2 ================================================ FILE: platformLibs/src/platform/android/gles3.def ================================================ depends = glesCommon posix package = platform.gles3 headers = GLES3/gl3.h GLES3/gl3ext.h GLES3/gl3platform.h headerFilter = GLES3/** linkerOpts = -lGLESv3 ================================================ FILE: platformLibs/src/platform/android/gles31.def ================================================ depends = gles3 glesCommon posix package = platform.gles31 headers = GLES3/gl31.h headerFilter = GLES3/** linkerOpts = -lGLESv3 ================================================ FILE: platformLibs/src/platform/android/glesCommon.def ================================================ depends = posix package = platform.glescommon headers = KHR/khrplatform.h headerFilter = KHR/** ================================================ FILE: platformLibs/src/platform/android/linux.def ================================================ depends = posix package = platform.linux headers = byteswap.h elf.h endian.h features.h lastlog.h link.h \ malloc.h mntent.h termio.h \ uchar.h \ sys/epoll.h sys/inotify.h sys/klog.h sys/sendfile.h \ sys/sysconf.h sys/sysinfo.h \ linux/if_ether.h linux/utime.h \ net/if_packet.h netinet/ether.h netinet/in6.h netpacket/packet.h headers.android_arm32 = time64.h headerFilter = ** linkerOpts = -ldl ================================================ FILE: platformLibs/src/platform/android/media.def ================================================ depends = android posix package = platform.media headers = media/NdkMediaCodec.h media/NdkMediaCrypto.h media/NdkMediaDrm.h media/NdkMediaError.h \ media/NdkMediaExtractor.h media/NdkMediaFormat.h media/NdkMediaMuxer.h headerFilter = media/** linkerOpts = -lmediandk ================================================ FILE: platformLibs/src/platform/android/omxal.def ================================================ depends = posix package = platform.omxal headers = OMXAL/OpenMAXAL.h OMXAL/OpenMAXAL_Android.h OMXAL/OpenMAXAL_Platform.h headerFilter = OMXAL/** linkerOpts = -lOpenMAXAL ================================================ FILE: platformLibs/src/platform/android/posix.def ================================================ depends = package = platform.posix headers = alloca.h ar.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h signal.h \ stdatomic.h stdbool.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h utmp.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h net/if_arp.h net/route.h \ netinet/icmp6.h netinet/if_ether.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h sys/ptrace.h \ sys/queue.h sys/select.h sys/shm.h sys/stat.h \ sys/time.h sys/times.h sys/utsname.h sys/wait.h linkerOpts = -ldl --- // cinterop -target android_arm32 -def klib/src/platform/android/posix.def -o platform.posix.klib // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/android/sles.def ================================================ depends = posix package = platform.sles headers = SLES//OpenSLES.h SLES/OpenSLES_Android.h SLES/OpenSLES_AndroidConfiguration.h \ SLES/OpenSLES_AndroidMetadata.h SLES/OpenSLES_Platform.h headerFilter = SLES/** linkerOpts = -lOpenSLES ================================================ FILE: platformLibs/src/platform/android/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/ios/ARKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMIDI CoreML CoreMedia CoreText CoreVideo EAGL FileProvider Foundation GLKit IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore QuickLook SceneKit Security SpriteKit UIKit UniformTypeIdentifiers UserNotifications Vision darwin posix language = Objective-C package = platform.ARKit modules = ARKit compilerOpts = -framework ARKit linkerOpts = -framework ARKit ================================================ FILE: platformLibs/src/platform/ios/AVFoundation.def ================================================ depends = AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreMedia CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.AVFoundation headers = AVFoundation/AVFoundation.h AVFoundation/AVFAudio.h AVFoundation/AVAudioBuffer.h headerFilter = AVFoundation/** AVFAudio/** compilerOpts = -framework AVFoundation linkerOpts = -framework AVFoundation ================================================ FILE: platformLibs/src/platform/ios/AVKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.AVKit modules = AVKit compilerOpts = -framework AVKit linkerOpts = -framework AVKit ================================================ FILE: platformLibs/src/platform/ios/Accelerate.def ================================================ depends = CoreFoundation CoreGraphics CoreVideo IOSurface darwin posix language = Objective-C package = platform.Accelerate modules = Accelerate compilerOpts = -framework Accelerate linkerOpts = -framework Accelerate ================================================ FILE: platformLibs/src/platform/ios/Accessibility.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.Accessibility modules = Accessibility compilerOpts = -framework Accessibility linkerOpts = -framework Accessibility ================================================ FILE: platformLibs/src/platform/ios/Accounts.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.Accounts modules = Accounts compilerOpts = -framework Accounts linkerOpts = -framework Accounts ================================================ FILE: platformLibs/src/platform/ios/AdSupport.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AdSupport modules = AdSupport compilerOpts = -framework AdSupport linkerOpts = -framework AdSupport ================================================ FILE: platformLibs/src/platform/ios/AddressBook.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.AddressBook modules = AddressBook compilerOpts = -framework AddressBook linkerOpts = -framework AddressBook ================================================ FILE: platformLibs/src/platform/ios/AddressBookUI.def ================================================ depends = AddressBook CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.AddressBookUI modules = AddressBookUI compilerOpts = -framework AddressBookUI linkerOpts = -framework AddressBookUI ================================================ FILE: platformLibs/src/platform/ios/AppClip.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AppClip modules = AppClip compilerOpts = -framework AppClip linkerOpts = -framework AppClip ================================================ FILE: platformLibs/src/platform/ios/AppTrackingTransparency.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AppTrackingTransparency modules = AppTrackingTransparency compilerOpts = -framework AppTrackingTransparency linkerOpts = -framework AppTrackingTransparency ================================================ FILE: platformLibs/src/platform/ios/AssetsLibrary.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.AssetsLibrary modules = AssetsLibrary compilerOpts = -framework AssetsLibrary linkerOpts = -framework AssetsLibrary ================================================ FILE: platformLibs/src/platform/ios/AudioToolbox.def ================================================ depends = CFNetwork CoreAudioTypes CoreFoundation CoreMIDI Foundation Security darwin posix language = Objective-C package = platform.AudioToolbox modules = AudioToolbox AudioUnit compilerOpts = -framework AudioToolbox linkerOpts = -framework AudioToolbox ================================================ FILE: platformLibs/src/platform/ios/AudioUnit.def.disabled ================================================ language = Objective-C package = platform.AudioUnit modules = AudioUnit compilerOpts = -framework AudioUnit linkerOpts = -framework AudioUnit #Disabled: part of AudioToolbox ================================================ FILE: platformLibs/src/platform/ios/AuthenticationServices.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.AuthenticationServices modules = AuthenticationServices compilerOpts = -framework AuthenticationServices linkerOpts = -framework AuthenticationServices ================================================ FILE: platformLibs/src/platform/ios/AutomaticAssessmentConfiguration.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AutomaticAssessmentConfiguration modules = AutomaticAssessmentConfiguration compilerOpts = -framework AutomaticAssessmentConfiguration linkerOpts = -framework AutomaticAssessmentConfiguration ================================================ FILE: platformLibs/src/platform/ios/BackgroundTasks.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.BackgroundTasks modules = BackgroundTasks compilerOpts = -framework BackgroundTasks linkerOpts = -framework BackgroundTasks ================================================ FILE: platformLibs/src/platform/ios/BusinessChat.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.BusinessChat modules = BusinessChat compilerOpts = -framework BusinessChat linkerOpts = -framework BusinessChat ================================================ FILE: platformLibs/src/platform/ios/CFNetwork.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CFNetwork modules = CFNetwork compilerOpts = -framework CFNetwork linkerOpts = -framework CFNetwork excludedFunctions = kCFHTTPAuthenticationSchemeKerberos \ kCFNetworkProxiesProxyAutoConfigJavaScript \ kCFProxyAutoConfigurationHTTPResponseKey ================================================ FILE: platformLibs/src/platform/ios/CallKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CallKit modules = CallKit compilerOpts = -framework CallKit linkerOpts = -framework CallKit ================================================ FILE: platformLibs/src/platform/ios/CarPlay.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreLocation CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MapKit Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.CarPlay modules = CarPlay compilerOpts = -framework CarPlay linkerOpts = -framework CarPlay ================================================ FILE: platformLibs/src/platform/ios/ClassKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.ClassKit modules = ClassKit compilerOpts = -framework ClassKit linkerOpts = -framework ClassKit ================================================ FILE: platformLibs/src/platform/ios/ClockKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.ClockKit modules = ClockKit compilerOpts = -framework ClockKit linkerOpts = -framework ClockKit ================================================ FILE: platformLibs/src/platform/ios/CloudKit.def ================================================ depends = CFNetwork CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CloudKit modules = CloudKit compilerOpts = -framework CloudKit linkerOpts = -framework CloudKit ================================================ FILE: platformLibs/src/platform/ios/Combine.def.disabled ================================================ language = Objective-C package = platform.Combine modules = Combine compilerOpts = -framework Combine linkerOpts = -framework Combine #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/CommonCrypto.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreCrypto modules = CommonCrypto compilerOpts = -D_XOPEN_SOURCE ================================================ FILE: platformLibs/src/platform/ios/Contacts.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.Contacts modules = Contacts compilerOpts = -framework Contacts linkerOpts = -framework Contacts ================================================ FILE: platformLibs/src/platform/ios/ContactsUI.def ================================================ depends = CFNetwork Contacts CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.ContactsUI modules = ContactsUI compilerOpts = -framework ContactsUI linkerOpts = -framework ContactsUI ================================================ FILE: platformLibs/src/platform/ios/CoreAudio.def ================================================ depends = CoreAudioTypes CoreFoundation darwin posix language = Objective-C package = platform.CoreAudio modules = CoreAudio compilerOpts = -framework CoreAudio linkerOpts = -framework CoreAudio ================================================ FILE: platformLibs/src/platform/ios/CoreAudioKit.def ================================================ depends = AudioToolbox CFNetwork CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.CoreAudioKit modules = CoreAudioKit compilerOpts = -framework CoreAudioKit linkerOpts = -framework CoreAudioKit ================================================ FILE: platformLibs/src/platform/ios/CoreAudioTypes.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreAudioTypes modules = CoreAudioTypes compilerOpts = -framework CoreAudioTypes ================================================ FILE: platformLibs/src/platform/ios/CoreBluetooth.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreBluetooth modules = CoreBluetooth compilerOpts = -framework CoreBluetooth linkerOpts = -framework CoreBluetooth excludedFunctions = CBConnectPeripheralOptionStartDelayKey ================================================ FILE: platformLibs/src/platform/ios/CoreData.def ================================================ depends = CFNetwork CloudKit CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CoreData modules = CoreData compilerOpts = -framework CoreData linkerOpts = -framework CoreData ================================================ FILE: platformLibs/src/platform/ios/CoreFoundation.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreFoundation modules = CoreFoundation compilerOpts = -framework CoreFoundation linkerOpts = -framework CoreFoundation ================================================ FILE: platformLibs/src/platform/ios/CoreGraphics.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreGraphics modules = CoreGraphics compilerOpts = -framework CoreGraphics linkerOpts = -framework CoreGraphics ================================================ FILE: platformLibs/src/platform/ios/CoreHaptics.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.CoreHaptics modules = CoreHaptics compilerOpts = -framework CoreHaptics linkerOpts = -framework CoreHaptics ================================================ FILE: platformLibs/src/platform/ios/CoreImage.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreImage modules = CoreImage compilerOpts = -framework CoreImage linkerOpts = -framework CoreImage ================================================ FILE: platformLibs/src/platform/ios/CoreLocation.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreLocation modules = CoreLocation compilerOpts = -framework CoreLocation linkerOpts = -framework CoreLocation ================================================ FILE: platformLibs/src/platform/ios/CoreMIDI.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreMIDI modules = CoreMIDI compilerOpts = -framework CoreMIDI linkerOpts = -framework CoreMIDI ================================================ FILE: platformLibs/src/platform/ios/CoreML.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreVideo Foundation IOSurface ImageIO Security darwin posix language = Objective-C package = platform.CoreML modules = CoreML compilerOpts = -framework CoreML linkerOpts = -framework CoreML ================================================ FILE: platformLibs/src/platform/ios/CoreMedia.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreMedia modules = CoreMedia compilerOpts = -framework CoreMedia linkerOpts = -framework CoreMedia ================================================ FILE: platformLibs/src/platform/ios/CoreMotion.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreMotion modules = CoreMotion compilerOpts = -framework CoreMotion linkerOpts = -framework CoreMotion ================================================ FILE: platformLibs/src/platform/ios/CoreNFC.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreNFC modules = CoreNFC compilerOpts = -framework CoreNFC linkerOpts = -framework CoreNFC ================================================ FILE: platformLibs/src/platform/ios/CoreServices.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreServices modules = CoreServices compilerOpts = -framework CoreServices linkerOpts = -framework CoreServices ================================================ FILE: platformLibs/src/platform/ios/CoreSpotlight.def ================================================ depends = CFNetwork CoreFoundation Foundation Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.CoreSpotlight modules = CoreSpotlight compilerOpts = -framework CoreSpotlight linkerOpts = -framework CoreSpotlight ================================================ FILE: platformLibs/src/platform/ios/CoreTelephony.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreTelephony modules = CoreTelephony compilerOpts = -framework CoreTelephony linkerOpts = -framework CoreTelephony ================================================ FILE: platformLibs/src/platform/ios/CoreText.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.CoreText modules = CoreText compilerOpts = -framework CoreText linkerOpts = -framework CoreText ================================================ FILE: platformLibs/src/platform/ios/CoreVideo.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreVideo modules = CoreVideo compilerOpts = -framework CoreVideo linkerOpts = -framework CoreVideo ================================================ FILE: platformLibs/src/platform/ios/CryptoKit.def.disabled ================================================ language = Objective-C package = platform.CryptoKit modules = CryptoKit compilerOpts = -framework CryptoKit linkerOpts = -framework CryptoKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/CryptoTokenKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CryptoTokenKit modules = CryptoTokenKit compilerOpts = -framework CryptoTokenKit linkerOpts = -framework CryptoTokenKit ================================================ FILE: platformLibs/src/platform/ios/DeveloperToolsSupport.def.disabled ================================================ language = Objective-C package = platform.DeveloperToolsSupport modules = DeveloperToolsSupport compilerOpts = -framework DeveloperToolsSupport linkerOpts = -framework DeveloperToolsSupport #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/DeviceCheck.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.DeviceCheck modules = DeviceCheck compilerOpts = -framework DeviceCheck linkerOpts = -framework DeviceCheck ================================================ FILE: platformLibs/src/platform/ios/EAGL.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.EAGL headers = OpenGLES/EAGL.h OpenGLES/EAGLDrawable.h headerFilter = OpenGLES/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/ios/EventKit.def ================================================ depends = AddressBook CFNetwork CoreFoundation CoreGraphics CoreLocation Foundation Security darwin posix language = Objective-C package = platform.EventKit modules = EventKit compilerOpts = -framework EventKit linkerOpts = -framework EventKit ================================================ FILE: platformLibs/src/platform/ios/EventKitUI.def ================================================ depends = AddressBook CFNetwork CoreFoundation CoreGraphics CoreImage CoreLocation CoreText CoreVideo EAGL EventKit FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.EventKitUI modules = EventKitUI compilerOpts = -framework EventKitUI linkerOpts = -framework EventKitUI ================================================ FILE: platformLibs/src/platform/ios/ExposureNotification.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.ExposureNotification modules = ExposureNotification compilerOpts = -framework ExposureNotification linkerOpts = -framework ExposureNotification ================================================ FILE: platformLibs/src/platform/ios/ExternalAccessory.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.ExternalAccessory modules = ExternalAccessory compilerOpts = -framework ExternalAccessory linkerOpts = -framework ExternalAccessory ================================================ FILE: platformLibs/src/platform/ios/FileProvider.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.FileProvider modules = FileProvider compilerOpts = -framework FileProvider linkerOpts = -framework FileProvider ================================================ FILE: platformLibs/src/platform/ios/FileProviderUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.FileProviderUI modules = FileProviderUI compilerOpts = -framework FileProviderUI linkerOpts = -framework FileProviderUI ================================================ FILE: platformLibs/src/platform/ios/Foundation.def ================================================ depends = CFNetwork CoreFoundation Security darwin posix language = Objective-C package = platform.Foundation modules = Foundation compilerOpts = -framework Foundation linkerOpts = -framework Foundation ================================================ FILE: platformLibs/src/platform/ios/GLKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal ModelIO OpenGLES2 OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.GLKit modules = GLKit compilerOpts = -framework GLKit linkerOpts = -framework GLKit ================================================ FILE: platformLibs/src/platform/ios/GSS.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.GSS modules = GSS compilerOpts = -framework GSS linkerOpts = -framework GSS ================================================ FILE: platformLibs/src/platform/ios/GameController.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit darwin posix language = Objective-C package = platform.GameController modules = GameController compilerOpts = -framework GameController linkerOpts = -framework GameController excludedFunctions = GCCurrentExtendedGamepadSnapshotDataVersion GCCurrentMicroGamepadSnapshotDataVersion ================================================ FILE: platformLibs/src/platform/ios/GameKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork Contacts CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation GLKit GameController GameplayKit IOSurface ImageIO MediaToolbox Metal MetalKit ModelIO OpenGLESCommon QuartzCore ReplayKit SceneKit Security SpriteKit UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.GameKit modules = GameKit compilerOpts = -framework GameKit linkerOpts = -framework GameKit ================================================ FILE: platformLibs/src/platform/ios/GameplayKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation GLKit IOSurface ImageIO Metal OpenGLESCommon QuartzCore SceneKit Security SpriteKit UIKit UserNotifications darwin posix language = Objective-C package = platform.GameplayKit modules = GameplayKit compilerOpts = -framework GameplayKit linkerOpts = -framework GameplayKit ================================================ FILE: platformLibs/src/platform/ios/HealthKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.HealthKit modules = HealthKit compilerOpts = -framework HealthKit linkerOpts = -framework HealthKit ================================================ FILE: platformLibs/src/platform/ios/HealthKitUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation HealthKit IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.HealthKitUI modules = HealthKitUI compilerOpts = -framework HealthKitUI linkerOpts = -framework HealthKitUI ================================================ FILE: platformLibs/src/platform/ios/HomeKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.HomeKit modules = HomeKit compilerOpts = -framework HomeKit linkerOpts = -framework HomeKit ================================================ FILE: platformLibs/src/platform/ios/IOKit.def.disabled ================================================ language = Objective-C package = platform.IOKit modules = IOKit compilerOpts = -framework IOKit linkerOpts = -framework IOKit #Disabled: Not officially available for ios ================================================ FILE: platformLibs/src/platform/ios/IOSurface.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.IOSurface modules = IOSurface compilerOpts = -framework IOSurface linkerOpts = -framework IOSurface ================================================ FILE: platformLibs/src/platform/ios/IdentityLookup.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.IdentityLookup modules = IdentityLookup compilerOpts = -framework IdentityLookup linkerOpts = -framework IdentityLookup ================================================ FILE: platformLibs/src/platform/ios/IdentityLookupUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface IdentityLookup ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.IdentityLookupUI modules = IdentityLookupUI compilerOpts = -framework IdentityLookupUI linkerOpts = -framework IdentityLookupUI ================================================ FILE: platformLibs/src/platform/ios/ImageCaptureCore.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.ImageCaptureCore modules = ImageCaptureCore compilerOpts = -framework ImageCaptureCore linkerOpts = -framework ImageCaptureCore ================================================ FILE: platformLibs/src/platform/ios/ImageIO.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.ImageIO modules = ImageIO compilerOpts = -framework ImageIO linkerOpts = -framework ImageIO ================================================ FILE: platformLibs/src/platform/ios/Intents.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreLocation Foundation Security darwin posix language = Objective-C package = platform.Intents modules = Intents compilerOpts = -framework Intents linkerOpts = -framework Intents ================================================ FILE: platformLibs/src/platform/ios/IntentsUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Intents Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.IntentsUI modules = IntentsUI compilerOpts = -framework IntentsUI linkerOpts = -framework IntentsUI ================================================ FILE: platformLibs/src/platform/ios/JavaScriptCore.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.JavaScriptCore modules = JavaScriptCore compilerOpts = -framework JavaScriptCore linkerOpts = -framework JavaScriptCore ================================================ FILE: platformLibs/src/platform/ios/LinkPresentation.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.LinkPresentation modules = LinkPresentation compilerOpts = -framework LinkPresentation linkerOpts = -framework LinkPresentation ================================================ FILE: platformLibs/src/platform/ios/LocalAuthentication.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.LocalAuthentication modules = LocalAuthentication compilerOpts = -framework LocalAuthentication linkerOpts = -framework LocalAuthentication ================================================ FILE: platformLibs/src/platform/ios/MLCompute.def ================================================ depends = CFNetwork CoreFoundation Foundation IOSurface Metal Security darwin posix language = Objective-C package = platform.MLCompute modules.ios_arm32 = MLCompute compilerOpts.ios_arm32 = -framework MLCompute linkerOpts.ios_arm32 = -framework MLCompute modules.ios_arm64 = MLCompute compilerOpts.ios_arm64 = -framework MLCompute linkerOpts.ios_arm64 = -framework MLCompute ================================================ FILE: platformLibs/src/platform/ios/MapKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreLocation CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MapKit modules = MapKit compilerOpts = -framework MapKit linkerOpts = -framework MapKit ================================================ FILE: platformLibs/src/platform/ios/MediaAccessibility.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreText EAGL Foundation Metal QuartzCore Security darwin posix language = Objective-C package = platform.MediaAccessibility modules = MediaAccessibility compilerOpts = -framework MediaAccessibility linkerOpts = -framework MediaAccessibility ================================================ FILE: platformLibs/src/platform/ios/MediaPlayer.def ================================================ depends = AVFoundation CFNetwork CoreFoundation CoreGraphics CoreImage CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MediaPlayer headers = MediaPlayer/MediaPlayer.h headerFilter = MediaPlayer/** compilerOpts = -framework MediaPlayer linkerOpts = -framework MediaPlayer ================================================ FILE: platformLibs/src/platform/ios/MediaSetup.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MediaSetup modules.ios_arm32 = MediaSetup compilerOpts.ios_arm32 = -framework MediaSetup linkerOpts.ios_arm32 = -framework MediaSetup modules.ios_arm64 = MediaSetup compilerOpts.ios_arm64 = -framework MediaSetup linkerOpts.ios_arm64 = -framework MediaSetup ================================================ FILE: platformLibs/src/platform/ios/MediaToolbox.def ================================================ depends = AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreMedia CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.MediaToolbox modules = MediaToolbox compilerOpts = -framework MediaToolbox linkerOpts = -framework MediaToolbox ================================================ FILE: platformLibs/src/platform/ios/MessageUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MessageUI modules = MessageUI compilerOpts = -framework MessageUI linkerOpts = -framework MessageUI ================================================ FILE: platformLibs/src/platform/ios/Messages.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.Messages modules = Messages compilerOpts = -framework Messages linkerOpts = -framework Messages ================================================ FILE: platformLibs/src/platform/ios/Metal.def ================================================ depends = CFNetwork CoreFoundation Foundation IOSurface Security darwin posix language = Objective-C package = platform.Metal modules = Metal compilerOpts = -framework Metal linkerOpts = -framework Metal excludedFunctions = MTLCommandBufferErrorDomain ================================================ FILE: platformLibs/src/platform/ios/MetalKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal ModelIO OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MetalKit modules = MetalKit compilerOpts = -framework MetalKit linkerOpts = -framework MetalKit ================================================ FILE: platformLibs/src/platform/ios/MetalPerformanceShaders.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal Security darwin posix language = Objective-C package = platform.MetalPerformanceShaders modules = MetalPerformanceShaders compilerOpts = -framework MetalPerformanceShaders linkerOpts = -framework MetalPerformanceShaders ================================================ FILE: platformLibs/src/platform/ios/MetalPerformanceShadersGraph.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal MetalPerformanceShaders Security darwin posix language = Objective-C package = platform.MetalPerformanceShadersGraph modules = MetalPerformanceShadersGraph compilerOpts = -framework MetalPerformanceShadersGraph linkerOpts = -framework MetalPerformanceShadersGraph ================================================ FILE: platformLibs/src/platform/ios/MetricKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.MetricKit modules = MetricKit compilerOpts = -framework MetricKit linkerOpts = -framework MetricKit ================================================ FILE: platformLibs/src/platform/ios/MobileCoreServices.def ================================================ depends = CoreFoundation CoreServices darwin posix language = Objective-C package = platform.MobileCoreServices modules = MobileCoreServices compilerOpts = -framework MobileCoreServices linkerOpts = -framework MobileCoreServices ================================================ FILE: platformLibs/src/platform/ios/ModelIO.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.ModelIO modules = ModelIO compilerOpts = -framework ModelIO linkerOpts = -framework ModelIO ================================================ FILE: platformLibs/src/platform/ios/MultipeerConnectivity.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MultipeerConnectivity modules = MultipeerConnectivity compilerOpts = -framework MultipeerConnectivity linkerOpts = -framework MultipeerConnectivity ================================================ FILE: platformLibs/src/platform/ios/NaturalLanguage.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.NaturalLanguage modules = NaturalLanguage compilerOpts = -framework NaturalLanguage linkerOpts = -framework NaturalLanguage ================================================ FILE: platformLibs/src/platform/ios/NearbyInteraction.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.NearbyInteraction modules = NearbyInteraction compilerOpts = -framework NearbyInteraction linkerOpts = -framework NearbyInteraction ================================================ FILE: platformLibs/src/platform/ios/Network.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.Network modules = Network compilerOpts = -framework Network linkerOpts = -framework Network excludedFunctions = _nw_data_transfer_report_all_paths excludedMacros = NW_ALL_PATHS ================================================ FILE: platformLibs/src/platform/ios/NetworkExtension.def ================================================ depends = CFNetwork CoreFoundation Foundation Network Security darwin posix language = Objective-C package = platform.NetworkExtension modules = NetworkExtension compilerOpts = -framework NetworkExtension linkerOpts = -framework NetworkExtension ================================================ FILE: platformLibs/src/platform/ios/NewsstandKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.NewsstandKit modules = NewsstandKit compilerOpts = -framework NewsstandKit linkerOpts = -framework NewsstandKit ================================================ FILE: platformLibs/src/platform/ios/NotificationCenter.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.NotificationCenter modules = NotificationCenter compilerOpts = -framework NotificationCenter linkerOpts = -framework NotificationCenter ================================================ FILE: platformLibs/src/platform/ios/OSLog.def.disabled ================================================ language = Objective-C package = platform.OSLog modules = OSLog compilerOpts = -framework OSLog linkerOpts = -framework OSLog #Disabled: Not officially available for ios ================================================ FILE: platformLibs/src/platform/ios/OpenAL.def ================================================ depends = darwin posix language = Objective-C package = platform.OpenAL modules = OpenAL compilerOpts = -framework OpenAL linkerOpts = -framework OpenAL ================================================ FILE: platformLibs/src/platform/ios/OpenGLES.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles headers = OpenGLES/ES1/gl.h OpenGLES/ES1/glext.h headerFilter = OpenGLES/ES1/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/ios/OpenGLES2.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles2 headers = OpenGLES/ES2/gl.h OpenGLES/ES2/glext.h headerFilter = OpenGLES/ES2/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/ios/OpenGLES3.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles3 headers = OpenGLES/ES3/gl.h OpenGLES/ES3/glext.h headerFilter = OpenGLES/ES3/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/ios/OpenGLESCommon.def ================================================ depends = posix language = Objective-C package = platform.glescommon headers = OpenGLES/gltypes.h headerFilter = OpenGLES/gltypes.h compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/ios/PDFKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.PDFKit modules = PDFKit compilerOpts = -framework PDFKit linkerOpts = -framework PDFKit ================================================ FILE: platformLibs/src/platform/ios/PassKit.def ================================================ depends = AddressBook CFNetwork Contacts CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.PassKit modules = PassKit compilerOpts = -framework PassKit linkerOpts = -framework PassKit ================================================ FILE: platformLibs/src/platform/ios/PencilKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.PencilKit modules = PencilKit compilerOpts = -framework PencilKit linkerOpts = -framework PencilKit ================================================ FILE: platformLibs/src/platform/ios/Photos.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.Photos modules = Photos compilerOpts = -framework Photos linkerOpts = -framework Photos --- // TODO: ugly hack while forwarded enums are supported. #import ================================================ FILE: platformLibs/src/platform/ios/PhotosUI.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon Photos QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.PhotosUI modules = PhotosUI compilerOpts = -framework PhotosUI linkerOpts = -framework PhotosUI ================================================ FILE: platformLibs/src/platform/ios/PushKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.PushKit modules = PushKit compilerOpts = -framework PushKit linkerOpts = -framework PushKit ================================================ FILE: platformLibs/src/platform/ios/QuartzCore.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics EAGL Foundation Metal Security darwin posix language = Objective-C package = platform.QuartzCore headers = QuartzCore/QuartzCore.h headerFilter = QuartzCore/** compilerOpts = -framework QuartzCore linkerOpts = -framework QuartzCore ================================================ FILE: platformLibs/src/platform/ios/QuickLook.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore QuickLookThumbnailing Security UIKit UserNotifications darwin posix language = Objective-C package = platform.QuickLook modules = QuickLook compilerOpts = -framework QuickLook linkerOpts = -framework QuickLook ================================================ FILE: platformLibs/src/platform/ios/QuickLookThumbnailing.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.QuickLookThumbnailing modules = QuickLookThumbnailing compilerOpts = -framework QuickLookThumbnailing linkerOpts = -framework QuickLookThumbnailing ================================================ FILE: platformLibs/src/platform/ios/RealityKit.def.disabled ================================================ language = Objective-C package = platform.RealityKit modules = RealityKit compilerOpts = -framework RealityKit linkerOpts = -framework RealityKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/ReplayKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.ReplayKit modules = ReplayKit compilerOpts = -framework ReplayKit linkerOpts = -framework ReplayKit ================================================ FILE: platformLibs/src/platform/ios/SafariServices.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.SafariServices modules = SafariServices compilerOpts = -framework SafariServices linkerOpts = -framework SafariServices ================================================ FILE: platformLibs/src/platform/ios/SceneKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation GLKit IOSurface ImageIO Metal ModelIO OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.SceneKit modules = SceneKit compilerOpts = -framework SceneKit linkerOpts = -framework SceneKit ================================================ FILE: platformLibs/src/platform/ios/ScreenTime.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.ScreenTime modules = ScreenTime compilerOpts = -framework ScreenTime linkerOpts = -framework ScreenTime ================================================ FILE: platformLibs/src/platform/ios/Security.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.Security modules = Security compilerOpts = -framework Security linkerOpts = -framework Security ================================================ FILE: platformLibs/src/platform/ios/SensorKit.def ================================================ depends = CFNetwork CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.SensorKit modules = SensorKit compilerOpts = -framework SensorKit linkerOpts = -framework SensorKit ================================================ FILE: platformLibs/src/platform/ios/Social.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.Social modules = Social compilerOpts = -framework Social linkerOpts = -framework Social ================================================ FILE: platformLibs/src/platform/ios/SoundAnalysis.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreML CoreMedia CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.SoundAnalysis modules = SoundAnalysis compilerOpts = -framework SoundAnalysis linkerOpts = -framework SoundAnalysis ================================================ FILE: platformLibs/src/platform/ios/Speech.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreMedia CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.Speech modules = Speech compilerOpts = -framework Speech linkerOpts = -framework Speech ================================================ FILE: platformLibs/src/platform/ios/SpriteKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation GLKit IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.SpriteKit modules = SpriteKit compilerOpts = -framework SpriteKit linkerOpts = -framework SpriteKit ================================================ FILE: platformLibs/src/platform/ios/StoreKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.StoreKit modules = StoreKit compilerOpts = -framework StoreKit linkerOpts = -framework StoreKit ================================================ FILE: platformLibs/src/platform/ios/SwiftUI.def.disabled ================================================ language = Objective-C package = platform.SwiftUI modules = SwiftUI compilerOpts = -framework SwiftUI linkerOpts = -framework SwiftUI #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/SystemConfiguration.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.SystemConfiguration modules = SystemConfiguration compilerOpts = -framework SystemConfiguration linkerOpts = -framework SystemConfiguration ================================================ FILE: platformLibs/src/platform/ios/Twitter.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security Social UIKit UserNotifications darwin posix language = Objective-C package = platform.Twitter modules = Twitter compilerOpts = -framework Twitter linkerOpts = -framework Twitter ================================================ FILE: platformLibs/src/platform/ios/UIKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UserNotifications darwin posix language = Objective-C package = platform.UIKit modules = UIKit compilerOpts = -framework UIKit linkerOpts = -framework UIKit excludedFunctions = UISceneErrorDomain ================================================ FILE: platformLibs/src/platform/ios/UniformTypeIdentifiers.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UniformTypeIdentifiers modules = UniformTypeIdentifiers compilerOpts = -framework UniformTypeIdentifiers linkerOpts = -framework UniformTypeIdentifiers ================================================ FILE: platformLibs/src/platform/ios/UserNotifications.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UserNotifications modules = UserNotifications compilerOpts = -framework UserNotifications linkerOpts = -framework UserNotifications ================================================ FILE: platformLibs/src/platform/ios/UserNotificationsUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.UserNotificationsUI modules = UserNotificationsUI compilerOpts = -framework UserNotificationsUI linkerOpts = -framework UserNotificationsUI ================================================ FILE: platformLibs/src/platform/ios/VideoSubscriberAccount.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.VideoSubscriberAccount modules = VideoSubscriberAccount compilerOpts = -framework VideoSubscriberAccount linkerOpts = -framework VideoSubscriberAccount ================================================ FILE: platformLibs/src/platform/ios/VideoToolbox.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.VideoToolbox modules = VideoToolbox compilerOpts = -framework VideoToolbox linkerOpts = -framework VideoToolbox excludedFunctions = kVTCompressionPropertyKey_UsingGPURegistryID \ kVTDecompressionPropertyKey_MaximizePowerEfficiency \ kVTDecompressionPropertyKey_UsingGPURegistryID \ kVTVideoDecoderSpecification_PreferredDecoderGPURegistryID \ kVTVideoDecoderSpecification_RequiredDecoderGPURegistryID \ kVTVideoEncoderList_GPURegistryID \ kVTVideoEncoderSpecification_PreferredEncoderGPURegistryID \ kVTVideoEncoderSpecification_RequiredEncoderGPURegistryID ================================================ FILE: platformLibs/src/platform/ios/Vision.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreML CoreMedia CoreVideo Foundation IOSurface ImageIO Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.Vision modules = Vision compilerOpts = -framework Vision linkerOpts = -framework Vision ================================================ FILE: platformLibs/src/platform/ios/VisionKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.VisionKit modules = VisionKit compilerOpts = -framework VisionKit linkerOpts = -framework VisionKit ================================================ FILE: platformLibs/src/platform/ios/WatchConnectivity.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.WatchConnectivity modules = WatchConnectivity compilerOpts = -framework WatchConnectivity linkerOpts = -framework WatchConnectivity ================================================ FILE: platformLibs/src/platform/ios/WebKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.WebKit modules = WebKit compilerOpts = -framework WebKit linkerOpts = -framework WebKit ================================================ FILE: platformLibs/src/platform/ios/WidgetKit.def.disabled ================================================ language = Objective-C package = platform.WidgetKit modules = WidgetKit compilerOpts = -framework WidgetKit linkerOpts = -framework WidgetKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/ios/_AVKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AVKit_SwiftUI modules = _AVKit_SwiftUI compilerOpts = -framework _AVKit_SwiftUI linkerOpts = -framework _AVKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_AuthenticationServices_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AuthenticationServices_SwiftUI modules = _AuthenticationServices_SwiftUI compilerOpts = -framework _AuthenticationServices_SwiftUI linkerOpts = -framework _AuthenticationServices_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_HomeKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._HomeKit_SwiftUI modules = _HomeKit_SwiftUI compilerOpts = -framework _HomeKit_SwiftUI linkerOpts = -framework _HomeKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_MapKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._MapKit_SwiftUI modules = _MapKit_SwiftUI compilerOpts = -framework _MapKit_SwiftUI linkerOpts = -framework _MapKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_QuickLook_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._QuickLook_SwiftUI modules = _QuickLook_SwiftUI compilerOpts = -framework _QuickLook_SwiftUI linkerOpts = -framework _QuickLook_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_SceneKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SceneKit_SwiftUI modules = _SceneKit_SwiftUI compilerOpts = -framework _SceneKit_SwiftUI linkerOpts = -framework _SceneKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_SpriteKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SpriteKit_SwiftUI modules = _SpriteKit_SwiftUI compilerOpts = -framework _SpriteKit_SwiftUI linkerOpts = -framework _SpriteKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/_StoreKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._StoreKit_SwiftUI modules = _StoreKit_SwiftUI compilerOpts = -framework _StoreKit_SwiftUI linkerOpts = -framework _StoreKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/ios/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = ** language = C excludedFunctions.ios_arm32 = builtin_clear_cache excludedFunctions.ios_arm64 = builtin_clear_cache --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/ios/darwin.def ================================================ depends = posix language = Objective-C package = platform.darwin headers = AppleTextureEncoder.h AssertMacros.h Availability.h AvailabilityInternal.h \ AvailabilityMacros.h Block.h ConditionalMacros.h MacTypes.h \ TargetConditionals.h __cxxabi_config.h _locale.h _types.h _wctype.h \ aio.h asl.h bitstring.h bzlib.h \ cache.h cache_callbacks.h checkint.h compression.h copyfile.h \ cpio.h cxxabi.h db.h \ dns.h dns_sd.h dns_util.h execinfo.h \ fmtmsg.h fstab.h \ gethostuuid.h glob.h ifaddrs.h inttypes.h iso646.h \ langinfo.h \ libgen.h libunwind.h \ membership.h monetary.h mpool.h \ nameser.h ndbm.h nl_types.h \ notify.h notify_keys.h ntsid.h \ printf.h \ readpassphrase.h removefile.h \ runetype.h sandbox.h standards.h \ stringlist.h sysdir.h sysexits.h tar.h \ ttyent.h \ unwind.h util.h utmpx.h vis.h wordexp.h xattr_flags.h \ bank/bank_types.h \ bsm/audit.h \ os/activity.h os/availability.h os/base.h os/lock.h \ os/log.h os/object.h os/overflow.h os/signpost.h os/trace.h \ simd/simd.h sys/sysctl.h headerFilter = ** excludedFunctions = __tg_promote KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN \ asl_decode_buffer asl_encode_buffer asl_remove_index \ averunnable dbm_forder pidlock ttyaction ttylock ttymsg ttyunlock uuid_generate_early_random \ vm_stats excludedFunctions.ios_arm32 = _Unwind_Backtrace _Unwind_FindEnclosingFunction _Unwind_Find_FDE \ _Unwind_SjLj_ForcedUnwind __deregister_frame __register_frame compilerOpts = -D_XOPEN_SOURCE -DSYSCTL_DEF_ENABLED linkerOpts = -ldl -lz -lbz2 -lcompression -late --- // menu.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/ios/iAd.def ================================================ depends = AVFoundation AVKit AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreText CoreVideo EAGL FileProvider Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.iAd modules = iAd compilerOpts = -framework iAd linkerOpts = -framework iAd ================================================ FILE: platformLibs/src/platform/ios/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h headerFilter = ** linkerOpts = -liconv ================================================ FILE: platformLibs/src/platform/ios/objc.def ================================================ depends = darwin posix language = Objective-C package = platform.objc headers = objc/NSObjCRuntime.h objc/NSObject.h objc/message.h objc/objc-api.h \ objc/objc-exception.h objc/objc-sync.h objc/objc.h objc/runtime.h headerFilter = objc/** compilerOpts = -D_XOPEN_SOURCE linkerOpts = -lobjc --- // objc-auto.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/ios/posix.def ================================================ depends = package = platform.posix headers = alloca.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h float.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h signal.h \ stdatomic.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h \ netinet/icmp6.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/acl.h sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h \ sys/queue.h sys/select.h sys/shm.h sys/stat.h \ sys/syslimits.h sys/time.h sys/times.h sys/utsname.h sys/wait.h compilerOpts = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE linkerOpts = -ldl -lresolv excludedFunctions = acl_valid_link_np add_profil pfctlinput profil unwhiteout zopen getdirentries \ uuid_generate_early_random setgrfile \ in6addr_linklocal_allv2routers excludedFunctions.ios_arm32 = longjmperror excludedFunctions.ios_arm64 = longjmperror excludedFunctions.ios_x64 = pthread_jit_write_protect_np pthread_jit_write_protect_supported_np --- // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/ios/set_depends.sh ================================================ #!/bin/bash ../../../../dist/bin/run_konan defFileDependencies -target ios_arm32 -target ios_arm64 -target ios_x64 *.def ================================================ FILE: platformLibs/src/platform/ios/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zconf.h zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/linux/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = language = C --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/linux/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h ================================================ FILE: platformLibs/src/platform/linux/linux.def ================================================ package = platform.linux headers = aio.h aliases.h a.out.h argp.h argz.h byteswap.h cpio.h crypt.h \ elf.h endian.h envz.h error.h execinfo.h features.h fmtmsg.h \ fpu_control.h \ fstab.h _G_config.h gconv.h glob.h gnu-versions.h \ gshadow.h ieee754.h ifaddrs.h langinfo.h lastlog.h \ libintl.h libio.h link.h malloc.h mcheck.h mntent.h \ monetary.h mqueue.h \ nl_types.h nss.h obstack.h \ printf.h pty.h re_comp.h \ spawn.h stab.h stdc-predef.h stdio_ext.h syscall.h \ tar.h termio.h thread_db.h ttyent.h uchar.h ulimit.h \ ustat.h utmpx.h values.h wait.h wordexp.h \ arpa/ftp.h arpa/inet.h arpa/nameser_compat.h \ arpa/nameser.h arpa/telnet.h arpa/tftp.h \ netinet/if_ether.h net/if_packet.h \ netinet/ether.h linux/in6.h netpacket/packet.h \ sys/acct.h sys/auxv.h sys/bitypes.h sys/cdefs.h \ sys/dir.h sys/epoll.h sys/errno.h \ sys/eventfd.h sys/fanotify.h sys/fcntl.h \ sys/file.h sys/fsuid.h sys/gmon.h sys/gmon_out.h \ sys/inotify.h sys/kd.h sys/klog.h sys/mount.h \ sys/msg.h sys/mtio.h sys/param.h sys/pci.h \ sys/personality.h sys/prctl.h sys/procfs.h sys/profil.h \ sys/raw.h sys/reboot.h sys/resource.h \ sys/sem.h sys/sendfile.h sys/signalfd.h sys/signal.h \ sys/socket.h sys/socketvar.h sys/soundcard.h sys/statfs.h \ sys/statvfs.h sys/stropts.h sys/swap.h sys/syscall.h \ sys/sysctl.h sys/sysinfo.h sys/syslog.h sys/sysmacros.h sys/termios.h \ sys/timeb.h sys/timerfd.h sys/timex.h sys/ttychars.h \ sys/ttydefaults.h sys/types.h sys/ucontext.h sys/uio.h \ sys/ultrasound.h sys/un.h sys/unistd.h sys/user.h \ sys/ustat.h utime.h sys/utsname.h sys/vfs.h sys/vlimit.h \ sys/vt.h sys/vtimes.h sys/xattr.h headers.x86-64 = sys/debugreg.h sys/reg.h sys/io.h sys/perm.h sys/kdaemon.h compilerOpts = -D_ANSI_SOURCE -D_POSIX_C_SOURCE=199309 -D_BSD_SOURCE -D_XOPEN_SOURCE=700 depends = posix ================================================ FILE: platformLibs/src/platform/linux/posix.def ================================================ package = platform.posix headers = alloca.h ar.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h sgtty.h signal.h \ stdatomic.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h utmp.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h net/if_arp.h net/route.h \ netinet/icmp6.h netinet/if_ether.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h sys/ptrace.h \ sys/queue.h sys/select.h sys/shm.h sys/stat.h sys/socket.h \ sys/time.h sys/times.h sys/utsname.h sys/wait.h compilerOpts = -D_ANSI_SOURCE -D_POSIX_C_SOURCE=199309 -D_BSD_SOURCE \ -D_XOPEN_SOURCE=700 -D__need_error_t linkerOpts = -lresolv -lm -lpthread -lutil -lcrypt -lrt excludedFunctions = bindresvport6 __p_section __res_nisourserver __res_npquery \ ns_sign ns_sign2 ns_sign_tcp ns_sign_tcp2 ns_sign_tcp_init \ ns_find_tsig ns_verify ns_verify_tcp ns_verify_tcp_init \ __acos __asin __atan __atan2 __cos __sin __tan __cosh __sinh \ __tanh __acosh __asinh __atanh __exp __frexp __ldexp __log __log10 \ __modf __expm1 __log1p __logb __exp2 __log2 __pow __sqrt __hypot \ __cbrt __ceil __fabs __floor __fmod __drem __significand __copysign \ __nan __j0 __j1 __jn __y0 __y1 __yn __erf __erfc __lgamma __tgamma \ __gamma __lgamma_r __rint __nextafter __remainder __scalbn __ilogb \ __scalbln __nearbyint __round __trunc __remquo __lrint __llrint \ __lround __llround __fdim __fmax __fmin __fma __scalb __acosf __asinf \ __atanf __atan2f __cosf __sinf __tanf __coshf __sinhf __tanhf __acoshf \ __asinhf __atanhf __expf __frexpf __ldexpf __logf __log10f __modff \ __expm1f __log1pf __logbf __exp2f __log2f __powf __sqrtf __hypotf \ __cbrtf __ceilf __fabsf __floorf __fmodf __dremf __significandf \ __copysignf __nanf __j0f __j1f __jnf __y0f __y1f __ynf __erff \ __erfcf __lgammaf __tgammaf __gammaf __lgammaf_r __rintf __nextafterf \ __remainderf __scalbnf __ilogbf __scalblnf __nearbyintf __roundf __truncf \ __remquof __lrintf __llrintf __lroundf __llroundf __fdimf __fmaxf __fminf \ __fmaf __scalbf _ns_flagdata --- // cinterop -target linux -def klib/src/platform/linux/posix.def -o platform.posix.klib // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static short posix_htons(short x) { return htons(x); } static void posix_FD_ZERO(fd_set *set) { FD_ZERO(set); } static void posix_FD_SET(int bit, fd_set *set) { FD_SET(bit, set); } static int posix_FD_ISSET(int bit, fd_set *set) { return FD_ISSET(bit, set); } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/linux/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef -D_ANSI_SOURCE -D_POSIX_C_SOURCE=199309 -D_BSD_SOURCE -D_XOPEN_SOURCE=700 linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/mingw/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = language = C --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/mingw/gdiplus.def ================================================ depends = windows posix package = platform.gdiplus headers = wtypes.h minwindef.h wtypes.h gdiplus/gdiplus.h headerFilter = gdiplus/** compilerOpts = -DUNICODE linkerOpts = -lgdiplus ================================================ FILE: platformLibs/src/platform/mingw/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h headerFilter = NOTHING linkerOpts = -Wl,-Bstatic -liconv -Wl,-Bdynamic --- #undef iconv_t typedef void *iconv_t; #undef iconv_open static inline iconv_t iconv_open(const char* tocode, const char* fromcode) { return libiconv_open(tocode, fromcode); } #undef iconv static inline size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { return libiconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); } #undef iconv_close static inline int iconv_close(iconv_t cd) { return libiconv_close(cd); } ================================================ FILE: platformLibs/src/platform/mingw/opengl32.def ================================================ package = platform.opengl32 headers = GL/gl.h GL/glext.h headerFilter = GL/gl.h GL/glext.h compilerOpts = -DUNICODE linkerOpts = -lopengl32 ================================================ FILE: platformLibs/src/platform/mingw/posix.def ================================================ package = platform.posix headers = assert.h complex.h ctype.h dirent.h errno.h fcntl.h \ fenv.h float.h ftw.h getopt.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h pthread.h sched.h search.h semaphore.h \ setjmp.h signal.h stdint.h stdio.h stdlib.h string.h \ time.h uchar.h unistd.h utime.h wchar.h wctype.h noStringConversion = send sendto recv compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 -DOEMRESOURCE -D_POSIX_C_SOURCE=1 linkerOpts = -lWs2_32 --- // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } static short posix_htons(short x) { return htons(x); } // Hacks to make MinGW Windows headers look more modular than they are. #ifdef _WIN64 #define UINT_PTR unsigned __int64 #define ULONG_PTR unsigned __int64 #else #define UINT_PTR unsigned int #define ULONG_PTR unsigned long #endif #define DWORD_PTR ULONG_PTR #define BYTE unsigned char #define WORD unsigned short #define DWORD unsigned __LONG32 #define ULONG DWORD #define INT int #define UINT unsigned int #define CHAR char #define WCHAR WORD #define LPBYTE BYTE* #define LPINT INT* #define LPWORD WORD* #define LPLONG __LONG32* #define LPDWORD DWORD* #define LPTSTR WCHAR* #define VOID void #define PVOID void* #define LPVOID void* #define LPSTR CHAR* #define LPWSTR WCHAR* #define WINBOOL int #define WPARAM UINT_PTR #define HANDLE LPVOID #define LPHANDLE HANDLE* #define HWND HANDLE #define FARPROC void* #define WINAPI __stdcall #define CALLBACK __stdcall #define PASCAL __pascal #define _INC_WINDOWS #define RPC_NO_WINDOWS_H #define COM_NO_WINDOWS_H #define __INSIDE_CYGWIN__ #include // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static int init_sockets() { WORD wVersionRequested = 0x202; WSADATA wsaData; return WSAStartup(wVersionRequested, &wsaData); } static void deinit_sockets() { WSACleanup(); return; } static void posix_FD_ZERO(fd_set *set) { FD_ZERO(set); } static void posix_FD_SET(int bit, fd_set *set) { FD_SET(bit, set); } static int posix_FD_ISSET(int bit, fd_set *set) { return FD_ISSET(bit, set); } ================================================ FILE: platformLibs/src/platform/mingw/windows.def ================================================ package = platform.windows headers = wtypes.h minwindef.h windows.h commctrl.h dwmapi.h shlobj.h shlwapi.h shobjidl.h \ urlmon.h usp10.h uxtheme.h vfw.h wininet.h winsock2.h ws2tcpip.h ws2def.h compilerOpts = -DUNICODE -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -DWINAPI_FAMILY=3 -DOEMRESOURCE \ -Wno-incompatible-pointer-types -Wno-deprecated-declarations linkerOpts = -lcomctl32 -lcrypt32 -lshlwapi -lshell32 -limm32 -lusp10 -lwininet -lgdi32 -luser32 -lkernel32 -lbcrypt -luuid -ldwmapi noStringConversion = LoadCursorA LoadBitmapA LoadIconA LoadImageA LoadCursorW LoadBitmapW LoadIconW LoadImageW depends = posix ================================================ FILE: platformLibs/src/platform/mingw/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -Wl,-Bstatic -lz -Wl,-Bdynamic --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/osx/AGL.def.disabled ================================================ language = Objective-C package = platform.AGL modules = AGL compilerOpts = -framework AGL linkerOpts = -framework AGL #Disabled: Deprecated. ================================================ FILE: platformLibs/src/platform/osx/AVFoundation.def ================================================ depends = ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.AVFoundation modules = AVFoundation compilerOpts = -framework AVFoundation linkerOpts = -framework AVFoundation ================================================ FILE: platformLibs/src/platform/osx/AVKit.def ================================================ depends = AVFoundation AppKit ApplicationServices AudioToolbox CFNetwork CloudKit Cocoa CoreAudio CoreAudioTypes CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.AVKit modules = AVKit compilerOpts = -framework AVKit linkerOpts = -framework AVKit ================================================ FILE: platformLibs/src/platform/osx/Accelerate.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText CoreVideo DiskArbitration IOKit IOSurface ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Accelerate modules = Accelerate compilerOpts = -framework Accelerate linkerOpts = -framework Accelerate ================================================ FILE: platformLibs/src/platform/osx/Accessibility.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Accessibility modules = Accessibility compilerOpts = -framework Accessibility linkerOpts = -framework Accessibility ================================================ FILE: platformLibs/src/platform/osx/Accounts.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Accounts modules = Accounts compilerOpts = -framework Accounts linkerOpts = -framework Accounts ================================================ FILE: platformLibs/src/platform/osx/AdSupport.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.AdSupport modules = AdSupport compilerOpts = -framework AdSupport linkerOpts = -framework AdSupport ================================================ FILE: platformLibs/src/platform/osx/AddressBook.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.AddressBook headers = AddressBook/AddressBook.h AddressBook/AddressBookUI.h AddressBook/ABActions.h AddressBook/ABPeoplePickerView.h AddressBook/ABPersonView.h AddressBook/ABPersonPicker.h AddressBook/ABPersonPickerDelegate.h headerFilter = AddressBook/** compilerOpts = -framework AddressBook linkerOpts = -framework AddressBook ================================================ FILE: platformLibs/src/platform/osx/AppKit.def ================================================ depends = ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.AppKit modules = AppKit compilerOpts = -framework AppKit linkerOpts = -framework AppKit ================================================ FILE: platformLibs/src/platform/osx/AppTrackingTransparency.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.AppTrackingTransparency modules = AppTrackingTransparency compilerOpts = -framework AppTrackingTransparency linkerOpts = -framework AppTrackingTransparency ================================================ FILE: platformLibs/src/platform/osx/AppleScriptKit.def.disabled ================================================ language = Objective-C package = platform.AppleScriptKit modules = AppleScriptKit compilerOpts = -framework AppleScriptKit linkerOpts = -framework AppleScriptKit #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/AppleScriptObjC.def.disabled ================================================ language = Objective-C package = platform.AppleScriptObjC modules = AppleScriptObjC compilerOpts = -framework AppleScriptObjC linkerOpts = -framework AppleScriptObjC #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/ApplicationServices.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ApplicationServices modules = ApplicationServices ColorSync excludedFunctions = kSpeechSynthesizerInfoManufacturer compilerOpts = -framework ApplicationServices linkerOpts = -framework ApplicationServices ================================================ FILE: platformLibs/src/platform/osx/AudioToolbox.def ================================================ depends = ApplicationServices CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.AudioToolbox headers = AudioToolbox/AudioToolbox.h AudioToolbox/DefaultAudioOutput.h AudioToolbox/AUCocoaUIView.h headerFilter = AudioToolbox/** compilerOpts = -framework AudioToolbox linkerOpts = -framework AudioToolbox ================================================ FILE: platformLibs/src/platform/osx/AudioUnit.def ================================================ depends = ApplicationServices AudioToolbox CFNetwork CoreAudioTypes CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.AudioUnit headers = AudioUnit/AudioUnit.h headerFilter = AudioUnit/** compilerOpts = -framework AudioUnit linkerOpts = -framework AudioUnit ================================================ FILE: platformLibs/src/platform/osx/AudioVideoBridging.def.disabled ================================================ language = Objective-C package = platform.AudioVideoBridging modules = AudioVideoBridging compilerOpts = -framework AudioVideoBridging linkerOpts = -framework AudioVideoBridging #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/AuthenticationServices.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.AuthenticationServices modules = AuthenticationServices compilerOpts = -framework AuthenticationServices linkerOpts = -framework AuthenticationServices ================================================ FILE: platformLibs/src/platform/osx/AutomaticAssessmentConfiguration.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.AutomaticAssessmentConfiguration modules = AutomaticAssessmentConfiguration compilerOpts = -framework AutomaticAssessmentConfiguration linkerOpts = -framework AutomaticAssessmentConfiguration ================================================ FILE: platformLibs/src/platform/osx/Automator.def.disabled ================================================ language = Objective-C package = platform.Automator modules = Automator compilerOpts = -framework Automator linkerOpts = -framework Automator #Disabled: depends on Carbon. ================================================ FILE: platformLibs/src/platform/osx/BackgroundTasks.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.BackgroundTasks modules = BackgroundTasks compilerOpts = -framework BackgroundTasks linkerOpts = -framework BackgroundTasks ================================================ FILE: platformLibs/src/platform/osx/BusinessChat.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.BusinessChat modules = BusinessChat compilerOpts = -framework BusinessChat linkerOpts = -framework BusinessChat ================================================ FILE: platformLibs/src/platform/osx/CFNetwork.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CFNetwork modules = CFNetwork excludedFunctions = kCFHTTPAuthenticationSchemeKerberos kCFHTTPAuthenticationSchemeOAuth1 kCFNetworkProxiesProxyAutoConfigJavaScript kCFProxyAutoConfigurationHTTPResponseKey compilerOpts = -framework CFNetwork linkerOpts = -framework CFNetwork ================================================ FILE: platformLibs/src/platform/osx/CalendarStore.def.disabled ================================================ language = Objective-C package = platform.CalendarStore modules = CalendarStore compilerOpts = -framework CalendarStore linkerOpts = -framework CalendarStore #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/CallKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CallKit modules = CallKit compilerOpts = -framework CallKit linkerOpts = -framework CallKit ================================================ FILE: platformLibs/src/platform/osx/Carbon.def.disabled ================================================ language = Objective-C package = platform.Carbon modules = Carbon compilerOpts = -framework Carbon linkerOpts = -framework Carbon #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/ClassKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ClassKit modules = ClassKit compilerOpts = -framework ClassKit linkerOpts = -framework ClassKit ================================================ FILE: platformLibs/src/platform/osx/CloudKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreLocation CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CloudKit modules = CloudKit compilerOpts = -framework CloudKit linkerOpts = -framework CloudKit ================================================ FILE: platformLibs/src/platform/osx/Cocoa.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.Cocoa modules = Cocoa compilerOpts = -framework Cocoa linkerOpts = -framework Cocoa ================================================ FILE: platformLibs/src/platform/osx/Collaboration.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.Collaboration modules = Collaboration compilerOpts = -framework Collaboration linkerOpts = -framework Collaboration ================================================ FILE: platformLibs/src/platform/osx/ColorSync.def.disabled ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.ColorSync modules = ColorSync compilerOpts = -framework ColorSync linkerOpts = -framework ColorSync #Disabled: ColorSync is a part of ApplicationServices framework. ================================================ FILE: platformLibs/src/platform/osx/Combine.def.disabled ================================================ language = Objective-C package = platform.Combine modules = Combine compilerOpts = -framework Combine linkerOpts = -framework Combine #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/CommonCrypto.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreCrypto modules = CommonCrypto compilerOpts = -D_XOPEN_SOURCE ================================================ FILE: platformLibs/src/platform/osx/Contacts.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Contacts modules = Contacts compilerOpts = -framework Contacts linkerOpts = -framework Contacts ================================================ FILE: platformLibs/src/platform/osx/ContactsUI.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.ContactsUI modules = ContactsUI compilerOpts = -framework ContactsUI linkerOpts = -framework ContactsUI ================================================ FILE: platformLibs/src/platform/osx/CoreAudio.def ================================================ depends = CoreAudioTypes CoreFoundation darwin posix language = Objective-C package = platform.CoreAudio headers = CoreAudio/CoreAudio.h CoreAudio/CoreAudioTypes.h CoreAudio/AudioServerPlugIn.h CoreAudio/AudioHardware.h headerFilter = CoreAudio/** compilerOpts = -framework CoreAudio linkerOpts = -framework CoreAudio ================================================ FILE: platformLibs/src/platform/osx/CoreAudioKit.def ================================================ depends = AppKit ApplicationServices AudioToolbox AudioUnit CFNetwork CloudKit Cocoa CoreAudioTypes CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.CoreAudioKit modules = CoreAudioKit compilerOpts = -framework CoreAudioKit linkerOpts = -framework CoreAudioKit ================================================ FILE: platformLibs/src/platform/osx/CoreAudioTypes.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreAudioTypes modules = CoreAudioTypes compilerOpts = -framework CoreAudioTypes ================================================ FILE: platformLibs/src/platform/osx/CoreBluetooth.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreBluetooth modules = CoreBluetooth compilerOpts = -framework CoreBluetooth linkerOpts = -framework CoreBluetooth ================================================ FILE: platformLibs/src/platform/osx/CoreData.def ================================================ depends = ApplicationServices CFNetwork CloudKit CoreFoundation CoreGraphics CoreLocation CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreData modules = CoreData compilerOpts = -framework CoreData linkerOpts = -framework CoreData ================================================ FILE: platformLibs/src/platform/osx/CoreDisplay.def.disabled ================================================ language = Objective-C package = platform.CoreDisplay modules = CoreDisplay compilerOpts = -framework CoreDisplay linkerOpts = -framework CoreDisplay #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/CoreFoundation.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreFoundation modules = CoreFoundation compilerOpts = -framework CoreFoundation linkerOpts = -framework CoreFoundation ================================================ FILE: platformLibs/src/platform/osx/CoreGraphics.def ================================================ depends = CoreFoundation IOKit darwin libkern posix language = Objective-C package = platform.CoreGraphics modules = CoreGraphics compilerOpts = -framework CoreGraphics linkerOpts = -framework CoreGraphics ================================================ FILE: platformLibs/src/platform/osx/CoreHaptics.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.CoreHaptics modules = CoreHaptics compilerOpts = -framework CoreHaptics linkerOpts = -framework CoreHaptics ================================================ FILE: platformLibs/src/platform/osx/CoreImage.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.CoreImage modules = CoreImage compilerOpts = -framework CoreImage linkerOpts = -framework CoreImage ================================================ FILE: platformLibs/src/platform/osx/CoreLocation.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreLocation modules = CoreLocation compilerOpts = -framework CoreLocation linkerOpts = -framework CoreLocation ================================================ FILE: platformLibs/src/platform/osx/CoreMIDI.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreMIDI modules = CoreMIDI compilerOpts = -framework CoreMIDI linkerOpts = -framework CoreMIDI ================================================ FILE: platformLibs/src/platform/osx/CoreMIDIServer.def.disabled ================================================ language = Objective-C package = platform.CoreMIDIServer modules = CoreMIDIServer compilerOpts = -framework CoreMIDIServer linkerOpts = -framework CoreMIDIServer #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/CoreML.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreML modules = CoreML compilerOpts = -framework CoreML linkerOpts = -framework CoreML ================================================ FILE: platformLibs/src/platform/osx/CoreMedia.def ================================================ depends = ApplicationServices CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.CoreMedia modules = CoreMedia compilerOpts = -framework CoreMedia linkerOpts = -framework CoreMedia ================================================ FILE: platformLibs/src/platform/osx/CoreMediaIO.def.disabled ================================================ language = Objective-C package = platform.CoreMediaIO modules = CoreMediaIO compilerOpts = -framework CoreMediaIO linkerOpts = -framework CoreMediaIO #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/CoreMotion.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreMotion modules = CoreMotion compilerOpts = -framework CoreMotion linkerOpts = -framework CoreMotion ================================================ FILE: platformLibs/src/platform/osx/CoreServices.def ================================================ depends = CFNetwork CoreFoundation DiskArbitration IOKit Security darwin libkern osx posix language = Objective-C package = platform.CoreServices modules = CoreServices excludedFunctions = MDItemCopyAttributeList MDQueryGetSortOptionFlagsForAttribute compilerOpts = -framework CoreServices linkerOpts = -framework CoreServices ================================================ FILE: platformLibs/src/platform/osx/CoreSpotlight.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.CoreSpotlight modules = CoreSpotlight compilerOpts = -framework CoreSpotlight linkerOpts = -framework CoreSpotlight ================================================ FILE: platformLibs/src/platform/osx/CoreTelephony.def ================================================ depends = posix language = Objective-C package = platform.CoreTelephony modules = CoreTelephony compilerOpts = -framework CoreTelephony linkerOpts = -framework CoreTelephony ================================================ FILE: platformLibs/src/platform/osx/CoreText.def ================================================ depends = CoreFoundation CoreGraphics IOKit darwin libkern posix language = Objective-C package = platform.CoreText modules = CoreText compilerOpts = -framework CoreText linkerOpts = -framework CoreText ================================================ FILE: platformLibs/src/platform/osx/CoreVideo.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.CoreVideo modules = CoreVideo compilerOpts = -framework CoreVideo linkerOpts = -framework CoreVideo ================================================ FILE: platformLibs/src/platform/osx/CoreWLAN.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CoreWLAN modules = CoreWLAN compilerOpts = -framework CoreWLAN linkerOpts = -framework CoreWLAN ================================================ FILE: platformLibs/src/platform/osx/CryptoKit.def.disabled ================================================ language = Objective-C package = platform.CryptoKit modules = CryptoKit compilerOpts = -framework CryptoKit linkerOpts = -framework CryptoKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/CryptoTokenKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.CryptoTokenKit modules = CryptoTokenKit compilerOpts = -framework CryptoTokenKit linkerOpts = -framework CryptoTokenKit ================================================ FILE: platformLibs/src/platform/osx/DVDPlayback.def.disabled ================================================ language = Objective-C package = platform.DVDPlayback modules = DVDPlayback compilerOpts = -framework DVDPlayback linkerOpts = -framework DVDPlayback #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/DeveloperToolsSupport.def.disabled ================================================ language = Objective-C package = platform.DeveloperToolsSupport modules = DeveloperToolsSupport compilerOpts = -framework DeveloperToolsSupport linkerOpts = -framework DeveloperToolsSupport #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/DeviceCheck.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.DeviceCheck modules = DeviceCheck compilerOpts = -framework DeviceCheck linkerOpts = -framework DeviceCheck ================================================ FILE: platformLibs/src/platform/osx/DirectoryService.def.disabled ================================================ language = Objective-C package = platform.DirectoryService modules = DirectoryService compilerOpts = -framework DirectoryService linkerOpts = -framework DirectoryService #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/DiscRecording.def.disabled ================================================ language = Objective-C package = platform.DiscRecording modules = DiscRecording compilerOpts = -framework DiscRecording linkerOpts = -framework DiscRecording #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/DiscRecordingUI.def.disabled ================================================ language = Objective-C package = platform.DiscRecordingUI modules = DiscRecordingUI compilerOpts = -framework DiscRecordingUI linkerOpts = -framework DiscRecordingUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/DiskArbitration.def ================================================ depends = CoreFoundation IOKit darwin libkern posix language = Objective-C package = platform.DiskArbitration modules = DiskArbitration compilerOpts = -framework DiskArbitration linkerOpts = -framework DiskArbitration ================================================ FILE: platformLibs/src/platform/osx/DriverKit.def.disabled ================================================ language = Objective-C package = platform.DriverKit modules = DriverKit compilerOpts = -framework DriverKit linkerOpts = -framework DriverKit #Disabled: part of DriverKit ================================================ FILE: platformLibs/src/platform/osx/EventKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreLocation CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.EventKit modules = EventKit compilerOpts = -framework EventKit linkerOpts = -framework EventKit ================================================ FILE: platformLibs/src/platform/osx/ExceptionHandling.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ExceptionHandling modules = ExceptionHandling compilerOpts = -framework ExceptionHandling linkerOpts = -framework ExceptionHandling ================================================ FILE: platformLibs/src/platform/osx/ExecutionPolicy.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ExecutionPolicy modules = ExecutionPolicy compilerOpts = -framework ExecutionPolicy linkerOpts = -framework ExecutionPolicy ================================================ FILE: platformLibs/src/platform/osx/ExternalAccessory.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ExternalAccessory modules = ExternalAccessory compilerOpts = -framework ExternalAccessory linkerOpts = -framework ExternalAccessory ================================================ FILE: platformLibs/src/platform/osx/FWAUserLib.def ================================================ depends = CoreFoundation IOKit darwin libkern posix language = Objective-C package = platform.FWAUserLib modules = FWAUserLib compilerOpts = -framework FWAUserLib linkerOpts = -framework FWAUserLib ================================================ FILE: platformLibs/src/platform/osx/FileProvider.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.FileProvider modules = FileProvider compilerOpts = -framework FileProvider linkerOpts = -framework FileProvider ================================================ FILE: platformLibs/src/platform/osx/FileProviderUI.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration FileProvider Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.FileProviderUI modules = FileProviderUI compilerOpts = -framework FileProviderUI linkerOpts = -framework FileProviderUI ================================================ FILE: platformLibs/src/platform/osx/FinderSync.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.FinderSync modules = FinderSync compilerOpts = -framework FinderSync linkerOpts = -framework FinderSync ================================================ FILE: platformLibs/src/platform/osx/ForceFeedback.def ================================================ depends = CoreFoundation IOKit darwin libkern posix language = Objective-C package = platform.ForceFeedback modules = ForceFeedback compilerOpts = -framework ForceFeedback linkerOpts = -framework ForceFeedback ================================================ FILE: platformLibs/src/platform/osx/Foundation.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Foundation modules = Foundation compilerOpts = -framework Foundation linkerOpts = -framework Foundation ================================================ FILE: platformLibs/src/platform/osx/GLKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal ModelIO OpenGL3 OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.GLKit modules = GLKit compilerOpts = -framework GLKit linkerOpts = -framework GLKit ================================================ FILE: platformLibs/src/platform/osx/GLUT.def ================================================ depends = OpenGL OpenGLCommon darwin posix language = Objective-C package = platform.GLUT modules = GLUT compilerOpts = -framework GLUT linkerOpts = -framework GLUT excludedFunctions = __smapDrawSphereMapMeshBack __smapDrawSphereMapMeshSide __smapValidateSphereMapMesh \ bisecting_plane draw_angle_style_back_cap draw_angle_style_front_cap \ draw_binorm_segment_c_and_edge_n draw_binorm_segment_c_and_facet_n draw_binorm_segment_edge_n \ draw_binorm_segment_facet_n draw_raw_style_end_cap draw_round_style_cap_callback \ draw_segment_c_and_edge_n draw_segment_c_and_facet_n draw_segment_color draw_segment_edge_n \ draw_segment_facet_n draw_segment_plain extrusion_angle_join extrusion_raw_join \ extrusion_round_or_cut_join rot_about_axis_d rot_about_axis_f rot_axis_d rot_axis_f \ rot_omega_d rot_omega_f up_sanity_check urot_about_axis_d urot_about_axis_f urot_axis_d \ urot_axis_f urot_omega_d urot_omega_f uview_direction_d uview_direction_f uviewpoint_d uviewpoint_f ================================================ FILE: platformLibs/src/platform/osx/GSS.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.GSS modules = GSS compilerOpts = -framework GSS linkerOpts = -framework GSS ================================================ FILE: platformLibs/src/platform/osx/GameController.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.GameController modules = GameController compilerOpts = -framework GameController linkerOpts = -framework GameController ================================================ FILE: platformLibs/src/platform/osx/GameKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa Contacts CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation GLKit GameController GameplayKit IOKit IOSurface ImageIO Metal MetalKit ModelIO OpenGLCommon QuartzCore SceneKit Security SpriteKit darwin libkern osx posix language = Objective-C package = platform.GameKit modules = GameKit compilerOpts = -framework GameKit linkerOpts = -framework GameKit excludedFunctions = GKVoiceChatServiceErrorDomain ================================================ FILE: platformLibs/src/platform/osx/GameplayKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation GLKit IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore SceneKit Security SpriteKit darwin libkern osx posix language = Objective-C package = platform.GameplayKit modules = GameplayKit compilerOpts = -framework GameplayKit linkerOpts = -framework GameplayKit ================================================ FILE: platformLibs/src/platform/osx/HIDDriverKit.def.disabled ================================================ language = Objective-C package = platform.HIDDriverKit modules = HIDDriverKit compilerOpts = -framework HIDDriverKit linkerOpts = -framework HIDDriverKit #Disabled: part of DriverKit ================================================ FILE: platformLibs/src/platform/osx/Hypervisor.def ================================================ depends = darwin osx posix language = Objective-C package = platform.Hypervisor # Using headers instead of modules to workaround incorrect module definition in Xcode 12.2: headers = Hypervisor/Hypervisor.h headerFilter = Hypervisor/** compilerOpts = -framework Hypervisor linkerOpts = -framework Hypervisor ================================================ FILE: platformLibs/src/platform/osx/ICADevices.def.disabled ================================================ language = Objective-C package = platform.ICADevices modules = ICADevices compilerOpts = -framework ICADevices linkerOpts = -framework ICADevices #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/IMServicePlugIn.def.disabled ================================================ language = Objective-C package = platform.IMServicePlugIn modules = IMServicePlugIn compilerOpts = -framework IMServicePlugIn linkerOpts = -framework IMServicePlugIn #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/IOBluetooth.def ================================================ depends = ApplicationServices CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.IOBluetooth modules = IOBluetooth compilerOpts = -framework IOBluetooth linkerOpts = -framework IOBluetooth ================================================ FILE: platformLibs/src/platform/osx/IOBluetoothUI.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOBluetooth IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.IOBluetoothUI modules = IOBluetoothUI # -DAPI_UNAVAILABLE_BEGIN workarounds bug in IOBluetoothUI headers which use this macro before importing it. compilerOpts = -framework IOBluetoothUI -DAPI_UNAVAILABLE_BEGIN=__API_UNAVAILABLE_BEGIN linkerOpts = -framework IOBluetoothUI ================================================ FILE: platformLibs/src/platform/osx/IOKit.def ================================================ depends = CoreFoundation darwin libkern posix language = Objective-C package = platform.IOKit modules = IOKit compilerOpts = -framework IOKit linkerOpts = -framework IOKit excludedFunctions = IOURLWriteDataAndPropertiesToResource ================================================ FILE: platformLibs/src/platform/osx/IOSurface.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.IOSurface modules = IOSurface compilerOpts = -framework IOSurface linkerOpts = -framework IOSurface ================================================ FILE: platformLibs/src/platform/osx/IOUSBHost.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.IOUSBHost modules = IOUSBHost compilerOpts = -framework IOUSBHost linkerOpts = -framework IOUSBHost ================================================ FILE: platformLibs/src/platform/osx/IdentityLookup.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.IdentityLookup modules = IdentityLookup compilerOpts = -framework IdentityLookup linkerOpts = -framework IdentityLookup ================================================ FILE: platformLibs/src/platform/osx/ImageCaptureCore.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.ImageCaptureCore modules = ImageCaptureCore compilerOpts = -framework ImageCaptureCore linkerOpts = -framework ImageCaptureCore ================================================ FILE: platformLibs/src/platform/osx/ImageIO.def ================================================ depends = CoreFoundation CoreGraphics IOKit darwin libkern posix language = Objective-C package = platform.ImageIO modules = ImageIO compilerOpts = -framework ImageIO linkerOpts = -framework ImageIO ================================================ FILE: platformLibs/src/platform/osx/InputMethodKit.def.disabled ================================================ language = Objective-C package = platform.InputMethodKit modules = InputMethodKit compilerOpts = -framework InputMethodKit linkerOpts = -framework InputMethodKit #Disabled: Deprecated ================================================ FILE: platformLibs/src/platform/osx/InstallerPlugins.def.disabled ================================================ language = Objective-C package = platform.InstallerPlugins modules = InstallerPlugins compilerOpts = -framework InstallerPlugins linkerOpts = -framework InstallerPlugins #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/InstantMessage.def.disabled ================================================ language = Objective-C package = platform.InstantMessage modules = InstantMessage compilerOpts = -framework InstantMessage linkerOpts = -framework InstantMessage #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Intents.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreLocation CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Intents modules = Intents compilerOpts = -framework Intents linkerOpts = -framework Intents ================================================ FILE: platformLibs/src/platform/osx/JavaFrameEmbedding.def.disabled ================================================ language = Objective-C package = platform.JavaFrameEmbedding modules = JavaFrameEmbedding compilerOpts = -framework JavaFrameEmbedding linkerOpts = -framework JavaFrameEmbedding #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/JavaNativeFoundation.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.JavaNativeFoundation modules = JavaNativeFoundation compilerOpts = -framework JavaNativeFoundation linkerOpts = -framework JavaNativeFoundation ================================================ FILE: platformLibs/src/platform/osx/JavaRuntimeSupport.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.JavaRuntimeSupport modules = JavaRuntimeSupport compilerOpts = -framework JavaRuntimeSupport linkerOpts = -framework JavaRuntimeSupport ================================================ FILE: platformLibs/src/platform/osx/JavaScriptCore.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.JavaScriptCore modules = JavaScriptCore compilerOpts = -framework JavaScriptCore linkerOpts = -framework JavaScriptCore ================================================ FILE: platformLibs/src/platform/osx/JavaVM.def.disabled ================================================ language = Objective-C package = platform.JavaVM modules = JavaVM compilerOpts = -framework JavaVM linkerOpts = -framework JavaVM #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Kerberos.def.disabled ================================================ language = Objective-C package = platform.Kerberos modules = Kerberos compilerOpts = -framework Kerberos linkerOpts = -framework Kerberos #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Kernel.def.disabled ================================================ language = Objective-C package = platform.Kernel modules = Kernel compilerOpts = -framework Kernel linkerOpts = -framework Kernel #Disabled: Framework without module ================================================ FILE: platformLibs/src/platform/osx/KernelManagement.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.KernelManagement modules = KernelManagement compilerOpts = -framework KernelManagement linkerOpts = -framework KernelManagement ================================================ FILE: platformLibs/src/platform/osx/LDAP.def.disabled ================================================ language = Objective-C package = platform.LDAP modules = LDAP compilerOpts = -framework LDAP linkerOpts = -framework LDAP #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/LatentSemanticMapping.def.disabled ================================================ language = Objective-C package = platform.LatentSemanticMapping modules = LatentSemanticMapping compilerOpts = -framework LatentSemanticMapping linkerOpts = -framework LatentSemanticMapping #Disabled: Framework without module ================================================ FILE: platformLibs/src/platform/osx/LinkPresentation.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.LinkPresentation modules = LinkPresentation compilerOpts = -framework LinkPresentation linkerOpts = -framework LinkPresentation ================================================ FILE: platformLibs/src/platform/osx/LocalAuthentication.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.LocalAuthentication modules = LocalAuthentication compilerOpts = -framework LocalAuthentication linkerOpts = -framework LocalAuthentication ================================================ FILE: platformLibs/src/platform/osx/MLCompute.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit IOSurface ImageIO Metal Security darwin libkern osx posix language = Objective-C package = platform.MLCompute modules = MLCompute compilerOpts = -framework MLCompute linkerOpts = -framework MLCompute ================================================ FILE: platformLibs/src/platform/osx/MapKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.MapKit modules = MapKit compilerOpts = -framework MapKit linkerOpts = -framework MapKit ================================================ FILE: platformLibs/src/platform/osx/MediaAccessibility.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.MediaAccessibility modules = MediaAccessibility compilerOpts = -framework MediaAccessibility linkerOpts = -framework MediaAccessibility ================================================ FILE: platformLibs/src/platform/osx/MediaLibrary.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.MediaLibrary modules = MediaLibrary compilerOpts = -framework MediaLibrary linkerOpts = -framework MediaLibrary ================================================ FILE: platformLibs/src/platform/osx/MediaPlayer.def ================================================ depends = AVFoundation ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreMedia CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.MediaPlayer modules = MediaPlayer compilerOpts = -framework MediaPlayer linkerOpts = -framework MediaPlayer ================================================ FILE: platformLibs/src/platform/osx/MediaToolbox.def ================================================ depends = ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.MediaToolbox modules = MediaToolbox compilerOpts = -framework MediaToolbox linkerOpts = -framework MediaToolbox ================================================ FILE: platformLibs/src/platform/osx/Message.def.disabled ================================================ language = Objective-C package = platform.Message modules = Message compilerOpts = -framework Message linkerOpts = -framework Message #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Metal.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit IOSurface ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Metal modules = Metal excludedFunctions = MTLRenderPipelineErrorDomain compilerOpts = -framework Metal linkerOpts = -framework Metal ================================================ FILE: platformLibs/src/platform/osx/MetalKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal ModelIO OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.MetalKit modules = MetalKit compilerOpts = -framework MetalKit linkerOpts = -framework MetalKit ================================================ FILE: platformLibs/src/platform/osx/MetalPerformanceShaders.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit IOSurface ImageIO Metal Security darwin libkern osx posix language = Objective-C package = platform.MetalPerformanceShaders modules = MetalPerformanceShaders compilerOpts = -framework MetalPerformanceShaders linkerOpts = -framework MetalPerformanceShaders ================================================ FILE: platformLibs/src/platform/osx/MetalPerformanceShadersGraph.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit IOSurface ImageIO Metal MetalPerformanceShaders Security darwin libkern osx posix language = Objective-C package = platform.MetalPerformanceShadersGraph modules = MetalPerformanceShadersGraph compilerOpts = -framework MetalPerformanceShadersGraph linkerOpts = -framework MetalPerformanceShadersGraph ================================================ FILE: platformLibs/src/platform/osx/MetricKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.MetricKit modules = MetricKit compilerOpts = -framework MetricKit linkerOpts = -framework MetricKit ================================================ FILE: platformLibs/src/platform/osx/ModelIO.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ModelIO modules = ModelIO compilerOpts = -framework ModelIO linkerOpts = -framework ModelIO ================================================ FILE: platformLibs/src/platform/osx/MorphunAssetsUpdater.def.disabled ================================================ language = Objective-C package = platform.MorphunAssetsUpdater modules = MorphunAssetsUpdater compilerOpts = -framework MorphunAssetsUpdater linkerOpts = -framework MorphunAssetsUpdater #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/MultipeerConnectivity.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.MultipeerConnectivity modules = MultipeerConnectivity compilerOpts = -framework MultipeerConnectivity linkerOpts = -framework MultipeerConnectivity ================================================ FILE: platformLibs/src/platform/osx/NaturalLanguage.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.NaturalLanguage modules = NaturalLanguage compilerOpts = -framework NaturalLanguage linkerOpts = -framework NaturalLanguage ================================================ FILE: platformLibs/src/platform/osx/NearbyInteraction.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.NearbyInteraction modules = NearbyInteraction compilerOpts = -framework NearbyInteraction linkerOpts = -framework NearbyInteraction ================================================ FILE: platformLibs/src/platform/osx/NetFS.def.disabled ================================================ language = Objective-C package = platform.NetFS modules = NetFS compilerOpts = -framework NetFS linkerOpts = -framework NetFS #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Network.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.Network modules = Network compilerOpts = -framework Network linkerOpts = -framework Network ================================================ FILE: platformLibs/src/platform/osx/NetworkExtension.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Network Security darwin libkern osx posix language = Objective-C package = platform.NetworkExtension modules = NetworkExtension compilerOpts = -framework NetworkExtension linkerOpts = -framework NetworkExtension ================================================ FILE: platformLibs/src/platform/osx/NetworkingDriverKit.def.disabled ================================================ language = Objective-C package = platform.NetworkingDriverKit modules = NetworkingDriverKit compilerOpts = -framework NetworkingDriverKit linkerOpts = -framework NetworkingDriverKit #Disabled: part of DriverKit ================================================ FILE: platformLibs/src/platform/osx/NotificationCenter.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.NotificationCenter modules = NotificationCenter compilerOpts = -framework NotificationCenter linkerOpts = -framework NotificationCenter ================================================ FILE: platformLibs/src/platform/osx/OSAKit.def.disabled ================================================ language = Objective-C package = platform.OSAKit modules = OSAKit compilerOpts = -framework OSAKit linkerOpts = -framework OSAKit #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/OSLog.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.OSLog modules = OSLog compilerOpts = -framework OSLog linkerOpts = -framework OSLog ================================================ FILE: platformLibs/src/platform/osx/OpenAL.def.disabled ================================================ language = Objective-C package = platform.OpenAL modules = OpenAL compilerOpts = -framework OpenAL linkerOpts = -framework OpenAL #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/OpenCL.def.disabled ================================================ language = Objective-C package = platform.OpenCL modules = OpenCL compilerOpts = -framework OpenCL linkerOpts = -framework OpenCL #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/OpenDirectory.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.OpenDirectory modules = OpenDirectory compilerOpts = -framework OpenDirectory linkerOpts = -framework OpenDirectory excludedFunctions = kODAuthenticationTypeClearTextReadOnly kODAuthenticationTypeSetCertificateHashAsCurrent ================================================ FILE: platformLibs/src/platform/osx/OpenGL.def ================================================ depends = OpenGLCommon darwin posix language = Objective-C package = platform.OpenGL headers = OpenGL/glu.h headerFilter = OpenGL/gl.h OpenGL/glext.h OpenGL/glu.h compilerOpts = -framework OpenGL linkerOpts = -framework OpenGL ================================================ FILE: platformLibs/src/platform/osx/OpenGL3.def ================================================ depends = OpenGLCommon darwin posix language = Objective-C package = platform.OpenGL3 headers = OpenGL/gl3.h OpenGL/gl3ext.h headerFilter = OpenGL/gl3.h OpenGL/gl3ext.h compilerOpts = -framework OpenGL linkerOpts = -framework OpenGL ================================================ FILE: platformLibs/src/platform/osx/OpenGLCommon.def ================================================ depends = darwin posix language = Objective-C package = platform.OpenGLCommon headers = OpenGL/OpenGL.h headerFilter = OpenGL/** compilerOpts = -framework OpenGL linkerOpts = -framework OpenGL ================================================ FILE: platformLibs/src/platform/osx/PCIDriverKit.def.disabled ================================================ language = Objective-C package = platform.PCIDriverKit modules = PCIDriverKit compilerOpts = -framework PCIDriverKit linkerOpts = -framework PCIDriverKit #Disabled: part of DriverKit ================================================ FILE: platformLibs/src/platform/osx/PCSC.def.disabled ================================================ language = Objective-C package = platform.PCSC modules = PCSC compilerOpts = -framework PCSC linkerOpts = -framework PCSC #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/PDFKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.PDFKit headers = PDFKit/PDFKit.h headerFilter = PDFKit/** compilerOpts = -framework PDFKit linkerOpts = -framework PDFKit ================================================ FILE: platformLibs/src/platform/osx/ParavirtualizedGraphics.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.ParavirtualizedGraphics modules = ParavirtualizedGraphics compilerOpts = -framework ParavirtualizedGraphics linkerOpts = -framework ParavirtualizedGraphics ================================================ FILE: platformLibs/src/platform/osx/PassKit.def ================================================ depends = AppKit ApplicationServices CFNetwork Contacts CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.PassKit modules = PassKit compilerOpts = -framework PassKit linkerOpts = -framework PassKit ================================================ FILE: platformLibs/src/platform/osx/PencilKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.PencilKit modules = PencilKit compilerOpts = -framework PencilKit linkerOpts = -framework PencilKit ================================================ FILE: platformLibs/src/platform/osx/Photos.def ================================================ depends = AVFoundation ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.Photos modules = Photos compilerOpts = -framework Photos linkerOpts = -framework Photos --- // TODO: ugly hack while forwarded enums are supported. typedef NS_ENUM(NSInteger, UIImageOrientation) { UIImageOrientationUnavailableOnMacOS }; ================================================ FILE: platformLibs/src/platform/osx/PhotosUI.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MapKit Metal OpenGLCommon Photos QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.PhotosUI modules = PhotosUI compilerOpts = -framework PhotosUI linkerOpts = -framework PhotosUI ================================================ FILE: platformLibs/src/platform/osx/PreferencePanes.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.PreferencePanes modules = PreferencePanes compilerOpts = -framework PreferencePanes linkerOpts = -framework PreferencePanes ================================================ FILE: platformLibs/src/platform/osx/PushKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.PushKit modules = PushKit compilerOpts = -framework PushKit linkerOpts = -framework PushKit ================================================ FILE: platformLibs/src/platform/osx/Python.def.disabled ================================================ language = Objective-C package = platform.Python modules = Python compilerOpts = -framework Python linkerOpts = -framework Python #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/QTKit.def.disabled ================================================ language = Objective-C package = platform.QTKit modules = QTKit compilerOpts = -framework QTKit linkerOpts = -framework QTKit #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Quartz.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageCaptureCore ImageIO Metal OpenGL OpenGLCommon PDFKit QuartzCore QuickLook Security darwin libkern osx posix language = Objective-C package = platform.Quartz modules = Quartz compilerOpts = -framework Quartz linkerOpts = -framework Quartz excludedFunctions = QCCompositionInputRSSArticleDurationKey QCCompositionInputRSSFeedURLKey QCCompositionProtocolRSSVisualizer ================================================ FILE: platformLibs/src/platform/osx/QuartzCore.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.QuartzCore modules = QuartzCore compilerOpts = -framework QuartzCore linkerOpts = -framework QuartzCore ================================================ FILE: platformLibs/src/platform/osx/QuickLook.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.QuickLook modules = QuickLook compilerOpts = -framework QuickLook linkerOpts = -framework QuickLook ================================================ FILE: platformLibs/src/platform/osx/QuickLookThumbnailing.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.QuickLookThumbnailing modules = QuickLookThumbnailing compilerOpts = -framework QuickLookThumbnailing linkerOpts = -framework QuickLookThumbnailing ================================================ FILE: platformLibs/src/platform/osx/RealityKit.def.disabled ================================================ language = Objective-C package = platform.RealityKit modules = RealityKit compilerOpts = -framework RealityKit linkerOpts = -framework RealityKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/ReplayKit.def ================================================ depends = AVFoundation AppKit ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreData CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.ReplayKit modules = ReplayKit compilerOpts = -framework ReplayKit linkerOpts = -framework ReplayKit ================================================ FILE: platformLibs/src/platform/osx/Ruby.def.disabled ================================================ language = Objective-C package = platform.Ruby modules = Ruby compilerOpts = -framework Ruby linkerOpts = -framework Ruby #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/SafariServices.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.SafariServices modules = SafariServices compilerOpts = -framework SafariServices linkerOpts = -framework SafariServices ================================================ FILE: platformLibs/src/platform/osx/SceneKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation GLKit IOKit IOSurface ImageIO Metal ModelIO OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.SceneKit modules = SceneKit compilerOpts = -framework SceneKit linkerOpts = -framework SceneKit ================================================ FILE: platformLibs/src/platform/osx/ScreenSaver.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.ScreenSaver modules = ScreenSaver compilerOpts = -framework ScreenSaver linkerOpts = -framework ScreenSaver ================================================ FILE: platformLibs/src/platform/osx/ScreenTime.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.ScreenTime modules = ScreenTime compilerOpts = -framework ScreenTime linkerOpts = -framework ScreenTime ================================================ FILE: platformLibs/src/platform/osx/ScriptingBridge.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.ScriptingBridge modules = ScriptingBridge compilerOpts = -framework ScriptingBridge linkerOpts = -framework ScriptingBridge ================================================ FILE: platformLibs/src/platform/osx/Security.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.Security modules = Security excludedFunctions = CSSMOID_APPLE_EXTENSION_DEVELOPER_AUTHENTICATION CSSMOID_APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING \ CSSMOID_APPLE_EXTENSION_SERVER_AUTHENTICATION CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE \ CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING CSSMOID_DES_CBC CSSMOID_DomainComponent CSSMOID_InhibitAnyPolicy \ CSSM_KR_CreateRecoveryEnablementContext CSSM_KR_CreateRecoveryRegistrationContext CSSM_KR_CreateRecoveryRequestContext \ CSSM_KR_GenerateRecoveryFields CSSM_KR_GetPolicyInfo CSSM_KR_GetRecoveredObject CSSM_KR_PassThrough \ CSSM_KR_ProcessRecoveryFields CSSM_KR_QueryPolicyInfo CSSM_KR_RecoveryRequest CSSM_KR_RecoveryRequestAbort \ CSSM_KR_RecoveryRetrieve CSSM_KR_RegistrationRequest CSSM_KR_RegistrationRetrieve CSSM_KR_SetEnterpriseRecoveryPolicy \ CSSM_SPI_ModuleAttach CSSM_SPI_ModuleDetach CSSM_SPI_ModuleLoad CSSM_SPI_ModuleUnload ModuleManagerAuthenticate \ SecDecryptTransformGetTypeID SecDigestTransformGetTypeID SecEncryptTransformGetTypeID kSecACLAuthorizationChangeACL \ kSecACLAuthorizationChangeOwner kSecCertificateUsageDeriveAndSign kSecCertificateUsageSigning \ kSecCertificateUsageSigningAndEncrypting kSecCodeInfoPlatformIdentifier kSecGuestAttributeArchitecture \ kSecGuestAttributeSubarchitecture kSecOAEPMGF1DigestAlgorithmAttributeName kSecOAEPMessageLengthAttributeName \ kSecOIDAPPLE_EXTENSION_AAI_INTERMEDIATE kSecOIDAPPLE_EXTENSION_APPLEID_INTERMEDIATE \ kSecOIDAPPLE_EXTENSION_INTERMEDIATE_MARKER kSecOIDAPPLE_EXTENSION_ITMS_INTERMEDIATE \ kSecOIDAPPLE_EXTENSION_WWDR_INTERMEDIATE kSecPolicyAppleiChat oidAnsip384r1 oidAnsip521r1 oidEcPrime192v1 \ oidEcPrime256v1 oidExtendedKeyUsageTimeStamping oidNameConstraints AuthorizationPluginCreate compilerOpts = -framework Security linkerOpts = -framework Security ================================================ FILE: platformLibs/src/platform/osx/SecurityFoundation.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.SecurityFoundation modules = SecurityFoundation compilerOpts = -framework SecurityFoundation linkerOpts = -framework SecurityFoundation ================================================ FILE: platformLibs/src/platform/osx/SecurityInterface.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security SecurityFoundation darwin libkern osx posix language = Objective-C package = platform.SecurityInterface modules = SecurityInterface compilerOpts = -framework SecurityInterface linkerOpts = -framework SecurityInterface ================================================ FILE: platformLibs/src/platform/osx/SensorKit.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreLocation CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.SensorKit modules = SensorKit compilerOpts = -framework SensorKit linkerOpts = -framework SensorKit ================================================ FILE: platformLibs/src/platform/osx/ServiceManagement.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.ServiceManagement modules = ServiceManagement compilerOpts = -framework ServiceManagement linkerOpts = -framework ServiceManagement ================================================ FILE: platformLibs/src/platform/osx/Social.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.Social modules = Social compilerOpts = -framework Social linkerOpts = -framework Social ================================================ FILE: platformLibs/src/platform/osx/SoundAnalysis.def ================================================ depends = AVFoundation ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreML CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.SoundAnalysis modules = SoundAnalysis compilerOpts = -framework SoundAnalysis linkerOpts = -framework SoundAnalysis ================================================ FILE: platformLibs/src/platform/osx/Speech.def ================================================ depends = AVFoundation ApplicationServices AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMIDI CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO MediaToolbox Metal OpenGLCommon QuartzCore Security UniformTypeIdentifiers darwin libkern osx posix language = Objective-C package = platform.Speech modules = Speech compilerOpts = -framework Speech linkerOpts = -framework Speech ================================================ FILE: platformLibs/src/platform/osx/SpriteKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CloudKit Cocoa CoreData CoreFoundation CoreGraphics CoreImage CoreLocation CoreServices CoreText CoreVideo DiskArbitration Foundation GLKit IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.SpriteKit modules = SpriteKit compilerOpts = -framework SpriteKit linkerOpts = -framework SpriteKit ================================================ FILE: platformLibs/src/platform/osx/StoreKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.StoreKit modules = StoreKit compilerOpts = -framework StoreKit linkerOpts = -framework StoreKit ================================================ FILE: platformLibs/src/platform/osx/SwiftUI.def.disabled ================================================ language = Objective-C package = platform.SwiftUI modules = SwiftUI compilerOpts = -framework SwiftUI linkerOpts = -framework SwiftUI #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/SyncServices.def.disabled ================================================ language = Objective-C package = platform.SyncServices modules = SyncServices compilerOpts = -framework SyncServices linkerOpts = -framework SyncServices #Disabled: Deprecated in 10.7 ================================================ FILE: platformLibs/src/platform/osx/System.def.disabled ================================================ language = Objective-C package = platform.System modules = System compilerOpts = -framework System linkerOpts = -framework System #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/SystemConfiguration.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.SystemConfiguration modules = SystemConfiguration compilerOpts = -framework SystemConfiguration linkerOpts = -framework SystemConfiguration ================================================ FILE: platformLibs/src/platform/osx/SystemExtensions.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.SystemExtensions modules = SystemExtensions compilerOpts = -framework SystemExtensions linkerOpts = -framework SystemExtensions ================================================ FILE: platformLibs/src/platform/osx/TWAIN.def.disabled ================================================ language = Objective-C package = platform.TWAIN modules = TWAIN compilerOpts = -framework TWAIN linkerOpts = -framework TWAIN #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Tcl.def.disabled ================================================ language = Objective-C package = platform.Tcl modules = Tcl compilerOpts = -framework Tcl linkerOpts = -framework Tcl #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/Tk.def.disabled ================================================ language = Objective-C package = platform.Tk modules = Tk compilerOpts = -framework Tk linkerOpts = -framework Tk #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/USBDriverKit.def.disabled ================================================ language = Objective-C package = platform.USBDriverKit modules = USBDriverKit compilerOpts = -framework USBDriverKit linkerOpts = -framework USBDriverKit #Disabled: part of DriverKit ================================================ FILE: platformLibs/src/platform/osx/UniformTypeIdentifiers.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.UniformTypeIdentifiers modules = UniformTypeIdentifiers compilerOpts = -framework UniformTypeIdentifiers linkerOpts = -framework UniformTypeIdentifiers ================================================ FILE: platformLibs/src/platform/osx/UserNotifications.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.UserNotifications modules = UserNotifications compilerOpts = -framework UserNotifications linkerOpts = -framework UserNotifications ================================================ FILE: platformLibs/src/platform/osx/UserNotificationsUI.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.UserNotificationsUI modules = UserNotificationsUI compilerOpts = -framework UserNotificationsUI linkerOpts = -framework UserNotificationsUI ================================================ FILE: platformLibs/src/platform/osx/VideoDecodeAcceleration.def.disabled ================================================ language = Objective-C package = platform.VideoDecodeAcceleration modules = VideoDecodeAcceleration compilerOpts = -framework VideoDecodeAcceleration linkerOpts = -framework VideoDecodeAcceleration #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/VideoSubscriberAccount.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.VideoSubscriberAccount modules = VideoSubscriberAccount compilerOpts = -framework VideoSubscriberAccount linkerOpts = -framework VideoSubscriberAccount ================================================ FILE: platformLibs/src/platform/osx/VideoToolbox.def ================================================ depends = ApplicationServices CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.VideoToolbox modules = VideoToolbox compilerOpts = -framework VideoToolbox linkerOpts = -framework VideoToolbox ================================================ FILE: platformLibs/src/platform/osx/Virtualization.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.Virtualization modules = Virtualization compilerOpts = -framework Virtualization linkerOpts = -framework Virtualization ================================================ FILE: platformLibs/src/platform/osx/Vision.def ================================================ depends = ApplicationServices CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreML CoreMedia CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO Metal OpenGLCommon Security darwin libkern osx posix language = Objective-C package = platform.Vision modules = Vision compilerOpts = -framework Vision linkerOpts = -framework Vision ================================================ FILE: platformLibs/src/platform/osx/WebKit.def ================================================ depends = AppKit ApplicationServices CFNetwork CoreData CoreFoundation CoreGraphics CoreImage CoreServices CoreText CoreVideo DiskArbitration Foundation IOKit IOSurface ImageIO JavaScriptCore Metal OpenGLCommon QuartzCore Security darwin libkern osx posix language = Objective-C package = platform.WebKit modules = WebKit compilerOpts = -framework WebKit linkerOpts = -framework WebKit excludedFunctions = NPN_Construct NPN_ConvertPoint NPN_CreateObject NPN_DestroyStream NPN_Enumerate \ NPN_Evaluate NPN_ForceRedraw NPN_GetAuthenticationInfo NPN_GetIntIdentifier \ NPN_GetJavaEnv NPN_GetJavaPeer NPN_GetProperty NPN_GetStringIdentifier \ NPN_GetStringIdentifiers NPN_GetURL NPN_GetURLNotify NPN_GetValue NPN_GetValueForURL \ NPN_HandleEvent NPN_HasMethod NPN_HasProperty NPN_IdentifierIsString NPN_IntFromIdentifier \ NPN_InvalidateRect NPN_InvalidateRegion NPN_Invoke NPN_InvokeDefault NPN_MemAlloc \ NPN_MemFlush NPN_MemFree NPN_NewStream NPN_PluginThreadAsyncCall NPN_PopPopupsEnabledState \ NPN_PopUpContextMenu NPN_PostURL NPN_PostURLNotify NPN_PushPopupsEnabledState NPN_ReleaseObject \ NPN_ReleaseVariantValue NPN_ReloadPlugins NPN_RemoveProperty NPN_RequestRead NPN_RetainObject \ NPN_ScheduleTimer NPN_SetException NPN_SetProperty NPN_SetValue NPN_SetValueForURL NPN_Status \ NPN_URLRedirectResponse NPN_UTF8FromIdentifier NPN_UnfocusInstance NPN_UnscheduleTimer \ NPN_UserAgent NPN_Version NPN_Write NPP_ClearSiteData NPP_Destroy NPP_DestroyStream \ NPP_GetJavaClass NPP_GetSitesWithData NPP_GetValue NPP_GotFocus NPP_HandleEvent NPP_Initialize \ NPP_LostFocus NPP_New NPP_NewStream NPP_Print NPP_SetValue NPP_SetWindow NPP_Shutdown \ NPP_StreamAsFile NPP_URLNotify NPP_URLRedirectNotify NPP_Write NPP_WriteReady ================================================ FILE: platformLibs/src/platform/osx/WidgetKit.def.disabled ================================================ language = Objective-C package = platform.WidgetKit modules = WidgetKit compilerOpts = -framework WidgetKit linkerOpts = -framework WidgetKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/osx/_AVKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AVKit_SwiftUI modules = _AVKit_SwiftUI compilerOpts = -framework _AVKit_SwiftUI linkerOpts = -framework _AVKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_AuthenticationServices_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AuthenticationServices_SwiftUI modules = _AuthenticationServices_SwiftUI compilerOpts = -framework _AuthenticationServices_SwiftUI linkerOpts = -framework _AuthenticationServices_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_MapKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._MapKit_SwiftUI modules = _MapKit_SwiftUI compilerOpts = -framework _MapKit_SwiftUI linkerOpts = -framework _MapKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_QuickLook_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._QuickLook_SwiftUI modules = _QuickLook_SwiftUI compilerOpts = -framework _QuickLook_SwiftUI linkerOpts = -framework _QuickLook_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_SceneKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SceneKit_SwiftUI modules = _SceneKit_SwiftUI compilerOpts = -framework _SceneKit_SwiftUI linkerOpts = -framework _SceneKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_SpriteKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SpriteKit_SwiftUI modules = _SpriteKit_SwiftUI compilerOpts = -framework _SpriteKit_SwiftUI linkerOpts = -framework _SpriteKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/_StoreKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._StoreKit_SwiftUI modules = _StoreKit_SwiftUI compilerOpts = -framework _StoreKit_SwiftUI linkerOpts = -framework _StoreKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/osx/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = ** language = C --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/osx/darwin.def ================================================ depends = posix language = Objective-C package = platform.darwin headers = AppleTextureEncoder.h AssertMacros.h Availability.h AvailabilityInternal.h \ AvailabilityMacros.h Block.h ConditionalMacros.h MacTypes.h \ TargetConditionals.h __cxxabi_config.h _locale.h _types.h _wctype.h \ aio.h asl.h bitstring.h bzlib.h \ cache.h cache_callbacks.h checkint.h compression.h copyfile.h \ cpio.h cxxabi.h db.h \ dns.h dns_sd.h dns_util.h execinfo.h \ fmtmsg.h fstab.h \ gethostuuid.h glob.h ifaddrs.h inttypes.h iso646.h \ langinfo.h \ libgen.h libunwind.h \ membership.h monetary.h mpool.h \ nameser.h ndbm.h nl_types.h \ notify.h notify_keys.h ntsid.h \ printf.h \ readpassphrase.h removefile.h \ runetype.h sandbox.h standards.h \ stringlist.h sysdir.h sysexits.h tar.h \ ttyent.h \ unwind.h util.h utmpx.h vis.h wordexp.h xattr_flags.h \ bank/bank_types.h \ bsm/libbsm.h \ os/activity.h os/availability.h os/base.h os/lock.h \ os/log.h os/object.h os/overflow.h os/signpost.h os/trace.h \ simd/simd.h sys/sysctl.h sys/user.h \ sys/_types/_os_inline.h \ net/if_media.h sys/disk.h sys/kernel_types.h headerFilter = ** excludedFunctions = __tg_promote KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN \ asl_decode_buffer asl_encode_buffer asl_remove_index \ averunnable dbm_forder pidlock ttyaction ttylock ttymsg ttyunlock uuid_generate_early_random \ DebugStr Debugger SysBreak SysBreakFunc SysBreakStr clock_get_res clock_set_res \ mach_vm_region_info mach_vm_region_info_64 os_trace_info_with_payload safe_gets \ task_wire vm_map_64 vm_map_exec_lockdown vm_mapped_pages_info vm_region vm_region_recurse \ xpc_debugger_api_misuse_info \ vm_stats compilerOpts.macos_x64 = -D_XOPEN_SOURCE -DSHARED_LIBBIND -D_DARWIN_NO_64_BIT_INODE -DSYSCTL_DEF_ENABLED compilerOpts.macos_arm64 = -D_XOPEN_SOURCE -DSHARED_LIBBIND -DSYSCTL_DEF_ENABLED linkerOpts = -ldl -lz -lcurses -lbz2 -lcompression -late -lbsm ================================================ FILE: platformLibs/src/platform/osx/iTunesLibrary.def ================================================ depends = ApplicationServices CFNetwork CoreFoundation CoreGraphics CoreServices CoreText DiskArbitration Foundation IOKit ImageIO Security darwin libkern osx posix language = Objective-C package = platform.iTunesLibrary modules = iTunesLibrary compilerOpts = -framework iTunesLibrary linkerOpts = -framework iTunesLibrary ================================================ FILE: platformLibs/src/platform/osx/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h headerFilter = ** linkerOpts = -liconv ================================================ FILE: platformLibs/src/platform/osx/libkern.def ================================================ depends = darwin posix language = Objective-C package = platform.libkern headers = libkern/OSTypes.h libkern/OSReturn.h libkern/OSAtomic.h device/device_types.h device/device_types.h headerFilter = libkern/** device/** compilerOpts = -DIOKIT linkerOpts = ================================================ FILE: platformLibs/src/platform/osx/objc.def ================================================ depends = darwin posix language = Objective-C package = platform.objc headers = objc/List.h objc/NSObjCRuntime.h objc/NSObject.h objc/Object.h objc/Protocol.h \ objc/hashtable.h objc/hashtable2.h objc/message.h objc/objc-api.h \ objc/objc-class.h objc/objc-exception.h objc/objc-load.h objc/objc-runtime.h \ objc/objc-sync.h objc/objc.h objc/runtime.h headerFilter = objc/** compilerOpts = -D_XOPEN_SOURCE excludedFunctions = KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN linkerOpts = -lobjc --- // objc-auto.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/osx/osx.def ================================================ depends = darwin posix language = Objective-C package = platform.osx headers = NSSystemDirectories.h \ aliasdb.h bootparams.h bootstrap.h \ com_err.h \ crt_externs.h \ disktab.h dtrace.h \ eti.h expat.h \ expat_external.h form.h fsproperties.h get_compat.h \ gssapi.h histedit.h \ krb5.h launch.h lber.h lber_types.h ldif.h libc.h libcharset.h \ libproc.h localcharset.h \ monitor.h \ nc_tparm.h ncurses.h ncurses_dll.h \ nlist.h \ panel.h pcap-bpf.h pcap-namedb.h pcap.h printerdb.h \ profile.h ranlib.h rune.h \ stab.h strhash.h \ struct.h term.h \ term_entry.h termcap.h tic.h timeconv.h tzfile.h \ unctrl.h vproc.h \ atm/atm_types.h corpses/task_corpse.h \ hfs/hfs_format.h hfs/hfs_mount.h hfs/hfs_unistr.h \ sys/kauth.h headers.macos_x64 = \ emmintrin.h \ mmintrin.h \ xmmintrin.h headers.macos_arm64 = \ arm64/hv/hv_kern_types.h headerFilter = ** exportForwardDeclarations = objcnames.classes.NSObject objcnames.protocols.NSObjectProtocol compilerOpts = -D_XOPEN_SOURCE excludedFunctions = KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN vm_map_64 vm_mapped_pages_info vm_region_recurse vm_region xpc_debugger_api_misuse_info \ _dtrace_debug _dtrace_mangled _nc_progname _nc_trace_xnames _nc_tracebits _nc_tracef _traceattr2 _tracechar _tracedump _tracef \ _tracemouse _traceattr _tracechtype _tracechtype2 trace DebugStr Debugger SysBreak SysBreakFunc SysBreakStr \ asl_decode_buffer asl_encode_buffer asl_remove_index au_to_kevent ber_bvreplace ber_decode_oid ber_encode_oid \ ber_flush2 ber_peek_element ber_skip_data ber_skip_element ber_sockbuf_io_debug ber_sockbuf_io_fd \ ber_sockbuf_io_readahead ber_sockbuf_io_tcp ber_sockbuf_io_udp ber_strndup ber_strnlen clock_get_res \ clock_set_res dbm_forder dns_search_list_domain_count dtrace_aggregate_walk_sorted dtrace_print \ error_manager et_asn1_error_table et_k524_error_table et_kdb5_error_table et_krb5_error_table et_kv5m_error_table \ et_prof_error_table gss_export_name_object gss_import_name_object initialize_asn1_error_table initialize_k524_error_table \ initialize_kdb5_error_table initialize_krb5_error_table initialize_kv5m_error_table initialize_prof_error_table \ krb5_c_keylengths krb5_c_prf krb5_c_prf_length krb5_c_random_to_key krb5_cc_get_flags krb5_get_fallback_host_realm \ ldif_debug libcharset_set_relocation_prefix locale_charset mach_vm_region_info mach_vm_region_info_64 map_fd \ nlist os_trace_info_with_payload safe_gets task_wire trace \ pcap_createsrcstr pcap_findalldevs_ex pcap_open pcap_parsesrcstr pcap_remoteact_accept pcap_remoteact_cleanup \ pcap_remoteact_close pcap_remoteact_list pcap_setsampling linkerOpts = -late -lbsm -lbz2 -lcompression -ledit -lexpat -lform -lkrb5 -llber -lldap -lncurses -lpanel -lpcap -ldtrace --- // menu.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/osx/posix.def ================================================ depends = package = platform.posix headers = alloca.h ar.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h float.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h sgtty.h signal.h \ stdatomic.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h utmp.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h net/if_arp.h net/route.h \ netinet/icmp6.h netinet/if_ether.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/acl.h sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h sys/ptrace.h \ sys/queue.h sys/select.h sys/shm.h sys/socket.h sys/stat.h \ sys/syslimits.h sys/time.h sys/times.h sys/utsname.h sys/wait.h compilerOpts.macos_x64 = -D_XOPEN_SOURCE -DSHARED_LIBBIND -D_DARWIN_NO_64_BIT_INODE -D_DARWIN_C_SOURCE compilerOpts.macos_arm64 = -D_XOPEN_SOURCE -DSHARED_LIBBIND -D_DARWIN_C_SOURCE # -D_ANSI_SOURCE, sigh, breaks user_addr_t excludedFunctions = KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN add_profil \ addrsel_policy_init \ in6addr_linklocal_allv2routers \ pfctlinput regwnexec_l res_send_setqhook res_send_setrhook \ unwhiteout zopen profil openat acl_valid_link_np uuid_generate_early_random setgrfile linkerOpts = -ldl -lresolv --- // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static short posix_htons(short x) { return htons(x); } static void posix_FD_ZERO(fd_set *set) { FD_ZERO(set); } static void posix_FD_SET(int bit, fd_set *set) { FD_SET(bit, set); } static int posix_FD_ISSET(int bit, fd_set *set) { return FD_ISSET(bit, set); } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/osx/set_depends.sh ================================================ #!/bin/bash ../../../../dist/bin/run_konan defFileDependencies -target macos_x64 -target macos_arm64 *.def ================================================ FILE: platformLibs/src/platform/osx/vmnet.def ================================================ depends = darwin posix language = Objective-C package = platform.vmnet modules = vmnet compilerOpts = -framework vmnet linkerOpts = -framework vmnet ================================================ FILE: platformLibs/src/platform/osx/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zconf.h zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/tvos/AVFoundation.def ================================================ depends = AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.AVFoundation headers = AVFoundation/AVFoundation.h AVFoundation/AVFAudio.h AVFoundation/AVAudioBuffer.h headerFilter = AVFoundation/** AVFAudio/** compilerOpts = -framework AVFoundation linkerOpts = -framework AVFoundation ================================================ FILE: platformLibs/src/platform/tvos/AVKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMedia CoreText CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.AVKit modules = AVKit compilerOpts = -framework AVKit linkerOpts = -framework AVKit ================================================ FILE: platformLibs/src/platform/tvos/Accelerate.def ================================================ depends = CoreFoundation CoreGraphics CoreVideo IOSurface darwin posix language = Objective-C package = platform.Accelerate modules = Accelerate compilerOpts = -framework Accelerate linkerOpts = -framework Accelerate ================================================ FILE: platformLibs/src/platform/tvos/Accessibility.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.Accessibility modules = Accessibility compilerOpts = -framework Accessibility linkerOpts = -framework Accessibility ================================================ FILE: platformLibs/src/platform/tvos/AdSupport.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AdSupport modules = AdSupport compilerOpts = -framework AdSupport linkerOpts = -framework AdSupport ================================================ FILE: platformLibs/src/platform/tvos/AppTrackingTransparency.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AppTrackingTransparency modules = AppTrackingTransparency compilerOpts = -framework AppTrackingTransparency linkerOpts = -framework AppTrackingTransparency ================================================ FILE: platformLibs/src/platform/tvos/AudioToolbox.def ================================================ depends = CFNetwork CoreAudioTypes CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AudioToolbox modules = AudioToolbox AudioUnit compilerOpts = -framework AudioToolbox linkerOpts = -framework AudioToolbox ================================================ FILE: platformLibs/src/platform/tvos/AudioUnit.def.disabled ================================================ depends = AudioToolbox CFNetwork CoreAudioTypes CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.AudioUnit modules = AudioUnit compilerOpts = -framework AudioUnit linkerOpts = -framework AudioUnit #Disabled: part of AudioToolbox ================================================ FILE: platformLibs/src/platform/tvos/AuthenticationServices.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.AuthenticationServices modules = AuthenticationServices compilerOpts = -framework AuthenticationServices linkerOpts = -framework AuthenticationServices ================================================ FILE: platformLibs/src/platform/tvos/BackgroundTasks.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.BackgroundTasks modules = BackgroundTasks compilerOpts = -framework BackgroundTasks linkerOpts = -framework BackgroundTasks ================================================ FILE: platformLibs/src/platform/tvos/CFNetwork.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CFNetwork modules = CFNetwork compilerOpts = -framework CFNetwork linkerOpts = -framework CFNetwork ================================================ FILE: platformLibs/src/platform/tvos/CloudKit.def ================================================ depends = CFNetwork CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CloudKit modules = CloudKit compilerOpts = -framework CloudKit linkerOpts = -framework CloudKit ================================================ FILE: platformLibs/src/platform/tvos/Combine.def.disabled ================================================ language = Objective-C package = platform.Combine modules = Combine compilerOpts = -framework Combine linkerOpts = -framework Combine #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/tvos/CommonCrypto.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreCrypto modules = CommonCrypto compilerOpts = -D_XOPEN_SOURCE ================================================ FILE: platformLibs/src/platform/tvos/CoreAudio.def ================================================ depends = CoreAudioTypes CoreFoundation darwin posix language = Objective-C package = platform.CoreAudio modules = CoreAudio compilerOpts = -framework CoreAudio linkerOpts = -framework CoreAudio ================================================ FILE: platformLibs/src/platform/tvos/CoreAudioKit.def.disabled ================================================ language = Objective-C package = platform.CoreAudioKit modules = CoreAudioKit compilerOpts = -framework CoreAudioKit linkerOpts = -framework CoreAudioKit #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/CoreAudioTypes.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreAudioTypes modules = CoreAudioTypes compilerOpts = -framework CoreAudioTypes ================================================ FILE: platformLibs/src/platform/tvos/CoreBluetooth.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreBluetooth modules = CoreBluetooth compilerOpts = -framework CoreBluetooth linkerOpts = -framework CoreBluetooth ================================================ FILE: platformLibs/src/platform/tvos/CoreData.def ================================================ depends = CFNetwork CloudKit CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CoreData modules = CoreData compilerOpts = -framework CoreData linkerOpts = -framework CoreData ================================================ FILE: platformLibs/src/platform/tvos/CoreFoundation.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreFoundation modules = CoreFoundation compilerOpts = -framework CoreFoundation linkerOpts = -framework CoreFoundation ================================================ FILE: platformLibs/src/platform/tvos/CoreGraphics.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreGraphics modules = CoreGraphics compilerOpts = -framework CoreGraphics linkerOpts = -framework CoreGraphics ================================================ FILE: platformLibs/src/platform/tvos/CoreHaptics.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.CoreHaptics modules = CoreHaptics compilerOpts = -framework CoreHaptics linkerOpts = -framework CoreHaptics ================================================ FILE: platformLibs/src/platform/tvos/CoreImage.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreImage modules = CoreImage compilerOpts = -framework CoreImage linkerOpts = -framework CoreImage ================================================ FILE: platformLibs/src/platform/tvos/CoreLocation.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreLocation modules = CoreLocation compilerOpts = -framework CoreLocation linkerOpts = -framework CoreLocation ================================================ FILE: platformLibs/src/platform/tvos/CoreML.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreVideo Foundation IOSurface ImageIO Security darwin posix language = Objective-C package = platform.CoreML modules = CoreML compilerOpts = -framework CoreML linkerOpts = -framework CoreML ================================================ FILE: platformLibs/src/platform/tvos/CoreMedia.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreMedia modules = CoreMedia compilerOpts = -framework CoreMedia linkerOpts = -framework CoreMedia ================================================ FILE: platformLibs/src/platform/tvos/CoreServices.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreServices modules = CoreServices compilerOpts = -framework CoreServices linkerOpts = -framework CoreServices ================================================ FILE: platformLibs/src/platform/tvos/CoreSpotlight.def ================================================ depends = CFNetwork CoreFoundation Foundation Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.CoreSpotlight modules = CoreSpotlight compilerOpts = -framework CoreSpotlight linkerOpts = -framework CoreSpotlight ================================================ FILE: platformLibs/src/platform/tvos/CoreText.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.CoreText modules = CoreText compilerOpts = -framework CoreText linkerOpts = -framework CoreText ================================================ FILE: platformLibs/src/platform/tvos/CoreVideo.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.CoreVideo modules = CoreVideo compilerOpts = -framework CoreVideo linkerOpts = -framework CoreVideo ================================================ FILE: platformLibs/src/platform/tvos/CryptoKit.def.disabled ================================================ language = Objective-C package = platform.CryptoKit modules = CryptoKit compilerOpts = -framework CryptoKit linkerOpts = -framework CryptoKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/tvos/CryptoTokenKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CryptoTokenKit modules = CryptoTokenKit compilerOpts = -framework CryptoTokenKit linkerOpts = -framework CryptoTokenKit ================================================ FILE: platformLibs/src/platform/tvos/DeveloperToolsSupport.def.disabled ================================================ language = Objective-C package = platform.DeveloperToolsSupport modules = DeveloperToolsSupport compilerOpts = -framework DeveloperToolsSupport linkerOpts = -framework DeveloperToolsSupport #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/tvos/DeviceCheck.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.DeviceCheck modules = DeviceCheck compilerOpts = -framework DeviceCheck linkerOpts = -framework DeviceCheck ================================================ FILE: platformLibs/src/platform/tvos/EAGL.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.EAGL headers = OpenGLES/EAGL.h OpenGLES/EAGLDrawable.h headerFilter = OpenGLES/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/tvos/ExposureNotification.def.disabled ================================================ language = Objective-C package = platform.ExposureNotification modules = ExposureNotification compilerOpts = -framework ExposureNotification linkerOpts = -framework ExposureNotification #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/ExternalAccessory.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.ExternalAccessory modules = ExternalAccessory compilerOpts = -framework ExternalAccessory linkerOpts = -framework ExternalAccessory ================================================ FILE: platformLibs/src/platform/tvos/Foundation.def ================================================ depends = CFNetwork CoreFoundation Security darwin posix language = Objective-C package = platform.Foundation modules = Foundation compilerOpts = -framework Foundation linkerOpts = -framework Foundation ================================================ FILE: platformLibs/src/platform/tvos/GLKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal ModelIO OpenGLES2 OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.GLKit modules = GLKit compilerOpts = -framework GLKit linkerOpts = -framework GLKit ================================================ FILE: platformLibs/src/platform/tvos/GameController.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit darwin posix language = Objective-C package = platform.GameController modules = GameController compilerOpts = -framework GameController linkerOpts = -framework GameController ================================================ FILE: platformLibs/src/platform/tvos/GameKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMedia CoreText CoreVideo EAGL Foundation GLKit GameController GameplayKit IOSurface ImageIO MediaToolbox Metal MetalKit ModelIO OpenGLESCommon QuartzCore ReplayKit SceneKit Security SpriteKit UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.GameKit modules = GameKit compilerOpts = -framework GameKit linkerOpts = -framework GameKit ================================================ FILE: platformLibs/src/platform/tvos/GameplayKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation GLKit IOSurface ImageIO Metal OpenGLESCommon QuartzCore SceneKit Security SpriteKit UIKit UserNotifications darwin posix language = Objective-C package = platform.GameplayKit modules = GameplayKit compilerOpts = -framework GameplayKit linkerOpts = -framework GameplayKit ================================================ FILE: platformLibs/src/platform/tvos/HomeKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.HomeKit modules = HomeKit compilerOpts = -framework HomeKit linkerOpts = -framework HomeKit ================================================ FILE: platformLibs/src/platform/tvos/IOKit.def.disabled ================================================ language = Objective-C package = platform.IOKit modules = IOKit compilerOpts = -framework IOKit linkerOpts = -framework IOKit #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/IOSurface.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.IOSurface modules = IOSurface compilerOpts = -framework IOSurface linkerOpts = -framework IOSurface ================================================ FILE: platformLibs/src/platform/tvos/ImageIO.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.ImageIO modules = ImageIO compilerOpts = -framework ImageIO linkerOpts = -framework ImageIO ================================================ FILE: platformLibs/src/platform/tvos/Intents.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreLocation Foundation Security darwin posix language = Objective-C package = platform.Intents modules = Intents compilerOpts = -framework Intents linkerOpts = -framework Intents ================================================ FILE: platformLibs/src/platform/tvos/IntentsUI.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Intents Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.IntentsUI modules = IntentsUI compilerOpts = -framework IntentsUI linkerOpts = -framework IntentsUI ================================================ FILE: platformLibs/src/platform/tvos/JavaScriptCore.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.JavaScriptCore modules = JavaScriptCore compilerOpts = -framework JavaScriptCore linkerOpts = -framework JavaScriptCore ================================================ FILE: platformLibs/src/platform/tvos/LinkPresentation.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.LinkPresentation modules = LinkPresentation compilerOpts = -framework LinkPresentation linkerOpts = -framework LinkPresentation ================================================ FILE: platformLibs/src/platform/tvos/LocalAuthentication.def.disabled ================================================ language = Objective-C package = platform.LocalAuthentication modules = LocalAuthentication compilerOpts = -framework LocalAuthentication linkerOpts = -framework LocalAuthentication #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/MLCompute.def ================================================ depends = CFNetwork CoreFoundation Foundation IOSurface Metal Security darwin posix language = Objective-C package = platform.MLCompute modules.tvos_arm64 = MLCompute compilerOpts.tvos_arm64 = -framework MLCompute linkerOpts.tvos_arm64 = -framework MLCompute ================================================ FILE: platformLibs/src/platform/tvos/MapKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreLocation CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MapKit modules = MapKit compilerOpts = -framework MapKit linkerOpts = -framework MapKit ================================================ FILE: platformLibs/src/platform/tvos/MediaAccessibility.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreText EAGL Foundation Metal QuartzCore Security darwin posix language = Objective-C package = platform.MediaAccessibility modules = MediaAccessibility compilerOpts = -framework MediaAccessibility linkerOpts = -framework MediaAccessibility ================================================ FILE: platformLibs/src/platform/tvos/MediaPlayer.def ================================================ depends = AVFoundation CFNetwork CoreFoundation CoreGraphics CoreImage CoreMedia CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MediaPlayer headers = MediaPlayer/MediaPlayer.h headerFilter = MediaPlayer/** compilerOpts = -framework MediaPlayer linkerOpts = -framework MediaPlayer ================================================ FILE: platformLibs/src/platform/tvos/MediaToolbox.def ================================================ depends = AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.MediaToolbox modules = MediaToolbox compilerOpts = -framework MediaToolbox linkerOpts = -framework MediaToolbox ================================================ FILE: platformLibs/src/platform/tvos/MessageUI.def.disabled ================================================ language = Objective-C package = platform.MessageUI modules = MessageUI compilerOpts = -framework MessageUI linkerOpts = -framework MessageUI #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/Metal.def ================================================ depends = CFNetwork CoreFoundation Foundation IOSurface Security darwin posix language = Objective-C package = platform.Metal modules = Metal compilerOpts = -framework Metal linkerOpts = -framework Metal ================================================ FILE: platformLibs/src/platform/tvos/MetalKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal ModelIO OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MetalKit modules = MetalKit compilerOpts = -framework MetalKit linkerOpts = -framework MetalKit ================================================ FILE: platformLibs/src/platform/tvos/MetalPerformanceShaders.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal Security darwin posix language = Objective-C package = platform.MetalPerformanceShaders modules.arm64 = MetalPerformanceShaders compilerOpts.arm64 = -framework MetalPerformanceShaders linkerOpts.arm64 = -framework MetalPerformanceShaders ================================================ FILE: platformLibs/src/platform/tvos/MetalPerformanceShadersGraph.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation IOSurface Metal MetalPerformanceShaders Security darwin posix language = Objective-C package = platform.MetalPerformanceShadersGraph modules.tvos_arm64 = MetalPerformanceShadersGraph compilerOpts.tvos_arm64 = -framework MetalPerformanceShadersGraph linkerOpts.tvos_arm64 = -framework MetalPerformanceShadersGraph ================================================ FILE: platformLibs/src/platform/tvos/MetricKit.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.MetricKit modules = MetricKit compilerOpts = -framework MetricKit linkerOpts = -framework MetricKit ================================================ FILE: platformLibs/src/platform/tvos/MobileCoreServices.def ================================================ depends = CoreFoundation CoreServices darwin posix language = Objective-C package = platform.MobileCoreServices modules = MobileCoreServices compilerOpts = -framework MobileCoreServices linkerOpts = -framework MobileCoreServices ================================================ FILE: platformLibs/src/platform/tvos/ModelIO.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.ModelIO modules = ModelIO compilerOpts = -framework ModelIO linkerOpts = -framework ModelIO ================================================ FILE: platformLibs/src/platform/tvos/MultipeerConnectivity.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.MultipeerConnectivity modules = MultipeerConnectivity compilerOpts = -framework MultipeerConnectivity linkerOpts = -framework MultipeerConnectivity ================================================ FILE: platformLibs/src/platform/tvos/NaturalLanguage.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.NaturalLanguage modules = NaturalLanguage compilerOpts = -framework NaturalLanguage linkerOpts = -framework NaturalLanguage ================================================ FILE: platformLibs/src/platform/tvos/Network.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.Network modules = Network compilerOpts = -framework Network linkerOpts = -framework Network ================================================ FILE: platformLibs/src/platform/tvos/OSLog.def.disabled ================================================ language = Objective-C package = platform.OSLog modules = OSLog compilerOpts = -framework OSLog linkerOpts = -framework OSLog #Disabled: Not officially available for tvos ================================================ FILE: platformLibs/src/platform/tvos/OpenAL.def ================================================ depends = darwin posix language = Objective-C package = platform.OpenAL modules = OpenAL compilerOpts = -framework OpenAL linkerOpts = -framework OpenAL ================================================ FILE: platformLibs/src/platform/tvos/OpenGLES.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles headers = OpenGLES/ES1/gl.h OpenGLES/ES1/glext.h headerFilter = OpenGLES/ES1/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/tvos/OpenGLES2.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles2 headers = OpenGLES/ES2/gl.h OpenGLES/ES2/glext.h headerFilter = OpenGLES/ES2/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/tvos/OpenGLES3.def ================================================ depends = EAGL OpenGLESCommon darwin posix language = Objective-C package = platform.gles3 headers = OpenGLES/ES3/gl.h OpenGLES/ES3/glext.h headerFilter = OpenGLES/ES3/** compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/tvos/OpenGLESCommon.def ================================================ depends = posix language = Objective-C package = platform.glescommon headers = OpenGLES/gltypes.h headerFilter = OpenGLES/gltypes.h compilerOpts = -framework OpenGLES linkerOpts = -framework OpenGLES ================================================ FILE: platformLibs/src/platform/tvos/Photos.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMedia CoreText CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.Photos modules = Photos compilerOpts = -framework Photos linkerOpts = -framework Photos --- // TODO: ugly hack while forwarded enums are supported. #import ================================================ FILE: platformLibs/src/platform/tvos/PhotosUI.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreLocation CoreMedia CoreText CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon Photos QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.PhotosUI modules = PhotosUI compilerOpts = -framework PhotosUI linkerOpts = -framework PhotosUI ================================================ FILE: platformLibs/src/platform/tvos/QuartzCore.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics EAGL Foundation Metal Security darwin posix language = Objective-C package = platform.QuartzCore headers = QuartzCore/QuartzCore.h headerFilter = QuartzCore/** compilerOpts = -framework QuartzCore linkerOpts = -framework QuartzCore ================================================ FILE: platformLibs/src/platform/tvos/ReplayKit.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreImage CoreMedia CoreText CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UIKit UniformTypeIdentifiers UserNotifications darwin posix language = Objective-C package = platform.ReplayKit modules = ReplayKit compilerOpts = -framework ReplayKit linkerOpts = -framework ReplayKit ================================================ FILE: platformLibs/src/platform/tvos/SceneKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation GLKit IOSurface ImageIO Metal ModelIO OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.SceneKit modules = SceneKit compilerOpts = -framework SceneKit linkerOpts = -framework SceneKit ================================================ FILE: platformLibs/src/platform/tvos/Security.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.Security modules = Security compilerOpts = -framework Security linkerOpts = -framework Security ================================================ FILE: platformLibs/src/platform/tvos/SoundAnalysis.def ================================================ depends = AVFoundation AudioToolbox CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreML CoreMedia CoreVideo EAGL Foundation IOSurface ImageIO MediaToolbox Metal OpenGLESCommon QuartzCore Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.SoundAnalysis modules = SoundAnalysis compilerOpts = -framework SoundAnalysis linkerOpts = -framework SoundAnalysis ================================================ FILE: platformLibs/src/platform/tvos/SpriteKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation GLKit IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.SpriteKit modules = SpriteKit compilerOpts = -framework SpriteKit linkerOpts = -framework SpriteKit ================================================ FILE: platformLibs/src/platform/tvos/StoreKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.StoreKit modules = StoreKit compilerOpts = -framework StoreKit linkerOpts = -framework StoreKit ================================================ FILE: platformLibs/src/platform/tvos/SwiftUI.def.disabled ================================================ language = Objective-C package = platform.SwiftUI modules = SwiftUI compilerOpts = -framework SwiftUI linkerOpts = -framework SwiftUI #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/tvos/SystemConfiguration.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.SystemConfiguration modules = SystemConfiguration compilerOpts = -framework SystemConfiguration linkerOpts = -framework SystemConfiguration ================================================ FILE: platformLibs/src/platform/tvos/TVMLKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO JavaScriptCore Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.TVMLKit modules = TVMLKit compilerOpts = -framework TVMLKit linkerOpts = -framework TVMLKit ================================================ FILE: platformLibs/src/platform/tvos/TVServices.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.TVServices modules = TVServices compilerOpts = -framework TVServices linkerOpts = -framework TVServices ================================================ FILE: platformLibs/src/platform/tvos/TVUIKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UIKit UserNotifications darwin posix language = Objective-C package = platform.TVUIKit modules = TVUIKit compilerOpts = -framework TVUIKit linkerOpts = -framework TVUIKit ================================================ FILE: platformLibs/src/platform/tvos/UIKit.def ================================================ depends = CFNetwork CoreFoundation CoreGraphics CoreImage CoreText CoreVideo EAGL Foundation IOSurface ImageIO Metal OpenGLESCommon QuartzCore Security UserNotifications darwin posix language = Objective-C package = platform.UIKit modules = UIKit compilerOpts = -framework UIKit linkerOpts = -framework UIKit excludedFunctions = UISceneErrorDomain ================================================ FILE: platformLibs/src/platform/tvos/UniformTypeIdentifiers.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UniformTypeIdentifiers modules = UniformTypeIdentifiers compilerOpts = -framework UniformTypeIdentifiers linkerOpts = -framework UniformTypeIdentifiers ================================================ FILE: platformLibs/src/platform/tvos/UserNotifications.def ================================================ depends = CFNetwork CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UserNotifications modules = UserNotifications compilerOpts = -framework UserNotifications linkerOpts = -framework UserNotifications ================================================ FILE: platformLibs/src/platform/tvos/VideoSubscriberAccount.def ================================================ depends = CoreFoundation Foundation darwin posix language = Objective-C package = platform.VideoSubscriberAccount modules = VideoSubscriberAccount compilerOpts = -framework VideoSubscriberAccount linkerOpts = -framework VideoSubscriberAccount ================================================ FILE: platformLibs/src/platform/tvos/VideoToolbox.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreVideo Foundation IOSurface Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.VideoToolbox modules = VideoToolbox compilerOpts = -framework VideoToolbox linkerOpts = -framework VideoToolbox ================================================ FILE: platformLibs/src/platform/tvos/Vision.def ================================================ depends = CFNetwork CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreML CoreMedia CoreVideo Foundation IOSurface ImageIO Metal OpenGLESCommon Security darwin posix language = Objective-C package = platform.Vision modules = Vision compilerOpts = -framework Vision linkerOpts = -framework Vision ================================================ FILE: platformLibs/src/platform/tvos/_AVKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AVKit_SwiftUI modules = _AVKit_SwiftUI compilerOpts = -framework _AVKit_SwiftUI linkerOpts = -framework _AVKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_AuthenticationServices_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AuthenticationServices_SwiftUI modules = _AuthenticationServices_SwiftUI compilerOpts = -framework _AuthenticationServices_SwiftUI linkerOpts = -framework _AuthenticationServices_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_HomeKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._HomeKit_SwiftUI modules = _HomeKit_SwiftUI compilerOpts = -framework _HomeKit_SwiftUI linkerOpts = -framework _HomeKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_MapKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._MapKit_SwiftUI modules = _MapKit_SwiftUI compilerOpts = -framework _MapKit_SwiftUI linkerOpts = -framework _MapKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_SceneKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SceneKit_SwiftUI modules = _SceneKit_SwiftUI compilerOpts = -framework _SceneKit_SwiftUI linkerOpts = -framework _SceneKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_SpriteKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SpriteKit_SwiftUI modules = _SpriteKit_SwiftUI compilerOpts = -framework _SpriteKit_SwiftUI linkerOpts = -framework _SpriteKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/_StoreKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._StoreKit_SwiftUI modules = _StoreKit_SwiftUI compilerOpts = -framework _StoreKit_SwiftUI linkerOpts = -framework _StoreKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/tvos/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = ** language = C excludedFunctions.tvos_arm64 = builtin_clear_cache --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/tvos/darwin.def ================================================ depends = posix language = Objective-C package = platform.darwin headers = AppleTextureEncoder.h AssertMacros.h Availability.h AvailabilityInternal.h \ AvailabilityMacros.h Block.h ConditionalMacros.h MacTypes.h \ TargetConditionals.h __cxxabi_config.h _locale.h _types.h _wctype.h \ aio.h asl.h bitstring.h bzlib.h \ cache.h cache_callbacks.h checkint.h compression.h copyfile.h \ cpio.h cxxabi.h db.h \ dns.h dns_sd.h dns_util.h execinfo.h \ fmtmsg.h fstab.h \ gethostuuid.h glob.h ifaddrs.h inttypes.h iso646.h \ langinfo.h \ libgen.h libunwind.h \ membership.h monetary.h mpool.h \ nameser.h ndbm.h nl_types.h \ notify.h notify_keys.h ntsid.h \ printf.h \ readpassphrase.h removefile.h \ runetype.h sandbox.h standards.h \ stringlist.h sysdir.h sysexits.h tar.h \ ttyent.h \ unwind.h util.h utmpx.h vis.h wordexp.h xattr_flags.h \ bank/bank_types.h \ bsm/audit.h \ os/activity.h os/availability.h os/base.h os/lock.h \ os/log.h os/object.h os/overflow.h os/signpost.h os/trace.h \ simd/simd.h sys/sysctl.h headerFilter = ** excludedFunctions = __tg_promote KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN \ asl_decode_buffer asl_encode_buffer asl_remove_index \ averunnable dbm_forder pidlock ttyaction ttylock ttymsg ttyunlock uuid_generate_early_random \ vm_stats compilerOpts = -D_XOPEN_SOURCE -DSYSCTL_DEF_ENABLED linkerOpts = -ldl -lz -lbz2 -lcompression -late --- // menu.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/tvos/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h headerFilter = ** linkerOpts = -liconv ================================================ FILE: platformLibs/src/platform/tvos/objc.def ================================================ depends = darwin posix language = Objective-C package = platform.objc headers = objc/NSObjCRuntime.h objc/NSObject.h objc/message.h objc/objc-api.h \ objc/objc-exception.h objc/objc-sync.h objc/objc.h objc/runtime.h headerFilter = objc/** compilerOpts = -D_XOPEN_SOURCE linkerOpts = -lobjc --- // objc-auto.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/tvos/posix.def ================================================ depends = package = platform.posix headers = alloca.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h float.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h signal.h \ stdatomic.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h \ netinet/icmp6.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/acl.h sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h \ sys/queue.h sys/select.h sys/shm.h sys/stat.h \ sys/syslimits.h sys/time.h sys/times.h sys/utsname.h sys/wait.h compilerOpts = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE linkerOpts = -ldl -lresolv excludedFunctions = acl_valid_link_np pfctlinput profil unwhiteout zopen getdirentries \ uuid_generate_early_random setgrfile excludedFunctions.tvos_arm64 = longjmperror excludedFunctions.tvos_x64 = pthread_jit_write_protect_np pthread_jit_write_protect_supported_np --- // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/tvos/set_depends.sh ================================================ #!/bin/bash ../../../../dist/bin/run_konan defFileDependencies -target tvos_arm64 -target tvos_x64 *.def ================================================ FILE: platformLibs/src/platform/tvos/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zconf.h zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: platformLibs/src/platform/watchos/AVFoundation.def ================================================ depends = CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreMedia CoreVideo Foundation ImageIO Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.AVFoundation modules = AVFoundation compilerOpts = -framework AVFoundation linkerOpts = -framework AVFoundation ================================================ FILE: platformLibs/src/platform/watchos/AVKit.def ================================================ depends = posix language = Objective-C package = platform.AVKit modules = AVKit compilerOpts = -framework AVKit linkerOpts = -framework AVKit ================================================ FILE: platformLibs/src/platform/watchos/Accelerate.def ================================================ depends = CoreFoundation CoreGraphics CoreVideo darwin posix language = Objective-C package = platform.Accelerate modules = Accelerate compilerOpts = -framework Accelerate linkerOpts = -framework Accelerate ================================================ FILE: platformLibs/src/platform/watchos/Accessibility.def ================================================ depends = CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.Accessibility modules = Accessibility compilerOpts = -framework Accessibility linkerOpts = -framework Accessibility ================================================ FILE: platformLibs/src/platform/watchos/AuthenticationServices.def ================================================ depends = CoreFoundation CoreGraphics CoreText Foundation Security UIKit darwin posix language = Objective-C package = platform.AuthenticationServices modules = AuthenticationServices compilerOpts = -framework AuthenticationServices linkerOpts = -framework AuthenticationServices ================================================ FILE: platformLibs/src/platform/watchos/CFNetwork.def.disabled ================================================ language = Objective-C package = platform.CFNetwork modules = CFNetwork compilerOpts = -framework CFNetwork linkerOpts = -framework CFNetwork #Disabled: Not officially available for watchos ================================================ FILE: platformLibs/src/platform/watchos/ClockKit.def ================================================ depends = CoreFoundation CoreGraphics CoreText Foundation Security UIKit darwin posix language = Objective-C package = platform.ClockKit headers = ClockKit/ClockKit.h headerFilter = ClockKit/** compilerOpts = -framework ClockKit linkerOpts = -framework ClockKit ================================================ FILE: platformLibs/src/platform/watchos/CloudKit.def ================================================ depends = CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CloudKit modules = CloudKit compilerOpts = -framework CloudKit linkerOpts = -framework CloudKit ================================================ FILE: platformLibs/src/platform/watchos/Combine.def.disabled ================================================ language = Objective-C package = platform.Combine modules = Combine compilerOpts = -framework Combine linkerOpts = -framework Combine #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/watchos/CommonCrypto.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreCrypto modules = CommonCrypto compilerOpts = -D_XOPEN_SOURCE ================================================ FILE: platformLibs/src/platform/watchos/Contacts.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.Contacts modules = Contacts compilerOpts = -framework Contacts linkerOpts = -framework Contacts ================================================ FILE: platformLibs/src/platform/watchos/CoreAudio.def ================================================ depends = CoreAudioTypes CoreFoundation darwin posix language = Objective-C package = platform.CoreAudio modules = CoreAudio compilerOpts = -framework CoreAudio linkerOpts = -framework CoreAudio ================================================ FILE: platformLibs/src/platform/watchos/CoreAudioTypes.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreAudioTypes modules = CoreAudioTypes compilerOpts = -framework CoreAudioTypes ================================================ FILE: platformLibs/src/platform/watchos/CoreBluetooth.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreBluetooth modules = CoreBluetooth compilerOpts = -framework CoreBluetooth linkerOpts = -framework CoreBluetooth ================================================ FILE: platformLibs/src/platform/watchos/CoreData.def ================================================ depends = CloudKit CoreFoundation CoreLocation Foundation Security darwin posix language = Objective-C package = platform.CoreData modules = CoreData compilerOpts = -framework CoreData linkerOpts = -framework CoreData ================================================ FILE: platformLibs/src/platform/watchos/CoreFoundation.def ================================================ depends = darwin posix language = Objective-C package = platform.CoreFoundation modules = CoreFoundation compilerOpts = -framework CoreFoundation linkerOpts = -framework CoreFoundation ================================================ FILE: platformLibs/src/platform/watchos/CoreGraphics.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreGraphics modules = CoreGraphics compilerOpts = -framework CoreGraphics linkerOpts = -framework CoreGraphics ================================================ FILE: platformLibs/src/platform/watchos/CoreLocation.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreLocation modules = CoreLocation compilerOpts = -framework CoreLocation linkerOpts = -framework CoreLocation ================================================ FILE: platformLibs/src/platform/watchos/CoreML.def ================================================ depends = CoreFoundation CoreGraphics CoreVideo Foundation ImageIO Security darwin posix language = Objective-C package = platform.CoreML modules = CoreML compilerOpts = -framework CoreML linkerOpts = -framework CoreML ================================================ FILE: platformLibs/src/platform/watchos/CoreMedia.def ================================================ depends = CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreVideo darwin posix language = Objective-C package = platform.CoreMedia modules = CoreMedia compilerOpts = -framework CoreMedia linkerOpts = -framework CoreMedia ================================================ FILE: platformLibs/src/platform/watchos/CoreMotion.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.CoreMotion modules = CoreMotion compilerOpts = -framework CoreMotion linkerOpts = -framework CoreMotion ================================================ FILE: platformLibs/src/platform/watchos/CoreServices.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.CoreServices modules = CoreServices compilerOpts = -framework CoreServices linkerOpts = -framework CoreServices ================================================ FILE: platformLibs/src/platform/watchos/CoreText.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.CoreText modules = CoreText compilerOpts = -framework CoreText linkerOpts = -framework CoreText ================================================ FILE: platformLibs/src/platform/watchos/CoreVideo.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.CoreVideo modules = CoreVideo compilerOpts = -framework CoreVideo linkerOpts = -framework CoreVideo ================================================ FILE: platformLibs/src/platform/watchos/CryptoKit.def.disabled ================================================ language = Objective-C package = platform.CryptoKit modules = CryptoKit compilerOpts = -framework CryptoKit linkerOpts = -framework CryptoKit #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/watchos/DeveloperToolsSupport.def.disabled ================================================ language = Objective-C package = platform.DeveloperToolsSupport modules = DeveloperToolsSupport compilerOpts = -framework DeveloperToolsSupport linkerOpts = -framework DeveloperToolsSupport #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/watchos/EventKit.def ================================================ depends = CoreFoundation CoreGraphics CoreLocation Foundation Security darwin posix language = Objective-C package = platform.EventKit modules = EventKit compilerOpts = -framework EventKit linkerOpts = -framework EventKit ================================================ FILE: platformLibs/src/platform/watchos/Foundation.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.Foundation modules = Foundation compilerOpts = -framework Foundation linkerOpts = -framework Foundation ================================================ FILE: platformLibs/src/platform/watchos/GameKit.def ================================================ depends = Contacts CoreFoundation CoreGraphics CoreText Foundation SceneKit Security SpriteKit UIKit darwin posix language = Objective-C package = platform.GameKit modules = GameKit compilerOpts = -framework GameKit linkerOpts = -framework GameKit ================================================ FILE: platformLibs/src/platform/watchos/HealthKit.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.HealthKit modules = HealthKit compilerOpts = -framework HealthKit linkerOpts = -framework HealthKit ================================================ FILE: platformLibs/src/platform/watchos/HomeKit.def ================================================ depends = CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.HomeKit modules = HomeKit compilerOpts = -framework HomeKit linkerOpts = -framework HomeKit ================================================ FILE: platformLibs/src/platform/watchos/ImageIO.def ================================================ depends = CoreFoundation CoreGraphics darwin posix language = Objective-C package = platform.ImageIO modules = ImageIO compilerOpts = -framework ImageIO linkerOpts = -framework ImageIO ================================================ FILE: platformLibs/src/platform/watchos/Intents.def ================================================ depends = CoreFoundation CoreGraphics CoreLocation Foundation Security darwin posix language = Objective-C package = platform.Intents modules = Intents compilerOpts = -framework Intents linkerOpts = -framework Intents ================================================ FILE: platformLibs/src/platform/watchos/MapKit.def ================================================ depends = CoreFoundation CoreGraphics CoreLocation CoreText Foundation Security UIKit darwin posix language = Objective-C package = platform.MapKit modules = MapKit compilerOpts = -framework MapKit linkerOpts = -framework MapKit ================================================ FILE: platformLibs/src/platform/watchos/MediaPlayer.def ================================================ depends = AVFoundation CoreFoundation CoreGraphics CoreMedia Foundation Security darwin posix language = Objective-C package = platform.MediaPlayer modules = MediaPlayer compilerOpts = -framework MediaPlayer linkerOpts = -framework MediaPlayer ================================================ FILE: platformLibs/src/platform/watchos/MobileCoreServices.def ================================================ depends = CoreFoundation CoreServices darwin posix language = Objective-C package = platform.MobileCoreServices modules = MobileCoreServices compilerOpts = -framework MobileCoreServices linkerOpts = -framework MobileCoreServices ================================================ FILE: platformLibs/src/platform/watchos/NaturalLanguage.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.NaturalLanguage modules = NaturalLanguage compilerOpts = -framework NaturalLanguage linkerOpts = -framework NaturalLanguage ================================================ FILE: platformLibs/src/platform/watchos/Network.def ================================================ depends = CoreFoundation Security darwin posix language = Objective-C package = platform.Network modules = Network compilerOpts = -framework Network linkerOpts = -framework Network ================================================ FILE: platformLibs/src/platform/watchos/NetworkExtension.def ================================================ depends = CoreFoundation Foundation Network Security darwin posix language = Objective-C package = platform.NetworkExtension modules = NetworkExtension compilerOpts = -framework NetworkExtension linkerOpts = -framework NetworkExtension ================================================ FILE: platformLibs/src/platform/watchos/PassKit.def ================================================ depends = Contacts CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.PassKit modules = PassKit compilerOpts = -framework PassKit linkerOpts = -framework PassKit ================================================ FILE: platformLibs/src/platform/watchos/PushKit.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.PushKit modules = PushKit compilerOpts = -framework PushKit linkerOpts = -framework PushKit ================================================ FILE: platformLibs/src/platform/watchos/SceneKit.def ================================================ depends = CoreFoundation CoreGraphics Foundation Security darwin posix language = Objective-C package = platform.SceneKit modules = SceneKit compilerOpts = -framework SceneKit linkerOpts = -framework SceneKit ================================================ FILE: platformLibs/src/platform/watchos/Security.def ================================================ depends = CoreFoundation darwin posix language = Objective-C package = platform.Security modules = Security compilerOpts = -framework Security linkerOpts = -framework Security ================================================ FILE: platformLibs/src/platform/watchos/SoundAnalysis.def ================================================ depends = AVFoundation CoreAudio CoreAudioTypes CoreFoundation CoreGraphics CoreML CoreMedia CoreVideo Foundation ImageIO Security UniformTypeIdentifiers darwin posix language = Objective-C package = platform.SoundAnalysis modules = SoundAnalysis compilerOpts = -framework SoundAnalysis linkerOpts = -framework SoundAnalysis ================================================ FILE: platformLibs/src/platform/watchos/SpriteKit.def ================================================ depends = CoreFoundation CoreGraphics CoreText Foundation Security UIKit darwin posix language = Objective-C package = platform.SpriteKit modules = SpriteKit compilerOpts = -framework SpriteKit linkerOpts = -framework SpriteKit ================================================ FILE: platformLibs/src/platform/watchos/StoreKit.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.StoreKit modules = StoreKit compilerOpts = -framework StoreKit linkerOpts = -framework StoreKit ================================================ FILE: platformLibs/src/platform/watchos/SwiftUI.def.disabled ================================================ language = Objective-C package = platform.SwiftUI modules = SwiftUI compilerOpts = -framework SwiftUI linkerOpts = -framework SwiftUI #Disabled: Swift-only framework ================================================ FILE: platformLibs/src/platform/watchos/UIKit.def ================================================ depends = CoreFoundation CoreGraphics CoreText Foundation Security darwin posix language = Objective-C package = platform.UIKit modules = UIKit compilerOpts = -framework UIKit linkerOpts = -framework UIKit ================================================ FILE: platformLibs/src/platform/watchos/UniformTypeIdentifiers.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UniformTypeIdentifiers modules = UniformTypeIdentifiers compilerOpts = -framework UniformTypeIdentifiers linkerOpts = -framework UniformTypeIdentifiers ================================================ FILE: platformLibs/src/platform/watchos/UserNotifications.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.UserNotifications headers = UserNotifications/UserNotifications.h headerFilter = UserNotifications/** compilerOpts = -framework UserNotifications linkerOpts = -framework UserNotifications ================================================ FILE: platformLibs/src/platform/watchos/WatchConnectivity.def ================================================ depends = CoreFoundation Foundation Security darwin posix language = Objective-C package = platform.WatchConnectivity modules = WatchConnectivity compilerOpts = -framework WatchConnectivity linkerOpts = -framework WatchConnectivity ================================================ FILE: platformLibs/src/platform/watchos/WatchKit.def ================================================ depends = CoreFoundation CoreGraphics CoreLocation CoreText Foundation HomeKit MapKit SceneKit Security UIKit darwin posix language = Objective-C package = platform.WatchKit modules = WatchKit compilerOpts = -framework WatchKit linkerOpts = -framework WatchKit ================================================ FILE: platformLibs/src/platform/watchos/_AVKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AVKit_SwiftUI modules = _AVKit_SwiftUI compilerOpts = -framework _AVKit_SwiftUI linkerOpts = -framework _AVKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_AuthenticationServices_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._AuthenticationServices_SwiftUI modules = _AuthenticationServices_SwiftUI compilerOpts = -framework _AuthenticationServices_SwiftUI linkerOpts = -framework _AuthenticationServices_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_ClockKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._ClockKit_SwiftUI modules = _ClockKit_SwiftUI compilerOpts = -framework _ClockKit_SwiftUI linkerOpts = -framework _ClockKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_HomeKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._HomeKit_SwiftUI modules = _HomeKit_SwiftUI compilerOpts = -framework _HomeKit_SwiftUI linkerOpts = -framework _HomeKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_MapKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._MapKit_SwiftUI modules = _MapKit_SwiftUI compilerOpts = -framework _MapKit_SwiftUI linkerOpts = -framework _MapKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_SceneKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SceneKit_SwiftUI modules = _SceneKit_SwiftUI compilerOpts = -framework _SceneKit_SwiftUI linkerOpts = -framework _SceneKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_SpriteKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._SpriteKit_SwiftUI modules = _SpriteKit_SwiftUI compilerOpts = -framework _SpriteKit_SwiftUI linkerOpts = -framework _SpriteKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_StoreKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._StoreKit_SwiftUI modules = _StoreKit_SwiftUI compilerOpts = -framework _StoreKit_SwiftUI linkerOpts = -framework _StoreKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/_WatchKit_SwiftUI.def.disabled ================================================ language = Objective-C package = platform._WatchKit_SwiftUI modules = _WatchKit_SwiftUI compilerOpts = -framework _WatchKit_SwiftUI linkerOpts = -framework _WatchKit_SwiftUI #Disabled: Unavailable ================================================ FILE: platformLibs/src/platform/watchos/builtin.def ================================================ depends = posix package = platform.builtin headerFilter = ** language = C excludedFunctions.watchos_arm32 = builtin_clear_cache --- // See https://github.com/llvm-mirror/clang/blob/master/include/clang/Basic/Builtins.def // TODO: autogenerate from machine format. // Returns x with the order of the bytes reversed; for example, 0xaabb becomes 0xbbaa. Byte here always means exactly 8 bits. static inline short builtin_bswap16(short x) { return __builtin_bswap16(x); } static inline int builtin_bswap32(int x) { return __builtin_bswap32(x); } static inline long long builtin_bswap64(long long x) { return __builtin_bswap64(x); } // Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined. static inline int builtin_clzs(unsigned short x) { return __builtin_clzs(x); } static inline int builtin_clz(unsigned int x) { return __builtin_clz(x); } static inline int builtin_clzl(unsigned long x) { return __builtin_clzl(x); } static inline int builtin_clzll(unsigned long long x) { return __builtin_clzll(x); } // Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. static inline int builtin_ctzs(unsigned short x) { return __builtin_ctzs(x); } static inline int builtin_ctz(unsigned int x) { return __builtin_ctz(x); } static inline int builtin_ctzl(unsigned long x) { return __builtin_ctzl(x); } static inline int builtin_ctzll(unsigned long long x) { return __builtin_ctzll(x); } // Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. static inline int builtin_ffs(int x) { return __builtin_ffs(x); } static inline int builtin_ffsl(long x) { return __builtin_ffsl(x); } static inline int builtin_ffsll(long long x) { return __builtin_ffsll(x); } // Returns the parity of x, i.e. the number of 1-bits in x modulo 2. static inline int builtin_parity(int x) { return __builtin_parity(x); } static inline int builtin_parityl(unsigned long x) { return __builtin_parityl(x); } static inline int builtin_parityll(unsigned long long x) { return __builtin_parityll(x); } // Returns the number of 1-bits in x. static inline int builtin_popcount(int x) { return __builtin_popcount(x); } static inline int builtin_popcountl(long x) { return __builtin_popcountl(x); } static inline int builtin_popcountll(long long x) { return __builtin_popcountll(x); } // This function is used to flush the processor's instruction cache for the region of memory between begin inclusive and end exclusive. static inline void builtin_clear_cache(void* begin, void* end) { __builtin___clear_cache(begin, end); } ================================================ FILE: platformLibs/src/platform/watchos/darwin.def ================================================ depends = posix language = Objective-C package = platform.darwin headers = AssertMacros.h Availability.h AvailabilityInternal.h \ AvailabilityMacros.h Block.h ConditionalMacros.h MacTypes.h \ TargetConditionals.h __cxxabi_config.h _locale.h _types.h _wctype.h \ aio.h asl.h bitstring.h bzlib.h \ cache.h cache_callbacks.h checkint.h compression.h copyfile.h \ cpio.h cxxabi.h db.h \ dns.h dns_sd.h dns_util.h execinfo.h \ fmtmsg.h fstab.h \ gethostuuid.h glob.h ifaddrs.h inttypes.h iso646.h \ langinfo.h \ libgen.h libunwind.h \ membership.h monetary.h mpool.h \ nameser.h ndbm.h nl_types.h \ notify.h notify_keys.h ntsid.h \ printf.h \ readpassphrase.h removefile.h \ runetype.h sandbox.h standards.h \ stringlist.h sysdir.h sysexits.h tar.h \ ttyent.h \ unwind.h util.h utmpx.h vis.h wordexp.h xattr_flags.h \ bank/bank_types.h \ bsm/audit.h \ os/activity.h os/availability.h os/base.h os/lock.h \ os/log.h os/object.h os/overflow.h os/signpost.h os/trace.h \ simd/simd.h sys/sysctl.h headerFilter = ** excludedFunctions = __tg_promote KERNEL_AUDIT_TOKEN KERNEL_SECURITY_TOKEN \ asl_decode_buffer asl_encode_buffer asl_remove_index \ averunnable dbm_forder pidlock ttyaction ttylock ttymsg ttyunlock uuid_generate_early_random \ vm_stats # These functions are depend on __arm__ macro. Include them back # when our LLVM distribution will gain support for arm64_32 target. excludedFunctions.watchos_arm64 = _simd_ceil_f4 _simd_ceil_d2 _simd_floor_f4 _simd_floor_d2 \ _simd_rint_f4 _simd_rint_d2 _simd_trunc_f4 _simd_trunc_d2 \ __tg_trunc __tg_ceil __tg_rint __tg_floor simd_fract compilerOpts = -D_XOPEN_SOURCE -DSYSCTL_DEF_ENABLED linkerOpts = -ldl -lz -lbz2 -lcompression --- // AppleTextureEncoder.h is not available for WatchOS simulator // menu.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/watchos/iconv.def ================================================ depends = posix package = platform.iconv headers = iconv.h headerFilter = ** linkerOpts = -liconv ================================================ FILE: platformLibs/src/platform/watchos/objc.def ================================================ depends = darwin posix language = Objective-C package = platform.objc headers = objc/NSObjCRuntime.h objc/NSObject.h objc/message.h objc/objc-api.h \ objc/objc-exception.h objc/objc-sync.h objc/objc.h objc/runtime.h headerFilter = objc/** excludedFunctions.watchos_arm64 = _objc_msgForward_stret \ class_getMethodImplementation_stret method_invoke_stret compilerOpts = -D_XOPEN_SOURCE linkerOpts = -lobjc --- // objc-auto.h is excluded so far due to interop issues. ================================================ FILE: platformLibs/src/platform/watchos/posix.def ================================================ depends = package = platform.posix headers = alloca.h assert.h complex.h ctype.h dirent.h dlfcn.h err.h errno.h fcntl.h \ fenv.h float.h fnmatch.h fts.h ftw.h getopt.h grp.h inttypes.h libgen.h limits.h \ locale.h math.h memory.h netdb.h paths.h poll.h \ pthread.h pwd.h regex.h resolv.h sched.h search.h semaphore.h setjmp.h signal.h \ stdatomic.h stdint.h stdio.h stdlib.h string.h strings.h syslog.h termios.h \ time.h ucontext.h unistd.h utime.h wchar.h wctype.h xlocale.h \ net/ethernet.h net/if.h \ netinet/icmp6.h netinet/in.h netinet/in_systm.h \ netinet/ip.h netinet/ip6.h netinet/ip_icmp.h netinet/tcp.h netinet/udp.h \ sys/acl.h sys/ioctl.h sys/ipc.h sys/mman.h sys/poll.h \ sys/queue.h sys/select.h sys/shm.h sys/stat.h \ sys/syslimits.h sys/time.h sys/times.h sys/utsname.h sys/wait.h compilerOpts = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE linkerOpts = -ldl -lresolv excludedFunctions = acl_valid_link_np pfctlinput profil unwhiteout zopen getdirentries \ uuid_generate_early_random setgrfile \ getcontext makecontext setcontext swapcontext excludedFunctions.watchos_arm32 = longjmperror excludedFunctions.watchos_arm64 = longjmperror excludedFunctions.watchos_x86 = pthread_jit_write_protect_np pthread_jit_write_protect_supported_np --- // Wrapper to access errno variable. static int posix_errno() { return errno; } static void set_posix_errno(int value) { errno = value; } // Wrapper to access h_errno variable. static int posix_h_errno() { return h_errno; } static void set_posix_h_errno(int value) { h_errno = value; } static int init_sockets() { return 0; } static void deinit_sockets() { } ================================================ FILE: platformLibs/src/platform/watchos/set_depends.sh ================================================ #!/bin/bash ../../../../dist/bin/run_konan defFileDependencies \ -target watchos_arm32 \ -target watchos_x86 \ -target watchos_arm64 \ -target watchos_x64 \ *.def ================================================ FILE: platformLibs/src/platform/watchos/zlib.def ================================================ depends = posix package = platform.zlib headers = zconf.h zlib.h headerFilter = zconf.h zlib.h compilerOpts = -DByte=uByte -DBytef=uBytef linkerOpts = -lz --- #undef deflateInit static inline int deflateInit(z_streamp strm, int level) { return deflateInit_(strm, level, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef deflateInit2 static inline int deflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit static inline int inflateInit(z_streamp strm) { return inflateInit_(strm, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateInit2 static inline int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION, (int)sizeof(z_stream)); } #undef inflateBackInit static inline int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { return inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, (int)sizeof(z_stream)); } ================================================ FILE: runtime/CMakeLists.txt ================================================ # Disclaimer: this is a straw-man attempt to add navigation to Clion or similar tools. # At the moment it can't be used for real building or debugging. Feel free to contribute cmake_minimum_required(VERSION 3.14) project(runtime) set(CMAKE_CXX_STANDARD 14) set(SRC_DIR ${CMAKE_SOURCE_DIR}/src) set(GOOGLETEST_DIR ${CMAKE_SOURCE_DIR}/googletest) include_directories(${SRC_DIR}/main/cpp) include_directories(${SRC_DIR}/debug/headers) include_directories(${CMAKE_SOURCE_DIR}/../common/src/hash/headers) include_directories(${GOOGLETEST_DIR}/googletest/include) include_directories(${GOOGLETEST_DIR}/googlemock/include) add_executable(runtime src/main/cpp/Arrays.cpp src/main/cpp/Atomic.cpp src/main/cpp/Boxing.cpp src/main/cpp/Console.cpp src/main/cpp/CyclicCollector.cpp src/main/cpp/Exceptions.cpp src/main/cpp/ExecFormat.cpp src/main/cpp/Interop.cpp src/main/cpp/JSInterop.cpp src/main/cpp/KAssert.cpp src/main/cpp/KString.cpp src/main/cpp/KotlinMath.cpp src/main/cpp/Memory.cpp src/main/cpp/MemorySharedRefs.cpp src/main/cpp/Natives.cpp src/main/cpp/ObjCExceptions.cpp src/main/cpp/Operator.cpp src/main/cpp/Porting.cpp src/main/cpp/Regex.cpp src/main/cpp/ReturnSlot.cpp src/main/cpp/Runtime.cpp src/main/cpp/StdCppStubs.cpp src/main/cpp/Time.cpp src/main/cpp/ToString.cpp src/main/cpp/TypeInfo.cpp src/main/cpp/Types.cpp src/main/cpp/Weak.cpp src/main/cpp/Worker.cpp src/main/cpp/dlmalloc/malloc.cpp src/main/cpp/dtoa/cbigint.cpp src/main/cpp/dtoa/dblparse.cpp src/main/cpp/dtoa/fltparse.cpp src/main/cpp/math/fmod.cpp src/main/cpp/math/fmodf.cpp src/main/cpp/math/scalbn.cpp src/main/cpp/snprintf/snprintf.cpp src/profile_runtime/cpp/ProfileRuntime.cpp src/relaxed/cpp/MemoryImpl.cpp src/release/cpp/SourceInfo.cpp src/strict/cpp/MemoryImpl.cpp src/opt_alloc/cpp/AllocImpl.cpp src/std_alloc/cpp/AllocImpl.cpp src/debug/cpp/KDebug.cpp src/debug/cpp/SourceInfo.cpp src/exceptions_support/cpp/ExceptionsSupport.cpp src/launcher/cpp/androidLauncher.cpp src/launcher/cpp/launcher.cpp src/main/cpp/ObjCExport.mm src/main/cpp/ObjCInterop.mm src/main/cpp/ObjCInteropUtils.mm src/main/cpp/ObjCExportCollectionUtils.mm src/main/cpp/ObjCExportErrors.mm src/main/cpp/ObjCExportExceptionDetails.mm src/objc/cpp/ObjCExportNumbers.mm src/objc/cpp/ObjCExportClasses.mm src/objc/cpp/ObjCExportCollections.mm src/objc/cpp/ObjCInteropUtilsClasses.mm # Tests src/test_support/cpp/CompilerGenerated.cpp src/test_support/cpp/CompilerGeneratedObjC.mm src/test_support/cpp/TestLauncher.cpp src/main/cpp/ArraysTest.cpp ) target_compile_definitions(runtime PUBLIC "-DKONAN_OSX=1") target_compile_definitions(runtime PUBLIC "-DKONAN_MACOSX=1") target_compile_definitions(runtime PUBLIC "-DKONAN_X64=1") target_compile_definitions(runtime PUBLIC "-DKONAN_OBJC_INTEROP") target_compile_definitions(runtime PUBLIC "-DKONAN_CORE_SYMBOLICATION=1") target_compile_definitions(runtime PUBLIC "-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1") target_compile_definitions(runtime PUBLIC "-DKONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG=1") ================================================ FILE: runtime/build.gradle.kts ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.* import org.jetbrains.kotlin.testing.native.* import org.jetbrains.kotlin.bitcode.CompileToBitcode import org.jetbrains.kotlin.bitcode.CompileToBitcodeExtension import org.jetbrains.kotlin.konan.target.* plugins { id("compile-to-bitcode") id("runtime-testing") } googletest { revision = project.property("gtestRevision") as String refresh = project.hasProperty("refresh-gtest") } fun CompileToBitcode.includeRuntime() { headersDirs += files("../common/src/hash/headers", "src/main/cpp") } val hostName: String by project val targetList: List by project bitcode { create("runtime", file("src/main")) { dependsOn( ":common:${target}Hash", "${target}StdAlloc", "${target}OptAlloc", "${target}Mimalloc", "${target}Launcher", "${target}Debug", "${target}Release", "${target}Strict", "${target}Relaxed", "${target}ProfileRuntime", "${target}Objc", "${target}ExceptionsSupport", "${target}LegacyMemoryManager", "${target}ExperimentalMemoryManager" ) includeRuntime() // TODO: Should depend on the sanitizer. linkerArgs.add(project.file("../common/build/bitcode/main/$target/hash.bc").path) } create("mimalloc") { language = CompileToBitcode.Language.C includeFiles = listOf("**/*.c") excludeFiles += listOf("**/alloc-override*.c", "**/page-queue.c", "**/static.c", "**/bitmap.inc.c") srcDirs = files("$srcRoot/c") compilerArgs.addAll(listOf("-DKONAN_MI_MALLOC=1", "-Wno-unknown-pragmas", "-ftls-model=initial-exec", "-Wno-unused-function", "-Wno-error=atomic-alignment", "-Wno-unused-parameter" /* for windows 32*/)) headersDirs = files("$srcRoot/c/include") onlyIf { targetSupportsMimallocAllocator(target) } } create("launcher") { includeRuntime() } create("debug") { includeRuntime() } create("std_alloc") create("opt_alloc") create("exceptionsSupport", file("src/exceptions_support")) { includeRuntime() } create("release") { includeRuntime() } create("strict") { includeRuntime() } create("relaxed") { includeRuntime() } create("profileRuntime", file("src/profile_runtime")) create("objc") { includeRuntime() } create("test_support", outputGroup = "test") { includeRuntime() dependsOn("downloadGoogleTest") headersDirs += googletest.headersDirs } create("legacy_memory_manager", file("src/legacymm")) { includeRuntime() } create("experimental_memory_manager", file("src/mm")) { includeRuntime() } } targetList.forEach { targetName -> val allTests = mutableListOf() allTests.addAll(createTestTasks( project, targetName, "${targetName}StdAllocRuntimeTests", listOf( "${targetName}Runtime", "${targetName}LegacyMemoryManager", "${targetName}Strict", "${targetName}Release", "${targetName}StdAlloc" ) ) { includeRuntime() }) allTests.addAll(createTestTasks( project, targetName, "${targetName}MimallocRuntimeTests", listOf( "${targetName}Runtime", "${targetName}LegacyMemoryManager", "${targetName}Strict", "${targetName}Release", "${targetName}Mimalloc", "${targetName}OptAlloc" ) ) { includeRuntime() }) allTests.addAll(createTestTasks( project, targetName, "${targetName}ExperimentalMMMimallocRuntimeTests", listOf( "${targetName}Runtime", "${targetName}ExperimentalMemoryManager", "${targetName}Release", "${targetName}Mimalloc", "${targetName}OptAlloc" ) ) { includeRuntime() }) allTests.addAll(createTestTasks( project, targetName, "${targetName}ExperimentalMMStdAllocRuntimeTests", listOf( "${targetName}Runtime", "${targetName}ExperimentalMemoryManager", "${targetName}Release", "${targetName}StdAlloc" ) ) { includeRuntime() }) // TODO: This "all tests" tasks should be provided by `CompileToBitcodeExtension` tasks.register("${targetName}RuntimeTests") { dependsOn(allTests) } } val hostRuntime by tasks.registering { dependsOn("${hostName}Runtime") } val hostRuntimeTests by tasks.registering { dependsOn("${hostName}RuntimeTests") } val hostStdAllocRuntimeTests by tasks.registering { dependsOn("${hostName}StdAllocRuntimeTests") } val hostMimallocRuntimeTests by tasks.registering { dependsOn("${hostName}MimallocRuntimeTests") } val hostExperimentalMMStdAllocRuntimeTests by tasks.registering { dependsOn("${hostName}ExperimentalMMStdAllocRuntimeTests") } val hostExperimentalMMMimallocRuntimeTests by tasks.registering { dependsOn("${hostName}ExperimentalMMMimallocRuntimeTests") } val assemble by tasks.registering { dependsOn(tasks.withType(CompileToBitcode::class).matching { it.outputGroup == "main" }) } val clean by tasks.registering { doLast { delete(buildDir) } } val generateJsMath by tasks.registering { dependsOn(":distCompiler") doLast { val distDir: File by project val jsinteropScript = if (PlatformInfo.isWindows()) "jsinterop.bat" else "jsinterop" val jsinterop = "$distDir/bin/$jsinteropScript" val targetDir = "$buildDir/generated" project.exec { commandLine( jsinterop, "-pkg", "kotlinx.interop.wasm.math", "-o", "$targetDir/math", "-target", "wasm32" ) } val generated = file("$targetDir/math-build/natives/js_stubs.js") val mathJs = file("src/main/js/math.js") mathJs.writeText( "// NOTE: THIS FILE IS AUTO-GENERATED!\n" + "// Run ':runtime:generateJsMath' to re-generate it.\n\n" ) mathJs.appendText(generated.readText()) } } ================================================ FILE: runtime/generator/build.gradle ================================================ configurations { generatorRuntime } repositories { maven { url buildKotlinCompilerRepo } } dependencies { generatorRuntime "org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdlibVersion}" generatorRuntime "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}" generatorRuntime "org.jetbrains.kotlin:kotlin-stdlib-gen:${kotlinStdlibVersion}" } task run(type: JavaExec) { group 'application' main 'generators.GenerateStandardLibKt' classpath configurations.generatorRuntime args = ["native", "${project(":runtime").projectDir}/src/main/kotlin/generated"] } task generateUnicodeData(type: JavaExec) { group 'application' main 'generators.unicode.GenerateUnicodeDataKt' classpath configurations.generatorRuntime args = ["native", "${project(":runtime").projectDir}/src/main/kotlin/generated", "${project(":backend.native").projectDir}/tests/stdlib_external/text"] } ================================================ FILE: runtime/src/debug/cpp/KDebug.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "KDebug.h" #include #include "KAssert.h" #include "KString.h" #include "Memory.h" #include "Natives.h" #include "Porting.h" #include "Types.h" #ifndef KONAN_NO_DEBUG_API extern "C" OBJ_GETTER(KonanObjectToUtf8Array, KRef object); namespace { char debugBuffer[4096]; constexpr int runtimeTypeSize[] = { -1, // INVALID sizeof(ObjHeader*), // OBJECT 1, // INT8 2, // INT16 4, // INT32 8, // INT64 4, // FLOAT32 8, // FLOAT64 sizeof(void*), // NATIVE_PTR 1, // BOOLEAN 16 // VECTOR128 }; constexpr int runtimeTypeAlignment[] = { -1, // INVALID alignof(ObjHeader*), // OBJECT alignof(int8_t), // INT8 alignof(int16_t), // INT16 alignof(int32_t), // INT32 alignof(int64_t), // INT64 alignof(float), // FLOAT32 alignof(double), // FLOAT64 alignof(void*), // NATIVE_PTR 1, // BOOLEAN 16 // VECTOR128 }; // Never ever change numbering in this enum, as it will break debugging of older binaries. enum Konan_DebugOperation { DO_DebugBuffer = 1, DO_DebugBufferSize = 2, DO_DebugBufferWithObject = 3, DO_DebugBufferSizeWithObject = 4, DO_DebugObjectToUtf8Array = 5, DO_DebugPrint = 6, DO_DebugIsArray = 7, DO_DebugGetFieldCount = 8, DO_DebugGetFieldType = 9, DO_DebugGetFieldAddress = 10, DO_DebugGetFieldName = 11, DO_DebugGetTypeName = 12, }; template F getImpl(KRef obj, Konan_DebugOperation operation) { if (obj == nullptr) return nullptr; auto* typeInfo = obj->type_info(); auto* extendedTypeInfo = typeInfo->extendedInfo_; if (extendedTypeInfo == nullptr) return nullptr; if (static_cast(operation) >= extendedTypeInfo->debugOperationsCount_) return nullptr; return reinterpret_cast(extendedTypeInfo->debugOperations_[operation]); } // Buffer that can be used by debugger for inspections. char* Konan_DebugBufferImpl() { return debugBuffer; } int Konan_DebugBufferSizeImpl() { return sizeof(debugBuffer); } char* Konan_DebugBufferWithObjectImpl(KRef obj) { return debugBuffer; } int Konan_DebugBufferSizeWithObjectImpl(KRef obj) { return sizeof(debugBuffer); } // Auxilary function which can be called by developer/debugger to inspect an object. int32_t Konan_DebugObjectToUtf8ArrayImpl(KRef obj, char* buffer, int32_t bufferSize) { ObjHolder stringHolder; auto data = KonanObjectToUtf8Array(obj, stringHolder.slot())->array(); if (data == nullptr) return 0; if (bufferSize < 1) return 0; KInt toCopy = data->count_ > static_cast(bufferSize - 1) ? bufferSize - 1 : data->count_; ::memcpy(buffer, ByteArrayAddressOfElementAt(data, 0), toCopy); buffer[toCopy] = '\0'; return toCopy + 1; } int32_t Konan_DebugPrintImpl(KRef obj) { int32_t size = Konan_DebugObjectToUtf8Array(obj, Konan_DebugBuffer(), Konan_DebugBufferSize()); if (size > 1) konan::consoleWriteUtf8(Konan_DebugBuffer(), size - 1); return 0; } int32_t Konan_DebugIsArrayImpl(KRef obj) { return obj == nullptr || IsArray(obj) ? 1 : 0; } int32_t Konan_DebugGetFieldCountImpl(KRef obj) { if (obj == nullptr) return 0; auto* typeInfo = obj->type_info(); auto* extendedTypeInfo = typeInfo->extendedInfo_; if (extendedTypeInfo == nullptr) return 0; if (IsArray(obj)) return obj->array()->count_; return extendedTypeInfo->fieldsCount_; } int32_t Konan_DebugGetFieldTypeImpl(KRef obj, int32_t index) { if (obj == nullptr || index < 0) return Konan_RuntimeType::RT_INVALID; auto typeInfo = obj->type_info(); auto extendedTypeInfo = typeInfo->extendedInfo_; if (extendedTypeInfo == nullptr) return Konan_RuntimeType::RT_INVALID; if (extendedTypeInfo->fieldsCount_ < 0) return -extendedTypeInfo->fieldsCount_; if (index >= extendedTypeInfo->fieldsCount_) return Konan_RuntimeType::RT_INVALID; return extendedTypeInfo->fieldTypes_[index]; } void* Konan_DebugGetFieldAddressImpl(KRef obj, int32_t index) { if (obj == nullptr || index < 0) return nullptr; auto typeInfo = obj->type_info(); auto extendedTypeInfo = typeInfo->extendedInfo_; if (extendedTypeInfo == nullptr) return nullptr; if (extendedTypeInfo->fieldsCount_ < 0) { if (static_cast(index) > obj->array()->count_) return nullptr; int32_t typeIndex = -extendedTypeInfo->fieldsCount_; return reinterpret_cast(obj->array()) + alignUp(sizeof(struct ArrayHeader), runtimeTypeAlignment[typeIndex]) + index * runtimeTypeSize[typeIndex]; } if (index >= extendedTypeInfo->fieldsCount_) return nullptr; return reinterpret_cast(obj) + extendedTypeInfo->fieldOffsets_[index]; } // Compute address of field or an array element at the index, or null, if incorrect. const char* Konan_DebugGetFieldNameImpl(KRef obj, int32_t index) { if (obj == nullptr || index < 0) return nullptr; auto typeInfo = obj->type_info(); auto extendedTypeInfo = typeInfo->extendedInfo_; if (extendedTypeInfo == nullptr) return nullptr; // For arrays, field name makes not much sense. if (extendedTypeInfo->fieldsCount_ < 0) return ""; if (index >= extendedTypeInfo->fieldsCount_) return nullptr; return extendedTypeInfo->fieldNames_[index]; } const char* Konan_DebugGetTypeNameImpl(KRef obj) { if (obj == nullptr) return nullptr; auto type_info = obj->type_info(); if (type_info == nullptr) return ""; return CreateCStringFromString(type_info->relativeName_); } } // namespace extern "C" { RUNTIME_USED RUNTIME_WEAK char* Konan_DebugBuffer() { return Konan_DebugBufferImpl(); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugBufferSize() { return Konan_DebugBufferSizeImpl(); } RUNTIME_USED RUNTIME_WEAK char* Konan_DebugBufferWithObject(KRef obj) { auto* impl = getImpl(obj, DO_DebugBufferWithObject); if (impl == nullptr) return nullptr; return impl(obj); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugBufferSizeWithObject(KRef obj) { auto* impl = getImpl(obj, DO_DebugBufferSizeWithObject); if (impl == nullptr) return 0; return impl(obj); } // Auxilary function which can be called by developer/debugger to inspect an object. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugObjectToUtf8Array(KRef obj, char* buffer, int32_t bufferSize) { auto* impl = getImpl(obj, DO_DebugObjectToUtf8Array); if (impl == nullptr) return 0; return impl(obj, buffer, bufferSize); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugPrint(KRef obj) { auto* impl = getImpl(obj, DO_DebugPrint); if (impl == nullptr) return 0; return impl(obj); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugIsArray(KRef obj) { auto* impl = getImpl(obj, DO_DebugIsArray); if (impl == nullptr) return 0; return impl(obj); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugGetFieldCount(KRef obj) { auto* impl = getImpl(obj, DO_DebugGetFieldCount); if (impl == nullptr) return 0; return impl(obj); } RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugGetFieldType(KRef obj, int32_t index) { auto* impl = getImpl(obj, DO_DebugGetFieldType); if (impl == nullptr) return 0; return impl(obj, index); } RUNTIME_USED RUNTIME_WEAK void* Konan_DebugGetFieldAddress(KRef obj, int32_t index) { auto* impl = getImpl(obj, DO_DebugGetFieldAddress); if (impl == nullptr) return nullptr; return impl(obj, index); } // Compute address of field or an array element at the index, or null, if incorrect. RUNTIME_USED RUNTIME_WEAK const char* Konan_DebugGetFieldName(KRef obj, int32_t index) { auto* impl = getImpl(obj, DO_DebugGetFieldName); if (impl == nullptr) return nullptr; return impl(obj, index); } RUNTIME_USED RUNTIME_WEAK const char* Konan_DebugGetTypeName(KRef obj) { auto* impl = getImpl(obj, DO_DebugGetTypeName); if (impl == nullptr) return nullptr; return impl(obj); } const void* Konan_debugOperationsList[] = { nullptr, reinterpret_cast(&Konan_DebugBufferImpl), reinterpret_cast(&Konan_DebugBufferSizeImpl), reinterpret_cast(&Konan_DebugBufferWithObjectImpl), reinterpret_cast(&Konan_DebugBufferSizeWithObjectImpl), reinterpret_cast(&Konan_DebugObjectToUtf8ArrayImpl), reinterpret_cast(&Konan_DebugPrintImpl), reinterpret_cast(&Konan_DebugIsArrayImpl), reinterpret_cast(&Konan_DebugGetFieldCountImpl), reinterpret_cast(&Konan_DebugGetFieldTypeImpl), reinterpret_cast(&Konan_DebugGetFieldAddressImpl), reinterpret_cast(&Konan_DebugGetFieldNameImpl), reinterpret_cast(&Konan_DebugGetTypeNameImpl) }; } // extern "C" #endif // !KONAN_NO_DEBUG_API ================================================ FILE: runtime/src/debug/cpp/SourceInfo.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "SourceInfo.h" #ifdef KONAN_CORE_SYMBOLICATION #include #include #include #include #include #include #define TRACE_SYMBOLICATION 0 #if TRACE_SYMBOLICATION #include #define SYM_LOG(...) fprintf(stderr, __VA_ARGS__) #define SYM_DUMP(p) CSShow((p)) #else #define SYM_LOG(...) #define SYM_DUMP(p) #endif typedef struct _CSTypeRef { unsigned long type; void* contents; } CSTypeRef; typedef CSTypeRef CSSymbolicatorRef; typedef CSTypeRef CSSymbolOwnerRef; typedef CSTypeRef CSSymbolRef; typedef CSTypeRef CSSourceInfoRef; typedef struct _CSRange { unsigned long long location; unsigned long long length; } CSRange; typedef unsigned long long CSArchitecture; constexpr auto kCSNow = std::numeric_limits::max(); namespace { CSSymbolicatorRef (*CSSymbolicatorCreateWithPid)(pid_t pid); CSSymbolOwnerRef (*CSSymbolicatorGetSymbolOwnerWithAddressAtTime)( CSSymbolicatorRef symbolicator, unsigned long long address, long long time ); CSSourceInfoRef (*CSSymbolOwnerGetSourceInfoWithAddress)( CSSymbolOwnerRef owner, unsigned long long address ); const char* (*CSSourceInfoGetPath)(CSSourceInfoRef info); uint32_t (*CSSourceInfoGetLineNumber)(CSSourceInfoRef info); uint32_t (*CSSourceInfoGetColumn)(CSSourceInfoRef info); bool (*CSIsNull)(CSTypeRef); CSSymbolRef (*CSSourceInfoGetSymbol)(CSSourceInfoRef info); typedef int (^CSSourceInfoIterator)(CSSourceInfoRef); int (*CSSymbolForeachSourceInfo)(CSSymbolRef, CSSourceInfoIterator); CSRange (*CSSourceInfoGetRange)(CSSourceInfoRef); CSSymbolRef (*CSSymbolOwnerGetSymbolWithAddress)(CSSymbolOwnerRef, unsigned long long); CSSymbolicatorRef symbolicator; /** * Function used for debug. */ #if TRACE_SYMBOLICATION void (*CSShow)(CSTypeRef); #endif bool TryInitializeCoreSymbolication() { void* cs = dlopen("/System/Library/PrivateFrameworks/CoreSymbolication.framework/CoreSymbolication", RTLD_LAZY); if (!cs) return false; #define KONAN_CS_LOOKUP(name) name = (decltype(name)) dlsym(cs, #name); if (!name) return false; KONAN_CS_LOOKUP(CSSymbolicatorCreateWithPid) KONAN_CS_LOOKUP(CSSymbolicatorGetSymbolOwnerWithAddressAtTime) KONAN_CS_LOOKUP(CSSymbolOwnerGetSourceInfoWithAddress) KONAN_CS_LOOKUP(CSSourceInfoGetPath) KONAN_CS_LOOKUP(CSSourceInfoGetLineNumber) KONAN_CS_LOOKUP(CSSourceInfoGetColumn) KONAN_CS_LOOKUP(CSIsNull) KONAN_CS_LOOKUP(CSSourceInfoGetSymbol) KONAN_CS_LOOKUP(CSSymbolForeachSourceInfo) KONAN_CS_LOOKUP(CSSymbolOwnerGetSymbolWithAddress) KONAN_CS_LOOKUP(CSSourceInfoGetRange) #if TRACE_SYMBOLICATION KONAN_CS_LOOKUP(CSShow) #endif #undef KONAN_CS_LOOKUP symbolicator = CSSymbolicatorCreateWithPid(getpid()); return !CSIsNull(symbolicator); } } // namespace typedef struct { const char * fileName; int start; int end; } SymbolSourceInfoLimits; extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) { __block SourceInfo result = { .fileName = nullptr, .lineNumber = -1, .column = -1 }; __block bool continueUpdateResult = true; __block SymbolSourceInfoLimits limits = {.start = -1, .end = -1}; static bool csIsAvailable = TryInitializeCoreSymbolication(); if (csIsAvailable) { unsigned long long address = static_cast((uintptr_t)addr); CSSymbolOwnerRef symbolOwner = CSSymbolicatorGetSymbolOwnerWithAddressAtTime(symbolicator, address, kCSNow); if (CSIsNull(symbolOwner)) return result; CSSymbolRef symbol = CSSymbolOwnerGetSymbolWithAddress(symbolOwner, address); if (CSIsNull(symbol)) return result; SYM_LOG("Kotlin_getSourceInfo: address: %p\n", addr); SYM_DUMP(symbol); /** * ASSUMPTION: we assume that the _first_ and the _last_ source infos should belong to real function(symbol) the rest might belong to * inlined functions. */ CSSymbolForeachSourceInfo(symbol, ^(CSSourceInfoRef ref) { // Expecting CSSourceInfoGetLineNumber not to overflow int32_t max value. int32_t lineNumber = CSSourceInfoGetLineNumber(ref); if (lineNumber == 0) return 0; if (limits.start == -1) { limits.start = lineNumber; limits.fileName = CSSourceInfoGetPath(ref); } else { limits.end = lineNumber; } return 0; }); SYM_LOG("limits: {%s %d..%d}\n", limits.fileName, limits.start, limits.end); result.fileName = limits.fileName; CSSymbolForeachSourceInfo(symbol, ^(CSSourceInfoRef ref) { // Expecting CSSourceInfoGetLineNumber not to overflow int32_t max value. int32_t lineNumber = CSSourceInfoGetLineNumber(ref); if (lineNumber == 0) return 0; SYM_DUMP(ref); CSRange range = CSSourceInfoGetRange(ref); const char* fileName = CSSourceInfoGetPath(ref); /** * We need to change API fo Kotlin_getSourceInfo to return information about inlines, * but for a moment we have to track that we updating result info _only_ for upper level or _inlined at_ and * don't go deeper. at deeper level we check only that we at the right _inlined at_ position. */ if (continueUpdateResult && strcmp(limits.fileName, fileName) == 0 && lineNumber >= limits.start && lineNumber <= limits.end) { result.lineNumber = lineNumber; result.column = CSSourceInfoGetColumn(ref); } /** * if found right inlined function don't bother with * updating high level inlined _at_ source info */ if (continueUpdateResult && (address >= range.location && address < range.location + range.length)) continueUpdateResult = false; return 0; }); } return result; } #else // KONAN_CORE_SYMBOLICATION extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) { return (SourceInfo) { .fileName = nullptr, .lineNumber = -1, .column = -1 }; } #endif // KONAN_CORE_SYMBOLICATION ================================================ FILE: runtime/src/exceptions_support/cpp/ExceptionsSupport.cpp ================================================ #include "Memory.h" #include "Porting.h" #include #ifndef KONAN_NO_EXCEPTIONS std::type_info const* ExceptionObjHolderRTTI; // Just some DCE-surviving code referencing RTTI of ExceptionObjHolder. // This is needed during compilation to cache. void referenceExceptionObjHolderRTTI() { ExceptionObjHolderRTTI = &typeid(ExceptionObjHolder); } #endif ================================================ FILE: runtime/src/launcher/cpp/androidLauncher.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "KString.h" #include "Memory.h" #include "Natives.h" #include "Porting.h" #include "Runtime.h" #include "Types.h" #ifdef KONAN_ANDROID #include #include #include #include #include #include "androidLauncher.h" #include #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Konan_main", __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "Konan_main", __VA_ARGS__)) /* For debug builds, always enable the debug traces in this library */ #ifndef NDEBUG # define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "Konan_main", __VA_ARGS__)) #else # define LOGV(...) ((void)0) #endif //--- main --------------------------------------------------------------------// extern "C" KInt Konan_start(const ObjHeader*); namespace { typedef struct { int pipeC; int pipeKonan; NativeActivityState nativeActivityState; } LauncherState; LauncherState* launcherState = nullptr; } extern "C" void getNativeActivityState(NativeActivityState* state) { state->activity = launcherState->nativeActivityState.activity; state->savedState = launcherState->nativeActivityState.savedState; state->savedStateSize = launcherState->nativeActivityState.savedStateSize; state->looper = launcherState->nativeActivityState.looper; } extern "C" void notifySysEventProcessed() { int8_t message; write(launcherState->pipeKonan, &message, sizeof(message)); } namespace { void launchMain() { Kotlin_initRuntimeIfNeeded(); { ObjHolder args; AllocArrayInstance(theArrayTypeInfo, 0, args.slot()); Konan_start(args.obj()); } // TODO: Can we shutdown runtime here? Kotlin_deinitRuntimeIfNeeded(); } void* entry(void* param) { ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, launcherState->pipeKonan, LOOPER_ID_SYS, ALOOPER_EVENT_INPUT, NULL, NULL); launcherState->nativeActivityState.looper = looper; launchMain(); return nullptr; } void runKonan_start(bool startThread) { if (!startThread) { launchMain(); return; } int pipes[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipes)) { LOGE("Could not create pipe: %s", strerror(errno)); return; } launcherState->pipeC = pipes[0]; launcherState->pipeKonan = pipes[1]; LOGE("runKonan_start() %d %d", launcherState->pipeC, launcherState->pipeKonan); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; pthread_create(&thread, &attr, entry, nullptr); } void putEventSynchronously(void* event) { auto value = reinterpret_cast(event); if (write(launcherState->pipeC, &value, sizeof(value)) != sizeof(value)) { LOGE("Failure writing event: %s\n", strerror(errno)); } int8_t response; if (read(launcherState->pipeC, &response, sizeof(response)) != sizeof(response)) { LOGE("Failure reading response: %s\n", strerror(errno)); } } void onDestroy(ANativeActivity* activity) { LOGV("onDestroy called"); NativeActivityEvent event = { DESTROY }; putEventSynchronously(&event); } void onStart(ANativeActivity* activity) { LOGV("onStart called"); NativeActivityEvent event = { START }; putEventSynchronously(&event); } void onResume(ANativeActivity* activity) { LOGV("onResume called"); NativeActivitySaveStateEvent event = { RESUME, nullptr, 0 }; putEventSynchronously(&event); } void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { LOGV("onSaveInstanceState called"); NativeActivitySaveStateEvent event = { SAVE_INSTANCE_STATE, nullptr, 0 }; putEventSynchronously(&event); *outLen = event.savedStateSize; return event.savedState; } void onPause(ANativeActivity* activity) { LOGV("onPause called"); NativeActivityEvent event = { PAUSE }; putEventSynchronously(&event); } void onStop(ANativeActivity* activity) { LOGV("onStop called"); NativeActivityEvent event = { STOP }; putEventSynchronously(&event); } void onConfigurationChanged(ANativeActivity* activity) { LOGV("onConfigurationChanged called"); NativeActivityEvent event = { CONFIGURATION_CHANGED }; putEventSynchronously(&event); } void onLowMemory(ANativeActivity* activity) { LOGV("onLowMemory called"); NativeActivityEvent event = { LOW_MEMORY }; putEventSynchronously(&event); } void onWindowFocusChanged(ANativeActivity* activity, int focused) { LOGV("onWindowFocusChanged called"); NativeActivityEvent event = { focused ? WINDOW_GAINED_FOCUS : WINDOW_LOST_FOCUS }; putEventSynchronously(&event); } void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { LOGV("onNativeWindowCreated called"); NativeActivityWindowEvent event = { NATIVE_WINDOW_CREATED, window }; putEventSynchronously(&event); } void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { LOGV("onNativeWindowDestroyed called"); NativeActivityWindowEvent event = { NATIVE_WINDOW_DESTROYED, window }; putEventSynchronously(&event); } void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { LOGV("onInputQueueCreated called"); NativeActivityQueueEvent event = { INPUT_QUEUE_CREATED, queue }; putEventSynchronously(&event); } void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { LOGV("onInputQueueDestroyed called"); NativeActivityQueueEvent event = { INPUT_QUEUE_DESTROYED, queue }; putEventSynchronously(&event); } } extern "C" void RUNTIME_USED Konan_main( ANativeActivity* activity, void* savedState, size_t savedStateSize) { bool launchThread = activity->instance == nullptr; if (launchThread) { launcherState = (LauncherState*)konan::calloc(sizeof(LauncherState), 1); launcherState->nativeActivityState = {activity, savedState, savedStateSize, nullptr}; activity->instance = launcherState; activity->callbacks->onDestroy = onDestroy; activity->callbacks->onStart = onStart; activity->callbacks->onResume = onResume; activity->callbacks->onSaveInstanceState = onSaveInstanceState; activity->callbacks->onPause = onPause; activity->callbacks->onStop = onStop; activity->callbacks->onConfigurationChanged = onConfigurationChanged; activity->callbacks->onLowMemory = onLowMemory; activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; activity->callbacks->onInputQueueCreated = onInputQueueCreated; activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; } else { launcherState = (LauncherState*)activity->instance; } runKonan_start(launchThread); } #endif // KONAN_ANDROID ================================================ FILE: runtime/src/launcher/cpp/androidLauncher.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_LAUNCHER_H #define ANDROID_LAUNCHER_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif struct NativeActivityState { struct ANativeActivity* activity; void* savedState; size_t savedStateSize; struct ALooper* looper; }; void getNativeActivityState(struct NativeActivityState* state); void notifySysEventProcessed(); #define LOOPER_ID_SYS 1 typedef enum NativeActivityEventKind { UNKNOWN, DESTROY, START, RESUME, SAVE_INSTANCE_STATE, PAUSE, STOP, CONFIGURATION_CHANGED, LOW_MEMORY, WINDOW_GAINED_FOCUS, WINDOW_LOST_FOCUS, NATIVE_WINDOW_CREATED, NATIVE_WINDOW_DESTROYED, INPUT_QUEUE_CREATED, INPUT_QUEUE_DESTROYED } NativeActivityEventKind; struct NativeActivityEvent { NativeActivityEventKind eventKind; }; struct NativeActivitySaveStateEvent { NativeActivityEventKind eventKind; void* savedState; size_t savedStateSize; }; struct NativeActivityWindowEvent { NativeActivityEventKind eventKind; struct ANativeWindow* window; }; struct NativeActivityQueueEvent { NativeActivityEventKind eventKind; struct AInputQueue* queue; }; #ifdef __cplusplus } #endif #endif // ANDROID_LAUNCHER_H ================================================ FILE: runtime/src/launcher/cpp/launcher.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Memory.h" #include "Natives.h" #include "Runtime.h" #include "KString.h" #include "Types.h" #include "Worker.h" #ifndef KONAN_ANDROID //--- Setup args --------------------------------------------------------------// OBJ_GETTER(setupArgs, int argc, const char** argv) { // The count is one less, because we skip argv[0] which is the binary name. ObjHeader* result = AllocArrayInstance(theArrayTypeInfo, argc - 1, OBJ_RESULT); ArrayHeader* array = result->array(); for (int index = 1; index < argc; index++) { ObjHolder result; CreateStringFromCString(argv[index], result.slot()); UpdateHeapRef(ArrayAddressOfElementAt(array, index - 1), result.obj()); } return result; } //--- main --------------------------------------------------------------------// extern "C" KInt Konan_start(const ObjHeader*); extern "C" KInt Konan_run_start(int argc, const char** argv) { ObjHolder args; setupArgs(argc, argv, args.slot()); return Konan_start(args.obj()); } extern "C" RUNTIME_USED int Init_and_run_start(int argc, const char** argv, int memoryDeInit) { #ifdef KONAN_NO_CTORS_SECTION extern void _Konan_constructors(void); _Konan_constructors(); #endif Kotlin_initRuntimeIfNeeded(); KInt exitStatus = Konan_run_start(argc, argv); if (memoryDeInit) { Kotlin_shutdownRuntime(); } return exitStatus; } extern "C" RUNTIME_USED int Konan_main(int argc, const char** argv) { return Init_and_run_start(argc, argv, 1); } #ifdef KONAN_WASM // Before we pass control to Konan_main, we need to obtain argv elements // from the javascript world. extern "C" int Konan_js_arg_size(int index); extern "C" int Konan_js_fetch_arg(int index, char* ptr); extern "C" RUNTIME_USED int Konan_js_main(int argc, int memoryDeInit) { char** argv = (char**)konan::calloc(1, argc); for (int i = 0; i< argc; ++i) { argv[i] = (char*)konan::calloc(1, Konan_js_arg_size(i)); Konan_js_fetch_arg(i, argv[i]); } return Init_and_run_start(argc, (const char**)argv, memoryDeInit); } #endif #endif ================================================ FILE: runtime/src/launcher/js/index.html ================================================ ================================================ FILE: runtime/src/launcher/js/launcher.js ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ let instance; let heap; let global_arguments; function isBrowser() { return typeof self !== 'undefined'; } let runtime; if (isBrowser()) { runtime = { print: console.log, stdout: '', write: function (message) { this.stdout += message; const lastNewlineIndex = this.stdout.lastIndexOf('\n'); if (lastNewlineIndex == -1) return; this.print(this.stdout.substring(0, lastNewlineIndex)); this.stdout = this.stdout.substring(lastNewlineIndex + 1) }, flush: function () { this.print(this.stdout); }, exit: function (status) { throw Error("Kotlin process called exit (" + status + ")"); } }; } else { runtime = { write: write, print: print, flush: function () { }, exit: quit }; } function print_usage() { // TODO: any reliable way to obtain the current script name? runtime.print('Usage: d8 --expose-wasm launcher.js -- ...') quit(1); // TODO: this is d8 specific } function utf8encode(s) { return unescape(encodeURIComponent(s)); } function utf8decode(s) { return decodeURIComponent(escape(s)); } function fromString(string, pointer) { for (let i = 0; i < string.length; i++) { heap[pointer + i] = string.charCodeAt(i); } heap[pointer + string.length] = 0; } function toString(pointer) { let string = ''; for (let i = pointer; heap[i] != 0; i++) { string += String.fromCharCode(heap[i]); } return string; } function toUTF16String(pointer, size) { let string = ''; for (let i = pointer; i < pointer + size; i += 2) { string += String.fromCharCode(heap[i] + heap[i + 1] * 256); } return string; } function twoIntsToDouble(upper, lower) { const buffer = new ArrayBuffer(8); const ints = new Int32Array(buffer); const doubles = new Float64Array(buffer); ints[1] = upper; ints[0] = lower; return doubles[0]; } function doubleToTwoInts(value) { const buffer = new ArrayBuffer(8); const ints = new Int32Array(buffer); const doubles = new Float64Array(buffer); doubles[0] = value; return {upper: ints[1], lower: ints[0]} } function int32ToHeap(value, pointer) { heap[pointer] = value & 0xff; heap[pointer + 1] = (value & 0xff00) >>> 8; heap[pointer + 2] = (value & 0xff0000) >>> 16; heap[pointer + 3] = (value & 0xff000000) >>> 24; } function doubleToReturnSlot(value) { const twoInts = doubleToTwoInts(value); instance.exports.ReturnSlot_setDouble(twoInts.upper, twoInts.lower); } let konan_dependencies = { env: { abort: function () { throw new Error("abort()"); }, // TODO: Account for file and size. fgets: function (str, size, file) { // TODO: readline can't read lines without a newline. // Browsers cant read from console at all. fromString(utf8encode(readline() + '\n'), str); return str; }, read: function (file, str, size) { let string = utf8encode(readline() + '\n'); fromString(string.substring(0, size), str); return string.length; }, Konan_notify_memory_grow: function() { heap = new Uint8Array(instance.exports.memory.buffer); }, Konan_abort: function (pointer) { throw new Error("Konan_abort(" + utf8decode(toString(pointer)) + ")"); }, Konan_exit: function (status) { runtime.exit(status); }, Konan_js_arg_size: function (index) { if (index >= global_arguments.length) return -1; return global_arguments[index].length + 1; // + 1 for trailing zero. }, Konan_js_fetch_arg: function (index, ptr) { let arg = utf8encode(global_arguments[index]); fromString(arg, ptr); }, Konan_date_now: function (pointer) { let now = Date.now(); let high = Math.floor(now / 0xffffffff); let low = Math.floor(now % 0xffffffff); int32ToHeap(low, pointer); int32ToHeap(high, pointer + 4); }, // TODO: Account for fd and size. write: function (fd, str, size) { if (fd != 1 && fd != 2) throw ("write(" + fd + ", ...)"); // TODO: There is no writeErr() in d8. // Approximate it with write() to stdout for now. runtime.write(utf8decode(toString(str))); }, fflush: function(file) { runtime.flush(); } } }; function linkJavaScriptLibraries() { konan.libraries.forEach(function (library) { for (const property in library) { konan_dependencies.env[property] = library[property]; } }); } function invokeModule(inst, args) { if (args.length < 1) print_usage(); global_arguments = args; instance = inst; heap = new Uint8Array(instance.exports.memory.buffer); let exit_status = 0; try { exit_status = instance.exports.Konan_js_main(args.length, isBrowser() ? 0 : 1); } catch (e) { runtime.print("Exception executing entry point: " + e); runtime.print(e.stack); exit_status = 1; } runtime.flush(); return exit_status; } // Instantiate module in Browser. function instantiateAndRun(arraybuffer, args) { linkJavaScriptLibraries(); WebAssembly.instantiate(arraybuffer, konan_dependencies) .then(resultObject => invokeModule(resultObject.instance, args)); } // Instantiate module in d8 synchronously. function instantiateAndRunSync(arraybuffer, args) { const module = new WebAssembly.Module(arraybuffer); linkJavaScriptLibraries(); const instance = new WebAssembly.Instance(module, konan_dependencies); return invokeModule(instance, args) } // Instantiate module in Browser using streaming instantiation. function instantiateAndRunStreaming(filename) { linkJavaScriptLibraries(); WebAssembly.instantiateStreaming(fetch(filename), konan_dependencies) .then(resultObject => invokeModule(resultObject.instance, [filename])); } konan.moduleEntry = function (args) { if (isBrowser()) { if (!document.currentScript.hasAttribute("wasm")) { throw new Error('Could not find the wasm attribute pointing to the WebAssembly binary.'); } const filename = document.currentScript.getAttribute("wasm"); if (typeof WebAssembly.instantiateStreaming === 'function') { instantiateAndRunStreaming(filename); } else { fetch(filename) .then(response => response.arrayBuffer()) .then(arraybuffer => instantiateAndRun(arraybuffer, [filename])); } } else { // Invoke from d8. const arrayBuffer = readbuffer(args[0]); const exitStatus = instantiateAndRunSync(arrayBuffer, args); quit(exitStatus); } }; ================================================ FILE: runtime/src/legacymm/cpp/CyclicCollector.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef KONAN_NO_THREADS #define WITH_WORKERS 1 #endif #include "Alloc.h" #include "Atomic.h" #include "KAssert.h" #include "Memory.h" #include "MemoryPrivate.hpp" #include "Natives.h" #include "Porting.h" #include "Types.h" #if WITH_WORKERS #include #include "PthreadUtils.h" #endif #if WITH_WORKERS // Define to 1 to print collector traces. #define TRACE_COLLECTOR 0 #if TRACE_COLLECTOR #define COLLECTOR_LOG(...) konan::consolePrintf(__VA_ARGS__); #else #define COLLECTOR_LOG(...) #endif /** * Theory of operations: * * Kotlin/Native runtime has concurrent cyclic garbage collection for the shared mutable objects, * such as `AtomicReference` and `FreezableAtomicReference` instances (further known as the atomic rootset). * We perform such analysis by iterating over the transitive closure of the atomic rootset, and computing * aggregated inner reference counter for rootset elements over this transitive closure. * Collector runs in its own thread and is started by an explicit request or after certain time interval since last * collection passes, thus its operation does not affect UI responsiveness in most cases. * Atomic rootset is built by maintaining the set of all atomic and freezable atomic references objects. * Elements whose transitive closure inner reference count matches the actual reference count are ones * belonging to the garbage cycles and thus can be discarded. * We ignore elements reachable from objects having external references (i.e. inner rc != real rc). * If during computations of the aggregated RC there were modifications in the reference counts of * elements of the atomic rootset: * - if it is being increased, then someone already got an external reference to this element, thus we may not * end up matching the inner reference count anyway * - if it is being decreased and object become garbage, it will be collected next time * If transitive closure of the atomic rootset mutates, it could only happen via changing the atomics references, * as all elements of this closure are frozen. * To handle such mutations we keep collector flag, which is cleared before analysis and set on every * atomic reference value update. If flag's value changes - collector restarts its analysis. * There are not so much of complications in this algorithm due to the delayed reference counting as if there's a * stack reference to the shared object - it's reflected in the reference counter (see rememberNewContainer()). * We release objects found by the collector on a rendezvouz callback, but not on the main thread, * to keep UI responsive, as taking GC lock can take time, sometimes. */ namespace { class Locker { pthread_mutex_t* lock_; public: Locker(pthread_mutex_t* alock): lock_(alock) { pthread_mutex_lock(lock_); } ~Locker() { pthread_mutex_unlock(lock_); } }; template inline void traverseObjectFields(ObjHeader* obj, func process) { RuntimeAssert(obj != nullptr, "Must be non null"); const TypeInfo* typeInfo = obj->type_info(); if (typeInfo != theArrayTypeInfo) { for (int index = 0; index < typeInfo->objOffsetsCount_; index++) { ObjHeader** location = reinterpret_cast( reinterpret_cast(obj) + typeInfo->objOffsets_[index]); process(location); } } else { ArrayHeader* array = obj->array(); for (uint32_t index = 0; index < array->count_; index++) { process(ArrayAddressOfElementAt(array, index)); } } } inline bool isAtomicReference(ObjHeader* obj) { return (obj->type_info()->flags_ & TF_LEAK_DETECTOR_CANDIDATE) != 0; } #define CHECK_CALL(call, message) RuntimeCheck((call) == 0, message) class CyclicCollector { pthread_mutex_t lock_; pthread_mutex_t timestampLock_; pthread_cond_t cond_; pthread_t gcThread_; int currentAliveWorkers_; int gcRunning_; int mutatedAtomics_; int pendingRelease_; bool shallRunCollector_; bool terminateCollector_; int32_t currentTick_; int32_t lastTick_; int64_t lastTimestampUs_; void* mainWorker_; KStdUnorderedSet rootset_; KStdUnorderedSet toRelease_; public: CyclicCollector() { CHECK_CALL(pthread_mutex_init(&lock_, nullptr), "Cannot init collector mutex"); CHECK_CALL(pthread_mutex_init(×tampLock_, nullptr), "Cannot init collector timestamp mutex"); CHECK_CALL(pthread_cond_init(&cond_, nullptr), "Cannot init collector condition"); CHECK_CALL(pthread_create(&gcThread_, nullptr, gcWorkerRoutine, this), "Cannot start collector thread"); } void clear() { Locker lock(&lock_); rootset_.clear(); toRelease_.clear(); } void terminate(bool enabled) { { Locker locker(&lock_); terminateCollector_ = true; if (enabled) shallRunCollector_ = true; CHECK_CALL(pthread_cond_signal(&cond_), "Cannot signal collector"); } // TODO: improve waiting for collector termination. while (atomicGet(&terminateCollector_)) {} releasePendingUnlocked(nullptr); } ~CyclicCollector() { pthread_cond_destroy(&cond_); pthread_mutex_destroy(&lock_); pthread_mutex_destroy(×tampLock_); } static void* gcWorkerRoutine(void* argument) { CyclicCollector* thiz = reinterpret_cast(argument); thiz->gcProcessor(); return nullptr; } void gcProcessor() { { Locker locker(&lock_); KStdDeque toVisit; KStdUnorderedSet visited; KStdUnorderedMap sideRefCounts; int restartCount = 0; while (!terminateCollector_) { CHECK_CALL(pthread_cond_wait(&cond_, &lock_), "Cannot wait collector condition"); if (!shallRunCollector_) continue; atomicSet(&gcRunning_, 1); restartCount = 0; restart: COLLECTOR_LOG("start cycle GC\n"); if (restartCount > 10 && !terminateCollector_) { COLLECTOR_LOG("wait for some time to avoid GC thrashing\n"); uint64_t nsDelta = 1000LL * 1000LL * (restartCount - 10); WaitOnCondVar(&cond_, &lock_, nsDelta); } atomicSet(&mutatedAtomics_, 0); visited.clear(); toVisit.clear(); sideRefCounts.clear(); for (auto* root: rootset_) { // We only care about frozen values here, as only they could become part of shared cycles. if (!containerFor(root)->frozen()) continue; COLLECTOR_LOG("process root %p\n", root); toVisit.push_back(root); sideRefCounts[root] = 0; } while (toVisit.size() > 0) { if (atomicGet(&mutatedAtomics_) != 0) { COLLECTOR_LOG("restarted during rootset visit\n") restartCount++; goto restart; } auto* obj = toVisit.front(); toVisit.pop_front(); COLLECTOR_LOG("visit %s%p\n", isAtomicReference(obj) ? "atomic " : "", obj); auto* objContainer = containerFor(obj); if (objContainer == nullptr) continue; // Permanent object. RuntimeCheck(objContainer->shareable(), "Must be shareable"); if (visited.count(obj) == 0) { visited.insert(obj); traverseObjectFields(obj, [&toVisit, obj, &sideRefCounts](ObjHeader** location) { ObjHeader* ref = *location; if (ref != nullptr) { COLLECTOR_LOG("object field %p in %p\n", ref, obj) int increment; // We shall not account for edges inside the same frozen container, unless it originates // from an atomic reference. if (isAtomicReference(obj) || (containerFor(obj) != containerFor(ref))) { COLLECTOR_LOG("counting %p -> %p\n", obj, ref) increment = 1; } else { COLLECTOR_LOG("not counting %p -> %p\n", obj, ref) increment = 0; } sideRefCounts[ref] += increment; toVisit.push_back(ref); } }); } } // Now find all elements with external references, and mark objects reachable from them as non suitable // for collection by setting their side reference count to -1. toVisit.clear(); for (auto it: sideRefCounts) { auto* obj = it.first; auto* objContainer = containerFor(obj); if (objContainer == nullptr) continue; // Permanent object. int refCount; // If object is in aggregated container - sum up RC for all elements. if (objContainer->objectCount() != 1) { RuntimeAssert(objContainer->frozen(), "Must be frozen aggregate"); ContainerHeader** subContainer = reinterpret_cast(objContainer + 1); refCount = 0; for (uint32_t i = 0; i < objContainer->objectCount(); ++i) { auto* componentObj = reinterpret_cast((*subContainer) + 1); refCount += sideRefCounts[componentObj]; subContainer++; } } else { refCount = it.second; } RuntimeAssert(refCount <= objContainer->refCount(), "Must properly count inner refs"); if (refCount != objContainer->refCount()) { COLLECTOR_LOG("for %p mismatched RC: %d vs %d, adding as possible root\n", obj, refCount, objContainer->refCount()) toVisit.push_back(it.first); } } visited.clear(); while (toVisit.size() > 0) { auto* obj = toVisit.front(); toVisit.pop_front(); auto* objContainer = containerFor(obj); if (objContainer == nullptr) continue; // Permanent object. RuntimeCheck(objContainer->shareable(), "Must be shareable"); sideRefCounts[obj] = -1; visited.insert(obj); if (atomicGet(&mutatedAtomics_) != 0) { COLLECTOR_LOG("restarted during reachable visit\n") restartCount++; goto restart; } traverseObjectFields(obj, [&toVisit, &visited](ObjHeader** location) { ObjHeader* ref = *location; if (ref != nullptr && (visited.count(ref) == 0)) { toVisit.push_back(ref); } }); } // Now release all atomic roots with matching reference counters, as only their destruction is controlled. for (auto it: sideRefCounts) { auto* obj = it.first; // Only do that for atomic rootset elements. For them we also do not have sum up references from // other elements of an aggregate, as atomic references are always in single object containers. if (!isAtomicReference(obj)) { continue; } if (atomicGet(&mutatedAtomics_) != 0) { COLLECTOR_LOG("restarted during matching check\n") restartCount++; goto restart; } auto* objContainer = containerFor(obj); if (!objContainer->frozen()) continue; RuntimeAssert(objContainer->objectCount() == 1, "Must be single object"); COLLECTOR_LOG("for %p inner %d actual %d\n", obj, it.second, objContainer->refCount()); // All references are inner. We compare the number of counted // inner references with the number of non-stack references and per-thread ownership value // (see rememberNewContainer()). if (it.second == objContainer->refCount()) { COLLECTOR_LOG("adding %p to release candidates\n", it.first); toRelease_.insert(it.first); } } if (toRelease_.size() > 0) atomicSet(&pendingRelease_, 1); atomicSet(&gcRunning_, 0); shallRunCollector_ = false; COLLECTOR_LOG("end cycle GC\n"); } } atomicSet(&terminateCollector_, false); } void addWorker(void* worker) { suggestLockRelease(); Locker lock(&lock_); currentAliveWorkers_++; if (mainWorker_ == nullptr) mainWorker_ = worker; } void removeWorker(void* worker, bool enabled) { suggestLockRelease(); Locker lock(&lock_); // When exiting the worker - we shall collect the cyclic garbage here. if (enabled) { shallRunCollector_ = true; CHECK_CALL(pthread_cond_signal(&cond_), "Cannot signal collector"); } currentAliveWorkers_--; } void addRoot(ObjHeader* obj) { COLLECTOR_LOG("add root %p\n", obj); // TODO: we can only add root when collector is not processing, which looks like a limitation, // instead we can add elements to the side buffer or have a separate lock for that. suggestLockRelease(); Locker lock(&lock_); rootset_.insert(obj); } void removeRoot(ObjHeader* obj) { COLLECTOR_LOG("remove root %p\n", obj); // Note that we can only remove root when the collector is not processing. suggestLockRelease(); Locker lock(&lock_); toRelease_.erase(obj); rootset_.erase(obj); } void mutateRoot(ObjHeader* newValue) { // TODO: consider optimization, when clearing value (setting to null) in atomic reference shall not lead // to invalidation of the collector analysis state. atomicSet(&mutatedAtomics_, 1); } void suggestLockRelease() { atomicSet(&mutatedAtomics_, 1); } bool checkIfShallCollect() { auto tick = atomicAdd(¤tTick_, 1); auto delta = tick - atomicGet(&lastTick_); if (delta > 10 || delta < 0) { auto currentTimestampUs = konan::getTimeMicros(); #if KONAN_NO_64BIT_ATOMIC if (currentTimestampUs - *(volatile int64_t*)&lastTimestampUs_ > 10000) { #else if (currentTimestampUs - atomicGet(&lastTimestampUs_) > 10000) { #endif // KONAN_NO_64BIT_ATOMIC // Do we care if this lock is not here? Locker locker(×tampLock_); lastTick_ = currentTick_; lastTimestampUs_ = currentTimestampUs; return true; } } return false; } void releasePendingUnlocked(void* worker) { // We are not doing that on the UI thread, as taking lock is slow, unless // it happens on deinit of the collector or if there are no other workers. if ((atomicGet(&pendingRelease_) != 0) && ((worker != mainWorker_) || (currentAliveWorkers_ == 1))) { KStdVector heapRefsToRelease; { suggestLockRelease(); Locker locker(&lock_); COLLECTOR_LOG("clearing %d release candidates on %p\n", toRelease_.size(), worker); for (auto* it: toRelease_) { COLLECTOR_LOG("clear references in %p\n", it) traverseObjectFields(it, [&heapRefsToRelease](ObjHeader** location) { // Avoid using ZeroHeapRef here: it can provoke garbageCollect() which would then stuck on taking [lock_] // (which is already taken above). auto* value = *location; if (reinterpret_cast(value) > 1) { *location = nullptr; heapRefsToRelease.push_back(value); } }); } toRelease_.clear(); atomicSet(&pendingRelease_, 0); } for (auto* it: heapRefsToRelease) { ReleaseHeapRef(it); } } } void collectorCallaback(void* worker) { if (atomicGet(&gcRunning_) != 0) return; releasePendingUnlocked(worker); if (checkIfShallCollect()) { Locker locker(&lock_); shallRunCollector_ = true; CHECK_CALL(pthread_cond_signal(&cond_), "Cannot signal collector"); } } void scheduleGarbageCollect() { if (atomicGet(&gcRunning_) != 0) return; Locker lock(&lock_); shallRunCollector_ = true; CHECK_CALL(pthread_cond_signal(&cond_), "Cannot signal collector"); } void localGC() { // We just need to take GC lock here, to avoid release of object we walk on. // TODO: consider optimization without taking the lock and just notifying collector via an atomic. suggestLockRelease(); Locker locker(&lock_); } }; CyclicCollector* cyclicCollector = nullptr; } // namespace #endif // WITH_WORKERS void cyclicInit() { #if WITH_WORKERS RuntimeAssert(cyclicCollector == nullptr, "Must be not yet inited"); cyclicCollector = konanConstructInstance(); #endif } void cyclicDeinit(bool enabled) { #if WITH_WORKERS RuntimeAssert(cyclicCollector != nullptr, "Must be inited"); auto* local = cyclicCollector; local->terminate(enabled); cyclicCollector = nullptr; // Workaround data race with threads non-atomically reading and then using [cyclicCollector]. // konanDestructInstance(local); // Note: memory leaks here indeed, but usually it happens once per application. // Make best effort to clean some memory: local->clear(); #endif // WITH_WORKERS } void cyclicAddWorker(void* worker) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->addWorker(worker); #endif // WITH_WORKERS } void cyclicRemoveWorker(void* worker, bool enabled) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->removeWorker(worker, enabled); #endif // WITH_WORKERS } void cyclicCollectorCallback(void* worker) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->collectorCallaback(worker); #endif // WITH_WORKERS } void cyclicScheduleGarbageCollect() { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->scheduleGarbageCollect(); #endif // WITH_WORKERS } void cyclicAddAtomicRoot(ObjHeader* obj) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->addRoot(obj); #endif // WITH_WORKERS } void cyclicRemoveAtomicRoot(ObjHeader* obj) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->removeRoot(obj); #endif // WITH_WORKERS } void cyclicMutateAtomicRoot(ObjHeader* newValue) { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->mutateRoot(newValue); #endif // WITH_WORKERS } void cyclicLocalGC() { #if WITH_WORKERS auto* local = cyclicCollector; if (local) local->localGC(); #endif // WITH_WORKERS } ================================================ FILE: runtime/src/legacymm/cpp/CyclicCollector.h ================================================ #ifndef RUNTIME_CYCLIC_COLLECTOR_H #define RUNTIME_CYCLIC_COLLECTOR_H struct ObjHeader; void cyclicInit(); void cyclicDeinit(bool enabled); void cyclicAddWorker(void* worker); void cyclicRemoveWorker(void* worker, bool enabled); void cyclicAddAtomicRoot(ObjHeader* obj); void cyclicRemoveAtomicRoot(ObjHeader* obj); void cyclicMutateAtomicRoot(ObjHeader* newValue); void cyclicCollectorCallback(void* worker); void cyclicLocalGC(); void cyclicScheduleGarbageCollect(); #endif // RUNTIME_CYCLIC_COLLECTOR_H ================================================ FILE: runtime/src/legacymm/cpp/Memory.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include // for offsetof #include // Allow concurrent global cycle collector. #define USE_CYCLIC_GC 0 // CycleDetector internally uses static local with runtime initialization, // which requires atomics. Atomics are not available on WASM. #ifdef KONAN_WASM #define USE_CYCLE_DETECTOR 0 #else #define USE_CYCLE_DETECTOR 1 #endif #include "Alloc.h" #include "KAssert.h" #include "Atomic.h" #include "Cleaner.h" #if USE_CYCLIC_GC #include "CyclicCollector.h" #endif // USE_CYCLIC_GC #include "Exceptions.h" #include "FinalizerHooks.hpp" #include "FreezeHooks.hpp" #include "KString.h" #include "Memory.h" #include "MemoryPrivate.hpp" #include "Mutex.hpp" #include "Natives.h" #include "ObjectTraversal.hpp" #include "Porting.h" #include "Runtime.h" #include "Utils.hpp" #include "WorkerBoundReference.h" #include "Weak.h" #ifdef KONAN_OBJC_INTEROP #include "ObjCMMAPI.h" #endif // If garbage collection algorithm for cyclic garbage to be used. // We are using the Bacon's algorithm for GC, see // http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon03Pure.pdf. #define USE_GC 1 // Define to 1 to print all memory operations. #define TRACE_MEMORY 0 // Define to 1 to print major GC events. #define TRACE_GC 0 // Collect memory manager events statistics. #define COLLECT_STATISTIC 0 // Define to 1 to print detailed time statistics for GC events. #define PROFILE_GC 0 #if COLLECT_STATISTIC #include #endif namespace { ALWAYS_INLINE bool IsStrictMemoryModel() noexcept { return CurrentMemoryModel == MemoryModel::kStrict; } typedef uint32_t container_size_t; // Granularity of arena container chunks. constexpr container_size_t kContainerAlignment = 1024; // Single object alignment. constexpr container_size_t kObjectAlignment = 8; // Required e.g. for object size computations to be correct. static_assert(sizeof(ContainerHeader) % kObjectAlignment == 0, "sizeof(ContainerHeader) is not aligned"); #if TRACE_MEMORY #undef TRACE_GC #define TRACE_GC 1 #define MEMORY_LOG(...) konan::consolePrintf(__VA_ARGS__); #else #define MEMORY_LOG(...) #endif #if TRACE_GC #define GC_LOG(...) konan::consolePrintf(__VA_ARGS__); #else #define GC_LOG(...) #endif #if USE_GC // Collection threshold default (collect after having so many elements in the // release candidates set). constexpr size_t kGcThreshold = 8 * 1024; // Ergonomic thresholds. // If GC to computations time ratio is above that value, // increase GC threshold by 1.5 times. constexpr double kGcToComputeRatioThreshold = 0.5; // Never exceed this value when increasing GC threshold. constexpr size_t kMaxErgonomicThreshold = 32 * 1024; // Threshold of size for toFree set, triggering actual cycle collector. constexpr size_t kMaxToFreeSizeThreshold = 8 * 1024; // Never exceed this value when increasing size for toFree set, triggering actual cycle collector. constexpr size_t kMaxErgonomicToFreeSizeThreshold = 8 * 1024 * 1024; // How many elements in finalizer queue allowed before cleaning it up. constexpr int32_t kFinalizerQueueThreshold = 32; // If allocated that much memory since last GC - force new GC. constexpr size_t kMaxGcAllocThreshold = 8 * 1024 * 1024; // If the ratio of GC collection cycles time to program execution time is greater this value, // increase GC threshold for cycles collection. constexpr double kGcCollectCyclesLoadRatio = 0.3; // Minimum time of cycles collection to change thresholds. constexpr size_t kGcCollectCyclesMinimumDuration = 200; #endif // USE_GC typedef KStdUnorderedSet ContainerHeaderSet; typedef KStdVector ContainerHeaderList; typedef KStdDeque ContainerHeaderDeque; typedef KStdVector KRefList; typedef KStdVector KRefPtrList; typedef KStdUnorderedSet KRefSet; typedef KStdUnorderedMap KRefIntMap; typedef KStdDeque KRefDeque; typedef KStdDeque KRefListDeque; // A little hack that allows to enable -O2 optimizations // Prevents clang from replacing FrameOverlay struct // with single pointer. // Can be removed when FrameOverlay will become more complex. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" FrameOverlay exportFrameOverlay; #pragma clang diagnostic pop // Current number of allocated containers. volatile int allocCount = 0; volatile int aliveMemoryStatesCount = 0; #if USE_CYCLIC_GC KBoolean g_hasCyclicCollector = true; #endif // USE_CYCLIC_GC // TODO: Consider using ObjHolder. class ScopedRefHolder : private kotlin::MoveOnly { public: ScopedRefHolder() = default; explicit ScopedRefHolder(KRef obj); ScopedRefHolder(ScopedRefHolder&& other) noexcept: obj_(other.obj_) { other.obj_ = nullptr; } ScopedRefHolder& operator=(ScopedRefHolder&& other) noexcept { ScopedRefHolder tmp(std::move(other)); swap(tmp); return *this; } ~ScopedRefHolder(); void swap(ScopedRefHolder& other) noexcept { std::swap(obj_, other.obj_); } private: KRef obj_ = nullptr; }; #if USE_CYCLE_DETECTOR struct CycleDetectorRootset { // Orders roots. KStdVector roots; // Pins a state of each root. KStdUnorderedMap> rootToFields; // Holding roots and their fields to avoid GC-ing them. KStdVector heldRefs; }; class CycleDetector : private kotlin::Pinned, public KonanAllocatorAware { public: static void insertCandidateIfNeeded(KRef object) { if (canBeACandidate(object)) instance().insertCandidate(object); } static void removeCandidateIfNeeded(KRef object) { if (canBeACandidate(object)) instance().removeCandidate(object); } static CycleDetectorRootset collectRootset(); private: CycleDetector() = default; ~CycleDetector() = default; static CycleDetector& instance() { // Only store a pointer to CycleDetector in .bss static CycleDetector* result = new CycleDetector(); return *result; } static bool canBeACandidate(KRef object) { return KonanNeedDebugInfo && Kotlin_memoryLeakCheckerEnabled() && (object->type_info()->flags_ & TF_LEAK_DETECTOR_CANDIDATE) != 0; } void insertCandidate(KRef candidate) { std::lock_guard guard(lock_); auto it = candidateList_.insert(candidateList_.begin(), candidate); candidateInList_.emplace(candidate, it); } void removeCandidate(KRef candidate) { std::lock_guard guard(lock_); auto it = candidateInList_.find(candidate); if (it == candidateInList_.end()) return; candidateList_.erase(it->second); candidateInList_.erase(it); } kotlin::SpinLock lock_; using CandidateList = KStdList; CandidateList candidateList_; KStdUnorderedMap candidateInList_; }; #endif // USE_CYCLE_DETECTOR // TODO: can we pass this variable as an explicit argument? THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr; THREAD_LOCAL_VARIABLE FrameOverlay* currentFrame = nullptr; #if COLLECT_STATISTIC class MemoryStatistic { public: // UpdateRef per-object type counters. uint64_t updateCounters[12][10]; // Alloc per container type counters. uint64_t containerAllocs[2]; // Free per container type counters. uint64_t objectAllocs[6]; // Histogram of allocation size distribution. KStdUnorderedMap* allocationHistogram; // Number of allocation cache hits. int allocCacheHit; // Number of allocation cache misses. int allocCacheMiss; // Number of regular reference increments. uint64_t addRefs; // Number of atomic reference increments. uint64_t atomicAddRefs; // Number of regular reference decrements. uint64_t releaseRefs; // Number of atomic reference decrements. uint64_t atomicReleaseRefs; // Number of potential cycle candidates. uint64_t releaseCyclicRefs; // Map of array index to human readable name. static constexpr const char* indexToName[] = { "local ", "stack ", "perm ", "frozen", "shared", "null " }; void init() { memset(containerAllocs, 0, sizeof(containerAllocs)); memset(objectAllocs, 0, sizeof(objectAllocs)); memset(updateCounters, 0, sizeof(updateCounters)); allocationHistogram = konanConstructInstance>(); allocCacheHit = 0; allocCacheMiss = 0; } void deinit() { konanDestructInstance(allocationHistogram); allocationHistogram = nullptr; } void incAddRef(const ContainerHeader* header, bool atomic, int stack) { if (atomic) atomicAddRefs++; else addRefs++; } void incReleaseRef(const ContainerHeader* header, bool atomic, bool cyclic, int stack) { if (atomic) { atomicReleaseRefs++; } else { if (cyclic) releaseCyclicRefs++; else releaseRefs++; } } void incUpdateRef(const ObjHeader* objOld, const ObjHeader* objNew, int stack) { updateCounters[toIndex(objOld, stack)][toIndex(objNew, stack)]++; } void incAlloc(size_t size, const ContainerHeader* header) { containerAllocs[0]++; ++(*allocationHistogram)[size]; } void incFree(const ContainerHeader* header) { containerAllocs[1]++; } void incAlloc(size_t size, const ObjHeader* header) { objectAllocs[toIndex(header, 0)]++; } static int toIndex(const ObjHeader* obj, int stack) { if (reinterpret_cast(obj) > 1) return toIndex(containerFor(obj), stack); else return 4 + stack * 6; } static int toIndex(const ContainerHeader* header, int stack) { if (header == nullptr) return 2 + stack * 6; // permanent. switch (header->tag()) { case CONTAINER_TAG_LOCAL : return 0 + stack * 6; case CONTAINER_TAG_STACK : return 1 + stack * 6; case CONTAINER_TAG_FROZEN : return 3 + stack * 6; case CONTAINER_TAG_SHARED : return 4 + stack * 6; } RuntimeAssert(false, "unknown container type"); return -1; } static double percents(uint64_t value, uint64_t all) { return all == 0 ? 0 : ((double)value / (double)all) * 100.0; } void printStatistic() { konan::consolePrintf("\nMemory manager statistic:\n\n"); konan::consolePrintf("Container alloc: %lld, free: %lld\n", containerAllocs[0], containerAllocs[1]); for (int i = 0; i < 6; i++) { // Only local, shared and frozen can be allocated. if (i == 0 || i == 3 || i == 4) konan::consolePrintf("Object %s alloc: %lld\n", indexToName[i], objectAllocs[i]); } konan::consolePrintf("\n"); uint64_t allUpdateRefs = 0, heapUpdateRefs = 0, stackUpdateRefs = 0; for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { allUpdateRefs += updateCounters[i][j]; if (i < 6 && j < 6) heapUpdateRefs += updateCounters[i][j]; if (i >= 6 && j >= 6) stackUpdateRefs += updateCounters[i][j]; } } konan::consolePrintf("Total updates: %lld, stack: %lld(%.2lf%%), heap: %lld(%.2lf%%)\n", allUpdateRefs, stackUpdateRefs, percents(stackUpdateRefs, allUpdateRefs), heapUpdateRefs, percents(heapUpdateRefs, allUpdateRefs)); for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (updateCounters[i][j] != 0) konan::consolePrintf("UpdateHeapRef[%s -> %s]: %lld (%.2lf%% of all, %.2lf%% of heap)\n", indexToName[i], indexToName[j], updateCounters[i][j], percents(updateCounters[i][j], allUpdateRefs), percents(updateCounters[i][j], heapUpdateRefs)); } } for (int i = 6; i < 12; i++) { for (int j = 6; j < 12; j++) { if (updateCounters[i][j] != 0) konan::consolePrintf("UpdateStackRef[%s -> %s]: %lld (%.2lf%% of all, %.2lf%% of stack)\n", indexToName[i - 6], indexToName[j - 6], updateCounters[i][j], percents(updateCounters[i][j], allUpdateRefs), percents(updateCounters[i][j], stackUpdateRefs)); } } konan::consolePrintf("\n"); konan::consolePrintf("Allocation histogram:\n"); KStdVector keys(allocationHistogram->size()); int index = 0; for (auto& it : *allocationHistogram) { keys[index++] = it.first; } std::sort(keys.begin(), keys.end()); int perLine = 4; int count = 0; for (auto it : keys) { konan::consolePrintf( "%d bytes -> %d times ", it, (*allocationHistogram)[it]); if (++count % perLine == (perLine - 1) || (count == keys.size())) konan::consolePrintf("\n"); } uint64_t allAddRefs = addRefs + atomicAddRefs; uint64_t allReleases = releaseRefs + atomicReleaseRefs + releaseCyclicRefs; konan::consolePrintf("AddRefs:\t%lld/%lld (%.2lf%% of atomic)\n" "Releases:\t%lld/%lld (%.2lf%% of atomic)\n" "ReleaseRefs affecting cycle collector : %lld (%.2lf%% of cyclic)\n", addRefs, atomicAddRefs, percents(atomicAddRefs, allAddRefs), releaseRefs, atomicReleaseRefs, percents(atomicReleaseRefs, allReleases), releaseCyclicRefs, percents(releaseCyclicRefs, allReleases)); } }; constexpr const char* MemoryStatistic::indexToName[]; #endif // COLLECT_STATISTIC inline bool isPermanentOrFrozen(ContainerHeader* container) { return container == nullptr || container->frozen(); } inline bool isShareable(ContainerHeader* container) { return container == nullptr || container->shareable(); } void setContainerFor(ObjHeader* obj, ContainerHeader* container) { obj->meta_object()->container_ = container; obj->typeInfoOrMeta_ = setPointerBits(obj->typeInfoOrMeta_, OBJECT_TAG_NONTRIVIAL_CONTAINER); } #if !KONAN_NO_EXCEPTIONS class ExceptionObjHolderImpl : public ExceptionObjHolder { public: explicit ExceptionObjHolderImpl(ObjHeader* obj) noexcept { ::SetHeapRef(&obj_, obj); } ~ExceptionObjHolderImpl() override { ZeroHeapRef(&obj_); } ObjHeader* obj() noexcept { return obj_; } private: ObjHeader* obj_; }; #endif } // namespace ContainerHeader* containerFor(const ObjHeader* obj) { unsigned bits = getPointerBits(obj->typeInfoOrMeta_, OBJECT_TAG_MASK); if ((bits & (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER)) == 0) return reinterpret_cast(const_cast(obj)) - 1; if ((bits & OBJECT_TAG_PERMANENT_CONTAINER) != 0) return nullptr; return (reinterpret_cast(clearPointerBits(obj->typeInfoOrMeta_, OBJECT_TAG_MASK)))->container_; } ALWAYS_INLINE bool isFrozen(const ObjHeader* obj) { return containerFor(obj)->frozen(); } ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) { auto* container = containerFor(obj); return container == nullptr || container->frozen(); } ALWAYS_INLINE bool isShareable(const ObjHeader* obj) { return containerFor(obj)->shareable(); } ObjHeader** ObjHeader::GetWeakCounterLocation() { return &this->meta_object()->WeakReference.counter_; } #if KONAN_OBJC_INTEROP void* ObjHeader::GetAssociatedObject() { if (!has_meta_object()) { return nullptr; } return this->meta_object()->associatedObject_; } void** ObjHeader::GetAssociatedObjectLocation() { return &this->meta_object()->associatedObject_; } void ObjHeader::SetAssociatedObject(void* obj) { this->meta_object()->associatedObject_ = obj; } #endif // KONAN_OBJC_INTEROP class ForeignRefManager { public: static ForeignRefManager* create() { ForeignRefManager* result = konanConstructInstance(); result->addRef(); return result; } void addRef() { atomicAdd(&refCount, 1); } void releaseRef() { if (atomicAdd(&this->refCount, -1) == 0) { // So the owning MemoryState has abandoned [this]. // Leaving the queued work items would result in memory leak. // Luckily current thread has exclusive access to [this], // so it can process the queue pretending like it takes ownership of all its objects: this->processAbandoned(); konanDestructInstance(this); } } bool tryReleaseRefOwned() { if (atomicAdd(&this->refCount, -1) == 0) { if (this->releaseList != nullptr) { // There are no more holders of [this] to process the enqueued work items in [releaseRef]. // Revert the reference counter back and notify the caller to process and then retry: atomicAdd(&this->refCount, 1); return false; } konanDestructInstance(this); } return true; } void enqueueReleaseRef(ObjHeader* obj) { ListNode* newListNode = konanConstructInstance(); newListNode->obj = obj; while (true) { ListNode* next = this->releaseList; newListNode->next = next; if (compareAndSet(&this->releaseList, next, newListNode)) break; } } template void processEnqueuedReleaseRefsWith(func process) { if (releaseList == nullptr) return; ListNode* toProcess = nullptr; while (true) { toProcess = releaseList; if (compareAndSet(&this->releaseList, toProcess, nullptr)) break; } while (toProcess != nullptr) { process(toProcess->obj); ListNode* next = toProcess->next; konanDestructInstance(toProcess); toProcess = next; } } private: int refCount; struct ListNode { ObjHeader* obj; ListNode* next; }; ListNode* volatile releaseList; void processAbandoned() { if (this->releaseList != nullptr) { bool hadNoStateInitialized = (memoryState == nullptr); if (hadNoStateInitialized) { // Disregard request if all runtimes are no longer alive. if (atomicGet(&aliveMemoryStatesCount) == 0) return; memoryState = InitMemory(false); // Required by ReleaseHeapRef. } processEnqueuedReleaseRefsWith([](ObjHeader* obj) { ReleaseHeapRef(obj); }); if (hadNoStateInitialized) { // Discard the memory state. DeinitMemory(memoryState, false); } } } }; namespace { class ThreadLocalStorage { public: using Key = void**; void Init() noexcept { map_ = konanConstructInstance(); } void Deinit() noexcept { RuntimeAssert(map_->size() == 0, "Must be already cleared"); konanDestructInstance(map_); } void Add(Key key, int size) noexcept { RuntimeAssert(storage_ == nullptr, "Storage must not be committed"); auto it = map_->find(key); if (it != map_->end()) { RuntimeAssert(it->second.size == size, "Attempt to add TLS record with the same key and different size"); return; } map_->emplace(key, Entry{size_, size}); size_ += size; } void Commit() noexcept { RuntimeAssert(storage_ == nullptr, "Cannot commit storage twice"); storage_ = reinterpret_cast(konanAllocMemory(size_ * sizeof(KRef))); } void Clear() noexcept { RuntimeAssert(storage_ != nullptr, "Storage must be committed"); for (int i = 0; i < size_; ++i) { UpdateHeapRef(storage_ + i, nullptr); } konanFreeMemory(storage_); map_->clear(); } KRef* Lookup(Key key, int index) noexcept { RuntimeAssert(storage_ != nullptr, "Storage must be committed"); // In many cases there is only one module, so this is one element cache. if (lastKey_ == key) { return storage_ + lastOffset_ + index; } auto it = map_->find(key); RuntimeAssert(it != map_->end(), "Must be there"); auto entry = it->second; RuntimeAssert(index < entry.size, "Out of bounds in TLS access"); lastKey_ = key; lastOffset_ = entry.offset; return storage_ + entry.offset + index; } private: struct Entry { int offset; int size; }; using Map = KStdUnorderedMap; Map* map_ = nullptr; KRef* storage_ = nullptr; int size_ = 0; int lastOffset_ = 0; Key lastKey_ = nullptr; }; } // namespace struct MemoryState { #if TRACE_MEMORY // Set of all containers. ContainerHeaderSet* containers; #endif ThreadLocalStorage tls; #if USE_GC // Finalizer queue - linked list of containers scheduled for finalization. ContainerHeader* finalizerQueue; int finalizerQueueSize; int finalizerQueueSuspendCount; /* * Typical scenario for GC is as following: * we have 90% of objects with refcount = 0 which will be deleted during * the first phase of the algorithm. * We could mark them with a bit in order to tell the next two phases to skip them * and thus requiring only one list, but the downside is that both of the * next phases would iterate over the whole list of objects instead of only 10%. */ ContainerHeaderList* toFree; // List of all cycle candidates. ContainerHeaderList* roots; // Real candidates excluding those with refcount = 0. // How many GC suspend requests happened. int gcSuspendCount; // How many candidate elements in toRelease shall trigger collection. size_t gcThreshold; // How many candidate elements in toFree shall trigger cycle collection. uint64_t gcCollectCyclesThreshold; // If collection is in progress. bool gcInProgress; // Objects to be released. ContainerHeaderList* toRelease; ForeignRefManager* foreignRefManager; bool gcErgonomics; uint64_t lastGcTimestamp; uint64_t lastCyclicGcTimestamp; uint32_t gcEpoque; uint64_t allocSinceLastGc; uint64_t allocSinceLastGcThreshold; #endif // USE_GC // A stack of initializing singletons. KStdVector> initializingSingletons; bool isMainThread = false; #if COLLECT_STATISTIC #define CONTAINER_ALLOC_STAT(state, size, container) state->statistic.incAlloc(size, container); #define CONTAINER_DESTROY_STAT(state, container) \ state->statistic.incFree(container); #define OBJECT_ALLOC_STAT(state, size, object) \ state->statistic.incAlloc(size, object); \ state->statistic.incAddRef(containerFor(object), 0, 0); #define UPDATE_REF_STAT(state, oldRef, newRef, slot, stack) \ state->statistic.incUpdateRef(oldRef, newRef, stack); #define UPDATE_ADDREF_STAT(state, obj, atomic, stack) \ state->statistic.incAddRef(obj, atomic, stack); #define UPDATE_RELEASEREF_STAT(state, obj, atomic, cyclic, stack) \ state->statistic.incReleaseRef(obj, atomic, cyclic, stack); #define INIT_STAT(state) \ state->statistic.init(); #define DEINIT_STAT(state) \ state->statistic.deinit(); #define PRINT_STAT(state) \ state->statistic.printStatistic(); MemoryStatistic statistic; #else #define CONTAINER_ALLOC_STAT(state, size, container) #define CONTAINER_DESTROY_STAT(state, container) #define OBJECT_ALLOC_STAT(state, size, object) #define UPDATE_REF_STAT(state, oldRef, newRef, slot, stack) #define UPDATE_ADDREF_STAT(state, obj, atomic, stack) #define UPDATE_RELEASEREF_STAT(state, obj, atomic, cyclic, stack) #define INIT_STAT(state) #define DEINIT_STAT(state) #define PRINT_STAT(state) #endif // COLLECT_STATISTIC }; namespace { #if TRACE_MEMORY #define INIT_TRACE(state) \ memoryState->containers = konanConstructInstance(); #define DEINIT_TRACE(state) \ konanDestructInstance(memoryState->containers); \ memoryState->containers = nullptr; #else #define INIT_TRACE(state) #define DEINIT_TRACE(state) #endif #define CONTAINER_ALLOC_TRACE(state, size, container) \ MEMORY_LOG("Container alloc %d at %p\n", size, container) #define CONTAINER_DESTROY_TRACE(state, container) \ MEMORY_LOG("Container destroy %p\n", container) #define OBJECT_ALLOC_TRACE(state, size, object) \ MEMORY_LOG("Object alloc %d at %p\n", size, object) #define UPDATE_REF_TRACE(state, oldRef, newRef, slot, stack) \ MEMORY_LOG("UpdateRef %s*%p: %p -> %p\n", stack ? "stack " : "heap ", slot, oldRef, newRef) // Events macro definitions. // Called on worker's memory init. #define INIT_EVENT(state) \ INIT_STAT(state) \ INIT_TRACE(state) // Called on worker's memory deinit. #define DEINIT_EVENT(state) \ DEINIT_STAT(state) // Called on container allocation. #define CONTAINER_ALLOC_EVENT(state, size, container) \ CONTAINER_ALLOC_STAT(state, size, container) \ CONTAINER_ALLOC_TRACE(state, size, container) // Called on container destroy (memory is released to allocator). #define CONTAINER_DESTROY_EVENT(state, container) \ CONTAINER_DESTROY_STAT(state, container) \ CONTAINER_DESTROY_TRACE(state, container) // Object was just allocated. #define OBJECT_ALLOC_EVENT(state, size, object) \ OBJECT_ALLOC_STAT(state, size, object) \ OBJECT_ALLOC_TRACE(state, size, object) // Object is freed. #define OBJECT_FREE_EVENT(state, size, object) \ OBJECT_FREE_STAT(state, size, object) \ OBJECT_FREE_TRACE(state, object) // Reference in memory is being updated. #define UPDATE_REF_EVENT(state, oldRef, newRef, slot, stack) \ UPDATE_REF_STAT(state, oldRef, newRef, slot, stack) \ UPDATE_REF_TRACE(state, oldRef, newRef, slot, stack) // Infomation shall be printed as worker is exiting. #define PRINT_EVENT(state) \ PRINT_STAT(state) // Forward declarations. void freeContainer(ContainerHeader* header) NO_INLINE; #if USE_GC void garbageCollect(MemoryState* state, bool force) NO_INLINE; void rememberNewContainer(ContainerHeader* container); #endif // USE_GC // Class representing arbitrary placement container. class Container { public: ContainerHeader* header() const { return header_; } protected: // Data where everything is being stored. ContainerHeader* header_; void SetHeader(ObjHeader* obj, const TypeInfo* type_info) { obj->typeInfoOrMeta_ = const_cast(type_info); // Take into account typeInfo's immutability for ARC strategy. if ((type_info->flags_ & TF_IMMUTABLE) != 0) header_->refCount_ |= CONTAINER_TAG_FROZEN; if ((type_info->flags_ & TF_ACYCLIC) != 0) header_->setColorEvenIfGreen(CONTAINER_TAG_GC_GREEN); } }; // Container for a single object. class ObjectContainer : public Container { public: // Single instance. explicit ObjectContainer(MemoryState* state, const TypeInfo* type_info) { Init(state, type_info); } // Object container shalln't have any dtor, as it's being freed by // ::Release(). ObjHeader* GetPlace() const { return reinterpret_cast(header_ + 1); } private: void Init(MemoryState* state, const TypeInfo* type_info); }; class ArrayContainer : public Container { public: ArrayContainer(MemoryState* state, const TypeInfo* type_info, uint32_t elements) { Init(state, type_info, elements); } // Array container shalln't have any dtor, as it's being freed by ::Release(). ArrayHeader* GetPlace() const { return reinterpret_cast(header_ + 1); } private: void Init(MemoryState* state, const TypeInfo* type_info, uint32_t elements); }; // Class representing arena-style placement container. // Container is used for reference counting, and it is assumed that objects // with related placement will share container. Only // whole container can be freed, individual objects are not taken into account. class ArenaContainer; struct ContainerChunk { ContainerChunk* next; ArenaContainer* arena; // Then we have ContainerHeader here. ContainerHeader* asHeader() { return reinterpret_cast(this + 1); } }; class ArenaContainer { public: void Init(); void Deinit(); // Place individual object in this container. ObjHeader* PlaceObject(const TypeInfo* type_info); // Places an array of certain type in this container. Note that array_type_info // is type info for an array, not for an individual element. Also note that exactly // same operation could be used to place strings. ArrayHeader* PlaceArray(const TypeInfo* array_type_info, container_size_t count); ObjHeader** getSlot(); private: void* place(container_size_t size); bool allocContainer(container_size_t minSize); void setHeader(ObjHeader* obj, const TypeInfo* typeInfo) { obj->typeInfoOrMeta_ = const_cast(typeInfo); setContainerFor(obj, currentChunk_->asHeader()); // Here we do not take into account typeInfo's immutability for ARC strategy, as there's no ARC. } ContainerChunk* currentChunk_; uint8_t* current_; uint8_t* end_; ArrayHeader* slots_; uint32_t slotsCount_; }; constexpr int kFrameOverlaySlots = sizeof(FrameOverlay) / sizeof(ObjHeader**); inline bool isFreeable(const ContainerHeader* header) { return header != nullptr && header->tag() != CONTAINER_TAG_STACK; } inline bool isArena(const ContainerHeader* header) { return header != nullptr && header->stack(); } inline bool isAggregatingFrozenContainer(const ContainerHeader* header) { return header != nullptr && header->frozen() && header->objectCount() > 1; } inline bool isMarkedAsRemoved(ContainerHeader* container) { return (reinterpret_cast(container) & 1) != 0; } inline ContainerHeader* markAsRemoved(ContainerHeader* container) { return reinterpret_cast(reinterpret_cast(container) | 1); } inline ContainerHeader* clearRemoved(ContainerHeader* container) { return reinterpret_cast( reinterpret_cast(container) & ~static_cast(1)); } inline container_size_t alignUp(container_size_t size, int alignment) { return (size + alignment - 1) & ~(alignment - 1); } inline ContainerHeader* realShareableContainer(ContainerHeader* container) { RuntimeAssert(container->shareable(), "Only makes sense on shareable objects"); return containerFor(reinterpret_cast(container + 1)); } inline uint32_t arrayObjectSize(const TypeInfo* typeInfo, uint32_t count) { // Note: array body is aligned, but for size computation it is enough to align the sum. static_assert(kObjectAlignment % alignof(KLong) == 0, ""); static_assert(kObjectAlignment % alignof(KDouble) == 0, ""); return alignUp(sizeof(ArrayHeader) - typeInfo->instanceSize_ * count, kObjectAlignment); } inline uint32_t arrayObjectSize(const ArrayHeader* obj) { return arrayObjectSize(obj->type_info(), obj->count_); } // TODO: shall we do padding for alignment? inline container_size_t objectSize(const ObjHeader* obj) { const TypeInfo* type_info = obj->type_info(); container_size_t size = (type_info->instanceSize_ < 0 ? // An array. arrayObjectSize(obj->array()) : type_info->instanceSize_); return alignUp(size, kObjectAlignment); } template inline void traverseContainerObjects(ContainerHeader* container, func process) { RuntimeAssert(!isAggregatingFrozenContainer(container), "Must not be called on such containers"); ObjHeader* obj = reinterpret_cast(container + 1); for (uint32_t i = 0; i < container->objectCount(); ++i) { process(obj); obj = reinterpret_cast( reinterpret_cast(obj) + objectSize(obj)); } } template inline void traverseContainerObjectFields(ContainerHeader* container, func process) { traverseContainerObjects(container, [process](ObjHeader* obj) { kotlin::traverseObjectFields(obj, process); }); } template inline void traverseContainerReferredObjects(ContainerHeader* container, func process) { traverseContainerObjectFields(container, [process](ObjHeader** location) { ObjHeader* ref = *location; if (ref != nullptr) process(ref); }); } inline FrameOverlay* asFrameOverlay(ObjHeader** slot) { return reinterpret_cast(slot); } inline void lock(KInt* spinlock) { while (compareAndSwap(spinlock, 0, 1) != 0) {} } inline void unlock(KInt* spinlock) { RuntimeCheck(compareAndSwap(spinlock, 1, 0) == 1, "Must succeed"); } inline bool canFreeze(ContainerHeader* container) { if (IsStrictMemoryModel()) // In strict memory model we ignore permanent, frozen and shared object when recursively freezing. return container != nullptr && !container->shareable(); else // In relaxed memory model we ignore permanent and frozen object when recursively freezing. return container != nullptr && !container->frozen(); } inline bool isFreezableAtomic(ObjHeader* obj) { return obj->type_info() == theFreezableAtomicReferenceTypeInfo; } inline bool isFreezableAtomic(ContainerHeader* container) { RuntimeAssert(!isAggregatingFrozenContainer(container), "Must be single object"); ObjHeader* obj = reinterpret_cast(container + 1); return isFreezableAtomic(obj); } ContainerHeader* allocContainer(MemoryState* state, size_t size) { ContainerHeader* result = nullptr; #if USE_GC // We recycle elements of finalizer queue for new allocations, to avoid trashing memory manager. ContainerHeader* container = state != nullptr ? state->finalizerQueue : nullptr; ContainerHeader* previous = nullptr; while (container != nullptr) { // TODO: shall it be == instead? if (container->hasContainerSize() && container->containerSize() >= size && container->containerSize() <= size + 16) { MEMORY_LOG("recycle %p for request %d\n", container, size) result = container; if (previous == nullptr) state->finalizerQueue = container->nextLink(); else previous->setNextLink(container->nextLink()); state->finalizerQueueSize--; memset(container, 0, size); break; } previous = container; container = container->nextLink(); } #endif if (result == nullptr) { #if USE_GC if (state != nullptr) state->allocSinceLastGc += size; #endif result = konanConstructSizedInstance(alignUp(size, kObjectAlignment)); atomicAdd(&allocCount, 1); } if (state != nullptr) { CONTAINER_ALLOC_EVENT(state, size, result); #if TRACE_MEMORY state->containers->insert(result); #endif } return result; } ContainerHeader* allocAggregatingFrozenContainer(KStdVector& containers) { auto componentSize = containers.size(); auto* superContainer = allocContainer(memoryState, sizeof(ContainerHeader) + sizeof(void*) * componentSize); auto* place = reinterpret_cast(superContainer + 1); for (auto* container : containers) { *place++ = container; // Set link to the new container. auto* obj = reinterpret_cast(container + 1); setContainerFor(obj, superContainer); MEMORY_LOG("Set fictitious frozen container for %p: %p\n", obj, superContainer); } superContainer->setObjectCount(componentSize); superContainer->freeze(); return superContainer; } #if USE_GC void processFinalizerQueue(MemoryState* state) { // TODO: reuse elements of finalizer queue for new allocations. while (state->finalizerQueue != nullptr) { auto* container = state->finalizerQueue; state->finalizerQueue = container->nextLink(); state->finalizerQueueSize--; #if TRACE_MEMORY state->containers->erase(container); #endif CONTAINER_DESTROY_EVENT(state, container) konanFreeMemory(container); atomicAdd(&allocCount, -1); } RuntimeAssert(state->finalizerQueueSize == 0, "Queue must be empty here"); } bool hasExternalRefs(ContainerHeader* start, ContainerHeaderSet* visited) { ContainerHeaderDeque toVisit; toVisit.push_back(start); while (!toVisit.empty()) { auto* container = toVisit.front(); toVisit.pop_front(); visited->insert(container); if (container->refCount() > 0) { MEMORY_LOG("container %p with rc %d blocks transfer\n", container, container->refCount()) return true; } traverseContainerReferredObjects(container, [&toVisit, visited](ObjHeader* ref) { auto* child = containerFor(ref); if (!isShareable(child) && (visited->count(child) == 0)) { toVisit.push_front(child); } }); } return false; } #endif // USE_GC void scheduleDestroyContainer(MemoryState* state, ContainerHeader* container) { #if USE_GC RuntimeAssert(container != nullptr, "Cannot destroy null container"); container->setNextLink(state->finalizerQueue); state->finalizerQueue = container; state->finalizerQueueSize++; // We cannot clean finalizer queue while in GC. if (!state->gcInProgress && state->finalizerQueueSuspendCount == 0 && state->finalizerQueueSize >= kFinalizerQueueThreshold) { processFinalizerQueue(state); } #else konanFreeMemory(container); atomicAdd(&allocCount, -1); CONTAINER_DESTROY_EVENT(state, container); #endif } void freeAggregatingFrozenContainer(ContainerHeader* container) { auto* state = memoryState; RuntimeAssert(isAggregatingFrozenContainer(container), "expected fictitious frozen container"); MEMORY_LOG("%p is fictitious frozen container\n", container); RuntimeAssert(!container->buffered(), "frozen objects must not participate in GC"); #if USE_GC // Forbid finalizerQueue handling. ++state->finalizerQueueSuspendCount; #endif // Special container for frozen objects. ContainerHeader** subContainer = reinterpret_cast(container + 1); MEMORY_LOG("Total subcontainers = %d\n", container->objectCount()); for (uint32_t i = 0; i < container->objectCount(); ++i) { MEMORY_LOG("Freeing subcontainer %p\n", *subContainer); freeContainer(*subContainer++); } #if USE_GC --state->finalizerQueueSuspendCount; #endif scheduleDestroyContainer(state, container); MEMORY_LOG("Freeing subcontainers done\n"); } // This is called from 2 places where it's unconditionally called, // so better be inlined. ALWAYS_INLINE void runDeallocationHooks(ContainerHeader* container) { ObjHeader* obj = reinterpret_cast(container + 1); for (uint32_t index = 0; index < container->objectCount(); index++) { #if USE_CYCLIC_GC if ((type_info->flags_ & TF_LEAK_DETECTOR_CANDIDATE) != 0) { cyclicRemoveAtomicRoot(obj); } #endif // USE_CYCLIC_GC #if USE_CYCLE_DETECTOR CycleDetector::removeCandidateIfNeeded(obj); #endif // USE_CYCLE_DETECTOR kotlin::RunFinalizers(obj); obj = reinterpret_cast(reinterpret_cast(obj) + objectSize(obj)); } } void freeContainer(ContainerHeader* container) { RuntimeAssert(container != nullptr, "this kind of container shalln't be freed"); if (isAggregatingFrozenContainer(container)) { freeAggregatingFrozenContainer(container); return; } runDeallocationHooks(container); // Now let's clean all object's fields in this container. traverseContainerObjectFields(container, [](ObjHeader** location) { ZeroHeapRef(location); }); // And release underlying memory. if (isFreeable(container)) { container->setColorEvenIfGreen(CONTAINER_TAG_GC_BLACK); if (!container->buffered()) scheduleDestroyContainer(memoryState, container); } } /** * Do DFS cycle detection with three colors: * - 'marked' bit as BLACK marker (object and its descendants processed) * - 'seen' bit as GRAY marker (object is being processed) * - not 'marked' and not 'seen' as WHITE marker (object is unprocessed) * When we see GREY during DFS, it means we see cycle. */ void depthFirstTraversal(ContainerHeader* start, bool* hasCycles, KRef* firstBlocker, KStdVector* order) { ContainerHeaderDeque toVisit; toVisit.push_back(start); start->setSeen(); while (!toVisit.empty()) { auto* container = toVisit.front(); toVisit.pop_front(); if (isMarkedAsRemoved(container)) { container = clearRemoved(container); // Mark BLACK. container->resetSeen(); container->mark(); order->push_back(container); continue; } toVisit.push_front(markAsRemoved(container)); traverseContainerReferredObjects(container, [container, hasCycles, firstBlocker, &toVisit](ObjHeader* obj) { if (*firstBlocker != nullptr) return; if (obj->has_meta_object() && ((obj->meta_object()->flags_ & MF_NEVER_FROZEN) != 0)) { *firstBlocker = obj; return; } ContainerHeader* objContainer = containerFor(obj); if (canFreeze(objContainer)) { // Marked GREY, there's cycle. if (objContainer->seen()) *hasCycles = true; // Go deeper if WHITE. if (!objContainer->seen() && !objContainer->marked()) { // Mark GRAY. objContainer->setSeen(); // Here we do rather interesting trick: when doing DFS we postpone processing references going from // FreezableAtomic, so that in 'order' referred value will be seen as not actually belonging // to the same SCC (unless there are other edges not going through FreezableAtomic reaching the same value). if (isFreezableAtomic(container)) { toVisit.push_back(objContainer); } else { toVisit.push_front(objContainer); } } } }); } } void traverseStronglyConnectedComponent(ContainerHeader* start, KStdUnorderedMap> const* reversedEdges, KStdVector* component) { ContainerHeaderDeque toVisit; toVisit.push_back(start); start->mark(); while (!toVisit.empty()) { auto* container = toVisit.front(); toVisit.pop_front(); component->push_back(container); auto it = reversedEdges->find(container); RuntimeAssert(it != reversedEdges->end(), "unknown node during condensation building"); for (auto* nextContainer : it->second) { if (!nextContainer->marked()) { nextContainer->mark(); toVisit.push_front(nextContainer); } } } } template inline bool tryIncrementRC(ContainerHeader* container) { return container->tryIncRefCount(); } #if !USE_GC template inline void incrementRC(ContainerHeader* container) { container->incRefCount(); } template inline void decrementRC(ContainerHeader* container) { if (container->decRefCount() == 0) { freeContainer(container); } } inline void decrementRC(ContainerHeader* container) { if (isShareable(container)) decrementRC(container); else decrementRC(container); } template inline void enqueueDecrementRC(ContainerHeader* container) { RuntimeCheck(false, "Not yet implemeneted"); } #else // USE_GC template inline void incrementRC(ContainerHeader* container) { container->incRefCount(); } template inline void decrementRC(ContainerHeader* container) { // TODO: enable me, once account for inner references in frozen objects correctly. // RuntimeAssert(container->refCount() > 0, "Must be positive"); if (container->decRefCount() == 0) { freeContainer(container); } else if (UseCycleCollector) { // Possible root. RuntimeAssert(container->refCount() > 0, "Must be positive"); RuntimeAssert(!Atomic && !container->shareable(), "Cycle collector shalln't be used with shared objects yet"); RuntimeAssert(container->objectCount() == 1, "cycle collector shall only work with single object containers"); // We do not use cycle collector for frozen objects, as we already detected // possible cycles during freezing. // Also do not use cycle collector for provable acyclic objects. int color = container->color(); if (color != CONTAINER_TAG_GC_PURPLE && color != CONTAINER_TAG_GC_GREEN) { container->setColorAssertIfGreen(CONTAINER_TAG_GC_PURPLE); if (!container->buffered()) { auto* state = memoryState; container->setBuffered(); if (state->toFree != nullptr) { state->toFree->push_back(container); MEMORY_LOG("toFree is now %lu\n", state->toFree->size()) if (state->gcSuspendCount == 0 && state->toRelease->size() >= state->gcThreshold) { GC_LOG("Calling GC from DecrementRC: %d\n", state->toRelease->size()) garbageCollect(state, false); } } } } } } inline void decrementRC(ContainerHeader* container) { auto* state = memoryState; RuntimeAssert(!IsStrictMemoryModel() || state->gcInProgress, "Must only be called during GC"); // TODO: enable me, once account for inner references in frozen objects correctly. // RuntimeAssert(container->refCount() > 0, "Must be positive"); bool useCycleCollector = container->local(); if (container->decRefCount() == 0) { freeContainer(container); } else if (useCycleCollector && state->toFree != nullptr) { RuntimeAssert(IsStrictMemoryModel(), "No cycle collector in relaxed mode yet"); RuntimeAssert(container->refCount() > 0, "Must be positive"); RuntimeAssert(!container->shareable(), "Cycle collector shalln't be used with shared objects yet"); RuntimeAssert(container->objectCount() == 1, "cycle collector shall only work with single object containers"); // We do not use cycle collector for frozen objects, as we already detected // possible cycles during freezing. // Also do not use cycle collector for provable acyclic objects. int color = container->color(); if (color != CONTAINER_TAG_GC_PURPLE && color != CONTAINER_TAG_GC_GREEN) { container->setColorAssertIfGreen(CONTAINER_TAG_GC_PURPLE); if (!container->buffered()) { container->setBuffered(); state->toFree->push_back(container); } } } } template inline void enqueueDecrementRC(ContainerHeader* container) { auto* state = memoryState; if (CanCollect) { if (state->toRelease->size() >= state->gcThreshold && state->gcSuspendCount == 0) { GC_LOG("Calling GC from EnqueueDecrementRC: %zu\n", state->toRelease->size()) garbageCollect(state, false); } } state->toRelease->push_back(container); } inline void initGcThreshold(MemoryState* state, uint32_t gcThreshold) { state->gcThreshold = gcThreshold; state->toRelease->reserve(gcThreshold); } inline void initGcCollectCyclesThreshold(MemoryState* state, uint64_t gcCollectCyclesThreshold) { state->gcCollectCyclesThreshold = gcCollectCyclesThreshold; state->toFree->reserve(gcCollectCyclesThreshold); } inline void increaseGcThreshold(MemoryState* state) { auto newThreshold = state->gcThreshold * 3 / 2 + 1; if (newThreshold <= kMaxErgonomicThreshold) { initGcThreshold(state, newThreshold); } } inline void increaseGcCollectCyclesThreshold(MemoryState* state) { auto newThreshold = state->gcCollectCyclesThreshold * 2; if (newThreshold <= kMaxErgonomicToFreeSizeThreshold) { initGcCollectCyclesThreshold(state, newThreshold); } } #endif // USE_GC #if TRACE_MEMORY && USE_GC const char* colorNames[] = {"BLACK", "GRAY", "WHITE", "PURPLE", "GREEN", "ORANGE", "RED"}; void dumpObject(ObjHeader* ref, int indent) { for (int i = 0; i < indent; i++) MEMORY_LOG(" "); auto* typeInfo = ref->type_info(); auto* packageName = typeInfo->packageName_ != nullptr ? CreateCStringFromString(typeInfo->packageName_) : nullptr; auto* relativeName = typeInfo->relativeName_ != nullptr ? CreateCStringFromString(typeInfo->relativeName_) : nullptr; MEMORY_LOG("%p %s.%s\n", ref, packageName ? packageName : "", relativeName ? relativeName : ""); if (packageName) konan::free(packageName); if (relativeName) konan::free(relativeName); } void dumpContainerContent(ContainerHeader* container) { if (container->refCount() < 0) { MEMORY_LOG("%p has negative RC %d, likely a memory bug\n", container, container->refCount()) return; } if (isAggregatingFrozenContainer(container)) { MEMORY_LOG("%s aggregating container %p with %d objects rc=%d\n", colorNames[container->color()], container, container->objectCount(), container->refCount()); ContainerHeader** subContainer = reinterpret_cast(container + 1); for (int i = 0; i < container->objectCount(); ++i) { ContainerHeader* sub = *subContainer++; MEMORY_LOG(" container %p\n ", sub); dumpContainerContent(sub); } } else { MEMORY_LOG("%s regular %s%scontainer %p with %d objects rc=%d\n", colorNames[container->color()], container->frozen() ? "frozen " : "", container->stack() ? "stack " : "", container, container->objectCount(), container->refCount()); ObjHeader* obj = reinterpret_cast(container + 1); dumpObject(obj, 4); } } void dumpWorker(const char* prefix, ContainerHeader* header, ContainerHeaderSet* seen) { dumpContainerContent(header); seen->insert(header); if (!isAggregatingFrozenContainer(header)) { traverseContainerReferredObjects(header, [prefix, seen](ObjHeader* ref) { auto* child = containerFor(ref); RuntimeAssert(!isArena(child), "A reference to local object is encountered"); if (child != nullptr && (seen->count(child) == 0)) { dumpWorker(prefix, child, seen); } }); } } void dumpReachable(const char* prefix, const ContainerHeaderSet* roots) { ContainerHeaderSet seen; for (auto* container : *roots) { dumpWorker(prefix, container, &seen); } } #endif #if USE_GC void markRoots(MemoryState*); void scanRoots(MemoryState*); void collectRoots(MemoryState*); void scan(ContainerHeader* container); template void markGray(ContainerHeader* start) { ContainerHeaderDeque toVisit; toVisit.push_front(start); while (!toVisit.empty()) { auto* container = toVisit.front(); MEMORY_LOG("MarkGray visit %p [%s]\n", container, colorNames[container->color()]); toVisit.pop_front(); if (useColor) { int color = container->color(); if (color == CONTAINER_TAG_GC_GRAY) continue; // If see an acyclic object not being garbage - ignore it. We must properly traverse garbage, although. if (color == CONTAINER_TAG_GC_GREEN && container->refCount() != 0) { continue; } // Only garbage green object could be recolored here. container->setColorEvenIfGreen(CONTAINER_TAG_GC_GRAY); } else { if (container->marked()) continue; container->mark(); } traverseContainerReferredObjects(container, [&toVisit](ObjHeader* ref) { auto* childContainer = containerFor(ref); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); if (!isShareable(childContainer)) { childContainer->decRefCount(); toVisit.push_front(childContainer); } }); } } template void scanBlack(ContainerHeader* start) { ContainerHeaderDeque toVisit; toVisit.push_front(start); while (!toVisit.empty()) { auto* container = toVisit.front(); MEMORY_LOG("ScanBlack visit %p [%s]\n", container, colorNames[container->color()]); toVisit.pop_front(); if (useColor) { auto color = container->color(); if (color == CONTAINER_TAG_GC_GREEN || color == CONTAINER_TAG_GC_BLACK) continue; container->setColorAssertIfGreen(CONTAINER_TAG_GC_BLACK); } else { if (!container->marked()) continue; container->unMark(); } traverseContainerReferredObjects(container, [&toVisit](ObjHeader* ref) { auto childContainer = containerFor(ref); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); if (!isShareable(childContainer)) { childContainer->incRefCount(); if (useColor) { int color = childContainer->color(); if (color != CONTAINER_TAG_GC_BLACK) toVisit.push_front(childContainer); } else { if (childContainer->marked()) toVisit.push_front(childContainer); } } }); } } void collectWhite(MemoryState*, ContainerHeader* container); void collectCycles(MemoryState* state) { markRoots(state); scanRoots(state); collectRoots(state); state->toFree->clear(); state->roots->clear(); } void markRoots(MemoryState* state) { for (auto container : *(state->toFree)) { if (isMarkedAsRemoved(container)) continue; // Acyclic containers cannot be in this list. RuntimeCheck(container->color() != CONTAINER_TAG_GC_GREEN, "Must not be green"); auto color = container->color(); auto rcIsZero = container->refCount() == 0; if (color == CONTAINER_TAG_GC_PURPLE && !rcIsZero) { markGray(container); state->roots->push_back(container); } else { container->resetBuffered(); RuntimeAssert(color != CONTAINER_TAG_GC_GREEN, "Must not be green"); if (color == CONTAINER_TAG_GC_BLACK && rcIsZero) { scheduleDestroyContainer(state, container); } } } } void scanRoots(MemoryState* state) { for (auto* container : *(state->roots)) { scan(container); } } void collectRoots(MemoryState* state) { // Here we might free some objects and call deallocation hooks on them, // which in turn might call DecrementRC and trigger new GC - forbid that. state->gcSuspendCount++; for (auto* container : *(state->roots)) { container->resetBuffered(); collectWhite(state, container); } state->gcSuspendCount--; } void scan(ContainerHeader* start) { ContainerHeaderDeque toVisit; toVisit.push_front(start); while (!toVisit.empty()) { auto* container = toVisit.front(); toVisit.pop_front(); if (container->color() != CONTAINER_TAG_GC_GRAY) continue; if (container->refCount() != 0) { scanBlack(container); continue; } container->setColorAssertIfGreen(CONTAINER_TAG_GC_WHITE); traverseContainerReferredObjects(container, [&toVisit](ObjHeader* ref) { auto* childContainer = containerFor(ref); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); if (!isShareable(childContainer)) { toVisit.push_front(childContainer); } }); } } void collectWhite(MemoryState* state, ContainerHeader* start) { ContainerHeaderDeque toVisit; toVisit.push_back(start); while (!toVisit.empty()) { auto* container = toVisit.front(); toVisit.pop_front(); if (container->color() != CONTAINER_TAG_GC_WHITE || container->buffered()) continue; container->setColorAssertIfGreen(CONTAINER_TAG_GC_BLACK); traverseContainerObjectFields(container, [&toVisit](ObjHeader** location) { auto* ref = *location; if (ref == nullptr) return; auto* childContainer = containerFor(ref); RuntimeAssert(!isArena(childContainer), "A reference to local object is encountered"); if (isShareable(childContainer)) { ZeroHeapRef(location); } else { toVisit.push_front(childContainer); } }); runDeallocationHooks(container); scheduleDestroyContainer(state, container); } } #endif #if COLLECT_STATISTIC inline bool needAtomicAccess(ContainerHeader* container) { return container->shareable(); } inline bool canBeCyclic(ContainerHeader* container) { if (container->refCount() == 1) return false; if (container->color() == CONTAINER_TAG_GC_GREEN) return false; return true; } #endif inline void addHeapRef(ContainerHeader* container) { MEMORY_LOG("AddHeapRef %p: rc=%d\n", container, container->refCount()) UPDATE_ADDREF_STAT(memoryState, container, needAtomicAccess(container), 0) switch (container->tag()) { case CONTAINER_TAG_STACK: break; case CONTAINER_TAG_LOCAL: RuntimeAssert(container->refCount() > 0, "add ref for reclaimed object"); incrementRC(container); break; /* case CONTAINER_TAG_FROZEN: case CONTAINER_TAG_SHARED: */ default: RuntimeAssert(container->refCount() > 0, "add ref for reclaimed object"); incrementRC(container); break; } } inline void addHeapRef(const ObjHeader* header) { auto* container = containerFor(header); if (container != nullptr) addHeapRef(const_cast(container)); } inline bool tryAddHeapRef(ContainerHeader* container) { switch (container->tag()) { case CONTAINER_TAG_STACK: break; case CONTAINER_TAG_LOCAL: if (!tryIncrementRC(container)) return false; break; /* case CONTAINER_TAG_FROZEN: case CONTAINER_TAG_SHARED: */ default: if (!tryIncrementRC(container)) return false; break; } MEMORY_LOG("AddHeapRef %p: rc=%d\n", container, container->refCount() - 1) UPDATE_ADDREF_STAT(memoryState, container, needAtomicAccess(container), 0) return true; } inline bool tryAddHeapRef(const ObjHeader* header) { auto* container = containerFor(header); return (container != nullptr) ? tryAddHeapRef(container) : true; } template inline void releaseHeapRef(ContainerHeader* container) { MEMORY_LOG("ReleaseHeapRef %p: rc=%d\n", container, container->refCount()) UPDATE_RELEASEREF_STAT(memoryState, container, needAtomicAccess(container), canBeCyclic(container), 0) if (container->tag() != CONTAINER_TAG_STACK) { if (Strict) enqueueDecrementRC(container); else decrementRC(container); } } template inline void releaseHeapRef(const ObjHeader* header) { auto* container = containerFor(header); if (container != nullptr) releaseHeapRef(const_cast(container)); } // TODO: Consider removing this unused stuff. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-function" // We use first slot as place to store frame-local arena container. // TODO: create ArenaContainer object on the stack, so that we don't // do two allocations per frame (ArenaContainer + actual container). inline ArenaContainer* initedArena(ObjHeader** auxSlot) { auto frame = asFrameOverlay(auxSlot); auto arena = reinterpret_cast(frame->arena); if (!arena) { arena = konanConstructInstance(); MEMORY_LOG("Initializing arena in %p\n", frame) arena->Init(); frame->arena = arena; } return arena; } inline size_t containerSize(const ContainerHeader* container) { size_t result = 0; const ObjHeader* obj = reinterpret_cast(container + 1); for (uint32_t object = 0; object < container->objectCount(); object++) { size_t size = objectSize(obj); result += size; obj = reinterpret_cast(reinterpret_cast(obj) + size); } return result; } #pragma clang diagnostic pop #if USE_GC void incrementStack(MemoryState* state) { FrameOverlay* frame = currentFrame; while (frame != nullptr) { ObjHeader** current = reinterpret_cast(frame + 1) + frame->parameters; ObjHeader** end = current + frame->count - kFrameOverlaySlots - frame->parameters; while (current < end) { ObjHeader* obj = *current++; if (obj != nullptr) { auto* container = containerFor(obj); if (container == nullptr) continue; if (container->shareable()) { incrementRC(container); } else { incrementRC(container); } } } frame = frame->previous; } } void processDecrements(MemoryState* state) { RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now"); auto* toRelease = state->toRelease; state->gcSuspendCount++; while (toRelease->size() > 0) { auto* container = toRelease->back(); toRelease->pop_back(); if (isMarkedAsRemoved(container)) continue; if (container->shareable()) container = realShareableContainer(container); decrementRC(container); } state->foreignRefManager->processEnqueuedReleaseRefsWith([](ObjHeader* obj) { ContainerHeader* container = containerFor(obj); if (container != nullptr) decrementRC(container); }); state->gcSuspendCount--; } void decrementStack(MemoryState* state) { RuntimeAssert(IsStrictMemoryModel(), "Only works in strict model now"); state->gcSuspendCount++; FrameOverlay* frame = currentFrame; while (frame != nullptr) { ObjHeader** current = reinterpret_cast(frame + 1) + frame->parameters; ObjHeader** end = current + frame->count - kFrameOverlaySlots - frame->parameters; while (current < end) { ObjHeader* obj = *current++; if (obj != nullptr) { MEMORY_LOG("decrement stack %p\n", obj) auto* container = containerFor(obj); if (container != nullptr) enqueueDecrementRC(container); } } frame = frame->previous; } state->gcSuspendCount--; } void garbageCollect(MemoryState* state, bool force) { RuntimeAssert(!state->gcInProgress, "Recursive GC is disallowed"); #if TRACE_GC uint64_t allocSinceLastGc = state->allocSinceLastGc; #endif // TRACE_GC state->allocSinceLastGc = 0; if (!IsStrictMemoryModel()) { // In relaxed model we just process finalizer queue and be done with it. processFinalizerQueue(state); return; } GC_LOG(">>> %s GC: threshold = %zu toFree %zu toRelease %zu alloc = %lld\n", \ force ? "forced" : "regular", state->gcThreshold, state->toFree->size(), state->toRelease->size(), allocSinceLastGc) auto gcStartTime = konan::getTimeMicros(); state->gcInProgress = true; state->gcEpoque++; incrementStack(state); #if USE_CYCLIC_GC // Block if the concurrent cycle collector is running. // We must do that to ensure collector sees state where actual RC properly upper estimated. if (g_hasCyclicCollector) cyclicLocalGC(); #endif // USE_CYCLIC_GC #if PROFILE_GC auto processDecrementsStartTime = konan::getTimeMicros(); #endif processDecrements(state); #if PROFILE_GC auto processDecrementsDuration = konan::getTimeMicros() - processDecrementsStartTime; GC_LOG("||| GC: processDecrementsDuration = %lld\n", processDecrementsDuration); auto decrementStackStartTime = konan::getTimeMicros(); #endif size_t beforeDecrements = state->toRelease->size(); decrementStack(state); size_t afterDecrements = state->toRelease->size(); #if PROFILE_GC auto decrementStackDuration = konan::getTimeMicros() - decrementStackStartTime; GC_LOG("||| GC: decrementStackDuration = %lld\n", decrementStackDuration); #endif RuntimeAssert(afterDecrements >= beforeDecrements, "toRelease size must not have decreased"); size_t stackReferences = afterDecrements - beforeDecrements; if (state->gcErgonomics && stackReferences * 5 > state->gcThreshold) { increaseGcThreshold(state); GC_LOG("||| GC: too many stack references, increased threshold to %zu\n", state->gcThreshold); } GC_LOG("||| GC: toFree %zu toRelease %zu\n", state->toFree->size(), state->toRelease->size()) #if PROFILE_GC auto processFinalizerQueueStartTime = konan::getTimeMicros(); #endif processFinalizerQueue(state); #if PROFILE_GC auto processFinalizerQueueDuration = konan::getTimeMicros() - processFinalizerQueueStartTime; GC_LOG("||| GC: processFinalizerQueueDuration %lld\n", processFinalizerQueueDuration); #endif if (force || state->toFree->size() > state->gcCollectCyclesThreshold) { auto cyclicGcStartTime = konan::getTimeMicros(); while (state->toFree->size() > 0) { collectCycles(state); #if PROFILE_GC processFinalizerQueueStartTime = konan::getTimeMicros(); #endif processFinalizerQueue(state); #if PROFILE_GC processFinalizerQueueDuration += konan::getTimeMicros() - processFinalizerQueueStartTime; GC_LOG("||| GC: processFinalizerQueueDuration = %lld\n", processFinalizerQueueDuration); #endif } auto cyclicGcEndTime = konan::getTimeMicros(); #if PROFILE_GC GC_LOG("||| GC: collectCyclesDuration = %lld\n", cyclicGcEndTime - cyclicGcStartTime); #endif auto cyclicGcDuration = cyclicGcEndTime - cyclicGcStartTime; if (!force && state->gcErgonomics && cyclicGcDuration > kGcCollectCyclesMinimumDuration && double(cyclicGcDuration) / (cyclicGcStartTime - state->lastCyclicGcTimestamp + 1) > kGcCollectCyclesLoadRatio) { increaseGcCollectCyclesThreshold(state); GC_LOG("Adjusting GC collecting cycles threshold to %lld\n", state->gcCollectCyclesThreshold); } state->lastCyclicGcTimestamp = cyclicGcEndTime; } state->gcInProgress = false; auto gcEndTime = konan::getTimeMicros(); if (state->gcErgonomics) { auto gcToComputeRatio = double(gcEndTime - gcStartTime) / (gcStartTime - state->lastGcTimestamp + 1); if (!force && gcToComputeRatio > kGcToComputeRatioThreshold) { increaseGcThreshold(state); GC_LOG("Adjusting GC threshold to %zu\n", state->gcThreshold); } } GC_LOG("GC: gcToComputeRatio=%f duration=%lld sinceLast=%lld\n", double(gcEndTime - gcStartTime) / (gcStartTime - state->lastGcTimestamp + 1), (gcEndTime - gcStartTime), gcStartTime - state->lastGcTimestamp); state->lastGcTimestamp = gcEndTime; #if TRACE_MEMORY for (auto* obj: *state->toRelease) { MEMORY_LOG("toRelease %p\n", obj) } #endif GC_LOG("<<< GC: toFree %zu toRelease %zu\n", state->toFree->size(), state->toRelease->size()) } void rememberNewContainer(ContainerHeader* container) { if (container == nullptr) return; // Instances can be allocated before actual runtime init - be prepared for that. if (memoryState != nullptr) { incrementRC(container); // We cannot collect until reference will be stored into the stack slot. enqueueDecrementRC(container); } } void garbageCollect() { garbageCollect(memoryState, true); } #endif // USE_GC ForeignRefManager* initLocalForeignRef(ObjHeader* object) { if (!IsStrictMemoryModel()) return nullptr; return memoryState->foreignRefManager; } ForeignRefManager* initForeignRef(ObjHeader* object) { addHeapRef(object); if (!IsStrictMemoryModel()) return nullptr; // Note: it is possible to return nullptr for shared object as an optimization, // but this will force the implementation to release objects on uninitialized threads // which is generally a memory leak. See [deinitForeignRef]. auto* manager = memoryState->foreignRefManager; manager->addRef(); return manager; } bool isForeignRefAccessible(ObjHeader* object, ForeignRefManager* manager) { if (!IsStrictMemoryModel()) return true; if (manager == memoryState->foreignRefManager) { // Note: it is important that this code neither crashes nor returns false-negative result // (although may produce false-positive one) if [manager] is a dangling pointer. // See BackRefFromAssociatedObject::releaseRef for more details. return true; } // Note: getting container and checking it with 'isShareable()' is supposed to be correct even for unowned object. return isShareable(containerFor(object)); } void deinitForeignRef(ObjHeader* object, ForeignRefManager* manager) { if (IsStrictMemoryModel()) { if (memoryState != nullptr && isForeignRefAccessible(object, manager)) { releaseHeapRef(object); } else { // Prefer this for (memoryState == nullptr) since otherwise the object may leak: // an uninitialized thread did not run any Kotlin code; // it may be an externally-managed thread which is not supposed to run Kotlin code // and not going to exit soon. manager->enqueueReleaseRef(object); } manager->releaseRef(); } else { releaseHeapRef(object); RuntimeAssert(manager == nullptr, "must be null"); } } MemoryState* initMemory(bool firstRuntime) { RuntimeAssert(offsetof(ArrayHeader, typeInfoOrMeta_) == offsetof(ObjHeader, typeInfoOrMeta_), "Layout mismatch"); RuntimeAssert(offsetof(TypeInfo, typeInfo_) == offsetof(MetaObjHeader, typeInfo_), "Layout mismatch"); RuntimeAssert(sizeof(FrameOverlay) % sizeof(ObjHeader**) == 0, "Frame overlay should contain only pointers"); RuntimeAssert(memoryState == nullptr, "memory state must be clear"); memoryState = konanConstructInstance(); INIT_EVENT(memoryState) #if USE_GC memoryState->toFree = konanConstructInstance(); memoryState->roots = konanConstructInstance(); memoryState->gcInProgress = false; memoryState->gcSuspendCount = 0; memoryState->toRelease = konanConstructInstance(); initGcThreshold(memoryState, kGcThreshold); initGcCollectCyclesThreshold(memoryState, kMaxToFreeSizeThreshold); memoryState->allocSinceLastGcThreshold = kMaxGcAllocThreshold; memoryState->gcErgonomics = true; #endif memoryState->tls.Init(); memoryState->foreignRefManager = ForeignRefManager::create(); bool firstMemoryState = atomicAdd(&aliveMemoryStatesCount, 1) == 1; switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: firstRuntime = firstMemoryState; break; case DESTROY_RUNTIME_ON_SHUTDOWN: // Nothing to do. break; } if (firstRuntime) { #if USE_CYCLIC_GC cyclicInit(); #endif // USE_CYCLIC_GC memoryState->isMainThread = true; } return memoryState; } void deinitMemory(MemoryState* memoryState, bool destroyRuntime) { static int pendingDeinit = 0; atomicAdd(&pendingDeinit, 1); #if USE_GC bool lastMemoryState = atomicAdd(&aliveMemoryStatesCount, -1) == 0; switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: destroyRuntime = lastMemoryState; break; case DESTROY_RUNTIME_ON_SHUTDOWN: // Nothing to do break; } bool checkLeaks = Kotlin_memoryLeakCheckerEnabled() && destroyRuntime; if (destroyRuntime) { garbageCollect(memoryState, true); #if USE_CYCLIC_GC // If there are other pending deinits (rare situation) - just skip the leak checker. // This may happen when there're several threads with Kotlin runtimes created // by foreign code, and that code stops those threads simultaneously. if (atomicGet(&pendingDeinit) > 1) { checkLeaks = false; } cyclicDeinit(g_hasCyclicCollector); #endif // USE_CYCLIC_GC } // Actual GC only implemented in strict memory model at the moment. do { GC_LOG("Calling garbageCollect from DeinitMemory()\n") garbageCollect(memoryState, true); } while (memoryState->toRelease->size() > 0 || !memoryState->foreignRefManager->tryReleaseRefOwned()); RuntimeAssert(memoryState->toFree->size() == 0, "Some memory have not been released after GC"); RuntimeAssert(memoryState->toRelease->size() == 0, "Some memory have not been released after GC"); konanDestructInstance(memoryState->toFree); konanDestructInstance(memoryState->roots); konanDestructInstance(memoryState->toRelease); memoryState->tls.Deinit(); RuntimeAssert(memoryState->finalizerQueue == nullptr, "Finalizer queue must be empty"); RuntimeAssert(memoryState->finalizerQueueSize == 0, "Finalizer queue must be empty"); #endif // USE_GC atomicAdd(&pendingDeinit, -1); #if TRACE_MEMORY if (IsStrictMemoryModel() && destroyRuntime && allocCount > 0) { MEMORY_LOG("*** Memory leaks, leaked %d containers ***\n", allocCount); dumpReachable("", memoryState->containers); } #else #if USE_GC if (IsStrictMemoryModel() && allocCount > 0 && checkLeaks) { konan::consoleErrorf( "Memory leaks detected, %d objects leaked!\n" "Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", allocCount); konan::consoleFlush(); konan::abort(); } #endif // USE_GC #endif // TRACE_MEMORY PRINT_EVENT(memoryState) DEINIT_EVENT(memoryState) konanFreeMemory(memoryState); ::memoryState = nullptr; } void makeShareable(ContainerHeader* container) { if (!container->frozen()) container->makeShared(); } template void setStackRef(ObjHeader** location, const ObjHeader* object) { MEMORY_LOG("SetStackRef *%p: %p\n", location, object) UPDATE_REF_EVENT(memoryState, nullptr, object, location, 1); if (!Strict && object != nullptr) addHeapRef(object); *const_cast(location) = object; } template void setHeapRef(ObjHeader** location, const ObjHeader* object) { MEMORY_LOG("SetHeapRef *%p: %p\n", location, object) UPDATE_REF_EVENT(memoryState, nullptr, object, location, 0); if (object != nullptr) addHeapRef(const_cast(object)); *const_cast(location) = object; } void zeroHeapRef(ObjHeader** location) { MEMORY_LOG("ZeroHeapRef %p\n", location) auto* value = *location; if (reinterpret_cast(value) > 1) { UPDATE_REF_EVENT(memoryState, value, nullptr, location, 0); *location = nullptr; ReleaseHeapRef(value); } } template void zeroStackRef(ObjHeader** location) { MEMORY_LOG("ZeroStackRef %p\n", location) if (Strict) { *location = nullptr; } else { auto* old = *location; *location = nullptr; if (old != nullptr) releaseHeapRef(old); } } template void updateHeapRef(ObjHeader** location, const ObjHeader* object) { UPDATE_REF_EVENT(memoryState, *location, object, location, 0); ObjHeader* old = *location; if (old != object) { if (object != nullptr) { addHeapRef(object); } *const_cast(location) = object; if (reinterpret_cast(old) > 1) { releaseHeapRef(old); } } } template void updateHeapRefsInsideOneArray(const ArrayHeader* array, int fromIndex, int toIndex, int count) { // In case of coping inside same array number of decrements and increments of RC can be decreased. auto countIndex = [=](int i) { return (fromIndex < toIndex) ? count - 1 - i : i; }; int rewrittenElementsNumber = std::abs(fromIndex - toIndex); // Release rewritten elements. for (int i = 0; i < rewrittenElementsNumber; i++) { int index = countIndex(i); ObjHeader* old = *ArrayAddressOfElementAt(array, toIndex + index); *const_cast(ArrayAddressOfElementAt(array, toIndex + index)) = *ArrayAddressOfElementAt(array, fromIndex + index); if (old != nullptr) { releaseHeapRef(old); } } for (int i = rewrittenElementsNumber; i < count - rewrittenElementsNumber; i++) { int index = countIndex(i); *const_cast(ArrayAddressOfElementAt(array, toIndex + index)) = *ArrayAddressOfElementAt(array, fromIndex + index); } for (int i = count - rewrittenElementsNumber; i < count; i++) { int index = countIndex(i); ObjHeader* object = *ArrayAddressOfElementAt(array, fromIndex + index); // Add extra heap ref for copied elements. if (object != nullptr) { addHeapRef(object); } *const_cast(ArrayAddressOfElementAt(array, toIndex + index)) = object; } } template void updateStackRef(ObjHeader** location, const ObjHeader* object) { UPDATE_REF_EVENT(memoryState, *location, object, location, 1) RuntimeAssert(object != reinterpret_cast(1), "Markers disallowed here"); if (Strict) { *const_cast(location) = object; } else { ObjHeader* old = *location; if (old != object) { if (object != nullptr) { addHeapRef(object); } *const_cast(location) = object; if (old != nullptr) { releaseHeapRef(old); } } } } template void updateReturnRef(ObjHeader** returnSlot, const ObjHeader* value) { updateStackRef(returnSlot, value); } void updateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) { if (object != nullptr) { #if KONAN_NO_THREADS ObjHeader* old = *location; if (old == nullptr) { addHeapRef(const_cast(object)); *const_cast(location) = object; } #else addHeapRef(const_cast(object)); auto old = __sync_val_compare_and_swap(location, nullptr, const_cast(object)); if (old != nullptr) { // Failed to store, was not null. ReleaseHeapRef(const_cast(object)); } #endif UPDATE_REF_EVENT(memoryState, old, object, location, 0); } } inline void checkIfGcNeeded(MemoryState* state) { if (state != nullptr && state->allocSinceLastGc > state->allocSinceLastGcThreshold && state->gcSuspendCount == 0) { // To avoid GC trashing check that at least 10ms passed since last GC. if (konan::getTimeMicros() - state->lastGcTimestamp > 10 * 1000) { GC_LOG("Calling GC from checkIfGcNeeded: %zu\n", state->toRelease->size()) garbageCollect(state, false); } } } inline void checkIfForceCyclicGcNeeded(MemoryState* state) { if (state != nullptr && state->toFree != nullptr && state->toFree->size() > kMaxToFreeSizeThreshold && state->gcSuspendCount == 0) { // To avoid GC trashing check that at least 10ms passed since last GC. if (konan::getTimeMicros() - state->lastGcTimestamp > 10 * 1000) { GC_LOG("Calling GC from checkIfForceCyclicGcNeeded: %zu\n", state->toFree->size()) garbageCollect(state, true); } } } template OBJ_GETTER(allocInstance, const TypeInfo* type_info) { RuntimeAssert(type_info->instanceSize_ >= 0, "must be an object"); auto* state = memoryState; #if USE_GC checkIfGcNeeded(state); #endif // USE_GC auto container = ObjectContainer(state, type_info); ObjHeader* obj = container.GetPlace(); #if USE_GC if (Strict) { rememberNewContainer(container.header()); } else { makeShareable(container.header()); } #endif // USE_GC #if USE_CYCLE_DETECTOR CycleDetector::insertCandidateIfNeeded(obj); #endif // USE_CYCLE_DETECTOR #if USE_CYCLIC_GC if ((obj->type_info()->flags_ & TF_LEAK_DETECTOR_CANDIDATE) != 0) { // Note: this should be performed after [rememberNewContainer] (above). // Otherwise cyclic collector can observe this atomic root with RC = 0, // thus consider it garbage and then zero it after initialization. cyclicAddAtomicRoot(obj); } #endif // USE_CYCLIC_GC RETURN_OBJ(obj); } template OBJ_GETTER(allocArrayInstance, const TypeInfo* type_info, int32_t elements) { RuntimeAssert(type_info->instanceSize_ < 0, "must be an array"); if (elements < 0) ThrowIllegalArgumentException(); auto* state = memoryState; #if USE_GC checkIfGcNeeded(state); #endif // USE_GC auto container = ArrayContainer(state, type_info, elements); #if USE_GC if (Strict) { rememberNewContainer(container.header()); } else { makeShareable(container.header()); } #endif // USE_GC RETURN_OBJ(container.GetPlace()->obj()); } template OBJ_GETTER(initThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { ObjHeader* value = *location; if (value != nullptr) { // OK'ish, inited by someone else. RETURN_OBJ(value); } ObjHeader* object = allocInstance(typeInfo, OBJ_RESULT); updateHeapRef(location, object); #if KONAN_NO_EXCEPTIONS ctor(object); return object; #else try { ctor(object); return object; } catch (...) { UpdateReturnRef(OBJ_RESULT, nullptr); ZeroHeapRef(location); throw; } #endif } template OBJ_GETTER(initSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { #if KONAN_NO_THREADS ObjHeader* value = *location; if (value != nullptr) { // OK'ish, inited by someone else. RETURN_OBJ(value); } ObjHeader* object = AllocInstance(typeInfo, OBJ_RESULT); UpdateHeapRef(location, object); #if KONAN_NO_EXCEPTIONS ctor(object); FreezeSubgraph(object); return object; #else try { ctor(object); if (Strict) FreezeSubgraph(object); return object; } catch (...) { UpdateReturnRef(OBJ_RESULT, nullptr); ZeroHeapRef(location); throw; } #endif // KONAN_NO_EXCEPTIONS #else // KONAN_NO_THREADS // Search from the top of the stack. for (auto it = memoryState->initializingSingletons.rbegin(); it != memoryState->initializingSingletons.rend(); ++it) { if (it->first == location) { RETURN_OBJ(it->second); } } ObjHeader* initializing = reinterpret_cast(1); // Spin lock. ObjHeader* value = nullptr; while ((value = __sync_val_compare_and_swap(location, nullptr, initializing)) == initializing); if (value != nullptr) { // OK'ish, inited by someone else. RETURN_OBJ(value); } ObjHeader* object = AllocInstance(typeInfo, OBJ_RESULT); memoryState->initializingSingletons.push_back(std::make_pair(location, object)); #if KONAN_NO_EXCEPTIONS ctor(object); if (Strict) FreezeSubgraph(object); UpdateHeapRef(location, object); synchronize(); memoryState->initializingSingletons.pop_back(); return object; #else // KONAN_NO_EXCEPTIONS try { ctor(object); if (Strict) FreezeSubgraph(object); UpdateHeapRef(location, object); synchronize(); memoryState->initializingSingletons.pop_back(); return object; } catch (...) { UpdateReturnRef(OBJ_RESULT, nullptr); zeroHeapRef(location); memoryState->initializingSingletons.pop_back(); synchronize(); throw; } #endif // KONAN_NO_EXCEPTIONS #endif // KONAN_NO_THREADS } /** * We keep thread affinity and reference value based cookie in the atomic references, so that * repeating read operation of the same value do not lead to the repeating rememberNewContainer() operation. * We must invalidate cookie after the local GC, as otherwise fact that container of the `value` is retained * may change, if the last reference to the value read is lost during GC and we re-read same value from * the same atomic reference. Thus we also include GC epoque into the cookie. */ inline int32_t computeCookie() { auto* state = memoryState; auto epoque = state->gcEpoque; return (static_cast(reinterpret_cast(state))) ^ static_cast(epoque); } OBJ_GETTER(swapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { lock(spinlock); ObjHeader* oldValue = *location; bool shallRemember = false; if (IsStrictMemoryModel()) { auto realCookie = computeCookie(); shallRemember = *cookie != realCookie; if (shallRemember) *cookie = realCookie; } if (oldValue == expectedValue) { #if USE_CYCLIC_GC if (g_hasCyclicCollector) cyclicMutateAtomicRoot(newValue); #endif // USE_CYCLIC_GC SetHeapRef(location, newValue); } UpdateReturnRef(OBJ_RESULT, oldValue); if (IsStrictMemoryModel() && shallRemember && oldValue != nullptr && oldValue != expectedValue) { // Only remember container if it is not known to this thread (i.e. != expectedValue). rememberNewContainer(containerFor(oldValue)); } unlock(spinlock); if (oldValue != nullptr && oldValue == expectedValue) { ReleaseHeapRef(oldValue); } return oldValue; } void setHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { lock(spinlock); ObjHeader* oldValue = *location; #if USE_CYCLIC_GC if (g_hasCyclicCollector) cyclicMutateAtomicRoot(newValue); #endif // USE_CYCLIC_GC // We do not use UpdateRef() here to avoid having ReleaseRef() on old value under the lock. SetHeapRef(location, newValue); *cookie = computeCookie(); unlock(spinlock); if (oldValue != nullptr) ReleaseHeapRef(oldValue); } OBJ_GETTER(readHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) { MEMORY_LOG("ReadHeapRefLocked: %p\n", location) lock(spinlock); ObjHeader* value = *location; auto realCookie = computeCookie(); bool shallRemember = *cookie != realCookie; if (shallRemember) *cookie = realCookie; UpdateReturnRef(OBJ_RESULT, value); #if USE_GC if (IsStrictMemoryModel() && shallRemember && value != nullptr) { auto* container = containerFor(value); rememberNewContainer(container); } #endif // USE_GC unlock(spinlock); return value; } OBJ_GETTER(readHeapRefNoLock, ObjHeader* object, KInt index) { MEMORY_LOG("ReadHeapRefNoLock: %p index %d\n", object, index) ObjHeader** location = reinterpret_cast( reinterpret_cast(object) + object->type_info()->objOffsets_[index]); ObjHeader* value = *location; #if USE_GC if (IsStrictMemoryModel() && (value != nullptr)) { // Maybe not so good to do that under lock. rememberNewContainer(containerFor(value)); } #endif // USE_GC RETURN_OBJ(value); } template void enterFrame(ObjHeader** start, int parameters, int count) { MEMORY_LOG("EnterFrame %p: %d parameters %d locals\n", start, parameters, count) FrameOverlay* frame = reinterpret_cast(start); if (Strict) { frame->previous = currentFrame; currentFrame = frame; // TODO: maybe compress in single value somehow. frame->parameters = parameters; frame->count = count; } } template void leaveFrame(ObjHeader** start, int parameters, int count) { MEMORY_LOG("LeaveFrame %p: %d parameters %d locals\n", start, parameters, count) FrameOverlay* frame = reinterpret_cast(start); if (Strict) { currentFrame = frame->previous; } else { ObjHeader** current = start + parameters + kFrameOverlaySlots; count -= parameters; while (count-- > kFrameOverlaySlots) { ObjHeader* object = *current; if (object != nullptr) { releaseHeapRef(object); } current++; } } } void suspendGC() { GC_LOG("suspendGC\n") memoryState->gcSuspendCount++; } void resumeGC() { GC_LOG("resumeGC\n") MemoryState* state = memoryState; if (state->gcSuspendCount > 0) { state->gcSuspendCount--; if (state->toRelease != nullptr && state->toRelease->size() >= state->gcThreshold && state->gcSuspendCount == 0) { garbageCollect(state, false); } } } void stopGC() { GC_LOG("stopGC\n") if (memoryState->toRelease != nullptr) { memoryState->gcSuspendCount = 0; garbageCollect(memoryState, true); konanDestructInstance(memoryState->toRelease); konanDestructInstance(memoryState->toFree); konanDestructInstance(memoryState->roots); memoryState->toRelease = nullptr; memoryState->toFree = nullptr; memoryState->roots = nullptr; } } void startGC() { GC_LOG("startGC\n") if (memoryState->toFree == nullptr) { memoryState->toFree = konanConstructInstance(); memoryState->toRelease = konanConstructInstance(); memoryState->roots = konanConstructInstance(); memoryState->gcSuspendCount = 0; } } void setGCThreshold(KInt value) { GC_LOG("setGCThreshold %d\n", value) if (value <= 0) { ThrowIllegalArgumentException(); } initGcThreshold(memoryState, value); } KInt getGCThreshold() { GC_LOG("getGCThreshold\n") return memoryState->gcThreshold; } void setGCCollectCyclesThreshold(KLong value) { GC_LOG("setGCCollectCyclesThreshold %lld\n", value) if (value <= 0) { ThrowIllegalArgumentException(); } initGcCollectCyclesThreshold(memoryState, value); } KInt getGCCollectCyclesThreshold() { GC_LOG("getGCCollectCyclesThreshold\n") return memoryState->gcCollectCyclesThreshold; } void setGCThresholdAllocations(KLong value) { GC_LOG("setGCThresholdAllocations %lld\n", value) if (value <= 0) { ThrowIllegalArgumentException(); } memoryState->allocSinceLastGcThreshold = value; } KLong getGCThresholdAllocations() { GC_LOG("getGCThresholdAllocation\n") return memoryState->allocSinceLastGcThreshold; } void setTuneGCThreshold(KBoolean value) { GC_LOG("setTuneGCThreshold %d\n", value) memoryState->gcErgonomics = value; } KBoolean getTuneGCThreshold() { GC_LOG("getTuneGCThreshold %d\n", memoryState->gcErgonomics) return memoryState->gcErgonomics; } KNativePtr createStablePointer(KRef any) { if (any == nullptr) return nullptr; MEMORY_LOG("CreateStablePointer for %p rc=%d\n", any, containerFor(any) ? containerFor(any)->refCount() : 0) addHeapRef(any); return reinterpret_cast(any); } void disposeStablePointer(KNativePtr pointer) { if (pointer == nullptr) return; KRef ref = reinterpret_cast(pointer); ReleaseHeapRef(ref); } OBJ_GETTER(derefStablePointer, KNativePtr pointer) { KRef ref = reinterpret_cast(pointer); AdoptReferenceFromSharedVariable(ref); RETURN_OBJ(ref); } OBJ_GETTER(adoptStablePointer, KNativePtr pointer) { synchronize(); KRef ref = reinterpret_cast(pointer); MEMORY_LOG("adopting stable pointer %p, rc=%d\n", \ ref, (ref && containerFor(ref)) ? containerFor(ref)->refCount() : -1) UpdateReturnRef(OBJ_RESULT, ref); DisposeStablePointer(pointer); return ref; } bool clearSubgraphReferences(ObjHeader* root, bool checked) { #if USE_GC MEMORY_LOG("ClearSubgraphReferences %p\n", root) if (root == nullptr) return true; auto state = memoryState; auto* container = containerFor(root); if (isShareable(container)) // We assume, that frozen/shareable objects can be safely passed and not present // in the GC candidate list. // TODO: assert for that? return true; // Free cyclic garbage to decrease number of analyzed objects. checkIfForceCyclicGcNeeded(state); ContainerHeaderSet visited; if (!checked) { hasExternalRefs(container, &visited); } else { // Now decrement RC of elements in toRelease set for reachibility analysis. for (auto it = state->toRelease->begin(); it != state->toRelease->end(); ++it) { auto released = *it; if (!isMarkedAsRemoved(released) && released->local()) { released->decRefCount(); } } container->decRefCount(); markGray(container); auto bad = hasExternalRefs(container, &visited); scanBlack(container); // Restore original RC. container->incRefCount(); for (auto it = state->toRelease->begin(); it != state->toRelease->end(); ++it) { auto released = *it; if (!isMarkedAsRemoved(released) && released->local()) { released->incRefCount(); } } if (bad) { return false; } } // Remove all no longer owned containers from GC structures. // TODO: not very efficient traversal. for (auto it = state->toFree->begin(); it != state->toFree->end(); ++it) { auto container = *it; if (visited.count(container) != 0) { MEMORY_LOG("removing %p from the toFree list\n", container) container->resetBuffered(); container->setColorAssertIfGreen(CONTAINER_TAG_GC_BLACK); *it = markAsRemoved(container); } } for (auto it = state->toRelease->begin(); it != state->toRelease->end(); ++it) { auto container = *it; if (!isMarkedAsRemoved(container) && visited.count(container) != 0) { MEMORY_LOG("removing %p from the toRelease list\n", container) container->decRefCount(); *it = markAsRemoved(container); } } #if TRACE_MEMORY // Forget transferred containers. for (auto* it: visited) { state->containers->erase(it); } #endif #endif // USE_GC return true; } void freezeAcyclic(ContainerHeader* rootContainer, ContainerHeaderSet* newlyFrozen) { KStdDeque queue; queue.push_back(rootContainer); while (!queue.empty()) { ContainerHeader* current = queue.front(); queue.pop_front(); current->unMark(); current->resetBuffered(); current->setColorUnlessGreen(CONTAINER_TAG_GC_BLACK); // Note, that once object is frozen, it could be concurrently accessed, so // color and similar attributes shall not be used. if (!current->frozen()) newlyFrozen->insert(current); MEMORY_LOG("freezing %p\n", current) current->freeze(); traverseContainerReferredObjects(current, [&queue](ObjHeader* obj) { ContainerHeader* objContainer = containerFor(obj); if (canFreeze(objContainer)) { if (objContainer->marked()) queue.push_back(objContainer); } }); } } void freezeCyclic(ObjHeader* root, const KStdVector& order, ContainerHeaderSet* newlyFrozen) { KStdUnorderedMap> reversedEdges; KStdDeque queue; queue.push_back(root); while (!queue.empty()) { ObjHeader* current = queue.front(); queue.pop_front(); ContainerHeader* currentContainer = containerFor(current); currentContainer->unMark(); reversedEdges.emplace(currentContainer, KStdVector(0)); traverseContainerReferredObjects(currentContainer, [current, currentContainer, &queue, &reversedEdges](ObjHeader* obj) { ContainerHeader* objContainer = containerFor(obj); if (canFreeze(objContainer)) { if (objContainer->marked()) queue.push_back(obj); // We ignore references from FreezableAtomicsReference during condensation, to avoid KT-33824. if (!isFreezableAtomic(current)) reversedEdges.emplace(objContainer, KStdVector(0)). first->second.push_back(currentContainer); } }); } KStdVector> components; MEMORY_LOG("Condensation:\n"); // Enumerate in the topological order. for (auto it = order.rbegin(); it != order.rend(); ++it) { auto* container = *it; if (container->marked()) continue; KStdVector component; traverseStronglyConnectedComponent(container, &reversedEdges, &component); MEMORY_LOG("SCC:\n"); #if TRACE_MEMORY for (auto c: component) konan::consolePrintf(" %p\n", c); #endif components.push_back(std::move(component)); } // Enumerate strongly connected components in reversed topological order. for (auto it = components.rbegin(); it != components.rend(); ++it) { auto& component = *it; int internalRefsCount = 0; int totalCount = 0; for (auto* container : component) { RuntimeAssert(!isAggregatingFrozenContainer(container), "Must not be called on such containers"); totalCount += container->refCount(); if (isFreezableAtomic(container)) { RuntimeAssert(component.size() == 1, "Must be trivial condensation"); continue; } traverseContainerReferredObjects(container, [&internalRefsCount](ObjHeader* obj) { auto* container = containerFor(obj); if (canFreeze(container)) ++internalRefsCount; }); } // Freeze component. for (auto* container : component) { container->resetBuffered(); container->setColorUnlessGreen(CONTAINER_TAG_GC_BLACK); if (!container->frozen()) newlyFrozen->insert(container); // Note, that once object is frozen, it could be concurrently accessed, so // color and similar attributes shall not be used. MEMORY_LOG("freezing %p\n", container) container->freeze(); // We set refcount of original container to zero, so that it is seen as such after removal // meta-object, where aggregating container is stored. container->setRefCount(0); } // Create fictitious container for the whole component. auto superContainer = component.size() == 1 ? component[0] : allocAggregatingFrozenContainer(component); // Don't count internal references. MEMORY_LOG("Setting aggregating %p rc to %d (total %d inner %d)\n", \ superContainer, totalCount - internalRefsCount, totalCount, internalRefsCount) superContainer->setRefCount(totalCount - internalRefsCount); newlyFrozen->insert(superContainer); } } void runFreezeHooksRecursive(ObjHeader* root) { KStdUnorderedSet seen; KStdVector toVisit; seen.insert(root); toVisit.push_back(root); while (!toVisit.empty()) { KRef obj = toVisit.back(); toVisit.pop_back(); kotlin::RunFreezeHooks(obj); kotlin::traverseReferredObjects(obj, [&seen, &toVisit](ObjHeader* field) { auto wasNotSeenYet = seen.insert(field).second; // Only iterating on unseen objects which containers will get frozen by freezeCyclic or freezeAcyclic. if (wasNotSeenYet && canFreeze(containerFor(field))) { toVisit.push_back(field); } }); } } /** * Theory of operations. * * Kotlin/Native supports object graph freezing, allowing to make certain subgraph immutable and thus * suitable for safe sharing amongst multiple concurrent executors. This operation recursively operates * on all objects reachable from the given object, and marks them as frozen. In frozen state object's * fields cannot be modified, and so, lifetime of frozen objects correlates. Practically, it means * that lifetimes of all strongly connected components are fully controlled by incoming reference * counters, and so if we place all members of strongly connected component to the single container * it could be correctly released by just atomic decrement on reference counter, without additional * cycle collector run. * So during subgraph freezing operation, we perform the following steps: * - run Kosoraju-Sharir algorithm to find strongly connected components * - put all objects in each strongly connected component into an artificial container * (we assume that they all were in single element containers initially), single-object * components remain in the same container * - artificial container sums up outer reference counters of all its objects (i.e. * incoming references from the same strongly connected component are not counted) * - mark all object's headers as frozen * * Further reference counting on frozen objects is performed with atomic operations, and so frozen * references could be passed across multiple threads. */ void freezeSubgraph(ObjHeader* root) { if (root == nullptr) return; // First check that passed object graph has no cycles. // If there are cycles - run graph condensation on cyclic graphs using Kosoraju-Sharir. ContainerHeader* rootContainer = containerFor(root); if (isPermanentOrFrozen(rootContainer)) return; MEMORY_LOG("Run freeze hooks on subgraph of %p\n", root); // Note: Actual freezing can fail, but these hooks won't be undone, and moreover // these hooks will run again on a repeated freezing attempt. runFreezeHooksRecursive(root); MEMORY_LOG("Freeze subgraph of %p\n", root) #if USE_GC auto state = memoryState; // Free cyclic garbage to decrease number of analyzed objects. checkIfForceCyclicGcNeeded(state); #endif // Do DFS cycle detection. bool hasCycles = false; KRef firstBlocker = root->has_meta_object() && ((root->meta_object()->flags_ & MF_NEVER_FROZEN) != 0) ? root : nullptr; KStdVector order; depthFirstTraversal(rootContainer, &hasCycles, &firstBlocker, &order); if (firstBlocker != nullptr) { MEMORY_LOG("See freeze blocker for %p: %p\n", root, firstBlocker) ThrowFreezingException(root, firstBlocker); } ContainerHeaderSet newlyFrozen; // Now unmark all marked objects, and freeze them, if no cycles detected. if (hasCycles) { freezeCyclic(root, order, &newlyFrozen); } else { freezeAcyclic(rootContainer, &newlyFrozen); } MEMORY_LOG("Graph of %p is %s with %d elements\n", root, hasCycles ? "cyclic" : "acyclic", newlyFrozen.size()) #if USE_GC // Now remove frozen objects from the toFree list. // TODO: optimize it by keeping ignored (i.e. freshly frozen) objects in the set, // and use it when analyzing toFree during collection. for (auto& container : *(state->toFree)) { if (!isMarkedAsRemoved(container) && container->frozen()) { RuntimeAssert(newlyFrozen.count(container) != 0, "Must be newly frozen"); container = markAsRemoved(container); } } #endif } void ensureNeverFrozen(ObjHeader* object) { auto* container = containerFor(object); if (container == nullptr || container->frozen()) ThrowFreezingException(object, object); // TODO: note, that this API could not not be called on frozen objects, so no need to care much about concurrency, // although there's subtle race with case, where other thread freezes the same object after check. object->meta_object()->flags_ |= MF_NEVER_FROZEN; } void shareAny(ObjHeader* obj) { auto* container = containerFor(obj); if (isShareable(container)) return; RuntimeCheck(container->objectCount() == 1, "Must be a single object container"); container->makeShared(); } ScopedRefHolder::ScopedRefHolder(KRef obj): obj_(obj) { if (obj_) { addHeapRef(obj_); } } ScopedRefHolder::~ScopedRefHolder() { if (obj_) { ReleaseHeapRef(obj_); } } #if USE_CYCLE_DETECTOR // static CycleDetectorRootset CycleDetector::collectRootset() { auto& detector = instance(); CycleDetectorRootset rootset; std::lock_guard guard(detector.lock_); for (auto* candidate: detector.candidateList_) { // Only frozen candidates are to be analyzed. if (!isPermanentOrFrozen(candidate)) continue; rootset.roots.push_back(candidate); rootset.heldRefs.emplace_back(candidate); kotlin::traverseReferredObjects(candidate, [&rootset, candidate](KRef field) { rootset.rootToFields[candidate].push_back(field); // TODO: There's currently a race here: // some other thread might null this field and destroy it in GC before // we put it in ScopedRefHolder. rootset.heldRefs.emplace_back(field); }); } return rootset; } KStdVector findCycleWithDFS(KRef root, const CycleDetectorRootset& rootset) { auto traverseFields = [&rootset](KRef obj, auto process) { auto it = rootset.rootToFields.find(obj); // If obj is in the rootset, use it's pinned state. if (it != rootset.rootToFields.end()) { const auto& fields = it->second; for (KRef field: fields) { if (field != nullptr) { process(field); } } return; } kotlin::traverseReferredObjects(obj, process); }; KStdVector> toVisit; auto appendFieldsToVisit = [&toVisit, &traverseFields](KRef obj, const KStdVector& currentPath) { traverseFields(obj, [&toVisit, ¤tPath](KRef field) { auto path = currentPath; path.push_back(field); toVisit.emplace_back(std::move(path)); }); }; appendFieldsToVisit(root, KRefList(1, root)); KStdUnorderedSet seen; seen.insert(root); while (!toVisit.empty()) { KStdVector currentPath = std::move(toVisit.back()); toVisit.pop_back(); KRef node = currentPath[currentPath.size() - 1]; if (node == root) { // Found a cycle. return currentPath; } // Already traversed this node. if (seen.count(node) != 0) continue; seen.insert(node); appendFieldsToVisit(node, currentPath); } return {}; } template OBJ_GETTER(createAndFillArray, const C& container) { auto* result = AllocArrayInstance(theArrayTypeInfo, container.size(), OBJ_RESULT)->array(); KRef* place = ArrayAddressOfElementAt(result, 0); for (KRef it: container) { UpdateHeapRef(place++, it); } RETURN_OBJ(result->obj()); } OBJ_GETTER0(detectCyclicReferences) { auto rootset = CycleDetector::collectRootset(); KStdVector cyclic; for (KRef root: rootset.roots) { if (!findCycleWithDFS(root, rootset).empty()) { cyclic.push_back(root); } } RETURN_RESULT_OF(createAndFillArray, cyclic); } OBJ_GETTER(findCycle, KRef root) { auto rootset = CycleDetector::collectRootset(); auto cycle = findCycleWithDFS(root, rootset); if (cycle.empty()) { RETURN_OBJ(nullptr); } RETURN_RESULT_OF(createAndFillArray, cycle); } #endif // USE_CYCLE_DETECTOR } // namespace MetaObjHeader* ObjHeader::createMetaObject(ObjHeader* object) { TypeInfo** location = &object->typeInfoOrMeta_; TypeInfo* typeInfo = *location; RuntimeCheck(!hasPointerBits(typeInfo, OBJECT_TAG_MASK), "Object must not be tagged"); #if !KONAN_NO_THREADS if (typeInfo->typeInfo_ != typeInfo) { // Someone installed a new meta-object since the check. return reinterpret_cast(typeInfo); } #endif MetaObjHeader* meta = konanConstructInstance(); meta->typeInfo_ = typeInfo; #if KONAN_NO_THREADS *location = reinterpret_cast(meta); #else TypeInfo* old = __sync_val_compare_and_swap(location, typeInfo, reinterpret_cast(meta)); if (old != typeInfo) { // Someone installed a new meta-object since the check. konanFreeMemory(meta); meta = reinterpret_cast(old); } #endif return meta; } void ObjHeader::destroyMetaObject(ObjHeader* object) { TypeInfo** location = &object->typeInfoOrMeta_; MetaObjHeader* meta = clearPointerBits(*(reinterpret_cast(location)), OBJECT_TAG_MASK); *const_cast(location) = meta->typeInfo_; if (meta->WeakReference.counter_ != nullptr) { WeakReferenceCounterClear(meta->WeakReference.counter_); ZeroHeapRef(&meta->WeakReference.counter_); } #ifdef KONAN_OBJC_INTEROP Kotlin_ObjCExport_releaseAssociatedObject(meta->associatedObject_); #endif konanFreeMemory(meta); } void ObjectContainer::Init(MemoryState* state, const TypeInfo* typeInfo) { RuntimeAssert(typeInfo->instanceSize_ >= 0, "Must be an object"); uint32_t allocSize = sizeof(ContainerHeader) + typeInfo->instanceSize_; header_ = allocContainer(state, allocSize); RuntimeCheck(header_ != nullptr, "Cannot alloc memory"); // One object in this container, no need to set. header_->setContainerSize(allocSize); RuntimeAssert(header_->objectCount() == 1, "Must work properly"); // header->refCount_ is zero initialized by allocContainer(). SetHeader(GetPlace(), typeInfo); OBJECT_ALLOC_EVENT(memoryState, typeInfo->instanceSize_, GetPlace()) } void ArrayContainer::Init(MemoryState* state, const TypeInfo* typeInfo, uint32_t elements) { RuntimeAssert(typeInfo->instanceSize_ < 0, "Must be an array"); uint32_t allocSize = sizeof(ContainerHeader) + arrayObjectSize(typeInfo, elements); header_ = allocContainer(state, allocSize); RuntimeCheck(header_ != nullptr, "Cannot alloc memory"); // One object in this container, no need to set. header_->setContainerSize(allocSize); RuntimeAssert(header_->objectCount() == 1, "Must work properly"); // header->refCount_ is zero initialized by allocContainer(). GetPlace()->count_ = elements; SetHeader(GetPlace()->obj(), typeInfo); OBJECT_ALLOC_EVENT(memoryState, arrayObjectSize(typeInfo, elements), GetPlace()->obj()) } // TODO: store arena containers in some reuseable data structure, similar to // finalizer queue. void ArenaContainer::Init() { allocContainer(1024); } void ArenaContainer::Deinit() { MEMORY_LOG("Arena::Deinit start: %p\n", this) auto chunk = currentChunk_; while (chunk != nullptr) { // freeContainer() doesn't release memory when CONTAINER_TAG_STACK is set. MEMORY_LOG("Arena::Deinit free chunk %p\n", chunk) freeContainer(chunk->asHeader()); chunk = chunk->next; } chunk = currentChunk_; while (chunk != nullptr) { auto toRemove = chunk; chunk = chunk->next; konanFreeMemory(toRemove); } } bool ArenaContainer::allocContainer(container_size_t minSize) { auto size = minSize + sizeof(ContainerHeader) + sizeof(ContainerChunk); size = alignUp(size, kContainerAlignment); // TODO: keep simple cache of container chunks. ContainerChunk* result = konanConstructSizedInstance(size); RuntimeCheck(result != nullptr, "Cannot alloc memory"); if (result == nullptr) return false; result->next = currentChunk_; result->arena = this; result->asHeader()->refCount_ = (CONTAINER_TAG_STACK | CONTAINER_TAG_INCREMENT); currentChunk_ = result; current_ = reinterpret_cast(result->asHeader() + 1); end_ = reinterpret_cast(result) + size; return true; } void* ArenaContainer::place(container_size_t size) { size = alignUp(size, kObjectAlignment); // Fast path. if (current_ + size < end_) { void* result = current_; current_ += size; return result; } if (!allocContainer(size)) { return nullptr; } void* result = current_; current_ += size; RuntimeAssert(current_ <= end_, "Must not overflow"); return result; } #define ARENA_SLOTS_CHUNK_SIZE 16 ObjHeader** ArenaContainer::getSlot() { if (slots_ == nullptr || slotsCount_ >= ARENA_SLOTS_CHUNK_SIZE) { slots_ = PlaceArray(theArrayTypeInfo, ARENA_SLOTS_CHUNK_SIZE); slotsCount_ = 0; } return ArrayAddressOfElementAt(slots_, slotsCount_++); } ObjHeader* ArenaContainer::PlaceObject(const TypeInfo* type_info) { RuntimeAssert(type_info->instanceSize_ >= 0, "must be an object"); uint32_t size = type_info->instanceSize_; ObjHeader* result = reinterpret_cast(place(size)); if (!result) { return nullptr; } OBJECT_ALLOC_EVENT(memoryState, type_info->instanceSize_, result) currentChunk_->asHeader()->incObjectCount(); setHeader(result, type_info); return result; } ArrayHeader* ArenaContainer::PlaceArray(const TypeInfo* type_info, uint32_t count) { RuntimeAssert(type_info->instanceSize_ < 0, "must be an array"); container_size_t size = arrayObjectSize(type_info, count); ArrayHeader* result = reinterpret_cast(place(size)); if (!result) { return nullptr; } OBJECT_ALLOC_EVENT(memoryState, arrayObjectSize(type_info, count), result->obj()) currentChunk_->asHeader()->incObjectCount(); setHeader(result->obj(), type_info); result->count_ = count; return result; } // API of the memory manager. extern "C" { // Private memory interface. bool TryAddHeapRef(const ObjHeader* object) { return tryAddHeapRef(object); } RUNTIME_NOTHROW void ReleaseHeapRefStrict(const ObjHeader* object) { releaseHeapRef(const_cast(object)); } RUNTIME_NOTHROW void ReleaseHeapRefRelaxed(const ObjHeader* object) { releaseHeapRef(const_cast(object)); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollectStrict(const ObjHeader* object) { releaseHeapRef(const_cast(object)); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollectRelaxed(const ObjHeader* object) { releaseHeapRef(const_cast(object)); } ForeignRefContext InitLocalForeignRef(ObjHeader* object) { return initLocalForeignRef(object); } ForeignRefContext InitForeignRef(ObjHeader* object) { return initForeignRef(object); } void DeinitForeignRef(ObjHeader* object, ForeignRefContext context) { deinitForeignRef(object, context); } bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context) { return isForeignRefAccessible(object, context); } void AdoptReferenceFromSharedVariable(ObjHeader* object) { #if USE_GC if (IsStrictMemoryModel() && object != nullptr && isShareable(containerFor(object))) rememberNewContainer(containerFor(object)); #endif // USE_GC } // Public memory interface. MemoryState* InitMemory(bool firstRuntime) { return initMemory(firstRuntime); } void DeinitMemory(MemoryState* memoryState, bool destroyRuntime) { deinitMemory(memoryState, destroyRuntime); } void RestoreMemory(MemoryState* memoryState) { RuntimeAssert((::memoryState == nullptr) || (::memoryState == memoryState), "Must not replace with unrelated memory state"); ::memoryState = memoryState; } OBJ_GETTER(AllocInstanceStrict, const TypeInfo* type_info) { RETURN_RESULT_OF(allocInstance, type_info); } OBJ_GETTER(AllocInstanceRelaxed, const TypeInfo* type_info) { RETURN_RESULT_OF(allocInstance, type_info); } OBJ_GETTER(AllocArrayInstanceStrict, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(allocArrayInstance, typeInfo, elements); } OBJ_GETTER(AllocArrayInstanceRelaxed, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(allocArrayInstance, typeInfo, elements); } OBJ_GETTER(InitThreadLocalSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(initThreadLocalSingleton, location, typeInfo, ctor); } OBJ_GETTER(InitThreadLocalSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(initThreadLocalSingleton, location, typeInfo, ctor); } OBJ_GETTER(InitSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(initSingleton, location, typeInfo, ctor); } OBJ_GETTER(InitSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(initSingleton, location, typeInfo, ctor); } void RUNTIME_NOTHROW InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) { RuntimeCheck(false, "Global registration is impossible in legacy MM"); } RUNTIME_NOTHROW void SetStackRefStrict(ObjHeader** location, const ObjHeader* object) { setStackRef(location, object); } RUNTIME_NOTHROW void SetStackRefRelaxed(ObjHeader** location, const ObjHeader* object) { setStackRef(location, object); } RUNTIME_NOTHROW void SetHeapRefStrict(ObjHeader** location, const ObjHeader* object) { setHeapRef(location, object); } RUNTIME_NOTHROW void SetHeapRefRelaxed(ObjHeader** location, const ObjHeader* object) { setHeapRef(location, object); } RUNTIME_NOTHROW void ZeroHeapRef(ObjHeader** location) { zeroHeapRef(location); } RUNTIME_NOTHROW void ZeroStackRefStrict(ObjHeader** location) { zeroStackRef(location); } RUNTIME_NOTHROW void ZeroStackRefRelaxed(ObjHeader** location) { zeroStackRef(location); } RUNTIME_NOTHROW void UpdateStackRefStrict(ObjHeader** location, const ObjHeader* object) { updateStackRef(location, object); } RUNTIME_NOTHROW void UpdateStackRefRelaxed(ObjHeader** location, const ObjHeader* object) { updateStackRef(location, object); } RUNTIME_NOTHROW void UpdateHeapRefStrict(ObjHeader** location, const ObjHeader* object) { updateHeapRef(location, object); } RUNTIME_NOTHROW void UpdateHeapRefRelaxed(ObjHeader** location, const ObjHeader* object) { updateHeapRef(location, object); } RUNTIME_NOTHROW void UpdateHeapRefsInsideOneArrayStrict(const ArrayHeader* array, int fromIndex, int toIndex, int count) { updateHeapRefsInsideOneArray(array, fromIndex, toIndex, count); } RUNTIME_NOTHROW void UpdateHeapRefsInsideOneArrayRelaxed(const ArrayHeader* array, int fromIndex, int toIndex, int count) { updateHeapRefsInsideOneArray(array, fromIndex, toIndex, count); } RUNTIME_NOTHROW void UpdateReturnRefStrict(ObjHeader** returnSlot, const ObjHeader* value) { updateReturnRef(returnSlot, value); } RUNTIME_NOTHROW void UpdateReturnRefRelaxed(ObjHeader** returnSlot, const ObjHeader* value) { updateReturnRef(returnSlot, value); } RUNTIME_NOTHROW void ZeroArrayRefs(ArrayHeader* array) { for (uint32_t index = 0; index < array->count_; ++index) { ObjHeader** location = ArrayAddressOfElementAt(array, index); zeroHeapRef(location); } } RUNTIME_NOTHROW void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) { updateHeapRefIfNull(location, object); } OBJ_GETTER(SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { RETURN_RESULT_OF(swapHeapRefLocked, location, expectedValue, newValue, spinlock, cookie); } RUNTIME_NOTHROW void SetHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { setHeapRefLocked(location, newValue, spinlock, cookie); } OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) { RETURN_RESULT_OF(readHeapRefLocked, location, spinlock, cookie); } OBJ_GETTER(ReadHeapRefNoLock, ObjHeader* object, KInt index) { RETURN_RESULT_OF(readHeapRefNoLock, object, index); } RUNTIME_NOTHROW void EnterFrameStrict(ObjHeader** start, int parameters, int count) { enterFrame(start, parameters, count); } RUNTIME_NOTHROW void EnterFrameRelaxed(ObjHeader** start, int parameters, int count) { enterFrame(start, parameters, count); } RUNTIME_NOTHROW void LeaveFrameStrict(ObjHeader** start, int parameters, int count) { leaveFrame(start, parameters, count); } RUNTIME_NOTHROW void LeaveFrameRelaxed(ObjHeader** start, int parameters, int count) { leaveFrame(start, parameters, count); } void Kotlin_native_internal_GC_collect(KRef) { #if USE_GC garbageCollect(); #endif } void Kotlin_native_internal_GC_collectCyclic(KRef) { #if USE_CYCLIC_GC if (g_hasCyclicCollector) cyclicScheduleGarbageCollect(); #else ThrowIllegalArgumentException(); #endif } void Kotlin_native_internal_GC_suspend(KRef) { #if USE_GC suspendGC(); #endif } void Kotlin_native_internal_GC_resume(KRef) { #if USE_GC resumeGC(); #endif } void Kotlin_native_internal_GC_stop(KRef) { #if USE_GC stopGC(); #endif } void Kotlin_native_internal_GC_start(KRef) { #if USE_GC startGC(); #endif } void Kotlin_native_internal_GC_setThreshold(KRef, KInt value) { #if USE_GC setGCThreshold(value); #endif } KInt Kotlin_native_internal_GC_getThreshold(KRef) { #if USE_GC return getGCThreshold(); #else return -1; #endif } void Kotlin_native_internal_GC_setCollectCyclesThreshold(KRef, KLong value) { #if USE_GC setGCCollectCyclesThreshold(value); #endif } KLong Kotlin_native_internal_GC_getCollectCyclesThreshold(KRef) { #if USE_GC return getGCCollectCyclesThreshold(); #else return -1; #endif } void Kotlin_native_internal_GC_setThresholdAllocations(KRef, KLong value) { #if USE_GC setGCThresholdAllocations(value); #endif } KLong Kotlin_native_internal_GC_getThresholdAllocations(KRef) { #if USE_GC return getGCThresholdAllocations(); #else return -1; #endif } void Kotlin_native_internal_GC_setTuneThreshold(KRef, KInt value) { #if USE_GC setTuneGCThreshold(value); #endif } KBoolean Kotlin_native_internal_GC_getTuneThreshold(KRef) { #if USE_GC return getTuneGCThreshold(); #else return false; #endif } OBJ_GETTER(Kotlin_native_internal_GC_detectCycles, KRef) { #if USE_CYCLE_DETECTOR if (!KonanNeedDebugInfo && !Kotlin_memoryLeakCheckerEnabled()) RETURN_OBJ(nullptr); RETURN_RESULT_OF0(detectCyclicReferences); #else RETURN_OBJ(nullptr); #endif } OBJ_GETTER(Kotlin_native_internal_GC_findCycle, KRef, KRef root) { #if USE_CYCLE_DETECTOR RETURN_RESULT_OF(findCycle, root); #else RETURN_OBJ(nullptr); #endif } RUNTIME_NOTHROW KNativePtr CreateStablePointer(KRef any) { return createStablePointer(any); } RUNTIME_NOTHROW void DisposeStablePointer(KNativePtr pointer) { disposeStablePointer(pointer); } OBJ_GETTER(DerefStablePointer, KNativePtr pointer) { RETURN_RESULT_OF(derefStablePointer, pointer); } OBJ_GETTER(AdoptStablePointer, KNativePtr pointer) { RETURN_RESULT_OF(adoptStablePointer, pointer); } RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) { return clearSubgraphReferences(root, checked); } void FreezeSubgraph(ObjHeader* root) { freezeSubgraph(root); } // This function is called from field mutators to check if object's header is frozen. // If object is frozen or permanent, an exception is thrown. void MutationCheck(ObjHeader* obj) { if (obj->local()) return; auto* container = containerFor(obj); if (container == nullptr || container->frozen()) ThrowInvalidMutabilityException(obj); } RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) { if (!obj->local() && pointee != nullptr && pointee->local()) { konan::consolePrintf("Attempt to store a stack object %p into a heap object %p\n", pointee, obj); konan::consolePrintf("This is a compiler bug, please report it to https://kotl.in/issue\n"); konan::abort(); } } void EnsureNeverFrozen(ObjHeader* object) { ensureNeverFrozen(object); } void Kotlin_Any_share(ObjHeader* obj) { shareAny(obj); } RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) { memory->tls.Add(key, size); } RUNTIME_NOTHROW void CommitTLSStorage(MemoryState* memory) { memory->tls.Commit(); } RUNTIME_NOTHROW void ClearTLS(MemoryState* memory) { memory->tls.Clear(); } RUNTIME_NOTHROW KRef* LookupTLS(void** key, int index) { return memoryState->tls.Lookup(key, index); } RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) { #if USE_CYCLIC_GC cyclicAddWorker(worker); #endif // USE_CYCLIC_GC } RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) { #if USE_CYCLIC_GC cyclicRemoveWorker(worker, g_hasCyclicCollector); #endif // USE_CYCLIC_GC } RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) { #if USE_CYCLIC_GC if (g_hasCyclicCollector) cyclicCollectorCallback(worker); #endif // USE_CYCLIC_GC } KBoolean Kotlin_native_internal_GC_getCyclicCollector(KRef gc) { #if USE_CYCLIC_GC return g_hasCyclicCollector; #else return false; #endif // USE_CYCLIC_GC } void Kotlin_native_internal_GC_setCyclicCollector(KRef gc, KBoolean value) { #if USE_CYCLIC_GC g_hasCyclicCollector = value; #else if (value) ThrowIllegalArgumentException(); #endif // USE_CYCLIC_GC } bool Kotlin_Any_isShareable(KRef thiz) { return thiz == nullptr || isShareable(containerFor(thiz)); } RUNTIME_NOTHROW void PerformFullGC(MemoryState* memory) { garbageCollect(memory, true); } void CheckGlobalsAccessible() { if (!::memoryState->isMainThread) ThrowIncorrectDereferenceException(); } ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { // no-op, used by the new MM only. } ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { // no-op, used by the new MM only. } ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionEpilogue() { // no-op, used by the new MM only. } ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() { // no-op, used by the new MM only. } ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_safePointExceptionUnwind() { // no-op, used by the new MM only. } } // extern "C" #if !KONAN_NO_EXCEPTIONS // static ALWAYS_INLINE RUNTIME_NORETURN void ExceptionObjHolder::Throw(ObjHeader* exception) { throw ExceptionObjHolderImpl(exception); } ALWAYS_INLINE ObjHeader* ExceptionObjHolder::GetExceptionObject() noexcept { return static_cast(this)->obj(); } #endif ALWAYS_INLINE kotlin::ThreadState kotlin::SwitchThreadState(MemoryState* thread, ThreadState newState) noexcept { // no-op, used by the new MM only. return ThreadState::kRunnable; } ALWAYS_INLINE void kotlin::AssertThreadState(MemoryState* thread, ThreadState expected) noexcept { // no-op, used by the new MM only. } MemoryState* kotlin::mm::GetMemoryState() { return ::memoryState; } ================================================ FILE: runtime/src/legacymm/cpp/MemoryPrivate.hpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_MEMORYPRIVATE_HPP #define RUNTIME_MEMORYPRIVATE_HPP #include "Memory.h" typedef enum { // Those bit masks are applied to refCount_ field. // Container is normal thread-local container. CONTAINER_TAG_LOCAL = 0, // Container is frozen, could only refer to other frozen objects. // Refcounter update is atomics. CONTAINER_TAG_FROZEN = 1 | 1, // shareable // Stack container, no need to free, children cleanup still shall be there. CONTAINER_TAG_STACK = 2, // Atomic container, reference counter is atomically updated. CONTAINER_TAG_SHARED = 3 | 1, // shareable // Shift to get actual counter. CONTAINER_TAG_SHIFT = 2, // Actual value to increment/decrement container by. Tag is in lower bits. CONTAINER_TAG_INCREMENT = 1 << CONTAINER_TAG_SHIFT, // Mask for container type. CONTAINER_TAG_MASK = CONTAINER_TAG_INCREMENT - 1, // Shift to get actual object count, if has it. CONTAINER_TAG_GC_SHIFT = 7, CONTAINER_TAG_GC_MASK = (1 << CONTAINER_TAG_GC_SHIFT) - 1, CONTAINER_TAG_GC_INCREMENT = 1 << CONTAINER_TAG_GC_SHIFT, // Color mask of a container. CONTAINER_TAG_COLOR_SHIFT = 3, CONTAINER_TAG_GC_COLOR_MASK = (1 << CONTAINER_TAG_COLOR_SHIFT) - 1, // Colors. // In use or free. CONTAINER_TAG_GC_BLACK = 0, // Possible member of garbage cycle. CONTAINER_TAG_GC_GRAY = 1, // Member of garbage cycle. CONTAINER_TAG_GC_WHITE = 2, // Possible root of cycle. CONTAINER_TAG_GC_PURPLE = 3, // Acyclic. CONTAINER_TAG_GC_GREEN = 4, // Orange and red are currently unused. // Candidate cycle awaiting epoch. CONTAINER_TAG_GC_ORANGE = 5, // Candidate cycle awaiting sigma computation. CONTAINER_TAG_GC_RED = 6, // Individual state bits used during GC and freezing. CONTAINER_TAG_GC_MARKED = 1 << CONTAINER_TAG_COLOR_SHIFT, CONTAINER_TAG_GC_BUFFERED = 1 << (CONTAINER_TAG_COLOR_SHIFT + 1), CONTAINER_TAG_GC_SEEN = 1 << (CONTAINER_TAG_COLOR_SHIFT + 2), // If indeed has more that one object. CONTAINER_TAG_GC_HAS_OBJECT_COUNT = 1 << (CONTAINER_TAG_COLOR_SHIFT + 3) } ContainerTag; // Header of all container objects. Contains reference counter. struct ContainerHeader { // Reference counter of container. Uses CONTAINER_TAG_SHIFT, lower bits of counter // for container type (for polymorphism in ::Release()). uint32_t refCount_; // Number of objects in the container. uint32_t objectCount_; inline bool local() const { return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_LOCAL; } inline bool frozen() const { return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_FROZEN; } inline void freeze() { refCount_ = (refCount_ & ~CONTAINER_TAG_MASK) | CONTAINER_TAG_FROZEN; } inline void makeShared() { refCount_ = (refCount_ & ~CONTAINER_TAG_MASK) | CONTAINER_TAG_SHARED; } inline bool shared() const { return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_SHARED; } inline bool shareable() const { return (tag() & 1) != 0; // CONTAINER_TAG_FROZEN || CONTAINER_TAG_SHARED } inline bool stack() const { return (refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_STACK; } inline int refCount() const { return (int)refCount_ >> CONTAINER_TAG_SHIFT; } inline void setRefCount(unsigned refCount) { refCount_ = tag() | (refCount << CONTAINER_TAG_SHIFT); } template inline void incRefCount() { #ifdef KONAN_NO_THREADS refCount_ += CONTAINER_TAG_INCREMENT; #else if (Atomic) __sync_add_and_fetch(&refCount_, CONTAINER_TAG_INCREMENT); else refCount_ += CONTAINER_TAG_INCREMENT; #endif } template inline bool tryIncRefCount() { if (Atomic) { while (true) { uint32_t currentRefCount_ = refCount_; if (((int)currentRefCount_ >> CONTAINER_TAG_SHIFT) > 0) { if (compareAndSet(&refCount_, currentRefCount_, currentRefCount_ + CONTAINER_TAG_INCREMENT)) { return true; } } else { return false; } } } else { // Note: tricky case here is doing this during cycle collection. // This can actually happen due to deallocation hooks. // Fortunately by this point reference counts have been made precise again. if (refCount() > 0) { incRefCount(); return true; } else { return false; } } } template inline int decRefCount() { #ifdef KONAN_NO_THREADS int value = refCount_ -= CONTAINER_TAG_INCREMENT; #else int value = Atomic ? __sync_sub_and_fetch(&refCount_, CONTAINER_TAG_INCREMENT) : refCount_ -= CONTAINER_TAG_INCREMENT; #endif return value >> CONTAINER_TAG_SHIFT; } inline int decRefCount() { #ifdef KONAN_NO_THREADS int value = refCount_ -= CONTAINER_TAG_INCREMENT; #else int value = shareable() ? __sync_sub_and_fetch(&refCount_, CONTAINER_TAG_INCREMENT) : refCount_ -= CONTAINER_TAG_INCREMENT; #endif return value >> CONTAINER_TAG_SHIFT; } inline unsigned tag() const { return refCount_ & CONTAINER_TAG_MASK; } inline unsigned objectCount() const { return (objectCount_ & CONTAINER_TAG_GC_HAS_OBJECT_COUNT) != 0 ? (objectCount_ >> CONTAINER_TAG_GC_SHIFT) : 1; } inline void incObjectCount() { RuntimeAssert((objectCount_ & CONTAINER_TAG_GC_HAS_OBJECT_COUNT) != 0, "Must have object count"); objectCount_ += CONTAINER_TAG_GC_INCREMENT; } inline void setObjectCount(int count) { if (count == 1) { objectCount_ &= ~CONTAINER_TAG_GC_HAS_OBJECT_COUNT; } else { objectCount_ = (count << CONTAINER_TAG_GC_SHIFT) | CONTAINER_TAG_GC_HAS_OBJECT_COUNT; } } inline unsigned containerSize() const { RuntimeAssert((objectCount_ & CONTAINER_TAG_GC_HAS_OBJECT_COUNT) == 0, "Must be single-object"); return (objectCount_ >> CONTAINER_TAG_GC_SHIFT); } inline void setContainerSize(unsigned size) { RuntimeAssert((objectCount_ & CONTAINER_TAG_GC_HAS_OBJECT_COUNT) == 0, "Must not have object count"); objectCount_ = (objectCount_ & CONTAINER_TAG_GC_MASK) | (size << CONTAINER_TAG_GC_SHIFT); } inline bool hasContainerSize() { return (objectCount_ & CONTAINER_TAG_GC_HAS_OBJECT_COUNT) == 0; } inline unsigned color() const { return objectCount_ & CONTAINER_TAG_GC_COLOR_MASK; } inline void setColorAssertIfGreen(unsigned color) { RuntimeAssert(this->color() != CONTAINER_TAG_GC_GREEN, "Must not be green"); setColorEvenIfGreen(color); } inline void setColorEvenIfGreen(unsigned color) { // TODO: do we need atomic color update? objectCount_ = (objectCount_ & ~CONTAINER_TAG_GC_COLOR_MASK) | color; } inline void setColorUnlessGreen(unsigned color) { // TODO: do we need atomic color update? unsigned objectCount = objectCount_; if ((objectCount & CONTAINER_TAG_GC_COLOR_MASK) != CONTAINER_TAG_GC_GREEN) objectCount_ = (objectCount & ~CONTAINER_TAG_GC_COLOR_MASK) | color; } inline bool buffered() const { return (objectCount_ & CONTAINER_TAG_GC_BUFFERED) != 0; } inline void setBuffered() { objectCount_ |= CONTAINER_TAG_GC_BUFFERED; } inline void resetBuffered() { objectCount_ &= ~CONTAINER_TAG_GC_BUFFERED; } inline bool marked() const { return (objectCount_ & CONTAINER_TAG_GC_MARKED) != 0; } inline void mark() { objectCount_ |= CONTAINER_TAG_GC_MARKED; } inline void unMark() { objectCount_ &= ~CONTAINER_TAG_GC_MARKED; } inline bool seen() const { return (objectCount_ & CONTAINER_TAG_GC_SEEN) != 0; } inline void setSeen() { objectCount_ |= CONTAINER_TAG_GC_SEEN; } inline void resetSeen() { objectCount_ &= ~CONTAINER_TAG_GC_SEEN; } // Following operations only work on freed container which is in finalization queue. // We cannot use 'this' here, as it conflicts with aliasing analysis in clang. inline void setNextLink(ContainerHeader* next) { *reinterpret_cast(this + 1) = next; } inline ContainerHeader* nextLink() { return *reinterpret_cast(this + 1); } }; ALWAYS_INLINE ContainerHeader* containerFor(const ObjHeader* obj); // Header for the meta-object. struct MetaObjHeader { // Pointer to the type info. Must be first, to match ArrayHeader and ObjHeader layout. const TypeInfo* typeInfo_; // Container pointer. ContainerHeader* container_; #ifdef KONAN_OBJC_INTEROP void* associatedObject_; #endif // Flags for the object state. int32_t flags_; struct { // Strong reference to the counter object. ObjHeader* counter_; } WeakReference; }; extern "C" { #define MODEL_VARIANTS(returnType, name, ...) \ returnType name##Strict(__VA_ARGS__) RUNTIME_NOTHROW; \ returnType name##Relaxed(__VA_ARGS__) RUNTIME_NOTHROW; OBJ_GETTER(AllocInstanceStrict, const TypeInfo* type_info) RUNTIME_NOTHROW; OBJ_GETTER(AllocInstanceRelaxed, const TypeInfo* type_info) RUNTIME_NOTHROW; OBJ_GETTER(AllocArrayInstanceStrict, const TypeInfo* type_info, int32_t elements); OBJ_GETTER(AllocArrayInstanceRelaxed, const TypeInfo* type_info, int32_t elements); OBJ_GETTER(InitThreadLocalSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); OBJ_GETTER(InitThreadLocalSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); OBJ_GETTER(InitSingletonStrict, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); OBJ_GETTER(InitSingletonRelaxed, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); MODEL_VARIANTS(void, SetStackRef, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, SetHeapRef, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, ZeroStackRef, ObjHeader** location); MODEL_VARIANTS(void, UpdateStackRef, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, UpdateHeapRef, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, UpdateHeapRefIfNull, ObjHeader** location, const ObjHeader* object); MODEL_VARIANTS(void, UpdateReturnRef, ObjHeader** returnSlot, const ObjHeader* object); MODEL_VARIANTS(void, UpdateHeapRefsInsideOneArray, const ArrayHeader* array, int fromIndex, int toIndex, int count); MODEL_VARIANTS(void, EnterFrame, ObjHeader** start, int parameters, int count); MODEL_VARIANTS(void, LeaveFrame, ObjHeader** start, int parameters, int count); MODEL_VARIANTS(void, ReleaseHeapRef, const ObjHeader* object); MODEL_VARIANTS(void, ReleaseHeapRefNoCollect, const ObjHeader* object); } // extern "C" #endif // RUNTIME_MEMORYPRIVATE_HPP ================================================ FILE: runtime/src/main/cpp/Alignment.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_ALIGNMENT_H #define RUNTIME_ALIGNMENT_H #include #include namespace kotlin { constexpr size_t kObjectAlignment = 8; constexpr inline size_t AlignUp(size_t size, size_t alignment) { return (size + alignment - 1) & ~(alignment - 1); } inline void* AlignUp(void* ptr, size_t alignment) { static_assert(sizeof(void*) == sizeof(size_t), "size_t size must be equal to pointer size for this to work"); return reinterpret_cast(AlignUp(reinterpret_cast(ptr), alignment)); } constexpr inline bool IsValidAlignment(size_t alignment) { return alignment != 0 && (alignment & (alignment - 1)) == 0; } constexpr inline bool IsAligned(size_t size, size_t alignment) { return size % alignment == 0; } inline bool IsAligned(void* ptr, size_t alignment) { return reinterpret_cast(ptr) % alignment == 0; } } // namespace kotlin #endif // RUNTIME_ALIGNMENT_H ================================================ FILE: runtime/src/main/cpp/AlignmentTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Alignment.hpp" #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Types.h" using namespace kotlin; namespace { template class NamedTestWithParam : public testing::TestWithParam> { public: using Param = std::tuple; static std::string Print(const testing::TestParamInfo& info) { return std::string(std::get<0>(info.param)); } template static const typename std::tuple_element::type& Get() { const auto& param = testing::TestWithParam::GetParam(); return std::get(param); } }; #define INSTANTIATE_NAMED_TEST(testName, ...) INSTANTIATE_TEST_SUITE_P(, testName, testing::Values(__VA_ARGS__), &testName::Print) } // namespace using IsValidAlignmentTest = NamedTestWithParam; TEST_P(IsValidAlignmentTest, Test) { const auto& alignment = Get<0>(); const auto& expected = Get<1>(); EXPECT_THAT(IsValidAlignment(alignment), expected); } INSTANTIATE_NAMED_TEST( IsValidAlignmentTest, std::make_tuple("0", 0, false), std::make_tuple("1", 1, true), std::make_tuple("2", 2, true), std::make_tuple("3", 3, false), std::make_tuple("4", 4, true), std::make_tuple("5", 5, false), std::make_tuple("6", 6, false), std::make_tuple("7", 7, false), std::make_tuple("8", 8, true), std::make_tuple("9", 9, false), std::make_tuple("10", 10, false), std::make_tuple("11", 11, false), std::make_tuple("12", 12, false), std::make_tuple("13", 13, false), std::make_tuple("14", 14, false), std::make_tuple("15", 15, false), std::make_tuple("16", 16, true), std::make_tuple("int", alignof(int), true), std::make_tuple("ptr", alignof(void*), true), std::make_tuple("max", alignof(std::max_align_t), true)); using IsAlignedSizeTest = NamedTestWithParam; TEST_P(IsAlignedSizeTest, Test) { const auto& size = Get<0>(); const auto& alignment = Get<1>(); const auto& expected = Get<2>(); EXPECT_THAT(IsAligned(size, alignment), expected); } INSTANTIATE_NAMED_TEST( IsAlignedSizeTest, std::make_tuple("1_1", 1, 1, true), std::make_tuple("2_1", 2, 1, true), std::make_tuple("3_1", 3, 1, true), std::make_tuple("4_1", 4, 1, true), std::make_tuple("1_2", 1, 2, false), std::make_tuple("2_2", 2, 2, true), std::make_tuple("3_2", 3, 2, false), std::make_tuple("4_2", 4, 2, true)); using IsAlignedPointerTest = NamedTestWithParam; TEST_P(IsAlignedPointerTest, Test) { const auto& ptr = Get<0>(); const auto& alignment = Get<1>(); const auto& expected = Get<2>(); EXPECT_THAT(IsAligned(reinterpret_cast(ptr), alignment), expected); } INSTANTIATE_NAMED_TEST( IsAlignedPointerTest, std::make_tuple("0_1", 0, 1, true), std::make_tuple("1_1", 1, 1, true), std::make_tuple("2_1", 2, 1, true), std::make_tuple("3_1", 3, 1, true), std::make_tuple("4_1", 4, 1, true), std::make_tuple("0_2", 0, 2, true), std::make_tuple("1_2", 1, 2, false), std::make_tuple("2_2", 2, 2, true), std::make_tuple("3_2", 3, 2, false), std::make_tuple("4_2", 4, 2, true)); using AlignUpSizeTest = NamedTestWithParam; TEST_P(AlignUpSizeTest, Test) { const auto& size = Get<0>(); const auto& alignment = Get<1>(); const auto& expected = Get<2>(); EXPECT_THAT(AlignUp(size, alignment), expected); } INSTANTIATE_NAMED_TEST( AlignUpSizeTest, std::make_tuple("1_1", 1, 1, 1), std::make_tuple("2_1", 2, 1, 2), std::make_tuple("3_1", 3, 1, 3), std::make_tuple("4_1", 4, 1, 4), std::make_tuple("1_2", 1, 2, 2), std::make_tuple("2_2", 2, 2, 2), std::make_tuple("3_2", 3, 2, 4), std::make_tuple("4_2", 4, 2, 4)); using AlignUpPointerTest = NamedTestWithParam; TEST_P(AlignUpPointerTest, Test) { const auto& ptr = Get<0>(); const auto& alignment = Get<1>(); const auto& expected = Get<2>(); EXPECT_THAT(AlignUp(reinterpret_cast(ptr), alignment), reinterpret_cast(expected)); } INSTANTIATE_NAMED_TEST( AlignUpPointerTest, std::make_tuple("0_1", 0, 1, 0), std::make_tuple("1_1", 1, 1, 1), std::make_tuple("2_1", 2, 1, 2), std::make_tuple("3_1", 3, 1, 3), std::make_tuple("4_1", 4, 1, 4), std::make_tuple("0_2", 0, 2, 0), std::make_tuple("1_2", 1, 2, 2), std::make_tuple("2_2", 2, 2, 2), std::make_tuple("3_2", 3, 2, 4), std::make_tuple("4_2", 4, 2, 4)); TEST(AlignmentTest, ObjectAlignment) { static_assert(IsValidAlignment(kObjectAlignment), "kObjectAlignment must be a valid alignment"); static_assert(kObjectAlignment % alignof(KLong) == 0, ""); static_assert(kObjectAlignment % alignof(KDouble) == 0, ""); } ================================================ FILE: runtime/src/main/cpp/Alloc.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_ALLOC_H #define RUNTIME_ALLOC_H #include #include #include #include #include "Porting.h" inline void* konanAllocMemory(size_t size) { return konan::calloc(1, size); } inline void* konanAllocAlignedMemory(size_t size, size_t alignment) { return konan::calloc_aligned(1, size, alignment); } inline void konanFreeMemory(void* memory) { konan::free(memory); } template inline T* konanAllocArray(size_t length) { return reinterpret_cast(konanAllocMemory(length * sizeof(T))); } template inline T* konanConstructInstance(A&& ...args) { return new (konanAllocMemory(sizeof(T))) T(::std::forward(args)...); } template inline T* konanConstructSizedInstance(size_t size, A&& ...args) { return new (konanAllocMemory(size)) T(::std::forward(args)...); } template inline void konanDestructInstance(T* instance) { instance->~T(); konanFreeMemory(instance); } template class KonanAllocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; KonanAllocator() {} KonanAllocator(const KonanAllocator&) {} pointer allocate(size_type n, const void * = 0) { return reinterpret_cast(konanAllocMemory(n * sizeof(T))); } void deallocate(void* p, size_type) { if (p != nullptr) konanFreeMemory(p); } pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } KonanAllocator& operator=(const KonanAllocator&) { return *this; } void construct(pointer p, const T& val) { new ((T*) p) T(val); } // C++-11 wants that. template void construct(U* const p, A&& ...args) { new (p) U(::std::forward(args)...); } void destroy(pointer p) { p->~T(); } size_type max_size() const { return size_t(-1); } template struct rebind { typedef KonanAllocator other; }; template KonanAllocator(const KonanAllocator&) {} template KonanAllocator& operator=(const KonanAllocator&) { return *this; } }; template bool operator==( KonanAllocator const&, KonanAllocator const&) noexcept { return true; } template bool operator!=( KonanAllocator const& x, KonanAllocator const& y) noexcept { return !(x == y); } template class KonanDeleter { public: void operator()(T* instance) noexcept { konanDestructInstance(instance); } }; // Force a class to be heap-allocated using `konanAllocMemory`. Does not prevent stack allocation, or // allocation as part of another object. // Usage: // class A : public KonanAllocatorAware { // ... // }; class KonanAllocatorAware { public: static void* operator new(size_t count) noexcept { return konanAllocMemory(count); } static void* operator new[](size_t count) noexcept { return konanAllocMemory(count); } static void* operator new(size_t count, void* ptr) noexcept { return ptr; } static void* operator new[](size_t count, void* ptr) noexcept { return ptr; } static void operator delete(void* ptr) noexcept { konanFreeMemory(ptr); } static void operator delete[](void* ptr) noexcept { konanFreeMemory(ptr); } protected: // Hide constructors, assignments and destructor to discourage operating on instance of `KonanAllocatorAware` KonanAllocatorAware() = default; KonanAllocatorAware(const KonanAllocatorAware&) = default; KonanAllocatorAware(KonanAllocatorAware&&) = default; KonanAllocatorAware& operator=(const KonanAllocatorAware&) = default; KonanAllocatorAware& operator=(KonanAllocatorAware&&) = default; // Not virtual by design. Since this class hides this destructor, no one can destroy an // instance of `KonanAllocatorAware` directly, so this destructor is never called in a virtual manner. ~KonanAllocatorAware() = default; }; #endif // RUNTIME_ALLOC_H ================================================ FILE: runtime/src/main/cpp/AllocTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Alloc.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Types.h" namespace { class A : public KonanAllocatorAware { public: using DestructorHook = testing::StrictMock>; static thread_local DestructorHook* destructorHook; explicit A(int value = -1) : value_(value) {} ~A() { destructorHook->Call(value_); } int value() const { return value_; } bool operator==(const A& rhs) const { return value_ == rhs.value_; } private: int value_; }; // static thread_local A::DestructorHook* A::destructorHook = nullptr; struct B { explicit B(int value) : a(value) {} A a; }; } // namespace class KonanAllocatorAwareTest : public testing::Test { public: KStdUniquePtr destructorHook; void SetUp() override { Test::SetUp(); destructorHook = make_unique(); A::destructorHook = destructorHook.get(); } void TearDown() override { A::destructorHook = nullptr; destructorHook.reset(); Test::TearDown(); } }; TEST_F(KonanAllocatorAwareTest, AllocatedOnStack) { A a(42); EXPECT_THAT(a.value(), 42); EXPECT_CALL(*destructorHook, Call(42)); } TEST_F(KonanAllocatorAwareTest, AllocatedInAnotherObject) { // We do not control how `B` is allocated. B* b = new B(42); EXPECT_THAT(b->a.value(), 42); EXPECT_CALL(*destructorHook, Call(42)); delete b; } TEST_F(KonanAllocatorAwareTest, AllocatedByItself) { A* a = new A(42); EXPECT_THAT(a->value(), 42); EXPECT_CALL(*destructorHook, Call(42)); delete a; } TEST_F(KonanAllocatorAwareTest, AllocateArray) { constexpr size_t kCount = 5; A* as = new A[kCount]; std::vector actual; for (A* a = as; a != as + kCount; ++a) { actual.push_back(a->value()); } std::array expected; for (int& element : expected) { element = -1; } EXPECT_THAT(actual, testing::ElementsAreArray(expected)); EXPECT_CALL(*destructorHook, Call(-1)).Times(kCount); delete[] as; } TEST_F(KonanAllocatorAwareTest, PlacementAllocated) { std::array buffer; A* a = new (buffer.data()) A(42); EXPECT_THAT(a->value(), 42); EXPECT_CALL(*destructorHook, Call(42)); a->~A(); } TEST_F(KonanAllocatorAwareTest, PlacementConstructedArray) { constexpr size_t kCount = 5; // TODO: Consider removing support for placement new[] altogether, since there's no // portable way to know needed storage size ahead of time. alignas(A) std::array buffer; A* as = new (buffer.data()) A[kCount]; std::vector actual; for (A* a = as; a != as + kCount; ++a) { actual.push_back(a->value()); } std::array expected; for (int& element : expected) { element = -1; } EXPECT_THAT(actual, testing::ElementsAreArray(expected)); EXPECT_CALL(*destructorHook, Call(-1)).Times(kCount); for (A* a = as; a != as + kCount; ++a) { a->~A(); } } ================================================ FILE: runtime/src/main/cpp/Arrays.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "KAssert.h" #include "Exceptions.h" #include "Memory.h" #include "Natives.h" #include "Types.h" extern "C" void checkRangeIndexes(KInt from, KInt to, KInt size); namespace { ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) { // TODO: optimize it! if (!thiz->local() && isFrozen(thiz)) { ThrowInvalidMutabilityException(thiz); } } ALWAYS_INLINE inline void boundsCheck(const ArrayHeader* array, KInt index) { // We couldn't have created an array bigger than max KInt value. // So if index is < 0, conversion to an unsigned value would make it bigger // than the array size. if (static_cast(index) >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } } template inline void fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, T value) { ArrayHeader* array = thiz->array(); checkRangeIndexes(fromIndex, toIndex, array->count_); mutabilityCheck(thiz); T* address = PrimitiveArrayAddressOfElementAt(array, fromIndex); for (KInt index = fromIndex; index < toIndex; ++index) { *address++ = value; } } template inline void copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { const ArrayHeader* array = thiz->array(); ArrayHeader* destinationArray = destination->array(); if (count < 0 || fromIndex < 0 || static_cast(count) + fromIndex > array->count_ || toIndex < 0 || static_cast(count) + toIndex > destinationArray->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(destination); memmove(PrimitiveArrayAddressOfElementAt(destinationArray, toIndex), PrimitiveArrayAddressOfElementAt(array, fromIndex), count * sizeof(T)); } template inline void PrimitiveArraySet(KRef thiz, KInt index, T value) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); mutabilityCheck(thiz); *PrimitiveArrayAddressOfElementAt(array, index) = value; } template inline T PrimitiveArrayGet(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); boundsCheck(array, index); return *PrimitiveArrayAddressOfElementAt(array, index); } } // namespace extern "C" { // Generated as part of Kotlin standard library. extern const ObjHeader theEmptyArray; // TODO: those must be compiler intrinsics afterwards. // Array.kt OBJ_GETTER(Kotlin_Array_get, KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); boundsCheck(array, index); RETURN_OBJ(*ArrayAddressOfElementAt(array, index)); } void Kotlin_Array_set(KRef thiz, KInt index, KConstRef value) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); mutabilityCheck(thiz); UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); } KInt Kotlin_Array_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } void Kotlin_Array_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KRef value) { ArrayHeader* array = thiz->array(); checkRangeIndexes(fromIndex, toIndex, array->count_); mutabilityCheck(thiz); for (KInt index = fromIndex; index < toIndex; ++index) { UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); } } void Kotlin_Array_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { const ArrayHeader* array = thiz->array(); ArrayHeader* destinationArray = destination->array(); if (count < 0 || fromIndex < 0 || static_cast(count) + fromIndex > array->count_ || toIndex < 0 || static_cast(count) + toIndex > destinationArray->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(destination); if (CurrentMemoryModel != MemoryModel::kExperimental && array == destinationArray && std::abs(fromIndex - toIndex) < count) { UpdateHeapRefsInsideOneArray(array, fromIndex, toIndex, count); } else { if (fromIndex >= toIndex) { for (int index = 0; index < count; index++) { UpdateHeapRef(ArrayAddressOfElementAt(destinationArray, toIndex + index), *ArrayAddressOfElementAt(array, fromIndex + index)); } } else { for (int index = count - 1; index >= 0; index--) { UpdateHeapRef(ArrayAddressOfElementAt(destinationArray, toIndex + index), *ArrayAddressOfElementAt(array, fromIndex + index)); } } } } // Arrays.kt OBJ_GETTER0(Kotlin_emptyArray) { RETURN_OBJ(const_cast(&theEmptyArray)); } KByte Kotlin_ByteArray_get(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); boundsCheck(array, index); return *ByteArrayAddressOfElementAt(array, index); } void Kotlin_ByteArray_set(KRef thiz, KInt index, KByte value) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); mutabilityCheck(thiz); *ByteArrayAddressOfElementAt(array, index) = value; } KInt Kotlin_ByteArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KChar Kotlin_ByteArray_getCharAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); return (static_cast(address[0]) << 0) | (static_cast(address[1]) << 8); #else auto result = *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); #if __BIG_ENDIAN__ return __builtin_bswap16(result); #else return result; #endif // __BIG_ENDIAN__ #endif // KONAN_NO_UNALIGNED_ACCESS } KShort Kotlin_ByteArray_getShortAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); return (static_cast(address[0]) << 0) | (static_cast(address[1]) << 8); #else auto result = *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); #if __BIG_ENDIAN__ return __builtin_bswap16(result); #else return result; #endif // __BIG_ENDIAN__ #endif // KONAN_NO_UNALIGNED_ACCESS } KInt Kotlin_ByteArray_getIntAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); return (static_cast(address[0]) << 0) | (static_cast(address[1]) << 8) | (static_cast(address[2]) << 16) | (static_cast(address[3]) << 24); #else auto result = *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); #if __BIG_ENDIAN__ return __builtin_bswap32(result); #else return result; #endif // __BIG_ENDIAN__ #endif // KONAN_NO_UNALIGNED_ACCESS } KLong Kotlin_ByteArray_getLongAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); return (static_cast(address[0]) << 0) | (static_cast(address[1]) << 8) | (static_cast(address[2]) << 16) | (static_cast(address[3]) << 24) | (static_cast(address[4]) << 32) | (static_cast(address[5]) << 40) | (static_cast(address[6]) << 48) | (static_cast(address[7]) << 56); #else auto result = *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); #if __BIG_ENDIAN__ return __builtin_bswap64(result); #else return result; #endif // __BIG_ENDIAN__ #endif // KONAN_NO_UNALIGNED_ACCESS } KFloat Kotlin_ByteArray_getFloatAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); union { KFloat f; uint8_t b[4]; } u; #if __BIG_ENDIAN__ u.b[0] = address[3]; u.b[1] = address[2]; u.b[2] = address[1]; u.b[3] = address[0]; #else u.b[0] = address[0]; u.b[1] = address[1]; u.b[2] = address[2]; u.b[3] = address[3]; #endif // __BIG_ENDIAN__ return u.f; #else auto result = *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); return result; #endif // KONAN_NO_UNALIGNED_ACCESS } KDouble Kotlin_ByteArray_getDoubleAt(KConstRef thiz, KInt index) { const ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } #if KONAN_NO_UNALIGNED_ACCESS const uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); union { KDouble d; uint8_t b[8]; } u; #if __BIG_ENDIAN__ u.b[0] = address[7]; u.b[1] = address[6]; u.b[2] = address[5]; u.b[3] = address[4]; u.b[4] = address[3]; u.b[5] = address[2]; u.b[6] = address[1]; u.b[7] = address[0]; #else u.b[0] = address[0]; u.b[1] = address[1]; u.b[2] = address[2]; u.b[3] = address[3]; u.b[4] = address[4]; u.b[5] = address[5]; u.b[6] = address[6]; u.b[7] = address[7]; #endif // __BIG_ENDIAN__ return u.d; #else return *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setCharAt(KRef thiz, KInt index, KChar value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); address[0] = (value >> 0) & 0xff; address[1] = (value >> 8) & 0xff; #else #if __BIG_ENDIAN__ value = __builtin_bswap16(value); #endif // __BIG_ENDIAN__ *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setShortAt(KRef thiz, KInt index, KShort value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 1 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); address[0] = (value >> 0) & 0xff; address[1] = (value >> 8) & 0xff; #else #if __BIG_ENDIAN__ value = __builtin_bswap16(value); #endif *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setIntAt(KRef thiz, KInt index, KInt value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); address[0] = (value >> 0) & 0xff; address[1] = (value >> 8) & 0xff; address[2] = (value >> 16) & 0xff; address[3] = (value >> 24) & 0xff; #else #if __BIG_ENDIAN__ value = __builtin_bswap32(value); #endif // __BIG_ENDIAN__ *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setLongAt(KRef thiz, KInt index, KLong value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); address[0] = (value >> 0) & 0xff; address[1] = (value >> 8) & 0xff; address[2] = (value >> 16) & 0xff; address[3] = (value >> 24) & 0xff; address[4] = (value >> 32) & 0xff; address[5] = (value >> 40) & 0xff; address[6] = (value >> 48) & 0xff; address[7] = (value >> 56) & 0xff; #else #if __BIG_ENDIAN__ value = __builtin_bswap64(value); #endif // __BIG_ENDIAN__ *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setFloatAt(KRef thiz, KInt index, KFloat value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 3 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); union { KFloat f; uint8_t b[4]; } u; u.f = value; address[0] = u.b[0]; address[1] = u.b[1]; address[2] = u.b[2]; address[3] = u.b[3]; #else *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } void Kotlin_ByteArray_setDoubleAt(KRef thiz, KInt index, KDouble value) { ArrayHeader* array = thiz->array(); if (index < 0 || static_cast(index) + 7 >= array->count_) { ThrowArrayIndexOutOfBoundsException(); } mutabilityCheck(thiz); #if KONAN_NO_UNALIGNED_ACCESS uint8_t* address = reinterpret_cast(ByteArrayAddressOfElementAt(array, index)); union { KDouble d; uint8_t b[8]; } u; u.d = value; address[0] = u.b[0]; address[1] = u.b[1]; address[2] = u.b[2]; address[3] = u.b[3]; address[4] = u.b[4]; address[5] = u.b[5]; address[6] = u.b[6]; address[7] = u.b[7]; #else *reinterpret_cast(ByteArrayAddressOfElementAt(array, index)) = value; #endif // KONAN_NO_UNALIGNED_ACCESS } KChar Kotlin_CharArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_CharArray_set(KRef thiz, KInt index, KChar value) { PrimitiveArraySet(thiz, index, value); } OBJ_GETTER(Kotlin_CharArray_copyOf, KConstRef thiz, KInt newSize) { const ArrayHeader* array = thiz->array(); if (newSize < 0) { ThrowIllegalArgumentException(); } ArrayHeader* result = AllocArrayInstance(array->type_info(), newSize, OBJ_RESULT)->array(); KInt toCopy = array->count_ < static_cast(newSize) ? array->count_ : newSize; memcpy( PrimitiveArrayAddressOfElementAt(result, 0), PrimitiveArrayAddressOfElementAt(array, 0), toCopy * sizeof(KChar)); RETURN_OBJ(result->obj()); } KInt Kotlin_CharArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KShort Kotlin_ShortArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_ShortArray_set(KRef thiz, KInt index, KShort value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_ShortArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KInt Kotlin_IntArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_IntArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } void Kotlin_ByteArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KByte value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_ShortArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KShort value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_CharArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KChar value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_IntArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KInt value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_LongArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KLong value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_FloatArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KFloat value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_DoubleArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KDouble value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_BooleanArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KBoolean value) { fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_ShortArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_CharArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_IntArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_LongArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_FloatArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_DoubleArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } void Kotlin_BooleanArray_copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { copyImpl(thiz, fromIndex, destination, toIndex, count); } KLong Kotlin_LongArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_LongArray_set(KRef thiz, KInt index, KLong value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_LongArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KFloat Kotlin_FloatArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_FloatArray_set(KRef thiz, KInt index, KFloat value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_FloatArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KDouble Kotlin_DoubleArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_DoubleArray_set(KRef thiz, KInt index, KDouble value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_DoubleArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KBoolean Kotlin_BooleanArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_BooleanArray_set(KRef thiz, KInt index, KBoolean value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_BooleanArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } KNativePtr Kotlin_NativePtrArray_get(KConstRef thiz, KInt index) { return PrimitiveArrayGet(thiz, index); } void Kotlin_NativePtrArray_set(KRef thiz, KInt index, KNativePtr value) { PrimitiveArraySet(thiz, index, value); } KInt Kotlin_NativePtrArray_getArrayLength(KConstRef thiz) { const ArrayHeader* array = thiz->array(); return array->count_; } OBJ_GETTER(Kotlin_ImmutableBlob_toByteArray, KConstRef thiz, KInt startIndex, KInt endIndex) { const ArrayHeader* array = thiz->array(); if (startIndex < 0 || static_cast(endIndex) > array->count_ || startIndex > endIndex) { ThrowArrayIndexOutOfBoundsException(); } KInt count = endIndex - startIndex; ArrayHeader* result = AllocArrayInstance(theByteArrayTypeInfo, count, OBJ_RESULT)->array(); memcpy(PrimitiveArrayAddressOfElementAt(result, 0), PrimitiveArrayAddressOfElementAt(array, startIndex), count); RETURN_OBJ(result->obj()); } KNativePtr Kotlin_ImmutableBlob_asCPointerImpl(KRef thiz, KInt offset) { ArrayHeader* array = thiz->array(); // We couldn't have created an array bigger than max KInt value. // So if index is < 0, conversion to an unsigned value would make it bigger // than the array size. if (static_cast(offset) > array->count_) { ThrowArrayIndexOutOfBoundsException(); } return PrimitiveArrayAddressOfElementAt(array, offset); } KNativePtr Kotlin_Arrays_getByteArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getCharArrayAddressOfElement (KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return CharArrayAddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getStringAddressOfElement (KRef thiz, KInt index) { return Kotlin_Arrays_getCharArrayAddressOfElement(thiz, index); } KNativePtr Kotlin_Arrays_getShortArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getIntArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getLongArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getFloatArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } KNativePtr Kotlin_Arrays_getDoubleArrayAddressOfElement(KRef thiz, KInt index) { ArrayHeader* array = thiz->array(); boundsCheck(array, index); return AddressOfElementAt(array, index); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Atomic.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Atomic.h" #include "Common.h" #include "Exceptions.h" #include "Memory.h" #include "Types.h" namespace { struct AtomicReferenceLayout { ObjHeader header; KRef value_; KInt lock_; KInt cookie_; }; template struct AtomicPrimitive { ObjHeader header; volatile T value_; }; template inline volatile T* getValueLocation(KRef thiz) { AtomicPrimitive* atomic = reinterpret_cast*>(thiz); return &atomic->value_; } template void setImpl(KRef thiz, T value) { volatile T* location = getValueLocation(thiz); atomicSet(location, value); } template T getImpl(KRef thiz) { volatile T* location = getValueLocation(thiz); return atomicGet(location); } template T addAndGetImpl(KRef thiz, T delta) { volatile T* location = getValueLocation(thiz); return atomicAdd(location, delta); } template T compareAndSwapImpl(KRef thiz, T expectedValue, T newValue) { volatile T* location = getValueLocation(thiz); return compareAndSwap(location, expectedValue, newValue); } template KBoolean compareAndSetImpl(KRef thiz, T expectedValue, T newValue) { volatile T* location = getValueLocation(thiz); return compareAndSet(location, expectedValue, newValue); } inline AtomicReferenceLayout* asAtomicReference(KRef thiz) { return reinterpret_cast(thiz); } } // namespace extern "C" { KInt Kotlin_AtomicInt_addAndGet(KRef thiz, KInt delta) { return addAndGetImpl(thiz, delta); } KInt Kotlin_AtomicInt_compareAndSwap(KRef thiz, KInt expectedValue, KInt newValue) { return compareAndSwapImpl(thiz, expectedValue, newValue); } KBoolean Kotlin_AtomicInt_compareAndSet(KRef thiz, KInt expectedValue, KInt newValue) { return compareAndSetImpl(thiz, expectedValue, newValue); } void Kotlin_AtomicInt_set(KRef thiz, KInt newValue) { setImpl(thiz, newValue); } KInt Kotlin_AtomicInt_get(KRef thiz) { return getImpl(thiz); } KLong Kotlin_AtomicLong_addAndGet(KRef thiz, KLong delta) { return addAndGetImpl(thiz, delta); } #if KONAN_NO_64BIT_ATOMIC static int lock64 = 0; #endif KLong Kotlin_AtomicLong_compareAndSwap(KRef thiz, KLong expectedValue, KLong newValue) { #if KONAN_NO_64BIT_ATOMIC // Potentially huge performance penalty, but correct. while (compareAndSwap(&lock64, 0, 1) != 0); volatile KLong* address = getValueLocation(thiz); KLong old = *address; if (old == expectedValue) { *address = newValue; } compareAndSwap(&lock64, 1, 0); return old; #else return compareAndSwapImpl(thiz, expectedValue, newValue); #endif } KBoolean Kotlin_AtomicLong_compareAndSet(KRef thiz, KLong expectedValue, KLong newValue) { #if KONAN_NO_64BIT_ATOMIC // Potentially huge performance penalty, but correct. KBoolean result = false; while (compareAndSwap(&lock64, 0, 1) != 0); volatile KLong* address = getValueLocation(thiz); KLong old = *address; if (old == expectedValue) { result = true; *address = newValue; } compareAndSwap(&lock64, 1, 0); return result; #else return compareAndSetImpl(thiz, expectedValue, newValue); #endif } void Kotlin_AtomicLong_set(KRef thiz, KLong newValue) { #if KONAN_NO_64BIT_ATOMIC // Potentially huge performance penalty, but correct. while (compareAndSwap(&lock64, 0, 1) != 0); volatile KLong* address = getValueLocation(thiz); *address = newValue; compareAndSwap(&lock64, 1, 0); #else setImpl(thiz, newValue); #endif } KLong Kotlin_AtomicLong_get(KRef thiz) { #if KONAN_NO_64BIT_ATOMIC // Potentially huge performance penalty, but correct. while (compareAndSwap(&lock64, 0, 1) != 0); volatile KLong* address = getValueLocation(thiz); KLong value = *address; compareAndSwap(&lock64, 1, 0); return value; #else return getImpl(thiz); #endif } KNativePtr Kotlin_AtomicNativePtr_compareAndSwap(KRef thiz, KNativePtr expectedValue, KNativePtr newValue) { return compareAndSwapImpl(thiz, expectedValue, newValue); } KBoolean Kotlin_AtomicNativePtr_compareAndSet(KRef thiz, KNativePtr expectedValue, KNativePtr newValue) { return compareAndSetImpl(thiz, expectedValue, newValue); } void Kotlin_AtomicNativePtr_set(KRef thiz, KNativePtr newValue) { setImpl(thiz, newValue); } KNativePtr Kotlin_AtomicNativePtr_get(KRef thiz) { return getImpl(thiz); } void Kotlin_AtomicReference_checkIfFrozen(KRef value) { if (CurrentMemoryModel == MemoryModel::kExperimental) { // TODO: Remove when freezing is implemented. return; } if (value != nullptr && !isPermanentOrFrozen(value)) { ThrowInvalidMutabilityException(value); } } OBJ_GETTER(Kotlin_AtomicReference_compareAndSwap, KRef thiz, KRef expectedValue, KRef newValue) { Kotlin_AtomicReference_checkIfFrozen(newValue); // See Kotlin_AtomicReference_get() for explanations, why locking is needed. AtomicReferenceLayout* ref = asAtomicReference(thiz); RETURN_RESULT_OF(SwapHeapRefLocked, &ref->value_, expectedValue, newValue, &ref->lock_, &ref->cookie_); } KBoolean Kotlin_AtomicReference_compareAndSet(KRef thiz, KRef expectedValue, KRef newValue) { Kotlin_AtomicReference_checkIfFrozen(newValue); // See Kotlin_AtomicReference_get() for explanations, why locking is needed. AtomicReferenceLayout* ref = asAtomicReference(thiz); ObjHolder holder; auto old = SwapHeapRefLocked(&ref->value_, expectedValue, newValue, &ref->lock_, &ref->cookie_, holder.slot()); return old == expectedValue; } void Kotlin_AtomicReference_set(KRef thiz, KRef newValue) { Kotlin_AtomicReference_checkIfFrozen(newValue); AtomicReferenceLayout* ref = asAtomicReference(thiz); SetHeapRefLocked(&ref->value_, newValue, &ref->lock_, &ref->cookie_); } OBJ_GETTER(Kotlin_AtomicReference_get, KRef thiz) { // Here we must take a lock to prevent race when value, while taken here, is CASed and immediately // destroyed by an another thread. AtomicReference no longer holds such an object, so if we got // rescheduled unluckily, between the moment value is read from the field and RC is incremented, // object may go away. AtomicReferenceLayout* ref = asAtomicReference(thiz); RETURN_RESULT_OF(ReadHeapRefLocked, &ref->value_, &ref->lock_, &ref->cookie_); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Atomic.h ================================================ #ifndef RUNTIME_ATOMIC_H #define RUNTIME_ATOMIC_H #include "Common.h" template ALWAYS_INLINE inline T atomicAdd(volatile T* where, T what) { #ifndef KONAN_NO_THREADS return __sync_add_and_fetch(where, what); #else return *where += what; #endif } template ALWAYS_INLINE inline T compareAndSwap(volatile T* where, T expectedValue, T newValue) { #ifndef KONAN_NO_THREADS return __sync_val_compare_and_swap(where, expectedValue, newValue); #else T oldValue = *where; if (oldValue == expectedValue) { *where = newValue; } return oldValue; #endif } template ALWAYS_INLINE inline bool compareAndSet(volatile T* where, T expectedValue, T newValue) { #ifndef KONAN_NO_THREADS return __sync_bool_compare_and_swap(where, expectedValue, newValue); #else T oldValue = *where; if (oldValue == expectedValue) { *where = newValue; return true; } return false; #endif } #pragma clang diagnostic push #if (KONAN_ANDROID || KONAN_IOS || KONAN_WATCHOS || KONAN_LINUX) && (KONAN_ARM32 || KONAN_X86 || KONAN_MIPS32 || KONAN_MIPSEL32) // On 32-bit Android clang generates library calls for "large" atomic operations // and warns about "significant performance penalty". See more details here: // https://github.com/llvm/llvm-project/blob/ce56e1a1cc5714f4af5675dd963cfebed766d9e1/clang/lib/CodeGen/CGAtomic.cpp#L775 // Ignore these warnings: #pragma clang diagnostic ignored "-Watomic-alignment" #endif template ALWAYS_INLINE inline void atomicSet(volatile T* where, T what) { #ifndef KONAN_NO_THREADS __atomic_store(where, &what, __ATOMIC_SEQ_CST); #else *where = what; #endif } template ALWAYS_INLINE inline T atomicGet(volatile T* where) { #ifndef KONAN_NO_THREADS T what; __atomic_load(where, &what, __ATOMIC_SEQ_CST); return what; #else return *where; #endif } #pragma clang diagnostic pop static ALWAYS_INLINE inline void synchronize() { #ifndef KONAN_NO_THREADS __sync_synchronize(); #endif } #endif // RUNTIME_ATOMIC_H ================================================ FILE: runtime/src/main/cpp/Boxing.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Memory.h" #include "Types.h" // C++ part of box caching. template struct KBox { ObjHeader header; const T value; }; // Keep naming of these in sync with codegen part. extern const KBoolean BOOLEAN_RANGE_FROM; extern const KBoolean BOOLEAN_RANGE_TO; extern const KByte BYTE_RANGE_FROM; extern const KByte BYTE_RANGE_TO; extern const KChar CHAR_RANGE_FROM; extern const KChar CHAR_RANGE_TO; extern const KShort SHORT_RANGE_FROM; extern const KShort SHORT_RANGE_TO; extern const KInt INT_RANGE_FROM; extern const KInt INT_RANGE_TO; extern const KLong LONG_RANGE_FROM; extern const KLong LONG_RANGE_TO; extern KBox BOOLEAN_CACHE[]; extern KBox BYTE_CACHE[]; extern KBox CHAR_CACHE[]; extern KBox SHORT_CACHE[]; extern KBox INT_CACHE[]; extern KBox LONG_CACHE[]; namespace { template inline bool isInRange(T value, T from, T to) { return value >= from && value <= to; } template OBJ_GETTER(getCachedBox, T value, KBox cache[], T from) { uint64_t index = value - from; RETURN_OBJ(&cache[index].header); } } // namespace extern "C" { bool inBooleanBoxCache(KBoolean value) { return isInRange(value, BOOLEAN_RANGE_FROM, BOOLEAN_RANGE_TO); } bool inByteBoxCache(KByte value) { return isInRange(value, BYTE_RANGE_FROM, BYTE_RANGE_TO); } bool inCharBoxCache(KChar value) { return isInRange(value, CHAR_RANGE_FROM, CHAR_RANGE_TO); } bool inShortBoxCache(KShort value) { return isInRange(value, SHORT_RANGE_FROM, SHORT_RANGE_TO); } bool inIntBoxCache(KInt value) { return isInRange(value, INT_RANGE_FROM, INT_RANGE_TO); } bool inLongBoxCache(KLong value) { return isInRange(value, LONG_RANGE_FROM, LONG_RANGE_TO); } OBJ_GETTER(getCachedBooleanBox, KBoolean value) { RETURN_RESULT_OF(getCachedBox, value, BOOLEAN_CACHE, BOOLEAN_RANGE_FROM); } OBJ_GETTER(getCachedByteBox, KByte value) { // Remember that KByte can't handle values >= 127 // so it can't be used as indexing type. RETURN_RESULT_OF(getCachedBox, value, BYTE_CACHE, BYTE_RANGE_FROM); } OBJ_GETTER(getCachedCharBox, KChar value) { RETURN_RESULT_OF(getCachedBox, value, CHAR_CACHE, CHAR_RANGE_FROM); } OBJ_GETTER(getCachedShortBox, KShort value) { RETURN_RESULT_OF(getCachedBox, value, SHORT_CACHE, SHORT_RANGE_FROM); } OBJ_GETTER(getCachedIntBox, KInt value) { RETURN_RESULT_OF(getCachedBox, value, INT_CACHE, INT_RANGE_FROM); } OBJ_GETTER(getCachedLongBox, KLong value) { RETURN_RESULT_OF(getCachedBox, value, LONG_CACHE, LONG_RANGE_FROM); } } ================================================ FILE: runtime/src/main/cpp/Cleaner.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Cleaner.h" #include "Memory.h" #include "Runtime.h" #include "Worker.h" // Defined in Cleaner.kt extern "C" void Kotlin_CleanerImpl_shutdownCleanerWorker(KInt, bool); extern "C" KInt Kotlin_CleanerImpl_createCleanerWorker(); namespace { struct CleanerImpl { ObjHeader header; KNativePtr cleanerStablePtr; }; constexpr KInt kCleanerWorkerUninitialized = 0; constexpr KInt kCleanerWorkerInitializing = -1; constexpr KInt kCleanerWorkerShutdown = -2; KInt globalCleanerWorker = kCleanerWorkerUninitialized; void disposeCleaner(CleanerImpl* thiz) { auto worker = atomicGet(&globalCleanerWorker); RuntimeAssert( worker != kCleanerWorkerUninitialized && worker != kCleanerWorkerInitializing, "Cleaner worker must've been initialized by now"); if (worker == kCleanerWorkerShutdown) { if (Kotlin_cleanersLeakCheckerEnabled()) { konan::consoleErrorf( "Cleaner %p was disposed during program exit\n" "Use `Platform.isCleanersLeakCheckerActive = false` to avoid this check.\n", thiz); RuntimeCheck(false, "Terminating now"); } return; } RuntimeAssert(worker > 0, "Cleaner worker must be fully initialized here"); bool result = WorkerSchedule(worker, thiz->cleanerStablePtr); RuntimeAssert(result, "Couldn't find Cleaner worker"); } } // namespace RUNTIME_NOTHROW void DisposeCleaner(KRef thiz) { #if KONAN_NO_EXCEPTIONS disposeCleaner(reinterpret_cast(thiz)); #else try { disposeCleaner(reinterpret_cast(thiz)); } catch (...) { // A trick to terminate with unhandled exception. This will print a stack trace // and write to iOS crash log. std::terminate(); } #endif } void ShutdownCleaners(bool executeScheduledCleaners) { KInt worker = 0; do { worker = atomicGet(&globalCleanerWorker); RuntimeAssert(worker != kCleanerWorkerShutdown, "Cleaner worker must not be shutdown twice"); if (worker == kCleanerWorkerUninitialized) { if (!compareAndSet(&globalCleanerWorker, kCleanerWorkerUninitialized, kCleanerWorkerShutdown)) { // Someone is trying to initialize the worker. Try again. continue; } // worker was never initialized. Just return. return; } if (worker == kCleanerWorkerInitializing) { // Someone is trying to initialize the worker. Try again. continue; } // Worker is in some proper state. break; } while (true); RuntimeAssert(worker > 0, "Cleaner worker must be fully initialized here"); atomicSet(&globalCleanerWorker, kCleanerWorkerShutdown); Kotlin_CleanerImpl_shutdownCleanerWorker(worker, executeScheduledCleaners); WaitNativeWorkerTermination(worker); } extern "C" KInt Kotlin_CleanerImpl_getCleanerWorker() { KInt worker = 0; do { worker = atomicGet(&globalCleanerWorker); RuntimeAssert(worker != kCleanerWorkerShutdown, "Cleaner worker must not have been shutdown"); if (worker == kCleanerWorkerUninitialized) { if (!compareAndSet(&globalCleanerWorker, kCleanerWorkerUninitialized, kCleanerWorkerInitializing)) { // Someone else is trying to initialize the worker. Try again. continue; } worker = Kotlin_CleanerImpl_createCleanerWorker(); if (!compareAndSet(&globalCleanerWorker, kCleanerWorkerInitializing, worker)) { RuntimeCheck(false, "Someone interrupted worker initializing"); } // Worker is initialized. break; } if (worker == kCleanerWorkerInitializing) { // Someone is trying to initialize the worker. Try again. continue; } // Worker is in some proper state. break; } while (true); RuntimeAssert(worker > 0, "Cleaner worker must be fully initialized here"); return worker; } void ResetCleanerWorkerForTests() { atomicSet(&globalCleanerWorker, kCleanerWorkerUninitialized); } ================================================ FILE: runtime/src/main/cpp/Cleaner.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_CLEANER_H #define RUNTIME_CLEANER_H #include "Common.h" #include "Types.h" RUNTIME_NOTHROW void DisposeCleaner(KRef thiz); void ShutdownCleaners(bool executeScheduledCleaners); extern "C" KInt Kotlin_CleanerImpl_getCleanerWorker(); void ResetCleanerWorkerForTests(); #endif // RUNTIME_CLEANER_H ================================================ FILE: runtime/src/main/cpp/CleanerTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Cleaner.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Atomic.h" #include "TestSupport.hpp" #include "TestSupportCompilerGenerated.hpp" #include "Types.h" using testing::_; // TODO: Also test disposal. (This requires extracting Worker interface) TEST(CleanerTest, ConcurrentCreation) { ResetCleanerWorkerForTests(); constexpr int threadCount = kotlin::kDefaultThreadCount; constexpr KInt workerId = 42; auto createCleanerWorkerMock = ScopedCreateCleanerWorkerMock(); EXPECT_CALL(*createCleanerWorkerMock, Call()).Times(1).WillOnce(testing::Return(workerId)); int startedThreads = 0; bool allowRunning = false; KStdVector> futures; for (int i = 0; i < threadCount; ++i) { auto future = std::async(std::launch::async, [&startedThreads, &allowRunning]() { atomicAdd(&startedThreads, 1); while (!atomicGet(&allowRunning)) { } return Kotlin_CleanerImpl_getCleanerWorker(); }); futures.push_back(std::move(future)); } while (atomicGet(&startedThreads) != threadCount) { } atomicSet(&allowRunning, true); KStdVector values; for (auto& future : futures) { values.push_back(future.get()); } ASSERT_THAT(values.size(), threadCount); EXPECT_THAT(values, testing::Each(workerId)); } TEST(CleanerTest, ShutdownWithoutCreation) { ResetCleanerWorkerForTests(); auto createCleanerWorkerMock = ScopedCreateCleanerWorkerMock(); auto shutdownCleanerWorkerMock = ScopedShutdownCleanerWorkerMock(); EXPECT_CALL(*createCleanerWorkerMock, Call()).Times(0); EXPECT_CALL(*shutdownCleanerWorkerMock, Call(_, _)).Times(0); ShutdownCleaners(true); } TEST(CleanerTest, ShutdownWithCreation) { ResetCleanerWorkerForTests(); constexpr KInt workerId = 42; constexpr bool executeScheduledCleaners = true; auto createCleanerWorkerMock = ScopedCreateCleanerWorkerMock(); auto shutdownCleanerWorkerMock = ScopedShutdownCleanerWorkerMock(); EXPECT_CALL(*createCleanerWorkerMock, Call()).WillOnce(testing::Return(workerId)); Kotlin_CleanerImpl_getCleanerWorker(); EXPECT_CALL(*shutdownCleanerWorkerMock, Call(workerId, executeScheduledCleaners)); ShutdownCleaners(executeScheduledCleaners); } ================================================ FILE: runtime/src/main/cpp/Common.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_COMMON_H #define RUNTIME_COMMON_H #define RUNTIME_NOTHROW __attribute__((nothrow)) #define RUNTIME_NORETURN __attribute__((noreturn)) #define RUNTIME_CONST __attribute__((const)) #define RUNTIME_PURE __attribute__((pure)) #define RUNTIME_USED __attribute__((used)) #define RUNTIME_WEAK __attribute__((weak)) #define ALWAYS_INLINE __attribute__((always_inline)) #define NO_INLINE __attribute__((noinline)) #if KONAN_NO_THREADS #define THREAD_LOCAL_VARIABLE #else #define THREAD_LOCAL_VARIABLE __thread #endif #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #if KONAN_OBJC_INTEROP #define KONAN_TYPE_INFO_HAS_WRITABLE_PART 1 #endif #endif // RUNTIME_COMMON_H ================================================ FILE: runtime/src/main/cpp/CompilerExport.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" namespace { template T defaultValue() { return T(); } template void ensureUsed(Ret (*f)(Args...)) { f(defaultValue()...); } } // namespace // This is a hack to force clang to emit possibly unused declarations. // TODO: Make sure this function gets DCE'd in the final binary. // TODO: Should be done with some sort of annotation on the declaration. void EnsureDeclarationsEmitted() { ensureUsed(AllocInstance); ensureUsed(AllocArrayInstance); ensureUsed(InitThreadLocalSingleton); ensureUsed(InitSingleton); ensureUsed(InitAndRegisterGlobal); ensureUsed(UpdateHeapRef); ensureUsed(UpdateStackRef); ensureUsed(UpdateReturnRef); ensureUsed(ZeroHeapRef); ensureUsed(ZeroArrayRefs); ensureUsed(EnterFrame); ensureUsed(LeaveFrame); ensureUsed(AddTLSRecord); ensureUsed(LookupTLS); ensureUsed(MutationCheck); ensureUsed(CheckLifetimesConstraint); ensureUsed(FreezeSubgraph); ensureUsed(FreezeSubgraph); ensureUsed(CheckGlobalsAccessible); ensureUsed(Kotlin_mm_switchThreadStateNative); ensureUsed(Kotlin_mm_switchThreadStateRunnable); ensureUsed(Kotlin_mm_safePointFunctionEpilogue); ensureUsed(Kotlin_mm_safePointWhileLoopBody); ensureUsed(Kotlin_mm_safePointExceptionUnwind); } ================================================ FILE: runtime/src/main/cpp/Console.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "KAssert.h" #include "Memory.h" #include "Natives.h" #include "KString.h" #include "Porting.h" #include "Types.h" #include "Exceptions.h" #include "utf8.h" extern "C" { // io/Console.kt void Kotlin_io_Console_print(KString message) { if (message->type_info() != theStringTypeInfo) { ThrowClassCastException(message->obj(), theStringTypeInfo); } // TODO: system stdout must be aware about UTF-8. const KChar* utf16 = CharArrayAddressOfElementAt(message, 0); KStdString utf8; utf8.reserve(message->count_); // Replace incorrect sequences with a default codepoint (see utf8::with_replacement::default_replacement) utf8::with_replacement::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8)); konan::consoleWriteUtf8(utf8.c_str(), utf8.size()); } void Kotlin_io_Console_println(KString message) { Kotlin_io_Console_print(message); #ifndef KONAN_ANDROID // On Android single print produces logcat entry, so no need in linefeed. Kotlin_io_Console_println0(); #endif } void Kotlin_io_Console_println0() { konan::consoleWriteUtf8("\n", 1); } OBJ_GETTER0(Kotlin_io_Console_readLine) { char data[4096]; if (konan::consoleReadUtf8(data, sizeof(data)) < 0) { RETURN_OBJ(nullptr); } RETURN_RESULT_OF(CreateStringFromCString, data); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/CppSupport.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_CPP_SUPPORT_H #define RUNTIME_CPP_SUPPORT_H // A collection of backported utilities from future C++ versions. namespace kotlin { namespace std_support { } // namespace std_support } // namespace kotlin #endif // RUNTIME_CPP_SUPPORT_H ================================================ FILE: runtime/src/main/cpp/DoubleConversions.h ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_DOUBLECONVERSIONS_H #define RUNTIME_DOUBLECONVERSIONS_H #include "Types.h" namespace { typedef union { KLong l; KDouble d; } DoubleAlias; typedef union { KInt i; KFloat f; } FloatAlias; } inline KDouble bitsToDouble(KLong bits) { DoubleAlias alias; alias.l = bits; return alias.d; } inline KLong doubleToBits(KDouble value) { DoubleAlias alias; alias.d = value; return alias.l; } inline KFloat bitsToFloat(KInt bits) { FloatAlias alias; alias.i = bits; return alias.f; } inline KInt floatToBits(KFloat value) { FloatAlias alias; alias.f = value; return alias.i; } extern "C" KInt doubleUpper(KDouble value); extern "C" KInt doubleLower(KDouble value); #endif // RUNTIME_DOUBLECONVERSIONS_H ================================================ FILE: runtime/src/main/cpp/Exceptions.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #if KONAN_NO_EXCEPTIONS #define OMIT_BACKTRACE 1 #endif #ifndef OMIT_BACKTRACE #if USE_GCC_UNWIND // GCC unwinder for backtrace. #include #else // Glibc backtrace() function. #include #endif #endif // OMIT_BACKTRACE #include "KAssert.h" #include "Exceptions.h" #include "ExecFormat.h" #include "Memory.h" #include "Mutex.hpp" #include "Natives.h" #include "KString.h" #include "SourceInfo.h" #include "Types.h" #include "Utils.hpp" #include "ObjCExceptions.h" namespace { #if USE_GCC_UNWIND struct Backtrace { Backtrace(int count, int skip) : index(0), skipCount(skip) { uint32_t size = count - skipCount; if (size < 0) { size = 0; } auto result = AllocArrayInstance(theNativePtrArrayTypeInfo, size, arrayHolder.slot()); // TODO: throw cached OOME? RuntimeCheck(result != nullptr, "Cannot create backtrace array"); } void setNextElement(_Unwind_Ptr element) { Kotlin_NativePtrArray_set(obj(), index++, (KNativePtr) element); } ObjHeader* obj() { return arrayHolder.obj(); } int index; int skipCount; ObjHolder arrayHolder; }; _Unwind_Reason_Code depthCountCallback( struct _Unwind_Context * context, void* arg) { int* result = reinterpret_cast(arg); (*result)++; return _URC_NO_REASON; } _Unwind_Reason_Code unwindCallback( struct _Unwind_Context* context, void* arg) { Backtrace* backtrace = reinterpret_cast(arg); if (backtrace->skipCount > 0) { backtrace->skipCount--; return _URC_NO_REASON; } #if (__MINGW32__ || __MINGW64__) _Unwind_Ptr address = _Unwind_GetRegionStart(context); #else _Unwind_Ptr address = _Unwind_GetIP(context); #endif backtrace->setNextElement(address); return _URC_NO_REASON; } #endif THREAD_LOCAL_VARIABLE bool disallowSourceInfo = false; #if !OMIT_BACKTRACE && !USE_GCC_UNWIND SourceInfo getSourceInfo(KConstRef stackTrace, int index) { return disallowSourceInfo ? SourceInfo { .fileName = nullptr, .lineNumber = -1, .column = -1 } : Kotlin_getSourceInfo(*PrimitiveArrayAddressOfElementAt(stackTrace->array(), index)); } #endif } // namespace // TODO: this implementation is just a hack, e.g. the result is inexact; // however it is better to have an inexact stacktrace than not to have any. NO_INLINE OBJ_GETTER0(Kotlin_getCurrentStackTrace) { #if OMIT_BACKTRACE return AllocArrayInstance(theNativePtrArrayTypeInfo, 0, OBJ_RESULT); #else // Skips first 2 elements as irrelevant: this function and primary Throwable constructor. constexpr int kSkipFrames = 2; #if USE_GCC_UNWIND int depth = 0; _Unwind_Backtrace(depthCountCallback, &depth); Backtrace result(depth, kSkipFrames); if (result.obj()->array()->count_ > 0) { _Unwind_Backtrace(unwindCallback, &result); } RETURN_OBJ(result.obj()); #else const int maxSize = 32; void* buffer[maxSize]; int size = backtrace(buffer, maxSize); if (size < kSkipFrames) return AllocArrayInstance(theNativePtrArrayTypeInfo, 0, OBJ_RESULT); ObjHolder resultHolder; ObjHeader* result = AllocArrayInstance(theNativePtrArrayTypeInfo, size - kSkipFrames, resultHolder.slot()); for (int index = kSkipFrames; index < size; ++index) { Kotlin_NativePtrArray_set(result, index - kSkipFrames, buffer[index]); } RETURN_OBJ(result); #endif #endif // !OMIT_BACKTRACE } OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace) { #if OMIT_BACKTRACE ObjHeader* result = AllocArrayInstance(theArrayTypeInfo, 1, OBJ_RESULT); ObjHolder holder; CreateStringFromCString("", holder.slot()); UpdateHeapRef(ArrayAddressOfElementAt(result->array(), 0), holder.obj()); return result; #else uint32_t size = stackTrace->array()->count_; ObjHolder resultHolder; ObjHeader* strings = AllocArrayInstance(theArrayTypeInfo, size, resultHolder.slot()); #if USE_GCC_UNWIND for (uint32_t index = 0; index < size; ++index) { KNativePtr address = Kotlin_NativePtrArray_get(stackTrace, index); char symbol[512]; if (!AddressToSymbol((const void*) address, symbol, sizeof(symbol))) { // Make empty string: symbol[0] = '\0'; } char line[512]; konan::snprintf(line, sizeof(line) - 1, "%s (%p)", symbol, (void*)(intptr_t)address); ObjHolder holder; CreateStringFromCString(line, holder.slot()); UpdateHeapRef(ArrayAddressOfElementAt(strings->array(), index), holder.obj()); } #else if (size > 0) { char **symbols = backtrace_symbols(PrimitiveArrayAddressOfElementAt(stackTrace->array(), 0), size); RuntimeCheck(symbols != nullptr, "Not enough memory to retrieve the stacktrace"); for (uint32_t index = 0; index < size; ++index) { auto sourceInfo = getSourceInfo(stackTrace, index); const char* symbol = symbols[index]; const char* result; char line[1024]; if (sourceInfo.fileName != nullptr) { if (sourceInfo.lineNumber != -1) { konan::snprintf(line, sizeof(line) - 1, "%s (%s:%d:%d)", symbol, sourceInfo.fileName, sourceInfo.lineNumber, sourceInfo.column); } else { konan::snprintf(line, sizeof(line) - 1, "%s (%s:)", symbol, sourceInfo.fileName); } result = line; } else { result = symbol; } ObjHolder holder; CreateStringFromCString(result, holder.slot()); UpdateHeapRef(ArrayAddressOfElementAt(strings->array(), index), holder.obj()); } // Not konan::free. Used to free memory allocated in backtrace_symbols where malloc is used. free(symbols); } #endif RETURN_OBJ(strings); #endif // !OMIT_BACKTRACE } void ThrowException(KRef exception) { RuntimeAssert(exception != nullptr && IsInstance(exception, theThrowableTypeInfo), "Throwing something non-throwable"); #if KONAN_NO_EXCEPTIONS PrintThrowable(exception); RuntimeCheck(false, "Exceptions unsupported"); #else ExceptionObjHolder::Throw(exception); #endif } namespace { class { /** * Timeout 5 sec for concurrent (second) terminate attempt to give a chance the first one to finish. * If the terminate handler hangs for 5 sec it is probably fatally broken, so let's do abnormal _Exit in that case. */ unsigned int timeoutSec = 5; int terminatingFlag = 0; public: template RUNTIME_NORETURN void operator()(Fun block) { if (compareAndSet(&terminatingFlag, 0, 1)) { block(); // block() is supposed to be NORETURN, otherwise go to normal abort() konan::abort(); } else { sleep(timeoutSec); // We come here when another terminate handler hangs for 5 sec, that looks fatally broken. Go to forced exit now. } _Exit(EXIT_FAILURE); // force exit } } concurrentTerminateWrapper; //! Process exception hook (if any) or just printStackTrace + write crash log void processUnhandledKotlinException(KRef throwable) { OnUnhandledException(throwable); #if KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG ReportBacktraceToIosCrashLog(throwable); #endif } } // namespace RUNTIME_NORETURN void TerminateWithUnhandledException(KRef throwable) { concurrentTerminateWrapper([=]() { processUnhandledKotlinException(throwable); konan::abort(); }); } ALWAYS_INLINE RUNTIME_NOTHROW OBJ_GETTER(Kotlin_getExceptionObject, void* holder) { #if !KONAN_NO_EXCEPTIONS RETURN_OBJ(static_cast(holder)->GetExceptionObject()); #else RETURN_OBJ(nullptr); #endif } #if !KONAN_NO_EXCEPTIONS namespace { // Copy, move and assign would be safe, but not much useful, so let's delete all (rule of 5) class TerminateHandler : private kotlin::Pinned { // In fact, it's safe to call my_handler directly from outside: it will do the job and then invoke original handler, // even if it has not been initialized yet. So one may want to make it public and/or not the class member RUNTIME_NORETURN static void kotlinHandler() { concurrentTerminateWrapper([]() { if (auto currentException = std::current_exception()) { try { std::rethrow_exception(currentException); } catch (ExceptionObjHolder& e) { processUnhandledKotlinException(e.GetExceptionObject()); konan::abort(); } catch (...) { // Not a Kotlin exception - call default handler instance().queuedHandler_(); } } // Come here in case of direct terminate() call or unknown exception - go to default terminate handler. instance().queuedHandler_(); }); } using QH = __attribute__((noreturn)) void(*)(); QH queuedHandler_; /// Use machinery like Meyers singleton to provide thread safety TerminateHandler() : queuedHandler_((QH)std::set_terminate(kotlinHandler)) {} static TerminateHandler& instance() { static TerminateHandler singleton [[clang::no_destroy]]; return singleton; } // Dtor might be in use to restore original handler. However, consequent install // will not reconstruct handler anyway, so let's keep dtor deleted to avoid confusion. ~TerminateHandler() = delete; public: /// First call will do the job, all consequent will do nothing. static void install() { instance(); // Use side effect of warming up } }; } // anon namespace // Use one public function to limit access to the class declaration void SetKonanTerminateHandler() { TerminateHandler::install(); } #else // !KONAN_NO_EXCEPTIONS void SetKonanTerminateHandler() { // Nothing to do. } #endif // !KONAN_NO_EXCEPTIONS void DisallowSourceInfo() { disallowSourceInfo = true; } ================================================ FILE: runtime/src/main/cpp/Exceptions.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_EXCEPTIONS_H #define RUNTIME_EXCEPTIONS_H #include "Types.h" #ifdef __cplusplus extern "C" { #endif // Returns current stacktrace as Array. OBJ_GETTER0(Kotlin_getCurrentStackTrace); OBJ_GETTER(GetStackTraceStrings, KConstRef stackTrace); // Throws arbitrary exception. void ThrowException(KRef exception); // RuntimeUtils.kt void OnUnhandledException(KRef throwable); RUNTIME_NORETURN void TerminateWithUnhandledException(KRef exception); void SetKonanTerminateHandler(); RUNTIME_NOTHROW OBJ_GETTER(Kotlin_getExceptionObject, void* holder); // The functions below are implemented in Kotlin (at package kotlin.native.internal). // Throws null pointer exception. Context is evaluated from caller's address. void RUNTIME_NORETURN ThrowNullPointerException(); // Throws array index out of bounds exception. // Context is evaluated from caller's address. void RUNTIME_NORETURN ThrowArrayIndexOutOfBoundsException(); // Throws class cast exception. void RUNTIME_NORETURN ThrowClassCastException(const ObjHeader* instance, const TypeInfo* type_info); // Throws arithmetic exception. void RUNTIME_NORETURN ThrowArithmeticException(); // Throws number format exception. void RUNTIME_NORETURN ThrowNumberFormatException(); // Throws out of memory error. void RUNTIME_NORETURN ThrowOutOfMemoryError(); // Throws not implemented error. void RUNTIME_NORETURN ThrowNotImplementedError(); // Throws character coding exception (used in UTF8/UTF16 conversions). void RUNTIME_NORETURN ThrowCharacterCodingException(); void RUNTIME_NORETURN ThrowIllegalArgumentException(); void RUNTIME_NORETURN ThrowIllegalStateException(); void RUNTIME_NORETURN ThrowInvalidMutabilityException(KConstRef where); void RUNTIME_NORETURN ThrowIncorrectDereferenceException(); void RUNTIME_NORETURN ThrowIllegalObjectSharingException(KConstNativePtr typeInfo, KConstNativePtr address); void RUNTIME_NORETURN ThrowFreezingException(KRef toFreeze, KRef blocker); // Prints out message of Throwable. void PrintThrowable(KRef); #ifdef __cplusplus } // extern "C" #endif // It's not always safe to extract SourceInfo during unhandled exception termination. void DisallowSourceInfo(); #endif // RUNTIME_NAMES_H ================================================ FILE: runtime/src/main/cpp/ExecFormat.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ExecFormat.h" #include "Types.h" #if USE_ELF_SYMBOLS #include #include #include #include #include #include #include #include #include #include "KAssert.h" namespace { #if !defined(ELFSIZE) #error "Define ELFSIZE to 32 or 64" #endif #if ELFSIZE == 32 #define Elf_Ehdr Elf32_Ehdr #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #elif ELFSIZE == 64 #define Elf_Ehdr Elf64_Ehdr #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #else #error "Impossible ELFSIZE" #endif struct SymRecord { Elf_Sym* symtabBegin; Elf_Sym* symtabEnd; char* strtab; }; typedef KStdVector SymRecordList; SymRecordList* symbols = nullptr; // Unfortunately, symbol tables are stored in ELF sections not mapped // during regular execution, so we have to map binary ourselves. Elf_Ehdr* findElfHeader() { int fd = open("/proc/self/exe", O_RDONLY); if (fd < 0) return nullptr; struct stat fd_stat; if (fstat(fd, &fd_stat) < 0) return nullptr; void* result = mmap(nullptr, fd_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (result == MAP_FAILED) return nullptr; return (Elf_Ehdr*)result; } void initSymbols() { RuntimeAssert(symbols == nullptr, "Init twice"); symbols = konanConstructInstance(); Elf_Ehdr* ehdr = findElfHeader(); if (ehdr == nullptr) return; RuntimeAssert(strncmp((const char*)ehdr->e_ident, ELFMAG, SELFMAG) == 0, "Must be an ELF"); char* mapAddress = (char*)ehdr; Elf_Shdr* shdr = (Elf_Shdr*)(mapAddress + ehdr->e_shoff); for (int i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB) { // Static symbol table. SymRecord record; record.symtabBegin = (Elf_Sym*)(mapAddress + shdr[i].sh_offset); record.symtabEnd = (Elf_Sym*)((char*)record.symtabBegin + shdr[i].sh_size); record.strtab = (char *)(mapAddress + shdr[shdr[i].sh_link].sh_offset); symbols->push_back(record); } if (shdr[i].sh_type == SHT_DYNSYM) { // Dynamic symbol table. SymRecord record; record.symtabBegin = (Elf_Sym*)(mapAddress + shdr[i].sh_offset); record.symtabEnd = (Elf_Sym*)((char*)record.symtabBegin + shdr[i].sh_size); record.strtab = (char*)(mapAddress + shdr[shdr[i].sh_link].sh_offset); symbols->push_back(record); } } } const char* addressToSymbol(const void* address) { if (address == nullptr) return nullptr; // First, look up in dynamically loaded symbols. Dl_info info; if (dladdr(address, &info) != 0 && info.dli_sname != nullptr) { return info.dli_sname; } // Otherwise, consult symbol table of the file. if (symbols == nullptr) { initSymbols(); } unsigned long addressValue = (unsigned long)address; for (auto record : *symbols) { auto begin = record.symtabBegin; auto end = record.symtabEnd; while (begin < end) { // st_value is load address adjusted. if (addressValue >= begin->st_value && addressValue < begin->st_value + begin->st_size) { return &record.strtab[begin->st_name]; } begin++; } } return nullptr; } } // namespace extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t resultBufferSize) { const char* result = addressToSymbol(address); if (result == nullptr) { return false; } else { strncpy(resultBuffer, result, resultBufferSize); resultBuffer[resultBufferSize - 1] = '\0'; return true; } } #elif USE_PE_COFF_SYMBOLS #include #include #include #include "KAssert.h" namespace { static void* mapModuleFile(HMODULE hModule) { DWORD bufferLength = 64; wchar_t* buffer = nullptr; for (;;) { auto newBuffer = (wchar_t*)konanAllocMemory(sizeof(wchar_t) * bufferLength); RuntimeAssert(newBuffer != nullptr, "Out of memory"); if (buffer != nullptr) { konanFreeMemory(buffer); } buffer = newBuffer; DWORD res = GetModuleFileNameW(hModule, buffer, bufferLength); if (res != 0 && res < bufferLength) { break; } const int MAX_BUFFER_SIZE = 32768; // Max path length + 1. if (res == bufferLength && bufferLength < MAX_BUFFER_SIZE) { // Buffer is too small, continue: bufferLength *= 2; continue; } // Invalid result. konanFreeMemory(buffer); return nullptr; } HANDLE hFile = CreateFileW( /* lpFileName = */ buffer, /* dwDesiredAccess = */ GENERIC_READ, /* dwShareMode = */ FILE_SHARE_READ, /* lpSecurityAttributes = */ nullptr, /* dwCreationDisposition = */ OPEN_EXISTING, /* dwFlagsAndAttributes = */ FILE_ATTRIBUTE_NORMAL, /* hTemplateFile = */ nullptr ); konanFreeMemory(buffer); if (hFile == INVALID_HANDLE_VALUE) { // Can't open module file. return nullptr; } HANDLE hFileMappingObject = CreateFileMapping( hFile, /* lpAttributes = */ nullptr, /* flProtect = */ PAGE_READONLY, /* dwMaximumSizeHigh = */ 0, /* dwMaximumSizeLow = */ 0, /* lpName = */ nullptr ); if (hFileMappingObject == nullptr) { // Can't create file mapping. CloseHandle(hFile); return nullptr; } LPVOID mapAddress = MapViewOfFile( hFileMappingObject, /* dwDesiredAccess = */ FILE_MAP_READ, /* dwFileOffsetHigh = */ 0, /* dwFileOffsetLow = */ 0, /* dwNumberOfBytesToMap = */ 0 ); if (mapAddress == nullptr) { // Failed to create map view. CloseHandle(hFileMappingObject); CloseHandle(hFile); return nullptr; } return mapAddress; } class SymbolTable { private: char* imageBase = nullptr; IMAGE_SECTION_HEADER* sectionHeaders = nullptr; IMAGE_SYMBOL* symbols = nullptr; DWORD numberOfSymbols = 0; // Note: it doesn't free resources yet. ~SymbolTable() {} static const int SYMBOL_SHORT_NAME_LENGTH = 8; void getSymbolName(IMAGE_SYMBOL* sym, char* resultBuffer, size_t resultBufferSize) { if (sym->N.Name.Short != 0) { // ShortName is not zero-terminated if its length exactly equals SYMBOL_SHORT_NAME_LENGTH. // Copy it to the buffer and zero-terminate explicitly: size_t bytesToCopy = SYMBOL_SHORT_NAME_LENGTH; if (bytesToCopy > resultBufferSize - 1) bytesToCopy = resultBufferSize - 1; memcpy(resultBuffer, sym->N.ShortName, bytesToCopy); resultBuffer[bytesToCopy] = '\0'; } else { const char* strTable = (const char*)(symbols + numberOfSymbols); const char* result = strTable + sym->N.Name.Long; strncpy(resultBuffer, result, resultBufferSize); resultBuffer[resultBufferSize - 1] = '\0'; } } const void* getSymbolAddress(IMAGE_SYMBOL* symbol) { IMAGE_SECTION_HEADER* sectionHeader = §ionHeaders[symbol->SectionNumber - 1]; return (const void*)(imageBase + sectionHeader->VirtualAddress + symbol->Value); } IMAGE_SYMBOL* findFunctionSymbol(const void* address) { for (DWORD i = 0; i < numberOfSymbols; ++i) { IMAGE_SYMBOL* symbol = &symbols[i]; if (symbol->Type == 0x20 && address == getSymbolAddress(symbol)) { return symbol; } } return nullptr; } public: explicit SymbolTable(HMODULE hModule) { imageBase = (char*)hModule; IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)imageBase; RuntimeAssert(dosHeader->e_magic == IMAGE_DOS_SIGNATURE, "PE executable e_magic mismatch"); IMAGE_NT_HEADERS* ntHeaders = (IMAGE_NT_HEADERS*)(imageBase + dosHeader->e_lfanew); RuntimeAssert(ntHeaders->Signature == IMAGE_NT_SIGNATURE, "PE executable NT signature mismatch"); IMAGE_FILE_HEADER* fileHeader = &ntHeaders->FileHeader; sectionHeaders = (IMAGE_SECTION_HEADER*)(((char*)(fileHeader + 1)) + fileHeader->SizeOfOptionalHeader); if (fileHeader->PointerToSymbolTable == 0 || fileHeader->NumberOfSymbols == 0) { // No symbols. return; } // Symbol table doesn't get mapped to the memory, so we have to load it ourselves: char* mappedModuleFile = (char*)mapModuleFile(hModule); if (mappedModuleFile != nullptr) { symbols = (IMAGE_SYMBOL*)(mappedModuleFile + fileHeader->PointerToSymbolTable); numberOfSymbols = fileHeader->NumberOfSymbols; } } bool functionAddressToSymbol(const void* address, char* resultBuffer, size_t resultBufferSize) { IMAGE_SYMBOL* symbol = findFunctionSymbol(address); if (symbol == nullptr) { return false; } else { getSymbolName(symbol, resultBuffer, resultBufferSize); return true; } } }; SymbolTable* theExeSymbolTable = nullptr; } // namespace extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t resultBufferSize) { if (theExeSymbolTable == nullptr) { // Note: do not protecting the lazy initialization by critical sections for simplicity; // this doesn't have any serious consequences. HMODULE hModule = nullptr; int rv = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(&AddressToSymbol), &hModule); RuntimeAssert(rv != 0, "GetModuleHandleExW fails"); theExeSymbolTable = konanConstructInstance(hModule); } return theExeSymbolTable->functionAddressToSymbol(address, resultBuffer, resultBufferSize); } #else extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t resultBufferSize) { return false; } #endif // USE_ELF_SYMBOLS ================================================ FILE: runtime/src/main/cpp/ExecFormat.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_EXECFORMAT_H #define RUNTIME_EXECFORMAT_H #include extern "C" { bool AddressToSymbol(const void* address, char* resultBuffer, size_t resultBufferSize); } // extern "C" #endif // RUNTIME_EXECFORMAT_H ================================================ FILE: runtime/src/main/cpp/FinalizerHooks.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FinalizerHooks.hpp" #include "Cleaner.h" #include "Memory.h" #include "Types.h" #include "WorkerBoundReference.h" using namespace kotlin; namespace { void (*g_hookOverrideForTesting)(ObjHeader*) = nullptr; // Not inlining this call as it affects deallocation performance for // all types. NO_INLINE void RunFinalizerHooksImpl(ObjHeader* object, const TypeInfo* type) noexcept { if (g_hookOverrideForTesting != nullptr) { g_hookOverrideForTesting(object); return; } // TODO: Consider some global registration. if (type == theCleanerImplTypeInfo) { DisposeCleaner(object); } else if (type == theWorkerBoundReferenceTypeInfo) { DisposeWorkerBoundReference(object); } } } // namespace ALWAYS_INLINE bool kotlin::HasFinalizers(ObjHeader* object) noexcept { return object->has_meta_object() || (object->type_info()->flags_ & TF_HAS_FINALIZER) != 0; } ALWAYS_INLINE void kotlin::RunFinalizers(ObjHeader* object) noexcept { auto* type = object->type_info(); if ((type->flags_ & TF_HAS_FINALIZER) != 0) { // This is a cold path. RunFinalizerHooksImpl(object, type); } if (object->has_meta_object()) { ObjHeader::destroyMetaObject(object); } } void kotlin::SetFinalizerHookForTesting(void (*hook)(ObjHeader*)) noexcept { g_hookOverrideForTesting = hook; } ================================================ FILE: runtime/src/main/cpp/FinalizerHooks.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_FINALIZER_HOOKS_H #define RUNTIME_MM_FINALIZER_HOOKS_H struct ObjHeader; namespace kotlin { bool HasFinalizers(ObjHeader* object) noexcept; void RunFinalizers(ObjHeader* object) noexcept; void SetFinalizerHookForTesting(void (*hook)(ObjHeader*)) noexcept; } // namespace kotlin #endif // RUNTIME_MM_FINALIZER_HOOKS_H ================================================ FILE: runtime/src/main/cpp/FinalizerHooksTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FinalizerHooks.hpp" #include "gtest/gtest.h" #include "gmock/gmock.h" #include "FinalizerHooksTestSupport.hpp" #include "Memory.h" using namespace kotlin; using ::testing::_; namespace { class FinalizerHooksTest : public testing::Test { public: testing::MockFunction& finalizerHook() { return finalizerHooks_.finalizerHook(); } private: FinalizerHooksTestSupport finalizerHooks_; }; } // namespace TEST_F(FinalizerHooksTest, TypeWithFinalizerHookWithoutExtra) { TypeInfo type; type.typeInfo_ = &type; type.flags_ |= TF_HAS_FINALIZER; ObjHeader obj = {&type}; ASSERT_FALSE(obj.has_meta_object()); EXPECT_TRUE(HasFinalizers(&obj)); EXPECT_CALL(finalizerHook(), Call(&obj)); RunFinalizers(&obj); EXPECT_FALSE(obj.has_meta_object()); } TEST_F(FinalizerHooksTest, TypeWithFinalizerHookWithExtra) { TypeInfo type; type.typeInfo_ = &type; type.flags_ |= TF_HAS_FINALIZER; ObjHeader obj = {&type}; ObjHeader::createMetaObject(&obj); ASSERT_TRUE(obj.has_meta_object()); EXPECT_TRUE(HasFinalizers(&obj)); EXPECT_CALL(finalizerHook(), Call(&obj)); RunFinalizers(&obj); EXPECT_FALSE(obj.has_meta_object()); } TEST_F(FinalizerHooksTest, TypeWithoutFinalizerHookWithoutExtra) { TypeInfo type; type.typeInfo_ = &type; type.flags_ &= ~TF_HAS_FINALIZER; ObjHeader obj = {&type}; ASSERT_FALSE(obj.has_meta_object()); EXPECT_FALSE(HasFinalizers(&obj)); EXPECT_CALL(finalizerHook(), Call(_)).Times(0); RunFinalizers(&obj); EXPECT_FALSE(obj.has_meta_object()); } TEST_F(FinalizerHooksTest, TypeWithoutFinalizerHookWithExtra) { TypeInfo type; type.typeInfo_ = &type; type.flags_ &= ~TF_HAS_FINALIZER; ObjHeader obj = {&type}; ObjHeader::createMetaObject(&obj); ASSERT_TRUE(obj.has_meta_object()); EXPECT_TRUE(HasFinalizers(&obj)); EXPECT_CALL(finalizerHook(), Call(_)).Times(0); RunFinalizers(&obj); EXPECT_FALSE(obj.has_meta_object()); } ================================================ FILE: runtime/src/main/cpp/FinalizerHooksTestSupport.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FinalizerHooksTestSupport.hpp" #include "FinalizerHooks.hpp" using namespace kotlin; namespace { testing::MockFunction* g_finalizerHook = nullptr; void finalizerHook(ObjHeader* object) { g_finalizerHook->Call(object); } } // namespace kotlin::FinalizerHooksTestSupport::FinalizerHooksTestSupport() { g_finalizerHook = &finalizerHook_; SetFinalizerHookForTesting(&::finalizerHook); } kotlin::FinalizerHooksTestSupport::~FinalizerHooksTestSupport() { SetFinalizerHookForTesting(nullptr); g_finalizerHook = nullptr; } ================================================ FILE: runtime/src/main/cpp/FinalizerHooksTestSupport.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_FINALIZER_HOOKS_TEST_SUPPORT_H #define RUNTIME_MM_FINALIZER_HOOKS_TEST_SUPPORT_H #include "gtest/gtest.h" #include "gmock/gmock.h" struct ObjHeader; namespace kotlin { class FinalizerHooksTestSupport { public: FinalizerHooksTestSupport(); ~FinalizerHooksTestSupport(); testing::MockFunction& finalizerHook() { return finalizerHook_; } private: testing::StrictMock> finalizerHook_; }; } // namespace kotlin #endif // RUNTIME_MM_FINALIZER_HOOKS_TEST_SUPPORT_H ================================================ FILE: runtime/src/main/cpp/FreezeHooks.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FreezeHooks.hpp" #include "Memory.h" #include "Types.h" #include "WorkerBoundReference.h" using namespace kotlin; namespace { void (*g_hookOverrideForTesting)(ObjHeader*) = nullptr; NO_INLINE void RunFreezeHooksImpl(ObjHeader* object, const TypeInfo* type) noexcept { if (g_hookOverrideForTesting != nullptr) { g_hookOverrideForTesting(object); return; } // TODO: Consider some global registration. if (type == theWorkerBoundReferenceTypeInfo) { WorkerBoundReferenceFreezeHook(object); } } } // namespace void kotlin::RunFreezeHooks(ObjHeader* object) noexcept { auto* type = object->type_info(); if ((type->flags_ & TF_HAS_FREEZE_HOOK) == 0) { return; } // This is a cold path. RunFreezeHooksImpl(object, type); } void kotlin::SetFreezeHookForTesting(void (*hook)(ObjHeader*)) noexcept { g_hookOverrideForTesting = hook; } ================================================ FILE: runtime/src/main/cpp/FreezeHooks.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_FREEZE_HOOKS_H #define RUNTIME_MM_FREEZE_HOOKS_H struct ObjHeader; struct TypeInfo; namespace kotlin { // These hooks are only allowed to modify `object` subgraph. void RunFreezeHooks(ObjHeader* object) noexcept; void SetFreezeHookForTesting(void (*hook)(ObjHeader*)) noexcept; } // namespace kotlin #endif // RUNTIME_MM_FREEZE_HOOKS_H ================================================ FILE: runtime/src/main/cpp/FreezeHooksTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FreezeHooks.hpp" #include "gtest/gtest.h" #include "gmock/gmock.h" #include "FreezeHooksTestSupport.hpp" #include "Memory.h" using namespace kotlin; using ::testing::_; namespace { class FreezeHooksTest : public testing::Test { public: testing::MockFunction& freezeHook() { return freezeHooks_.freezeHook(); } private: FreezeHooksTestSupport freezeHooks_; }; } // namespace TEST_F(FreezeHooksTest, TypeWithFreezeHook) { TypeInfo type; type.typeInfo_ = &type; type.flags_ |= TF_HAS_FREEZE_HOOK; ObjHeader obj = {&type}; EXPECT_CALL(freezeHook(), Call(&obj)); RunFreezeHooks(&obj); } TEST_F(FreezeHooksTest, TypeWithoutFreezeHook) { TypeInfo type; type.typeInfo_ = &type; type.flags_ &= ~TF_HAS_FREEZE_HOOK; ObjHeader obj = {&type}; EXPECT_CALL(freezeHook(), Call(_)).Times(0); RunFreezeHooks(&obj); } ================================================ FILE: runtime/src/main/cpp/FreezeHooksTestSupport.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "FreezeHooksTestSupport.hpp" #include "FreezeHooks.hpp" using namespace kotlin; namespace { testing::MockFunction* g_freezeHook = nullptr; void freezeHook(ObjHeader* object) { g_freezeHook->Call(object); } } // namespace kotlin::FreezeHooksTestSupport::FreezeHooksTestSupport() { g_freezeHook = &freezeHook_; SetFreezeHookForTesting(&::freezeHook); } kotlin::FreezeHooksTestSupport::~FreezeHooksTestSupport() { SetFreezeHookForTesting(nullptr); g_freezeHook = nullptr; } ================================================ FILE: runtime/src/main/cpp/FreezeHooksTestSupport.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_FREEZE_HOOKS_TEST_SUPPORT_H #define RUNTIME_MM_FREEZE_HOOKS_TEST_SUPPORT_H #include "gtest/gtest.h" #include "gmock/gmock.h" struct ObjHeader; namespace kotlin { class FreezeHooksTestSupport { public: FreezeHooksTestSupport(); ~FreezeHooksTestSupport(); testing::MockFunction& freezeHook() { return freezeHook_; } private: testing::StrictMock> freezeHook_; }; } // namespace kotlin #endif // RUNTIME_MM_FREEZE_HOOKS_TEST_SUPPORT_H ================================================ FILE: runtime/src/main/cpp/Interop.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "Alloc.h" #include "KString.h" #include "Memory.h" #include "MemorySharedRefs.hpp" #include "Types.h" extern "C" { KNativePtr Kotlin_Interop_createStablePointer(KRef any) { KRefSharedHolder* holder = konanConstructInstance(); holder->init(any); return holder; } void Kotlin_Interop_disposeStablePointer(KNativePtr pointer) { KRefSharedHolder* holder = reinterpret_cast(pointer); holder->dispose(); konanDestructInstance(holder); } OBJ_GETTER(Kotlin_Interop_derefStablePointer, KNativePtr pointer) { KRefSharedHolder* holder = reinterpret_cast(pointer); RETURN_OBJ(holder->ref()); } OBJ_GETTER(Kotlin_CString_toKStringFromUtf8Impl, const char* cstring) { RETURN_RESULT_OF(StringFromUtf8Buffer, cstring, strlen(cstring)); } } ================================================ FILE: runtime/src/main/cpp/JSInterop.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Porting.h" #include "Types.h" typedef KInt Arena; typedef KInt Object; typedef KInt Pointer; #ifndef KONAN_WASM extern "C" { // These functions are implemented in JS file for WASM and are not available on other platforms. RUNTIME_NORETURN Arena Konan_js_allocateArena() { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN void Konan_js_freeArena(Arena arena) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN void Konan_js_pushIntToArena(Arena arena, KInt value) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN KInt Konan_js_getInt(Arena arena, Object obj, Pointer propertyPtr, KInt propertyLen) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN KInt Konan_js_getProperty(Arena arena, Object obj, Pointer propertyPtr, KInt propertyLen) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN void Konan_js_setFunction(Arena arena, Object obj, Pointer propertyName, KInt propertyLength, KInt function) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } RUNTIME_NORETURN void Konan_js_setString(Arena arena, Object obj, Pointer propertyName, KInt propertyLength, Pointer stringPtr, KInt stringLength) { RuntimeAssert(false, "JavaScript interop is disabled"); konan::abort(); } }; // extern "C" #endif // #ifndef KONAN_WASM ================================================ FILE: runtime/src/main/cpp/KAssert.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include "Porting.h" RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* format, ...) { char buf[1024]; int written = -1; // Write the title with a source location. if (location != nullptr) { written = konan::snprintf(buf, sizeof(buf), "%s: runtime assert: ", location); } else { written = konan::snprintf(buf, sizeof(buf), "runtime assert: "); } // Write the message. if (written >= 0 && static_cast(written) < sizeof(buf)) { std::va_list args; va_start(args, format); konan::vsnprintf(buf + written, sizeof(buf) - written, format, args); va_end(args); } konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf))); konan::consoleErrorf("\n"); // TODO: Write the stacktrace. konan::abort(); } // TODO: this function is not used by runtime, but apparently there are // third-party libraries that use it (despite the fact it is not a public API). // Keeping the function here for now for backward compatibility, to be removed later. RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message) { char buf[1024]; if (location != nullptr) konan::snprintf(buf, sizeof(buf), "%s: runtime assert: %s\n", location, message); else konan::snprintf(buf, sizeof(buf), "runtime assert: %s\n", message); konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf))); konan::abort(); } ================================================ FILE: runtime/src/main/cpp/KAssert.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_ASSERT_H #define RUNTIME_ASSERT_H #include "Common.h" // To avoid cluttering optimized code with asserts, they could be turned off. #define KONAN_ENABLE_ASSERT 1 #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #if KONAN_ENABLE_ASSERT #define CURRENT_SOURCE_LOCATION __FILE__ ":" TOSTRING(__LINE__) #else // Do not generate location strings, when asserts are disabled to reduce code size. #define CURRENT_SOURCE_LOCATION nullptr #endif RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* format, ...) __attribute__((format(printf, 2, 3))); namespace internal { inline RUNTIME_NORETURN void TODOImpl(const char* location) { RuntimeAssertFailed(location, "Unimplemented"); } // TODO: Support format string when `RuntimeAssertFailed` supports it. inline RUNTIME_NORETURN void TODOImpl(const char* location, const char* message) { RuntimeAssertFailed(location, "%s", message); } } // namespace internal // During codegeneration we set this constant to 1 or 0 to allow bitcode optimizer // to get rid of code behind condition. extern "C" const int KonanNeedDebugInfo; #if KONAN_ENABLE_ASSERT // Use RuntimeAssert() in internal state checks, which could be ignored in production. #define RuntimeAssert(condition, format, ...) \ do { \ if (KonanNeedDebugInfo && (!(condition))) { \ RuntimeAssertFailed(CURRENT_SOURCE_LOCATION, format, ##__VA_ARGS__); \ } \ } while (false) #else #define RuntimeAssert(condition, format, ...) \ do { \ } while (false) #endif // Use RuntimeCheck() in runtime checks that could fail due to external condition and shall lead // to program termination. Never compiled out. // TODO: Consider using `CURRENT_SOURCE_LOCATION` when `KonanNeedDebugInfo` is `true`. #define RuntimeCheck(condition, format, ...) \ do { \ if (!(condition)) { \ RuntimeAssertFailed(nullptr, format, ##__VA_ARGS__); \ } \ } while (false) #define TODO(...) \ do { \ ::internal::TODOImpl(CURRENT_SOURCE_LOCATION, ##__VA_ARGS__); \ } while (false) // Use RuntimeFail() to unconditionally fail, signifying compiler/runtime bug. // TODO: Consider using `CURRENT_SOURCE_LOCATION` when `KonanNeedDebugInfo` is `true`. #define RuntimeFail(format, ...) \ do { \ RuntimeAssertFailed(nullptr, format, ##__VA_ARGS__); \ } while (false) #endif // RUNTIME_ASSERT_H ================================================ FILE: runtime/src/main/cpp/KAssertTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "KAssert.h" #include "gtest/gtest.h" TEST(TODODeathTest, EmptyTODO) { EXPECT_DEATH({ TODO(); }, "KAssertTest.cpp:12: runtime assert: Unimplemented"); } TEST(TODODeathTest, TODOWithMessage) { EXPECT_DEATH({ TODO("Nope"); }, "KAssertTest.cpp:18: runtime assert: Nope"); } ================================================ FILE: runtime/src/main/cpp/KDebug.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_KDEBUG_H #define RUNTIME_KDEBUG_H #include "Common.h" #include "Memory.h" #include "Types.h" #include "TypeInfo.h" #ifndef KONAN_NO_DEBUG_API #ifdef __cplusplus extern "C" { #endif // PLEASE READ: please do not alter signatures of the existing functions, and when adding // the new function please do not forget to add new functions into the debug operations list. // Get memory buffer where debugger can put data in Konan app process. RUNTIME_USED RUNTIME_WEAK char* Konan_DebugBuffer(); // Same, but runtime-specific. RUNTIME_USED RUNTIME_WEAK char* Konan_DebugBufferWithObject(KRef obj); // Get size of memory buffer where debugger can put data in Konan app process. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugBufferSize(); // Same, but runtime-specific. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugBufferSizeWithObject(KRef obj); // Put string representation of an object to the provided buffer. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugObjectToUtf8Array(KRef obj, char* buffer, int32_t bufferSize); // Print to console string representation of an object. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugPrint(KRef obj); // Returns 1 if obj refers to an array, string or binary blob and 0 otherwise. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugIsArray(KRef obj); // Returns number of fields in an objects, or elements in an array. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugGetFieldCount(KRef obj); // Compute type of field or an array element at the index, or 0, if incorrect, // see Konan_RuntimeType. RUNTIME_USED RUNTIME_WEAK int32_t Konan_DebugGetFieldType(KRef obj, int32_t index); // Compute address of field or an array element at the index, or null, if incorrect. RUNTIME_USED RUNTIME_WEAK void* Konan_DebugGetFieldAddress(KRef obj, int32_t index); // Compute address of field or an array element at the index, or null, if incorrect. RUNTIME_USED RUNTIME_WEAK const char* Konan_DebugGetFieldName(KRef obj, int32_t index); // Returns name of type. RUNTIME_USED RUNTIME_WEAK const char* Konan_DebugGetTypeName(KRef obj); /** * Given an object finds debugger interface operation suitable for manipulation with this object. * Important for cases where multiple K/N runtimes coexist in the same address space and debugger * doesn't know which debug operation to use on particular instance. */ RUNTIME_USED RUNTIME_WEAK void* Konan_DebugGetOperation(KRef obj, /* Konan_DebugOperation */ int32_t operation); #ifdef __cplusplus } #endif #endif // !KONAN_NO_DEBUG_API #endif // RUNTIME_KDEBUG_H ================================================ FILE: runtime/src/main/cpp/KString.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "KAssert.h" #include "City.h" #include "Exceptions.h" #include "Memory.h" #include "Natives.h" #include "KString.h" #include "Porting.h" #include "Types.h" #include "utf8.h" #include "polyhash/PolyHash.h" namespace { typedef std::back_insert_iterator KStdStringInserter; typedef KChar* utf8to16(const char*, const char*, KChar*); typedef KStdStringInserter utf16to8(const KChar*,const KChar*, KStdStringInserter); KStdStringInserter utf16toUtf8OrThrow(const KChar* start, const KChar* end, KStdStringInserter result) { TRY_CATCH(result = utf8::utf16to8(start, end, result), result = utf8::unchecked::utf16to8(start, end, result), ThrowCharacterCodingException()); return result; } template OBJ_GETTER(utf8ToUtf16Impl, const char* rawString, const char* end, uint32_t charCount) { if (rawString == nullptr) RETURN_OBJ(nullptr); ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, charCount, OBJ_RESULT)->array(); KChar* rawResult = CharArrayAddressOfElementAt(result, 0); conversion(rawString, end, rawResult); RETURN_OBJ(result->obj()); } template OBJ_GETTER(unsafeUtf16ToUtf8Impl, KString thiz, KInt start, KInt size) { RuntimeAssert(thiz->type_info() == theStringTypeInfo, "Must use String"); const KChar* utf16 = CharArrayAddressOfElementAt(thiz, start); KStdString utf8; utf8.reserve(size); conversion(utf16, utf16 + size, back_inserter(utf8)); ArrayHeader* result = AllocArrayInstance(theByteArrayTypeInfo, utf8.size(), OBJ_RESULT)->array(); ::memcpy(ByteArrayAddressOfElementAt(result, 0), utf8.c_str(), utf8.size()); RETURN_OBJ(result->obj()); } OBJ_GETTER(utf8ToUtf16OrThrow, const char* rawString, size_t rawStringLength) { const char* end = rawString + rawStringLength; uint32_t charCount; TRY_CATCH(charCount = utf8::utf16_length(rawString, end), charCount = utf8::unchecked::utf16_length(rawString, end), ThrowCharacterCodingException()); RETURN_RESULT_OF(utf8ToUtf16Impl, rawString, end, charCount); } OBJ_GETTER(utf8ToUtf16, const char* rawString, size_t rawStringLength) { const char* end = rawString + rawStringLength; uint32_t charCount = utf8::with_replacement::utf16_length(rawString, end); RETURN_RESULT_OF(utf8ToUtf16Impl, rawString, end, charCount); } constexpr KChar digitKeys[] = { 0x30, 0x41, 0x61, 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xbe7, 0xc66, 0xce6, 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x1369, 0x17e0, 0x1810, 0xff10, 0xff21, 0xff41 }; constexpr KChar digitValues[] = { 0x39, 0x30, 0x5a, 0x37, 0x7a, 0x57, 0x669, 0x660, 0x6f9, 0x6f0, 0x96f, 0x966, 0x9ef, 0x9e6, 0xa6f, 0xa66, 0xaef, 0xae6, 0xb6f, 0xb66, 0xbef, 0xbe6, 0xc6f, 0xc66, 0xcef, 0xce6, 0xd6f, 0xd66, 0xe59, 0xe50, 0xed9, 0xed0, 0xf29, 0xf20, 0x1049, 0x1040, 0x1371, 0x1368, 0x17e9, 0x17e0, 0x1819, 0x1810, 0xff19, 0xff10, 0xff3a, 0xff17, 0xff5a, 0xff37 }; } // namespace extern "C" { OBJ_GETTER(CreateStringFromCString, const char* cstring) { RETURN_RESULT_OF(utf8ToUtf16, cstring, cstring ? strlen(cstring) : 0); } OBJ_GETTER(CreateStringFromUtf8, const char* utf8, uint32_t lengthBytes) { RETURN_RESULT_OF(utf8ToUtf16, utf8, lengthBytes); } char* CreateCStringFromString(KConstRef kref) { if (kref == nullptr) return nullptr; KString kstring = kref->array(); const KChar* utf16 = CharArrayAddressOfElementAt(kstring, 0); KStdString utf8; utf8.reserve(kstring->count_); utf8::unchecked::utf16to8(utf16, utf16 + kstring->count_, back_inserter(utf8)); char* result = reinterpret_cast(konan::calloc(1, utf8.size() + 1)); ::memcpy(result, utf8.c_str(), utf8.size()); return result; } void DisposeCString(char* cstring) { if (cstring) konan::free(cstring); } // String.kt OBJ_GETTER(Kotlin_String_replace, KString thiz, KChar oldChar, KChar newChar) { auto count = thiz->count_; ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, count, OBJ_RESULT)->array(); const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0); KChar* resultRaw = CharArrayAddressOfElementAt(result, 0); for (uint32_t index = 0; index < count; ++index) { KChar thizChar = *thizRaw++; *resultRaw++ = thizChar == oldChar ? newChar : thizChar; } RETURN_OBJ(result->obj()); } OBJ_GETTER(Kotlin_String_plusImpl, KString thiz, KString other) { RuntimeAssert(thiz != nullptr, "this cannot be null"); RuntimeAssert(other != nullptr, "other cannot be null"); RuntimeAssert(thiz->type_info() == theStringTypeInfo, "Must be a string"); RuntimeAssert(other->type_info() == theStringTypeInfo, "Must be a string"); RuntimeAssert(thiz->count_ <= static_cast(std::numeric_limits::max()), "this cannot be this large"); RuntimeAssert(other->count_ <= static_cast(std::numeric_limits::max()), "other cannot be this large"); // Since thiz and other sizes are bounded by int32_t max value, their sum cannot exceed uint32_t max value - 1. uint32_t result_length = thiz->count_ + other->count_; if (result_length > static_cast(std::numeric_limits::max())) { ThrowArrayIndexOutOfBoundsException(); } ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, result_length, OBJ_RESULT)->array(); memcpy( CharArrayAddressOfElementAt(result, 0), CharArrayAddressOfElementAt(thiz, 0), thiz->count_ * sizeof(KChar)); memcpy( CharArrayAddressOfElementAt(result, thiz->count_), CharArrayAddressOfElementAt(other, 0), other->count_ * sizeof(KChar)); RETURN_OBJ(result->obj()); } OBJ_GETTER(Kotlin_String_unsafeStringFromCharArray, KConstRef thiz, KInt start, KInt size) { const ArrayHeader* array = thiz->array(); RuntimeAssert(array->type_info() == theCharArrayTypeInfo, "Must use a char array"); if (size == 0) { RETURN_RESULT_OF0(TheEmptyString); } ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, size, OBJ_RESULT)->array(); memcpy(CharArrayAddressOfElementAt(result, 0), CharArrayAddressOfElementAt(array, start), size * sizeof(KChar)); RETURN_OBJ(result->obj()); } OBJ_GETTER(Kotlin_String_toCharArray, KString string, KInt start, KInt size) { ArrayHeader* result = AllocArrayInstance(theCharArrayTypeInfo, size, OBJ_RESULT)->array(); memcpy(CharArrayAddressOfElementAt(result, 0), CharArrayAddressOfElementAt(string, start), size * sizeof(KChar)); RETURN_OBJ(result->obj()); } OBJ_GETTER(Kotlin_String_subSequence, KString thiz, KInt startIndex, KInt endIndex) { if (startIndex < 0 || static_cast(endIndex) > thiz->count_ || startIndex > endIndex) { // TODO: is it correct exception? ThrowArrayIndexOutOfBoundsException(); } if (startIndex == endIndex) { RETURN_RESULT_OF0(TheEmptyString); } KInt length = endIndex - startIndex; ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, length, OBJ_RESULT)->array(); memcpy(CharArrayAddressOfElementAt(result, 0), CharArrayAddressOfElementAt(thiz, startIndex), length * sizeof(KChar)); RETURN_OBJ(result->obj()); } KInt Kotlin_String_compareTo(KString thiz, KString other) { int result = memcmp( CharArrayAddressOfElementAt(thiz, 0), CharArrayAddressOfElementAt(other, 0), (thiz->count_ < other->count_ ? thiz->count_ : other->count_) * sizeof(KChar)); if (result != 0) return result; int diff = thiz->count_ - other->count_; if (diff == 0) return 0; return diff < 0 ? -1 : 1; } KChar Kotlin_String_get(KString thiz, KInt index) { // We couldn't have created a string bigger than max KInt value. // So if index is < 0, conversion to an unsigned value would make it bigger // than the array size. if (static_cast(index) >= thiz->count_) { ThrowArrayIndexOutOfBoundsException(); } return *CharArrayAddressOfElementAt(thiz, index); } KInt Kotlin_String_getStringLength(KString thiz) { return thiz->count_; } const char* unsafeByteArrayAsCString(KConstRef thiz, KInt start, KInt size) { const ArrayHeader* array = thiz->array(); RuntimeAssert(array->type_info() == theByteArrayTypeInfo, "Must use a byte array"); return reinterpret_cast(ByteArrayAddressOfElementAt(array, start)); } OBJ_GETTER(Kotlin_ByteArray_unsafeStringFromUtf8OrThrow, KConstRef thiz, KInt start, KInt size) { if (size == 0) { RETURN_RESULT_OF0(TheEmptyString); } const char* rawString = unsafeByteArrayAsCString(thiz, start, size); RETURN_RESULT_OF(utf8ToUtf16OrThrow, rawString, size); } OBJ_GETTER(Kotlin_ByteArray_unsafeStringFromUtf8, KConstRef thiz, KInt start, KInt size) { if (size == 0) { RETURN_RESULT_OF0(TheEmptyString); } const char* rawString = unsafeByteArrayAsCString(thiz, start, size); RETURN_RESULT_OF(utf8ToUtf16, rawString, size); } OBJ_GETTER(StringFromUtf8Buffer, const char* start, size_t size) { if (size == 0) { RETURN_RESULT_OF0(TheEmptyString); } RETURN_RESULT_OF(utf8ToUtf16, start, size); } OBJ_GETTER(Kotlin_String_unsafeStringToUtf8, KString thiz, KInt start, KInt size) { RETURN_RESULT_OF(unsafeUtf16ToUtf8Impl, thiz, start, size); } OBJ_GETTER(Kotlin_String_unsafeStringToUtf8OrThrow, KString thiz, KInt start, KInt size) { RETURN_RESULT_OF(unsafeUtf16ToUtf8Impl, thiz, start, size); } KInt Kotlin_StringBuilder_insertString(KRef builder, KInt distIndex, KString fromString, KInt sourceIndex, KInt count) { auto toArray = builder->array(); RuntimeAssert(sourceIndex >= 0 && static_cast(sourceIndex + count) <= fromString->count_, "must be true"); RuntimeAssert(distIndex >= 0 && static_cast(distIndex + count) <= toArray->count_, "must be true"); memcpy(CharArrayAddressOfElementAt(toArray, distIndex), CharArrayAddressOfElementAt(fromString, sourceIndex), count * sizeof(KChar)); return count; } KInt Kotlin_StringBuilder_insertInt(KRef builder, KInt position, KInt value) { auto toArray = builder->array(); RuntimeAssert(toArray->count_ >= static_cast(11 + position), "must be true"); char cstring[12]; auto length = konan::snprintf(cstring, sizeof(cstring), "%d", value); RuntimeAssert(length >= 0, "This should never happen"); // may be overkill RuntimeAssert(static_cast(length) < sizeof(cstring), "Unexpectedly large value"); // Can't be, but this is what sNprintf for auto* from = &cstring[0]; auto* to = CharArrayAddressOfElementAt(toArray, position); while (*from) { *to++ = *from++; } return from - cstring; } KBoolean Kotlin_String_equals(KString thiz, KConstRef other) { if (other == nullptr || other->type_info() != theStringTypeInfo) return false; // Important, due to literal internalization. KString otherString = other->array(); if (thiz == otherString) return true; return thiz->count_ == otherString->count_ && memcmp(CharArrayAddressOfElementAt(thiz, 0), CharArrayAddressOfElementAt(otherString, 0), thiz->count_ * sizeof(KChar)) == 0; } // Bounds checks is are performed on Kotlin side KBoolean Kotlin_String_unsafeRangeEquals(KString thiz, KInt thizOffset, KString other, KInt otherOffset, KInt length) { return memcmp( CharArrayAddressOfElementAt(thiz, thizOffset), CharArrayAddressOfElementAt(other, otherOffset), length * sizeof(KChar) ) == 0; } KBoolean Kotlin_Char_isIdentifierIgnorable(KChar ch) { RuntimeAssert(false, "Kotlin_Char_isIdentifierIgnorable() is not implemented"); return false; } KBoolean Kotlin_Char_isISOControl(KChar ch) { return (ch <= 0x1F) || (ch >= 0x7F && ch <= 0x9F); } KBoolean Kotlin_Char_isHighSurrogate(KChar ch) { return ((ch & 0xfc00) == 0xd800); } KBoolean Kotlin_Char_isLowSurrogate(KChar ch) { return ((ch & 0xfc00) == 0xdc00); } constexpr KInt digits[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 }; // Based on Apache Harmony implementation. // Radix check is performed on the Kotlin side. KInt Kotlin_Char_digitOfChecked(KChar ch, KInt radix) { KInt result = -1; if (ch >= 0x30 /* 0 */ && ch <= 0x7a /* z */) { result = digits[ch - 0x30]; } else { int index = -1; index = binarySearchRange(digitKeys, ARRAY_SIZE(digitKeys), ch); if (index >= 0 && ch <= digitValues[index * 2]) { result = ch - digitValues[index * 2 + 1]; } } if (result >= radix) return -1; return result; } KInt Kotlin_String_indexOfChar(KString thiz, KChar ch, KInt fromIndex) { if (fromIndex < 0) { fromIndex = 0; } if (static_cast(fromIndex) > thiz->count_) { return -1; } KInt count = thiz->count_; const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, fromIndex); while (fromIndex < count) { if (*thizRaw++ == ch) return fromIndex; fromIndex++; } return -1; } KInt Kotlin_String_lastIndexOfChar(KString thiz, KChar ch, KInt fromIndex) { if (fromIndex < 0 || thiz->count_ == 0) { return -1; } if (static_cast(fromIndex) >= thiz->count_) { fromIndex = thiz->count_ - 1; } KInt index = fromIndex; const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, index); while (index >= 0) { if (*thizRaw-- == ch) return index; index--; } return -1; } // TODO: or code up Knuth-Moris-Pratt. KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) { if (fromIndex < 0) { fromIndex = 0; } if (static_cast(fromIndex) >= thiz->count_) { return (other->count_ == 0) ? thiz->count_ : -1; } if (static_cast(other->count_) > static_cast(thiz->count_) - fromIndex) { return -1; } // An empty string can be always found. if (other->count_ == 0) { return fromIndex; } const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, fromIndex); const KChar* otherRaw = CharArrayAddressOfElementAt(other, 0); void* result = konan::memmem(thizRaw, (thiz->count_ - fromIndex) * sizeof(KChar), otherRaw, other->count_ * sizeof(KChar)); if (result == nullptr) return -1; return (reinterpret_cast(result) - reinterpret_cast( CharArrayAddressOfElementAt(thiz, 0))) / sizeof(KChar); } KInt Kotlin_String_lastIndexOfString(KString thiz, KString other, KInt fromIndex) { KInt count = thiz->count_; KInt otherCount = other->count_; if (fromIndex < 0 || otherCount > count) { return -1; } if (otherCount == 0) { return fromIndex < count ? fromIndex : count; } KInt start = fromIndex; if (fromIndex > count - otherCount) start = count - otherCount; KChar firstChar = *CharArrayAddressOfElementAt(other, 0); while (true) { KInt candidate = Kotlin_String_lastIndexOfChar(thiz, firstChar, start); if (candidate == -1) return -1; KInt offsetThiz = candidate; KInt offsetOther = 0; while (++offsetOther < otherCount && *CharArrayAddressOfElementAt(thiz, ++offsetThiz) == *CharArrayAddressOfElementAt(other, offsetOther)) {} if (offsetOther == otherCount) { return candidate; } start = candidate - 1; } } KInt Kotlin_String_hashCode(KString thiz) { // TODO: consider caching strings hashes. return polyHash(thiz->count_, CharArrayAddressOfElementAt(thiz, 0)); } const KChar* Kotlin_String_utf16pointer(KString message) { RuntimeAssert(message->type_info() == theStringTypeInfo, "Must use a string"); const KChar* utf16 = CharArrayAddressOfElementAt(message, 0); return utf16; } KInt Kotlin_String_utf16length(KString message) { RuntimeAssert(message->type_info() == theStringTypeInfo, "Must use a string"); return message->count_ * sizeof(KChar); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/KString.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_KSTRING_H #define RUNTIME_KSTRING_H #include "Common.h" #include "Memory.h" #include "Types.h" #include "TypeInfo.h" #ifdef __cplusplus extern "C" { #endif OBJ_GETTER(CreateStringFromCString, const char* cstring); OBJ_GETTER(CreateStringFromUtf8, const char* utf8, uint32_t lengthBytes); char* CreateCStringFromString(KConstRef kstring); void DisposeCString(char* cstring); OBJ_GETTER(StringFromUtf8Buffer, const char* start, size_t size); #ifdef __cplusplus } #endif template int binarySearchRange(const T* array, int arrayLength, T needle) { int bottom = 0; int top = arrayLength - 1; int middle = -1; T value = 0; while (bottom <= top) { middle = (bottom + top) / 2; value = array[middle]; if (needle > value) bottom = middle + 1; else if (needle == value) return middle; else top = middle - 1; } return middle - (needle < value ? 1 : 0); } #endif // RUNTIME_KSTRING_H ================================================ FILE: runtime/src/main/cpp/KotlinMath.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "DoubleConversions.h" #include "Exceptions.h" #include "KotlinMath.h" #include "ReturnSlot.h" #include "Types.h" #if (__MINGW32__ || __MINGW64__) #define KONAN_NEED_ASINH_ACOSH 1 #else #define KONAN_NEED_ASINH_ACOSH 0 #endif #if KONAN_NEED_ASINH_ACOSH namespace { // MinGW's implmenetation of asinh/acosh function returns NaN for large arguments so we use another implementation. // Both implementations derived from boost special math functions and are also used by Kotlin/JVM. // Copyright Eric Ford & Hubert Holin 2001. constexpr KDouble LN2 = 0.69314718055994530942; constexpr KDouble SQRT2 = 1.41421356237309504880; KDouble taylor_2_bound = sqrt(DBL_EPSILON); KDouble taylor_n_bound = sqrt(taylor_2_bound); KDouble upper_taylor_2_bound = 1.0 / taylor_2_bound; KDouble upper_taylor_n_bound = 1.0 / taylor_n_bound; KDouble custom_asinh(KDouble x) { if (x >= +taylor_n_bound) { if (x > upper_taylor_n_bound) { if (x > upper_taylor_2_bound) { // approximation by laurent series in 1/x at 0+ order from -1 to 0 return log(x) + LN2; } else { // approximation by laurent series in 1/x at 0+ order from -1 to 1 return log(x * 2 + (1.0 / (x * 2))); } } else { return log(x + sqrt(x * x + 1)); } } else if (x <= -taylor_n_bound) { return -custom_asinh(-x); } else { // approximation by taylor series in x at 0 up to order 2 KDouble result = x; if (fabs(x) >= taylor_2_bound) { // approximation by taylor series in x at 0 up to order 4 result -= (x * x * x) / 6; } return result; } } KDouble custom_acosh(KDouble x) { if (x < 1) { return NAN; } else if (x > upper_taylor_2_bound) { // approximation by laurent series in 1/x at 0+ order from -1 to 0 return log(x) + LN2; } else if (x - 1 >= taylor_n_bound) { return log(x + sqrt(x * x - 1)); } else { KDouble y = sqrt(x - 1); // approximation by taylor series in y at 0 up to order 2 KDouble result = y; if (y >= taylor_2_bound) { // approximation by taylor series in y at 0 up to order 4 result -= (y * y * y) / 12; } return SQRT2 * result; } } } #endif extern "C" { #ifndef KONAN_NO_MATH // We have a platform math library. Call its math functions. #ifndef KONAN_WASM // Use libm. // region Double math. KDouble Kotlin_math_sin(KDouble x) { return sin(x); } KDouble Kotlin_math_cos(KDouble x) { return cos(x); } KDouble Kotlin_math_tan(KDouble x) { return tan(x); } KDouble Kotlin_math_asin(KDouble x) { return asin(x); } KDouble Kotlin_math_acos(KDouble x) { return acos(x); } KDouble Kotlin_math_atan(KDouble x) { return atan(x); } KDouble Kotlin_math_atan2(KDouble y, KDouble x) { return atan2(y, x); } KDouble Kotlin_math_sinh(KDouble x) { return sinh(x); } KDouble Kotlin_math_cosh(KDouble x) { return cosh(x); } KDouble Kotlin_math_tanh(KDouble x) { return tanh(x); } KDouble Kotlin_math_asinh(KDouble x) { #if (KONAN_NEED_ASINH_ACOSH) return custom_asinh(x); #else return asinh(x); #endif } KDouble Kotlin_math_acosh(KDouble x) { #if (KONAN_NEED_ASINH_ACOSH) return custom_acosh(x); #else return acosh(x); #endif } KDouble Kotlin_math_atanh(KDouble x) { return atanh(x); } KDouble Kotlin_math_hypot(KDouble x, KDouble y) { if (isinf(x) || isinf(y)) return INFINITY; if (isnan(x) || isnan(y)) return NAN; return hypot(x, y); } KDouble Kotlin_math_sqrt(KDouble x) { return sqrt(x); } KDouble Kotlin_math_exp(KDouble x) { return exp(x); } KDouble Kotlin_math_expm1(KDouble x) { return expm1(x); } KDouble Kotlin_math_ln(KDouble x) { return log(x); } KDouble Kotlin_math_log10(KDouble x) { return log10(x); } KDouble Kotlin_math_log2(KDouble x) { return log2(x); } KDouble Kotlin_math_ln1p(KDouble x) { return log1p(x); } KDouble Kotlin_math_ceil(KDouble x) { return ceil(x); } KDouble Kotlin_math_floor(KDouble x) { return floor(x); } KDouble Kotlin_math_round(KDouble x) { return rint(x); } KDouble Kotlin_math_abs(KDouble x) { return fabs(x); } // extensions KDouble Kotlin_math_Double_pow(KDouble thiz, KDouble x) { // Kotlin corner cases if (x == 0.0 || x == -0.0) return 1.0; if (isinf(x) && (thiz == 1.0 || thiz == -1.0)) return NAN; return pow(thiz, x); } KDouble Kotlin_math_Double_IEEErem(KDouble thiz, KDouble divisor) { return remainder(thiz, divisor); } KDouble Kotlin_math_Double_withSign(KDouble thiz, KDouble sign) { return copysign(thiz, sign); } KDouble Kotlin_math_Double_nextUp(KDouble thiz) { return nextafter(thiz, HUGE_VAL); } KDouble Kotlin_math_Double_nextDown(KDouble thiz) { return nextafter(thiz, -HUGE_VAL); } KDouble Kotlin_math_Double_nextTowards(KDouble thiz, KDouble to) { return (thiz == to) ? to : nextafter(thiz, to); } KBoolean Kotlin_math_Double_signBit(KDouble thiz) { return signbit(thiz) != 0; } // endregion // region Float math. KFloat Kotlin_math_sinf(KFloat x) { return sinf(x); } KFloat Kotlin_math_cosf(KFloat x) { return cosf(x); } KFloat Kotlin_math_tanf(KFloat x) { return tanf(x); } KFloat Kotlin_math_asinf(KFloat x) { return asinf(x); } KFloat Kotlin_math_acosf(KFloat x) { return acosf(x); } KFloat Kotlin_math_atanf(KFloat x) { return atanf(x); } KFloat Kotlin_math_atan2f(KFloat y, KFloat x) { return atan2f(y, x); } KFloat Kotlin_math_sinhf(KFloat x) { return sinhf(x); } KFloat Kotlin_math_coshf(KFloat x) { return coshf(x); } KFloat Kotlin_math_tanhf(KFloat x) { return tanhf(x); } KFloat Kotlin_math_asinhf(KFloat x) { #if (KONAN_NEED_ASINH_ACOSH) return (KFloat)custom_asinh((KDouble)x); #else return asinhf(x); #endif } KFloat Kotlin_math_acoshf(KFloat x) { #if (KONAN_NEED_ASINH_ACOSH) return (KFloat)custom_acosh((KDouble)x); #else return acoshf(x); #endif } KFloat Kotlin_math_atanhf(KFloat x) { return atanhf(x); } KFloat Kotlin_math_hypotf(KFloat x, KFloat y) { if (isinf(x) || isinf(y)) return INFINITY; if (isnan(x) || isnan(y)) return NAN; return hypotf(x, y); } KFloat Kotlin_math_sqrtf(KFloat x) { return sqrtf(x); } KFloat Kotlin_math_expf(KFloat x) { return expf(x); } KFloat Kotlin_math_expm1f(KFloat x) { return expm1f(x); } KFloat Kotlin_math_lnf(KFloat x) { return logf(x); } KFloat Kotlin_math_log10f(KFloat x) { return log10f(x); } KFloat Kotlin_math_log2f(KFloat x) { return log2f(x); } KFloat Kotlin_math_ln1pf(KFloat x) { return log1pf(x); } KFloat Kotlin_math_ceilf(KFloat x) { return ceilf(x); } KFloat Kotlin_math_floorf(KFloat x) { return floorf(x); } KFloat Kotlin_math_roundf(KFloat x) { return rintf(x); } KFloat Kotlin_math_absf(KFloat x) { return fabsf(x); } // extensions KFloat Kotlin_math_Float_pow(KFloat thiz, KFloat x) { // Kotlin corner cases if (x == 0.0 || x == -0.0) return 1.0; if (isinf(x) && (thiz == 1.0 || thiz == -1.0)) return NAN; return powf(thiz, x); } KFloat Kotlin_math_Float_IEEErem(KFloat thiz, KFloat divisor) { return remainderf(thiz, divisor); } KFloat Kotlin_math_Float_withSign(KFloat thiz, KFloat sign) { return copysignf(thiz, sign); } KFloat Kotlin_math_Float_nextUp(KFloat thiz) { return nextafterf(thiz, HUGE_VALF); } KFloat Kotlin_math_Float_nextDown(KFloat thiz) { return nextafterf(thiz, -HUGE_VALF); } KFloat Kotlin_math_Float_nextTowards(KFloat thiz, KFloat to) { return (thiz == to) ? to : nextafterf(thiz, to); } KBoolean Kotlin_math_Float_signBit(KFloat thiz) { return signbit(thiz) != 0; } // endregion // region Integer math. KInt Kotlin_math_absi(KInt x) { return labs(x); } KLong Kotlin_math_absl(KLong x) { return llabs(x); } // endregion #else // KONAN_WASM defined. Use JS math implementation. #define RETURN_RESULT_OF_JS_CALL(call, doubleArg) { \ call(doubleUpper(doubleArg), doubleLower(doubleArg)); \ return ReturnSlot_getDouble(); \ } #define RETURN_RESULT_OF_JS_CALL2(call, doubleArg1, doubleArg2) { \ call(doubleUpper(doubleArg1), \ doubleLower(doubleArg1), \ doubleUpper(doubleArg2), \ doubleLower(doubleArg2)); \ return ReturnSlot_getDouble(); \ } KDouble Kotlin_math_sin(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sin, x); } KDouble Kotlin_math_cos(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_cos, x); } KDouble Kotlin_math_tan(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_tan, x); } KDouble Kotlin_math_asin(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_asin, x); } KDouble Kotlin_math_acos(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_acos, x); } KDouble Kotlin_math_atan(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_atan, x); } KDouble Kotlin_math_sinh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sinh, x); } KDouble Kotlin_math_cosh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_cosh, x); } KDouble Kotlin_math_tanh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_tanh, x); } KDouble Kotlin_math_asinh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_asinh, x); } KDouble Kotlin_math_acosh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_acosh, x); } KDouble Kotlin_math_atanh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_atanh, x); } KDouble Kotlin_math_sqrt(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sqrt, x); } KDouble Kotlin_math_exp(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_exp, x); } KDouble Kotlin_math_expm1(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_expm1, x); } KDouble Kotlin_math_ln(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log, x); } KDouble Kotlin_math_log10(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log10, x); } KDouble Kotlin_math_log2(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log2, x); } KDouble Kotlin_math_ln1p(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log1p, x); } KDouble Kotlin_math_ceil(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_ceil, x); } KDouble Kotlin_math_floor(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_floor, x); } KDouble Kotlin_math_round(KDouble x) { if (fmod(x, 0.5) != 0.0) { RETURN_RESULT_OF_JS_CALL(knjs__Math_round, x); } KDouble f = floor(x); return (fmod(f, 2) == 0.0) ? f : ceil(x); } KDouble Kotlin_math_abs(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_abs, x); } KDouble Kotlin_math_atan2(KDouble y, KDouble x) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_atan2, y, x); } KDouble Kotlin_math_hypot(KDouble x, KDouble y) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_hypot, x, y); } // extensions KDouble Kotlin_math_Double_pow(KDouble thiz, KDouble x) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_pow, thiz, x); } KDouble Kotlin_math_Double_IEEErem(KDouble thiz, KDouble divisor) { if (isnan(thiz) || isnan(divisor) || isinf(thiz) || divisor == 0.0) { return NAN; } if (!isinf(thiz) && isinf(divisor)) { return thiz; } KDouble rounded = Kotlin_math_round(thiz / divisor); return thiz - rounded * divisor; } KDouble Kotlin_math_Double_nextUp(KDouble thiz) { if (isnan(thiz) || thiz == HUGE_VAL) { return thiz; } if (thiz == 0.0) { return DBL_TRUE_MIN; } return bitsToDouble(doubleToBits(thiz) + (thiz > 0 ? 1 : -1)); } KDouble Kotlin_math_Double_nextDown(KDouble thiz) { if (isnan(thiz) || thiz == -HUGE_VAL) { return thiz; } if (thiz == 0.0) { return -DBL_TRUE_MIN; } return bitsToDouble(doubleToBits(thiz) - (thiz > 0 ? 1 : -1)); } KDouble Kotlin_math_Double_nextTowards(KDouble thiz, KDouble to) { if (isnan(thiz) || isnan(to)) { return NAN; } if (to > thiz) { return Kotlin_math_Double_nextUp(thiz); } if (to < thiz) { return Kotlin_math_Double_nextDown(thiz); } // thiz == to return to; } KBoolean Kotlin_math_Double_signBit(KDouble thiz) { return (doubleToBits(thiz) & (KLong) 1 << 63) != 0; } KDouble Kotlin_math_Double_withSign(KDouble thiz, KDouble sign) { bool oldSign = Kotlin_math_Double_signBit(thiz); bool newSign = Kotlin_math_Double_signBit(sign); return (oldSign == newSign) ? thiz : -thiz; } // endregion // region Float math. KFloat Kotlin_math_sinf(KFloat x) { return (KFloat)Kotlin_math_sin (x); } KFloat Kotlin_math_cosf(KFloat x) { return (KFloat)Kotlin_math_cos (x); } KFloat Kotlin_math_tanf(KFloat x) { return (KFloat)Kotlin_math_tan (x); } KFloat Kotlin_math_asinf(KFloat x) { return (KFloat)Kotlin_math_asin (x); } KFloat Kotlin_math_acosf(KFloat x) { return (KFloat)Kotlin_math_acos (x); } KFloat Kotlin_math_atanf(KFloat x) { return (KFloat)Kotlin_math_atan (x); } KFloat Kotlin_math_sinhf(KFloat x) { return (KFloat)Kotlin_math_sinh (x); } KFloat Kotlin_math_coshf(KFloat x) { return (KFloat)Kotlin_math_cosh (x); } KFloat Kotlin_math_tanhf(KFloat x) { return (KFloat)Kotlin_math_tanh (x); } KFloat Kotlin_math_asinhf(KFloat x) { return (KFloat)Kotlin_math_asinh (x); } KFloat Kotlin_math_acoshf(KFloat x) { return (KFloat)Kotlin_math_acosh (x); } KFloat Kotlin_math_atanhf(KFloat x) { return (KFloat)Kotlin_math_atanh (x); } KFloat Kotlin_math_sqrtf(KFloat x) { return (KFloat)Kotlin_math_sqrt (x); } KFloat Kotlin_math_expf(KFloat x) { return (KFloat)Kotlin_math_exp (x); } KFloat Kotlin_math_expm1f(KFloat x) { return (KFloat)Kotlin_math_expm1 (x); } KFloat Kotlin_math_lnf(KFloat x) { return (KFloat)Kotlin_math_ln (x); } KFloat Kotlin_math_log10f(KFloat x) { return (KFloat)Kotlin_math_log10 (x); } KFloat Kotlin_math_log2f(KFloat x) { return (KFloat)Kotlin_math_log2 (x); } KFloat Kotlin_math_ln1pf(KFloat x) { return (KFloat)Kotlin_math_ln1p (x); } KFloat Kotlin_math_ceilf(KFloat x) { return (KFloat)Kotlin_math_ceil (x); } KFloat Kotlin_math_floorf(KFloat x) { return (KFloat)Kotlin_math_floor (x); } KFloat Kotlin_math_roundf(KFloat x) { return (KFloat)Kotlin_math_round (x); } KFloat Kotlin_math_absf(KFloat x) { return (KFloat)Kotlin_math_abs (x); } KFloat Kotlin_math_atan2f(KFloat y, KFloat x) { return (KFloat)Kotlin_math_atan2(y, x); } KFloat Kotlin_math_hypotf(KFloat x, KFloat y) { return (KFloat)Kotlin_math_hypot(x, y); } // extensions KFloat Kotlin_math_Float_pow(KFloat thiz, KFloat x) { return (KFloat)Kotlin_math_Double_pow(thiz, x); } KFloat Kotlin_math_Float_IEEErem(KFloat thiz, KFloat divisor) { return (KFloat)Kotlin_math_Double_IEEErem(thiz, divisor); } KFloat Kotlin_math_Float_withSign(KFloat thiz, KFloat sign) { return (KFloat)Kotlin_math_Double_withSign(thiz, sign); } KFloat Kotlin_math_Float_nextUp(KFloat thiz) { if (isnan(thiz) || thiz == HUGE_VALF) { return thiz; } if (thiz == 0.0) { return FLT_TRUE_MIN; } return bitsToFloat(floatToBits(thiz) + (thiz > 0 ? 1 : -1)); } KFloat Kotlin_math_Float_nextDown(KFloat thiz) { if (isnan(thiz) || thiz == -HUGE_VALF) { return thiz; } if (thiz == 0.0) { return -FLT_TRUE_MIN; } return bitsToFloat(floatToBits(thiz) - (thiz > 0 ? 1 : -1)); } KFloat Kotlin_math_Float_nextTowards(KFloat thiz, KFloat to) { if (isnan(thiz) || isnan(to)) { return NAN; } if (to > thiz) { return Kotlin_math_Float_nextUp(thiz); } if (to < thiz) { return Kotlin_math_Float_nextDown(thiz); } // thiz == to return to; } KBoolean Kotlin_math_Float_signBit(KFloat thiz) { return Kotlin_math_Double_signBit(thiz); } // endregion // region Integer math KInt Kotlin_math_absi(KInt x) { return (x >= 0) ? x : -x; } KLong Kotlin_math_absl(KLong x) { return (x >= 0) ? x : -x; } #endif // #ifndef KONAN_WASM #else // KONAN_NO_MATH defined - we have no patform math library. Throw NotImplementedError from math functions. namespace { RUNTIME_NORETURN void NotImplemented() { ThrowNotImplementedError(); } } // namespace KDouble Kotlin_math_sin(KDouble x) { NotImplemented(); } KDouble Kotlin_math_cos(KDouble x) { NotImplemented(); } KDouble Kotlin_math_tan(KDouble x) { NotImplemented(); } KDouble Kotlin_math_asin(KDouble x) { NotImplemented(); } KDouble Kotlin_math_acos(KDouble x) { NotImplemented(); } KDouble Kotlin_math_atan(KDouble x) { NotImplemented(); } KDouble Kotlin_math_atan2(KDouble y, KDouble x) { NotImplemented(); } KDouble Kotlin_math_sinh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_cosh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_tanh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_asinh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_acosh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_atanh(KDouble x) { NotImplemented(); } KDouble Kotlin_math_hypot(KDouble x, KDouble y) { NotImplemented(); } KDouble Kotlin_math_sqrt(KDouble x) { NotImplemented(); } KDouble Kotlin_math_exp(KDouble x) { NotImplemented(); } KDouble Kotlin_math_expm1(KDouble x) { NotImplemented(); } KDouble Kotlin_math_ln(KDouble x) { NotImplemented(); } KDouble Kotlin_math_log10(KDouble x) { NotImplemented(); } KDouble Kotlin_math_log2(KDouble x) { NotImplemented(); } KDouble Kotlin_math_ln1p(KDouble x) { NotImplemented(); } KDouble Kotlin_math_ceil(KDouble x) { NotImplemented(); } KDouble Kotlin_math_floor(KDouble x) { NotImplemented(); } KDouble Kotlin_math_round(KDouble x) { NotImplemented(); } KDouble Kotlin_math_abs(KDouble x) { NotImplemented(); } // extensions KDouble Kotlin_math_Double_pow(KDouble thiz, KDouble x) { NotImplemented(); } KDouble Kotlin_math_Double_IEEErem(KDouble thiz, KDouble divisor) { NotImplemented(); } KDouble Kotlin_math_Double_withSign(KDouble thiz, KDouble sign) { NotImplemented(); } KDouble Kotlin_math_Double_nextUp(KDouble thiz) { NotImplemented(); } KDouble Kotlin_math_Double_nextDown(KDouble thiz) { NotImplemented(); } KDouble Kotlin_math_Double_nextTowards(KDouble thiz, KDouble to) { NotImplemented(); } KBoolean Kotlin_math_Double_signBit(KDouble thiz) { NotImplemented(); } // endregion // region Float math. KFloat Kotlin_math_sinf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_cosf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_tanf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_asinf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_acosf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_atanf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_atan2f(KFloat y, KFloat x) { NotImplemented(); } KFloat Kotlin_math_sinhf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_coshf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_tanhf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_asinhf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_acoshf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_atanhf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_hypotf(KFloat x, KFloat y) { NotImplemented(); } KFloat Kotlin_math_sqrtf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_expf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_expm1f(KFloat x) { NotImplemented(); } KFloat Kotlin_math_lnf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_log10f(KFloat x) { NotImplemented(); } KFloat Kotlin_math_log2f(KFloat x) { NotImplemented(); } KFloat Kotlin_math_ln1pf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_ceilf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_floorf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_roundf(KFloat x) { NotImplemented(); } KFloat Kotlin_math_absf(KFloat x) { NotImplemented(); } // extensions KFloat Kotlin_math_Float_pow(KFloat thiz, KFloat x) { NotImplemented(); } KFloat Kotlin_math_Float_IEEErem(KFloat thiz, KFloat divisor) { NotImplemented(); } KFloat Kotlin_math_Float_withSign(KFloat thiz, KFloat sign) { NotImplemented(); } KFloat Kotlin_math_Float_nextUp(KFloat thiz) { NotImplemented(); } KFloat Kotlin_math_Float_nextDown(KFloat thiz) { NotImplemented(); } KFloat Kotlin_math_Float_nextTowards(KFloat thiz, KFloat to) { NotImplemented(); } KBoolean Kotlin_math_Float_signBit(KFloat thiz) { NotImplemented(); } // endregion // region Integer math KInt Kotlin_math_absi(KInt x) { NotImplemented(); } KInt Kotlin_math_mini(KInt a, KInt b) { NotImplemented(); } KInt Kotlin_math_maxi(KInt a, KInt b) { NotImplemented(); } KLong Kotlin_math_absl(KLong x) { NotImplemented(); } KLong Kotlin_math_minl(KLong a, KLong b) { NotImplemented(); } KLong Kotlin_math_maxl(KLong a, KLong b) { NotImplemented(); } #endif // #ifndef KONAN_NO_MATH } // extern "C" ================================================ FILE: runtime/src/main/cpp/KotlinMath.h ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_KOTLINMATH_H #define RUNTIME_KOTLINMATH_H #include "Types.h" #ifdef KONAN_WASM extern "C" { // TODO: consider auto-generating this header file. // Bridges for JS math. void knjs__Math_abs(KInt xUpper, KInt xLower); void knjs__Math_acos(KInt xUpper, KInt xLower); void knjs__Math_acosh(KInt xUpper, KInt xLower); void knjs__Math_asin(KInt xUpper, KInt xLower); void knjs__Math_asinh(KInt xUpper, KInt xLower); void knjs__Math_atan(KInt xUpper, KInt xLower); void knjs__Math_atan2(KInt yUpper, KInt yLower, KInt xUpper, KInt xLower); void knjs__Math_atanh(KInt xUpper, KInt xLower); void knjs__Math_cbrt(KInt xUpper, KInt xLower); void knjs__Math_ceil(KInt xUpper, KInt xLower); void knjs__Math_clz32(KInt xUpper, KInt xLower); void knjs__Math_cos(KInt xUpper, KInt xLower); void knjs__Math_cosh(KInt xUpper, KInt xLower); void knjs__Math_exp(KInt xUpper, KInt xLower); void knjs__Math_expm1(KInt xUpper, KInt xLower); void knjs__Math_floor(KInt xUpper, KInt xLower); void knjs__Math_fround(KInt xUpper, KInt xLower); void knjs__Math_log(KInt xUpper, KInt xLower); void knjs__Math_log1p(KInt xUpper, KInt xLower); void knjs__Math_log10(KInt xUpper, KInt xLower); void knjs__Math_log2(KInt xUpper, KInt xLower); void knjs__Math_round(KInt xUpper, KInt xLower); void knjs__Math_sign(KInt xUpper, KInt xLower); void knjs__Math_sin(KInt xUpper, KInt xLower); void knjs__Math_sinh(KInt xUpper, KInt xLower); void knjs__Math_sqrt(KInt xUpper, KInt xLower); void knjs__Math_tan(KInt xUpper, KInt xLower); void knjs__Math_tanh(KInt xUpper, KInt xLower); void knjs__Math_trunc(KInt xUpper, KInt xLower); void knjs__Math_hypot(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower); void knjs__Math_max(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower); void knjs__Math_min(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower); void knjs__Math_pow(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower); } #endif // KONAN_WASM #endif // RUNTIME_KOTLINMATH_H ================================================ FILE: runtime/src/main/cpp/Memory.h ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_MEMORY_H #define RUNTIME_MEMORY_H #include #include "KAssert.h" #include "Common.h" #include "TypeInfo.h" #include "Atomic.h" #include "PointerBits.h" #include "Utils.hpp" typedef enum { // Must match to permTag() in Kotlin. OBJECT_TAG_PERMANENT_CONTAINER = 1 << 0, OBJECT_TAG_NONTRIVIAL_CONTAINER = 1 << 1, // Keep in sync with immTypeInfoMask in Kotlin. OBJECT_TAG_MASK = (1 << 2) - 1 } ObjectTag; struct ArrayHeader; struct MetaObjHeader; // Header of every object. struct ObjHeader { TypeInfo* typeInfoOrMeta_; // Returns `nullptr` if it's not a meta object. static MetaObjHeader* AsMetaObject(TypeInfo* typeInfo) noexcept { auto* typeInfoOrMeta = clearPointerBits(typeInfo, OBJECT_TAG_MASK); if (typeInfoOrMeta != typeInfoOrMeta->typeInfo_) { return reinterpret_cast(typeInfoOrMeta); } else { return nullptr; } } const TypeInfo* type_info() const { return clearPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK)->typeInfo_; } bool has_meta_object() const { return AsMetaObject(typeInfoOrMeta_) != nullptr; } MetaObjHeader* meta_object() { if (auto* metaObject = AsMetaObject(typeInfoOrMeta_)) { return metaObject; } return createMetaObject(this); } ALWAYS_INLINE ObjHeader** GetWeakCounterLocation(); #ifdef KONAN_OBJC_INTEROP ALWAYS_INLINE void* GetAssociatedObject(); ALWAYS_INLINE void** GetAssociatedObjectLocation(); ALWAYS_INLINE void SetAssociatedObject(void* obj); #endif inline bool local() const { unsigned bits = getPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK); return (bits & (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER)) == (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER); } // Unsafe cast to ArrayHeader. Use carefully! ArrayHeader* array() { return reinterpret_cast(this); } const ArrayHeader* array() const { return reinterpret_cast(this); } inline bool permanent() const { return hasPointerBits(typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER); } inline bool heap() const { return getPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK) == 0; } static MetaObjHeader* createMetaObject(ObjHeader* object); static void destroyMetaObject(ObjHeader* object); }; // Header of value type array objects. Keep layout in sync with that of object header. struct ArrayHeader { TypeInfo* typeInfoOrMeta_; const TypeInfo* type_info() const { return clearPointerBits(typeInfoOrMeta_, OBJECT_TAG_MASK)->typeInfo_; } ObjHeader* obj() { return reinterpret_cast(this); } const ObjHeader* obj() const { return reinterpret_cast(this); } // Elements count. Element size is stored in instanceSize_ field of TypeInfo, negated. uint32_t count_; }; ALWAYS_INLINE bool isFrozen(const ObjHeader* obj); ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj); ALWAYS_INLINE bool isShareable(const ObjHeader* obj); class ForeignRefManager; typedef ForeignRefManager* ForeignRefContext; #ifdef __cplusplus extern "C" { #endif #define OBJ_RESULT __result__ #define OBJ_GETTER0(name) ObjHeader* name(ObjHeader** OBJ_RESULT) #define OBJ_GETTER(name, ...) ObjHeader* name(__VA_ARGS__, ObjHeader** OBJ_RESULT) #define RETURN_OBJ(value) { ObjHeader* __obj = value; \ UpdateReturnRef(OBJ_RESULT, __obj); \ return __obj; } #define RETURN_RESULT_OF0(name) { \ ObjHeader* __obj = name(OBJ_RESULT); \ return __obj; \ } #define RETURN_RESULT_OF(name, ...) { \ ObjHeader* __result = name(__VA_ARGS__, OBJ_RESULT); \ return __result; \ } struct MemoryState; MemoryState* InitMemory(bool firstRuntime); void DeinitMemory(MemoryState*, bool destroyRuntime); void RestoreMemory(MemoryState*); // // Object allocation. // // Allocation can happen in either GLOBAL, FRAME or ARENA scope. Depending on that, // Alloc* or ArenaAlloc* is called. Regular alloc means allocation happens in the heap, // and each object gets its individual container. Otherwise, allocator uses aux slot in // an implementation-defined manner, current behavior is to keep arena pointer there. // Arena containers are not reference counted, and is explicitly freed when leaving // its owner frame. // Escape analysis algorithm is the provider of information for decision on exact aux slot // selection, and comes from upper bound esteemation of object lifetime. // OBJ_GETTER(AllocInstance, const TypeInfo* type_info) RUNTIME_NOTHROW; OBJ_GETTER(AllocArrayInstance, const TypeInfo* type_info, int32_t elements); OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); // `initialValue` may be `nullptr`, which signifies that the appropriate initial value was already // set by static initialization. // TODO: When global initialization becomes lazy, this signature won't do. void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) RUNTIME_NOTHROW; // // Object reference management. // // Reference management scheme we use assumes significant degree of flexibility, so that // one could implement either pure reference counting scheme, or tracing collector without // much ado. // Most important primitive is Update*Ref() API, which modifies location to use new // object reference. In pure reference counted scheme it will check old value, // decrement reference, increment counter on the new value, and store it into the field. // In tracing collector-like scheme, only field updates counts, and all other operations are // essentially no-ops. // // On codegeneration phase we adopt following approaches: // - every stack frame has several slots, holding object references (allRefs) // - those are known by compiler (and shall be grouped together) // - it keeps all locally allocated objects in such slot // - all local variables keeping an object also allocate a slot // - most manipulations on objects happens in SSA variables and do no affect slots // - exception handlers knowns slot locations for every function, and can update references // in intermediate frames when throwing // // NOTE: Must match `MemoryModel` in `Platform.kt` enum class MemoryModel { kStrict = 0, kRelaxed = 1, kExperimental = 2, }; // Controls the current memory model, is compile-time constant. extern const MemoryModel CurrentMemoryModel; // Sets stack location. void SetStackRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; // Sets heap location. void SetHeapRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; // Zeroes heap location. void ZeroHeapRef(ObjHeader** location) RUNTIME_NOTHROW; // Zeroes an array. void ZeroArrayRefs(ArrayHeader* array) RUNTIME_NOTHROW; // Zeroes stack location. void ZeroStackRef(ObjHeader** location) RUNTIME_NOTHROW; // Updates stack location. void UpdateStackRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; // Updates heap/static data location. void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; // Updates heap/static data in one array. void UpdateHeapRefsInsideOneArray(const ArrayHeader* array, int fromIndex, int toIndex, int count) RUNTIME_NOTHROW; // Updates location if it is null, atomically. void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) RUNTIME_NOTHROW; // Updates reference in return slot. void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) RUNTIME_NOTHROW; // Compares and swaps reference with taken lock. OBJ_GETTER(SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) RUNTIME_NOTHROW; // Sets reference with taken lock. void SetHeapRefLocked(ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) RUNTIME_NOTHROW; // Reads reference with taken lock. OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) RUNTIME_NOTHROW; OBJ_GETTER(ReadHeapRefNoLock, ObjHeader* object, int32_t index); // Called on frame enter, if it has object slots. void EnterFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; // Called on frame leave, if it has object slots. void LeaveFrame(ObjHeader** start, int parameters, int count) RUNTIME_NOTHROW; // Clears object subgraph references from memory subsystem, and optionally // checks if subgraph referenced by given root is disjoint from the rest of // object graph, i.e. no external references exists. bool ClearSubgraphReferences(ObjHeader* root, bool checked) RUNTIME_NOTHROW; // Creates stable pointer out of the object. void* CreateStablePointer(ObjHeader* obj) RUNTIME_NOTHROW; // Disposes stable pointer to the object. void DisposeStablePointer(void* pointer) RUNTIME_NOTHROW; // Translate stable pointer to object reference. OBJ_GETTER(DerefStablePointer, void*) RUNTIME_NOTHROW; // Move stable pointer ownership. OBJ_GETTER(AdoptStablePointer, void*) RUNTIME_NOTHROW; // Check mutability state. void MutationCheck(ObjHeader* obj); void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) RUNTIME_NOTHROW; // Freeze object subgraph. void FreezeSubgraph(ObjHeader* obj); // Ensure this object shall block freezing. void EnsureNeverFrozen(ObjHeader* obj); // Add TLS object storage, called by the generated code. void AddTLSRecord(MemoryState* memory, void** key, int size) RUNTIME_NOTHROW; // Allocate storage for TLS. `AddTLSRecord` cannot be called after this. void CommitTLSStorage(MemoryState* memory) RUNTIME_NOTHROW; // Clear TLS object storage. void ClearTLS(MemoryState* memory) RUNTIME_NOTHROW; // Lookup element in TLS object storage. ObjHeader** LookupTLS(void** key, int index) RUNTIME_NOTHROW; // APIs for the async GC. void GC_RegisterWorker(void* worker) RUNTIME_NOTHROW; void GC_UnregisterWorker(void* worker) RUNTIME_NOTHROW; void GC_CollectorCallback(void* worker) RUNTIME_NOTHROW; void Kotlin_native_internal_GC_collect(ObjHeader*); void Kotlin_native_internal_GC_collectCyclic(ObjHeader*); void Kotlin_native_internal_GC_suspend(ObjHeader*); void Kotlin_native_internal_GC_resume(ObjHeader*); void Kotlin_native_internal_GC_stop(ObjHeader*); void Kotlin_native_internal_GC_start(ObjHeader*); void Kotlin_native_internal_GC_setThreshold(ObjHeader*, int32_t value); int32_t Kotlin_native_internal_GC_getThreshold(ObjHeader*); void Kotlin_native_internal_GC_setCollectCyclesThreshold(ObjHeader*, int64_t value); int64_t Kotlin_native_internal_GC_getCollectCyclesThreshold(ObjHeader*); void Kotlin_native_internal_GC_setThresholdAllocations(ObjHeader*, int64_t value); int64_t Kotlin_native_internal_GC_getThresholdAllocations(ObjHeader*); void Kotlin_native_internal_GC_setTuneThreshold(ObjHeader*, int32_t value); bool Kotlin_native_internal_GC_getTuneThreshold(ObjHeader*); OBJ_GETTER(Kotlin_native_internal_GC_detectCycles, ObjHeader*); OBJ_GETTER(Kotlin_native_internal_GC_findCycle, ObjHeader*, ObjHeader* root); bool Kotlin_native_internal_GC_getCyclicCollector(ObjHeader* gc); void Kotlin_native_internal_GC_setCyclicCollector(ObjHeader* gc, bool value); bool Kotlin_Any_isShareable(ObjHeader* thiz); void Kotlin_Any_share(ObjHeader* thiz); void PerformFullGC(MemoryState* memory) RUNTIME_NOTHROW; bool TryAddHeapRef(const ObjHeader* object); void ReleaseHeapRef(const ObjHeader* object) RUNTIME_NOTHROW; void ReleaseHeapRefNoCollect(const ObjHeader* object) RUNTIME_NOTHROW; ForeignRefContext InitLocalForeignRef(ObjHeader* object); ForeignRefContext InitForeignRef(ObjHeader* object); void DeinitForeignRef(ObjHeader* object, ForeignRefContext context); bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context); // Should be used when reference is read from a possibly shared variable, // and there's nothing else keeping the object alive. void AdoptReferenceFromSharedVariable(ObjHeader* object); void CheckGlobalsAccessible(); // Sets state of the current thread to NATIVE (used by the new MM). ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative(); // Sets state of the current thread to RUNNABLE (used by the new MM). ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable(); // Safe point callbacks from Kotlin code generator. void Kotlin_mm_safePointFunctionEpilogue() RUNTIME_NOTHROW; void Kotlin_mm_safePointWhileLoopBody() RUNTIME_NOTHROW; void Kotlin_mm_safePointExceptionUnwind() RUNTIME_NOTHROW; #ifdef __cplusplus } #endif struct FrameOverlay { void* arena; FrameOverlay* previous; // As they go in pair, sizeof(FrameOverlay) % sizeof(void*) == 0 is always held. int32_t parameters; int32_t count; }; // Class holding reference to an object, holding object during C++ scope. class ObjHolder { public: ObjHolder() : obj_(nullptr) { EnterFrame(frame(), 0, sizeof(*this)/sizeof(void*)); } explicit ObjHolder(const ObjHeader* obj) { EnterFrame(frame(), 0, sizeof(*this)/sizeof(void*)); ::SetStackRef(slot(), obj); } ~ObjHolder() { LeaveFrame(frame(), 0, sizeof(*this)/sizeof(void*)); } ObjHeader* obj() { return obj_; } const ObjHeader* obj() const { return obj_; } ObjHeader** slot() { return &obj_; } void clear() { ::ZeroStackRef(&obj_); } private: ObjHeader** frame() { return reinterpret_cast(&frame_); } FrameOverlay frame_; ObjHeader* obj_; }; class ExceptionObjHolder { public: #if !KONAN_NO_EXCEPTIONS static void Throw(ObjHeader* exception) RUNTIME_NORETURN; ObjHeader* GetExceptionObject() noexcept; #endif // Exceptions are not on a hot path, so having virtual dispatch is fine. virtual ~ExceptionObjHolder() = default; }; namespace kotlin { namespace mm { // Returns the MemoryState for the current thread. The runtime must be initialized. // Try not to use it very often, as (1) thread local access can be slow on some platforms, // (2) TLS gets deallocated before our thread destruction hooks run. MemoryState* GetMemoryState(); } // namespace mm enum class ThreadState { kRunnable, kNative }; // Switches the state of the given thread to `newState` and returns the previous thread state. ALWAYS_INLINE ThreadState SwitchThreadState(MemoryState* thread, ThreadState newState) noexcept; // Asserts that the given thread is in the given state. ALWAYS_INLINE void AssertThreadState(MemoryState* thread, ThreadState expected) noexcept; // Asserts that the current thread is in the the given state. ALWAYS_INLINE inline void AssertThreadState(ThreadState expected) noexcept { AssertThreadState(mm::GetMemoryState(), expected); } // Scopely sets the given thread state for the given thread. class ThreadStateGuard final : private Pinned { public: // Set the state for the given thread. ThreadStateGuard(MemoryState* thread, ThreadState state) noexcept : thread_(thread) { oldState_ = SwitchThreadState(thread_, state); } // Sets the state for the current thread. explicit ThreadStateGuard(ThreadState state) noexcept : ThreadStateGuard(mm::GetMemoryState(), state) {}; ~ThreadStateGuard() noexcept { SwitchThreadState(thread_, oldState_); } private: MemoryState* thread_; ThreadState oldState_; }; // Calls the given function in the `Runnable` thread state. template ALWAYS_INLINE inline R CallKotlin(R(*kotlinFunction)(Args...), Args... args) { ThreadStateGuard guard(ThreadState::kRunnable); return kotlinFunction(std::forward(args)...); } // Calls the given function in the `Runnable` thread state. The function must be marked as RUNTIME_NORETURN. // If the function returns, behaviour is undefined. template ALWAYS_INLINE RUNTIME_NORETURN inline void CallKotlinNoReturn(void(*noreturnKotlinFunction)(Args...), Args... args) { CallKotlin(noreturnKotlinFunction, std::forward(args)...); RuntimeFail("The function must not return"); } } // namespace kotlin #endif // RUNTIME_MEMORY_H ================================================ FILE: runtime/src/main/cpp/MemorySharedRefs.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Exceptions.h" #include "MemorySharedRefs.hpp" #include "Runtime.h" #include "Types.h" extern "C" { // Returns a string describing object at `address` of type `typeInfo`. OBJ_GETTER(DescribeObjectForDebugging, KConstNativePtr typeInfo, KConstNativePtr address); } // extern "C" namespace { inline bool isForeignRefAccessible(ObjHeader* object, ForeignRefContext context) { // If runtime has not been initialized on this thread, then the object is either unowned or shared. // In the former case initialized runtime is required to throw exceptions // in the latter case -- to provide proper execution context for caller. Kotlin_initRuntimeIfNeeded(); return IsForeignRefAccessible(object, context); } RUNTIME_NORETURN inline void throwIllegalSharingException(ObjHeader* object) { // TODO: add some info about the context. // Note: retrieving 'type_info()' is supposed to be correct even for unowned object. ThrowIllegalObjectSharingException(object->type_info(), object); } RUNTIME_NORETURN inline void terminateWithIllegalSharingException(ObjHeader* object) { #if KONAN_NO_EXCEPTIONS // This will terminate. throwIllegalSharingException(object); #else try { throwIllegalSharingException(object); } catch (...) { // A trick to terminate with unhandled exception. This will print a stack trace // and write to iOS crash log. std::terminate(); } #endif } template bool ensureRefAccessible(ObjHeader* object, ForeignRefContext context) { static_assert(errorPolicy != ErrorPolicy::kIgnore, "Must've been handled by specialization"); if (isForeignRefAccessible(object, context)) { return true; } switch (errorPolicy) { case ErrorPolicy::kDefaultValue: return false; case ErrorPolicy::kThrow: throwIllegalSharingException(object); case ErrorPolicy::kTerminate: terminateWithIllegalSharingException(object); } } template <> bool ensureRefAccessible(ObjHeader* object, ForeignRefContext context) { return true; } } // namespace void KRefSharedHolder::initLocal(ObjHeader* obj) { RuntimeAssert(obj != nullptr, "must not be null"); context_ = InitLocalForeignRef(obj); obj_ = obj; } void KRefSharedHolder::init(ObjHeader* obj) { RuntimeAssert(obj != nullptr, "must not be null"); context_ = InitForeignRef(obj); obj_ = obj; } template ObjHeader* KRefSharedHolder::ref() const { if (!ensureRefAccessible(obj_, context_)) { return nullptr; } AdoptReferenceFromSharedVariable(obj_); return obj_; } template ObjHeader* KRefSharedHolder::ref() const; template ObjHeader* KRefSharedHolder::ref() const; template ObjHeader* KRefSharedHolder::ref() const; void KRefSharedHolder::dispose() const { if (obj_ == nullptr) { // To handle the case when it is not initialized. See [KotlinMutableSet/Dictionary dealloc]. return; } DeinitForeignRef(obj_, context_); } OBJ_GETTER0(KRefSharedHolder::describe) const { // Note: retrieving 'type_info()' is supposed to be correct even for unowned object. RETURN_RESULT_OF(DescribeObjectForDebugging, obj_->type_info(), obj_); } void BackRefFromAssociatedObject::initAndAddRef(ObjHeader* obj) { RuntimeAssert(obj != nullptr, "must not be null"); obj_ = obj; // Generally a specialized addRef below: context_ = InitForeignRef(obj); refCount = 1; } template void BackRefFromAssociatedObject::addRef() { static_assert(errorPolicy != ErrorPolicy::kDefaultValue, "Cannot use default return value here"); if (atomicAdd(&refCount, 1) == 1) { if (obj_ == nullptr) return; // E.g. after [detach]. // There are no references to the associated object itself, so Kotlin object is being passed from Kotlin, // and it is owned therefore. ensureRefAccessible(obj_, context_); // TODO: consider removing explicit verification. // Foreign reference has already been deinitialized (see [releaseRef]). // Create a new one: context_ = InitForeignRef(obj_); } } template void BackRefFromAssociatedObject::addRef(); template void BackRefFromAssociatedObject::addRef(); template bool BackRefFromAssociatedObject::tryAddRef() { static_assert(errorPolicy != ErrorPolicy::kDefaultValue, "Cannot use default return value here"); if (obj_ == nullptr) return false; // E.g. after [detach]. // Suboptimal but simple: ensureRefAccessible(obj_, context_); ObjHeader* obj = obj_; if (!TryAddHeapRef(obj)) return false; RuntimeAssert(isForeignRefAccessible(obj_, context_), "Cannot be inaccessible because of the check above"); // TODO: This is a very weird way to ask for "unsafe" addRef. addRef(); ReleaseHeapRefNoCollect(obj); // Balance TryAddHeapRef. // TODO: consider optimizing for non-shared objects. return true; } template bool BackRefFromAssociatedObject::tryAddRef(); template bool BackRefFromAssociatedObject::tryAddRef(); void BackRefFromAssociatedObject::releaseRef() { ForeignRefContext context = context_; if (atomicAdd(&refCount, -1) == 0) { if (obj_ == nullptr) return; // E.g. after [detach]. // Note: by this moment "subsequent" addRef may have already happened and patched context_. // So use the value loaded before refCount update: DeinitForeignRef(obj_, context); // From this moment [context] is generally a dangling pointer. // This is handled in [IsForeignRefAccessible] and [addRef]. // TODO: This probably isn't fine in new MM. Make sure it works. } } void BackRefFromAssociatedObject::detach() { RuntimeAssert(atomicGet(&refCount) == 0, "unexpected refCount"); obj_ = nullptr; // Handled in addRef/tryAddRef/releaseRef/ref. } template ObjHeader* BackRefFromAssociatedObject::ref() const { RuntimeAssert(obj_ != nullptr, "no valid Kotlin object found"); if (!ensureRefAccessible(obj_, context_)) { return nullptr; } AdoptReferenceFromSharedVariable(obj_); return obj_; } template ObjHeader* BackRefFromAssociatedObject::ref() const; template ObjHeader* BackRefFromAssociatedObject::ref() const; template ObjHeader* BackRefFromAssociatedObject::ref() const; extern "C" { RUNTIME_NOTHROW void KRefSharedHolder_initLocal(KRefSharedHolder* holder, ObjHeader* obj) { holder->initLocal(obj); } RUNTIME_NOTHROW void KRefSharedHolder_init(KRefSharedHolder* holder, ObjHeader* obj) { holder->init(obj); } RUNTIME_NOTHROW void KRefSharedHolder_dispose(const KRefSharedHolder* holder) { holder->dispose(); } RUNTIME_NOTHROW ObjHeader* KRefSharedHolder_ref(const KRefSharedHolder* holder) { return holder->ref(); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/MemorySharedRefs.hpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MEMORYSHAREDREFS_HPP #define RUNTIME_MEMORYSHAREDREFS_HPP #include #include "Memory.h" // TODO: Generalize for uses outside this file. enum class ErrorPolicy { kIgnore, // Ignore any errors. (i.e. unsafe mode) kDefaultValue, // Return the default value from the function when an error happens. kThrow, // Throw a Kotlin exception when an error happens. The exact exception is chosen by the callee. kTerminate, // Terminate immediately when an error happens. }; class KRefSharedHolder { public: void initLocal(ObjHeader* obj); void init(ObjHeader* obj); // Error if called from the wrong worker with non-frozen obj_. template ObjHeader* ref() const; void dispose() const; OBJ_GETTER0(describe) const; private: ObjHeader* obj_; ForeignRefContext context_; }; static_assert(std::is_trivially_destructible_v, "KRefSharedHolder destructor is not guaranteed to be called."); class BackRefFromAssociatedObject { public: void initAndAddRef(ObjHeader* obj); // Error if refCount is zero and it's called from the wrong worker with non-frozen obj_. template void addRef(); // Error if called from the wrong worker with non-frozen obj_. template bool tryAddRef(); void releaseRef(); void detach(); // Error if called from the wrong worker with non-frozen obj_. template ObjHeader* ref() const; private: ObjHeader* obj_; // May be null before [initAndAddRef] or after [detach]. ForeignRefContext context_; volatile int refCount; }; static_assert( std::is_trivially_destructible_v, "BackRefFromAssociatedObject destructor is not guaranteed to be called."); #endif // RUNTIME_MEMORYSHAREDREFS_HPP ================================================ FILE: runtime/src/main/cpp/MultiSourceQueue.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MULTI_SOURCE_QUEUE_H #define RUNTIME_MULTI_SOURCE_QUEUE_H #include #include #include #include "Mutex.hpp" #include "Types.h" namespace kotlin { // A queue that is constructed by collecting subqueues from several `Producer`s. template class MultiSourceQueue { public: class Producer; // TODO: Consider switching from `KStdList` to `SingleLockList` to hide the constructor // and to not store the iterator. class Node : private Pinned, public KonanAllocatorAware { public: Node(const T& value, Producer* owner) noexcept : value_(value), owner_(owner) {} T& operator*() noexcept { return value_; } private: friend class MultiSourceQueue; T value_; std::atomic owner_; // `nullptr` signifies that `MultiSourceQueue` owns it. typename KStdList::iterator position_; }; class Producer { public: explicit Producer(MultiSourceQueue& owner) noexcept : owner_(owner) {} ~Producer() { Publish(); } Node* Insert(const T& value) noexcept { queue_.emplace_back(value, this); auto& node = queue_.back(); node.position_ = std::prev(queue_.end()); return &node; } void Erase(Node* node) noexcept { if (node->owner_ == this) { // If we own it, delete it immediately. queue_.erase(node->position_); return; } // If it's owned by the global queue or some other `Producer`, queue it. deletionQueue_.push_back(node); } // Merge `this` queue with owning `MultiSourceQueue`. `this` will have empty queue after the call. // This call is performed without heap allocations. TODO: Test that no allocations are happening. void Publish() noexcept { for (auto& node : queue_) { node.owner_ = nullptr; } std::lock_guard guard(owner_.mutex_); owner_.queue_.splice(owner_.queue_.end(), queue_); owner_.deletionQueue_.splice(owner_.deletionQueue_.end(), deletionQueue_); } void ClearForTests() noexcept { queue_.clear(); deletionQueue_.clear(); } private: MultiSourceQueue& owner_; // weak KStdList queue_; KStdList deletionQueue_; }; class Iterator { public: T& operator*() noexcept { return **position_; } Iterator& operator++() noexcept { ++position_; return *this; } bool operator==(const Iterator& rhs) const noexcept { return position_ == rhs.position_; } bool operator!=(const Iterator& rhs) const noexcept { return position_ != rhs.position_; } private: friend class MultiSourceQueue; explicit Iterator(const typename KStdList::iterator& position) noexcept : position_(position) {} typename KStdList::iterator position_; }; class Iterable : MoveOnly { public: Iterator begin() noexcept { return Iterator(owner_.queue_.begin()); } Iterator end() noexcept { return Iterator(owner_.queue_.end()); } private: friend class MultiSourceQueue; explicit Iterable(MultiSourceQueue& owner) noexcept : owner_(owner), guard_(owner_.mutex_) {} MultiSourceQueue& owner_; // weak std::unique_lock guard_; }; // Lock `MultiSourceQueue` for safe iteration. If element was scheduled for deletion, // it'll still be iterated. Use `ApplyDeletions` to remove those elements. Iterable Iter() noexcept { return Iterable(*this); } // Lock `MultiSourceQueue` and apply deletions. Only deletes elements that were published. void ApplyDeletions() noexcept { std::lock_guard guard(mutex_); KStdList remainingDeletions; auto it = deletionQueue_.begin(); while (it != deletionQueue_.end()) { auto next = std::next(it); Node* node = *it; if (node->owner_ != nullptr) { // If the `Node` is still owned by some `Producer`, skip it. remainingDeletions.splice(remainingDeletions.end(), deletionQueue_, it); } else { queue_.erase(node->position_); // `node` is invalid after this } it = next; } deletionQueue_ = std::move(remainingDeletions); } void ClearForTests() noexcept { queue_.clear(); deletionQueue_.clear(); } private: // Using `KStdList` as it allows to implement `Collect` without memory allocations, // which is important for GC mark phase. KStdList queue_; KStdList deletionQueue_; SpinLock mutex_; }; } // namespace kotlin #endif // RUNTIME_MULTI_SOURCE_QUEUE_H ================================================ FILE: runtime/src/main/cpp/MultiSourceQueueTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "MultiSourceQueue.hpp" #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "TestSupport.hpp" #include "Types.h" using namespace kotlin; namespace { template KStdVector Collect(MultiSourceQueue& queue) { KStdVector result; for (const auto& element : queue.Iter()) { result.push_back(element); } return result; } } // namespace using IntQueue = MultiSourceQueue; TEST(MultiSourceQueueTest, Insert) { IntQueue queue; IntQueue::Producer producer(queue); constexpr int kFirst = 1; constexpr int kSecond = 2; auto* node1 = producer.Insert(kFirst); auto* node2 = producer.Insert(kSecond); EXPECT_THAT(**node1, kFirst); EXPECT_THAT(**node2, kSecond); } TEST(MultiSourceQueueTest, EraseFromTheSameProducer) { IntQueue queue; IntQueue::Producer producer(queue); constexpr int kFirst = 1; constexpr int kSecond = 2; producer.Insert(kFirst); auto* node2 = producer.Insert(kSecond); producer.Erase(node2); producer.Publish(); auto actual = Collect(queue); EXPECT_THAT(actual, testing::ElementsAre(kFirst)); } TEST(MultiSourceQueueTest, EraseFromGlobal) { IntQueue queue; IntQueue::Producer producer(queue); constexpr int kFirst = 1; constexpr int kSecond = 2; producer.Insert(kFirst); auto* node2 = producer.Insert(kSecond); producer.Publish(); producer.Erase(node2); producer.Publish(); auto actual1 = Collect(queue); EXPECT_THAT(actual1, testing::ElementsAre(kFirst, kSecond)); queue.ApplyDeletions(); auto actual2 = Collect(queue); EXPECT_THAT(actual2, testing::ElementsAre(kFirst)); } TEST(MultiSourceQueueTest, EraseFromOtherProducer) { IntQueue queue; IntQueue::Producer producer1(queue); IntQueue::Producer producer2(queue); constexpr int kFirst = 1; constexpr int kSecond = 2; producer1.Insert(kFirst); auto* node2 = producer1.Insert(kSecond); producer2.Erase(node2); producer1.Publish(); auto actual1 = Collect(queue); EXPECT_THAT(actual1, testing::ElementsAre(kFirst, kSecond)); queue.ApplyDeletions(); auto actual2 = Collect(queue); EXPECT_THAT(actual2, testing::ElementsAre(kFirst, kSecond)); producer2.Publish(); auto actual3 = Collect(queue); EXPECT_THAT(actual3, testing::ElementsAre(kFirst, kSecond)); queue.ApplyDeletions(); auto actual4 = Collect(queue); EXPECT_THAT(actual4, testing::ElementsAre(kFirst)); } TEST(MultiSourceQueueTest, Empty) { IntQueue queue; auto actual = Collect(queue); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(MultiSourceQueueTest, DoNotPublish) { IntQueue queue; IntQueue::Producer producer(queue); producer.Insert(1); producer.Insert(2); auto actual = Collect(queue); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(MultiSourceQueueTest, Publish) { IntQueue queue; IntQueue::Producer producer1(queue); IntQueue::Producer producer2(queue); producer1.Insert(1); producer1.Insert(2); producer2.Insert(10); producer2.Insert(20); producer1.Publish(); producer2.Publish(); auto actual = Collect(queue); EXPECT_THAT(actual, testing::ElementsAre(1, 2, 10, 20)); } TEST(MultiSourceQueueTest, PublishSeveralTimes) { IntQueue queue; IntQueue::Producer producer(queue); // Add 2 elements and publish. producer.Insert(1); producer.Insert(2); producer.Publish(); // Add another element and publish. producer.Insert(3); producer.Publish(); // Publish without adding elements. producer.Publish(); // Add yet another two elements and publish. producer.Insert(4); producer.Insert(5); producer.Publish(); auto actual = Collect(queue); EXPECT_THAT(actual, testing::ElementsAre(1, 2, 3, 4, 5)); } TEST(MultiSourceQueueTest, PublishInDestructor) { IntQueue queue; { IntQueue::Producer producer(queue); producer.Insert(1); producer.Insert(2); } auto actual = Collect(queue); EXPECT_THAT(actual, testing::ElementsAre(1, 2)); } TEST(MultiSourceQueueTest, ConcurrentPublish) { IntQueue queue; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; KStdVector expected; for (int i = 0; i < kThreadCount; ++i) { expected.push_back(i); threads.emplace_back([i, &queue, &canStart, &readyCount]() { IntQueue::Producer producer(queue); producer.Insert(i); ++readyCount; while (!canStart) { } producer.Publish(); }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } auto actual = Collect(queue); EXPECT_THAT(actual, testing::UnorderedElementsAreArray(expected)); } TEST(MultiSourceQueueTest, IterWhileConcurrentPublish) { IntQueue queue; constexpr int kStartCount = 50; constexpr int kThreadCount = kDefaultThreadCount; KStdVector expectedBefore; KStdVector expectedAfter; IntQueue::Producer producer(queue); for (int i = 0; i < kStartCount; ++i) { expectedBefore.push_back(i); expectedAfter.push_back(i); producer.Insert(i); } producer.Publish(); std::atomic canStart(false); std::atomic readyCount(0); std::atomic startedCount(0); KStdVector threads; for (int i = 0; i < kThreadCount; ++i) { int j = i + kStartCount; expectedAfter.push_back(j); threads.emplace_back([j, &queue, &canStart, &startedCount, &readyCount]() { IntQueue::Producer producer(queue); producer.Insert(j); ++readyCount; while (!canStart) { } ++startedCount; producer.Publish(); }); } KStdVector actualBefore; { auto iter = queue.Iter(); while (readyCount < kThreadCount) { } canStart = true; while (startedCount < kThreadCount) { } for (int element : iter) { actualBefore.push_back(element); } } for (auto& t : threads) { t.join(); } EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore)); auto actualAfter = Collect(queue); EXPECT_THAT(actualAfter, testing::UnorderedElementsAreArray(expectedAfter)); } TEST(MultiSourceQueueTest, ConcurrentPublishAndApplyDeletions) { IntQueue queue; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); std::atomic startedCount(0); KStdVector threads; for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back([&queue, i, &canStart, &readyCount, &startedCount]() { IntQueue::Producer producer(queue); auto* node = producer.Insert(i); producer.Publish(); producer.Erase(node); ++readyCount; while (!canStart) { } ++startedCount; producer.Publish(); }); } while (readyCount < kThreadCount) { } canStart = true; while (startedCount < kThreadCount) { } queue.ApplyDeletions(); for (auto& t : threads) { t.join(); } // We do not know which elements were deleted at this point. Expecting not to crash by this point. // This must make the queue empty. queue.ApplyDeletions(); auto actual = Collect(queue); EXPECT_THAT(actual, testing::IsEmpty()); } ================================================ FILE: runtime/src/main/cpp/Mutex.hpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_MUTEX_H #define RUNTIME_MUTEX_H #include #include "KAssert.h" #include "Utils.hpp" namespace kotlin { class SpinLock : private Pinned { public: void lock() noexcept { while (!__sync_bool_compare_and_swap(&atomicInt, 0, 1)) { // TODO: yield. } } void unlock() noexcept { if (!__sync_bool_compare_and_swap(&atomicInt, 1, 0)) { RuntimeAssert(false, "Unable to unlock"); } } private: // TODO: Consider using `std::atomic_flag`. int32_t atomicInt = 0; }; } // namespace kotlin #endif // RUNTIME_MUTEX_H ================================================ FILE: runtime/src/main/cpp/Natives.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "KAssert.h" #include "Exceptions.h" #include "Memory.h" #include "Natives.h" #include "Types.h" extern "C" { // Any.kt KBoolean Kotlin_Any_equals(KConstRef thiz, KConstRef other) { return thiz == other; } KInt Kotlin_Any_hashCode(KConstRef thiz) { // Here we will use different mechanism for stable hashcode, using meta-objects // if moving collector will be used. return reinterpret_cast(thiz); } OBJ_GETTER(Kotlin_getStackTraceStrings, KConstRef stackTrace) { RETURN_RESULT_OF(GetStackTraceStrings, stackTrace); } // TODO: consider handling it with compiler magic instead. OBJ_GETTER0(Kotlin_native_internal_undefined) { RETURN_OBJ(nullptr); } void* Kotlin_interop_malloc(KLong size, KInt align) { if (size < 0 || static_cast>(size) > std::numeric_limits::max()) { return nullptr; } RuntimeAssert(align > 0, "Unsupported alignment"); RuntimeAssert((align & (align - 1)) == 0, "Alignment must be power of two"); void* result = konan::calloc_aligned(1, size, align); if ((reinterpret_cast(result) & (align - 1)) != 0) { // Unaligned! RuntimeAssert(false, "unsupported alignment"); } return result; } void Kotlin_interop_free(void* ptr) { konan::free(ptr); } void Kotlin_system_exitProcess(KInt status) { konan::exit(status); } const void* Kotlin_Any_getTypeInfo(KConstRef obj) { return obj->type_info(); } void Kotlin_CPointer_CopyMemory(KNativePtr to, KNativePtr from, KInt count) { memcpy(to, from, count); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Natives.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_NATIVES_H #define RUNTIME_NATIVES_H #include "Types.h" #include "Exceptions.h" #include "Memory.h" constexpr size_t alignUp(size_t size, size_t alignment) { return (size + alignment - 1) & ~(alignment - 1); } template inline T* AddressOfElementAt(ArrayHeader* obj, KInt index) { int8_t* body = reinterpret_cast(obj) + alignUp(sizeof(ArrayHeader), alignof(T)); return reinterpret_cast(body) + index; } template inline const T* AddressOfElementAt(const ArrayHeader* obj, KInt index) { const int8_t* body = reinterpret_cast(obj) + alignUp(sizeof(ArrayHeader), alignof(T)); return reinterpret_cast(body) + index; } // Optimized versions not accessing type info. inline KByte* ByteArrayAddressOfElementAt(ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline const KByte* ByteArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline KChar* CharArrayAddressOfElementAt(ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline const KChar* CharArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline KInt* IntArrayAddressOfElementAt(ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline const KInt* IntArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } // Consider aligning of base to sizeof(T). template inline T* PrimitiveArrayAddressOfElementAt(ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } template inline const T* PrimitiveArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline KRef* ArrayAddressOfElementAt(ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } inline const KRef* ArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) { return AddressOfElementAt(obj, index); } #ifdef __cplusplus extern "C" { #endif OBJ_GETTER0(TheEmptyString); void Kotlin_io_Console_println0(); void Kotlin_NativePtrArray_set(KRef thiz, KInt index, KNativePtr value); KNativePtr Kotlin_NativePtrArray_get(KConstRef thiz, KInt index); #ifdef __cplusplus } #endif #endif // RUNTIME_NATIVES_H ================================================ FILE: runtime/src/main/cpp/ObjCExceptions.cpp ================================================ #if KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG #include #include #include #include #include "Natives.h" #include "ObjCExceptions.h" #include "Types.h" extern "C" OBJ_GETTER(Kotlin_Throwable_getStackTrace, KRef throwable); static void writeStackTraceToBuffer(KRef throwable, char* buffer, unsigned long bufferSize) { if (bufferSize < 2) return; ObjHolder stackTraceHolder; ArrayHeader* stackTrace = Kotlin_Throwable_getStackTrace(throwable, stackTraceHolder.slot())->array(); char* bufferPointer = buffer; unsigned long remainingBytes = bufferSize; *(bufferPointer++) = '('; --remainingBytes; for (uint32_t index = 0; index < stackTrace->count_; ++index) { KNativePtr ptr = *PrimitiveArrayAddressOfElementAt(stackTrace, index); int bytes = snprintf(bufferPointer, remainingBytes, "0x%" PRIxPTR " ", reinterpret_cast(ptr)); if (bytes < 0 || static_cast(bytes) >= remainingBytes) { break; } bufferPointer += bytes; remainingBytes -= bytes; } *(bufferPointer - 1) = ')'; // Replace last space. *bufferPointer = '\0'; } #if !defined(MACHSIZE) #error "Define MACHSIZE to 32 or 64" #endif #if MACHSIZE == 32 typedef struct mach_header mach_header_target; typedef struct segment_command segment_command_target; typedef struct section section_target; static const uint32_t MH_MAGIC_TARGET = MH_MAGIC; static const uint32_t LC_SEGMENT_TARGET = LC_SEGMENT; #elif MACHSIZE == 64 typedef struct mach_header_64 mach_header_target; typedef struct segment_command_64 segment_command_target; typedef struct section_64 section_target; static const uint32_t MH_MAGIC_TARGET = MH_MAGIC_64; static const uint32_t LC_SEGMENT_TARGET = LC_SEGMENT_64; #else #error "Impossible MACHSIZE" #endif static mach_header_target* findCoreFoundationMachHeader() { Dl_info info; if (dladdr(reinterpret_cast(&CFRunLoopRun), &info) == 0) return nullptr; return reinterpret_cast(info.dli_fbase); } template bool bufferEqualsString(const char (&buffer)[n], const char* str) { return strncmp(buffer, str, n) == 0; } static char* findExceptionBacktraceSection(unsigned long *size) { mach_header_target* header = findCoreFoundationMachHeader(); if (header == nullptr) return nullptr; if (header->magic != MH_MAGIC_TARGET) return nullptr; uintptr_t textVmaddr = 0; load_command* loadCommand = reinterpret_cast(header + 1); for (uint32_t loadCommandIndex = 0; loadCommandIndex < header->ncmds; ++loadCommandIndex) { if (loadCommand->cmd == LC_SEGMENT_TARGET) { segment_command_target* segmentCommand = reinterpret_cast(loadCommand); if (bufferEqualsString(segmentCommand->segname, "__TEXT")) { textVmaddr = segmentCommand->vmaddr; } if (bufferEqualsString(segmentCommand->segname, "__DATA")) { section_target* sections = reinterpret_cast(segmentCommand + 1); for (uint32_t sectionIndex = 0; sectionIndex < segmentCommand->nsects; ++sectionIndex) { section_target* section = §ions[sectionIndex]; if (bufferEqualsString(section->sectname, "__cf_except_bt") && bufferEqualsString(section->segname, "__DATA")) { *size = section->size; return reinterpret_cast(reinterpret_cast(header) + section->addr - textVmaddr); } } } } loadCommand = reinterpret_cast(reinterpret_cast(loadCommand) + loadCommand->cmdsize); } return nullptr; } void ReportBacktraceToIosCrashLog(KRef throwable) { unsigned long bufferSize = 0; char* buffer = findExceptionBacktraceSection(&bufferSize); if (buffer == nullptr) return; // Note: access to this buffer is protected by a lock, but it is not easily accessible. // Instead assume that typically this buffer is accessed only during termination, and // rely on caller guaranteeing this code to be executed only before system termination handlers. writeStackTraceToBuffer(throwable, buffer, bufferSize); } #endif // KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG ================================================ FILE: runtime/src/main/cpp/ObjCExceptions.h ================================================ #ifndef RUNTIME_OBJCEXCEPTIONS_H #define RUNTIME_OBJCEXCEPTIONS_H #if KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG #include "Common.h" #include "Types.h" void ReportBacktraceToIosCrashLog(KRef throwable); #endif // KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG #endif // RUNTIME_OBJCEXCEPTIONS_H ================================================ FILE: runtime/src/main/cpp/ObjCExport.h ================================================ #ifndef RUNTIME_OBJCEXPORT_H #define RUNTIME_OBJCEXPORT_H #if KONAN_OBJC_INTEROP #import #import #import "Types.h" #import "Memory.h" extern "C" id objc_retain(id self); extern "C" id objc_retainBlock(id self); extern "C" void objc_release(id self); inline static id GetAssociatedObject(ObjHeader* obj) { return (id)obj->GetAssociatedObject(); } // Note: this function shall not be used on shared objects. inline static void SetAssociatedObject(ObjHeader* obj, id value) { obj->SetAssociatedObject((void*)value); } inline static id AtomicCompareAndSwapAssociatedObject(ObjHeader* obj, id expectedValue, id newValue) { id* location = reinterpret_cast(obj->GetAssociatedObjectLocation()); return __sync_val_compare_and_swap(location, expectedValue, newValue); } inline static OBJ_GETTER(AllocInstanceWithAssociatedObject, const TypeInfo* typeInfo, id associatedObject) { ObjHeader* result = AllocInstance(typeInfo, OBJ_RESULT); SetAssociatedObject(result, associatedObject); return result; } extern "C" id Kotlin_ObjCExport_refToObjC(ObjHeader* obj); extern "C" OBJ_GETTER(Kotlin_ObjCExport_refFromObjC, id obj); extern "C" id Kotlin_Interop_CreateNSStringFromKString(KRef str); extern "C" OBJ_GETTER(Kotlin_Interop_CreateKStringFromNSString, NSString* str); #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCEXPORT_H ================================================ FILE: runtime/src/main/cpp/ObjCExport.mm ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "Types.h" #import "Memory.h" #include "Natives.h" #include "ObjCInterop.h" #if KONAN_OBJC_INTEROP #import #import #import #import #import #import #import #import #import #import #import #import #import #import "ObjCExport.h" #import "ObjCExportInit.h" #import "ObjCExportPrivate.h" #import "ObjCMMAPI.h" #import "Runtime.h" #import "Mutex.hpp" #import "Exceptions.h" struct ObjCToKotlinMethodAdapter { const char* selector; const char* encoding; IMP imp; }; struct KotlinToObjCMethodAdapter { const char* selector; MethodNameHash nameSignature; ClassId interfaceId; int itableSize; int itableIndex; int vtableIndex; const void* kotlinImpl; }; struct ObjCTypeAdapter { const TypeInfo* kotlinTypeInfo; const void * const * kotlinVtable; int kotlinVtableSize; const MethodTableRecord* kotlinMethodTable; int kotlinMethodTableSize; const InterfaceTableRecord* kotlinItable; int kotlinItableSize; const char* objCName; const ObjCToKotlinMethodAdapter* directAdapters; int directAdapterNum; const ObjCToKotlinMethodAdapter* classAdapters; int classAdapterNum; const ObjCToKotlinMethodAdapter* virtualAdapters; int virtualAdapterNum; const KotlinToObjCMethodAdapter* reverseAdapters; int reverseAdapterNum; }; typedef id (*convertReferenceToObjC)(ObjHeader* obj); typedef OBJ_GETTER((*convertReferenceFromObjC), id obj); struct TypeInfoObjCExportAddition { /*convertReferenceToObjC*/ void* convert; Class objCClass; const ObjCTypeAdapter* typeAdapter; }; struct WritableTypeInfo { TypeInfoObjCExportAddition objCExport; }; static char associatedTypeInfoKey; extern "C" const TypeInfo* Kotlin_ObjCExport_getAssociatedTypeInfo(Class clazz) { return (const TypeInfo*)[objc_getAssociatedObject(clazz, &associatedTypeInfoKey) pointerValue]; } static void setAssociatedTypeInfo(Class clazz, const TypeInfo* typeInfo) { objc_setAssociatedObject(clazz, &associatedTypeInfoKey, [NSValue valueWithPointer:typeInfo], OBJC_ASSOCIATION_RETAIN); } extern "C" id Kotlin_ObjCExport_GetAssociatedObject(ObjHeader* obj) { return GetAssociatedObject(obj); } extern "C" OBJ_GETTER(Kotlin_ObjCExport_AllocInstanceWithAssociatedObject, const TypeInfo* typeInfo, id associatedObject) RUNTIME_NOTHROW; extern "C" OBJ_GETTER(Kotlin_ObjCExport_AllocInstanceWithAssociatedObject, const TypeInfo* typeInfo, id associatedObject) { RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, typeInfo, associatedObject); } static Class getOrCreateClass(const TypeInfo* typeInfo); extern "C" id objc_retainAutoreleaseReturnValue(id self); extern "C" ALWAYS_INLINE void Kotlin_ObjCExport_releaseAssociatedObject(void* associatedObject) { if (associatedObject != nullptr) { auto msgSend = reinterpret_cast(&objc_msgSend); msgSend(associatedObject, Kotlin_ObjCExport_releaseAsAssociatedObjectSelector); } } extern "C" id Kotlin_ObjCExport_convertUnit(ObjHeader* unitInstance) { static dispatch_once_t onceToken; static id instance = nullptr; dispatch_once(&onceToken, ^{ Class unitClass = getOrCreateClass(unitInstance->type_info()); instance = [[unitClass createWrapper:unitInstance] retain]; }); return instance; } extern "C" id Kotlin_ObjCExport_CreateNSStringFromKString(ObjHeader* str) { KChar* utf16Chars = CharArrayAddressOfElementAt(str->array(), 0); auto numBytes = str->array()->count_ * sizeof(KChar); if (str->permanent()) { return [[[NSString alloc] initWithBytesNoCopy:utf16Chars length:numBytes encoding:NSUTF16LittleEndianStringEncoding freeWhenDone:NO] autorelease]; } else { // TODO: consider making NSString subclass to avoid copying here. NSString* candidate = [[NSString alloc] initWithBytes:utf16Chars length:numBytes encoding:NSUTF16LittleEndianStringEncoding]; if (!isShareable(str)) { SetAssociatedObject(str, candidate); } else { id old = AtomicCompareAndSwapAssociatedObject(str, nullptr, candidate); if (old != nullptr) { objc_release(candidate); return objc_retainAutoreleaseReturnValue(old); } } return objc_retainAutoreleaseReturnValue(candidate); } } static const ObjCTypeAdapter* findAdapterByName( const char* name, const ObjCTypeAdapter** sortedAdapters, int adapterNum ) { int left = 0, right = adapterNum - 1; while (right >= left) { int mid = (left + right) / 2; int cmp = strcmp(name, sortedAdapters[mid]->objCName); if (cmp < 0) { right = mid - 1; } else if (cmp > 0) { left = mid + 1; } else { return sortedAdapters[mid]; } } return nullptr; } __attribute__((weak)) const ObjCTypeAdapter** Kotlin_ObjCExport_sortedClassAdapters = nullptr; __attribute__((weak)) int Kotlin_ObjCExport_sortedClassAdaptersNum = 0; __attribute__((weak)) const ObjCTypeAdapter** Kotlin_ObjCExport_sortedProtocolAdapters = nullptr; __attribute__((weak)) int Kotlin_ObjCExport_sortedProtocolAdaptersNum = 0; __attribute__((weak)) bool Kotlin_ObjCExport_initTypeAdapters = false; static const ObjCTypeAdapter* findClassAdapter(Class clazz) { return findAdapterByName(class_getName(clazz), Kotlin_ObjCExport_sortedClassAdapters, Kotlin_ObjCExport_sortedClassAdaptersNum ); } static const ObjCTypeAdapter* findProtocolAdapter(Protocol* prot) { return findAdapterByName(protocol_getName(prot), Kotlin_ObjCExport_sortedProtocolAdapters, Kotlin_ObjCExport_sortedProtocolAdaptersNum ); } static const ObjCTypeAdapter* getTypeAdapter(const TypeInfo* typeInfo) { return typeInfo->writableInfo_->objCExport.typeAdapter; } static void addProtocolForAdapter(Class clazz, const ObjCTypeAdapter* protocolAdapter) { Protocol* protocol = objc_getProtocol(protocolAdapter->objCName); if (protocol != nullptr) { class_addProtocol(clazz, protocol); class_addProtocol(object_getClass(clazz), protocol); } else { // TODO: construct the protocol in compiler instead, because this case can't be handled easily. } } static void addProtocolForInterface(Class clazz, const TypeInfo* interfaceInfo) { const ObjCTypeAdapter* protocolAdapter = getTypeAdapter(interfaceInfo); if (protocolAdapter != nullptr) { addProtocolForAdapter(clazz, protocolAdapter); } } extern "C" const TypeInfo* Kotlin_ObjCInterop_getTypeInfoForClass(Class clazz) { const TypeInfo* candidate = Kotlin_ObjCExport_getAssociatedTypeInfo(clazz); if (candidate != nullptr && (candidate->flags_ & TF_OBJC_DYNAMIC) == 0) { return candidate; } else { return nullptr; } } extern "C" const TypeInfo* Kotlin_ObjCInterop_getTypeInfoForProtocol(Protocol* protocol) { const ObjCTypeAdapter* typeAdapter = findProtocolAdapter(protocol); return (typeAdapter != nullptr) ? typeAdapter->kotlinTypeInfo : nullptr; } static const TypeInfo* getOrCreateTypeInfo(Class clazz); extern "C" void Kotlin_ObjCExport_initializeClass(Class clazz) { const ObjCTypeAdapter* typeAdapter = findClassAdapter(clazz); if (typeAdapter == nullptr) { getOrCreateTypeInfo(clazz); return; } const TypeInfo* typeInfo = typeAdapter->kotlinTypeInfo; bool isClassForPackage = typeInfo == nullptr; if (!isClassForPackage) { setAssociatedTypeInfo(clazz, typeInfo); } for (int i = 0; i < typeAdapter->directAdapterNum; ++i) { const ObjCToKotlinMethodAdapter* adapter = typeAdapter->directAdapters + i; SEL selector = sel_registerName(adapter->selector); BOOL added = class_addMethod(clazz, selector, adapter->imp, adapter->encoding); RuntimeAssert(added, "Unexpected selector clash"); } for (int i = 0; i < typeAdapter->classAdapterNum; ++i) { const ObjCToKotlinMethodAdapter* adapter = typeAdapter->classAdapters + i; SEL selector = sel_registerName(adapter->selector); BOOL added = class_addMethod(object_getClass(clazz), selector, adapter->imp, adapter->encoding); RuntimeAssert(added, "Unexpected selector clash"); } if (isClassForPackage) return; for (int i = 0; i < typeInfo->implementedInterfacesCount_; ++i) { addProtocolForInterface(clazz, typeInfo->implementedInterfaces_[i]); } } extern "C" ALWAYS_INLINE OBJ_GETTER(Kotlin_ObjCExport_convertUnmappedObjCObject, id obj) { const TypeInfo* typeInfo = getOrCreateTypeInfo(object_getClass(obj)); RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, typeInfo, objc_retain(obj)); } // Initialized by [ObjCExportClasses.mm]. extern "C" SEL Kotlin_ObjCExport_toKotlinSelector = nullptr; extern "C" SEL Kotlin_ObjCExport_releaseAsAssociatedObjectSelector = nullptr; static OBJ_GETTER(blockToKotlinImp, id self, SEL cmd); static OBJ_GETTER(boxedBooleanToKotlinImp, NSNumber* self, SEL cmd); static OBJ_GETTER(SwiftObject_toKotlinImp, id self, SEL cmd); static void SwiftObject_releaseAsAssociatedObjectImp(id self, SEL cmd); static void initTypeAdaptersFrom(const ObjCTypeAdapter** adapters, int count) { for (int index = 0; index < count; ++index) { const ObjCTypeAdapter* adapter = adapters[index]; const TypeInfo* typeInfo = adapter->kotlinTypeInfo; if (typeInfo != nullptr) { typeInfo->writableInfo_->objCExport.typeAdapter = adapter; } } } static void initTypeAdapters() { if (!Kotlin_ObjCExport_initTypeAdapters) return; initTypeAdaptersFrom(Kotlin_ObjCExport_sortedClassAdapters, Kotlin_ObjCExport_sortedClassAdaptersNum); initTypeAdaptersFrom(Kotlin_ObjCExport_sortedProtocolAdapters, Kotlin_ObjCExport_sortedProtocolAdaptersNum); } static void Kotlin_ObjCExport_initializeImpl() { RuntimeCheck(Kotlin_ObjCExport_toKotlinSelector != nullptr, "unexpected initialization order"); RuntimeCheck(Kotlin_ObjCExport_releaseAsAssociatedObjectSelector != nullptr, "unexpected initialization order"); initTypeAdapters(); SEL toKotlinSelector = Kotlin_ObjCExport_toKotlinSelector; Method toKotlinMethod = class_getClassMethod([NSObject class], toKotlinSelector); RuntimeAssert(toKotlinMethod != nullptr, ""); const char* toKotlinTypeEncoding = method_getTypeEncoding(toKotlinMethod); SEL releaseAsAssociatedObjectSelector = Kotlin_ObjCExport_releaseAsAssociatedObjectSelector; Method releaseAsAssociatedObjectMethod = class_getClassMethod([NSObject class], releaseAsAssociatedObjectSelector); RuntimeAssert(releaseAsAssociatedObjectMethod != nullptr, ""); const char* releaseAsAssociatedObjectTypeEncoding = method_getTypeEncoding(releaseAsAssociatedObjectMethod); Class nsBlockClass = objc_getClass("NSBlock"); RuntimeAssert(nsBlockClass != nullptr, "NSBlock class not found"); // Note: can't add it with category, because it would be considered as private API usage. BOOL added = class_addMethod(nsBlockClass, toKotlinSelector, (IMP)blockToKotlinImp, toKotlinTypeEncoding); RuntimeAssert(added, "Unable to add 'toKotlin:' method to NSBlock class"); // Note: __NSCFBoolean is not visible to linker, so this case can't be handled with a category too. Class booleanClass = objc_getClass("__NSCFBoolean"); RuntimeAssert(booleanClass != nullptr, "__NSCFBoolean class not found"); added = class_addMethod(booleanClass, toKotlinSelector, (IMP)boxedBooleanToKotlinImp, toKotlinTypeEncoding); RuntimeAssert(added, "Unable to add 'toKotlin:' method to __NSCFBoolean class"); for (const char* swiftRootClassName : { "SwiftObject", "_TtCs12_SwiftObject" }) { Class swiftRootClass = objc_getClass(swiftRootClassName); if (swiftRootClass != nullptr) { added = class_addMethod(swiftRootClass, toKotlinSelector, (IMP)SwiftObject_toKotlinImp, toKotlinTypeEncoding); RuntimeAssert(added, "Unable to add 'toKotlin:' method to SwiftObject class"); added = class_addMethod( swiftRootClass, releaseAsAssociatedObjectSelector, (IMP)SwiftObject_releaseAsAssociatedObjectImp, releaseAsAssociatedObjectTypeEncoding ); RuntimeAssert(added, "Unable to add 'releaseAsAssociatedObject' method to SwiftObject class"); } } } // Initializes ObjCExport for current process (if not initialized yet). // Generally this is equal to some "binary patching" (which is usually done at link time // but postponed until runtime here due to various reasons): // adds methods to Objective-C classes, initializes static memory with "constant" values etc. extern "C" void Kotlin_ObjCExport_initialize() { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Kotlin_ObjCExport_initializeImpl(); }); } static OBJ_GETTER(SwiftObject_toKotlinImp, id self, SEL cmd) { RETURN_RESULT_OF(Kotlin_ObjCExport_convertUnmappedObjCObject, self); } static void SwiftObject_releaseAsAssociatedObjectImp(id self, SEL cmd) { objc_release(self); } extern "C" OBJ_GETTER(Kotlin_boxBoolean, KBoolean value); static OBJ_GETTER(boxedBooleanToKotlinImp, NSNumber* self, SEL cmd) { RETURN_RESULT_OF(Kotlin_boxBoolean, self.boolValue); } struct Block_descriptor_1; // Based on https://clang.llvm.org/docs/Block-ABI-Apple.html and libclosure source. struct Block_literal_1 { void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor_1 *descriptor; // IFF (1<<25) // Or: // struct Block_descriptor_1_without_helpers* descriptor // if hasn't (1<<25). // imported variables }; struct Block_literal_1 exportBlockLiteral; struct Block_descriptor_1 { unsigned long int reserved; // NULL unsigned long int size; // sizeof(struct Block_literal_1) // optional helper functions void (*copy_helper)(void *dst, void *src); void (*dispose_helper)(void *src); // required ABI.2010.3.16 const char *signature; // IFF (1<<30) const void* layout; // IFF (1<<31) }; struct Block_descriptor_1_without_helpers { unsigned long int reserved; // NULL unsigned long int size; // sizeof(struct Block_literal_1) // required ABI.2010.3.16 const char *signature; // IFF (1<<30) const void* layout; // IFF (1<<31) }; static const char* getBlockEncoding(id block) { Block_literal_1* literal = reinterpret_cast(block); int flags = literal->flags; RuntimeAssert((flags & (1 << 30)) != 0, "block has no signature stored"); return (flags & (1 << 25)) != 0 ? literal->descriptor->signature : reinterpret_cast(literal->descriptor)->signature; } // Note: defined by compiler. extern "C" convertReferenceFromObjC* Kotlin_ObjCExport_blockToFunctionConverters; extern "C" int Kotlin_ObjCExport_blockToFunctionConverters_size; static OBJ_GETTER(blockToKotlinImp, id block, SEL cmd) { const char* encoding = getBlockEncoding(block); // TODO: optimize: NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:encoding]; int parameterCount = signature.numberOfArguments - 1; // 1 for the block itself. for (int i = 1; i <= parameterCount; ++i) { const char* argEncoding = [signature getArgumentTypeAtIndex:i]; if (argEncoding[0] != '@') { [NSException raise:NSGenericException format:@"Blocks with non-reference-typed arguments aren't supported (%s)", argEncoding]; } } const char* returnTypeEncoding = signature.methodReturnType; if (returnTypeEncoding[0] != '@') { [NSException raise:NSGenericException format:@"Blocks with non-reference-typed return value aren't supported (%s)", returnTypeEncoding]; } auto converter = parameterCount < Kotlin_ObjCExport_blockToFunctionConverters_size ? Kotlin_ObjCExport_blockToFunctionConverters[parameterCount] : nullptr; if (converter != nullptr) { RETURN_RESULT_OF(converter, block); } else { // There is no function class for this arity, so resulting object will not be cast to FunctionN class, // and it is enough to convert block to arbitrary object conforming Function. RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, theOpaqueFunctionTypeInfo, objc_retainBlock(block)); } } static id Kotlin_ObjCExport_refToObjC_slowpath(ObjHeader* obj); template static ALWAYS_INLINE id Kotlin_ObjCExport_refToObjCImpl(ObjHeader* obj) { if (obj == nullptr) return nullptr; id associatedObject = GetAssociatedObject(obj); if (associatedObject != nullptr) { return retainAutorelease ? objc_retainAutoreleaseReturnValue(associatedObject) : associatedObject; } // TODO: propagate [retainAutorelease] to the code below. convertReferenceToObjC converter = (convertReferenceToObjC)obj->type_info()->writableInfo_->objCExport.convert; if (converter != nullptr) { return converter(obj); } return Kotlin_ObjCExport_refToObjC_slowpath(obj); } extern "C" id Kotlin_ObjCExport_refToObjC(ObjHeader* obj) { // TODO: in some cases (e.g. when converting a bridge argument) performing retain-autorelease is not necessary. return Kotlin_ObjCExport_refToObjCImpl(obj); } extern "C" ALWAYS_INLINE id Kotlin_Interop_refToObjC(ObjHeader* obj) { return Kotlin_ObjCExport_refToObjCImpl(obj); } extern "C" ALWAYS_INLINE OBJ_GETTER(Kotlin_Interop_refFromObjC, id obj) { // TODO: consider removing this function. RETURN_RESULT_OF(Kotlin_ObjCExport_refFromObjC, obj); } extern "C" OBJ_GETTER(Kotlin_Interop_CreateObjCObjectHolder, id obj) { RuntimeAssert(obj != nullptr, "wrapped object must not be null"); const TypeInfo* typeInfo = theForeignObjCObjectTypeInfo; RETURN_RESULT_OF(AllocInstanceWithAssociatedObject, typeInfo, objc_retain(obj)); } extern "C" OBJ_GETTER(Kotlin_ObjCExport_refFromObjC, id obj) { if (obj == nullptr) RETURN_OBJ(nullptr); auto msgSend = reinterpret_cast(&objc_msgSend); RETURN_RESULT_OF(msgSend, obj, Kotlin_ObjCExport_toKotlinSelector); } static id convertKotlinObject(ObjHeader* obj) { Class clazz = obj->type_info()->writableInfo_->objCExport.objCClass; RuntimeAssert(clazz != nullptr, ""); return [clazz createWrapper:obj]; } static convertReferenceToObjC findConverterFromInterfaces(const TypeInfo* typeInfo) { const TypeInfo* foundTypeInfo = nullptr; for (int i = 0; i < typeInfo->implementedInterfacesCount_; ++i) { const TypeInfo* interfaceTypeInfo = typeInfo->implementedInterfaces_[i]; if ((interfaceTypeInfo->flags_ & TF_SUSPEND_FUNCTION) != 0) { // interfaceTypeInfo is a SuspendFunction$N interface. // So any instance of typeInfo is a suspend lambda or a suspend callable reference // (user-defined Kotlin classes implementing SuspendFunction$N are prohibited by the compiler). // // Such types also actually implement Function${N+1} interface as an optimization // (see e.g. [startCoroutineUninterceptedOrReturn implementation). // This fact is not user-visible, so ignoring Function${N+1} interface here // (and thus not converting such objects to Obj-C blocks) should be safe enough // (because such objects aren't expected to be passed from Kotlin to Swift // under formal Function${N+1} type). // // On the other hand, this fixes support for SuspendFunction$N type: it is mapped as // regular Kotlin interface, so its instances should be converted on a general basis // (i.e. to objects implementing Obj-C representation of SuspendFunction$N, not to Obj-C blocks). // // "If typeInfo is a suspend lambda or callable reference type, convert its instances on a regular basis": return nullptr; } if (interfaceTypeInfo->writableInfo_->objCExport.convert != nullptr) { if (foundTypeInfo == nullptr || IsSubInterface(interfaceTypeInfo, foundTypeInfo)) { foundTypeInfo = interfaceTypeInfo; } else if (!IsSubInterface(foundTypeInfo, interfaceTypeInfo)) { [NSException raise:NSGenericException format:@"Can't convert to Objective-C Kotlin object that is '%@' and '%@' and the same time", Kotlin_Interop_CreateNSStringFromKString(foundTypeInfo->relativeName_), Kotlin_Interop_CreateNSStringFromKString(interfaceTypeInfo->relativeName_)]; } } } return foundTypeInfo == nullptr ? nullptr : (convertReferenceToObjC)foundTypeInfo->writableInfo_->objCExport.convert; } static id Kotlin_ObjCExport_refToObjC_slowpath(ObjHeader* obj) { const TypeInfo* typeInfo = obj->type_info(); convertReferenceToObjC converter = nullptr; converter = findConverterFromInterfaces(typeInfo); if (converter == nullptr) { getOrCreateClass(typeInfo); converter = (typeInfo == theUnitTypeInfo) ? &Kotlin_ObjCExport_convertUnit : &convertKotlinObject; } typeInfo->writableInfo_->objCExport.convert = (void*)converter; return converter(obj); } static void buildITable(TypeInfo* result, const KStdOrderedMap>& interfaceVTables) { // Check if can use fast optimistic version - check if the size of the itable could be 2^k and <= 32. bool useFastITable; int itableSize = 1; for (; itableSize <= 32; itableSize <<= 1) { useFastITable = true; bool used[32]; memset(used, 0, sizeof(used)); for (auto& pair : interfaceVTables) { auto interfaceId = pair.first; auto index = interfaceId & (itableSize - 1); if (used[index]) { useFastITable = false; break; } used[index] = true; } if (useFastITable) break; } if (!useFastITable) itableSize = interfaceVTables.size(); auto itable_ = konanAllocArray(itableSize); result->interfaceTable_ = itable_; result->interfaceTableSize_ = useFastITable ? itableSize - 1 : -itableSize; if (useFastITable) { for (auto& pair : interfaceVTables) { auto interfaceId = pair.first; auto index = interfaceId & (itableSize - 1); itable_[index].id = interfaceId; } } else { // Otherwise: conservative version. // The table will be sorted since we're using KStdOrderedMap. int index = 0; for (auto& pair : interfaceVTables) { auto interfaceId = pair.first; itable_[index++].id = interfaceId; } } for (int i = 0; i < itableSize; ++i) { auto interfaceId = itable_[i].id; if (interfaceId == kInvalidInterfaceId) continue; auto interfaceVTableIt = interfaceVTables.find(interfaceId); RuntimeAssert(interfaceVTableIt != interfaceVTables.end(), ""); auto const& interfaceVTable = interfaceVTableIt->second; int interfaceVTableSize = interfaceVTable.size(); auto interfaceVTable_ = interfaceVTableSize == 0 ? nullptr : konanAllocArray(interfaceVTableSize); for (int j = 0; j < interfaceVTableSize; ++j) interfaceVTable_[j] = interfaceVTable[j]; itable_[i].vtable = interfaceVTable_; itable_[i].vtableSize = interfaceVTableSize; } } static const TypeInfo* createTypeInfo( const TypeInfo* superType, const KStdVector& superInterfaces, const KStdVector& vtable, const KStdVector& methodTable, const KStdOrderedMap>& interfaceVTables, const InterfaceTableRecord* superItable, int superItableSize, bool itableEqualsSuper, const TypeInfo* fieldsInfo ) { TypeInfo* result = (TypeInfo*)konanAllocMemory(sizeof(TypeInfo) + vtable.size() * sizeof(void*)); result->typeInfo_ = result; result->flags_ = TF_OBJC_DYNAMIC; result->superType_ = superType; if (fieldsInfo == nullptr) { result->instanceSize_ = superType->instanceSize_; result->objOffsets_ = superType->objOffsets_; result->objOffsetsCount_ = superType->objOffsetsCount_; // So TF_IMMUTABLE can also be inherited: if ((superType->flags_ & TF_IMMUTABLE) != 0) { result->flags_ |= TF_IMMUTABLE; } } else { result->instanceSize_ = fieldsInfo->instanceSize_; result->objOffsets_ = fieldsInfo->objOffsets_; result->objOffsetsCount_ = fieldsInfo->objOffsetsCount_; } result->classId_ = superType->classId_; KStdVector implementedInterfaces( superType->implementedInterfaces_, superType->implementedInterfaces_ + superType->implementedInterfacesCount_ ); KStdUnorderedSet usedInterfaces(implementedInterfaces.begin(), implementedInterfaces.end()); for (const TypeInfo* interface : superInterfaces) { if (usedInterfaces.insert(interface).second) { implementedInterfaces.push_back(interface); } } const TypeInfo** implementedInterfaces_ = konanAllocArray(implementedInterfaces.size()); for (size_t i = 0; i < implementedInterfaces.size(); ++i) { implementedInterfaces_[i] = implementedInterfaces[i]; } result->implementedInterfaces_ = implementedInterfaces_; result->implementedInterfacesCount_ = implementedInterfaces.size(); if (superItable != nullptr) { if (itableEqualsSuper) { result->interfaceTableSize_ = superItableSize; result->interfaceTable_ = superItable; } else { buildITable(result, interfaceVTables); } } MethodTableRecord* openMethods_ = konanAllocArray(methodTable.size()); for (size_t i = 0; i < methodTable.size(); ++i) openMethods_[i] = methodTable[i]; result->openMethods_ = openMethods_; result->openMethodsCount_ = methodTable.size(); result->packageName_ = nullptr; result->relativeName_ = nullptr; // TODO: add some info. result->writableInfo_ = (WritableTypeInfo*)konanAllocMemory(sizeof(WritableTypeInfo)); for (size_t i = 0; i < vtable.size(); ++i) result->vtable()[i] = vtable[i]; return result; } static void addDefinedSelectors(Class clazz, KStdUnorderedSet& result) { unsigned int objcMethodCount; Method* objcMethods = class_copyMethodList(clazz, &objcMethodCount); for (unsigned int i = 0; i < objcMethodCount; ++i) { result.insert(method_getName(objcMethods[i])); } if (objcMethods != nullptr) free(objcMethods); } static KStdVector getProtocolsAsInterfaces(Class clazz) { KStdVector result; KStdUnorderedSet handledProtocols; KStdVector protocolsToHandle; { unsigned int protocolCount; Protocol** protocols = class_copyProtocolList(clazz, &protocolCount); if (protocols != nullptr) { protocolsToHandle.insert(protocolsToHandle.end(), protocols, protocols + protocolCount); free(protocols); } } while (!protocolsToHandle.empty()) { Protocol* proto = protocolsToHandle[protocolsToHandle.size() - 1]; protocolsToHandle.pop_back(); if (handledProtocols.insert(proto).second) { const ObjCTypeAdapter* typeAdapter = findProtocolAdapter(proto); if (typeAdapter != nullptr) result.push_back(typeAdapter->kotlinTypeInfo); unsigned int protocolCount; Protocol** protocols = protocol_copyProtocolList(proto, &protocolCount); if (protocols != nullptr) { protocolsToHandle.insert(protocolsToHandle.end(), protocols, protocols + protocolCount); free(protocols); } } } return result; } static int getVtableSize(const TypeInfo* typeInfo) { for (const TypeInfo* current = typeInfo; current != nullptr; current = current->superType_) { auto typeAdapter = getTypeAdapter(current); if (typeAdapter != nullptr) return typeAdapter->kotlinVtableSize; } RuntimeAssert(false, ""); return -1; } static void insertOrReplace(KStdVector& methodTable, MethodNameHash nameSignature, void* entryPoint) { MethodTableRecord record = {nameSignature, entryPoint}; for (int i = methodTable.size() - 1; i >= 0; --i) { if (methodTable[i].nameSignature_ == nameSignature) { methodTable[i].methodEntryPoint_ = entryPoint; return; } else if (methodTable[i].nameSignature_ < nameSignature) { methodTable.insert(methodTable.begin() + (i + 1), record); return; } } methodTable.insert(methodTable.begin(), record); } static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter* adapter) { if (adapter->kotlinImpl == nullptr) { NSString* reason; switch (adapter->vtableIndex) { case -1: reason = @"it is final"; break; case -2: reason = @"original Kotlin method has more than one selector"; break; default: reason = @""; break; } [NSException raise:NSGenericException format:@"[%s %s] can't be overridden: %@", class_getName(clazz), adapter->selector, reason]; } } static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, const TypeInfo* fieldsInfo) { KStdUnorderedSet definedSelectors; addDefinedSelectors(clazz, definedSelectors); const ObjCTypeAdapter* superTypeAdapter = getTypeAdapter(superType); const void * const * superVtable = nullptr; int superVtableSize = getVtableSize(superType); const MethodTableRecord* superMethodTable = nullptr; int superMethodTableSize = 0; InterfaceTableRecord const* superITable = nullptr; int superITableSize = 0; if (superTypeAdapter != nullptr) { // Then super class is Kotlin class. // And if it is abstract, then vtable and method table are not available from TypeInfo, // but present in type adapter instead: superVtable = superTypeAdapter->kotlinVtable; superMethodTable = superTypeAdapter->kotlinMethodTable; superMethodTableSize = superTypeAdapter->kotlinMethodTableSize; superITable = superTypeAdapter->kotlinItable; superITableSize = superTypeAdapter->kotlinItableSize; } if (superVtable == nullptr) superVtable = superType->vtable(); if (superMethodTable == nullptr) { superMethodTable = superType->openMethods_; superMethodTableSize = superType->openMethodsCount_; } KStdVector vtable( superVtable, superVtable + superVtableSize ); KStdVector methodTable( superMethodTable, superMethodTable + superMethodTableSize ); if (superITable == nullptr) { superITable = superType->interfaceTable_; superITableSize = superType->interfaceTableSize_; } KStdOrderedMap> interfaceVTables; if (superITable != nullptr) { int actualItableSize = superITableSize >= 0 ? superITableSize + 1 : -superITableSize; for (int i = 0; i < actualItableSize; ++i) { auto& record = superITable[i]; auto interfaceId = record.id; if (interfaceId == kInvalidInterfaceId) continue; int vtableSize = record.vtableSize; KStdVector interfaceVTable(vtableSize); for (int j = 0; j < vtableSize; ++j) interfaceVTable[j] = record.vtable[j]; interfaceVTables.emplace(interfaceId, std::move(interfaceVTable)); } } KStdVector addedInterfaces = getProtocolsAsInterfaces(clazz); KStdVector supers( superType->implementedInterfaces_, superType->implementedInterfaces_ + superType->implementedInterfacesCount_ ); for (const TypeInfo* t = superType; t != nullptr; t = t->superType_) { supers.push_back(t); } bool itableEqualsSuper = true; auto addToITable = [&interfaceVTables](ClassId interfaceId, int methodIndex, VTableElement entry) { RuntimeAssert(interfaceId != kInvalidInterfaceId, ""); auto interfaceVTableIt = interfaceVTables.find(interfaceId); RuntimeAssert(interfaceVTableIt != interfaceVTables.end(), ""); auto& interfaceVTable = interfaceVTableIt->second; RuntimeAssert(methodIndex >= 0 && static_cast(methodIndex) < interfaceVTable.size(), ""); interfaceVTable[methodIndex] = entry; }; auto addITable = [&interfaceVTables, &itableEqualsSuper](ClassId interfaceId, int itableSize) { RuntimeAssert(itableSize >= 0, ""); auto interfaceVTablesIt = interfaceVTables.find(interfaceId); if (interfaceVTablesIt == interfaceVTables.end()) { itableEqualsSuper = false; interfaceVTables.emplace(interfaceId, KStdVector(itableSize)); } else { auto const& interfaceVTable = interfaceVTablesIt->second; RuntimeAssert(interfaceVTable.size() == static_cast(itableSize), ""); } }; // Compiler relies on using reverse adapters here from all supertypes // in [ObjCExportCodeGenerator.createReverseAdapters]. for (const TypeInfo* t : supers) { const ObjCTypeAdapter* typeAdapter = getTypeAdapter(t); if (typeAdapter == nullptr) continue; for (int i = 0; i < typeAdapter->reverseAdapterNum; ++i) { const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i]; if (definedSelectors.find(sel_registerName(adapter->selector)) == definedSelectors.end()) continue; throwIfCantBeOverridden(clazz, adapter); itableEqualsSuper = false; insertOrReplace(methodTable, adapter->nameSignature, const_cast(adapter->kotlinImpl)); if (adapter->vtableIndex != -1) vtable[adapter->vtableIndex] = adapter->kotlinImpl; if (adapter->itableIndex != -1 && superITable != nullptr) addToITable(adapter->interfaceId, adapter->itableIndex, adapter->kotlinImpl); } } // Compiler relies on using reverse adapters here from all supertypes // in [ObjCExportCodeGenerator.createReverseAdapters]. for (const TypeInfo* typeInfo : addedInterfaces) { const ObjCTypeAdapter* typeAdapter = getTypeAdapter(typeInfo); if (typeAdapter == nullptr) continue; if (superITable != nullptr) { // The interface vtable has to be created always in order for type checks to work. addITable(typeInfo->classId_, typeAdapter->kotlinItableSize); } for (int i = 0; i < typeAdapter->reverseAdapterNum; ++i) { itableEqualsSuper = false; const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i]; throwIfCantBeOverridden(clazz, adapter); insertOrReplace(methodTable, adapter->nameSignature, const_cast(adapter->kotlinImpl)); RuntimeAssert(adapter->vtableIndex == -1, ""); if (adapter->itableIndex != -1 && superITable != nullptr) { // In general, [adapter->interfaceId] might not be equal to [typeInfo->classId_]. auto interfaceId = adapter->interfaceId; addITable(interfaceId, adapter->itableSize); addToITable(interfaceId, adapter->itableIndex, adapter->kotlinImpl); } } } // TODO: consider forbidding the class being abstract. const TypeInfo* result = createTypeInfo(superType, addedInterfaces, vtable, methodTable, interfaceVTables, superITable, superITableSize, itableEqualsSuper, fieldsInfo); // TODO: it will probably never be requested, since such a class can't be instantiated in Kotlin. result->writableInfo_->objCExport.objCClass = clazz; return result; } static kotlin::SpinLock typeInfoCreationMutex; static const TypeInfo* getOrCreateTypeInfo(Class clazz) { const TypeInfo* result = Kotlin_ObjCExport_getAssociatedTypeInfo(clazz); if (result != nullptr) { return result; } Class superClass = class_getSuperclass(clazz); const TypeInfo* superType = superClass == nullptr ? theForeignObjCObjectTypeInfo : getOrCreateTypeInfo(superClass); std::lock_guard lockGuard(typeInfoCreationMutex); result = Kotlin_ObjCExport_getAssociatedTypeInfo(clazz); // double-checking. if (result == nullptr) { result = createTypeInfo(clazz, superType, nullptr); setAssociatedTypeInfo(clazz, result); } return result; } const TypeInfo* Kotlin_ObjCExport_createTypeInfoWithKotlinFieldsFrom(Class clazz, const TypeInfo* fieldsInfo) { Class superClass = class_getSuperclass(clazz); RuntimeCheck(superClass != nullptr, ""); const TypeInfo* superType = getOrCreateTypeInfo(superClass); return createTypeInfo(clazz, superType, fieldsInfo); } static kotlin::SpinLock classCreationMutex; static int anonymousClassNextId = 0; static void addVirtualAdapters(Class clazz, const ObjCTypeAdapter* typeAdapter) { for (int i = 0; i < typeAdapter->virtualAdapterNum; ++i) { const ObjCToKotlinMethodAdapter* adapter = typeAdapter->virtualAdapters + i; SEL selector = sel_registerName(adapter->selector); class_addMethod(clazz, selector, adapter->imp, adapter->encoding); } } static Class createClass(const TypeInfo* typeInfo, Class superClass) { RuntimeAssert(typeInfo->superType_ != nullptr, ""); int classIndex = (anonymousClassNextId++); KStdString className = Kotlin_ObjCInterop_getUniquePrefix(); className += "_kobjcc"; className += std::to_string(classIndex); Class result = objc_allocateClassPair(superClass, className.c_str(), 0); RuntimeCheck(result != nullptr, ""); // TODO: optimize by adding virtual adapters only for overridden methods. if (getTypeAdapter(typeInfo->superType_) == nullptr) { // class for super type is also synthesized, no need to add class adapters; } else { for (const TypeInfo* superType = typeInfo->superType_; superType != nullptr; superType = superType->superType_) { const ObjCTypeAdapter* typeAdapter = getTypeAdapter(superType); if (typeAdapter != nullptr) { addVirtualAdapters(result, typeAdapter); } } } KStdUnorderedSet superImplementedInterfaces( typeInfo->superType_->implementedInterfaces_, typeInfo->superType_->implementedInterfaces_ + typeInfo->superType_->implementedInterfacesCount_ ); for (int i = 0; i < typeInfo->implementedInterfacesCount_; ++i) { const TypeInfo* interface = typeInfo->implementedInterfaces_[i]; if (superImplementedInterfaces.find(interface) == superImplementedInterfaces.end()) { const ObjCTypeAdapter* typeAdapter = getTypeAdapter(interface); if (typeAdapter != nullptr) { addVirtualAdapters(result, typeAdapter); addProtocolForAdapter(result, typeAdapter); } } } objc_registerClassPair(result); // TODO: it will probably never be requested, since such a class can't be instantiated in Objective-C. setAssociatedTypeInfo(result, typeInfo); return result; } static Class getOrCreateClass(const TypeInfo* typeInfo) { Class result = typeInfo->writableInfo_->objCExport.objCClass; if (result != nullptr) { return result; } const ObjCTypeAdapter* typeAdapter = getTypeAdapter(typeInfo); if (typeAdapter != nullptr) { result = objc_getClass(typeAdapter->objCName); RuntimeAssert(result != nullptr, ""); typeInfo->writableInfo_->objCExport.objCClass = result; } else { Class superClass = getOrCreateClass(typeInfo->superType_); std::lock_guard lockGuard(classCreationMutex); // Note: non-recursive result = typeInfo->writableInfo_->objCExport.objCClass; // double-checking. if (result == nullptr) { result = createClass(typeInfo, superClass); RuntimeAssert(result != nullptr, ""); typeInfo->writableInfo_->objCExport.objCClass = result; } } return result; } extern "C" void Kotlin_ObjCExport_AbstractMethodCalled(id self, SEL selector) { [NSException raise:NSGenericException format:@"[%s %s] is abstract", class_getName(object_getClass(self)), sel_getName(selector)]; } #else extern "C" ALWAYS_INLINE void* Kotlin_Interop_refToObjC(ObjHeader* obj) { RuntimeAssert(false, "Unavailable operation"); return nullptr; } extern "C" ALWAYS_INLINE OBJ_GETTER(Kotlin_Interop_refFromObjC, void* obj) { RuntimeAssert(false, "Unavailable operation"); RETURN_OBJ(nullptr); } #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/main/cpp/ObjCExportCollectionUtils.mm ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "Memory.h" #import "Types.h" #if KONAN_OBJC_INTEROP #import #import #import #import #import "Exceptions.h" #import "ObjCExport.h" #import "ObjCExportCollections.h" extern "C" { // Imports from ObjCExportUtils.kt: OBJ_GETTER0(Kotlin_NSEnumeratorAsKIterator_create); void Kotlin_NSEnumeratorAsKIterator_done(KRef thiz); void Kotlin_NSEnumeratorAsKIterator_setNext(KRef thiz, KRef value); void Kotlin_ObjCExport_ThrowCollectionTooLarge(); void Kotlin_ObjCExport_ThrowCollectionConcurrentModification(); } static inline KInt objCSizeToKotlinOrThrow(NSUInteger size) { if (size > std::numeric_limits::max()) { Kotlin_ObjCExport_ThrowCollectionTooLarge(); } return size; } // Exported to ObjCExportUtils.kt: extern "C" KInt Kotlin_NSArrayAsKList_getSize(KRef obj) { NSArray* array = (NSArray*) GetAssociatedObject(obj); return objCSizeToKotlinOrThrow([array count]); } extern "C" OBJ_GETTER(Kotlin_NSArrayAsKList_get, KRef obj, KInt index) { NSArray* array = (NSArray*) GetAssociatedObject(obj); id element = [array objectAtIndex:index]; RETURN_RESULT_OF(refFromObjCOrNSNull, element); } extern "C" void Kotlin_NSMutableArrayAsKMutableList_add(KRef thiz, KInt index, KRef element) { NSMutableArray* mutableArray = (NSMutableArray*) GetAssociatedObject(thiz); [mutableArray insertObject:refToObjCOrNSNull(element) atIndex:index]; } extern "C" OBJ_GETTER(Kotlin_NSMutableArrayAsKMutableList_removeAt, KRef thiz, KInt index) { NSMutableArray* mutableArray = (NSMutableArray*) GetAssociatedObject(thiz); KRef res = refFromObjCOrNSNull([mutableArray objectAtIndex:index], OBJ_RESULT); [mutableArray removeObjectAtIndex:index]; return res; } extern "C" OBJ_GETTER(Kotlin_NSMutableArrayAsKMutableList_set, KRef thiz, KInt index, KRef element) { NSMutableArray* mutableArray = (NSMutableArray*) GetAssociatedObject(thiz); KRef res = refFromObjCOrNSNull([mutableArray objectAtIndex:index], OBJ_RESULT); [mutableArray replaceObjectAtIndex:index withObject:refToObjCOrNSNull(element)]; return res; } extern "C" void Kotlin_NSEnumeratorAsKIterator_computeNext(KRef thiz) { NSEnumerator* enumerator = (NSEnumerator*) GetAssociatedObject(thiz); id next = [enumerator nextObject]; if (next == nullptr) { Kotlin_NSEnumeratorAsKIterator_done(thiz); } else { ObjHolder holder; Kotlin_NSEnumeratorAsKIterator_setNext(thiz, refFromObjCOrNSNull(next, holder.slot())); } } extern "C" KInt Kotlin_NSSetAsKSet_getSize(KRef thiz) { NSSet* set = (NSSet*) GetAssociatedObject(thiz); return objCSizeToKotlinOrThrow(set.count); } extern "C" KBoolean Kotlin_NSSetAsKSet_contains(KRef thiz, KRef element) { NSSet* set = (NSSet*) GetAssociatedObject(thiz); return [set containsObject:refToObjCOrNSNull(element)]; } extern "C" OBJ_GETTER(Kotlin_NSSetAsKSet_getElement, KRef thiz, KRef element) { NSSet* set = (NSSet*) GetAssociatedObject(thiz); id res = [set member:refToObjCOrNSNull(element)]; RETURN_RESULT_OF(refFromObjCOrNSNull, res); } static inline OBJ_GETTER(CreateKIteratorFromNSEnumerator, NSEnumerator* enumerator) { RETURN_RESULT_OF(invokeAndAssociate, Kotlin_NSEnumeratorAsKIterator_create, objc_retain(enumerator)); } extern "C" OBJ_GETTER(Kotlin_NSSetAsKSet_iterator, KRef thiz) { NSSet* set = (NSSet*) GetAssociatedObject(thiz); RETURN_RESULT_OF(CreateKIteratorFromNSEnumerator, [set objectEnumerator]); } extern "C" KInt Kotlin_NSDictionaryAsKMap_getSize(KRef thiz) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); return objCSizeToKotlinOrThrow(dict.count); } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsKey(KRef thiz, KRef key) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); return [dict objectForKey:refToObjCOrNSNull(key)] != nullptr; } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsValue(KRef thiz, KRef value) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); id objCValue = refToObjCOrNSNull(value); for (id key in dict) { if ([[dict objectForKey:key] isEqual:objCValue]) { return true; } } return false; } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_get, KRef thiz, KRef key) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); id value = [dict objectForKey:refToObjCOrNSNull(key)]; RETURN_RESULT_OF(refFromObjCOrNSNull, value); } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_getOrThrowConcurrentModification, KRef thiz, KRef key) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); id value = [dict objectForKey:refToObjCOrNSNull(key)]; if (value == nullptr) { Kotlin_ObjCExport_ThrowCollectionConcurrentModification(); } RETURN_RESULT_OF(refFromObjCOrNSNull, value); } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsEntry(KRef thiz, KRef key, KRef value) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); return [refToObjCOrNSNull(value) isEqual:[dict objectForKey:refToObjCOrNSNull(key)]]; } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_keyIterator, KRef thiz) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); RETURN_RESULT_OF(CreateKIteratorFromNSEnumerator, [dict keyEnumerator]); } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_valueIterator, KRef thiz) { NSDictionary* dict = (NSDictionary*) GetAssociatedObject(thiz); RETURN_RESULT_OF(CreateKIteratorFromNSEnumerator, [dict objectEnumerator]); } #else // KONAN_OBJC_INTEROP extern "C" KInt Kotlin_NSArrayAsKList_getSize(KRef obj) { RuntimeAssert(false, "Objective-C interop is disabled"); return -1; } extern "C" OBJ_GETTER(Kotlin_NSArrayAsKList_get, KRef obj, KInt index) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" void Kotlin_NSMutableArrayAsKMutableList_add(KRef thiz, KInt index, KRef element) { RuntimeAssert(false, "Objective-C interop is disabled"); } extern "C" OBJ_GETTER(Kotlin_NSMutableArrayAsKMutableList_removeAt, KRef thiz, KInt index) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" OBJ_GETTER(Kotlin_NSMutableArrayAsKMutableList_set, KRef thiz, KInt index, KRef element) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" void Kotlin_NSEnumeratorAsKIterator_computeNext(KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); } extern "C" KInt Kotlin_NSSetAsKSet_getSize(KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); return -1; } extern "C" KBoolean Kotlin_NSSetAsKSet_contains(KRef thiz, KRef element) { RuntimeAssert(false, "Objective-C interop is disabled"); return false; } extern "C" OBJ_GETTER(Kotlin_NSSetAsKSet_getElement, KRef thiz, KRef element) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" OBJ_GETTER(Kotlin_NSSetAsKSet_iterator, KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" KInt Kotlin_NSDictionaryAsKMap_getSize(KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); return -1; } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsKey(KRef thiz, KRef key) { RuntimeAssert(false, "Objective-C interop is disabled"); return false; } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsValue(KRef thiz, KRef value) { RuntimeAssert(false, "Objective-C interop is disabled"); return false; } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_get, KRef thiz, KRef key) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_getOrThrowConcurrentModification, KRef thiz, KRef key) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" KBoolean Kotlin_NSDictionaryAsKMap_containsEntry(KRef thiz, KRef key, KRef value) { RuntimeAssert(false, "Objective-C interop is disabled"); return false; } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_keyIterator, KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } extern "C" OBJ_GETTER(Kotlin_NSDictionaryAsKMap_valueIterator, KRef thiz) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/main/cpp/ObjCExportCollections.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_OBJCEXPORTCOLLECTIONS_H #define RUNTIME_OBJCEXPORTCOLLECTIONS_H #if KONAN_OBJC_INTEROP #import #import #import "Memory.h" #import "ObjCExport.h" #import "Runtime.h" // Objective-C collections can't store `nil`, and the common convention is to use `NSNull.null` instead. // Follow the convention when converting Kotlin `null`: static inline id refToObjCOrNSNull(KRef obj) { if (obj == nullptr) { return NSNull.null; } else { return Kotlin_ObjCExport_refToObjC(obj); } } static inline OBJ_GETTER(refFromObjCOrNSNull, id obj) { if (obj == NSNull.null) { RETURN_OBJ(nullptr); } else { RETURN_RESULT_OF(Kotlin_ObjCExport_refFromObjC, obj); } } static inline OBJ_GETTER(invokeAndAssociate, KRef (*func)(KRef* result), id obj) { Kotlin_initRuntimeIfNeeded(); KRef kotlinObj = func(OBJ_RESULT); SetAssociatedObject(kotlinObj, obj); return kotlinObj; } #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCEXPORTCOLLECTIONS_H ================================================ FILE: runtime/src/main/cpp/ObjCExportCoroutines.mm ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #if KONAN_OBJC_INTEROP #import #import #import #import "ObjCExport.h" #import "ObjCExportErrors.h" typedef void (^Completion)(id _Nullable, NSError* _Nullable); extern "C" void Kotlin_ObjCExport_runCompletionSuccess(KRef completionHolder, KRef result) { Completion completion = (Completion)GetAssociatedObject(completionHolder); completion(Kotlin_ObjCExport_refToObjC(result), nullptr); } extern "C" void Kotlin_ObjCExport_runCompletionFailure( KRef completionHolder, KRef exception, const TypeInfo** exceptionTypes ) { id error = Kotlin_ObjCExport_ExceptionAsNSError(exception, exceptionTypes); Completion completion = (Completion)GetAssociatedObject(completionHolder); completion(nullptr, error); } extern "C" OBJ_GETTER(Kotlin_ObjCExport_createContinuationArgumentImpl, KRef completionHolder, const TypeInfo** exceptionTypes); extern "C" OBJ_GETTER(Kotlin_ObjCExport_createContinuationArgument, id completion, const TypeInfo** exceptionTypes) { if (pthread_main_np() != 1) { [NSException raise:NSGenericException format:@"Calling Kotlin suspend functions from Swift/Objective-C is currently supported only on main thread"]; } ObjHolder slot; KRef completionHolder = AllocInstanceWithAssociatedObject(theForeignObjCObjectTypeInfo, objc_retainBlock(completion), slot.slot()); RETURN_RESULT_OF(Kotlin_ObjCExport_createContinuationArgumentImpl, completionHolder, exceptionTypes); } extern "C" void Kotlin_ObjCExport_resumeContinuationSuccess(KRef continuation, KRef result); extern "C" void Kotlin_ObjCExport_resumeContinuationFailure(KRef continuation, KRef exception); extern "C" void Kotlin_ObjCExport_resumeContinuation(KRef continuation, id result, id error) { ObjHolder holder; if (error != nullptr) { if (result != nullptr) { [NSException raise:NSGenericException format:@"Kotlin completion handler is called with both result (%@) and error (%@) specified", result, error]; } KRef exception = Kotlin_ObjCExport_NSErrorAsException(error, holder.slot()); Kotlin_ObjCExport_resumeContinuationFailure(continuation, exception); } else { KRef kotlinResult = Kotlin_ObjCExport_refFromObjC(result, holder.slot()); Kotlin_ObjCExport_resumeContinuationSuccess(continuation, kotlinResult); } } #endif ================================================ FILE: runtime/src/main/cpp/ObjCExportErrors.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #import "Types.h" extern "C" id Kotlin_ObjCExport_ExceptionAsNSError(KRef exception, const TypeInfo** types); extern "C" OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsException, id error); ================================================ FILE: runtime/src/main/cpp/ObjCExportErrors.mm ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if KONAN_OBJC_INTEROP #import #import #import #import "Exceptions.h" #import "ObjCExport.h" #import "Porting.h" #import "Runtime.h" #import "Mutex.hpp" #import "ObjCExportErrors.h" extern "C" OBJ_GETTER(Kotlin_Throwable_getMessage, KRef throwable); extern "C" OBJ_GETTER(Kotlin_ObjCExport_getWrappedError, KRef throwable); static void printlnMessage(const char* message) { konan::consolePrintf("%s\n", message); } extern "C" RUNTIME_NORETURN void Kotlin_ObjCExport_trapOnUndeclaredException(KRef exception) { printlnMessage("Function doesn't have or inherit @Throws annotation and thus exception isn't propagated " "from Kotlin to Objective-C/Swift as NSError.\n" "It is considered unexpected and unhandled instead. Program will be terminated."); TerminateWithUnhandledException(exception); } static char kotlinExceptionOriginChar; static bool isExceptionOfType(KRef exception, const TypeInfo** types) { if (types) for (int i = 0; types[i] != nullptr; ++i) { // TODO: use fast instance check when possible. if (IsInstance(exception, types[i])) return true; } return false; } extern "C" id Kotlin_ObjCExport_ExceptionAsNSError(KRef exception, const TypeInfo** types) { ObjHolder errorHolder; KRef error = Kotlin_ObjCExport_getWrappedError(exception, errorHolder.slot()); if (error != nullptr) { // Thrown originally by Swift/Objective-C. // Not actually a Kotlin exception, so don't check if it matches [types]. return Kotlin_ObjCExport_refToObjC(error); } if (!isExceptionOfType(exception, types)) { printlnMessage("Exception doesn't match @Throws-specified class list and thus isn't propagated " "from Kotlin to Objective-C/Swift as NSError.\n" "It is considered unexpected and unhandled instead. Program will be terminated."); TerminateWithUnhandledException(exception); } NSMutableDictionary* userInfo = [[NSMutableDictionary new] autorelease]; userInfo[@"KotlinException"] = Kotlin_ObjCExport_refToObjC(exception); userInfo[@"KotlinExceptionOrigin"] = @(&kotlinExceptionOriginChar); // Support for different Kotlin runtimes loaded. ObjHolder messageHolder; KRef message = Kotlin_Throwable_getMessage(exception, messageHolder.slot()); NSString* description = Kotlin_Interop_CreateNSStringFromKString(message); if (description != nullptr) { userInfo[NSLocalizedDescriptionKey] = description; } return [NSError errorWithDomain:@"KotlinException" code:0 userInfo:userInfo]; } extern "C" void Kotlin_ObjCExport_RethrowExceptionAsNSError(KRef exception, id* outError, const TypeInfo** types) { id error = Kotlin_ObjCExport_ExceptionAsNSError(exception, types); // Also traps on unexpected exception. if (outError != nullptr) *outError = error; } extern "C" OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsExceptionImpl, KRef message, KRef error); extern "C" OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsException, id error) { NSString* description; NSError* e = (NSError*) error; if (e != nullptr) { auto userInfo = e.userInfo; if (userInfo != nullptr) { id kotlinException = userInfo[@"KotlinException"]; id kotlinExceptionOrigin = userInfo[@"KotlinExceptionOrigin"]; if (kotlinException != nullptr && kotlinExceptionOrigin != nullptr && [kotlinExceptionOrigin isEqual:@(&kotlinExceptionOriginChar)] ) { RETURN_RESULT_OF(Kotlin_ObjCExport_refFromObjC, kotlinException); } } description = e.localizedDescription; } else { description = nullptr; } ObjHolder messageHolder, errorHolder; KRef message = Kotlin_Interop_CreateKStringFromNSString(description, messageHolder.slot()); KRef kotlinError = Kotlin_ObjCExport_refFromObjC(error, errorHolder.slot()); // TODO: a simple opaque wrapper would be enough. RETURN_RESULT_OF(Kotlin_ObjCExport_NSErrorAsExceptionImpl, message, kotlinError); } extern "C" void Kotlin_ObjCExport_RethrowNSErrorAsException(id error) { ObjHolder holder; KRef exception = Kotlin_ObjCExport_NSErrorAsException(error, holder.slot()); ThrowException(exception); } @interface NSError (NSErrorKotlinException) @end; @implementation NSError (NSErrorKotlinException) -(id)kotlinException { auto userInfo = self.userInfo; return userInfo == nullptr ? nullptr : userInfo[@"KotlinException"]; } @end; #endif ================================================ FILE: runtime/src/main/cpp/ObjCExportExceptionDetails.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "Memory.h" #import "Types.h" #ifdef __cplusplus extern "C" { #endif OBJ_GETTER(Kotlin_ObjCExport_ExceptionDetails, KRef thiz, KRef exceptionHolder); #ifdef __cplusplus } #endif ================================================ FILE: runtime/src/main/cpp/ObjCExportExceptionDetails.mm ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "Memory.h" #import "ObjCExportExceptionDetails.h" #import "ObjCExport.h" #if KONAN_OBJC_INTEROP #import //! TODO: Use not_null signature. OBJ_GETTER(Kotlin_ObjCExport_ExceptionDetails, KRef /*thiz*/, KRef exceptionHolder) { if (NSException* exception = (NSException*)Kotlin_ObjCExport_refToObjC(exceptionHolder)) { RuntimeAssert([exception isKindOfClass:[NSException class]], "Illegal type: NSException expected"); NSString* ret = [NSString stringWithFormat: @"%@:: %@", exception.name, exception.reason]; RETURN_RESULT_OF(Kotlin_Interop_CreateKStringFromNSString, ret); } RETURN_OBJ(nullptr); } #else // KONAN_OBJC_INTEROP OBJ_GETTER(Kotlin_ObjCExport_ExceptionDetails, KRef /*thiz*/, KRef /*exceptionHolder*/) { RETURN_OBJ(nullptr); } #endif ================================================ FILE: runtime/src/main/cpp/ObjCExportInit.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJCEXPORTINIT_H #define RUNTIME_OBJCEXPORTINIT_H #if KONAN_OBJC_INTEROP extern "C" void Kotlin_ObjCExport_initialize(void); #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCEXPORTINIT_H ================================================ FILE: runtime/src/main/cpp/ObjCExportPrivate.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJCEXPORTPRIVATE_H #define RUNTIME_OBJCEXPORTPRIVATE_H #if KONAN_OBJC_INTEROP #import #import "Types.h" #import "Memory.h" #import "ObjCExport.h" @interface KotlinBase : NSObject +(instancetype)createWrapper:(ObjHeader*)obj; @end; extern "C" void Kotlin_ObjCExport_initializeClass(Class clazz); extern "C" const TypeInfo* Kotlin_ObjCExport_getAssociatedTypeInfo(Class clazz); extern "C" OBJ_GETTER(Kotlin_ObjCExport_convertUnmappedObjCObject, id obj); extern "C" SEL Kotlin_ObjCExport_toKotlinSelector; extern "C" SEL Kotlin_ObjCExport_releaseAsAssociatedObjectSelector; const TypeInfo* Kotlin_ObjCExport_createTypeInfoWithKotlinFieldsFrom(Class clazz, const TypeInfo* fieldsInfo); #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCEXPORTPRIVATE_H ================================================ FILE: runtime/src/main/cpp/ObjCInterop.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJCINTEROP_H #define RUNTIME_OBJCINTEROP_H #if KONAN_OBJC_INTEROP const char* Kotlin_ObjCInterop_getUniquePrefix(); #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCINTEROP_H ================================================ FILE: runtime/src/main/cpp/ObjCInterop.mm ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if KONAN_OBJC_INTEROP #import #import #include #include #include #include #include #include #include "Memory.h" #include "MemorySharedRefs.hpp" #include "Natives.h" #include "ObjCInterop.h" #include "ObjCExportPrivate.h" #include "ObjCMMAPI.h" #include "Types.h" #include "Mutex.hpp" // Replaced in ObjCExportCodeGenerator. __attribute__((weak)) const char* Kotlin_ObjCInterop_uniquePrefix = nullptr; const char* Kotlin_ObjCInterop_getUniquePrefix() { auto result = Kotlin_ObjCInterop_uniquePrefix; RuntimeCheck(result != nullptr, "unique prefix is not initialized"); return result; } extern "C" id objc_msgSendSuper2(struct objc_super *super, SEL op, ...); struct KotlinObjCClassData { const TypeInfo* typeInfo; Class objcClass; int32_t bodyOffset; }; // Acts only as container for the method, not actually applied to any class. @protocol HasKotlinObjCClassData @required -(void*)_kotlinObjCClassData; @end; static inline struct KotlinObjCClassData* GetKotlinClassData(id objOrClass) { void* ptr = [(id)objOrClass _kotlinObjCClassData]; return static_cast(ptr); } namespace { BackRefFromAssociatedObject* getBackRef(id obj, KotlinObjCClassData* classData) { void* body = reinterpret_cast(reinterpret_cast(obj) + classData->bodyOffset); return reinterpret_cast(body); } BackRefFromAssociatedObject* getBackRef(id obj) { // TODO: suboptimal; consider specializing methods for each class. auto* classData = GetKotlinClassData(obj); return getBackRef(obj, classData); } OBJ_GETTER(toKotlinImp, id self, SEL _cmd) { RETURN_OBJ(getBackRef(self)->ref()); } id allocWithZoneImp(Class self, SEL _cmd, void* zone) { // [super allocWithZone:zone] auto* classData = GetKotlinClassData(self); // TODO: suboptimal; consider specializing. struct objc_super s = {(id)self, object_getClass(classData->objcClass)}; auto messenger = reinterpret_cast(objc_msgSendSuper2); id result = messenger(&s, _cmd, zone); auto* typeInfo = classData->typeInfo; ObjHolder holder; auto kotlinObj = AllocInstanceWithAssociatedObject(typeInfo, result, holder.slot()); getBackRef(result, classData)->initAndAddRef(kotlinObj); return result; } id retainImp(id self, SEL _cmd) { getBackRef(self)->addRef(); return self; } BOOL _tryRetainImp(id self, SEL _cmd) { // TODO: [tryAddRef] currently works only on the owner thread for non-shared objects; // this is a regression for instances of Kotlin subclasses of Obj-C classes: // loading a reference to such an object from Obj-C weak reference now fails on "wrong" thread // unless the object is frozen. try { return getBackRef(self)->tryAddRef(); } catch (ExceptionObjHolder& e) { // TODO: check for IncorrectDereferenceException and possible weak property access // Cannot use SourceInfo here, because CoreSymbolication framework (CSSymbolOwnerGetSymbolWithAddress) // fails at recursive retain lock. Similarly, cannot use objc exception here, because its unhandled // exception handler might fail at recursive retain lock too. // TODO: Refactor to be more explicit. Instead of relying on an unhandled exception termination // (and effectively setting a global to alter its behavior), just call an appropriate termination // function by hand. DisallowSourceInfo(); std::terminate(); } } void releaseImp(id self, SEL _cmd) { getBackRef(self)->releaseRef(); } void releaseAsAssociatedObjectImp(id self, SEL _cmd) { auto* classData = GetKotlinClassData(self); // This function is called by the GC. It made a decision to reclaim Kotlin object, and runs // deallocation hooks at the moment, including deallocation of the "associated object" ([self]) // using the [super release] call below. // The deallocation involves running [self dealloc] which can contain arbitrary code. // In particular, this code can retain and release [self]. Obj-C and Swift runtimes handle this // gracefully (unless the object gets accessed after the deallocation of course), but Kotlin doesn't. // For example, this happens in https://youtrack.jetbrains.com/issue/KT-41811, provoked by // UIViewController.dealloc (which retains-releases self._view._viewDelegate == self) and UIView.dealloc. // Generally retaining and releasing Kotlin object that is being deallocated would lead to // use-after-dispose and double-dispose problems (with unpredictable consequences) or to an assertion failure. // To workaround this, detach the back ref from the Kotlin object: getBackRef(self, classData)->detach(); // So retain/release/etc. on [self] won't affect the Kotlin object, and an attempt to get // the reference to it (e.g. when calling Kotlin method on [self]) would crash. // The latter is generally ok, because by the time superclass dealloc gets launched, subclass state // should already be deinitialized, and Kotlin methods operate on the subclass. // [super release] Class clazz = classData->objcClass; struct objc_super s = {self, clazz}; auto messenger = reinterpret_cast(objc_msgSendSuper2); messenger(&s, @selector(release)); } } extern "C" { Class Kotlin_Interop_getObjCClass(const char* name); const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) RUNTIME_NOTHROW; RUNTIME_NOTHROW const TypeInfo* GetObjCKotlinTypeInfo(ObjHeader* obj) { void* objcPtr = obj->GetAssociatedObject(); RuntimeAssert(objcPtr != nullptr, ""); return GetKotlinClassData(reinterpret_cast(objcPtr))->typeInfo; } static void AddNSObjectOverride(bool isClassMethod, Class clazz, SEL selector, void* imp) { Class nsObjectClass = Kotlin_Interop_getObjCClass("NSObject"); Method nsObjectMethod = class_getInstanceMethod( isClassMethod ? object_getClass((id)nsObjectClass) : nsObjectClass, selector); RuntimeCheck(nsObjectMethod != nullptr, "NSObject method not found"); const char* nsObjectMethodTypeEncoding = method_getTypeEncoding(nsObjectMethod); RuntimeCheck(nsObjectMethodTypeEncoding != nullptr, "NSObject method has no encoding provided"); // TODO: something of the above can be cached. BOOL added = class_addMethod( isClassMethod ? object_getClass((id)clazz) : clazz, selector, (IMP)imp, nsObjectMethodTypeEncoding); RuntimeCheck(added, "Unable to add method to Objective-C class"); } static void AddKotlinClassData(bool isClassMethod, Class clazz, void* imp) { SEL selector = @selector(_kotlinObjCClassData); auto methodDescription = protocol_getMethodDescription( @protocol(HasKotlinObjCClassData), selector, YES, YES ); const char* typeEncoding = methodDescription.types; RuntimeCheck(typeEncoding != nullptr, "unable to find method in Objective-C protocol"); BOOL added = class_addMethod( isClassMethod ? object_getClass((id)clazz) : clazz, selector, (IMP)imp, typeEncoding); RuntimeCheck(added, "Unable to add method to Objective-C class"); } struct ObjCMethodDescription { void* (*imp)(void*, void*, ...); const char* selector; const char* encoding; }; struct KotlinObjCClassInfo { const char* name; int exported; const char* superclassName; const char** protocolNames; const struct ObjCMethodDescription* instanceMethods; int32_t instanceMethodsNum; const struct ObjCMethodDescription* classMethods; int32_t classMethodsNum; int32_t* bodyOffset; const TypeInfo* typeInfo; const TypeInfo* metaTypeInfo; void** createdClass; KotlinObjCClassData* (*classDataImp)(void*, void*); }; static void AddMethods(Class clazz, const struct ObjCMethodDescription* methods, int32_t methodsNum) { for (int32_t i = 0; i < methodsNum; ++i) { const struct ObjCMethodDescription* method = &methods[i]; BOOL added = class_addMethod(clazz, sel_registerName(method->selector), (IMP)method->imp, method->encoding); RuntimeAssert(added == YES, "Unable to add method to Objective-C class"); } } static kotlin::SpinLock classCreationMutex; static int anonymousClassNextId = 0; static Class allocateClass(const KotlinObjCClassInfo* info) { Class superclass = Kotlin_Interop_getObjCClass(info->superclassName); if (info->exported) { RuntimeCheck(info->name != nullptr, "exported Objective-C class must have a name"); Class result = objc_allocateClassPair(superclass, info->name, 0); if (result != nullptr) return result; // Similar to how Objective-C runtime handles this: fprintf(stderr, "Class %s has multiple implementations. Which one will be used is undefined.\n", info->name); } KStdString className = Kotlin_ObjCInterop_getUniquePrefix(); if (info->name != nullptr) { className += info->name; } else { className += "_kobjc"; } int classId = anonymousClassNextId++; className += std::to_string(classId); Class result = objc_allocateClassPair(superclass, className.c_str(), 0); RuntimeCheck(result != nullptr, "Failed to allocate Objective-C class"); return result; } void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) { std::lock_guard lockGuard(classCreationMutex); void* createdClass = *info->createdClass; if (createdClass != nullptr) { return createdClass; } Class newClass = allocateClass(info); RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class"); Class newMetaclass = object_getClass(reinterpret_cast(newClass)); for (size_t i = 0;; ++i) { const char* protocolName = info->protocolNames[i]; if (protocolName == nullptr) break; Protocol* proto = objc_getProtocol(protocolName); if (proto != nullptr) { BOOL added = class_addProtocol(newClass, proto); RuntimeAssert(added == YES, "Unable to add protocol to Objective-C class"); added = class_addProtocol(newMetaclass, proto); RuntimeAssert(added == YES, "Unable to add protocol to Objective-C metaclass"); } } AddNSObjectOverride(false, newClass, Kotlin_ObjCExport_toKotlinSelector, (void*)&toKotlinImp); AddNSObjectOverride(true, newClass, @selector(allocWithZone:), (void*)&allocWithZoneImp); AddNSObjectOverride(false, newClass, @selector(retain), (void*)&retainImp); AddNSObjectOverride(false, newClass, @selector(_tryRetain), (void*)&_tryRetainImp); AddNSObjectOverride(false, newClass, @selector(release), (void*)&releaseImp); AddNSObjectOverride(false, newClass, Kotlin_ObjCExport_releaseAsAssociatedObjectSelector, (void*)&releaseAsAssociatedObjectImp); AddMethods(newClass, info->instanceMethods, info->instanceMethodsNum); AddMethods(newMetaclass, info->classMethods, info->classMethodsNum); // Adding both instance and class methods to make [GetKotlinClassData] work // for instances as well as the class itself. AddKotlinClassData(false, newClass, (void*)info->classDataImp); AddKotlinClassData(true, newClass, (void*)info->classDataImp); const TypeInfo* actualTypeInfo = Kotlin_ObjCExport_createTypeInfoWithKotlinFieldsFrom(newClass, info->typeInfo); int bodySize = sizeof(BackRefFromAssociatedObject); char bodyTypeEncoding[16]; snprintf(bodyTypeEncoding, sizeof(bodyTypeEncoding), "[%dc]", bodySize); BOOL added = class_addIvar(newClass, "kotlinBody", bodySize, /* log2(align) = */ 3, bodyTypeEncoding); RuntimeAssert(added == YES, "Unable to add ivar to Objective-C class"); objc_registerClassPair(newClass); Ivar body = class_getInstanceVariable(newClass, "kotlinBody"); RuntimeAssert(body != nullptr, "Unable to get ivar added to Objective-C class"); int32_t offset = (int32_t)ivar_getOffset(body); *info->bodyOffset = offset; // Doing this after objc_registerClassPair because it is not clear whether calling class methods // is safe before that. auto* classData = GetKotlinClassData(newClass); classData->typeInfo = actualTypeInfo; classData->objcClass = newClass; classData->bodyOffset = offset; *info->createdClass = newClass; return newClass; } void* objc_autoreleasePoolPush(); void objc_autoreleasePoolPop(void* ptr); id objc_allocWithZone(Class clazz); id objc_retain(id ptr); void objc_release(id ptr); konan::AutoreleasePool::AutoreleasePool() : handle(objc_autoreleasePoolPush()) {} konan::AutoreleasePool::~AutoreleasePool() { objc_autoreleasePoolPop(handle); } void* Kotlin_objc_autoreleasePoolPush() { return objc_autoreleasePoolPush(); } void Kotlin_objc_autoreleasePoolPop(void* ptr) { objc_autoreleasePoolPop(ptr); } id Kotlin_objc_allocWithZone(Class clazz) { return objc_allocWithZone(clazz); } id Kotlin_objc_retain(id ptr) { return objc_retain(ptr); } void Kotlin_objc_release(id ptr) { objc_release(ptr); } Class Kotlin_objc_lookUpClass(const char* name) { return objc_lookUpClass(name); } } // extern "C" #else // KONAN_OBJC_INTEROP #include "KAssert.h" extern "C" { void* Kotlin_objc_autoreleasePoolPush() { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } void Kotlin_objc_autoreleasePoolPop(void* ptr) { RuntimeAssert(false, "Objective-C interop is disabled"); } void* Kotlin_objc_allocWithZone(void* clazz) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } void* Kotlin_objc_retain(void* ptr) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } void Kotlin_objc_release(void* ptr) { RuntimeAssert(false, "Objective-C interop is disabled"); } void* Kotlin_objc_lookUpClass(const char* name) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } } // extern "C" #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/main/cpp/ObjCInteropUtils.mm ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Natives.h" #if KONAN_OBJC_INTEROP #import #import #import #import #import "Memory.h" #import "ObjCInteropUtilsPrivate.h" namespace { Class nsStringClass = nullptr; Class getNSStringClass() { Class result = nsStringClass; if (result == nullptr) { // Lookup dynamically to avoid direct reference to Foundation: result = objc_getClass("NSString"); RuntimeAssert(result != nullptr, "NSString class not found"); nsStringClass = result; } return result; } // Note: using @"foo" string literals leads to linkage dependency on frameworks. NSString* cStringToNS(const char* str) { return [getNSStringClass() stringWithCString:str encoding:NSUTF8StringEncoding]; } } extern "C" { id Kotlin_ObjCExport_CreateNSStringFromKString(ObjHeader* str); id Kotlin_Interop_CreateNSStringFromKString(ObjHeader* str) { // Note: this function is just a bit specialized [Kotlin_Interop_refToObjC]. if (str == nullptr) { return nullptr; } if (void* associatedObject = str->GetAssociatedObject()) { return (id)associatedObject; } return Kotlin_ObjCExport_CreateNSStringFromKString(str); } OBJ_GETTER(Kotlin_Interop_CreateKStringFromNSString, NSString* str) { if (str == nullptr) { RETURN_OBJ(nullptr); } CFStringRef immutableCopyOrSameStr = CFStringCreateCopy(nullptr, (CFStringRef)str); auto length = CFStringGetLength(immutableCopyOrSameStr); CFRange range = {0, length}; ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, length, OBJ_RESULT)->array(); KChar* rawResult = CharArrayAddressOfElementAt(result, 0); CFStringGetCharacters(immutableCopyOrSameStr, range, rawResult); result->obj()->SetAssociatedObject((void*)immutableCopyOrSameStr); RETURN_OBJ(result->obj()); } // Note: this body is used for init methods with signatures differing from this; // it is correct on arm64 and x86_64, because the body uses only the first two arguments which are fixed, // and returns pointers. id MissingInitImp(id self, SEL _cmd) { const char* className = object_getClassName(self); [self release]; // Since init methods receive ownership on the receiver. // Lookup dynamically to avoid direct reference to Foundation: Class nsExceptionClass = objc_getClass("NSException"); RuntimeAssert(nsExceptionClass != nullptr, "NSException class not found"); [nsExceptionClass raise:cStringToNS("Initializer is not implemented") format:cStringToNS("%s is not implemented in %s"), sel_getName(_cmd), className]; return nullptr; } // Initialized in [ObjCInteropUtilsClasses.mm]. id (*Kotlin_Interop_createKotlinObjectHolder_ptr)(KRef any) = nullptr; KRef (*Kotlin_Interop_unwrapKotlinObjectHolder_ptr)(id holder) = nullptr; id Kotlin_Interop_createKotlinObjectHolder(KRef any) { return Kotlin_Interop_createKotlinObjectHolder_ptr(any); } KRef Kotlin_Interop_unwrapKotlinObjectHolder(id holder) { return Kotlin_Interop_unwrapKotlinObjectHolder_ptr(holder); } KBoolean Kotlin_Interop_DoesObjectConformToProtocol(id obj, void* prot, KBoolean isMeta) { BOOL objectIsClass = class_isMetaClass(object_getClass(obj)); if ((isMeta && !objectIsClass) || (!isMeta && objectIsClass)) return false; // TODO: handle root classes properly. return [((id)obj) conformsToProtocol:(Protocol*)prot]; } KBoolean Kotlin_Interop_IsObjectKindOfClass(id obj, void* cls) { return [((id)obj) isKindOfClass:(Class)cls]; } OBJ_GETTER((*Konan_ObjCInterop_getWeakReference_ptr), KRef ref) = nullptr; void (*Konan_ObjCInterop_initWeakReference_ptr)(KRef ref, id objcPtr) = nullptr; OBJ_GETTER(Konan_ObjCInterop_getWeakReference, KRef ref) { RETURN_RESULT_OF(Konan_ObjCInterop_getWeakReference_ptr, ref); } void Konan_ObjCInterop_initWeakReference(KRef ref, id objcPtr) { Konan_ObjCInterop_initWeakReference_ptr(ref, objcPtr); } } // extern "C" #else // KONAN_OBJC_INTEROP extern "C" { void* Kotlin_Interop_CreateNSStringFromKString(const ArrayHeader* str) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } OBJ_GETTER(Kotlin_Interop_CreateKStringFromNSString, void* str) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } void* Kotlin_Interop_createKotlinObjectHolder(KRef any) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } KRef Kotlin_Interop_unwrapKotlinObjectHolder(void* holder) { RuntimeAssert(false, "Objective-C interop is disabled"); return nullptr; } OBJ_GETTER(Konan_ObjCInterop_getWeakReference, KRef ref) { RuntimeAssert(false, "Objective-C interop is disabled"); RETURN_OBJ(nullptr); } void Konan_ObjCInterop_initWeakReference(KRef ref, void* objcPtr) { RuntimeAssert(false, "Objective-C interop is disabled"); } } // extern "C" #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/main/cpp/ObjCInteropUtilsPrivate.h ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJCINTEROPUTILSPRIVATE_H #define RUNTIME_OBJCINTEROPUTILSPRIVATE_H #if KONAN_OBJC_INTEROP #import #import "Types.h" #import "Memory.h" extern "C" id (*Kotlin_Interop_createKotlinObjectHolder_ptr)(KRef any); extern "C" KRef (*Kotlin_Interop_unwrapKotlinObjectHolder_ptr)(id holder); extern "C" OBJ_GETTER((*Konan_ObjCInterop_getWeakReference_ptr), KRef ref); extern "C" void (*Konan_ObjCInterop_initWeakReference_ptr)(KRef ref, id objcPtr); #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCINTEROPUTILSPRIVATE_H ================================================ FILE: runtime/src/main/cpp/ObjCMMAPI.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJCMMAPI_H #define RUNTIME_OBJCMMAPI_H #include "Common.h" #include "Utils.hpp" #if KONAN_OBJC_INTEROP extern "C" ALWAYS_INLINE void Kotlin_ObjCExport_releaseAssociatedObject(void* associatedObject); namespace konan { class AutoreleasePool : private kotlin::Pinned { public: AutoreleasePool(); ~AutoreleasePool(); private: void* handle; }; } // namespace konan #endif // KONAN_OBJC_INTEROP #endif // RUNTIME_OBJCMMAPI_H ================================================ FILE: runtime/src/main/cpp/ObjectTraversal.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_OBJECT_TRAVERSAL_H #define RUNTIME_OBJECT_TRAVERSAL_H #include #include "Memory.h" #include "Natives.h" #include "Types.h" namespace kotlin { // TODO: Consider an iterator/ranges based approaches for traversals. template void traverseObjectFields(ObjHeader* object, F process) noexcept(noexcept(process(std::declval()))) { const TypeInfo* typeInfo = object->type_info(); // Only consider arrays of objects, not arrays of primitives. if (typeInfo != theArrayTypeInfo) { for (int index = 0; index < typeInfo->objOffsetsCount_; index++) { process(reinterpret_cast(reinterpret_cast(object) + typeInfo->objOffsets_[index])); } } else { ArrayHeader* array = object->array(); for (uint32_t index = 0; index < array->count_; index++) { process(ArrayAddressOfElementAt(array, index)); } } } template void traverseReferredObjects(ObjHeader* object, F process) noexcept(noexcept(process(std::declval()))) { traverseObjectFields(object, [&process](ObjHeader** location) noexcept(noexcept(process(std::declval()))) { if (ObjHeader* ref = *location) { process(ref); } }); } } // namespace kotlin #endif // RUNTIME_OBJECT_TRAVERSAL_H ================================================ FILE: runtime/src/main/cpp/ObjectTraversalTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ObjectTraversal.hpp" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Types.h" #include "Utils.hpp" using namespace kotlin; using ::testing::_; namespace { template class Object : private Pinned { public: Object() { header_.typeInfoOrMeta_ = &type_; type_.typeInfo_ = &type_; type_.objOffsetsCount_ = Count; type_.objOffsets_ = fieldOffsets_.data(); for (size_t i = 0; i < Count; ++i) { fieldOffsets_[i] = reinterpret_cast(&fields_[i]) - reinterpret_cast(&header_); } } ObjHeader* header() { return &header_; } ObjHeader*& operator[](size_t index) { return fields_[index]; } private: ObjHeader header_; TypeInfo type_; std::array fieldOffsets_; std::array fields_{}; }; template class Array : private Pinned { public: Array() { header_.typeInfoOrMeta_ = const_cast(theArrayTypeInfo); header_.count_ = Count; } ObjHeader* header() { return header_.obj(); } ObjHeader*& operator[](size_t index) { return fields_[index]; } private: ArrayHeader header_; std::array fields_{}; }; struct CallableWithExceptions { void operator()(ObjHeader*) noexcept(false) {} void operator()(ObjHeader**) noexcept(false) {} }; struct CallableWithoutExceptions { void operator()(ObjHeader*) noexcept {} void operator()(ObjHeader**) noexcept {} }; } // namespace TEST(ObjectTraversalTest, TraverseFieldsExceptions) { static_assert( noexcept(traverseObjectFields(std::declval(), std::declval())), "Callable is noexcept, so traverse is noexcept"); static_assert( !noexcept(traverseObjectFields(std::declval(), std::declval())), "Callable is noexcept(false), so traverse is noexcept(false)"); } TEST(ObjectTraversalTest, TraverseEmptyObjectFields) { Object<0> object; testing::StrictMock> process; EXPECT_CALL(process, Call(_)).Times(0); traverseObjectFields(object.header(), [&process](ObjHeader** field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseObjectFields) { ObjHeader field1; ObjHeader field3; Object<3> object; object[0] = &field1; object[2] = &field3; testing::StrictMock> process; EXPECT_CALL(process, Call(&object[0])); EXPECT_CALL(process, Call(&object[1])); EXPECT_CALL(process, Call(&object[2])); traverseObjectFields(object.header(), [&process](ObjHeader** field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseObjectFieldsWithException) { constexpr int kException = 1; ObjHeader field1; ObjHeader field2; ObjHeader field3; Object<3> object; object[0] = &field1; object[1] = &field2; object[2] = &field3; testing::StrictMock> process; EXPECT_CALL(process, Call(&object[0])); EXPECT_CALL(process, Call(&object[1])).WillOnce([]() { throw kException; }); EXPECT_CALL(process, Call(&object[2])).Times(0); try { traverseObjectFields(object.header(), [&process](ObjHeader** field) { process.Call(field); }); } catch (int exception) { EXPECT_THAT(exception, kException); } catch (...) { EXPECT_TRUE(false); } } TEST(ObjectTraversalTest, TraverseEmptyArrayFields) { Array<0> array; testing::StrictMock> process; EXPECT_CALL(process, Call(_)).Times(0); traverseObjectFields(array.header(), [&process](ObjHeader** field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseArrayFields) { ObjHeader element1; ObjHeader element3; Array<3> array; array[0] = &element1; array[2] = &element3; testing::StrictMock> process; EXPECT_CALL(process, Call(&array[0])); EXPECT_CALL(process, Call(&array[1])); EXPECT_CALL(process, Call(&array[2])); traverseObjectFields(array.header(), [&process](ObjHeader** field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseArrayFieldsWithException) { constexpr int kException = 1; ObjHeader element1; ObjHeader element2; ObjHeader element3; Array<3> array; array[0] = &element1; array[1] = &element2; array[2] = &element3; testing::StrictMock> process; EXPECT_CALL(process, Call(&array[0])); EXPECT_CALL(process, Call(&array[1])).WillOnce([]() { throw kException; }); EXPECT_CALL(process, Call(&array[2])).Times(0); try { traverseObjectFields(array.header(), [&process](ObjHeader** field) { process.Call(field); }); } catch (int exception) { EXPECT_THAT(exception, kException); } catch (...) { EXPECT_TRUE(false); } } TEST(ObjectTraversalTest, TraverseRefsExceptions) { static_assert( noexcept(traverseReferredObjects(std::declval(), std::declval())), "Callable is noexcept, so traverse is noexcept"); static_assert( !noexcept(traverseReferredObjects(std::declval(), std::declval())), "Callable is noexcept(false), so traverse is noexcept(false)"); } TEST(ObjectTraversalTest, TraverseEmptyObjectRefs) { Object<0> object; testing::StrictMock> process; EXPECT_CALL(process, Call(_)).Times(0); traverseReferredObjects(object.header(), [&process](ObjHeader* field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseObjectRefs) { ObjHeader field1; ObjHeader field3; Object<3> object; object[0] = &field1; object[2] = &field3; testing::StrictMock> process; EXPECT_CALL(process, Call(&field1)); EXPECT_CALL(process, Call(&field3)); traverseReferredObjects(object.header(), [&process](ObjHeader* field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseObjectRefsWithException) { constexpr int kException = 1; ObjHeader field1; ObjHeader field2; ObjHeader field3; Object<3> object; object[0] = &field1; object[1] = &field2; object[2] = &field3; testing::StrictMock> process; EXPECT_CALL(process, Call(&field1)); EXPECT_CALL(process, Call(&field2)).WillOnce([]() { throw kException; }); EXPECT_CALL(process, Call(&field3)).Times(0); try { traverseReferredObjects(object.header(), [&process](ObjHeader* field) { process.Call(field); }); } catch (int exception) { EXPECT_THAT(exception, kException); } catch (...) { EXPECT_TRUE(false); } } TEST(ObjectTraversalTest, TraverseEmptyArrayRefs) { Array<0> array; testing::StrictMock> process; EXPECT_CALL(process, Call(_)).Times(0); traverseReferredObjects(array.header(), [&process](ObjHeader* field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseArrayRefs) { ObjHeader element1; ObjHeader element3; Array<3> array; array[0] = &element1; array[2] = &element3; testing::StrictMock> process; EXPECT_CALL(process, Call(&element1)); EXPECT_CALL(process, Call(&element3)); traverseReferredObjects(array.header(), [&process](ObjHeader* field) { process.Call(field); }); } TEST(ObjectTraversalTest, TraverseArrayRefsWithException) { constexpr int kException = 1; ObjHeader element1; ObjHeader element2; ObjHeader element3; Array<3> array; array[0] = &element1; array[1] = &element2; array[2] = &element3; testing::StrictMock> process; EXPECT_CALL(process, Call(&element1)); EXPECT_CALL(process, Call(&element2)).WillOnce([]() { throw kException; }); EXPECT_CALL(process, Call(&element3)).Times(0); try { traverseReferredObjects(array.header(), [&process](ObjHeader* field) { process.Call(field); }); } catch (int exception) { EXPECT_THAT(exception, kException); } catch (...) { EXPECT_TRUE(false); } } ================================================ FILE: runtime/src/main/cpp/Operator.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "DoubleConversions.h" #include "Natives.h" #include "Common.h" extern "C" { //--- Float -------------------------------------------------------------------// KInt Kotlin_Float_toInt(KFloat a) { if (isnan(a)) return 0; if (a >= (KFloat) INT32_MAX) return INT32_MAX; if (a <= (KFloat) INT32_MIN) return INT32_MIN; return a; } KLong Kotlin_Float_toLong(KFloat a) { if (isnan(a)) return 0; if (a >= (KFloat) INT64_MAX) return INT64_MAX; if (a <= (KFloat) INT64_MIN) return INT64_MIN; return a; } KByte Kotlin_Float_toByte(KFloat a) { return (KByte) Kotlin_Float_toInt(a); } KShort Kotlin_Float_toShort(KFloat a) { return (KShort) Kotlin_Float_toInt(a); } ALWAYS_INLINE KBoolean Kotlin_Float_isNaN(KFloat a) { return isnan(a); } ALWAYS_INLINE KBoolean Kotlin_Float_isInfinite(KFloat a) { return isinf(a); } ALWAYS_INLINE KBoolean Kotlin_Float_isFinite(KFloat a) { return isfinite(a); } //--- Double ------------------------------------------------------------------// KInt Kotlin_Double_toInt(KDouble a) { if (isnan(a)) return 0; if (a >= (KDouble) INT32_MAX) return INT32_MAX; if (a <= (KDouble) INT32_MIN) return INT32_MIN; return a; } KLong Kotlin_Double_toLong(KDouble a) { if (isnan(a)) return 0; if (a >= (KDouble) INT64_MAX) return INT64_MAX; if (a <= (KDouble) INT64_MIN) return INT64_MIN; return a; } ALWAYS_INLINE KBoolean Kotlin_Double_isNaN(KDouble a) { return isnan(a); } ALWAYS_INLINE KBoolean Kotlin_Double_isInfinite(KDouble a) { return isinf(a); } ALWAYS_INLINE KBoolean Kotlin_Double_isFinite(KDouble a) { return isfinite(a); } //--- Bit operations ---------------------------------------------------------// ALWAYS_INLINE KInt Kotlin_Int_countOneBits(KInt value) { return __builtin_popcount(value); } ALWAYS_INLINE KInt Kotlin_Long_countOneBits(KLong value) { return __builtin_popcountll(value); } ALWAYS_INLINE KInt Kotlin_Int_countTrailingZeroBits(KInt value) { return __builtin_ctz(value); } ALWAYS_INLINE KInt Kotlin_Long_countTrailingZeroBits(KLong value) { return __builtin_ctzll(value); } ALWAYS_INLINE KInt Kotlin_Int_countLeadingZeroBits(KInt value) { return __builtin_clz(value); } ALWAYS_INLINE KInt Kotlin_Long_countLeadingZeroBits(KLong value) { return __builtin_clzll(value); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/PointerBits.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POINTER_BITS_H #define RUNTIME_POINTER_BITS_H #include #include "Common.h" template ALWAYS_INLINE T* setPointerBits(T* ptr, unsigned bits) { return reinterpret_cast(reinterpret_cast(ptr) | bits); } template ALWAYS_INLINE T* clearPointerBits(T* ptr, unsigned bits) { return reinterpret_cast(reinterpret_cast(ptr) & ~static_cast(bits)); } template ALWAYS_INLINE unsigned getPointerBits(T* ptr, unsigned bits) { return reinterpret_cast(ptr) & static_cast(bits); } template ALWAYS_INLINE bool hasPointerBits(T* ptr, unsigned bits) { return getPointerBits(ptr, bits) != 0; } #endif // RUNTIME_POINTER_BITS_H ================================================ FILE: runtime/src/main/cpp/Porting.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef KONAN_ANDROID #include #endif #include #include #include #include #include #if !KONAN_NO_THREADS #include #endif #include #if KONAN_WINDOWS #include #endif #include #include "Common.h" #include "Porting.h" #include "KAssert.h" #if KONAN_WASM || KONAN_ZEPHYR extern "C" RUNTIME_NORETURN void Konan_abort(const char*); extern "C" RUNTIME_NORETURN void Konan_exit(int32_t status); #endif #ifdef KONAN_ZEPHYR // In Zephyr's Newlib strnlen(3) is not included from string.h by default. extern "C" size_t strnlen(const char* buffer, size_t maxSize); #endif namespace konan { // Console operations. void consoleInit() { #if KONAN_WINDOWS // Note that this code enforces UTF-8 console output, so we may want to rethink // how we perform console IO, if it turns out, that UTF-16 is better output format. ::SetConsoleCP(CP_UTF8); ::SetConsoleOutputCP(CP_UTF8); // FIXME: should set original CP back during the deinit of the program. // Otherwise, this codepage remains in the console. #endif } void consoleWriteUtf8(const void* utf8, uint32_t sizeBytes) { #ifdef KONAN_ANDROID // TODO: use sizeBytes! __android_log_print(ANDROID_LOG_INFO, "Konan_main", "%s", utf8); #else ::write(STDOUT_FILENO, utf8, sizeBytes); #endif } void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes) { #ifdef KONAN_ANDROID // TODO: use sizeBytes! __android_log_print(ANDROID_LOG_ERROR, "Konan_main", "%s", utf8); #else ::write(STDERR_FILENO, utf8, sizeBytes); #endif } #if KONAN_WINDOWS int getLastErrorMessage(char* message, uint32_t size) { auto errCode = ::GetLastError(); if (errCode) { auto flags = FORMAT_MESSAGE_FROM_SYSTEM; auto errMsgBufSize = size / 4; wchar_t errMsgBuffer[errMsgBufSize]; ::FormatMessageW(flags, NULL, errCode, 0, errMsgBuffer, errMsgBufSize, NULL); ::WideCharToMultiByte(CP_UTF8, 0, errMsgBuffer, -1, message, size, NULL, NULL); } return errCode; } #endif int32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes) { #ifdef KONAN_ZEPHYR return 0; #elif KONAN_WINDOWS auto length = 0; void *stdInHandle = ::GetStdHandle(STD_INPUT_HANDLE); if (::GetFileType(stdInHandle) == FILE_TYPE_CHAR) { unsigned long bufferRead; // In UTF-16 there are surrogate pairs that a 2 * 16-bit long (4 bytes). auto bufferLength = maxSizeBytes / 4 - 1; wchar_t buffer[bufferLength]; if (::ReadConsoleW(stdInHandle, buffer, bufferLength, &bufferRead, NULL)) { length = ::WideCharToMultiByte(CP_UTF8, 0, buffer, bufferRead, (char*) utf8, maxSizeBytes - 1, NULL, NULL); if (!length && KonanNeedDebugInfo) { char msg[512]; auto errCode = getLastErrorMessage(msg, sizeof(msg)); consoleErrorf("UTF-16 to UTF-8 conversion error %d: %s", errCode, msg); } ((char*) utf8)[length] = 0; } else if (KonanNeedDebugInfo) { char msg[512]; auto errCode = getLastErrorMessage(msg, sizeof(msg)); consoleErrorf("Console read failure: %d %s", errCode, msg); } } else { length = ::read(STDIN_FILENO, utf8, maxSizeBytes - 1); } #else auto length = ::read(STDIN_FILENO, utf8, maxSizeBytes - 1); #endif if (length <= 0) return -1; char* start = reinterpret_cast(utf8); char* current = start + length - 1; bool isTrimming = true; while (current >= start && isTrimming) { switch (*current) { case '\n': case '\r': *current = 0; length--; break; default: isTrimming = false; } current--; } return length; } #if KONAN_INTERNAL_SNPRINTF extern "C" int rpl_vsnprintf(char *, size_t, const char *, va_list); #define vsnprintf_impl rpl_vsnprintf #else #define vsnprintf_impl ::vsnprintf #endif void consolePrintf(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args); if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate? if (static_cast(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. va_end(args); consoleWriteUtf8(buffer, rv); } // TODO: Avoid code duplication. void consoleErrorf(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args); if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate? if (static_cast(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating. va_end(args); consoleErrorUtf8(buffer, rv); } void consoleFlush() { ::fflush(stdout); ::fflush(stderr); } // Thread execution. #if !KONAN_NO_THREADS pthread_key_t terminationKey; pthread_once_t terminationKeyOnceControl = PTHREAD_ONCE_INIT; typedef void (*destructor_t)(void*); struct DestructorRecord { struct DestructorRecord* next; destructor_t destructor; void* destructorParameter; }; static void onThreadExitCallback(void* value) { DestructorRecord* record = reinterpret_cast(value); while (record != nullptr) { record->destructor(record->destructorParameter); auto next = record->next; free(record); record = next; } pthread_setspecific(terminationKey, nullptr); } #if KONAN_LINUX static pthread_key_t dummyKey; #endif static void onThreadExitInit() { #if KONAN_LINUX // Due to glibc bug we have to create first key as dummy, to avoid // conflicts with potentially uninitialized dlfcn error key. // https://code.woboq.org/userspace/glibc/dlfcn/dlerror.c.html#237 // As one may see, glibc checks value of the key even if it was not inited (and == 0), // and so data associated with our legit key (== 0 as being the first one) is used. // Other libc are not affected, as usually == 0 pthread key is impossible. pthread_key_create(&dummyKey, nullptr); #endif pthread_key_create(&terminationKey, onThreadExitCallback); } #endif // !KONAN_NO_THREADS void onThreadExit(void (*destructor)(void*), void* destructorParameter) { #if KONAN_NO_THREADS #if KONAN_WASM || KONAN_ZEPHYR // No way to do that. #else #error "How to do onThreadExit()?" #endif #else // !KONAN_NO_THREADS // We cannot use pthread_cleanup_push() as it is lexical scope bound. pthread_once(&terminationKeyOnceControl, onThreadExitInit); DestructorRecord* destructorRecord = (DestructorRecord*)calloc(1, sizeof(DestructorRecord)); destructorRecord->destructor = destructor; destructorRecord->destructorParameter = destructorParameter; destructorRecord->next = reinterpret_cast(pthread_getspecific(terminationKey)); pthread_setspecific(terminationKey, destructorRecord); #endif // !KONAN_NO_THREADS } // Process execution. void abort(void) { ::abort(); } #if KONAN_WASM || KONAN_ZEPHYR void exit(int32_t status) { Konan_exit(status); } #else void exit(int32_t status) { ::exit(status); } #endif // String/byte operations. // memcpy/memmove are not here intentionally, as frequently implemented/optimized // by C compiler. void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen) { #if KONAN_NO_MEMMEM for (size_t i = 0; i + littleLen <= bigLen; ++i) { void* pos = ((char*)big) + i; if (::memcmp(little, pos, littleLen) == 0) return pos; } return nullptr; #else return ::memmem(big, bigLen, little, littleLen); #endif } // The sprintf family. int snprintf(char* buffer, size_t size, const char* format, ...) { va_list args; va_start(args, format); int rv = vsnprintf(buffer, size, format, args); va_end(args); return rv; } int vsnprintf(char* buffer, size_t size, const char* format, va_list args) { return vsnprintf_impl(buffer, size, format, args); } size_t strnlen(const char* buffer, size_t maxSize) { return ::strnlen(buffer, maxSize); } // Memory operations. #if KONAN_INTERNAL_DLMALLOC extern "C" void* dlcalloc(size_t, size_t); extern "C" void dlfree(void*); #define calloc_impl dlcalloc #define free_impl dlfree #define calloc_aligned_impl(count, size, alignment) dlcalloc(count, size) #else extern "C" void* konan_calloc_impl(size_t, size_t); extern "C" void konan_free_impl(void*); extern "C" void* konan_calloc_aligned_impl(size_t count, size_t size, size_t alignment); #define calloc_impl konan_calloc_impl #define free_impl konan_free_impl #define calloc_aligned_impl konan_calloc_aligned_impl #endif void* calloc(size_t count, size_t size) { return calloc_impl(count, size); } void* calloc_aligned(size_t count, size_t size, size_t alignment) { return calloc_aligned_impl(count, size, alignment); } void free(void* pointer) { free_impl(pointer); } #if KONAN_INTERNAL_NOW #ifdef KONAN_ZEPHYR void Konan_date_now(uint64_t* arg) { // TODO: so how will we support time for embedded? *arg = 0LL; } #else extern "C" void Konan_date_now(uint64_t*); #endif uint64_t getTimeMillis() { uint64_t now; Konan_date_now(&now); return now; } uint64_t getTimeMicros() { return getTimeMillis() * 1000ULL; } uint64_t getTimeNanos() { return getTimeMillis() * 1000000ULL; } #else // Time operations. using namespace std::chrono; // Get steady clock as a source of time using steady_time_clock = std::conditional::type; uint64_t getTimeMillis() { return duration_cast(steady_time_clock::now().time_since_epoch()).count(); } uint64_t getTimeNanos() { return duration_cast(steady_time_clock::now().time_since_epoch()).count(); } uint64_t getTimeMicros() { return duration_cast(steady_time_clock::now().time_since_epoch()).count(); } #endif #if KONAN_INTERNAL_DLMALLOC // This function is being called when memory allocator needs more RAM. #if KONAN_WASM namespace { constexpr uint32_t MFAIL = ~(uint32_t)0; constexpr uint32_t WASM_PAGESIZE_EXPONENT = 16; constexpr uint32_t WASM_PAGESIZE = 1u << WASM_PAGESIZE_EXPONENT; constexpr uint32_t WASM_PAGEMASK = WASM_PAGESIZE-1; uint32_t pageAlign(int32_t value) { return (value + WASM_PAGEMASK) & ~ (WASM_PAGEMASK); } uint32_t inBytes(uint32_t pageCount) { return pageCount << WASM_PAGESIZE_EXPONENT; } uint32_t inPages(uint32_t value) { return value >> WASM_PAGESIZE_EXPONENT; } extern "C" void Konan_notify_memory_grow(); uint32_t memorySize() { return __builtin_wasm_memory_size(0); } int32_t growMemory(uint32_t delta) { int32_t oldLength = __builtin_wasm_memory_grow(0, delta); Konan_notify_memory_grow(); return oldLength; } } void* moreCore(int32_t delta) { uint32_t top = inBytes(memorySize()); if (delta > 0) { if (growMemory(inPages(pageAlign(delta))) == 0) { return (void *) MFAIL; } } else if (delta < 0) { return (void *) MFAIL; } return (void *) top; } // dlmalloc() wants to know the page size. long getpagesize() { return WASM_PAGESIZE; } #else void* moreCore(int size) { return sbrk(size); } long getpagesize() { return sysconf(_SC_PAGESIZE); } #endif #endif } // namespace konan extern "C" { // TODO: get rid of these. #if (KONAN_WASM || KONAN_ZEPHYR) void _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(void) { Konan_abort("TODO: throw_length_error not implemented."); } void _ZNKSt3__220__vector_base_commonILb1EE20__throw_length_errorEv(void) { Konan_abort("TODO: throw_length_error not implemented."); } void _ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv(void) { Konan_abort("TODO: throw_length_error not implemented."); } void _ZNKSt3__221__basic_string_commonILb1EE20__throw_length_errorEv(void) { Konan_abort("TODO: throw_length_error not implemented."); } int _ZNSt3__212__next_primeEj(unsigned long n) { static unsigned long primes[] = { 11UL, 101UL, 1009UL, 10007UL, 100003UL, 1000003UL, 10000019UL, 100000007UL, 1000000007UL }; size_t table_length = sizeof(primes)/sizeof(unsigned long); if (n > primes[table_length - 1]) konan::abort(); unsigned long prime = primes[0]; for (unsigned long i=0; i< table_length; i++) { prime = primes[i]; if (prime >= n) break; } return prime; } int _ZNSt3__212__next_primeEm(int n) { return _ZNSt3__212__next_primeEj(n); } int _ZNSt3__112__next_primeEj(unsigned long n) { return _ZNSt3__212__next_primeEj(n); } void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) { char buf[1024]; konan::snprintf(buf, sizeof(buf), "%s:%d in %s: runtime assert: %s\n", file, line, function, assertion); Konan_abort(buf); } int* __errno_location() { static int theErrno = 0; return &theErrno; } // Some math.h functions. double pow(double x, double y) { return __builtin_pow(x, y); } #endif #ifdef KONAN_WASM // Some string.h functions. void *memcpy(void *dst, const void *src, size_t n) { for (size_t i = 0; i != n; ++i) *((char*)dst + i) = *((char*)src + i); return dst; } void *memmove(void *dst, const void *src, size_t len) { if (src < dst) { for (long i = len; i != 0; --i) { *((char*)dst + i - 1) = *((char*)src + i - 1); } } else { memcpy(dst, src, len); } return dst; } int memcmp(const void *s1, const void *s2, size_t n) { for (size_t i = 0; i != n; ++i) { if (*((char*)s1 + i) != *((char*)s2 + i)) { return *((char*)s1 + i) - *((char*)s2 + i); } } return 0; } void *memset(void *b, int c, size_t len) { for (size_t i = 0; i != len; ++i) { *((char*)b + i) = c; } return b; } size_t strlen(const char *s) { for (long i = 0;; ++i) { if (s[i] == 0) return i; } } size_t strnlen(const char *s, size_t maxlen) { for (size_t i = 0; i<=maxlen; ++i) { if (s[i] == 0) return i; } return maxlen; } #endif #ifdef KONAN_ZEPHYR RUNTIME_USED void Konan_abort(const char*) { while(1) {} } #endif // KONAN_ZEPHYR } // extern "C" ================================================ FILE: runtime/src/main/cpp/Porting.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_PORTING_H #define RUNTIME_PORTING_H #include #include #include #include "Common.h" namespace konan { // Console operations. void consoleInit(); void consolePrintf(const char* format, ...) __attribute__((format(printf, 1, 2))); void consoleErrorf(const char* format, ...) __attribute__((format(printf, 1, 2))); void consoleWriteUtf8(const void* utf8, uint32_t sizeBytes); void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes); // Negative return value denotes that read wasn't successful. int32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes); void consoleFlush(); // Process control. RUNTIME_NORETURN void abort(void); RUNTIME_NORETURN void exit(int32_t status); // Thread control. void onThreadExit(void (*destructor)(void*), void* destructorParameter); // String/byte operations. // memcpy/memmove/memcmp are not here intentionally, as frequently implemented/optimized // by C compiler. void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen); int snprintf(char* buffer, size_t size, const char* format, ...) __attribute__((format(printf, 3, 4))); int vsnprintf(char* buffer, size_t size, const char* format, va_list args) __attribute__((format(printf, 3, 0))); size_t strnlen(const char* buffer, size_t maxSize); // These functions should be marked with RUNTIME_USED attribute for wasm target // because clang replaces these operations with intrinsics that will be // replaced back to library calls only on codegen step. And there is no stdlib // for wasm target for now :( // Otherwise `opt` will see no usages of these definitions and will remove them. extern "C" { #ifdef KONAN_WASM RUNTIME_USED double pow(double x, double y); RUNTIME_USED void *memcpy(void *dst, const void *src, size_t n); RUNTIME_USED void *memmove(void *dst, const void *src, size_t len); RUNTIME_USED int memcmp(const void *s1, const void *s2, size_t n); RUNTIME_USED void *memset(void *b, int c, size_t len); #endif } // Memory operations. void* calloc(size_t count, size_t size); void* calloc_aligned(size_t count, size_t size, size_t alignment); void free(void* ptr); // Time operations. uint64_t getTimeMillis(); uint64_t getTimeMicros(); uint64_t getTimeNanos(); #if KONAN_NO_EXCEPTIONS #define TRY_CATCH(tryAction, actionWithoutExceptions, catchAction) actionWithoutExceptions; #else #define TRY_CATCH(tryAction, actionWithoutExceptions, catchAction) \ do { \ try { tryAction; } \ catch(...) { catchAction; } \ } while(0) #endif } // namespace konan #endif // RUNTIME_PORTING_H ================================================ FILE: runtime/src/main/cpp/PthreadUtils.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "PthreadUtils.h" #include #include namespace { constexpr int64_t kNanosecondsInASecond = 1000000000LL; } // namespace int WaitOnCondVar( pthread_cond_t* cond, pthread_mutex_t* mutex, uint64_t timeoutNanoseconds, uint64_t* microsecondsPassed) { struct timeval tvBefore; // TODO: Error reporting? gettimeofday(&tvBefore, nullptr); struct timespec ts; const uint64_t nanoseconds = tvBefore.tv_usec * 1000LL + timeoutNanoseconds; ts.tv_sec = tvBefore.tv_sec + nanoseconds / kNanosecondsInASecond; ts.tv_nsec = nanoseconds % kNanosecondsInASecond; auto result = pthread_cond_timedwait(cond, mutex, &ts); if (microsecondsPassed) { struct timeval tvAfter; // TODO: Error reporting? gettimeofday(&tvAfter, nullptr); *microsecondsPassed = (tvAfter.tv_sec - tvBefore.tv_sec) * 1000000LL + tvAfter.tv_usec - tvBefore.tv_usec; } return result; } ================================================ FILE: runtime/src/main/cpp/PthreadUtils.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_PTHREAD_UTILS_H #define RUNTIME_PTHREAD_UTILS_H #include #include // Releases mutex and waits on cond for timeoutNanoseconds. // Returns ETIMEDOUT if timeoutNanoseconds has passed. int WaitOnCondVar( pthread_cond_t* cond, pthread_mutex_t* mutex, uint64_t timeoutNanoseconds, uint64_t* microsecondsPassed = nullptr); #endif // RUNTIME_PTHREAD_UTILS_H ================================================ FILE: runtime/src/main/cpp/Regex.cpp ================================================ #include #include "Types.h" #include "KString.h" #include "Natives.h" namespace { /* Contains canonical classes (see http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt). */ constexpr KInt canonicalClassesKeys[] = { 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 1155, 1156, 1157, 1158, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1467, 1468, 1469, 1471, 1473, 1474, 1476, 1477, 1479, 1552, 1553, 1554, 1555, 1556, 1557, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1648, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1759, 1760, 1761, 1762, 1763, 1764, 1767, 1768, 1770, 1771, 1772, 1773, 1809, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 2364, 2381, 2385, 2386, 2387, 2388, 2492, 2509, 2620, 2637, 2748, 2765, 2876, 2893, 3021, 3149, 3157, 3158, 3260, 3277, 3405, 3530, 3640, 3641, 3642, 3656, 3657, 3658, 3659, 3768, 3769, 3784, 3785, 3786, 3787, 3864, 3865, 3893, 3895, 3897, 3953, 3954, 3956, 3962, 3963, 3964, 3965, 3968, 3970, 3971, 3972, 3974, 3975, 4038, 4151, 4153, 4959, 5908, 5940, 6098, 6109, 6313, 6457, 6458, 6459, 6679, 6680, 7616, 7617, 7618, 7619, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8411, 8412, 8417, 8421, 8422, 8423, 8424, 8425, 8426, 8427, 12330, 12331, 12332, 12333, 12334, 12335, 12441, 12442, 43014, 64286, 65056, 65057, 65058, 65059, 68109, 68111, 68152, 68153, 68154, 68159, 119141, 119142, 119143, 119144, 119145, 119149, 119150, 119151, 119152, 119153, 119154, 119163, 119164, 119165, 119166, 119167, 119168, 119169, 119170, 119173, 119174, 119175, 119176, 119177, 119178, 119179, 119210, 119211, 119212, 119213, 119362, 119363, 119364, }; constexpr KInt canonicalClassesValues[] = { 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 230, 220, 18, 230, 230, 230, 230, 230, 230, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 35, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 230, 220, 230, 230, 220, 36, 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 7, 9, 230, 220, 230, 230, 7, 9, 7, 9, 7, 9, 7, 9, 9, 9, 84, 91, 7, 9, 9, 9, 103, 103, 9, 107, 107, 107, 107, 118, 118, 122, 122, 122, 122, 220, 220, 220, 220, 216, 129, 130, 132, 130, 130, 130, 130, 130, 230, 230, 9, 230, 230, 220, 7, 9, 230, 9, 9, 9, 230, 228, 222, 230, 220, 230, 220, 230, 230, 220, 230, 230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 230, 1, 1, 230, 220, 230, 1, 1, 218, 228, 232, 222, 224, 224, 8, 8, 9, 26, 230, 230, 230, 230, 220, 230, 230, 1, 220, 9, 216, 216, 1, 1, 1, 226, 216, 216, 216, 216, 216, 220, 220, 220, 220, 220, 220, 220, 220, 230, 230, 230, 230, 230, 220, 220, 230, 230, 230, 230, 230, 230, 230, }; /* Symbols that are one symbol decompositions (see http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt). */ constexpr KInt singleDecompositions[] = { 59, 75, 96, 180, 183, 197, 697, 768, 769, 787, 901, 902, 904, 905, 906, 908, 910, 911, 912, 937, 940, 941, 942, 943, 944, 953, 972, 973, 974, 8194, 8195, 12296, 12297, 13470, 13497, 13499, 13535, 13589, 14062, 14076, 14209, 14383, 14434, 14460, 14535, 14563, 14620, 14650, 14894, 14956, 15076, 15112, 15129, 15177, 15261, 15384, 15438, 15667, 15766, 16044, 16056, 16155, 16380, 16392, 16408, 16441, 16454, 16534, 16611, 16687, 16898, 16935, 17056, 17153, 17204, 17241, 17365, 17369, 17419, 17515, 17707, 17757, 17761, 17771, 17879, 17913, 17973, 18110, 18119, 18837, 18918, 19054, 19062, 19122, 19251, 19406, 19662, 19693, 19704, 19798, 19981, 20006, 20018, 20024, 20025, 20029, 20033, 20098, 20102, 20142, 20160, 20172, 20196, 20320, 20352, 20358, 20363, 20398, 20411, 20415, 20482, 20523, 20602, 20633, 20687, 20698, 20711, 20800, 20805, 20813, 20820, 20836, 20839, 20840, 20841, 20845, 20855, 20864, 20877, 20882, 20885, 20887, 20900, 20908, 20917, 20919, 20937, 20940, 20956, 20958, 20981, 20995, 20999, 21015, 21033, 21050, 21051, 21062, 21106, 21111, 21129, 21147, 21155, 21171, 21191, 21193, 21202, 21214, 21220, 21237, 21242, 21253, 21254, 21271, 21311, 21321, 21329, 21338, 21363, 21365, 21373, 21375, 21443, 21450, 21471, 21477, 21483, 21489, 21510, 21519, 21533, 21560, 21570, 21576, 21608, 21662, 21666, 21693, 21750, 21776, 21843, 21845, 21859, 21892, 21895, 21913, 21917, 21931, 21939, 21952, 21954, 21986, 22022, 22097, 22120, 22132, 22265, 22294, 22295, 22411, 22478, 22516, 22541, 22577, 22578, 22592, 22618, 22622, 22696, 22700, 22707, 22744, 22751, 22766, 22770, 22775, 22790, 22810, 22818, 22852, 22856, 22865, 22868, 22882, 22899, 23000, 23020, 23067, 23079, 23138, 23142, 23221, 23304, 23336, 23358, 23429, 23491, 23512, 23527, 23534, 23539, 23551, 23558, 23586, 23615, 23648, 23650, 23652, 23653, 23662, 23693, 23744, 23833, 23875, 23888, 23915, 23918, 23932, 23986, 23994, 24033, 24034, 24061, 24104, 24125, 24169, 24180, 24230, 24240, 24243, 24246, 24265, 24266, 24274, 24275, 24281, 24300, 24318, 24324, 24354, 24403, 24418, 24425, 24427, 24459, 24474, 24489, 24493, 24525, 24535, 24565, 24569, 24594, 24604, 24705, 24724, 24775, 24792, 24801, 24840, 24900, 24904, 24908, 24910, 24928, 24936, 24954, 24974, 24976, 24996, 25007, 25010, 25054, 25074, 25078, 25088, 25104, 25115, 25134, 25140, 25181, 25265, 25289, 25295, 25299, 25300, 25340, 25342, 25405, 25424, 25448, 25467, 25475, 25504, 25513, 25540, 25541, 25572, 25628, 25634, 25682, 25705, 25719, 25726, 25754, 25757, 25796, 25935, 25942, 25964, 25976, 26009, 26053, 26082, 26083, 26131, 26185, 26228, 26248, 26257, 26268, 26292, 26310, 26356, 26360, 26368, 26391, 26395, 26401, 26446, 26451, 26454, 26462, 26491, 26501, 26519, 26611, 26618, 26647, 26655, 26706, 26753, 26757, 26766, 26792, 26900, 26946, 27043, 27114, 27138, 27155, 27304, 27347, 27355, 27396, 27425, 27476, 27506, 27511, 27513, 27551, 27566, 27578, 27579, 27726, 27751, 27784, 27839, 27852, 27853, 27877, 27926, 27931, 27934, 27956, 27966, 27969, 28009, 28010, 28023, 28024, 28037, 28107, 28122, 28138, 28153, 28186, 28207, 28270, 28316, 28346, 28359, 28363, 28369, 28379, 28431, 28450, 28451, 28526, 28614, 28651, 28670, 28699, 28702, 28729, 28746, 28784, 28791, 28797, 28825, 28845, 28872, 28889, 28997, 29001, 29038, 29084, 29134, 29136, 29200, 29211, 29224, 29227, 29237, 29264, 29282, 29312, 29333, 29359, 29376, 29436, 29482, 29557, 29562, 29575, 29579, 29605, 29618, 29662, 29702, 29705, 29730, 29767, 29788, 29801, 29809, 29829, 29833, 29848, 29898, 29958, 29988, 30011, 30014, 30041, 30053, 30064, 30178, 30224, 30237, 30239, 30274, 30313, 30410, 30427, 30439, 30452, 30465, 30494, 30495, 30528, 30538, 30603, 30631, 30798, 30827, 30860, 30865, 30922, 30924, 30971, 31018, 31036, 31038, 31048, 31049, 31056, 31062, 31069, 31070, 31077, 31103, 31117, 31118, 31119, 31150, 31178, 31211, 31260, 31296, 31306, 31311, 31361, 31409, 31435, 31470, 31520, 31680, 31686, 31689, 31806, 31840, 31867, 31890, 31934, 31954, 31958, 31971, 31975, 31976, 32000, 32016, 32034, 32047, 32091, 32099, 32160, 32190, 32199, 32244, 32258, 32265, 32311, 32321, 32325, 32574, 32626, 32633, 32634, 32645, 32661, 32666, 32701, 32762, 32769, 32773, 32838, 32864, 32879, 32880, 32894, 32907, 32941, 32946, 33027, 33086, 33240, 33256, 33261, 33281, 33284, 33391, 33401, 33419, 33425, 33437, 33457, 33459, 33469, 33509, 33510, 33565, 33571, 33590, 33618, 33619, 33635, 33709, 33725, 33737, 33738, 33740, 33756, 33767, 33775, 33777, 33853, 33865, 33879, 34030, 34033, 34035, 34044, 34070, 34148, 34253, 34298, 34310, 34322, 34349, 34367, 34384, 34396, 34407, 34409, 34440, 34473, 34530, 34574, 34600, 34667, 34681, 34694, 34746, 34785, 34817, 34847, 34892, 34912, 34915, 35010, 35023, 35031, 35038, 35041, 35064, 35066, 35088, 35137, 35172, 35206, 35211, 35222, 35488, 35498, 35519, 35531, 35538, 35542, 35565, 35576, 35582, 35585, 35641, 35672, 35712, 35722, 35912, 35925, 36011, 36033, 36034, 36040, 36051, 36104, 36123, 36215, 36284, 36299, 36335, 36336, 36554, 36564, 36646, 36650, 36664, 36667, 36706, 36766, 36784, 36790, 36899, 36920, 36978, 36988, 37007, 37012, 37070, 37105, 37117, 37137, 37147, 37226, 37273, 37300, 37324, 37327, 37329, 37428, 37432, 37494, 37500, 37591, 37592, 37636, 37706, 37881, 37909, 38283, 38317, 38327, 38446, 38475, 38477, 38517, 38520, 38524, 38534, 38563, 38584, 38595, 38626, 38627, 38646, 38647, 38691, 38706, 38728, 38742, 38875, 38880, 38911, 38923, 38936, 38953, 38971, 39006, 39138, 39151, 39164, 39208, 39209, 39335, 39362, 39409, 39422, 39530, 39698, 39791, 40000, 40023, 40189, 40295, 40372, 40442, 40478, 40575, 40599, 40607, 40635, 40654, 40697, 40702, 40709, 40719, 40726, 40763, 40771, 40845, 40846, 40860, 131362, 132380, 132389, 132427, 132666, 133124, 133342, 133676, 133987, 136420, 136872, 136938, 137672, 138008, 138507, 138724, 138726, 139651, 139679, 140081, 141012, 141380, 141386, 142092, 142321, 143370, 144056, 144223, 144275, 144284, 144323, 144341, 144493, 145059, 145575, 146061, 146170, 146620, 146718, 147153, 147294, 147342, 148067, 148395, 149000, 149301, 149524, 150582, 150674, 151457, 151480, 151620, 151794, 151795, 151833, 151859, 152137, 152605, 153126, 153242, 153285, 153980, 154279, 154539, 154752, 154832, 155526, 156122, 156200, 156231, 156377, 156478, 156890, 156963, 157096, 157607, 157621, 158524, 158774, 158933, 159083, 159532, 159665, 159954, 160714, 161383, 161966, 162150, 162984, 163539, 163631, 165330, 165357, 165678, 166906, 167287, 168261, 168415, 168474, 168970, 169110, 169398, 170800, 172238, 172293, 172558, 172689, 172946, 173568 }; constexpr KInt decompositionKeys[] = { 192, 193, 194, 195, 196, 197, 199, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 241, 242, 243, 244, 245, 246, 249, 250, 251, 252, 253, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 296, 297, 298, 299, 300, 301, 302, 303, 304, 308, 309, 310, 311, 313, 314, 315, 316, 317, 318, 323, 324, 325, 326, 327, 328, 332, 333, 334, 335, 336, 337, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 416, 417, 431, 432, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 478, 479, 480, 481, 482, 483, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 500, 501, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 542, 543, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 832, 833, 835, 836, 884, 894, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 938, 939, 940, 941, 942, 943, 944, 970, 971, 972, 973, 974, 979, 980, 1024, 1025, 1027, 1031, 1036, 1037, 1038, 1049, 1081, 1104, 1105, 1107, 1111, 1116, 1117, 1118, 1142, 1143, 1217, 1218, 1232, 1233, 1234, 1235, 1238, 1239, 1242, 1243, 1244, 1245, 1246, 1247, 1250, 1251, 1252, 1253, 1254, 1255, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1272, 1273, 1570, 1571, 1572, 1573, 1574, 1728, 1730, 1747, 2345, 2353, 2356, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2507, 2508, 2524, 2525, 2527, 2611, 2614, 2649, 2650, 2651, 2654, 2888, 2891, 2892, 2908, 2909, 2964, 3018, 3019, 3020, 3144, 3264, 3271, 3272, 3274, 3275, 3402, 3403, 3404, 3546, 3548, 3549, 3550, 3907, 3917, 3922, 3927, 3932, 3945, 3955, 3957, 3958, 3960, 3969, 3987, 3997, 4002, 4007, 4012, 4025, 4134, 7680, 7681, 7682, 7683, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7702, 7703, 7704, 7705, 7706, 7707, 7708, 7709, 7710, 7711, 7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7726, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7743, 7744, 7745, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 7779, 7780, 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, 7790, 7791, 7792, 7793, 7794, 7795, 7796, 7797, 7798, 7799, 7800, 7801, 7802, 7803, 7804, 7805, 7806, 7807, 7808, 7809, 7810, 7811, 7812, 7813, 7814, 7815, 7816, 7817, 7818, 7819, 7820, 7821, 7822, 7823, 7824, 7825, 7826, 7827, 7828, 7829, 7830, 7831, 7832, 7833, 7835, 7840, 7841, 7842, 7843, 7844, 7845, 7846, 7847, 7848, 7849, 7850, 7851, 7852, 7853, 7854, 7855, 7856, 7857, 7858, 7859, 7860, 7861, 7862, 7863, 7864, 7865, 7866, 7867, 7868, 7869, 7870, 7871, 7872, 7873, 7874, 7875, 7876, 7877, 7878, 7879, 7880, 7881, 7882, 7883, 7884, 7885, 7886, 7887, 7888, 7889, 7890, 7891, 7892, 7893, 7894, 7895, 7896, 7897, 7898, 7899, 7900, 7901, 7902, 7903, 7904, 7905, 7906, 7907, 7908, 7909, 7910, 7911, 7912, 7913, 7914, 7915, 7916, 7917, 7918, 7919, 7920, 7921, 7922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7960, 7961, 7962, 7963, 7964, 7965, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 8000, 8001, 8002, 8003, 8004, 8005, 8008, 8009, 8010, 8011, 8012, 8013, 8016, 8017, 8018, 8019, 8020, 8021, 8022, 8023, 8025, 8027, 8029, 8031, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 8048, 8049, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8118, 8119, 8120, 8121, 8122, 8123, 8124, 8126, 8129, 8130, 8131, 8132, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8150, 8151, 8152, 8153, 8154, 8155, 8157, 8158, 8159, 8160, 8161, 8162, 8163, 8164, 8165, 8166, 8167, 8168, 8169, 8170, 8171, 8172, 8173, 8174, 8175, 8178, 8179, 8180, 8182, 8183, 8184, 8185, 8186, 8187, 8188, 8189, 8192, 8193, 8486, 8490, 8491, 8602, 8603, 8622, 8653, 8654, 8655, 8708, 8713, 8716, 8740, 8742, 8769, 8772, 8775, 8777, 8800, 8802, 8813, 8814, 8815, 8816, 8817, 8820, 8821, 8824, 8825, 8832, 8833, 8836, 8837, 8840, 8841, 8876, 8877, 8878, 8879, 8928, 8929, 8930, 8931, 8938, 8939, 8940, 8941, 9001, 9002, 10972, 12364, 12366, 12368, 12370, 12372, 12374, 12376, 12378, 12380, 12382, 12384, 12386, 12389, 12391, 12393, 12400, 12401, 12403, 12404, 12406, 12407, 12409, 12410, 12412, 12413, 12436, 12446, 12460, 12462, 12464, 12466, 12468, 12470, 12472, 12474, 12476, 12478, 12480, 12482, 12485, 12487, 12489, 12496, 12497, 12499, 12500, 12502, 12503, 12505, 12506, 12508, 12509, 12532, 12535, 12536, 12537, 12538, 12542, 63744, 63745, 63746, 63747, 63748, 63749, 63750, 63751, 63752, 63753, 63754, 63755, 63756, 63757, 63758, 63759, 63760, 63761, 63762, 63763, 63764, 63765, 63766, 63767, 63768, 63769, 63770, 63771, 63772, 63773, 63774, 63775, 63776, 63777, 63778, 63779, 63780, 63781, 63782, 63783, 63784, 63785, 63786, 63787, 63788, 63789, 63790, 63791, 63792, 63793, 63794, 63795, 63796, 63797, 63798, 63799, 63800, 63801, 63802, 63803, 63804, 63805, 63806, 63807, 63808, 63809, 63810, 63811, 63812, 63813, 63814, 63815, 63816, 63817, 63818, 63819, 63820, 63821, 63822, 63823, 63824, 63825, 63826, 63827, 63828, 63829, 63830, 63831, 63832, 63833, 63834, 63835, 63836, 63837, 63838, 63839, 63840, 63841, 63842, 63843, 63844, 63845, 63846, 63847, 63848, 63849, 63850, 63851, 63852, 63853, 63854, 63855, 63856, 63857, 63858, 63859, 63860, 63861, 63862, 63863, 63864, 63865, 63866, 63867, 63868, 63869, 63870, 63871, 63872, 63873, 63874, 63875, 63876, 63877, 63878, 63879, 63880, 63881, 63882, 63883, 63884, 63885, 63886, 63887, 63888, 63889, 63890, 63891, 63892, 63893, 63894, 63895, 63896, 63897, 63898, 63899, 63900, 63901, 63902, 63903, 63904, 63905, 63906, 63907, 63908, 63909, 63910, 63911, 63912, 63913, 63914, 63915, 63916, 63917, 63918, 63919, 63920, 63921, 63922, 63923, 63924, 63925, 63926, 63927, 63928, 63929, 63930, 63931, 63932, 63933, 63934, 63935, 63936, 63937, 63938, 63939, 63940, 63941, 63942, 63943, 63944, 63945, 63946, 63947, 63948, 63949, 63950, 63951, 63952, 63953, 63954, 63955, 63956, 63957, 63958, 63959, 63960, 63961, 63962, 63963, 63964, 63965, 63966, 63967, 63968, 63969, 63970, 63971, 63972, 63973, 63974, 63975, 63976, 63977, 63978, 63979, 63980, 63981, 63982, 63983, 63984, 63985, 63986, 63987, 63988, 63989, 63990, 63991, 63992, 63993, 63994, 63995, 63996, 63997, 63998, 63999, 64000, 64001, 64002, 64003, 64004, 64005, 64006, 64007, 64008, 64009, 64010, 64011, 64012, 64013, 64016, 64018, 64021, 64022, 64023, 64024, 64025, 64026, 64027, 64028, 64029, 64030, 64032, 64034, 64037, 64038, 64042, 64043, 64044, 64045, 64048, 64049, 64050, 64051, 64052, 64053, 64054, 64055, 64056, 64057, 64058, 64059, 64060, 64061, 64062, 64063, 64064, 64065, 64066, 64067, 64068, 64069, 64070, 64071, 64072, 64073, 64074, 64075, 64076, 64077, 64078, 64079, 64080, 64081, 64082, 64083, 64084, 64085, 64086, 64087, 64088, 64089, 64090, 64091, 64092, 64093, 64094, 64095, 64096, 64097, 64098, 64099, 64100, 64101, 64102, 64103, 64104, 64105, 64106, 64112, 64113, 64114, 64115, 64116, 64117, 64118, 64119, 64120, 64121, 64122, 64123, 64124, 64125, 64126, 64127, 64128, 64129, 64130, 64131, 64132, 64133, 64134, 64135, 64136, 64137, 64138, 64139, 64140, 64141, 64142, 64143, 64144, 64145, 64146, 64147, 64148, 64149, 64150, 64151, 64152, 64153, 64154, 64155, 64156, 64157, 64158, 64159, 64160, 64161, 64162, 64163, 64164, 64165, 64166, 64167, 64168, 64169, 64170, 64171, 64172, 64173, 64174, 64175, 64176, 64177, 64178, 64179, 64180, 64181, 64182, 64183, 64184, 64185, 64186, 64187, 64188, 64189, 64190, 64191, 64192, 64193, 64194, 64195, 64196, 64197, 64198, 64199, 64200, 64201, 64202, 64203, 64204, 64205, 64206, 64207, 64208, 64209, 64210, 64211, 64212, 64213, 64214, 64215, 64216, 64217, 64285, 64287, 64298, 64299, 64300, 64301, 64302, 64303, 64304, 64305, 64306, 64307, 64308, 64309, 64310, 64312, 64313, 64314, 64315, 64316, 64318, 64320, 64321, 64323, 64324, 64326, 64327, 64328, 64329, 64330, 64331, 64332, 64333, 64334, 119134, 119135, 119136, 119137, 119138, 119139, 119140, 119227, 119228, 119229, 119230, 119231, 119232, 194560, 194561, 194562, 194563, 194564, 194565, 194566, 194567, 194568, 194569, 194570, 194571, 194572, 194573, 194574, 194575, 194576, 194577, 194578, 194579, 194580, 194581, 194582, 194583, 194584, 194585, 194586, 194587, 194588, 194589, 194590, 194591, 194592, 194593, 194594, 194595, 194596, 194597, 194598, 194599, 194600, 194601, 194602, 194603, 194604, 194605, 194606, 194607, 194608, 194609, 194610, 194611, 194612, 194613, 194614, 194615, 194616, 194617, 194618, 194619, 194620, 194621, 194622, 194623, 194624, 194625, 194626, 194627, 194628, 194629, 194630, 194631, 194632, 194633, 194634, 194635, 194636, 194637, 194638, 194639, 194640, 194641, 194642, 194643, 194644, 194645, 194646, 194647, 194648, 194649, 194650, 194651, 194652, 194653, 194654, 194655, 194656, 194657, 194658, 194659, 194660, 194661, 194662, 194663, 194664, 194665, 194666, 194667, 194668, 194669, 194670, 194671, 194672, 194673, 194674, 194675, 194676, 194677, 194678, 194679, 194680, 194681, 194682, 194683, 194684, 194685, 194686, 194687, 194688, 194689, 194690, 194691, 194692, 194693, 194694, 194695, 194696, 194697, 194698, 194699, 194700, 194701, 194702, 194703, 194704, 194705, 194706, 194707, 194708, 194709, 194710, 194711, 194712, 194713, 194714, 194715, 194716, 194717, 194718, 194719, 194720, 194721, 194722, 194723, 194724, 194725, 194726, 194727, 194728, 194729, 194730, 194731, 194732, 194733, 194734, 194735, 194736, 194737, 194738, 194739, 194740, 194741, 194742, 194743, 194744, 194745, 194746, 194747, 194748, 194749, 194750, 194751, 194752, 194753, 194754, 194755, 194756, 194757, 194758, 194759, 194760, 194761, 194762, 194763, 194764, 194765, 194766, 194767, 194768, 194769, 194770, 194771, 194772, 194773, 194774, 194775, 194776, 194777, 194778, 194779, 194780, 194781, 194782, 194783, 194784, 194785, 194786, 194787, 194788, 194789, 194790, 194791, 194792, 194793, 194794, 194795, 194796, 194797, 194798, 194799, 194800, 194801, 194802, 194803, 194804, 194805, 194806, 194807, 194808, 194809, 194810, 194811, 194812, 194813, 194814, 194815, 194816, 194817, 194818, 194819, 194820, 194821, 194822, 194823, 194824, 194825, 194826, 194827, 194828, 194829, 194830, 194831, 194832, 194833, 194834, 194835, 194836, 194837, 194838, 194839, 194840, 194841, 194842, 194843, 194844, 194845, 194846, 194847, 194848, 194849, 194850, 194851, 194852, 194853, 194854, 194855, 194856, 194857, 194858, 194859, 194860, 194861, 194862, 194863, 194864, 194865, 194866, 194867, 194868, 194869, 194870, 194871, 194872, 194873, 194874, 194875, 194876, 194877, 194878, 194879, 194880, 194881, 194882, 194883, 194884, 194885, 194886, 194887, 194888, 194889, 194890, 194891, 194892, 194893, 194894, 194895, 194896, 194897, 194898, 194899, 194900, 194901, 194902, 194903, 194904, 194905, 194906, 194907, 194908, 194909, 194910, 194911, 194912, 194913, 194914, 194915, 194916, 194917, 194918, 194919, 194920, 194921, 194922, 194923, 194924, 194925, 194926, 194927, 194928, 194929, 194930, 194931, 194932, 194933, 194934, 194935, 194936, 194937, 194938, 194939, 194940, 194941, 194942, 194943, 194944, 194945, 194946, 194947, 194948, 194949, 194950, 194951, 194952, 194953, 194954, 194955, 194956, 194957, 194958, 194959, 194960, 194961, 194962, 194963, 194964, 194965, 194966, 194967, 194968, 194969, 194970, 194971, 194972, 194973, 194974, 194975, 194976, 194977, 194978, 194979, 194980, 194981, 194982, 194983, 194984, 194985, 194986, 194987, 194988, 194989, 194990, 194991, 194992, 194993, 194994, 194995, 194996, 194997, 194998, 194999, 195000, 195001, 195002, 195003, 195004, 195005, 195006, 195007, 195008, 195009, 195010, 195011, 195012, 195013, 195014, 195015, 195016, 195017, 195018, 195019, 195020, 195021, 195022, 195023, 195024, 195025, 195026, 195027, 195028, 195029, 195030, 195031, 195032, 195033, 195034, 195035, 195036, 195037, 195038, 195039, 195040, 195041, 195042, 195043, 195044, 195045, 195046, 195047, 195048, 195049, 195050, 195051, 195052, 195053, 195054, 195055, 195056, 195057, 195058, 195059, 195060, 195061, 195062, 195063, 195064, 195065, 195066, 195067, 195068, 195069, 195070, 195071, 195072, 195073, 195074, 195075, 195076, 195077, 195078, 195079, 195080, 195081, 195082, 195083, 195084, 195085, 195086, 195087, 195088, 195089, 195090, 195091, 195092, 195093, 195094, 195095, 195096, 195097, 195098, 195099, 195100, 195101 }; struct Decomposition { const KInt array[4]; const KByte length; }; constexpr Decomposition decompositionValues[] = { {{65, 768}, 2}, {{65, 769}, 2}, {{65, 770}, 2}, {{65, 771}, 2}, {{65, 776}, 2}, {{65, 778}, 2}, {{67, 807}, 2}, {{69, 768}, 2}, {{69, 769}, 2}, {{69, 770}, 2}, {{69, 776}, 2}, {{73, 768}, 2}, {{73, 769}, 2}, {{73, 770}, 2}, {{73, 776}, 2}, {{78, 771}, 2}, {{79, 768}, 2}, {{79, 769}, 2}, {{79, 770}, 2}, {{79, 771}, 2}, {{79, 776}, 2}, {{85, 768}, 2}, {{85, 769}, 2}, {{85, 770}, 2}, {{85, 776}, 2}, {{89, 769}, 2}, {{97, 768}, 2}, {{97, 769}, 2}, {{97, 770}, 2}, {{97, 771}, 2}, {{97, 776}, 2}, {{97, 778}, 2}, {{99, 807}, 2}, {{101, 768}, 2}, {{101, 769}, 2}, {{101, 770}, 2}, {{101, 776}, 2}, {{105, 768}, 2}, {{105, 769}, 2}, {{105, 770}, 2}, {{105, 776}, 2}, {{110, 771}, 2}, {{111, 768}, 2}, {{111, 769}, 2}, {{111, 770}, 2}, {{111, 771}, 2}, {{111, 776}, 2}, {{117, 768}, 2}, {{117, 769}, 2}, {{117, 770}, 2}, {{117, 776}, 2}, {{121, 769}, 2}, {{121, 776}, 2}, {{65, 772}, 2}, {{97, 772}, 2}, {{65, 774}, 2}, {{97, 774}, 2}, {{65, 808}, 2}, {{97, 808}, 2}, {{67, 769}, 2}, {{99, 769}, 2}, {{67, 770}, 2}, {{99, 770}, 2}, {{67, 775}, 2}, {{99, 775}, 2}, {{67, 780}, 2}, {{99, 780}, 2}, {{68, 780}, 2}, {{100, 780}, 2}, {{69, 772}, 2}, {{101, 772}, 2}, {{69, 774}, 2}, {{101, 774}, 2}, {{69, 775}, 2}, {{101, 775}, 2}, {{69, 808}, 2}, {{101, 808}, 2}, {{69, 780}, 2}, {{101, 780}, 2}, {{71, 770}, 2}, {{103, 770}, 2}, {{71, 774}, 2}, {{103, 774}, 2}, {{71, 775}, 2}, {{103, 775}, 2}, {{71, 807}, 2}, {{103, 807}, 2}, {{72, 770}, 2}, {{104, 770}, 2}, {{73, 771}, 2}, {{105, 771}, 2}, {{73, 772}, 2}, {{105, 772}, 2}, {{73, 774}, 2}, {{105, 774}, 2}, {{73, 808}, 2}, {{105, 808}, 2}, {{73, 775}, 2}, {{74, 770}, 2}, {{106, 770}, 2}, {{75, 807}, 2}, {{107, 807}, 2}, {{76, 769}, 2}, {{108, 769}, 2}, {{76, 807}, 2}, {{108, 807}, 2}, {{76, 780}, 2}, {{108, 780}, 2}, {{78, 769}, 2}, {{110, 769}, 2}, {{78, 807}, 2}, {{110, 807}, 2}, {{78, 780}, 2}, {{110, 780}, 2}, {{79, 772}, 2}, {{111, 772}, 2}, {{79, 774}, 2}, {{111, 774}, 2}, {{79, 779}, 2}, {{111, 779}, 2}, {{82, 769}, 2}, {{114, 769}, 2}, {{82, 807}, 2}, {{114, 807}, 2}, {{82, 780}, 2}, {{114, 780}, 2}, {{83, 769}, 2}, {{115, 769}, 2}, {{83, 770}, 2}, {{115, 770}, 2}, {{83, 807}, 2}, {{115, 807}, 2}, {{83, 780}, 2}, {{115, 780}, 2}, {{84, 807}, 2}, {{116, 807}, 2}, {{84, 780}, 2}, {{116, 780}, 2}, {{85, 771}, 2}, {{117, 771}, 2}, {{85, 772}, 2}, {{117, 772}, 2}, {{85, 774}, 2}, {{117, 774}, 2}, {{85, 778}, 2}, {{117, 778}, 2}, {{85, 779}, 2}, {{117, 779}, 2}, {{85, 808}, 2}, {{117, 808}, 2}, {{87, 770}, 2}, {{119, 770}, 2}, {{89, 770}, 2}, {{121, 770}, 2}, {{89, 776}, 2}, {{90, 769}, 2}, {{122, 769}, 2}, {{90, 775}, 2}, {{122, 775}, 2}, {{90, 780}, 2}, {{122, 780}, 2}, {{79, 795}, 2}, {{111, 795}, 2}, {{85, 795}, 2}, {{117, 795}, 2}, {{65, 780}, 2}, {{97, 780}, 2}, {{73, 780}, 2}, {{105, 780}, 2}, {{79, 780}, 2}, {{111, 780}, 2}, {{85, 780}, 2}, {{117, 780}, 2}, {{85, 776, 772}, 3}, {{117, 776, 772}, 3}, {{85, 776, 769}, 3}, {{117, 776, 769}, 3}, {{85, 776, 780}, 3}, {{117, 776, 780}, 3}, {{85, 776, 768}, 3}, {{117, 776, 768}, 3}, {{65, 776, 772}, 3}, {{97, 776, 772}, 3}, {{65, 775, 772}, 3}, {{97, 775, 772}, 3}, {{198, 772}, 2}, {{230, 772}, 2}, {{71, 780}, 2}, {{103, 780}, 2}, {{75, 780}, 2}, {{107, 780}, 2}, {{79, 808}, 2}, {{111, 808}, 2}, {{79, 808, 772}, 3}, {{111, 808, 772}, 3}, {{439, 780}, 2}, {{658, 780}, 2}, {{106, 780}, 2}, {{71, 769}, 2}, {{103, 769}, 2}, {{78, 768}, 2}, {{110, 768}, 2}, {{65, 778, 769}, 3}, {{97, 778, 769}, 3}, {{198, 769}, 2}, {{230, 769}, 2}, {{216, 769}, 2}, {{248, 769}, 2}, {{65, 783}, 2}, {{97, 783}, 2}, {{65, 785}, 2}, {{97, 785}, 2}, {{69, 783}, 2}, {{101, 783}, 2}, {{69, 785}, 2}, {{101, 785}, 2}, {{73, 783}, 2}, {{105, 783}, 2}, {{73, 785}, 2}, {{105, 785}, 2}, {{79, 783}, 2}, {{111, 783}, 2}, {{79, 785}, 2}, {{111, 785}, 2}, {{82, 783}, 2}, {{114, 783}, 2}, {{82, 785}, 2}, {{114, 785}, 2}, {{85, 783}, 2}, {{117, 783}, 2}, {{85, 785}, 2}, {{117, 785}, 2}, {{83, 806}, 2}, {{115, 806}, 2}, {{84, 806}, 2}, {{116, 806}, 2}, {{72, 780}, 2}, {{104, 780}, 2}, {{65, 775}, 2}, {{97, 775}, 2}, {{69, 807}, 2}, {{101, 807}, 2}, {{79, 776, 772}, 3}, {{111, 776, 772}, 3}, {{79, 771, 772}, 3}, {{111, 771, 772}, 3}, {{79, 775}, 2}, {{111, 775}, 2}, {{79, 775, 772}, 3}, {{111, 775, 772}, 3}, {{89, 772}, 2}, {{121, 772}, 2}, {{768}, 1}, {{769}, 1}, {{787}, 1}, {{776, 769}, 2}, {{697}, 1}, {{59}, 1}, {{168, 769}, 2}, {{913, 769}, 2}, {{183}, 1}, {{917, 769}, 2}, {{919, 769}, 2}, {{921, 769}, 2}, {{927, 769}, 2}, {{933, 769}, 2}, {{937, 769}, 2}, {{953, 776, 769}, 3}, {{921, 776}, 2}, {{933, 776}, 2}, {{945, 769}, 2}, {{949, 769}, 2}, {{951, 769}, 2}, {{953, 769}, 2}, {{965, 776, 769}, 3}, {{953, 776}, 2}, {{965, 776}, 2}, {{959, 769}, 2}, {{965, 769}, 2}, {{969, 769}, 2}, {{978, 769}, 2}, {{978, 776}, 2}, {{1045, 768}, 2}, {{1045, 776}, 2}, {{1043, 769}, 2}, {{1030, 776}, 2}, {{1050, 769}, 2}, {{1048, 768}, 2}, {{1059, 774}, 2}, {{1048, 774}, 2}, {{1080, 774}, 2}, {{1077, 768}, 2}, {{1077, 776}, 2}, {{1075, 769}, 2}, {{1110, 776}, 2}, {{1082, 769}, 2}, {{1080, 768}, 2}, {{1091, 774}, 2}, {{1140, 783}, 2}, {{1141, 783}, 2}, {{1046, 774}, 2}, {{1078, 774}, 2}, {{1040, 774}, 2}, {{1072, 774}, 2}, {{1040, 776}, 2}, {{1072, 776}, 2}, {{1045, 774}, 2}, {{1077, 774}, 2}, {{1240, 776}, 2}, {{1241, 776}, 2}, {{1046, 776}, 2}, {{1078, 776}, 2}, {{1047, 776}, 2}, {{1079, 776}, 2}, {{1048, 772}, 2}, {{1080, 772}, 2}, {{1048, 776}, 2}, {{1080, 776}, 2}, {{1054, 776}, 2}, {{1086, 776}, 2}, {{1256, 776}, 2}, {{1257, 776}, 2}, {{1069, 776}, 2}, {{1101, 776}, 2}, {{1059, 772}, 2}, {{1091, 772}, 2}, {{1059, 776}, 2}, {{1091, 776}, 2}, {{1059, 779}, 2}, {{1091, 779}, 2}, {{1063, 776}, 2}, {{1095, 776}, 2}, {{1067, 776}, 2}, {{1099, 776}, 2}, {{1575, 1619}, 2}, {{1575, 1620}, 2}, {{1608, 1620}, 2}, {{1575, 1621}, 2}, {{1610, 1620}, 2}, {{1749, 1620}, 2}, {{1729, 1620}, 2}, {{1746, 1620}, 2}, {{2344, 2364}, 2}, {{2352, 2364}, 2}, {{2355, 2364}, 2}, {{2325, 2364}, 2}, {{2326, 2364}, 2}, {{2327, 2364}, 2}, {{2332, 2364}, 2}, {{2337, 2364}, 2}, {{2338, 2364}, 2}, {{2347, 2364}, 2}, {{2351, 2364}, 2}, {{2503, 2494}, 2}, {{2503, 2519}, 2}, {{2465, 2492}, 2}, {{2466, 2492}, 2}, {{2479, 2492}, 2}, {{2610, 2620}, 2}, {{2616, 2620}, 2}, {{2582, 2620}, 2}, {{2583, 2620}, 2}, {{2588, 2620}, 2}, {{2603, 2620}, 2}, {{2887, 2902}, 2}, {{2887, 2878}, 2}, {{2887, 2903}, 2}, {{2849, 2876}, 2}, {{2850, 2876}, 2}, {{2962, 3031}, 2}, {{3014, 3006}, 2}, {{3015, 3006}, 2}, {{3014, 3031}, 2}, {{3142, 3158}, 2}, {{3263, 3285}, 2}, {{3270, 3285}, 2}, {{3270, 3286}, 2}, {{3270, 3266}, 2}, {{3270, 3266, 3285}, 3}, {{3398, 3390}, 2}, {{3399, 3390}, 2}, {{3398, 3415}, 2}, {{3545, 3530}, 2}, {{3545, 3535}, 2}, {{3545, 3535, 3530}, 3}, {{3545, 3551}, 2}, {{3906, 4023}, 2}, {{3916, 4023}, 2}, {{3921, 4023}, 2}, {{3926, 4023}, 2}, {{3931, 4023}, 2}, {{3904, 4021}, 2}, {{3953, 3954}, 2}, {{3953, 3956}, 2}, {{4018, 3968}, 2}, {{4019, 3968}, 2}, {{3953, 3968}, 2}, {{3986, 4023}, 2}, {{3996, 4023}, 2}, {{4001, 4023}, 2}, {{4006, 4023}, 2}, {{4011, 4023}, 2}, {{3984, 4021}, 2}, {{4133, 4142}, 2}, {{65, 805}, 2}, {{97, 805}, 2}, {{66, 775}, 2}, {{98, 775}, 2}, {{66, 803}, 2}, {{98, 803}, 2}, {{66, 817}, 2}, {{98, 817}, 2}, {{67, 807, 769}, 3}, {{99, 807, 769}, 3}, {{68, 775}, 2}, {{100, 775}, 2}, {{68, 803}, 2}, {{100, 803}, 2}, {{68, 817}, 2}, {{100, 817}, 2}, {{68, 807}, 2}, {{100, 807}, 2}, {{68, 813}, 2}, {{100, 813}, 2}, {{69, 772, 768}, 3}, {{101, 772, 768}, 3}, {{69, 772, 769}, 3}, {{101, 772, 769}, 3}, {{69, 813}, 2}, {{101, 813}, 2}, {{69, 816}, 2}, {{101, 816}, 2}, {{69, 807, 774}, 3}, {{101, 807, 774}, 3}, {{70, 775}, 2}, {{102, 775}, 2}, {{71, 772}, 2}, {{103, 772}, 2}, {{72, 775}, 2}, {{104, 775}, 2}, {{72, 803}, 2}, {{104, 803}, 2}, {{72, 776}, 2}, {{104, 776}, 2}, {{72, 807}, 2}, {{104, 807}, 2}, {{72, 814}, 2}, {{104, 814}, 2}, {{73, 816}, 2}, {{105, 816}, 2}, {{73, 776, 769}, 3}, {{105, 776, 769}, 3}, {{75, 769}, 2}, {{107, 769}, 2}, {{75, 803}, 2}, {{107, 803}, 2}, {{75, 817}, 2}, {{107, 817}, 2}, {{76, 803}, 2}, {{108, 803}, 2}, {{76, 803, 772}, 3}, {{108, 803, 772}, 3}, {{76, 817}, 2}, {{108, 817}, 2}, {{76, 813}, 2}, {{108, 813}, 2}, {{77, 769}, 2}, {{109, 769}, 2}, {{77, 775}, 2}, {{109, 775}, 2}, {{77, 803}, 2}, {{109, 803}, 2}, {{78, 775}, 2}, {{110, 775}, 2}, {{78, 803}, 2}, {{110, 803}, 2}, {{78, 817}, 2}, {{110, 817}, 2}, {{78, 813}, 2}, {{110, 813}, 2}, {{79, 771, 769}, 3}, {{111, 771, 769}, 3}, {{79, 771, 776}, 3}, {{111, 771, 776}, 3}, {{79, 772, 768}, 3}, {{111, 772, 768}, 3}, {{79, 772, 769}, 3}, {{111, 772, 769}, 3}, {{80, 769}, 2}, {{112, 769}, 2}, {{80, 775}, 2}, {{112, 775}, 2}, {{82, 775}, 2}, {{114, 775}, 2}, {{82, 803}, 2}, {{114, 803}, 2}, {{82, 803, 772}, 3}, {{114, 803, 772}, 3}, {{82, 817}, 2}, {{114, 817}, 2}, {{83, 775}, 2}, {{115, 775}, 2}, {{83, 803}, 2}, {{115, 803}, 2}, {{83, 769, 775}, 3}, {{115, 769, 775}, 3}, {{83, 780, 775}, 3}, {{115, 780, 775}, 3}, {{83, 803, 775}, 3}, {{115, 803, 775}, 3}, {{84, 775}, 2}, {{116, 775}, 2}, {{84, 803}, 2}, {{116, 803}, 2}, {{84, 817}, 2}, {{116, 817}, 2}, {{84, 813}, 2}, {{116, 813}, 2}, {{85, 804}, 2}, {{117, 804}, 2}, {{85, 816}, 2}, {{117, 816}, 2}, {{85, 813}, 2}, {{117, 813}, 2}, {{85, 771, 769}, 3}, {{117, 771, 769}, 3}, {{85, 772, 776}, 3}, {{117, 772, 776}, 3}, {{86, 771}, 2}, {{118, 771}, 2}, {{86, 803}, 2}, {{118, 803}, 2}, {{87, 768}, 2}, {{119, 768}, 2}, {{87, 769}, 2}, {{119, 769}, 2}, {{87, 776}, 2}, {{119, 776}, 2}, {{87, 775}, 2}, {{119, 775}, 2}, {{87, 803}, 2}, {{119, 803}, 2}, {{88, 775}, 2}, {{120, 775}, 2}, {{88, 776}, 2}, {{120, 776}, 2}, {{89, 775}, 2}, {{121, 775}, 2}, {{90, 770}, 2}, {{122, 770}, 2}, {{90, 803}, 2}, {{122, 803}, 2}, {{90, 817}, 2}, {{122, 817}, 2}, {{104, 817}, 2}, {{116, 776}, 2}, {{119, 778}, 2}, {{121, 778}, 2}, {{383, 775}, 2}, {{65, 803}, 2}, {{97, 803}, 2}, {{65, 777}, 2}, {{97, 777}, 2}, {{65, 770, 769}, 3}, {{97, 770, 769}, 3}, {{65, 770, 768}, 3}, {{97, 770, 768}, 3}, {{65, 770, 777}, 3}, {{97, 770, 777}, 3}, {{65, 770, 771}, 3}, {{97, 770, 771}, 3}, {{65, 803, 770}, 3}, {{97, 803, 770}, 3}, {{65, 774, 769}, 3}, {{97, 774, 769}, 3}, {{65, 774, 768}, 3}, {{97, 774, 768}, 3}, {{65, 774, 777}, 3}, {{97, 774, 777}, 3}, {{65, 774, 771}, 3}, {{97, 774, 771}, 3}, {{65, 803, 774}, 3}, {{97, 803, 774}, 3}, {{69, 803}, 2}, {{101, 803}, 2}, {{69, 777}, 2}, {{101, 777}, 2}, {{69, 771}, 2}, {{101, 771}, 2}, {{69, 770, 769}, 3}, {{101, 770, 769}, 3}, {{69, 770, 768}, 3}, {{101, 770, 768}, 3}, {{69, 770, 777}, 3}, {{101, 770, 777}, 3}, {{69, 770, 771}, 3}, {{101, 770, 771}, 3}, {{69, 803, 770}, 3}, {{101, 803, 770}, 3}, {{73, 777}, 2}, {{105, 777}, 2}, {{73, 803}, 2}, {{105, 803}, 2}, {{79, 803}, 2}, {{111, 803}, 2}, {{79, 777}, 2}, {{111, 777}, 2}, {{79, 770, 769}, 3}, {{111, 770, 769}, 3}, {{79, 770, 768}, 3}, {{111, 770, 768}, 3}, {{79, 770, 777}, 3}, {{111, 770, 777}, 3}, {{79, 770, 771}, 3}, {{111, 770, 771}, 3}, {{79, 803, 770}, 3}, {{111, 803, 770}, 3}, {{79, 795, 769}, 3}, {{111, 795, 769}, 3}, {{79, 795, 768}, 3}, {{111, 795, 768}, 3}, {{79, 795, 777}, 3}, {{111, 795, 777}, 3}, {{79, 795, 771}, 3}, {{111, 795, 771}, 3}, {{79, 795, 803}, 3}, {{111, 795, 803}, 3}, {{85, 803}, 2}, {{117, 803}, 2}, {{85, 777}, 2}, {{117, 777}, 2}, {{85, 795, 769}, 3}, {{117, 795, 769}, 3}, {{85, 795, 768}, 3}, {{117, 795, 768}, 3}, {{85, 795, 777}, 3}, {{117, 795, 777}, 3}, {{85, 795, 771}, 3}, {{117, 795, 771}, 3}, {{85, 795, 803}, 3}, {{117, 795, 803}, 3}, {{89, 768}, 2}, {{121, 768}, 2}, {{89, 803}, 2}, {{121, 803}, 2}, {{89, 777}, 2}, {{121, 777}, 2}, {{89, 771}, 2}, {{121, 771}, 2}, {{945, 787}, 2}, {{945, 788}, 2}, {{945, 787, 768}, 3}, {{945, 788, 768}, 3}, {{945, 787, 769}, 3}, {{945, 788, 769}, 3}, {{945, 787, 834}, 3}, {{945, 788, 834}, 3}, {{913, 787}, 2}, {{913, 788}, 2}, {{913, 787, 768}, 3}, {{913, 788, 768}, 3}, {{913, 787, 769}, 3}, {{913, 788, 769}, 3}, {{913, 787, 834}, 3}, {{913, 788, 834}, 3}, {{949, 787}, 2}, {{949, 788}, 2}, {{949, 787, 768}, 3}, {{949, 788, 768}, 3}, {{949, 787, 769}, 3}, {{949, 788, 769}, 3}, {{917, 787}, 2}, {{917, 788}, 2}, {{917, 787, 768}, 3}, {{917, 788, 768}, 3}, {{917, 787, 769}, 3}, {{917, 788, 769}, 3}, {{951, 787}, 2}, {{951, 788}, 2}, {{951, 787, 768}, 3}, {{951, 788, 768}, 3}, {{951, 787, 769}, 3}, {{951, 788, 769}, 3}, {{951, 787, 834}, 3}, {{951, 788, 834}, 3}, {{919, 787}, 2}, {{919, 788}, 2}, {{919, 787, 768}, 3}, {{919, 788, 768}, 3}, {{919, 787, 769}, 3}, {{919, 788, 769}, 3}, {{919, 787, 834}, 3}, {{919, 788, 834}, 3}, {{953, 787}, 2}, {{953, 788}, 2}, {{953, 787, 768}, 3}, {{953, 788, 768}, 3}, {{953, 787, 769}, 3}, {{953, 788, 769}, 3}, {{953, 787, 834}, 3}, {{953, 788, 834}, 3}, {{921, 787}, 2}, {{921, 788}, 2}, {{921, 787, 768}, 3}, {{921, 788, 768}, 3}, {{921, 787, 769}, 3}, {{921, 788, 769}, 3}, {{921, 787, 834}, 3}, {{921, 788, 834}, 3}, {{959, 787}, 2}, {{959, 788}, 2}, {{959, 787, 768}, 3}, {{959, 788, 768}, 3}, {{959, 787, 769}, 3}, {{959, 788, 769}, 3}, {{927, 787}, 2}, {{927, 788}, 2}, {{927, 787, 768}, 3}, {{927, 788, 768}, 3}, {{927, 787, 769}, 3}, {{927, 788, 769}, 3}, {{965, 787}, 2}, {{965, 788}, 2}, {{965, 787, 768}, 3}, {{965, 788, 768}, 3}, {{965, 787, 769}, 3}, {{965, 788, 769}, 3}, {{965, 787, 834}, 3}, {{965, 788, 834}, 3}, {{933, 788}, 2}, {{933, 788, 768}, 3}, {{933, 788, 769}, 3}, {{933, 788, 834}, 3}, {{969, 787}, 2}, {{969, 788}, 2}, {{969, 787, 768}, 3}, {{969, 788, 768}, 3}, {{969, 787, 769}, 3}, {{969, 788, 769}, 3}, {{969, 787, 834}, 3}, {{969, 788, 834}, 3}, {{937, 787}, 2}, {{937, 788}, 2}, {{937, 787, 768}, 3}, {{937, 788, 768}, 3}, {{937, 787, 769}, 3}, {{937, 788, 769}, 3}, {{937, 787, 834}, 3}, {{937, 788, 834}, 3}, {{945, 768}, 2}, {{945, 769}, 2}, {{949, 768}, 2}, {{949, 769}, 2}, {{951, 768}, 2}, {{951, 769}, 2}, {{953, 768}, 2}, {{953, 769}, 2}, {{959, 768}, 2}, {{959, 769}, 2}, {{965, 768}, 2}, {{965, 769}, 2}, {{969, 768}, 2}, {{969, 769}, 2}, {{945, 787, 837}, 3}, {{945, 788, 837}, 3}, {{945, 787, 768, 837}, 4}, {{945, 788, 768, 837}, 4}, {{945, 787, 769, 837}, 4}, {{945, 788, 769, 837}, 4}, {{945, 787, 834, 837}, 4}, {{945, 788, 834, 837}, 4}, {{913, 787, 837}, 3}, {{913, 788, 837}, 3}, {{913, 787, 768, 837}, 4}, {{913, 788, 768, 837}, 4}, {{913, 787, 769, 837}, 4}, {{913, 788, 769, 837}, 4}, {{913, 787, 834, 837}, 4}, {{913, 788, 834, 837}, 4}, {{951, 787, 837}, 3}, {{951, 788, 837}, 3}, {{951, 787, 768, 837}, 4}, {{951, 788, 768, 837}, 4}, {{951, 787, 769, 837}, 4}, {{951, 788, 769, 837}, 4}, {{951, 787, 834, 837}, 4}, {{951, 788, 834, 837}, 4}, {{919, 787, 837}, 3}, {{919, 788, 837}, 3}, {{919, 787, 768, 837}, 4}, {{919, 788, 768, 837}, 4}, {{919, 787, 769, 837}, 4}, {{919, 788, 769, 837}, 4}, {{919, 787, 834, 837}, 4}, {{919, 788, 834, 837}, 4}, {{969, 787, 837}, 3}, {{969, 788, 837}, 3}, {{969, 787, 768, 837}, 4}, {{969, 788, 768, 837}, 4}, {{969, 787, 769, 837}, 4}, {{969, 788, 769, 837}, 4}, {{969, 787, 834, 837}, 4}, {{969, 788, 834, 837}, 4}, {{937, 787, 837}, 3}, {{937, 788, 837}, 3}, {{937, 787, 768, 837}, 4}, {{937, 788, 768, 837}, 4}, {{937, 787, 769, 837}, 4}, {{937, 788, 769, 837}, 4}, {{937, 787, 834, 837}, 4}, {{937, 788, 834, 837}, 4}, {{945, 774}, 2}, {{945, 772}, 2}, {{945, 768, 837}, 3}, {{945, 837}, 2}, {{945, 769, 837}, 3}, {{945, 834}, 2}, {{945, 834, 837}, 3}, {{913, 774}, 2}, {{913, 772}, 2}, {{913, 768}, 2}, {{913, 769}, 2}, {{913, 837}, 2}, {{953}, 1}, {{168, 834}, 2}, {{951, 768, 837}, 3}, {{951, 837}, 2}, {{951, 769, 837}, 3}, {{951, 834}, 2}, {{951, 834, 837}, 3}, {{917, 768}, 2}, {{917, 769}, 2}, {{919, 768}, 2}, {{919, 769}, 2}, {{919, 837}, 2}, {{8127, 768}, 2}, {{8127, 769}, 2}, {{8127, 834}, 2}, {{953, 774}, 2}, {{953, 772}, 2}, {{953, 776, 768}, 3}, {{953, 776, 769}, 3}, {{953, 834}, 2}, {{953, 776, 834}, 3}, {{921, 774}, 2}, {{921, 772}, 2}, {{921, 768}, 2}, {{921, 769}, 2}, {{8190, 768}, 2}, {{8190, 769}, 2}, {{8190, 834}, 2}, {{965, 774}, 2}, {{965, 772}, 2}, {{965, 776, 768}, 3}, {{965, 776, 769}, 3}, {{961, 787}, 2}, {{961, 788}, 2}, {{965, 834}, 2}, {{965, 776, 834}, 3}, {{933, 774}, 2}, {{933, 772}, 2}, {{933, 768}, 2}, {{933, 769}, 2}, {{929, 788}, 2}, {{168, 768}, 2}, {{168, 769}, 2}, {{96}, 1}, {{969, 768, 837}, 3}, {{969, 837}, 2}, {{969, 769, 837}, 3}, {{969, 834}, 2}, {{969, 834, 837}, 3}, {{927, 768}, 2}, {{927, 769}, 2}, {{937, 768}, 2}, {{937, 769}, 2}, {{937, 837}, 2}, {{180}, 1}, {{8194}, 1}, {{8195}, 1}, {{937}, 1}, {{75}, 1}, {{65, 778}, 2}, {{8592, 824}, 2}, {{8594, 824}, 2}, {{8596, 824}, 2}, {{8656, 824}, 2}, {{8660, 824}, 2}, {{8658, 824}, 2}, {{8707, 824}, 2}, {{8712, 824}, 2}, {{8715, 824}, 2}, {{8739, 824}, 2}, {{8741, 824}, 2}, {{8764, 824}, 2}, {{8771, 824}, 2}, {{8773, 824}, 2}, {{8776, 824}, 2}, {{61, 824}, 2}, {{8801, 824}, 2}, {{8781, 824}, 2}, {{60, 824}, 2}, {{62, 824}, 2}, {{8804, 824}, 2}, {{8805, 824}, 2}, {{8818, 824}, 2}, {{8819, 824}, 2}, {{8822, 824}, 2}, {{8823, 824}, 2}, {{8826, 824}, 2}, {{8827, 824}, 2}, {{8834, 824}, 2}, {{8835, 824}, 2}, {{8838, 824}, 2}, {{8839, 824}, 2}, {{8866, 824}, 2}, {{8872, 824}, 2}, {{8873, 824}, 2}, {{8875, 824}, 2}, {{8828, 824}, 2}, {{8829, 824}, 2}, {{8849, 824}, 2}, {{8850, 824}, 2}, {{8882, 824}, 2}, {{8883, 824}, 2}, {{8884, 824}, 2}, {{8885, 824}, 2}, {{12296}, 1}, {{12297}, 1}, {{10973, 824}, 2}, {{12363, 12441}, 2}, {{12365, 12441}, 2}, {{12367, 12441}, 2}, {{12369, 12441}, 2}, {{12371, 12441}, 2}, {{12373, 12441}, 2}, {{12375, 12441}, 2}, {{12377, 12441}, 2}, {{12379, 12441}, 2}, {{12381, 12441}, 2}, {{12383, 12441}, 2}, {{12385, 12441}, 2}, {{12388, 12441}, 2}, {{12390, 12441}, 2}, {{12392, 12441}, 2}, {{12399, 12441}, 2}, {{12399, 12442}, 2}, {{12402, 12441}, 2}, {{12402, 12442}, 2}, {{12405, 12441}, 2}, {{12405, 12442}, 2}, {{12408, 12441}, 2}, {{12408, 12442}, 2}, {{12411, 12441}, 2}, {{12411, 12442}, 2}, {{12358, 12441}, 2}, {{12445, 12441}, 2}, {{12459, 12441}, 2}, {{12461, 12441}, 2}, {{12463, 12441}, 2}, {{12465, 12441}, 2}, {{12467, 12441}, 2}, {{12469, 12441}, 2}, {{12471, 12441}, 2}, {{12473, 12441}, 2}, {{12475, 12441}, 2}, {{12477, 12441}, 2}, {{12479, 12441}, 2}, {{12481, 12441}, 2}, {{12484, 12441}, 2}, {{12486, 12441}, 2}, {{12488, 12441}, 2}, {{12495, 12441}, 2}, {{12495, 12442}, 2}, {{12498, 12441}, 2}, {{12498, 12442}, 2}, {{12501, 12441}, 2}, {{12501, 12442}, 2}, {{12504, 12441}, 2}, {{12504, 12442}, 2}, {{12507, 12441}, 2}, {{12507, 12442}, 2}, {{12454, 12441}, 2}, {{12527, 12441}, 2}, {{12528, 12441}, 2}, {{12529, 12441}, 2}, {{12530, 12441}, 2}, {{12541, 12441}, 2}, {{35912}, 1}, {{26356}, 1}, {{36554}, 1}, {{36040}, 1}, {{28369}, 1}, {{20018}, 1}, {{21477}, 1}, {{40860}, 1}, {{40860}, 1}, {{22865}, 1}, {{37329}, 1}, {{21895}, 1}, {{22856}, 1}, {{25078}, 1}, {{30313}, 1}, {{32645}, 1}, {{34367}, 1}, {{34746}, 1}, {{35064}, 1}, {{37007}, 1}, {{27138}, 1}, {{27931}, 1}, {{28889}, 1}, {{29662}, 1}, {{33853}, 1}, {{37226}, 1}, {{39409}, 1}, {{20098}, 1}, {{21365}, 1}, {{27396}, 1}, {{29211}, 1}, {{34349}, 1}, {{40478}, 1}, {{23888}, 1}, {{28651}, 1}, {{34253}, 1}, {{35172}, 1}, {{25289}, 1}, {{33240}, 1}, {{34847}, 1}, {{24266}, 1}, {{26391}, 1}, {{28010}, 1}, {{29436}, 1}, {{37070}, 1}, {{20358}, 1}, {{20919}, 1}, {{21214}, 1}, {{25796}, 1}, {{27347}, 1}, {{29200}, 1}, {{30439}, 1}, {{32769}, 1}, {{34310}, 1}, {{34396}, 1}, {{36335}, 1}, {{38706}, 1}, {{39791}, 1}, {{40442}, 1}, {{30860}, 1}, {{31103}, 1}, {{32160}, 1}, {{33737}, 1}, {{37636}, 1}, {{40575}, 1}, {{35542}, 1}, {{22751}, 1}, {{24324}, 1}, {{31840}, 1}, {{32894}, 1}, {{29282}, 1}, {{30922}, 1}, {{36034}, 1}, {{38647}, 1}, {{22744}, 1}, {{23650}, 1}, {{27155}, 1}, {{28122}, 1}, {{28431}, 1}, {{32047}, 1}, {{32311}, 1}, {{38475}, 1}, {{21202}, 1}, {{32907}, 1}, {{20956}, 1}, {{20940}, 1}, {{31260}, 1}, {{32190}, 1}, {{33777}, 1}, {{38517}, 1}, {{35712}, 1}, {{25295}, 1}, {{27138}, 1}, {{35582}, 1}, {{20025}, 1}, {{23527}, 1}, {{24594}, 1}, {{29575}, 1}, {{30064}, 1}, {{21271}, 1}, {{30971}, 1}, {{20415}, 1}, {{24489}, 1}, {{19981}, 1}, {{27852}, 1}, {{25976}, 1}, {{32034}, 1}, {{21443}, 1}, {{22622}, 1}, {{30465}, 1}, {{33865}, 1}, {{35498}, 1}, {{27578}, 1}, {{36784}, 1}, {{27784}, 1}, {{25342}, 1}, {{33509}, 1}, {{25504}, 1}, {{30053}, 1}, {{20142}, 1}, {{20841}, 1}, {{20937}, 1}, {{26753}, 1}, {{31975}, 1}, {{33391}, 1}, {{35538}, 1}, {{37327}, 1}, {{21237}, 1}, {{21570}, 1}, {{22899}, 1}, {{24300}, 1}, {{26053}, 1}, {{28670}, 1}, {{31018}, 1}, {{38317}, 1}, {{39530}, 1}, {{40599}, 1}, {{40654}, 1}, {{21147}, 1}, {{26310}, 1}, {{27511}, 1}, {{36706}, 1}, {{24180}, 1}, {{24976}, 1}, {{25088}, 1}, {{25754}, 1}, {{28451}, 1}, {{29001}, 1}, {{29833}, 1}, {{31178}, 1}, {{32244}, 1}, {{32879}, 1}, {{36646}, 1}, {{34030}, 1}, {{36899}, 1}, {{37706}, 1}, {{21015}, 1}, {{21155}, 1}, {{21693}, 1}, {{28872}, 1}, {{35010}, 1}, {{35498}, 1}, {{24265}, 1}, {{24565}, 1}, {{25467}, 1}, {{27566}, 1}, {{31806}, 1}, {{29557}, 1}, {{20196}, 1}, {{22265}, 1}, {{23527}, 1}, {{23994}, 1}, {{24604}, 1}, {{29618}, 1}, {{29801}, 1}, {{32666}, 1}, {{32838}, 1}, {{37428}, 1}, {{38646}, 1}, {{38728}, 1}, {{38936}, 1}, {{20363}, 1}, {{31150}, 1}, {{37300}, 1}, {{38584}, 1}, {{24801}, 1}, {{20102}, 1}, {{20698}, 1}, {{23534}, 1}, {{23615}, 1}, {{26009}, 1}, {{27138}, 1}, {{29134}, 1}, {{30274}, 1}, {{34044}, 1}, {{36988}, 1}, {{40845}, 1}, {{26248}, 1}, {{38446}, 1}, {{21129}, 1}, {{26491}, 1}, {{26611}, 1}, {{27969}, 1}, {{28316}, 1}, {{29705}, 1}, {{30041}, 1}, {{30827}, 1}, {{32016}, 1}, {{39006}, 1}, {{20845}, 1}, {{25134}, 1}, {{38520}, 1}, {{20523}, 1}, {{23833}, 1}, {{28138}, 1}, {{36650}, 1}, {{24459}, 1}, {{24900}, 1}, {{26647}, 1}, {{29575}, 1}, {{38534}, 1}, {{21033}, 1}, {{21519}, 1}, {{23653}, 1}, {{26131}, 1}, {{26446}, 1}, {{26792}, 1}, {{27877}, 1}, {{29702}, 1}, {{30178}, 1}, {{32633}, 1}, {{35023}, 1}, {{35041}, 1}, {{37324}, 1}, {{38626}, 1}, {{21311}, 1}, {{28346}, 1}, {{21533}, 1}, {{29136}, 1}, {{29848}, 1}, {{34298}, 1}, {{38563}, 1}, {{40023}, 1}, {{40607}, 1}, {{26519}, 1}, {{28107}, 1}, {{33256}, 1}, {{31435}, 1}, {{31520}, 1}, {{31890}, 1}, {{29376}, 1}, {{28825}, 1}, {{35672}, 1}, {{20160}, 1}, {{33590}, 1}, {{21050}, 1}, {{20999}, 1}, {{24230}, 1}, {{25299}, 1}, {{31958}, 1}, {{23429}, 1}, {{27934}, 1}, {{26292}, 1}, {{36667}, 1}, {{34892}, 1}, {{38477}, 1}, {{35211}, 1}, {{24275}, 1}, {{20800}, 1}, {{21952}, 1}, {{22618}, 1}, {{26228}, 1}, {{20958}, 1}, {{29482}, 1}, {{30410}, 1}, {{31036}, 1}, {{31070}, 1}, {{31077}, 1}, {{31119}, 1}, {{38742}, 1}, {{31934}, 1}, {{32701}, 1}, {{34322}, 1}, {{35576}, 1}, {{36920}, 1}, {{37117}, 1}, {{39151}, 1}, {{39164}, 1}, {{39208}, 1}, {{40372}, 1}, {{20398}, 1}, {{20711}, 1}, {{20813}, 1}, {{21193}, 1}, {{21220}, 1}, {{21329}, 1}, {{21917}, 1}, {{22022}, 1}, {{22120}, 1}, {{22592}, 1}, {{22696}, 1}, {{23652}, 1}, {{23662}, 1}, {{24724}, 1}, {{24936}, 1}, {{24974}, 1}, {{25074}, 1}, {{25935}, 1}, {{26082}, 1}, {{26257}, 1}, {{26757}, 1}, {{28023}, 1}, {{28186}, 1}, {{28450}, 1}, {{29038}, 1}, {{29227}, 1}, {{29730}, 1}, {{30865}, 1}, {{31038}, 1}, {{31049}, 1}, {{31048}, 1}, {{31056}, 1}, {{31062}, 1}, {{31069}, 1}, {{31117}, 1}, {{31118}, 1}, {{31296}, 1}, {{31361}, 1}, {{31680}, 1}, {{32244}, 1}, {{32265}, 1}, {{32321}, 1}, {{32626}, 1}, {{32773}, 1}, {{33261}, 1}, {{33401}, 1}, {{33401}, 1}, {{33879}, 1}, {{35088}, 1}, {{35222}, 1}, {{35585}, 1}, {{35641}, 1}, {{36051}, 1}, {{36104}, 1}, {{36790}, 1}, {{36920}, 1}, {{38627}, 1}, {{38911}, 1}, {{38971}, 1}, {{20006}, 1}, {{20917}, 1}, {{20840}, 1}, {{20352}, 1}, {{20805}, 1}, {{20864}, 1}, {{21191}, 1}, {{21242}, 1}, {{21917}, 1}, {{21845}, 1}, {{21913}, 1}, {{21986}, 1}, {{22618}, 1}, {{22707}, 1}, {{22852}, 1}, {{22868}, 1}, {{23138}, 1}, {{23336}, 1}, {{24274}, 1}, {{24281}, 1}, {{24425}, 1}, {{24493}, 1}, {{24792}, 1}, {{24910}, 1}, {{24840}, 1}, {{24974}, 1}, {{24928}, 1}, {{25074}, 1}, {{25140}, 1}, {{25540}, 1}, {{25628}, 1}, {{25682}, 1}, {{25942}, 1}, {{26228}, 1}, {{26391}, 1}, {{26395}, 1}, {{26454}, 1}, {{27513}, 1}, {{27578}, 1}, {{27969}, 1}, {{28379}, 1}, {{28363}, 1}, {{28450}, 1}, {{28702}, 1}, {{29038}, 1}, {{30631}, 1}, {{29237}, 1}, {{29359}, 1}, {{29482}, 1}, {{29809}, 1}, {{29958}, 1}, {{30011}, 1}, {{30237}, 1}, {{30239}, 1}, {{30410}, 1}, {{30427}, 1}, {{30452}, 1}, {{30538}, 1}, {{30528}, 1}, {{30924}, 1}, {{31409}, 1}, {{31680}, 1}, {{31867}, 1}, {{32091}, 1}, {{32244}, 1}, {{32574}, 1}, {{32773}, 1}, {{33618}, 1}, {{33775}, 1}, {{34681}, 1}, {{35137}, 1}, {{35206}, 1}, {{35222}, 1}, {{35519}, 1}, {{35576}, 1}, {{35531}, 1}, {{35585}, 1}, {{35582}, 1}, {{35565}, 1}, {{35641}, 1}, {{35722}, 1}, {{36104}, 1}, {{36664}, 1}, {{36978}, 1}, {{37273}, 1}, {{37494}, 1}, {{38524}, 1}, {{38627}, 1}, {{38742}, 1}, {{38875}, 1}, {{38911}, 1}, {{38923}, 1}, {{38971}, 1}, {{39698}, 1}, {{40860}, 1}, {{141386}, 1}, {{141380}, 1}, {{144341}, 1}, {{15261}, 1}, {{16408}, 1}, {{16441}, 1}, {{152137}, 1}, {{154832}, 1}, {{163539}, 1}, {{40771}, 1}, {{40846}, 1}, {{1497, 1460}, 2}, {{1522, 1463}, 2}, {{1513, 1473}, 2}, {{1513, 1474}, 2}, {{1513, 1468, 1473}, 3}, {{1513, 1468, 1474}, 3}, {{1488, 1463}, 2}, {{1488, 1464}, 2}, {{1488, 1468}, 2}, {{1489, 1468}, 2}, {{1490, 1468}, 2}, {{1491, 1468}, 2}, {{1492, 1468}, 2}, {{1493, 1468}, 2}, {{1494, 1468}, 2}, {{1496, 1468}, 2}, {{1497, 1468}, 2}, {{1498, 1468}, 2}, {{1499, 1468}, 2}, {{1500, 1468}, 2}, {{1502, 1468}, 2}, {{1504, 1468}, 2}, {{1505, 1468}, 2}, {{1507, 1468}, 2}, {{1508, 1468}, 2}, {{1510, 1468}, 2}, {{1511, 1468}, 2}, {{1512, 1468}, 2}, {{1513, 1468}, 2}, {{1514, 1468}, 2}, {{1493, 1465}, 2}, {{1489, 1471}, 2}, {{1499, 1471}, 2}, {{1508, 1471}, 2}, {{119127, 119141}, 2}, {{119128, 119141}, 2}, {{119128, 119141, 119150}, 3}, {{119128, 119141, 119151}, 3}, {{119128, 119141, 119152}, 3}, {{119128, 119141, 119153}, 3}, {{119128, 119141, 119154}, 3}, {{119225, 119141}, 2}, {{119226, 119141}, 2}, {{119225, 119141, 119150}, 3}, {{119226, 119141, 119150}, 3}, {{119225, 119141, 119151}, 3}, {{119226, 119141, 119151}, 3}, {{20029}, 1}, {{20024}, 1}, {{20033}, 1}, {{131362}, 1}, {{20320}, 1}, {{20398}, 1}, {{20411}, 1}, {{20482}, 1}, {{20602}, 1}, {{20633}, 1}, {{20711}, 1}, {{20687}, 1}, {{13470}, 1}, {{132666}, 1}, {{20813}, 1}, {{20820}, 1}, {{20836}, 1}, {{20855}, 1}, {{132380}, 1}, {{13497}, 1}, {{20839}, 1}, {{20877}, 1}, {{132427}, 1}, {{20887}, 1}, {{20900}, 1}, {{20172}, 1}, {{20908}, 1}, {{20917}, 1}, {{168415}, 1}, {{20981}, 1}, {{20995}, 1}, {{13535}, 1}, {{21051}, 1}, {{21062}, 1}, {{21106}, 1}, {{21111}, 1}, {{13589}, 1}, {{21191}, 1}, {{21193}, 1}, {{21220}, 1}, {{21242}, 1}, {{21253}, 1}, {{21254}, 1}, {{21271}, 1}, {{21321}, 1}, {{21329}, 1}, {{21338}, 1}, {{21363}, 1}, {{21373}, 1}, {{21375}, 1}, {{21375}, 1}, {{21375}, 1}, {{133676}, 1}, {{28784}, 1}, {{21450}, 1}, {{21471}, 1}, {{133987}, 1}, {{21483}, 1}, {{21489}, 1}, {{21510}, 1}, {{21662}, 1}, {{21560}, 1}, {{21576}, 1}, {{21608}, 1}, {{21666}, 1}, {{21750}, 1}, {{21776}, 1}, {{21843}, 1}, {{21859}, 1}, {{21892}, 1}, {{21892}, 1}, {{21913}, 1}, {{21931}, 1}, {{21939}, 1}, {{21954}, 1}, {{22294}, 1}, {{22022}, 1}, {{22295}, 1}, {{22097}, 1}, {{22132}, 1}, {{20999}, 1}, {{22766}, 1}, {{22478}, 1}, {{22516}, 1}, {{22541}, 1}, {{22411}, 1}, {{22578}, 1}, {{22577}, 1}, {{22700}, 1}, {{136420}, 1}, {{22770}, 1}, {{22775}, 1}, {{22790}, 1}, {{22810}, 1}, {{22818}, 1}, {{22882}, 1}, {{136872}, 1}, {{136938}, 1}, {{23020}, 1}, {{23067}, 1}, {{23079}, 1}, {{23000}, 1}, {{23142}, 1}, {{14062}, 1}, {{14076}, 1}, {{23304}, 1}, {{23358}, 1}, {{23358}, 1}, {{137672}, 1}, {{23491}, 1}, {{23512}, 1}, {{23527}, 1}, {{23539}, 1}, {{138008}, 1}, {{23551}, 1}, {{23558}, 1}, {{24403}, 1}, {{23586}, 1}, {{14209}, 1}, {{23648}, 1}, {{23662}, 1}, {{23744}, 1}, {{23693}, 1}, {{138724}, 1}, {{23875}, 1}, {{138726}, 1}, {{23918}, 1}, {{23915}, 1}, {{23932}, 1}, {{24033}, 1}, {{24034}, 1}, {{14383}, 1}, {{24061}, 1}, {{24104}, 1}, {{24125}, 1}, {{24169}, 1}, {{14434}, 1}, {{139651}, 1}, {{14460}, 1}, {{24240}, 1}, {{24243}, 1}, {{24246}, 1}, {{24266}, 1}, {{172946}, 1}, {{24318}, 1}, {{140081}, 1}, {{140081}, 1}, {{33281}, 1}, {{24354}, 1}, {{24354}, 1}, {{14535}, 1}, {{144056}, 1}, {{156122}, 1}, {{24418}, 1}, {{24427}, 1}, {{14563}, 1}, {{24474}, 1}, {{24525}, 1}, {{24535}, 1}, {{24569}, 1}, {{24705}, 1}, {{14650}, 1}, {{14620}, 1}, {{24724}, 1}, {{141012}, 1}, {{24775}, 1}, {{24904}, 1}, {{24908}, 1}, {{24910}, 1}, {{24908}, 1}, {{24954}, 1}, {{24974}, 1}, {{25010}, 1}, {{24996}, 1}, {{25007}, 1}, {{25054}, 1}, {{25074}, 1}, {{25078}, 1}, {{25104}, 1}, {{25115}, 1}, {{25181}, 1}, {{25265}, 1}, {{25300}, 1}, {{25424}, 1}, {{142092}, 1}, {{25405}, 1}, {{25340}, 1}, {{25448}, 1}, {{25475}, 1}, {{25572}, 1}, {{142321}, 1}, {{25634}, 1}, {{25541}, 1}, {{25513}, 1}, {{14894}, 1}, {{25705}, 1}, {{25726}, 1}, {{25757}, 1}, {{25719}, 1}, {{14956}, 1}, {{25935}, 1}, {{25964}, 1}, {{143370}, 1}, {{26083}, 1}, {{26360}, 1}, {{26185}, 1}, {{15129}, 1}, {{26257}, 1}, {{15112}, 1}, {{15076}, 1}, {{20882}, 1}, {{20885}, 1}, {{26368}, 1}, {{26268}, 1}, {{32941}, 1}, {{17369}, 1}, {{26391}, 1}, {{26395}, 1}, {{26401}, 1}, {{26462}, 1}, {{26451}, 1}, {{144323}, 1}, {{15177}, 1}, {{26618}, 1}, {{26501}, 1}, {{26706}, 1}, {{26757}, 1}, {{144493}, 1}, {{26766}, 1}, {{26655}, 1}, {{26900}, 1}, {{15261}, 1}, {{26946}, 1}, {{27043}, 1}, {{27114}, 1}, {{27304}, 1}, {{145059}, 1}, {{27355}, 1}, {{15384}, 1}, {{27425}, 1}, {{145575}, 1}, {{27476}, 1}, {{15438}, 1}, {{27506}, 1}, {{27551}, 1}, {{27578}, 1}, {{27579}, 1}, {{146061}, 1}, {{138507}, 1}, {{146170}, 1}, {{27726}, 1}, {{146620}, 1}, {{27839}, 1}, {{27853}, 1}, {{27751}, 1}, {{27926}, 1}, {{27966}, 1}, {{28023}, 1}, {{27969}, 1}, {{28009}, 1}, {{28024}, 1}, {{28037}, 1}, {{146718}, 1}, {{27956}, 1}, {{28207}, 1}, {{28270}, 1}, {{15667}, 1}, {{28363}, 1}, {{28359}, 1}, {{147153}, 1}, {{28153}, 1}, {{28526}, 1}, {{147294}, 1}, {{147342}, 1}, {{28614}, 1}, {{28729}, 1}, {{28702}, 1}, {{28699}, 1}, {{15766}, 1}, {{28746}, 1}, {{28797}, 1}, {{28791}, 1}, {{28845}, 1}, {{132389}, 1}, {{28997}, 1}, {{148067}, 1}, {{29084}, 1}, {{148395}, 1}, {{29224}, 1}, {{29237}, 1}, {{29264}, 1}, {{149000}, 1}, {{29312}, 1}, {{29333}, 1}, {{149301}, 1}, {{149524}, 1}, {{29562}, 1}, {{29579}, 1}, {{16044}, 1}, {{29605}, 1}, {{16056}, 1}, {{16056}, 1}, {{29767}, 1}, {{29788}, 1}, {{29809}, 1}, {{29829}, 1}, {{29898}, 1}, {{16155}, 1}, {{29988}, 1}, {{150582}, 1}, {{30014}, 1}, {{150674}, 1}, {{30064}, 1}, {{139679}, 1}, {{30224}, 1}, {{151457}, 1}, {{151480}, 1}, {{151620}, 1}, {{16380}, 1}, {{16392}, 1}, {{30452}, 1}, {{151795}, 1}, {{151794}, 1}, {{151833}, 1}, {{151859}, 1}, {{30494}, 1}, {{30495}, 1}, {{30495}, 1}, {{30538}, 1}, {{16441}, 1}, {{30603}, 1}, {{16454}, 1}, {{16534}, 1}, {{152605}, 1}, {{30798}, 1}, {{30860}, 1}, {{30924}, 1}, {{16611}, 1}, {{153126}, 1}, {{31062}, 1}, {{153242}, 1}, {{153285}, 1}, {{31119}, 1}, {{31211}, 1}, {{16687}, 1}, {{31296}, 1}, {{31306}, 1}, {{31311}, 1}, {{153980}, 1}, {{154279}, 1}, {{154279}, 1}, {{31470}, 1}, {{16898}, 1}, {{154539}, 1}, {{31686}, 1}, {{31689}, 1}, {{16935}, 1}, {{154752}, 1}, {{31954}, 1}, {{17056}, 1}, {{31976}, 1}, {{31971}, 1}, {{32000}, 1}, {{155526}, 1}, {{32099}, 1}, {{17153}, 1}, {{32199}, 1}, {{32258}, 1}, {{32325}, 1}, {{17204}, 1}, {{156200}, 1}, {{156231}, 1}, {{17241}, 1}, {{156377}, 1}, {{32634}, 1}, {{156478}, 1}, {{32661}, 1}, {{32762}, 1}, {{32773}, 1}, {{156890}, 1}, {{156963}, 1}, {{32864}, 1}, {{157096}, 1}, {{32880}, 1}, {{144223}, 1}, {{17365}, 1}, {{32946}, 1}, {{33027}, 1}, {{17419}, 1}, {{33086}, 1}, {{23221}, 1}, {{157607}, 1}, {{157621}, 1}, {{144275}, 1}, {{144284}, 1}, {{33281}, 1}, {{33284}, 1}, {{36766}, 1}, {{17515}, 1}, {{33425}, 1}, {{33419}, 1}, {{33437}, 1}, {{21171}, 1}, {{33457}, 1}, {{33459}, 1}, {{33469}, 1}, {{33510}, 1}, {{158524}, 1}, {{33509}, 1}, {{33565}, 1}, {{33635}, 1}, {{33709}, 1}, {{33571}, 1}, {{33725}, 1}, {{33767}, 1}, {{33879}, 1}, {{33619}, 1}, {{33738}, 1}, {{33740}, 1}, {{33756}, 1}, {{158774}, 1}, {{159083}, 1}, {{158933}, 1}, {{17707}, 1}, {{34033}, 1}, {{34035}, 1}, {{34070}, 1}, {{160714}, 1}, {{34148}, 1}, {{159532}, 1}, {{17757}, 1}, {{17761}, 1}, {{159665}, 1}, {{159954}, 1}, {{17771}, 1}, {{34384}, 1}, {{34396}, 1}, {{34407}, 1}, {{34409}, 1}, {{34473}, 1}, {{34440}, 1}, {{34574}, 1}, {{34530}, 1}, {{34681}, 1}, {{34600}, 1}, {{34667}, 1}, {{34694}, 1}, {{17879}, 1}, {{34785}, 1}, {{34817}, 1}, {{17913}, 1}, {{34912}, 1}, {{34915}, 1}, {{161383}, 1}, {{35031}, 1}, {{35038}, 1}, {{17973}, 1}, {{35066}, 1}, {{13499}, 1}, {{161966}, 1}, {{162150}, 1}, {{18110}, 1}, {{18119}, 1}, {{35488}, 1}, {{35565}, 1}, {{35722}, 1}, {{35925}, 1}, {{162984}, 1}, {{36011}, 1}, {{36033}, 1}, {{36123}, 1}, {{36215}, 1}, {{163631}, 1}, {{133124}, 1}, {{36299}, 1}, {{36284}, 1}, {{36336}, 1}, {{133342}, 1}, {{36564}, 1}, {{36664}, 1}, {{165330}, 1}, {{165357}, 1}, {{37012}, 1}, {{37105}, 1}, {{37137}, 1}, {{165678}, 1}, {{37147}, 1}, {{37432}, 1}, {{37591}, 1}, {{37592}, 1}, {{37500}, 1}, {{37881}, 1}, {{37909}, 1}, {{166906}, 1}, {{38283}, 1}, {{18837}, 1}, {{38327}, 1}, {{167287}, 1}, {{18918}, 1}, {{38595}, 1}, {{23986}, 1}, {{38691}, 1}, {{168261}, 1}, {{168474}, 1}, {{19054}, 1}, {{19062}, 1}, {{38880}, 1}, {{168970}, 1}, {{19122}, 1}, {{169110}, 1}, {{38923}, 1}, {{38923}, 1}, {{38953}, 1}, {{169398}, 1}, {{39138}, 1}, {{19251}, 1}, {{39209}, 1}, {{39335}, 1}, {{39362}, 1}, {{39422}, 1}, {{19406}, 1}, {{170800}, 1}, {{39698}, 1}, {{40000}, 1}, {{40189}, 1}, {{19662}, 1}, {{19693}, 1}, {{40295}, 1}, {{172238}, 1}, {{19704}, 1}, {{172293}, 1}, {{172558}, 1}, {{172689}, 1}, {{40635}, 1}, {{19798}, 1}, {{40697}, 1}, {{40702}, 1}, {{40709}, 1}, {{40719}, 1}, {{40726}, 1}, {{40763}, 1}, {{173568}, 1} }; KInt getCanonicalClass(KInt ch) { int index = binarySearchRange(canonicalClassesKeys, ARRAY_SIZE(canonicalClassesKeys), ch); if (canonicalClassesKeys[index] != ch) { return 0; } return canonicalClassesValues[index]; } const Decomposition* getDecomposition(KInt codePoint) { int index = binarySearchRange(decompositionKeys, ARRAY_SIZE(decompositionKeys), codePoint); if (decompositionKeys[index] != codePoint) { return nullptr; } return &decompositionValues[index]; } } // namespace extern "C" { KInt Kotlin_text_regex_getCanonicalClassInternal(KInt ch) { return getCanonicalClass(ch); } KBoolean Kotlin_text_regex_hasSingleCodepointDecompositionInternal(KInt ch) { int index = binarySearchRange(singleDecompositions, ARRAY_SIZE(singleDecompositions), ch); return singleDecompositions[index] == ch; } OBJ_GETTER(Kotlin_text_regex_getDecompositionInternal, KInt ch) { const Decomposition* decomposition = getDecomposition(ch); if (decomposition == nullptr) { return nullptr; } ArrayHeader* result = AllocArrayInstance(theIntArrayTypeInfo, decomposition->length, OBJ_RESULT)->array(); KInt* resultRaw = IntArrayAddressOfElementAt(result, 0); for (int i = 0; i < decomposition->length; i++) { *resultRaw++ = decomposition->array[i]; } RETURN_OBJ(result->obj()); } KInt Kotlin_text_regex_decomposeString(ArrayHeader* inputCodePoints, KInt inputLength, ArrayHeader* outputCodePoints) { RuntimeAssert(inputCodePoints->type_info() == theIntArrayTypeInfo, "Must use an Int array"); RuntimeAssert(outputCodePoints->type_info() == theIntArrayTypeInfo, "Must use an Int array"); RuntimeAssert(inputLength >= 0, "Input length must be >= 0"); if (inputLength == 0) { return 0; } int outputLength = 0; const KInt* inputArray = IntArrayAddressOfElementAt(inputCodePoints, 0); KInt* outputArray = IntArrayAddressOfElementAt(outputCodePoints, 0); for (int i = 0; i < inputLength; i++) { const Decomposition* decomposition = getDecomposition(inputArray[i]); if (decomposition == nullptr) { outputArray[outputLength++] = inputArray[i]; } else { memcpy(outputArray + outputLength, decomposition->array, decomposition->length * sizeof(KInt)); outputLength+=decomposition->length; } } return outputLength; } KInt Kotlin_text_regex_decomposeCodePoint(KInt codePoint, ArrayHeader* outputCodePoints, KInt fromIndex) { RuntimeAssert(outputCodePoints->type_info() == theIntArrayTypeInfo, "Must be an Int array"); RuntimeAssert(fromIndex >= 0 && static_cast(fromIndex) < outputCodePoints->count_, "Start index must be >= 0 and < array size"); KInt* rawResult = IntArrayAddressOfElementAt(outputCodePoints, fromIndex); const Decomposition* decomposition = getDecomposition(codePoint); if (decomposition == nullptr) { *rawResult = codePoint; return 1; } else { memcpy(rawResult, decomposition->array, decomposition->length * sizeof(KInt)); return decomposition->length; } } } // extern "C" ================================================ FILE: runtime/src/main/cpp/ReturnSlot.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ReturnSlot.h" #ifdef KONAN_WASM namespace { THREAD_LOCAL_VARIABLE long long storage; } // namespace extern "C" { RUNTIME_USED KDouble ReturnSlot_getDouble() { return *reinterpret_cast(&::storage); } RUNTIME_USED void ReturnSlot_setDouble(KInt upper, KInt lower) { reinterpret_cast(&::storage)[0] = lower; reinterpret_cast(&::storage)[1] = upper; } } // extern "C" #endif // KONAN_WASM ================================================ FILE: runtime/src/main/cpp/ReturnSlot.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Types.h" #ifdef KONAN_WASM #ifdef __cplusplus extern "C" { #endif KDouble ReturnSlot_getDouble(); void ReturnSlot_setDouble(KInt upper, KInt lower); #ifdef __cplusplus } // extern "C" #endif #endif // KONAN_WASM ================================================ FILE: runtime/src/main/cpp/Runtime.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Alloc.h" #include "Atomic.h" #include "Cleaner.h" #include "Exceptions.h" #include "KAssert.h" #include "Memory.h" #include "ObjCExportInit.h" #include "Porting.h" #include "Runtime.h" #include "Worker.h" typedef void (*Initializer)(int initialize, MemoryState* memory); struct InitNode { Initializer init; InitNode* next; }; // This global is overriden by the compiler. RUNTIME_WEAK DestroyRuntimeMode Kotlin_destroyRuntimeMode = DESTROY_RUNTIME_ON_SHUTDOWN; DestroyRuntimeMode Kotlin_getDestroyRuntimeMode() { return Kotlin_destroyRuntimeMode; } namespace { InitNode* initHeadNode = nullptr; InitNode* initTailNode = nullptr; enum class RuntimeStatus { kUninitialized, kRunning, kDestroying, }; struct RuntimeState { MemoryState* memoryState; Worker* worker; RuntimeStatus status = RuntimeStatus::kUninitialized; }; // Must be synchronized with IrToBitcode.kt enum { ALLOC_THREAD_LOCAL_GLOBALS = 0, INIT_GLOBALS = 1, INIT_THREAD_LOCAL_GLOBALS = 2, DEINIT_GLOBALS = 3 }; void InitOrDeinitGlobalVariables(int initialize, MemoryState* memory) { InitNode* currentNode = initHeadNode; while (currentNode != nullptr) { currentNode->init(initialize, memory); currentNode = currentNode->next; } } KBoolean g_checkLeaks = false; KBoolean g_checkLeakedCleaners = false; KBoolean g_forceCheckedShutdown = false; constexpr RuntimeState* kInvalidRuntime = nullptr; THREAD_LOCAL_VARIABLE RuntimeState* runtimeState = kInvalidRuntime; inline bool isValidRuntime() { return ::runtimeState != kInvalidRuntime; } volatile int aliveRuntimesCount = 0; enum GlobalRuntimeStatus { kGlobalRuntimeUninitialized = 0, kGlobalRuntimeRunning, kGlobalRuntimeShutdown, }; volatile GlobalRuntimeStatus globalRuntimeStatus = kGlobalRuntimeUninitialized; RuntimeState* initRuntime() { SetKonanTerminateHandler(); RuntimeState* result = konanConstructInstance(); if (!result) return kInvalidRuntime; RuntimeCheck(!isValidRuntime(), "No active runtimes allowed"); ::runtimeState = result; bool firstRuntime = false; switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeUninitialized, kGlobalRuntimeRunning); result->memoryState = InitMemory(false); // The argument will be ignored for legacy DestroyRuntimeMode result->worker = WorkerInit(true); firstRuntime = atomicAdd(&aliveRuntimesCount, 1) == 1; if (CurrentMemoryModel == MemoryModel::kExperimental) { RuntimeCheck(firstRuntime, "Experimental MM does not support multiple mutator threads yet"); } break; case DESTROY_RUNTIME_ON_SHUTDOWN: // First update `aliveRuntimesCount` and then update `globalRuntimeStatus`, for synchronization with // runtime shutdown, which does it the other way around. atomicAdd(&aliveRuntimesCount, 1); auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeUninitialized, kGlobalRuntimeRunning); if (Kotlin_forceCheckedShutdown()) { RuntimeAssert(lastStatus != kGlobalRuntimeShutdown, "Kotlin runtime was shut down. Cannot create new runtimes."); } firstRuntime = lastStatus == kGlobalRuntimeUninitialized; if (CurrentMemoryModel == MemoryModel::kExperimental) { RuntimeCheck(firstRuntime, "Experimental MM does not support multiple mutator threads yet"); } result->memoryState = InitMemory(firstRuntime); result->worker = WorkerInit(true); } InitOrDeinitGlobalVariables(ALLOC_THREAD_LOCAL_GLOBALS, result->memoryState); CommitTLSStorage(result->memoryState); // Keep global variables in state as well. if (firstRuntime) { konan::consoleInit(); #if KONAN_OBJC_INTEROP Kotlin_ObjCExport_initialize(); #endif InitOrDeinitGlobalVariables(INIT_GLOBALS, result->memoryState); } InitOrDeinitGlobalVariables(INIT_THREAD_LOCAL_GLOBALS, result->memoryState); RuntimeAssert(result->status == RuntimeStatus::kUninitialized, "Runtime must still be in the uninitialized state"); result->status = RuntimeStatus::kRunning; return result; } void deinitRuntime(RuntimeState* state, bool destroyRuntime) { RuntimeAssert(state->status == RuntimeStatus::kRunning, "Runtime must be in the running state"); state->status = RuntimeStatus::kDestroying; // This may be called after TLS is zeroed out, so ::runtimeState and ::memoryState in Memory cannot be trusted. // TODO: This may in fact reallocate TLS without guarantees that it'll be deallocated again. ::runtimeState = state; RestoreMemory(state->memoryState); bool lastRuntime = atomicAdd(&aliveRuntimesCount, -1) == 0; switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: destroyRuntime = lastRuntime; break; case DESTROY_RUNTIME_ON_SHUTDOWN: // Nothing to do. break; } ClearTLS(state->memoryState); if (destroyRuntime) InitOrDeinitGlobalVariables(DEINIT_GLOBALS, state->memoryState); auto workerId = GetWorkerId(state->worker); WorkerDeinit(state->worker); DeinitMemory(state->memoryState, destroyRuntime); konanDestructInstance(state); WorkerDestroyThreadDataIfNeeded(workerId); ::runtimeState = kInvalidRuntime; } void Kotlin_deinitRuntimeCallback(void* argument) { auto* state = reinterpret_cast(argument); deinitRuntime(state, false); } } // namespace extern "C" { void AppendToInitializersTail(InitNode *next) { // TODO: use RuntimeState. if (initHeadNode == nullptr) { initHeadNode = next; } else { initTailNode->next = next; } initTailNode = next; } RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded() { if (!isValidRuntime()) { initRuntime(); // Register runtime deinit function at thread cleanup. konan::onThreadExit(Kotlin_deinitRuntimeCallback, runtimeState); } } void Kotlin_deinitRuntimeIfNeeded() { if (isValidRuntime()) { deinitRuntime(::runtimeState, false); } } // TODO: Consider exporting it to interop API. void Kotlin_shutdownRuntime() { auto* runtime = ::runtimeState; RuntimeAssert(runtime != kInvalidRuntime, "Current thread must have Kotlin runtime initialized on it"); bool needsFullShutdown = false; switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: needsFullShutdown = true; break; case DESTROY_RUNTIME_ON_SHUTDOWN: needsFullShutdown = Kotlin_forceCheckedShutdown() || Kotlin_memoryLeakCheckerEnabled() || Kotlin_cleanersLeakCheckerEnabled(); break; } if (!needsFullShutdown) { auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeRunning, kGlobalRuntimeShutdown); RuntimeAssert(lastStatus == kGlobalRuntimeRunning, "Invalid runtime status for shutdown"); return; } if (Kotlin_cleanersLeakCheckerEnabled()) { // Make sure to collect any lingering cleaners. PerformFullGC(runtime->memoryState); } // Stop cleaner worker. Only execute the cleaners if checker is enabled. ShutdownCleaners(Kotlin_cleanersLeakCheckerEnabled()); // Cleaners are now done, disallow new runtimes. auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeRunning, kGlobalRuntimeShutdown); RuntimeAssert(lastStatus == kGlobalRuntimeRunning, "Invalid runtime status for shutdown"); bool canDestroyRuntime = true; // TODO: When legacy mode is gone, this `if` will become unnecessary. if (Kotlin_forceCheckedShutdown() || Kotlin_memoryLeakCheckerEnabled() || Kotlin_cleanersLeakCheckerEnabled()) { // First make sure workers are gone. WaitNativeWorkersTermination(); // Now check for existence of any other runtimes. auto otherRuntimesCount = atomicGet(&aliveRuntimesCount) - 1; RuntimeAssert(otherRuntimesCount >= 0, "Cannot be negative"); if (Kotlin_forceCheckedShutdown()) { if (otherRuntimesCount > 0) { konan::consoleErrorf("Cannot run checkers when there are %d alive runtimes at the shutdown", otherRuntimesCount); konan::abort(); } } else { // Cannot destroy runtime globally if there're some other threads with Kotlin runtime on them. canDestroyRuntime = otherRuntimesCount == 0; } } deinitRuntime(runtime, canDestroyRuntime); } KInt Konan_Platform_canAccessUnaligned() { #if KONAN_NO_UNALIGNED_ACCESS return 0; #else return 1; #endif } KInt Konan_Platform_isLittleEndian() { #ifdef __BIG_ENDIAN__ return 0; #else return 1; #endif } KInt Konan_Platform_getOsFamily() { #if KONAN_MACOSX return 1; #elif KONAN_IOS return 2; #elif KONAN_LINUX return 3; #elif KONAN_WINDOWS return 4; #elif KONAN_ANDROID return 5; #elif KONAN_WASM return 6; #elif KONAN_TVOS return 7; #elif KONAN_WATCHOS return 8; #else #warning "Unknown platform" return 0; #endif } KInt Konan_Platform_getCpuArchitecture() { #if KONAN_ARM32 return 1; #elif KONAN_ARM64 return 2; #elif KONAN_X86 return 3; #elif KONAN_X64 return 4; #elif KONAN_MIPS32 return 5; #elif KONAN_MIPSEL32 return 6; #elif KONAN_WASM return 7; #else #warning "Unknown CPU" return 0; #endif } KInt Konan_Platform_getMemoryModel() { return static_cast(CurrentMemoryModel); } KBoolean Konan_Platform_isDebugBinary() { return KonanNeedDebugInfo ? true : false; } bool Kotlin_memoryLeakCheckerEnabled() { return g_checkLeaks; } KBoolean Konan_Platform_getMemoryLeakChecker() { return g_checkLeaks; } void Konan_Platform_setMemoryLeakChecker(KBoolean value) { g_checkLeaks = value; } bool Kotlin_cleanersLeakCheckerEnabled() { return g_checkLeakedCleaners; } KBoolean Konan_Platform_getCleanersLeakChecker() { return g_checkLeakedCleaners; } void Konan_Platform_setCleanersLeakChecker(KBoolean value) { g_checkLeakedCleaners = value; } bool Kotlin_forceCheckedShutdown() { return g_forceCheckedShutdown; } KBoolean Kotlin_Debugging_getForceCheckedShutdown() { return g_forceCheckedShutdown; } void Kotlin_Debugging_setForceCheckedShutdown(KBoolean value) { switch (Kotlin_getDestroyRuntimeMode()) { case DESTROY_RUNTIME_LEGACY: // Only applicable to ON_SHUTDOWN modes. return; case DESTROY_RUNTIME_ON_SHUTDOWN: break; } g_forceCheckedShutdown = value; } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Runtime.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_RUNTIME_H #define RUNTIME_RUNTIME_H #include "Porting.h" struct InitNode; #ifdef __cplusplus extern "C" { #endif // Must match DestroyRuntimeMode in DestroyRuntimeMode.kt enum DestroyRuntimeMode { DESTROY_RUNTIME_LEGACY = 0, DESTROY_RUNTIME_ON_SHUTDOWN = 1, }; DestroyRuntimeMode Kotlin_getDestroyRuntimeMode(); RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded(); void Kotlin_deinitRuntimeIfNeeded(); // Can only be called once. // No new runtimes can be initialized on any thread after this. // Must be called on a thread with active runtime. // Using already initialized runtimes on any thread after this is undefined behaviour. void Kotlin_shutdownRuntime(); // Appends given node to an initializer list. void AppendToInitializersTail(struct InitNode*); bool Kotlin_memoryLeakCheckerEnabled(); bool Kotlin_cleanersLeakCheckerEnabled(); bool Kotlin_forceCheckedShutdown(); #ifdef __cplusplus } // extern "C" #endif #endif // RUNTIME_RUNTIME_H ================================================ FILE: runtime/src/main/cpp/SingleLockList.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_SINGLE_LOCK_LIST_H #define RUNTIME_SINGLE_LOCK_LIST_H #include #include #include #include "Alloc.h" #include "Mutex.hpp" #include "Types.h" #include "Utils.hpp" namespace kotlin { // TODO: Consider different locking mechanisms. template class SingleLockList : private Pinned { public: class Node; private: class NodeDeleter { public: void operator()(Node* node) const { delete node; } }; using NodeOwner = std::unique_ptr; public: class Node : private Pinned, public KonanAllocatorAware { public: Value* Get() noexcept { return &value_; } private: friend class SingleLockList; template Node(Args&&... args) noexcept : value_(std::forward(args)...) {} // Make sure `Node` can only be deleted by `SingleLockList` itself. ~Node() = default; Value value_; NodeOwner next_; Node* previous_ = nullptr; // weak }; class Iterator { public: explicit Iterator(Node* node) noexcept : node_(node) {} Value& operator*() noexcept { return node_->value_; } Iterator& operator++() noexcept { node_ = node_->next_.get(); return *this; } bool operator==(const Iterator& rhs) const noexcept { return node_ == rhs.node_; } bool operator!=(const Iterator& rhs) const noexcept { return node_ != rhs.node_; } private: Node* node_; }; class Iterable : private MoveOnly { public: explicit Iterable(SingleLockList* list) noexcept : list_(list), guard_(list->mutex_) {} Iterator begin() noexcept { return Iterator(list_->root_.get()); } Iterator end() noexcept { return Iterator(nullptr); } private: SingleLockList* list_; std::unique_lock guard_; }; ~SingleLockList() { AssertCorrectUnsafe(); // Make sure not to blow up the stack by nested `~Node` calls. for (auto node = std::move(root_); node != nullptr; node = std::move(node->next_)) { } last_ = nullptr; AssertCorrectUnsafe(); } // TODO: Consider making `Emplace` append to `last_`. template Node* Emplace(Args&&... args) noexcept { auto* nodePtr = new Node(std::forward(args)...); NodeOwner node(nodePtr); std::lock_guard guard(mutex_); AssertCorrectUnsafe(); if (root_) { root_->previous_ = node.get(); } else { last_ = nodePtr; } node->next_ = std::move(root_); root_ = std::move(node); AssertCorrectUnsafe(); return nodePtr; } // Using `node` including its referred `Value` after `Erase` is undefined behaviour. void Erase(Node* node) noexcept { std::lock_guard guard(mutex_); AssertCorrectUnsafe(); if (last_ == node) { last_ = node->previous_; } if (root_.get() == node) { root_ = std::move(node->next_); if (root_) { root_->previous_ = nullptr; } AssertCorrectUnsafe(); return; } auto* previous = node->previous_; RuntimeAssert(previous != nullptr, "Only the root node doesn't have the previous node"); auto ownedNode = std::move(previous->next_); previous->next_ = std::move(node->next_); if (auto& next = previous->next_) { next->previous_ = previous; } AssertCorrectUnsafe(); } // Returned value locks `this` to perform safe iteration. `this` unlocks when // `Iterable` gets out of scope. Example usage: // for (auto& value: list.Iter()) { // // Do something with `value`, there's a guarantee that it'll not be // // destroyed mid-iteration. // } // // At this point `list` is unlocked. Iterable Iter() noexcept { return Iterable(this); } private: // Expects `mutex_` to be held by the current thread. ALWAYS_INLINE void AssertCorrectUnsafe() const noexcept { if (root_ == nullptr) { RuntimeAssert(last_ == nullptr, "last_ must be null"); } else { RuntimeAssert(root_->previous_ == nullptr, "root_ must not have previous_"); RuntimeAssert(last_ != nullptr, "last_ must not be null"); RuntimeAssert(last_->next_ == nullptr, "last_ must not have next_"); } } NodeOwner root_; Node* last_ = nullptr; Mutex mutex_; }; } // namespace kotlin #endif // RUNTIME_SINGLE_LOCK_LIST_H ================================================ FILE: runtime/src/main/cpp/SingleLockListTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "SingleLockList.hpp" #include #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "TestSupport.hpp" #include "Types.h" using namespace kotlin; namespace { using IntList = SingleLockList; } // namespace TEST(SingleLockListTest, Emplace) { IntList list; constexpr int kFirst = 1; constexpr int kSecond = 2; constexpr int kThird = 3; auto* firstNode = list.Emplace(kFirst); auto* secondNode = list.Emplace(kSecond); auto* thirdNode = list.Emplace(kThird); int* first = firstNode->Get(); int* second = secondNode->Get(); int* third = thirdNode->Get(); EXPECT_THAT(*first, kFirst); EXPECT_THAT(*second, kSecond); EXPECT_THAT(*third, kThird); } TEST(SingleLockListTest, EmplaceAndIter) { IntList list; constexpr int kFirst = 1; constexpr int kSecond = 2; constexpr int kThird = 3; list.Emplace(kFirst); list.Emplace(kSecond); list.Emplace(kThird); KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::ElementsAre(kThird, kSecond, kFirst)); } TEST(SingleLockListTest, EmplaceEraseAndIter) { IntList list; constexpr int kFirst = 1; constexpr int kSecond = 2; constexpr int kThird = 3; list.Emplace(kFirst); auto* secondNode = list.Emplace(kSecond); list.Emplace(kThird); list.Erase(secondNode); KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::ElementsAre(kThird, kFirst)); } TEST(SingleLockListTest, IterEmpty) { IntList list; KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(SingleLockListTest, EraseToEmptyEmplaceAndIter) { IntList list; constexpr int kFirst = 1; constexpr int kSecond = 2; constexpr int kThird = 3; constexpr int kFourth = 4; auto* firstNode = list.Emplace(kFirst); auto* secondNode = list.Emplace(kSecond); list.Erase(firstNode); list.Erase(secondNode); list.Emplace(kThird); list.Emplace(kFourth); KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::ElementsAre(kFourth, kThird)); } TEST(SingleLockListTest, ConcurrentEmplace) { IntList list; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; KStdVector expected; for (int i = 0; i < kThreadCount; ++i) { expected.push_back(i); threads.emplace_back([i, &list, &canStart, &readyCount]() { ++readyCount; while (!canStart) { } list.Emplace(i); }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::UnorderedElementsAreArray(expected)); } TEST(SingleLockListTest, ConcurrentErase) { IntList list; constexpr int kThreadCount = kDefaultThreadCount; KStdVector items; for (int i = 0; i < kThreadCount; ++i) { items.push_back(list.Emplace(i)); } std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; for (auto* item : items) { threads.emplace_back([item, &list, &canStart, &readyCount]() { ++readyCount; while (!canStart) { } list.Erase(item); }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } KStdVector actual; for (int element : list.Iter()) { actual.push_back(element); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(SingleLockListTest, IterWhileConcurrentEmplace) { IntList list; constexpr int kStartCount = 50; constexpr int kThreadCount = kDefaultThreadCount; KStdDeque expectedBefore; KStdVector expectedAfter; for (int i = 0; i < kStartCount; ++i) { expectedBefore.push_front(i); expectedAfter.push_back(i); list.Emplace(i); } std::atomic canStart(false); std::atomic startedCount(0); KStdVector threads; for (int i = 0; i < kThreadCount; ++i) { int j = i + kStartCount; expectedAfter.push_back(j); threads.emplace_back([j, &list, &canStart, &startedCount]() { while (!canStart) { } ++startedCount; list.Emplace(j); }); } KStdVector actualBefore; { auto iter = list.Iter(); canStart = true; while (startedCount < kThreadCount) { } for (int element : iter) { actualBefore.push_back(element); } } for (auto& t : threads) { t.join(); } EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore)); KStdVector actualAfter; for (int element : list.Iter()) { actualAfter.push_back(element); } EXPECT_THAT(actualAfter, testing::UnorderedElementsAreArray(expectedAfter)); } TEST(SingleLockListTest, IterWhileConcurrentErase) { IntList list; constexpr int kThreadCount = kDefaultThreadCount; KStdDeque expectedBefore; KStdVector items; for (int i = 0; i < kThreadCount; ++i) { expectedBefore.push_front(i); items.push_back(list.Emplace(i)); } std::atomic canStart(false); std::atomic startedCount(0); KStdVector threads; for (auto* item : items) { threads.emplace_back([item, &list, &canStart, &startedCount]() { while (!canStart) { } ++startedCount; list.Erase(item); }); } KStdVector actualBefore; { auto iter = list.Iter(); canStart = true; while (startedCount < kThreadCount) { } for (int element : iter) { actualBefore.push_back(element); } } for (auto& t : threads) { t.join(); } EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore)); KStdVector actualAfter; for (int element : list.Iter()) { actualAfter.push_back(element); } EXPECT_THAT(actualAfter, testing::IsEmpty()); } namespace { class PinnedType : private Pinned { public: PinnedType(int value) : value_(value) {} int value() const { return value_; } private: int value_; }; } // namespace TEST(SingleLockListTest, PinnedType) { SingleLockList list; constexpr int kFirst = 1; auto* itemNode = list.Emplace(kFirst); PinnedType* item = itemNode->Get(); EXPECT_THAT(item->value(), kFirst); list.Erase(itemNode); KStdVector actualAfter; for (auto& element : list.Iter()) { actualAfter.push_back(&element); } EXPECT_THAT(actualAfter, testing::IsEmpty()); } namespace { class WithDestructorHook; using DestructorHook = void(WithDestructorHook*); class WithDestructorHook : private Pinned { public: explicit WithDestructorHook(std::function hook) : hook_(std::move(hook)) {} ~WithDestructorHook() { hook_(this); } private: std::function hook_; }; } // namespace TEST(SingleLockListTest, Destructor) { testing::StrictMock> hook; { SingleLockList list; auto* first = list.Emplace(hook.AsStdFunction())->Get(); auto* second = list.Emplace(hook.AsStdFunction())->Get(); auto* third = list.Emplace(hook.AsStdFunction())->Get(); { testing::InSequence seq; // `list` is `third`->`second`->`first`. If destruction // were to cause recursion, the order of destructors // would've been backwards. EXPECT_CALL(hook, Call(third)); EXPECT_CALL(hook, Call(second)); EXPECT_CALL(hook, Call(first)); } } } ================================================ FILE: runtime/src/main/cpp/SourceInfo.h ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_SOURCEINFO_H #define RUNTIME_SOURCEINFO_H struct SourceInfo { const char* fileName; int lineNumber; int column; }; #ifdef __cplusplus extern "C" { #endif struct SourceInfo Kotlin_getSourceInfo(void* addr); #ifdef __cplusplus } // extern "C" #endif #endif // RUNTIME_SOURCEINFO_H ================================================ FILE: runtime/src/main/cpp/StdCppStubs.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "KAssert.h" #include "Porting.h" #include "Common.h" #if KONAN_LINUX || KONAN_WINDOWS // This function replaces `__cxa_demangle` defined in GNU libstdc++ // by adding `--defsym` flag in `konan.properties`. // This allows to avoid linking `__cxa_demangle` and its dependencies, thus reducing binary size. RUNTIME_USED RUNTIME_WEAK extern "C" char* Konan_cxa_demangle( const char* __mangled_name, char* __output_buffer, size_t* __length, int* __status ) { *__status = -2; // __mangled_name is not a valid name under the C++ ABI mangling rules. return nullptr; } namespace std { RUNTIME_WEAK void __throw_length_error(const char* __s __attribute__((unused))) { RuntimeCheck(false, "%s", __s); } } // namespace std #endif // KONAN_LINUX || KONAN_WINDOWS #if KONAN_LINUX #include // Since GCC 4.8.5 mangling for std::system_category has changed from _ZNSt3_V215system_categoryEv to _ZSt15system_categoryv. // It causes linkage problems in case of kotlinx-datetime:0.1.1 usage, because its C++ dependency is compiled with old GCC 4.8.5. // So to avoid nasty linkage problems when users migrate their projects with kotlinx-datetime:0.1.1 dependency from 1.4.x to 1.5.x // we provide this compatibility layer. RUNTIME_WEAK const std::error_category& std_system_category_backward_compatibility_with_gcc_4_8_5() noexcept __asm("_ZSt15system_categoryv"); const std::error_category& std_system_category_backward_compatibility_with_gcc_4_8_5() noexcept { return std::system_category(); } #endif // KONAN_LINUX ================================================ FILE: runtime/src/main/cpp/TestSupport.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include #include "Memory.h" #include "Runtime.h" namespace kotlin { #if KONAN_WINDOWS // TODO: Figure out why creating many threads on windows is so slow. constexpr int kDefaultThreadCount = 10; #elif __has_feature(thread_sanitizer) // TSAN has a huge overhead. constexpr int kDefaultThreadCount = 10; #else constexpr int kDefaultThreadCount = 100; #endif // Scopely initializes the memory subsystem of the current thread for tests. class ScopedRuntimeInit : private kotlin::Pinned { public: ScopedRuntimeInit() : memoryState_(InitMemory(false)) {} ~ScopedRuntimeInit() { DeinitMemory(memoryState_, false); } MemoryState* memoryState() { return memoryState_; } private: MemoryState* memoryState_; }; // Runs the given function in a separate thread with minimally initialized runtime. inline void RunInNewThread(std::function f) { std::thread([&f]() { ScopedRuntimeInit init; f(init.memoryState()); }).join(); } // Runs the given function in a separate thread with minimally initialized runtime. inline void RunInNewThread(std::function f) { RunInNewThread([&f](MemoryState* unused) { f(); }); } } // namespace kotlin ================================================ FILE: runtime/src/main/cpp/TestSupportCompilerGenerated.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Types.h" #include "Utils.hpp" template class ScopedStrictMockFunction : private kotlin::MoveOnly { public: using Mock = testing::StrictMock>; explicit ScopedStrictMockFunction(Mock** globalMockLocation) : globalMockLocation_(globalMockLocation) { RuntimeCheck(globalMockLocation != nullptr, "ScopedStrictMockFunction needs non-null global mock location"); RuntimeCheck(*globalMockLocation == nullptr, "ScopedStrictMockFunction needs null global mock"); mock_ = make_unique(); *globalMockLocation_ = mock_.get(); } ScopedStrictMockFunction(ScopedStrictMockFunction&& rhs) : globalMockLocation_(rhs.globalMockLocation_), mock_(std::move(rhs.mock_)) { rhs.globalMockLocation_ = nullptr; } ScopedStrictMockFunction& operator=(ScopedStrictMockFunction&& rhs) { ScopedStrictMockFunction tmp(std::move(rhs)); swap(tmp); return *this; } ~ScopedStrictMockFunction() { if (!globalMockLocation_) return; RuntimeCheck(*globalMockLocation_ == mock_.get(), "unexpected global mock location"); mock_.reset(); *globalMockLocation_ = nullptr; } void swap(ScopedStrictMockFunction& other) { std::swap(globalMockLocation_, other.globalMockLocation_); std::swap(mock_, other.mock_); } Mock& get() { return *mock_; } Mock& operator*() { return *mock_; } private: // Can be null if moved-out of. Mock** globalMockLocation_; KStdUniquePtr mock_; }; ScopedStrictMockFunction ScopedCreateCleanerWorkerMock(); ScopedStrictMockFunction ScopedShutdownCleanerWorkerMock(); ================================================ FILE: runtime/src/main/cpp/Time.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Natives.h" #include "Porting.h" #include "Types.h" extern "C" { KLong Kotlin_system_getTimeMillis() { return konan::getTimeMillis(); } KLong Kotlin_system_getTimeNanos() { return konan::getTimeNanos(); } KLong Kotlin_system_getTimeMicros() { return konan::getTimeMicros(); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/ToString.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "KAssert.h" #include "Exceptions.h" #include "Memory.h" #include "Natives.h" #include "KString.h" #include "Porting.h" #include "Types.h" namespace { char int_to_digit(uint32_t value) { if (value < 10) { return '0' + value; } else { return 'a' + (value - 10); } } // Radix is checked on the Kotlin side. template OBJ_GETTER(Kotlin_toStringRadix, T value, KInt radix) { if (value == 0) { RETURN_RESULT_OF(CreateStringFromCString, "0"); } // In the worst case, we convert to binary, with sign. char cstring[sizeof(T) * CHAR_BIT + 2]; bool negative = (value < 0); if (!negative) { value = -value; } int32_t length = 0; while (value < 0) { cstring[length++] = int_to_digit(-(value % radix)); value /= radix; } if (negative) { cstring[length++] = '-'; } for (int i = 0, j = length - 1; i < j; i++, j--) { char tmp = cstring[i]; cstring[i] = cstring[j]; cstring[j] = tmp; } cstring[length] = '\0'; RETURN_RESULT_OF(CreateStringFromCString, cstring); } } // namespace extern "C" { OBJ_GETTER(Kotlin_Byte_toString, KByte value) { char cstring[8]; konan::snprintf(cstring, sizeof(cstring), "%d", value); RETURN_RESULT_OF(CreateStringFromCString, cstring); } OBJ_GETTER(Kotlin_Char_toString, KChar value) { ArrayHeader* result = AllocArrayInstance(theStringTypeInfo, 1, OBJ_RESULT)->array(); *CharArrayAddressOfElementAt(result, 0) = value; RETURN_OBJ(result->obj()); } OBJ_GETTER(Kotlin_Short_toString, KShort value) { char cstring[8]; konan::snprintf(cstring, sizeof(cstring), "%d", value); RETURN_RESULT_OF(CreateStringFromCString, cstring); } OBJ_GETTER(Kotlin_Int_toString, KInt value) { char cstring[16]; konan::snprintf(cstring, sizeof(cstring), "%d", value); RETURN_RESULT_OF(CreateStringFromCString, cstring); } OBJ_GETTER(Kotlin_Int_toStringRadix, KInt value, KInt radix) { RETURN_RESULT_OF(Kotlin_toStringRadix, value, radix) } OBJ_GETTER(Kotlin_Long_toString, KLong value) { char cstring[32]; konan::snprintf(cstring, sizeof(cstring), "%lld", static_cast(value)); RETURN_RESULT_OF(CreateStringFromCString, cstring); } OBJ_GETTER(Kotlin_Long_toStringRadix, KLong value, KInt radix) { RETURN_RESULT_OF(Kotlin_toStringRadix, value, radix) } OBJ_GETTER(Kotlin_DurationValue_formatToExactDecimals, KDouble value, KInt decimals) { char cstring[32]; konan::snprintf(cstring, sizeof(cstring), "%.*f", decimals, value); RETURN_RESULT_OF(CreateStringFromCString, cstring) } OBJ_GETTER(Kotlin_DurationValue_formatScientificImpl, KDouble value) { char cstring[16]; konan::snprintf(cstring, sizeof(cstring), "%.2e", value); RETURN_RESULT_OF(CreateStringFromCString, cstring) } } // extern "C" ================================================ FILE: runtime/src/main/cpp/TypeInfo.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "KAssert.h" #include "TypeInfo.h" // If one shall use binary search when looking up methods and fields. // TODO: maybe select strategy basing on number of elements. #define USE_BINARY_SEARCH 1 extern "C" { #if USE_BINARY_SEARCH void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) { int bottom = 0; int top = info->openMethodsCount_ - 1; while (bottom <= top) { int middle = (bottom + top) / 2; if (info->openMethods_[middle].nameSignature_ < nameSignature) bottom = middle + 1; else if (info->openMethods_[middle].nameSignature_ == nameSignature) return info->openMethods_[middle].methodEntryPoint_; else top = middle - 1; } RuntimeAssert(false, "Unknown open method"); return nullptr; } #else void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) { for (int i = 0; i < info->openMethodsCount_; ++i) { if (info->openMethods_[i].nameSignature_ == nameSignature) { return info->openMethods_[i].methodEntryPoint_; } } RuntimeAssert(false, "Unknown open method"); return nullptr; } #endif // Seeks for the specified id. In case of failure returns a valid pointer to some record, never returns nullptr. // It is the caller's responsibility to check if the search has succeeded or not. InterfaceTableRecord const* LookupInterfaceTableRecord(InterfaceTableRecord const* interfaceTable, int interfaceTableSize, ClassId interfaceId) { if (interfaceTableSize <= 8) { // Linear search. int i; for (i = 0; i < interfaceTableSize - 1 && interfaceTable[i].id < interfaceId; ++i); return interfaceTable + i; } int l = 0, r = interfaceTableSize - 1; while (l < r) { int m = (l + r) / 2; if (interfaceTable[m].id < interfaceId) l = m + 1; else r = m; } return interfaceTable + l; } } ================================================ FILE: runtime/src/main/cpp/TypeInfo.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_TYPEINFO_H #define RUNTIME_TYPEINFO_H #include #include "Common.h" #include "Names.h" #if KONAN_TYPE_INFO_HAS_WRITABLE_PART struct WritableTypeInfo; #endif struct ObjHeader; struct AssociatedObjectTableRecord; // An element of sorted by hash in-place array representing methods. // For systems where introspection is not needed - only open methods are in // this table. struct MethodTableRecord { MethodNameHash nameSignature_; void* methodEntryPoint_; }; // Type for runtime representation of Konan object. // Keep in sync with runtimeTypeMap in RTTIGenerator. enum Konan_RuntimeType { RT_INVALID = 0, RT_OBJECT = 1, RT_INT8 = 2, RT_INT16 = 3, RT_INT32 = 4, RT_INT64 = 5, RT_FLOAT32 = 6, RT_FLOAT64 = 7, RT_NATIVE_PTR = 8, RT_BOOLEAN = 9, RT_VECTOR128 = 10 }; // Flags per type. // Keep in sync with constants in RTTIGenerator. enum Konan_TypeFlags { TF_IMMUTABLE = 1 << 0, TF_ACYCLIC = 1 << 1, TF_INTERFACE = 1 << 2, TF_OBJC_DYNAMIC = 1 << 3, TF_LEAK_DETECTOR_CANDIDATE = 1 << 4, TF_SUSPEND_FUNCTION = 1 << 5, TF_HAS_FINALIZER = 1 << 6, TF_HAS_FREEZE_HOOK = 1 << 7, }; // Flags per object instance. enum Konan_MetaFlags { // If freeze attempt happens on such an object - throw an exception. MF_NEVER_FROZEN = 1 << 0, }; // Extended information about a type. struct ExtendedTypeInfo { // Number of fields (negated Konan_RuntimeType for array types). int32_t fieldsCount_; // Offsets of all fields. const int32_t* fieldOffsets_; // Types of all fields. const uint8_t* fieldTypes_; // Names of all fields. const char** fieldNames_; // Number of supported debug operations. int32_t debugOperationsCount_; // Table of supported debug operations functions. void** debugOperations_; }; typedef void const* VTableElement; typedef int32_t ClassId; const ClassId kInvalidInterfaceId = 0; struct InterfaceTableRecord { ClassId id; uint32_t vtableSize; VTableElement const* vtable; }; // This struct represents runtime type information and by itself is the compile time // constant. struct TypeInfo { // Reference to self, to allow simple obtaining TypeInfo via meta-object. const TypeInfo* typeInfo_; // Extended RTTI, to retain cross-version debuggability, since ABI version 5 shall always be at the second position. const ExtendedTypeInfo* extendedInfo_; // Unused field. uint32_t unused_; // Negative value marks array class/string, and it is negated element size. int32_t instanceSize_; // Must be pointer to Any for array classes, and null for Any. const TypeInfo* superType_; // All object reference fields inside this object. const int32_t* objOffsets_; // Count of object reference fields inside this object. // 1 for kotlin.Array to mark it as non-leaf. int32_t objOffsetsCount_; const TypeInfo* const* implementedInterfaces_; int32_t implementedInterfacesCount_; // Null for abstract classes and interfaces. const MethodTableRecord* openMethods_; uint32_t openMethodsCount_; int32_t interfaceTableSize_; InterfaceTableRecord const* interfaceTable_; // String for the fully qualified dot-separated name of the package containing class, // or `null` if the class is local or anonymous. ObjHeader* packageName_; // String for the qualified class name relative to the containing package // (e.g. TopLevel.Nested1.Nested2), or simple class name if it is local, // or `null` if the class is anonymous. ObjHeader* relativeName_; // Various flags. int32_t flags_; // Class id built with the whole class hierarchy taken into account. The details are in ClassLayoutBuilder. ClassId classId_; #if KONAN_TYPE_INFO_HAS_WRITABLE_PART WritableTypeInfo* writableInfo_; #endif // Null-terminated array. const AssociatedObjectTableRecord* associatedObjects; // vtable starts just after declared contents of the TypeInfo: // void* const vtable_[]; #ifdef __cplusplus inline VTableElement const* vtable() const { return reinterpret_cast(this + 1); } inline VTableElement* vtable() { return reinterpret_cast(this + 1); } inline bool IsArray() const { return instanceSize_ < 0; } #endif }; #ifdef __cplusplus extern "C" { #endif // Find open method by its hash. Other methods are resolved in compile-time. // Note, that we use attribute const, which assumes function doesn't // dereference global memory, while this function does. However, it seems // to be safe, as actual result of this computation depends only on 'type_info' // and 'hash' numeric values and doesn't really depends on global memory state // (as TypeInfo is compile time constant and type info pointers are stable). void* LookupOpenMethod(const TypeInfo* info, MethodNameHash nameSignature) RUNTIME_CONST; InterfaceTableRecord const* LookupInterfaceTableRecord(InterfaceTableRecord const* interfaceTable, int interfaceTableSize, ClassId interfaceId) RUNTIME_CONST; #ifdef __cplusplus } // extern "C" #endif #endif // RUNTIME_TYPEINFO_H ================================================ FILE: runtime/src/main/cpp/Types.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Types.h" #include "Exceptions.h" extern "C" { KBoolean IsInstance(const ObjHeader* obj, const TypeInfo* type_info) { // We assume null check is handled by caller. RuntimeAssert(obj != nullptr, "must not be null"); const TypeInfo* obj_type_info = obj->type_info(); // If it is an interface - check in list of implemented interfaces. if ((type_info->flags_ & TF_INTERFACE) != 0) { for (int i = 0; i < obj_type_info->implementedInterfacesCount_; ++i) { if (obj_type_info->implementedInterfaces_[i] == type_info) { return 1; } } return 0; } while (obj_type_info != nullptr && obj_type_info != type_info) { obj_type_info = obj_type_info->superType_; } return obj_type_info != nullptr; } KBoolean IsInstanceOfClassFast(const ObjHeader* obj, int32_t lo, int32_t hi) { // We assume null check is handled by caller. RuntimeAssert(obj != nullptr, "must not be null"); const TypeInfo* obj_type_info = obj->type_info(); // Super type's interval should contain our interval. return obj_type_info->classId_ >= lo && obj_type_info->classId_ <= hi; } KBoolean IsArray(KConstRef obj) { RuntimeAssert(obj != nullptr, "Object must not be null"); return obj->type_info()->instanceSize_ < 0; } KBoolean Kotlin_TypeInfo_isInstance(KConstRef obj, KNativePtr typeInfo) { return IsInstance(obj, reinterpret_cast(typeInfo)); } OBJ_GETTER(Kotlin_TypeInfo_getPackageName, KNativePtr typeInfo) { RETURN_OBJ(reinterpret_cast(typeInfo)->packageName_); } OBJ_GETTER(Kotlin_TypeInfo_getRelativeName, KNativePtr typeInfo) { RETURN_OBJ(reinterpret_cast(typeInfo)->relativeName_); } struct AssociatedObjectTableRecord { const TypeInfo* key; OBJ_GETTER0((*getAssociatedObjectInstance)); }; OBJ_GETTER(Kotlin_TypeInfo_findAssociatedObject, KNativePtr typeInfo, KNativePtr key) { const AssociatedObjectTableRecord* associatedObjects = reinterpret_cast(typeInfo)->associatedObjects; if (associatedObjects == nullptr) { RETURN_OBJ(nullptr); } for (int index = 0; associatedObjects[index].key != nullptr; ++index) { if (associatedObjects[index].key == key) { RETURN_RESULT_OF0(associatedObjects[index].getAssociatedObjectInstance); } } RETURN_OBJ(nullptr); } bool IsSubInterface(const TypeInfo* thiz, const TypeInfo* other) { for (int i = 0; i < thiz->implementedInterfacesCount_; ++i) { if (thiz->implementedInterfaces_[i] == other) { return true; } } return false; } KVector4f Kotlin_Vector4f_of(KFloat f0, KFloat f1, KFloat f2, KFloat f3) { return {f0, f1, f2, f3}; } /* * In the current design all simd types are mapped internally to floating type, e.g. <4 x float>. * However, some platforms (ex. arm32) have different calling convention for <4 x float> and <4 x i32>. * To avoid illegal bitcast from/to function types the following function * return type MUST be <4 x float> and explicit type cast is done on the variable type. */ KVector4f Kotlin_Vector4i32_of(KInt f0, KInt f1, KInt f2, KInt f3) { KInt __attribute__ ((__vector_size__(16))) v4i = {f0, f1, f2, f3}; return (KVector4f)v4i; } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Types.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_TYPES_H #define RUNTIME_TYPES_H #include #if (KONAN_WASM || KONAN_ZEPHYR) && !defined(assert) // assert() is needed by STLport. #define assert(cond) if (!(cond)) abort() #endif #include #include #include #include #include #include #include #include #include #include "Alloc.h" #include "Common.h" #include "Memory.h" #include "TypeInfo.h" // Note that almost all types are signed. typedef bool KBoolean; typedef int8_t KByte; typedef uint16_t KChar; typedef int16_t KShort; typedef int32_t KInt; typedef int64_t KLong; typedef uint8_t KUByte; typedef uint16_t KUShort; typedef uint32_t KUInt; typedef uint64_t KULong; typedef float KFloat; typedef double KDouble; typedef void* KNativePtr; typedef KFloat __attribute__ ((__vector_size__ (16))) KVector4f; typedef const void* KConstNativePtr; typedef ObjHeader* KRef; typedef const ObjHeader* KConstRef; typedef const ArrayHeader* KString; // TODO: Consider moving these into `kotlin::std_support` namespace keeping STL names. // Definitions of STL classes used inside Konan runtime. typedef std::basic_string, KonanAllocator> KStdString; template using KStdDeque = std::deque>; template using KStdUnorderedMap = std::unordered_map, std::equal_to, KonanAllocator>>; template using KStdUnorderedSet = std::unordered_set, std::equal_to, KonanAllocator>; template> using KStdOrderedSet = std::set>; template> using KStdOrderedMap = std::map>>; template using KStdVector = std::vector>; template using KStdList = std::list>; template using KStdUniquePtr = std::unique_ptr>; template KStdUniquePtr make_unique(Args&&... args) noexcept { return KStdUniquePtr(konanConstructInstance(std::forward(args)...)); } #ifdef __cplusplus extern "C" { #endif extern const TypeInfo* theAnyTypeInfo; extern const TypeInfo* theArrayTypeInfo; extern const TypeInfo* theBooleanArrayTypeInfo; extern const TypeInfo* theByteArrayTypeInfo; extern const TypeInfo* theCharArrayTypeInfo; extern const TypeInfo* theDoubleArrayTypeInfo; extern const TypeInfo* theForeignObjCObjectTypeInfo; extern const TypeInfo* theIntArrayTypeInfo; extern const TypeInfo* theLongArrayTypeInfo; extern const TypeInfo* theNativePtrArrayTypeInfo; extern const TypeInfo* theFloatArrayTypeInfo; extern const TypeInfo* theForeignObjCObjectTypeInfo; extern const TypeInfo* theFreezableAtomicReferenceTypeInfo; extern const TypeInfo* theObjCObjectWrapperTypeInfo; extern const TypeInfo* theOpaqueFunctionTypeInfo; extern const TypeInfo* theShortArrayTypeInfo; extern const TypeInfo* theStringTypeInfo; extern const TypeInfo* theThrowableTypeInfo; extern const TypeInfo* theUnitTypeInfo; extern const TypeInfo* theWorkerBoundReferenceTypeInfo; extern const TypeInfo* theCleanerImplTypeInfo; KBoolean IsInstance(const ObjHeader* obj, const TypeInfo* type_info) RUNTIME_PURE; KBoolean IsInstanceOfClassFast(const ObjHeader* obj, int32_t lo, int32_t hi) RUNTIME_PURE; void CheckCast(const ObjHeader* obj, const TypeInfo* type_info); KBoolean IsArray(KConstRef obj) RUNTIME_PURE; bool IsSubInterface(const TypeInfo* thiz, const TypeInfo* other) RUNTIME_PURE; #ifdef __cplusplus } #endif #endif // RUNTIME_TYPES_H ================================================ FILE: runtime/src/main/cpp/Utils.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_UTILS_H #define RUNTIME_UTILS_H namespace kotlin { // A helper for implementing classes with disabled copy constructor and copy assignment. // Usage: // class A: private MoveOnly { // ... // }; // Prefer private inheritance to discourage casting instances of `A` to instances // of `MoveOnly`. class MoveOnly { // Hide constructors, assignments and destructor, to discourage operating on an instance of `MoveOnly`. protected: MoveOnly() noexcept = default; MoveOnly(const MoveOnly&) = delete; MoveOnly(MoveOnly&&) noexcept = default; MoveOnly& operator=(const MoveOnly&) = delete; MoveOnly& operator=(MoveOnly&&) noexcept = default; // Not virtual by design. Since this class hides this destructor, no one can destroy an // instance of `MoveOnly` directly, so this destructor is never called in a virtual manner. ~MoveOnly() = default; }; // A helper for implementing classes with disabled copy and move constructors, and copy and move assignments. // Usage: // class A: private Pinned { // ... // }; // Prefer private inheritance to discourage casting instances of `A` to instances // of `Pinned`. class Pinned { // Hide constructors, assignments and destructor, to discourage operating on an instance of `Pinned`. protected: Pinned() noexcept = default; Pinned(const Pinned&) = delete; Pinned(Pinned&&) = delete; Pinned& operator=(const Pinned&) = delete; Pinned& operator=(Pinned&&) = delete; // Not virtual by design. Since this class hides this destructor, no one can destroy an // instance of `Pinned` directly, so this destructor is never called in a virtual manner. ~Pinned() = default; }; } // namespace kotlin #endif // RUNTIME_UTILS_H ================================================ FILE: runtime/src/main/cpp/UtilsTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Utils.hpp" #include #include "gtest/gtest.h" using namespace kotlin; namespace { struct A { int field; }; class MoveOnlyImpl : private MoveOnly { public: A a; }; class PinnedImpl : private Pinned { public: A a; }; } // namespace TEST(UtilsTest, MoveOnlyImpl) { static_assert(std::is_nothrow_default_constructible_v, "Must be nothrow default constructible"); static_assert(std::is_nothrow_destructible_v, "Must be nothrow destructible"); static_assert(!std::is_copy_constructible_v, "Must not be copy constructible"); static_assert(!std::is_copy_assignable_v, "Must not be copy assignable"); static_assert(std::is_nothrow_move_constructible_v, "Must be nothrow move constructible"); static_assert(std::is_nothrow_move_assignable_v, "Must be nothrow move assignable"); static_assert(sizeof(MoveOnlyImpl) == sizeof(A), "Must not increase size"); } TEST(UtilsTest, PinnedImpl) { static_assert(std::is_nothrow_default_constructible_v, "Must be nothrow default constructible"); static_assert(std::is_nothrow_destructible_v, "Must be nothrow destructible"); static_assert(!std::is_copy_constructible_v, "Must not be copy constructible"); static_assert(!std::is_copy_assignable_v, "Must not be copy assignable"); static_assert(!std::is_move_constructible_v, "Must not be move constructible"); static_assert(!std::is_move_assignable_v, "Must not be move assignable"); static_assert(sizeof(PinnedImpl) == sizeof(A), "Must not increase size"); } ================================================ FILE: runtime/src/main/cpp/Weak.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "Weak.h" #include "Memory.h" #include "Types.h" namespace { // TODO: an ugly hack with fixed layout. struct WeakReferenceCounter { ObjHeader header; KRef referred; KInt lock; KInt cookie; }; inline WeakReferenceCounter* asWeakReferenceCounter(ObjHeader* obj) { return reinterpret_cast(obj); } #if !KONAN_NO_THREADS inline void lock(int32_t* address) { RuntimeAssert(*address == 0 || *address == 1, "Incorrect lock state"); while (__sync_val_compare_and_swap(address, 0, 1) == 1); } inline void unlock(int32_t* address) { int old = __sync_val_compare_and_swap(address, 1, 0); RuntimeAssert(old == 1, "Incorrect lock state"); } #endif } // namespace extern "C" { OBJ_GETTER(makeWeakReferenceCounter, void*); OBJ_GETTER(makeObjCWeakReferenceImpl, void*); OBJ_GETTER(makePermanentWeakReferenceImpl, ObjHeader*); // See Weak.kt for implementation details. // Retrieve link on the counter object. OBJ_GETTER(Konan_getWeakReferenceImpl, ObjHeader* referred) { if (referred->permanent()) { RETURN_RESULT_OF(makePermanentWeakReferenceImpl, referred); } #if KONAN_OBJC_INTEROP if (IsInstance(referred, theObjCObjectWrapperTypeInfo)) { RETURN_RESULT_OF(makeObjCWeakReferenceImpl, referred->GetAssociatedObject()); } #endif // KONAN_OBJC_INTEROP ObjHeader** weakCounterLocation = referred->GetWeakCounterLocation(); if (*weakCounterLocation == nullptr) { ObjHolder counterHolder; // Cast unneeded, just to emphasize we store an object reference as void*. ObjHeader* counter = makeWeakReferenceCounter(reinterpret_cast(referred), counterHolder.slot()); UpdateHeapRefIfNull(weakCounterLocation, counter); } RETURN_OBJ(*weakCounterLocation); } // Materialize a weak reference to either null or the real reference. OBJ_GETTER(Konan_WeakReferenceCounter_get, ObjHeader* counter) { ObjHeader** referredAddress = &asWeakReferenceCounter(counter)->referred; #if KONAN_NO_THREADS RETURN_OBJ(*referredAddress); #else auto* weakCounter = asWeakReferenceCounter(counter); RETURN_RESULT_OF(ReadHeapRefLocked, referredAddress, &weakCounter->lock, &weakCounter->cookie); #endif } void WeakReferenceCounterClear(ObjHeader* counter) { ObjHeader** referredAddress = &asWeakReferenceCounter(counter)->referred; // Note, that we don't do UpdateRef here, as reference is weak. #if KONAN_NO_THREADS *referredAddress = nullptr; #else int32_t* lockAddress = &asWeakReferenceCounter(counter)->lock; // Spinlock. lock(lockAddress); *referredAddress = nullptr; unlock(lockAddress); #endif } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Weak.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_WEAK_H #define RUNTIME_WEAK_H #include "Memory.h" extern "C" { // Atomically clears counter object reference. void WeakReferenceCounterClear(ObjHeader* counter); } // extern "C" #endif // RUNTIME_WEAK_H ================================================ FILE: runtime/src/main/cpp/Worker.cpp ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef KONAN_NO_THREADS #define WITH_WORKERS 1 #endif #include #include #include #if WITH_WORKERS #include #include "PthreadUtils.h" #endif #include "Alloc.h" #include "Exceptions.h" #include "KAssert.h" #include "Memory.h" #include "ObjCMMAPI.h" #include "Runtime.h" #include "Types.h" #include "Worker.h" extern "C" { RUNTIME_NORETURN void ThrowWorkerInvalidState(); RUNTIME_NORETURN void ThrowWorkerUnsupported(); OBJ_GETTER(WorkerLaunchpad, KRef); } // extern "C" #if WITH_WORKERS namespace { class Future; enum { INVALID = 0, SCHEDULED = 1, COMPUTED = 2, CANCELLED = 3, THROWN = 4 }; enum { CHECKED = 0, UNCHECKED = 1 }; enum JobKind { JOB_NONE = 0, JOB_TERMINATE = 1, // Order is important in sense that all job kinds after this one is considered // processed for APIs returning request process status. JOB_REGULAR = 2, JOB_EXECUTE_AFTER = 3, }; enum class WorkerKind { kNative, // Workers created using Worker.start public API. kOther, // Any other kind of workers. }; struct Job { enum JobKind kind; union { struct { KRef (*function)(KRef, ObjHeader**); KNativePtr argument; Future* future; KInt transferMode; } regularJob; struct { Future* future; bool waitDelayed; } terminationRequest; struct { KNativePtr operation; uint64_t whenExecute; } executeAfter; }; }; struct JobCompare { bool operator() (const Job& lhs, const Job& rhs) const { RuntimeAssert(lhs.kind == JOB_EXECUTE_AFTER && rhs.kind == JOB_EXECUTE_AFTER, "Must be delayed jobs"); return lhs.executeAfter.whenExecute < rhs.executeAfter.whenExecute; } }; typedef KStdOrderedSet DelayedJobSet; } // namespace class Worker { public: Worker(KInt id, bool errorReporting, KRef customName, WorkerKind kind) : id_(id), kind_(kind), errorReporting_(errorReporting) { name_ = customName != nullptr ? CreateStablePointer(customName) : nullptr; pthread_mutex_init(&lock_, nullptr); pthread_cond_init(&cond_, nullptr); } ~Worker(); void startEventLoop(); void putJob(Job job, bool toFront); void putDelayedJob(Job job); bool waitDelayed(bool blocking); Job getJob(bool blocking); KLong checkDelayedLocked(); bool waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining); JobKind processQueueElement(bool blocking); bool park(KLong timeoutMicroseconds, bool process); KInt id() const { return id_; } bool errorReporting() const { return errorReporting_; } KNativePtr name() const { return name_; } WorkerKind kind() const { return kind_; } pthread_t thread() const { return thread_; } private: KInt id_; WorkerKind kind_; KStdDeque queue_; DelayedJobSet delayed_; // Stable pointer with worker's name. KNativePtr name_; // Lock and condition for waiting on the queue. pthread_mutex_t lock_; pthread_cond_t cond_; // If errors to be reported on console. bool errorReporting_; bool terminated_ = false; pthread_t thread_ = 0; }; #endif // WITH_WORKERS namespace { #if WITH_WORKERS THREAD_LOCAL_VARIABLE Worker* g_worker = nullptr; KNativePtr transfer(ObjHolder* holder, KInt mode) { void* result = CreateStablePointer(holder->obj()); if (!ClearSubgraphReferences(holder->obj(), mode == CHECKED)) { DisposeStablePointer(result); ThrowWorkerInvalidState(); } holder->clear(); return result; } class Locker { public: explicit Locker(pthread_mutex_t* lock) : lock_(lock) { pthread_mutex_lock(lock_); } ~Locker() { pthread_mutex_unlock(lock_); } private: pthread_mutex_t* lock_; }; class Future { public: Future(KInt id) : state_(SCHEDULED), id_(id) { pthread_mutex_init(&lock_, nullptr); pthread_cond_init(&cond_, nullptr); } ~Future() { clear(); pthread_mutex_destroy(&lock_); pthread_cond_destroy(&cond_); } void clear() { Locker locker(&lock_); if (result_ != nullptr) { // No one cared to consume result - dispose it. DisposeStablePointer(result_); result_ = nullptr; } } OBJ_GETTER0(consumeResultUnlocked) { Locker locker(&lock_); while (state_ == SCHEDULED) { pthread_cond_wait(&cond_, &lock_); } // TODO: maybe use message from exception? if (state_ == THROWN) ThrowIllegalStateException(); auto result = AdoptStablePointer(result_, OBJ_RESULT); result_ = nullptr; return result; } void storeResultUnlocked(KNativePtr result, bool ok); void cancelUnlocked(); // Those are called with the lock taken. KInt state() const { return state_; } KInt id() const { return id_; } private: // State of future execution. KInt state_; // Integer id of the future. KInt id_; // Stable pointer with future's result. KNativePtr result_; // Lock and condition for waiting on the future. pthread_mutex_t lock_; pthread_cond_t cond_; }; class State { public: State() { pthread_mutex_init(&lock_, nullptr); pthread_cond_init(&cond_, nullptr); currentWorkerId_ = 1; currentFutureId_ = 1; currentVersion_ = 0; } ~State() { // TODO: some sanity check here? pthread_mutex_destroy(&lock_); pthread_cond_destroy(&cond_); } Worker* addWorkerUnlocked(bool errorReporting, KRef customName, WorkerKind kind) { Worker* worker = nullptr; { Locker locker(&lock_); worker = konanConstructInstance(nextWorkerId(), errorReporting, customName, kind); if (worker == nullptr) return nullptr; workers_[worker->id()] = worker; } GC_RegisterWorker(worker); return worker; } void removeWorkerUnlocked(KInt id) { Locker locker(&lock_); auto it = workers_.find(id); if (it == workers_.end()) return; Worker* worker = it->second; if (worker->kind() == WorkerKind::kNative) { terminating_native_workers_[id] = worker->thread(); } workers_.erase(it); } void destroyWorkerUnlocked(Worker* worker) { { Locker locker(&lock_); auto id = worker->id(); auto it = workers_.find(id); if (it != workers_.end()) { workers_.erase(it); } } GC_UnregisterWorker(worker); konanDestructInstance(worker); } Future* addJobToWorkerUnlocked( KInt id, KNativePtr jobFunction, KNativePtr jobArgument, bool toFront, KInt transferMode) { Future* future = nullptr; Worker* worker = nullptr; Locker locker(&lock_); auto it = workers_.find(id); if (it == workers_.end()) return nullptr; worker = it->second; future = konanConstructInstance(nextFutureId()); futures_[future->id()] = future; Job job; if (jobFunction == nullptr) { job.kind = JOB_TERMINATE; job.terminationRequest.future = future; job.terminationRequest.waitDelayed = !toFront; } else { job.kind = JOB_REGULAR; job.regularJob.function = reinterpret_cast(jobFunction); job.regularJob.argument = jobArgument; job.regularJob.future = future; job.regularJob.transferMode = transferMode; } worker->putJob(job, toFront); return future; } bool executeJobAfterInWorkerUnlocked(KInt id, KRef operation, KLong afterMicroseconds) { Worker* worker = nullptr; Locker locker(&lock_); RuntimeAssert(afterMicroseconds >= 0, "afterMicroseconds cannot be negative"); auto it = workers_.find(id); if (it == workers_.end()) { return false; } worker = it->second; Job job; job.kind = JOB_EXECUTE_AFTER; job.executeAfter.operation = CreateStablePointer(operation); if (afterMicroseconds == 0) { worker->putJob(job, false); } else { job.executeAfter.whenExecute = konan::getTimeMicros() + afterMicroseconds; worker->putDelayedJob(job); } return true; } bool scheduleJobInWorkerUnlocked(KInt id, KNativePtr operationStablePtr) { Worker* worker = nullptr; Locker locker(&lock_); auto it = workers_.find(id); if (it == workers_.end()) { return false; } worker = it->second; Job job; job.kind = JOB_EXECUTE_AFTER; job.executeAfter.operation = operationStablePtr; worker->putJob(job, false); return true; } // Returns `true` if something was indeed processed. bool processQueueUnlocked(KInt id) { // Can only process queue of the current worker. if (::g_worker == nullptr || id != ::g_worker->id()) ThrowWorkerInvalidState(); JobKind kind = ::g_worker->processQueueElement(false); return kind != JOB_NONE && kind != JOB_TERMINATE; } bool parkUnlocked(KInt id, KLong timeoutMicroseconds, KBoolean process) { // Can only park current worker. if (::g_worker == nullptr || id != ::g_worker->id()) ThrowWorkerInvalidState(); return ::g_worker->park(timeoutMicroseconds, process); } KInt stateOfFutureUnlocked(KInt id) { Locker locker(&lock_); auto it = futures_.find(id); if (it == futures_.end()) return INVALID; return it->second->state(); } OBJ_GETTER(consumeFutureUnlocked, KInt id) { Future* future = nullptr; { Locker locker(&lock_); auto it = futures_.find(id); if (it == futures_.end()) ThrowWorkerInvalidState(); future = it->second; } KRef result = future->consumeResultUnlocked(OBJ_RESULT); { Locker locker(&lock_); auto it = futures_.find(id); if (it != futures_.end()) { futures_.erase(it); konanDestructInstance(future); } } return result; } OBJ_GETTER(getWorkerNameUnlocked, KInt id) { ObjHolder nameHolder; { Locker locker(&lock_); auto it = workers_.find(id); if (it == workers_.end()) { ThrowWorkerInvalidState(); } DerefStablePointer(it->second->name(), nameHolder.slot()); } RETURN_OBJ(nameHolder.obj()); } KBoolean waitForAnyFuture(KInt version, KInt millis) { Locker locker(&lock_); if (version != currentVersion_) return false; if (millis < 0) { pthread_cond_wait(&cond_, &lock_); return true; } uint64_t nsDelta = millis * 1000000LL; WaitOnCondVar(&cond_, &lock_, nsDelta); return true; } void signalAnyFuture() { { Locker locker(&lock_); currentVersion_++; } pthread_cond_broadcast(&cond_); } KInt versionToken() { Locker locker(&lock_); return currentVersion_; } // All those called with lock taken. KInt nextWorkerId() { return currentWorkerId_++; } KInt nextFutureId() { return currentFutureId_++; } void destroyWorkerThreadDataUnlocked(KInt id) { Locker locker(&lock_); auto it = terminating_native_workers_.find(id); if (it == terminating_native_workers_.end()) return; // If this worker was not joined, detach it to free resources. pthread_detach(it->second); terminating_native_workers_.erase(it); } template void waitNativeWorkersTerminationUnlocked(bool checkLeaks, F waitForWorker) { KStdVector> workersToWait; { Locker locker(&lock_); if (checkLeaks) { checkNativeWorkersLeakLocked(); } for (auto& kvp : terminating_native_workers_) { RuntimeAssert(!pthread_equal(kvp.second, pthread_self()), "Native worker is joining with itself"); if (waitForWorker(kvp.first)) { workersToWait.push_back(kvp); } } for (auto worker : workersToWait) { terminating_native_workers_.erase(worker.first); } } for (auto worker : workersToWait) { pthread_join(worker.second, nullptr); } } void checkNativeWorkersLeakLocked() { size_t remainingNativeWorkers = 0; for (const auto& kvp : workers_) { Worker* worker = kvp.second; if (worker->kind() == WorkerKind::kNative) { ++remainingNativeWorkers; } } if (remainingNativeWorkers != 0) { konan::consoleErrorf( "Unfinished workers detected, %zu workers leaked!\n" "Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n", remainingNativeWorkers); konan::consoleFlush(); konan::abort(); } } private: pthread_mutex_t lock_; pthread_cond_t cond_; KStdUnorderedMap futures_; KStdUnorderedMap workers_; KStdUnorderedMap terminating_native_workers_; KInt currentWorkerId_; KInt currentFutureId_; KInt currentVersion_; }; State* theState() { static State* state = nullptr; if (state != nullptr) { return state; } State* result = konanConstructInstance(); State* old = __sync_val_compare_and_swap(&state, nullptr, result); if (old != nullptr) { konanDestructInstance(result); // Someone else inited this data. return old; } return state; } void Future::storeResultUnlocked(KNativePtr result, bool ok) { { Locker locker(&lock_); state_ = ok ? COMPUTED : THROWN; result_ = result; // Beware here: although manual clearly says that pthread_cond_broadcast() could be called outside // of the taken lock, it's not on macOS (as of 10.13.1). If moved outside of the lock, // some notifications are missing. pthread_cond_broadcast(&cond_); } theState()->signalAnyFuture(); } void Future::cancelUnlocked() { { Locker locker(&lock_); state_ = CANCELLED; result_ = nullptr; pthread_cond_broadcast(&cond_); } theState()->signalAnyFuture(); } // Defined in RuntimeUtils.kt. extern "C" void ReportUnhandledException(KRef e); KInt startWorker(KBoolean errorReporting, KRef customName) { Worker* worker = theState()->addWorkerUnlocked(errorReporting != 0, customName, WorkerKind::kNative); if (worker == nullptr) return -1; worker->startEventLoop(); return worker->id(); } KInt currentWorker() { if (g_worker == nullptr) ThrowWorkerInvalidState(); return ::g_worker->id(); } KInt execute(KInt id, KInt transferMode, KRef producer, KNativePtr jobFunction) { ObjHolder holder; WorkerLaunchpad(producer, holder.slot()); KNativePtr jobArgument = transfer(&holder, transferMode); Future* future = theState()->addJobToWorkerUnlocked(id, jobFunction, jobArgument, false, transferMode); if (future == nullptr) ThrowWorkerInvalidState(); return future->id(); } void executeAfter(KInt id, KRef job, KLong afterMicroseconds) { if (!theState()->executeJobAfterInWorkerUnlocked(id, job, afterMicroseconds)) ThrowWorkerInvalidState(); } KBoolean processQueue(KInt id) { return theState()->processQueueUnlocked(id); } KBoolean park(KInt id, KLong timeoutMicroseconds, KBoolean process) { return theState()->parkUnlocked(id, timeoutMicroseconds, process); } KInt stateOfFuture(KInt id) { return theState()->stateOfFutureUnlocked(id); } OBJ_GETTER(consumeFuture, KInt id) { RETURN_RESULT_OF(theState()->consumeFutureUnlocked, id); } OBJ_GETTER(getWorkerName, KInt id) { RETURN_RESULT_OF(theState()->getWorkerNameUnlocked, id); } KInt requestTermination(KInt id, KBoolean processScheduledJobs) { Future* future = theState()->addJobToWorkerUnlocked( id, nullptr, nullptr, /* toFront = */ !processScheduledJobs, UNCHECKED); if (future == nullptr) ThrowWorkerInvalidState(); return future->id(); } KBoolean waitForAnyFuture(KInt version, KInt millis) { return theState()->waitForAnyFuture(version, millis); } KInt versionToken() { return theState()->versionToken(); } OBJ_GETTER(attachObjectGraphInternal, KNativePtr stable) { RETURN_RESULT_OF(AdoptStablePointer, stable); } KNativePtr detachObjectGraphInternal(KInt transferMode, KRef producer) { ObjHolder result; WorkerLaunchpad(producer, result.slot()); if (result.obj() != nullptr) { return transfer(&result, transferMode); } else { return nullptr; } } #else KInt startWorker(KBoolean errorReporting, KRef customName) { ThrowWorkerUnsupported(); } KInt stateOfFuture(KInt id) { ThrowWorkerUnsupported(); } KInt execute(KInt id, KInt transferMode, KRef producer, KNativePtr jobFunction) { ThrowWorkerUnsupported(); } void executeAfter(KInt id, KRef job, KLong afterMicroseconds) { ThrowWorkerUnsupported(); } KBoolean processQueue(KInt id) { ThrowWorkerUnsupported(); } KBoolean park(KInt id, KLong timeoutMicroseconds, KBoolean process) { ThrowWorkerUnsupported(); } KInt currentWorker() { ThrowWorkerUnsupported(); } OBJ_GETTER(consumeFuture, KInt id) { ThrowWorkerUnsupported(); } OBJ_GETTER(getWorkerName, KInt id) { ThrowWorkerUnsupported(); } KInt requestTermination(KInt id, KBoolean processScheduledJobs) { ThrowWorkerUnsupported(); } KBoolean waitForAnyFuture(KInt versionToken, KInt millis) { ThrowWorkerUnsupported(); } KInt versionToken() { ThrowWorkerUnsupported(); } OBJ_GETTER(attachObjectGraphInternal, KNativePtr stable) { ThrowWorkerUnsupported(); } KNativePtr detachObjectGraphInternal(KInt transferMode, KRef producer) { ThrowWorkerUnsupported(); } #endif // WITH_WORKERS } // namespace KInt GetWorkerId(Worker* worker) { #if WITH_WORKERS return worker->id(); #else return 0; #endif // WITH_WORKERS } Worker* WorkerInit(KBoolean errorReporting) { #if WITH_WORKERS if (::g_worker != nullptr) return ::g_worker; Worker* worker = theState()->addWorkerUnlocked(errorReporting != 0, nullptr, WorkerKind::kOther); ::g_worker = worker; return worker; #else return nullptr; #endif // WITH_WORKERS } void WorkerDeinit(Worker* worker) { #if WITH_WORKERS ::g_worker = nullptr; theState()->destroyWorkerUnlocked(worker); #endif // WITH_WORKERS } void WorkerDestroyThreadDataIfNeeded(KInt id) { #if WITH_WORKERS theState()->destroyWorkerThreadDataUnlocked(id); #endif } void WaitNativeWorkersTermination() { #if WITH_WORKERS theState()->waitNativeWorkersTerminationUnlocked(true, [](KInt worker) { return true; }); #endif } void WaitNativeWorkerTermination(KInt id) { #if WITH_WORKERS theState()->waitNativeWorkersTerminationUnlocked(false, [id](KInt worker) { return worker == id; }); #endif } bool WorkerSchedule(KInt id, KNativePtr jobStablePtr) { #if WITH_WORKERS return theState()->scheduleJobInWorkerUnlocked(id, jobStablePtr); #else return false; #endif // WITH_WORKERS } #if WITH_WORKERS Worker::~Worker() { // Cleanup jobs in the queue. for (auto job : queue_) { switch (job.kind) { case JOB_REGULAR: DisposeStablePointer(job.regularJob.argument); job.regularJob.future->cancelUnlocked(); break; case JOB_EXECUTE_AFTER: { // TODO: what do we do here? Shall we execute them? DisposeStablePointer(job.executeAfter.operation); break; } case JOB_TERMINATE: { // TODO: any more processing here? job.terminationRequest.future->cancelUnlocked(); break; } case JOB_NONE: { RuntimeCheck(false, "Cannot be in queue"); break; } } } for (auto job : delayed_) { RuntimeAssert(job.kind == JOB_EXECUTE_AFTER, "Must be delayed"); DisposeStablePointer(job.executeAfter.operation); } if (name_ != nullptr) DisposeStablePointer(name_); pthread_mutex_destroy(&lock_); pthread_cond_destroy(&cond_); } namespace { void* workerRoutine(void* argument) { Worker* worker = reinterpret_cast(argument); // Kotlin_initRuntimeIfNeeded calls WorkerInit that needs // to see there's already a worker created for this thread. ::g_worker = worker; Kotlin_initRuntimeIfNeeded(); do { if (worker->processQueueElement(true) == JOB_TERMINATE) break; } while (true); return nullptr; } } // namespace void Worker::startEventLoop() { pthread_create(&thread_, nullptr, workerRoutine, this); } void Worker::putJob(Job job, bool toFront) { Locker locker(&lock_); if (toFront) queue_.push_front(job); else queue_.push_back(job); pthread_cond_signal(&cond_); } void Worker::putDelayedJob(Job job) { Locker locker(&lock_); delayed_.insert(job); pthread_cond_signal(&cond_); } bool Worker::waitDelayed(bool blocking) { Locker locker(&lock_); if (delayed_.size() == 0) return false; if (blocking) waitForQueueLocked(-1, nullptr); return true; } Job Worker::getJob(bool blocking) { Locker locker(&lock_); RuntimeAssert(!terminated_, "Must not be terminated"); if (queue_.size() == 0 && !blocking) return Job { .kind = JOB_NONE }; waitForQueueLocked(-1, nullptr); auto result = queue_.front(); queue_.pop_front(); return result; } KLong Worker::checkDelayedLocked() { if (delayed_.size() == 0) { return -1; } auto it = delayed_.begin(); auto job = *it; RuntimeAssert(job.kind == JOB_EXECUTE_AFTER, "Must be delayed job"); auto now = konan::getTimeMicros(); if (job.executeAfter.whenExecute <= now) { delayed_.erase(it); queue_.push_back(job); return 0; } else { return job.executeAfter.whenExecute - now; } } bool Worker::waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining) { while (queue_.size() == 0) { KLong closestToRunMicroseconds = checkDelayedLocked(); if (closestToRunMicroseconds == 0) { continue; } if (timeoutMicroseconds >= 0) { closestToRunMicroseconds = (timeoutMicroseconds < closestToRunMicroseconds || closestToRunMicroseconds < 0) ? timeoutMicroseconds : closestToRunMicroseconds; } if (closestToRunMicroseconds == 0) { // Just no wait at all here. } else if (closestToRunMicroseconds > 0) { // Protect from potential overflow, cutting at 10_000_000 seconds, aka 115 days. if (closestToRunMicroseconds > 10LL * 1000 * 1000 * 1000 * 1000) closestToRunMicroseconds = 10LL * 1000 * 1000 * 1000 * 1000; uint64_t nsDelta = closestToRunMicroseconds * 1000LL; uint64_t microsecondsPassed = 0; WaitOnCondVar(&cond_, &lock_, nsDelta, remaining ? µsecondsPassed : nullptr); if (remaining) { *remaining = timeoutMicroseconds - microsecondsPassed; } } else { pthread_cond_wait(&cond_, &lock_); if (remaining) *remaining = 0; } if (timeoutMicroseconds >= 0) return queue_.size() != 0; } return true; } bool Worker::park(KLong timeoutMicroseconds, bool process) { { Locker locker(&lock_); if (terminated_) { return false; } auto arrived = false; KLong remaining = timeoutMicroseconds; do { arrived = waitForQueueLocked(remaining, &remaining); } while (remaining > 0 && !arrived); if (!process) { return arrived; } if (!arrived) { return false; } } return processQueueElement(false) >= JOB_REGULAR; } JobKind Worker::processQueueElement(bool blocking) { GC_CollectorCallback(this); ObjHolder argumentHolder; ObjHolder resultHolder; if (terminated_) return JOB_TERMINATE; Job job = getJob(blocking); switch (job.kind) { case JOB_NONE: { break; } case JOB_TERMINATE: { if (job.terminationRequest.waitDelayed) { if (waitDelayed(blocking)) { putJob(job, false); return JOB_NONE; } } terminated_ = true; // Termination request, remove the worker and notify the future. theState()->removeWorkerUnlocked(id()); job.terminationRequest.future->storeResultUnlocked(nullptr, true); break; } case JOB_EXECUTE_AFTER: { ObjHolder operationHolder, dummyHolder; KRef obj = DerefStablePointer(job.executeAfter.operation, operationHolder.slot()); try { #if KONAN_OBJC_INTEROP konan::AutoreleasePool autoreleasePool; #endif WorkerLaunchpad(obj, dummyHolder.slot()); } catch (ExceptionObjHolder& e) { if (errorReporting()) ReportUnhandledException(e.GetExceptionObject()); } DisposeStablePointer(job.executeAfter.operation); break; } case JOB_REGULAR: { KRef argument = AdoptStablePointer(job.regularJob.argument, argumentHolder.slot()); KNativePtr result = nullptr; bool ok = true; try { #if KONAN_OBJC_INTEROP konan::AutoreleasePool autoreleasePool; #endif job.regularJob.function(argument, resultHolder.slot()); argumentHolder.clear(); // Transfer the result. result = transfer(&resultHolder, job.regularJob.transferMode); } catch (ExceptionObjHolder& e) { ok = false; if (errorReporting()) ReportUnhandledException(e.GetExceptionObject()); } // Notify the future. job.regularJob.future->storeResultUnlocked(result, ok); break; } default: { RuntimeCheck(false, "Must be exhaustive"); } } return job.kind; } #endif // WITH_WORKERS extern "C" { KInt Kotlin_Worker_startInternal(KBoolean noErrorReporting, KRef customName) { return startWorker(noErrorReporting, customName); } KInt Kotlin_Worker_currentInternal() { return currentWorker(); } KInt Kotlin_Worker_requestTerminationWorkerInternal(KInt id, KBoolean processScheduledJobs) { return requestTermination(id, processScheduledJobs); } KInt Kotlin_Worker_executeInternal(KInt id, KInt transferMode, KRef producer, KNativePtr job) { return execute(id, transferMode, producer, job); } void Kotlin_Worker_executeAfterInternal(KInt id, KRef job, KLong afterMicroseconds) { executeAfter(id, job, afterMicroseconds); } KBoolean Kotlin_Worker_processQueueInternal(KInt id) { return processQueue(id); } KBoolean Kotlin_Worker_parkInternal(KInt id, KLong timeoutMicroseconds, KBoolean process) { return park(id, timeoutMicroseconds, process); } OBJ_GETTER(Kotlin_Worker_getNameInternal, KInt id) { RETURN_RESULT_OF(getWorkerName, id); } KInt Kotlin_Worker_stateOfFuture(KInt id) { return stateOfFuture(id); } OBJ_GETTER(Kotlin_Worker_consumeFuture, KInt id) { RETURN_RESULT_OF(consumeFuture, id); } KBoolean Kotlin_Worker_waitForAnyFuture(KInt versionToken, KInt millis) { return waitForAnyFuture(versionToken, millis); } KInt Kotlin_Worker_versionToken() { return versionToken(); } OBJ_GETTER(Kotlin_Worker_attachObjectGraphInternal, KNativePtr stable) { RETURN_RESULT_OF(attachObjectGraphInternal, stable); } KNativePtr Kotlin_Worker_detachObjectGraphInternal(KInt transferMode, KRef producer) { return detachObjectGraphInternal(transferMode, producer); } void Kotlin_Worker_freezeInternal(KRef object) { if (object != nullptr) FreezeSubgraph(object); } KBoolean Kotlin_Worker_isFrozenInternal(KRef object) { return object == nullptr || isPermanentOrFrozen(object); } void Kotlin_Worker_ensureNeverFrozen(KRef object) { EnsureNeverFrozen(object); } void Kotlin_Worker_waitTermination(KInt id) { WaitNativeWorkerTermination(id); } } // extern "C" ================================================ FILE: runtime/src/main/cpp/Worker.h ================================================ #ifndef RUNTIME_WORKER_H #define RUNTIME_WORKER_H #include "Common.h" #include "Types.h" class Worker; KInt GetWorkerId(Worker* worker); Worker* WorkerInit(KBoolean errorReporting); void WorkerDeinit(Worker* worker); // Clean up all associated thread state, if this was a native worker. void WorkerDestroyThreadDataIfNeeded(KInt id); // Wait until all terminating native workers finish termination. Expected to be called at most once. void WaitNativeWorkersTermination(); // Wait until terminating native worker `id` finishes termination. Expected to be called at most once for each worker. void WaitNativeWorkerTermination(KInt id); // Schedule the job without the result. bool WorkerSchedule(KInt id, KNativePtr jobStablePtr); #endif // RUNTIME_WORKER_H ================================================ FILE: runtime/src/main/cpp/WorkerBoundReference.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "WorkerBoundReference.h" #include "Alloc.h" #include "Memory.h" #include "MemorySharedRefs.hpp" namespace { struct WorkerBoundReference { ObjHeader header; KRefSharedHolder* holder; }; WorkerBoundReference* asWorkerBoundReference(KRef thiz) { return reinterpret_cast(thiz); } } // namespace RUNTIME_NOTHROW void DisposeWorkerBoundReference(KRef thiz) { // DisposeSharedRef is only called when all references to thiz are gone. // Can be null if WorkerBoundReference wasn't frozen. if (auto* holder = asWorkerBoundReference(thiz)->holder) { holder->dispose(); konanDestructInstance(holder); } } // Defined in WorkerBoundReference.kt extern "C" void Kotlin_WorkerBoundReference_freezeHook(KRef thiz); RUNTIME_NOTHROW void WorkerBoundReferenceFreezeHook(KRef thiz) { Kotlin_WorkerBoundReference_freezeHook(thiz); } extern "C" { KNativePtr Kotlin_WorkerBoundReference_create(KRef value) { auto* holder = konanConstructInstance(); holder->init(value); return holder; } OBJ_GETTER(Kotlin_WorkerBoundReference_deref, KNativePtr holder) { RETURN_OBJ(reinterpret_cast(holder)->ref()); } OBJ_GETTER(Kotlin_WorkerBoundReference_describe, KNativePtr holder) { RETURN_RESULT_OF0(reinterpret_cast(holder)->describe); } } ================================================ FILE: runtime/src/main/cpp/WorkerBoundReference.h ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_SHAREDREF_H #define RUNTIME_SHAREDREF_H #include "Common.h" #include "Types.h" RUNTIME_NOTHROW void DisposeWorkerBoundReference(KRef thiz); RUNTIME_NOTHROW void WorkerBoundReferenceFreezeHook(KRef thiz); #endif // RUNTIME_SHAREDREF_H ================================================ FILE: runtime/src/main/cpp/dlmalloc/malloc.cpp ================================================ // Uses GNU extension on null pointer arithmetic. #pragma clang diagnostic ignored "-Wnull-pointer-arithmetic" /* This is a version (aka dlmalloc) of malloc/free/realloc written by Doug Lea and released to the public domain, as explained at http://creativecommons.org/publicdomain/zero/1.0/ Send questions, comments, complaints, performance data, etc to dl@cs.oswego.edu * Version 2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea Note: There may be an updated version of this malloc obtainable at ftp://gee.cs.oswego.edu/pub/misc/malloc.c Check before installing! * Quickstart This library is all in one file to simplify the most common usage: ftp it, compile it (-O3), and link it into another program. All of the compile-time options default to reasonable values for use on most platforms. You might later want to step through various compile-time and dynamic tuning options. For convenience, an include file for code using this malloc is at: ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h You don't really need this .h file unless you call functions not defined in your system include files. The .h file contains only the excerpts from this file needed for using this malloc on ANSI C/C++ systems, so long as you haven't changed compile-time options about naming and tuning parameters. If you do, then you can create your own malloc.h that does include all settings by cutting at the point indicated below. Note that you may already by default be using a C library containing a malloc that is based on some version of this malloc (for example in linux). You might still want to use the one in this file to customize settings or to avoid overheads associated with library versions. * Vital statistics: Supported pointer/size_t representation: 4 or 8 bytes size_t MUST be an unsigned type of the same width as pointers. (If you are using an ancient system that declares size_t as a signed type, or need it to be a different width than pointers, you can use a previous release of this malloc (e.g. 2.7.2) supporting these.) Alignment: 8 bytes (minimum) This suffices for nearly all current machines and C compilers. However, you can define MALLOC_ALIGNMENT to be wider than this if necessary (up to 128bytes), at the expense of using more space. Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) 8 or 16 bytes (if 8byte sizes) Each malloced chunk has a hidden word of overhead holding size and status information, and additional cross-check word if FOOTERS is defined. Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) 8-byte ptrs: 32 bytes (including overhead) Even a request for zero bytes (i.e., malloc(0)) returns a pointer to something of the minimum allocatable size. The maximum overhead wastage (i.e., number of extra bytes allocated than were requested in malloc) is less than or equal to the minimum size, except for requests >= mmap_threshold that are serviced via mmap(), where the worst case wastage is about 32 bytes plus the remainder from a system page (the minimal mmap unit); typically 4096 or 8192 bytes. Security: static-safe; optionally more or less The "security" of malloc refers to the ability of malicious code to accentuate the effects of errors (for example, freeing space that is not currently malloc'ed or overwriting past the ends of chunks) in code that calls malloc. This malloc guarantees not to modify any memory locations below the base of heap, i.e., static variables, even in the presence of usage errors. The routines additionally detect most improper frees and reallocs. All this holds as long as the static bookkeeping for malloc itself is not corrupted by some other means. This is only one aspect of security -- these checks do not, and cannot, detect all possible programming errors. If FOOTERS is defined nonzero, then each allocated chunk carries an additional check word to verify that it was malloced from its space. These check words are the same within each execution of a program using malloc, but differ across executions, so externally crafted fake chunks cannot be freed. This improves security by rejecting frees/reallocs that could corrupt heap memory, in addition to the checks preventing writes to statics that are always on. This may further improve security at the expense of time and space overhead. (Note that FOOTERS may also be worth using with MSPACES.) By default detected errors cause the program to abort (calling "abort()"). You can override this to instead proceed past errors by defining PROCEED_ON_ERROR. In this case, a bad free has no effect, and a malloc that encounters a bad address caused by user overwrites will ignore the bad address by dropping pointers and indices to all known memory. This may be appropriate for programs that should continue if at all possible in the face of programming errors, although they may run out of memory because dropped memory is never reclaimed. If you don't like either of these options, you can define CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything else. And if if you are sure that your program using malloc has no errors or vulnerabilities, you can define INSECURE to 1, which might (or might not) provide a small performance improvement. It is also possible to limit the maximum total allocatable space, using malloc_set_footprint_limit. This is not designed as a security feature in itself (calls to set limits are not screened or privileged), but may be useful as one aspect of a secure implementation. Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero When USE_LOCKS is defined, each public call to malloc, free, etc is surrounded with a lock. By default, this uses a plain pthread mutex, win32 critical section, or a spin-lock if if available for the platform and not disabled by setting USE_SPIN_LOCKS=0. However, if USE_RECURSIVE_LOCKS is defined, recursive versions are used instead (which are not required for base functionality but may be needed in layered extensions). Using a global lock is not especially fast, and can be a major bottleneck. It is designed only to provide minimal protection in concurrent environments, and to provide a basis for extensions. If you are using malloc in a concurrent program, consider instead using nedmalloc (http://www.nedprod.com/programs/portable/nedmalloc/) or ptmalloc (See http://www.malloc.de), which are derived from versions of this malloc. System requirements: Any combination of MORECORE and/or MMAP/MUNMAP This malloc can use unix sbrk or any emulation (invoked using the CALL_MORECORE macro) and/or mmap/munmap or any emulation (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system memory. On most unix systems, it tends to work best if both MORECORE and MMAP are enabled. On Win32, it uses emulations based on VirtualAlloc. It also uses common C library functions like memset. Compliance: I believe it is compliant with the Single Unix Specification (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably others as well. * Overview of algorithms This is not the fastest, most space-conserving, most portable, or most tunable malloc ever written. However it is among the fastest while also being among the most space-conserving, portable and tunable. Consistent balance across these factors results in a good general-purpose allocator for malloc-intensive programs. In most ways, this malloc is a best-fit allocator. Generally, it chooses the best-fitting existing chunk for a request, with ties broken in approximately least-recently-used order. (This strategy normally maintains low fragmentation.) However, for requests less than 256bytes, it deviates from best-fit when there is not an exactly fitting available chunk by preferring to use space adjacent to that used for the previous small request, as well as by breaking ties in approximately most-recently-used order. (These enhance locality of series of small allocations.) And for very large requests (>= 256Kb by default), it relies on system memory mapping facilities, if supported. (This helps avoid carrying around and possibly fragmenting memory used only for large chunks.) All operations (except malloc_stats and mallinfo) have execution times that are bounded by a constant factor of the number of bits in a size_t, not counting any clearing in calloc or copying in realloc, or actions surrounding MORECORE and MMAP that have times proportional to the number of non-contiguous regions returned by system allocation routines, which is often just 1. In real-time applications, you can optionally suppress segment traversals using NO_SEGMENT_TRAVERSAL, which assures bounded execution even when system allocators return non-contiguous spaces, at the typical expense of carrying around more memory and increased fragmentation. The implementation is not very modular and seriously overuses macros. Perhaps someday all C compilers will do as good a job inlining modular code as can now be done by brute-force expansion, but now, enough of them seem not to. Some compilers issue a lot of warnings about code that is dead/unreachable only on some platforms, and also about intentional uses of negation on unsigned types. All known cases of each can be ignored. For a longer but out of date high-level description, see http://gee.cs.oswego.edu/dl/html/malloc.html * MSPACES If MSPACES is defined, then in addition to malloc, free, etc., this file also defines mspace_malloc, mspace_free, etc. These are versions of malloc routines that take an "mspace" argument obtained using create_mspace, to control all internal bookkeeping. If ONLY_MSPACES is defined, only these versions are compiled. So if you would like to use this allocator for only some allocations, and your system malloc for others, you can compile with ONLY_MSPACES and then do something like... static mspace mymspace = create_mspace(0,0); // for example #define mymalloc(bytes) mspace_malloc(mymspace, bytes) (Note: If you only need one instance of an mspace, you can instead use "USE_DL_PREFIX" to relabel the global malloc.) You can similarly create thread-local allocators by storing mspaces as thread-locals. For example: static __thread mspace tlms = 0; void* tlmalloc(size_t bytes) { if (tlms == 0) tlms = create_mspace(0, 0); return mspace_malloc(tlms, bytes); } void tlfree(void* mem) { mspace_free(tlms, mem); } Unless FOOTERS is defined, each mspace is completely independent. You cannot allocate from one and free to another (although conformance is only weakly checked, so usage errors are not always caught). If FOOTERS is defined, then each chunk carries around a tag indicating its originating mspace, and frees are directed to their originating spaces. Normally, this requires use of locks. ------------------------- Compile-time options --------------------------- Be careful in setting #define values for numerical constants of type size_t. On some systems, literal values are not automatically extended to size_t precision unless they are explicitly casted. You can also use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. WIN32 default: defined if _WIN32 defined Defining WIN32 sets up defaults for MS environment and compilers. Otherwise defaults are for unix. Beware that there seem to be some cases where this malloc might not be a pure drop-in replacement for Win32 malloc: Random-looking failures from Win32 GDI API's (eg; SetDIBits()) may be due to bugs in some video driver implementations when pixel buffers are malloc()ed, and the region spans more than one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) default granularity, pixel buffers may straddle virtual allocation regions more often than when using the Microsoft allocator. You can avoid this by using VirtualAlloc() and VirtualFree() for all pixel buffers rather than using malloc(). If this is not possible, recompile this malloc with a larger DEFAULT_GRANULARITY. Note: in cases where MSC and gcc (cygwin) are known to differ on WIN32, conditions use _MSC_VER to distinguish them. DLMALLOC_EXPORT default: extern Defines how public APIs are declared. If you want to export via a Windows DLL, you might define this as #define DLMALLOC_EXPORT extern __declspec(dllexport) If you want a POSIX ELF shared object, you might use #define DLMALLOC_EXPORT extern __attribute__((visibility("default"))) MALLOC_ALIGNMENT default: (size_t)(2 * sizeof(void *)) Controls the minimum alignment for malloc'ed chunks. It must be a power of two and at least 8, even on machines for which smaller alignments would suffice. It may be defined as larger than this though. Note however that code and data structures are optimized for the case of 8-byte alignment. MSPACES default: 0 (false) If true, compile in support for independent allocation spaces. This is only supported if HAVE_MMAP is true. ONLY_MSPACES default: 0 (false) If true, only compile in mspace versions, not regular versions. USE_LOCKS default: 0 (false) Causes each call to each public routine to be surrounded with pthread or WIN32 mutex lock/unlock. (If set true, this can be overridden on a per-mspace basis for mspace versions.) If set to a non-zero value other than 1, locks are used, but their implementation is left out, so lock functions must be supplied manually, as described below. USE_SPIN_LOCKS default: 1 iff USE_LOCKS and spin locks available If true, uses custom spin locks for locking. This is currently supported only gcc >= 4.1, older gccs on x86 platforms, and recent MS compilers. Otherwise, posix locks or win32 critical sections are used. USE_RECURSIVE_LOCKS default: not defined If defined nonzero, uses recursive (aka reentrant) locks, otherwise uses plain mutexes. This is not required for malloc proper, but may be needed for layered allocators such as nedmalloc. LOCK_AT_FORK default: not defined If defined nonzero, performs pthread_atfork upon initialization to initialize child lock while holding parent lock. The implementation assumes that pthread locks (not custom locks) are being used. In other cases, you may need to customize the implementation. FOOTERS default: 0 If true, provide extra checking and dispatching by placing information in the footers of allocated chunks. This adds space and time overhead. INSECURE default: 0 If true, omit checks for usage errors and heap space overwrites. USE_DL_PREFIX default: NOT defined Causes compiler to prefix all public routines with the string 'dl'. This can be useful when you only want to use this malloc in one part of a program, using your regular system malloc elsewhere. MALLOC_INSPECT_ALL default: NOT defined If defined, compiles malloc_inspect_all and mspace_inspect_all, that perform traversal of all heap space. Unless access to these functions is otherwise restricted, you probably do not want to include them in secure implementations. ABORT default: defined as abort() Defines how to abort on failed checks. On most systems, a failed check cannot die with an "assert" or even print an informative message, because the underlying print routines in turn call malloc, which will fail again. Generally, the best policy is to simply call abort(). It's not very useful to do more than this because many errors due to overwriting will show up as address faults (null, odd addresses etc) rather than malloc-triggered checks, so will also abort. Also, most compilers know that abort() does not return, so can better optimize code conditionally calling it. PROCEED_ON_ERROR default: defined as 0 (false) Controls whether detected bad addresses cause them to bypassed rather than aborting. If set, detected bad arguments to free and realloc are ignored. And all bookkeeping information is zeroed out upon a detected overwrite of freed heap space, thus losing the ability to ever return it from malloc again, but enabling the application to proceed. If PROCEED_ON_ERROR is defined, the static variable malloc_corruption_error_count is compiled in and can be examined to see if errors have occurred. This option generates slower code than the default abort policy. DEBUG default: NOT defined The DEBUG setting is mainly intended for people trying to modify this code or diagnose problems when porting to new platforms. However, it may also be able to better isolate user errors than just using runtime checks. The assertions in the check routines spell out in more detail the assumptions and invariants underlying the algorithms. The checking is fairly extensive, and will slow down execution noticeably. Calling malloc_stats or mallinfo with DEBUG set will attempt to check every non-mmapped allocated and free chunk in the course of computing the summaries. ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) Debugging assertion failures can be nearly impossible if your version of the assert macro causes malloc to be called, which will lead to a cascade of further failures, blowing the runtime stack. ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), which will usually make debugging easier. MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 The action to take before "return 0" when malloc fails to be able to return memory because there is none available. HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES True if this system supports sbrk or an emulation of it. MORECORE default: sbrk The name of the sbrk-style system routine to call to obtain more memory. See below for guidance on writing custom MORECORE functions. The type of the argument to sbrk/MORECORE varies across systems. It cannot be size_t, because it supports negative arguments, so it is normally the signed type of the same width as size_t (sometimes declared as "intptr_t"). It doesn't much matter though. Internally, we only call it with arguments less than half the max value of a size_t, which should work across all reasonable possibilities, although sometimes generating compiler warnings. MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE If true, take advantage of fact that consecutive calls to MORECORE with positive arguments always return contiguous increasing addresses. This is true of unix sbrk. It does not hurt too much to set it true anyway, since malloc copes with non-contiguities. Setting it false when definitely non-contiguous saves time and possibly wasted space it would take to discover this though. MORECORE_CANNOT_TRIM default: NOT defined True if MORECORE cannot release space back to the system when given negative arguments. This is generally necessary only if you are using a hand-crafted MORECORE function that cannot handle negative arguments. NO_SEGMENT_TRAVERSAL default: 0 If non-zero, suppresses traversals of memory segments returned by either MORECORE or CALL_MMAP. This disables merging of segments that are contiguous, and selectively releasing them to the OS if unused, but bounds execution times. HAVE_MMAP default: 1 (true) True if this system supports mmap or an emulation of it. If so, and HAVE_MORECORE is not true, MMAP is used for all system allocation. If set and HAVE_MORECORE is true as well, MMAP is primarily used to directly allocate very large blocks. It is also used as a backup strategy in cases where MORECORE fails to provide space from system. Note: A single call to MUNMAP is assumed to be able to unmap memory that may have be allocated using multiple calls to MMAP, so long as they are adjacent. HAVE_MREMAP default: 1 on linux, else 0 If true realloc() uses mremap() to re-allocate large blocks and extend or shrink allocation spaces. MMAP_CLEARS default: 1 except on WINCE. True if mmap clears memory so calloc doesn't need to. This is true for standard unix mmap using /dev/zero and on WIN32 except for WINCE. USE_BUILTIN_FFS default: 0 (i.e., not used) Causes malloc to use the builtin ffs() function to compute indices. Some compilers may recognize and intrinsify ffs to be faster than the supplied C version. Also, the case of x86 using gcc is special-cased to an asm instruction, so is already as fast as it can be, and so this setting has no effect. Similarly for Win32 under recent MS compilers. (On most x86s, the asm version is only slightly faster than the C version.) malloc_getpagesize default: derive from system includes, or 4096. The system page size. To the extent possible, this malloc manages memory from the system in page-size units. This may be (and usually is) a function rather than a constant. This is ignored if WIN32, where page size is determined using getSystemInfo during initialization. USE_DEV_RANDOM default: 0 (i.e., not used) Causes malloc to use /dev/random to initialize secure magic seed for stamping footers. Otherwise, the current time is used. NO_MALLINFO default: 0 If defined, don't compile "mallinfo". This can be a simple way of dealing with mismatches between system declarations and those in this file. MALLINFO_FIELD_TYPE default: size_t The type of the fields in the mallinfo struct. This was originally defined as "int" in SVID etc, but is more usefully defined as size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set NO_MALLOC_STATS default: 0 If defined, don't compile "malloc_stats". This avoids calls to fprintf and bringing in stdio dependencies you might not want. REALLOC_ZERO_BYTES_FREES default: not defined This should be set if a call to realloc with zero bytes should be the same as a call to free. Some people think it should. Otherwise, since this malloc returns a unique pointer for malloc(0), so does realloc(p, 0). LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H default: NOT defined unless on WIN32 Define these if your system does not have these header files. You might need to manually insert some of the declarations they provide. DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, system_info.dwAllocationGranularity in WIN32, otherwise 64K. Also settable using mallopt(M_GRANULARITY, x) The unit for allocating and deallocating memory from the system. On most systems with contiguous MORECORE, there is no reason to make this more than a page. However, systems with MMAP tend to either require or encourage larger granularities. You can increase this value to prevent system allocation functions to be called so often, especially if they are slow. The value must be at least one page and must be a power of two. Setting to 0 causes initialization to either page size or win32 region size. (Note: In previous versions of malloc, the equivalent of this option was called "TOP_PAD") DEFAULT_TRIM_THRESHOLD default: 2MB Also settable using mallopt(M_TRIM_THRESHOLD, x) The maximum amount of unused top-most memory to keep before releasing via malloc_trim in free(). Automatic trimming is mainly useful in long-lived programs using contiguous MORECORE. Because trimming via sbrk can be slow on some systems, and can sometimes be wasteful (in cases where programs immediately afterward allocate more large chunks) the value should be high enough so that your overall system performance would improve by releasing this much memory. As a rough guide, you might set to a value close to the average size of a process (program) running on your system. Releasing this much memory would allow such a process to run in memory. Generally, it is worth tuning trim thresholds when a program undergoes phases where several large chunks are allocated and released in ways that can reuse each other's storage, perhaps mixed with phases where there are no such chunks at all. The trim value must be greater than page size to have any useful effect. To disable trimming completely, you can set to MAX_SIZE_T. Note that the trick some people use of mallocing a huge space and then freeing it at program startup, in an attempt to reserve system memory, doesn't have the intended effect under automatic trimming, since that memory will immediately be returned to the system. DEFAULT_MMAP_THRESHOLD default: 256K Also settable using mallopt(M_MMAP_THRESHOLD, x) The request size threshold for using MMAP to directly service a request. Requests of at least this size that cannot be allocated using already-existing space will be serviced via mmap. (If enough normal freed space already exists it is used instead.) Using mmap segregates relatively large chunks of memory so that they can be individually obtained and released from the host system. A request serviced through mmap is never reused by any other request (at least not directly; the system may just so happen to remap successive requests to the same locations). Segregating space in this way has the benefits that: Mmapped space can always be individually released back to the system, which helps keep the system level memory demands of a long-lived program low. Also, mapped memory doesn't become `locked' between other chunks, as can happen with normally allocated chunks, which means that even trimming via malloc_trim would not release them. However, it has the disadvantage that the space cannot be reclaimed, consolidated, and then used to service later requests, as happens with normal chunks. The advantages of mmap nearly always outweigh disadvantages for "large" chunks, but the value of "large" may vary across systems. The default is an empirically derived value that works well in most systems. You can disable mmap by setting to MAX_SIZE_T. MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP The number of consolidated frees between checks to release unused segments when freeing. When using non-contiguous segments, especially with multiple mspaces, checking only for topmost space doesn't always suffice to trigger trimming. To compensate for this, free() will, with a period of MAX_RELEASE_CHECK_RATE (or the current number of segments, if greater) try to release unused segments to the OS when freeing chunks that result in consolidation. The best value for this parameter is a compromise between slowing down frees with relatively costly checks that rarely trigger versus holding on to unused memory. To effectively disable, set to MAX_SIZE_T. This may lead to a very slight speed improvement at the expense of carrying around more memory. */ #if KONAN_INTERNAL_DLMALLOC /**** Start of Konan-specific dlmalloc configuration. ****/ #define USE_DL_PREFIX 1 #if KONAN_WASM #define USE_LOCKS 0 #define LACKS_TIME_H 1 #define NO_MALLOC_STATS 1 #define HAVE_MMAP 0 // don't try to allocate large chunks of memory using mmap(). // It will go to malloc->calloc->sbrk->morecore chain anyways. #else #define USE_LOCKS 1 #endif #define DLMALLOC_EXPORT extern "C" #define HAVE_MORECORE 1 #define MORECORE konan::moreCore #define malloc_getpagesize konan::getpagesize() namespace konan { extern void* moreCore(int size); extern long getpagesize(); } // namespace konan /**** End of Konan-specific dlmalloc configuration. ****/ /* Version identifier to allow people to support multiple versions */ #ifndef DLMALLOC_VERSION #define DLMALLOC_VERSION 20806 #endif /* DLMALLOC_VERSION */ #ifndef DLMALLOC_EXPORT #define DLMALLOC_EXPORT extern #endif #ifndef WIN32 #ifdef _WIN32 #define WIN32 1 #endif /* _WIN32 */ #ifdef _WIN32_WCE #define LACKS_FCNTL_H #define WIN32 1 #endif /* _WIN32_WCE */ #endif /* WIN32 */ #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include #include #define HAVE_MMAP 1 #define HAVE_MORECORE 0 #define LACKS_UNISTD_H #define LACKS_SYS_PARAM_H #define LACKS_SYS_MMAN_H #define LACKS_STRING_H #define LACKS_STRINGS_H #define LACKS_SYS_TYPES_H #define LACKS_ERRNO_H #define LACKS_SCHED_H #ifndef MALLOC_FAILURE_ACTION #define MALLOC_FAILURE_ACTION #endif /* MALLOC_FAILURE_ACTION */ #ifndef MMAP_CLEARS #ifdef _WIN32_WCE /* WINCE reportedly does not clear */ #define MMAP_CLEARS 0 #else #define MMAP_CLEARS 1 #endif /* _WIN32_WCE */ #endif /*MMAP_CLEARS */ #endif /* WIN32 */ #if defined(DARWIN) || defined(_DARWIN) /* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ #ifndef HAVE_MORECORE #define HAVE_MORECORE 0 #define HAVE_MMAP 1 /* OSX allocators provide 16 byte alignment */ #ifndef MALLOC_ALIGNMENT #define MALLOC_ALIGNMENT ((size_t)16U) #endif #endif /* HAVE_MORECORE */ #endif /* DARWIN */ #ifndef LACKS_SYS_TYPES_H #include /* For size_t */ #endif /* LACKS_SYS_TYPES_H */ /* The maximum possible size_t value has all bits set */ #define MAX_SIZE_T (~(size_t)0) #ifndef USE_LOCKS /* ensure true if spin or recursive locks set */ #define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \ (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0)) #endif /* USE_LOCKS */ #if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */ #if ((defined(__GNUC__) && \ ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) || \ defined(__i386__) || defined(__x86_64__))) || \ (defined(_MSC_VER) && _MSC_VER>=1310)) #ifndef USE_SPIN_LOCKS #define USE_SPIN_LOCKS 1 #endif /* USE_SPIN_LOCKS */ #elif USE_SPIN_LOCKS #error "USE_SPIN_LOCKS defined without implementation" #endif /* ... locks available... */ #elif !defined(USE_SPIN_LOCKS) #define USE_SPIN_LOCKS 0 #endif /* USE_LOCKS */ #ifndef ONLY_MSPACES #define ONLY_MSPACES 0 #endif /* ONLY_MSPACES */ #ifndef MSPACES #if ONLY_MSPACES #define MSPACES 1 #else /* ONLY_MSPACES */ #define MSPACES 0 #endif /* ONLY_MSPACES */ #endif /* MSPACES */ #ifndef MALLOC_ALIGNMENT #define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *))) #endif /* MALLOC_ALIGNMENT */ #ifndef FOOTERS #define FOOTERS 0 #endif /* FOOTERS */ #ifndef ABORT #define ABORT abort() #endif /* ABORT */ #ifndef ABORT_ON_ASSERT_FAILURE #define ABORT_ON_ASSERT_FAILURE 1 #endif /* ABORT_ON_ASSERT_FAILURE */ #ifndef PROCEED_ON_ERROR #define PROCEED_ON_ERROR 0 #endif /* PROCEED_ON_ERROR */ #ifndef INSECURE #define INSECURE 0 #endif /* INSECURE */ #ifndef MALLOC_INSPECT_ALL #define MALLOC_INSPECT_ALL 0 #endif /* MALLOC_INSPECT_ALL */ #ifndef HAVE_MMAP #define HAVE_MMAP 1 #endif /* HAVE_MMAP */ #ifndef MMAP_CLEARS #define MMAP_CLEARS 1 #endif /* MMAP_CLEARS */ #ifndef HAVE_MREMAP #ifdef linux #define HAVE_MREMAP 1 #define _GNU_SOURCE /* Turns on mremap() definition */ #else /* linux */ #define HAVE_MREMAP 0 #endif /* linux */ #endif /* HAVE_MREMAP */ #ifndef MALLOC_FAILURE_ACTION #define MALLOC_FAILURE_ACTION errno = ENOMEM; #endif /* MALLOC_FAILURE_ACTION */ #ifndef HAVE_MORECORE #if ONLY_MSPACES #define HAVE_MORECORE 0 #else /* ONLY_MSPACES */ #define HAVE_MORECORE 1 #endif /* ONLY_MSPACES */ #endif /* HAVE_MORECORE */ #if !HAVE_MORECORE #define MORECORE_CONTIGUOUS 0 #else /* !HAVE_MORECORE */ #define MORECORE_DEFAULT sbrk #ifndef MORECORE_CONTIGUOUS #define MORECORE_CONTIGUOUS 1 #endif /* MORECORE_CONTIGUOUS */ #endif /* HAVE_MORECORE */ #ifndef DEFAULT_GRANULARITY #if (MORECORE_CONTIGUOUS || defined(WIN32)) #define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ #else /* MORECORE_CONTIGUOUS */ #define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) #endif /* MORECORE_CONTIGUOUS */ #endif /* DEFAULT_GRANULARITY */ #ifndef DEFAULT_TRIM_THRESHOLD #ifndef MORECORE_CANNOT_TRIM #define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) #else /* MORECORE_CANNOT_TRIM */ #define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T #endif /* MORECORE_CANNOT_TRIM */ #endif /* DEFAULT_TRIM_THRESHOLD */ #ifndef DEFAULT_MMAP_THRESHOLD #if HAVE_MMAP #define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) #else /* HAVE_MMAP */ #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T #endif /* HAVE_MMAP */ #endif /* DEFAULT_MMAP_THRESHOLD */ #ifndef MAX_RELEASE_CHECK_RATE #if HAVE_MMAP #define MAX_RELEASE_CHECK_RATE 4095 #else #define MAX_RELEASE_CHECK_RATE MAX_SIZE_T #endif /* HAVE_MMAP */ #endif /* MAX_RELEASE_CHECK_RATE */ #ifndef USE_BUILTIN_FFS #define USE_BUILTIN_FFS 0 #endif /* USE_BUILTIN_FFS */ #ifndef USE_DEV_RANDOM #define USE_DEV_RANDOM 0 #endif /* USE_DEV_RANDOM */ #ifndef NO_MALLINFO #define NO_MALLINFO 0 #endif /* NO_MALLINFO */ #ifndef MALLINFO_FIELD_TYPE #define MALLINFO_FIELD_TYPE size_t #endif /* MALLINFO_FIELD_TYPE */ #ifndef NO_MALLOC_STATS #define NO_MALLOC_STATS 0 #endif /* NO_MALLOC_STATS */ #ifndef NO_SEGMENT_TRAVERSAL #define NO_SEGMENT_TRAVERSAL 0 #endif /* NO_SEGMENT_TRAVERSAL */ /* mallopt tuning options. SVID/XPG defines four standard parameter numbers for mallopt, normally defined in malloc.h. None of these are used in this malloc, so setting them has no effect. But this malloc does support the following options. */ #define M_TRIM_THRESHOLD (-1) #define M_GRANULARITY (-2) #define M_MMAP_THRESHOLD (-3) /* ------------------------ Mallinfo declarations ------------------------ */ #if !NO_MALLINFO /* This version of malloc supports the standard SVID/XPG mallinfo routine that returns a struct containing usage properties and statistics. It should work on any system that has a /usr/include/malloc.h defining struct mallinfo. The main declaration needed is the mallinfo struct that is returned (by-copy) by mallinfo(). The malloinfo struct contains a bunch of fields that are not even meaningful in this version of malloc. These fields are are instead filled by mallinfo() with other numbers that might be of interest. HAVE_USR_INCLUDE_MALLOC_H should be set if you have a /usr/include/malloc.h file that includes a declaration of struct mallinfo. If so, it is included; else a compliant version is declared below. These must be precisely the same for mallinfo() to work. The original SVID version of this struct, defined on most systems with mallinfo, declares all fields as ints. But some others define as unsigned long. If your system defines the fields using a type of different width than listed here, you MUST #include your system version and #define HAVE_USR_INCLUDE_MALLOC_H. */ /* #define HAVE_USR_INCLUDE_MALLOC_H */ #ifdef HAVE_USR_INCLUDE_MALLOC_H #include "/usr/include/malloc.h" #else /* HAVE_USR_INCLUDE_MALLOC_H */ #ifndef STRUCT_MALLINFO_DECLARED /* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */ #define _STRUCT_MALLINFO #define STRUCT_MALLINFO_DECLARED 1 struct mallinfo { MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ MALLINFO_FIELD_TYPE smblks; /* always 0 */ MALLINFO_FIELD_TYPE hblks; /* always 0 */ MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ MALLINFO_FIELD_TYPE fordblks; /* total free space */ MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ }; #endif /* STRUCT_MALLINFO_DECLARED */ #endif /* HAVE_USR_INCLUDE_MALLOC_H */ #endif /* NO_MALLINFO */ /* Try to persuade compilers to inline. The most critical functions for inlining are defined as macros, so these aren't used for them. */ #ifndef FORCEINLINE #if defined(__GNUC__) #define FORCEINLINE __inline __attribute__ ((always_inline)) #elif defined(_MSC_VER) #define FORCEINLINE __forceinline #endif #endif #ifndef NOINLINE #if defined(__GNUC__) #define NOINLINE __attribute__ ((noinline)) #elif defined(_MSC_VER) #define NOINLINE __declspec(noinline) #else #define NOINLINE #endif #endif #ifdef __cplusplus extern "C" { #ifndef FORCEINLINE #define FORCEINLINE inline #endif #endif /* __cplusplus */ #ifndef FORCEINLINE #define FORCEINLINE #endif #if !ONLY_MSPACES /* ------------------- Declarations of public routines ------------------- */ #ifndef USE_DL_PREFIX #define dlcalloc calloc #define dlfree free #define dlmalloc malloc #define dlmemalign memalign #define dlposix_memalign posix_memalign #define dlrealloc realloc #define dlrealloc_in_place realloc_in_place #define dlvalloc valloc #define dlpvalloc pvalloc #define dlmallinfo mallinfo #define dlmallopt mallopt #define dlmalloc_trim malloc_trim #define dlmalloc_stats malloc_stats #define dlmalloc_usable_size malloc_usable_size #define dlmalloc_footprint malloc_footprint #define dlmalloc_max_footprint malloc_max_footprint #define dlmalloc_footprint_limit malloc_footprint_limit #define dlmalloc_set_footprint_limit malloc_set_footprint_limit #define dlmalloc_inspect_all malloc_inspect_all #define dlindependent_calloc independent_calloc #define dlindependent_comalloc independent_comalloc #define dlbulk_free bulk_free #endif /* USE_DL_PREFIX */ /* malloc(size_t n) Returns a pointer to a newly allocated chunk of at least n bytes, or null if no space is available, in which case errno is set to ENOMEM on ANSI C systems. If n is zero, malloc returns a minimum-sized chunk. (The minimum size is 16 bytes on most 32bit systems, and 32 bytes on 64bit systems.) Note that size_t is an unsigned type, so calls with arguments that would be negative if signed are interpreted as requests for huge amounts of space, which will often fail. The maximum supported value of n differs across systems, but is in all cases less than the maximum representable value of a size_t. */ DLMALLOC_EXPORT void* dlmalloc(size_t); /* free(void* p) Releases the chunk of memory pointed to by p, that had been previously allocated using malloc or a related routine such as realloc. It has no effect if p is null. If p was not malloced or already freed, free(p) will by default cause the current program to abort. */ DLMALLOC_EXPORT void dlfree(void*); /* calloc(size_t n_elements, size_t element_size); Returns a pointer to n_elements * element_size bytes, with all locations set to zero. */ DLMALLOC_EXPORT void* dlcalloc(size_t, size_t); /* realloc(void* p, size_t n) Returns a pointer to a chunk of size n that contains the same data as does chunk p up to the minimum of (n, p's size) bytes, or null if no space is available. The returned pointer may or may not be the same as p. The algorithm prefers extending p in most cases when possible, otherwise it employs the equivalent of a malloc-copy-free sequence. If p is null, realloc is equivalent to malloc. If space is not available, realloc returns null, errno is set (if on ANSI) and p is NOT freed. if n is for fewer bytes than already held by p, the newly unused space is lopped off and freed if possible. realloc with a size argument of zero (re)allocates a minimum-sized chunk. The old unix realloc convention of allowing the last-free'd chunk to be used as an argument to realloc is not supported. */ DLMALLOC_EXPORT void* dlrealloc(void*, size_t); /* realloc_in_place(void* p, size_t n) Resizes the space allocated for p to size n, only if this can be done without moving p (i.e., only if there is adjacent space available if n is greater than p's current allocated size, or n is less than or equal to p's size). This may be used instead of plain realloc if an alternative allocation strategy is needed upon failure to expand space; for example, reallocation of a buffer that must be memory-aligned or cleared. You can use realloc_in_place to trigger these alternatives only when needed. Returns p if successful; otherwise null. */ DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t); /* memalign(size_t alignment, size_t n); Returns a pointer to a newly allocated chunk of n bytes, aligned in accord with the alignment argument. The alignment argument should be a power of two. If the argument is not a power of two, the nearest greater power is used. 8-byte alignment is guaranteed by normal malloc calls, so don't bother calling memalign with an argument of 8 or less. Overreliance on memalign is a sure way to fragment space. */ DLMALLOC_EXPORT void* dlmemalign(size_t, size_t); /* int posix_memalign(void** pp, size_t alignment, size_t n); Allocates a chunk of n bytes, aligned in accord with the alignment argument. Differs from memalign only in that it (1) assigns the allocated memory to *pp rather than returning it, (2) fails and returns EINVAL if the alignment is not a power of two (3) fails and returns ENOMEM if memory cannot be allocated. */ DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t); /* valloc(size_t n); Equivalent to memalign(pagesize, n), where pagesize is the page size of the system. If the pagesize is unknown, 4096 is used. */ DLMALLOC_EXPORT void* dlvalloc(size_t); /* mallopt(int parameter_number, int parameter_value) Sets tunable parameters The format is to provide a (parameter-number, parameter-value) pair. mallopt then sets the corresponding parameter to the argument value if it can (i.e., so long as the value is meaningful), and returns 1 if successful else 0. To workaround the fact that mallopt is specified to use int, not size_t parameters, the value -1 is specially treated as the maximum unsigned size_t value. SVID/XPG/ANSI defines four standard param numbers for mallopt, normally defined in malloc.h. None of these are use in this malloc, so setting them has no effect. But this malloc also supports other options in mallopt. See below for details. Briefly, supported parameters are as follows (listed defaults are for "typical" configurations). Symbol param # default allowed param values M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) M_GRANULARITY -2 page size any power of 2 >= page size M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) */ DLMALLOC_EXPORT int dlmallopt(int, int); /* malloc_footprint(); Returns the number of bytes obtained from the system. The total number of bytes allocated by malloc, realloc etc., is less than this value. Unlike mallinfo, this function returns only a precomputed result, so can be called frequently to monitor memory consumption. Even if locks are otherwise defined, this function does not use them, so results might not be up to date. */ DLMALLOC_EXPORT size_t dlmalloc_footprint(void); /* malloc_max_footprint(); Returns the maximum number of bytes obtained from the system. This value will be greater than current footprint if deallocated space has been reclaimed by the system. The peak number of bytes allocated by malloc, realloc etc., is less than this value. Unlike mallinfo, this function returns only a precomputed result, so can be called frequently to monitor memory consumption. Even if locks are otherwise defined, this function does not use them, so results might not be up to date. */ DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void); /* malloc_footprint_limit(); Returns the number of bytes that the heap is allowed to obtain from the system, returning the last value returned by malloc_set_footprint_limit, or the maximum size_t value if never set. The returned value reflects a permission. There is no guarantee that this number of bytes can actually be obtained from the system. */ DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(); /* malloc_set_footprint_limit(); Sets the maximum number of bytes to obtain from the system, causing failure returns from malloc and related functions upon attempts to exceed this value. The argument value may be subject to page rounding to an enforceable limit; this actual value is returned. Using an argument of the maximum possible size_t effectively disables checks. If the argument is less than or equal to the current malloc_footprint, then all future allocations that require additional system memory will fail. However, invocation cannot retroactively deallocate existing used memory. */ DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes); #if MALLOC_INSPECT_ALL /* malloc_inspect_all(void(*handler)(void *start, void *end, size_t used_bytes, void* callback_arg), void* arg); Traverses the heap and calls the given handler for each managed region, skipping all bytes that are (or may be) used for bookkeeping purposes. Traversal does not include include chunks that have been directly memory mapped. Each reported region begins at the start address, and continues up to but not including the end address. The first used_bytes of the region contain allocated data. If used_bytes is zero, the region is unallocated. The handler is invoked with the given callback argument. If locks are defined, they are held during the entire traversal. It is a bad idea to invoke other malloc functions from within the handler. For example, to count the number of in-use chunks with size greater than 1000, you could write: static int count = 0; void count_chunks(void* start, void* end, size_t used, void* arg) { if (used >= 1000) ++count; } then: malloc_inspect_all(count_chunks, NULL); malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. */ DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*), void* arg); #endif /* MALLOC_INSPECT_ALL */ #if !NO_MALLINFO /* mallinfo() Returns (by copy) a struct containing various summary statistics: arena: current total non-mmapped bytes allocated from system ordblks: the number of free chunks smblks: always zero. hblks: current number of mmapped regions hblkhd: total bytes held in mmapped regions usmblks: the maximum total allocated space. This will be greater than current total if trimming has occurred. fsmblks: always zero uordblks: current total allocated space (normal or mmapped) fordblks: total free space keepcost: the maximum number of bytes that could ideally be released back to system via malloc_trim. ("ideally" means that it ignores page restrictions etc.) Because these fields are ints, but internal bookkeeping may be kept as longs, the reported values may wrap around zero and thus be inaccurate. */ DLMALLOC_EXPORT struct mallinfo dlmallinfo(void); #endif /* NO_MALLINFO */ /* independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); independent_calloc is similar to calloc, but instead of returning a single cleared space, it returns an array of pointers to n_elements independent elements that can hold contents of size elem_size, each of which starts out cleared, and can be independently freed, realloc'ed etc. The elements are guaranteed to be adjacently allocated (this is not guaranteed to occur with multiple callocs or mallocs), which may also improve cache locality in some applications. The "chunks" argument is optional (i.e., may be null, which is probably the most typical usage). If it is null, the returned array is itself dynamically allocated and should also be freed when it is no longer needed. Otherwise, the chunks array must be of at least n_elements in length. It is filled in with the pointers to the chunks. In either case, independent_calloc returns this pointer array, or null if the allocation failed. If n_elements is zero and "chunks" is null, it returns a chunk representing an array with zero elements (which should be freed if not wanted). Each element must be freed when it is no longer needed. This can be done all at once using bulk_free. independent_calloc simplifies and speeds up implementations of many kinds of pools. It may also be useful when constructing large data structures that initially have a fixed number of fixed-sized nodes, but the number is not known at compile time, and some of the nodes may later need to be freed. For example: struct Node { int item; struct Node* next; }; struct Node* build_list() { struct Node** pool; int n = read_number_of_nodes_needed(); if (n <= 0) return 0; pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); if (pool == 0) die(); // organize into a linked list... struct Node* first = pool[0]; for (i = 0; i < n-1; ++i) pool[i]->next = pool[i+1]; free(pool); // Can now free the array (or not, if it is needed later) return first; } */ DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**); /* independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); independent_comalloc allocates, all at once, a set of n_elements chunks with sizes indicated in the "sizes" array. It returns an array of pointers to these elements, each of which can be independently freed, realloc'ed etc. The elements are guaranteed to be adjacently allocated (this is not guaranteed to occur with multiple callocs or mallocs), which may also improve cache locality in some applications. The "chunks" argument is optional (i.e., may be null). If it is null the returned array is itself dynamically allocated and should also be freed when it is no longer needed. Otherwise, the chunks array must be of at least n_elements in length. It is filled in with the pointers to the chunks. In either case, independent_comalloc returns this pointer array, or null if the allocation failed. If n_elements is zero and chunks is null, it returns a chunk representing an array with zero elements (which should be freed if not wanted). Each element must be freed when it is no longer needed. This can be done all at once using bulk_free. independent_comallac differs from independent_calloc in that each element may have a different size, and also that it does not automatically clear elements. independent_comalloc can be used to speed up allocation in cases where several structs or objects must always be allocated at the same time. For example: struct Head { ... } struct Foot { ... } void send_message(char* msg) { int msglen = strlen(msg); size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; void* chunks[3]; if (independent_comalloc(3, sizes, chunks) == 0) die(); struct Head* head = (struct Head*)(chunks[0]); char* body = (char*)(chunks[1]); struct Foot* foot = (struct Foot*)(chunks[2]); // ... } In general though, independent_comalloc is worth using only for larger values of n_elements. For small values, you probably won't detect enough difference from series of malloc calls to bother. Overuse of independent_comalloc can increase overall memory usage, since it cannot reuse existing noncontiguous small chunks that might be available for some of the elements. */ DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**); /* bulk_free(void* array[], size_t n_elements) Frees and clears (sets to null) each non-null pointer in the given array. This is likely to be faster than freeing them one-by-one. If footers are used, pointers that have been allocated in different mspaces are not freed or cleared, and the count of all such pointers is returned. For large arrays of pointers with poor locality, it may be worthwhile to sort this array before calling bulk_free. */ DLMALLOC_EXPORT size_t dlbulk_free(void**, size_t n_elements); /* pvalloc(size_t n); Equivalent to valloc(minimum-page-that-holds(n)), that is, round up n to nearest pagesize. */ DLMALLOC_EXPORT void* dlpvalloc(size_t); /* malloc_trim(size_t pad); If possible, gives memory back to the system (via negative arguments to sbrk) if there is unused memory at the `high' end of the malloc pool or in unused MMAP segments. You can call this after freeing large blocks of memory to potentially reduce the system-level memory requirements of a program. However, it cannot guarantee to reduce memory. Under some allocation patterns, some large free blocks of memory will be locked between two used chunks, so they cannot be given back to the system. The `pad' argument to malloc_trim represents the amount of free trailing space to leave untrimmed. If this argument is zero, only the minimum amount of memory to maintain internal data structures will be left. Non-zero arguments can be supplied to maintain enough trailing space to service future expected allocations without having to re-obtain memory from the system. Malloc_trim returns 1 if it actually released any memory, else 0. */ DLMALLOC_EXPORT int dlmalloc_trim(size_t); /* malloc_stats(); Prints on stderr the amount of space obtained from the system (both via sbrk and mmap), the maximum amount (which may be more than current if malloc_trim and/or munmap got called), and the current number of bytes allocated via malloc (or realloc, etc) but not yet freed. Note that this is the number of bytes allocated, not the number requested. It will be larger than the number requested because of alignment and bookkeeping overhead. Because it includes alignment wastage as being in use, this figure may be greater than zero even when no user-level chunks are allocated. The reported current and maximum system memory can be inaccurate if a program makes other calls to system memory allocation functions (normally sbrk) outside of malloc. malloc_stats prints only the most commonly interesting statistics. More information can be obtained by calling mallinfo. */ DLMALLOC_EXPORT void dlmalloc_stats(void); /* malloc_usable_size(void* p); Returns the number of bytes you can actually use in an allocated chunk, which may be more than you requested (although often not) due to alignment and minimum size constraints. You can use this many bytes without worrying about overwriting other allocated objects. This is not a particularly great programming practice. malloc_usable_size can be more useful in debugging and assertions, for example: p = malloc(n); assert(malloc_usable_size(p) >= 256); */ size_t dlmalloc_usable_size(void*); #endif /* ONLY_MSPACES */ #if MSPACES /* mspace is an opaque type representing an independent region of space that supports mspace_malloc, etc. */ typedef void* mspace; /* create_mspace creates and returns a new independent space with the given initial capacity, or, if 0, the default granularity size. It returns null if there is no system memory available to create the space. If argument locked is non-zero, the space uses a separate lock to control access. The capacity of the space will grow dynamically as needed to service mspace_malloc requests. You can control the sizes of incremental increases of this space by compiling with a different DEFAULT_GRANULARITY or dynamically setting with mallopt(M_GRANULARITY, value). */ DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked); /* destroy_mspace destroys the given space, and attempts to return all of its memory back to the system, returning the total number of bytes freed. After destruction, the results of access to all memory used by the space become undefined. */ DLMALLOC_EXPORT size_t destroy_mspace(mspace msp); /* create_mspace_with_base uses the memory supplied as the initial base of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this space is used for bookkeeping, so the capacity must be at least this large. (Otherwise 0 is returned.) When this initial space is exhausted, additional memory will be obtained from the system. Destroying this space will deallocate all additionally allocated space (if possible) but not the initial base. */ DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked); /* mspace_track_large_chunks controls whether requests for large chunks are allocated in their own untracked mmapped regions, separate from others in this mspace. By default large chunks are not tracked, which reduces fragmentation. However, such chunks are not necessarily released to the system upon destroy_mspace. Enabling tracking by setting to true may increase fragmentation, but avoids leakage when relying on destroy_mspace to release all memory allocated using this space. The function returns the previous setting. */ DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable); /* mspace_malloc behaves as malloc, but operates within the given space. */ DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes); /* mspace_free behaves as free, but operates within the given space. If compiled with FOOTERS==1, mspace_free is not actually needed. free may be called instead of mspace_free because freed chunks from any space are handled by their originating spaces. */ DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem); /* mspace_realloc behaves as realloc, but operates within the given space. If compiled with FOOTERS==1, mspace_realloc is not actually needed. realloc may be called instead of mspace_realloc because realloced chunks from any space are handled by their originating spaces. */ DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize); /* mspace_calloc behaves as calloc, but operates within the given space. */ DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); /* mspace_memalign behaves as memalign, but operates within the given space. */ DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); /* mspace_independent_calloc behaves as independent_calloc, but operates within the given space. */ DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements, size_t elem_size, void* chunks[]); /* mspace_independent_comalloc behaves as independent_comalloc, but operates within the given space. */ DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements, size_t sizes[], void* chunks[]); /* mspace_footprint() returns the number of bytes obtained from the system for this space. */ DLMALLOC_EXPORT size_t mspace_footprint(mspace msp); /* mspace_max_footprint() returns the peak number of bytes obtained from the system for this space. */ DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp); #if !NO_MALLINFO /* mspace_mallinfo behaves as mallinfo, but reports properties of the given space. */ DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp); #endif /* NO_MALLINFO */ /* malloc_usable_size(void* p) behaves the same as malloc_usable_size; */ DLMALLOC_EXPORT size_t mspace_usable_size(const void* mem); /* mspace_malloc_stats behaves as malloc_stats, but reports properties of the given space. */ DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp); /* mspace_trim behaves as malloc_trim, but operates within the given space. */ DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad); /* An alias for mallopt. */ DLMALLOC_EXPORT int mspace_mallopt(int, int); #endif /* MSPACES */ #ifdef __cplusplus } /* end of extern "C" */ #endif /* __cplusplus */ /* ======================================================================== To make a fully customizable malloc.h header file, cut everything above this line, put into file malloc.h, edit to suit, and #include it on the next line, as well as in programs that use this malloc. ======================================================================== */ /* #include "malloc.h" */ /*------------------------------ internal #includes ---------------------- */ #ifdef _MSC_VER #pragma warning( disable : 4146 ) /* no "unsigned" warnings */ #endif /* _MSC_VER */ #if !NO_MALLOC_STATS #include /* for printing in malloc_stats */ #endif /* NO_MALLOC_STATS */ #ifndef LACKS_ERRNO_H #include /* for MALLOC_FAILURE_ACTION */ #endif /* LACKS_ERRNO_H */ #ifdef DEBUG #if ABORT_ON_ASSERT_FAILURE #undef assert #define assert(x) if(!(x)) ABORT #else /* ABORT_ON_ASSERT_FAILURE */ #include #endif /* ABORT_ON_ASSERT_FAILURE */ #else /* DEBUG */ #ifndef assert #define assert(x) #endif #define DEBUG 0 #endif /* DEBUG */ #if !defined(WIN32) && !defined(LACKS_TIME_H) #include /* for magic initialization */ #endif /* WIN32 */ #ifndef LACKS_STDLIB_H #include /* for abort() */ #endif /* LACKS_STDLIB_H */ #ifndef LACKS_STRING_H #include /* for memset etc */ #endif /* LACKS_STRING_H */ #if USE_BUILTIN_FFS #ifndef LACKS_STRINGS_H #include /* for ffs */ #endif /* LACKS_STRINGS_H */ #endif /* USE_BUILTIN_FFS */ #if HAVE_MMAP #ifndef LACKS_SYS_MMAN_H /* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ #if (defined(linux) && !defined(__USE_GNU)) #define __USE_GNU 1 #include /* for mmap */ #undef __USE_GNU #else #include /* for mmap */ #endif /* linux */ #endif /* LACKS_SYS_MMAN_H */ #ifndef LACKS_FCNTL_H #include #endif /* LACKS_FCNTL_H */ #endif /* HAVE_MMAP */ #ifndef LACKS_UNISTD_H #include /* for sbrk, sysconf */ #else /* LACKS_UNISTD_H */ #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) extern void* sbrk(ptrdiff_t); #endif /* FreeBSD etc */ #endif /* LACKS_UNISTD_H */ /* Declarations for locking */ #if USE_LOCKS #ifndef WIN32 #if defined (__SVR4) && defined (__sun) /* solaris */ #include #elif !defined(LACKS_SCHED_H) #include #endif /* solaris or LACKS_SCHED_H */ #if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS #include #endif /* USE_RECURSIVE_LOCKS ... */ #elif defined(_MSC_VER) #ifndef _M_AMD64 /* These are already defined on AMD64 builds */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _M_AMD64 */ #pragma intrinsic (_InterlockedCompareExchange) #pragma intrinsic (_InterlockedExchange) #define interlockedcompareexchange _InterlockedCompareExchange #define interlockedexchange _InterlockedExchange #elif defined(WIN32) && defined(__GNUC__) #define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b) #define interlockedexchange __sync_lock_test_and_set #endif /* Win32 */ #else /* USE_LOCKS */ #endif /* USE_LOCKS */ #ifndef LOCK_AT_FORK #define LOCK_AT_FORK 0 #endif /* Declarations for bit scanning on win32 */ #if defined(_MSC_VER) && _MSC_VER>=1300 #ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ unsigned char _BitScanForward(unsigned long *index, unsigned long mask); unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); #ifdef __cplusplus } #endif /* __cplusplus */ #define BitScanForward _BitScanForward #define BitScanReverse _BitScanReverse #pragma intrinsic(_BitScanForward) #pragma intrinsic(_BitScanReverse) #endif /* BitScanForward */ #endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ #ifndef WIN32 #ifndef malloc_getpagesize # ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ # ifndef _SC_PAGE_SIZE # define _SC_PAGE_SIZE _SC_PAGESIZE # endif # endif # ifdef _SC_PAGE_SIZE # define malloc_getpagesize sysconf(_SC_PAGE_SIZE) # else # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) extern size_t getpagesize(); # define malloc_getpagesize getpagesize() # else # ifdef WIN32 /* use supplied emulation of getpagesize */ # define malloc_getpagesize getpagesize() # else # ifndef LACKS_SYS_PARAM_H # include # endif # ifdef EXEC_PAGESIZE # define malloc_getpagesize EXEC_PAGESIZE # else # ifdef NBPG # ifndef CLSIZE # define malloc_getpagesize NBPG # else # define malloc_getpagesize (NBPG * CLSIZE) # endif # else # ifdef NBPC # define malloc_getpagesize NBPC # else # ifdef PAGESIZE # define malloc_getpagesize PAGESIZE # else /* just guess */ # define malloc_getpagesize ((size_t)4096U) # endif # endif # endif # endif # endif # endif # endif #endif #endif /* ------------------- size_t and alignment properties -------------------- */ /* The byte and bit size of a size_t */ #define SIZE_T_SIZE (sizeof(size_t)) #define SIZE_T_BITSIZE (sizeof(size_t) << 3) /* Some constants coerced to size_t */ /* Annoying but necessary to avoid errors on some platforms */ #define SIZE_T_ZERO ((size_t)0) #define SIZE_T_ONE ((size_t)1) #define SIZE_T_TWO ((size_t)2) #define SIZE_T_FOUR ((size_t)4) #define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) #define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) #define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) #define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) /* The bit mask value corresponding to MALLOC_ALIGNMENT */ #define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) /* True if address a has acceptable alignment */ #define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) /* the number of bytes to offset an address to align it */ #define align_offset(A)\ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) /* -------------------------- MMAP preliminaries ------------------------- */ /* If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and checks to fail so compiler optimizer can delete code rather than using so many "#if"s. */ /* MORECORE and MMAP must return MFAIL on failure */ #define MFAIL ((void*)(MAX_SIZE_T)) #define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ #if HAVE_MMAP #ifndef WIN32 #define MUNMAP_DEFAULT(a, s) munmap((a), (s)) #define MMAP_PROT (PROT_READ|PROT_WRITE) #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) #define MAP_ANONYMOUS MAP_ANON #endif /* MAP_ANON */ #ifdef MAP_ANONYMOUS #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) #define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) #else /* MAP_ANONYMOUS */ /* Nearly all versions of mmap support MAP_ANONYMOUS, so the following is unlikely to be needed, but is supplied just in case. */ #define MMAP_FLAGS (MAP_PRIVATE) static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ #define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ (dev_zero_fd = open("/dev/zero", O_RDWR), \ mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) #endif /* MAP_ANONYMOUS */ #define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) #else /* WIN32 */ /* Win32 MMAP via VirtualAlloc */ static FORCEINLINE void* win32mmap(size_t size) { void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); return (ptr != 0)? ptr: MFAIL; } /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ static FORCEINLINE void* win32direct_mmap(size_t size) { void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE); return (ptr != 0)? ptr: MFAIL; } /* This function supports releasing coalesed segments */ static FORCEINLINE int win32munmap(void* ptr, size_t size) { MEMORY_BASIC_INFORMATION minfo; char* cptr = (char*)ptr; while (size) { if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) return -1; if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || minfo.State != MEM_COMMIT || minfo.RegionSize > size) return -1; if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) return -1; cptr += minfo.RegionSize; size -= minfo.RegionSize; } return 0; } #define MMAP_DEFAULT(s) win32mmap(s) #define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) #define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) #endif /* WIN32 */ #endif /* HAVE_MMAP */ #if HAVE_MREMAP #ifndef WIN32 #define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) #endif /* WIN32 */ #endif /* HAVE_MREMAP */ /** * Define CALL_MORECORE */ #if HAVE_MORECORE #ifdef MORECORE #define CALL_MORECORE(S) MORECORE(S) #else /* MORECORE */ #define CALL_MORECORE(S) MORECORE_DEFAULT(S) #endif /* MORECORE */ #else /* HAVE_MORECORE */ #define CALL_MORECORE(S) MFAIL #endif /* HAVE_MORECORE */ /** * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP */ #if HAVE_MMAP #define USE_MMAP_BIT (SIZE_T_ONE) #ifdef MMAP #define CALL_MMAP(s) MMAP(s) #else /* MMAP */ #define CALL_MMAP(s) MMAP_DEFAULT(s) #endif /* MMAP */ #ifdef MUNMAP #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) #else /* MUNMAP */ #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) #endif /* MUNMAP */ #ifdef DIRECT_MMAP #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) #else /* DIRECT_MMAP */ #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) #endif /* DIRECT_MMAP */ #else /* HAVE_MMAP */ #define USE_MMAP_BIT (SIZE_T_ZERO) #define MMAP(s) MFAIL #define MUNMAP(a, s) (-1) #define DIRECT_MMAP(s) MFAIL #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) #define CALL_MMAP(s) MMAP(s) #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) #endif /* HAVE_MMAP */ /** * Define CALL_MREMAP */ #if HAVE_MMAP && HAVE_MREMAP #ifdef MREMAP #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) #else /* MREMAP */ #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) #endif /* MREMAP */ #else /* HAVE_MMAP && HAVE_MREMAP */ #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL #endif /* HAVE_MMAP && HAVE_MREMAP */ /* mstate bit set if continguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ #define EXTERN_BIT (8U) /* --------------------------- Lock preliminaries ------------------------ */ /* When locks are defined, there is one global lock, plus one per-mspace lock. The global lock_ensures that mparams.magic and other unique mparams values are initialized only once. It also protects sequences of calls to MORECORE. In many cases sys_alloc requires two calls, that should not be interleaved with calls by other threads. This does not protect against direct calls to MORECORE by other threads not using this lock, so there is still code to cope the best we can on interference. Per-mspace locks surround calls to malloc, free, etc. By default, locks are simple non-reentrant mutexes. Because lock-protected regions generally have bounded times, it is OK to use the supplied simple spinlocks. Spinlocks are likely to improve performance for lightly contended applications, but worsen performance under heavy contention. If USE_LOCKS is > 1, the definitions of lock routines here are bypassed, in which case you will need to define the type MLOCK_T, and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and TRY_LOCK. You must also declare a static MLOCK_T malloc_global_mutex = { initialization values };. */ #if !USE_LOCKS #define USE_LOCK_BIT (0U) #define INITIAL_LOCK(l) (0) #define DESTROY_LOCK(l) (0) #define ACQUIRE_MALLOC_GLOBAL_LOCK() #define RELEASE_MALLOC_GLOBAL_LOCK() #else #if USE_LOCKS > 1 /* ----------------------- User-defined locks ------------------------ */ /* Define your own lock implementation here */ /* #define INITIAL_LOCK(lk) ... */ /* #define DESTROY_LOCK(lk) ... */ /* #define ACQUIRE_LOCK(lk) ... */ /* #define RELEASE_LOCK(lk) ... */ /* #define TRY_LOCK(lk) ... */ /* static MLOCK_T malloc_global_mutex = ... */ #elif USE_SPIN_LOCKS /* First, define CAS_LOCK and CLEAR_LOCK on ints */ /* Note CAS_LOCK defined to return 0 on success */ #if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) #define CAS_LOCK(sl) __sync_lock_test_and_set(sl, 1) #define CLEAR_LOCK(sl) __sync_lock_release(sl) #elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) /* Custom spin locks for older gcc on x86 */ static FORCEINLINE int x86_cas_lock(int *sl) { int ret; int val = 1; int cmp = 0; __asm__ __volatile__ ("lock; cmpxchgl %1, %2" : "=a" (ret) : "r" (val), "m" (*(sl)), "0"(cmp) : "memory", "cc"); return ret; } static FORCEINLINE void x86_clear_lock(int* sl) { assert(*sl != 0); int prev = 0; int ret; __asm__ __volatile__ ("lock; xchgl %0, %1" : "=r" (ret) : "m" (*(sl)), "0"(prev) : "memory"); } #define CAS_LOCK(sl) x86_cas_lock(sl) #define CLEAR_LOCK(sl) x86_clear_lock(sl) #else /* Win32 MSC */ #define CAS_LOCK(sl) interlockedexchange(sl, (LONG)1) #define CLEAR_LOCK(sl) interlockedexchange (sl, (LONG)0) #endif /* ... gcc spins locks ... */ /* How to yield for a spin lock */ #define SPINS_PER_YIELD 63 #if defined(_MSC_VER) #define SLEEP_EX_DURATION 50 /* delay for yield/sleep */ #define SPIN_LOCK_YIELD SleepEx(SLEEP_EX_DURATION, FALSE) #elif defined (__SVR4) && defined (__sun) /* solaris */ #define SPIN_LOCK_YIELD thr_yield(); #elif !defined(LACKS_SCHED_H) #define SPIN_LOCK_YIELD sched_yield(); #else #define SPIN_LOCK_YIELD #endif /* ... yield ... */ #if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 /* Plain spin locks use single word (embedded in malloc_states) */ static int spin_acquire_lock(int *sl) { int spins = 0; while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { if ((++spins & SPINS_PER_YIELD) == 0) { SPIN_LOCK_YIELD; } } return 0; } #define MLOCK_T int #define TRY_LOCK(sl) !CAS_LOCK(sl) #define RELEASE_LOCK(sl) CLEAR_LOCK(sl) #define ACQUIRE_LOCK(sl) (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0) #define INITIAL_LOCK(sl) (*sl = 0) #define DESTROY_LOCK(sl) (0) static MLOCK_T malloc_global_mutex = 0; #else /* USE_RECURSIVE_LOCKS */ /* types for lock owners */ #ifdef WIN32 #define THREAD_ID_T DWORD #define CURRENT_THREAD GetCurrentThreadId() #define EQ_OWNER(X,Y) ((X) == (Y)) #else /* Note: the following assume that pthread_t is a type that can be initialized to (casted) zero. If this is not the case, you will need to somehow redefine these or not use spin locks. */ #define THREAD_ID_T pthread_t #define CURRENT_THREAD pthread_self() #define EQ_OWNER(X,Y) pthread_equal(X, Y) #endif struct malloc_recursive_lock { int sl; unsigned int c; THREAD_ID_T threadid; }; #define MLOCK_T struct malloc_recursive_lock static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0}; static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) { assert(lk->sl != 0); if (--lk->c == 0) { CLEAR_LOCK(&lk->sl); } } static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) { THREAD_ID_T mythreadid = CURRENT_THREAD; int spins = 0; for (;;) { if (*((volatile int *)(&lk->sl)) == 0) { if (!CAS_LOCK(&lk->sl)) { lk->threadid = mythreadid; lk->c = 1; return 0; } } else if (EQ_OWNER(lk->threadid, mythreadid)) { ++lk->c; return 0; } if ((++spins & SPINS_PER_YIELD) == 0) { SPIN_LOCK_YIELD; } } } static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) { THREAD_ID_T mythreadid = CURRENT_THREAD; if (*((volatile int *)(&lk->sl)) == 0) { if (!CAS_LOCK(&lk->sl)) { lk->threadid = mythreadid; lk->c = 1; return 1; } } else if (EQ_OWNER(lk->threadid, mythreadid)) { ++lk->c; return 1; } return 0; } #define RELEASE_LOCK(lk) recursive_release_lock(lk) #define TRY_LOCK(lk) recursive_try_lock(lk) #define ACQUIRE_LOCK(lk) recursive_acquire_lock(lk) #define INITIAL_LOCK(lk) ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0) #define DESTROY_LOCK(lk) (0) #endif /* USE_RECURSIVE_LOCKS */ #elif defined(WIN32) /* Win32 critical sections */ #define MLOCK_T CRITICAL_SECTION #define ACQUIRE_LOCK(lk) (EnterCriticalSection(lk), 0) #define RELEASE_LOCK(lk) LeaveCriticalSection(lk) #define TRY_LOCK(lk) TryEnterCriticalSection(lk) #define INITIAL_LOCK(lk) (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000)) #define DESTROY_LOCK(lk) (DeleteCriticalSection(lk), 0) #define NEED_GLOBAL_LOCK_INIT static MLOCK_T malloc_global_mutex; static volatile LONG malloc_global_mutex_status; /* Use spin loop to initialize global lock */ static void init_malloc_global_mutex() { for (;;) { long stat = malloc_global_mutex_status; if (stat > 0) return; /* transition to < 0 while initializing, then to > 0) */ if (stat == 0 && interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) { InitializeCriticalSection(&malloc_global_mutex); interlockedexchange(&malloc_global_mutex_status, (LONG)1); return; } SleepEx(0, FALSE); } } #else /* pthreads-based locks */ #define MLOCK_T pthread_mutex_t #define ACQUIRE_LOCK(lk) pthread_mutex_lock(lk) #define RELEASE_LOCK(lk) pthread_mutex_unlock(lk) #define TRY_LOCK(lk) (!pthread_mutex_trylock(lk)) #define INITIAL_LOCK(lk) pthread_init_lock(lk) #define DESTROY_LOCK(lk) pthread_mutex_destroy(lk) #if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE) /* Cope with old-style linux recursive lock initialization by adding */ /* skipped internal declaration from pthread.h */ extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, int __kind)); #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP #define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) #endif /* USE_RECURSIVE_LOCKS ... */ static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; static int pthread_init_lock (MLOCK_T *lk) { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr)) return 1; #if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; #endif if (pthread_mutex_init(lk, &attr)) return 1; if (pthread_mutexattr_destroy(&attr)) return 1; return 0; } #endif /* ... lock types ... */ /* Common code for all lock types */ #define USE_LOCK_BIT (2U) #ifndef ACQUIRE_MALLOC_GLOBAL_LOCK #define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); #endif #ifndef RELEASE_MALLOC_GLOBAL_LOCK #define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); #endif #endif /* USE_LOCKS */ /* ----------------------- Chunk representations ------------------------ */ /* (The following includes lightly edited explanations by Colin Plumb.) The malloc_chunk declaration below is misleading (but accurate and necessary). It declares a "view" into memory allowing access to necessary fields at known offsets from a given base. Chunks of memory are maintained using a `boundary tag' method as originally described by Knuth. (See the paper by Paul Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such techniques.) Sizes of free chunks are stored both in the front of each chunk and at the end. This makes consolidating fragmented chunks into bigger chunks fast. The head fields also hold bits representing whether chunks are free or in use. Here are some pictures to make it clearer. They are "exploded" to show that the state of a chunk can be thought of as extending from the high 31 bits of the head field of its header through the prev_foot and PINUSE_BIT bit of the following chunk header. A chunk that's in use looks like: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk (if P = 0) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| | Size of this chunk 1| +-+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | +- -+ | | +- -+ | : +- size - sizeof(size_t) available payload bytes -+ : | chunk-> +- -+ | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| | Size of next chunk (may or may not be in use) | +-+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ And if it's free, it looks like this: chunk-> +- -+ | User payload (must be in use, or we would have merged!) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| | Size of this chunk 0| +-+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Next pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Prev pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | : +- size - sizeof(struct chunk) unused bytes -+ : | chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of this chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| | Size of next chunk (must be in use, or we would have merged)| +-+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | : +- User payload -+ : | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| +-+ Note that since we always merge adjacent free chunks, the chunks adjacent to a free chunk must be in use. Given a pointer to a chunk (which can be derived trivially from the payload pointer) we can, in O(1) time, find out whether the adjacent chunks are free, and if so, unlink them from the lists that they are on and merge them with the current chunk. Chunks always begin on even word boundaries, so the mem portion (which is returned to the user) is also on an even word boundary, and thus at least double-word aligned. The P (PINUSE_BIT) bit, stored in the unused low-order bit of the chunk size (which is always a multiple of two words), is an in-use bit for the *previous* chunk. If that bit is *clear*, then the word before the current chunk size contains the previous chunk size, and can be used to find the front of the previous chunk. The very first chunk allocated always has this bit set, preventing access to non-existent (or non-owned) memory. If pinuse is set for any given chunk, then you CANNOT determine the size of the previous chunk, and might even get a memory addressing fault when trying to do so. The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of the chunk size redundantly records whether the current chunk is inuse (unless the chunk is mmapped). This redundancy enables usage checks within free and realloc, and reduces indirection when freeing and consolidating chunks. Each freshly allocated chunk must have both cinuse and pinuse set. That is, each allocated chunk borders either a previously allocated and still in-use chunk, or the base of its memory arena. This is ensured by making all allocations from the `lowest' part of any found chunk. Further, no free chunk physically borders another one, so each free chunk is known to be preceded and followed by either inuse chunks or the ends of memory. Note that the `foot' of the current chunk is actually represented as the prev_foot of the NEXT chunk. This makes it easier to deal with alignments etc but can be very confusing when trying to extend or adapt this code. The exceptions to all this are 1. The special chunk `top' is the top-most available chunk (i.e., the one bordering the end of available memory). It is treated specially. Top is never included in any bin, is used only if no other chunk is available, and is released back to the system if it is very large (see M_TRIM_THRESHOLD). In effect, the top chunk is treated as larger (and thus less well fitting) than any other available chunk. The top chunk doesn't update its trailing size field since there is no next contiguous chunk that would have to index off it. However, space is still allocated for it (TOP_FOOT_SIZE) to enable separation or merging when space is extended. 3. Chunks allocated via mmap, have both cinuse and pinuse bits cleared in their head fields. Because they are allocated one-by-one, each must carry its own prev_foot field, which is also used to hold the offset this chunk has within its mmapped region, which is needed to preserve alignment. Each mmapped chunk is trailed by the first two fields of a fake next-chunk for sake of usage checks. */ struct malloc_chunk { size_t prev_foot; /* Size of previous chunk (if free). */ size_t head; /* Size and inuse bits. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; }; typedef struct malloc_chunk mchunk; typedef struct malloc_chunk* mchunkptr; typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ typedef unsigned int bindex_t; /* Described below */ typedef unsigned int binmap_t; /* Described below */ typedef unsigned int flag_t; /* The type of various bit flag sets */ /* ------------------- Chunks sizes and alignments ----------------------- */ #define MCHUNK_SIZE (sizeof(mchunk)) #if FOOTERS #define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) #else /* FOOTERS */ #define CHUNK_OVERHEAD (SIZE_T_SIZE) #endif /* FOOTERS */ /* MMapped chunks need a second word of overhead ... */ #define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) /* ... and additional padding for fake next-chunk at foot */ #define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) /* The smallest size we can malloc is an aligned minimal chunk */ #define MIN_CHUNK_SIZE\ ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) /* conversion from malloc headers to user pointers, and back */ #define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) /* chunk associated with aligned address A */ #define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) /* Bounds on request (not chunk) sizes. */ #define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) #define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) /* pad request bytes into a usable size */ #define pad_request(req) \ (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) /* pad request, checking for minimum (but not maximum) */ #define request2size(req) \ (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) /* ------------------ Operations on head and foot fields ----------------- */ /* The head field of a chunk is or'ed with PINUSE_BIT when previous adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in use, unless mmapped, in which case both bits are cleared. FLAG4_BIT is not used by this malloc, but might be useful in extensions. */ #define PINUSE_BIT (SIZE_T_ONE) #define CINUSE_BIT (SIZE_T_TWO) #define FLAG4_BIT (SIZE_T_FOUR) #define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) #define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) /* Head value for fenceposts */ #define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) /* extraction of fields from head words */ #define cinuse(p) ((p)->head & CINUSE_BIT) #define pinuse(p) ((p)->head & PINUSE_BIT) #define flag4inuse(p) ((p)->head & FLAG4_BIT) #define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) #define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) #define chunksize(p) ((p)->head & ~(FLAG_BITS)) #define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) #define set_flag4(p) ((p)->head |= FLAG4_BIT) #define clear_flag4(p) ((p)->head &= ~FLAG4_BIT) /* Treat space at ptr +/- offset as a chunk */ #define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) #define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) /* Ptr to next or previous physical malloc_chunk. */ #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) #define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) /* extract next chunk's pinuse bit */ #define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) /* Get/set size at footer */ #define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) #define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) /* Set size, pinuse bit, and foot */ #define set_size_and_pinuse_of_free_chunk(p, s)\ ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) /* Set size, pinuse bit, foot, and clear next pinuse */ #define set_free_with_pinuse(p, s, n)\ (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) /* Get the internal overhead associated with chunk p */ #define overhead_for(p)\ (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) /* Return true if malloced space is not necessarily cleared */ #if MMAP_CLEARS #define calloc_must_clear(p) (!is_mmapped(p)) #else /* MMAP_CLEARS */ #define calloc_must_clear(p) (1) #endif /* MMAP_CLEARS */ /* ---------------------- Overlaid data structures ----------------------- */ /* When chunks are not in use, they are treated as nodes of either lists or trees. "Small" chunks are stored in circular doubly-linked lists, and look like this: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `head:' | Size of chunk, in bytes |P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Forward pointer to next chunk in list | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Back pointer to previous chunk in list | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Unused space (may be 0 bytes long) . . . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `foot:' | Size of chunk, in bytes | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Larger chunks are kept in a form of bitwise digital trees (aka tries) keyed on chunksizes. Because malloc_tree_chunks are only for free chunks greater than 256 bytes, their size doesn't impose any constraints on user chunk sizes. Each node looks like: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `head:' | Size of chunk, in bytes |P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Forward pointer to next chunk of same size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Back pointer to previous chunk of same size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Pointer to left child (child[0]) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Pointer to right child (child[1]) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Pointer to parent | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | bin index of this chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Unused space . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `foot:' | Size of chunk, in bytes | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Each tree holding treenodes is a tree of unique chunk sizes. Chunks of the same size are arranged in a circularly-linked list, with only the oldest chunk (the next to be used, in our FIFO ordering) actually in the tree. (Tree members are distinguished by a non-null parent pointer.) If a chunk with the same size an an existing node is inserted, it is linked off the existing node using pointers that work in the same way as fd/bk pointers of small chunks. Each tree contains a power of 2 sized range of chunk sizes (the smallest is 0x100 <= x < 0x180), which is is divided in half at each tree level, with the chunks in the smaller half of the range (0x100 <= x < 0x140 for the top nose) in the left subtree and the larger half (0x140 <= x < 0x180) in the right subtree. This is, of course, done by inspecting individual bits. Using these rules, each node's left subtree contains all smaller sizes than its right subtree. However, the node at the root of each subtree has no particular ordering relationship to either. (The dividing line between the subtree sizes is based on trie relation.) If we remove the last chunk of a given size from the interior of the tree, we need to replace it with a leaf node. The tree ordering rules permit a node to be replaced by any leaf below it. The smallest chunk in a tree (a common operation in a best-fit allocator) can be found by walking a path to the leftmost leaf in the tree. Unlike a usual binary tree, where we follow left child pointers until we reach a null, here we follow the right child pointer any time the left one is null, until we reach a leaf with both child pointers null. The smallest chunk in the tree will be somewhere along that path. The worst case number of steps to add, find, or remove a node is bounded by the number of bits differentiating chunks within bins. Under current bin calculations, this ranges from 6 up to 21 (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case is of course much better. */ struct malloc_tree_chunk { /* The first four fields must be compatible with malloc_chunk */ size_t prev_foot; size_t head; struct malloc_tree_chunk* fd; struct malloc_tree_chunk* bk; struct malloc_tree_chunk* child[2]; struct malloc_tree_chunk* parent; bindex_t index; }; typedef struct malloc_tree_chunk tchunk; typedef struct malloc_tree_chunk* tchunkptr; typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ /* A little helper macro for trees */ #define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) /* ----------------------------- Segments -------------------------------- */ /* Each malloc space may include non-contiguous segments, held in a list headed by an embedded malloc_segment record representing the top-most space. Segments also include flags holding properties of the space. Large chunks that are directly allocated by mmap are not included in this list. They are instead independently created and destroyed without otherwise keeping track of them. Segment management mainly comes into play for spaces allocated by MMAP. Any call to MMAP might or might not return memory that is adjacent to an existing segment. MORECORE normally contiguously extends the current space, so this space is almost always adjacent, which is simpler and faster to deal with. (This is why MORECORE is used preferentially to MMAP when both are available -- see sys_alloc.) When allocating using MMAP, we don't use any of the hinting mechanisms (inconsistently) supported in various implementations of unix mmap, or distinguish reserving from committing memory. Instead, we just ask for space, and exploit contiguity when we get it. It is probably possible to do better than this on some systems, but no general scheme seems to be significantly better. Management entails a simpler variant of the consolidation scheme used for chunks to reduce fragmentation -- new adjacent memory is normally prepended or appended to an existing segment. However, there are limitations compared to chunk consolidation that mostly reflect the fact that segment processing is relatively infrequent (occurring only when getting memory from system) and that we don't expect to have huge numbers of segments: * Segments are not indexed, so traversal requires linear scans. (It would be possible to index these, but is not worth the extra overhead and complexity for most programs on most platforms.) * New segments are only appended to old ones when holding top-most memory; if they cannot be prepended to others, they are held in different segments. Except for the top-most segment of an mstate, each segment record is kept at the tail of its segment. Segments are added by pushing segment records onto the list headed by &mstate.seg for the containing mstate. Segment flags control allocation/merge/deallocation policies: * If EXTERN_BIT set, then we did not allocate this segment, and so should not try to deallocate or merge with others. (This currently holds only for the initial segment passed into create_mspace_with_base.) * If USE_MMAP_BIT set, the segment may be merged with other surrounding mmapped segments and trimmed/de-allocated using munmap. * If neither bit is set, then the segment was obtained using MORECORE so can be merged with surrounding MORECORE'd segments and deallocated/trimmed using MORECORE with negative arguments. */ struct malloc_segment { char* base; /* base address */ size_t size; /* allocated size */ struct malloc_segment* next; /* ptr to next segment */ flag_t sflags; /* mmap and extern flag */ }; #define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) #define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) typedef struct malloc_segment msegment; typedef struct malloc_segment* msegmentptr; /* ---------------------------- malloc_state ----------------------------- */ /* A malloc_state holds all of the bookkeeping for a space. The main fields are: Top The topmost chunk of the currently active segment. Its size is cached in topsize. The actual size of topmost space is topsize+TOP_FOOT_SIZE, which includes space reserved for adding fenceposts and segment records if necessary when getting more space from the system. The size at which to autotrim top is cached from mparams in trim_check, except that it is disabled if an autotrim fails. Designated victim (dv) This is the preferred chunk for servicing small requests that don't have exact fits. It is normally the chunk split off most recently to service another small request. Its size is cached in dvsize. The link fields of this chunk are not maintained since it is not kept in a bin. SmallBins An array of bin headers for free chunks. These bins hold chunks with sizes less than MIN_LARGE_SIZE bytes. Each bin contains chunks of all the same size, spaced 8 bytes apart. To simplify use in double-linked lists, each bin header acts as a malloc_chunk pointing to the real first node, if it exists (else pointing to itself). This avoids special-casing for headers. But to avoid waste, we allocate only the fd/bk pointers of bins, and then use repositioning tricks to treat these as the fields of a chunk. TreeBins Treebins are pointers to the roots of trees holding a range of sizes. There are 2 equally spaced treebins for each power of two from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything larger. Bin maps There is one bit map for small bins ("smallmap") and one for treebins ("treemap). Each bin sets its bit when non-empty, and clears the bit when empty. Bit operations are then used to avoid bin-by-bin searching -- nearly all "search" is done without ever looking at bins that won't be selected. The bit maps conservatively use 32 bits per map word, even if on 64bit system. For a good description of some of the bit-based techniques used here, see Henry S. Warren Jr's book "Hacker's Delight" (and supplement at http://hackersdelight.org/). Many of these are intended to reduce the branchiness of paths through malloc etc, as well as to reduce the number of memory locations read or written. Segments A list of segments headed by an embedded malloc_segment record representing the initial space. Address check support The least_addr field is the least address ever obtained from MORECORE or MMAP. Attempted frees and reallocs of any address less than this are trapped (unless INSECURE is defined). Magic tag A cross-check field that should always hold same value as mparams.magic. Max allowed footprint The maximum allowed bytes to allocate from system (zero means no limit) Flags Bits recording whether to use MMAP, locks, or contiguous MORECORE Statistics Each space keeps track of current and maximum system memory obtained via MORECORE or MMAP. Trim support Fields holding the amount of unused topmost memory that should trigger trimming, and a counter to force periodic scanning to release unused non-topmost segments. Locking If USE_LOCKS is defined, the "mutex" lock is acquired and released around every public call using this mspace. Extension support A void* pointer and a size_t field that can be used to help implement extensions to this malloc. */ /* Bin types, widths and sizes */ #define NSMALLBINS (32U) #define NTREEBINS (32U) #define SMALLBIN_SHIFT (3U) #define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) #define TREEBIN_SHIFT (8U) #define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) #define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) #define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) struct malloc_state { binmap_t smallmap; binmap_t treemap; size_t dvsize; size_t topsize; char* least_addr; mchunkptr dv; mchunkptr top; size_t trim_check; size_t release_checks; size_t magic; mchunkptr smallbins[(NSMALLBINS+1)*2]; tbinptr treebins[NTREEBINS]; size_t footprint; size_t max_footprint; size_t footprint_limit; /* zero means no limit */ flag_t mflags; #if USE_LOCKS MLOCK_T mutex; /* locate lock among fields that rarely change */ #endif /* USE_LOCKS */ msegment seg; void* extp; /* Unused but available for extensions */ size_t exts; }; typedef struct malloc_state* mstate; /* ------------- Global malloc_state and malloc_params ------------------- */ /* malloc_params holds global properties, including those that can be dynamically set using mallopt. There is a single instance, mparams, initialized in init_mparams. Note that the non-zeroness of "magic" also serves as an initialization flag. */ struct malloc_params { size_t magic; size_t page_size; size_t granularity; size_t mmap_threshold; size_t trim_threshold; flag_t default_mflags; }; static struct malloc_params mparams; /* Ensure mparams initialized */ #define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) #if !ONLY_MSPACES /* The global malloc_state used for all non-"mspace" calls */ static struct malloc_state _gm_; #define gm (&_gm_) #define is_global(M) ((M) == &_gm_) #endif /* !ONLY_MSPACES */ #define is_initialized(M) ((M)->top != 0) /* -------------------------- system alloc setup ------------------------- */ /* Operations on mflags */ #define use_lock(M) ((M)->mflags & USE_LOCK_BIT) #define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) #if USE_LOCKS #define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) #else #define disable_lock(M) #endif #define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) #define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) #if HAVE_MMAP #define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) #else #define disable_mmap(M) #endif #define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) #define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) #define set_lock(M,L)\ ((M)->mflags = (L)?\ ((M)->mflags | USE_LOCK_BIT) :\ ((M)->mflags & ~USE_LOCK_BIT)) /* page-align a size */ #define page_align(S)\ (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) /* granularity-align a size */ #define granularity_align(S)\ (((S) + (mparams.granularity - SIZE_T_ONE))\ & ~(mparams.granularity - SIZE_T_ONE)) /* For mmap, use granularity alignment on windows, else page-align */ #ifdef WIN32 #define mmap_align(S) granularity_align(S) #else #define mmap_align(S) page_align(S) #endif /* For sys_alloc, enough padding to ensure can malloc request on success */ #define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) #define is_page_aligned(S)\ (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) #define is_granularity_aligned(S)\ (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) /* True if segment S holds address A */ #define segment_holds(S, A)\ ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) /* Return segment holding given address */ static msegmentptr segment_holding(mstate m, char* addr) { msegmentptr sp = &m->seg; for (;;) { if (addr >= sp->base && addr < sp->base + sp->size) return sp; if ((sp = sp->next) == 0) return 0; } } /* Return true if segment contains a segment link */ static int has_segment_link(mstate m, msegmentptr ss) { msegmentptr sp = &m->seg; for (;;) { if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) return 1; if ((sp = sp->next) == 0) return 0; } } #ifndef MORECORE_CANNOT_TRIM #define should_trim(M,s) ((s) > (M)->trim_check) #else /* MORECORE_CANNOT_TRIM */ #define should_trim(M,s) (0) #endif /* MORECORE_CANNOT_TRIM */ /* TOP_FOOT_SIZE is padding at the end of a segment, including space that may be needed to place segment records and fenceposts when new noncontiguous segments are added. */ #define TOP_FOOT_SIZE\ (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) /* ------------------------------- Hooks -------------------------------- */ /* PREACTION should be defined to return 0 on success, and nonzero on failure. If you are not using locking, you can redefine these to do anything you like. */ #if USE_LOCKS #define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) #define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } #else /* USE_LOCKS */ #ifndef PREACTION #define PREACTION(M) (0) #endif /* PREACTION */ #ifndef POSTACTION #define POSTACTION(M) #endif /* POSTACTION */ #endif /* USE_LOCKS */ /* CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. USAGE_ERROR_ACTION is triggered on detected bad frees and reallocs. The argument p is an address that might have triggered the fault. It is ignored by the two predefined actions, but might be useful in custom actions that try to help diagnose errors. */ #if PROCEED_ON_ERROR /* A count of the number of corruption errors causing resets */ int malloc_corruption_error_count; /* default corruption action */ static void reset_on_error(mstate m); #define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) #define USAGE_ERROR_ACTION(m, p) #else /* PROCEED_ON_ERROR */ #ifndef CORRUPTION_ERROR_ACTION #define CORRUPTION_ERROR_ACTION(m) ABORT #endif /* CORRUPTION_ERROR_ACTION */ #ifndef USAGE_ERROR_ACTION #define USAGE_ERROR_ACTION(m,p) ABORT #endif /* USAGE_ERROR_ACTION */ #endif /* PROCEED_ON_ERROR */ /* -------------------------- Debugging setup ---------------------------- */ #if ! DEBUG #define check_free_chunk(M,P) #define check_inuse_chunk(M,P) #define check_malloced_chunk(M,P,N) #define check_mmapped_chunk(M,P) #define check_malloc_state(M) #define check_top_chunk(M,P) #else /* DEBUG */ #define check_free_chunk(M,P) do_check_free_chunk(M,P) #define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) #define check_top_chunk(M,P) do_check_top_chunk(M,P) #define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) #define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) #define check_malloc_state(M) do_check_malloc_state(M) static void do_check_any_chunk(mstate m, mchunkptr p); static void do_check_top_chunk(mstate m, mchunkptr p); static void do_check_mmapped_chunk(mstate m, mchunkptr p); static void do_check_inuse_chunk(mstate m, mchunkptr p); static void do_check_free_chunk(mstate m, mchunkptr p); static void do_check_malloced_chunk(mstate m, void* mem, size_t s); static void do_check_tree(mstate m, tchunkptr t); static void do_check_treebin(mstate m, bindex_t i); static void do_check_smallbin(mstate m, bindex_t i); static void do_check_malloc_state(mstate m); static int bin_find(mstate m, mchunkptr x); static size_t traverse_and_check(mstate m); #endif /* DEBUG */ /* ---------------------------- Indexing Bins ---------------------------- */ #define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) #define small_index(s) (bindex_t)((s) >> SMALLBIN_SHIFT) #define small_index2size(i) ((i) << SMALLBIN_SHIFT) #define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) /* addressing by index. See above about smallbin repositioning */ #define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) #define treebin_at(M,i) (&((M)->treebins[i])) /* assign tree index for size S to variable I. Use x86 asm if possible */ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #define compute_tree_index(S, I)\ {\ unsigned int X = S >> TREEBIN_SHIFT;\ if (X == 0)\ I = 0;\ else if (X > 0xFFFF)\ I = NTREEBINS-1;\ else {\ unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \ I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ }\ } #elif defined (__INTEL_COMPILER) #define compute_tree_index(S, I)\ {\ size_t X = S >> TREEBIN_SHIFT;\ if (X == 0)\ I = 0;\ else if (X > 0xFFFF)\ I = NTREEBINS-1;\ else {\ unsigned int K = _bit_scan_reverse (X); \ I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ }\ } #elif defined(_MSC_VER) && _MSC_VER>=1300 #define compute_tree_index(S, I)\ {\ size_t X = S >> TREEBIN_SHIFT;\ if (X == 0)\ I = 0;\ else if (X > 0xFFFF)\ I = NTREEBINS-1;\ else {\ unsigned int K;\ _BitScanReverse((DWORD *) &K, (DWORD) X);\ I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ }\ } #else /* GNUC */ #define compute_tree_index(S, I)\ {\ size_t X = S >> TREEBIN_SHIFT;\ if (X == 0)\ I = 0;\ else if (X > 0xFFFF)\ I = NTREEBINS-1;\ else {\ unsigned int Y = (unsigned int)X;\ unsigned int N = ((Y - 0x100) >> 16) & 8;\ unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ N += K;\ N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ K = 14 - N + ((Y <<= K) >> 15);\ I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ }\ } #endif /* GNUC */ /* Bit representing maximum resolved size in a treebin at i */ #define bit_for_tree_index(i) \ (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) /* Shift placing maximum resolved bit in a treebin at i as sign bit */ #define leftshift_for_tree_index(i) \ ((i == NTREEBINS-1)? 0 : \ ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) /* The size of the smallest chunk held in bin with index i */ #define minsize_for_tree_index(i) \ ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) /* ------------------------ Operations on bin maps ----------------------- */ /* bit corresponding to given index */ #define idx2bit(i) ((binmap_t)(1) << (i)) /* Mark/Clear bits with given index */ #define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) #define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) #define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) #define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) #define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) #define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) /* isolate the least set bit of a bitmap */ #define least_bit(x) ((x) & -(x)) /* mask with all bits to left of least bit of x on */ #define left_bits(x) ((x<<1) | -(x<<1)) /* mask with all bits to left of or equal to least bit of x on */ #define same_or_left_bits(x) ((x) | -(x)) /* index corresponding to given bit. Use x86 asm if possible */ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #define compute_bit2idx(X, I)\ {\ unsigned int J;\ J = __builtin_ctz(X); \ I = (bindex_t)J;\ } #elif defined (__INTEL_COMPILER) #define compute_bit2idx(X, I)\ {\ unsigned int J;\ J = _bit_scan_forward (X); \ I = (bindex_t)J;\ } #elif defined(_MSC_VER) && _MSC_VER>=1300 #define compute_bit2idx(X, I)\ {\ unsigned int J;\ _BitScanForward((DWORD *) &J, X);\ I = (bindex_t)J;\ } #elif USE_BUILTIN_FFS #define compute_bit2idx(X, I) I = ffs(X)-1 #else #define compute_bit2idx(X, I)\ {\ unsigned int Y = X - 1;\ unsigned int K = Y >> (16-4) & 16;\ unsigned int N = K; Y >>= K;\ N += K = Y >> (8-3) & 8; Y >>= K;\ N += K = Y >> (4-2) & 4; Y >>= K;\ N += K = Y >> (2-1) & 2; Y >>= K;\ N += K = Y >> (1-0) & 1; Y >>= K;\ I = (bindex_t)(N + Y);\ } #endif /* GNUC */ /* ----------------------- Runtime Check Support ------------------------- */ /* For security, the main invariant is that malloc/free/etc never writes to a static address other than malloc_state, unless static malloc_state itself has been corrupted, which cannot occur via malloc (because of these checks). In essence this means that we believe all pointers, sizes, maps etc held in malloc_state, but check all of those linked or offsetted from other embedded data structures. These checks are interspersed with main code in a way that tends to minimize their run-time cost. When FOOTERS is defined, in addition to range checking, we also verify footer fields of inuse chunks, which can be used guarantee that the mstate controlling malloc/free is intact. This is a streamlined version of the approach described by William Robertson et al in "Run-time Detection of Heap-based Overflows" LISA'03 http://www.usenix.org/events/lisa03/tech/robertson.html The footer of an inuse chunk holds the xor of its mstate and a random seed, that is checked upon calls to free() and realloc(). This is (probabalistically) unguessable from outside the program, but can be computed by any code successfully malloc'ing any chunk, so does not itself provide protection against code that has already broken security through some other means. Unlike Robertson et al, we always dynamically check addresses of all offset chunks (previous, next, etc). This turns out to be cheaper than relying on hashes. */ #if !INSECURE /* Check if address a is at least as high as any from MORECORE or MMAP */ #define ok_address(M, a) ((char*)(a) >= (M)->least_addr) /* Check if address of next chunk n is higher than base chunk p */ #define ok_next(p, n) ((char*)(p) < (char*)(n)) /* Check if p has inuse status */ #define ok_inuse(p) is_inuse(p) /* Check if p has its pinuse bit on */ #define ok_pinuse(p) pinuse(p) #else /* !INSECURE */ #define ok_address(M, a) (1) #define ok_next(b, n) (1) #define ok_inuse(p) (1) #define ok_pinuse(p) (1) #endif /* !INSECURE */ #if (FOOTERS && !INSECURE) /* Check if (alleged) mstate m has expected magic field */ #define ok_magic(M) ((M)->magic == mparams.magic) #else /* (FOOTERS && !INSECURE) */ #define ok_magic(M) (1) #endif /* (FOOTERS && !INSECURE) */ /* In gcc, use __builtin_expect to minimize impact of checks */ #if !INSECURE #if defined(__GNUC__) && __GNUC__ >= 3 #define RTCHECK(e) __builtin_expect(e, 1) #else /* GNUC */ #define RTCHECK(e) (e) #endif /* GNUC */ #else /* !INSECURE */ #define RTCHECK(e) (1) #endif /* !INSECURE */ /* macros to set up inuse chunks with or without footers */ #if !FOOTERS #define mark_inuse_foot(M,p,s) /* Macros for setting head/foot of non-mmapped chunks */ /* Set cinuse bit and pinuse bit of next chunk */ #define set_inuse(M,p,s)\ ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) /* Set cinuse and pinuse of this chunk and pinuse of next chunk */ #define set_inuse_and_pinuse(M,p,s)\ ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) /* Set size, cinuse and pinuse bit of this chunk */ #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) #else /* FOOTERS */ /* Set foot of inuse chunk to be xor of mstate and seed */ #define mark_inuse_foot(M,p,s)\ (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) #define get_mstate_for(p)\ ((mstate)(((mchunkptr)((char*)(p) +\ (chunksize(p))))->prev_foot ^ mparams.magic)) #define set_inuse(M,p,s)\ ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ mark_inuse_foot(M,p,s)) #define set_inuse_and_pinuse(M,p,s)\ ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ mark_inuse_foot(M,p,s)) #define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ mark_inuse_foot(M, p, s)) #endif /* !FOOTERS */ /* ---------------------------- setting mparams -------------------------- */ #if LOCK_AT_FORK static void pre_fork(void) { ACQUIRE_LOCK(&(gm)->mutex); } static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); } static void post_fork_child(void) { INITIAL_LOCK(&(gm)->mutex); } #endif /* LOCK_AT_FORK */ /* Initialize mparams */ static int init_mparams(void) { #ifdef NEED_GLOBAL_LOCK_INIT if (malloc_global_mutex_status <= 0) init_malloc_global_mutex(); #endif ACQUIRE_MALLOC_GLOBAL_LOCK(); if (mparams.magic == 0) { size_t magic; size_t psize; size_t gsize; #ifndef WIN32 psize = malloc_getpagesize; gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); #else /* WIN32 */ { SYSTEM_INFO system_info; GetSystemInfo(&system_info); psize = system_info.dwPageSize; gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); } #endif /* WIN32 */ /* Sanity-check configuration: size_t must be unsigned and as wide as pointer type. ints must be at least 4 bytes. alignment must be at least 8. Alignment, min chunk size, and page size must all be powers of 2. */ if ((sizeof(size_t) != sizeof(char*)) || (MAX_SIZE_T < MIN_CHUNK_SIZE) || (sizeof(int) < 4) || (MALLOC_ALIGNMENT < (size_t)8U) || ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || ((gsize & (gsize-SIZE_T_ONE)) != 0) || ((psize & (psize-SIZE_T_ONE)) != 0)) ABORT; mparams.granularity = gsize; mparams.page_size = psize; mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; #if MORECORE_CONTIGUOUS mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; #else /* MORECORE_CONTIGUOUS */ mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; #endif /* MORECORE_CONTIGUOUS */ #if !ONLY_MSPACES /* Set up lock for main malloc area */ gm->mflags = mparams.default_mflags; (void)INITIAL_LOCK(&gm->mutex); #endif #if LOCK_AT_FORK pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child); #endif { #if USE_DEV_RANDOM int fd; unsigned char buf[sizeof(size_t)]; /* Try to use /dev/urandom, else fall back on using time */ if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && read(fd, buf, sizeof(buf)) == sizeof(buf)) { magic = *((size_t *) buf); close(fd); } else #endif /* USE_DEV_RANDOM */ #ifdef WIN32 magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); #elif defined(LACKS_TIME_H) magic = (size_t)&magic ^ (size_t)0x55555555U; #else magic = (size_t)(time(0) ^ (size_t)0x55555555U); #endif magic |= (size_t)8U; /* ensure nonzero */ magic &= ~(size_t)7U; /* improve chances of fault for bad values */ /* Until memory modes commonly available, use volatile-write */ (*(volatile size_t *)(&(mparams.magic))) = magic; } } RELEASE_MALLOC_GLOBAL_LOCK(); return 1; } /* support for mallopt */ static int change_mparam(int param_number, int value) { size_t val; ensure_initialization(); val = (value == -1)? MAX_SIZE_T : (size_t)value; switch(param_number) { case M_TRIM_THRESHOLD: mparams.trim_threshold = val; return 1; case M_GRANULARITY: if (val >= mparams.page_size && ((val & (val-1)) == 0)) { mparams.granularity = val; return 1; } else return 0; case M_MMAP_THRESHOLD: mparams.mmap_threshold = val; return 1; default: return 0; } } #if DEBUG /* ------------------------- Debugging Support --------------------------- */ /* Check properties of any chunk, whether free, inuse, mmapped etc */ static void do_check_any_chunk(mstate m, mchunkptr p) { assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); assert(ok_address(m, p)); } /* Check properties of top chunk */ static void do_check_top_chunk(mstate m, mchunkptr p) { msegmentptr sp = segment_holding(m, (char*)p); size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ assert(sp != 0); assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); assert(ok_address(m, p)); assert(sz == m->topsize); assert(sz > 0); assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); assert(pinuse(p)); assert(!pinuse(chunk_plus_offset(p, sz))); } /* Check properties of (inuse) mmapped chunks */ static void do_check_mmapped_chunk(mstate m, mchunkptr p) { size_t sz = chunksize(p); size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); assert(is_mmapped(p)); assert(use_mmap(m)); assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); assert(ok_address(m, p)); assert(!is_small(sz)); assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); } /* Check properties of inuse chunks */ static void do_check_inuse_chunk(mstate m, mchunkptr p) { do_check_any_chunk(m, p); assert(is_inuse(p)); assert(next_pinuse(p)); /* If not pinuse and not mmapped, previous chunk has OK offset */ assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); if (is_mmapped(p)) do_check_mmapped_chunk(m, p); } /* Check properties of free chunks */ static void do_check_free_chunk(mstate m, mchunkptr p) { size_t sz = chunksize(p); mchunkptr next = chunk_plus_offset(p, sz); do_check_any_chunk(m, p); assert(!is_inuse(p)); assert(!next_pinuse(p)); assert (!is_mmapped(p)); if (p != m->dv && p != m->top) { if (sz >= MIN_CHUNK_SIZE) { assert((sz & CHUNK_ALIGN_MASK) == 0); assert(is_aligned(chunk2mem(p))); assert(next->prev_foot == sz); assert(pinuse(p)); assert (next == m->top || is_inuse(next)); assert(p->fd->bk == p); assert(p->bk->fd == p); } else /* markers are always of size SIZE_T_SIZE */ assert(sz == SIZE_T_SIZE); } } /* Check properties of malloced chunks at the point they are malloced */ static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { if (mem != 0) { mchunkptr p = mem2chunk(mem); size_t sz = p->head & ~INUSE_BITS; do_check_inuse_chunk(m, p); assert((sz & CHUNK_ALIGN_MASK) == 0); assert(sz >= MIN_CHUNK_SIZE); assert(sz >= s); /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); } } /* Check a tree and its subtrees. */ static void do_check_tree(mstate m, tchunkptr t) { tchunkptr head = 0; tchunkptr u = t; bindex_t tindex = t->index; size_t tsize = chunksize(t); bindex_t idx; compute_tree_index(tsize, idx); assert(tindex == idx); assert(tsize >= MIN_LARGE_SIZE); assert(tsize >= minsize_for_tree_index(idx)); assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); do { /* traverse through chain of same-sized nodes */ do_check_any_chunk(m, ((mchunkptr)u)); assert(u->index == tindex); assert(chunksize(u) == tsize); assert(!is_inuse(u)); assert(!next_pinuse(u)); assert(u->fd->bk == u); assert(u->bk->fd == u); if (u->parent == 0) { assert(u->child[0] == 0); assert(u->child[1] == 0); } else { assert(head == 0); /* only one node on chain has parent */ head = u; assert(u->parent != u); assert (u->parent->child[0] == u || u->parent->child[1] == u || *((tbinptr*)(u->parent)) == u); if (u->child[0] != 0) { assert(u->child[0]->parent == u); assert(u->child[0] != u); do_check_tree(m, u->child[0]); } if (u->child[1] != 0) { assert(u->child[1]->parent == u); assert(u->child[1] != u); do_check_tree(m, u->child[1]); } if (u->child[0] != 0 && u->child[1] != 0) { assert(chunksize(u->child[0]) < chunksize(u->child[1])); } } u = u->fd; } while (u != t); assert(head != 0); } /* Check all the chunks in a treebin. */ static void do_check_treebin(mstate m, bindex_t i) { tbinptr* tb = treebin_at(m, i); tchunkptr t = *tb; int empty = (m->treemap & (1U << i)) == 0; if (t == 0) assert(empty); if (!empty) do_check_tree(m, t); } /* Check all the chunks in a smallbin. */ static void do_check_smallbin(mstate m, bindex_t i) { sbinptr b = smallbin_at(m, i); mchunkptr p = b->bk; unsigned int empty = (m->smallmap & (1U << i)) == 0; if (p == b) assert(empty); if (!empty) { for (; p != b; p = p->bk) { size_t size = chunksize(p); mchunkptr q; /* each chunk claims to be free */ do_check_free_chunk(m, p); /* chunk belongs in bin */ assert(small_index(size) == i); assert(p->bk == b || chunksize(p->bk) == chunksize(p)); /* chunk is followed by an inuse chunk */ q = next_chunk(p); if (q->head != FENCEPOST_HEAD) do_check_inuse_chunk(m, q); } } } /* Find x in a bin. Used in other check functions. */ static int bin_find(mstate m, mchunkptr x) { size_t size = chunksize(x); if (is_small(size)) { bindex_t sidx = small_index(size); sbinptr b = smallbin_at(m, sidx); if (smallmap_is_marked(m, sidx)) { mchunkptr p = b; do { if (p == x) return 1; } while ((p = p->fd) != b); } } else { bindex_t tidx; compute_tree_index(size, tidx); if (treemap_is_marked(m, tidx)) { tchunkptr t = *treebin_at(m, tidx); size_t sizebits = size << leftshift_for_tree_index(tidx); while (t != 0 && chunksize(t) != size) { t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; sizebits <<= 1; } if (t != 0) { tchunkptr u = t; do { if (u == (tchunkptr)x) return 1; } while ((u = u->fd) != t); } } } return 0; } /* Traverse each chunk and check it; return total */ static size_t traverse_and_check(mstate m) { size_t sum = 0; if (is_initialized(m)) { msegmentptr s = &m->seg; sum += m->topsize + TOP_FOOT_SIZE; while (s != 0) { mchunkptr q = align_as_chunk(s->base); mchunkptr lastq = 0; assert(pinuse(q)); while (segment_holds(s, q) && q != m->top && q->head != FENCEPOST_HEAD) { sum += chunksize(q); if (is_inuse(q)) { assert(!bin_find(m, q)); do_check_inuse_chunk(m, q); } else { assert(q == m->dv || bin_find(m, q)); assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ do_check_free_chunk(m, q); } lastq = q; q = next_chunk(q); } s = s->next; } } return sum; } /* Check all properties of malloc_state. */ static void do_check_malloc_state(mstate m) { bindex_t i; size_t total; /* check bins */ for (i = 0; i < NSMALLBINS; ++i) do_check_smallbin(m, i); for (i = 0; i < NTREEBINS; ++i) do_check_treebin(m, i); if (m->dvsize != 0) { /* check dv chunk */ do_check_any_chunk(m, m->dv); assert(m->dvsize == chunksize(m->dv)); assert(m->dvsize >= MIN_CHUNK_SIZE); assert(bin_find(m, m->dv) == 0); } if (m->top != 0) { /* check top chunk */ do_check_top_chunk(m, m->top); /*assert(m->topsize == chunksize(m->top)); redundant */ assert(m->topsize > 0); assert(bin_find(m, m->top) == 0); } total = traverse_and_check(m); assert(total <= m->footprint); assert(m->footprint <= m->max_footprint); } #endif /* DEBUG */ /* ----------------------------- statistics ------------------------------ */ #if !NO_MALLINFO static struct mallinfo internal_mallinfo(mstate m) { struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ensure_initialization(); if (!PREACTION(m)) { check_malloc_state(m); if (is_initialized(m)) { size_t nfree = SIZE_T_ONE; /* top always free */ size_t mfree = m->topsize + TOP_FOOT_SIZE; size_t sum = mfree; msegmentptr s = &m->seg; while (s != 0) { mchunkptr q = align_as_chunk(s->base); while (segment_holds(s, q) && q != m->top && q->head != FENCEPOST_HEAD) { size_t sz = chunksize(q); sum += sz; if (!is_inuse(q)) { mfree += sz; ++nfree; } q = next_chunk(q); } s = s->next; } nm.arena = sum; nm.ordblks = nfree; nm.hblkhd = m->footprint - sum; nm.usmblks = m->max_footprint; nm.uordblks = m->footprint - mfree; nm.fordblks = mfree; nm.keepcost = m->topsize; } POSTACTION(m); } return nm; } #endif /* !NO_MALLINFO */ #if !NO_MALLOC_STATS static void internal_malloc_stats(mstate m) { ensure_initialization(); if (!PREACTION(m)) { size_t maxfp = 0; size_t fp = 0; size_t used = 0; check_malloc_state(m); if (is_initialized(m)) { msegmentptr s = &m->seg; maxfp = m->max_footprint; fp = m->footprint; used = fp - (m->topsize + TOP_FOOT_SIZE); while (s != 0) { mchunkptr q = align_as_chunk(s->base); while (segment_holds(s, q) && q != m->top && q->head != FENCEPOST_HEAD) { if (!is_inuse(q)) used -= chunksize(q); q = next_chunk(q); } s = s->next; } } POSTACTION(m); /* drop lock */ fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); } } #endif /* NO_MALLOC_STATS */ /* ----------------------- Operations on smallbins ----------------------- */ /* Various forms of linking and unlinking are defined as macros. Even the ones for trees, which are very long but have very short typical paths. This is ugly but reduces reliance on inlining support of compilers. */ /* Link a free chunk into a smallbin */ #define insert_small_chunk(M, P, S) {\ bindex_t I = small_index(S);\ mchunkptr B = smallbin_at(M, I);\ mchunkptr F = B;\ assert(S >= MIN_CHUNK_SIZE);\ if (!smallmap_is_marked(M, I))\ mark_smallmap(M, I);\ else if (RTCHECK(ok_address(M, B->fd)))\ F = B->fd;\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ B->fd = P;\ F->bk = P;\ P->fd = F;\ P->bk = B;\ } /* Unlink a chunk from a smallbin */ #define unlink_small_chunk(M, P, S) {\ mchunkptr F = P->fd;\ mchunkptr B = P->bk;\ bindex_t I = small_index(S);\ assert(P != B);\ assert(P != F);\ assert(chunksize(P) == small_index2size(I));\ if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \ if (B == F) {\ clear_smallmap(M, I);\ }\ else if (RTCHECK(B == smallbin_at(M,I) ||\ (ok_address(M, B) && B->fd == P))) {\ F->bk = B;\ B->fd = F;\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ } /* Unlink the first chunk from a smallbin */ #define unlink_first_small_chunk(M, B, P, I) {\ mchunkptr F = P->fd;\ assert(P != B);\ assert(P != F);\ assert(chunksize(P) == small_index2size(I));\ if (B == F) {\ clear_smallmap(M, I);\ }\ else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\ F->bk = B;\ B->fd = F;\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ } /* Replace dv node, binning the old one */ /* Used only when dvsize known to be small */ #define replace_dv(M, P, S) {\ size_t DVS = M->dvsize;\ assert(is_small(DVS));\ if (DVS != 0) {\ mchunkptr DV = M->dv;\ insert_small_chunk(M, DV, DVS);\ }\ M->dvsize = S;\ M->dv = P;\ } /* ------------------------- Operations on trees ------------------------- */ /* Insert chunk into tree */ #define insert_large_chunk(M, X, S) {\ tbinptr* H;\ bindex_t I;\ compute_tree_index(S, I);\ H = treebin_at(M, I);\ X->index = I;\ X->child[0] = X->child[1] = 0;\ if (!treemap_is_marked(M, I)) {\ mark_treemap(M, I);\ *H = X;\ X->parent = (tchunkptr)H;\ X->fd = X->bk = X;\ }\ else {\ tchunkptr T = *H;\ size_t K = S << leftshift_for_tree_index(I);\ for (;;) {\ if (chunksize(T) != S) {\ tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ K <<= 1;\ if (*C != 0)\ T = *C;\ else if (RTCHECK(ok_address(M, C))) {\ *C = X;\ X->parent = T;\ X->fd = X->bk = X;\ break;\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ break;\ }\ }\ else {\ tchunkptr F = T->fd;\ if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ T->fd = F->bk = X;\ X->fd = F;\ X->bk = T;\ X->parent = 0;\ break;\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ break;\ }\ }\ }\ }\ } /* Unlink steps: 1. If x is a chained node, unlink it from its same-sized fd/bk links and choose its bk node as its replacement. 2. If x was the last node of its size, but not a leaf node, it must be replaced with a leaf node (not merely one with an open left or right), to make sure that lefts and rights of descendents correspond properly to bit masks. We use the rightmost descendent of x. We could use any other leaf, but this is easy to locate and tends to counteract removal of leftmosts elsewhere, and so keeps paths shorter than minimally guaranteed. This doesn't loop much because on average a node in a tree is near the bottom. 3. If x is the base of a chain (i.e., has parent links) relink x's parent and children to x's replacement (or null if none). */ #define unlink_large_chunk(M, X) {\ tchunkptr XP = X->parent;\ tchunkptr R;\ if (X->bk != X) {\ tchunkptr F = X->fd;\ R = X->bk;\ if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\ F->bk = R;\ R->fd = F;\ }\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ }\ else {\ tchunkptr* RP;\ if (((R = *(RP = &(X->child[1]))) != 0) ||\ ((R = *(RP = &(X->child[0]))) != 0)) {\ tchunkptr* CP;\ while ((*(CP = &(R->child[1])) != 0) ||\ (*(CP = &(R->child[0])) != 0)) {\ R = *(RP = CP);\ }\ if (RTCHECK(ok_address(M, RP)))\ *RP = 0;\ else {\ CORRUPTION_ERROR_ACTION(M);\ }\ }\ }\ if (XP != 0) {\ tbinptr* H = treebin_at(M, X->index);\ if (X == *H) {\ if ((*H = R) == 0) \ clear_treemap(M, X->index);\ }\ else if (RTCHECK(ok_address(M, XP))) {\ if (XP->child[0] == X) \ XP->child[0] = R;\ else \ XP->child[1] = R;\ }\ else\ CORRUPTION_ERROR_ACTION(M);\ if (R != 0) {\ if (RTCHECK(ok_address(M, R))) {\ tchunkptr C0, C1;\ R->parent = XP;\ if ((C0 = X->child[0]) != 0) {\ if (RTCHECK(ok_address(M, C0))) {\ R->child[0] = C0;\ C0->parent = R;\ }\ else\ CORRUPTION_ERROR_ACTION(M);\ }\ if ((C1 = X->child[1]) != 0) {\ if (RTCHECK(ok_address(M, C1))) {\ R->child[1] = C1;\ C1->parent = R;\ }\ else\ CORRUPTION_ERROR_ACTION(M);\ }\ }\ else\ CORRUPTION_ERROR_ACTION(M);\ }\ }\ } /* Relays to large vs small bin operations */ #define insert_chunk(M, P, S)\ if (is_small(S)) insert_small_chunk(M, P, S)\ else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } #define unlink_chunk(M, P, S)\ if (is_small(S)) unlink_small_chunk(M, P, S)\ else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } /* Relays to internal calls to malloc/free from realloc, memalign etc */ #if ONLY_MSPACES #define internal_malloc(m, b) mspace_malloc(m, b) #define internal_free(m, mem) mspace_free(m,mem); #else /* ONLY_MSPACES */ #if MSPACES #define internal_malloc(m, b)\ ((m == gm)? dlmalloc(b) : mspace_malloc(m, b)) #define internal_free(m, mem)\ if (m == gm) dlfree(mem); else mspace_free(m,mem); #else /* MSPACES */ #define internal_malloc(m, b) dlmalloc(b) #define internal_free(m, mem) dlfree(mem) #endif /* MSPACES */ #endif /* ONLY_MSPACES */ /* ----------------------- Direct-mmapping chunks ----------------------- */ /* Directly mmapped chunks are set up with an offset to the start of the mmapped region stored in the prev_foot field of the chunk. This allows reconstruction of the required argument to MUNMAP when freed, and also allows adjustment of the returned chunk to meet alignment requirements (especially in memalign). */ /* Malloc using mmap */ static void* mmap_alloc(mstate m, size_t nb) { size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); if (m->footprint_limit != 0) { size_t fp = m->footprint + mmsize; if (fp <= m->footprint || fp > m->footprint_limit) return 0; } if (mmsize > nb) { /* Check for wrap around 0 */ char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); if (mm != CMFAIL) { size_t offset = align_offset(chunk2mem(mm)); size_t psize = mmsize - offset - MMAP_FOOT_PAD; mchunkptr p = (mchunkptr)(mm + offset); p->prev_foot = offset; p->head = psize; mark_inuse_foot(m, p, psize); chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; if (m->least_addr == 0 || mm < m->least_addr) m->least_addr = mm; if ((m->footprint += mmsize) > m->max_footprint) m->max_footprint = m->footprint; assert(is_aligned(chunk2mem(p))); check_mmapped_chunk(m, p); return chunk2mem(p); } } return 0; } /* Realloc using mmap */ static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { size_t oldsize = chunksize(oldp); (void)flags; /* placate people compiling -Wunused */ if (is_small(nb)) /* Can't shrink mmap regions below small size */ return 0; /* Keep old chunk if big enough but not too big */ if (oldsize >= nb + SIZE_T_SIZE && (oldsize - nb) <= (mparams.granularity << 1)) return oldp; else { size_t offset = oldp->prev_foot; size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); char* cp = (char*)CALL_MREMAP((char*)oldp - offset, oldmmsize, newmmsize, flags); if (cp != CMFAIL) { mchunkptr newp = (mchunkptr)(cp + offset); size_t psize = newmmsize - offset - MMAP_FOOT_PAD; newp->head = psize; mark_inuse_foot(m, newp, psize); chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; if (cp < m->least_addr) m->least_addr = cp; if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) m->max_footprint = m->footprint; check_mmapped_chunk(m, newp); return newp; } } return 0; } /* -------------------------- mspace management -------------------------- */ /* Initialize top chunk and its size */ static void init_top(mstate m, mchunkptr p, size_t psize) { /* Ensure alignment */ size_t offset = align_offset(chunk2mem(p)); p = (mchunkptr)((char*)p + offset); psize -= offset; m->top = p; m->topsize = psize; p->head = psize | PINUSE_BIT; /* set size of fake trailing chunk holding overhead space only once */ chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; m->trim_check = mparams.trim_threshold; /* reset on each update */ } /* Initialize bins for a new mstate that is otherwise zeroed out */ static void init_bins(mstate m) { /* Establish circular links for smallbins */ bindex_t i; for (i = 0; i < NSMALLBINS; ++i) { sbinptr bin = smallbin_at(m,i); bin->fd = bin->bk = bin; } } #if PROCEED_ON_ERROR /* default corruption action */ static void reset_on_error(mstate m) { int i; ++malloc_corruption_error_count; /* Reinitialize fields to forget about all memory */ m->smallmap = m->treemap = 0; m->dvsize = m->topsize = 0; m->seg.base = 0; m->seg.size = 0; m->seg.next = 0; m->top = m->dv = 0; for (i = 0; i < NTREEBINS; ++i) *treebin_at(m, i) = 0; init_bins(m); } #endif /* PROCEED_ON_ERROR */ /* Allocate chunk and prepend remainder with chunk in successor base. */ static void* prepend_alloc(mstate m, char* newbase, char* oldbase, size_t nb) { mchunkptr p = align_as_chunk(newbase); mchunkptr oldfirst = align_as_chunk(oldbase); size_t psize = (char*)oldfirst - (char*)p; mchunkptr q = chunk_plus_offset(p, nb); size_t qsize = psize - nb; set_size_and_pinuse_of_inuse_chunk(m, p, nb); assert((char*)oldfirst > (char*)q); assert(pinuse(oldfirst)); assert(qsize >= MIN_CHUNK_SIZE); /* consolidate remainder with first chunk of old base */ if (oldfirst == m->top) { size_t tsize = m->topsize += qsize; m->top = q; q->head = tsize | PINUSE_BIT; check_top_chunk(m, q); } else if (oldfirst == m->dv) { size_t dsize = m->dvsize += qsize; m->dv = q; set_size_and_pinuse_of_free_chunk(q, dsize); } else { if (!is_inuse(oldfirst)) { size_t nsize = chunksize(oldfirst); unlink_chunk(m, oldfirst, nsize); oldfirst = chunk_plus_offset(oldfirst, nsize); qsize += nsize; } set_free_with_pinuse(q, qsize, oldfirst); insert_chunk(m, q, qsize); check_free_chunk(m, q); } check_malloced_chunk(m, chunk2mem(p), nb); return chunk2mem(p); } /* Add a segment to hold a new noncontiguous region */ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { /* Determine locations and sizes of segment, fenceposts, old top */ char* old_top = (char*)m->top; msegmentptr oldsp = segment_holding(m, old_top); char* old_end = oldsp->base + oldsp->size; size_t ssize = pad_request(sizeof(struct malloc_segment)); char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); size_t offset = align_offset(chunk2mem(rawsp)); char* asp = rawsp + offset; char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; mchunkptr sp = (mchunkptr)csp; msegmentptr ss = (msegmentptr)(chunk2mem(sp)); mchunkptr tnext = chunk_plus_offset(sp, ssize); mchunkptr p = tnext; int nfences = 0; /* reset top to new space */ init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); /* Set up segment record */ assert(is_aligned(ss)); set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); *ss = m->seg; /* Push current record */ m->seg.base = tbase; m->seg.size = tsize; m->seg.sflags = mmapped; m->seg.next = ss; /* Insert trailing fenceposts */ for (;;) { mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); p->head = FENCEPOST_HEAD; ++nfences; if ((char*)(&(nextp->head)) < old_end) p = nextp; else break; } assert(nfences >= 2); /* Insert the rest of old top into a bin as an ordinary free chunk */ if (csp != old_top) { mchunkptr q = (mchunkptr)old_top; size_t psize = csp - old_top; mchunkptr tn = chunk_plus_offset(q, psize); set_free_with_pinuse(q, psize, tn); insert_chunk(m, q, psize); } check_top_chunk(m, m->top); } /* -------------------------- System allocation -------------------------- */ /* Get memory from system using MORECORE or MMAP */ static void* sys_alloc(mstate m, size_t nb) { char* tbase = CMFAIL; size_t tsize = 0; flag_t mmap_flag = 0; size_t asize; /* allocation size */ ensure_initialization(); /* Directly map large chunks, but only if already initialized */ if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { void* mem = mmap_alloc(m, nb); if (mem != 0) return mem; } asize = granularity_align(nb + SYS_ALLOC_PADDING); if (asize <= nb) return 0; /* wraparound */ if (m->footprint_limit != 0) { size_t fp = m->footprint + asize; if (fp <= m->footprint || fp > m->footprint_limit) return 0; } /* Try getting memory in any of three ways (in most-preferred to least-preferred order): 1. A call to MORECORE that can normally contiguously extend memory. (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or or main space is mmapped or a previous contiguous call failed) 2. A call to MMAP new space (disabled if not HAVE_MMAP). Note that under the default settings, if MORECORE is unable to fulfill a request, and HAVE_MMAP is true, then mmap is used as a noncontiguous system allocator. This is a useful backup strategy for systems with holes in address spaces -- in this case sbrk cannot contiguously expand the heap, but mmap may be able to find space. 3. A call to MORECORE that cannot usually contiguously extend memory. (disabled if not HAVE_MORECORE) In all cases, we need to request enough bytes from system to ensure we can malloc nb bytes upon success, so pad with enough space for top_foot, plus alignment-pad to make sure we don't lose bytes if not on boundary, and round this up to a granularity unit. */ if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { char* br = CMFAIL; size_t ssize = asize; /* sbrk call size */ msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); ACQUIRE_MALLOC_GLOBAL_LOCK(); if (ss == 0) { /* First time through or recovery */ char* base = (char*)CALL_MORECORE(0); if (base != CMFAIL) { size_t fp; /* Adjust to end on a page boundary */ if (!is_page_aligned(base)) ssize += (page_align((size_t)base) - (size_t)base); fp = m->footprint + ssize; /* recheck limits */ if (ssize > nb && ssize < HALF_MAX_SIZE_T && (m->footprint_limit == 0 || (fp > m->footprint && fp <= m->footprint_limit)) && (br = (char*)(CALL_MORECORE(ssize))) == base) { tbase = base; tsize = ssize; } } } else { /* Subtract out existing available top space from MORECORE request. */ ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); /* Use mem here only if it did continuously extend old space */ if (ssize < HALF_MAX_SIZE_T && (br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) { tbase = br; tsize = ssize; } } if (tbase == CMFAIL) { /* Cope with partial failure */ if (br != CMFAIL) { /* Try to use/extend the space we did get */ if (ssize < HALF_MAX_SIZE_T && ssize < nb + SYS_ALLOC_PADDING) { size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize); if (esize < HALF_MAX_SIZE_T) { char* end = (char*)CALL_MORECORE(esize); if (end != CMFAIL) ssize += esize; else { /* Can't use; try to release */ (void) CALL_MORECORE(-ssize); br = CMFAIL; } } } } if (br != CMFAIL) { /* Use the space we did get */ tbase = br; tsize = ssize; } else disable_contiguous(m); /* Don't try contiguous path in the future */ } RELEASE_MALLOC_GLOBAL_LOCK(); } if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ char* mp = (char*)(CALL_MMAP(asize)); if (mp != CMFAIL) { tbase = mp; tsize = asize; mmap_flag = USE_MMAP_BIT; } } if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ if (asize < HALF_MAX_SIZE_T) { char* br = CMFAIL; char* end = CMFAIL; ACQUIRE_MALLOC_GLOBAL_LOCK(); br = (char*)(CALL_MORECORE(asize)); end = (char*)(CALL_MORECORE(0)); RELEASE_MALLOC_GLOBAL_LOCK(); if (br != CMFAIL && end != CMFAIL && br < end) { size_t ssize = end - br; if (ssize > nb + TOP_FOOT_SIZE) { tbase = br; tsize = ssize; } } } } if (tbase != CMFAIL) { if ((m->footprint += tsize) > m->max_footprint) m->max_footprint = m->footprint; if (!is_initialized(m)) { /* first-time initialization */ if (m->least_addr == 0 || tbase < m->least_addr) m->least_addr = tbase; m->seg.base = tbase; m->seg.size = tsize; m->seg.sflags = mmap_flag; m->magic = mparams.magic; m->release_checks = MAX_RELEASE_CHECK_RATE; init_bins(m); #if !ONLY_MSPACES if (is_global(m)) init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); else #endif { /* Offset top by embedded malloc_state */ mchunkptr mn = next_chunk(mem2chunk(m)); init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); } } else { /* Try to merge with an existing segment */ msegmentptr sp = &m->seg; /* Only consider most recent segment if traversal suppressed */ while (sp != 0 && tbase != sp->base + sp->size) sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; if (sp != 0 && !is_extern_segment(sp) && (sp->sflags & USE_MMAP_BIT) == mmap_flag && segment_holds(sp, m->top)) { /* append */ sp->size += tsize; init_top(m, m->top, m->topsize + tsize); } else { if (tbase < m->least_addr) m->least_addr = tbase; sp = &m->seg; while (sp != 0 && sp->base != tbase + tsize) sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; if (sp != 0 && !is_extern_segment(sp) && (sp->sflags & USE_MMAP_BIT) == mmap_flag) { char* oldbase = sp->base; sp->base = tbase; sp->size += tsize; return prepend_alloc(m, tbase, oldbase, nb); } else add_segment(m, tbase, tsize, mmap_flag); } } if (nb < m->topsize) { /* Allocate from new or extended top space */ size_t rsize = m->topsize -= nb; mchunkptr p = m->top; mchunkptr r = m->top = chunk_plus_offset(p, nb); r->head = rsize | PINUSE_BIT; set_size_and_pinuse_of_inuse_chunk(m, p, nb); check_top_chunk(m, m->top); check_malloced_chunk(m, chunk2mem(p), nb); return chunk2mem(p); } } MALLOC_FAILURE_ACTION; return 0; } /* ----------------------- system deallocation -------------------------- */ /* Unmap and unlink any mmapped segments that don't contain used chunks */ static size_t release_unused_segments(mstate m) { size_t released = 0; int nsegs = 0; msegmentptr pred = &m->seg; msegmentptr sp = pred->next; while (sp != 0) { char* base = sp->base; size_t size = sp->size; msegmentptr next = sp->next; ++nsegs; if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { mchunkptr p = align_as_chunk(base); size_t psize = chunksize(p); /* Can unmap if first chunk holds entire segment and not pinned */ if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { tchunkptr tp = (tchunkptr)p; assert(segment_holds(sp, (char*)sp)); if (p == m->dv) { m->dv = 0; m->dvsize = 0; } else { unlink_large_chunk(m, tp); } if (CALL_MUNMAP(base, size) == 0) { released += size; m->footprint -= size; /* unlink obsoleted record */ sp = pred; sp->next = next; } else { /* back out if cannot unmap */ insert_large_chunk(m, tp, psize); } } } if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ break; pred = sp; sp = next; } /* Reset check counter */ m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)? (size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE); return released; } static int sys_trim(mstate m, size_t pad) { size_t released = 0; ensure_initialization(); if (pad < MAX_REQUEST && is_initialized(m)) { pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ if (m->topsize > pad) { /* Shrink top space in granularity-size units, keeping at least one */ size_t unit = mparams.granularity; size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - SIZE_T_ONE) * unit; msegmentptr sp = segment_holding(m, (char*)m->top); if (!is_extern_segment(sp)) { if (is_mmapped_segment(sp)) { if (HAVE_MMAP && sp->size >= extra && !has_segment_link(m, sp)) { /* can't shrink if pinned */ size_t newsize = sp->size - extra; (void)newsize; /* placate people compiling -Wunused-variable */ /* Prefer mremap, fall back to munmap */ if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { released = extra; } } } else if (HAVE_MORECORE) { if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; ACQUIRE_MALLOC_GLOBAL_LOCK(); { /* Make sure end of memory is where we last set it. */ char* old_br = (char*)(CALL_MORECORE(0)); if (old_br == sp->base + sp->size) { char* rel_br = (char*)(CALL_MORECORE(-extra)); char* new_br = (char*)(CALL_MORECORE(0)); if (rel_br != CMFAIL && new_br < old_br) released = old_br - new_br; } } RELEASE_MALLOC_GLOBAL_LOCK(); } } if (released != 0) { sp->size -= released; m->footprint -= released; init_top(m, m->top, m->topsize - released); check_top_chunk(m, m->top); } } /* Unmap any unused mmapped segments */ if (HAVE_MMAP) released += release_unused_segments(m); /* On failure, disable autotrim to avoid repeated failed future calls */ if (released == 0 && m->topsize > m->trim_check) m->trim_check = MAX_SIZE_T; } return (released != 0)? 1 : 0; } /* Consolidate and bin a chunk. Differs from exported versions of free mainly in that the chunk need not be marked as inuse. */ static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { mchunkptr next = chunk_plus_offset(p, psize); if (!pinuse(p)) { mchunkptr prev; size_t prevsize = p->prev_foot; if (is_mmapped(p)) { psize += prevsize + MMAP_FOOT_PAD; if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) m->footprint -= psize; return; } prev = chunk_minus_offset(p, prevsize); psize += prevsize; p = prev; if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */ if (p != m->dv) { unlink_chunk(m, p, prevsize); } else if ((next->head & INUSE_BITS) == INUSE_BITS) { m->dvsize = psize; set_free_with_pinuse(p, psize, next); return; } } else { CORRUPTION_ERROR_ACTION(m); return; } } if (RTCHECK(ok_address(m, next))) { if (!cinuse(next)) { /* consolidate forward */ if (next == m->top) { size_t tsize = m->topsize += psize; m->top = p; p->head = tsize | PINUSE_BIT; if (p == m->dv) { m->dv = 0; m->dvsize = 0; } return; } else if (next == m->dv) { size_t dsize = m->dvsize += psize; m->dv = p; set_size_and_pinuse_of_free_chunk(p, dsize); return; } else { size_t nsize = chunksize(next); psize += nsize; unlink_chunk(m, next, nsize); set_size_and_pinuse_of_free_chunk(p, psize); if (p == m->dv) { m->dvsize = psize; return; } } } else { set_free_with_pinuse(p, psize, next); } insert_chunk(m, p, psize); } else { CORRUPTION_ERROR_ACTION(m); } } /* ---------------------------- malloc --------------------------- */ /* allocate a large request from the best fitting chunk in a treebin */ static void* tmalloc_large(mstate m, size_t nb) { tchunkptr v = 0; size_t rsize = -nb; /* Unsigned negation */ tchunkptr t; bindex_t idx; compute_tree_index(nb, idx); if ((t = *treebin_at(m, idx)) != 0) { /* Traverse tree for this bin looking for node with size == nb */ size_t sizebits = nb << leftshift_for_tree_index(idx); tchunkptr rst = 0; /* The deepest untaken right subtree */ for (;;) { tchunkptr rt; size_t trem = chunksize(t) - nb; if (trem < rsize) { v = t; if ((rsize = trem) == 0) break; } rt = t->child[1]; t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; if (rt != 0 && rt != t) rst = rt; if (t == 0) { t = rst; /* set t to least subtree holding sizes > nb */ break; } sizebits <<= 1; } } if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; if (leftbits != 0) { bindex_t i; binmap_t leastbit = least_bit(leftbits); compute_bit2idx(leastbit, i); t = *treebin_at(m, i); } } while (t != 0) { /* find smallest of tree or subtree */ size_t trem = chunksize(t) - nb; if (trem < rsize) { rsize = trem; v = t; } t = leftmost_child(t); } /* If dv is a better fit, return 0 so malloc will use it */ if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { if (RTCHECK(ok_address(m, v))) { /* split */ mchunkptr r = chunk_plus_offset(v, nb); assert(chunksize(v) == rsize + nb); if (RTCHECK(ok_next(v, r))) { unlink_large_chunk(m, v); if (rsize < MIN_CHUNK_SIZE) set_inuse_and_pinuse(m, v, (rsize + nb)); else { set_size_and_pinuse_of_inuse_chunk(m, v, nb); set_size_and_pinuse_of_free_chunk(r, rsize); insert_chunk(m, r, rsize); } return chunk2mem(v); } } CORRUPTION_ERROR_ACTION(m); } return 0; } /* allocate a small request from the best fitting chunk in a treebin */ static void* tmalloc_small(mstate m, size_t nb) { tchunkptr t, v; size_t rsize; bindex_t i; binmap_t leastbit = least_bit(m->treemap); compute_bit2idx(leastbit, i); v = t = *treebin_at(m, i); rsize = chunksize(t) - nb; while ((t = leftmost_child(t)) != 0) { size_t trem = chunksize(t) - nb; if (trem < rsize) { rsize = trem; v = t; } } if (RTCHECK(ok_address(m, v))) { mchunkptr r = chunk_plus_offset(v, nb); assert(chunksize(v) == rsize + nb); if (RTCHECK(ok_next(v, r))) { unlink_large_chunk(m, v); if (rsize < MIN_CHUNK_SIZE) set_inuse_and_pinuse(m, v, (rsize + nb)); else { set_size_and_pinuse_of_inuse_chunk(m, v, nb); set_size_and_pinuse_of_free_chunk(r, rsize); replace_dv(m, r, rsize); } return chunk2mem(v); } } CORRUPTION_ERROR_ACTION(m); return 0; } #if !ONLY_MSPACES void* dlmalloc(size_t bytes) { /* Basic algorithm: If a small request (< 256 bytes minus per-chunk overhead): 1. If one exists, use a remainderless chunk in associated smallbin. (Remainderless means that there are too few excess bytes to represent as a chunk.) 2. If it is big enough, use the dv chunk, which is normally the chunk adjacent to the one used for the most recent small request. 3. If one exists, split the smallest available chunk in a bin, saving remainder in dv. 4. If it is big enough, use the top chunk. 5. If available, get memory from system and use it Otherwise, for a large request: 1. Find the smallest available binned chunk that fits, and use it if it is better fitting than dv chunk, splitting if necessary. 2. If better fitting than any binned chunk, use the dv chunk. 3. If it is big enough, use the top chunk. 4. If request size >= mmap threshold, try to directly mmap this chunk. 5. If available, get memory from system and use it The ugly goto's here ensure that postaction occurs along all paths. */ #if USE_LOCKS ensure_initialization(); /* initialize in sys_alloc if not using locks */ #endif if (!PREACTION(gm)) { void* mem; size_t nb; if (bytes <= MAX_SMALL_REQUEST) { bindex_t idx; binmap_t smallbits; nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); idx = small_index(nb); smallbits = gm->smallmap >> idx; if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ mchunkptr b, p; idx += ~smallbits & 1; /* Uses next bin if idx empty */ b = smallbin_at(gm, idx); p = b->fd; assert(chunksize(p) == small_index2size(idx)); unlink_first_small_chunk(gm, b, p, idx); set_inuse_and_pinuse(gm, p, small_index2size(idx)); mem = chunk2mem(p); check_malloced_chunk(gm, mem, nb); goto postaction; } else if (nb > gm->dvsize) { if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ mchunkptr b, p, r; size_t rsize; bindex_t i; binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); binmap_t leastbit = least_bit(leftbits); compute_bit2idx(leastbit, i); b = smallbin_at(gm, i); p = b->fd; assert(chunksize(p) == small_index2size(i)); unlink_first_small_chunk(gm, b, p, i); rsize = small_index2size(i) - nb; /* Fit here cannot be remainderless if 4byte sizes */ if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) set_inuse_and_pinuse(gm, p, small_index2size(i)); else { set_size_and_pinuse_of_inuse_chunk(gm, p, nb); r = chunk_plus_offset(p, nb); set_size_and_pinuse_of_free_chunk(r, rsize); replace_dv(gm, r, rsize); } mem = chunk2mem(p); check_malloced_chunk(gm, mem, nb); goto postaction; } else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { check_malloced_chunk(gm, mem, nb); goto postaction; } } } else if (bytes >= MAX_REQUEST) nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ else { nb = pad_request(bytes); if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { check_malloced_chunk(gm, mem, nb); goto postaction; } } if (nb <= gm->dvsize) { size_t rsize = gm->dvsize - nb; mchunkptr p = gm->dv; if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ mchunkptr r = gm->dv = chunk_plus_offset(p, nb); gm->dvsize = rsize; set_size_and_pinuse_of_free_chunk(r, rsize); set_size_and_pinuse_of_inuse_chunk(gm, p, nb); } else { /* exhaust dv */ size_t dvs = gm->dvsize; gm->dvsize = 0; gm->dv = 0; set_inuse_and_pinuse(gm, p, dvs); } mem = chunk2mem(p); check_malloced_chunk(gm, mem, nb); goto postaction; } else if (nb < gm->topsize) { /* Split top */ size_t rsize = gm->topsize -= nb; mchunkptr p = gm->top; mchunkptr r = gm->top = chunk_plus_offset(p, nb); r->head = rsize | PINUSE_BIT; set_size_and_pinuse_of_inuse_chunk(gm, p, nb); mem = chunk2mem(p); check_top_chunk(gm, gm->top); check_malloced_chunk(gm, mem, nb); goto postaction; } mem = sys_alloc(gm, nb); postaction: POSTACTION(gm); return mem; } return 0; } /* ---------------------------- free --------------------------- */ void dlfree(void* mem) { /* Consolidate freed chunks with preceeding or succeeding bordering free chunks, if they exist, and then place in a bin. Intermixed with special cases for top, dv, mmapped chunks, and usage errors. */ if (mem != 0) { mchunkptr p = mem2chunk(mem); #if FOOTERS mstate fm = get_mstate_for(p); if (!ok_magic(fm)) { USAGE_ERROR_ACTION(fm, p); return; } #else /* FOOTERS */ #define fm gm #endif /* FOOTERS */ if (!PREACTION(fm)) { check_inuse_chunk(fm, p); if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { size_t psize = chunksize(p); mchunkptr next = chunk_plus_offset(p, psize); if (!pinuse(p)) { size_t prevsize = p->prev_foot; if (is_mmapped(p)) { psize += prevsize + MMAP_FOOT_PAD; if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) fm->footprint -= psize; goto postaction; } else { mchunkptr prev = chunk_minus_offset(p, prevsize); psize += prevsize; p = prev; if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ if (p != fm->dv) { unlink_chunk(fm, p, prevsize); } else if ((next->head & INUSE_BITS) == INUSE_BITS) { fm->dvsize = psize; set_free_with_pinuse(p, psize, next); goto postaction; } } else goto erroraction; } } if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { if (!cinuse(next)) { /* consolidate forward */ if (next == fm->top) { size_t tsize = fm->topsize += psize; fm->top = p; p->head = tsize | PINUSE_BIT; if (p == fm->dv) { fm->dv = 0; fm->dvsize = 0; } if (should_trim(fm, tsize)) sys_trim(fm, 0); goto postaction; } else if (next == fm->dv) { size_t dsize = fm->dvsize += psize; fm->dv = p; set_size_and_pinuse_of_free_chunk(p, dsize); goto postaction; } else { size_t nsize = chunksize(next); psize += nsize; unlink_chunk(fm, next, nsize); set_size_and_pinuse_of_free_chunk(p, psize); if (p == fm->dv) { fm->dvsize = psize; goto postaction; } } } else set_free_with_pinuse(p, psize, next); if (is_small(psize)) { insert_small_chunk(fm, p, psize); check_free_chunk(fm, p); } else { tchunkptr tp = (tchunkptr)p; insert_large_chunk(fm, tp, psize); check_free_chunk(fm, p); if (--fm->release_checks == 0) release_unused_segments(fm); } goto postaction; } } erroraction: USAGE_ERROR_ACTION(fm, p); postaction: POSTACTION(fm); } } #if !FOOTERS #undef fm #endif /* FOOTERS */ } void* dlcalloc(size_t n_elements, size_t elem_size) { void* mem; size_t req = 0; if (n_elements != 0) { req = n_elements * elem_size; if (((n_elements | elem_size) & ~(size_t)0xffff) && (req / n_elements != elem_size)) req = MAX_SIZE_T; /* force downstream failure on overflow */ } mem = dlmalloc(req); if (mem != 0 && calloc_must_clear(mem2chunk(mem))) memset(mem, 0, req); return mem; } #endif /* !ONLY_MSPACES */ /* ------------ Internal support for realloc, memalign, etc -------------- */ /* Try to realloc; only in-place unless can_move true */ static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, int can_move) { mchunkptr newp = 0; size_t oldsize = chunksize(p); mchunkptr next = chunk_plus_offset(p, oldsize); if (RTCHECK(ok_address(m, p) && ok_inuse(p) && ok_next(p, next) && ok_pinuse(next))) { if (is_mmapped(p)) { newp = mmap_resize(m, p, nb, can_move); } else if (oldsize >= nb) { /* already big enough */ size_t rsize = oldsize - nb; if (rsize >= MIN_CHUNK_SIZE) { /* split off remainder */ mchunkptr r = chunk_plus_offset(p, nb); set_inuse(m, p, nb); set_inuse(m, r, rsize); dispose_chunk(m, r, rsize); } newp = p; } else if (next == m->top) { /* extend into top */ if (oldsize + m->topsize > nb) { size_t newsize = oldsize + m->topsize; size_t newtopsize = newsize - nb; mchunkptr newtop = chunk_plus_offset(p, nb); set_inuse(m, p, nb); newtop->head = newtopsize |PINUSE_BIT; m->top = newtop; m->topsize = newtopsize; newp = p; } } else if (next == m->dv) { /* extend into dv */ size_t dvs = m->dvsize; if (oldsize + dvs >= nb) { size_t dsize = oldsize + dvs - nb; if (dsize >= MIN_CHUNK_SIZE) { mchunkptr r = chunk_plus_offset(p, nb); mchunkptr n = chunk_plus_offset(r, dsize); set_inuse(m, p, nb); set_size_and_pinuse_of_free_chunk(r, dsize); clear_pinuse(n); m->dvsize = dsize; m->dv = r; } else { /* exhaust dv */ size_t newsize = oldsize + dvs; set_inuse(m, p, newsize); m->dvsize = 0; m->dv = 0; } newp = p; } } else if (!cinuse(next)) { /* extend into next free chunk */ size_t nextsize = chunksize(next); if (oldsize + nextsize >= nb) { size_t rsize = oldsize + nextsize - nb; unlink_chunk(m, next, nextsize); if (rsize < MIN_CHUNK_SIZE) { size_t newsize = oldsize + nextsize; set_inuse(m, p, newsize); } else { mchunkptr r = chunk_plus_offset(p, nb); set_inuse(m, p, nb); set_inuse(m, r, rsize); dispose_chunk(m, r, rsize); } newp = p; } } } else { USAGE_ERROR_ACTION(m, chunk2mem(p)); } return newp; } static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { void* mem = 0; if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ alignment = MIN_CHUNK_SIZE; if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ size_t a = MALLOC_ALIGNMENT << 1; while (a < alignment) a <<= 1; alignment = a; } if (bytes >= MAX_REQUEST - alignment) { if (m != 0) { /* Test isn't needed but avoids compiler warning */ MALLOC_FAILURE_ACTION; } } else { size_t nb = request2size(bytes); size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; mem = internal_malloc(m, req); if (mem != 0) { mchunkptr p = mem2chunk(mem); if (PREACTION(m)) return 0; if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */ /* Find an aligned spot inside chunk. Since we need to give back leading space in a chunk of at least MIN_CHUNK_SIZE, if the first calculation places us at a spot with less than MIN_CHUNK_SIZE leader, we can move to the next aligned spot. We've allocated enough total room so that this is always possible. */ char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment - SIZE_T_ONE)) & -alignment)); char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? br : br+alignment; mchunkptr newp = (mchunkptr)pos; size_t leadsize = pos - (char*)(p); size_t newsize = chunksize(p) - leadsize; if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ newp->prev_foot = p->prev_foot + leadsize; newp->head = newsize; } else { /* Otherwise, give back leader, use the rest */ set_inuse(m, newp, newsize); set_inuse(m, p, leadsize); dispose_chunk(m, p, leadsize); } p = newp; } /* Give back spare room at the end */ if (!is_mmapped(p)) { size_t size = chunksize(p); if (size > nb + MIN_CHUNK_SIZE) { size_t remainder_size = size - nb; mchunkptr remainder = chunk_plus_offset(p, nb); set_inuse(m, p, nb); set_inuse(m, remainder, remainder_size); dispose_chunk(m, remainder, remainder_size); } } mem = chunk2mem(p); assert (chunksize(p) >= nb); assert(((size_t)mem & (alignment - 1)) == 0); check_inuse_chunk(m, p); POSTACTION(m); } } return mem; } /* Common support for independent_X routines, handling all of the combinations that can result. The opts arg has: bit 0 set if all elements are same size (using sizes[0]) bit 1 set if elements should be zeroed */ static void** ialloc(mstate m, size_t n_elements, size_t* sizes, int opts, void* chunks[]) { size_t element_size; /* chunksize of each element, if all same */ size_t contents_size; /* total size of elements */ size_t array_size; /* request size of pointer array */ void* mem; /* malloced aggregate space */ mchunkptr p; /* corresponding chunk */ size_t remainder_size; /* remaining bytes while splitting */ void** marray; /* either "chunks" or malloced ptr array */ mchunkptr array_chunk; /* chunk for malloced ptr array */ flag_t was_enabled; /* to disable mmap */ size_t size; size_t i; ensure_initialization(); /* compute array length, if needed */ if (chunks != 0) { if (n_elements == 0) return chunks; /* nothing to do */ marray = chunks; array_size = 0; } else { /* if empty req, must still return chunk representing empty array */ if (n_elements == 0) return (void**)internal_malloc(m, 0); marray = 0; array_size = request2size(n_elements * (sizeof(void*))); } /* compute total element size */ if (opts & 0x1) { /* all-same-size */ element_size = request2size(*sizes); contents_size = n_elements * element_size; } else { /* add up all the sizes */ element_size = 0; contents_size = 0; for (i = 0; i != n_elements; ++i) contents_size += request2size(sizes[i]); } size = contents_size + array_size; /* Allocate the aggregate chunk. First disable direct-mmapping so malloc won't use it, since we would not be able to later free/realloc space internal to a segregated mmap region. */ was_enabled = use_mmap(m); disable_mmap(m); mem = internal_malloc(m, size - CHUNK_OVERHEAD); if (was_enabled) enable_mmap(m); if (mem == 0) return 0; if (PREACTION(m)) return 0; p = mem2chunk(mem); remainder_size = chunksize(p); assert(!is_mmapped(p)); if (opts & 0x2) { /* optionally clear the elements */ memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); } /* If not provided, allocate the pointer array as final part of chunk */ if (marray == 0) { size_t array_chunk_size; array_chunk = chunk_plus_offset(p, contents_size); array_chunk_size = remainder_size - contents_size; marray = (void**) (chunk2mem(array_chunk)); set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); remainder_size = contents_size; } /* split out elements */ for (i = 0; ; ++i) { marray[i] = chunk2mem(p); if (i != n_elements-1) { if (element_size != 0) size = element_size; else size = request2size(sizes[i]); remainder_size -= size; set_size_and_pinuse_of_inuse_chunk(m, p, size); p = chunk_plus_offset(p, size); } else { /* the final element absorbs any overallocation slop */ set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); break; } } #if DEBUG if (marray != chunks) { /* final element must have exactly exhausted chunk */ if (element_size != 0) { assert(remainder_size == element_size); } else { assert(remainder_size == request2size(sizes[i])); } check_inuse_chunk(m, mem2chunk(marray)); } for (i = 0; i != n_elements; ++i) check_inuse_chunk(m, mem2chunk(marray[i])); #endif /* DEBUG */ POSTACTION(m); return marray; } /* Try to free all pointers in the given array. Note: this could be made faster, by delaying consolidation, at the price of disabling some user integrity checks, We still optimize some consolidations by combining adjacent chunks before freeing, which will occur often if allocated with ialloc or the array is sorted. */ static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) { size_t unfreed = 0; if (!PREACTION(m)) { void** a; void** fence = &(array[nelem]); for (a = array; a != fence; ++a) { void* mem = *a; if (mem != 0) { mchunkptr p = mem2chunk(mem); size_t psize = chunksize(p); #if FOOTERS if (get_mstate_for(p) != m) { ++unfreed; continue; } #endif check_inuse_chunk(m, p); *a = 0; if (RTCHECK(ok_address(m, p) && ok_inuse(p))) { void ** b = a + 1; /* try to merge with next chunk */ mchunkptr next = next_chunk(p); if (b != fence && *b == chunk2mem(next)) { size_t newsize = chunksize(next) + psize; set_inuse(m, p, newsize); *b = chunk2mem(p); } else dispose_chunk(m, p, psize); } else { CORRUPTION_ERROR_ACTION(m); break; } } } if (should_trim(m, m->topsize)) sys_trim(m, 0); POSTACTION(m); } return unfreed; } /* Traversal */ #if MALLOC_INSPECT_ALL static void internal_inspect_all(mstate m, void(*handler)(void *start, void *end, size_t used_bytes, void* callback_arg), void* arg) { if (is_initialized(m)) { mchunkptr top = m->top; msegmentptr s; for (s = &m->seg; s != 0; s = s->next) { mchunkptr q = align_as_chunk(s->base); while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) { mchunkptr next = next_chunk(q); size_t sz = chunksize(q); size_t used; void* start; if (is_inuse(q)) { used = sz - CHUNK_OVERHEAD; /* must not be mmapped */ start = chunk2mem(q); } else { used = 0; if (is_small(sz)) { /* offset by possible bookkeeping */ start = (void*)((char*)q + sizeof(struct malloc_chunk)); } else { start = (void*)((char*)q + sizeof(struct malloc_tree_chunk)); } } if (start < (void*)next) /* skip if all space is bookkeeping */ handler(start, next, used, arg); if (q == top) break; q = next; } } } } #endif /* MALLOC_INSPECT_ALL */ /* ------------------ Exported realloc, memalign, etc -------------------- */ #if !ONLY_MSPACES void* dlrealloc(void* oldmem, size_t bytes) { void* mem = 0; if (oldmem == 0) { mem = dlmalloc(bytes); } else if (bytes >= MAX_REQUEST) { MALLOC_FAILURE_ACTION; } #ifdef REALLOC_ZERO_BYTES_FREES else if (bytes == 0) { dlfree(oldmem); } #endif /* REALLOC_ZERO_BYTES_FREES */ else { size_t nb = request2size(bytes); mchunkptr oldp = mem2chunk(oldmem); #if ! FOOTERS mstate m = gm; #else /* FOOTERS */ mstate m = get_mstate_for(oldp); if (!ok_magic(m)) { USAGE_ERROR_ACTION(m, oldmem); return 0; } #endif /* FOOTERS */ if (!PREACTION(m)) { mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); POSTACTION(m); if (newp != 0) { check_inuse_chunk(m, newp); mem = chunk2mem(newp); } else { mem = internal_malloc(m, bytes); if (mem != 0) { size_t oc = chunksize(oldp) - overhead_for(oldp); memcpy(mem, oldmem, (oc < bytes)? oc : bytes); internal_free(m, oldmem); } } } } return mem; } void* dlrealloc_in_place(void* oldmem, size_t bytes) { void* mem = 0; if (oldmem != 0) { if (bytes >= MAX_REQUEST) { MALLOC_FAILURE_ACTION; } else { size_t nb = request2size(bytes); mchunkptr oldp = mem2chunk(oldmem); #if ! FOOTERS mstate m = gm; #else /* FOOTERS */ mstate m = get_mstate_for(oldp); if (!ok_magic(m)) { USAGE_ERROR_ACTION(m, oldmem); return 0; } #endif /* FOOTERS */ if (!PREACTION(m)) { mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); POSTACTION(m); if (newp == oldp) { check_inuse_chunk(m, newp); mem = oldmem; } } } } return mem; } void* dlmemalign(size_t alignment, size_t bytes) { if (alignment <= MALLOC_ALIGNMENT) { return dlmalloc(bytes); } return internal_memalign(gm, alignment, bytes); } int dlposix_memalign(void** pp, size_t alignment, size_t bytes) { void* mem = 0; if (alignment == MALLOC_ALIGNMENT) mem = dlmalloc(bytes); else { size_t d = alignment / sizeof(void*); size_t r = alignment % sizeof(void*); if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0) return EINVAL; else if (bytes <= MAX_REQUEST - alignment) { if (alignment < MIN_CHUNK_SIZE) alignment = MIN_CHUNK_SIZE; mem = internal_memalign(gm, alignment, bytes); } } if (mem == 0) return ENOMEM; else { *pp = mem; return 0; } } void* dlvalloc(size_t bytes) { size_t pagesz; ensure_initialization(); pagesz = mparams.page_size; return dlmemalign(pagesz, bytes); } void* dlpvalloc(size_t bytes) { size_t pagesz; ensure_initialization(); pagesz = mparams.page_size; return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); } void** dlindependent_calloc(size_t n_elements, size_t elem_size, void* chunks[]) { size_t sz = elem_size; /* serves as 1-element array */ return ialloc(gm, n_elements, &sz, 3, chunks); } void** dlindependent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]) { return ialloc(gm, n_elements, sizes, 0, chunks); } size_t dlbulk_free(void* array[], size_t nelem) { return internal_bulk_free(gm, array, nelem); } #if MALLOC_INSPECT_ALL void dlmalloc_inspect_all(void(*handler)(void *start, void *end, size_t used_bytes, void* callback_arg), void* arg) { ensure_initialization(); if (!PREACTION(gm)) { internal_inspect_all(gm, handler, arg); POSTACTION(gm); } } #endif /* MALLOC_INSPECT_ALL */ int dlmalloc_trim(size_t pad) { int result = 0; ensure_initialization(); if (!PREACTION(gm)) { result = sys_trim(gm, pad); POSTACTION(gm); } return result; } size_t dlmalloc_footprint(void) { return gm->footprint; } size_t dlmalloc_max_footprint(void) { return gm->max_footprint; } size_t dlmalloc_footprint_limit(void) { size_t maf = gm->footprint_limit; return maf == 0 ? MAX_SIZE_T : maf; } size_t dlmalloc_set_footprint_limit(size_t bytes) { size_t result; /* invert sense of 0 */ if (bytes == 0) result = granularity_align(1); /* Use minimal size */ if (bytes == MAX_SIZE_T) result = 0; /* disable */ else result = granularity_align(bytes); return gm->footprint_limit = result; } #if !NO_MALLINFO struct mallinfo dlmallinfo(void) { return internal_mallinfo(gm); } #endif /* NO_MALLINFO */ #if !NO_MALLOC_STATS void dlmalloc_stats() { internal_malloc_stats(gm); } #endif /* NO_MALLOC_STATS */ int dlmallopt(int param_number, int value) { return change_mparam(param_number, value); } size_t dlmalloc_usable_size(void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem); if (is_inuse(p)) return chunksize(p) - overhead_for(p); } return 0; } #endif /* !ONLY_MSPACES */ /* ----------------------------- user mspaces ---------------------------- */ #if MSPACES static mstate init_user_mstate(char* tbase, size_t tsize) { size_t msize = pad_request(sizeof(struct malloc_state)); mchunkptr mn; mchunkptr msp = align_as_chunk(tbase); mstate m = (mstate)(chunk2mem(msp)); memset(m, 0, msize); (void)INITIAL_LOCK(&m->mutex); msp->head = (msize|INUSE_BITS); m->seg.base = m->least_addr = tbase; m->seg.size = m->footprint = m->max_footprint = tsize; m->magic = mparams.magic; m->release_checks = MAX_RELEASE_CHECK_RATE; m->mflags = mparams.default_mflags; m->extp = 0; m->exts = 0; disable_contiguous(m); init_bins(m); mn = next_chunk(mem2chunk(m)); init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); check_top_chunk(m, m->top); return m; } mspace create_mspace(size_t capacity, int locked) { mstate m = 0; size_t msize; ensure_initialization(); msize = pad_request(sizeof(struct malloc_state)); if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { size_t rs = ((capacity == 0)? mparams.granularity : (capacity + TOP_FOOT_SIZE + msize)); size_t tsize = granularity_align(rs); char* tbase = (char*)(CALL_MMAP(tsize)); if (tbase != CMFAIL) { m = init_user_mstate(tbase, tsize); m->seg.sflags = USE_MMAP_BIT; set_lock(m, locked); } } return (mspace)m; } mspace create_mspace_with_base(void* base, size_t capacity, int locked) { mstate m = 0; size_t msize; ensure_initialization(); msize = pad_request(sizeof(struct malloc_state)); if (capacity > msize + TOP_FOOT_SIZE && capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { m = init_user_mstate((char*)base, capacity); m->seg.sflags = EXTERN_BIT; set_lock(m, locked); } return (mspace)m; } int mspace_track_large_chunks(mspace msp, int enable) { int ret = 0; mstate ms = (mstate)msp; if (!PREACTION(ms)) { if (!use_mmap(ms)) { ret = 1; } if (!enable) { enable_mmap(ms); } else { disable_mmap(ms); } POSTACTION(ms); } return ret; } size_t destroy_mspace(mspace msp) { size_t freed = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { msegmentptr sp = &ms->seg; (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */ while (sp != 0) { char* base = sp->base; size_t size = sp->size; flag_t flag = sp->sflags; (void)base; /* placate people compiling -Wunused-variable */ sp = sp->next; if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && CALL_MUNMAP(base, size) == 0) freed += size; } } else { USAGE_ERROR_ACTION(ms,ms); } return freed; } /* mspace versions of routines are near-clones of the global versions. This is not so nice but better than the alternatives. */ void* mspace_malloc(mspace msp, size_t bytes) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); return 0; } if (!PREACTION(ms)) { void* mem; size_t nb; if (bytes <= MAX_SMALL_REQUEST) { bindex_t idx; binmap_t smallbits; nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); idx = small_index(nb); smallbits = ms->smallmap >> idx; if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ mchunkptr b, p; idx += ~smallbits & 1; /* Uses next bin if idx empty */ b = smallbin_at(ms, idx); p = b->fd; assert(chunksize(p) == small_index2size(idx)); unlink_first_small_chunk(ms, b, p, idx); set_inuse_and_pinuse(ms, p, small_index2size(idx)); mem = chunk2mem(p); check_malloced_chunk(ms, mem, nb); goto postaction; } else if (nb > ms->dvsize) { if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ mchunkptr b, p, r; size_t rsize; bindex_t i; binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); binmap_t leastbit = least_bit(leftbits); compute_bit2idx(leastbit, i); b = smallbin_at(ms, i); p = b->fd; assert(chunksize(p) == small_index2size(i)); unlink_first_small_chunk(ms, b, p, i); rsize = small_index2size(i) - nb; /* Fit here cannot be remainderless if 4byte sizes */ if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) set_inuse_and_pinuse(ms, p, small_index2size(i)); else { set_size_and_pinuse_of_inuse_chunk(ms, p, nb); r = chunk_plus_offset(p, nb); set_size_and_pinuse_of_free_chunk(r, rsize); replace_dv(ms, r, rsize); } mem = chunk2mem(p); check_malloced_chunk(ms, mem, nb); goto postaction; } else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { check_malloced_chunk(ms, mem, nb); goto postaction; } } } else if (bytes >= MAX_REQUEST) nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ else { nb = pad_request(bytes); if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { check_malloced_chunk(ms, mem, nb); goto postaction; } } if (nb <= ms->dvsize) { size_t rsize = ms->dvsize - nb; mchunkptr p = ms->dv; if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ mchunkptr r = ms->dv = chunk_plus_offset(p, nb); ms->dvsize = rsize; set_size_and_pinuse_of_free_chunk(r, rsize); set_size_and_pinuse_of_inuse_chunk(ms, p, nb); } else { /* exhaust dv */ size_t dvs = ms->dvsize; ms->dvsize = 0; ms->dv = 0; set_inuse_and_pinuse(ms, p, dvs); } mem = chunk2mem(p); check_malloced_chunk(ms, mem, nb); goto postaction; } else if (nb < ms->topsize) { /* Split top */ size_t rsize = ms->topsize -= nb; mchunkptr p = ms->top; mchunkptr r = ms->top = chunk_plus_offset(p, nb); r->head = rsize | PINUSE_BIT; set_size_and_pinuse_of_inuse_chunk(ms, p, nb); mem = chunk2mem(p); check_top_chunk(ms, ms->top); check_malloced_chunk(ms, mem, nb); goto postaction; } mem = sys_alloc(ms, nb); postaction: POSTACTION(ms); return mem; } return 0; } void mspace_free(mspace msp, void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem); #if FOOTERS mstate fm = get_mstate_for(p); (void)msp; /* placate people compiling -Wunused */ #else /* FOOTERS */ mstate fm = (mstate)msp; #endif /* FOOTERS */ if (!ok_magic(fm)) { USAGE_ERROR_ACTION(fm, p); return; } if (!PREACTION(fm)) { check_inuse_chunk(fm, p); if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { size_t psize = chunksize(p); mchunkptr next = chunk_plus_offset(p, psize); if (!pinuse(p)) { size_t prevsize = p->prev_foot; if (is_mmapped(p)) { psize += prevsize + MMAP_FOOT_PAD; if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) fm->footprint -= psize; goto postaction; } else { mchunkptr prev = chunk_minus_offset(p, prevsize); psize += prevsize; p = prev; if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ if (p != fm->dv) { unlink_chunk(fm, p, prevsize); } else if ((next->head & INUSE_BITS) == INUSE_BITS) { fm->dvsize = psize; set_free_with_pinuse(p, psize, next); goto postaction; } } else goto erroraction; } } if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { if (!cinuse(next)) { /* consolidate forward */ if (next == fm->top) { size_t tsize = fm->topsize += psize; fm->top = p; p->head = tsize | PINUSE_BIT; if (p == fm->dv) { fm->dv = 0; fm->dvsize = 0; } if (should_trim(fm, tsize)) sys_trim(fm, 0); goto postaction; } else if (next == fm->dv) { size_t dsize = fm->dvsize += psize; fm->dv = p; set_size_and_pinuse_of_free_chunk(p, dsize); goto postaction; } else { size_t nsize = chunksize(next); psize += nsize; unlink_chunk(fm, next, nsize); set_size_and_pinuse_of_free_chunk(p, psize); if (p == fm->dv) { fm->dvsize = psize; goto postaction; } } } else set_free_with_pinuse(p, psize, next); if (is_small(psize)) { insert_small_chunk(fm, p, psize); check_free_chunk(fm, p); } else { tchunkptr tp = (tchunkptr)p; insert_large_chunk(fm, tp, psize); check_free_chunk(fm, p); if (--fm->release_checks == 0) release_unused_segments(fm); } goto postaction; } } erroraction: USAGE_ERROR_ACTION(fm, p); postaction: POSTACTION(fm); } } } void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { void* mem; size_t req = 0; mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); return 0; } if (n_elements != 0) { req = n_elements * elem_size; if (((n_elements | elem_size) & ~(size_t)0xffff) && (req / n_elements != elem_size)) req = MAX_SIZE_T; /* force downstream failure on overflow */ } mem = internal_malloc(ms, req); if (mem != 0 && calloc_must_clear(mem2chunk(mem))) memset(mem, 0, req); return mem; } void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { void* mem = 0; if (oldmem == 0) { mem = mspace_malloc(msp, bytes); } else if (bytes >= MAX_REQUEST) { MALLOC_FAILURE_ACTION; } #ifdef REALLOC_ZERO_BYTES_FREES else if (bytes == 0) { mspace_free(msp, oldmem); } #endif /* REALLOC_ZERO_BYTES_FREES */ else { size_t nb = request2size(bytes); mchunkptr oldp = mem2chunk(oldmem); #if ! FOOTERS mstate m = (mstate)msp; #else /* FOOTERS */ mstate m = get_mstate_for(oldp); if (!ok_magic(m)) { USAGE_ERROR_ACTION(m, oldmem); return 0; } #endif /* FOOTERS */ if (!PREACTION(m)) { mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); POSTACTION(m); if (newp != 0) { check_inuse_chunk(m, newp); mem = chunk2mem(newp); } else { mem = mspace_malloc(m, bytes); if (mem != 0) { size_t oc = chunksize(oldp) - overhead_for(oldp); memcpy(mem, oldmem, (oc < bytes)? oc : bytes); mspace_free(m, oldmem); } } } } return mem; } void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { void* mem = 0; if (oldmem != 0) { if (bytes >= MAX_REQUEST) { MALLOC_FAILURE_ACTION; } else { size_t nb = request2size(bytes); mchunkptr oldp = mem2chunk(oldmem); #if ! FOOTERS mstate m = (mstate)msp; #else /* FOOTERS */ mstate m = get_mstate_for(oldp); (void)msp; /* placate people compiling -Wunused */ if (!ok_magic(m)) { USAGE_ERROR_ACTION(m, oldmem); return 0; } #endif /* FOOTERS */ if (!PREACTION(m)) { mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0); POSTACTION(m); if (newp == oldp) { check_inuse_chunk(m, newp); mem = oldmem; } } } } return mem; } void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); return 0; } if (alignment <= MALLOC_ALIGNMENT) return mspace_malloc(msp, bytes); return internal_memalign(ms, alignment, bytes); } void** mspace_independent_calloc(mspace msp, size_t n_elements, size_t elem_size, void* chunks[]) { size_t sz = elem_size; /* serves as 1-element array */ mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); return 0; } return ialloc(ms, n_elements, &sz, 3, chunks); } void** mspace_independent_comalloc(mspace msp, size_t n_elements, size_t sizes[], void* chunks[]) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); return 0; } return ialloc(ms, n_elements, sizes, 0, chunks); } size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) { return internal_bulk_free((mstate)msp, array, nelem); } #if MALLOC_INSPECT_ALL void mspace_inspect_all(mspace msp, void(*handler)(void *start, void *end, size_t used_bytes, void* callback_arg), void* arg) { mstate ms = (mstate)msp; if (ok_magic(ms)) { if (!PREACTION(ms)) { internal_inspect_all(ms, handler, arg); POSTACTION(ms); } } else { USAGE_ERROR_ACTION(ms,ms); } } #endif /* MALLOC_INSPECT_ALL */ int mspace_trim(mspace msp, size_t pad) { int result = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { if (!PREACTION(ms)) { result = sys_trim(ms, pad); POSTACTION(ms); } } else { USAGE_ERROR_ACTION(ms,ms); } return result; } #if !NO_MALLOC_STATS void mspace_malloc_stats(mspace msp) { mstate ms = (mstate)msp; if (ok_magic(ms)) { internal_malloc_stats(ms); } else { USAGE_ERROR_ACTION(ms,ms); } } #endif /* NO_MALLOC_STATS */ size_t mspace_footprint(mspace msp) { size_t result = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { result = ms->footprint; } else { USAGE_ERROR_ACTION(ms,ms); } return result; } size_t mspace_max_footprint(mspace msp) { size_t result = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { result = ms->max_footprint; } else { USAGE_ERROR_ACTION(ms,ms); } return result; } size_t mspace_footprint_limit(mspace msp) { size_t result = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { size_t maf = ms->footprint_limit; result = (maf == 0) ? MAX_SIZE_T : maf; } else { USAGE_ERROR_ACTION(ms,ms); } return result; } size_t mspace_set_footprint_limit(mspace msp, size_t bytes) { size_t result = 0; mstate ms = (mstate)msp; if (ok_magic(ms)) { if (bytes == 0) result = granularity_align(1); /* Use minimal size */ if (bytes == MAX_SIZE_T) result = 0; /* disable */ else result = granularity_align(bytes); ms->footprint_limit = result; } else { USAGE_ERROR_ACTION(ms,ms); } return result; } #if !NO_MALLINFO struct mallinfo mspace_mallinfo(mspace msp) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { USAGE_ERROR_ACTION(ms,ms); } return internal_mallinfo(ms); } #endif /* NO_MALLINFO */ size_t mspace_usable_size(const void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem); if (is_inuse(p)) return chunksize(p) - overhead_for(p); } return 0; } int mspace_mallopt(int param_number, int value) { return change_mparam(param_number, value); } #endif /* MSPACES */ /* -------------------- Alternative MORECORE functions ------------------- */ /* Guidelines for creating a custom version of MORECORE: * For best performance, MORECORE should allocate in multiples of pagesize. * MORECORE may allocate more memory than requested. (Or even less, but this will usually result in a malloc failure.) * MORECORE must not allocate memory when given argument zero, but instead return one past the end address of memory from previous nonzero call. * For best performance, consecutive calls to MORECORE with positive arguments should return increasing addresses, indicating that space has been contiguously extended. * Even though consecutive calls to MORECORE need not return contiguous addresses, it must be OK for malloc'ed chunks to span multiple regions in those cases where they do happen to be contiguous. * MORECORE need not handle negative arguments -- it may instead just return MFAIL when given negative arguments. Negative arguments are always multiples of pagesize. MORECORE must not misinterpret negative args as large positive unsigned args. You can suppress all such calls from even occurring by defining MORECORE_CANNOT_TRIM, As an example alternative MORECORE, here is a custom allocator kindly contributed for pre-OSX macOS. It uses virtually but not necessarily physically contiguous non-paged memory (locked in, present and won't get swapped out). You can use it by uncommenting this section, adding some #includes, and setting up the appropriate defines above: #define MORECORE osMoreCore There is also a shutdown routine that should somehow be called for cleanup upon program exit. #define MAX_POOL_ENTRIES 100 #define MINIMUM_MORECORE_SIZE (64 * 1024U) static int next_os_pool; void *our_os_pools[MAX_POOL_ENTRIES]; void *osMoreCore(int size) { void *ptr = 0; static void *sbrk_top = 0; if (size > 0) { if (size < MINIMUM_MORECORE_SIZE) size = MINIMUM_MORECORE_SIZE; if (CurrentExecutionLevel() == kTaskLevel) ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); if (ptr == 0) { return (void *) MFAIL; } // save ptrs so they can be freed during cleanup our_os_pools[next_os_pool] = ptr; next_os_pool++; ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); sbrk_top = (char *) ptr + size; return ptr; } else if (size < 0) { // we don't currently support shrink behavior return (void *) MFAIL; } else { return sbrk_top; } } // cleanup any allocated memory pools // called as last thing before shutting down driver void osCleanupMem(void) { void **ptr; for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) if (*ptr) { PoolDeallocate(*ptr); *ptr = 0; } } */ /* ----------------------------------------------------------------------- History: v2.8.6 Wed Aug 29 06:57:58 2012 Doug Lea * fix bad comparison in dlposix_memalign * don't reuse adjusted asize in sys_alloc * add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion * reduce compiler warnings -- thanks to all who reported/suggested these v2.8.5 Sun May 22 10:26:02 2011 Doug Lea (dl at gee) * Always perform unlink checks unless INSECURE * Add posix_memalign. * Improve realloc to expand in more cases; expose realloc_in_place. Thanks to Peter Buhr for the suggestion. * Add footprint_limit, inspect_all, bulk_free. Thanks to Barry Hayes and others for the suggestions. * Internal refactorings to avoid calls while holding locks * Use non-reentrant locks by default. Thanks to Roland McGrath for the suggestion. * Small fixes to mspace_destroy, reset_on_error. * Various configuration extensions/changes. Thanks to all who contributed these. V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu) * Update Creative Commons URL V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) * Use zeros instead of prev foot for is_mmapped * Add mspace_track_large_chunks; thanks to Jean Brouwers * Fix set_inuse in internal_realloc; thanks to Jean Brouwers * Fix insufficient sys_alloc padding when using 16byte alignment * Fix bad error check in mspace_footprint * Adaptations for ptmalloc; thanks to Wolfram Gloger. * Reentrant spin locks; thanks to Earl Chew and others * Win32 improvements; thanks to Niall Douglas and Earl Chew * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options * Extension hook in malloc_state * Various small adjustments to reduce warnings on some compilers * Various configuration extensions/changes for more platforms. Thanks to all who contributed these. V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) * Add max_footprint functions * Ensure all appropriate literals are size_t * Fix conditional compilation problem for some #define settings * Avoid concatenating segments with the one provided in create_mspace_with_base * Rename some variables to avoid compiler shadowing warnings * Use explicit lock initialization. * Better handling of sbrk interference. * Simplify and fix segment insertion, trimming and mspace_destroy * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x * Thanks especially to Dennis Flanagan for help on these. V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) * Fix memalign brace error. V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) * Fix improper #endif nesting in C++ * Add explicit casts needed for C++ V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) * Use trees for large bins * Support mspaces * Use segments to unify sbrk-based and mmap-based system allocation, removing need for emulation on most platforms without sbrk. * Default safety checks * Optional footer checks. Thanks to William Robertson for the idea. * Internal code refactoring * Incorporate suggestions and platform-specific changes. Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, Aaron Bachmann, Emery Berger, and others. * Speed up non-fastbin processing enough to remove fastbins. * Remove useless cfree() to avoid conflicts with other apps. * Remove internal memcpy, memset. Compilers handle builtins better. * Remove some options that no one ever used and rename others. V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) * Fix malloc_state bitmap array misdeclaration V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) * Allow tuning of FIRST_SORTED_BIN_SIZE * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. * Better detection and support for non-contiguousness of MORECORE. Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger * Bypass most of malloc if no frees. Thanks To Emery Berger. * Fix freeing of old top non-contiguous chunk im sysmalloc. * Raised default trim and map thresholds to 256K. * Fix mmap-related #defines. Thanks to Lubos Lunak. * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. * Branch-free bin calculation * Default trim and mmap thresholds now 256K. V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) * Introduce independent_comalloc and independent_calloc. Thanks to Michael Pachos for motivation and help. * Make optional .h file available * Allow > 2GB requests on 32bit systems. * new WIN32 sbrk, mmap, munmap, lock code from . Thanks also to Andreas Mueller , and Anonymous. * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for helping test this.) * memalign: check alignment arg * realloc: don't try to shift chunks backwards, since this leads to more fragmentation in some programs and doesn't seem to help in any others. * Collect all cases in malloc requiring system memory into sysmalloc * Use mmap as backup to sbrk * Place all internal state in malloc_state * Introduce fastbins (although similar to 2.5.1) * Many minor tunings and cosmetic improvements * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS Thanks to Tony E. Bennett and others. * Include errno.h to support default failure action. V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) * return null for negative arguments * Added Several WIN32 cleanups from Martin C. Fong * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' (e.g. WIN32 platforms) * Cleanup header file inclusion for WIN32 platforms * Cleanup code to avoid Microsoft Visual C++ compiler complaints * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing memory allocation routines * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to usage of 'assert' in non-WIN32 code * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to avoid infinite loop * Always call 'fREe()' rather than 'free()' V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) * Fixed ordering problem with boundary-stamping V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) * Added pvalloc, as recommended by H.J. Liu * Added 64bit pointer support mainly from Wolfram Gloger * Added anonymously donated WIN32 sbrk emulation * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen * malloc_extend_top: fix mask error that caused wastage after foreign sbrks * Add linux mremap support code from HJ Liu V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) * Integrated most documentation with the code. * Add support for mmap, with help from Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu * Use ordered bins instead of best-fit threshhold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top * Fix error occuring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen (raymond@es.ele.tue.nl) for the suggestion. * Add `pad' argument to malloc_trim and top_pad mallopt parameter. * More precautions for cases where other routines call sbrk, courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Added macros etc., allowing use in linux libc from H.J. Lu (hjl@gnu.ai.mit.edu) * Inverted this history list V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) * Re-tuned and fixed to behave more nicely with V2.6.0 changes. * Removed all preallocation code since under current scheme the work required to undo bad preallocations exceeds the work saved in good cases for most test programs. * No longer use return list or unconsolidated bins since no scheme using them consistently outperforms those that don't given above changes. * Use best fit for very large chunks to prevent some worst-cases. * Added some support for debugging V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) * Removed footers when chunks are in use. Thanks to Paul Wilson (wilson@cs.texas.edu) for the suggestion. V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) * Added malloc_trim, with help from Wolfram Gloger (wmglo@Dent.MED.Uni-Muenchen.DE). V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) * realloc: try to expand in both directions * malloc: swap order of clean-bin strategy; * realloc: only conditionally expand backwards * Try not to scavenge used bins * Use bin counts as a guide to preallocation * Occasionally bin return list chunks in first scan * Add a few optimizations from colin@nyx10.cs.du.edu V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) * faster bin computation & slightly different binning * merged all consolidations to one part of malloc proper (eliminating old malloc_find_space & malloc_clean_bin) * Scan 2 returns chunks (not just 1) * Propagate failure in realloc if malloc returns 0 * Add stuff to allow compilation on non-ANSI compilers from kpv@research.att.com V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) * removed potential for odd address access in prev_chunk * removed dependency on getpagesize.h * misc cosmetics and a bit more internal documentation * anticosmetics: mangled names in macros to evade debugger strangeness * tested on sparc, hp-700, dec-mips, rs6000 with gcc & native cc (hp, dec only) allowing Detlefs & Zorn comparison study (in SIGPLAN Notices.) Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) * Based loosely on libg++-1.2X malloc. (It retains some of the overall structure of old version, but most details differ.) */ #endif // KONAN_INTERNAL_MALLOC ================================================ FILE: runtime/src/main/cpp/dtoa/cbigint.cpp ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "cbigint.h" #if defined(LINUX) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX) #define USE_LL #endif #ifdef HY_LITTLE_ENDIAN #define at(i) (i) #else #define at(i) ((i)^1) /* the sequence for halfAt is -1, 2, 1, 4, 3, 6, 5, 8... */ /* and it should correspond to 0, 1, 2, 3, 4, 5, 6, 7... */ #define halfAt(i) (-((-(i)) ^ 1)) #endif #define HIGH_IN_U64(u64) ((u64) >> 32) #if defined(USE_LL) #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFLL) #else #if defined(USE_L) #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFL) #else #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFF) #endif /* USE_L */ #endif /* USE_LL */ #if defined(USE_LL) #define TEN_E1 (0xALL) #define TEN_E2 (0x64LL) #define TEN_E3 (0x3E8LL) #define TEN_E4 (0x2710LL) #define TEN_E5 (0x186A0LL) #define TEN_E6 (0xF4240LL) #define TEN_E7 (0x989680LL) #define TEN_E8 (0x5F5E100LL) #define TEN_E9 (0x3B9ACA00LL) #define TEN_E19 (0x8AC7230489E80000LL) #else #if defined(USE_L) #define TEN_E1 (0xAL) #define TEN_E2 (0x64L) #define TEN_E3 (0x3E8L) #define TEN_E4 (0x2710L) #define TEN_E5 (0x186A0L) #define TEN_E6 (0xF4240L) #define TEN_E7 (0x989680L) #define TEN_E8 (0x5F5E100L) #define TEN_E9 (0x3B9ACA00L) #define TEN_E19 (0x8AC7230489E80000L) #else #define TEN_E1 (0xA) #define TEN_E2 (0x64) #define TEN_E3 (0x3E8) #define TEN_E4 (0x2710) #define TEN_E5 (0x186A0) #define TEN_E6 (0xF4240) #define TEN_E7 (0x989680) #define TEN_E8 (0x5F5E100) #define TEN_E9 (0x3B9ACA00) #define TEN_E19 (0x8AC7230489E80000) #endif /* USE_L */ #endif /* USE_LL */ #define TIMES_TEN(x) (((x) << 3) + ((x) << 1)) #define bitSection(x, mask, shift) (((x) & (mask)) >> (shift)) #define DOUBLE_TO_LONGBITS(dbl) (*((U_64 *)(&dbl))) #define FLOAT_TO_INTBITS(flt) (*((U_32 *)(&flt))) #define CREATE_DOUBLE_BITS(normalizedM, e) (((normalizedM) & MANTISSA_MASK) | (((U_64)((e) + E_OFFSET)) << 52)) #if defined(USE_LL) #define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL) #define EXPONENT_MASK (0x7FF0000000000000LL) #define NORMAL_MASK (0x0010000000000000LL) #define SIGN_MASK (0x8000000000000000LL) #else #if defined(USE_L) #define MANTISSA_MASK (0x000FFFFFFFFFFFFFL) #define EXPONENT_MASK (0x7FF0000000000000L) #define NORMAL_MASK (0x0010000000000000L) #define SIGN_MASK (0x8000000000000000L) #else #define MANTISSA_MASK (0x000FFFFFFFFFFFFF) #define EXPONENT_MASK (0x7FF0000000000000) #define NORMAL_MASK (0x0010000000000000) #define SIGN_MASK (0x8000000000000000) #endif /* USE_L */ #endif /* USE_LL */ #define E_OFFSET (1075) #define FLOAT_MANTISSA_MASK (0x007FFFFF) #define FLOAT_EXPONENT_MASK (0x7F800000) #define FLOAT_NORMAL_MASK (0x00800000) #define FLOAT_E_OFFSET (150) IDATA simpleAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2) { /* assumes length > 0 */ IDATA index = 1; *arg1 += arg2; if (arg2 <= *arg1) return 0; else if (length == 1) return 1; while (++arg1[index] == 0 && ++index < length); return (IDATA) index == length; } IDATA addHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) { /* addition is limited by length of arg1 as it this function is * storing the result in arg1 */ /* fix for cc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7): code generated does not * do the temp1 + temp2 + carry addition correct. carry is 64 bit because gcc has * subtle issues when you mix 64 / 32 bit maths. */ U_64 temp1, temp2, temp3; /* temporary variables to help the SH-4, and gcc */ U_64 carry; IDATA index; if (length1 == 0 || length2 == 0) { return 0; } else if (length1 < length2) { length2 = length1; } carry = 0; index = 0; do { temp1 = arg1[index]; temp2 = arg2[index]; temp3 = temp1 + temp2; arg1[index] = temp3 + carry; if (arg2[index] < arg1[index]) carry = 0; else if (arg2[index] != arg1[index]) carry = 1; } while (++index < length2); if (!carry) return 0; else if (index == length1) return 1; while (++arg1[index] == 0 && ++index < length1); return (IDATA) index == length1; } void subtractHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) { /* assumes arg1 > arg2 */ IDATA index; for (index = 0; index < length1; ++index) arg1[index] = ~arg1[index]; simpleAddHighPrecision (arg1, length1, 1); while (length2 > 0 && arg2[length2 - 1] == 0) --length2; addHighPrecision (arg1, length1, arg2, length2); for (index = 0; index < length1; ++index) arg1[index] = ~arg1[index]; simpleAddHighPrecision (arg1, length1, 1); } U_32 simpleMultiplyHighPrecision (U_64 * arg1, IDATA length, U_64 arg2) { /* assumes arg2 only holds 32 bits of information */ U_64 product; IDATA index; index = 0; product = 0; do { product = HIGH_IN_U64 (product) + arg2 * LOW_U32_FROM_PTR (arg1 + index); LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); product = HIGH_IN_U64 (product) + arg2 * HIGH_U32_FROM_PTR (arg1 + index); HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); } while (++index < length); return HIGH_U32_FROM_VAR (product); } void simpleMultiplyAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2, U_32 * result) { /* Assumes result can hold the product and arg2 only holds 32 bits of information */ U_64 product; IDATA index, resultIndex; index = resultIndex = 0; product = 0; do { product = HIGH_IN_U64 (product) + result[at (resultIndex)] + arg2 * LOW_U32_FROM_PTR (arg1 + index); result[at (resultIndex)] = LOW_U32_FROM_VAR (product); ++resultIndex; product = HIGH_IN_U64 (product) + result[at (resultIndex)] + arg2 * HIGH_U32_FROM_PTR (arg1 + index); result[at (resultIndex)] = LOW_U32_FROM_VAR (product); ++resultIndex; } while (++index < length); result[at (resultIndex)] += HIGH_U32_FROM_VAR (product); if (result[at (resultIndex)] < HIGH_U32_FROM_VAR (product)) { /* must be careful with ++ operator and macro expansion */ ++resultIndex; while (++result[at (resultIndex)] == 0) ++resultIndex; } } #ifndef HY_LITTLE_ENDIAN void simpleMultiplyAddHighPrecisionBigEndianFix(U_64 *arg1, IDATA length, U_64 arg2, U_32 *result) { /* Assumes result can hold the product and arg2 only holds 32 bits of information */ U_64 product; IDATA index, resultIndex; index = resultIndex = 0; product = 0; do { product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * LOW_U32_FROM_PTR(arg1 + index); result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product); ++resultIndex; product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * HIGH_U32_FROM_PTR(arg1 + index); result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product); ++resultIndex; } while (++index < length); result[halfAt(resultIndex)] += HIGH_U32_FROM_VAR(product); if (result[halfAt(resultIndex)] < HIGH_U32_FROM_VAR(product)) { /* must be careful with ++ operator and macro expansion */ ++resultIndex; while (++result[halfAt(resultIndex)] == 0) ++resultIndex; } } #endif void multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2, U_64 * result, IDATA length) { /* assumes result is large enough to hold product */ U_64 *temp; U_32 *resultIn32; IDATA count, index; if (length1 < length2) { temp = arg1; arg1 = arg2; arg2 = temp; count = length1; length1 = length2; length2 = count; } memset (result, 0, sizeof (U_64) * length); /* length1 > length2 */ resultIn32 = (U_32 *) result; index = -1; for (count = 0; count < length2; ++count) { simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]), resultIn32 + (++index)); #ifdef HY_LITTLE_ENDIAN simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); #else simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); #endif } } U_32 simpleAppendDecimalDigitHighPrecision (U_64 * arg1, IDATA length, U_64 digit) { /* assumes digit is less than 32 bits */ U_64 arg; IDATA index = 0; digit <<= 32; do { arg = LOW_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); arg = HIGH_IN_U64 (arg1[index]); digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); } while (++index < length); return HIGH_U32_FROM_VAR (digit); } void simpleShiftLeftHighPrecision (U_64 * arg1, IDATA length, IDATA arg2) { /* assumes length > 0 */ IDATA index, offset; if (arg2 >= 64) { offset = arg2 >> 6; index = length; while (--index - offset >= 0) arg1[index] = arg1[index - offset]; do { arg1[index] = 0; } while (--index >= 0); arg2 &= 0x3F; } if (arg2 == 0) return; while (--length > 0) { arg1[length] = arg1[length] << arg2 | arg1[length - 1] >> (64 - arg2); } *arg1 <<= arg2; } IDATA highestSetBit (U_64 * y) { U_32 x; IDATA result; if (*y == 0) return 0; #if defined(USE_LL) if (*y & 0xFFFFFFFF00000000LL) { x = HIGH_U32_FROM_PTR (y); result = 32; } else { x = LOW_U32_FROM_PTR (y); result = 0; } #else #if defined(USE_L) if (*y & 0xFFFFFFFF00000000L) { x = HIGH_U32_FROM_PTR (y); result = 32; } else { x = LOW_U32_FROM_PTR (y); result = 0; } #else if (*y & 0xFFFFFFFF00000000) { x = HIGH_U32_FROM_PTR (y); result = 32; } else { x = LOW_U32_FROM_PTR (y); result = 0; } #endif /* USE_L */ #endif /* USE_LL */ if (x & 0xFFFF0000) { x = bitSection (x, 0xFFFF0000, 16); result += 16; } if (x & 0xFF00) { x = bitSection (x, 0xFF00, 8); result += 8; } if (x & 0xF0) { x = bitSection (x, 0xF0, 4); result += 4; } if (x > 0x7) return result + 4; else if (x > 0x3) return result + 3; else if (x > 0x1) return result + 2; else return result + 1; } IDATA lowestSetBit (U_64 * y) { U_32 x; IDATA result; if (*y == 0) return 0; #if defined(USE_LL) if (*y & 0x00000000FFFFFFFFLL) { x = LOW_U32_FROM_PTR (y); result = 0; } else { x = HIGH_U32_FROM_PTR (y); result = 32; } #else #if defined(USE_L) if (*y & 0x00000000FFFFFFFFL) { x = LOW_U32_FROM_PTR (y); result = 0; } else { x = HIGH_U32_FROM_PTR (y); result = 32; } #else if (*y & 0x00000000FFFFFFFF) { x = LOW_U32_FROM_PTR (y); result = 0; } else { x = HIGH_U32_FROM_PTR (y); result = 32; } #endif /* USE_L */ #endif /* USE_LL */ if (!(x & 0xFFFF)) { x = bitSection (x, 0xFFFF0000, 16); result += 16; } if (!(x & 0xFF)) { x = bitSection (x, 0xFF00, 8); result += 8; } if (!(x & 0xF)) { x = bitSection (x, 0xF0, 4); result += 4; } if (x & 0x1) return result + 1; else if (x & 0x2) return result + 2; else if (x & 0x4) return result + 3; else return result + 4; } IDATA highestSetBitHighPrecision (U_64 * arg, IDATA length) { IDATA highBit; while (--length >= 0) { highBit = highestSetBit (arg + length); if (highBit) return highBit + 64 * length; } return 0; } IDATA lowestSetBitHighPrecision (U_64 * arg, IDATA length) { IDATA lowBit, index = -1; while (++index < length) { lowBit = lowestSetBit (arg + index); if (lowBit) return lowBit + 64 * index; } return 0; } IDATA compareHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2) { while (--length1 >= 0 && arg1[length1] == 0); while (--length2 >= 0 && arg2[length2] == 0); if (length1 > length2) return 1; else if (length1 < length2) return -1; else if (length1 > -1) { do { if (arg1[length1] > arg2[length1]) return 1; else if (arg1[length1] < arg2[length1]) return -1; } while (--length1 >= 0); } return 0; } KDouble toDoubleHighPrecision (U_64 * arg, IDATA length) { IDATA highBit; U_64 mantissa, test64; U_32 test; KDouble result; while (length > 0 && arg[length - 1] == 0) --length; if (length == 0) result = 0.0; else if (length > 16) { DOUBLE_TO_LONGBITS (result) = EXPONENT_MASK; } else if (length == 1) { highBit = highestSetBit (arg); if (highBit <= 53) { highBit = 53 - highBit; mantissa = *arg << highBit; DOUBLE_TO_LONGBITS (result) = CREATE_DOUBLE_BITS (mantissa, -highBit); } else { highBit -= 53; mantissa = *arg >> highBit; DOUBLE_TO_LONGBITS (result) = CREATE_DOUBLE_BITS (mantissa, highBit); /* perform rounding, round to even in case of tie */ test = (LOW_U32_FROM_PTR (arg) << (11 - highBit)) & 0x7FF; if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; } } else { highBit = highestSetBit (arg + (--length)); if (highBit <= 53) { highBit = 53 - highBit; if (highBit > 0) { mantissa = (arg[length] << highBit) | (arg[length - 1] >> (64 - highBit)); } else { mantissa = arg[length]; } DOUBLE_TO_LONGBITS (result) = CREATE_DOUBLE_BITS (mantissa, length * 64 - highBit); /* perform rounding, round to even in case of tie */ test64 = arg[--length] << highBit; if (test64 > SIGN_MASK || ((test64 == SIGN_MASK) && (mantissa & 1))) DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; else if (test64 == SIGN_MASK) { while (--length >= 0) { if (arg[length] != 0) { DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; break; } } } } else { highBit -= 53; mantissa = arg[length] >> highBit; DOUBLE_TO_LONGBITS (result) = CREATE_DOUBLE_BITS (mantissa, length * 64 + highBit); /* perform rounding, round to even in case of tie */ test = (LOW_U32_FROM_PTR (arg + length) << (11 - highBit)) & 0x7FF; if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; else if (test == 0x400) { do { if (arg[--length] != 0) { DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; break; } } while (length > 0); } } } return result; } IDATA tenToTheEHighPrecision (U_64 * result, IDATA length, int e) { /* size test */ if (length < ((e / 19) + 1)) return 0; memset (result, 0, length * sizeof (U_64)); *result = 1; if (e == 0) return 1; length = 1; length = timesTenToTheEHighPrecision (result, length, e); /* bad O(n) way of doing it, but simple */ /* do { overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0); if (overflow) result[length++] = overflow; } while (--e); */ return length; } IDATA timesTenToTheEHighPrecision (U_64 * result, IDATA length, int e) { /* assumes result can hold value */ U_64 overflow; int exp10 = e; if (e == 0) return length; /* bad O(n) way of doing it, but simple */ /* do { overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0); if (overflow) result[length++] = overflow; } while (--e); */ /* Replace the current implementation which performs a * "multiplication" by 10 e number of times with an actual * multiplication. 10e19 is the largest exponent to the power of ten * that will fit in a 64-bit integer, and 10e9 is the largest exponent to * the power of ten that will fit in a 64-bit integer. Not sure where the * break-even point is between an actual multiplication and a * simpleAappendDecimalDigit() so just pick 10e3 as that point for * now. */ while (exp10 >= 19) { overflow = simpleMultiplyHighPrecision64 (result, length, TEN_E19); if (overflow) result[length++] = overflow; exp10 -= 19; } while (exp10 >= 9) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E9); if (overflow) result[length++] = overflow; exp10 -= 9; } if (exp10 == 0) return length; else if (exp10 == 1) { overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); if (overflow) result[length++] = overflow; } else if (exp10 == 2) { overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); if (overflow) result[length++] = overflow; overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); if (overflow) result[length++] = overflow; } else if (exp10 == 3) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E3); if (overflow) result[length++] = overflow; } else if (exp10 == 4) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E4); if (overflow) result[length++] = overflow; } else if (exp10 == 5) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E5); if (overflow) result[length++] = overflow; } else if (exp10 == 6) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E6); if (overflow) result[length++] = overflow; } else if (exp10 == 7) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E7); if (overflow) result[length++] = overflow; } else if (exp10 == 8) { overflow = simpleMultiplyHighPrecision (result, length, TEN_E8); if (overflow) result[length++] = overflow; } return length; } U_64 doubleMantissa (KDouble z) { U_64 m = DOUBLE_TO_LONGBITS (z); if ((m & EXPONENT_MASK) != 0) m = (m & MANTISSA_MASK) | NORMAL_MASK; else m = (m & MANTISSA_MASK); return m; } IDATA doubleExponent (KDouble z) { /* assumes positive double */ IDATA k = HIGH_U32_FROM_VAR (z) >> 20; if (k) k -= E_OFFSET; else k = 1 - E_OFFSET; return k; } UDATA floatMantissa (KFloat z) { UDATA m = (UDATA) FLOAT_TO_INTBITS (z); if ((m & FLOAT_EXPONENT_MASK) != 0) m = (m & FLOAT_MANTISSA_MASK) | FLOAT_NORMAL_MASK; else m = (m & FLOAT_MANTISSA_MASK); return m; } IDATA floatExponent (KFloat z) { /* assumes positive float */ IDATA k = FLOAT_TO_INTBITS (z) >> 23; if (k) k -= FLOAT_E_OFFSET; else k = 1 - FLOAT_E_OFFSET; return k; } /* Allow a 64-bit value in arg2 */ U_64 simpleMultiplyHighPrecision64 (U_64 * arg1, IDATA length, U_64 arg2) { U_64 intermediate, *pArg1, carry1, carry2, prod1, prod2, sum; IDATA index; U_32 buf32; index = 0; intermediate = 0; pArg1 = arg1 + index; carry1 = carry2 = 0; do { if ((*pArg1 != 0) || (intermediate != 0)) { prod1 = (U_64) LOW_U32_FROM_VAR (arg2) * (U_64) LOW_U32_FROM_PTR (pArg1); sum = intermediate + prod1; if ((sum < prod1) || (sum < intermediate)) { carry1 = 1; } else { carry1 = 0; } prod1 = (U_64) LOW_U32_FROM_VAR (arg2) * (U_64) HIGH_U32_FROM_PTR (pArg1); prod2 = (U_64) HIGH_U32_FROM_VAR (arg2) * (U_64) LOW_U32_FROM_PTR (pArg1); intermediate = carry2 + HIGH_IN_U64 (sum) + prod1 + prod2; if ((intermediate < prod1) || (intermediate < prod2)) { carry2 = 1; } else { carry2 = 0; } LOW_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (sum); buf32 = HIGH_U32_FROM_PTR (pArg1); HIGH_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (intermediate); intermediate = carry1 + HIGH_IN_U64 (intermediate) + (U_64) HIGH_U32_FROM_VAR (arg2) * (U_64) buf32; } pArg1++; } while (++index < length); return intermediate; } ================================================ FILE: runtime/src/main/cpp/dtoa/cbigint.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(cbigint_h) #define cbigint_h #include "fltconst.h" #include "../Types.h" //#include "vmi.h" #define LOW_U32_FROM_VAR(u64) LOW_U32_FROM_LONG64(u64) #define LOW_U32_FROM_PTR(u64ptr) LOW_U32_FROM_LONG64_PTR(u64ptr) #define HIGH_U32_FROM_VAR(u64) HIGH_U32_FROM_LONG64(u64) #define HIGH_U32_FROM_PTR(u64ptr) HIGH_U32_FROM_LONG64_PTR(u64ptr) #if defined(__cplusplus) extern "C" { #endif void multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2, U_64 * result, IDATA length); U_32 simpleAppendDecimalDigitHighPrecision (U_64 * arg1, IDATA length, U_64 digit); KDouble toDoubleHighPrecision (U_64 * arg, IDATA length); IDATA tenToTheEHighPrecision (U_64 * result, IDATA length, int e); U_64 doubleMantissa (KDouble z); IDATA compareHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2); IDATA highestSetBitHighPrecision (U_64 * arg, IDATA length); void subtractHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2); IDATA doubleExponent (KDouble z); U_32 simpleMultiplyHighPrecision (U_64 * arg1, IDATA length, U_64 arg2); IDATA addHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2); void simpleMultiplyAddHighPrecisionBigEndianFix (U_64 * arg1, IDATA length, U_64 arg2, U_32 * result); IDATA lowestSetBit (U_64 * y); IDATA timesTenToTheEHighPrecision (U_64 * result, IDATA length, int e); void simpleMultiplyAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2, U_32 * result); IDATA highestSetBit (U_64 * y); IDATA lowestSetBitHighPrecision (U_64 * arg, IDATA length); void simpleShiftLeftHighPrecision (U_64 * arg1, IDATA length, IDATA arg2); UDATA floatMantissa (KFloat z); U_64 simpleMultiplyHighPrecision64 (U_64 * arg1, IDATA length, U_64 arg2); IDATA simpleAddHighPrecision (U_64 * arg1, IDATA length, U_64 arg2); IDATA floatExponent (KFloat z); #if defined(__cplusplus) } #endif #endif /* cbigint_h */ ================================================ FILE: runtime/src/main/cpp/dtoa/dblparse.cpp ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "cbigint.h" #include "../Exceptions.h" #include "../KString.h" #include "../Natives.h" #include "../utf8.h" #if defined(LINUX) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX) #define USE_LL #endif #define LOW_I32_FROM_VAR(u64) LOW_I32_FROM_LONG64(u64) #define LOW_I32_FROM_PTR(u64ptr) LOW_I32_FROM_LONG64_PTR(u64ptr) #define HIGH_I32_FROM_VAR(u64) HIGH_I32_FROM_LONG64(u64) #define HIGH_I32_FROM_PTR(u64ptr) HIGH_I32_FROM_LONG64_PTR(u64ptr) #define MAX_ACCURACY_WIDTH 17 #define DEFAULT_WIDTH MAX_ACCURACY_WIDTH extern "C" { KDouble Kotlin_native_FloatingPointParser_parseDoubleImpl (KString s, KInt e); void Kotlin_native_NumberConverter_bigIntDigitGeneratorInstImpl (KRef results, KRef uArray, KLong f, KInt e, KBoolean isDenormalized, KBoolean mantissaIsZero, KInt p); KDouble Kotlin_native_NumberConverter_ceil(KDouble x) { return ceil(x); } void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value); KDouble Kotlin_native_long_bits_to_double(KLong x); } KDouble Kotlin_native_long_bits_to_double(KLong x) { union { int64_t x; double d; } tmp; tmp.x = x; return tmp.d; } KDouble createDouble (const char *s, KInt e); KDouble createDouble1 (U_64 * f, IDATA length, KInt e); KDouble doubleAlgorithm (U_64 * f, IDATA length, KInt e, KDouble z); U_64 dblparse_shiftRight64 (U_64 * lp, volatile int mbe); static const KDouble tens[] = { 1.0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22 }; #define tenToTheE(e) (*(tens + (e))) #define LOG5_OF_TWO_TO_THE_N 23 #define INV_LOG_OF_TEN_BASE_2 (0.30102999566398114) #define DOUBLE_MIN_VALUE 5.0e-324 #define sizeOfTenToTheE(e) (((e) / 19) + 1) #if defined(USE_LL) #define INFINITE_LONGBITS (0x7FF0000000000000LL) #else #if defined(USE_L) #define INFINITE_LONGBITS (0x7FF0000000000000L) #else #define INFINITE_LONGBITS (0x7FF0000000000000) #endif /* USE_L */ #endif /* USE_LL */ #define MINIMUM_LONGBITS (0x1) #if defined(USE_LL) #define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL) #define EXPONENT_MASK (0x7FF0000000000000LL) #define NORMAL_MASK (0x0010000000000000LL) #else #if defined(USE_L) #define MANTISSA_MASK (0x000FFFFFFFFFFFFFL) #define EXPONENT_MASK (0x7FF0000000000000L) #define NORMAL_MASK (0x0010000000000000L) #else #define MANTISSA_MASK (0x000FFFFFFFFFFFFF) #define EXPONENT_MASK (0x7FF0000000000000) #define NORMAL_MASK (0x0010000000000000) #endif /* USE_L */ #endif /* USE_LL */ #define DOUBLE_TO_LONGBITS(dbl) (*((U_64 *)(&dbl))) /* Keep a count of the number of times we decrement and increment to * approximate the double, and attempt to detect the case where we * could potentially toggle back and forth between decrementing and * incrementing. It is possible for us to be stuck in the loop when * incrementing by one or decrementing by one may exceed or stay below * the value that we are looking for. In this case, just break out of * the loop if we toggle between incrementing and decrementing for more * than twice. */ #define INCREMENT_DOUBLE(_x, _decCount, _incCount) \ { \ ++DOUBLE_TO_LONGBITS(_x); \ _incCount++; \ if( (_incCount > 2) && (_decCount > 2) ) { \ if( _decCount > _incCount ) { \ DOUBLE_TO_LONGBITS(_x) += _decCount - _incCount; \ } else if( _incCount > _decCount ) { \ DOUBLE_TO_LONGBITS(_x) -= _incCount - _decCount; \ } \ break; \ } \ } #define DECREMENT_DOUBLE(_x, _decCount, _incCount) \ { \ --DOUBLE_TO_LONGBITS(_x); \ _decCount++; \ if( (_incCount > 2) && (_decCount > 2) ) { \ if( _decCount > _incCount ) { \ DOUBLE_TO_LONGBITS(_x) += _decCount - _incCount; \ } else if( _incCount > _decCount ) { \ DOUBLE_TO_LONGBITS(_x) -= _incCount - _decCount; \ } \ break; \ } \ } #define ERROR_OCCURED(x) (HIGH_I32_FROM_VAR(x) < 0) #define allocateU64(x, n) if (!((x) = (U_64*) konan::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory; #define release(r) if ((r)) konan::free((r)); /*NB the Number converter methods are synchronized so it is possible to *have global data for use by bigIntDigitGenerator */ #define RM_SIZE 21 #define STemp_SIZE 22 KDouble createDouble (const char *s, KInt e) { /* assumes s is a null terminated string with at least one * character in it */ U_64 def[DEFAULT_WIDTH]; U_64 defBackup[DEFAULT_WIDTH]; U_64 *f, *fNoOverflow, *g, *tempBackup; U_32 overflow; KDouble result; IDATA index = 1; int unprocessedDigits = 0; f = def; fNoOverflow = defBackup; *f = 0; tempBackup = g = 0; do { if (*s >= '0' && *s <= '9') { /* Make a back up of f before appending, so that we can * back out of it if there is no more room, i.e. index > * MAX_ACCURACY_WIDTH. */ memcpy (fNoOverflow, f, sizeof (U_64) * index); overflow = simpleAppendDecimalDigitHighPrecision (f, index, *s - '0'); if (overflow) { f[index++] = overflow; /* There is an overflow, but there is no more room * to store the result. We really only need the top 52 * bits anyway, so we must back out of the overflow, * and ignore the rest of the string. */ if (index >= MAX_ACCURACY_WIDTH) { index--; memcpy (f, fNoOverflow, sizeof (U_64) * index); break; } if (tempBackup) { fNoOverflow = tempBackup; } } } else index = -1; } while (index > 0 && *(++s) != '\0'); /* We've broken out of the parse loop either because we've reached * the end of the string or we've overflowed the maximum accuracy * limit of a double. If we still have unprocessed digits in the * given string, then there are three possible results: * 1. (unprocessed digits + e) == 0, in which case we simply * convert the existing bits that are already parsed * 2. (unprocessed digits + e) < 0, in which case we simply * convert the existing bits that are already parsed along * with the given e * 3. (unprocessed digits + e) > 0 indicates that the value is * simply too big to be stored as a double, so return Infinity */ if ((unprocessedDigits = strlen (s)) > 0) { e += unprocessedDigits; if (index > -1) { if (e == 0) result = toDoubleHighPrecision (f, index); else if (e < 0) result = createDouble1 (f, index, e); else { DOUBLE_TO_LONGBITS (result) = INFINITE_LONGBITS; } } else { LOW_I32_FROM_VAR (result) = -1; HIGH_I32_FROM_VAR (result) = -1; } } else { if (index > -1) { if (e == 0) result = toDoubleHighPrecision (f, index); else result = createDouble1 (f, index, e); } else { LOW_I32_FROM_VAR (result) = -1; HIGH_I32_FROM_VAR (result) = -1; } } return result; } KDouble createDouble1 (U_64 * f, IDATA length, KInt e) { IDATA numBits; KDouble result; #define APPROX_MIN_MAGNITUDE -309 #define APPROX_MAX_MAGNITUDE 309 numBits = highestSetBitHighPrecision (f, length) + 1; numBits -= lowestSetBitHighPrecision (f, length); if (numBits < 54 && e >= 0 && e < LOG5_OF_TWO_TO_THE_N) { return toDoubleHighPrecision (f, length) * tenToTheE (e); } else if (numBits < 54 && e < 0 && (-e) < LOG5_OF_TWO_TO_THE_N) { return toDoubleHighPrecision (f, length) / tenToTheE (-e); } else if (e >= 0 && e < APPROX_MAX_MAGNITUDE) { result = toDoubleHighPrecision (f, length) * pow (10.0, (double) e); } else if (e >= APPROX_MAX_MAGNITUDE) { /* Convert the partial result to make sure that the * non-exponential part is not zero. This check fixes the case * where the user enters 0.0e309! */ result = toDoubleHighPrecision (f, length); /* Don't go straight to zero as the fact that x*0 = 0 independent of x might cause the algorithm to produce an incorrect result. Instead try the min value first and let it fall to zero if need be. */ if (result == 0.0) DOUBLE_TO_LONGBITS (result) = MINIMUM_LONGBITS; else DOUBLE_TO_LONGBITS (result) = INFINITE_LONGBITS; } else if (e > APPROX_MIN_MAGNITUDE) { result = toDoubleHighPrecision (f, length) / pow (10.0, (double) -e); } if (e <= APPROX_MIN_MAGNITUDE) { result = toDoubleHighPrecision (f, length) * pow (10.0, (double) (e + 52)); result = result * pow (10.0, (double) -52); } /* Don't go straight to zero as the fact that x*0 = 0 independent of x might cause the algorithm to produce an incorrect result. Instead try the min value first and let it fall to zero if need be. */ if (result == 0.0) DOUBLE_TO_LONGBITS (result) = MINIMUM_LONGBITS; return doubleAlgorithm (f, length, e, result); } U_64 dblparse_shiftRight64 (U_64 * lp, volatile int mbe) { U_64 b1Value = 0; U_32 hi = HIGH_U32_FROM_LONG64_PTR (lp); U_32 lo = LOW_U32_FROM_LONG64_PTR (lp); int srAmt; if (mbe == 0) return 0; if (mbe >= 128) { HIGH_U32_FROM_LONG64_PTR (lp) = 0; LOW_U32_FROM_LONG64_PTR (lp) = 0; return 0; } /* Certain platforms do not handle de-referencing a 64-bit value * from a pointer on the stack correctly (e.g. MVL-hh/XScale) * because the pointer may not be properly aligned, so we'll have * to handle two 32-bit chunks. */ if (mbe < 32) { LOW_U32_FROM_LONG64 (b1Value) = 0; HIGH_U32_FROM_LONG64 (b1Value) = lo << (32 - mbe); LOW_U32_FROM_LONG64_PTR (lp) = (hi << (32 - mbe)) | (lo >> mbe); HIGH_U32_FROM_LONG64_PTR (lp) = hi >> mbe; } else if (mbe == 32) { LOW_U32_FROM_LONG64 (b1Value) = 0; HIGH_U32_FROM_LONG64 (b1Value) = lo; LOW_U32_FROM_LONG64_PTR (lp) = hi; HIGH_U32_FROM_LONG64_PTR (lp) = 0; } else if (mbe < 64) { srAmt = mbe - 32; LOW_U32_FROM_LONG64 (b1Value) = lo << (32 - srAmt); HIGH_U32_FROM_LONG64 (b1Value) = (hi << (32 - srAmt)) | (lo >> srAmt); LOW_U32_FROM_LONG64_PTR (lp) = hi >> srAmt; HIGH_U32_FROM_LONG64_PTR (lp) = 0; } else if (mbe == 64) { LOW_U32_FROM_LONG64 (b1Value) = lo; HIGH_U32_FROM_LONG64 (b1Value) = hi; LOW_U32_FROM_LONG64_PTR (lp) = 0; HIGH_U32_FROM_LONG64_PTR (lp) = 0; } else if (mbe < 96) { srAmt = mbe - 64; b1Value = *lp; HIGH_U32_FROM_LONG64_PTR (lp) = 0; LOW_U32_FROM_LONG64_PTR (lp) = 0; LOW_U32_FROM_LONG64 (b1Value) >>= srAmt; LOW_U32_FROM_LONG64 (b1Value) |= (hi << (32 - srAmt)); HIGH_U32_FROM_LONG64 (b1Value) >>= srAmt; } else if (mbe == 96) { LOW_U32_FROM_LONG64 (b1Value) = hi; HIGH_U32_FROM_LONG64 (b1Value) = 0; HIGH_U32_FROM_LONG64_PTR (lp) = 0; LOW_U32_FROM_LONG64_PTR (lp) = 0; } else { LOW_U32_FROM_LONG64 (b1Value) = hi >> (mbe - 96); HIGH_U32_FROM_LONG64 (b1Value) = 0; HIGH_U32_FROM_LONG64_PTR (lp) = 0; LOW_U32_FROM_LONG64_PTR (lp) = 0; } return b1Value; } #if defined(WIN32) /* disable global optimizations on the microsoft compiler for the * doubleAlgorithm function otherwise it won't compile */ #pragma optimize("g",off) #endif /* The algorithm for the function doubleAlgorithm() below can be found * in: * * "How to Read Floating-Point Numbers Accurately", William D. * Clinger, Proceedings of the ACM SIGPLAN '90 Conference on * Programming Language Design and Implementation, June 20-22, * 1990, pp. 92-101. * * There is a possibility that the function will end up in an endless * loop if the given approximating floating-point number (a very small * floating-point whose value is very close to zero) straddles between * two approximating integer values. We modified the algorithm slightly * to detect the case where it oscillates back and forth between * incrementing and decrementing the floating-point approximation. It * is currently set such that if the oscillation occurs more than twice * then return the original approximation. */ KDouble doubleAlgorithm (U_64 * f, IDATA length, KInt e, KDouble z) { U_64 m; IDATA k, comparison, comparison2; U_64 *x, *y, *D, *D2; IDATA xLength, yLength, DLength, D2Length, decApproxCount, incApproxCount; //PORT_ACCESS_FROM_ENV (env); x = y = D = D2 = 0; xLength = yLength = DLength = D2Length = 0; decApproxCount = incApproxCount = 0; do { m = doubleMantissa (z); k = doubleExponent (z); if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); if (e >= 0 && k >= 0) { xLength = sizeOfTenToTheE (e) + length; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); timesTenToTheEHighPrecision (x, xLength, e); yLength = (k >> 6) + 2; allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; simpleShiftLeftHighPrecision (y, yLength, k); } else if (e >= 0) { xLength = sizeOfTenToTheE (e) + length + ((-k) >> 6) + 1; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); timesTenToTheEHighPrecision (x, xLength, e); simpleShiftLeftHighPrecision (x, xLength, -k); yLength = 1; allocateU64 (y, 1); *y = m; } else if (k >= 0) { xLength = length; x = f; yLength = sizeOfTenToTheE (-e) + 2 + (k >> 6); allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; timesTenToTheEHighPrecision (y, yLength, -e); simpleShiftLeftHighPrecision (y, yLength, k); } else { xLength = length + ((-k) >> 6) + 1; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); simpleShiftLeftHighPrecision (x, xLength, -k); yLength = sizeOfTenToTheE (-e) + 1; allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; timesTenToTheEHighPrecision (y, yLength, -e); } comparison = compareHighPrecision (x, xLength, y, yLength); if (comparison > 0) { /* x > y */ DLength = xLength; allocateU64 (D, DLength); memcpy (D, x, DLength * sizeof (U_64)); subtractHighPrecision (D, DLength, y, yLength); } else if (comparison) { /* y > x */ DLength = yLength; allocateU64 (D, DLength); memcpy (D, y, DLength * sizeof (U_64)); subtractHighPrecision (D, DLength, x, xLength); } else { /* y == x */ DLength = 1; allocateU64 (D, 1); *D = 0; } D2Length = DLength + 1; allocateU64 (D2, D2Length); m <<= 1; multiplyHighPrecision (D, DLength, &m, 1, D2, D2Length); m >>= 1; comparison2 = compareHighPrecision (D2, D2Length, y, yLength); if (comparison2 < 0) { if (comparison < 0 && m == NORMAL_MASK) { simpleShiftLeftHighPrecision (D2, D2Length, 1); if (compareHighPrecision (D2, D2Length, y, yLength) > 0) { DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); } else { break; } } else { break; } } else if (comparison2 == 0) { if ((LOW_U32_FROM_VAR (m) & 1) == 0) { if (comparison < 0 && m == NORMAL_MASK) { DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); } else { break; } } else if (comparison < 0) { DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); break; } else { INCREMENT_DOUBLE (z, decApproxCount, incApproxCount); break; } } else if (comparison < 0) { DECREMENT_DOUBLE (z, decApproxCount, incApproxCount); } else { if (DOUBLE_TO_LONGBITS (z) == INFINITE_LONGBITS) break; INCREMENT_DOUBLE (z, decApproxCount, incApproxCount); } } while (1); if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); return z; OutOfMemory: if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); DOUBLE_TO_LONGBITS (z) = -2; return z; } #if defined(WIN32) #pragma optimize("",on) /*restore optimizations */ #endif KDouble Kotlin_native_FloatingPointParser_parseDoubleImpl (KString s, KInt e) { const KChar* utf16 = CharArrayAddressOfElementAt(s, 0); KStdString utf8; utf8.reserve(s->count_); TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)), utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)), /* Illegal UTF-16 string. */ ThrowNumberFormatException()); const char *str = utf8.c_str(); auto dbl = createDouble (str, e); if (!ERROR_OCCURED (dbl)) { return dbl; } else if (LOW_I32_FROM_VAR (dbl) == (I_32) - 1) { /* NumberFormatException */ ThrowNumberFormatException(); } else { /* OutOfMemoryError */ ThrowOutOfMemoryError(); } return 0.0; } /* The algorithm for this particular function can be found in: * * Printing Floating-Point Numbers Quickly and Accurately, Robert * G. Burger, and R. Kent Dybvig, Programming Language Design and * Implementation (PLDI) 1996, pp.108-116. * * The previous implementation of this function combined m+ and m- into * one single M which caused some inaccuracy of the last digit. The * particular case below shows this inaccuracy: * * System.out.println(new Double((1.234123412431233E107)).toString()); * System.out.println(new Double((1.2341234124312331E107)).toString()); * System.out.println(new Double((1.2341234124312332E107)).toString()); * * outputs the following: * * 1.234123412431233E107 * 1.234123412431233E107 * 1.234123412431233E107 * * instead of: * * 1.234123412431233E107 * 1.2341234124312331E107 * 1.2341234124312331E107 * */ void Kotlin_native_NumberConverter_bigIntDigitGeneratorInstImpl (KRef results, KRef uArray, KLong f, KInt e, KBoolean isDenormalized, KBoolean mantissaIsZero, KInt p) { int RLength, SLength, TempLength, mplus_Length, mminus_Length; int high, low, i; int k, firstK, U; int getCount, setCount; U_64 R[RM_SIZE], S[STemp_SIZE], mplus[RM_SIZE], mminus[RM_SIZE], Temp[STemp_SIZE]; memset (R, 0, RM_SIZE * sizeof (U_64)); memset (S, 0, STemp_SIZE * sizeof (U_64)); memset (mplus, 0, RM_SIZE * sizeof (U_64)); memset (mminus, 0, RM_SIZE * sizeof (U_64)); memset (Temp, 0, STemp_SIZE * sizeof (U_64)); if (e >= 0) { *R = f; *mplus = *mminus = 1; simpleShiftLeftHighPrecision (mminus, RM_SIZE, e); if (f != (2 << (p - 1))) { simpleShiftLeftHighPrecision (R, RM_SIZE, e + 1); *S = 2; /* * m+ = m+ << e results in 1.0e23 to be printed as * 0.9999999999999999E23 * m+ = m+ << e+1 results in 1.0e23 to be printed as * 1.0e23 (caused too much rounding) * 470fffffffffffff = 2.0769187434139308E34 * 4710000000000000 = 2.076918743413931E34 */ simpleShiftLeftHighPrecision (mplus, RM_SIZE, e); } else { simpleShiftLeftHighPrecision (R, RM_SIZE, e + 2); *S = 4; simpleShiftLeftHighPrecision (mplus, RM_SIZE, e + 1); } } else { if (isDenormalized || (f != (2 << (p - 1)))) { *R = f << 1; *S = 1; simpleShiftLeftHighPrecision (S, STemp_SIZE, 1 - e); *mplus = *mminus = 1; } else { *R = f << 2; *S = 1; simpleShiftLeftHighPrecision (S, STemp_SIZE, 2 - e); *mplus = 2; *mminus = 1; } } k = (int) ceil ((e + p - 1) * INV_LOG_OF_TEN_BASE_2 - 1e-10); if (k > 0) { timesTenToTheEHighPrecision (S, STemp_SIZE, k); } else { timesTenToTheEHighPrecision (R, RM_SIZE, -k); timesTenToTheEHighPrecision (mplus, RM_SIZE, -k); timesTenToTheEHighPrecision (mminus, RM_SIZE, -k); } RLength = mplus_Length = mminus_Length = RM_SIZE; SLength = TempLength = STemp_SIZE; memset (Temp + RM_SIZE, 0, (STemp_SIZE - RM_SIZE) * sizeof (U_64)); memcpy (Temp, R, RM_SIZE * sizeof (U_64)); while (RLength > 1 && R[RLength - 1] == 0) --RLength; while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0) --mplus_Length; while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0) --mminus_Length; while (SLength > 1 && S[SLength - 1] == 0) --SLength; TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1; addHighPrecision (Temp, TempLength, mplus, mplus_Length); if (compareHighPrecision (Temp, TempLength, S, SLength) >= 0) { firstK = k; } else { firstK = k - 1; simpleAppendDecimalDigitHighPrecision (R, ++RLength, 0); simpleAppendDecimalDigitHighPrecision (mplus, ++mplus_Length, 0); simpleAppendDecimalDigitHighPrecision (mminus, ++mminus_Length, 0); while (RLength > 1 && R[RLength - 1] == 0) --RLength; while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0) --mplus_Length; while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0) --mminus_Length; } getCount = setCount = 0; do { U = 0; for (i = 3; i >= 0; --i) { TempLength = SLength + 1; Temp[SLength] = 0; memcpy (Temp, S, SLength * sizeof (U_64)); simpleShiftLeftHighPrecision (Temp, TempLength, i); if (compareHighPrecision (R, RLength, Temp, TempLength) >= 0) { subtractHighPrecision (R, RLength, Temp, TempLength); U += 1 << i; } } low = compareHighPrecision (R, RLength, mminus, mminus_Length) <= 0; memset (Temp + RLength, 0, (STemp_SIZE - RLength) * sizeof (U_64)); memcpy (Temp, R, RLength * sizeof (U_64)); TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1; addHighPrecision (Temp, TempLength, mplus, mplus_Length); high = compareHighPrecision (Temp, TempLength, S, SLength) >= 0; if (low || high) break; simpleAppendDecimalDigitHighPrecision (R, ++RLength, 0); simpleAppendDecimalDigitHighPrecision (mplus, ++mplus_Length, 0); simpleAppendDecimalDigitHighPrecision (mminus, ++mminus_Length, 0); while (RLength > 1 && R[RLength - 1] == 0) --RLength; while (mplus_Length > 1 && mplus[mplus_Length - 1] == 0) --mplus_Length; while (mminus_Length > 1 && mminus[mminus_Length - 1] == 0) --mminus_Length; Kotlin_IntArray_set(uArray, setCount++, U); //uArray[setCount++] = U; } while (1); simpleShiftLeftHighPrecision (R, ++RLength, 1); if (low && !high) Kotlin_IntArray_set(uArray, setCount++, U); //uArray[setCount++] = U; else if (high && !low) Kotlin_IntArray_set(uArray, setCount++, U + 1); //uArray[setCount++] = U + 1; else if (compareHighPrecision (R, RLength, S, SLength) < 0) Kotlin_IntArray_set(uArray, setCount++, U); //uArray[setCount++] = U; else Kotlin_IntArray_set(uArray, setCount++, U + 1); //uArray[setCount++] = U + 1; Kotlin_IntArray_set(results, 0, setCount); // fid = (*env)->GetFieldID (env, clazz, "setCount", "I"); // (*env)->SetIntField (env, inst, fid, setCount); Kotlin_IntArray_set(results, 1, getCount); // fid = (*env)->GetFieldID (env, clazz, "getCount", "I"); // (*env)->SetIntField (env, inst, fid, getCount); Kotlin_IntArray_set(results, 2, firstK); // fid = (*env)->GetFieldID (env, clazz, "firstK", "I"); // (*env)->SetIntField (env, inst, fid, firstK); } ================================================ FILE: runtime/src/main/cpp/dtoa/fltconst.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(fltconst_h) #define fltconst_h #include "hycomp.h" /* IEEE floats consist of: sign bit, exponent field, significand field single: 31 = sign bit, 30..23 = exponent (8 bits), 22..0 = significand (23 bits) double: 63 = sign bit, 62..52 = exponent (11 bits), 51..0 = significand (52 bits) inf == (all exponent bits set) and (all mantissa bits clear) nan == (all exponent bits set) and (at least one mantissa bit set) finite == (at least one exponent bit clear) zero == (all exponent bits clear) and (all mantissa bits clear) denormal == (all exponent bits clear) and (at least one mantissa bit set) positive == sign bit clear negative == sign bit set */ #define MAX_U32_DOUBLE (ESDOUBLE) (4294967296.0) /* 2^32 */ #define MAX_U32_SINGLE (ESSINGLE) (4294967296.0) /* 2^32 */ #define HY_POS_PI (ESDOUBLE)(3.141592653589793) #ifdef HY_LITTLE_ENDIAN #ifdef HY_PLATFORM_DOUBLE_ORDER #define DOUBLE_LO_OFFSET 0 #define DOUBLE_HI_OFFSET 1 #else #define DOUBLE_LO_OFFSET 1 #define DOUBLE_HI_OFFSET 0 #endif #define LONG_LO_OFFSET 0 #define LONG_HI_OFFSET 1 #else #ifdef HY_PLATFORM_DOUBLE_ORDER #define DOUBLE_LO_OFFSET 1 #define DOUBLE_HI_OFFSET 0 #else #define DOUBLE_LO_OFFSET 0 #define DOUBLE_HI_OFFSET 1 #endif #define LONG_LO_OFFSET 1 #define LONG_HI_OFFSET 0 #endif #define RETURN_FINITE 0 #define RETURN_NAN 1 #define RETURN_POS_INF 2 #define RETURN_NEG_INF 3 #define DOUBLE_SIGN_MASK_HI 0x80000000 #define DOUBLE_EXPONENT_MASK_HI 0x7FF00000 #define DOUBLE_MANTISSA_MASK_LO 0xFFFFFFFF #define DOUBLE_MANTISSA_MASK_HI 0x000FFFFF #define SINGLE_SIGN_MASK 0x80000000 #define SINGLE_EXPONENT_MASK 0x7F800000 #define SINGLE_MANTISSA_MASK 0x007FFFFF #define SINGLE_NAN_BITS (SINGLE_EXPONENT_MASK | 0x00400000) typedef union u64u32dbl_tag { U_64 u64val; U_32 u32val[2]; I_32 i32val[2]; double dval; } U64U32DBL; /* Replace P_FLOAT_HI and P_FLOAT_LOW */ /* These macros are used to access the high and low 32-bit parts of a double (64-bit) value. */ #define LOW_U32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->u32val[DOUBLE_LO_OFFSET]) #define HIGH_U32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->u32val[DOUBLE_HI_OFFSET]) #define LOW_I32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->i32val[DOUBLE_LO_OFFSET]) #define HIGH_I32_FROM_DBL_PTR(dblptr) (((U64U32DBL *)(dblptr))->i32val[DOUBLE_HI_OFFSET]) #define LOW_U32_FROM_DBL(dbl) LOW_U32_FROM_DBL_PTR(&(dbl)) #define HIGH_U32_FROM_DBL(dbl) HIGH_U32_FROM_DBL_PTR(&(dbl)) #define LOW_I32_FROM_DBL(dbl) LOW_I32_FROM_DBL_PTR(&(dbl)) #define HIGH_I32_FROM_DBL(dbl) HIGH_I32_FROM_DBL_PTR(&(dbl)) #define LOW_U32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->u32val[LONG_LO_OFFSET]) #define HIGH_U32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->u32val[LONG_HI_OFFSET]) #define LOW_I32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->i32val[LONG_LO_OFFSET]) #define HIGH_I32_FROM_LONG64_PTR(long64ptr) (((U64U32DBL *)(long64ptr))->i32val[LONG_HI_OFFSET]) #define LOW_U32_FROM_LONG64(long64) LOW_U32_FROM_LONG64_PTR(&(long64)) #define HIGH_U32_FROM_LONG64(long64) HIGH_U32_FROM_LONG64_PTR(&(long64)) #define LOW_I32_FROM_LONG64(long64) LOW_I32_FROM_LONG64_PTR(&(long64)) #define HIGH_I32_FROM_LONG64(long64) HIGH_I32_FROM_LONG64_PTR(&(long64)) #define IS_ZERO_DBL_PTR(dblptr) ((LOW_U32_FROM_DBL_PTR(dblptr) == 0) && ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0) || (HIGH_U32_FROM_DBL_PTR(dblptr) == DOUBLE_SIGN_MASK_HI))) #define IS_ONE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0x3ff00000 || HIGH_U32_FROM_DBL_PTR(dblptr) == 0xbff00000) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0)) #define IS_NAN_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) == DOUBLE_EXPONENT_MASK_HI) && (LOW_U32_FROM_DBL_PTR(dblptr) | (HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_MANTISSA_MASK_HI))) #define IS_INF_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & (DOUBLE_EXPONENT_MASK_HI|DOUBLE_MANTISSA_MASK_HI)) == DOUBLE_EXPONENT_MASK_HI) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0)) #define IS_DENORMAL_DBL_PTR(dblptr) (((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) == 0) && ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_MANTISSA_MASK_HI) != 0 || (LOW_U32_FROM_DBL_PTR(dblptr) != 0))) #define IS_FINITE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_EXPONENT_MASK_HI) < DOUBLE_EXPONENT_MASK_HI) #define IS_POSITIVE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_SIGN_MASK_HI) == 0) #define IS_NEGATIVE_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) & DOUBLE_SIGN_MASK_HI) != 0) #define IS_NEGATIVE_MAX_DBL_PTR(dblptr) ((HIGH_U32_FROM_DBL_PTR(dblptr) == 0xFFEFFFFF) && (LOW_U32_FROM_DBL_PTR(dblptr) == 0xFFFFFFFF)) #define IS_ZERO_DBL(dbl) IS_ZERO_DBL_PTR(&(dbl)) #define IS_ONE_DBL(dbl) IS_ONE_DBL_PTR(&(dbl)) #define IS_NAN_DBL(dbl) IS_NAN_DBL_PTR(&(dbl)) #define IS_INF_DBL(dbl) IS_INF_DBL_PTR(&(dbl)) #define IS_DENORMAL_DBL(dbl) IS_DENORMAL_DBL_PTR(&(dbl)) #define IS_FINITE_DBL(dbl) IS_FINITE_DBL_PTR(&(dbl)) #define IS_POSITIVE_DBL(dbl) IS_POSITIVE_DBL_PTR(&(dbl)) #define IS_NEGATIVE_DBL(dbl) IS_NEGATIVE_DBL_PTR(&(dbl)) #define IS_NEGATIVE_MAX_DBL(dbl) IS_NEGATIVE_MAX_DBL_PTR(&(dbl)) #define IS_ZERO_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) == (U_32)0) #define IS_ONE_SNGL_PTR(fltptr) ((*U32P((fltptr)) == 0x3f800000) || (*U32P((fltptr)) == 0xbf800000)) #define IS_NAN_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) > (U_32)SINGLE_EXPONENT_MASK) #define IS_INF_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) == (U_32)SINGLE_EXPONENT_MASK) #define IS_DENORMAL_SNGL_PTR(fltptr) (((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK)-(U_32)1) < (U_32)SINGLE_MANTISSA_MASK) #define IS_FINITE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)~SINGLE_SIGN_MASK) < (U_32)SINGLE_EXPONENT_MASK) #define IS_POSITIVE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)SINGLE_SIGN_MASK) == (U_32)0) #define IS_NEGATIVE_SNGL_PTR(fltptr) ((*U32P((fltptr)) & (U_32)SINGLE_SIGN_MASK) != (U_32)0) #define IS_ZERO_SNGL(flt) IS_ZERO_SNGL_PTR(&(flt)) #define IS_ONE_SNGL(flt) IS_ONE_SNGL_PTR(&(flt)) #define IS_NAN_SNGL(flt) IS_NAN_SNGL_PTR(&(flt)) #define IS_INF_SNGL(flt) IS_INF_SNGL_PTR(&(flt)) #define IS_DENORMAL_SNGL(flt) IS_DENORMAL_SNGL_PTR(&(flt)) #define IS_FINITE_SNGL(flt) IS_FINITE_SNGL_PTR(&(flt)) #define IS_POSITIVE_SNGL(flt) IS_POSITIVE_SNGL_PTR(&(flt)) #define IS_NEGATIVE_SNGL(flt) IS_NEGATIVE_SNGL_PTR(&(flt)) #define SET_NAN_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = (DOUBLE_EXPONENT_MASK_HI | 0x00080000); LOW_U32_FROM_DBL_PTR(dblptr) = 0 #define SET_PZERO_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = 0; LOW_U32_FROM_DBL_PTR(dblptr) = 0 #define SET_NZERO_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = DOUBLE_SIGN_MASK_HI; LOW_U32_FROM_DBL_PTR(dblptr) = 0 #define SET_PINF_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = DOUBLE_EXPONENT_MASK_HI; LOW_U32_FROM_DBL_PTR(dblptr) = 0 #define SET_NINF_DBL_PTR(dblptr) HIGH_U32_FROM_DBL_PTR(dblptr) = (DOUBLE_EXPONENT_MASK_HI | DOUBLE_SIGN_MASK_HI); LOW_U32_FROM_DBL_PTR(dblptr) = 0 #define SET_NAN_SNGL_PTR(fltptr) *U32P((fltptr)) = ((U_32)SINGLE_NAN_BITS) #define SET_PZERO_SNGL_PTR(fltptr) *U32P((fltptr)) = 0 #define SET_NZERO_SNGL_PTR(fltptr) *U32P((fltptr)) = SINGLE_SIGN_MASK #define SET_PINF_SNGL_PTR(fltptr) *U32P((fltptr)) = SINGLE_EXPONENT_MASK #define SET_NINF_SNGL_PTR(fltptr) *U32P((fltptr)) = (SINGLE_EXPONENT_MASK | SINGLE_SIGN_MASK) #if defined(HY_WORD64) #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) ((U64U32DBL *)(aDoublePtr))->u64val = ((U64U32DBL *)(dstPtr))->u64val #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) ((U64U32DBL *)(dstPtr))->u64val = ((U64U32DBL *)(aDoublePtr))->u64val #define STORE_LONG(dstPtr, hi, lo) ((U64U32DBL *)(dstPtr))->u64val = (((U_64)(hi)) << 32) | (lo) #else /* on some platforms (HP720) we cannot reference an unaligned float. Build them by hand, one U_32 at a time. */ #if defined(ATOMIC_FLOAT_ACCESS) #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(dstPtr) = HIGH_U32_FROM_DBL_PTR(aDoublePtr); LOW_U32_FROM_DBL_PTR(dstPtr) = LOW_U32_FROM_DBL_PTR(aDoublePtr) #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(aDoublePtr) = HIGH_U32_FROM_DBL_PTR(dstPtr); LOW_U32_FROM_DBL_PTR(aDoublePtr) = LOW_U32_FROM_DBL_PTR(dstPtr) #else #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) (*(dstPtr) = *(aDoublePtr)) #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) (*(aDoublePtr) = *(dstPtr)) #endif #define STORE_LONG(dstPtr, hi, lo) HIGH_U32_FROM_LONG64_PTR(dstPtr) = (hi); LOW_U32_FROM_LONG64_PTR(dstPtr) = (lo) #endif /* HY_WORD64 */ #define PTR_SINGLE_VALUE(dstPtr, aSinglePtr) (*U32P(aSinglePtr) = *U32P(dstPtr)) #define PTR_SINGLE_STORE(dstPtr, aSinglePtr) *((U_32 *)(dstPtr)) = (*U32P(aSinglePtr)) #endif /* fltconst_h */ ================================================ FILE: runtime/src/main/cpp/dtoa/fltparse.cpp ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "cbigint.h" #include "../Exceptions.h" #include "../KString.h" #include "../Natives.h" #include "../utf8.h" #if defined(LINUX) || defined(FREEBSD) || defined(MACOSX) || defined(ZOS) || defined(AIX) #define USE_LL #endif #ifdef HY_LITTLE_ENDIAN #define LOW_I32_FROM_PTR(ptr64) (*(I_32 *) (ptr64)) #else #define LOW_I32_FROM_PTR(ptr64) (*(((I_32 *) (ptr64)) + 1)) #endif #define MAX_ACCURACY_WIDTH 8 #define DEFAULT_WIDTH MAX_ACCURACY_WIDTH extern "C" KFloat Kotlin_native_int_bits_to_float(KInt x) { union { int32_t x; float f; } tmp; tmp.x = x; return tmp.f; } KFloat createFloat1 (U_64 * f, IDATA length, KInt e); KFloat floatAlgorithm (U_64 * f, IDATA length, KInt e, KFloat z); KFloat createFloat (const char *s, KInt e); static const U_32 tens[] = { 0x3f800000, 0x41200000, 0x42c80000, 0x447a0000, 0x461c4000, 0x47c35000, 0x49742400, 0x4b189680, 0x4cbebc20, 0x4e6e6b28, 0x501502f9 /* 10 ^ 10 in float */ }; #define tenToTheE(e) (*((KFloat *) (tens + (e)))) #define LOG5_OF_TWO_TO_THE_N 11 #define sizeOfTenToTheE(e) (((e) / 19) + 1) #define INFINITE_INTBITS (0x7F800000) #define MINIMUM_INTBITS (1) #define MANTISSA_MASK (0x007FFFFF) #define EXPONENT_MASK (0x7F800000) #define NORMAL_MASK (0x00800000) #define FLOAT_TO_INTBITS(flt) (*((U_32 *)(&flt))) /* Keep a count of the number of times we decrement and increment to * approximate the double, and attempt to detect the case where we * could potentially toggle back and forth between decrementing and * incrementing. It is possible for us to be stuck in the loop when * incrementing by one or decrementing by one may exceed or stay below * the value that we are looking for. In this case, just break out of * the loop if we toggle between incrementing and decrementing for more * than twice. */ #define INCREMENT_FLOAT(_x, _decCount, _incCount) \ { \ ++FLOAT_TO_INTBITS(_x); \ _incCount++; \ if( (_incCount > 2) && (_decCount > 2) ) { \ if( _decCount > _incCount ) { \ FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \ } else if( _incCount > _decCount ) { \ FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \ } \ break; \ } \ } #define DECREMENT_FLOAT(_x, _decCount, _incCount) \ { \ --FLOAT_TO_INTBITS(_x); \ _decCount++; \ if( (_incCount > 2) && (_decCount > 2) ) { \ if( _decCount > _incCount ) { \ FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \ } else if( _incCount > _decCount ) { \ FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \ } \ break; \ } \ } #define allocateU64(x, n) if (!((x) = (U_64*) konan::calloc(1, (n) * sizeof(U_64)))) goto OutOfMemory; #define release(r) if ((r)) konan::free((r)); KFloat createFloat(const char *s, KInt e) { /* assumes s is a null terminated string with at least one * character in it */ U_64 def[DEFAULT_WIDTH]; U_64 defBackup[DEFAULT_WIDTH]; U_64 *f, *fNoOverflow, *g, *tempBackup; U_32 overflow; KFloat result; IDATA index = 1; int unprocessedDigits = 0; f = def; fNoOverflow = defBackup; *f = 0; tempBackup = g = 0; do { if (*s >= '0' && *s <= '9') { /* Make a back up of f before appending, so that we can * back out of it if there is no more room, i.e. index > * MAX_ACCURACY_WIDTH. */ memcpy (fNoOverflow, f, sizeof (U_64) * index); overflow = simpleAppendDecimalDigitHighPrecision (f, index, *s - '0'); if (overflow) { f[index++] = overflow; /* There is an overflow, but there is no more room * to store the result. We really only need the top 52 * bits anyway, so we must back out of the overflow, * and ignore the rest of the string. */ if (index >= MAX_ACCURACY_WIDTH) { index--; memcpy (f, fNoOverflow, sizeof (U_64) * index); break; } if (tempBackup) { fNoOverflow = tempBackup; } } } else index = -1; } while (index > 0 && *(++s) != '\0'); /* We've broken out of the parse loop either because we've reached * the end of the string or we've overflowed the maximum accuracy * limit of a double. If we still have unprocessed digits in the * given string, then there are three possible results: * 1. (unprocessed digits + e) == 0, in which case we simply * convert the existing bits that are already parsed * 2. (unprocessed digits + e) < 0, in which case we simply * convert the existing bits that are already parsed along * with the given e * 3. (unprocessed digits + e) > 0 indicates that the value is * simply too big to be stored as a double, so return Infinity */ if ((unprocessedDigits = strlen (s)) > 0) { e += unprocessedDigits; if (index > -1) { if (e <= 0) { result = createFloat1 (f, index, e); } else { FLOAT_TO_INTBITS (result) = INFINITE_INTBITS; } } else { result = *(KFloat *) & index; } } else { if (index > -1) { result = createFloat1 (f, index, e); } else { result = *(KFloat *) & index; } } return result; } KFloat createFloat1 (U_64 * f, IDATA length, KInt e) { IDATA numBits; KDouble dresult; KFloat result; numBits = highestSetBitHighPrecision (f, length) + 1; if (numBits < 25 && e >= 0 && e < LOG5_OF_TWO_TO_THE_N) { return ((KFloat) LOW_I32_FROM_PTR (f)) * tenToTheE (e); } else if (numBits < 25 && e < 0 && (-e) < LOG5_OF_TWO_TO_THE_N) { return ((KFloat) LOW_I32_FROM_PTR (f)) / tenToTheE (-e); } else if (e >= 0 && e < 39) { result = (KFloat) (toDoubleHighPrecision (f, length) * pow (10.0, (double) e)); } else if (e >= 39) { /* Convert the partial result to make sure that the * non-exponential part is not zero. This check fixes the case * where the user enters 0.0e309! */ result = (KFloat) toDoubleHighPrecision (f, length); if (result == 0.0) FLOAT_TO_INTBITS (result) = MINIMUM_INTBITS; else FLOAT_TO_INTBITS (result) = INFINITE_INTBITS; } else if (e > -309) { int dexp; U_32 fmant, fovfl; U_64 dmant; dresult = toDoubleHighPrecision (f, length) / pow (10.0, (double) -e); if (IS_DENORMAL_DBL (dresult)) { FLOAT_TO_INTBITS (result) = 0; return result; } dexp = doubleExponent (dresult) + 51; dmant = doubleMantissa (dresult); /* Is it too small to be represented by a single-precision * float? */ if (dexp <= -155) { FLOAT_TO_INTBITS (result) = 0; return result; } /* Is it a denormalized single-precision float? */ if ((dexp <= -127) && (dexp > -155)) { /* Only interested in 24 msb bits of the 53-bit double mantissa */ fmant = (U_32) (dmant >> 29); fovfl = ((U_32) (dmant & 0x1FFFFFFF)) << 3; while ((dexp < -127) && ((fmant | fovfl) != 0)) { if ((fmant & 1) != 0) { fovfl |= 0x80000000; } fovfl >>= 1; fmant >>= 1; dexp++; } if ((fovfl & 0x80000000) != 0) { if ((fovfl & 0x7FFFFFFC) != 0) { fmant++; } else if ((fmant & 1) != 0) { fmant++; } } else if ((fovfl & 0x40000000) != 0) { if ((fovfl & 0x3FFFFFFC) != 0) { fmant++; } } FLOAT_TO_INTBITS (result) = fmant; } else { result = (KFloat) dresult; } } /* Don't go straight to zero as the fact that x*0 = 0 independent * of x might cause the algorithm to produce an incorrect result. * Instead try the min value first and let it fall to zero if need * be. */ if (e <= -309 || FLOAT_TO_INTBITS (result) == 0) FLOAT_TO_INTBITS (result) = MINIMUM_INTBITS; return floatAlgorithm (f, length, e, result); } #if defined(WIN32) /* disable global optimizations on the microsoft compiler for the * floatAlgorithm function otherwise it won't properly compile */ #pragma optimize("g",off) #endif /* The algorithm for the function floatAlgorithm() below can be found * in: * * "How to Read Floating-Point Numbers Accurately", William D. * Clinger, Proceedings of the ACM SIGPLAN '90 Conference on * Programming Language Design and Implementation, June 20-22, * 1990, pp. 92-101. * * There is a possibility that the function will end up in an endless * loop if the given approximating floating-point number (a very small * floating-point whose value is very close to zero) straddles between * two approximating integer values. We modified the algorithm slightly * to detect the case where it oscillates back and forth between * incrementing and decrementing the floating-point approximation. It * is currently set such that if the oscillation occurs more than twice * then return the original approximation. */ KFloat floatAlgorithm (U_64 * f, IDATA length, KInt e, KFloat z) { U_64 m; IDATA k, comparison, comparison2; U_64 *x, *y, *D, *D2; IDATA xLength, yLength, DLength, D2Length; IDATA decApproxCount, incApproxCount; //PORT_ACCESS_FROM_ENV (env); x = y = D = D2 = 0; xLength = yLength = DLength = D2Length = 0; decApproxCount = incApproxCount = 0; do { m = floatMantissa (z); k = floatExponent (z); if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); if (e >= 0 && k >= 0) { xLength = sizeOfTenToTheE (e) + length; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); timesTenToTheEHighPrecision (x, xLength, e); yLength = (k >> 6) + 2; allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; simpleShiftLeftHighPrecision (y, yLength, k); } else if (e >= 0) { xLength = sizeOfTenToTheE (e) + length + ((-k) >> 6) + 1; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); timesTenToTheEHighPrecision (x, xLength, e); simpleShiftLeftHighPrecision (x, xLength, -k); yLength = 1; allocateU64 (y, 1); *y = m; } else if (k >= 0) { xLength = length; x = f; yLength = sizeOfTenToTheE (-e) + 2 + (k >> 6); allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; timesTenToTheEHighPrecision (y, yLength, -e); simpleShiftLeftHighPrecision (y, yLength, k); } else { xLength = length + ((-k) >> 6) + 1; allocateU64 (x, xLength); memset (x + length, 0, sizeof (U_64) * (xLength - length)); memcpy (x, f, sizeof (U_64) * length); simpleShiftLeftHighPrecision (x, xLength, -k); yLength = sizeOfTenToTheE (-e) + 1; allocateU64 (y, yLength); memset (y + 1, 0, sizeof (U_64) * (yLength - 1)); *y = m; timesTenToTheEHighPrecision (y, yLength, -e); } comparison = compareHighPrecision (x, xLength, y, yLength); if (comparison > 0) { /* x > y */ DLength = xLength; allocateU64 (D, DLength); memcpy (D, x, DLength * sizeof (U_64)); subtractHighPrecision (D, DLength, y, yLength); } else if (comparison) { /* y > x */ DLength = yLength; allocateU64 (D, DLength); memcpy (D, y, DLength * sizeof (U_64)); subtractHighPrecision (D, DLength, x, xLength); } else { /* y == x */ DLength = 1; allocateU64 (D, 1); *D = 0; } D2Length = DLength + 1; allocateU64 (D2, D2Length); m <<= 1; multiplyHighPrecision (D, DLength, &m, 1, D2, D2Length); m >>= 1; comparison2 = compareHighPrecision (D2, D2Length, y, yLength); if (comparison2 < 0) { if (comparison < 0 && m == NORMAL_MASK) { simpleShiftLeftHighPrecision (D2, D2Length, 1); if (compareHighPrecision (D2, D2Length, y, yLength) > 0) { DECREMENT_FLOAT (z, decApproxCount, incApproxCount); } else { break; } } else { break; } } else if (comparison2 == 0) { if ((m & 1) == 0) { if (comparison < 0 && m == NORMAL_MASK) { DECREMENT_FLOAT (z, decApproxCount, incApproxCount); } else { break; } } else if (comparison < 0) { DECREMENT_FLOAT (z, decApproxCount, incApproxCount); break; } else { INCREMENT_FLOAT (z, decApproxCount, incApproxCount); break; } } else if (comparison < 0) { DECREMENT_FLOAT (z, decApproxCount, incApproxCount); } else { if (FLOAT_TO_INTBITS (z) == EXPONENT_MASK) break; INCREMENT_FLOAT (z, decApproxCount, incApproxCount); } } while (1); if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); return z; OutOfMemory: if (x && x != f) //jclmem_free_memory (env, x); release(x); release (y); release (D); release (D2); FLOAT_TO_INTBITS (z) = -2; return z; } #if defined(WIN32) #pragma optimize("",on) /*restore optimizations */ #endif extern "C" KFloat Kotlin_native_FloatingPointParser_parseFloatImpl(KString s, KInt e) { const KChar* utf16 = CharArrayAddressOfElementAt(s, 0); KStdString utf8; utf8.reserve(s->count_); TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)), utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)), /* Illegal UTF-16 string. */ ThrowNumberFormatException()); const char *str = utf8.c_str(); auto flt = createFloat(str, e); if (((I_32) FLOAT_TO_INTBITS (flt)) >= 0) { return flt; } else if (((I_32) FLOAT_TO_INTBITS (flt)) == (I_32) - 1) { /* NumberFormatException */ ThrowNumberFormatException(); } else { /* OutOfMemoryError */ ThrowOutOfMemoryError(); } return 0.0f; } ================================================ FILE: runtime/src/main/cpp/dtoa/hycomp.h ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(hycomp_h) #define hycomp_h // TODO: Move to settings #define MACOSX /** * USE_PROTOTYPES: Use full ANSI prototypes. * * CLOCK_PRIMS: We want the timer/clock prims to be used * * LITTLE_ENDIAN: This is for the intel machines or other * little endian processors. Defaults to big endian. * * NO_LVALUE_CASTING: This is for compilers that don't like the left side * of assigns to be cast. It hacks around to do the * right thing. * * ATOMIC_FLOAT_ACCESS: So that float operations will work. * * LINKED_USER_PRIMITIVES: Indicates that user primitives are statically linked * with the VM executeable. * * OLD_SPACE_SIZE_DIFF: The 68k uses a different amount of old space. * This "legitimizes" the change. * * SIMPLE_SIGNAL: For machines that don't use real signals in C. * (eg: PC, 68k) * * OS_NAME_LOOKUP: Use nlist to lookup user primitive addresses. * * VMCALL: Tag for all functions called by the VM. * * VMAPICALL: Tag for all functions called via the PlatformFunction * callWith: mechanism. * * SYS_FLOAT: For some math functions where extended types (80 or 96 bits) are returned * Most platforms return as a double * * FLOAT_EXTENDED: If defined, the type name for extended precision floats. * * PLATFORM_IS_ASCII: Must be defined if the platform is ASCII * * EXE_EXTENSION_CHAR: the executable has a delimiter that we want to stop at as part of argv[0]. */ /** * By default order doubles in the native (that is big/little endian) ordering. */ #define HY_PLATFORM_DOUBLE_ORDER /** * Define common types: *
    *
  • U_32 / I_32 - unsigned/signed 32 bits
  • *
  • U_16 / I_16 - unsigned/signed 16 bits
  • *
  • U_8 / I_8 - unsigned/signed 8 bits (bytes -- not to be * confused with char)
  • *
*/ typedef int I_32; typedef short I_16; typedef signed char I_8; /* chars can be unsigned */ typedef unsigned int U_32; typedef unsigned short U_16; typedef unsigned char U_8; /** * Define platform specific types: *
    *
  • U_64 / I_64 - unsigned/signed 64 bits
  • *
*/ #if defined(LINUX) || defined(FREEBSD) || defined(AIX) || defined(MACOSX) #define DATA_TYPES_DEFINED /* NOTE: Linux supports different processors -- do not assume 386 */ #if defined(HYX86_64) || defined(HYIA64) || defined(HYPPC64) || defined(HYS390X) typedef unsigned long int U_64; /* 64bits */ typedef long int I_64; #define TOC_UNWRAP_ADDRESS(wrappedPointer) ((void *) (wrappedPointer)[0]) #define TOC_STORE_TOC(dest,wrappedPointer) (dest = ((UDATA*)wrappedPointer)[1]) #define HY_WORD64 #else typedef long long I_64; typedef unsigned long long U_64; #endif #if defined(HYS390X) || defined(HYS390) || defined(HYPPC64) || defined(HYPPC32) || defined(__MIPSEB__) #define HY_BIG_ENDIAN #else #define HY_LITTLE_ENDIAN #endif #if defined(HYPPC32) && defined(LINUX) #define VA_PTR(valist) (&valist[0]) #endif typedef double SYS_FLOAT; #define HYCONST64(x) x##LL #define NO_LVALUE_CASTING #define FLOAT_EXTENDED long double #define PLATFORM_IS_ASCII #define PLATFORM_LINE_DELIMITER "\012" #define DIR_SEPARATOR '/' #define DIR_SEPARATOR_STR "/" #define PATH_SEPARATOR ':' #define PATH_SEPARATOR_STR ":" #if defined(AIX) #define LIBPATH_ENV_VAR "LIBPATH" #else #if defined(MACOSX) #define LIBPATH_ENV_VAR "DYLD_LIBRARY_PATH" #else #define LIBPATH_ENV_VAR "LD_LIBRARY_PATH" #endif #endif #if defined(MACOSX) #define PLATFORM_DLL_EXTENSION ".dylib" #else #define PLATFORM_DLL_EXTENSION ".so" #endif /** * No priorities on Linux */ #define HY_PRIORITY_MAP {0,0,0,0,0,0,0,0,0,0,0,0} typedef U_32 BOOLEAN; #endif /* Win32 - Windows 3.1 & NT using Win32 */ #if defined(WIN32) #define HY_LITTLE_ENDIAN /* Define 64-bit integers for Windows */ typedef __int64 I_64; typedef unsigned __int64 U_64; typedef double SYS_FLOAT; #define NO_LVALUE_CASTING #define VMAPICALL _stdcall #define VMCALL _cdecl #define EXE_EXTENSION_CHAR '.' #define DIR_SEPARATOR '\\' #define DIR_SEPARATOR_STR "\\" #define PATH_SEPARATOR ';' #define PATH_SEPARATOR_STR ";" #define LIBPATH_ENV_VAR "PATH" /* Modifications for the Alpha running WIN-NT */ #if defined(_ALPHA_) #undef small /* defined as char in rpcndr.h */ typedef double FLOAT_EXTENDED; #endif #define HY_PRIORITY_MAP { \ THREAD_PRIORITY_IDLE, /* 0 */\ THREAD_PRIORITY_LOWEST, /* 1 */\ THREAD_PRIORITY_BELOW_NORMAL, /* 2 */\ THREAD_PRIORITY_BELOW_NORMAL, /* 3 */\ THREAD_PRIORITY_BELOW_NORMAL, /* 4 */\ THREAD_PRIORITY_NORMAL, /* 5 */\ THREAD_PRIORITY_ABOVE_NORMAL, /* 6 */\ THREAD_PRIORITY_ABOVE_NORMAL, /* 7 */\ THREAD_PRIORITY_ABOVE_NORMAL, /* 8 */\ THREAD_PRIORITY_ABOVE_NORMAL, /* 9 */\ THREAD_PRIORITY_HIGHEST, /*10 */\ THREAD_PRIORITY_TIME_CRITICAL /*11 */} #endif /* defined(WIN32) */ #if defined(ZOS) #define HY_BIG_ENDIAN #define DATA_TYPES_DEFINED typedef unsigned int BOOLEAN; #if defined (HYS390X) typedef unsigned long U_64; typedef long I_64; #else typedef signed long long I_64; typedef unsigned long long U_64; #endif typedef double SYS_FLOAT; #define HYCONST64(x) x##LL #define NO_LVALUE_CASTING #define PLATFORM_LINE_DELIMITER "\012" #define DIR_SEPARATOR '/' #define DIR_SEPARATOR_STR "/" #define PATH_SEPARATOR ':' #define PATH_SEPARATOR_STR ":" #define LIBPATH_ENV_VAR "LIBPATH" #define VA_PTR(valist) (&valist[0]) typedef struct { #if !defined(HYS390X) char stuff[16]; #endif char *ada; void (*rawFnAddress)(); } HyFunctionDescriptor_T; #define TOC_UNWRAP_ADDRESS(wrappedPointer) (((HyFunctionDescriptor_T *) (wrappedPointer))->rawFnAddress) #define PLATFORM_DLL_EXTENSION ".so" #ifdef HYS390X #ifndef HY_WORD64 #define HY_WORD64 #endif /* ifndef HY_WORD64 */ #endif /* HYS390X */ #endif /* ZOS */ #if !defined(VMCALL) #define VMCALL #define VMAPICALL #endif #define PVMCALL VMCALL * #define GLOBAL_DATA(symbol) ((void*)&(symbol)) #define GLOBAL_TABLE(symbol) GLOBAL_DATA(symbol) /** * Define platform specific types: *
    *
  • UDATA - unsigned data, can be used as an integer or * pointer storage
  • *
  • IDATA - signed data, can be used as an integer or * pointer storage
  • *
*/ /* FIXME: POINTER64 */ #if defined(HYX86_64) || defined(HYIA64) || defined(HYPPC64) || defined(HYS390X) || defined(POINTER64) typedef I_64 IDATA; typedef U_64 UDATA; #else /* this is default for non-64bit systems */ typedef I_32 IDATA; typedef U_32 UDATA; #endif /* defined(HYX86_64) */ #if !defined(DATA_TYPES_DEFINED) /* no generic U_64 or I_64 */ /* don't typedef BOOLEAN since it's already def'ed on Win32 */ #define BOOLEAN UDATA #ifndef HY_BIG_ENDIAN #define HY_LITTLE_ENDIAN #endif #endif #if !defined(HYCONST64) #define HYCONST64(x) x##L #endif #if !defined(HY_DEFAULT_SCHED) /** * By default, pthreads platforms use the SCHED_OTHER thread * scheduling policy. */ #define HY_DEFAULT_SCHED SCHED_OTHER #endif #if !defined(HY_PRIORITY_MAP) /** * If no priority map if provided, priorities will be determined * algorithmically. */ #endif #if !defined(FALSE) #define FALSE ((BOOLEAN) 0) #if !defined(TRUE) #define TRUE ((BOOLEAN) (!FALSE)) #endif #endif #if !defined(NULL) #if defined(__cplusplus) #define NULL (0) #else #define NULL ((void *)0) #endif #endif #define USE_PROTOTYPES #if defined(USE_PROTOTYPES) #define PROTOTYPE(x) x #define VARARGS , ... #else #define PROTOTYPE(x) () #define VARARGS #endif /** * Assign the default line delimiter, if it was not set. */ #if !defined(PLATFORM_LINE_DELIMITER) #define PLATFORM_LINE_DELIMITER "\015\012" #endif /** * Set the max path length, if it was not set. */ #if !defined(MAX_IMAGE_PATH_LENGTH) #define MAX_IMAGE_PATH_LENGTH (2048) #endif typedef double ESDOUBLE; typedef float ESSINGLE; /** * Helpers for U_64s. */ #define CLEAR_U64(u64) (u64 = (U_64)0) #define LOW_LONG(l) (*((U_32 *) &(l))) #define HIGH_LONG(l) (*(((U_32 *) &(l)) + 1)) #define I8(x) ((I_8) (x)) #define I8P(x) ((I_8 *) (x)) #define U16(x) ((U_16) (x)) #define I16(x) ((I_16) (x)) #define I16P(x) ((I_16 *) (x)) #define U32(x) ((U_32) (x)) #define I32(x) ((I_32) (x)) #define I32P(x) ((I_32 *) (x)) #define U16P(x) ((U_16 *) (x)) #define U32P(x) ((U_32 *) (x)) #define OBJP(x) ((HyObject *) (x)) #define OBJPP(x) ((HyObject **) (x)) #define OBJPPP(x) ((HyObject ***) (x)) #define CLASSP(x) ((Class *) (x)) #define CLASSPP(x) ((Class **) (x)) #define BYTEP(x) ((BYTE *) (x)) /** * Test - was conflicting with OS2.h */ #define ESCHAR(x) ((CHARACTER) (x)) #define FLT(x) ((FLOAT) x) #define FLTP(x) ((FLOAT *) (x)) #if defined(NO_LVALUE_CASTING) #define LI8(x) (*((I_8 *) &(x))) #define LI8P(x) (*((I_8 **) &(x))) #define LU16(x) (*((U_16 *) &(x))) #define LI16(x) (*((I_16 *) &(x))) #define LU32(x) (*((U_32 *) &(x))) #define LI32(x) (*((I_32 *) &(x))) #define LI32P(x) (*((I_32 **) &(x))) #define LU16P(x) (*((U_16 **) &(x))) #define LU32P(x) (*((U_32 **) &(x))) #define LOBJP(x) (*((HyObject **) &(x))) #define LOBJPP(x) (*((HyObject ***) &(x))) #define LOBJPPP(x) (*((HyObject ****) &(x)) #define LCLASSP(x) (*((Class **) &(x))) #define LBYTEP(x) (*((BYTE **) &(x))) #define LCHAR(x) (*((CHARACTER) &(x))) #define LFLT(x) (*((FLOAT) &x)) #define LFLTP(x) (*((FLOAT *) &(x))) #else #define LI8(x) I8((x)) #define LI8P(x) I8P((x)) #define LU16(x) U16((x)) #define LI16(x) I16((x)) #define LU32(x) U32((x)) #define LI32(x) I32((x)) #define LI32P(x) I32P((x)) #define LU16P(x) U16P((x)) #define LU32P(x) U32P((x)) #define LOBJP(x) OBJP((x)) #define LOBJPP(x) OBJPP((x)) #define LOBJPPP(x) OBJPPP((x)) #define LIOBJP(x) IOBJP((x)) #define LCLASSP(x) CLASSP((x)) #define LBYTEP(x) BYTEP((x)) #define LCHAR(x) CHAR((x)) #define LFLT(x) FLT((x)) #define LFLTP(x) FLTP((x)) #endif /** * Macros for converting between words and longs and accessing bits. */ #define HIGH_WORD(x) U16(U32((x)) >> 16) #define LOW_WORD(x) U16(U32((x)) & 0xFFFF) #define LOW_BIT(o) (U32((o)) & 1) #define LOW_2_BITS(o) (U32((o)) & 3) #define LOW_3_BITS(o) (U32((o)) & 7) #define LOW_4_BITS(o) (U32((o)) & 15) #define MAKE_32(h, l) ((U32((h)) << 16) | U32((l))) #define MAKE_64(h, l) ((((I_64)(h)) << 32) | (l)) #if defined(__cplusplus) #define HY_CFUNC "C" #define HY_CDATA "C" #else #define HY_CFUNC #define HY_CDATA #endif /** * Macros for tagging functions which read/write the vm thread. */ #define READSVMTHREAD #define WRITESVMTHREAD #define REQUIRESSTACKFRAME /** * Macro for tagging functions, which never return. */ #if defined(__GNUC__) /** * On GCC, we can actually pass this information on to the compiler. */ #define NORETURN __attribute__((noreturn)) #else #define NORETURN #endif /** * On some systems va_list is an array type. This is probably in * violation of the ANSI C spec, but it's not entirely clear. Because of * this, we end up with an undesired extra level of indirection if we take * the address of a va_list argument. * * To get it right, always use the VA_PTR macro */ #if !defined(VA_PTR) #define VA_PTR(valist) (&valist) #endif #if !defined(TOC_UNWRAP_ADDRESS) #define TOC_UNWRAP_ADDRESS(wrappedPointer) (wrappedPointer) #endif #if !defined(TOC_STORE_TOC) #define TOC_STORE_TOC(dest,wrappedPointer) #endif /** * Macros for accessing I_64 values. */ #if defined(ATOMIC_LONG_ACCESS) #define PTR_LONG_STORE(dstPtr, aLongPtr) ((*U32P(dstPtr) = *U32P(aLongPtr)), (*(U32P(dstPtr)+1) = *(U32P(aLongPtr)+1))) #define PTR_LONG_VALUE(dstPtr, aLongPtr) ((*U32P(aLongPtr) = *U32P(dstPtr)), (*(U32P(aLongPtr)+1) = *(U32P(dstPtr)+1))) #else #define PTR_LONG_STORE(dstPtr, aLongPtr) (*(dstPtr) = *(aLongPtr)) #define PTR_LONG_VALUE(dstPtr, aLongPtr) (*(aLongPtr) = *(dstPtr)) #endif /** * Macro used when declaring tables which require relocations. */ #if !defined(HYCONST_TABLE) #define HYCONST_TABLE const #endif /** * ANSI qsort is not always available. */ #if !defined(HY_SORT) #define HY_SORT(base, nmemb, size, compare) qsort((base), (nmemb), (size), (compare)) #endif /** * Helper macros for storing/restoring pointers to jlong. */ #define jlong2addr(a, x) ((a *)((IDATA)(x))) #define addr2jlong(x) ((jlong)((IDATA)(x))) #endif /* hycomp_h */ ================================================ FILE: runtime/src/main/cpp/math/COPYRIGHT ================================================ musl as a whole is licensed under the following standard MIT license: ---------------------------------------------------------------------- Copyright © 2005-2014 Rich Felker, et al. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------- Authors/contributors include: Anthony G. Basile Arvid Picciani Bobby Bingham Boris Brezillon Chris Spiegel Emil Renner Berthing Hiltjo Posthuma Isaac Dunham Jens Gustedt Jeremy Huntwork John Spencer Justin Cormack Luca Barbato Luka Perkov Michael Forney Nicholas J. Kain orc Pascal Cuoq Pierre Carrier Rich Felker Richard Pennington Solar Designer Strake Szabolcs Nagy Timo Teräs Valentin Ochs William Haddon Portions of this software are derived from third-party works licensed under terms compatible with the above MIT license: The TRE regular expression implementation (src/regex/reg* and src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed under a 2-clause BSD license (license text in the source files). The included version has been heavily modified by Rich Felker in 2012, in the interests of size, simplicity, and namespace cleanliness. Much of the math library code (src/math/* and src/complex/*) is Copyright © 1993,2004 Sun Microsystems or Copyright © 2003-2011 David Schultz or Copyright © 2003-2009 Steven G. Kargl or Copyright © 2003-2009 Bruce D. Evans or Copyright © 2008 Stephen L. Moshier and labelled as such in comments in the individual source files. All have been licensed under extremely permissive terms. The ARM memcpy code (src/string/armel/memcpy.s) is Copyright © 2008 The Android Open Source Project and is licensed under a two-clause BSD license. It was taken from Bionic libc, used on Android. The implementation of DES for crypt (src/misc/crypt_des.c) is Copyright © 1994 David Burren. It is licensed under a BSD license. The implementation of blowfish crypt (src/misc/crypt_blowfish.c) was originally written by Solar Designer and placed into the public domain. The code also comes with a fallback permissive license for use in jurisdictions that may not recognize the public domain. The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011 Valentin Ochs and is licensed under an MIT-style license. The BSD PRNG implementation (src/prng/random.c) and XSI search API (src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and licensed under following terms: "Permission to use, copy, modify, and/or distribute this code for any purpose with or without fee is hereby granted. There is no warranty." The x86_64 port was written by Nicholas J. Kain. Several files (crt) were released into the public domain; others are licensed under the standard MIT license terms at the top of this file. See individual files for their copyright status. The mips and microblaze ports were originally written by Richard Pennington for use in the ellcc project. The original code was adapted by Rich Felker for build system and code conventions during upstream integration. It is licensed under the standard MIT terms. The powerpc port was also originally written by Richard Pennington, and later supplemented and integrated by John Spencer. It is licensed under the standard MIT terms. All other files which have no copyright comments are original works produced specifically for use as part of this library, written either by Rich Felker, the main author of the library, or by one or more contibutors listed above. Details on authorship of individual files can be found in the git version control history of the project. The omission of copyright and license comments in each file is in the interest of source tree size. All public header files (include/* and arch/*/bits/*) should be treated as Public Domain as they intentionally contain no content which can be covered by copyright. Some source modules may fall in this category as well. If you believe that a file is so trivial that it should be in the Public Domain, please contact the authors and request an explicit statement releasing it from copyright. The following files are trivial, believed not to be copyrightable in the first place, and hereby explicitly released to the Public Domain: All public headers: include/*, arch/*/bits/* Startup files: crt/* ================================================ FILE: runtime/src/main/cpp/math/endian.h ================================================ #ifndef _ENDIAN_H #define _ENDIAN_H #include #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 #define __PDP_ENDIAN 3412 #if defined(__GNUC__) && defined(__BYTE_ORDER__) #define __BYTE_ORDER __BYTE_ORDER__ #else #include #endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #define BIG_ENDIAN __BIG_ENDIAN #define LITTLE_ENDIAN __LITTLE_ENDIAN #define PDP_ENDIAN __PDP_ENDIAN #define BYTE_ORDER __BYTE_ORDER #include static __inline uint16_t __bswap16(uint16_t __x) { return __x<<8 | __x>>8; } static __inline uint32_t __bswap32(uint32_t __x) { return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24; } static __inline uint64_t __bswap64(uint64_t __x) { return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32); } #if __BYTE_ORDER == __LITTLE_ENDIAN #define htobe16(x) __bswap16(x) #define be16toh(x) __bswap16(x) #define betoh16(x) __bswap16(x) #define htobe32(x) __bswap32(x) #define be32toh(x) __bswap32(x) #define betoh32(x) __bswap32(x) #define htobe64(x) __bswap64(x) #define be64toh(x) __bswap64(x) #define betoh64(x) __bswap64(x) #define htole16(x) (uint16_t)(x) #define le16toh(x) (uint16_t)(x) #define letoh16(x) (uint16_t)(x) #define htole32(x) (uint32_t)(x) #define le32toh(x) (uint32_t)(x) #define letoh32(x) (uint32_t)(x) #define htole64(x) (uint64_t)(x) #define le64toh(x) (uint64_t)(x) #define letoh64(x) (uint64_t)(x) #else #define htobe16(x) (uint16_t)(x) #define be16toh(x) (uint16_t)(x) #define betoh16(x) (uint16_t)(x) #define htobe32(x) (uint32_t)(x) #define be32toh(x) (uint32_t)(x) #define betoh32(x) (uint32_t)(x) #define htobe64(x) (uint64_t)(x) #define be64toh(x) (uint64_t)(x) #define betoh64(x) (uint64_t)(x) #define htole16(x) __bswap16(x) #define le16toh(x) __bswap16(x) #define letoh16(x) __bswap16(x) #define htole32(x) __bswap32(x) #define le32toh(x) __bswap32(x) #define letoh32(x) __bswap32(x) #define htole64(x) __bswap64(x) #define le64toh(x) __bswap64(x) #define letoh64(x) __bswap64(x) #endif #endif #endif ================================================ FILE: runtime/src/main/cpp/math/fmod.cpp ================================================ #include #include #ifdef KONAN_WASM #include "Common.h" #endif #ifdef KONAN_WASM RUNTIME_USED #endif double fmod(double x, double y) { union {double f; uint64_t i;} ux = {x}, uy = {y}; int ex = ux.i>>52 & 0x7ff; int ey = uy.i>>52 & 0x7ff; int sx = ux.i>>63; uint64_t i; /* in the followings uxi should be ux.i, but then gcc wrongly adds */ /* float load/store to inner loops ruining performance and code size */ uint64_t uxi = ux.i; if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) return (x*y)/(x*y); if (uxi<<1 <= uy.i<<1) { if (uxi<<1 == uy.i<<1) return 0*x; return x; } /* normalize x and y */ if (!ex) { for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1); uxi <<= -ex + 1; } else { uxi &= -1ULL >> 12; uxi |= 1ULL << 52; } if (!ey) { for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); uy.i <<= -ey + 1; } else { uy.i &= -1ULL >> 12; uy.i |= 1ULL << 52; } /* x mod y */ for (; ex > ey; ex--) { i = uxi - uy.i; if (i >> 63 == 0) { if (i == 0) return 0*x; uxi = i; } uxi <<= 1; } i = uxi - uy.i; if (i >> 63 == 0) { if (i == 0) return 0*x; uxi = i; } for (; uxi>>52 == 0; uxi <<= 1, ex--); /* scale result */ if (ex > 0) { uxi -= 1ULL << 52; uxi |= (uint64_t)ex << 52; } else { uxi >>= -ex + 1; } uxi |= (uint64_t)sx << 63; ux.i = uxi; return ux.f; } ================================================ FILE: runtime/src/main/cpp/math/fmodf.cpp ================================================ #include #include #ifdef KONAN_WASM #include "Common.h" #endif #ifdef KONAN_WASM RUNTIME_USED #endif float fmodf(float x, float y) { union {float f; uint32_t i;} ux = {x}, uy = {y}; int ex = ux.i>>23 & 0xff; int ey = uy.i>>23 & 0xff; uint32_t sx = ux.i & 0x80000000; uint32_t i; uint32_t uxi = ux.i; if (uy.i<<1 == 0 || isnan(y) || ex == 0xff) return (x*y)/(x*y); if (uxi<<1 <= uy.i<<1) { if (uxi<<1 == uy.i<<1) return 0*x; return x; } /* normalize x and y */ if (!ex) { for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1); uxi <<= -ex + 1; } else { uxi &= -1U >> 9; uxi |= 1U << 23; } if (!ey) { for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1); uy.i <<= -ey + 1; } else { uy.i &= -1U >> 9; uy.i |= 1U << 23; } /* x mod y */ for (; ex > ey; ex--) { i = uxi - uy.i; if (i >> 31 == 0) { if (i == 0) return 0*x; uxi = i; } uxi <<= 1; } i = uxi - uy.i; if (i >> 31 == 0) { if (i == 0) return 0*x; uxi = i; } for (; uxi>>23 == 0; uxi <<= 1, ex--); /* scale result up */ if (ex > 0) { uxi -= 1U << 23; uxi |= (uint32_t)ex << 23; } else { uxi >>= -ex + 1; } uxi |= sx; ux.i = uxi; return ux.f; } ================================================ FILE: runtime/src/main/cpp/math/libm.h ================================================ /* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ #ifndef _LIBM_H #define _LIBM_H #include #include #include //#include "endian.h" #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN union ldshape { long double f; struct { uint64_t m; uint16_t se; } i; }; #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN union ldshape { long double f; struct { uint64_t lo; uint32_t mid; uint16_t top; uint16_t se; } i; struct { uint64_t lo; uint64_t hi; } i2; }; #else #error Unsupported long double representation #endif #ifdef __EMSCRIPTEN__ /* * asm.js doesn't have user-accessible floating point exceptions, so there's * no point in trying to force expression evaluations to produce them. */ #define FORCE_EVAL(x) #else #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ volatile float __x; \ __x = (x); \ } else if (sizeof(x) == sizeof(double)) { \ volatile double __x; \ __x = (x); \ } else { \ volatile long double __x; \ __x = (x); \ } \ } while(0) #endif /* Get two 32 bit ints from a double. */ #define EXTRACT_WORDS(hi,lo,d) \ do { \ union {double f; uint64_t i;} __u; \ __u.f = (d); \ (hi) = __u.i >> 32; \ (lo) = (uint32_t)__u.i; \ } while (0) /* Get the more significant 32 bit int from a double. */ #define GET_HIGH_WORD(hi,d) \ do { \ union {double f; uint64_t i;} __u; \ __u.f = (d); \ (hi) = __u.i >> 32; \ } while (0) /* Get the less significant 32 bit int from a double. */ #define GET_LOW_WORD(lo,d) \ do { \ union {double f; uint64_t i;} __u; \ __u.f = (d); \ (lo) = (uint32_t)__u.i; \ } while (0) /* Set a double from two 32 bit ints. */ #define INSERT_WORDS(d,hi,lo) \ do { \ union {double f; uint64_t i;} __u; \ __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \ (d) = __u.f; \ } while (0) /* Set the more significant 32 bits of a double from an int. */ #define SET_HIGH_WORD(d,hi) \ do { \ union {double f; uint64_t i;} __u; \ __u.f = (d); \ __u.i &= 0xffffffff; \ __u.i |= (uint64_t)(hi) << 32; \ (d) = __u.f; \ } while (0) /* Set the less significant 32 bits of a double from an int. */ #define SET_LOW_WORD(d,lo) \ do { \ union {double f; uint64_t i;} __u; \ __u.f = (d); \ __u.i &= 0xffffffff00000000ull; \ __u.i |= (uint32_t)(lo); \ (d) = __u.f; \ } while (0) /* Get a 32 bit int from a float. */ #define GET_FLOAT_WORD(w,d) \ do { \ union {float f; uint32_t i;} __u; \ __u.f = (d); \ (w) = __u.i; \ } while (0) /* Set a float from a 32 bit int. */ #define SET_FLOAT_WORD(d,w) \ do { \ union {float f; uint32_t i;} __u; \ __u.i = (w); \ (d) = __u.f; \ } while (0) /* fdlibm kernel functions */ int __rem_pio2_large(double*,double*,int,int,int); int __rem_pio2(double,double*); double __sin(double,double,int); double __cos(double,double); double __tan(double,double,int); double __expo2(double); int __rem_pio2f(float,double*); float __sindf(double); float __cosdf(double); float __tandf(double,int); float __expo2f(float); int __rem_pio2l(long double, long double *); long double __sinl(long double, long double, int); long double __cosl(long double, long double); long double __tanl(long double, long double, int); /* polynomial evaluation */ long double __polevll(long double, const long double *, int); long double __p1evll(long double, const long double *, int); #endif ================================================ FILE: runtime/src/main/cpp/math/scalbn.cpp ================================================ #include #include double scalbn(double x, int n) { union {double f; uint64_t i;} u; double_t y = x; if (n > 1023) { y *= 0x1p1023; n -= 1023; if (n > 1023) { y *= 0x1p1023; n -= 1023; if (n > 1023) n = 1023; } } else if (n < -1022) { y *= 0x1p-1022; n += 1022; if (n < -1022) { y *= 0x1p-1022; n += 1022; if (n < -1022) n = -1022; } } u.i = (uint64_t)(0x3ff+n)<<52; x = y * u.f; return x; } ================================================ FILE: runtime/src/main/cpp/polyhash/PolyHash.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "polyhash/PolyHash.h" #include "polyhash/naive.h" #include "polyhash/x86.h" #include "polyhash/arm.h" int polyHash(int length, uint16_t const* str) { #if defined(__x86_64__) or defined(__i386__) return polyHash_x86(length, str); #elif defined(__arm__) or defined(__aarch64__) return polyHash_arm(length, str); #else return polyHash_naive(length, str); #endif } ================================================ FILE: runtime/src/main/cpp/polyhash/PolyHash.h ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POLYHASH_H #define RUNTIME_POLYHASH_H #include // Computes polynomial hash with base = 31. int polyHash(int length, uint16_t const* str); #endif // RUNTIME_POLYHASH_H ================================================ FILE: runtime/src/main/cpp/polyhash/PolyHashTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "polyhash/PolyHash.h" #include "polyhash/naive.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace { TEST(PolyHashTest, Correctness) { const int maxLength = 10000; uint16_t str[maxLength + 100]; for (int k = 1; k <= maxLength; ++k) { for (int i = 0; i < k; ++i) str[i] = k * maxLength + i; str[k] = 0; for (int shift = 0; shift < 8 && k - shift > 0; ++shift) EXPECT_EQ(polyHash_naive(k - shift, str + shift), polyHash(k - shift, str + shift)); } } } ================================================ FILE: runtime/src/main/cpp/polyhash/arm.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "polyhash/common.h" #include "polyhash/arm.h" #if defined(__arm__) or defined(__aarch64__) #ifndef __ARM_NEON int polyHash_arm(int length, uint16_t const* str) { return polyHash_naive(length, str); } #else #include namespace { alignas(32) constexpr auto p32 = DecreasingPowers<32>(31); // [base^31, base^30, .., base^2, base, 1] alignas(32) constexpr auto b32 = RepeatingPowers<8>(31, 32); // [base^32, base^32, .., base^32] (8) alignas(32) constexpr auto b16 = RepeatingPowers<8>(31, 16); // [base^16, base^16, .., base^16] (8) alignas(32) constexpr auto b8 = RepeatingPowers<8>(31, 8); // [base^8, base^8, .., base^8 ] (8) alignas(32) constexpr auto b4 = RepeatingPowers<8>(31, 4); // [base^4, base^4, .., base^4 ] (8) struct NeonTraits { using VecType = uint32x4_t; using Vec128Type = uint32x4_t; using U16VecType = uint16x4_t; ALWAYS_INLINE static VecType initVec() { return vdupq_n_u32(0); } ALWAYS_INLINE static Vec128Type initVec128() { return vdupq_n_u32(0); } ALWAYS_INLINE static int vec128toInt(Vec128Type x) { return vgetq_lane_u32(x, 0); } ALWAYS_INLINE static VecType u16Load(U16VecType x) { return vmovl_u16(x); } ALWAYS_INLINE static Vec128Type vec128Mul(Vec128Type x, Vec128Type y) { return vmulq_u32(x, y); } ALWAYS_INLINE static Vec128Type vec128Add(Vec128Type x, Vec128Type y) { return vaddq_u32(x, y); } ALWAYS_INLINE static VecType vecMul(VecType x, VecType y) { return vmulq_u32(x, y); } ALWAYS_INLINE static VecType vecAdd(VecType x, VecType y) { return vaddq_u32(x, y); } ALWAYS_INLINE static Vec128Type squash2(VecType x, VecType y) { return squash1(vaddq_u32(x, y)); // [x0 + y0, x1 + y1, x2 + y2, x3 + y3] } ALWAYS_INLINE static uint32x4_t squash1(uint32x4_t z) { #ifdef __aarch64__ return vdupq_n_u32(vaddvq_u32(z)); // [z0..3, same, same, same] #else uint32x2_t lo = vget_low_u32(z); // [z0, z1] uint32x2_t hi = vget_high_u32(z); // [z2, z3] uint32x2_t sum = vadd_u32(lo, hi); // [z0 + z2, z1 + z3] sum = vpadd_u32(sum, sum); // [z0..3, same] return vcombine_u32(sum, sum); // [z0..3, same, same, same] #endif }; static int polyHashUnalignedUnrollUpTo16(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll4(n, str, res, &b16[0], &p32[16]); polyHashUnroll2(n, str, res, &b8[0], &p32[24]); polyHashTail(n, str, res, &b4[0], &p32[28]); return vec128toInt(res); } static int polyHashUnalignedUnrollUpTo32(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll8(n, str, res, &b32[0], &p32[0]); polyHashUnroll4(n, str, res, &b16[0], &p32[16]); polyHashUnroll2(n, str, res, &b8[0], &p32[24]); polyHashTail(n, str, res, &b4[0], &p32[28]); return vec128toInt(res); } }; #if defined(__aarch64__) const bool neonSupported = true; // AArch64 always supports Neon. #elif defined(__ANDROID__) #include const bool neonSupported = android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON; #elif defined(__APPLE__) const bool neonSupported = true; // It is supported starting from iPhone 3GS. #elif defined(__linux__) or defined(__unix__) #include #include const bool neonSupported = getauxval(AT_HWCAP) & HWCAP_NEON; #else #error "Not supported" #endif } int polyHash_arm(int length, uint16_t const* str) { if (!neonSupported) { // Vectorization is not supported. return polyHash_naive(length, str); } uint32_t res; if (length < 488) res = NeonTraits::polyHashUnalignedUnrollUpTo16(length / 4, str); else res = NeonTraits::polyHashUnalignedUnrollUpTo32(length / 4, str); // Handle the tail naively. for (int i = length & 0xFFFFFFFC; i < length; ++i) res = res * 31 + str[i]; return res; } #endif // __ARM_NEON #endif // defined(__arm__) or defined(__aarch64__) ================================================ FILE: runtime/src/main/cpp/polyhash/arm.h ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POLYHASH_ARM_H #define RUNTIME_POLYHASH_ARM_H int polyHash_arm(int length, uint16_t const* str); #endif // RUNTIME_POLYHASH_ARM_H ================================================ FILE: runtime/src/main/cpp/polyhash/common.h ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POLYHASH_COMMON_H #define RUNTIME_POLYHASH_COMMON_H #include #include #include "polyhash/naive.h" #include "../Common.h" constexpr uint32_t Power(uint32_t base, uint8_t exponent) { uint32_t result = 1; for (uint8_t i = 0; i < exponent; ++i) { result *= base; } return result; } template constexpr std::array DecreasingPowers(uint32_t base) { std::array result = {}; uint32_t current = 1; for (auto it = result.rbegin(); it != result.rend(); ++it) { *it = current; current *= base; } return result; } template constexpr std::array RepeatingPowers(uint32_t base, uint8_t exponent) { std::array result = {}; uint32_t value = Power(base, exponent); for (auto& element : result) element = value; return result; } template ALWAYS_INLINE void polyHashTail(int& n, uint16_t const*& str, typename Traits::Vec128Type& res, uint32_t const* b, uint32_t const* p) { using VecType = typename Traits::VecType; using Vec128Type = typename Traits::Vec128Type; using U16VecType = typename Traits::U16VecType; const int vecLength = sizeof(VecType) / 4; if (n < vecLength / 4) return; VecType x = Traits::u16Load(*reinterpret_cast(str)); res = Traits::vec128Mul(res, *reinterpret_cast(b)); VecType z = Traits::vecMul(x, *reinterpret_cast(p)); res = Traits::vec128Add(res, Traits::squash1(z)); str += vecLength; n -= vecLength / 4; } template ALWAYS_INLINE void polyHashUnroll2(int& n, uint16_t const*& str, typename Traits::Vec128Type& res, uint32_t const* b, uint32_t const* p) { using VecType = typename Traits::VecType; using Vec128Type = typename Traits::Vec128Type; using U16VecType = typename Traits::U16VecType; const int vecLength = sizeof(VecType) / 4; if (n < vecLength / 2) return; res = Traits::vec128Mul(res, *reinterpret_cast(b)); VecType res0 = Traits::initVec(); VecType res1 = Traits::initVec(); do { VecType x0 = Traits::u16Load(*reinterpret_cast(str)); VecType x1 = Traits::u16Load(*reinterpret_cast(str + vecLength)); res0 = Traits::vecMul(res0, *reinterpret_cast(b)); res1 = Traits::vecMul(res1, *reinterpret_cast(b)); VecType z0 = Traits::vecMul(x0, *reinterpret_cast(p)); VecType z1 = Traits::vecMul(x1, *reinterpret_cast(p + vecLength)); res0 = Traits::vecAdd(res0, z0); res1 = Traits::vecAdd(res1, z1); str += vecLength * 2; n -= vecLength / 2; } while (n >= vecLength / 2); res = Traits::vec128Add(res, Traits::squash2(res0, res1)); } template ALWAYS_INLINE void polyHashUnroll4(int& n, uint16_t const*& str, typename Traits::Vec128Type& res, uint32_t const* b, uint32_t const* p) { using VecType = typename Traits::VecType; using Vec128Type = typename Traits::Vec128Type; using U16VecType = typename Traits::U16VecType; const int vecLength = sizeof(VecType) / 4; if (n < vecLength) return; res = Traits::vec128Mul(res, *reinterpret_cast(b)); VecType res0 = Traits::initVec(); VecType res1 = Traits::initVec(); VecType res2 = Traits::initVec(); VecType res3 = Traits::initVec(); do { VecType x0 = Traits::u16Load(*reinterpret_cast(str)); VecType x1 = Traits::u16Load(*reinterpret_cast(str + vecLength)); VecType x2 = Traits::u16Load(*reinterpret_cast(str + vecLength * 2)); VecType x3 = Traits::u16Load(*reinterpret_cast(str + vecLength * 3)); res0 = Traits::vecMul(res0, *reinterpret_cast(b)); res1 = Traits::vecMul(res1, *reinterpret_cast(b)); res2 = Traits::vecMul(res2, *reinterpret_cast(b)); res3 = Traits::vecMul(res3, *reinterpret_cast(b)); VecType z0 = Traits::vecMul(x0, *reinterpret_cast(p)); VecType z1 = Traits::vecMul(x1, *reinterpret_cast(p + vecLength)); VecType z2 = Traits::vecMul(x2, *reinterpret_cast(p + vecLength * 2)); VecType z3 = Traits::vecMul(x3, *reinterpret_cast(p + vecLength * 3)); res0 = Traits::vecAdd(res0, z0); res1 = Traits::vecAdd(res1, z1); res2 = Traits::vecAdd(res2, z2); res3 = Traits::vecAdd(res3, z3); str += vecLength * 4; n -= vecLength; } while (n >= vecLength); res = Traits::vec128Add(res, Traits::vec128Add(Traits::squash2(res0, res1), Traits::squash2(res2, res3))); } template ALWAYS_INLINE void polyHashUnroll8(int& n, uint16_t const*& str, typename Traits::Vec128Type& res, uint32_t const* b, uint32_t const* p) { using VecType = typename Traits::VecType; using Vec128Type = typename Traits::Vec128Type; using U16VecType = typename Traits::U16VecType; const int vecLength = sizeof(VecType) / 4; if (n < vecLength * 2) return; VecType res0 = Traits::initVec(); VecType res1 = Traits::initVec(); VecType res2 = Traits::initVec(); VecType res3 = Traits::initVec(); VecType res4 = Traits::initVec(); VecType res5 = Traits::initVec(); VecType res6 = Traits::initVec(); VecType res7 = Traits::initVec(); do { VecType x0 = Traits::u16Load(*reinterpret_cast(str)); VecType x1 = Traits::u16Load(*reinterpret_cast(str + vecLength)); VecType x2 = Traits::u16Load(*reinterpret_cast(str + vecLength * 2)); VecType x3 = Traits::u16Load(*reinterpret_cast(str + vecLength * 3)); VecType x4 = Traits::u16Load(*reinterpret_cast(str + vecLength * 4)); VecType x5 = Traits::u16Load(*reinterpret_cast(str + vecLength * 5)); VecType x6 = Traits::u16Load(*reinterpret_cast(str + vecLength * 6)); VecType x7 = Traits::u16Load(*reinterpret_cast(str + vecLength * 7)); res0 = Traits::vecMul(res0, *reinterpret_cast(b)); res1 = Traits::vecMul(res1, *reinterpret_cast(b)); res2 = Traits::vecMul(res2, *reinterpret_cast(b)); res3 = Traits::vecMul(res3, *reinterpret_cast(b)); res4 = Traits::vecMul(res4, *reinterpret_cast(b)); res5 = Traits::vecMul(res5, *reinterpret_cast(b)); res6 = Traits::vecMul(res6, *reinterpret_cast(b)); res7 = Traits::vecMul(res7, *reinterpret_cast(b)); VecType z0 = Traits::vecMul(x0, *reinterpret_cast(p)); VecType z1 = Traits::vecMul(x1, *reinterpret_cast(p + vecLength)); VecType z2 = Traits::vecMul(x2, *reinterpret_cast(p + vecLength * 2)); VecType z3 = Traits::vecMul(x3, *reinterpret_cast(p + vecLength * 3)); VecType z4 = Traits::vecMul(x4, *reinterpret_cast(p + vecLength * 4)); VecType z5 = Traits::vecMul(x5, *reinterpret_cast(p + vecLength * 5)); VecType z6 = Traits::vecMul(x6, *reinterpret_cast(p + vecLength * 6)); VecType z7 = Traits::vecMul(x7, *reinterpret_cast(p + vecLength * 7)); res0 = Traits::vecAdd(res0, z0); res1 = Traits::vecAdd(res1, z1); res2 = Traits::vecAdd(res2, z2); res3 = Traits::vecAdd(res3, z3); res4 = Traits::vecAdd(res4, z4); res5 = Traits::vecAdd(res5, z5); res6 = Traits::vecAdd(res6, z6); res7 = Traits::vecAdd(res7, z7); str += vecLength * 8; n -= vecLength * 2; } while (n >= vecLength * 2); Vec128Type sum1 = Traits::vec128Add(Traits::squash2(res0, res1), Traits::squash2(res2, res3)); Vec128Type sum2 = Traits::vec128Add(Traits::squash2(res4, res5), Traits::squash2(res6, res7)); res = Traits::vec128Add(res, Traits::vec128Add(sum1, sum2)); } #endif // RUNTIME_POLYHASH_COMMON_H ================================================ FILE: runtime/src/main/cpp/polyhash/naive.h ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POLYHASH_NAIVE_H #define RUNTIME_POLYHASH_NAIVE_H #include inline int polyHash_naive(int length, uint16_t const* str) { uint32_t res = 0; for (int i = 0; i < length; ++i) res = res * 31 + str[i]; return res; } #endif // RUNTIME_POLYHASH_NAIVE_H ================================================ FILE: runtime/src/main/cpp/polyhash/x86.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "polyhash/common.h" #include "polyhash/x86.h" #if defined(__x86_64__) or defined(__i386__) #define __SSE41__ __attribute__((target("sse4.1"))) #define __AVX2__ __attribute__((target("avx2"))) #include namespace { alignas(32) constexpr auto p64 = DecreasingPowers<64>(31); // [base^63, base^62, .., base^2, base, 1] alignas(32) constexpr auto b64 = RepeatingPowers<8>(31, 64); // [base^64, base^64, .., base^64] (8) alignas(32) constexpr auto b32 = RepeatingPowers<8>(31, 32); // [base^32, base^32, .., base^32] (8) alignas(32) constexpr auto b16 = RepeatingPowers<8>(31, 16); // [base^16, base^16, .., base^16] (8) alignas(32) constexpr auto b8 = RepeatingPowers<8>(31, 8); // [base^8, base^8, .., base^8 ] (8) alignas(32) constexpr auto b4 = RepeatingPowers<8>(31, 4); // [base^4, base^4, .., base^4 ] (8) struct SSETraits { using VecType = __m128i; using Vec128Type = __m128i; using U16VecType = __m128i; __SSE41__ static VecType initVec() { return _mm_setzero_si128(); } __SSE41__ static Vec128Type initVec128() { return _mm_setzero_si128(); } __SSE41__ static int vec128toInt(Vec128Type x) { return _mm_cvtsi128_si32(x); } __SSE41__ static VecType u16Load(U16VecType x) { return _mm_cvtepu16_epi32(x); } __SSE41__ static Vec128Type vec128Mul(Vec128Type x, Vec128Type y) { return _mm_mullo_epi32(x, y); } __SSE41__ static Vec128Type vec128Add(Vec128Type x, Vec128Type y) { return _mm_add_epi32(x, y); } __SSE41__ static VecType vecMul(VecType x, VecType y) { return _mm_mullo_epi32(x, y); } __SSE41__ static VecType vecAdd(VecType x, VecType y) { return _mm_add_epi32(x, y); } __SSE41__ static Vec128Type squash2(VecType x, VecType y) { return squash1(_mm_hadd_epi32(x, y)); // [x0 + x1, x2 + x3, y0 + y1, y2 + y3] } __SSE41__ static Vec128Type squash1(VecType z) { VecType sum = _mm_hadd_epi32(z, z); // [z0 + z1, z2 + z3, z0 + z1, z2 + z3] return _mm_hadd_epi32(sum, sum); // [z0..3, same, same, same] } __SSE41__ static int polyHashUnalignedUnrollUpTo8(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll2(n, str, res, &b8[0], &p64[56]); polyHashTail(n, str, res, &b4[0], &p64[60]); return vec128toInt(res); } __SSE41__ static int polyHashUnalignedUnrollUpTo16(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll4(n, str, res, &b16[0], &p64[48]); polyHashUnroll2(n, str, res, &b8[0], &p64[56]); polyHashTail(n, str, res, &b4[0], &p64[60]); return vec128toInt(res); } }; struct AVX2Traits { using VecType = __m256i; using Vec128Type = __m128i; using U16VecType = __m128i; __AVX2__ static VecType initVec() { return _mm256_setzero_si256(); } __AVX2__ static Vec128Type initVec128() { return _mm_setzero_si128(); } __AVX2__ static int vec128toInt(Vec128Type x) { return _mm_cvtsi128_si32(x); } __AVX2__ static VecType u16Load(U16VecType x) { return _mm256_cvtepu16_epi32(x); } __AVX2__ static Vec128Type vec128Mul(Vec128Type x, Vec128Type y) { return _mm_mullo_epi32(x, y); } __AVX2__ static Vec128Type vec128Add(Vec128Type x, Vec128Type y) { return _mm_add_epi32(x, y); } __AVX2__ static VecType vecMul(VecType x, VecType y) { return _mm256_mullo_epi32(x, y); } __AVX2__ static VecType vecAdd(VecType x, VecType y) { return _mm256_add_epi32(x, y); } __AVX2__ static Vec128Type squash2(VecType x, VecType y) { return squash1(_mm256_hadd_epi32(x, y)); // [x0 + x1, x2 + x3, y0 + y1, y2 + y3, x4 + x5, x6 + x7, y4 + y5, y6 + y7] } __AVX2__ static Vec128Type squash1(VecType z) { VecType sum = _mm256_hadd_epi32(z, z); // [z0 + z1, z2 + z3, z0 + z1, z2 + z3, z4 + z5, z6 + z7, z4 + z5, z6 + z7] sum = _mm256_hadd_epi32(sum, sum); // [z0..3, z0..3, z0..3, z0..3, z4..7, z4..7, z4..7, z4..7] Vec128Type lo = _mm256_extracti128_si256(sum, 0); // [z0..3, same, same, same] Vec128Type hi = _mm256_extracti128_si256(sum, 1); // [z4..7, same, same, same] return _mm_add_epi32(lo, hi); // [z0..7, same, same, same] } __AVX2__ static int polyHashUnalignedUnrollUpTo16(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll2(n, str, res, &b16[0], &p64[48]); polyHashTail(n, str, res, &b8[0], &p64[56]); polyHashTail(n, str, res, &b4[0], &p64[60]); return vec128toInt(res); } __AVX2__ static int polyHashUnalignedUnrollUpTo32(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll4(n, str, res, &b32[0], &p64[32]); polyHashUnroll2(n, str, res, &b16[0], &p64[48]); polyHashTail(n, str, res, &b8[0], &p64[56]); polyHashTail(n, str, res, &b4[0], &p64[60]); return vec128toInt(res); } __AVX2__ static int polyHashUnalignedUnrollUpTo64(int n, uint16_t const* str) { Vec128Type res = initVec128(); polyHashUnroll8(n, str, res, &b64[0], &p64[0]); polyHashUnroll4(n, str, res, &b32[0], &p64[32]); polyHashUnroll2(n, str, res, &b16[0], &p64[48]); polyHashTail(n, str, res, &b8[0], &p64[56]); polyHashTail(n, str, res, &b4[0], &p64[60]); return vec128toInt(res); } }; #if defined(__x86_64__) const bool x64 = true; #else const bool x64 = false; #endif bool initialized = false; bool sseSupported = false; bool avx2Supported = false; } int polyHash_x86(int length, uint16_t const* str) { if (!initialized) { initialized = true; sseSupported = __builtin_cpu_supports("sse4.1"); avx2Supported = __builtin_cpu_supports("avx2"); } if (length < 16 || (!sseSupported && !avx2Supported)) { // Either vectorization is not supported or the string is too short to gain from it. return polyHash_naive(length, str); } uint32_t res; if (length < 32) res = SSETraits::polyHashUnalignedUnrollUpTo8(length / 4, str); else if (!avx2Supported) res = SSETraits::polyHashUnalignedUnrollUpTo16(length / 4, str); else if (length < 128) res = AVX2Traits::polyHashUnalignedUnrollUpTo16(length / 4, str); else if (!x64 || length < 576) res = AVX2Traits::polyHashUnalignedUnrollUpTo32(length / 4, str); else // Such big unrolling requires 64-bit mode (in 32-bit mode there are only 8 vector registers) res = AVX2Traits::polyHashUnalignedUnrollUpTo64(length / 4, str); // Handle the tail naively. for (int i = length & 0xFFFFFFFC; i < length; ++i) res = res * 31 + str[i]; return res; } #endif ================================================ FILE: runtime/src/main/cpp/polyhash/x86.h ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_POLYHASH_X86_H #define RUNTIME_POLYHASH_X86_H int polyHash_x86(int length, uint16_t const* str); #endif // RUNTIME_POLYHASH_X86_H ================================================ FILE: runtime/src/main/cpp/snprintf/AUTHORS ================================================ Patrick Powell Brandon Long Thomas Roessler Michael Elkins Andrew Tridgell Russ Allbery Hrvoje Niksic Damien Miller Holger Weiss ================================================ FILE: runtime/src/main/cpp/snprintf/COPYING ================================================ UNLESS SPECIFIED OTHERWISE IN THE INDIVIDUAL SOURCE FILES INCLUDED WITH THIS PACKAGE, they may freely be used, modified and/or redistributed for any purpose. ================================================ FILE: runtime/src/main/cpp/snprintf/snprintf.cpp ================================================ /* * Copyright (c) 1995 Patrick Powell. * * This code is based on code written by Patrick Powell . * It may be used for any purpose as long as this notice remains intact on all * source code distributions. */ /* * Copyright (c) 2008 Holger Weiss. * * This version of the code is maintained by Holger Weiss . * My changes to the code may freely be used, modified and/or redistributed for * any purpose. It would be nice if additions and fixes to this file (including * trivial code cleanups) would be sent back in order to let me include them in * the version available at . * However, this is not a requirement for using or redistributing (possibly * modified) versions of this file, nor is leaving this notice intact mandatory. */ /* * History * * 2008-01-20 Holger Weiss for C99-snprintf 1.1: * * Fixed the detection of infinite floating point values on IRIX (and * possibly other systems) and applied another few minor cleanups. * * 2008-01-06 Holger Weiss for C99-snprintf 1.0: * * Added a lot of new features, fixed many bugs, and incorporated various * improvements done by Andrew Tridgell , Russ Allbery * , Hrvoje Niksic , Damien Miller * , and others for the Samba, INN, Wget, and OpenSSH * projects. The additions include: support the "e", "E", "g", "G", and * "F" conversion specifiers (and use conversion style "f" or "F" for the * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", * "t", and "z" length modifiers; support the "#" flag and the (non-C99) * "'" flag; use localeconv(3) (if available) to get both the current * locale's decimal point character and the separator between groups of * digits; fix the handling of various corner cases of field width and * precision specifications; fix various floating point conversion bugs; * handle infinite and NaN floating point values; don't attempt to write to * the output buffer (which may be NULL) if a size of zero was specified; * check for integer overflow of the field width, precision, and return * values and during the floating point conversion; use the OUTCHAR() macro * instead of a function for better performance; provide asprintf(3) and * vasprintf(3) functions; add new test cases. The replacement functions * have been renamed to use an "rpl_" prefix, the function calls in the * main project (and in this file) must be redefined accordingly for each * replacement function which is needed (by using Autoconf or other means). * Various other minor improvements have been applied and the coding style * was cleaned up for consistency. * * 2007-07-23 Holger Weiss for Mutt 1.5.13: * * C99 compliant snprintf(3) and vsnprintf(3) functions return the number * of characters that would have been written to a sufficiently sized * buffer (excluding the '\0'). The original code simply returned the * length of the resulting output string, so that's been fixed. * * 1998-03-05 Michael Elkins for Mutt 0.90.8: * * The original code assumed that both snprintf(3) and vsnprintf(3) were * missing. Some systems only have snprintf(3) but not vsnprintf(3), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * 1998-01-27 Thomas Roessler for Mutt 0.89i: * * The PGP code was using unsigned hexadecimal formats. Unfortunately, * unsigned formats simply didn't work. * * 1997-10-22 Brandon Long for Mutt 0.87.1: * * Ok, added some minimal floating point support, which means this probably * requires libm on most operating systems. Don't yet support the exponent * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just * wasn't being exercised in ways which showed it, so that's been fixed. * Also, formatted the code to Mutt conventions, and removed dead code left * over from the original. Also, there is now a builtin-test, run with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf * * 2996-09-15 Brandon Long for Mutt 0.43: * * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything from the * normal C string format, at least as far as I can tell from the Solaris * 2.5 printf(3S) man page. */ /* * ToDo * * - Add wide character support. * - Add support for "%a" and "%A" conversions. * - Create test routines which predefine the expected results. Our test cases * usually expose bugs in system implementations rather than in ours :-) */ /* * Usage * * 1) The following preprocessor macros should be defined to 1 if the feature or * file in question is available on the target system (by using Autoconf or * other means), though basic functionality should be available as long as * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: * * HAVE_VSNPRINTF * HAVE_SNPRINTF * HAVE_VASPRINTF * HAVE_ASPRINTF * HAVE_STDARG_H * HAVE_STDDEF_H * HAVE_STDINT_H * HAVE_STDLIB_H * HAVE_FLOAT_H * HAVE_INTTYPES_H * HAVE_LOCALE_H * HAVE_LOCALECONV * HAVE_LCONV_DECIMAL_POINT * HAVE_LCONV_THOUSANDS_SEP * HAVE_LONG_DOUBLE * HAVE_LONG_LONG_INT * HAVE_UNSIGNED_LONG_LONG_INT * HAVE_INTMAX_T * HAVE_UINTMAX_T * HAVE_UINTPTR_T * HAVE_PTRDIFF_T * HAVE_VA_COPY * HAVE___VA_COPY * * 2) The calls to the functions which should be replaced must be redefined * throughout the project files (by using Autoconf or other means): * * #define vsnprintf rpl_vsnprintf * #define snprintf rpl_snprintf * #define vasprintf rpl_vasprintf * #define asprintf rpl_asprintf * * 3) The required replacement functions should be declared in some header file * included throughout the project files: * * #if HAVE_CONFIG_H * #include * #endif * #if HAVE_STDARG_H * #include * #if !HAVE_VSNPRINTF * int rpl_vsnprintf(char *, size_t, const char *, va_list); * #endif * #if !HAVE_SNPRINTF * int rpl_snprintf(char *, size_t, const char *, ...); * #endif * #if !HAVE_VASPRINTF * int rpl_vasprintf(char **, const char *, va_list); * #endif * #if !HAVE_ASPRINTF * int rpl_asprintf(char **, const char *, ...); * #endif * #endif * * Autoconf macros for handling step 1 and step 2 are available at * . */ #if KONAN_INTERNAL_SNPRINTF /**** Start of Konan-specific c99-snprintf configuration. ****/ #define HAVE_FLOAT_H 1 #define HAVE_STDARG_H 1 #define HAVE_STDDEF_H 1 #define HAVE_STDLIB_H 1 #define HAVE_SNPRINTF 1 #define HAVE_VASPRINTF 1 #define HAVE_ASPRINTF 1 #define HAVE_LONG_LONG_INT 1 #define HAVE_UNSIGNED_LONG_LONG_INT 1 #include #include extern "C" int rpl_vsnprintf(char *, size_t, const char *, va_list); #define malloc(size) konan:calloc(1, size) /**** End of Konan-specific c99-snprintf configuration. ****/ #if HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #if TEST_SNPRINTF #include /* For pow(3), NAN, and INFINITY. */ #include /* For strcmp(3). */ #if defined(__NetBSD__) || \ defined(__FreeBSD__) || \ defined(__OpenBSD__) || \ defined(__NeXT__) || \ defined(__bsd__) #define OS_BSD 1 #elif defined(sgi) || defined(__sgi) #ifndef __c99 #define __c99 /* Force C99 mode to get included on IRIX 6.5.30. */ #endif /* !defined(__c99) */ #define OS_IRIX 1 #define OS_SYSV 1 #elif defined(__svr4__) #define OS_SYSV 1 #elif defined(__linux__) #define OS_LINUX 1 #endif /* defined(__NetBSD__) || defined(__FreeBSD__) || [...] */ #if HAVE_CONFIG_H /* Undefine definitions possibly done in config.h. */ #ifdef HAVE_SNPRINTF #undef HAVE_SNPRINTF #endif /* defined(HAVE_SNPRINTF) */ #ifdef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF #endif /* defined(HAVE_VSNPRINTF) */ #ifdef HAVE_ASPRINTF #undef HAVE_ASPRINTF #endif /* defined(HAVE_ASPRINTF) */ #ifdef HAVE_VASPRINTF #undef HAVE_VASPRINTF #endif /* defined(HAVE_VASPRINTF) */ #ifdef snprintf #undef snprintf #endif /* defined(snprintf) */ #ifdef vsnprintf #undef vsnprintf #endif /* defined(vsnprintf) */ #ifdef asprintf #undef asprintf #endif /* defined(asprintf) */ #ifdef vasprintf #undef vasprintf #endif /* defined(vasprintf) */ #else /* By default, we assume a modern system for testing. */ #ifndef HAVE_STDARG_H #define HAVE_STDARG_H 1 #endif /* HAVE_STDARG_H */ #ifndef HAVE_STDDEF_H #define HAVE_STDDEF_H 1 #endif /* HAVE_STDDEF_H */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* HAVE_STDINT_H */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* HAVE_STDLIB_H */ #ifndef HAVE_FLOAT_H #define HAVE_FLOAT_H 1 #endif /* HAVE_FLOAT_H */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* HAVE_INTTYPES_H */ #ifndef HAVE_LOCALE_H #define HAVE_LOCALE_H 1 #endif /* HAVE_LOCALE_H */ #ifndef HAVE_LOCALECONV #define HAVE_LOCALECONV 1 #endif /* !defined(HAVE_LOCALECONV) */ #ifndef HAVE_LCONV_DECIMAL_POINT #define HAVE_LCONV_DECIMAL_POINT 1 #endif /* HAVE_LCONV_DECIMAL_POINT */ #ifndef HAVE_LCONV_THOUSANDS_SEP #define HAVE_LCONV_THOUSANDS_SEP 1 #endif /* HAVE_LCONV_THOUSANDS_SEP */ #ifndef HAVE_LONG_DOUBLE #define HAVE_LONG_DOUBLE 1 #endif /* !defined(HAVE_LONG_DOUBLE) */ #ifndef HAVE_LONG_LONG_INT #define HAVE_LONG_LONG_INT 1 #endif /* !defined(HAVE_LONG_LONG_INT) */ #ifndef HAVE_UNSIGNED_LONG_LONG_INT #define HAVE_UNSIGNED_LONG_LONG_INT 1 #endif /* !defined(HAVE_UNSIGNED_LONG_LONG_INT) */ #ifndef HAVE_INTMAX_T #define HAVE_INTMAX_T 1 #endif /* !defined(HAVE_INTMAX_T) */ #ifndef HAVE_UINTMAX_T #define HAVE_UINTMAX_T 1 #endif /* !defined(HAVE_UINTMAX_T) */ #ifndef HAVE_UINTPTR_T #define HAVE_UINTPTR_T 1 #endif /* !defined(HAVE_UINTPTR_T) */ #ifndef HAVE_PTRDIFF_T #define HAVE_PTRDIFF_T 1 #endif /* !defined(HAVE_PTRDIFF_T) */ #ifndef HAVE_VA_COPY #define HAVE_VA_COPY 1 #endif /* !defined(HAVE_VA_COPY) */ #ifndef HAVE___VA_COPY #define HAVE___VA_COPY 1 #endif /* !defined(HAVE___VA_COPY) */ #endif /* HAVE_CONFIG_H */ #define snprintf rpl_snprintf #define vsnprintf rpl_vsnprintf #define asprintf rpl_asprintf #define vasprintf rpl_vasprintf #endif /* TEST_SNPRINTF */ #if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF #include /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ #ifdef VA_START #undef VA_START #endif /* defined(VA_START) */ #ifdef VA_SHIFT #undef VA_SHIFT #endif /* defined(VA_SHIFT) */ #if HAVE_STDARG_H #include #define VA_START(ap, last) va_start(ap, last) #define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ #else /* Assume is available. */ #include #define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ #define VA_SHIFT(ap, value, type) value = va_arg(ap, type) #endif /* HAVE_STDARG_H */ #if !HAVE_VASPRINTF #if HAVE_STDLIB_H #include /* For malloc(3). */ #endif /* HAVE_STDLIB_H */ #ifdef VA_COPY #undef VA_COPY #endif /* defined(VA_COPY) */ #ifdef VA_END_COPY #undef VA_END_COPY #endif /* defined(VA_END_COPY) */ #if HAVE_VA_COPY #define VA_COPY(dest, src) va_copy(dest, src) #define VA_END_COPY(ap) va_end(ap) #elif HAVE___VA_COPY #define VA_COPY(dest, src) __va_copy(dest, src) #define VA_END_COPY(ap) va_end(ap) #else #define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) #define VA_END_COPY(ap) /* No-op. */ #define NEED_MYMEMCPY 1 static void *mymemcpy(void *, void *, size_t); #endif /* HAVE_VA_COPY */ #endif /* !HAVE_VASPRINTF */ #if !HAVE_VSNPRINTF #include /* For ERANGE and errno. */ #include /* For *_MAX. */ #if HAVE_FLOAT_H #include /* For *DBL_{MIN,MAX}_10_EXP. */ #endif /* HAVE_FLOAT_H */ #if HAVE_INTTYPES_H #include /* For intmax_t (if not defined in ). */ #endif /* HAVE_INTTYPES_H */ #if HAVE_LOCALE_H #include /* For localeconv(3). */ #endif /* HAVE_LOCALE_H */ #if HAVE_STDDEF_H #include /* For ptrdiff_t. */ #endif /* HAVE_STDDEF_H */ #if HAVE_STDINT_H #include /* For intmax_t. */ #endif /* HAVE_STDINT_H */ /* Support for unsigned long long int. We may also need ULLONG_MAX. */ #ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ #ifdef UINT_MAX #define ULONG_MAX UINT_MAX #else #define ULONG_MAX INT_MAX #endif /* defined(UINT_MAX) */ #endif /* !defined(ULONG_MAX) */ #ifdef ULLONG #undef ULLONG #endif /* defined(ULLONG) */ #if HAVE_UNSIGNED_LONG_LONG_INT #define ULLONG unsigned long long int #ifndef ULLONG_MAX #define ULLONG_MAX ULONG_MAX #endif /* !defined(ULLONG_MAX) */ #else #define ULLONG unsigned long int #ifdef ULLONG_MAX #undef ULLONG_MAX #endif /* defined(ULLONG_MAX) */ #define ULLONG_MAX ULONG_MAX #endif /* HAVE_LONG_LONG_INT */ /* Support for uintmax_t. We also need UINTMAX_MAX. */ #ifdef UINTMAX_T #undef UINTMAX_T #endif /* defined(UINTMAX_T) */ #if HAVE_UINTMAX_T || defined(uintmax_t) #define UINTMAX_T uintmax_t #ifndef UINTMAX_MAX #define UINTMAX_MAX ULLONG_MAX #endif /* !defined(UINTMAX_MAX) */ #else #define UINTMAX_T ULLONG #ifdef UINTMAX_MAX #undef UINTMAX_MAX #endif /* defined(UINTMAX_MAX) */ #define UINTMAX_MAX ULLONG_MAX #endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ /* Support for long double. */ #ifndef LDOUBLE #if HAVE_LONG_DOUBLE #define LDOUBLE long double #define LDOUBLE_MIN_10_EXP LDBL_MIN_10_EXP #define LDOUBLE_MAX_10_EXP LDBL_MAX_10_EXP #else #define LDOUBLE double #define LDOUBLE_MIN_10_EXP DBL_MIN_10_EXP #define LDOUBLE_MAX_10_EXP DBL_MAX_10_EXP #endif /* HAVE_LONG_DOUBLE */ #endif /* !defined(LDOUBLE) */ /* Support for long long int. */ #ifndef LLONG #if HAVE_LONG_LONG_INT #define LLONG long long int #else #define LLONG long int #endif /* HAVE_LONG_LONG_INT */ #endif /* !defined(LLONG) */ /* Support for intmax_t. */ #ifndef INTMAX_T #if HAVE_INTMAX_T || defined(intmax_t) #define INTMAX_T intmax_t #else #define INTMAX_T LLONG #endif /* HAVE_INTMAX_T || defined(intmax_t) */ #endif /* !defined(INTMAX_T) */ /* Support for uintptr_t. */ #ifndef UINTPTR_T #if HAVE_UINTPTR_T || defined(uintptr_t) #define UINTPTR_T uintptr_t #else #define UINTPTR_T unsigned long int #endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ #endif /* !defined(UINTPTR_T) */ /* Support for ptrdiff_t. */ #ifndef PTRDIFF_T #if HAVE_PTRDIFF_T || defined(ptrdiff_t) #define PTRDIFF_T ptrdiff_t #else #define PTRDIFF_T long int #endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ #endif /* !defined(PTRDIFF_T) */ /* * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an * unsigned type if necessary. This should work just fine in practice. */ #ifndef UPTRDIFF_T #define UPTRDIFF_T PTRDIFF_T #endif /* !defined(UPTRDIFF_T) */ /* * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). * However, we'll simply use size_t and convert it to a signed type if * necessary. This should work just fine in practice. */ #ifndef SSIZE_T #define SSIZE_T size_t #endif /* !defined(SSIZE_T) */ /* Either ERANGE or E2BIG should be available everywhere. */ #ifndef ERANGE #define ERANGE E2BIG #endif /* !defined(ERANGE) */ #ifndef EOVERFLOW #define EOVERFLOW ERANGE #endif /* !defined(EOVERFLOW) */ /* * Buffer size to hold the octal string representation of UINT128_MAX without * nul-termination ("3777777777777777777777777777777777777777777"). */ #ifdef MAX_CONVERT_LENGTH #undef MAX_CONVERT_LENGTH #endif /* defined(MAX_CONVERT_LENGTH) */ #define MAX_CONVERT_LENGTH 43 /* Format read states. */ #define PRINT_S_DEFAULT 0 #define PRINT_S_FLAGS 1 #define PRINT_S_WIDTH 2 #define PRINT_S_DOT 3 #define PRINT_S_PRECISION 4 #define PRINT_S_MOD 5 #define PRINT_S_CONV 6 /* Format flags. */ #define PRINT_F_MINUS (1 << 0) #define PRINT_F_PLUS (1 << 1) #define PRINT_F_SPACE (1 << 2) #define PRINT_F_NUM (1 << 3) #define PRINT_F_ZERO (1 << 4) #define PRINT_F_QUOTE (1 << 5) #define PRINT_F_UP (1 << 6) #define PRINT_F_UNSIGNED (1 << 7) #define PRINT_F_TYPE_G (1 << 8) #define PRINT_F_TYPE_E (1 << 9) /* Conversion flags. */ #define PRINT_C_CHAR 1 #define PRINT_C_SHORT 2 #define PRINT_C_LONG 3 #define PRINT_C_LLONG 4 #define PRINT_C_LDOUBLE 5 #define PRINT_C_SIZE 6 #define PRINT_C_PTRDIFF 7 #define PRINT_C_INTMAX 8 #ifndef MAX #define MAX(x, y) ((x >= y) ? x : y) #endif /* !defined(MAX) */ #ifndef CHARTOINT #define CHARTOINT(ch) (ch - '0') #endif /* !defined(CHARTOINT) */ #ifndef ISDIGIT #define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') #endif /* !defined(ISDIGIT) */ #ifndef ISNAN #define ISNAN(x) (x != x) #endif /* !defined(ISNAN) */ #ifndef ISINF #define ISINF(x) ((x < -1 || x > 1) && x + x == x) #endif /* !defined(ISINF) */ #ifdef OUTCHAR #undef OUTCHAR #endif /* defined(OUTCHAR) */ #define OUTCHAR(str, len, size, ch) \ do { \ if (len + 1 < size) \ str[len] = ch; \ (len)++; \ } while (/* CONSTCOND */ 0) static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); static void printsep(char *, size_t *, size_t); static int getnumsep(int); static int getexponent(LDOUBLE); static int convert(UINTMAX_T, char *, size_t, int, int); static UINTMAX_T cast(LDOUBLE); static UINTMAX_T myround(LDOUBLE); static LDOUBLE mypow10(int); extern int errno; int rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) { LDOUBLE fvalue; INTMAX_T value; unsigned char cvalue; const char *strvalue; INTMAX_T *intmaxptr; PTRDIFF_T *ptrdiffptr; SSIZE_T *sizeptr; LLONG *llongptr; long int *longptr; int *intptr; short int *shortptr; signed char *charptr; size_t len = 0; int overflow = 0; int base = 0; int cflags = 0; int flags = 0; int width = 0; int precision = -1; int state = PRINT_S_DEFAULT; char ch = *format++; /* * C99 says: "If `n' is zero, nothing is written, and `s' may be a null * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer * even if a size larger than zero was specified. At least NetBSD's * snprintf(3) does the same, as well as other versions of this file. * (Though some of these versions will write to a non-NULL buffer even * if a size of zero was specified, which violates the standard.) */ if (str == NULL && size != 0) size = 0; while (ch != '\0') switch (state) { case PRINT_S_DEFAULT: if (ch == '%') state = PRINT_S_FLAGS; else OUTCHAR(str, len, size, ch); ch = *format++; break; case PRINT_S_FLAGS: switch (ch) { case '-': flags |= PRINT_F_MINUS; ch = *format++; break; case '+': flags |= PRINT_F_PLUS; ch = *format++; break; case ' ': flags |= PRINT_F_SPACE; ch = *format++; break; case '#': flags |= PRINT_F_NUM; ch = *format++; break; case '0': flags |= PRINT_F_ZERO; ch = *format++; break; case '\'': /* SUSv2 flag (not in C99). */ flags |= PRINT_F_QUOTE; ch = *format++; break; default: state = PRINT_S_WIDTH; break; } break; case PRINT_S_WIDTH: if (ISDIGIT(ch)) { ch = CHARTOINT(ch); if (width > (INT_MAX - ch) / 10) { overflow = 1; goto out; } width = 10 * width + ch; ch = *format++; } else if (ch == '*') { /* * C99 says: "A negative field width argument is * taken as a `-' flag followed by a positive * field width." (7.19.6.1, 5) */ if ((width = va_arg(args, int)) < 0) { flags |= PRINT_F_MINUS; width = -width; } ch = *format++; state = PRINT_S_DOT; } else state = PRINT_S_DOT; break; case PRINT_S_DOT: if (ch == '.') { state = PRINT_S_PRECISION; ch = *format++; } else state = PRINT_S_MOD; break; case PRINT_S_PRECISION: if (precision == -1) precision = 0; if (ISDIGIT(ch)) { ch = CHARTOINT(ch); if (precision > (INT_MAX - ch) / 10) { overflow = 1; goto out; } precision = 10 * precision + ch; ch = *format++; } else if (ch == '*') { /* * C99 says: "A negative precision argument is * taken as if the precision were omitted." * (7.19.6.1, 5) */ if ((precision = va_arg(args, int)) < 0) precision = -1; ch = *format++; state = PRINT_S_MOD; } else state = PRINT_S_MOD; break; case PRINT_S_MOD: switch (ch) { case 'h': ch = *format++; if (ch == 'h') { /* It's a char. */ ch = *format++; cflags = PRINT_C_CHAR; } else cflags = PRINT_C_SHORT; break; case 'l': ch = *format++; if (ch == 'l') { /* It's a long long. */ ch = *format++; cflags = PRINT_C_LLONG; } else cflags = PRINT_C_LONG; break; case 'L': cflags = PRINT_C_LDOUBLE; ch = *format++; break; case 'j': cflags = PRINT_C_INTMAX; ch = *format++; break; case 't': cflags = PRINT_C_PTRDIFF; ch = *format++; break; case 'z': cflags = PRINT_C_SIZE; ch = *format++; break; } state = PRINT_S_CONV; break; case PRINT_S_CONV: switch (ch) { case 'd': /* FALLTHROUGH */ case 'i': switch (cflags) { case PRINT_C_CHAR: value = (signed char)va_arg(args, int); break; case PRINT_C_SHORT: value = (short int)va_arg(args, int); break; case PRINT_C_LONG: value = va_arg(args, long int); break; case PRINT_C_LLONG: value = va_arg(args, LLONG); break; case PRINT_C_SIZE: value = va_arg(args, SSIZE_T); break; case PRINT_C_INTMAX: value = va_arg(args, INTMAX_T); break; case PRINT_C_PTRDIFF: value = va_arg(args, PTRDIFF_T); break; default: value = va_arg(args, int); break; } fmtint(str, &len, size, value, 10, width, precision, flags); break; case 'X': flags |= PRINT_F_UP; /* FALLTHROUGH */ case 'x': base = 16; /* FALLTHROUGH */ case 'o': if (base == 0) base = 8; /* FALLTHROUGH */ case 'u': if (base == 0) base = 10; flags |= PRINT_F_UNSIGNED; switch (cflags) { case PRINT_C_CHAR: value = (unsigned char)va_arg(args, unsigned int); break; case PRINT_C_SHORT: value = (unsigned short int)va_arg(args, unsigned int); break; case PRINT_C_LONG: value = va_arg(args, unsigned long int); break; case PRINT_C_LLONG: value = va_arg(args, ULLONG); break; case PRINT_C_SIZE: value = va_arg(args, size_t); break; case PRINT_C_INTMAX: value = va_arg(args, UINTMAX_T); break; case PRINT_C_PTRDIFF: value = va_arg(args, UPTRDIFF_T); break; default: value = va_arg(args, unsigned int); break; } fmtint(str, &len, size, value, base, width, precision, flags); break; case 'A': /* Not yet supported, we'll use "%F". */ /* FALLTHROUGH */ case 'E': if (ch == 'E') flags |= PRINT_F_TYPE_E; /* FALLTHROUGH */ case 'G': if (ch == 'G') flags |= PRINT_F_TYPE_G; /* FALLTHROUGH */ case 'F': flags |= PRINT_F_UP; /* FALLTHROUGH */ case 'a': /* Not yet supported, we'll use "%f". */ /* FALLTHROUGH */ case 'e': if (ch == 'e') flags |= PRINT_F_TYPE_E; /* FALLTHROUGH */ case 'g': if (ch == 'g') flags |= PRINT_F_TYPE_G; /* FALLTHROUGH */ case 'f': if (cflags == PRINT_C_LDOUBLE) fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); fmtflt(str, &len, size, fvalue, width, precision, flags, &overflow); if (overflow) goto out; break; case 'c': cvalue = va_arg(args, int); OUTCHAR(str, len, size, cvalue); break; case 's': strvalue = va_arg(args, char *); fmtstr(str, &len, size, strvalue, width, precision, flags); break; case 'p': /* * C99 says: "The value of the pointer is * converted to a sequence of printing * characters, in an implementation-defined * manner." (C99: 7.19.6.1, 8) */ if ((strvalue = (char*)va_arg(args, void *)) == NULL) /* * We use the glibc format. BSD prints * "0x0", SysV "0". */ fmtstr(str, &len, size, "(nil)", width, -1, flags); else { /* * We use the BSD/glibc format. SysV * omits the "0x" prefix (which we emit * using the PRINT_F_NUM flag). */ flags |= PRINT_F_NUM; flags |= PRINT_F_UNSIGNED; fmtint(str, &len, size, (UINTPTR_T)strvalue, 16, width, precision, flags); } break; case 'n': switch (cflags) { case PRINT_C_CHAR: charptr = va_arg(args, signed char *); *charptr = len; break; case PRINT_C_SHORT: shortptr = va_arg(args, short int *); *shortptr = len; break; case PRINT_C_LONG: longptr = va_arg(args, long int *); *longptr = len; break; case PRINT_C_LLONG: llongptr = va_arg(args, LLONG *); *llongptr = len; break; case PRINT_C_SIZE: /* * C99 says that with the "z" length * modifier, "a following `n' conversion * specifier applies to a pointer to a * signed integer type corresponding to * size_t argument." (7.19.6.1, 7) */ sizeptr = va_arg(args, SSIZE_T *); *sizeptr = len; break; case PRINT_C_INTMAX: intmaxptr = va_arg(args, INTMAX_T *); *intmaxptr = len; break; case PRINT_C_PTRDIFF: ptrdiffptr = va_arg(args, PTRDIFF_T *); *ptrdiffptr = len; break; default: intptr = va_arg(args, int *); *intptr = len; break; } break; case '%': /* Print a "%" character verbatim. */ OUTCHAR(str, len, size, ch); break; default: /* Skip other characters. */ break; } ch = *format++; state = PRINT_S_DEFAULT; base = cflags = flags = width = 0; precision = -1; break; } out: if (len < size) str[len] = '\0'; else if (size > 0) str[size - 1] = '\0'; if (overflow || len > INT_MAX) { errno = EOVERFLOW; return -1; } return (int)len; } static void fmtstr(char *str, size_t *len, size_t size, const char *value, int width, int precision, int flags) { int padlen, strln; /* Amount to pad. */ int noprecision = (precision == -1); if (value == NULL) /* We're forgiving. */ value = "(null)"; /* If a precision was specified, don't read the string past it. */ for (strln = 0; value[strln] != '\0' && (noprecision || strln < precision); strln++) continue; if ((padlen = width - strln) < 0) padlen = 0; if (flags & PRINT_F_MINUS) /* Left justify. */ padlen = -padlen; while (padlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); padlen--; } while (*value != '\0' && (noprecision || precision-- > 0)) { OUTCHAR(str, *len, size, *value); value++; } while (padlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); padlen++; } } static void fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, int precision, int flags) { UINTMAX_T uvalue; char iconvert[MAX_CONVERT_LENGTH]; char sign = 0; char hexprefix = 0; int spadlen = 0; /* Amount to space pad. */ int zpadlen = 0; /* Amount to zero pad. */ int pos; int separators = (flags & PRINT_F_QUOTE); int noprecision = (precision == -1); if (flags & PRINT_F_UNSIGNED) uvalue = value; else { uvalue = (value >= 0) ? value : -value; if (value < 0) sign = '-'; else if (flags & PRINT_F_PLUS) /* Do a sign. */ sign = '+'; else if (flags & PRINT_F_SPACE) sign = ' '; } pos = convert(uvalue, iconvert, sizeof(iconvert), base, flags & PRINT_F_UP); if (flags & PRINT_F_NUM && uvalue != 0) { /* * C99 says: "The result is converted to an `alternative form'. * For `o' conversion, it increases the precision, if and only * if necessary, to force the first digit of the result to be a * zero (if the value and precision are both 0, a single 0 is * printed). For `x' (or `X') conversion, a nonzero result has * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) */ switch (base) { case 8: if (precision <= pos) precision = pos + 1; break; case 16: hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; break; } } if (separators) /* Get the number of group separators we'll print. */ separators = getnumsep(pos); zpadlen = precision - pos - separators; spadlen = width /* Minimum field width. */ - separators /* Number of separators. */ - MAX(precision, pos) /* Number of integer digits. */ - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; /* * C99 says: "If the `0' and `-' flags both appear, the `0' flag is * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) */ if (flags & PRINT_F_MINUS) /* Left justify. */ spadlen = -spadlen; else if (flags & PRINT_F_ZERO && noprecision) { zpadlen += spadlen; spadlen = 0; } while (spadlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); spadlen--; } if (sign != 0) /* Sign. */ OUTCHAR(str, *len, size, sign); if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ OUTCHAR(str, *len, size, '0'); OUTCHAR(str, *len, size, hexprefix); } while (zpadlen > 0) { /* Leading zeros. */ OUTCHAR(str, *len, size, '0'); zpadlen--; } while (pos > 0) { /* The actual digits. */ pos--; OUTCHAR(str, *len, size, iconvert[pos]); if (separators > 0 && pos > 0 && pos % 3 == 0) printsep(str, len, size); } while (spadlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); spadlen++; } } static void fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, int precision, int flags, int *overflow) { LDOUBLE ufvalue; UINTMAX_T intpart; UINTMAX_T fracpart; UINTMAX_T mask; const char *infnan = NULL; char iconvert[MAX_CONVERT_LENGTH]; char fconvert[MAX_CONVERT_LENGTH]; char econvert[5]; /* "e-300" (without nul-termination). */ char esign = 0; char sign = 0; int leadfraczeros = 0; int exponent = 0; int emitpoint = 0; int omitzeros = 0; int omitcount = 0; int padlen = 0; int epos = 0; int fpos = 0; int ipos = 0; int separators = (flags & PRINT_F_QUOTE); int estyle = (flags & PRINT_F_TYPE_E); #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT struct lconv *lc = localeconv(); #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ /* * AIX' man page says the default is 0, but C99 and at least Solaris' * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX * defaults to 6. */ if (precision == -1) precision = 6; if (fvalue < 0.0) sign = '-'; else if (flags & PRINT_F_PLUS) /* Do a sign. */ sign = '+'; else if (flags & PRINT_F_SPACE) sign = ' '; if (ISNAN(fvalue)) infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; else if (ISINF(fvalue)) infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; if (infnan != NULL) { if (sign != 0) iconvert[ipos++] = sign; while (*infnan != '\0') iconvert[ipos++] = *infnan++; fmtstr(str, len, size, iconvert, width, ipos, flags); return; } /* "%e" (or "%E") or "%g" (or "%G") conversion. */ if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { if (flags & PRINT_F_TYPE_G) { /* * If the precision is zero, it is treated as one (cf. * C99: 7.19.6.1, 8). */ if (precision == 0) precision = 1; /* * For "%g" (and "%G") conversions, the precision * specifies the number of significant digits, which * includes the digits in the integer part. The * conversion will or will not be using "e-style" (like * "%e" or "%E" conversions) depending on the precision * and on the exponent. However, the exponent can be * affected by rounding the converted value, so we'll * leave this decision for later. Until then, we'll * assume that we're going to do an "e-style" conversion * (in order to get the exponent calculated). For * "e-style", the precision must be decremented by one. */ precision--; /* * For "%g" (and "%G") conversions, trailing zeros are * removed from the fractional portion of the result * unless the "#" flag was specified. */ if (!(flags & PRINT_F_NUM)) omitzeros = 1; } exponent = getexponent(fvalue); estyle = 1; } again: /* * Sorry, we only support 9, 19, or 38 digits (that is, the number of * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value * minus one) past the decimal point due to our conversion method. */ switch (sizeof(UINTMAX_T)) { case 16: if (precision > 38) precision = 38; break; case 8: if (precision > 19) precision = 19; break; default: if (precision > 9) precision = 9; break; } ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; if (estyle) /* We want exactly one integer digit. */ ufvalue /= mypow10(exponent); if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { *overflow = 1; return; } /* * Factor of ten with the number of digits needed for the fractional * part. For example, if the precision is 3, the mask will be 1000. */ mask = mypow10(precision); /* * We "cheat" by converting the fractional part to integer by * multiplying by a factor of ten. */ if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { /* * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 * (because precision = 3). Now, myround(1000 * 0.99962) will * return 1000. So, the integer part must be incremented by one * and the fractional part must be set to zero. */ intpart++; fracpart = 0; if (estyle && intpart == 10) { /* * The value was rounded up to ten, but we only want one * integer digit if using "e-style". So, the integer * part must be set to one and the exponent must be * incremented by one. */ intpart = 1; exponent++; } } /* * Now that we know the real exponent, we can check whether or not to * use "e-style" for "%g" (and "%G") conversions. If we don't need * "e-style", the precision must be adjusted and the integer and * fractional parts must be recalculated from the original value. * * C99 says: "Let P equal the precision if nonzero, 6 if the precision * is omitted, or 1 if the precision is zero. Then, if a conversion * with style `E' would have an exponent of X: * * - if P > X >= -4, the conversion is with style `f' (or `F') and * precision P - (X + 1). * * - otherwise, the conversion is with style `e' (or `E') and precision * P - 1." (7.19.6.1, 8) * * Note that we had decremented the precision by one. */ if (flags & PRINT_F_TYPE_G && estyle && precision + 1 > exponent && exponent >= -4) { precision -= exponent; estyle = 0; goto again; } if (estyle) { if (exponent < 0) { exponent = -exponent; esign = '-'; } else esign = '+'; /* * Convert the exponent. The sizeof(econvert) is 5. So, the * econvert buffer can hold e.g. "e+999" and "e-999". We don't * support an exponent which contains more than three digits. * Therefore, the following stores are safe. */ epos = convert(exponent, econvert, 3, 10, 0); /* * C99 says: "The exponent always contains at least two digits, * and only as many more digits as necessary to represent the * exponent." (7.19.6.1, 8) */ if (epos == 1) econvert[epos++] = '0'; econvert[epos++] = esign; econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; } /* Convert the integer part and the fractional part. */ ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); leadfraczeros = precision - fpos; if (omitzeros) { if (fpos > 0) /* Omit trailing fractional part zeros. */ while (omitcount < fpos && fconvert[omitcount] == '0') omitcount++; else { /* The fractional part is zero, omit it completely. */ omitcount = precision; leadfraczeros = 0; } precision -= omitcount; } /* * Print a decimal point if either the fractional part is non-zero * and/or the "#" flag was specified. */ if (precision > 0 || flags & PRINT_F_NUM) emitpoint = 1; if (separators) /* Get the number of group separators we'll print. */ separators = getnumsep(ipos); padlen = width /* Minimum field width. */ - ipos /* Number of integer digits. */ - epos /* Number of exponent characters. */ - precision /* Number of fractional digits. */ - separators /* Number of group separators. */ - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ if (padlen < 0) padlen = 0; /* * C99 says: "If the `0' and `-' flags both appear, the `0' flag is * ignored." (7.19.6.1, 6) */ if (flags & PRINT_F_MINUS) /* Left justifty. */ padlen = -padlen; else if (flags & PRINT_F_ZERO && padlen > 0) { if (sign != 0) { /* Sign. */ OUTCHAR(str, *len, size, sign); sign = 0; } while (padlen > 0) { /* Leading zeros. */ OUTCHAR(str, *len, size, '0'); padlen--; } } while (padlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); padlen--; } if (sign != 0) /* Sign. */ OUTCHAR(str, *len, size, sign); while (ipos > 0) { /* Integer part. */ ipos--; OUTCHAR(str, *len, size, iconvert[ipos]); if (separators > 0 && ipos > 0 && ipos % 3 == 0) printsep(str, len, size); } if (emitpoint) { /* Decimal point. */ #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT if (lc->decimal_point != NULL && *lc->decimal_point != '\0') OUTCHAR(str, *len, size, *lc->decimal_point); else /* We'll always print some decimal point character. */ #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ OUTCHAR(str, *len, size, '.'); } while (leadfraczeros > 0) { /* Leading fractional part zeros. */ OUTCHAR(str, *len, size, '0'); leadfraczeros--; } while (fpos > omitcount) { /* The remaining fractional part. */ fpos--; OUTCHAR(str, *len, size, fconvert[fpos]); } while (epos > 0) { /* Exponent. */ epos--; OUTCHAR(str, *len, size, econvert[epos]); } while (padlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); padlen++; } } static void printsep(char *str, size_t *len, size_t size) { #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP struct lconv *lc = localeconv(); int i; if (lc->thousands_sep != NULL) for (i = 0; lc->thousands_sep[i] != '\0'; i++) OUTCHAR(str, *len, size, lc->thousands_sep[i]); else #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ OUTCHAR(str, *len, size, ','); } static int getnumsep(int digits) { int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP int strln; struct lconv *lc = localeconv(); /* We support an arbitrary separator length (including zero). */ if (lc->thousands_sep != NULL) { for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) continue; separators *= strln; } #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ return separators; } static int getexponent(LDOUBLE value) { LDOUBLE tmp = (value >= 0.0) ? value : -value; int exponent = 0; /* * We check for LDOUBLE_MAX_10_EXP >= exponent >= LDOUBLE_MIN_10_EXP in * order to work around possible endless loops which could happen (at * least) in the second loop (at least) if we're called with an infinite * value. However, we checked for infinity before calling this function * using our ISINF() macro, so this might be somewhat paranoid. */ while (tmp < 1.0 && tmp > 0.0 && --exponent >= LDOUBLE_MIN_10_EXP) tmp *= 10; while (tmp >= 10.0 && ++exponent <= LDOUBLE_MAX_10_EXP) tmp /= 10; return exponent; } static int convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) { const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; size_t pos = 0; /* We return an unterminated buffer with the digits in reverse order. */ do { buf[pos++] = digits[value % base]; value /= base; } while (value != 0 && pos < size); return (int)pos; } static UINTMAX_T cast(LDOUBLE value) { UINTMAX_T result; /* * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), * it may be increased to the nearest higher representable value for the * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE * value although converting the latter to UINTMAX_T would overflow. */ if (value >= UINTMAX_MAX) return UINTMAX_MAX; result = value; /* * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates * the standard). Sigh. */ return (result <= value) ? result : result - 1; } static UINTMAX_T myround(LDOUBLE value) { UINTMAX_T intpart = cast(value); return ((value -= intpart) < 0.5) ? intpart : intpart + 1; } static LDOUBLE mypow10(int exponent) { LDOUBLE result = 1; while (exponent > 0) { result *= 10; exponent--; } while (exponent < 0) { result /= 10; exponent++; } return result; } #endif /* !HAVE_VSNPRINTF */ #if !HAVE_VASPRINTF #if NEED_MYMEMCPY void * mymemcpy(void *dst, void *src, size_t len) { const char *from = (char*)src; char *to = (char*)dst; /* No need for optimization, we use this only to replace va_copy(3). */ while (len-- > 0) *to++ = *from++; return dst; } #endif /* NEED_MYMEMCPY */ int rpl_vasprintf(char **ret, const char *format, va_list ap) { size_t size; int len; va_list aq; VA_COPY(aq, ap); len = vsnprintf(NULL, 0, format, aq); VA_END_COPY(aq); if (len < 0 || (*ret = (char*)malloc(size = len + 1)) == NULL) return -1; return vsnprintf(*ret, size, format, ap); } #endif /* !HAVE_VASPRINTF */ #if !HAVE_SNPRINTF #if HAVE_STDARG_H int rpl_snprintf(char *str, size_t size, const char *format, ...) #else int rpl_snprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H char *str; size_t size; char *format; #endif /* HAVE_STDARG_H */ va_list ap; int len; VA_START(ap, format); VA_SHIFT(ap, str, char *); VA_SHIFT(ap, size, size_t); VA_SHIFT(ap, format, const char *); len = vsnprintf(str, size, format, ap); va_end(ap); return len; } #endif /* !HAVE_SNPRINTF */ #if !HAVE_ASPRINTF #if HAVE_STDARG_H int rpl_asprintf(char **ret, const char *format, ...) #else int rpl_asprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H char **ret; char *format; #endif /* HAVE_STDARG_H */ va_list ap; int len; VA_START(ap, format); VA_SHIFT(ap, ret, char **); VA_SHIFT(ap, format, const char *); len = vasprintf(ret, format, ap); va_end(ap); return len; } #endif /* !HAVE_ASPRINTF */ #else /* Dummy declaration to avoid empty translation unit warnings. */ int main(int argc, char **argv); #endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ #if TEST_SNPRINTF int main(void) { const char *float_fmt[] = { /* "%E" and "%e" formats. */ #if HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX "%.16e", "%22.16e", "%022.16e", "%-22.16e", "%#+'022.16e", #endif /* HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX */ "foo|%#+0123.9E|bar", "%-123.9e", "%123.9e", "%+23.9e", "%+05.8e", "%-05.8e", "%05.8e", "%+5.8e", "%-5.8e", "% 5.8e", "%5.8e", "%+4.9e", #if !OS_LINUX /* glibc sometimes gets these wrong. */ "%+#010.0e", "%#10.1e", "%10.5e", "% 10.5e", "%5.0e", "%5.e", "%#5.0e", "%#5.e", "%3.2e", "%3.1e", "%-1.5e", "%1.5e", "%01.3e", "%1.e", "%.1e", "%#.0e", "%+.0e", "% .0e", "%.0e", "%#.e", "%+.e", "% .e", "%.e", "%4e", "%e", "%E", #endif /* !OS_LINUX */ /* "%F" and "%f" formats. */ #if !OS_BSD && !OS_IRIX "% '022f", "%+'022f", "%-'22f", "%'22f", #if HAVE_LONG_LONG_INT "%.16f", "%22.16f", "%022.16f", "%-22.16f", "%#+'022.16f", #endif /* HAVE_LONG_LONG_INT */ #endif /* !OS_BSD && !OS_IRIX */ "foo|%#+0123.9F|bar", "%-123.9f", "%123.9f", "%+23.9f", "%+#010.0f", "%#10.1f", "%10.5f", "% 10.5f", "%+05.8f", "%-05.8f", "%05.8f", "%+5.8f", "%-5.8f", "% 5.8f", "%5.8f", "%5.0f", "%5.f", "%#5.0f", "%#5.f", "%+4.9f", "%3.2f", "%3.1f", "%-1.5f", "%1.5f", "%01.3f", "%1.f", "%.1f", "%#.0f", "%+.0f", "% .0f", "%.0f", "%#.f", "%+.f", "% .f", "%.f", "%4f", "%f", "%F", /* "%G" and "%g" formats. */ #if !OS_BSD && !OS_IRIX && !OS_LINUX "% '022g", "%+'022g", "%-'22g", "%'22g", #if HAVE_LONG_LONG_INT "%.16g", "%22.16g", "%022.16g", "%-22.16g", "%#+'022.16g", #endif /* HAVE_LONG_LONG_INT */ #endif /* !OS_BSD && !OS_IRIX && !OS_LINUX */ "foo|%#+0123.9G|bar", "%-123.9g", "%123.9g", "%+23.9g", "%+05.8g", "%-05.8g", "%05.8g", "%+5.8g", "%-5.8g", "% 5.8g", "%5.8g", "%+4.9g", #if !OS_LINUX /* glibc sometimes gets these wrong. */ "%+#010.0g", "%#10.1g", "%10.5g", "% 10.5g", "%5.0g", "%5.g", "%#5.0g", "%#5.g", "%3.2g", "%3.1g", "%-1.5g", "%1.5g", "%01.3g", "%1.g", "%.1g", "%#.0g", "%+.0g", "% .0g", "%.0g", "%#.g", "%+.g", "% .g", "%.g", "%4g", "%g", "%G", #endif /* !OS_LINUX */ NULL }; double float_val[] = { -4.136, -134.52, -5.04030201, -3410.01234, -999999.999999, -913450.29876, -913450.2, -91345.2, -9134.2, -913.2, -91.2, -9.2, -9.9, 4.136, 134.52, 5.04030201, 3410.01234, 999999.999999, 913450.29876, 913450.2, 91345.2, 9134.2, 913.2, 91.2, 9.2, 9.9, 9.96, 9.996, 9.9996, 9.99996, 9.999996, 9.9999996, 9.99999996, 0.99999996, 0.99999999, 0.09999999, 0.00999999, 0.00099999, 0.00009999, 0.00000999, 0.00000099, 0.00000009, 0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0, 1.5, -1.5, -1.0, -0.1, #if !OS_BSD /* BSD sometimes gets these wrong. */ #ifdef INFINITY INFINITY, -INFINITY, #endif /* defined(INFINITY) */ #ifdef NAN NAN, #endif /* defined(NAN) */ #endif /* !OS_BSD */ 0 }; const char *long_fmt[] = { "foo|%0123ld|bar", #if !OS_IRIX "% '0123ld", "%+'0123ld", "%-'123ld", "%'123ld", #endif /* !OS_IRiX */ "%123.9ld", "% 123.9ld", "%+123.9ld", "%-123.9ld", "%0123ld", "% 0123ld", "%+0123ld", "%-0123ld", "%10.5ld", "% 10.5ld", "%+10.5ld", "%-10.5ld", "%010ld", "% 010ld", "%+010ld", "%-010ld", "%4.2ld", "% 4.2ld", "%+4.2ld", "%-4.2ld", "%04ld", "% 04ld", "%+04ld", "%-04ld", "%5.5ld", "%+22.33ld", "%01.3ld", "%1.5ld", "%-1.5ld", "%44ld", "%4ld", "%4.0ld", "%4.ld", "%.44ld", "%.4ld", "%.0ld", "%.ld", "%ld", NULL }; long int long_val[] = { #ifdef LONG_MAX LONG_MAX, #endif /* LONG_MAX */ #ifdef LONG_MIN LONG_MIN, #endif /* LONG_MIN */ -91340, 91340, 341, 134, 0203, -1, 1, 0 }; const char *ulong_fmt[] = { /* "%u" formats. */ "foo|%0123lu|bar", #if !OS_IRIX "% '0123lu", "%+'0123lu", "%-'123lu", "%'123lu", #endif /* !OS_IRiX */ "%123.9lu", "% 123.9lu", "%+123.9lu", "%-123.9lu", "%0123lu", "% 0123lu", "%+0123lu", "%-0123lu", "%5.5lu", "%+22.33lu", "%01.3lu", "%1.5lu", "%-1.5lu", "%44lu", "%lu", /* "%o" formats. */ "foo|%#0123lo|bar", "%#123.9lo", "%# 123.9lo", "%#+123.9lo", "%#-123.9lo", "%#0123lo", "%# 0123lo", "%#+0123lo", "%#-0123lo", "%#5.5lo", "%#+22.33lo", "%#01.3lo", "%#1.5lo", "%#-1.5lo", "%#44lo", "%#lo", "%123.9lo", "% 123.9lo", "%+123.9lo", "%-123.9lo", "%0123lo", "% 0123lo", "%+0123lo", "%-0123lo", "%5.5lo", "%+22.33lo", "%01.3lo", "%1.5lo", "%-1.5lo", "%44lo", "%lo", /* "%X" and "%x" formats. */ "foo|%#0123lX|bar", "%#123.9lx", "%# 123.9lx", "%#+123.9lx", "%#-123.9lx", "%#0123lx", "%# 0123lx", "%#+0123lx", "%#-0123lx", "%#5.5lx", "%#+22.33lx", "%#01.3lx", "%#1.5lx", "%#-1.5lx", "%#44lx", "%#lx", "%#lX", "%123.9lx", "% 123.9lx", "%+123.9lx", "%-123.9lx", "%0123lx", "% 0123lx", "%+0123lx", "%-0123lx", "%5.5lx", "%+22.33lx", "%01.3lx", "%1.5lx", "%-1.5lx", "%44lx", "%lx", "%lX", NULL }; unsigned long int ulong_val[] = { #ifdef ULONG_MAX ULONG_MAX, #endif /* ULONG_MAX */ 91340, 341, 134, 0203, 1, 0 }; const char *llong_fmt[] = { "foo|%0123lld|bar", "%123.9lld", "% 123.9lld", "%+123.9lld", "%-123.9lld", "%0123lld", "% 0123lld", "%+0123lld", "%-0123lld", "%5.5lld", "%+22.33lld", "%01.3lld", "%1.5lld", "%-1.5lld", "%44lld", "%lld", NULL }; LLONG llong_val[] = { #ifdef LLONG_MAX LLONG_MAX, #endif /* LLONG_MAX */ #ifdef LLONG_MIN LLONG_MIN, #endif /* LLONG_MIN */ -91340, 91340, 341, 134, 0203, -1, 1, 0 }; const char *string_fmt[] = { "foo|%10.10s|bar", "%-10.10s", "%10.10s", "%10.5s", "%5.10s", "%10.1s", "%1.10s", "%10.0s", "%0.10s", "%-42.5s", "%2.s", "%.10s", "%.1s", "%.0s", "%.s", "%4s", "%s", NULL }; const char *string_val[] = { "Hello", "Hello, world!", "Sound check: One, two, three.", "This string is a little longer than the other strings.", "1", "", NULL }; #if !OS_SYSV /* SysV uses a different format than we do. */ const char *pointer_fmt[] = { "foo|%p|bar", "%42p", "%p", NULL }; const char *pointer_val[] = { *pointer_fmt, *string_fmt, *string_val, NULL }; #endif /* !OS_SYSV */ char buf1[1024], buf2[1024]; double value, digits = 9.123456789012345678901234567890123456789; int i, j, r1, r2, failed = 0, num = 0; /* * Use -DTEST_NILS in order to also test the conversion of nil values. Might * segfault on systems which don't support converting a NULL pointer with "%s" * and lets some test cases fail against BSD and glibc due to bugs in their * implementations. */ #ifndef TEST_NILS #define TEST_NILS 0 #elif TEST_NILS #undef TEST_NILS #define TEST_NILS 1 #endif /* !defined(TEST_NILS) */ #ifdef TEST #undef TEST #endif /* defined(TEST) */ #define TEST(fmt, val) \ do { \ for (i = 0; fmt[i] != NULL; i++) \ for (j = 0; j == 0 || val[j - TEST_NILS] != 0; j++) { \ r1 = sprintf(buf1, fmt[i], val[j]); \ r2 = snprintf(buf2, sizeof(buf2), fmt[i], val[j]); \ if (strcmp(buf1, buf2) != 0 || r1 != r2) { \ (void)printf("Results don't match, " \ "format string: %s\n" \ "\t sprintf(3): [%s] (%d)\n" \ "\tsnprintf(3): [%s] (%d)\n", \ fmt[i], buf1, r1, buf2, r2); \ failed++; \ } \ num++; \ } \ } while (/* CONSTCOND */ 0) #if HAVE_LOCALE_H (void)setlocale(LC_ALL, ""); #endif /* HAVE_LOCALE_H */ (void)puts("Testing our snprintf(3) against your system's sprintf(3)."); TEST(float_fmt, float_val); TEST(long_fmt, long_val); TEST(ulong_fmt, ulong_val); TEST(llong_fmt, llong_val); TEST(string_fmt, string_val); #if !OS_SYSV /* SysV uses a different format than we do. */ TEST(pointer_fmt, pointer_val); #endif /* !OS_SYSV */ (void)printf("Result: %d out of %d tests failed.\n", failed, num); (void)fputs("Checking how many digits we support: ", stdout); for (i = 0; i < 100; i++) { value = pow(10, i) * digits; (void)sprintf(buf1, "%.1f", value); (void)snprintf(buf2, sizeof(buf2), "%.1f", value); if (strcmp(buf1, buf2) != 0) { (void)printf("apparently %d.\n", i); break; } } return (failed == 0) ? 0 : 1; } #endif /* TEST_SNPRINTF */ #endif // KONAN_INTERNAL_SNPRINTF /* vim: set joinspaces noexpandtab textwidth=80 cinoptions=(4,u0: */ ================================================ FILE: runtime/src/main/cpp/utf8/checked.h ================================================ // Copyright 2006 Nemanja Trifunovic /* Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #include "core.h" #include namespace utf8 { // Base for the exceptions that may be thrown from the library class exception : public ::std::exception { }; // Exceptions that may be thrown from the library functions. class invalid_code_point : public exception { uint32_t cp; public: invalid_code_point(uint32_t cp) : cp(cp) {} virtual const char* what() const throw() { return "Invalid code point"; } uint32_t code_point() const {return cp;} }; class invalid_utf8 : public exception { uint8_t u8; public: invalid_utf8 (uint8_t u) : u8(u) {} virtual const char* what() const throw() { return "Invalid UTF-8"; } uint8_t utf8_octet() const {return u8;} }; class invalid_utf16 : public exception { uint16_t u16; public: invalid_utf16 (uint16_t u) : u16(u) {} virtual const char* what() const throw() { return "Invalid UTF-16"; } uint16_t utf16_word() const {return u16;} }; class not_enough_room : public exception { public: virtual const char* what() const throw() { return "Not enough space"; } }; /// The library API - functions intended to be called by the users template octet_iterator append(uint32_t cp, octet_iterator result) { if (!utf8::internal::is_code_point_valid(cp)) throw invalid_code_point(cp); if (cp < 0x80) // one octet *(result++) = static_cast(cp); else if (cp < 0x800) { // two octets *(result++) = static_cast((cp >> 6) | 0xc0); *(result++) = static_cast((cp & 0x3f) | 0x80); } else if (cp < 0x10000) { // three octets *(result++) = static_cast((cp >> 12) | 0xe0); *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); *(result++) = static_cast((cp & 0x3f) | 0x80); } else { // four octets *(result++) = static_cast((cp >> 18) | 0xf0); *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); *(result++) = static_cast((cp & 0x3f) | 0x80); } return result; } template output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) { while (start != end) { octet_iterator sequence_start = start; internal::utf_error err_code = utf8::internal::validate_next(start, end); switch (err_code) { case internal::UTF8_OK : for (octet_iterator it = sequence_start; it != start; ++it) *out++ = *it; break; case internal::NOT_ENOUGH_ROOM: throw not_enough_room(); case internal::INVALID_LEAD: out = utf8::append (replacement, out); ++start; break; case internal::INCOMPLETE_SEQUENCE: case internal::OVERLONG_SEQUENCE: case internal::INVALID_CODE_POINT: out = utf8::append (replacement, out); ++start; // just one replacement mark for the sequence while (start != end && utf8::internal::is_trail(*start)) ++start; break; } } return out; } template inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) { static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); return utf8::replace_invalid(start, end, out, replacement_marker); } template uint32_t next(octet_iterator& it, octet_iterator end) { uint32_t cp = 0; internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); switch (err_code) { case internal::UTF8_OK : break; case internal::NOT_ENOUGH_ROOM : throw not_enough_room(); case internal::INVALID_LEAD : case internal::INCOMPLETE_SEQUENCE : case internal::OVERLONG_SEQUENCE : throw invalid_utf8(*it); case internal::INVALID_CODE_POINT : throw invalid_code_point(cp); } return cp; } template uint32_t peek_next(octet_iterator it, octet_iterator end) { return utf8::next(it, end); } template uint32_t prior(octet_iterator& it, octet_iterator start) { // can't do much if it == start if (it == start) throw not_enough_room(); octet_iterator end = it; // Go back until we hit either a lead octet or start while (utf8::internal::is_trail(*(--it))) if (it == start) throw invalid_utf8(*it); // error - no lead byte in the sequence return utf8::peek_next(it, end); } /// Deprecated in versions that include "prior" template uint32_t previous(octet_iterator& it, octet_iterator pass_start) { octet_iterator end = it; while (utf8::internal::is_trail(*(--it))) if (it == pass_start) throw invalid_utf8(*it); // error - no lead byte in the sequence octet_iterator temp = it; return utf8::next(temp, end); } template void advance (octet_iterator& it, distance_type n, octet_iterator end) { for (distance_type i = 0; i < n; ++i) utf8::next(it, end); } /** * Calculates a count of characters needed to represent the string from first to last in UTF-16 * taking into account surrogate symbols. Throws an exception if the input is invalid. */ template uint32_t utf16_length(octet_iterator first, octet_iterator last) { uint32_t dist = 0; while(first < last) { uint32_t cp = utf8::next(first, last); dist += (cp > 0xffff) ? 2 : 1; } return dist; } template typename std::iterator_traits::difference_type distance (octet_iterator first, octet_iterator last) { typename std::iterator_traits::difference_type dist; for (dist = 0; first < last; ++dist) utf8::next(first, last); return dist; } template octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) { while (start != end) { uint32_t cp = utf8::internal::mask16(*start++); // Take care of surrogate pairs first if (utf8::internal::is_lead_surrogate(cp)) { if (start != end) { uint32_t trail_surrogate = utf8::internal::mask16(*start++); if (utf8::internal::is_trail_surrogate(trail_surrogate)) cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; else throw invalid_utf16(static_cast(trail_surrogate)); } else throw invalid_utf16(static_cast(cp)); } // Lone trail surrogate else if (utf8::internal::is_trail_surrogate(cp)) throw invalid_utf16(static_cast(cp)); result = utf8::append(cp, result); } return result; } template u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) { while (start != end) { uint32_t cp = utf8::next(start, end); if (cp > 0xffff) { //make a surrogate pair *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); } else *result++ = static_cast(cp); } return result; } template octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) { while (start != end) result = utf8::append(*(start++), result); return result; } template u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) { while (start != end) (*result++) = utf8::next(start, end); return result; } // The iterator class template class iterator : public std::iterator { octet_iterator it; octet_iterator range_start; octet_iterator range_end; public: iterator () {} explicit iterator (const octet_iterator& octet_it, const octet_iterator& range_start, const octet_iterator& range_end) : it(octet_it), range_start(range_start), range_end(range_end) { if (it < range_start || it > range_end) throw std::out_of_range("Invalid utf-8 iterator position"); } // the default "big three" are OK octet_iterator base () const { return it; } uint32_t operator * () const { octet_iterator temp = it; return utf8::next(temp, range_end); } bool operator == (const iterator& rhs) const { if (range_start != rhs.range_start || range_end != rhs.range_end) throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); return (it == rhs.it); } bool operator != (const iterator& rhs) const { return !(operator == (rhs)); } iterator& operator ++ () { utf8::next(it, range_end); return *this; } iterator operator ++ (int) { iterator temp = *this; utf8::next(it, range_end); return temp; } iterator& operator -- () { utf8::prior(it, range_start); return *this; } iterator operator -- (int) { iterator temp = *this; utf8::prior(it, range_start); return temp; } }; // class iterator } // namespace utf8 #endif //header guard ================================================ FILE: runtime/src/main/cpp/utf8/core.h ================================================ // Copyright 2006 Nemanja Trifunovic /* Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #include namespace utf8 { // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers // You may need to change them to match your system. // These typedefs have the same names as ones from cstdint, or boost/cstdint typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; // Helper code - not intended to be directly called by the library users. May be changed at any time namespace internal { // Unicode constants // Leading (high) surrogates: 0xd800 - 0xdbff // Trailing (low) surrogates: 0xdc00 - 0xdfff const uint16_t LEAD_SURROGATE_MIN = 0xd800u; const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; // Maximum valid value for a Unicode code point const uint32_t CODE_POINT_MAX = 0x0010ffffu; template inline uint8_t mask8(octet_type oc) { return static_cast(0xff & oc); } template inline uint16_t mask16(u16_type oc) { return static_cast(0xffff & oc); } template inline bool is_trail(octet_type oc) { return ((utf8::internal::mask8(oc) >> 6) == 0x2); } template inline bool is_lead_surrogate(u16 cp) { return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); } template inline bool is_trail_surrogate(u16 cp) { return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); } template inline bool is_surrogate(u16 cp) { return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); } template inline bool is_out_of_unicode_domain(u32 cp) { return cp > CODE_POINT_MAX; } template inline bool is_code_point_valid(u32 cp) { return (!utf8::internal::is_out_of_unicode_domain(cp) && !utf8::internal::is_surrogate(cp)); } template inline typename std::iterator_traits::difference_type sequence_length(octet_iterator lead_it) { uint8_t lead = utf8::internal::mask8(*lead_it); if (lead < 0x80) return 1; else if ((lead >> 5) == 0x6) return 2; else if ((lead >> 4) == 0xe) return 3; else if ((lead >> 3) == 0x1e) return 4; else return 0; } template inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) { if (cp < 0x80) { if (length != 1) return true; } else if (cp < 0x800) { if (length != 2) return true; } else if (cp < 0x10000) { if (length != 3) return true; } return false; } enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; /// Helper for get_sequence_x template utf_error increase_safely(octet_iterator& it, octet_iterator end) { if (++it == end) return NOT_ENOUGH_ROOM; if (!utf8::internal::is_trail(*it)) return INCOMPLETE_SEQUENCE; return UTF8_OK; } #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} #define UTF8_CPP_RETURN_ON_OVERLONG_SEQUENCE(CP, LENGTH) {if (utf8::internal::is_overlong_sequence(CP, LENGTH)) return OVERLONG_SEQUENCE;} /// get_sequence_x functions decode utf-8 sequences of the length x template utf_error get_sequence_1(octet_iterator& it, const octet_iterator end, uint32_t& code_point) { if (it == end) return NOT_ENOUGH_ROOM; code_point = utf8::internal::mask8(*it); return UTF8_OK; } template utf_error get_sequence_2(octet_iterator& it, const octet_iterator end, uint32_t& code_point) { if (it == end) return NOT_ENOUGH_ROOM; code_point = utf8::internal::mask8(*it); UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); UTF8_CPP_RETURN_ON_OVERLONG_SEQUENCE(code_point, 2) return UTF8_OK; } template utf_error get_sequence_3(octet_iterator& it, const octet_iterator end, uint32_t& code_point) { if (it == end) return NOT_ENOUGH_ROOM; code_point = utf8::internal::mask8(*it); UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); if (utf8::internal::is_surrogate(code_point)) return INVALID_CODE_POINT; UTF8_CPP_RETURN_ON_OVERLONG_SEQUENCE(code_point, 3) UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point += (*it) & 0x3f; return UTF8_OK; } template utf_error get_sequence_4(octet_iterator& it, const octet_iterator end, uint32_t& code_point) { if (it == end) return NOT_ENOUGH_ROOM; code_point = utf8::internal::mask8(*it); UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); if (utf8::internal::is_out_of_unicode_domain(code_point)) return INVALID_CODE_POINT; UTF8_CPP_RETURN_ON_OVERLONG_SEQUENCE(code_point, 4) UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) code_point += (*it) & 0x3f; return UTF8_OK; } #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR template utf_error validate_next(octet_iterator& it, const octet_iterator end, uint32_t& code_point) { // Save the original value of it so we can go back in case of failure // Of course, it does not make much sense with i.e. stream iterators octet_iterator original_it = it; uint32_t cp = 0; // Determine the sequence length based on the lead octet typedef typename std::iterator_traits::difference_type octet_difference_type; const octet_difference_type length = utf8::internal::sequence_length(it); // Get trail octets and calculate the code point utf_error err = UTF8_OK; switch (length) { case 0: return INVALID_LEAD; case 1: err = utf8::internal::get_sequence_1(it, end, cp); break; case 2: err = utf8::internal::get_sequence_2(it, end, cp); break; case 3: err = utf8::internal::get_sequence_3(it, end, cp); break; case 4: err = utf8::internal::get_sequence_4(it, end, cp); break; } if (err == UTF8_OK) { // Decoding succeeded. code_point = cp; ++it; } else { // Failure branch - restore the original value of the iterator it = original_it; } return err; } template inline utf_error validate_next(octet_iterator& it, octet_iterator end) { uint32_t ignored; return utf8::internal::validate_next(it, end, ignored); } } // namespace internal /// The library API - functions intended to be called by the users // Byte order mark const uint8_t bom[] = {0xef, 0xbb, 0xbf}; template octet_iterator find_invalid(octet_iterator start, octet_iterator end) { octet_iterator result = start; while (result != end) { utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); if (err_code != internal::UTF8_OK) return result; } return result; } template inline bool is_valid(octet_iterator start, octet_iterator end) { return (utf8::find_invalid(start, end) == end); } template inline bool starts_with_bom (octet_iterator it, octet_iterator end) { return ( ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) ); } //Deprecated in release 2.3 template inline bool is_bom (octet_iterator it) { return ( (utf8::internal::mask8(*it++)) == bom[0] && (utf8::internal::mask8(*it++)) == bom[1] && (utf8::internal::mask8(*it)) == bom[2] ); } } // namespace utf8 #endif // header guard ================================================ FILE: runtime/src/main/cpp/utf8/unchecked.h ================================================ // Copyright 2006 Nemanja Trifunovic /* Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 #include "core.h" namespace utf8 { namespace unchecked { template octet_iterator append(uint32_t cp, octet_iterator result) { if (cp < 0x80) // one octet *(result++) = static_cast(cp); else if (cp < 0x800) { // two octets *(result++) = static_cast((cp >> 6) | 0xc0); *(result++) = static_cast((cp & 0x3f) | 0x80); } else if (cp < 0x10000) { // three octets *(result++) = static_cast((cp >> 12) | 0xe0); *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); *(result++) = static_cast((cp & 0x3f) | 0x80); } else { // four octets *(result++) = static_cast((cp >> 18) | 0xf0); *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); *(result++) = static_cast((cp & 0x3f) | 0x80); } return result; } template uint32_t next(octet_iterator& it) { uint32_t cp = utf8::internal::mask8(*it); typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); switch (length) { case 1: break; case 2: it++; cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); break; case 3: ++it; cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); ++it; cp += (*it) & 0x3f; break; case 4: ++it; cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); ++it; cp += (utf8::internal::mask8(*it) << 6) & 0xfff; ++it; cp += (*it) & 0x3f; break; } ++it; return cp; } template uint32_t peek_next(octet_iterator it) { return utf8::unchecked::next(it); } template uint32_t prior(octet_iterator& it) { while (utf8::internal::is_trail(*(--it))) ; octet_iterator temp = it; return utf8::unchecked::next(temp); } // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) template inline uint32_t previous(octet_iterator& it) { return utf8::unchecked::prior(it); } template void advance (octet_iterator& it, distance_type n) { for (distance_type i = 0; i < n; ++i) utf8::unchecked::next(it); } /** * Calculates a count of characters needed to represent the string from first to last in UTF-16 * taking into account surrogate symbols. Doesn't validate the input. */ template uint32_t utf16_length(octet_iterator first, const octet_iterator last) { uint32_t dist = 0; while (first < last) { uint32_t cp = utf8::unchecked::next(first); dist += (cp > 0xffff) ? 2 : 1; } return dist; } template typename std::iterator_traits::difference_type distance (octet_iterator first, octet_iterator last) { typename std::iterator_traits::difference_type dist; for (dist = 0; first < last; ++dist) utf8::unchecked::next(first); return dist; } template octet_iterator utf16to8 (u16bit_iterator start, const u16bit_iterator end, octet_iterator result) { while (start != end) { uint32_t cp = utf8::internal::mask16(*start++); // Take care of surrogate pairs first if (utf8::internal::is_lead_surrogate(cp)) { uint32_t trail_surrogate = utf8::internal::mask16(*start++); cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; } result = utf8::unchecked::append(cp, result); } return result; } template u16bit_iterator utf8to16 (octet_iterator start, const octet_iterator end, u16bit_iterator result) { while (start < end) { uint32_t cp = utf8::unchecked::next(start); if (cp > 0xffff) { //make a surrogate pair *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); } else *result++ = static_cast(cp); } return result; } template octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) { while (start != end) result = utf8::unchecked::append(*(start++), result); return result; } template u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) { while (start < end) (*result++) = utf8::unchecked::next(start); return result; } // The iterator class template class iterator : public std::iterator { octet_iterator it; public: iterator () {} explicit iterator (const octet_iterator& octet_it): it(octet_it) {} // the default "big three" are OK octet_iterator base () const { return it; } uint32_t operator * () const { octet_iterator temp = it; return utf8::unchecked::next(temp); } bool operator == (const iterator& rhs) const { return (it == rhs.it); } bool operator != (const iterator& rhs) const { return !(operator == (rhs)); } iterator& operator ++ () { ::std::advance(it, utf8::internal::sequence_length(it)); return *this; } iterator operator ++ (int) { iterator temp = *this; ::std::advance(it, utf8::internal::sequence_length(it)); return temp; } iterator& operator -- () { utf8::unchecked::prior(it); return *this; } iterator operator -- (int) { iterator temp = *this; utf8::unchecked::prior(it); return temp; } }; // class iterator } // namespace utf8::unchecked } // namespace utf8 #endif // header guard ================================================ FILE: runtime/src/main/cpp/utf8/with_replacement.h ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef UTF_FOR_CPP_WITH_REPLACEMENT_H #define UTF_FOR_CPP_WITH_REPLACEMENT_H #include "core.h" #include "unchecked.h" namespace utf8 { namespace with_replacement { constexpr uint32_t default_replacement = 0xfffd; /* * Returns the next codepoint replacing any invalid sequence with the replacement codepoint. */ template uint32_t next(octet_iterator &it, const octet_iterator end, uint32_t replacement) { uint32_t cp = 0; internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); switch (err_code) { case internal::UTF8_OK : return cp; case internal::INVALID_LEAD : case internal::INVALID_CODE_POINT : case internal::OVERLONG_SEQUENCE : it++; return replacement; case internal::NOT_ENOUGH_ROOM : case internal::INCOMPLETE_SEQUENCE : // The whole incomplete sequence is replaced with one replacement codepoint. for (it++; it < end && utf8::internal::is_trail(*it); it++); return replacement; } } // Library API /** * Calculates a count of characters needed to represent the string from first to last in UTF-16 * taking into account surrogate symbols and invalid sequences. * Assumes that all invalid sequences in the input will be replaced with `replacement` * so each invalid sequence increases the result by 1 or 2 depending on `replacement`. */ template uint32_t utf16_length(octet_iterator first, const octet_iterator last, const uint32_t replacement = default_replacement) { uint32_t dist = 0; while (first < last) { uint32_t cp = next(first, last, replacement); dist += (cp > 0xffff) ? 2 : 1; } return dist; } template typename std::iterator_traits::difference_type distance(octet_iterator first, const octet_iterator last) { typename std::iterator_traits::difference_type dist; uint32_t unused = 0; for (dist = 0; first < last; dist++) { next(first, last, unused); } return dist; } template octet_iterator utf16to8(u16bit_iterator start, const u16bit_iterator end, octet_iterator result, const uint32_t replacement) { while (start != end) { uint32_t cp = utf8::internal::mask16(*start++); // Process surrogates. if (utf8::internal::is_lead_surrogate(cp)) { if (start != end) { uint32_t trail_surrogate = utf8::internal::mask16(*start); if (utf8::internal::is_trail_surrogate(trail_surrogate)) { // Valid surrogate pair. cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; start++; } else { cp = replacement; // Invalid input: lone lead surrogate. } } else { cp = replacement; // Invalid input: lone lead surrogate at the end of input. } } else if (utf8::internal::is_trail_surrogate(cp)) { cp = replacement; // Invalid input: lone trail surrogate } result = utf8::unchecked::append(cp, result); } return result; } template inline octet_iterator utf16to8(u16bit_iterator start, const u16bit_iterator end, octet_iterator result) { return utf16to8(start, end, result, default_replacement); } template u16bit_iterator utf8to16(octet_iterator start, const octet_iterator end, u16bit_iterator result, const uint32_t replacement) { while (start != end) { // The `next` method takes care about replacing invalid sequences. uint32_t cp = next(start, end, replacement); if (cp > 0xffff) { //make a surrogate pair *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); } else *result++ = static_cast(cp); } return result; } template inline u16bit_iterator utf8to16(octet_iterator start, const octet_iterator end, u16bit_iterator result) { return utf8to16(start, end, result, default_replacement); } } // namespace with_replacement } // namespace utf8 #endif // UTF_FOR_CPP_WITH_REPLACEMENT_H ================================================ FILE: runtime/src/main/cpp/utf8.h ================================================ // Copyright 2006 Nemanja Trifunovic /* Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 #include "utf8/unchecked.h" #include "utf8/with_replacement.h" #if !KONAN_NO_EXCEPTIONS #include "utf8/checked.h" #endif #endif // header guard ================================================ FILE: runtime/src/main/js/math.js ================================================ // NOTE: THIS FILE IS AUTO-GENERATED! // Run ':runtime:generateJsMath' to re-generate it. konan.libraries.push ({ knjs_get__Math_E: function() { var result = Math.E; return doubleToReturnSlot(result); }, knjs_get__Math_LN2: function() { var result = Math.LN2; return doubleToReturnSlot(result); }, knjs_get__Math_LN10: function() { var result = Math.LN10; return doubleToReturnSlot(result); }, knjs_get__Math_LOG2E: function() { var result = Math.LOG2E; return doubleToReturnSlot(result); }, knjs_get__Math_LOG10E: function() { var result = Math.LOG10E; return doubleToReturnSlot(result); }, knjs_get__Math_PI: function() { var result = Math.PI; return doubleToReturnSlot(result); }, knjs_get__Math_SQRT1_2: function() { var result = Math.SQRT1_2; return doubleToReturnSlot(result); }, knjs_get__Math_SQRT2: function() { var result = Math.SQRT2; return doubleToReturnSlot(result); }, knjs__Math_abs: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.abs(x); return doubleToReturnSlot(result); }, knjs__Math_acos: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.acos(x); return doubleToReturnSlot(result); }, knjs__Math_acosh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.acosh(x); return doubleToReturnSlot(result); }, knjs__Math_asin: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.asin(x); return doubleToReturnSlot(result); }, knjs__Math_asinh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.asinh(x); return doubleToReturnSlot(result); }, knjs__Math_atan: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.atan(x); return doubleToReturnSlot(result); }, knjs__Math_atanh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.atanh(x); return doubleToReturnSlot(result); }, knjs__Math_atan2: function(yUpper, yLower, xUpper, xLower) { var y = twoIntsToDouble(yUpper, yLower); var x = twoIntsToDouble(xUpper, xLower); var result = Math.atan2(y, x); return doubleToReturnSlot(result); }, knjs__Math_cbrt: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.cbrt(x); return doubleToReturnSlot(result); }, knjs__Math_ceil: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.ceil(x); return doubleToReturnSlot(result); }, knjs__Math_clz32: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.clz32(x); return doubleToReturnSlot(result); }, knjs__Math_cos: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.cos(x); return doubleToReturnSlot(result); }, knjs__Math_cosh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.cosh(x); return doubleToReturnSlot(result); }, knjs__Math_exp: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.exp(x); return doubleToReturnSlot(result); }, knjs__Math_expm1: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.expm1(x); return doubleToReturnSlot(result); }, knjs__Math_floor: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.floor(x); return doubleToReturnSlot(result); }, knjs__Math_fround: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.fround(x); return doubleToReturnSlot(result); }, knjs__Math_log: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.log(x); return doubleToReturnSlot(result); }, knjs__Math_log1p: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.log1p(x); return doubleToReturnSlot(result); }, knjs__Math_log10: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.log10(x); return doubleToReturnSlot(result); }, knjs__Math_log2: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.log2(x); return doubleToReturnSlot(result); }, knjs__Math_pow: function(xUpper, xLower, yUpper, yLower) { var x = twoIntsToDouble(xUpper, xLower); var y = twoIntsToDouble(yUpper, yLower); var result = Math.pow(x, y); return doubleToReturnSlot(result); }, knjs__Math_random: function() { var result = Math.random(); return doubleToReturnSlot(result); }, knjs__Math_round: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.round(x); return doubleToReturnSlot(result); }, knjs__Math_sign: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.sign(x); return doubleToReturnSlot(result); }, knjs__Math_sin: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.sin(x); return doubleToReturnSlot(result); }, knjs__Math_sinh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.sinh(x); return doubleToReturnSlot(result); }, knjs__Math_sqrt: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.sqrt(x); return doubleToReturnSlot(result); }, knjs__Math_tan: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.tan(x); return doubleToReturnSlot(result); }, knjs__Math_tanh: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.tanh(x); return doubleToReturnSlot(result); }, knjs__Math_trunc: function(xUpper, xLower) { var x = twoIntsToDouble(xUpper, xLower); var result = Math.trunc(x); return doubleToReturnSlot(result); }, knjs__Math_hypot: function(xUpper, xLower, yUpper, yLower) { var x = twoIntsToDouble(xUpper, xLower); var y = twoIntsToDouble(yUpper, yLower); var result = Math.hypot(x, y); return doubleToReturnSlot(result); }, knjs__Math_max: function(xUpper, xLower, yUpper, yLower) { var x = twoIntsToDouble(xUpper, xLower); var y = twoIntsToDouble(yUpper, yLower); var result = Math.max(x, y); return doubleToReturnSlot(result); }, knjs__Math_min: function(xUpper, xLower, yUpper, yLower) { var x = twoIntsToDouble(xUpper, xLower); var y = twoIntsToDouble(yUpper, yLower); var result = Math.min(x, y); return doubleToReturnSlot(result); } }) ================================================ FILE: runtime/src/main/kotlin/generated/_ArraysNative.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.collections // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // import kotlin.ranges.contains import kotlin.ranges.reversed /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun Array.elementAt(index: Int): T { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun ByteArray.elementAt(index: Int): Byte { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun ShortArray.elementAt(index: Int): Short { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun IntArray.elementAt(index: Int): Int { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun LongArray.elementAt(index: Int): Long { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun FloatArray.elementAt(index: Int): Float { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun DoubleArray.elementAt(index: Int): Double { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun BooleanArray.elementAt(index: Int): Boolean { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun CharArray.elementAt(index: Int): Char { return get(index) } /** * Returns a [List] that wraps the original array. */ public actual fun Array.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: T): Boolean = this@asList.contains(element) override fun get(index: Int): T = this@asList[index] override fun indexOf(element: T): Int = this@asList.indexOf(element) override fun lastIndexOf(element: T): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun ByteArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Byte): Boolean = this@asList.contains(element) override fun get(index: Int): Byte = this@asList[index] override fun indexOf(element: Byte): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Byte): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun ShortArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Short): Boolean = this@asList.contains(element) override fun get(index: Int): Short = this@asList[index] override fun indexOf(element: Short): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Short): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun IntArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Int): Boolean = this@asList.contains(element) override fun get(index: Int): Int = this@asList[index] override fun indexOf(element: Int): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Int): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun LongArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Long): Boolean = this@asList.contains(element) override fun get(index: Int): Long = this@asList[index] override fun indexOf(element: Long): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Long): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun FloatArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Float): Boolean = this@asList.any { it.toBits() == element.toBits() } override fun get(index: Int): Float = this@asList[index] override fun indexOf(element: Float): Int = this@asList.indexOfFirst { it.toBits() == element.toBits() } override fun lastIndexOf(element: Float): Int = this@asList.indexOfLast { it.toBits() == element.toBits() } } } /** * Returns a [List] that wraps the original array. */ public actual fun DoubleArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Double): Boolean = this@asList.any { it.toBits() == element.toBits() } override fun get(index: Int): Double = this@asList[index] override fun indexOf(element: Double): Int = this@asList.indexOfFirst { it.toBits() == element.toBits() } override fun lastIndexOf(element: Double): Int = this@asList.indexOfLast { it.toBits() == element.toBits() } } } /** * Returns a [List] that wraps the original array. */ public actual fun BooleanArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Boolean): Boolean = this@asList.contains(element) override fun get(index: Int): Boolean = this@asList[index] override fun indexOf(element: Boolean): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Boolean): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ public actual fun CharArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: Char): Boolean = this@asList.contains(element) override fun get(index: Int): Char = this@asList[index] override fun indexOf(element: Char): Int = this@asList.indexOf(element) override fun lastIndexOf(element: Char): Int = this@asList.lastIndexOf(element) } } /** * Returns `true` if the two specified arrays are *deeply* equal to one another, * i.e. contain the same number of the same elements in the same order. * * If two corresponding elements are nested arrays, they are also compared deeply. * If any of arrays contains itself on any nesting level the behavior is undefined. * * The elements of other types are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") @kotlin.internal.LowPriorityInOverloadResolution public actual infix fun Array.contentDeepEquals(other: Array): Boolean { return this.contentDeepEquals(other) } /** * Returns `true` if the two specified arrays are *deeply* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The specified arrays are also considered deeply equal if both are `null`. * * If two corresponding elements are nested arrays, they are also compared deeply. * If any of arrays contains itself on any nesting level the behavior is undefined. * * The elements of other types are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun Array?.contentDeepEquals(other: Array?): Boolean { return contentDeepEqualsImpl(other) } /** * Returns a hash code based on the contents of this array as if it is [List]. * Nested arrays are treated as lists too. * * If any of arrays contains itself on any nesting level the behavior is undefined. */ @SinceKotlin("1.1") @kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentDeepHashCode(): Int { return this.contentDeepHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. * Nested arrays are treated as lists too. * * If any of arrays contains itself on any nesting level the behavior is undefined. */ @SinceKotlin("1.4") public actual fun Array?.contentDeepHashCode(): Int { return contentDeepHashCodeImpl() } /** * Returns a string representation of the contents of this array as if it is a [List]. * Nested arrays are treated as lists too. * * If any of arrays contains itself on any nesting level that reference * is rendered as `"[...]"` to prevent recursion. * * @sample samples.collections.Arrays.ContentOperations.contentDeepToString */ @SinceKotlin("1.1") @kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentDeepToString(): String { return this.contentDeepToString() } /** * Returns a string representation of the contents of this array as if it is a [List]. * Nested arrays are treated as lists too. * * If any of arrays contains itself on any nesting level that reference * is rendered as `"[...]"` to prevent recursion. * * @sample samples.collections.Arrays.ContentOperations.contentDeepToString */ @SinceKotlin("1.4") public actual fun Array?.contentDeepToString(): String { return contentDeepToStringImpl() } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun Array.contentEquals(other: Array): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun ByteArray.contentEquals(other: ByteArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun ShortArray.contentEquals(other: ShortArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun IntArray.contentEquals(other: IntArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun LongArray.contentEquals(other: LongArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun FloatArray.contentEquals(other: FloatArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun DoubleArray.contentEquals(other: DoubleArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun BooleanArray.contentEquals(other: BooleanArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual infix fun CharArray.contentEquals(other: CharArray): Boolean { return this.contentEquals(other) } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun Array?.contentEquals(other: Array?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun ByteArray?.contentEquals(other: ByteArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun ShortArray?.contentEquals(other: ShortArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun IntArray?.contentEquals(other: IntArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun LongArray?.contentEquals(other: LongArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun FloatArray?.contentEquals(other: FloatArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (!this[i].equals(other[i])) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun DoubleArray?.contentEquals(other: DoubleArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (!this[i].equals(other[i])) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun BooleanArray?.contentEquals(other: BooleanArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns `true` if the two specified arrays are *structurally* equal to one another, * i.e. contain the same number of the same elements in the same order. * * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.4") public actual infix fun CharArray?.contentEquals(other: CharArray?): Boolean { if (this === other) return true if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false } return true } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun Array.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun ByteArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun ShortArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun IntArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun LongArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun FloatArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun DoubleArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun BooleanArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun CharArray.contentHashCode(): Int { return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun Array?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun ByteArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun ShortArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun IntArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun LongArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun FloatArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun DoubleArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun BooleanArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.4") public actual fun CharArray?.contentHashCode(): Int { if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() return result } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun Array.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun ByteArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun ShortArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun IntArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun LongArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun FloatArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun DoubleArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun BooleanArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @SinceKotlin("1.1") @DeprecatedSinceKotlin(hiddenSince = "1.4") public actual fun CharArray.contentToString(): String { return this.contentToString() } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun Array?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun ByteArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun ShortArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun IntArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun LongArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun FloatArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun DoubleArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun BooleanArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Returns a string representation of the contents of the specified array as if it is [List]. * * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.4") public actual fun CharArray?.contentToString(): String { return this?.joinToString(", ", "[", "]") ?: "null" } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun Array.copyInto(destination: Array, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): Array { @Suppress("UNCHECKED_CAST") arrayCopy(this as Array, startIndex, destination as Array, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ByteArray.copyInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ByteArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ShortArray.copyInto(destination: ShortArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ShortArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun IntArray.copyInto(destination: IntArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): IntArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun LongArray.copyInto(destination: LongArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): LongArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun FloatArray.copyInto(destination: FloatArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): FloatArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun DoubleArray.copyInto(destination: DoubleArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): DoubleArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun BooleanArray.copyInto(destination: BooleanArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): BooleanArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Copies this array or its subrange into the [destination] array and returns that array. * * It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range. * * @param destination the array to copy to. * @param destinationOffset the position in the [destination] array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this array by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. * * @return the [destination] array. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun CharArray.copyInto(destination: CharArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): CharArray { arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex) return destination } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun Array.copyOf(): Array { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun ByteArray.copyOf(): ByteArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun ShortArray.copyOf(): ShortArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun IntArray.copyOf(): IntArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun LongArray.copyOf(): LongArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun FloatArray.copyOf(): FloatArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun DoubleArray.copyOf(): DoubleArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun BooleanArray.copyOf(): BooleanArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array. * * @sample samples.collections.Arrays.CopyOfOperations.copyOf */ public actual fun CharArray.copyOf(): CharArray { return this.copyOfUninitializedElements(size) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun ByteArray.copyOf(newSize: Int): ByteArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun ShortArray.copyOf(newSize: Int): ShortArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun IntArray.copyOf(newSize: Int): IntArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun LongArray.copyOf(newSize: Int): LongArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun FloatArray.copyOf(newSize: Int): FloatArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with zero values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with zero values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun DoubleArray.copyOf(newSize: Int): DoubleArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with `false` values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with `false` values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun BooleanArray.copyOf(newSize: Int): BooleanArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with null char (`\u0000`) values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with null char (`\u0000`) values. * * @sample samples.collections.Arrays.CopyOfOperations.resizedPrimitiveCopyOf */ public actual fun CharArray.copyOf(newSize: Int): CharArray { return this.copyOfUninitializedElements(newSize) } /** * Returns new array which is a copy of the original array, resized to the given [newSize]. * The copy is either truncated or padded at the end with `null` values if necessary. * * - If [newSize] is less than the size of the original array, the copy array is truncated to the [newSize]. * - If [newSize] is greater than the size of the original array, the extra elements in the copy array are filled with `null` values. * * @sample samples.collections.Arrays.CopyOfOperations.resizingCopyOf */ public actual fun Array.copyOf(newSize: Int): Array { return this.copyOfNulls(newSize) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun Array.copyOfRange(fromIndex: Int, toIndex: Int): Array { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns a new array which is a copy of the specified range of the original array. * * @param fromIndex the start of the range (inclusive) to copy. * @param toIndex the end of the range (exclusive) to copy. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ public actual fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray { checkCopyOfRangeArguments(fromIndex, toIndex, size) return copyOfUninitializedElements(fromIndex, toIndex) } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun Array.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): Array { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = arrayOfUninitializedElements(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun ByteArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): ByteArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = ByteArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun ShortArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): ShortArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = ShortArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun IntArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): IntArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = IntArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun LongArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): LongArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = LongArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun FloatArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): FloatArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = FloatArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun DoubleArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): DoubleArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = DoubleArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun BooleanArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): BooleanArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = BooleanArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array's range between [fromIndex] (inclusive) * and [toIndex] (exclusive) with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun CharArray.copyOfUninitializedElements(fromIndex: Int, toIndex: Int): CharArray { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = CharArray(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun Array.copyOfUninitializedElements(newSize: Int): Array { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun ByteArray.copyOfUninitializedElements(newSize: Int): ByteArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun ShortArray.copyOfUninitializedElements(newSize: Int): ShortArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun IntArray.copyOfUninitializedElements(newSize: Int): IntArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun LongArray.copyOfUninitializedElements(newSize: Int): LongArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun FloatArray.copyOfUninitializedElements(newSize: Int): FloatArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun DoubleArray.copyOfUninitializedElements(newSize: Int): DoubleArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun BooleanArray.copyOfUninitializedElements(newSize: Int): BooleanArray { return copyOfUninitializedElements(0, newSize) } /** * Returns new array which is a copy of the original array with new elements filled with **lateinit** _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun CharArray.copyOfUninitializedElements(newSize: Int): CharArray { return copyOfUninitializedElements(0, newSize) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun Array.fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Fills this array or its subrange with the specified [element] value. * * @param fromIndex the start of the range (inclusive) to fill, 0 by default. * @param toIndex the end of the range (exclusive) to fill, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @SinceKotlin("1.3") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size): Unit { arrayFill(this, fromIndex, toIndex, element) } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun Array.plus(element: T): Array { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun ByteArray.plus(element: Byte): ByteArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun ShortArray.plus(element: Short): ShortArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun IntArray.plus(element: Int): IntArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun LongArray.plus(element: Long): LongArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun FloatArray.plus(element: Float): FloatArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun DoubleArray.plus(element: Double): DoubleArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun BooleanArray.plus(element: Boolean): BooleanArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ public actual operator fun CharArray.plus(element: Char): CharArray { val index = size val result = copyOfUninitializedElements(index + 1) result[index] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun Array.plus(elements: Collection): Array { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun ByteArray.plus(elements: Collection): ByteArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun ShortArray.plus(elements: Collection): ShortArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun IntArray.plus(elements: Collection): IntArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun LongArray.plus(elements: Collection): LongArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun FloatArray.plus(elements: Collection): FloatArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun DoubleArray.plus(elements: Collection): DoubleArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun BooleanArray.plus(elements: Collection): BooleanArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] collection. */ public actual operator fun CharArray.plus(elements: Collection): CharArray { var index = size val result = copyOfUninitializedElements(index + elements.size) for (element in elements) result[index++] = element return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun Array.plus(elements: Array): Array { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun ByteArray.plus(elements: ByteArray): ByteArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun ShortArray.plus(elements: ShortArray): ShortArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun IntArray.plus(elements: IntArray): IntArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun LongArray.plus(elements: LongArray): LongArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun FloatArray.plus(elements: FloatArray): FloatArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun DoubleArray.plus(elements: DoubleArray): DoubleArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun BooleanArray.plus(elements: BooleanArray): BooleanArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then all elements of the given [elements] array. */ public actual operator fun CharArray.plus(elements: CharArray): CharArray { val thisSize = size val arraySize = elements.size val result = copyOfUninitializedElements(thisSize + arraySize) elements.copyInto(result, thisSize) return result } /** * Returns an array containing all elements of the original array and then the given [element]. */ @kotlin.internal.InlineOnly public actual inline fun Array.plusElement(element: T): Array { return plus(element) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun IntArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun LongArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun ByteArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun ShortArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun DoubleArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun FloatArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place. * * @sample samples.collections.Arrays.Sorting.sortArray */ public actual fun CharArray.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts the array in-place according to the natural order of its elements. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. * * @sample samples.collections.Arrays.Sorting.sortArrayOfComparable */ public actual fun > Array.sort(): Unit { if (size > 1) sortArray(this, 0, size) } /** * Sorts a range in the array in-place. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArrayOfComparable */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun > Array.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ByteArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun ShortArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun IntArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun LongArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun FloatArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun DoubleArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts a range in the array in-place. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. * * @sample samples.collections.Arrays.Sorting.sortRangeOfArray */ @SinceKotlin("1.4") @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun CharArray.sort(fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArray(this, fromIndex, toIndex) } /** * Sorts the array in-place according to the order specified by the given [comparator]. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public actual fun Array.sortWith(comparator: Comparator): Unit { if (size > 1) sortArrayWith(this, 0, size, comparator) } /** * Sorts a range in the array in-place with the given [comparator]. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. * * @param fromIndex the start of the range (inclusive) to sort, 0 by default. * @param toIndex the end of the range (exclusive) to sort, size of this array by default. * * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. */ @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun Array.sortWith(comparator: Comparator, fromIndex: Int = 0, toIndex: Int = size): Unit { AbstractList.checkRangeIndexes(fromIndex, toIndex, size) sortArrayWith(this, fromIndex, toIndex, comparator) } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun ByteArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun ShortArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun IntArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun LongArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun FloatArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun DoubleArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun BooleanArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } /** * Returns a *typed* object array containing all of the elements of this primitive array. */ public actual fun CharArray.toTypedArray(): Array { return Array(size) { index -> this[index] } } ================================================ FILE: runtime/src/main/kotlin/generated/_CharCategories.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 1343 ranges totally @SharedImmutable private val rangeStart = intArrayOf( 0x0000, 0x0020, 0x0022, 0x0027, 0x002b, 0x002e, 0x0030, 0x003a, 0x003c, 0x003f, 0x0041, 0x005b, 0x005e, 0x0061, 0x007b, 0x007e, 0x007f, 0x00a0, 0x00a2, 0x00a6, 0x00aa, 0x00ad, 0x00b0, 0x00b3, 0x00b6, 0x00b9, 0x00bd, 0x00c0, 0x00d7, 0x00d8, 0x00df, 0x00f7, 0x00f8, 0x00ff, 0x0138, 0x0149, 0x0179, 0x017f, 0x0182, 0x0184, 0x018b, 0x018e, 0x0190, 0x0198, 0x019b, 0x01a0, 0x01a7, 0x01aa, 0x01ac, 0x01b3, 0x01b8, 0x01bb, 0x01bd, 0x01c0, 0x01c4, 0x01cc, 0x01dd, 0x01f0, 0x01f4, 0x01f8, 0x0233, 0x0239, 0x0240, 0x0243, 0x0246, 0x024f, 0x0294, 0x0295, 0x02b0, 0x02c2, 0x02c6, 0x02d2, 0x02e0, 0x02e5, 0x02eb, 0x02ef, 0x0300, 0x0370, 0x0374, 0x0377, 0x037a, 0x037d, 0x0380, 0x0384, 0x0386, 0x038a, 0x038f, 0x0391, 0x03a2, 0x03a3, 0x03ac, 0x03cd, 0x03d2, 0x03d5, 0x03d7, 0x03ef, 0x03f4, 0x03f9, 0x03fb, 0x03fd, 0x0430, 0x045f, 0x0482, 0x0483, 0x0488, 0x048a, 0x04c1, 0x04cf, 0x0530, 0x0531, 0x0557, 0x055a, 0x0560, 0x0589, 0x058c, 0x058f, 0x0591, 0x05be, 0x05bf, 0x05c8, 0x05d0, 0x05eb, 0x05ef, 0x05f3, 0x05f5, 0x0600, 0x0606, 0x0609, 0x060e, 0x0610, 0x061b, 0x061e, 0x0620, 0x0640, 0x0641, 0x064b, 0x0660, 0x066a, 0x066e, 0x0671, 0x06d3, 0x06d6, 0x06dd, 0x06df, 0x06e4, 0x06e8, 0x06ea, 0x06ee, 0x06f0, 0x06fa, 0x06fc, 0x0700, 0x070e, 0x0711, 0x0712, 0x0730, 0x074b, 0x074d, 0x07a6, 0x07b1, 0x07b2, 0x07c0, 0x07ca, 0x07eb, 0x07f4, 0x07f7, 0x07fa, 0x07fd, 0x0800, 0x0816, 0x081a, 0x081b, 0x0822, 0x0827, 0x0829, 0x082e, 0x0830, 0x083f, 0x0840, 0x0859, 0x085c, 0x0860, 0x086b, 0x08a0, 0x08b5, 0x08b6, 0x08c8, 0x08d3, 0x08e2, 0x08e3, 0x0903, 0x0904, 0x093a, 0x093d, 0x093e, 0x0941, 0x0949, 0x094b, 0x0950, 0x0951, 0x0958, 0x0962, 0x0964, 0x0966, 0x0970, 0x0972, 0x0981, 0x0984, 0x0985, 0x098c, 0x0990, 0x0993, 0x09a9, 0x09aa, 0x09b1, 0x09b5, 0x09b8, 0x09bb, 0x09be, 0x09c1, 0x09c5, 0x09c8, 0x09cc, 0x09cf, 0x09d7, 0x09d8, 0x09db, 0x09e1, 0x09e4, 0x09e6, 0x09f0, 0x09f2, 0x09f4, 0x09fa, 0x09fd, 0x0a00, 0x0a03, 0x0a05, 0x0a0b, 0x0a0f, 0x0a11, 0x0a13, 0x0a29, 0x0a2a, 0x0a2f, 0x0a3b, 0x0a3e, 0x0a41, 0x0a43, 0x0a46, 0x0a4a, 0x0a4d, 0x0a50, 0x0a52, 0x0a59, 0x0a5c, 0x0a5f, 0x0a66, 0x0a70, 0x0a73, 0x0a76, 0x0a77, 0x0a81, 0x0a84, 0x0a85, 0x0a8c, 0x0a91, 0x0a93, 0x0aa9, 0x0aaa, 0x0aaf, 0x0ab5, 0x0aba, 0x0abd, 0x0abe, 0x0ac1, 0x0ac4, 0x0ac9, 0x0acd, 0x0ad0, 0x0ad1, 0x0ae0, 0x0ae3, 0x0ae6, 0x0af0, 0x0af2, 0x0af9, 0x0afa, 0x0b00, 0x0b03, 0x0b05, 0x0b0c, 0x0b10, 0x0b13, 0x0b29, 0x0b2a, 0x0b2f, 0x0b35, 0x0b3a, 0x0b3d, 0x0b3f, 0x0b43, 0x0b46, 0x0b4a, 0x0b4d, 0x0b4e, 0x0b55, 0x0b58, 0x0b5b, 0x0b61, 0x0b64, 0x0b66, 0x0b70, 0x0b72, 0x0b78, 0x0b81, 0x0b85, 0x0b8b, 0x0b8e, 0x0b8f, 0x0b94, 0x0b97, 0x0b9a, 0x0b9f, 0x0ba2, 0x0ba5, 0x0ba8, 0x0bab, 0x0bae, 0x0bba, 0x0bbe, 0x0bc3, 0x0bc6, 0x0bc7, 0x0bcc, 0x0bcf, 0x0bd1, 0x0bd7, 0x0bd8, 0x0be6, 0x0bf0, 0x0bf3, 0x0bf8, 0x0bfb, 0x0c00, 0x0c03, 0x0c05, 0x0c0b, 0x0c10, 0x0c12, 0x0c29, 0x0c2a, 0x0c3a, 0x0c3d, 0x0c40, 0x0c43, 0x0c46, 0x0c49, 0x0c4a, 0x0c4e, 0x0c54, 0x0c58, 0x0c5b, 0x0c60, 0x0c63, 0x0c66, 0x0c70, 0x0c77, 0x0c78, 0x0c7f, 0x0c82, 0x0c85, 0x0c8b, 0x0c90, 0x0c92, 0x0ca9, 0x0caa, 0x0cb4, 0x0cb5, 0x0cba, 0x0cbc, 0x0cc0, 0x0cc5, 0x0cc7, 0x0ccc, 0x0cce, 0x0cd5, 0x0cd7, 0x0cde, 0x0ce2, 0x0ce4, 0x0ce6, 0x0cf0, 0x0cf3, 0x0d00, 0x0d02, 0x0d04, 0x0d0b, 0x0d10, 0x0d12, 0x0d3a, 0x0d3e, 0x0d41, 0x0d45, 0x0d47, 0x0d4c, 0x0d4f, 0x0d52, 0x0d55, 0x0d58, 0x0d5f, 0x0d62, 0x0d64, 0x0d66, 0x0d70, 0x0d79, 0x0d7a, 0x0d80, 0x0d83, 0x0d85, 0x0d97, 0x0d9a, 0x0db2, 0x0db3, 0x0dbc, 0x0dc0, 0x0dc7, 0x0dc8, 0x0dcd, 0x0dd0, 0x0dd3, 0x0dd7, 0x0dd8, 0x0de0, 0x0de6, 0x0df0, 0x0df3, 0x0df5, 0x0e01, 0x0e2f, 0x0e34, 0x0e3b, 0x0e3f, 0x0e40, 0x0e46, 0x0e47, 0x0e4f, 0x0e50, 0x0e5a, 0x0e5c, 0x0e80, 0x0e85, 0x0e86, 0x0e8b, 0x0e8c, 0x0ea3, 0x0ea7, 0x0eaf, 0x0eb4, 0x0ebd, 0x0ec0, 0x0ec5, 0x0ec8, 0x0ece, 0x0ed0, 0x0eda, 0x0edc, 0x0ee0, 0x0f00, 0x0f01, 0x0f04, 0x0f13, 0x0f17, 0x0f1a, 0x0f20, 0x0f2a, 0x0f34, 0x0f3a, 0x0f3e, 0x0f40, 0x0f48, 0x0f49, 0x0f6d, 0x0f71, 0x0f7f, 0x0f80, 0x0f83, 0x0f88, 0x0f8d, 0x0f98, 0x0f99, 0x0fbd, 0x0fbe, 0x0fc6, 0x0fc7, 0x0fcb, 0x0fd0, 0x0fd5, 0x0fd9, 0x0fdb, 0x1000, 0x102b, 0x102d, 0x1031, 0x1032, 0x1036, 0x103c, 0x103f, 0x1040, 0x104a, 0x1050, 0x1056, 0x1059, 0x105c, 0x105f, 0x1062, 0x1065, 0x1067, 0x106e, 0x1071, 0x1075, 0x1082, 0x1085, 0x1087, 0x108c, 0x1090, 0x109a, 0x109d, 0x10a0, 0x10c5, 0x10c8, 0x10cb, 0x10d0, 0x10fb, 0x10fd, 0x1100, 0x1249, 0x124a, 0x124e, 0x1250, 0x1256, 0x125a, 0x125e, 0x1260, 0x1289, 0x128a, 0x128e, 0x1290, 0x12b1, 0x12b2, 0x12b6, 0x12b8, 0x12be, 0x12c2, 0x12c6, 0x12c8, 0x12d7, 0x12d8, 0x1311, 0x1312, 0x1316, 0x1318, 0x135b, 0x135d, 0x1360, 0x1369, 0x137d, 0x1380, 0x1390, 0x139a, 0x13a0, 0x13f6, 0x13f8, 0x13fe, 0x1401, 0x166d, 0x166f, 0x1680, 0x1681, 0x169b, 0x169d, 0x16a0, 0x16eb, 0x16ee, 0x16f1, 0x16f9, 0x1700, 0x170d, 0x170e, 0x1712, 0x1715, 0x1720, 0x1732, 0x1735, 0x1737, 0x1740, 0x1752, 0x1754, 0x1760, 0x176b, 0x1770, 0x1772, 0x1774, 0x1780, 0x17b4, 0x17b7, 0x17be, 0x17c4, 0x17c9, 0x17d4, 0x17d5, 0x17da, 0x17dd, 0x17e0, 0x17ea, 0x17f0, 0x17fa, 0x1800, 0x1804, 0x1809, 0x180c, 0x180f, 0x1810, 0x181a, 0x1820, 0x1843, 0x1844, 0x1879, 0x1880, 0x1885, 0x1887, 0x18a8, 0x18ab, 0x18b0, 0x18f6, 0x1900, 0x191f, 0x1922, 0x1925, 0x1928, 0x192b, 0x192e, 0x1931, 0x1933, 0x1939, 0x193c, 0x193e, 0x1943, 0x1946, 0x1950, 0x196e, 0x1970, 0x1975, 0x1980, 0x19ac, 0x19b0, 0x19ca, 0x19d0, 0x19da, 0x19db, 0x19de, 0x1a00, 0x1a17, 0x1a1a, 0x1a1d, 0x1a20, 0x1a55, 0x1a58, 0x1a5e, 0x1a61, 0x1a65, 0x1a6d, 0x1a73, 0x1a7c, 0x1a80, 0x1a8a, 0x1a90, 0x1a9a, 0x1aa0, 0x1aa7, 0x1aa8, 0x1aae, 0x1ab0, 0x1abc, 0x1ac1, 0x1b00, 0x1b04, 0x1b05, 0x1b34, 0x1b36, 0x1b3a, 0x1b3d, 0x1b40, 0x1b45, 0x1b4c, 0x1b50, 0x1b5a, 0x1b61, 0x1b6b, 0x1b74, 0x1b7d, 0x1b80, 0x1b83, 0x1ba1, 0x1ba4, 0x1ba7, 0x1bad, 0x1bb0, 0x1bba, 0x1be6, 0x1beb, 0x1bef, 0x1bf2, 0x1bf4, 0x1bfc, 0x1c00, 0x1c24, 0x1c2c, 0x1c34, 0x1c36, 0x1c38, 0x1c3b, 0x1c40, 0x1c4a, 0x1c4d, 0x1c50, 0x1c5a, 0x1c78, 0x1c7e, 0x1c80, 0x1c89, 0x1c90, 0x1cbb, 0x1cbd, 0x1cc0, 0x1cc8, 0x1cd0, 0x1cd3, 0x1cd4, 0x1ce1, 0x1ce2, 0x1ce9, 0x1ced, 0x1cee, 0x1cf2, 0x1cf7, 0x1cfa, 0x1cfb, 0x1d00, 0x1d2c, 0x1d6b, 0x1d78, 0x1d79, 0x1d9b, 0x1dc0, 0x1dfa, 0x1dfb, 0x1e00, 0x1e95, 0x1e9d, 0x1eff, 0x1f08, 0x1f10, 0x1f16, 0x1f18, 0x1f1e, 0x1f20, 0x1f28, 0x1f30, 0x1f38, 0x1f40, 0x1f46, 0x1f48, 0x1f4e, 0x1f50, 0x1f58, 0x1f60, 0x1f68, 0x1f70, 0x1f7e, 0x1f80, 0x1f88, 0x1f90, 0x1f98, 0x1fa0, 0x1fa8, 0x1fb0, 0x1fb3, 0x1fb8, 0x1fbc, 0x1fbf, 0x1fc2, 0x1fc3, 0x1fc8, 0x1fcc, 0x1fcf, 0x1fd2, 0x1fd5, 0x1fd8, 0x1fdc, 0x1fdd, 0x1fe0, 0x1fe8, 0x1fed, 0x1ff0, 0x1ff3, 0x1ff8, 0x1ffc, 0x1fff, 0x2000, 0x200b, 0x2010, 0x2016, 0x2018, 0x201c, 0x2020, 0x2028, 0x202a, 0x202f, 0x2030, 0x2039, 0x203b, 0x203e, 0x2042, 0x2045, 0x2047, 0x2052, 0x2055, 0x205f, 0x2060, 0x2065, 0x2066, 0x2070, 0x2072, 0x2074, 0x207a, 0x207d, 0x2080, 0x208a, 0x208d, 0x2090, 0x209d, 0x20a0, 0x20c0, 0x20d0, 0x20dd, 0x20e1, 0x20e2, 0x20e5, 0x20f1, 0x2100, 0x2105, 0x210a, 0x210d, 0x2111, 0x2114, 0x2118, 0x2119, 0x211e, 0x2123, 0x212a, 0x212e, 0x2130, 0x2134, 0x2135, 0x2139, 0x213d, 0x2140, 0x2145, 0x2146, 0x214a, 0x214d, 0x2150, 0x2160, 0x2183, 0x2185, 0x2189, 0x218c, 0x2190, 0x2195, 0x219a, 0x219c, 0x219e, 0x21a7, 0x21ae, 0x21af, 0x21cd, 0x21d1, 0x21d5, 0x21f4, 0x2300, 0x2308, 0x230c, 0x2320, 0x2322, 0x2329, 0x232b, 0x237c, 0x237d, 0x239b, 0x23b4, 0x23dc, 0x23e2, 0x2427, 0x2440, 0x244b, 0x2460, 0x249c, 0x24ea, 0x2500, 0x25b7, 0x25b8, 0x25c1, 0x25c2, 0x25f8, 0x2600, 0x266f, 0x2670, 0x2768, 0x2776, 0x2794, 0x27c0, 0x27c5, 0x27c7, 0x27e6, 0x27f0, 0x2800, 0x2900, 0x2983, 0x2999, 0x29d8, 0x29dc, 0x29fc, 0x29fe, 0x2b00, 0x2b30, 0x2b45, 0x2b47, 0x2b4d, 0x2b74, 0x2b76, 0x2b96, 0x2b97, 0x2c00, 0x2c2f, 0x2c30, 0x2c5e, 0x2c62, 0x2c65, 0x2c66, 0x2c6d, 0x2c71, 0x2c76, 0x2c7c, 0x2c7e, 0x2c80, 0x2ce3, 0x2ce5, 0x2ceb, 0x2cef, 0x2cf2, 0x2cf4, 0x2cf9, 0x2cfb, 0x2d00, 0x2d25, 0x2d28, 0x2d2b, 0x2d30, 0x2d68, 0x2d6f, 0x2d71, 0x2d7f, 0x2d80, 0x2d97, 0x2da0, 0x2da7, 0x2da8, 0x2daf, 0x2db0, 0x2db7, 0x2db8, 0x2dbf, 0x2dc0, 0x2dc7, 0x2dc8, 0x2dcf, 0x2dd0, 0x2dd7, 0x2dd8, 0x2ddf, 0x2de0, 0x2e00, 0x2e02, 0x2e06, 0x2e08, 0x2e0e, 0x2e15, 0x2e1b, 0x2e1f, 0x2e22, 0x2e2a, 0x2e2f, 0x2e30, 0x2e3a, 0x2e3c, 0x2e40, 0x2e43, 0x2e4f, 0x2e53, 0x2e80, 0x2e9a, 0x2e9b, 0x2ef4, 0x2f00, 0x2fd6, 0x2ff0, 0x2ffc, 0x3000, 0x3003, 0x3006, 0x3008, 0x3012, 0x3014, 0x301a, 0x301f, 0x3021, 0x302a, 0x302e, 0x3031, 0x3036, 0x3039, 0x303c, 0x303f, 0x3041, 0x3097, 0x309a, 0x309d, 0x30a0, 0x30a1, 0x30fb, 0x30fe, 0x3100, 0x3105, 0x3130, 0x3131, 0x318f, 0x3192, 0x3196, 0x31a0, 0x31c0, 0x31e4, 0x31f0, 0x3200, 0x321f, 0x3220, 0x322a, 0x3248, 0x3250, 0x3251, 0x3260, 0x3280, 0x328a, 0x32b1, 0x32c0, 0x3400, 0x4dc0, 0x4e00, 0x9ffd, 0xa000, 0xa015, 0xa016, 0xa48d, 0xa490, 0xa4c7, 0xa4d0, 0xa4f8, 0xa4fe, 0xa500, 0xa60c, 0xa60d, 0xa610, 0xa620, 0xa62a, 0xa62c, 0xa640, 0xa66e, 0xa671, 0xa674, 0xa67e, 0xa680, 0xa69c, 0xa69e, 0xa6a0, 0xa6e6, 0xa6f0, 0xa6f2, 0xa6f8, 0xa700, 0xa717, 0xa720, 0xa722, 0xa72f, 0xa731, 0xa770, 0xa771, 0xa778, 0xa77e, 0xa788, 0xa78b, 0xa78f, 0xa791, 0xa795, 0xa7aa, 0xa7af, 0xa7b0, 0xa7b4, 0xa7c0, 0xa7c2, 0xa7c6, 0xa7ca, 0xa7cb, 0xa7f5, 0xa7f8, 0xa7fb, 0xa801, 0xa804, 0xa809, 0xa80c, 0xa823, 0xa826, 0xa828, 0xa82c, 0xa82d, 0xa830, 0xa836, 0xa83a, 0xa840, 0xa874, 0xa878, 0xa880, 0xa882, 0xa8b4, 0xa8c4, 0xa8c6, 0xa8ce, 0xa8d0, 0xa8da, 0xa8e0, 0xa8f2, 0xa8f8, 0xa8fb, 0xa8ff, 0xa900, 0xa90a, 0xa926, 0xa92e, 0xa930, 0xa947, 0xa952, 0xa954, 0xa95f, 0xa960, 0xa97d, 0xa980, 0xa983, 0xa984, 0xa9b3, 0xa9b6, 0xa9ba, 0xa9bc, 0xa9be, 0xa9c1, 0xa9ce, 0xa9d0, 0xa9da, 0xa9de, 0xa9e0, 0xa9e5, 0xa9e7, 0xa9f0, 0xa9fa, 0xa9ff, 0xaa00, 0xaa29, 0xaa2e, 0xaa32, 0xaa35, 0xaa37, 0xaa40, 0xaa43, 0xaa44, 0xaa4c, 0xaa4e, 0xaa50, 0xaa5a, 0xaa5c, 0xaa60, 0xaa70, 0xaa71, 0xaa77, 0xaa7a, 0xaa7d, 0xaa7e, 0xaab0, 0xaab4, 0xaab7, 0xaab9, 0xaabd, 0xaac2, 0xaac3, 0xaadb, 0xaade, 0xaae0, 0xaaeb, 0xaaef, 0xaaf2, 0xaaf5, 0xaaf7, 0xab01, 0xab07, 0xab09, 0xab0f, 0xab11, 0xab17, 0xab20, 0xab27, 0xab28, 0xab2f, 0xab30, 0xab5b, 0xab5c, 0xab60, 0xab69, 0xab6c, 0xab70, 0xabc0, 0xabe3, 0xabeb, 0xabee, 0xabf0, 0xabfa, 0xac00, 0xd7a4, 0xd7b0, 0xd7c7, 0xd7cb, 0xd7fc, 0xd800, 0xe000, 0xf900, 0xfa6e, 0xfa70, 0xfada, 0xfb00, 0xfb07, 0xfb13, 0xfb18, 0xfb1d, 0xfb1f, 0xfb29, 0xfb2a, 0xfb37, 0xfb38, 0xfb3d, 0xfb3e, 0xfb46, 0xfbb2, 0xfbc2, 0xfbd3, 0xfd3e, 0xfd40, 0xfd50, 0xfd90, 0xfd92, 0xfdc8, 0xfdf0, 0xfdfc, 0xfdfe, 0xfe00, 0xfe10, 0xfe16, 0xfe1a, 0xfe20, 0xfe30, 0xfe33, 0xfe35, 0xfe45, 0xfe48, 0xfe4b, 0xfe4e, 0xfe51, 0xfe56, 0xfe59, 0xfe5f, 0xfe62, 0xfe66, 0xfe68, 0xfe6c, 0xfe70, 0xfe75, 0xfe76, 0xfefd, 0xff01, 0xff02, 0xff07, 0xff0b, 0xff0e, 0xff10, 0xff1a, 0xff1c, 0xff1f, 0xff21, 0xff3b, 0xff3e, 0xff41, 0xff5b, 0xff5e, 0xff5f, 0xff64, 0xff66, 0xff70, 0xff71, 0xff9e, 0xffa0, 0xffbf, 0xffc2, 0xffc8, 0xffca, 0xffd0, 0xffd2, 0xffd7, 0xffdb, 0xffde, 0xffe1, 0xffe4, 0xffe7, 0xffe9, 0xffed, 0xffef, 0xfff9, 0xfffc, 0xfffe, ) @SharedImmutable private val rangeCategory = intArrayOf( 0x000f, 0x030c, 0x6b18, 0x5ab8, 0x5319, 0x0018, 0x0009, 0x0018, 0x0019, 0x0018, 0x0001, 0x5b15, 0x02fb, 0x0002, 0x5b35, 0x0019, 0x000f, 0x030c, 0x001a, 0x6f1c, 0x67a5, 0x6f90, 0x2f3c, 0x0b6b, 0x6f18, 0x78ab, 0x616b, 0x0001, 0x0019, 0x0001, 0x0002, 0x0019, 0x0002, 0x0022, 0x0022, 0x0022, 0x0041, 0x0442, 0x0041, 0x0441, 0x0841, 0x0001, 0x0821, 0x0841, 0x0422, 0x0041, 0x0041, 0x0002, 0x0441, 0x0041, 0x0841, 0x0025, 0x0002, 0x0005, 0x0861, 0x0022, 0x0022, 0x0c22, 0x0441, 0x0041, 0x0002, 0x0422, 0x0022, 0x0001, 0x0041, 0x0002, 0x0005, 0x0002, 0x0004, 0x001b, 0x0004, 0x001b, 0x0004, 0x001b, 0x009b, 0x001b, 0x0006, 0x0041, 0x0764, 0x4622, 0x0844, 0x0702, 0x0011, 0x001b, 0x0701, 0x0221, 0x0041, 0x0001, 0x0011, 0x0001, 0x0002, 0x0442, 0x0001, 0x0002, 0x0022, 0x0002, 0x6441, 0x0001, 0x0002, 0x0001, 0x0002, 0x0022, 0x001c, 0x0006, 0x0007, 0x0041, 0x0041, 0x0022, 0x0011, 0x0001, 0x1231, 0x0018, 0x0002, 0x4698, 0x7391, 0x023a, 0x0006, 0x0014, 0x1b06, 0x0011, 0x0005, 0x0011, 0x0005, 0x0018, 0x0011, 0x0010, 0x0019, 0x6b18, 0x001c, 0x0006, 0x4618, 0x0018, 0x0005, 0x0004, 0x0005, 0x0006, 0x0009, 0x0018, 0x18a5, 0x0005, 0x0305, 0x0006, 0x0390, 0x0006, 0x1086, 0x0386, 0x0006, 0x0005, 0x0009, 0x0005, 0x7385, 0x0018, 0x1611, 0x0006, 0x0005, 0x0006, 0x0011, 0x0005, 0x0006, 0x0005, 0x0011, 0x0009, 0x0005, 0x0006, 0x7084, 0x0018, 0x4624, 0x6b46, 0x0005, 0x0006, 0x0004, 0x0006, 0x10c6, 0x0086, 0x0006, 0x0011, 0x0018, 0x0011, 0x0005, 0x0006, 0x6231, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0006, 0x0010, 0x0006, 0x0008, 0x0005, 0x0106, 0x0005, 0x0008, 0x0006, 0x0008, 0x1908, 0x0005, 0x0006, 0x0005, 0x0006, 0x0018, 0x0009, 0x0098, 0x0005, 0x2106, 0x0011, 0x0005, 0x4625, 0x4625, 0x0005, 0x0011, 0x0005, 0x44b1, 0x14b1, 0x44a5, 0x14d1, 0x0008, 0x0006, 0x2231, 0x4628, 0x14c8, 0x0011, 0x0008, 0x0011, 0x14b1, 0x18c5, 0x0011, 0x0009, 0x0005, 0x001a, 0x000b, 0x175c, 0x44d8, 0x18d1, 0x0228, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x44a5, 0x00d1, 0x0008, 0x0006, 0x0011, 0x18d1, 0x18d1, 0x4626, 0x00d1, 0x0011, 0x0005, 0x0225, 0x0011, 0x0009, 0x14c6, 0x18a5, 0x0018, 0x0011, 0x20c6, 0x0011, 0x0005, 0x44a5, 0x0225, 0x0005, 0x0011, 0x0005, 0x44a5, 0x0005, 0x1a31, 0x0005, 0x0008, 0x0006, 0x44c6, 0x2228, 0x4626, 0x0005, 0x0011, 0x18a5, 0x4626, 0x0009, 0x0358, 0x0011, 0x0005, 0x0006, 0x20d1, 0x0228, 0x0005, 0x4625, 0x4625, 0x0005, 0x0011, 0x0005, 0x44a5, 0x0005, 0x1a31, 0x0105, 0x1906, 0x44c6, 0x2111, 0x2111, 0x0006, 0x0011, 0x20c6, 0x0011, 0x14b1, 0x18c5, 0x0011, 0x0009, 0x00bc, 0x000b, 0x0011, 0x14d1, 0x0005, 0x0011, 0x0005, 0x44a5, 0x44a5, 0x1631, 0x0225, 0x4625, 0x14b1, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x1908, 0x0011, 0x0008, 0x4508, 0x44c8, 0x00b1, 0x0011, 0x0008, 0x0011, 0x0009, 0x000b, 0x001c, 0x035c, 0x0011, 0x2106, 0x00c8, 0x0005, 0x44a5, 0x0225, 0x0005, 0x0011, 0x0005, 0x0011, 0x18c5, 0x2106, 0x4508, 0x0006, 0x0011, 0x0006, 0x0011, 0x18d1, 0x0005, 0x0011, 0x18a5, 0x4626, 0x0009, 0x0011, 0x0018, 0x000b, 0x18bc, 0x6108, 0x0005, 0x44a5, 0x0225, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x20a6, 0x0008, 0x00d1, 0x4508, 0x0006, 0x0011, 0x0008, 0x0011, 0x1625, 0x0006, 0x0011, 0x0009, 0x14b1, 0x0011, 0x0006, 0x0008, 0x0005, 0x44a5, 0x0225, 0x0005, 0x18c5, 0x0008, 0x0006, 0x0111, 0x4508, 0x14c8, 0x463c, 0x1631, 0x20a5, 0x000b, 0x0005, 0x0006, 0x0011, 0x0009, 0x000b, 0x001c, 0x0005, 0x20d1, 0x0228, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x44b1, 0x0005, 0x0011, 0x1a31, 0x2231, 0x1908, 0x44c6, 0x0011, 0x0008, 0x0011, 0x0009, 0x2231, 0x0308, 0x0011, 0x0005, 0x18a5, 0x0006, 0x0011, 0x001a, 0x0005, 0x0004, 0x0006, 0x0018, 0x0009, 0x0018, 0x0011, 0x14b1, 0x0011, 0x0005, 0x0011, 0x0005, 0x0225, 0x0005, 0x18a5, 0x0006, 0x4625, 0x0005, 0x0091, 0x0006, 0x0011, 0x0009, 0x0011, 0x0005, 0x0011, 0x0005, 0x001c, 0x0018, 0x731c, 0x18dc, 0x001c, 0x0009, 0x000b, 0x00dc, 0x02d5, 0x0008, 0x0005, 0x0011, 0x0005, 0x0011, 0x0006, 0x0008, 0x0006, 0x60c6, 0x0005, 0x0006, 0x0011, 0x0006, 0x0011, 0x001c, 0x0006, 0x001c, 0x479c, 0x0018, 0x001c, 0x0018, 0x0011, 0x0005, 0x0008, 0x0006, 0x0008, 0x0006, 0x20c6, 0x18c8, 0x0005, 0x0009, 0x0018, 0x0005, 0x1908, 0x14a6, 0x18a5, 0x14c6, 0x0008, 0x0005, 0x0008, 0x0005, 0x0006, 0x0005, 0x2106, 0x0006, 0x0008, 0x14c8, 0x0009, 0x0008, 0x7386, 0x0001, 0x0221, 0x0011, 0x0631, 0x0002, 0x0098, 0x0002, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0225, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0225, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0006, 0x0018, 0x000b, 0x0011, 0x0005, 0x001c, 0x0011, 0x0001, 0x0011, 0x0002, 0x5231, 0x0005, 0x031c, 0x0005, 0x000c, 0x0005, 0x02d5, 0x0011, 0x0005, 0x0018, 0x000a, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0006, 0x0011, 0x0005, 0x0006, 0x0018, 0x0011, 0x0005, 0x0006, 0x0011, 0x0005, 0x44a5, 0x0225, 0x0006, 0x0011, 0x0005, 0x20c6, 0x0006, 0x0008, 0x1908, 0x0006, 0x0018, 0x1318, 0x1758, 0x4626, 0x0009, 0x0011, 0x000b, 0x0011, 0x0018, 0x5318, 0x1b18, 0x40c6, 0x0011, 0x0009, 0x0011, 0x0005, 0x0004, 0x0005, 0x0011, 0x0005, 0x0006, 0x0005, 0x00c5, 0x0011, 0x0005, 0x0011, 0x0005, 0x18d1, 0x2106, 0x1908, 0x2106, 0x4628, 0x2231, 0x00c8, 0x0008, 0x0006, 0x0011, 0x7231, 0x6311, 0x0009, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0009, 0x000b, 0x0011, 0x001c, 0x0005, 0x20c6, 0x44c8, 0x6311, 0x0005, 0x00c8, 0x0006, 0x0226, 0x20c8, 0x0006, 0x0008, 0x0006, 0x4626, 0x0009, 0x0011, 0x0009, 0x0011, 0x0018, 0x0004, 0x0018, 0x0011, 0x0006, 0x1cc6, 0x0011, 0x0006, 0x0008, 0x0005, 0x0106, 0x0006, 0x0106, 0x0008, 0x1908, 0x0005, 0x0011, 0x0009, 0x0018, 0x001c, 0x0006, 0x001c, 0x0011, 0x20c6, 0x0005, 0x18c8, 0x20c6, 0x18c8, 0x14a6, 0x0009, 0x0005, 0x1906, 0x1908, 0x0006, 0x0008, 0x0011, 0x0018, 0x0005, 0x0008, 0x0006, 0x0008, 0x0006, 0x0011, 0x0018, 0x0009, 0x0011, 0x0005, 0x0009, 0x0005, 0x0004, 0x0018, 0x0002, 0x0011, 0x0001, 0x0011, 0x0001, 0x0018, 0x0011, 0x0006, 0x0018, 0x0006, 0x0008, 0x0006, 0x0005, 0x0006, 0x0005, 0x18a5, 0x18c8, 0x0005, 0x0011, 0x0002, 0x0004, 0x0002, 0x0004, 0x0002, 0x0004, 0x0006, 0x0011, 0x0006, 0x0041, 0x0002, 0x0022, 0x0002, 0x0001, 0x0002, 0x0011, 0x0001, 0x0011, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0011, 0x0001, 0x0011, 0x0002, 0x0031, 0x0002, 0x0001, 0x0002, 0x0011, 0x0002, 0x0003, 0x0002, 0x0003, 0x0002, 0x0003, 0x0002, 0x4442, 0x0001, 0x0b63, 0x001b, 0x0002, 0x4442, 0x0001, 0x6f63, 0x085b, 0x4442, 0x0851, 0x0001, 0x0011, 0x001b, 0x0002, 0x0001, 0x001b, 0x0a31, 0x4442, 0x0001, 0x6f63, 0x0011, 0x000c, 0x0010, 0x0014, 0x0018, 0x57dd, 0x57dd, 0x0018, 0x01cd, 0x0010, 0x000c, 0x0018, 0x03dd, 0x0018, 0x5ef8, 0x6718, 0x02d5, 0x0018, 0x5f19, 0x0018, 0x000c, 0x0010, 0x0011, 0x0010, 0x008b, 0x0011, 0x000b, 0x0019, 0x12d5, 0x000b, 0x0019, 0x46d5, 0x0004, 0x0011, 0x001a, 0x0011, 0x0006, 0x0007, 0x0006, 0x0007, 0x0006, 0x0011, 0x079c, 0x079c, 0x0422, 0x0841, 0x0821, 0x703c, 0x0019, 0x0001, 0x001c, 0x003c, 0x0001, 0x005c, 0x0001, 0x0002, 0x0005, 0x7382, 0x0422, 0x0019, 0x0001, 0x0002, 0x033c, 0x005c, 0x000b, 0x000a, 0x0041, 0x000a, 0x738b, 0x0011, 0x0019, 0x001c, 0x0019, 0x001c, 0x679c, 0x001c, 0x0019, 0x001c, 0x673c, 0x033c, 0x001c, 0x0019, 0x001c, 0x02d5, 0x001c, 0x0019, 0x001c, 0x02d5, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x0011, 0x001c, 0x0011, 0x000b, 0x001c, 0x000b, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x02d5, 0x000b, 0x001c, 0x0019, 0x02d5, 0x0019, 0x02d5, 0x0019, 0x001c, 0x0019, 0x02d5, 0x0019, 0x02d5, 0x0019, 0x02d5, 0x0019, 0x001c, 0x0019, 0x001c, 0x0019, 0x001c, 0x0011, 0x001c, 0x0011, 0x001c, 0x0001, 0x0011, 0x0002, 0x0622, 0x0001, 0x0002, 0x0022, 0x0001, 0x0822, 0x0002, 0x0004, 0x0001, 0x0041, 0x0002, 0x001c, 0x0041, 0x0006, 0x0041, 0x0011, 0x0018, 0x2f18, 0x0002, 0x0222, 0x0011, 0x0a31, 0x0005, 0x0011, 0x0304, 0x0011, 0x0006, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0006, 0x0018, 0x03dd, 0x0018, 0x7bb8, 0x0018, 0x5318, 0x7bb8, 0x7bb8, 0x02d5, 0x0018, 0x0004, 0x0018, 0x0014, 0x0018, 0x5714, 0x0018, 0x7398, 0x0011, 0x001c, 0x0011, 0x001c, 0x0011, 0x001c, 0x0011, 0x001c, 0x0011, 0x630c, 0x1398, 0x0145, 0x02d5, 0x001c, 0x02d5, 0x52d5, 0x0396, 0x000a, 0x0006, 0x5108, 0x0004, 0x2b9c, 0x114a, 0x7305, 0x023c, 0x0005, 0x1a31, 0x6f66, 0x1484, 0x0014, 0x0005, 0x1098, 0x00a4, 0x0011, 0x0005, 0x0011, 0x0005, 0x7391, 0x000b, 0x001c, 0x0005, 0x001c, 0x0011, 0x0005, 0x001c, 0x0011, 0x000b, 0x001c, 0x000b, 0x001c, 0x000b, 0x001c, 0x000b, 0x001c, 0x000b, 0x001c, 0x0005, 0x001c, 0x0005, 0x0011, 0x0005, 0x0004, 0x0005, 0x0011, 0x001c, 0x0011, 0x0005, 0x0004, 0x0018, 0x0005, 0x0004, 0x0018, 0x0005, 0x0009, 0x0005, 0x0011, 0x0041, 0x1cc5, 0x60e7, 0x0006, 0x0098, 0x0041, 0x0004, 0x0006, 0x0005, 0x000a, 0x0006, 0x0018, 0x0011, 0x001b, 0x0004, 0x001b, 0x0041, 0x0002, 0x0022, 0x0004, 0x0002, 0x0022, 0x0041, 0x6f64, 0x0041, 0x0025, 0x0822, 0x0022, 0x0001, 0x0002, 0x0001, 0x0041, 0x0011, 0x0441, 0x0821, 0x0002, 0x0011, 0x1441, 0x0884, 0x0005, 0x00c5, 0x18a5, 0x18a5, 0x0005, 0x1908, 0x0106, 0x001c, 0x0006, 0x0011, 0x000b, 0x6b9c, 0x0011, 0x0005, 0x0018, 0x0011, 0x0008, 0x0005, 0x0008, 0x0006, 0x0011, 0x0018, 0x0009, 0x0011, 0x0006, 0x0005, 0x0018, 0x1705, 0x0006, 0x0009, 0x0005, 0x0006, 0x0018, 0x0005, 0x0006, 0x0008, 0x0011, 0x0018, 0x0005, 0x0011, 0x0006, 0x0008, 0x0005, 0x2106, 0x0006, 0x0008, 0x0006, 0x0008, 0x0018, 0x0091, 0x0009, 0x0011, 0x0018, 0x0005, 0x0086, 0x0005, 0x0009, 0x0005, 0x0011, 0x0005, 0x0006, 0x2106, 0x2106, 0x0006, 0x0011, 0x0005, 0x0006, 0x0005, 0x0106, 0x0011, 0x0009, 0x0011, 0x0018, 0x0005, 0x0004, 0x0005, 0x001c, 0x1905, 0x0008, 0x0005, 0x18a6, 0x14a6, 0x0006, 0x0005, 0x18c5, 0x0005, 0x0011, 0x10a5, 0x0018, 0x0005, 0x18c8, 0x6308, 0x1085, 0x00c8, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0002, 0x001b, 0x0004, 0x0002, 0x6f64, 0x0011, 0x0002, 0x0005, 0x1908, 0x1918, 0x0011, 0x0009, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0013, 0x0012, 0x0005, 0x0011, 0x0005, 0x0011, 0x0002, 0x0011, 0x0002, 0x0011, 0x00c5, 0x0005, 0x0019, 0x0005, 0x0011, 0x0005, 0x0011, 0x1625, 0x0005, 0x001b, 0x0011, 0x0005, 0x02b6, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x039a, 0x0011, 0x0006, 0x0018, 0x5ab8, 0x0011, 0x0006, 0x5298, 0x0017, 0x02d5, 0x5718, 0x6316, 0x5f18, 0x62f7, 0x4718, 0x5318, 0x02d5, 0x0018, 0x6699, 0x0239, 0x6358, 0x0011, 0x0005, 0x0011, 0x0005, 0x4231, 0x0018, 0x6b18, 0x5ab8, 0x5319, 0x0018, 0x0009, 0x0018, 0x0019, 0x0018, 0x0001, 0x5b15, 0x02fb, 0x0002, 0x5b35, 0x0019, 0x62d5, 0x0018, 0x0005, 0x0004, 0x0005, 0x0004, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x0011, 0x0005, 0x4625, 0x44a5, 0x6a31, 0x6f3a, 0x6b5c, 0x0391, 0x0019, 0x001c, 0x0011, 0x0010, 0x001c, 0x0011, ) private fun categoryValueFrom(code: Int, ch: Int): Int { return when { code < 0x20 -> code code < 0x400 -> if ((ch and 1) == 1) code shr 5 else code and 0x1f else -> when (ch % 3) { 2 -> code shr 10 1 -> (code shr 5) and 0x1f else -> code and 0x1f } } } /** * Returns the Unicode general category of this character as an Int. */ internal fun Char.getCategoryValue(): Int { val ch = this.toInt() val index = binarySearchRange(rangeStart, ch) val start = rangeStart[index] val code = rangeCategory[index] val value = categoryValueFrom(code, ch - start) return if (value == 17) CharCategory.UNASSIGNED.value else value } ================================================ FILE: runtime/src/main/kotlin/generated/_CollectionsNative.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.collections // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // import kotlin.ranges.contains import kotlin.ranges.reversed /** * Reverses elements in the list in-place. */ public actual fun MutableList.reverse(): Unit { val midPoint = (size / 2) - 1 if (midPoint < 0) return var reverseIndex = lastIndex for (index in 0..midPoint) { val tmp = this[index] this[index] = this[reverseIndex] this[reverseIndex] = tmp reverseIndex-- } } ================================================ FILE: runtime/src/main/kotlin/generated/_ComparisonsNative.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.comparisons // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // /** * Returns the greater of two values. * * If values are equal, returns the first one. */ @SinceKotlin("1.1") public actual fun > maxOf(a: T, b: T): T { return if (a >= b) a else b } /** * Returns the greater of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Byte, b: Byte): Byte { return maxOf(a.toInt(), b.toInt()).toByte() } /** * Returns the greater of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Short, b: Short): Short { return maxOf(a.toInt(), b.toInt()).toShort() } /** * Returns the greater of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Int, b: Int): Int { return if (a >= b) a else b } /** * Returns the greater of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Long, b: Long): Long { return if (a >= b) a else b } /** * Returns the greater of two values. * * If either value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Float, b: Float): Float { return if (a.compareTo(b) >= 0) a else b } /** * Returns the greater of two values. * * If either value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Double, b: Double): Double { return if (a.compareTo(b) >= 0) a else b } /** * Returns the greater of three values. * * If there are multiple equal maximal values, returns the first of them. */ @SinceKotlin("1.1") public actual fun > maxOf(a: T, b: T, c: T): T { return maxOf(a, maxOf(b, c)) } /** * Returns the greater of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Byte, b: Byte, c: Byte): Byte { return maxOf(a.toInt(), maxOf(b.toInt(), c.toInt())).toByte() } /** * Returns the greater of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Short, b: Short, c: Short): Short { return maxOf(a.toInt(), maxOf(b.toInt(), c.toInt())).toShort() } /** * Returns the greater of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Int, b: Int, c: Int): Int { return maxOf(a, maxOf(b, c)) } /** * Returns the greater of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Long, b: Long, c: Long): Long { return maxOf(a, maxOf(b, c)) } /** * Returns the greater of three values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Float, b: Float, c: Float): Float { return maxOf(a, maxOf(b, c)) } /** * Returns the greater of three values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun maxOf(a: Double, b: Double, c: Double): Double { return maxOf(a, maxOf(b, c)) } /** * Returns the greater of the given values. * * If there are multiple equal maximal values, returns the first of them. */ @SinceKotlin("1.4") public actual fun > maxOf(a: T, vararg other: T): T { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. */ @SinceKotlin("1.4") public actual fun maxOf(a: Byte, vararg other: Byte): Byte { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. */ @SinceKotlin("1.4") public actual fun maxOf(a: Short, vararg other: Short): Short { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. */ @SinceKotlin("1.4") public actual fun maxOf(a: Int, vararg other: Int): Int { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. */ @SinceKotlin("1.4") public actual fun maxOf(a: Long, vararg other: Long): Long { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.4") public actual fun maxOf(a: Float, vararg other: Float): Float { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the greater of the given values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.4") public actual fun maxOf(a: Double, vararg other: Double): Double { var max = a for (e in other) max = maxOf(max, e) return max } /** * Returns the smaller of two values. * * If values are equal, returns the first one. */ @SinceKotlin("1.1") public actual fun > minOf(a: T, b: T): T { return if (a <= b) a else b } /** * Returns the smaller of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Byte, b: Byte): Byte { return minOf(a.toInt(), b.toInt()).toByte() } /** * Returns the smaller of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Short, b: Short): Short { return minOf(a.toInt(), b.toInt()).toShort() } /** * Returns the smaller of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Int, b: Int): Int { return if (a <= b) a else b } /** * Returns the smaller of two values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Long, b: Long): Long { return if (a <= b) a else b } /** * Returns the smaller of two values. * * If either value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Float, b: Float): Float { return when { a.isNaN() -> a b.isNaN() -> b else -> if (a.compareTo(b) <= 0) a else b } } /** * Returns the smaller of two values. * * If either value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Double, b: Double): Double { return when { a.isNaN() -> a b.isNaN() -> b else -> if (a.compareTo(b) <= 0) a else b } } /** * Returns the smaller of three values. * * If there are multiple equal minimal values, returns the first of them. */ @SinceKotlin("1.1") public actual fun > minOf(a: T, b: T, c: T): T { return minOf(a, minOf(b, c)) } /** * Returns the smaller of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Byte, b: Byte, c: Byte): Byte { return minOf(a.toInt(), minOf(b.toInt(), c.toInt())).toByte() } /** * Returns the smaller of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Short, b: Short, c: Short): Short { return minOf(a.toInt(), minOf(b.toInt(), c.toInt())).toShort() } /** * Returns the smaller of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Int, b: Int, c: Int): Int { return minOf(a, minOf(b, c)) } /** * Returns the smaller of three values. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Long, b: Long, c: Long): Long { return minOf(a, minOf(b, c)) } /** * Returns the smaller of three values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Float, b: Float, c: Float): Float { return minOf(a, minOf(b, c)) } /** * Returns the smaller of three values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun minOf(a: Double, b: Double, c: Double): Double { return minOf(a, minOf(b, c)) } /** * Returns the smaller of the given values. * * If there are multiple equal minimal values, returns the first of them. */ @SinceKotlin("1.4") public actual fun > minOf(a: T, vararg other: T): T { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. */ @SinceKotlin("1.4") public actual fun minOf(a: Byte, vararg other: Byte): Byte { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. */ @SinceKotlin("1.4") public actual fun minOf(a: Short, vararg other: Short): Short { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. */ @SinceKotlin("1.4") public actual fun minOf(a: Int, vararg other: Int): Int { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. */ @SinceKotlin("1.4") public actual fun minOf(a: Long, vararg other: Long): Long { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.4") public actual fun minOf(a: Float, vararg other: Float): Float { var min = a for (e in other) min = minOf(min, e) return min } /** * Returns the smaller of the given values. * * If any value is `NaN`, returns `NaN`. */ @SinceKotlin("1.4") public actual fun minOf(a: Double, vararg other: Double): Double { var min = a for (e in other) min = minOf(min, e) return min } ================================================ FILE: runtime/src/main/kotlin/generated/_DigitChars.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 37 ranges totally @SharedImmutable private val rangeStart = intArrayOf( 0x0030, 0x0660, 0x06f0, 0x07c0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66, 0x0ce6, 0x0d66, 0x0de6, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x1090, 0x17e0, 0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, 0x1c40, 0x1c50, 0xa620, 0xa8d0, 0xa900, 0xa9d0, 0xa9f0, 0xaa50, 0xabf0, 0xff10, ) internal fun binarySearchRange(array: IntArray, needle: Int): Int { var bottom = 0 var top = array.size - 1 var middle = -1 var value = 0 while (bottom <= top) { middle = (bottom + top) / 2 value = array[middle] if (needle > value) bottom = middle + 1 else if (needle == value) return middle else top = middle - 1 } return middle - (if (needle < value) 1 else 0) } /** * Returns `true` if this character is a digit. */ internal fun Char.isDigitImpl(): Boolean { val ch = this.toInt() val index = binarySearchRange(rangeStart, ch) val high = rangeStart[index] + 9 return ch <= high } ================================================ FILE: runtime/src/main/kotlin/generated/_LetterChars.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 222 ranges totally @SharedImmutable private val rangeStart = intArrayOf( 0x0041, 0x0061, 0x00aa, 0x00ba, 0x00c0, 0x00d8, 0x00df, 0x00f8, 0x00ff, 0x0138, 0x0149, 0x0172, 0x0181, 0x0190, 0x019f, 0x01ae, 0x01bd, 0x01cc, 0x01dd, 0x01e9, 0x01f8, 0x0231, 0x0240, 0x024f, 0x0294, 0x02a3, 0x02b2, 0x02ec, 0x0370, 0x037f, 0x038e, 0x039d, 0x03ac, 0x03c8, 0x03d7, 0x03ee, 0x03fd, 0x0430, 0x045f, 0x048a, 0x04c1, 0x04cf, 0x0531, 0x0559, 0x0560, 0x05d0, 0x066e, 0x06e5, 0x06ff, 0x074d, 0x07f4, 0x081a, 0x0840, 0x08b6, 0x0950, 0x0985, 0x09aa, 0x09bd, 0x09df, 0x0a05, 0x0a2a, 0x0a39, 0x0a72, 0x0a93, 0x0ab5, 0x0ae0, 0x0b0f, 0x0b32, 0x0b5c, 0x0b83, 0x0b92, 0x0ba3, 0x0bd0, 0x0c12, 0x0c58, 0x0c85, 0x0caa, 0x0cde, 0x0d04, 0x0d3d, 0x0d5f, 0x0d9a, 0x0dc0, 0x0e40, 0x0e86, 0x0ea7, 0x0ec0, 0x0f00, 0x0f88, 0x1050, 0x1065, 0x108e, 0x10a0, 0x10bf, 0x10d0, 0x10f1, 0x1100, 0x124a, 0x125a, 0x1290, 0x12c0, 0x12d8, 0x1380, 0x13a0, 0x13f8, 0x1401, 0x166f, 0x16f1, 0x1720, 0x176e, 0x17dc, 0x1887, 0x1900, 0x1980, 0x1a20, 0x1b45, 0x1bba, 0x1c5a, 0x1c80, 0x1c90, 0x1cbd, 0x1ce9, 0x1cfa, 0x1d00, 0x1d2c, 0x1d6a, 0x1d79, 0x1d9b, 0x1e00, 0x1e95, 0x1e9d, 0x1f00, 0x1f0f, 0x1f20, 0x1f2f, 0x1f3e, 0x1f4d, 0x1f5d, 0x1f6c, 0x1f7b, 0x1f8a, 0x1f99, 0x1fa8, 0x1fae, 0x1fbe, 0x1fd0, 0x1fe0, 0x1ff2, 0x2071, 0x2102, 0x210f, 0x2124, 0x2131, 0x2145, 0x2183, 0x2c00, 0x2c30, 0x2c60, 0x2c6f, 0x2c7e, 0x2c80, 0x2ce4, 0x2cf3, 0x2d00, 0x2d27, 0x2d36, 0x2da0, 0x2db8, 0x2dd0, 0x3005, 0x3041, 0x30fc, 0x31a0, 0x3400, 0x4e00, 0xa000, 0xa4d0, 0xa610, 0xa640, 0xa66e, 0xa680, 0xa69c, 0xa722, 0xa731, 0xa770, 0xa77f, 0xa78e, 0xa79d, 0xa7ac, 0xa7bb, 0xa7ca, 0xa7f5, 0xa804, 0xa840, 0xa8fb, 0xa930, 0xa9cf, 0xa9fa, 0xaa44, 0xaa7e, 0xaab9, 0xaadb, 0xab01, 0xab20, 0xab30, 0xab5c, 0xab70, 0xabc0, 0xd7b0, 0xf900, 0xfa70, 0xfb00, 0xfb13, 0xfb22, 0xfb3e, 0xfb4d, 0xfd50, 0xfe70, 0xff21, 0xff41, 0xff66, 0xffd2, ) @SharedImmutable private val rangeLength = intArrayOf( 0x001a, 0x001a, 0x000c, 0x0001, 0x0017, 0x0007, 0x0018, 0x0007, 0x0039, 0x0011, 0x0029, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x0011, 0x000c, 0x000f, 0x0039, 0x000f, 0x000f, 0x0045, 0x000f, 0x000f, 0x0033, 0x0003, 0x000e, 0x000e, 0x000f, 0x000f, 0x001c, 0x000f, 0x0017, 0x000f, 0x0033, 0x002f, 0x0023, 0x0037, 0x000e, 0x0061, 0x0026, 0x0001, 0x0029, 0x007b, 0x0068, 0x0018, 0x0031, 0x009e, 0x0022, 0x000f, 0x0075, 0x0088, 0x0031, 0x0024, 0x0010, 0x0021, 0x001e, 0x0024, 0x000f, 0x0026, 0x0020, 0x0021, 0x001c, 0x002d, 0x0022, 0x000c, 0x0016, 0x000e, 0x000e, 0x0017, 0x0041, 0x002c, 0x0029, 0x0024, 0x0014, 0x0015, 0x0037, 0x001a, 0x0038, 0x0024, 0x0074, 0x0045, 0x0020, 0x0017, 0x0020, 0x006d, 0x00b8, 0x0012, 0x001d, 0x0001, 0x001f, 0x000f, 0x0021, 0x000f, 0x0149, 0x000f, 0x0034, 0x002f, 0x0017, 0x0083, 0x0010, 0x0056, 0x0006, 0x026c, 0x007c, 0x0021, 0x004d, 0x006a, 0x00a9, 0x006f, 0x0075, 0x0097, 0x0114, 0x006b, 0x0096, 0x0024, 0x0009, 0x002b, 0x0003, 0x000e, 0x0001, 0x002c, 0x003e, 0x000f, 0x0022, 0x0025, 0x0095, 0x0008, 0x0063, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x0006, 0x000f, 0x000f, 0x000c, 0x000d, 0x000b, 0x002c, 0x000d, 0x000f, 0x000d, 0x000f, 0x000a, 0x0002, 0x002f, 0x002f, 0x000f, 0x000f, 0x0002, 0x0064, 0x000f, 0x0001, 0x0026, 0x000f, 0x0061, 0x0017, 0x0017, 0x0060, 0x0038, 0x00ba, 0x0093, 0x0060, 0x19c0, 0x51fd, 0x048d, 0x013d, 0x001c, 0x002e, 0x0012, 0x001c, 0x0084, 0x000f, 0x003f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x0001, 0x000f, 0x001f, 0x00b8, 0x002b, 0x0083, 0x0021, 0x0049, 0x0037, 0x0039, 0x000a, 0x001a, 0x0016, 0x000f, 0x002b, 0x000e, 0x0050, 0x2be4, 0x004c, 0x016e, 0x006a, 0x0007, 0x000f, 0x001b, 0x000f, 0x01f1, 0x00ac, 0x008d, 0x001a, 0x001a, 0x006a, 0x000b, ) @SharedImmutable private val rangeCategory = intArrayOf( 0x0006, 0x0005, 0x1400003, 0x0007, 0x0006, 0x0006, 0x0005, 0x0005, 0x0019, 0x0019, 0x0019, 0x5599a666, 0x696a699a, 0x5a56a69a, 0x5966999a, 0x6d699a9a, 0x79e7bfd5, 0x0019, 0x0019, 0x699e5999, 0x0016, 0x5a695559, 0x66666a99, 0x0005, 0x55555557, 0x7d555555, 0x70c0840, 0x0013, 0x15706366, 0x18a88002, 0x6aaaaa9a, 0x6aaaa2aa, 0x0005, 0x56a59555, 0x0019, 0x56986556, 0x0006, 0x0005, 0x0019, 0x0016, 0x0016, 0x0019, 0x0006, 0x0007, 0x0005, 0x1684086c, 0xe30208, 0x5020e08, 0x812004, 0xc011764, 0x2810808, 0x1811204, 0x1a8b0e64, 0x1b67848, 0x78a0e04, 0x1020420, 0x181021c, 0x6812004, 0x5021c0c, 0x1020818, 0x73cf3fff, 0x843e04, 0x89200c, 0x870258, 0x9010614, 0x5812e08, 0x960408, 0x1850208, 0x7830208, 0x1860204, 0x1f33c0ff, 0x1830608, 0x886804, 0x190025c, 0xf020a0c, 0x830220, 0x1850228, 0x7820204, 0x830224, 0x2812004, 0x286300c, 0x890260, 0xb0741c, 0x82741c, 0x980214, 0x4820228, 0xa810214, 0x887e04, 0xa2be614, 0x1840818, 0x2030e08, 0x0007, 0x0006, 0x60022aaa, 0x0005, 0x55c55555, 0x0007, 0x870410, 0xa90410, 0x1040284, 0x1040204, 0x10402e4, 0x0007, 0x0006, 0x0005, 0x0007, 0x29a0244, 0x8d0e20, 0x7121c48, 0x11b41e0c, 0x3d98604, 0x2810288, 0x11e627c, 0x1b1a08b0, 0x2e81a4d4, 0x69e6e1c, 0x14a434b0, 0x0007, 0x0005, 0x0006, 0x0006, 0x860210, 0x0007, 0x0005, 0x0007, 0x75555557, 0x0005, 0x0007, 0x0016, 0x0005, 0x0019, 0x6aaa5555, 0x6aa81556, 0x6aaa5555, 0x6aa95556, 0x6aa0555a, 0x62155542, 0x6a955562, 0x555555aa, 0x7d555415, 0x75555fff, 0x55557fff, 0x0007, 0x7aa5155f, 0x7aa51501, 0x1aa5055, 0x6aa5555, 0x7aa515, 0x8011a04, 0x5a90802, 0x6aa021a9, 0x64aa222, 0x6941ff6a, 0x140156, 0x0016, 0x0006, 0x0005, 0x699996a6, 0x7d55659a, 0x0006, 0x0016, 0x60198001, 0x0005, 0x0005, 0x7ffc1001, 0x8010ec8, 0x87021c, 0x87021c, 0x2807021c, 0x2855408, 0x830d58, 0xab0a10, 0x6080, 0x0007, 0x0007, 0x0007, 0x04b8, 0x1440, 0x0016, 0x2004, 0x0016, 0x18c60408, 0x56666666, 0x0019, 0x69995557, 0x660d9999, 0x6666566d, 0x69999999, 0x6666aa6a, 0x66a98199, 0x0005, 0x73fff7f6, 0x840208, 0x1f321cd0, 0x5820204, 0x39d325c, 0x852004, 0xba90214, 0x1972820, 0x18102c8, 0x810414, 0x38b040c, 0x1060418, 0x021c, 0x0005, 0x1d5555ff, 0x0005, 0x3a8c, 0x085c, 0x0007, 0x0007, 0x0005, 0x7f300155, 0x8d021c, 0x7fff3cf3, 0x4394, 0x14360500, 0x0214, 0x0006, 0x0005, 0x1060764, 0x0418, ) /** * Returns `true` if this character is a letter. */ internal fun Char.isLetterImpl(): Boolean { return getLetterType() != 0 } /** * Returns `true` if this character is a lower case letter. */ internal fun Char.isLowerCaseImpl(): Boolean { return getLetterType() == 1 } /** * Returns `true` if this character is an upper case letter. */ internal fun Char.isUpperCaseImpl(): Boolean { return getLetterType() == 2 } /** * Returns * - `1` if the character is a lower case letter, * - `2` if the character is an upper case letter, * - `3` if the character is a letter but not a lower or upper case letter, * - `0` otherwise. */ private fun Char.getLetterType(): Int { val ch = this.toInt() val index = binarySearchRange(rangeStart, ch) val rangeStart = rangeStart[index] val rangeEnd = rangeStart + rangeLength[index] - 1 val code = rangeCategory[index] if (ch > rangeEnd) { return 0 } val lastTwoBits = code and 0x3 if (lastTwoBits == 0) { // gap pattern var shift = 2 var threshold = rangeStart for (i in 0..1) { threshold += (code shr shift) and 0x7f if (threshold > ch) { return 3 } shift += 7 threshold += (code shr shift) and 0x7f if (threshold > ch) { return 0 } shift += 7 } return 3 } if (code <= 0x7) { return lastTwoBits } val distance = (ch - rangeStart) val shift = if (code <= 0x1F) distance % 2 else distance return (code shr (2 * shift)) and 0x3 } ================================================ FILE: runtime/src/main/kotlin/generated/_LowercaseMappings.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 174 ranges totally @SharedImmutable private val rangeStart = intArrayOf( 0x0041, 0x00c0, 0x00d8, 0x0100, 0x0130, 0x0132, 0x0139, 0x014a, 0x0178, 0x0179, 0x0181, 0x0182, 0x0186, 0x0187, 0x0189, 0x018b, 0x018e, 0x018f, 0x0190, 0x0191, 0x0193, 0x0194, 0x0196, 0x0197, 0x0198, 0x019c, 0x019d, 0x019f, 0x01a0, 0x01a6, 0x01a7, 0x01a9, 0x01ac, 0x01ae, 0x01af, 0x01b1, 0x01b3, 0x01b7, 0x01b8, 0x01c4, 0x01c5, 0x01c7, 0x01c8, 0x01ca, 0x01cb, 0x01de, 0x01f1, 0x01f2, 0x01f6, 0x01f7, 0x01f8, 0x0220, 0x0222, 0x023a, 0x023b, 0x023d, 0x023e, 0x0241, 0x0243, 0x0244, 0x0245, 0x0246, 0x0370, 0x0376, 0x037f, 0x0386, 0x0388, 0x038c, 0x038e, 0x0391, 0x03a3, 0x03cf, 0x03d8, 0x03f4, 0x03f7, 0x03f9, 0x03fa, 0x03fd, 0x0400, 0x0410, 0x0460, 0x048a, 0x04c0, 0x04c1, 0x04d0, 0x0531, 0x10a0, 0x10c7, 0x13a0, 0x13f0, 0x1c90, 0x1cbd, 0x1e00, 0x1e9e, 0x1ea0, 0x1f08, 0x1f18, 0x1f28, 0x1f38, 0x1f48, 0x1f59, 0x1f68, 0x1f88, 0x1f98, 0x1fa8, 0x1fb8, 0x1fba, 0x1fbc, 0x1fc8, 0x1fcc, 0x1fd8, 0x1fda, 0x1fe8, 0x1fea, 0x1fec, 0x1ff8, 0x1ffa, 0x1ffc, 0x2126, 0x212a, 0x212b, 0x2132, 0x2160, 0x2183, 0x24b6, 0x2c00, 0x2c60, 0x2c62, 0x2c63, 0x2c64, 0x2c67, 0x2c6d, 0x2c6e, 0x2c6f, 0x2c70, 0x2c72, 0x2c7e, 0x2c80, 0x2ceb, 0x2cf2, 0xa640, 0xa680, 0xa722, 0xa732, 0xa779, 0xa77d, 0xa77e, 0xa78b, 0xa78d, 0xa790, 0xa796, 0xa7aa, 0xa7ab, 0xa7ac, 0xa7ad, 0xa7ae, 0xa7b0, 0xa7b1, 0xa7b2, 0xa7b3, 0xa7b4, 0xa7c2, 0xa7c4, 0xa7c5, 0xa7c6, 0xa7c7, 0xa7f5, 0xff21, 0x10400, 0x104b0, 0x10c80, 0x118a0, 0x16e40, 0x1e900, ) @SharedImmutable private val rangeLength = intArrayOf( 0x2011a, 0x20117, 0x20107, 0x122f, -0xc6eff, 0x1205, 0x120f, 0x122d, -0x78eff, 0x1205, 0xd2101, 0x1203, 0xce101, 0x1101, 0xcd102, 0x1101, 0x4f101, 0xca101, 0xcb101, 0x1101, 0xcd101, 0xcf101, 0xd3101, 0xd1101, 0x1101, 0xd3101, 0xd5101, 0xd6101, 0x1205, 0xda101, 0x1101, 0xda101, 0x1101, 0xda101, 0x1101, 0xd9102, 0x1203, 0xdb101, 0x1405, 0x2101, 0x1101, 0x2101, 0x1101, 0x2101, 0x1211, 0x1211, 0x2101, 0x1203, -0x60eff, -0x37eff, 0x1227, -0x81eff, 0x1211, 0x2a2b101, 0x1101, -0xa2eff, 0x2a28101, 0x1101, -0xc2eff, 0x45101, 0x47101, 0x1209, 0x1203, 0x1101, 0x74101, 0x26101, 0x25103, 0x40101, 0x3f102, 0x20111, 0x20109, 0x8101, 0x1217, -0x3beff, 0x1101, -0x6eff, 0x1101, -0x81efd, 0x50110, 0x20120, 0x1221, 0x1235, 0xf101, 0x120d, 0x125f, 0x30126, 0x1c60126, 0x1c60607, 0x97d0150, 0x8106, -0xbbfed5, -0xbbfefd, 0x1295, -0x1dbeeff, 0x125f, -0x7ef8, -0x7efa, -0x7ef8, -0x7ef8, -0x7efa, -0x7df9, -0x7ef8, -0x7ef8, -0x7ef8, -0x7ef8, -0x7efe, -0x49efe, -0x8eff, -0x55efc, -0x8eff, -0x7efe, -0x63efe, -0x7efe, -0x6fefe, -0x6eff, -0x7fefe, -0x7defe, -0x8eff, -0x1d5ceff, -0x20beeff, -0x2045eff, 0x1c101, 0x10110, 0x1101, 0x1a11a, 0x3012f, 0x1101, -0x29f6eff, -0xee5eff, -0x29e6eff, 0x1205, -0x2a1beff, -0x29fceff, -0x2a1eeff, -0x2a1deff, 0x1304, -0x2a3eefe, 0x1263, 0x1203, 0x1101, 0x122d, 0x121b, 0x120d, 0x123d, 0x1203, -0x8a03eff, 0x1209, 0x1101, -0xa527eff, 0x1203, 0x1213, -0xa543eff, -0xa54eeff, -0xa54aeff, -0xa540eff, -0xa543eff, -0xa511eff, -0xa529eff, -0xa514eff, 0x3a0101, 0x120b, 0x1101, -0x2feff, -0xa542eff, -0x8a37eff, 0x1203, 0x1101, 0x2011a, 0x28128, 0x28124, 0x40133, 0x20120, 0x20120, 0x22122, ) internal fun Int.lowercaseCodePoint(): Int { if (this in 0x41..0x5a) { return this + 32 } if (this < 0x80) { return this } val index = binarySearchRange(rangeStart, this) return equalDistanceMapping(this, rangeStart[index], rangeLength[index]) } internal fun Char.lowercaseCharImpl(): Char { return toInt().lowercaseCodePoint().toChar() } ================================================ FILE: runtime/src/main/kotlin/generated/_OneToManyLowercaseMappings.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 1 mappings totally internal fun Char.lowercaseImpl(): String { if (this == '\u0130') { return "\u0069\u0307" } return lowercaseCharImpl().toString() } ================================================ FILE: runtime/src/main/kotlin/generated/_OneToManyUppercaseMappings.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 102 mappings totally @SharedImmutable private val keys = intArrayOf( 0x00df, 0x0149, 0x01f0, 0x0390, 0x03b0, 0x0587, 0x1e96, 0x1e97, 0x1e98, 0x1e99, 0x1e9a, 0x1f50, 0x1f52, 0x1f54, 0x1f56, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb6, 0x1fb7, 0x1fbc, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc6, 0x1fc7, 0x1fcc, 0x1fd2, 0x1fd3, 0x1fd6, 0x1fd7, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe6, 0x1fe7, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff6, 0x1ff7, 0x1ffc, 0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb05, 0xfb06, 0xfb13, 0xfb14, 0xfb15, 0xfb16, 0xfb17, ) @SharedImmutable private val values = arrayOf( "\u0053\u0053", "\u02BC\u004E", "\u004A\u030C", "\u0399\u0308\u0301", "\u03A5\u0308\u0301", "\u0535\u0552", "\u0048\u0331", "\u0054\u0308", "\u0057\u030A", "\u0059\u030A", "\u0041\u02BE", "\u03A5\u0313", "\u03A5\u0313\u0300", "\u03A5\u0313\u0301", "\u03A5\u0313\u0342", "\u1F08\u0399", "\u1F09\u0399", "\u1F0A\u0399", "\u1F0B\u0399", "\u1F0C\u0399", "\u1F0D\u0399", "\u1F0E\u0399", "\u1F0F\u0399", "\u1F08\u0399", "\u1F09\u0399", "\u1F0A\u0399", "\u1F0B\u0399", "\u1F0C\u0399", "\u1F0D\u0399", "\u1F0E\u0399", "\u1F0F\u0399", "\u1F28\u0399", "\u1F29\u0399", "\u1F2A\u0399", "\u1F2B\u0399", "\u1F2C\u0399", "\u1F2D\u0399", "\u1F2E\u0399", "\u1F2F\u0399", "\u1F28\u0399", "\u1F29\u0399", "\u1F2A\u0399", "\u1F2B\u0399", "\u1F2C\u0399", "\u1F2D\u0399", "\u1F2E\u0399", "\u1F2F\u0399", "\u1F68\u0399", "\u1F69\u0399", "\u1F6A\u0399", "\u1F6B\u0399", "\u1F6C\u0399", "\u1F6D\u0399", "\u1F6E\u0399", "\u1F6F\u0399", "\u1F68\u0399", "\u1F69\u0399", "\u1F6A\u0399", "\u1F6B\u0399", "\u1F6C\u0399", "\u1F6D\u0399", "\u1F6E\u0399", "\u1F6F\u0399", "\u1FBA\u0399", "\u0391\u0399", "\u0386\u0399", "\u0391\u0342", "\u0391\u0342\u0399", "\u0391\u0399", "\u1FCA\u0399", "\u0397\u0399", "\u0389\u0399", "\u0397\u0342", "\u0397\u0342\u0399", "\u0397\u0399", "\u0399\u0308\u0300", "\u0399\u0308\u0301", "\u0399\u0342", "\u0399\u0308\u0342", "\u03A5\u0308\u0300", "\u03A5\u0308\u0301", "\u03A1\u0313", "\u03A5\u0342", "\u03A5\u0308\u0342", "\u1FFA\u0399", "\u03A9\u0399", "\u038F\u0399", "\u03A9\u0342", "\u03A9\u0342\u0399", "\u03A9\u0399", "\u0046\u0046", "\u0046\u0049", "\u0046\u004C", "\u0046\u0046\u0049", "\u0046\u0046\u004C", "\u0053\u0054", "\u0053\u0054", "\u0544\u0546", "\u0544\u0535", "\u0544\u053B", "\u054E\u0546", "\u0544\u053D", ) internal fun Char.oneToManyUppercase(): String? { if (this < '\u00df') { return null } val code = this.toInt() val index = binarySearchRange(keys, code) if (keys[index] == code) { return values[index] } return null } internal fun Char.uppercaseImpl(): String { return oneToManyUppercase() ?: uppercaseCharImpl().toString() } ================================================ FILE: runtime/src/main/kotlin/generated/_StringLowercase.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // @SharedImmutable private val casedStart = intArrayOf( 0x00aa, 0x00ba, 0x02b0, 0x02c0, 0x02e0, 0x0345, 0x037a, 0x1d2c, 0x1d78, 0x1d9b, 0x2071, 0x207f, 0x2090, 0x2160, 0x2170, 0x24b6, 0x24d0, 0x2c7c, 0xa69c, 0xa770, 0xa7f8, 0xab5c, 0x10400, 0x104b0, 0x104d8, 0x10c80, 0x10cc0, 0x118a0, 0x16e40, 0x1d400, 0x1d456, 0x1d49e, 0x1d4a2, 0x1d4a5, 0x1d4a9, 0x1d4ae, 0x1d4bb, 0x1d4bd, 0x1d4c5, 0x1d507, 0x1d50d, 0x1d516, 0x1d51e, 0x1d53b, 0x1d540, 0x1d546, 0x1d54a, 0x1d552, 0x1d6a8, 0x1d6c2, 0x1d6dc, 0x1d6fc, 0x1d716, 0x1d736, 0x1d750, 0x1d770, 0x1d78a, 0x1d7aa, 0x1d7c4, 0x1e900, 0x1f130, 0x1f150, 0x1f170, ) @SharedImmutable private val casedEnd = intArrayOf( 0x00aa, 0x00ba, 0x02b8, 0x02c1, 0x02e4, 0x0345, 0x037a, 0x1d6a, 0x1d78, 0x1dbf, 0x2071, 0x207f, 0x209c, 0x216f, 0x217f, 0x24cf, 0x24e9, 0x2c7d, 0xa69d, 0xa770, 0xa7f9, 0xab5f, 0x1044f, 0x104d3, 0x104fb, 0x10cb2, 0x10cf2, 0x118df, 0x16e7f, 0x1d454, 0x1d49c, 0x1d49f, 0x1d4a2, 0x1d4a6, 0x1d4ac, 0x1d4b9, 0x1d4bb, 0x1d4c3, 0x1d505, 0x1d50a, 0x1d514, 0x1d51c, 0x1d539, 0x1d53e, 0x1d544, 0x1d546, 0x1d550, 0x1d6a5, 0x1d6c0, 0x1d6da, 0x1d6fa, 0x1d714, 0x1d734, 0x1d74e, 0x1d76e, 0x1d788, 0x1d7a8, 0x1d7c2, 0x1d7cb, 0x1e943, 0x1f149, 0x1f169, 0x1f189, ) // Lu + Ll + Lt + Other_Lowercase + Other_Uppercase (PropList.txt of Unicode Character Database files) // Declared internal for testing internal fun Int.isCased(): Boolean { if (this <= Char.MAX_VALUE.toInt()) { when (toChar().getCategoryValue()) { CharCategory.UPPERCASE_LETTER.value, CharCategory.LOWERCASE_LETTER.value, CharCategory.TITLECASE_LETTER.value -> return true } } val index = binarySearchRange(casedStart, this) return index >= 0 && this <= casedEnd[index] } @SharedImmutable private val caseIgnorableStart = intArrayOf( 0x0027, 0x002e, 0x003a, 0x00b7, 0x0387, 0x055f, 0x05f4, 0x2018, 0x2019, 0x2024, 0x2027, 0xfe13, 0xfe52, 0xfe55, 0xff07, 0xff0e, 0xff1a, 0x101fd, 0x102e0, 0x10376, 0x10a01, 0x10a05, 0x10a0c, 0x10a38, 0x10a3f, 0x10ae5, 0x10d24, 0x10eab, 0x10f46, 0x11001, 0x11038, 0x1107f, 0x110b3, 0x110b9, 0x110bd, 0x110cd, 0x11100, 0x11127, 0x1112d, 0x11173, 0x11180, 0x111b6, 0x111c9, 0x111cf, 0x1122f, 0x11234, 0x11236, 0x1123e, 0x112df, 0x112e3, 0x11300, 0x1133b, 0x11340, 0x11366, 0x11370, 0x11438, 0x11442, 0x11446, 0x1145e, 0x114b3, 0x114ba, 0x114bf, 0x114c2, 0x115b2, 0x115bc, 0x115bf, 0x115dc, 0x11633, 0x1163d, 0x1163f, 0x116ab, 0x116ad, 0x116b0, 0x116b7, 0x1171d, 0x11722, 0x11727, 0x1182f, 0x11839, 0x1193b, 0x1193e, 0x11943, 0x119d4, 0x119da, 0x119e0, 0x11a01, 0x11a33, 0x11a3b, 0x11a47, 0x11a51, 0x11a59, 0x11a8a, 0x11a98, 0x11c30, 0x11c38, 0x11c3f, 0x11c92, 0x11caa, 0x11cb2, 0x11cb5, 0x11d31, 0x11d3a, 0x11d3c, 0x11d3f, 0x11d47, 0x11d90, 0x11d95, 0x11d97, 0x11ef3, 0x13430, 0x16af0, 0x16b30, 0x16b40, 0x16f4f, 0x16f8f, 0x16fe0, 0x16fe3, 0x1bc9d, 0x1bca0, 0x1d167, 0x1d173, 0x1d185, 0x1d1aa, 0x1d242, 0x1da00, 0x1da3b, 0x1da75, 0x1da84, 0x1da9b, 0x1daa1, 0x1e000, 0x1e008, 0x1e01b, 0x1e023, 0x1e026, 0x1e130, 0x1e2ec, 0x1e8d0, 0x1e944, 0x1f3fb, 0xe0001, 0xe0020, 0xe0100, ) @SharedImmutable private val caseIgnorableEnd = intArrayOf( 0x0027, 0x002e, 0x003a, 0x00b7, 0x0387, 0x055f, 0x05f4, 0x2018, 0x2019, 0x2024, 0x2027, 0xfe13, 0xfe52, 0xfe55, 0xff07, 0xff0e, 0xff1a, 0x101fd, 0x102e0, 0x1037a, 0x10a03, 0x10a06, 0x10a0f, 0x10a3a, 0x10a3f, 0x10ae6, 0x10d27, 0x10eac, 0x10f50, 0x11001, 0x11046, 0x11081, 0x110b6, 0x110ba, 0x110bd, 0x110cd, 0x11102, 0x1112b, 0x11134, 0x11173, 0x11181, 0x111be, 0x111cc, 0x111cf, 0x11231, 0x11234, 0x11237, 0x1123e, 0x112df, 0x112ea, 0x11301, 0x1133c, 0x11340, 0x1136c, 0x11374, 0x1143f, 0x11444, 0x11446, 0x1145e, 0x114b8, 0x114ba, 0x114c0, 0x114c3, 0x115b5, 0x115bd, 0x115c0, 0x115dd, 0x1163a, 0x1163d, 0x11640, 0x116ab, 0x116ad, 0x116b5, 0x116b7, 0x1171f, 0x11725, 0x1172b, 0x11837, 0x1183a, 0x1193c, 0x1193e, 0x11943, 0x119d7, 0x119db, 0x119e0, 0x11a0a, 0x11a38, 0x11a3e, 0x11a47, 0x11a56, 0x11a5b, 0x11a96, 0x11a99, 0x11c36, 0x11c3d, 0x11c3f, 0x11ca7, 0x11cb0, 0x11cb3, 0x11cb6, 0x11d36, 0x11d3a, 0x11d3d, 0x11d45, 0x11d47, 0x11d91, 0x11d95, 0x11d97, 0x11ef4, 0x13438, 0x16af4, 0x16b36, 0x16b43, 0x16f4f, 0x16f9f, 0x16fe1, 0x16fe4, 0x1bc9e, 0x1bca3, 0x1d169, 0x1d182, 0x1d18b, 0x1d1ad, 0x1d244, 0x1da36, 0x1da6c, 0x1da75, 0x1da84, 0x1da9f, 0x1daaf, 0x1e006, 0x1e018, 0x1e021, 0x1e024, 0x1e02a, 0x1e13d, 0x1e2ef, 0x1e8d6, 0x1e94b, 0x1f3ff, 0xe0001, 0xe007f, 0xe01ef, ) // Mn + Me + Cf + Lm + Sk + Word_Break=MidLetter + Word_Break=MidNumLet + Word_Break=Single_Quote (WordBreakProperty.txt of Unicode Character Database files) // Declared internal for testing internal fun Int.isCaseIgnorable(): Boolean { if (this <= Char.MAX_VALUE.toInt()) { when (toChar().getCategoryValue()) { CharCategory.NON_SPACING_MARK.value, CharCategory.ENCLOSING_MARK.value, CharCategory.FORMAT.value, CharCategory.MODIFIER_LETTER.value, CharCategory.MODIFIER_SYMBOL.value -> return true } } val index = binarySearchRange(caseIgnorableStart, this) return index >= 0 && this <= caseIgnorableEnd[index] } private fun String.codePointBefore(index: Int): Int { val low = this[index] if (low.isLowSurrogate() && index - 1 >= 0) { val high = this[index - 1] if (high.isHighSurrogate()) { return Char.toCodePoint(high, low) } } return low.toInt() } // \p{cased} (\p{case-ignorable})* Sigma !( (\p{case-ignorable})* \p{cased} ) // The regular-expression operator * is "possessive", consuming as many characters as possible, with no backup. // This is significant in the case of Final_Sigma, because the sets of case-ignorable and cased characters are not disjoint. private fun String.isFinalSigmaAt(index: Int): Boolean { if (this[index] == '\u03A3' && index > 0) { var i = index - 1 var codePoint: Int = 0 while (i >= 0) { codePoint = codePointBefore(i) if (codePoint.isCaseIgnorable()) { i -= codePoint.charCount() } else { break } } if (i >= 0 && codePoint.isCased()) { var j = index + 1 while (j < length) { codePoint = codePointAt(j) if (codePoint.isCaseIgnorable()) { j += codePoint.charCount() } else { break } } if (j >= length || !codePoint.isCased()) { return true } } } return false } internal fun String.lowercaseImpl(): String { var unchangedIndex = 0 while (unchangedIndex < this.length) { val codePoint = codePointAt(unchangedIndex) if (codePoint.lowercaseCodePoint() != codePoint) { // '\u0130' and '\u03A3' have lowercase corresponding mapping in UnicodeData.txt, no need to check them separately break } unchangedIndex += codePoint.charCount() } if (unchangedIndex == this.length) { return this } val sb = StringBuilder(this.length) sb.appendRange(this, 0, unchangedIndex) var index = unchangedIndex while (index < this.length) { if (this[index] == '\u0130') { sb.append("\u0069\u0307") index++ continue } if (isFinalSigmaAt(index)) { sb.append('\u03C2') index++ continue } val codePoint = codePointAt(index) val lowercaseCodePoint = codePoint.lowercaseCodePoint() sb.appendCodePoint(lowercaseCodePoint) index += codePoint.charCount() } return sb.toString() } ================================================ FILE: runtime/src/main/kotlin/generated/_StringUppercase.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // internal fun String.codePointAt(index: Int): Int { val high = this[index] if (high.isHighSurrogate() && index + 1 < this.length) { val low = this[index + 1] if (low.isLowSurrogate()) { return Char.toCodePoint(high, low) } } return high.toInt() } internal fun Int.charCount(): Int = if (this >= Char.MIN_SUPPLEMENTARY_CODE_POINT) 2 else 1 internal fun StringBuilder.appendCodePoint(codePoint: Int) { if (codePoint < Char.MIN_SUPPLEMENTARY_CODE_POINT) { append(codePoint.toChar()) } else { append(Char.MIN_HIGH_SURROGATE + ((codePoint - 0x10000) shr 10)) append(Char.MIN_LOW_SURROGATE + (codePoint and 0x3ff)) } } internal fun String.uppercaseImpl(): String { var unchangedIndex = 0 while (unchangedIndex < this.length) { val codePoint = codePointAt(unchangedIndex) if (this[unchangedIndex].oneToManyUppercase() != null || codePoint.uppercaseCodePoint() != codePoint) { break } unchangedIndex += codePoint.charCount() } if (unchangedIndex == this.length) { return this } val sb = StringBuilder(this.length) sb.appendRange(this, 0, unchangedIndex) var index = unchangedIndex while (index < this.length) { val specialCasing = this[index].oneToManyUppercase() if (specialCasing != null) { sb.append(specialCasing) index++ continue } val codePoint = codePointAt(index) val uppercaseCodePoint = codePoint.uppercaseCodePoint() sb.appendCodePoint(uppercaseCodePoint) index += codePoint.charCount() } return sb.toString() } ================================================ FILE: runtime/src/main/kotlin/generated/_StringsNative.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // /** * Returns a character at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this char sequence. * * @sample samples.collections.Collections.Elements.elementAt */ @kotlin.internal.InlineOnly public actual inline fun CharSequence.elementAt(index: Int): Char { return get(index) } ================================================ FILE: runtime/src/main/kotlin/generated/_TitlecaseMappings.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 4 ranges totally @OptIn(ExperimentalStdlibApi::class) internal fun Char.titlecaseCharImpl(): Char { val code = this.toInt() // Letters repeating sequence and code of the Lt is a multiple of 3, e.g. <DŽ, Dž, dž> if (code in 0x01c4..0x01cc || code in 0x01f1..0x01f3) { return (3 * ((code + 1) / 3)).toChar() } // Lower case letters whose title case mapping equivalent is equal to the original letter if (code in 0x10d0..0x10fa || code in 0x10fd..0x10ff) { return this } return uppercaseChar() } ================================================ FILE: runtime/src/main/kotlin/generated/_UArraysNative.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.collections // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // import kotlin.ranges.contains import kotlin.ranges.reversed /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public actual inline fun UIntArray.elementAt(index: Int): UInt { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public actual inline fun ULongArray.elementAt(index: Int): ULong { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public actual inline fun UByteArray.elementAt(index: Int): UByte { return get(index) } /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this array. * * @sample samples.collections.Collections.Elements.elementAt */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public actual inline fun UShortArray.elementAt(index: Int): UShort { return get(index) } /** * Returns a [List] that wraps the original array. */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes public actual fun UIntArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: UInt): Boolean = this@asList.contains(element) override fun get(index: Int): UInt = this@asList[index] override fun indexOf(element: UInt): Int = this@asList.indexOf(element) override fun lastIndexOf(element: UInt): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes public actual fun ULongArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: ULong): Boolean = this@asList.contains(element) override fun get(index: Int): ULong = this@asList[index] override fun indexOf(element: ULong): Int = this@asList.indexOf(element) override fun lastIndexOf(element: ULong): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes public actual fun UByteArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: UByte): Boolean = this@asList.contains(element) override fun get(index: Int): UByte = this@asList[index] override fun indexOf(element: UByte): Int = this@asList.indexOf(element) override fun lastIndexOf(element: UByte): Int = this@asList.lastIndexOf(element) } } /** * Returns a [List] that wraps the original array. */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes public actual fun UShortArray.asList(): List { return object : AbstractList(), RandomAccess { override val size: Int get() = this@asList.size override fun isEmpty(): Boolean = this@asList.isEmpty() override fun contains(element: UShort): Boolean = this@asList.contains(element) override fun get(index: Int): UShort = this@asList[index] override fun indexOf(element: UShort): Int = this@asList.indexOf(element) override fun lastIndexOf(element: UShort): Int = this@asList.lastIndexOf(element) } } ================================================ FILE: runtime/src/main/kotlin/generated/_UppercaseMappings.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 189 ranges totally @SharedImmutable private val rangeStart = intArrayOf( 0x0061, 0x00b5, 0x00e0, 0x00f8, 0x00ff, 0x0101, 0x0131, 0x0133, 0x013a, 0x014b, 0x017a, 0x017f, 0x0180, 0x0183, 0x0188, 0x0192, 0x0195, 0x0199, 0x019a, 0x019e, 0x01a1, 0x01a8, 0x01b0, 0x01b6, 0x01bd, 0x01bf, 0x01c5, 0x01c6, 0x01c8, 0x01c9, 0x01cb, 0x01cc, 0x01ce, 0x01dd, 0x01df, 0x01f2, 0x01f3, 0x01f5, 0x01fb, 0x0223, 0x023c, 0x023f, 0x0242, 0x0249, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0256, 0x0259, 0x025b, 0x025c, 0x0260, 0x0261, 0x0263, 0x0265, 0x0266, 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026f, 0x0271, 0x0272, 0x0275, 0x027d, 0x0280, 0x0282, 0x0283, 0x0287, 0x0288, 0x0289, 0x028a, 0x028c, 0x0292, 0x029d, 0x029e, 0x0345, 0x0371, 0x0377, 0x037b, 0x03ac, 0x03ad, 0x03b1, 0x03c2, 0x03c3, 0x03cc, 0x03cd, 0x03d0, 0x03d1, 0x03d5, 0x03d6, 0x03d7, 0x03d9, 0x03f0, 0x03f1, 0x03f2, 0x03f3, 0x03f5, 0x03f8, 0x0430, 0x0450, 0x0461, 0x048b, 0x04c2, 0x04cf, 0x04d1, 0x0561, 0x10d0, 0x10fd, 0x13f8, 0x1c80, 0x1c81, 0x1c82, 0x1c83, 0x1c85, 0x1c86, 0x1c87, 0x1c88, 0x1d79, 0x1d7d, 0x1d8e, 0x1e01, 0x1e9b, 0x1ea1, 0x1f00, 0x1f10, 0x1f20, 0x1f30, 0x1f40, 0x1f51, 0x1f60, 0x1f70, 0x1f72, 0x1f76, 0x1f78, 0x1f7a, 0x1f7c, 0x1f80, 0x1f90, 0x1fa0, 0x1fb0, 0x1fb3, 0x1fbe, 0x1fc3, 0x1fd0, 0x1fe0, 0x1fe5, 0x1ff3, 0x214e, 0x2170, 0x2184, 0x24d0, 0x2c30, 0x2c61, 0x2c65, 0x2c66, 0x2c68, 0x2c73, 0x2c81, 0x2cec, 0x2cf3, 0x2d00, 0x2d27, 0xa641, 0xa681, 0xa723, 0xa733, 0xa77a, 0xa77f, 0xa78c, 0xa793, 0xa794, 0xa797, 0xa7b5, 0xa7c3, 0xa7ca, 0xa7f6, 0xab53, 0xab70, 0xff41, 0x10428, 0x104d8, 0x10cc0, 0x118c0, 0x16e60, 0x1e922, ) @SharedImmutable private val rangeLength = intArrayOf( -0x1fee6, 0x2e7101, -0x1fee9, -0x1fef9, 0x79101, -0x0dd1, -0xe7eff, -0x0dfb, -0x0df1, -0x0dd3, -0x0dfb, -0x12beff, 0xc3101, -0x0dfd, -0x0bfb, -0x0eff, 0x61101, -0x0eff, 0xa3101, 0x82101, -0x0dfb, -0x0afa, -0x0bfb, -0x0cfc, -0x0eff, 0x38101, -0x0eff, -0x1eff, -0x0eff, -0x1eff, -0x0eff, -0x1eff, -0x0df1, -0x4eeff, -0x0def, -0x0eff, -0x1eff, -0x0bfb, -0x0ddb, -0x0def, -0x0eff, 0x2a3f102, -0x0afa, -0x0df9, 0x2a1f101, 0x2a1c101, 0x2a1e101, -0xd1eff, -0xcdeff, -0xccefe, -0xc9eff, -0xcaeff, 0xa54f101, -0xcceff, 0xa54b101, -0xceeff, 0xa528101, 0xa544101, -0xd0eff, -0xd2eff, 0xa544101, 0x29f7101, 0xa541101, -0xd2eff, 0x29fd101, -0xd4eff, -0xd5eff, 0x29e7101, -0xd9eff, 0xa543101, -0xd9eff, 0xa52a101, -0xd9eff, -0x44eff, -0xd8efe, -0x46eff, -0xdaeff, 0xa515101, 0xa512101, 0x54101, -0x0dfd, -0x0eff, 0x82103, -0x25eff, -0x24efd, -0x1feef, -0x1eeff, -0x1fef7, -0x3feff, -0x3eefe, -0x3deff, -0x38eff, -0x2eeff, -0x35eff, -0x7eff, -0x0de9, -0x55eff, -0x4feff, 0x7101, -0x73eff, -0x5feff, -0x0cfc, -0x1fee0, -0x4fef0, -0x0ddf, -0x0dcb, -0x0df3, -0xeeff, -0x0da1, -0x2feda, 0xbc012b, 0xbc0103, -0x7efa, -0x186deff, -0x186ceff, -0x1863eff, -0x1861efe, -0x1862eff, -0x185beff, -0x1824eff, 0x89c2101, 0x8a04101, 0xee6101, 0x8a38101, -0x0d6b, -0x3aeff, -0x0da1, 0x8108, 0x8106, 0x8108, 0x8108, 0x8106, 0x8207, 0x8108, 0x4a102, 0x56104, 0x64102, 0x80102, 0x70102, 0x7e102, 0x8108, 0x8108, 0x8108, 0x8102, 0x9101, -0x1c24eff, 0x9101, 0x8102, 0x8102, 0x7101, 0x9101, -0x1beff, -0xfef0, -0x0eff, -0x19ee6, -0x2fed1, -0x0eff, -0x2a2aeff, -0x2a27eff, -0x0dfb, -0x0cfc, -0x0d9d, -0x0dfd, -0x0eff, -0x1c5feda, -0x1c5f9f9, -0x0dd3, -0x0de5, -0x0df3, -0x0dc3, -0x0dfd, -0x0df7, -0x0afa, -0x0eff, 0x30101, -0x0ded, -0x0df5, -0x0afa, -0x0eff, -0x0eff, -0x39feff, -0x97cfeb0, -0x1fee6, -0x27ed8, -0x27edc, -0x3fecd, -0x1fee0, -0x1fee0, -0x21ede, ) internal fun equalDistanceMapping(code: Int, start: Int, pattern: Int): Int { val diff = code - start val length = pattern and 0xff if (diff >= length) { return code } val distance = (pattern shr 8) and 0xf if (diff % distance != 0) { return code } val mapping = pattern shr 12 return code + mapping } internal fun Int.uppercaseCodePoint(): Int { if (this in 0x61..0x7a) { return this - 32 } if (this < 0x80) { return this } val index = binarySearchRange(rangeStart, this) return equalDistanceMapping(this, rangeStart[index], rangeLength[index]) } internal fun Char.uppercaseCharImpl(): Char { return toInt().uppercaseCodePoint().toChar() } ================================================ FILE: runtime/src/main/kotlin/generated/_WhitespaceChars.kt ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text // // NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt // See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib // // 9 ranges totally /** * Returns `true` if this character is a whitespace. */ internal fun Char.isWhitespaceImpl(): Boolean { val ch = this.toInt() return ch in 0x0009..0x000d || ch in 0x001c..0x0020 || ch == 0x00a0 || ch > 0x1000 && ( ch == 0x1680 || ch in 0x2000..0x200a || ch == 0x2028 || ch == 0x2029 || ch == 0x202f || ch == 0x205f || ch == 0x3000 ) } ================================================ FILE: runtime/src/main/kotlin/kotlin/Annotation.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin /** * Base interface implicitly implemented by all annotation interfaces. * See [Kotlin language documentation](https://kotlinlang.org/docs/reference/annotations.html) for more information * on annotations. */ public interface Annotation ================================================ FILE: runtime/src/main/kotlin/kotlin/Annotations.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationRetention.SOURCE import kotlin.annotation.AnnotationTarget.* import kotlin.reflect.KClass /** * Marks the annotated declaration as deprecated. * * A deprecated API element is not recommended to use, typically because it's being phased out or a better alternative exists. * * To help removing deprecated API gradually, the property [level] could be used. * Usually a gradual phase-out goes through the "warning", then "error", then "hidden" or "removed" stages: * - First and by default, [DeprecationLevel.WARNING] is used to notify API consumers, but not to break their compilation or runtime usages. * - Then, some time later the deprecation level is raised to [DeprecationLevel.ERROR], so that no new Kotlin code can be compiled * using the deprecated API. * - Finally, the API is either removed entirely, or hidden ([DeprecationLevel.HIDDEN]) from code, * so its usages look like unresolved references, while the API remains in the compiled code * preserving binary compatibility with previously compiled code. * * @property message The message explaining the deprecation and recommending an alternative API to use. * @property replaceWith If present, specifies a code fragment which should be used as a replacement for * the deprecated API usage. * @property level Specifies how the deprecated element usages are reported in code. * See the [DeprecationLevel] enum for the possible values. */ @Target(CLASS, FUNCTION, PROPERTY, ANNOTATION_CLASS, CONSTRUCTOR, PROPERTY_SETTER, PROPERTY_GETTER, TYPEALIAS) @MustBeDocumented public annotation class Deprecated( val message: String, val replaceWith: ReplaceWith = ReplaceWith(""), val level: DeprecationLevel = DeprecationLevel.WARNING ) /** * Marks the annotated declaration as deprecated. In contrast to [Deprecated], severity of the reported diagnostic is not a constant value, * but differs depending on the API version of the usage (the value of the `-api-version` argument when compiling the module where * the usage is located). If the API version is greater or equal than [hiddenSince], the declaration will not be accessible from the code * (as if it was deprecated with level [DeprecationLevel.HIDDEN]), otherwise if the API version is greater or equal than [errorSince], * the usage will be marked as an error (as with [DeprecationLevel.ERROR]), otherwise if the API version is greater or equal * than [warningSince], the usage will be marked as a warning (as with [DeprecationLevel.WARNING]), otherwise the annotation is ignored. * * @property warningSince the version, since which this deprecation should be reported as a warning. * @property errorSince the version, since which this deprecation should be reported as a error. * @property hiddenSince the version, since which the annotated declaration should not be available in code. */ @Target(CLASS, FUNCTION, PROPERTY, ANNOTATION_CLASS, CONSTRUCTOR, PROPERTY_SETTER, PROPERTY_GETTER, TYPEALIAS) @MustBeDocumented @SinceKotlin("1.4") public annotation class DeprecatedSinceKotlin( val warningSince: String = "", val errorSince: String = "", val hiddenSince: String = "" ) /** * Specifies a code fragment that can be used to replace a deprecated function, property or class. Tools such * as IDEs can automatically apply the replacements specified through this annotation. * * @property expression the replacement expression. The replacement expression is interpreted in the context * of the symbol being used, and can reference members of enclosing classes etc. * For function calls, the replacement expression may contain argument names of the deprecated function, * which will be substituted with actual parameters used in the call being updated. The imports used in the file * containing the deprecated function or property are NOT accessible; if the replacement expression refers * on any of those imports, they need to be specified explicitly in the [imports] parameter. * @property imports the qualified names that need to be imported in order for the references in the * replacement expression to be resolved correctly. */ @Target() @Retention(BINARY) @MustBeDocumented public annotation class ReplaceWith(val expression: String, vararg val imports: String) /** * Possible levels of a deprecation. The level specifies how the deprecated element usages are reported in code. * * @see Deprecated */ public enum class DeprecationLevel { /** Usage of the deprecated element will be reported as a warning. */ WARNING, /** Usage of the deprecated element will be reported as an error. */ ERROR, /** Deprecated element will not be accessible from code. */ HIDDEN } /** * Signifies that the annotated functional type represents an extension function. */ @Target(TYPE) @MustBeDocumented public annotation class ExtensionFunctionType /** * Annotates type arguments of functional type and holds corresponding parameter name specified by the user in type declaration (if any). */ @Target(TYPE) @MustBeDocumented @SinceKotlin("1.1") public annotation class ParameterName(val name: String) /** * Suppresses the given compilation warnings in the annotated element. * @property names names of the compiler diagnostics to suppress. */ @Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPE, EXPRESSION, FILE, TYPEALIAS) @Retention(SOURCE) public annotation class Suppress(vararg val names: String) /** * Suppresses errors about variance conflict */ @Target(TYPE) @Retention(SOURCE) @MustBeDocumented public annotation class UnsafeVariance /** * Specifies the first version of Kotlin where a declaration has appeared. * Using the declaration and specifying an older API version (via the `-api-version` command line option) will result in an error. * * @property version the version in the following formats: `.` or `..`, where major, minor and patch * are non-negative integer numbers without leading zeros. */ @Target(CLASS, PROPERTY, FIELD, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS) @Retention(AnnotationRetention.BINARY) @MustBeDocumented public annotation class SinceKotlin(val version: String) /** * When applied to annotation class X specifies that X defines a DSL language * * The general rule: * - an implicit receiver may *belong to a DSL @X* if marked with a corresponding DSL marker annotation * - two implicit receivers of the same DSL are not accessible in the same scope * - the closest one wins * - other available receivers are resolved as usual, but if the resulting resolved call binds to such a receiver, it's a compilation error * * Marking rules: an implicit receiver is considered marked with @Ann if * - its type is marked, or * - its type's classifier is marked * - or any of its superclasses/superinterfaces */ @Target(ANNOTATION_CLASS) @Retention(BINARY) @MustBeDocumented @SinceKotlin("1.1") public annotation class DslMarker /** * When applied to a class or a member with internal visibility allows to use it from public inline functions and * makes it effectively public. * * Public inline functions cannot use non-public API, since if they are inlined, those non-public API references * would violate access restrictions at a call site (https://kotlinlang.org/docs/reference/inline-functions.html#public-inline-restrictions). * * To overcome this restriction an `internal` declaration can be annotated with the `@PublishedApi` annotation: * - this allows to call that declaration from public inline functions; * - the declaration becomes effectively public, and this should be considered with respect to binary compatibility maintaining. */ @Target(AnnotationTarget.CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.BINARY) @MustBeDocumented @SinceKotlin("1.1") public annotation class PublishedApi /** * This annotation indicates what exceptions should be declared by a function when compiled to a platform method. * * When compiling to Objective-C/Swift framework, non-`suspend` functions having or inheriting * this annotation are represented as `NSError*`-producing methods in Objective-C * and as `throws` methods in Swift. Representations for `suspend` functions always have * `NSError*`/`Error` parameter in completion handler * * When Kotlin function called from Swift/Objective-C code throws an exception * which is an instance of one of the [exceptionClasses] or their subclasses, * it is propagated as `NSError`. Other Kotlin exceptions reaching Swift/Objective-C * are considered unhandled and cause program termination. * * Note: `suspend` functions without `@Throws` propagate only * [kotlin.coroutines.cancellation.CancellationException] as `NSError`. * Non-`suspend` functions without `@Throws` don't propagate Kotlin exceptions at all. * * @property exceptionClasses the list of checked exception classes that may be thrown by the function. */ @SinceKotlin("1.4") @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) @Retention(AnnotationRetention.BINARY) public actual annotation class Throws(actual vararg val exceptionClasses: KClass) ================================================ FILE: runtime/src/main/kotlin/kotlin/Any.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.identityHashCode import kotlin.native.internal.ExportTypeInfo /** * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. */ @ExportTypeInfo("theAnyTypeInfo") public open class Any { /** * Indicates whether some other object is "equal to" this one. Implementations must fulfil the following * requirements: * * * Reflexive: for any non-null value `x`, `x.equals(x)` should return true. * * Symmetric: for any non-null values `x` and `y`, `x.equals(y)` should return true if and only if `y.equals(x)` returns true. * * Transitive: for any non-null values `x`, `y`, and `z`, if `x.equals(y)` returns true and `y.equals(z)` returns true, then `x.equals(z)` should return true. * * Consistent: for any non-null values `x` and `y`, multiple invocations of `x.equals(y)` consistently return true or consistently return false, provided no information used in `equals` comparisons on the objects is modified. * * Never equal to null: for any non-null value `x`, `x.equals(null)` should return false. * * Read more about [equality](https://kotlinlang.org/docs/reference/equality.html) in Kotlin. */ @SymbolName("Kotlin_Any_equals") external public open operator fun equals(other: Any?): Boolean /** * Returns a hash code value for the object. The general contract of `hashCode` is: * * * Whenever it is invoked on the same object more than once, the `hashCode` method must consistently return the same integer, provided no information used in `equals` comparisons on the object is modified. * * If two objects are equal according to the `equals()` method, then calling the `hashCode` method on each of the two objects must produce the same integer result. */ public open fun hashCode(): Int = this.identityHashCode() /** * Returns a string representation of the object. */ public open fun toString(): String { val kClass = this::class val className = kClass.qualifiedName ?: kClass.simpleName ?: "" // TODO: consider using [identityHashCode]. val unsignedHashCode = this.hashCode().toLong() and 0xffffffffL val hashCodeStr = unsignedHashCode.toString(16) return "$className@$hashCodeStr" } } ================================================ FILE: runtime/src/main/kotlin/kotlin/Array.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.ExportForCompiler import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.PointsTo /** * Represents an array. Array instances can be created using the constructor, [arrayOf], [arrayOfNulls] and [emptyArray] * standard library functions. * See [Kotlin language documentation](https://kotlinlang.org/docs/reference/basic-types.html#arrays) * for more information on arrays. */ @ExportTypeInfo("theArrayTypeInfo") public final class Array { /** * Creates a new array with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ @Suppress("TYPE_PARAMETER_AS_REIFIED") public constructor(size: Int, init: (Int) -> T): this(size) { var index = 0 while (index < size) { this[index] = init(index) index++ } } @PublishedApi @ExportForCompiler internal constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the specified [index]. This method can be called using the * index operator. * ``` * value = arr[index] * ``` * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_Array_get") @PointsTo(0x000, 0x000, 0x002) // ret -> this.intestines external public operator fun get(index: Int): T /** * Sets the array element at the specified [index] to the specified [value]. This method can * be called using the index operator. * ``` * arr[index] = value * ``` * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_Array_set") @PointsTo(0x300, 0x000, 0x000) // this.intestines -> value external public operator fun set(index: Int, value: T): Unit /** * Creates an [Iterator] for iterating over the elements of the array. */ public operator fun iterator(): kotlin.collections.Iterator { return IteratorImpl(this) } @SymbolName("Kotlin_Array_getArrayLength") external private fun getArrayLength(): Int } private class IteratorImpl(val collection: Array) : Iterator { var index : Int = 0 public override fun next(): T { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } ================================================ FILE: runtime/src/main/kotlin/kotlin/Arrays.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // TODO: Add SortedSet class and implement toSortedSet extensions // TODO: Add fill and binary search methods for primitive arrays (with tests) package kotlin import kotlin.internal.PureReifiable import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.IntrinsicType import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.PointsTo /** * An array of bytes. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theByteArrayTypeInfo") public final class ByteArray { // Constructors are handled with compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Byte): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_ByteArray_get") external public operator fun get(index: Int): Byte /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_ByteArray_set") external public operator fun set(index: Int, value: Byte): Unit @SymbolName("Kotlin_ByteArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): ByteIterator { return ByteIteratorImpl(this) } } private class ByteIteratorImpl(val collection: ByteArray) : ByteIterator() { var index : Int = 0 public override fun nextByte(): Byte { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * An array of chars. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theCharArrayTypeInfo") public final class CharArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Char): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_CharArray_get") external public operator fun get(index: Int): Char /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_CharArray_set") external public operator fun set(index: Int, value: Char): Unit @SymbolName("Kotlin_CharArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.CharIterator { return CharIteratorImpl(this) } } private class CharIteratorImpl(val collection: CharArray) : CharIterator() { var index : Int = 0 public override fun nextChar(): Char { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * An array of shorts. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theShortArrayTypeInfo") public final class ShortArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Short): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_ShortArray_get") external public operator fun get(index: Int): Short /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_ShortArray_set") external public operator fun set(index: Int, value: Short): Unit @SymbolName("Kotlin_ShortArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.ShortIterator { return ShortIteratorImpl(this) } } private class ShortIteratorImpl(val collection: ShortArray) : ShortIterator() { var index : Int = 0 public override fun nextShort(): Short { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * An array of ints. When targeting the JVM, instances of this class are represented as `int[]`. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theIntArrayTypeInfo") public final class IntArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Int): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_IntArray_get") external public operator fun get(index: Int): Int /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_IntArray_set") external public operator fun set(index: Int, value: Int): Unit @SymbolName("Kotlin_IntArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.IntIterator { return IntIteratorImpl(this) } } private class IntIteratorImpl(val collection: IntArray) : IntIterator() { var index : Int = 0 public override fun nextInt(): Int { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * An array of longs. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theLongArrayTypeInfo") public final class LongArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Long): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_LongArray_get") external public operator fun get(index: Int): Long /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_LongArray_set") external public operator fun set(index: Int, value: Long): Unit @SymbolName("Kotlin_LongArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.LongIterator { return LongIteratorImpl(this) } } private class LongIteratorImpl(val collection: LongArray) : LongIterator() { var index : Int = 0 public override fun nextLong(): Long { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * An array of floats. * @constructor Creates a new array of the specified [size], with all elements initialized to zero. */ @ExportTypeInfo("theFloatArrayTypeInfo") public final class FloatArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Float): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_FloatArray_get") external public operator fun get(index: Int): Float /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_FloatArray_set") external public operator fun set(index: Int, value: Float): Unit @SymbolName("Kotlin_FloatArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.FloatIterator { return FloatIteratorImpl(this) } } private class FloatIteratorImpl(val collection: FloatArray) : FloatIterator() { var index : Int = 0 public override fun nextFloat(): Float { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } @ExportTypeInfo("theDoubleArrayTypeInfo") public final class DoubleArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Double): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_DoubleArray_get") external public operator fun get(index: Int): Double /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_DoubleArray_set") external public operator fun set(index: Int, value: Double): Unit @SymbolName("Kotlin_DoubleArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.DoubleIterator { return DoubleIteratorImpl(this) } } private class DoubleIteratorImpl(val collection: DoubleArray) : DoubleIterator() { var index : Int = 0 public override fun nextDouble(): Double { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } @ExportTypeInfo("theBooleanArrayTypeInfo") public final class BooleanArray { // Constructors are handled with the compiler magic. public constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} /** * Creates a new array of the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for an array element given its index. */ public constructor(size: Int, init: (Int) -> Boolean): this(size) { for (i in 0..size - 1) { this[i] = init(i) } } /** Returns the number of elements in the array. */ public val size: Int get() = getArrayLength() /** * Returns the array element at the given [index]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_BooleanArray_get") external public operator fun get(index: Int): Boolean /** * Sets the element at the given [index] to the given [value]. This method can be called using the index operator. * * If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_BooleanArray_set") external public operator fun set(index: Int, value: Boolean): Unit @SymbolName("Kotlin_BooleanArray_getArrayLength") external private fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): kotlin.collections.BooleanIterator { return BooleanIteratorImpl(this) } } private class BooleanIteratorImpl(val collection: BooleanArray) : BooleanIterator() { var index : Int = 0 public override fun nextBoolean(): Boolean { if (!hasNext()) throw NoSuchElementException("$index") return collection[index++] } public override operator fun hasNext(): Boolean { return index < collection.size } } /** * Returns an array of objects of the given type with the given [size], initialized with null values. */ public inline fun arrayOfNulls(size: Int): Array = @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") arrayOfUninitializedElements(size) /** * Returns an array containing the specified elements. */ @TypedIntrinsic(IntrinsicType.IDENTITY) @PointsTo(0x00, 0x01) // ret -> elements public external inline fun arrayOf(vararg elements: T): Array @SymbolName("Kotlin_emptyArray") external public fun emptyArray(): Array /** * Returns an array containing the specified [Double] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun doubleArrayOf(vararg elements: Double) = elements /** * Returns an array containing the specified [Float] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun floatArrayOf(vararg elements: Float) = elements /** * Returns an array containing the specified [Long] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun longArrayOf(vararg elements: Long) = elements /** * Returns an array containing the specified [Int] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun intArrayOf(vararg elements: Int) = elements /** * Returns an array containing the specified characters. */ @Suppress("NOTHING_TO_INLINE") public inline fun charArrayOf(vararg elements: Char) = elements /** * Returns an array containing the specified [Short] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun shortArrayOf(vararg elements: Short) = elements /** * Returns an array containing the specified [Byte] numbers. */ @Suppress("NOTHING_TO_INLINE") public inline fun byteArrayOf(vararg elements: Byte) = elements /** * Returns an array containing the specified boolean values. */ @Suppress("NOTHING_TO_INLINE") public inline fun booleanArrayOf(vararg elements: Boolean) = elements ================================================ FILE: runtime/src/main/kotlin/kotlin/Assertions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin /** * Throws an [AssertionError] if the [value] is false * and runtime assertions have been enabled during compilation. */ @Suppress("NOTHING_TO_INLINE") public inline fun assert(value: Boolean) { assert(value) { "Assertion failed" } } /** * Throws an [AssertionError] calculated by [lazyMessage] if the [value] is false * and runtime assertions have been enabled during compilation. */ public inline fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) { val message = lazyMessage() throw AssertionError(message) } } ================================================ FILE: runtime/src/main/kotlin/kotlin/Boolean.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType /** * Represents a value which is either `true` or `false`. On the JVM, non-nullable values of this type are * represented as values of the primitive type `boolean`. */ public class Boolean private constructor() : Comparable { @SinceKotlin("1.3") companion object {} /** * Returns the inverse of this boolean. */ @TypedIntrinsic(IntrinsicType.NOT) external public operator fun not(): Boolean /** * Performs a logical `and` operation between this Boolean and the [other] one. Unlike the `&&` operator, * this function does not perform short-circuit evaluation. Both `this` and [other] will always be evaluated. */ @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Boolean): Boolean /** * Performs a logical `or` operation between this Boolean and the [other] one. Unlike the `||` operator, * this function does not perform short-circuit evaluation. Both `this` and [other] will always be evaluated. */ @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Boolean): Boolean /** * Performs a logical `xor` operation between this Boolean and the [other] one. */ @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Boolean): Boolean @TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO) external public override fun compareTo(other: Boolean): Int public fun equals(other: Boolean): Boolean = kotlin.native.internal.areEqualByValue(this, other) public override fun equals(other: Any?): Boolean = other is Boolean && kotlin.native.internal.areEqualByValue(this, other) public override fun toString() = if (this) "true" else "false" public override fun hashCode() = if (this) 1 else 0 } ================================================ FILE: runtime/src/main/kotlin/kotlin/Char.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("NOTHING_TO_INLINE") package kotlin import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType /** * Represents a 16-bit Unicode character. */ public class Char private constructor() : Comparable { /** * Compares this value with the specified value for order. * * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO) external public override fun compareTo(other: Char): Int /** Adds the other Int value to this value resulting a Char. */ public inline operator fun plus(other: Int): Char = (this.toInt() + other).toChar() /** Subtracts the other Char value from this value resulting an Int. */ public inline operator fun minus(other: Char): Int = this.toInt() - other.toInt() /** Subtracts the other Int value from this value resulting a Char. */ public inline operator fun minus(other: Int): Char = (this.toInt() - other).toChar() /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Char /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Char /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Char): CharRange { return CharRange(this, other) } /** Returns the value of this character as a `Byte`. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public fun toByte(): Byte /** Returns the value of this character as a `Char`. */ public inline fun toChar(): Char = this /** Returns the value of this character as a `Short`. */ @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toShort(): Short /** Returns the value of this character as a `Int`. */ @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toInt(): Int /** Returns the value of this character as a `Long`. */ @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toLong(): Long /** Returns the value of this character as a `Float`. */ @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toFloat(): Float /** Returns the value of this character as a `Double`. */ @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toDouble(): Double @kotlin.native.internal.CanBePrecreated companion object { /** * The minimum value of a character code unit. */ @SinceKotlin("1.3") public const val MIN_VALUE: Char = '\u0000' /** * The maximum value of a character code unit. */ @SinceKotlin("1.3") public const val MAX_VALUE: Char = '\uFFFF' /** * The number of bytes used to represent a Char in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BYTES: Int = 2 /** * The number of bits used to represent a Char in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BITS: Int = 16 /** * The minimum value of a Unicode high-surrogate code unit. */ public const val MIN_HIGH_SURROGATE: Char = '\uD800' /** * The maximum value of a Unicode high-surrogate code unit. */ public const val MAX_HIGH_SURROGATE: Char = '\uDBFF' /** * The minimum value of a Unicode low-surrogate code unit. */ public const val MIN_LOW_SURROGATE: Char = '\uDC00' /** * The maximum value of a Unicode low-surrogate code unit. */ public const val MAX_LOW_SURROGATE: Char = '\uDFFF' /** * The minimum value of a Unicode surrogate code unit. */ public const val MIN_SURROGATE: Char = MIN_HIGH_SURROGATE /** * The maximum value of a Unicode surrogate code unit. */ public const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE /** * The minimum value of a supplementary code point, `\u0x10000`. Kotlin/Native specific. */ public const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 /** * The minimum value of a Unicode code point. Kotlin/Native specific. */ public const val MIN_CODE_POINT = 0x000000 /** * The maximum value of a Unicode code point. Kotlin/Native specific. */ public const val MAX_CODE_POINT = 0X10FFFF /** * The minimum radix available for conversion to and from strings. */ public const val MIN_RADIX: Int = 2 /** * The maximum radix available for conversion to and from strings. */ public const val MAX_RADIX: Int = 36 } public fun equals(other: Char): Boolean = this == other public override fun equals(other: Any?): Boolean = other is Char && this.equals(other) @SymbolName("Kotlin_Char_toString") external public override fun toString(): String public override fun hashCode(): Int { return this.toInt(); } } ================================================ FILE: runtime/src/main/kotlin/kotlin/CharCode.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin /** * Creates a Char with the specified [code]. * * @sample samples.text.Chars.charFromCode */ @OptIn(ExperimentalUnsignedTypes::class) @ExperimentalStdlibApi @SinceKotlin("1.4") @kotlin.internal.InlineOnly public actual inline fun Char(code: UShort): Char { return code.toInt().toChar() } ================================================ FILE: runtime/src/main/kotlin/kotlin/CharSequence.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin /** * Represents a readable sequence of [Char] values. */ public interface CharSequence { /** * Returns the length of this character sequence. */ public val length: Int /** * Returns the character at the specified [index] in this character sequence. * * @throws [IndexOutOfBoundsException] if the [index] is out of bounds of this character sequence. */ public operator fun get(index: Int): Char /** * Returns a new character sequence that is a subsequence of this character sequence, * starting at the specified [startIndex] and ending right before the specified [endIndex]. * * @param startIndex the start index (inclusive). * @param endIndex the end index (exclusive). */ public fun subSequence(startIndex: Int, endIndex: Int): CharSequence } ================================================ FILE: runtime/src/main/kotlin/kotlin/Comparable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.Comparator /** * Classes which inherit from this interface have a defined total ordering between their instances. */ public interface Comparable { /** * Compares this object with the specified object for order. Returns zero if this object is equal * to the specified [other] object, a negative number if it's less than [other], or a positive number * if it's greater than [other]. */ public operator fun compareTo(other: T): Int } ================================================ FILE: runtime/src/main/kotlin/kotlin/Comparator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin public actual fun interface Comparator { public actual fun compare(a: T, b: T): Int } ================================================ FILE: runtime/src/main/kotlin/kotlin/Enum.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.enumValueOfIntrinsic import kotlin.native.internal.enumValuesIntrinsic /** * The common base class of all enum classes. * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/enum-classes.html) for more * information on enum classes. */ public abstract class Enum>(public val name: String, public val ordinal: Int): Comparable { public companion object { } public override final fun compareTo(other: E): Int { return ordinal - other.ordinal } public override final fun equals(other: Any?): Boolean { return this === other } public override final fun hashCode(): Int { return ordinal } public override fun toString(): String { return name } } /** * Returns an enum entry with specified name. */ public inline fun > enumValueOf(name: String): T = enumValueOfIntrinsic(name) /** * Returns an array containing enum T entries. */ public inline fun > enumValues(): Array = enumValuesIntrinsic() ================================================ FILE: runtime/src/main/kotlin/kotlin/Exceptions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin public actual open class Error : Throwable { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class Exception : Throwable { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class RuntimeException : Exception { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class NullPointerException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) } public actual open class NoSuchElementException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) } public actual open class IllegalArgumentException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class IllegalStateException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class UnsupportedOperationException : RuntimeException { actual constructor() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class IndexOutOfBoundsException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) } public open class ArrayIndexOutOfBoundsException : IndexOutOfBoundsException { constructor() : super() constructor(message: String?) : super(message) } public actual open class ClassCastException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) } public open class TypeCastException : ClassCastException { constructor() : super() constructor(message: String?) : super(message) } public actual open class ArithmeticException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) } public actual open class AssertionError : Error { actual constructor() constructor(cause: Throwable?) : super(cause) actual constructor(message: Any?) : super(message?.toString()) constructor(message: String?, cause: Throwable?) : super(message, cause) } public actual open class NoWhenBranchMatchedException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public actual open class UninitializedPropertyAccessException : RuntimeException { actual constructor() : super() actual constructor(message: String?) : super(message) actual constructor(message: String?, cause: Throwable?) : super(message, cause) actual constructor(cause: Throwable?) : super(cause) } public open class OutOfMemoryError : Error { constructor() : super() constructor(message: String?) : super(message) } public actual open class NumberFormatException : IllegalArgumentException { actual constructor() : super() actual constructor(message: String?) : super(message) } @Deprecated("Use CharacterCodingException instead", ReplaceWith("CharacterCodingException"), DeprecationLevel.ERROR) public open class IllegalCharacterConversionException : IllegalArgumentException { constructor(): super() constructor(message: String?) : super(message) } public actual open class ConcurrentModificationException actual constructor(message: String?, cause: Throwable?) : RuntimeException(message, cause) { actual constructor() : this(null, null) actual constructor(message: String?) : this(message, null) actual constructor(cause: Throwable?) : this(null, cause) } ================================================ FILE: runtime/src/main/kotlin/kotlin/Experimental.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /** * Empty package to avoid unresolved reference errors in bitwiseOp tests * (e.g. external_codegen_box_binaryOp/bitwiseOp.kt). * Byte/Short bitwise operations are supported in Kotlin Native by default. */ package kotlin.experimental ================================================ FILE: runtime/src/main/kotlin/kotlin/Function.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.FixmeReflection /** * Represents a value of a functional type, such as a lambda, an anonymous function or a function reference. * * @param R return type of the function. */ @FixmeReflection public interface Function ================================================ FILE: runtime/src/main/kotlin/kotlin/Lazy.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.concurrent.FreezeAwareLazyImpl import kotlin.native.internal.FixmeConcurrency import kotlin.reflect.KProperty /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] * and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED]. * * If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access. * * Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on * the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future. */ public actual fun lazy(initializer: () -> T): Lazy = FreezeAwareLazyImpl(initializer) /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] * and thread-safety [mode]. * * If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access. * * Note that when the [LazyThreadSafetyMode.SYNCHRONIZED] mode is specified the returned instance uses itself * to synchronize on. Do not synchronize from external code on the returned instance as it may cause accidental deadlock. * Also this behavior can be changed in the future. */ @FixmeConcurrency public actual fun lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy = when (mode) { LazyThreadSafetyMode.SYNCHRONIZED -> throw UnsupportedOperationException() LazyThreadSafetyMode.PUBLICATION -> FreezeAwareLazyImpl(initializer) LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer) } /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] * and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED]. * * If the initialization of a value throws an exception, it will attempt to reinitialize the value at next access. * * The returned instance uses the specified [lock] object to synchronize on. * When the [lock] is not specified the instance uses itself to synchronize on, * in this case do not synchronize from external code on the returned instance as it may cause accidental deadlock. * Also this behavior can be changed in the future. */ @FixmeConcurrency @Suppress("UNUSED_PARAMETER") public actual fun lazy(lock: Any?, initializer: () -> T): Lazy = throw UnsupportedOperationException() ================================================ FILE: runtime/src/main/kotlin/kotlin/Nothing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin /** * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example, * if a function has the return type of Nothing, it means that it never returns (always throws an exception). */ public final class Nothing private constructor() {} ================================================ FILE: runtime/src/main/kotlin/kotlin/Number.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin /** * Superclass for all platform classes representing numeric values. */ public abstract class Number { /** * Returns the value of this number as a [Double], which may involve rounding. */ public abstract fun toDouble(): Double /** * Returns the value of this number as a [Float], which may involve rounding. */ public abstract fun toFloat(): Float /** * Returns the value of this number as a [Long], which may involve rounding or truncation. */ public abstract fun toLong(): Long /** * Returns the value of this number as an [Int], which may involve rounding or truncation. */ public abstract fun toInt(): Int /** * Returns the [Char] with the numeric value equal to this number, truncated to 16 bits if appropriate. */ public abstract fun toChar(): Char /** * Returns the value of this number as a [Short], which may involve rounding or truncation. */ public abstract fun toShort(): Short /** * Returns the value of this number as a [Byte], which may involve rounding or truncation. */ public abstract fun toByte(): Byte } ================================================ FILE: runtime/src/main/kotlin/kotlin/Numbers.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType /** * Returns `true` if the specified number is a * Not-a-Number (NaN) value, `false` otherwise. */ @SymbolName("Kotlin_Double_isNaN") public actual external fun Double.isNaN(): Boolean /** * Returns `true` if the specified number is a * Not-a-Number (NaN) value, `false` otherwise. */ @SymbolName("Kotlin_Float_isNaN") public actual external fun Float.isNaN(): Boolean /** * Returns `true` if this value is infinitely large in magnitude. */ @SymbolName("Kotlin_Double_isInfinite") public actual external fun Double.isInfinite(): Boolean /** * Returns `true` if this value is infinitely large in magnitude. */ @SymbolName("Kotlin_Float_isInfinite") public actual external fun Float.isInfinite(): Boolean /** * Returns `true` if the argument is a finite floating-point value; returns `false` otherwise (for `NaN` and infinity arguments). */ @SymbolName("Kotlin_Double_isFinite") public actual external fun Double.isFinite(): Boolean /** * Returns `true` if the argument is a finite floating-point value; returns `false` otherwise (for `NaN` and infinity arguments). */ @SymbolName("Kotlin_Float_isFinite") public actual external fun Float.isFinite(): Boolean /** * Returns a bit representation of the specified floating-point value as [Long] * according to the IEEE 754 floating-point "double format" bit layout. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Double.toBits(): Long = if (isNaN()) Double.NaN.toRawBits() else toRawBits() /** * Returns a bit representation of the specified floating-point value as [Long] * according to the IEEE 754 floating-point "double format" bit layout, * preserving `NaN` values exact layout. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Double.toRawBits(): Long = bits() /** * Returns the [Double] value corresponding to a given bit representation. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Double.Companion.fromBits(bits: Long): Double = kotlin.fromBits(bits) @PublishedApi @TypedIntrinsic(IntrinsicType.REINTERPRET) internal external fun fromBits(bits: Long): Double /** * Returns a bit representation of the specified floating-point value as [Int] * according to the IEEE 754 floating-point "single format" bit layout. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Float.toBits(): Int = if (isNaN()) Float.NaN.toRawBits() else toRawBits() /** * Returns a bit representation of the specified floating-point value as [Int] * according to the IEEE 754 floating-point "single format" bit layout, * preserving `NaN` values exact layout. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Float.toRawBits(): Int = bits() /** * Returns the [Float] value corresponding to a given bit representation. */ @SinceKotlin("1.2") @kotlin.internal.InlineOnly public actual inline fun Float.Companion.fromBits(bits: Int): Float = kotlin.fromBits(bits) @PublishedApi @TypedIntrinsic(IntrinsicType.REINTERPRET) internal external fun fromBits(bits: Int): Float // TODO: Replace 32 and 64 literals with Int/Long.SIZE_BITS constants when constant propagation is working /** * Counts the number of set bits in the binary representation of this [Int] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @SymbolName("Kotlin_Int_countOneBits") public actual external fun Int.countOneBits(): Int /** * Counts the number of consecutive most significant bits that are zero in the binary representation of [Int] [value]. * Returns undefined result for zero [value]. */ @SymbolName("Kotlin_Int_countLeadingZeroBits") private external fun countLeadingZeroBits(value: Int): Int /** * Counts the number of consecutive most significant bits that are zero in the binary representation of this [Int] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Int.countLeadingZeroBits(): Int = if (this == 0) 32 else countLeadingZeroBits(this) /** * Counts the number of consecutive least significant bits that are zero in the binary representation of [Int] [value]. * Returns undefined result for zero [value]. */ @SymbolName("Kotlin_Int_countTrailingZeroBits") private external fun countTrailingZeroBits(value: Int): Int /** * Counts the number of consecutive least significant bits that are zero in the binary representation of this [Int] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Int.countTrailingZeroBits(): Int = if (this == 0) 32 else countTrailingZeroBits(this) /** * Returns a number having a single bit set in the position of the most significant set bit of this [Int] number, * or zero, if this number is zero. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Int.takeHighestOneBit(): Int = if (this == 0) 0 else 1.shl(32 - 1 - countLeadingZeroBits(this)) /** * Returns a number having a single bit set in the position of the least significant set bit of this [Int] number, * or zero, if this number is zero. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Int.takeLowestOneBit(): Int = this and -this /** * Rotates the binary representation of this [Int] number left by the specified [bitCount] number of bits. * The most significant bits pushed out from the left side reenter the number as the least significant bits on the right side. * * Rotating the number left by a negative bit count is the same as rotating it right by the negated bit count: * `number.rotateLeft(-n) == number.rotateRight(n)` * * Rotating by a multiple of [Int.SIZE_BITS] (32) returns the same number, or more generally * `number.rotateLeft(n) == number.rotateLeft(n % 32)` */ @SinceKotlin("1.3") @ExperimentalStdlibApi public actual fun Int.rotateLeft(bitCount: Int): Int = shl(bitCount) or ushr(32 - bitCount) /** * Rotates the binary representation of this [Int] number right by the specified [bitCount] number of bits. * The least significant bits pushed out from the right side reenter the number as the most significant bits on the left side. * * Rotating the number right by a negative bit count is the same as rotating it left by the negated bit count: * `number.rotateRight(-n) == number.rotateLeft(n)` * * Rotating by a multiple of [Int.SIZE_BITS] (32) returns the same number, or more generally * `number.rotateRight(n) == number.rotateRight(n % 32)` */ @SinceKotlin("1.3") @ExperimentalStdlibApi public actual fun Int.rotateRight(bitCount: Int): Int = shl(32 - bitCount) or ushr(bitCount) /** * Counts the number of set bits in the binary representation of this [Long] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @SymbolName("Kotlin_Long_countOneBits") public actual external fun Long.countOneBits(): Int /** * Counts the number of consecutive most significant bits that are zero in the binary representation of [Long] [value]. * Returns undefined result for zero [value]. */ @SymbolName("Kotlin_Long_countLeadingZeroBits") private external fun countLeadingZeroBits(value: Long): Int /** * Counts the number of consecutive most significant bits that are zero in the binary representation of this [Long] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Long.countLeadingZeroBits(): Int = if (this == 0L) 64 else countLeadingZeroBits(this) /** * Counts the number of consecutive least significant bits that are zero in the binary representation of [Long] [value]. * Returns undefined result for zero [value]. */ @SymbolName("Kotlin_Long_countTrailingZeroBits") private external fun countTrailingZeroBits(value: Long): Int /** * Counts the number of consecutive least significant bits that are zero in the binary representation of this [Long] number. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Long.countTrailingZeroBits(): Int = if (this == 0L) 64 else countTrailingZeroBits(this) /** * Returns a number having a single bit set in the position of the most significant set bit of this [Long] number, * or zero, if this number is zero. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Long.takeHighestOneBit(): Long = if (this == 0L) 0L else 1L.shl(64 - 1 - countLeadingZeroBits(this)) /** * Returns a number having a single bit set in the position of the least significant set bit of this [Long] number, * or zero, if this number is zero. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) public actual fun Long.takeLowestOneBit(): Long = this and -this /** * Rotates the binary representation of this [Long] number left by the specified [bitCount] number of bits. * The most significant bits pushed out from the left side reenter the number as the least significant bits on the right side. * * Rotating the number left by a negative bit count is the same as rotating it right by the negated bit count: * `number.rotateLeft(-n) == number.rotateRight(n)` * * Rotating by a multiple of [Long.SIZE_BITS] (64) returns the same number, or more generally * `number.rotateLeft(n) == number.rotateLeft(n % 64)` */ @SinceKotlin("1.3") @ExperimentalStdlibApi public actual fun Long.rotateLeft(bitCount: Int): Long = shl(bitCount) or ushr(64 - bitCount) /** * Rotates the binary representation of this [Long] number right by the specified [bitCount] number of bits. * The least significant bits pushed out from the right side reenter the number as the most significant bits on the left side. * * Rotating the number right by a negative bit count is the same as rotating it left by the negated bit count: * `number.rotateRight(-n) == number.rotateLeft(n)` * * Rotating by a multiple of [Long.SIZE_BITS] (64) returns the same number, or more generally * `number.rotateRight(n) == number.rotateRight(n % 64)` */ @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly public actual inline fun Long.rotateRight(bitCount: Int): Long = shl(64 - bitCount) or ushr(bitCount) ================================================ FILE: runtime/src/main/kotlin/kotlin/Primitives.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") package kotlin import kotlin.native.internal.CanBePrecreated import kotlin.native.internal.IntrinsicType import kotlin.native.internal.NumberConverter import kotlin.native.internal.TypedIntrinsic /** * Represents a 8-bit signed integer. */ public final class Byte private constructor() : Number(), Comparable { @CanBePrecreated companion object { /** * A constant holding the minimum value an instance of Byte can have. */ public const val MIN_VALUE: Byte = -128 /** * A constant holding the maximum value an instance of Byte can have. */ public const val MAX_VALUE: Byte = 127 /** * The number of bytes used to represent an instance of Byte in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BYTES: Int = 1 /** * The number of bits used to represent an instance of Byte in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BITS: Int = 8 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Byte): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Short): Int = this.toShort().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Int): Int = this.toInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Long): Int = this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Float): Int = this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Double): Int = this.toDouble().compareTo(other) /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Int = this.toInt() + other.toInt() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Int = this.toInt() + other.toInt() /** Adds the other value to this value. */ public inline operator fun plus(other: Int): Int = this.toInt() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Long): Long = this.toLong() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Float): Float = this.toFloat() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Double): Double = this.toDouble() + other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Int = this.toInt() - other.toInt() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Int = this.toInt() - other.toInt() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Int): Int = this.toInt() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Long): Long = this.toLong() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Float): Float = this.toFloat() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Double): Double = this.toDouble() - other /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Int = this.toInt() * other.toInt() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Int = this.toInt() * other.toInt() /** Multiplies this value by the other value. */ public inline operator fun times(other: Int): Int = this.toInt() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Long): Long = this.toLong() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Float): Float = this.toFloat() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Double): Double = this.toDouble() * other /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Int = this.toInt() / other.toInt() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Int = this.toInt() / other.toInt() /** Divides this value by the other value. */ public inline operator fun div(other: Int): Int = this.toInt() / other /** Divides this value by the other value. */ public inline operator fun div(other: Long): Long = this.toLong() / other /** Divides this value by the other value. */ public inline operator fun div(other: Float): Float = this.toFloat() / other /** Divides this value by the other value. */ public inline operator fun div(other: Double): Double = this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Int = this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Int = this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Int): Int = this.toInt() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Long): Long = this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Float): Float = this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Double): Double = this.toDouble() % other /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Byte /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Byte /** Returns this value. */ public inline operator fun unaryPlus(): Int = this.toInt() /** Returns the negative of this value. */ public inline operator fun unaryMinus(): Int = -this.toInt() /** Returns this value. */ public inline override fun toByte(): Byte = this /** * Converts this [Byte] value to [Char]. * * If this value is non-negative, the resulting `Char` code is equal to this value. * * The least significant 8 bits of the resulting `Char` code are the same as the bits of this `Byte` value, * whereas the most significant 8 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toChar(): Char /** * Converts this [Byte] value to [Short]. * * The resulting `Short` value represents the same numerical value as this `Byte`. * * The least significant 8 bits of the resulting `Short` value are the same as the bits of this `Byte` value, * whereas the most significant 8 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toShort(): Short /** * Converts this [Byte] value to [Int]. * * The resulting `Int` value represents the same numerical value as this `Byte`. * * The least significant 8 bits of the resulting `Int` value are the same as the bits of this `Byte` value, * whereas the most significant 24 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toInt(): Int /** * Converts this [Byte] value to [Long]. * * The resulting `Long` value represents the same numerical value as this `Byte`. * * The least significant 8 bits of the resulting `Long` value are the same as the bits of this `Byte` value, * whereas the most significant 56 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long /** * Converts this [Byte] value to [Float]. * * The resulting `Float` value represents the same numerical value as this `Byte`. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float /** * Converts this [Byte] value to [Double]. * * The resulting `Double` value represents the same numerical value as this `Byte`. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Byte): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Short): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Long): LongRange { return LongRange(this.toLong(), other.toLong()) } // Konan-specific. public fun equals(other: Byte): Boolean = kotlin.native.internal.areEqualByValue(this, other) public override fun equals(other: Any?): Boolean = other is Byte && kotlin.native.internal.areEqualByValue(this, other) @SymbolName("Kotlin_Byte_toString") external public override fun toString(): String public override fun hashCode(): Int { return this.toInt() } } /** * Represents a 16-bit signed integer. */ public final class Short private constructor() : Number(), Comparable { @CanBePrecreated companion object { /** * A constant holding the minimum value an instance of Short can have. */ public const val MIN_VALUE: Short = -32768 /** * A constant holding the maximum value an instance of Short can have. */ public const val MAX_VALUE: Short = 32767 /** * The number of bytes used to represent an instance of Short in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BYTES: Int = 2 /** * The number of bits used to represent an instance of Short in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BITS: Int = 16 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Byte): Int = this.compareTo(other.toShort()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Short): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Int): Int = this.toInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Long): Int = this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Float): Int = this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Double): Int = this.toDouble().compareTo(other) /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Int = this.toInt() + other.toInt() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Int = this.toInt() + other.toInt() /** Adds the other value to this value. */ public inline operator fun plus(other: Int): Int = this.toInt() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Long): Long = this.toLong() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Float): Float = this.toFloat() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Double): Double = this.toDouble() + other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Int = this.toInt() - other.toInt() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Int = this.toInt() - other.toInt() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Int): Int = this.toInt() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Long): Long = this.toLong() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Float): Float = this.toFloat() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Double): Double = this.toDouble() - other /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Int = this.toInt() * other.toInt() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Int = this.toInt() * other.toInt() /** Multiplies this value by the other value. */ public inline operator fun times(other: Int): Int = this.toInt() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Long): Long = this.toLong() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Float): Float = this.toFloat() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Double): Double = this.toDouble() * other /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Int = this.toInt() / other.toInt() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Int = this.toInt() / other.toInt() /** Divides this value by the other value. */ public inline operator fun div(other: Int): Int = this.toInt() / other /** Divides this value by the other value. */ public inline operator fun div(other: Long): Long = this.toLong() / other /** Divides this value by the other value. */ public inline operator fun div(other: Float): Float = this.toFloat() / other /** Divides this value by the other value. */ public inline operator fun div(other: Double): Double = this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Int = this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Int = this.toInt() % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Int): Int = this.toInt() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Long): Long = this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Float): Float = this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Double): Double = this.toDouble() % other /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Short /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Short /** Returns this value. */ public operator fun unaryPlus(): Int = this.toInt() /** Returns the negative of this value. */ public inline operator fun unaryMinus(): Int = -this.toInt() /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Byte): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Short): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): IntRange { return IntRange(this.toInt(), other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Long): LongRange { return LongRange(this.toLong(), other.toLong()) } /** * Converts this [Short] value to [Byte]. * * If this value is in [Byte.MIN_VALUE]..[Byte.MAX_VALUE], the resulting `Byte` value represents * the same numerical value as this `Short`. * * The resulting `Byte` value is represented by the least significant 8 bits of this `Short` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte /** * Converts this [Short] value to [Char]. * * The resulting `Char` code is equal to this value reinterpreted as an unsigned number, * i.e. it has the same binary representation as this `Short`. */ @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public override fun toChar(): Char /** Returns this value. */ public inline override fun toShort(): Short = this /** * Converts this [Short] value to [Int]. * * The resulting `Int` value represents the same numerical value as this `Short`. * * The least significant 16 bits of the resulting `Int` value are the same as the bits of this `Short` value, * whereas the most significant 16 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toInt(): Int /** * Converts this [Short] value to [Long]. * * The resulting `Long` value represents the same numerical value as this `Short`. * * The least significant 16 bits of the resulting `Long` value are the same as the bits of this `Short` value, * whereas the most significant 48 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long /** * Converts this [Short] value to [Float]. * * The resulting `Float` value represents the same numerical value as this `Short`. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float /** * Converts this [Short] value to [Double]. * * The resulting `Double` value represents the same numerical value as this `Short`. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. public fun equals(other: Short): Boolean = kotlin.native.internal.areEqualByValue(this, other) public override fun equals(other: Any?): Boolean = other is Short && kotlin.native.internal.areEqualByValue(this, other) @SymbolName("Kotlin_Short_toString") external public override fun toString(): String public override fun hashCode(): Int { return this.toInt() } } /** * Represents a 32-bit signed integer. */ public final class Int private constructor() : Number(), Comparable { @CanBePrecreated companion object { /** * A constant holding the minimum value an instance of Int can have. */ public const val MIN_VALUE: Int = -2147483648 /** * A constant holding the maximum value an instance of Int can have. */ public const val MAX_VALUE: Int = 2147483647 /** * The number of bytes used to represent an instance of Int in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BYTES: Int = 4 /** * The number of bits used to represent an instance of Int in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BITS: Int = 32 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Byte): Int = this.compareTo(other.toInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Short): Int = this.compareTo(other.toInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Int): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Long): Int = this.toLong().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Float): Int = this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Double): Int = this.toDouble().compareTo(other) /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Int = this + other.toInt() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Int = this + other.toInt() /** Adds the other value to this value. */ @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Int): Int /** Adds the other value to this value. */ public inline operator fun plus(other: Long): Long = this.toLong() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Float): Float = this.toFloat() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Double): Double = this.toDouble() + other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Int = this - other.toInt() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Int = this - other.toInt() /** Subtracts the other value from this value. */ @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Int): Int /** Subtracts the other value from this value. */ public inline operator fun minus(other: Long): Long = this.toLong() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Float): Float = this.toFloat() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Double): Double = this.toDouble() - other /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Int = this * other.toInt() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Int = this * other.toInt() /** Multiplies this value by the other value. */ @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Int): Int /** Multiplies this value by the other value. */ public inline operator fun times(other: Long): Long = this.toLong() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Float): Float = this.toFloat() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Double): Double = this.toDouble() * other /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Int = this / other.toInt() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Int = this / other.toInt() /** Divides this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Int): Int /** Divides this value by the other value. */ public inline operator fun div(other: Long): Long = this.toLong() / other /** Divides this value by the other value. */ public inline operator fun div(other: Float): Float = this.toFloat() / other /** Divides this value by the other value. */ public inline operator fun div(other: Double): Double = this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Int = this % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Int = this % other.toInt() /** Calculates the remainder of dividing this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Int): Int /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Long): Long = this.toLong() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Float): Float = this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Double): Double = this.toDouble() % other /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Int /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Int /** Returns this value. */ @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Int /** Returns the negative of this value. */ @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Int /** Shifts this value left by the [bitCount] number of bits. */ @TypedIntrinsic(IntrinsicType.SHL) external public infix fun shl(bitCount: Int): Int /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */ @TypedIntrinsic(IntrinsicType.SHR) external public infix fun shr(bitCount: Int): Int /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */ @TypedIntrinsic(IntrinsicType.USHR) external public infix fun ushr(bitCount: Int): Int /** Performs a bitwise AND operation between the two values. */ @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Int): Int /** Performs a bitwise OR operation between the two values. */ @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Int): Int /** Performs a bitwise XOR operation between the two values. */ @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Int): Int /** Inverts the bits in this value. */ @TypedIntrinsic(IntrinsicType.INV) external public fun inv(): Int /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Byte): IntRange { return IntRange(this, other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Short): IntRange { return IntRange(this, other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): IntRange { return IntRange(this, other.toInt()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Long): LongRange { return LongRange(this.toLong(), other.toLong()) } /** * Converts this [Int] value to [Byte]. * * If this value is in [Byte.MIN_VALUE]..[Byte.MAX_VALUE], the resulting `Byte` value represents * the same numerical value as this `Int`. * * The resulting `Byte` value is represented by the least significant 8 bits of this `Int` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte /** * Converts this [Int] value to [Char]. * * If this value is in the range of `Char` codes `Char.MIN_VALUE..Char.MAX_VALUE`, * the resulting `Char` code is equal to this value. * * The resulting `Char` code is represented by the least significant 16 bits of this `Int` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toChar(): Char /** * Converts this [Int] value to [Short]. * * If this value is in [Short.MIN_VALUE]..[Short.MAX_VALUE], the resulting `Short` value represents * the same numerical value as this `Int`. * * The resulting `Short` value is represented by the least significant 16 bits of this `Int` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toShort(): Short /** Returns this value. */ public inline override fun toInt(): Int = this /** * Converts this [Int] value to [Long]. * * The resulting `Long` value represents the same numerical value as this `Int`. * * The least significant 32 bits of the resulting `Long` value are the same as the bits of this `Int` value, * whereas the most significant 32 bits are filled with the sign bit of this value. */ @TypedIntrinsic(IntrinsicType.SIGN_EXTEND) external public override fun toLong(): Long /** * Converts this [Int] value to [Float]. * * The resulting value is the closest `Float` to this `Int` value. * In case when this `Int` value is exactly between two `Float`s, * the one with zero at least significant bit of mantissa is selected. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float /** * Converts this [Int] value to [Double]. * * The resulting `Double` value represents the same numerical value as this `Int`. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. public fun equals(other: Int): Boolean = kotlin.native.internal.areEqualByValue(this, other) public override fun equals(other: Any?): Boolean = other is Int && kotlin.native.internal.areEqualByValue(this, other) @SymbolName("Kotlin_Int_toString") external public override fun toString(): String public override fun hashCode(): Int { return this } } /** * Represents a 64-bit signed integer. */ public final class Long private constructor() : Number(), Comparable { @CanBePrecreated companion object { /** * A constant holding the minimum value an instance of Long can have. */ public const val MIN_VALUE: Long = -9223372036854775807L - 1L /** * A constant holding the maximum value an instance of Long can have. */ public const val MAX_VALUE: Long = 9223372036854775807L /** * The number of bytes used to represent an instance of Long in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BYTES: Int = 8 /** * The number of bits used to represent an instance of Long in a binary form. */ @SinceKotlin("1.3") public const val SIZE_BITS: Int = 64 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Byte): Int = this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Short): Int = this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Int): Int = this.compareTo(other.toLong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @TypedIntrinsic(IntrinsicType.SIGNED_COMPARE_TO) external public override operator fun compareTo(other: Long): Int /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Float): Int = this.toFloat().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public inline operator fun compareTo(other: Double): Int = this.toDouble().compareTo(other) /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Long = this + other.toLong() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Long = this + other.toLong() /** Adds the other value to this value. */ public inline operator fun plus(other: Int): Long = this + other.toLong() /** Adds the other value to this value. */ @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Long): Long /** Adds the other value to this value. */ public inline operator fun plus(other: Float): Float = this.toFloat() + other /** Adds the other value to this value. */ public inline operator fun plus(other: Double): Double = this.toDouble() + other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Long = this - other.toLong() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Long = this - other.toLong() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Int): Long = this - other.toLong() /** Subtracts the other value from this value. */ @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Long): Long /** Subtracts the other value from this value. */ public inline operator fun minus(other: Float): Float = this.toFloat() - other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Double): Double = this.toDouble() - other /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Long = this * other.toLong() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Long = this * other.toLong() /** Multiplies this value by the other value. */ public inline operator fun times(other: Int): Long = this * other.toLong() /** Multiplies this value by the other value. */ @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Long): Long /** Multiplies this value by the other value. */ public inline operator fun times(other: Float): Float = this.toFloat() * other /** Multiplies this value by the other value. */ public inline operator fun times(other: Double): Double = this.toDouble() * other /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Long = this / other.toLong() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Long = this / other.toLong() /** Divides this value by the other value. */ public inline operator fun div(other: Int): Long = this / other.toLong() /** Divides this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Long): Long /** Divides this value by the other value. */ public inline operator fun div(other: Float): Float = this.toFloat() / other /** Divides this value by the other value. */ public inline operator fun div(other: Double): Double = this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Long = this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Long = this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Int): Long = this % other.toLong() /** Calculates the remainder of dividing this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Long): Long /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Float): Float = this.toFloat() % other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Double): Double = this.toDouble() % other /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Long /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Long /** Returns this value. */ public inline operator fun unaryPlus(): Long = this /** Returns the negative of this value. */ @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Long /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Byte): LongRange { return LongRange(this, other.toLong()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Short): LongRange { return LongRange(this, other.toLong()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Int): LongRange { return LongRange(this, other.toLong()) } /** Creates a range from this value to the specified [other] value. */ public operator fun rangeTo(other: Long): LongRange { return LongRange(this, other.toLong()) } /** Shifts this value left by the [bitCount] number of bits. */ @TypedIntrinsic(IntrinsicType.SHL) external public infix fun shl(bitCount: Int): Long /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit. */ @TypedIntrinsic(IntrinsicType.SHR) external public infix fun shr(bitCount: Int): Long /** Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros. */ @TypedIntrinsic(IntrinsicType.USHR) external public infix fun ushr(bitCount: Int): Long /** Performs a bitwise AND operation between the two values. */ @TypedIntrinsic(IntrinsicType.AND) external public infix fun and(other: Long): Long /** Performs a bitwise OR operation between the two values. */ @TypedIntrinsic(IntrinsicType.OR) external public infix fun or(other: Long): Long /** Performs a bitwise XOR operation between the two values. */ @TypedIntrinsic(IntrinsicType.XOR) external public infix fun xor(other: Long): Long /** Inverts the bits in this value. */ @TypedIntrinsic(IntrinsicType.INV) external public fun inv(): Long /** * Converts this [Long] value to [Byte]. * * If this value is in [Byte.MIN_VALUE]..[Byte.MAX_VALUE], the resulting `Byte` value represents * the same numerical value as this `Long`. * * The resulting `Byte` value is represented by the least significant 8 bits of this `Long` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toByte(): Byte /** * Converts this [Long] value to [Char]. * * If this value is in the range of `Char` codes `Char.MIN_VALUE..Char.MAX_VALUE`, * the resulting `Char` code is equal to this value. * * The resulting `Char` code is represented by the least significant 16 bits of this `Long` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toChar(): Char /** * Converts this [Long] value to [Short]. * * If this value is in [Short.MIN_VALUE]..[Short.MAX_VALUE], the resulting `Short` value represents * the same numerical value as this `Long`. * * The resulting `Short` value is represented by the least significant 16 bits of this `Long` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toShort(): Short /** * Converts this [Long] value to [Int]. * * If this value is in [Int.MIN_VALUE]..[Int.MAX_VALUE], the resulting `Int` value represents * the same numerical value as this `Long`. * * The resulting `Int` value is represented by the least significant 32 bits of this `Long` value. */ @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public override fun toInt(): Int /** Returns this value. */ public inline override fun toLong(): Long = this /** * Converts this [Long] value to [Float]. * * The resulting value is the closest `Float` to this `Long` value. * In case when this `Long` value is exactly between two `Float`s, * the one with zero at least significant bit of mantissa is selected. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toFloat(): Float /** * Converts this [Long] value to [Double]. * * The resulting value is the closest `Double` to this `Long` value. * In case when this `Long` value is exactly between two `Double`s, * the one with zero at least significant bit of mantissa is selected. */ @TypedIntrinsic(IntrinsicType.SIGNED_TO_FLOAT) external public override fun toDouble(): Double // Konan-specific. public fun equals(other: Long): Boolean = kotlin.native.internal.areEqualByValue(this, other) public override fun equals(other: Any?): Boolean = other is Long && kotlin.native.internal.areEqualByValue(this, other) @SymbolName("Kotlin_Long_toString") external public override fun toString(): String public override fun hashCode(): Int { return ((this ushr 32) xor this).toInt() } } /** * Represents a single-precision 32-bit IEEE 754 floating point number. */ public final class Float private constructor() : Number(), Comparable { companion object { /** * A constant holding the smallest *positive* nonzero value of Float. */ public const val MIN_VALUE: Float = 1.40129846432481707e-45f /** * A constant holding the largest positive finite value of Float. */ public const val MAX_VALUE: Float = 3.40282346638528860e+38f /** * A constant holding the positive infinity value of Float. */ @Suppress("DIVISION_BY_ZERO") public const val POSITIVE_INFINITY: Float = 1.0f / 0.0f /** * A constant holding the negative infinity value of Float. */ @Suppress("DIVISION_BY_ZERO") public const val NEGATIVE_INFINITY: Float = -1.0f / 0.0f /** * A constant holding the "not a number" value of Float. */ @Suppress("DIVISION_BY_ZERO") public const val NaN: Float = -(0.0f / 0.0f) /** * The number of bytes used to represent an instance of Float in a binary form. */ @SinceKotlin("1.4") public const val SIZE_BYTES: Int = 4 /** * The number of bits used to represent an instance of Float in a binary form. */ @SinceKotlin("1.4") public const val SIZE_BITS: Int = 32 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Byte): Int = compareTo(other.toFloat()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Short): Int = compareTo(other.toFloat()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Int): Int = compareTo(other.toFloat()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Long): Int = compareTo(other.toFloat()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public override operator fun compareTo(other: Float): Int { // if any of values in NaN both comparisons return false if (this > other) return 1 if (this < other) return -1 val thisBits = this.toBits() val otherBits = other.toBits() // Canonical NaN bits representation higher than any other bit representvalue return thisBits.compareTo(otherBits) } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Double): Int = - other.compareTo(this) /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Float = this + other.toFloat() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Float = this + other.toFloat() /** Adds the other value to this value. */ public inline operator fun plus(other: Int): Float = this + other.toFloat() /** Adds the other value to this value. */ public inline operator fun plus(other: Long): Float = this + other.toFloat() /** Adds the other value to this value. */ @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Float): Float /** Adds the other value to this value. */ public inline operator fun plus(other: Double): Double = this.toDouble() + other /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Float = this - other.toFloat() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Float = this - other.toFloat() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Int): Float = this - other.toFloat() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Long): Float = this - other.toFloat() /** Subtracts the other value from this value. */ @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Float): Float /** Subtracts the other value from this value. */ public inline operator fun minus(other: Double): Double = this.toDouble() - other /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Float = this * other.toFloat() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Float = this * other.toFloat() /** Multiplies this value by the other value. */ public inline operator fun times(other: Int): Float = this * other.toFloat() /** Multiplies this value by the other value. */ public inline operator fun times(other: Long): Float = this * other.toFloat() /** Multiplies this value by the other value. */ @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Float): Float /** Multiplies this value by the other value. */ public inline operator fun times(other: Double): Double = this.toDouble() * other /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Float = this / other.toFloat() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Float = this / other.toFloat() /** Divides this value by the other value. */ public inline operator fun div(other: Int): Float = this / other.toFloat() /** Divides this value by the other value. */ public inline operator fun div(other: Long): Float = this / other.toFloat() /** Divides this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Float): Float /** Divides this value by the other value. */ public inline operator fun div(other: Double): Double = this.toDouble() / other /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Float = this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Float = this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Int): Float = this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Long): Float = this % other.toFloat() /** Calculates the remainder of dividing this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Float): Float /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Double): Double = this.toDouble() % other /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Float /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Float /** Returns this value. */ @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Float /** Returns the negative of this value. */ @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Float /** * Converts this [Float] value to [Byte]. * * The resulting `Byte` value is equal to `this.toInt().toByte()`. */ @Deprecated("Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.", ReplaceWith("toInt().toByte()")) public override fun toByte(): Byte = this.toInt().toByte() /** * Converts this [Float] value to [Char]. * * The resulting `Char` value is equal to `this.toInt().toChar()`. */ public override fun toChar(): Char = this.toInt().toChar() /** * Converts this [Float] value to [Short]. * * The resulting `Short` value is equal to `this.toInt().toShort()`. */ @Deprecated("Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.", ReplaceWith("toInt().toShort()")) public override fun toShort(): Short = this.toInt().toShort() /** * Converts this [Float] value to [Int]. * * The fractional part, if any, is rounded down. * Returns zero if this `Float` value is `NaN`, [Int.MIN_VALUE] if it's less than `Int.MIN_VALUE`, * [Int.MAX_VALUE] if it's bigger than `Int.MAX_VALUE`. */ @SymbolName("Kotlin_Float_toInt") external public override fun toInt(): Int /** * Converts this [Float] value to [Long]. * * The fractional part, if any, is rounded down. * Returns zero if this `Float` value is `NaN`, [Long.MIN_VALUE] if it's less than `Long.MIN_VALUE`, * [Long.MAX_VALUE] if it's bigger than `Long.MAX_VALUE`. */ @SymbolName("Kotlin_Float_toLong") external public override fun toLong(): Long /** Returns this value. */ public inline override fun toFloat(): Float = this /** * Converts this [Float] value to [Double]. * * The resulting `Double` value represents the same numerical value as this `Float`. */ @TypedIntrinsic(IntrinsicType.FLOAT_EXTEND) external public override fun toDouble(): Double public fun equals(other: Float): Boolean = toBits() == other.toBits() public override fun equals(other: Any?): Boolean = other is Float && this.equals(other) public override fun toString() = NumberConverter.convert(this) public override fun hashCode(): Int { return bits() } @TypedIntrinsic(IntrinsicType.REINTERPRET) @PublishedApi external internal fun bits(): Int } /** * Represents a double-precision 64-bit IEEE 754 floating point number. */ public final class Double private constructor() : Number(), Comparable { companion object { /** * A constant holding the smallest *positive* nonzero value of Double. */ public const val MIN_VALUE: Double = 4.9e-324 /** * A constant holding the largest positive finite value of Double. */ public const val MAX_VALUE: Double = 1.7976931348623157e+308 /** * A constant holding the positive infinity value of Double. */ @Suppress("DIVISION_BY_ZERO") public const val POSITIVE_INFINITY: Double = 1.0 / 0.0 /** * A constant holding the negative infinity value of Double. */ @Suppress("DIVISION_BY_ZERO") public const val NEGATIVE_INFINITY: Double = -1.0 / 0.0 /** * A constant holding the "not a number" value of Double. */ @Suppress("DIVISION_BY_ZERO") public const val NaN: Double = -(0.0 / 0.0) /** * The number of bytes used to represent an instance of Double in a binary form. */ @SinceKotlin("1.4") public const val SIZE_BYTES: Int = 8 /** * The number of bits used to represent an instance of Double in a binary form. */ @SinceKotlin("1.4") public const val SIZE_BITS: Int = 64 } /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Byte): Int = compareTo(other.toDouble()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Short): Int = compareTo(other.toDouble()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Int): Int = compareTo(other.toDouble()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Long): Int = compareTo(other.toDouble()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public operator fun compareTo(other: Float): Int = compareTo(other.toDouble()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ public override operator fun compareTo(other: Double): Int { // if any of values in NaN both comparisons return false if (this > other) return 1 if (this < other) return -1 val thisBits = this.toBits() val otherBits = other.toBits() // Canonical NaN bits representation higher than any other bit representvalue return thisBits.compareTo(otherBits) } /** Adds the other value to this value. */ public inline operator fun plus(other: Byte): Double = this + other.toDouble() /** Adds the other value to this value. */ public inline operator fun plus(other: Short): Double = this + other.toDouble() /** Adds the other value to this value. */ public inline operator fun plus(other: Int): Double = this + other.toDouble() /** Adds the other value to this value. */ public inline operator fun plus(other: Long): Double = this + other.toDouble() /** Adds the other value to this value. */ public inline operator fun plus(other: Float): Double = this + other.toDouble() /** Adds the other value to this value. */ @TypedIntrinsic(IntrinsicType.PLUS) external public operator fun plus(other: Double): Double /** Subtracts the other value from this value. */ public inline operator fun minus(other: Byte): Double = this - other.toDouble() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Short): Double = this - other.toDouble() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Int): Double = this - other.toDouble() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Long): Double = this - other.toDouble() /** Subtracts the other value from this value. */ public inline operator fun minus(other: Float): Double = this - other.toDouble() /** Subtracts the other value from this value. */ @TypedIntrinsic(IntrinsicType.MINUS) external public operator fun minus(other: Double): Double /** Multiplies this value by the other value. */ public inline operator fun times(other: Byte): Double = this * other.toDouble() /** Multiplies this value by the other value. */ public inline operator fun times(other: Short): Double = this * other.toDouble() /** Multiplies this value by the other value. */ public inline operator fun times(other: Int): Double = this * other.toDouble() /** Multiplies this value by the other value. */ public inline operator fun times(other: Long): Double = this * other.toDouble() /** Multiplies this value by the other value. */ public inline operator fun times(other: Float): Double = this * other.toDouble() /** Multiplies this value by the other value. */ @TypedIntrinsic(IntrinsicType.TIMES) external public operator fun times(other: Double): Double /** Divides this value by the other value. */ public inline operator fun div(other: Byte): Double = this / other.toDouble() /** Divides this value by the other value. */ public inline operator fun div(other: Short): Double = this / other.toDouble() /** Divides this value by the other value. */ public inline operator fun div(other: Int): Double = this / other.toDouble() /** Divides this value by the other value. */ public inline operator fun div(other: Long): Double = this / other.toDouble() /** Divides this value by the other value. */ public inline operator fun div(other: Float): Double = this / other.toDouble() /** Divides this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_DIV) external public operator fun div(other: Double): Double /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Byte): Double = this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Short): Double = this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Int): Double = this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Long): Double = this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ public inline operator fun rem(other: Float): Double = this % other.toDouble() /** Calculates the remainder of dividing this value by the other value. */ @TypedIntrinsic(IntrinsicType.SIGNED_REM) external public operator fun rem(other: Double): Double /** Increments this value. */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Double /** Decrements this value. */ @TypedIntrinsic(IntrinsicType.DEC) external public operator fun dec(): Double /** Returns this value. */ @TypedIntrinsic(IntrinsicType.UNARY_PLUS) external public operator fun unaryPlus(): Double /** Returns the negative of this value. */ @TypedIntrinsic(IntrinsicType.UNARY_MINUS) external public operator fun unaryMinus(): Double /** * Converts this [Double] value to [Byte]. * * The resulting `Byte` value is equal to `this.toInt().toByte()`. */ @Deprecated("Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.", ReplaceWith("toInt().toByte()")) public override fun toByte(): Byte = this.toInt().toByte() /** * Converts this [Double] value to [Char]. * * The resulting `Char` value is equal to `this.toInt().toChar()`. */ public override fun toChar(): Char = this.toInt().toChar() /** * Converts this [Double] value to [Short]. * * The resulting `Short` value is equal to `this.toInt().toShort()`. */ @Deprecated("Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.", ReplaceWith("toInt().toShort()")) public override fun toShort(): Short = this.toInt().toShort() /** * Converts this [Double] value to [Int]. * * The fractional part, if any, is rounded down. * Returns zero if this `Double` value is `NaN`, [Int.MIN_VALUE] if it's less than `Int.MIN_VALUE`, * [Int.MAX_VALUE] if it's bigger than `Int.MAX_VALUE`. */ @SymbolName("Kotlin_Double_toInt") external public override fun toInt(): Int /** * Converts this [Double] value to [Long]. * * The fractional part, if any, is rounded down. * Returns zero if this `Double` value is `NaN`, [Long.MIN_VALUE] if it's less than `Long.MIN_VALUE`, * [Long.MAX_VALUE] if it's bigger than `Long.MAX_VALUE`. */ @SymbolName("Kotlin_Double_toLong") external public override fun toLong(): Long /** * Converts this [Double] value to [Float]. * * The resulting value is the closest `Float` to this `Double` value. * In case when this `Double` value is exactly between two `Float`s, * the one with zero at least significant bit of mantissa is selected. */ @TypedIntrinsic(IntrinsicType.FLOAT_TRUNCATE) external public override fun toFloat(): Float /** Returns this value. */ public inline override fun toDouble(): Double = this public fun equals(other: Double): Boolean = toBits() == other.toBits() public override fun equals(other: Any?): Boolean = other is Double && this.equals(other) public override fun toString(): String = NumberConverter.convert(this) public override fun hashCode(): Int = bits().hashCode() @TypedIntrinsic(IntrinsicType.REINTERPRET) @PublishedApi external internal fun bits(): Long } ================================================ FILE: runtime/src/main/kotlin/kotlin/String.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.Frozen @ExportTypeInfo("theStringTypeInfo") @Frozen public final class String : Comparable, CharSequence { public companion object { } @SymbolName("Kotlin_String_hashCode") external public override fun hashCode(): Int public operator fun plus(other: Any?): String { return plusImpl(other.toString()) } override public fun toString(): String { return this } public override val length: Int get() = getStringLength() /** * Returns the character of this string at the specified [index]. * * If the [index] is out of bounds of this string, throws an [IndexOutOfBoundsException]. */ @SymbolName("Kotlin_String_get") external override public fun get(index: Int): Char @SymbolName("Kotlin_String_subSequence") external override public fun subSequence(startIndex: Int, endIndex: Int): CharSequence @SymbolName("Kotlin_String_compareTo") override external public fun compareTo(other: String): Int @SymbolName("Kotlin_String_getStringLength") external private fun getStringLength(): Int @SymbolName("Kotlin_String_plusImpl") external private fun plusImpl(other: String): String @SymbolName("Kotlin_String_equals") external public override fun equals(other: Any?): Boolean } public inline operator fun kotlin.String?.plus(other: kotlin.Any?): kotlin.String = (this?.toString() ?: "null").plus(other?.toString() ?: "null") public inline fun Any?.toString() = this?.toString() ?: "null" ================================================ FILE: runtime/src/main/kotlin/kotlin/Throwable.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.concurrent.freeze import kotlin.native.concurrent.isFrozen import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.NativePtrArray /** * The base class for all errors and exceptions. Only instances of this class can be thrown or caught. * * @param message the detail message string. * @param cause the cause of this throwable. */ @ExportTypeInfo("theThrowableTypeInfo") public open class Throwable(open val message: String?, open val cause: Throwable?) { constructor(message: String?) : this(message, null) constructor(cause: Throwable?) : this(cause?.toString(), cause) constructor() : this(null, null) @get:ExportForCppRuntime("Kotlin_Throwable_getStackTrace") private val stackTrace: NativePtrArray = getCurrentStackTrace() private val stackTraceStrings: Array by lazy { getStackTraceStrings(stackTrace).freeze() } /** * Returns an array of stack trace strings representing the stack trace * pertaining to this throwable. */ public fun getStackTrace(): Array = stackTraceStrings internal fun getStackTraceAddressesInternal(): List = (0 until stackTrace.size).map { index -> stackTrace[index].toLong() } /** * Prints the [detailed description][Throwable.stackTraceToString] of this throwable to the standard output. */ public fun printStackTrace(): Unit = ExceptionTraceBuilder(this).print() internal fun dumpStackTrace(): String = ExceptionTraceBuilder(this).build() private class ExceptionTraceBuilder(private val top: Throwable) { private val target = StringBuilder() private var printOut = false private val visited = mutableSetOf() fun build(): String { top.dumpFullTrace("", "") return target.toString() } fun print() { printOut = true top.dumpFullTrace("", "") } private fun StringBuilder.endln() { if (printOut) { println(this) clear() } else { appendLine() } } private fun Throwable.dumpFullTrace(indent: String, qualifier: String) { this.dumpSelfTrace(indent, qualifier) || return var cause = this.cause while (cause != null) { cause.dumpSelfTrace(indent, "Caused by: ") cause = cause.cause } } private fun Throwable.dumpSelfTrace(indent: String, qualifier: String): Boolean { if (!visited.add(this)) { target.append(indent).append(qualifier).append("[CIRCULAR REFERENCE, SEE ABOVE: ").append(this).append("]").endln() return false } target.append(indent).append(qualifier).append(this).endln() // leave 1 common frame to ease matching with the top exception stack val commonFrames = (commonStackFrames() - 1).coerceAtLeast(0) for (frameIndex in 0 until stackTraceStrings.size - commonFrames) { val element = stackTraceStrings[frameIndex] target.append(indent).append(" at ").append(element).endln() } if (commonFrames > 0) { target.append(indent).append(" ... and ").append(commonFrames).append(" more common stack frames skipped").endln() } val suppressed = suppressedExceptionsList if (!suppressed.isNullOrEmpty()) { val suppressedIndent = indent + " " for (s in suppressed) { s.dumpFullTrace(suppressedIndent, "Suppressed: ") } } return true } private fun Throwable.commonStackFrames(): Int { if (top === this) return 0 val topStack = top.stackTrace val topSize = topStack.size val thisStack = this.stackTrace val thisSize = thisStack.size val maxSize = minOf(topSize, thisSize) var frame = 0 while (frame < maxSize) { if (thisStack[thisSize - 1 - frame] != topStack[topSize - 1 - frame]) break frame++ } return frame } } /** * Returns the short description of this throwable consisting of * the exception class name (fully qualified if possible) * followed by the exception message if it is not null. */ public override fun toString(): String { val kClass = this::class val s = kClass.qualifiedName ?: kClass.simpleName ?: "Throwable" return if (message != null) s + ": " + message.toString() else s } internal var suppressedExceptionsList: MutableList? = null } @SymbolName("Kotlin_getCurrentStackTrace") private external fun getCurrentStackTrace(): NativePtrArray @SymbolName("Kotlin_getStackTraceStrings") private external fun getStackTraceStrings(stackTrace: NativePtrArray): Array /** * Returns the detailed description of this throwable with its stack trace. * * The detailed description includes: * - the short description (see [Throwable.toString]) of this throwable; * - the complete stack trace; * - detailed descriptions of the exceptions that were [suppressed][suppressedExceptions] in order to deliver this exception; * - the detailed description of each throwable in the [Throwable.cause] chain. */ @SinceKotlin("1.4") public actual fun Throwable.stackTraceToString(): String = dumpStackTrace() /** * Prints the [detailed description][Throwable.stackTraceToString] of this throwable to the standard output. */ @SinceKotlin("1.4") @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun Throwable.printStackTrace(): Unit = printStackTrace() /** * Adds the specified exception to the list of exceptions that were * suppressed in order to deliver this exception. * * Does nothing if this [Throwable] is frozen. */ @SinceKotlin("1.4") public actual fun Throwable.addSuppressed(exception: Throwable) { if (this !== exception && !this.isFrozen) { val suppressed = suppressedExceptionsList when { suppressed == null -> suppressedExceptionsList = mutableListOf(exception) suppressed.isFrozen -> suppressedExceptionsList = suppressed.toMutableList().apply { add(exception) } else -> suppressed.add(exception) } } } /** * Returns a list of all exceptions that were suppressed in order to deliver this exception. */ @SinceKotlin("1.4") public actual val Throwable.suppressedExceptions: List get() { return this.suppressedExceptionsList ?: emptyList() } ================================================ FILE: runtime/src/main/kotlin/kotlin/Unit.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin import kotlin.native.internal.ExportTypeInfo /** * The type with only one value: the `Unit` object. */ @ExportTypeInfo("theUnitTypeInfo") public object Unit { override fun toString() = "kotlin.Unit" } ================================================ FILE: runtime/src/main/kotlin/kotlin/annotation/Annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.annotation import kotlin.annotation.AnnotationTarget.* /** * Contains the list of code elements which are the possible annotation targets */ public enum class AnnotationTarget { /** Class, interface or object, annotation class is also included */ CLASS, /** Annotation class only */ ANNOTATION_CLASS, /** Generic type parameter (unsupported yet) */ TYPE_PARAMETER, /** Property */ PROPERTY, /** Field, including property's backing field */ FIELD, /** Local variable */ LOCAL_VARIABLE, /** Value parameter of a function or a constructor */ VALUE_PARAMETER, /** Constructor only (primary or secondary) */ CONSTRUCTOR, /** Function (constructors are not included) */ FUNCTION, /** Property getter only */ PROPERTY_GETTER, /** Property setter only */ PROPERTY_SETTER, /** Type usage */ TYPE, /** Any expression */ EXPRESSION, /** File */ FILE, /** Type alias */ @SinceKotlin("1.1") TYPEALIAS } /** * Contains the list of possible annotation's retentions. * * Determines how an annotation is stored in binary output. */ public enum class AnnotationRetention { /** Annotation isn't stored in binary output */ SOURCE, /** Annotation is stored in binary output, but invisible for reflection */ BINARY, /** Annotation is stored in binary output and visible for reflection (default retention) */ RUNTIME } /** * This meta-annotation indicates the kinds of code elements which are possible targets of an annotation. * * If the target meta-annotation is not present on an annotation declaration, the annotation is applicable to the following elements: * [CLASS], [PROPERTY], [FIELD], [LOCAL_VARIABLE], [VALUE_PARAMETER], [CONSTRUCTOR], [FUNCTION], [PROPERTY_GETTER], [PROPERTY_SETTER]. * * @property allowedTargets list of allowed annotation targets */ @Target(AnnotationTarget.ANNOTATION_CLASS) @MustBeDocumented public annotation class Target(vararg val allowedTargets: AnnotationTarget) /** * This meta-annotation determines whether an annotation is stored in binary output and visible for reflection. By default, both are true. * * @property value necessary annotation retention (RUNTIME, BINARY or SOURCE) */ @Target(AnnotationTarget.ANNOTATION_CLASS) public annotation class Retention(val value: AnnotationRetention = AnnotationRetention.RUNTIME) /** * This meta-annotation determines that an annotation is applicable twice or more on a single code element */ @Target(AnnotationTarget.ANNOTATION_CLASS) public annotation class Repeatable /** * This meta-annotation determines that an annotation is a part of public API and therefore should be included in the generated * documentation for the element to which the annotation is applied. */ @Target(AnnotationTarget.ANNOTATION_CLASS) public annotation class MustBeDocumented ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/AbstractMutableCollection.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * Provides a skeletal implementation of the [MutableCollection] interface. * * @param E the type of elements contained in the collection. The collection is invariant in its element type. */ public actual abstract class AbstractMutableCollection protected actual constructor(): MutableCollection, AbstractCollection() { // Bulk Modification Operations /** * Adds all of the elements of the specified collection to this collection. * * @return `true` if any of the specified elements was added to the collection, `false` if the collection was not modified. */ actual override public fun addAll(elements: Collection): Boolean { var changed = false for (v in elements) { if (add(v)) changed = true } return changed } /** * Removes a single instance of the specified element from this * collection, if it is present. * * @return `true` if the element has been successfully removed; `false` if it was not present in the collection. */ actual override fun remove(element: E): Boolean { val it = iterator() while (it.hasNext()) { if (it.next() == element) { it.remove() return true } } return false } /** * Removes all of this collection's elements that are also contained in the specified collection. * * @return `true` if any of the specified elements was removed from the collection, `false` if the collection was not modified. */ actual override public fun removeAll(elements: Collection): Boolean = (this as MutableIterable).removeAll { it in elements } /** * Retains only the elements in this collection that are contained in the specified collection. * * @return `true` if any element was removed from the collection, `false` if the collection was not modified. */ actual override public fun retainAll(elements: Collection): Boolean = (this as MutableIterable).retainAll { it in elements } /** * Removes all elements from this collection. */ actual override fun clear(): Unit { val it = iterator() while (it.hasNext()) { it.next() it.remove() } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/AbstractMutableList.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * AbstractMutableList implementation copied from JS backend * (see js/js.libraries/src/core/collections/AbstractMutableList.kt). * * Based on GWT AbstractList * Copyright 2007 Google Inc. */ /** * Provides a skeletal implementation of the [MutableList] interface. * * @param E the type of elements contained in the list. The list is invariant in its element type. */ public actual abstract class AbstractMutableList protected actual constructor() : AbstractMutableCollection(), MutableList { protected var modCount: Int = 0 abstract override fun add(index: Int, element: E): Unit abstract override fun removeAt(index: Int): E abstract override fun set(index: Int, element: E): E /** * Adds the specified element to the end of this list. * * @return `true` because the list is always modified as the result of this operation. */ override actual fun add(element: E): Boolean { add(size, element) return true } override actual fun addAll(index: Int, elements: Collection): Boolean { var i = index var changed = false for (e in elements) { add(i++, e) changed = true } return changed } override actual fun clear() { removeRange(0, size) } override actual fun removeAll(elements: Collection): Boolean = removeAll { it in elements } override actual fun retainAll(elements: Collection): Boolean = removeAll { it !in elements } override actual fun iterator(): MutableIterator = IteratorImpl() override actual fun contains(element: E): Boolean = indexOf(element) >= 0 override actual fun indexOf(element: E): Int { for (index in 0..lastIndex) { if (get(index) == element) { return index } } return -1 } override actual fun lastIndexOf(element: E): Int { for (index in lastIndex downTo 0) { if (get(index) == element) { return index } } return -1 } override actual fun listIterator(): MutableListIterator = listIterator(0) override actual fun listIterator(index: Int): MutableListIterator = ListIteratorImpl(index) override actual fun subList(fromIndex: Int, toIndex: Int): MutableList = SubList(this, fromIndex, toIndex) /** * Removes the range of elements from this list starting from [fromIndex] and ending with but not including [toIndex]. */ protected open fun removeRange(fromIndex: Int, toIndex: Int) { val iterator = listIterator(fromIndex) repeat(toIndex - fromIndex) { iterator.next() iterator.remove() } } override fun equals(other: Any?): Boolean { if (other === this) return true if (other !is List<*>) return false return AbstractList.orderedEquals(this, other) } override fun hashCode(): Int = AbstractList.orderedHashCode(this) private open inner class IteratorImpl : MutableIterator { /** the index of the item that will be returned on the next call to [next]`()` */ protected var index = 0 /** the index of the item that was returned on the previous call to [next]`()` * or [ListIterator.previous]`()` (for `ListIterator`), * -1 if no such item exists */ protected var last = -1 override fun hasNext(): Boolean = index < size override fun next(): E { if (!hasNext()) throw NoSuchElementException() last = index++ return get(last) } override fun remove() { check(last != -1) { "Call next() or previous() before removing element from the iterator."} removeAt(last) index = last last = -1 } } /** * Implementation of `MutableListIterator` for abstract lists. */ private inner class ListIteratorImpl(index: Int) : IteratorImpl(), MutableListIterator { init { AbstractList.checkPositionIndex(index, this@AbstractMutableList.size) this.index = index } override fun hasPrevious(): Boolean = index > 0 override fun nextIndex(): Int = index override fun previous(): E { if (!hasPrevious()) throw NoSuchElementException() last = --index return get(last) } override fun previousIndex(): Int = index - 1 override fun add(element: E) { add(index, element) index++ last = -1 } override fun set(element: E) { check(last != -1) { "Call next() or previous() before updating element value with the iterator."} this@AbstractMutableList[last] = element } } private class SubList(private val list: AbstractMutableList, private val fromIndex: Int, toIndex: Int) : AbstractMutableList() { private var _size: Int = 0 init { AbstractList.checkRangeIndexes(fromIndex, toIndex, list.size) this._size = toIndex - fromIndex } override fun add(index: Int, element: E) { AbstractList.checkPositionIndex(index, _size) list.add(fromIndex + index, element) _size++ } override fun get(index: Int): E { AbstractList.checkElementIndex(index, _size) return list[fromIndex + index] } override fun removeAt(index: Int): E { AbstractList.checkElementIndex(index, _size) val result = list.removeAt(fromIndex + index) _size-- return result } override fun set(index: Int, element: E): E { AbstractList.checkElementIndex(index, _size) return list.set(fromIndex + index, element) } override val size: Int get() = _size } } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/AbstractMutableMap.kt ================================================ package kotlin.collections /** * Provides a skeletal implementation of the [MutableMap] interface. * * The implementor is required to implement [entries] property, which should return mutable set of map entries, and [put] function. * * @param K the type of map keys. The map is invariant in its key type. * @param V the type of map values. The map is invariant in its value type. */ @SinceKotlin("1.1") public actual abstract class AbstractMutableMap protected actual constructor() : AbstractMap(), MutableMap { /** * Associates the specified [value] with the specified [key] in the map. * * @return the previous value associated with the key, or `null` if the key was not present in the map. */ actual abstract override fun put(key: K, value: V): V? /** * A mutable [Map.Entry] shared by several [Map] implementations. */ internal open class SimpleEntry(override val key: K, value: V) : MutableMap.MutableEntry { constructor(entry: Map.Entry) : this(entry.key, entry.value) private var _value = value override val value: V get() = _value override fun setValue(newValue: V): V { val oldValue = this._value this._value = newValue return oldValue } override fun hashCode(): Int = entryHashCode(this) override fun toString(): String = entryToString(this) override fun equals(other: Any?): Boolean = entryEquals(this, other) } actual override fun putAll(from: Map) { for ((key, value) in from) { put(key, value) } } actual override fun remove(key: K): V? { val iter = entries.iterator() while (iter.hasNext()) { val entry = iter.next() val k = entry.key if (key == k) { val value = entry.value iter.remove() return value } } return null } actual override fun clear() { entries.clear() } private var _keys: MutableSet? = null actual override val keys: MutableSet get() { if (_keys == null) { _keys = object : AbstractMutableSet() { override fun add(element: K): Boolean = throw UnsupportedOperationException("Add is not supported on keys") override fun clear() { this@AbstractMutableMap.clear() } override operator fun contains(element: K): Boolean = containsKey(element) override operator fun iterator(): MutableIterator { val entryIterator = entries.iterator() return object : MutableIterator { override fun hasNext(): Boolean = entryIterator.hasNext() override fun next(): K = entryIterator.next().key override fun remove() = entryIterator.remove() } } override fun remove(element: K): Boolean { if (containsKey(element)) { this@AbstractMutableMap.remove(element) return true } return false } override val size: Int get() = this@AbstractMutableMap.size } } return _keys!! } private var _values: MutableCollection? = null actual override val values: MutableCollection get() { if (_values == null) { _values = object : AbstractMutableCollection() { override fun add(element: V): Boolean = throw UnsupportedOperationException("Add is not supported on values") override fun clear() = this@AbstractMutableMap.clear() override operator fun contains(element: V): Boolean = containsValue(element) override operator fun iterator(): MutableIterator { val entryIterator = entries.iterator() return object : MutableIterator { override fun hasNext(): Boolean = entryIterator.hasNext() override fun next(): V = entryIterator.next().value override fun remove() = entryIterator.remove() } } override val size: Int get() = this@AbstractMutableMap.size // TODO: should we implement them this way? Currently it's unspecified in JVM override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Collection<*>) return false return AbstractList.orderedEquals(this, other) } override fun hashCode(): Int = AbstractList.orderedHashCode(this) } } return _values!! } } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/AbstractMutableSet.kt ================================================ package kotlin.collections /** * Provides a skeletal implementation of the [MutableSet] interface. * * @param E the type of elements contained in the set. The set is invariant in its element type. */ @SinceKotlin("1.1") public actual abstract class AbstractMutableSet protected actual constructor() : AbstractMutableCollection(), MutableSet { /** * Adds the specified element to the set. * * @return `true` if the element has been added, `false` if the element is already contained in the set. */ actual abstract override fun add(element: E): Boolean /** * Compares this set with another set instance with the unordered structural equality. * * @return `true`, if [other] instance is a [Set] of the same size, all elements of which are contained in this set. */ override fun equals(other: Any?): Boolean { if (other === this) return true if (other !is Set<*>) return false return AbstractSet.setEquals(this, other) } /** * Returns the hash code value for this set. */ override fun hashCode(): Int = AbstractSet.unorderedHashCode(this) } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/ArrayList.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections actual class ArrayList private constructor( private var array: Array, private var offset: Int, private var length: Int, private var isReadOnly: Boolean, private val backing: ArrayList?, private val root: ArrayList? ) : MutableList, RandomAccess, AbstractMutableList() { actual constructor() : this(10) actual constructor(initialCapacity: Int) : this( arrayOfUninitializedElements(initialCapacity), 0, 0, false, null, null) actual constructor(elements: Collection) : this(elements.size) { addAll(elements) } @PublishedApi internal fun build(): List { if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList checkIsMutable() isReadOnly = true return this } override actual val size: Int get() = length override actual fun isEmpty(): Boolean = length == 0 override actual fun get(index: Int): E { checkElementIndex(index) return array[offset + index] } override actual operator fun set(index: Int, element: E): E { checkIsMutable() checkElementIndex(index) val old = array[offset + index] array[offset + index] = element return old } override actual fun indexOf(element: E): Int { var i = 0 while (i < length) { if (array[offset + i] == element) return i i++ } return -1 } override actual fun lastIndexOf(element: E): Int { var i = length - 1 while (i >= 0) { if (array[offset + i] == element) return i i-- } return -1 } override actual fun iterator(): MutableIterator = Itr(this, 0) override actual fun listIterator(): MutableListIterator = Itr(this, 0) override actual fun listIterator(index: Int): MutableListIterator { checkPositionIndex(index) return Itr(this, index) } override actual fun add(element: E): Boolean { checkIsMutable() addAtInternal(offset + length, element) return true } override actual fun add(index: Int, element: E) { checkIsMutable() checkPositionIndex(index) addAtInternal(offset + index, element) } override actual fun addAll(elements: Collection): Boolean { checkIsMutable() val n = elements.size addAllInternal(offset + length, elements, n) return n > 0 } override actual fun addAll(index: Int, elements: Collection): Boolean { checkIsMutable() checkPositionIndex(index) val n = elements.size addAllInternal(offset + index, elements, n) return n > 0 } override actual fun clear() { checkIsMutable() removeRangeInternal(offset, length) } override actual fun removeAt(index: Int): E { checkIsMutable() checkElementIndex(index) return removeAtInternal(offset + index) } override actual fun remove(element: E): Boolean { checkIsMutable() val i = indexOf(element) if (i >= 0) removeAt(i) return i >= 0 } override actual fun removeAll(elements: Collection): Boolean { checkIsMutable() return retainOrRemoveAllInternal(offset, length, elements, false) > 0 } override actual fun retainAll(elements: Collection): Boolean { checkIsMutable() return retainOrRemoveAllInternal(offset, length, elements, true) > 0 } override actual fun subList(fromIndex: Int, toIndex: Int): MutableList { checkRangeIndexes(fromIndex, toIndex) return ArrayList(array, offset + fromIndex, toIndex - fromIndex, isReadOnly, this, root ?: this) } actual fun trimToSize() { if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList if (length < array.size) array = array.copyOfUninitializedElements(length) } @OptIn(ExperimentalStdlibApi::class) final actual fun ensureCapacity(minCapacity: Int) { if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList if (minCapacity > array.size) { val newSize = ArrayDeque.newCapacity(array.size, minCapacity) array = array.copyOfUninitializedElements(newSize) } } override fun equals(other: Any?): Boolean { return other === this || (other is List<*>) && contentEquals(other) } override fun hashCode(): Int { return array.subarrayContentHashCode(offset, length) } override fun toString(): String { @Suppress("DEPRECATION") return array.subarrayContentToString(offset, length) } // ---------------------------- private ---------------------------- private fun checkElementIndex(index: Int) { if (index < 0 || index >= length) { throw IndexOutOfBoundsException("index: $index, size: $length") } } private fun checkPositionIndex(index: Int) { if (index < 0 || index > length) { throw IndexOutOfBoundsException("index: $index, size: $length") } } private fun checkRangeIndexes(fromIndex: Int, toIndex: Int) { if (fromIndex < 0 || toIndex > length) { throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex, size: $length") } if (fromIndex > toIndex) { throw IllegalArgumentException("fromIndex: $fromIndex > toIndex: $toIndex") } } private fun checkIsMutable() { if (isReadOnly || root != null && root.isReadOnly) throw UnsupportedOperationException() } private fun ensureExtraCapacity(n: Int) { ensureCapacity(length + n) } private fun contentEquals(other: List<*>): Boolean { return array.subarrayContentEquals(offset, length, other) } private fun insertAtInternal(i: Int, n: Int) { ensureExtraCapacity(n) array.copyInto(array, startIndex = i, endIndex = offset + length, destinationOffset = i + n) length += n } private fun addAtInternal(i: Int, element: E) { if (backing != null) { backing.addAtInternal(i, element) array = backing.array length++ } else { insertAtInternal(i, 1) array[i] = element } } private fun addAllInternal(i: Int, elements: Collection, n: Int) { if (backing != null) { backing.addAllInternal(i, elements, n) array = backing.array length += n } else { insertAtInternal(i, n) var j = 0 val it = elements.iterator() while (j < n) { array[i + j] = it.next() j++ } } } private fun removeAtInternal(i: Int): E { if (backing != null) { val old = backing.removeAtInternal(i) length-- return old } else { val old = array[i] array.copyInto(array, startIndex = i + 1, endIndex = offset + length, destinationOffset = i) array.resetAt(offset + length - 1) length-- return old } } private fun removeRangeInternal(rangeOffset: Int, rangeLength: Int) { if (backing != null) { backing.removeRangeInternal(rangeOffset, rangeLength) } else { array.copyInto(array, startIndex = rangeOffset + rangeLength, endIndex = length, destinationOffset = rangeOffset) array.resetRange(fromIndex = length - rangeLength, toIndex = length) } length -= rangeLength } /** Retains elements if [retain] == true and removes them it [retain] == false. */ private fun retainOrRemoveAllInternal(rangeOffset: Int, rangeLength: Int, elements: Collection, retain: Boolean): Int { if (backing != null) { val removed = backing.retainOrRemoveAllInternal(rangeOffset, rangeLength, elements, retain) length -= removed return removed } else { var i = 0 var j = 0 while (i < rangeLength) { if (elements.contains(array[rangeOffset + i]) == retain) { array[rangeOffset + j++] = array[rangeOffset + i++] } else { i++ } } val removed = rangeLength - j array.copyInto(array, startIndex = rangeOffset + rangeLength, endIndex = length, destinationOffset = rangeOffset + j) array.resetRange(fromIndex = length - removed, toIndex = length) length -= removed return removed } } private class Itr : MutableListIterator { private val list: ArrayList private var index: Int private var lastIndex: Int constructor(list: ArrayList, index: Int) { this.list = list this.index = index this.lastIndex = -1 } override fun hasPrevious(): Boolean = index > 0 override fun hasNext(): Boolean = index < list.length override fun previousIndex(): Int = index - 1 override fun nextIndex(): Int = index override fun previous(): E { if (index <= 0) throw NoSuchElementException() lastIndex = --index return list.array[list.offset + lastIndex] } override fun next(): E { if (index >= list.length) throw NoSuchElementException() lastIndex = index++ return list.array[list.offset + lastIndex] } override fun set(element: E) { check(lastIndex != -1) { "Call next() or previous() before replacing element from the iterator." } list.set(lastIndex, element) } override fun add(element: E) { list.add(index++, element) lastIndex = -1 } override fun remove() { check(lastIndex != -1) { "Call next() or previous() before removing element from the iterator." } list.removeAt(lastIndex) index = lastIndex lastIndex = -1 } } } private fun Array.subarrayContentHashCode(offset: Int, length: Int): Int { var result = 1 var i = 0 while (i < length) { val nextElement = this[offset + i] result = result * 31 + nextElement.hashCode() i++ } return result } private fun Array.subarrayContentEquals(offset: Int, length: Int, other: List<*>): Boolean { if (length != other.size) return false var i = 0 while (i < length) { if (this[offset + i] != other[i]) return false i++ } return true } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/ArraySorting.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections private fun > mergeSort(array: Array, start: Int, endInclusive: Int) { @Suppress("UNCHECKED_CAST") val buffer = arrayOfNulls(array.size) as Array val result = mergeSort(array, buffer, start, endInclusive) if (result !== array) { for (i in start..endInclusive) array[i] = result[i] } } // Both start and end are inclusive indices. private fun > mergeSort(array: Array, buffer: Array, start: Int, end: Int): Array { if (start == end) { return array } val median = (start + end) / 2 val left = mergeSort(array, buffer, start, median) val right = mergeSort(array, buffer, median + 1, end) val target = if (left === buffer) array else buffer // Merge. var leftIndex = start var rightIndex = median + 1 for (i in start..end) { when { leftIndex <= median && rightIndex <= end -> { val leftValue = left[leftIndex] val rightValue = right[rightIndex] if (leftValue <= rightValue) { target[i] = leftValue leftIndex++ } else { target[i] = rightValue rightIndex++ } } leftIndex <= median -> { target[i] = left[leftIndex] leftIndex++ } else /* rightIndex <= end */ -> { target[i] = right[rightIndex] rightIndex++ } } } return target } // Sort with comparator. private fun mergeSort(array: Array, start: Int, endInclusive: Int, comparator: Comparator) { @Suppress("UNCHECKED_CAST") val buffer = arrayOfNulls(array.size) as Array val result = mergeSort(array, buffer, start, endInclusive, comparator) if (result !== array) { for (i in start..endInclusive) array[i] = result[i] } } // Both start and end are inclusive indices. private fun mergeSort(array: Array, buffer: Array, start: Int, end: Int, comparator: Comparator): Array { if (start == end) { return array } val median = (start + end) / 2 val left = mergeSort(array, buffer, start, median, comparator) val right = mergeSort(array, buffer, median + 1, end, comparator) val target = if (left === buffer) array else buffer // Merge. var leftIndex = start var rightIndex = median + 1 for (i in start..end) { when { leftIndex <= median && rightIndex <= end -> { val leftValue = left[leftIndex] val rightValue = right[rightIndex] if (comparator.compare(leftValue, rightValue) <= 0) { target[i] = leftValue leftIndex++ } else { target[i] = rightValue rightIndex++ } } leftIndex <= median -> { target[i] = left[leftIndex] leftIndex++ } else /* rightIndex <= end */ -> { target[i] = right[rightIndex] rightIndex++ } } } return target } // ByteArray ============================================================================= private fun partition( array: ByteArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: ByteArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // ShortArray ============================================================================= private fun partition( array: ShortArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: ShortArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // IntArray ============================================================================= private fun partition( array: IntArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: IntArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // LongArray ============================================================================= private fun partition( array: LongArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: LongArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // CharArray ============================================================================= private fun partition( array: CharArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: CharArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // FloatArray ============================================================================= private fun partition( array: FloatArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i].compareTo(pivot) < 0) i++ while (array[j].compareTo(pivot) > 0) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: FloatArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // DoubleArray ============================================================================= private fun partition( array: DoubleArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i].compareTo(pivot) < 0) i++ while (array[j].compareTo(pivot) > 0) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: DoubleArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // BooleanArray ============================================================================= private fun partition( array: BooleanArray, left: Int, right: Int): Int { var i = left var j = right val pivot = array[(left + right) / 2] while (i <= j) { while (array[i] < pivot) i++ while (array[j] > pivot) j-- if (i <= j) { val tmp = array[i] array[i] = array[j] array[j] = tmp i++ j-- } } return i } private fun quickSort( array: BooleanArray, left: Int, right: Int) { val index = partition(array, left, right) if (left < index - 1) quickSort(array, left, index - 1) if (index < right) quickSort(array, index, right) } // Interfaces ============================================================================= /** * Sorts the subarray specified by [fromIndex] (inclusive) and [toIndex] (exclusive) parameters * using the merge sort algorithm with the given [comparator]. */ internal fun sortArrayWith(array: Array, fromIndex: Int, toIndex: Int, comparator: Comparator) { if (fromIndex < toIndex - 1) { @Suppress("UNCHECKED_CAST") mergeSort(array as Array, fromIndex, toIndex - 1, comparator) } } /** * Sorts a subarray of [Comparable] elements specified by [fromIndex] (inclusive) and * [toIndex] (exclusive) parameters using the merge sort algorithm. */ internal fun > sortArray(array: Array, fromIndex: Int, toIndex: Int) { if (fromIndex < toIndex - 1) { @Suppress("UNCHECKED_CAST") mergeSort(array as Array, fromIndex, toIndex - 1) } } /** * Sorts the given array using qsort algorithm. */ internal fun sortArray(array: ByteArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: ShortArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: IntArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: LongArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: CharArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: FloatArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: DoubleArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) internal fun sortArray(array: BooleanArray, fromIndex: Int, toIndex: Int) = quickSort(array, fromIndex, toIndex - 1) ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections import kotlin.native.internal.PointsTo import kotlin.native.internal.ExportForCppRuntime /** * Returns an array of objects of the given type with the given [size], initialized with _uninitialized_ values. * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ @PublishedApi internal inline fun arrayOfUninitializedElements(size: Int): Array { // TODO: special case for size == 0? require(size >= 0) { "capacity must be non-negative." } @Suppress("TYPE_PARAMETER_AS_REIFIED") return Array(size) } /** * Returns a new array which is a copy of the original array with new elements filled with null values. */ internal fun Array.copyOfNulls(newSize: Int): Array = copyOfNulls(0, newSize) internal fun Array.copyOfNulls(fromIndex: Int, toIndex: Int): Array { val newSize = toIndex - fromIndex if (newSize < 0) { throw IllegalArgumentException("$fromIndex > $toIndex") } val result = @Suppress("TYPE_PARAMETER_AS_REIFIED") arrayOfNulls(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result } /** * Copies elements of the [collection] into the given [array]. * If the array is too small, allocates a new one of collection.size size. * @return [array] with the elements copied from the collection. */ internal fun collectionToArray(collection: Collection, array: Array): Array { val toArray = if (collection.size > array.size) { arrayOfUninitializedElements(collection.size) } else { array } var i = 0 for (v in collection) { @Suppress("UNCHECKED_CAST") toArray[i] = v as T i++ } return toArray } /** * Creates an array of collection.size size and copies elements of the [collection] into it. * @return [array] with the elements copied from the collection. */ internal fun collectionToArray(collection: Collection): Array = collectionToArray(collection, arrayOfUninitializedElements(collection.size)) /** * Resets an array element at a specified index to some implementation-specific _uninitialized_ value. * In particular, references stored in this element are released and become available for garbage collection. * Attempts to read _uninitialized_ value work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun Array.resetAt(index: Int) { (@Suppress("UNCHECKED_CAST")(this as Array))[index] = null } @SymbolName("Kotlin_Array_fillImpl") @PointsTo(0x3000, 0x0000, 0x0000, 0x0000) // array.intestines -> value internal external fun arrayFill(array: Array, fromIndex: Int, toIndex: Int, value: T) @SymbolName("Kotlin_ByteArray_fillImpl") internal external fun arrayFill(array: ByteArray, fromIndex: Int, toIndex: Int, value: Byte) @SymbolName("Kotlin_ShortArray_fillImpl") internal external fun arrayFill(array: ShortArray, fromIndex: Int, toIndex: Int, value: Short) @SymbolName("Kotlin_CharArray_fillImpl") internal external fun arrayFill(array: CharArray, fromIndex: Int, toIndex: Int, value: Char) @SymbolName("Kotlin_IntArray_fillImpl") internal external fun arrayFill(array: IntArray, fromIndex: Int, toIndex: Int, value: Int) @SymbolName("Kotlin_LongArray_fillImpl") internal external fun arrayFill(array: LongArray, fromIndex: Int, toIndex: Int, value: Long) @SymbolName("Kotlin_DoubleArray_fillImpl") internal external fun arrayFill(array: DoubleArray, fromIndex: Int, toIndex: Int, value: Double) @SymbolName("Kotlin_FloatArray_fillImpl") internal external fun arrayFill(array: FloatArray, fromIndex: Int, toIndex: Int, value: Float) @SymbolName("Kotlin_BooleanArray_fillImpl") internal external fun arrayFill(array: BooleanArray, fromIndex: Int, toIndex: Int, value: Boolean) @ExportForCppRuntime internal fun checkRangeIndexes(fromIndex: Int, toIndex: Int, size: Int) { if (fromIndex < 0 || toIndex > size) { throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex, size: $size") } if (fromIndex > toIndex) { throw IllegalArgumentException("fromIndex: $fromIndex > toIndex: $toIndex") } } /** * Resets a range of array elements at a specified [fromIndex] (inclusive) to [toIndex] (exclusive) range of indices * to some implementation-specific _uninitialized_ value. * In particular, references stored in these elements are released and become available for garbage collection. * Attempts to read _uninitialized_ values work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ internal fun Array.resetRange(fromIndex: Int, toIndex: Int) { arrayFill(@Suppress("UNCHECKED_CAST") (this as Array), fromIndex, toIndex, null) } @SymbolName("Kotlin_Array_copyImpl") @PointsTo(0x00000, 0x00000, 0x00004, 0x00000, 0x00000) // destination.intestines -> array.intestines internal external fun arrayCopy(array: Array, fromIndex: Int, destination: Array, toIndex: Int, count: Int) @SymbolName("Kotlin_ByteArray_copyImpl") internal external fun arrayCopy(array: ByteArray, fromIndex: Int, destination: ByteArray, toIndex: Int, count: Int) @SymbolName("Kotlin_ShortArray_copyImpl") internal external fun arrayCopy(array: ShortArray, fromIndex: Int, destination: ShortArray, toIndex: Int, count: Int) @SymbolName("Kotlin_CharArray_copyImpl") internal external fun arrayCopy(array: CharArray, fromIndex: Int, destination: CharArray, toIndex: Int, count: Int) @SymbolName("Kotlin_IntArray_copyImpl") internal external fun arrayCopy(array: IntArray, fromIndex: Int, destination: IntArray, toIndex: Int, count: Int) @SymbolName("Kotlin_LongArray_copyImpl") internal external fun arrayCopy(array: LongArray, fromIndex: Int, destination: LongArray, toIndex: Int, count: Int) @SymbolName("Kotlin_FloatArray_copyImpl") internal external fun arrayCopy(array: FloatArray, fromIndex: Int, destination: FloatArray, toIndex: Int, count: Int) @SymbolName("Kotlin_DoubleArray_copyImpl") internal external fun arrayCopy(array: DoubleArray, fromIndex: Int, destination: DoubleArray, toIndex: Int, count: Int) @SymbolName("Kotlin_BooleanArray_copyImpl") internal external fun arrayCopy(array: BooleanArray, fromIndex: Int, destination: BooleanArray, toIndex: Int, count: Int) internal fun Collection.collectionToString(): String { val sb = StringBuilder(2 + size * 3) sb.append("[") var i = 0 val it = iterator() while (it.hasNext()) { if (i > 0) sb.append(", ") val next = it.next() if (next == this) sb.append("(this Collection)") else sb.append(next) i++ } sb.append("]") return sb.toString() } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Arrays.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections import kotlin.internal.PureReifiable /** Returns the array if it's not `null`, or an empty array otherwise. */ public actual inline fun Array?.orEmpty(): Array = this ?: emptyArray() internal fun checkCopyOfRangeArguments(fromIndex: Int, toIndex: Int, size: Int) { if (toIndex > size) throw IndexOutOfBoundsException("toIndex ($toIndex) is greater than size ($size).") if (fromIndex > toIndex) throw IllegalArgumentException("fromIndex ($fromIndex) is greater than toIndex ($toIndex).") } // TODO: internal /** * Returns a string representation of the contents of the subarray of the specified array as if it is [List]. */ @kotlin.internal.InlineOnly @Deprecated("This function will become internal soon.", level = DeprecationLevel.WARNING) public inline fun Array.subarrayContentToString(offset: Int, length: Int): String { val sb = StringBuilder(2 + length * 3) sb.append("[") var i = 0 while (i < length) { if (i > 0) sb.append(", ") sb.append(this[offset + i]) i++ } sb.append("]") return sb.toString() } /** * Returns a hash code based on the contents of this array as if it is [List]. * Nested arrays are treated as lists too. * * If any of arrays contains itself on any nesting level the behavior is undefined. */ @SinceKotlin("1.1") @OptIn(ExperimentalUnsignedTypes::class) internal fun Array?.contentDeepHashCodeImpl(): Int { if (this == null) return 0 var result = 1 for (element in this) { val elementHash = when (element) { null -> 0 is Array<*> -> element.contentDeepHashCode() is ByteArray -> element.contentHashCode() is ShortArray -> element.contentHashCode() is IntArray -> element.contentHashCode() is LongArray -> element.contentHashCode() is FloatArray -> element.contentHashCode() is DoubleArray -> element.contentHashCode() is CharArray -> element.contentHashCode() is BooleanArray -> element.contentHashCode() is UByteArray -> element.contentHashCode() is UShortArray -> element.contentHashCode() is UIntArray -> element.contentHashCode() is ULongArray -> element.contentHashCode() else -> element.hashCode() } result = 31 * result + elementHash } return result } @Suppress("UNCHECKED_CAST") internal actual fun arrayOfNulls(reference: Array, size: Int): Array = arrayOfNulls(size) as Array internal actual fun copyToArrayImpl(collection: Collection<*>): Array { val array = arrayOfUninitializedElements(collection.size) val iterator = collection.iterator() var index = 0 while (iterator.hasNext()) array[index++] = iterator.next() return array } @Suppress("UNCHECKED_CAST") internal actual fun copyToArrayImpl(collection: Collection<*>, array: Array): Array { if (array.size < collection.size) return copyToArrayImpl(collection) as Array val iterator = collection.iterator() var index = 0 while (iterator.hasNext()) { array[index++] = iterator.next() as T } if (index < array.size) { return array.copyOf(index) as Array } return array } /** * Returns a *typed* array containing all of the elements of this collection. * * Allocates an array of runtime type `T` having its size equal to the size of this collection * and populates the array with the elements of this collection. */ public actual inline fun Collection.toTypedArray(): Array { val result = arrayOfNulls(size) var index = 0 for (element in this) result[index++] = element @Suppress("UNCHECKED_CAST") return result as Array } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Collection.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * A generic collection of elements. Methods in this interface support only read-only access to the collection; * read/write access is supported through the [MutableCollection] interface. * @param E the type of elements contained in the collection. The collection is covariant in its element type. */ public interface Collection : Iterable { // Query Operations /** * Returns the size of the collection. */ public val size: Int /** * Returns `true` if the collection is empty (contains no elements), `false` otherwise. */ public fun isEmpty(): Boolean /** * Checks if the specified element is contained in this collection. */ public operator fun contains(element: @UnsafeVariance E): Boolean override fun iterator(): Iterator // Bulk Operations /** * Checks if all elements in the specified collection are contained in this collection. */ public fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean } /** * A generic collection of elements that supports adding and removing elements. * * @param E the type of elements contained in the collection. The mutable collection is invariant in its element type. */ public interface MutableCollection : Collection, MutableIterable { // Query Operations override fun iterator(): MutableIterator // Modification Operations /** * Adds the specified element to the collection. * * @return `true` if the element has been added, `false` if the collection does not support duplicates * and the element is already contained in the collection. */ public fun add(element: E): Boolean /** * Removes a single instance of the specified element from this * collection, if it is present. * * @return `true` if the element has been successfully removed; `false` if it was not present in the collection. */ public fun remove(element: E): Boolean // Bulk Modification Operations /** * Adds all of the elements of the specified collection to this collection. * * @return `true` if any of the specified elements was added to the collection, `false` if the collection was not modified. */ public fun addAll(elements: Collection): Boolean /** * Removes all of this collection's elements that are also contained in the specified collection. * * @return `true` if any of the specified elements was removed from the collection, `false` if the collection was not modified. */ public fun removeAll(elements: Collection): Boolean /** * Retains only the elements in this collection that are contained in the specified collection. * * @return `true` if any element was removed from the collection, `false` if the collection was not modified. */ public fun retainAll(elements: Collection): Boolean /** * Removes all elements from this collection. */ public fun clear(): Unit } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Collections.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections import kotlin.comparisons.* import kotlin.internal.InlineOnly import kotlin.random.* /** Copies typed varargs array to an array of objects */ internal actual fun Array.copyToArrayOfAny(isVarargs: Boolean): Array = // if the array came from varargs and already is array of Any, copying isn't required. if (isVarargs) this else this.copyOfUninitializedElements(this.size) /** * Classes that inherit from this interface can be represented as a sequence of elements that can * be iterated over. * @param T the type of element being iterated over. The iterator is covariant in its element type. */ public interface Iterable { /** * Returns an iterator over the elements of this object. */ public operator fun iterator(): Iterator } /** * Classes that inherit from this interface can be represented as a sequence of elements that can * be iterated over and that supports removing elements during iteration. * @param T the type of element being iterated over. The mutable iterator is invariant in its element type. */ public interface MutableIterable : Iterable { /** * Returns an iterator over the elements of this sequence that supports removing elements during iteration. */ override fun iterator(): MutableIterator } @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildListInternal(builderAction: MutableList.() -> Unit): List { return ArrayList().apply(builderAction).build() } @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildListInternal(capacity: Int, builderAction: MutableList.() -> Unit): List { return ArrayList(capacity).apply(builderAction).build() } /** * Replaces each element in the list with a result of a transformation specified. */ public fun MutableList.replaceAll(transformation: (T) -> T) { val it = listIterator() while (it.hasNext()) { val element = it.next() it.set(transformation(element)) } } /** * Groups elements from the [Grouping] source by key and counts elements in each group. * * @return a [Map] associating the key of each group with the count of elements in the group. * * @sample samples.collections.Grouping.groupingByEachCount */ @SinceKotlin("1.1") public actual fun Grouping.eachCount(): Map = eachCountTo(mutableMapOf()) // Copied from JS. /** * Fills the list with the provided [value]. * * Each element in the list gets replaced with the [value]. */ @SinceKotlin("1.2") public actual fun MutableList.fill(value: T): Unit { for (index in 0..lastIndex) { this[index] = value } } /** * Randomly shuffles elements in this list. * * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm */ @SinceKotlin("1.2") public actual fun MutableList.shuffle(): Unit { for (i in lastIndex downTo 1) { val j = Random.nextInt(i + 1) val copy = this[i] this[i] = this[j] this[j] = copy } } /** * Returns a new list with the elements of this list randomly shuffled. */ @SinceKotlin("1.2") public actual fun Iterable.shuffled(): List = toMutableList().apply { shuffle() } @PublishedApi @SinceKotlin("1.3") @InlineOnly internal actual inline fun checkIndexOverflow(index: Int): Int { if (index < 0) { // TODO: api version check? throwIndexOverflow() } return index } @PublishedApi @SinceKotlin("1.3") @InlineOnly internal actual inline fun checkCountOverflow(count: Int): Int { if (count < 0) { // TODO: api version check? throwCountOverflow() } return count } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/HashMap.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections import kotlin.native.concurrent.isFrozen actual class HashMap private constructor( private var keysArray: Array, private var valuesArray: Array?, // allocated only when actually used, always null in pure HashSet private var presenceArray: IntArray, private var hashArray: IntArray, private var maxProbeDistance: Int, private var length: Int ) : MutableMap { private var hashShift: Int = computeShift(hashSize) private var _size: Int = 0 override actual val size: Int get() = _size private var keysView: HashMapKeys? = null private var valuesView: HashMapValues? = null private var entriesView: HashMapEntrySet? = null private var isReadOnly: Boolean = false // ---------------------------- functions ---------------------------- actual constructor() : this(INITIAL_CAPACITY) actual constructor(initialCapacity: Int) : this( arrayOfUninitializedElements(initialCapacity), null, IntArray(initialCapacity), IntArray(computeHashSize(initialCapacity)), INITIAL_MAX_PROBE_DISTANCE, 0) actual constructor(original: Map) : this(original.size) { putAll(original) } // This implementation doesn't use a loadFactor, this constructor is used for compatibility with common stdlib actual constructor(initialCapacity: Int, loadFactor: Float) : this(initialCapacity) @PublishedApi internal fun build(): Map { checkIsMutable() isReadOnly = true return this } override actual fun isEmpty(): Boolean = _size == 0 override actual fun containsKey(key: K): Boolean = findKey(key) >= 0 override actual fun containsValue(value: V): Boolean = findValue(value) >= 0 override actual operator fun get(key: K): V? { val index = findKey(key) if (index < 0) return null return valuesArray!![index] } override actual fun put(key: K, value: V): V? { checkIsMutable() val index = addKey(key) val valuesArray = allocateValuesArray() if (index < 0) { val oldValue = valuesArray[-index - 1] valuesArray[-index - 1] = value return oldValue } else { valuesArray[index] = value return null } } override actual fun putAll(from: Map) { checkIsMutable() putAllEntries(from.entries) } override actual fun remove(key: K): V? { val index = removeKey(key) // mutability gets checked here if (index < 0) return null val valuesArray = valuesArray!! val oldValue = valuesArray[index] valuesArray.resetAt(index) return oldValue } override actual fun clear() { checkIsMutable() // O(length) implementation for hashArray cleanup for (i in 0..length - 1) { val hash = presenceArray[i] if (hash >= 0) { hashArray[hash] = 0 presenceArray[i] = TOMBSTONE } } keysArray.resetRange(0, length) valuesArray?.resetRange(0, length) _size = 0 length = 0 } override actual val keys: MutableSet get() { val cur = keysView return if (cur == null) { val new = HashMapKeys(this) if (!isFrozen) keysView = new new } else cur } override actual val values: MutableCollection get() { val cur = valuesView return if (cur == null) { val new = HashMapValues(this) if (!isFrozen) valuesView = new new } else cur } override actual val entries: MutableSet> get() { val cur = entriesView return if (cur == null) { val new = HashMapEntrySet(this) if (!isFrozen) entriesView = new return new } else cur } override fun equals(other: Any?): Boolean { return other === this || (other is Map<*, *>) && contentEquals(other) } override fun hashCode(): Int { var result = 0 val it = entriesIterator() while (it.hasNext()) { result += it.nextHashCode() } return result } override fun toString(): String { val sb = StringBuilder(2 + _size * 3) sb.append("{") var i = 0 val it = entriesIterator() while (it.hasNext()) { if (i > 0) sb.append(", ") it.nextAppendString(sb) i++ } sb.append("}") return sb.toString() } // ---------------------------- private ---------------------------- private val capacity: Int get() = keysArray.size private val hashSize: Int get() = hashArray.size internal fun checkIsMutable() { if (isReadOnly) throw UnsupportedOperationException() } private fun ensureExtraCapacity(n: Int) { ensureCapacity(length + n) } private fun ensureCapacity(capacity: Int) { if (capacity > this.capacity) { var newSize = this.capacity * 3 / 2 if (capacity > newSize) newSize = capacity keysArray = keysArray.copyOfUninitializedElements(newSize) valuesArray = valuesArray?.copyOfUninitializedElements(newSize) presenceArray = presenceArray.copyOf(newSize) val newHashSize = computeHashSize(newSize) if (newHashSize > hashSize) rehash(newHashSize) } else if (length + capacity - _size > this.capacity) { rehash(hashSize) } } private fun allocateValuesArray(): Array { val curValuesArray = valuesArray if (curValuesArray != null) return curValuesArray val newValuesArray = arrayOfUninitializedElements(capacity) valuesArray = newValuesArray return newValuesArray } // Null-check for escaping extra boxing for non-nullable keys. private fun hash(key: K) = if (key == null) 0 else (key.hashCode() * MAGIC) ushr hashShift private fun compact() { var i = 0 var j = 0 val valuesArray = valuesArray while (i < length) { if (presenceArray[i] >= 0) { keysArray[j] = keysArray[i] if (valuesArray != null) valuesArray[j] = valuesArray[i] j++ } i++ } keysArray.resetRange(j, length) valuesArray?.resetRange(j, length) length = j //check(length == size) { "Internal invariant violated during compact: length=$length != size=$size" } } private fun rehash(newHashSize: Int) { if (length > _size) compact() if (newHashSize != hashSize) { hashArray = IntArray(newHashSize) hashShift = computeShift(newHashSize) } else { hashArray.fill(0, 0, hashSize) } var i = 0 while (i < length) { if (!putRehash(i++)) { throw IllegalStateException("This cannot happen with fixed magic multiplier and grow-only hash array. " + "Have object hashCodes changed?") } } } private fun putRehash(i: Int): Boolean { var hash = hash(keysArray[i]) var probesLeft = maxProbeDistance while (true) { val index = hashArray[hash] if (index == 0) { hashArray[hash] = i + 1 presenceArray[i] = hash return true } if (--probesLeft < 0) return false if (hash-- == 0) hash = hashSize - 1 } } private fun findKey(key: K): Int { var hash = hash(key) var probesLeft = maxProbeDistance while (true) { val index = hashArray[hash] if (index == 0) return TOMBSTONE if (index > 0 && keysArray[index - 1] == key) return index - 1 if (--probesLeft < 0) return TOMBSTONE if (hash-- == 0) hash = hashSize - 1 } } private fun findValue(value: V): Int { var i = length while (--i >= 0) { if (presenceArray[i] >= 0 && valuesArray!![i] == value) return i } return TOMBSTONE } internal fun addKey(key: K): Int { checkIsMutable() retry@ while (true) { var hash = hash(key) // put is allowed to grow maxProbeDistance with some limits (resize hash on reaching limits) val tentativeMaxProbeDistance = (maxProbeDistance * 2).coerceAtMost(hashSize / 2) var probeDistance = 0 while (true) { val index = hashArray[hash] if (index <= 0) { // claim or reuse hash slot if (length >= capacity) { ensureExtraCapacity(1) continue@retry } val putIndex = length++ keysArray[putIndex] = key presenceArray[putIndex] = hash hashArray[hash] = putIndex + 1 _size++ if (probeDistance > maxProbeDistance) maxProbeDistance = probeDistance return putIndex } if (keysArray[index - 1] == key) { return -index } if (++probeDistance > tentativeMaxProbeDistance) { rehash(hashSize * 2) // cannot find room even with extra "tentativeMaxProbeDistance" -- grow hash continue@retry } if (hash-- == 0) hash = hashSize - 1 } } } internal fun removeKey(key: K): Int { checkIsMutable() val index = findKey(key) if (index < 0) return TOMBSTONE removeKeyAt(index) return index } private fun removeKeyAt(index: Int) { keysArray.resetAt(index) removeHashAt(presenceArray[index]) presenceArray[index] = TOMBSTONE _size-- } private fun removeHashAt(removedHash: Int) { var hash = removedHash var hole = removedHash // will try to patch the hole in hash array var probeDistance = 0 var patchAttemptsLeft = (maxProbeDistance * 2).coerceAtMost(hashSize / 2) // don't spend too much effort while (true) { if (hash-- == 0) hash = hashSize - 1 if (++probeDistance > maxProbeDistance) { // too far away -- can release the hole, bad case will not happen hashArray[hole] = 0 return } val index = hashArray[hash] if (index == 0) { // end of chain -- can release the hole, bad case will not happen hashArray[hole] = 0 return } if (index < 0) { // TOMBSTONE FOUND // - <--- [ TS ] ------ [hole] ---> + // \------------/ // probeDistance // move tombstone into the hole hashArray[hole] = TOMBSTONE hole = hash probeDistance = 0 } else { val otherHash = hash(keysArray[index - 1]) // Bad case: // - <--- [hash] ------ [hole] ------ [otherHash] ---> + // \------------/ // probeDistance if ((otherHash - hash) and (hashSize - 1) >= probeDistance) { // move otherHash into the hole, move the hole hashArray[hole] = index presenceArray[index - 1] = hole hole = hash probeDistance = 0 } } // check how long we're patching holes if (--patchAttemptsLeft < 0) { // just place tombstone into the hole hashArray[hole] = TOMBSTONE return } } } internal fun containsEntry(entry: Map.Entry): Boolean { val index = findKey(entry.key) if (index < 0) return false return valuesArray!![index] == entry.value } internal fun getEntry(entry: Map.Entry): MutableMap.MutableEntry? { val index = findKey(entry.key) return if (index < 0 || valuesArray!![index] != entry.value) { null } else { EntryRef(this, index) } } internal fun getKey(key: K): K? { val index = findKey(key) return if (index >= 0) { keysArray[index]!! } else { null } } private fun contentEquals(other: Map<*, *>): Boolean = _size == other.size && containsAllEntries(other.entries) internal fun containsAllEntries(m: Collection<*>): Boolean { val it = m.iterator() while (it.hasNext()) { val entry = it.next() try { @Suppress("UNCHECKED_CAST") // todo: get rid of unchecked cast here somehow if (entry == null || !containsEntry(entry as Map.Entry)) return false } catch (e: ClassCastException) { return false } } return true } private fun putEntry(entry: Map.Entry): Boolean { val index = addKey(entry.key) val valuesArray = allocateValuesArray() if (index >= 0) { valuesArray[index] = entry.value return true } val oldValue = valuesArray[-index - 1] if (entry.value != oldValue) { valuesArray[-index - 1] = entry.value return true } return false } private fun putAllEntries(from: Collection>): Boolean { if (from.isEmpty()) return false ensureExtraCapacity(from.size) val it = from.iterator() var updated = false while (it.hasNext()) { if (putEntry(it.next())) updated = true } return updated } internal fun removeEntry(entry: Map.Entry): Boolean { checkIsMutable() val index = findKey(entry.key) if (index < 0) return false if (valuesArray!![index] != entry.value) return false removeKeyAt(index) return true } internal fun removeValue(element: V): Boolean { checkIsMutable() val index = findValue(element) if (index < 0) return false removeKeyAt(index) return true } internal fun keysIterator() = KeysItr(this) internal fun valuesIterator() = ValuesItr(this) internal fun entriesIterator() = EntriesItr(this) @kotlin.native.internal.CanBePrecreated private companion object { private const val MAGIC = -1640531527 // 2654435769L.toInt(), golden ratio private const val INITIAL_CAPACITY = 8 private const val INITIAL_MAX_PROBE_DISTANCE = 2 private const val TOMBSTONE = -1 @OptIn(ExperimentalStdlibApi::class) private fun computeHashSize(capacity: Int): Int = (capacity.coerceAtLeast(1) * 3).takeHighestOneBit() @OptIn(ExperimentalStdlibApi::class) private fun computeShift(hashSize: Int): Int = hashSize.countLeadingZeroBits() + 1 } internal open class Itr( internal val map: HashMap ) { internal var index = 0 internal var lastIndex: Int = -1 init { initNext() } internal fun initNext() { while (index < map.length && map.presenceArray[index] < 0) index++ } fun hasNext(): Boolean = index < map.length fun remove() { map.checkIsMutable() map.removeKeyAt(lastIndex) lastIndex = -1 } } internal class KeysItr(map: HashMap) : Itr(map), MutableIterator { override fun next(): K { if (index >= map.length) throw NoSuchElementException() lastIndex = index++ val result = map.keysArray[lastIndex] initNext() return result } } internal class ValuesItr(map: HashMap) : Itr(map), MutableIterator { override fun next(): V { if (index >= map.length) throw NoSuchElementException() lastIndex = index++ val result = map.valuesArray!![lastIndex] initNext() return result } } internal class EntriesItr(map: HashMap) : Itr(map), MutableIterator> { override fun next(): EntryRef { if (index >= map.length) throw NoSuchElementException() lastIndex = index++ val result = EntryRef(map, lastIndex) initNext() return result } internal fun nextHashCode(): Int { if (index >= map.length) throw NoSuchElementException() lastIndex = index++ val result = map.keysArray[lastIndex].hashCode() xor map.valuesArray!![lastIndex].hashCode() initNext() return result } fun nextAppendString(sb: StringBuilder) { if (index >= map.length) throw NoSuchElementException() lastIndex = index++ val key = map.keysArray[lastIndex] if (key == map) sb.append("(this Map)") else sb.append(key) sb.append('=') val value = map.valuesArray!![lastIndex] if (value == map) sb.append("(this Map)") else sb.append(value) initNext() } } internal class EntryRef( private val map: HashMap, private val index: Int ) : MutableMap.MutableEntry { override val key: K get() = map.keysArray[index] override val value: V get() = map.valuesArray!![index] override fun setValue(newValue: V): V { map.checkIsMutable() val valuesArray = map.allocateValuesArray() val oldValue = valuesArray[index] valuesArray[index] = newValue return oldValue } override fun equals(other: Any?): Boolean = other is Map.Entry<*, *> && other.key == key && other.value == value override fun hashCode(): Int = key.hashCode() xor value.hashCode() override fun toString(): String = "$key=$value" } } internal class HashMapKeys internal constructor( private val backing: HashMap ) : MutableSet, kotlin.native.internal.KonanSet, AbstractMutableSet() { override val size: Int get() = backing.size override fun isEmpty(): Boolean = backing.isEmpty() override fun contains(element: E): Boolean = backing.containsKey(element) override fun getElement(element: E): E? = backing.getKey(element) override fun clear() = backing.clear() override fun add(element: E): Boolean = throw UnsupportedOperationException() override fun addAll(elements: Collection): Boolean = throw UnsupportedOperationException() override fun remove(element: E): Boolean = backing.removeKey(element) >= 0 override fun iterator(): MutableIterator = backing.keysIterator() override fun removeAll(elements: Collection): Boolean { backing.checkIsMutable() return super.removeAll(elements) } override fun retainAll(elements: Collection): Boolean { backing.checkIsMutable() return super.retainAll(elements) } } internal class HashMapValues internal constructor( val backing: HashMap<*, V> ) : MutableCollection, AbstractMutableCollection() { override val size: Int get() = backing.size override fun isEmpty(): Boolean = backing.isEmpty() override fun contains(element: V): Boolean = backing.containsValue(element) override fun add(element: V): Boolean = throw UnsupportedOperationException() override fun addAll(elements: Collection): Boolean = throw UnsupportedOperationException() override fun clear() = backing.clear() override fun iterator(): MutableIterator = backing.valuesIterator() override fun remove(element: V): Boolean = backing.removeValue(element) override fun removeAll(elements: Collection): Boolean { backing.checkIsMutable() return super.removeAll(elements) } override fun retainAll(elements: Collection): Boolean { backing.checkIsMutable() return super.retainAll(elements) } } /** * Note: intermediate class with [E] `: Map.Entry` is required to support * [contains] for values that are [Map.Entry] but not [MutableMap.MutableEntry], * and probably same for other functions. * This is important because an instance of this class can be used as a result of [Map.entries], * which should support [contains] for [Map.Entry]. * For example, this happens when upcasting [MutableMap] to [Map]. * * The compiler enables special type-safe barriers to methods like [contains], which has [UnsafeVariance]. * Changing type from [MutableMap.MutableEntry] to [E] makes the compiler generate barriers checking that * argument `is` [E] (so technically `is` [Map.Entry]) instead of `is` [MutableMap.MutableEntry]. * * See also [KT-42248](https://youtrack.jetbrains.com/issue/KT-42428). */ internal abstract class HashMapEntrySetBase> internal constructor( val backing: HashMap ) : MutableSet, kotlin.native.internal.KonanSet, AbstractMutableSet() { override val size: Int get() = backing.size override fun isEmpty(): Boolean = backing.isEmpty() override fun contains(element: E): Boolean = backing.containsEntry(element) override fun getElement(element: E): E? = getEntry(element) protected abstract fun getEntry(element: Map.Entry): E? override fun clear() = backing.clear() override fun add(element: E): Boolean = throw UnsupportedOperationException() override fun addAll(elements: Collection): Boolean = throw UnsupportedOperationException() override fun remove(element: E): Boolean = backing.removeEntry(element) override fun containsAll(elements: Collection): Boolean = backing.containsAllEntries(elements) override fun removeAll(elements: Collection): Boolean { backing.checkIsMutable() return super.removeAll(elements) } override fun retainAll(elements: Collection): Boolean { backing.checkIsMutable() return super.retainAll(elements) } } internal class HashMapEntrySet internal constructor( backing: HashMap ) : HashMapEntrySetBase>(backing) { override fun getEntry(element: Map.Entry): MutableMap.MutableEntry? = backing.getEntry(element) override fun iterator(): MutableIterator> = backing.entriesIterator() } // This hash map keeps insertion order. actual typealias LinkedHashMap = HashMap ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/HashSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections actual class HashSet internal constructor( private val backing: HashMap ) : MutableSet, kotlin.native.internal.KonanSet, AbstractMutableSet() { actual constructor() : this(HashMap()) actual constructor(initialCapacity: Int) : this(HashMap(initialCapacity)) actual constructor(elements: Collection) : this(elements.size) { addAll(elements) } // This implementation doesn't use a loadFactor actual constructor(initialCapacity: Int, loadFactor: Float) : this(initialCapacity) @PublishedApi internal fun build(): Set { backing.build() return this } override actual val size: Int get() = backing.size override actual fun isEmpty(): Boolean = backing.isEmpty() override actual fun contains(element: E): Boolean = backing.containsKey(element) override fun getElement(element: E): E? = backing.getKey(element) override actual fun clear() = backing.clear() override actual fun add(element: E): Boolean = backing.addKey(element) >= 0 override actual fun remove(element: E): Boolean = backing.removeKey(element) >= 0 override actual fun iterator(): MutableIterator = backing.keysIterator() override actual fun addAll(elements: Collection): Boolean { backing.checkIsMutable() return super.addAll(elements) } override actual fun removeAll(elements: Collection): Boolean { backing.checkIsMutable() return super.removeAll(elements) } override actual fun retainAll(elements: Collection): Boolean { backing.checkIsMutable() return super.retainAll(elements) } } // This hash set keeps insertion order. actual typealias LinkedHashSet = HashSet ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Iterator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * An iterator over a collection or another entity that can be represented as a sequence of elements. * Allows to sequentially access the elements. */ public interface Iterator { /** * Returns the next element in the iteration. */ public operator fun next(): T /** * Returns `true` if the iteration has more elements. */ public operator fun hasNext(): Boolean } /** * An iterator over a mutable collection. Provides the ability to remove elements while iterating. * @see MutableCollection.iterator */ public interface MutableIterator : Iterator { /** * Removes from the underlying collection the last element returned by this iterator. */ public fun remove(): Unit } /** * An iterator over a collection that supports indexed access. * @see List.listIterator */ public interface ListIterator : Iterator { // Query Operations override fun next(): T override fun hasNext(): Boolean /** * Returns `true` if there are elements in the iteration before the current element. */ public fun hasPrevious(): Boolean /** * Returns the previous element in the iteration and moves the cursor position backwards. */ public fun previous(): T /** * Returns the index of the element that would be returned by a subsequent call to [next]. */ public fun nextIndex(): Int /** * Returns the index of the element that would be returned by a subsequent call to [previous]. */ public fun previousIndex(): Int } /** * An iterator over a mutable collection that supports indexed access. Provides the ability * to add, modify and remove elements while iterating. */ public interface MutableListIterator : ListIterator, MutableIterator { // Query Operations override fun next(): T override fun hasNext(): Boolean // Modification Operations override fun remove(): Unit /** * Replaces the last element returned by [next] or [previous] with the specified element [element]. */ public fun set(element: T): Unit /** * Adds the specified element [element] into the underlying collection immediately before the element that would be * returned by [next], if any, and after the element that would be returned by [previous], if any. * (If the collection contains no elements, the new element becomes the sole element in the collection.) * The new element is inserted before the implicit cursor: a subsequent call to [next] would be unaffected, * and a subsequent call to [previous] would return the new element. (This call increases by one the value \ * that would be returned by a call to [nextIndex] or [previousIndex].) */ public fun add(element: T): Unit } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Iterators.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** An iterator over a sequence of values of type `Byte`. */ public abstract class ByteIterator : Iterator { override final fun next() = nextByte() /** Returns the next value in the sequence without boxing. */ public abstract fun nextByte(): Byte } /** An iterator over a sequence of values of type `Char`. */ public abstract class CharIterator : Iterator { override final fun next() = nextChar() /** Returns the next value in the sequence without boxing. */ public abstract fun nextChar(): Char } /** An iterator over a sequence of values of type `Short`. */ public abstract class ShortIterator : Iterator { override final fun next() = nextShort() /** Returns the next value in the sequence without boxing. */ public abstract fun nextShort(): Short } /** An iterator over a sequence of values of type `Int`. */ public abstract class IntIterator : Iterator { override final fun next() = nextInt() /** Returns the next value in the sequence without boxing. */ public abstract fun nextInt(): Int } /** An iterator over a sequence of values of type `Long`. */ public abstract class LongIterator : Iterator { override final fun next() = nextLong() /** Returns the next value in the sequence without boxing. */ public abstract fun nextLong(): Long } /** An iterator over a sequence of values of type `Float`. */ public abstract class FloatIterator : Iterator { override final fun next() = nextFloat() /** Returns the next value in the sequence without boxing. */ public abstract fun nextFloat(): Float } /** An iterator over a sequence of values of type `Double`. */ public abstract class DoubleIterator : Iterator { override final fun next() = nextDouble() /** Returns the next value in the sequence without boxing. */ public abstract fun nextDouble(): Double } /** An iterator over a sequence of values of type `Boolean`. */ public abstract class BooleanIterator : Iterator { override final fun next() = nextBoolean() /** Returns the next value in the sequence without boxing. */ public abstract fun nextBoolean(): Boolean } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/List.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * A generic ordered collection of elements. Methods in this interface support only read-only access to the list; * read/write access is supported through the [MutableList] interface. * @param E the type of elements contained in the list. The list is covariant in its element type. */ public interface List : Collection { // Query Operations override val size: Int override fun isEmpty(): Boolean override fun contains(element: @UnsafeVariance E): Boolean override fun iterator(): Iterator // Bulk Operations override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean // Positional Access Operations /** * Returns the element at the specified index in the list. */ public operator fun get(index: Int): E // Search Operations /** * Returns the index of the first occurrence of the specified element in the list, or -1 if the specified * element is not contained in the list. */ public fun indexOf(element: @UnsafeVariance E): Int /** * Returns the index of the last occurrence of the specified element in the list, or -1 if the specified * element is not contained in the list. */ public fun lastIndexOf(element: @UnsafeVariance E): Int // List Iterators /** * Returns a list iterator over the elements in this list (in proper sequence). */ public fun listIterator(): ListIterator /** * Returns a list iterator over the elements in this list (in proper sequence), starting at the specified [index]. */ public fun listIterator(index: Int): ListIterator // View /** * Returns a view of the portion of this list between the specified [fromIndex] (inclusive) and [toIndex] (exclusive). * The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa. * * Structural changes in the base list make the behavior of the view undefined. */ public fun subList(fromIndex: Int, toIndex: Int): List } /** * A generic ordered collection of elements that supports adding and removing elements. * @param E the type of elements contained in the list. The mutable list is invariant in its element type. */ public interface MutableList : List, MutableCollection { // Modification Operations /** * Adds the specified element to the end of this list. * * @return `true` because the list is always modified as the result of this operation. */ override fun add(element: E): Boolean override fun remove(element: E): Boolean // Bulk Modification Operations /** * Adds all of the elements of the specified collection to the end of this list. * * The elements are appended in the order they appear in the [elements] collection. * * @return `true` if the list was changed as the result of the operation. */ override fun addAll(elements: Collection): Boolean /** * Inserts all of the elements of the specified collection [elements] into this list at the specified [index]. * * @return `true` if the list was changed as the result of the operation. */ public fun addAll(index: Int, elements: Collection): Boolean override fun removeAll(elements: Collection): Boolean override fun retainAll(elements: Collection): Boolean override fun clear(): Unit // Positional Access Operations /** * Replaces the element at the specified position in this list with the specified element. * * @return the element previously at the specified position. */ public operator fun set(index: Int, element: E): E /** * Inserts an element into the list at the specified [index]. */ public fun add(index: Int, element: E): Unit /** * Removes an element at the specified [index] from the list. * * @return the element that has been removed. */ public fun removeAt(index: Int): E // List Iterators override fun listIterator(): MutableListIterator override fun listIterator(index: Int): MutableListIterator // View override fun subList(fromIndex: Int, toIndex: Int): MutableList } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Map.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * A collection that holds pairs of objects (keys and values) and supports efficiently retrieving * the value corresponding to each key. Map keys are unique; the map holds only one value for each key. * Methods in this interface support only read-only access to the map; read-write access is supported through * the [MutableMap] interface. * @param K the type of map keys. The map is invariant in its key type, as it * can accept key as a parameter (of [containsKey] for example) and return it in [keys] set. * @param V the type of map values. The map is covariant in its value type. */ public interface Map { // Query Operations /** * Returns the number of key/value pairs in the map. */ public val size: Int /** * Returns `true` if the map is empty (contains no elements), `false` otherwise. */ public fun isEmpty(): Boolean /** * Returns `true` if the map contains the specified [key]. */ public fun containsKey(key: K): Boolean /** * Returns `true` if the map maps one or more keys to the specified [value]. */ public fun containsValue(value: @UnsafeVariance V): Boolean /** * Returns the value corresponding to the given [key], or `null` if such a key is not present in the map. */ public operator fun get(key: K): V? // Views /** * Returns a read-only [Set] of all keys in this map. */ public val keys: Set /** * Returns a read-only [Collection] of all values in this map. Note that this collection may contain duplicate values. */ public val values: Collection /** * Returns a read-only [Set] of all key/value pairs in this map. */ public val entries: Set> /** * Represents a key/value pair held by a [Map]. */ public interface Entry { /** * Returns the key of this key/value pair. */ public val key: K /** * Returns the value of this key/value pair. */ public val value: V } } /** * A modifiable collection that holds pairs of objects (keys and values) and supports efficiently retrieving * the value corresponding to each key. Map keys are unique; the map holds only one value for each key. * @param K the type of map keys. The map is invariant in its key type. * @param V the type of map values. The mutable map is invariant in its value type. */ public interface MutableMap : Map { // Modification Operations /** * Associates the specified [value] with the specified [key] in the map. * * @return the previous value associated with the key, or `null` if the key was not present in the map. */ public fun put(key: K, value: V): V? /** * Removes the specified key and its corresponding value from this map. * * @return the previous value associated with the key, or `null` if the key was not present in the map. */ public fun remove(key: K): V? // Bulk Modification Operations /** * Updates this map with key/value pairs from the specified map [from]. */ public fun putAll(from: Map): Unit /** * Removes all elements from this map. */ public fun clear(): Unit // Views /** * Returns a [MutableSet] of all keys in this map. */ override val keys: MutableSet /** * Returns a [MutableCollection] of all values in this map. Note that this collection may contain duplicate values. */ override val values: MutableCollection /** * Returns a [MutableSet] of all key/value pairs in this map. */ override val entries: MutableSet> /** * Represents a key/value pair held by a [MutableMap]. */ public interface MutableEntry : Map.Entry { /** * Changes the value associated with the key of this entry. * * @return the previous value corresponding to the key. */ public fun setValue(newValue: V): V } } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Maps.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildMapInternal(builderAction: MutableMap.() -> Unit): Map { return HashMap().apply(builderAction).build() } @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildMapInternal(capacity: Int, builderAction: MutableMap.() -> Unit): Map { return HashMap(capacity).apply(builderAction).build() } // creates a singleton copy of map, if there is specialization available in target platform, otherwise returns itself @Suppress("NOTHING_TO_INLINE") internal inline actual fun Map.toSingletonMapOrSelf(): Map = toSingletonMap() // creates a singleton copy of map internal actual fun Map.toSingletonMap(): Map = with(entries.iterator().next()) { mutableMapOf(key to value) } /** * Native map and set implementations do not make use of capacities or load factors. */ @PublishedApi internal actual fun mapCapacity(expectedSize: Int) = expectedSize ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/MutableCollections.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * Sorts elements in the list in-place according to their natural sort order. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public actual fun > MutableList.sort(): Unit = sortWith(naturalOrder()) /** * Sorts elements in the list in-place according to the order specified with [comparator]. * * The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting. */ public actual fun MutableList.sortWith(comparator: Comparator): Unit { if (size > 1) { val it = listIterator() val sortedArray = @Suppress("UNCHECKED_CAST") (toTypedArray() as Array).apply { sortWith(comparator) } for (v in sortedArray) { it.next() it.set(v) } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/RandomAccess.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * Marker interface indicating that the [List] implementation supports fast indexed access. */ public actual interface RandomAccess ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Set.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections /** * A generic unordered collection of elements that does not support duplicate elements. * Methods in this interface support only read-only access to the set; * read/write access is supported through the [MutableSet] interface. * @param E the type of elements contained in the set. The set is covariant in its element type. */ public interface Set : Collection { // Query Operations override val size: Int override fun isEmpty(): Boolean override fun contains(element: @UnsafeVariance E): Boolean override fun iterator(): Iterator // Bulk Operations override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean } /** * A generic unordered collection of elements that does not support duplicate elements, and supports * adding and removing elements. * @param E the type of elements contained in the set. The mutable set is invariant in its element type. */ public interface MutableSet : Set, MutableCollection { // Query Operations override fun iterator(): MutableIterator // Modification Operations /** * Adds the specified element to the set. * * @return `true` if the element has been added, `false` if the element is already contained in the set. */ override fun add(element: E): Boolean override fun remove(element: E): Boolean // Bulk Modification Operations override fun addAll(elements: Collection): Boolean override fun removeAll(elements: Collection): Boolean override fun retainAll(elements: Collection): Boolean override fun clear(): Unit } ================================================ FILE: runtime/src/main/kotlin/kotlin/collections/Sets.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.collections // TODO: Add SingletonSet class /** * Returns an immutable set containing only the specified object [element]. */ public fun setOf(element: T): Set = hashSetOf(element) @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildSetInternal(builderAction: MutableSet.() -> Unit): Set { return HashSet().apply(builderAction).build() } @PublishedApi @SinceKotlin("1.3") @ExperimentalStdlibApi @kotlin.internal.InlineOnly internal actual inline fun buildSetInternal(capacity: Int, builderAction: MutableSet.() -> Unit): Set { return HashSet(capacity).apply(builderAction).build() } ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines.native.internal import kotlin.coroutines.* import kotlin.coroutines.intrinsics.CoroutineSingletons import kotlin.coroutines.intrinsics.* @SinceKotlin("1.3") internal abstract class BaseContinuationImpl( // This is `public val` so that it is private on JVM and cannot be modified by untrusted code, yet // it has a public getter (since even untrusted code is allowed to inspect its call stack). public val completion: Continuation? ) : Continuation, Serializable { // This implementation is final. This fact is used to unroll resumeWith recursion. public final override fun resumeWith(result: Result) { // Invoke "resume" debug probe only once, even if previous frames are "resumed" in the loop below, too probeCoroutineResumed(this) // This loop unrolls recursion in current.resumeWith(param) to make saner and shorter stack traces on resume var current = this var param = result while (true) { with(current) { val completion = completion!! // fail fast when trying to resume continuation without completion val outcome: Result = try { val outcome = invokeSuspend(param) if (outcome === COROUTINE_SUSPENDED) return Result.success(outcome) } catch (exception: Throwable) { Result.failure(exception) } releaseIntercepted() // this state machine instance is terminating if (completion is BaseContinuationImpl) { // unrolling recursion via loop current = completion param = outcome } else { // top-level completion reached -- invoke and return completion.resumeWith(outcome) return } } } } protected abstract fun invokeSuspend(result: Result): Any? protected open fun releaseIntercepted() { // does nothing here, overridden in ContinuationImpl } public open fun create(completion: Continuation<*>): Continuation { throw UnsupportedOperationException("create(Continuation) has not been overridden") } public open fun create(value: Any?, completion: Continuation<*>): Continuation { throw UnsupportedOperationException("create(Any?;Continuation) has not been overridden") } public override fun toString(): String { // todo: how continuation shall be rendered? return "Continuation @ ${this::class.simpleName}" } } @SinceKotlin("1.3") // State machines for named restricted suspend functions extend from this class internal abstract class RestrictedContinuationImpl( completion: Continuation? ) : BaseContinuationImpl(completion) { init { completion?.let { require(it.context === EmptyCoroutineContext) { "Coroutines with restricted suspension must have EmptyCoroutineContext" } } } public override val context: CoroutineContext get() = EmptyCoroutineContext } @SinceKotlin("1.3") // State machines for named suspend functions extend from this class internal abstract class ContinuationImpl( completion: Continuation?, private val _context: CoroutineContext? ) : BaseContinuationImpl(completion) { constructor(completion: Continuation?) : this(completion, completion?.context) public override val context: CoroutineContext get() = _context!! private var intercepted: Continuation? = null public fun intercepted(): Continuation = intercepted ?: (context[ContinuationInterceptor]?.interceptContinuation(this) ?: this) .also { intercepted = it } protected override fun releaseIntercepted() { val intercepted = intercepted if (intercepted != null && intercepted !== this) { context[ContinuationInterceptor]!!.releaseInterceptedContinuation(intercepted) } this.intercepted = CompletedContinuation // just in case } } internal object CompletedContinuation : Continuation { override val context: CoroutineContext get() = error("This continuation is already complete") override fun resumeWith(result: Result) { error("This continuation is already complete") } override fun toString(): String = "This continuation is already complete" } ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/DebugProbes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines.native.internal // TODO: support coroutines debugging in Kotlin/Native. import kotlin.coroutines.Continuation import kotlin.coroutines.intrinsics.* /** * This probe is invoked when coroutine is being created and it can replace completion * with its own wrapped object to intercept completion of this coroutine. * * This probe is invoked from stdlib implementation of [createCoroutineUnintercepted] function. * * Once created, coroutine is repeatedly [resumed][probeCoroutineResumed] and [suspended][probeCoroutineSuspended], * until it is complete. On completion, the object that was returned by this probe is invoked. * * ``` * +-------+ probeCoroutineCreated +-----------+ * | START | ---------------------->| SUSPENDED | * +-------+ +-----------+ * probeCoroutineResumed | ^ probeCoroutineSuspended * V | * +------------+ completion invoked +-----------+ * | RUNNING | ------------------->| COMPLETED | * +------------+ +-----------+ * ``` * * While the coroutine is resumed and suspended, it is represented by the pointer to its `frame` * which always extends [BaseContinuationImpl] and represents a pointer to the topmost frame of the * coroutine. Each [BaseContinuationImpl] object has [completion][BaseContinuationImpl.completion] reference * that points either to another frame (extending [BaseContinuationImpl]) or to the completion object * that was returned by this `probeCoroutineCreated` function. * * When coroutine is [suspended][probeCoroutineSuspended], then it is later [resumed][probeCoroutineResumed] * with a reference to the same frame. However, while coroutine is running it can unwind its frames and * invoke other suspending functions, so its next suspension can happen with a different frame pointer. */ @SinceKotlin("1.3") internal fun probeCoroutineCreated(completion: Continuation): Continuation { return completion } /** * This probe is invoked when coroutine is resumed using [Continuation.resumeWith]. * * This probe is invoked from stdlib implementation of [BaseContinuationImpl.resumeWith] function. * * Coroutines machinery implementation guarantees that the actual [frame] instance extends * [BaseContinuationImpl] class, despite the fact that the declared type of [frame] * parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details. */ @Suppress("UNUSED_PARAMETER") @SinceKotlin("1.3") internal fun probeCoroutineResumed(frame: Continuation<*>) { } /** * This probe is invoked when coroutine is suspended using [suspendCoroutineUninterceptedOrReturn], that is * when the corresponding `block` returns [COROUTINE_SUSPENDED]. * * This probe is invoked from compiler-generated intrinsic for [suspendCoroutineUninterceptedOrReturn] function. * * Coroutines machinery implementation guarantees that the actual [frame] instance extends * [BaseContinuationImpl] class, despite the fact that the declared type of [frame] * parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details. */ @Suppress("UNUSED_PARAMETER") @SinceKotlin("1.3") internal fun probeCoroutineSuspended(frame: Continuation<*>) { } ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/SafeContinuationNative.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines import kotlin.* import kotlin.coroutines.intrinsics.CoroutineSingletons.* import kotlin.coroutines.intrinsics.* @PublishedApi @SinceKotlin("1.3") internal actual class SafeContinuation internal actual constructor( private val delegate: Continuation, initialResult: Any? ) : Continuation { @PublishedApi internal actual constructor(delegate: Continuation) : this(delegate, UNDECIDED) public actual override val context: CoroutineContext get() = delegate.context private var result: Any? = initialResult public actual override fun resumeWith(result: Result) { val cur = this.result when { cur === UNDECIDED -> this.result = result.value cur === COROUTINE_SUSPENDED -> { this.result = RESUMED delegate.resumeWith(result) } else -> throw IllegalStateException("Already resumed") } } @PublishedApi internal actual fun getOrThrow(): Any? { val result = this.result if (result === UNDECIDED) { this.result = COROUTINE_SUSPENDED return COROUTINE_SUSPENDED } return when { result === RESUMED -> COROUTINE_SUSPENDED // already called continuation, indicate COROUTINE_SUSPENDED upstream result is Result.Failure -> throw result.exception else -> result // either COROUTINE_SUSPENDED or data } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/SuspendFunction.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines import kotlin.native.internal.FixmeReflection /** * Represents a value of a functional type, such as a lambda, an anonymous function or a function reference. * * @param R return type of the function. */ @FixmeReflection public interface SuspendFunction ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/cancellation/CancellationException.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines.cancellation @SinceKotlin("1.4") public actual open class CancellationException : IllegalStateException { actual constructor() : super() actual constructor(message: String?) : super(message) constructor(message: String?, cause: Throwable?) : super(message, cause) constructor(cause: Throwable?) : super(cause) } ================================================ FILE: runtime/src/main/kotlin/kotlin/coroutines/intrinsics/IntrinsicsNative.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.coroutines.intrinsics import kotlin.coroutines.* import kotlin.coroutines.native.internal.* import kotlin.native.internal.* /** * Starts an unintercepted coroutine without a receiver and with result type [T] and executes it until its first suspension. * Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends. * In the latter case, the [completion] continuation is invoked when the coroutine completes with a result or an exception. * * The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might * be present in the completion's [CoroutineContext]. It is the invoker's responsibility to ensure that a proper invocation * context is established. * * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of the suspended * coroutine using a reference to the suspending function. */ @Suppress("UNCHECKED_CAST") @kotlin.internal.InlineOnly public actual inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation ): Any? = (this as Function1, Any?>).invoke(completion) /** * Starts an unintercepted coroutine with receiver type [R] and result type [T] and executes it until its first suspension. * Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends. * In the latter case, the [completion] continuation is invoked when the coroutine completes with a result or an exception. * * The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might * be present in the completion's [CoroutineContext]. It is the invoker's responsibility to ensure that a proper invocation * context is established. * * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of the suspended * coroutine using a reference to the suspending function. */ @Suppress("UNCHECKED_CAST") @kotlin.internal.InlineOnly public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedOrReturn( receiver: R, completion: Continuation ): Any? = (this as Function2, Any?>).invoke(receiver, completion) @Suppress("UNCHECKED_CAST") @kotlin.internal.InlineOnly internal actual inline fun (suspend R.(P) -> T).startCoroutineUninterceptedOrReturn( receiver: R, param: P, completion: Continuation ): Any? = (this as Function3, Any?>).invoke(receiver, param, completion) private object CoroutineSuspendedMarker /** * Creates unintercepted coroutine without receiver and with result type [T]. * This function creates a new, fresh instance of suspendable computation every time it is invoked. * * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. * The [completion] continuation is invoked when coroutine completes with result or exception. * * This function returns unintercepted continuation. * Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the * [ContinuationInterceptor] that might be present in the completion's [CoroutineContext]. * It is the invoker's responsibility to ensure that a proper invocation context is established. * Note that [completion] of this function may get invoked in an arbitrary context. * * [Continuation.intercepted] can be used to acquire the intercepted continuation. * Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of * both the coroutine and [completion] happens in the invocation context established by * [ContinuationInterceptor]. * * Repeated invocation of any resume function on the resulting continuation corrupts the * state machine of the coroutine and may result in arbitrary behaviour or exception. */ @SinceKotlin("1.3") @Suppress("UNCHECKED_CAST") public actual fun (suspend () -> T).createCoroutineUnintercepted( completion: Continuation ): Continuation { val probeCompletion = probeCoroutineCreated(completion) return if (this is BaseContinuationImpl) create(probeCompletion) else createCoroutineFromSuspendFunction(probeCompletion) { (this as Function1, Any?>).invoke(it) } } /** * Creates unintercepted coroutine with receiver type [R] and result type [T]. * This function creates a new, fresh instance of suspendable computation every time it is invoked. * * To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance. * The [completion] continuation is invoked when coroutine completes with result or exception. * * This function returns unintercepted continuation. * Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the * [ContinuationInterceptor] that might be present in the completion's [CoroutineContext]. * It is the invoker's responsibility to ensure that a proper invocation context is established. * Note that [completion] of this function may get invoked in an arbitrary context. * * [Continuation.intercepted] can be used to acquire the intercepted continuation. * Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of * both the coroutine and [completion] happens in the invocation context established by * [ContinuationInterceptor]. * * Repeated invocation of any resume function on the resulting continuation corrupts the * state machine of the coroutine and may result in arbitrary behaviour or exception. */ @SinceKotlin("1.3") @Suppress("UNCHECKED_CAST") public actual fun (suspend R.() -> T).createCoroutineUnintercepted( receiver: R, completion: Continuation ): Continuation { val probeCompletion = probeCoroutineCreated(completion) return if (this is BaseContinuationImpl) create(receiver, probeCompletion) else { createCoroutineFromSuspendFunction(probeCompletion) { (this as Function2, Any?>).invoke(receiver, it) } } } /** * Intercepts this continuation with [ContinuationInterceptor]. * * This function shall be used on the immediate result of [createCoroutineUnintercepted] or [suspendCoroutineUninterceptedOrReturn], * in which case it checks for [ContinuationInterceptor] in the continuation's [context][Continuation.context], * invokes [ContinuationInterceptor.interceptContinuation], caches and returns the result. * * If this function is invoked on other [Continuation] instances it returns `this` continuation unchanged. */ @SinceKotlin("1.3") public actual fun Continuation.intercepted(): Continuation = (this as? ContinuationImpl)?.intercepted() ?: this // INTERNAL DEFINITIONS /** * This function is used when [createCoroutineUnintercepted] encounters suspending lambda that does not extend BaseContinuationImpl. * * It happens in two cases: * 1. Callable reference to suspending function, * 2. Suspending function reference implemented by Java code. * * We must wrap it into an instance that extends [BaseContinuationImpl], because that is an expectation of all coroutines machinery. * As an optimization we use lighter-weight [RestrictedContinuationImpl] base class (it has less fields) if the context is * [EmptyCoroutineContext], and a full-blown [ContinuationImpl] class otherwise. * * The instance of [BaseContinuationImpl] is passed to the [block] so that it can be passed to the corresponding invocation. */ @SinceKotlin("1.3") @Suppress("UNCHECKED_CAST") private inline fun createCoroutineFromSuspendFunction( completion: Continuation, crossinline block: (Continuation) -> Any? ): Continuation { val context = completion.context // label == 0 when coroutine is not started yet (initially) or label == 1 when it was return if (context === EmptyCoroutineContext) object : RestrictedContinuationImpl(completion as Continuation) { private var label = 0 override fun invokeSuspend(result: Result): Any? = when (label) { 0 -> { label = 1 result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith block(this) // run the block, may return or suspend } 1 -> { label = 2 result.getOrThrow() // this is the result if the block had suspended } else -> error("This coroutine had already completed") } } else object : ContinuationImpl(completion as Continuation, context) { private var label = 0 override fun invokeSuspend(result: Result): Any? = when (label) { 0 -> { label = 1 result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith block(this) // run the block, may return or suspend } 1 -> { label = 2 result.getOrThrow() // this is the result if the block had suspended } else -> error("This coroutine had already completed") } } } /** * This function creates continuation suitable for passing as implicit argument to suspend functions. * The continuation calls [callback] and then delegates to [completion]. * * The result is [ContinuationImpl] because that is an expectation of all coroutines machinery. * * It can be thought as a state machine of * ``` * suspend fun foo() { * val result = runCatching { } * callback(result) * } * ``` */ @Suppress("UNCHECKED_CAST") internal inline fun createContinuationArgumentFromCallback( completion: Continuation, crossinline callback: (Result) -> Unit ): Continuation = object : ContinuationImpl(completion as Continuation) { private var invoked = false override fun invokeSuspend(result: Result): Any? { if (invoked) error("This coroutine had already completed") invoked = true callback(result) return Unit // Not suspended. } } ================================================ FILE: runtime/src/main/kotlin/kotlin/internal/Annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.internal /** * Specifies that the corresponding type parameter is not used for unsafe operations such as casts or 'is' checks * That means it's completely safe to use generic types as argument for such parameter. */ @Target(AnnotationTarget.TYPE_PARAMETER) @Retention(AnnotationRetention.BINARY) internal annotation class PureReifiable ================================================ FILE: runtime/src/main/kotlin/kotlin/internal/ProgressionUtil.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.internal // a mod b (in arithmetical sense) private fun mod(a: Int, b: Int): Int { val mod = a % b return if (mod >= 0) mod else mod + b } private fun mod(a: Long, b: Long): Long { val mod = a % b return if (mod >= 0) mod else mod + b } // (a - b) mod c private fun differenceModulo(a: Int, b: Int, c: Int): Int { return mod(mod(a, c) - mod(b, c), c) } private fun differenceModulo(a: Long, b: Long, c: Long): Long { return mod(mod(a, c) - mod(b, c), c) } /** * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range * from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative * [step]. * * No validation on passed parameters is performed. The given parameters should satisfy the condition: * * - either `step > 0` and `start <= end`, * - or `step < 0` and `start >= end`. * * @param start first element of the progression * @param end ending bound for the progression * @param step increment, or difference of successive elements in the progression * @return the final element of the progression * @suppress */ @PublishedApi internal fun getProgressionLastElement(start: Int, end: Int, step: Int): Int = when { step > 0 -> if (start >= end) end else end - differenceModulo(end, start, step) step < 0 -> if (start <= end) end else end + differenceModulo(start, end, -step) else -> throw kotlin.IllegalArgumentException("Step is zero.") } /** * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range * from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative * [step]. * * No validation on passed parameters is performed. The given parameters should satisfy the condition: * * - either `step > 0` and `start <= end`, * - or `step < 0` and `start >= end`. * * @param start first element of the progression * @param end ending bound for the progression * @param step increment, or difference of successive elements in the progression * @return the final element of the progression * @suppress */ @PublishedApi internal fun getProgressionLastElement(start: Long, end: Long, step: Long): Long = when { step > 0 -> if (start >= end) end else end - differenceModulo(end, start, step) step < 0 -> if (start <= end) end else end + differenceModulo(start, end, -step) else -> throw kotlin.IllegalArgumentException("Step is zero.") } ================================================ FILE: runtime/src/main/kotlin/kotlin/io/Console.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.io /** Prints the given [message] to the standard output stream. */ @SymbolName("Kotlin_io_Console_print") external public fun print(message: String) /** Prints the given [message] to the standard output stream. */ public actual fun print(message: Any?) { print(message.toString()) } /** Prints the given [message] and the line separator to the standard output stream. */ @SymbolName("Kotlin_io_Console_println") external public fun println(message: String) /** Prints the given [message] and the line separator to the standard output stream. */ public actual fun println(message: Any?) { println(message.toString()) } /** Prints the line separator to the standard output stream. */ @SymbolName("Kotlin_io_Console_println0") external public actual fun println() /** * Reads a line of input from the standard input stream. * * @return the line read or `null` if the input stream is redirected to a file and the end of file has been reached. */ @SymbolName("Kotlin_io_Console_readLine") external public fun readLine(): String? ================================================ FILE: runtime/src/main/kotlin/kotlin/io/Serializable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.io // TODO: This interface is a temporary solution for common collections and not used in Native. internal actual interface Serializable ================================================ FILE: runtime/src/main/kotlin/kotlin/math/math.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.math // region ================ Double Math ======================================== /** Computes the sine of the angle [x] given in radians. * * Special cases: * - `sin(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sin") external public actual fun sin(x: Double): Double /** Computes the cosine of the angle [x] given in radians. * * Special cases: * - `cos(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_cos") external public actual fun cos(x: Double): Double /** Computes the tangent of the angle [x] given in radians. * * Special cases: * - `tan(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_tan") external public actual fun tan(x: Double): Double /** * Computes the arc sine of the value [x]; * the returned value is an angle in the range from `-PI/2` to `PI/2` radians. * * Special cases: * - `asin(x)` is `NaN`, when `abs(x) > 1` or x is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_asin") external public actual fun asin(x: Double): Double /** * Computes the arc cosine of the value [x]; * the returned value is an angle in the range from `0.0` to `PI` radians. * * Special cases: * - `acos(x)` is `NaN`, when `abs(x) > 1` or x is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_acos") external public actual fun acos(x: Double): Double /** * Computes the arc tangent of the value [x]; * the returned value is an angle in the range from `-PI/2` to `PI/2` radians. * * Special cases: * - `atan(NaN)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atan") external public actual fun atan(x: Double): Double /** * Returns the angle `theta` of the polar coordinates `(r, theta)` that correspond * to the rectangular coordinates `(x, y)` by computing the arc tangent of the value [y] / [x]; * the returned value is an angle in the range from `-PI` to `PI` radians. * * Special cases: * - `atan2(0.0, 0.0)` is `0.0` * - `atan2(0.0, x)` is `0.0` for `x > 0` and `PI` for `x < 0` * - `atan2(-0.0, x)` is `-0.0` for 'x > 0` and `-PI` for `x < 0` * - `atan2(y, +Inf)` is `0.0` for `0 < y < +Inf` and `-0.0` for '-Inf < y < 0` * - `atan2(y, -Inf)` is `PI` for `0 < y < +Inf` and `-PI` for `-Inf < y < 0` * - `atan2(y, 0.0)` is `PI/2` for `y > 0` and `-PI/2` for `y < 0` * - `atan2(+Inf, x)` is `PI/2` for finite `x`y * - `atan2(-Inf, x)` is `-PI/2` for finite `x` * - `atan2(NaN, x)` and `atan2(y, NaN)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atan2") external public actual fun atan2(y: Double, x: Double): Double /** * Computes the hyperbolic sine of the value [x]. * * Special cases: * - `sinh(NaN)` is `NaN` * - `sinh(+Inf)` is `+Inf` * - `sinh(-Inf)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sinh") external public actual fun sinh(x: Double): Double /** * Computes the hyperbolic cosine of the value [x]. * * Special cases: * - `cosh(NaN)` is `NaN` * - `cosh(+Inf|-Inf)` is `+Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_cosh") external public actual fun cosh(x: Double): Double /** * Computes the hyperbolic tangent of the value [x]. * * Special cases: * - `tanh(NaN)` is `NaN` * - `tanh(+Inf)` is `1.0` * - `tanh(-Inf)` is `-1.0` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_tanh") external public actual fun tanh(x: Double): Double /** * Computes the inverse hyperbolic sine of the value [x]. * * The returned value is `y` such that `sinh(y) == x`. * * Special cases: * - `asinh(NaN)` is `NaN` * - `asinh(+Inf)` is `+Inf` * - `asinh(-Inf)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_asinh") external public actual fun asinh(x: Double): Double /** * Computes the inverse hyperbolic cosine of the value [x]. * * The returned value is positive `y` such that `cosh(y) == x`. * * Special cases: * - `acosh(NaN)` is `NaN` * - `acosh(x)` is `NaN` when `x < 1` * - `acosh(+Inf)` is `+Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_acosh") external public actual fun acosh(x: Double): Double /** * Computes the inverse hyperbolic tangent of the value [x]. * * The returned value is `y` such that `tanh(y) == x`. * * Special cases: * - `tanh(NaN)` is `NaN` * - `tanh(x)` is `NaN` when `x > 1` or `x < -1` * - `tanh(1.0)` is `+Inf` * - `tanh(-1.0)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atanh") external public actual fun atanh(x: Double): Double /** * Computes `sqrt(x^2 + y^2)` without intermediate overflow or underflow. * * Special cases: * - returns `+Inf` if any of arguments is infinite * - returns `NaN` if any of arguments is `NaN` and the other is not infinite */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_hypot") external public actual fun hypot(x: Double, y: Double): Double /** * Computes the positive square root of the value [x]. * * Special cases: * - `sqrt(x)` is `NaN` when `x < 0` or `x` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sqrt") external public actual fun sqrt(x: Double): Double /** * Computes Euler's number `e` raised to the power of the value [x]. * * Special cases: * - `exp(NaN)` is `NaN` * - `exp(+Inf)` is `+Inf` * - `exp(-Inf)` is `0.0` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_exp") external public actual fun exp(x: Double): Double /** * Computes `exp(x) - 1`. * * This function can be implemented to produce more precise result for [x] near zero. * * Special cases: * - `expm1(NaN)` is `NaN` * - `expm1(+Inf)` is `+Inf` * - `expm1(-Inf)` is `-1.0` * * @see [exp] function. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_expm1") external public actual fun expm1(x: Double): Double /** * Computes the logarithm of the value [x] to the given [base]. * * Special cases: * - `log(x, b)` is `NaN` if either `x` or `b` are `NaN` * - `log(x, b)` is `NaN` when `x < 0` or `b <= 0` or `b == 1.0` * - `log(+Inf, +Inf)` is `NaN` * - `log(+Inf, b)` is `+Inf` for `b > 1` and `-Inf` for `b < 1` * - `log(0.0, b)` is `-Inf` for `b > 1` and `+Inf` for `b > 1` * * See also logarithm functions for common fixed bases: [ln], [log10] and [log2]. */ @SinceKotlin("1.2") public actual fun log(x: Double, base: Double): Double { if (base <= 0.0 || base == 1.0) return Double.NaN return ln(x) / ln(base) } /** * Computes the natural logarithm (base `E`) of the value [x]. * * Special cases: * - `ln(NaN)` is `NaN` * - `ln(x)` is `NaN` when `x < 0.0` * - `ln(+Inf)` is `+Inf` * - `ln(0.0)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_ln") external public actual fun ln(x: Double): Double /** * Computes the common logarithm (base 10) of the value [x]. * * @see [ln] actual function for special cases. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_log10") external public actual fun log10(x: Double): Double /** * Computes the binary logarithm (base 2) of the value [x]. * * @see [ln] actual function for special cases. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_log2") external public actual fun log2(x: Double): Double /** * Computes `ln(x + 1)`. * * This function can be implemented to produce more precise result for [x] near zero. * * Special cases: * - `ln1p(NaN)` is `NaN` * - `ln1p(x)` is `NaN` where `x < -1.0` * - `ln1p(-1.0)` is `-Inf` * - `ln1p(+Inf)` is `+Inf` * * @see [ln] function * @see [expm1] function */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_ln1p") external public actual fun ln1p(x: Double): Double /** * Rounds the given value [x] to an integer towards positive infinity. * @return the smallest double value that is greater than or equal to the given value [x] and is a mathematical integer. * * Special cases: * - `ceil(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_ceil") external public actual fun ceil(x: Double): Double /** * Rounds the given value [x] to an integer towards negative infinity. * @return the largest double value that is smaller than or equal to the given value [x] and is a mathematical integer. * * Special cases: * - `floor(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_floor") external public actual fun floor(x: Double): Double /** * Rounds the given value [x] to an integer towards zero. * * @return the value [x] having its fractional part truncated. * * Special cases: * - `truncate(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") public actual fun truncate(x: Double): Double = when { x.isNaN() || x.isInfinite() -> x x > 0 -> floor(x) else -> ceil(x) } /** * Rounds the given value [x] towards the closest integer with ties rounded towards even integer. * * Special cases: * - `round(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_round") external public actual fun round(x: Double): Double /** * Returns the absolute value of the given value [x]. * * Special cases: * - `abs(NaN)` is `NaN` * * @see absoluteValue extension property for [Double] */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_abs") external public actual fun abs(x: Double): Double /** * Returns the sign of the given value [x]: * - `-1.0` if the value is negative, * - zero if the value is zero, * - `1.0` if the value is positive * * Special case: * - `sign(NaN)` is `NaN` */ @SinceKotlin("1.2") public actual fun sign(x: Double): Double = when { x.isNaN() -> Double.NaN x > 0 -> 1.0 x < 0 -> -1.0 else -> x } /** * Returns the smaller of two values. * * If either value is `NaN`, then the result is `NaN`. */ @SinceKotlin("1.2") public actual fun min(a: Double, b: Double): Double = when { a.isNaN() || b.isNaN() -> Double.NaN a == 0.0 && b == 0.0 -> if (a.signBit()) a else b // -0.0 < +0.0 else -> if (a < b) a else b } /** * Returns the greater of two values. * * If either value is `NaN`, then the result is `NaN`. */ @SinceKotlin("1.2") public actual fun max(a: Double, b: Double): Double = when { a.isNaN() || b.isNaN() -> Double.NaN a == 0.0 && b == 0.0 -> if (!a.signBit()) a else b // -0.0 < +0.0 else -> if (a > b) a else b } // extensions /** * Raises this value to the power [x]. * * Special cases: * - `b.pow(0.0)` is `1.0` * - `b.pow(1.0) == b` * - `b.pow(NaN)` is `NaN` * - `NaN.pow(x)` is `NaN` for `x != 0.0` * - `b.pow(Inf)` is `NaN` for `abs(b) == 1.0` * - `b.pow(x)` is `NaN` for `b < 0` and `x` is finite and not an integer */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_pow") external public actual fun Double.pow(x: Double): Double /** * Raises this value to the integer power [n]. * * See the other overload of [pow] for details. */ @SinceKotlin("1.2") public actual fun Double.pow(n: Int): Double = pow(n.toDouble()) /** * Computes the remainder of division of this value by the [divisor] value according to the IEEE 754 standard. * * The result is computed as `r = this - (q * divisor)` where `q` is the quotient of division rounded to the nearest integer, * `q = round(this / other)`. * * Special cases: * - `x.IEEErem(y)` is `NaN`, when `x` is `NaN` or `y` is `NaN` or `x` is `+Inf|-Inf` or `y` is zero. * - `x.IEEErem(y) == x` when `x` is finite and `y` is infinite. * * @see round */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_IEEErem") external public fun Double.IEEErem(divisor: Double): Double /** * Returns the absolute value of this value. * * Special cases: * - `NaN.absoluteValue` is `NaN` * * @see abs actual function */ @SinceKotlin("1.2") public actual val Double.absoluteValue: Double get() = abs(this) /** * Returns the sign of this value: * - `-1.0` if the value is negative, * - zero if the value is zero, * - `1.0` if the value is positive * * Special case: * - `NaN.sign` is `NaN` */ @SinceKotlin("1.2") public actual val Double.sign: Double get() = sign(this) /** * Returns this value with the sign bit same as of the [sign] value. * * If [sign] is `NaN` the sign of the result is undefined. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_withSign") external public actual fun Double.withSign(sign: Double): Double /** * Returns this value with the sign bit same as of the [sign] value. */ @SinceKotlin("1.2") public actual fun Double.withSign(sign: Int): Double = withSign(sign.toDouble()) /** * Returns the ulp (unit in the last place) of this value. * * An ulp is a positive distance between this value and the next nearest [Double] value larger in magnitude. * * Special Cases: * - `NaN.ulp` is `NaN` * - `x.ulp` is `+Inf` when `x` is `+Inf` or `-Inf` * - `0.0.ulp` is `Double.MIN_VALUE` */ @SinceKotlin("1.2") public actual val Double.ulp: Double get() = when { isNaN() -> Double.NaN isInfinite() -> Double.POSITIVE_INFINITY this == Double.MAX_VALUE || this == -Double.MAX_VALUE -> 2.0.pow(971) else -> { val d = absoluteValue d.nextUp() - d } } /** * Returns the [Double] value nearest to this value in direction of positive infinity. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_nextUp") external public actual fun Double.nextUp(): Double /** * Returns the [Double] value nearest to this value in direction of negative infinity. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_nextDown") external public actual fun Double.nextDown(): Double /** * Returns the [Double] value nearest to this value in direction from this value towards the value [to]. * * Special cases: * - `x.nextTowards(y)` is `NaN` if either `x` or `y` are `NaN` * - `x.nextTowards(x) == x` * */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Double_nextTowards") external public actual fun Double.nextTowards(to: Double): Double /** * Returns true if the sign of [this] value is negative and false otherwise */ @SymbolName("Kotlin_math_Double_signBit") external private fun Double.signBit(): Boolean /** * Rounds this [Double] value to the nearest integer and converts the result to [Int]. * Ties are rounded towards positive infinity. * * Special cases: * - `x.roundToInt() == Int.MAX_VALUE` when `x > Int.MAX_VALUE` * - `x.roundToInt() == Int.MIN_VALUE` when `x < Int.MIN_VALUE` * * @throws IllegalArgumentException when this value is `NaN` */ @SinceKotlin("1.2") public actual fun Double.roundToInt(): Int = when { isNaN() -> throw IllegalArgumentException("Cannot round NaN value.") this > Int.MAX_VALUE -> Int.MAX_VALUE this < Int.MIN_VALUE -> Int.MIN_VALUE else -> floor(this + 0.5).toInt() } /** * Rounds this [Double] value to the nearest integer and converts the result to [Long]. * Ties are rounded towards positive infinity. * * Special cases: * - `x.roundToLong() == Long.MAX_VALUE` when `x > Long.MAX_VALUE` * - `x.roundToLong() == Long.MIN_VALUE` when `x < Long.MIN_VALUE` * * @throws IllegalArgumentException when this value is `NaN` */ @SinceKotlin("1.2") public actual fun Double.roundToLong(): Long = when { isNaN() -> throw IllegalArgumentException("Cannot round NaN value.") this > Long.MAX_VALUE -> Long.MAX_VALUE this < Long.MIN_VALUE -> Long.MIN_VALUE else -> floor(this + 0.5).toLong() } // endregion // region ================ Float Math ======================================== /** Computes the sine of the angle [x] given in radians. * * Special cases: * - `sin(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sinf") external public actual fun sin(x: Float): Float /** Computes the cosine of the angle [x] given in radians. * * Special cases: * - `cos(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_cosf") external public actual fun cos(x: Float): Float /** Computes the tangent of the angle [x] given in radians. * * Special cases: * - `tan(NaN|+Inf|-Inf)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_tanf") external public actual fun tan(x: Float): Float /** * Computes the arc sine of the value [x]; * the returned value is an angle in the range from `-PI/2` to `PI/2` radians. * * Special cases: * - `asin(x)` is `NaN`, when `abs(x) > 1` or x is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_asinf") external public actual fun asin(x: Float): Float /** * Computes the arc cosine of the value [x]; * the returned value is an angle in the range from `0.0` to `PI` radians. * * Special cases: * - `acos(x)` is `NaN`, when `abs(x) > 1` or x is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_acosf") external public actual fun acos(x: Float): Float /** * Computes the arc tangent of the value [x]; * the returned value is an angle in the range from `-PI/2` to `PI/2` radians. * * Special cases: * - `atan(NaN)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atanf") external public actual fun atan(x: Float): Float /** * Returns the angle `theta` of the polar coordinates `(r, theta)` that correspond * to the rectangular coordinates `(x, y)` by computing the arc tangent of the value [y] / [x]; * the returned value is an angle in the range from `-PI` to `PI` radians. * * Special cases: * - `atan2(0.0, 0.0)` is `0.0` * - `atan2(0.0, x)` is `0.0` for `x > 0` and `PI` for `x < 0` * - `atan2(-0.0, x)` is `-0.0` for 'x > 0` and `-PI` for `x < 0` * - `atan2(y, +Inf)` is `0.0` for `0 < y < +Inf` and `-0.0` for '-Inf < y < 0` * - `atan2(y, -Inf)` is `PI` for `0 < y < +Inf` and `-PI` for `-Inf < y < 0` * - `atan2(y, 0.0)` is `PI/2` for `y > 0` and `-PI/2` for `y < 0` * - `atan2(+Inf, x)` is `PI/2` for finite `x`y * - `atan2(-Inf, x)` is `-PI/2` for finite `x` * - `atan2(NaN, x)` and `atan2(y, NaN)` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atan2f") external public actual fun atan2(y: Float, x: Float): Float /** * Computes the hyperbolic sine of the value [x]. * * Special cases: * - `sinh(NaN)` is `NaN` * - `sinh(+Inf)` is `+Inf` * - `sinh(-Inf)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sinhf") external public actual fun sinh(x: Float): Float /** * Computes the hyperbolic cosine of the value [x]. * * Special cases: * - `cosh(NaN)` is `NaN` * - `cosh(+Inf|-Inf)` is `+Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_coshf") external public actual fun cosh(x: Float): Float /** * Computes the hyperbolic tangent of the value [x]. * * Special cases: * - `tanh(NaN)` is `NaN` * - `tanh(+Inf)` is `1.0` * - `tanh(-Inf)` is `-1.0` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_tanhf") external public actual fun tanh(x: Float): Float /** * Computes the inverse hyperbolic sine of the value [x]. * * The returned value is `y` such that `sinh(y) == x`. * * Special cases: * - `asinh(NaN)` is `NaN` * - `asinh(+Inf)` is `+Inf` * - `asinh(-Inf)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_asinhf") external public actual fun asinh(x: Float): Float /** * Computes the inverse hyperbolic cosine of the value [x]. * * The returned value is positive `y` such that `cosh(y) == x`. * * Special cases: * - `acosh(NaN)` is `NaN` * - `acosh(x)` is `NaN` when `x < 1` * - `acosh(+Inf)` is `+Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_acoshf") external public actual fun acosh(x: Float): Float /** * Computes the inverse hyperbolic tangent of the value [x]. * * The returned value is `y` such that `tanh(y) == x`. * * Special cases: * - `tanh(NaN)` is `NaN` * - `tanh(x)` is `NaN` when `x > 1` or `x < -1` * - `tanh(1.0)` is `+Inf` * - `tanh(-1.0)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_atanhf") external public actual fun atanh(x: Float): Float /** * Computes `sqrt(x^2 + y^2)` without intermediate overflow or underflow. * * Special cases: * - returns `+Inf` if any of arguments is infinite * - returns `NaN` if any of arguments is `NaN` and the other is not infinite */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_hypotf") external public actual fun hypot(x: Float, y: Float): Float /** * Computes the positive square root of the value [x]. * * Special cases: * - `sqrt(x)` is `NaN` when `x < 0` or `x` is `NaN` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_sqrtf") external public actual fun sqrt(x: Float): Float /** * Computes Euler's number `e` raised to the power of the value [x]. * * Special cases: * - `exp(NaN)` is `NaN` * - `exp(+Inf)` is `+Inf` * - `exp(-Inf)` is `0.0` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_expf") external public actual fun exp(x: Float): Float /** * Computes `exp(x) - 1`. * * This function can be implemented to produce more precise result for [x] near zero. * * Special cases: * - `expm1(NaN)` is `NaN` * - `expm1(+Inf)` is `+Inf` * - `expm1(-Inf)` is `-1.0` * * @see [exp] function. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_expm1f") external public actual fun expm1(x: Float): Float /** * Computes the logarithm of the value [x] to the given [base]. * * Special cases: * - `log(x, b)` is `NaN` if either `x` or `b` are `NaN` * - `log(x, b)` is `NaN` when `x < 0` or `b <= 0` or `b == 1.0` * - `log(+Inf, +Inf)` is `NaN` * - `log(+Inf, b)` is `+Inf` for `b > 1` and `-Inf` for `b < 1` * - `log(0.0, b)` is `-Inf` for `b > 1` and `+Inf` for `b > 1` * * See also logarithm functions for common fixed bases: [ln], [log10] and [log2]. */ @SinceKotlin("1.2") public actual fun log(x: Float, base: Float): Float { if (base <= 0.0F || base == 1.0F) return Float.NaN return ln(x) / ln(base) } /** * Computes the natural logarithm (base `E`) of the value [x]. * * Special cases: * - `ln(NaN)` is `NaN` * - `ln(x)` is `NaN` when `x < 0.0` * - `ln(+Inf)` is `+Inf` * - `ln(0.0)` is `-Inf` */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_lnf") external public actual fun ln(x: Float): Float /** * Computes the common logarithm (base 10) of the value [x]. * * @see [ln] actual function for special cases. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_log10f") external public actual fun log10(x: Float): Float /** * Computes the binary logarithm (base 2) of the value [x]. * * @see [ln] actual function for special cases. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_log2f") external public actual fun log2(x: Float): Float /** * Computes `ln(a + 1)`. * * This function can be implemented to produce more precise result for [x] near zero. * * Special cases: * - `ln1p(NaN)` is `NaN` * - `ln1p(x)` is `NaN` where `x < -1.0` * - `ln1p(-1.0)` is `-Inf` * - `ln1p(+Inf)` is `+Inf` * * @see [ln] function * @see [expm1] function */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_ln1pf") external public actual fun ln1p(x: Float): Float /** * Rounds the given value [x] to an integer towards positive infinity. * @return the smallest Float value that is greater than or equal to the given value [x] and is a mathematical integer. * * Special cases: * - `ceil(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_ceilf") external public actual fun ceil(x: Float): Float /** * Rounds the given value [x] to an integer towards negative infinity. * @return the largest Float value that is smaller than or equal to the given value [x] and is a mathematical integer. * * Special cases: * - `floor(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_floorf") external public actual fun floor(x: Float): Float /** * Rounds the given value [x] to an integer towards zero. * * @return the value [x] having its fractional part truncated. * * Special cases: * - `truncate(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") public actual fun truncate(x: Float): Float = when { x.isNaN() || x.isInfinite() -> x x > 0 -> floor(x) else -> ceil(x) } /** * Rounds the given value [x] towards the closest integer with ties rounded towards even integer. * * Special cases: * - `round(x)` is `x` where `x` is `NaN` or `+Inf` or `-Inf` or already a mathematical integer. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_roundf") external public actual fun round(x: Float): Float /** * Returns the absolute value of the given value [x]. * * Special cases: * - `abs(NaN)` is `NaN` * * @see absoluteValue extension property for [Float] */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_absf") external public actual fun abs(x: Float): Float /** * Returns the sign of the given value [x]: * - `-1.0` if the value is negative, * - zero if the value is zero, * - `1.0` if the value is positive * * Special case: * - `sign(NaN)` is `NaN` */ @SinceKotlin("1.2") public actual fun sign(x: Float): Float = when { x.isNaN() -> Float.NaN x > 0 -> 1.0f x < 0 -> -1.0f else -> x } /** * Returns the smaller of two values. * * If either value is `NaN`, then the result is `NaN`. */ @SinceKotlin("1.2") public actual fun min(a: Float, b: Float): Float = when { a.isNaN() || b.isNaN() -> Float.NaN a == 0.0f && b == 0.0f -> if (a.signBit()) a else b // -0.0 < +0.0 else -> if (a < b) a else b } /** * Returns the greater of two values. * * If either value is `NaN`, then the result is `NaN`. */ @SinceKotlin("1.2") public actual fun max(a: Float, b: Float): Float = when { a.isNaN() || b.isNaN() -> Float.NaN a == 0.0f && b == 0.0f -> if (!a.signBit()) a else b // -0.0 < +0.0 else -> if (a > b) a else b } // extensions /** * Raises this value to the power [x]. * * Special cases: * - `b.pow(0.0)` is `1.0` * - `b.pow(1.0) == b` * - `b.pow(NaN)` is `NaN` * - `NaN.pow(x)` is `NaN` for `x != 0.0` * - `b.pow(Inf)` is `NaN` for `abs(b) == 1.0` * - `b.pow(x)` is `NaN` for `b < 0` and `x` is finite and not an integer */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_pow") external public actual fun Float.pow(x: Float): Float /** * Raises this value to the integer power [n]. * * See the other overload of [pow] for details. */ @SinceKotlin("1.2") public actual fun Float.pow(n: Int): Float = pow(n.toFloat()) /** * Computes the remainder of division of this value by the [divisor] value according to the IEEE 754 standard. * * The result is computed as `r = this - (q * divisor)` where `q` is the quotient of division rounded to the nearest integer, * `q = round(this / other)`. * * Special cases: * - `x.IEEErem(y)` is `NaN`, when `x` is `NaN` or `y` is `NaN` or `x` is `+Inf|-Inf` or `y` is zero. * - `x.IEEErem(y) == x` when `x` is finite and `y` is infinite. * * @see round */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_IEEErem") external public fun Float.IEEErem(divisor: Float): Float /** * Returns the absolute value of this value. * * Special cases: * - `NaN.absoluteValue` is `NaN` * * @see abs actual function */ @SinceKotlin("1.2") public actual val Float.absoluteValue: Float get() = abs(this) /** * Returns the sign of this value: * - `-1.0` if the value is negative, * - zero if the value is zero, * - `1.0` if the value is positive * * Special case: * - `NaN.sign` is `NaN` */ @SinceKotlin("1.2") public actual val Float.sign: Float get() = sign(this) /** * Returns this value with the sign bit same as of the [sign] value. * * If [sign] is `NaN` the sign of the result is undefined. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_withSign") external public actual fun Float.withSign(sign: Float): Float /** * Returns this value with the sign bit same as of the [sign] value. */ @SinceKotlin("1.2") public actual fun Float.withSign(sign: Int): Float = withSign(sign.toFloat()) @SinceKotlin("1.2") public val Float.ulp: Float get() = when { isNaN() -> Float.NaN isInfinite() -> Float.POSITIVE_INFINITY this == Float.MAX_VALUE || this == -Float.MAX_VALUE -> 2.0f.pow(104) else -> { val d = absoluteValue d.nextUp() - d } } /** * Returns the [Float] value nearest to this value in direction of positive infinity. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_nextUp") external public fun Float.nextUp(): Float /** * Returns the [Float] value nearest to this value in direction of negative infinity. */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_nextDown") external public fun Float.nextDown(): Float /** * Returns the [Float] value nearest to this value in direction from this value towards the value [to]. * * Special cases: * - `x.nextTowards(y)` is `NaN` if either `x` or `y` are `NaN` * - `x.nextTowards(x) == x` * */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_Float_nextTowards") external public fun Float.nextTowards(to: Float): Float /** * Returns true if the sign of [this] value is negative and false otherwise */ @SymbolName("Kotlin_math_Float_signBit") external private fun Float.signBit(): Boolean /** * Rounds this [Float] value to the nearest integer and converts the result to [Int]. * Ties are rounded towards positive infinity. * * Special cases: * - `x.roundToInt() == Int.MAX_VALUE` when `x > Int.MAX_VALUE` * - `x.roundToInt() == Int.MIN_VALUE` when `x < Int.MIN_VALUE` * * @throws IllegalArgumentException when this value is `NaN` */ @SinceKotlin("1.2") public actual fun Float.roundToInt(): Int = when { isNaN() -> throw IllegalArgumentException("Cannot round NaN value.") this > Int.MAX_VALUE -> Int.MAX_VALUE this < Int.MIN_VALUE -> Int.MIN_VALUE else -> floor(this + 0.5f).toInt() } /** * Rounds this [Float] value to the nearest integer and converts the result to [Long]. * Ties are rounded towards positive infinity. * * Special cases: * - `x.roundToLong() == Long.MAX_VALUE` when `x > Long.MAX_VALUE` * - `x.roundToLong() == Long.MIN_VALUE` when `x < Long.MIN_VALUE` * * @throws IllegalArgumentException when this value is `NaN` */ @SinceKotlin("1.2") public actual fun Float.roundToLong(): Long = when { isNaN() -> throw IllegalArgumentException("Cannot round NaN value.") this > Long.MAX_VALUE -> Long.MAX_VALUE this < Long.MIN_VALUE -> Long.MIN_VALUE else -> floor(this + 0.5f).toLong() } // endregion // region ================ Integer Math ======================================== /** * Returns the absolute value of the given value [n]. * * Special cases: * - `abs(Int.MIN_VALUE)` is `Int.MIN_VALUE` due to an overflow * * @see absoluteValue extension property for [Int] */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_absi") external public actual fun abs(n: Int): Int /** * Returns the smaller of two values. */ @SinceKotlin("1.2") public actual fun min(a: Int, b: Int): Int = if (a < b) a else b /** * Returns the greater of two values. */ @SinceKotlin("1.2") public actual fun max(a: Int, b: Int): Int = if (a > b) a else b /** * Returns the absolute value of this value. * * Special cases: * - `Int.MIN_VALUE.absoluteValue` is `Int.MIN_VALUE` due to an overflow * * @see abs actual function */ @SinceKotlin("1.2") public actual val Int.absoluteValue: Int get() = abs(this) /** * Returns the sign of this value: * - `-1` if the value is negative, * - `0` if the value is zero, * - `1` if the value is positive */ @SinceKotlin("1.2") public actual val Int.sign: Int get() = when { this < 0 -> -1 this > 0 -> 1 else -> 0 } /** * Returns the absolute value of the given value [n]. * * Special cases: * - `abs(Long.MIN_VALUE)` is `Long.MIN_VALUE` due to an overflow * * @see absoluteValue extension property for [Long] */ @SinceKotlin("1.2") @SymbolName("Kotlin_math_absl") external public actual fun abs(n: Long): Long /** * Returns the smaller of two values. */ @SinceKotlin("1.2") public actual fun min(a: Long, b: Long): Long = if (a < b) a else b /** * Returns the greater of two values. */ @SinceKotlin("1.2") public actual fun max(a: Long, b: Long): Long = if (a > b) a else b /** * Returns the absolute value of this value. * * Special cases: * - `Long.MIN_VALUE.absoluteValue` is `Long.MIN_VALUE` due to an overflow * * @see abs actual function */ @SinceKotlin("1.2") public actual val Long.absoluteValue: Long get() = abs(this) /** * Returns the sign of this value: * - `-1` if the value is negative, * - `0` if the value is zero, * - `1` if the value is positive */ @SinceKotlin("1.2") public actual val Long.sign: Int get() = when { this < 0 -> -1 this > 0 -> 1 else -> 0 } // endregion ================================================ FILE: runtime/src/main/kotlin/kotlin/native/Annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlin.reflect.KClass /** * Forces the compiler to use specified symbol name for the target `external` function. * * TODO: changing symbol name breaks the binary compatibility, * so it should probably be allowed on `internal` and `private` functions only. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) public annotation class SymbolName(val name: String) /** * Preserve the function entry point during global optimizations. */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class Retain /** * Preserve the function entry point during global optimizations, only for the given target. */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class RetainForTarget(val target: String) /** @suppress */ @Deprecated("Use common kotlin.Throws annotation instead.", ReplaceWith("kotlin.Throws"), DeprecationLevel.WARNING) public typealias Throws = kotlin.Throws /** @suppress */ public typealias ThreadLocal = kotlin.native.concurrent.ThreadLocal /** @suppress */ public typealias SharedImmutable = kotlin.native.concurrent.SharedImmutable /** * Makes top level function available from C/C++ code with the given name. * * [externName] controls the name of top level function, [shortName] controls the short name. * If [externName] is empty, no top level declaration is being created. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) public annotation class CName(val externName: String = "", val shortName: String = "") ================================================ FILE: runtime/src/main/kotlin/kotlin/native/BitSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native /** * A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index. * * @constructor creates an empty bit set with the specified [size] * @param size the size of one element in the array used to store bits. */ public class BitSet(size: Int = ELEMENT_SIZE) { @kotlin.native.internal.CanBePrecreated companion object { // Default size of one element in the array used to store bits. private const val ELEMENT_SIZE = 64 private const val MAX_BIT_OFFSET = ELEMENT_SIZE - 1 private const val ALL_TRUE = -1L // 0xFFFF_FFFF_FFFF_FFFF private const val ALL_FALSE = 0L // 0x0000_0000_0000_0000 } private var bits: LongArray = LongArray(bitToElementSize(size)) private val lastIndex: Int get() = size - 1 /** Returns an index of the last bit that has `true` value. Returns -1 if the set is empty. */ val lastTrueIndex: Int get() = previousSetBit(size) /** True if this BitSet contains no bits set to true. */ val isEmpty: Boolean get() = bits.all { it == ALL_FALSE } /** Actual number of bits available in the set. All bits with indices >= size assumed to be 0 */ var size: Int = size private set /** * Creates a bit set of given [length] filling elements using [initializer] */ constructor(length: Int, initializer: (Int) -> Boolean): this(length) { for (i in 0 until length) { set(i, initializer(i)) } } // Transforms a bit index into an element index in the `bits` array. private val Int.elementIndex: Int get() = this / ELEMENT_SIZE // Transforms a bit index in the set into a bit in the element of the `bits` array. private val Int.bitOffset: Int get() = this % ELEMENT_SIZE // Transforms a bit index in the set into pair of a `bits` element index and a bit index in the element. private val Int.asBitCoordinates: Pair get() = Pair(elementIndex, bitOffset) // Transforms a bit offset to the mask with only bit set corresponding to the offset. private val Int.asMask: Long get() = 0x1L shl this // Transforms a bit offset to the mask with only bits before the index (inclusive) set. private val Int.asMaskBefore: Long get() = getMaskBetween(0, this) // Transforms a bit offset to the mask with only bits after the index (inclusive) set. private val Int.asMaskAfter: Long get() = getMaskBetween(this, MAX_BIT_OFFSET) // Builds a masks with 1 between fromOffset and toOffset (both inclusive). private fun getMaskBetween(fromOffset: Int, toOffset: Int): Long { var res = 0L val maskToAdd = fromOffset.asMask for (i in fromOffset..toOffset) { res = (res shl 1) or maskToAdd } return res } // Transforms a size in bits to a size in elements of the `bits` array. private fun bitToElementSize(bitSize: Int): Int = (bitSize + ELEMENT_SIZE - 1) / ELEMENT_SIZE // Transforms a pair of an element index and a bit offset to a bit index. private fun bitIndex(elementIndex: Int, bitOffset: Int) = elementIndex * ELEMENT_SIZE + bitOffset // Sets all bits after the last available bit (size - 1) to 0. private fun clearUnusedTail() { val (lastElementIndex, lastBitOffset) = lastIndex.asBitCoordinates bits[bits.lastIndex] = bits[bits.lastIndex] and lastBitOffset.asMaskBefore for (i in lastElementIndex + 1 until bits.size) { bits[i] = ALL_FALSE } } // Internal function. Sets bits specified by the element index and the given mask to value. private fun setBitsWithMask(elementIndex: Int, mask: Long, value: Boolean) { val element = bits[elementIndex] if (value) { bits[elementIndex] = element or mask } else { bits[elementIndex] = element and mask.inv() } } // Internal function. Flips bits specified by the element index and the given mask. private fun flipBitsWithMask(elementIndex: Int, mask: Long) { val element = bits[elementIndex] bits[elementIndex] = element xor mask } /** * Checks if index is valid and extends the `bits` array if the index exceeds its size. * @throws [IndexOutOfBoundsException] if [index] < 0. */ private fun ensureCapacity(index: Int) { if (index < 0) { throw IndexOutOfBoundsException() } if (index >= size) { size = index + 1 if (index.elementIndex >= bits.size) { // Create a new array containing the index-th bit. bits = bits.copyOf(bitToElementSize(index + 1)) } // Set all bits after the index to 0. TODO: We can remove it. clearUnusedTail() } } /** Set the bit specified to the specified value. */ fun set(index: Int, value: Boolean = true) { ensureCapacity(index) val (elementIndex, offset) = index.asBitCoordinates setBitsWithMask(elementIndex, offset.asMask, value) } /** Sets the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ fun set(from : Int, to: Int, value: Boolean = true) = set(from until to, value) /** Sets the bits from the range specified to the specified value. */ fun set(range: IntRange, value: Boolean = true) { if (range.start < 0 || range.endInclusive < 0) { throw IndexOutOfBoundsException() } if (range.start > range.endInclusive) { // Empty range. return } ensureCapacity(range.endInclusive) val (fromIndex, fromOffset) = range.start.asBitCoordinates val (toIndex, toOffset) = range.endInclusive.asBitCoordinates if (toIndex == fromIndex) { val mask = getMaskBetween(fromOffset, toOffset) setBitsWithMask(fromIndex, mask, value) } else { // Set bits in the first element. setBitsWithMask(fromIndex, fromOffset.asMaskAfter, value) // Set all bits of all elements (excluding border ones) to 0 or 1 depending. for (index in fromIndex + 1 until toIndex) { bits[index] = if (value) ALL_TRUE else ALL_FALSE } // Set bits in the last element setBitsWithMask(toIndex, toOffset.asMaskBefore, value) } } /** Clears the bit specified */ fun clear(index: Int) = set(index, false) /** Clears the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ fun clear(from : Int, to: Int) = set(from, to, false) /** Clears the bit specified */ fun clear(range: IntRange) = set(range, false) /** Sets all bits in the BitSet to `false`. */ fun clear() { for (i in bits.indices) { bits[i] = ALL_FALSE } } /** Reverses the bit specified. */ fun flip(index: Int) { ensureCapacity(index) val (elementIndex, offset) = index.asBitCoordinates flipBitsWithMask(elementIndex, offset.asMask) } /** Reverses the bits with indices between [from] (inclusive) and [to] (exclusive). */ fun flip(from: Int, to: Int) = flip(from until to) /** Reverses the bits from the range specified. */ fun flip(range: IntRange) { if (range.start < 0 || range.endInclusive < 0) { throw IndexOutOfBoundsException() } if (range.start > range.endInclusive) { // Empty range. return } ensureCapacity(range.endInclusive) val (fromIndex, fromOffset) = range.start.asBitCoordinates val (toIndex, toOffset) = range.endInclusive.asBitCoordinates if (toIndex == fromIndex) { val mask = getMaskBetween(fromOffset, toOffset) flipBitsWithMask(fromIndex, mask) } else { // Flip bits in the first element. flipBitsWithMask(toIndex, toOffset.asMaskAfter) // Flip bits between the first and the last elements. for (index in fromIndex + 1 until toIndex) { bits[index] = bits[index].inv() } // Flip bits in the last element. flipBitsWithMask(toIndex, toOffset.asMaskBefore) } } /** * Returns an index of a next set (if [lookFor] == true) or clear * (if [lookFor] == false) bit after [startIndex] (inclusive). * Returns -1 (for [lookFor] == true) or [size] (for lookFor == false) * if there is no such bits between [startIndex] and [size] - 1. * @throws IndexOutOfBoundException if [startIndex] < 0. */ private fun nextBit(startIndex: Int, lookFor: Boolean): Int { if (startIndex < 0) { throw IndexOutOfBoundsException() } if (startIndex >= size) { return if (lookFor) -1 else startIndex } val (startElementIndex, startOffset) = startIndex.asBitCoordinates // Look for the next set bit in the first element. var element = bits[startElementIndex] for (offset in startOffset..MAX_BIT_OFFSET) { val bit = element and (0x1L shl offset) != 0L if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. return bitIndex(startElementIndex, offset) } } // Look for in the remaining elements. for (index in startElementIndex + 1..bits.lastIndex) { element = bits[index] for (offset in 0..MAX_BIT_OFFSET) { val bit = element and (0x1L shl offset) != 0L if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. return bitIndex(index, offset) } } } return if (lookFor) -1 else size } /** * Returns an index of a next bit which value is `true` after [startIndex] (inclusive). * Returns -1 if there is no such bits after [startIndex]. * @throws IndexOutOfBoundException if [startIndex] < 0. */ fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) /** * Returns an index of a next bit which value is `false` after [startIndex] (inclusive). * Returns [size] if there is no such bits between [startIndex] and [size] - 1 assuming that the set has an infinite * sequence of `false` bits after (size - 1)-th. * @throws IndexOutOfBoundException if [startIndex] < 0. */ fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) /** * Returns the biggest index of a bit which value is [lookFor] before [startIndex] (inclusive). * Returns -1 if there is no such bits before [startIndex]. * If [startIndex] >= [size] returns -1 */ fun previousBit(startIndex: Int, lookFor: Boolean): Int { var correctStartIndex = startIndex if (startIndex >= size) { // We assume that all bits after `size - 1` are 0. So we can return the start index if we are looking for 0. if (!lookFor) { return startIndex } else { // If we are looking for 1 we can skip all these 0 after `size - 1`. correctStartIndex = size - 1 } } if (correctStartIndex < -1) { throw IndexOutOfBoundsException() } if (correctStartIndex == -1) { return -1 } val (startElementIndex, startOffset) = correctStartIndex.asBitCoordinates // Look for the next set bit in the first element. var element = bits[startElementIndex] for (offset in startOffset downTo 0) { val bit = element and (0x1L shl offset) != 0L if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. return bitIndex(startElementIndex, offset) } } // Look for in the remaining elements. for (index in startElementIndex - 1 downTo 0) { element = bits[index] for (offset in MAX_BIT_OFFSET downTo 0) { val bit = element and (0x1L shl offset) != 0L if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. return bitIndex(index, offset) } } } return -1 } /** * Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive). * Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1. * If [startIndex] >= size will search from (size - 1)-th bit. * @throws IndexOutOfBoundException if [startIndex] < -1. */ fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true) /** * Returns the biggest index of a bit which value is `false` before [startIndex] (inclusive). * Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1. * If [startIndex] >= size will return [startIndex] assuming that the set has an infinite * sequence of `false` bits after (size - 1)-th. * @throws IndexOutOfBoundException if [startIndex] < -1. */ fun previousClearBit(startIndex: Int): Int = previousBit(startIndex, false) /** Returns a value of a bit with the [index] specified. */ operator fun get(index: Int): Boolean { if (index < 0) { throw IndexOutOfBoundsException() } if (index >= size) { return false } val (elementIndex, offset) = index.asBitCoordinates return bits[elementIndex] and offset.asMask != 0L } private inline fun doOperation(another: BitSet, operation: Long.(Long) -> Long) { ensureCapacity(another.lastIndex) var index = 0 while (index < another.bits.size) { bits[index] = operation(bits[index], another.bits[index]) index++ } while (index < bits.size) { bits[index] = operation(bits[index], ALL_FALSE) index++ } } /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ fun and(another: BitSet) = doOperation(another, Long::and) /** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ fun or(another: BitSet) = doOperation(another, Long::or) /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ fun xor(another: BitSet) = doOperation(another, Long::xor) /** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ fun andNot(another: BitSet) { ensureCapacity(another.lastIndex) var index = 0 while (index < another.bits.size) { bits[index] = bits[index] and another.bits[index].inv() index++ } while (index < bits.size) { bits[index] = bits[index] and ALL_TRUE index++ } } /** Returns true if the specified BitSet has any bits set to true that are also set to true in this BitSet. */ fun intersects(another: BitSet): Boolean = (0 until minOf(bits.size, another.bits.size)).any { bits[it] and another.bits[it] != 0L } override fun toString(): String { val sb = StringBuilder() var first = true sb.append('[') var index = nextSetBit(0) while (index != -1) { if (!first) { sb.append('|') } else { first = false } sb.append(index) index = nextSetBit(index + 1) } sb.append(']') return sb.toString() } override fun hashCode(): Int { var x: Long = 1234 for (i in 0..bits.lastIndex) { x = x xor bits[i] * (i + 1) } return (x shr 32 xor x).toInt() } override fun equals(other: Any?): Boolean { if (this === other) { return true } if (other !is BitSet) { return false } var index = 0 while (index < minOf(bits.size, other.bits.size)) { if (bits[index] != other.bits[index]) { return false } index++ } val longestBits = if (bits.size > other.bits.size) bits else other.bits while (index < longestBits.size) { if (longestBits[index] != ALL_FALSE) { return false } index++ } return true } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/Blob.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlin.native.internal.* import kotlinx.cinterop.* /** * An immutable compile-time array of bytes. */ @ExportTypeInfo("theImmutableBlobTypeInfo") public final class ImmutableBlob private constructor() { public val size: Int get() = getArrayLength() // Data layout is the same as for ByteArray, so we can share native functions. @SymbolName("Kotlin_ByteArray_get") public external operator fun get(index: Int): Byte @SymbolName("Kotlin_ByteArray_getArrayLength") private external fun getArrayLength(): Int /** Creates an iterator over the elements of the array. */ public operator fun iterator(): ByteIterator { return ImmutableBlobIteratorImpl(this) } } private class ImmutableBlobIteratorImpl(val blob: ImmutableBlob) : ByteIterator() { var index : Int = 0 public override fun nextByte(): Byte { if (!hasNext()) throw NoSuchElementException("$index") return blob[index++] } public override operator fun hasNext(): Boolean { return index < blob.size } } /** * Copies the data from this blob into a new [ByteArray]. * * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this blob by default. */ @SymbolName("Kotlin_ImmutableBlob_toByteArray") public external fun ImmutableBlob.toByteArray(startIndex: Int = 0, endIndex: Int = size): ByteArray /** * Copies the data from this blob into a new [UByteArray]. * * @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default. * @param endIndex the end (exclusive) of the subrange to copy, size of this blob by default. */ @ExperimentalUnsignedTypes @SymbolName("Kotlin_ImmutableBlob_toByteArray") public external fun ImmutableBlob.toUByteArray(startIndex: Int = 0, endIndex: Int = size): UByteArray /** * Returns stable C pointer to data at certain [offset], useful as a way to pass resource * to C APIs. * @see kotlinx.cinterop.CPointer */ public fun ImmutableBlob.asCPointer(offset: Int = 0): CPointer = interpretCPointer(asCPointerImpl(offset))!! public fun ImmutableBlob.asUCPointer(offset: Int = 0): CPointer = interpretCPointer(asCPointerImpl(offset))!! @SymbolName("Kotlin_ImmutableBlob_asCPointerImpl") private external fun ImmutableBlob.asCPointerImpl(offset: Int): kotlin.native.internal.NativePtr /** * Creates [ImmutableBlob] out of compile-time constant data. * * This method accepts values of [Short] type in range `0x00..0xff`, other values are prohibited. * * One element still represent one byte in the output data. * This is the only way to create ImmutableBlob for now. */ @TypedIntrinsic(IntrinsicType.IMMUTABLE_BLOB) public external fun immutableBlobOf(vararg elements: Short): ImmutableBlob ================================================ FILE: runtime/src/main/kotlin/kotlin/native/Platform.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native /** * Operating system family. */ public enum class OsFamily { UNKNOWN, MACOSX, IOS, LINUX, WINDOWS, ANDROID, WASM, TVOS, WATCHOS } /** * Central Processor Unit architecture. */ public enum class CpuArchitecture(val bitness: Int) { UNKNOWN(-1), ARM32(32), ARM64(64), X86(32), X64(64), MIPS32(32), MIPSEL32(32), WASM32(32); } /** * Memory model. */ // NOTE: Must match `MemoryModel` in `Memory.h` public enum class MemoryModel { STRICT, RELAXED, EXPERIMENTAL, } /** * Object describing the current platform program executes upon. */ public object Platform { /** * Check if current architecture allows unaligned access to wider than byte locations. */ public val canAccessUnaligned: Boolean get() = Platform_canAccessUnaligned() != 0 /** * Check if byte order of the current platform is least significant byte (LSB) first, aka little endian. */ public val isLittleEndian: Boolean get() = Platform_isLittleEndian() != 0 /** * Operating system family program executes upon. */ public val osFamily: OsFamily get() = OsFamily.values()[Platform_getOsFamily()] /** * Architechture of the CPU program executes upon. */ public val cpuArchitecture: CpuArchitecture get() = CpuArchitecture.values()[Platform_getCpuArchitecture()] /** * Memory model binary was compiled with. */ public val memoryModel: MemoryModel get() = MemoryModel.values()[Platform_getMemoryModel()] /** * If binary was compiled in debug mode. */ public val isDebugBinary: Boolean get() = Platform_isDebugBinary() /** * If the memory leak checker is activated, by default `true` in debug mode, `false` in release. * When memory leak checker is activated, and leak is detected during last Kotlin context * deinitialization process - error message with leak information is printed and application * execution is aborted. * * @see isDebugBinary */ public var isMemoryLeakCheckerActive: Boolean get() = Platform_getMemoryLeakChecker() set(value) = Platform_setMemoryLeakChecker(value) public var isCleanersLeakCheckerActive: Boolean get() = Platform_getCleanersLeakChecker() set(value) = Platform_setCleanersLeakChecker(value) } @SymbolName("Konan_Platform_canAccessUnaligned") private external fun Platform_canAccessUnaligned(): Int @SymbolName("Konan_Platform_isLittleEndian") private external fun Platform_isLittleEndian(): Int @SymbolName("Konan_Platform_getOsFamily") private external fun Platform_getOsFamily(): Int @SymbolName("Konan_Platform_getCpuArchitecture") private external fun Platform_getCpuArchitecture(): Int @SymbolName("Konan_Platform_getMemoryModel") private external fun Platform_getMemoryModel(): Int @SymbolName("Konan_Platform_isDebugBinary") private external fun Platform_isDebugBinary(): Boolean @SymbolName("Konan_Platform_getMemoryLeakChecker") private external fun Platform_getMemoryLeakChecker(): Boolean @SymbolName("Konan_Platform_setMemoryLeakChecker") private external fun Platform_setMemoryLeakChecker(value: Boolean): Unit @SymbolName("Konan_Platform_getCleanersLeakChecker") private external fun Platform_getCleanersLeakChecker(): Boolean @SymbolName("Konan_Platform_setCleanersLeakChecker") private external fun Platform_setCleanersLeakChecker(value: Boolean): Unit ================================================ FILE: runtime/src/main/kotlin/kotlin/native/Runtime.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlin.native.concurrent.InvalidMutabilityException import kotlin.native.internal.UnhandledExceptionHookHolder /** * Initializes Kotlin runtime for the current thread, if not inited already. */ @SymbolName("Kotlin_initRuntimeIfNeeded") external public fun initRuntimeIfNeeded(): Unit /** * Deinitializes Kotlin runtime for the current thread, if was inited. * Cannot be called from Kotlin frames holding references, thus deprecated. */ @SymbolName("Kotlin_deinitRuntimeIfNeeded") @Deprecated("Deinit runtime can not be called from Kotlin", level = DeprecationLevel.ERROR) external public fun deinitRuntimeIfNeeded(): Unit /** * Exception thrown when top level variable is accessed from incorrect execution context. */ public class IncorrectDereferenceException : RuntimeException { constructor() : super() constructor(message: String) : super(message) } /** * Typealias describing custom exception reporting hook. */ public typealias ReportUnhandledExceptionHook = Function1 /** * Install custom unhandled exception hook. Returns old hook, or null if it was not specified. * Hook is invoked whenever there's uncaught exception reaching boundaries of the Kotlin world, * i.e. top level main(), or when Objective-C to Kotlin call not marked with @Throws throws an exception. * Hook must be a frozen lambda, so that it could be called from any thread/worker. * Hook is invoked once, and is cleared afterwards, so that memory leak detection works as expected even * with custom exception hooks. */ public fun setUnhandledExceptionHook(hook: ReportUnhandledExceptionHook): ReportUnhandledExceptionHook? { try { return UnhandledExceptionHookHolder.hook.swap(hook) } catch (e: InvalidMutabilityException) { throw InvalidMutabilityException("Unhandled exception hook must be frozen") } } /** * Compute stable wrt potential object relocations by the memory manager identity hash code. * @return 0 for `null` object, identity hash code otherwise. */ @SymbolName("Kotlin_Any_hashCode") public external fun Any?.identityHashCode(): Int ================================================ FILE: runtime/src/main/kotlin/kotlin/native/Text.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlinx.cinterop.toKString /** * Converts an UTF-8 array into a [String]. Replaces invalid input sequences with a default character. */ @Deprecated( "Use toKString or decodeToString instead", ReplaceWith("toKString()", "kotlinx.cinterop.toKString"), DeprecationLevel.ERROR ) public fun ByteArray.stringFromUtf8() : String { @Suppress("DEPRECATION_ERROR") return this.stringFromUtf8(0, this.size) } /** * Converts an UTF-8 array into a [String]. Replaces invalid input sequences with a default character. */ @Deprecated( "Use toKString or decodeToString instead", ReplaceWith("toKString(start, start + size)", "kotlinx.cinterop.toKString"), DeprecationLevel.ERROR ) public fun ByteArray.stringFromUtf8(start: Int = 0, size: Int = this.size) : String { return toKString(start, start + size) } /** * Converts an UTF-8 array into a [String]. * @throws [IllegalCharacterConversionException] if the input is invalid. */ @Deprecated( "Use toKString or decodeToString instead", ReplaceWith("toKString(throwOnInvalidSequence = true)", "kotlinx.cinterop.toKString"), DeprecationLevel.ERROR ) public fun ByteArray.stringFromUtf8OrThrow() : String { @Suppress("DEPRECATION_ERROR") return this.stringFromUtf8OrThrow(0, this.size) } /** * Converts an UTF-8 array into a [String]. * @throws [IllegalCharacterConversionException] if the input is invalid. */ @Deprecated( "Use toKString or decodeToString instead", ReplaceWith("toKString(start, start + size, throwOnInvalidSequence = true)", "kotlinx.cinterop.toKString"), DeprecationLevel.ERROR ) public fun ByteArray.stringFromUtf8OrThrow(start: Int = 0, size: Int = this.size) : String { try { return toKString(start, start + size, throwOnInvalidSequence = true) } catch (e: CharacterCodingException) { @Suppress("DEPRECATION_ERROR") throw IllegalCharacterConversionException() } } /** * Converts a [String] into an UTF-8 array. Replaces invalid input sequences with a default character. */ @Deprecated( "Use encodeToByteArray instead", ReplaceWith("encodeToByteArray()"), DeprecationLevel.ERROR ) public fun String.toUtf8() : ByteArray { @Suppress("DEPRECATION_ERROR") return this.toUtf8(0, this.length) } /** * Converts a [String] into an UTF-8 array. Replaces invalid input sequences with a default character. */ @Deprecated( "Use encodeToByteArray instead", ReplaceWith("encodeToByteArray(start, start + size)"), DeprecationLevel.ERROR ) public fun String.toUtf8(start: Int = 0, size: Int = this.length) : ByteArray { checkBoundsIndexes(start, start + size, this.length) return unsafeStringToUtf8(start, size) } /** * Converts a [String] into an UTF-8 array. * @throws [IllegalCharacterConversionException] if the input is invalid. */ @Deprecated( "Use encodeToByteArray instead", ReplaceWith("encodeToByteArray(throwOnInvalidSequence = true)"), DeprecationLevel.ERROR ) public fun String.toUtf8OrThrow() : ByteArray { @Suppress("DEPRECATION_ERROR") return this.toUtf8OrThrow(0, this.length) } /** * Converts a [String] into an UTF-8 array. * @throws [IllegalCharacterConversionException] if the input is invalid. */ @Deprecated( "Use encodeToByteArray instead", ReplaceWith("encodeToByteArray(start, start + size, throwOnInvalidSequence = true)"), DeprecationLevel.ERROR ) public fun String.toUtf8OrThrow(start: Int = 0, size: Int = this.length) : ByteArray { checkBoundsIndexes(start, start + size, this.length) try { return unsafeStringToUtf8OrThrow(start, size) } catch (e: CharacterCodingException) { @Suppress("DEPRECATION_ERROR") throw IllegalCharacterConversionException() } } internal fun checkBoundsIndexes(startIndex: Int, endIndex: Int, size: Int) { if (startIndex < 0 || endIndex > size) { throw IndexOutOfBoundsException("startIndex: $startIndex, endIndex: $endIndex, size: $size") } if (startIndex > endIndex) { throw IllegalArgumentException("startIndex: $startIndex > endIndex: $endIndex") } } internal fun insertString(array: CharArray, start: Int, value: String): Int = insertString(array, start, value, 0, value.length) @SymbolName("Kotlin_ByteArray_unsafeStringFromUtf8") internal external fun ByteArray.unsafeStringFromUtf8(start: Int, size: Int) : String @SymbolName("Kotlin_ByteArray_unsafeStringFromUtf8OrThrow") internal external fun ByteArray.unsafeStringFromUtf8OrThrow(start: Int, size: Int) : String @SymbolName("Kotlin_String_unsafeStringToUtf8") internal external fun String.unsafeStringToUtf8(start: Int, size: Int) : ByteArray @SymbolName("Kotlin_String_unsafeStringToUtf8OrThrow") internal external fun String.unsafeStringToUtf8OrThrow(start: Int, size: Int) : ByteArray @SymbolName("Kotlin_String_unsafeStringFromCharArray") internal external fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int) : String @SymbolName("Kotlin_StringBuilder_insertString") internal external fun insertString(array: CharArray, distIndex: Int, value: String, sourceIndex: Int, count: Int): Int @SymbolName("Kotlin_StringBuilder_insertInt") internal external fun insertInt(array: CharArray, start: Int, value: Int): Int ================================================ FILE: runtime/src/main/kotlin/kotlin/native/ThrowableExtensions.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native /** * Returns a list of stack trace addresses representing the stack trace * pertaining to this throwable. */ public fun Throwable.getStackTraceAddresses(): List = this.getStackTraceAddressesInternal() ================================================ FILE: runtime/src/main/kotlin/kotlin/native/TypedArrays.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlin.native.SymbolName /** * Those operations allows to extract primitive values out of the [ByteArray] byte buffers. * Data is treated as if it was in Least-Significant-Byte first (little-endian) byte order. * If index is outside of array boundaries - [ArrayIndexOutOfBoundsException] is thrown. */ /** * Gets [UByte] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @ExperimentalUnsignedTypes public fun ByteArray.getUByteAt(index: Int): UByte = UByte(get(index)) /** * Gets [Char] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getCharAt") public external fun ByteArray.getCharAt(index: Int): Char /** * Gets [Short] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getShortAt") public external fun ByteArray.getShortAt(index: Int): Short /** * Gets [UShort] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getShortAt") @ExperimentalUnsignedTypes public external fun ByteArray.getUShortAt(index: Int): UShort /** * Gets [Int] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getIntAt") public external fun ByteArray.getIntAt(index: Int): Int /** * Gets [UInt] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getIntAt") @ExperimentalUnsignedTypes public external fun ByteArray.getUIntAt(index: Int): UInt /** * Gets [Long] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getLongAt") public external fun ByteArray.getLongAt(index: Int): Long /** * Gets [ULong] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getLongAt") @ExperimentalUnsignedTypes public external fun ByteArray.getULongAt(index: Int): ULong /** * Gets [Float] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getFloatAt") public external fun ByteArray.getFloatAt(index: Int): Float /** * Gets [Double] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_getDoubleAt") public external fun ByteArray.getDoubleAt(index: Int): Double /** * Sets [UByte] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_set") public external fun ByteArray.setUByteAt(index: Int, value: UByte) /** * Sets [Char] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setCharAt") public external fun ByteArray.setCharAt(index: Int, value: Char) /** * Sets [Short] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setShortAt") public external fun ByteArray.setShortAt(index: Int, value: Short) /** * Sets [UShort] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setShortAt") @ExperimentalUnsignedTypes public external fun ByteArray.setUShortAt(index: Int, value: UShort) /** * Sets [Int] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setIntAt") public external fun ByteArray.setIntAt(index: Int, value: Int) /** * Sets [UInt] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setIntAt") public external fun ByteArray.setUIntAt(index: Int, value: UInt) /** * Sets [Long] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setLongAt") public external fun ByteArray.setLongAt(index: Int, value: Long) /** * Sets [ULong] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setLongAt") @ExperimentalUnsignedTypes public external fun ByteArray.setULongAt(index: Int, value: ULong) /** * Sets [Float] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setFloatAt") public external fun ByteArray.setFloatAt(index: Int, value: Float) /** * Sets [Double] out of the [ByteArray] byte buffer at specified index [index] * @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries. */ @SymbolName("Kotlin_ByteArray_setDoubleAt") public external fun ByteArray.setDoubleAt(index: Int, value: Double) ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent /** * Marks a top level property with a backing field or an object as thread local. * The object remains mutable and it is possible to change its state, * but every thread will have a distinct copy of this object, * so changes in one thread are not reflected in another. * * The annotation has effect only in Kotlin/Native platform. * * PLEASE NOTE THAT THIS ANNOTATION MAY GO AWAY IN UPCOMING RELEASES. */ @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public actual annotation class ThreadLocal /** * Marks a top level property with a backing field as immutable. * It is possible to share the value of such property between multiple threads, but it becomes deeply frozen, * so no changes can be made to its state or the state of objects it refers to. * * The annotation has effect only in Kotlin/Native platform. * * PLEASE NOTE THAT THIS ANNOTATION MAY GO AWAY IN UPCOMING RELEASES. */ @Target(AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.BINARY) public actual annotation class SharedImmutable ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Atomics.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.Frozen import kotlin.native.internal.LeakDetectorCandidate import kotlin.native.internal.NoReorderFields import kotlin.native.SymbolName import kotlinx.cinterop.NativePtr /** * Atomic values and freezing: atomics [AtomicInt], [AtomicLong], [AtomicNativePtr] and [AtomicReference] * are unique types with regard to freezing. Namely, they provide mutating operations, while can participate * in frozen subgraphs. So shared frozen objects can have fields of atomic types. */ @Frozen public class AtomicInt(private var value_: Int) { /** * The value being held by this class. */ public var value: Int get() = getImpl() set(new) = setImpl(new) /** * Increments the value by [delta] and returns the new value. * * @param delta the value to add * @return the new value */ @SymbolName("Kotlin_AtomicInt_addAndGet") external public fun addAndGet(delta: Int): Int /** * Compares value with [expected] and replaces it with [new] value if values matches. * * @param expected the expected value * @param new the new value * @return the old value */ @SymbolName("Kotlin_AtomicInt_compareAndSwap") external public fun compareAndSwap(expected: Int, new: Int): Int /** * Compares value with [expected] and replaces it with [new] value if values matches. * * @param expected the expected value * @param new the new value * @return true if successful */ @SymbolName("Kotlin_AtomicInt_compareAndSet") external public fun compareAndSet(expected: Int, new: Int): Boolean /** * Increments value by one. */ public fun increment(): Unit { addAndGet(1) } /** * Decrements value by one. */ public fun decrement(): Unit { addAndGet(-1) } /** * Returns the string representation of this object. * * @return the string representation */ public override fun toString(): String = value.toString() // Implementation details. @SymbolName("Kotlin_AtomicInt_set") private external fun setImpl(new: Int): Unit @SymbolName("Kotlin_AtomicInt_get") private external fun getImpl(): Int } @Frozen public class AtomicLong(private var value_: Long = 0) { /** * The value being held by this class. */ public var value: Long get() = getImpl() set(new) = setImpl(new) /** * Increments the value by [delta] and returns the new value. * * @param delta the value to add * @return the new value */ @SymbolName("Kotlin_AtomicLong_addAndGet") external public fun addAndGet(delta: Long): Long /** * Increments the value by [delta] and returns the new value. * * @param delta the value to add * @return the new value */ public fun addAndGet(delta: Int): Long = addAndGet(delta.toLong()) /** * Compares value with [expected] and replaces it with [new] value if values matches. * * @param expected the expected value * @param new the new value * @return the old value */ @SymbolName("Kotlin_AtomicLong_compareAndSwap") external public fun compareAndSwap(expected: Long, new: Long): Long /** * Compares value with [expected] and replaces it with [new] value if values matches. * * @param expected the expected value * @param new the new value * @return true if successful, false if state is unchanged */ @SymbolName("Kotlin_AtomicLong_compareAndSet") external public fun compareAndSet(expected: Long, new: Long): Boolean /** * Increments value by one. */ public fun increment(): Unit { addAndGet(1L) } /** * Decrements value by one. */ fun decrement(): Unit { addAndGet(-1L) } /** * Returns the string representation of this object. * * @return the string representation of this object */ public override fun toString(): String = value.toString() // Implementation details. @SymbolName("Kotlin_AtomicLong_set") private external fun setImpl(new: Long): Unit @SymbolName("Kotlin_AtomicLong_get") private external fun getImpl(): Long } @Frozen public class AtomicNativePtr(private var value_: NativePtr) { /** * The value being held by this class. */ public var value: NativePtr get() = getImpl() set(new) = setImpl(new) /** * Compares value with [expected] and replaces it with [new] value if values matches. * If [new] value is not null, it must be frozen or permanent object. * * @param expected the expected value * @param new the new value * @throws InvalidMutabilityException if [new] is not frozen or a permanent object * @return the old value */ @SymbolName("Kotlin_AtomicNativePtr_compareAndSwap") external public fun compareAndSwap(expected: NativePtr, new: NativePtr): NativePtr /** * Compares value with [expected] and replaces it with [new] value if values matches. * * @param expected the expected value * @param new the new value * @return true if successful */ @SymbolName("Kotlin_AtomicNativePtr_compareAndSet") external public fun compareAndSet(expected: NativePtr, new: NativePtr): Boolean /** * Returns the string representation of this object. * * @return string representation of this object */ public override fun toString(): String = value.toString() // Implementation details. @SymbolName("Kotlin_AtomicNativePtr_set") private external fun setImpl(new: NativePtr): Unit @SymbolName("Kotlin_AtomicNativePtr_get") private external fun getImpl(): NativePtr } private fun idString(value: Any) = "${value.hashCode().toUInt().toString(16)}" private fun debugString(value: Any?): String { if (value == null) return "null" return "${value::class.qualifiedName}: ${idString(value)}" } /** * An atomic reference to a frozen Kotlin object. Can be used in concurrent scenarious * but frequently shall be of nullable type and be zeroed out once no longer needed. * Otherwise memory leak could happen. To detect such leaks [kotlin.native.internal.GC.detectCycles] * in debug mode could be helpful. */ @Frozen @LeakDetectorCandidate @NoReorderFields public class AtomicReference { private var value_: T // A spinlock to fix potential ARC race. private var lock: Int = 0 // Optimization for speeding up access. private var cookie: Int = 0 /** * Creates a new atomic reference pointing to given [ref]. * @throws InvalidMutabilityException if reference is not frozen. */ constructor(value: T) { checkIfFrozen(value) value_ = value } /** * The referenced value. * Gets the value or sets the [new] value. If [new] value is not null, * it must be frozen or permanent object. * * @throws InvalidMutabilityException if the value is not frozen or a permanent object */ public var value: T get() = @Suppress("UNCHECKED_CAST")(getImpl() as T) set(new) = setImpl(new) /** * Compares value with [expected] and replaces it with [new] value if values matches. * Note that comparison is identity-based, not value-based. * If [new] value is not null, it must be frozen or permanent object. * * @param expected the expected value * @param new the new value * @throws InvalidMutabilityException if the value is not frozen or a permanent object * @return the old value */ @SymbolName("Kotlin_AtomicReference_compareAndSwap") external public fun compareAndSwap(expected: T, new: T): T /** * Compares value with [expected] and replaces it with [new] value if values matches. * Note that comparison is identity-based, not value-based. * * @param expected the expected value * @param new the new value * @return true if successful */ @SymbolName("Kotlin_AtomicReference_compareAndSet") external public fun compareAndSet(expected: T, new: T): Boolean /** * Returns the string representation of this object. * * @return string representation of this object */ public override fun toString(): String = "${debugString(this)} -> ${debugString(value)}" // TODO: Consider making this public. internal fun swap(new: T): T { while (true) { val old = value if (old === new) { return old } if (compareAndSet(old, new)) { return old } } } // Implementation details. @SymbolName("Kotlin_AtomicReference_set") private external fun setImpl(new: Any?): Unit @SymbolName("Kotlin_AtomicReference_get") private external fun getImpl(): Any? } /** * An atomic reference to a Kotlin object. Can be used in concurrent scenarious, but must be frozen first, * otherwise behaves as regular box for the value. If frozen, shall be zeroed out once no longer needed. * Otherwise memory leak could happen. To detect such leaks [kotlin.native.internal.GC.detectCycles] * in debug mode could be helpful. */ @NoReorderFields @LeakDetectorCandidate @ExportTypeInfo("theFreezableAtomicReferenceTypeInfo") public class FreezableAtomicReference(private var value_: T) { // A spinlock to fix potential ARC race. private var lock: Int = 0 // Optimization for speeding up access. private var cookie: Int = 0 /** * The referenced value. * Gets the value or sets the [new] value. If [new] value is not null, * and `this` is frozen - it must be frozen or permanent object. * * @throws InvalidMutabilityException if the value is not frozen or a permanent object */ public var value: T get() = @Suppress("UNCHECKED_CAST")(getImpl() as T) set(new) { if (this.isFrozen) setImpl(new) else value_ = new } /** * Compares value with [expected] and replaces it with [new] value if values matches. * If [new] value is not null and object is frozen, it must be frozen or permanent object. * * @param expected the expected value * @param new the new value * @throws InvalidMutabilityException if the value is not frozen or a permanent object * @return the old value */ public fun compareAndSwap(expected: T, new: T): T { return if (this.isFrozen) @Suppress("UNCHECKED_CAST")(compareAndSwapImpl(expected, new) as T) else { val old = value_ if (old === expected) value_ = new old } } /** * Compares value with [expected] and replaces it with [new] value if values matches. * Note that comparison is identity-based, not value-based. * * @param expected the expected value * @param new the new value * @return true if successful */ public fun compareAndSet(expected: T, new: T): Boolean { if (this.isFrozen) return compareAndSetImpl(expected, new) val old = value_ if (old === expected) { value_ = new return true } else { return false } } /** * Returns the string representation of this object. * * @return string representation of this object */ public override fun toString(): String = "${debugString(this)} -> ${debugString(value)}" // Implementation details. @SymbolName("Kotlin_AtomicReference_set") private external fun setImpl(new: Any?): Unit @SymbolName("Kotlin_AtomicReference_get") private external fun getImpl(): Any? @SymbolName("Kotlin_AtomicReference_compareAndSwap") private external fun compareAndSwapImpl(expected: Any?, new: Any?): Any? @SymbolName("Kotlin_AtomicReference_compareAndSet") private external fun compareAndSetImpl(expected: Any?, new: Any?): Boolean } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Continuation.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.* import kotlinx.cinterop.* public class Continuation0(block: () -> Unit, private val invoker: CPointer Unit>>, private val singleShot: Boolean = false): Function0 { private val stable = StableRef.create(block) init { freeze() } public override operator fun invoke() { invoker(stable.asCPointer()) if (singleShot) { stable.dispose() } } public fun dispose() { assert(!singleShot) stable.dispose() } } public class Continuation1( block: (p1: T1) -> Unit, private val invoker: CPointer Unit>>, private val singleShot: Boolean = false) : Function1 { private val stable = StableRef.create(block) init { freeze() } public override operator fun invoke(p1: T1) { require(p1.isFrozen) val args = StableRef.create(Pair(stable, p1).freeze()) try { invoker(args.asCPointer()) } finally { args.dispose() } if (singleShot) { stable.dispose() } } public fun dispose() { assert(!singleShot) stable.dispose() } } public class Continuation2( block: (p1: T1, p2: T2) -> Unit, private val invoker: CPointer Unit>>, private val singleShot: Boolean = false) : Function2 { private val stable = StableRef.create(block) init { freeze() } public override operator fun invoke(p1: T1, p2: T2) { require(p1.isFrozen) require(p2.isFrozen) val args = StableRef.create(Triple(stable, p1, p2).freeze()) try { invoker(args.asCPointer()) } finally { args.dispose() } if (singleShot) { stable.dispose() } } fun dispose() { assert(!singleShot) stable.dispose() } } public fun COpaquePointer.callContinuation0() { val single = this.asStableRef<() -> Unit>() single.get()() } public fun COpaquePointer.callContinuation1() { val pair = this.asStableRef Unit>, T1>>().get() pair.first.get()(pair.second) } public fun COpaquePointer.callContinuation2() { val triple = this.asStableRef Unit>, T1, T2>>().get() triple.first.get()(triple.second, triple.third) } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent /** * Exception thrown whenever freezing is not possible. * * @param toFreeze an object intended to be frozen. * @param blocker an object preventing freezing, usually one marked with [ensureNeverFrozen] earlier. */ public class FreezingException(toFreeze: Any, blocker: Any) : RuntimeException("freezing of $toFreeze has failed, first blocker is $blocker") /** * Exception thrown whenever we attempt to mutate frozen objects. * * @param where a frozen object that was attempted to mutate */ public class InvalidMutabilityException(message: String) : RuntimeException(message) /** * Freezes object subgraph reachable from this object. Frozen objects can be freely * shared between threads/workers. * * @throws FreezingException if freezing is not possible * @return the object itself * @see ensureNeverFrozen */ public fun T.freeze(): T { freezeInternal(this) return this } /** * Checks if given object is null or frozen or permanent (i.e. instantiated at compile-time). * * @return true if given object is null or frozen or permanent */ public val Any?.isFrozen get() = isFrozenInternal(this) /** * This function ensures that if we see such an object during freezing attempt - freeze fails and * [FreezingException] is thrown. * * @throws FreezingException thrown immediately if this object is already frozen * @see freeze */ @SymbolName("Kotlin_Worker_ensureNeverFrozen") public external fun Any.ensureNeverFrozen() ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Future.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.Frozen /** * State of the future object. */ enum class FutureState(val value: Int) { INVALID(0), /** Future is scheduled for execution. */ SCHEDULED(1), /** Future result is computed. */ COMPUTED(2), /** Future is cancelled. */ CANCELLED(3), /** Computation thrown an exception. */ THROWN(4) } /** * Class representing abstract computation, whose result may become available in the future. */ @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") public inline class Future @PublishedApi internal constructor(val id: Int) { /** * Blocks execution until the future is ready. * * @return the execution result of [code] consumed future's computaiton * @throws IllegalStateException if future is in [FutureState.INVALID], [FutureState.CANCELLED] or * [FutureState.THROWN] state */ public inline fun consume(code: (T) -> R): R = when (state) { FutureState.SCHEDULED, FutureState.COMPUTED -> { val value = @Suppress("UNCHECKED_CAST", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") (consumeFuture(id) as T) code(value) } FutureState.INVALID -> throw IllegalStateException("Future is in an invalid state") FutureState.CANCELLED -> { consumeFuture(id) throw IllegalStateException("Future is cancelled") } FutureState.THROWN -> { consumeFuture(id) throw IllegalStateException("Job has thrown an exception") } } /** * The result of the future computation. * Blocks execution until the future is ready. Second attempt to get will result in an error. */ public val result: T get() = consume { it -> it } /** * A [FutureState] of this future */ public val state: FutureState get() = FutureState.values()[stateOfFuture(id)] override public fun toString(): String = "future $id" } @Deprecated("Use 'waitForMultipleFutures' top-level function instead", ReplaceWith("waitForMultipleFutures(this, millis)"), DeprecationLevel.ERROR) public fun Collection>.waitForMultipleFutures(millis: Int): Set> = waitForMultipleFutures(this, millis) /** * Wait for availability of futures in the collection. Returns set with all futures which have * value available for the consumption, i.e. [FutureState.COMPUTED]. * * @param timeoutMillis the amount of time in milliseconds to wait for the computed future */ public fun waitForMultipleFutures(futures: Collection>, timeoutMillis: Int): Set> { val result = mutableSetOf>() while (true) { val versionToken = versionToken() for (future in futures) { if (future.state == FutureState.COMPUTED) { result += future } } if (result.isNotEmpty()) return result if (waitForAnyFuture(versionToken, timeoutMillis)) break } for (future in futures) { if (future.state == FutureState.COMPUTED) { result += future } } return result } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.DescribeObjectForDebugging import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.InternalForKotlinNative import kotlin.native.internal.debugDescription import kotlin.native.identityHashCode import kotlin.reflect.KClass import kotlinx.cinterop.* // Implementation details. @SymbolName("Kotlin_Worker_stateOfFuture") external internal fun stateOfFuture(id: Int): Int @SymbolName("Kotlin_Worker_consumeFuture") @PublishedApi external internal fun consumeFuture(id: Int): Any? @SymbolName("Kotlin_Worker_waitForAnyFuture") external internal fun waitForAnyFuture(versionToken: Int, millis: Int): Boolean @SymbolName("Kotlin_Worker_versionToken") external internal fun versionToken(): Int @kotlin.native.internal.ExportForCompiler internal fun executeImpl(worker: Worker, mode: TransferMode, producer: () -> Any?, job: CPointer>): Future = Future(executeInternal(worker.id, mode.value, producer, job)) @SymbolName("Kotlin_Worker_startInternal") external internal fun startInternal(errorReporting: Boolean, name: String?): Int @SymbolName("Kotlin_Worker_currentInternal") external internal fun currentInternal(): Int @SymbolName("Kotlin_Worker_requestTerminationWorkerInternal") external internal fun requestTerminationInternal(id: Int, processScheduledJobs: Boolean): Int @SymbolName("Kotlin_Worker_executeInternal") external internal fun executeInternal( id: Int, mode: Int, producer: () -> Any?, job: CPointer>): Int @SymbolName("Kotlin_Worker_executeAfterInternal") external internal fun executeAfterInternal(id: Int, operation: () -> Unit, afterMicroseconds: Long): Unit @SymbolName("Kotlin_Worker_processQueueInternal") external internal fun processQueueInternal(id: Int): Boolean @SymbolName("Kotlin_Worker_parkInternal") external internal fun parkInternal(id: Int, timeoutMicroseconds: Long, process: Boolean): Boolean @SymbolName("Kotlin_Worker_getNameInternal") external internal fun getWorkerNameInternal(id: Int): String? @ExportForCppRuntime internal fun ThrowWorkerUnsupported(): Unit = throw UnsupportedOperationException("Workers are not supported") @ExportForCppRuntime internal fun ThrowWorkerInvalidState(): Unit = throw IllegalStateException("Illegal transfer state") @ExportForCppRuntime internal fun WorkerLaunchpad(function: () -> Any?) = function() @PublishedApi @SymbolName("Kotlin_Worker_detachObjectGraphInternal") external internal fun detachObjectGraphInternal(mode: Int, producer: () -> Any?): NativePtr @PublishedApi @SymbolName("Kotlin_Worker_attachObjectGraphInternal") external internal fun attachObjectGraphInternal(stable: NativePtr): Any? @SymbolName("Kotlin_Worker_freezeInternal") internal external fun freezeInternal(it: Any?) @SymbolName("Kotlin_Worker_isFrozenInternal") internal external fun isFrozenInternal(it: Any?): Boolean @ExportForCppRuntime internal fun ThrowFreezingException(toFreeze: Any, blocker: Any): Nothing = throw FreezingException(toFreeze, blocker) @ExportForCppRuntime internal fun ThrowInvalidMutabilityException(where: Any): Nothing { val description = debugDescription(where::class, where.identityHashCode()) throw InvalidMutabilityException("mutation attempt of frozen $description") } @ExportForCppRuntime internal fun ThrowIllegalObjectSharingException(typeInfo: NativePtr, address: NativePtr) { val description = DescribeObjectForDebugging(typeInfo, address) throw IncorrectDereferenceException("illegal attempt to access non-shared $description from other thread") } @SymbolName("Kotlin_AtomicReference_checkIfFrozen") external internal fun checkIfFrozen(ref: Any?) @InternalForKotlinNative @SymbolName("Kotlin_Worker_waitTermination") external public fun waitWorkerTermination(worker: Worker) ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Lazy.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.Frozen internal class FreezeAwareLazyImpl(initializer: () -> T) : Lazy { private val value_ = FreezableAtomicReference(UNINITIALIZED) private var initializer_: (() -> T)? = initializer private val lock_ = Lock() private fun getOrInit(doFreeze: Boolean): T { var result = value_.value if (result !== UNINITIALIZED) { if (result === INITIALIZING) { value_.value = UNINITIALIZED throw IllegalStateException("Recursive lazy computation") } @Suppress("UNCHECKED_CAST") return result as T } // Set value_ to INITIALIZING. value_.value = INITIALIZING try { result = initializer_!!() if (doFreeze) result.freeze() } catch (throwable: Throwable) { value_.value = UNINITIALIZED throw throwable } if (!doFreeze) { if (this.isFrozen) { value_.value = UNINITIALIZED throw InvalidMutabilityException("Frozen during lazy computation") } // Clear initializer. initializer_ = null } // Set value_ to actual one. value_.value = result return result } override val value: T get() { return if (isFrozen) { locked(lock_) { getOrInit(true) } } else { getOrInit(false) } } /** * This operation on shared objects may return value which is no longer reflect the current state of lazy. */ override fun isInitialized(): Boolean = (value_.value !== UNINITIALIZED) && (value_.value !== INITIALIZING) override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet" } internal object UNINITIALIZED { // So that single-threaded configs can use those as well. init { freeze() } } internal object INITIALIZING { // So that single-threaded configs can use those as well. init { freeze() } } @Frozen internal class AtomicLazyImpl(initializer: () -> T) : Lazy { private val initializer_ = AtomicReference?>(initializer.freeze()) private val value_ = AtomicReference(UNINITIALIZED) override val value: T get() { if (value_.compareAndSwap(UNINITIALIZED, INITIALIZING) === UNINITIALIZED) { // We execute exclusively here. val ctor = initializer_.value if (ctor != null && initializer_.compareAndSet(ctor, null)) { value_.compareAndSet(INITIALIZING, ctor().freeze()) } else { // Something wrong. assert(false) } } var result: Any? do { result = value_.value } while (result === INITIALIZING) assert(result !== UNINITIALIZED && result !== INITIALIZING) @Suppress("UNCHECKED_CAST") return result as T } override fun isInitialized(): Boolean = value_.value !== UNINITIALIZED override fun toString(): String = if (isInitialized()) value_.value.toString() else "Lazy value not initialized yet." } /** * Atomic lazy initializer, could be used in frozen objects, freezes initializing lambda, * so use very carefully. Also, as with other uses of an [AtomicReference] may potentially * leak memory, so it is recommended to use `atomicLazy` in cases of objects living forever, * such as object signletons, or in cases where it's guaranteed not to have cyclical garbage. */ public fun atomicLazy(initializer: () -> T): Lazy = AtomicLazyImpl(initializer) ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Lock.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.Frozen @ThreadLocal private object CurrentThread { val id = Any().freeze() } @Frozen internal class Lock { private val locker_ = AtomicInt(0) private val reenterCount_ = AtomicInt(0) // TODO: make it properly reschedule instead of spinning. fun lock() { val lockData = CurrentThread.id.hashCode() loop@ do { val old = locker_.compareAndSwap(0, lockData) when (old) { lockData -> { // Was locked by us already. reenterCount_.increment() break@loop } 0 -> { // We just got the lock. assert(reenterCount_.value == 0) break@loop } } } while (true) } fun unlock() { if (reenterCount_.value > 0) { reenterCount_.decrement() } else { val lockData = CurrentThread.id.hashCode() val old = locker_.compareAndSwap(lockData, 0) assert(old == lockData) } } } internal inline fun locked(lock: Lock, block: () -> R): R { lock.lock() try { return block() } finally { lock.unlock() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/MutableData.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.* import kotlinx.cinterop.* @SymbolName("Kotlin_Any_share") external private fun Any.share() @SymbolName("Kotlin_CPointer_CopyMemory") external private fun CopyMemory(to: COpaquePointer?, from: COpaquePointer?, count: Int) @SymbolName("ReadHeapRefNoLock") internal external fun readHeapRefNoLock(where: Any, index: Int): Any? /** * Mutable concurrently accessible data buffer. Could be accessed from several workers simulteniously. */ @Frozen @NoReorderFields public class MutableData constructor(capacity: Int = 16) { init { if (capacity <= 0) throw IllegalArgumentException() // Instance of MutableData is shared. share() } private var buffer_ = ByteArray(capacity).apply { share() } private var buffer: ByteArray get() = when (kotlin.native.Platform.memoryModel) { kotlin.native.MemoryModel.EXPERIMENTAL -> buffer_ else -> readHeapRefNoLock(this, 0) as ByteArray } set(value) { buffer_ = value} private var size_ = 0 private val lock = Lock() private fun resizeDataLocked(newSize: Int): Int { assert(newSize >= size) if (newSize > buffer.size) { val actualSize = maxOf(buffer.size * 3 / 2 + 1, newSize) val newBuffer = ByteArray(actualSize) buffer.copyInto(newBuffer, startIndex = 0, endIndex = size) newBuffer.share() buffer = newBuffer } val position = size size_ = newSize return position } /** * Current data size, may concurrently change later on. */ public val size: Int get() = size_ /** * Reset the data buffer, makings its size 0. */ public fun reset() = locked(lock) { size_ = 0 } /** * Appends data to the buffer. */ public fun append(data: MutableData) = locked(lock) { val toCopy = data.size val where = resizeDataLocked(size + toCopy) data.copyInto(buffer, 0, toCopy, where) } /** * Appends byte array to the buffer. */ public fun append(data: ByteArray, fromIndex: Int = 0, toIndex: Int = data.size): Unit = locked(lock) { if (fromIndex > toIndex) throw IndexOutOfBoundsException("$fromIndex is bigger than $toIndex") if (fromIndex == toIndex) return val where = resizeDataLocked(this.size + (toIndex - fromIndex)) data.copyInto(buffer, where, fromIndex, toIndex) } /** * Appends C data to the buffer, if `data` is null or `count` is non-positive - return. */ public fun append(data: COpaquePointer?, count: Int): Unit = locked(lock) { if (data == null || count <= 0) return val where = resizeDataLocked(this.size + count) buffer.usePinned { it -> CopyMemory(it.addressOf(where), data, count) } } /** * Copies range of mutable data to the byte array. */ public fun copyInto(output: ByteArray, destinationIndex: Int, startIndex: Int, endIndex: Int): Unit = locked(lock) { buffer.copyInto(output, destinationIndex, startIndex, endIndex) } /** * Get a byte from the mutable data. * * @Throws IndexOutOfBoundsException if index is beyond range. */ public operator fun get(index: Int): Byte = locked(lock) { // index < 0 is checked below by array access. if (index >= size) throw IndexOutOfBoundsException("$index is not below $size") buffer[index] } /** * Executes provided block under lock with raw pointer to the data stored in the buffer. * Block is executed under the spinlock, and must be short. */ public fun withPointerLocked(block: (COpaquePointer, dataSize: Int) -> R) = locked(lock) { buffer.usePinned { it -> block(it.addressOf(0), size) } } /** * Executes provided block under lock with the raw data buffer. * Block is executed under the spinlock, and must be short. */ public fun withBufferLocked(block: (array: ByteArray, dataSize: Int) -> R) = locked(lock) { block(buffer, size) } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/ObjectTransfer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlinx.cinterop.* import kotlin.native.internal.Frozen /** * ## Object Transfer Basics. * * Objects can be passed between threads in one of two possible modes. * * - [SAFE] - object subgraph is checked to be not reachable by other globals or locals, and passed * if so, otherwise an exception is thrown * - [UNSAFE] - object is blindly passed to another worker, if there are references * left in the passing worker - it may lead to crash or program malfunction * * Safe mode checks if object is no longer used in passing worker, using memory-management * specific algorithm (ARC implementation relies on trial deletion on object graph rooted in * passed object), and throws an [IllegalStateException] if object graph rooted in transferred object * is reachable by some other means, * * Unsafe mode is intended for most performance critical operations, where object graph ownership * is expected to be correct (such as application debugged earlier in [SAFE] mode), just transfers * ownership without further checks. * * Note, that for some cases cycle collection need to be done to ensure that dead cycles do not affect * reachability of passed object graph. * * @see [kotlin.native.internal.GC.collect]. */ public enum class TransferMode(val value: Int) { /** * Reachibility check is performed. */ SAFE(0), /** * Skip reachibility check, can lead to mysterious crashes in an application. * USE UNSAFE MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!! */ UNSAFE(1) } /** * Detached object graph encapsulates transferrable detached subgraph which cannot be accessed * externally, until it is attached with the [attach] extension function. */ @Frozen public class DetachedObjectGraph internal constructor(pointer: NativePtr) { @PublishedApi internal val stable = AtomicNativePtr(pointer) /** * Creates stable pointer to object, ensuring associated object subgraph is disjoint in specified mode * ([TransferMode.SAFE] by default). * Raw value returned by [asCPointer] could be stored to a C variable or passed to another Kotlin machine. */ public constructor(mode: TransferMode = TransferMode.SAFE, producer: () -> T) : this(detachObjectGraphInternal(mode.value, producer as () -> Any?)) /** * Restores detached object graph from the value stored earlier in a C raw pointer. */ public constructor(pointer: COpaquePointer?) : this(pointer?.rawValue ?: NativePtr.NULL) /** * Returns raw C pointer value, usable for interoperability with C scenarious. */ public fun asCPointer(): COpaquePointer? = interpretCPointer(stable.value) } /** * Attaches previously detached object subgraph created by [DetachedObjectGraph]. * Please note, that once object graph is attached, the [DetachedObjectGraph.stable] pointer does not * make sense anymore, and shall be discarded, so attach of one DetachedObjectGraph object can only * happen once. */ public inline fun DetachedObjectGraph.attach(): T { var rawStable: NativePtr do { rawStable = stable.value } while (!stable.compareAndSet(rawStable, NativePtr.NULL)) val result = attachObjectGraphInternal(rawStable) as T return result } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/Worker.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.Frozen import kotlin.native.internal.VolatileLambda import kotlin.native.internal.IntrinsicType import kotlin.native.internal.TypedIntrinsic import kotlinx.cinterop.* /** * ## Workers: theory of operations. * * [Worker] represents asynchronous and concurrent computation, usually performed by other threads * in the same process. Object passing between workers is performed using transfer operation, so that * object graph belongs to one worker at the time, but can be disconnected and reconnected as needed. * See 'Object Transfer Basics' and [TransferMode] for more details on how objects shall be transferred. * This approach ensures that no concurrent access happens to same object, while data may flow between * workers as needed. */ /** * Class representing worker. */ @Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS") public inline class Worker @PublishedApi internal constructor(val id: Int) { companion object { /** * Start new scheduling primitive, such as thread, to accept new tasks via `execute` interface. * Typically new worker may be needed for computations offload to another core, for IO it may be * better to use non-blocking IO combined with more lightweight coroutines. * * @param errorReporting controls if an uncaught exceptions in the worker will be printed out * @param name defines the optional name of this worker, if none - default naming is used. * @return worker object, usable across multiple concurrent contexts. */ public fun start(errorReporting: Boolean = true, name: String? = null): Worker = Worker(startInternal(errorReporting, name)) /** * Return the current worker. Worker context is accessible to any valid Kotlin context, * but only actual active worker produced with [Worker.start] automatically processes execution requests. * For other situations [processQueue] must be called explicitly to process request queue. * @return current worker object, usable across multiple concurrent contexts. */ public val current: Worker get() = Worker(currentInternal()) /** * Create worker object from a C pointer. * * This function is deprecated. See [Worker.asCPointer] for more details. * * @param pointer value returned earlier by [Worker.asCPointer] */ @Deprecated("Use kotlinx.cinterop.StableRef instead", level = DeprecationLevel.WARNING) public fun fromCPointer(pointer: COpaquePointer?): Worker = if (pointer != null) Worker(pointer.toLong().toInt()) else throw IllegalArgumentException() } /** * Requests termination of the worker. * * @param processScheduledJobs controls is we shall wait until all scheduled jobs processed, * or terminate immediately. If there are jobs to be execucted with [executeAfter] their execution * is awaited for. */ public fun requestTermination(processScheduledJobs: Boolean = true): Future = Future(requestTerminationInternal(id, processScheduledJobs)) /** * Plan job for further execution in the worker. Execute is a two-phase operation: * - first [producer] function is executed, and resulting object and whatever it refers to * is analyzed for being an isolated object subgraph, if in checked mode. * - Afterwards, this disconnected object graph and [job] function pointer is being added to jobs queue * of the selected worker. Note that [job] must not capture any state itself, so that whole state is * explicitly stored in object produced by [producer]. Scheduled job is being executed by the worker, * and result of such a execution is being disconnected from worker's object graph. Whoever will consume * the future, can use result of worker's computations. * Note, that some technically disjoint subgraphs may lead to `kotlin.IllegalStateException` * so `kotlin.native.internal.GC.collect()` could be called in the end of `producer` and `job` * if garbage cyclic structures or other uncollected objects refer to the value being transferred. * * @return the future with the computation result of [job]. */ @Suppress("UNUSED_PARAMETER") @TypedIntrinsic(IntrinsicType.WORKER_EXECUTE) public fun execute(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future = /* * This function is a magical operation, handled by lowering in the compiler, and replaced with call to * executeImpl(worker, mode, producer, job) * but first ensuring that `job` parameter doesn't capture any state. */ throw RuntimeException("Shall not be called directly") /** * Plan job for further execution in the worker. [operation] parameter must be either frozen, or execution to be * planned on the current worker. Otherwise [IllegalStateException] will be thrown. * * @param afterMicroseconds defines after how many microseconds delay execution shall happen, 0 means immediately, * @throws [IllegalArgumentException] on negative values of [afterMicroseconds]. * @throws [IllegalStateException] if [operation] parameter is not frozen and worker is not current. */ public fun executeAfter(afterMicroseconds: Long = 0, operation: () -> Unit): Unit { val current = currentInternal() if (current != id && !operation.isFrozen) throw IllegalStateException("Job for another worker must be frozen") if (afterMicroseconds < 0) throw IllegalArgumentException("Timeout parameter must be non-negative") executeAfterInternal(id, operation, afterMicroseconds) } /** * Process pending job(s) on the queue of this worker. * Note that jobs scheduled with [executeAfter] using non-zero timeout are * not processed this way. If termination request arrives while processing the queue via this API, * worker is marked as terminated and will exit once the current request is done with. * * @throws [IllegalStateException] if this request is executed on non-current [Worker]. * @return `true` if request(s) was processed and `false` otherwise. */ public fun processQueue(): Boolean = processQueueInternal(id) /** * Park execution of the current worker until a new request arrives or timeout specified in * [timeoutMicroseconds] elapsed. If [process] is true, pending queue elements are processed, * including delayed requests. Note that multiple requests could be processed this way. * * @param timeoutMicroseconds defines how long to park worker if no requests arrive, waits forever if -1. * @param process defines if arrived request(s) shall be processed. * @return if [process] is `true`: if request(s) was processed `true` and `false` otherwise. * if [process] is `false`:` true` if request(s) has arrived and `false` if timeout happens. * @throws [IllegalStateException] if this request is executed on non-current [Worker]. * @throws [IllegalArgumentException] if timeout value is incorrect. */ public fun park(timeoutMicroseconds: Long, process: Boolean = false): Boolean { if (timeoutMicroseconds < -1) throw IllegalArgumentException() return parkInternal(id, timeoutMicroseconds, process) } /** * Name of the worker, as specified in [Worker.start] or "worker $id" by default, * * @throws [IllegalStateException] if this request is executed on an invalid worker. */ public val name: String get() { val customName = getWorkerNameInternal(id) return if (customName == null) "worker $id" else customName } /** * String representation of the worker. */ override public fun toString(): String = "Worker $name" /** * Convert worker to a COpaquePointer value that could be passed via native void* pointer. * Can be used as an argument of [Worker.fromCPointer]. * * This function is deprecated. Use `kotlinx.cinterop.StableRef.create(worker).asCPointer()` instead. * The result can be unwrapped with `pointer.asStableRef().get()`. * [StableRef] should be eventually disposed manually with [StableRef.dispose]. * * @return worker identifier as C pointer. */ @Deprecated("Use kotlinx.cinterop.StableRef instead", level = DeprecationLevel.WARNING) public fun asCPointer() : COpaquePointer? = id.toLong().toCPointer() } /** * Executes [block] with new [Worker] as resource, by starting the new worker, calling provided [block] * (in current context) with newly started worker as [this] and terminating worker after the block completes. * Note that this operation is pretty heavyweight, use preconfigured worker or worker pool if need to * execute it frequently. * * @param name of the started worker. * @param errorReporting controls if uncaught errors in worker to be reported. * @param block to be executed. * @return value returned by the block. */ public inline fun withWorker(name: String? = null, errorReporting: Boolean = true, block: Worker.() -> R): R { val worker = Worker.start(errorReporting, name) try { return worker.block() } finally { worker.requestTermination().result } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/concurrent/WorkerBoundReference.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.concurrent import kotlin.native.internal.* @SymbolName("Kotlin_WorkerBoundReference_create") external private fun createWorkerBoundReference(value: Any): NativePtr @SymbolName("Kotlin_WorkerBoundReference_deref") external private fun derefWorkerBoundReference(ref: NativePtr): Any? @SymbolName("Kotlin_WorkerBoundReference_describe") external private fun describeWorkerBoundReference(ref: NativePtr): String /** * A shared reference to a Kotlin object that doesn't freeze the referred object when it gets frozen itself. * * After freezing can be safely passed between workers, but [value] can only be accessed on * the worker [WorkerBoundReference] was created on, unless the referred object is frozen too. * * Note: Garbage collector currently cannot free any reference cycles with frozen [WorkerBoundReference] in them. * To resolve such cycles consider using [AtomicReference]`` which can be explicitly * nulled out. */ @NoReorderFields @ExportTypeInfo("theWorkerBoundReferenceTypeInfo") @HasFinalizer @HasFreezeHook public class WorkerBoundReference(value: T) { private var ptr = NativePtr.NULL private val ownerName = Worker.current.name private var valueBeforeFreezing: T? = value private val valueDescription get() = describeWorkerBoundReference(ptr) /** * The referenced value. * @throws IncorrectDereferenceException if referred object is not frozen and current worker is different from the one created [this]. */ val value: T get() = valueOrNull ?: throw IncorrectDereferenceException("illegal attempt to access non-shared $valueDescription bound to `$ownerName` from `${Worker.current.name}`") /** * The referenced value or null if referred object is not frozen and current worker is different from the one created [this]. */ val valueOrNull: T? get() = valueBeforeFreezing ?: @Suppress("UNCHECKED_CAST") (derefWorkerBoundReference(ptr) as T?) /** * Worker that [value] is bound to. */ val worker: Worker = Worker.current @ExportForCppRuntime("Kotlin_WorkerBoundReference_freezeHook") private fun freezeHook() { // If this hook was already run, do nothing. if (valueBeforeFreezing == null) return ptr = createWorkerBoundReference(valueBeforeFreezing!!) valueBeforeFreezing = null } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal /** * Makes this function to be possible to call by given name from C++ part of runtime using C ABI. * The parameters are mapped in an implementation-dependent manner. * * The function to call from C++ can be a wrapper around the original function. * * If the name is not specified, the function to call will be available by its Kotlin unqualified name. * * This annotation is not intended for the general consumption and is public only for the launcher! */ @Target( AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER ) @Retention(AnnotationRetention.BINARY) public annotation class ExportForCppRuntime(val name: String = "") /** * This annotation denotes that the element is intrinsic and its usages require special handling in compiler. */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.BINARY) internal annotation class Intrinsic /** * Exports symbol for compiler needs. * * This annotation is not intended for the general consumption and is public only for interop! */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class ExportForCompiler /** * Class is frozen by default. Also this annotation is (ab)used for marking objects * where mutability checks are not needed, and they are shared, such as atomics. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) internal annotation class Frozen /** * Fields of annotated class won't be sorted. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) internal annotation class NoReorderFields /** * Exports the TypeInfo of this class by given name to use it from runtime. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) public annotation class ExportTypeInfo(val name: String) /** * If a lambda shall be carefully lowered by the compiler. */ @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.BINARY) internal annotation class VolatileLambda /** * Need to be fixed because of reflection. */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) internal annotation class FixmeReflection /** * Need to be fixed because of concurrency. */ @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) internal annotation class FixmeConcurrency /** * Escape analysis annotations. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) internal annotation class Escapes(val who: Int) // Decyphering of binary values can be found in EscapeAnalysis.kt @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) internal annotation class PointsTo(vararg val onWhom: Int) @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) internal annotation class TypedIntrinsic(val kind: String) /** * Indicates that `@SymbolName external` function is implemented in library-stored bitcode * and doesn't have native dependencies. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) annotation class Independent /** * Indicates that `@SymbolName external` function can throw foreign exception to be filtered on callsite. * * Note: this annotation describes rather behaviour of the (direct) call than that of the function. * E.g. it doesn't have any effect when calling the function virtually. TODO: rework. */ @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.BINARY) @PublishedApi internal annotation class FilterExceptions(val mode: String = "terminate") /** * Marks a class whose instances to be added to the list of leak detector candidates. */ @Target(AnnotationTarget.CLASS) @PublishedApi internal annotation class LeakDetectorCandidate /** * Indicates that given top level signleton object can be created in compile time and thus * members access doesn't need to use an init barrier and allow better optimizations for * field access, such as constant folding. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) public annotation class CanBePrecreated /** * Marks a class that has a finalizer. */ @Target(AnnotationTarget.CLASS) internal annotation class HasFinalizer /** * Marks a declaration that is internal for Kotlin/Native and shouldn't be used externally. */ @RequiresOptIn(level = RequiresOptIn.Level.ERROR) @Retention(value = AnnotationRetention.BINARY) internal annotation class InternalForKotlinNative /** * Marks a class that has a freeze hook. */ @Target(AnnotationTarget.CLASS) internal annotation class HasFreezeHook ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Boxing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal @SymbolName("getCachedBooleanBox") external fun getCachedBooleanBox(value: Boolean): Boolean? @SymbolName("inBooleanBoxCache") external fun inBooleanBoxCache(value: Boolean): Boolean @SymbolName("getCachedByteBox") external fun getCachedByteBox(value: Byte): Byte? @SymbolName("inByteBoxCache") external fun inByteBoxCache(value: Byte): Boolean @SymbolName("getCachedCharBox") external fun getCachedCharBox(value: Char): Char? @SymbolName("inCharBoxCache") external fun inCharBoxCache(value: Char): Boolean @SymbolName("getCachedShortBox") external fun getCachedShortBox(value: Short): Short? @SymbolName("inShortBoxCache") external fun inShortBoxCache(value: Short): Boolean @SymbolName("getCachedIntBox") external fun getCachedIntBox(idx: Int): Int? @SymbolName("inIntBoxCache") external fun inIntBoxCache(value: Int): Boolean @SymbolName("getCachedLongBox") external fun getCachedLongBox(value: Long): Long? @SymbolName("inLongBoxCache") external fun inLongBoxCache(value: Long): Boolean // TODO: functions below are used for ObjCExport, move and rename them correspondigly. @ExportForCppRuntime("Kotlin_boxBoolean") fun boxBoolean(value: Boolean): Boolean? = value @ExportForCppRuntime("Kotlin_boxChar") fun boxChar(value: Char): Char? = value @ExportForCppRuntime("Kotlin_boxByte") fun boxByte(value: Byte): Byte? = value @ExportForCppRuntime("Kotlin_boxShort") fun boxShort(value: Short): Short? = value @ExportForCppRuntime("Kotlin_boxInt") fun boxInt(value: Int): Int? = value @ExportForCppRuntime("Kotlin_boxLong") fun boxLong(value: Long): Long? = value @ExperimentalUnsignedTypes @ExportForCppRuntime("Kotlin_boxUByte") fun boxUByte(value: UByte): UByte? = value @ExperimentalUnsignedTypes @ExportForCppRuntime("Kotlin_boxUShort") fun boxUShort(value: UShort): UShort? = value @ExperimentalUnsignedTypes @ExportForCppRuntime("Kotlin_boxUInt") fun boxUInt(value: UInt): UInt? = value @ExperimentalUnsignedTypes @ExportForCppRuntime("Kotlin_boxULong") fun boxULong(value: ULong): ULong? = value @ExportForCppRuntime("Kotlin_boxFloat") fun boxFloat(value: Float): Float? = value @ExportForCppRuntime("Kotlin_boxDouble") fun boxDouble(value: Double): Double? = value @ExportForCppRuntime("Kotlin_boxUnit") internal fun Kotlin_boxUnit(): Unit? = Unit ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Cleaner.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.native.concurrent.* import kotlinx.cinterop.NativePtr public interface Cleaner /** * Creates an object with a cleanup associated. * * After the resulting object ("cleaner") gets deallocated by memory manager, * [block] is eventually called once with [argument]. * * Example of usage: * ``` * class ResourceWrapper { * private val resource = Resource() * * private val cleaner = createCleaner(resource) { it.dispose() } * } * ``` * * When `ResourceWrapper` becomes unused and gets deallocated, its `cleaner` * is also deallocated, and the resource is disposed later. * * It is not specified which thread runs [block], as well as whether two or more * blocks from different cleaners can be run in parallel. * * Note: if [argument] refers (directly or indirectly) the cleaner, then both * might leak, and the [block] will not be called in this case. * For example, the code below has a leak: * ``` * class LeakingResourceWrapper { * private val resource = Resource() * private val cleaner = createCleaner(this) { it.resource.dispose() } * } * ``` * In this case cleaner's argument (`LeakingResourceWrapper`) can't be deallocated * until cleaner's block is executed, which can happen only strictly after * the cleaner is deallocated, which can't happen until `LeakingResourceWrapper` * is deallocated. So the requirements on object deallocations are contradictory * in this case, which can't be handled gracefully. The cleaner's block * is not executed then, and cleaner and its argument might leak * (depending on the implementation). * * [block] should not use `@ThreadLocal` globals, because it may * be executed on a different thread. * * If [block] throws an exception, the behavior is unspecified. * * Cleaners should not be kept in globals, because if cleaner is not deallocated * before exiting main(), it'll never get executed. * Use `Platform.isCleanersLeakCheckerActive` to warn about unexecuted cleaners. * * If cleaners are not GC'd before main() exits, then it's not guaranteed that * they will be run. Moreover, it depends on `Platform.isCleanersLeakCheckerActive`. * With the checker enabled, cleaners will be run (and therefore not reported as * unexecuted cleaners); with the checker disabled - they might not get run. * * @param argument must be shareable * @param block must not capture anything */ // TODO: Consider just annotating the lambda argument rather than hardcoding checking // by function name in the compiler. @ExperimentalStdlibApi @ExportForCompiler fun createCleaner(argument: T, block: (T) -> Unit): Cleaner { if (!argument.isShareable()) throw IllegalArgumentException("$argument must be shareable") val clean = { // TODO: Maybe if this fails with exception, it should be (optionally) reported. block(argument) }.freeze() // Make sure there's an extra reference to clean, so it's definitely alive when CleanerImpl is destroyed. val cleanPtr = createStablePointer(clean) // Make sure cleaner worker is initialized. getCleanerWorker() return CleanerImpl(cleanPtr).freeze() } /** * Perform GC on a worker that executes Cleaner blocks. */ @InternalForKotlinNative fun performGCOnCleanerWorker() = getCleanerWorker().execute(TransferMode.SAFE, {}) { GC.collect() }.result /** * Wait for a worker that executes Cleaner blocks to complete its scheduled tasks. */ @InternalForKotlinNative fun waitCleanerWorker() = getCleanerWorker().execute(TransferMode.SAFE, {}) { Unit }.result @SymbolName("Kotlin_CleanerImpl_getCleanerWorker") external private fun getCleanerWorker(): Worker @ExportForCppRuntime("Kotlin_CleanerImpl_shutdownCleanerWorker") private fun shutdownCleanerWorker(worker: Worker, executeScheduledCleaners: Boolean) { worker.requestTermination(executeScheduledCleaners).result } @ExportForCppRuntime("Kotlin_CleanerImpl_createCleanerWorker") private fun createCleanerWorker(): Worker { return Worker.start(errorReporting = false, name = "Cleaner worker") } @NoReorderFields @ExportTypeInfo("theCleanerImplTypeInfo") @HasFinalizer private class CleanerImpl( private val cleanPtr: NativePtr, ): Cleaner {} @SymbolName("Kotlin_Any_isShareable") external private fun Any?.isShareable(): Boolean @SymbolName("CreateStablePointer") external private fun createStablePointer(obj: Any): NativePtr ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Coroutines.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* @kotlin.internal.InlineOnly @PublishedApi internal inline suspend fun suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation) -> Any?): T = returnIfSuspended(block(getContinuation())) @TypedIntrinsic(IntrinsicType.GET_CONTINUATION) @PublishedApi internal external fun getContinuation(): Continuation @kotlin.internal.InlineOnly @PublishedApi internal inline suspend fun getCoroutineContext(): CoroutineContext = getContinuation().context @TypedIntrinsic(IntrinsicType.RETURN_IF_SUSPENDED) @PublishedApi internal external suspend fun returnIfSuspended(@Suppress("UNUSED_PARAMETER") argument: Any?): T @TypedIntrinsic(IntrinsicType.COROUTINE_LAUNCHPAD) internal external fun coroutineLaunchpad(suspendFunctionCall: Any?, continuation: Continuation<*>): Any? ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Debugging.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal /* * Internal utilities for debugging K/N compiler and runtime. */ public object Debugging { public var forceCheckedShutdown: Boolean get() = Debugging_getForceCheckedShutdown() set(value) = Debugging_setForceCheckedShutdown(value) } @SymbolName("Kotlin_Debugging_getForceCheckedShutdown") private external fun Debugging_getForceCheckedShutdown(): Boolean @SymbolName("Kotlin_Debugging_setForceCheckedShutdown") private external fun Debugging_setForceCheckedShutdown(value: Boolean): Unit ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/DefaultConstructorMarker.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal @ExportForCompiler internal object DefaultConstructorMarker; ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Enums.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal @TypedIntrinsic(IntrinsicType.ENUM_VALUES) @PublishedApi internal external fun > enumValuesIntrinsic(): Array @TypedIntrinsic(IntrinsicType.ENUM_VALUE_OF) @PublishedApi internal external fun > enumValueOfIntrinsic(name: String): T ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/FloatingPointParser.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.native.internal import kotlin.comparisons.* /** * Takes a String and an integer exponent. The String should hold a positive * integer value (or zero). The exponent will be used to calculate the * floating point number by taking the positive integer the String * represents and multiplying by 10 raised to the power of the * exponent. Returns the closest double value to the real number. * @param s the String that will be parsed to a floating point * @param e an int represent the 10 to part * @return the double closest to the real number * @exception NumberFormatException if the String doesn't represent a positive integer value */ @SymbolName("Kotlin_native_FloatingPointParser_parseDoubleImpl") private external fun parseDoubleImpl(s: String, e: Int): Double /** * Takes a String and an integer exponent. The String should hold a positive * integer value (or zero). The exponent will be used to calculate the * floating point number by taking the positive integer the String * represents and multiplying by 10 raised to the power of the * exponent. Returns the closest float value to the real number. * @param s the String that will be parsed to a floating point * @param e an int represent the 10 to part * @return the float closest to the real number * @exception NumberFormatException if the String doesn't represent a positive integer value */ @SymbolName("Kotlin_native_FloatingPointParser_parseFloatImpl") private external fun parseFloatImpl(s: String, e: Int): Float /** * Used to parse a string and return either a single or double precision * floating point number. */ object FloatingPointParser { /* * All number with exponent larger than MAX_EXP can be treated as infinity. * All number with exponent smaller than MIN_EXP can be treated as zero. * Exponent is 10 based. * Eg. double's min value is 5e-324, so double "1e-325" should be parsed as 0.0 */ private val FLOAT_MIN_EXP = -46 private val FLOAT_MAX_EXP = 38 private val DOUBLE_MIN_EXP = -324 private val DOUBLE_MAX_EXP = 308 private class StringExponentPair(var s: String, var e: Int, var negative: Boolean) /** * Takes a String and does some initial parsing. Should return a * StringExponentPair containing a String with no leading or trailing white * space and trailing zeroes eliminated. The exponent of the * StringExponentPair will be used to calculate the floating point number by * taking the positive integer the String represents and multiplying by 10 * raised to the power of the exponent. * @param string the String that will be parsed to a floating point * @return a StringExponentPair with necessary values * @exception NumberFormatException if the String doesn't pass basic tests */ private fun initialParse(string: String): StringExponentPair { var s = string var length = s.length var negative = false var c: Char var start: Int var end: Int val decimal: Int var shift: Int var e = 0 start = 0 if (length == 0) throw NumberFormatException(s) c = s[length - 1] if (c == 'D' || c == 'd' || c == 'F' || c == 'f') { length-- if (length == 0) throw NumberFormatException(s) } end = maxOf(s.indexOf('E'), s.indexOf('e')) if (end > -1) { if (end + 1 == length) throw NumberFormatException(s) var exponent_offset = end + 1 if (s[exponent_offset] == '+') { if (s[exponent_offset + 1] == '-') { throw NumberFormatException(s) } exponent_offset++ // skip the plus sign if (exponent_offset == length) throw NumberFormatException(s) } val strExp = s.substring(exponent_offset, length) try { e = strExp.toInt() } catch (ex: NumberFormatException) { // strExp is not empty, so there are 2 situations the exception be thrown // if the string is invalid we should throw exception, if the actual number // is out of the range of Integer, we can still parse the original number to // double or float. var ch: Char for (i in 0..strExp.length - 1) { ch = strExp[i] if (ch < '0' || ch > '9') { if (i == 0 && ch == '-') continue // ex contains the exponent substring only so throw // a new exception with the correct string. throw NumberFormatException(s) } } e = if (strExp[0] == '-') Int.MIN_VALUE else Int.MAX_VALUE } } else { end = length } if (length == 0) throw NumberFormatException(s) c = s[start] if (c == '-') { ++start --length negative = true } else if (c == '+') { ++start --length } if (length == 0) throw NumberFormatException(s) decimal = s.indexOf('.') if (decimal > -1) { shift = end - decimal - 1 // Prevent e overflow, shift >= 0. if (e >= 0 || e - Int.MIN_VALUE > shift) { e -= shift } s = s.substring(start, decimal) + s.substring(decimal + 1, end) } else { s = s.substring(start, end) } length = s.length if (length == 0) throw NumberFormatException() end = length while (end > 1 && s[end - 1] == '0') --end start = 0 while (start < end - 1 && s[start] == '0') start++ if (end != length || start != 0) { shift = length - end if (e <= 0 || Int.MAX_VALUE - e > shift) { e += shift } s = s.substring(start, end) } // Trim the length of very small numbers, natives can only handle down to E-309. val APPROX_MIN_MAGNITUDE = -359 val MAX_DIGITS = 52 length = s.length if (length > MAX_DIGITS && e < APPROX_MIN_MAGNITUDE) { val d = minOf(APPROX_MIN_MAGNITUDE - e, length - 1) s = s.substring(0, length - d) e += d } return StringExponentPair(s, e, negative) } /* * Assumes the string is trimmed. */ private fun parseDoubleName(namedDouble: String, length: Int): Double { // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity, -Infinity. if (length != 3 && length != 4 && length != 8 && length != 9) { throw NumberFormatException() } var negative = false var cmpstart = 0 when (namedDouble[0]) { '-' -> { negative = true cmpstart = 1 } '+' -> cmpstart = 1 } if (namedDouble.regionMatches(cmpstart, "Infinity", 0, 8, ignoreCase = false)) { return if (negative) Double.NEGATIVE_INFINITY else Double.POSITIVE_INFINITY } if (namedDouble.regionMatches(cmpstart, "NaN", 0, 3, ignoreCase = false)) { return Double.NaN } throw NumberFormatException() } /* * Assumes the string is trimmed. */ private fun parseFloatName(namedFloat: String, length: Int): Float { // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity, -Infinity. if (length != 3 && length != 4 && length != 8 && length != 9) { throw NumberFormatException() } var negative = false var cmpstart = 0 when (namedFloat[0]) { '-' -> { negative = true cmpstart = 1 } '+' -> cmpstart = 1 } if (namedFloat.regionMatches(cmpstart, "Infinity", 0, 8, ignoreCase = false)) { return if (negative) Float.NEGATIVE_INFINITY else Float.POSITIVE_INFINITY } if (namedFloat.regionMatches(cmpstart, "NaN", 0, 3, ignoreCase = false)) { return Float.NaN } throw NumberFormatException() } /* * Answers true if the string should be parsed as a hex encoding. * Assumes the string is trimmed. */ private fun parseAsHex(s: String): Boolean { val length = s.length if (length < 2) { return false } var first = s[0] var second = s[1] if (first == '+' || first == '-') { // Move along. if (length < 3) { return false } first = second second = s[2] } return first == '0' && (second == 'x' || second == 'X') } /** * Returns the closest double value to the real number in the string. * * @param string the String that will be parsed to a floating point * @return the double closest to the real number * @exception NumberFormatException if the String doesn't represent a double */ fun parseDouble(string: String): Double { var s = string s = s.trim { it <= ' ' } val length = s.length if (length == 0) { throw NumberFormatException(s) } // See if this could be a named double. val last = s[length - 1] if (last == 'y' || last == 'N') { return parseDoubleName(s, length) } // See if it could be a hexadecimal representation. if (parseAsHex(s)) { return HexStringParser.parseDouble(s) } val info = initialParse(s) // Two kinds of situation will directly return 0.0: // 1. info.s is 0; // 2. actual exponent is less than Double.MIN_EXPONENT. if ("0" == info.s || info.e + info.s.length - 1 < DOUBLE_MIN_EXP) { return if (info.negative) -0.0 else 0.0 } // If actual exponent is larger than Double.MAX_EXPONENT, return infinity. // Prevent overflow, check twice. if (info.e > DOUBLE_MAX_EXP || info.e + info.s.length - 1 > DOUBLE_MAX_EXP) { return if (info.negative) Double.NEGATIVE_INFINITY else Double.POSITIVE_INFINITY } var result = parseDoubleImpl(info.s, info.e) if (info.negative) result = -result return result } /** * Returns the closest float value to the real number in the string. * * @param s the String that will be parsed to a floating point * @return the float closest to the real number * @exception NumberFormatException if the String doesn't represent a float */ fun parseFloat(string: String): Float { var s = string s = s.trim { it <= ' ' } val length = s.length if (length == 0) { throw NumberFormatException(s) } // See if this could be a named float. val last = s[length - 1] if (last == 'y' || last == 'N') { return parseFloatName(s, length) } // See if it could be a hexadecimal representation. if (parseAsHex(s)) { return HexStringParser.parseFloat(s) } val info = initialParse(s) // Two kinds of situation will directly return 0.0f. // 1. info.s is 0; // 2. actual exponent is less than Float.MIN_EXPONENT. if ("0" == info.s || info.e + info.s.length - 1 < FLOAT_MIN_EXP) { return if (info.negative) -0.0f else 0.0f } // If actual exponent is larger than Float.MAX_EXPONENT, return infinity. // Prevent overflow, check twice. if (info.e > FLOAT_MAX_EXP || info.e + info.s.length - 1 > FLOAT_MAX_EXP) { return if (info.negative) Float.NEGATIVE_INFINITY else Float.POSITIVE_INFINITY } var result = parseFloatImpl(info.s, info.e) if (info.negative) result = -result return result } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/FunctionAdapter.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.Function internal interface FunctionAdapter { fun getFunctionDelegate(): Function<*> } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/GC.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal /** * ## Cycle garbage collector interface. * * Konan relies upon reference counting for object management, however it could * not collect cyclical garbage, so we perform periodic garbage collection. * This may slow down application, so this interface provides control over how * garbage collector activates and runs. * Garbage collector can be in one of the following states: * - running * - suspended (so cycle candidates are collected, but GC is not performed until resume) * - stopped (all cyclical garbage is hopelessly lost) * Immediately after startup GC is in running state. * Depending on application needs it may select to suspend GC for certain phases of * its lifetime, and resume it later on, or just completely turn it off, if GC pauses * are less desirable than cyclical garbage leaks. */ object GC { /** * To force garbage collection immediately, unless collector is stopped * with [stop] operation. Even if GC is suspended, [collect] still triggers collection. */ @SymbolName("Kotlin_native_internal_GC_collect") external fun collect() /** * Request global cyclic collector, operation is async and just triggers the collection. */ @SymbolName("Kotlin_native_internal_GC_collectCyclic") external fun collectCyclic() /** * Suspend garbage collection. Release candidates are still collected, but * GC algorithm is not executed. */ @SymbolName("Kotlin_native_internal_GC_suspend") external fun suspend() /** * Resume garbage collection. Can potentially lead to GC immediately. */ @SymbolName("Kotlin_native_internal_GC_resume") external fun resume() /** * Stop garbage collection. Cyclical garbage is no longer collected. */ @SymbolName("Kotlin_native_internal_GC_stop") external fun stop() /** * Start garbage collection. Cyclical garbage produced while GC was stopped * cannot be reclaimed, but all new garbage is collected. */ @SymbolName("Kotlin_native_internal_GC_start") external fun start() /** * GC threshold, controlling how frequenly GC is activated, and how much time GC * takes. Bigger values lead to longer GC pauses, but less GCs. */ var threshold: Int get() = getThreshold() set(value) = setThreshold(value) /** * GC allocation threshold, controlling how frequenly GC collect cycles, and how much time * this process takes. Bigger values lead to longer GC pauses, but less GCs. */ var collectCyclesThreshold: Long get() = getCollectCyclesThreshold() set(value) = setCollectCyclesThreshold(value) /** * GC allocation threshold, controlling how many bytes allocated since last * collection will trigger new GC. */ var thresholdAllocations: Long get() = getThresholdAllocations() set(value) = setThresholdAllocations(value) /** * If GC shall auto-tune thresholds, depending on how much time is spent in collection. */ var autotune: Boolean get() = getTuneThreshold() set(value) = setTuneThreshold(value) /** * If cyclic collector for atomic references to be deployed. */ var cyclicCollectorEnabled: Boolean get() = getCyclicCollectorEnabled() set(value) = setCyclicCollectorEnabled(value) /** * Detect cyclic references going via atomic references and return list of cycle-inducing objects * or `null` if the leak detector is not available. Use [Platform.isMemoryLeakCheckerActive] to check * leak detector availability. */ @SymbolName("Kotlin_native_internal_GC_detectCycles") external fun detectCycles(): Array? /** * Find a reference cycle including from the given object, `null` if no cycles detected. */ @SymbolName("Kotlin_native_internal_GC_findCycle") external fun findCycle(root: Any): Array? @SymbolName("Kotlin_native_internal_GC_getThreshold") private external fun getThreshold(): Int @SymbolName("Kotlin_native_internal_GC_setThreshold") private external fun setThreshold(value: Int) @SymbolName("Kotlin_native_internal_GC_getCollectCyclesThreshold") private external fun getCollectCyclesThreshold(): Long @SymbolName("Kotlin_native_internal_GC_setCollectCyclesThreshold") private external fun setCollectCyclesThreshold(value: Long) @SymbolName("Kotlin_native_internal_GC_getThresholdAllocations") private external fun getThresholdAllocations(): Long @SymbolName("Kotlin_native_internal_GC_setThresholdAllocations") private external fun setThresholdAllocations(value: Long) @SymbolName("Kotlin_native_internal_GC_getTuneThreshold") private external fun getTuneThreshold(): Boolean @SymbolName("Kotlin_native_internal_GC_setTuneThreshold") private external fun setTuneThreshold(value: Boolean) @SymbolName("Kotlin_native_internal_GC_getCyclicCollector") private external fun getCyclicCollectorEnabled(): Boolean @SymbolName("Kotlin_native_internal_GC_setCyclicCollector") private external fun setCyclicCollectorEnabled(value: Boolean) } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/HexStringParser.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.native.internal import kotlin.text.regex.* @SymbolName("Kotlin_native_int_bits_to_float") private external fun intBitsToFloat(x: Int): Float @SymbolName("Kotlin_native_long_bits_to_double") private external fun longBitsToDouble(x: Long): Double /* * Parses hex string to a single or double precision floating point number. */ internal class HexStringParser(private val EXPONENT_WIDTH: Int, private val MANTISSA_WIDTH: Int) { private val EXPONENT_BASE: Long private val MAX_EXPONENT: Long private val MIN_EXPONENT: Long private val MANTISSA_MASK: Long private var sign: Long = 0 private var exponent: Long = 0 private var mantissa: Long = 0 private var abandonedNumber = "" //$NON-NLS-1$ init { this.EXPONENT_BASE = (-1L shl (EXPONENT_WIDTH - 1)).inv() this.MAX_EXPONENT = (-1L shl EXPONENT_WIDTH).inv() this.MIN_EXPONENT = (-(MANTISSA_WIDTH + 1)).toLong() this.MANTISSA_MASK = (-1L shl MANTISSA_WIDTH).inv() } private fun parse(hexString: String): Long { val hexSegments = getSegmentsFromHexString(hexString) val signStr = hexSegments[0] val significantStr = hexSegments[1] val exponentStr = hexSegments[2] parseHexSign(signStr) parseExponent(exponentStr) parseMantissa(significantStr) sign = sign shl (MANTISSA_WIDTH + EXPONENT_WIDTH) exponent = exponent shl MANTISSA_WIDTH return sign or exponent or mantissa } /* * Parses the sign field. */ private fun parseHexSign(signStr: String) { this.sign = (if (signStr == "-") 1 else 0).toLong() //$NON-NLS-1$ } /* * Parses the exponent field. */ private fun parseExponent(exponentString: String) { var exponentStr = exponentString val leadingChar = exponentStr[0] val expSign = if (leadingChar == '-') -1 else 1 if (!leadingChar.isDigit()) { exponentStr = exponentStr.substring(1) } try { exponent = expSign * exponentStr.toLong() checkedAddExponent(EXPONENT_BASE) } catch (e: NumberFormatException) { exponent = expSign * Long.MAX_VALUE } } /* * Parses the mantissa field. */ private fun parseMantissa(significantStr: String) { val strings = significantStr.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() //$NON-NLS-1$ val strIntegerPart = strings[0] val strDecimalPart = if (strings.size > 1) strings[1] else "" //$NON-NLS-1$ var significand = getNormalizedSignificand(strIntegerPart, strDecimalPart) if (significand == "0") { //$NON-NLS-1$ setZero() return } val offset = getOffset(strIntegerPart, strDecimalPart) checkedAddExponent(offset.toLong()) if (exponent >= MAX_EXPONENT) { setInfinite() return } if (exponent <= MIN_EXPONENT) { setZero() return } if (significand.length > MAX_SIGNIFICANT_LENGTH) { abandonedNumber = significand.substring(MAX_SIGNIFICANT_LENGTH) significand = significand.substring(0, MAX_SIGNIFICANT_LENGTH) } mantissa = significand.toLong(HEX_RADIX) if (exponent >= 1) { processNormalNumber() } else { processSubNormalNumber() } } private fun setInfinite() { exponent = MAX_EXPONENT mantissa = 0 } private fun setZero() { exponent = 0 mantissa = 0 } private fun signum(x: Long) = when { x == 0L -> 0 x > 0L -> 1 else -> -1 } /* * Sets the exponent variable to Long.MAX_VALUE or -Long.MAX_VALUE if * overflow or underflow happens. */ private fun checkedAddExponent(offset: Long) { val result = exponent + offset val expSign = signum(exponent) if (expSign * signum(offset) > 0 && expSign * signum(result) < 0) { exponent = expSign * Long.MAX_VALUE } else { exponent = result } } private fun processNormalNumber() { val desiredWidth = MANTISSA_WIDTH + 2 fitMantissaInDesiredWidth(desiredWidth) round() mantissa = mantissa and MANTISSA_MASK } private fun processSubNormalNumber() { var desiredWidth = MANTISSA_WIDTH + 1 desiredWidth += exponent.toInt()//lends bit from mantissa to exponent exponent = 0 fitMantissaInDesiredWidth(desiredWidth) round() mantissa = mantissa and MANTISSA_MASK } /* * Adjusts the mantissa to desired width for further analysis. */ private fun fitMantissaInDesiredWidth(desiredWidth: Int) { val bitLength = countBitsLength(mantissa) if (bitLength > desiredWidth) { discardTrailingBits((bitLength - desiredWidth).toLong()) } else { mantissa = mantissa shl (desiredWidth - bitLength) } } /* * Stores the discarded bits to abandonedNumber. */ private fun discardTrailingBits(num: Long) { val mask = (-1L shl num.toInt()).inv() abandonedNumber += mantissa and mask mantissa = mantissa shr num.toInt() } /* * The value is rounded up or down to the nearest infinitely precise result. * If the value is exactly halfway between two infinitely precise results, * then it should be rounded up to the nearest infinitely precise even. */ private fun round() { val result = abandonedNumber.replace("0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$ val moreThanZero = result.length > 0 val lastDiscardedBit = (mantissa and 1L).toInt() mantissa = mantissa shr 1 val tailBitInMantissa = (mantissa and 1L).toInt() if (lastDiscardedBit == 1 && (moreThanZero || tailBitInMantissa == 1)) { val oldLength = countBitsLength(mantissa) mantissa += 1L val newLength = countBitsLength(mantissa) //Rounds up to exponent when whole bits of mantissa are one-bits. if (oldLength >= MANTISSA_WIDTH && newLength > oldLength) { checkedAddExponent(1) } } } /* * Returns the normalized significand after removing the leading zeros. */ private fun getNormalizedSignificand(strIntegerPart: String, strDecimalPart: String): String { var significand = strIntegerPart + strDecimalPart significand = significand.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$//$NON-NLS-2$ if (significand.length == 0) { significand = "0" //$NON-NLS-1$ } return significand } /* * Calculates the offset between the normalized number and unnormalized * number. In a normalized representation, significand is represented by the * characters "0x1." followed by a lowercase hexadecimal representation of * the rest of the significand as a fraction. */ private fun getOffset(strIntegerPartParam: String, strDecimalPart: String): Int { var strIntegerPart = strIntegerPartParam strIntegerPart = strIntegerPart.replaceFirst("^0+".toRegex(), "") //$NON-NLS-1$ //$NON-NLS-2$ // If the Integer part is a nonzero number. if (strIntegerPart.length != 0) { val leadingNumber = strIntegerPart.substring(0, 1) return (strIntegerPart.length - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1 } // If the Integer part is a zero number. var i = 0 while (i < strDecimalPart.length && strDecimalPart[i] == '0') { i++ } if (i == strDecimalPart.length) { return 0 } val leadingNumber = strDecimalPart.substring(i, i + 1) return (-i - 1) * 4 + countBitsLength(leadingNumber.toLong(HEX_RADIX)) - 1 } fun numberOfLeadingZeros(i: Long): Int { // HD, Figure 5-6 if (i == 0L) return 64 var n = 1 var x = (i ushr 32).toInt() if (x == 0) { n += 32 x = i.toInt() } if (x ushr 16 == 0) { n += 16 x = x shl 16 } if (x ushr 24 == 0) { n += 8 x = x shl 8 } if (x ushr 28 == 0) { n += 4 x = x shl 4 } if (x ushr 30 == 0) { n += 2 x = x shl 2 } n -= x ushr 31 return n } private fun countBitsLength(value: Long) = 64 - numberOfLeadingZeros(value) companion object { private val DOUBLE_EXPONENT_WIDTH = 11 private val DOUBLE_MANTISSA_WIDTH = 52 private val FLOAT_EXPONENT_WIDTH = 8 private val FLOAT_MANTISSA_WIDTH = 23 private val HEX_RADIX = 16 private val MAX_SIGNIFICANT_LENGTH = 15 private val HEX_SIGNIFICANT = "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)" //$NON-NLS-1$ private val BINARY_EXPONENT = "[pP]([+-]?\\d+)" //$NON-NLS-1$ private val FLOAT_TYPE_SUFFIX = "[fFdD]?" //$NON-NLS-1$ private val HEX_PATTERN = "[\\x00-\\x20]*([+-]?)$HEX_SIGNIFICANT" + //$NON-NLS-1$ BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*" //$NON-NLS-1$ private val PATTERN = Regex(HEX_PATTERN) /* * Parses the hex string to a double number. */ fun parseDouble(hexString: String): Double { val parser = HexStringParser(DOUBLE_EXPONENT_WIDTH, DOUBLE_MANTISSA_WIDTH) val result = parser.parse(hexString) return longBitsToDouble(result) } /* * Parses the hex string to a float number. */ fun parseFloat(hexString: String): Float { val parser = HexStringParser(FLOAT_EXPONENT_WIDTH, FLOAT_MANTISSA_WIDTH) val result = parser.parse(hexString).toInt() return intBitsToFloat(result) } /* * Analyzes the hex string and extracts the sign and digit segments. */ private fun getSegmentsFromHexString(hexString: String): Array { val matchResult = PATTERN.matchEntire(hexString) if (matchResult == null) { throw NumberFormatException() } val hexSegments = arrayOf( matchResult.groupValues[1], matchResult.groupValues[2], matchResult.groupValues[3] ) return hexSegments } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/InteropBoxing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlinx.cinterop.* @Frozen class NativePtrBox(val value: NativePtr) { override fun equals(other: Any?): Boolean { if (other !is NativePtrBox) { return false } return this.value == other.value } override fun hashCode() = value.hashCode() override fun toString() = value.toString() } fun boxNativePtr(value: NativePtr) = NativePtrBox(value) @Frozen class NativePointedBox(val value: NativePointed) { override fun equals(other: Any?): Boolean { if (other !is NativePointedBox) { return false } return this.value == other.value } // TODO: can't delegate the following methods to `this.value` // because `NativePointed` doesn't provide them. override fun hashCode() = this.value.rawPtr.hashCode() override fun toString() = "NativePointed(raw=${this.value.rawPtr})" } fun boxNativePointed(value: NativePointed?) = if (value != null) NativePointedBox(value) else null fun unboxNativePointed(box: NativePointedBox?) = box?.value @Frozen class CPointerBox(val value: CPointer) : CValuesRef() { override fun equals(other: Any?): Boolean { if (other !is CPointerBox) { return false } return this.value == other.value } override fun hashCode() = value.hashCode() override fun toString() = value.toString() override fun getPointer(scope: AutofreeScope) = value.getPointer(scope) } fun boxCPointer(value: CPointer?) = if (value != null) CPointerBox(value) else null fun unboxCPointer(box: CPointerBox?) = box?.value ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/IntrinsicType.kt ================================================ package kotlin.native.internal class IntrinsicType { companion object { // Arithmetic const val PLUS = "PLUS" const val MINUS = "MINUS" const val TIMES = "TIMES" const val SIGNED_DIV = "SIGNED_DIV" const val SIGNED_REM = "SIGNED_REM" const val UNSIGNED_DIV = "UNSIGNED_DIV" const val UNSIGNED_REM = "UNSIGNED_REM" const val INC = "INC" const val DEC = "DEC" const val UNARY_PLUS = "UNARY_PLUS" const val UNARY_MINUS = "UNARY_MINUS" const val SHL = "SHL" const val SHR = "SHR" const val USHR = "USHR" const val AND = "AND" const val OR = "OR" const val XOR = "XOR" const val INV = "INV" const val SIGN_EXTEND = "SIGN_EXTEND" const val ZERO_EXTEND = "ZERO_EXTEND" const val INT_TRUNCATE = "INT_TRUNCATE" const val FLOAT_TRUNCATE = "FLOAT_TRUNCATE" const val FLOAT_EXTEND = "FLOAT_EXTEND" const val SIGNED_TO_FLOAT = "SIGNED_TO_FLOAT" const val UNSIGNED_TO_FLOAT = "UNSIGNED_TO_FLOAT" const val FLOAT_TO_SIGNED = "FLOAT_TO_SIGNED" const val SIGNED_COMPARE_TO = "SIGNED_COMPARE_TO" const val UNSIGNED_COMPARE_TO = "UNSIGNED_COMPARE_TO" const val NOT = "NOT" const val REINTERPRET = "REINTERPRET" const val EXTRACT_ELEMENT = "EXTRACT_ELEMENT" const val ARE_EQUAL_BY_VALUE = "ARE_EQUAL_BY_VALUE" const val IEEE_754_EQUALS = "IEEE_754_EQUALS" // ObjC related stuff const val OBJC_GET_MESSENGER = "OBJC_GET_MESSENGER" const val OBJC_GET_MESSENGER_STRET = "OBJC_GET_MESSENGER_STRET" const val OBJC_GET_OBJC_CLASS = "OBJC_GET_OBJC_CLASS" const val OBJC_CREATE_SUPER_STRUCT = "OBJC_CREATE_SUPER_STRUCT" const val OBJC_INIT_BY = "OBJC_INIT_BY" const val OBJC_GET_SELECTOR = "OBJC_GET_SELECTOR" // Other const val GET_CLASS_TYPE_INFO = "GET_CLASS_TYPE_INFO" const val INTEROP_READ_BITS = "INTEROP_READ_BITS" const val INTEROP_WRITE_BITS = "INTEROP_WRITE_BITS" const val CREATE_UNINITIALIZED_INSTANCE = "CREATE_UNINITIALIZED_INSTANCE" const val LIST_OF_INTERNAL = "LIST_OF_INTERNAL" const val IDENTITY = "IDENTITY" const val IMMUTABLE_BLOB = "IMMUTABLE_BLOB" const val INIT_INSTANCE = "INIT_INSTANCE" // Enums const val ENUM_VALUES = "ENUM_VALUES" const val ENUM_VALUE_OF = "ENUM_VALUE_OF" // Coroutines const val GET_CONTINUATION = "GET_CONTINUATION" const val RETURN_IF_SUSPENDED = "RETURN_IF_SUSPENDED" const val COROUTINE_LAUNCHPAD = "COROUTINE_LAUNCHPAD" // Interop const val INTEROP_READ_PRIMITIVE = "INTEROP_READ_PRIMITIVE" const val INTEROP_WRITE_PRIMITIVE = "INTEROP_WRITE_PRIMITIVE" const val INTEROP_GET_POINTER_SIZE = "INTEROP_GET_POINTER_SIZE" const val INTEROP_NATIVE_PTR_TO_LONG = "INTEROP_NATIVE_PTR_TO_LONG" const val INTEROP_NATIVE_PTR_PLUS_LONG = "INTEROP_NATIVE_PTR_PLUS_LONG" const val INTEROP_GET_NATIVE_NULL_PTR = "INTEROP_GET_NATIVE_NULL_PTR" const val INTEROP_CONVERT = "INTEROP_CONVERT" const val INTEROP_BITS_TO_FLOAT = "INTEROP_BITS_TO_FLOAT" const val INTEROP_BITS_TO_DOUBLE = "INTEROP_BITS_TO_DOUBLE" const val INTEROP_SIGN_EXTEND = "INTEROP_SIGN_EXTEND" const val INTEROP_NARROW = "INTEROP_NARROW" const val INTEROP_STATIC_C_FUNCTION = "INTEROP_STATIC_C_FUNCTION" const val INTEROP_FUNPTR_INVOKE = "INTEROP_FUNPTR_INVOKE" // Worker const val WORKER_EXECUTE = "WORKER_EXECUTE" } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Intrinsics.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlinx.cinterop.CPointer import kotlinx.cinterop.NativePointed import kotlinx.cinterop.NativePtr import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Boolean, second: Boolean): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Byte, second: Byte): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Short, second: Short): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Int, second: Int): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Long, second: Long): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: NativePtr, second: NativePtr): Boolean // Bitwise equality: @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Float, second: Float): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Double, second: Double): Boolean @TypedIntrinsic(IntrinsicType.ARE_EQUAL_BY_VALUE) @PublishedApi external internal fun areEqualByValue(first: Vector128, second: Vector128): Boolean // IEEE754 equality: @TypedIntrinsic(IntrinsicType.IEEE_754_EQUALS) @PublishedApi external internal fun ieee754Equals(first: Float, second: Float): Boolean @TypedIntrinsic(IntrinsicType.IEEE_754_EQUALS) @PublishedApi external internal fun ieee754Equals(first: Double, second: Double): Boolean // Reinterprets this value from T to R having the same binary representation (e.g. to unwrap inline class). @TypedIntrinsic(IntrinsicType.IDENTITY) @PublishedApi external internal fun T.reinterpret(): R ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KClassImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.KClass @ExportForCompiler internal class KClassImpl(private val typeInfo: NativePtr) : KClass { override val simpleName: String? get() { val relativeName = getRelativeName(typeInfo) ?: return null return relativeName.substringAfterLast(".") } override val qualifiedName: String? get() { val packageName = getPackageName(typeInfo) ?: return null val relativeName = getRelativeName(typeInfo)!! return if (packageName.isEmpty()) { relativeName } else { "$packageName.$relativeName" } } override fun isInstance(value: Any?): Boolean = value != null && isInstance(value, this.typeInfo) override fun equals(other: Any?): Boolean = other is KClassImpl<*> && this.typeInfo == other.typeInfo override fun hashCode(): Int = typeInfo.hashCode() override fun toString(): String { return "class " + (qualifiedName ?: simpleName ?: "") } internal fun findAssociatedObjectImpl(key: KClassImpl<*>): Any? = findAssociatedObjectImpl(this.typeInfo, key.typeInfo) } @PublishedApi internal fun KClass<*>.findAssociatedObject(key: KClass<*>): Any? = if (this is KClassImpl<*> && key is KClassImpl<*>) { this.findAssociatedObjectImpl(key) } else { null } @PublishedApi internal class KClassUnsupportedImpl(private val message: String) : KClass { override val simpleName: String? get() = error(message) override val qualifiedName: String? get() = error(message) override fun isInstance(value: Any?): Boolean = error(message) override fun equals(other: Any?): Boolean = error(message) override fun hashCode(): Int = error(message) override fun toString(): String = "unreflected class ($message)" } @SymbolName("Kotlin_TypeInfo_findAssociatedObject") private external fun findAssociatedObjectImpl(typeInfo: NativePtr, key: NativePtr): Any? @ExportForCompiler @SymbolName("Kotlin_Any_getTypeInfo") internal external fun getObjectTypeInfo(obj: Any): NativePtr @ExportForCompiler @TypedIntrinsic(IntrinsicType.GET_CLASS_TYPE_INFO) internal external inline fun getClassTypeInfo(): NativePtr @SymbolName("Kotlin_TypeInfo_getPackageName") private external fun getPackageName(typeInfo: NativePtr): String? @SymbolName("Kotlin_TypeInfo_getRelativeName") private external fun getRelativeName(typeInfo: NativePtr): String? @SymbolName("Kotlin_TypeInfo_isInstance") private external fun isInstance(obj: Any, typeInfo: NativePtr): Boolean ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KFunctionImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.KFunction import kotlin.reflect.KType @FixmeReflection internal abstract class KFunctionImpl( override val name: String, val fqName: String, val receiver: Any?, val arity: Int, val flags: Int, override val returnType: KType ): KFunction { override fun equals(other: Any?): Boolean { if (other !is KFunctionImpl<*>) return false return fqName == other.fqName && receiver == other.receiver && arity == other.arity && flags == other.flags } private fun evalutePolynom(x: Int, vararg coeffs: Int): Int { var res = 0 for (coeff in coeffs) res = res * x + coeff return res } override fun hashCode() = evalutePolynom(31, fqName.hashCode(), receiver.hashCode(), arity, flags) override fun toString(): String { return "${if (name == "") "constructor" else "function " + name}" } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KPropertyImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.UnsupportedOperationException import kotlin.reflect.* @FixmeReflection open class KProperty0Impl(override val name: String, override val returnType: KType, val getter: () -> R): KProperty0 { override fun get(): R { return getter() } override fun invoke(): R { return getter() } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KProperty0Impl<*> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter } override fun hashCode(): Int { return name.hashCode() * 31 + getter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } @FixmeReflection open class KProperty1Impl(override val name: String, override val returnType: KType, val getter: (T) -> R): KProperty1 { override fun get(receiver: T): R { return getter(receiver) } override fun invoke(p1: T): R { return getter(p1) } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KProperty1Impl<*, *> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter } override fun hashCode(): Int { return name.hashCode() * 31 + getter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } @FixmeReflection open class KProperty2Impl(override val name: String, override val returnType: KType, val getter: (T1, T2) -> R): KProperty2 { override fun get(receiver1: T1, receiver2: T2): R { return getter(receiver1, receiver2) } override fun invoke(p1: T1, p2: T2): R { return getter(p1, p2) } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KProperty2Impl<*, *, *> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter } override fun hashCode(): Int { return name.hashCode() * 31 + getter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } @FixmeReflection class KMutableProperty0Impl(name: String, returnType: KType, getter: () -> R, val setter: (R) -> Unit) : KProperty0Impl(name, returnType, getter), KMutableProperty0 { override fun set(value: R): Unit { setter(value) } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KMutableProperty0Impl<*> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter && setter == otherKProperty.setter } override fun hashCode(): Int { return (name.hashCode() * 31 + getter.hashCode()) * 31 + setter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } @FixmeReflection class KMutableProperty1Impl(name: String, returnType: KType, getter: (T) -> R, val setter: (T, R) -> Unit) : KProperty1Impl(name, returnType, getter), KMutableProperty1 { override fun set(receiver: T, value: R): Unit { setter(receiver, value) } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KMutableProperty1Impl<*, *> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter && setter == otherKProperty.setter } override fun hashCode(): Int { return (name.hashCode() * 31 + getter.hashCode()) * 31 + setter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } @FixmeReflection class KMutableProperty2Impl(name: String, returnType: KType, getter: (T1, T2) -> R, val setter: (T1, T2, R) -> Unit) : KProperty2Impl(name, returnType, getter), KMutableProperty2 { override fun set(receiver1: T1, receiver2: T2, value: R): Unit { setter(receiver1, receiver2, value) } override fun equals(other: Any?): Boolean { val otherKProperty = other as? KMutableProperty2Impl<* ,*, *> if (otherKProperty == null) return false return name == otherKProperty.name && getter == otherKProperty.getter && setter == otherKProperty.setter } override fun hashCode(): Int { return (name.hashCode() * 31 + getter.hashCode()) * 31 + setter.hashCode() } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } open class KLocalDelegatedPropertyImpl(override val name: String, override val returnType: KType): KProperty0 { override fun get(): R { throw UnsupportedOperationException("Not supported for local property reference.") } override fun invoke(): R { throw UnsupportedOperationException("Not supported for local property reference.") } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } class KLocalDelegatedMutablePropertyImpl(name: String, returnType: KType): KLocalDelegatedPropertyImpl(name, returnType), KMutableProperty0 { override fun set(value: R): Unit { throw UnsupportedOperationException("Not supported for local property reference.") } override fun toString(): String { return "property $name (Kotlin reflection is not available)" } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KSuspendFunctionImpl.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.KType import kotlin.reflect.KFunction import kotlin.reflect.KClass @FixmeReflection internal abstract class KSuspendFunctionImpl( name: String, fqName: String, receiver: Any?, arity: Int, flags: Int, returnType: KType ): KFunctionImpl(name, fqName, receiver, arity, flags, returnType) { override fun toString() = "suspend function $name" } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KTypeImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.* internal class KTypeImpl( override val classifier: KClassifier?, override val arguments: List, override val isMarkedNullable: Boolean ) : KType { override fun equals(other: Any?) = other is KTypeImpl && this.classifier == other.classifier && this.arguments == other.arguments && this.isMarkedNullable == other.isMarkedNullable override fun hashCode(): Int { return (classifier?.hashCode() ?: 0) * 31 * 31 + this.arguments.hashCode() * 31 + if (isMarkedNullable) 1 else 0 } override fun toString(): String { val classifierString = when (classifier) { is KClass<*> -> classifier.qualifiedName ?: classifier.simpleName is KTypeParameter -> classifier.name else -> null } ?: return "(non-denotable type)" return buildString { append(classifierString) if (arguments.isNotEmpty()) { append('<') arguments.forEachIndexed { index, argument -> if (index > 0) append(", ") append(argument) } append('>') } if (isMarkedNullable) append('?') } } } internal class KTypeImplForTypeParametersWithRecursiveBounds : KType { override val classifier: KClassifier? get() = error("Type parameters with recursive bounds are not yet supported in reflection") override val arguments: List get() = emptyList() override val isMarkedNullable: Boolean get() = error("Type parameters with recursive bounds are not yet supported in reflection") override fun equals(other: Any?) = error("Type parameters with recursive bounds are not yet supported in reflection") override fun hashCode(): Int = error("Type parameters with recursive bounds are not yet supported in reflection") } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KTypeParameterImpl.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.* internal class KTypeParameterImpl( override val name: String, private val containerFqName: String, override val upperBounds: List, override val variance: KVariance, override val isReified: Boolean ) : KTypeParameter { override fun toString(): String = when (variance) { KVariance.INVARIANT -> "" KVariance.IN -> "in " KVariance.OUT -> "out " } + name override fun equals(other: Any?) = other is KTypeParameterImpl && name == other.name && containerFqName == other.containerFqName override fun hashCode() = containerFqName.hashCode() * 31 + name.hashCode() } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KonanCollections.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal internal interface KonanSet : Set { /** * Searches for the specified element in this set. * * @return the element from the set equal to [element], or `null` if no such element found. */ fun getElement(element: @UnsafeVariance E): E? } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/KonanRuntimeTypes.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal internal class FunctionReference ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/NativePtr.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:Suppress("RESERVED_MEMBER_INSIDE_INLINE_CLASS") package kotlin.native.internal @TypedIntrinsic(IntrinsicType.INTEROP_GET_NATIVE_NULL_PTR) external fun getNativeNullPtr(): NativePtr class NativePtr @PublishedApi internal constructor(private val value: NonNullNativePtr?) { companion object { // TODO: make it properly precreated, maybe use an intrinsic for that. val NULL = getNativeNullPtr() } @TypedIntrinsic(IntrinsicType.INTEROP_NATIVE_PTR_PLUS_LONG) external operator fun plus(offset: Long): NativePtr @TypedIntrinsic(IntrinsicType.INTEROP_NATIVE_PTR_TO_LONG) external fun toLong(): Long override fun equals(other: Any?) = (other is NativePtr) && kotlin.native.internal.areEqualByValue(this, other) override fun hashCode() = this.toLong().hashCode() override fun toString() = "0x${this.toLong().toString(16)}" internal fun isNull(): Boolean = (value == null) } @PublishedApi internal class NonNullNativePtr private constructor() { // TODO: refactor to use this type widely. @Suppress("NOTHING_TO_INLINE") inline fun toNativePtr() = NativePtr(this) override fun toString() = toNativePtr().toString() override fun hashCode() = toNativePtr().hashCode() override fun equals(other: Any?) = other is NonNullNativePtr && kotlin.native.internal.areEqualByValue(this.toNativePtr(), other.toNativePtr()) } @ExportTypeInfo("theNativePtrArrayTypeInfo") internal class NativePtrArray { @SymbolName("Kotlin_NativePtrArray_get") external public operator fun get(index: Int): NativePtr @SymbolName("Kotlin_NativePtrArray_set") external public operator fun set(index: Int, value: NativePtr): Unit val size: Int get() = getArrayLength() @SymbolName("Kotlin_NativePtrArray_getArrayLength") external private fun getArrayLength(): Int } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/NumberConverter.kt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.native.internal @SymbolName("Kotlin_native_NumberConverter_bigIntDigitGeneratorInstImpl") private external fun bigIntDigitGeneratorInstImpl(results: IntArray, uArray: IntArray, f: Long, e: Int, isDenormalized: Boolean, mantissaIsZero: Boolean, p: Int) @SymbolName("Kotlin_native_NumberConverter_ceil") private external fun ceil(x: Double): Double /** * Converts [Float] or [Double] numbers to the [String] representation */ class NumberConverter { private var setCount: Int = 0 // Number of times u and k have been gotten. private var getCount: Int = 0 // Number of times u and k have been set. private val uArray = IntArray(64) private var firstK: Int = 0 private fun convertDouble(inputNumber: Double): String { val p = 1023 + 52 // The power offset (precision). @Suppress("INTEGER_OVERFLOW") val signMask = 0x7FFFFFFFFFFFFFFFL + 1 // The mask to get the sign of. // The number. val eMask = 0x7FF0000000000000L // The mask to get the power bits. val fMask = 0x000FFFFFFFFFFFFFL // The mask to get the significand. // Bits. val inputNumberBits = inputNumber.bits() // The value of the sign... 0 is positive, ~0 is negative. val signString = if (inputNumberBits and signMask == 0L) "" else "-" // The value of the 'power bits' of the inputNumber. val e = (inputNumberBits and eMask shr 52).toInt() // The value of the 'significand bits' of the inputNumber. var f = inputNumberBits and fMask val mantissaIsZero = f == 0L var pow: Int var numBits = 52 if (e == 2047) return if (mantissaIsZero) signString + "Infinity" else "NaN" if (e == 0) { if (mantissaIsZero) return signString + "0.0" if (f == 1L) // Special case to increase precision even though 2 * Double.MIN_VALUE is 1.0e-323. return signString + "4.9E-324" pow = 1 - p // A denormalized number. var ff = f while (ff and 0x0010000000000000L == 0L) { ff = ff shl 1 numBits-- } } else { // 0 < e < 2047. // A "normalized" number. f = f or 0x0010000000000000L pow = e - p } if (-59 < pow && pow < 6 || pow == -59 && !mantissaIsZero) longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits) else bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero, numBits) if (inputNumber >= 1e7 || inputNumber <= -1e7 || inputNumber > -1e-3 && inputNumber < 1e-3) return signString + freeFormatExponential() return signString + freeFormat() } private fun convertFloat(inputNumber: Float): String { val p = 127 + 23 // The power offset (precision). @Suppress("INTEGER_OVERFLOW") val signMask = 0x7FFFFFFF + 1 // The mask to get the sign of the number. val eMask = 0x7F800000 // The mask to get the power bits. val fMask = 0x007FFFFF // The mask to get the significand bits. val inputNumberBits = inputNumber.bits() // The value of the sign... 0 is positive, ~0 is negative. val signString = if (inputNumberBits and signMask == 0) "" else "-" // The value of the 'power bits' of the inputNumber. val e = inputNumberBits and eMask shr 23 // The value of the 'significand bits' of the inputNumber. var f = inputNumberBits and fMask val mantissaIsZero = f == 0 var pow: Int var numBits = 23 if (e == 255) return if (mantissaIsZero) signString + "Infinity" else "NaN" if (e == 0) { if (mantissaIsZero) return signString + "0.0" pow = 1 - p // A denormalized number. if (f < 8) { // Want more precision with smallest values. f = f shl 2 pow -= 2 } var ff = f while (ff and 0x00800000 == 0) { ff = ff shl 1 numBits-- } } else { // 0 < e < 255. // A "normalized" number. f = f or 0x00800000 pow = e - p } if (-59 < pow && pow < 35 || pow == -59 && !mantissaIsZero) longDigitGenerator(f.toLong(), pow, e == 0, mantissaIsZero, numBits) else bigIntDigitGeneratorInstImpl(f.toLong(), pow, e == 0, mantissaIsZero, numBits) if (inputNumber >= 1e7f || inputNumber <= -1e7f || inputNumber > -1e-3f && inputNumber < 1e-3f) return signString + freeFormatExponential() return signString + freeFormat() } private fun freeFormatExponential(): String { // Corresponds to process "Free-Format Exponential". val formattedDecimal = CharArray(25) formattedDecimal[0] = ('0' + uArray[getCount++]) formattedDecimal[1] = '.' // The position the next character is to be inserted into formattedDecimal. var charPos = 2 var k = firstK val expt = k while (true) { k-- if (getCount >= setCount) break formattedDecimal[charPos++] = ('0' + uArray[getCount++]) } if (k == expt - 1) formattedDecimal[charPos++] = '0' formattedDecimal[charPos++] = 'E' return unsafeStringFromCharArray(formattedDecimal, 0, charPos) + expt.toString() } private fun freeFormat(): String { // Corresponds to process "Free-Format". val formattedDecimal = CharArray(25) // The position the next character is to be inserted into formattedDecimal. var charPos = 0 var k = firstK if (k < 0) { formattedDecimal[0] = '0' formattedDecimal[1] = '.' charPos += 2 for (i in k + 1 .. -1) formattedDecimal[charPos++] = '0' } var u = uArray[getCount++] do { if (u != -1) formattedDecimal[charPos++] = ('0' + u) else if (k >= -1) formattedDecimal[charPos++] = '0' if (k == 0) formattedDecimal[charPos++] = '.' k-- u = if (getCount < setCount) uArray[getCount++] else -1 } while (u != -1 || k >= -1) return unsafeStringFromCharArray(formattedDecimal, 0, charPos) } private fun bigIntDigitGeneratorInstImpl(f: Long, e: Int, isDenormalized: Boolean, mantissaIsZero: Boolean, p: Int) { val results = IntArray(3) bigIntDigitGeneratorInstImpl(results, uArray, f, e, isDenormalized, mantissaIsZero, p) setCount = results[0] getCount = results[1] firstK = results[2] } private fun longDigitGenerator(f: Long, e: Int, isDenormalized: Boolean, mantissaIsZero: Boolean, p: Int) { var r: Long var s: Long var m: Long if (e >= 0) { m = 1L shl e if (!mantissaIsZero) { r = f shl e + 1 s = 2 } else { r = f shl e + 2 s = 4 } } else { m = 1 if (isDenormalized || !mantissaIsZero) { r = f shl 1 s = 1L shl 1 - e } else { r = f shl 2 s = 1L shl 2 - e } } val k = ceil((e + p - 1) * invLogOfTenBaseTwo - 1e-10).toInt() if (k > 0) { s *= TEN_TO_THE[k] } else if (k < 0) { val scale = TEN_TO_THE[-k] r *= scale m = if (m == 1L) scale else m * scale } if (r + m > s) { // Was M_plus. firstK = k } else { firstK = k - 1 r *= 10 m *= 10 } setCount = 0 getCount = setCount // Reset indices. var low: Boolean var high: Boolean var u: Int val si = longArrayOf(s, s shl 1, s shl 2, s shl 3) while (true) { // Set U to be floor (r / s) and r to be the remainder // using a kind of "binary search" to find the answer. // It's a lot quicker than actually dividing since we know // the answer will be between 0 and 10. u = 0 var remainder: Long for (i in 3 downTo 0) { remainder = r - si[i] if (remainder >= 0) { r = remainder u += 1 shl i } } low = r < m // Was M_minus. high = r + m > s // Was M_plus. if (low || high) break r *= 10 m *= 10 uArray[setCount++] = u } if (low && !high) uArray[setCount++] = u else if (high && !low) uArray[setCount++] = u + 1 else if (r shl 1 < s) uArray[setCount++] = u else uArray[setCount++] = u + 1 } companion object { private val invLogOfTenBaseTwo = 0.30102999566398114251 private val TEN_TO_THE = LongArray(20) init { TEN_TO_THE[0] = 1L for (i in 1 until TEN_TO_THE.size) { TEN_TO_THE[i] = TEN_TO_THE[i - 1] * 10 } } private val converter: NumberConverter get() = NumberConverter() fun convert(input: Double): String { return converter.convertDouble(input) } fun convert(input: Float): String { return converter.convertFloat(input) } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/ObjCExportCoroutines.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* import kotlin.coroutines.native.internal.* import kotlin.native.concurrent.* @ExportForCppRuntime private fun Kotlin_ObjCExport_createContinuationArgumentImpl( completionHolder: Any, exceptionTypes: NativePtr ): Continuation = createContinuationArgumentFromCallback(EmptyCompletion) { result -> result.fold( onSuccess = { value -> runCompletionSuccess(completionHolder, value) }, onFailure = { exception -> runCompletionFailure(completionHolder, exception, exceptionTypes) } ) } private object EmptyCompletion : Continuation { override val context: CoroutineContext get() = EmptyCoroutineContext override fun resumeWith(result: Result) { val exception = result.exceptionOrNull() ?: return TerminateWithUnhandledException(exception) // Throwing the exception from [resumeWith] is not generally expected. // Also terminating is consistent with other pieces of ObjCExport machinery. } } @PublishedApi @ExportForCppRuntime("Kotlin_ObjCExport_resumeContinuationSuccess") // Also makes it a data flow root. internal fun resumeContinuation(continuation: Continuation, value: Any?) { continuation.resume(value) } @PublishedApi @ExportForCppRuntime("Kotlin_ObjCExport_resumeContinuationFailure") // Also makes it a data flow root. internal fun resumeContinuationWithException(continuation: Continuation, exception: Throwable) { continuation.resumeWithException(exception) } @PublishedApi @ExportForCompiler // Mark as data flow root. internal fun getCoroutineSuspended(): Any = COROUTINE_SUSPENDED @PublishedApi @ExportForCompiler // Mark as data flow root. internal fun interceptedContinuation(continuation: Continuation): Continuation = continuation.intercepted() @FilterExceptions @SymbolName("Kotlin_ObjCExport_runCompletionSuccess") private external fun runCompletionSuccess(completionHolder: Any, result: Any?) @FilterExceptions @SymbolName("Kotlin_ObjCExport_runCompletionFailure") private external fun runCompletionFailure(completionHolder: Any, exception: Throwable, exceptionTypes: NativePtr) ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/ObjCExportUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.KonanSet import kotlin.native.internal.ReportUnhandledException /** * This interface denotes the object to be a wrapper for the Objective-C object, * so the latter should be used to observe object lifetime. */ @ExportTypeInfo("theObjCObjectWrapperTypeInfo") internal interface ObjCObjectWrapper internal class NSArrayAsKList : AbstractList(), ObjCObjectWrapper { override val size: Int get() = getSize() @SymbolName("Kotlin_NSArrayAsKList_getSize") private external fun getSize(): Int @SymbolName("Kotlin_NSArrayAsKList_get") external override fun get(index: Int): Any? } internal class NSMutableArrayAsKMutableList : AbstractMutableList(), ObjCObjectWrapper { override val size: Int get() = getSize() @SymbolName("Kotlin_NSArrayAsKList_getSize") private external fun getSize(): Int @SymbolName("Kotlin_NSArrayAsKList_get") external override fun get(index: Int): Any? @SymbolName("Kotlin_NSMutableArrayAsKMutableList_add") external override fun add(index: Int, element: Any?): Unit @SymbolName("Kotlin_NSMutableArrayAsKMutableList_removeAt") external override fun removeAt(index: Int): Any? @SymbolName("Kotlin_NSMutableArrayAsKMutableList_set") external override fun set(index: Int, element: Any?): Any? } internal class NSSetAsKSet : AbstractSet(), KonanSet, ObjCObjectWrapper { override val size: Int get() = getSize() @SymbolName("Kotlin_NSSetAsKSet_getSize") private external fun getSize(): Int @SymbolName("Kotlin_NSSetAsKSet_contains") external override fun contains(element: Any?): Boolean @SymbolName("Kotlin_NSSetAsKSet_getElement") external override fun getElement(element: Any?): Any? @SymbolName("Kotlin_NSSetAsKSet_iterator") external override fun iterator(): Iterator } internal class NSDictionaryAsKMap : Map, ObjCObjectWrapper { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Map<*, *>) return false if (this.size != other.size) return false return other.entries.all { this.containsEntry(it.key, it.value) } } override fun hashCode(): Int { var result = 0 keyIterator().forEach { key -> result += key.hashCode() xor this.getOrThrowConcurrentModification(key).hashCode() } return result } override fun toString(): String = entries.joinToString(", ", "{", "}") { toString(it.key) + "=" + toString(it.value) } private fun toString(o: Any?): String = if (o === this) "(this Map)" else o.toString() override val size: Int get() = getSize() @SymbolName("Kotlin_NSDictionaryAsKMap_getSize") private external fun getSize(): Int override fun isEmpty(): Boolean = (size == 0) @SymbolName("Kotlin_NSDictionaryAsKMap_containsKey") override external fun containsKey(key: Any?): Boolean @SymbolName("Kotlin_NSDictionaryAsKMap_containsValue") override external fun containsValue(value: Any?): Boolean @SymbolName("Kotlin_NSDictionaryAsKMap_get") external override operator fun get(key: Any?): Any? @SymbolName("Kotlin_NSDictionaryAsKMap_getOrThrowConcurrentModification") private external fun getOrThrowConcurrentModification(key: Any?): Any? @SymbolName("Kotlin_NSDictionaryAsKMap_containsEntry") private external fun containsEntry(key: Any?, value: Any?): Boolean // Views override val keys: Set get() = this.Keys() override val values: Collection get() = this.Values() override val entries: Set> get() = this.Entries() @SymbolName("Kotlin_NSDictionaryAsKMap_keyIterator") private external fun keyIterator(): Iterator private inner class Keys : AbstractSet() { override val size: Int get() = this@NSDictionaryAsKMap.size override fun iterator(): Iterator = this@NSDictionaryAsKMap.keyIterator() override fun contains(element: Any?): Boolean = this@NSDictionaryAsKMap.containsKey(element) } @SymbolName("Kotlin_NSDictionaryAsKMap_valueIterator") private external fun valueIterator(): Iterator private inner class Values : AbstractCollection() { // TODO: what about equals and hashCode? override val size: Int get() = this@NSDictionaryAsKMap.size override fun iterator(): Iterator = this@NSDictionaryAsKMap.valueIterator() override fun contains(element: Any?): Boolean = this@NSDictionaryAsKMap.containsValue(element) } private inner class Entries : AbstractSet>() { override val size: Int get() = this@NSDictionaryAsKMap.size override fun iterator(): Iterator> = this@NSDictionaryAsKMap.EntryIterator() override fun contains(element: Map.Entry): Boolean { return this@NSDictionaryAsKMap.containsEntry(element.key, element.value) } } private class Entry(override val key: Any?, override val value: Any?) : Map.Entry { override fun equals(other: Any?): Boolean = other is Map.Entry<*, *> && other.key == key && other.value == value override fun hashCode(): Int = key.hashCode() xor value.hashCode() override fun toString(): String = "$key=$value" } private inner class EntryIterator : Iterator> { val keyIterator = this@NSDictionaryAsKMap.keyIterator() override fun hasNext(): Boolean = keyIterator.hasNext() override fun next(): Map.Entry { val nextKey = keyIterator.next() val nextValue = this@NSDictionaryAsKMap.getOrThrowConcurrentModification(nextKey) return Entry(nextKey, nextValue) } } } internal class NSEnumeratorAsKIterator : AbstractIterator() { @SymbolName("Kotlin_NSEnumeratorAsKIterator_computeNext") override external fun computeNext() @ExportForCppRuntime private fun Kotlin_NSEnumeratorAsKIterator_done() = this.done() @ExportForCppRuntime private fun Kotlin_NSEnumeratorAsKIterator_setNext(value: Any?) = this.setNext(value) } @ExportForCppRuntime private fun Kotlin_Collection_getSize(collection: Collection<*>): Int = collection.size @ExportForCppRuntime private fun Kotlin_List_get(list: List<*>, index: Int): Any? = list.get(index) @ExportForCppRuntime private fun Kotlin_MutableList_addObjectAtIndex(list: MutableList, index: Int, obj: Any?) { list.add(index, obj) } @ExportForCppRuntime private fun Kotlin_MutableList_removeObjectAtIndex(list: MutableList, index: Int) { list.removeAt(index) } @ExportForCppRuntime private fun Kotlin_MutableCollection_addObject(list: MutableCollection, obj: Any?) { list.add(obj) } @ExportForCppRuntime private fun Kotlin_MutableList_removeLastObject(list: MutableList) { list.removeAt(list.lastIndex) } @ExportForCppRuntime private fun Kotlin_MutableList_setObject(list: MutableList, index: Int, obj: Any?) { list.set(index, obj) } @ExportForCppRuntime private fun Kotlin_MutableCollection_removeObject( collection: MutableCollection, element: Any? ) { collection.remove(element) } @ExportForCppRuntime private fun Kotlin_Iterator_hasNext(iterator: Iterator): Boolean = iterator.hasNext() @ExportForCppRuntime private fun Kotlin_Iterator_next(iterator: Iterator): Any? = iterator.next() @ExportForCppRuntime private fun Kotlin_Set_contains(set: Set, element: Any?): Boolean = set.contains(element) @ExportForCppRuntime private fun Kotlin_Set_getElement(set: Set, element: Any?): Any? = if (set is KonanSet) { set.getElement(element) } else if (set.contains(element)) { set.first { it == element } } else { null } @ExportForCppRuntime private fun Kotlin_Set_iterator(set: Set): Iterator = set.iterator() @ExportForCppRuntime private fun Kotlin_MutableSet_createWithCapacity(capacity: Int): MutableSet = HashSet(capacity) @ExportForCppRuntime private fun Kotlin_Map_getSize(map: Map): Int = map.size @ExportForCppRuntime private fun Kotlin_Map_containsKey(map: Map, key: Any?): Boolean = map.containsKey(key) @ExportForCppRuntime private fun Kotlin_Map_get(map: Map, key: Any?): Any? = map.get(key) @ExportForCppRuntime private fun Kotlin_Map_keyIterator(map: Map): Iterator = map.keys.iterator() @ExportForCppRuntime private fun Kotlin_MutableMap_createWithCapacity(capacity: Int): MutableMap = HashMap(capacity) @ExportForCppRuntime private fun Kotlin_MutableMap_set(map: MutableMap, key: Any?, value: Any?) { map.set(key, value) } @ExportForCppRuntime private fun Kotlin_MutableMap_remove(map: MutableMap, key: Any?) { map.remove(key) } @ExportForCppRuntime private fun Kotlin_ObjCExport_ThrowCollectionTooLarge() { throw Error("an Objective-C collection is too large") } @ExportForCppRuntime private fun Kotlin_ObjCExport_ThrowCollectionConcurrentModification() { throw Error("an Objective-C collection was modified while iterating") } @ExportForCppRuntime private fun Kotlin_NSArrayAsKList_create() = NSArrayAsKList() @ExportForCppRuntime private fun Kotlin_NSMutableArrayAsKMutableList_create() = NSMutableArrayAsKMutableList() @ExportForCppRuntime private fun Kotlin_NSEnumeratorAsKIterator_create() = NSEnumeratorAsKIterator() @ExportForCppRuntime private fun Kotlin_NSSetAsKSet_create() = NSSetAsKSet() @ExportForCppRuntime private fun Kotlin_NSDictionaryAsKMap_create() = NSDictionaryAsKMap() @ExportForCppRuntime private fun Kotlin_ObjCExport_NSErrorAsExceptionImpl( message: String?, error: Any ) = ObjCErrorException(message, error) class ObjCErrorException( message: String?, internal val error: Any ) : Exception(message) { override fun toString(): String = "NSError-based exception: $message" } @PublishedApi @SymbolName("Kotlin_ObjCExport_trapOnUndeclaredException") @ExportForCppRuntime internal external fun trapOnUndeclaredException(exception: Throwable) @ExportForCppRuntime private fun Kotlin_Throwable_getMessage(throwable: Throwable): String? = throwable.message @ExportForCppRuntime private fun Kotlin_ObjCExport_getWrappedError(throwable: Throwable): Any? = (throwable as? ObjCErrorException)?.error @ExportTypeInfo("theOpaqueFunctionTypeInfo") @PublishedApi internal class OpaqueFunction : Function ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Ref.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal /** * This class is used to allocate closure-captured variables in the heap. */ class Ref { var element: T = undefined() } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.internal.getProgressionLastElement import kotlin.reflect.KClass import kotlin.native.concurrent.AtomicReference @ExportForCppRuntime fun ThrowNullPointerException(): Nothing { throw NullPointerException() } @ExportForCppRuntime internal fun ThrowIndexOutOfBoundsException(): Nothing { throw IndexOutOfBoundsException() } @ExportForCppRuntime internal fun ThrowArrayIndexOutOfBoundsException(): Nothing { throw ArrayIndexOutOfBoundsException() } @ExportForCppRuntime fun ThrowClassCastException(instance: Any, typeInfo: NativePtr): Nothing { val clazz = KClassImpl(typeInfo) throw ClassCastException("${instance::class.qualifiedName} cannot be cast to ${clazz.qualifiedName}") } @ExportForCppRuntime fun ThrowTypeCastException(): Nothing { throw TypeCastException() } @ExportForCppRuntime fun ThrowKotlinNothingValueException(): Nothing { throw KotlinNothingValueException() } @ExportForCppRuntime fun ThrowInvalidReceiverTypeException(klass: KClass<*>): Nothing { throw RuntimeException("Unexpected receiver type: " + (klass.qualifiedName ?: "noname")) } @ExportForCppRuntime internal fun ThrowArithmeticException() : Nothing { throw ArithmeticException() } @ExportForCppRuntime internal fun ThrowNumberFormatException() : Nothing { throw NumberFormatException() } @ExportForCppRuntime internal fun ThrowOutOfMemoryError() : Nothing { throw OutOfMemoryError() } fun ThrowNoWhenBranchMatchedException(): Nothing { throw NoWhenBranchMatchedException() } fun ThrowUninitializedPropertyAccessException(propertyName: String): Nothing { throw UninitializedPropertyAccessException("lateinit property $propertyName has not been initialized") } @ExportForCppRuntime internal fun ThrowIllegalArgumentException() : Nothing { throw IllegalArgumentException() } @ExportForCppRuntime internal fun ThrowIllegalArgumentExceptionWithMessage(message: String) : Nothing { throw IllegalArgumentException(message) } @ExportForCppRuntime internal fun ThrowIllegalStateException() : Nothing { throw IllegalStateException() } @ExportForCppRuntime internal fun ThrowIllegalStateExceptionWithMessage(message:String) : Nothing { throw IllegalStateException(message) } @ExportForCppRuntime internal fun ThrowNotImplementedError(): Nothing { throw NotImplementedError("An operation is not implemented.") } @ExportForCppRuntime internal fun ThrowCharacterCodingException(): Nothing { throw CharacterCodingException() } @ExportForCppRuntime internal fun ThrowIncorrectDereferenceException() { throw IncorrectDereferenceException( "Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread") } @ExportForCppRuntime internal fun PrintThrowable(throwable: Throwable) { println(throwable) } @ExportForCppRuntime internal fun ReportUnhandledException(throwable: Throwable) { print("Uncaught Kotlin exception: ") throwable.printStackTrace() } @SymbolName("TerminateWithUnhandledException") internal external fun TerminateWithUnhandledException(throwable: Throwable) // Using object to make sure that `hook` is initialized when it's needed instead of // in a normal global initialization flow. This is important if some global happens // to throw an exception during it's initialization before this hook would've been initialized. internal object UnhandledExceptionHookHolder { internal val hook: AtomicReference = AtomicReference(null) } @PublishedApi @ExportForCppRuntime internal fun OnUnhandledException(throwable: Throwable) { val handler = UnhandledExceptionHookHolder.hook.swap(null) if (handler == null) { ReportUnhandledException(throwable); return } try { handler(throwable) } catch (t: Throwable) { ReportUnhandledException(t) } } @ExportForCppRuntime internal fun TheEmptyString() = "" public fun > valueOfForEnum(name: String, values: Array) : T { var left = 0 var right = values.size - 1 while (left <= right) { val middle = (left + right) / 2 val x = values[middle].name.compareTo(name) when { x < 0 -> left = middle + 1 x > 0 -> right = middle - 1 else -> return values[middle] } } throw Exception("Invalid enum value name: $name") } public fun > valuesForEnum(values: Array): Array { val result = @Suppress("TYPE_PARAMETER_AS_REIFIED") Array(values.size) for (value in values) result[value.ordinal] = value @Suppress("UNCHECKED_CAST") return result as Array } @PublishedApi @TypedIntrinsic(IntrinsicType.CREATE_UNINITIALIZED_INSTANCE) internal external fun createUninitializedInstance(): T @PublishedApi @TypedIntrinsic(IntrinsicType.INIT_INSTANCE) internal external fun initInstance(thiz: Any, constructorCall: Any): Unit @PublishedApi internal fun checkProgressionStep(step: Int) = if (step > 0) step else throw IllegalArgumentException("Step must be positive, was: $step.") @PublishedApi internal fun checkProgressionStep(step: Long) = if (step > 0) step else throw IllegalArgumentException("Step must be positive, was: $step.") @PublishedApi internal fun getProgressionLast(start: Char, end: Char, step: Int): Char = getProgressionLast(start.toInt(), end.toInt(), step).toChar() @PublishedApi internal fun getProgressionLast(start: Int, end: Int, step: Int): Int = getProgressionLastElement(start, end, step) @PublishedApi internal fun getProgressionLast(start: Long, end: Long, step: Long): Long = getProgressionLastElement(start, end, step) @PublishedApi // Called by the debugger. @ExportForCppRuntime internal fun KonanObjectToUtf8Array(value: Any?): ByteArray { val string = try { when (value) { is Array<*> -> value.contentToString() is CharArray -> value.contentToString() is BooleanArray -> value.contentToString() is ByteArray -> value.contentToString() is ShortArray -> value.contentToString() is IntArray -> value.contentToString() is LongArray -> value.contentToString() is FloatArray -> value.contentToString() is DoubleArray -> value.contentToString() else -> value.toString() } } catch (error: Throwable) { "" } return string.encodeToByteArray() } @TypedIntrinsic(IntrinsicType.LIST_OF_INTERNAL) @PublishedApi internal fun listOfInternal(vararg elements: T): List { val result = ArrayList(elements.size) for (i in 0 until elements.size) result.add(elements[i]) return result } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Undefined.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal /** * Returns undefined value of type `T`. * This method is unsafe and should be used with care. */ @SymbolName("Kotlin_native_internal_undefined") internal external fun undefined(): T ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/Utils.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal import kotlin.reflect.KClass @ExportForCppRuntime internal fun DescribeObjectForDebugging(typeInfo: NativePtr, address: NativePtr): String { val kClass = kotlin.native.internal.KClassImpl(typeInfo) return debugDescription(kClass, address.toLong().toInt()) } internal fun debugDescription(kClass: KClass<*>, identity: Int): String { val className = kClass.qualifiedName ?: kClass.simpleName ?: "" val unsignedIdentity = identity.toLong() and 0xffffffffL val identityStr = unsignedIdentity.toString(16) return "$className@$identityStr" } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/GTestLogger.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test internal class GTestLogger : TestLoggerWithStatistics() { private val Collection.totalTestsNotIgnored: Int get() = asSequence().filter { !it.ignored }.sumBy { it.testCases.values.count { !it.ignored } } private val Collection.totalNotIgnored: Int get() = filter { !it.ignored }.size override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection) { if (runner.iterations != 1) { println("\nRepeating all tests (iteration $iteration) . . .\n") } super.startIteration(runner, iteration, suites) println("[==========] Running ${suites.totalTestsNotIgnored} tests from ${suites.totalNotIgnored} test cases.") // Just hack to deal with GTest output parsers. println("[----------] Global test environment set-up.") } private fun printResults(timeMillis: Long) = with (statistics) { println("[----------] Global test environment tear-down") // Just hack to deal with GTest output parsers. println("[==========] $total tests from $totalSuites test cases ran. ($timeMillis ms total)") println("[ PASSED ] $passed tests.") if (hasFailedTests) { println("[ FAILED ] $failed tests, listed below:") failedTests.forEach { println("[ FAILED ] ${it.prettyName}") } println("\n$failed FAILED TESTS") } if (ignored != 0) { println("YOU HAVE $ignored DISABLED TEST(S)") } } override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) = printResults(timeMillis) override fun startSuite(suite: TestSuite) = println("[----------] ${suite.size} tests from ${suite.name}") override fun finishSuite(suite: TestSuite, timeMillis: Long) { super.finishSuite(suite, timeMillis) println("[----------] ${suite.size} tests from ${suite.name} ($timeMillis ms total)\n") } override fun start(testCase: TestCase) = println("[ RUN ] ${testCase.prettyName}") override fun pass(testCase: TestCase, timeMillis: Long) { super.pass(testCase, timeMillis) println("[ OK ] ${testCase.prettyName} ($timeMillis ms)") } override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) { super.fail(testCase, e, timeMillis) e.printStackTrace() println("[ FAILED ] ${testCase.prettyName} ($timeMillis ms)") } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test import kotlin.system.exitProcess import kotlin.native.concurrent.* @ThreadLocal private object GeneratedSuites { val suites = mutableListOf() fun add(suite: TestSuite) = suites.add(suite) } public fun registerSuite(suite: TestSuite): Unit { GeneratedSuites.add(suite) } fun testLauncherEntryPoint(args: Array): Int { return TestRunner(GeneratedSuites.suites, args).run() } fun main(args: Array) { val exitCode = testLauncherEntryPoint(args) if (exitCode != 0) { exitProcess(exitCode) } } fun worker(args: Array) { val worker = Worker.start() val exitCode = worker.execute(TransferMode.SAFE, { args.freeze() }) { it -> testLauncherEntryPoint(it) }.result worker.requestTermination().result if (exitCode != 0) { exitProcess(exitCode) } } fun mainNoExit(args: Array) { testLauncherEntryPoint(args) } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TeamCityLogger.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test import kotlin.text.StringBuilder internal class TeamCityLogger : BaseTestLogger() { private fun String.escapeForTC(): String = StringBuilder(length).apply { for(char in this@escapeForTC) { append(when(char) { '|' -> "||" '\'' -> "|'" '\n' -> "|n" '\r' -> "|r" '[' -> "|[" ']' -> "|]" else -> char }) } }.toString() private val TestCase.tcName get() = name.escapeForTC() private val TestSuite.tcName get() = name.escapeForTC() private fun finish(testCase: TestCase, durationMs: Long) = report("testFinished name='${testCase.tcName}' duration='$durationMs'") private fun report(msg: String) = println("##teamcity[$msg]") override fun start(testCase: TestCase) = report("testStarted" + " name='${testCase.tcName}'" + " locationHint='ktest:test://${testCase.suite.tcName}.${testCase.tcName}'") override fun startSuite(suite: TestSuite) = report("testSuiteStarted" + " name='${suite.tcName}'" + " locationHint='ktest:suite://${suite.tcName}'") override fun ignoreSuite(suite: TestSuite) { startSuite(suite) suite.testCases.values.forEach { ignore(it) } finishSuite(suite, 0L) } override fun finishSuite(suite: TestSuite, timeMillis: Long) = report("testSuiteFinished name='${suite.tcName}'") override fun pass(testCase: TestCase, timeMillis: Long) = finish(testCase, timeMillis) override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) { val stackTrace = e.dumpStackTrace().escapeForTC() val message = e.message?.escapeForTC() report("testFailed name='${testCase.tcName}' message='$message' details='$stackTrace'") finish(testCase, timeMillis) } override fun ignore(testCase: TestCase) = report("testIgnored name='${testCase.tcName}'") } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TestListener.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test internal interface TestListener { fun startTesting(runner: TestRunner) fun finishTesting(runner: TestRunner, timeMillis: Long) fun startIteration(runner: TestRunner, iteration: Int, suites: Collection) fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) fun startSuite(suite: TestSuite) fun finishSuite(suite: TestSuite, timeMillis: Long) fun ignoreSuite(suite: TestSuite) fun start(testCase: TestCase) fun pass(testCase: TestCase, timeMillis: Long) fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) fun ignore(testCase: TestCase) } internal open class BaseTestListener: TestListener { override fun startTesting(runner: TestRunner) {} override fun finishTesting(runner: TestRunner, timeMillis: Long) {} override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection) {} override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) {} override fun startSuite(suite: TestSuite) {} override fun finishSuite(suite: TestSuite, timeMillis: Long) {} override fun ignoreSuite(suite: TestSuite) {} override fun start(testCase: TestCase) {} override fun pass(testCase: TestCase, timeMillis: Long) {} override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) {} override fun ignore(testCase: TestCase) {} } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TestLogger.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test internal interface TestLogger: TestListener { fun logTestList(runner: TestRunner, suites: Collection) fun log(message: String) } internal open class BaseTestLogger: BaseTestListener(), TestLogger { override fun log(message: String) = println(message) override fun logTestList(runner: TestRunner, suites: Collection) { suites.forEach { suite -> println("${suite.name}.") suite.testCases.values.forEach { println(" ${it.name}") } } } } internal open class TestLoggerWithStatistics: BaseTestLogger() { protected val statistics = MutableTestStatistics() override fun startTesting(runner: TestRunner) = statistics.reset() override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection) = statistics.reset() override fun finishSuite(suite: TestSuite, timeMillis: Long) = statistics.registerSuite() override fun ignoreSuite(suite: TestSuite) = statistics.registerIgnore(suite.size) override fun pass(testCase: TestCase, timeMillis: Long) = statistics.registerPass() override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) = statistics.registerFail(testCase) override fun ignore(testCase: TestCase) = statistics.registerIgnore() } internal class SilentTestLogger: BaseTestLogger() { override fun logTestList(runner: TestRunner, suites: Collection) {} override fun log(message: String) {} override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) = e.printStackTrace() } internal class SimpleTestLogger: BaseTestLogger() { override fun startTesting(runner: TestRunner) = println("Starting testing") override fun finishTesting(runner: TestRunner, timeMillis: Long) = println("Testing finished") override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection) = println("Starting iteration: $iteration") override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) = println("Iteration finished: $iteration") override fun startSuite(suite: TestSuite) = println("Starting test suite: $suite") override fun finishSuite(suite: TestSuite, timeMillis: Long) = println("Test suite finished: $suite") override fun ignoreSuite(suite: TestSuite) = println("Test suite ignored: $suite") override fun start(testCase: TestCase) = println("Starting test case: $testCase") override fun pass(testCase: TestCase, timeMillis: Long) = println("Passed: $testCase") override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) { println("Failed: $testCase. Exception:") e.printStackTrace() } override fun ignore(testCase: TestCase) = println("Ignore: $testCase") } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test import kotlin.IllegalArgumentException import kotlin.system.getTimeMillis import kotlin.system.measureTimeMillis import kotlin.text.StringBuilder internal class TestRunner(val suites: List, args: Array) { private val filters = mutableListOf<(TestCase) -> Boolean>() private val listeners = mutableSetOf() private var logger: TestLogger = GTestLogger() private var runTests = true private var useExitCode = true var iterations = 1 private set var exitCode = 0 private set init { args.filter { it.startsWith("--gtest_") || it.startsWith("--ktest_") || it == "--help" || it == "-h" }.forEach { val arg = it.split('=') when (arg.size) { 1 -> when (arg[0]) { "--gtest_list_tests", "--ktest_list_tests" -> { logger.logTestList(this, filterSuites()); runTests = false } "-h", "--help" -> { logger.log(help); runTests = false } "--ktest_no_exit_code" -> useExitCode = false else -> throw IllegalArgumentException("Unknown option: $it\n$help") } 2 -> { val key = arg[0] val value = arg[1] when (key) { "--ktest_logger" -> setLoggerFromArg(value) "--gtest_filter", "--ktest_filter" -> setGTestFilterFromArg(value) "--ktest_regex_filter" -> setRegexFilterFromArg(value, true) "--ktest_negative_regex_filter" -> setRegexFilterFromArg(value, false) "--ktest_gradle_filter" -> setGradleFilterFromArg(value, true) "--ktest_negative_gradle_filter" -> setGradleFilterFromArg(value, false) "--ktest_repeat", "--gtest_repeat" -> iterations = value.toIntOrNull() ?: throw IllegalArgumentException("Cannot parse number: $value") else -> throw IllegalArgumentException("Unknown option: $it\n$help") } } else -> throw IllegalArgumentException("Unknown option: $it\n$help") } } } inner class FilteredSuite(val innerSuite: TestSuite) : TestSuite by innerSuite { private val TestCase.matchFilters: Boolean get() = filters.all { it(this) } override val size: Int get() = testCases.size override val testCases: Map = innerSuite.testCases.filter { it.value.matchFilters } override fun toString() = innerSuite.toString() } private fun filterSuites(): Collection = suites.map { FilteredSuite(it) } // TODO: Support short aliases. // TODO: Support several test iterations. /** * Initialize the TestRunner using the command line options passed in [args]. * Returns: true if tests may be ran, false otherwise (there are unrecognized options or just help). * The following options are available: * * --gtest_list_tests * --ktest_list_tests - Show all available tests. * * --gtest_filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS] * --ktest_filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS] - Run only the tests whose name matches one of the * positive patterns but none of the negative patterns. * '?' matches any single character; '*' matches any * substring; ':' separates two patterns. * * --ktest_regex_filter=PATTERN - Run only the tests whose name matches the pattern. * The pattern is a Kotlin regular expression. * * --ktest_negative_regex_filter=PATTERN - Run only the tests whose name doesn't match the pattern. * The pattern is a Kotlin regular expression. * * --gtest_repeat=COUNT * --ktest_repeat=COUNT - Run the tests repeatedly. * Use a negative count to repeat forever. * * --ktest_logger=GTEST|TEAMCITY|SIMPLE|SILENT - Use the specified output format. The default one is GTEST. * * --ktest_no_exit_code - Don't return a non-zero exit code if there are failing tests. */ private fun String.substringEscaped(range: IntRange) = this.substring(range).let { if (it.isNotEmpty()) Regex.escape(it) else "" } private fun String.toGTestPatterns() = splitToSequence(':').map { pattern -> val result = StringBuilder() var prevIndex = 0 pattern.forEachIndexed { index, c -> if (c == '*' || c == '?') { result.append(pattern.substringEscaped(prevIndex until index)) prevIndex = index + 1 result.append(if (c == '*') ".*" else ".") } } result.append(pattern.substringEscaped(prevIndex until pattern.length)) return@map result.toString().toRegex() }.toList() private fun setGTestFilterFromArg(filter: String) { if (filter.isEmpty()) { throw IllegalArgumentException("Empty filter") } val filters = filter.split('-') if (filters.size > 2) { throw IllegalArgumentException("Wrong pattern syntax: $filter.") } val positivePatterns = filters[0].toGTestPatterns() val negativePatterns = filters.getOrNull(1)?.toGTestPatterns() ?: emptyList() this.filters.add { testCase -> positivePatterns.any { testCase.prettyName.matches(it) } && negativePatterns.none { testCase.prettyName.matches(it) } } } private fun setRegexFilterFromArg(filter: String, positive: Boolean = true) { if (filter.isEmpty()) { throw IllegalArgumentException("Empty filter") } val pattern = filter.toRegex() filters.add { testCase -> testCase.prettyName.matches(pattern) == positive } } private fun setGradleFilterFromArg(filter: String, positive: Boolean = true) { if (filter.isEmpty()) { throw IllegalArgumentException("Empty filter") } val patterns = filter.split(',').map { pattern -> pattern.split('*').joinToString(separator = ".*") { Regex.escape(it) }.toRegex() } fun TestCase.matches(pattern: Regex) = prettyName.matches(pattern) || suite.name.matches(pattern) if (positive) { filters.add { testCase -> patterns.any { testCase.matches(it) } } } else { filters.add { testCase -> patterns.none { testCase.matches(it) } } } } private fun setLoggerFromArg(logger: String) { when (logger.toUpperCase()) { "GTEST" -> this.logger = GTestLogger() "TEAMCITY" -> this.logger = TeamCityLogger() "SIMPLE" -> this.logger = SimpleTestLogger() "SILENT" -> this.logger = SilentTestLogger() else -> throw IllegalArgumentException("Unknown logger type. Available types: GTEST, TEAMCITY, SIMPLE") } } private val help: String get() = """ |Available options: |--gtest_list_tests |--ktest_list_tests - Show all available tests. | |--gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS] |--ktest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS] - Run only the tests whose name matches one of the | positive patterns but none of the negative patterns. | '?' matches any single character; '*' matches any | substring; ':' separates two patterns. | |--ktest_regex_filter=PATTERN - Run only the tests whose name matches the pattern. | The pattern is a Kotlin regular expression. | |--ktest_negative_regex_filter=PATTERN - Run only the tests whose name doesn't match the pattern. | The pattern is a Kotlin regular expression. | |--ktest_gradle_filter=PATTERNS - Run only the tests which matches the at least one of the patterns. | '*' matches any number of characters, ',' separates patterns. | A test matches a pattern if: | - its name matches the pattern or | - its class name matches the pattern. | |--ktest_negative_gradle_filter=PATTERNS - Don't run tests if they match at least one of the patterns. | The pattern is the same as for the ktest_gradle_filter option. | |--gtest_repeat=COUNT |--ktest_repeat=COUNT - Run the tests repeatedly. | Use a negative count to repeat forever. | |--ktest_logger=GTEST|TEAMCITY|SIMPLE|SILENT - Use the specified output format. The default one is GTEST. | |--ktest_no_exit_code - Don't return a non-zero exit code if there are failing tests. """.trimMargin() private inline fun sendToListeners(event: TestListener.() -> Unit) { logger.event() listeners.forEach(event) } private fun TestSuite.run() { // Do not run @BeforeClass/@AfterClass hooks if all test cases are ignored. if (testCases.values.all { it.ignored }) { testCases.values.forEach { testCase -> sendToListeners { ignore(testCase) } } return } // Normal path: run all hooks and execute test cases. doBeforeClass() testCases.values.forEach { testCase -> if (testCase.ignored) { sendToListeners { ignore(testCase) } } else { val startTime = getTimeMillis() try { sendToListeners { start(testCase) } testCase.run() sendToListeners { pass(testCase, getTimeMillis() - startTime) } } catch (e: Throwable) { sendToListeners { fail(testCase, e, getTimeMillis() - startTime) } if (useExitCode) { exitCode = 1 } } } } doAfterClass() } private fun runIteration(iteration: Int) { val suitesFiltered = filterSuites() sendToListeners { startIteration(this@TestRunner, iteration, suitesFiltered) } val iterationTime = measureTimeMillis { suitesFiltered.forEach { if (it.ignored) { sendToListeners { ignoreSuite(it) } } else { // Do not run filtered out suites. if (it.size == 0) { return@forEach } sendToListeners { startSuite(it) } val time = measureTimeMillis { it.run() } sendToListeners { finishSuite(it, time) } } } } sendToListeners { finishIteration(this@TestRunner, iteration, iterationTime) } } fun run(): Int { if (!runTests) return 0 sendToListeners { startTesting(this@TestRunner) } val totalTime = measureTimeMillis { var i = 1 while (i <= iterations || iterations < 0) { runIteration(i) i++ } } sendToListeners { finishTesting(this@TestRunner, totalTime) } return exitCode } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TestStatistics.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test internal interface TestStatistics { val total: Int val passed: Int val failed: Int val ignored: Int val totalSuites: Int val failedTests: Collection val hasFailedTests: Boolean } internal class MutableTestStatistics: TestStatistics { override var total: Int = 0; private set override var passed: Int = 0; private set override var ignored: Int = 0; private set override var totalSuites: Int = 0; private set override val failed: Int get() = _failedTests.size override val hasFailedTests: Boolean get() = _failedTests.isNotEmpty() private val _failedTests = mutableListOf() override val failedTests: Collection get() = _failedTests fun registerSuite(count: Int = 1) { require(count >= 0) totalSuites += count } fun registerPass(count: Int = 1) { require(count >= 0) total += count passed += count } fun registerFail(testCases: Collection) { total += testCases.size _failedTests.addAll(testCases) } fun registerFail(testCase: TestCase) = registerFail(listOf(testCase)) fun registerIgnore(count: Int = 1) { require(count >= 0) total += count ignored += count } fun reset() { total = 0 passed = 0 ignored = 0 totalSuites = 0 _failedTests.clear() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.internal.test import kotlin.IllegalArgumentException import kotlin.system.getTimeMillis import kotlin.system.measureTimeMillis public interface TestCase { val name: String val ignored: Boolean val suite: TestSuite fun run() } internal val TestCase.prettyName get() = "${suite.name}.$name" public interface TestSuite { val name: String val ignored: Boolean val testCases: Map val size : Int fun doBeforeClass() fun doAfterClass() } public enum class TestFunctionKind { BEFORE_TEST, AFTER_TEST, BEFORE_CLASS, AFTER_CLASS } public abstract class AbstractTestSuite>(override val name: String, override val ignored: Boolean) : TestSuite { override fun toString(): String = name // TODO: Make inner and remove the type param when the bug is fixed. abstract class BasicTestCase>( override val name: String, override val suite: AbstractTestSuite, val testFunction: F, override val ignored: Boolean ) : TestCase { override fun toString(): String = "$name ($suite)" } private val _testCases = mutableMapOf>() override val testCases: Map> get() = _testCases private fun registerTestCase(testCase: BasicTestCase) = _testCases.put(testCase.name, testCase) fun registerTestCase(name: String, testFunction: F, ignored: Boolean) = registerTestCase(createTestCase(name, testFunction, ignored)) abstract fun createTestCase(name: String, testFunction: F, ignored: Boolean): BasicTestCase init { registerSuite(this) } override val size: Int get() = testCases.size } public abstract class BaseClassSuite(name: String, ignored: Boolean) : AbstractTestSuite Unit>(name, ignored) { class TestCase(name: String, override val suite: BaseClassSuite, testFunction: INSTANCE.() -> Unit, ignored: Boolean) : BasicTestCase Unit>(name, suite, testFunction, ignored) { override fun run() { val instance = suite.createInstance() try { suite.before.forEach { instance.it() } instance.testFunction() } finally { suite.after.forEach { instance.it() } } } } // These two methods are overridden in test suite classes generated by the compiler. abstract fun createInstance(): INSTANCE open fun getCompanion(): COMPANION = throw NotImplementedError("Test class has no companion object") companion object { val INSTANCE_KINDS = listOf(TestFunctionKind.BEFORE_TEST, TestFunctionKind.AFTER_TEST) val COMPANION_KINDS = listOf(TestFunctionKind.BEFORE_CLASS, TestFunctionKind.AFTER_CLASS) } private val instanceFunctions = mutableMapOf Unit>>() private fun getInstanceFunctions(kind: TestFunctionKind): MutableCollection Unit> { check(kind in INSTANCE_KINDS) return instanceFunctions.getOrPut(kind) { mutableSetOf() } } private val companionFunction = mutableMapOf Unit>>() private fun getCompanionFunctions(kind: TestFunctionKind): MutableCollection Unit> { check(kind in COMPANION_KINDS) return companionFunction.getOrPut(kind) { mutableSetOf() } } val before: Collection Unit> get() = getInstanceFunctions(TestFunctionKind.BEFORE_TEST) val after: Collection Unit> get() = getInstanceFunctions(TestFunctionKind.AFTER_TEST) val beforeClass: Collection Unit> get() = getCompanionFunctions(TestFunctionKind.BEFORE_CLASS) val afterClass: Collection Unit> get() = getCompanionFunctions(TestFunctionKind.AFTER_CLASS) @Suppress("UNCHECKED_CAST") fun registerFunction(kind: TestFunctionKind, function: Function1<*, Unit>) = when (kind) { in INSTANCE_KINDS -> getInstanceFunctions(kind).add(function as INSTANCE.() -> Unit) in COMPANION_KINDS -> getCompanionFunctions(kind).add(function as COMPANION.() -> Unit) else -> throw IllegalArgumentException("Unknown function kind: $kind") } override fun doBeforeClass() = beforeClass.forEach { getCompanion().it() } override fun doAfterClass() = afterClass.forEach { getCompanion().it() } override fun createTestCase(name: String, testFunction: INSTANCE.() -> Unit, ignored: Boolean) : BasicTestCase Unit> = TestCase(name, this, testFunction, ignored) } private typealias TopLevelFun = () -> Unit public class TopLevelSuite(name: String): AbstractTestSuite(name, false) { class TestCase(name: String, override val suite: TopLevelSuite, testFunction: TopLevelFun, ignored: Boolean) : BasicTestCase(name, suite, testFunction, ignored) { override fun run() { try { suite.before.forEach { it() } testFunction() } finally { suite.after.forEach { it() } } } } private val specialFunctions = mutableMapOf>() private fun getFunctions(type: TestFunctionKind) = specialFunctions.getOrPut(type) { mutableSetOf() } val before: Collection get() = getFunctions(TestFunctionKind.BEFORE_TEST) val after: Collection get() = getFunctions(TestFunctionKind.AFTER_TEST) val beforeClass: Collection get() = getFunctions(TestFunctionKind.BEFORE_CLASS) val afterClass: Collection get() = getFunctions(TestFunctionKind.AFTER_CLASS) fun registerFunction(kind: TestFunctionKind, function: TopLevelFun) = getFunctions(kind).add(function) override fun doBeforeClass() = beforeClass.forEach { it() } override fun doAfterClass() = afterClass.forEach { it() } override fun createTestCase(name: String, testFunction: TopLevelFun, ignored: Boolean) : BasicTestCase = TestCase(name, this, testFunction, ignored) } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/ref/Weak.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.ref /** * Class WeakReference encapsulates weak reference to an object, which could be used to either * retrieve a strong reference to an object, or return null, if object was already destroyed by * the memory manager. */ public class WeakReference { /** * Creates a weak reference object pointing to an object. Weak reference doesn't prevent * removing object, and is nullified once object is collected. */ constructor(referred: T) { pointer = getWeakReferenceImpl(referred) } /** * Backing store for the object pointer, inaccessible directly. */ @PublishedApi internal var pointer: WeakReferenceImpl? /** * Clears reference to an object. */ public fun clear() { pointer = null } /** * Returns either reference to an object or null, if it was collected. */ @Suppress("UNCHECKED_CAST") public fun get(): T? = pointer?.get() as T? /** * Returns either reference to an object or null, if it was collected. */ public val value: T? get() = this.get() } ================================================ FILE: runtime/src/main/kotlin/kotlin/native/ref/WeakPrivate.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native.ref import kotlinx.cinterop.COpaquePointer import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.Frozen import kotlin.native.internal.NoReorderFields import kotlin.native.internal.Escapes /** * Theory of operations: * * Weak references in Kotlin/Native are implemented in the following way. Whenever weak reference to an * object is created, we atomically modify type info pointer in the object to point into a metaobject. * This metaobject contains a strong reference to the counter object (instance of WeakReferenceCounter class). * Every other weak reference contains a strong reference to the counter object. * * [weak1] [weak2] * \ / * V V * .......[Counter] <---- * . | * . | * ->[Object] -> [Meta]- * * References from weak reference objects to the counter and from the metaobject to the counter are strong, * and from the counter to the object is nullably weak. So whenever an object dies, if it has a metaobject, * it is traversed to find a counter object, and atomically nullify reference to the object. Afterward, all attempts * to get the object would yield null. */ // Clear holding the counter object, which refers to the actual object. @NoReorderFields @Frozen internal class WeakReferenceCounter(var referred: COpaquePointer?) : WeakReferenceImpl() { // Spinlock, potentially taken when materializing or removing 'referred' object. var lock: Int = 0 // Optimization for concurrent access. var cookie: Int = 0 @SymbolName("Konan_WeakReferenceCounter_get") external override fun get(): Any? } @PublishedApi internal abstract class WeakReferenceImpl { abstract fun get(): Any? } // Get a counter from non-null object. @SymbolName("Konan_getWeakReferenceImpl") @Escapes(0b01) // referent escapes. external internal fun getWeakReferenceImpl(referent: Any): WeakReferenceImpl // Create a counter object. @ExportForCppRuntime internal fun makeWeakReferenceCounter(referred: COpaquePointer) = WeakReferenceCounter(referred) internal class PermanentWeakReferenceImpl(val referred: Any): kotlin.native.ref.WeakReferenceImpl() { override fun get(): Any? = referred } // Create a reference to the permanent object. @ExportForCppRuntime internal fun makePermanentWeakReferenceImpl(referred: Any) = PermanentWeakReferenceImpl(referred) ================================================ FILE: runtime/src/main/kotlin/kotlin/native/simd.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.native import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType public final class Vector128 private constructor() { @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getByteAt(index: Int): Byte @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getIntAt(index: Int): Int @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getLongAt(index: Int): Long @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getFloatAt(index: Int): Float @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getDoubleAt(index: Int): Double @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getUByteAt(index: Int): UByte @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getUIntAt(index: Int): UInt @TypedIntrinsic(IntrinsicType.EXTRACT_ELEMENT) external fun getULongAt(index: Int): ULong public override fun toString() = "(0x${getUIntAt(0).toString(16)}, 0x${getUIntAt(1).toString(16)}, 0x${getUIntAt(2).toString(16)}, 0x${getUIntAt(3).toString(16)})" // Not as good for floating types public fun equals(other: Vector128): Boolean = getLongAt(0) == other.getLongAt(0) && getLongAt(1) == other.getLongAt(1) public override fun equals(other: Any?): Boolean = other is Vector128 && this.equals(other) override fun hashCode(): Int { val x0 = getLongAt(0) val x1 = getLongAt(1) return 31 * (x0 xor (x0 shr 32)).toInt() + (x1 xor (x1 shr 32)).toInt() } } @SymbolName("Kotlin_Vector4f_of") external fun vectorOf(f0: Float, f1: Float, f2: Float, f3: Float): Vector128 @SymbolName("Kotlin_Vector4i32_of") external fun vectorOf(f0: Int, f1: Int, f2: Int, f3: Int): Vector128 ================================================ FILE: runtime/src/main/kotlin/kotlin/random/Random.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.random import kotlin.native.concurrent.AtomicLong import kotlin.system.getTimeNanos /** * The default implementation of pseudo-random generator using the linear congruential generator. */ internal object NativeRandom : Random() { private const val MULTIPLIER = 0x5deece66dL private val _seed = AtomicLong(mult(getTimeNanos())) /** * Random generator seed value. */ private val seed: Long get() = _seed.value private fun mult(value: Long) = (value xor MULTIPLIER) and ((1L shl 48) - 1) private fun update(seed: Long): Unit { _seed.value = seed } override fun nextBits(bitCount: Int): Int { update((seed * MULTIPLIER + 0xbL) and ((1L shl 48) - 1)) return (seed ushr (48 - bitCount)).toInt() } override fun nextInt(): Int = nextBits(32) } internal actual fun defaultPlatformRandom(): Random = NativeRandom internal actual fun doubleFromParts(hi26: Int, low27: Int): Double = (hi26.toLong().shl(27) + low27) / (1L shl 53).toDouble() ================================================ FILE: runtime/src/main/kotlin/kotlin/ranges/ProgressionIterators.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.ranges /** * An iterator over a progression of values of type `Char`. * @property step the number by which the value is incremented on each step. */ internal class CharProgressionIterator(first: Char, last: Char, val step: Int) : CharIterator() { private val finalElement = last.toInt() private var hasNext: Boolean = if (step > 0) first <= last else first >= last private var next = if (hasNext) first.toInt() else finalElement override fun hasNext(): Boolean = hasNext override fun nextChar(): Char { val value = next if (value == finalElement) { if (!hasNext) throw kotlin.NoSuchElementException() hasNext = false } else { next += step } return value.toChar() } } /** * An iterator over a progression of values of type `Int`. * @property step the number by which the value is incremented on each step. */ internal class IntProgressionIterator(first: Int, last: Int, val step: Int) : IntIterator() { private val finalElement = last private var hasNext: Boolean = if (step > 0) first <= last else first >= last private var next = if (hasNext) first else finalElement override fun hasNext(): Boolean = hasNext override fun nextInt(): Int { val value = next if (value == finalElement) { if (!hasNext) throw kotlin.NoSuchElementException() hasNext = false } else { next += step } return value } } /** * An iterator over a progression of values of type `Long`. * @property step the number by which the value is incremented on each step. */ internal class LongProgressionIterator(first: Long, last: Long, val step: Long) : LongIterator() { private val finalElement = last private var hasNext: Boolean = if (step > 0) first <= last else first >= last private var next = if (hasNext) first else finalElement override fun hasNext(): Boolean = hasNext override fun nextLong(): Long { val value = next if (value == finalElement) { if (!hasNext) throw kotlin.NoSuchElementException() hasNext = false } else { next += step } return value } } ================================================ FILE: runtime/src/main/kotlin/kotlin/ranges/Progressions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ // A copy-paste from kotlin/core/builtins/src/kotlin/Progressions.kt package kotlin.ranges import kotlin.internal.getProgressionLastElement /** * A progression of values of type `Char`. */ public open class CharProgression internal constructor ( start: Char, endInclusive: Char, step: Int ) : Iterable { init { if (step == 0) throw kotlin.IllegalArgumentException("Step must be non-zero.") if (step == Int.MIN_VALUE) throw kotlin.IllegalArgumentException("Step must be greater than Int.MIN_VALUE to avoid overflow on negation.") } /** * The first element in the progression. */ public val first: Char = start /** * The last element in the progression. */ public val last: Char = getProgressionLastElement(start.toInt(), endInclusive.toInt(), step).toChar() /** * The step of the progression. */ public val step: Int = step override fun iterator(): CharIterator = CharProgressionIterator(first, last, step) /** Checks if the progression is empty. */ public open fun isEmpty(): Boolean = if (step > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is CharProgression && (isEmpty() && other.isEmpty() || first == other.first && last == other.last && step == other.step) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * (31 * first.toInt() + last.toInt()) + step) override fun toString(): String = if (step > 0) "$first..$last step $step" else "$first downTo $last step ${-step}" companion object { /** * Creates CharProgression within the specified bounds of a closed range. * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. * * [step] must be greater than `Int.MIN_VALUE` and not equal to zero. */ public fun fromClosedRange(rangeStart: Char, rangeEnd: Char, step: Int): CharProgression = CharProgression(rangeStart, rangeEnd, step) } } /** * A progression of values of type `Int`. */ public open class IntProgression internal constructor ( start: Int, endInclusive: Int, step: Int ) : Iterable { init { if (step == 0) throw kotlin.IllegalArgumentException("Step must be non-zero.") if (step == Int.MIN_VALUE) throw kotlin.IllegalArgumentException("Step must be greater than Int.MIN_VALUE to avoid overflow on negation.") } /** * The first element in the progression. */ public val first: Int = start /** * The last element in the progression. */ public val last: Int = getProgressionLastElement(start.toInt(), endInclusive.toInt(), step).toInt() /** * The step of the progression. */ public val step: Int = step override fun iterator(): IntIterator = IntProgressionIterator(first, last, step) /** Checks if the progression is empty. */ public open fun isEmpty(): Boolean = if (step > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is IntProgression && (isEmpty() && other.isEmpty() || first == other.first && last == other.last && step == other.step) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * (31 * first + last) + step) override fun toString(): String = if (step > 0) "$first..$last step $step" else "$first downTo $last step ${-step}" companion object { /** * Creates IntProgression within the specified bounds of a closed range. * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. * * [step] must be greater than `Int.MIN_VALUE` and not equal to zero. */ public fun fromClosedRange(rangeStart: Int, rangeEnd: Int, step: Int): IntProgression = IntProgression(rangeStart, rangeEnd, step) } } /** * A progression of values of type `Long`. */ public open class LongProgression internal constructor ( start: Long, endInclusive: Long, step: Long ) : Iterable { init { if (step == 0L) throw kotlin.IllegalArgumentException("Step must be non-zero.") if (step == Long.MIN_VALUE) throw kotlin.IllegalArgumentException("Step must be greater than Long.MIN_VALUE to avoid overflow on negation.") } /** * The first element in the progression. */ public val first: Long = start /** * The last element in the progression. */ public val last: Long = getProgressionLastElement(start.toLong(), endInclusive.toLong(), step).toLong() /** * The step of the progression. */ public val step: Long = step override fun iterator(): LongIterator = LongProgressionIterator(first, last, step) /** Checks if the progression is empty. */ public open fun isEmpty(): Boolean = if (step > 0) first > last else first < last override fun equals(other: Any?): Boolean = other is LongProgression && (isEmpty() && other.isEmpty() || first == other.first && last == other.last && step == other.step) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * (31 * (first xor (first ushr 32)) + (last xor (last ushr 32))) + (step xor (step ushr 32))).toInt() override fun toString(): String = if (step > 0) "$first..$last step $step" else "$first downTo $last step ${-step}" companion object { /** * Creates LongProgression within the specified bounds of a closed range. * The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step]. * In order to go backwards the [step] must be negative. * * [step] must be greater than `Long.MIN_VALUE` and not equal to zero. */ public fun fromClosedRange(rangeStart: Long, rangeEnd: Long, step: Long): LongProgression = LongProgression(rangeStart, rangeEnd, step) } } ================================================ FILE: runtime/src/main/kotlin/kotlin/ranges/Range.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.ranges /** * Represents a range of values (for example, numbers or characters). * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/ranges.html) for more information. */ public interface ClosedRange> { /** * The minimum value in the range. */ public val start: T /** * The maximum value in the range (inclusive). */ public val endInclusive: T /** * Checks whether the specified [value] belongs to the range. */ public operator fun contains(value: T): Boolean = value >= start && value <= endInclusive /** * Checks whether the range is empty. */ public fun isEmpty(): Boolean = start > endInclusive } ================================================ FILE: runtime/src/main/kotlin/kotlin/ranges/Ranges.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.ranges /** * A range of values of type `Char`. */ public class CharRange(start: Char, endInclusive: Char) : CharProgression(start, endInclusive, 1), ClosedRange { override val start: Char get() = first override val endInclusive: Char get() = last override fun contains(value: Char): Boolean = first <= value && value <= last override fun isEmpty(): Boolean = first > last override fun equals(other: Any?): Boolean = other is CharRange && (isEmpty() && other.isEmpty() || first == other.first && last == other.last) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * first.toInt() + last.toInt()) override fun toString(): String = "$first..$last" companion object { /** An empty range of values of type Char. */ public val EMPTY: CharRange = CharRange(1.toChar(), 0.toChar()) } } /** * A range of values of type `Int`. */ public class IntRange(start: Int, endInclusive: Int) : IntProgression(start, endInclusive, 1), ClosedRange { override val start: Int get() = first override val endInclusive: Int get() = last override fun contains(value: Int): Boolean = first <= value && value <= last override fun isEmpty(): Boolean = first > last override fun equals(other: Any?): Boolean = other is IntRange && (isEmpty() && other.isEmpty() || first == other.first && last == other.last) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * first + last) override fun toString(): String = "$first..$last" companion object { /** An empty range of values of type Int. */ public val EMPTY: IntRange = IntRange(1, 0) } } /** * A range of values of type `Long`. */ public class LongRange(start: Long, endInclusive: Long) : LongProgression(start, endInclusive, 1), ClosedRange { override val start: Long get() = first override val endInclusive: Long get() = last override fun contains(value: Long): Boolean = first <= value && value <= last override fun isEmpty(): Boolean = first > last override fun equals(other: Any?): Boolean = other is LongRange && (isEmpty() && other.isEmpty() || first == other.first && last == other.last) override fun hashCode(): Int = if (isEmpty()) -1 else (31 * (first xor (first ushr 32)) + (last xor (last ushr 32))).toInt() override fun toString(): String = "$first..$last" companion object { /** An empty range of values of type Long. */ public val EMPTY: LongRange = LongRange(1, 0) } } ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/AssociatedObjects.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect import kotlin.native.internal.* /** * The experimental marker for associated objects API. * * Any usage of a declaration annotated with `@ExperimentalAssociatedObjects` must be accepted either by * annotating that usage with the [OptIn] annotation, e.g. `@OptIn(ExperimentalAssociatedObjects::class)`, * or by using the compiler argument `-Xopt-in=kotlin.reflect.ExperimentalAssociatedObjects`. */ @RequiresOptIn(level = RequiresOptIn.Level.ERROR) @Retention(value = AnnotationRetention.BINARY) public annotation class ExperimentalAssociatedObjects /** * Makes the annotated annotation class an associated object key. * * An associated object key annotation should have single [KClass] parameter. * When applied to a class with reference to an object declaration as an argument, it binds * the object to the class, making this binding discoverable at runtime using [findAssociatedObject]. */ @ExperimentalAssociatedObjects @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.ANNOTATION_CLASS) public annotation class AssociatedObjectKey /** * If [T] is an @[AssociatedObjectKey]-annotated annotation class and [this] class is annotated with @[T] (`S::class`), * returns object `S`. * * Otherwise returns `null`. */ @ExperimentalAssociatedObjects public inline fun KClass<*>.findAssociatedObject(): Any? = this.findAssociatedObject(T::class) ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KAnnotatedElement.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect import kotlin.native.internal.FixmeReflection /** * Represents an annotated element and allows to obtain its annotations. * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/annotations.html) * for more information. */ @FixmeReflection public interface KAnnotatedElement ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KCallable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect import kotlin.native.internal.FixmeReflection /** * Represents a callable entity, such as a function or a property. * * @param R return type of the callable. */ public actual interface KCallable : KAnnotatedElement { /** * The name of this callable as it was declared in the source code. * If the callable has no name, a special invented name is created. * Nameless callables include: * - constructors have the name "", * - property accessors: the getter for a property named "foo" will have the name "", * the setter, similarly, will have the name "". */ public actual val name: String /** * The type of values returned by this callable. */ public val returnType: KType } ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect /** * Represents a class and provides introspection capabilities. * Instances of this class are obtainable by the `::class` syntax. * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/reflection.html#class-references) * for more information. * * @param T the type of the class. */ public actual interface KClass : KDeclarationContainer, KAnnotatedElement, KClassifier { /** * The simple name of the class as it was declared in the source code, * or `null` if the class has no name (if, for example, it is a class of an anonymous object). */ public actual val simpleName: String? /** * The fully qualified dot-separated name of the class, * or `null` if the class is local or a class of an anonymous object. */ public actual val qualifiedName: String? /** * Returns `true` if [value] is an instance of this class on a given platform. */ @SinceKotlin("1.1") public actual fun isInstance(value: Any?): Boolean /** * Returns `true` if this [KClass] instance represents the same Kotlin class as the class represented by [other]. * On JVM this means that all of the following conditions are satisfied: * * 1. [other] has the same (fully qualified) Kotlin class name as this instance. * 2. [other]'s backing [Class] object is loaded with the same class loader as the [Class] object of this instance. * 3. If the classes represent [Array], then [Class] objects of their element types are equal. * * For example, on JVM, [KClass] instances for a primitive type (`int`) and the corresponding wrapper type (`java.lang.Integer`) * are considered equal, because they have the same fully qualified name "kotlin.Int". */ override fun equals(other: Any?): Boolean override fun hashCode(): Int } ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KClassesImpl.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.reflect internal actual inline val KClass<*>.qualifiedOrSimpleName: String? get() = qualifiedName ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KDeclarationContainer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect /** * Represents an entity which may contain declarations of any other entities, * such as a class or a package. */ public interface KDeclarationContainer ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KFunction.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect public actual interface KFunction : KCallable, Function ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KProperty.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect import kotlin.native.internal.FixmeReflection /** * Represents a property, such as a named `val` or `var` declaration. * Instances of this class are obtainable by the `::` operator. * * See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/reflection.html) * for more information. * * @param V the type of the property value. */ public actual interface KProperty : KCallable public actual interface KProperty0 : kotlin.reflect.KProperty, () -> V { public actual fun get(): V public override abstract operator fun invoke(): V } public actual interface KProperty1 : kotlin.reflect.KProperty, (T) -> V { public actual fun get(receiver: T): V public override operator fun invoke(p1: T): V } public actual interface KProperty2 : kotlin.reflect.KProperty, (D, E) -> V { public actual fun get(receiver1: D, receiver2: E): V public override operator fun invoke(p1: D, p2: E): V } /** * Represents a property declared as a `var`. */ public actual interface KMutableProperty : KProperty public actual interface KMutableProperty0 : KProperty0, KMutableProperty { public actual fun set(value: V) } public actual interface KMutableProperty1 : KProperty1, KMutableProperty { public actual fun set(receiver: T, value: V) } public actual interface KMutableProperty2 : KProperty2, KMutableProperty { public actual fun set(receiver1: D, receiver2: E, value: V) } ================================================ FILE: runtime/src/main/kotlin/kotlin/reflect/KType.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.reflect /** * Represents a type. Type is usually either a class with optional type arguments, * or a type parameter of some declaration, plus nullability. */ public actual interface KType { /** * The declaration of the classifier used in this type. * For example, in the type `List` the classifier would be the [KClass] instance for [List]. * * Returns `null` if this type is not denotable in Kotlin, for example if it is an intersection type. */ @SinceKotlin("1.1") public actual val classifier: KClassifier? /** * Type arguments passed for the parameters of the classifier in this type. * For example, in the type `Array` the only type argument is `out Number`. * * In case this type is based on an inner class, the returned list contains the type arguments provided for the innermost class first, * then its outer class, and so on. * For example, in the type `Outer.Inner` the returned list is `[C, D, A, B]`. */ @SinceKotlin("1.1") public actual val arguments: List /** * `true` if this type was marked nullable in the source code. * * For Kotlin types, it means that `null` value is allowed to be represented by this type. * In practice it means that the type was declared with a question mark at the end. * For non-Kotlin types, it means the type or the symbol which was declared with this type * is annotated with a runtime-retained nullability annotation such as [javax.annotation.Nullable]. * * Note that even if [isMarkedNullable] is false, values of the type can still be `null`. * This may happen if it is a type of the type parameter with a nullable upper bound: * * ``` * fun foo(t: T) { * // isMarkedNullable == false for t's type, but t can be null here when T = "Any?" * } * ``` */ public actual val isMarkedNullable: Boolean } ================================================ FILE: runtime/src/main/kotlin/kotlin/sequences/Sequences.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.sequences import kotlin.comparisons.* import kotlin.native.internal.FixmeConcurrency @FixmeConcurrency internal actual class ConstrainedOnceSequence actual constructor(sequence: Sequence) : Sequence { // TODO: not MT friendly. private var sequenceRef : Sequence? = sequence override actual fun iterator(): Iterator { val sequence = sequenceRef if (sequence == null) throw IllegalStateException("This sequence can be consumed only once.") sequenceRef = null return sequence.iterator() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/system/Process.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.system /** * Terminates the currently running process. * * @param status serves as a status code; by convention, * a nonzero status code indicates abnormal termination. * * @return This method never returns normally. */ @SymbolName("Kotlin_system_exitProcess") public external fun exitProcess(status: Int): Nothing ================================================ FILE: runtime/src/main/kotlin/kotlin/system/Timing.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.system /** * Gets current system time in milliseconds since certain moment in the past, * only delta between two subsequent calls makes sense. */ @SymbolName("Kotlin_system_getTimeMillis") public external fun getTimeMillis() : Long /** * Gets current system time in nanoseconds since certain moment in the past, * only delta between two subsequent calls makes sense. */ @SymbolName("Kotlin_system_getTimeNanos") public external fun getTimeNanos() : Long /** * Gets current system time in microseconds since certain moment in the past, * only delta between two subsequent calls makes sense. */ @SymbolName("Kotlin_system_getTimeMicros") public external fun getTimeMicros() : Long /** Executes the given [block] and returns elapsed time in milliseconds. */ public inline fun measureTimeMillis(block: () -> Unit) : Long { val start = getTimeMillis() block() return getTimeMillis() - start } /** Executes the given [block] and returns elapsed time in microseconds (Kotlin/Native only). */ public inline fun measureTimeMicros(block: () -> Unit) : Long { val start = getTimeMicros() block() return getTimeMicros() - start } /** Executes the given [block] and returns elapsed time in nanoseconds. */ public inline fun measureNanoTime(block: () -> Unit) : Long { val start = getTimeNanos() block() return getTimeNanos() - start } ================================================ FILE: runtime/src/main/kotlin/kotlin/test/Annotation.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.test /** * Marks a function as a test. */ @Target(AnnotationTarget.FUNCTION) public actual annotation class Test /** * Marks a function to be executed before a suite. Not supported in Kotlin/Common. */ @Target(AnnotationTarget.FUNCTION) public annotation class BeforeClass /** * Marks a function to be executed after a suite. Not supported in Kotlin/Common. */ @Target(AnnotationTarget.FUNCTION) public annotation class AfterClass /** * Marks a function to be invoked before each test. */ @Target(AnnotationTarget.FUNCTION) public actual annotation class BeforeTest /** * Marks a function to be invoked after each test. */ @Target(AnnotationTarget.FUNCTION) public actual annotation class AfterTest /** * Marks a test or a suite as ignored. */ @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) public actual annotation class Ignore @Deprecated("AfterEach should be replaced with AfterTest to unify usage of kotlin.test", level = DeprecationLevel.ERROR) public typealias AfterEach = AfterTest @Deprecated("BeforeEach should be replaced with BeforeTest to unify usage of kotlin.test", level = DeprecationLevel.ERROR) public typealias BeforeEach = BeforeTest ================================================ FILE: runtime/src/main/kotlin/kotlin/test/Assertions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /** * A number of common helper methods for writing unit tests. */ @file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") package kotlin.test import kotlin.reflect.KClass /** * Takes the given [block] of test code and _doesn't_ execute it. * * This keeps the code under test referenced, but doesn't actually test it until it is implemented. */ @Suppress("UNUSED_PARAMETER") public actual inline fun todo(block: () -> Unit) { println("TODO") } @PublishedApi internal actual fun checkResultIsFailure(exceptionClass: KClass, message: String?, blockResult: Result): T { blockResult.fold( onSuccess = { asserter.fail(messagePrefix(message) + "Expected an exception of ${exceptionClass.qualifiedName} to be thrown, but was completed successfully.") }, onFailure = { e -> if (exceptionClass.isInstance(e)) { @Suppress("UNCHECKED_CAST") return e as T } asserter.fail(messagePrefix(message) + "Expected an exception of ${exceptionClass.qualifiedName} to be thrown, but was $e", e) } ) } /** Platform-specific construction of AssertionError with cause */ @Suppress("NOTHING_TO_INLINE") internal actual inline fun AssertionErrorWithCause(message: String?, cause: Throwable?): AssertionError = AssertionError(message, cause) internal actual fun lookupAsserter(): Asserter = DefaultAsserter ================================================ FILE: runtime/src/main/kotlin/kotlin/text/Appendable.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text /** * An object to which char sequences and values can be appended. */ public actual interface Appendable { /** * Appends the specified character [value] to this Appendable and returns this instance. * * @param value the character to append. */ actual fun append(value: Char): Appendable /** * Appends the specified character sequence [value] to this Appendable and returns this instance. * * @param value the character sequence to append. If [value] is `null`, then the four characters `"null"` are appended to this Appendable. */ actual fun append(value: CharSequence?): Appendable /** * Appends a subsequence of the specified character sequence [value] to this Appendable and returns this instance. * * @param value the character sequence from which a subsequence is appended. If [value] is `null`, * then characters are appended as if [value] contained the four characters `"null"`. * @param startIndex the beginning (inclusive) of the subsequence to append. * @param endIndex the end (exclusive) of the subsequence to append. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. */ actual fun append(value: CharSequence?, startIndex: Int, endIndex: Int): Appendable } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/Char.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text import kotlin.IllegalArgumentException /** * Returns `true` if this character (Unicode code point) is defined in Unicode. * * A character is considered to be defined in Unicode if its [category] is not [CharCategory.UNASSIGNED]. */ public actual fun Char.isDefined(): Boolean { if (this < '\u0080') { return true } return getCategoryValue() != CharCategory.UNASSIGNED.value } /** * Returns `true` if this character is a letter. * * A character is considered to be a letter if its [category] is [CharCategory.UPPERCASE_LETTER], * [CharCategory.LOWERCASE_LETTER], [CharCategory.TITLECASE_LETTER], [CharCategory.MODIFIER_LETTER], or [CharCategory.OTHER_LETTER]. * * @sample samples.text.Chars.isLetter */ public actual fun Char.isLetter(): Boolean { if (this in 'a'..'z' || this in 'A'..'Z') { return true } if (this < '\u0080') { return false } return isLetterImpl() } /** * Returns `true` if this character is a letter or digit. * * @see isLetter * @see isDigit * * @sample samples.text.Chars.isLetterOrDigit */ public actual fun Char.isLetterOrDigit(): Boolean { if (this in 'a'..'z' || this in 'A'..'Z' || this in '0'..'9') { return true } if (this < '\u0080') { return false } return isDigit() || isLetter() } /** * Returns `true` if this character is a digit. * * A character is considered to be a digit if its [category] is [CharCategory.DECIMAL_DIGIT_NUMBER]. * * @sample samples.text.Chars.isDigit */ public actual fun Char.isDigit(): Boolean { if (this in '0'..'9') { return true } if (this < '\u0080') { return false } return isDigitImpl() } /** * Returns `true` if this character (Unicode code point) should be regarded as an ignorable * character in a Java identifier or a Unicode identifier. */ @SymbolName("Kotlin_Char_isIdentifierIgnorable") external public fun Char.isIdentifierIgnorable(): Boolean /** * Returns `true` if this character is an ISO control character. * * A character is considered to be an ISO control character if its code is in the range `'\u0000'..'\u001F'` or in the range `'\u007F'..'\u009F'`. * * @sample samples.text.Chars.isISOControl */ @SymbolName("Kotlin_Char_isISOControl") external public actual fun Char.isISOControl(): Boolean /** * Determines whether a character is whitespace according to the Unicode standard. * Returns `true` if the character is whitespace. * * @sample samples.text.Chars.isWhitespace */ public actual fun Char.isWhitespace(): Boolean = isWhitespaceImpl() /** * Returns `true` if this character is an upper case letter. * * A character is considered to be an upper case letter if its [category] is [CharCategory.UPPERCASE_LETTER]. * * @sample samples.text.Chars.isUpperCase */ public actual fun Char.isUpperCase(): Boolean { if (this in 'A'..'Z') { return true } if (this < '\u0080') { return false } return isUpperCaseImpl() } /** * Returns `true` if this character is a lower case letter. * * A character is considered to be a lower case letter if its [category] is [CharCategory.LOWERCASE_LETTER]. * * @sample samples.text.Chars.isLowerCase */ public actual fun Char.isLowerCase(): Boolean { if (this in 'a'..'z') { return true } if (this < '\u0080') { return false } return isLowerCaseImpl() } /** * Returns `true` if this character is a title case letter. * * A character is considered to be a title case letter if its [category] is [CharCategory.TITLECASE_LETTER]. * * @sample samples.text.Chars.isTitleCase */ public actual fun Char.isTitleCase(): Boolean { if (this < '\u0080') { return false } return getCategoryValue() == CharCategory.TITLECASE_LETTER.value } /** * Converts this character to upper case using Unicode mapping rules of the invariant locale. */ public actual fun Char.toUpperCase(): Char = uppercaseCharImpl() /** * Converts this character to upper case using Unicode mapping rules of the invariant locale. * * This function performs one-to-one character mapping. * To support one-to-many character mapping use the [uppercase] function. * If this character has no mapping equivalent, the character itself is returned. * * @sample samples.text.Chars.uppercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun Char.uppercaseChar(): Char = uppercaseCharImpl() /** * Converts this character to upper case using Unicode mapping rules of the invariant locale. * * This function supports one-to-many character mapping, thus the length of the returned string can be greater than one. * For example, `'\uFB00'.uppercase()` returns `"\u0046\u0046"`, * where `'\uFB00'` is the LATIN SMALL LIGATURE FF character (`ff`). * If this character has no upper case mapping, the result of `toString()` of this char is returned. * * @sample samples.text.Chars.uppercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun Char.uppercase(): String = uppercaseImpl() /** * Converts this character to lower case using Unicode mapping rules of the invariant locale. */ public actual fun Char.toLowerCase(): Char = lowercaseCharImpl() /** * Converts this character to lower case using Unicode mapping rules of the invariant locale. * * This function performs one-to-one character mapping. * To support one-to-many character mapping use the [lowercase] function. * If this character has no mapping equivalent, the character itself is returned. * * @sample samples.text.Chars.lowercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun Char.lowercaseChar(): Char = lowercaseCharImpl() /** * Converts this character to lower case using Unicode mapping rules of the invariant locale. * * This function supports one-to-many character mapping, thus the length of the returned string can be greater than one. * For example, `'\u0130'.lowercase()` returns `"\u0069\u0307"`, * where `'\u0130'` is the LATIN CAPITAL LETTER I WITH DOT ABOVE character (`İ`). * If this character has no lower case mapping, the result of `toString()` of this char is returned. * * @sample samples.text.Chars.lowercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun Char.lowercase(): String = lowercaseImpl() /** * Converts this character to title case using Unicode mapping rules of the invariant locale. * * This function performs one-to-one character mapping. * To support one-to-many character mapping use the [titlecase] function. * If this character has no mapping equivalent, the result of calling [uppercaseChar] is returned. * * @sample samples.text.Chars.titlecase */ @SinceKotlin("1.4") public actual fun Char.titlecaseChar(): Char = titlecaseCharImpl() /** * Returns `true` if this character is a Unicode high-surrogate code unit (also known as leading-surrogate code unit). */ @SymbolName("Kotlin_Char_isHighSurrogate") external public actual fun Char.isHighSurrogate(): Boolean /** * Returns `true` if this character is a Unicode low-surrogate code unit (also known as trailing-surrogate code unit). */ @SymbolName("Kotlin_Char_isLowSurrogate") external public actual fun Char.isLowSurrogate(): Boolean internal actual fun digitOf(char: Char, radix: Int): Int = digitOfChecked(char, checkRadix(radix)) @SymbolName("Kotlin_Char_digitOfChecked") external internal fun digitOfChecked(char: Char, radix: Int): Int /** * Returns the Unicode general category of this character. */ public actual val Char.category: CharCategory get() = CharCategory.valueOf(getCategoryValue()) /** * Checks whether the given [radix] is valid radix for string to number and number to string conversion. */ @PublishedApi internal actual fun checkRadix(radix: Int): Int { if(radix !in Char.MIN_RADIX..Char.MAX_RADIX) { throw IllegalArgumentException("radix $radix was not in valid range ${Char.MIN_RADIX..Char.MAX_RADIX}") } return radix } // Char.Compaion methods. Konan specific. // TODO: Make public when supplementary codepoints are supported. /** Converts a unicode code point to lower case. */ internal fun Char.Companion.toLowerCase(codePoint: Int): Int = if (codePoint < MIN_SUPPLEMENTARY_CODE_POINT) { codePoint.toChar().toLowerCase().toInt() } else { codePoint // TODO: Implement this transformation for supplementary codepoints. } /** Converts a unicode code point to upper case. */ internal fun Char.Companion.toUpperCase(codePoint: Int): Int = if (codePoint < MIN_SUPPLEMENTARY_CODE_POINT) { codePoint.toChar().toUpperCase().toInt() } else { codePoint // TODO: Implement this transformation for supplementary codepoints. } /** Converts a surrogate pair to a unicode code point. Doesn't validate that the characters are a valid surrogate pair. */ public fun Char.Companion.toCodePoint(high: Char, low: Char): Int = (((high - MIN_HIGH_SURROGATE) shl 10) or (low - MIN_LOW_SURROGATE)) + 0x10000 /** Checks if the codepoint specified is a supplementary codepoint or not. */ public fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean = codepoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT public fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean = high.isHighSurrogate() && low.isLowSurrogate() /** * Converts the codepoint specified to a char array. If the codepoint is not supplementary, the method will * return an array with one element otherwise it will return an array A with a high surrogate in A[0] and * a low surrogate in A[1]. */ public fun Char.Companion.toChars(codePoint: Int): CharArray = when { codePoint in 0 until MIN_SUPPLEMENTARY_CODE_POINT -> charArrayOf(codePoint.toChar()) codePoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT -> { val low = ((codePoint - 0x10000) and 0x3FF) + MIN_LOW_SURROGATE.toInt() val high = (((codePoint - 0x10000) ushr 10) and 0x3FF) + MIN_HIGH_SURROGATE.toInt() charArrayOf(high.toChar(), low.toChar()) } else -> throw IllegalArgumentException() } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/CharCategory.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.text /** * Represents the character general category in the Unicode specification. */ public actual enum class CharCategory(public val value: Int, public actual val code: String) { /** * General category "Cn" in the Unicode specification. */ UNASSIGNED(0, "Cn"), /** * General category "Lu" in the Unicode specification. */ UPPERCASE_LETTER(1, "Lu"), /** * General category "Ll" in the Unicode specification. */ LOWERCASE_LETTER(2, "Ll"), /** * General category "Lt" in the Unicode specification. */ TITLECASE_LETTER(3, "Lt"), /** * General category "Lm" in the Unicode specification. */ MODIFIER_LETTER(4, "Lm"), /** * General category "Lo" in the Unicode specification. */ OTHER_LETTER(5, "Lo"), /** * General category "Mn" in the Unicode specification. */ NON_SPACING_MARK(6, "Mn"), /** * General category "Me" in the Unicode specification. */ ENCLOSING_MARK(7, "Me"), /** * General category "Mc" in the Unicode specification. */ COMBINING_SPACING_MARK(8, "Mc"), /** * General category "Nd" in the Unicode specification. */ DECIMAL_DIGIT_NUMBER(9, "Nd"), /** * General category "Nl" in the Unicode specification. */ LETTER_NUMBER(10, "Nl"), /** * General category "No" in the Unicode specification. */ OTHER_NUMBER(11, "No"), /** * General category "Zs" in the Unicode specification. */ SPACE_SEPARATOR(12, "Zs"), /** * General category "Zl" in the Unicode specification. */ LINE_SEPARATOR(13, "Zl"), /** * General category "Zp" in the Unicode specification. */ PARAGRAPH_SEPARATOR(14, "Zp"), /** * General category "Cc" in the Unicode specification. */ CONTROL(15, "Cc"), /** * General category "Cf" in the Unicode specification. */ FORMAT(16, "Cf"), /** * General category "Co" in the Unicode specification. */ PRIVATE_USE(18, "Co"), /** * General category "Cs" in the Unicode specification. */ SURROGATE(19, "Cs"), /** * General category "Pd" in the Unicode specification. */ DASH_PUNCTUATION(20, "Pd"), /** * General category "Ps" in the Unicode specification. */ START_PUNCTUATION(21, "Ps"), /** * General category "Pe" in the Unicode specification. */ END_PUNCTUATION(22, "Pe"), /** * General category "Pc" in the Unicode specification. */ CONNECTOR_PUNCTUATION(23, "Pc"), /** * General category "Po" in the Unicode specification. */ OTHER_PUNCTUATION(24, "Po"), /** * General category "Sm" in the Unicode specification. */ MATH_SYMBOL(25, "Sm"), /** * General category "Sc" in the Unicode specification. */ CURRENCY_SYMBOL(26, "Sc"), /** * General category "Sk" in the Unicode specification. */ MODIFIER_SYMBOL(27, "Sk"), /** * General category "So" in the Unicode specification. */ OTHER_SYMBOL(28, "So"), /** * General category "Pi" in the Unicode specification. */ INITIAL_QUOTE_PUNCTUATION(29, "Pi"), /** * General category "Pf" in the Unicode specification. */ FINAL_QUOTE_PUNCTUATION(30, "Pf"); /** * Returns `true` if [char] character belongs to this category. */ public actual operator fun contains(char: Char): Boolean = char.getCategoryValue() == this.value public companion object { public fun valueOf(category: Int): CharCategory = when (category) { in 0..16 -> values()[category] in 18..30 -> values()[category - 1] else -> throw IllegalArgumentException("Category #$category is not defined.") } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/CharacterCodingException.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text /** * The exception thrown when a character encoding or decoding error occurs. */ @SinceKotlin("1.3") public actual open class CharacterCodingException(message: String?) : Exception(message) { actual constructor() : this(null) } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/PatternSyntaxException.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text /** * Encapsulates a syntax error that occurred during the compilation of a * [Pattern]. Might include a detailed description, the original regular * expression, and the index at which the error occurred. */ internal class PatternSyntaxException( val description: String = "", val pattern: String = "", val index: Int = -1 ) : IllegalArgumentException(formatMessage(description, pattern, index)) { companion object { fun formatMessage(description: String, pattern: String, index: Int): String { if (index < 0 || pattern == "") { return description } val filler = if (index >= 1) " ".repeat(index) else "" return """ $description near index: $index $pattern $filler^ """.trimIndent() } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/Regex.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text import kotlin.text.regex.* @PublishedApi internal interface FlagEnum { val value: Int val mask: Int } private fun Iterable.toInt(): Int = this.fold(0, { value, option -> value or option.value }) private fun fromInt(value: Int): Set = RegexOption.values().filterTo(mutableSetOf()) { value and it.mask == it.value } /** * Provides enumeration values to use to set regular expression options. */ public actual enum class RegexOption(override val value: Int, override val mask: Int = value) : FlagEnum { // common /** Enables case-insensitive matching. Case comparison is Unicode-aware. */ IGNORE_CASE(Pattern.CASE_INSENSITIVE), /** * Enables multiline mode. * * In multiline mode the expressions `^` and `$` match just after or just before, * respectively, a line terminator or the end of the input sequence. */ MULTILINE(Pattern.MULTILINE), /** * Enables literal parsing of the pattern. * * Metacharacters or escape sequences in the input sequence will be given no special meaning. */ LITERAL(Pattern.LITERAL), /** Enables Unix lines mode. In this mode, only the `'\n'` is recognized as a line terminator. */ UNIX_LINES(Pattern.UNIX_LINES), /** Permits whitespace and comments in pattern. */ COMMENTS(Pattern.COMMENTS), /** Enables the mode, when the expression `.` matches any character, including a line terminator. */ DOT_MATCHES_ALL(Pattern.DOTALL), /** Enables equivalence by canonical decomposition. */ CANON_EQ(Pattern.CANON_EQ) } /** * Represents the results from a single capturing group within a [MatchResult] of [Regex]. * * @param value The value of captured group. * @param range The range of indices in the input string where group was captured. * * The [range] property is available on JVM only. */ public actual data class MatchGroup(actual val value: String, val range: IntRange) /** * Represents a compiled regular expression. * Provides functions to match strings in text with a pattern, replace the found occurrences and split text around matches. */ public actual class Regex internal constructor(internal val nativePattern: Pattern) { internal enum class Mode { FIND, MATCH } /** Creates a regular expression from the specified [pattern] string and the default options. */ actual constructor(pattern: String): this(Pattern(pattern)) /** Creates a regular expression from the specified [pattern] string and the specified single [option]. */ actual constructor(pattern: String, option: RegexOption): this(Pattern(pattern, ensureUnicodeCase(option.value))) /** Creates a regular expression from the specified [pattern] string and the specified set of [options]. */ actual constructor(pattern: String, options: Set): this(Pattern(pattern, ensureUnicodeCase(options.toInt()))) /** The pattern string of this regular expression. */ actual val pattern: String get() = nativePattern.pattern private val startNode = nativePattern.startNode /** The set of options that were used to create this regular expression. */ actual val options: Set = fromInt(nativePattern.flags) actual companion object { /** * Returns a regular expression that matches the specified [literal] string literally. * No characters of that string will have special meaning when searching for an occurrence of the regular expression. */ actual fun fromLiteral(literal: String): Regex = Regex(literal, RegexOption.LITERAL) /** * Returns a regular expression pattern string that matches the specified [literal] string literally. * No characters of that string will have special meaning when searching for an occurrence of the regular expression. */ actual fun escape(literal: String): String = Pattern.quote(literal) /** * Returns a literal replacement expression for the specified [literal] string. * No characters of that string will have special meaning when it is used as a replacement string in [Regex.replace] function. */ actual fun escapeReplacement(literal: String): String { if (!literal.contains('\\') && !literal.contains('$')) return literal val result = StringBuilder(literal.length * 2) literal.forEach { if (it == '\\' || it == '$') { result.append('\\') } result.append(it) } return result.toString() } // TODO: Remove private fun ensureUnicodeCase(flags: Int) = flags } private fun doMatch(input: CharSequence, mode: Mode): MatchResult? { // TODO: Harmony has a default constructor for MatchResult. Do we need it? // TODO: Reuse the matchResult. val matchResult = MatchResultImpl(input, this) matchResult.mode = mode val matches = startNode.matches(0, input, matchResult) >= 0 if (!matches) { return null } matchResult.finalizeMatch() return matchResult } /** Indicates whether the regular expression matches the entire [input]. */ actual infix fun matches(input: CharSequence): Boolean = doMatch(input, Mode.MATCH) != null /** Indicates whether the regular expression can find at least one match in the specified [input]. */ actual fun containsMatchIn(input: CharSequence): Boolean = find(input) != null /** * Returns the first match of a regular expression in the [input], beginning at the specified [startIndex]. * * @param startIndex An index to start search with, by default 0. Must be not less than zero and not greater than `input.length()` * @return An instance of [MatchResult] if match was found or `null` otherwise. * @throws IndexOutOfBoundsException if [startIndex] is less than zero or greater than the length of the [input] char sequence. */ actual fun find(input: CharSequence, startIndex: Int): MatchResult? { if (startIndex < 0 || startIndex > input.length) { throw IndexOutOfBoundsException("Start index is out of bounds: $startIndex, input length: ${input.length}") } val matchResult = MatchResultImpl(input, this) matchResult.mode = Mode.FIND matchResult.startIndex = startIndex val foundIndex = startNode.find(startIndex, input, matchResult) if (foundIndex >= 0) { matchResult.finalizeMatch() return matchResult } else { return null } } /** * Returns a sequence of all occurrences of a regular expression within the [input] string, beginning at the specified [startIndex]. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or greater than the length of the [input] char sequence. */ actual fun findAll(input: CharSequence, startIndex: Int): Sequence { if (startIndex < 0 || startIndex > input.length) { throw IndexOutOfBoundsException("Start index is out of bounds: $startIndex, input length: ${input.length}") } return generateSequence({ find(input, startIndex) }, MatchResult::next) } /** * Attempts to match the entire [input] CharSequence against the pattern. * * @return An instance of [MatchResult] if the entire input matches or `null` otherwise. */ actual fun matchEntire(input: CharSequence): MatchResult?= doMatch(input, Mode.MATCH) private fun processReplacement(match: MatchResult, replacement: String): String { val result = StringBuilder(replacement.length) var escaped = false var backReference = false for (ch in replacement) { when { escaped -> { result.append(ch) escaped = false } backReference -> { if (ch !in '0'..'9') { throw IllegalArgumentException("Incorrect back reference: $ch.") } val group = ch - '0' result.append(match.groupValues[group]) // We don't catch IndexOutOfBoundException here because // it's a correct exception in case of a wrong group number. // TODO: But we can rethrow it with more informative message. backReference = false } ch == '\\' -> escaped = true ch == '$' -> backReference = true else -> result.append(ch) } } if (backReference || escaped) { throw IllegalArgumentException("Unexpected end of replacement.") } return result.toString() } /** * Replaces all occurrences of this regular expression in the specified [input] string with * specified [replacement] expression. * * @param replacement A replacement expression that can include substitutions. */ actual fun replace(input: CharSequence, replacement: String): String = replace(input) { match -> processReplacement(match, replacement) } /** * Replaces all occurrences of this regular expression in the specified [input] string with the result of * the given function [transform] that takes [MatchResult] and returns a string to be used as a * replacement for that match. */ actual fun replace(input: CharSequence, transform: (MatchResult) -> CharSequence): String { var match: MatchResult? = find(input) ?: return input.toString() var lastStart = 0 val length = input.length val sb = StringBuilder(length) do { val foundMatch = match!! sb.append(input, lastStart, foundMatch.range.start) sb.append(transform(foundMatch)) lastStart = foundMatch.range.endInclusive + 1 match = foundMatch.next() } while (lastStart < length && match != null) if (lastStart < length) { sb.append(input, lastStart, length) } return sb.toString() } /** * Replaces the first occurrence of this regular expression in the specified [input] string with specified [replacement] expression. * * @param replacement A replacement expression that can include substitutions. */ actual fun replaceFirst(input: CharSequence, replacement: String): String { val match = find(input) ?: return input.toString() val length = input.length val result = StringBuilder(length) result.append(input, 0, match.range.start) result.append(processReplacement(match, replacement)) if (match.range.endInclusive + 1 < length) { result.append(input, match.range.endInclusive + 1, length) } return result.toString() } /** * Splits the [input] CharSequence around matches of this regular expression. * * @param limit Non-negative value specifying the maximum number of substrings the string can be split to. * Zero by default means no limit is set. */ actual fun split(input: CharSequence, limit: Int): List { require(limit >= 0, { "Limit must be non-negative, but was $limit." } ) var match: MatchResult? = find(input) if (match == null || limit == 1) return listOf(input.toString()) val result = ArrayList(if (limit > 0) limit.coerceAtMost(10) else 10) var lastStart = 0 val lastSplit = limit - 1 // negative if there's no limit do { result.add(input.substring(lastStart, match!!.range.start)) lastStart = match.range.endInclusive + 1 if (lastSplit >= 0 && result.size == lastSplit) break match = match.next() } while (match != null) result.add(input.substring(lastStart, input.length)) return result } /** * Returns the string representation of this regular expression, namely the [pattern] of this regular expression. * * Note that another regular expression constructed from the same pattern string may have different [options] * and may match strings differently. */ override fun toString(): String = nativePattern.toString() } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/StringBuilder.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text /** * A mutable sequence of characters. * * String builder can be used to efficiently perform multiple string manipulation operations. */ actual class StringBuilder private constructor ( private var array: CharArray) : CharSequence, Appendable { /** Constructs an empty string builder. */ actual constructor() : this(10) /** Constructs an empty string builder with the specified initial [capacity]. */ actual constructor(capacity: Int) : this(CharArray(capacity)) /** Constructs a string builder that contains the same characters as the specified [content] string. */ actual constructor(content: String) : this(content.toCharArray()) { _length = array.size } /** Constructs a string builder that contains the same characters as the specified [content] char sequence. */ actual constructor(content: CharSequence): this(content.length) { append(content) } // Of CharSequence. private var _length: Int = 0 set(capacity) { ensureCapacity(capacity) field = capacity } actual override val length: Int get() = _length actual override fun get(index: Int): Char { checkIndex(index) return array[index] } actual override fun subSequence(startIndex: Int, endIndex: Int): CharSequence = substring(startIndex, endIndex) // Of Appenable. actual override fun append(value: Char) : StringBuilder { ensureExtraCapacity(1) array[_length++] = value return this } actual override fun append(value: CharSequence?): StringBuilder { // Kotlin/JVM processes null as if the argument was "null" char sequence. val toAppend = value ?: "null" return append(toAppend, 0, toAppend.length) } actual override fun append(value: CharSequence?, startIndex: Int, endIndex: Int): StringBuilder = this.appendRange(value ?: "null", startIndex, endIndex) /** * Reverses the contents of this string builder and returns this instance. * * Surrogate pairs included in this string builder are treated as single characters. * Therefore, the order of the high-low surrogates is never reversed. * * Note that the reverse operation may produce new surrogate pairs that were unpaired low-surrogates and high-surrogates before the operation. * For example, reversing `"\uDC00\uD800"` produces `"\uD800\uDC00"` which is a valid surrogate pair. */ // Based on Apache Harmony implementation. actual fun reverse(): StringBuilder { if (this.length < 2) { return this } var end = _length - 1 var front = 0 var frontLeadingChar = array[0] var endTrailingChar = array[end] var allowFrontSurrogate = true var allowEndSurrogate = true while (front < _length / 2) { var frontTrailingChar = array[front + 1] var endLeadingChar = array[end - 1] var surrogateAtFront = allowFrontSurrogate && frontTrailingChar.isLowSurrogate() && frontLeadingChar.isHighSurrogate() if (surrogateAtFront && _length < 3) { return this } var surrogateAtEnd = allowEndSurrogate && endTrailingChar.isLowSurrogate() && endLeadingChar.isHighSurrogate() allowFrontSurrogate = true allowEndSurrogate = true when { surrogateAtFront && surrogateAtEnd -> { // Both surrogates - just exchange them. array[end] = frontTrailingChar array[end - 1] = frontLeadingChar array[front] = endLeadingChar array[front + 1] = endTrailingChar frontLeadingChar = array[front + 2] endTrailingChar = array[end - 2] front++ end-- } !surrogateAtFront && !surrogateAtEnd -> { // Neither surrogates - exchange only front/end. array[end] = frontLeadingChar array[front] = endTrailingChar frontLeadingChar = frontTrailingChar endTrailingChar = endLeadingChar } surrogateAtFront && !surrogateAtEnd -> { // Surrogate only at the front - // move the low part, the high part will be moved as a usual character on the next iteration. array[end] = frontTrailingChar array[front] = endTrailingChar endTrailingChar = endLeadingChar allowFrontSurrogate = false } !surrogateAtFront && surrogateAtEnd -> { // Surrogate only at the end - // move the high part, the low part will be moved as a usual character on the next iteration. array[end] = frontLeadingChar array[front] = endLeadingChar frontLeadingChar = frontTrailingChar allowEndSurrogate = false } } front++ end-- } if (_length % 2 == 1 && (!allowEndSurrogate || !allowFrontSurrogate)) { array[end] = if (allowFrontSurrogate) endTrailingChar else frontLeadingChar } return this } /** * Appends the string representation of the specified object [value] to this string builder and returns this instance. * * The overall effect is exactly as if the [value] were converted to a string by the `value.toString()` method, * and then that string was appended to this string builder. */ actual fun append(value: Any?): StringBuilder = append(value.toString()) /** * Appends the string representation of the specified boolean [value] to this string builder and returns this instance. * * The overall effect is exactly as if the [value] were converted to a string by the `value.toString()` method, * and then that string was appended to this string builder. */ // TODO: optimize those! actual fun append(value: Boolean): StringBuilder = append(value.toString()) fun append(value: Byte): StringBuilder = append(value.toString()) fun append(value: Short): StringBuilder = append(value.toString()) fun append(value: Int): StringBuilder { ensureExtraCapacity(11) _length += insertInt(array, _length, value) return this } fun append(value: Long): StringBuilder = append(value.toString()) fun append(value: Float): StringBuilder = append(value.toString()) fun append(value: Double): StringBuilder = append(value.toString()) /** * Appends characters in the specified character array [value] to this string builder and returns this instance. * * Characters are appended in order, starting at the index 0. */ actual fun append(value: CharArray): StringBuilder { ensureExtraCapacity(value.size) value.copyInto(array, _length) _length += value.size return this } @Deprecated("Provided for binary compatibility.", level = DeprecationLevel.HIDDEN) fun append(value: String): StringBuilder = append(value) /** * Appends the specified string [value] to this string builder and returns this instance. * * If [value] is `null`, then the four characters `"null"` are appended. */ actual fun append(value: String?): StringBuilder { val toAppend = value ?: "null" ensureExtraCapacity(toAppend.length) _length += insertString(array, _length, toAppend) return this } /** * Returns the current capacity of this string builder. * * The capacity is the maximum length this string builder can have before an allocation occurs. */ actual fun capacity(): Int = array.size /** * Ensures that the capacity of this string builder is at least equal to the specified [minimumCapacity]. * * If the current capacity is less than the [minimumCapacity], a new backing storage is allocated with greater capacity. * Otherwise, this method takes no action and simply returns. */ actual fun ensureCapacity(minimumCapacity: Int) { if (minimumCapacity > array.size) { var newSize = array.size * 2 + 2 if (minimumCapacity > newSize) newSize = minimumCapacity array = array.copyOf(newSize) } } /** * Returns the index within this string builder of the first occurrence of the specified [string]. * * Returns `-1` if the specified [string] does not occur in this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) actual fun indexOf(string: String): Int { return (this as CharSequence).indexOf(string, startIndex = 0, ignoreCase = false) } /** * Returns the index within this string builder of the first occurrence of the specified [string], * starting at the specified [startIndex]. * * Returns `-1` if the specified [string] does not occur in this string builder starting at the specified [startIndex]. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) actual fun indexOf(string: String, startIndex: Int): Int { if (string.isEmpty() && startIndex >= _length) return _length return (this as CharSequence).indexOf(string, startIndex, ignoreCase = false) } /** * Returns the index within this string builder of the last occurrence of the specified [string]. * The last occurrence of empty string `""` is considered to be at the index equal to `this.length`. * * Returns `-1` if the specified [string] does not occur in this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) actual fun lastIndexOf(string: String): Int { if (string.isEmpty()) return _length return (this as CharSequence).lastIndexOf(string, startIndex = lastIndex, ignoreCase = false) } /** * Returns the index within this string builder of the last occurrence of the specified [string], * starting from the specified [startIndex] toward the beginning. * * Returns `-1` if the specified [string] does not occur in this string builder starting at the specified [startIndex]. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) actual fun lastIndexOf(string: String, startIndex: Int): Int { if (string.isEmpty() && startIndex >= _length) return _length return (this as CharSequence).lastIndexOf(string, startIndex, ignoreCase = false) } /** * Inserts the string representation of the specified boolean [value] into this string builder at the specified [index] and returns this instance. * * The overall effect is exactly as if the [value] were converted to a string by the `value.toString()` method, * and then that string was inserted into this string builder at the specified [index]. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ // TODO: optimize those! actual fun insert(index: Int, value: Boolean): StringBuilder = insert(index, value.toString()) fun insert(index: Int, value: Byte) = insert(index, value.toString()) fun insert(index: Int, value: Short) = insert(index, value.toString()) fun insert(index: Int, value: Int) = insert(index, value.toString()) fun insert(index: Int, value: Long) = insert(index, value.toString()) fun insert(index: Int, value: Float) = insert(index, value.toString()) fun insert(index: Int, value: Double) = insert(index, value.toString()) /** * Inserts the specified character [value] into this string builder at the specified [index] and returns this instance. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ actual fun insert(index: Int, value: Char): StringBuilder { checkInsertIndex(index) ensureExtraCapacity(1) val newLastIndex = lastIndex + 1 for (i in newLastIndex downTo index + 1) { array[i] = array[i - 1] } array[index] = value _length++ return this } /** * Inserts characters in the specified character array [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in same order as in the [value] character array, starting at [index]. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ actual fun insert(index: Int, value: CharArray): StringBuilder { checkInsertIndex(index) ensureExtraCapacity(value.size) array.copyInto(array, startIndex = index, endIndex = _length, destinationOffset = index + value.size) value.copyInto(array, destinationOffset = index) _length += value.size return this } /** * Inserts characters in the specified character sequence [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in the same order as in the [value] character sequence, starting at [index]. * * @param index the position in this string builder to insert at. * @param value the character sequence from which characters are inserted. If [value] is `null`, then the four characters `"null"` are inserted. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ actual fun insert(index: Int, value: CharSequence?): StringBuilder { // Kotlin/JVM inserts the "null" string if the argument is null. val toInsert = value ?: "null" return insertRange(index, toInsert, 0, toInsert.length) } /** * Inserts the string representation of the specified object [value] into this string builder at the specified [index] and returns this instance. * * The overall effect is exactly as if the [value] were converted to a string by the `value.toString()` method, * and then that string was inserted into this string builder at the specified [index]. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ actual fun insert(index: Int, value: Any?): StringBuilder = insert(index, value.toString()) @Deprecated("Provided for binary compatibility.", level = DeprecationLevel.HIDDEN) fun insert(index: Int, value: String): StringBuilder = insert(index, value) /** * Inserts the string [value] into this string builder at the specified [index] and returns this instance. * * If [value] is `null`, then the four characters `"null"` are inserted. * * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ actual fun insert(index: Int, value: String?): StringBuilder { val toInsert = value ?: "null" checkInsertIndex(index) ensureExtraCapacity(toInsert.length) array.copyInto(array, startIndex = index, endIndex = _length, destinationOffset = index + toInsert.length) _length += insertString(array, index, toInsert) return this } /** * Sets the length of this string builder to the specified [newLength]. * * If the [newLength] is less than the current length, it is changed to the specified [newLength]. * Otherwise, null characters '\u0000' are appended to this string builder until its length is less than the [newLength]. * * Note that in Kotlin/JS [set] operator function has non-constant execution time complexity. * Therefore, increasing length of this string builder and then updating each character by index may slow down your program. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] if [newLength] is less than zero. */ actual fun setLength(newLength: Int) { if (newLength < 0) { throw IllegalArgumentException("Negative new length: $newLength.") } if (newLength > _length) { array.fill('\u0000', _length, newLength.coerceAtMost(array.size)) } _length = newLength } /** * Returns a new [String] that contains characters in this string builder at [startIndex] (inclusive) and up to the [endIndex] (exclusive). * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this string builder indices or when `startIndex > endIndex`. */ actual fun substring(startIndex: Int, endIndex: Int): String { checkBoundsIndexes(startIndex, endIndex, _length) return unsafeStringFromCharArray(array, startIndex, endIndex - startIndex) } /** * Returns a new [String] that contains characters in this string builder at [startIndex] (inclusive) and up to the [length] (exclusive). * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or greater than the length of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) actual fun substring(startIndex: Int): String { return substring(startIndex, _length) } /** * Attempts to reduce storage used for this string builder. * * If the backing storage of this string builder is larger than necessary to hold its current contents, * then it may be resized to become more space efficient. * Calling this method may, but is not required to, affect the value of the [capacity] property. */ actual fun trimToSize() { if (_length < array.size) array = array.copyOf(_length) } override fun toString(): String = unsafeStringFromCharArray(array, 0, _length) /** * Sets the character at the specified [index] to the specified [value]. * * @throws IndexOutOfBoundsException if [index] is out of bounds of this string builder. */ operator fun set(index: Int, value: Char) { checkIndex(index) array[index] = value } /** * Replaces characters in the specified range of this string builder with characters in the specified string [value] and returns this instance. * * @param startIndex the beginning (inclusive) of the range to replace. * @param endIndex the end (exclusive) of the range to replace. * @param value the string to replace with. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] if [startIndex] is less than zero, greater than the length of this string builder, or `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun setRange(startIndex: Int, endIndex: Int, value: String): StringBuilder { checkReplaceRange(startIndex, endIndex, _length) val coercedEndIndex = endIndex.coerceAtMost(_length) val lengthDiff = value.length - (coercedEndIndex - startIndex) ensureExtraCapacity(_length + lengthDiff) array.copyInto(array, startIndex = coercedEndIndex, endIndex = _length, destinationOffset = startIndex + value.length) var replaceIndex = startIndex for (index in 0 until value.length) array[replaceIndex++] = value[index] // optimize _length += lengthDiff return this } /** * Removes the character at the specified [index] from this string builder and returns this instance. * * If the `Char` at the specified [index] is part of a supplementary code point, this method does not remove the entire supplementary character. * * @param index the index of `Char` to remove. * * @throws IndexOutOfBoundsException if [index] is out of bounds of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun deleteAt(index: Int): StringBuilder { checkIndex(index) array.copyInto(array, startIndex = index + 1, endIndex = _length, destinationOffset = index) --_length return this } /** * Removes characters in the specified range from this string builder and returns this instance. * * @param startIndex the beginning (inclusive) of the range to remove. * @param endIndex the end (exclusive) of the range to remove. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] is out of range of this string builder indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun deleteRange(startIndex: Int, endIndex: Int): StringBuilder { checkReplaceRange(startIndex, endIndex, _length) val coercedEndIndex = endIndex.coerceAtMost(_length) array.copyInto(array, startIndex = coercedEndIndex, endIndex = _length, destinationOffset = startIndex) _length -= coercedEndIndex - startIndex return this } /** * Copies characters from this string builder into the [destination] character array. * * @param destination the array to copy to. * @param destinationOffset the position in the array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the range to copy, 0 by default. * @param endIndex the end (exclusive) of the range to copy, length of this string builder by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this string builder indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun toCharArray(destination: CharArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = this.length) { checkBoundsIndexes(startIndex, endIndex, _length) checkBoundsIndexes(destinationOffset, destinationOffset + endIndex - startIndex, destination.size) array.copyInto(destination, destinationOffset, startIndex, endIndex) } /** * Appends characters in a subarray of the specified character array [value] to this string builder and returns this instance. * * Characters are appended in order, starting at specified [startIndex]. * * @param value the array from which characters are appended. * @param startIndex the beginning (inclusive) of the subarray to append. * @param endIndex the end (exclusive) of the subarray to append. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] array indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun appendRange(value: CharArray, startIndex: Int, endIndex: Int): StringBuilder { checkBoundsIndexes(startIndex, endIndex, value.size) val extraLength = endIndex - startIndex ensureExtraCapacity(extraLength) value.copyInto(array, _length, startIndex, endIndex) _length += extraLength return this } /** * Appends a subsequence of the specified character sequence [value] to this string builder and returns this instance. * * @param value the character sequence from which a subsequence is appended. * @param startIndex the beginning (inclusive) of the subsequence to append. * @param endIndex the end (exclusive) of the subsequence to append. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun appendRange(value: CharSequence, startIndex: Int, endIndex: Int): StringBuilder { checkBoundsIndexes(startIndex, endIndex, value.length) val extraLength = endIndex - startIndex ensureExtraCapacity(extraLength) (value as? String)?.let { _length += insertString(array, _length, it, startIndex, extraLength) return this } var index = startIndex while (index < endIndex) array[_length++] = value[index++] return this } /** * Inserts characters in a subsequence of the specified character sequence [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in the same order as in the [value] character sequence, starting at [index]. * * @param index the position in this string builder to insert at. * @param value the character sequence from which a subsequence is inserted. * @param startIndex the beginning (inclusive) of the subsequence to insert. * @param endIndex the end (exclusive) of the subsequence to insert. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun insertRange(index: Int, value: CharSequence, startIndex: Int, endIndex: Int): StringBuilder { checkBoundsIndexes(startIndex, endIndex, value.length) checkInsertIndex(index) val extraLength = endIndex - startIndex ensureExtraCapacity(extraLength) array.copyInto(array, startIndex = index, endIndex = _length, destinationOffset = index + extraLength) var from = startIndex var to = index while (from < endIndex) { array[to++] = value[from++] } _length += extraLength return this } /** * Inserts characters in a subarray of the specified character array [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in same order as in the [value] array, starting at [index]. * * @param index the position in this string builder to insert at. * @param value the array from which characters are inserted. * @param startIndex the beginning (inclusive) of the subarray to insert. * @param endIndex the end (exclusive) of the subarray to insert. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) fun insertRange(index: Int, value: CharArray, startIndex: Int, endIndex: Int): StringBuilder { checkInsertIndex(index) checkBoundsIndexes(startIndex, endIndex, value.size) val extraLength = endIndex - startIndex array.copyInto(array, startIndex = index, endIndex = _length, destinationOffset = index + extraLength) value.copyInto(array, startIndex = startIndex, endIndex = endIndex, destinationOffset = index) _length += extraLength return this } // ---------------------------- private ---------------------------- private fun ensureExtraCapacity(n: Int) { ensureCapacity(_length + n) } private fun checkIndex(index: Int) { if (index < 0 || index >= _length) throw IndexOutOfBoundsException() } private fun checkInsertIndex(index: Int) { if (index < 0 || index > _length) throw IndexOutOfBoundsException() } private fun checkInsertIndexFrom(index: Int, fromIndex: Int) { if (index < fromIndex || index > _length) throw IndexOutOfBoundsException() } private fun checkReplaceRange(startIndex: Int, endIndex: Int, length: Int) { if (startIndex < 0 || startIndex > length) { throw IndexOutOfBoundsException("startIndex: $startIndex, length: $length") } if (startIndex > endIndex) { throw IllegalArgumentException("startIndex($startIndex) > endIndex($endIndex)") } } } /** * Clears the content of this string builder making it empty. * * @sample samples.text.Strings.clearStringBuilder */ @SinceKotlin("1.3") public actual fun StringBuilder.clear(): StringBuilder = apply { setLength(0) } /** * Sets the character at the specified [index] to the specified [value]. * * @throws IndexOutOfBoundsException if [index] is out of bounds of this string builder. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline operator fun StringBuilder.set(index: Int, value: Char): Unit = this.set(index, value) /** * Replaces characters in the specified range of this string builder with characters in the specified string [value] and returns this instance. * * @param startIndex the beginning (inclusive) of the range to replace. * @param endIndex the end (exclusive) of the range to replace. * @param value the string to replace with. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] if [startIndex] is less than zero, greater than the length of this string builder, or `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.setRange(startIndex: Int, endIndex: Int, value: String): StringBuilder = this.setRange(startIndex, endIndex, value) /** * Removes the character at the specified [index] from this string builder and returns this instance. * * If the `Char` at the specified [index] is part of a supplementary code point, this method does not remove the entire supplementary character. * * @param index the index of `Char` to remove. * * @throws IndexOutOfBoundsException if [index] is out of bounds of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.deleteAt(index: Int): StringBuilder = this.deleteAt(index) /** * Removes characters in the specified range from this string builder and returns this instance. * * @param startIndex the beginning (inclusive) of the range to remove. * @param endIndex the end (exclusive) of the range to remove. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this string builder indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.deleteRange(startIndex: Int, endIndex: Int): StringBuilder = this.deleteRange(startIndex, endIndex) /** * Copies characters from this string builder into the [destination] character array. * * @param destination the array to copy to. * @param destinationOffset the position in the array to copy to, 0 by default. * @param startIndex the beginning (inclusive) of the range to copy, 0 by default. * @param endIndex the end (exclusive) of the range to copy, length of this string builder by default. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this string builder indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationOffset], * or when that index is out of the [destination] array indices range. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.toCharArray(destination: CharArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = this.length) = this.toCharArray(destination, destinationOffset, startIndex, endIndex) /** * Appends characters in a subarray of the specified character array [value] to this string builder and returns this instance. * * Characters are appended in order, starting at specified [startIndex]. * * @param value the array from which characters are appended. * @param startIndex the beginning (inclusive) of the subarray to append. * @param endIndex the end (exclusive) of the subarray to append. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] array indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.appendRange(value: CharArray, startIndex: Int, endIndex: Int): StringBuilder = this.appendRange(value, startIndex, endIndex) /** * Appends a subsequence of the specified character sequence [value] to this string builder and returns this instance. * * @param value the character sequence from which a subsequence is appended. * @param startIndex the beginning (inclusive) of the subsequence to append. * @param endIndex the end (exclusive) of the subsequence to append. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.appendRange(value: CharSequence, startIndex: Int, endIndex: Int): StringBuilder = this.appendRange(value, startIndex, endIndex) /** * Inserts characters in a subarray of the specified character array [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in same order as in the [value] array, starting at [index]. * * @param index the position in this string builder to insert at. * @param value the array from which characters are inserted. * @param startIndex the beginning (inclusive) of the subarray to insert. * @param endIndex the end (exclusive) of the subarray to insert. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] array indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.insertRange(index: Int, value: CharArray, startIndex: Int, endIndex: Int): StringBuilder = this.insertRange(index, value, startIndex, endIndex) /** * Inserts characters in a subsequence of the specified character sequence [value] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in the same order as in the [value] character sequence, starting at [index]. * * @param index the position in this string builder to insert at. * @param value the character sequence from which a subsequence is inserted. * @param startIndex the beginning (inclusive) of the subsequence to insert. * @param endIndex the end (exclusive) of the subsequence to insert. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ @SinceKotlin("1.4") @WasExperimental(ExperimentalStdlibApi::class) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @kotlin.internal.InlineOnly public actual inline fun StringBuilder.insertRange(index: Int, value: CharSequence, startIndex: Int, endIndex: Int): StringBuilder = this.insertRange(index, value, startIndex, endIndex) // Method parameters renamings @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Boolean) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Boolean): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Byte) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Byte): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Short) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Short): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Int) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Int): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Long) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Long): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Float) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Float): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: Double) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: Double): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: String) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: String): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use append(value: CharArray) instead", ReplaceWith("append(value = it)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.append(it: CharArray): StringBuilder = this.append(value = it) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use ensureCapacity(minimumCapacity: Int) instead", ReplaceWith("ensureCapacity(minimumCapacity = capacity)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.ensureCapacity(capacity: Int): Unit = this.ensureCapacity(minimumCapacity = capacity) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use insert(index: Int, value: Char) instead", ReplaceWith("insert(index, value = c)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.insert(index: Int, c: Char): StringBuilder = this.insert(index, value = c) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use insert(index: Int, value: CharArray) instead", ReplaceWith("insert(index, value = chars)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.insert(index: Int, chars: CharArray): StringBuilder = this.insert(index, value = chars) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use insert(index: Int, value: CharSequence?) instead", ReplaceWith("insert(index, value = csq)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.insert(index: Int, csq: CharSequence?): StringBuilder = this.insert(index, value = csq) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use insert(index: Int, value: String) instead", ReplaceWith("insert(index, value = string)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.insert(index: Int, string: String): StringBuilder = this.insert(index, value = string) @Suppress("EXTENSION_SHADOWED_BY_MEMBER") @Deprecated("Use setLength(newLength: Int) instead", ReplaceWith("setLength(newLength = l)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.setLength(l: Int) = this.setLength(newLength = l) // Method renamings /** * Inserts characters in a subsequence of the specified character sequence [csq] into this string builder at the specified [index] and returns this instance. * * The inserted characters go in the same order as in the [csq] character sequence, starting at [index]. * * @param index the position in this string builder to insert at. * @param csq the character sequence from which a subsequence is inserted. If [csq] is `null`, * then characters will be inserted as if [csq] contained the four characters `"null"`. * @param start the beginning (inclusive) of the subsequence to insert. * @param end the end (exclusive) of the subsequence to insert. * * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [start] or [end] is out of range of the [csq] character sequence indices or when `start > end`. * @throws IndexOutOfBoundsException if [index] is less than zero or greater than the length of this string builder. */ @Deprecated( "Use insertRange(index: Int, csq: CharSequence, start: Int, end: Int) instead", ReplaceWith("insertRange(index, csq ?: \"null\", start, end)"), DeprecationLevel.WARNING ) @kotlin.internal.InlineOnly public inline fun StringBuilder.insert(index: Int, csq: CharSequence?, start: Int, end: Int): StringBuilder = this.insertRange(index, csq ?: "null", start, end) @Deprecated("Use set(index: Int, value: Char) instead", ReplaceWith("set(index, value)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.setCharAt(index: Int, value: Char) = this.set(index, value) /** * Removes the character at the specified [index] from this string builder and returns this instance. * * If the `Char` at the specified [index] is part of a supplementary code point, this method does not remove the entire supplementary character. * * @param index the index of `Char` to remove. * * @throws IndexOutOfBoundsException if [index] is out of bounds of this string builder. */ @Deprecated("Use deleteAt(index: Int) instead", ReplaceWith("deleteAt(index)"), DeprecationLevel.WARNING) @kotlin.internal.InlineOnly public inline fun StringBuilder.deleteCharAt(index: Int) = this.deleteAt(index) ================================================ FILE: runtime/src/main/kotlin/kotlin/text/StringBuilderNative.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Byte): StringBuilder = append(value).appendLine() /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Short): StringBuilder = append(value).appendLine() /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Int): StringBuilder = append(value).appendLine() /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Long): StringBuilder = append(value).appendLine() /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Float): StringBuilder = append(value).appendLine() /** Appends [value] to this [StringBuilder], followed by a line feed character (`\n`). */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public inline fun StringBuilder.appendLine(value: Double): StringBuilder = append(value).appendLine() @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: String): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Boolean): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Byte): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Short): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Int): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Long): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Float): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Double): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine(it)"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(it: Any?): StringBuilder = appendLine(it) @Deprecated("Use appendLine instead", ReplaceWith("appendLine()"), level = DeprecationLevel.WARNING) public fun StringBuilder.appendln(): StringBuilder = appendLine() ================================================ FILE: runtime/src/main/kotlin/kotlin/text/StringNumberConversions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text import kotlin.native.internal.FloatingPointParser /** * Returns a string representation of this [Byte] value in the specified [radix]. * * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun Byte.toString(radix: Int): String = this.toInt().toString(checkRadix(radix)) /** * Returns a string representation of this [Short] value in the specified [radix]. * * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun Short.toString(radix: Int): String = this.toInt().toString(checkRadix(radix)) @SymbolName("Kotlin_Int_toStringRadix") @PublishedApi external internal fun intToString(value: Int, radix: Int): String /** * Returns a string representation of this [Int] value in the specified [radix]. * * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun Int.toString(radix: Int): String = intToString(this, checkRadix(radix)) @SymbolName("Kotlin_Long_toStringRadix") @PublishedApi external internal fun longToString(value: Long, radix: Int): String /** * Returns a string representation of this [Long] value in the specified [radix]. * * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun Long.toString(radix: Int): String = longToString(this, checkRadix(radix)) /** * Returns `true` if the content of this string is equal to the word "true", ignoring case, and `false` otherwise. */ @Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") @DeprecatedSinceKotlin(hiddenSince = "1.4") @kotlin.internal.InlineOnly public actual inline fun String.toBoolean(): Boolean = this.toBoolean() /** * Returns `true` if this string is not `null` and its content is equal to the word "true", ignoring case, and `false` otherwise. */ @SinceKotlin("1.4") @kotlin.internal.InlineOnly public actual inline fun String?.toBoolean(): Boolean = this.equals("true", ignoreCase = true) /** * Parses the string as a signed [Byte] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toByte(): Byte = toByteOrNull() ?: throw NumberFormatException() /** * Parses the string as a signed [Byte] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun String.toByte(radix: Int): Byte = toByteOrNull(radix) ?: throw NumberFormatException() /** * Parses the string as a [Short] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toShort(): Short = toShortOrNull() ?: throw NumberFormatException() /** * Parses the string as a [Short] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun String.toShort(radix: Int): Short = toShortOrNull(radix) ?: throw NumberFormatException() /** * Parses the string as an [Int] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toInt(): Int = toIntOrNull() ?: throw NumberFormatException() /** * Parses the string as an [Int] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun String.toInt(radix: Int): Int = toIntOrNull(radix) ?: throw NumberFormatException() /** * Parses the string as a [Long] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toLong(): Long = toLongOrNull() ?: throw NumberFormatException() /** * Parses the string as a [Long] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public actual inline fun String.toLong(radix: Int): Long = toLongOrNull(radix) ?: throw NumberFormatException() /** * Parses the string as a [Float] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toFloat(): Float = FloatingPointParser.parseFloat(this) /** * Parses the string as a [Double] number and returns the result. * @throws NumberFormatException if the string is not a valid representation of a number. */ @kotlin.internal.InlineOnly public actual inline fun String.toDouble(): Double = FloatingPointParser.parseDouble(this) /** * Parses the string as a [Float] number and returns the result * or `null` if the string is not a valid representation of a number. */ @SinceKotlin("1.1") public actual fun String.toFloatOrNull(): Float? { try { return toFloat() } catch (e: NumberFormatException) { return null } } /** * Parses the string as a [Double] number and returns the result * or `null` if the string is not a valid representation of a number. */ @SinceKotlin("1.1") public actual fun String.toDoubleOrNull(): Double? { try { return toDouble() } catch (e: NumberFormatException) { return null } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/Strings.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package kotlin.text import kotlin.native.concurrent.SharedImmutable /** * Returns the index within this string of the first occurrence of the specified character, starting from the specified offset. */ @SymbolName("Kotlin_String_indexOfChar") internal actual external fun String.nativeIndexOf(ch: Char, fromIndex: Int): Int /** * Returns the index within this string of the first occurrence of the specified substring, starting from the specified offset. */ @SymbolName("Kotlin_String_indexOfString") internal actual external fun String.nativeIndexOf(str: String, fromIndex: Int): Int /** * Returns the index within this string of the last occurrence of the specified character. */ @SymbolName("Kotlin_String_lastIndexOfChar") internal actual external fun String.nativeLastIndexOf(ch: Char, fromIndex: Int): Int /** * Returns the index within this string of the last occurrence of the specified character, starting from the specified offset. */ @SymbolName("Kotlin_String_lastIndexOfString") internal actual external fun String.nativeLastIndexOf(str: String, fromIndex: Int): Int /** * Returns `true` if this string is equal to [other], optionally ignoring character case. * * @param ignoreCase `true` to ignore character case when comparing strings. By default `false`. */ public actual fun String?.equals(other: String?, ignoreCase: Boolean): Boolean { if (this === null) return other === null if (other === null) return false return if (!ignoreCase) this.equals(other) else if (length != other.length) false else unsafeRangeEqualsIgnoreCase(0, other, 0, length) } /** * Returns a new string with all occurrences of [oldChar] replaced with [newChar]. */ public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean): String { return if (!ignoreCase) replace(oldChar, newChar) else replaceIgnoreCase(oldChar, newChar) } @SymbolName("Kotlin_String_replace") private external fun String.replace(oldChar: Char, newChar: Char): String @OptIn(ExperimentalStdlibApi::class) private fun String.replaceIgnoreCase(oldChar: Char, newChar: Char): String { val charArray = CharArray(length) val oldCharLower = oldChar.lowercaseChar() for (index in 0 until length) { val thisChar = this[index] val thisCharLower = thisChar.lowercaseChar() charArray[index] = if (thisCharLower == oldCharLower) newChar else thisChar } return charArray.concatToString() } /** * Returns a new string obtained by replacing all occurrences of the [oldValue] substring in this string * with the specified [newValue] string. */ public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean): String = splitToSequence(oldValue, ignoreCase = ignoreCase).joinToString(separator = newValue) /** * Returns a new string with the first occurrence of [oldChar] replaced with [newChar]. */ public actual fun String.replaceFirst(oldChar: Char, newChar: Char, ignoreCase: Boolean): String { val index = indexOf(oldChar, ignoreCase = ignoreCase) return if (index < 0) this else this.replaceRange(index, index + 1, newChar.toString()) } /** * Returns a new string obtained by replacing the first occurrence of the [oldValue] substring in this string * with the specified [newValue] string. */ public actual fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: Boolean): String { val index = indexOf(oldValue, ignoreCase = ignoreCase) return if (index < 0) this else this.replaceRange(index, index + oldValue.length, newValue) } /** * Returns `true` if this string is empty or consists solely of whitespace characters. * * @sample samples.text.Strings.stringIsBlank */ public actual fun CharSequence.isBlank(): Boolean = length == 0 || indices.all { this[it].isWhitespace() } /** * Returns the substring of this string starting at the [startIndex] and ending right before the [endIndex]. * * @param startIndex the start index (inclusive). * @param endIndex the end index (exclusive). */ @kotlin.internal.InlineOnly public actual inline fun String.substring(startIndex: Int, endIndex: Int): String = subSequence(startIndex, endIndex) as String /** * Returns a substring of this string that starts at the specified [startIndex] and continues to the end of the string. */ @kotlin.internal.InlineOnly public actual inline fun String.substring(startIndex: Int): String = subSequence(startIndex, this.length) as String /** * Returns `true` if this string starts with the specified prefix. */ public actual fun String.startsWith(prefix: String, ignoreCase: Boolean): Boolean = regionMatches(0, prefix, 0, prefix.length, ignoreCase) /** * Returns `true` if a substring of this string starting at the specified offset [startIndex] starts with the specified prefix. */ public actual fun String.startsWith(prefix: String, startIndex: Int, ignoreCase: Boolean): Boolean = regionMatches(startIndex, prefix, 0, prefix.length, ignoreCase) /** * Returns `true` if this string ends with the specified suffix. */ public actual fun String.endsWith(suffix: String, ignoreCase: Boolean): Boolean = regionMatches(length - suffix.length, suffix, 0, suffix.length, ignoreCase) /** * Returns `true` if the specified range in this char sequence is equal to the specified range in another char sequence. * @param thisOffset the start offset in this char sequence of the substring to compare. * @param other the string against a substring of which the comparison is performed. * @param otherOffset the start offset in the other char sequence of the substring to compare. * @param length the length of the substring to compare. */ public actual fun CharSequence.regionMatches( thisOffset: Int, other: CharSequence, otherOffset: Int, length: Int, ignoreCase: Boolean): Boolean { return if (this is String && other is String) { this.regionMatches(thisOffset, other, otherOffset, length, ignoreCase) } else { regionMatchesImpl(thisOffset, other, otherOffset, length, ignoreCase) } } /** * Returns `true` if the specified range in this string is equal to the specified range in another string. * @param thisOffset the start offset in this string of the substring to compare. * @param other the string against a substring of which the comparison is performed. * @param otherOffset the start offset in the other string of the substring to compare. * @param length the length of the substring to compare. */ public fun String.regionMatches( thisOffset: Int, other: String, otherOffset: Int, length: Int, ignoreCase: Boolean = false): Boolean { if (length < 0 || thisOffset < 0 || otherOffset < 0 || thisOffset + length > this.length || otherOffset + length > other.length) { return false } return if (!ignoreCase) unsafeRangeEquals(thisOffset, other, otherOffset, length) else unsafeRangeEqualsIgnoreCase(thisOffset, other, otherOffset, length) } // Bounds must be checked before calling this method @SymbolName("Kotlin_String_unsafeRangeEquals") private external fun String.unsafeRangeEquals(thisOffset: Int, other: String, otherOffset: Int, length: Int): Boolean // Bounds must be checked before calling this method @OptIn(ExperimentalStdlibApi::class) private fun String.unsafeRangeEqualsIgnoreCase(thisOffset: Int, other: String, otherOffset: Int, length: Int): Boolean { for (index in 0 until length) { val thisCharLower = this[thisOffset + index].lowercaseChar() val otherCharLower = other[otherOffset + index].lowercaseChar() if (thisCharLower != otherCharLower) { return false } } return true } /** * Returns a copy of this string converted to upper case using the rules of the default locale. */ public actual fun String.toUpperCase(): String = uppercaseImpl() /** * Returns a copy of this string converted to upper case using Unicode mapping rules of the invariant locale. * * This function supports one-to-many and many-to-one character mapping, * thus the length of the returned string can be different from the length of the original string. * * @sample samples.text.Strings.uppercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun String.uppercase(): String = uppercaseImpl() /** * Returns a copy of this string converted to lower case using the rules of the default locale. */ public actual fun String.toLowerCase(): String = lowercaseImpl() /** * Returns a copy of this string converted to lower case using Unicode mapping rules of the invariant locale. * * This function supports one-to-many and many-to-one character mapping, * thus the length of the returned string can be different from the length of the original string. * * @sample samples.text.Strings.lowercase */ @SinceKotlin("1.4") @ExperimentalStdlibApi public actual fun String.lowercase(): String = lowercaseImpl() /** * Returns a [CharArray] containing characters of this string. */ public actual fun String.toCharArray(): CharArray = toCharArray(this, 0, length) @SymbolName("Kotlin_String_toCharArray") private external fun toCharArray(string: String, start: Int, size: Int): CharArray /** * Returns a copy of this string having its first letter titlecased using the rules of the default locale, * or the original string if it's empty or already starts with a title case letter. * * The title case of a character is usually the same as its upper case with several exceptions. * The particular list of characters with the special title case form depends on the underlying platform. * * @sample samples.text.Strings.capitalize */ public actual fun String.capitalize(): String { return if (isNotEmpty() && this[0].isLowerCase()) substring(0, 1).toUpperCase() + substring(1) else this } /** * Returns a copy of this string having its first letter lowercased using the rules of the default locale, * or the original string if it's empty or already starts with a lower case letter. * * @sample samples.text.Strings.decapitalize */ public actual fun String.decapitalize(): String { return if (isNotEmpty() && !this[0].isLowerCase()) substring(0, 1).toLowerCase() + substring(1) else this } /** * Returns a string containing this char sequence repeated [n] times. * @throws [IllegalArgumentException] when n < 0. * @sample samples.text.Strings.repeat */ public actual fun CharSequence.repeat(n: Int): String { require(n >= 0) { "Count 'n' must be non-negative, but was $n." } return when (n) { 0 -> "" 1 -> this.toString() else -> { when (length) { 0 -> "" 1 -> this[0].let { char -> CharArray(n) { char }.concatToString() } else -> { val sb = StringBuilder(n * length) for (i in 1..n) { sb.append(this) } sb.toString() } } } } } /** * Converts the characters in the specified array to a string. */ @Deprecated("Use CharArray.concatToString() instead", ReplaceWith("chars.concatToString()")) public actual fun String(chars: CharArray): String = chars.concatToString() /** * Converts the characters from a portion of the specified array to a string. * * @throws IndexOutOfBoundsException if either [offset] or [length] are less than zero * or `offset + length` is out of [chars] array bounds. */ @Deprecated("Use CharArray.concatToString(startIndex, endIndex) instead", ReplaceWith("chars.concatToString(offset, offset + length)")) public actual fun String(chars: CharArray, offset: Int, length: Int): String { if (offset < 0 || length < 0 || offset + length > chars.size) throw ArrayIndexOutOfBoundsException() return unsafeStringFromCharArray(chars, offset, length) } /** * Concatenates characters in this [CharArray] into a String. */ @SinceKotlin("1.3") public actual fun CharArray.concatToString(): String = unsafeStringFromCharArray(this, 0, size) /** * Concatenates characters in this [CharArray] or its subrange into a String. * * @param startIndex the beginning (inclusive) of the subrange of characters, 0 by default. * @param endIndex the end (exclusive) of the subrange of characters, size of this array by default. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. */ @SinceKotlin("1.3") public actual fun CharArray.concatToString(startIndex: Int, endIndex: Int): String { checkBoundsIndexes(startIndex, endIndex, size) return unsafeStringFromCharArray(this, startIndex, endIndex - startIndex) } /** * Returns a [CharArray] containing characters of this string or its substring. * * @param startIndex the beginning (inclusive) of the substring, 0 by default. * @param endIndex the end (exclusive) of the substring, length of this string by default. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. */ @SinceKotlin("1.3") public actual fun String.toCharArray(startIndex: Int, endIndex: Int): CharArray { checkBoundsIndexes(startIndex, endIndex, length) return toCharArray(this, startIndex, endIndex - startIndex) } /** * Decodes a string from the bytes in UTF-8 encoding in this array. * * Malformed byte sequences are replaced by the replacement char `\uFFFD`. */ @SinceKotlin("1.3") public actual fun ByteArray.decodeToString(): String = unsafeStringFromUtf8(0, size) /** * Decodes a string from the bytes in UTF-8 encoding in this array or its subrange. * * @param startIndex the beginning (inclusive) of the subrange to decode, 0 by default. * @param endIndex the end (exclusive) of the subrange to decode, size of this array by default. * @param throwOnInvalidSequence specifies whether to throw an exception on malformed byte sequence or replace it by the replacement char `\uFFFD`. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. * @throws CharacterCodingException if the byte array contains malformed UTF-8 byte sequence and [throwOnInvalidSequence] is true. */ @SinceKotlin("1.3") public actual fun ByteArray.decodeToString(startIndex: Int, endIndex: Int, throwOnInvalidSequence: Boolean): String { checkBoundsIndexes(startIndex, endIndex, size) return if (throwOnInvalidSequence) unsafeStringFromUtf8OrThrow(startIndex, endIndex - startIndex) else unsafeStringFromUtf8(startIndex, endIndex - startIndex) } /** * Encodes this string to an array of bytes in UTF-8 encoding. * * Any malformed char sequence is replaced by the replacement byte sequence. */ @SinceKotlin("1.3") public actual fun String.encodeToByteArray(): ByteArray = unsafeStringToUtf8(0, length) /** * Encodes this string or its substring to an array of bytes in UTF-8 encoding. * * @param startIndex the beginning (inclusive) of the substring to encode, 0 by default. * @param endIndex the end (exclusive) of the substring to encode, length of this string by default. * @param throwOnInvalidSequence specifies whether to throw an exception on malformed char sequence or replace. * * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. * @throws CharacterCodingException if this string contains malformed char sequence and [throwOnInvalidSequence] is true. */ @SinceKotlin("1.3") public actual fun String.encodeToByteArray(startIndex: Int, endIndex: Int, throwOnInvalidSequence: Boolean): ByteArray { checkBoundsIndexes(startIndex, endIndex, length) return if (throwOnInvalidSequence) unsafeStringToUtf8OrThrow(startIndex, endIndex - startIndex) else unsafeStringToUtf8(startIndex, endIndex - startIndex) } @OptIn(ExperimentalStdlibApi::class) internal fun compareToIgnoreCase(thiz: String, other: String): Int { val length = minOf(thiz.length, other.length) for (index in 0 until length) { val thisLowerChar = thiz[index].lowercaseChar() val otherLowerChar = other[index].lowercaseChar() if (thisLowerChar != otherLowerChar) { return if (thisLowerChar < otherLowerChar) -1 else 1 } } return if (thiz.length == other.length) 0 else if (thiz.length < other.length) -1 else 1 } public actual fun String.compareTo(other: String, ignoreCase: Boolean): Int { return if (!ignoreCase) this.compareTo(other) else compareToIgnoreCase(this, other) } @SharedImmutable private val STRING_CASE_INSENSITIVE_ORDER = Comparator { a, b -> a.compareTo(b, ignoreCase = true) } public actual val String.Companion.CASE_INSENSITIVE_ORDER: Comparator get() = STRING_CASE_INSENSITIVE_ORDER ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex import kotlin.collections.associate import kotlin.native.concurrent.AtomicReference import kotlin.native.concurrent.freeze /** * Unicode category (i.e. Ll, Lu). */ internal open class UnicodeCategory(protected val category: Int) : AbstractCharClass() { override fun contains(ch: Int): Boolean = alt xor (ch.toChar().category.value == category) } /** * Unicode category scope (i.e IsL, IsM, ...) */ internal class UnicodeCategoryScope(category: Int) : UnicodeCategory(category) { override fun contains(ch: Int): Boolean { return alt xor (((category shr ch.toChar().category.value) and 1) != 0) } } /** * This class represents character classes, i.e. sets of character either predefined or user defined. * Note: this class represent a token, not node, so being constructed by lexer. */ internal abstract class AbstractCharClass : SpecialToken() { /** * Show if the class has alternative meaning: * if the class contains character 'a' and alt == true then the class will contains all characters except 'a'. */ internal var alt: Boolean = false internal var altSurrogates: Boolean = false internal val lowHighSurrogates = BitSet(SURROGATE_CARDINALITY) // Bit set for surrogates? /* * Indicates if this class may contain supplementary Unicode codepoints. * If this flag is specified it doesn't mean that this class contains supplementary characters but may contain. */ var mayContainSupplCodepoints = false protected set /** Returns true if this char class contains character specified. */ abstract operator fun contains(ch: Int): Boolean open fun contains(ch: Char): Boolean = contains(ch.toInt()) /** * Returns BitSet representing this character class or `null` * if this character class does not have character representation; */ open internal val bits: BitSet? get() = null fun hasLowHighSurrogates(): Boolean { return if (altSurrogates) lowHighSurrogates.nextClearBit(0) != -1 else lowHighSurrogates.nextSetBit(0) != -1 } override val type: Type = Type.CHARCLASS open val instance: AbstractCharClass get() = this private val surrogates_ = AtomicReference(null) fun classWithSurrogates(): AbstractCharClass { surrogates_.value?.let { return it } val surrogates = lowHighSurrogates val result = object : AbstractCharClass() { override fun contains(ch: Int): Boolean { val index = ch - Char.MIN_SURROGATE.toInt() return if (index >= 0 && index < AbstractCharClass.SURROGATE_CARDINALITY) { this.altSurrogates xor surrogates[index] } else { false } } } result.setNegative(this.altSurrogates) surrogates_.compareAndSet(null, result.freeze()) return surrogates_.value!! } // We cannot cache this class as we've done with surrogates above because // here is a circular reference between it and AbstractCharClass. fun classWithoutSurrogates(): AbstractCharClass { val result = object : AbstractCharClass() { override fun contains(ch: Int): Boolean { val index = ch - Char.MIN_SURROGATE.toInt() val containslHS = if (index >= 0 && index < AbstractCharClass.SURROGATE_CARDINALITY) this.altSurrogates xor this@AbstractCharClass.lowHighSurrogates.get(index) else false return this@AbstractCharClass.contains(ch) && !containslHS } } result.setNegative(isNegative()) result.mayContainSupplCodepoints = mayContainSupplCodepoints return result } /** * Sets this CharClass to negative form, i.e. if they will add some characters and after that set this * class to negative it will accept all the characters except previously set ones. * * Although this method will not alternate all the already set characters, * just overall meaning of the class. */ fun setNegative(value: Boolean): AbstractCharClass { if (alt xor value) { alt = !alt altSurrogates = !altSurrogates } if (!mayContainSupplCodepoints) { mayContainSupplCodepoints = true } return this } fun isNegative(): Boolean { return alt } internal abstract class CachedCharClass { lateinit private var posValue: AbstractCharClass lateinit private var negValue: AbstractCharClass // Somewhat ugly init sequence, as computeValue() may depend on fields, initialized in subclass ctor. protected fun initValues() { posValue = computeValue() negValue = computeValue().setNegative(true) } fun getValue(negative: Boolean): AbstractCharClass = if (!negative) posValue else negValue protected abstract fun computeValue(): AbstractCharClass } internal class CachedDigit : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('0', '9') } internal class CachedNonDigit : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('0', '9').setNegative(true).apply { mayContainSupplCodepoints = true } } internal class CachedSpace : CachedCharClass() { init { initValues() } /* 9-13 - \t\n\x0B\f\r; 32 - ' ' */ override fun computeValue(): AbstractCharClass = CharClass().add(9, 13).add(32) } internal class CachedNonSpace : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CachedSpace().getValue(negative = true).apply { mayContainSupplCodepoints = true } } internal class CachedWord : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z').add('A', 'Z').add('0', '9').add('_') } internal class CachedNonWord : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CachedWord().getValue(negative = true).apply { mayContainSupplCodepoints = true } } internal class CachedLower : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z') } internal class CachedUpper : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('A', 'Z') } internal class CachedASCII : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add(0x00, 0x7F) } internal class CachedAlpha : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('a', 'z').add('A', 'Z') } internal class CachedAlnum : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = (CachedAlpha().getValue(negative = false) as CharClass).add('0', '9') } internal class CachedPunct : CachedCharClass() { init { initValues() } /* Punctuation !"#$%&'()*+,-./:;<=>?@ [\]^_` {|}~ */ override fun computeValue(): AbstractCharClass = CharClass().add(0x21, 0x40).add(0x5B, 0x60).add(0x7B, 0x7E) } internal class CachedGraph : CachedCharClass() { init { initValues() } /* plus punctuation */ override fun computeValue(): AbstractCharClass = (CachedAlnum().getValue(negative = false) as CharClass) .add(0x21, 0x40) .add(0x5B, 0x60) .add(0x7B, 0x7E) } internal class CachedPrint : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = (CachedGraph().getValue(negative = true) as CharClass).add(0x20) } internal class CachedBlank : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add(' ').add('\t') } internal class CachedCntrl : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add(0x00, 0x1F).add(0x7F) } internal class CachedXDigit : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = CharClass().add('0', '9').add('a', 'f').add('A', 'F') } internal class CachedRange(var start: Int, var end: Int) : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass = object: AbstractCharClass() { override fun contains(ch: Int): Boolean = alt xor (ch in start..end) }.apply { if (end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) { mayContainSupplCodepoints = true } val minSurrogate = Char.MIN_SURROGATE.toInt() val maxSurrogate = Char.MAX_SURROGATE.toInt() // There is an intersection with surrogate characters. if (end >= minSurrogate && start <= maxSurrogate && start <= end) { val surrogatesStart = maxOf(start, minSurrogate) - minSurrogate val surrogatesEnd = minOf(end, maxSurrogate) - minSurrogate lowHighSurrogates.set(surrogatesStart..surrogatesEnd) } } } internal class CachedSpecialsBlock : CachedCharClass() { init { initValues() } public override fun computeValue(): AbstractCharClass = CharClass().add(0xFEFF, 0xFEFF).add(0xFFF0, 0xFFFD) } internal class CachedCategoryScope( val category: Int, val mayContainSupplCodepoints: Boolean, val containsAllSurrogates: Boolean = false) : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass { val result = UnicodeCategoryScope(category) if (containsAllSurrogates) { result.lowHighSurrogates.set(0, SURROGATE_CARDINALITY) } result.mayContainSupplCodepoints = mayContainSupplCodepoints return result } } internal class CachedCategory( val category: Int, val mayContainSupplCodepoints: Boolean, val containsAllSurrogates: Boolean = false) : CachedCharClass() { init { initValues() } override fun computeValue(): AbstractCharClass { val result = UnicodeCategory(category) if (containsAllSurrogates) { result.lowHighSurrogates.set(0, SURROGATE_CARDINALITY) } result.mayContainSupplCodepoints = mayContainSupplCodepoints return result } } companion object { //Char.MAX_SURROGATE - Char.MIN_SURROGATE + 1 const val SURROGATE_CARDINALITY = 2048 /** * Character classes. * See http://www.unicode.org/reports/tr18/, http://www.unicode.org/Public/4.1.0/ucd/Blocks.txt */ enum class CharClasses(val regexName : String, val factory: () -> CachedCharClass) { LOWER("Lower", ::CachedLower), UPPER("Upper", ::CachedUpper), ASCII("ASCII", ::CachedASCII), ALPHA("Alpha", ::CachedAlpha), DIGIT("Digit", ::CachedDigit), ALNUM("Alnum", :: CachedAlnum), PUNCT("Punct", ::CachedPunct), GRAPH("Graph", ::CachedGraph), PRINT("Print", ::CachedPrint), BLANK("Blank", ::CachedBlank), CNTRL("Cntrl", ::CachedCntrl), XDIGIT("XDigit", ::CachedXDigit), SPACE("Space", ::CachedSpace), WORD("w", ::CachedWord), NON_WORD("W", ::CachedNonWord), SPACE_SHORT("s", ::CachedSpace), NON_SPACE("S", ::CachedNonSpace), DIGIT_SHORT("d", ::CachedDigit), NON_DIGIT("D", ::CachedNonDigit), BASIC_LATIN("BasicLatin", { CachedRange(0x0000, 0x007F) }), LATIN1_SUPPLEMENT("Latin-1Supplement", { CachedRange(0x0080, 0x00FF) }), LATIN_EXTENDED_A("LatinExtended-A", { CachedRange(0x0100, 0x017F) }), LATIN_EXTENDED_B("LatinExtended-B", { CachedRange(0x0180, 0x024F) }), IPA_EXTENSIONS("IPAExtensions", { CachedRange(0x0250, 0x02AF) }), SPACING_MODIFIER_LETTERS("SpacingModifierLetters", { CachedRange(0x02B0, 0x02FF) }), COMBINING_DIACRITICAL_MARKS("CombiningDiacriticalMarks", { CachedRange(0x0300, 0x036F) }), GREEK("Greek", { CachedRange(0x0370, 0x03FF) }), CYRILLIC("Cyrillic", { CachedRange(0x0400, 0x04FF) }), CYRILLIC_SUPPLEMENT("CyrillicSupplement", { CachedRange(0x0500, 0x052F) }), ARMENIAN("Armenian", { CachedRange(0x0530, 0x058F) }), HEBREW("Hebrew", { CachedRange(0x0590, 0x05FF) }), ARABIC("Arabic", { CachedRange(0x0600, 0x06FF) }), SYRIAC("Syriac", { CachedRange(0x0700, 0x074F) }), ARABICSUPPLEMENT("ArabicSupplement", { CachedRange(0x0750, 0x077F) }), THAANA("Thaana", { CachedRange(0x0780, 0x07BF) }), DEVANAGARI("Devanagari", { CachedRange(0x0900, 0x097F) }), BENGALI("Bengali", { CachedRange(0x0980, 0x09FF) }), GURMUKHI("Gurmukhi", { CachedRange(0x0A00, 0x0A7F) }), GUJARATI("Gujarati", { CachedRange(0x0A80, 0x0AFF) }), ORIYA("Oriya", { CachedRange(0x0B00, 0x0B7F) }), TAMIL("Tamil", { CachedRange(0x0B80, 0x0BFF) }), TELUGU("Telugu", { CachedRange(0x0C00, 0x0C7F) }), KANNADA("Kannada", { CachedRange(0x0C80, 0x0CFF) }), MALAYALAM("Malayalam", { CachedRange(0x0D00, 0x0D7F) }), SINHALA("Sinhala", { CachedRange(0x0D80, 0x0DFF) }), THAI("Thai", { CachedRange(0x0E00, 0x0E7F) }), LAO("Lao", { CachedRange(0x0E80, 0x0EFF) }), TIBETAN("Tibetan", { CachedRange(0x0F00, 0x0FFF) }), MYANMAR("Myanmar", { CachedRange(0x1000, 0x109F) }), GEORGIAN("Georgian", { CachedRange(0x10A0, 0x10FF) }), HANGULJAMO("HangulJamo", { CachedRange(0x1100, 0x11FF) }), ETHIOPIC("Ethiopic", { CachedRange(0x1200, 0x137F) }), ETHIOPICSUPPLEMENT("EthiopicSupplement", { CachedRange(0x1380, 0x139F) }), CHEROKEE("Cherokee", { CachedRange(0x13A0, 0x13FF) }), UNIFIEDCANADIANABORIGINALSYLLABICS("UnifiedCanadianAboriginalSyllabics", { CachedRange(0x1400, 0x167F) }), OGHAM("Ogham", { CachedRange(0x1680, 0x169F) }), RUNIC("Runic", { CachedRange(0x16A0, 0x16FF) }), TAGALOG("Tagalog", { CachedRange(0x1700, 0x171F) }), HANUNOO("Hanunoo", { CachedRange(0x1720, 0x173F) }), BUHID("Buhid", { CachedRange(0x1740, 0x175F) }), TAGBANWA("Tagbanwa", { CachedRange(0x1760, 0x177F) }), KHMER("Khmer", { CachedRange(0x1780, 0x17FF) }), MONGOLIAN("Mongolian", { CachedRange(0x1800, 0x18AF) }), LIMBU("Limbu", { CachedRange(0x1900, 0x194F) }), TAILE("TaiLe", { CachedRange(0x1950, 0x197F) }), NEWTAILUE("NewTaiLue", { CachedRange(0x1980, 0x19DF) }), KHMERSYMBOLS("KhmerSymbols", { CachedRange(0x19E0, 0x19FF) }), BUGINESE("Buginese", { CachedRange(0x1A00, 0x1A1F) }), PHONETICEXTENSIONS("PhoneticExtensions", { CachedRange(0x1D00, 0x1D7F) }), PHONETICEXTENSIONSSUPPLEMENT("PhoneticExtensionsSupplement", { CachedRange(0x1D80, 0x1DBF) }), COMBININGDIACRITICALMARKSSUPPLEMENT("CombiningDiacriticalMarksSupplement", { CachedRange(0x1DC0, 0x1DFF) }), LATINEXTENDEDADDITIONAL("LatinExtendedAdditional", { CachedRange(0x1E00, 0x1EFF) }), GREEKEXTENDED("GreekExtended", { CachedRange(0x1F00, 0x1FFF) }), GENERALPUNCTUATION("GeneralPunctuation", { CachedRange(0x2000, 0x206F) }), SUPERSCRIPTSANDSUBSCRIPTS("SuperscriptsandSubscripts", { CachedRange(0x2070, 0x209F) }), CURRENCYSYMBOLS("CurrencySymbols", { CachedRange(0x20A0, 0x20CF) }), COMBININGMARKSFORSYMBOLS("CombiningMarksforSymbols", { CachedRange(0x20D0, 0x20FF) }), LETTERLIKESYMBOLS("LetterlikeSymbols", { CachedRange(0x2100, 0x214F) }), NUMBERFORMS("NumberForms", { CachedRange(0x2150, 0x218F) }), ARROWS("Arrows", { CachedRange(0x2190, 0x21FF) }), MATHEMATICALOPERATORS("MathematicalOperators", { CachedRange(0x2200, 0x22FF) }), MISCELLANEOUSTECHNICAL("MiscellaneousTechnical", { CachedRange(0x2300, 0x23FF) }), CONTROLPICTURES("ControlPictures", { CachedRange(0x2400, 0x243F) }), OPTICALCHARACTERRECOGNITION("OpticalCharacterRecognition", { CachedRange(0x2440, 0x245F) }), ENCLOSEDALPHANUMERICS("EnclosedAlphanumerics", { CachedRange(0x2460, 0x24FF) }), BOXDRAWING("BoxDrawing", { CachedRange(0x2500, 0x257F) }), BLOCKELEMENTS("BlockElements", { CachedRange(0x2580, 0x259F) }), GEOMETRICSHAPES("GeometricShapes", { CachedRange(0x25A0, 0x25FF) }), MISCELLANEOUSSYMBOLS("MiscellaneousSymbols", { CachedRange(0x2600, 0x26FF) }), DINGBATS("Dingbats", { CachedRange(0x2700, 0x27BF) }), MISCELLANEOUSMATHEMATICALSYMBOLS_A("MiscellaneousMathematicalSymbols-A", { CachedRange(0x27C0, 0x27EF) }), SUPPLEMENTALARROWS_A("SupplementalArrows-A", { CachedRange(0x27F0, 0x27FF) }), BRAILLEPATTERNS("BraillePatterns", { CachedRange(0x2800, 0x28FF) }), SUPPLEMENTALARROWS_B("SupplementalArrows-B", { CachedRange(0x2900, 0x297F) }), MISCELLANEOUSMATHEMATICALSYMBOLS_B("MiscellaneousMathematicalSymbols-B", { CachedRange(0x2980, 0x29FF) }), SUPPLEMENTALMATHEMATICALOPERATORS("SupplementalMathematicalOperators", { CachedRange(0x2A00, 0x2AFF) }), MISCELLANEOUSSYMBOLSANDARROWS("MiscellaneousSymbolsandArrows", { CachedRange(0x2B00, 0x2BFF) }), GLAGOLITIC("Glagolitic", { CachedRange(0x2C00, 0x2C5F) }), COPTIC("Coptic", { CachedRange(0x2C80, 0x2CFF) }), GEORGIANSUPPLEMENT("GeorgianSupplement", { CachedRange(0x2D00, 0x2D2F) }), TIFINAGH("Tifinagh", { CachedRange(0x2D30, 0x2D7F) }), ETHIOPICEXTENDED("EthiopicExtended", { CachedRange(0x2D80, 0x2DDF) }), SUPPLEMENTALPUNCTUATION("SupplementalPunctuation", { CachedRange(0x2E00, 0x2E7F) }), CJKRADICALSSUPPLEMENT("CJKRadicalsSupplement", { CachedRange(0x2E80, 0x2EFF) }), KANGXIRADICALS("KangxiRadicals", { CachedRange(0x2F00, 0x2FDF) }), IDEOGRAPHICDESCRIPTIONCHARACTERS("IdeographicDescriptionCharacters", { CachedRange(0x2FF0, 0x2FFF) }), CJKSYMBOLSANDPUNCTUATION("CJKSymbolsandPunctuation", { CachedRange(0x3000, 0x303F) }), HIRAGANA("Hiragana", { CachedRange(0x3040, 0x309F) }), KATAKANA("Katakana", { CachedRange(0x30A0, 0x30FF) }), BOPOMOFO("Bopomofo", { CachedRange(0x3100, 0x312F) }), HANGULCOMPATIBILITYJAMO("HangulCompatibilityJamo", { CachedRange(0x3130, 0x318F) }), KANBUN("Kanbun", { CachedRange(0x3190, 0x319F) }), BOPOMOFOEXTENDED("BopomofoExtended", { CachedRange(0x31A0, 0x31BF) }), CJKSTROKES("CJKStrokes", { CachedRange(0x31C0, 0x31EF) }), KATAKANAPHONETICEXTENSIONS("KatakanaPhoneticExtensions", { CachedRange(0x31F0, 0x31FF) }), ENCLOSEDCJKLETTERSANDMONTHS("EnclosedCJKLettersandMonths", { CachedRange(0x3200, 0x32FF) }), CJKCOMPATIBILITY("CJKCompatibility", { CachedRange(0x3300, 0x33FF) }), CJKUNIFIEDIDEOGRAPHSEXTENSIONA("CJKUnifiedIdeographsExtensionA", { CachedRange(0x3400, 0x4DB5) }), YIJINGHEXAGRAMSYMBOLS("YijingHexagramSymbols", { CachedRange(0x4DC0, 0x4DFF) }), CJKUNIFIEDIDEOGRAPHS("CJKUnifiedIdeographs", { CachedRange(0x4E00, 0x9FFF) }), YISYLLABLES("YiSyllables", { CachedRange(0xA000, 0xA48F) }), YIRADICALS("YiRadicals", { CachedRange(0xA490, 0xA4CF) }), MODIFIERTONELETTERS("ModifierToneLetters", { CachedRange(0xA700, 0xA71F) }), SYLOTINAGRI("SylotiNagri", { CachedRange(0xA800, 0xA82F) }), HANGULSYLLABLES("HangulSyllables", { CachedRange(0xAC00, 0xD7A3) }), HIGHSURROGATES("HighSurrogates", { CachedRange(0xD800, 0xDB7F) }), HIGHPRIVATEUSESURROGATES("HighPrivateUseSurrogates", { CachedRange(0xDB80, 0xDBFF) }), LOWSURROGATES("LowSurrogates", { CachedRange(0xDC00, 0xDFFF) }), PRIVATEUSEAREA("PrivateUseArea", { CachedRange(0xE000, 0xF8FF) }), CJKCOMPATIBILITYIDEOGRAPHS("CJKCompatibilityIdeographs", { CachedRange(0xF900, 0xFAFF) }), ALPHABETICPRESENTATIONFORMS("AlphabeticPresentationForms", { CachedRange(0xFB00, 0xFB4F) }), ARABICPRESENTATIONFORMS_A("ArabicPresentationForms-A", { CachedRange(0xFB50, 0xFDFF) }), VARIATIONSELECTORS("VariationSelectors", { CachedRange(0xFE00, 0xFE0F) }), VERTICALFORMS("VerticalForms", { CachedRange(0xFE10, 0xFE1F) }), COMBININGHALFMARKS("CombiningHalfMarks", { CachedRange(0xFE20, 0xFE2F) }), CJKCOMPATIBILITYFORMS("CJKCompatibilityForms", { CachedRange(0xFE30, 0xFE4F) }), SMALLFORMVARIANTS("SmallFormVariants", { CachedRange(0xFE50, 0xFE6F) }), ARABICPRESENTATIONFORMS_B("ArabicPresentationForms-B", { CachedRange(0xFE70, 0xFEFF) }), HALFWIDTHANDFULLWIDTHFORMS("HalfwidthandFullwidthForms", { CachedRange(0xFF00, 0xFFEF) }), ALL("all", { CachedRange(0x00, 0x10FFFF) }), SPECIALS("Specials", ::CachedSpecialsBlock), CN("Cn", { CachedCategory(CharCategory.UNASSIGNED.value, true) }), ISL("IsL", { CachedCategoryScope(0x3E, true) }), LU("Lu", { CachedCategory(CharCategory.UPPERCASE_LETTER.value, true) }), LL("Ll", { CachedCategory(CharCategory.LOWERCASE_LETTER.value, true) }), LT("Lt", { CachedCategory(CharCategory.TITLECASE_LETTER.value, false) }), LM("Lm", { CachedCategory(CharCategory.MODIFIER_LETTER.value, false) }), LO("Lo", { CachedCategory(CharCategory.OTHER_LETTER.value, true) }), ISM("IsM", { CachedCategoryScope(0x1C0, true) }), MN("Mn", { CachedCategory(CharCategory.NON_SPACING_MARK.value, true) }), ME("Me", { CachedCategory(CharCategory.ENCLOSING_MARK.value, false) }), MC("Mc", { CachedCategory(CharCategory.COMBINING_SPACING_MARK.value, true) }), N("N", { CachedCategoryScope(0xE00, true) }), ND("Nd", { CachedCategory(CharCategory.DECIMAL_DIGIT_NUMBER.value, true) }), NL("Nl", { CachedCategory(CharCategory.LETTER_NUMBER.value, true) }), NO("No", { CachedCategory(CharCategory.OTHER_NUMBER.value, true) }), ISZ("IsZ", { CachedCategoryScope(0x7000, false) }), ZS("Zs", { CachedCategory(CharCategory.SPACE_SEPARATOR.value, false) }), ZL("Zl", { CachedCategory(CharCategory.LINE_SEPARATOR.value, false) }), ZP("Zp", { CachedCategory(CharCategory.PARAGRAPH_SEPARATOR.value, false) }), ISC("IsC", { CachedCategoryScope(0xF0000, true, true) }), CC("Cc", { CachedCategory(CharCategory.CONTROL.value, false) }), CF("Cf", { CachedCategory(CharCategory.FORMAT.value, true) }), CO("Co", { CachedCategory(CharCategory.PRIVATE_USE.value, true) }), CS("Cs", { CachedCategory(CharCategory.SURROGATE.value, false, true) }), ISP("IsP", { CachedCategoryScope((1 shl CharCategory.DASH_PUNCTUATION.value) or (1 shl CharCategory.START_PUNCTUATION.value) or (1 shl CharCategory.END_PUNCTUATION.value) or (1 shl CharCategory.CONNECTOR_PUNCTUATION.value) or (1 shl CharCategory.OTHER_PUNCTUATION.value) or (1 shl CharCategory.INITIAL_QUOTE_PUNCTUATION.value) or (1 shl CharCategory.FINAL_QUOTE_PUNCTUATION.value), true) }), PD("Pd", { CachedCategory(CharCategory.DASH_PUNCTUATION.value, false) }), PS("Ps", { CachedCategory(CharCategory.START_PUNCTUATION.value, false) }), PE("Pe", { CachedCategory(CharCategory.END_PUNCTUATION.value, false) }), PC("Pc", { CachedCategory(CharCategory.CONNECTOR_PUNCTUATION.value, false) }), PO("Po", { CachedCategory(CharCategory.OTHER_PUNCTUATION.value, true) }), ISS("IsS", { CachedCategoryScope(0x7E000000, true) }), SM("Sm", { CachedCategory(CharCategory.MATH_SYMBOL.value, true) }), SC("Sc", { CachedCategory(CharCategory.CURRENCY_SYMBOL.value, false) }), SK("Sk", { CachedCategory(CharCategory.MODIFIER_SYMBOL.value, false) }), SO("So", { CachedCategory(CharCategory.OTHER_SYMBOL.value, true) }), PI("Pi", { CachedCategory(CharCategory.INITIAL_QUOTE_PUNCTUATION.value, false) }), PF("Pf", { CachedCategory(CharCategory.FINAL_QUOTE_PUNCTUATION.value, false) }) } private val classCache = Array>(CharClasses.values().size, { AtomicReference(null) }) private val classCacheMap = CharClasses.values().associate { it -> it.regexName to it } fun intersects(ch1: Int, ch2: Int): Boolean = ch1 == ch2 fun intersects(cc: AbstractCharClass, ch: Int): Boolean = cc.contains(ch) fun intersects(cc1: AbstractCharClass, cc2: AbstractCharClass): Boolean { if (cc1.bits == null || cc2.bits == null) { return true } return cc1.bits!!.intersects(cc2.bits!!) } fun getPredefinedClass(name: String, negative: Boolean): AbstractCharClass { val charClass = classCacheMap[name] ?: throw PatternSyntaxException("No such character class") val cachedClass = classCache[charClass.ordinal].value ?: run { classCache[charClass.ordinal].compareAndSwap(null, charClass.factory().freeze()) classCache[charClass.ordinal].value!! } return cachedClass.getValue(negative) } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/AbstractLineTerminator.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex private object unixLT : AbstractLineTerminator() { override fun isLineTerminator(codepoint: Int): Boolean = (codepoint == '\n'.toInt()) override fun isLineTerminatorPair(char1: Char, char2: Char): Boolean = false override fun isAfterLineTerminator(previous: Char, checked: Char): Boolean = (previous == '\n') } private object unicodeLT : AbstractLineTerminator() { override fun isLineTerminatorPair(char1: Char, char2: Char): Boolean { return char1 == '\r' && char2 == '\n' } override fun isLineTerminator(codepoint: Int): Boolean { return codepoint == '\n'.toInt() || codepoint == '\r'.toInt() || codepoint == '\u0085'.toInt() || codepoint or 1 == '\u2029'.toInt() } override fun isAfterLineTerminator(previous: Char, checked: Char): Boolean { return previous == '\n' || previous == '\u0085' || previous.toInt() or 1 == '\u2029'.toInt() || previous == '\r' && checked != '\n' } } /** * Line terminator factory */ internal abstract class AbstractLineTerminator { /** Checks if the single character is a line terminator or not. */ open fun isLineTerminator(char: Char): Boolean = isLineTerminator(char.toInt()) /** Checks if the codepoint is a line terminator or not */ abstract fun isLineTerminator(codepoint: Int): Boolean /** Checks if the pair of symbols is a line terminator (e.g. for \r\n case) */ abstract fun isLineTerminatorPair(char1: Char, char2: Char): Boolean /** Checks if a [checked] character is after a line terminator using the [previous] character.*/ abstract fun isAfterLineTerminator(previous: Char, checked: Char): Boolean companion object { fun getInstance(flag: Int): AbstractLineTerminator { if (flag and Pattern.UNIX_LINES != 0) { return unixLT } else { return unicodeLT } } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/CharClass.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * User defined character classes (e.g. [abef]). */ // TODO: replace the implementation with one using BitSet for first 256 symbols and a hash table / tree for the rest of UTF. internal class CharClass(val ignoreCase: Boolean = false, negative: Boolean = false) : AbstractCharClass() { var invertedSurrogates = false /** * Shows if the alt flags was inverted during the range construction process. * E.g. consider the following range: [\D3]. Here we firstly add the \D char class (which has the alt flag set) into a * resulting char set. After that the resulting char also has the alt flag set. But then we need to add the '3' character * into this class with positive sense. So we set the inverted flag to show that the range is not negative ([^..]) * by itself but was inverted during some transformations. */ var inverted = false var hideBits = false internal var bits_ = BitSet() override val bits: BitSet? get() { if (hideBits) return null return bits_ } var nonBitSet: AbstractCharClass? = null private val Int.asciiSupplement: Int get() = when { this in 'a'.toInt()..'z'.toInt() -> this - 32 this in 'A'.toInt()..'Z'.toInt() -> this + 32 else -> this } private val Int.isSurrogate: Boolean get() = this in Char.MIN_SURROGATE.toInt()..Char.MAX_SURROGATE.toInt() init { setNegative(negative) } /* * We can use this method safely even if nonBitSet != null * due to specific of range constructions in regular expressions. */ fun add(ch: Int): CharClass { var character = ch if (ignoreCase) { if (character.toChar() in 'a'..'z' || character.toChar() in 'A'..'Z') { bits_.set(character.asciiSupplement, !inverted) } else if (character > 128) { character = Char.toLowerCase(Char.toUpperCase(character)) } } if (character.toChar().isSurrogate()) { lowHighSurrogates.set(character - Char.MIN_SURROGATE.toInt(), !invertedSurrogates) } bits_.set(character, !inverted) if (!mayContainSupplCodepoints && Char.isSupplementaryCodePoint(ch)) { mayContainSupplCodepoints = true } return this } fun add(ch: Char): CharClass = add(ch.toInt()) /* * The difference between add(AbstractCharClass) and union(AbstractCharClass) * is that add() is used for constructions like "[^abc\\d]" * (this pattern doesn't match "1") * while union is used for constructions like "[^abc[\\d]]" * (this pattern matches "1"). */ fun add(another: AbstractCharClass): CharClass { if (!mayContainSupplCodepoints && another.mayContainSupplCodepoints) { mayContainSupplCodepoints = true } // Process surrogates. if (!invertedSurrogates) { //A | !B = ! ((A ^ B) & B) if (another.altSurrogates) { lowHighSurrogates.xor(another.lowHighSurrogates) lowHighSurrogates.and(another.lowHighSurrogates) altSurrogates = !altSurrogates invertedSurrogates = true //A | B } else { lowHighSurrogates.or(another.lowHighSurrogates) } } else { //!A | !B = !(A & B) if (another.altSurrogates) { lowHighSurrogates.and(another.lowHighSurrogates) //!A | B = !(A & !B) } else { lowHighSurrogates.andNot(another.lowHighSurrogates) } } val anotherBits = another.bits if (!hideBits && anotherBits != null) { if (!inverted) { //A | !B = ! ((A ^ B) & B) if (another.isNegative()) { bits_.xor(anotherBits) bits_.and(anotherBits) alt = !alt inverted = true //A | B } else { bits_.or(anotherBits) } } else { //!A | !B = !(A & B) if (another.isNegative()) { bits_.and(anotherBits) //!A | B = !(A & !B) } else { bits_.andNot(anotherBits) } } // Some of charclasses hides its bits } else { val curAlt = alt if (nonBitSet == null) { if (curAlt && !inverted && bits_.isEmpty) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return another.contains(ch) } } } else { /* * We keep the value of alt unchanged for * constructions like [^[abc]fgb] by using * the formula a ^ b == !a ^ !b. */ if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(curAlt xor bits_.get(ch) || curAlt xor inverted xor another.contains(ch)) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return curAlt xor bits_.get(ch) || curAlt xor inverted xor another.contains(ch) } } } } hideBits = true } else { val nb = nonBitSet if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(curAlt xor (nb!!.contains(ch) || another.contains(ch))) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return curAlt xor (nb!!.contains(ch) || another.contains(ch)) } } } } } return this } fun add(start: Int, end: Int): CharClass { if (start > end) throw IllegalArgumentException("Incorrect range of symbols (start > end)") val minSurrogate = Char.MIN_SURROGATE.toInt() val maxSurrogate = Char.MAX_SURROGATE.toInt() if (ignoreCase) { // TODO: Make a faster implementation. for (i in start..end) { add(i) } } else { // No intersection with surrogate characters. if (end < minSurrogate || start > maxSurrogate) { bits_.set(start, end + 1, !inverted) } else { val surrogatesStart = maxOf(start, minSurrogate) val surrogatesEnd = minOf(end, maxSurrogate) bits_.set(start, end + 1, !inverted) lowHighSurrogates.set(surrogatesStart - minSurrogate, surrogatesEnd - minSurrogate + 1, !invertedSurrogates) if (!mayContainSupplCodepoints && end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) { mayContainSupplCodepoints = true } } } return this } fun add(start: Char, end: Char): CharClass = add(start.toInt(), end.toInt()) // OR operation fun union(another: AbstractCharClass) { if (!mayContainSupplCodepoints && another.mayContainSupplCodepoints) { mayContainSupplCodepoints = true } if (altSurrogates xor another.altSurrogates) { //!A | B = !(A & !B) if (altSurrogates) { lowHighSurrogates.andNot(another.lowHighSurrogates) //A | !B = !((A ^ B) & B) } else { lowHighSurrogates.xor(another.lowHighSurrogates) lowHighSurrogates.and(another.lowHighSurrogates) altSurrogates = true } } else { //!A | !B = !(A & B) if (altSurrogates) { lowHighSurrogates.and(another.lowHighSurrogates) //A | B } else { lowHighSurrogates.or(another.lowHighSurrogates) } } val anotherBits = another.bits if (!hideBits && anotherBits != null) { if (alt xor another.isNegative()) { //!A | B = !(A & !B) if (alt) { bits_.andNot(anotherBits) //A | !B = !((A ^ B) & B) } else { bits_.xor(anotherBits) bits_.and(anotherBits) alt = true } } else { //!A | !B = !(A & B) if (alt) { bits_.and(anotherBits) //A | B } else { bits_.or(anotherBits) } } } else { val curAlt = alt if (nonBitSet == null) { if (!inverted && bits_.isEmpty) { if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !another.contains(ch) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return another.contains(ch) } } } } else { if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(another.contains(ch) || curAlt xor bits_.get(ch)) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return another.contains(ch) || curAlt xor bits_.get(ch) } } } } hideBits = true } else { val nb = nonBitSet if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(curAlt xor nb!!.contains(ch) || another.contains(ch)) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return curAlt xor nb!!.contains(ch) || another.contains(ch) } } } } } } // AND operation fun intersection(another: AbstractCharClass) { if (!mayContainSupplCodepoints && another.mayContainSupplCodepoints) { mayContainSupplCodepoints = true } if (altSurrogates xor another.altSurrogates) { //!A & B = ((A ^ B) & B) if (altSurrogates) { lowHighSurrogates.xor(another.lowHighSurrogates) lowHighSurrogates.and(another.lowHighSurrogates) altSurrogates = false //A & !B } else { lowHighSurrogates.andNot(another.lowHighSurrogates) } } else { //!A & !B = !(A | B) if (altSurrogates) { lowHighSurrogates.or(another.lowHighSurrogates) //A & B } else { lowHighSurrogates.and(another.lowHighSurrogates) } } val anotherBits = another.bits if (!hideBits && anotherBits != null) { if (alt xor another.isNegative()) { //!A & B = ((A ^ B) & B) if (alt) { bits_.xor(anotherBits) bits_.and(anotherBits) alt = false //A & !B } else { bits_.andNot(anotherBits) } } else { //!A & !B = !(A | B) if (alt) { bits_.or(anotherBits) //A & B } else { bits_.and(anotherBits) } } } else { val curAlt = alt if (nonBitSet == null) { if (!inverted && bits_.isEmpty) { if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !another.contains(ch) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return another.contains(ch) } } } } else { if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(another.contains(ch) && curAlt xor bits_.get(ch)) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return another.contains(ch) && curAlt xor bits_.get(ch) } } } } hideBits = true } else { val nb = nonBitSet if (curAlt) { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return !(curAlt xor nb!!.contains(ch) && another.contains(ch)) } } } else { nonBitSet = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return curAlt xor nb!!.contains(ch) && another.contains(ch) } } } } } } /** * Returns `true` if character class contains symbol specified, * `false` otherwise. Note: #setNegative() method changes the * meaning of contains method; * @param ch * * * @return `true` if character class contains symbol specified; * */ override operator fun contains(ch: Int): Boolean { if (nonBitSet == null) { return alt xor bits_.get(ch) } else { return alt xor nonBitSet!!.contains(ch) } } @OptIn(ExperimentalStdlibApi::class) override val instance: AbstractCharClass get() { if (nonBitSet == null) { val bs = bits val res = object : AbstractCharClass() { override operator fun contains(ch: Int): Boolean { return this.alt xor bs!!.get(ch) } override fun toString(): String { val temp = StringBuilder() var i = bs!!.nextSetBit(0) while (i >= 0) { temp.append(Char.toChars(i)) temp.append('|') i = bs.nextSetBit(i + 1) } if (temp.length > 0) temp.deleteAt(temp.length - 1) return temp.toString() } } return res.setNegative(isNegative()) } else { return this } } @OptIn(ExperimentalStdlibApi::class) //for debugging purposes only override fun toString(): String { val temp = StringBuilder() var i = bits_.nextSetBit(0) while (i >= 0) { temp.append(Char.toChars(i)) temp.append('|') i = bits_.nextSetBit(i + 1) } if (temp.length > 0) temp.deleteAt(temp.length - 1) return temp.toString() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/Lexer.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // TODO: Licenses. package kotlin.text.regex // Access to the decomposition tables. ========================================================================= /** Gets canonical class for given codepoint from decomposition mappings table. */ @SymbolName("Kotlin_text_regex_getCanonicalClassInternal") external private fun getCanonicalClassInternal(ch: Int): Int /** Check if the given character is in table of single decompositions. */ @SymbolName("Kotlin_text_regex_hasSingleCodepointDecompositionInternal") external private fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean /** Returns a decomposition for a given codepoint. */ @SymbolName("Kotlin_text_regex_getDecompositionInternal") external private fun getDecompositionInternal(ch: Int): IntArray? /** * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. * Returns the length of the decomposition. */ @SymbolName("Kotlin_text_regex_decomposeString") external private fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int // ============================================================================================================= /** * This is base class for special tokens like character classes and quantifiers. */ internal abstract class SpecialToken { /** * Returns the type of the token, may return following values: * TOK_CHARCLASS - token representing character class; * TOK_QUANTIFIER - token representing quantifier; */ abstract val type: Type enum class Type { CHARCLASS, QUANTIFIER } } internal class Lexer(val patternString: String, flags: Int) { // The property is set in the init block after some transformations over the pattern string. private val pattern: CharArray var flags = flags private set // Modes =========================================================================================================== enum class Mode { PATTERN, RANGE, ESCAPE } /** * Mode: whether the lexer processes character range ([Mode.RANGE]), escaped sequence ([Mode.RANGE]) * or any other part of a regex ([PATTERN]). */ var mode = Mode.PATTERN private set /** When in [Mode.ESCAPE] mode, this field will save the previous one */ private var savedMode = Mode.PATTERN fun setModeWithReread(value: Mode) { if(value == Mode.PATTERN || value == Mode.RANGE) { mode = value } if (mode == Mode.PATTERN) { reread() } } // Tokens ========================================================================================================== internal var lookBack: Int = 0 // Previous char read. private set internal var currentChar: Int = 0 // Current character read. Returns 0 if there is no more characters. private set internal var lookAhead: Int = 0 // Next character. private set internal var curSpecialToken: SpecialToken? = null // Current special token (e.g. quantifier) private set internal var lookAheadSpecialToken: SpecialToken? = null // Next special token private set // Indices in the pattern. var index = 0 // Current char being processed index. private set var prevNonWhitespaceIndex = 0 // Previous non-whitespace character index. private set var curTokenIndex = 0 // Current token start index. private set var lookAheadTokenIndex = 0 // Next token index. private set init { var processedPattern = patternString if (flags and Pattern.LITERAL > 0) { processedPattern = Pattern.quote(patternString) } else if (flags and Pattern.CANON_EQ > 0) { processedPattern = Lexer.normalize(patternString) } this.pattern = processedPattern.toCharArray().copyOf(processedPattern.length + 2) this.pattern[this.pattern.size - 1] = 0.toChar() this.pattern[this.pattern.size - 2] = 0.toChar() // Read first two tokens. movePointer() movePointer() } // Character checks ================================================================================================ /** Returns true, if current token is special, i.e. quantifier, or other compound token. */ val isSpecial: Boolean get() = curSpecialToken != null val isQuantifier: Boolean get() = isSpecial && curSpecialToken!!.type == SpecialToken.Type.QUANTIFIER val isNextSpecial: Boolean get() = lookAheadSpecialToken != null private fun Int.isSurrogatePair() : Boolean { val high = (this ushr 16).toChar() val low = this.toChar() return high.isHighSurrogate() && low.isLowSurrogate() } private fun Char.isLineSeparator(): Boolean = this == '\n' || this == '\r' || this == '\u0085' || this.toInt() or 1 == '\u2029'.toInt() /** Checks if there are any characters in the pattern. */ fun isEmpty(): Boolean = currentChar == 0 && lookAhead == 0 && index >= pattern.size && !isSpecial /** Return true if the current character is letter, false otherwise .*/ fun isLetter(): Boolean = !isEmpty() && !isSpecial && isLetter(currentChar) /** Check if the current char is high/low surrogate. */ fun isHighSurrogate(): Boolean = currentChar in 0xDBFF..0xD800 fun isLowSurrogate(): Boolean = currentChar in 0xDFFF..0xDC00 fun isSurrogate(): Boolean = isHighSurrogate() || isLowSurrogate() /** * Restores flags for Lexer * @param flags */ fun restoreFlags(flags: Int) { this.flags = flags lookAhead = currentChar lookAheadSpecialToken = curSpecialToken // curTokenIndex is an index of closing bracket ')' index = curTokenIndex + 1 lookAheadTokenIndex = curTokenIndex movePointer() } override fun toString(): String { return patternString } // Processing index moving ========================================================================================= /** Returns current character and moves string index to the next one. */ operator fun next(): Int { movePointer() return lookBack } /** Returns current special token and moves string index to the next one */ fun nextSpecial(): SpecialToken? { val res = curSpecialToken movePointer() return res } /** * Reread current character. May be required if a previous token changes mode * to one with different character interpretation. */ private fun reread() { lookAhead = currentChar lookAheadSpecialToken = curSpecialToken index = lookAheadTokenIndex lookAheadTokenIndex = curTokenIndex movePointer() } /** * Returns the next character index to read and moves pointer to the next one. * If comments flag is on this method will skip comments and whitespaces. * * The following actions are equivalent if comments flag is off: * currentChar = pattern[index++] == currentChar = pattern[nextIndex] */ private fun nextIndex(): Int { prevNonWhitespaceIndex = index if (flags and Pattern.COMMENTS != 0) { skipComments() } else { index++ } return prevNonWhitespaceIndex } /** Skips comments and whitespaces */ private fun skipComments(): Int { val length = pattern.size - 2 index++ do { while (index < length && pattern[index].isWhitespace()) { index++ } if (index < length && pattern[index] == '#') { index++ while (index < length && !pattern[index].isLineSeparator()) { index++ } } else { return index } } while (true) } /** * Returns the next code point in the pattern string. */ private fun nextCodePoint(): Int { val high = pattern[nextIndex()] // nextIndex skips comments and whitespaces if comments flag is on. if (high.isHighSurrogate()) { // Low and high chars may be delimited by spaces. val lowExpectedIndex = prevNonWhitespaceIndex + 1 if (lowExpectedIndex < pattern.size) { val low = pattern[lowExpectedIndex] if (low.isLowSurrogate()) { nextIndex() return Char.toCodePoint(high, low) } } } return high.toInt() } /** * Moves pointer one position right. Saves the current character to [lookBack], * [lookAhead] to the current one and finally read one more to [lookAhead]. */ private fun movePointer() { // swap pointers lookBack = currentChar currentChar = lookAhead curSpecialToken = lookAheadSpecialToken curTokenIndex = lookAheadTokenIndex lookAheadTokenIndex = index var reread: Boolean do { // Read the next character, analyze it and construct a token. lookAhead = if (index < pattern.size) nextCodePoint() else 0 lookAheadSpecialToken = null if (mode == Mode.ESCAPE) { processInEscapeMode() } reread = when (mode) { Mode.PATTERN -> processInPatternMode() Mode.RANGE -> processInRangeMode() else -> false } } while (reread) } // Special functions called from [movePointer] function to process chars in different modes ======================== /** * Processing an escaped sequence like "\Q foo \E". Just skip a character if it is not \E. * Returns whether we need to reread the character or not */ private fun processInEscapeMode(): Boolean { if (lookAhead == '\\'.toInt()) { // Need not care about supplementary code points here. val lookAheadChar: Char = if (index < pattern.size) pattern[nextIndex()] else '\u0000' lookAhead = lookAheadChar.toInt() if (lookAheadChar == 'E') { // If \E found - change the mode to the previous one and shift to the next char. mode = savedMode lookAhead = if (index <= pattern.size - 2) nextCodePoint() else 0 } else { // If \ have no E - make a step back and return. lookAhead = '\\'.toInt() index = prevNonWhitespaceIndex } } return false } /** Processes a next character in [Mode.PATTERN] mode. Returns whether we need to reread the character or not */ private fun processInPatternMode(): Boolean { if (lookAhead.isSurrogatePair()) { return false } val lookAheadChar = lookAhead.toChar() if (lookAheadChar == '\\') { return processEscapedChar() } // TODO: Look like we can create a quantifier here. when (lookAheadChar) { // Quantifier (*, +, ?). '+', '*', '?' -> { val mode = if (index < pattern.size) pattern[index] else '*' // look at the next character to determine if the mode is greedy, reluctant or possessive. when (mode) { '+' -> { lookAhead = lookAhead or Lexer.QMOD_POSSESSIVE; nextIndex() } '?' -> { lookAhead = lookAhead or Lexer.QMOD_RELUCTANT; nextIndex() } else -> lookAhead = lookAhead or Lexer.QMOD_GREEDY } } // Quantifier ({x,y}). '{' -> lookAheadSpecialToken = processQuantifier() // $. '$' -> lookAhead = CHAR_DOLLAR // A group or a special construction. '(' -> { if (pattern[index] != '?') { // Group lookAhead = CHAR_LEFT_PARENTHESIS } else { // Special constructs (non-capturing groups, look ahead/look behind etc). nextIndex() var char = pattern[index] var isLookBehind = false do { if (!isLookBehind) { when (char) { // Look ahead or an atomic group. '!' -> { lookAhead = CHAR_NEG_LOOKAHEAD; nextIndex() } '=' -> { lookAhead = CHAR_POS_LOOKAHEAD; nextIndex() } '>' -> { lookAhead = CHAR_ATOMIC_GROUP; nextIndex() } // Positive / negaitve look behind - need to check the next char. '<' -> { nextIndex() char = pattern[index] isLookBehind = true } // Flags. else -> { lookAhead = readFlags() // We return `res = res or 1 shl 8` from readFlags() if we read (?idmsux-idmsux) if (lookAhead >= 256) { // Just flags (no non-capturing group with them). Erase auxiliary bit. lookAhead = lookAhead and 0xff flags = lookAhead lookAhead = lookAhead shl 16 lookAhead = CHAR_FLAGS or lookAhead } else { // A non-capturing group with flags: (?:Foo) flags = lookAhead lookAhead = lookAhead shl 16 lookAhead = CHAR_NONCAP_GROUP or lookAhead } } } } else { // Process the second char for look behind construction. isLookBehind = false when (char) { '!' -> { lookAhead = CHAR_NEG_LOOKBEHIND; nextIndex() } '=' -> { lookAhead = CHAR_POS_LOOKBEHIND; nextIndex() } else -> throw PatternSyntaxException("Unknown look behind", patternString, curTokenIndex) } } } while (isLookBehind) } } ')' -> lookAhead = CHAR_RIGHT_PARENTHESIS '[' -> { lookAhead = CHAR_LEFT_SQUARE_BRACKET; mode = Mode.RANGE } '^' -> lookAhead = CHAR_CARET '|' -> lookAhead = CHAR_VERTICAL_BAR '.' -> lookAhead = CHAR_DOT } return false } /** Processes a character inside a range. Returns whether we need to reread the character or not */ private fun processInRangeMode(): Boolean { if (lookAhead.isSurrogatePair()) { return false } val lookAheadChar = lookAhead.toChar() when (lookAheadChar) { '\\' -> return processEscapedChar() '[' -> lookAhead = CHAR_LEFT_SQUARE_BRACKET ']' -> lookAhead = CHAR_RIGHT_SQUARE_BRACKET '^' -> lookAhead = CHAR_CARET '&' -> lookAhead = CHAR_AMPERSAND '-' -> lookAhead = CHAR_HYPHEN } return false } /** Processes an escaped (\x) character in any mode. Returns whether we need to reread the character or not */ private fun processEscapedChar() : Boolean { lookAhead = if (index < pattern.size - 2) { nextCodePoint() } else { throw PatternSyntaxException("Trailing \\", patternString, curTokenIndex) } // The current code point cannot be a surrogate pair because it is an escaped special one. // Cast it to char or just skip it as if we pass through the else branch of the when below. if (lookAhead.isSurrogatePair()) { return false } val lookAheadChar = lookAhead.toChar() when (lookAheadChar) { // Character class. 'P', 'p' -> { val cs = parseCharClassName() val negative = lookAheadChar == 'P' lookAheadSpecialToken = AbstractCharClass.getPredefinedClass(cs, negative) lookAhead = 0 } // Word/whitespace/digit. 'w', 's', 'd', 'W', 'S', 'D' -> { lookAheadSpecialToken = AbstractCharClass.getPredefinedClass( pattern.concatToString(prevNonWhitespaceIndex, prevNonWhitespaceIndex + 1), false ) lookAhead = 0 } // Enter in ESCAPE mode. Skip this \Q symbol. 'Q' -> { savedMode = mode mode = Mode.ESCAPE return true } // Special characters like tab, new line etc. 't' -> lookAhead = '\t'.toInt() 'n' -> lookAhead = '\n'.toInt() 'r' -> lookAhead = '\r'.toInt() 'f' -> lookAhead = '\u000C'.toInt() 'a' -> lookAhead = '\u0007'.toInt() 'e' -> lookAhead = '\u001B'.toInt() // Back references to capturing groups. '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { if (mode == Mode.PATTERN) { lookAhead = 0x80000000.toInt() or lookAhead // Captured group reference is 0x80... } } // A literal: octal, hex, or hex unicode. '0' -> lookAhead = readOctals() 'x' -> lookAhead = readHex("hexadecimal", 2) 'u' -> lookAhead = readHex("Unicode", 4) // Special characters like EOL, EOI etc 'b' -> lookAhead = CHAR_WORD_BOUND 'B' -> lookAhead = CHAR_NONWORD_BOUND 'A' -> lookAhead = CHAR_START_OF_INPUT 'G' -> lookAhead = CHAR_PREVIOUS_MATCH 'Z' -> lookAhead = CHAR_END_OF_LINE 'z' -> lookAhead = CHAR_END_OF_INPUT // \cx - A control character corresponding to x. 'c' -> { if (index < pattern.size - 2) { // Need not care about supplementary codepoints here. lookAhead = pattern[nextIndex()].toInt() and 0x1f } else { throw PatternSyntaxException("Illegal control sequence", patternString, curTokenIndex) } } 'C', 'E', 'F', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'R', 'T', 'U', 'V', 'X', 'Y', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'q', 'y' -> throw PatternSyntaxException("Illegal escape sequence", patternString, curTokenIndex) } return false } /** Process [lookAhead] in assumption that it's quantifier. */ private fun processQuantifier(): Quantifier { assert(lookAhead == '{'.toInt()) val sb = StringBuilder(4) var min = -1 var max = -1 // Obtain a min value. var char: Char = if (index < pattern.size) { pattern[nextIndex()] } else { throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) } while (char != '}') { if (char == ',' && min < 0) { try { val minParsed = sb.toString().toInt() min = if (minParsed >= 0) minParsed else throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) sb.setLength(0) } catch (nfe: NumberFormatException) { throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) } } else { sb.append(char) } char = if (index < pattern.size) pattern[nextIndex()] else break } if (char != '}') { throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) } // Obtain a max value, if it exists if (sb.isNotEmpty()) { try { val maxParsed = sb.toString().toInt() max = if (maxParsed >= 0) maxParsed else throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) if (min < 0) { min = max } } catch (nfe: NumberFormatException) { throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) } } if (min < 0 || max >=0 && max < min) { throw PatternSyntaxException("Incorrect Quantifier Syntax", patternString, curTokenIndex) } val mod = if (index < pattern.size) pattern[index] else '*' when (mod) { '+' -> { lookAhead = Lexer.QUANT_COMP_P; nextIndex() } '?' -> { lookAhead = Lexer.QUANT_COMP_R; nextIndex() } else -> lookAhead = Lexer.QUANT_COMP } return Quantifier(min, max) } // Reading methods for specific tokens ============================================================================= /** Process expression flags given with (?idmsux-idmsux). Returns the flags processed. */ private fun readFlags(): Int { var positive = true var result = flags while (index < pattern.size) { val char = pattern[index] when (char) { '-' -> { if (!positive) { throw PatternSyntaxException("Illegal inline construct", patternString, curTokenIndex) } positive = false } 'i' -> result = if (positive) result or Pattern.CASE_INSENSITIVE else result xor Pattern.CASE_INSENSITIVE and result 'd' -> result = if (positive) result or Pattern.UNIX_LINES else result xor Pattern.UNIX_LINES and result 'm' -> result = if (positive) result or Pattern.MULTILINE else result xor Pattern.MULTILINE and result 's' -> result = if (positive) result or Pattern.DOTALL else result xor Pattern.DOTALL and result // We don't support UNICODE_CASE. /*'u' -> result = if (positive) result or Pattern.UNICODE_CASE else result xor Pattern.UNICODE_CASE and result*/ 'x' -> result = if (positive) result or Pattern.COMMENTS else result xor Pattern.COMMENTS and result ':' -> { nextIndex() return result } ')' -> { nextIndex() return result or (1 shl 8) } } nextIndex() } throw PatternSyntaxException("Illegal inline construct", patternString, curTokenIndex) } /** Parse character classes names and verifies correction of the syntax */ private fun parseCharClassName(): String { val sb = StringBuilder(10) if (index < pattern.size - 2) { // one symbol family if (pattern[index] != '{') { return "Is${pattern[nextIndex()]}" } nextIndex() // Skip '{' var char = pattern[nextIndex()] while (index < pattern.size - 2 && char != '}') { sb.append(char) char = pattern[nextIndex()] } if (char != '}') throw PatternSyntaxException("Unclosed character family", patternString, curTokenIndex) } if (sb.isEmpty()) throw PatternSyntaxException("Empty character family", patternString, curTokenIndex) val res = sb.toString() return when { res.length == 1 -> "Is$res" res.length > 3 && (res.startsWith("Is") || res.startsWith("In")) -> res.substring(2) else -> res } } /** Process hexadecimal integer. */ private fun readHex(radixName: String, max: Int): Int { val builder = StringBuilder(max) val length = pattern.size - 2 var i = 0 while (i < max && index < length) { builder.append(pattern[nextIndex()]) i++ } if (i == max) { try { return builder.toString().toInt(16) } catch (e: NumberFormatException) {} } throw PatternSyntaxException("Invalid $radixName escape sequence", patternString, curTokenIndex) } /** Process octal integer. */ private fun readOctals(): Int { val length = pattern.size - 2 var result = 0 var digit = digitOf(pattern[index], 8) if (digit == -1) { throw PatternSyntaxException("Invalid octal escape sequence", patternString, curTokenIndex) } val max = if (digit > 3) 2 else 3 var i = 0 while (i < max && index < length && digit != -1) { result *= 8 result += digit nextIndex() digit = digitOf(pattern[index], 8) i++ } return result } companion object { // Special characters. val CHAR_DOLLAR = 0xe0000000.toInt() or '$'.toInt() val CHAR_RIGHT_PARENTHESIS = 0xe0000000.toInt() or ')'.toInt() val CHAR_LEFT_SQUARE_BRACKET = 0xe0000000.toInt() or '['.toInt() val CHAR_RIGHT_SQUARE_BRACKET = 0xe0000000.toInt() or ']'.toInt() val CHAR_CARET = 0xe0000000.toInt() or '^'.toInt() val CHAR_VERTICAL_BAR = 0xe0000000.toInt() or '|'.toInt() val CHAR_AMPERSAND = 0xe0000000.toInt() or '&'.toInt() val CHAR_HYPHEN = 0xe0000000.toInt() or '-'.toInt() val CHAR_DOT = 0xe0000000.toInt() or '.'.toInt() val CHAR_LEFT_PARENTHESIS = 0x80000000.toInt() or '('.toInt() val CHAR_NONCAP_GROUP = 0xc0000000.toInt() or '('.toInt() val CHAR_POS_LOOKAHEAD = 0xe0000000.toInt() or '('.toInt() val CHAR_NEG_LOOKAHEAD = 0xf0000000.toInt() or '('.toInt() val CHAR_POS_LOOKBEHIND = 0xf8000000.toInt() or '('.toInt() val CHAR_NEG_LOOKBEHIND = 0xfc000000.toInt() or '('.toInt() val CHAR_ATOMIC_GROUP = 0xfe000000.toInt() or '('.toInt() val CHAR_FLAGS = 0xff000000.toInt() or '('.toInt() val CHAR_START_OF_INPUT = 0x80000000.toInt() or 'A'.toInt() val CHAR_WORD_BOUND = 0x80000000.toInt() or 'b'.toInt() val CHAR_NONWORD_BOUND = 0x80000000.toInt() or 'B'.toInt() val CHAR_PREVIOUS_MATCH = 0x80000000.toInt() or 'G'.toInt() val CHAR_END_OF_INPUT = 0x80000000.toInt() or 'z'.toInt() val CHAR_END_OF_LINE = 0x80000000.toInt() or 'Z'.toInt() // Quantifier modes. val QMOD_GREEDY = 0xe0000000.toInt() val QMOD_RELUCTANT = 0xc0000000.toInt() val QMOD_POSSESSIVE = 0x80000000.toInt() // Quantifiers. val QUANT_STAR = QMOD_GREEDY or '*'.toInt() val QUANT_STAR_P = QMOD_POSSESSIVE or '*'.toInt() val QUANT_STAR_R = QMOD_RELUCTANT or '*'.toInt() val QUANT_PLUS = QMOD_GREEDY or '+'.toInt() val QUANT_PLUS_P = QMOD_POSSESSIVE or '+'.toInt() val QUANT_PLUS_R = QMOD_RELUCTANT or '+'.toInt() val QUANT_ALT = QMOD_GREEDY or '?'.toInt() val QUANT_ALT_P = QMOD_POSSESSIVE or '?'.toInt() val QUANT_ALT_R = QMOD_RELUCTANT or '?'.toInt() val QUANT_COMP = QMOD_GREEDY or '{'.toInt() val QUANT_COMP_P = QMOD_POSSESSIVE or '{'.toInt() val QUANT_COMP_R = QMOD_RELUCTANT or '{'.toInt() /** Returns true if [ch] is a plain token. */ fun isLetter(ch: Int): Boolean { // All supplementary codepoints have integer value that is >= 0. return ch >= 0 } private fun String.codePointAt(index: Int): Int { val high = this[index] if (high.isHighSurrogate() && index + 1 < this.length) { val low = this[index + 1] if (low.isLowSurrogate()) { return Char.toCodePoint(high, low) } } return high.toInt() } // Decomposition =============================================================================================== // Maximum length of decomposition. val MAX_DECOMPOSITION_LENGTH = 4 // Maximum length of Hangul decomposition. Note that MAX_HANGUL_DECOMPOSITION_LENGTH <= MAX_DECOMPOSITION_LENGTH. val MAX_HANGUL_DECOMPOSITION_LENGTH = 3 /* * Following constants are needed for Hangul canonical decomposition. * Hangul decomposition algorithm and constants are taken according * to description at http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf * "3.12 Conjoining Jamo Behavior" */ const val SBase = 0xAC00 const val LBase = 0x1100 const val VBase = 0x1161 const val TBase = 0x11A7 const val SCount = 11172 const val LCount = 19 const val VCount = 21 const val TCount = 28 const val NCount = 588 // Access to the decomposition tables. ========================================================================= /** Gets canonical class for given codepoint from decomposition mappings table. */ fun getCanonicalClass(ch: Int): Int = getCanonicalClassInternal(ch) /** Tests Unicode codepoint if it is a boundary of decomposed Unicode codepoint. */ fun isDecomposedCharBoundary(ch: Int): Boolean = getCanonicalClass(ch) == 0 /** Tests if given codepoint is a canonical decomposition of another codepoint. */ fun hasSingleCodepointDecomposition(ch: Int): Boolean = hasSingleCodepointDecompositionInternal(ch) /** Tests if given codepoint has canonical decomposition and given codepoint's canonical class is not 0. */ fun hasDecompositionNonNullCanClass(ch: Int): Boolean = (ch == 0x0340) or (ch == 0x0341) or (ch == 0x0343) or (ch == 0x0344) /** Gets decomposition for given codepoint from decomposition mappings table. */ fun getDecomposition(ch: Int): IntArray? = getDecompositionInternal(ch) // ============================================================================================================= /** * Normalize given string. */ fun normalize(input: String): String { val inputChars = input.toCharArray() val inputLength = inputChars.size var inputCodePointsIndex = 0 var decompHangulIndex = 0 //codePoints of input val inputCodePoints = IntArray(inputLength) //result of canonical decomposition of input var resCodePoints = IntArray(inputLength * MAX_DECOMPOSITION_LENGTH) //current symbol's codepoint var ch: Int //current symbol's decomposition var decomp: IntArray? //result of canonical and Hangul decomposition of input val decompHangul: IntArray //result of canonical decomposition of input in UTF-16 encoding val result = StringBuilder() var i = 0 while (i < inputLength) { ch = input.codePointAt(i) inputCodePoints[inputCodePointsIndex++] = ch i += if (Char.isSupplementaryCodePoint(ch)) 2 else 1 } // Canonical decomposition based on mappings in decomposition table. var resCodePointsIndex = decomposeString(inputCodePoints, inputCodePointsIndex, resCodePoints) // Canonical ordering. // See http://www.unicode.org/reports/tr15/#Decomposition for details resCodePoints = Lexer.getCanonicalOrder(resCodePoints, resCodePointsIndex) // Decomposition for Hangul syllables. // See http://www.unicode.org/reports/tr15/#Hangul for details decompHangul = IntArray(resCodePoints.size) @Suppress("NAME_SHADOWING") for (i in 0..resCodePointsIndex - 1) { val curSymb = resCodePoints[i] decomp = getHangulDecomposition(curSymb) if (decomp == null) { decompHangul[decompHangulIndex++] = curSymb } else { // Note that Hangul decompositions have length that is equal 2 or 3. decompHangul[decompHangulIndex++] = decomp[0] decompHangul[decompHangulIndex++] = decomp[1] if (decomp.size == 3) { decompHangul[decompHangulIndex++] = decomp[2] } } } // Translating into UTF-16 encoding @Suppress("NAME_SHADOWING") for (i in 0..decompHangulIndex - 1) { result.append(Char.toChars(decompHangul[i])) } return result.toString() } /** * Rearrange codepoints in [inputInts] according to canonical order. Return an array with rearranged codepoints. */ fun getCanonicalOrder(inputInts: IntArray, length: Int): IntArray { val inputLength = if (length < inputInts.size) length else inputInts.size /* * Simple bubble-sort algorithm. Note that many codepoints have 0 canonical class, so this algorithm works * almost lineary in overwhelming majority of cases. This is due to specific of Unicode combining * classes and codepoints. */ for (i in 1..inputLength - 1) { var j = i - 1 val iCanonicalClass = getCanonicalClass(inputInts[i]) val ch: Int if (iCanonicalClass == 0) { continue } while (j > -1) { if (getCanonicalClass(inputInts[j]) > iCanonicalClass) { j = j - 1 } else { break } } ch = inputInts[i] for (k in i downTo j + 1 + 1) { inputInts[k] = inputInts[k - 1] } inputInts[j + 1] = ch } return inputInts } /** * Gets decomposition for given Hangul syllable. * This is an implementation of Hangul decomposition algorithm * according to http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf "3.12 Conjoining Jamo Behavior". */ fun getHangulDecomposition(ch: Int): IntArray? { val SIndex = ch - SBase if (SIndex < 0 || SIndex >= SCount) { return null } else { val L = LBase + SIndex / NCount val V = VBase + SIndex % NCount / TCount var T = SIndex % TCount val decomp: IntArray if (T == 0) { decomp = intArrayOf(L, V) } else { T = TBase + T decomp = intArrayOf(L, V, T) } return decomp } } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/MatchResultImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Match result implementation */ internal class MatchResultImpl /** * @param input an input sequence for matching/searching. * @param regex a [Regex] instance used for matching/searching. * @param rightBound index in the [input] used as a right bound for matching/searching. Exclusive. */ constructor (internal val input: CharSequence, internal val regex: Regex) : MatchResult { // Harmony's implementation ======================================================================================== private val nativePattern = regex.nativePattern private val groupCount = nativePattern.capturingGroupCount private val groupBounds = IntArray(groupCount * 2) { -1 } private val consumers = IntArray(nativePattern.consumersCount + 1) { -1 } // Used by quantifiers to store a count of a quantified expression occurrences. val enterCounters: IntArray = IntArray( maxOf(nativePattern.groupQuantifierCount, 0) ) var startIndex: Int = 0 set (startIndex: Int) { field = startIndex if (previousMatch < 0) { previousMatch = startIndex } } var previousMatch = -1 var mode = Regex.Mode.MATCH // MatchResult interface =========================================================================================== /** The range of indices in the original string where match was captured. */ override val range: IntRange get() = getStart(0) until getEnd(0) /** The substring from the input string captured by this match. */ override val value: String get() = group(0) ?: throw AssertionError("No groupIndex #0 in the match result.") /** * A collection of groups matched by the regular expression. * * This collection has size of `groupCount + 1` where `groupCount` is the count of groups in the regular expression. * Groups are indexed from 1 to `groupCount` and group with the index 0 corresponds to the entire match. */ // Create one object or several ones? override val groups: MatchGroupCollection = object: MatchGroupCollection, AbstractCollection() { override val size: Int get() = this@MatchResultImpl.groupCount override fun iterator(): Iterator { return object: Iterator { var nextIndex: Int = 0 override fun hasNext(): Boolean { return nextIndex < size } override fun next(): MatchGroup? { if (!hasNext()) { throw NoSuchElementException() } return get(nextIndex++) } } } override fun get(index: Int): MatchGroup? { val value = group(index) ?: return null return MatchGroup(value, getStart(index) until getEnd(index)) } } /** * A list of matched indexed group values. * * This list has size of `groupCount + 1` where `groupCount` is the count of groups in the regular expression. * Groups are indexed from 1 to `groupCount` and group with the index 0 corresponds to the entire match. * * If the group in the regular expression is optional and there were no match captured by that group, * corresponding item in [groupValues] is an empty string. * * @sample: samples.text.Regexps.matchDestructuringToGroupValues */ override val groupValues: List get() = mutableListOf().apply { for (i in 0 until groupCount) { this.add(group(i) ?: "") } } override fun next(): MatchResult? { var nextStart = range.endInclusive + 1 // If the current match is empty - shift by 1. if (nextStart == range.start) { nextStart++ } if (nextStart > input.length) { return null } return regex.find(input, nextStart) } // ================================================================================================================= // Harmony's implementation ======================================================================================== fun setConsumed(counter: Int, value: Int) { this.consumers[counter] = value } fun getConsumed(counter: Int): Int { return this.consumers[counter] } fun isCaptured(group: Int): Boolean = getStart(group) >= 0 // Setters and getters for starts and ends of groups =============================================================== internal fun setStart(group: Int, offset: Int) { checkGroup(group) groupBounds[group * 2] = offset } internal fun setEnd(group: Int, offset: Int) { checkGroup(group) groupBounds[group * 2 + 1] = offset } /** * Returns the index of the first character of the text that matched a given group. * * @param group the group, ranging from 0 to groupCount() - 1, with 0 representing the whole pattern. * @return the character index. */ fun getStart(group: Int = 0): Int { checkGroup(group) return groupBounds[group * 2] } /** * Returns the index of the first character following the text that matched a given group. * * @param group the group, ranging from 0 to groupCount() - 1, with 0 representing the whole pattern. * @return the character index. */ fun getEnd(group: Int = 0): Int { checkGroup(group) return groupBounds[group * 2 + 1] } // ================================================================================================== /** * Returns the text that matched a given group of the regular expression. * * @param group the group, ranging from 0 to groupCount() - 1, with 0 representing the whole pattern. * @return the text that matched the group. */ fun group(group: Int = 0): String? { val start = getStart(group) val end = getEnd(group) if (start < 0 || end < 0) { return null } return input.subSequence(getStart(group), getEnd(group)).toString() } /** * Returns the number of groups in the result, which is always equal to * the number of groups in the original regular expression. * * @return the number of groups. */ fun groupCount(): Int { return groupCount - 1 } /* * This method being called after any successful match; For now it's being * used to check zero group for empty match; */ fun finalizeMatch() { if (this.groupBounds[0] == -1) { this.groupBounds[0] = this.startIndex this.groupBounds[1] = this.startIndex } previousMatch = getEnd() } private fun checkGroup(group: Int) { if (group < 0 || group > groupCount) { throw IndexOutOfBoundsException("Group index out of bounds: $group") } } fun updateGroup(index: Int, srtOffset: Int, endOffset: Int) { checkGroup(index) groupBounds[index * 2] = srtOffset groupBounds[index * 2 + 1] = endOffset } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/Pattern.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** Represents a compiled pattern used by [Regex] for matching, searching, or replacing strings. */ internal class Pattern(val pattern: String, flags: Int = 0) { var flags = flags private set /** A lexer instance used to get tokens from the pattern. */ private val lexemes = Lexer(pattern, flags) /* All back references that may be used in pattern. */ private val backRefs = arrayOfNulls(BACK_REF_NUMBER) /** Is true if back referenced sets replacement by second compilation pass is needed.*/ private var needsBackRefReplacement = false /** Global count of found capturing groups. */ var capturingGroupCount = 0 private set /** A number of group quantifiers in the pattern */ var groupQuantifierCount = 0 private set /** * A number of consumers found in the pattern. * Consumer is any expression ending with an FSet except capturing groups (they are counted by [capturingGroupCount]) */ var consumersCount = 0 private set /** A node to start a matching/searching process by call startNode.matches/startNode.find. */ internal val startNode: AbstractSet /** Compiles the given pattern */ init { if (flags != 0 && flags or flagsBitMask != flagsBitMask) { throw IllegalArgumentException("Invalid match flags value") } startNode = processExpression(-1, this.flags, null) if (!lexemes.isEmpty()) { throw PatternSyntaxException("Trailing characters", pattern, lexemes.curTokenIndex) } // Finalize compilation if (needsBackRefReplacement) { startNode.processSecondPass() } } override fun toString(): String = pattern /** Return true if the pattern has the specified flag */ private fun hasFlag(flag: Int): Boolean = flags and flag == flag // Compilation methods. ============================================================================================ /** A->(a|)+ */ private fun processAlternations(last: AbstractSet): AbstractSet { val auxRange = CharClass(hasFlag(Pattern.CASE_INSENSITIVE)) while (!lexemes.isEmpty() && lexemes.isLetter() && (lexemes.lookAhead == 0 || lexemes.lookAhead == Lexer.CHAR_VERTICAL_BAR || lexemes.lookAhead == Lexer.CHAR_RIGHT_PARENTHESIS)) { auxRange.add(lexemes.next()) if (lexemes.currentChar == Lexer.CHAR_VERTICAL_BAR) { lexemes.next() } } val rangeSet = processRangeSet(auxRange) rangeSet.next = last return rangeSet } /** E->AE; E->S|E; E->S; A->(a|)+ E->S(|S)* */ private fun processExpression(ch: Int, newFlags: Int, last: AbstractSet?): AbstractSet { val children = ArrayList() val savedFlags = flags var saveChangedFlags = false if (newFlags != flags) { flags = newFlags } // Create a right finalizing set. val fSet: FSet when (ch) { // Special groups: non-capturing, look ahead/behind etc. Lexer.CHAR_NONCAP_GROUP -> fSet = NonCapFSet(consumersCount++) Lexer.CHAR_POS_LOOKAHEAD, Lexer.CHAR_NEG_LOOKAHEAD -> fSet = AheadFSet() Lexer.CHAR_POS_LOOKBEHIND, Lexer.CHAR_NEG_LOOKBEHIND -> fSet = BehindFSet(consumersCount++) Lexer.CHAR_ATOMIC_GROUP -> fSet = AtomicFSet(consumersCount++) // A Capturing group. else -> { if (last == null) { // Whole pattern - group #0. fSet = FinalSet() saveChangedFlags = true } else { fSet = FSet(capturingGroupCount) } if (capturingGroupCount < BACK_REF_NUMBER) { backRefs[capturingGroupCount] = fSet } capturingGroupCount++ } } //Process to EOF or ')' do { val child: AbstractSet when { // a|... lexemes.isLetter() && lexemes.lookAhead == Lexer.CHAR_VERTICAL_BAR -> child = processAlternations(fSet) // ..|.., e.g. in "a||||b" lexemes.currentChar == Lexer.CHAR_VERTICAL_BAR -> { child = EmptySet(fSet) lexemes.next() } else -> { child = processSubExpression(fSet) if (lexemes.currentChar == Lexer.CHAR_VERTICAL_BAR) { lexemes.next() } } } children.add(child) } while (!(lexemes.isEmpty() || lexemes.currentChar == Lexer.CHAR_RIGHT_PARENTHESIS)) // |) or | - add an empty node. if (lexemes.lookBack == Lexer.CHAR_VERTICAL_BAR) { children.add(EmptySet(fSet)) } // Restore flags. if (flags != savedFlags && !saveChangedFlags) { flags = savedFlags lexemes.restoreFlags(flags) } when (ch) { Lexer.CHAR_NONCAP_GROUP -> return NonCapturingJointSet(children, fSet) Lexer.CHAR_POS_LOOKAHEAD -> return PositiveLookAheadSet(children, fSet) Lexer.CHAR_NEG_LOOKAHEAD -> return NegativeLookAheadSet(children, fSet) Lexer.CHAR_POS_LOOKBEHIND -> return PositiveLookBehindSet(children, fSet) Lexer.CHAR_NEG_LOOKBEHIND -> return NegativeLookBehindSet(children, fSet) Lexer.CHAR_ATOMIC_GROUP -> return AtomicJointSet(children, fSet) else -> when (children.size) { 0 -> return EmptySet(fSet) 1 -> return SingleSet(children[0], fSet) else -> return JointSet(children, fSet) } } } /** * T->aaa */ private fun processSequence(): AbstractSet { val substring = StringBuilder() while (!lexemes.isEmpty() && lexemes.isLetter() && !lexemes.isSurrogate() && (!lexemes.isNextSpecial && lexemes.lookAhead == 0 // End of a pattern. || !lexemes.isNextSpecial && Lexer.isLetter(lexemes.lookAhead) || lexemes.lookAhead == Lexer.CHAR_RIGHT_PARENTHESIS || lexemes.lookAhead and 0x8000ffff.toInt() == Lexer.CHAR_LEFT_PARENTHESIS || lexemes.lookAhead == Lexer.CHAR_VERTICAL_BAR || lexemes.lookAhead == Lexer.CHAR_DOLLAR)) { val ch = lexemes.next() if (Char.isSupplementaryCodePoint(ch)) { substring.append(Char.toChars(ch)) } else { substring.append(ch.toChar()) } } return SequenceSet(substring, hasFlag(CASE_INSENSITIVE)) } /** * D->a */ private fun processDecomposedChar(): AbstractSet { val codePoints = IntArray(Lexer.MAX_DECOMPOSITION_LENGTH) val codePointsHangul: CharArray var readCodePoints = 0 var curSymb = -1 var curSymbIndex = -1 if (!lexemes.isEmpty() && lexemes.isLetter()) { curSymb = lexemes.next() codePoints[readCodePoints] = curSymb curSymbIndex = curSymb - Lexer.LBase } /* * We process decomposed Hangul syllable LV or LVT or process jamo L. * See http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf * "3.12 Conjoining Jamo Behavior" */ if (curSymbIndex >= 0 && curSymbIndex < Lexer.LCount) { codePointsHangul = CharArray(Lexer.MAX_HANGUL_DECOMPOSITION_LENGTH) codePointsHangul[readCodePoints++] = curSymb.toChar() curSymb = lexemes.currentChar curSymbIndex = curSymb - Lexer.VBase if (curSymbIndex >= 0 && curSymbIndex < Lexer.VCount) { codePointsHangul[readCodePoints++] = curSymb.toChar() lexemes.next() curSymb = lexemes.currentChar curSymbIndex = curSymb - Lexer.TBase if (curSymbIndex >= 0 && curSymbIndex < Lexer.TCount) { codePointsHangul[@Suppress("UNUSED_CHANGED_VALUE")readCodePoints++] = curSymb.toChar() lexemes.next() //LVT syllable return HangulDecomposedCharSet(codePointsHangul, 3) } else { //LV syllable return HangulDecomposedCharSet(codePointsHangul, 2) } } else { //L jamo return CharSet(codePointsHangul[0], hasFlag(CASE_INSENSITIVE)) } /* * We process single codepoint or decomposed codepoint. * We collect decomposed codepoint and obtain * one DecomposedCharSet. */ } else { readCodePoints++ while (readCodePoints < Lexer.MAX_DECOMPOSITION_LENGTH && !lexemes.isEmpty() && lexemes.isLetter() && !Lexer.isDecomposedCharBoundary(lexemes.currentChar)) { codePoints[readCodePoints++] = lexemes.next() } /* * We have read an ordinary symbol. */ if (readCodePoints == 1 && !Lexer.hasSingleCodepointDecomposition(codePoints[0])) { return processCharSet(codePoints[0]) } else { return DecomposedCharSet(codePoints, readCodePoints) } } } /** * S->BS; S->QS; S->Q; B->a+ */ private fun processSubExpression(last: AbstractSet): AbstractSet { var cur: AbstractSet when { lexemes.isLetter() && !lexemes.isNextSpecial && Lexer.isLetter(lexemes.lookAhead) -> { when { hasFlag(Pattern.CANON_EQ) -> { cur = processDecomposedChar() if (!lexemes.isEmpty() && (lexemes.currentChar != Lexer.CHAR_RIGHT_PARENTHESIS || last is FinalSet) && lexemes.currentChar != Lexer.CHAR_VERTICAL_BAR && !lexemes.isLetter()) { cur = processQuantifier(last, cur) } } lexemes.isHighSurrogate() || lexemes.isLowSurrogate() -> { val term = processTerminal(last) cur = processQuantifier(last, term) } else -> { cur = processSequence() } } } lexemes.currentChar == Lexer.CHAR_RIGHT_PARENTHESIS -> { if (last is FinalSet) { throw PatternSyntaxException("unmatched )", pattern, lexemes.curTokenIndex) } cur = EmptySet(last) } else -> { val term = processTerminal(last) cur = processQuantifier(last, term) } } if (!lexemes.isEmpty() && (lexemes.currentChar != Lexer.CHAR_RIGHT_PARENTHESIS || last is FinalSet) && lexemes.currentChar != Lexer.CHAR_VERTICAL_BAR) { val next = processSubExpression(last) if (cur is LeafQuantifierSet // '*' or '{0,}' quantifier && cur.max == Quantifier.INF && cur.min == 0 && !next.first(cur.innerSet)) { // An Optimizer node for the case where there is no intersection with the next node cur = UnifiedQuantifierSet(cur) } cur.next = next } else { cur.next = last } return cur } /** * Q->T(*|+|?...) also do some optimizations. */ private fun processQuantifier(last: AbstractSet, term: AbstractSet): AbstractSet { val quant = lexemes.currentChar if (term !is LeafSet) { return when (quant) { Lexer.QUANT_STAR, Lexer.QUANT_PLUS -> { val q: QuantifierSet lexemes.next() if (term.type == AbstractSet.TYPE_DOTSET) { q = DotQuantifierSet(term, last, quant, AbstractLineTerminator.getInstance(flags), hasFlag(Pattern.DOTALL)) } else { q = GroupQuantifierSet(Quantifier.fromLexerToken(quant), term, last, quant, groupQuantifierCount++) } term.next = q q } Lexer.QUANT_ALT -> { lexemes.next() val q = GroupQuantifierSet(Quantifier.fromLexerToken(quant), term, last, quant, groupQuantifierCount++) term.next = q q } Lexer.QUANT_STAR_R, Lexer.QUANT_PLUS_R, Lexer.QUANT_ALT_R -> { lexemes.next() val q = ReluctantGroupQuantifierSet(Quantifier.fromLexerToken(quant), term, last, quant, groupQuantifierCount++) term.next = q q } Lexer.QUANT_PLUS_P, Lexer.QUANT_STAR_P, Lexer.QUANT_ALT_P -> { lexemes.next() PossessiveGroupQuantifierSet(Quantifier.fromLexerToken(quant), term, last, quant, groupQuantifierCount++) } Lexer.QUANT_COMP -> { val q = GroupQuantifierSet(lexemes.nextSpecial() as Quantifier, term, last, Lexer.QUANT_ALT, groupQuantifierCount++) term.next = q q } Lexer.QUANT_COMP_R -> { val q = ReluctantGroupQuantifierSet(lexemes.nextSpecial() as Quantifier, term, last, Lexer.QUANT_ALT, groupQuantifierCount++) term.next = q q } Lexer.QUANT_COMP_P -> { return PossessiveGroupQuantifierSet(lexemes.nextSpecial() as Quantifier, term, last, Lexer.QUANT_ALT, groupQuantifierCount++) } else -> term } } else { val leaf: LeafSet = term return when (quant) { Lexer.QUANT_STAR, Lexer.QUANT_PLUS -> { lexemes.next() val q = LeafQuantifierSet(Quantifier.fromLexerToken(quant), leaf, last, quant) leaf.next = q q } Lexer.QUANT_STAR_R, Lexer.QUANT_PLUS_R -> { lexemes.next() val q = ReluctantLeafQuantifierSet(Quantifier.fromLexerToken(quant), leaf, last, quant) leaf.next = q q } Lexer.QUANT_PLUS_P, Lexer.QUANT_STAR_P -> { lexemes.next() val q = PossessiveLeafQuantifierSet(Quantifier.fromLexerToken(quant), leaf, last, quant) leaf.next = q q } Lexer.QUANT_ALT -> { lexemes.next() LeafQuantifierSet(Quantifier.altQuantifier, leaf, last, Lexer.QUANT_ALT) } Lexer.QUANT_ALT_R -> { lexemes.next() ReluctantLeafQuantifierSet(Quantifier.altQuantifier, leaf, last, Lexer.QUANT_ALT_R) } Lexer.QUANT_ALT_P -> { lexemes.next() PossessiveLeafQuantifierSet(Quantifier.altQuantifier, leaf, last, Lexer.QUANT_ALT_P) } Lexer.QUANT_COMP -> { LeafQuantifierSet(lexemes.nextSpecial() as Quantifier, leaf, last, Lexer.QUANT_COMP) } Lexer.QUANT_COMP_R -> { ReluctantLeafQuantifierSet(lexemes.nextSpecial() as Quantifier, leaf, last, Lexer.QUANT_COMP_R) } Lexer.QUANT_COMP_P -> { ReluctantLeafQuantifierSet(lexemes.nextSpecial() as Quantifier, leaf, last, Lexer.QUANT_COMP_P) } else -> term } } } /** * T-> letter|[range]|{char-class}|(E) */ private fun processTerminal(last: AbstractSet): AbstractSet { val term: AbstractSet var char = lexemes.currentChar // Process flags: (?...)(?...)... while (char and 0xff00ffff.toInt() == Lexer.CHAR_FLAGS) { lexemes.next() flags = (char shr 16) and flagsBitMask char = lexemes.currentChar } // The terminal is some kind of group: (E). Call processExpression for it. if (char and 0x8000ffff.toInt() == Lexer.CHAR_LEFT_PARENTHESIS) { lexemes.next() var newFlags = flags if (char and 0xff00ffff.toInt() == Lexer.CHAR_NONCAP_GROUP) { newFlags = (char shr 16) and flagsBitMask } term = processExpression(char and 0xff00ffff.toInt(), newFlags, last) // Remove flags from the token. if (lexemes.currentChar != Lexer.CHAR_RIGHT_PARENTHESIS) { throw PatternSyntaxException("unmatched (", pattern, lexemes.curTokenIndex) } lexemes.next() } else { // Other terminals. when (char) { Lexer.CHAR_LEFT_SQUARE_BRACKET -> { // Range: [...] lexemes.next() var negative = false if (lexemes.currentChar == Lexer.CHAR_CARET) { negative = true lexemes.next() } term = processRange(negative, last) if (lexemes.currentChar != Lexer.CHAR_RIGHT_SQUARE_BRACKET) { throw PatternSyntaxException("unmatched [", pattern, lexemes.curTokenIndex) } lexemes.setModeWithReread(Lexer.Mode.PATTERN) lexemes.next() } Lexer.CHAR_DOT -> { // Dot: . lexemes.next() term = DotSet(AbstractLineTerminator.getInstance(flags), hasFlag(DOTALL)) } Lexer.CHAR_CARET -> { // Beginning of the string: ^ lexemes.next() term = SOLSet(AbstractLineTerminator.getInstance(flags), hasFlag(MULTILINE)) consumersCount++ } Lexer.CHAR_DOLLAR -> { // End of the string: $ lexemes.next() term = EOLSet(consumersCount++, AbstractLineTerminator.getInstance(flags), hasFlag(MULTILINE)) } // Word / non-word boundary. Lexer.CHAR_WORD_BOUND -> { lexemes.next() term = WordBoundarySet(true) } Lexer.CHAR_NONWORD_BOUND -> { lexemes.next() term = WordBoundarySet(false) } Lexer.CHAR_END_OF_INPUT -> { // End of an input: \z lexemes.next() term = EOISet() } Lexer.CHAR_END_OF_LINE -> { // End of a line: \Z lexemes.next() term = EOLSet(consumersCount++, AbstractLineTerminator.getInstance(flags)) } Lexer.CHAR_START_OF_INPUT -> { // Start if an input: \A lexemes.next() term = SOLSet(AbstractLineTerminator.getInstance(flags)) } Lexer.CHAR_PREVIOUS_MATCH -> { // A previous match: \G lexemes.next() term = PreviousMatchSet() } // Back references: \1, \2 etc. 0x80000000.toInt() or '1'.toInt(), 0x80000000.toInt() or '2'.toInt(), 0x80000000.toInt() or '3'.toInt(), 0x80000000.toInt() or '4'.toInt(), 0x80000000.toInt() or '5'.toInt(), 0x80000000.toInt() or '6'.toInt(), 0x80000000.toInt() or '7'.toInt(), 0x80000000.toInt() or '8'.toInt(), 0x80000000.toInt() or '9'.toInt() -> { val number = (char and 0x7FFFFFFF) - '0'.toInt() if (number < capturingGroupCount) { // All is ok - the group exists. lexemes.next() term = BackReferenceSet(number, consumersCount++, hasFlag(CASE_INSENSITIVE)) // backRefs[number] is proved to be not null because the group is already created (number < capturingGroupCount) backRefs[number]!!.isBackReferenced = true needsBackRefReplacement = true // And process back references in the second pass. } else { throw PatternSyntaxException("No such group yet exists at this point in the pattern", pattern, lexemes.curTokenIndex) } } // A special token (\D, \w etc), 'u0000' or the end of the pattern. 0 -> { val cc: AbstractCharClass? = lexemes.curSpecialToken as AbstractCharClass? when { cc != null -> { term = processRangeSet(cc) lexemes.next() } !lexemes.isEmpty() -> { term = CharSet(char.toChar()) lexemes.next() } else -> term = EmptySet(last) } } else -> { when { // A regular character. char >= 0 && !lexemes.isSpecial -> { term = processCharSet(char) lexemes.next() } char == Lexer.CHAR_VERTICAL_BAR -> { term = EmptySet(last) } char == Lexer.CHAR_RIGHT_PARENTHESIS -> { if (last is FinalSet) { throw PatternSyntaxException("unmatched )", pattern, lexemes.curTokenIndex) } term = EmptySet(last) } else -> { val current = if (lexemes.isSpecial) lexemes.curSpecialToken.toString() else char.toString() throw PatternSyntaxException("Dangling meta construction: $current", pattern, lexemes.curTokenIndex) } } } } } return term } /** * Process [...] ranges */ private fun processRange(negative: Boolean, last: AbstractSet): AbstractSet { val res = processRangeExpression(negative) val rangeSet = processRangeSet(res) rangeSet.next = last return rangeSet } private fun processRangeExpression(alt: Boolean): CharClass { var result = CharClass(hasFlag(Pattern.CASE_INSENSITIVE), alt) var buffer = -1 var intersection = false var firstInClass = true var notClosed = lexemes.currentChar != Lexer.CHAR_RIGHT_SQUARE_BRACKET while (!lexemes.isEmpty() && (notClosed || firstInClass)) { when (lexemes.currentChar) { Lexer.CHAR_RIGHT_SQUARE_BRACKET -> { if (buffer >= 0) { result.add(buffer) } buffer = ']'.toInt() lexemes.next() } Lexer.CHAR_LEFT_SQUARE_BRACKET -> { if (buffer >= 0) { result.add(buffer) buffer = -1 } lexemes.next() var negative = false if (lexemes.currentChar == Lexer.CHAR_CARET) { lexemes.next() negative = true } if (intersection) result.intersection(processRangeExpression(negative)) else result.union(processRangeExpression(negative)) intersection = false lexemes.next() } Lexer.CHAR_AMPERSAND -> { if (buffer >= 0) { result.add(buffer) } buffer = lexemes.next() // buffer == Lexer.CHAR_AMPERSAND since next() returns currentChar. /* * If there is a start for subrange we will do an intersection * otherwise treat '&' as a normal character */ if (lexemes.currentChar == Lexer.CHAR_AMPERSAND) { if (lexemes.lookAhead == Lexer.CHAR_LEFT_SQUARE_BRACKET) { lexemes.next() intersection = true buffer = -1 } else { lexemes.next() if (firstInClass) { // Skip "&&" at "[&&...]" or "[^&&...]" result = processRangeExpression(false) } else { // Ignore "&&" at "[X&&]" ending where X != empty string if (lexemes.currentChar != Lexer.CHAR_RIGHT_SQUARE_BRACKET) { result.intersection(processRangeExpression(false)) } } } } else { //treat '&' as a normal character buffer = '&'.toInt() } } Lexer.CHAR_HYPHEN -> { if (firstInClass || lexemes.lookAhead == Lexer.CHAR_RIGHT_SQUARE_BRACKET || lexemes.lookAhead == Lexer.CHAR_LEFT_SQUARE_BRACKET || buffer < 0) { // Treat the hypen as a normal character. if (buffer >= 0) { result.add(buffer) } buffer = '-'.toInt() lexemes.next() } else { // A range. lexemes.next() var cur = lexemes.currentChar if (!lexemes.isSpecial && (cur >= 0 || lexemes.lookAhead == Lexer.CHAR_RIGHT_SQUARE_BRACKET || lexemes.lookAhead == Lexer.CHAR_LEFT_SQUARE_BRACKET || buffer < 0)) { try { if (!Lexer.isLetter(cur)) { cur = cur and 0xFFFF } result.add(buffer, cur) } catch (e: Exception) { throw PatternSyntaxException("Illegal character range", pattern, lexemes.curTokenIndex) } lexemes.next() buffer = -1 } else { throw PatternSyntaxException("Illegal character range", pattern, lexemes.curTokenIndex) } } } Lexer.CHAR_CARET -> { if (buffer >= 0) { result.add(buffer) } buffer = '^'.toInt() lexemes.next() } 0 -> { if (buffer >= 0) { result.add(buffer) } val cs = lexemes.curSpecialToken as AbstractCharClass? if (cs != null) { result.add(cs) buffer = -1 } else { buffer = 0 } lexemes.next() } else -> { if (buffer >= 0) { result.add(buffer) } buffer = lexemes.next() } } firstInClass = false notClosed = lexemes.currentChar != Lexer.CHAR_RIGHT_SQUARE_BRACKET } if (notClosed) { throw PatternSyntaxException("Missing ']'", pattern, lexemes.curTokenIndex) } if (buffer >= 0) { result.add(buffer) } return result } private fun processRangeSet(charClass: AbstractCharClass): AbstractSet { if (charClass.hasLowHighSurrogates()) { val lowHighSurrRangeSet = SurrogateRangeSet(charClass.classWithSurrogates()) if (charClass.mayContainSupplCodepoints) { return CompositeRangeSet(SupplementaryRangeSet(charClass.classWithoutSurrogates(), hasFlag(CASE_INSENSITIVE)), lowHighSurrRangeSet) } return CompositeRangeSet(RangeSet(charClass.classWithoutSurrogates(), hasFlag(CASE_INSENSITIVE)), lowHighSurrRangeSet) } if (charClass.mayContainSupplCodepoints) { return SupplementaryRangeSet(charClass, hasFlag(CASE_INSENSITIVE)) } return RangeSet(charClass, hasFlag(CASE_INSENSITIVE)) } private fun processCharSet(ch: Int): AbstractSet { val isSupplCodePoint = Char.isSupplementaryCodePoint(ch) return when { isSupplCodePoint -> SequenceSet(Char.toChars(ch).concatToString(0, 2), hasFlag(CASE_INSENSITIVE)) ch.toChar().isLowSurrogate() -> LowSurrogateCharSet(ch.toChar()) ch.toChar().isHighSurrogate() -> HighSurrogateCharSet(ch.toChar()) else -> CharSet(ch.toChar(), hasFlag(CASE_INSENSITIVE)) } } companion object { //TODO: Use RegexOption enum here. // Flags. /** * This constant specifies that a pattern matches Unix line endings ('\n') * only against the '.', '^', and '$' meta characters. */ val UNIX_LINES = 1 shl 0 /** * This constant specifies that a `Pattern` is matched * case-insensitively. That is, the patterns "a+" and "A+" would both match * the string "aAaAaA". */ val CASE_INSENSITIVE = 1 shl 1 /** * This constant specifies that a `Pattern` may contain whitespace or * comments. Otherwise comments and whitespace are taken as literal * characters. */ val COMMENTS = 1 shl 2 /** * This constant specifies that the meta characters '^' and '$' match only * the beginning and end end of an input line, respectively. Normally, they * match the beginning and the end of the complete input. */ val MULTILINE = 1 shl 3 /** * This constant specifies that the whole `Pattern` is to be taken * literally, that is, all meta characters lose their meanings. */ val LITERAL = 1 shl 4 /** * This constant specifies that the '.' meta character matches arbitrary * characters, including line endings, which is normally not the case. */ val DOTALL = 1 shl 5 /** * This constant specifies that a character in a `Pattern` and a * character in the input string only match if they are canonically * equivalent. */ val CANON_EQ = 1 shl 6 /** Max number of back references supported. */ internal val BACK_REF_NUMBER = 10 /** A bit mask that includes all defined match flags */ internal val flagsBitMask = Pattern.UNIX_LINES or Pattern.CASE_INSENSITIVE or Pattern.COMMENTS or Pattern.MULTILINE or Pattern.LITERAL or Pattern.DOTALL or Pattern.CANON_EQ /** * Quotes a given string using "\Q" and "\E", so that all other meta-characters lose their special meaning. * If the string is used for a `Pattern` afterwards, it can only be matched literally. */ fun quote(s: String): String { return StringBuilder() .append("\\Q") .append(s.replace("\\E", "\\E\\\\E\\Q")) .append("\\E").toString() } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/Quantifier.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex import kotlin.IllegalArgumentException /** * Represents RE quantifier; contains two fields responsible for min and max number of repetitions. * -1 as a maximum number of repetition represents infinity(i.e. +,*). */ internal class Quantifier(val min: Int, val max: Int = min) : SpecialToken() { init { if (min < 0 || max < -1) { throw IllegalArgumentException("Incorrect quantifier value: $this") } } override fun toString() = "{$min, ${if (max == INF) "" else max}}" override val type: Type = SpecialToken.Type.QUANTIFIER companion object { val starQuantifier = Quantifier(0, -1) val plusQuantifier = Quantifier(1, -1) val altQuantifier = Quantifier(0, 1) val INF = -1 fun fromLexerToken(token: Int) = when(token) { Lexer.QUANT_STAR, Lexer.QUANT_STAR_P, Lexer.QUANT_STAR_R -> starQuantifier Lexer.QUANT_ALT, Lexer.QUANT_ALT_P, Lexer.QUANT_ALT_R -> altQuantifier Lexer.QUANT_PLUS, Lexer.QUANT_PLUS_P, Lexer.QUANT_PLUS_R -> plusQuantifier else -> throw IllegalArgumentException("Unknown quantifier token: $token") } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/AbstractSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex import kotlin.AssertionError /** Basic class for sets which have no complex next node handling. */ internal abstract class SimpleSet : AbstractSet { override var next: AbstractSet = dummyNext constructor() constructor(type : Int): super(type) } /** * Basic class for nodes, representing given regular expression. * Note: (Almost) All the classes representing nodes has 'set' suffix. */ internal abstract class AbstractSet(val type: Int = 0) { companion object { const val TYPE_LEAF = 1 shl 0 const val TYPE_FSET = 1 shl 1 const val TYPE_QUANT = 1 shl 3 const val TYPE_DOTSET = 0x80000000.toInt() or '.'.toInt() val dummyNext = object : AbstractSet() { override var next: AbstractSet get() = throw AssertionError("This method is not expected to be called.") @Suppress("UNUSED_PARAMETER") set(value) {} override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl) = throw AssertionError("This method is not expected to be called.") override fun hasConsumed(matchResult: MatchResultImpl): Boolean = throw AssertionError("This method is not expected to be called.") override fun processSecondPassInternal(): AbstractSet = this override fun processSecondPass(): AbstractSet = this } } var secondPassVisited = false abstract var next: AbstractSet protected open val name: String get() = "" /** * Checks if this node matches in given position and recursively call * next node matches on positive self match. Returns positive integer if * entire match succeed, negative otherwise. * @param startIndex - string index to start from. * @param testString - input string. * @param matchResult - MatchResult to sore result into. * @return -1 if match fails or n > 0; */ abstract fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int /** * Attempts to apply pattern starting from this set/startIndex; returns * index this search was started from, if value is negative, this means that * this search didn't succeed, additional information could be obtained via * matchResult. * * Note: this is default implementation for find method, it's based on * matches, subclasses do not have to override find method unless * more effective find method exists for a particular node type * (sequence, i.e. substring, for example). Same applies for find back * method. * * @param startIndex - starting index. * @param testString - string to search in. * @param matchResult - result of the match. * @return last searched index. */ open fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int = (startIndex..testString.length).firstOrNull { index -> matches(index, testString, matchResult) >= 0 } ?: -1 /** * @param leftLimit - an index, to finish search back (left limit, inclusive). * @param rightLimit - an index to start search from (right limit, exclusive). * @param testString - test string. * @param matchResult - match result. * @return an index to start back search next time if this search fails(new left bound); * if this search fails the value is negative. */ open fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int = (rightLimit downTo leftLimit).firstOrNull { index -> matches(index, testString, matchResult) >= 0 } ?: -1 /** * Returns true, if this node has consumed any characters during * positive match attempt, for example node representing character always * consumes one character if it matches. If particular node matches * empty sting this method will return false. * * @param matchResult - match result; * @return true if the node consumes any character and false otherwise. */ abstract fun hasConsumed(matchResult: MatchResultImpl): Boolean /** * Returns true if the given node intersects with this one, false otherwise. * This method is being used for quantifiers construction, lets consider the * following regular expression (a|b)*ccc. (a|b) does not intersects with "ccc" * and thus can be quantified greedily (w/o kickbacks), like *+ instead of *. * @param set - A node the intersection is checked for. Usually a previous node. * @return true if the given node intersects with this one, false otherwise. */ open fun first(set: AbstractSet): Boolean = true /** * This method is used for replacement backreferenced sets. * * @return null if current node need not to be replaced, * [JointSet] which is replacement of current node otherwise. */ open fun processBackRefReplacement(): JointSet? { return null } /** * This method performs the second pass without checking if it's already performed or not. */ protected open fun processSecondPassInternal(): AbstractSet { if (!next.secondPassVisited) { this.next = next.processSecondPass() } return processBackRefReplacement() ?: this } /** * This method is used for traversing nodes after the first stage of compilation. */ open fun processSecondPass(): AbstractSet { secondPassVisited = true return processSecondPassInternal() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/AtomicJointSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * This class represent atomic group (?>X), once X matches, this match become unchangeable till the end of the match. */ open internal class AtomicJointSet(children: List, fSet: FSet) : NonCapturingJointSet(children, fSet) { /** Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val start = matchResult.getConsumed(groupIndex) matchResult.setConsumed(groupIndex, startIndex) children.forEach { val shift = it.matches(startIndex, testString, matchResult) if (shift >= 0) { // AtomicFset always returns true, but saves the index to run this next.match() from; return next.matches((fSet as AtomicFSet).index, testString, matchResult) } } matchResult.setConsumed(groupIndex, start) return -1 } override val name: String get() = "AtomicJointSet" override var next: AbstractSet = dummyNext } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/BackReferenceSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Back reference node; */ open internal class BackReferenceSet(val referencedGroup: Int, val consCounter: Int, val ignoreCase: Boolean = false) : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val groupValue = getReferencedGroupValue(matchResult) if (groupValue == null || startIndex + groupValue.length > testString.length) { return -1 } if (testString.startsWith(groupValue, startIndex, ignoreCase)) { matchResult.setConsumed(consCounter, groupValue.length) return next.matches(startIndex + groupValue.length, testString, matchResult) } return -1 } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val groupValue = getReferencedGroupValue(matchResult) if (groupValue == null || startIndex + groupValue.length > testString.length) { return -1 } var index = startIndex while (index <= testString.length) { index = testString.indexOf(groupValue, index, ignoreCase) if (index < 0) { return -1 } if (index < testString.length && next.matches(index + groupValue.length, testString, matchResult) >=0) { return index } index++ } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val groupValue = getReferencedGroupValue(matchResult) if (groupValue == null || leftLimit + groupValue.length > rightLimit) { return -1 } var index = rightLimit while (index >= leftLimit) { index = testString.lastIndexOf(groupValue, index, ignoreCase) if (index < 0) { return -1 } if (index >= 0 && next.matches(index + groupValue.length, testString, matchResult) >= 0) { return index } index-- } return -1 } protected fun getReferencedGroupValue(matchResult: MatchResultImpl) = matchResult.group(referencedGroup) override val name: String get() = "back reference: $referencedGroup" override fun hasConsumed(matchResult: MatchResultImpl): Boolean { val result = matchResult.getConsumed(consCounter) != 0 matchResult.setConsumed(consCounter, -1) return result } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/CharSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents node accepting single character. */ open internal class CharSet(char: Char, val ignoreCase: Boolean = false) : LeafSet() { // We use only low case characters when working in case insensitive mode. val char: Char = if (ignoreCase) char.toLowerCase() else char // Overrides ======================================================================================================= override fun accepts(startIndex: Int, testString: CharSequence): Int { if (ignoreCase) { return if (this.char == testString[startIndex].toLowerCase()) 1 else -1 } else { return if (this.char == testString[startIndex]) 1 else -1 } } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex while (index < testString.length) { index = testString.indexOf(char, index, ignoreCase) if (index < 0) { return -1 } if (next.matches(index + charCount, testString, matchResult) >= 0) { return index } index++ } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = rightLimit while (index >= leftLimit) { index = testString.lastIndexOf(char, index, ignoreCase) if (index < 0) { return -1 } if (next.matches(index + charCount, testString, matchResult) >= 0) { return index } index-- } return -1 } override val name: String get()= char.toString() override fun first(set: AbstractSet): Boolean { if (ignoreCase) { return super.first(set) } return when (set) { is CharSet -> set.char == char is RangeSet -> set.accepts(0, char.toString()) > 0 is SupplementaryCharSet -> false is SupplementaryRangeSet -> set.contains(char) else -> true } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/CompositeRangeSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * * Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. * * COPYRIGHT AND PERMISSION NOTICE * * Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. Permission is * hereby granted, free of charge, to any person obtaining a copy of the * Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") * to deal in the Data Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Data Files or Software, and to permit persons * to whom the Data Files or Software are furnished to do so, provided that * (a) the above copyright notice(s) and this permission notice appear with * all copies of the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated documentation, * and (c) there is clear notice in each modified Data File or in the Software * as well as in the documentation associated with the Data File(s) or Software * that the data or software has been modified. * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in these Data Files or Software without prior written * authorization of the copyright holder. * * 2. Additional terms from the Database: * * Copyright © 1995-1999 Unicode, Inc. All Rights reserved. * * Disclaimer * * The Unicode Character Database is provided as is by Unicode, Inc. * No claims are made as to fitness for any particular purpose. No warranties * of any kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been purchased * on magnetic or optical media from Unicode, Inc., the sole remedy for any claim * will be exchange of defective media within 90 days of receipt. This disclaimer * is applicable for all other data files accompanying the Unicode Character Database, * some of which have been compiled by the Unicode Consortium, and some of which * have been supplied by other sources. * * Limitations on Rights to Redistribute This Data * * Recipient is granted the right to make copies in any form for internal * distribution and to freely use the information supplied in the creation of * products supporting the UnicodeTM Standard. The files in * the Unicode Character Database can be redistributed to third parties or other * organizations (whether for profit or not) as long as this notice and the disclaimer * notice are retained. Information can be extracted from these files and used * in documentation or programs, as long as there is an accompanying notice * indicating the source. */ package kotlin.text.regex /** * This class is used to split the range that contains surrogate characters into two ranges: * the first consisting of these surrogate characters and the second consisting of all others characters * from the parent range. This class represents the parent range split in such a manner. */ internal class CompositeRangeSet(/* range without surrogates */ val withoutSurrogates: AbstractSet, /* range containing surrogates only */ val surrogates: AbstractSet) : SimpleSet() { override var next: AbstractSet = dummyNext get() = field set(next) { field = next surrogates.next = next withoutSurrogates.next = next } override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var result = withoutSurrogates.matches(startIndex, testString, matchResult) if (result < 0) { result = surrogates.matches(startIndex, testString, matchResult) } return result } override val name: String get() = "CompositeRangeSet: " + " " + withoutSurrogates + " " + surrogates override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override fun first(set: AbstractSet): Boolean { return true } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/DecomposedCharSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. * Returns the length of the decomposition. */ @SymbolName("Kotlin_text_regex_decomposeCodePoint") external private fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int /** Represents canonical decomposition of Unicode character. Is used when CANON_EQ flag of Pattern class is specified. */ open internal class DecomposedCharSet( /** Decomposition of the Unicode codepoint */ private val decomposedChar: IntArray, /** Length of useful part of decomposedChar decomposedCharLength <= decomposedChar.length */ private val decomposedCharLength: Int) : SimpleSet() { /** Contains information about number of chars that were read for a codepoint last time */ private var readCharsForCodePoint = 1 /** UTF-16 encoding of decomposedChar */ private val decomposedCharUTF16: String by lazy { val strBuff = StringBuilder() for (i in 0..decomposedCharLength - 1) { strBuff.append(Char.toChars(decomposedChar[i])) } return@lazy strBuff.toString() } override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var strIndex = startIndex val rightBound = testString.length if (strIndex >= rightBound) { return -1 } // We read testString and decompose it gradually to compare with this decomposedChar at position strIndex var curChar = codePointAt(strIndex, testString, rightBound) strIndex += readCharsForCodePoint var readCodePoints = 0 var i = 0 // All decompositions have length that is less or equal Lexer.MAX_DECOMPOSITION_LENGTH var decomposedCodePoint: IntArray = IntArray(Lexer.MAX_DECOMPOSITION_LENGTH) readCodePoints += decomposeCodePoint(curChar, decomposedCodePoint, readCodePoints) if (strIndex < rightBound) { curChar = codePointAt(strIndex, testString, rightBound) // Read testString until we met a decomposed char boundary and decompose obtained portion of testString. while (readCodePoints < Lexer.MAX_DECOMPOSITION_LENGTH && !Lexer.isDecomposedCharBoundary(curChar)) { if (!Lexer.hasDecompositionNonNullCanClass(curChar)) { decomposedCodePoint[readCodePoints++] = curChar } else { /* * A few codepoints have decompositions and non null canonical classes, we have to take them into * consideration, but general rule is: if canonical class != 0 then no decomposition */ readCodePoints += decomposeCodePoint(curChar, decomposedCodePoint, readCodePoints) } strIndex += readCharsForCodePoint if (strIndex < rightBound) { curChar = codePointAt(strIndex, testString, rightBound) } else { break } } } // Some optimization since length of decomposed char is <= 3 usually when (readCodePoints) { 0, 1, 2 -> {} 3 -> { var i1 = Lexer.getCanonicalClass(decomposedCodePoint[1]) val i2 = Lexer.getCanonicalClass(decomposedCodePoint[2]) if (i2 != 0 && i1 > i2) { i1 = decomposedCodePoint[1] decomposedCodePoint[1] = decomposedCodePoint[2] decomposedCodePoint[2] = i1 } } else -> decomposedCodePoint = Lexer.getCanonicalOrder(decomposedCodePoint, readCodePoints) } // Compare decomposedChar with decomposed char that was just read from testString if (readCodePoints != decomposedCharLength) { return -1 } if ((0 until readCodePoints).firstOrNull { decomposedCodePoint[i] != decomposedChar[i] } != null) { return -1 } return next.matches(strIndex, testString, matchResult) } override val name: String get() = "decomposed char: $decomposedChar" /** Reads Unicode codepoint from [testString] starting from [strIndex] until [rightBound]. */ fun codePointAt(strIndex: Int, testString: CharSequence, rightBound: Int): Int { var index = strIndex // We store information about number of codepoints we read at variable readCharsForCodePoint. val curChar: Int readCharsForCodePoint = 1 if (index < rightBound - 1) { val high = testString[index++] val low = testString[index] if (Char.isSurrogatePair(high, low)) { curChar = Char.toCodePoint(high, low) readCharsForCodePoint = 2 } else { curChar = high.toInt() } } else { curChar = testString[index].toInt() } return curChar } override fun first(set: AbstractSet): Boolean { return if (set is DecomposedCharSet) set.decomposedChar.contentEquals(decomposedChar) else true } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/DotQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Special node for ".*" construction. * The main idea here is to find line terminator and try to find the rest of the construction from this point. */ // TODO: Add optimized implementation for '.+' case internal class DotQuantifierSet( innerSet: AbstractSet, next: AbstractSet, type: Int, val lineTerminator: AbstractLineTerminator, val matchLineTerminator: Boolean = false ) : QuantifierSet(innerSet, next, type) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = testString.length val startSearch = if (matchLineTerminator) rightBound else testString.findLineTerminator(startIndex, rightBound) if (startSearch <= startIndex) { return if (type.toChar() == '+') { -1 } else { next.matches(startIndex, testString, matchResult) } } val result = next.findBack(startIndex, startSearch, testString, matchResult) if (type.toChar() == '+' && result == startIndex) { return -1 } return result } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = testString.length if (matchLineTerminator) { val foundIndex = next.findBack(startIndex, rightBound, testString, matchResult) if (foundIndex >= 0 && !(type.toChar() == '+' && foundIndex == startIndex)) { return startIndex } else { return -1 } } else { // 1. find first occurrence of the searched pattern. var nextFound = next.find(startIndex, testString, matchResult) if (nextFound < 0) { return -1 } // 2. Check if we have other occurrences till the end of line (because .* is greedy and we need the last one). val nextFoundLast = next.findBack(nextFound, testString.findLineTerminator(nextFound, rightBound), testString, matchResult) nextFound = maxOf(nextFound, nextFoundLast) // 3. Find the left boundary of this search. val leftBound = findBackLineTerminator(startIndex, nextFound, testString) if (type.toChar() == '+' && leftBound + 1 == nextFound) { return -1 } return leftBound + 1 } } /** * Find the first line terminator between [from] (inclusive) and [to] (exclusive) indices. * Returns [to] if no terminator found. */ private fun CharSequence.findLineTerminator(from: Int, to: Int): Int = (from until to).firstOrNull { lineTerminator.isLineTerminator(this[it]) } ?: to /** * Find the first line terminator between [from] (inclusive) and [to] (exclusive) indices. * Returns [from - 1] if no terminator found. */ private fun findBackLineTerminator(from: Int, to: Int, testString: CharSequence): Int = (from until to).lastOrNull { lineTerminator.isLineTerminator(testString[it]) } ?: from - 1 override val name: String get() = ".*" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/DotSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Node accepting any character except line terminators. */ internal class DotSet(val lt: AbstractLineTerminator, val matchLineTerminator: Boolean) : SimpleSet(AbstractSet.TYPE_DOTSET) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = testString.length if (startIndex >= rightBound) { return -1 } val high = testString[startIndex] if (high.isHighSurrogate() && startIndex + 2 <= rightBound) { val low = testString[startIndex + 1] if (Char.isSurrogatePair(high, low)) { if (!matchLineTerminator && lt.isLineTerminator(Char.toCodePoint(high, low))) { return -1 } else { return next.matches(startIndex + 2, testString, matchResult) } } } if (!matchLineTerminator && lt.isLineTerminator(high)) { return -1 } else { return next.matches(startIndex + 1, testString, matchResult) } } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override val name: String get() = "." } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/EOISet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents end of input '\z', i.e. matches only character after the last one; */ internal class EOISet : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (startIndex < testString.length) { return -1 } return next.matches(startIndex, testString, matchResult) } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = false override val name: String get() = "EOI" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/EOLSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents a node for a '$' sign. * Note: In Kotlin we use only the "anchoring bounds" mode when "$" matches the end of a match region. * See: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html#useAnchoringBounds-boolean- */ internal class EOLSet(val consCounter: Int, val lt: AbstractLineTerminator, val multiline: Boolean = false) : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = testString.length val remainingChars = rightBound - startIndex when { startIndex >= rightBound || remainingChars == 1 && lt.isLineTerminator(testString[startIndex]) || remainingChars == 2 && lt.isLineTerminatorPair(testString[startIndex], testString[startIndex+1]) || multiline && lt.isLineTerminator(testString[startIndex]) -> { matchResult.setConsumed(consCounter, 0) return next.matches(startIndex, testString, matchResult) } } return -1 } override fun hasConsumed(matchResult: MatchResultImpl): Boolean { val result = matchResult.getConsumed(consCounter) != 0 matchResult.setConsumed(consCounter, -1) return result } override val name: String get()= "" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/EmptySet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Valid constant zero character match. */ internal class EmptySet(override var next: AbstractSet) : LeafSet() { override val charCount = 0 override fun accepts(startIndex: Int, testString: CharSequence): Int = 0 override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { for (index in startIndex..testString.length) { if (index < testString.length) { if (testString[index].isLowSurrogate() && index > 0 && testString[index - 1].isHighSurrogate()) { continue } } if (next.matches(index, testString, matchResult) >= 0) { return index } } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { for (index in rightLimit downTo leftLimit) { if (index < testString.length) { if (testString[index].isLowSurrogate() && index > 0 && testString[index - 1].isHighSurrogate()) { continue } } if (next.matches(index, testString, matchResult) >= 0) { return index } } return -1 } override val name: String get()= "" override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return false } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/FSets.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * The node which marks end of the particular group. */ open internal class FSet(val groupIndex: Int) : SimpleSet() { var isBackReferenced = false override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val oldEnd = matchResult.getEnd(groupIndex) matchResult.setEnd(groupIndex, startIndex) val shift = next.matches(startIndex, testString, matchResult) if (shift < 0) { matchResult.setEnd(groupIndex, oldEnd) } return shift } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = false override val name: String get() = "fSet" override fun processSecondPass(): FSet { val result = super.processSecondPass() assert(result == this) return this } /** * Marks the end of the particular group and not take into account possible * kickbacks (required for atomic groups, for instance) */ internal class PossessiveFSet : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { return startIndex } override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return false } override val name: String get() = "possessiveFSet" } companion object { val possessiveFSet = PossessiveFSet() } } /** * Special construction which marks end of pattern. */ internal class FinalSet : FSet(0) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (matchResult.mode == Regex.Mode.FIND || startIndex == testString.length) { matchResult.setEnd(0, startIndex) return startIndex } return -1 } override val name: String get() = "FinalSet" } /** * Non-capturing group closing node. */ internal class NonCapFSet(groupIndex: Int) : FSet(groupIndex) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { matchResult.setConsumed(groupIndex, startIndex - matchResult.getConsumed(groupIndex)) return next.matches(startIndex, testString, matchResult) } override val name: String get() = "NonCapFSet" override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return false } } /** * LookAhead FSet, always returns true */ internal class AheadFSet : FSet(-1) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { return startIndex } override val name: String get() = "AheadFSet" } /** * FSet for lookbehind constructs. Checks if string index saved by corresponding * jointSet in "consumers" equals to current index and return current string * index, return -1 otherwise. */ internal class BehindFSet(groupIndex: Int) : FSet(groupIndex) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = matchResult.getConsumed(groupIndex) return if (rightBound == startIndex) startIndex else -1 } override val name: String get() = "BehindFSet" } /** * Represents an end of an atomic group. */ internal class AtomicFSet(groupIndex: Int) : FSet(groupIndex) { var index: Int = 0 override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { matchResult.setConsumed(groupIndex, startIndex - matchResult.getConsumed(groupIndex)) index = startIndex return startIndex } override val name: String get() = "AtomicFSet" override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return false } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/GroupQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Default quantifier over groups, in fact this type of quantifier is * generally used for constructions we cant identify number of characters they * consume. */ open internal class GroupQuantifierSet( val quantifier: Quantifier, innerSet: AbstractSet, next: AbstractSet, type: Int, val groupQuantifierIndex: Int // It's used to remember a number of the innerSet occurrences during the recursive search. ) : QuantifierSet(innerSet, next, type) { val max: Int get() = quantifier.max val min: Int get() = quantifier.min // We call innerSet.matches here, if it succeeds it call next.matches where next is this QuantifierSet. // So we have a recursive searching procedure. override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var enterCount = matchResult.enterCounters[groupQuantifierIndex] fun matchNext(): Int { matchResult.enterCounters[groupQuantifierIndex] = 0 val result = next.matches(startIndex, testString, matchResult) matchResult.enterCounters[groupQuantifierIndex] = enterCount return result } if (!innerSet.hasConsumed(matchResult)) { return matchNext() } // Fast case: '*' or {0, } - no need to count occurrences. if (min == 0 && max == Quantifier.INF) { val nextIndex = innerSet.matches(startIndex, testString, matchResult) return if (nextIndex < 0) { matchNext() } else { nextIndex } } // can't go inner set; if (max != Quantifier.INF && enterCount >= max) { return matchNext() } // go inner set; matchResult.enterCounters[groupQuantifierIndex] = ++enterCount val nextIndex = innerSet.matches(startIndex, testString, matchResult) return if (nextIndex < 0) { matchResult.enterCounters[groupQuantifierIndex] = --enterCount if (enterCount >= min) { matchNext() } else { -1 } } else { nextIndex } } override val name: String get() = quantifier.toString() } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/HangulDecomposedCharSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex import kotlin.text.* /** * Represents canonical decomposition of Hangul syllable. Is used when * CANON_EQ flag of Pattern class is specified. */ internal class HangulDecomposedCharSet( /** * Decomposed Hangul syllable. */ private val decomposedChar: CharArray, /** * Length of useful part of decomposedChar * decomposedCharLength <= decomposedChar.length */ private val decomposedCharLength: Int) : SimpleSet() { /** * String representing syllable */ private val decomposedCharUTF16: String by lazy { decomposedChar.concatToString(0, decomposedChar.size) } override val name: String get() = "decomposed Hangul syllable: $decomposedCharUTF16" override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex /* * All decompositions for Hangul syllables have length that * is less or equal Lexer.MAX_DECOMPOSITION_LENGTH */ val rightBound = testString.length var SyllIndex = 0 val decompSyllable = IntArray(Lexer .MAX_HANGUL_DECOMPOSITION_LENGTH) val decompCurSymb: IntArray? var curSymb: Char /* * For details about Hangul composition and decomposition see * http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf * "3.12 Conjoining Jamo Behavior" */ var LIndex: Int var VIndex = -1 var TIndex = -1 if (index >= rightBound) { return -1 } curSymb = testString[index++] decompCurSymb = Lexer.getHangulDecomposition(curSymb.toInt()) if (decompCurSymb == null) { /* * We deal with ordinary letter or sequence of jamos * at index at testString. */ decompSyllable[SyllIndex++] = curSymb.toInt() LIndex = curSymb.toInt() - Lexer.LBase if (LIndex < 0 || LIndex >= Lexer.LCount) { /* * Ordinary letter, that doesn't match this */ return -1 } if (index < rightBound) { curSymb = testString[index] VIndex = curSymb.toInt() - Lexer.VBase } if (VIndex < 0 || VIndex >= Lexer.VCount) { /* * Single L jamo doesn't compose Hangul syllable, * so doesn't match */ return -1 } index++ decompSyllable[SyllIndex++] = curSymb.toInt() if (index < rightBound) { curSymb = testString[index] TIndex = curSymb.toInt() - Lexer.TBase } if (TIndex < 0 || TIndex >= Lexer.TCount) { /* * We deal with LV syllable at testString, so * compare it to this */ return if (decomposedCharLength == 2 && decompSyllable[0] == decomposedChar[0].toInt() && decompSyllable[1] == decomposedChar[1].toInt()) next.matches(index, testString, matchResult) else -1 } index++ decompSyllable[@Suppress("UNUSED_CHANGED_VALUE")SyllIndex++] = curSymb.toInt() /* * We deal with LVT syllable at testString, so * compare it to this */ return if (decomposedCharLength == 3 && decompSyllable[0] == decomposedChar[0].toInt() && decompSyllable[1] == decomposedChar[1].toInt() && decompSyllable[2] == decomposedChar[2].toInt()) next.matches(index, testString, matchResult) else -1 } else { /* * We deal with Hangul syllable at index at testString. * So we decomposed it to compare with this. */ var i = 0 if (decompCurSymb.size != decomposedCharLength) { return -1 } while (i < decomposedCharLength) { if (decompCurSymb[i] != decomposedChar[i].toInt()) { return -1 } i++ } return next.matches(index, testString, matchResult) } } override fun first(set: AbstractSet): Boolean { return if (set is HangulDecomposedCharSet) set.decomposedCharUTF16 == decomposedCharUTF16 else true } override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return true } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/JointSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents group, which is alternation of other subexpression. * One should think about "group" in this model as JointSet opening group and corresponding FSet closing group. */ open internal class JointSet(children: List, fSet: FSet) : AbstractSet() { protected var children: MutableList = mutableListOf().apply { addAll(children) } var fSet: FSet = fSet protected set var groupIndex: Int = fSet.groupIndex protected set /** * Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (children.isEmpty()) { return -1 } val oldStart = matchResult.getStart(groupIndex) matchResult.setStart(groupIndex, startIndex) children.forEach { val shift = it.matches(startIndex, testString, matchResult) if (shift >= 0) { return shift } } matchResult.setStart(groupIndex, oldStart) return -1 } override var next: AbstractSet get() = fSet.next set(next) { fSet.next = next } override val name: String get() = "JointSet" override fun first(set: AbstractSet): Boolean = children.any { it.first(set) } override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return !(matchResult.getEnd(groupIndex) >= 0 && matchResult.getStart(groupIndex) == matchResult.getEnd(groupIndex)) } override fun processSecondPassInternal(): AbstractSet { val fSet = this.fSet if (!fSet.secondPassVisited) { val newFSet = fSet.processSecondPass() assert(newFSet == fSet) } children.replaceAll { child -> if (!child.secondPassVisited) child.processSecondPass() else child } return super.processSecondPassInternal() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/LeafQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex import kotlin.RuntimeException /** * Generalized greedy quantifier node over the leaf nodes. * - a{n,m}; * - a* == a{0, }; * - a? == a{0, 1}; * - a+ == a{1, }; */ open internal class LeafQuantifierSet(var quantifier: Quantifier, innerSet: LeafSet, next: AbstractSet, type: Int ) : QuantifierSet(innerSet, next, type) { val leaf: LeafSet get() = super.innerSet as LeafSet val min: Int get() = quantifier.min val max: Int get() = quantifier.max override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex var occurrences = 0 // Process first occurrences of the sequence being looked for. while (occurrences < min) { if (index + leaf.charCount > testString.length) { return -1 } val shift = leaf.accepts(index, testString) if (shift < 1) { return -1 } index += shift occurrences++ } // Process occurrences between min and max. while ((max == Quantifier.INF || occurrences < max) && index + leaf.charCount <= testString.length) { val shift = leaf.accepts(index, testString) if (shift < 1) { break } index += shift occurrences++ } // Roll back if the next node does't match the remaining string. while (occurrences >= min) { val shift = next.matches(index, testString, matchResult) if (shift >= 0) { return shift } index -= leaf.charCount occurrences-- } return -1 } override val name: String get() = quantifier.toString() override var innerSet: AbstractSet get() = super.innerSet set(innerSet) { if (innerSet !is LeafSet) throw RuntimeException("Internal Error") super.innerSet = innerSet } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/LeafSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Base class for nodes representing leaf tokens of the RE, those who consumes fixed number of characters. */ internal abstract class LeafSet : SimpleSet(AbstractSet.TYPE_LEAF) { open val charCount = 1 /** Returns "shift", the number of accepted chars. Commonly internal function, but called by quantifiers. */ abstract fun accepts(startIndex: Int, testString: CharSequence): Int /** * Checks if we can enter this state and pass the control to the next one. * Return positive value if match succeeds, negative otherwise. */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (startIndex + charCount > testString.length) { return -1 } val shift = accepts(startIndex, testString) // TODO: may be move the check above in accept function. if (shift < 0) { return -1 } return next.matches(startIndex + shift, testString, matchResult) } override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return true } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/LookAheadSets.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Positive lookahead node. */ internal class PositiveLookAheadSet(children: List, fSet: FSet) : AtomicJointSet(children, fSet) { /** Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { children.forEach { val shift = it.matches(startIndex, testString, matchResult) if (shift >= 0) { // PosLookaheadFset always returns true, position remains the same next.match() from; return next.matches(startIndex, testString, matchResult) } } return -1 } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override val name: String get() = "PositiveLookaheadJointSet" } /** * Negative look ahead node. */ internal class NegativeLookAheadSet(children: List, fSet: FSet) : AtomicJointSet(children, fSet) { /** Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { children.forEach { if (it.matches(startIndex, testString, matchResult) >= 0) { return -1 } } return next.matches(startIndex, testString, matchResult) } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override val name: String get() = "NegativeLookaheadJointSet" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/LookBehindSets.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Positive lookbehind node. */ internal class PositiveLookBehindSet(children: List, fSet: FSet) : AtomicJointSet(children, fSet) { /** Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { matchResult.setConsumed(groupIndex, startIndex) children.forEach { if (it.findBack(0, startIndex, testString, matchResult) >= 0) { matchResult.setConsumed(groupIndex, -1) return next.matches(startIndex, testString, matchResult) } } return -1 } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override val name: String get() = "PositiveBehindJointSet" } /** * Negative look behind node. */ internal class NegativeLookBehindSet(children: List, fSet: FSet) : AtomicJointSet(children, fSet) { /** Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { matchResult.setConsumed(groupIndex, startIndex) children.forEach { val shift = it.findBack(0, startIndex, testString, matchResult) if (shift >= 0) { return -1 } } return next.matches(startIndex, testString, matchResult) } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override val name: String get() = "NegativeBehindJointSet" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/NonCapturingJointSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Node representing non-capturing group */ open internal class NonCapturingJointSet(children: List, fSet: FSet) : JointSet(children, fSet) { /** * Returns startIndex+shift, the next position to match */ override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val start = matchResult.getConsumed(groupIndex) matchResult.setConsumed(groupIndex, startIndex) children.forEach { val shift = it.matches(startIndex, testString, matchResult) if (shift >= 0) { return shift } } matchResult.setConsumed(groupIndex, start) return -1 } override val name: String get() = "NonCapturingJointSet" override fun hasConsumed(matchResult: MatchResultImpl): Boolean { return matchResult.getConsumed(groupIndex) != 0 } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Possessive quantifier set over groups. */ internal class PossessiveGroupQuantifierSet( quantifier: Quantifier, innerSet: AbstractSet, next: AbstractSet, type: Int, setCounter: Int ): GroupQuantifierSet(quantifier, innerSet, next, type, setCounter) { init { innerSet.next = FSet.possessiveFSet } override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex var nextIndex: Int = innerSet.matches(index, testString, matchResult) var occurrences = 0 while (nextIndex > index && (max == Quantifier.INF || occurrences < max)) { occurrences++ index = nextIndex nextIndex = innerSet.matches(index, testString, matchResult) } if (occurrences < quantifier.min) { return -1 } else { return next.matches(index, testString, matchResult) } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Possessive quantifier node over a leaf node. * - a{n,m}+; * - a*+ == a{0, }+; * - a?+ == a{0, 1}+; * - a++ == a{1, }+; */ internal class PossessiveLeafQuantifierSet( quant: Quantifier, innerSet: LeafSet, next: AbstractSet, type: Int ) : LeafQuantifierSet(quant, innerSet, next, type) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex var occurrences = 0 while (occurrences < min) { if (index + leaf.charCount > testString.length) { return -1 } val shift = leaf.accepts(index, testString) if (shift < 1) { return -1 } index += shift occurrences++ } while ((max == Quantifier.INF || occurrences < max) && index + leaf.charCount <= testString.length) { val shift = leaf.accepts(index, testString) if (shift < 1) { break } index += shift occurrences++ } return next.matches(index, testString, matchResult) } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/PreviousMatchSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Node representing previous match (\G). */ internal class PreviousMatchSet : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (startIndex == matchResult.previousMatch) { return next.matches(startIndex, testString, matchResult) } return -1 } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = false override val name: String get() = "PreviousMatchSet" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/QuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Base class for quantifiers. */ internal abstract class QuantifierSet(open var innerSet: AbstractSet, override var next: AbstractSet, type: Int) : SimpleSet(type) { override fun first(set: AbstractSet): Boolean = innerSet.first(set) || next.first(set) override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true override fun processSecondPassInternal(): AbstractSet { val innerSet = this.innerSet if (innerSet.secondPassVisited) { this.innerSet = innerSet.processSecondPass() } return super.processSecondPassInternal() } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/RangeSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents node accepting single character from the given char class. */ open internal class RangeSet(charClass: AbstractCharClass, val ignoreCase: Boolean = false) : LeafSet() { val chars: AbstractCharClass = charClass.instance override fun accepts(startIndex: Int, testString: CharSequence): Int { if (ignoreCase) { val char = testString[startIndex] return if (chars.contains(char.toUpperCase()) || chars.contains(char.toLowerCase())) 1 else -1 } else { return if (chars.contains(testString[startIndex])) 1 else -1 } } override val name: String get() = "range:" + (if (chars.alt) "^ " else " ") + chars.toString() override fun first(set: AbstractSet): Boolean { return when (set) { is CharSet -> AbstractCharClass.intersects(chars, set.char.toInt()) is RangeSet -> AbstractCharClass.intersects(chars, set.chars) is SupplementaryCharSet -> false is SupplementaryRangeSet -> AbstractCharClass.intersects(chars, set.chars) else -> true } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Reluctant version of the group quantifier set. */ internal class ReluctantGroupQuantifierSet( quantifier: Quantifier, innerSet: AbstractSet, next: AbstractSet, type: Int, setCounter: Int ) : GroupQuantifierSet(quantifier, innerSet, next, type, setCounter) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var enterCount = matchResult.enterCounters[groupQuantifierIndex] fun matchNext(): Int { matchResult.enterCounters[groupQuantifierIndex] = 0 val result = next.matches(startIndex, testString, matchResult) matchResult.enterCounters[groupQuantifierIndex] = enterCount return result } if (!innerSet.hasConsumed(matchResult)) { return matchNext() } // Fast case: '*' or {0, } - no need to count occurrences. if (min == 0 && max == Quantifier.INF) { val res = next.matches(startIndex, testString, matchResult) return if (res < 0) { innerSet.matches(startIndex, testString, matchResult) } else { res } } // can't go inner set; if (max != Quantifier.INF && enterCount >= max) { return matchNext() } return if (enterCount >= min) { val nextIndex = matchNext() if (nextIndex < 0) { matchResult.enterCounters[groupQuantifierIndex] = ++enterCount innerSet.matches(startIndex, testString, matchResult) } else { nextIndex } } else { matchResult.enterCounters[groupQuantifierIndex] = ++enterCount innerSet.matches(startIndex, testString, matchResult) } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Reluctant quantifier node over a leaf node. * - a{n,m}?; * - a*? == a{0, }?; * - a?? == a{0, 1}?; * - a+? == a{1, }?; */ internal class ReluctantLeafQuantifierSet( quant: Quantifier, innerSet: LeafSet, next: AbstractSet, type: Int ) : LeafQuantifierSet(quant, innerSet, next, type) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex var occurrences = 0 while (occurrences < min) { if (index + leaf.charCount > testString.length) { return -1 } val shift = leaf.accepts(index, testString) if (shift < 1) { return -1 } index += shift occurrences++ } do { var shift = next.matches(index, testString, matchResult) if (shift >= 0) { return shift } if (index + leaf.charCount <= testString.length) { shift = leaf.accepts(index, testString) index += shift occurrences++ } } while (shift >= 1 && (max == Quantifier.INF || occurrences <= max)) return -1 } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SOLSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * A node representing a '^' sign. * Note: In Kotlin we use only the "anchoring bounds" mode when "^" matches beginning of a match region. * See: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html#useAnchoringBounds-boolean- */ internal class SOLSet(val lt: AbstractLineTerminator, val multiline: Boolean = false) : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { if (!multiline) { if (startIndex == 0) { return next.matches(startIndex, testString, matchResult) } } else { if (startIndex != testString.length && (startIndex == 0 || lt.isAfterLineTerminator(testString[startIndex - 1], testString[startIndex]))) { return next.matches(startIndex, testString, matchResult) } } return -1 } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = false override val name: String get() = "^" } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SequenceSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * This class represents nodes constructed with character sequences. For * example, lets consider regular expression: ".*word.*". During regular * expression compilation phase character sequence w-o-r-d, will be represented * with single node for the entire word. */ open internal class SequenceSet(substring: CharSequence, val ignoreCase: Boolean = false) : LeafSet() { /** Represents a character sequence used for matching/searching. */ protected val patternString: String = substring.toString() override val name: String= "sequence: " + patternString override val charCount = substring.length // Overrides ======================================================================================================= /** Returns true if [index] points to a low surrogate following a high surrogate */ private fun isLowSurrogateOfSupplement(string: CharSequence, index: Int): Boolean = index < string.length && string[index].isLowSurrogate() && index > 0 && string[index - 1].isHighSurrogate() override fun accepts(startIndex: Int, testString: CharSequence): Int { return if (testString.startsWith(patternString, startIndex, ignoreCase) && !isLowSurrogateOfSupplement(testString, startIndex) && !isLowSurrogateOfSupplement(testString, startIndex + patternString.length)) { charCount } else { -1 } } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex while (index < testString.length) { index = testString.indexOf(patternString, index, ignoreCase) if (index < 0) { return -1 } // Check if we have a supplementary code point at the beginning or at the end of the string. if (!isLowSurrogateOfSupplement(testString, index) && !isLowSurrogateOfSupplement(testString, index + patternString.length) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index++ } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = rightLimit while (index >= leftLimit) { index = testString.lastIndexOf(patternString, index, ignoreCase) if (index < 0) { return -1 } // Check if we have a supplementary code point at the beginning or at the end of the string. if (!isLowSurrogateOfSupplement(testString, index) && !isLowSurrogateOfSupplement(testString, index + patternString.length) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index-- } return -1 } override fun first(set: AbstractSet): Boolean { if (ignoreCase) { return super.first(set) } return when (set) { is CharSet -> set.char == patternString[0] is RangeSet -> set.accepts(0, patternString.substring(0, 1)) > 0 is SupplementaryRangeSet -> set.contains(patternString[0]) || patternString.length > 1 && set.contains(Char.toCodePoint(patternString[0], patternString[1])) is SupplementaryCharSet -> if (patternString.length > 1) set.codePoint == Char.toCodePoint(patternString[0], patternString[1]) else false else -> true } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SingleSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Group node over subexpression without alternations. */ open internal class SingleSet(var kid: AbstractSet, fSet: FSet) : JointSet(listOf(), fSet) { var backReferencedSet: BackReferencedSingleSet? = null // Overrides (API) ================================================================================================= override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val start = matchResult.getStart(groupIndex) matchResult.setStart(groupIndex, startIndex) val shift = kid.matches(startIndex, testString, matchResult) if (shift >= 0) { return shift } matchResult.setStart(groupIndex, start) return -1 } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val res = kid.find(startIndex, testString, matchResult) if (res >= 0) matchResult.setStart(groupIndex, res) return res } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val res = kid.findBack(leftLimit, rightLimit, testString, matchResult) if (res >= 0) matchResult.setStart(groupIndex, res) return res } override fun first(set: AbstractSet): Boolean = kid.first(set) // Second pass processing ========================================================================================== override fun processBackRefReplacement(): JointSet? { /** * We will store a reference to created BackReferencedSingleSet * in [backReferencedSet] field. This is needed to process replacement * of sets correctly since sometimes we cannot renew all references to * detachable set in the current point of traverse. See * QuantifierSet and AbstractSet processSecondPass() methods for * more details. */ val result = BackReferencedSingleSet(this) backReferencedSet = result return result } override fun processSecondPassInternal(): AbstractSet { fSet = fSet.processSecondPass() kid = kid.processSecondPass() return processBackRefReplacement() ?: this } /** * This method is used for traversing nodes after the first stage of compilation. */ override fun processSecondPass(): AbstractSet { if (secondPassVisited) { if (fSet.isBackReferenced) { assert(backReferencedSet != null) // secondPassVisited return backReferencedSet!! } } secondPassVisited = true return processSecondPassInternal() } // Backreferenced version of the class ============================================================================= /** * Group node over subexpression without alternations. * This node is used if current group is referenced via a backreference. */ internal class BackReferencedSingleSet(node: SingleSet) : SingleSet(node.kid, node.fSet) { /* * This class is needed only for overwriting find() and findBack() methods of SingleSet class, which is being * back referenced. The following example explains the need for such substitution: * * Let's consider the pattern ".*(.)\\1". * Leading .* works as follows: finds line terminator and runs findBack from that point. * `findBack` method in its turn (in contrast to matches) sets group boundaries on the back trace. * Thus at the point we try to match back reference(\\1) groups are not yet set. * * To fix this problem we replace backreferenced groups with instances of this class, * which will use matches instead of find; this will affect performance, but ensure correctness of the match. */ override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { for (index in startIndex..testString.length) { val oldStart = matchResult.getStart(groupIndex) matchResult.setStart(groupIndex, index) val res = kid.matches(index, testString, matchResult) if (res >= 0) { return index } else { matchResult.setStart(groupIndex, oldStart) } } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { for (index in rightLimit downTo leftLimit) { val oldStart = matchResult.getStart(groupIndex) matchResult.setStart(groupIndex, index) val res = kid.matches(index, testString, matchResult) if (res >= 0) { return index } else { matchResult.setStart(groupIndex, oldStart) } } return -1 } override fun processBackRefReplacement(): JointSet? = null } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryCharSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * * Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. * * COPYRIGHT AND PERMISSION NOTICE * * Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. Permission is * hereby granted, free of charge, to any person obtaining a copy of the * Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") * to deal in the Data Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Data Files or Software, and to permit persons * to whom the Data Files or Software are furnished to do so, provided that * (a) the above copyright notice(s) and this permission notice appear with * all copies of the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated documentation, * and (c) there is clear notice in each modified Data File or in the Software * as well as in the documentation associated with the Data File(s) or Software * that the data or software has been modified. * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in these Data Files or Software without prior written * authorization of the copyright holder. * * 2. Additional terms from the Database: * * Copyright © 1995-1999 Unicode, Inc. All Rights reserved. * * Disclaimer * * The Unicode Character Database is provided as is by Unicode, Inc. * No claims are made as to fitness for any particular purpose. No warranties * of any kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been purchased * on magnetic or optical media from Unicode, Inc., the sole remedy for any claim * will be exchange of defective media within 90 days of receipt. This disclaimer * is applicable for all other data files accompanying the Unicode Character Database, * some of which have been compiled by the Unicode Consortium, and some of which * have been supplied by other sources. * * Limitations on Rights to Redistribute This Data * * Recipient is granted the right to make copies in any form for internal * distribution and to freely use the information supplied in the creation of * products supporting the UnicodeTM Standard. The files in * the Unicode Character Database can be redistributed to third parties or other * organizations (whether for profit or not) as long as this notice and the disclaimer * notice are retained. Information can be extracted from these files and used * in documentation or programs, as long as there is an accompanying notice * indicating the source. */ package kotlin.text.regex /** * Represents node accepting single supplementary codepoint. */ internal class SupplementaryCharSet(val codePoint: Int, ignoreCase: Boolean) : SequenceSet(Char.toChars(codePoint).concatToString(0, 2), ignoreCase) { override val name: String get() = patternString override fun first(set: AbstractSet): Boolean { return when (set) { is SupplementaryCharSet -> set.codePoint == codePoint is SupplementaryRangeSet -> set.contains(codePoint) is CharSet, is RangeSet -> false else -> true } } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryRangeSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * * Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. * * COPYRIGHT AND PERMISSION NOTICE * * Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. Permission is * hereby granted, free of charge, to any person obtaining a copy of the * Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") * to deal in the Data Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Data Files or Software, and to permit persons * to whom the Data Files or Software are furnished to do so, provided that * (a) the above copyright notice(s) and this permission notice appear with * all copies of the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated documentation, * and (c) there is clear notice in each modified Data File or in the Software * as well as in the documentation associated with the Data File(s) or Software * that the data or software has been modified. * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in these Data Files or Software without prior written * authorization of the copyright holder. * * 2. Additional terms from the Database: * * Copyright © 1995-1999 Unicode, Inc. All Rights reserved. * * Disclaimer * * The Unicode Character Database is provided as is by Unicode, Inc. * No claims are made as to fitness for any particular purpose. No warranties * of any kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been purchased * on magnetic or optical media from Unicode, Inc., the sole remedy for any claim * will be exchange of defective media within 90 days of receipt. This disclaimer * is applicable for all other data files accompanying the Unicode Character Database, * some of which have been compiled by the Unicode Consortium, and some of which * have been supplied by other sources. * * Limitations on Rights to Redistribute This Data * * Recipient is granted the right to make copies in any form for internal * distribution and to freely use the information supplied in the creation of * products supporting the UnicodeTM Standard. The files in * the Unicode Character Database can be redistributed to third parties or other * organizations (whether for profit or not) as long as this notice and the disclaimer * notice are retained. Information can be extracted from these files and used * in documentation or programs, as long as there is an accompanying notice * indicating the source. */ package kotlin.text.regex /** * Represents node accepting single character from the given char class. * This character can be supplementary (2 chars needed to represent) or from * basic multilingual pane (1 needed char to represent it). */ open internal class SupplementaryRangeSet(charClass: AbstractCharClass, val ignoreCase: Boolean = false): SimpleSet() { val chars = charClass.instance override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val rightBound = testString.length if (startIndex >= rightBound) { return -1 } var index = startIndex val high = testString[index++] if (contains(high)) { val result = next.matches(index, testString, matchResult) if (result >= 0) return result } if (index < rightBound) { val low = testString[index++] if (Char.isSurrogatePair(high, low) && contains(Char.toCodePoint(high, low))) { return next.matches(index, testString, matchResult) } } return -1 } fun contains(char: Char): Boolean { if (ignoreCase) { return chars.contains(char.toUpperCase()) || chars.contains(char.toLowerCase()) } else { return chars.contains(char) } } fun contains(char: Int): Boolean { return chars.contains(char) } override val name: String get() = "range:" + (if (chars.alt) "^ " else " ") + chars.toString() override fun first(set: AbstractSet): Boolean { return when(set) { is SupplementaryCharSet -> AbstractCharClass.intersects(chars, set.codePoint) is CharSet -> AbstractCharClass.intersects(chars, set.char.toInt()) is SupplementaryRangeSet -> AbstractCharClass.intersects(chars, set.chars) is RangeSet -> AbstractCharClass.intersects(chars, set.chars) else -> true } } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateCharSets.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * * Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. * * COPYRIGHT AND PERMISSION NOTICE * * Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. Permission is * hereby granted, free of charge, to any person obtaining a copy of the * Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") * to deal in the Data Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Data Files or Software, and to permit persons * to whom the Data Files or Software are furnished to do so, provided that * (a) the above copyright notice(s) and this permission notice appear with * all copies of the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated documentation, * and (c) there is clear notice in each modified Data File or in the Software * as well as in the documentation associated with the Data File(s) or Software * that the data or software has been modified. * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in these Data Files or Software without prior written * authorization of the copyright holder. * * 2. Additional terms from the Database: * * Copyright © 1995-1999 Unicode, Inc. All Rights reserved. * * Disclaimer * * The Unicode Character Database is provided as is by Unicode, Inc. * No claims are made as to fitness for any particular purpose. No warranties * of any kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been purchased * on magnetic or optical media from Unicode, Inc., the sole remedy for any claim * will be exchange of defective media within 90 days of receipt. This disclaimer * is applicable for all other data files accompanying the Unicode Character Database, * some of which have been compiled by the Unicode Consortium, and some of which * have been supplied by other sources. * * Limitations on Rights to Redistribute This Data * * Recipient is granted the right to make copies in any form for internal * distribution and to freely use the information supplied in the creation of * products supporting the UnicodeTM Standard. The files in * the Unicode Character Database can be redistributed to third parties or other * organizations (whether for profit or not) as long as this notice and the disclaimer * notice are retained. Information can be extracted from these files and used * in documentation or programs, as long as there is an accompanying notice * indicating the source. */ package kotlin.text.regex /** * This class represents low surrogate character. * * Note that we can use high and low surrogate characters * that don't combine into supplementary code point. * See http://www.unicode.org/reports/tr18/#Supplementary_Characters */ internal class LowSurrogateCharSet(low: Char) : CharSet(low) { override fun accepts(startIndex: Int, testString: CharSequence): Int { val result = super.accepts(startIndex, testString) if (result < 0 || testString.isHighSurrogate(startIndex - 1)) { return -1 } return result } private fun CharSequence.isHighSurrogate(index: Int, leftBound: Int = 0, rightBound: Int = length) = (index in leftBound until rightBound && this[index].isHighSurrogate()) override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex while (index < testString.length) { index = testString.indexOf(char, index, ignoreCase) if (index < 0) { return -1 } if (!testString.isHighSurrogate(index - 1) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index++ } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = rightLimit while (index >= leftLimit) { index = testString.lastIndexOf(char, index, ignoreCase) if (index < 0) { return -1 } if (!testString.isHighSurrogate(index - 1, leftLimit, rightLimit) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index-- } return -1 } override fun first(set: AbstractSet): Boolean { return when(set) { is LowSurrogateCharSet -> set.char == this.char is CharSet, is RangeSet, is SupplementaryCharSet, is SupplementaryRangeSet -> false else -> true } } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true } /** * This class represents high surrogate character. */ internal class HighSurrogateCharSet(high: Char) : CharSet(high) { override fun accepts(startIndex: Int, testString: CharSequence): Int { val result = super.accepts(startIndex, testString) if (result < 0 || testString.isLowSurrogate(startIndex + 1)) { return -1 } return result } private fun CharSequence.isLowSurrogate(index: Int, leftBound: Int = 0, rightBound: Int = length) = (index in leftBound until rightBound && this[index].isLowSurrogate()) // TODO: We have a similar code here, in LowSurrogateCharSet and in CharSet. Reuse it somehow. override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex while (index < testString.length) { index = testString.indexOf(char, index, ignoreCase) if (index < 0) { return -1 } // Remove params. if (!testString.isLowSurrogate(index + 1) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index++ } return -1 } override fun findBack(leftLimit: Int, rightLimit: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = rightLimit while (index >= leftLimit) { index = testString.lastIndexOf(char, index, ignoreCase) if (index < 0) { return -1 } if (!testString.isLowSurrogate(index + 1, leftLimit, rightLimit) && next.matches(index + charCount, testString, matchResult) >= 0) { return index } index-- } return -1 } override fun first(set: AbstractSet): Boolean { return when (set) { is HighSurrogateCharSet -> set.char == this.char is CharSet, is RangeSet, is SupplementaryCharSet, is SupplementaryRangeSet -> false else -> true } } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateRangeSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * * Portions, Copyright © 1991-2005 Unicode, Inc. The following applies to Unicode. * * COPYRIGHT AND PERMISSION NOTICE * * Copyright © 1991-2005 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. Permission is * hereby granted, free of charge, to any person obtaining a copy of the * Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") * to deal in the Data Files or Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Data Files or Software, and to permit persons * to whom the Data Files or Software are furnished to do so, provided that * (a) the above copyright notice(s) and this permission notice appear with * all copies of the Data Files or Software, (b) both the above copyright * notice(s) and this permission notice appear in associated documentation, * and (c) there is clear notice in each modified Data File or in the Software * as well as in the documentation associated with the Data File(s) or Software * that the data or software has been modified. * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or other * dealings in these Data Files or Software without prior written * authorization of the copyright holder. * * 2. Additional terms from the Database: * * Copyright © 1995-1999 Unicode, Inc. All Rights reserved. * * Disclaimer * * The Unicode Character Database is provided as is by Unicode, Inc. * No claims are made as to fitness for any particular purpose. No warranties * of any kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been purchased * on magnetic or optical media from Unicode, Inc., the sole remedy for any claim * will be exchange of defective media within 90 days of receipt. This disclaimer * is applicable for all other data files accompanying the Unicode Character Database, * some of which have been compiled by the Unicode Consortium, and some of which * have been supplied by other sources. * * Limitations on Rights to Redistribute This Data * * Recipient is granted the right to make copies in any form for internal * distribution and to freely use the information supplied in the creation of * products supporting the UnicodeTM Standard. The files in * the Unicode Character Database can be redistributed to third parties or other * organizations (whether for profit or not) as long as this notice and the disclaimer * notice are retained. Information can be extracted from these files and used * in documentation or programs, as long as there is an accompanying notice * indicating the source. */ package kotlin.text.regex /* * This class is a range that contains only surrogate characters. */ internal class SurrogateRangeSet(surrChars: AbstractCharClass) : RangeSet(surrChars) { override fun accepts(startIndex: Int, testString: CharSequence): Int { val result = super.accepts(startIndex, testString) when { result < 0 || testString.isHighSurrogate(startIndex - 1) && testString.isLowSurrogate(startIndex) || testString.isHighSurrogate(startIndex) && testString.isLowSurrogate(startIndex + 1) -> return -1 } return result } private fun CharSequence.isHighSurrogate(index: Int, leftBound: Int = 0, rightBound: Int = length) = (index in leftBound until rightBound && this[index].isHighSurrogate()) private fun CharSequence.isLowSurrogate(index: Int, leftBound: Int = 0, rightBound: Int = length) = (index in leftBound until rightBound && this[index].isLowSurrogate()) override fun first(set: AbstractSet): Boolean { return when (set) { is SurrogateRangeSet -> true is CharSet, is RangeSet, is SupplementaryCharSet, is SupplementaryRangeSet -> false else -> true } } override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/UnifiedQuantifierSet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Optimized greedy quantifier node ('*') for the case where there is no intersection with * next node and normal quantifiers could be treated as greedy and possessive. */ internal class UnifiedQuantifierSet(quant: LeafQuantifierSet) : LeafQuantifierSet(Quantifier.starQuantifier, quant.leaf, quant.next, quant.type) { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var index = startIndex while (index + leaf.charCount <= testString.length && leaf.accepts(index, testString) > 0) { index += leaf.charCount } return next.matches(index, testString, matchResult) } override fun find(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { var startSearch = next.find(startIndex, testString, matchResult) if (startSearch < 0) return -1 var result = startSearch var index = startSearch - leaf.charCount while (index >= startIndex && leaf.accepts(index, testString) > 0) { result = index index -= leaf.charCount } return result } init { innerSet.next = this } } ================================================ FILE: runtime/src/main/kotlin/kotlin/text/regex/sets/WordBoundarySet.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kotlin.text.regex /** * Represents word boundary, checks current character and previous one. If they have different types returns true; */ internal class WordBoundarySet(var positive: Boolean) : SimpleSet() { override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int { val curChar = if (startIndex >= testString.length) ' ' else testString[startIndex] val prevChar = if (startIndex == 0) ' ' else testString[startIndex - 1] val right = curChar == ' ' || isSpace(curChar, startIndex, testString) val left = prevChar == ' ' || isSpace(prevChar, startIndex - 1, testString) return if (left xor right xor positive) -1 else next.matches(startIndex, testString, matchResult) } /** Returns false, because word boundary does not consumes any characters and do not move string index. */ override fun hasConsumed(matchResult: MatchResultImpl): Boolean = false override val name: String get() = "WordBoundarySet" private fun isSpace(char: Char, startIndex: Int, testString: CharSequence): Boolean { if (char.isLetterOrDigit() || char == '_') { return false } if (char.category == CharCategory.NON_SPACING_MARK) { var index = startIndex while (--index >= 0) { val ch = testString[index] when { ch.isLetterOrDigit() -> return false char.category != CharCategory.NON_SPACING_MARK -> return true } } } return true } } ================================================ FILE: runtime/src/main/kotlin/kotlin/time/DurationUnit.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.time @SinceKotlin("1.3") @ExperimentalTime public actual enum class DurationUnit(internal val scale: Double) { /** * Time unit representing one nanosecond, which is 1/1000 of a microsecond. */ NANOSECONDS(1e0), /** * Time unit representing one microsecond, which is 1/1000 of a millisecond. */ MICROSECONDS(1e3), /** * Time unit representing one millisecond, which is 1/1000 of a second. */ MILLISECONDS(1e6), /** * Time unit representing one second. */ SECONDS(1e9), /** * Time unit representing one minute. */ MINUTES(60e9), /** * Time unit representing one hour. */ HOURS(3600e9), /** * Time unit representing one day, which is always equal to 24 hours. */ DAYS(86400e9); } @SinceKotlin("1.3") @ExperimentalTime internal actual fun convertDurationUnit(value: Double, sourceUnit: DurationUnit, targetUnit: DurationUnit): Double { val sourceCompareTarget = sourceUnit.scale.compareTo(targetUnit.scale) return when { sourceCompareTarget > 0 -> value * (sourceUnit.scale / targetUnit.scale) sourceCompareTarget < 0 -> value / (targetUnit.scale / sourceUnit.scale) else -> value } } ================================================ FILE: runtime/src/main/kotlin/kotlin/time/MonotonicTimeSource.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.time import kotlin.system.* @SinceKotlin("1.3") @ExperimentalTime internal actual object MonotonicTimeSource : AbstractLongTimeSource(unit = DurationUnit.NANOSECONDS), TimeSource { // TODO: interface should not be required here override fun read(): Long = getTimeNanos() override fun toString(): String = "TimeSource(nanoTime())" } ================================================ FILE: runtime/src/main/kotlin/kotlin/time/formatToDecimals.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package kotlin.time @SymbolName("Kotlin_DurationValue_formatToExactDecimals") internal actual external fun formatToExactDecimals(value: Double, decimals: Int): String internal actual fun formatUpToDecimals(value: Double, decimals: Int): String { return formatToExactDecimals(value, decimals).trimEnd('0') } @SymbolName("Kotlin_DurationValue_formatScientificImpl") internal external fun formatScientificImpl(value: Double): String internal actual fun formatScientific(value: Double): String { val result = formatScientificImpl(value) val expIndex = result.indexOf("e+0") return if (expIndex < 0) result else result.removeRange(expIndex + 2, expIndex + 3) } ================================================ FILE: runtime/src/mimalloc/README.md ================================================ #mimalloc mimalloc is a general purpose allocator with excellent performance characteristics. Initially developed by Daan Leijen for the run-time systems of the Koka and Lean languages. Source code: https://github.com/microsoft/mimalloc Used version: 1.6.7 (https://github.com/microsoft/mimalloc/releases/tag/v1.6.7) The constant KONAN_MI_MALLOC is used to integrate mimalloc code in K/N runtime. All changes that are done should be under directives `#if defined(KONAN_MI_MALLOC)` To add code, do: #if defined(KONAN_MI_MALLOC) #endif // KONAN_MI_MALLOC To delete code, do: #if !defined(KONAN_MI_MALLOC) #endif // KONAN_MI_MALLOC To modify code, do: #if !defined(KONAN_MI_MALLOC) #else // KONAN_MI_MALLOC #endif // KONAN_MI_MALLOC or #if defined(KONAN_MI_MALLOC) #else // KONAN_MI_MALLOC #endif // KONAN_MI_MALLOC ================================================ FILE: runtime/src/mimalloc/c/alloc-aligned.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include // memset, memcpy // ------------------------------------------------------ // Aligned Allocation // ------------------------------------------------------ static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept { // note: we don't require `size > offset`, we just guarantee that // the address at offset is aligned regardless of the allocated size. mi_assert(alignment > 0); if (mi_unlikely(size > PTRDIFF_MAX)) return NULL; // we don't allocate more than PTRDIFF_MAX (see ) if (mi_unlikely(alignment==0 || !_mi_is_power_of_two(alignment))) return NULL; // require power-of-two (see ) const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)` // try if there is a small block available with just the right alignment const size_t padsize = size + MI_PADDING_SIZE; if (mi_likely(padsize <= MI_SMALL_SIZE_MAX)) { mi_page_t* page = _mi_heap_get_free_small_page(heap,padsize); const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0; if (mi_likely(page->free != NULL && is_aligned)) { #if MI_STAT>1 mi_heap_stat_increase( heap, malloc, size); #endif void* p = _mi_page_malloc(heap,page,padsize); // TODO: inline _mi_page_malloc mi_assert_internal(p != NULL); mi_assert_internal(((uintptr_t)p + offset) % alignment == 0); if (zero) _mi_block_zero_init(page,p,size); return p; } } // use regular allocation if it is guaranteed to fit the alignment constraints if (offset==0 && alignment<=padsize && padsize<=MI_MEDIUM_OBJ_SIZE_MAX && (padsize&align_mask)==0) { void* p = _mi_heap_malloc_zero(heap, size, zero); mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0); return p; } // otherwise over-allocate void* p = _mi_heap_malloc_zero(heap, size + alignment - 1, zero); if (p == NULL) return NULL; // .. and align within the allocation uintptr_t adjust = alignment - (((uintptr_t)p + offset) & align_mask); mi_assert_internal(adjust <= alignment); void* aligned_p = (adjust == alignment ? p : (void*)((uintptr_t)p + adjust)); if (aligned_p != p) mi_page_set_has_aligned(_mi_ptr_page(p), true); mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0); mi_assert_internal( p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p),_mi_ptr_page(aligned_p),aligned_p) ); return aligned_p; } mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false); } mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_malloc_aligned_at(heap, size, alignment, 0); } mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true); } mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_zalloc_aligned_at(heap, size, alignment, 0); } mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(count, size, &total)) return NULL; return mi_heap_zalloc_aligned_at(heap, total, alignment, offset); } mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_calloc_aligned_at(heap,count,size,alignment,0); } mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_malloc_aligned_at(mi_get_default_heap(), size, alignment, offset); } mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_malloc_aligned(mi_get_default_heap(), size, alignment); } mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_zalloc_aligned_at(mi_get_default_heap(), size, alignment, offset); } mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_zalloc_aligned(mi_get_default_heap(), size, alignment); } mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_calloc_aligned_at(mi_get_default_heap(), count, size, alignment, offset); } mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_calloc_aligned(mi_get_default_heap(), count, size, alignment); } static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept { mi_assert(alignment > 0); if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero); size_t size = mi_usable_size(p); if (newsize <= size && newsize >= (size - (size / 2)) && (((uintptr_t)p + offset) % alignment) == 0) { return p; // reallocation still fits, is aligned and not more than 50% waste } else { void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset); if (newp != NULL) { if (zero && newsize > size) { const mi_page_t* page = _mi_ptr_page(newp); if (page->is_zero) { // already zero initialized mi_assert_expensive(mi_mem_is_zero(newp,newsize)); } else { // also set last word in the previous allocation to zero to ensure any padding is zero-initialized size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); memset((uint8_t*)newp + start, 0, newsize - start); } } memcpy(newp, p, (newsize > size ? size : newsize)); mi_free(p); // only free if successful } return newp; } } static void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept { mi_assert(alignment > 0); if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); size_t offset = ((uintptr_t)p % alignment); // use offset of previous allocation (p can be NULL) return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,zero); } void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false); } void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false); } void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_realloc_zero_aligned_at(heap, p, newsize, alignment, offset, true); } void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { return mi_heap_realloc_zero_aligned(heap, p, newsize, alignment, true); } void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(newcount, size, &total)) return NULL; return mi_heap_rezalloc_aligned_at(heap, p, total, alignment, offset); } void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(newcount, size, &total)) return NULL; return mi_heap_rezalloc_aligned(heap, p, total, alignment); } void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_realloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset); } void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { return mi_heap_realloc_aligned(mi_get_default_heap(), p, newsize, alignment); } void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_rezalloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset); } void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { return mi_heap_rezalloc_aligned(mi_get_default_heap(), p, newsize, alignment); } void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { return mi_heap_recalloc_aligned_at(mi_get_default_heap(), p, newcount, size, alignment, offset); } void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { return mi_heap_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment); } ================================================ FILE: runtime/src/mimalloc/c/alloc-override-osx.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // Copyright 2019-2020 JetBrains s.r.o. #if !KONAN_MI_MALLOC #include "mimalloc.h" #include "mimalloc-internal.h" #if defined(MI_MALLOC_OVERRIDE) #if !defined(__APPLE__) #error "this file should only be included on macOS" #endif /* ------------------------------------------------------ Override system malloc on macOS This is done through the malloc zone interface. It seems we also need to interpose (see `alloc-override.c`) or otherwise we get zone errors as there are usually already allocations done by the time we take over the zone. Unfortunately, that means we need to replace the `free` with a checked free (`cfree`) impacting performance. ------------------------------------------------------ */ #include #include #include // memset #if defined(MAC_OS_X_VERSION_10_6) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // only available from OSX 10.6 extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import)); #endif /* ------------------------------------------------------ malloc zone members ------------------------------------------------------ */ static size_t zone_size(malloc_zone_t* zone, const void* p) { UNUSED(zone); if (!mi_is_in_heap_region(p)) return 0; // not our pointer, bail out return mi_usable_size(p); } static void* zone_malloc(malloc_zone_t* zone, size_t size) { UNUSED(zone); return mi_malloc(size); } static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) { UNUSED(zone); return mi_calloc(count, size); } static void* zone_valloc(malloc_zone_t* zone, size_t size) { UNUSED(zone); return mi_malloc_aligned(size, _mi_os_page_size()); } static void zone_free(malloc_zone_t* zone, void* p) { UNUSED(zone); return mi_free(p); } static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { UNUSED(zone); return mi_realloc(p, newsize); } static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) { UNUSED(zone); return mi_malloc_aligned(size,alignment); } static void zone_destroy(malloc_zone_t* zone) { UNUSED(zone); // todo: ignore for now? } static unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) { size_t i; for (i = 0; i < count; i++) { ps[i] = zone_malloc(zone, size); if (ps[i] == NULL) break; } return i; } static void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) { for(size_t i = 0; i < count; i++) { zone_free(zone, ps[i]); ps[i] = NULL; } } static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) { UNUSED(zone); UNUSED(size); mi_collect(false); return 0; } static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) { UNUSED(size); zone_free(zone,p); } /* ------------------------------------------------------ Introspection members ------------------------------------------------------ */ static kern_return_t intro_enumerator(task_t task, void* p, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder) { // todo: enumerate all memory UNUSED(task); UNUSED(p); UNUSED(type_mask); UNUSED(zone_address); UNUSED(reader); UNUSED(recorder); return KERN_SUCCESS; } static size_t intro_good_size(malloc_zone_t* zone, size_t size) { UNUSED(zone); return mi_good_size(size); } static boolean_t intro_check(malloc_zone_t* zone) { UNUSED(zone); return true; } static void intro_print(malloc_zone_t* zone, boolean_t verbose) { UNUSED(zone); UNUSED(verbose); mi_stats_print(NULL); } static void intro_log(malloc_zone_t* zone, void* p) { UNUSED(zone); UNUSED(p); // todo? } static void intro_force_lock(malloc_zone_t* zone) { UNUSED(zone); // todo? } static void intro_force_unlock(malloc_zone_t* zone) { UNUSED(zone); // todo? } static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { UNUSED(zone); // todo... stats->blocks_in_use = 0; stats->size_in_use = 0; stats->max_size_in_use = 0; stats->size_allocated = 0; } static boolean_t intro_zone_locked(malloc_zone_t* zone) { UNUSED(zone); return false; } /* ------------------------------------------------------ At process start, override the default allocator ------------------------------------------------------ */ static malloc_zone_t* mi_get_default_zone() { // The first returned zone is the real default malloc_zone_t** zones = NULL; unsigned count = 0; kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count); if (ret == KERN_SUCCESS && count > 0) { return zones[0]; } else { // fallback return malloc_default_zone(); } } static void __attribute__((constructor)) _mi_macos_override_malloc() { static malloc_introspection_t intro; memset(&intro, 0, sizeof(intro)); intro.enumerator = &intro_enumerator; intro.good_size = &intro_good_size; intro.check = &intro_check; intro.print = &intro_print; intro.log = &intro_log; intro.force_lock = &intro_force_lock; intro.force_unlock = &intro_force_unlock; static malloc_zone_t zone; memset(&zone, 0, sizeof(zone)); zone.version = 4; zone.zone_name = "mimalloc"; zone.size = &zone_size; zone.introspect = &intro; zone.malloc = &zone_malloc; zone.calloc = &zone_calloc; zone.valloc = &zone_valloc; zone.free = &zone_free; zone.realloc = &zone_realloc; zone.destroy = &zone_destroy; zone.batch_malloc = &zone_batch_malloc; zone.batch_free = &zone_batch_free; malloc_zone_t* purgeable_zone = NULL; #if defined(MAC_OS_X_VERSION_10_6) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // switch to version 9 on OSX 10.6 to support memalign. zone.version = 9; zone.memalign = &zone_memalign; zone.free_definite_size = &zone_free_definite_size; zone.pressure_relief = &zone_pressure_relief; intro.zone_locked = &intro_zone_locked; intro.statistics = &intro_statistics; // force the purgeable zone to exist to avoid strange bugs if (malloc_default_purgeable_zone) { purgeable_zone = malloc_default_purgeable_zone(); } #endif // Register our zone malloc_zone_register(&zone); // Unregister the default zone, this makes our zone the new default // as that was the last registered. malloc_zone_t *default_zone = mi_get_default_zone(); malloc_zone_unregister(default_zone); // Reregister the default zone so free and realloc in that zone keep working. malloc_zone_register(default_zone); // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs // earlier than the default zone. if (purgeable_zone != NULL) { malloc_zone_unregister(purgeable_zone); malloc_zone_register(purgeable_zone); } } #endif // MI_MALLOC_OVERRIDE #endif ================================================ FILE: runtime/src/mimalloc/c/alloc-override.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // Copyright 2019-2020 JetBrains s.r.o. #if !KONAN_MI_MALLOC #if !defined(MI_IN_ALLOC_C) #error "this file should be included from 'alloc.c' (so aliases can work)" #endif #if defined(MI_MALLOC_OVERRIDE) && defined(_WIN32) && !(defined(MI_SHARED_LIB) && defined(_DLL)) #error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)" #endif #if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) // || (defined(__MACH__) && !defined(MI_INTERPOSE))) // ------------------------------------------------------ // Override system malloc // ------------------------------------------------------ #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) // use aliasing to alias the exported function to one of our `mi_` functions #if (defined(__GNUC__) && __GNUC__ >= 9) #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun))) #else #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"))) #endif #define MI_FORWARD1(fun,x) MI_FORWARD(fun) #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun) #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun) #define MI_FORWARD0(fun,x) MI_FORWARD(fun) #define MI_FORWARD02(fun,x,y) MI_FORWARD(fun) #else // use forwarding by calling our `mi_` function #define MI_FORWARD1(fun,x) { return fun(x); } #define MI_FORWARD2(fun,x,y) { return fun(x,y); } #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); } #define MI_FORWARD0(fun,x) { fun(x); } #define MI_FORWARD02(fun,x,y) { fun(x,y); } #endif #if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE) // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` // See: struct mi_interpose_s { const void* replacement; const void* target; }; #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } #define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) __attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) = { MI_INTERPOSE_MI(malloc), MI_INTERPOSE_MI(calloc), MI_INTERPOSE_MI(realloc), MI_INTERPOSE_MI(strdup), MI_INTERPOSE_MI(strndup), MI_INTERPOSE_MI(realpath), MI_INTERPOSE_MI(posix_memalign), MI_INTERPOSE_MI(reallocf), MI_INTERPOSE_MI(valloc), // some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity ) MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us }; #elif defined(_MSC_VER) // cannot override malloc unless using a dll. // we just override new/delete which does work in a static library. #else // On all other systems forward to our API void* malloc(size_t size) MI_FORWARD1(mi_malloc, size); void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n); void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize); void free(void* p) MI_FORWARD0(mi_free, p); #endif #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) #pragma GCC visibility push(default) #endif // ------------------------------------------------------ // Override new/delete // This is not really necessary as they usually call // malloc/free anyway, but it improves performance. // ------------------------------------------------------ #ifdef __cplusplus // ------------------------------------------------------ // With a C++ compiler we override the new/delete operators. // see // ------------------------------------------------------ #include void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p); void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p); void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } #if (__cplusplus >= 201402L || _MSC_VER >= 1916) void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); #endif #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5)) void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } #endif #elif (defined(__GNUC__) || defined(__clang__)) // ------------------------------------------------------ // Override by defining the mangled C++ names of the operators (as // used by GCC and CLang). // See // ------------------------------------------------------ void _ZdlPv(void* p) MI_FORWARD0(mi_free,p); // delete void _ZdaPv(void* p) MI_FORWARD0(mi_free,p); // delete[] void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } typedef struct mi_nothrow_s { } mi_nothrow_t; #if (MI_INTPTR_SIZE==8) void* _Znwm(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit void* _Znam(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } #elif (MI_INTPTR_SIZE==4) void* _Znwj(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit void* _Znaj(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } #else #error "define overloads for new/delete for this platform (just for performance, can be skipped)" #endif #endif // __cplusplus #ifdef __cplusplus extern "C" { #endif // ------------------------------------------------------ // Posix & Unix functions definitions // ------------------------------------------------------ void cfree(void* p) MI_FORWARD0(mi_free, p); void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize); size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p); #if !defined(__ANDROID__) size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p); #else size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p); #endif // no forwarding here due to aliasing/name mangling issues void* valloc(size_t size) { return mi_valloc(size); } void* pvalloc(size_t size) { return mi_pvalloc(size); } void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); } void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } // on some glibc `aligned_alloc` is declared `static inline` so we cannot override it (e.g. Conda). This happens // when _GLIBCXX_HAVE_ALIGNED_ALLOC is not defined. However, in those cases it will use `memalign`, `posix_memalign`, // or `_aligned_malloc` and we can avoid overriding it ourselves. // We should always override if using C compilation. (issue #276) #if _GLIBCXX_HAVE_ALIGNED_ALLOC || !defined(__cplusplus) void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } #endif #if defined(__GLIBC__) && defined(__linux__) // forward __libc interface (needed for glibc-based Linux distributions) void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size); void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size); void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size); void __libc_free(void* p) MI_FORWARD0(mi_free,p); void __libc_cfree(void* p) MI_FORWARD0(mi_free,p); void* __libc_valloc(size_t size) { return mi_valloc(size); } void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); } void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); } int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); } #endif #ifdef __cplusplus } #endif #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) #pragma GCC visibility pop #endif #endif // MI_MALLOC_OVERRIDE && !_WIN32 #endif // KONAN_MI_MALLOC ================================================ FILE: runtime/src/mimalloc/c/alloc-posix.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018,2019, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // ------------------------------------------------------------------------ // mi prefixed publi definitions of various Posix, Unix, and C++ functions // for convenience and used when overriding these functions. // ------------------------------------------------------------------------ #include "mimalloc.h" #include "mimalloc-internal.h" // ------------------------------------------------------ // Posix & Unix functions definitions // ------------------------------------------------------ #include #include // memcpy #include // getenv #ifdef _MSC_VER #pragma warning(disable:4996) // getenv _wgetenv #endif #ifndef EINVAL #define EINVAL 22 #endif #ifndef ENOMEM #define ENOMEM 12 #endif size_t mi_malloc_size(const void* p) mi_attr_noexcept { return mi_usable_size(p); } size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept { return mi_usable_size(p); } void mi_cfree(void* p) mi_attr_noexcept { if (mi_is_in_heap_region(p)) { mi_free(p); } } int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept { // Note: The spec dictates we should not modify `*p` on an error. (issue#27) // if (p == NULL) return EINVAL; if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment if (!_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2 void* q = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); if (q==NULL && size != 0) return ENOMEM; mi_assert_internal(((uintptr_t)q % alignment) == 0); *p = q; return 0; } mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept { void* p = (mi_malloc_satisfies_alignment(alignment,size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); mi_assert_internal(((uintptr_t)p % alignment) == 0); return p; } mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept { return mi_memalign( _mi_os_page_size(), size ); } mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept { size_t psize = _mi_os_page_size(); if (size >= SIZE_MAX - psize) return NULL; // overflow size_t asize = _mi_align_up(size, psize); return mi_malloc_aligned(asize, psize); } mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept { if (alignment==0 || !_mi_is_power_of_two(alignment)) return NULL; if ((size&(alignment-1)) != 0) return NULL; // C11 requires integral multiple, see void* p = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); mi_assert_internal(((uintptr_t)p % alignment) == 0); return p; } void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD void* newp = mi_reallocn(p,count,size); if (newp==NULL) errno = ENOMEM; return newp; } void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft void* res = mi_expand(p, newsize); if (res == NULL) errno = ENOMEM; return res; } mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept { if (s==NULL) return NULL; size_t len; for(len = 0; s[len] != 0; len++) { } size_t size = (len+1)*sizeof(unsigned short); unsigned short* p = (unsigned short*)mi_malloc(size); if (p != NULL) { memcpy(p,s,size); } return p; } mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept { return (unsigned char*)mi_strdup((const char*)s); } int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept { if (buf==NULL || name==NULL) return EINVAL; if (size != NULL) *size = 0; char* p = getenv(name); // mscver warning 4996 if (p==NULL) { *buf = NULL; } else { *buf = mi_strdup(p); if (*buf==NULL) return ENOMEM; if (size != NULL) *size = strlen(p); } return 0; } int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept { if (buf==NULL || name==NULL) return EINVAL; if (size != NULL) *size = 0; #if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)) // not supported *buf = NULL; return EINVAL; #else unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); // msvc warning 4996 if (p==NULL) { *buf = NULL; } else { *buf = mi_wcsdup(p); if (*buf==NULL) return ENOMEM; if (size != NULL) *size = wcslen((const wchar_t*)p); } return 0; #endif } void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft return mi_recalloc_aligned_at(p, newcount, size, alignment, offset); } void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft return mi_recalloc_aligned(p, newcount, size, alignment); } ================================================ FILE: runtime/src/mimalloc/c/alloc.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // memset, memcpy, strlen #include // malloc, exit #define MI_IN_ALLOC_C #include "alloc-override.c" #undef MI_IN_ALLOC_C // ------------------------------------------------------ // Allocation // ------------------------------------------------------ // Fast allocation in a page: just pop from the free list. // Fall back to generic allocation only if the list is empty. extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept { mi_assert_internal(page->xblock_size==0||mi_page_block_size(page) >= size); mi_block_t* block = page->free; if (mi_unlikely(block == NULL)) { return _mi_malloc_generic(heap, size); } mi_assert_internal(block != NULL && _mi_ptr_page(block) == page); // pop from the free list page->free = mi_block_next(page, block); page->used++; mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page); #if (MI_DEBUG>0) if (!page->is_zero) { memset(block, MI_DEBUG_UNINIT, size); } #elif (MI_SECURE!=0) block->next = 0; // don't leak internal data #endif #if (MI_STAT>1) const size_t bsize = mi_page_usable_block_size(page); if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { const size_t bin = _mi_bin(bsize); mi_heap_stat_increase(heap, normal[bin], 1); } #endif #if (MI_PADDING > 0) && defined(MI_ENCODE_FREELIST) mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page)); ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE)); mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta)); padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys)); padding->delta = (uint32_t)(delta); uint8_t* fill = (uint8_t*)padding - delta; const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; } #endif return block; } // allocate a small block extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept { mi_assert(heap!=NULL); mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local mi_assert(size <= MI_SMALL_SIZE_MAX); #if (MI_PADDING) if (size == 0) { size = sizeof(void*); } #endif mi_page_t* page = _mi_heap_get_free_small_page(heap,size + MI_PADDING_SIZE); void* p = _mi_page_malloc(heap, page, size + MI_PADDING_SIZE); mi_assert_internal(p==NULL || mi_usable_size(p) >= size); #if MI_STAT>1 if (p != NULL) { if (!mi_heap_is_initialized(heap)) { heap = mi_get_default_heap(); } mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); } #endif return p; } extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept { return mi_heap_malloc_small(mi_get_default_heap(), size); } // The main allocation function extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { if (mi_likely(size <= MI_SMALL_SIZE_MAX)) { return mi_heap_malloc_small(heap, size); } else { mi_assert(heap!=NULL); mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE); // note: size can overflow but it is detected in malloc_generic mi_assert_internal(p == NULL || mi_usable_size(p) >= size); #if MI_STAT>1 if (p != NULL) { if (!mi_heap_is_initialized(heap)) { heap = mi_get_default_heap(); } mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); } #endif return p; } } extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept { return mi_heap_malloc(mi_get_default_heap(), size); } void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size) { // note: we need to initialize the whole usable block size to zero, not just the requested size, // or the recalloc/rezalloc functions cannot safely expand in place (see issue #63) UNUSED(size); mi_assert_internal(p != NULL); mi_assert_internal(mi_usable_size(p) >= size); // size can be zero mi_assert_internal(_mi_ptr_page(p)==page); if (page->is_zero && size > sizeof(mi_block_t)) { // already zero initialized memory ((mi_block_t*)p)->next = 0; // clear the free list pointer mi_assert_expensive(mi_mem_is_zero(p, mi_usable_size(p))); } else { // otherwise memset memset(p, 0, mi_usable_size(p)); } } // zero initialized small block mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept { void* p = mi_malloc_small(size); if (p != NULL) { _mi_block_zero_init(_mi_ptr_page(p), p, size); // todo: can we avoid getting the page again? } return p; } void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) { void* p = mi_heap_malloc(heap,size); if (zero && p != NULL) { _mi_block_zero_init(_mi_ptr_page(p),p,size); // todo: can we avoid getting the page again? } return p; } extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { return _mi_heap_malloc_zero(heap, size, true); } mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept { return mi_heap_zalloc(mi_get_default_heap(),size); } // ------------------------------------------------------ // Check for double free in secure and debug mode // This is somewhat expensive so only enabled for secure mode 4 // ------------------------------------------------------ #if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0)) // linear check if the free list contains a specific element static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) { while (list != NULL) { if (elem==list) return true; list = mi_block_next(page, list); } return false; } static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) { // The decoded value is in the same page (or NULL). // Walk the free lists to verify positively if it is already freed if (mi_list_contains(page, page->free, block) || mi_list_contains(page, page->local_free, block) || mi_list_contains(page, mi_page_thread_free(page), block)) { _mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_block_size(page)); return true; } return false; } static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer? (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL? { // Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free? // (continue in separate function to improve code generation) return mi_check_is_double_freex(page, block); } return false; } #else static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { UNUSED(page); UNUSED(block); return false; } #endif // --------------------------------------------------------------------------- // Check for heap block overflow by setting up padding at the end of the block // --------------------------------------------------------------------------- #if (MI_PADDING>0) && defined(MI_ENCODE_FREELIST) static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) { *bsize = mi_page_usable_block_size(page); const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize); *delta = padding->delta; return ((uint32_t)mi_ptr_encode(page,block,page->keys) == padding->canary && *delta <= *bsize); } // Return the exact usable size of a block. static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { size_t bsize; size_t delta; bool ok = mi_page_decode_padding(page, block, &delta, &bsize); mi_assert_internal(ok); mi_assert_internal(delta <= bsize); return (ok ? bsize - delta : 0); } static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) { size_t bsize; size_t delta; bool ok = mi_page_decode_padding(page, block, &delta, &bsize); *size = *wrong = bsize; if (!ok) return false; mi_assert_internal(bsize >= delta); *size = bsize - delta; uint8_t* fill = (uint8_t*)block + bsize - delta; const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes for (size_t i = 0; i < maxpad; i++) { if (fill[i] != MI_DEBUG_PADDING) { *wrong = bsize - delta + i; return false; } } return true; } static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { size_t size; size_t wrong; if (!mi_verify_padding(page,block,&size,&wrong)) { _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong ); } } // When a non-thread-local block is freed, it becomes part of the thread delayed free // list that is freed later by the owning heap. If the exact usable size is too small to // contain the pointer for the delayed list, then shrink the padding (by decreasing delta) // so it will later not trigger an overflow error in `mi_free_block`. static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { size_t bsize; size_t delta; bool ok = mi_page_decode_padding(page, block, &delta, &bsize); mi_assert_internal(ok); if (!ok || (bsize - delta) >= min_size) return; // usually already enough space mi_assert_internal(bsize >= min_size); if (bsize < min_size) return; // should never happen size_t new_delta = (bsize - min_size); mi_assert_internal(new_delta < bsize); mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize); padding->delta = (uint32_t)new_delta; } #else static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { UNUSED(page); UNUSED(block); } static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { UNUSED(block); return mi_page_usable_block_size(page); } static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { UNUSED(page); UNUSED(block); UNUSED(min_size); } #endif // ------------------------------------------------------ // Free // ------------------------------------------------------ // multi-threaded free static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* block) { // The padding check may access the non-thread-owned page for the key values. // that is safe as these are constant and the page won't be freed (as the block is not freed yet). mi_check_padding(page, block); mi_padding_shrink(page, block, sizeof(mi_block_t)); // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection #if (MI_DEBUG!=0) memset(block, MI_DEBUG_FREED, mi_usable_size(block)); #endif // huge page segments are always abandoned and can be freed immediately mi_segment_t* const segment = _mi_page_segment(page); if (segment->page_kind==MI_PAGE_HUGE) { _mi_segment_huge_page_free(segment, page, block); return; } // Try to put the block on either the page-local thread free list, or the heap delayed free list. mi_thread_free_t tfreex; bool use_delayed; mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); do { use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE); if (mi_unlikely(use_delayed)) { // unlikely: this only happens on the first concurrent free in a page that is in the full list tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING); } else { // usual: directly add to page thread_free list mi_block_set_next(page, block, mi_tf_block(tfree)); tfreex = mi_tf_set_block(tfree,block); } } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); if (mi_unlikely(use_delayed)) { // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`) mi_heap_t* const heap = (mi_heap_t*)(mi_atomic_load_acquire(&page->xheap)); //mi_page_heap(page); mi_assert_internal(heap != NULL); if (heap != NULL) { // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity) mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); do { mi_block_set_nextx(heap,block,dfree, heap->keys); } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); } // and reset the MI_DELAYED_FREEING flag tfree = mi_atomic_load_relaxed(&page->xthread_free); do { tfreex = tfree; mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING); tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE); } while (!mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); } } // regular free static inline void _mi_free_block(mi_page_t* page, bool local, mi_block_t* block) { // and push it on the free list if (mi_likely(local)) { // owning thread can free a block directly if (mi_unlikely(mi_check_is_double_free(page, block))) return; mi_check_padding(page, block); #if (MI_DEBUG!=0) memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); #endif mi_block_set_next(page, block, page->local_free); page->local_free = block; page->used--; if (mi_unlikely(mi_page_all_free(page))) { _mi_page_retire(page); } else if (mi_unlikely(mi_page_is_in_full(page))) { _mi_page_unfull(page); } } else { _mi_free_block_mt(page,block); } } // Adjust a block that was allocated aligned, to the actual start of the block in the page. mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) { mi_assert_internal(page!=NULL && p!=NULL); const size_t diff = (uint8_t*)p - _mi_page_start(segment, page, NULL); const size_t adjust = (diff % mi_page_block_size(page)); return (mi_block_t*)((uintptr_t)p - adjust); } static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool local, void* p) { mi_page_t* const page = _mi_segment_page_of(segment, p); mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p); _mi_free_block(page, local, block); } // Get the segment data belonging to a pointer // This is just a single `and` in assembly but does further checks in debug mode // (and secure mode) if this was a valid pointer. static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg) { UNUSED(msg); #if (MI_DEBUG>0) if (mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0)) { _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p); return NULL; } #endif mi_segment_t* const segment = _mi_ptr_segment(p); if (mi_unlikely(segment == NULL)) return NULL; // checks also for (p==NULL) #if (MI_DEBUG>0) if (mi_unlikely(!mi_is_in_heap_region(p))) { _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n" "(this may still be a valid very large allocation (over 64MiB))\n", msg, p); if (mi_likely(_mi_ptr_cookie(segment) == segment->cookie)) { _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p); } } #endif #if (MI_DEBUG>0 || MI_SECURE>=4) if (mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) { _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", p); } #endif return segment; } // Free a block void mi_free(void* p) mi_attr_noexcept { const mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free"); if (mi_unlikely(segment == NULL)) return; const uintptr_t tid = _mi_thread_id(); mi_page_t* const page = _mi_segment_page_of(segment, p); mi_block_t* const block = (mi_block_t*)p; #if (MI_STAT>1) mi_heap_t* const heap = mi_heap_get_default(); const size_t bsize = mi_page_usable_block_size(page); mi_heap_stat_decrease(heap, malloc, bsize); if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { // huge page stats are accounted for in `_mi_page_retire` mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], 1); } #endif if (mi_likely(tid == segment->thread_id && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks // local, and not full or aligned if (mi_unlikely(mi_check_is_double_free(page,block))) return; mi_check_padding(page, block); #if (MI_DEBUG!=0) memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); #endif mi_block_set_next(page, block, page->local_free); page->local_free = block; if (mi_unlikely(--page->used == 0)) { // using this expression generates better code than: page->used--; if (mi_page_all_free(page)) _mi_page_retire(page); } } else { // non-local, aligned blocks, or a full page; use the more generic path // note: recalc page in generic to improve code generation mi_free_generic(segment, tid == segment->thread_id, p); } } bool _mi_free_delayed_block(mi_block_t* block) { // get segment and page const mi_segment_t* const segment = _mi_ptr_segment(block); mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); mi_assert_internal(_mi_thread_id() == segment->thread_id); mi_page_t* const page = _mi_segment_page_of(segment, block); // Clear the no-delayed flag so delayed freeing is used again for this page. // This must be done before collecting the free lists on this page -- otherwise // some blocks may end up in the page `thread_free` list with no blocks in the // heap `thread_delayed_free` list which may cause the page to be never freed! // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`) _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */); // collect all other non-local frees to ensure up-to-date `used` count _mi_page_free_collect(page, false); // and free the block (possibly freeing the page as well since used is updated) _mi_free_block(page, true, block); return true; } // Bytes available in a block static size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept { const mi_segment_t* const segment = mi_checked_ptr_segment(p,msg); if (segment==NULL) return 0; const mi_page_t* const page = _mi_segment_page_of(segment, p); const mi_block_t* block = (const mi_block_t*)p; if (mi_unlikely(mi_page_has_aligned(page))) { block = _mi_page_ptr_unalign(segment, page, p); size_t size = mi_page_usable_size_of(page, block); ptrdiff_t const adjust = (uint8_t*)p - (uint8_t*)block; mi_assert_internal(adjust >= 0 && (size_t)adjust <= size); return (size - adjust); } else { return mi_page_usable_size_of(page, block); } } size_t mi_usable_size(const void* p) mi_attr_noexcept { return _mi_usable_size(p, "mi_usable_size"); } // ------------------------------------------------------ // ensure explicit external inline definitions are emitted! // ------------------------------------------------------ #ifdef __cplusplus void* _mi_externs[] = { (void*)&_mi_page_malloc, (void*)&mi_malloc, (void*)&mi_malloc_small, (void*)&mi_heap_malloc, (void*)&mi_heap_zalloc, (void*)&mi_heap_malloc_small }; #endif // ------------------------------------------------------ // Allocation extensions // ------------------------------------------------------ void mi_free_size(void* p, size_t size) mi_attr_noexcept { UNUSED_RELEASE(size); mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size")); mi_free(p); } void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept { UNUSED_RELEASE(alignment); mi_assert(((uintptr_t)p % alignment) == 0); mi_free_size(p,size); } void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept { UNUSED_RELEASE(alignment); mi_assert(((uintptr_t)p % alignment) == 0); mi_free(p); } extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(count,size,&total)) return NULL; return mi_heap_zalloc(heap,total); } mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept { return mi_heap_calloc(mi_get_default_heap(),count,size); } // Uninitialized `calloc` extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(count, size, &total)) return NULL; return mi_heap_malloc(heap, total); } mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept { return mi_heap_mallocn(mi_get_default_heap(),count,size); } // Expand in place or fail void* mi_expand(void* p, size_t newsize) mi_attr_noexcept { if (p == NULL) return NULL; size_t size = _mi_usable_size(p,"mi_expand"); if (newsize > size) return NULL; return p; // it fits } void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) { if (p == NULL) return _mi_heap_malloc_zero(heap,newsize,zero); size_t size = _mi_usable_size(p,"mi_realloc"); if (newsize <= size && newsize >= (size / 2)) { return p; // reallocation still fits and not more than 50% waste } void* newp = mi_heap_malloc(heap,newsize); if (mi_likely(newp != NULL)) { if (zero && newsize > size) { // also set last word in the previous allocation to zero to ensure any padding is zero-initialized size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); memset((uint8_t*)newp + start, 0, newsize - start); } memcpy(newp, p, (newsize > size ? size : newsize)); mi_free(p); // only free if successful } return newp; } void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { return _mi_heap_realloc_zero(heap, p, newsize, false); } void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(count, size, &total)) return NULL; return mi_heap_realloc(heap, p, total); } // Reallocate but free `p` on errors void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { void* newp = mi_heap_realloc(heap, p, newsize); if (newp==NULL && p!=NULL) mi_free(p); return newp; } void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { return _mi_heap_realloc_zero(heap, p, newsize, true); } void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { size_t total; if (mi_count_size_overflow(count, size, &total)) return NULL; return mi_heap_rezalloc(heap, p, total); } void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept { return mi_heap_realloc(mi_get_default_heap(),p,newsize); } void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept { return mi_heap_reallocn(mi_get_default_heap(),p,count,size); } // Reallocate but free `p` on errors void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept { return mi_heap_reallocf(mi_get_default_heap(),p,newsize); } void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept { return mi_heap_rezalloc(mi_get_default_heap(), p, newsize); } void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { return mi_heap_recalloc(mi_get_default_heap(), p, count, size); } // ------------------------------------------------------ // strdup, strndup, and realpath // ------------------------------------------------------ // `strdup` using mi_malloc mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept { if (s == NULL) return NULL; size_t n = strlen(s); char* t = (char*)mi_heap_malloc(heap,n+1); if (t != NULL) memcpy(t, s, n + 1); return t; } mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept { return mi_heap_strdup(mi_get_default_heap(), s); } // `strndup` using mi_malloc mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept { if (s == NULL) return NULL; const char* end = (const char*)memchr(s, 0, n); // find end of string in the first `n` characters (returns NULL if not found) const size_t m = (end != NULL ? (size_t)(end - s) : n); // `m` is the minimum of `n` or the end-of-string mi_assert_internal(m <= n); char* t = (char*)mi_heap_malloc(heap, m+1); if (t == NULL) return NULL; memcpy(t, s, m); t[m] = 0; return t; } mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept { return mi_heap_strndup(mi_get_default_heap(),s,n); } #ifndef __wasi__ // `realpath` using mi_malloc #ifdef _WIN32 #ifndef PATH_MAX #define PATH_MAX MAX_PATH #endif #include mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { // todo: use GetFullPathNameW to allow longer file names char buf[PATH_MAX]; DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL); if (res == 0) { errno = GetLastError(); return NULL; } else if (res > PATH_MAX) { errno = EINVAL; return NULL; } else if (resolved_name != NULL) { return resolved_name; } else { return mi_heap_strndup(heap, buf, PATH_MAX); } } #else #include // pathconf static size_t mi_path_max() { static size_t path_max = 0; if (path_max <= 0) { long m = pathconf("/",_PC_PATH_MAX); if (m <= 0) path_max = 4096; // guess else if (m < 256) path_max = 256; // at least 256 else path_max = m; } return path_max; } char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { if (resolved_name != NULL) { return realpath(fname,resolved_name); } else { size_t n = mi_path_max(); char* buf = (char*)mi_malloc(n+1); if (buf==NULL) return NULL; char* rname = realpath(fname,buf); char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL` mi_free(buf); return result; } } #endif mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept { return mi_heap_realpath(mi_get_default_heap(),fname,resolved_name); } #endif /*------------------------------------------------------- C++ new and new_aligned The standard requires calling into `get_new_handler` and throwing the bad_alloc exception on failure. If we compile with a C++ compiler we can implement this precisely. If we use a C compiler we cannot throw a `bad_alloc` exception but we call `exit` instead (i.e. not returning). -------------------------------------------------------*/ #ifdef __cplusplus #include static bool mi_try_new_handler(bool nothrow) { std::new_handler h = std::get_new_handler(); if (h==NULL) { if (!nothrow) throw std::bad_alloc(); return false; } else { h(); return true; } } #else typedef void (*std_new_handler_t)(); #if (defined(__GNUC__) || defined(__clang__)) std_new_handler_t __attribute((weak)) _ZSt15get_new_handlerv() { return NULL; } static std_new_handler_t mi_get_new_handler() { return _ZSt15get_new_handlerv(); } #else // note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`. static std_new_handler_t mi_get_new_handler() { return NULL; } #endif static bool mi_try_new_handler(bool nothrow) { std_new_handler_t h = mi_get_new_handler(); if (h==NULL) { if (!nothrow) exit(ENOMEM); // cannot throw in plain C, use exit as we are out of memory anyway. return false; } else { h(); return true; } } #endif static mi_decl_noinline void* mi_try_new(size_t size, bool nothrow ) { void* p = NULL; while(p == NULL && mi_try_new_handler(nothrow)) { p = mi_malloc(size); } return p; } mi_decl_restrict void* mi_new(size_t size) { void* p = mi_malloc(size); if (mi_unlikely(p == NULL)) return mi_try_new(size,false); return p; } mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept { void* p = mi_malloc(size); if (mi_unlikely(p == NULL)) return mi_try_new(size, true); return p; } mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) { void* p; do { p = mi_malloc_aligned(size, alignment); } while(p == NULL && mi_try_new_handler(false)); return p; } mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept { void* p; do { p = mi_malloc_aligned(size, alignment); } while(p == NULL && mi_try_new_handler(true)); return p; } mi_decl_restrict void* mi_new_n(size_t count, size_t size) { size_t total; if (mi_unlikely(mi_count_size_overflow(count, size, &total))) { mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc return NULL; } else { return mi_new(total); } } void* mi_new_realloc(void* p, size_t newsize) { void* q; do { q = mi_realloc(p, newsize); } while (q == NULL && mi_try_new_handler(false)); return q; } void* mi_new_reallocn(void* p, size_t newcount, size_t size) { size_t total; if (mi_unlikely(mi_count_size_overflow(newcount, size, &total))) { mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc return NULL; } else { return mi_new_realloc(p, total); } } ================================================ FILE: runtime/src/mimalloc/c/arena.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2019, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------- "Arenas" are fixed area's of OS memory from which we can allocate large blocks (>= MI_ARENA_BLOCK_SIZE, 32MiB). In contrast to the rest of mimalloc, the arenas are shared between threads and need to be accessed using atomic operations. Currently arenas are only used to for huge OS page (1GiB) reservations, otherwise it delegates to direct allocation from the OS. In the future, we can expose an API to manually add more kinds of arenas which is sometimes needed for embedded devices or shared memory for example. (We can also employ this with WASI or `sbrk` systems to reserve large arenas on demand and be able to reuse them efficiently). The arena allocation needs to be thread safe and we use an atomic bitmap to allocate. The current implementation of the bitmap can only do this within a field (`uintptr_t`) so we can allocate at most blocks of 2GiB (64*32MiB) and no object can cross the boundary. This can lead to fragmentation but fortunately most objects will be regions of 256MiB in practice. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // memset #include "bitmap.inc.c" // atomic bitmap // os.c void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld); void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* stats); void _mi_os_free(void* p, size_t size, mi_stats_t* stats); void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize); void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats); bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); /* ----------------------------------------------------------- Arena allocation ----------------------------------------------------------- */ #define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE #define MI_ARENA_BLOCK_SIZE (8*MI_SEGMENT_ALIGN) // 32MiB #define MI_ARENA_MAX_OBJ_SIZE (MI_BITMAP_FIELD_BITS * MI_ARENA_BLOCK_SIZE) // 2GiB #define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 16MiB #define MI_MAX_ARENAS (64) // not more than 256 (since we use 8 bits in the memid) // A memory arena descriptor typedef struct mi_arena_s { _Atomic(uint8_t*) start; // the start of the memory area size_t block_count; // size of the area in arena blocks (of `MI_ARENA_BLOCK_SIZE`) size_t field_count; // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`) int numa_node; // associated NUMA node bool is_zero_init; // is the arena zero initialized? bool is_committed; // is the memory committed bool is_large; // large OS page allocated _Atomic(uintptr_t) search_idx; // optimization to start the search for free blocks mi_bitmap_field_t* blocks_dirty; // are the blocks potentially non-zero? mi_bitmap_field_t* blocks_committed; // if `!is_committed`, are the blocks committed? mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`) } mi_arena_t; // The available arenas static mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS]; static mi_decl_cache_align _Atomic(uintptr_t) mi_arena_count; // = 0 /* ----------------------------------------------------------- Arena allocations get a memory id where the lower 8 bits are the arena index +1, and the upper bits the block index. ----------------------------------------------------------- */ // Use `0` as a special id for direct OS allocated memory. #define MI_MEMID_OS 0 static size_t mi_arena_id_create(size_t arena_index, mi_bitmap_index_t bitmap_index) { mi_assert_internal(arena_index < 0xFE); mi_assert_internal(((bitmap_index << 8) >> 8) == bitmap_index); // no overflow? return ((bitmap_index << 8) | ((arena_index+1) & 0xFF)); } static void mi_arena_id_indices(size_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index) { mi_assert_internal(memid != MI_MEMID_OS); *arena_index = (memid & 0xFF) - 1; *bitmap_index = (memid >> 8); } static size_t mi_block_count_of_size(size_t size) { return _mi_divide_up(size, MI_ARENA_BLOCK_SIZE); } /* ----------------------------------------------------------- Thread safe allocation in an arena ----------------------------------------------------------- */ static bool mi_arena_alloc(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx) { const size_t fcount = arena->field_count; size_t idx = mi_atomic_load_acquire(&arena->search_idx); // start from last search for (size_t visited = 0; visited < fcount; visited++, idx++) { if (idx >= fcount) idx = 0; // wrap around // try to atomically claim a range of bits if (mi_bitmap_try_find_claim_field(arena->blocks_inuse, idx, blocks, bitmap_idx)) { mi_atomic_store_release(&arena->search_idx, idx); // start search from here next time return true; } } return false; } /* ----------------------------------------------------------- Arena Allocation ----------------------------------------------------------- */ static void* mi_arena_alloc_from(mi_arena_t* arena, size_t arena_index, size_t needed_bcount, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) { mi_bitmap_index_t bitmap_index; if (!mi_arena_alloc(arena, needed_bcount, &bitmap_index)) return NULL; // claimed it! set the dirty bits (todo: no need for an atomic op here?) void* p = arena->start + (mi_bitmap_index_bit(bitmap_index)*MI_ARENA_BLOCK_SIZE); *memid = mi_arena_id_create(arena_index, bitmap_index); *is_zero = mi_bitmap_claim(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL); *large = arena->is_large; if (arena->is_committed) { // always committed *commit = true; } else if (*commit) { // arena not committed as a whole, but commit requested: ensure commit now bool any_uncommitted; mi_bitmap_claim(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted); if (any_uncommitted) { bool commit_zero; _mi_os_commit(p, needed_bcount * MI_ARENA_BLOCK_SIZE, &commit_zero, tld->stats); if (commit_zero) *is_zero = true; } } else { // no need to commit, but check if already fully committed *commit = mi_bitmap_is_claimed(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index); } return p; } void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) { mi_assert_internal(commit != NULL && large != NULL && is_zero != NULL && memid != NULL && tld != NULL); mi_assert_internal(size > 0); *memid = MI_MEMID_OS; *is_zero = false; // try to allocate in an arena if the alignment is small enough // and the object is not too large or too small. if (alignment <= MI_SEGMENT_ALIGN && size <= MI_ARENA_MAX_OBJ_SIZE && size >= MI_ARENA_MIN_OBJ_SIZE) { const size_t bcount = mi_block_count_of_size(size); const int numa_node = _mi_os_numa_node(tld); // current numa node mi_assert_internal(size <= bcount*MI_ARENA_BLOCK_SIZE); // try numa affine allocation for (size_t i = 0; i < MI_MAX_ARENAS; i++) { mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]); if (arena==NULL) break; // end reached if ((arena->numa_node<0 || arena->numa_node==numa_node) && // numa local? (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages { void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld); mi_assert_internal((uintptr_t)p % alignment == 0); if (p != NULL) return p; } } // try from another numa node instead.. for (size_t i = 0; i < MI_MAX_ARENAS; i++) { mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t, &mi_arenas[i]); if (arena==NULL) break; // end reached if ((arena->numa_node>=0 && arena->numa_node!=numa_node) && // not numa local! (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages { void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld); mi_assert_internal((uintptr_t)p % alignment == 0); if (p != NULL) return p; } } } // finally, fall back to the OS *is_zero = true; *memid = MI_MEMID_OS; return _mi_os_alloc_aligned(size, alignment, *commit, large, tld); } void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) { return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, commit, large, is_zero, memid, tld); } /* ----------------------------------------------------------- Arena free ----------------------------------------------------------- */ void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats) { mi_assert_internal(size > 0 && stats != NULL); if (p==NULL) return; if (size==0) return; if (memid == MI_MEMID_OS) { // was a direct OS allocation, pass through _mi_os_free_ex(p, size, all_committed, stats); } else { // allocated in an arena size_t arena_idx; size_t bitmap_idx; mi_arena_id_indices(memid, &arena_idx, &bitmap_idx); mi_assert_internal(arena_idx < MI_MAX_ARENAS); mi_arena_t* arena = mi_atomic_load_ptr_relaxed(mi_arena_t,&mi_arenas[arena_idx]); mi_assert_internal(arena != NULL); if (arena == NULL) { _mi_error_message(EINVAL, "trying to free from non-existent arena: %p, size %zu, memid: 0x%zx\n", p, size, memid); return; } mi_assert_internal(arena->field_count > mi_bitmap_index_field(bitmap_idx)); if (arena->field_count <= mi_bitmap_index_field(bitmap_idx)) { _mi_error_message(EINVAL, "trying to free from non-existent arena block: %p, size %zu, memid: 0x%zx\n", p, size, memid); return; } const size_t blocks = mi_block_count_of_size(size); bool ones = mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx); if (!ones) { _mi_error_message(EAGAIN, "trying to free an already freed block: %p, size %zu\n", p, size); return; }; } } /* ----------------------------------------------------------- Add an arena. ----------------------------------------------------------- */ static bool mi_arena_add(mi_arena_t* arena) { mi_assert_internal(arena != NULL); mi_assert_internal((uintptr_t)mi_atomic_load_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0); mi_assert_internal(arena->block_count > 0); uintptr_t i = mi_atomic_increment_acq_rel(&mi_arena_count); if (i >= MI_MAX_ARENAS) { mi_atomic_decrement_acq_rel(&mi_arena_count); return false; } mi_atomic_store_ptr_release(mi_arena_t,&mi_arenas[i], arena); return true; } /* ----------------------------------------------------------- Reserve a huge page arena. ----------------------------------------------------------- */ #include // ENOMEM // reserve at a specific numa node int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept { if (pages==0) return 0; if (numa_node < -1) numa_node = -1; if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count(); size_t hsize = 0; size_t pages_reserved = 0; void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize); if (p==NULL || pages_reserved==0) { _mi_warning_message("failed to reserve %zu gb huge pages\n", pages); return ENOMEM; } _mi_verbose_message("numa node %i: reserved %zu gb huge pages (of the %zu gb requested)\n", numa_node, pages_reserved, pages); size_t bcount = mi_block_count_of_size(hsize); size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS); size_t asize = sizeof(mi_arena_t) + (2*fields*sizeof(mi_bitmap_field_t)); mi_arena_t* arena = (mi_arena_t*)_mi_os_alloc(asize, &_mi_stats_main); // TODO: can we avoid allocating from the OS? if (arena == NULL) { _mi_os_free_huge_pages(p, hsize, &_mi_stats_main); return ENOMEM; } arena->block_count = bcount; arena->field_count = fields; arena->start = (uint8_t*)p; arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1) arena->is_large = true; arena->is_zero_init = true; arena->is_committed = true; arena->search_idx = 0; arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap arena->blocks_committed = NULL; // the bitmaps are already zero initialized due to os_alloc // just claim leftover blocks if needed ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount; mi_assert_internal(post >= 0); if (post > 0) { // don't use leftover bits at the end mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post); mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL); } mi_arena_add(arena); return 0; } // reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected) int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept { if (pages == 0) return 0; // pages per numa node size_t numa_count = (numa_nodes > 0 ? numa_nodes : _mi_os_numa_node_count()); if (numa_count <= 0) numa_count = 1; const size_t pages_per = pages / numa_count; const size_t pages_mod = pages % numa_count; const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50); // reserve evenly among numa nodes for (size_t numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) { size_t node_pages = pages_per; // can be 0 if (numa_node < pages_mod) node_pages++; int err = mi_reserve_huge_os_pages_at(node_pages, (int)numa_node, timeout_per); if (err) return err; if (pages < node_pages) { pages = 0; } else { pages -= node_pages; } } return 0; } int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept { UNUSED(max_secs); _mi_warning_message("mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\n"); if (pages_reserved != NULL) *pages_reserved = 0; int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0)); if (err==0 && pages_reserved!=NULL) *pages_reserved = pages; return err; } ================================================ FILE: runtime/src/mimalloc/c/bitmap.inc.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2019, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------- This file is meant to be included in other files for efficiency. It implements a bitmap that can set/reset sequences of bits atomically and is used to concurrently claim memory ranges. A bitmap is an array of fields where each field is a machine word (`uintptr_t`) A current limitation is that the bit sequences cannot cross fields and that the sequence must be smaller or equal to the bits in a field. ---------------------------------------------------------------------------- */ #pragma once #ifndef MI_BITMAP_C #define MI_BITMAP_C #include "mimalloc.h" #include "mimalloc-internal.h" /* ----------------------------------------------------------- Bitmap definition ----------------------------------------------------------- */ #define MI_BITMAP_FIELD_BITS (8*MI_INTPTR_SIZE) #define MI_BITMAP_FIELD_FULL (~((uintptr_t)0)) // all bits set // An atomic bitmap of `uintptr_t` fields typedef _Atomic(uintptr_t) mi_bitmap_field_t; typedef mi_bitmap_field_t* mi_bitmap_t; // A bitmap index is the index of the bit in a bitmap. typedef size_t mi_bitmap_index_t; // Create a bit index. static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) { mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS); return (idx*MI_BITMAP_FIELD_BITS) + bitidx; } // Get the field index from a bit index. static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) { return (bitmap_idx / MI_BITMAP_FIELD_BITS); } // Get the bit index in a bitmap field static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) { return (bitmap_idx % MI_BITMAP_FIELD_BITS); } // Get the full bit index static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) { return bitmap_idx; } // The bit mask for a given number of blocks at a specified bit index. static inline uintptr_t mi_bitmap_mask_(size_t count, size_t bitidx) { mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS); if (count == MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL; return ((((uintptr_t)1 << count) - 1) << bitidx); } /* ----------------------------------------------------------- Use bit scan forward/reverse to quickly find the first zero bit if it is available ----------------------------------------------------------- */ #if defined(_MSC_VER) #define MI_HAVE_BITSCAN #include #ifndef MI_64 #if MI_INTPTR_SIZE==8 #define MI_64(f) f##64 #else #define MI_64(f) f #endif #endif static inline size_t mi_bsf(uintptr_t x) { if (x==0) return 8*MI_INTPTR_SIZE; DWORD idx; MI_64(_BitScanForward)(&idx, x); return idx; } static inline size_t mi_bsr(uintptr_t x) { if (x==0) return 8*MI_INTPTR_SIZE; DWORD idx; MI_64(_BitScanReverse)(&idx, x); return idx; } #elif defined(__GNUC__) || defined(__clang__) #include // LONG_MAX #define MI_HAVE_BITSCAN #if (INTPTR_MAX == LONG_MAX) # define MI_L(x) x##l #else # define MI_L(x) x##ll #endif static inline size_t mi_bsf(uintptr_t x) { return (x==0 ? 8*MI_INTPTR_SIZE : MI_L(__builtin_ctz)(x)); } static inline size_t mi_bsr(uintptr_t x) { return (x==0 ? 8*MI_INTPTR_SIZE : (8*MI_INTPTR_SIZE - 1) - MI_L(__builtin_clz)(x)); } #endif /* ----------------------------------------------------------- Claim a bit sequence atomically ----------------------------------------------------------- */ // Try to atomically claim a sequence of `count` bits at in `idx` // in the bitmap field. Returns `true` on success. static inline bool mi_bitmap_try_claim_field(mi_bitmap_t bitmap, size_t bitmap_fields, const size_t count, mi_bitmap_index_t bitmap_idx) { const size_t idx = mi_bitmap_index_field(bitmap_idx); const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); const uintptr_t mask = mi_bitmap_mask_(count, bitidx); mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); mi_assert_internal(bitidx + count <= MI_BITMAP_FIELD_BITS); uintptr_t field = mi_atomic_load_relaxed(&bitmap[idx]); if ((field & mask) == 0) { // free? if (mi_atomic_cas_strong_acq_rel(&bitmap[idx], &field, (field|mask))) { // claimed! return true; } } return false; } // Try to atomically claim a sequence of `count` bits in a single // field at `idx` in `bitmap`. Returns `true` on success. static inline bool mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx) { mi_assert_internal(bitmap_idx != NULL); _Atomic(uintptr_t)* field = &bitmap[idx]; uintptr_t map = mi_atomic_load_relaxed(field); if (map==MI_BITMAP_FIELD_FULL) return false; // short cut // search for 0-bit sequence of length count const uintptr_t mask = mi_bitmap_mask_(count, 0); const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count; #ifdef MI_HAVE_BITSCAN size_t bitidx = mi_bsf(~map); // quickly find the first zero bit if possible #else size_t bitidx = 0; // otherwise start at 0 #endif uintptr_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx // scan linearly for a free range of zero bits while (bitidx <= bitidx_max) { if ((map & m) == 0) { // are the mask bits free at bitidx? mi_assert_internal((m >> bitidx) == mask); // no overflow? const uintptr_t newmap = map | m; mi_assert_internal((newmap^map) >> bitidx == mask); if (!mi_atomic_cas_weak_acq_rel(field, &map, newmap)) { // TODO: use strong cas here? // no success, another thread claimed concurrently.. keep going (with updated `map`) continue; } else { // success, we claimed the bits! *bitmap_idx = mi_bitmap_index_create(idx, bitidx); return true; } } else { // on to the next bit range #ifdef MI_HAVE_BITSCAN const size_t shift = (count == 1 ? 1 : mi_bsr(map & m) - bitidx + 1); mi_assert_internal(shift > 0 && shift <= count); #else const size_t shift = 1; #endif bitidx += shift; m <<= shift; } } // no bits found return false; } // Find `count` bits of 0 and set them to 1 atomically; returns `true` on success. // For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never span fields. static inline bool mi_bitmap_try_find_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t* bitmap_idx) { for (size_t idx = 0; idx < bitmap_fields; idx++) { if (mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { return true; } } return false; } // Set `count` bits at `bitmap_idx` to 0 atomically // Returns `true` if all `count` bits were 1 previously. static inline bool mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { const size_t idx = mi_bitmap_index_field(bitmap_idx); const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); const uintptr_t mask = mi_bitmap_mask_(count, bitidx); mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); // mi_assert_internal((bitmap[idx] & mask) == mask); uintptr_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask); return ((prev & mask) == mask); } // Set `count` bits at `bitmap_idx` to 1 atomically // Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. static inline bool mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) { const size_t idx = mi_bitmap_index_field(bitmap_idx); const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); const uintptr_t mask = mi_bitmap_mask_(count, bitidx); mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0); uintptr_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask); if (any_zero != NULL) *any_zero = ((prev & mask) != mask); return ((prev & mask) == 0); } // Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one. static inline bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) { const size_t idx = mi_bitmap_index_field(bitmap_idx); const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); const uintptr_t mask = mi_bitmap_mask_(count, bitidx); mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); uintptr_t field = mi_atomic_load_relaxed(&bitmap[idx]); if (any_ones != NULL) *any_ones = ((field & mask) != 0); return ((field & mask) == mask); } static inline bool mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL); } static inline bool mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { bool any_ones; mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); return any_ones; } #endif ================================================ FILE: runtime/src/mimalloc/c/heap.c ================================================ /*---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // memset, memcpy #if defined(_MSC_VER) && (_MSC_VER < 1920) #pragma warning(disable:4204) // non-constant aggregate initializer #endif /* ----------------------------------------------------------- Helpers ----------------------------------------------------------- */ // return `true` if ok, `false` to break typedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2); // Visit all pages in a heap; returns `false` if break was called. static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void* arg1, void* arg2) { if (heap==NULL || heap->page_count==0) return 0; // visit all pages #if MI_DEBUG>1 size_t total = heap->page_count; #endif size_t count = 0; for (size_t i = 0; i <= MI_BIN_FULL; i++) { mi_page_queue_t* pq = &heap->pages[i]; mi_page_t* page = pq->first; while(page != NULL) { mi_page_t* next = page->next; // save next in case the page gets removed from the queue mi_assert_internal(mi_page_heap(page) == heap); count++; if (!fn(heap, pq, page, arg1, arg2)) return false; page = next; // and continue } } mi_assert_internal(count == total); return true; } #if MI_DEBUG>=2 static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { UNUSED(arg1); UNUSED(arg2); UNUSED(pq); mi_assert_internal(mi_page_heap(page) == heap); mi_segment_t* segment = _mi_page_segment(page); mi_assert_internal(segment->thread_id == heap->thread_id); mi_assert_expensive(_mi_page_is_valid(page)); return true; } #endif #if MI_DEBUG>=3 static bool mi_heap_is_valid(mi_heap_t* heap) { mi_assert_internal(heap!=NULL); mi_heap_visit_pages(heap, &mi_heap_page_is_valid, NULL, NULL); return true; } #endif /* ----------------------------------------------------------- "Collect" pages by migrating `local_free` and `thread_free` lists and freeing empty pages. This is done when a thread stops (and in that case abandons pages if there are still blocks alive) ----------------------------------------------------------- */ typedef enum mi_collect_e { MI_NORMAL, MI_FORCE, MI_ABANDON } mi_collect_t; static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) { UNUSED(arg2); UNUSED(heap); mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL)); mi_collect_t collect = *((mi_collect_t*)arg_collect); _mi_page_free_collect(page, collect >= MI_FORCE); if (mi_page_all_free(page)) { // no more used blocks, free the page. // note: this will free retired pages as well. _mi_page_free(page, pq, collect >= MI_FORCE); } else if (collect == MI_ABANDON) { // still used blocks but the thread is done; abandon the page _mi_page_abandon(page, pq); } return true; // don't break } static bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { UNUSED(arg1); UNUSED(arg2); UNUSED(heap); UNUSED(pq); _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); return true; // don't break } static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect) { if (!mi_heap_is_initialized(heap)) return; _mi_deferred_free(heap, collect >= MI_FORCE); // note: never reclaim on collect but leave it to threads that need storage to reclaim if ( #ifdef NDEBUG collect == MI_FORCE #else collect >= MI_FORCE #endif && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim) { // the main thread is abandoned (end-of-program), try to reclaim all abandoned segments. // if all memory is freed by now, all segments should be freed. _mi_abandoned_reclaim_all(heap, &heap->tld->segments); } // if abandoning, mark all pages to no longer add to delayed_free if (collect == MI_ABANDON) { mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, NULL, NULL); } // free thread delayed blocks. // (if abandoning, after this there are no more thread-delayed references into the pages.) _mi_heap_delayed_free(heap); // collect retired pages _mi_heap_collect_retired(heap, collect >= MI_FORCE); // collect all pages owned by this thread mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL); mi_assert_internal( collect != MI_ABANDON || mi_atomic_load_ptr_acquire(mi_block_t,&heap->thread_delayed_free) == NULL ); // collect segment caches if (collect >= MI_FORCE) { _mi_segment_thread_collect(&heap->tld->segments); } // collect regions on program-exit (or shared library unload) if (collect >= MI_FORCE && _mi_is_main_thread() && mi_heap_is_backing(heap)) { _mi_mem_collect(&heap->tld->os); } } void _mi_heap_collect_abandon(mi_heap_t* heap) { mi_heap_collect_ex(heap, MI_ABANDON); } void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept { mi_heap_collect_ex(heap, (force ? MI_FORCE : MI_NORMAL)); } void mi_collect(bool force) mi_attr_noexcept { mi_heap_collect(mi_get_default_heap(), force); } /* ----------------------------------------------------------- Heap new ----------------------------------------------------------- */ mi_heap_t* mi_heap_get_default(void) { mi_thread_init(); return mi_get_default_heap(); } mi_heap_t* mi_heap_get_backing(void) { mi_heap_t* heap = mi_heap_get_default(); mi_assert_internal(heap!=NULL); mi_heap_t* bheap = heap->tld->heap_backing; mi_assert_internal(bheap!=NULL); mi_assert_internal(bheap->thread_id == _mi_thread_id()); return bheap; } mi_heap_t* mi_heap_new(void) { mi_heap_t* bheap = mi_heap_get_backing(); mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode? if (heap==NULL) return NULL; memcpy(heap, &_mi_heap_empty, sizeof(mi_heap_t)); heap->tld = bheap->tld; heap->thread_id = _mi_thread_id(); _mi_random_split(&bheap->random, &heap->random); heap->cookie = _mi_heap_random_next(heap) | 1; heap->keys[0] = _mi_heap_random_next(heap); heap->keys[1] = _mi_heap_random_next(heap); heap->no_reclaim = true; // don't reclaim abandoned pages or otherwise destroy is unsafe // push on the thread local heaps list heap->next = heap->tld->heaps; heap->tld->heaps = heap; return heap; } uintptr_t _mi_heap_random_next(mi_heap_t* heap) { return _mi_random_next(&heap->random); } // zero out the page queues static void mi_heap_reset_pages(mi_heap_t* heap) { mi_assert_internal(mi_heap_is_initialized(heap)); // TODO: copy full empty heap instead? memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct)); #ifdef MI_MEDIUM_DIRECT memset(&heap->pages_free_medium, 0, sizeof(heap->pages_free_medium)); #endif memcpy(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages)); heap->thread_delayed_free = NULL; heap->page_count = 0; } // called from `mi_heap_destroy` and `mi_heap_delete` to free the internal heap resources. static void mi_heap_free(mi_heap_t* heap) { mi_assert(heap != NULL); mi_assert_internal(mi_heap_is_initialized(heap)); if (mi_heap_is_backing(heap)) return; // dont free the backing heap // reset default if (mi_heap_is_default(heap)) { _mi_heap_set_default_direct(heap->tld->heap_backing); } // remove ourselves from the thread local heaps list // linear search but we expect the number of heaps to be relatively small mi_heap_t* prev = NULL; mi_heap_t* curr = heap->tld->heaps; while (curr != heap && curr != NULL) { prev = curr; curr = curr->next; } mi_assert_internal(curr == heap); if (curr == heap) { if (prev != NULL) { prev->next = heap->next; } else { heap->tld->heaps = heap->next; } } mi_assert_internal(heap->tld->heaps != NULL); // and free the used memory mi_free(heap); } /* ----------------------------------------------------------- Heap destroy ----------------------------------------------------------- */ static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { UNUSED(arg1); UNUSED(arg2); UNUSED(heap); UNUSED(pq); // ensure no more thread_delayed_free will be added _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); // stats const size_t bsize = mi_page_block_size(page); if (bsize > MI_LARGE_OBJ_SIZE_MAX) { if (bsize > MI_HUGE_OBJ_SIZE_MAX) { _mi_stat_decrease(&heap->tld->stats.giant, bsize); } else { _mi_stat_decrease(&heap->tld->stats.huge, bsize); } } #if (MI_STAT>1) _mi_page_free_collect(page, false); // update used count const size_t inuse = page->used; if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], inuse); } mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks... #endif /// pretend it is all free now mi_assert_internal(mi_page_thread_free(page) == NULL); page->used = 0; // and free the page // mi_page_free(page,false); page->next = NULL; page->prev = NULL; _mi_segment_page_free(page,false /* no force? */, &heap->tld->segments); return true; // keep going } void _mi_heap_destroy_pages(mi_heap_t* heap) { mi_heap_visit_pages(heap, &_mi_heap_page_destroy, NULL, NULL); mi_heap_reset_pages(heap); } void mi_heap_destroy(mi_heap_t* heap) { mi_assert(heap != NULL); mi_assert(mi_heap_is_initialized(heap)); mi_assert(heap->no_reclaim); mi_assert_expensive(mi_heap_is_valid(heap)); if (!mi_heap_is_initialized(heap)) return; if (!heap->no_reclaim) { // don't free in case it may contain reclaimed pages mi_heap_delete(heap); } else { // free all pages _mi_heap_destroy_pages(heap); mi_heap_free(heap); } } /* ----------------------------------------------------------- Safe Heap delete ----------------------------------------------------------- */ // Tranfer the pages from one heap to the other static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) { mi_assert_internal(heap!=NULL); if (from==NULL || from->page_count == 0) return; // reduce the size of the delayed frees _mi_heap_delayed_free(from); // transfer all pages by appending the queues; this will set a new heap field // so threads may do delayed frees in either heap for a while. // note: appending waits for each page to not be in the `MI_DELAYED_FREEING` state // so after this only the new heap will get delayed frees for (size_t i = 0; i <= MI_BIN_FULL; i++) { mi_page_queue_t* pq = &heap->pages[i]; mi_page_queue_t* append = &from->pages[i]; size_t pcount = _mi_page_queue_append(heap, pq, append); heap->page_count += pcount; from->page_count -= pcount; } mi_assert_internal(from->page_count == 0); // and do outstanding delayed frees in the `from` heap // note: be careful here as the `heap` field in all those pages no longer point to `from`, // turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a // the regular `_mi_free_delayed_block` which is safe. _mi_heap_delayed_free(from); mi_assert_internal(from->thread_delayed_free == NULL); // and reset the `from` heap mi_heap_reset_pages(from); } // Safe delete a heap without freeing any still allocated blocks in that heap. void mi_heap_delete(mi_heap_t* heap) { mi_assert(heap != NULL); mi_assert(mi_heap_is_initialized(heap)); mi_assert_expensive(mi_heap_is_valid(heap)); if (!mi_heap_is_initialized(heap)) return; if (!mi_heap_is_backing(heap)) { // tranfer still used pages to the backing heap mi_heap_absorb(heap->tld->heap_backing, heap); } else { // the backing heap abandons its pages _mi_heap_collect_abandon(heap); } mi_assert_internal(heap->page_count==0); mi_heap_free(heap); } mi_heap_t* mi_heap_set_default(mi_heap_t* heap) { mi_assert(mi_heap_is_initialized(heap)); if (!mi_heap_is_initialized(heap)) return NULL; mi_assert_expensive(mi_heap_is_valid(heap)); mi_heap_t* old = mi_get_default_heap(); _mi_heap_set_default_direct(heap); return old; } /* ----------------------------------------------------------- Analysis ----------------------------------------------------------- */ // static since it is not thread safe to access heaps from other threads. static mi_heap_t* mi_heap_of_block(const void* p) { if (p == NULL) return NULL; mi_segment_t* segment = _mi_ptr_segment(p); bool valid = (_mi_ptr_cookie(segment) == segment->cookie); mi_assert_internal(valid); if (mi_unlikely(!valid)) return NULL; return mi_page_heap(_mi_segment_page_of(segment,p)); } bool mi_heap_contains_block(mi_heap_t* heap, const void* p) { mi_assert(heap != NULL); if (!mi_heap_is_initialized(heap)) return false; return (heap == mi_heap_of_block(p)); } static bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) { UNUSED(heap); UNUSED(pq); bool* found = (bool*)vfound; mi_segment_t* segment = _mi_page_segment(page); void* start = _mi_page_start(segment, page, NULL); void* end = (uint8_t*)start + (page->capacity * mi_page_block_size(page)); *found = (p >= start && p < end); return (!*found); // continue if not found } bool mi_heap_check_owned(mi_heap_t* heap, const void* p) { mi_assert(heap != NULL); if (!mi_heap_is_initialized(heap)) return false; if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers bool found = false; mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found); return found; } bool mi_check_owned(const void* p) { return mi_heap_check_owned(mi_get_default_heap(), p); } /* ----------------------------------------------------------- Visit all heap blocks and areas Todo: enable visiting abandoned pages, and enable visiting all blocks of all heaps across threads ----------------------------------------------------------- */ // Separate struct to keep `mi_page_t` out of the public interface typedef struct mi_heap_area_ex_s { mi_heap_area_t area; mi_page_t* page; } mi_heap_area_ex_t; static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_visit_fun* visitor, void* arg) { mi_assert(xarea != NULL); if (xarea==NULL) return true; const mi_heap_area_t* area = &xarea->area; mi_page_t* page = xarea->page; mi_assert(page != NULL); if (page == NULL) return true; _mi_page_free_collect(page,true); mi_assert_internal(page->local_free == NULL); if (page->used == 0) return true; const size_t bsize = mi_page_block_size(page); size_t psize; uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize); if (page->capacity == 1) { // optimize page with one block mi_assert_internal(page->used == 1 && page->free == NULL); return visitor(mi_page_heap(page), area, pstart, bsize, arg); } // create a bitmap of free blocks. #define MI_MAX_BLOCKS (MI_SMALL_PAGE_SIZE / sizeof(void*)) uintptr_t free_map[MI_MAX_BLOCKS / sizeof(uintptr_t)]; memset(free_map, 0, sizeof(free_map)); size_t free_count = 0; for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { free_count++; mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize)); size_t offset = (uint8_t*)block - pstart; mi_assert_internal(offset % bsize == 0); size_t blockidx = offset / bsize; // Todo: avoid division? mi_assert_internal( blockidx < MI_MAX_BLOCKS); size_t bitidx = (blockidx / sizeof(uintptr_t)); size_t bit = blockidx - (bitidx * sizeof(uintptr_t)); free_map[bitidx] |= ((uintptr_t)1 << bit); } mi_assert_internal(page->capacity == (free_count + page->used)); // walk through all blocks skipping the free ones size_t used_count = 0; for (size_t i = 0; i < page->capacity; i++) { size_t bitidx = (i / sizeof(uintptr_t)); size_t bit = i - (bitidx * sizeof(uintptr_t)); uintptr_t m = free_map[bitidx]; if (bit == 0 && m == UINTPTR_MAX) { i += (sizeof(uintptr_t) - 1); // skip a run of free blocks } else if ((m & ((uintptr_t)1 << bit)) == 0) { used_count++; uint8_t* block = pstart + (i * bsize); if (!visitor(mi_page_heap(page), area, block, bsize, arg)) return false; } } mi_assert_internal(page->used == used_count); return true; } typedef bool (mi_heap_area_visit_fun)(const mi_heap_t* heap, const mi_heap_area_ex_t* area, void* arg); static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) { UNUSED(heap); UNUSED(pq); mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun; mi_heap_area_ex_t xarea; const size_t bsize = mi_page_block_size(page); xarea.page = page; xarea.area.reserved = page->reserved * bsize; xarea.area.committed = page->capacity * bsize; xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL); xarea.area.used = page->used; xarea.area.block_size = bsize; return fun(heap, &xarea, arg); } // Visit all heap pages as areas static bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) { if (visitor == NULL) return false; return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, (void*)(visitor), arg); // note: function pointer to void* :-{ } // Just to pass arguments typedef struct mi_visit_blocks_args_s { bool visit_blocks; mi_block_visit_fun* visitor; void* arg; } mi_visit_blocks_args_t; static bool mi_heap_area_visitor(const mi_heap_t* heap, const mi_heap_area_ex_t* xarea, void* arg) { mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg; if (!args->visitor(heap, &xarea->area, NULL, xarea->area.block_size, args->arg)) return false; if (args->visit_blocks) { return mi_heap_area_visit_blocks(xarea, args->visitor, args->arg); } else { return true; } } // Visit all blocks in a heap bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) { mi_visit_blocks_args_t args = { visit_blocks, visitor, arg }; return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args); } ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc-atomic.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018,2020 Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // Copyright 2019-2020 JetBrains s.r.o. #pragma once #ifndef MIMALLOC_ATOMIC_H #define MIMALLOC_ATOMIC_H // -------------------------------------------------------------------------------------------- // Atomics // We need to be portable between C, C++, and MSVC. // We base the primitives on the C/C++ atomics and create a mimimal wrapper for MSVC in C compilation mode. // This is why we try to use only `uintptr_t` and `*` as atomic types. // To gain better insight in the range of used atomics, we use explicitly named memory order operations // instead of passing the memory order as a parameter. // ----------------------------------------------------------------------------------------------- #if defined(__cplusplus) // Use C++ atomics #include #define _Atomic(tp) std::atomic #define mi_atomic(name) std::atomic_##name #define mi_memory_order(name) std::memory_order_##name #elif defined(_MSC_VER) // Use MSVC C wrapper for C11 atomics #define _Atomic(tp) tp #define ATOMIC_VAR_INIT(x) x #define mi_atomic(name) mi_atomic_##name #define mi_memory_order(name) mi_memory_order_##name #else // Use C11 atomics #include #define mi_atomic(name) atomic_##name #define mi_memory_order(name) memory_order_##name #endif // Various defines for all used memory orders in mimalloc #define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail) \ mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail) #define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail) \ mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail) #define mi_atomic_load_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) #define mi_atomic_load_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) #define mi_atomic_store_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) #define mi_atomic_store_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) #define mi_atomic_exchange_release(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(release)) #define mi_atomic_exchange_acq_rel(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel)) #define mi_atomic_cas_weak_release(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) #define mi_atomic_cas_weak_acq_rel(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) #define mi_atomic_cas_strong_release(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed)) #define mi_atomic_cas_strong_acq_rel(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire)) #define mi_atomic_add_relaxed(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed)) #define mi_atomic_sub_relaxed(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed)) #define mi_atomic_add_acq_rel(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel)) #define mi_atomic_sub_acq_rel(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel)) #define mi_atomic_and_acq_rel(p,x) mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel)) #define mi_atomic_or_acq_rel(p,x) mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel)) #define mi_atomic_increment_relaxed(p) mi_atomic_add_relaxed(p,(uintptr_t)1) #define mi_atomic_decrement_relaxed(p) mi_atomic_sub_relaxed(p,(uintptr_t)1) #define mi_atomic_increment_acq_rel(p) mi_atomic_add_acq_rel(p,(uintptr_t)1) #define mi_atomic_decrement_acq_rel(p) mi_atomic_sub_acq_rel(p,(uintptr_t)1) static inline void mi_atomic_yield(void); static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add); static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub); #if defined(__cplusplus) || !defined(_MSC_VER) // In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value) // We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well #define mi_atomic_load_ptr_acquire(tp,p) mi_atomic_load_acquire(p) #define mi_atomic_load_ptr_relaxed(tp,p) mi_atomic_load_relaxed(p) // In C++ we need to add casts to help resolve templates if NULL is passed #if defined(__cplusplus) #define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,(tp*)x) #define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,(tp*)x) #define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,(tp*)des) #define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des) #define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,(tp*)des) #define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,(tp*)x) #define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,(tp*)x) #else #define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,x) #define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,x) #define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,des) #define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,des) #define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,des) #define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,x) #define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,x) #endif // These are used by the statistics static inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) { return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed)); } static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) { int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p); while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, ¤t, x)) { /* nothing */ }; } // Used by timers #define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) #define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) #define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) #define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) #elif defined(_MSC_VER) // MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics. #define WIN32_LEAN_AND_MEAN #include #include #ifdef _WIN64 typedef LONG64 msc_intptr_t; #define MI_64(f) f##64 #else typedef LONG msc_intptr_t; #define MI_64(f) f #endif typedef enum mi_memory_order_e { mi_memory_order_relaxed, mi_memory_order_consume, mi_memory_order_acquire, mi_memory_order_release, mi_memory_order_acq_rel, mi_memory_order_seq_cst } mi_memory_order; static inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) { (void)(mo); return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add); } static inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) { (void)(mo); return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub)); } static inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { (void)(mo); return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x); } static inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { (void)(mo); return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x); } static inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { (void)(mo1); (void)(mo2); uintptr_t read = (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected)); if (read == *expected) { return true; } else { *expected = read; return false; } } static inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) { return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2); } static inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) { (void)(mo); return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange); } static inline void mi_atomic_thread_fence(mi_memory_order mo) { (void)(mo); _Atomic(uintptr_t)x = 0; mi_atomic_exchange_explicit(&x, 1, mo); } static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) { (void)(mo); #if defined(_M_IX86) || defined(_M_X64) return *p; #else uintptr_t x = *p; if (mo > mi_memory_order_relaxed) { while (!mi_atomic_compare_exchange_weak_explicit(p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ }; } return x; #endif } static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) { (void)(mo); #if defined(_M_IX86) || defined(_M_X64) *p = x; #else mi_atomic_exchange_explicit(p, x, mo); #endif } static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) { (void)(mo); #if defined(_M_X64) return *p; #else int64_t old = *p; int64_t x = old; while ((old = InterlockedCompareExchange64(p, x, old)) != x) { x = old; } return x; #endif } static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) { (void)(mo); #if defined(x_M_IX86) || defined(_M_X64) *p = x; #else InterlockedExchange64(p, x); #endif } // These are used by the statistics static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) { #ifdef _WIN64 return (int64_t)mi_atomic_addi((int64_t*)p, add); #else int64_t current; int64_t sum; do { current = *p; sum = current + add; } while (_InterlockedCompareExchange64(p, sum, current) != current); return current; #endif } static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) { int64_t current; do { current = *p; } while (current < x && _InterlockedCompareExchange64(p, x, current) != current); } // The pointer macros cast to `uintptr_t`. #define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p)) #define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p)) #define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) #define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x)) #define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des) #define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x) #define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x) #define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire)) #define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed)) #define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release)) #define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed)) #endif // Atomically add a signed value; returns the previous value. static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) { return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add); } // Atomically subtract a signed value; returns the previous value. static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) { return (intptr_t)mi_atomic_addi(p, -sub); } // Yield #if defined(__cplusplus) #include static inline void mi_atomic_yield(void) { std::this_thread::yield(); } #elif defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include static inline void mi_atomic_yield(void) { YieldProcessor(); } #elif (defined(__GNUC__) || defined(__clang__)) && \ (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)) #if defined(__x86_64__) || defined(__i386__) static inline void mi_atomic_yield(void) { __asm__ volatile ("pause" ::: "memory"); } #elif defined(__arm__) || defined(__aarch64__) #if KONAN_MI_MALLOC #if defined(__arm__) #include static inline void mi_atomic_yield(void) { sched_yield(); } #else static inline void mi_atomic_yield(void) { asm volatile("yield"); } #endif #else // KONAN_MI_MALLOC static inline void mi_atomic_yield(void) { asm volatile("yield"); } #endif // KONAN_MI_MALLOC #endif #elif defined(__wasi__) #include static inline void mi_atomic_yield(void) { sched_yield(); } #else #include static inline void mi_atomic_yield(void) { sleep(0); } #endif #endif // __MIMALLOC_ATOMIC_H ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc-internal.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // Copyright 2019-2020 JetBrains s.r.o. #pragma once #ifndef MIMALLOC_INTERNAL_H #define MIMALLOC_INTERNAL_H #include "mimalloc-types.h" #if (MI_DEBUG>0) #define mi_trace_message(...) _mi_trace_message(__VA_ARGS__) #else #define mi_trace_message(...) #endif #define MI_CACHE_LINE 64 #if defined(_MSC_VER) #pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths) #define mi_decl_noinline __declspec(noinline) #define mi_decl_thread __declspec(thread) #define mi_decl_cache_align __declspec(align(MI_CACHE_LINE)) #elif (defined(__GNUC__) && (__GNUC__>=3)) // includes clang and icc #define mi_decl_noinline __attribute__((noinline)) #define mi_decl_thread __thread #define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE))) #else #define mi_decl_noinline #define mi_decl_thread __thread // hope for the best :-) #define mi_decl_cache_align #endif // "options.c" void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message); void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...); void _mi_warning_message(const char* fmt, ...); void _mi_verbose_message(const char* fmt, ...); void _mi_trace_message(const char* fmt, ...); void _mi_options_init(void); void _mi_error_message(int err, const char* fmt, ...); // random.c void _mi_random_init(mi_random_ctx_t* ctx); void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx); uintptr_t _mi_random_next(mi_random_ctx_t* ctx); uintptr_t _mi_heap_random_next(mi_heap_t* heap); uintptr_t _os_random_weak(uintptr_t extra_seed); static inline uintptr_t _mi_random_shuffle(uintptr_t x); // init.c extern mi_stats_t _mi_stats_main; extern const mi_page_t _mi_page_empty; bool _mi_is_main_thread(void); bool _mi_preloading(); // true while the C runtime is not ready // os.c size_t _mi_os_page_size(void); void _mi_os_init(void); // called from process init void* _mi_os_alloc(size_t size, mi_stats_t* stats); // to allocate thread local data void _mi_os_free(void* p, size_t size, mi_stats_t* stats); // to free thread local data size_t _mi_os_good_alloc_size(size_t size); // memory.c void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* id, mi_os_tld_t* tld); void _mi_mem_free(void* p, size_t size, size_t id, bool fully_committed, bool any_reset, mi_os_tld_t* tld); bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld); bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld); bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld); bool _mi_mem_protect(void* addr, size_t size); bool _mi_mem_unprotect(void* addr, size_t size); void _mi_mem_collect(mi_os_tld_t* tld); // "segment.c" mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_wsize, mi_segments_tld_t* tld, mi_os_tld_t* os_tld); void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld); void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld); uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size); // page start for any page void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); void _mi_segment_thread_collect(mi_segments_tld_t* tld); void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld); void _mi_abandoned_await_readers(void); // "page.c" void* _mi_malloc_generic(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc; void _mi_page_retire(mi_page_t* page); // free the page if there are no other pages with many free blocks void _mi_page_unfull(mi_page_t* page); void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread... void _mi_heap_delayed_free(mi_heap_t* heap); void _mi_heap_collect_retired(mi_heap_t* heap, bool force); void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append); void _mi_deferred_free(mi_heap_t* heap, bool force); void _mi_page_free_collect(mi_page_t* page,bool force); void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments size_t _mi_bin_size(uint8_t bin); // for stats uint8_t _mi_bin(size_t size); // for stats uint8_t _mi_bsr(uintptr_t x); // bit-scan-right, used on BSD in "os.c" // "heap.c" void _mi_heap_destroy_pages(mi_heap_t* heap); void _mi_heap_collect_abandon(mi_heap_t* heap); void _mi_heap_set_default_direct(mi_heap_t* heap); // "stats.c" void _mi_stats_done(mi_stats_t* stats); mi_msecs_t _mi_clock_now(void); mi_msecs_t _mi_clock_end(mi_msecs_t start); mi_msecs_t _mi_clock_start(void); // "alloc.c" void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept; // called from `_mi_malloc_generic` void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero); void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero); mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); bool _mi_free_delayed_block(mi_block_t* block); void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size); #if MI_DEBUG>1 bool _mi_page_is_valid(mi_page_t* page); #endif // ------------------------------------------------------ // Branches // ------------------------------------------------------ #if defined(__GNUC__) || defined(__clang__) #define mi_unlikely(x) __builtin_expect((x),0) #define mi_likely(x) __builtin_expect((x),1) #else #define mi_unlikely(x) (x) #define mi_likely(x) (x) #endif #ifndef __has_builtin #define __has_builtin(x) 0 #endif /* ----------------------------------------------------------- Error codes passed to `_mi_fatal_error` All are recoverable but EFAULT is a serious error and aborts by default in secure mode. For portability define undefined error codes using common Unix codes: ----------------------------------------------------------- */ #include #ifndef EAGAIN // double free #define EAGAIN (11) #endif #ifndef ENOMEM // out of memory #define ENOMEM (12) #endif #ifndef EFAULT // corrupted free-list or meta-data #define EFAULT (14) #endif #ifndef EINVAL // trying to free an invalid pointer #define EINVAL (22) #endif #ifndef EOVERFLOW // count*size overflow #define EOVERFLOW (75) #endif /* ----------------------------------------------------------- Inlined definitions ----------------------------------------------------------- */ #define UNUSED(x) (void)(x) #if (MI_DEBUG>0) #define UNUSED_RELEASE(x) #else #define UNUSED_RELEASE(x) UNUSED(x) #endif #define MI_INIT4(x) x(),x(),x(),x() #define MI_INIT8(x) MI_INIT4(x),MI_INIT4(x) #define MI_INIT16(x) MI_INIT8(x),MI_INIT8(x) #define MI_INIT32(x) MI_INIT16(x),MI_INIT16(x) #define MI_INIT64(x) MI_INIT32(x),MI_INIT32(x) #define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x) #define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x) // Is `x` a power of two? (0 is considered a power of two) static inline bool _mi_is_power_of_two(uintptr_t x) { return ((x & (x - 1)) == 0); } // Align upwards static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { mi_assert_internal(alignment != 0); uintptr_t mask = alignment - 1; if ((alignment & mask) == 0) { // power of two? return ((sz + mask) & ~mask); } else { return (((sz + mask)/alignment)*alignment); } } // Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`. static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) { mi_assert_internal(divider != 0); return (divider == 0 ? size : ((size + divider - 1) / divider)); } // Is memory zero initialized? static inline bool mi_mem_is_zero(void* p, size_t size) { for (size_t i = 0; i < size; i++) { if (((uint8_t*)p)[i] != 0) return false; } return true; } // Align a byte size to a size in _machine words_, // i.e. byte size == `wsize*sizeof(void*)`. static inline size_t _mi_wsize_from_size(size_t size) { mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t)); return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); } // Does malloc satisfy the alignment constraints already? static inline bool mi_malloc_satisfies_alignment(size_t alignment, size_t size) { return (alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2))); } // Overflow detecting multiply #if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5 #include // UINT_MAX, ULONG_MAX #if defined(_CLOCK_T) // for Illumos #undef _CLOCK_T #endif static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { // Changed order for armv7 (ULONG_MAX == UINT_MAX, but size_t = unsigned long) #if defined(__MACH__) && KONAN_MI_MALLOC #if (SIZE_MAX == ULONG_MAX) return __builtin_umull_overflow(count, size, total); #elif (SIZE_MAX == UINT_MAX) return __builtin_umul_overflow(count, size, total); #else return __builtin_umulll_overflow(count, size, total); #endif #else // KONAN_MI_MALLOC #if (SIZE_MAX == UINT_MAX) return __builtin_umul_overflow(count, size, total); #elif (SIZE_MAX == ULONG_MAX) return __builtin_umull_overflow(count, size, total); #else return __builtin_umulll_overflow(count, size, total); #endif #endif // KONAN_MI_MALLOC } #else /* __builtin_umul_overflow is unavailable */ static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX) *total = count * size; return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW) && size > 0 && (SIZE_MAX / size) < count); } #endif // Safe multiply `count*size` into `total`; return `true` on overflow. static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) { if (count==1) { // quick check for the case where count is one (common for C++ allocators) *total = size; return false; } else if (mi_unlikely(mi_mul_overflow(count, size, total))) { _mi_error_message(EOVERFLOW, "allocation request is too large (%zu * %zu bytes)\n", count, size); *total = SIZE_MAX; return true; } else return false; } /* ---------------------------------------------------------------------------------------- The thread local default heap: `_mi_get_default_heap` returns the thread local heap. On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a __thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures that the storage will always be available (allocated on the thread stacks). On some platforms though we cannot use that when overriding `malloc` since the underlying TLS implementation (or the loader) will call itself `malloc` on a first access and recurse. We try to circumvent this in an efficient way: - macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the loader itself calls `malloc` even before the modules are initialized. - OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS). - DragonFly: not yet working. ------------------------------------------------------------------------------------------- */ extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap extern bool _mi_process_is_initialized; mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap #if defined(MI_MALLOC_OVERRIDE) #if defined(__MACH__) // OSX #define MI_TLS_SLOT 89 // seems unused? // other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89) // see #elif defined(__OpenBSD__) // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16) // see #define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24) #elif defined(__DragonFly__) #warning "mimalloc is not working correctly on DragonFly yet." #define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) #endif #endif #if defined(MI_TLS_SLOT) static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept; // forward declaration #elif defined(MI_TLS_PTHREAD_SLOT_OFS) #include static inline mi_heap_t** mi_tls_pthread_heap_slot(void) { pthread_t self = pthread_self(); #if defined(__DragonFly__) if (self==NULL) { static mi_heap_t* pheap_main = _mi_heap_main_get(); return &pheap_main; } #endif return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS); } #elif defined(MI_TLS_PTHREAD) #include extern pthread_key_t _mi_heap_default_key; #else extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from #endif static inline mi_heap_t* mi_get_default_heap(void) { #if defined(MI_TLS_SLOT) mi_heap_t* heap = (mi_heap_t*)mi_tls_slot(MI_TLS_SLOT); return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); #elif defined(MI_TLS_PTHREAD_SLOT_OFS) mi_heap_t* heap = *mi_tls_pthread_heap_slot(); return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); #elif defined(MI_TLS_PTHREAD) mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key)); return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); #else #if defined(MI_TLS_RECURSE_GUARD) if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get(); #endif return _mi_heap_default; #endif } static inline bool mi_heap_is_default(const mi_heap_t* heap) { return (heap == mi_get_default_heap()); } static inline bool mi_heap_is_backing(const mi_heap_t* heap) { return (heap->tld->heap_backing == heap); } static inline bool mi_heap_is_initialized(mi_heap_t* heap) { mi_assert_internal(heap != NULL); return (heap != &_mi_heap_empty); } static inline uintptr_t _mi_ptr_cookie(const void* p) { extern mi_heap_t _mi_heap_main; mi_assert_internal(_mi_heap_main.cookie != 0); return ((uintptr_t)p ^ _mi_heap_main.cookie); } /* ----------------------------------------------------------- Pages ----------------------------------------------------------- */ static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) { mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE)); const size_t idx = _mi_wsize_from_size(size); mi_assert_internal(idx < MI_PAGES_DIRECT); return heap->pages_free_direct[idx]; } // Get the page belonging to a certain size class static inline mi_page_t* _mi_get_free_small_page(size_t size) { return _mi_heap_get_free_small_page(mi_get_default_heap(), size); } // Segment that contains the pointer static inline mi_segment_t* _mi_ptr_segment(const void* p) { // mi_assert_internal(p != NULL); return (mi_segment_t*)((uintptr_t)p & ~MI_SEGMENT_MASK); } // Segment belonging to a page static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) { mi_segment_t* segment = _mi_ptr_segment(page); mi_assert_internal(segment == NULL || page == &segment->pages[page->segment_idx]); return segment; } // used internally static inline uintptr_t _mi_segment_page_idx_of(const mi_segment_t* segment, const void* p) { // if (segment->page_size > MI_SEGMENT_SIZE) return &segment->pages[0]; // huge pages ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment; mi_assert_internal(diff >= 0 && (size_t)diff < MI_SEGMENT_SIZE); uintptr_t idx = (uintptr_t)diff >> segment->page_shift; mi_assert_internal(idx < segment->capacity); mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM || idx == 0); return idx; } // Get the page containing the pointer static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) { uintptr_t idx = _mi_segment_page_idx_of(segment, p); return &((mi_segment_t*)segment)->pages[idx]; } // Quick page start for initialized pages static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { const size_t bsize = page->xblock_size; mi_assert_internal(bsize > 0 && (bsize%sizeof(void*)) == 0); return _mi_segment_page_start(segment, page, bsize, page_size, NULL); } // Get the page containing the pointer static inline mi_page_t* _mi_ptr_page(void* p) { return _mi_segment_page_of(_mi_ptr_segment(p), p); } // Get the block size of a page (special cased for huge objects) static inline size_t mi_page_block_size(const mi_page_t* page) { const size_t bsize = page->xblock_size; mi_assert_internal(bsize > 0); if (mi_likely(bsize < MI_HUGE_BLOCK_SIZE)) { return bsize; } else { size_t psize; _mi_segment_page_start(_mi_page_segment(page), page, bsize, &psize, NULL); return psize; } } // Get the usable block size of a page without fixed padding. // This may still include internal padding due to alignment and rounding up size classes. static inline size_t mi_page_usable_block_size(const mi_page_t* page) { return mi_page_block_size(page) - MI_PADDING_SIZE; } // Thread free access static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) { return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3); } static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) { return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3); } // Heap access static inline mi_heap_t* mi_page_heap(const mi_page_t* page) { return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap)); } static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) { mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING); mi_atomic_store_release(&page->xheap,(uintptr_t)heap); } // Thread free flag helpers static inline mi_block_t* mi_tf_block(mi_thread_free_t tf) { return (mi_block_t*)(tf & ~0x03); } static inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) { return (mi_delayed_t)(tf & 0x03); } static inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) { return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed); } static inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) { return mi_tf_make(mi_tf_block(tf),delayed); } static inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) { return mi_tf_make(block, mi_tf_delayed(tf)); } // are all blocks in a page freed? // note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`. static inline bool mi_page_all_free(const mi_page_t* page) { mi_assert_internal(page != NULL); return (page->used == 0); } // are there any available blocks? static inline bool mi_page_has_any_available(const mi_page_t* page) { mi_assert_internal(page != NULL && page->reserved > 0); return (page->used < page->reserved || (mi_page_thread_free(page) != NULL)); } // are there immediately available blocks, i.e. blocks available on the free list. static inline bool mi_page_immediate_available(const mi_page_t* page) { mi_assert_internal(page != NULL); return (page->free != NULL); } // is more than 7/8th of a page in use? static inline bool mi_page_mostly_used(const mi_page_t* page) { if (page==NULL) return true; uint16_t frac = page->reserved / 8U; return (page->reserved - page->used <= frac); } static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) { return &((mi_heap_t*)heap)->pages[_mi_bin(size)]; } //----------------------------------------------------------- // Page flags //----------------------------------------------------------- static inline bool mi_page_is_in_full(const mi_page_t* page) { return page->flags.x.in_full; } static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) { page->flags.x.in_full = in_full; } static inline bool mi_page_has_aligned(const mi_page_t* page) { return page->flags.x.has_aligned; } static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) { page->flags.x.has_aligned = has_aligned; } /* ------------------------------------------------------------------- Encoding/Decoding the free list next pointers This is to protect against buffer overflow exploits where the free list is mutated. Many hardened allocators xor the next pointer `p` with a secret key `k1`, as `p^k1`. This prevents overwriting with known values but might be still too weak: if the attacker can guess the pointer `p` this can reveal `k1` (since `p^k1^p == k1`). Moreover, if multiple blocks can be read as well, the attacker can xor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot about the pointers (and subsequently `k1`). Instead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<> (MI_INTPTR_BITS - shift)))); } static inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) { shift %= MI_INTPTR_BITS; return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift)))); } static inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) { void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]); return (mi_unlikely(p==null) ? NULL : p); } static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) { uintptr_t x = (uintptr_t)(mi_unlikely(p==NULL) ? null : p); return mi_rotl(x ^ keys[1], keys[0]) + keys[0]; } static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) { #ifdef MI_ENCODE_FREELIST return (mi_block_t*)mi_ptr_decode(null, block->next, keys); #else UNUSED(keys); UNUSED(null); return (mi_block_t*)block->next; #endif } static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) { #ifdef MI_ENCODE_FREELIST block->next = mi_ptr_encode(null, next, keys); #else UNUSED(keys); UNUSED(null); block->next = (mi_encoded_t)next; #endif } static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) { #ifdef MI_ENCODE_FREELIST mi_block_t* next = mi_block_nextx(page,block,page->keys); // check for free list corruption: is `next` at least in the same page? // TODO: check if `next` is `page->block_size` aligned? if (mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next))) { _mi_error_message(EFAULT, "corrupted free list entry of size %zub at %p: value 0x%zx\n", mi_page_block_size(page), block, (uintptr_t)next); next = NULL; } return next; #else UNUSED(page); return mi_block_nextx(page,block,NULL); #endif } static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) { #ifdef MI_ENCODE_FREELIST mi_block_set_nextx(page,block,next, page->keys); #else UNUSED(page); mi_block_set_nextx(page,block,next,NULL); #endif } // ------------------------------------------------------------------- // Fast "random" shuffle // ------------------------------------------------------------------- static inline uintptr_t _mi_random_shuffle(uintptr_t x) { if (x==0) { x = 17; } // ensure we don't get stuck in generating zeros #if (MI_INTPTR_SIZE==8) // by Sebastiano Vigna, see: x ^= x >> 30; x *= 0xbf58476d1ce4e5b9UL; x ^= x >> 27; x *= 0x94d049bb133111ebUL; x ^= x >> 31; #elif (MI_INTPTR_SIZE==4) // by Chris Wellons, see: x ^= x >> 16; x *= 0x7feb352dUL; x ^= x >> 15; x *= 0x846ca68bUL; x ^= x >> 16; #endif return x; } // ------------------------------------------------------------------- // Optimize numa node access for the common case (= one node) // ------------------------------------------------------------------- int _mi_os_numa_node_get(mi_os_tld_t* tld); size_t _mi_os_numa_node_count_get(void); extern size_t _mi_numa_node_count; static inline int _mi_os_numa_node(mi_os_tld_t* tld) { if (mi_likely(_mi_numa_node_count == 1)) return 0; else return _mi_os_numa_node_get(tld); } static inline size_t _mi_os_numa_node_count(void) { if (mi_likely(_mi_numa_node_count>0)) return _mi_numa_node_count; else return _mi_os_numa_node_count_get(); } // ------------------------------------------------------------------- // Getting the thread id should be performant as it is called in the // fast path of `_mi_free` and we specialize for various platforms. // ------------------------------------------------------------------- #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { // Windows: works on Intel and ARM in both 32- and 64-bit return (uintptr_t)NtCurrentTeb(); } #elif defined(__GNUC__) && \ (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)) #if KONAN_MI_MALLOC #include pthread_t pthread_self(void); #endif // KONAN_MI_MALLOC // TLS register on x86 is in the FS or GS register, see: https://akkadia.org/drepper/tls.pdf static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept { void* res; const size_t ofs = (slot*sizeof(void*)); #if defined(__i386__) __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // 32-bit always uses GS #elif defined(__MACH__) && defined(__x86_64__) __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS #elif defined(__x86_64__) __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS #elif defined(__arm__) void** tcb; UNUSED(ofs); __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); res = tcb[slot]; #elif defined(__aarch64__) void** tcb; UNUSED(ofs); __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); res = tcb[slot]; #endif return res; } // setting is only used on macOSX for now static inline void mi_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { const size_t ofs = (slot*sizeof(void*)); #if defined(__i386__) __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS #elif defined(__MACH__) && defined(__x86_64__) __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOSX uses GS #elif defined(__x86_64__) __asm__("movq %1,%%fs:%1" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS #elif defined(__arm__) void** tcb; UNUSED(ofs); __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); tcb[slot] = value; #elif defined(__aarch64__) void** tcb; UNUSED(ofs); __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); tcb[slot] = value; #endif } static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { #if defined(__MACH__) && KONAN_MI_MALLOC #include #if TARGET_OS_EMBEDDED // iOS/tvOS/watchOS devices. return pthread_mach_thread_np(pthread_self()); #else // in all our targets, slot 0 is the pointer to the thread control block return (uintptr_t)mi_tls_slot(0); #endif #else // KONAN_MI_MALLOC // in all our targets, slot 0 is the pointer to the thread control block return (uintptr_t)mi_tls_slot(0); #endif // KONAN_MI_MALLOC } #else // otherwise use standard C static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { return (uintptr_t)&_mi_heap_default; } #endif #endif ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc-new-delete.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018,2019 Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #pragma once #ifndef MIMALLOC_NEW_DELETE_H #define MIMALLOC_NEW_DELETE_H // ---------------------------------------------------------------------------- // This header provides convenient overrides for the new and // delete operations in C++. // // This header should be included in only one source file! // // On Windows, or when linking dynamically with mimalloc, these // can be more performant than the standard new-delete operations. // See // --------------------------------------------------------------------------- #if defined(__cplusplus) #include #include void operator delete(void* p) noexcept { mi_free(p); }; void operator delete[](void* p) noexcept { mi_free(p); }; void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } #if (__cplusplus >= 201402L || _MSC_VER >= 1916) void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); }; void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); }; #endif #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } #endif #endif #endif // MIMALLOC_NEW_DELETE_H ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc-override.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018,2019 Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #pragma once #ifndef MIMALLOC_OVERRIDE_H #define MIMALLOC_OVERRIDE_H /* ---------------------------------------------------------------------------- This header can be used to statically redirect malloc/free and new/delete to the mimalloc variants. This can be useful if one can include this file on each source file in a project (but be careful when using external code to not accidentally mix pointers from different allocators). -----------------------------------------------------------------------------*/ #include // Standard C allocation #define malloc(n) mi_malloc(n) #define calloc(n,c) mi_calloc(n,c) #define realloc(p,n) mi_realloc(p,n) #define free(p) mi_free(p) #define strdup(s) mi_strdup(s) #define strndup(s) mi_strndup(s) #define realpath(f,n) mi_realpath(f,n) // Microsoft extensions #define _expand(p,n) mi_expand(p,n) #define _msize(p) mi_usable_size(p) #define _recalloc(p,n,c) mi_recalloc(p,n,c) #define _strdup(s) mi_strdup(s) #define _strndup(s) mi_strndup(s) #define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s)) #define _mbsdup(s) mi_mbsdup(s) #define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v) #define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v)) // Various Posix and Unix variants #define reallocf(p,n) mi_reallocf(p,n) #define malloc_size(p) mi_usable_size(p) #define malloc_usable_size(p) mi_usable_size(p) #define cfree(p) mi_free(p) #define valloc(n) mi_valloc(n) #define pvalloc(n) mi_pvalloc(n) #define reallocarray(p,s,n) mi_reallocarray(p,s,n) #define memalign(a,n) mi_memalign(a,n) #define aligned_alloc(a,n) mi_aligned_alloc(a,n) #define posix_memalign(p,a,n) mi_posix_memalign(p,a,n) #define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n) // Microsoft aligned variants #define _aligned_malloc(n,a) mi_malloc_aligned(n,a) #define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a) #define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a) #define _aligned_msize(p,a,o) mi_usable_size(p) #define _aligned_free(p) mi_free(p) #define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o) #define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o) #define _aligned_offset_recalloc(p,s,n,a,o) mi_recalloc_aligned_at(p,s,n,a,o) #endif // MIMALLOC_OVERRIDE_H ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc-types.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ // Copyright 2019-2020 JetBrains s.r.o. #pragma once #ifndef MIMALLOC_TYPES_H #define MIMALLOC_TYPES_H #include // ptrdiff_t #include // uintptr_t, uint16_t, etc #include // _Atomic #ifdef _MSC_VER #pragma warning(disable:4214) // bitfield is not int #endif // Minimal alignment necessary. On most platforms 16 bytes are needed // due to SSE registers for example. This must be at least `MI_INTPTR_SIZE` #ifndef MI_MAX_ALIGN_SIZE #define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t) #endif // ------------------------------------------------------ // Variants // ------------------------------------------------------ // Define NDEBUG in the release version to disable assertions. #if KONAN_MI_MALLOC #define NDEBUG #endif // KONAN_MI_MALLOC // Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance). // #define MI_STAT 1 // Define MI_SECURE to enable security mitigations // #define MI_SECURE 1 // guard page around metadata // #define MI_SECURE 2 // guard page around each mimalloc page // #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free) // #define MI_SECURE 4 // checks for double free. (may be more expensive) #if !defined(MI_SECURE) #define MI_SECURE 0 #endif // Define MI_DEBUG for debug mode // #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. // #define MI_DEBUG 2 // + internal assertion checks // #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON) #if !defined(MI_DEBUG) #if !defined(NDEBUG) || defined(_DEBUG) #define MI_DEBUG 2 #else #define MI_DEBUG 0 #endif #endif // Reserve extra padding at the end of each block to be more resilient against heap block overflows. // The padding can detect byte-precise buffer overflow on free. #if !defined(MI_PADDING) && (MI_DEBUG>=1) #define MI_PADDING 1 #endif // Encoded free lists allow detection of corrupted free lists // and can detect buffer overflows, modify after free, and double `free`s. #if (MI_SECURE>=3 || MI_DEBUG>=1 || MI_PADDING > 0) #define MI_ENCODE_FREELIST 1 #endif // ------------------------------------------------------ // Platform specific values // ------------------------------------------------------ // ------------------------------------------------------ // Size of a pointer. // We assume that `sizeof(void*)==sizeof(intptr_t)` // and it holds for all platforms we know of. // // However, the C standard only requires that: // p == (void*)((intptr_t)p)) // but we also need: // i == (intptr_t)((void*)i) // or otherwise one might define an intptr_t type that is larger than a pointer... // ------------------------------------------------------ #if INTPTR_MAX == 9223372036854775807LL # define MI_INTPTR_SHIFT (3) #elif INTPTR_MAX == 2147483647LL # define MI_INTPTR_SHIFT (2) #else #error platform must be 32 or 64 bits #endif #define MI_INTPTR_SIZE (1<= 655360) #error "define more bins" #endif // Used as a special value to encode block sizes in 32 bits. #define MI_HUGE_BLOCK_SIZE ((uint32_t)MI_HUGE_OBJ_SIZE_MAX) // The free lists use encoded next fields // (Only actually encodes when MI_ENCODED_FREELIST is defined.) typedef uintptr_t mi_encoded_t; // free lists contain blocks typedef struct mi_block_s { mi_encoded_t next; } mi_block_t; // The delayed flags are used for efficient multi-threaded free-ing typedef enum mi_delayed_e { MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list MI_NEVER_DELAYED_FREE = 3 // sticky, only resets on page reclaim } mi_delayed_t; // The `in_full` and `has_aligned` page flags are put in a union to efficiently // test if both are false (`full_aligned == 0`) in the `mi_free` routine. #if !MI_TSAN typedef union mi_page_flags_s { uint8_t full_aligned; struct { uint8_t in_full : 1; uint8_t has_aligned : 1; } x; } mi_page_flags_t; #else // under thread sanitizer, use a byte for each flag to suppress warning, issue #130 typedef union mi_page_flags_s { uint16_t full_aligned; struct { uint8_t in_full; uint8_t has_aligned; } x; } mi_page_flags_t; #endif // Thread free list. // We use the bottom 2 bits of the pointer for mi_delayed_t flags typedef uintptr_t mi_thread_free_t; // A page contains blocks of one specific size (`block_size`). // Each page has three list of free blocks: // `free` for blocks that can be allocated, // `local_free` for freed blocks that are not yet available to `mi_malloc` // `thread_free` for freed blocks by other threads // The `local_free` and `thread_free` lists are migrated to the `free` list // when it is exhausted. The separate `local_free` list is necessary to // implement a monotonic heartbeat. The `thread_free` list is needed for // avoiding atomic operations in the common case. // // // `used - |thread_free|` == actual blocks that are in use (alive) // `used - |thread_free| + |free| + |local_free| == capacity` // // We don't count `freed` (as |free|) but use `used` to reduce // the number of memory accesses in the `mi_page_all_free` function(s). // // Notes: // - Access is optimized for `mi_free` and `mi_page_alloc` (in `alloc.c`) // - Using `uint16_t` does not seem to slow things down // - The size is 8 words on 64-bit which helps the page index calculations // (and 10 words on 32-bit, and encoded free lists add 2 words. Sizes 10 // and 12 are still good for address calculation) // - To limit the structure size, the `xblock_size` is 32-bits only; for // blocks > MI_HUGE_BLOCK_SIZE the size is determined from the segment page size // - `thread_free` uses the bottom bits as a delayed-free flags to optimize // concurrent frees where only the first concurrent free adds to the owning // heap `thread_delayed_free` list (see `alloc.c:mi_free_block_mt`). // The invariant is that no-delayed-free is only set if there is // at least one block that will be added, or as already been added, to // the owning heap `thread_delayed_free` list. This guarantees that pages // will be freed correctly even if only other threads free blocks. typedef struct mi_page_s { // "owned" by the segment uint8_t segment_idx; // index in the segment `pages` array, `page == &segment->pages[page->segment_idx]` uint8_t segment_in_use:1; // `true` if the segment allocated this page uint8_t is_reset:1; // `true` if the page memory was reset uint8_t is_committed:1; // `true` if the page virtual memory is committed uint8_t is_zero_init:1; // `true` if the page was zero initialized // layout like this to optimize access in `mi_malloc` and `mi_free` uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear` uint16_t reserved; // number of blocks reserved in memory mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits) uint8_t is_zero:1; // `true` if the blocks in the free list are zero initialized uint8_t retire_expire:7; // expiration count for retired blocks mi_block_t* free; // list of available free blocks (`malloc` allocates from this list) #ifdef MI_ENCODE_FREELIST uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) #endif uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`) uint32_t xblock_size; // size available in each block (always `>0`) mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`) _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads _Atomic(uintptr_t) xheap; struct mi_page_s* next; // next page owned by this thread with the same `block_size` struct mi_page_s* prev; // previous page owned by this thread with the same `block_size` } mi_page_t; typedef enum mi_page_kind_e { MI_PAGE_SMALL, // small blocks go into 64kb pages inside a segment MI_PAGE_MEDIUM, // medium blocks go into 512kb pages inside a segment MI_PAGE_LARGE, // larger blocks go into a single page spanning a whole segment MI_PAGE_HUGE // huge blocks (>512kb) are put into a single page in a segment of the exact size (but still 2mb aligned) } mi_page_kind_t; // Segments are large allocated memory blocks (2mb on 64 bit) from // the OS. Inside segments we allocated fixed size _pages_ that // contain blocks. typedef struct mi_segment_s { // memory fields size_t memid; // id for the os-level memory manager bool mem_is_fixed; // `true` if we cannot decommit/reset/protect in this memory (i.e. when allocated using large OS pages) bool mem_is_committed; // `true` if the whole segment is eagerly committed // segment fields _Atomic(struct mi_segment_s*) abandoned_next; struct mi_segment_s* next; // must be the first segment field after abandoned_next -- see `segment.c:segment_init` struct mi_segment_s* prev; size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`) size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long) size_t used; // count of pages in use (`used <= capacity`) size_t capacity; // count of available pages (`#free + used`) size_t segment_size; // for huge pages this may be different from `MI_SEGMENT_SIZE` size_t segment_info_size;// space we are using from the first page for segment meta-data and possible guard pages. uintptr_t cookie; // verify addresses in secure mode: `_mi_ptr_cookie(segment) == segment->cookie` // layout like this to optimize access in `mi_free` size_t page_shift; // `1 << page_shift` == the page sizes == `page->block_size * page->reserved` (unless the first page, then `-segment_info_size`). _Atomic(uintptr_t) thread_id; // unique id of the thread owning this segment mi_page_kind_t page_kind; // kind of pages: small, large, or huge mi_page_t pages[1]; // up to `MI_SMALL_PAGES_PER_SEGMENT` pages } mi_segment_t; // ------------------------------------------------------ // Heaps // Provide first-class heaps to allocate from. // A heap just owns a set of pages for allocation and // can only be allocate/reallocate from the thread that created it. // Freeing blocks can be done from any thread though. // Per thread, the segments are shared among its heaps. // Per thread, there is always a default heap that is // used for allocation; it is initialized to statically // point to an empty heap to avoid initialization checks // in the fast path. // ------------------------------------------------------ // Thread local data typedef struct mi_tld_s mi_tld_t; // Pages of a certain block size are held in a queue. typedef struct mi_page_queue_s { mi_page_t* first; mi_page_t* last; size_t block_size; } mi_page_queue_t; #define MI_BIN_FULL (MI_BIN_HUGE+1) // Random context typedef struct mi_random_cxt_s { uint32_t input[16]; uint32_t output[16]; int output_available; } mi_random_ctx_t; // In debug mode there is a padding stucture at the end of the blocks to check for buffer overflows #if (MI_PADDING) typedef struct mi_padding_s { uint32_t canary; // encoded block value to check validity of the padding (in case of overflow) uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes) } mi_padding_t; #define MI_PADDING_SIZE (sizeof(mi_padding_t)) #define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE) #else #define MI_PADDING_SIZE 0 #define MI_PADDING_WSIZE 0 #endif #define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1) // A heap owns a set of pages. struct mi_heap_s { mi_tld_t* tld; mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size. mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin") _Atomic(mi_block_t*) thread_delayed_free; uintptr_t thread_id; // thread this heap belongs too uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`) uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list mi_random_ctx_t random; // random number context used for secure allocation size_t page_count; // total number of pages in the `pages` queues. size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues) size_t page_retired_max; // largest retired index into the `pages` array. mi_heap_t* next; // list of heaps per thread bool no_reclaim; // `true` if this heap should not reclaim abandoned pages }; // ------------------------------------------------------ // Debug // ------------------------------------------------------ #define MI_DEBUG_UNINIT (0xD0) #define MI_DEBUG_FREED (0xDF) #define MI_DEBUG_PADDING (0xDE) #if (MI_DEBUG) // use our own assertion to print without memory allocation void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func ); #define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__)) #else #define mi_assert(x) #endif #if (MI_DEBUG>1) #define mi_assert_internal mi_assert #else #define mi_assert_internal(x) #endif #if (MI_DEBUG>2) #define mi_assert_expensive mi_assert #else #define mi_assert_expensive(x) #endif // ------------------------------------------------------ // Statistics // ------------------------------------------------------ #ifndef MI_STAT #if (MI_DEBUG>0) #define MI_STAT 2 #else #define MI_STAT 0 #endif #endif typedef struct mi_stat_count_s { int64_t allocated; int64_t freed; int64_t peak; int64_t current; } mi_stat_count_t; typedef struct mi_stat_counter_s { int64_t total; int64_t count; } mi_stat_counter_t; typedef struct mi_stats_s { mi_stat_count_t segments; mi_stat_count_t pages; mi_stat_count_t reserved; mi_stat_count_t committed; mi_stat_count_t reset; mi_stat_count_t page_committed; mi_stat_count_t segments_abandoned; mi_stat_count_t pages_abandoned; mi_stat_count_t threads; mi_stat_count_t huge; mi_stat_count_t giant; mi_stat_count_t malloc; mi_stat_count_t segments_cache; mi_stat_counter_t pages_extended; mi_stat_counter_t mmap_calls; mi_stat_counter_t commit_calls; mi_stat_counter_t page_no_retire; mi_stat_counter_t searches; mi_stat_counter_t huge_count; mi_stat_counter_t giant_count; #if MI_STAT>1 mi_stat_count_t normal[MI_BIN_HUGE+1]; #endif } mi_stats_t; void _mi_stat_increase(mi_stat_count_t* stat, size_t amount); void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount); void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount); #if (MI_STAT) #define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount) #define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount) #define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount) #else #define mi_stat_increase(stat,amount) (void)0 #define mi_stat_decrease(stat,amount) (void)0 #define mi_stat_counter_increase(stat,amount) (void)0 #endif #define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount) #define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount) // ------------------------------------------------------ // Thread Local data // ------------------------------------------------------ typedef int64_t mi_msecs_t; // Queue of segments typedef struct mi_segment_queue_s { mi_segment_t* first; mi_segment_t* last; } mi_segment_queue_t; // OS thread local data typedef struct mi_os_tld_s { size_t region_idx; // start point for next allocation mi_stats_t* stats; // points to tld stats } mi_os_tld_t; // Segments thread local data typedef struct mi_segments_tld_s { mi_segment_queue_t small_free; // queue of segments with free small pages mi_segment_queue_t medium_free; // queue of segments with free medium pages mi_page_queue_t pages_reset; // queue of freed pages that can be reset size_t count; // current number of segments; size_t peak_count; // peak number of segments size_t current_size; // current size of all segments size_t peak_size; // peak size of all segments size_t cache_count; // number of segments in the cache size_t cache_size; // total size of all segments in the cache mi_segment_t* cache; // (small) cache of segments mi_stats_t* stats; // points to tld stats mi_os_tld_t* os; // points to os stats } mi_segments_tld_t; // Thread local data struct mi_tld_s { unsigned long long heartbeat; // monotonic heartbeat count bool recurse; // true if deferred was called; used to prevent infinite recursion. mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted) mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates) mi_segments_tld_t segments; // segment tld mi_os_tld_t os; // os tld mi_stats_t stats; // statistics }; #endif ================================================ FILE: runtime/src/mimalloc/c/include/mimalloc.h ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018-2020, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #pragma once #ifndef MIMALLOC_H #define MIMALLOC_H #define MI_MALLOC_VERSION 167 // major + 2 digits minor // ------------------------------------------------------ // Compiler specific attributes // ------------------------------------------------------ #ifdef __cplusplus #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 #define mi_attr_noexcept noexcept #else #define mi_attr_noexcept throw() #endif #else #define mi_attr_noexcept #endif #if defined(__cplusplus) && (__cplusplus >= 201703) #define mi_decl_nodiscard [[nodiscard]] #elif (__GNUC__ >= 4) || defined(__clang__) // includes clang, icc, and clang-cl #define mi_decl_nodiscard __attribute__((warn_unused_result)) #elif (_MSC_VER >= 1700) #define mi_decl_nodiscard _Check_return_ #else #define mi_decl_nodiscard #endif #if defined(_MSC_VER) || defined(__MINGW32__) #if !defined(MI_SHARED_LIB) #define mi_decl_export #elif defined(MI_SHARED_LIB_EXPORT) #define mi_decl_export __declspec(dllexport) #else #define mi_decl_export __declspec(dllimport) #endif #if defined(__MINGW32__) #define mi_decl_restrict #define mi_attr_malloc __attribute__((malloc)) #else #if (_MSC_VER >= 1900) && !defined(__EDG__) #define mi_decl_restrict __declspec(allocator) __declspec(restrict) #else #define mi_decl_restrict __declspec(restrict) #endif #define mi_attr_malloc #endif #define mi_cdecl __cdecl #define mi_attr_alloc_size(s) #define mi_attr_alloc_size2(s1,s2) #define mi_attr_alloc_align(p) #elif defined(__GNUC__) // includes clang and icc #define mi_cdecl // leads to warnings... __attribute__((cdecl)) #define mi_decl_export __attribute__((visibility("default"))) #define mi_decl_restrict #define mi_attr_malloc __attribute__((malloc)) #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5) #define mi_attr_alloc_size(s) #define mi_attr_alloc_size2(s1,s2) #define mi_attr_alloc_align(p) #elif defined(__INTEL_COMPILER) #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) #define mi_attr_alloc_align(p) #else #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) #define mi_attr_alloc_align(p) __attribute__((alloc_align(p))) #endif #else #define mi_cdecl #define mi_decl_export #define mi_decl_restrict #define mi_attr_malloc #define mi_attr_alloc_size(s) #define mi_attr_alloc_size2(s1,s2) #define mi_attr_alloc_align(p) #endif // ------------------------------------------------------ // Includes // ------------------------------------------------------ #include // size_t #include // bool #ifdef __cplusplus extern "C" { #endif // ------------------------------------------------------ // Standard malloc interface // ------------------------------------------------------ mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); mi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); mi_decl_export void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); mi_decl_export void mi_free(void* p) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; // ------------------------------------------------------ // Extended functionality // ------------------------------------------------------ #define MI_SMALL_WSIZE_MAX (128) #define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*)) mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); mi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); mi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; // ------------------------------------------------------ // Internals // ------------------------------------------------------ typedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg); mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept; typedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg); mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept; typedef void (mi_cdecl mi_error_fun)(int err, void* arg); mi_decl_export void mi_register_error(mi_error_fun* fun, void* arg); mi_decl_export void mi_collect(bool force) mi_attr_noexcept; mi_decl_export int mi_version(void) mi_attr_noexcept; mi_decl_export void mi_stats_reset(void) mi_attr_noexcept; mi_decl_export void mi_stats_merge(void) mi_attr_noexcept; mi_decl_export void mi_stats_print(void* out) mi_attr_noexcept; // backward compatibility: `out` is ignored and should be NULL mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; mi_decl_export void mi_process_init(void) mi_attr_noexcept; mi_decl_export void mi_thread_init(void) mi_attr_noexcept; mi_decl_export void mi_thread_done(void) mi_attr_noexcept; mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept; // ------------------------------------------------------------------------------------- // Aligned allocation // Note that `alignment` always follows `size` for consistency with unaligned // allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`. // ------------------------------------------------------------------------------------- mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); // ------------------------------------------------------------------------------------- // Heaps: first-class, but can only allocate from the same thread that created it. // ------------------------------------------------------------------------------------- struct mi_heap_s; typedef struct mi_heap_s mi_heap_t; mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void); mi_decl_export void mi_heap_delete(mi_heap_t* heap); mi_decl_export void mi_heap_destroy(mi_heap_t* heap); mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); mi_decl_export mi_heap_t* mi_heap_get_default(void); mi_decl_export mi_heap_t* mi_heap_get_backing(void); mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); // -------------------------------------------------------------------------------- // Zero initialized re-allocation. // Only valid on memory that was originally allocated with zero initialization too. // e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. // see // -------------------------------------------------------------------------------- mi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4); mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3); mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5); mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4); // ------------------------------------------------------ // Analysis // ------------------------------------------------------ mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); mi_decl_export bool mi_check_owned(const void* p); // An area of heap space contains blocks of a single size. typedef struct mi_heap_area_s { void* blocks; // start of the area containing heap blocks size_t reserved; // bytes reserved for this area (virtual) size_t committed; // current available bytes for this area size_t used; // bytes in use by allocated blocks size_t block_size; // size in bytes of each block } mi_heap_area_t; typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); // Experimental mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept; mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept; mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept; // deprecated mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept; // ------------------------------------------------------ // Convenience // ------------------------------------------------------ #define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) #define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) #define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp))) #define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp))) #define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp))) #define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp))) #define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) #define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) #define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp))) #define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp))) #define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp))) #define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp))) // ------------------------------------------------------ // Options, all `false` by default // ------------------------------------------------------ typedef enum mi_option_e { // stable options mi_option_show_errors, mi_option_show_stats, mi_option_verbose, // the following options are experimental mi_option_eager_commit, mi_option_eager_region_commit, mi_option_reset_decommits, mi_option_large_os_pages, // implies eager commit mi_option_reserve_huge_os_pages, mi_option_segment_cache, mi_option_page_reset, mi_option_abandoned_page_reset, mi_option_segment_reset, mi_option_eager_commit_delay, mi_option_reset_delay, mi_option_use_numa_nodes, mi_option_os_tag, mi_option_max_errors, _mi_option_last } mi_option_t; mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option); mi_decl_export void mi_option_enable(mi_option_t option); mi_decl_export void mi_option_disable(mi_option_t option); mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option); mi_decl_export void mi_option_set(mi_option_t option, long value); mi_decl_export void mi_option_set_default(mi_option_t option, long value); // ------------------------------------------------------------------------------------------------------- // "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. // (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.) // note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing. // ------------------------------------------------------------------------------------------------------- mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept mi_attr_malloc; mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept mi_attr_malloc; mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept; mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept; mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; // The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`. // (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception). mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size) mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1, 2); mi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize) mi_attr_alloc_size(2); mi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3); #ifdef __cplusplus } #endif // --------------------------------------------------------------------------------------------- // Implement the C++ std::allocator interface for use in STL containers. // (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally) // --------------------------------------------------------------------------------------------- #ifdef __cplusplus #include // PTRDIFF_MAX #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 #include // std::true_type #include // std::forward #endif template struct mi_stl_allocator { typedef T value_type; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef value_type& reference; typedef value_type const& const_reference; typedef value_type* pointer; typedef value_type const* const_pointer; template struct rebind { typedef mi_stl_allocator other; }; mi_stl_allocator() mi_attr_noexcept = default; mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default; template mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept { } mi_stl_allocator select_on_container_copy_construction() const { return *this; } void deallocate(T* p, size_type) { mi_free(p); } #if (__cplusplus >= 201703L) // C++17 mi_decl_nodiscard T* allocate(size_type count) { return static_cast(mi_new_n(count, sizeof(T))); } mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } #else mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast(mi_new_n(count, sizeof(value_type))); } #endif #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 using propagate_on_container_copy_assignment = std::true_type; using propagate_on_container_move_assignment = std::true_type; using propagate_on_container_swap = std::true_type; using is_always_equal = std::true_type; template void construct(U* p, Args&& ...args) { ::new(p) U(std::forward(args)...); } template void destroy(U* p) mi_attr_noexcept { p->~U(); } #else void construct(pointer p, value_type const& val) { ::new(p) value_type(val); } void destroy(pointer p) { p->~value_type(); } #endif size_type max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); } pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } }; template bool operator==(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return true; } template bool operator!=(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return false; } #endif // __cplusplus #endif ================================================ FILE: runtime/src/mimalloc/c/init.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include // memcpy, memset #include // atexit // Empty page used to initialize the small free pages array const mi_page_t _mi_page_empty = { 0, false, false, false, false, 0, // capacity 0, // reserved capacity { 0 }, // flags false, // is_zero 0, // retire_expire NULL, // free #if MI_ENCODE_FREELIST { 0, 0 }, #endif 0, // used 0, // xblock_size NULL, // local_free ATOMIC_VAR_INIT(0), // xthread_free ATOMIC_VAR_INIT(0), // xheap NULL, NULL }; #define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty) #if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8) #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } #elif (MI_PADDING>0) #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } #else #define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() } #endif // Empty page queues for every bin #define QNULL(sz) { NULL, NULL, (sz)*sizeof(uintptr_t) } #define MI_PAGE_QUEUES_EMPTY \ { QNULL(1), \ QNULL( 1), QNULL( 2), QNULL( 3), QNULL( 4), QNULL( 5), QNULL( 6), QNULL( 7), QNULL( 8), /* 8 */ \ QNULL( 10), QNULL( 12), QNULL( 14), QNULL( 16), QNULL( 20), QNULL( 24), QNULL( 28), QNULL( 32), /* 16 */ \ QNULL( 40), QNULL( 48), QNULL( 56), QNULL( 64), QNULL( 80), QNULL( 96), QNULL( 112), QNULL( 128), /* 24 */ \ QNULL( 160), QNULL( 192), QNULL( 224), QNULL( 256), QNULL( 320), QNULL( 384), QNULL( 448), QNULL( 512), /* 32 */ \ QNULL( 640), QNULL( 768), QNULL( 896), QNULL( 1024), QNULL( 1280), QNULL( 1536), QNULL( 1792), QNULL( 2048), /* 40 */ \ QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \ QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \ QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \ QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \ QNULL(MI_LARGE_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \ QNULL(MI_LARGE_OBJ_WSIZE_MAX + 2) /* Full queue */ } #define MI_STAT_COUNT_NULL() {0,0,0,0} // Empty statistics #if MI_STAT>1 #define MI_STAT_COUNT_END_NULL() , { MI_STAT_COUNT_NULL(), MI_INIT32(MI_STAT_COUNT_NULL) } #else #define MI_STAT_COUNT_END_NULL() #endif #define MI_STATS_NULL \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ MI_STAT_COUNT_NULL(), \ { 0, 0 }, { 0, 0 }, { 0, 0 }, \ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \ MI_STAT_COUNT_END_NULL() // -------------------------------------------------------- // Statically allocate an empty heap as the initial // thread local value for the default heap, // and statically allocate the backing heap for the main // thread so it can function without doing any allocation // itself (as accessing a thread local for the first time // may lead to allocation itself on some platforms) // -------------------------------------------------------- const mi_heap_t _mi_heap_empty = { NULL, MI_SMALL_PAGES_EMPTY, MI_PAGE_QUEUES_EMPTY, ATOMIC_VAR_INIT(NULL), 0, // tid 0, // cookie { 0, 0 }, // keys { {0}, {0}, 0 }, 0, // page count MI_BIN_FULL, 0, // page retired min/max NULL, // next false }; // the thread-local default heap for allocation mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty; extern mi_heap_t _mi_heap_main; static mi_tld_t tld_main = { 0, false, &_mi_heap_main, &_mi_heap_main, { { NULL, NULL }, {NULL ,NULL}, {NULL ,NULL, 0}, 0, 0, 0, 0, 0, 0, NULL, &tld_main.stats, &tld_main.os }, // segments { 0, &tld_main.stats }, // os { MI_STATS_NULL } // stats }; mi_heap_t _mi_heap_main = { &tld_main, MI_SMALL_PAGES_EMPTY, MI_PAGE_QUEUES_EMPTY, ATOMIC_VAR_INIT(NULL), 0, // thread id 0, // initial cookie { 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!) { {0x846ca68b}, {0}, 0 }, // random 0, // page count MI_BIN_FULL, 0, // page retired min/max NULL, // next heap false // can reclaim }; bool _mi_process_is_initialized = false; // set to `true` in `mi_process_init`. mi_stats_t _mi_stats_main = { MI_STATS_NULL }; static void mi_heap_main_init(void) { if (_mi_heap_main.cookie == 0) { _mi_heap_main.thread_id = _mi_thread_id(); _mi_heap_main.cookie = _os_random_weak((uintptr_t)&mi_heap_main_init); _mi_random_init(&_mi_heap_main.random); _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main); _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main); } } mi_heap_t* _mi_heap_main_get(void) { mi_heap_main_init(); return &_mi_heap_main; } /* ----------------------------------------------------------- Initialization and freeing of the thread local heaps ----------------------------------------------------------- */ // note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size). typedef struct mi_thread_data_s { mi_heap_t heap; // must come first due to cast in `_mi_heap_done` mi_tld_t tld; } mi_thread_data_t; // Initialize the thread local default heap, called from `mi_thread_init` static bool _mi_heap_init(void) { if (mi_heap_is_initialized(mi_get_default_heap())) return true; if (_mi_is_main_thread()) { // mi_assert_internal(_mi_heap_main.thread_id != 0); // can happen on freeBSD where alloc is called before any initialization // the main heap is statically allocated mi_heap_main_init(); _mi_heap_set_default_direct(&_mi_heap_main); //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_get_default_heap()); } else { // use `_mi_os_alloc` to allocate directly from the OS mi_thread_data_t* td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); // Todo: more efficient allocation? if (td == NULL) { // if this fails, try once more. (issue #257) td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); if (td == NULL) { // really out of memory _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t)); return false; } } // OS allocated so already zero initialized mi_tld_t* tld = &td->tld; mi_heap_t* heap = &td->heap; memcpy(heap, &_mi_heap_empty, sizeof(*heap)); heap->thread_id = _mi_thread_id(); _mi_random_init(&heap->random); heap->cookie = _mi_heap_random_next(heap) | 1; heap->keys[0] = _mi_heap_random_next(heap); heap->keys[1] = _mi_heap_random_next(heap); heap->tld = tld; tld->heap_backing = heap; tld->heaps = heap; tld->segments.stats = &tld->stats; tld->segments.os = &tld->os; tld->os.stats = &tld->stats; _mi_heap_set_default_direct(heap); } return false; } // Free the thread local default heap (called from `mi_thread_done`) static bool _mi_heap_done(mi_heap_t* heap) { if (!mi_heap_is_initialized(heap)) return true; // reset default heap _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty); // switch to backing heap heap = heap->tld->heap_backing; if (!mi_heap_is_initialized(heap)) return false; // delete all non-backing heaps in this thread mi_heap_t* curr = heap->tld->heaps; while (curr != NULL) { mi_heap_t* next = curr->next; // save `next` as `curr` will be freed if (curr != heap) { mi_assert_internal(!mi_heap_is_backing(curr)); mi_heap_delete(curr); } curr = next; } mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL); mi_assert_internal(mi_heap_is_backing(heap)); // collect if not the main thread if (heap != &_mi_heap_main) { _mi_heap_collect_abandon(heap); } // merge stats _mi_stats_done(&heap->tld->stats); // free if not the main thread if (heap != &_mi_heap_main) { mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id()); _mi_os_free(heap, sizeof(mi_thread_data_t), &_mi_stats_main); } #if 0 // never free the main thread even in debug mode; if a dll is linked statically with mimalloc, // there may still be delete/free calls after the mi_fls_done is called. Issue #207 else { _mi_heap_destroy_pages(heap); mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main); } #endif return false; } // -------------------------------------------------------- // Try to run `mi_thread_done()` automatically so any memory // owned by the thread but not yet released can be abandoned // and re-owned by another thread. // // 1. windows dynamic library: // call from DllMain on DLL_THREAD_DETACH // 2. windows static library: // use `FlsAlloc` to call a destructor when the thread is done // 3. unix, pthreads: // use a pthread key to call a destructor when a pthread is done // // In the last two cases we also need to call `mi_process_init` // to set up the thread local keys. // -------------------------------------------------------- static void _mi_thread_done(mi_heap_t* default_heap); #ifdef __wasi__ // no pthreads in the WebAssembly Standard Interface #elif !defined(_WIN32) #define MI_USE_PTHREADS #endif #if defined(_WIN32) && defined(MI_SHARED_LIB) // nothing to do as it is done in DllMain #elif defined(_WIN32) && !defined(MI_SHARED_LIB) // use thread local storage keys to detect thread ending #include #include #if (_WIN32_WINNT < 0x600) // before Windows Vista WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback ); WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex ); WINBASEAPI BOOL WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData ); WINBASEAPI BOOL WINAPI FlsFree(_In_ DWORD dwFlsIndex); #endif static DWORD mi_fls_key = (DWORD)(-1); static void NTAPI mi_fls_done(PVOID value) { if (value!=NULL) _mi_thread_done((mi_heap_t*)value); } #elif defined(MI_USE_PTHREADS) // use pthread local storage keys to detect thread ending // (and used with MI_TLS_PTHREADS for the default heap) #include pthread_key_t _mi_heap_default_key = (pthread_key_t)(-1); static void mi_pthread_done(void* value) { if (value!=NULL) _mi_thread_done((mi_heap_t*)value); } #elif defined(__wasi__) // no pthreads in the WebAssembly Standard Interface #else #pragma message("define a way to call mi_thread_done when a thread is done") #endif // Set up handlers so `mi_thread_done` is called automatically static void mi_process_setup_auto_thread_done(void) { static bool tls_initialized = false; // fine if it races if (tls_initialized) return; tls_initialized = true; #if defined(_WIN32) && defined(MI_SHARED_LIB) // nothing to do as it is done in DllMain #elif defined(_WIN32) && !defined(MI_SHARED_LIB) mi_fls_key = FlsAlloc(&mi_fls_done); #elif defined(MI_USE_PTHREADS) mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1)); pthread_key_create(&_mi_heap_default_key, &mi_pthread_done); #endif _mi_heap_set_default_direct(&_mi_heap_main); } bool _mi_is_main_thread(void) { return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id()); } // This is called from the `mi_malloc_generic` void mi_thread_init(void) mi_attr_noexcept { // ensure our process has started already mi_process_init(); // initialize the thread local default heap // (this will call `_mi_heap_set_default_direct` and thus set the // fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called) if (_mi_heap_init()) return; // returns true if already initialized _mi_stat_increase(&_mi_stats_main.threads, 1); //_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id()); } void mi_thread_done(void) mi_attr_noexcept { _mi_thread_done(mi_get_default_heap()); } static void _mi_thread_done(mi_heap_t* heap) { _mi_stat_decrease(&_mi_stats_main.threads, 1); // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps... if (heap->thread_id != _mi_thread_id()) return; // abandon the thread local heap if (_mi_heap_done(heap)) return; // returns true if already ran } void _mi_heap_set_default_direct(mi_heap_t* heap) { mi_assert_internal(heap != NULL); #if defined(MI_TLS_SLOT) mi_tls_slot_set(MI_TLS_SLOT,heap); #elif defined(MI_TLS_PTHREAD_SLOT_OFS) *mi_tls_pthread_heap_slot() = heap; #elif defined(MI_TLS_PTHREAD) // we use _mi_heap_default_key #else _mi_heap_default = heap; #endif // ensure the default heap is passed to `_mi_thread_done` // setting to a non-NULL value also ensures `mi_thread_done` is called. #if defined(_WIN32) && defined(MI_SHARED_LIB) // nothing to do as it is done in DllMain #elif defined(_WIN32) && !defined(MI_SHARED_LIB) mi_assert_internal(mi_fls_key != 0); FlsSetValue(mi_fls_key, heap); #elif defined(MI_USE_PTHREADS) if (_mi_heap_default_key != (pthread_key_t)(-1)) { // can happen during recursive invocation on freeBSD pthread_setspecific(_mi_heap_default_key, heap); } #endif } // -------------------------------------------------------- // Run functions on process init/done, and thread init/done // -------------------------------------------------------- static void mi_process_done(void); static bool os_preloading = true; // true until this module is initialized static bool mi_redirected = false; // true if malloc redirects to mi_malloc // Returns true if this module has not been initialized; Don't use C runtime routines until it returns false. bool _mi_preloading(void) { return os_preloading; } bool mi_is_redirected(void) mi_attr_noexcept { return mi_redirected; } // Communicate with the redirection module on Windows #if defined(_WIN32) && defined(MI_SHARED_LIB) #ifdef __cplusplus extern "C" { #endif mi_decl_export void _mi_redirect_entry(DWORD reason) { // called on redirection; careful as this may be called before DllMain if (reason == DLL_PROCESS_ATTACH) { mi_redirected = true; } else if (reason == DLL_PROCESS_DETACH) { mi_redirected = false; } else if (reason == DLL_THREAD_DETACH) { mi_thread_done(); } } __declspec(dllimport) bool mi_allocator_init(const char** message); __declspec(dllimport) void mi_allocator_done(void); #ifdef __cplusplus } #endif #else static bool mi_allocator_init(const char** message) { if (message != NULL) *message = NULL; return true; } static void mi_allocator_done(void) { // nothing to do } #endif // Called once by the process loader static void mi_process_load(void) { mi_heap_main_init(); #if defined(MI_TLS_RECURSE_GUARD) volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true; UNUSED(dummy); #endif os_preloading = false; atexit(&mi_process_done); _mi_options_init(); mi_process_init(); //mi_stats_reset();- if (mi_redirected) _mi_verbose_message("malloc is redirected.\n"); // show message from the redirector (if present) const char* msg = NULL; mi_allocator_init(&msg); if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) { _mi_fputs(NULL,NULL,NULL,msg); } } // Initialize the process; called by thread_init or the process loader void mi_process_init(void) mi_attr_noexcept { // ensure we are called once if (_mi_process_is_initialized) return; _mi_process_is_initialized = true; mi_process_setup_auto_thread_done(); _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id()); _mi_os_init(); mi_heap_main_init(); #if (MI_DEBUG) _mi_verbose_message("debug level : %d\n", MI_DEBUG); #endif _mi_verbose_message("secure level: %d\n", MI_SECURE); mi_thread_init(); mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { size_t pages = mi_option_get(mi_option_reserve_huge_os_pages); mi_reserve_huge_os_pages_interleave(pages, 0, pages*500); } } // Called when the process is done (through `at_exit`) static void mi_process_done(void) { // only shutdown if we were initialized if (!_mi_process_is_initialized) return; // ensure we are called once static bool process_done = false; if (process_done) return; process_done = true; #if defined(_WIN32) && !defined(MI_SHARED_LIB) FlsSetValue(mi_fls_key, NULL); // don't call main-thread callback FlsFree(mi_fls_key); // call thread-done on all threads to prevent dangling callback pointer if statically linked with a DLL; Issue #208 #endif #if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB) // free all memory if possible on process exit. This is not needed for a stand-alone process // but should be done if mimalloc is statically linked into another shared library which // is repeatedly loaded/unloaded, see issue #281. mi_collect(true /* force */ ); #endif if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) { mi_stats_print(NULL); } mi_allocator_done(); _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); os_preloading = true; // don't call the C runtime anymore } #if defined(_WIN32) && defined(MI_SHARED_LIB) // Windows DLL: easy to hook into process_init and thread_done __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { UNUSED(reserved); UNUSED(inst); if (reason==DLL_PROCESS_ATTACH) { mi_process_load(); } else if (reason==DLL_THREAD_DETACH) { if (!mi_is_redirected()) mi_thread_done(); } return TRUE; } #elif defined(__cplusplus) // C++: use static initialization to detect process start static bool _mi_process_init(void) { mi_process_load(); return (_mi_heap_main.thread_id != 0); } static bool mi_initialized = _mi_process_init(); #elif defined(__GNUC__) || defined(__clang__) // GCC,Clang: use the constructor attribute static void __attribute__((constructor)) _mi_process_init(void) { mi_process_load(); } #elif defined(_MSC_VER) // MSVC: use data section magic for static libraries // See static int _mi_process_init(void) { mi_process_load(); return 0; } typedef int(*_crt_cb)(void); #ifdef _M_X64 __pragma(comment(linker, "/include:" "_mi_msvc_initu")) #pragma section(".CRT$XIU", long, read) #else __pragma(comment(linker, "/include:" "__mi_msvc_initu")) #endif #pragma data_seg(".CRT$XIU") _crt_cb _mi_msvc_initu[] = { &_mi_process_init }; #pragma data_seg() #else #pragma message("define a way to call mi_process_load on your platform") #endif ================================================ FILE: runtime/src/mimalloc/c/options.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include #include // strtol #include // strncpy, strncat, strlen, strstr #include // toupper #include #ifdef _MSC_VER #pragma warning(disable:4996) // strncpy, strncat #endif static uintptr_t mi_max_error_count = 16; // stop outputting errors after this static void mi_add_stderr_output(); int mi_version(void) mi_attr_noexcept { return MI_MALLOC_VERSION; } #ifdef _WIN32 #include #endif // -------------------------------------------------------- // Options // These can be accessed by multiple threads and may be // concurrently initialized, but an initializing data race // is ok since they resolve to the same value. // -------------------------------------------------------- typedef enum mi_init_e { UNINIT, // not yet initialized DEFAULTED, // not found in the environment, use default value INITIALIZED // found in environment or set explicitly } mi_init_t; typedef struct mi_option_desc_s { long value; // the value mi_init_t init; // is it initialized yet? (from the environment) mi_option_t option; // for debugging: the option index should match the option const char* name; // option name without `mimalloc_` prefix } mi_option_desc_t; #define MI_OPTION(opt) mi_option_##opt, #opt #define MI_OPTION_DESC(opt) {0, UNINIT, MI_OPTION(opt) } static mi_option_desc_t options[_mi_option_last] = { // stable options #if MI_DEBUG || defined(MI_SHOW_ERRORS) { 1, UNINIT, MI_OPTION(show_errors) }, #else { 0, UNINIT, MI_OPTION(show_errors) }, #endif { 0, UNINIT, MI_OPTION(show_stats) }, { 0, UNINIT, MI_OPTION(verbose) }, // the following options are experimental and not all combinations make sense. { 1, UNINIT, MI_OPTION(eager_commit) }, // commit per segment directly (4MiB) (but see also `eager_commit_delay`) #if defined(_WIN32) || (MI_INTPTR_SIZE <= 4) // and other OS's without overcommit? { 0, UNINIT, MI_OPTION(eager_region_commit) }, { 1, UNINIT, MI_OPTION(reset_decommits) }, // reset decommits memory #else { 1, UNINIT, MI_OPTION(eager_region_commit) }, { 0, UNINIT, MI_OPTION(reset_decommits) }, // reset uses MADV_FREE/MADV_DONTNEED #endif { 0, UNINIT, MI_OPTION(large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) }, { 0, UNINIT, MI_OPTION(segment_cache) }, // cache N segments per thread { 1, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free { 0, UNINIT, MI_OPTION(abandoned_page_reset) },// reset free page memory when a thread terminates { 0, UNINIT, MI_OPTION(segment_reset) }, // reset segment memory on free (needs eager commit) #if defined(__NetBSD__) { 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed #else { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed (but per page in the segment on demand) #endif { 100, UNINIT, MI_OPTION(reset_delay) }, // reset delay in milli-seconds { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes. { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose { 16, UNINIT, MI_OPTION(max_errors) } // maximum errors that are output }; static void mi_option_init(mi_option_desc_t* desc); void _mi_options_init(void) { // called on process load; should not be called before the CRT is initialized! // (e.g. do not call this from process_init as that may run before CRT initialization) mi_add_stderr_output(); // now it safe to use stderr for output for(int i = 0; i < _mi_option_last; i++ ) { mi_option_t option = (mi_option_t)i; long l = mi_option_get(option); UNUSED(l); // initialize if (option != mi_option_verbose) { mi_option_desc_t* desc = &options[option]; _mi_verbose_message("option '%s': %ld\n", desc->name, desc->value); } } mi_max_error_count = mi_option_get(mi_option_max_errors); } long mi_option_get(mi_option_t option) { mi_assert(option >= 0 && option < _mi_option_last); mi_option_desc_t* desc = &options[option]; mi_assert(desc->option == option); // index should match the option if (mi_unlikely(desc->init == UNINIT)) { mi_option_init(desc); } return desc->value; } void mi_option_set(mi_option_t option, long value) { mi_assert(option >= 0 && option < _mi_option_last); mi_option_desc_t* desc = &options[option]; mi_assert(desc->option == option); // index should match the option desc->value = value; desc->init = INITIALIZED; } void mi_option_set_default(mi_option_t option, long value) { mi_assert(option >= 0 && option < _mi_option_last); mi_option_desc_t* desc = &options[option]; if (desc->init != INITIALIZED) { desc->value = value; } } bool mi_option_is_enabled(mi_option_t option) { return (mi_option_get(option) != 0); } void mi_option_set_enabled(mi_option_t option, bool enable) { mi_option_set(option, (enable ? 1 : 0)); } void mi_option_set_enabled_default(mi_option_t option, bool enable) { mi_option_set_default(option, (enable ? 1 : 0)); } void mi_option_enable(mi_option_t option) { mi_option_set_enabled(option,true); } void mi_option_disable(mi_option_t option) { mi_option_set_enabled(option,false); } static void mi_out_stderr(const char* msg, void* arg) { UNUSED(arg); #ifdef _WIN32 // on windows with redirection, the C runtime cannot handle locale dependent output // after the main thread closes so we use direct console output. if (!_mi_preloading()) { _cputs(msg); } #else fputs(msg, stderr); #endif } // Since an output function can be registered earliest in the `main` // function we also buffer output that happens earlier. When // an output function is registered it is called immediately with // the output up to that point. #ifndef MI_MAX_DELAY_OUTPUT #define MI_MAX_DELAY_OUTPUT ((uintptr_t)(32*1024)) #endif static char out_buf[MI_MAX_DELAY_OUTPUT+1]; static _Atomic(uintptr_t) out_len; static void mi_out_buf(const char* msg, void* arg) { UNUSED(arg); if (msg==NULL) return; if (mi_atomic_load_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return; size_t n = strlen(msg); if (n==0) return; // claim space uintptr_t start = mi_atomic_add_acq_rel(&out_len, n); if (start >= MI_MAX_DELAY_OUTPUT) return; // check bound if (start+n >= MI_MAX_DELAY_OUTPUT) { n = MI_MAX_DELAY_OUTPUT-start-1; } memcpy(&out_buf[start], msg, n); } static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) { if (out==NULL) return; // claim (if `no_more_buf == true`, no more output will be added after this point) size_t count = mi_atomic_add_acq_rel(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1)); // and output the current contents if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT; out_buf[count] = 0; out(out_buf,arg); if (!no_more_buf) { out_buf[count] = '\n'; // if continue with the buffer, insert a newline } } // Once this module is loaded, switch to this routine // which outputs to stderr and the delayed output buffer. static void mi_out_buf_stderr(const char* msg, void* arg) { mi_out_stderr(msg,arg); mi_out_buf(msg,arg); } // -------------------------------------------------------- // Default output handler // -------------------------------------------------------- // Should be atomic but gives errors on many platforms as generally we cannot cast a function pointer to a uintptr_t. // For now, don't register output from multiple threads. static mi_output_fun* volatile mi_out_default; // = NULL static _Atomic(void*) mi_out_arg; // = NULL static mi_output_fun* mi_out_get_default(void** parg) { if (parg != NULL) { *parg = mi_atomic_load_ptr_acquire(void,&mi_out_arg); } mi_output_fun* out = mi_out_default; return (out == NULL ? &mi_out_buf : out); } void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept { mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer mi_atomic_store_ptr_release(void,&mi_out_arg, arg); if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now } // add stderr to the delayed output after the module is loaded static void mi_add_stderr_output() { mi_assert_internal(mi_out_default == NULL); mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output } // -------------------------------------------------------- // Messages, all end up calling `_mi_fputs`. // -------------------------------------------------------- static _Atomic(uintptr_t) error_count; // = 0; // when MAX_ERROR_COUNT stop emitting errors and warnings // When overriding malloc, we may recurse into mi_vfprintf if an allocation // inside the C runtime causes another message. static mi_decl_thread bool recurse = false; static bool mi_recurse_enter(void) { #ifdef MI_TLS_RECURSE_GUARD if (_mi_preloading()) return true; #endif if (recurse) return false; recurse = true; return true; } static void mi_recurse_exit(void) { #ifdef MI_TLS_RECURSE_GUARD if (_mi_preloading()) return; #endif recurse = false; } void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) { if (out==NULL || (FILE*)out==stdout || (FILE*)out==stderr) { // TODO: use mi_out_stderr for stderr? if (!mi_recurse_enter()) return; out = mi_out_get_default(&arg); if (prefix != NULL) out(prefix, arg); out(message, arg); mi_recurse_exit(); } else { if (prefix != NULL) out(prefix, arg); out(message, arg); } } // Define our own limited `fprintf` that avoids memory allocation. // We do this using `snprintf` with a limited buffer. static void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) { char buf[512]; if (fmt==NULL) return; if (!mi_recurse_enter()) return; vsnprintf(buf,sizeof(buf)-1,fmt,args); mi_recurse_exit(); _mi_fputs(out,arg,prefix,buf); } void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) { va_list args; va_start(args,fmt); mi_vfprintf(out,arg,NULL,fmt,args); va_end(args); } void _mi_trace_message(const char* fmt, ...) { if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher va_list args; va_start(args, fmt); mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); va_end(args); } void _mi_verbose_message(const char* fmt, ...) { if (!mi_option_is_enabled(mi_option_verbose)) return; va_list args; va_start(args,fmt); mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); va_end(args); } static void mi_show_error_message(const char* fmt, va_list args) { if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; if (mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; mi_vfprintf(NULL, NULL, "mimalloc: error: ", fmt, args); } void _mi_warning_message(const char* fmt, ...) { if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; if (mi_atomic_increment_acq_rel(&error_count) > mi_max_error_count) return; va_list args; va_start(args,fmt); mi_vfprintf(NULL, NULL, "mimalloc: warning: ", fmt, args); va_end(args); } #if MI_DEBUG void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) { _mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion); abort(); } #endif // -------------------------------------------------------- // Errors // -------------------------------------------------------- static mi_error_fun* volatile mi_error_handler; // = NULL static _Atomic(void*) mi_error_arg; // = NULL static void mi_error_default(int err) { UNUSED(err); #if (MI_DEBUG>0) if (err==EFAULT) { #ifdef _MSC_VER __debugbreak(); #endif abort(); } #endif #if (MI_SECURE>0) if (err==EFAULT) { // abort on serious errors in secure mode (corrupted meta-data) abort(); } #endif #if defined(MI_XMALLOC) if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode abort(); } #endif } void mi_register_error(mi_error_fun* fun, void* arg) { mi_error_handler = fun; // can be NULL mi_atomic_store_ptr_release(void,&mi_error_arg, arg); } void _mi_error_message(int err, const char* fmt, ...) { // show detailed error message va_list args; va_start(args, fmt); mi_show_error_message(fmt, args); va_end(args); // and call the error handler which may abort (or return normally) if (mi_error_handler != NULL) { mi_error_handler(err, mi_atomic_load_ptr_acquire(void,&mi_error_arg)); } else { mi_error_default(err); } } // -------------------------------------------------------- // Initialize options by checking the environment // -------------------------------------------------------- static void mi_strlcpy(char* dest, const char* src, size_t dest_size) { dest[0] = 0; strncpy(dest, src, dest_size - 1); dest[dest_size - 1] = 0; } static void mi_strlcat(char* dest, const char* src, size_t dest_size) { strncat(dest, src, dest_size - 1); dest[dest_size - 1] = 0; } static inline int mi_strnicmp(const char* s, const char* t, size_t n) { if (n==0) return 0; for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) { if (toupper(*s) != toupper(*t)) break; } return (n==0 ? 0 : *s - *t); } #if defined _WIN32 // On Windows use GetEnvironmentVariable instead of getenv to work // reliably even when this is invoked before the C runtime is initialized. // i.e. when `_mi_preloading() == true`. // Note: on windows, environment names are not case sensitive. #include static bool mi_getenv(const char* name, char* result, size_t result_size) { result[0] = 0; size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size); return (len > 0 && len < result_size); } #elif !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0) // On Posix systemsr use `environ` to acces environment variables // even before the C runtime is initialized. #if defined(__APPLE__) && defined(__has_include) && __has_include() #include static char** mi_get_environ(void) { return (*_NSGetEnviron()); } #else extern char** environ; static char** mi_get_environ(void) { return environ; } #endif static bool mi_getenv(const char* name, char* result, size_t result_size) { if (name==NULL) return false; const size_t len = strlen(name); if (len == 0) return false; char** env = mi_get_environ(); if (env == NULL) return false; // compare up to 256 entries for (int i = 0; i < 256 && env[i] != NULL; i++) { const char* s = env[i]; if (mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive // found it mi_strlcpy(result, s + len + 1, result_size); return true; } } return false; } #else // fallback: use standard C `getenv` but this cannot be used while initializing the C runtime static bool mi_getenv(const char* name, char* result, size_t result_size) { // cannot call getenv() when still initializing the C runtime. if (_mi_preloading()) return false; const char* s = getenv(name); if (s == NULL) { // we check the upper case name too. char buf[64+1]; size_t len = strlen(name); if (len >= sizeof(buf)) len = sizeof(buf) - 1; for (size_t i = 0; i < len; i++) { buf[i] = toupper(name[i]); } buf[len] = 0; s = getenv(buf); } if (s != NULL && strlen(s) < result_size) { mi_strlcpy(result, s, result_size); return true; } else { return false; } } #endif static void mi_option_init(mi_option_desc_t* desc) { // Read option value from the environment char buf[64+1]; mi_strlcpy(buf, "mimalloc_", sizeof(buf)); mi_strlcat(buf, desc->name, sizeof(buf)); char s[64+1]; if (mi_getenv(buf, s, sizeof(s))) { size_t len = strlen(s); if (len >= sizeof(buf)) len = sizeof(buf) - 1; for (size_t i = 0; i < len; i++) { buf[i] = (char)toupper(s[i]); } buf[len] = 0; if (buf[0]==0 || strstr("1;TRUE;YES;ON", buf) != NULL) { desc->value = 1; desc->init = INITIALIZED; } else if (strstr("0;FALSE;NO;OFF", buf) != NULL) { desc->value = 0; desc->init = INITIALIZED; } else { char* end = buf; long value = strtol(buf, &end, 10); if (*end == 0) { desc->value = value; desc->init = INITIALIZED; } else { _mi_warning_message("environment option mimalloc_%s has an invalid value: %s\n", desc->name, buf); desc->init = DEFAULTED; } } mi_assert_internal(desc->init != UNINIT); } else if (!_mi_preloading()) { desc->init = DEFAULTED; } } ================================================ FILE: runtime/src/mimalloc/c/os.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE // ensure mmap flags are defined #endif #if defined(__sun) // illumos provides new mman.h api when any of these are defined // otherwise the old api based on caddr_t which predates the void pointers one. // stock solaris provides only the former, chose to atomically to discard those // flags only here rather than project wide tough. #undef _XOPEN_SOURCE #undef _POSIX_C_SOURCE #endif #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // strerror #ifdef _MSC_VER #pragma warning(disable:4996) // strerror #endif #if defined(_WIN32) #include #elif defined(__wasi__) // stdlib.h is all we need, and has already been included in mimalloc.h #else #include // mmap #include // sysconf #if defined(__linux__) #include #if defined(__GLIBC__) #include // linux mmap flags #else #include #endif #endif #if defined(__APPLE__) #include #if !TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR #include #endif #endif #if defined(__HAIKU__) #define madvise posix_madvise #define MADV_DONTNEED POSIX_MADV_DONTNEED #endif #endif /* ----------------------------------------------------------- Initialization. On windows initializes support for aligned allocation and large OS pages (if MIMALLOC_LARGE_OS_PAGES is true). ----------------------------------------------------------- */ bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); static void* mi_align_up_ptr(void* p, size_t alignment) { return (void*)_mi_align_up((uintptr_t)p, alignment); } static uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { return (sz / alignment) * alignment; } static void* mi_align_down_ptr(void* p, size_t alignment) { return (void*)_mi_align_down((uintptr_t)p, alignment); } // page size (initialized properly in `os_init`) static size_t os_page_size = 4096; // minimal allocation granularity static size_t os_alloc_granularity = 4096; // if non-zero, use large page allocation static size_t large_os_page_size = 0; // OS (small) page size size_t _mi_os_page_size() { return os_page_size; } // if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB) size_t _mi_os_large_page_size() { return (large_os_page_size != 0 ? large_os_page_size : _mi_os_page_size()); } static bool use_large_os_page(size_t size, size_t alignment) { // if we have access, check the size and alignment requirements if (large_os_page_size == 0 || !mi_option_is_enabled(mi_option_large_os_pages)) return false; return ((size % large_os_page_size) == 0 && (alignment % large_os_page_size) == 0); } // round to a good OS allocation size (bounded by max 12.5% waste) size_t _mi_os_good_alloc_size(size_t size) { size_t align_size; if (size < 512*KiB) align_size = _mi_os_page_size(); else if (size < 2*MiB) align_size = 64*KiB; else if (size < 8*MiB) align_size = 256*KiB; else if (size < 32*MiB) align_size = 1*MiB; else align_size = 4*MiB; if (size >= (SIZE_MAX - align_size)) return size; // possible overflow? return _mi_align_up(size, align_size); } #if defined(_WIN32) // We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. // So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility) // NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB) // // We hide MEM_EXTENDED_PARAMETER to compile with older SDK's. #include typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ void*, ULONG); typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ PVOID, ULONG); static PVirtualAlloc2 pVirtualAlloc2 = NULL; static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL; // Similarly, GetNumaProcesorNodeEx is only supported since Windows 7 #if (_WIN32_WINNT < 0x601) // before Win7 typedef struct _PROCESSOR_NUMBER { WORD Group; BYTE Number; BYTE Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; #endif typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(PPROCESSOR_NUMBER ProcNumber); typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(PPROCESSOR_NUMBER Processor, PUSHORT NodeNumber); typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask); static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL; static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL; static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL; static bool mi_win_enable_large_os_pages() { if (large_os_page_size > 0) return true; // Try to see if large OS pages are supported // To use large pages on Windows, we first need access permission // Set "Lock pages in memory" permission in the group policy editor // unsigned long err = 0; HANDLE token = NULL; BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); if (ok) { TOKEN_PRIVILEGES tp; ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid); if (ok) { tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (ok) { err = GetLastError(); ok = (err == ERROR_SUCCESS); if (ok) { large_os_page_size = GetLargePageMinimum(); } } } CloseHandle(token); } if (!ok) { if (err == 0) err = GetLastError(); _mi_warning_message("cannot enable large OS page support, error %lu\n", err); } return (ok!=0); } void _mi_os_init(void) { // get the page size SYSTEM_INFO si; GetSystemInfo(&si); if (si.dwPageSize > 0) os_page_size = si.dwPageSize; if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity; // get the VirtualAlloc2 function HINSTANCE hDll; hDll = LoadLibrary(TEXT("kernelbase.dll")); if (hDll != NULL) { // use VirtualAlloc2FromApp if possible as it is available to Windows store apps pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2FromApp"); if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2"); FreeLibrary(hDll); } // NtAllocateVirtualMemoryEx is used for huge page allocation hDll = LoadLibrary(TEXT("ntdll.dll")); if (hDll != NULL) { pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx"); FreeLibrary(hDll); } // Try to use Win7+ numa API hDll = LoadLibrary(TEXT("kernel32.dll")); if (hDll != NULL) { pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx"); pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx"); pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx"); FreeLibrary(hDll); } if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { mi_win_enable_large_os_pages(); } } #elif defined(__wasi__) void _mi_os_init() { os_page_size = 0x10000; // WebAssembly has a fixed page size: 64KB os_alloc_granularity = 16; } #else void _mi_os_init() { // get the page size long result = sysconf(_SC_PAGESIZE); if (result > 0) { os_page_size = (size_t)result; os_alloc_granularity = os_page_size; } large_os_page_size = 2*MiB; // TODO: can we query the OS for this? } #endif /* ----------------------------------------------------------- Raw allocation on Windows (VirtualAlloc) and Unix's (mmap). ----------------------------------------------------------- */ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats_t* stats) { if (addr == NULL || size == 0) return true; // || _mi_os_is_huge_reserved(addr) bool err = false; #if defined(_WIN32) err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); #elif defined(__wasi__) err = 0; // WebAssembly's heap cannot be shrunk #else err = (munmap(addr, size) == -1); #endif if (was_committed) _mi_stat_decrease(&stats->committed, size); _mi_stat_decrease(&stats->reserved, size); if (err) { _mi_warning_message("munmap failed: %s, addr 0x%8li, size %lu\n", strerror(errno), (size_t)addr, size); return false; } else { return true; } } static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size); #ifdef _WIN32 static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment, DWORD flags) { #if (MI_INTPTR_SIZE >= 8) // on 64-bit systems, try to use the virtual address area after 4TiB for 4MiB aligned allocations void* hint; if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment,size)) != NULL) { void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); if (p != NULL) return p; DWORD err = GetLastError(); if (err != ERROR_INVALID_ADDRESS && // If linked with multiple instances, we may have tried to allocate at an already allocated area (#210) err != ERROR_INVALID_PARAMETER) { // Windows7 instability (#230) return NULL; } // fall through } #endif #if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) // on modern Windows try use VirtualAlloc2 for aligned allocation if (try_alignment > 0 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) { MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 }; reqs.Alignment = try_alignment; MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} }; param.Type = MemExtendedParameterAddressRequirements; param.Pointer = &reqs; return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); } #endif // last resort return VirtualAlloc(addr, size, flags, PAGE_READWRITE); } static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) { mi_assert_internal(!(large_only && !allow_large)); static _Atomic(uintptr_t) large_page_try_ok; // = 0; void* p = NULL; if ((large_only || use_large_os_page(size, try_alignment)) && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { uintptr_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); if (!large_only && try_ok > 0) { // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive. // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times. mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); } else { // large OS pages must always reserve and commit. *is_large = true; p = mi_win_virtual_allocx(addr, size, try_alignment, flags | MEM_LARGE_PAGES); if (large_only) return p; // fall back to non-large page allocation on error (`p == NULL`). if (p == NULL) { mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations } } } if (p == NULL) { *is_large = ((flags&MEM_LARGE_PAGES) != 0); p = mi_win_virtual_allocx(addr, size, try_alignment, flags); } if (p == NULL) { _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, GetLastError(), addr, large_only, allow_large); } return p; } #elif defined(__wasi__) static void* mi_wasm_heap_grow(size_t size, size_t try_alignment) { uintptr_t base = __builtin_wasm_memory_size(0) * _mi_os_page_size(); uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment); size_t alloc_size = _mi_align_up( aligned_base - base + size, _mi_os_page_size()); mi_assert(alloc_size >= size && (alloc_size % _mi_os_page_size()) == 0); if (alloc_size < size) return NULL; if (__builtin_wasm_memory_grow(0, alloc_size / _mi_os_page_size()) == SIZE_MAX) { errno = ENOMEM; return NULL; } return (void*)aligned_base; } #else #define MI_OS_USE_MMAP static void* mi_unix_mmapx(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) { void* p = NULL; #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED) // on 64-bit systems, use the virtual address area after 4TiB for 4MiB aligned allocations void* hint; if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment, size)) != NULL) { p = mmap(hint,size,protect_flags,flags,fd,0); if (p==MAP_FAILED) p = NULL; // fall back to regular mmap } #else UNUSED(try_alignment); UNUSED(mi_os_get_aligned_hint); #endif if (p==NULL) { p = mmap(addr,size,protect_flags,flags,fd,0); if (p==MAP_FAILED) p = NULL; } return p; } static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) { void* p = NULL; #if !defined(MAP_ANONYMOUS) #define MAP_ANONYMOUS MAP_ANON #endif #if !defined(MAP_NORESERVE) #define MAP_NORESERVE 0 #endif int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; int fd = -1; #if defined(MAP_ALIGNED) // BSD if (try_alignment > 0) { size_t n = _mi_bsr(try_alignment); if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB flags |= MAP_ALIGNED(n); } } #endif #if defined(PROT_MAX) protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD #endif #if defined(VM_MAKE_TAG) // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99) int os_tag = (int)mi_option_get(mi_option_os_tag); if (os_tag < 100 || os_tag > 255) os_tag = 100; fd = VM_MAKE_TAG(os_tag); #endif if ((large_only || use_large_os_page(size, try_alignment)) && allow_large) { static _Atomic(uintptr_t) large_page_try_ok; // = 0; uintptr_t try_ok = mi_atomic_load_acquire(&large_page_try_ok); if (!large_only && try_ok > 0) { // If the OS is not configured for large OS pages, or the user does not have // enough permission, the `mmap` will always fail (but it might also fail for other reasons). // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times // to avoid too many failing calls to mmap. mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1); } else { int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux int lfd = fd; #ifdef MAP_ALIGNED_SUPER lflags |= MAP_ALIGNED_SUPER; #endif #ifdef MAP_HUGETLB lflags |= MAP_HUGETLB; #endif #ifdef MAP_HUGE_1GB static bool mi_huge_pages_available = true; if ((size % GiB) == 0 && mi_huge_pages_available) { lflags |= MAP_HUGE_1GB; } else #endif { #ifdef MAP_HUGE_2MB lflags |= MAP_HUGE_2MB; #endif } #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB; #endif if (large_only || lflags != flags) { // try large OS page allocation *is_large = true; p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, lflags, lfd); #ifdef MAP_HUGE_1GB if (p == NULL && (lflags & MAP_HUGE_1GB) != 0) { mi_huge_pages_available = false; // don't try huge 1GiB pages again _mi_warning_message("unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (error %i)\n", errno); lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB); p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, lflags, lfd); } #endif if (large_only) return p; if (p == NULL) { mi_atomic_store_release(&large_page_try_ok, 10UL); // on error, don't try again for the next N allocations } } } } if (p == NULL) { *is_large = false; p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, flags, fd); #if defined(MADV_HUGEPAGE) // Many Linux systems don't allow MAP_HUGETLB but they support instead // transparent huge pages (THP). It is not required to call `madvise` with MADV_HUGE // though since properly aligned allocations will already use large pages if available // in that case -- in particular for our large regions (in `memory.c`). // However, some systems only allow THP if called with explicit `madvise`, so // when large OS pages are enabled for mimalloc, we call `madvice` anyways. if (allow_large && use_large_os_page(size, try_alignment)) { if (madvise(p, size, MADV_HUGEPAGE) == 0) { *is_large = true; // possibly }; } #endif #if defined(__sun) if (allow_large && use_large_os_page(size, try_alignment)) { struct memcntl_mha cmd = {0}; cmd.mha_pagesize = large_os_page_size; cmd.mha_cmd = MHA_MAPSIZE_VA; if (memcntl(p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) { *is_large = true; } } #endif } if (p == NULL) { _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, errno, addr, large_only, allow_large); } return p; } #endif // On 64-bit systems, we can do efficient aligned allocation by using // the 4TiB to 30TiB area to allocate them. #if (MI_INTPTR_SIZE >= 8) && (defined(_WIN32) || (defined(MI_OS_USE_MMAP) && !defined(MAP_ALIGNED))) static mi_decl_cache_align _Atomic(uintptr_t) aligned_base; // Return a 4MiB aligned address that is probably available static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { if (try_alignment == 0 || try_alignment > MI_SEGMENT_SIZE) return NULL; if ((size%MI_SEGMENT_SIZE) != 0) return NULL; uintptr_t hint = mi_atomic_add_acq_rel(&aligned_base, size); if (hint == 0 || hint > ((intptr_t)30<<40)) { // try to wrap around after 30TiB (area after 32TiB is used for huge OS pages) uintptr_t init = ((uintptr_t)4 << 40); // start at 4TiB area #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode uintptr_t r = _mi_heap_random_next(mi_get_default_heap()); init = init + (MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)); // (randomly 20 bits)*4MiB == 0 to 4TiB #endif uintptr_t expected = hint + size; mi_atomic_cas_strong_acq_rel(&aligned_base, &expected, init); hint = mi_atomic_add_acq_rel(&aligned_base, size); // this may still give 0 or > 30TiB but that is ok, it is a hint after all } if (hint%try_alignment != 0) return NULL; return (void*)hint; } #else static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { UNUSED(try_alignment); UNUSED(size); return NULL; } #endif // Primitive allocation from the OS. // Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) { mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); if (size == 0) return NULL; if (!commit) allow_large = false; void* p = NULL; /* if (commit && allow_large) { p = _mi_os_try_alloc_from_huge_reserved(size, try_alignment); if (p != NULL) { *is_large = true; return p; } } */ #if defined(_WIN32) int flags = MEM_RESERVE; if (commit) flags |= MEM_COMMIT; p = mi_win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); #elif defined(__wasi__) *is_large = false; p = mi_wasm_heap_grow(size, try_alignment); #else int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE); p = mi_unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large); #endif mi_stat_counter_increase(stats->mmap_calls, 1); if (p != NULL) { _mi_stat_increase(&stats->reserved, size); if (commit) { _mi_stat_increase(&stats->committed, size); } } return p; } // Primitive aligned allocation from the OS. // This function guarantees the allocated memory is aligned. static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) { mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0)); mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); if (!commit) allow_large = false; if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL; size = _mi_align_up(size, _mi_os_page_size()); // try first with a hint (this will be aligned directly on Win 10+ or BSD) void* p = mi_os_mem_alloc(size, alignment, commit, allow_large, is_large, stats); if (p == NULL) return NULL; // if not aligned, free it, overallocate, and unmap around it if (((uintptr_t)p % alignment != 0)) { mi_os_mem_free(p, size, commit, stats); if (size >= (SIZE_MAX - alignment)) return NULL; // overflow size_t over_size = size + alignment; #if _WIN32 // over-allocate and than re-allocate exactly at an aligned address in there. // this may fail due to threads allocating at the same time so we // retry this at most 3 times before giving up. // (we can not decommit around the overallocation on Windows, because we can only // free the original pointer, not one pointing inside the area) int flags = MEM_RESERVE; if (commit) flags |= MEM_COMMIT; for (int tries = 0; tries < 3; tries++) { // over-allocate to determine a virtual memory range p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats); if (p == NULL) return NULL; // error if (((uintptr_t)p % alignment) == 0) { // if p happens to be aligned, just decommit the left-over area _mi_os_decommit((uint8_t*)p + size, over_size - size, stats); break; } else { // otherwise free and allocate at an aligned address in there mi_os_mem_free(p, over_size, commit, stats); void* aligned_p = mi_align_up_ptr(p, alignment); p = mi_win_virtual_alloc(aligned_p, size, alignment, flags, false, allow_large, is_large); if (p == aligned_p) break; // success! if (p != NULL) { // should not happen? mi_os_mem_free(p, size, commit, stats); p = NULL; } } } #else // overallocate... p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats); if (p == NULL) return NULL; // and selectively unmap parts around the over-allocated area. void* aligned_p = mi_align_up_ptr(p, alignment); size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p; size_t mid_size = _mi_align_up(size, _mi_os_page_size()); size_t post_size = over_size - pre_size - mid_size; mi_assert_internal(pre_size < over_size && post_size < over_size && mid_size >= size); if (pre_size > 0) mi_os_mem_free(p, pre_size, commit, stats); if (post_size > 0) mi_os_mem_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); // we can return the aligned pointer on `mmap` systems p = aligned_p; #endif } mi_assert_internal(p == NULL || (p != NULL && ((uintptr_t)p % alignment) == 0)); return p; } /* ----------------------------------------------------------- OS API: alloc, free, alloc_aligned ----------------------------------------------------------- */ void* _mi_os_alloc(size_t size, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; if (size == 0) return NULL; size = _mi_os_good_alloc_size(size); bool is_large = false; return mi_os_mem_alloc(size, 0, true, false, &is_large, stats); } void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; if (size == 0 || p == NULL) return; size = _mi_os_good_alloc_size(size); mi_os_mem_free(p, size, was_committed, stats); } void _mi_os_free(void* p, size_t size, mi_stats_t* stats) { _mi_os_free_ex(p, size, true, stats); } void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld) { UNUSED(tld); if (size == 0) return NULL; size = _mi_os_good_alloc_size(size); alignment = _mi_align_up(alignment, _mi_os_page_size()); bool allow_large = false; if (large != NULL) { allow_large = *large; *large = false; } return mi_os_mem_alloc_aligned(size, alignment, commit, allow_large, (large!=NULL?large:&allow_large), &_mi_stats_main /*tld->stats*/ ); } /* ----------------------------------------------------------- OS memory API: reset, commit, decommit, protect, unprotect. ----------------------------------------------------------- */ // OS page align within a given area, either conservative (pages inside the area only), // or not (straddling pages outside the area is possible) static void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) { mi_assert(addr != NULL && size > 0); if (newsize != NULL) *newsize = 0; if (size == 0 || addr == NULL) return NULL; // page align conservatively within the range void* start = (conservative ? mi_align_up_ptr(addr, _mi_os_page_size()) : mi_align_down_ptr(addr, _mi_os_page_size())); void* end = (conservative ? mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size()) : mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size())); ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start; if (diff <= 0) return NULL; mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size)); if (newsize != NULL) *newsize = (size_t)diff; return start; } static void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) { return mi_os_page_align_areax(true, addr, size, newsize); } static void mi_mprotect_hint(int err) { #if defined(MI_OS_USE_MMAP) && (MI_SECURE>=2) // guard page around every mimalloc page if (err == ENOMEM) { _mi_warning_message("the previous warning may have been caused by a low memory map limit.\n" " On Linux this is controlled by the vm.max_map_count. For example:\n" " > sudo sysctl -w vm.max_map_count=262144\n"); } #else UNUSED(err); #endif } // Commit/Decommit memory. // Usually commit is aligned liberal, while decommit is aligned conservative. // (but not for the reset version where we want commit to be conservative as well) static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservative, bool* is_zero, mi_stats_t* stats) { // page align in the range, commit liberally, decommit conservative if (is_zero != NULL) { *is_zero = false; } size_t csize; void* start = mi_os_page_align_areax(conservative, addr, size, &csize); if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr)) int err = 0; if (commit) { _mi_stat_increase(&stats->committed, size); // use size for precise commit vs. decommit _mi_stat_counter_increase(&stats->commit_calls, 1); } else { _mi_stat_decrease(&stats->committed, size); } #if defined(_WIN32) if (commit) { // if the memory was already committed, the call succeeds but it is not zero'd // *is_zero = true; void* p = VirtualAlloc(start, csize, MEM_COMMIT, PAGE_READWRITE); err = (p == start ? 0 : GetLastError()); } else { BOOL ok = VirtualFree(start, csize, MEM_DECOMMIT); err = (ok ? 0 : GetLastError()); } #elif defined(__wasi__) // WebAssembly guests can't control memory protection #elif defined(MAP_FIXED) if (!commit) { // use mmap with MAP_FIXED to discard the existing memory (and reduce commit charge) void* p = mmap(start, csize, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), -1, 0); if (p != start) { err = errno; } } else { // for commit, just change the protection err = mprotect(start, csize, (PROT_READ | PROT_WRITE)); if (err != 0) { err = errno; } } #else err = mprotect(start, csize, (commit ? (PROT_READ | PROT_WRITE) : PROT_NONE)); if (err != 0) { err = errno; } #endif if (err != 0) { _mi_warning_message("%s error: start: %p, csize: 0x%x, err: %i\n", commit ? "commit" : "decommit", start, csize, err); mi_mprotect_hint(err); } mi_assert_internal(err == 0); return (err == 0); } bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; return mi_os_commitx(addr, size, true, false /* liberal */, is_zero, stats); } bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; bool is_zero; return mi_os_commitx(addr, size, false, true /* conservative */, &is_zero, stats); } static bool mi_os_commit_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) { return mi_os_commitx(addr, size, true, true /* conservative */, is_zero, stats); } // Signal to the OS that the address range is no longer in use // but may be used later again. This will release physical memory // pages and reduce swapping while keeping the memory committed. // We page align to a conservative area inside the range to reset. static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats) { // page align conservatively within the range size_t csize; void* start = mi_os_page_align_area_conservative(addr, size, &csize); if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr) if (reset) _mi_stat_increase(&stats->reset, csize); else _mi_stat_decrease(&stats->reset, csize); if (!reset) return true; // nothing to do on unreset! #if (MI_DEBUG>1) if (MI_SECURE==0) { memset(start, 0, csize); // pretend it is eagerly reset } #endif #if defined(_WIN32) // Testing shows that for us (on `malloc-large`) MEM_RESET is 2x faster than DiscardVirtualMemory void* p = VirtualAlloc(start, csize, MEM_RESET, PAGE_READWRITE); mi_assert_internal(p == start); #if 1 if (p == start && start != NULL) { VirtualUnlock(start,csize); // VirtualUnlock after MEM_RESET removes the memory from the working set } #endif if (p != start) return false; #else #if defined(MADV_FREE) static _Atomic(uintptr_t) advice = ATOMIC_VAR_INIT(MADV_FREE); int err = madvise(start, csize, (int)mi_atomic_load_relaxed(&advice)); if (err != 0 && errno == EINVAL && advice == MADV_FREE) { // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on mi_atomic_store_release(&advice, (uintptr_t)MADV_DONTNEED); err = madvise(start, csize, MADV_DONTNEED); } #elif defined(__wasi__) int err = 0; #else int err = madvise(start, csize, MADV_DONTNEED); #endif if (err != 0) { _mi_warning_message("madvise reset error: start: %p, csize: 0x%x, errno: %i\n", start, csize, errno); } //mi_assert(err == 0); if (err != 0) return false; #endif return true; } // Signal to the OS that the address range is no longer in use // but may be used later again. This will release physical memory // pages and reduce swapping while keeping the memory committed. // We page align to a conservative area inside the range to reset. bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; if (mi_option_is_enabled(mi_option_reset_decommits)) { return _mi_os_decommit(addr, size, stats); } else { return mi_os_resetx(addr, size, true, stats); } } bool _mi_os_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) { UNUSED(tld_stats); mi_stats_t* stats = &_mi_stats_main; if (mi_option_is_enabled(mi_option_reset_decommits)) { return mi_os_commit_unreset(addr, size, is_zero, stats); // re-commit it (conservatively!) } else { *is_zero = false; return mi_os_resetx(addr, size, false, stats); } } // Protect a region in memory to be not accessible. static bool mi_os_protectx(void* addr, size_t size, bool protect) { // page align conservatively within the range size_t csize = 0; void* start = mi_os_page_align_area_conservative(addr, size, &csize); if (csize == 0) return false; /* if (_mi_os_is_huge_reserved(addr)) { _mi_warning_message("cannot mprotect memory allocated in huge OS pages\n"); } */ int err = 0; #ifdef _WIN32 DWORD oldprotect = 0; BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect); err = (ok ? 0 : GetLastError()); #elif defined(__wasi__) err = 0; #else err = mprotect(start, csize, protect ? PROT_NONE : (PROT_READ | PROT_WRITE)); if (err != 0) { err = errno; } #endif if (err != 0) { _mi_warning_message("mprotect error: start: %p, csize: 0x%x, err: %i\n", start, csize, err); mi_mprotect_hint(err); } return (err == 0); } bool _mi_os_protect(void* addr, size_t size) { return mi_os_protectx(addr, size, true); } bool _mi_os_unprotect(void* addr, size_t size) { return mi_os_protectx(addr, size, false); } bool _mi_os_shrink(void* p, size_t oldsize, size_t newsize, mi_stats_t* stats) { // page align conservatively within the range mi_assert_internal(oldsize > newsize && p != NULL); if (oldsize < newsize || p == NULL) return false; if (oldsize == newsize) return true; // oldsize and newsize should be page aligned or we cannot shrink precisely void* addr = (uint8_t*)p + newsize; size_t size = 0; void* start = mi_os_page_align_area_conservative(addr, oldsize - newsize, &size); if (size == 0 || start != addr) return false; #ifdef _WIN32 // we cannot shrink on windows, but we can decommit return _mi_os_decommit(start, size, stats); #else return mi_os_mem_free(start, size, true, stats); #endif } /* ---------------------------------------------------------------------------- Support for allocating huge OS pages (1Gib) that are reserved up-front and possibly associated with a specific NUMA node. (use `numa_node>=0`) -----------------------------------------------------------------------------*/ #define MI_HUGE_OS_PAGE_SIZE (GiB) #if defined(_WIN32) && (MI_INTPTR_SIZE >= 8) static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) { mi_assert_internal(size%GiB == 0); mi_assert_internal(addr != NULL); const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE; mi_win_enable_large_os_pages(); #if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} }; // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages static bool mi_huge_pages_available = true; if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) { #ifndef MEM_EXTENDED_PARAMETER_NONPAGED_HUGE #define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE (0x10) #endif params[0].Type = 5; // == MemExtendedParameterAttributeFlags; params[0].ULong64 = MEM_EXTENDED_PARAMETER_NONPAGED_HUGE; ULONG param_count = 1; if (numa_node >= 0) { param_count++; params[1].Type = MemExtendedParameterNumaNode; params[1].ULong = (unsigned)numa_node; } SIZE_T psize = size; void* base = addr; NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count); if (err == 0 && base != NULL) { return base; } else { // fall back to regular large pages mi_huge_pages_available = false; // don't try further huge pages _mi_warning_message("unable to allocate using huge (1gb) pages, trying large (2mb) pages instead (status 0x%lx)\n", err); } } // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation if (pVirtualAlloc2 != NULL && numa_node >= 0) { params[0].Type = MemExtendedParameterNumaNode; params[0].ULong = (unsigned)numa_node; return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, params, 1); } #else UNUSED(numa_node); #endif // otherwise use regular virtual alloc on older windows return VirtualAlloc(addr, size, flags, PAGE_READWRITE); } #elif defined(MI_OS_USE_MMAP) && (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) #include #ifndef MPOL_PREFERRED #define MPOL_PREFERRED 1 #endif #if defined(SYS_mbind) static long mi_os_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags); } #else static long mi_os_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { UNUSED(start); UNUSED(len); UNUSED(mode); UNUSED(nmask); UNUSED(maxnode); UNUSED(flags); return 0; } #endif static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) { mi_assert_internal(size%GiB == 0); bool is_large = true; void* p = mi_unix_mmap(addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large); if (p == NULL) return NULL; if (numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes uintptr_t numa_mask = (1UL << numa_node); // TODO: does `mbind` work correctly for huge OS pages? should we // use `set_mempolicy` before calling mmap instead? // see: long err = mi_os_mbind(p, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0); if (err != 0) { _mi_warning_message("failed to bind huge (1gb) pages to numa node %d: %s\n", numa_node, strerror(errno)); } } return p; } #else static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) { UNUSED(addr); UNUSED(size); UNUSED(numa_node); return NULL; } #endif #if (MI_INTPTR_SIZE >= 8) // To ensure proper alignment, use our own area for huge OS pages static mi_decl_cache_align _Atomic(uintptr_t) mi_huge_start; // = 0 // Claim an aligned address range for huge pages static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { if (total_size != NULL) *total_size = 0; const size_t size = pages * MI_HUGE_OS_PAGE_SIZE; uintptr_t start = 0; uintptr_t end = 0; uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start); do { start = huge_start; if (start == 0) { // Initialize the start address after the 32TiB area start = ((uintptr_t)32 << 40); // 32TiB virtual start address #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of huge pages unless in debug mode uintptr_t r = _mi_heap_random_next(mi_get_default_heap()); start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF)); // (randomly 12bits)*1GiB == between 0 to 4TiB #endif } end = start + size; mi_assert_internal(end % MI_SEGMENT_SIZE == 0); } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end)); if (total_size != NULL) *total_size = size; return (uint8_t*)start; } #else static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { UNUSED(pages); if (total_size != NULL) *total_size = 0; return NULL; } #endif // Allocate MI_SEGMENT_SIZE aligned huge pages void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize) { if (psize != NULL) *psize = 0; if (pages_reserved != NULL) *pages_reserved = 0; size_t size = 0; uint8_t* start = mi_os_claim_huge_pages(pages, &size); if (start == NULL) return NULL; // or 32-bit systems // Allocate one page at the time but try to place them contiguously // We allocate one page at the time to be able to abort if it takes too long // or to at least allocate as many as available on the system. mi_msecs_t start_t = _mi_clock_start(); size_t page; for (page = 0; page < pages; page++) { // allocate a page void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE); void* p = mi_os_alloc_huge_os_pagesx(addr, MI_HUGE_OS_PAGE_SIZE, numa_node); // Did we succeed at a contiguous address? if (p != addr) { // no success, issue a warning and break if (p != NULL) { _mi_warning_message("could not allocate contiguous huge page %zu at %p\n", page, addr); _mi_os_free(p, MI_HUGE_OS_PAGE_SIZE, &_mi_stats_main); } break; } // success, record it _mi_stat_increase(&_mi_stats_main.committed, MI_HUGE_OS_PAGE_SIZE); _mi_stat_increase(&_mi_stats_main.reserved, MI_HUGE_OS_PAGE_SIZE); // check for timeout if (max_msecs > 0) { mi_msecs_t elapsed = _mi_clock_end(start_t); if (page >= 1) { mi_msecs_t estimate = ((elapsed / (page+1)) * pages); if (estimate > 2*max_msecs) { // seems like we are going to timeout, break elapsed = max_msecs + 1; } } if (elapsed > max_msecs) { _mi_warning_message("huge page allocation timed out\n"); break; } } } mi_assert_internal(page*MI_HUGE_OS_PAGE_SIZE <= size); if (pages_reserved != NULL) *pages_reserved = page; if (psize != NULL) *psize = page * MI_HUGE_OS_PAGE_SIZE; return (page == 0 ? NULL : start); } // free every huge page in a range individually (as we allocated per page) // note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems. void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats) { if (p==NULL || size==0) return; uint8_t* base = (uint8_t*)p; while (size >= MI_HUGE_OS_PAGE_SIZE) { _mi_os_free(base, MI_HUGE_OS_PAGE_SIZE, stats); size -= MI_HUGE_OS_PAGE_SIZE; } } /* ---------------------------------------------------------------------------- Support NUMA aware allocation -----------------------------------------------------------------------------*/ #ifdef _WIN32 static size_t mi_os_numa_nodex() { USHORT numa_node = 0; if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) { // Extended API is supported PROCESSOR_NUMBER pnum; (*pGetCurrentProcessorNumberEx)(&pnum); USHORT nnode = 0; BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode); if (ok) numa_node = nnode; } else { // Vista or earlier, use older API that is limited to 64 processors. Issue #277 DWORD pnum = GetCurrentProcessorNumber(); UCHAR nnode = 0; BOOL ok = GetNumaProcessorNode((UCHAR)pnum, &nnode); if (ok) numa_node = nnode; } return numa_node; } static size_t mi_os_numa_node_countx(void) { ULONG numa_max = 0; GetNumaHighestNodeNumber(&numa_max); // find the highest node number that has actual processors assigned to it. Issue #282 while(numa_max > 0) { if (pGetNumaNodeProcessorMaskEx != NULL) { // Extended API is supported GROUP_AFFINITY affinity; if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) { if (affinity.Mask != 0) break; // found the maximum non-empty node } } else { // Vista or earlier, use older API that is limited to 64 processors. ULONGLONG mask; if (GetNumaNodeProcessorMask((UCHAR)numa_max, &mask)) { if (mask != 0) break; // found the maximum non-empty node }; } // max node was invalid or had no processor assigned, try again numa_max--; } return ((size_t)numa_max + 1); } #elif defined(__linux__) #include // getcpu #include // access static size_t mi_os_numa_nodex(void) { #ifdef SYS_getcpu unsigned long node = 0; unsigned long ncpu = 0; long err = syscall(SYS_getcpu, &ncpu, &node, NULL); if (err != 0) return 0; return node; #else return 0; #endif } static size_t mi_os_numa_node_countx(void) { char buf[128]; unsigned node = 0; for(node = 0; node < 256; node++) { // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation) snprintf(buf, 127, "/sys/devices/system/node/node%u", node + 1); if (access(buf,R_OK) != 0) break; } return (node+1); } #else static size_t mi_os_numa_nodex(void) { return 0; } static size_t mi_os_numa_node_countx(void) { return 1; } #endif size_t _mi_numa_node_count = 0; // cache the node count size_t _mi_os_numa_node_count_get(void) { if (mi_unlikely(_mi_numa_node_count <= 0)) { long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly? if (ncount <= 0) ncount = (long)mi_os_numa_node_countx(); // or detect dynamically _mi_numa_node_count = (size_t)(ncount <= 0 ? 1 : ncount); _mi_verbose_message("using %zd numa regions\n", _mi_numa_node_count); } mi_assert_internal(_mi_numa_node_count >= 1); return _mi_numa_node_count; } int _mi_os_numa_node_get(mi_os_tld_t* tld) { UNUSED(tld); size_t numa_count = _mi_os_numa_node_count(); if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0 // never more than the node count and >= 0 size_t numa_node = mi_os_numa_nodex(); if (numa_node >= numa_count) { numa_node = numa_node % numa_count; } return (int)numa_node; } ================================================ FILE: runtime/src/mimalloc/c/page-queue.c ================================================ /*---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ /* ----------------------------------------------------------- Definition of page queues for each block size ----------------------------------------------------------- */ #ifndef MI_IN_PAGE_C #error "this file should be included from 'page.c'" #endif /* ----------------------------------------------------------- Minimal alignment in machine words (i.e. `sizeof(void*)`) ----------------------------------------------------------- */ #if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE) #error "define alignment for more than 4x word size for this platform" #elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE) #define MI_ALIGN4W // 4 machine words minimal alignment #elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE) #define MI_ALIGN2W // 2 machine words minimal alignment #else // ok, default alignment is 1 word #endif /* ----------------------------------------------------------- Queue query ----------------------------------------------------------- */ static inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) { return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+sizeof(uintptr_t))); } static inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) { return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+(2*sizeof(uintptr_t)))); } static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) { return (pq->block_size > MI_LARGE_OBJ_SIZE_MAX); } /* ----------------------------------------------------------- Bins ----------------------------------------------------------- */ // Bit scan reverse: return the index of the highest bit. static inline uint8_t mi_bsr32(uint32_t x); #if defined(_MSC_VER) #include static inline uint8_t mi_bsr32(uint32_t x) { uint32_t idx; _BitScanReverse((DWORD*)&idx, x); return (uint8_t)idx; } #elif defined(__GNUC__) || defined(__clang__) static inline uint8_t mi_bsr32(uint32_t x) { return (31 - __builtin_clz(x)); } #else static inline uint8_t mi_bsr32(uint32_t x) { // de Bruijn multiplication, see static const uint8_t debruijn[32] = { 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12, 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13, }; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x++; return debruijn[(x*0x076be629) >> 27]; } #endif // Bit scan reverse: return the index of the highest bit. uint8_t _mi_bsr(uintptr_t x) { if (x == 0) return 0; #if MI_INTPTR_SIZE==8 uint32_t hi = (x >> 32); return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); #elif MI_INTPTR_SIZE==4 return mi_bsr32(x); #else # error "define bsr for non-32 or 64-bit platforms" #endif } // Return the bin for a given field size. // Returns MI_BIN_HUGE if the size is too large. // We use `wsize` for the size in "machine word sizes", // i.e. byte size == `wsize*sizeof(void*)`. extern inline uint8_t _mi_bin(size_t size) { size_t wsize = _mi_wsize_from_size(size); uint8_t bin; if (wsize <= 1) { bin = 1; } #if defined(MI_ALIGN4W) else if (wsize <= 4) { bin = (uint8_t)((wsize+1)&~1); // round to double word sizes } #elif defined(MI_ALIGN2W) else if (wsize <= 8) { bin = (uint8_t)((wsize+1)&~1); // round to double word sizes } #else else if (wsize <= 8) { bin = (uint8_t)wsize; } #endif else if (wsize > MI_LARGE_OBJ_WSIZE_MAX) { bin = MI_BIN_HUGE; } else { #if defined(MI_ALIGN4W) if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes #endif wsize--; // find the highest bit uint8_t b = mi_bsr32((uint32_t)wsize); // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). // - adjust with 3 because we use do not round the first 8 sizes // which each get an exact bin bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; mi_assert_internal(bin < MI_BIN_HUGE); } mi_assert_internal(bin > 0 && bin <= MI_BIN_HUGE); return bin; } /* ----------------------------------------------------------- Queue of pages with free blocks ----------------------------------------------------------- */ size_t _mi_bin_size(uint8_t bin) { return _mi_heap_empty.pages[bin].block_size; } // Good size for allocation size_t mi_good_size(size_t size) mi_attr_noexcept { if (size <= MI_LARGE_OBJ_SIZE_MAX) { return _mi_bin_size(_mi_bin(size)); } else { return _mi_align_up(size,_mi_os_page_size()); } } #if (MI_DEBUG>1) static bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) { mi_assert_internal(page != NULL); mi_page_t* list = queue->first; while (list != NULL) { mi_assert_internal(list->next == NULL || list->next->prev == list); mi_assert_internal(list->prev == NULL || list->prev->next == list); if (list == page) break; list = list->next; } return (list == page); } #endif #if (MI_DEBUG>1) static bool mi_heap_contains_queue(const mi_heap_t* heap, const mi_page_queue_t* pq) { return (pq >= &heap->pages[0] && pq <= &heap->pages[MI_BIN_FULL]); } #endif static mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) { uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size)); mi_heap_t* heap = mi_page_heap(page); mi_assert_internal(heap != NULL && bin <= MI_BIN_FULL); mi_page_queue_t* pq = &heap->pages[bin]; mi_assert_internal(bin >= MI_BIN_HUGE || page->xblock_size == pq->block_size); mi_assert_expensive(mi_page_queue_contains(pq, page)); return pq; } static mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) { uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size)); mi_assert_internal(bin <= MI_BIN_FULL); mi_page_queue_t* pq = &heap->pages[bin]; mi_assert_internal(mi_page_is_in_full(page) || page->xblock_size == pq->block_size); return pq; } // The current small page array is for efficiency and for each // small size (up to 256) it points directly to the page for that // size without having to compute the bin. This means when the // current free page queue is updated for a small bin, we need to update a // range of entries in `_mi_page_small_free`. static inline void mi_heap_queue_first_update(mi_heap_t* heap, const mi_page_queue_t* pq) { mi_assert_internal(mi_heap_contains_queue(heap,pq)); size_t size = pq->block_size; if (size > MI_SMALL_SIZE_MAX) return; mi_page_t* page = pq->first; if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty; // find index in the right direct page array size_t start; size_t idx = _mi_wsize_from_size(size); mi_page_t** pages_free = heap->pages_free_direct; if (pages_free[idx] == page) return; // already set // find start slot if (idx<=1) { start = 0; } else { // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped uint8_t bin = _mi_bin(size); const mi_page_queue_t* prev = pq - 1; while( bin == _mi_bin(prev->block_size) && prev > &heap->pages[0]) { prev--; } start = 1 + _mi_wsize_from_size(prev->block_size); if (start > idx) start = idx; } // set size range to the right page mi_assert(start <= idx); for (size_t sz = start; sz <= idx; sz++) { pages_free[sz] = page; } } /* static bool mi_page_queue_is_empty(mi_page_queue_t* queue) { return (queue->first == NULL); } */ static void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) { mi_assert_internal(page != NULL); mi_assert_expensive(mi_page_queue_contains(queue, page)); mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); mi_heap_t* heap = mi_page_heap(page); if (page->prev != NULL) page->prev->next = page->next; if (page->next != NULL) page->next->prev = page->prev; if (page == queue->last) queue->last = page->prev; if (page == queue->first) { queue->first = page->next; // update first mi_assert_internal(mi_heap_contains_queue(heap, queue)); mi_heap_queue_first_update(heap,queue); } heap->page_count--; page->next = NULL; page->prev = NULL; // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), NULL); mi_page_set_in_full(page,false); } static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) { mi_assert_internal(mi_page_heap(page) == heap); mi_assert_internal(!mi_page_queue_contains(queue, page)); mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE); mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); mi_page_set_in_full(page, mi_page_queue_is_full(queue)); // mi_atomic_store_ptr_release(mi_atomic_cast(void*, &page->heap), heap); page->next = queue->first; page->prev = NULL; if (queue->first != NULL) { mi_assert_internal(queue->first->prev == NULL); queue->first->prev = page; queue->first = page; } else { queue->first = queue->last = page; } // update direct mi_heap_queue_first_update(heap, queue); heap->page_count++; } static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) { mi_assert_internal(page != NULL); mi_assert_expensive(mi_page_queue_contains(from, page)); mi_assert_expensive(!mi_page_queue_contains(to, page)); mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) || (page->xblock_size == to->block_size && mi_page_queue_is_full(from)) || (page->xblock_size == from->block_size && mi_page_queue_is_full(to)) || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(to)) || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_full(to))); mi_heap_t* heap = mi_page_heap(page); if (page->prev != NULL) page->prev->next = page->next; if (page->next != NULL) page->next->prev = page->prev; if (page == from->last) from->last = page->prev; if (page == from->first) { from->first = page->next; // update first mi_assert_internal(mi_heap_contains_queue(heap, from)); mi_heap_queue_first_update(heap, from); } page->prev = to->last; page->next = NULL; if (to->last != NULL) { mi_assert_internal(heap == mi_page_heap(to->last)); to->last->next = page; to->last = page; } else { to->first = page; to->last = page; mi_heap_queue_first_update(heap, to); } mi_page_set_in_full(page, mi_page_queue_is_full(to)); } // Only called from `mi_heap_absorb`. size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) { mi_assert_internal(mi_heap_contains_queue(heap,pq)); mi_assert_internal(pq->block_size == append->block_size); if (append->first==NULL) return 0; // set append pages to new heap and count size_t count = 0; for (mi_page_t* page = append->first; page != NULL; page = page->next) { // inline `mi_page_set_heap` to avoid wrong assertion during absorption; // in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive. mi_atomic_store_release(&page->xheap, (uintptr_t)heap); // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a // side effect that it spins until any DELAYED_FREEING is finished. This ensures // that after appending only the new heap will be used for delayed free operations. _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false); count++; } if (pq->last==NULL) { // take over afresh mi_assert_internal(pq->first==NULL); pq->first = append->first; pq->last = append->last; mi_heap_queue_first_update(heap, pq); } else { // append to end mi_assert_internal(pq->last!=NULL); mi_assert_internal(append->first!=NULL); pq->last->next = append->first; append->first->prev = pq->last; pq->last = append->last; } return count; } ================================================ FILE: runtime/src/mimalloc/c/page.c ================================================ /*---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ /* ----------------------------------------------------------- The core of the allocator. Every segment contains pages of a {certain block size. The main function exported is `mi_malloc_generic`. ----------------------------------------------------------- */ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" /* ----------------------------------------------------------- Definition of page queues for each block size ----------------------------------------------------------- */ #define MI_IN_PAGE_C #include "page-queue.c" #undef MI_IN_PAGE_C /* ----------------------------------------------------------- Page helpers ----------------------------------------------------------- */ // Index a block in a page static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) { UNUSED(page); mi_assert_internal(page != NULL); mi_assert_internal(i <= page->reserved); return (mi_block_t*)((uint8_t*)page_start + (i * block_size)); } static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld); static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld); #if (MI_DEBUG>=3) static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) { size_t count = 0; while (head != NULL) { mi_assert_internal(page == _mi_ptr_page(head)); count++; head = mi_block_next(page, head); } return count; } /* // Start of the page available memory static inline uint8_t* mi_page_area(const mi_page_t* page) { return _mi_page_start(_mi_page_segment(page), page, NULL); } */ static bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) { size_t psize; uint8_t* page_area = _mi_page_start(_mi_page_segment(page), page, &psize); mi_block_t* start = (mi_block_t*)page_area; mi_block_t* end = (mi_block_t*)(page_area + psize); while(p != NULL) { if (p < start || p >= end) return false; p = mi_block_next(page, p); } return true; } static bool mi_page_is_valid_init(mi_page_t* page) { mi_assert_internal(page->xblock_size > 0); mi_assert_internal(page->used <= page->capacity); mi_assert_internal(page->capacity <= page->reserved); const size_t bsize = mi_page_block_size(page); mi_segment_t* segment = _mi_page_segment(page); uint8_t* start = _mi_page_start(segment,page,NULL); mi_assert_internal(start == _mi_segment_page_start(segment,page,bsize,NULL,NULL)); //mi_assert_internal(start + page->capacity*page->block_size == page->top); mi_assert_internal(mi_page_list_is_valid(page,page->free)); mi_assert_internal(mi_page_list_is_valid(page,page->local_free)); #if MI_DEBUG>3 // generally too expensive to check this if (page->flags.is_zero) { for(mi_block_t* block = page->free; block != NULL; mi_block_next(page,block)) { mi_assert_expensive(mi_mem_is_zero(block + 1, page->block_size - sizeof(mi_block_t))); } } #endif mi_block_t* tfree = mi_page_thread_free(page); mi_assert_internal(mi_page_list_is_valid(page, tfree)); //size_t tfree_count = mi_page_list_count(page, tfree); //mi_assert_internal(tfree_count <= page->thread_freed + 1); size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free); mi_assert_internal(page->used + free_count == page->capacity); return true; } bool _mi_page_is_valid(mi_page_t* page) { mi_assert_internal(mi_page_is_valid_init(page)); #if MI_SECURE mi_assert_internal(page->keys[0] != 0); #endif if (mi_page_heap(page)!=NULL) { mi_segment_t* segment = _mi_page_segment(page); mi_assert_internal(!_mi_process_is_initialized || segment->thread_id == mi_page_heap(page)->thread_id || segment->thread_id==0); if (segment->page_kind != MI_PAGE_HUGE) { mi_page_queue_t* pq = mi_page_queue_of(page); mi_assert_internal(mi_page_queue_contains(pq, page)); mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_LARGE_OBJ_SIZE_MAX || mi_page_is_in_full(page)); mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq)); } } return true; } #endif void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { mi_thread_free_t tfreex; mi_delayed_t old_delay; mi_thread_free_t tfree; do { tfree = mi_atomic_load_acquire(&page->xthread_free); // note: must acquire as we can break/repeat this loop and not do a CAS; tfreex = mi_tf_set_delayed(tfree, delay); old_delay = mi_tf_delayed(tfree); if (mi_unlikely(old_delay == MI_DELAYED_FREEING)) { mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done. // tfree = mi_tf_set_delayed(tfree, MI_NO_DELAYED_FREE); // will cause CAS to busy fail } else if (delay == old_delay) { break; // avoid atomic operation if already equal } else if (!override_never && old_delay == MI_NEVER_DELAYED_FREE) { break; // leave never-delayed flag set } } while ((old_delay == MI_DELAYED_FREEING) || !mi_atomic_cas_weak_release(&page->xthread_free, &tfree, tfreex)); } /* ----------------------------------------------------------- Page collect the `local_free` and `thread_free` lists ----------------------------------------------------------- */ // Collect the local `thread_free` list using an atomic exchange. // Note: The exchange must be done atomically as this is used right after // moving to the full list in `mi_page_collect_ex` and we need to // ensure that there was no race where the page became unfull just before the move. static void _mi_page_thread_free_collect(mi_page_t* page) { mi_block_t* head; mi_thread_free_t tfreex; mi_thread_free_t tfree = mi_atomic_load_relaxed(&page->xthread_free); do { head = mi_tf_block(tfree); tfreex = mi_tf_set_block(tfree,NULL); } while (!mi_atomic_cas_weak_acq_rel(&page->xthread_free, &tfree, tfreex)); // return if the list is empty if (head == NULL) return; // find the tail -- also to get a proper count (without data races) uint32_t max_count = page->capacity; // cannot collect more than capacity uint32_t count = 1; mi_block_t* tail = head; mi_block_t* next; while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) { count++; tail = next; } // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free) if (count > max_count) { _mi_error_message(EFAULT, "corrupted thread-free list\n"); return; // the thread-free items cannot be freed } // and append the current local free list mi_block_set_next(page,tail, page->local_free); page->local_free = head; // update counts now page->used -= count; } void _mi_page_free_collect(mi_page_t* page, bool force) { mi_assert_internal(page!=NULL); // collect the thread free list if (force || mi_page_thread_free(page) != NULL) { // quick test to avoid an atomic operation _mi_page_thread_free_collect(page); } // and the local free list if (page->local_free != NULL) { if (mi_likely(page->free == NULL)) { // usual case page->free = page->local_free; page->local_free = NULL; page->is_zero = false; } else if (force) { // append -- only on shutdown (force) as this is a linear operation mi_block_t* tail = page->local_free; mi_block_t* next; while ((next = mi_block_next(page, tail)) != NULL) { tail = next; } mi_block_set_next(page, tail, page->free); page->free = page->local_free; page->local_free = NULL; page->is_zero = false; } } mi_assert_internal(!force || page->local_free == NULL); } /* ----------------------------------------------------------- Page fresh and retire ----------------------------------------------------------- */ // called from segments when reclaiming abandoned pages void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) { mi_assert_expensive(mi_page_is_valid_init(page)); mi_assert_internal(mi_page_heap(page) == heap); mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE); mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE); mi_assert_internal(!page->is_reset); // TODO: push on full queue immediately if it is full? mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page)); mi_page_queue_push(heap, pq, page); mi_assert_expensive(_mi_page_is_valid(page)); } // allocate a fresh page from a segment static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size) { mi_assert_internal(pq==NULL||mi_heap_contains_queue(heap, pq)); mi_assert_internal(pq==NULL||block_size == pq->block_size); mi_page_t* page = _mi_segment_page_alloc(heap, block_size, &heap->tld->segments, &heap->tld->os); if (page == NULL) { // this may be out-of-memory, or an abandoned page was reclaimed (and in our queue) return NULL; } // a fresh page was found, initialize it mi_assert_internal(pq==NULL || _mi_page_segment(page)->page_kind != MI_PAGE_HUGE); mi_page_init(heap, page, block_size, heap->tld); _mi_stat_increase(&heap->tld->stats.pages, 1); if (pq!=NULL) mi_page_queue_push(heap, pq, page); // huge pages use pq==NULL mi_assert_expensive(_mi_page_is_valid(page)); return page; } // Get a fresh page to use static mi_page_t* mi_page_fresh(mi_heap_t* heap, mi_page_queue_t* pq) { mi_assert_internal(mi_heap_contains_queue(heap, pq)); mi_page_t* page = mi_page_fresh_alloc(heap, pq, pq->block_size); if (page==NULL) return NULL; mi_assert_internal(pq->block_size==mi_page_block_size(page)); mi_assert_internal(pq==mi_page_queue(heap, mi_page_block_size(page))); return page; } /* ----------------------------------------------------------- Do any delayed frees (put there by other threads if they deallocated in a full page) ----------------------------------------------------------- */ void _mi_heap_delayed_free(mi_heap_t* heap) { // take over the list (note: no atomic exchange since it is often NULL) mi_block_t* block = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); while (block != NULL && !mi_atomic_cas_ptr_weak_acq_rel(mi_block_t, &heap->thread_delayed_free, &block, NULL)) { /* nothing */ }; // and free them all while(block != NULL) { mi_block_t* next = mi_block_nextx(heap,block, heap->keys); // use internal free instead of regular one to keep stats etc correct if (!_mi_free_delayed_block(block)) { // we might already start delayed freeing while another thread has not yet // reset the delayed_freeing flag; in that case delay it further by reinserting. mi_block_t* dfree = mi_atomic_load_ptr_relaxed(mi_block_t, &heap->thread_delayed_free); do { mi_block_set_nextx(heap, block, dfree, heap->keys); } while (!mi_atomic_cas_ptr_weak_release(mi_block_t,&heap->thread_delayed_free, &dfree, block)); } block = next; } } /* ----------------------------------------------------------- Unfull, abandon, free and retire ----------------------------------------------------------- */ // Move a page from the full list back to a regular list void _mi_page_unfull(mi_page_t* page) { mi_assert_internal(page != NULL); mi_assert_expensive(_mi_page_is_valid(page)); mi_assert_internal(mi_page_is_in_full(page)); if (!mi_page_is_in_full(page)) return; mi_heap_t* heap = mi_page_heap(page); mi_page_queue_t* pqfull = &heap->pages[MI_BIN_FULL]; mi_page_set_in_full(page, false); // to get the right queue mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page); mi_page_set_in_full(page, true); mi_page_queue_enqueue_from(pq, pqfull, page); } static void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) { mi_assert_internal(pq == mi_page_queue_of(page)); mi_assert_internal(!mi_page_immediate_available(page)); mi_assert_internal(!mi_page_is_in_full(page)); if (mi_page_is_in_full(page)) return; mi_page_queue_enqueue_from(&mi_page_heap(page)->pages[MI_BIN_FULL], pq, page); _mi_page_free_collect(page,false); // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set } // Abandon a page with used blocks at the end of a thread. // Note: only call if it is ensured that no references exist from // the `page->heap->thread_delayed_free` into this page. // Currently only called through `mi_heap_collect_ex` which ensures this. void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) { mi_assert_internal(page != NULL); mi_assert_expensive(_mi_page_is_valid(page)); mi_assert_internal(pq == mi_page_queue_of(page)); mi_assert_internal(mi_page_heap(page) != NULL); mi_heap_t* pheap = mi_page_heap(page); // remove from our page list mi_segments_tld_t* segments_tld = &pheap->tld->segments; mi_page_queue_remove(pq, page); // page is no longer associated with our heap mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); mi_page_set_heap(page, NULL); #if MI_DEBUG>1 // check there are no references left.. for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) { mi_assert_internal(_mi_ptr_page(block) != page); } #endif // and abandon it mi_assert_internal(mi_page_heap(page) == NULL); _mi_segment_page_abandon(page,segments_tld); } // Free a page with no more free blocks void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { mi_assert_internal(page != NULL); mi_assert_expensive(_mi_page_is_valid(page)); mi_assert_internal(pq == mi_page_queue_of(page)); mi_assert_internal(mi_page_all_free(page)); mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING); // no more aligned blocks in here mi_page_set_has_aligned(page, false); // remove from the page list // (no need to do _mi_heap_delayed_free first as all blocks are already free) mi_segments_tld_t* segments_tld = &mi_page_heap(page)->tld->segments; mi_page_queue_remove(pq, page); // and free it mi_page_set_heap(page,NULL); _mi_segment_page_free(page, force, segments_tld); } #define MI_MAX_RETIRE_SIZE MI_LARGE_OBJ_SIZE_MAX #define MI_RETIRE_CYCLES (8) // Retire a page with no more used blocks // Important to not retire too quickly though as new // allocations might coming. // Note: called from `mi_free` and benchmarks often // trigger this due to freeing everything and then // allocating again so careful when changing this. void _mi_page_retire(mi_page_t* page) { mi_assert_internal(page != NULL); mi_assert_expensive(_mi_page_is_valid(page)); mi_assert_internal(mi_page_all_free(page)); mi_page_set_has_aligned(page, false); // don't retire too often.. // (or we end up retiring and re-allocating most of the time) // NOTE: refine this more: we should not retire if this // is the only page left with free blocks. It is not clear // how to check this efficiently though... // for now, we don't retire if it is the only page left of this size class. mi_page_queue_t* pq = mi_page_queue_of(page); if (mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_is_in_full(page))) { if (pq->last==page && pq->first==page) { // the only page in the queue? mi_stat_counter_increase(_mi_stats_main.page_no_retire,1); page->retire_expire = (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4); mi_heap_t* heap = mi_page_heap(page); mi_assert_internal(pq >= heap->pages); const size_t index = pq - heap->pages; mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE); if (index < heap->page_retired_min) heap->page_retired_min = index; if (index > heap->page_retired_max) heap->page_retired_max = index; mi_assert_internal(mi_page_all_free(page)); return; // dont't free after all } } _mi_page_free(page, pq, false); } // free retired pages: we don't need to look at the entire queues // since we only retire pages that are at the head position in a queue. void _mi_heap_collect_retired(mi_heap_t* heap, bool force) { size_t min = MI_BIN_FULL; size_t max = 0; for(size_t bin = heap->page_retired_min; bin <= heap->page_retired_max; bin++) { mi_page_queue_t* pq = &heap->pages[bin]; mi_page_t* page = pq->first; if (page != NULL && page->retire_expire != 0) { if (mi_page_all_free(page)) { page->retire_expire--; if (force || page->retire_expire == 0) { _mi_page_free(pq->first, pq, force); } else { // keep retired, update min/max if (bin < min) min = bin; if (bin > max) max = bin; } } else { page->retire_expire = 0; } } } heap->page_retired_min = min; heap->page_retired_max = max; } /* ----------------------------------------------------------- Initialize the initial free list in a page. In secure mode we initialize a randomized list by alternating between slices. ----------------------------------------------------------- */ #define MI_MAX_SLICE_SHIFT (6) // at most 64 slices #define MI_MAX_SLICES (1UL << MI_MAX_SLICE_SHIFT) #define MI_MIN_SLICES (2) static void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) { UNUSED(stats); #if (MI_SECURE<=2) mi_assert_internal(page->free == NULL); mi_assert_internal(page->local_free == NULL); #endif mi_assert_internal(page->capacity + extend <= page->reserved); mi_assert_internal(bsize == mi_page_block_size(page)); void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL); // initialize a randomized free list // set up `slice_count` slices to alternate between size_t shift = MI_MAX_SLICE_SHIFT; while ((extend >> shift) == 0) { shift--; } const size_t slice_count = (size_t)1U << shift; const size_t slice_extend = extend / slice_count; mi_assert_internal(slice_extend >= 1); mi_block_t* blocks[MI_MAX_SLICES]; // current start of the slice size_t counts[MI_MAX_SLICES]; // available objects in the slice for (size_t i = 0; i < slice_count; i++) { blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend); counts[i] = slice_extend; } counts[slice_count-1] += (extend % slice_count); // final slice holds the modulus too (todo: distribute evenly?) // and initialize the free list by randomly threading through them // set up first element const uintptr_t r = _mi_heap_random_next(heap); size_t current = r % slice_count; counts[current]--; mi_block_t* const free_start = blocks[current]; // and iterate through the rest; use `random_shuffle` for performance uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0 for (size_t i = 1; i < extend; i++) { // call random_shuffle only every INTPTR_SIZE rounds const size_t round = i%MI_INTPTR_SIZE; if (round == 0) rnd = _mi_random_shuffle(rnd); // select a random next slice index size_t next = ((rnd >> 8*round) & (slice_count-1)); while (counts[next]==0) { // ensure it still has space next++; if (next==slice_count) next = 0; } // and link the current block to it counts[next]--; mi_block_t* const block = blocks[current]; blocks[current] = (mi_block_t*)((uint8_t*)block + bsize); // bump to the following block mi_block_set_next(page, block, blocks[next]); // and set next; note: we may have `current == next` current = next; } // prepend to the free list (usually NULL) mi_block_set_next(page, blocks[current], page->free); // end of the list page->free = free_start; } static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) { UNUSED(stats); #if (MI_SECURE <= 2) mi_assert_internal(page->free == NULL); mi_assert_internal(page->local_free == NULL); #endif mi_assert_internal(page->capacity + extend <= page->reserved); mi_assert_internal(bsize == mi_page_block_size(page)); void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL ); mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity); // initialize a sequential free list mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1); mi_block_t* block = start; while(block <= last) { mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize); mi_block_set_next(page,block,next); block = next; } // prepend to free list (usually `NULL`) mi_block_set_next(page, last, page->free); page->free = start; } /* ----------------------------------------------------------- Page initialize and extend the capacity ----------------------------------------------------------- */ #define MI_MAX_EXTEND_SIZE (4*1024) // heuristic, one OS page seems to work well. #if (MI_SECURE>0) #define MI_MIN_EXTEND (8*MI_SECURE) // extend at least by this many #else #define MI_MIN_EXTEND (1) #endif // Extend the capacity (up to reserved) by initializing a free list // We do at most `MI_MAX_EXTEND` to avoid touching too much memory // Note: we also experimented with "bump" allocation on the first // allocations but this did not speed up any benchmark (due to an // extra test in malloc? or cache effects?) static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) { mi_assert_expensive(mi_page_is_valid_init(page)); #if (MI_SECURE<=2) mi_assert(page->free == NULL); mi_assert(page->local_free == NULL); if (page->free != NULL) return; #endif if (page->capacity >= page->reserved) return; size_t page_size; //uint8_t* page_start = _mi_page_start(_mi_page_segment(page), page, &page_size); mi_stat_counter_increase(tld->stats.pages_extended, 1); // calculate the extend count const size_t bsize = (page->xblock_size < MI_HUGE_BLOCK_SIZE ? page->xblock_size : page_size); size_t extend = page->reserved - page->capacity; size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize); if (max_extend < MI_MIN_EXTEND) max_extend = MI_MIN_EXTEND; if (extend > max_extend) { // ensure we don't touch memory beyond the page to reduce page commit. // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%. extend = (max_extend==0 ? 1 : max_extend); } mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved); mi_assert_internal(extend < (1UL<<16)); // and append the extend the free list if (extend < MI_MIN_SLICES || MI_SECURE==0) { //!mi_option_is_enabled(mi_option_secure)) { mi_page_free_list_extend(page, bsize, extend, &tld->stats ); } else { mi_page_free_list_extend_secure(heap, page, bsize, extend, &tld->stats); } // enable the new free list page->capacity += (uint16_t)extend; mi_stat_increase(tld->stats.page_committed, extend * bsize); // extension into zero initialized memory preserves the zero'd free list if (!page->is_zero_init) { page->is_zero = false; } mi_assert_expensive(mi_page_is_valid_init(page)); } // Initialize a fresh page static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi_tld_t* tld) { mi_assert(page != NULL); mi_segment_t* segment = _mi_page_segment(page); mi_assert(segment != NULL); mi_assert_internal(block_size > 0); // set fields mi_page_set_heap(page, heap); size_t page_size; _mi_segment_page_start(segment, page, block_size, &page_size, NULL); page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE); mi_assert_internal(page_size / block_size < (1L<<16)); page->reserved = (uint16_t)(page_size / block_size); #ifdef MI_ENCODE_FREELIST page->keys[0] = _mi_heap_random_next(heap); page->keys[1] = _mi_heap_random_next(heap); #endif page->is_zero = page->is_zero_init; mi_assert_internal(page->capacity == 0); mi_assert_internal(page->free == NULL); mi_assert_internal(page->used == 0); mi_assert_internal(page->xthread_free == 0); mi_assert_internal(page->next == NULL); mi_assert_internal(page->prev == NULL); mi_assert_internal(page->retire_expire == 0); mi_assert_internal(!mi_page_has_aligned(page)); #if (MI_ENCODE_FREELIST) mi_assert_internal(page->keys[0] != 0); mi_assert_internal(page->keys[1] != 0); #endif mi_assert_expensive(mi_page_is_valid_init(page)); // initialize an initial free list mi_page_extend_free(heap,page,tld); mi_assert(mi_page_immediate_available(page)); } /* ----------------------------------------------------------- Find pages with free blocks -------------------------------------------------------------*/ // Find a page with free blocks of `page->block_size`. static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try) { // search through the pages in "next fit" order size_t count = 0; mi_page_t* page = pq->first; while (page != NULL) { mi_page_t* next = page->next; // remember next count++; // 0. collect freed blocks by us and other threads _mi_page_free_collect(page, false); // 1. if the page contains free blocks, we are done if (mi_page_immediate_available(page)) { break; // pick this one } // 2. Try to extend if (page->capacity < page->reserved) { mi_page_extend_free(heap, page, heap->tld); mi_assert_internal(mi_page_immediate_available(page)); break; } // 3. If the page is completely full, move it to the `mi_pages_full` // queue so we don't visit long-lived pages too often. mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page)); mi_page_to_full(page, pq); page = next; } // for each page mi_stat_counter_increase(heap->tld->stats.searches, count); if (page == NULL) { _mi_heap_collect_retired(heap, false); // perhaps make a page available page = mi_page_fresh(heap, pq); if (page == NULL && first_try) { // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again page = mi_page_queue_find_free_ex(heap, pq, false); } } else { mi_assert(pq->first == page); page->retire_expire = 0; } mi_assert_internal(page == NULL || mi_page_immediate_available(page)); return page; } // Find a page with free blocks of `size`. static inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) { mi_page_queue_t* pq = mi_page_queue(heap,size); mi_page_t* page = pq->first; if (page != NULL) { if ((MI_SECURE >= 3) && page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) { // in secure mode, we extend half the time to increase randomness mi_page_extend_free(heap, page, heap->tld); mi_assert_internal(mi_page_immediate_available(page)); } else { _mi_page_free_collect(page,false); } if (mi_page_immediate_available(page)) { page->retire_expire = 0; return page; // fast path } } return mi_page_queue_find_free_ex(heap, pq, true); } /* ----------------------------------------------------------- Users can register a deferred free function called when the `free` list is empty. Since the `local_free` is separate this is deterministically called after a certain number of allocations. ----------------------------------------------------------- */ static mi_deferred_free_fun* volatile deferred_free = NULL; static _Atomic(void*) deferred_arg; // = NULL void _mi_deferred_free(mi_heap_t* heap, bool force) { heap->tld->heartbeat++; if (deferred_free != NULL && !heap->tld->recurse) { heap->tld->recurse = true; deferred_free(force, heap->tld->heartbeat, mi_atomic_load_ptr_relaxed(void,&deferred_arg)); heap->tld->recurse = false; } } void mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept { deferred_free = fn; mi_atomic_store_ptr_release(void,&deferred_arg, arg); } /* ----------------------------------------------------------- General allocation ----------------------------------------------------------- */ // A huge page is allocated directly without being in a queue. // Because huge pages contain just one block, and the segment contains // just that page, we always treat them as abandoned and any thread // that frees the block can free the whole page and segment directly. static mi_page_t* mi_huge_page_alloc(mi_heap_t* heap, size_t size) { size_t block_size = _mi_os_good_alloc_size(size); mi_assert_internal(_mi_bin(block_size) == MI_BIN_HUGE); mi_page_t* page = mi_page_fresh_alloc(heap,NULL,block_size); if (page != NULL) { const size_t bsize = mi_page_block_size(page); // note: not `mi_page_usable_block_size` as `size` includes padding already mi_assert_internal(bsize >= size); mi_assert_internal(mi_page_immediate_available(page)); mi_assert_internal(_mi_page_segment(page)->page_kind==MI_PAGE_HUGE); mi_assert_internal(_mi_page_segment(page)->used==1); mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue mi_page_set_heap(page, NULL); if (bsize > MI_HUGE_OBJ_SIZE_MAX) { _mi_stat_increase(&heap->tld->stats.giant, bsize); _mi_stat_counter_increase(&heap->tld->stats.giant_count, 1); } else { _mi_stat_increase(&heap->tld->stats.huge, bsize); _mi_stat_counter_increase(&heap->tld->stats.huge_count, 1); } } return page; } // Allocate a page // Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. static mi_page_t* mi_find_page(mi_heap_t* heap, size_t size) mi_attr_noexcept { // huge allocation? const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` if (mi_unlikely(req_size > (MI_LARGE_OBJ_SIZE_MAX - MI_PADDING_SIZE) )) { if (mi_unlikely(req_size > PTRDIFF_MAX)) { // we don't allocate more than PTRDIFF_MAX (see ) _mi_error_message(EOVERFLOW, "allocation request is too large (%zu bytes)\n", req_size); return NULL; } else { return mi_huge_page_alloc(heap,size); } } else { // otherwise find a page with free blocks in our size segregated queues mi_assert_internal(size >= MI_PADDING_SIZE); return mi_find_free_page(heap, size); } } // Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed. // Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. void* _mi_malloc_generic(mi_heap_t* heap, size_t size) mi_attr_noexcept { mi_assert_internal(heap != NULL); // initialize if necessary if (mi_unlikely(!mi_heap_is_initialized(heap))) { mi_thread_init(); // calls `_mi_heap_init` in turn heap = mi_get_default_heap(); if (mi_unlikely(!mi_heap_is_initialized(heap))) { return NULL; } } mi_assert_internal(mi_heap_is_initialized(heap)); // call potential deferred free routines _mi_deferred_free(heap, false); // free delayed frees from other threads _mi_heap_delayed_free(heap); // find (or allocate) a page of the right size mi_page_t* page = mi_find_page(heap, size); if (mi_unlikely(page == NULL)) { // first time out of memory, try to collect and retry the allocation once more mi_heap_collect(heap, true /* force */); page = mi_find_page(heap, size); } if (mi_unlikely(page == NULL)) { // out of memory const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` _mi_error_message(ENOMEM, "unable to allocate memory (%zu bytes)\n", req_size); return NULL; } mi_assert_internal(mi_page_immediate_available(page)); mi_assert_internal(mi_page_block_size(page) >= size); // and try again, this time succeeding! (i.e. this should never recurse) return _mi_page_malloc(heap, page, size); } ================================================ FILE: runtime/src/mimalloc/c/random.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2019, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include // memset /* ---------------------------------------------------------------------------- We use our own PRNG to keep predictable performance of random number generation and to avoid implementations that use a lock. We only use the OS provided random source to initialize the initial seeds. Since we do not need ultimate performance but we do rely on the security (for secret cookies in secure mode) we use a cryptographically secure generator (chacha20). -----------------------------------------------------------------------------*/ #define MI_CHACHA_ROUNDS (20) // perhaps use 12 for better performance? /* ---------------------------------------------------------------------------- Chacha20 implementation as the original algorithm with a 64-bit nonce and counter: https://en.wikipedia.org/wiki/Salsa20 The input matrix has sixteen 32-bit values: Position 0 to 3: constant key Position 4 to 11: the key Position 12 to 13: the counter. Position 14 to 15: the nonce. The implementation uses regular C code which compiles very well on modern compilers. (gcc x64 has no register spills, and clang 6+ uses SSE instructions) -----------------------------------------------------------------------------*/ static inline uint32_t rotl(uint32_t x, uint32_t shift) { return (x << shift) | (x >> (32 - shift)); } static inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) { x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 16); x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 12); x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 8); x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 7); } static void chacha_block(mi_random_ctx_t* ctx) { // scramble into `x` uint32_t x[16]; for (size_t i = 0; i < 16; i++) { x[i] = ctx->input[i]; } for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) { qround(x, 0, 4, 8, 12); qround(x, 1, 5, 9, 13); qround(x, 2, 6, 10, 14); qround(x, 3, 7, 11, 15); qround(x, 0, 5, 10, 15); qround(x, 1, 6, 11, 12); qround(x, 2, 7, 8, 13); qround(x, 3, 4, 9, 14); } // add scrambled data to the initial state for (size_t i = 0; i < 16; i++) { ctx->output[i] = x[i] + ctx->input[i]; } ctx->output_available = 16; // increment the counter for the next round ctx->input[12] += 1; if (ctx->input[12] == 0) { ctx->input[13] += 1; if (ctx->input[13] == 0) { // and keep increasing into the nonce ctx->input[14] += 1; } } } static uint32_t chacha_next32(mi_random_ctx_t* ctx) { if (ctx->output_available <= 0) { chacha_block(ctx); ctx->output_available = 16; // (assign again to suppress static analysis warning) } const uint32_t x = ctx->output[16 - ctx->output_available]; ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out ctx->output_available--; return x; } static inline uint32_t read32(const uint8_t* p, size_t idx32) { const size_t i = 4*idx32; return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24); } static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce) { // since we only use chacha for randomness (and not encryption) we // do not _need_ to read 32-bit values as little endian but we do anyways // just for being compatible :-) memset(ctx, 0, sizeof(*ctx)); for (size_t i = 0; i < 4; i++) { const uint8_t* sigma = (uint8_t*)"expand 32-byte k"; ctx->input[i] = read32(sigma,i); } for (size_t i = 0; i < 8; i++) { ctx->input[i + 4] = read32(key,i); } ctx->input[12] = 0; ctx->input[13] = 0; ctx->input[14] = (uint32_t)nonce; ctx->input[15] = (uint32_t)(nonce >> 32); } static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) { memset(ctx_new, 0, sizeof(*ctx_new)); memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input)); ctx_new->input[12] = 0; ctx_new->input[13] = 0; ctx_new->input[14] = (uint32_t)nonce; ctx_new->input[15] = (uint32_t)(nonce >> 32); mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces! chacha_block(ctx_new); } /* ---------------------------------------------------------------------------- Random interface -----------------------------------------------------------------------------*/ #if MI_DEBUG>1 static bool mi_random_is_initialized(mi_random_ctx_t* ctx) { return (ctx != NULL && ctx->input[0] != 0); } #endif void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) { mi_assert_internal(mi_random_is_initialized(ctx)); mi_assert_internal(ctx != ctx_new); chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new); } uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { mi_assert_internal(mi_random_is_initialized(ctx)); #if MI_INTPTR_SIZE <= 4 return chacha_next32(ctx); #elif MI_INTPTR_SIZE == 8 return (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx)); #else # error "define mi_random_next for this platform" #endif } /* ---------------------------------------------------------------------------- To initialize a fresh random context we rely on the OS: - Windows : BCryptGenRandom (or RtlGenRandom) - osX,bsd,wasi: arc4random_buf - Linux : getrandom,/dev/urandom If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. -----------------------------------------------------------------------------*/ #if defined(_WIN32) #if !defined(MI_USE_RTLGENRANDOM) // We prefer BCryptGenRandom over RtlGenRandom #pragma comment (lib,"bcrypt.lib") #include static bool os_random_buf(void* buf, size_t buf_len) { return (BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0); } #else // Use (unofficial) RtlGenRandom #pragma comment (lib,"advapi32.lib") #define RtlGenRandom SystemFunction036 #ifdef __cplusplus extern "C" { #endif BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); #ifdef __cplusplus } #endif static bool os_random_buf(void* buf, size_t buf_len) { return (RtlGenRandom(buf, (ULONG)buf_len) != 0); } #endif #elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__sun) || defined(__wasi__) #include static bool os_random_buf(void* buf, size_t buf_len) { arc4random_buf(buf, buf_len); return true; } #elif defined(__linux__) #include #include #include #include #include #include static bool os_random_buf(void* buf, size_t buf_len) { // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h` // and for the latter the actual `getrandom` call is not always defined. // (see ) // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed. #ifdef SYS_getrandom #ifndef GRND_NONBLOCK #define GRND_NONBLOCK (1) #endif static _Atomic(uintptr_t) no_getrandom; // = 0 if (mi_atomic_load_acquire(&no_getrandom)==0) { ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK); if (ret >= 0) return (buf_len == (size_t)ret); if (ret != ENOSYS) return false; mi_atomic_store_release(&no_getrandom, 1UL); // don't call again, and fall back to /dev/urandom } #endif int flags = O_RDONLY; #if defined(O_CLOEXEC) flags |= O_CLOEXEC; #endif int fd = open("/dev/urandom", flags, 0); if (fd < 0) return false; size_t count = 0; while(count < buf_len) { ssize_t ret = read(fd, (char*)buf + count, buf_len - count); if (ret<=0) { if (errno!=EAGAIN && errno!=EINTR) break; } else { count += ret; } } close(fd); return (count==buf_len); } #else static bool os_random_buf(void* buf, size_t buf_len) { return false; } #endif #if defined(_WIN32) #include #elif defined(__APPLE__) #include #else #include #endif uintptr_t _os_random_weak(uintptr_t extra_seed) { uintptr_t x = (uintptr_t)&_os_random_weak ^ extra_seed; // ASLR makes the address random #if defined(_WIN32) LARGE_INTEGER pcount; QueryPerformanceCounter(&pcount); x ^= (uintptr_t)(pcount.QuadPart); #elif defined(__APPLE__) x ^= (uintptr_t)mach_absolute_time(); #else struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time); x ^= (uintptr_t)time.tv_sec; x ^= (uintptr_t)time.tv_nsec; #endif // and do a few randomization steps uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1; for (uintptr_t i = 0; i < max; i++) { x = _mi_random_shuffle(x); } mi_assert_internal(x != 0); return x; } void _mi_random_init(mi_random_ctx_t* ctx) { uint8_t key[32]; if (!os_random_buf(key, sizeof(key))) { // if we fail to get random data from the OS, we fall back to a // weak random source based on the current time _mi_warning_message("unable to use secure randomness\n"); uintptr_t x = _os_random_weak(0); for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words. x = _mi_random_shuffle(x); ((uint32_t*)key)[i] = (uint32_t)x; } } chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ ); } /* -------------------------------------------------------- test vectors from ----------------------------------------------------------- */ /* static bool array_equals(uint32_t* x, uint32_t* y, size_t n) { for (size_t i = 0; i < n; i++) { if (x[i] != y[i]) return false; } return true; } static void chacha_test(void) { uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 }; uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb }; qround(x, 0, 1, 2, 3); mi_assert_internal(array_equals(x, x_out, 4)); uint32_t y[16] = { 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c, 0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963, 0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320 }; uint32_t y_out[16] = { 0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a, 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2, 0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963, 0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320 }; qround(y, 2, 7, 8, 13); mi_assert_internal(array_equals(y, y_out, 16)); mi_random_ctx_t r = { { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c, 0x00000001, 0x09000000, 0x4a000000, 0x00000000 }, {0}, 0 }; uint32_t r_out[16] = { 0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3, 0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3, 0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9, 0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 }; chacha_block(&r); mi_assert_internal(array_equals(r.output, r_out, 16)); } */ ================================================ FILE: runtime/src/mimalloc/c/region.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2019, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "LICENSE" at the root of this distribution. -----------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------- This implements a layer between the raw OS memory (VirtualAlloc/mmap/sbrk/..) and the segment and huge object allocation by mimalloc. There may be multiple implementations of this (one could be the identity going directly to the OS, another could be a simple cache etc), but the current one uses large "regions". In contrast to the rest of mimalloc, the "regions" are shared between threads and need to be accessed using atomic operations. We need this memory layer between the raw OS calls because of: 1. on `sbrk` like systems (like WebAssembly) we need our own memory maps in order to reuse memory effectively. 2. It turns out that for large objects, between 1MiB and 32MiB (?), the cost of an OS allocation/free is still (much) too expensive relative to the accesses in that object :-( (`malloc-large` tests this). This means we need a cheaper way to reuse memory. 3. This layer allows for NUMA aware allocation. Possible issues: - (2) can potentially be addressed too with a small cache per thread which is much simpler. Generally though that requires shrinking of huge pages, and may overuse memory per thread. (and is not compatible with `sbrk`). - Since the current regions are per-process, we need atomic operations to claim blocks which may be contended - In the worst case, we need to search the whole region map (16KiB for 256GiB) linearly. At what point will direct OS calls be faster? Is there a way to do this better without adding too much complexity? -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // memset #include "bitmap.inc.c" // Internal raw OS interface size_t _mi_os_large_page_size(); bool _mi_os_protect(void* addr, size_t size); bool _mi_os_unprotect(void* addr, size_t size); bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); bool _mi_os_decommit(void* p, size_t size, mi_stats_t* stats); bool _mi_os_reset(void* p, size_t size, mi_stats_t* stats); bool _mi_os_unreset(void* p, size_t size, bool* is_zero, mi_stats_t* stats); // arena.c void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats); void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld); void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld); // Constants #if (MI_INTPTR_SIZE==8) #define MI_HEAP_REGION_MAX_SIZE (256 * GiB) // 64KiB for the region map #elif (MI_INTPTR_SIZE==4) #define MI_HEAP_REGION_MAX_SIZE (3 * GiB) // ~ KiB for the region map #else #error "define the maximum heap space allowed for regions on this platform" #endif #define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE #define MI_REGION_MAX_BLOCKS MI_BITMAP_FIELD_BITS #define MI_REGION_SIZE (MI_SEGMENT_SIZE * MI_BITMAP_FIELD_BITS) // 256MiB (64MiB on 32 bits) #define MI_REGION_MAX (MI_HEAP_REGION_MAX_SIZE / MI_REGION_SIZE) // 1024 (48 on 32 bits) #define MI_REGION_MAX_OBJ_BLOCKS (MI_REGION_MAX_BLOCKS/4) // 64MiB #define MI_REGION_MAX_OBJ_SIZE (MI_REGION_MAX_OBJ_BLOCKS*MI_SEGMENT_SIZE) // Region info typedef union mi_region_info_u { uintptr_t value; struct { bool valid; // initialized? bool is_large; // allocated in fixed large/huge OS pages short numa_node; // the associated NUMA node (where -1 means no associated node) } x; } mi_region_info_t; // A region owns a chunk of REGION_SIZE (256MiB) (virtual) memory with // a bit map with one bit per MI_SEGMENT_SIZE (4MiB) block. typedef struct mem_region_s { _Atomic(uintptr_t) info; // mi_region_info_t.value _Atomic(void*) start; // start of the memory area mi_bitmap_field_t in_use; // bit per in-use block mi_bitmap_field_t dirty; // track if non-zero per block mi_bitmap_field_t commit; // track if committed per block mi_bitmap_field_t reset; // track if reset per block _Atomic(uintptr_t) arena_memid; // if allocated from a (huge page) arena uintptr_t padding; // round to 8 fields } mem_region_t; // The region map static mem_region_t regions[MI_REGION_MAX]; // Allocated regions static _Atomic(uintptr_t) regions_count; // = 0; /* ---------------------------------------------------------------------------- Utility functions -----------------------------------------------------------------------------*/ // Blocks (of 4MiB) needed for the given size. static size_t mi_region_block_count(size_t size) { return _mi_divide_up(size, MI_SEGMENT_SIZE); } /* // Return a rounded commit/reset size such that we don't fragment large OS pages into small ones. static size_t mi_good_commit_size(size_t size) { if (size > (SIZE_MAX - _mi_os_large_page_size())) return size; return _mi_align_up(size, _mi_os_large_page_size()); } */ // Return if a pointer points into a region reserved by us. bool mi_is_in_heap_region(const void* p) mi_attr_noexcept { if (p==NULL) return false; size_t count = mi_atomic_load_relaxed(®ions_count); for (size_t i = 0; i < count; i++) { uint8_t* start = (uint8_t*)mi_atomic_load_ptr_relaxed(uint8_t, ®ions[i].start); if (start != NULL && (uint8_t*)p >= start && (uint8_t*)p < start + MI_REGION_SIZE) return true; } return false; } static void* mi_region_blocks_start(const mem_region_t* region, mi_bitmap_index_t bit_idx) { uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t, &((mem_region_t*)region)->start); mi_assert_internal(start != NULL); return (start + (bit_idx * MI_SEGMENT_SIZE)); } static size_t mi_memid_create(mem_region_t* region, mi_bitmap_index_t bit_idx) { mi_assert_internal(bit_idx < MI_BITMAP_FIELD_BITS); size_t idx = region - regions; mi_assert_internal(®ions[idx] == region); return (idx*MI_BITMAP_FIELD_BITS + bit_idx)<<1; } static size_t mi_memid_create_from_arena(size_t arena_memid) { return (arena_memid << 1) | 1; } static bool mi_memid_is_arena(size_t id, mem_region_t** region, mi_bitmap_index_t* bit_idx, size_t* arena_memid) { if ((id&1)==1) { if (arena_memid != NULL) *arena_memid = (id>>1); return true; } else { size_t idx = (id >> 1) / MI_BITMAP_FIELD_BITS; *bit_idx = (mi_bitmap_index_t)(id>>1) % MI_BITMAP_FIELD_BITS; *region = ®ions[idx]; return false; } } /* ---------------------------------------------------------------------------- Allocate a region is allocated from the OS (or an arena) -----------------------------------------------------------------------------*/ static bool mi_region_try_alloc_os(size_t blocks, bool commit, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld) { // not out of regions yet? if (mi_atomic_load_relaxed(®ions_count) >= MI_REGION_MAX - 1) return false; // try to allocate a fresh region from the OS bool region_commit = (commit && mi_option_is_enabled(mi_option_eager_region_commit)); bool region_large = (commit && allow_large); bool is_zero = false; size_t arena_memid = 0; void* const start = _mi_arena_alloc_aligned(MI_REGION_SIZE, MI_SEGMENT_ALIGN, ®ion_commit, ®ion_large, &is_zero, &arena_memid, tld); if (start == NULL) return false; mi_assert_internal(!(region_large && !allow_large)); mi_assert_internal(!region_large || region_commit); // claim a fresh slot const uintptr_t idx = mi_atomic_increment_acq_rel(®ions_count); if (idx >= MI_REGION_MAX) { mi_atomic_decrement_acq_rel(®ions_count); _mi_arena_free(start, MI_REGION_SIZE, arena_memid, region_commit, tld->stats); _mi_warning_message("maximum regions used: %zu GiB (perhaps recompile with a larger setting for MI_HEAP_REGION_MAX_SIZE)", _mi_divide_up(MI_HEAP_REGION_MAX_SIZE, GiB)); return false; } // allocated, initialize and claim the initial blocks mem_region_t* r = ®ions[idx]; r->arena_memid = arena_memid; mi_atomic_store_release(&r->in_use, (uintptr_t)0); mi_atomic_store_release(&r->dirty, (is_zero ? 0 : MI_BITMAP_FIELD_FULL)); mi_atomic_store_release(&r->commit, (region_commit ? MI_BITMAP_FIELD_FULL : 0)); mi_atomic_store_release(&r->reset, (uintptr_t)0); *bit_idx = 0; mi_bitmap_claim(&r->in_use, 1, blocks, *bit_idx, NULL); mi_atomic_store_ptr_release(void,&r->start, start); // and share it mi_region_info_t info; info.value = 0; // initialize the full union to zero info.x.valid = true; info.x.is_large = region_large; info.x.numa_node = (short)_mi_os_numa_node(tld); mi_atomic_store_release(&r->info, info.value); // now make it available to others *region = r; return true; } /* ---------------------------------------------------------------------------- Try to claim blocks in suitable regions -----------------------------------------------------------------------------*/ static bool mi_region_is_suitable(const mem_region_t* region, int numa_node, bool allow_large ) { // initialized at all? mi_region_info_t info; info.value = mi_atomic_load_relaxed(&((mem_region_t*)region)->info); if (info.value==0) return false; // numa correct if (numa_node >= 0) { // use negative numa node to always succeed int rnode = info.x.numa_node; if (rnode >= 0 && rnode != numa_node) return false; } // check allow-large if (!allow_large && info.x.is_large) return false; return true; } static bool mi_region_try_claim(int numa_node, size_t blocks, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld) { // try all regions for a free slot const size_t count = mi_atomic_load_relaxed(®ions_count); // monotonic, so ok to be relaxed size_t idx = tld->region_idx; // Or start at 0 to reuse low addresses? Starting at 0 seems to increase latency though for (size_t visited = 0; visited < count; visited++, idx++) { if (idx >= count) idx = 0; // wrap around mem_region_t* r = ®ions[idx]; // if this region suits our demand (numa node matches, large OS page matches) if (mi_region_is_suitable(r, numa_node, allow_large)) { // then try to atomically claim a segment(s) in this region if (mi_bitmap_try_find_claim_field(&r->in_use, 0, blocks, bit_idx)) { tld->region_idx = idx; // remember the last found position *region = r; return true; } } } return false; } static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* is_large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) { mi_assert_internal(blocks <= MI_BITMAP_FIELD_BITS); mem_region_t* region; mi_bitmap_index_t bit_idx; const int numa_node = (_mi_os_numa_node_count() <= 1 ? -1 : _mi_os_numa_node(tld)); // try to claim in existing regions if (!mi_region_try_claim(numa_node, blocks, *is_large, ®ion, &bit_idx, tld)) { // otherwise try to allocate a fresh region and claim in there if (!mi_region_try_alloc_os(blocks, *commit, *is_large, ®ion, &bit_idx, tld)) { // out of regions or memory return NULL; } } // ------------------------------------------------ // found a region and claimed `blocks` at `bit_idx`, initialize them now mi_assert_internal(region != NULL); mi_assert_internal(mi_bitmap_is_claimed(®ion->in_use, 1, blocks, bit_idx)); mi_region_info_t info; info.value = mi_atomic_load_acquire(®ion->info); uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t,®ion->start); mi_assert_internal(!(info.x.is_large && !*is_large)); mi_assert_internal(start != NULL); *is_zero = mi_bitmap_claim(®ion->dirty, 1, blocks, bit_idx, NULL); *is_large = info.x.is_large; *memid = mi_memid_create(region, bit_idx); void* p = start + (mi_bitmap_index_bit_in_field(bit_idx) * MI_SEGMENT_SIZE); // commit if (*commit) { // ensure commit bool any_uncommitted; mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, &any_uncommitted); if (any_uncommitted) { mi_assert_internal(!info.x.is_large); bool commit_zero = false; if (!_mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld)) { // failed to commit! unclaim and return mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx); return NULL; } if (commit_zero) *is_zero = true; } } else { // no need to commit, but check if already fully committed *commit = mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx); } mi_assert_internal(!*commit || mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx)); // unreset reset blocks if (mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)) { // some blocks are still reset mi_assert_internal(!info.x.is_large); mi_assert_internal(!mi_option_is_enabled(mi_option_eager_commit) || *commit || mi_option_get(mi_option_eager_commit_delay) > 0); mi_bitmap_unclaim(®ion->reset, 1, blocks, bit_idx); if (*commit || !mi_option_is_enabled(mi_option_reset_decommits)) { // only if needed bool reset_zero = false; _mi_mem_unreset(p, blocks * MI_SEGMENT_SIZE, &reset_zero, tld); if (reset_zero) *is_zero = true; } } mi_assert_internal(!mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)); #if (MI_DEBUG>=2) if (*commit) { ((uint8_t*)p)[0] = 0; } #endif // and return the allocation mi_assert_internal(p != NULL); return p; } /* ---------------------------------------------------------------------------- Allocation -----------------------------------------------------------------------------*/ // Allocate `size` memory aligned at `alignment`. Return non NULL on success, with a given memory `id`. // (`id` is abstract, but `id = idx*MI_REGION_MAP_BITS + bitidx`) void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) { mi_assert_internal(memid != NULL && tld != NULL); mi_assert_internal(size > 0); *memid = 0; *is_zero = false; bool default_large = false; if (large==NULL) large = &default_large; // ensure `large != NULL` if (size == 0) return NULL; size = _mi_align_up(size, _mi_os_page_size()); // allocate from regions if possible void* p = NULL; size_t arena_memid; const size_t blocks = mi_region_block_count(size); if (blocks <= MI_REGION_MAX_OBJ_BLOCKS && alignment <= MI_SEGMENT_ALIGN) { p = mi_region_try_alloc(blocks, commit, large, is_zero, memid, tld); if (p == NULL) { _mi_warning_message("unable to allocate from region: size %zu\n", size); } } if (p == NULL) { // and otherwise fall back to the OS p = _mi_arena_alloc_aligned(size, alignment, commit, large, is_zero, &arena_memid, tld); *memid = mi_memid_create_from_arena(arena_memid); } if (p != NULL) { mi_assert_internal((uintptr_t)p % alignment == 0); #if (MI_DEBUG>=2) if (*commit) { ((uint8_t*)p)[0] = 0; } // ensure the memory is committed #endif } return p; } /* ---------------------------------------------------------------------------- Free -----------------------------------------------------------------------------*/ // Free previously allocated memory with a given id. void _mi_mem_free(void* p, size_t size, size_t id, bool full_commit, bool any_reset, mi_os_tld_t* tld) { mi_assert_internal(size > 0 && tld != NULL); if (p==NULL) return; if (size==0) return; size = _mi_align_up(size, _mi_os_page_size()); size_t arena_memid = 0; mi_bitmap_index_t bit_idx; mem_region_t* region; if (mi_memid_is_arena(id,®ion,&bit_idx,&arena_memid)) { // was a direct arena allocation, pass through _mi_arena_free(p, size, arena_memid, full_commit, tld->stats); } else { // allocated in a region mi_assert_internal(size <= MI_REGION_MAX_OBJ_SIZE); if (size > MI_REGION_MAX_OBJ_SIZE) return; const size_t blocks = mi_region_block_count(size); mi_assert_internal(blocks + bit_idx <= MI_BITMAP_FIELD_BITS); mi_region_info_t info; info.value = mi_atomic_load_acquire(®ion->info); mi_assert_internal(info.value != 0); void* blocks_start = mi_region_blocks_start(region, bit_idx); mi_assert_internal(blocks_start == p); // not a pointer in our area? mi_assert_internal(bit_idx + blocks <= MI_BITMAP_FIELD_BITS); if (blocks_start != p || bit_idx + blocks > MI_BITMAP_FIELD_BITS) return; // or `abort`? // committed? if (full_commit && (size % MI_SEGMENT_SIZE) == 0) { mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, NULL); } if (any_reset) { // set the is_reset bits if any pages were reset mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, NULL); } // reset the blocks to reduce the working set. if (!info.x.is_large && mi_option_is_enabled(mi_option_segment_reset) && (mi_option_is_enabled(mi_option_eager_commit) || mi_option_is_enabled(mi_option_reset_decommits))) // cannot reset halfway committed segments, use only `option_page_reset` instead { bool any_unreset; mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, &any_unreset); if (any_unreset) { _mi_abandoned_await_readers(); // ensure no more pending write (in case reset = decommit) _mi_mem_reset(p, blocks * MI_SEGMENT_SIZE, tld); } } // and unclaim bool all_unclaimed = mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx); mi_assert_internal(all_unclaimed); UNUSED(all_unclaimed); } } /* ---------------------------------------------------------------------------- collection -----------------------------------------------------------------------------*/ void _mi_mem_collect(mi_os_tld_t* tld) { // free every region that has no segments in use. uintptr_t rcount = mi_atomic_load_relaxed(®ions_count); for (size_t i = 0; i < rcount; i++) { mem_region_t* region = ®ions[i]; if (mi_atomic_load_relaxed(®ion->info) != 0) { // if no segments used, try to claim the whole region uintptr_t m = mi_atomic_load_relaxed(®ion->in_use); while (m == 0 && !mi_atomic_cas_weak_release(®ion->in_use, &m, MI_BITMAP_FIELD_FULL)) { /* nothing */ }; if (m == 0) { // on success, free the whole region uint8_t* start = (uint8_t*)mi_atomic_load_ptr_acquire(uint8_t,®ions[i].start); size_t arena_memid = mi_atomic_load_relaxed(®ions[i].arena_memid); uintptr_t commit = mi_atomic_load_relaxed(®ions[i].commit); memset(®ions[i], 0, sizeof(mem_region_t)); // and release the whole region mi_atomic_store_release(®ion->info, (uintptr_t)0); if (start != NULL) { // && !_mi_os_is_huge_reserved(start)) { _mi_abandoned_await_readers(); // ensure no pending reads _mi_arena_free(start, MI_REGION_SIZE, arena_memid, (~commit == 0), tld->stats); } } } } } /* ---------------------------------------------------------------------------- Other -----------------------------------------------------------------------------*/ bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld) { return _mi_os_reset(p, size, tld->stats); } bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) { return _mi_os_unreset(p, size, is_zero, tld->stats); } bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) { return _mi_os_commit(p, size, is_zero, tld->stats); } bool _mi_mem_decommit(void* p, size_t size, mi_os_tld_t* tld) { return _mi_os_decommit(p, size, tld->stats); } bool _mi_mem_protect(void* p, size_t size) { return _mi_os_protect(p, size); } bool _mi_mem_unprotect(void* p, size_t size) { return _mi_os_unprotect(p, size); } ================================================ FILE: runtime/src/mimalloc/c/segment.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // memset #include #define MI_PAGE_HUGE_ALIGN (256*1024) static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); /* -------------------------------------------------------------------------------- Segment allocation We allocate pages inside bigger "segments" (4mb on 64-bit). This is to avoid splitting VMA's on Linux and reduce fragmentation on other OS's. Each thread owns its own segments. Currently we have: - small pages (64kb), 64 in one segment - medium pages (512kb), 8 in one segment - large pages (4mb), 1 in one segment - huge blocks > MI_LARGE_OBJ_SIZE_MAX become large segment with 1 page In any case the memory for a segment is virtual and usually committed on demand. (i.e. we are careful to not touch the memory until we actually allocate a block there) If a thread ends, it "abandons" pages with used blocks and there is an abandoned segment list whose segments can be reclaimed by still running threads, much like work-stealing. -------------------------------------------------------------------------------- */ /* ----------------------------------------------------------- Queue of segments containing free pages ----------------------------------------------------------- */ #if (MI_DEBUG>=3) static bool mi_segment_queue_contains(const mi_segment_queue_t* queue, const mi_segment_t* segment) { mi_assert_internal(segment != NULL); mi_segment_t* list = queue->first; while (list != NULL) { if (list == segment) break; mi_assert_internal(list->next==NULL || list->next->prev == list); mi_assert_internal(list->prev==NULL || list->prev->next == list); list = list->next; } return (list == segment); } #endif static bool mi_segment_queue_is_empty(const mi_segment_queue_t* queue) { return (queue->first == NULL); } static void mi_segment_queue_remove(mi_segment_queue_t* queue, mi_segment_t* segment) { mi_assert_expensive(mi_segment_queue_contains(queue, segment)); if (segment->prev != NULL) segment->prev->next = segment->next; if (segment->next != NULL) segment->next->prev = segment->prev; if (segment == queue->first) queue->first = segment->next; if (segment == queue->last) queue->last = segment->prev; segment->next = NULL; segment->prev = NULL; } static void mi_segment_enqueue(mi_segment_queue_t* queue, mi_segment_t* segment) { mi_assert_expensive(!mi_segment_queue_contains(queue, segment)); segment->next = NULL; segment->prev = queue->last; if (queue->last != NULL) { mi_assert_internal(queue->last->next == NULL); queue->last->next = segment; queue->last = segment; } else { queue->last = queue->first = segment; } } static mi_segment_queue_t* mi_segment_free_queue_of_kind(mi_page_kind_t kind, mi_segments_tld_t* tld) { if (kind == MI_PAGE_SMALL) return &tld->small_free; else if (kind == MI_PAGE_MEDIUM) return &tld->medium_free; else return NULL; } static mi_segment_queue_t* mi_segment_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) { return mi_segment_free_queue_of_kind(segment->page_kind, tld); } // remove from free queue if it is in one static void mi_segment_remove_from_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld); // may be NULL bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment)); if (in_queue) { mi_segment_queue_remove(queue, segment); } } static void mi_segment_insert_in_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_segment_enqueue(mi_segment_free_queue(segment, tld), segment); } /* ----------------------------------------------------------- Invariant checking ----------------------------------------------------------- */ #if (MI_DEBUG>=2) static bool mi_segment_is_in_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) { mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld); bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment)); if (in_queue) { mi_assert_expensive(mi_segment_queue_contains(queue, segment)); } return in_queue; } #endif static size_t mi_segment_page_size(const mi_segment_t* segment) { if (segment->capacity > 1) { mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM); return ((size_t)1 << segment->page_shift); } else { mi_assert_internal(segment->page_kind >= MI_PAGE_LARGE); return segment->segment_size; } } #if (MI_DEBUG>=2) static bool mi_pages_reset_contains(const mi_page_t* page, mi_segments_tld_t* tld) { mi_page_t* p = tld->pages_reset.first; while (p != NULL) { if (p == page) return true; p = p->next; } return false; } #endif #if (MI_DEBUG>=3) static bool mi_segment_is_valid(const mi_segment_t* segment, mi_segments_tld_t* tld) { mi_assert_internal(segment != NULL); mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); mi_assert_internal(segment->used <= segment->capacity); mi_assert_internal(segment->abandoned <= segment->used); size_t nfree = 0; for (size_t i = 0; i < segment->capacity; i++) { const mi_page_t* const page = &segment->pages[i]; if (!page->segment_in_use) { nfree++; } if (page->segment_in_use || page->is_reset) { mi_assert_expensive(!mi_pages_reset_contains(page, tld)); } } mi_assert_internal(nfree + segment->used == segment->capacity); // mi_assert_internal(segment->thread_id == _mi_thread_id() || (segment->thread_id==0)); // or 0 mi_assert_internal(segment->page_kind == MI_PAGE_HUGE || (mi_segment_page_size(segment) * segment->capacity == segment->segment_size)); return true; } #endif static bool mi_page_not_in_queue(const mi_page_t* page, mi_segments_tld_t* tld) { mi_assert_internal(page != NULL); if (page->next != NULL || page->prev != NULL) { mi_assert_internal(mi_pages_reset_contains(page, tld)); return false; } else { // both next and prev are NULL, check for singleton list return (tld->pages_reset.first != page && tld->pages_reset.last != page); } } /* ----------------------------------------------------------- Guard pages ----------------------------------------------------------- */ static void mi_segment_protect_range(void* p, size_t size, bool protect) { if (protect) { _mi_mem_protect(p, size); } else { _mi_mem_unprotect(p, size); } } static void mi_segment_protect(mi_segment_t* segment, bool protect, mi_os_tld_t* tld) { // add/remove guard pages if (MI_SECURE != 0) { // in secure mode, we set up a protected page in between the segment info and the page data const size_t os_psize = _mi_os_page_size(); mi_assert_internal((segment->segment_info_size - os_psize) >= (sizeof(mi_segment_t) + ((segment->capacity - 1) * sizeof(mi_page_t)))); mi_assert_internal(((uintptr_t)segment + segment->segment_info_size) % os_psize == 0); mi_segment_protect_range((uint8_t*)segment + segment->segment_info_size - os_psize, os_psize, protect); if (MI_SECURE <= 1 || segment->capacity == 1) { // and protect the last (or only) page too mi_assert_internal(MI_SECURE <= 1 || segment->page_kind >= MI_PAGE_LARGE); uint8_t* start = (uint8_t*)segment + segment->segment_size - os_psize; if (protect && !segment->mem_is_committed) { if (protect) { // ensure secure page is committed if (_mi_mem_commit(start, os_psize, NULL, tld)) { // if this fails that is ok (as it is an unaccessible page) mi_segment_protect_range(start, os_psize, protect); } } } else { mi_segment_protect_range(start, os_psize, protect); } } else { // or protect every page const size_t page_size = mi_segment_page_size(segment); for (size_t i = 0; i < segment->capacity; i++) { if (segment->pages[i].is_committed) { mi_segment_protect_range((uint8_t*)segment + (i+1)*page_size - os_psize, os_psize, protect); } } } } } /* ----------------------------------------------------------- Page reset ----------------------------------------------------------- */ static void mi_page_reset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld) { mi_assert_internal(page->is_committed); if (!mi_option_is_enabled(mi_option_page_reset)) return; if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return; size_t psize; void* start = mi_segment_raw_page_start(segment, page, &psize); page->is_reset = true; mi_assert_internal(size <= psize); size_t reset_size = ((size == 0 || size > psize) ? psize : size); if (reset_size > 0) _mi_mem_reset(start, reset_size, tld->os); } static bool mi_page_unreset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld) { mi_assert_internal(page->is_reset); mi_assert_internal(page->is_committed); mi_assert_internal(!segment->mem_is_fixed); if (segment->mem_is_fixed || !page->is_committed || !page->is_reset) return true; page->is_reset = false; size_t psize; uint8_t* start = mi_segment_raw_page_start(segment, page, &psize); size_t unreset_size = (size == 0 || size > psize ? psize : size); bool is_zero = false; bool ok = true; if (unreset_size > 0) { ok = _mi_mem_unreset(start, unreset_size, &is_zero, tld->os); } if (is_zero) page->is_zero_init = true; return ok; } /* ----------------------------------------------------------- The free page queue ----------------------------------------------------------- */ // we re-use the `used` field for the expiration counter. Since this is a // a 32-bit field while the clock is always 64-bit we need to guard // against overflow, we use substraction to check for expiry which work // as long as the reset delay is under (2^30 - 1) milliseconds (~12 days) static void mi_page_reset_set_expire(mi_page_t* page) { uint32_t expire = (uint32_t)_mi_clock_now() + mi_option_get(mi_option_reset_delay); page->used = expire; } static bool mi_page_reset_is_expired(mi_page_t* page, mi_msecs_t now) { int32_t expire = (int32_t)(page->used); return (((int32_t)now - expire) >= 0); } static void mi_pages_reset_add(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) { mi_assert_internal(!page->segment_in_use || !page->is_committed); mi_assert_internal(mi_page_not_in_queue(page,tld)); mi_assert_expensive(!mi_pages_reset_contains(page, tld)); mi_assert_internal(_mi_page_segment(page)==segment); if (!mi_option_is_enabled(mi_option_page_reset)) return; if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return; if (mi_option_get(mi_option_reset_delay) == 0) { // reset immediately? mi_page_reset(segment, page, 0, tld); } else { // otherwise push on the delayed page reset queue mi_page_queue_t* pq = &tld->pages_reset; // push on top mi_page_reset_set_expire(page); page->next = pq->first; page->prev = NULL; if (pq->first == NULL) { mi_assert_internal(pq->last == NULL); pq->first = pq->last = page; } else { pq->first->prev = page; pq->first = page; } } } static void mi_pages_reset_remove(mi_page_t* page, mi_segments_tld_t* tld) { if (mi_page_not_in_queue(page,tld)) return; mi_page_queue_t* pq = &tld->pages_reset; mi_assert_internal(pq!=NULL); mi_assert_internal(!page->segment_in_use); mi_assert_internal(mi_pages_reset_contains(page, tld)); if (page->prev != NULL) page->prev->next = page->next; if (page->next != NULL) page->next->prev = page->prev; if (page == pq->last) pq->last = page->prev; if (page == pq->first) pq->first = page->next; page->next = page->prev = NULL; page->used = 0; } static void mi_pages_reset_remove_all_in_segment(mi_segment_t* segment, bool force_reset, mi_segments_tld_t* tld) { if (segment->mem_is_fixed) return; // never reset in huge OS pages for (size_t i = 0; i < segment->capacity; i++) { mi_page_t* page = &segment->pages[i]; if (!page->segment_in_use && page->is_committed && !page->is_reset) { mi_pages_reset_remove(page, tld); if (force_reset) { mi_page_reset(segment, page, 0, tld); } } else { mi_assert_internal(mi_page_not_in_queue(page,tld)); } } } static void mi_reset_delayed(mi_segments_tld_t* tld) { if (!mi_option_is_enabled(mi_option_page_reset)) return; mi_msecs_t now = _mi_clock_now(); mi_page_queue_t* pq = &tld->pages_reset; // from oldest up to the first that has not expired yet mi_page_t* page = pq->last; while (page != NULL && mi_page_reset_is_expired(page,now)) { mi_page_t* const prev = page->prev; // save previous field mi_page_reset(_mi_page_segment(page), page, 0, tld); page->used = 0; page->prev = page->next = NULL; page = prev; } // discard the reset pages from the queue pq->last = page; if (page != NULL){ page->next = NULL; } else { pq->first = NULL; } } /* ----------------------------------------------------------- Segment size calculations ----------------------------------------------------------- */ // Raw start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set) // The raw start is not taking aligned block allocation into consideration. static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { size_t psize = (segment->page_kind == MI_PAGE_HUGE ? segment->segment_size : (size_t)1 << segment->page_shift); uint8_t* p = (uint8_t*)segment + page->segment_idx * psize; if (page->segment_idx == 0) { // the first page starts after the segment info (and possible guard page) p += segment->segment_info_size; psize -= segment->segment_info_size; } if (MI_SECURE > 1 || (MI_SECURE == 1 && page->segment_idx == segment->capacity - 1)) { // secure == 1: the last page has an os guard page at the end // secure > 1: every page has an os guard page psize -= _mi_os_page_size(); } if (page_size != NULL) *page_size = psize; mi_assert_internal(page->xblock_size == 0 || _mi_ptr_page(p) == page); mi_assert_internal(_mi_ptr_segment(p) == segment); return p; } // Start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set) uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size) { size_t psize; uint8_t* p = mi_segment_raw_page_start(segment, page, &psize); if (pre_size != NULL) *pre_size = 0; if (page->segment_idx == 0 && block_size > 0 && segment->page_kind <= MI_PAGE_MEDIUM) { // for small and medium objects, ensure the page start is aligned with the block size (PR#66 by kickunderscore) size_t adjust = block_size - ((uintptr_t)p % block_size); if (adjust < block_size) { p += adjust; psize -= adjust; if (pre_size != NULL) *pre_size = adjust; } mi_assert_internal((uintptr_t)p % block_size == 0); } if (page_size != NULL) *page_size = psize; mi_assert_internal(page->xblock_size==0 || _mi_ptr_page(p) == page); mi_assert_internal(_mi_ptr_segment(p) == segment); return p; } static size_t mi_segment_size(size_t capacity, size_t required, size_t* pre_size, size_t* info_size) { const size_t minsize = sizeof(mi_segment_t) + ((capacity - 1) * sizeof(mi_page_t)) + 16 /* padding */; size_t guardsize = 0; size_t isize = 0; if (MI_SECURE == 0) { // normally no guard pages isize = _mi_align_up(minsize, 16 * MI_MAX_ALIGN_SIZE); } else { // in secure mode, we set up a protected page in between the segment info // and the page data (and one at the end of the segment) const size_t page_size = _mi_os_page_size(); isize = _mi_align_up(minsize, page_size); guardsize = page_size; required = _mi_align_up(required, page_size); } if (info_size != NULL) *info_size = isize; if (pre_size != NULL) *pre_size = isize + guardsize; return (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + 2*guardsize, MI_PAGE_HUGE_ALIGN) ); } /* ---------------------------------------------------------------------------- Segment caches We keep a small segment cache per thread to increase local reuse and avoid setting/clearing guard pages in secure mode. ------------------------------------------------------------------------------- */ static void mi_segments_track_size(long segment_size, mi_segments_tld_t* tld) { if (segment_size>=0) _mi_stat_increase(&tld->stats->segments,1); else _mi_stat_decrease(&tld->stats->segments,1); tld->count += (segment_size >= 0 ? 1 : -1); if (tld->count > tld->peak_count) tld->peak_count = tld->count; tld->current_size += segment_size; if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size; } static void mi_segment_os_free(mi_segment_t* segment, size_t segment_size, mi_segments_tld_t* tld) { segment->thread_id = 0; mi_segments_track_size(-((long)segment_size),tld); if (MI_SECURE != 0) { mi_assert_internal(!segment->mem_is_fixed); mi_segment_protect(segment, false, tld->os); // ensure no more guard pages are set } bool any_reset = false; bool fully_committed = true; for (size_t i = 0; i < segment->capacity; i++) { mi_page_t* page = &segment->pages[i]; if (!page->is_committed) { fully_committed = false; } if (page->is_reset) { any_reset = true; } } if (any_reset && mi_option_is_enabled(mi_option_reset_decommits)) { fully_committed = false; } _mi_mem_free(segment, segment_size, segment->memid, fully_committed, any_reset, tld->os); } // The thread local segment cache is limited to be at most 1/8 of the peak size of segments in use, #define MI_SEGMENT_CACHE_FRACTION (8) // note: returned segment may be partially reset static mi_segment_t* mi_segment_cache_pop(size_t segment_size, mi_segments_tld_t* tld) { if (segment_size != 0 && segment_size != MI_SEGMENT_SIZE) return NULL; mi_segment_t* segment = tld->cache; if (segment == NULL) return NULL; tld->cache_count--; tld->cache = segment->next; segment->next = NULL; mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE); _mi_stat_decrease(&tld->stats->segments_cache, 1); return segment; } static bool mi_segment_cache_full(mi_segments_tld_t* tld) { // if (tld->count == 1 && tld->cache_count==0) return false; // always cache at least the final segment of a thread size_t max_cache = mi_option_get(mi_option_segment_cache); if (tld->cache_count < max_cache && tld->cache_count < (1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION)) // at least allow a 1 element cache ) { return false; } // take the opportunity to reduce the segment cache if it is too large (now) // TODO: this never happens as we check against peak usage, should we use current usage instead? while (tld->cache_count > max_cache) { //(1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION))) { mi_segment_t* segment = mi_segment_cache_pop(0,tld); mi_assert_internal(segment != NULL); if (segment != NULL) mi_segment_os_free(segment, segment->segment_size, tld); } return true; } static bool mi_segment_cache_push(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_assert_internal(!mi_segment_is_in_free_queue(segment, tld)); mi_assert_internal(segment->next == NULL); if (segment->segment_size != MI_SEGMENT_SIZE || mi_segment_cache_full(tld)) { return false; } mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE); segment->next = tld->cache; tld->cache = segment; tld->cache_count++; _mi_stat_increase(&tld->stats->segments_cache,1); return true; } // called by threads that are terminating to free cached segments void _mi_segment_thread_collect(mi_segments_tld_t* tld) { mi_segment_t* segment; while ((segment = mi_segment_cache_pop(0,tld)) != NULL) { mi_segment_os_free(segment, segment->segment_size, tld); } mi_assert_internal(tld->cache_count == 0); mi_assert_internal(tld->cache == NULL); #if MI_DEBUG>=2 if (!_mi_is_main_thread()) { mi_assert_internal(tld->pages_reset.first == NULL); mi_assert_internal(tld->pages_reset.last == NULL); } #endif } /* ----------------------------------------------------------- Segment allocation ----------------------------------------------------------- */ // Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` . static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { // the segment parameter is non-null if it came from our cache mi_assert_internal(segment==NULL || (required==0 && page_kind <= MI_PAGE_LARGE)); // calculate needed sizes first size_t capacity; if (page_kind == MI_PAGE_HUGE) { mi_assert_internal(page_shift == MI_SEGMENT_SHIFT && required > 0); capacity = 1; } else { mi_assert_internal(required == 0); size_t page_size = (size_t)1 << page_shift; capacity = MI_SEGMENT_SIZE / page_size; mi_assert_internal(MI_SEGMENT_SIZE % page_size == 0); mi_assert_internal(capacity >= 1 && capacity <= MI_SMALL_PAGES_PER_SEGMENT); } size_t info_size; size_t pre_size; size_t segment_size = mi_segment_size(capacity, required, &pre_size, &info_size); mi_assert_internal(segment_size >= required); // Initialize parameters const bool eager_delayed = (page_kind <= MI_PAGE_MEDIUM && tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay)); const bool eager = !eager_delayed && mi_option_is_enabled(mi_option_eager_commit); bool commit = eager; // || (page_kind >= MI_PAGE_LARGE); bool pages_still_good = false; bool is_zero = false; // Try to get it from our thread local cache first if (segment != NULL) { // came from cache mi_assert_internal(segment->segment_size == segment_size); if (page_kind <= MI_PAGE_MEDIUM && segment->page_kind == page_kind && segment->segment_size == segment_size) { pages_still_good = true; } else { if (MI_SECURE!=0) { mi_assert_internal(!segment->mem_is_fixed); mi_segment_protect(segment, false, tld->os); // reset protection if the page kind differs } // different page kinds; unreset any reset pages, and unprotect // TODO: optimize cache pop to return fitting pages if possible? for (size_t i = 0; i < segment->capacity; i++) { mi_page_t* page = &segment->pages[i]; if (page->is_reset) { if (!commit && mi_option_is_enabled(mi_option_reset_decommits)) { page->is_reset = false; } else { mi_page_unreset(segment, page, 0, tld); // todo: only unreset the part that was reset? (instead of the full page) } } } // ensure the initial info is committed if (segment->capacity < capacity) { bool commit_zero = false; bool ok = _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); if (commit_zero) is_zero = true; if (!ok) { return NULL; } } } } else { // Allocate the segment from the OS size_t memid; bool mem_large = (!eager_delayed && (MI_SECURE==0)); // only allow large OS pages once we are no longer lazy segment = (mi_segment_t*)_mi_mem_alloc_aligned(segment_size, MI_SEGMENT_SIZE, &commit, &mem_large, &is_zero, &memid, os_tld); if (segment == NULL) return NULL; // failed to allocate if (!commit) { // ensure the initial info is committed bool commit_zero = false; bool ok = _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); if (commit_zero) is_zero = true; if (!ok) { // commit failed; we cannot touch the memory: free the segment directly and return `NULL` _mi_mem_free(segment, MI_SEGMENT_SIZE, memid, false, false, os_tld); return NULL; } } segment->memid = memid; segment->mem_is_fixed = mem_large; segment->mem_is_committed = commit; mi_segments_track_size((long)segment_size, tld); } mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0); mi_assert_internal(segment->mem_is_fixed ? segment->mem_is_committed : true); mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); // tsan if (!pages_still_good) { // zero the segment info (but not the `mem` fields) ptrdiff_t ofs = offsetof(mi_segment_t, next); memset((uint8_t*)segment + ofs, 0, info_size - ofs); // initialize pages info for (uint8_t i = 0; i < capacity; i++) { segment->pages[i].segment_idx = i; segment->pages[i].is_reset = false; segment->pages[i].is_committed = commit; segment->pages[i].is_zero_init = is_zero; } } else { // zero the segment info but not the pages info (and mem fields) ptrdiff_t ofs = offsetof(mi_segment_t, next); memset((uint8_t*)segment + ofs, 0, offsetof(mi_segment_t,pages) - ofs); } // initialize segment->page_kind = page_kind; segment->capacity = capacity; segment->page_shift = page_shift; segment->segment_size = segment_size; segment->segment_info_size = pre_size; segment->thread_id = _mi_thread_id(); segment->cookie = _mi_ptr_cookie(segment); // _mi_stat_increase(&tld->stats->page_committed, segment->segment_info_size); // set protection mi_segment_protect(segment, true, tld->os); // insert in free lists for small and medium pages if (page_kind <= MI_PAGE_MEDIUM) { mi_segment_insert_in_free_queue(segment, tld); } //fprintf(stderr,"mimalloc: alloc segment at %p\n", (void*)segment); return segment; } static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { return mi_segment_init(NULL, required, page_kind, page_shift, tld, os_tld); } static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) { UNUSED(force); mi_assert(segment != NULL); // note: don't reset pages even on abandon as the whole segment is freed? (and ready for reuse) bool force_reset = (force && mi_option_is_enabled(mi_option_abandoned_page_reset)); mi_pages_reset_remove_all_in_segment(segment, force_reset, tld); mi_segment_remove_from_free_queue(segment,tld); mi_assert_expensive(!mi_segment_queue_contains(&tld->small_free, segment)); mi_assert_expensive(!mi_segment_queue_contains(&tld->medium_free, segment)); mi_assert(segment->next == NULL); mi_assert(segment->prev == NULL); _mi_stat_decrease(&tld->stats->page_committed, segment->segment_info_size); if (!force && mi_segment_cache_push(segment, tld)) { // it is put in our cache } else { // otherwise return it to the OS mi_segment_os_free(segment, segment->segment_size, tld); } } /* ----------------------------------------------------------- Free page management inside a segment ----------------------------------------------------------- */ static bool mi_segment_has_free(const mi_segment_t* segment) { return (segment->used < segment->capacity); } static bool mi_segment_page_claim(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) { mi_assert_internal(_mi_page_segment(page) == segment); mi_assert_internal(!page->segment_in_use); mi_pages_reset_remove(page, tld); // check commit if (!page->is_committed) { mi_assert_internal(!segment->mem_is_fixed); mi_assert_internal(!page->is_reset); size_t psize; uint8_t* start = mi_segment_raw_page_start(segment, page, &psize); bool is_zero = false; const size_t gsize = (MI_SECURE >= 2 ? _mi_os_page_size() : 0); bool ok = _mi_mem_commit(start, psize + gsize, &is_zero, tld->os); if (!ok) return false; // failed to commit! if (gsize > 0) { mi_segment_protect_range(start + psize, gsize, true); } if (is_zero) { page->is_zero_init = true; } page->is_committed = true; } // set in-use before doing unreset to prevent delayed reset page->segment_in_use = true; segment->used++; // check reset if (page->is_reset) { mi_assert_internal(!segment->mem_is_fixed); bool ok = mi_page_unreset(segment, page, 0, tld); if (!ok) { page->segment_in_use = false; segment->used--; return false; } } mi_assert_internal(page->segment_in_use); mi_assert_internal(segment->used <= segment->capacity); if (segment->used == segment->capacity && segment->page_kind <= MI_PAGE_MEDIUM) { // if no more free pages, remove from the queue mi_assert_internal(!mi_segment_has_free(segment)); mi_segment_remove_from_free_queue(segment, tld); } return true; } /* ----------------------------------------------------------- Free ----------------------------------------------------------- */ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld); // clear page data; can be called on abandoned segments static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, bool allow_reset, mi_segments_tld_t* tld) { mi_assert_internal(page->segment_in_use); mi_assert_internal(mi_page_all_free(page)); mi_assert_internal(page->is_committed); mi_assert_internal(mi_page_not_in_queue(page, tld)); size_t inuse = page->capacity * mi_page_block_size(page); _mi_stat_decrease(&tld->stats->page_committed, inuse); _mi_stat_decrease(&tld->stats->pages, 1); // calculate the used size from the raw (non-aligned) start of the page //size_t pre_size; //_mi_segment_page_start(segment, page, page->block_size, NULL, &pre_size); //size_t used_size = pre_size + (page->capacity * page->block_size); page->is_zero_init = false; page->segment_in_use = false; // reset the page memory to reduce memory pressure? // note: must come after setting `segment_in_use` to false but before block_size becomes 0 //mi_page_reset(segment, page, 0 /*used_size*/, tld); // zero the page data, but not the segment fields and capacity, and block_size (for page size calculations) uint32_t block_size = page->xblock_size; uint16_t capacity = page->capacity; uint16_t reserved = page->reserved; ptrdiff_t ofs = offsetof(mi_page_t,capacity); memset((uint8_t*)page + ofs, 0, sizeof(*page) - ofs); page->capacity = capacity; page->reserved = reserved; page->xblock_size = block_size; segment->used--; // add to the free page list for reuse/reset if (allow_reset) { mi_pages_reset_add(segment, page, tld); } page->capacity = 0; // after reset these can be zero'd now page->reserved = 0; } void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld) { mi_assert(page != NULL); mi_segment_t* segment = _mi_page_segment(page); mi_assert_expensive(mi_segment_is_valid(segment,tld)); mi_reset_delayed(tld); // mark it as free now mi_segment_page_clear(segment, page, true, tld); if (segment->used == 0) { // no more used pages; remove from the free list and free the segment mi_segment_free(segment, force, tld); } else { if (segment->used == segment->abandoned) { // only abandoned pages; remove from free list and abandon mi_segment_abandon(segment,tld); } else if (segment->used + 1 == segment->capacity) { mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM); // for now we only support small and medium pages // move back to segments free list mi_segment_insert_in_free_queue(segment,tld); } } } /* ----------------------------------------------------------- Abandonment When threads terminate, they can leave segments with live blocks (reached through other threads). Such segments are "abandoned" and will be reclaimed by other threads to reuse their pages and/or free them eventually We maintain a global list of abandoned segments that are reclaimed on demand. Since this is shared among threads the implementation needs to avoid the A-B-A problem on popping abandoned segments: We use tagged pointers to avoid accidentially identifying reused segments, much like stamped references in Java. Secondly, we maintain a reader counter to avoid resetting or decommitting segments that have a pending read operation. Note: the current implementation is one possible design; another way might be to keep track of abandoned segments in the regions. This would have the advantage of keeping all concurrent code in one place and not needing to deal with ABA issues. The drawback is that it is unclear how to scan abandoned segments efficiently in that case as they would be spread among all other segments in the regions. ----------------------------------------------------------- */ // Use the bottom 20-bits (on 64-bit) of the aligned segment pointers // to put in a tag that increments on update to avoid the A-B-A problem. #define MI_TAGGED_MASK MI_SEGMENT_MASK typedef uintptr_t mi_tagged_segment_t; static mi_segment_t* mi_tagged_segment_ptr(mi_tagged_segment_t ts) { return (mi_segment_t*)(ts & ~MI_TAGGED_MASK); } static mi_tagged_segment_t mi_tagged_segment(mi_segment_t* segment, mi_tagged_segment_t ts) { mi_assert_internal(((uintptr_t)segment & MI_TAGGED_MASK) == 0); uintptr_t tag = ((ts & MI_TAGGED_MASK) + 1) & MI_TAGGED_MASK; return ((uintptr_t)segment | tag); } // This is a list of visited abandoned pages that were full at the time. // this list migrates to `abandoned` when that becomes NULL. The use of // this list reduces contention and the rate at which segments are visited. static mi_decl_cache_align _Atomic(mi_segment_t*) abandoned_visited; // = NULL // The abandoned page list (tagged as it supports pop) static mi_decl_cache_align _Atomic(mi_tagged_segment_t) abandoned; // = NULL // Maintain these for debug purposes (these counts may be a bit off) static mi_decl_cache_align _Atomic(uintptr_t) abandoned_count; static mi_decl_cache_align _Atomic(uintptr_t) abandoned_visited_count; // We also maintain a count of current readers of the abandoned list // in order to prevent resetting/decommitting segment memory if it might // still be read. static mi_decl_cache_align _Atomic(uintptr_t) abandoned_readers; // = 0 // Push on the visited list static void mi_abandoned_visited_push(mi_segment_t* segment) { mi_assert_internal(segment->thread_id == 0); mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t,&segment->abandoned_next) == NULL); mi_assert_internal(segment->next == NULL && segment->prev == NULL); mi_assert_internal(segment->used > 0); mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited); do { mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, anext); } while (!mi_atomic_cas_ptr_weak_release(mi_segment_t, &abandoned_visited, &anext, segment)); mi_atomic_increment_relaxed(&abandoned_visited_count); } // Move the visited list to the abandoned list. static bool mi_abandoned_visited_revisit(void) { // quick check if the visited list is empty if (mi_atomic_load_ptr_relaxed(mi_segment_t, &abandoned_visited) == NULL) return false; // grab the whole visited list mi_segment_t* first = mi_atomic_exchange_ptr_acq_rel(mi_segment_t, &abandoned_visited, NULL); if (first == NULL) return false; // first try to swap directly if the abandoned list happens to be NULL mi_tagged_segment_t afirst; mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); if (mi_tagged_segment_ptr(ts)==NULL) { uintptr_t count = mi_atomic_load_relaxed(&abandoned_visited_count); afirst = mi_tagged_segment(first, ts); if (mi_atomic_cas_strong_acq_rel(&abandoned, &ts, afirst)) { mi_atomic_add_relaxed(&abandoned_count, count); mi_atomic_sub_relaxed(&abandoned_visited_count, count); return true; } } // find the last element of the visited list: O(n) mi_segment_t* last = first; mi_segment_t* next; while ((next = mi_atomic_load_ptr_relaxed(mi_segment_t, &last->abandoned_next)) != NULL) { last = next; } // and atomically prepend to the abandoned list // (no need to increase the readers as we don't access the abandoned segments) mi_tagged_segment_t anext = mi_atomic_load_relaxed(&abandoned); uintptr_t count; do { count = mi_atomic_load_relaxed(&abandoned_visited_count); mi_atomic_store_ptr_release(mi_segment_t, &last->abandoned_next, mi_tagged_segment_ptr(anext)); afirst = mi_tagged_segment(first, anext); } while (!mi_atomic_cas_weak_release(&abandoned, &anext, afirst)); mi_atomic_add_relaxed(&abandoned_count, count); mi_atomic_sub_relaxed(&abandoned_visited_count, count); return true; } // Push on the abandoned list. static void mi_abandoned_push(mi_segment_t* segment) { mi_assert_internal(segment->thread_id == 0); mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); mi_assert_internal(segment->next == NULL && segment->prev == NULL); mi_assert_internal(segment->used > 0); mi_tagged_segment_t next; mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); do { mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, mi_tagged_segment_ptr(ts)); next = mi_tagged_segment(segment, ts); } while (!mi_atomic_cas_weak_release(&abandoned, &ts, next)); mi_atomic_increment_relaxed(&abandoned_count); } // Wait until there are no more pending reads on segments that used to be in the abandoned list void _mi_abandoned_await_readers(void) { uintptr_t n; do { n = mi_atomic_load_acquire(&abandoned_readers); if (n != 0) mi_atomic_yield(); } while (n != 0); } // Pop from the abandoned list static mi_segment_t* mi_abandoned_pop(void) { mi_segment_t* segment; // Check efficiently if it is empty (or if the visited list needs to be moved) mi_tagged_segment_t ts = mi_atomic_load_relaxed(&abandoned); segment = mi_tagged_segment_ptr(ts); if (mi_likely(segment == NULL)) { if (mi_likely(!mi_abandoned_visited_revisit())) { // try to swap in the visited list on NULL return NULL; } } // Do a pop. We use a reader count to prevent // a segment to be decommitted while a read is still pending, // and a tagged pointer to prevent A-B-A link corruption. // (this is called from `region.c:_mi_mem_free` for example) mi_atomic_increment_relaxed(&abandoned_readers); // ensure no segment gets decommitted mi_tagged_segment_t next = 0; ts = mi_atomic_load_acquire(&abandoned); do { segment = mi_tagged_segment_ptr(ts); if (segment != NULL) { mi_segment_t* anext = mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next); next = mi_tagged_segment(anext, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted } } while (segment != NULL && !mi_atomic_cas_weak_acq_rel(&abandoned, &ts, next)); mi_atomic_decrement_relaxed(&abandoned_readers); // release reader lock if (segment != NULL) { mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); mi_atomic_decrement_relaxed(&abandoned_count); } return segment; } /* ----------------------------------------------------------- Abandon segment/page ----------------------------------------------------------- */ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_assert_internal(segment->used == segment->abandoned); mi_assert_internal(segment->used > 0); mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); mi_assert_expensive(mi_segment_is_valid(segment, tld)); // remove the segment from the free page queue if needed mi_reset_delayed(tld); mi_pages_reset_remove_all_in_segment(segment, mi_option_is_enabled(mi_option_abandoned_page_reset), tld); mi_segment_remove_from_free_queue(segment, tld); mi_assert_internal(segment->next == NULL && segment->prev == NULL); // all pages in the segment are abandoned; add it to the abandoned list _mi_stat_increase(&tld->stats->segments_abandoned, 1); mi_segments_track_size(-((long)segment->segment_size), tld); segment->thread_id = 0; segment->abandoned_visits = 0; mi_atomic_store_ptr_release(mi_segment_t, &segment->abandoned_next, NULL); mi_abandoned_push(segment); } void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) { mi_assert(page != NULL); mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); mi_assert_internal(mi_page_heap(page) == NULL); mi_segment_t* segment = _mi_page_segment(page); mi_assert_expensive(!mi_pages_reset_contains(page, tld)); mi_assert_expensive(mi_segment_is_valid(segment, tld)); segment->abandoned++; _mi_stat_increase(&tld->stats->pages_abandoned, 1); mi_assert_internal(segment->abandoned <= segment->used); if (segment->used == segment->abandoned) { // all pages are abandoned, abandon the entire segment mi_segment_abandon(segment, tld); } } /* ----------------------------------------------------------- Reclaim abandoned pages ----------------------------------------------------------- */ // Possibly clear pages and check if free space is available static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, bool* all_pages_free) { mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); bool has_page = false; size_t pages_used = 0; size_t pages_used_empty = 0; for (size_t i = 0; i < segment->capacity; i++) { mi_page_t* page = &segment->pages[i]; if (page->segment_in_use) { pages_used++; // ensure used count is up to date and collect potential concurrent frees _mi_page_free_collect(page, false); if (mi_page_all_free(page)) { // if everything free already, page can be reused for some block size // note: don't clear the page yet as we can only OS reset it once it is reclaimed pages_used_empty++; has_page = true; } else if (page->xblock_size == block_size && mi_page_has_any_available(page)) { // a page has available free blocks of the right size has_page = true; } } else { // whole empty page has_page = true; } } mi_assert_internal(pages_used == segment->used && pages_used >= pages_used_empty); if (all_pages_free != NULL) { *all_pages_free = ((pages_used - pages_used_empty) == 0); } return has_page; } // Reclaim a segment; returns NULL if the segment was freed // set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full. static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) { mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL); if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; } segment->thread_id = _mi_thread_id(); segment->abandoned_visits = 0; mi_segments_track_size((long)segment->segment_size, tld); mi_assert_internal(segment->next == NULL && segment->prev == NULL); mi_assert_expensive(mi_segment_is_valid(segment, tld)); _mi_stat_decrease(&tld->stats->segments_abandoned, 1); for (size_t i = 0; i < segment->capacity; i++) { mi_page_t* page = &segment->pages[i]; if (page->segment_in_use) { mi_assert_internal(!page->is_reset); mi_assert_internal(page->is_committed); mi_assert_internal(mi_page_not_in_queue(page, tld)); mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); mi_assert_internal(mi_page_heap(page) == NULL); segment->abandoned--; mi_assert(page->next == NULL); _mi_stat_decrease(&tld->stats->pages_abandoned, 1); // set the heap again and allow heap thread delayed free again. mi_page_set_heap(page, heap); _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set) // TODO: should we not collect again given that we just collected in `check_free`? _mi_page_free_collect(page, false); // ensure used count is up to date if (mi_page_all_free(page)) { // if everything free already, clear the page directly mi_segment_page_clear(segment, page, true, tld); // reset is ok now } else { // otherwise reclaim it into the heap _mi_page_reclaim(heap, page); if (requested_block_size == page->xblock_size && mi_page_has_any_available(page)) { if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; } } } } else if (page->is_committed && !page->is_reset) { // not in-use, and not reset yet // note: do not reset as this includes pages that were not touched before // mi_pages_reset_add(segment, page, tld); } } mi_assert_internal(segment->abandoned == 0); if (segment->used == 0) { mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed)); mi_segment_free(segment, false, tld); return NULL; } else { if (segment->page_kind <= MI_PAGE_MEDIUM && mi_segment_has_free(segment)) { mi_segment_insert_in_free_queue(segment, tld); } return segment; } } void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld) { mi_segment_t* segment; while ((segment = mi_abandoned_pop()) != NULL) { mi_segment_reclaim(segment, heap, 0, NULL, tld); } } static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, bool* reclaimed, mi_segments_tld_t* tld) { *reclaimed = false; mi_segment_t* segment; int max_tries = 8; // limit the work to bound allocation times while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { segment->abandoned_visits++; bool all_pages_free; bool has_page = mi_segment_check_free(segment,block_size,&all_pages_free); // try to free up pages (due to concurrent frees) if (all_pages_free) { // free the segment (by forced reclaim) to make it available to other threads. // note1: we prefer to free a segment as that might lead to reclaiming another // segment that is still partially used. // note2: we could in principle optimize this by skipping reclaim and directly // freeing but that would violate some invariants temporarily) mi_segment_reclaim(segment, heap, 0, NULL, tld); } else if (has_page && segment->page_kind == page_kind) { // found a free page of the right kind, or page of the right block_size with free space // we return the result of reclaim (which is usually `segment`) as it might free // the segment due to concurrent frees (in which case `NULL` is returned). return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld); } else if (segment->abandoned_visits >= 3) { // always reclaim on 3rd visit to limit the list length. mi_segment_reclaim(segment, heap, 0, NULL, tld); } else { // otherwise, push on the visited list so it gets not looked at too quickly again mi_abandoned_visited_push(segment); } } return NULL; } /* ----------------------------------------------------------- Reclaim or allocate ----------------------------------------------------------- */ static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { mi_assert_internal(page_kind <= MI_PAGE_LARGE); mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); // 1. try to get a segment from our cache mi_segment_t* segment = mi_segment_cache_pop(MI_SEGMENT_SIZE, tld); if (segment != NULL) { mi_segment_init(segment, 0, page_kind, page_shift, tld, os_tld); return segment; } // 2. try to reclaim an abandoned segment bool reclaimed; segment = mi_segment_try_reclaim(heap, block_size, page_kind, &reclaimed, tld); if (reclaimed) { // reclaimed the right page right into the heap mi_assert_internal(segment != NULL && segment->page_kind == page_kind && page_kind <= MI_PAGE_LARGE); return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks } else if (segment != NULL) { // reclaimed a segment with empty pages (of `page_kind`) in it return segment; } // 3. otherwise allocate a fresh segment return mi_segment_alloc(0, page_kind, page_shift, tld, os_tld); } /* ----------------------------------------------------------- Small page allocation ----------------------------------------------------------- */ static mi_page_t* mi_segment_find_free(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_assert_internal(mi_segment_has_free(segment)); mi_assert_expensive(mi_segment_is_valid(segment, tld)); for (size_t i = 0; i < segment->capacity; i++) { // TODO: use a bitmap instead of search? mi_page_t* page = &segment->pages[i]; if (!page->segment_in_use) { bool ok = mi_segment_page_claim(segment, page, tld); if (ok) return page; } } mi_assert(false); return NULL; } // Allocate a page inside a segment. Requires that the page has free pages static mi_page_t* mi_segment_page_alloc_in(mi_segment_t* segment, mi_segments_tld_t* tld) { mi_assert_internal(mi_segment_has_free(segment)); return mi_segment_find_free(segment, tld); } static mi_page_t* mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { // find an available segment the segment free queue mi_segment_queue_t* const free_queue = mi_segment_free_queue_of_kind(kind, tld); if (mi_segment_queue_is_empty(free_queue)) { // possibly allocate or reclaim a fresh segment mi_segment_t* const segment = mi_segment_reclaim_or_alloc(heap, block_size, kind, page_shift, tld, os_tld); if (segment == NULL) return NULL; // return NULL if out-of-memory (or reclaimed) mi_assert_internal(free_queue->first == segment); mi_assert_internal(segment->page_kind==kind); mi_assert_internal(segment->used < segment->capacity); } mi_assert_internal(free_queue->first != NULL); mi_page_t* const page = mi_segment_page_alloc_in(free_queue->first, tld); mi_assert_internal(page != NULL); #if MI_DEBUG>=2 // verify it is committed _mi_segment_page_start(_mi_page_segment(page), page, sizeof(void*), NULL, NULL)[0] = 0; #endif return page; } static mi_page_t* mi_segment_small_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { return mi_segment_page_alloc(heap, block_size, MI_PAGE_SMALL,MI_SMALL_PAGE_SHIFT,tld,os_tld); } static mi_page_t* mi_segment_medium_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { return mi_segment_page_alloc(heap, block_size, MI_PAGE_MEDIUM, MI_MEDIUM_PAGE_SHIFT, tld, os_tld); } /* ----------------------------------------------------------- large page allocation ----------------------------------------------------------- */ static mi_page_t* mi_segment_large_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { mi_segment_t* segment = mi_segment_reclaim_or_alloc(heap,block_size,MI_PAGE_LARGE,MI_LARGE_PAGE_SHIFT,tld,os_tld); if (segment == NULL) return NULL; mi_page_t* page = mi_segment_find_free(segment, tld); mi_assert_internal(page != NULL); #if MI_DEBUG>=2 _mi_segment_page_start(segment, page, sizeof(void*), NULL, NULL)[0] = 0; #endif return page; } static mi_page_t* mi_segment_huge_page_alloc(size_t size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { mi_segment_t* segment = mi_segment_alloc(size, MI_PAGE_HUGE, MI_SEGMENT_SHIFT,tld,os_tld); if (segment == NULL) return NULL; mi_assert_internal(mi_segment_page_size(segment) - segment->segment_info_size - (2*(MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= size); segment->thread_id = 0; // huge pages are immediately abandoned mi_segments_track_size(-(long)segment->segment_size, tld); mi_page_t* page = mi_segment_find_free(segment, tld); mi_assert_internal(page != NULL); return page; } // free huge block from another thread void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { // huge page segments are always abandoned and can be freed immediately by any thread mi_assert_internal(segment->page_kind==MI_PAGE_HUGE); mi_assert_internal(segment == _mi_page_segment(page)); mi_assert_internal(mi_atomic_load_relaxed(&segment->thread_id)==0); // claim it and free mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized. // paranoia: if this it the last reference, the cas should always succeed uintptr_t expected_tid = 0; if (mi_atomic_cas_strong_acq_rel(&segment->thread_id, &expected_tid, heap->thread_id)) { mi_block_set_next(page, block, page->free); page->free = block; page->used--; page->is_zero = false; mi_assert(page->used == 0); mi_tld_t* tld = heap->tld; const size_t bsize = mi_page_usable_block_size(page); if (bsize > MI_HUGE_OBJ_SIZE_MAX) { _mi_stat_decrease(&tld->stats.giant, bsize); } else { _mi_stat_decrease(&tld->stats.huge, bsize); } mi_segments_track_size((long)segment->segment_size, &tld->segments); _mi_segment_page_free(page, true, &tld->segments); } #if (MI_DEBUG!=0) else { mi_assert_internal(false); } #endif } /* ----------------------------------------------------------- Page allocation ----------------------------------------------------------- */ mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { mi_page_t* page; if (block_size <= MI_SMALL_OBJ_SIZE_MAX) { page = mi_segment_small_page_alloc(heap, block_size, tld, os_tld); } else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) { page = mi_segment_medium_page_alloc(heap, block_size, tld, os_tld); } else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) { page = mi_segment_large_page_alloc(heap, block_size, tld, os_tld); } else { page = mi_segment_huge_page_alloc(block_size,tld,os_tld); } mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size); mi_reset_delayed(tld); mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld)); return page; } ================================================ FILE: runtime/src/mimalloc/c/static.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #if defined(__sun) // same remarks as os.c for the static's context. #undef _XOPEN_SOURCE #undef _POSIX_C_SOURCE #endif #include "mimalloc.h" #include "mimalloc-internal.h" // For a static override we create a single object file // containing the whole library. If it is linked first // it will override all the standard library allocation // functions (on Unix's). #include "stats.c" #include "random.c" #include "os.c" #include "arena.c" #include "region.c" #include "segment.c" #include "page.c" #include "heap.c" #include "alloc.c" #include "alloc-aligned.c" #include "alloc-posix.c" #if MI_OSX_ZONE #include "alloc-override-osx.c" #endif #include "init.c" #include "options.c" ================================================ FILE: runtime/src/mimalloc/c/stats.c ================================================ /* ---------------------------------------------------------------------------- Copyright (c) 2018, Microsoft Research, Daan Leijen This is free software; you can redistribute it and/or modify it under the terms of the MIT license. A copy of the license can be found in the file "licenses/third_party/mimalloc_LICENSE.txt" at the root of this distribution. -----------------------------------------------------------------------------*/ #include "mimalloc.h" #include "mimalloc-internal.h" #include "mimalloc-atomic.h" #include // fputs, stderr #include // memset #if defined(_MSC_VER) && (_MSC_VER < 1920) #pragma warning(disable:4204) // non-constant aggregate initializer #endif /* ----------------------------------------------------------- Statistics operations ----------------------------------------------------------- */ static bool mi_is_in_main(void* stat) { return ((uint8_t*)stat >= (uint8_t*)&_mi_stats_main && (uint8_t*)stat < ((uint8_t*)&_mi_stats_main + sizeof(mi_stats_t))); } static void mi_stat_update(mi_stat_count_t* stat, int64_t amount) { if (amount == 0) return; if (mi_is_in_main(stat)) { // add atomically (for abandoned pages) int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount); mi_atomic_maxi64_relaxed(&stat->peak, current + amount); if (amount > 0) { mi_atomic_addi64_relaxed(&stat->allocated,amount); } else { mi_atomic_addi64_relaxed(&stat->freed, -amount); } } else { // add thread local stat->current += amount; if (stat->current > stat->peak) stat->peak = stat->current; if (amount > 0) { stat->allocated += amount; } else { stat->freed += -amount; } } } void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) { if (mi_is_in_main(stat)) { mi_atomic_addi64_relaxed( &stat->count, 1 ); mi_atomic_addi64_relaxed( &stat->total, (int64_t)amount ); } else { stat->count++; stat->total += amount; } } void _mi_stat_increase(mi_stat_count_t* stat, size_t amount) { mi_stat_update(stat, (int64_t)amount); } void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount) { mi_stat_update(stat, -((int64_t)amount)); } // must be thread safe as it is called from stats_merge static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) { if (stat==src) return; if (src->allocated==0 && src->freed==0) return; mi_atomic_addi64_relaxed( &stat->allocated, src->allocated * unit); mi_atomic_addi64_relaxed( &stat->current, src->current * unit); mi_atomic_addi64_relaxed( &stat->freed, src->freed * unit); // peak scores do not work across threads.. mi_atomic_addi64_relaxed( &stat->peak, src->peak * unit); } static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) { if (stat==src) return; mi_atomic_addi64_relaxed( &stat->total, src->total * unit); mi_atomic_addi64_relaxed( &stat->count, src->count * unit); } // must be thread safe as it is called from stats_merge static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) { if (stats==src) return; mi_stat_add(&stats->segments, &src->segments,1); mi_stat_add(&stats->pages, &src->pages,1); mi_stat_add(&stats->reserved, &src->reserved, 1); mi_stat_add(&stats->committed, &src->committed, 1); mi_stat_add(&stats->reset, &src->reset, 1); mi_stat_add(&stats->page_committed, &src->page_committed, 1); mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned, 1); mi_stat_add(&stats->segments_abandoned, &src->segments_abandoned, 1); mi_stat_add(&stats->threads, &src->threads, 1); mi_stat_add(&stats->malloc, &src->malloc, 1); mi_stat_add(&stats->segments_cache, &src->segments_cache, 1); mi_stat_add(&stats->huge, &src->huge, 1); mi_stat_add(&stats->giant, &src->giant, 1); mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1); mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1); mi_stat_counter_add(&stats->commit_calls, &src->commit_calls, 1); mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1); mi_stat_counter_add(&stats->searches, &src->searches, 1); mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1); mi_stat_counter_add(&stats->giant_count, &src->giant_count, 1); #if MI_STAT>1 for (size_t i = 0; i <= MI_BIN_HUGE; i++) { if (src->normal[i].allocated > 0 || src->normal[i].freed > 0) { mi_stat_add(&stats->normal[i], &src->normal[i], 1); } } #endif } /* ----------------------------------------------------------- Display statistics ----------------------------------------------------------- */ // unit > 0 : size in binary bytes // unit == 0: count as decimal // unit < 0 : count in binary static void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) { char buf[32]; int len = 32; const char* suffix = (unit <= 0 ? " " : "b"); const int64_t base = (unit == 0 ? 1000 : 1024); if (unit>0) n *= unit; const int64_t pos = (n < 0 ? -n : n); if (pos < base) { snprintf(buf, len, "%d %s ", (int)n, suffix); } else { int64_t divider = base; const char* magnitude = "k"; if (pos >= divider*base) { divider *= base; magnitude = "m"; } if (pos >= divider*base) { divider *= base; magnitude = "g"; } const int64_t tens = (n / (divider/10)); const long whole = (long)(tens/10); const long frac1 = (long)(tens%10); snprintf(buf, len, "%ld.%ld %s%s", whole, frac1, magnitude, suffix); } _mi_fprintf(out, arg, (fmt==NULL ? "%11s" : fmt), buf); } static void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { mi_printf_amount(n,unit,out,arg,NULL); } static void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { if (unit==1) _mi_fprintf(out, arg, "%11s"," "); else mi_print_amount(n,0,out,arg); } static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg ) { _mi_fprintf(out, arg,"%10s:", msg); if (unit>0) { mi_print_amount(stat->peak, unit, out, arg); mi_print_amount(stat->allocated, unit, out, arg); mi_print_amount(stat->freed, unit, out, arg); mi_print_amount(unit, 1, out, arg); mi_print_count(stat->allocated, unit, out, arg); if (stat->allocated > stat->freed) _mi_fprintf(out, arg, " not all freed!\n"); else _mi_fprintf(out, arg, " ok\n"); } else if (unit<0) { mi_print_amount(stat->peak, -1, out, arg); mi_print_amount(stat->allocated, -1, out, arg); mi_print_amount(stat->freed, -1, out, arg); if (unit==-1) { _mi_fprintf(out, arg, "%22s", ""); } else { mi_print_amount(-unit, 1, out, arg); mi_print_count((stat->allocated / -unit), 0, out, arg); } if (stat->allocated > stat->freed) _mi_fprintf(out, arg, " not all freed!\n"); else _mi_fprintf(out, arg, " ok\n"); } else { mi_print_amount(stat->peak, 1, out, arg); mi_print_amount(stat->allocated, 1, out, arg); _mi_fprintf(out, arg, "\n"); } } static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) { _mi_fprintf(out, arg, "%10s:", msg); mi_print_amount(stat->total, -1, out, arg); _mi_fprintf(out, arg, "\n"); } static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg) { const int64_t avg_tens = (stat->count == 0 ? 0 : (stat->total*10 / stat->count)); const long avg_whole = (long)(avg_tens/10); const long avg_frac1 = (long)(avg_tens%10); _mi_fprintf(out, arg, "%10s: %5ld.%ld avg\n", msg, avg_whole, avg_frac1); } static void mi_print_header(mi_output_fun* out, void* arg ) { _mi_fprintf(out, arg, "%10s: %10s %10s %10s %10s %10s\n", "heap stats", "peak ", "total ", "freed ", "unit ", "count "); } #if MI_STAT>1 static void mi_stats_print_bins(mi_stat_count_t* all, const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) { bool found = false; char buf[64]; for (size_t i = 0; i <= max; i++) { if (bins[i].allocated > 0) { found = true; int64_t unit = _mi_bin_size((uint8_t)i); snprintf(buf, 64, "%s %3lu", fmt, (long)i); mi_stat_add(all, &bins[i], unit); mi_stat_print(&bins[i], buf, unit, out, arg); } } //snprintf(buf, 64, "%s all", fmt); //mi_stat_print(all, buf, 1); if (found) { _mi_fprintf(out, arg, "\n"); mi_print_header(out, arg); } } #endif //------------------------------------------------------------ // Use an output wrapper for line-buffered output // (which is nice when using loggers etc.) //------------------------------------------------------------ typedef struct buffered_s { mi_output_fun* out; // original output function void* arg; // and state char* buf; // local buffer of at least size `count+1` size_t used; // currently used chars `used <= count` size_t count; // total chars available for output } buffered_t; static void mi_buffered_flush(buffered_t* buf) { buf->buf[buf->used] = 0; _mi_fputs(buf->out, buf->arg, NULL, buf->buf); buf->used = 0; } static void mi_buffered_out(const char* msg, void* arg) { buffered_t* buf = (buffered_t*)arg; if (msg==NULL || buf==NULL) return; for (const char* src = msg; *src != 0; src++) { char c = *src; if (buf->used >= buf->count) mi_buffered_flush(buf); mi_assert_internal(buf->used < buf->count); buf->buf[buf->used++] = c; if (c == '\n') mi_buffered_flush(buf); } } //------------------------------------------------------------ // Print statistics //------------------------------------------------------------ static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults); static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr_noexcept { // wrap the output function to be line buffered char buf[256]; buffered_t buffer = { out0, arg0, NULL, 0, 255 }; buffer.buf = buf; mi_output_fun* out = &mi_buffered_out; void* arg = &buffer; // and print using that mi_print_header(out,arg); #if MI_STAT>1 mi_stat_count_t normal = { 0,0,0,0 }; mi_stats_print_bins(&normal, stats->normal, MI_BIN_HUGE, "normal",out,arg); mi_stat_print(&normal, "normal", 1, out, arg); mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg); mi_stat_print(&stats->giant, "giant", (stats->giant_count.count == 0 ? 1 : -(stats->giant.allocated / stats->giant_count.count)), out, arg); mi_stat_count_t total = { 0,0,0,0 }; mi_stat_add(&total, &normal, 1); mi_stat_add(&total, &stats->huge, 1); mi_stat_add(&total, &stats->giant, 1); mi_stat_print(&total, "total", 1, out, arg); _mi_fprintf(out, arg, "malloc requested: "); mi_print_amount(stats->malloc.allocated, 1, out, arg); _mi_fprintf(out, arg, "\n\n"); #endif mi_stat_print(&stats->reserved, "reserved", 1, out, arg); mi_stat_print(&stats->committed, "committed", 1, out, arg); mi_stat_print(&stats->reset, "reset", 1, out, arg); mi_stat_print(&stats->page_committed, "touched", 1, out, arg); mi_stat_print(&stats->segments, "segments", -1, out, arg); mi_stat_print(&stats->segments_abandoned, "-abandoned", -1, out, arg); mi_stat_print(&stats->segments_cache, "-cached", -1, out, arg); mi_stat_print(&stats->pages, "pages", -1, out, arg); mi_stat_print(&stats->pages_abandoned, "-abandoned", -1, out, arg); mi_stat_counter_print(&stats->pages_extended, "-extended", out, arg); mi_stat_counter_print(&stats->page_no_retire, "-noretire", out, arg); mi_stat_counter_print(&stats->mmap_calls, "mmaps", out, arg); mi_stat_counter_print(&stats->commit_calls, "commits", out, arg); mi_stat_print(&stats->threads, "threads", -1, out, arg); mi_stat_counter_print_avg(&stats->searches, "searches", out, arg); _mi_fprintf(out, arg, "%10s: %7i\n", "numa nodes", _mi_os_numa_node_count()); mi_msecs_t elapsed; mi_msecs_t user_time; mi_msecs_t sys_time; size_t current_rss; size_t peak_rss; size_t current_commit; size_t peak_commit; size_t page_faults; mi_stat_process_info(&elapsed, &user_time, &sys_time, ¤t_rss, &peak_rss, ¤t_commit, &peak_commit, &page_faults); _mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000); _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, rss: ", "process", user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults ); mi_printf_amount((int64_t)peak_rss, 1, out, arg, "%s"); if (peak_commit > 0) { _mi_fprintf(out, arg, ", commit: "); mi_printf_amount((int64_t)peak_commit, 1, out, arg, "%s"); } _mi_fprintf(out, arg, "\n"); } static mi_msecs_t mi_process_start; // = 0 static mi_stats_t* mi_stats_get_default(void) { mi_heap_t* heap = mi_heap_get_default(); return &heap->tld->stats; } static void mi_stats_merge_from(mi_stats_t* stats) { if (stats != &_mi_stats_main) { mi_stats_add(&_mi_stats_main, stats); memset(stats, 0, sizeof(mi_stats_t)); } } void mi_stats_reset(void) mi_attr_noexcept { mi_stats_t* stats = mi_stats_get_default(); if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); } memset(&_mi_stats_main, 0, sizeof(mi_stats_t)); if (mi_process_start == 0) { mi_process_start = _mi_clock_start(); }; } void mi_stats_merge(void) mi_attr_noexcept { mi_stats_merge_from( mi_stats_get_default() ); } void _mi_stats_done(mi_stats_t* stats) { // called from `mi_thread_done` mi_stats_merge_from(stats); } void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { mi_stats_merge_from(mi_stats_get_default()); _mi_stats_print(&_mi_stats_main, out, arg); } void mi_stats_print(void* out) mi_attr_noexcept { // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`) mi_stats_print_out((mi_output_fun*)out, NULL); } void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { _mi_stats_print(mi_stats_get_default(), out, arg); } // ---------------------------------------------------------------- // Basic timer for convenience; use milli-seconds to avoid doubles // ---------------------------------------------------------------- #ifdef _WIN32 #include static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) { static LARGE_INTEGER mfreq; // = 0 if (mfreq.QuadPart == 0LL) { LARGE_INTEGER f; QueryPerformanceFrequency(&f); mfreq.QuadPart = f.QuadPart/1000LL; if (mfreq.QuadPart == 0) mfreq.QuadPart = 1; } return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart); } mi_msecs_t _mi_clock_now(void) { LARGE_INTEGER t; QueryPerformanceCounter(&t); return mi_to_msecs(t); } #else #include #ifdef CLOCK_REALTIME mi_msecs_t _mi_clock_now(void) { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); } #else // low resolution timer mi_msecs_t _mi_clock_now(void) { return ((mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000)); } #endif #endif static mi_msecs_t mi_clock_diff; mi_msecs_t _mi_clock_start(void) { if (mi_clock_diff == 0.0) { mi_msecs_t t0 = _mi_clock_now(); mi_clock_diff = _mi_clock_now() - t0; } return _mi_clock_now(); } mi_msecs_t _mi_clock_end(mi_msecs_t start) { mi_msecs_t end = _mi_clock_now(); return (end - start - mi_clock_diff); } // -------------------------------------------------------- // Basic process statistics // -------------------------------------------------------- #if defined(_WIN32) #include #include #pragma comment(lib,"psapi.lib") static mi_msecs_t filetime_msecs(const FILETIME* ftime) { ULARGE_INTEGER i; i.LowPart = ftime->dwLowDateTime; i.HighPart = ftime->dwHighDateTime; mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds return msecs; } static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) { *elapsed = _mi_clock_end(mi_process_start); FILETIME ct; FILETIME ut; FILETIME st; FILETIME et; GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut); *utime = filetime_msecs(&ut); *stime = filetime_msecs(&st); PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); *current_rss = (size_t)info.WorkingSetSize; *peak_rss = (size_t)info.PeakWorkingSetSize; *current_commit = (size_t)info.PagefileUsage; *peak_commit = (size_t)info.PeakPagefileUsage; *page_faults = (size_t)info.PageFaultCount; } #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) #include #include #include #if defined(__APPLE__) && defined(__MACH__) #include #endif #if defined(__HAIKU__) #include #endif static mi_msecs_t timeval_secs(const struct timeval* tv) { return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L); } static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) { *elapsed = _mi_clock_end(mi_process_start); struct rusage rusage; getrusage(RUSAGE_SELF, &rusage); *utime = timeval_secs(&rusage.ru_utime); *stime = timeval_secs(&rusage.ru_stime); #if !defined(__HAIKU__) *page_faults = rusage.ru_majflt; #endif // estimate commit using our stats *peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); *current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); *current_rss = *current_commit; // estimate #if defined(__HAIKU__) // Haiku does not have (yet?) a way to // get these stats per process thread_info tid; area_info mem; ssize_t c; get_thread_info(find_thread(0), &tid); while (get_next_area_info(tid.team, &c, &mem) == B_OK) { *peak_rss += mem.ram_size; } #elif defined(__APPLE__) && defined(__MACH__) *peak_rss = rusage.ru_maxrss; // BSD reports in bytes struct mach_task_basic_info info; mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS) { *current_rss = (size_t)info.resident_size; } #else *peak_rss = rusage.ru_maxrss * 1024; // Linux reports in KiB #endif } #else #ifndef __wasi__ // WebAssembly instances are not processes #pragma message("define a way to get process info") #endif static void mi_stat_process_info(mi_msecs_t* elapsed, mi_msecs_t* utime, mi_msecs_t* stime, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) { *elapsed = _mi_clock_end(mi_process_start); *peak_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.peak)); *current_commit = (size_t)(mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)&_mi_stats_main.committed.current)); *peak_rss = *peak_commit; *current_rss = *current_commit; *page_faults = 0; *utime = 0; *stime = 0; } #endif mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs, size_t* current_rss, size_t* peak_rss, size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept { mi_msecs_t elapsed = 0; mi_msecs_t utime = 0; mi_msecs_t stime = 0; size_t current_rss0 = 0; size_t peak_rss0 = 0; size_t current_commit0 = 0; size_t peak_commit0 = 0; size_t page_faults0 = 0; mi_stat_process_info(&elapsed,&utime, &stime, ¤t_rss0, &peak_rss0, ¤t_commit0, &peak_commit0, &page_faults0); if (elapsed_msecs!=NULL) *elapsed_msecs = (elapsed < 0 ? 0 : (elapsed < (mi_msecs_t)PTRDIFF_MAX ? (size_t)elapsed : PTRDIFF_MAX)); if (user_msecs!=NULL) *user_msecs = (utime < 0 ? 0 : (utime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)utime : PTRDIFF_MAX)); if (system_msecs!=NULL) *system_msecs = (stime < 0 ? 0 : (stime < (mi_msecs_t)PTRDIFF_MAX ? (size_t)stime : PTRDIFF_MAX)); if (current_rss!=NULL) *current_rss = current_rss0; if (peak_rss!=NULL) *peak_rss = peak_rss0; if (current_commit!=NULL) *current_commit = current_commit0; if (peak_commit!=NULL) *peak_commit = peak_commit0; if (page_faults!=NULL) *page_faults = page_faults0; } ================================================ FILE: runtime/src/mm/cpp/ExceptionObjHolder.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" #include "StableRefRegistry.hpp" #include "ThreadData.hpp" #include "ThreadRegistry.hpp" using namespace kotlin; namespace { #if !KONAN_NO_EXCEPTIONS class ExceptionObjHolderImpl : public ExceptionObjHolder { public: explicit ExceptionObjHolderImpl(ObjHeader* obj) noexcept { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); stableRef_ = threadData->stableRefThreadQueue().Insert(obj); } ~ExceptionObjHolderImpl() override { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->stableRefThreadQueue().Erase(stableRef_); } ObjHeader* obj() noexcept { return **stableRef_; } private: mm::StableRefRegistry::Node* stableRef_; }; #endif } // namespace #if !KONAN_NO_EXCEPTIONS // static RUNTIME_NORETURN void ExceptionObjHolder::Throw(ObjHeader* exception) { throw ExceptionObjHolderImpl(exception); } ObjHeader* ExceptionObjHolder::GetExceptionObject() noexcept { return static_cast(this)->obj(); } #endif ================================================ FILE: runtime/src/mm/cpp/ExceptionObjHolderTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Memory.h" #include "TestSupport.hpp" #include "ThreadData.hpp" #include "Types.h" using namespace kotlin; namespace { class ExceptionObjHolderTest : public ::testing::Test { public: ~ExceptionObjHolderTest() { auto& stableRefs = mm::StableRefRegistry::Instance(); stableRefs.ClearForTests(); } static KStdVector Collect(mm::ThreadData& threadData) { auto& stableRefs = mm::StableRefRegistry::Instance(); stableRefs.ProcessThread(&threadData); stableRefs.ProcessDeletions(); KStdVector result; for (const auto& obj : stableRefs.Iter()) { result.push_back(obj); } return result; } private: }; } // namespace TEST_F(ExceptionObjHolderTest, NothingByDefault) { RunInNewThread([](mm::ThreadData& threadData) { EXPECT_THAT(Collect(threadData), testing::IsEmpty()); }); } TEST_F(ExceptionObjHolderTest, Throw) { RunInNewThread([](mm::ThreadData& threadData) { ASSERT_THAT(Collect(threadData), testing::IsEmpty()); ObjHeader exception; try { ExceptionObjHolder::Throw(&exception); } catch (...) { EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception)); } EXPECT_THAT(Collect(threadData), testing::IsEmpty()); }); } TEST_F(ExceptionObjHolderTest, ThrowInsideCatch) { RunInNewThread([](mm::ThreadData& threadData) { ASSERT_THAT(Collect(threadData), testing::IsEmpty()); ObjHeader exception1; try { ExceptionObjHolder::Throw(&exception1); } catch (...) { ObjHeader exception2; try { ExceptionObjHolder::Throw(&exception2); } catch (...) { EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception1, &exception2)); } EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception1)); } EXPECT_THAT(Collect(threadData), testing::IsEmpty()); }); } TEST_F(ExceptionObjHolderTest, StoreException) { RunInNewThread([](mm::ThreadData& threadData) { ASSERT_THAT(Collect(threadData), testing::IsEmpty()); ObjHeader exception1; std::exception_ptr storedException1; try { ExceptionObjHolder::Throw(&exception1); } catch (...) { storedException1 = std::current_exception(); } EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception1)); ObjHeader exception2; std::exception_ptr storedException2; try { ExceptionObjHolder::Throw(&exception2); } catch (...) { storedException2 = std::current_exception(); } EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception1, &exception2)); storedException1 = std::exception_ptr(); EXPECT_THAT(Collect(threadData), testing::ElementsAre(&exception2)); storedException2 = std::exception_ptr(); EXPECT_THAT(Collect(threadData), testing::IsEmpty()); }); } ================================================ FILE: runtime/src/mm/cpp/ExtraObjectData.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ExtraObjectData.hpp" #include "PointerBits.h" #include "Weak.h" #ifdef KONAN_OBJC_INTEROP #include "ObjCMMAPI.h" #endif using namespace kotlin; namespace { template ALWAYS_INLINE T UnsafeRead(T* location) noexcept { #if __has_feature(thread_sanitizer) // Make TSAN think that this load is fine. return __atomic_load_n(location, __ATOMIC_ACQUIRE); #else return *location; #endif } } // namespace // static mm::ExtraObjectData& mm::ExtraObjectData::Install(ObjHeader* object) noexcept { // TODO: Consider extracting initialization scheme with speculative load. // `object->typeInfoOrMeta_` is assigned at most once. If we read some old value (i.e. not a meta object), // we will fail at CAS below. If we read the new value, we will immediately return it. TypeInfo* typeInfo = UnsafeRead(&object->typeInfoOrMeta_); if (auto* metaObject = ObjHeader::AsMetaObject(typeInfo)) { return mm::ExtraObjectData::FromMetaObjHeader(metaObject); } RuntimeCheck(!hasPointerBits(typeInfo, OBJECT_TAG_MASK), "Object must not be tagged"); auto* data = new ExtraObjectData(typeInfo); TypeInfo* old = __sync_val_compare_and_swap(&object->typeInfoOrMeta_, typeInfo, reinterpret_cast(data)); if (old != typeInfo) { // Somebody else created `mm::ExtraObjectData` for this object delete data; return *reinterpret_cast(old); } return *data; } // static void mm::ExtraObjectData::Uninstall(ObjHeader* object) noexcept { RuntimeAssert(object->has_meta_object(), "Object must have a meta object set"); auto& data = ExtraObjectData::FromMetaObjHeader(object->meta_object()); *const_cast(&object->typeInfoOrMeta_) = data.typeInfo_; delete &data; } mm::ExtraObjectData::~ExtraObjectData() { if (weakReferenceCounter_) { WeakReferenceCounterClear(weakReferenceCounter_); ZeroHeapRef(&weakReferenceCounter_); } #ifdef KONAN_OBJC_INTEROP Kotlin_ObjCExport_releaseAssociatedObject(associatedObject_); #endif } ================================================ FILE: runtime/src/mm/cpp/ExtraObjectData.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_EXTRA_OBJECT_DATA_H #define RUNTIME_MM_EXTRA_OBJECT_DATA_H #include #include #include "Alloc.h" #include "Memory.h" #include "TypeInfo.h" #include "Utils.hpp" namespace kotlin { namespace mm { // Optional data that's lazily allocated only for objects that need it. class ExtraObjectData : private Pinned, public KonanAllocatorAware { public: MetaObjHeader* AsMetaObjHeader() noexcept { return reinterpret_cast(this); } static ExtraObjectData& FromMetaObjHeader(MetaObjHeader* header) noexcept { return *reinterpret_cast(header); } static ExtraObjectData& Install(ObjHeader* object) noexcept; static void Uninstall(ObjHeader* object) noexcept; #ifdef KONAN_OBJC_INTEROP void** GetAssociatedObjectLocation() noexcept { return &associatedObject_; } #endif ObjHeader** GetWeakCounterLocation() noexcept { return &weakReferenceCounter_; } private: explicit ExtraObjectData(const TypeInfo* typeInfo) noexcept : typeInfo_(typeInfo) {} ~ExtraObjectData(); // Must be first to match `TypeInfo` layout. const TypeInfo* typeInfo_; #ifdef KONAN_OBJC_INTEROP void* associatedObject_ = nullptr; #endif // TODO: Need to respect when marking. ObjHeader* weakReferenceCounter_ = nullptr; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_EXTRA_OBJECT_DATA_H ================================================ FILE: runtime/src/mm/cpp/ExtraObjectDataTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ExtraObjectData.hpp" #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "TestSupport.hpp" using namespace kotlin; TEST(ExtraObjectDataTest, Install) { TypeInfo typeInfo; typeInfo.typeInfo_ = &typeInfo; ObjHeader object; object.typeInfoOrMeta_ = &typeInfo; ASSERT_FALSE(object.has_meta_object()); auto& extraData = mm::ExtraObjectData::Install(&object); EXPECT_TRUE(object.has_meta_object()); EXPECT_THAT(object.meta_object(), extraData.AsMetaObjHeader()); EXPECT_THAT(object.type_info(), &typeInfo); mm::ExtraObjectData::Uninstall(&object); EXPECT_FALSE(object.has_meta_object()); EXPECT_THAT(object.type_info(), &typeInfo); } TEST(ExtraObjectDataTest, ConcurrentInstall) { TypeInfo typeInfo; typeInfo.typeInfo_ = &typeInfo; ObjHeader object; object.typeInfoOrMeta_ = &typeInfo; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); std::vector threads; std::vector actual(kThreadCount, nullptr); for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back([i, &actual, &object, &canStart, &readyCount]() { ++readyCount; while (!canStart) { } auto& extraData = mm::ExtraObjectData::Install(&object); actual[i] = &extraData; }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } std::vector expected(kThreadCount, actual[0]); EXPECT_THAT(actual, testing::ElementsAreArray(expected)); mm::ExtraObjectData::Uninstall(&object); } ================================================ FILE: runtime/src/mm/cpp/GC.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_GC_H #define RUNTIME_MM_GC_H #include "gc/NoOpGC.hpp" namespace kotlin { namespace mm { // TODO: GC should be extracted into a separate module, so that we can do different GCs without // the need to redo the entire MM. For now changing GCs can be done by modifying `using` below. using GC = NoOpGC; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_GC_H ================================================ FILE: runtime/src/mm/cpp/GlobalData.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "GlobalData.hpp" using namespace kotlin; mm::GlobalData::GlobalData() = default; // static mm::GlobalData mm::GlobalData::instance_ [[clang::no_destroy]]; ================================================ FILE: runtime/src/mm/cpp/GlobalData.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_GLOBAL_DATA_H #define RUNTIME_MM_GLOBAL_DATA_H #include "ObjectFactory.hpp" #include "GlobalsRegistry.hpp" #include "GC.hpp" #include "StableRefRegistry.hpp" #include "ThreadRegistry.hpp" #include "Utils.hpp" namespace kotlin { namespace mm { // Global (de)initialization is undefined in C++. Use single global singleton to define it for simplicity. class GlobalData : private Pinned { public: static GlobalData& Instance() noexcept { return instance_; } ThreadRegistry& threadRegistry() noexcept { return threadRegistry_; } GlobalsRegistry& globalsRegistry() noexcept { return globalsRegistry_; } StableRefRegistry& stableRefRegistry() noexcept { return stableRefRegistry_; } ObjectFactory& objectFactory() noexcept { return objectFactory_; } GC& gc() noexcept { return gc_; } private: GlobalData(); ~GlobalData() = delete; // This `GlobalData` is never destroyed. static GlobalData instance_; ThreadRegistry threadRegistry_; GlobalsRegistry globalsRegistry_; StableRefRegistry stableRefRegistry_; ObjectFactory objectFactory_; GC gc_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_GLOBAL_DATA_H ================================================ FILE: runtime/src/mm/cpp/GlobalsRegistry.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "GlobalsRegistry.hpp" #include #include "GlobalData.hpp" #include "ThreadData.hpp" using namespace kotlin; // static mm::GlobalsRegistry& mm::GlobalsRegistry::Instance() noexcept { return GlobalData::Instance().globalsRegistry(); } void mm::GlobalsRegistry::RegisterStorageForGlobal(mm::ThreadData* threadData, ObjHeader** location) noexcept { threadData->globalsThreadQueue().Insert(location); } void mm::GlobalsRegistry::ProcessThread(mm::ThreadData* threadData) noexcept { threadData->globalsThreadQueue().Publish(); } mm::GlobalsRegistry::GlobalsRegistry() = default; mm::GlobalsRegistry::~GlobalsRegistry() = default; ================================================ FILE: runtime/src/mm/cpp/GlobalsRegistry.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_GLOBALS_REGISTRY_H #define RUNTIME_MM_GLOBALS_REGISTRY_H #include "Memory.h" #include "MultiSourceQueue.hpp" #include "ThreadRegistry.hpp" #include "Utils.hpp" namespace kotlin { namespace mm { class GlobalsRegistry : Pinned { public: class ThreadQueue : public MultiSourceQueue::Producer { public: explicit ThreadQueue(GlobalsRegistry& registry) : Producer(registry.globals_) {} // Do not add fields as this is just a wrapper and Producer does not have virtual destructor. }; using Iterable = MultiSourceQueue::Iterable; using Iterator = MultiSourceQueue::Iterator; GlobalsRegistry(); ~GlobalsRegistry(); static GlobalsRegistry& Instance() noexcept; void RegisterStorageForGlobal(mm::ThreadData* threadData, ObjHeader** location) noexcept; // Collect globals from thread corresponding to `threadData`. Must be called by the thread // when it's asked by GC to stop. void ProcessThread(mm::ThreadData* threadData) noexcept; // Lock registry for safe iteration. // TODO: Iteration over `globals_` will be slow, because it's `KStdList` collected at different times from // different threads, and so the nodes are all over the memory. Use metrics to understand how // much of a problem is it. Iterable Iter() noexcept { return globals_.Iter(); } private: // TODO: Add-only MultiSourceQueue can be made more efficient. Measure, if it's a problem. MultiSourceQueue globals_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_GLOBALS_REGISTRY_H ================================================ FILE: runtime/src/mm/cpp/InitializationScheme.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "InitializationScheme.hpp" #include "Common.h" #include "ObjectOps.hpp" #include "ThreadData.hpp" using namespace kotlin; OBJ_GETTER(mm::InitThreadLocalSingleton, ThreadData* threadData, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { if (auto* value = *location) { // Initialized by someone else. RETURN_OBJ(value); } auto* value = mm::AllocateObject(threadData, typeInfo, OBJ_RESULT); mm::SetHeapRef(location, value); #if KONAN_NO_EXCEPTIONS ctor(value); #else try { ctor(value); } catch (...) { mm::SetStackRef(OBJ_RESULT, nullptr); mm::SetHeapRef(location, nullptr); throw; } #endif return value; } OBJ_GETTER(mm::InitSingleton, ThreadData* threadData, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { auto& initializingSingletons = threadData->initializingSingletons(); // Search from the top of the stack. for (auto it = initializingSingletons.rbegin(); it != initializingSingletons.rend(); ++it) { if (it->first == location) { RETURN_OBJ(it->second); } } ObjHeader* initializing = reinterpret_cast(1); // Spin lock. ObjHeader* value = nullptr; while ((value = __sync_val_compare_and_swap(location, nullptr, initializing)) == initializing) { } if (value != nullptr) { // Initialized by someone else. RETURN_OBJ(value); } auto* object = mm::AllocateObject(threadData, typeInfo, OBJ_RESULT); initializingSingletons.push_back(std::make_pair(location, object)); #if KONAN_NO_EXCEPTIONS ctor(object); #else try { ctor(object); } catch (...) { mm::SetStackRef(OBJ_RESULT, nullptr); mm::SetHeapRefAtomic(location, nullptr); initializingSingletons.pop_back(); throw; } #endif mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location); mm::SetHeapRefAtomic(location, object); initializingSingletons.pop_back(); return object; } ================================================ FILE: runtime/src/mm/cpp/InitializationScheme.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_INITIALIZATION_SCHEME_H #define RUNTIME_MM_INITIALIZATION_SCHEME_H #include "Memory.h" namespace kotlin { namespace mm { class ThreadData; OBJ_GETTER(InitThreadLocalSingleton, ThreadData* threadData, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); OBJ_GETTER(InitSingleton, ThreadData* threadData, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)); } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_INITIALIZATION_SCHEME_H ================================================ FILE: runtime/src/mm/cpp/InitializationSchemeTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "InitializationScheme.hpp" #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "TestSupport.hpp" #include "ThreadData.hpp" #include "Types.h" using namespace kotlin; using testing::_; namespace { class InitSingletonTest : public testing::Test { public: InitSingletonTest() { typeInfo_.typeInfo_ = &typeInfo_; typeInfo_.instanceSize_ = sizeof(ObjHeader); globalConstructor_ = &constructor_; for (auto& threadData : threadDatas_) { threadData = make_unique(pthread_t{}); } } ~InitSingletonTest() { globalConstructor_ = nullptr; // Make sure to clean everything allocated by the tests. for (auto& threadData : threadDatas_) { threadData->objectFactoryThreadQueue().ClearForTests(); threadData->globalsThreadQueue().ClearForTests(); } } mm::ThreadData& threadData(size_t threadIndex) { return *threadDatas_[threadIndex]; } testing::MockFunction& constructor() { return constructor_; } OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, size_t threadIndex) { RETURN_RESULT_OF(mm::InitThreadLocalSingleton, threadDatas_[threadIndex].get(), location, &typeInfo_, constructorImpl); } OBJ_GETTER(InitSingleton, ObjHeader** location, size_t threadIndex) { RETURN_RESULT_OF(mm::InitSingleton, threadDatas_[threadIndex].get(), location, &typeInfo_, constructorImpl); } private: testing::StrictMock> constructor_; // TODO: It makes sense to somehow abstract `ThreadData` stuff away. Allocation in this case. std::array, kDefaultThreadCount> threadDatas_; TypeInfo typeInfo_; // Only used for allocator calls, uninteresting for these tests. static testing::MockFunction* globalConstructor_; static void constructorImpl(ObjHeader* object) { globalConstructor_->Call(object); } }; // static testing::MockFunction* InitSingletonTest::globalConstructor_ = nullptr; } // namespace TEST_F(InitSingletonTest, InitThreadLocalSingleton) { ObjHeader* location = nullptr; ObjHeader* stackLocation = nullptr; ObjHeader* valueAtConstructor = nullptr; EXPECT_CALL(constructor(), Call(_)).WillOnce([&location, &stackLocation, &valueAtConstructor](ObjHeader* value) { EXPECT_THAT(value, stackLocation); EXPECT_THAT(value, location); valueAtConstructor = value; }); ObjHeader* value = InitThreadLocalSingleton(&location, 0, &stackLocation); EXPECT_THAT(value, stackLocation); EXPECT_THAT(value, location); EXPECT_THAT(valueAtConstructor, location); } TEST_F(InitSingletonTest, InitThreadLocalSingletonTwice) { ObjHeader previousValue; ObjHeader* location = &previousValue; ObjHeader* stackLocation = nullptr; EXPECT_CALL(constructor(), Call(_)).Times(0); ObjHeader* value = InitThreadLocalSingleton(&location, 0, &stackLocation); EXPECT_THAT(value, stackLocation); EXPECT_THAT(value, location); EXPECT_THAT(value, &previousValue); } TEST_F(InitSingletonTest, InitThreadLocalSingletonFail) { ObjHeader* location = nullptr; ObjHeader* stackLocation = nullptr; constexpr int kException = 42; EXPECT_CALL(constructor(), Call(_)).WillOnce([]() { throw kException; }); try { InitThreadLocalSingleton(&location, 0, &stackLocation); ASSERT_TRUE(false); // Cannot be reached. } catch (int exception) { EXPECT_THAT(exception, kException); } EXPECT_THAT(stackLocation, nullptr); EXPECT_THAT(location, nullptr); } TEST_F(InitSingletonTest, InitSingleton) { ObjHeader* location = nullptr; ObjHeader* stackLocation = nullptr; ObjHeader* valueAtConstructor = nullptr; EXPECT_CALL(constructor(), Call(_)).WillOnce([&location, &stackLocation, &valueAtConstructor](ObjHeader* value) { EXPECT_THAT(value, stackLocation); EXPECT_THAT(location, reinterpret_cast(1)); valueAtConstructor = value; }); ObjHeader* value = InitSingleton(&location, 0, &stackLocation); EXPECT_THAT(value, stackLocation); EXPECT_THAT(value, location); EXPECT_THAT(valueAtConstructor, location); } TEST_F(InitSingletonTest, InitSingletonTwice) { ObjHeader previousValue; ObjHeader* location = &previousValue; ObjHeader* stackLocation = nullptr; EXPECT_CALL(constructor(), Call(_)).Times(0); ObjHeader* value = InitSingleton(&location, 0, &stackLocation); EXPECT_THAT(value, stackLocation); EXPECT_THAT(value, location); EXPECT_THAT(value, &previousValue); } TEST_F(InitSingletonTest, InitSingletonFail) { ObjHeader* location = nullptr; ObjHeader* stackLocation = nullptr; constexpr int kException = 42; EXPECT_CALL(constructor(), Call(_)).WillOnce([]() { throw kException; }); try { InitSingleton(&location, 0, &stackLocation); ASSERT_TRUE(false); // Cannot be reached. } catch (int exception) { EXPECT_THAT(exception, kException); } EXPECT_THAT(stackLocation, nullptr); EXPECT_THAT(location, nullptr); } TEST_F(InitSingletonTest, InitSingletonRecursive) { // The first singleton. Its constructor depends on the second singleton. ObjHeader* location1 = nullptr; ObjHeader* stackLocation1 = nullptr; // The second singleton. Its constructor depends on the first singleton. ObjHeader* location2 = nullptr; ObjHeader* stackLocation2 = nullptr; EXPECT_CALL(constructor(), Call(_)) .Times(2) // called only once for each singleton. .WillRepeatedly([this, &location1, &stackLocation1, &location2, &stackLocation2](ObjHeader* value) { if (value == stackLocation1) { ObjHeader* result = InitSingleton(&location2, 0, &stackLocation2); EXPECT_THAT(result, stackLocation2); EXPECT_THAT(result, location2); EXPECT_THAT(result, testing::Ne(reinterpret_cast(1))); } else { ObjHeader* result = InitSingleton(&location1, 0, &stackLocation1); EXPECT_THAT(result, stackLocation1); EXPECT_THAT(result, testing::Ne(location1)); EXPECT_THAT(location1, reinterpret_cast(1)); } }); ObjHeader* value = InitSingleton(&location1, 0, &stackLocation1); EXPECT_THAT(value, stackLocation1); EXPECT_THAT(value, location1); } TEST_F(InitSingletonTest, InitSingletonConcurrent) { constexpr size_t kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; ObjHeader* location = nullptr; KStdVector stackLocations(kThreadCount, nullptr); KStdVector actual(kThreadCount, nullptr); for (size_t i = 0; i < kThreadCount; ++i) { threads.emplace_back([this, i, &location, &stackLocations, &actual, &readyCount, &canStart]() { ++readyCount; while (!canStart) { } actual[i] = InitSingleton(&location, i, &stackLocations[i]); }); } while (readyCount < kThreadCount) { } // Constructor is called exactly once. EXPECT_CALL(constructor(), Call(_)); canStart = true; for (auto& t : threads) { t.join(); } testing::Mock::VerifyAndClearExpectations(&constructor()); EXPECT_THAT(location, testing::Ne(nullptr)); EXPECT_THAT(location, testing::Ne(reinterpret_cast(1))); EXPECT_THAT(stackLocations, testing::Each(location)); EXPECT_THAT(actual, testing::Each(location)); } TEST_F(InitSingletonTest, InitSingletonConcurrentFailing) { constexpr size_t kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; constexpr int kException = 42; ObjHeader* location = nullptr; KStdVector stackLocations(kThreadCount, nullptr); for (size_t i = 0; i < kThreadCount; ++i) { threads.emplace_back([this, i, &location, &stackLocations, &readyCount, &canStart]() { ++readyCount; while (!canStart) { } try { InitSingleton(&location, i, &stackLocations[i]); ASSERT_TRUE(false); // Cannot be reached. } catch (int exception) { EXPECT_THAT(exception, kException); } }); } while (readyCount < kThreadCount) { } // Constructor is called exactly `kThreadCount` times. EXPECT_CALL(constructor(), Call(_)).Times(kThreadCount).WillRepeatedly([]() { throw kException; }); canStart = true; for (auto& t : threads) { t.join(); } testing::Mock::VerifyAndClearExpectations(&constructor()); EXPECT_THAT(location, nullptr); EXPECT_THAT(stackLocations, testing::Each(nullptr)); } ================================================ FILE: runtime/src/mm/cpp/Memory.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" #include "MemoryPrivate.hpp" #include "Exceptions.h" #include "ExtraObjectData.hpp" #include "GlobalsRegistry.hpp" #include "InitializationScheme.hpp" #include "KAssert.h" #include "Natives.h" #include "Porting.h" #include "ObjectOps.hpp" #include "StableRefRegistry.hpp" #include "ThreadData.hpp" #include "ThreadRegistry.hpp" #include "Utils.hpp" using namespace kotlin; // TODO: This name does not make sense anymore. // Delete all means of creating this type directly as it only serves // as a typedef for `mm::StableRefRegistry::Node`. class ForeignRefManager : Pinned { public: ForeignRefManager() = delete; ~ForeignRefManager() = delete; }; namespace { // `reinterpret_cast` to it and back to the same type // will yield precisely the same pointer, so it's safe. ALWAYS_INLINE ForeignRefManager* ToForeignRefManager(mm::StableRefRegistry::Node* data) { return reinterpret_cast(data); } ALWAYS_INLINE mm::StableRefRegistry::Node* FromForeignRefManager(ForeignRefManager* manager) { return reinterpret_cast(manager); } } // namespace ObjHeader** ObjHeader::GetWeakCounterLocation() { return mm::ExtraObjectData::FromMetaObjHeader(this->meta_object()).GetWeakCounterLocation(); } #ifdef KONAN_OBJC_INTEROP void* ObjHeader::GetAssociatedObject() { if (!has_meta_object()) { return nullptr; } return *GetAssociatedObjectLocation(); } void** ObjHeader::GetAssociatedObjectLocation() { return mm::ExtraObjectData::FromMetaObjHeader(this->meta_object()).GetAssociatedObjectLocation(); } void ObjHeader::SetAssociatedObject(void* obj) { *GetAssociatedObjectLocation() = obj; } #endif // KONAN_OBJC_INTEROP // static MetaObjHeader* ObjHeader::createMetaObject(ObjHeader* object) { return mm::ExtraObjectData::Install(object).AsMetaObjHeader(); } // static void ObjHeader::destroyMetaObject(ObjHeader* object) { mm::ExtraObjectData::Uninstall(object); } ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj) { return obj->permanent() || isFrozen(obj); } ALWAYS_INLINE bool isShareable(const ObjHeader* obj) { // TODO: Remove when legacy MM is gone. return true; } extern "C" MemoryState* InitMemory(bool firstRuntime) { return mm::ToMemoryState(mm::ThreadRegistry::Instance().RegisterCurrentThread()); } extern "C" void DeinitMemory(MemoryState* state, bool destroyRuntime) { mm::ThreadRegistry::Instance().Unregister(mm::FromMemoryState(state)); } extern "C" void RestoreMemory(MemoryState*) { // TODO: Remove when legacy MM is gone. } extern "C" RUNTIME_NOTHROW OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); RETURN_RESULT_OF(mm::AllocateObject, threadData, typeInfo); } extern "C" OBJ_GETTER(AllocArrayInstance, const TypeInfo* typeInfo, int32_t elements) { if (elements < 0) { ThrowIllegalArgumentException(); } auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); RETURN_RESULT_OF(mm::AllocateArray, threadData, typeInfo, static_cast(elements)); } extern "C" ALWAYS_INLINE OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); RETURN_RESULT_OF(mm::InitThreadLocalSingleton, threadData, location, typeInfo, ctor); } extern "C" ALWAYS_INLINE OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); RETURN_RESULT_OF(mm::InitSingleton, threadData, location, typeInfo, ctor); } extern "C" RUNTIME_NOTHROW void InitAndRegisterGlobal(ObjHeader** location, const ObjHeader* initialValue) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(threadData, location); // Null `initialValue` means that the appropriate value was already set by static initialization. if (initialValue != nullptr) { mm::SetHeapRef(location, const_cast(initialValue)); } } extern "C" const MemoryModel CurrentMemoryModel = MemoryModel::kExperimental; extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) { mm::SetStackRef(location, const_cast(object)); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) { mm::SetHeapRef(location, const_cast(object)); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void ZeroHeapRef(ObjHeader** location) { mm::SetHeapRef(location, nullptr); } extern "C" RUNTIME_NOTHROW void ZeroArrayRefs(ArrayHeader* array) { for (uint32_t index = 0; index < array->count_; ++index) { ObjHeader** location = ArrayAddressOfElementAt(array, index); mm::SetHeapRef(location, nullptr); } } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) { mm::SetStackRef(location, nullptr); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { mm::SetStackRef(location, const_cast(object)); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) { mm::SetHeapRef(location, const_cast(object)); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void UpdateHeapRefIfNull(ObjHeader** location, const ObjHeader* object) { if (object == nullptr) return; ObjHeader* result = nullptr; // No need to store this value in a rootset. mm::CompareAndSwapHeapRef(location, nullptr, const_cast(object), &result); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void UpdateHeapRefsInsideOneArray(const ArrayHeader* array, int fromIndex, int toIndex, int count) { RuntimeFail("Only for legacy MM"); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) { mm::SetStackRef(returnSlot, const_cast(object)); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW OBJ_GETTER( SwapHeapRefLocked, ObjHeader** location, ObjHeader* expectedValue, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { RETURN_RESULT_OF(mm::CompareAndSwapHeapRef, location, expectedValue, newValue); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void SetHeapRefLocked( ObjHeader** location, ObjHeader* newValue, int32_t* spinlock, int32_t* cookie) { mm::SetHeapRefAtomic(location, newValue); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW OBJ_GETTER(ReadHeapRefLocked, ObjHeader** location, int32_t* spinlock, int32_t* cookie) { RETURN_RESULT_OF(mm::ReadHeapRefAtomic, location); } extern "C" OBJ_GETTER(ReadHeapRefNoLock, ObjHeader* object, int32_t index) { // TODO: Remove when legacy MM is gone. ThrowNotImplementedError(); } extern "C" RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->shadowStack().EnterFrame(start, parameters, count); } extern "C" RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->shadowStack().LeaveFrame(start, parameters, count); } extern "C" RUNTIME_NOTHROW void AddTLSRecord(MemoryState* memory, void** key, int size) { memory->GetThreadData()->tls().AddRecord(key, size); } extern "C" RUNTIME_NOTHROW void CommitTLSStorage(MemoryState* memory) { memory->GetThreadData()->tls().Commit(); } extern "C" RUNTIME_NOTHROW void ClearTLS(MemoryState* memory) { memory->GetThreadData()->tls().Clear(); } extern "C" RUNTIME_NOTHROW ObjHeader** LookupTLS(void** key, int index) { return mm::ThreadRegistry::Instance().CurrentThreadData()->tls().Lookup(key, index); } extern "C" RUNTIME_NOTHROW void GC_RegisterWorker(void* worker) { // TODO: Remove when legacy MM is gone. // Nothing to do } extern "C" RUNTIME_NOTHROW void GC_UnregisterWorker(void* worker) { // TODO: Remove when legacy MM is gone. // Nothing to do } extern "C" RUNTIME_NOTHROW void GC_CollectorCallback(void* worker) { // TODO: Remove when legacy MM is gone. // Nothing to do } extern "C" void Kotlin_native_internal_GC_collect(ObjHeader*) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->gc().PerformFullGC(); } extern "C" void Kotlin_native_internal_GC_collectCyclic(ObjHeader*) { // TODO: Remove when legacy MM is gone. ThrowIllegalArgumentException(); } extern "C" void Kotlin_native_internal_GC_setThreshold(ObjHeader*, int32_t value) { if (value < 0) { ThrowIllegalArgumentException(); } mm::GlobalData::Instance().gc().SetThreshold(static_cast(value)); } extern "C" int32_t Kotlin_native_internal_GC_getThreshold(ObjHeader*) { auto threshold = mm::GlobalData::Instance().gc().GetThreshold(); auto maxValue = std::numeric_limits::max(); if (threshold > static_cast(maxValue)) { return maxValue; } return static_cast(maxValue); } extern "C" void Kotlin_native_internal_GC_setCollectCyclesThreshold(ObjHeader*, int64_t value) { // TODO: Remove when legacy MM is gone. ThrowIllegalArgumentException(); } extern "C" int64_t Kotlin_native_internal_GC_getCollectCyclesThreshold(ObjHeader*) { // TODO: Remove when legacy MM is gone. ThrowIllegalArgumentException(); } extern "C" void Kotlin_native_internal_GC_setThresholdAllocations(ObjHeader*, int64_t value) { if (value < 0) { ThrowIllegalArgumentException(); } mm::GlobalData::Instance().gc().SetAllocationThresholdBytes(static_cast(value)); } extern "C" int64_t Kotlin_native_internal_GC_getThresholdAllocations(ObjHeader*) { auto threshold = mm::GlobalData::Instance().gc().GetAllocationThresholdBytes(); auto maxValue = std::numeric_limits::max(); if (threshold > static_cast(maxValue)) { return maxValue; } return static_cast(maxValue); } extern "C" OBJ_GETTER(Kotlin_native_internal_GC_detectCycles, ObjHeader*) { // TODO: Remove when legacy MM is gone. RETURN_OBJ(nullptr); } extern "C" OBJ_GETTER(Kotlin_native_internal_GC_findCycle, ObjHeader*, ObjHeader* root) { // TODO: Remove when legacy MM is gone. RETURN_OBJ(nullptr); } extern "C" bool Kotlin_native_internal_GC_getCyclicCollector(ObjHeader* gc) { // TODO: Remove when legacy MM is gone. return false; } extern "C" void Kotlin_native_internal_GC_setCyclicCollector(ObjHeader* gc, bool value) { // TODO: Remove when legacy MM is gone. if (value) ThrowIllegalArgumentException(); } extern "C" bool Kotlin_Any_isShareable(ObjHeader* thiz) { // TODO: Remove when legacy MM is gone. return true; } extern "C" void Kotlin_Any_share(ObjHeader* thiz) { // TODO: Remove when legacy MM is gone. // Nothing to do } extern "C" RUNTIME_NOTHROW void PerformFullGC(MemoryState* memory) { memory->GetThreadData()->gc().PerformFullGC(); } extern "C" RUNTIME_NOTHROW bool ClearSubgraphReferences(ObjHeader* root, bool checked) { // TODO: Remove when legacy MM is gone. return true; } extern "C" RUNTIME_NOTHROW void* CreateStablePointer(ObjHeader* object) { if (!object) return nullptr; auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); return mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object); } extern "C" RUNTIME_NOTHROW void DisposeStablePointer(void* pointer) { if (!pointer) return; auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); auto* node = static_cast(pointer); mm::StableRefRegistry::Instance().UnregisterStableRef(threadData, node); } extern "C" RUNTIME_NOTHROW OBJ_GETTER(DerefStablePointer, void* pointer) { if (!pointer) RETURN_OBJ(nullptr); auto* node = static_cast(pointer); ObjHeader* object = **node; RETURN_OBJ(object); } extern "C" RUNTIME_NOTHROW OBJ_GETTER(AdoptStablePointer, void* pointer) { if (!pointer) RETURN_OBJ(nullptr); auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); auto* node = static_cast(pointer); ObjHeader* object = **node; // Make sure `object` stays in the rootset: put it on the stack before removing it from `StableRefRegistry`. mm::SetStackRef(OBJ_RESULT, object); mm::StableRefRegistry::Instance().UnregisterStableRef(threadData, node); return object; } extern "C" RUNTIME_NOTHROW void CheckLifetimesConstraint(ObjHeader* obj, ObjHeader* pointee) { // TODO: Consider making it a `RuntimeCheck`. Probably all `RuntimeCheck`s and `RuntimeAssert`s should specify // that their firing is a compiler bug and should be reported. if (!obj->local() && pointee != nullptr && pointee->local()) { konan::consolePrintf("Attempt to store a stack object %p into a heap object %p\n", pointee, obj); konan::consolePrintf("This is a compiler bug, please report it to https://kotl.in/issue\n"); konan::abort(); } } extern "C" ForeignRefContext InitForeignRef(ObjHeader* object) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); auto* node = mm::StableRefRegistry::Instance().RegisterStableRef(threadData, object); return ToForeignRefManager(node); } extern "C" void DeinitForeignRef(ObjHeader* object, ForeignRefContext context) { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); auto* node = FromForeignRefManager(context); RuntimeAssert(object == **node, "Must correspond to the same object"); mm::StableRefRegistry::Instance().UnregisterStableRef(threadData, node); } extern "C" bool IsForeignRefAccessible(ObjHeader* object, ForeignRefContext context) { // TODO: Remove when legacy MM is gone. return true; } extern "C" void AdoptReferenceFromSharedVariable(ObjHeader* object) { // TODO: Remove when legacy MM is gone. // Nothing to do. } extern "C" void CheckGlobalsAccessible() { // TODO: Remove when legacy MM is gone. // Always accessible } extern "C" RUNTIME_NOTHROW void Kotlin_mm_safePointFunctionEpilogue() { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->gc().SafePointFunctionEpilogue(); } extern "C" RUNTIME_NOTHROW void Kotlin_mm_safePointWhileLoopBody() { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->gc().SafePointLoopBody(); } extern "C" RUNTIME_NOTHROW void Kotlin_mm_safePointExceptionUnwind() { auto* threadData = mm::ThreadRegistry::Instance().CurrentThreadData(); threadData->gc().SafePointExceptionUnwind(); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateNative() { SwitchThreadState(mm::ThreadRegistry::Instance().CurrentThreadData(), ThreadState::kNative); } extern "C" ALWAYS_INLINE RUNTIME_NOTHROW void Kotlin_mm_switchThreadStateRunnable() { SwitchThreadState(mm::ThreadRegistry::Instance().CurrentThreadData(), ThreadState::kRunnable); } MemoryState* kotlin::mm::GetMemoryState() { return ToMemoryState(ThreadRegistry::Instance().CurrentThreadDataNode()); } ================================================ FILE: runtime/src/mm/cpp/MemoryPrivate.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MEMORYPRIVATE_HPP #define RUNTIME_MEMORYPRIVATE_HPP #include "Utils.hpp" #include "ThreadData.hpp" #include "ThreadRegistry.hpp" using namespace kotlin; namespace kotlin { namespace mm { // `reinterpret_cast` to it and back to the same type // will yield precisely the same pointer, so it's safe. ALWAYS_INLINE inline MemoryState* ToMemoryState(ThreadRegistry::Node* data) { return reinterpret_cast(data); } ALWAYS_INLINE inline ThreadRegistry::Node* FromMemoryState(MemoryState* state) { return reinterpret_cast(state); } } // namespace mm } // namepace kotlin // Delete all means of creating this type directly as it only serves // as a typedef for `mm::ThreadRegistry::Node`. extern "C" struct MemoryState : kotlin::Pinned { MemoryState() = delete; ~MemoryState() = delete; ALWAYS_INLINE mm::ThreadData* GetThreadData() { return mm::FromMemoryState(this)->Get(); } }; #endif //RUNTIME_MEMORYPRIVATE_HPP ================================================ FILE: runtime/src/mm/cpp/ObjectFactory.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_OBJECT_FACTORY_H #define RUNTIME_MM_OBJECT_FACTORY_H #include #include #include #include #include "Alignment.hpp" #include "Alloc.h" #include "Memory.h" #include "Mutex.hpp" #include "Types.h" #include "Utils.hpp" namespace kotlin { namespace mm { namespace internal { // A queue that is constructed by collecting subqueues from several `Producer`s. // This is essentially a heterogeneous `MultiSourceQueue` on top of a singly linked list that // uses `Allocator` to allocate and free memory. // TODO: Consider merging with `MultiSourceQueue` somehow. template class ObjectFactoryStorage : private Pinned { static_assert(IsValidAlignment(DataAlignment), "DataAlignment is not a valid alignment"); template class Deleter { public: void operator()(T* instance) noexcept { instance->~T(); Allocator::Free(instance); } }; template using unique_ptr = std::unique_ptr>; public: // This class does not know its size at compile-time. Does not inherit from `KonanAllocatorAware` because // in `KonanAllocatorAware::operator new(size_t size, KonanAllocTag)` `size` would be incorrect. class Node : private Pinned { constexpr static size_t DataOffset() noexcept { return AlignUp(sizeof(Node), DataAlignment); } public: ~Node() = default; static Node& FromData(void* data) noexcept { constexpr size_t kDataOffset = DataOffset(); Node* node = reinterpret_cast(reinterpret_cast(data) - kDataOffset); RuntimeAssert(node->Data() == data, "Node layout has broken"); return *node; } // Note: This can only be trivially destructible data, as nobody can invoke its destructor. void* Data() noexcept { constexpr size_t kDataOffset = DataOffset(); void* ptr = reinterpret_cast(this) + kDataOffset; RuntimeAssert(IsAligned(ptr, DataAlignment), "Data=%p is not aligned to %zu", ptr, DataAlignment); return ptr; } // It's a caller responsibility to know if the underlying data is `T`. template T& Data() noexcept { return *static_cast(Data()); } private: friend class ObjectFactoryStorage; Node() noexcept = default; static unique_ptr Create(Allocator& allocator, size_t dataSize) noexcept { size_t dataSizeAligned = AlignUp(dataSize, DataAlignment); size_t totalAlignment = std::max(alignof(Node), DataAlignment); size_t totalSize = AlignUp(sizeof(Node) + dataSizeAligned, totalAlignment); RuntimeAssert( DataOffset() + dataSize <= totalSize, "totalSize %zu is not enough to fit data %zu at offset %zu", totalSize, dataSize, DataOffset()); void* ptr = allocator.Alloc(totalSize, totalAlignment); if (!ptr) { konan::consoleErrorf("Out of memory trying to allocate %zu bytes. Aborting.\n", totalSize); konan::abort(); } RuntimeAssert(IsAligned(ptr, totalAlignment), "Allocator returned unaligned to %zu pointer %p", totalAlignment, ptr); return unique_ptr(new (ptr) Node()); } unique_ptr next_; // There's some more data of an unknown (at compile-time) size here, but it cannot be represented // with C++ members. }; class Producer : private MoveOnly { public: Producer(ObjectFactoryStorage& owner, Allocator allocator) noexcept : owner_(owner), allocator_(std::move(allocator)) {} ~Producer() { Publish(); } Node& Insert(size_t dataSize) noexcept { AssertCorrect(); auto node = Node::Create(allocator_, dataSize); auto* nodePtr = node.get(); if (!root_) { root_ = std::move(node); } else { last_->next_ = std::move(node); } last_ = nodePtr; RuntimeAssert(root_ != nullptr, "Must not be empty"); AssertCorrect(); return *nodePtr; } template Node& Insert(Args&&... args) noexcept { static_assert(alignof(T) <= DataAlignment, "Cannot insert type with alignment bigger than DataAlignment"); static_assert(std::is_trivially_destructible_v, "Type must be trivially destructible"); auto& node = Insert(sizeof(T)); new (node.Data()) T(std::forward(args)...); return node; } // Merge `this` queue with owning `ObjectFactoryStorage`. // `this` will have empty queue after the call. // This call is performed without heap allocations. TODO: Test that no allocations are happening. void Publish() noexcept { AssertCorrect(); if (!root_) { return; } std::lock_guard guard(owner_.mutex_); owner_.AssertCorrectUnsafe(); if (!owner_.root_) { owner_.root_ = std::move(root_); } else { owner_.last_->next_ = std::move(root_); } owner_.last_ = last_; last_ = nullptr; RuntimeAssert(root_ == nullptr, "Must be empty"); AssertCorrect(); RuntimeAssert(owner_.root_ != nullptr, "Must not be empty"); owner_.AssertCorrectUnsafe(); } void ClearForTests() noexcept { // Since it's only for tests, no need to worry about stack overflows. root_.reset(); last_ = nullptr; } private: friend class ObjectFactoryStorage; ALWAYS_INLINE void AssertCorrect() const noexcept { if (root_ == nullptr) { RuntimeAssert(last_ == nullptr, "last_ must be null"); } else { RuntimeAssert(last_ != nullptr, "last_ must not be null"); RuntimeAssert(last_->next_ == nullptr, "last_ must not have next"); } } ObjectFactoryStorage& owner_; // weak Allocator allocator_; unique_ptr root_; Node* last_ = nullptr; }; class Iterator { public: Node& operator*() noexcept { return *node_; } Node* operator->() noexcept { return node_; } Iterator& operator++() noexcept { previousNode_ = node_; node_ = node_->next_.get(); return *this; } bool operator==(const Iterator& rhs) const noexcept { return node_ == rhs.node_; } bool operator!=(const Iterator& rhs) const noexcept { return node_ != rhs.node_; } private: friend class ObjectFactoryStorage; Iterator(Node* previousNode, Node* node) noexcept : previousNode_(previousNode), node_(node) {} Node* previousNode_; // Kept for `Iterable::EraseAndAdvance`. Node* node_; }; class Consumer : private MoveOnly { public: class Iterator { public: Node& operator*() noexcept { return *node_; } Node* operator->() noexcept { return node_; } Iterator& operator++() noexcept { node_ = node_->next_.get(); return *this; } bool operator==(const Iterator& rhs) const noexcept { return node_ == rhs.node_; } bool operator!=(const Iterator& rhs) const noexcept { return node_ != rhs.node_; } private: friend class Consumer; explicit Iterator(Node* node) noexcept : node_(node) {} Node* node_; }; Consumer() noexcept = default; Consumer(Consumer&&) noexcept = default; Consumer& operator=(Consumer&&) noexcept = default; ~Consumer() { // Make sure not to blow up the stack by nested `~Node` calls. for (auto node = std::move(root_); node != nullptr; node = std::move(node->next_)) { } } Iterator begin() noexcept { return Iterator(root_.get()); } Iterator end() noexcept { return Iterator(nullptr); } private: friend class ObjectFactoryStorage; void Insert(unique_ptr node) noexcept { AssertCorrect(); auto* nodePtr = node.get(); if (!root_) { root_ = std::move(node); } else { last_->next_ = std::move(node); } last_ = nodePtr; AssertCorrect(); } ALWAYS_INLINE void AssertCorrect() const noexcept { if (root_ == nullptr) { RuntimeAssert(last_ == nullptr, "last_ must be null"); } else { RuntimeAssert(last_ != nullptr, "last_ must not be null"); RuntimeAssert(last_->next_ == nullptr, "last_ must not have next"); } } unique_ptr root_; Node* last_ = nullptr; }; class Iterable : private MoveOnly { public: explicit Iterable(ObjectFactoryStorage& owner) noexcept : owner_(owner), guard_(owner_.mutex_) {} Iterator begin() noexcept { return Iterator(nullptr, owner_.root_.get()); } Iterator end() noexcept { return Iterator(owner_.last_, nullptr); } void EraseAndAdvance(Iterator& iterator) noexcept { auto result = owner_.ExtractUnsafe(iterator.previousNode_); iterator.node_ = result.second; } void MoveAndAdvance(Consumer& consumer, Iterator& iterator) noexcept { auto result = owner_.ExtractUnsafe(iterator.previousNode_); iterator.node_ = result.second; consumer.Insert(std::move(result.first)); } private: ObjectFactoryStorage& owner_; // weak std::unique_lock guard_; }; ~ObjectFactoryStorage() { // Make sure not to blow up the stack by nested `~Node` calls. for (auto node = std::move(root_); node != nullptr; node = std::move(node->next_)) {} } // Lock `ObjectFactoryStorage` for safe iteration. Iterable Iter() noexcept { return Iterable(*this); } private: // Expects `mutex_` to be held by the current thread. std::pair, Node*> ExtractUnsafe(Node* previousNode) noexcept { RuntimeAssert(root_ != nullptr, "Must not be empty"); AssertCorrectUnsafe(); if (previousNode == nullptr) { // Extracting the root. auto node = std::move(root_); root_ = std::move(node->next_); if (!root_) { last_ = nullptr; } AssertCorrectUnsafe(); return {std::move(node), root_.get()}; } auto node = std::move(previousNode->next_); previousNode->next_ = std::move(node->next_); if (!previousNode->next_) { last_ = previousNode; } AssertCorrectUnsafe(); return {std::move(node), previousNode->next_.get()}; } // Expects `mutex_` to be held by the current thread. ALWAYS_INLINE void AssertCorrectUnsafe() const noexcept { if (root_ == nullptr) { RuntimeAssert(last_ == nullptr, "last_ must be null"); } else { RuntimeAssert(last_ != nullptr, "last_ must not be null"); RuntimeAssert(last_->next_ == nullptr, "last_ must not have next"); } } unique_ptr root_; Node* last_ = nullptr; SpinLock mutex_; }; class SimpleAllocator { public: void* Alloc(size_t size, size_t alignment) noexcept { return konanAllocAlignedMemory(size, alignment); } static void Free(void* instance) noexcept { konanFreeMemory(instance); } }; template class AllocatorWithGC { public: AllocatorWithGC(BaseAllocator base, GC& gc) noexcept : base_(std::move(base)), gc_(gc) {} void* Alloc(size_t size, size_t alignment) noexcept { gc_.SafePointAllocation(size); if (void* ptr = base_.Alloc(size, alignment)) { return ptr; } // Tell GC that we failed to allocate, and try one more time. gc_.OnOOM(size); return base_.Alloc(size, alignment); } static void Free(void* instance) noexcept { BaseAllocator::Free(instance); } private: BaseAllocator base_; GC& gc_; }; } // namespace internal template class ObjectFactory : private Pinned { using GCObjectData = typename GC::ObjectData; using GCThreadData = typename GC::ThreadData; using Allocator = internal::AllocatorWithGC; struct HeapObjHeader { GCObjectData gcData; alignas(kObjectAlignment) ObjHeader object; }; // Needs to be kept compatible with `HeapObjHeader` just like `ArrayHeader` is compatible // with `ObjHeader`: the former can always be casted to the other. struct HeapArrayHeader { GCObjectData gcData; alignas(kObjectAlignment) ArrayHeader array; }; public: using Storage = internal::ObjectFactoryStorage; class NodeRef { public: explicit NodeRef(typename Storage::Node& node) noexcept : node_(node) {} static NodeRef From(ObjHeader* object) noexcept { RuntimeAssert(object->heap(), "Must be a heap object"); auto* heapObject = reinterpret_cast(reinterpret_cast(object) - offsetof(HeapObjHeader, object)); RuntimeAssert(&heapObject->object == object, "HeapObjHeader layout has broken"); return NodeRef(Storage::Node::FromData(heapObject)); } static NodeRef From(ArrayHeader* array) noexcept { // `ArrayHeader` and `ObjHeader` are kept compatible, so the former can // be always casted to the other. RuntimeAssert(reinterpret_cast(array)->heap(), "Must be a heap object"); auto* heapArray = reinterpret_cast(reinterpret_cast(array) - offsetof(HeapArrayHeader, array)); RuntimeAssert(&heapArray->array == array, "HeapArrayHeader layout has broken"); return NodeRef(Storage::Node::FromData(heapArray)); } NodeRef* operator->() noexcept { return this; } GCObjectData& GCObjectData() noexcept { // `HeapArrayHeader` and `HeapObjHeader` are kept compatible, so the former can // be always casted to the other. return static_cast(node_.Data())->gcData; } bool IsArray() const noexcept { // `HeapArrayHeader` and `HeapObjHeader` are kept compatible, so the former can // be always casted to the other. auto* object = &static_cast(node_.Data())->object; return object->type_info()->IsArray(); } ObjHeader* GetObjHeader() noexcept { auto* object = &static_cast(node_.Data())->object; RuntimeAssert(!object->type_info()->IsArray(), "Must not be an array"); return object; } ArrayHeader* GetArrayHeader() noexcept { auto* array = &static_cast(node_.Data())->array; RuntimeAssert(array->type_info()->IsArray(), "Must be an array"); return array; } bool operator==(const NodeRef& rhs) const noexcept { return &node_ == &rhs.node_; } bool operator!=(const NodeRef& rhs) const noexcept { return !(*this == rhs); } private: typename Storage::Node& node_; }; class ThreadQueue : private MoveOnly { public: ThreadQueue(ObjectFactory& owner, GCThreadData& gc) noexcept : producer_(owner.storage_, internal::AllocatorWithGC(internal::SimpleAllocator(), gc)) {} ObjHeader* CreateObject(const TypeInfo* typeInfo) noexcept { RuntimeAssert(!typeInfo->IsArray(), "Must not be an array"); size_t membersSize = typeInfo->instanceSize_ - sizeof(ObjHeader); size_t allocSize = AlignUp(sizeof(HeapObjHeader) + membersSize, kObjectAlignment); auto& node = producer_.Insert(allocSize); auto* heapObject = new (node.Data()) HeapObjHeader(); auto* object = &heapObject->object; object->typeInfoOrMeta_ = const_cast(typeInfo); return object; } ArrayHeader* CreateArray(const TypeInfo* typeInfo, uint32_t count) noexcept { RuntimeAssert(typeInfo->IsArray(), "Must be an array"); uint32_t membersSize = static_cast(-typeInfo->instanceSize_) * count; // Note: array body is aligned, but for size computation it is enough to align the sum. size_t allocSize = AlignUp(sizeof(HeapArrayHeader) + membersSize, kObjectAlignment); auto& node = producer_.Insert(allocSize); auto* heapArray = new (node.Data()) HeapArrayHeader(); auto* array = &heapArray->array; array->typeInfoOrMeta_ = const_cast(typeInfo); array->count_ = count; return array; } void Publish() noexcept { producer_.Publish(); } void ClearForTests() noexcept { producer_.ClearForTests(); } private: typename Storage::Producer producer_; }; class Iterator { public: NodeRef operator*() noexcept { return NodeRef(*iterator_); } NodeRef operator->() noexcept { return NodeRef(*iterator_); } Iterator& operator++() noexcept { ++iterator_; return *this; } bool operator==(const Iterator& rhs) const noexcept { return iterator_ == rhs.iterator_; } bool operator!=(const Iterator& rhs) const noexcept { return iterator_ != rhs.iterator_; } private: friend class ObjectFactory; explicit Iterator(typename Storage::Iterator iterator) noexcept : iterator_(std::move(iterator)) {} typename Storage::Iterator iterator_; }; class FinalizerQueue : private MoveOnly { public: class Iterator { public: NodeRef operator*() noexcept { return NodeRef(*iterator_); } NodeRef operator->() noexcept { return NodeRef(*iterator_); } Iterator& operator++() noexcept { ++iterator_; return *this; } bool operator==(const Iterator& rhs) const noexcept { return iterator_ == rhs.iterator_; } bool operator!=(const Iterator& rhs) const noexcept { return iterator_ != rhs.iterator_; } private: friend class ObjectFactory; explicit Iterator(typename Storage::Consumer::Iterator iterator) noexcept : iterator_(std::move(iterator)) {} typename Storage::Consumer::Iterator iterator_; }; Iterator begin() noexcept { return Iterator(consumer_.begin()); } Iterator end() noexcept { return Iterator(consumer_.end()); } private: friend class ObjectFactory; typename Storage::Consumer consumer_; }; class Iterable { public: Iterable(ObjectFactory& owner) noexcept : iter_(owner.storage_.Iter()) {} Iterator begin() noexcept { return Iterator(iter_.begin()); } Iterator end() noexcept { return Iterator(iter_.end()); } void EraseAndAdvance(Iterator& iterator) noexcept { iter_.EraseAndAdvance(iterator.iterator_); } void MoveAndAdvance(FinalizerQueue& queue, Iterator& iterator) noexcept { iter_.MoveAndAdvance(queue.consumer_, iterator.iterator_); } private: typename Storage::Iterable iter_; }; ObjectFactory() noexcept = default; ~ObjectFactory() = default; Iterable Iter() noexcept { return Iterable(*this); } private: Storage storage_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_OBJECT_FACTORY_H ================================================ FILE: runtime/src/mm/cpp/ObjectFactoryTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ObjectFactory.hpp" #include #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "GC.hpp" #include "TestSupport.hpp" #include "Types.h" using namespace kotlin; using testing::_; namespace { using SimpleAllocator = mm::internal::SimpleAllocator; template using ObjectFactoryStorage = mm::internal::ObjectFactoryStorage; using ObjectFactoryStorageRegular = ObjectFactoryStorage; template using Producer = typename Storage::Producer; template using Consumer = typename Storage::Consumer; template KStdVector Collect(ObjectFactoryStorage& storage) { KStdVector result; for (auto& node : storage.Iter()) { result.push_back(node.Data()); } return result; } template KStdVector Collect(ObjectFactoryStorage& storage) { KStdVector result; for (auto& node : storage.Iter()) { result.push_back(*static_cast(node.Data())); } return result; } template KStdVector Collect(Consumer>& consumer) { KStdVector result; for (auto& node : consumer) { result.push_back(*static_cast(node.Data())); } return result; } struct MoveOnlyImpl : private MoveOnly { MoveOnlyImpl(int value1, int value2) : value1(value1), value2(value2) {} int value1; int value2; }; struct PinnedImpl : private Pinned { PinnedImpl(int value1, int value2, int value3) : value1(value1), value2(value2), value3(value3) {} int value1; int value2; int value3; }; struct MaxAlignedData { explicit MaxAlignedData(int value) : value(value) {} std::max_align_t padding; int value; }; } // namespace TEST(ObjectFactoryStorageTest, Empty) { ObjectFactoryStorageRegular storage; auto actual = Collect(storage); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ObjectFactoryStorageTest, DoNotPublish) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); auto actual = Collect(storage); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ObjectFactoryStorageTest, Publish) { ObjectFactoryStorageRegular storage; Producer producer1(storage, SimpleAllocator()); Producer producer2(storage, SimpleAllocator()); producer1.Insert(1); producer1.Insert(2); producer2.Insert(10); producer2.Insert(20); producer1.Publish(); producer2.Publish(); auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(1, 2, 10, 20)); } TEST(ObjectFactoryStorageTest, PublishDifferentTypes) { ObjectFactoryStorage storage; Producer> producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); producer.Insert(3, 4); producer.Insert(5, 6, 7); producer.Insert(8); producer.Publish(); auto actual = storage.Iter(); auto it = actual.begin(); EXPECT_THAT(it->Data(), 1); ++it; EXPECT_THAT(it->Data(), 2); ++it; auto& moveOnly = it->Data(); EXPECT_THAT(moveOnly.value1, 3); EXPECT_THAT(moveOnly.value2, 4); ++it; auto& pinned = it->Data(); EXPECT_THAT(pinned.value1, 5); EXPECT_THAT(pinned.value2, 6); EXPECT_THAT(pinned.value3, 7); ++it; auto& maxAlign = it->Data(); EXPECT_THAT(maxAlign.value, 8); ++it; EXPECT_THAT(it, actual.end()); } TEST(ObjectFactoryStorageTest, PublishSeveralTimes) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); // Add 2 elements and publish. producer.Insert(1); producer.Insert(2); producer.Publish(); // Add another element and publish. producer.Insert(3); producer.Publish(); // Publish without adding elements. producer.Publish(); // Add yet another two elements and publish. producer.Insert(4); producer.Insert(5); producer.Publish(); auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(1, 2, 3, 4, 5)); } TEST(ObjectFactoryStorageTest, PublishInDestructor) { ObjectFactoryStorageRegular storage; { Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); } auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(1, 2)); } TEST(ObjectFactoryStorageTest, FindNode) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); auto& node1 = producer.Insert(1); auto& node2 = producer.Insert(2); producer.Publish(); EXPECT_THAT(&ObjectFactoryStorageRegular::Node::FromData(node1.Data()), &node1); EXPECT_THAT(&ObjectFactoryStorageRegular::Node::FromData(node2.Data()), &node2); } TEST(ObjectFactoryStorageTest, EraseFirst) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 1) { iter.EraseAndAdvance(it); } else { ++it; } } } auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(2, 3)); } TEST(ObjectFactoryStorageTest, EraseMiddle) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 2) { iter.EraseAndAdvance(it); } else { ++it; } } } auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(1, 3)); } TEST(ObjectFactoryStorageTest, EraseLast) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 3) { iter.EraseAndAdvance(it); } else { ++it; } } } auto actual = Collect(storage); EXPECT_THAT(actual, testing::ElementsAre(1, 2)); } TEST(ObjectFactoryStorageTest, EraseAll) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { iter.EraseAndAdvance(it); } } auto actual = Collect(storage); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ObjectFactoryStorageTest, EraseTheOnlyElement) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); producer.Insert(1); producer.Publish(); { auto iter = storage.Iter(); auto it = iter.begin(); iter.EraseAndAdvance(it); EXPECT_THAT(it, iter.end()); } auto actual = Collect(storage); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ObjectFactoryStorageTest, MoveFirst) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 1) { iter.MoveAndAdvance(consumer, it); } else { ++it; } } } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::ElementsAre(2, 3)); EXPECT_THAT(actualConsumer, testing::ElementsAre(1)); } TEST(ObjectFactoryStorageTest, MoveMiddle) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 2) { iter.MoveAndAdvance(consumer, it); } else { ++it; } } } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::ElementsAre(1, 3)); EXPECT_THAT(actualConsumer, testing::ElementsAre(2)); } TEST(ObjectFactoryStorageTest, MoveLast) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->Data() == 3) { iter.MoveAndAdvance(consumer, it); } else { ++it; } } } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::ElementsAre(1, 2)); EXPECT_THAT(actualConsumer, testing::ElementsAre(3)); } TEST(ObjectFactoryStorageTest, MoveAll) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { iter.MoveAndAdvance(consumer, it); } } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::IsEmpty()); EXPECT_THAT(actualConsumer, testing::ElementsAre(1, 2, 3)); } TEST(ObjectFactoryStorageTest, MoveTheOnlyElement) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Publish(); { auto iter = storage.Iter(); auto it = iter.begin(); iter.MoveAndAdvance(consumer, it); EXPECT_THAT(it, iter.end()); } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::IsEmpty()); EXPECT_THAT(actualConsumer, testing::ElementsAre(1)); } TEST(ObjectFactoryStorageTest, MoveAndErase) { ObjectFactoryStorageRegular storage; Producer producer(storage, SimpleAllocator()); Consumer consumer; producer.Insert(1); producer.Insert(2); producer.Insert(3); producer.Insert(4); producer.Insert(5); producer.Insert(6); producer.Insert(7); producer.Insert(8); producer.Insert(9); producer.Publish(); { auto iter = storage.Iter(); for (auto it = iter.begin(); it != iter.end();) { ++it; iter.EraseAndAdvance(it); iter.MoveAndAdvance(consumer, it); } } auto actual = Collect(storage); auto actualConsumer = Collect(consumer); EXPECT_THAT(actual, testing::ElementsAre(1, 4, 7)); EXPECT_THAT(actualConsumer, testing::ElementsAre(3, 6, 9)); } TEST(ObjectFactoryStorageTest, ConcurrentPublish) { ObjectFactoryStorageRegular storage; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; KStdVector expected; for (int i = 0; i < kThreadCount; ++i) { expected.push_back(i); threads.emplace_back([i, &storage, &canStart, &readyCount]() { Producer producer(storage, SimpleAllocator()); producer.Insert(i); ++readyCount; while (!canStart) { } producer.Publish(); }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } auto actual = Collect(storage); EXPECT_THAT(actual, testing::UnorderedElementsAreArray(expected)); } TEST(ObjectFactoryStorageTest, IterWhileConcurrentPublish) { ObjectFactoryStorageRegular storage; constexpr int kStartCount = 50; constexpr int kThreadCount = kDefaultThreadCount; KStdVector expectedBefore; KStdVector expectedAfter; Producer producer(storage, SimpleAllocator()); for (int i = 0; i < kStartCount; ++i) { expectedBefore.push_back(i); expectedAfter.push_back(i); producer.Insert(i); } producer.Publish(); std::atomic canStart(false); std::atomic readyCount(0); std::atomic startedCount(0); KStdVector threads; for (int i = 0; i < kThreadCount; ++i) { int j = i + kStartCount; expectedAfter.push_back(j); threads.emplace_back([j, &storage, &canStart, &startedCount, &readyCount]() { Producer producer(storage, SimpleAllocator()); producer.Insert(j); ++readyCount; while (!canStart) { } ++startedCount; producer.Publish(); }); } KStdVector actualBefore; { auto iter = storage.Iter(); while (readyCount < kThreadCount) { } canStart = true; while (startedCount < kThreadCount) { } for (auto& node : iter) { int element = *static_cast(node.Data()); actualBefore.push_back(element); } } for (auto& t : threads) { t.join(); } EXPECT_THAT(actualBefore, testing::ElementsAreArray(expectedBefore)); auto actualAfter = Collect(storage); EXPECT_THAT(actualAfter, testing::UnorderedElementsAreArray(expectedAfter)); } TEST(ObjectFactoryStorageTest, EraseWhileConcurrentPublish) { ObjectFactoryStorageRegular storage; constexpr int kStartCount = 50; constexpr int kThreadCount = kDefaultThreadCount; KStdVector expectedAfter; Producer producer(storage, SimpleAllocator()); for (int i = 0; i < kStartCount; ++i) { if (i % 2 == 0) { expectedAfter.push_back(i); } producer.Insert(i); } producer.Publish(); std::atomic canStart(false); std::atomic readyCount(0); std::atomic startedCount(0); KStdVector threads; for (int i = 0; i < kThreadCount; ++i) { int j = i + kStartCount; expectedAfter.push_back(j); threads.emplace_back([j, &storage, &canStart, &startedCount, &readyCount]() { Producer producer(storage, SimpleAllocator()); producer.Insert(j); ++readyCount; while (!canStart) { } ++startedCount; producer.Publish(); }); } { auto iter = storage.Iter(); while (readyCount < kThreadCount) { } canStart = true; while (startedCount < kThreadCount) { } for (auto it = iter.begin(); it != iter.end();) { if (it->Data() % 2 != 0) { iter.EraseAndAdvance(it); } else { ++it; } } } for (auto& t : threads) { t.join(); } auto actual = Collect(storage); EXPECT_THAT(actual, testing::UnorderedElementsAreArray(expectedAfter)); } using mm::internal::AllocatorWithGC; namespace { class MockAllocator { public: MOCK_METHOD(void*, Alloc, (size_t, size_t)); }; class MockAllocatorWrapper { public: MockAllocator& operator*() { return *mock_; } void* Alloc(size_t size, size_t alignment) { return mock_->Alloc(size, alignment); } private: KStdUniquePtr> mock_ = make_unique>(); }; class MockGC { public: MOCK_METHOD(void, SafePointAllocation, (size_t)); MOCK_METHOD(void, OnOOM, (size_t)); }; } // namespace TEST(AllocatorWithGCTest, AllocateWithoutOOM) { constexpr size_t size = 256; constexpr size_t alignment = 8; void* nonNull = reinterpret_cast(1); MockAllocatorWrapper baseAllocator; testing::StrictMock gc; { testing::InSequence seq; EXPECT_CALL(gc, SafePointAllocation(size)); EXPECT_CALL(*baseAllocator, Alloc(size, alignment)).WillOnce(testing::Return(nonNull)); EXPECT_CALL(gc, OnOOM(_)).Times(0); } AllocatorWithGC allocator(std::move(baseAllocator), gc); void* ptr = allocator.Alloc(size, alignment); EXPECT_THAT(ptr, nonNull); } TEST(AllocatorWithGCTest, AllocateWithFixableOOM) { constexpr size_t size = 256; constexpr size_t alignment = 8; void* nonNull = reinterpret_cast(1); MockAllocatorWrapper baseAllocator; testing::StrictMock gc; { testing::InSequence seq; EXPECT_CALL(gc, SafePointAllocation(size)); EXPECT_CALL(*baseAllocator, Alloc(size, alignment)).WillOnce(testing::Return(nullptr)); EXPECT_CALL(gc, OnOOM(size)); EXPECT_CALL(*baseAllocator, Alloc(size, alignment)).WillOnce(testing::Return(nonNull)); } AllocatorWithGC allocator(std::move(baseAllocator), gc); void* ptr = allocator.Alloc(size, alignment); EXPECT_THAT(ptr, nonNull); } TEST(AllocatorWithGCTest, AllocateWithUnfixableOOM) { constexpr size_t size = 256; constexpr size_t alignment = 8; MockAllocatorWrapper baseAllocator; testing::StrictMock gc; { testing::InSequence seq; EXPECT_CALL(gc, SafePointAllocation(size)); EXPECT_CALL(*baseAllocator, Alloc(size, alignment)).WillOnce(testing::Return(nullptr)); EXPECT_CALL(gc, OnOOM(size)); EXPECT_CALL(*baseAllocator, Alloc(size, alignment)).WillOnce(testing::Return(nullptr)); } AllocatorWithGC allocator(std::move(baseAllocator), gc); void* ptr = allocator.Alloc(size, alignment); EXPECT_THAT(ptr, nullptr); } namespace { class GC { public: struct ObjectData { uint32_t flags = 42; }; class ThreadData { public: void SafePointAllocation(size_t size) noexcept {} void OnOOM(size_t size) noexcept {} }; }; using ObjectFactory = mm::ObjectFactory; KStdUniquePtr MakeObjectTypeInfo(int32_t size) { auto typeInfo = make_unique(); typeInfo->typeInfo_ = typeInfo.get(); typeInfo->instanceSize_ = size; return typeInfo; } KStdUniquePtr MakeArrayTypeInfo(int32_t elementSize) { auto typeInfo = make_unique(); typeInfo->typeInfo_ = typeInfo.get(); typeInfo->instanceSize_ = -elementSize; return typeInfo; } } // namespace TEST(ObjectFactoryTest, CreateObject) { auto typeInfo = MakeObjectTypeInfo(24); GC::ThreadData gc; ObjectFactory objectFactory; ObjectFactory::ThreadQueue threadQueue(objectFactory, gc); auto* object = threadQueue.CreateObject(typeInfo.get()); threadQueue.Publish(); auto node = ObjectFactory::NodeRef::From(object); EXPECT_FALSE(node.IsArray()); EXPECT_THAT(node.GetObjHeader(), object); EXPECT_THAT(node.GCObjectData().flags, 42); auto iter = objectFactory.Iter(); auto it = iter.begin(); EXPECT_THAT(*it, node); ++it; EXPECT_THAT(it, iter.end()); } TEST(ObjectFactoryTest, CreateArray) { auto typeInfo = MakeArrayTypeInfo(24); GC::ThreadData gc; ObjectFactory objectFactory; ObjectFactory::ThreadQueue threadQueue(objectFactory, gc); auto* array = threadQueue.CreateArray(typeInfo.get(), 3); threadQueue.Publish(); auto node = ObjectFactory::NodeRef::From(array); EXPECT_TRUE(node.IsArray()); EXPECT_THAT(node.GetArrayHeader(), array); EXPECT_THAT(node.GCObjectData().flags, 42); auto iter = objectFactory.Iter(); auto it = iter.begin(); EXPECT_THAT(*it, node); ++it; EXPECT_THAT(it, iter.end()); } TEST(ObjectFactoryTest, Erase) { auto objectTypeInfo = MakeObjectTypeInfo(24); auto arrayTypeInfo = MakeArrayTypeInfo(24); GC::ThreadData gc; ObjectFactory objectFactory; ObjectFactory::ThreadQueue threadQueue(objectFactory, gc); for (int i = 0; i < 10; ++i) { threadQueue.CreateObject(objectTypeInfo.get()); threadQueue.CreateArray(arrayTypeInfo.get(), 3); } threadQueue.Publish(); { auto iter = objectFactory.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->IsArray()) { iter.EraseAndAdvance(it); } else { ++it; } } } { auto iter = objectFactory.Iter(); int count = 0; for (auto it = iter.begin(); it != iter.end(); ++it, ++count) { EXPECT_FALSE(it->IsArray()); } EXPECT_THAT(count, 10); } } TEST(ObjectFactoryTest, Move) { auto objectTypeInfo = MakeObjectTypeInfo(24); auto arrayTypeInfo = MakeArrayTypeInfo(24); GC::ThreadData gc; ObjectFactory objectFactory; ObjectFactory::ThreadQueue threadQueue(objectFactory, gc); ObjectFactory::FinalizerQueue finalizerQueue; for (int i = 0; i < 10; ++i) { threadQueue.CreateObject(objectTypeInfo.get()); threadQueue.CreateArray(arrayTypeInfo.get(), 3); } threadQueue.Publish(); { auto iter = objectFactory.Iter(); for (auto it = iter.begin(); it != iter.end();) { if (it->IsArray()) { iter.MoveAndAdvance(finalizerQueue, it); } else { ++it; } } } { auto iter = objectFactory.Iter(); int count = 0; for (auto it = iter.begin(); it != iter.end(); ++it, ++count) { EXPECT_FALSE(it->IsArray()); } EXPECT_THAT(count, 10); } { int count = 0; for (auto it = finalizerQueue.begin(); it != finalizerQueue.end(); ++it, ++count) { EXPECT_TRUE(it->IsArray()); } EXPECT_THAT(count, 10); } } TEST(ObjectFactoryTest, ConcurrentPublish) { auto typeInfo = MakeObjectTypeInfo(24); ObjectFactory objectFactory; constexpr int kThreadCount = kDefaultThreadCount; std::atomic canStart(false); std::atomic readyCount(0); KStdVector threads; std::mutex expectedMutex; KStdVector expected; for (int i = 0; i < kThreadCount; ++i) { threads.emplace_back([&typeInfo, &objectFactory, &canStart, &readyCount, &expected, &expectedMutex]() { GC::ThreadData gc; ObjectFactory::ThreadQueue threadQueue(objectFactory, gc); auto* object = threadQueue.CreateObject(typeInfo.get()); { std::lock_guard guard(expectedMutex); expected.push_back(object); } ++readyCount; while (!canStart) { } threadQueue.Publish(); }); } while (readyCount < kThreadCount) { } canStart = true; for (auto& t : threads) { t.join(); } auto iter = objectFactory.Iter(); KStdVector actual; for (auto it = iter.begin(); it != iter.end(); ++it) { actual.push_back(it->GetObjHeader()); } EXPECT_THAT(actual, testing::UnorderedElementsAreArray(expected)); } ================================================ FILE: runtime/src/mm/cpp/ObjectOps.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ObjectOps.hpp" #include "Common.h" #include "ThreadData.hpp" using namespace kotlin; // TODO: Memory barriers. ALWAYS_INLINE void mm::SetStackRef(ObjHeader** location, ObjHeader* value) noexcept { *location = value; } ALWAYS_INLINE void mm::SetHeapRef(ObjHeader** location, ObjHeader* value) noexcept { *location = value; } #pragma clang diagnostic push // On 32-bit android arm clang warns of significant performance penalty because of large // atomic operations. TODO: Consider using alternative ways of ordering memory operations if they // turn out to be more efficient on these platforms. #pragma clang diagnostic ignored "-Watomic-alignment" ALWAYS_INLINE void mm::SetHeapRefAtomic(ObjHeader** location, ObjHeader* value) noexcept { __atomic_store_n(location, value, __ATOMIC_RELEASE); } ALWAYS_INLINE OBJ_GETTER(mm::ReadHeapRefAtomic, ObjHeader** location) noexcept { // TODO: Make this work with GCs that can stop thread at any point. auto result = __atomic_load_n(location, __ATOMIC_ACQUIRE); RETURN_OBJ(result); } ALWAYS_INLINE OBJ_GETTER(mm::CompareAndSwapHeapRef, ObjHeader** location, ObjHeader* expected, ObjHeader* value) noexcept { // TODO: Make this work with GCs that can stop thread at any point. ObjHeader* actual = expected; // TODO: Do we need this strong memory model? Do we need to use strong CAS? // This intrinsic modifies `actual` non-atomically. __atomic_compare_exchange_n(location, &actual, value, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); // On success, we already have old value (== `expected`) in `actual`. // On failure, we have the old value written into `actual`. RETURN_OBJ(actual); } #pragma clang diagnostic pop OBJ_GETTER(mm::AllocateObject, ThreadData* threadData, const TypeInfo* typeInfo) noexcept { // TODO: Make this work with GCs that can stop thread at any point. auto* object = threadData->objectFactoryThreadQueue().CreateObject(typeInfo); RETURN_OBJ(object); } OBJ_GETTER(mm::AllocateArray, ThreadData* threadData, const TypeInfo* typeInfo, uint32_t elements) noexcept { // TODO: Make this work with GCs that can stop thread at any point. auto* array = threadData->objectFactoryThreadQueue().CreateArray(typeInfo, static_cast(elements)); // `ArrayHeader` and `ObjHeader` are expected to be compatible. RETURN_OBJ(reinterpret_cast(array)); } ================================================ FILE: runtime/src/mm/cpp/ObjectOps.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_OBJECT_OPS_H #define RUNTIME_MM_OBJECT_OPS_H #include "Memory.h" namespace kotlin { namespace mm { class ThreadData; // TODO: Make sure these operations work with any kind of thread stopping: safepoints and signals. // TODO: Consider adding some kind of an `Object` type (that wraps `ObjHeader*`) which // will have these operations for a friendlier API. // TODO: `OBJ_GETTER` is used because the returned objects needs to be accessible via the rootset before the function // returns. If we had a different way to efficiently keep the object in the roots, `OBJ_GETTER` can be removed. void SetStackRef(ObjHeader** location, ObjHeader* value) noexcept; void SetHeapRef(ObjHeader** location, ObjHeader* value) noexcept; void SetHeapRefAtomic(ObjHeader** location, ObjHeader* value) noexcept; OBJ_GETTER(ReadHeapRefAtomic, ObjHeader** location) noexcept; OBJ_GETTER(CompareAndSwapHeapRef, ObjHeader** location, ObjHeader* expected, ObjHeader* value) noexcept; OBJ_GETTER(AllocateObject, ThreadData* threadData, const TypeInfo* typeInfo) noexcept; OBJ_GETTER(AllocateArray, ThreadData* threadData, const TypeInfo* typeInfo, uint32_t elements) noexcept; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_OBJECT_OPS_H ================================================ FILE: runtime/src/mm/cpp/RootSet.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "RootSet.hpp" #include "KAssert.h" #include "GlobalData.hpp" #include "ThreadData.hpp" using namespace kotlin; mm::ThreadRootSet::Iterator::Iterator(begin_t, ThreadRootSet& owner) noexcept : owner_(owner), phase_(Phase::kStack), stackIterator_(owner_.stack_.begin()) { Init(); } mm::ThreadRootSet::Iterator::Iterator(end_t, ThreadRootSet& owner) noexcept : owner_(owner), phase_(Phase::kDone) {} ObjHeader*& mm::ThreadRootSet::Iterator::operator*() noexcept { switch (phase_) { case Phase::kStack: return *stackIterator_; case Phase::kTLS: return **tlsIterator_; case Phase::kDone: RuntimeFail("Cannot dereference"); } } mm::ThreadRootSet::Iterator& mm::ThreadRootSet::Iterator::operator++() noexcept { switch (phase_) { case Phase::kStack: ++stackIterator_; Init(); return *this; case Phase::kTLS: ++tlsIterator_; Init(); return *this; case Phase::kDone: return *this; } } bool mm::ThreadRootSet::Iterator::operator==(const Iterator& rhs) const noexcept { if (phase_ != rhs.phase_) { return false; } switch (phase_) { case Phase::kDone: return true; case Phase::kStack: return stackIterator_ == rhs.stackIterator_; case Phase::kTLS: return tlsIterator_ == rhs.tlsIterator_; } } void mm::ThreadRootSet::Iterator::Init() noexcept { while (phase_ != Phase::kDone) { switch (phase_) { case Phase::kStack: if (stackIterator_ != owner_.stack_.end()) return; phase_ = Phase::kTLS; tlsIterator_ = owner_.tls_.begin(); break; case Phase::kTLS: if (tlsIterator_ != owner_.tls_.end()) return; phase_ = Phase::kDone; break; case Phase::kDone: RuntimeFail("Impossible"); } } } mm::GlobalRootSet::Iterator::Iterator(begin_t, GlobalRootSet& owner) noexcept : owner_(owner), phase_(Phase::kGlobals), globalsIterator_(owner_.globalsIterable_.begin()) { Init(); } mm::GlobalRootSet::Iterator::Iterator(end_t, GlobalRootSet& owner) noexcept : owner_(owner), phase_(Phase::kDone) {} ObjHeader*& mm::GlobalRootSet::Iterator::operator*() noexcept { switch (phase_) { case Phase::kGlobals: return **globalsIterator_; case Phase::kStableRefs: return *stableRefsIterator_; case Phase::kDone: RuntimeFail("Cannot dereference"); } } mm::GlobalRootSet::Iterator& mm::GlobalRootSet::Iterator::operator++() noexcept { switch (phase_) { case Phase::kGlobals: ++globalsIterator_; Init(); return *this; case Phase::kStableRefs: ++stableRefsIterator_; Init(); return *this; case Phase::kDone: return *this; } } bool mm::GlobalRootSet::Iterator::operator==(const Iterator& rhs) const noexcept { if (phase_ != rhs.phase_) { return false; } switch (phase_) { case Phase::kDone: return true; case Phase::kGlobals: return globalsIterator_ == rhs.globalsIterator_; case Phase::kStableRefs: return stableRefsIterator_ == rhs.stableRefsIterator_; } } void mm::GlobalRootSet::Iterator::Init() noexcept { while (phase_ != Phase::kDone) { switch (phase_) { case Phase::kGlobals: if (globalsIterator_ != owner_.globalsIterable_.end()) return; phase_ = Phase::kStableRefs; stableRefsIterator_ = owner_.stableRefsIterable_.begin(); break; case Phase::kStableRefs: if (stableRefsIterator_ != owner_.stableRefsIterable_.end()) return; phase_ = Phase::kDone; break; case Phase::kDone: RuntimeFail("Impossible"); } } } mm::ThreadRootSet::ThreadRootSet(ThreadData& threadData) noexcept : ThreadRootSet(threadData.shadowStack(), threadData.tls()) {} mm::GlobalRootSet::GlobalRootSet() noexcept : GlobalRootSet(mm::GlobalData::Instance().globalsRegistry(), mm::GlobalData::Instance().stableRefRegistry()) {} ================================================ FILE: runtime/src/mm/cpp/RootSet.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_ROOT_SET_H #define RUNTIME_MM_ROOT_SET_H #include "GlobalsRegistry.hpp" #include "ShadowStack.hpp" #include "StableRefRegistry.hpp" #include "ThreadLocalStorage.hpp" struct ObjHeader; namespace kotlin { namespace mm { class ThreadData; class ThreadRootSet { public: class Iterator { public: struct begin_t {}; static constexpr inline begin_t begin = begin_t{}; struct end_t {}; static constexpr inline end_t end = end_t{}; Iterator(begin_t, ThreadRootSet& owner) noexcept; Iterator(end_t, ThreadRootSet& owner) noexcept; ObjHeader*& operator*() noexcept; Iterator& operator++() noexcept; bool operator==(const Iterator& rhs) const noexcept; bool operator!=(const Iterator& rhs) const noexcept { return !(*this == rhs); } private: enum class Phase { kStack, kTLS, kDone, }; void Init() noexcept; ThreadRootSet& owner_; Phase phase_; union { ShadowStack::Iterator stackIterator_; ThreadLocalStorage::Iterator tlsIterator_; }; }; ThreadRootSet(ShadowStack& stack, ThreadLocalStorage& tls) noexcept : stack_(stack), tls_(tls) {} explicit ThreadRootSet(ThreadData& threadData) noexcept; Iterator begin() noexcept { return Iterator(Iterator::begin, *this); } Iterator end() noexcept { return Iterator(Iterator::end, *this); } private: ShadowStack& stack_; ThreadLocalStorage& tls_; }; class GlobalRootSet { public: class Iterator { public: struct begin_t {}; static constexpr inline begin_t begin = begin_t{}; struct end_t {}; static constexpr inline end_t end = end_t{}; Iterator(begin_t, GlobalRootSet& owner) noexcept; Iterator(end_t, GlobalRootSet& owner) noexcept; ObjHeader*& operator*() noexcept; Iterator& operator++() noexcept; bool operator==(const Iterator& rhs) const noexcept; bool operator!=(const Iterator& rhs) const noexcept { return !(*this == rhs); } private: enum class Phase { kGlobals, kStableRefs, kDone, }; void Init() noexcept; GlobalRootSet& owner_; Phase phase_; union { GlobalsRegistry::Iterator globalsIterator_; StableRefRegistry::Iterator stableRefsIterator_; }; }; GlobalRootSet(GlobalsRegistry& globalsRegistry, StableRefRegistry& stableRefRegistry) noexcept : globalsIterable_(globalsRegistry.Iter()), stableRefsIterable_(stableRefRegistry.Iter()) {} GlobalRootSet() noexcept; Iterator begin() noexcept { return Iterator(Iterator::begin, *this); } Iterator end() noexcept { return Iterator(Iterator::end, *this); } private: // TODO: These use separate locks, which is inefficient, and slightly dangerous. In practice it's // fine, because this is the only place where these two locks are taken simultaneously. GlobalsRegistry::Iterable globalsIterable_; StableRefRegistry::Iterable stableRefsIterable_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_ROOT_SET_H ================================================ FILE: runtime/src/mm/cpp/RootSetTest.cpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "RootSet.hpp" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "ShadowStack.hpp" using namespace kotlin; namespace { // TODO: All the test helpers to create the rootset should be abstracted out. template class StackEntry : private Pinned { public: static_assert(LocalsCount > 0, "Must have at least 1 object on stack"); explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(make_unique()) { // Fill `locals_` with some values. for (size_t i = 0; i < LocalsCount; ++i) { (*this)[i] = value_.get() + i; } shadowStack_.EnterFrame(data_.data(), 0, kTotalCount); } ~StackEntry() { shadowStack_.LeaveFrame(data_.data(), 0, kTotalCount); } ObjHeader*& operator[](size_t index) { return data_[kFrameOverlayCount + index]; } private: mm::ShadowStack& shadowStack_; KStdUniquePtr value_; // The following is what the compiler creates on the stack. static inline constexpr int kFrameOverlayCount = sizeof(FrameOverlay) / sizeof(ObjHeader**); static inline constexpr int kTotalCount = kFrameOverlayCount + LocalsCount; std::array data_; }; struct TLSKey {}; } // namespace TEST(ThreadRootSetTest, Basic) { mm::ShadowStack stack; StackEntry<2> entry(stack); TLSKey key; mm::ThreadLocalStorage tls; tls.AddRecord(&key, 3); tls.Commit(); mm::ThreadRootSet iter(stack, tls); KStdVector actual; for (auto& object : iter) { actual.push_back(object); } EXPECT_THAT(actual, testing::ElementsAre(entry[0], entry[1], *tls.Lookup(&key, 0), *tls.Lookup(&key, 1), *tls.Lookup(&key, 2))); } TEST(ThreadRootSetTest, Empty) { mm::ShadowStack stack; mm::ThreadLocalStorage tls; mm::ThreadRootSet iter(stack, tls); KStdVector actual; for (auto& object : iter) { actual.push_back(object); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(GlobalRootSetTest, Basic) { mm::GlobalsRegistry globals; mm::GlobalsRegistry::ThreadQueue globalsProducer(globals); ObjHeader* global1 = reinterpret_cast(1); ObjHeader* global2 = reinterpret_cast(2); globalsProducer.Insert(&global1); globalsProducer.Insert(&global2); mm::StableRefRegistry stableRefs; mm::StableRefRegistry::ThreadQueue stableRefsProducer(stableRefs); ObjHeader* stableRef1 = reinterpret_cast(3); ObjHeader* stableRef2 = reinterpret_cast(4); ObjHeader* stableRef3 = reinterpret_cast(5); stableRefsProducer.Insert(stableRef1); stableRefsProducer.Insert(stableRef2); stableRefsProducer.Insert(stableRef3); globalsProducer.Publish(); stableRefsProducer.Publish(); mm::GlobalRootSet iter(globals, stableRefs); KStdVector actual; for (auto& object : iter) { actual.push_back(object); } EXPECT_THAT(actual, testing::ElementsAre(global1, global2, stableRef1, stableRef2, stableRef3)); } TEST(GlobalRootSetTest, Empty) { mm::GlobalsRegistry globals; mm::StableRefRegistry stableRefs; mm::GlobalRootSet iter(globals, stableRefs); KStdVector actual; for (auto& object : iter) { actual.push_back(object); } EXPECT_THAT(actual, testing::IsEmpty()); } ================================================ FILE: runtime/src/mm/cpp/ShadowStack.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ShadowStack.hpp" using namespace kotlin; mm::ShadowStack::Iterator& mm::ShadowStack::Iterator::operator++() noexcept { ++object_; Init(); return *this; } void mm::ShadowStack::Iterator::Init() noexcept { while (frame_) { if (object_ < end_) return; frame_ = frame_->previous; object_ = begin(); end_ = end(); } } void mm::ShadowStack::EnterFrame(ObjHeader** start, int parameters, int count) noexcept { FrameOverlay* frame = reinterpret_cast(start); frame->previous = currentFrame_; currentFrame_ = frame; // TODO: maybe compress in single value somehow. frame->parameters = parameters; frame->count = count; } void mm::ShadowStack::LeaveFrame(ObjHeader** start, int parameters, int count) noexcept { FrameOverlay* frame = reinterpret_cast(start); currentFrame_ = frame->previous; } ================================================ FILE: runtime/src/mm/cpp/ShadowStack.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_SHADOW_STACK #define RUNTIME_MM_SHADOW_STACK #include "Memory.h" #include "Utils.hpp" struct FrameOverlay; struct ObjHeader; namespace kotlin { namespace mm { // Accessing current stack as provided by K/N compiler. The compiler calls `EnterFrame` when // it has allocated and zeroed stack space in the function prologue. And it calls `LeaveFrame` in // the function epilogue (both for regular return and for exception unwinding). // // Stack scanning does not lock anything and so must either be done while the mutator is stopped (or is // running code outside Kotlin), or by the mutator itself. So, in concurrent collection case, make sure // to do as little as possible while scanning the stack to free the mutator as soon as possible. // // TODO: This is currently incompatible with stack-allocated objects. Fix it. class ShadowStack : private Pinned { public: class Iterator { public: explicit Iterator(FrameOverlay* frame) noexcept : frame_(frame), object_(begin()), end_(end()) { Init(); } ObjHeader*& operator*() noexcept { return *object_; } Iterator& operator++() noexcept; bool operator==(const Iterator& rhs) const noexcept { return frame_ == rhs.frame_ && object_ == rhs.object_; } bool operator!=(const Iterator& rhs) const noexcept { return !(*this == rhs); } private: void Init() noexcept; // TODO: This copies the approach in the old MM. Do we need to also traverse function parameters in the new MM? ObjHeader** begin() noexcept { return frame_ ? reinterpret_cast(frame_ + 1) + frame_->parameters : nullptr; } ObjHeader** end() noexcept { constexpr int kFrameOverlaySlots = sizeof(FrameOverlay) / sizeof(ObjHeader**); return frame_ ? begin() + frame_->count - kFrameOverlaySlots - frame_->parameters : nullptr; } FrameOverlay* frame_; ObjHeader** object_ = nullptr; ObjHeader** end_ = nullptr; }; void EnterFrame(ObjHeader** start, int parameters, int count) noexcept; void LeaveFrame(ObjHeader** start, int parameters, int count) noexcept; Iterator begin() noexcept { return Iterator(currentFrame_); } Iterator end() noexcept { return Iterator(nullptr); } private: FrameOverlay* currentFrame_ = nullptr; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_SHADOW_STACK ================================================ FILE: runtime/src/mm/cpp/ShadowStackTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ShadowStack.hpp" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Memory.h" #include "Types.h" #include "Utils.hpp" using namespace kotlin; namespace { template class StackEntry : private Pinned { public: static_assert(ParametersCount + LocalsCount > 0, "Must have at least 1 object on stack"); explicit StackEntry(mm::ShadowStack& shadowStack) : shadowStack_(shadowStack), value_(make_unique()) { // Fill `locals_` with some values. for (size_t i = 0; i < LocalsCount; ++i) { (*this)[i] = value_.get() + i; } shadowStack_.EnterFrame(data_.data(), ParametersCount, kTotalCount); } ~StackEntry() { shadowStack_.LeaveFrame(data_.data(), ParametersCount, kTotalCount); } ObjHeader*& operator[](size_t index) { return data_[kFrameOverlayCount + ParametersCount + index]; } private: mm::ShadowStack& shadowStack_; KStdUniquePtr value_; // The following is what the compiler creates on the stack. static inline constexpr int kFrameOverlayCount = sizeof(FrameOverlay) / sizeof(ObjHeader**); static inline constexpr int kTotalCount = kFrameOverlayCount + ParametersCount + LocalsCount; std::array data_; }; KStdVector Collect(mm::ShadowStack& shadowStack) { KStdVector result; for (ObjHeader* local : shadowStack) { result.push_back(local); } return result; } } // namespace TEST(ShadowStackTest, Empty) { mm::ShadowStack shadowStack; auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ShadowStackTest, OneLocal) { mm::ShadowStack shadowStack; StackEntry<0, 1> frame1(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::ElementsAre(frame1[0])); } TEST(ShadowStackTest, ThreeLocals) { mm::ShadowStack shadowStack; StackEntry<0, 3> frame1(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::ElementsAre(frame1[0], frame1[1], frame1[2])); } TEST(ShadowStackTest, OneParameter) { mm::ShadowStack shadowStack; StackEntry<1, 0> frame1(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ShadowStackTest, ThreeLocalsAndOneParameter) { mm::ShadowStack shadowStack; StackEntry<1, 3> frame1(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::ElementsAre(frame1[0], frame1[1], frame1[2])); } TEST(ShadowStackTest, TwoStackFrames) { mm::ShadowStack shadowStack; StackEntry<1, 3> frame1(shadowStack); StackEntry<1, 3> frame2(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::ElementsAre(frame2[0], frame2[1], frame2[2], frame1[0], frame1[1], frame1[2])); } TEST(ShadowStackTest, ManyStackFrames) { mm::ShadowStack shadowStack; StackEntry<0, 3> frame1(shadowStack); StackEntry<1, 0> frame2(shadowStack); StackEntry<3, 1> frame3(shadowStack); StackEntry<3, 3> frame4(shadowStack); auto actual = Collect(shadowStack); EXPECT_THAT(actual, testing::ElementsAre(frame4[0], frame4[1], frame4[2], frame3[0], frame1[0], frame1[1], frame1[2])); } ================================================ FILE: runtime/src/mm/cpp/StableRefRegistry.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "StableRefRegistry.hpp" #include "GlobalData.hpp" #include "ThreadData.hpp" using namespace kotlin; // static mm::StableRefRegistry& mm::StableRefRegistry::Instance() noexcept { return GlobalData::Instance().stableRefRegistry(); } mm::StableRefRegistry::Node* mm::StableRefRegistry::RegisterStableRef(mm::ThreadData* threadData, ObjHeader* object) noexcept { return threadData->stableRefThreadQueue().Insert(object); } void mm::StableRefRegistry::UnregisterStableRef(mm::ThreadData* threadData, Node* node) noexcept { threadData->stableRefThreadQueue().Erase(node); } void mm::StableRefRegistry::ProcessThread(mm::ThreadData* threadData) noexcept { threadData->stableRefThreadQueue().Publish(); } void mm::StableRefRegistry::ProcessDeletions() noexcept { stableRefs_.ApplyDeletions(); } mm::StableRefRegistry::StableRefRegistry() = default; mm::StableRefRegistry::~StableRefRegistry() = default; ================================================ FILE: runtime/src/mm/cpp/StableRefRegistry.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_STABLE_REF_REGISTRY_H #define RUNTIME_MM_STABLE_REF_REGISTRY_H #include "Memory.h" #include "MultiSourceQueue.hpp" #include "ThreadRegistry.hpp" namespace kotlin { namespace mm { // Registry for all objects that have references outside of Kotlin. class StableRefRegistry : Pinned { public: class ThreadQueue : public MultiSourceQueue::Producer { public: explicit ThreadQueue(StableRefRegistry& registry) : Producer(registry.stableRefs_) {} // Do not add fields as this is just a wrapper and Producer does not have virtual destructor. }; using Iterable = MultiSourceQueue::Iterable; using Iterator = MultiSourceQueue::Iterator; using Node = MultiSourceQueue::Node; StableRefRegistry(); ~StableRefRegistry(); static StableRefRegistry& Instance() noexcept; Node* RegisterStableRef(mm::ThreadData* threadData, ObjHeader* object) noexcept; void UnregisterStableRef(mm::ThreadData* threadData, Node* node) noexcept; // Collect stable references from thread corresponding to `threadData`. Must be called by the thread // when it's asked by GC to stop. void ProcessThread(mm::ThreadData* threadData) noexcept; // Lock registry and apply deletions. Should be called on GC thread after all threads have published, and before `Iter`. void ProcessDeletions() noexcept; // Lock registry for safe iteration. // TODO: Iteration over `stableRefs_` will be slow, because it's `KStdList` collected at different times from // different threads, and so the nodes are all over the memory. Use metrics to understand how // much of a problem is it. Iterable Iter() noexcept { return stableRefs_.Iter(); } void ClearForTests() noexcept { stableRefs_.ClearForTests(); } private: // Current approach optimizes for creating and disposing of stable refs: // * creation just enqueues ref, disposing either queues or deletes the ref immediately (if it still resides in the current queue). // * when thread is stopped, it'll scan through the local queue (to mark that refs no longer reside in it) and push creation and // deletion queues to the global registry. // * during marking GC will have to `ProcessDeletions` to actually delete the refs that were enqueued for deletion. // So, we sacrifice memory (to keep deleted queues) and marking time (to process these queues) to improve creation and disposal times. // // Other alternatives: // * Use a single global collection (e.g. lock free doubly linked list). // * Sacrifice disposal time to try to delete as early as possible (e.g. post directly into owning producer, so it processes deletions // before posting queue to the global registry) // // TODO: Measure to understand, if this approach is problematic. MultiSourceQueue stableRefs_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_STABLE_REF_REGISTRY_H ================================================ FILE: runtime/src/mm/cpp/Stubs.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" #include "KAssert.h" ALWAYS_INLINE bool isFrozen(const ObjHeader* obj) { // TODO: Unimplemented return false; } extern "C" { void MutationCheck(ObjHeader* obj) { // TODO: Unimplemented } void FreezeSubgraph(ObjHeader* obj) { // TODO: Unimplemented } void EnsureNeverFrozen(ObjHeader* obj) { TODO(); } void Kotlin_native_internal_GC_suspend(ObjHeader*) { TODO(); } void Kotlin_native_internal_GC_resume(ObjHeader*) { TODO(); } void Kotlin_native_internal_GC_stop(ObjHeader*) { TODO(); } void Kotlin_native_internal_GC_start(ObjHeader*) { TODO(); } void Kotlin_native_internal_GC_setTuneThreshold(ObjHeader*, int32_t value) { TODO(); } bool Kotlin_native_internal_GC_getTuneThreshold(ObjHeader*) { TODO(); } bool TryAddHeapRef(const ObjHeader* object) { TODO(); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) { TODO(); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) { TODO(); } ForeignRefContext InitLocalForeignRef(ObjHeader* object) { TODO(); } } // extern "C" ================================================ FILE: runtime/src/mm/cpp/TestSupport.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "../../main/cpp/TestSupport.hpp" #include "MemoryPrivate.hpp" #include "ThreadData.hpp" namespace kotlin { inline void RunInNewThread(std::function f) { kotlin::RunInNewThread([&f](MemoryState* state) { f(*state->GetThreadData()); }); } } // namespace kotlin ================================================ FILE: runtime/src/mm/cpp/ThreadData.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_THREAD_DATA_H #define RUNTIME_MM_THREAD_DATA_H #include #include #include "GlobalData.hpp" #include "GlobalsRegistry.hpp" #include "GC.hpp" #include "ObjectFactory.hpp" #include "ShadowStack.hpp" #include "StableRefRegistry.hpp" #include "ThreadLocalStorage.hpp" #include "ThreadState.hpp" #include "Types.h" #include "Utils.hpp" struct ObjHeader; namespace kotlin { namespace mm { // `ThreadData` is supposed to be thread local singleton. // Pin it in memory to prevent accidental copying. class ThreadData final : private Pinned { public: ThreadData(pthread_t threadId) noexcept : threadId_(threadId), globalsThreadQueue_(GlobalsRegistry::Instance()), stableRefThreadQueue_(StableRefRegistry::Instance()), state_(ThreadState::kRunnable), gc_(GlobalData::Instance().gc()), objectFactoryThreadQueue_(GlobalData::Instance().objectFactory(), gc_) {} ~ThreadData() = default; pthread_t threadId() const noexcept { return threadId_; } GlobalsRegistry::ThreadQueue& globalsThreadQueue() noexcept { return globalsThreadQueue_; } ThreadLocalStorage& tls() noexcept { return tls_; } StableRefRegistry::ThreadQueue& stableRefThreadQueue() noexcept { return stableRefThreadQueue_; } ThreadState state() noexcept { return state_; } ThreadState setState(ThreadState state) noexcept { return state_.exchange(state); } ObjectFactory::ThreadQueue& objectFactoryThreadQueue() noexcept { return objectFactoryThreadQueue_; } ShadowStack& shadowStack() noexcept { return shadowStack_; } KStdVector>& initializingSingletons() noexcept { return initializingSingletons_; } GC::ThreadData& gc() noexcept { return gc_; } void Publish() noexcept { // TODO: These use separate locks, which is inefficient. globalsThreadQueue_.Publish(); stableRefThreadQueue_.Publish(); objectFactoryThreadQueue_.Publish(); } private: const pthread_t threadId_; GlobalsRegistry::ThreadQueue globalsThreadQueue_; ThreadLocalStorage tls_; StableRefRegistry::ThreadQueue stableRefThreadQueue_; std::atomic state_; ShadowStack shadowStack_; GC::ThreadData gc_; ObjectFactory::ThreadQueue objectFactoryThreadQueue_; KStdVector> initializingSingletons_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_THREAD_DATA_H ================================================ FILE: runtime/src/mm/cpp/ThreadLocalStorage.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ThreadLocalStorage.hpp" using namespace kotlin; void mm::ThreadLocalStorage::AddRecord(Key key, int size) noexcept { RuntimeAssert(state_ == State::kBuilding, "Storage must be in the building state"); RuntimeAssert(size >= 0, "Size cannot be negative"); auto it = map_.find(key); if (it != map_.end()) { RuntimeAssert(it->second.size == size, "Attempt to add TLS record with the same key, but different size"); return; } map_.emplace(key, Entry{size_, size}); size_ += size; } void mm::ThreadLocalStorage::Commit() noexcept { RuntimeAssert(state_ == State::kBuilding, "Storage must be in the building state"); storage_.resize(size_); state_ = State::kCommitted; } void mm::ThreadLocalStorage::Clear() noexcept { RuntimeAssert(state_ == State::kCommitted, "Storage must be in the committed state"); // Just free the storage. storage_.clear(); state_ = State::kCleared; } ObjHeader** mm::ThreadLocalStorage::Lookup(Key key, int index) noexcept { RuntimeAssert(state_ == State::kCommitted, "Storage must be in the committed state"); if (lastKeyAndEntry_.first == key) { return Lookup(lastKeyAndEntry_.second, index); } auto it = map_.find(key); RuntimeAssert(it != map_.end(), "Unknown TLS key"); lastKeyAndEntry_ = *it; return Lookup(it->second, index); } ObjHeader** mm::ThreadLocalStorage::Lookup(Entry entry, int index) noexcept { RuntimeAssert(index < entry.size, "Out of bounds TLS access"); return &storage_[entry.offset + index]; } ================================================ FILE: runtime/src/mm/cpp/ThreadLocalStorage.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_THREAD_LOCAL_STORAGE_H #define RUNTIME_MM_THREAD_LOCAL_STORAGE_H #include #include #include #include "Memory.h" #include "Types.h" #include "Utils.hpp" namespace kotlin { namespace mm { class ThreadLocalStorage : Pinned { public: using Key = void*; class Iterator { public: explicit Iterator(KStdVector::iterator iterator) : iterator_(iterator) {} ObjHeader** operator*() noexcept { return &*iterator_; } Iterator& operator++() noexcept { ++iterator_; return *this; } bool operator==(const Iterator& rhs) const noexcept { return iterator_ == rhs.iterator_; } bool operator!=(const Iterator& rhs) const noexcept { return iterator_ != rhs.iterator_; } private: KStdVector::iterator iterator_; }; // Add TLS record. Can only be called before `Commit`. void AddRecord(Key key, int size) noexcept; // Prepare storage for records added by `AddRecord`. void Commit() noexcept; // Clear storage. Can only be called after `Commit`. void Clear() noexcept; // Lookup value in storage. Can only be called after `Commit`. ObjHeader** Lookup(Key key, int index) noexcept; Iterator begin() noexcept { return Iterator(storage_.begin()); } Iterator end() noexcept { return Iterator(storage_.end()); } private: enum class State { kBuilding, kCommitted, kCleared, }; struct Entry { int offset; int size; }; ObjHeader** Lookup(Entry entry, int index) noexcept; KStdVector storage_; // TODO: `KStdUnorderedMap` is probably the wrong container here. KStdUnorderedMap map_; State state_ = State::kBuilding; int size_ = 0; // Only used in `State::kBuilding` std::pair lastKeyAndEntry_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_THREAD_LOCAL_STORAGE_H ================================================ FILE: runtime/src/mm/cpp/ThreadLocalStorageTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ThreadLocalStorage.hpp" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "Types.h" using namespace kotlin; namespace { struct Key {}; } // namespace TEST(ThreadLocalStorageTest, Lookup) { Key key1; Key key2; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.AddRecord(&key2, 2); tls.Commit(); ObjHeader** location1 = tls.Lookup(&key1, 0); ObjHeader** location2 = tls.Lookup(&key2, 0); ObjHeader** location3 = tls.Lookup(&key2, 1); // Locations are not nulls. EXPECT_NE(location1, nullptr); EXPECT_NE(location2, nullptr); EXPECT_NE(location3, nullptr); // All three are different. EXPECT_NE(location1, location2); EXPECT_NE(location1, location3); EXPECT_NE(location2, location3); // All three can be written into. *location1 = nullptr; *location2 = nullptr; *location3 = nullptr; } TEST(ThreadLocalStorageTest, Iterate) { Key key1; Key key2; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.AddRecord(&key2, 2); tls.Commit(); KStdVector expected; expected.push_back(tls.Lookup(&key1, 0)); expected.push_back(tls.Lookup(&key2, 0)); expected.push_back(tls.Lookup(&key2, 1)); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::ElementsAreArray(expected)); } TEST(ThreadLocalStorageTest, AddRecordEmpty) { Key key1; Key key2; Key key3; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.AddRecord(&key2, 0); tls.AddRecord(&key3, 2); tls.Commit(); KStdVector expected; expected.push_back(tls.Lookup(&key1, 0)); expected.push_back(tls.Lookup(&key3, 0)); expected.push_back(tls.Lookup(&key3, 1)); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::ElementsAreArray(expected)); } TEST(ThreadLocalStorageTest, AddRecordSameSize) { Key key1; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.AddRecord(&key1, 1); tls.Commit(); KStdVector expected; expected.push_back(tls.Lookup(&key1, 0)); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::ElementsAreArray(expected)); } TEST(ThreadLocalStorageTest, NoRecords) { mm::ThreadLocalStorage tls; tls.Commit(); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ThreadLocalStorageTest, ClearEmpty) { mm::ThreadLocalStorage tls; tls.Commit(); tls.Clear(); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ThreadLocalStorageTest, ClearNonEmpty) { Key key1; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.Commit(); tls.Clear(); KStdVector actual; for (auto item : tls) { actual.push_back(item); } EXPECT_THAT(actual, testing::IsEmpty()); } TEST(ThreadLocalStorageTest, LookupCaching) { Key key1; Key key2; mm::ThreadLocalStorage tls; tls.AddRecord(&key1, 1); tls.AddRecord(&key2, 1); tls.Commit(); ObjHeader** location1 = tls.Lookup(&key1, 0); ObjHeader** location2 = tls.Lookup(&key2, 0); // Lookup same stuff again in different order. EXPECT_EQ(location1, tls.Lookup(&key1, 0)); EXPECT_EQ(location2, tls.Lookup(&key2, 0)); EXPECT_EQ(location2, tls.Lookup(&key2, 0)); EXPECT_EQ(location1, tls.Lookup(&key1, 0)); } ================================================ FILE: runtime/src/mm/cpp/ThreadRegistry.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ThreadRegistry.hpp" #include "GlobalData.hpp" #include "ThreadData.hpp" using namespace kotlin; // static mm::ThreadRegistry& mm::ThreadRegistry::Instance() noexcept { return mm::GlobalData::Instance().threadRegistry(); } mm::ThreadRegistry::Node* mm::ThreadRegistry::RegisterCurrentThread() noexcept { auto* threadDataNode = list_.Emplace(pthread_self()); Node*& currentDataNode = currentThreadDataNode_; RuntimeAssert(currentDataNode == nullptr, "This thread already had some data assigned to it."); currentDataNode = threadDataNode; return threadDataNode; } void mm::ThreadRegistry::Unregister(Node* threadDataNode) noexcept { list_.Erase(threadDataNode); // Do not touch `currentThreadData_` as TLS may already have been deallocated. } mm::ThreadRegistry::Iterable mm::ThreadRegistry::Iter() noexcept { return list_.Iter(); } ALWAYS_INLINE mm::ThreadData* mm::ThreadRegistry::CurrentThreadData() const noexcept { return CurrentThreadDataNode()->Get(); } mm::ThreadRegistry::ThreadRegistry() = default; mm::ThreadRegistry::~ThreadRegistry() = default; // static thread_local mm::ThreadRegistry::Node* mm::ThreadRegistry::currentThreadDataNode_ = nullptr; ================================================ FILE: runtime/src/mm/cpp/ThreadRegistry.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_THREAD_REGISTRY_H #define RUNTIME_MM_THREAD_REGISTRY_H #include #include "SingleLockList.hpp" #include "Utils.hpp" namespace kotlin { namespace mm { class ThreadData; class ThreadRegistry final : private Pinned { public: using Node = SingleLockList::Node; using Iterable = SingleLockList::Iterable; static ThreadRegistry& Instance() noexcept; Node* RegisterCurrentThread() noexcept; // `ThreadData` associated with `threadDataNode` cannot be used after this call. void Unregister(Node* threadDataNode) noexcept; // Locks `ThreadRegistry` for safe iteration. Iterable Iter() noexcept; // Try not to use these methods very often, as (1) thread local access can be slow on some platforms, // (2) TLS gets deallocated before our thread destruction hooks run. // Using this after `Unregister` for the thread has been called is undefined behaviour. ALWAYS_INLINE ThreadData* CurrentThreadData() const noexcept; Node* CurrentThreadDataNode() const noexcept { return currentThreadDataNode_; } private: friend class GlobalData; ThreadRegistry(); ~ThreadRegistry(); static thread_local Node* currentThreadDataNode_; SingleLockList list_; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_THREAD_REGISTRY_H ================================================ FILE: runtime/src/mm/cpp/ThreadRegistryTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "ThreadRegistry.hpp" #include #include #include "gtest/gtest.h" #include "ThreadData.hpp" using namespace kotlin; TEST(ThreadRegistryTest, RegisterCurrentThread) { std::thread t([]() { auto* node = mm::ThreadRegistry::Instance().RegisterCurrentThread(); auto* threadData = node->Get(); EXPECT_EQ(pthread_self(), threadData->threadId()); EXPECT_EQ(threadData, mm::ThreadRegistry::Instance().CurrentThreadData()); }); t.join(); } ================================================ FILE: runtime/src/mm/cpp/ThreadState.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "MemoryPrivate.hpp" #include "ThreadData.hpp" #include "ThreadState.hpp" namespace { ALWAYS_INLINE bool isStateSwitchAllowed(ThreadState oldState, ThreadState newState) noexcept { return oldState != newState; } const char* stateToString(ThreadState state) noexcept { switch (state) { case ThreadState::kRunnable: return "RUNNABLE"; case ThreadState::kNative: return "NATIVE"; } } } // namespace // Switches the state of the current thread to `newState` and returns the previous state. ALWAYS_INLINE ThreadState kotlin::SwitchThreadState(mm::ThreadData* threadData, ThreadState newState) noexcept { auto oldState = threadData->setState(newState); // TODO(perf): Mesaure the impact of this assert in debug and opt modes. RuntimeAssert(isStateSwitchAllowed(oldState, newState), "Illegal thread state switch. Old state: %s. New state: %s.", stateToString(oldState), stateToString(newState)); return oldState; } ALWAYS_INLINE ThreadState kotlin::SwitchThreadState(MemoryState* thread, ThreadState newState) noexcept { return SwitchThreadState(thread->GetThreadData(), newState); } ALWAYS_INLINE void kotlin::AssertThreadState(mm::ThreadData* threadData, ThreadState expected) noexcept { auto actual = threadData->state(); RuntimeAssert(actual == expected, "Unexpected thread state. Expected: %s. Actual: %s.", stateToString(expected), stateToString(actual)); } ALWAYS_INLINE void kotlin::AssertThreadState(MemoryState* thread, ThreadState expected) noexcept { AssertThreadState(thread->GetThreadData(), expected); } ================================================ FILE: runtime/src/mm/cpp/ThreadState.hpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_THREAD_STATE_H #define RUNTIME_MM_THREAD_STATE_H #include #include namespace kotlin { // Switches the state of the given thread to `newState` and returns the previous thread state. ALWAYS_INLINE ThreadState SwitchThreadState(mm::ThreadData* threadData, ThreadState newState) noexcept; ALWAYS_INLINE void AssertThreadState(mm::ThreadData* threadData, ThreadState expected) noexcept; } // namespace kotlin #endif // RUNTIME_MM_THREAD_STATE_H ================================================ FILE: runtime/src/mm/cpp/ThreadStateTest.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include "gtest/gtest.h" #include "gmock/gmock.h" #include "MemoryPrivate.hpp" #include "TestSupport.hpp" #include "ThreadData.hpp" #include "ThreadState.hpp" using namespace kotlin; namespace { class ThreadStateTest : public testing::Test { public: ThreadStateTest() { globalKotlinFunctionMock = &kotlinFunctionMock_; } ~ThreadStateTest() { globalKotlinFunctionMock = nullptr; } testing::MockFunction& kotlinFunctionMock() { return kotlinFunctionMock_; } static int32_t kotlinFunction(int32_t arg) { return globalKotlinFunctionMock->Call(arg); } static RUNTIME_NORETURN void noReturnKotlinFunciton(int32_t arg) { globalKotlinFunctionMock->Call(arg); throw std::exception(); } private: testing::MockFunction kotlinFunctionMock_; static testing::MockFunction* globalKotlinFunctionMock; }; //static testing::MockFunction* ThreadStateTest::globalKotlinFunctionMock = nullptr; } // namespace TEST_F(ThreadStateTest, StateSwitchWithThreadData) { RunInNewThread([](mm::ThreadData& threadData) { auto initialState = threadData.state(); EXPECT_EQ(ThreadState::kRunnable, initialState); ThreadState oldState = SwitchThreadState(&threadData, ThreadState::kNative); EXPECT_EQ(initialState, oldState); EXPECT_EQ(ThreadState::kNative, threadData.state()); }); } TEST_F(ThreadStateTest, StateSwitchWithMemoryState) { RunInNewThread([](MemoryState* memoryState) { auto threadData = memoryState->GetThreadData(); auto initialState = threadData->state(); EXPECT_EQ(ThreadState::kRunnable, initialState); ThreadState oldState = SwitchThreadState(memoryState, ThreadState::kNative); EXPECT_EQ(initialState, oldState); EXPECT_EQ(ThreadState::kNative, threadData->state()); }); } TEST_F(ThreadStateTest, StateSwitchExported) { RunInNewThread([](mm::ThreadData& threadData) { // Check functions exported for the compiler. EXPECT_EQ(ThreadState::kRunnable, threadData.state()); Kotlin_mm_switchThreadStateNative(); EXPECT_EQ(ThreadState::kNative, threadData.state()); Kotlin_mm_switchThreadStateRunnable(); EXPECT_EQ(ThreadState::kRunnable, threadData.state()); }); } TEST_F(ThreadStateTest, StateGuard) { RunInNewThread([](MemoryState* memoryState) { mm::ThreadData& threadData = *memoryState->GetThreadData(); auto initialState = threadData.state(); EXPECT_EQ(ThreadState::kRunnable, initialState); { ThreadStateGuard guard(memoryState, ThreadState::kNative); EXPECT_EQ(ThreadState::kNative, threadData.state()); } EXPECT_EQ(initialState, threadData.state()); }); } TEST_F(ThreadStateTest, StateGuardForCurrentThread) { RunInNewThread([]() { auto* memoryState = mm::GetMemoryState(); auto initialState = memoryState->GetThreadData()->state(); EXPECT_EQ(ThreadState::kRunnable, initialState); { ThreadStateGuard guard(memoryState, ThreadState::kNative); EXPECT_EQ(ThreadState::kNative, memoryState->GetThreadData()->state()); } EXPECT_EQ(initialState, memoryState->GetThreadData()->state()); }); } TEST_F(ThreadStateTest, CallKotlin) { RunInNewThread([this](mm::ThreadData& threadData) { SwitchThreadState(&threadData, ThreadState::kNative); ASSERT_THAT(threadData.state(), ThreadState::kNative); EXPECT_CALL(kotlinFunctionMock(), Call(42)) .WillOnce([&threadData](int32_t arg) { EXPECT_THAT(threadData.state(), ThreadState::kRunnable); return 24; }); int32_t result = CallKotlin(kotlinFunction, 42); EXPECT_THAT(threadData.state(), ThreadState::kNative); EXPECT_THAT(result, 24); }); } TEST_F(ThreadStateTest, CallKotlinNoReturn) { RunInNewThread([this](mm::ThreadData& threadData) { SwitchThreadState(&threadData, ThreadState::kNative); ASSERT_THAT(threadData.state(), ThreadState::kNative); EXPECT_CALL(kotlinFunctionMock(), Call(42)) .WillOnce([&threadData](int32_t arg){ EXPECT_THAT(threadData.state(), ThreadState::kRunnable); return 24; }); EXPECT_THROW(CallKotlinNoReturn(noReturnKotlinFunciton, 42), std::exception); EXPECT_THAT(threadData.state(), ThreadState::kNative); }); } TEST(ThreadStateDeathTest, StateAsserts) { RunInNewThread([](MemoryState* memoryState) { mm::ThreadData* threadData = memoryState->GetThreadData(); EXPECT_DEATH(AssertThreadState(memoryState, ThreadState::kNative), "runtime assert: Unexpected thread state. Expected: NATIVE. Actual: RUNNABLE"); EXPECT_DEATH(AssertThreadState(threadData, ThreadState::kNative), "runtime assert: Unexpected thread state. Expected: NATIVE. Actual: RUNNABLE"); EXPECT_DEATH(AssertThreadState(ThreadState::kNative), "runtime assert: Unexpected thread state. Expected: NATIVE. Actual: RUNNABLE"); }); } TEST(ThreadStateDeathTest, IncorrectStateSwitch) { RunInNewThread([](MemoryState* memoryState) { auto* threadData = memoryState->GetThreadData(); EXPECT_DEATH(SwitchThreadState(memoryState, ThreadState::kRunnable), "runtime assert: Illegal thread state switch. Old state: RUNNABLE. New state: RUNNABLE"); EXPECT_DEATH(SwitchThreadState(threadData, ThreadState::kRunnable), "runtime assert: Illegal thread state switch. Old state: RUNNABLE. New state: RUNNABLE"); EXPECT_DEATH(Kotlin_mm_switchThreadStateRunnable(), "runtime assert: Illegal thread state switch. Old state: RUNNABLE. New state: RUNNABLE"); SwitchThreadState(threadData, kotlin::ThreadState::kNative); EXPECT_DEATH(Kotlin_mm_switchThreadStateNative(), "runtime assert: Illegal thread state switch. Old state: NATIVE. New state: NATIVE"); }); } ================================================ FILE: runtime/src/mm/cpp/gc/NoOpGC.hpp ================================================ /* * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #ifndef RUNTIME_MM_NOOP_GC_H #define RUNTIME_MM_NOOP_GC_H #include #include "Utils.hpp" namespace kotlin { namespace mm { // No-op GC is a GC that does not free memory. // TODO: It can be made more efficient. class NoOpGC : private Pinned { public: class ObjectData {}; class ThreadData : private Pinned { public: using ObjectData = NoOpGC::ObjectData; explicit ThreadData(NoOpGC& gc) noexcept {} ~ThreadData() = default; void SafePointFunctionEpilogue() noexcept {} void SafePointLoopBody() noexcept {} void SafePointExceptionUnwind() noexcept {} void SafePointAllocation(size_t size) noexcept {} void PerformFullGC() noexcept {} void OnOOM(size_t size) noexcept {} private: }; NoOpGC() noexcept {} ~NoOpGC() = default; void SetThreshold(size_t value) noexcept { threshold_ = value; } size_t GetThreshold() noexcept { return threshold_; } void SetAllocationThresholdBytes(size_t value) noexcept { allocationThresholdBytes_ = value; } size_t GetAllocationThresholdBytes() noexcept { return allocationThresholdBytes_; } private: size_t threshold_ = 0; size_t allocationThresholdBytes_ = 0; }; } // namespace mm } // namespace kotlin #endif // RUNTIME_MM_NOOP_GC_H ================================================ FILE: runtime/src/objc/cpp/ObjCExportClasses.mm ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #import "Types.h" #import "Memory.h" #import "MemorySharedRefs.hpp" #if KONAN_OBJC_INTEROP #import #import #import #import #import #import #import #import #import "ObjCExport.h" #import "ObjCExportInit.h" #import "ObjCExportPrivate.h" #import "Runtime.h" #import "Mutex.hpp" #import "Exceptions.h" extern "C" id objc_retainAutoreleaseReturnValue(id self); extern "C" id objc_autoreleaseReturnValue(id self); @interface NSObject (NSObjectPrivateMethods) // Implemented for NSObject in libobjc/NSObject.mm -(BOOL)_tryRetain; @end; static void injectToRuntime(); // Note: `KotlinBase`'s `toKotlin` and `_tryRetain` methods will terminate if // called with non-frozen object on a wrong worker. `retain` will also terminate // in these conditions if backref's refCount is zero. @implementation KotlinBase { BackRefFromAssociatedObject refHolder; bool permanent; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(refHolder.ref()); } +(void)load { injectToRuntime(); } +(void)initialize { if (self == [KotlinBase class]) { Kotlin_ObjCExport_initialize(); } Kotlin_ObjCExport_initializeClass(self); } +(instancetype)allocWithZone:(NSZone*)zone { Kotlin_initRuntimeIfNeeded(); KotlinBase* result = [super allocWithZone:zone]; const TypeInfo* typeInfo = Kotlin_ObjCExport_getAssociatedTypeInfo(self); if (typeInfo == nullptr) { [NSException raise:NSGenericException format:@"%s is not allocatable or +[KotlinBase initialize] method wasn't called on it", class_getName(object_getClass(self))]; } if (typeInfo->instanceSize_ < 0) { [NSException raise:NSGenericException format:@"%s must be allocated and initialized with a factory method", class_getName(object_getClass(self))]; } ObjHolder holder; AllocInstanceWithAssociatedObject(typeInfo, result, holder.slot()); result->refHolder.initAndAddRef(holder.obj()); RuntimeAssert(!holder.obj()->permanent(), "dynamically allocated object is permanent"); result->permanent = false; return result; } +(instancetype)createWrapper:(ObjHeader*)obj { KotlinBase* candidate = [super allocWithZone:nil]; // TODO: should we call NSObject.init ? candidate->refHolder.initAndAddRef(obj); candidate->permanent = obj->permanent(); if (!obj->permanent()) { // TODO: permanent objects should probably be supported as custom types. if (!isShareable(obj)) { SetAssociatedObject(obj, candidate); } else { id old = AtomicCompareAndSwapAssociatedObject(obj, nullptr, candidate); if (old != nullptr) { candidate->refHolder.releaseRef(); [candidate releaseAsAssociatedObject]; return objc_retainAutoreleaseReturnValue(old); } } } return objc_autoreleaseReturnValue(candidate); } -(instancetype)retain { if (permanent) { [super retain]; } else { refHolder.addRef(); } return self; } -(BOOL)_tryRetain { if (permanent) { return [super _tryRetain]; } else { return refHolder.tryAddRef(); } } -(oneway void)release { if (permanent) { [super release]; } else { refHolder.releaseRef(); } } -(void)releaseAsAssociatedObject { // This function is called by the GC. It made a decision to reclaim Kotlin object, and runs // deallocation hooks at the moment, including deallocation of the "associated object" ([self]) // using the [super release] call below. // The deallocation involves running [self dealloc] which can contain arbitrary code. // In particular, this code can retain and release [self]. Obj-C and Swift runtimes handle this // gracefully (unless the object gets accessed after the deallocation of course), but Kotlin doesn't. // Generally retaining and releasing Kotlin object that is being deallocated would lead to // use-after-dispose and double-dispose problems (with unpredictable consequences) or to an assertion failure. // To workaround this, detach the back ref from the Kotlin object: refHolder.detach(); // So retain/release/etc. on [self] won't affect the Kotlin object, and an attempt to get // the reference to it (e.g. when calling Kotlin method on [self]) would crash. // The latter is generally ok because can be triggered only by user-defined Swift/Obj-C // subclasses of Kotlin classes. [super release]; } - (instancetype)copyWithZone:(NSZone *)zone { // TODO: write documentation. return [self retain]; } @end; @interface NSObject (NSObjectToKotlin) @end; @implementation NSObject (NSObjectToKotlin) -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_ObjCExport_convertUnmappedObjCObject, self); } -(void)releaseAsAssociatedObject { objc_release(self); } @end; @interface NSString (NSStringToKotlin) @end; @implementation NSString (NSStringToKotlin) -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_Interop_CreateKStringFromNSString, self); } @end; extern "C" { OBJ_GETTER(Kotlin_boxByte, KByte value); OBJ_GETTER(Kotlin_boxShort, KShort value); OBJ_GETTER(Kotlin_boxInt, KInt value); OBJ_GETTER(Kotlin_boxLong, KLong value); OBJ_GETTER(Kotlin_boxUByte, KUByte value); OBJ_GETTER(Kotlin_boxUShort, KUShort value); OBJ_GETTER(Kotlin_boxUInt, KUInt value); OBJ_GETTER(Kotlin_boxULong, KULong value); OBJ_GETTER(Kotlin_boxFloat, KFloat value); OBJ_GETTER(Kotlin_boxDouble, KDouble value); } @interface NSNumber (NSNumberToKotlin) @end; @implementation NSNumber (NSNumberToKotlin) -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { const char* type = self.objCType; // TODO: the code below makes some assumption on char, short, int and long sizes. switch (type[0]) { case 'c': RETURN_RESULT_OF(Kotlin_boxByte, self.charValue); case 's': RETURN_RESULT_OF(Kotlin_boxShort, self.shortValue); case 'i': RETURN_RESULT_OF(Kotlin_boxInt, self.intValue); case 'q': RETURN_RESULT_OF(Kotlin_boxLong, self.longLongValue); case 'C': RETURN_RESULT_OF(Kotlin_boxUByte, self.unsignedCharValue); case 'S': RETURN_RESULT_OF(Kotlin_boxUShort, self.unsignedShortValue); case 'I': RETURN_RESULT_OF(Kotlin_boxUInt, self.unsignedIntValue); case 'Q': RETURN_RESULT_OF(Kotlin_boxULong, self.unsignedLongLongValue); case 'f': RETURN_RESULT_OF(Kotlin_boxFloat, self.floatValue); case 'd': RETURN_RESULT_OF(Kotlin_boxDouble, self.doubleValue); default: RETURN_RESULT_OF(Kotlin_ObjCExport_convertUnmappedObjCObject, self); } } @end; @interface NSDecimalNumber (NSDecimalNumberToKotlin) @end; @implementation NSDecimalNumber (NSDecimalNumberToKotlin) // Overrides [NSNumber toKotlin:] implementation. -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_ObjCExport_convertUnmappedObjCObject, self); } @end; static void injectToRuntime() { // If the code below fails, then it is most likely caused by KT-42254. constexpr const char* errorMessage = "runtime injected twice; https://youtrack.jetbrains.com/issue/KT-42254 might be related"; RuntimeCheck(Kotlin_ObjCExport_toKotlinSelector == nullptr, errorMessage); Kotlin_ObjCExport_toKotlinSelector = @selector(toKotlin:); RuntimeCheck(Kotlin_ObjCExport_releaseAsAssociatedObjectSelector == nullptr, errorMessage); Kotlin_ObjCExport_releaseAsAssociatedObjectSelector = @selector(releaseAsAssociatedObject); } #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/objc/cpp/ObjCExportCollections.mm ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "Memory.h" #import "MemorySharedRefs.hpp" #import "Types.h" #if KONAN_OBJC_INTEROP #import #import #import #import #import #import #import "Exceptions.h" #import "Runtime.h" #import "ObjCExport.h" #import "ObjCExportCollections.h" extern "C" { // Imports from ObjCExportUtils.kt: OBJ_GETTER0(Kotlin_NSArrayAsKList_create); OBJ_GETTER0(Kotlin_NSMutableArrayAsKMutableList_create); OBJ_GETTER0(Kotlin_NSSetAsKSet_create); OBJ_GETTER0(Kotlin_NSDictionaryAsKMap_create); KBoolean Kotlin_Iterator_hasNext(KRef iterator); OBJ_GETTER(Kotlin_Iterator_next, KRef iterator); KInt Kotlin_Collection_getSize(KRef collection); KBoolean Kotlin_Set_contains(KRef set, KRef element); OBJ_GETTER(Kotlin_Set_getElement, KRef set, KRef element); OBJ_GETTER(Kotlin_Set_iterator, KRef set); void Kotlin_MutableCollection_removeObject(KRef collection, KRef element); void Kotlin_MutableCollection_addObject(KRef list, KRef obj); OBJ_GETTER(Kotlin_MutableSet_createWithCapacity, KInt capacity); KInt Kotlin_Map_getSize(KRef map); KBoolean Kotlin_Map_containsKey(KRef map, KRef key); OBJ_GETTER(Kotlin_Map_get, KRef map, KRef key); OBJ_GETTER(Kotlin_Map_keyIterator, KRef map); OBJ_GETTER(Kotlin_List_get, KRef list, KInt index); OBJ_GETTER(Kotlin_MutableMap_createWithCapacity, KInt capacity); void Kotlin_MutableMap_set(KRef map, KRef key, KRef value); void Kotlin_MutableMap_remove(KRef map, KRef key); void Kotlin_MutableList_addObjectAtIndex(KRef list, KInt index, KRef obj); void Kotlin_MutableList_removeObjectAtIndex(KRef list, KInt index); void Kotlin_MutableList_removeLastObject(KRef list); void Kotlin_MutableList_setObject(KRef list, KInt index, KRef obj); } // extern "C" static inline KInt objCCapacityToKotlin(NSUInteger capacity) { NSUInteger max = std::numeric_limits::max(); return capacity > max ? max : capacity; } static inline KInt objCIndexToKotlinOrThrow(NSUInteger index) { if (index > std::numeric_limits::max()) { ThrowArrayIndexOutOfBoundsException(); } return index; } // Note: collections can only be iterated on and converted to Kotlin representation // when they are either frozen or if they are called on the worker that created them. @interface NSArray (NSArrayToKotlin) @end; @implementation NSArray (NSArrayToKotlin) -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_RESULT_OF(invokeAndAssociate, Kotlin_NSArrayAsKList_create, objc_retain(self)); } -(void)releaseAsAssociatedObject { objc_release(self); } @end; @interface NSMutableArray (NSMutableArrayToKotlin) @end; @implementation NSMutableArray (NSArrayToKotlin) -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_RESULT_OF(invokeAndAssociate, Kotlin_NSMutableArrayAsKMutableList_create, objc_retain(self)); } -(void)releaseAsAssociatedObject { objc_release(self); } @end; @interface NSSet (NSSetToKotlin) @end; @implementation NSSet (NSSetToKotlin) -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_RESULT_OF(invokeAndAssociate, Kotlin_NSSetAsKSet_create, objc_retain(self)); } -(void)releaseAsAssociatedObject { objc_release(self); } @end; @interface NSDictionary (NSDictionaryToKotlin) @end; @implementation NSDictionary (NSDictionaryToKotlin) -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_RESULT_OF(invokeAndAssociate, Kotlin_NSDictionaryAsKMap_create, objc_retain(self)); } -(void)releaseAsAssociatedObject { objc_release(self); } @end; @interface KIteratorAsNSEnumerator : NSEnumerator @end; @implementation KIteratorAsNSEnumerator { KRefSharedHolder iteratorHolder; } -(void)dealloc { iteratorHolder.dispose(); [super dealloc]; } +(id)createWithKIterator:(KRef)iterator { KIteratorAsNSEnumerator* result = [[[KIteratorAsNSEnumerator alloc] init] autorelease]; result->iteratorHolder.init(iterator); return result; } - (id)nextObject { KRef iterator = iteratorHolder.ref(); if (Kotlin_Iterator_hasNext(iterator)) { ObjHolder holder; return refToObjCOrNSNull(Kotlin_Iterator_next(iterator, holder.slot())); } else { return nullptr; } } @end; @interface KListAsNSArray : NSArray @end; @implementation KListAsNSArray { KRefSharedHolder listHolder; } -(void)dealloc { listHolder.dispose(); [super dealloc]; } +(id)createWithKList:(KRef)list { KListAsNSArray* result = [[[KListAsNSArray alloc] init] autorelease]; result->listHolder.init(list); return result; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(listHolder.ref()); } -(id)objectAtIndex:(NSUInteger)index { ObjHolder kotlinValueHolder; KRef kotlinValue = Kotlin_List_get(listHolder.ref(), index, kotlinValueHolder.slot()); return refToObjCOrNSNull(kotlinValue); } -(NSUInteger)count { return Kotlin_Collection_getSize(listHolder.ref()); } @end; @interface KMutableListAsNSMutableArray : NSMutableArray @end; @implementation KMutableListAsNSMutableArray { KRefSharedHolder listHolder; } -(void)dealloc { listHolder.dispose(); [super dealloc]; } +(id)createWithKList:(KRef)list { KMutableListAsNSMutableArray* result = [[[KMutableListAsNSMutableArray alloc] init] autorelease]; result->listHolder.init(list); return result; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(listHolder.ref()); } -(id)objectAtIndex:(NSUInteger)index { ObjHolder kotlinValueHolder; KRef kotlinValue = Kotlin_List_get(listHolder.ref(), index, kotlinValueHolder.slot()); return refToObjCOrNSNull(kotlinValue); } -(NSUInteger)count { return Kotlin_Collection_getSize(listHolder.ref()); } - (void)insertObject:(id)anObject atIndex:(NSUInteger)index { ObjHolder holder; KRef kotlinObject = refFromObjCOrNSNull(anObject, holder.slot()); Kotlin_MutableList_addObjectAtIndex(listHolder.ref(), objCIndexToKotlinOrThrow(index), kotlinObject); } - (void)removeObjectAtIndex:(NSUInteger)index { Kotlin_MutableList_removeObjectAtIndex(listHolder.ref(), objCIndexToKotlinOrThrow(index)); } - (void)addObject:(id)anObject { ObjHolder holder; Kotlin_MutableCollection_addObject(listHolder.ref(), refFromObjCOrNSNull(anObject, holder.slot())); } - (void)removeLastObject { Kotlin_MutableList_removeLastObject(listHolder.ref()); } - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject { ObjHolder holder; KRef kotlinObject = refFromObjCOrNSNull(anObject, holder.slot()); Kotlin_MutableList_setObject(listHolder.ref(), objCIndexToKotlinOrThrow(index), kotlinObject); } @end; @interface KSetAsNSSet : NSSet @end; static inline id KSet_getElement(KRef set, id object) { if (object == NSNull.null) { return Kotlin_Set_contains(set, nullptr) ? object : nullptr; } else { ObjHolder requestHolder, resultHolder; KRef request = Kotlin_ObjCExport_refFromObjC(object, requestHolder.slot()); KRef result = Kotlin_Set_getElement(set, request, resultHolder.slot()); // Note: if result is nullptr, then it can't be a null element of the set, because request != nullptr; // so map nullptr to nullptr: return Kotlin_ObjCExport_refToObjC(result); } } @implementation KSetAsNSSet { KRefSharedHolder setHolder; } -(void)dealloc { setHolder.dispose(); [super dealloc]; } +(id)createWithKSet:(KRef)set { KSetAsNSSet* result = [[[KSetAsNSSet alloc] init] autorelease]; result->setHolder.init(set); return result; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(setHolder.ref()); } -(NSUInteger) count { return Kotlin_Collection_getSize(setHolder.ref()); } - (id)member:(id)object { return KSet_getElement(setHolder.ref(), object); } // Not mandatory, just an optimization: - (BOOL)containsObject:(id)anObject { ObjHolder holder; return Kotlin_Set_contains(setHolder.ref(), refFromObjCOrNSNull(anObject, holder.slot())); } - (NSEnumerator*)objectEnumerator { ObjHolder holder; return [KIteratorAsNSEnumerator createWithKIterator:Kotlin_Set_iterator(setHolder.ref(), holder.slot())]; } @end; @interface KotlinMutableSet : NSMutableSet @end; @implementation KotlinMutableSet { KRefSharedHolder setHolder; } -(instancetype)init { if (self = [super init]) { Kotlin_initRuntimeIfNeeded(); ObjHolder holder; KRef set = Kotlin_MutableSet_createWithCapacity(8, holder.slot()); self->setHolder.init(set); } return self; } - (instancetype)initWithCapacity:(NSUInteger)numItems { if (self = [super init]) { Kotlin_initRuntimeIfNeeded(); ObjHolder holder; KRef set = Kotlin_MutableSet_createWithCapacity(objCCapacityToKotlin(numItems), holder.slot()); self->setHolder.init(set); } return self; } // TODO: super class implementation appears to be good enough. - (instancetype)initWithObjects:(const id _Nonnull [_Nullable])objects count:(NSUInteger)cnt { if (self = [self initWithCapacity:cnt]) { for (NSUInteger i = 0; i < cnt; ++i) { [self addObject:objects[i]]; } } return self; } // TODO: what about // - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder // ? -(void)dealloc { // Note: since setHolder initialization is not performed directly with alloc, // it is possible that it wasn't initialized properly. // Fortunately setHolder.dispose() handles the zero-initialized case too. setHolder.dispose(); [super dealloc]; } -(instancetype)initWithKSet:(KRef)set { if (self = [super init]) { setHolder.init(set); } return self; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(setHolder.ref()); } -(NSUInteger) count { return Kotlin_Collection_getSize(setHolder.ref()); } - (id)member:(id)object { return KSet_getElement(setHolder.ref(), object); } // Not mandatory, just an optimization: - (BOOL)containsObject:(id)anObject { ObjHolder holder; return Kotlin_Set_contains(setHolder.ref(), refFromObjCOrNSNull(anObject, holder.slot())); } - (NSEnumerator*)objectEnumerator { ObjHolder holder; return [KIteratorAsNSEnumerator createWithKIterator:Kotlin_Set_iterator(setHolder.ref(), holder.slot())]; } - (void)addObject:(id)object { ObjHolder holder; Kotlin_MutableCollection_addObject(setHolder.ref(), refFromObjCOrNSNull(object, holder.slot())); } - (void)removeObject:(id)object { ObjHolder holder; Kotlin_MutableCollection_removeObject(setHolder.ref(), refFromObjCOrNSNull(object, holder.slot())); } @end; @interface KMapAsNSDictionary : NSDictionary @end; static inline id KMap_get(KRef map, id aKey) { ObjHolder keyHolder, valueHolder; KRef kotlinKey = refFromObjCOrNSNull(aKey, keyHolder.slot()); KRef kotlinValue = Kotlin_Map_get(map, kotlinKey, valueHolder.slot()); if (kotlinValue == nullptr) { // Either null or not found. return Kotlin_Map_containsKey(map, kotlinKey) ? NSNull.null : nullptr; } else { return refToObjCOrNSNull(kotlinValue); } } @implementation KMapAsNSDictionary { KRefSharedHolder mapHolder; } -(void)dealloc { mapHolder.dispose(); [super dealloc]; } +(id)createWithKMap:(KRef)map { KMapAsNSDictionary* result = [[[KMapAsNSDictionary alloc] init] autorelease]; result->mapHolder.init(map); return result; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(mapHolder.ref()); } // According to documentation, initWithObjects:forKeys:count: is required to be overridden when subclassing. // But that doesn't make any sense, since this class can't be arbitrary initialized. -(NSUInteger) count { return Kotlin_Map_getSize(mapHolder.ref()); } - (id)objectForKey:(id)aKey { return KMap_get(mapHolder.ref(), aKey); } - (NSEnumerator *)keyEnumerator { ObjHolder holder; return [KIteratorAsNSEnumerator createWithKIterator:Kotlin_Map_keyIterator(mapHolder.ref(), holder.slot())]; } @end; @interface KotlinMutableDictionary : NSMutableDictionary @end; @implementation KotlinMutableDictionary { KRefSharedHolder mapHolder; } -(void)dealloc { // Note: since mapHolder initialization is not performed directly with alloc, // it is possible that it wasn't initialized properly. // Fortunately mapHolder.dispose() handles the zero-initialized case too. mapHolder.dispose(); [super dealloc]; } -(instancetype)init { if (self = [super init]) { Kotlin_initRuntimeIfNeeded(); ObjHolder holder; KRef map = Kotlin_MutableMap_createWithCapacity(8, holder.slot()); self->mapHolder.init(map); } return self; } // 'initWithObjects:forKeys:count:' seems to be implemented in base class. // TODO: what about // - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder // ? - (instancetype)initWithCapacity:(NSUInteger)numItems { if (self = [super init]) { Kotlin_initRuntimeIfNeeded(); ObjHolder holder; KRef map = Kotlin_MutableMap_createWithCapacity(objCCapacityToKotlin(numItems), holder.slot()); self->mapHolder.init(map); } return self; } -(instancetype)initWithKMap:(KRef)map { if (self = [super init]) { mapHolder.init(map); } return self; } -(KRef)toKotlin:(KRef*)OBJ_RESULT { RETURN_OBJ(mapHolder.ref()); } -(NSUInteger) count { return Kotlin_Map_getSize(mapHolder.ref()); } - (id)objectForKey:(id)aKey { return KMap_get(mapHolder.ref(), aKey); } - (NSEnumerator *)keyEnumerator { ObjHolder holder; return [KIteratorAsNSEnumerator createWithKIterator:Kotlin_Map_keyIterator(mapHolder.ref(), holder.slot())]; } - (void)setObject:(id)anObject forKey:(id)aKey { ObjHolder keyHolder, valueHolder; id keyCopy = [aKey copyWithZone:nullptr]; // Correspond to the expected NSMutableDictionary behaviour. KRef kotlinKey = refFromObjCOrNSNull(keyCopy, keyHolder.slot()); objc_release(keyCopy); KRef kotlinValue = refFromObjCOrNSNull(anObject, valueHolder.slot()); Kotlin_MutableMap_set(mapHolder.ref(), kotlinKey, kotlinValue); } - (void)removeObjectForKey:(id)aKey { ObjHolder holder; KRef kotlinKey = refFromObjCOrNSNull(aKey, holder.slot()); Kotlin_MutableMap_remove(mapHolder.ref(), kotlinKey); } @end; @interface NSEnumerator (NSEnumeratorAsAssociatedObject) @end; @implementation NSEnumerator (NSEnumeratorAsAssociatedObject) -(void)releaseAsAssociatedObject { objc_release(self); } @end; // Referenced from the generated code: extern "C" id Kotlin_Interop_CreateNSArrayFromKList(KRef obj) { return [KListAsNSArray createWithKList:obj]; } extern "C" id Kotlin_Interop_CreateNSMutableArrayFromKList(KRef obj) { return [KMutableListAsNSMutableArray createWithKList:obj]; } extern "C" id Kotlin_Interop_CreateNSSetFromKSet(KRef obj) { return [KSetAsNSSet createWithKSet:obj]; } extern "C" id Kotlin_Interop_CreateKotlinMutableSetFromKSet(KRef obj) { return [[[KotlinMutableSet alloc] initWithKSet:obj] autorelease]; } extern "C" id Kotlin_Interop_CreateNSDictionaryFromKMap(KRef obj) { return [KMapAsNSDictionary createWithKMap:obj]; } extern "C" id Kotlin_Interop_CreateKotlinMutableDictonaryFromKMap(KRef obj) { return [[[KotlinMutableDictionary alloc] initWithKMap:obj] autorelease]; } #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/objc/cpp/ObjCExportNumbers.mm ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if KONAN_OBJC_INTEROP #import #import #import #import #import "ObjCExport.h" #import "Runtime.h" #import "Mutex.hpp" extern "C" { OBJ_GETTER(Kotlin_boxBoolean, KBoolean value); OBJ_GETTER(Kotlin_boxByte, KByte value); OBJ_GETTER(Kotlin_boxShort, KShort value); OBJ_GETTER(Kotlin_boxInt, KInt value); OBJ_GETTER(Kotlin_boxLong, KLong value); OBJ_GETTER(Kotlin_boxUByte, KUByte value); OBJ_GETTER(Kotlin_boxUShort, KUShort value); OBJ_GETTER(Kotlin_boxUInt, KUInt value); OBJ_GETTER(Kotlin_boxULong, KULong value); OBJ_GETTER(Kotlin_boxFloat, KFloat value); OBJ_GETTER(Kotlin_boxDouble, KDouble value); } #pragma clang diagnostic ignored "-Wobjc-designated-initializers" @interface KotlinNumber : NSNumber @end; [[ noreturn ]] static void incorrectNumberInitialization(KotlinNumber* self, SEL _cmd) { [NSException raise:NSGenericException format:@"%@ can't be initialized with %s, use properly typed initialized", NSStringFromClass([self class]), sel_getName(_cmd)]; abort(); } [[ noreturn ]] static void incorrectNumberFactory(Class self, SEL _cmd) { [NSException raise:NSGenericException format:@"%@ can't be created with %s, use properly typed factory", NSStringFromClass(self), sel_getName(_cmd)]; abort(); } @implementation KotlinNumber : NSNumber - (NSNumber *)initWithBool:(BOOL)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithChar:(char)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithShort:(short)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithInt:(int)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithInteger:(NSInteger)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithLong:(long)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithLongLong:(long long)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedChar:(unsigned char)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedShort:(unsigned short)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedInt:(unsigned int)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedInteger:(NSUInteger)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedLong:(unsigned long)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithUnsignedLongLong:(unsigned long long)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithFloat:(float)value { incorrectNumberInitialization(self, _cmd); } - (NSNumber *)initWithDouble:(double)value { incorrectNumberInitialization(self, _cmd); } + (NSNumber *)numberWithBool:(BOOL)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithChar:(char)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithShort:(short)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithInt:(int)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithInteger:(NSInteger)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithLong:(long)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithLongLong:(long long)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedChar:(unsigned char)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedShort:(unsigned short)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedInt:(unsigned int)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedLong:(unsigned long)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithFloat:(float)value { incorrectNumberFactory(self, _cmd); } + (NSNumber *)numberWithDouble:(double)value { incorrectNumberFactory(self, _cmd); } @end; /* The code below is generated by: fun main(args: Array) { println(genBoolean()) println(genInteger("Byte", "c", "char")) println(genInteger("Short", "s", "short")) println(genInteger("Int", "i", "int")) println(genInteger("Long", "q", "long long")) println(genInteger("UByte", "C", "unsigned char")) println(genInteger("UShort", "S", "unsigned short")) println(genInteger("UInt", "I", "unsigned int")) println(genInteger("ULong", "Q", "unsigned long long")) println(genFloating("Float", "f", "float")) println(genFloating("Double", "d", "double")) } private fun genBoolean(): String = """ @interface KotlinBoolean : KotlinNumber @end; @implementation KotlinBoolean { BOOL value_; } - (void)getValue:(void *)value { *(BOOL*)value = value_; } - (instancetype)initWithBool:(BOOL)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithBool:(BOOL)value { KotlinBoolean* result = [[self new] autorelease]; result->value_ = value; return result; } - (BOOL)boolValue { return value_; } - (char)charValue { return value_; } - (const char *)objCType { return "c"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxBoolean, value_); } @end; """.trimIndent() private fun genInteger( name: String, encoding: String, cType: String, kind: String = getNSNumberKind(cType) ) = """ @interface Kotlin$name : KotlinNumber @end; @implementation Kotlin$name { $cType value_; } - (void)getValue:(void *)value { *($cType*)value = value_; } - (instancetype)initWith${kind.capitalize()}:($cType)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWith${kind.capitalize()}:($cType)value { Kotlin$name* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - ($cType)${kind}Value { return value_; } - (const char *)objCType { return "$encoding"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_box$name, value_); } @end; """.trimIndent() private fun getNSNumberKind(cType: String) = cType.split(' ').joinToString("") { it.capitalize() }.decapitalize() private fun genFloating( name: String, encoding: String, cType: String, kind: String = getNSNumberKind(cType) ): String = """ @interface Kotlin$name : KotlinNumber @end; @implementation Kotlin$name { $cType value_; } - (void)getValue:(void *)value { *($cType*)value = value_; } - (instancetype)initWith${kind.capitalize()}:($cType)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWith${kind.capitalize()}:($cType)value { Kotlin$name* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } ${if (cType != "double") """ // Required to convert Swift floating literals. - (instancetype)initWithDouble:(double)value { self = [super init]; value_ = value; // TODO: check fits. return self; } """ else ""} - ($cType)${kind}Value { return value_; } - (const char *)objCType { return "$encoding"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_box$name, value_); } @end; """.trimIndent() */ // TODO: consider generating it by compiler. @interface KotlinBoolean : KotlinNumber @end; @implementation KotlinBoolean { BOOL value_; } - (void)getValue:(void *)value { *(BOOL*)value = value_; } - (instancetype)initWithBool:(BOOL)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithBool:(BOOL)value { KotlinBoolean* result = [[self new] autorelease]; result->value_ = value; return result; } - (BOOL)boolValue { return value_; } - (char)charValue { return value_; } - (const char *)objCType { return "c"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxBoolean, value_); } @end; @interface KotlinByte : KotlinNumber @end; @implementation KotlinByte { char value_; } - (void)getValue:(void *)value { *(char*)value = value_; } - (instancetype)initWithChar:(char)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithChar:(char)value { KotlinByte* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (char)charValue { return value_; } - (const char *)objCType { return "c"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxByte, value_); } @end; @interface KotlinShort : KotlinNumber @end; @implementation KotlinShort { short value_; } - (void)getValue:(void *)value { *(short*)value = value_; } - (instancetype)initWithShort:(short)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithShort:(short)value { KotlinShort* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (short)shortValue { return value_; } - (const char *)objCType { return "s"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxShort, value_); } @end; @interface KotlinInt : KotlinNumber @end; @implementation KotlinInt { int value_; } - (void)getValue:(void *)value { *(int*)value = value_; } - (instancetype)initWithInt:(int)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithInt:(int)value { KotlinInt* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (int)intValue { return value_; } - (const char *)objCType { return "i"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxInt, value_); } @end; @interface KotlinLong : KotlinNumber @end; @implementation KotlinLong { long long value_; } - (void)getValue:(void *)value { *(long long*)value = value_; } - (instancetype)initWithLongLong:(long long)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithLongLong:(long long)value { KotlinLong* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (long long)longLongValue { return value_; } - (const char *)objCType { return "q"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxLong, value_); } @end; @interface KotlinUByte : KotlinNumber @end; @implementation KotlinUByte { unsigned char value_; } - (void)getValue:(void *)value { *(unsigned char*)value = value_; } - (instancetype)initWithUnsignedChar:(unsigned char)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithUnsignedChar:(unsigned char)value { KotlinUByte* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (unsigned char)unsignedCharValue { return value_; } - (const char *)objCType { return "C"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxUByte, value_); } @end; @interface KotlinUShort : KotlinNumber @end; @implementation KotlinUShort { unsigned short value_; } - (void)getValue:(void *)value { *(unsigned short*)value = value_; } - (instancetype)initWithUnsignedShort:(unsigned short)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithUnsignedShort:(unsigned short)value { KotlinUShort* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (unsigned short)unsignedShortValue { return value_; } - (const char *)objCType { return "S"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxUShort, value_); } @end; @interface KotlinUInt : KotlinNumber @end; @implementation KotlinUInt { unsigned int value_; } - (void)getValue:(void *)value { *(unsigned int*)value = value_; } - (instancetype)initWithUnsignedInt:(unsigned int)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithUnsignedInt:(unsigned int)value { KotlinUInt* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (unsigned int)unsignedIntValue { return value_; } - (const char *)objCType { return "I"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxUInt, value_); } @end; @interface KotlinULong : KotlinNumber @end; @implementation KotlinULong { unsigned long long value_; } - (void)getValue:(void *)value { *(unsigned long long*)value = value_; } - (instancetype)initWithUnsignedLongLong:(unsigned long long)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithUnsignedLongLong:(unsigned long long)value { KotlinULong* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (unsigned long long)unsignedLongLongValue { return value_; } - (const char *)objCType { return "Q"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxULong, value_); } @end; @interface KotlinFloat : KotlinNumber @end; @implementation KotlinFloat { float value_; } - (void)getValue:(void *)value { *(float*)value = value_; } - (instancetype)initWithFloat:(float)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithFloat:(float)value { KotlinFloat* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } // Required to convert Swift floating literals. - (instancetype)initWithDouble:(double)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (float)floatValue { return value_; } - (const char *)objCType { return "f"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxFloat, value_); } @end; @interface KotlinDouble : KotlinNumber @end; @implementation KotlinDouble { double value_; } - (void)getValue:(void *)value { *(double*)value = value_; } - (instancetype)initWithDouble:(double)value { self = [super init]; value_ = value; return self; } + (instancetype)numberWithDouble:(double)value { KotlinDouble* result = [[self new] autorelease]; result->value_ = value; return result; } // Required to convert Swift integer literals. - (instancetype)initWithInteger:(NSInteger)value { self = [super init]; value_ = value; // TODO: check fits. return self; } - (double)doubleValue { return value_; } - (const char *)objCType { return "d"; } -(ObjHeader*)toKotlin:(ObjHeader**)OBJ_RESULT { RETURN_RESULT_OF(Kotlin_boxDouble, value_); } @end; #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/objc/cpp/ObjCInteropUtilsClasses.mm ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #if KONAN_OBJC_INTEROP #import #import #import "Memory.h" #import "MemorySharedRefs.hpp" #import "ObjCInteropUtilsPrivate.h" // TODO: rework the interface to reduce the number of virtual calls // in Kotlin_Interop_createKotlinObjectHolder and Kotlin_Interop_unwrapKotlinObjectHolder @interface KotlinObjectHolder : NSObject -(id)initWithRef:(KRef)ref; -(KRef)ref; @end; @implementation KotlinObjectHolder { KRefSharedHolder refHolder; }; -(id)initWithRef:(KRef)ref { if (self = [super init]) { refHolder.init(ref); } return self; } -(KRef)ref { return refHolder.ref(); } -(void)dealloc { refHolder.dispose(); [super dealloc]; } @end; static id Kotlin_Interop_createKotlinObjectHolder(KRef any) { if (any == nullptr) { return nullptr; } return [[[KotlinObjectHolder alloc] initWithRef:any] autorelease]; } static KRef Kotlin_Interop_unwrapKotlinObjectHolder(id holder) { if (holder == nullptr) { return nullptr; } return [((KotlinObjectHolder*)holder) ref]; } // Used as an associated object for ObjCWeakReferenceImpl. @interface KotlinObjCWeakReference : NSObject @end; // libobjc: extern "C" { id objc_loadWeakRetained(id *location); id objc_storeWeak(id *location, id newObj); void objc_destroyWeak(id *location); void objc_release(id obj); } @implementation KotlinObjCWeakReference { @public id referred; } // Called when removing Kotlin object. -(void)releaseAsAssociatedObject { objc_destroyWeak(&referred); objc_release(self); } @end; extern "C" OBJ_GETTER(Kotlin_Interop_refFromObjC, id obj); static OBJ_GETTER(Konan_ObjCInterop_getWeakReference, KRef ref) { KotlinObjCWeakReference* objcRef = (KotlinObjCWeakReference*)ref->GetAssociatedObject(); id objcReferred = objc_loadWeakRetained(&objcRef->referred); KRef result = Kotlin_Interop_refFromObjC(objcReferred, OBJ_RESULT); objc_release(objcReferred); return result; } static void Konan_ObjCInterop_initWeakReference(KRef ref, id objcPtr) { KotlinObjCWeakReference* objcRef = [KotlinObjCWeakReference new]; objc_storeWeak(&objcRef->referred, objcPtr); ref->SetAssociatedObject(objcRef); } __attribute__((constructor)) static void injectToRuntime() { RuntimeCheck(Kotlin_Interop_createKotlinObjectHolder_ptr == nullptr, "runtime injected twice"); Kotlin_Interop_createKotlinObjectHolder_ptr = &Kotlin_Interop_createKotlinObjectHolder; RuntimeCheck(Kotlin_Interop_unwrapKotlinObjectHolder_ptr == nullptr, "runtime injected twice"); Kotlin_Interop_unwrapKotlinObjectHolder_ptr = &Kotlin_Interop_unwrapKotlinObjectHolder; RuntimeCheck(Konan_ObjCInterop_getWeakReference_ptr == nullptr, "runtime injected twice"); Konan_ObjCInterop_getWeakReference_ptr = &Konan_ObjCInterop_getWeakReference; RuntimeCheck(Konan_ObjCInterop_initWeakReference_ptr == nullptr, "runtime injected twice"); Konan_ObjCInterop_initWeakReference_ptr = &Konan_ObjCInterop_initWeakReference; } #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/opt_alloc/cpp/AllocImpl.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include extern "C" { void* mi_calloc(size_t, size_t); void mi_free(void*); void* mi_calloc_aligned(size_t count, size_t size, size_t alignment); void* konan_calloc_impl(size_t n_elements, size_t elem_size) { return mi_calloc(n_elements, elem_size); } void* konan_calloc_aligned_impl(size_t count, size_t size, size_t alignment) { return mi_calloc_aligned(count, size, alignment); } void konan_free_impl (void* mem) { mi_free(mem); } } // extern "C" ================================================ FILE: runtime/src/profile_runtime/cpp/ProfileRuntime.cpp ================================================ // Define symbols that are required for code coverage but missing in compiler-RT for MinGW.
 // See https://reviews.llvm.org/D58106/ for details. #ifdef KONAN_WINDOWS #include extern "C" { __attribute__((used)) int lprofGetHostName(char *hostName, int length) { const int maxHostNameLength = 128; WCHAR buffer[maxHostNameLength]; DWORD bufferSize = sizeof(buffer); COMPUTER_NAME_FORMAT nameType = ComputerNameDnsFullyQualified; if (!GetComputerNameExW(nameType, buffer, &bufferSize)) { return -1; } int bytesWritten = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, hostName, length, nullptr, nullptr); if (bytesWritten == 0) { return -1; } else { return 0; } } } #endif ================================================ FILE: runtime/src/relaxed/cpp/MemoryImpl.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" #include "../../legacymm/cpp/MemoryPrivate.hpp" // Fine, because this module is a part of legacy MM. // Note that only C++ part of the runtime goes via those functions, Kotlin uses specialized versions. extern "C" { const MemoryModel CurrentMemoryModel = MemoryModel::kRelaxed; OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) { RETURN_RESULT_OF(AllocInstanceRelaxed, typeInfo); } OBJ_GETTER(AllocArrayInstance, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(AllocArrayInstanceRelaxed, typeInfo, elements); } OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(InitThreadLocalSingletonRelaxed, location, typeInfo, ctor); } OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(InitSingletonRelaxed, location, typeInfo, ctor); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) { ReleaseHeapRefRelaxed(object); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) { ReleaseHeapRefNoCollectRelaxed(object); } RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) { ZeroStackRefRelaxed(location); } RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) { SetStackRefRelaxed(location, object); } RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) { SetHeapRefRelaxed(location, object); } RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) { UpdateHeapRefRelaxed(location, object); } RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) { UpdateReturnRefRelaxed(returnSlot, object); } RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) { EnterFrameRelaxed(start, parameters, count); } RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) { LeaveFrameRelaxed(start, parameters, count); } RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { UpdateStackRefRelaxed(location, object); } RUNTIME_NOTHROW void UpdateHeapRefsInsideOneArray(const ArrayHeader* array, int fromIndex, int toIndex, int count) { UpdateHeapRefsInsideOneArrayRelaxed(array, fromIndex, toIndex, count); } } // extern "C" ================================================ FILE: runtime/src/release/cpp/SourceInfo.cpp ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "SourceInfo.h" struct SourceInfo Kotlin_getSourceInfo(void* addr) { return (SourceInfo) { .fileName = nullptr, .lineNumber = -1, .column = -1 }; } ================================================ FILE: runtime/src/std_alloc/cpp/AllocImpl.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include #include extern "C" { // Memory operations. void* konan_calloc_impl(size_t n_elements, size_t elem_size) { return calloc(n_elements, elem_size); } void* konan_calloc_aligned_impl(size_t count, size_t size, size_t alignment) { // alignment is not supported by std alloc - use mimalloc return calloc(count, size); } void konan_free_impl (void* mem) { free(mem); } } ================================================ FILE: runtime/src/strict/cpp/MemoryImpl.cpp ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "Memory.h" #include "../../legacymm/cpp/MemoryPrivate.hpp" // Fine, because this module is a part of legacy MM. // Note that only C++ part of the runtime goes via those functions, Kotlin uses specialized versions. extern "C" { const MemoryModel CurrentMemoryModel = MemoryModel::kStrict; OBJ_GETTER(AllocInstance, const TypeInfo* typeInfo) { RETURN_RESULT_OF(AllocInstanceStrict, typeInfo); } OBJ_GETTER(AllocArrayInstance, const TypeInfo* typeInfo, int32_t elements) { RETURN_RESULT_OF(AllocArrayInstanceStrict, typeInfo, elements); } OBJ_GETTER(InitThreadLocalSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(InitThreadLocalSingletonStrict, location, typeInfo, ctor); } OBJ_GETTER(InitSingleton, ObjHeader** location, const TypeInfo* typeInfo, void (*ctor)(ObjHeader*)) { RETURN_RESULT_OF(InitSingletonStrict, location, typeInfo, ctor); } RUNTIME_NOTHROW void ReleaseHeapRef(const ObjHeader* object) { ReleaseHeapRefStrict(object); } RUNTIME_NOTHROW void ReleaseHeapRefNoCollect(const ObjHeader* object) { ReleaseHeapRefNoCollectStrict(object); } RUNTIME_NOTHROW void SetStackRef(ObjHeader** location, const ObjHeader* object) { SetStackRefStrict(location, object); } RUNTIME_NOTHROW void SetHeapRef(ObjHeader** location, const ObjHeader* object) { SetHeapRefStrict(location, object); } RUNTIME_NOTHROW void ZeroStackRef(ObjHeader** location) { ZeroStackRefStrict(location); } RUNTIME_NOTHROW void UpdateHeapRef(ObjHeader** location, const ObjHeader* object) { UpdateHeapRefStrict(location, object); } RUNTIME_NOTHROW void UpdateReturnRef(ObjHeader** returnSlot, const ObjHeader* object) { UpdateReturnRefStrict(returnSlot, object); } RUNTIME_NOTHROW void EnterFrame(ObjHeader** start, int parameters, int count) { EnterFrameStrict(start, parameters, count); } RUNTIME_NOTHROW void LeaveFrame(ObjHeader** start, int parameters, int count) { LeaveFrameStrict(start, parameters, count); } RUNTIME_NOTHROW void UpdateStackRef(ObjHeader** location, const ObjHeader* object) { UpdateStackRefStrict(location, object); } RUNTIME_NOTHROW void UpdateHeapRefsInsideOneArray(const ArrayHeader* array, int fromIndex, int toIndex, int count) { UpdateHeapRefsInsideOneArrayStrict(array, fromIndex, toIndex, count); } } // extern "C" ================================================ FILE: runtime/src/test_support/cpp/CompilerGenerated.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "TestSupportCompilerGenerated.hpp" #include "Types.h" namespace { class TypeInfoImpl { public: TypeInfoImpl() { type_.typeInfo_ = &type_; } TypeInfo* type() { return &type_; } private: TypeInfo type_; }; TypeInfoImpl theAnyTypeInfoImpl; TypeInfoImpl theArrayTypeInfoImpl; TypeInfoImpl theBooleanArrayTypeInfoImpl; TypeInfoImpl theByteArrayTypeInfoImpl; TypeInfoImpl theCharArrayTypeInfoImpl; TypeInfoImpl theDoubleArrayTypeInfoImpl; TypeInfoImpl theFloatArrayTypeInfoImpl; TypeInfoImpl theForeignObjCObjectTypeInfoImpl; TypeInfoImpl theFreezableAtomicReferenceTypeInfoImpl; TypeInfoImpl theIntArrayTypeInfoImpl; TypeInfoImpl theLongArrayTypeInfoImpl; TypeInfoImpl theNativePtrArrayTypeInfoImpl; TypeInfoImpl theObjCObjectWrapperTypeInfoImpl; TypeInfoImpl theOpaqueFunctionTypeInfoImpl; TypeInfoImpl theShortArrayTypeInfoImpl; TypeInfoImpl theStringTypeInfoImpl; TypeInfoImpl theThrowableTypeInfoImpl; TypeInfoImpl theUnitTypeInfoImpl; TypeInfoImpl theWorkerBoundReferenceTypeInfoImpl; TypeInfoImpl theCleanerImplTypeInfoImpl; ArrayHeader theEmptyStringImpl = {theStringTypeInfoImpl.type(), /* element count */ 0}; template struct KBox { ObjHeader header; const T value; }; testing::StrictMock>* createCleanerWorkerMock = nullptr; testing::StrictMock>* shutdownCleanerWorkerMock = nullptr; } // namespace extern "C" { // Set to 1 to enable runtime assertions. extern const int KonanNeedDebugInfo = 1; extern const TypeInfo* theAnyTypeInfo = theAnyTypeInfoImpl.type(); extern const TypeInfo* theArrayTypeInfo = theArrayTypeInfoImpl.type(); extern const TypeInfo* theBooleanArrayTypeInfo = theBooleanArrayTypeInfoImpl.type(); extern const TypeInfo* theByteArrayTypeInfo = theByteArrayTypeInfoImpl.type(); extern const TypeInfo* theCharArrayTypeInfo = theCharArrayTypeInfoImpl.type(); extern const TypeInfo* theDoubleArrayTypeInfo = theDoubleArrayTypeInfoImpl.type(); extern const TypeInfo* theFloatArrayTypeInfo = theFloatArrayTypeInfoImpl.type(); extern const TypeInfo* theForeignObjCObjectTypeInfo = theForeignObjCObjectTypeInfoImpl.type(); extern const TypeInfo* theFreezableAtomicReferenceTypeInfo = theFreezableAtomicReferenceTypeInfoImpl.type(); extern const TypeInfo* theIntArrayTypeInfo = theIntArrayTypeInfoImpl.type(); extern const TypeInfo* theLongArrayTypeInfo = theLongArrayTypeInfoImpl.type(); extern const TypeInfo* theNativePtrArrayTypeInfo = theNativePtrArrayTypeInfoImpl.type(); extern const TypeInfo* theObjCObjectWrapperTypeInfo = theObjCObjectWrapperTypeInfoImpl.type(); extern const TypeInfo* theOpaqueFunctionTypeInfo = theOpaqueFunctionTypeInfoImpl.type(); extern const TypeInfo* theShortArrayTypeInfo = theShortArrayTypeInfoImpl.type(); extern const TypeInfo* theStringTypeInfo = theStringTypeInfoImpl.type(); extern const TypeInfo* theThrowableTypeInfo = theThrowableTypeInfoImpl.type(); extern const TypeInfo* theUnitTypeInfo = theUnitTypeInfoImpl.type(); extern const TypeInfo* theWorkerBoundReferenceTypeInfo = theWorkerBoundReferenceTypeInfoImpl.type(); extern const TypeInfo* theCleanerImplTypeInfo = theCleanerImplTypeInfoImpl.type(); extern const ArrayHeader theEmptyArray = {theArrayTypeInfoImpl.type(), /* element count */ 0}; OBJ_GETTER0(TheEmptyString) { RETURN_OBJ(theEmptyStringImpl.obj()); } RUNTIME_NORETURN OBJ_GETTER(makeWeakReferenceCounter, void*) { throw std::runtime_error("Not implemented for tests"); } RUNTIME_NORETURN OBJ_GETTER(makePermanentWeakReferenceImpl, void*) { throw std::runtime_error("Not implemented for tests"); } RUNTIME_NORETURN OBJ_GETTER(makeObjCWeakReferenceImpl, void*) { throw std::runtime_error("Not implemented for tests"); } void checkRangeIndexes(KInt from, KInt to, KInt size) { if (from < 0 || to > size) { throw std::out_of_range("Index out of bounds: from=" + std::to_string(from) + ", to=" + std::to_string(to) + ", size=" + std::to_string(size)); } if (from > to) { throw std::invalid_argument("Illegal argument: from > to, from=" + std::to_string(from) + ", to=" + std::to_string(to)); } } RUNTIME_NORETURN OBJ_GETTER(WorkerLaunchpad, KRef) { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowWorkerInvalidState() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowNullPointerException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowArrayIndexOutOfBoundsException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowClassCastException(const ObjHeader* instance, const TypeInfo* type_info) { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowArithmeticException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowNumberFormatException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowOutOfMemoryError() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowNotImplementedError() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowCharacterCodingException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowIllegalArgumentException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowIllegalStateException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowInvalidMutabilityException(KConstRef where) { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowIncorrectDereferenceException() { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowIllegalObjectSharingException(KConstNativePtr typeInfo, KConstNativePtr address) { throw std::runtime_error("Not implemented for tests"); } void RUNTIME_NORETURN ThrowFreezingException(KRef toFreeze, KRef blocker) { throw std::runtime_error("Not implemented for tests"); } void ReportUnhandledException(KRef throwable) { konan::consolePrintf("Uncaught Kotlin exception."); } RUNTIME_NORETURN OBJ_GETTER(DescribeObjectForDebugging, KConstNativePtr typeInfo, KConstNativePtr address) { throw std::runtime_error("Not implemented for tests"); } void OnUnhandledException(KRef throwable) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_WorkerBoundReference_freezeHook(KRef thiz) { throw std::runtime_error("Not implemented for tests"); } extern const KBoolean BOOLEAN_RANGE_FROM = false; extern const KBoolean BOOLEAN_RANGE_TO = true; extern KBox BOOLEAN_CACHE[] = { {{}, false}, {{}, true}, }; OBJ_GETTER(Kotlin_boxBoolean, KBoolean value) { if (value) { RETURN_OBJ(&BOOLEAN_CACHE[1].header); } else { RETURN_OBJ(&BOOLEAN_CACHE[0].header); } } extern const KByte BYTE_RANGE_FROM = -1; extern const KByte BYTE_RANGE_TO = 1; extern KBox BYTE_CACHE[] = { {{}, -1}, {{}, 0}, {{}, 1}, }; extern const KChar CHAR_RANGE_FROM = 0; extern const KChar CHAR_RANGE_TO = 2; extern KBox CHAR_CACHE[] = { {{}, 0}, {{}, 1}, {{}, 2}, }; extern const KShort SHORT_RANGE_FROM = -1; extern const KShort SHORT_RANGE_TO = 1; extern KBox SHORT_CACHE[] = { {{}, -1}, {{}, 0}, {{}, 1}, }; extern const KInt INT_RANGE_FROM = -1; extern const KInt INT_RANGE_TO = 1; extern KBox INT_CACHE[] = { {{}, -1}, {{}, 0}, {{}, 1}, }; extern const KLong LONG_RANGE_FROM = -1; extern const KLong LONG_RANGE_TO = 1; extern KBox LONG_CACHE[] = { {{}, -1}, {{}, 0}, {{}, 1}, }; RUNTIME_NORETURN OBJ_GETTER(Kotlin_Throwable_getMessage, KRef throwable) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_CleanerImpl_shutdownCleanerWorker(KInt worker, bool executeScheduledCleaners) { if (!shutdownCleanerWorkerMock) throw std::runtime_error("Not implemented for tests"); return shutdownCleanerWorkerMock->Call(worker, executeScheduledCleaners); } KInt Kotlin_CleanerImpl_createCleanerWorker() { if (!createCleanerWorkerMock) throw std::runtime_error("Not implemented for tests"); return createCleanerWorkerMock->Call(); } } // extern "C" ScopedStrictMockFunction ScopedCreateCleanerWorkerMock() { return ScopedStrictMockFunction(&createCleanerWorkerMock); } ScopedStrictMockFunction ScopedShutdownCleanerWorkerMock() { return ScopedStrictMockFunction(&shutdownCleanerWorkerMock); } ================================================ FILE: runtime/src/test_support/cpp/CompilerGeneratedObjC.mm ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #if KONAN_OBJC_INTEROP #include "TestSupportCompilerGenerated.hpp" #include #include #include "Types.h" extern "C" { Class Kotlin_Interop_getObjCClass(const char* name) { Class result = objc_lookUpClass(name); if (result == nil) { // GTest can display error messages of C++ exceptions so we use them instead of ObjC ones. throw std::invalid_argument("Incorrect class name"); } return result; } RUNTIME_NORETURN OBJ_GETTER0(Kotlin_NSEnumeratorAsKIterator_create) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_NSEnumeratorAsKIterator_done(KRef thiz) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_NSEnumeratorAsKIterator_setNext(KRef thiz, KRef value) { throw std::runtime_error("Not implemented for tests"); } RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsExceptionImpl, KRef message, KRef error) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_ObjCExport_ThrowCollectionConcurrentModification() { throw std::runtime_error("Not implemented for tests"); } void Kotlin_ObjCExport_ThrowCollectionTooLarge() { throw std::runtime_error("Not implemented for tests"); } typedef OBJ_GETTER((*convertReferenceFromObjC), id obj); extern convertReferenceFromObjC Kotlin_ObjCExport_blockToFunctionConverters[] = {}; extern int Kotlin_ObjCExport_blockToFunctionConverters_size = 0; RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_createContinuationArgumentImpl, KRef completionHolder, const TypeInfo** exceptionTypes) { throw std::runtime_error("Not implemented for tests"); } RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_getWrappedError, KRef throwable) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_ObjCExport_resumeContinuationFailure(KRef continuation, KRef exception) { throw std::runtime_error("Not implemented for tests"); } void Kotlin_ObjCExport_resumeContinuationSuccess(KRef continuation, KRef result) { throw std::runtime_error("Not implemented for tests"); } } // extern "C" #endif // KONAN_OBJC_INTEROP ================================================ FILE: runtime/src/test_support/cpp/TestLauncher.cpp ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ #include "gmock/gmock.h" #include "gtest/gtest.h" int main(int argc, char** argv) { testing::InitGoogleMock(&argc, argv); // Use the `threadsafe` style to mitigate possible issues with multithreaded death tests. // See more about death test styles: https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#how-it-works testing::FLAGS_gtest_death_test_style="threadsafe"; return RUN_ALL_TESTS(); } ================================================ FILE: runtime/tsan_suppressions.txt ================================================ # Trust mimalloc to be thread safe. race:^mi_ race:^_mi_ ================================================ FILE: samples/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/androidNativeActivity/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/calculator/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/cocoapods/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/coverage/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/csvparser/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/curl/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/echoServer/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/gitchurn/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/globalState/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/gtk/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/html5Canvas/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/libcurl/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/nonBlockingEchoServer/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/objc/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/opengl/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/python_extension/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/simd/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/tensorflow/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/tetris/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/torch/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/uikit/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/videoplayer/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/watchos/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/weather_function/readme.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/win32/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/workers/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: samples/zephyr/README.md ================================================ Moved to https://github.com/JetBrains/kotlin/tree/master/kotlin-native/samples. ================================================ FILE: settings.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ include ':dependencies' include ':Interop:Indexer' include ':Interop:JsRuntime' include ':Interop:StubGenerator' include ':Interop:Runtime' include ':llvmCoverageMappingC' include ':llvmDebugInfoC' include ':libclangext' include ':klib' include ':backend.native' include ':runtime' include ':common' include ':backend.native:tests' include ':backend.native:debugger-tests' include ':utilities:basic-utils' include ':utilities:cli-runner' include ':dependencyPacker' include ':platformLibs' include ':endorsedLibraries' include ':endorsedLibraries:kotlinx.cli' if (hasProperty("kotlinProjectPath")) { include ':runtime:generator' includeBuild(kotlinProjectPath) { dependencySubstitution { substitute module("org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion") with project(':include:kotlin-compiler') substitute module("org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinStdlibVersion") with project(':include:kotlin-stdlib-common-sources') substitute module("org.jetbrains.kotlin:kotlin-stdlib-gen:$kotlinStdlibVersion") with project(':tools:kotlin-stdlib-gen') substitute module("org.jetbrains.kotlin:kotlin-util-io:$kotlinVersion") with project(':kotlin-util-io') substitute module("org.jetbrains.kotlin:kotlin-util-klib:$kotlinVersion") with project(':kotlin-util-klib') substitute module("org.jetbrains.kotlin:kotlin-util-klib-metadata:$kotlinVersion") with project(':kotlin-util-klib-metadata') substitute module("org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion") with project(':native:kotlin-native-utils') substitute module("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") with project(':kotlin-reflect') substitute module("org.jetbrains.kotlinx:kotlinx-metadata-klib") with project(':kotlinx-metadata-klib') } } } includeBuild 'shared' includeBuild 'build-tools' includeBuild 'tools/kotlin-native-gradle-plugin' ================================================ FILE: shared/build.gradle.kts ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UnstableApiUsage") import org.jetbrains.kotlin.VersionGenerator import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet plugins { id("kotlin") } val rootBuildDirectory by extra(file("..")) apply(from="../gradle/loadRootProperties.gradle") val kotlinVersion: String by extra val buildKotlinVersion: String by extra val konanVersion: String by extra val kotlinCompilerRepo: String by extra val buildKotlinCompilerRepo: String by extra group = "org.jetbrains.kotlin" version = konanVersion repositories { maven("https://cache-redirector.jetbrains.com/maven-central") mavenCentral() maven(kotlinCompilerRepo) maven(buildKotlinCompilerRepo) } // FIXME(ddol): KLIB-REFACTORING-CLEANUP: drop generation of KonanVersion! val generateCompilerVersion by tasks.registering(VersionGenerator::class) {} sourceSets["main"].withConvention(KotlinSourceSet::class) { kotlin.srcDir("src/main/kotlin") kotlin.srcDir("src/library/kotlin") kotlin.srcDir(generateCompilerVersion.get().versionSourceDirectory) } tasks.withType { dependsOn(generateCompilerVersion) kotlinOptions.jvmTarget = "1.8" kotlinOptions.freeCompilerArgs = listOf("-Xskip-prerelease-check") } tasks.clean { doFirst { val versionSourceDirectory = generateCompilerVersion.get().versionSourceDirectory if (versionSourceDirectory.exists()) { versionSourceDirectory.delete() } } } tasks.jar { archiveFileName.set("shared.jar") } dependencies { kotlinCompilerClasspath("org.jetbrains.kotlin:kotlin-compiler-embeddable:$buildKotlinVersion") implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion") api("org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion") api("org.jetbrains.kotlin:kotlin-util-klib:$kotlinVersion") } ================================================ FILE: shared/buildSrc/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ buildscript { ext.rootBuildDirectory = "$rootDir/../.." } apply plugin: 'java' repositories { mavenCentral() } dependencies { compile gradleApi() } ================================================ FILE: shared/buildSrc/settings.gradle ================================================ // workaround for https://youtrack.jetbrains.com/issue/IDEA-257366 if (gradle.startParameter.projectDir?.name == 'buildSrc') { gradle.startParameter.setIncludedBuilds(new ArrayList()) } ================================================ FILE: shared/buildSrc/src/main/java/org/jetbrains/kotlin/VersionGenerator.java ================================================ package org.jetbrains.kotlin; import groovy.lang.Closure; import org.gradle.api.DefaultTask; import org.gradle.api.Task; import org.gradle.api.tasks.*; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; public class VersionGenerator extends DefaultTask { @OutputDirectory public File getVersionSourceDirectory() { return getProject().file("build/generated"); } @OutputFile public File getVersionFile() { return getProject().file(getVersionSourceDirectory().getPath() + "/org/jetbrains/kotlin/konan/CompilerVersionGenerated.kt"); } @Input public String getKonanVersion() { return getProject().getProperties().get("konanVersion").toString(); } // TeamCity passes all configuration parameters into a build script as project properties. // Thus we can use them here instead of environment variables. @Optional @Input public String getBuildNumber() { Object property = getProject().findProperty("build.number"); if (property == null) return null; return property.toString(); } @Input public String getMeta() { Object konanMetaVersionProperty = getProject().getProperties().get("konanMetaVersion"); if (konanMetaVersionProperty == null) { return "MetaVersion.DEV"; } return "MetaVersion." + konanMetaVersionProperty.toString().toUpperCase(); } private final static Pattern versionPattern = Pattern.compile( "^(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:-M(\\p{Digit}))?(?:-(\\p{Alpha}\\p{Alnum}*))?(?:-(\\d+))?$" ); @TaskAction public void generateVersion() { Matcher matcher = versionPattern.matcher(getKonanVersion()); if (!matcher.matches()) { throw new IllegalArgumentException("Cannot parse Kotlin/Native version: $konanVersion"); } int major = Integer.parseInt(matcher.group(1)); int minor = Integer.parseInt(matcher.group(2)); String maintenanceStr = matcher.group(3); int maintenance = maintenanceStr != null ? Integer.parseInt(maintenanceStr) : 0; String milestoneStr = matcher.group(4); int milestone = milestoneStr != null ? Integer.parseInt(milestoneStr) : -1; String buildNumber = getBuildNumber(); getProject().getLogger().info("BUILD_NUMBER: " + getBuildNumber()); int build = -1; if (buildNumber != null) { String[] buildNumberSplit = buildNumber.split("-"); build = Integer.parseInt(buildNumberSplit[buildNumberSplit.length - 1]); // //7-dev-buildcount } try (PrintWriter printWriter = new PrintWriter(getVersionFile())) { printWriter.println( "package org.jetbrains.kotlin.konan\n" + "\n" + "internal val currentCompilerVersion: CompilerVersion =\n" + " CompilerVersionImpl(\n" + getMeta() + ", " + major + ", " + minor + ",\n" + maintenance + ", " + milestone + ", "+ build + ")\n" + "\n" + "val CompilerVersion.Companion.CURRENT: CompilerVersion\n" + " get() = currentCompilerVersion" ); } catch (FileNotFoundException e) { throw new IllegalStateException(e); } } } ================================================ FILE: shared/settings.gradle.kts ================================================ pluginManagement { val rootProperties = java.util.Properties().apply { rootDir.resolve("../gradle.properties").reader().use(::load) } val kotlinCompilerRepo: String by rootProperties val kotlinVersion: String by rootProperties repositories { maven(kotlinCompilerRepo) maven("https://cache-redirector.jetbrains.com/maven-central") mavenCentral() } resolutionStrategy { eachPlugin { if (requested.id.id == "kotlin") { useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") } } } } rootProject.name = "kotlin-native-shared" ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/KonanLibrary.kt ================================================ package org.jetbrains.kotlin.konan.library import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.library.* const val KLIB_PROPERTY_LINKED_OPTS = "linkerOpts" const val KLIB_PROPERTY_INCLUDED_HEADERS = "includedHeaders" interface TargetedLibrary { val targetList: List val includedPaths: List } interface BitcodeLibrary : TargetedLibrary { val bitcodePaths: List } interface KonanLibrary : BitcodeLibrary, KotlinLibrary { val linkerOpts: List } val KonanLibrary.includedHeaders get() = manifestProperties.propertyList(KLIB_PROPERTY_INCLUDED_HEADERS, escapeInQuotes = true) ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/KonanLibraryLayout.kt ================================================ /** * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.library import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.IrKotlinLibraryLayout import org.jetbrains.kotlin.library.KotlinLibraryLayout import org.jetbrains.kotlin.library.MetadataKotlinLibraryLayout interface TargetedKotlinLibraryLayout : KotlinLibraryLayout { val target: KonanTarget? // This is a default implementation. Can't make it an assignment. get() = null val targetsDir get() = File(componentDir, "targets") val targetDir get() = File(targetsDir, target!!.visibleName) val includedDir get() = File(targetDir, "included") } interface BitcodeKotlinLibraryLayout : TargetedKotlinLibraryLayout, KotlinLibraryLayout { val kotlinDir get() = File(targetDir, "kotlin") val nativeDir get() = File(targetDir, "native") // TODO: Experiment with separate bitcode files. // Per package or per class. val mainBitcodeFile get() = File(kotlinDir, "program.kt.bc") val mainBitcodeFileName get() = mainBitcodeFile.path } interface KonanLibraryLayout : MetadataKotlinLibraryLayout, BitcodeKotlinLibraryLayout, IrKotlinLibraryLayout ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/KonanLibraryWriter.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.konan.library import org.jetbrains.kotlin.library.BaseWriter import org.jetbrains.kotlin.library.IrWriter import org.jetbrains.kotlin.library.MetadataWriter interface TargetedWriter { fun addIncludedBinary(library: String) } interface BitcodeWriter : TargetedWriter { fun addNativeBitcode(library: String) } interface KonanLibraryWriter : MetadataWriter, BaseWriter, IrWriter, BitcodeWriter ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/SearchPathResolver.kt ================================================ package org.jetbrains.kotlin.konan.library import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl import org.jetbrains.kotlin.konan.library.impl.createKonanLibraryComponents import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.library.impl.createKotlinLibrary import org.jetbrains.kotlin.util.DummyLogger import org.jetbrains.kotlin.util.Logger interface SearchPathResolverWithTarget: SearchPathResolver { val target: KonanTarget } fun defaultResolver( repositories: List, target: KonanTarget, distribution: Distribution ): SearchPathResolverWithTarget = defaultResolver(repositories, emptyList(), target, distribution) fun defaultResolver( repositories: List, directLibs: List, target: KonanTarget, distribution: Distribution, logger: Logger = DummyLogger, skipCurrentDir: Boolean = false ): SearchPathResolverWithTarget = KonanLibraryProperResolver( repositories, directLibs, target, distribution.klib, distribution.localKonanDir.absolutePath, skipCurrentDir, logger ) fun resolverByName( repositories: List, directLibs: List = emptyList(), distributionKlib: String? = null, localKotlinDir: String? = null, skipCurrentDir: Boolean = false, logger: Logger ): SearchPathResolver = object : KotlinLibrarySearchPathResolver( repositories, directLibs, distributionKlib, localKotlinDir, skipCurrentDir, logger ) { override fun libraryComponentBuilder(file: File, isDefault: Boolean) = createKonanLibraryComponents(file, null, isDefault) } internal class KonanLibraryProperResolver( repositories: List, directLibs: List, override val target: KonanTarget, distributionKlib: String?, localKonanDir: String?, skipCurrentDir: Boolean, override val logger: Logger ) : KotlinLibraryProperResolverWithAttributes( repositories, directLibs, distributionKlib, localKonanDir, skipCurrentDir, logger, listOf(KLIB_INTEROP_IR_PROVIDER_IDENTIFIER) ), SearchPathResolverWithTarget { override fun libraryComponentBuilder(file: File, isDefault: Boolean) = createKonanLibraryComponents(file, target, isDefault) override val distPlatformHead: File? get() = distributionKlib?.File()?.child("platform")?.child(target.visibleName) override fun libraryMatch(candidate: KonanLibrary, unresolved: UnresolvedLibrary): Boolean { val resolverTarget = this.target val candidatePath = candidate.libraryFile.absolutePath if (!candidate.targetList.contains(resolverTarget.visibleName)) { logger.warning("skipping $candidatePath. The target doesn't match. Expected '$resolverTarget', found ${candidate.targetList}") return false } return super.libraryMatch(candidate, unresolved) } } ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/impl/BitcodeWriterImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.konan.library.impl import org.jetbrains.kotlin.konan.library.BitcodeWriter import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.BitcodeKotlinLibraryLayout import org.jetbrains.kotlin.konan.library.TargetedKotlinLibraryLayout open class TargetedWriterImpl(val targetLayout: TargetedKotlinLibraryLayout) { init { targetLayout.targetDir.mkdirs() targetLayout.includedDir.mkdirs() } fun addIncludedBinary(library: String) { val basename = File(library).name File(library).copyTo(File(targetLayout.includedDir, basename)) } } class BitcodeWriterImpl( libraryLayout: BitcodeKotlinLibraryLayout ) : BitcodeWriter, TargetedWriterImpl(libraryLayout) { val bitcodeLayout = libraryLayout init { bitcodeLayout.kotlinDir.mkdirs() bitcodeLayout.nativeDir.mkdirs() } override fun addNativeBitcode(library: String) { val basename = File(library).name File(library).copyTo(File(bitcodeLayout.nativeDir, basename)) } } ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/impl/KonanLibraryImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.library.impl import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.* import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.properties.loadProperties import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions import org.jetbrains.kotlin.konan.util.substitute import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.library.impl.* open class TargetedLibraryImpl( private val access: TargetedLibraryAccess, private val base: BaseKotlinLibrary ) : TargetedLibrary, BaseKotlinLibrary by base { private val target: KonanTarget? get() = access.target override val targetList: List get() = nativeTargets.ifEmpty { // TODO: We have a choice: either assume it is the CURRENT TARGET // or a list of ALL KNOWN targets. listOfNotNull(access.target?.visibleName) } override val manifestProperties: Properties by lazy { val properties = base.manifestProperties target?.let { substitute(properties, defaultTargetSubstitutions(it)) } properties } override val includedPaths: List get() = access.realFiles { it.includedDir.listFilesOrEmpty.map { it.absolutePath } } } open class BitcodeLibraryImpl( private val access: BitcodeLibraryAccess, targeted: TargetedLibrary ) : BitcodeLibrary, TargetedLibrary by targeted { override val bitcodePaths: List get() = access.realFiles { it: BitcodeKotlinLibraryLayout -> (it.kotlinDir.listFilesOrEmpty + it.nativeDir.listFilesOrEmpty).map { it.absolutePath } } } class KonanLibraryImpl( targeted: TargetedLibraryImpl, metadata: MetadataLibraryImpl, ir: IrLibraryImpl, bitcode: BitcodeLibraryImpl ) : KonanLibrary, BaseKotlinLibrary by targeted, MetadataLibrary by metadata, IrLibrary by ir, BitcodeLibrary by bitcode { override val linkerOpts: List get() = manifestProperties.propertyList(KLIB_PROPERTY_LINKED_OPTS, escapeInQuotes = true) } fun createKonanLibrary( libraryFile: File, component: String, target: KonanTarget? = null, isDefault: Boolean = false ): KonanLibrary { val baseAccess = BaseLibraryAccess(libraryFile, component) val targetedAccess = TargetedLibraryAccess(libraryFile, component, target) val metadataAccess = MetadataLibraryAccess(libraryFile, component) val irAccess = IrLibraryAccess(libraryFile, component) val bitcodeAccess = BitcodeLibraryAccess(libraryFile, component, target) val base = BaseKotlinLibraryImpl(baseAccess, isDefault) val targeted = TargetedLibraryImpl(targetedAccess, base) val metadata = MetadataLibraryImpl(metadataAccess) val ir = IrMonoliticLibraryImpl(irAccess) val bitcode = BitcodeLibraryImpl(bitcodeAccess, targeted) return KonanLibraryImpl(targeted, metadata, ir, bitcode) } fun createKonanLibraryComponents( libraryFile: File, target: KonanTarget? = null, isDefault: Boolean = true ) : List { val baseAccess = BaseLibraryAccess(libraryFile, null) val base = BaseKotlinLibraryImpl(baseAccess, isDefault) return base.componentList.map { createKonanLibrary(libraryFile, it, target, isDefault) } } ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/impl/KonanLibraryLayoutImpl.kt ================================================ package org.jetbrains.kotlin.konan.library.impl import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.* import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.library.impl.* import java.nio.file.FileSystem open class TargetedLibraryLayoutImpl(klib: File, component: String, override val target: KonanTarget?) : KotlinLibraryLayoutImpl(klib, component), TargetedKotlinLibraryLayout { override val extractingToTemp: TargetedKotlinLibraryLayout by lazy { ExtractingTargetedLibraryImpl(this) } override fun directlyFromZip(zipFileSystem: FileSystem): TargetedKotlinLibraryLayout = FromZipTargetedLibraryImpl(this, zipFileSystem) } class BitcodeLibraryLayoutImpl(klib: File, component: String, target: KonanTarget?) : TargetedLibraryLayoutImpl(klib, component, target), BitcodeKotlinLibraryLayout { override val extractingToTemp: BitcodeKotlinLibraryLayout by lazy { ExtractingBitcodeLibraryImpl(this) } override fun directlyFromZip(zipFileSystem: FileSystem): BitcodeKotlinLibraryLayout = FromZipBitcodeLibraryImpl(this, zipFileSystem) } open class TargetedLibraryAccess(klib: File, component: String, val target: KonanTarget?) : BaseLibraryAccess(klib, component) { override val layout = TargetedLibraryLayoutImpl(klib, component, target) } open class BitcodeLibraryAccess(klib: File, component: String, target: KonanTarget?) : TargetedLibraryAccess(klib, component, target) { override val layout = BitcodeLibraryLayoutImpl(klib, component, target) } private open class FromZipTargetedLibraryImpl(zipped: TargetedLibraryLayoutImpl, zipFileSystem: FileSystem) : FromZipBaseLibraryImpl(zipped, zipFileSystem), TargetedKotlinLibraryLayout private class FromZipBitcodeLibraryImpl(zipped: BitcodeLibraryLayoutImpl, zipFileSystem: FileSystem) : FromZipTargetedLibraryImpl(zipped, zipFileSystem), BitcodeKotlinLibraryLayout open class ExtractingTargetedLibraryImpl(zipped: TargetedLibraryLayoutImpl) : ExtractingKotlinLibraryLayout(zipped), TargetedKotlinLibraryLayout { override val includedDir: File by lazy { zipped.extractDir(zipped.includedDir) } } class ExtractingBitcodeLibraryImpl(zipped: BitcodeLibraryLayoutImpl) : ExtractingTargetedLibraryImpl(zipped), BitcodeKotlinLibraryLayout { override val kotlinDir: File by lazy { zipped.extractDir(zipped.kotlinDir) } override val nativeDir: File by lazy { zipped.extractDir(zipped.nativeDir) } } ================================================ FILE: shared/src/library/kotlin/org/jetbrains/kotlin/konan/library/impl/KonanLibraryWriterImpl.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.konan.library.impl import org.jetbrains.kotlin.konan.library.BitcodeWriter import org.jetbrains.kotlin.konan.library.KonanLibraryWriter import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.library.KonanLibraryLayout import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.library.impl.* class KonanLibraryLayoutForWriter( libFile: File, unzippedDir: File, override val target: KonanTarget ) : KonanLibraryLayout, KotlinLibraryLayoutForWriter(libFile, unzippedDir) /** * Requires non-null [target]. */ class KonanLibraryWriterImpl( moduleName: String, versions: KotlinLibraryVersioning, target: KonanTarget, builtInsPlatform: BuiltInsPlatform, nopack: Boolean = false, shortName: String? = null, val layout: KonanLibraryLayoutForWriter, base: BaseWriter = BaseWriterImpl(layout, moduleName, versions, builtInsPlatform, listOf(target.visibleName), nopack, shortName), bitcode: BitcodeWriter = BitcodeWriterImpl(layout), metadata: MetadataWriter = MetadataWriterImpl(layout), ir: IrWriter = IrMonoliticWriterImpl(layout) ) : BaseWriter by base, BitcodeWriter by bitcode, MetadataWriter by metadata, IrWriter by ir, KonanLibraryWriter fun buildLibrary( natives: List, included: List, linkDependencies: List, metadata: SerializedMetadata, ir: SerializedIrModule?, versions: KotlinLibraryVersioning, target: KonanTarget, output: String, moduleName: String, nopack: Boolean, shortName: String?, manifestProperties: Properties?, dataFlowGraph: ByteArray? ): KonanLibraryLayout { val libFile = File(output) val unzippedDir = if (nopack) libFile else org.jetbrains.kotlin.konan.file.createTempDir("klib") val layout = KonanLibraryLayoutForWriter(libFile, unzippedDir, target) val library = KonanLibraryWriterImpl( moduleName, versions, target, BuiltInsPlatform.NATIVE, nopack, shortName, layout ) library.addMetadata(metadata) if (ir != null) { library.addIr(ir) } natives.forEach { library.addNativeBitcode(it) } included.forEach { library.addIncludedBinary(it) } manifestProperties?.let { library.addManifestAddend(it) } library.addLinkDependencies(linkDependencies) dataFlowGraph?.let { library.addDataFlowGraph(it) } library.commit() return library.layout } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/Exceptions.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan /** * This is a common ancestor of all Kotlin/Native exceptions. */ open class KonanException(message: String = "", cause: Throwable? = null) : Exception(message, cause) /** * An error occurred during external tool invocation. Such as non-zero exit code. */ class KonanExternalToolFailure(message: String, val toolName: String, cause: Throwable? = null) : KonanException(message, cause) /** * An exception indicating a failed attempt to access some parts of Xcode (e.g. get SDK paths or version). */ class MissingXcodeException(message: String, cause: Throwable? = null) : KonanException(message, cause) /** * Native exception handling in Kotlin: terminate, wrap, etc. * Foreign exceptionMode mode is per library option: controlled by cinterop command-line option or def file property * than stored in klib manifest and used by compiler to generate appropriate handler. */ class ForeignExceptionMode { companion object { val manifestKey = "foreignExceptionMode" val default = Mode.TERMINATE fun byValue(value: String?): Mode = value?.let { Mode.values().find { it.value == value } ?: throw IllegalArgumentException("Illegal ForeignExceptionMode $value") } ?: default } enum class Mode(val value: String) { TERMINATE("terminate"), OBJC_WRAP("objc-wrap") } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/KonanAbiVersion.kt ================================================ /** * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan fun String.parseKonanAbiVersion(): KonanAbiVersion { return KonanAbiVersion(this.toInt()) } data class KonanAbiVersion(val version: Int) { companion object { val CURRENT = KonanAbiVersion(10) } override fun toString() = "$version" } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/TempFiles.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.* /** * Creates and stores temporary compiler outputs * If pathToTemporaryDir is given and is not empty then temporary outputs will be preserved */ class TempFiles(outputPath: String, pathToTemporaryDir: String? = null) { private val outputName = File(outputPath).name val deleteOnExit = pathToTemporaryDir == null || pathToTemporaryDir.isEmpty() val nativeBinaryFile by lazy { create(outputName,".kt.bc") } val cAdapterCpp by lazy { create("api", ".cpp") } val cAdapterBitcode by lazy { create("api", ".bc") } val nativeBinaryFileName get() = nativeBinaryFile.absolutePath val cAdapterCppName get() = cAdapterCpp.absolutePath val cAdapterBitcodeName get() = cAdapterBitcode.absolutePath private val dir by lazy { if (deleteOnExit) { createTempDir("konan_temp").deleteOnExit() } else { createDirForTemporaryFiles(pathToTemporaryDir!!) } } private fun createDirForTemporaryFiles(path: String): File { if (File(path).isFile) { throw IllegalArgumentException("Given file is not a directory: $path") } return File(path).apply { if (!exists) { mkdirs() } } } /** * Create file named {name}{suffix} inside temporary dir */ fun create(prefix: String, suffix: String = ""): File = File(dir, "$prefix$suffix").also { if (deleteOnExit) it.deleteOnExit() } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/exec/ExecuteCommand.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.exec import org.jetbrains.kotlin.konan.KonanExternalToolFailure import java.io.BufferedReader import java.io.InputStreamReader import java.lang.ProcessBuilder.Redirect import java.nio.file.Files open class Command(initialCommand: List) { constructor(tool: String) : this(listOf(tool)) constructor(vararg command: String) : this(command.toList()) protected val command = initialCommand.toMutableList() val argsWithExecutable: List = command val args: List get() = command.drop(1) operator fun String.unaryPlus(): Command { command += this return this@Command } operator fun List.unaryPlus(): Command { command.addAll(this) return this@Command } var logger: ((() -> String)->Unit)? = null private var stdError: List = emptyList() fun logWith(newLogger: ((() -> String)->Unit)): Command { logger = newLogger return this } open fun runProcess(): Int { stdError = emptyList() val builder = ProcessBuilder(command) builder.redirectOutput(Redirect.INHERIT) builder.redirectInput(Redirect.INHERIT) val process = builder.start() val reader = BufferedReader(InputStreamReader(process.errorStream)) stdError = reader.readLines() val exitCode = process.waitFor() return exitCode } open fun execute() { log() val code = runProcess() handleExitCode(code, stdError) } /** * If withErrors is true then output from error stream will be added */ fun getOutputLines(withErrors: Boolean = false): List = getResult(withErrors, handleError = true).outputLines fun getResult(withErrors: Boolean, handleError: Boolean = false): Result { log() val outputFile = Files.createTempFile(null, null).toFile() outputFile.deleteOnExit() try { val builder = ProcessBuilder(command) builder.redirectInput(Redirect.INHERIT) builder.redirectError(Redirect.INHERIT) builder.redirectOutput(Redirect.to(outputFile)) .redirectErrorStream(withErrors) // Note: getting process output could be done without redirecting to temporary file, // however this would require managing a thread to read `process.inputStream` because // it may have limited capacity. val process = builder.start() val code = process.waitFor() if (handleError) handleExitCode(code, outputFile.readLines()) return Result(code, outputFile.readLines()) } finally { outputFile.delete() } } class Result(val exitCode: Int, val outputLines: List) private fun handleExitCode(code: Int, output: List = emptyList()) { if (code != 0) throw KonanExternalToolFailure(""" The ${command[0]} command returned non-zero exit code: $code. output: """.trimIndent() + "\n${output.joinToString("\n")}", command[0]) // Show warnings in case of success linkage. if (stdError.isNotEmpty()) { stdError.joinToString("\n").also { message -> logger?.let { it { message } } ?: println(message) } } } private fun log() { if (logger != null) logger!! { command.joinToString(" ") } } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/file/NativeFileType.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.file val String.isJavaScript get() = this.endsWith(".js") val String.isUnixStaticLib get() = this.endsWith(".a") val String.isWindowsStaticLib get() = this.endsWith(".lib") val String.isBitcode get() = this.endsWith(".bc") ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Apple.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed -> in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.util.InternalServer import kotlin.math.max class AppleConfigurablesImpl( target: KonanTarget, properties: Properties, baseDir: String? ) : AppleConfigurables, KonanPropertiesLoader(target, properties, baseDir) { private val sdkDependency = this.targetSysRoot!! private val toolchainDependency = this.targetToolchain!! private val xcodeAddonDependency = this.additionalToolsDir!! override val absoluteTargetSysRoot: String get() = when (val provider = xcodePartsProvider) { is XcodePartsProvider.Local -> when (target) { KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64 -> provider.xcode.macosxSdk KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64 -> provider.xcode.iphoneosSdk KonanTarget.IOS_X64 -> provider.xcode.iphonesimulatorSdk KonanTarget.TVOS_ARM64 -> provider.xcode.appletvosSdk KonanTarget.TVOS_X64 -> provider.xcode.appletvsimulatorSdk KonanTarget.WATCHOS_ARM64, KonanTarget.WATCHOS_ARM32 -> provider.xcode.watchosSdk KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_X86 -> provider.xcode.watchsimulatorSdk else -> error(target) } XcodePartsProvider.InternalServer -> absolute(sdkDependency) } override val absoluteTargetToolchain: String get() = when (val provider = xcodePartsProvider) { is XcodePartsProvider.Local -> provider.xcode.toolchain XcodePartsProvider.InternalServer -> absolute(toolchainDependency) } override val absoluteAdditionalToolsDir: String get() = when (val provider = xcodePartsProvider) { is XcodePartsProvider.Local -> provider.xcode.additionalTools XcodePartsProvider.InternalServer -> absolute(additionalToolsDir) } override val dependencies get() = super.dependencies + when (xcodePartsProvider) { is XcodePartsProvider.Local -> emptyList() XcodePartsProvider.InternalServer -> listOf(sdkDependency, toolchainDependency, xcodeAddonDependency) } private val xcodePartsProvider by lazy { if (InternalServer.isAvailable) { XcodePartsProvider.InternalServer } else { val xcode = Xcode.current if (properties.getProperty("ignoreXcodeVersionCheck") != "true") { properties.getProperty("minimalXcodeVersion")?.let { minimalXcodeVersion -> val currentXcodeVersion = xcode.version checkXcodeVersion(minimalXcodeVersion, currentXcodeVersion) } } XcodePartsProvider.Local(xcode) } } private fun checkXcodeVersion(minimalVersion: String, currentVersion: String) { // Xcode versions contain only numbers (even betas). // But we still split by '-' and whitespaces to take into account versions like 11.2-beta. val minimalVersionParts = minimalVersion.split("(\\s+|\\.|-)".toRegex()).map { it.toIntOrNull() ?: 0 } val currentVersionParts = currentVersion.split("(\\s+|\\.|-)".toRegex()).map { it.toIntOrNull() ?: 0 } val size = max(minimalVersionParts.size, currentVersionParts.size) for (i in 0 until size) { val currentPart = currentVersionParts.getOrElse(i) { 0 } val minimalPart = minimalVersionParts.getOrElse(i) { 0 } when { currentPart > minimalPart -> return currentPart < minimalPart -> error("Unsupported Xcode version $currentVersion, minimal supported version is $minimalVersion.") } } } private sealed class XcodePartsProvider { class Local(val xcode: Xcode) : XcodePartsProvider() object InternalServer : XcodePartsProvider() } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed -> in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.file.File internal object Android { const val API = "21" private val architectureMap = mapOf( KonanTarget.ANDROID_X86 to "x86", KonanTarget.ANDROID_X64 to "x86_64", KonanTarget.ANDROID_ARM32 to "arm", KonanTarget.ANDROID_ARM64 to "arm64" ) fun architectureDirForTarget(target: KonanTarget) = "android-${API}/arch-${architectureMap.getValue(target)}" } class ClangArgs(private val configurables: Configurables) : Configurables by configurables { private val targetArg = if (configurables is TargetableConfigurables) configurables.targetArg else null private val clangArgsSpecificForKonanSources get() = runtimeDefinitions.map { "-D$it" } private val binDir = when (HostManager.host) { KonanTarget.LINUX_X64 -> "$absoluteTargetToolchain/bin" KonanTarget.MINGW_X64 -> "$absoluteTargetToolchain/bin" KonanTarget.MACOS_X64 -> "$absoluteTargetToolchain/usr/bin" else -> throw TargetSupportException("Unexpected host platform") } // TODO: Use buildList private val commonClangArgs: List = mutableListOf>().apply { add(listOf("-B$binDir", "-fno-stack-protector")) if (configurables is GccConfigurables) { add(listOf("--gcc-toolchain=${configurables.absoluteGccToolchain}")) } if (configurables is TargetableConfigurables) { add(listOf("-target", configurables.targetArg!!)) } val hasCustomSysroot = configurables is ZephyrConfigurables || configurables is WasmConfigurables || configurables is AndroidConfigurables if (!hasCustomSysroot) { when (configurables) { // isysroot and sysroot on darwin are _almost_ synonyms. // The first one parses SDKSettings.json while second one is not. is AppleConfigurables -> add(listOf("-isysroot", absoluteTargetSysRoot)) else -> add(listOf("--sysroot=$absoluteTargetSysRoot")) } } // PIC is not required on Windows (and Clang will fail with `error: unsupported option '-fPIC'`) if (configurables !is MingwConfigurables) { // `-fPIC` allows us to avoid some problems when producing dynamic library. // See KT-43502. add(listOf("-fPIC")) } }.flatten() private val osVersionMin: String get() { require(configurables is AppleConfigurables) return configurables.osVersionMin } private val specificClangArgs: List = when (target) { KonanTarget.LINUX_X64, KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32, KonanTarget.LINUX_ARM64, KonanTarget.MINGW_X64, KonanTarget.MINGW_X86 -> emptyList() KonanTarget.LINUX_ARM32_HFP -> listOf( "-mfpu=vfp", "-mfloat-abi=hard" ) KonanTarget.MACOS_X64 -> listOf( "-mmacosx-version-min=$osVersionMin" ) // Here we workaround Clang 8 limitation: macOS major version should be 10. // So we compile runtime with version 10.16 and then override version in BitcodeCompiler. // TODO: Fix with LLVM Update. KonanTarget.MACOS_ARM64 -> listOf( "-arch", "arm64", "-mmacosx-version-min=10.16" ) KonanTarget.IOS_ARM32 -> listOf( "-stdlib=libc++", "-arch", "armv7", "-miphoneos-version-min=$osVersionMin" ) KonanTarget.IOS_ARM64 -> listOf( "-stdlib=libc++", "-arch", "arm64", "-miphoneos-version-min=$osVersionMin" ) KonanTarget.IOS_X64 -> listOf( "-stdlib=libc++", "-miphoneos-version-min=$osVersionMin" ) KonanTarget.TVOS_ARM64 -> listOf( "-stdlib=libc++", "-arch", "arm64", "-mtvos-version-min=$osVersionMin" ) KonanTarget.TVOS_X64 -> listOf( "-stdlib=libc++", "-mtvos-simulator-version-min=$osVersionMin" ) KonanTarget.WATCHOS_ARM64, KonanTarget.WATCHOS_ARM32 -> listOf( "-stdlib=libc++", "-arch", "armv7k", "-mwatchos-version-min=$osVersionMin" ) KonanTarget.WATCHOS_X86 -> listOf( "-stdlib=libc++", "-arch", "i386", "-mwatchos-simulator-version-min=$osVersionMin" ) KonanTarget.WATCHOS_X64 -> listOf( "-stdlib=libc++", "-mwatchos-simulator-version-min=$osVersionMin" ) KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64, KonanTarget.ANDROID_X86, KonanTarget.ANDROID_X64 -> { val clangTarget = targetArg!! val architectureDir = Android.architectureDirForTarget(target) val toolchainSysroot = "$absoluteTargetToolchain/sysroot" listOf( "-D__ANDROID_API__=${Android.API}", "--sysroot=$absoluteTargetSysRoot/$architectureDir", "-I$toolchainSysroot/usr/include/c++/v1", "-I$toolchainSysroot/usr/include", "-I$toolchainSysroot/usr/include/$clangTarget" ) } // By default WASM target forces `hidden` visibility which causes linkage problems. KonanTarget.WASM32 -> listOf( "-fno-rtti", "-fno-exceptions", "-fvisibility=default", "-D_LIBCPP_ABI_VERSION=2", "-D_LIBCPP_NO_EXCEPTIONS=1", "-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libcxx", "-Xclang", "-isystem$absoluteTargetSysRoot/lib/libcxxabi/include", "-Xclang", "-isystem$absoluteTargetSysRoot/include/compat", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libc" ) is KonanTarget.ZEPHYR -> listOf( "-fno-rtti", "-fno-exceptions", "-fno-asynchronous-unwind-tables", "-fno-pie", "-fno-pic", "-fshort-enums", "-nostdinc", // TODO: make it a libGcc property? // We need to get rid of wasm sysroot first. "-isystem $targetToolchain/../lib/gcc/arm-none-eabi/7.2.1/include", "-isystem $targetToolchain/../lib/gcc/arm-none-eabi/7.2.1/include-fixed", "-isystem$absoluteTargetSysRoot/include/libcxx", "-isystem$absoluteTargetSysRoot/include/libc" ) + (configurables as ZephyrConfigurables).constructClangArgs() } val clangPaths = listOf("$absoluteLlvmHome/bin", binDir) private val jdkDir by lazy { val home = File.javaHome.absoluteFile if (home.child("include").exists) home.absolutePath else home.parentFile.absolutePath } val hostCompilerArgsForJni = listOf("", HostManager.jniHostPlatformIncludeDir).map { "-I$jdkDir/include/$it" }.toTypedArray() val clangArgs = (commonClangArgs + specificClangArgs).toTypedArray() val clangArgsForKonanSources = clangArgs + clangArgsSpecificForKonanSources val targetLibclangArgs: List = // libclang works not exactly the same way as the clang binary and // (in particular) uses different default header search path. // See e.g. http://lists.llvm.org/pipermail/cfe-dev/2013-November/033680.html // We workaround the problem with -isystem flag below. listOf("-isystem", "$absoluteLlvmHome/lib/clang/$llvmVersion/include", *clangArgs) private val targetClangCmd = listOf("${absoluteLlvmHome}/bin/clang") + clangArgs private val targetClangXXCmd = listOf("${absoluteLlvmHome}/bin/clang++") + clangArgs fun clangC(vararg userArgs: String) = targetClangCmd + userArgs.asList() fun clangCXX(vararg userArgs: String) = targetClangXXCmd + userArgs.asList() companion object { @JvmStatic fun filterGradleNativeSoftwareFlags(args: MutableList) { args.remove("/usr/include") // HACK: over gradle-4.4. args.remove("-nostdinc") // HACK: over gradle-5.1. when (HostManager.host) { KonanTarget.LINUX_X64 -> args.remove("/usr/include/x86_64-linux-gnu") // HACK: over gradle-4.4. KonanTarget.MACOS_X64 -> { val indexToRemove = args.indexOf(args.find { it.contains("MacOSX.platform")}) // HACK: over gradle-4.7. if (indexToRemove != -1) { args.removeAt(indexToRemove - 1) // drop -I. args.removeAt(indexToRemove - 1) // drop /Application/Xcode.app/... } } } } } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed -> in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.properties.* interface RelocationModeFlags : TargetableExternalStorage { val dynamicLibraryRelocationMode get() = targetString("dynamicLibraryRelocationMode").mode() val staticLibraryRelocationMode get() = targetString("staticLibraryRelocationMode").mode() val executableRelocationMode get() = targetString("executableRelocationMode").mode() private fun String?.mode(): Mode = when (this?.toLowerCase()) { null -> Mode.DEFAULT "pic" -> Mode.PIC "static" -> Mode.STATIC else -> error("Unknown relocation mode: $this") } enum class Mode { PIC, STATIC, DEFAULT } } interface ClangFlags : TargetableExternalStorage, RelocationModeFlags { val clangFlags get() = targetList("clangFlags") val clangNooptFlags get() = targetList("clangNooptFlags") val clangOptFlags get() = targetList("clangOptFlags") val clangDebugFlags get() = targetList("clangDebugFlags") } interface LldFlags : TargetableExternalStorage { val lldFlags get() = targetList("lld") } interface Configurables : TargetableExternalStorage, RelocationModeFlags { val target: KonanTarget val llvmHome get() = hostString("llvmHome") val llvmVersion get() = hostString("llvmVersion") val libffiDir get() = hostString("libffiDir") val cacheableTargets get() = hostList("cacheableTargets") val additionalCacheFlags get() = targetList("additionalCacheFlags") // TODO: Delegate to a map? val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags") val linkerKonanFlags get() = targetList("linkerKonanFlags") val mimallocLinkerDependencies get() = targetList("mimallocLinkerDependencies") val linkerNoDebugFlags get() = targetList("linkerNoDebugFlags") val linkerDynamicFlags get() = targetList("linkerDynamicFlags") val targetSysRoot get() = targetString("targetSysRoot") // Notice: these ones are host-target. val targetToolchain get() = hostTargetString("targetToolchain") val absoluteTargetSysRoot get() = absolute(targetSysRoot) val absoluteTargetToolchain get() = absolute(targetToolchain) val absoluteLlvmHome get() = absolute(llvmHome) val targetCpu get() = targetString("targetCpu") val targetCpuFeatures get() = targetString("targetCpuFeatures") val llvmInlineThreshold get() = targetString("llvmInlineThreshold") val runtimeDefinitions get() = targetList("runtimeDefinitions") } interface ConfigurablesWithEmulator : Configurables { val emulatorDependency get() = hostTargetString("emulatorDependency") // TODO: We need to find a way to represent absolute path in properties. // In case of QEMU, absolute path to dynamic linker should be specified. val emulatorExecutable get() = hostTargetString("emulatorExecutable") val absoluteEmulatorExecutable get() = absolute(emulatorExecutable) } interface TargetableConfigurables : Configurables { val targetArg get() = targetString("quadruple") } interface AppleConfigurables : Configurables, ClangFlags { val arch get() = targetString("arch")!! val osVersionMin get() = targetString("osVersionMin")!! val osVersionMinFlagLd get() = targetString("osVersionMinFlagLd")!! val stripFlags get() = targetList("stripFlags") val additionalToolsDir get() = hostString("additionalToolsDir") val absoluteAdditionalToolsDir get() = absolute(additionalToolsDir) } interface MingwConfigurables : TargetableConfigurables, ClangFlags interface GccConfigurables : TargetableConfigurables, ClangFlags { val gccToolchain get() = targetString("gccToolchain") val absoluteGccToolchain get() = absolute(gccToolchain) val libGcc get() = targetString("libGcc")!! val dynamicLinker get() = targetString("dynamicLinker")!! val abiSpecificLibraries get() = targetList("abiSpecificLibraries") val crtFilesLocation get() = targetString("crtFilesLocation")!! val linker get() = hostTargetString("linker") val linkerHostSpecificFlags get() = hostTargetList("linkerHostSpecificFlags") val absoluteLinker get() = absolute(linker) val linkerGccFlags get() = targetList("linkerGccFlags") } interface AndroidConfigurables : TargetableConfigurables, ClangFlags interface WasmConfigurables : TargetableConfigurables, ClangFlags, LldFlags interface ZephyrConfigurables : TargetableConfigurables, ClangFlags { val boardSpecificClangFlags get() = targetList("boardSpecificClangFlags") val targetAbi get() = targetString("targetAbi") } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ConfigurablesExtensions.kt ================================================ package org.jetbrains.kotlin.konan.target fun ZephyrConfigurables.constructClangArgs(): List = mutableListOf().apply { targetCpu?.let { add("-mcpu=$it") } targetAbi?.let { add("-mabi=$it") } addAll(boardSpecificClangFlags) } fun ZephyrConfigurables.constructClangCC1Args(): List = mutableListOf().apply { addAll("-cc1 -emit-obj -disable-llvm-optzns -x ir -fdata-sections -ffunction-sections".split(" ")) targetCpu?.let { addAll(listOf("-target-abi", it)) } targetAbi?.let { addAll(listOf("-target-cpu", it)) } addAll(boardSpecificClangFlags) } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ConfigurablesImpl.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed -> in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.properties.* class GccConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?) : GccConfigurables, KonanPropertiesLoader(target, properties, baseDir), ConfigurablesWithEmulator { override val dependencies: List get() = super.dependencies + listOfNotNull(emulatorDependency) } class AndroidConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?) : AndroidConfigurables, KonanPropertiesLoader(target, properties, baseDir) class MingwConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?) : MingwConfigurables, KonanPropertiesLoader(target, properties, baseDir) class WasmConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?) : WasmConfigurables, KonanPropertiesLoader(target, properties, baseDir) class ZephyrConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?) : ZephyrConfigurables, KonanPropertiesLoader(target, properties, baseDir) fun loadConfigurables(target: KonanTarget, properties: Properties, baseDir: String?): Configurables = when (target) { KonanTarget.LINUX_X64, KonanTarget.LINUX_ARM32_HFP, KonanTarget.LINUX_ARM64, KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 -> GccConfigurablesImpl(target, properties, baseDir) KonanTarget.MACOS_X64, KonanTarget.MACOS_ARM64, KonanTarget.IOS_ARM32, KonanTarget.IOS_ARM64, KonanTarget.IOS_X64, KonanTarget.TVOS_ARM64, KonanTarget.TVOS_X64, KonanTarget.WATCHOS_ARM64, KonanTarget.WATCHOS_ARM32, KonanTarget.WATCHOS_X64, KonanTarget.WATCHOS_X86 -> AppleConfigurablesImpl(target, properties, baseDir) KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64, KonanTarget.ANDROID_X86, KonanTarget.ANDROID_X64 -> AndroidConfigurablesImpl(target, properties, baseDir) KonanTarget.MINGW_X64, KonanTarget.MINGW_X86 -> MingwConfigurablesImpl(target, properties, baseDir) KonanTarget.WASM32 -> WasmConfigurablesImpl(target, properties, baseDir) is KonanTarget.ZEPHYR -> ZephyrConfigurablesImpl(target, properties, baseDir) } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanProperties.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed -> in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.properties import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.Configurables import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.util.ArchiveType import org.jetbrains.kotlin.konan.util.DependencyProcessor import java.io.File interface TargetableExternalStorage { fun targetString(key: String): String? fun targetList(key: String): List fun hostString(key: String): String? fun hostList(key: String): List fun hostTargetString(key: String): String? fun hostTargetList(key: String): List fun absolute(value: String?): String fun downloadDependencies() } abstract class KonanPropertiesLoader(override val target: KonanTarget, val properties: Properties, private val baseDir: String? = null, private val host: KonanTarget = HostManager.host) : Configurables { private val predefinedLlvmDistributions: Set = properties.propertyList("predefinedLlvmDistributions").toSet() private fun llvmDependencies(): List { // Store into variable to avoid repeated resolve. val llvmHome = llvmHome ?: error("Undefined LLVM home!") return when (llvmHome) { in predefinedLlvmDistributions -> llvmHome else -> null }.let(::listOfNotNull) } open val dependencies: List get() = hostTargetList("dependencies") + llvmDependencies() override fun downloadDependencies() { dependencyProcessor!!.run() } // TODO: We may want to add caching to avoid repeated resolve. override fun targetString(key: String): String? = properties.targetString(key, target) override fun targetList(key: String): List = properties.targetList(key, target) override fun hostString(key: String): String? = properties.hostString(key, host) override fun hostList(key: String): List = properties.hostList(key, host) override fun hostTargetString(key: String): String? = properties.hostTargetString(key, target, host) override fun hostTargetList(key: String): List = properties.hostTargetList(key, target, host) override fun absolute(value: String?): String = dependencyProcessor!!.resolve(value!!).absolutePath private val dependencyProcessor by lazy { baseDir?.let { DependencyProcessor( dependenciesRoot = File(baseDir), properties = this, archiveType = defaultArchiveTypeByHost(host) ) } } } private fun defaultArchiveTypeByHost(host: KonanTarget): ArchiveType = when (host) { KonanTarget.LINUX_X64 -> ArchiveType.TAR_GZ KonanTarget.MACOS_X64 -> ArchiveType.TAR_GZ KonanTarget.MINGW_X64 -> ArchiveType.ZIP else -> error("$host can't be a host platform!") } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTargetExtenstions.kt ================================================ package org.jetbrains.kotlin.konan.target // TODO: This all needs to go to konan.properties fun KonanTarget.supportsCodeCoverage(): Boolean = this == KonanTarget.MINGW_X64 || this == KonanTarget.LINUX_X64 || this == KonanTarget.MACOS_X64 || this == KonanTarget.IOS_X64 fun KonanTarget.supportsMimallocAllocator(): Boolean = when(this) { is KonanTarget.LINUX_X64 -> true is KonanTarget.MINGW_X86 -> true is KonanTarget.MINGW_X64 -> true is KonanTarget.MACOS_X64 -> true is KonanTarget.LINUX_ARM64 -> true is KonanTarget.LINUX_ARM32_HFP -> true is KonanTarget.ANDROID_X64 -> true is KonanTarget.ANDROID_ARM64 -> true is KonanTarget.IOS_ARM32 -> true is KonanTarget.IOS_ARM64 -> true is KonanTarget.IOS_X64 -> true else -> false // watchOS/tvOS/android_x86/android_arm32 aren't tested; linux_mips32/linux_mipsel32 need linking with libatomic. } fun KonanTarget.supportsThreads(): Boolean = when(this) { is KonanTarget.WASM32 -> false is KonanTarget.ZEPHYR -> false else -> true } fun KonanTarget.supportedSanitizers(): List = when(this) { is KonanTarget.LINUX_X64 -> listOf(SanitizerKind.ADDRESS) is KonanTarget.MACOS_X64 -> listOf(SanitizerKind.THREAD) // TODO: Enable ASAN on macOS. Currently there's an incompatibility between clang frontend version and clang_rt.asan version. // TODO: Enable TSAN on linux. Currently there's a link error between clang_rt.tsan and libstdc++. // TODO: Consider supporting mingw. // TODO: Support macOS arm64 else -> listOf() } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import java.lang.ProcessBuilder import java.lang.ProcessBuilder.Redirect import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.* typealias ObjectFile = String typealias ExecutableFile = String enum class LinkerOutputKind { DYNAMIC_LIBRARY, STATIC_LIBRARY, EXECUTABLE } // Here we take somewhat unexpected approach - we create the thin // library, and then repack it during post-link phase. // This way we ensure .a inputs are properly processed. private fun staticGnuArCommands(ar: String, executable: ExecutableFile, objectFiles: List, libraries: List) = when { HostManager.hostIsMingw -> { val temp = executable.replace('/', '\\') + "__" val arWindows = ar.replace('/', '\\') listOf( Command(arWindows, "-rucT", temp).apply { +objectFiles +libraries }, Command("cmd", "/c").apply { +"(echo create $executable & echo addlib ${temp} & echo save & echo end) | $arWindows -M" }, Command("cmd", "/c", "del", "/q", temp)) } HostManager.hostIsLinux || HostManager.hostIsMac -> listOf( Command(ar, "cqT", executable).apply { +objectFiles +libraries }, Command("/bin/sh", "-c").apply { +"printf 'create $executable\\naddlib $executable\\nsave\\nend' | $ar -M" }) else -> TODO("Unsupported host ${HostManager.host}") } // Use "clang -v -save-temps" to write linkCommand() method // for another implementation of this class. abstract class LinkerFlags(val configurables: Configurables) { protected val llvmBin = "${configurables.absoluteLlvmHome}/bin" protected val llvmLib = "${configurables.absoluteLlvmHome}/lib" open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor. /** * Returns list of commands that produces final linker output. */ // TODO: Number of arguments is quite big. Better to pass args via object. abstract fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind? = null): List /** * Returns list of commands that link object files into a single one. * Pre-linkage is useful for hiding dependency symbols. */ open fun preLinkCommands(objectFiles: List, output: ObjectFile): List = error("Pre-link is unsupported for ${configurables.target}.") abstract fun filterStaticLibraries(binaries: List): List open fun linkStaticLibraries(binaries: List): List { val libraries = filterStaticLibraries(binaries) // Let's just pass them as absolute paths. return libraries } protected open fun provideCompilerRtLibrary(libraryName: String, isDynamic: Boolean = false): String? { System.err.println("Can't provide $libraryName.") return null } // Code coverage requires this library. protected val profileLibrary: String? by lazy { provideCompilerRtLibrary("profile") } } class AndroidLinker(targetProperties: AndroidConfigurables) : LinkerFlags(targetProperties), AndroidConfigurables by targetProperties { private val clangQuad = when (targetProperties.targetArg) { "arm-linux-androideabi" -> "armv7a-linux-androideabi" else -> targetProperties.targetArg } private val prefix = "$absoluteTargetToolchain/bin/${clangQuad}${Android.API}" private val clang = if (HostManager.hostIsMingw) "$prefix-clang.cmd" else "$prefix-clang" private val ar = "$absoluteTargetToolchain/${targetProperties.targetArg}/bin/ar" override val useCompilerDriverAsLinker: Boolean get() = true override fun filterStaticLibraries(binaries: List) = binaries.filter { it.isUnixStaticLib } override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { require(sanitizer == null) { "Sanitizers are unsupported" } if (kind == LinkerOutputKind.STATIC_LIBRARY) return staticGnuArCommands(ar, executable, objectFiles, libraries) val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY val toolchainSysroot = "${absoluteTargetToolchain}/sysroot" val architectureDir = Android.architectureDirForTarget(target) val apiSysroot = "$absoluteTargetSysRoot/$architectureDir" val clangTarget = targetArg!! val libDirs = listOf( "--sysroot=$apiSysroot", if (target == KonanTarget.ANDROID_X64) "-L$apiSysroot/usr/lib64" else "-L$apiSysroot/usr/lib", "-L$toolchainSysroot/usr/lib/$clangTarget/${Android.API}", "-L$toolchainSysroot/usr/lib/$clangTarget") return listOf(Command(clang).apply { +"-o" +executable +"-fPIC" +"-shared" +"-target" +targetArg!! +libDirs +objectFiles if (optimize) +linkerOptimizationFlags if (!debug) +linkerNoDebugFlags if (dynamic) +linkerDynamicFlags if (dynamic) +"-Wl,-soname,${File(executable).name}" +linkerKonanFlags if (mimallocEnabled) +mimallocLinkerDependencies +libraries +linkerArgs }) } } class MacOSBasedLinker(targetProperties: AppleConfigurables) : LinkerFlags(targetProperties), AppleConfigurables by targetProperties { private val libtool = "$absoluteTargetToolchain/usr/bin/libtool" private val linker = "$absoluteTargetToolchain/usr/bin/ld" private val strip = "$absoluteTargetToolchain/usr/bin/strip" private val dsymutil = "$absoluteTargetToolchain/usr/bin/dsymutil" private val KonanTarget.isSimulator: Boolean get() = this == KonanTarget.TVOS_X64 || this == KonanTarget.IOS_X64 || this == KonanTarget.WATCHOS_X86 || this == KonanTarget.WATCHOS_X64 private val compilerRtDir: String? by lazy { val dir = File("$absoluteTargetToolchain/usr/lib/clang/").listFiles.firstOrNull()?.absolutePath if (dir != null) "$dir/lib/darwin/" else null } override fun provideCompilerRtLibrary(libraryName: String, isDynamic: Boolean): String? { val prefix = when (target.family) { Family.IOS -> "ios" Family.WATCHOS -> "watchos" Family.TVOS -> "tvos" Family.OSX -> "osx" else -> error("Target $target is unsupported") } val suffix = if (libraryName.isNotEmpty() && target.isSimulator) { "sim" } else { "" } val dir = compilerRtDir val mangledLibraryName = if (libraryName.isEmpty()) "" else "${libraryName}_" val extension = if (isDynamic) "_dynamic.dylib" else ".a" return if (dir != null) "$dir/libclang_rt.$mangledLibraryName$prefix$suffix$extension" else null } private val osVersionMinFlags: List by lazy { listOf(osVersionMinFlagLd, osVersionMin + ".0") } override fun filterStaticLibraries(binaries: List) = binaries.filter { it.isUnixStaticLib } // Note that may break in case of 32-bit Mach-O. See KT-37368. override fun preLinkCommands(objectFiles: List, output: ObjectFile): List = Command(linker).apply { +"-r" +listOf("-arch", arch) +listOf("-syslibroot", absoluteTargetSysRoot) +objectFiles +listOf("-o", output) }.let(::listOf) override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { if (kind == LinkerOutputKind.STATIC_LIBRARY) { require(sanitizer == null) { "Sanitizers are unsupported" } return listOf(Command(libtool).apply { +"-static" +listOf("-o", executable) +objectFiles +libraries }) } val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY val result = mutableListOf() result += Command(linker).apply { +"-demangle" +listOf("-dynamic", "-arch", arch) +osVersionMinFlags +listOf("-syslibroot", absoluteTargetSysRoot, "-o", executable) +objectFiles if (optimize) +linkerOptimizationFlags if (!debug) +linkerNoDebugFlags if (dynamic) +linkerDynamicFlags +linkerKonanFlags if (mimallocEnabled) +mimallocLinkerDependencies if (compilerRtLibrary != null) +compilerRtLibrary!! if (needsProfileLibrary) +profileLibrary!! +libraries +linkerArgs +rpath(dynamic, sanitizer) when (sanitizer) { null -> {} SanitizerKind.ADDRESS -> +provideCompilerRtLibrary("asan", isDynamic=true)!! SanitizerKind.THREAD -> +provideCompilerRtLibrary("tsan", isDynamic=true)!! } } // TODO: revise debug information handling. if (debug) { result += dsymUtilCommand(executable, outputDsymBundle) if (optimize) { result += Command(strip, *stripFlags.toTypedArray(), executable) } } return result } private val compilerRtLibrary: String? by lazy { provideCompilerRtLibrary("") } private fun rpath(dynamic: Boolean, sanitizer: SanitizerKind?): List = listOfNotNull( when (target.family) { Family.OSX -> "@executable_path/../Frameworks" Family.IOS, Family.WATCHOS, Family.TVOS -> "@executable_path/Frameworks" else -> error(target) }, "@loader_path/Frameworks".takeIf { dynamic }, compilerRtDir.takeIf { sanitizer != null }, ).flatMap { listOf("-rpath", it) } fun dsymUtilCommand(executable: ExecutableFile, outputDsymBundle: String) = object : Command(dsymutilCommand(executable, outputDsymBundle)) { override fun runProcess(): Int = executeCommandWithFilter(command) } // TODO: consider introducing a better filtering directly in Command. private fun executeCommandWithFilter(command: List): Int { val builder = ProcessBuilder(command) // Inherit main process output streams. val isDsymUtil = (command[0] == dsymutil) builder.redirectOutput(Redirect.INHERIT) builder.redirectInput(Redirect.INHERIT) if (!isDsymUtil) builder.redirectError(Redirect.INHERIT) val process = builder.start() if (isDsymUtil) { /** * llvm-lto has option -alias that lets tool to know which symbol we use instead of _main, * llvm-dsym doesn't have such a option, so we ignore annoying warning manually. */ val errorStream = process.errorStream val outputStream = bufferedReader(errorStream) while (true) { val line = outputStream.readLine() ?: break if (!line.contains("warning: could not find object file symbol for symbol _main")) System.err.println(line) } outputStream.close() } val exitCode = process.waitFor() return exitCode } fun dsymutilCommand(executable: ExecutableFile, outputDsymBundle: String): List = listOf(dsymutil, executable, "-o", outputDsymBundle) fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List = listOf(dsymutil, "-dump-debug-map", executable) } class GccBasedLinker(targetProperties: GccConfigurables) : LinkerFlags(targetProperties), GccConfigurables by targetProperties { private val ar = if (HostManager.hostIsMac) "$absoluteTargetToolchain/bin/llvm-ar" else "$absoluteTargetToolchain/bin/ar" override val libGcc = "$absoluteTargetSysRoot/${super.libGcc}" private val specificLibs = abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" } override fun provideCompilerRtLibrary(libraryName: String, isDynamic: Boolean): String? { require(!isDynamic) { "Dynamic compiler rt librares are unsupported" } val targetSuffix = when (target) { KonanTarget.LINUX_X64 -> "x86_64" else -> error("$target is not supported.") } val dir = File("$absoluteLlvmHome/lib/clang/").listFiles.firstOrNull()?.absolutePath return if (dir != null) "$dir/lib/linux/libclang_rt.$libraryName-$targetSuffix.a" else null } override fun filterStaticLibraries(binaries: List) = binaries.filter { it.isUnixStaticLib } override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { if (kind == LinkerOutputKind.STATIC_LIBRARY) { require(sanitizer == null) { "Sanitizers are unsupported" } return staticGnuArCommands(ar, executable, objectFiles, libraries) } val isMips = target == KonanTarget.LINUX_MIPS32 || target == KonanTarget.LINUX_MIPSEL32 val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY val crtPrefix = "$absoluteTargetSysRoot/$crtFilesLocation" // TODO: Can we extract more to the konan.configurables? return listOf(Command(absoluteLinker).apply { +"--sysroot=${absoluteTargetSysRoot}" +"-export-dynamic" +"-z" +"relro" +"--build-id" +"--eh-frame-hdr" +"-dynamic-linker" +dynamicLinker linkerHostSpecificFlags.forEach { +it } +"-o" +executable if (!dynamic) +"$crtPrefix/crt1.o" +"$crtPrefix/crti.o" +if (dynamic) "$libGcc/crtbeginS.o" else "$libGcc/crtbegin.o" +"-L$libGcc" if (!isMips) +"--hash-style=gnu" // MIPS doesn't support hash-style=gnu +specificLibs if (optimize) +linkerOptimizationFlags if (!debug) +linkerNoDebugFlags if (dynamic) +linkerDynamicFlags +objectFiles +libraries +linkerArgs if (mimallocEnabled) +mimallocLinkerDependencies // See explanation about `-u__llvm_profile_runtime` here: // https://github.com/llvm/llvm-project/blob/21e270a479a24738d641e641115bce6af6ed360a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp#L930 if (needsProfileLibrary) +listOf("-u__llvm_profile_runtime", profileLibrary!!) +linkerKonanFlags +linkerGccFlags +if (dynamic) "$libGcc/crtendS.o" else "$libGcc/crtend.o" +"$crtPrefix/crtn.o" when (sanitizer) { null -> {} SanitizerKind.ADDRESS -> { +"-lrt" +provideCompilerRtLibrary("asan")!! +provideCompilerRtLibrary("asan_cxx")!! } SanitizerKind.THREAD -> { +"-lrt" +provideCompilerRtLibrary("tsan")!! +provideCompilerRtLibrary("tsan_cxx")!! } } }) } } class MingwLinker(targetProperties: MingwConfigurables) : LinkerFlags(targetProperties), MingwConfigurables by targetProperties { private val ar = "$absoluteTargetToolchain/bin/ar" private val linker = "$absoluteTargetToolchain/bin/clang++" override val useCompilerDriverAsLinker: Boolean get() = true override fun filterStaticLibraries(binaries: List) = binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib } override fun provideCompilerRtLibrary(libraryName: String, isDynamic: Boolean): String? { require(!isDynamic) { "Dynamic compiler rt librares are unsupported" } val targetSuffix = when (target) { KonanTarget.MINGW_X64 -> "x86_64" else -> error("$target is not supported.") } val dir = File("$absoluteLlvmHome/lib/clang/").listFiles.firstOrNull()?.absolutePath return if (dir != null) "$dir/lib/windows/libclang_rt.$libraryName-$targetSuffix.a" else null } override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { require(sanitizer == null) { "Sanitizers are unsupported" } if (kind == LinkerOutputKind.STATIC_LIBRARY) return staticGnuArCommands(ar, executable, objectFiles, libraries) val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY return listOf(when { HostManager.hostIsMingw -> Command(linker) else -> Command("wine64", "$linker.exe") }.apply { +listOf("-o", executable) +objectFiles // --gc-sections flag may affect profiling. // See https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#drawbacks-and-limitations. // TODO: switching to lld may help. if (optimize && !needsProfileLibrary) +linkerOptimizationFlags if (!debug) +linkerNoDebugFlags if (dynamic) +linkerDynamicFlags +libraries if (needsProfileLibrary) +profileLibrary!! +linkerArgs +linkerKonanFlags if (mimallocEnabled) +mimallocLinkerDependencies }) } } class WasmLinker(targetProperties: WasmConfigurables) : LinkerFlags(targetProperties), WasmConfigurables by targetProperties { override val useCompilerDriverAsLinker: Boolean get() = false override fun filterStaticLibraries(binaries: List) = binaries.filter { it.isJavaScript } override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind") require(sanitizer == null) { "Sanitizers are unsupported" } val linkage = Command("$llvmBin/wasm-ld").apply { +objectFiles +listOf("-o", executable) +lldFlags } // TODO(horsh): maybe rethink it. val jsBindingsGeneration = object : Command() { override fun execute() { javaScriptLink(libraries, executable) } private fun javaScriptLink(jsFiles: List, executable: String): String { val linkedJavaScript = File("$executable.js") val linkerHeader = "var konan = { libraries: [] };\n" val linkerFooter = """|if (isBrowser()) { | konan.moduleEntry([]); |} else { | konan.moduleEntry(arguments); |}""".trimMargin() linkedJavaScript.writeText(linkerHeader) jsFiles.forEach { linkedJavaScript.appendBytes(File(it).readBytes()) } linkedJavaScript.appendBytes(linkerFooter.toByteArray()) return linkedJavaScript.name } } return listOf(linkage, jsBindingsGeneration) } } open class ZephyrLinker(targetProperties: ZephyrConfigurables) : LinkerFlags(targetProperties), ZephyrConfigurables by targetProperties { private val linker = "$absoluteTargetToolchain/bin/ld" override val useCompilerDriverAsLinker: Boolean get() = false override fun filterStaticLibraries(binaries: List) = emptyList() override fun finalLinkCommands(objectFiles: List, executable: ExecutableFile, libraries: List, linkerArgs: List, optimize: Boolean, debug: Boolean, kind: LinkerOutputKind, outputDsymBundle: String, needsProfileLibrary: Boolean, mimallocEnabled: Boolean, sanitizer: SanitizerKind?): List { if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind: $kind") require(sanitizer == null) { "Sanitizers are unsupported" } return listOf(Command(linker).apply { +listOf("-r", "--gc-sections", "--entry", "main") +listOf("-o", executable) +objectFiles +libraries +linkerArgs }) } } fun linker(configurables: Configurables): LinkerFlags = when (configurables) { is GccConfigurables -> GccBasedLinker(configurables) is AppleConfigurables -> MacOSBasedLinker(configurables) is AndroidConfigurables-> AndroidLinker(configurables) is MingwConfigurables -> MingwLinker(configurables) is WasmConfigurables -> WasmLinker(configurables) is ZephyrConfigurables -> ZephyrLinker(configurables) else -> error("Unexpected target: ${configurables.target}") } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Platform.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.util.DependencyProcessor class Platform(val configurables: Configurables) : Configurables by configurables { val clang by lazy { ClangArgs(configurables) } val linker by lazy { linker(configurables) } } class PlatformManager(private val distribution: Distribution, experimental: Boolean = false) : HostManager(distribution, experimental) { constructor(konanHome: String, experimental: Boolean = false): this(Distribution(konanHome), experimental) private val loaders = enabled.map { it to loadConfigurables(it, distribution.properties, DependencyProcessor.defaultDependenciesRoot.absolutePath) }.toMap() private val platforms = loaders.map { it.key to Platform(it.value) }.toMap() fun platform(target: KonanTarget) = platforms.getValue(target) val hostPlatform = platforms.getValue(host) fun loader(target: KonanTarget) = loaders.getValue(target) } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Sanitizer.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.konan.target enum class SanitizerKind { ADDRESS, THREAD, } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetProperties.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.properties import org.jetbrains.kotlin.konan.target.* fun Properties.hostString(name: String, host: KonanTarget): String? = this.resolvablePropertyString(name, host.name) fun Properties.hostList(name: String, host: KonanTarget): List = this.resolvablePropertyList(name, host.name) fun Properties.targetString(name: String, target: KonanTarget): String? = this.resolvablePropertyString(name, target.name) fun Properties.targetList(name: String, target: KonanTarget): List = this.resolvablePropertyList(name, target.name) fun Properties.hostTargetString(name: String, target: KonanTarget, host: KonanTarget): String? = this.resolvablePropertyString(name, hostTargetSuffix(host, target)) fun Properties.hostTargetList(name: String, target: KonanTarget, host: KonanTarget): List = this.resolvablePropertyList(name, hostTargetSuffix(host, target)) ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Xcode.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.KonanExternalToolFailure import org.jetbrains.kotlin.konan.MissingXcodeException import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.file.File interface Xcode { val toolchain: String val macosxSdk: String val iphoneosSdk: String val iphonesimulatorSdk: String val version: String val appletvosSdk: String val appletvsimulatorSdk: String val watchosSdk: String val watchsimulatorSdk: String // Xcode.app/Contents/Developer/usr val additionalTools: String val simulatorRuntimes: String companion object { val current: Xcode by lazy { CurrentXcode } } } private object CurrentXcode : Xcode { override val toolchain by lazy { val ldPath = xcrun("-f", "ld") // = $toolchain/usr/bin/ld File(ldPath).parentFile.parentFile.parentFile.absolutePath } override val additionalTools: String by lazy { val bitcodeBuildToolPath = xcrun("-f", "bitcode-build-tool") File(bitcodeBuildToolPath).parentFile.parentFile.absolutePath } override val simulatorRuntimes: String by lazy { Command("/usr/bin/xcrun", "simctl", "list", "runtimes", "-j").getOutputLines().joinToString(separator = "\n") } override val macosxSdk by lazy { getSdkPath("macosx") } override val iphoneosSdk by lazy { getSdkPath("iphoneos") } override val iphonesimulatorSdk by lazy { getSdkPath("iphonesimulator") } override val appletvosSdk by lazy { getSdkPath("appletvos") } override val appletvsimulatorSdk by lazy { getSdkPath("appletvsimulator") } override val watchosSdk: String by lazy { getSdkPath("watchos") } override val watchsimulatorSdk: String by lazy { getSdkPath("watchsimulator") } override val version by lazy { xcrun("xcodebuild", "-version") .removePrefix("Xcode ") } private fun xcrun(vararg args: String): String = try { Command("/usr/bin/xcrun", *args).getOutputLines().first() } catch(e: KonanExternalToolFailure) { throw MissingXcodeException("An error occurred during an xcrun execution. Make sure that Xcode and its command line tools are properly installed.", e) } private fun getSdkPath(sdk: String) = xcrun("--sdk", sdk, "--show-sdk-path") } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DefFile.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.util import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs import java.io.File import java.io.StringReader import java.util.* class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProperties:Properties, val defHeaderLines:List) { private constructor(file0:File?, triple: Triple>): this(file0, DefFileConfig(triple.first), triple.second, triple.third) constructor(file:File?, substitutions: Map) : this(file, parseDefFile(file, substitutions)) val name by lazy { file?.nameWithoutExtension ?: "" } class DefFileConfig(private val properties: Properties) { val headers by lazy { properties.getSpaceSeparated("headers") } val modules by lazy { properties.getSpaceSeparated("modules") } val language by lazy { properties.getProperty("language") } val compilerOpts by lazy { properties.getSpaceSeparated("compilerOpts") } val excludeSystemLibs by lazy { properties.getProperty("excludeSystemLibs")?.toBoolean() ?: false } val excludeDependentModules by lazy { properties.getProperty("excludeDependentModules")?.toBoolean() ?: false } val entryPoints by lazy { properties.getSpaceSeparated("entryPoint") } val linkerOpts by lazy { properties.getSpaceSeparated("linkerOpts") } val linker by lazy { properties.getProperty("linker", "clang") } val excludedFunctions by lazy { properties.getSpaceSeparated("excludedFunctions") } val excludedMacros by lazy { properties.getSpaceSeparated("excludedMacros") } val staticLibraries by lazy { properties.getSpaceSeparated("staticLibraries") } val libraryPaths by lazy { properties.getSpaceSeparated("libraryPaths") } val packageName by lazy { properties.getProperty("package") } val headerFilter by lazy { properties.getSpaceSeparated("headerFilter") } val strictEnums by lazy { properties.getSpaceSeparated("strictEnums") } val nonStrictEnums by lazy { properties.getSpaceSeparated("nonStrictEnums") } val noStringConversion by lazy { properties.getSpaceSeparated("noStringConversion") } val depends by lazy { properties.getSpaceSeparated("depends") } val exportForwardDeclarations by lazy { properties.getSpaceSeparated("exportForwardDeclarations") } val disableDesignatedInitializerChecks by lazy { properties.getProperty("disableDesignatedInitializerChecks")?.toBoolean() ?: false } val foreignExceptionMode by lazy { properties.getProperty("foreignExceptionMode") } } } private fun Properties.getSpaceSeparated(name: String): List = this.getProperty(name)?.let { parseSpaceSeparatedArgs(it) } ?: emptyList() private fun parseDefFile(file: File?, substitutions: Map): Triple> { val properties = Properties() if (file == null) { return Triple(properties, Properties(), emptyList()) } val lines = file.readLines() val separator = "---" val separatorIndex = lines.indexOf(separator) val propertyLines: List val headerLines: List if (separatorIndex != -1) { propertyLines = lines.subList(0, separatorIndex) headerLines = lines.subList(separatorIndex + 1, lines.size) } else { propertyLines = lines headerLines = emptyList() } // \ isn't escaping character in quotes, so replace them with \\. val joinedLines = propertyLines.joinToString(System.lineSeparator()) val escapedTokens = joinedLines.split('"') val postprocessProperties = escapedTokens.mapIndexed { index, token -> if (index % 2 != 0) { token.replace("""\\(?=.)""".toRegex(), Regex.escapeReplacement("""\\""")) } else { token } }.joinToString("\"") val propertiesReader = StringReader(postprocessProperties) properties.load(propertiesReader) // Pass unsubstituted copy of properties we have obtained from `.def` // to compiler `-manifest`. val manifestAddendProperties = properties.duplicate() substitute(properties, substitutions) return Triple(properties, manifestAddendProperties, headerLines) } private fun Properties.duplicate() = Properties().apply { putAll(this@duplicate) } fun DefFile(file: File?, target: KonanTarget) = DefFile(file, defaultTargetSubstitutions(target)) ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DependencyDownloader.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.util import java.io.* import java.net.HttpURLConnection import java.net.URL import java.net.URLConnection import java.nio.file.Files import java.nio.file.StandardCopyOption import java.util.concurrent.* typealias ProgressCallback = (url: String, currentBytes: Long, totalBytes: Long) -> Unit class DependencyDownloader( var maxAttempts: Int = DEFAULT_MAX_ATTEMPTS, var attemptIntervalMs: Long = DEFAULT_ATTEMPT_INTERVAL_MS, customProgressCallback: ProgressCallback? = null ) { private val progressCallback = customProgressCallback ?: { url, currentBytes, totalBytes -> print("\rDownloading dependency: $url (${currentBytes.humanReadable}/${totalBytes.humanReadable}). ") } val executor = ExecutorCompletionService(Executors.newSingleThreadExecutor(object : ThreadFactory { override fun newThread(r: Runnable?): Thread { val thread = Thread(r) thread.name = "konan-dependency-downloader" thread.isDaemon = true return thread } })) enum class ReplacingMode { /** Redownload the file and replace the existing one. */ REPLACE, /** Throw FileAlreadyExistsException */ THROW, /** Don't download the file and return the existing one*/ RETURN_EXISTING } class HTTPResponseException(val url: URL, val responseCode: Int) : IOException("Server returned HTTP response code: $responseCode for URL: $url") class DownloadingProgress(@Volatile var currentBytes: Long) { fun update(readBytes: Int) { currentBytes += readBytes } } private fun HttpURLConnection.checkHTTPResponse(expected: Int, originalUrl: URL = url) { if (responseCode != expected) { throw HTTPResponseException(originalUrl, responseCode) } } private fun HttpURLConnection.checkHTTPResponse(originalUrl: URL, predicate: (Int) -> Boolean) { if (!predicate(responseCode)) { throw HTTPResponseException(originalUrl, responseCode) } } private fun doDownload(originalUrl: URL, connection: URLConnection, tmpFile: File, currentBytes: Long, totalBytes: Long, append: Boolean) { val progress = DownloadingProgress(currentBytes) // TODO: Implement multi-thread downloading. executor.submit { connection.getInputStream().use { from -> FileOutputStream(tmpFile, append).use { to -> val buffer = ByteArray(DEFAULT_BUFFER_SIZE) var read = from.read(buffer) while (read != -1) { if (Thread.interrupted()) { throw InterruptedException() } to.write(buffer, 0, read) progress.update(read) read = from.read(buffer) } if (progress.currentBytes != totalBytes) { throw EOFException("The stream closed before end of downloading.") } } } } var result: Future? do { progressCallback(originalUrl.toString(), progress.currentBytes, totalBytes) result = executor.poll(1, TimeUnit.SECONDS) } while(result == null) progressCallback(originalUrl.toString(), progress.currentBytes, totalBytes) try { result.get() } catch (e: ExecutionException) { throw e.cause ?: e } } private fun resumeDownload(originalUrl: URL, originalConnection: HttpURLConnection, tmpFile: File) { originalConnection.connect() val totalBytes = originalConnection.contentLengthLong val currentBytes = tmpFile.length() if (currentBytes >= totalBytes || originalConnection.getHeaderField("Accept-Ranges") != "bytes") { // The temporary file is bigger then expected or the server doesn't support resuming downloading. // Download the file from scratch. doDownload(originalUrl, originalConnection, tmpFile, 0, totalBytes, false) } else { originalConnection.disconnect() val rangeConnection = originalUrl.openConnection() as HttpURLConnection rangeConnection.setRequestProperty("range", "bytes=$currentBytes-") rangeConnection.connect() rangeConnection.checkHTTPResponse(originalUrl) { it == HttpURLConnection.HTTP_PARTIAL || it == HttpURLConnection.HTTP_OK } doDownload(originalUrl, rangeConnection, tmpFile, currentBytes, totalBytes, true) } } /** Performs an attempt to download a specified file into the specified location */ private fun tryDownload(url: URL, tmpFile: File) { val connection = url.openConnection() (connection as? HttpURLConnection)?.checkHTTPResponse(HttpURLConnection.HTTP_OK, url) if (connection is HttpURLConnection && tmpFile.exists()) { resumeDownload(url, connection, tmpFile) } else { connection.connect() val totalBytes = connection.contentLengthLong doDownload(url, connection, tmpFile, 0, totalBytes, false) } } /** Downloads a file from [source] url to [destination]. Returns [destination]. */ fun download(source: URL, destination: File, replace: ReplacingMode = ReplacingMode.RETURN_EXISTING): File { if (destination.exists()) { when (replace) { ReplacingMode.RETURN_EXISTING -> return destination ReplacingMode.THROW -> throw FileAlreadyExistsException(destination) ReplacingMode.REPLACE -> Unit // Just continue with downloading. } } val tmpFile = File("${destination.canonicalPath}.$TMP_SUFFIX") check(!tmpFile.isDirectory) { "A temporary file is a directory: ${tmpFile.canonicalPath}. Remove it and try again." } check(!destination.isDirectory) { "The destination file is a directory: ${destination.canonicalPath}. Remove it and try again." } var attempt = 1 var waitTime = 0L val handleException = { e: Exception -> if (attempt >= maxAttempts) { throw e } attempt++ waitTime += attemptIntervalMs println("Cannot download a dependency: $e\n" + "Waiting ${waitTime.toDouble() / 1000} sec and trying again (attempt: $attempt/$maxAttempts).") // TODO: Wait better Thread.sleep(waitTime) } while (true) { try { tryDownload(source, tmpFile) break } catch (e: HTTPResponseException) { if (e.responseCode >= 500) { // Retry server errors. handleException(e) } else { // Do not retry client errors. throw e } } catch (e: IOException) { handleException(e) } } Files.move(tmpFile.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING) println("Done.") return destination } private val Long.humanReadable: String get() { if (this < 0) { return "-" } if (this < 1024) { return "$this bytes" } val exp = (Math.log(this.toDouble()) / Math.log(1024.0)).toInt() val prefix = "kMGTPE"[exp-1] return "%.1f %siB".format(this / Math.pow(1024.0, exp.toDouble()), prefix) } companion object { const val DEFAULT_MAX_ATTEMPTS = 10 const val DEFAULT_ATTEMPT_INTERVAL_MS = 3000L const val TMP_SUFFIX = "part" } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DependencyExtractor.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.util import org.jetbrains.kotlin.konan.file.unzipTo import java.io.File import java.util.concurrent.TimeUnit enum class ArchiveType(val fileExtension: String) { ZIP("zip"), TAR_GZ("tar.gz"); companion object { val systemDefault = if (System.getProperty("os.name").startsWith("Windows")) { ZIP } else { TAR_GZ } } } class DependencyExtractor( private val archiveType: ArchiveType ) { private fun extractTarGz(tarGz: File, targetDirectory: File) { val tarProcess = ProcessBuilder().apply { command("tar", "-xzf", tarGz.canonicalPath) directory(targetDirectory) inheritIO() }.start() val finished = tarProcess.waitFor(extractionTimeout, extractionTimeoutUntis) when { finished && tarProcess.exitValue() != 0 -> throw RuntimeException( "Cannot extract archive with dependency: ${tarGz.canonicalPath}.\n" + "Tar exit code: ${tarProcess.exitValue()}." ) !finished -> { tarProcess.destroy() throw RuntimeException( "Cannot extract archive with dependency: ${tarGz.canonicalPath}.\n" + "Tar process hasn't finished in ${extractionTimeoutUntis.toSeconds(extractionTimeout)} sec.") } } } fun extract(archive: File, targetDirectory: File) { when (archiveType) { ArchiveType.ZIP -> archive.toPath().unzipTo(targetDirectory.toPath()) ArchiveType.TAR_GZ -> extractTarGz(archive, targetDirectory) } } companion object { val extractionTimeout = 3600L val extractionTimeoutUntis = TimeUnit.SECONDS } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/DependencyProcessor.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.konan.util import org.jetbrains.kotlin.konan.file.use import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader import org.jetbrains.kotlin.konan.properties.Properties import org.jetbrains.kotlin.konan.properties.propertyList import java.io.File import java.io.FileNotFoundException import java.io.RandomAccessFile import java.net.InetAddress import java.net.URL import java.net.UnknownHostException import java.nio.file.Paths import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock private val Properties.dependenciesUrl : String get() = getProperty("dependenciesUrl") ?: throw IllegalStateException("No such property in konan.properties: dependenciesUrl") private val Properties.airplaneMode : Boolean get() = getProperty("airplaneMode")?.toBoolean() ?: false private val Properties.downloadingAttempts : Int get() = getProperty("downloadingAttempts")?.toInt() ?: DependencyDownloader.DEFAULT_MAX_ATTEMPTS private val Properties.downloadingAttemptIntervalMs : Long get() = getProperty("downloadingAttemptPauseMs")?.toLong() ?: DependencyDownloader.DEFAULT_ATTEMPT_INTERVAL_MS private fun Properties.findCandidates(dependencies: List): Map> { val dependencyProfiles = this.propertyList("dependencyProfiles") return dependencies.map { dependency -> dependency to dependencyProfiles.flatMap { profile -> val candidateSpecs = propertyList("$dependency.$profile") if (profile == "default" && candidateSpecs.isEmpty()) { listOf(DependencySource.Remote.Public) } else { candidateSpecs.map { candidateSpec -> when (candidateSpec) { "remote:public" -> DependencySource.Remote.Public "remote:internal" -> DependencySource.Remote.Internal else -> DependencySource.Local(File(candidateSpec)) } } } } }.toMap() } private val KonanPropertiesLoader.dependenciesUrl : String get() = properties.dependenciesUrl private val KonanPropertiesLoader.airplaneMode : Boolean get() = properties.airplaneMode private val KonanPropertiesLoader.downloadingAttempts : Int get() = properties.downloadingAttempts private val KonanPropertiesLoader.downloadingAttemptIntervalMs : Long get() = properties.downloadingAttemptIntervalMs sealed class DependencySource { data class Local(val path: File) : DependencySource() sealed class Remote : DependencySource() { object Public : Remote() object Internal : Remote() } } /** * Inspects [dependencies] and downloads all the missing ones into [dependenciesDirectory] from [dependenciesUrl]. * If [airplaneMode] is true will throw a RuntimeException instead of downloading. */ class DependencyProcessor(dependenciesRoot: File, private val dependenciesUrl: String, dependencyToCandidates: Map>, homeDependencyCache: File = defaultDependencyCacheDir, private val airplaneMode: Boolean = false, maxAttempts: Int = DependencyDownloader.DEFAULT_MAX_ATTEMPTS, attemptIntervalMs: Long = DependencyDownloader.DEFAULT_ATTEMPT_INTERVAL_MS, customProgressCallback: ProgressCallback? = null, private val keepUnstable: Boolean = true, private val deleteArchives: Boolean = true, private val archiveType: ArchiveType = ArchiveType.systemDefault) { private val dependenciesDirectory = dependenciesRoot.apply { mkdirs() } private val cacheDirectory = homeDependencyCache.apply { mkdirs() } private val lockFile = File(cacheDirectory, ".lock").apply { if (!exists()) createNewFile() } var showInfo = true private var isInfoShown = false private val downloader = DependencyDownloader(maxAttempts, attemptIntervalMs, customProgressCallback) private val extractor = DependencyExtractor(archiveType) constructor(dependenciesRoot: File, properties: KonanPropertiesLoader, dependenciesUrl: String = properties.dependenciesUrl, keepUnstable:Boolean = true, archiveType: ArchiveType = ArchiveType.systemDefault) : this( dependenciesRoot, properties.properties, properties.dependencies, dependenciesUrl, keepUnstable = keepUnstable, archiveType = archiveType) constructor(dependenciesRoot: File, properties: Properties, dependencies: List, dependenciesUrl: String = properties.dependenciesUrl, keepUnstable:Boolean = true, archiveType: ArchiveType = ArchiveType.systemDefault) : this( dependenciesRoot, dependenciesUrl, dependencyToCandidates = properties.findCandidates(dependencies), airplaneMode = properties.airplaneMode, maxAttempts = properties.downloadingAttempts, attemptIntervalMs = properties.downloadingAttemptIntervalMs, keepUnstable = keepUnstable, archiveType = archiveType) class DependencyFile(directory: File, fileName: String) { val file = File(directory, fileName).apply { createNewFile() } private val dependencies = file.readLines().toMutableSet() fun contains(dependency: String) = dependencies.contains(dependency) fun add(dependency: String) = dependencies.add(dependency) fun remove(dependency: String) = dependencies.remove(dependency) fun removeAndSave(dependency: String) { remove(dependency) save() } fun addAndSave(dependency: String) { add(dependency) save() } fun save() { val writer = file.writer() writer.use { dependencies.forEach { writer.write(it) writer.write("\n") } } } } private fun downloadDependency(dependency: String, baseUrl: String) { val depDir = File(dependenciesDirectory, dependency) val depName = depDir.name val fileName = "$depName.${archiveType.fileExtension}" val archive = cacheDirectory.resolve(fileName) val url = URL("$baseUrl/$fileName") val extractedDependencies = DependencyFile(dependenciesDirectory, ".extracted") if (extractedDependencies.contains(depName) && depDir.exists() && depDir.isDirectory && depDir.list().isNotEmpty()) { if (!keepUnstable && depDir.list().contains(".unstable")) { // The downloaded version of the dependency is unstable -> redownload it. depDir.deleteRecursively() archive.delete() extractedDependencies.removeAndSave(dependency) } else { return } } if (showInfo && !isInfoShown) { println("Downloading native dependencies (LLVM, sysroot etc). This is a one-time action performed only on the first run of the compiler.") isInfoShown = true } if (!archive.exists()) { if (airplaneMode) { throw FileNotFoundException(""" Cannot find a dependency locally: $dependency. Set `airplaneMode = false` in konan.properties to download it. """.trimIndent()) } downloader.download(url, archive) } println("Extracting dependency: $archive into $dependenciesDirectory") extractor.extract(archive, dependenciesDirectory) if (deleteArchives) { archive.delete() } extractedDependencies.addAndSave(depName) } companion object { val localKonanDir: File by lazy { File(System.getenv("KONAN_DATA_DIR") ?: (System.getProperty("user.home") + File.separator + ".konan")) } @JvmStatic val defaultDependenciesRoot: File get() = localKonanDir.resolve("dependencies") val defaultDependencyCacheDir: File get() = localKonanDir.resolve("cache") val isInternalSeverAvailable: Boolean get() = InternalServer.isAvailable } private val resolvedDependencies = dependencyToCandidates.map { (dependency, candidates) -> val candidate = candidates.asSequence().mapNotNull { candidate -> when (candidate) { is DependencySource.Local -> candidate.takeIf { it.path.exists() } DependencySource.Remote.Public -> candidate DependencySource.Remote.Internal -> candidate.takeIf { InternalServer.isAvailable } } }.firstOrNull() candidate ?: error("$dependency is not available; candidates:\n${candidates.joinToString("\n")}") dependency to candidate }.toMap() private fun resolveDependency(dependency: String): File { val candidate = resolvedDependencies[dependency] return when (candidate) { is DependencySource.Local -> candidate.path is DependencySource.Remote -> File(dependenciesDirectory, dependency) null -> error("$dependency not declared as dependency") } } /** * If given [path] is relative, resolves it relative to dependecies directory. * In case of absolute path just wraps it into a [File]. * * Support of both relative and absolute path kinds allows to substitute predefined * dependencies with system ones. * * TODO: It looks like DependencyProcessor have two split responsibilities: * * Dependency resolving * * Dependency downloading * Also it is tightly tied to KonanProperties. */ fun resolve(path: String): File = if (Paths.get(path).isAbsolute) File(path) else resolveRelative(path) private fun resolveRelative(relative: String): File { val path = Paths.get(relative) if (path.isAbsolute) error("not a relative path: $relative") val dependency = path.first().toString() return resolveDependency(dependency).let { if (path.nameCount > 1) { it.toPath().resolve(path.subpath(1, path.nameCount)).toFile() } else { it } } } fun run() { // We need a lock that can be shared between different classloaders (KT-39781). // TODO: Rework dependencies downloading to avoid storing the lock in the system properties. val lock = System.getProperties().computeIfAbsent("kotlin.native.dependencies.lock") { // String literals are internalized so we create a new instance to avoid synchronization on a shared object. java.lang.String("lock") } synchronized(lock) { RandomAccessFile(lockFile, "rw").channel.lock().use { resolvedDependencies.forEach { (dependency, candidate) -> val baseUrl = when (candidate) { is DependencySource.Local -> null DependencySource.Remote.Public -> dependenciesUrl DependencySource.Remote.Internal -> InternalServer.url } // TODO: consider using different caches for different remotes. if (baseUrl != null) { downloadDependency(dependency, baseUrl) } } } } } } internal object InternalServer { private const val host = "repo.labs.intellij.net" const val url = "https://$host/kotlin-native" private const val internalDomain = "labs.intellij.net" val isAvailable: Boolean get() { val envKey = "KONAN_USE_INTERNAL_SERVER" return when (val envValue = System.getenv(envKey)) { null, "0" -> false "1" -> true "auto" -> isAccessible else -> error("unexpected environment: $envKey=$envValue") } } private val isAccessible by lazy { checkAccessible() } private fun checkAccessible() = try { if (!InetAddress.getLocalHost().canonicalHostName.endsWith(".$internalDomain")) { // Fast path: false } else { InetAddress.getByName(host) true } } catch (e: UnknownHostException) { false } } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/PlatformLibsInfo.kt ================================================ package org.jetbrains.kotlin.konan.util object PlatformLibsInfo { const val namePrefix = "org.jetbrains.kotlin.native.platform." } ================================================ FILE: shared/src/main/kotlin/org/jetbrains/kotlin/konan/util/Substitution.kt ================================================ package org.jetbrains.kotlin.konan.util import org.jetbrains.kotlin.konan.target.KonanTarget import java.util.* // FIXME(ddol): KLIB-REFACTORING-CLEANUP: remove the whole file! fun defaultTargetSubstitutions(target: KonanTarget) = mapOf( "target" to target.visibleName, "arch" to target.architecture.visibleName, "family" to target.family.visibleName) // Performs substitution similar to: // foo = ${foo} ${foo.${arch}} ${foo.${os}} fun substitute(properties: Properties, substitutions: Map) { for (key in properties.stringPropertyNames()) { for (substitution in substitutions.values) { val suffix = ".$substitution" if (key.endsWith(suffix)) { val baseKey = key.removeSuffix(suffix) val oldValue = properties.getProperty(baseKey, "") val appendedValue = properties.getProperty(key, "") val newValue = if (oldValue != "") "$oldValue $appendedValue" else appendedValue properties.setProperty(baseKey, newValue) } } } } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/analyzer/FieldChange.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer // Report with changes of different fields. class ChangeReport(val entityName: String, val changes: List>) { fun renderAsTextReport(): String { var content = "" if (!changes.isEmpty()) { content = "$content$entityName changes\n" content = "$content====================\n" changes.forEach { content = "$content${it.renderAsText()}" } } return content } } // Change of report field. class FieldChange(val field: String, val previous: T, val current: T) { companion object { fun getFieldChangeOrNull(field: String, previous: T, current: T): FieldChange? { if (previous != current) { return FieldChange(field, previous, current) } return null } } fun renderAsText(): String { return "$field: $previous -> $current\n" } } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/analyzer/Statistics.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import org.jetbrains.report.BenchmarkResult import org.jetbrains.report.MeanVariance import org.jetbrains.report.MeanVarianceBenchmark import kotlin.math.abs import kotlin.math.max import kotlin.math.min import kotlin.math.pow import kotlin.math.sqrt val MeanVariance.description: String get() { val format = { number: Double -> number.format(2) } return "${format(mean)} ± ${format(variance)}" } val MeanVarianceBenchmark.description: String get() = "${score.format()} ± ${variance.format()}" // Calculate difference in percentage compare to another. fun MeanVarianceBenchmark.calcPercentageDiff(other: MeanVarianceBenchmark): MeanVariance { if (score == 0.0 && variance == 0.0 && other.score == 0.0 && other.variance == 0.0) return MeanVariance(score, variance) assert(other.score >= 0 && other.variance >= 0 && (other.score - other.variance != 0.0 || other.score == 0.0), { "Mean and variance should be positive and not equal!" }) // Analyze intervals. Calculate difference between border points. val (bigValue, smallValue) = if (score > other.score) Pair(this, other) else Pair(other, this) val bigValueIntervalStart = bigValue.score - bigValue.variance val bigValueIntervalEnd = bigValue.score + bigValue.variance val smallValueIntervalStart = smallValue.score - smallValue.variance val smallValueIntervalEnd = smallValue.score + smallValue.variance if (smallValueIntervalEnd > bigValueIntervalStart) { // Interval intersect. return MeanVariance(0.0, 0.0) } val mean = ((smallValueIntervalEnd - bigValueIntervalStart) / bigValueIntervalStart) * (if (score > other.score) -1 else 1) val maxValueChange = ((bigValueIntervalEnd - smallValueIntervalEnd) / bigValueIntervalEnd) val minValueChange = ((bigValueIntervalStart - smallValueIntervalStart) / bigValueIntervalStart) val variance = abs(abs(mean) - max(minValueChange, maxValueChange)) return MeanVariance(mean * 100, variance * 100) } // Calculate ratio value compare to another. fun MeanVarianceBenchmark.calcRatio(other: MeanVarianceBenchmark): MeanVariance { if (other.score == 0.0 && other.variance == 0.0) return MeanVariance(1.0, 0.0) assert(other.score >= 0 && other.variance >= 0 && (other.score - other.variance != 0.0 || other.score == 0.0), { "Mean and variance should be positive and not equal!" }) val mean = if (other.score != 0.0) (score / other.score) else 0.0 val minRatio = (score - variance) / (other.score + other.variance) val maxRatio = (score + variance) / (other.score - other.variance) val ratioConfInt = min(abs(minRatio - mean), abs(maxRatio - mean)) return MeanVariance(mean, ratioConfInt) } fun geometricMean(values: Collection, totalNumber: Int = values.size) = with(values.asSequence().filter { it != 0.0 }) { if (count() == 0 || totalNumber == 0) { 0.0 } else { map { it.pow(1.0 / totalNumber) }.reduce { a, b -> a * b } } } fun computeMeanVariance(samples: List): MeanVariance { val removedBroadSamples = 0.2 val zStar = 1.67 // Critical point for 90% confidence of normal distribution. // Skip several minimal and maximum values. val filteredSamples = if (samples.size >= 1/removedBroadSamples) { samples.sorted().subList((samples.size * removedBroadSamples).toInt(), samples.size - (samples.size * removedBroadSamples).toInt()) } else { samples } val mean = filteredSamples.sum() / filteredSamples.size val variance = samples.indices.sumByDouble { (samples[it] - mean) * (samples[it] - mean) } / samples.size val confidenceInterval = sqrt(variance / samples.size) * zStar return MeanVariance(mean, confidenceInterval) } // Calculate average results for benchmarks (each benchmark can be run several times). fun collectMeanResults(benchmarks: Map>): BenchmarksTable { return benchmarks.map { (name, resultsSet) -> val repeatedSequence = IntArray(resultsSet.size) var metric = BenchmarkResult.Metric.EXECUTION_TIME var currentStatus = BenchmarkResult.Status.PASSED var currentWarmup = -1 // Results can be already processed. if (resultsSet[0] is MeanVarianceBenchmark) { assert(resultsSet.size == 1) { "Several MeanVarianceBenchmark instances." } name to resultsSet[0] as MeanVarianceBenchmark } else { // Collect common benchmark values and check them. resultsSet.forEachIndexed { index, result -> // If there was at least one failure, summary is marked as failure. if (result.status == BenchmarkResult.Status.FAILED) { currentStatus = result.status } repeatedSequence[index] = result.repeat if (currentWarmup != -1) if (result.warmup != currentWarmup) println("Check data consistency. Warmup value for benchmark '${result.name}' differs.") currentWarmup = result.warmup metric = result.metric } repeatedSequence.sort() // Check if there are missed loop during running benchmarks. repeatedSequence.forEachIndexed { index, element -> if (index != 0) if ((element - repeatedSequence[index - 1]) != 1) println("Check data consistency. For benchmark '$name' there is no run" + " between ${repeatedSequence[index - 1]} and $element.") } // Create mean and variance benchmarks result. val scoreMeanVariance = computeMeanVariance(resultsSet.map { it.score }) val runtimeInUsMeanVariance = computeMeanVariance(resultsSet.map { it.runtimeInUs }) val meanBenchmark = MeanVarianceBenchmark(name, currentStatus, scoreMeanVariance.mean, metric, runtimeInUsMeanVariance.mean, repeatedSequence[resultsSet.size - 1], currentWarmup, scoreMeanVariance.variance) name to meanBenchmark } }.toMap() } fun collectBenchmarksDurations(benchmarks: Map>): Map = benchmarks.map { (name, resultsSet) -> name to resultsSet.sumByDouble { it.runtimeInUs } }.toMap() ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/analyzer/SummaryBenchmarksReport.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import org.jetbrains.report.BenchmarkResult import org.jetbrains.report.BenchmarksReport import org.jetbrains.report.Compiler import org.jetbrains.report.Environment import org.jetbrains.report.MeanVariance import org.jetbrains.report.MeanVarianceBenchmark import kotlin.math.abs typealias SummaryBenchmark = Pair typealias BenchmarksTable = Map typealias SummaryBenchmarksTable = Map typealias ScoreChange = Pair class DetailedBenchmarksReport(currentBenchmarks: Map>, previousBenchmarks: Map>? = null, val meaningfulChangesValue: Double = 0.5) { // Report created by joining comparing reports. val mergedReport: Map // Lists of benchmarks in different status. private val benchmarksWithChangedStatus = mutableListOf>() // Maps with changes of performance. var regressions = mapOf() private set var improvements = mapOf() private set // Summary value of report - geometric mean. val geoMeanBenchmark: SummaryBenchmark var geoMeanScoreChange: ScoreChange? = null private set val maximumRegression: Double get() = getMaximumChange(regressions) val maximumImprovement: Double get() = getMaximumChange(improvements) val regressionsGeometricMean: Double get() = getGeometricMeanOfChanges(regressions) val improvementsGeometricMean: Double get() = getGeometricMeanOfChanges(improvements) val benchmarksNumber: Int get() = mergedReport.keys.size init { // Count avarage values for each benchmark. val currentBenchmarksTable = collectMeanResults(currentBenchmarks) val previousBenchmarksTable = previousBenchmarks?.let { collectMeanResults(previousBenchmarks) } mergedReport = createMergedReport(currentBenchmarksTable, previousBenchmarksTable) geoMeanBenchmark = calculateGeoMeanBenchmark(currentBenchmarksTable, previousBenchmarksTable) if (previousBenchmarks != null) { // Check changes in environment and tools. analyzePerformanceChanges() } } private fun getMaximumChange(bucket: Map): Double = // Maps of regressions and improvements are sorted. if (bucket.isEmpty()) 0.0 else bucket.values.map { it.first.mean }.first() // Analyze and collect changes in performance between same becnhmarks. private fun analyzePerformanceChanges() { val performanceChanges = mergedReport.asSequence().map { (name, element) -> getBenchmarkPerfomanceChange(name, element) }.filterNotNull().groupBy { if (it.second.first.mean > 0) "regressions" else "improvements" } // Sort regressions and improvements. regressions = performanceChanges["regressions"] ?.sortedByDescending { it.second.first.mean }?.map { it.first to it.second } ?.toMap() ?: mapOf() improvements = performanceChanges["improvements"] ?.sortedBy { it.second.first.mean }?.map { it.first to it.second } ?.toMap() ?: mapOf() // Calculate change for geometric mean. val (current, previous) = geoMeanBenchmark geoMeanScoreChange = current?.let { previous?.let { Pair(current.calcPercentageDiff(previous), current.calcRatio(previous)) } } } private fun getGeometricMeanOfChanges(bucket: Map): Double { if (bucket.isEmpty()) return 0.0 var percentsList = bucket.values.map { it.first.mean } return if (percentsList.first() > 0.0) { geometricMean(percentsList, benchmarksNumber) } else { // Geometric mean can be counted on positive numbers. percentsList = percentsList.map { abs(it) } -geometricMean(percentsList, benchmarksNumber) } } fun getBenchmarksWithChangedStatus(): List> = benchmarksWithChangedStatus // Merge current and compare to report. private fun createMergedReport(currentBenchmarks: BenchmarksTable, previousBenchmarks: BenchmarksTable?): Map { val mergedTable = mutableMapOf() mergedTable.apply { currentBenchmarks.forEach { (name, current) -> // Check existance of benchmark in previous results. if (previousBenchmarks == null || name !in previousBenchmarks) { getOrPut(name) { SummaryBenchmark(current, null) } } else { val previousBenchmark = previousBenchmarks.getValue(name) getOrPut(name) { SummaryBenchmark(current, previousBenchmarks[name]) } // Explore change of status. if (previousBenchmark.status != current.status) { val statusChange = FieldChange("$name", previousBenchmark.status, current.status) benchmarksWithChangedStatus.add(statusChange) } } } } // Add removed benchmarks to merged report. mergedTable.apply { previousBenchmarks?.filter { (key, _) -> key !in currentBenchmarks }?.forEach { (key, value) -> getOrPut(key) { SummaryBenchmark(null, value) } } } return mergedTable } // Calculate geometric mean. private fun calculateGeoMeanBenchmark(currentBenchmarks: BenchmarksTable, previousBenchmarks: BenchmarksTable?): SummaryBenchmark { // Calculate geometric mean. val currentGeoMean = createGeoMeanBenchmark(currentBenchmarks) val previousGeoMean = previousBenchmarks?.let { createGeoMeanBenchmark(previousBenchmarks) } return SummaryBenchmark(currentGeoMean, previousGeoMean) } private fun getBenchmarkPerfomanceChange(name: String, benchmark: SummaryBenchmark): Pair? { val (current, previous) = benchmark current?.let { previous?.let { // Calculate metrics for showing difference. val percent = current.calcPercentageDiff(previous) val ratio = current.calcRatio(previous) if (abs(percent.mean) - percent.variance >= meaningfulChangesValue) { return Pair(name, Pair(percent, ratio)) } } } return null } // Create geometric mean. private fun createGeoMeanBenchmark(benchTable: BenchmarksTable): MeanVarianceBenchmark { val geoMeanBenchmarkName = "Geometric mean" val geoMean = geometricMean(benchTable.toList().map { (_, value) -> value.score }) val varianceGeoMean = geometricMean(benchTable.toList().map { (_, value) -> value.variance }) return MeanVarianceBenchmark(geoMeanBenchmarkName, geoMean, varianceGeoMean) } } // Summary report with comparasion of separate benchmarks results. class SummaryBenchmarksReport(val currentReport: BenchmarksReport, val previousReport: BenchmarksReport? = null, val meaningfulChangesValue: Double = 0.5, private val unstableBenchmarks: List = emptyList()) { val detailedMetricReports: Map private val benchmarksDurations: Map> // Lists of benchmarks in different status. val benchmarksWithChangedStatus get() = getReducedResult { report -> report.getBenchmarksWithChangedStatus() } // Environment and tools. val environments: Pair val compilers: Pair private fun getReducedResult(convertor: (DetailedBenchmarksReport) -> List): List { return detailedMetricReports.values.map { convertor(it) }.flatten() } // Countable properties. val failedBenchmarks: List get() = getReducedResult { report -> report.mergedReport.filter { it.value.first?.status == BenchmarkResult.Status.FAILED }.map { it.key } } val addedBenchmarks: List get() = getReducedResult { report -> report.mergedReport.filter { it.value.second == null }.map { it.key } } val removedBenchmarks: List get() = getReducedResult { report -> report.mergedReport.filter { it.value.first == null }.map { it.key } } val currentMeanVarianceBenchmarks: List get() = getReducedResult { report -> report.mergedReport.filter { it.value.first != null }.map { it.value.first!! } } val benchmarksNumber: Int get() = detailedMetricReports.values.fold(0) { acc, it -> acc + it.benchmarksNumber } val currentBenchmarksDuration: Map get() = benchmarksDurations.filter { it.value.first != null }.map { it.key to it.value.first!! }.toMap() val envChanges: List> get() { val previousEnvironment = environments.second val currentEnvironment = environments.first return previousEnvironment?.let { mutableListOf>().apply { addFieldChange("Machine CPU", previousEnvironment.machine.cpu, currentEnvironment.machine.cpu) addFieldChange("Machine OS", previousEnvironment.machine.os, currentEnvironment.machine.os) addFieldChange("JDK version", previousEnvironment.jdk.version, currentEnvironment.jdk.version) addFieldChange("JDK vendor", previousEnvironment.jdk.vendor, currentEnvironment.jdk.vendor) } } ?: listOf>() } val kotlinChanges: List> get() { val previousCompiler = compilers.second val currentCompiler = compilers.first return previousCompiler?.let { mutableListOf>().apply { addFieldChange("Backend type", previousCompiler.backend.type.type, currentCompiler.backend.type.type) addFieldChange("Backend version", previousCompiler.backend.version, currentCompiler.backend.version) addFieldChange("Backend flags", previousCompiler.backend.flags.toString(), currentCompiler.backend.flags.toString()) addFieldChange("Kotlin version", previousCompiler.kotlinVersion, currentCompiler.kotlinVersion) } } ?: listOf>() } init { // Count avarage values for each benchmark. detailedMetricReports = BenchmarkResult.Metric.values().map { metric -> val currentBenchmarks = currentReport.benchmarks.map { (name, benchmarks) -> name to benchmarks.filter { it.metric == metric } }.filter { it.second.isNotEmpty() }.toMap() val previousBenchmarks = previousReport?.benchmarks?.map { (name, benchmarks) -> name to benchmarks.filter { it.metric == metric } }?.filter { it.second.isNotEmpty() }?.toMap() metric to DetailedBenchmarksReport( currentReport.benchmarks.map { (name, benchmarks) -> name to benchmarks.filter { it.metric == metric } }.filter { it.second.isNotEmpty() }.toMap(), previousReport?.benchmarks?.map { (name, benchmarks) -> name to benchmarks.filter { it.metric == metric } }?.filter { it.second.isNotEmpty() }?.toMap(), meaningfulChangesValue ) }.toMap() benchmarksDurations = calculateBenchmarksDuration(currentReport, previousReport) environments = Pair(currentReport.env, previousReport?.env) compilers = Pair(currentReport.compiler, previousReport?.compiler) } // Get benchmark report. fun getBenchmarksReport(takeMainReport: Boolean = true) = if (takeMainReport) BenchmarksReport(environments.first, getReducedResult { report -> report.mergedReport.map { (_, value) -> value.first!! } }, compilers.first) else BenchmarksReport(environments.second!!, getReducedResult { report -> report.mergedReport.map { (_, value) -> value.second!! } }, compilers.second!!) fun getUnstableBenchmarksForMetric(metric: BenchmarkResult.Metric) = if (metric == BenchmarkResult.Metric.EXECUTION_TIME) unstableBenchmarks else emptyList() // Generate map with summary durations of each benchmark. private fun calculateBenchmarksDuration(currentReport: BenchmarksReport, previousReport: BenchmarksReport?): Map> { val currentDurations = collectBenchmarksDurations(currentReport.benchmarks) val previousDurations = previousReport?.let { collectBenchmarksDurations(previousReport.benchmarks) } ?: mapOf() return currentDurations.keys.union(previousDurations.keys) .map { it to Pair(currentDurations[it], previousDurations[it]) }.toMap() } private fun MutableList>.addFieldChange(field: String, previous: T, current: T) { FieldChange.getFieldChangeOrNull(field, previous, current)?.let { add(it) } } } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/analyzer/Utils.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer expect fun readFile(fileName: String): String expect fun Double.format(decimalNumber: Int = 4): String expect fun writeToFile(fileName: String, text: String) expect fun assert(value: Boolean, lazyMessage: () -> Any) expect fun sendGetRequest(url: String, user: String? = null, password: String? = null, followLocation: Boolean = false) : String ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/BenchmarksReport.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.report import org.jetbrains.report.json.* interface JsonSerializable { fun serializeFields(): String fun toJson(): String { return """ { ${serializeFields()} } """ } // Convert iterable objects arrays, lists to json. fun arrayToJson(data: Iterable): String { return data.joinToString(prefix = "[", postfix = "]") { if (it is JsonSerializable) it.toJson() else it.toString() } } } interface EntityFromJsonFactory : ConvertedFromJson { fun create(data: JsonElement): T } // Parse array with benchmarks to list fun parseBenchmarksArray(data: JsonElement): List { if (data is JsonArray) { return data.jsonArray.map { if (MeanVarianceBenchmark.isMeanVarianceBenchmark(it)) MeanVarianceBenchmark.create(it as JsonObject) else BenchmarkResult.create(it as JsonObject) } } else { error("Benchmarks field is expected to be an array. Please, check origin files.") } } // Class for benchmarks report with all information of run. open class BenchmarksReport(val env: Environment, benchmarksList: List, val compiler: Compiler) : JsonSerializable { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): BenchmarksReport { if (data is JsonObject) { val env = Environment.create(data.getRequiredField("env")) val benchmarksObj = data.getRequiredField("benchmarks") val compiler = Compiler.create(data.getRequiredField("kotlin")) val buildNumberField = data.getOptionalField("buildNumber") val benchmarksList = parseBenchmarksArray(benchmarksObj) val report = BenchmarksReport(env, benchmarksList, compiler) buildNumberField?.let { report.buildNumber = (it as JsonLiteral).unquoted() } return report } else { error("Top level entity is expected to be an object. Please, check origin files.") } } // Made a map of becnhmarks with name as key from list. private fun structBenchmarks(benchmarksList: List) = benchmarksList.groupBy { it.name } } val benchmarks = structBenchmarks(benchmarksList) var buildNumber: String? = null override fun serializeFields(): String { val buildNumberField = buildNumber?.let { """, "buildNumber": "$buildNumber" """ } ?: "" return """ "env": ${env.toJson()}, "kotlin": ${compiler.toJson()}, "benchmarks": ${arrayToJson(benchmarks.flatMap { it.value })}$buildNumberField """.trimIndent() } fun merge(other: BenchmarksReport): BenchmarksReport { val mergedBenchmarks = HashMap(benchmarks) other.benchmarks.forEach { if (it.key in mergedBenchmarks) { error("${it.key} already exists in report!") } } mergedBenchmarks.putAll(other.benchmarks) return BenchmarksReport(env, mergedBenchmarks.flatMap { it.value }, compiler) } // Concatenate benchmarks report if they have same environment and compiler. operator fun plus(other: BenchmarksReport): BenchmarksReport { if (compiler != other.compiler || env != other.env) { error("It's impossible to concat reports from different machines!") } return merge(other) } } // Class for kotlin compiler data class Compiler(val backend: Backend, val kotlinVersion: String) : JsonSerializable { enum class BackendType(val type: String) { JVM("jvm"), NATIVE("native") } companion object : EntityFromJsonFactory { override fun create(data: JsonElement): Compiler { if (data is JsonObject) { val backend = Backend.create(data.getRequiredField("backend")) val kotlinVersion = elementToString(data.getRequiredField("kotlinVersion"), "kotlinVersion") return Compiler(backend, kotlinVersion) } else { error("Kotlin entity is expected to be an object. Please, check origin files.") } } fun backendTypeFromString(s: String): BackendType? = BackendType.values().find { it.type == s } } // Class for compiler backend data class Backend(val type: BackendType, val version: String, val flags: List) : JsonSerializable { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): Backend { if (data is JsonObject) { val typeElement = data.getRequiredField("type") if (typeElement is JsonLiteral) { val type = backendTypeFromString(typeElement.unquoted()) ?: error("Backend type should be 'jvm' or 'native'") val version = elementToString(data.getRequiredField("version"), "version") val flagsArray = data.getOptionalField("flags") var flags: List = emptyList() if (flagsArray != null && flagsArray is JsonArray) { flags = flagsArray.jsonArray.map { it.toString() } } return Backend(type, version, flags) } else { error("Backend type should be string literal.") } } else { error("Backend entity is expected to be an object. Please, check origin files.") } } } override fun serializeFields(): String { val result = """ "type": "${type.type}", "version": "${version}"""" // Don't print flags field if there is no one. if (flags.isEmpty()) { return """$result """ } else { return """ $result, "flags": ${arrayToJson(flags.map { if (it.startsWith("\"")) it else "\"$it\"" })} """ } } } override fun serializeFields(): String { return """ "backend": ${backend.toJson()}, "kotlinVersion": "${kotlinVersion}" """ } } // Class for description of environment of benchmarks run data class Environment(val machine: Machine, val jdk: JDKInstance) : JsonSerializable { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): Environment { if (data is JsonObject) { val machine = Machine.create(data.getRequiredField("machine")) val jdk = JDKInstance.create(data.getRequiredField("jdk")) return Environment(machine, jdk) } else { error("Environment entity is expected to be an object. Please, check origin files.") } } } // Class for description of machine used for benchmarks run. data class Machine(val cpu: String, val os: String) : JsonSerializable { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): Machine { if (data is JsonObject) { val cpu = elementToString(data.getRequiredField("cpu"), "cpu") val os = elementToString(data.getRequiredField("os"), "os") return Machine(cpu, os) } else { error("Machine entity is expected to be an object. Please, check origin files.") } } } override fun serializeFields(): String { return """ "cpu": "$cpu", "os": "$os" """ } } // Class for description of jdk used for benchmarks run. data class JDKInstance(val version: String, val vendor: String) : JsonSerializable { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): JDKInstance { if (data is JsonObject) { val version = elementToString(data.getRequiredField("version"), "version") val vendor = elementToString(data.getRequiredField("vendor"), "vendor") return JDKInstance(version, vendor) } else { error("JDK entity is expected to be an object. Please, check origin files.") } } } override fun serializeFields(): String { return """ "version": "$version", "vendor": "$vendor" """ } } override fun serializeFields(): String { return """ "machine": ${machine.toJson()}, "jdk": ${jdk.toJson()} """ } } open class BenchmarkResult(val name: String, val status: Status, val score: Double, val metric: Metric, val runtimeInUs: Double, val repeat: Int, val warmup: Int) : JsonSerializable { enum class Metric(val suffix: String, val value: String) { EXECUTION_TIME("", "EXECUTION_TIME"), CODE_SIZE(".codeSize", "CODE_SIZE"), COMPILE_TIME(".compileTime", "COMPILE_TIME"), BUNDLE_SIZE(".bundleSize", "BUNDLE_SIZE") } constructor(name: String, score: Double) : this(name, Status.PASSED, score, Metric.EXECUTION_TIME, 0.0, 0, 0) companion object : EntityFromJsonFactory { override fun create(data: JsonElement): BenchmarkResult { if (data is JsonObject) { var name = elementToString(data.getRequiredField("name"), "name") val metricElement = data.getOptionalField("metric") val metric = if (metricElement != null && metricElement is JsonLiteral) metricFromString(metricElement.unquoted()) ?: Metric.EXECUTION_TIME else Metric.EXECUTION_TIME val statusElement = data.getRequiredField("status") if (statusElement is JsonLiteral) { val status = statusFromString(statusElement.unquoted()) ?: error("Status should be PASSED or FAILED") val score = elementToDouble(data.getRequiredField("score"), "score") val runtimeInUs = elementToDouble(data.getRequiredField("runtimeInUs"), "runtimeInUs") val repeat = elementToInt(data.getRequiredField("repeat"), "repeat") val warmup = elementToInt(data.getRequiredField("warmup"), "warmup") return BenchmarkResult(name, status, score, metric, runtimeInUs, repeat, warmup) } else { error("Status should be string literal.") } } else { error("Benchmark entity is expected to be an object. Please, check origin files.") } } fun statusFromString(s: String): Status? = Status.values().find { it.value == s } fun metricFromString(s: String): Metric? = Metric.values().find { it.value == s } } enum class Status(val value: String) { PASSED("PASSED"), FAILED("FAILED") } override fun serializeFields(): String { return """ "name": "${name.removeSuffix(metric.suffix)}", "status": "${status.value}", "score": ${score}, "metric": "${metric.value}", "runtimeInUs": ${runtimeInUs}, "repeat": ${repeat}, "warmup": ${warmup} """ } val shortName: String get() = name.removeSuffix(metric.suffix) } // Entity to describe avarage values which conssists of mean and variance values. data class MeanVariance(val mean: Double, val variance: Double) // Processed benchmark result with calculated mean and variance value. open class MeanVarianceBenchmark(name: String, status: BenchmarkResult.Status, score: Double, metric: BenchmarkResult.Metric, runtimeInUs: Double, repeat: Int, warmup: Int, val variance: Double) : BenchmarkResult(name, status, score, metric, runtimeInUs, repeat, warmup) { constructor(name: String, score: Double, variance: Double) : this(name, BenchmarkResult.Status.PASSED, score, BenchmarkResult.Metric.EXECUTION_TIME, 0.0, 0, 0, variance) companion object : EntityFromJsonFactory { fun isMeanVarianceBenchmark(data: JsonElement) = data is JsonObject && data.getOptionalField("variance") != null override fun create(data: JsonElement): MeanVarianceBenchmark { if (data is JsonObject) { val baseBenchmark = BenchmarkResult.create(data) val variance = elementToDouble(data.getRequiredField("variance"), "variance") return MeanVarianceBenchmark(baseBenchmark.name, baseBenchmark.status, baseBenchmark.score, baseBenchmark.metric, baseBenchmark.runtimeInUs, baseBenchmark.repeat, baseBenchmark.warmup, variance) } else { error("Benchmark entity is expected to be an object. Please, check origin files.") } } } override fun serializeFields(): String { return """ ${super.serializeFields()}, "variance": $variance """ } } // Benchmark with set results stability state. open class BenchmarkWithStabilityState(name: String, status: BenchmarkResult.Status, score: Double, metric: BenchmarkResult.Metric, runtimeInUs: Double, repeat: Int, warmup: Int, val unstable: Boolean) : BenchmarkResult(name, status, score, metric, runtimeInUs, repeat, warmup) { constructor(benchmarkResult: BenchmarkResult, unstable: Boolean) : this(benchmarkResult.name, benchmarkResult.status, benchmarkResult.score, benchmarkResult.metric, benchmarkResult.runtimeInUs, benchmarkResult.repeat, benchmarkResult.warmup, unstable) override fun serializeFields(): String { return """ ${super.serializeFields()}, "unstable": $unstable """ } companion object : EntityFromJsonFactory { override fun create(data: JsonElement): BenchmarkWithStabilityState { val parsedObject = BenchmarkResult.create(data) if (data is JsonObject) { val unstableElement = data.getOptionalField("unstable") val unstableFlag = if (unstableElement != null && unstableElement is JsonPrimitive) unstableElement.boolean else false return BenchmarkWithStabilityState(parsedObject, unstableFlag) } else { error("Benchmark entity is expected to be an object. Please, check origin files.") } } } } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/ConvertedFromJson.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.report.json // Entity can be created from json description. interface ConvertedFromJson { // Methods for conversion to expected type with checks of possibility of such conversions. fun elementToDouble(element: JsonElement, name: String): Double = if (element is JsonPrimitive) element.double else error("Field '$name' in '$element' is expected to be a double number. Please, check origin files.") fun elementToInt(element: JsonElement, name: String): Int = if (element is JsonPrimitive) element.int else error("Field '$name' in '$element' is expected to be an integer number. Please, check origin files.") fun elementToString(element: JsonElement, name:String): String = if (element is JsonLiteral) element.unquoted() else error("Field '$name' in '$element' is expected to be a string. Please, check origin files.") fun elementToStringOrNull(element: JsonElement, name:String): String? = when (element) { is JsonLiteral -> element.unquoted() is JsonNull -> null else -> error("Field '$name' in '$element' is expected to be a string. Please, check origin files.") } } fun JsonObject.getRequiredField(fieldName: String): JsonElement { return getOrNull(fieldName) ?: error("Field '$fieldName' doesn't exist in '$this'. Please, check origin files.") } fun JsonObject.getOptionalField(fieldName: String): JsonElement? { return getOrNull(fieldName) } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/JsonElement.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.report.json /** * Class representing single JSON element. * Can be [JsonPrimitive], [JsonArray] or [JsonObject]. * * [JsonElement.toString] properly prints JSON tree as valid JSON, taking into * account quoted values and primitives */ sealed class JsonElement { /** * Convenience method to get current element as [JsonPrimitive] * @throws JsonElementTypeMismatchException is current element is not a [JsonPrimitive] */ open val primitive: JsonPrimitive get() = error("JsonLiteral") /** * Convenience method to get current element as [JsonObject] * @throws JsonElementTypeMismatchException is current element is not a [JsonObject] */ open val jsonObject: JsonObject get() = error("JsonObject") /** * Convenience method to get current element as [JsonArray] * @throws JsonElementTypeMismatchException is current element is not a [JsonArray] */ open val jsonArray: JsonArray get() = error("JsonArray") /** * Convenience method to get current element as [JsonNull] * @throws JsonElementTypeMismatchException is current element is not a [JsonNull] */ open val jsonNull: JsonNull get() = error("JsonPrimitive") /** * Checks whether current element is [JsonNull] */ val isNull: Boolean get() = this === JsonNull private fun error(element: String): Nothing = throw JsonElementTypeMismatchException(this::class.toString(), element) } /** * Class representing JSON primitive value. Can be either [JsonLiteral] or [JsonNull]. */ sealed class JsonPrimitive : JsonElement() { /** * Content of given element without quotes. For [JsonNull] this methods returns `"null"` */ abstract val content: String /** * Content of the given element without quotes or `null` if current element is [JsonNull] */ abstract val contentOrNull: String? @Suppress("LeakingThis") final override val primitive: JsonPrimitive = this /** * Returns content of current element as int * @throws NumberFormatException if current element is not a valid representation of number */ val int: Int get() = content.toInt() /** * Returns content of current element as int or `null` if current element is not a valid representation of number **/ val intOrNull: Int? get() = content.toIntOrNull() /** * Returns content of current element as long * @throws NumberFormatException if current element is not a valid representation of number */ val long: Long get() = content.toLong() /** * Returns content of current element as long or `null` if current element is not a valid representation of number */ val longOrNull: Long? get() = content.toLongOrNull() /** * Returns content of current element as double * @throws NumberFormatException if current element is not a valid representation of number */ val double: Double get() = content.toDouble() /** * Returns content of current element as double or `null` if current element is not a valid representation of number */ val doubleOrNull: Double? get() = content.toDoubleOrNull() /** * Returns content of current element as float * @throws NumberFormatException if current element is not a valid representation of number */ val float: Float get() = content.toFloat() /** * Returns content of current element as float or `null` if current element is not a valid representation of number */ val floatOrNull: Float? get() = content.toFloatOrNull() /** * Returns content of current element as boolean * @throws IllegalStateException if current element doesn't represent boolean */ val boolean: Boolean get() = content.toBooleanStrict() /** * Returns content of current element as boolean or `null` if current element is not a valid representation of boolean */ val booleanOrNull: Boolean? get() = content.toBooleanStrictOrNull() override fun toString() = content } /** * Class representing JSON literals: numbers, booleans and string. * Strings are always quoted. */ data class JsonLiteral internal constructor( private val body: Any, private val isString: Boolean ) : JsonPrimitive() { override val content = body.toString() override val contentOrNull: String = content /** * Creates number literal */ constructor(number: Number) : this(number, false) /** * Creates boolean literal */ constructor(boolean: Boolean) : this(boolean, false) /** * Creates quoted string literal */ constructor(string: String) : this(string, true) override fun toString() = if (isString) buildString { printQuoted(content) } else content fun unquoted() = content } /** * Class representing JSON `null` value */ object JsonNull : JsonPrimitive() { override val jsonNull: JsonNull = this override val content: String = "null" override val contentOrNull: String? = null } /** * Class representing JSON object, consisting of name-value pairs, where value is arbitrary [JsonElement] */ data class JsonObject(val content: Map) : JsonElement(), Map by content { override val jsonObject: JsonObject = this /** * Returns [JsonElement] associated with given [key] * @throws NoSuchElementException if element is not present */ override fun get(key: String): JsonElement = content[key] ?: throw NoSuchElementException("Element $key is missing") /** * Returns [JsonElement] associated with given [key] or `null` if element is not present */ fun getOrNull(key: String): JsonElement? = content[key] /** * Returns [JsonPrimitive] associated with given [key] * * @throws NoSuchElementException if element is not present * @throws JsonElementTypeMismatchException if element is present, but has invalid type */ fun getPrimitive(key: String): JsonPrimitive = get(key) as? JsonPrimitive ?: unexpectedJson(key, "JsonPrimitive") /** * Returns [JsonObject] associated with given [key] * * @throws NoSuchElementException if element is not present * @throws JsonElementTypeMismatchException if element is present, but has invalid type */ fun getObject(key: String): JsonObject = get(key) as? JsonObject ?: unexpectedJson(key, "JsonObject") /** * Returns [JsonArray] associated with given [key] * * @throws NoSuchElementException if element is not present * @throws JsonElementTypeMismatchException if element is present, but has invalid type */ fun getArray(key: String): JsonArray = get(key) as? JsonArray ?: unexpectedJson(key, "JsonArray") /** * Returns [JsonPrimitive] associated with given [key] or `null` if element * is not present or has different type */ fun getPrimitiveOrNull(key: String): JsonPrimitive? = content[key] as? JsonPrimitive /** * Returns [JsonObject] associated with given [key] or `null` if element * is not present or has different type */ fun getObjectOrNull(key: String): JsonObject? = content[key] as? JsonObject /** * Returns [JsonArray] associated with given [key] or `null` if element * is not present or has different type */ fun getArrayOrNull(key: String): JsonArray? = content[key] as? JsonArray /** * Returns [J] associated with given [key] * * @throws NoSuchElementException if element is not present * @throws JsonElementTypeMismatchException if element is present, but has invalid type */ inline fun getAs(key: String): J = get(key) as? J ?: unexpectedJson(key, J::class.toString()) /** * Returns [J] associated with given [key] or `null` if element * is not present or has different type */ inline fun lookup(key: String): J? = content[key] as? J override fun toString(): String { return content.entries.joinToString( prefix = "{", postfix = "}", transform = {(k, v) -> """"$k": $v"""} ) } } data class JsonArray(val content: List) : JsonElement(), List by content { override val jsonArray: JsonArray = this /** * Returns [index]-th element of an array as [JsonPrimitive] * @throws JsonElementTypeMismatchException if element has invalid type */ fun getPrimitive(index: Int) = content[index] as? JsonPrimitive ?: unexpectedJson("at $index", "JsonPrimitive") /** * Returns [index]-th element of an array as [JsonObject] * @throws JsonElementTypeMismatchException if element has invalid type */ fun getObject(index: Int) = content[index] as? JsonObject ?: unexpectedJson("at $index", "JsonObject") /** * Returns [index]-th element of an array as [JsonArray] * @throws JsonElementTypeMismatchException if element has invalid type */ fun getArray(index: Int) = content[index] as? JsonArray ?: unexpectedJson("at $index", "JsonArray") /** * Returns [index]-th element of an array as [JsonPrimitive] or `null` if element is missing or has different type */ fun getPrimitiveOrNull(index: Int) = content.getOrNull(index) as? JsonPrimitive /** * Returns [index]-th element of an array as [JsonObject] or `null` if element is missing or has different type */ fun getObjectOrNull(index: Int) = content.getOrNull(index) as? JsonObject /** * Returns [index]-th element of an array as [JsonArray] or `null` if element is missing or has different type */ fun getArrayOrNull(index: Int) = content.getOrNull(index) as? JsonArray /** * Returns [index]-th element of an array as [J] * @throws JsonElementTypeMismatchException if element has invalid type */ inline fun getAs(index: Int): J = content[index] as? J ?: unexpectedJson("at $index", J::class.toString()) /** * Returns [index]-th element of an array as [J] or `null` if element is missing or has different type */ inline fun getAsOrNull(index: Int): J? = content.getOrNull(index) as? J override fun toString() = content.joinToString(prefix = "[", postfix = "]") } fun unexpectedJson(key: String, expected: String): Nothing = throw JsonElementTypeMismatchException(key, expected) ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/JsonExceptions.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.report.json class JsonInvalidValueInStrictModeException(value: Any, valueDescription: String) : Exception( "$value is not a valid $valueDescription as per JSON spec.\n" + "You can disable strict mode to serialize such values" ) { constructor(floatValue: Float) : this(floatValue, "float") constructor(doubleValue: Double) : this(doubleValue, "double") } class JsonUnknownKeyException(key: String) : Exception( "Strict JSON encountered unknown key: $key\n" + "You can disable strict mode to skip unknown keys" ) class JsonParsingException(position: Int, message: String) : Exception("Invalid JSON at $position: $message") class JsonElementTypeMismatchException(key: String, expected: String) : Exception("Element $key is not a $expected") ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/JsonParser.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.report.json import org.jetbrains.report.json.EscapeCharMappings.ESC2C // special strings internal const val NULL = "null" // special chars internal const val COMMA = ',' internal const val COLON = ':' internal const val BEGIN_OBJ = '{' internal const val END_OBJ = '}' internal const val BEGIN_LIST = '[' internal const val END_LIST = ']' internal const val STRING = '"' internal const val STRING_ESC = '\\' internal const val INVALID = 0.toChar() internal const val UNICODE_ESC = 'u' // token classes internal const val TC_OTHER: Byte = 0 internal const val TC_STRING: Byte = 1 internal const val TC_STRING_ESC: Byte = 2 internal const val TC_WS: Byte = 3 internal const val TC_COMMA: Byte = 4 internal const val TC_COLON: Byte = 5 internal const val TC_BEGIN_OBJ: Byte = 6 internal const val TC_END_OBJ: Byte = 7 internal const val TC_BEGIN_LIST: Byte = 8 internal const val TC_END_LIST: Byte = 9 internal const val TC_NULL: Byte = 10 internal const val TC_INVALID: Byte = 11 internal const val TC_EOF: Byte = 12 // mapping from chars to token classes private const val CTC_MAX = 0x7e // mapping from escape chars real chars private const val C2ESC_MAX = 0x5d private const val ESC2C_MAX = 0x75 internal val C2TC = ByteArray(CTC_MAX).apply { for (i in 0..0x20) initC2TC(i, TC_INVALID) initC2TC(0x09, TC_WS) initC2TC(0x0a, TC_WS) initC2TC(0x0d, TC_WS) initC2TC(0x20, TC_WS) initC2TC(COMMA, TC_COMMA) initC2TC(COLON, TC_COLON) initC2TC(BEGIN_OBJ, TC_BEGIN_OBJ) initC2TC(END_OBJ, TC_END_OBJ) initC2TC(BEGIN_LIST, TC_BEGIN_LIST) initC2TC(END_LIST, TC_END_LIST) initC2TC(STRING, TC_STRING) initC2TC(STRING_ESC, TC_STRING_ESC) } // object instead of @SharedImmutable because there is mutual initialization in [initC2ESC] internal object EscapeCharMappings { internal val ESC2C = CharArray(ESC2C_MAX) internal val C2ESC = CharArray(C2ESC_MAX).apply { for (i in 0x00..0x1f) initC2ESC(i, UNICODE_ESC) initC2ESC(0x08, 'b') initC2ESC(0x09, 't') initC2ESC(0x0a, 'n') initC2ESC(0x0c, 'f') initC2ESC(0x0d, 'r') initC2ESC('/', '/') initC2ESC(STRING, STRING) initC2ESC(STRING_ESC, STRING_ESC) } private fun CharArray.initC2ESC(c: Int, esc: Char) { this[c] = esc if (esc != UNICODE_ESC) ESC2C[esc.toInt()] = c.toChar() } private fun CharArray.initC2ESC(c: Char, esc: Char) = initC2ESC(c.toInt(), esc) } private fun ByteArray.initC2TC(c: Int, cl: Byte) { this[c] = cl } private fun ByteArray.initC2TC(c: Char, cl: Byte) { initC2TC(c.toInt(), cl) } internal fun charToTokenClass(c: Char) = if (c.toInt() < CTC_MAX) C2TC[c.toInt()] else TC_OTHER internal fun escapeToChar(c: Int): Char = if (c < ESC2C_MAX) ESC2C[c] else INVALID // JSON low level parser internal class Parser(val source: String) { var curPos: Int = 0 // position in source private set // updated by nextToken var tokenPos: Int = 0 private set var tc: Byte = TC_EOF private set // update by nextString/nextLiteral private var offset = -1 // when offset >= 0 string is in source, otherwise in buf private var length = 0 // length of string private var buf = CharArray(16) // only used for strings with escapes init { nextToken() } internal inline fun requireTc(expected: Byte, lazyErrorMsg: () -> String) { if (tc != expected) fail(tokenPos, lazyErrorMsg()) } val canBeginValue: Boolean get() = when (tc) { TC_BEGIN_LIST, TC_BEGIN_OBJ, TC_OTHER, TC_STRING, TC_NULL -> true else -> false } @OptIn(ExperimentalStdlibApi::class) fun takeStr(): String { if (tc != TC_OTHER && tc != TC_STRING) fail(tokenPos, "Expected string or non-null literal") val prevStr = if (offset < 0) buf.concatToString(0, length) else source.substring(offset, offset + length) nextToken() return prevStr } private fun append(ch: Char) { if (length >= buf.size) buf = buf.copyOf(2 * buf.size) buf[length++] = ch } // initializes buf usage upon the first encountered escaped char private fun appendRange(source: String, fromIndex: Int, toIndex: Int) { val addLen = toIndex - fromIndex val oldLen = length val newLen = oldLen + addLen if (newLen > buf.size) buf = buf.copyOf(newLen.coerceAtLeast(2 * buf.size)) for (i in 0 until addLen) buf[oldLen + i] = source[fromIndex + i] length += addLen } fun nextToken() { val source = source var curPos = curPos val maxLen = source.length while (true) { if (curPos >= maxLen) { tokenPos = curPos tc = TC_EOF return } val ch = source[curPos] val tc = charToTokenClass(ch) when (tc) { TC_WS -> curPos++ // skip whitespace TC_OTHER -> { nextLiteral(source, curPos) return } TC_STRING -> { nextString(source, curPos) return } else -> { this.tokenPos = curPos this.tc = tc this.curPos = curPos + 1 return } } } } private fun nextLiteral(source: String, startPos: Int) { tokenPos = startPos offset = startPos var curPos = startPos val maxLen = source.length while (true) { curPos++ if (curPos >= maxLen || charToTokenClass(source[curPos]) != TC_OTHER) break } this.curPos = curPos length = curPos - offset tc = if (rangeEquals(source, offset, length, NULL)) TC_NULL else TC_OTHER } private fun nextString(source: String, startPos: Int) { tokenPos = startPos length = 0 // in buffer var curPos = startPos + 1 var lastPos = curPos val maxLen = source.length parse@ while (true) { if (curPos >= maxLen) fail(curPos, "Unexpected end in string") if (source[curPos] == STRING) { break@parse } else if (source[curPos] == STRING_ESC) { appendRange(source, lastPos, curPos) val newPos = appendEsc(source, curPos + 1) curPos = newPos lastPos = newPos } else { curPos++ } } if (lastPos == startPos + 1) { // there was no escaped chars this.offset = lastPos this.length = curPos - lastPos } else { // some escaped chars were there appendRange(source, lastPos, curPos) this.offset = -1 } this.curPos = curPos + 1 tc = TC_STRING } private fun appendEsc(source: String, startPos: Int): Int { var curPos = startPos require(curPos < source.length, curPos) { "Unexpected end after escape char" } val curChar = source[curPos++] if (curChar == UNICODE_ESC) { curPos = appendHex(source, curPos) } else { val c = escapeToChar(curChar.toInt()) require(c != INVALID, curPos) { "Invalid escaped char '$curChar'" } append(c) } return curPos } private fun appendHex(source: String, startPos: Int): Int { var curPos = startPos append( ((fromHexChar(source, curPos++) shl 12) + (fromHexChar(source, curPos++) shl 8) + (fromHexChar(source, curPos++) shl 4) + fromHexChar(source, curPos++)).toChar() ) return curPos } fun skipElement() { if (tc != TC_BEGIN_OBJ && tc != TC_BEGIN_LIST) { nextToken() return } val tokenStack = mutableListOf() do { when (tc) { TC_BEGIN_LIST, TC_BEGIN_OBJ -> tokenStack.add(tc) TC_END_LIST -> { if (tokenStack.last() != TC_BEGIN_LIST) throw JsonParsingException(curPos, "found ] instead of }") tokenStack.removeAt(tokenStack.size - 1) } TC_END_OBJ -> { if (tokenStack.last() != TC_BEGIN_OBJ) throw JsonParsingException(curPos, "found } instead of ]") tokenStack.removeAt(tokenStack.size - 1) } } nextToken() } while (tokenStack.isNotEmpty()) } } // Utility functions private fun fromHexChar(source: String, curPos: Int): Int { require(curPos < source.length, curPos) { "Unexpected end in unicode escape" } val curChar = source[curPos] return when (curChar) { in '0'..'9' -> curChar.toInt() - '0'.toInt() in 'a'..'f' -> curChar.toInt() - 'a'.toInt() + 10 in 'A'..'F' -> curChar.toInt() - 'A'.toInt() + 10 else -> fail(curPos, "Invalid toHexChar char '$curChar' in unicode escape") } } private fun rangeEquals(source: String, start: Int, length: Int, str: String): Boolean { val n = str.length if (length != n) return false for (i in 0 until n) if (source[start + i] != str[i]) return false return true } internal inline fun require(condition: Boolean, pos: Int, msg: () -> String) { if (!condition) fail(pos, msg()) } @Suppress("NOTHING_TO_INLINE") internal inline fun fail(pos: Int, msg: String): Nothing { throw JsonParsingException(pos, msg) } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/JsonTreeParser.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // A bit changed part of kotlinx.serialization plugin package org.jetbrains.report.json class JsonTreeParser internal constructor(private val p: Parser) { companion object { fun parse(input: String): JsonElement = JsonTreeParser(input).readFully() } constructor(input: String) : this(Parser(input)) private fun readObject(): JsonElement { p.requireTc(TC_BEGIN_OBJ) { "Expected start of object" } p.nextToken() val result: MutableMap = hashMapOf() while (true) { if (p.tc == TC_COMMA) p.nextToken() if (!p.canBeginValue) break val key = p.takeStr() p.requireTc(TC_COLON) { "Expected ':'" } p.nextToken() val elem = read() result[key] = elem } p.requireTc(TC_END_OBJ) { "Expected end of object" } p.nextToken() return JsonObject(result) } private fun readValue(isString: Boolean): JsonElement { val str = p.takeStr() return JsonLiteral(str, isString) } private fun readArray(): JsonElement { p.requireTc(TC_BEGIN_LIST) { "Expected start of array" } p.nextToken() val result: MutableList = arrayListOf() while (true) { if (p.tc == TC_COMMA) p.nextToken() if (!p.canBeginValue) break val elem = read() result.add(elem) } p.requireTc(TC_END_LIST) { "Expected end of array" } p.nextToken() return JsonArray(result) } fun read(): JsonElement { if (!p.canBeginValue) fail(p.curPos, "Can't begin reading value from here") val tc = p.tc return when (tc) { TC_NULL -> JsonNull.also { p.nextToken() } TC_STRING -> readValue(isString = true) TC_OTHER -> readValue(isString = false) TC_BEGIN_OBJ -> readObject() TC_BEGIN_LIST -> readArray() else -> fail(p.curPos, "Can't begin reading element") } } fun readFully(): JsonElement { val r = read() p.requireTc(TC_EOF) { "Input wasn't consumed fully" } return r } } ================================================ FILE: tools/benchmarks/shared/src/main/kotlin/report/json/StringOps.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.report.json private fun toHexChar(i: Int) : Char { val d = i and 0xf return if (d < 10) (d + '0'.toInt()).toChar() else (d - 10 + 'a'.toInt()).toChar() } private val ESCAPE_CHARS: Array = arrayOfNulls(128).apply { for (c in 0..0x1f) { val c1 = toHexChar(c shr 12) val c2 = toHexChar(c shr 8) val c3 = toHexChar(c shr 4) val c4 = toHexChar(c) this[c] = "\\u$c1$c2$c3$c4" } this['"'.toInt()] = "\\\"" this['\\'.toInt()] = "\\\\" this['\t'.toInt()] = "\\t" this['\b'.toInt()] = "\\b" this['\n'.toInt()] = "\\n" this['\r'.toInt()] = "\\r" this[0x0c] = "\\f" } internal fun StringBuilder.printQuoted(value: String) { append(STRING) var lastPos = 0 val length = value.length for (i in 0 until length) { val c = value[i].toInt() // Do not replace this constant with C2ESC_MAX (which is smaller than ESCAPE_CHARS size), // otherwise JIT won't eliminate range check and won't vectorize this loop if (c >= ESCAPE_CHARS.size) continue // no need to escape val esc = ESCAPE_CHARS[c] ?: continue append(value, lastPos, i) // flush prev append(esc) lastPos = i + 1 } append(value, lastPos, length) append(STRING) } /** * Returns `true` if the contents of this string is equal to the word "true", ignoring case, `false` if content equals "false", * and throws [IllegalStateException] otherwise. */ fun String.toBooleanStrict(): Boolean = toBooleanStrictOrNull() ?: throw IllegalStateException("$this does not represent a Boolean") /** * Returns `true` if the contents of this string is equal to the word "true", ignoring case, `false` if content equals "false", * and returns `null` otherwise. */ fun String.toBooleanStrictOrNull(): Boolean? = when { this.equals("true", ignoreCase = true) -> true this.equals("false", ignoreCase = true) -> false else -> null } ================================================ FILE: tools/benchmarksAnalyzer/build.gradle ================================================ buildscript { ext.rootBuildDirectory = file('../..') apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle" apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } apply plugin: 'kotlin-multiplatform' repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } maven { url buildKotlinCompilerRepo } } def getHostName() { def target = System.getProperty("os.name") if (target == 'Linux') return 'linux' if (target.startsWith('Windows')) return 'windows' if (target.startsWith('Mac')) return 'macos' return 'unknown' } kotlin { sourceSets { commonMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" } kotlin.srcDir '../benchmarks/shared/src' kotlin.srcDir 'src/main/kotlin' kotlin.srcDir '../../endorsedLibraries/kotlinx.cli/src/main/kotlin' } commonTest { dependencies { implementation "org.jetbrains.kotlin:kotlin-test-common:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlinVersion" } kotlin.srcDir 'src/tests' } jvmTest { dependencies { implementation "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion" } } jsTest { dependencies { implementation "org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion" } } nativeMain { dependsOn commonMain kotlin.srcDir 'src/main/kotlin-native' kotlin.srcDir '../../endorsedLibraries/kotlinx.cli/src/main/kotlin-native' } jvmMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" } kotlin.srcDir 'src/main/kotlin-jvm' kotlin.srcDir '../../endorsedLibraries/kotlinx.cli/src/main/kotlin-jvm' } jsMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" } kotlin.srcDir 'src/main/kotlin-js' kotlin.srcDir '../../endorsedLibraries/kotlinx.cli/src/main/kotlin-js' } linuxMain { dependsOn nativeMain } windowsMain { dependsOn nativeMain } macosMain {dependsOn nativeMain } } targets { fromPreset(presets.jvm, 'jvm') { compilations.all { tasks[compileKotlinTaskName].kotlinOptions { jvmTarget = '1.8' } tasks[compileKotlinTaskName].kotlinOptions.suppressWarnings = true } } fromPreset(presets.mingwX64, 'windows') { binaries.all { linkerOpts = ["-L${getMingwPath()}/lib".toString()] } compilations.main.cinterops { libcurl { includeDirs.headerFilterOnly "${getMingwPath()}/include" } } } fromPreset(presets.linuxX64, 'linux') { compilations.main.cinterops { libcurl { includeDirs.headerFilterOnly '/usr/include', '/usr/include/x86_64-linux-gnu' } } } fromPreset(presets.macosX64, 'macos') { compilations.main.cinterops { libcurl { includeDirs.headerFilterOnly '/opt/local/include', '/usr/local/include' } } } fromPreset(presets.js, 'js') { compilations.main.kotlinOptions { main = "noCall" } } configure([windows, linux, macos]) { def isCurrentHost = (name == getHostName()) compilations.all { cinterops.all { project.tasks[interopProcessingTaskName].enabled = isCurrentHost } compileKotlinTask.enabled = isCurrentHost } binaries.all { linkTask.enabled = isCurrentHost } binaries { executable('benchmarksAnalyzer', [RELEASE]) { if (org.gradle.internal.os.OperatingSystem.current().isWindows()) { linkerOpts("-L${getMingwPath()}/lib") } } } } } js { browser { distribution { directory = new File("$projectDir/web/") } dceTask { keep 'benchmarksAnalyzer.main_kand9s$' } } } } def getMingwPath() { def directory = System.getenv("MINGW64_DIR") if (directory == null) directory = "c:/msys64/mingw64" return directory } task assembleWeb(type: Sync) { def runtimeDependencies = kotlin.targets.js.compilations.main.runtimeDependencyFiles from(files { runtimeDependencies.collect { File file -> zipTree(file.absolutePath) } }.builtBy(runtimeDependencies)) { includeEmptyDirs = false include { fileTreeElement -> def path = fileTreeElement.path path.endsWith(".js") && (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/")) } } from compileKotlinJs.destinationDir into "${projectDir}/web" } ================================================ FILE: tools/benchmarksAnalyzer/gradle.properties ================================================ org.jetbrains.kotlin.native.home=../../dist org.gradle.jvmargs=-Xmx2048m # Avoid building platform libraries by the MPP plugin. kotlin.native.distribution.type=prebuilt ================================================ FILE: tools/benchmarksAnalyzer/settings.gradle ================================================ ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlinx.cli.* import org.jetbrains.analyzer.sendGetRequest import org.jetbrains.analyzer.readFile import org.jetbrains.analyzer.SummaryBenchmarksReport import org.jetbrains.renders.* import org.jetbrains.report.* import org.jetbrains.report.json.* abstract class Connector { abstract val connectorPrefix: String fun isCompatible(fileName: String) = fileName.startsWith(connectorPrefix) abstract fun getFileContent(fileLocation: String, user: String? = null): String } object ArtifactoryConnector : Connector() { override val connectorPrefix = "artifactory:" val artifactoryUrl = "https://repo.labs.intellij.net/kotlin-native-benchmarks" override fun getFileContent(fileLocation: String, user: String?): String { val fileParametersSize = 3 val fileDescription = fileLocation.substringAfter(connectorPrefix) val fileParameters = fileDescription.split(':', limit = fileParametersSize) // Right link to Artifactory file. if (fileParameters.size == 1) { val accessFileUrl = "$artifactoryUrl/${fileParameters[0]}" return sendGetRequest(accessFileUrl, followLocation = true) } // Used builds description format. if (fileParameters.size != fileParametersSize) { error("To get file from Artifactory, please, specify, build number from TeamCity and target" + " in format artifactory:build_number:target:filename") } val (buildNumber, target, fileName) = fileParameters val accessFileUrl = "$artifactoryUrl/$target/$buildNumber/$fileName" return sendGetRequest(accessFileUrl, followLocation = true) } } object TeamCityConnector : Connector() { override val connectorPrefix = "teamcity:" val teamCityUrl = "http://buildserver.labs.intellij.net" override fun getFileContent(fileLocation: String, user: String?): String { val fileDescription = fileLocation.substringAfter(connectorPrefix) val buildLocator = fileDescription.substringBeforeLast(':') val fileName = fileDescription.substringAfterLast(':') if (fileDescription == fileLocation || fileDescription == buildLocator || fileName == fileDescription) { error("To get file from TeamCity, please, specify, build locator and filename on TeamCity" + " in format teamcity:build_locator:filename") } val accessFileUrl = "$teamCityUrl/app/rest/builds/$buildLocator/artifacts/content/$fileName" val userName = user?.substringBefore(':') val password = user?.substringAfter(':') return sendGetRequest(accessFileUrl, userName, password) } } object DBServerConnector : Connector() { override val connectorPrefix = "" val serverUrl = "https://kotlin-native-perf-summary.labs.jb.gg" override fun getFileContent(fileLocation: String, user: String?): String { val buildNumber = fileLocation.substringBefore(':') val target = fileLocation.substringAfter(':') if (target == buildNumber) { error("To get file from database, please, specify, target and build number" + " in format target:build_number") } val accessFileUrl = "$serverUrl/report/$target/$buildNumber" return sendGetRequest(accessFileUrl) } fun getUnstableBenchmarks(): List? { try { val unstableList = sendGetRequest("$serverUrl/unstable") val data = JsonTreeParser.parse(unstableList) if (data !is JsonArray) { return null } return data.jsonArray.map { (it as JsonPrimitive).content } } catch (e: Exception) { return null } } } fun getFileContent(fileName: String, user: String? = null): String { return when { ArtifactoryConnector.isCompatible(fileName) -> ArtifactoryConnector.getFileContent(fileName, user) TeamCityConnector.isCompatible(fileName) -> TeamCityConnector.getFileContent(fileName, user) fileName.endsWith(".json") -> readFile(fileName) else -> DBServerConnector.getFileContent(fileName, user) } } fun getBenchmarkReport(fileName: String, user: String? = null): List { val jsonEntity = JsonTreeParser.parse(getFileContent(fileName, user)) return when (jsonEntity) { is JsonObject -> listOf(BenchmarksReport.create(jsonEntity)) is JsonArray -> jsonEntity.map { BenchmarksReport.create(it) } else -> error("Wrong format of report. Expected object or array of objects.") } } fun parseNormalizeResults(results: String): Map> { val parsedNormalizeResults = mutableMapOf>() val tokensNumber = 3 results.lines().forEach { if (!it.isEmpty()) { val tokens = it.split(",").map { it.trim() } if (tokens.size != tokensNumber) { error("Data for normalization should include benchmark name, metric name and value. Got $it") } parsedNormalizeResults.getOrPut(tokens[0], { mutableMapOf() })[tokens[1]] = tokens[2].toDouble() } } return parsedNormalizeResults } fun mergeCompilerFlags(reports: List): List { val flagsMap = mutableMapOf>() reports.forEach { val benchmarks = it.benchmarks.values.flatten().asSequence().filter { it.metric == BenchmarkResult.Metric.COMPILE_TIME } .map { it.shortName }.toList() if (benchmarks.isNotEmpty()) (flagsMap.getOrPut("${it.compiler.backend.flags.joinToString()}") { mutableListOf() }).addAll(benchmarks) } return flagsMap.map { (flags, benchmarks) -> "$flags for [${benchmarks.distinct().sorted().joinToString()}]" } } fun mergeReportsWithDetailedFlags(reports: List) = if (reports.size > 1) { // Merge reports. val detailedFlags = mergeCompilerFlags(reports) reports.map { BenchmarksReport(it.env, it.benchmarks.values.flatten(), Compiler(Compiler.Backend(it.compiler.backend.type, it.compiler.backend.version, detailedFlags), it.compiler.kotlinVersion)) }.reduce { result, it -> result + it } } else { reports.first() } fun main(args: Array) { // Parse args. val argParser = ArgParser("benchmarksAnalyzer") val mainReport by argParser.argument(ArgType.String, description = "Main report for analysis") val compareToReport by argParser.argument(ArgType.String, description = "Report to compare to").optional() val output by argParser.option(ArgType.String, shortName = "o", description = "Output file") val epsValue by argParser.option(ArgType.Double, "eps", "e", "Meaningful performance changes").default(1.0) val useShortForm by argParser.option(ArgType.Boolean, "short", "s", "Show short version of report").default(false) val renders by argParser.option(ArgType.Choice(), shortName = "r", description = "Renders for showing information").multiple().default(listOf(RenderType.TEXT)) val user by argParser.option(ArgType.String, shortName = "u", description = "User access information for authorization") argParser.parse(args) // Get unstable benchmarks. val unstableBenchmarks = DBServerConnector.getUnstableBenchmarks() unstableBenchmarks ?: println("Failed to get access to server and get unstable benchmarks list!") // Read contents of file. val mainBenchsReport = mergeReportsWithDetailedFlags(getBenchmarkReport(mainReport, user)) var compareToBenchsReport = compareToReport?.let { mergeReportsWithDetailedFlags(getBenchmarkReport(it, user)) } // Generate comparasion report. val summaryReport = SummaryBenchmarksReport(mainBenchsReport, compareToBenchsReport, epsValue, unstableBenchmarks ?: emptyList()) var outputFile = output renders.forEach { it.createRender().print(summaryReport, useShortForm, outputFile) outputFile = null } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/HTMLRender.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.* import kotlin.math.sin import kotlin.math.abs import kotlin.math.pow private fun > clamp(value: T, minValue: T, maxValue: T): T = minOf(maxOf(value, minValue), maxValue) // Natural number. class Natural(initValue: Int) { val value = if (initValue > 0) initValue else error("Provided value $initValue isn't natural") override fun toString(): String { return value.toString() } } interface Element { fun render(builder: StringBuilder, indent: String) } class TextElement(val text: String) : Element { override fun render(builder: StringBuilder, indent: String) { builder.append("$indent$text\n") } } @DslMarker annotation class HtmlTagMarker @HtmlTagMarker abstract class Tag(val name: String) : Element { val children = arrayListOf() val attributes = hashMapOf() protected fun initTag(tag: T, init: T.() -> Unit): T { tag.init() children.add(tag) return tag } override fun render(builder: StringBuilder, indent: String) { builder.append("$indent<$name${renderAttributes()}>\n") for (c in children) { c.render(builder, indent + " ") } builder.append("$indent\n") } private fun renderAttributes(): String = attributes.map { (attr, value) -> "$attr=\"$value\"" }.joinToString(separator = " ", prefix = " ") override fun toString(): String { val builder = StringBuilder() render(builder, "") return builder.toString() } } abstract class TagWithText(name: String) : Tag(name) { operator fun String.unaryPlus() { children.add(TextElement(this)) } } class HTML : TagWithText("html") { fun head(init: Head.() -> Unit) = initTag(Head(), init) fun body(init: Body.() -> Unit) = initTag(Body(), init) } class Head : TagWithText("head") { fun title(init: Title.() -> Unit) = initTag(Title(), init) fun link(init: Link.() -> Unit) = initTag(Link(), init) fun script(init: Script.() -> Unit) = initTag(Script(), init) } class Title : TagWithText("title") class Link : TagWithText("link") class Script : TagWithText("script") abstract class BodyTag(name: String) : TagWithText(name) { fun b(init: B.() -> Unit) = initTag(B(), init) fun p(init: P.() -> Unit) = initTag(P(), init) fun h1(init: H1.() -> Unit) = initTag(H1(), init) fun h2(init: H2.() -> Unit) = initTag(H2(), init) fun h4(init: H4.() -> Unit) = initTag(H4(), init) fun hr(init: HR.() -> Unit) = initTag(HR(), init) fun a(href: String, init: A.() -> Unit) { val a = initTag(A(), init) a.href = href } fun img(src: String, init: Image.() -> Unit) { val element = initTag(Image(), init) element.src = src } fun table(init: Table.() -> Unit) = initTag(Table(), init) fun div(classAttr: String, init: Div.() -> Unit) = initTag(Div(classAttr), init) fun button(classAttr: String, init: Button.() -> Unit) = initTag(Button(classAttr), init) fun header(classAttr: String, init: Header.() -> Unit) = initTag(Header(classAttr), init) fun span(classAttr: String, init: Span.() -> Unit) = initTag(Span(classAttr), init) } abstract class BodyTagWithClass(name: String, val classAttr: String) : BodyTag(name) { init { attributes["class"] = classAttr } } class Body : BodyTag("body") class B : BodyTag("b") class P : BodyTag("p") class H1 : BodyTag("h1") class H2 : BodyTag("h2") class H4 : BodyTag("h4") class HR : BodyTag("hr") class Div(classAttr: String) : BodyTagWithClass("div", classAttr) class Header(classAttr: String) : BodyTagWithClass("header", classAttr) class Button(classAttr: String) : BodyTagWithClass("button", classAttr) class Span(classAttr: String) : BodyTagWithClass("span", classAttr) class A : BodyTag("a") { var href: String by attributes } class Image : BodyTag("img") { var src: String by attributes } abstract class TableTag(name: String) : BodyTag(name) { fun thead(init: THead.() -> Unit) = initTag(THead(), init) fun tbody(init: TBody.() -> Unit) = initTag(TBody(), init) fun tfoot(init: TFoot.() -> Unit) = initTag(TFoot(), init) } abstract class TableBlock(name: String) : TableTag(name) { fun tr(init: TableRow.() -> Unit) = initTag(TableRow(), init) } class Table : TableTag("table") class THead : TableBlock("thead") class TFoot : TableBlock("tfoot") class TBody : TableBlock("tbody") abstract class TableRowTag(name: String) : TableBlock(name) { var colspan = Natural(1) set(value) { attributes["colspan"] = value.toString() } var rowspan = Natural(1) set(value) { attributes["rowspan"] = value.toString() } fun th(rowspan: Natural = Natural(1), colspan: Natural = Natural(1), init: TableHeadInfo.() -> Unit) { val element = initTag(TableHeadInfo(), init) element.rowspan = rowspan element.colspan = colspan } fun td(rowspan: Natural = Natural(1), colspan: Natural = Natural(1), init: TableDataInfo.() -> Unit) { val element = initTag(TableDataInfo(), init) element.rowspan = rowspan element.colspan = colspan } } class TableRow : TableRowTag("tr") class TableHeadInfo : TableRowTag("th") class TableDataInfo : TableRowTag("td") fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html } // Report render to html format. class HTMLRender: Render() { override val name: String get() = "html" override fun render (report: SummaryBenchmarksReport, onlyChanges: Boolean) = html { head { title { +"Benchmarks report" } // Links to bootstrap files. link { attributes["href"] = "https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" attributes["rel"] = "stylesheet" } script { attributes["src"] = "https://code.jquery.com/jquery-3.3.1.slim.min.js" } script { attributes["src"] = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" } script { attributes["src"] = "https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" } } body { header("navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar") { attributes["style"] = "background-color:#161616;" img("https://dashboard.snapcraft.io/site_media/appmedia/2018/04/256px-kotlin-logo-svg.png") { attributes["style"] = "width:60px;height:60px;" } span("navbar-brand mb-0 h1") { +"Benchmarks report" } } div("container-fluid") { p{} renderEnvironmentTable(report.environments) renderCompilerTable(report.compilers) hr {} renderStatusSummary(report) hr {} renderPerformanceSummary(report) renderPerformanceDetails(report, onlyChanges) } } }.toString() private fun TableRowTag.formatComparedTableData(data: String, compareToData: String?) { td { compareToData?. let { // Highlight changed data. if (it != data) attributes["bgcolor"] = "yellow" } if (data.isEmpty()) { +"-" } else { +data } } } private fun TableTag.renderEnvironment(environment: Environment, name: String, compareTo: Environment? = null) { tbody { tr { th { attributes["scope"] = "row" +name } formatComparedTableData(environment.machine.os, compareTo?.machine?.os) formatComparedTableData(environment.machine.cpu, compareTo?.machine?.cpu) formatComparedTableData(environment.jdk.version, compareTo?.jdk?.version) formatComparedTableData(environment.jdk.vendor, compareTo?.jdk?.vendor) } } } private fun BodyTag.renderEnvironmentTable(environments: Pair) { h4 { +"Environment" } table { attributes["class"] = "table table-sm table-bordered table-hover" attributes["style"] = "width:initial;" val firstEnvironment = environments.first val secondEnvironment = environments.second // Table header. thead { tr { th(rowspan = Natural(2)) { +"Run" } th(colspan = Natural(2)) { +"Machine" } th(colspan = Natural(2)) { +"JDK" } } tr { th { + "OS" } th { + "CPU" } th { + "Version"} th { + "Vendor"} } } renderEnvironment(firstEnvironment, "First") secondEnvironment?. let { renderEnvironment(it, "Second", firstEnvironment) } } } private fun TableTag.renderCompiler(compiler: Compiler, name: String, compareTo: Compiler? = null) { tbody { tr { th { attributes["scope"] = "row" +name } formatComparedTableData(compiler.backend.type.type, compareTo?.backend?.type?.type) formatComparedTableData(compiler.backend.version, compareTo?.backend?.version) formatComparedTableData(compiler.backend.flags.joinToString(), compareTo?.backend?.flags?.joinToString()) formatComparedTableData(compiler.kotlinVersion, compareTo?.kotlinVersion) } } } private fun BodyTag.renderCompilerTable(compilers: Pair) { h4 { +"Compiler" } table { attributes["class"] = "table table-sm table-bordered table-hover" attributes["style"] = "width:initial;" val firstCompiler = compilers.first val secondCompiler = compilers.second // Table header. thead { tr { th(rowspan = Natural(2)) { +"Run" } th(colspan = Natural(3)) { +"Backend" } th(rowspan = Natural(2)) { +"Kotlin" } } tr { th { + "Type" } th { + "Version" } th { + "Flags"} } } renderCompiler(firstCompiler, "First") secondCompiler?. let { renderCompiler(it, "Second", firstCompiler) } } } private fun TableBlock.renderBucketInfo(bucket: Collection, name: String) { if (!bucket.isEmpty()) { tr { th { attributes["scope"] = "row" +name } td { +"${bucket.size}" } } } } private fun BodyTag.renderCollapsedData(name: String, isCollapsed: Boolean = false, colorStyle: String = "", init: BodyTag.() -> Unit) { val show = if (!isCollapsed) "show" else "" val tagName = name.replace(' ', '_') div("accordion") { div("card") { attributes["style"] = "border-bottom: 1px solid rgba(0,0,0,.125);" div("card-header") { attributes["id"] = "heading" attributes["style"] = "padding: 0;$colorStyle" button("btn btn-link") { attributes["data-toggle"] = "collapse" attributes["data-target"] = "#$tagName" +name } } div("collapse $show") { attributes["id"] = tagName div("accordion-inner") { init() } } } } } private fun TableTag.renderTableFromList(list: List, name: String) { if (!list.isEmpty()) { thead { tr { th { +name } } } list.forEach { tbody { tr { td { +it } } } } } } private fun BodyTag.renderStatusSummary(report: SummaryBenchmarksReport) { h4 { +"Status Summary" } val failedBenchmarks = report.failedBenchmarks if (failedBenchmarks.isEmpty()) { div("alert alert-success") { attributes["role"] = "alert" +"All benchmarks passed!" } } else { div("alert alert-danger") { attributes["role"] = "alert" +"There are failed benchmarks!" } } val benchmarksWithChangedStatus = report.benchmarksWithChangedStatus val newFailures = benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.FAILED } val newPasses = benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.PASSED } table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial; font-size: 11pt;" thead { tr { th { +"Status Group" } th { +"#" } } } tbody { renderBucketInfo(failedBenchmarks, "Failed (total)") renderBucketInfo(newFailures, "New Failures") renderBucketInfo(newPasses, "New Passes") renderBucketInfo(report.addedBenchmarks, "Added") renderBucketInfo(report.removedBenchmarks, "Removed") } tfoot { tr { th { +"Total becnhmarks number" } th { +"${report.benchmarksNumber}" } } } } if (!failedBenchmarks.isEmpty()) { renderCollapsedData("Failures", colorStyle = "background-color: lightpink") { table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial; font-size: 11pt;" val newFailuresList = newFailures.map { it.field } renderTableFromList(newFailuresList, "New Failures") val existingFailures = failedBenchmarks.filter { it !in newFailuresList } renderTableFromList(existingFailures, "Existing Failures") } } } if (!newPasses.isEmpty()) { renderCollapsedData("New Passes", colorStyle = "background-color: lightgreen") { table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial; font-size: 11pt;" renderTableFromList(newPasses.map { it.field }, "New Passes") } } } if (!report.addedBenchmarks.isEmpty()) { renderCollapsedData("Added", true) { table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial; font-size: 11pt;" renderTableFromList(report.addedBenchmarks, "Added benchmarks") } } } if (!report.removedBenchmarks.isEmpty()) { renderCollapsedData("Removed", true) { table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial; font-size: 11pt;" renderTableFromList(report.removedBenchmarks, "Removed benchmarks") } } } } private fun BodyTag.renderPerformanceSummary(report: SummaryBenchmarksReport) { if (report.detailedMetricReports.values.any { it.improvements.isNotEmpty() } || report.detailedMetricReports.values.any { it.regressions.isNotEmpty() }) { h4 { +"Performance Summary" } table { attributes["class"] = "table table-sm table-striped table-hover" attributes["style"] = "width:initial;" thead { tr { th(rowspan = Natural(2)) { +"Change" } report.detailedMetricReports.forEach { (metric, _) -> th(colspan = Natural(3)) { +metric.value } } } tr { report.detailedMetricReports.forEach { _ -> th { +"#" } th { +"Maximum" } th { +"Geometric mean" } } } } tbody { tr { th { +"Regressions" } report.detailedMetricReports.values.forEach { report -> val maximumRegression = report.maximumRegression val regressionsGeometricMean = report.regressionsGeometricMean val maximumImprovement = report.maximumImprovement val improvementsGeometricMean = report.improvementsGeometricMean val maximumChange = maxOf(maximumRegression, abs(maximumImprovement)) val maximumChangeGeoMean = maxOf(regressionsGeometricMean, abs(improvementsGeometricMean)) if (!report.regressions.isEmpty()) { td { +"${report.regressions.size}" } td { attributes["bgcolor"] = ColoredCell( (maximumRegression/maximumChange).takeIf{ maximumChange > 0.0 } ).backgroundStyle +formatValue(maximumRegression, true) } td { attributes["bgcolor"] = ColoredCell( (regressionsGeometricMean/maximumChangeGeoMean).takeIf{ maximumChangeGeoMean > 0.0 } ).backgroundStyle +formatValue(report.regressionsGeometricMean, true) } } else { repeat(3) { td { +"-" } } } } tr { th { +"Improvements" } report.detailedMetricReports.values.forEach { report -> val maximumRegression = report.maximumRegression val regressionsGeometricMean = report.regressionsGeometricMean val maximumImprovement = report.maximumImprovement val improvementsGeometricMean = report.improvementsGeometricMean val maximumChange = maxOf(maximumRegression, abs(maximumImprovement)) val maximumChangeGeoMean = maxOf(regressionsGeometricMean, abs(improvementsGeometricMean)) if (!report.improvements.isEmpty()) { td { +"${report.improvements.size}" } td { attributes["bgcolor"] = ColoredCell( (maximumImprovement / maximumChange).takeIf{ maximumChange > 0.0 } ).backgroundStyle +formatValue(report.maximumImprovement, true) } td { attributes["bgcolor"] = ColoredCell( (improvementsGeometricMean / maximumChangeGeoMean) .takeIf{ maximumChangeGeoMean > 0.0 } ).backgroundStyle +formatValue(report.improvementsGeometricMean, true) } } else { repeat(3) { td { +"-" } } } } } } } } } } private fun TableBlock.renderBenchmarksDetails(fullSet: Map, bucket: Map? = null, rowStyle: String? = null) { if (bucket != null && !bucket.isEmpty()) { // Find max ratio. val maxRatio = bucket.values.map { it.second.mean }.maxOrNull()!! // There are changes in performance. // Output changed benchmarks. for ((name, change) in bucket) { tr { rowStyle?. let { attributes["style"] = rowStyle } th { +name } td { +"${fullSet.getValue(name).first?.description}" } td { +"${fullSet.getValue(name).second?.description}" } td { attributes["bgcolor"] = ColoredCell(if (bucket.values.first().first.mean == 0.0) null else change.first.mean / abs(bucket.values.first().first.mean)) .backgroundStyle +"${change.first.description + " %"}" } td { val scaledRatio = if (maxRatio == 0.0) null else change.second.mean / maxRatio attributes["bgcolor"] = ColoredCell(scaledRatio, borderPositive = { cellValue -> cellValue > 1.0 / maxRatio }).backgroundStyle +"${change.second.description}" } } } } else if (bucket == null) { // Output all values without performance changes. val placeholder = "-" for ((name, value) in fullSet) { tr { th { +name } td { +"${value.first?.description ?: placeholder}" } td { +"${value.second?.description ?: placeholder}" } td { +placeholder } td { +placeholder } } } } } private fun TableBlock.renderFilteredBenchmarks(detailedReport: DetailedBenchmarksReport, onlyChanges: Boolean, unstableBenchmarks: List, filterUnstable: Boolean) { fun filterBenchmarks(bucket: Map) = bucket.filter { (name, _) -> if (filterUnstable) name in unstableBenchmarks else name !in unstableBenchmarks } val filteredRegressions = filterBenchmarks(detailedReport.regressions) val filteredImprovements = filterBenchmarks(detailedReport.improvements) renderBenchmarksDetails(detailedReport.mergedReport, filteredRegressions) renderBenchmarksDetails(detailedReport.mergedReport, filteredImprovements) if (!onlyChanges) { // Print all remaining results. renderBenchmarksDetails(filterBenchmarks(detailedReport.mergedReport).filter { it.key !in detailedReport.regressions.keys && it.key !in detailedReport.improvements.keys }) } } private fun BodyTag.renderPerformanceDetails(report: SummaryBenchmarksReport, onlyChanges: Boolean) { if (onlyChanges) { if (report.detailedMetricReports.values.all { it.improvements.isEmpty() } && report.detailedMetricReports.values.all { it.regressions.isEmpty() }) { div("alert alert-success") { attributes["role"] = "alert" +"All becnhmarks are stable!" } } } report.detailedMetricReports.forEach { (metric, detailedReport) -> renderCollapsedData(metric.value, false) { table { attributes["id"] = "result" attributes["class"] = "table table-striped table-bordered" thead { tr { th { +"Benchmark" } th { +"First score" } th { +"Second score" } th { +"Percent" } th { +"Ratio" } } } val geoMeanChangeMap = detailedReport.geoMeanScoreChange?.let { mapOf(detailedReport.geoMeanBenchmark.first!!.name to detailedReport.geoMeanScoreChange!!) } tbody { val boldRowStyle = "border-bottom: 2.3pt solid black; border-top: 2.3pt solid black" renderBenchmarksDetails( mutableMapOf(detailedReport.geoMeanBenchmark.first!!.name to detailedReport.geoMeanBenchmark), geoMeanChangeMap, boldRowStyle) val unstableBenchmarks = report.getUnstableBenchmarksForMetric(metric) if (unstableBenchmarks.isNotEmpty()) { tr { attributes["style"] = boldRowStyle th(colspan = Natural(5)) { +"Stable" } } } renderFilteredBenchmarks(detailedReport, onlyChanges, unstableBenchmarks, false) if (unstableBenchmarks.isNotEmpty()) { tr { attributes["style"] = boldRowStyle th(colspan = Natural(5)) { +"Unstable" } } } renderFilteredBenchmarks(detailedReport, onlyChanges, unstableBenchmarks, true) } } } hr {} } } data class Color(val red: Double, val green: Double, val blue: Double) { operator fun times(coefficient: Double) = Color(red * coefficient, green * coefficient, blue * coefficient) operator fun plus(other: Color) = Color(red + other.red, green + other.green, blue + other.blue) override fun toString() = "#" + buildString { listOf(red, green, blue).forEach { append(clamp((it * 255).toInt(), 0, 255).toString(16).padStart(2, '0')) } } } class ColoredCell(val scaledValue: Double?, val reverse: Boolean = false, val borderPositive: (cellValue: Double) -> Boolean = { cellValue -> cellValue > 0 }) { val value: Double val neutralColor = Color(1.0,1.0 , 1.0) val negativeColor = Color(0.0, 1.0, 0.0) val positiveColor = Color(1.0, 0.0, 0.0) init { value = scaledValue?.let { if (abs(scaledValue) <= 1.0) scaledValue else error ("Value should be scaled in range [-1.0; 1.0]") } ?: 0.0 } val backgroundStyle: String get() = scaledValue?.let { getColor().toString() } ?: "" fun getColor(): Color { val currentValue = clamp(value, -1.0, 1.0) val cellValue = if (reverse) -currentValue else currentValue val baseColor = if (borderPositive(cellValue)) positiveColor else negativeColor // Smooth mapping to put first 20% of change into 50% of range, // although really we should compensate for luma. val color = sin((abs(cellValue).pow(.477)) * kotlin.math.PI * .5) return linearInterpolation(neutralColor, baseColor, color) } private fun linearInterpolation(a: Color, b: Color, coefficient: Double): Color { val reversedCoefficient = 1.0 - coefficient return a * reversedCoefficient + b * coefficient } } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/JsonResultsRender.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.* // Report render to text format. class JsonResultsRender: Render() { override val name: String get() = "json" override fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean) = report.getBenchmarksReport().toJson() } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/MetricResultsRender.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.BenchmarkResult // Report render to text format. class MetricResultsRender: Render() { override val name: String get() = "metrics" override fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean): String { val results = report.detailedMetricReports.values.map { it.mergedReport }.map { report -> report.map { entry -> buildString { val metric = entry.value.first!!.metric append("{ \"benchmarkName\": \"${entry.key.removeSuffix(metric.suffix)}\",") append("\"metric\": \"${metric}\",") append("\"value\": \"${entry.value.first!!.score}\" }") } } }.flatten().joinToString(", ") return "[ $results ]" } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/Render.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.* import kotlin.math.abs enum class RenderType(val createRender: () -> Render) { TEXT(::TextRender), HTML(::HTMLRender), TEAMCITY(::TeamCityStatisticsRender), STATISTICS(::StatisticsRender) } // Base class for printing report in different formats. abstract class Render { abstract val name: String abstract fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean = false): String // Print report using render. fun print(report: SummaryBenchmarksReport, onlyChanges: Boolean = false, outputFile: String? = null) { val content = render(report, onlyChanges) outputFile?.let { writeToFile(outputFile, content) } ?: println(content) } protected fun formatValue(number: Double, isPercent: Boolean = false): String = if (isPercent) number.format(2) + "%" else number.format() } // Report render to text format. class TextRender: Render() { override val name: String get() = "text" private val content = StringBuilder() private val headerSeparator = "=================" private val wideColumnWidth = 50 private val standardColumnWidth = 25 private fun append(text: String = "") { content.append("$text\n") } override fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean): String { renderEnvChanges(report.envChanges, "Environment") renderEnvChanges(report.kotlinChanges, "Compiler") renderStatusSummary(report) renderStatusChangesDetails(report.benchmarksWithChangedStatus) renderPerformanceSummary(report) renderPerformanceDetails(report, onlyChanges) return content.toString() } private fun printBucketInfo(bucket: Collection, name: String) { if (!bucket.isEmpty()) { append("$name: ${bucket.size}") } } private fun printStatusChangeInfo(bucket: List>, name: String) { if (!bucket.isEmpty()) { append("$name:") for (change in bucket) { append(change.renderAsText()) } } } fun renderEnvChanges(envChanges: List>, bucketName: String) { if (!envChanges.isEmpty()) { append(ChangeReport(bucketName, envChanges).renderAsTextReport()) } } fun renderStatusChangesDetails(benchmarksWithChangedStatus: List>) { if (!benchmarksWithChangedStatus.isEmpty()) { append("Changes in status") append(headerSeparator) printStatusChangeInfo(benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.FAILED }, "New failures") printStatusChangeInfo(benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.PASSED }, "New passes") append() } } fun renderStatusSummary(report: SummaryBenchmarksReport) { append("Status summary") append(headerSeparator) val failedBenchmarks = report.failedBenchmarks val addedBenchmarks = report.addedBenchmarks val removedBenchmarks = report.removedBenchmarks if (failedBenchmarks.isEmpty()) { append("All benchmarks passed!") } if (!failedBenchmarks.isEmpty() || !addedBenchmarks.isEmpty() || !removedBenchmarks.isEmpty()) { printBucketInfo(failedBenchmarks, "Failed benchmarks") printBucketInfo(addedBenchmarks, "Added benchmarks") printBucketInfo(removedBenchmarks, "Removed benchmarks") } append("Total becnhmarks number: ${report.benchmarksNumber}") append() } fun renderPerformanceSummary(report: SummaryBenchmarksReport) { if (report.detailedMetricReports.values.any { it.improvements.isNotEmpty() } || report.detailedMetricReports.values.any { it.regressions.isNotEmpty() }) { append("Performance summary") append(headerSeparator) append() report.detailedMetricReports.forEach { (metric, detailedReport) -> if (detailedReport.regressions.isNotEmpty() || detailedReport.improvements.isNotEmpty()) { append(metric.value) append(headerSeparator) if (!detailedReport.regressions.isEmpty()) { append("Regressions: Maximum = ${formatValue(detailedReport.maximumRegression, true)}," + " Geometric mean = ${formatValue(detailedReport.regressionsGeometricMean, true)}") } if (!detailedReport.improvements.isEmpty()) { append("Improvements: Maximum = ${formatValue(detailedReport.maximumImprovement, true)}," + " Geometric mean = ${formatValue(detailedReport.improvementsGeometricMean, true)}") } append() } } } } private fun formatColumn(content:String, isWide: Boolean = false): String = content.padEnd(if (isWide) wideColumnWidth else standardColumnWidth, ' ') private fun printBenchmarksDetails(fullSet: Map, bucket: Map? = null) { val placeholder = "-" if (bucket != null) { // There are changes in performance. // Output changed benchmarks. for ((name, change) in bucket) { append(formatColumn(name, true) + formatColumn(fullSet.getValue(name).first?.description ?: placeholder) + formatColumn(fullSet.getValue(name).second?.description ?: placeholder) + formatColumn(change.first.description + " %") + formatColumn(change.second.description)) } } else { // Output all values without performance changes. for ((name, value) in fullSet) { append(formatColumn(name, true) + formatColumn(value.first?.description ?: placeholder) + formatColumn(value.second?.description ?: placeholder) + formatColumn(placeholder) + formatColumn(placeholder)) } } } private fun printTableLineSeparator(tableWidth: Int) = append("${"-".padEnd(tableWidth, '-')}") private fun printPerformanceTableHeader(): Int { val wideColumns = listOf(formatColumn("Benchmark", true)) val standardColumns = listOf(formatColumn("First score"), formatColumn("Second score"), formatColumn("Percent"), formatColumn("Ratio")) val tableWidth = wideColumnWidth * wideColumns.size + standardColumnWidth * standardColumns.size append("${wideColumns.joinToString(separator = "")}${standardColumns.joinToString(separator = "")}") printTableLineSeparator(tableWidth) return tableWidth } fun renderPerformanceDetails(report: SummaryBenchmarksReport, onlyChanges: Boolean = false) { append("Performance details") append(headerSeparator) if (onlyChanges) { if (report.detailedMetricReports.values.all { it.improvements.isEmpty() } && report.detailedMetricReports.values.all { it.regressions.isEmpty() }) { append("All becnhmarks are stable.") } } report.detailedMetricReports.forEach { (metric, detailedReport) -> append() append(metric.value) append(headerSeparator) val tableWidth = printPerformanceTableHeader() // Print geometric mean. val geoMeanChangeMap = detailedReport.geoMeanScoreChange?.let { mapOf(detailedReport.geoMeanBenchmark.first!!.name to detailedReport.geoMeanScoreChange!!) } printBenchmarksDetails( mutableMapOf(detailedReport.geoMeanBenchmark.first!!.name to detailedReport.geoMeanBenchmark), geoMeanChangeMap) printTableLineSeparator(tableWidth) val unstableBenchmarks = report.getUnstableBenchmarksForMetric(metric) if (unstableBenchmarks.isNotEmpty()) { append("Stable") printTableLineSeparator(tableWidth) } renderFilteredPerformanceDetails(detailedReport, onlyChanges, unstableBenchmarks, false) if (unstableBenchmarks.isNotEmpty()) { printTableLineSeparator(tableWidth) append("Unstable") printTableLineSeparator(tableWidth) } renderFilteredPerformanceDetails(detailedReport, onlyChanges, unstableBenchmarks,true) } } fun renderFilteredPerformanceDetails(detailedReport: DetailedBenchmarksReport, onlyChanges: Boolean, unstableBenchmarks: List, filterUnstable: Boolean) { fun filterBenchmarks(bucket: Map) = bucket.filter { (name, _) -> if (filterUnstable) name in unstableBenchmarks else name !in unstableBenchmarks } val filteredRegressions = filterBenchmarks(detailedReport.regressions) val filteredImprovements = filterBenchmarks(detailedReport.improvements) printBenchmarksDetails(detailedReport.mergedReport, filteredRegressions) printBenchmarksDetails(detailedReport.mergedReport, filteredImprovements) if (!onlyChanges) { // Print all remaining results. printBenchmarksDetails(filterBenchmarks(detailedReport.mergedReport).filter { it.key !in detailedReport.regressions.keys && it.key !in detailedReport.improvements.keys }) } } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/StatisticsRender.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.BenchmarkResult enum class Status { FAILED, FIXED, IMPROVED, REGRESSED, STABLE, UNSTABLE } // Report render to short summary statistics. class StatisticsRender: Render() { override val name: String get() = "statistics" private var content = StringBuilder() override fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean): String { val benchmarksWithChangedStatus = report.benchmarksWithChangedStatus val newPasses = benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.PASSED } val newFailures = benchmarksWithChangedStatus .filter { it.current == BenchmarkResult.Status.FAILED } if (report.failedBenchmarks.isNotEmpty()) { content.append("failed: ${report.failedBenchmarks.size}\n") } val regressionsSize = report.detailedMetricReports.values.fold(0) { acc, it -> acc + it.regressions.size } val improvementsSize = report.detailedMetricReports.values.fold(0) { acc, it -> acc + it.improvements.size } val status = when { newFailures.isNotEmpty() -> { content.append("new failures: ${newFailures.size}\n") Status.FAILED } newPasses.isNotEmpty() -> { content.append("new passes: ${newPasses.size}\n") Status.FIXED } regressionsSize != 0 && improvementsSize != 0 -> { content.append("regressions: $regressionsSize\nimprovements: $improvementsSize") Status.UNSTABLE } improvementsSize != 0 && regressionsSize == 0 -> { content.append("improvements: $improvementsSize") Status.IMPROVED } improvementsSize == 0 && regressionsSize != 0 -> { content.append("regressions: $regressionsSize") Status.REGRESSED } else -> Status.STABLE } return """ status: $status total: ${report.benchmarksNumber} """.trimIndent() + "\n$content" } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin/org/jetbrains/renders/TeamCityStatisticsRender.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.renders import org.jetbrains.analyzer.* import org.jetbrains.report.BenchmarkResult import org.jetbrains.report.MeanVarianceBenchmark // Report render to text format. class TeamCityStatisticsRender: Render() { override val name: String get() = "teamcity" private var content = StringBuilder() override fun render(report: SummaryBenchmarksReport, onlyChanges: Boolean): String { val currentDurations = report.currentBenchmarksDuration content.append("##teamcity[testSuiteStarted name='Benchmarks']\n") // For current benchmarks print score as TeamCity Test Metadata report.currentMeanVarianceBenchmarks.forEach { benchmark -> renderBenchmark(benchmark, currentDurations[benchmark.name]!!) renderSummaryBecnhmarkValue(benchmark) } content.append("##teamcity[testSuiteFinished name='Benchmarks']\n") // Report geometric mean as build statistic value report.detailedMetricReports.forEach { (metric, detailedReport) -> renderGeometricMean(metric.value, detailedReport.geoMeanBenchmark.first!!) } return content.toString() } private fun renderSummaryBecnhmarkValue(benchmark: MeanVarianceBenchmark) { content.append("##teamcity[testMetadata testName='${benchmark.name}' name='Mean'" + " type='number' value='${benchmark.score}']\n") content.append("##teamcity[testMetadata testName='${benchmark.name}' name='Variance'" + " type='number' value='${benchmark.variance}']\n") } // Produce benchmark as test in TeamCity private fun renderBenchmark(benchmark: BenchmarkResult , duration: Double) { content.append("##teamcity[testStarted name='${benchmark.name}']\n") if (benchmark.status == BenchmarkResult.Status.FAILED) { content.append("##teamcity[testFailed name='${benchmark.name}']\n") } // test_duration_in_milliseconds is set for TeamCity content.append("##teamcity[testFinished name='${benchmark.name}' duration='${(duration / 1000).toInt()}']\n") } private fun renderGeometricMean(metricName: String, geoMeanBenchmark: MeanVarianceBenchmark) { content.append("##teamcity[buildStatisticValue key='$metricName Geometric mean' value='${geoMeanBenchmark.score}']\n") content.append("##teamcity[buildStatisticValue key='$metricName Geometric mean variance' value='${geoMeanBenchmark.variance}']\n") } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin-js/org/jetbrains/analyzer/Utils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import org.w3c.xhr.* import kotlin.browser.* import kotlin.js.* actual fun readFile(fileName: String): String { error("Reading from local file for JS isn't supported") } actual fun Double.format(decimalNumber: Int): String = this.asDynamic().toFixed(decimalNumber) actual fun writeToFile(fileName: String, text: String) { if (fileName != "html") error("Writing to local file for JS isn't supported") val bodyPart = text.substringAfter("").substringBefore("") document.body?.innerHTML = bodyPart } actual fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) error(lazyMessage) } actual fun sendGetRequest(url: String, user: String?, password: String?, followLocation: Boolean) : String { val proxyServerAddress = "https://perf-proxy.labs.jb.gg/" val newUrl = proxyServerAddress + url val request = XMLHttpRequest() request.open("GET", newUrl, false, user, password) request.send() if (request.status == 200.toShort()) { return request.responseText } error("Request to $url has status ${request.status}") } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin-jvm/org/jetbrains/analyzer/Utils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import java.io.File import java.io.InputStream import java.net.HttpURLConnection import java.net.URL import java.util.Base64 actual fun readFile(fileName: String): String { val inputStream = File(fileName).inputStream() val inputString = inputStream.bufferedReader().use { it.readText() } return inputString } actual fun Double.format(decimalNumber: Int): String = "%.${decimalNumber}f".format(this) actual fun writeToFile(fileName: String, text: String) { File(fileName).printWriter().use { out -> out.println(text) } } actual fun assert(value: Boolean, lazyMessage: () -> Any) = kotlin.assert(value, lazyMessage) // Create http(-s) request. fun getHttpRequest(url: String, user: String?, password: String?): HttpURLConnection { val connection = URL(url).openConnection() as HttpURLConnection if (user != null && password != null) { val auth = Base64.getEncoder().encode((user + ":" + password).toByteArray()).toString(Charsets.UTF_8) connection.addRequestProperty("Authorization", "Basic $auth") } connection.setRequestProperty("Accept", "application/json") return connection } actual fun sendGetRequest(url: String, user: String?, password: String?, followLocation: Boolean) : String { val connection = getHttpRequest(url, user, password) connection.connect() val responseCode = connection.responseCode if (!followLocation) { connection.connect() return connection.inputStream.use { it.reader().use { reader -> reader.readText() } } } // Request with redirect. if (responseCode != HttpURLConnection.HTTP_MOVED_TEMP && responseCode != HttpURLConnection.HTTP_MOVED_PERM && responseCode != HttpURLConnection.HTTP_SEE_OTHER) { error("No opportunity to redirect, but flag for redirecting to location was provided!") } val newUrl = connection.getHeaderField("Location") val cookies = connection.getHeaderField("Set-Cookie") val redirect = getHttpRequest(newUrl, user, password) redirect.setRequestProperty("Cookie", cookies) redirect.connect() return redirect.inputStream.use { it.reader().use { reader -> reader.readText() } } } ================================================ FILE: tools/benchmarksAnalyzer/src/main/kotlin-native/org/jetbrains/analyzer/Utils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import platform.posix.* import kotlinx.cinterop.* import libcurl.* actual fun readFile(fileName: String): String { val file = fopen(fileName, "r") ?: error("Cannot read file '$fileName'") var buffer = ByteArray(1024) var text = StringBuilder() try { while (true) { val nextLine = fgets(buffer.refTo(0), buffer.size, file)?.toKString() if (nextLine == null) break text.append(nextLine) } } finally { fclose(file) } return text.toString() } actual fun Double.format(decimalNumber: Int): String { var buffer = ByteArray(1024) snprintf(buffer.refTo(0), buffer.size.toULong(), "%.${decimalNumber}f", this) return buffer.toKString() } actual fun writeToFile(fileName: String, text: String) { val file = fopen(fileName, "wt") ?: error("Cannot write file '$fileName'") try { if (fputs(text, file) == EOF) throw Error("File write error") } finally { fclose(file) } } actual fun assert(value: Boolean, lazyMessage: () -> Any) = kotlin.assert(value, lazyMessage) class CUrl(url: String, user: String? = null, password: String? = null, followLocation: Boolean = false) { private val stableRef = StableRef.create(this) private val curl = curl_easy_init() init { curl_easy_setopt(curl, CURLOPT_URL, url) val writeData = staticCFunction(::collectResponse) curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData) curl_easy_setopt(curl, CURLOPT_WRITEDATA, stableRef.asCPointer()) if (followLocation) { curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L) } user ?.let { curl_easy_setopt(curl, CURLOPT_USERNAME, it) } password ?.let { curl_easy_setopt(curl, CURLOPT_PASSWORD, it) } } val body = StringBuilder() fun fetch() { memScoped { val res = curl_easy_perform(curl) if (res != CURLE_OK) error("curl_easy_perform() failed: ${curl_easy_strerror(res)?.toKString()}") val http_code = alloc() curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, http_code.ptr) if (http_code.value >= 400L) { error("Error http code ${http_code.value}") } } } fun close() { curl_easy_cleanup(curl) stableRef.dispose() } } fun CPointer.toKString(length: Int): String { val bytes = this.readBytes(length) return bytes.toKString() } fun collectResponse(buffer: CPointer?, size: size_t, nitems: size_t, userdata: COpaquePointer?): size_t { buffer ?: return 0u userdata ?. let { val data = buffer.toKString((size * nitems).toInt()).trim() val curl = userdata.asStableRef().get() curl.body.append(data) } return size * nitems } actual fun sendGetRequest(url: String, user: String?, password: String?, followLocation: Boolean) : String { val curl = CUrl(url, user, password, followLocation) curl.fetch() curl.close() return curl.body.toString() } ================================================ FILE: tools/benchmarksAnalyzer/src/nativeInterop/cinterop/libcurl.def ================================================ headers = curl/curl.h headerFilter = curl/* linkerOpts.osx = -L/opt/local/lib -L/usr/local/opt/curl/lib -lcurl linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -lcurl linkerOpts.mingw = -lcurl ================================================ FILE: tools/benchmarksAnalyzer/src/tests/AnalyzerTests.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import kotlin.test.* import kotlin.math.abs import org.jetbrains.report.BenchmarkResult import org.jetbrains.report.MeanVarianceBenchmark class AnalyzerTests { private val eps = 0.000001 private fun createMeanVarianceBenchmarks(): Pair { val first = MeanVarianceBenchmark("testBenchmark", BenchmarkResult.Status.PASSED, 9.0, BenchmarkResult.Metric.EXECUTION_TIME, 9.0, 10, 10, 0.0001) val second = MeanVarianceBenchmark("testBenchmark", BenchmarkResult.Status.PASSED, 10.0, BenchmarkResult.Metric.EXECUTION_TIME, 10.0, 10, 10, 0.0001) return Pair(first, second) } @Test fun testGeoMean() { val numbers = listOf(4.0, 6.0, 9.0) val value = geometricMean(numbers) val expected = 6.0 assertTrue(abs(value - expected) < eps) } @Test fun testComputeMeanVariance() { val numbers = listOf(10.1, 10.2, 10.3) val value = computeMeanVariance(numbers) val expectedMean = 10.2 val expectedVariance = 0.07872455 assertTrue(abs(value.mean - expectedMean) < eps) assertTrue(abs(value.variance - expectedVariance) < eps) } @Test fun calcPercentageDiff() { val inputs = createMeanVarianceBenchmarks() val percent = inputs.first.calcPercentageDiff(inputs.second) val expectedMean = -9.99809998 val expectedVariance = 0.0021 assertTrue(abs(percent.mean - expectedMean) < eps) //assertTrue(abs(percent.variance - expectedVariance) < eps) } @Test fun calcRatio() { val inputs = createMeanVarianceBenchmarks() val ratio = inputs.first.calcRatio(inputs.second) val expectedMean = 0.9 val expectedVariance = 0.00001899 assertTrue(abs(ratio.mean - expectedMean) < eps) assertTrue(abs(ratio.variance - expectedVariance) < eps) } } ================================================ FILE: tools/kotlin-native-gradle-plugin/build.gradle ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.jetbrains.kotlin.konan.* buildscript { ext.rootBuildDirectory = file('../../') apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle" apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" repositories { maven { url = 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url "https://cache-redirector.jetbrains.com/plugins.gradle.org/m2/" } gradlePluginPortal() } dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.4' classpath "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" } } apply plugin: 'java-gradle-plugin' apply plugin: 'kotlin' apply plugin: 'groovy' apply plugin: 'com.github.johnrengelman.shadow' group = 'org.jetbrains.kotlin' version = CompilerVersionGeneratedKt.getCurrentCompilerVersion() repositories { mavenCentral() maven { url buildKotlinCompilerRepo } maven { url kotlinCompilerRepo } } configurations { bundleDependencies { transitive = false } implementation.extendsFrom shadow compileOnly.extendsFrom bundleDependencies testImplementation.extendsFrom bundleDependencies } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions.freeCompilerArgs = ["-Xskip-prerelease-check"] } dependencies { shadow "org.jetbrains.kotlin:kotlin-stdlib:1.3.0" // Bundle the serialization plugin into the final jar because we shade classes of the kotlin plugin // while the serialization one extends them. bundleDependencies "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-gradle-plugin-api:$kotlinVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-native-utils:$kotlinVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-util-io:$kotlinVersion" bundleDependencies "org.jetbrains.kotlin:kotlin-util-klib:$kotlinVersion" testImplementation 'junit:junit:4.12' testImplementation "org.jetbrains.kotlin:kotlin-test:$buildKotlinVersion" testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$buildKotlinVersion" testImplementation "org.tools4j:tools4j-spockito:1.6" testImplementation('org.spockframework:spock-core:1.1-groovy-2.4') { exclude module: 'groovy-all' } } shadowJar { from sourceSets.main.output configurations = [project.configurations.bundleDependencies] archiveClassifier.set(null) relocate('org.jetbrains.kotlinx', 'shadow.org.jetbrains.kotlinx') relocate('org.jetbrains.kotlin.compilerRunner', 'shadow.org.jetbrains.kotlin.compilerRunner') relocate('org.jetbrains.kotlin.konan', 'shadow.org.jetbrains.kotlin.konan') relocate('org.jetbrains.kotlin.gradle', 'shadow.org.jetbrains.kotlin.gradle') { exclude('org.jetbrains.kotlin.gradle.plugin.experimental.**') exclude('org.jetbrains.kotlin.gradle.plugin.konan.**') exclude('org.jetbrains.kotlin.gradle.plugin.model.**') } exclude { def path = it.relativePath.pathString if (path.startsWith("META-INF/gradle-plugins") && path.endsWith(".properties")) { def fileName = it.name def id = fileName.take(fileName.lastIndexOf('.')) return project.gradlePlugin.plugins.findByName(id) == null } return false } exclude('META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar') exclude('META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin') } jar { dependsOn shadowJar enabled = false } pluginUnderTestMetadata { dependsOn shadowJar doLast { // Since Gradle 4.10 it isn't possible to edit the pluginUnderTest classpath. // So we have to manually set the implementation-classpath to get the output fat-jar. def pluginMetadata = outputDirectory.get().file(PluginUnderTestMetadata.METADATA_FILE_NAME).getAsFile() def classpath = files(shadowJar.archivePath) + configurations.shadow new Properties().with { properties -> pluginMetadata.withInputStream { properties.load(it) } properties.setProperty(PluginUnderTestMetadata.IMPLEMENTATION_CLASSPATH_PROP_KEY , classpath.asPath) pluginMetadata.withOutputStream { properties.store(it, null) } } } } test { dependsOn shadowJar systemProperty("kotlin.version", kotlinVersion) systemProperty("kotlin.repo", kotlinCompilerRepo) if (project.hasProperty("konan.home")) { systemProperty("konan.home", project.property("konan.home")) systemProperty("org.jetbrains.kotlin.native.home", project.property("konan.home")) } else if (project.hasProperty("org.jetbrains.kotlin.native.home")) { systemProperty("org.jetbrains.kotlin.native.home", project.property("org.jetbrains.kotlin.native.home")) } else { // The Koltin/Native compiler must be built before test execution. systemProperty("konan.home", distDir.absolutePath) systemProperty("org.jetbrains.kotlin.native.home", distDir.absolutePath) } if (project.hasProperty("konan.jvmArgs")) { systemProperty("konan.jvmArgs", project.property("konan.jvmArgs")) } // Uncomment for debugging. //testLogging.showStandardStreams = true if (project.hasProperty("maxParallelForks")) { maxParallelForks=project.property("maxParallelForks") } if (project.hasProperty("filter")) { filter.includeTestsMatching project.property("filter") } if (project.hasProperty("gradleVersion")) { systemProperty("gradleVersion", project.property("gradleVersion")) } } processResources { from(file("$rootBuildDirectory/utilities/env_blacklist")) } tasks.named('compileTestGroovy') { classpath = sourceSets.test.compileClasspath } tasks.named('compileTestKotlin') { classpath += files(sourceSets.test.groovy.classesDirectory) } gradlePlugin { plugins { create('konan') { id = 'konan' implementationClass = 'org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin' } // We bundle a shaded version of kotlinx-serialization plugin create('kotlinx-serialization-native') { id = 'kotlinx-serialization-native' implementationClass = 'shadow.org.jetbrains.kotlinx.serialization.gradle.SerializationGradleSubplugin' } create('org.jetbrains.kotlin.konan') { id = 'org.jetbrains.kotlin.konan' implementationClass = 'org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin' } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/settings.gradle ================================================ rootProject.name = "kotlin-native-gradle-plugin" includeBuild '../../shared' ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/experimental/internal/KotlinNativePlatform.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.experimental.internal import org.gradle.api.Project import org.gradle.api.internal.component.UsageContext import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Provider import org.gradle.internal.os.OperatingSystem import org.gradle.language.cpp.internal.NativeVariantIdentity import org.gradle.nativeplatform.MachineArchitecture import org.gradle.nativeplatform.OperatingSystemFamily import org.gradle.nativeplatform.TargetMachine import org.gradle.nativeplatform.TargetMachineFactory import org.gradle.nativeplatform.platform.NativePlatform import org.gradle.nativeplatform.platform.internal.* import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.visibleName interface KotlinNativePlatform: NativePlatform { val target: KonanTarget } fun KonanTarget.getGradleOS(): OperatingSystemInternal = family.visibleName.let { DefaultOperatingSystem(it, OperatingSystem.forName(it)) } fun KonanTarget.getGradleOSFamily(objectFactory: ObjectFactory): OperatingSystemFamily { return objectFactory.named(OperatingSystemFamily::class.java, family.visibleName) } fun KonanTarget.getGradleCPU(): ArchitectureInternal = architecture.visibleName.let { Architectures.forInput(it) } fun KonanTarget.toTargetMachine(objectFactory: ObjectFactory): TargetMachine = object: TargetMachine { override fun getOperatingSystemFamily(): OperatingSystemFamily = getGradleOSFamily(objectFactory) override fun getArchitecture(): MachineArchitecture = objectFactory.named(MachineArchitecture::class.java, this@toTargetMachine.architecture.visibleName) } class DefaultKotlinNativePlatform(name: String, override val target: KonanTarget): DefaultNativePlatform(name, target.getGradleOS(), target.getGradleCPU()), KotlinNativePlatform { constructor(target: KonanTarget): this(target.visibleName, target) // TODO: Extend ImmutableDefaultNativePlatform and get rid of these methods after switch to Gradle 4.8 private fun notImplemented(): Nothing = throw NotImplementedError("Not Implemented in Kotlin/Native plugin") override fun operatingSystem(name: String?) = notImplemented() override fun withArchitecture(architecture: ArchitectureInternal?) = notImplemented() override fun architecture(name: String?) = notImplemented() } // NativeVariantIdentity constructor was changed in Gradle 5.1 // So we have to use reflection to create instance of this class in earlier versions. internal fun compatibleVariantIdentity( project: Project, name: String, baseName: Provider, group: Provider, version: Provider, debuggable: Boolean, optimized: Boolean, target: KonanTarget, linkUsage: UsageContext?, runtimeUsage: UsageContext? ): NativeVariantIdentity = if (isGradleVersionAtLeast(5, 1)) { val targetMachineFactory = (project as ProjectInternal).services.get(TargetMachineFactory::class.java) NativeVariantIdentity( name, baseName, group, version, debuggable, optimized, targetMachineFactory.os(target.family.name), linkUsage, runtimeUsage ) } else { NativeVariantIdentity::class.java.getConstructor( String::class.java, Provider::class.java, Provider::class.java, Provider::class.java, Boolean::class.javaPrimitiveType, Boolean::class.javaPrimitiveType, OperatingSystemFamily::class.java, UsageContext::class.java, UsageContext::class.java ).newInstance( name, baseName, group, version, debuggable, optimized, target.getGradleOSFamily(project.objects), linkUsage, runtimeUsage ) } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/EnvironmentVariables.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin.ProjectProperty import java.io.File /** * The plugin allows an IDE to specify some building parameters. These parameters * are passed to the plugin via environment variables. Two variables are supported: * - CONFIGURATION_BUILD_DIR - A path to a destination directory for all compilation tasks. * The IDE should take care about specifying different directories * for different targets. This setting has less priority than * an explicitly specified destination directory in the build script. * * - DEBUGGING_SYMBOLS - If YES, the debug support will be enabled for all artifacts. This option has less * priority than explicitly specified enableDebug option in the build script and * enableDebug project property. * * - KONAN_ENABLE_OPTIMIZATIONS - If YES, optimizations will be enabled for all artifacts by default. This option * has less priority than explicitly specified enableOptimizations option in the * build script. * * Support for environment variables should be explicitly enabled by setting a project property: * konan.useEnvironmentVariables = true. */ internal interface EnvironmentVariables { val configurationBuildDir: File? val debuggingSymbols: Boolean val enableOptimizations: Boolean } internal class EnvironmentVariablesUnused: EnvironmentVariables { override val configurationBuildDir: File? get() = null override val debuggingSymbols: Boolean get() = false override val enableOptimizations: Boolean get() = false } internal class EnvironmentVariablesImpl(val project: Project): EnvironmentVariables { override val configurationBuildDir: File? get() = System.getenv("CONFIGURATION_BUILD_DIR")?.let { project.file(it) } override val debuggingSymbols: Boolean get() = System.getenv("DEBUGGING_SYMBOLS")?.toUpperCase() == "YES" override val enableOptimizations: Boolean get() = System.getenv("KONAN_ENABLE_OPTIMIZATIONS")?.toUpperCase() == "YES" } /** * Due to https://github.com/gradle/gradle/issues/3468 we cannot use environment * variables in Java 9. Until Gradle API for environment variables is provided * we use project properties instead of them. TODO: Return to using env vars when the issue is fixed. */ internal class EnvironmentVariablesFromProperties(val project: Project): EnvironmentVariables { override val configurationBuildDir: File? get() = project.findProperty(ProjectProperty.KONAN_CONFIGURATION_BUILD_DIR)?.let { project.file(it) } override val debuggingSymbols: Boolean get() = project.findProperty(ProjectProperty.KONAN_DEBUGGING_SYMBOLS)?.toString()?.toUpperCase().let { it == "YES" || it == "TRUE" } override val enableOptimizations: Boolean get() = project.findProperty(ProjectProperty.KONAN_OPTIMIZATIONS_ENABLE)?.toString()?.toUpperCase().let { it == "YES" || it == "TRUE" } } internal val Project.useEnvironmentVariables: Boolean get() = findProperty(ProjectProperty.KONAN_USE_ENVIRONMENT_VARIABLES)?.toString()?.toBoolean() ?: false /* TODO: Return to using env vars when the issue is fixed. Take into account the useEnvironmentVariables property (and may be rename it) in the following way: if (useEnvironmentVariables) { EnvironmentVariablesImpl(project) } else { EnvironmentVariablesUnused() } */ internal val Project.environmentVariables: EnvironmentVariables get() = EnvironmentVariablesFromProperties(project) ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanArtifactContainer.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer import org.gradle.api.internal.project.ProjectInternal import org.gradle.internal.reflect.Instantiator import org.gradle.util.ConfigureUtil import kotlin.reflect.KClass open class KonanArtifactContainer(val project: ProjectInternal) : DefaultPolymorphicDomainObjectContainer>( KonanBuildingConfig::class.java, project.services.get(Instantiator::class.java) ) { private inner class KonanBuildingConfigFactory>(val configClass: KClass) : NamedDomainObjectFactory { var targets: Iterable = emptyList() override fun create(name: String?): T = instantiator.newInstance(configClass.java, name, project, targets) } private val factories = mutableMapOf>, KonanBuildingConfigFactory<*>>() private fun > createFactory(configClass: KClass) { val factory = KonanBuildingConfigFactory(configClass) super.registerFactory(configClass.java, factory) factories.put(configClass, factory) } init { createFactory(KonanProgram::class) createFactory(KonanDynamic::class) createFactory(KonanFramework::class) createFactory(KonanLibrary::class) createFactory(KonanBitcode::class) createFactory(KonanInteropLibrary::class) } private fun determineTargets(configClass: KClass>, args: Map) { val targetsArg = args["targets"] val targets = when { targetsArg == null -> project.konanExtension.targets targetsArg is Iterable<*> -> targetsArg.map { it.toString() } else -> listOf(targetsArg.toString()) } factories[configClass]?.targets = targets } private fun > create(name: String, configClass: KClass, args: Map, configureAction: Action) { determineTargets(configClass, args) super.create(name, configClass.java, configureAction) } private fun > create(name: String, configClass: KClass, args: Map, configureAction: T.() -> Unit) { determineTargets(configClass, args) super.create(name, configClass.java, configureAction) } private fun > create(name: String, configClass: KClass, args: Map) { determineTargets(configClass, args) super.create(name, configClass.java) } fun program(args: Map, name: String) = create(name, KonanProgram::class, args) fun program(args: Map, name: String, configureAction: Action) = create(name, KonanProgram::class, args, configureAction) fun program(args: Map, name: String, configureAction: KonanProgram.() -> Unit) = create(name, KonanProgram::class, args, configureAction) fun program(args: Map, name: String, configureAction: Closure<*>) = program(args, name, ConfigureUtil.configureUsing(configureAction)) fun dynamic(args: Map, name: String) = create(name, KonanDynamic::class, args) fun dynamic(args: Map, name: String, configureAction: Action) = create(name, KonanDynamic::class, args, configureAction) fun dynamic(args: Map, name: String, configureAction: KonanDynamic.() -> Unit) = create(name, KonanDynamic::class, args, configureAction) fun dynamic(args: Map, name: String, configureAction: Closure<*>) = dynamic(args, name, ConfigureUtil.configureUsing(configureAction)) fun framework(args: Map, name: String) = create(name, KonanFramework::class, args) fun framework(args: Map, name: String, configureAction: Action) = create(name, KonanFramework::class, args, configureAction) fun framework(args: Map, name: String, configureAction: KonanFramework.() -> Unit) = create(name, KonanFramework::class, args, configureAction) fun framework(args: Map, name: String, configureAction: Closure<*>) = framework(args, name, ConfigureUtil.configureUsing(configureAction)) fun library(args: Map, name: String) = create(name, KonanLibrary::class, args) fun library(args: Map, name: String, configureAction: Action) = create(name, KonanLibrary::class, args, configureAction) fun library(args: Map, name: String, configureAction: KonanLibrary.() -> Unit) = create(name, KonanLibrary::class, args, configureAction) fun library(args: Map, name: String, configureAction: Closure<*>) = library(args, name, ConfigureUtil.configureUsing(configureAction)) fun bitcode(args: Map, name: String) = create(name, KonanBitcode::class, args) fun bitcode(args: Map, name: String, configureAction: Action) = create(name, KonanBitcode::class, args, configureAction) fun bitcode(args: Map, name: String, configureAction: KonanBitcode.() -> Unit) = create(name, KonanBitcode::class, args, configureAction) fun bitcode(args: Map, name: String, configureAction: Closure<*>) = bitcode(args, name, ConfigureUtil.configureUsing(configureAction)) fun interop(args: Map, name: String) = create(name, KonanInteropLibrary::class, args) fun interop(args: Map, name: String, configureAction: Action) = create(name, KonanInteropLibrary::class, args, configureAction) fun interop(args: Map, name: String, configureAction: KonanInteropLibrary.() -> Unit) = create(name, KonanInteropLibrary::class, args, configureAction) fun interop(args: Map, name: String, configureAction: Closure<*>) = interop(args, name, ConfigureUtil.configureUsing(configureAction)) fun program(name: String) = program(emptyMap(), name) fun program(name: String, configureAction: Action) = program(emptyMap(), name, configureAction) fun program(name: String, configureAction: KonanProgram.() -> Unit) = program(emptyMap(), name, configureAction) fun program(name: String, configureAction: Closure<*>) = program(emptyMap(), name, configureAction) fun dynamic(name: String) = dynamic(emptyMap(), name) fun dynamic(name: String, configureAction: Action) = dynamic(emptyMap(), name, configureAction) fun dynamic(name: String, configureAction: KonanDynamic.() -> Unit) = dynamic(emptyMap(), name, configureAction) fun dynamic(name: String, configureAction: Closure<*>) = dynamic(emptyMap(), name, configureAction) fun framework(name: String) = framework(emptyMap(), name) fun framework(name: String, configureAction: Action) = framework(emptyMap(), name, configureAction) fun framework(name: String, configureAction: KonanFramework.() -> Unit) = framework(emptyMap(), name, configureAction) fun framework(name: String, configureAction: Closure<*>) = framework(emptyMap(), name, configureAction) fun library(name: String) = library(emptyMap(), name) fun library(name: String, configureAction: Action) = library(emptyMap(), name, configureAction) fun library(name: String, configureAction: KonanLibrary.() -> Unit) = library(emptyMap(), name, configureAction) fun library(name: String, configureAction: Closure<*>) = library(emptyMap(), name, configureAction) fun bitcode(name: String) = bitcode(emptyMap(), name) fun bitcode(name: String, configureAction: Action) = bitcode(emptyMap(), name, configureAction) fun bitcode(name: String, configureAction: KonanBitcode.() -> Unit) = bitcode(emptyMap(), name, configureAction) fun bitcode(name: String, configureAction: Closure<*>) = bitcode(emptyMap(), name, configureAction) fun interop(name: String) = interop(emptyMap(), name) fun interop(name: String, configureAction: Action) = interop(emptyMap(), name, configureAction) fun interop(name: String, configureAction: KonanInteropLibrary.() -> Unit) = interop(emptyMap(), name, configureAction) fun interop(name: String, configureAction: Closure<*>) = interop(emptyMap(), name, configureAction) } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanBuildingConfig.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.InvalidUserDataException import org.gradle.api.Named import org.gradle.api.Task import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.ExtensionAware import org.gradle.api.publish.maven.MavenPom import org.gradle.api.tasks.TaskProvider import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File /** Base class for all Kotlin/Native artifacts. */ abstract class KonanBuildingConfig( private val name_: String, val type: Class, val project: ProjectInternal, val targets: Iterable ) : KonanBuildingSpec, Named { internal val mainVariant = KonanSoftwareComponent(project) override fun getName() = name_ protected val targetToTask = mutableMapOf>() fun tasks() = targetToTask.values private val aggregateBuildTask: TaskProvider internal var pomActions = mutableListOf>() private val konanTargets: Iterable get() = project.hostManager.toKonanTargets(targets).distinct() init { for (targetName in targets.distinct()) { val konanTarget = project.hostManager.targetByName(targetName) if (!project.hostManager.isEnabled(konanTarget)) { project.logger.info("The target is not enabled on the current host: $targetName") continue } if (!targetIsSupported(konanTarget)) { project.logger.info("The target $targetName is not supported by the artifact $name") continue } if (this[konanTarget] == null) { val task = createTask(konanTarget) targetToTask[konanTarget] = task // Allow accessing targets just by their names in Groovy DSL. (this as? ExtensionAware)?.extensions?.add(konanTarget.visibleName, task) } if (targetName != konanTarget.visibleName) { createTargetAliasTaskIfDeclared(targetName) } } aggregateBuildTask = createAggregateTask() } protected open fun generateTaskName(target: KonanTarget) = "compileKonan${name.capitalize()}${target.visibleName.capitalize()}" protected open fun generateAggregateTaskName() = "compileKonan${name.capitalize()}" protected open fun generateTargetAliasTaskName(targetName: String) = "compileKonan${name.capitalize()}${targetName.capitalize()}" protected abstract fun generateTaskDescription(task: T): String protected abstract fun generateAggregateTaskDescription(task: Task): String protected abstract fun generateTargetAliasTaskDescription(task: Task, targetName: String): String protected abstract val defaultBaseDir: File protected open fun targetIsSupported(target: KonanTarget): Boolean = true data class OutputPlacement(val destinationDir: File, val artifactName: String) // There are two options for output placement. // 1. Gradle's build directory. We use it by default, e.g. if user runs Gradle from command line. // In this case all produced files has the same name but are placed in different directories // depending on their targets (e.g. linux/foo.kexe and macbook/foo.kexe). // 2. Custom path provided by IDE. In this case CONFIGURATION_BUILD_DIR environment variable should // contain a path to a destination directory. All produced files are placed in this directory so IDE // should take care about setting different CONFIGURATION_BUILD_DIR for different targets. protected fun determineOutputPlacement(target: KonanTarget): OutputPlacement { val configurationBuildDir = project.environmentVariables.configurationBuildDir return if (configurationBuildDir != null) { OutputPlacement(configurationBuildDir, name) } else { OutputPlacement(defaultBaseDir.targetSubdir(target), name) } } private fun createTask(target: KonanTarget): TaskProvider = project.tasks.register(generateTaskName(target), type) { val outputDescription = determineOutputPlacement(target) it.init(this, outputDescription.destinationDir, outputDescription.artifactName, target) it.group = BasePlugin.BUILD_GROUP it.description = generateTaskDescription(it) } ?: throw Exception("Cannot create task for target: ${target.visibleName}") private fun createAggregateTask(): TaskProvider = project.tasks.register(generateAggregateTaskName()) { task -> task.group = BasePlugin.BUILD_GROUP task.description = generateAggregateTaskDescription(task) targetToTask.filter { project.targetIsRequested(it.key) }.forEach { task.dependsOn(it.value) } }.also { project.compileAllTask.dependsOn(it) } protected fun createTargetAliasTaskIfDeclared(targetName: String): TaskProvider? { val canonicalTarget = project.hostManager.targetByName(targetName) return this[canonicalTarget]?.let { canonicalBuild -> project.tasks.register(generateTargetAliasTaskName(targetName)) { it.group = BasePlugin.BUILD_GROUP it.description = generateTargetAliasTaskDescription(it, targetName) it.dependsOn(canonicalBuild) } } } internal operator fun get(target: KonanTarget) = targetToTask[target] fun getByTarget(target: String) = findByTarget(target) ?: throw NoSuchElementException("No such target for artifact $name: $target") fun findByTarget(target: String) = this[project.hostManager.targetByName(target)] fun getArtifactByTarget(target: String) = getByTarget(target).get().artifact fun findArtifactByTarget(target: String) = findByTarget(target)?.get()?.artifact // Common building DSL. override fun artifactName(name: String) = tasks().forEach { it.configure { t -> t.artifactName(name) } } fun baseDir(dir: Any) = tasks().forEach { it.configure { t -> t.destinationDir( project.file(dir).targetSubdir(t.konanTarget) ) } } override fun libraries(closure: Closure) = tasks().forEach { it.configure { t -> t.libraries(closure) } } override fun libraries(action: Action) = tasks().forEach { it.configure { t -> t.libraries(action) } } override fun libraries(configure: KonanLibrariesSpec.() -> Unit) = tasks().forEach { it.configure { t -> t.libraries(configure) } } override fun noDefaultLibs(flag: Boolean) = tasks().forEach { it.configure { t -> t.noDefaultLibs(flag) } } override fun noEndorsedLibs(flag: Boolean) = tasks().forEach { it.configure { t -> t.noEndorsedLibs(flag) } } override fun dumpParameters(flag: Boolean) = tasks().forEach { it.configure { t -> t.dumpParameters(flag) } } override fun extraOpts(vararg values: Any) = tasks().forEach { it.configure { t -> t.extraOpts(*values) } } override fun extraOpts(values: List) = tasks().forEach { it.configure { t -> t.extraOpts(values) } } fun dependsOn(vararg dependencies: Any?) = tasks().forEach { it.configure { t -> t.dependsOn(*dependencies) } } fun target(targetString: String, configureAction: T.() -> Unit) { val target = project.hostManager.targetByName(targetString) if (!project.hostManager.isEnabled(target)) { project.logger.info("Target '$targetString' of artifact '$name' is not supported on the current host") return } val task = this[target] ?: throw InvalidUserDataException("Target '$targetString' is not declared. Please add it into project.konanTasks list") task.configure(configureAction) } fun target(targetString: String, configureAction: Action) = target(targetString) { configureAction.execute(this) } fun target(targetString: String, configureAction: Closure) = target(targetString, ConfigureUtil.configureUsing(configureAction)) fun pom(action: Action) = pomActions + action } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanCompileConfig.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.gradle.api.Task import org.gradle.api.file.FileCollection import org.gradle.api.internal.project.ProjectInternal import org.jetbrains.kotlin.gradle.plugin.tasks.* import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget.WASM32 import java.io.File abstract class KonanCompileConfig(name: String, type: Class, project: ProjectInternal, targets: Iterable) : KonanBuildingConfig(name, type, project, targets), KonanCompileSpec { protected abstract val typeForDescription: String override fun generateTaskDescription(task: T) = "Build the Kotlin/Native $typeForDescription '${task.name}' for target '${task.konanTarget}'" override fun generateAggregateTaskDescription(task: Task) = "Build the Kotlin/Native $typeForDescription '${task.name}' for all supported and declared targets" override fun generateTargetAliasTaskDescription(task: Task, targetName: String) = "Build the Kotlin/Native $typeForDescription '${task.name}' for target '$targetName'" override fun srcDir(dir: Any) = tasks().forEach { it.configure { t -> t.srcDir(dir) } } override fun srcFiles(vararg files: Any) = tasks().forEach { it.configure { t -> t.srcFiles(*files) } } override fun srcFiles(files: Collection) = tasks().forEach { it.configure { t -> t.srcFiles(files) } } override fun nativeLibrary(lib: Any) = tasks().forEach { it.configure { t -> t.nativeLibrary(lib) } } override fun nativeLibraries(vararg libs: Any) = tasks().forEach { it.configure { t -> t.nativeLibraries(*libs) } } override fun nativeLibraries(libs: FileCollection) = tasks().forEach { it.configure { t -> t.nativeLibraries(libs) } } @Deprecated("Use commonSourceSets instead", ReplaceWith("commonSourceSets(sourceSetName)")) override fun commonSourceSet(sourceSetName: String) = tasks().forEach { it.configure { t -> t.commonSourceSets(sourceSetName) } } override fun commonSourceSets(vararg sourceSetNames: String) = tasks().forEach { it.configure { t -> t.commonSourceSets(*sourceSetNames) } } override fun enableMultiplatform(flag: Boolean) = tasks().forEach { it.configure { t -> t.enableMultiplatform(flag) } } override fun linkerOpts(values: List) = tasks().forEach { it.configure { t -> t.linkerOpts(values) } } override fun linkerOpts(vararg values: String) = tasks().forEach { it.configure { t -> t.linkerOpts(*values) } } override fun enableDebug(flag: Boolean) = tasks().forEach { it.configure { t -> t.enableDebug(flag) } } override fun noStdLib(flag: Boolean) = tasks().forEach { it.configure { t -> t.noStdLib(flag) } } override fun noMain(flag: Boolean) = tasks().forEach { it.configure { t -> t.noMain(flag) } } override fun enableOptimizations(flag: Boolean) = tasks().forEach { it.configure { t -> t.enableOptimizations(flag) } } override fun enableAssertions(flag: Boolean) = tasks().forEach { it.configure { t -> t.enableAssertions(flag) } } override fun entryPoint(entryPoint: String) = tasks().forEach { it.configure { t -> t.entryPoint(entryPoint) } } override fun measureTime(flag: Boolean) = tasks().forEach { it.configure { t -> t.measureTime(flag) } } override fun dependencies(closure: Closure) = tasks().forEach { it.configure { t -> t.dependencies(closure) } } } open class KonanProgram(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets ) : KonanCompileConfig(name, KonanCompileProgramTask::class.java, project, targets ) { override val typeForDescription: String get() = "executable" override val defaultBaseDir: File get() = project.konanBinBaseDir } open class KonanDynamic(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets) : KonanCompileConfig(name, KonanCompileDynamicTask::class.java, project, targets ) { override val typeForDescription: String get() = "dynamic library" override val defaultBaseDir: File get() = project.konanBinBaseDir override fun targetIsSupported(target: KonanTarget): Boolean = target != WASM32 } open class KonanFramework(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets) : KonanCompileConfig(name, KonanCompileFrameworkTask::class.java, project, targets ) { override val typeForDescription: String get() = "framework" override val defaultBaseDir: File get() = project.konanBinBaseDir override fun targetIsSupported(target: KonanTarget): Boolean = target.family.isAppleFamily } open class KonanLibrary(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets) : KonanCompileConfig(name, KonanCompileLibraryTask::class.java, project, targets ) { override val typeForDescription: String get() = "library" override val defaultBaseDir: File get() = project.konanLibsBaseDir } open class KonanBitcode(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets) : KonanCompileConfig(name, KonanCompileBitcodeTask::class.java, project, targets ) { override val typeForDescription: String get() = "bitcode" override fun generateTaskDescription(task: KonanCompileBitcodeTask) = "Generates bitcode for the artifact '${task.name}' and target '${task.konanTarget}'" override fun generateAggregateTaskDescription(task: Task) = "Generates bitcode for the artifact '${task.name}' for all supported and declared targets'" override fun generateTargetAliasTaskDescription(task: Task, targetName: String) = "Generates bitcode for the artifact '${task.name}' for '$targetName'" override val defaultBaseDir: File get() = project.konanBitcodeBaseDir } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanInteropLibrary.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.Task import org.gradle.api.file.FileCollection import org.gradle.api.internal.project.ProjectInternal import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.konan.KonanInteropSpec.IncludeDirectoriesSpec import org.jetbrains.kotlin.gradle.plugin.tasks.KonanInteropTask import java.io.File open class KonanInteropLibrary(name: String, project: ProjectInternal, targets: Iterable = project.konanExtension.targets ) : KonanBuildingConfig(name, KonanInteropTask::class.java, project, targets), KonanInteropSpec { override fun generateTaskDescription(task: KonanInteropTask) = "Build the Kotlin/Native interop library '${task.name}' for target '${task.konanTarget}'" override fun generateAggregateTaskDescription(task: Task) = "Build the Kotlin/Native interop library '${task.name}' for all supported and declared targets'" override fun generateTargetAliasTaskDescription(task: Task, targetName: String) = "Build the Kotlin/Native interop library '${task.name}' for '$targetName'" override val defaultBaseDir: File get() = project.konanLibsBaseDir // DSL inner class IncludeDirectoriesSpecImpl: IncludeDirectoriesSpec { override fun allHeaders(vararg includeDirs: Any) = allHeaders(includeDirs.toList()) override fun allHeaders(includeDirs: Collection) = tasks().forEach { it.configure { t -> t.includeDirs.allHeaders(includeDirs) } } override fun headerFilterOnly(vararg includeDirs: Any) = headerFilterOnly(includeDirs.toList()) override fun headerFilterOnly(includeDirs: Collection) = tasks().forEach { it.configure { t -> t.includeDirs.headerFilterOnly(includeDirs) } } } val includeDirs = IncludeDirectoriesSpecImpl() override fun defFile(file: Any) = tasks().forEach { it.configure { t -> t.defFile(file) } } override fun packageName(value: String) = tasks().forEach { it.configure { t -> t.packageName(value) } } override fun compilerOpts(vararg values: String) = tasks().forEach { it.configure { t -> t.compilerOpts(*values) } } override fun headers(vararg files: Any) = tasks().forEach { it.configure { t -> t.headers(*files) } } override fun headers(files: FileCollection) = tasks().forEach { it.configure { t -> t.headers(files) } } override fun includeDirs(vararg values: Any) = tasks().forEach { it.configure { t -> t.includeDirs(*values) } } override fun includeDirs(closure: Closure) = includeDirs(ConfigureUtil.configureUsing(closure)) override fun includeDirs(action: Action) = includeDirs { action.execute(this) } override fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) = includeDirs.configure() override fun linkerOpts(values: List) = tasks().forEach { it.configure { t -> t.linkerOpts(values) } } override fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) override fun link(vararg files: Any) = tasks().forEach { it.configure { t -> t.link(*files) } } override fun link(files: FileCollection) = tasks().forEach { it.configure { t -> t.link(files) } } override fun dependencies(closure: Closure) = tasks().forEach { it.configure { t -> t.dependencies(closure) }} } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanLibrariesSpec.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import org.gradle.api.InvalidUserDataException import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.jetbrains.kotlin.gradle.plugin.tasks.KonanArtifactWithLibrariesTask import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask import org.jetbrains.kotlin.konan.* import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.SearchPathResolver import java.io.File open class KonanLibrariesSpec( @Internal val task: KonanArtifactWithLibrariesTask, @Internal val project: Project ) { @InputFiles val files = mutableSetOf() @Input val namedKlibs = mutableSetOf() @Internal val artifacts = mutableListOf() val artifactFiles: List @InputFiles get() = artifacts.map { it.artifact } @Internal val explicitRepos = mutableSetOf() val repos: Set @Input get() = mutableSetOf().apply { addAll(explicitRepos) add(task.destinationDir) // TODO: Check if task is a library - create a Library interface add(task.destinationDir) // TODO: Check if task is a library - create a Library interface add(task.project.konanLibsBaseDir.targetSubdir(target)) addAll(artifacts.flatMap { it.libraries.repos }) addAll(task.platformConfiguration.files.map { it.parentFile }) } val target: KonanTarget @Internal get() = task.konanTarget private val friendsTasks = mutableSetOf() @get:Internal // Taken into account by tasks's dependOn. val friends: Set get() = mutableSetOf().apply { addAll(friendsTasks.map { it.artifact }) } // DSL Methods /** Absolute path */ fun file(file: Any) = files.add(project.files(file)) fun files(vararg files: Any) = this.files.addAll(files.map { project.files(it) }) fun files(collection: FileCollection) = this.files.add(collection) /** The compiler with search the library in repos */ fun klib(lib: String) = namedKlibs.add(lib) fun klibs(vararg libs: String) = namedKlibs.addAll(libs) fun klibs(libs: Iterable) = namedKlibs.addAll(libs) private fun klibInternal(lib: KonanBuildingConfig<*>, friend: Boolean) { if (!(lib is KonanLibrary || lib is KonanInteropLibrary)) { throw InvalidUserDataException("Config ${lib.name} is not a library") } val libraryTask = lib[target]?.get() ?: throw InvalidUserDataException("Library ${lib.name} has no target ${target.visibleName}") if (libraryTask == task) { throw InvalidUserDataException("Attempt to use a library as its own dependency: " + "${task.name} (in project: ${project.path})") } artifacts.add(libraryTask) task.dependsOn(libraryTask) if (friend) friendsTasks.add(libraryTask) } /** Direct link to a config */ fun klib(lib: KonanLibrary) = klibInternal(lib, false) /** Direct link to a config */ fun klib(lib: KonanInteropLibrary) = klibInternal(lib, false) /** Artifact in the specified project by name */ fun artifact(libraryProject: Project, name: String, friend: Boolean) { project.evaluationDependsOn(libraryProject) klibInternal(libraryProject.konanArtifactsContainer.getByName(name), friend) } fun artifact(libraryProject: Project, name: String) = artifact(libraryProject, name, false) /** Artifact in the current project by name */ fun artifact(name: String, friend: Boolean) = artifact(project, name, friend) fun artifact(name: String) = artifact(project, name, false) /** Artifact by direct link */ fun artifact(artifact: KonanLibrary) = klib(artifact) /** Direct link to a config */ fun artifact(artifact: KonanInteropLibrary) = klib(artifact) private fun allArtifactsFromInternal(libraryProjects: Array, filter: (KonanBuildingConfig<*>) -> Boolean) { libraryProjects.forEach { prj -> project.evaluationDependsOn(prj) prj.konanArtifactsContainer.filter(filter).forEach { klibInternal(it, false) } } } /** All libraries (both interop and non-interop ones) from the projects by direct references */ fun allLibrariesFrom(vararg libraryProjects: Project) = allArtifactsFromInternal(libraryProjects) { it is KonanLibrary || it is KonanInteropLibrary } /** All interop libraries from the projects by direct references */ fun allInteropLibrariesFrom(vararg libraryProjects: Project) = allArtifactsFromInternal(libraryProjects) { it is KonanInteropLibrary } /** Add repo for library search */ fun useRepo(directory: Any) = explicitRepos.add(project.file(directory)) /** Add repos for library search */ fun useRepos(vararg directories: Any) = directories.forEach { useRepo(it) } /** Add repos for library search */ fun useRepos(directories: Iterable) = directories.forEach { useRepo(it) } private fun Project.evaluationDependsOn(another: Project) { if (this != another) { evaluationDependsOn(another.path) } } fun asFiles(): List = asFiles( defaultResolver( repos.map { it.absolutePath }, task.konanTarget, Distribution(project.konanHome) ) ) fun asFiles(resolver: SearchPathResolver<*>): List = mutableListOf().apply { files.flatMapTo(this) { it.files } addAll(artifactFiles) addAll(task.platformConfiguration.files) namedKlibs.mapTo(this) { project.file(resolver.resolve(it).libraryFile.absolutePath) } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanPlugin.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.codehaus.groovy.runtime.GStringImpl import org.gradle.api.* import org.gradle.api.component.ComponentWithVariants import org.gradle.api.component.SoftwareComponent import org.gradle.api.file.FileCollection import org.gradle.api.internal.FeaturePreviews import org.gradle.api.internal.component.SoftwareComponentInternal import org.gradle.api.internal.component.UsageContext import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.plugins.BasePlugin import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal import org.gradle.api.tasks.Exec import org.gradle.language.cpp.internal.NativeVariantIdentity import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME import org.jetbrains.kotlin.gradle.plugin.tasks.* import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.parseCompilerVersion import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.buildDistribution import org.jetbrains.kotlin.konan.target.customerDistribution import org.jetbrains.kotlin.konan.util.DependencyProcessor import java.io.File import javax.inject.Inject /** * We use the following properties: * org.jetbrains.kotlin.native.home - directory where compiler is located (aka dist in konan project output). * org.jetbrains.kotlin.native.version - a konan compiler version for downloading. * konan.build.targets - list of targets to build (by default all the declared targets are built). * konan.jvmArgs - additional args to be passed to a JVM executing the compiler/cinterop tool. */ internal fun Project.warnAboutDeprecatedProperty(property: KonanPlugin.ProjectProperty) = property.deprecatedPropertyName?.let { deprecated -> if (project.hasProperty(deprecated)) { logger.warn("Project property '$deprecated' is deprecated. Use '${property.propertyName}' instead.") } } internal fun Project.hasProperty(property: KonanPlugin.ProjectProperty) = with(property) { when { hasProperty(propertyName) -> true deprecatedPropertyName != null && hasProperty(deprecatedPropertyName) -> true else -> false } } internal fun Project.findProperty(property: KonanPlugin.ProjectProperty): Any? = with(property) { return findProperty(propertyName) ?: deprecatedPropertyName?.let { findProperty(it) } } internal fun Project.getProperty(property: KonanPlugin.ProjectProperty) = findProperty(property) ?: throw IllegalArgumentException("No such property in the project: ${property.propertyName}") internal fun Project.getProperty(property: KonanPlugin.ProjectProperty, defaultValue: Any) = findProperty(property) ?: defaultValue internal fun Project.setProperty(property: KonanPlugin.ProjectProperty, value: Any) { extensions.extraProperties.set(property.propertyName, value) } // konanHome extension is set by downloadKonanCompiler task. internal val Project.konanHome: String get() { assert(hasProperty(KonanPlugin.ProjectProperty.KONAN_HOME)) return project.file(getProperty(KonanPlugin.ProjectProperty.KONAN_HOME)).canonicalPath } internal val Project.konanVersion: CompilerVersion get() = project.findProperty(KonanPlugin.ProjectProperty.KONAN_VERSION) ?.toString()?.let { CompilerVersion.fromString(it) } ?: CompilerVersion.CURRENT internal val Project.konanBuildRoot get() = buildDir.resolve("konan") internal val Project.konanBinBaseDir get() = konanBuildRoot.resolve("bin") internal val Project.konanLibsBaseDir get() = konanBuildRoot.resolve("libs") internal val Project.konanBitcodeBaseDir get() = konanBuildRoot.resolve("bitcode") internal fun File.targetSubdir(target: KonanTarget) = resolve(target.visibleName) internal val Project.konanDefaultSrcFiles get() = fileTree("${projectDir.canonicalPath}/src/main/kotlin") internal fun Project.konanDefaultDefFile(libName: String) = file("${projectDir.canonicalPath}/src/main/c_interop/$libName.def") @Suppress("UNCHECKED_CAST") internal val Project.konanArtifactsContainer: KonanArtifactContainer get() = extensions.getByName(KonanPlugin.ARTIFACTS_CONTAINER_NAME) as KonanArtifactContainer // TODO: The Kotlin/Native compiler is downloaded manually by a special task so the compilation tasks // are configured without the compile distribution. After target management refactoring // we need .properties files from the distribution to configure targets. This is worked around here // by using HostManager instead of PlatformManager. But we need to download the compiler at the configuration // stage (e.g. by getting it from maven as a plugin dependency) and bring back the PlatformManager here. internal val Project.hostManager: HostManager get() = findProperty("hostManager") as HostManager? ?: if (hasProperty("org.jetbrains.kotlin.native.experimentalTargets")) HostManager(buildDistribution(rootProject.rootDir.absolutePath), true) else HostManager(customerDistribution(konanHome)) internal val Project.konanTargets: List get() = hostManager.toKonanTargets(konanExtension.targets) .filter{ hostManager.isEnabled(it) } .distinct() @Suppress("UNCHECKED_CAST") internal val Project.konanExtension: KonanExtension get() = extensions.getByName(KonanPlugin.KONAN_EXTENSION_NAME) as KonanExtension internal val Project.konanCompilerDownloadTask get() = tasks.getByName(KonanPlugin.KONAN_DOWNLOAD_TASK_NAME) internal val Project.requestedTargets get() = findProperty(KonanPlugin.ProjectProperty.KONAN_BUILD_TARGETS)?.let { it.toString().trim().split("\\s+".toRegex()) }.orEmpty() internal val Project.jvmArgs get() = (findProperty(KonanPlugin.ProjectProperty.KONAN_JVM_ARGS) as String?)?.split("\\s+".toRegex()).orEmpty() internal val Project.compileAllTask get() = getOrCreateTask(COMPILE_ALL_TASK_NAME) internal fun Project.targetIsRequested(target: KonanTarget): Boolean { val targets = requestedTargets return (targets.isEmpty() || targets.contains(target.visibleName) || targets.contains("all")) } /** Looks for task with given name in the given project. Throws [UnknownTaskException] if there's not such task. */ private fun Project.getTask(name: String): Task = tasks.getByPath(name) /** * Looks for task with given name in the given project. * If such task isn't found, will create it. Returns created/found task. */ private fun Project.getOrCreateTask(name: String): Task = with(tasks) { findByPath(name) ?: create(name, DefaultTask::class.java) } internal fun Project.konanCompilerName(): String = "kotlin-native-${project.simpleOsName}-${project.konanVersion}" internal fun Project.konanCompilerDownloadDir(): String = DependencyProcessor.localKonanDir.resolve(project.konanCompilerName()).absolutePath // region Useful extensions and functions --------------------------------------- internal fun MutableList.addArg(parameter: String, value: String) { add(parameter) add(value) } internal fun MutableList.addArgs(parameter: String, values: Iterable) { values.forEach { addArg(parameter, it) } } internal fun MutableList.addArgIfNotNull(parameter: String, value: String?) { if (value != null) { addArg(parameter, value) } } internal fun MutableList.addKey(key: String, enabled: Boolean) { if (enabled) { add(key) } } internal fun MutableList.addFileArgs(parameter: String, values: FileCollection) { values.files.forEach { addArg(parameter, it.canonicalPath) } } internal fun MutableList.addFileArgs(parameter: String, values: Collection) { values.forEach { addFileArgs(parameter, it) } } // endregion internal fun dumpProperties(task: Task) { fun Iterable.dump() = joinToString(prefix = "[", separator = ",\n${" ".repeat(22)}", postfix = "]") fun Collection.dump() = flatMap { it.files }.map { it.canonicalPath }.dump() when (task) { is KonanCompileTask -> with(task) { println() println("Compilation task: $name") println("destinationDir : $destinationDir") println("artifact : ${artifact.canonicalPath}") println("srcFiles : ${srcFiles.dump()}") println("produce : $produce") println("libraries : ${libraries.files.dump()}") println(" : ${libraries.artifacts.map { it.artifact.canonicalPath }.dump()}") println(" : ${libraries.namedKlibs.dump()}") println("nativeLibraries : ${nativeLibraries.dump()}") println("linkerOpts : $linkerOpts") println("enableDebug : $enableDebug") println("noStdLib : $noStdLib") println("noMain : $noMain") println("enableOptimization : $enableOptimizations") println("enableAssertions : $enableAssertions") println("noDefaultLibs : $noDefaultLibs") println("noEndorsedLibs : $noEndorsedLibs") println("target : $target") println("languageVersion : $languageVersion") println("apiVersion : $apiVersion") println("konanVersion : ${CompilerVersion.CURRENT}") println("konanHome : $konanHome") println() } is KonanInteropTask -> with(task) { println() println("Stub generation task: $name") println("destinationDir : $destinationDir") println("artifact : $artifact") println("libraries : ${libraries.files.dump()}") println(" : ${libraries.artifacts.map { it.artifact.canonicalPath }.dump()}") println(" : ${libraries.namedKlibs.dump()}") println("defFile : $defFile") println("target : $target") println("packageName : $packageName") println("compilerOpts : $compilerOpts") println("linkerOpts : $linkerOpts") println("headers : ${headers.dump()}") println("linkFiles : ${linkFiles.dump()}") println("konanVersion : ${CompilerVersion.CURRENT}") println("konanHome : $konanHome") println() } else -> { println("Unsupported task.") } } } open class KonanExtension { var targets = mutableListOf("host") var languageVersion: String? = null var apiVersion: String? = null var jvmArgs = mutableListOf() } open class KonanSoftwareComponent(val project: ProjectInternal?): SoftwareComponentInternal, ComponentWithVariants { private val usages = mutableSetOf() override fun getUsages(): MutableSet = usages private val variants = mutableSetOf() override fun getName() = "main" override fun getVariants(): Set = variants fun addVariant(component: SoftwareComponent) = variants.add(component) } class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderRegistry) : Plugin { enum class ProjectProperty(val propertyName: String, val deprecatedPropertyName: String? = null) { KONAN_HOME ("org.jetbrains.kotlin.native.home", "konan.home"), KONAN_VERSION ("org.jetbrains.kotlin.native.version"), KONAN_BUILD_TARGETS ("konan.build.targets"), KONAN_JVM_ARGS ("konan.jvmArgs"), KONAN_USE_ENVIRONMENT_VARIABLES("konan.useEnvironmentVariables"), DOWNLOAD_COMPILER ("download.compiler"), // Properties used instead of env vars until https://github.com/gradle/gradle/issues/3468 is fixed. // TODO: Remove them when an API for env vars is provided. KONAN_CONFIGURATION_BUILD_DIR ("konan.configuration.build.dir"), KONAN_DEBUGGING_SYMBOLS ("konan.debugging.symbols"), KONAN_OPTIMIZATIONS_ENABLE ("konan.optimizations.enable"), } companion object { internal const val ARTIFACTS_CONTAINER_NAME = "konanArtifacts" internal const val KONAN_DOWNLOAD_TASK_NAME = "checkKonanCompiler" internal const val KONAN_GENERATE_CMAKE_TASK_NAME = "generateCMake" internal const val COMPILE_ALL_TASK_NAME = "compileKonan" internal const val KONAN_EXTENSION_NAME = "konan" internal val REQUIRED_GRADLE_VERSION = GradleVersion.version("4.7") } private fun Project.cleanKonan() = project.tasks.withType(KonanBuildingTask::class.java).forEach { project.delete(it.artifact) } private fun checkGradleVersion() = GradleVersion.current().let { current -> check(current >= REQUIRED_GRADLE_VERSION) { "Kotlin/Native Gradle plugin is incompatible with this version of Gradle.\n" + "The minimal required version is $REQUIRED_GRADLE_VERSION\n" + "Current version is ${current}" } } override fun apply(project: ProjectInternal?) { if (project == null) { return } checkGradleVersion() project.plugins.apply("base") // Create necessary tasks and extensions. project.tasks.create(KONAN_DOWNLOAD_TASK_NAME, KonanCompilerDownloadTask::class.java) project.extensions.create(KONAN_EXTENSION_NAME, KonanExtension::class.java) val container = project.extensions.create( KonanArtifactContainer::class.java, ARTIFACTS_CONTAINER_NAME, KonanArtifactContainer::class.java, project ) project.warnAboutDeprecatedProperty(ProjectProperty.KONAN_HOME) // Set additional project properties like org.jetbrains.kotlin.native.home, konan.build.targets etc. if (!project.hasProperty(ProjectProperty.KONAN_HOME)) { project.setProperty(ProjectProperty.KONAN_HOME, project.konanCompilerDownloadDir()) project.setProperty(ProjectProperty.DOWNLOAD_COMPILER, true) } // Create and set up aggregate building tasks. val compileKonanTask = project.getOrCreateTask(COMPILE_ALL_TASK_NAME).apply { group = BasePlugin.BUILD_GROUP description = "Compiles all the Kotlin/Native artifacts" } project.getTask("build").apply { dependsOn(compileKonanTask) } project.getTask("clean").apply { doLast { project.cleanKonan() } } project.afterEvaluate { project.tasks .withType(KonanCompileProgramTask::class.java) .forEach { task -> val isCrossCompile = (task.target != HostManager.host.visibleName) if (!isCrossCompile && !project.hasProperty("konanNoRun")) task.runTask = project.tasks.register("run${task.artifactName.capitalize()}", Exec::class.java) { it.group= "run" it.dependsOn(task) val artifactPathClosure = object : Closure(this) { override fun call() = task.artifactPath } // Use GString to evaluate a path to the artifact lazily thus allow changing it at configuration phase. val lazyArtifactPath = GStringImpl(arrayOf(artifactPathClosure), arrayOf("")) it.executable(lazyArtifactPath) // Add values passed in the runArgs project property as arguments. it.argumentProviders.add(task.RunArgumentProvider()) } } } val runTask = project.getOrCreateTask("run") project.afterEvaluate { project.konanArtifactsContainer .filterIsInstance(KonanProgram::class.java) .forEach { program -> program.tasks().forEach { compile -> compile.configure { it.runTask?.let { runTask.dependsOn(it) } } } } } // Enable multiplatform support project.pluginManager.apply(KotlinNativePlatformPlugin::class.java) project.afterEvaluate { project.pluginManager.withPlugin("maven-publish") { container.all { buildingConfig -> val konanSoftwareComponent = buildingConfig.mainVariant project.extensions.configure(PublishingExtension::class.java) { val builtArtifact = buildingConfig.name val mavenPublication = it.publications.maybeCreate(builtArtifact, MavenPublication::class.java) mavenPublication.apply { artifactId = builtArtifact groupId = project.group.toString() from(konanSoftwareComponent) } (mavenPublication as MavenPublicationInternal).publishWithOriginalFileName() buildingConfig.pomActions.forEach { mavenPublication.pom(it) } } project.extensions.configure(PublishingExtension::class.java) { val publishing = it for (v in konanSoftwareComponent.variants) { publishing.publications.create(v.name, MavenPublication::class.java) { mavenPublication -> val coordinates = (v as NativeVariantIdentity).coordinates project.logger.info("variant with coordinates($coordinates) and module: ${coordinates.module}") mavenPublication.artifactId = coordinates.module.name mavenPublication.groupId = coordinates.group mavenPublication.version = coordinates.version mavenPublication.from(v) (mavenPublication as MavenPublicationInternal).publishWithOriginalFileName() buildingConfig.pomActions.forEach { mavenPublication.pom(it) } } } } } } } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanSpecs.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.file.FileCollection interface KonanArtifactSpec { fun artifactName(name: String) } interface KonanArtifactWithLibrariesSpec: KonanArtifactSpec { fun libraries(closure: Closure) fun libraries(action: Action) fun libraries(configure: KonanLibrariesSpec.() -> Unit) fun noDefaultLibs(flag: Boolean) fun noEndorsedLibs(flag: Boolean) fun dependencies(closure: Closure) } interface KonanBuildingSpec: KonanArtifactWithLibrariesSpec { fun dumpParameters(flag: Boolean) fun extraOpts(vararg values: Any) fun extraOpts(values: List) } interface KonanCompileSpec: KonanBuildingSpec { fun srcDir(dir: Any) fun srcFiles(vararg files: Any) fun srcFiles(files: Collection) // DSL. Native libraries. fun nativeLibrary(lib: Any) fun nativeLibraries(vararg libs: Any) fun nativeLibraries(libs: FileCollection) // DSL. Multiplatform projects fun enableMultiplatform(flag: Boolean) // TODO: Get rid of commonSourceSet in 0.7 @Deprecated("Use commonSourceSets instead", ReplaceWith("commonSourceSets(sourceSetName)")) fun commonSourceSet(sourceSetName: String) fun commonSourceSets(vararg sourceSetNames: String) // DSL. Other parameters. fun linkerOpts(vararg values: String) fun linkerOpts(values: List) fun enableDebug(flag: Boolean) fun noStdLib(flag: Boolean) fun noMain(flag: Boolean) fun enableOptimizations(flag: Boolean) fun enableAssertions(flag: Boolean) fun entryPoint(entryPoint: String) fun measureTime(flag: Boolean) } interface KonanInteropSpec: KonanBuildingSpec { interface IncludeDirectoriesSpec { fun allHeaders(vararg includeDirs: Any) fun allHeaders(includeDirs: Collection) fun headerFilterOnly(vararg includeDirs: Any) fun headerFilterOnly(includeDirs: Collection) } fun defFile(file: Any) fun packageName(value: String) fun compilerOpts(vararg values: String) fun header(file: Any) = headers(file) fun headers(vararg files: Any) fun headers(files: FileCollection) fun includeDirs(vararg values: Any) fun includeDirs(closure: Closure) fun includeDirs(action: Action) fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) fun linkerOpts(vararg values: String) fun linkerOpts(values: List) fun link(vararg files: Any) fun link(files: FileCollection) } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KonanToolRunner.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.konan import org.gradle.api.Named import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.gradle.plugin.konan.KonanPlugin.ProjectProperty.KONAN_HOME import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.DependencyProcessor import java.nio.file.Files internal interface KonanToolRunner: Named { val mainClass: String val classpath: FileCollection val jvmArgs: List val environment: Map fun run(args: List) fun run(vararg args: String) = run(args.toList()) } internal abstract class KonanCliRunner( val toolName: String, val fullName: String, val project: Project, private val additionalJvmArgs: List, private val konanHome: String ): KonanToolRunner { override val mainClass = "org.jetbrains.kotlin.cli.utilities.MainKt" override fun getName() = toolName // We need to unset some environment variables which are set by XCode and may potentially affect the tool executed. protected val blacklistEnvironment: List by lazy { KonanPlugin::class.java.getResourceAsStream("/env_blacklist")?.let { stream -> stream.reader().use { it.readLines() } } ?: emptyList() } protected val blacklistProperties: Set = setOf("java.endorsed.dirs") override val classpath: FileCollection = project.fileTree("$konanHome/konan/lib/") .apply { include("*.jar") } override val jvmArgs = HostManager.defaultJvmArgs.toMutableList().apply { if (additionalJvmArgs.none { it.startsWith("-Xmx") } && project.jvmArgs.none { it.startsWith("-Xmx") }) { add("-Xmx3G") } addAll(additionalJvmArgs) addAll(project.jvmArgs) } override val environment = mutableMapOf("LIBCLANG_DISABLE_CRASH_RECOVERY" to "1") private fun String.escapeQuotes() = replace("\"", "\\\"") private fun Sequence>.escapeQuotesForWindows() = if (HostManager.hostIsMingw) { map { (key, value) -> key.escapeQuotes() to value.escapeQuotes() } } else { this } open protected fun transformArgs(args: List): List = args override fun run(args: List) { project.logger.info("Run tool: $toolName with args: ${args.joinToString(separator = " ")}") if (classpath.isEmpty) { throw IllegalStateException("Classpath of the tool is empty: $toolName\n" + "Probably the '${KONAN_HOME.propertyName}' project property contains an incorrect path.\n" + "Please change it to the compiler root directory and rerun the build.") } project.javaexec { spec -> spec.main = mainClass spec.classpath = classpath spec.jvmArgs(jvmArgs) spec.systemProperties( System.getProperties().asSequence() .map { (k, v) -> k.toString() to v.toString() } .filter { (k, _) -> k !in blacklistProperties } .escapeQuotesForWindows() .toMap() ) spec.args(listOf(toolName) + transformArgs(args)) blacklistEnvironment.forEach { spec.environment.remove(it) } spec.environment(environment) } } } internal class KonanInteropRunner( project: Project, additionalJvmArgs: List = emptyList(), konanHome: String = project.konanHome ) : KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs, konanHome) { init { if (HostManager.host == KonanTarget.MINGW_X64) { //TODO: Oh-ho-ho fix it in more convinient way. environment.put("PATH", DependencyProcessor.defaultDependenciesRoot.absolutePath + "\\msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1" + "\\bin;${environment.get("PATH")}") } } } internal class KonanCompilerRunner( project: Project, additionalJvmArgs: List = emptyList(), val useArgFile: Boolean = true, konanHome: String = project.konanHome ) : KonanCliRunner("konanc", "Kotlin/Native compiler", project, additionalJvmArgs, konanHome) { override fun transformArgs(args: List): List { if (!useArgFile) { return args } val argFile = Files.createTempFile("konancArgs", ".lst").toAbsolutePath().apply { toFile().deleteOnExit() } Files.write(argFile, args) return listOf("@${argFile}") } } internal class KonanKlibRunner( project: Project, additionalJvmArgs: List = emptyList(), konanHome: String = project.konanHome ) : KonanCliRunner("klib", "Klib management tool", project, additionalJvmArgs, konanHome) ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/KotlinNativePlatformPlugin.kt ================================================ package org.jetbrains.kotlin.gradle.plugin.konan import org.gradle.api.Named import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformImplementationPluginBase import org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompileTask import javax.inject.Inject open class KotlinNativePlatformPlugin: KotlinPlatformImplementationPluginBase("native") { private val Project.konanMultiplatformTasks: Collection get() = tasks.withType(KonanCompileTask::class.java).filter { it.enableMultiplatform } open class RequestedCommonSourceSet @Inject constructor(private val name: String): Named { override fun getName() = name } override fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) { val commonSourceSetName = commonSourceSet.name platformProject.konanMultiplatformTasks .filter { it.commonSourceSets.contains(commonSourceSetName) } .forEach { task: KonanCompileTask -> getKotlinSourceDirectorySetSafe(commonSourceSet)!!.srcDirs.forEach { task.commonSrcDir(it) } } } override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> = project.container(RequestedCommonSourceSet::class.java).apply { project.konanMultiplatformTasks.forEach { task -> task.commonSourceSets.forEach { maybeCreate(it) } } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanBaseTasks.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.tasks import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.artifacts.* import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.Usage import org.gradle.api.capabilities.Capability import org.gradle.api.internal.component.UsageContext import org.gradle.api.internal.tasks.DefaultTaskDependency import org.gradle.api.tasks.* import org.gradle.language.cpp.CppBinary import org.gradle.language.cpp.internal.DefaultUsageContext import org.gradle.nativeplatform.Linkage import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.experimental.internal.compatibleVariantIdentity import org.jetbrains.kotlin.gradle.plugin.konan.* import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File import java.util.* internal val Project.host get() = HostManager.host.visibleName internal val Project.simpleOsName get() = HostManager.simpleOsName() /** A task with a KonanTarget specified. */ abstract class KonanTargetableTask: DefaultTask() { @get:Input val konanTargetName: String get() = konanTarget.name @get:Internal internal lateinit var konanTarget: KonanTarget internal open fun init(target: KonanTarget) { this.konanTarget = target } val isCrossCompile: Boolean @Internal get() = (konanTarget != HostManager.host) val target: String @Internal get() = konanTarget.visibleName } /** A task building an artifact. */ abstract class KonanArtifactTask: KonanTargetableTask(), KonanArtifactSpec { open val artifact: File @OutputFile get() = destinationDir.resolve(artifactFullName) @Internal lateinit var destinationDir: File @Internal lateinit var artifactName: String @Internal lateinit var platformConfiguration: Configuration @Internal lateinit var configuration: Configuration protected val artifactFullName: String @Internal get() = "$artifactPrefix$artifactName$artifactSuffix" val artifactPath: String @Internal get() = artifact.canonicalPath protected abstract val artifactSuffix: String @Internal get protected abstract val artifactPrefix: String @Internal get internal open fun init(config: KonanBuildingConfig<*>, destinationDir: File, artifactName: String, target: KonanTarget) { super.init(target) this.destinationDir = destinationDir this.artifactName = artifactName configuration = project.configurations.maybeCreate("artifact$artifactName") platformConfiguration = project.configurations.create("artifact${artifactName}_${target.name}") platformConfiguration.extendsFrom(configuration) platformConfiguration.attributes{ it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.NATIVE_LINK)) it.attribute(CppBinary.LINKAGE_ATTRIBUTE, Linkage.STATIC) it.attribute(CppBinary.OPTIMIZED_ATTRIBUTE, false) it.attribute(CppBinary.DEBUGGABLE_ATTRIBUTE, false) it.attribute(Attribute.of("org.gradle.native.kotlin.platform", String::class.java), target.name) } val artifactNameWithoutSuffix = artifact.name.removeSuffix("$artifactSuffix") project.pluginManager.withPlugin("maven-publish") { platformConfiguration.artifacts.add(object: PublishArtifact { override fun getName(): String = artifactNameWithoutSuffix override fun getExtension() = if (artifactSuffix.startsWith('.')) artifactSuffix.substring(1) else artifactSuffix override fun getType() = artifactSuffix override fun getClassifier():String? = target.name override fun getFile() = artifact override fun getDate() = Date(artifact.lastModified()) override fun getBuildDependencies(): TaskDependency = DefaultTaskDependency().apply { add(this@KonanArtifactTask) } }) val objectFactory = project.objects val linkUsage = objectFactory.named(Usage::class.java, Usage.NATIVE_LINK) val konanSoftwareComponent = config.mainVariant val variantName = "${artifactNameWithoutSuffix}_${target.name}" val context = DefaultUsageContext(object:UsageContext { override fun getUsage(): Usage = linkUsage override fun getName(): String = "${variantName}Link" override fun getCapabilities(): MutableSet = mutableSetOf() override fun getDependencies(): MutableSet = mutableSetOf() override fun getDependencyConstraints(): MutableSet = mutableSetOf() override fun getArtifacts(): MutableSet = platformConfiguration.allArtifacts override fun getAttributes(): AttributeContainer = platformConfiguration.attributes override fun getGlobalExcludes(): Set = emptySet() }, platformConfiguration.allArtifacts, platformConfiguration) konanSoftwareComponent.addVariant( compatibleVariantIdentity( project, variantName, project.provider{ artifactName }, project.provider{ project.group.toString() }, project.provider{ project.version.toString() }, false, false, target, context, null ) ) } } fun dependencies(closure: Closure) { if (konanTarget in project.konanTargets) project.dependencies(closure) } // DSL. override fun artifactName(name: String) { artifactName = name } fun destinationDir(dir: Any) { destinationDir = project.file(dir) } } /** Task building an artifact with libraries */ abstract class KonanArtifactWithLibrariesTask: KonanArtifactTask(), KonanArtifactWithLibrariesSpec { @Nested val libraries = KonanLibrariesSpec(this, project) @Input var noDefaultLibs = false @Input var noEndorsedLibs = false // DSL override fun libraries(closure: Closure) = libraries(ConfigureUtil.configureUsing(closure)) override fun libraries(action: Action) = libraries { action.execute(this) } override fun libraries(configure: KonanLibrariesSpec.() -> Unit) { libraries.configure() } override fun noDefaultLibs(flag: Boolean) { noDefaultLibs = flag } override fun noEndorsedLibs(flag: Boolean) { noEndorsedLibs = flag } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanBuildingTask.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.tasks import org.gradle.api.tasks.Console import org.gradle.api.tasks.Input import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.gradle.plugin.konan.* import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File /** Base class for both interop and compiler tasks. */ abstract class KonanBuildingTask: KonanArtifactWithLibrariesTask(), KonanBuildingSpec { @get:Internal internal abstract val toolRunner: KonanToolRunner override fun init(config: KonanBuildingConfig<*>, destinationDir: File, artifactName: String, target: KonanTarget) { dependsOn(project.konanCompilerDownloadTask) super.init(config, destinationDir, artifactName, target) } @Console var dumpParameters: Boolean = false @Input val extraOpts = mutableListOf() val konanHome @Input get() = project.konanHome val konanVersion @Input get() = project.konanVersion.toString(true, true) @TaskAction abstract fun run() // DSL. override fun dumpParameters(flag: Boolean) { dumpParameters = flag } override fun extraOpts(vararg values: Any) = extraOpts(values.toList()) override fun extraOpts(values: List) { extraOpts.addAll(values.map { it.toString() }) } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCacheTask.kt ================================================ package org.jetbrains.kotlin.gradle.plugin.konan.tasks import org.gradle.api.DefaultTask import org.gradle.api.provider.Property import org.gradle.api.tasks.* import org.jetbrains.kotlin.gradle.plugin.konan.KonanCompilerRunner import org.jetbrains.kotlin.gradle.plugin.konan.konanHome import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.PlatformManager import java.io.File enum class KonanCacheKind(val outputKind: CompilerOutputKind) { STATIC(CompilerOutputKind.STATIC_CACHE), DYNAMIC(CompilerOutputKind.DYNAMIC_CACHE) } open class KonanCacheTask: DefaultTask() { @InputDirectory lateinit var originalKlib: File // Taken into account by the [cacheFile] property. @Internal lateinit var cacheRoot: File @get:Input lateinit var target: String @get:Internal // TODO: Reuse NativeCacheKind from Big Kotlin plugin when it is available. val cacheDirectory: File get() = cacheRoot.resolve("$target-g$cacheKind") @get:OutputDirectory protected val cacheFile: File get() { val klibName = originalKlib.let { if (it.isDirectory) it.name else it.nameWithoutExtension } return cacheDirectory.resolve("${klibName}-cache") } @Input var cacheKind: KonanCacheKind = KonanCacheKind.STATIC @Input /** Path to a compiler distribution that is used to build this cache. */ val compilerDistributionPath: Property = project.objects.property(File::class.java).apply { set(project.provider { project.file(project.konanHome) }) } @TaskAction fun compile() { // Compiler doesn't create a cache if the cacheFile already exists. So we need to remove it manually. if (cacheFile.exists()) { val deleted = cacheFile.deleteRecursively() check(deleted) { "Cannot delete stale cache: ${cacheFile.absolutePath}" } } val konanHome = compilerDistributionPath.get().absolutePath val additionalCacheFlags = PlatformManager(konanHome).let { it.targetByName(target).let(it::loader).additionalCacheFlags } val args = listOf( "-g", "-target", target, "-produce", cacheKind.outputKind.name.toLowerCase(), "-Xadd-cache=${originalKlib.absolutePath}", "-Xcache-directory=${cacheDirectory.absolutePath}" ) + additionalCacheFlags KonanCompilerRunner(project, konanHome = konanHome).run(args) } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompileTask.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.tasks import groovy.lang.Closure import org.codehaus.groovy.runtime.GStringImpl import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* import org.gradle.process.CommandLineArgumentProvider import org.jetbrains.kotlin.gradle.plugin.konan.* import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File /** * A task compiling the target executable/library using Kotlin/Native compiler */ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { @get:Internal override val toolRunner = KonanCompilerRunner(project, project.konanExtension.jvmArgs) abstract val produce: CompilerOutputKind @Internal get // Output artifact -------------------------------------------------------- override val artifactSuffix: String @Internal get() = produce.suffix(konanTarget) override val artifactPrefix: String @Internal get() = produce.prefix(konanTarget) // Multiplatform support -------------------------------------------------- @Input var commonSourceSets = listOf("main") @Internal var enableMultiplatform = false private val commonSrcFiles_ = mutableSetOf() val commonSrcFiles: Collection @Internal get() = if (enableMultiplatform) commonSrcFiles_ else emptyList() // Other compilation parameters ------------------------------------------- private val srcFiles_ = mutableSetOf() val srcFiles: Collection @Internal get() = srcFiles_.takeIf { !it.isEmpty() } ?: listOf(project.konanDefaultSrcFiles) val allSources: Collection @InputFiles get() = listOf(srcFiles, commonSrcFiles).flatten() private val allSourceFiles: List get() = allSources .flatMap { it.files } .filter { it.name.endsWith(".kt") } @InputFiles val nativeLibraries = mutableSetOf() @Input val linkerOpts = mutableListOf() @Input var enableDebug = project.findProperty("enableDebug")?.toString()?.toBoolean() ?: project.environmentVariables.debuggingSymbols @Input var noStdLib = false @Input var noMain = false @Input var enableOptimizations = project.environmentVariables.enableOptimizations @Input var enableAssertions = false @Optional @Input var entryPoint: String? = null @Console var measureTime = false val languageVersion : String? @Optional @Input get() = project.konanExtension.languageVersion val apiVersion : String? @Optional @Input get() = project.konanExtension.apiVersion /** * Is the two-stage compilation enabled. * * In regular (one-stage) compilation, sources are directly compiled into a final native binary. * In two-stage compilation, sources are compiled into a klib first and then a final native binary is produced from this klib. */ @get:Input abstract val enableTwoStageCompilation: Boolean protected fun directoryToKt(dir: Any) = project.fileTree(dir).apply { include("**/*.kt") exclude { it.file.startsWith(project.buildDir) } } // Command line ------------------------------------------------------------ // Exclude elements matching the predicate. private fun List.excludeFlags(predicate: (String) -> Boolean) = filterNot(predicate) // Exclude the listed elements. private fun List.excludeFlags(vararg keys: String) = keys.toSet().let { keysToExclude -> excludeFlags { it in keysToExclude } } // Exclude the arguments passed by the given keys. // E.g. if the list contains the following elements: ["-l", "foo", "-r", "bar"], // call exclude("-r") returns the following list: ["-l", "foo"]. private fun List.excludeArguments(vararg args: String): List { val argsToExclude = args.toSet() val xPrefixesToExclude = argsToExclude.filter { it.startsWith("-X") }.map { "$it=" } val result = mutableListOf() var i = 0 while (i < size) { val key = this[i] when { key in argsToExclude -> { // Skip the key and the following arg. i++ } // Support args passed as -X=. xPrefixesToExclude.any { key.startsWith(it) } -> { /* Skip the key. */ } else -> result += key } i++ } return result } // Don't include coverage flags into the first stage because they are not supported when compiling a klib. private fun firstStageExtraOpts() = extraOpts .excludeFlags("-Xcoverage") .excludeArguments("-Xcoverage-file", "-Xlibrary-to-cover") // Don't include the -Xemit-lazy-objc-header flag into // the second stage because this stage have no sources. private fun secondStageExtraOpts() = extraOpts .excludeArguments("-Xemit-lazy-objc-header") /** Args passed to the compiler at the first stage of two-stage compilation (klib building). */ protected fun buildFirstStageArgs(klibPath: String) = mutableListOf().apply { addArg("-output", klibPath) addArg("-produce", CompilerOutputKind.LIBRARY.name.toLowerCase()) addAll(buildCommonArgs()) addAll(firstStageExtraOpts()) allSourceFiles.mapTo(this) { it.absolutePath } commonSrcFiles .flatMap { it.files } .mapTo(this) { "-Xcommon-sources=${it.absolutePath}" } } /** Args passed to the compiler at the second stage of two-stage compilation (producing a final binary from the klib). */ protected fun buildSecondStageArgs(klibPath: String) = mutableListOf().apply { addArg("-output", artifact.canonicalPath) addArg("-produce", produce.name.toLowerCase()) addArgIfNotNull("-entry", entryPoint) addAll(buildCommonArgs()) addFileArgs("-native-library", nativeLibraries) linkerOpts.forEach { addArg("-linker-option", it) } addAll(secondStageExtraOpts()) add("-Xinclude=${klibPath}") } /** Args passed to the compiler at both stages of the two-stage compilation and during the singe-stage compilation. */ protected fun buildCommonArgs() = mutableListOf().apply { addArgs("-repo", libraries.repos.map { it.canonicalPath }) if (platformConfiguration.files.isNotEmpty()) { platformConfiguration.files.filter { it.name.endsWith(".klib") }.forEach { // The library's directory is added in libraries.repos. addArg("-library", it.nameWithoutExtension) } } addFileArgs("-library", libraries.files) addArgs("-library", libraries.namedKlibs) // The library's directory is added in libraries.repos. addArgs("-library", libraries.artifacts.map { it.artifact.nameWithoutExtension }) addArgIfNotNull("-target", konanTarget.visibleName) addArgIfNotNull("-language-version", languageVersion) addArgIfNotNull("-api-version", apiVersion) addArgIfNotNull("-entry", entryPoint) addKey("-g", enableDebug) addKey("-nostdlib", noStdLib) addKey("-nomain", noMain) addKey("-opt", enableOptimizations) addKey("-ea", enableAssertions) addKey("-Xtime", measureTime) addKey("-Xprofile-phases", measureTime) addKey("-no-default-libs", noDefaultLibs) addKey("-no-endorsed-libs", noEndorsedLibs) addKey("-Xmulti-platform", enableMultiplatform) if (libraries.friends.isNotEmpty()) addArg("-friend-modules", libraries.friends.joinToString(File.pathSeparator)) } /** Args passed to the compiler if the two-stage compilation is disabled. */ fun buildSingleStageArgs() = mutableListOf().apply { addArg("-output", artifact.canonicalPath) addArg("-produce", produce.name.toLowerCase()) addArgIfNotNull("-entry", entryPoint) addAll(buildCommonArgs()) addFileArgs("-native-library", nativeLibraries) linkerOpts.forEach { addArg("-linker-option", it) } addAll(extraOpts) allSourceFiles.mapTo(this) { it.absolutePath } commonSrcFiles .flatMap { it.files } .mapTo(this) { "-Xcommon-sources=${it.absolutePath}" } } // region DSL. // DSL. Input/output files. override fun srcDir(dir: Any) { srcFiles_.add(directoryToKt(dir)) } override fun srcFiles(vararg files: Any) { srcFiles_.add(project.files(files)) } override fun srcFiles(files: Collection) = srcFiles(*files.toTypedArray()) // DSL. Native libraries. override fun nativeLibrary(lib: Any) = nativeLibraries(lib) override fun nativeLibraries(vararg libs: Any) { nativeLibraries.add(project.files(*libs)) } override fun nativeLibraries(libs: FileCollection) { nativeLibraries.add(libs) } // DSL. Multiplatform projects. override fun enableMultiplatform(flag: Boolean) { enableMultiplatform = flag } @Deprecated("Use commonSourceSets instead", ReplaceWith("commonSourceSets(sourceSetName)")) override fun commonSourceSet(sourceSetName: String) { commonSourceSets = listOf(sourceSetName) enableMultiplatform(true) } override fun commonSourceSets(vararg sourceSetNames: String) { commonSourceSets = sourceSetNames.toList() enableMultiplatform(true) } internal fun commonSrcDir(dir: Any) { commonSrcFiles_.add(directoryToKt(dir)) } // DSL. Other parameters. override fun linkerOpts(values: List) = linkerOpts(*values.toTypedArray()) override fun linkerOpts(vararg values: String) { linkerOpts.addAll(values) } override fun enableDebug(flag: Boolean) { enableDebug = flag } override fun noStdLib(flag: Boolean) { noStdLib = flag } override fun noMain(flag: Boolean) { noMain = flag } override fun enableOptimizations(flag: Boolean) { enableOptimizations = flag } override fun enableAssertions(flag: Boolean) { enableAssertions = flag } override fun entryPoint(entryPoint: String) { this.entryPoint = entryPoint } override fun measureTime(flag: Boolean) { measureTime = flag } // endregion override fun run() { destinationDir.mkdirs() if (dumpParameters) { dumpProperties(this) } if (enableTwoStageCompilation) { logger.info("Start two-stage compilation") val intermediateDir = project.konanBuildRoot .resolve("intermediate") .targetSubdir(konanTarget) .apply { mkdirs() } val klibPrefix = CompilerOutputKind.LIBRARY.prefix(konanTarget) val klibSuffix = CompilerOutputKind.LIBRARY.suffix(konanTarget) val intermediateKlib = intermediateDir.resolve("$klibPrefix$artifactName$klibSuffix").absolutePath logger.info("Start first stage") toolRunner.run(buildFirstStageArgs(intermediateKlib)) logger.info("Start second stage") toolRunner.run(buildSecondStageArgs(intermediateKlib)) } else { toolRunner.run(buildSingleStageArgs()) } } } abstract class KonanCompileNativeBinary: KonanCompileTask() { @Input override var enableTwoStageCompilation: Boolean = false } open class KonanCompileProgramTask: KonanCompileNativeBinary() { override val produce: CompilerOutputKind get() = CompilerOutputKind.PROGRAM @Internal var runTask: TaskProvider? = null inner class RunArgumentProvider: CommandLineArgumentProvider { override fun asArguments() = project.findProperty("runArgs")?.let { it.toString().split(' ') } ?: emptyList() } } open class KonanCompileDynamicTask: KonanCompileNativeBinary() { override val produce: CompilerOutputKind get() = CompilerOutputKind.DYNAMIC val headerFile: File @OutputFile get() = destinationDir.resolve("$artifactPrefix${artifactName}_api.h") } open class KonanCompileFrameworkTask: KonanCompileNativeBinary() { override val produce: CompilerOutputKind get() = CompilerOutputKind.FRAMEWORK override val artifact @OutputDirectory get() = super.artifact } open class KonanCompileLibraryTask: KonanCompileTask() { override val produce: CompilerOutputKind get() = CompilerOutputKind.LIBRARY override val enableTwoStageCompilation: Boolean = false } open class KonanCompileBitcodeTask: KonanCompileNativeBinary() { override val produce: CompilerOutputKind get() = CompilerOutputKind.BITCODE } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanCompilerDownloadTask.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.tasks import org.gradle.api.DefaultTask import org.gradle.api.GradleScriptException import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.gradle.plugin.konan.* import org.jetbrains.kotlin.konan.MetaVersion import org.jetbrains.kotlin.konan.util.DependencyProcessor import org.jetbrains.kotlin.konan.util.DependencySource import java.io.IOException open class KonanCompilerDownloadTask : DefaultTask() { internal companion object { internal const val BASE_DOWNLOAD_URL = "https://download.jetbrains.com/kotlin/native/builds" } /** * If true the task will also download dependencies for targets specified by the konan.targets project extension. */ @Internal var downloadDependencies: Boolean = false @TaskAction fun downloadAndExtract() { if (!project.hasProperty(KonanPlugin.ProjectProperty.DOWNLOAD_COMPILER)) { val konanHome = project.getProperty(KonanPlugin.ProjectProperty.KONAN_HOME) logger.info("Use a user-defined compiler path: $konanHome") } else { try { val downloadUrlDirectory = buildString { append("$BASE_DOWNLOAD_URL/") val version = project.konanVersion when (version.meta) { MetaVersion.DEV -> append("dev/") else -> append("releases/") } append("$version/") append(project.simpleOsName) } val konanCompiler = project.konanCompilerName() val parentDir = DependencyProcessor.localKonanDir logger.info("Downloading Kotlin/Native compiler from $downloadUrlDirectory/$konanCompiler into $parentDir") DependencyProcessor( parentDir, downloadUrlDirectory, mapOf(konanCompiler to listOf(DependencySource.Remote.Public)) ).run() } catch (e: IOException) { throw GradleScriptException("Cannot download Kotlin/Native compiler", e) } } // Download dependencies if a user said so. if (downloadDependencies) { val runner = KonanCompilerRunner(project, project.konanExtension.jvmArgs) project.konanTargets.forEach { runner.run("-Xcheck_dependencies", "-target", it.visibleName) } } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/konan/tasks/KonanInteropTask.kt ================================================ /* * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.tasks import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* import org.gradle.util.ConfigureUtil import org.gradle.workers.IsolationMode import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters import org.gradle.workers.WorkerExecutor import org.jetbrains.kotlin.gradle.plugin.konan.* import org.jetbrains.kotlin.gradle.plugin.konan.KonanInteropSpec.IncludeDirectoriesSpec import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File import java.util.concurrent.ConcurrentHashMap import javax.inject.Inject /** * A task executing cinterop tool with the given args and compiling the stubs produced by this tool. */ open class KonanInteropTask @Inject constructor(@Internal val workerExecutor: WorkerExecutor) : KonanBuildingTask(), KonanInteropSpec { @get:Internal override val toolRunner: KonanToolRunner = KonanInteropRunner(project, project.konanExtension.jvmArgs) override fun init(config: KonanBuildingConfig<*>, destinationDir: File, artifactName: String, target: KonanTarget) { super.init(config, destinationDir, artifactName, target) this.defFile = project.konanDefaultDefFile(artifactName) } // Output directories ----------------------------------------------------- override val artifactSuffix: String @Internal get() = ".klib" override val artifactPrefix: String @Internal get() = "" // Interop stub generator parameters ------------------------------------- @Internal var enableParallel: Boolean = false @InputFile lateinit var defFile: File @Optional @Input var packageName: String? = null @Input val compilerOpts = mutableListOf() @Input val linkerOpts = mutableListOf() @Nested val includeDirs = IncludeDirectoriesSpecImpl() @InputFiles val headers = mutableSetOf() @InputFiles val linkFiles = mutableSetOf() fun buildArgs() = mutableListOf().apply { addArg("-o", artifact.canonicalPath) addArgIfNotNull("-target", konanTarget.visibleName) addArgIfNotNull("-def", defFile.canonicalPath) addArgIfNotNull("-pkg", packageName) addFileArgs("-header", headers) compilerOpts.forEach { addArg("-compiler-option", it) } val linkerOpts = mutableListOf().apply { addAll(linkerOpts) } linkFiles.forEach { linkerOpts.addAll(it.files.map { it.canonicalPath }) } linkerOpts.forEach { addArg("-linker-option", it) } addArgs("-compiler-option", includeDirs.allHeadersDirs.map { "-I${it.absolutePath}" }) addArgs("-headerFilterAdditionalSearchPrefix", includeDirs.headerFilterDirs.map { it.absolutePath }) addArgs("-repo", libraries.repos.map { it.canonicalPath }) addFileArgs("-library", libraries.files) addArgs("-library", libraries.namedKlibs) addArgs("-library", libraries.artifacts.map { it.artifact.canonicalPath }) addKey("-no-default-libs", noDefaultLibs) addKey("-no-endorsed-libs", noEndorsedLibs) addAll(extraOpts) } // region DSL. inner class IncludeDirectoriesSpecImpl: IncludeDirectoriesSpec { @Input val allHeadersDirs = mutableSetOf() @Input val headerFilterDirs = mutableSetOf() override fun allHeaders(vararg includeDirs: Any) = allHeaders(includeDirs.toList()) override fun allHeaders(includeDirs: Collection) { allHeadersDirs.addAll(includeDirs.map { project.file(it) }) } override fun headerFilterOnly(vararg includeDirs: Any) = headerFilterOnly(includeDirs.toList()) override fun headerFilterOnly(includeDirs: Collection) { headerFilterDirs.addAll(includeDirs.map { project.file(it) }) } } override fun defFile(file: Any) { defFile = project.file(file) } override fun packageName(value: String) { packageName = value } override fun compilerOpts(vararg values: String) { compilerOpts.addAll(values) } override fun header(file: Any) = headers(file) override fun headers(vararg files: Any) { headers.add(project.files(files)) } override fun headers(files: FileCollection) { headers.add(files) } override fun includeDirs(vararg values: Any) = includeDirs.allHeaders(values.toList()) override fun includeDirs(closure: Closure) = includeDirs(ConfigureUtil.configureUsing(closure)) override fun includeDirs(action: Action) = includeDirs { action.execute(this) } override fun includeDirs(configure: IncludeDirectoriesSpec.() -> Unit) = includeDirs.configure() override fun linkerOpts(vararg values: String) = linkerOpts(values.toList()) override fun linkerOpts(values: List) { linkerOpts.addAll(values) } override fun link(vararg files: Any) { linkFiles.add(project.files(files)) } override fun link(files: FileCollection) { linkFiles.add(files) } // endregion internal interface RunToolParameters: WorkParameters { var taskName: String var args: List } internal abstract class RunTool @Inject constructor() : WorkAction { override fun execute() { val toolRunner = interchangeBox.remove(parameters.taskName) ?: error(":(") toolRunner.run(parameters.args) } } override fun run() { destinationDir.mkdirs() if (dumpParameters) { dumpProperties(this) } val args = buildArgs() if (enableParallel) { val workQueue = workerExecutor.noIsolation() interchangeBox[this.path] = toolRunner workQueue.submit(RunTool::class.java) { it.taskName = this.path it.args = args } } else { toolRunner.run(args) } } } internal val interchangeBox = ConcurrentHashMap() ================================================ FILE: tools/kotlin-native-gradle-plugin/src/main/resources/META-INF/services/shadow.org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin ================================================ # # Copyright 2010-2017 JetBrains s.r.o. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shadow.org.jetbrains.kotlinx.serialization.gradle.SerializationKotlinGradleSubplugin ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/BaseKonanSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.junit.Rule import org.junit.rules.TemporaryFolder import spock.lang.Specification class BaseKonanSpecification extends Specification { @Rule TemporaryFolder tmpFolder = new TemporaryFolder() File getProjectDirectory() { return tmpFolder.root } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/DefaultSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.TaskOutcome class DefaultSpecification extends BaseKonanSpecification { def 'Plugin should build a project without additional settings'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.buildFile.write(""" plugins { id 'konan' } konanArtifacts { interop('stdio') library('main') } """.stripIndent()) it.generateDefFile("stdio.def", "") it.generateSrcFile("main.kt") } def result = project.createRunner().withArguments('build').build() then: !result.tasks.collect { it.outcome }.contains(TaskOutcome.FAILED) } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/EnvVariableSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import spock.lang.Ignore import spock.lang.Unroll import static org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes // TODO: Rewrite tests using Kotlin. class EnvVariableSpecification extends BaseKonanSpecification { class WrapperResult { private int exitValue; private String stdout; private String stderr; WrapperResult(Process process) { exitValue = process.exitValue() stdout = process.getInputStream().readLines().join("\n") stderr = process.getErrorStream().readLines().join("\n") } int getExitValue() { return exitValue } String getStdout() { return stdout } String getStderr() { return stderr } WrapperResult printStdout() { println(stdout); return this } WrapperResult printStderr() { println(stderr); return this } } private KonanProject createProjectWithWrapper() { def project = KonanProject.createEmpty(projectDirectory) def runner = project.createRunner() // Gradle TestKit doesn't support setting environment variables for runners. // So we use the following hack: we create a gradle wrapper, start it as a separate // process with custom environment variables and check its exit code and output. runner.withArguments("wrapper").build() def classpath = runner.pluginClasspath.collect { "'${escapeBackSlashes(it.absolutePath)}'" }.join(", ") project.buildFile.write("""\ buildscript { dependencies { classpath files($classpath) } } """.stripIndent()) return project } private WrapperResult runWrapper(KonanProject project, List tasks, Map environment = [:], Map properties = ["konan.useEnvironmentVariables": 'true']) { def wrapper = (HostManager.host.family == Family.MINGW) ? "gradlew.bat" : "gradlew" def command = ["$project.projectDir.absolutePath/$wrapper".toString()] command.addAll(tasks) command.addAll(properties.collect { "-P${it.key}=${it.value}".toString() }) def projectBuilder = new ProcessBuilder() .directory(project.projectDir) .command(command) projectBuilder.environment().putAll(environment) def process = projectBuilder.start() process.waitFor() return new WrapperResult(process) } private WrapperResult runWrapper(KonanProject project, String task, Map environment = [:], Map properties = ["konan.useEnvironmentVariables": 'true']) { return runWrapper(project, [task], environment, properties) } private String artifactFileName(String baseName, ArtifactType type, KonanTarget target = HostManager.host) { String suffix = "" String prefix = "" switch (type) { case ArtifactType.PROGRAM: suffix = target.family.exeSuffix break case ArtifactType.INTEROP: case ArtifactType.LIBRARY: suffix = "klib" break case ArtifactType.BITCODE: suffix = "bc" break; case ArtifactType.DYNAMIC: prefix = target.family.dynamicPrefix suffix = target.family.dynamicSuffix break case ArtifactType.STATIC: prefix = target.family.staticPrefix suffix = target.family.staticSuffix break case ArtifactType.FRAMEWORK: suffix = "framework" } return "$prefix${baseName}.$suffix" } @Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.") @Unroll("Plugin should support #action via an env variable") def 'Plugin should support enabling/disabling debug/opt via an env variable'() { when: def project = createProjectWithWrapper() project.buildFile.append("""\ apply plugin: 'konan' konanArtifacts { library('main') } task assertEnableDebug { doLast { konanArtifacts.main.forEach { if (!($assertion)) throw new AssertionError("$message for \${it.name}") } } } """.stripIndent()) def result = runWrapper(project,"assertEnableDebug", [(variable): value]) .printStderr() .getExitValue() then: result == 0 where: action |variable |value |assertion |message "enabling debug" |"DEBUGGING_SYMBOLS" |"YES" |"it.enableDebug" |"Debug should be enabled" "disabling debug" |"DEBUGGING_SYMBOLS" |"NO" |"!it.enableDebug" |"Debug should be disabled" "enabling opt" |"KONAN_ENABLE_OPTIMIZATIONS" |"YES" |"it.enableOptimizations" |"Opts should be enabled" "disabling opt" |"KONAN_ENABLE_OPTIMIZATIONS" |"NO" |"!it.enableOptimizations" |"Opts should be disabled" } @Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.") def 'Plugin should support setting destination directory via an env variable'() { when: def project = createProjectWithWrapper() def newDestinationDir = project.createSubDir("newDestination") def newDestinationPath = newDestinationDir.absolutePath project.buildFile.append("""\ apply plugin: 'konan' konanArtifacts { program('program') library('library') dynamic('dynamic') framework('framework') } task assertDestinationDir { doLast { konanArtifacts.forEach { artifact -> artifact.forEach { if (it.destinationDir.absolutePath != '${escapeBackSlashes(newDestinationPath)}'){ throw new AssertionError("Unexpected destination dir for \$it.name\\n" + "expected: ${escapeBackSlashes(newDestinationPath)}\\n" + "actual: \$it.destinationDir") } } } } } """.stripIndent()) project.generateSrcFile("main.kt") def assertResult = runWrapper(project, "assertDestinationDir", ["CONFIGURATION_BUILD_DIR": newDestinationPath]) .printStderr() .getExitValue() def buildResult = runWrapper(project, "build", ["CONFIGURATION_BUILD_DIR": newDestinationPath]) .printStderr() .getExitValue() def files = newDestinationDir.list() then: assertResult == 0 buildResult == 0 files.contains(artifactFileName("program", ArtifactType.PROGRAM)) files.contains(artifactFileName("library", ArtifactType.LIBRARY)) files.contains(artifactFileName("dynamic", ArtifactType.DYNAMIC)) files.contains(artifactFileName("static", ArtifactType.STATIC)) if (HostManager.hostIsMac) { files.contains(artifactFileName("framework", ArtifactType.FRAMEWORK)) } } @Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.") def 'Plugin should rerun tasks if CONFIGURATION_BUILD_DIR has been changed'() { when: def project = createProjectWithWrapper() def destination1 = project.createSubDir("destination1", "subdir") def destination2 = project.createSubDir("destination2", "subdir") project.buildFile.append("""\ apply plugin: 'konan' konanArtifacts { library('main') } """.stripIndent()) project.generateSrcFile("main.kt") def buildResult1 = runWrapper(project, "build", ["CONFIGURATION_BUILD_DIR": destination1.absolutePath]) .printStderr() .getExitValue() def buildResult2 = runWrapper(project, "build", ["CONFIGURATION_BUILD_DIR": destination2.absolutePath]) .printStderr() .getExitValue() def files1 = destination1.list() def files2 = destination2.list() then: buildResult1 == 0 buildResult2 == 0 destination1.exists() destination2.exists() files1.contains(artifactFileName("main", ArtifactType.LIBRARY)) files2.contains(artifactFileName("main", ArtifactType.LIBRARY)) } @Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.") def 'Plugin should ignore environmentVariables if konan.useEnvironmentVariables is false or is not set'() { when: def project = createProjectWithWrapper() def newDestinationDir = project.createSubDir("newDestination") def newDestinationPath = newDestinationDir.absolutePath project.buildFile.append("""\ apply plugin: 'konan' konanArtifacts { program('program') library('library') dynamic('dynamic') framework('framework') } task assertNoOverrides { doLast { konanArtifacts.forEach { artifact -> artifact.forEach { if (it.destinationDir.absolutePath == '${escapeBackSlashes(newDestinationPath)}'){ throw new AssertionError("CONFIGURATION_BUILD_DIR overrides a default output path " + "when it shouldn't.\\n" + "Task: \${it.name}, Path: \${it.destinationDir}") } if (it.enableDebug) { throw new AssertionError("DEBUGGING_SYMBOLS overrides a default value " + "when it shouldn't\\n" + "Task: \${it.name}") } } } } } """.stripIndent()) def resultNoProp = runWrapper(project, "assertNoOverrides", ["DEBUGGING_SYMBOLS": "true", "CONFIGURATION_BUILD_DIR": newDestinationPath], [:]) .printStderr() .getExitValue() def resultFalseValue = runWrapper(project, "assertNoOverrides", ["DEBUGGING_SYMBOLS": "true", "CONFIGURATION_BUILD_DIR": newDestinationPath], ["konan.useEnvironmentVariables": "false"]) .printStderr() .getExitValue() then: resultNoProp == 0 resultFalseValue == 0 } @Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.") def 'Up-to-date checks should work with different directories for different targets'() { when: def project = createProjectWithWrapper() def fooDir = project.createSubDir("foo") def barDir = project.createSubDir("bar") project.buildFile.append("""\ apply plugin: 'konan' konanArtifacts { library('foo') library('bar') } task assertUpToDate { dependsOn 'compileKonanFoo' doLast { if (!konanArtifacts.foo.getByTarget('host').state.upToDate) { throw new AssertionError("Compilation task is not up-to-date") } } } """.stripIndent()) project.generateSrcFile("main.kt") def buildResult1 = runWrapper(project, "compileKonanFoo", ["CONFIGURATION_BUILD_DIR": fooDir.absolutePath]) .printStderr() .getExitValue() def buildResult2 = runWrapper(project, "compileKonanBar", ["CONFIGURATION_BUILD_DIR": barDir.absolutePath]) .printStderr() .getExitValue() def buildResult3 = runWrapper(project, "assertUpToDate", ["CONFIGURATION_BUILD_DIR": fooDir.absolutePath]) .printStderr() .getExitValue() then: buildResult1 == 0 buildResult2 == 0 buildResult3 == 0 } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/IncrementalSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.TaskOutcome import spock.lang.Unroll class IncrementalSpecification extends BaseKonanSpecification { Tuple buildTwice(KonanProject project, String task = 'build', Closure change) { def runner = project.createRunner().withArguments(task) def firstResult = runner.build() change(project) def secondResult = runner.build() return new Tuple(project, firstResult, secondResult) } Tuple buildTwice(ArtifactType mainArtifactType = ArtifactType.LIBRARY, String task = 'build', Closure change) { return buildTwice(KonanProject.createWithInterop(projectDirectory, mainArtifactType), change) } Boolean noRecompilationHappened(KonanProject project, BuildResult firstResult, BuildResult secondResult) { return project.with { firstResult.tasks.collect { it.path }.containsAll(buildingTasks) && firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) && secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(buildingTasks) && firstResult.task(downloadTask).outcome == TaskOutcome.SUCCESS && secondResult.task(downloadTask).outcome == TaskOutcome.SUCCESS } } Boolean onlyRecompilationHappened(KonanProject project, BuildResult firstResult, BuildResult secondResult) { return project.with { firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) && secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(compilationTasks) && secondResult.taskPaths(TaskOutcome.UP_TO_DATE).containsAll(interopTasks) } } Boolean recompilationAndInteropProcessingHappened(KonanProject project, BuildResult firstResult, BuildResult secondResult) { return project.with { firstResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) && secondResult.taskPaths(TaskOutcome.SUCCESS).containsAll(buildingTasks) } } //region tests ===================================================================================================== def 'Compilation is up-to-date if there is no changes'() { when: def results = buildTwice {} then: noRecompilationHappened(*results) } def 'Source change should cause only recompilation'() { when: def results = buildTwice { KonanProject project -> project.srcFiles[0].append("\n // Some change in the source file") } then: onlyRecompilationHappened(*results) } def 'Def-file change should cause recompilation and interop reprocessing'() { when: def results = buildTwice { KonanProject project -> project.defFiles[0].append("\n # Some change in the def-file") } then: recompilationAndInteropProcessingHappened(*results) } @Unroll("#parameter change for a compilation task should cause only recompilation") def 'Parameter changes should cause only recompilaton'() { when: def results = buildTwice { KonanProject project -> project.addSetting("main", parameter, value) } then: onlyRecompilationHappened(*results) where: parameter | value "baseDir" | "'build/new/outputDir'" "enableOptimizations" | "true" "linkerOpts" | "'--help'" "enableAssertions" | "true" "enableDebug" | "true" "artifactName" | "'foo'" "extraOpts" | "'-Xtime'" "noDefaultLibs" | "true" "noEndorsedLibs" | "true" } def 'Plugin should support a custom entry point and recompile an artifact if it changes'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("main", """ |fun main(args: Array) { println("default main") } | """.stripMargin()) } def results = buildTwice(project) { KonanProject it -> it.srcFiles[0].write(""" |package foo | |fun bar(args: Array) { println("changed main") } | """.stripMargin()) it.addSetting("main", "entryPoint", "'foo.bar'") } then: onlyRecompilationHappened(*results) } def 'srcFiles change for a compilation task should cause only recompilation'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it -> it.generateSrcFile(["src", "foo", "kotlin"], 'bar.kt', """ fun foo(args: Array) { println("Hello!") } """.stripIndent()) } def results = buildTwice(project) { KonanProject it -> it.addSetting("main", "srcFiles", "project.fileTree('src/foo/kotlin')") } then: onlyRecompilationHappened(*results) } def 'Library change for a compilation task should cause only recompilation'() { when: def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY) { KonanProject it -> it.generateSrcFile(["src", "lib", "kotlin"], "lib.kt", "fun bar() { println(\"Hello!\") }") it.buildFile.append(""" konanArtifacts { library('lib') { srcFiles fileTree('src/lib/kotlin') } } """.stripIndent()) } def results = buildTwice(project) { KonanProject it -> it.addLibraryToArtifact("main", 'lib') } then: onlyRecompilationHappened(*results) } def 'Native library change for a compilation task should cause only recompilaton'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it -> it.generateSrcFile(["src", "lib", "kotlin"], "lib.kt", "fun bar() { println(\"Hello!\") }") it.buildFile.append(""" konanArtifacts { bitcode('lib') { srcFiles fileTree('src/lib/kotlin') } } """.stripIndent()) } def results = buildTwice(project) { KonanProject it -> it.addSetting("main", "nativeLibrary", "compileKonanLib${KonanProject.HOST.capitalize()}.artifact") } then: onlyRecompilationHappened(*results) } // TODO: Test library for incremental compilation. @Unroll("#parameter change for an interop task should cause recompilation and interop reprocessing") def 'Parameter change for an interop task should cause recompilation and interop reprocessing'() { when: def results = buildTwice { KonanProject project -> project.addSetting("stdio", parameter, value) } then: recompilationAndInteropProcessingHappened(*results) where: parameter | value "packageName" | "'org.sample'" "compilerOpts" | "'-g'" "linkerOpts" | "'--help'" "includeDirs" | "'src'" "includeDirs.allHeaders" | "'src'" "extraOpts" | "'-verbose'" "noDefaultLibs" | "true" "noEndorsedLibs" | "true" } def 'includeDirs.headerFilterOnly change should cause recompilation and interop reprocessing'() { when: def project = KonanProject.createWithInterop(projectDirectory) { KonanProject it -> it.defFiles.first().write("headers = stdio.h\nheaderFilter = stdio.h") } def results = buildTwice(project) { KonanProject it -> it.addSetting(KonanProject.DEFAULT_INTEROP_NAME, "includeDirs.headerFilterOnly", "'.'") } then: recompilationAndInteropProcessingHappened(*results) } def 'defFile change for an interop task should cause recompilation and interop reprocessing'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) def defFile = project.generateDefFile("foo.def", "#some content") def results = buildTwice(project) { KonanProject it -> it.addSetting("stdio", "defFile", defFile) } then: recompilationAndInteropProcessingHappened(*results) } def 'header change for an interop task should cause recompilation and interop reprocessing'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) def header = project.generateSrcFile('header.h', "#define CONST 1") def results = buildTwice(project) { KonanProject it -> it.addSetting("stdio", "headers", header) } then: recompilationAndInteropProcessingHappened(*results) } def 'link change for an interop task should cause recompilation and interop reprocessing'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) { KonanProject it -> it.generateSrcFile(["src", "lib", "kotlin"], 'lib.kt', 'fun foo() { println(42) }') it.buildFile.append(""" konanArtifacts { bitcode('lib') { srcFiles fileTree('src/lib/kotlin') } } """.stripIndent()) } def results = buildTwice(project) { KonanProject it -> it.addSetting("stdio", "dependsOn", "konanArtifacts.lib.${KonanProject.HOST}") it.addSetting("stdio", "link", "files(konanArtifacts.lib.${KonanProject.HOST}.artifactPath)") } then: recompilationAndInteropProcessingHappened(*results) } def 'Common source change should cause recompilation'() { when: File commonSource def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = MultiplatformSpecification.createCommonProject(it) commonSource = MultiplatformSpecification.createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") println(it.settingsFile.text) it.generateSrcFile("actual.kt", "actual fun foo() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy project(':common') } """.stripIndent()) it.buildingTasks.addAll([":compileKonanFoo", ":compileKonanFoo${KonanProject.HOST}}"]) } def results = buildTwice(project, ':build') { KonanProject -> commonSource.append("\nfun bar() = 43") } then: onlyRecompilationHappened(*results) } // TODO: Add incremental tests for the 'libraries' block. //endregion } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/KonanProject.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.GradleRunner import org.gradle.util.GradleVersion import org.jetbrains.kotlin.konan.target.HostManager import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths enum ArtifactType { PROGRAM("program"), LIBRARY("library"), BITCODE("bitcode"), INTEROP("interop"), DYNAMIC("dynamic"), STATIC("static"), FRAMEWORK("framework") String type ArtifactType(String type) { this.type = type } String toString() { return type } } class KonanProject { static String DEFAULT_ARTIFACT_NAME = 'main' static String DEFAULT_INTEROP_NAME = "stdio" static String HOST = HostManager.hostName File projectDir Path projectPath File konanBuildDir String konanHome String gradleVersion File buildFile File propertiesFile File settingsFile Set srcFiles = [] Set defFiles = [] List interopTasks = [] List compilationTasks = [] String downloadTask = ":checkKonanCompiler" List targets List getBuildingTasks() { return compilationTasks + interopTasks } List getKonanTasks() { return getBuildingTasks() + downloadTask } static String DEFAULT_SRC_CONTENT = """ fun main(args: Array) { println(42) } """ static String DEFAULT_DEF_CONTENT = """ headers = stdio.h """.stripIndent() protected KonanProject(File projectDir){ this(projectDir, [HOST]) } protected KonanProject(File projectDir, List targets) { this.projectDir = projectDir this.targets = targets projectPath = projectDir.toPath() konanBuildDir = projectPath.resolve('build/konan').toFile() def konanHomeDir = new File(getKonanHome()) if (!konanHomeDir.exists() || !konanHomeDir.directory) { throw new IllegalStateException("konan.home doesn't exist or is not a directory: $konanHomeDir.canonicalPath") } // Escape windows path separator this.konanHome = escapeBackSlashes(konanHomeDir.canonicalPath) this.gradleVersion = System.getProperty("gradleVersion") ?: GradleVersion.current().version } GradleRunner createRunner(boolean withDebug = true) { return GradleRunner.create() .withProjectDir(projectDir) .withPluginClasspath() .withDebug(withDebug) .withGradleVersion(gradleVersion) } /** Creates a subdirectory specified by the given path. */ File createSubDir(String ... path) { return createSubDir(Paths.get(*path)) } /** Creates a subdirectory specified by the given path. */ File createSubDir(Path path) { return Files.createDirectories(projectPath.resolve(path)).toFile() } /** Creates a file with the given content in project subdirectory specified by parentDirectory. */ File createFile(Path parentDirectory = projectPath, String fileName, String content) { def parent = projectPath.resolve(parentDirectory) Files.createDirectories(parent) def result = parent.resolve(fileName).toFile() result.createNewFile() result.write(content) return result } /** Creates a file with the given content in project subdirectory specified by parentPath. */ File createFile(List parentPath, String fileName, String content) { return createFile(Paths.get(*parentPath), fileName, content) } /** Creates a folder for project source files (src/main/kotlin). */ void generateFolders() { createSubDir("src", "main", "kotlin") createSubDir("src", "main", "c_interop") } /** Generates a build.gradle file in the root project directory with the given content. */ File generateBuildFile(String content) { buildFile = createFile(projectPath, "build.gradle", content) return buildFile } /** Generates a settings.gradle file in the root project directory with the given content. */ File generateSettingsFile(String content) { settingsFile = createFile(projectPath, "settings.gradle", content) return settingsFile } /** * Generates a build.gradle file in root project directory with the default content (see below) * and fills the compilationTasks array. * * plugins { id 'konan' } * * konanArtifacts { * program('$DEFAULT_ARTIFACT_NAME') * } */ File generateBuildFile() { def result = generateBuildFile(""" |plugins { id 'konan' } | |konan.targets = [${targets.collect { "'$it'" }.join(", ")}] |""".stripMargin() ) compilationTasks = [":compileKonan", ":build"] return result } /** Generates a source file with the given name and content in the given directory and adds it into srcFiles */ File generateSrcFile(Path parentDirectory, String fileName, String content) { def result = createFile(parentDirectory, fileName, content) srcFiles.add(result) return result } /** Generates a source file with the given name and content in the given directory and adds it into srcFiles */ File generateSrcFile(List parentPath, String fileName, String content) { return generateSrcFile(Paths.get(*parentPath), fileName, content) } /** Generates a source file with the given name and content in 'src/main/kotlin' and adds it into srcFiles */ File generateSrcFile(String fileName, String content) { return generateSrcFile(["src", "main", "kotlin"], fileName, content) } /** * Generates a source file with the given name and default content (see below) in src/main/kotlin * and adds it into srcFiles. * * fun main(args: Array) { * println(42) * } */ File generateSrcFile(String fileName) { return generateSrcFile(fileName, DEFAULT_SRC_CONTENT) } /** Creates a def-file with the given name and content in src/main/c_interop directory and adds it to defFiles. */ File generateDefFile(String fileName, String content) { def result = createFile(["src", "main", "c_interop"], fileName, content) defFiles.add(result) return result } /** * Creates a def-file with the given name and the default content (see below) in src/main/c_interop directory * and adds it to defFiles. * * headers = stdio.h stdlib.h string.h */ File generateDefFile(String fileName = "${DEFAULT_INTEROP_NAME}.def") { return generateDefFile(fileName, DEFAULT_DEF_CONTENT) } /** Generates gradle.properties file with the konan.home and konan.jvmArgs properties set. */ File generatePropertiesFile(String konanHome, String konanJvmArgs = System.getProperty("konan.jvmArgs") ?: "") { propertiesFile = createFile(projectPath, "gradle.properties", """\ org.jetbrains.kotlin.native.home=$konanHome ${!konanJvmArgs.isEmpty() ? "konan.jvmArgs=$konanJvmArgs\n" : ""} """.stripIndent()) return propertiesFile } /** * Sets the given setting of the given project extension. * In other words adds the following string in the build file: * * $container.$section.$parameter $value */ protected void addSetting(String container, String section, String parameter, String value) { buildFile.append("$container.$section.$parameter $value\n") } /** * Sets the given setting of the given project extension using the path of the file as a value. * In other words adds the following string in the build file: * * $container.$section.$parameter ${value.canonicalPath.replace(\, \\)} */ protected void addSetting(String container, String section, String parameter, File value) { addSetting(container, section, parameter, "'${escapeBackSlashes(value.canonicalPath)}'") } /** Sets the given setting of the given konanArtifact */ void addSetting(String artifactName = DEFAULT_ARTIFACT_NAME, String parameter, String value) { addSetting("konanArtifacts", artifactName, parameter, value) } /** Sets the given setting of the given konanArtifact using the path of the file as a value. */ void addSetting(String artifactName = DEFAULT_ARTIFACT_NAME, String parameter, File value) { addSetting("konanArtifacts", artifactName, parameter, value) } void addLibraryToArtifact(String artifactName = DEFAULT_ARTIFACT_NAME, String library = DEFAULT_INTEROP_NAME) { addLibraryToArtifactCustom(artifactName, "artifact '$library'") } void addLibraryToArtifactCustom(String artifactName = DEFAULT_ARTIFACT_NAME, String closureContent) { buildFile.append("konanArtifacts.${artifactName}.libraries { $closureContent }\n") } /** Returns the path of compileKonan... task for the default artifact. */ static String defaultCompilationTask(String target = HOST) { return compilationTask(DEFAULT_ARTIFACT_NAME, target) } static String defaultInteropTask(String target = HOST) { return compilationTask(DEFAULT_INTEROP_NAME, target) } /** Returns the path of compileKonan... task for the artifact specified. */ static String compilationTask(String artifactName, String target = HOST) { return ":compileKonan${artifactName.capitalize()}${target.capitalize()}" } static String defaultCompilationConfig() { return artifactConfig(DEFAULT_ARTIFACT_NAME) } static String defaultInteropConfig() { return artifactConfig(DEFAULT_INTEROP_NAME) } static String artifactConfig(String artifactName) { return "konanArtifacts.$artifactName" } static String outputAccessCode(String artifact, String target = HOST) { return "${artifactConfig(artifact)}.${target}.artifact" } void addCompilerArtifact(String name, String content = "", ArtifactType type = ArtifactType.PROGRAM) { def newTasks = targets.collect { compilationTask(name, it) } + ":compileKonan${name.capitalize()}".toString() buildFile.append("konanArtifacts { $type('$name') }\n") if (type == ArtifactType.INTEROP) { defFiles += generateDefFile("${name}.def", content) interopTasks += newTasks } else { def src = generateSrcFile(projectPath.resolve("src/$name/kotlin"), "source.kt", content) addSetting(name, "srcFiles", src) srcFiles += src compilationTasks += newTasks } } /** Creates a project with default build and source files. */ static KonanProject create(File projectDir, ArtifactType artifactType = ArtifactType.PROGRAM, List targets = [HOST]) { return createEmpty(projectDir, targets) { KonanProject p -> p.addCompilerArtifact(DEFAULT_ARTIFACT_NAME, DEFAULT_SRC_CONTENT, artifactType) } } /** Creates a project with default build and source files. */ static KonanProject create(File projectDir, ArtifactType artifactType = ArtifactType.PROGRAM, List targets = [HOST], Closure config) { def result = create(projectDir, artifactType, targets) config(result) return result } static KonanProject createWithInterop(File projectDir, ArtifactType mainArtifactType = ArtifactType.PROGRAM, List targets = [HOST]) { return create(projectDir, mainArtifactType, targets) { KonanProject p -> p.addCompilerArtifact(DEFAULT_INTEROP_NAME, DEFAULT_DEF_CONTENT, ArtifactType.INTEROP) p.addLibraryToArtifact() } } static KonanProject createWithInterop(File projectDir, ArtifactType mainArtifactType = ArtifactType.PROGRAM, List targets = [HOST], Closure config) { def result = createWithInterop(projectDir, mainArtifactType, targets) config(result) return result } /** Creates a project with the default build file and without any source files. */ static KonanProject createEmpty(File projectDir, List targets = [HOST]) { def result = new KonanProject(projectDir, targets) result.with { generateFolders() generateBuildFile() generatePropertiesFile(konanHome) generateSettingsFile("") } return result } /** Creates a project with the default build file and without any source files. */ static KonanProject createEmpty(File projectDir, List targets = [HOST], Closure config) { def result = createEmpty(projectDir, targets) config(result) return result } static String escapeBackSlashes(String value) { return value.replace('\\', '\\\\') } static String getKonanHome() { def konanHome = System.getProperty("konan.home") ?: System.getProperty("org.jetbrains.kotlin.native.home") if (konanHome == null) { throw new IllegalStateException("konan.home isn't specified") } return konanHome } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/LibrarySpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test class LibrarySpecification extends BaseKonanSpecification { def libraries = [ [manualDependsOn: true , code: { l1, l2 -> "file ${KonanProject.outputAccessCode(l1)}\nfile ${KonanProject.outputAccessCode(l2)}" }], [manualDependsOn: true , code: { l1, l2 -> "files ${KonanProject.outputAccessCode(l1)}, ${KonanProject.outputAccessCode(l2)}" }], [manualDependsOn: true , code: { l1, l2 -> "files project.files(${KonanProject.outputAccessCode(l1)}, ${KonanProject.outputAccessCode(l2)})" }], [manualDependsOn: true , code: { l1, l2 -> "klib '$l1'\nklib '$l2'" }], [manualDependsOn: true , code: { l1, l2 -> "klibs '$l1', '$l2'" }], [manualDependsOn: false, code: { l1, l2 -> "artifact '$l1'\nartifact '$l2'" }], [manualDependsOn: false, code: { l1, l2 -> "artifact konanArtifacts.$l1\nartifact konanArtifacts.$l2" }], ] String createMainWithCalls(List> functions, Closure callBuilder) { def result = new StringBuilder(""" |fun main(args: Array) {\n """.stripMargin()) functions.forEach { result.append(callBuilder(it.first)) result.append(callBuilder(it.second)) } result.append("}") return result.toString() } void createLibraryWithFunction(KonanProject project, String name) { project.addCompilerArtifact(name, """ |package $name | |fun $name() { | println("$name") |} """.stripMargin(), ArtifactType.LIBRARY) project.addSetting(name, "noDefaultLibs", "true") project.addSetting(name, "noEndorsedLibs", "true") } void createInteropLibrary(KonanProject project, String name) { project.addCompilerArtifact(name, "headers = math.h", ArtifactType.INTEROP) project.addSetting(name, "noDefaultLibs", "true") project.addSetting(name, "noEndorsedLibs", "true") } KonanProject createProjectWithLibraries(Closure createLibraryFunction, Closure callBuilder) { def result = KonanProject.createEmpty(projectDirectory) def libraryNames = new ArrayList>() for (int i = 0; i < libraries.size(); i++) { libraryNames.add(new Tuple2("foo$i", "bar$i")) } libraryNames.forEach { createLibraryFunction(result, it.first) createLibraryFunction(result, it.second) } result.addCompilerArtifact("main", createMainWithCalls(libraryNames, callBuilder)) result.addSetting("main", "noDefaultLibs", "true") result.addSetting("main", "noEndorsedLibs", "true") for (int i = 0; i < libraries.size(); i++) { def foo = libraryNames[i].first def bar = libraryNames[i].second result.addLibraryToArtifactCustom("main", libraries[i].code(foo, bar) ) if (libraries[i].manualDependsOn) { result.addSetting("main", "dependsOn", "konanArtifacts.$foo") result.addSetting("main", "dependsOn", "konanArtifacts.$bar") } } return result } KonanProject createProjectWithSimpleLibraries() { return createProjectWithLibraries( { p, n -> createLibraryWithFunction(p, n) }, { "$it.$it()\n" } ) } KonanProject createProjectWithInteropLibraries() { return createProjectWithLibraries( { p, n -> createInteropLibrary(p, n) }, { "println(${it}.cos(0.0))\n" } ) } def 'Plugin should support libraries from the same project'() { expect: createProjectWithSimpleLibraries() .createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support interop libraries from the same project'() { expect: createProjectWithInteropLibraries() .createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support allLibrariesFrom method for the current project'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("foo", "fun foo() { println(42) }", ArtifactType.LIBRARY) it.addSetting("foo", "noDefaultLibs", "true") it.addSetting("foo", "noEndorsedLibs", "true") it.addCompilerArtifact("bar", "fun bar() { println(43) }", ArtifactType.LIBRARY) it.addSetting("bar", "noDefaultLibs", "true") it.addSetting("bar", "noEndorsedLibs", "true") it.addCompilerArtifact("main" ,"fun main(args: Array) { foo(); bar() }") it.addSetting("main", "noDefaultLibs", "true" ) it.addSetting("main", "noEndorsedLibs", "true" ) it.addLibraryToArtifactCustom("main", "allLibrariesFrom project") } project.createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support allLibrariesFrom method for another project'() { expect: def project = KonanProject.createEmpty(projectDirectory) def subproject = KonanProject.createEmpty(project.createSubDir("subproject")) { KonanProject it -> it.buildFile.write("apply plugin: 'konan'\n") } project.settingsFile.append("include ':subproject'") project.addCompilerArtifact("wrongFoo","fun foo() { println(24) }", ArtifactType.LIBRARY) project.addSetting("wrongFoo", "noDefaultLibs", "true") project.addSetting("wrongFoo", "noEndorsedLibs", "true") subproject.addCompilerArtifact("foo", "fun foo() { println(42) }", ArtifactType.LIBRARY) subproject.addSetting("foo", "noDefaultLibs", "true") subproject.addSetting("foo", "noEndorsedLibs", "true") subproject.addCompilerArtifact("bar", "fun bar() { println(43) }", ArtifactType.LIBRARY) subproject.addSetting("bar", "noDefaultLibs", "true") subproject.addSetting("bar", "noEndorsedLibs", "true") project.addCompilerArtifact("main" ,"fun main(args: Array) { foo(); bar() }") project.addSetting("main", "noDefaultLibs", "true" ) project.addSetting("main", "noEndorsedLibs", "true" ) project.addLibraryToArtifactCustom("main", "allLibrariesFrom project('subproject')") project.createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support allInteropLibrariesFrom method for the current project'() { expect: def project = KonanProject.createEmpty(projectDirectory) def subproject = KonanProject.createEmpty(project.createSubDir("subproject")) { KonanProject it -> it.buildFile.write("apply plugin: 'konan'\n") } project.settingsFile.append("include ':subproject'") project.addCompilerArtifact("wrongFoo1", "fun foo() { println(42) }", ArtifactType.LIBRARY) project.addSetting("wrongFoo1", "noDefaultLibs", "true") project.addSetting("wrongFoo1", "noEndorsedLibs", "true") subproject.addCompilerArtifact("wrongFoo2", "fun foo() { println(42) }", ArtifactType.LIBRARY) subproject.addSetting("wrongFoo2", "noDefaultLibs", "true") subproject.addSetting("wrongFoo2", "noEndorsedLibs", "true") subproject.addCompilerArtifact("math1", "headers = math.h", ArtifactType.INTEROP) subproject.addSetting("math1", "noDefaultLibs", "true") subproject.addSetting("math1", "noEndorsedLibs", "true") subproject.addCompilerArtifact("math2", "headers = math.h", ArtifactType.INTEROP) subproject.addSetting("math2", "noDefaultLibs", "true") subproject.addSetting("math2", "noEndorsedLibs", "true") project.addCompilerArtifact("main" ,""" |fun foo() {} | |fun main(args: Array) { foo(); math1.cos(0.0); math2.cos(0.0) } """.stripMargin()) project.addSetting("main", "noDefaultLibs", "true" ) project.addSetting("main", "noEndorsedLibs", "true" ) project.addLibraryToArtifactCustom("main", "allInteropLibrariesFrom project('subproject')") project.createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support allInteropLibrariesFrom method for another projecct'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("wrongFoo", "fun foo() { println(42) }", ArtifactType.LIBRARY) it.addSetting("wrongFoo", "noDefaultLibs", "true") it.addSetting("wrongFoo", "noEndorsedLibs", "true") it.addCompilerArtifact("math1", "headers = math.h", ArtifactType.INTEROP) it.addSetting("math1", "noDefaultLibs", "true") it.addSetting("math1", "noEndorsedLibs", "true") it.addCompilerArtifact("math2", "headers = math.h", ArtifactType.INTEROP) it.addSetting("math2", "noDefaultLibs", "true") it.addSetting("math2", "noEndorsedLibs", "true") it.addCompilerArtifact("main" ,""" |fun foo() {} | |fun main(args: Array) { foo(); math1.cos(0.0); math2.cos(0.0) } """.stripMargin()) it.addSetting("main", "noDefaultLibs", "true" ) it.addSetting("main", "noEndorsedLibs", "true" ) it.addLibraryToArtifactCustom("main", "allInteropLibrariesFrom project") } project.createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } def 'Plugin should support custom repositories for libraries'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("foo", "fun foo() { println(42) }", ArtifactType.LIBRARY) it.addSetting("foo", "noDefaultLibs", "true") it.addSetting("foo", "noEndorsedLibs", "true") it.addSetting("foo", "baseDir", "file('out')") it.addCompilerArtifact("main" ,"fun main(args: Array) { foo() }") it.addSetting("main", "noDefaultLibs", "true" ) it.addSetting("main", "noEndorsedLibs", "true" ) it.addSetting("main", "dependsOn", "konanArtifacts.foo.$KonanProject.HOST") it.addLibraryToArtifactCustom("main", "klib 'foo'") it.addLibraryToArtifactCustom("main", "useRepo 'out/$KonanProject.HOST'") } project.createRunner() .withArguments(KonanProject.compilationTask("main"), "-i") .build() } def 'Plugin should support library dependencies in the same project'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("foo", "fun foo() { println(42) }", ArtifactType.LIBRARY) it.addSetting("foo", "noDefaultLibs", "true") it.addSetting("foo", "noEndorsedLibs", "true") it.addCompilerArtifact("bar", "fun bar() { println(43) }", ArtifactType.LIBRARY) it.addSetting("bar", "noDefaultLibs", "true") it.addSetting("bar", "noEndorsedLibs", "true") it.addLibraryToArtifact("bar", "foo") it.addCompilerArtifact("main" ,"fun main(args: Array) { foo(); bar() }") it.addSetting("main", "noDefaultLibs", "true" ) it.addSetting("main", "noEndorsedLibs", "true" ) it.addLibraryToArtifact("main", "bar") } project.createRunner() .withArguments(KonanProject.compilationTask("main"), "-i") .build() } def 'Plugin should support library dependencies from other projects'() { expect: def project = KonanProject.createEmpty(projectDirectory) def subproject1 = KonanProject.createEmpty(project.createSubDir("subproject1")) { KonanProject it -> it.buildFile.write("apply plugin: 'konan'\n") } def subproject2 = KonanProject.createEmpty(project.createSubDir("subproject2")) { KonanProject it -> it.buildFile.write("apply plugin: 'konan'\n") } project.settingsFile.append("include ':subproject1'\ninclude ':subproject2'") subproject1.addCompilerArtifact("foo", "fun foo() { println(42) }", ArtifactType.LIBRARY) subproject1.addSetting("foo", "noDefaultLibs", "true") subproject1.addSetting("foo", "noEndorsedLibs", "true") subproject2.addCompilerArtifact("bar", "fun bar() { println(43) }", ArtifactType.LIBRARY) subproject2.addSetting("bar", "noDefaultLibs", "true") subproject2.addSetting("bar", "noEndorsedLibs", "true") subproject2.addLibraryToArtifactCustom( "bar", "artifact rootProject.project('subproject1'), 'foo'" ) project.addCompilerArtifact("main" ,"fun main(args: Array) { foo(); bar() }") project.addSetting("main", "noDefaultLibs", "true" ) project.addSetting("main", "noEndorsedLibs", "true" ) project.addLibraryToArtifactCustom( "main", "artifact project('subproject2'), 'bar'" ) project.createRunner() .withArguments(KonanProject.compilationTask("main")) .build() } // TODO: Add tests for incorrect cases (e.g. attempt to use an executable as a library) } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/MultiplatformSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import spock.lang.Ignore import java.nio.file.Files import java.nio.file.Paths class MultiplatformSpecification extends BaseKonanSpecification { public static final String KOTLIN_VERSION = System.getProperty("kotlin.version") public static final String KOTLIN_REPO = System.getProperty("kotlin.repo") public static final String DEFAULT_COMMON_BUILD_FILE_CONTENT = """\ buildscript { repositories { maven { url = '$KOTLIN_REPO' } maven { url = 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION" } } apply plugin: 'kotlin-platform-common' repositories { maven { url = '$KOTLIN_REPO' } maven { url = 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-common:$KOTLIN_VERSION" } """.stripIndent() static File createCommonProject(KonanProject platformProject, String commonProjectName = "common", String commonBuildFileContent = DEFAULT_COMMON_BUILD_FILE_CONTENT) { def commonDirectory = platformProject.createSubDir(commonProjectName) def commonBuildFile = Paths.get(commonDirectory.absolutePath, "build.gradle") commonBuildFile.write(commonBuildFileContent) platformProject.settingsFile.append("include ':$commonProjectName'\n") return commonDirectory } static File createCommonSource(File commonDirectory, Iterable subdirectory, String fileName, String content) { def commonSrcDir = commonDirectory.toPath().resolve(Paths.get(*subdirectory)) def commonSource = commonSrcDir.resolve(fileName) Files.createDirectories(commonSrcDir) commonSource.write(content) return commonSource.toFile() } def 'Plugin should support multiplatform projects'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", """\ @file:Suppress("EXPERIMENTAL_API_USAGE_ERROR") @OptionalExpectation expect annotation class Optional() @Optional fun opt() = 42 expect fun foo(): Int """.stripIndent() ) it.generateSrcFile("platform.kt", "actual fun foo() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Multiplatform projects should be disabled by default'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") it.generateSrcFile("platform.kt", "fun foo() = 42") it.buildFile.append(""" konanArtifacts { library('foo') {} } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Plugin should use the \'main\' source set as a default common source set'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) Paths.get(commonDirectory.absolutePath, "build.gradle").append(""" sourceSets { common.kotlin.srcDir 'src/common/kotlin' } """.stripIndent()) createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") createCommonSource(commonDirectory, ["src", "common", "kotlin"], "common.kt", "expect fun bar(): Int") it.generateSrcFile("platform.kt", "actual fun foo() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Plugin should allow a user to specify custom common source set'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) Paths.get(commonDirectory.absolutePath, "build.gradle").append(""" sourceSets { common.kotlin.srcDir 'src/common/kotlin' } """.stripIndent()) createCommonSource(commonDirectory, ["src", "common", "kotlin"], "common.kt", "expect fun bar(): Int") it.generateSrcFile("platform.kt", "actual fun bar() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true commonSourceSets 'common' } } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Plugin should allow setting several common source sets'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) Paths.get(commonDirectory.absolutePath, "build.gradle").append(""" sourceSets { common.kotlin.srcDir 'src/common/kotlin' } """.stripIndent()) createCommonSource(commonDirectory, ["src", "common", "kotlin"], "common.kt", "expect fun bar(): Int") createCommonSource(commonDirectory, ["src", "main", "kotlin"], "main.kt", "expect fun foo() : Int") it.generateSrcFile("platform.kt", "actual fun bar() = 42\nactual fun foo() = 43") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true commonSourceSets 'common', 'main' } } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Build should fail if the expectedBy dependency is not a project one'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") it.generateSrcFile("platform.kt", "actual fun foo() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy files('common/src/main/kotlin/common.kt') } """.stripIndent()) } def result = project.createRunner().withArguments(":build").buildAndFail() then: result.output.contains("dependency is not a project: ") } def 'Build should support several expectedBy-dependencies'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it, "commonFoo") createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") commonDirectory = createCommonProject(it, "commonBar") createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun bar(): Int") it.generateSrcFile("platform.kt", "actual fun foo() = 0\nactual fun bar() = 0") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy project(':commonFoo') expectedBy project(':commonBar') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } def 'Build should fail if the common project has no common plugin'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it,"common", "") createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") it.generateSrcFile("platform.kt", "actual fun bar() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true } } dependencies { expectedBy project(':common') } """.stripIndent()) } def result = project.createRunner().withArguments(":build").buildAndFail() then: result.output.contains("has an 'expectedBy' dependency to non-common project") } @Ignore("TODO in the Big Kotlin plugin") def 'Build should fail if custom common source set doesn\'t exist'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) createCommonSource(commonDirectory, ["src", "main", "kotlin"], "common.kt", "expect fun foo(): Int") it.generateSrcFile("platform.kt", "actual fun bar() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { enableMultiplatform true commonSourceSets 'common' } } dependencies { expectedBy project(':common') } """.stripIndent()) } def result = project.createRunner().withArguments(":build").buildAndFail() then: result.output.contains("Cannot find a source set with name 'common' in a common project") } def 'Setting custom source set should enable the multiplatform support'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> def commonDirectory = createCommonProject(it) Paths.get(commonDirectory.absolutePath, "build.gradle").append(""" sourceSets { common.kotlin.srcDir 'src/common/kotlin' } """.stripIndent()) createCommonSource(commonDirectory, ["src", "common", "kotlin"], "common.kt", "expect fun bar(): Int") it.generateSrcFile("platform.kt", "actual fun bar() = 42") it.buildFile.append(""" konanArtifacts { library('foo') { commonSourceSets 'common' } } dependencies { expectedBy project(':common') } """.stripIndent()) } project.createRunner().withArguments(":build").build() } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/PathSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.TaskOutcome import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.PlatformManager class PathSpecification extends BaseKonanSpecification { boolean fileExists(KonanProject project, String path) { project.konanBuildDir.toPath().resolve(path).toFile().exists() } def platformManager = new PlatformManager(new Distribution(KonanProject.konanHome, false, null), false) def 'Plugin should provide a correct path to the artifacts created'() { expect: def project = KonanProject.createEmpty( projectDirectory, platformManager.enabled.collect { t -> t.visibleName } ) { KonanProject it -> it.generateSrcFile("main.kt") it.generateDefFile("interop.def", "") it.buildFile.append(""" konanArtifacts { program('program') library('library') bitcode('bitcode') interop('interop') framework('framework') dynamic('dynamic') } task checkArtifacts(type: DefaultTask) { dependsOn(':build') doLast { for(artifact in konanArtifacts) { for (target in artifact) { if (!target.artifact.exists()) throw new Exception("Artifact doesn't exist. Type: \${artifact.name}, target: \${target.target}") } } for (target in konanArtifacts.dynamic) { if (!target.headerFile.exists()) throw new Exception("Header file doesn't exist. Target: \${target.target}") } } } """.stripIndent()) } project.createRunner().withArguments("checkArtifacts").build() } def 'Plugin should create all necessary directories'() { when: def project = KonanProject.createWithInterop(projectDirectory) project.addCompilerArtifact("lib", "fun foo() {}", ArtifactType.LIBRARY) project.addCompilerArtifact("bit", "fun bar() {}", ArtifactType.BITCODE) project.createRunner().withArguments('build').build() then: project.konanBuildDir.toPath().resolve("bin/$KonanProject.HOST").toFile().listFiles().findAll { File it -> it.file && it.name.matches("^${KonanProject.DEFAULT_ARTIFACT_NAME}\\.[^.]+") }.size() > 0 fileExists(project, "libs/$KonanProject.HOST/${KonanProject.DEFAULT_INTEROP_NAME}.klib") fileExists(project, "libs/$KonanProject.HOST/lib.klib") fileExists(project, "bitcode/$KonanProject.HOST/bit.bc") } def 'Plugin should stop building if the compiler classpath is empty'() { when: def project = KonanProject.create(projectDirectory) project.propertiesFile.write("konan.home=fakepath") def result = project.createRunner().withArguments('build').buildAndFail() def task = result.task(project.defaultCompilationTask()) then: task == null || task.outcome == TaskOutcome.FAILED } def 'Plugin should stop building if the stub generator classpath is empty'() { when: def project = KonanProject.createWithInterop(projectDirectory) project.propertiesFile.write("konan.home=fakepath") def result = project.createRunner().withArguments('build').buildAndFail() def task = result.task(project.compilationTask(KonanProject.DEFAULT_INTEROP_NAME)) then: task == null || task.outcome == TaskOutcome.FAILED } def 'Plugin should remove custom output directories'() { when: def customOutputDir = projectDirectory.toPath().resolve("foo").toFile() def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY) { KonanProject it -> it.addSetting("baseDir", customOutputDir) } def res1 = project.createRunner().withArguments("build").build() def artifactExistsAfterBuild = customOutputDir.toPath() .resolve("${KonanProject.HOST}/${KonanProject.DEFAULT_ARTIFACT_NAME}.klib").toFile() .exists() def res2 = project.createRunner().withArguments("clean").build() def artifactExistsAfterClean = customOutputDir.toPath() .resolve("${KonanProject.HOST}/${KonanProject.DEFAULT_ARTIFACT_NAME}.klib").toFile() .exists() then: res1.taskPaths(TaskOutcome.SUCCESS).containsAll(project.buildingTasks) res2.taskPaths(TaskOutcome.SUCCESS).contains(":clean") artifactExistsAfterBuild !artifactExistsAfterClean } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/RegressionSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.TaskOutcome class RegressionSpecification extends BaseKonanSpecification { def 'KT-19916'() { when: def project = KonanProject.createEmpty(getProjectDirectory()) { KonanProject prj -> prj.generateSettingsFile("include ':subproject'") def subprojectDir = prj.projectPath.resolve("subproject").toFile() subprojectDir.mkdirs() subprojectDir.toPath().resolve("build.gradle").write(""" dependencies { libs gradleApi() } """.stripIndent()) prj.buildFile.append(""" subprojects { apply plugin: 'konan' apply plugin: Foo } class Foo implements Plugin { void apply(Project project) { project.configurations.maybeCreate("libs") } } """.stripIndent()) } def result = project.createRunner().withArguments('tasks').build() then: result.task(':tasks').outcome == TaskOutcome.SUCCESS } // Ensure gradle plugin fails in case of linker errors. def 'KT-20192'() { when: def project = KonanProject.createEmpty(getProjectDirectory()) { KonanProject prj -> prj.addCompilerArtifact(KonanProject.DEFAULT_ARTIFACT_NAME,""" external fun foo() fun main(args: Array) { foo() } """, ArtifactType.PROGRAM) } def result = project.createRunner().withArguments('build').buildAndFail() then: result.taskPaths(TaskOutcome.FAILED).contains(project.defaultCompilationTask()) } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/groovy/org/jetbrains/kotlin/gradle/plugin/test/TaskSpecification.groovy ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.TaskOutcome import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import spock.lang.Requires import spock.lang.Unroll class TaskSpecification extends BaseKonanSpecification { def 'Configs should allow user to add dependencies to them'() { when: def project = KonanProject.createWithInterop(projectDirectory, ArtifactType.LIBRARY) project.buildFile.append(""" task beforeInterop(type: DefaultTask) { doLast { println("Before Interop") } } task beforeCompilation(type: DefaultTask) { doLast { println("Before compilation") } } """.stripIndent()) project.addSetting(KonanProject.DEFAULT_INTEROP_NAME,"dependsOn", "beforeInterop") project.addSetting("dependsOn", "beforeCompilation") def result = project.createRunner().withArguments('build').build() then: def beforeInterop = result.task(":beforeInterop") beforeInterop != null && beforeInterop.outcome == TaskOutcome.SUCCESS def beforeCompilation = result.task(":beforeCompilation") beforeCompilation != null && beforeCompilation.outcome == TaskOutcome.SUCCESS } def 'Compiler should print time measurements if measureTime flag is set'() { when: def project = KonanProject.create(projectDirectory, ArtifactType.LIBRARY) project.addSetting("measureTime", "true") def result = project.createRunner().withArguments('build').build() then: result.output.findAll(~/Frontend builds AST:\s+\d+\s+msec/).size() == 1 result.output.findAll(~/IR Lowering:\s+\d+\s+msec/).size() == 1 } @Unroll('Plugin should support #option option for cinterop') def 'Plugin should support includeDir option for cinterop'() { expect: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.addCompilerArtifact("interopLib", "headers=foo.h\n$headerFilter", ArtifactType.INTEROP) it.generateSrcFile(it.projectPath, "foo.h", "#include ") def fooDir = it.projectPath.resolve("foo") it.generateSrcFile(fooDir, "bar.h", "const int foo = 5;") it.addSetting("interopLib", option, fooDir.toFile()) it.addSetting("interopLib", option, it.projectDir) } project.createRunner().withArguments("build").build() where: option | headerFilter "includeDirs.headerFilterOnly" | "headerFilter=foo.h bar.h" "includeDirs.allHeaders" | "" "includeDirs" | "" } @Requires({ HostManager.host instanceof KonanTarget.MACOS_X64 }) def 'Plugin should create framework tasks only for Apple targets'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.buildFile.append(""" konan.targets = ['wasm32', 'macbook', 'iphone', 'iphone_sim'] konanArtifacts { framework('foo') } """.stripIndent()) } def result = project.createRunner().withArguments('tasks', '--all').build() then: !compilationTaskExists(result,'foo', 'wasm32') compilationTaskExists (result,'foo', 'macbook') compilationTaskExists (result,'foo', 'iphone') compilationTaskExists (result,'foo', 'iphone_sim') } def 'Plugin should support different targets for different artifacts'() { when: def project = KonanProject.createEmpty(projectDirectory, ['host']) { KonanProject it -> it.buildFile.append(""" konanArtifacts { program('defaultTarget') program('customTarget', targets: ['wasm32']) program('customTargets', targets: ['host', 'wasm32']) } """.stripIndent()) } def result = project.createRunner().withArguments('tasks', '--all').build() def hostName = HostManager.hostName then: compilationTaskExists (result, 'defaultTarget', hostName) !compilationTaskExists(result, 'defaultTarget', 'wasm32') !compilationTaskExists(result, 'customTarget', hostName) compilationTaskExists (result, 'customTarget', 'wasm32') compilationTaskExists (result, 'customTargets', hostName) compilationTaskExists (result, 'customTargets', 'wasm32') } def 'Plugin should not create dynamic task for wasm'() { when: def project = KonanProject.createEmpty(projectDirectory) { KonanProject it -> it.buildFile.append(""" konan.targets = ['wasm32'] konanArtifacts { dynamic('foo') } """.stripIndent()) } def result = project.createRunner().withArguments('tasks', '--all').build() then: !compilationTaskExists(result, 'foo', 'wasm32') } boolean taskExists(BuildResult result, String taskName) { def taskNameForSearch = taskName.startsWith(':') ? taskName.substring(1) : taskName return result.output =~ "\\s$taskNameForSearch\\s" } boolean compilationTaskExists(BuildResult result, String artifactName, String targetName) { return taskExists(result, KonanProject.compilationTask(artifactName, targetName)) } BuildResult failOnPropertyAccess(KonanProject project, String property) { project.buildFile.append(""" task testTask(type: DefaultTask) { doLast { println(${project.defaultInteropConfig()}.$property) } } """.stripIndent()) return project.createRunner().withArguments("testTask").buildAndFail() } BuildResult failOnTaskAccess(KonanProject project, String task) { project.buildFile.append(""" task testTask(type: DefaultTask) { dependsOn $task } """.stripIndent()) return project.createRunner().withArguments("testTask").buildAndFail() } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/kotlin/CompatibilityTests.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.junit.Rule import org.junit.rules.TemporaryFolder import java.io.File import java.net.URI import kotlin.test.Test import kotlin.test.assertTrue open class CompatibilityTests { val tmpFolder = TemporaryFolder() @Rule get val projectDirectory: File get() = tmpFolder.root @Test fun `Plugin should fail if running with Gradle prior to the required one`() { val project = KonanProject.createEmpty(projectDirectory) val result = project .createRunner() .withGradleDistribution(URI.create( "https://cache-redirector.jetbrains.com/services.gradle.org/distributions/gradle-4.5-bin.zip" )) .withArguments("tasks") .buildAndFail() println(result.output) assertTrue("Build doesn't show the warning message") { result.output.contains("Kotlin/Native Gradle plugin is incompatible with this version of Gradle.") } } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariablesTest.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.junit.Rule import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.tools4j.spockito.Spockito import java.io.File import kotlin.test.Test @RunWith(Spockito::class) open class PropertiesAsEnvVariablesTest { val tmpFolder = TemporaryFolder() @Rule get val projectDirectory: File get() = tmpFolder.root private fun artifactFileName(baseName: String, type: ArtifactType, target: KonanTarget = HostManager.host): String { var suffix = "" var prefix = "" when (type) { ArtifactType.PROGRAM -> suffix = target.family.exeSuffix ArtifactType.INTEROP, ArtifactType.LIBRARY -> suffix = "klib" ArtifactType.BITCODE -> suffix = "bc" ArtifactType.FRAMEWORK -> suffix = "framework" ArtifactType.DYNAMIC -> { prefix = target.family.dynamicPrefix suffix = target.family.dynamicSuffix } ArtifactType.STATIC -> { prefix = target.family.staticPrefix suffix = target.family.staticSuffix } } return "$prefix${baseName}.$suffix" } private fun assertFileExists(directory: File, filename: String) = assert(directory.list().contains(filename)) { "No such file: $filename in directory: ${directory.absolutePath}" } @Test @Spockito.Unroll( "|property |value |assertion |message |", "|konan.debugging.symbols |YES |it.enableDebug |Debug should be enabled |", "|konan.debugging.symbols |true |it.enableDebug |Debug should be enabled |", "|konan.debugging.symbols |NO |!it.enableDebug |Debug should be disabled |", "|konan.debugging.symbols |false |!it.enableDebug |Debug should be disabled |", "|konan.optimizations.enable |YES |it.enableOptimizations |Opts should be enabled |", "|konan.optimizations.enable |true |it.enableOptimizations |Opts should be enabled |", "|konan.optimizations.enable |NO |!it.enableOptimizations |Opts should be disabled |", "|konan.optimizations.enable |false |!it.enableOptimizations |Opts should be disabled |" ) @Spockito.Name("[{row}]: {variable}={value}") fun `Plugin should support enabling and disabling debug and opt options via a project property`( property: String, value: String, assertion: String, message: String ) { val project = KonanProject.createEmpty(projectDirectory) project.buildFile.appendText(""" apply plugin: 'konan' konanArtifacts { library('main') } task assertEnableDebug { doLast { konanArtifacts.main.forEach { if (!($assertion)) throw new AssertionError("$message for ${'$'}it.name") } } } """.trimIndent()) project.createRunner() .withArguments("assertEnableDebug", "-P${property}=${value}") .build() } @Test fun `Plugin should support setting destination directory via a project property`() { val project = KonanProject.createEmpty(projectDirectory) val newDestinationDir = project.createSubDir("newDestination") val newDestinationPath = newDestinationDir.absolutePath project.buildFile.appendText(""" apply plugin: 'konan' konanArtifacts { program('program') library('library') dynamic('dynamic') framework('framework') } task assertDestinationDir { doLast { konanArtifacts.forEach { artifact -> artifact.forEach { if (it.destinationDir.absolutePath != '${escapeBackSlashes(newDestinationPath)}'){ throw new AssertionError("Unexpected destination dir for ${'$'}it.name\\n" + "expected: ${escapeBackSlashes(newDestinationPath)}\\n" + "actual: ${'$'}it.destinationDir") } } } } } """.trimIndent()) project.generateSrcFile("main.kt") project.createRunner() .withArguments("assertDestinationDir", "build", "-Pkonan.configuration.build.dir=$newDestinationPath") .build() assertFileExists(newDestinationDir, artifactFileName("program", ArtifactType.PROGRAM)) assertFileExists(newDestinationDir, artifactFileName("library", ArtifactType.LIBRARY)) assertFileExists(newDestinationDir, artifactFileName("dynamic", ArtifactType.DYNAMIC)) if (HostManager.hostIsMac) { assertFileExists(newDestinationDir, artifactFileName("framework", ArtifactType.FRAMEWORK)) } } @Test fun `Plugin should rerun tasks if konan_configuration_build_dir has been changed`() { val project = KonanProject.createEmpty(projectDirectory) val destination1 = project.createSubDir("destination1", "subdir") val destination2 = project.createSubDir("destination2", "subdir") project.buildFile.appendText(""" apply plugin: 'konan' konanArtifacts { library('main') } """.trimIndent()) project.generateSrcFile("main.kt") project.createRunner() .withArguments("build", "-Pkonan.configuration.build.dir=${destination1.absolutePath}") .build() project.createRunner() .withArguments("build", "-Pkonan.configuration.build.dir=${destination2.absolutePath}") .build() assertFileExists(destination1, artifactFileName("main", ArtifactType.LIBRARY)) assertFileExists(destination2, artifactFileName("main", ArtifactType.LIBRARY)) } @Test fun `Up-to-date checks should work with different directories for different targets`() { val project = KonanProject.createEmpty(projectDirectory) val fooDir = project.createSubDir("foo") val barDir = project.createSubDir("bar") project.buildFile.appendText(""" apply plugin: 'konan' konanArtifacts { library('foo') library('bar') } task assertUpToDate { dependsOn 'compileKonanFoo' doLast { if (!konanArtifacts.foo.getByTarget('host').state.upToDate) { throw new AssertionError("Compilation task is not up-to-date") } } } """.trimIndent()) project.generateSrcFile("main.kt") project.createRunner() .withArguments("compileKonanFoo", "-Pkonan.configuration.build.dir=${fooDir.absolutePath}") .build() project.createRunner() .withArguments("compileKonanBar", "-Pkonan.configuration.build.dir=${barDir.absolutePath}") .build() project.createRunner() .withArguments("assertUpToDate", "-Pkonan.configuration.build.dir=${fooDir.absolutePath}") .build() } } ================================================ FILE: tools/kotlin-native-gradle-plugin/src/test/kotlin/TaskTests.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.gradle.plugin.test import org.junit.Rule import org.junit.rules.TemporaryFolder import java.io.File import kotlin.test.Test import kotlin.test.assertFalse import kotlin.test.assertTrue class TaskTests { val tmpFolder = TemporaryFolder() @Rule get val projectDirectory: File get() = tmpFolder.root @Test fun `Plugin should support separate run tasks for different binaries`() { val project = KonanProject.createEmpty(projectDirectory).apply { buildFile.appendText(""" konanArtifacts { program('foo') { srcDir 'src/foo/kotlin' } program('bar') { srcDir 'src/bar/kotlin' } } """.trimIndent()) } project.generateSrcFile( listOf("src", "foo", "kotlin"), "main.kt", "fun main(args: Array) = println(\"Run Foo: \${args[0]}, \${args[1]}\")") project.generateSrcFile( listOf("src", "bar", "kotlin"), "main.kt", "fun main(args: Array) = println(\"Run Bar: \${args[0]}, \${args[1]}\")") val resultFoo = project.createRunner() .withArguments("runFoo", "-PrunArgs=arg1 arg2") .build() val resultAll = project.createRunner() .withArguments("run", "-PrunArgs=arg1 arg2") .build() assertTrue(resultFoo.output.contains("Run Foo: arg1, arg2"), "No Foo output for 'runFoo'") assertFalse(resultFoo.output.contains("Run Bar: "), "There is Bar output for 'runFoo'") assertTrue(resultAll.output.contains("Run Foo: arg1, arg2"), "No Foo output for 'run'") assertTrue(resultAll.output.contains("Run Bar: arg1, arg2"), "No Bar output for 'run'") } } ================================================ FILE: tools/performance-server/build.gradle ================================================ buildscript { ext.rootBuildDirectory = file('../..') apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle" apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } apply plugin: 'kotlin-multiplatform' repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } maven { url buildKotlinCompilerRepo } } kotlin { sourceSets { commonMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" } kotlin.srcDir '../benchmarks/shared/src' } jsMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" implementation(npm("aws-sdk", "~2.670.0")) } kotlin.srcDir 'src/main/kotlin' kotlin.srcDir 'src/main/kotlin-js' kotlin.srcDir 'shared/src/main/kotlin' } } targets { fromPreset(presets.js, 'js') { nodejs() compilations.main.kotlinOptions { outputFile = "${projectDir}/server/app.js" moduleKind = "commonjs" sourceMap = true } } } } ================================================ FILE: tools/performance-server/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: tools/performance-server/gradle.properties ================================================ org.jetbrains.kotlin.native.home=../../dist ================================================ FILE: tools/performance-server/gradlew ================================================ #!/usr/bin/env sh # # Copyright 2015 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn () { echo "$*" } die () { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin or MSYS, switch paths to Windows format before running java if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=`expr $i + 1` done case $i in 0) set -- ;; 1) set -- "$args0" ;; 2) set -- "$args0" "$args1" ;; 3) set -- "$args0" "$args1" "$args2" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Escape application args save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" exec "$JAVACMD" "$@" ================================================ FILE: tools/performance-server/gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: tools/performance-server/package.json ================================================ { "name": "performance-server", "version": "1.0.0", "main": "server/app.js", "scripts": { "start": "node server/app.js" }, "dependencies": { "aws-sdk": "~2.670.0", "body-parser": "~1.18.3", "debug": "~4.1.1", "ejs": "~2.6.1", "express": "~4.16.4", "kotlin": "~1.4.0", "node-fetch": "~2.6.1" } } ================================================ FILE: tools/performance-server/settings.gradle ================================================ ================================================ FILE: tools/performance-server/shared/src/main/kotlin/org/jetbrains/buildInfo/BuildInfo.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.buildInfo import org.jetbrains.report.* import org.jetbrains.report.json.* data class Build(val buildNumber: String, val startTime: String, val finishTime: String, val branch: String, val commits: String, val failuresNumber: Int) { companion object : EntityFromJsonFactory { override fun create(data: JsonElement): Build { if (data is JsonObject) { val buildNumber = elementToString(data.getRequiredField("buildNumber"), "buildNumber").replace("\"", "") val startTime = elementToString(data.getRequiredField("startTime"), "startTime").replace("\"", "") val finishTime = elementToString(data.getRequiredField("finishTime"), "finishTime").replace("\"", "") val branch = elementToString(data.getRequiredField("branch"), "branch").replace("\"", "") val commits = elementToString(data.getRequiredField("commits"), "commits") val failuresNumber = elementToInt(data.getRequiredField("failuresNumber"), "failuresNumber") return Build(buildNumber, startTime, finishTime, branch, commits, failuresNumber) } else { error("Top level entity is expected to be an object. Please, check origin files.") } } } private fun formatTime(time: String, targetZone: Int = 3): String { val matchResult = "^\\d{8}T(\\d{2})(\\d{2})\\d{2}((\\+|-)\\d{2})".toRegex().find(time)?.groupValues matchResult?.let { val timeZone = matchResult[3].toInt() val timeDifference = targetZone - timeZone var hours = (matchResult[1].toInt() + timeDifference) if (hours > 23) { hours -= 24 } return "${if (hours < 10) "0$hours" else "$hours"}:${matchResult[2]}" } ?: error { "Wrong format of time $startTime" } } val date: String by lazy { val matchResult = "^(\\d{4})(\\d{2})(\\d{2})".toRegex().find(startTime)?.groupValues matchResult?.let { "${matchResult[3]}/${matchResult[2]}/${matchResult[1]}" } ?: error { "Wrong format of time $startTime" } } val formattedStartTime: String by lazy { formatTime(startTime) } val formattedFinishTime: String by lazy { formatTime(finishTime) } } ================================================ FILE: tools/performance-server/shared/src/main/kotlin/org/jetbrains/elastic/ElasticSearchConnector.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.elastic import kotlin.js.Promise // TODO - migrate to multiplatform. import org.jetbrains.report.json.* import org.jetbrains.network.* // Connector with InfluxDB. class ElasticSearchConnector(private val connector: NetworkConnector, private val user: String? = null, private val password: String? = null) { // Execute ElasticSearch request. fun request(method: RequestMethod, path: String, acceptJsonContentType: Boolean = true, body: String? = null) = connector.sendRequest(method, path, user, password, acceptJsonContentType, body) } ================================================ FILE: tools/performance-server/shared/src/main/kotlin/org/jetbrains/elastic/ElasticSearchIndex.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.elastic import org.jetbrains.report.* import org.jetbrains.report.json.* import org.jetbrains.report.MeanVarianceBenchmark import org.jetbrains.network.* import kotlin.js.Promise // TODO - migrate to multiplatform. data class Commit(val revision: String, val developer: String) : JsonSerializable { override fun toString() = "$revision by $developer" override fun serializeFields() = """ "revision": "$revision", "developer": "$developer" """ companion object : EntityFromJsonFactory { fun parse(description: String) = if (description != "...") { description.split(" by ").let { val (currentRevision, currentDeveloper) = it Commit(currentRevision, currentDeveloper) } } else { Commit("unknown", "unknown") } override fun create(data: JsonElement): Commit { if (data is JsonObject) { val revision = elementToString(data.getRequiredField("revision"), "revision") val developer = elementToString(data.getRequiredField("developer"), "developer") return Commit(revision, developer) } else { error("Top level entity is expected to be an object. Please, check origin files.") } } } } // List of commits. class CommitsList : ConvertedFromJson, JsonSerializable { val commits: List constructor(data: JsonElement) { if (data !is JsonObject) { error("Commits description is expected to be a JSON object!") } val changesElement = data.getOptionalField("change") commits = changesElement?.let { if (changesElement !is JsonArray) { error("Change field is expected to be an array. Please, check source.") } changesElement.jsonArray.map { with(it as JsonObject) { Commit(elementToString(getRequiredField("version"), "version"), elementToString(getRequiredField("username"), "username") ) } } } ?: listOf() } constructor(_commits: List) { commits = _commits } override fun toString(): String = commits.toString() companion object { fun parse(description: String) = CommitsList(description.split(";").filter { it.isNotEmpty() }.map { Commit.parse(it) }) } override fun serializeFields() = """ "commits": ${arrayToJson(commits)} """ } data class BuildInfo(val buildNumber: String, val startTime: String, val endTime: String, val commitsList: CommitsList, val branch: String, val agentInfo: String /* Important agent information often used in requests.*/) : JsonSerializable { override fun serializeFields() = """ "buildNumber": "$buildNumber", "startTime": "$startTime", "endTime": "$endTime", ${commitsList.serializeFields()}, "branch": "$branch", "agentInfo": "$agentInfo" """ companion object : EntityFromJsonFactory { override fun create(data: JsonElement): BuildInfo { if (data is JsonObject) { val buildNumber = elementToString(data.getRequiredField("buildNumber"), "buildNumber") val startTime = elementToString(data.getRequiredField("startTime"), "startTime") val endTime = elementToString(data.getRequiredField("endTime"), "endTime") val branch = elementToString(data.getRequiredField("branch"), "branch") val commitsList = data.getRequiredField("commits") val commits = if (commitsList is JsonArray) { commitsList.jsonArray.map { Commit.create(it as JsonObject) } } else { error("benchmarksSets field is expected to be an array. Please, check origin files.") } val agentInfoElement = data.getOptionalField("agentInfo") val agentInfo = agentInfoElement?.let { elementToString(agentInfoElement, "agentInfo") } ?: "" return BuildInfo(buildNumber, startTime, endTime, CommitsList(commits), branch, agentInfo) } else { error("Top level entity is expected to be an object. Please, check origin files.") } } } } enum class ElasticSearchType { TEXT, KEYWORD, DATE, LONG, DOUBLE, BOOLEAN, OBJECT, NESTED } abstract class ElasticSearchIndex(val indexName: String, val connector: ElasticSearchConnector) { // Insert data. fun insert(data: JsonSerializable): Promise { val description = data.toJson() val writePath = "$indexName/_doc/" return connector.request(RequestMethod.POST, writePath, body = description) } // Delete data. fun delete(data: String): Promise { val writePath = "$indexName/_delete_by_query" return connector.request(RequestMethod.POST, writePath, body = data) } // Make search request. fun search(requestJson: String, filterPathes: List = emptyList()): Promise { val path = "$indexName/_search?pretty${if (filterPathes.isNotEmpty()) "&filter_path=" + filterPathes.joinToString(",") else ""}" return connector.request(RequestMethod.POST, path, body = requestJson) } abstract val mapping: Map val mappingDescription: String get() = """ { "mappings": { "properties": { ${mapping.map { (property, type) -> "\"${property}\": { \"type\": \"${type.name.toLowerCase()}\"${if (type == ElasticSearchType.DATE) "," + "\"format\": \"basic_date_time_no_millis\"" else ""} }" }.joinToString()}} } } """.trimIndent() fun createMapping() = connector.request(RequestMethod.PUT, indexName, body = mappingDescription) } class BenchmarksIndex(name: String, connector: ElasticSearchConnector) : ElasticSearchIndex(name, connector) { override val mapping: Map get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD, "benchmarks" to ElasticSearchType.NESTED, "env" to ElasticSearchType.NESTED, "kotlin" to ElasticSearchType.NESTED) } class GoldenResultsIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("golden", connector) { override val mapping: Map get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD, "benchmarks" to ElasticSearchType.NESTED, "env" to ElasticSearchType.NESTED, "kotlin" to ElasticSearchType.NESTED) } class BuildInfoIndex(connector: ElasticSearchConnector) : ElasticSearchIndex("builds", connector) { override val mapping: Map get() = mapOf("buildNumber" to ElasticSearchType.KEYWORD, "startTime" to ElasticSearchType.DATE, "endTime" to ElasticSearchType.DATE, "commits" to ElasticSearchType.NESTED) } // Processed benchmark result with calculated mean, variance and normalized reult. class NormalizedMeanVarianceBenchmark(name: String, status: BenchmarkResult.Status, score: Double, metric: BenchmarkResult.Metric, runtimeInUs: Double, repeat: Int, warmup: Int, variance: Double, val normalizedScore: Double) : MeanVarianceBenchmark(name, status, score, metric, runtimeInUs, repeat, warmup, variance) { override fun serializeFields(): String { return """ ${super.serializeFields()}, "normalizedScore": $normalizedScore """ } } ================================================ FILE: tools/performance-server/shared/src/main/kotlin/org/jetbrains/network/NetworkConnector.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.network import kotlin.js.Promise // TODO - migrate to multiplatform. import kotlin.js.json // TODO - migrate to multiplatform. // Now implemenation for network connection only for Node.js. TODO - multiplatform. external fun require(module: String): dynamic enum class RequestMethod { POST, GET, PUT } // Abstract class for working with network. abstract class NetworkConnector { fun getAuth(user: String, password: String): String { val buffer = js("Buffer").from(user + ":" + password) val based64String = buffer.toString("base64") return "Basic " + based64String } protected abstract fun sendBaseRequest(method: RequestMethod, path: String, user: String? = null, password: String? = null, acceptJsonContentType: Boolean = true, body: String? = null, errorHandler: (url: String, response: dynamic) -> Nothing?): Promise open fun sendRequest(method: RequestMethod, path: String, user: String? = null, password: String? = null, acceptJsonContentType: Boolean = true, body: String? = null): Promise = sendBaseRequest(method, path, user, password, acceptJsonContentType, body) { url, response -> error("Error during getting response from $url\n$response") } open fun sendOptionalRequest(method: RequestMethod, path: String, user: String? = null, password: String? = null, acceptJsonContentType: Boolean = true, body: String? = null): Promise = sendBaseRequest(method, path, user, password, acceptJsonContentType, body) { url, response -> println("Error during getting response from $url\n$response") null } } ================================================ FILE: tools/performance-server/shared/src/main/kotlin/org/jetbrains/network/UrlNetworkConnector.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.network import kotlin.js.Promise // TODO - migrate to multiplatform. import kotlin.js.json // TODO - migrate to multiplatform. // Network connector to work with basic url requests. class UrlNetworkConnector(private val host: String, private val port: Int? = null) : NetworkConnector() { private val url = "$host${port?.let { ":$port" } ?: ""}" override fun sendBaseRequest(method: RequestMethod, path: String, user: String?, password: String?, acceptJsonContentType: Boolean, body: String?, errorHandler: (url: String, response: dynamic) -> Nothing?): Promise { val fullUrl = "$url/$path" val request = require("node-fetch") val headers = mutableListOf>() if (user != null && password != null) { headers.add("Authorization" to getAuth(user, password)) } if (acceptJsonContentType) { headers.add("Accept" to "application/json") headers.add("Content-Type" to "application/json") } return request(fullUrl, json( "method" to method.toString(), "headers" to json(*(headers.toTypedArray())), "body" to body ) ).then { response -> if (!response.ok) { println(JSON.stringify(response)) errorHandler(fullUrl, response) } else { response.text() } } } } ================================================ FILE: tools/performance-server/src/main/kotlin/database/BenchmarksIndexesDispatcher.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.database import kotlin.js.Promise import org.jetbrains.elastic.* import org.jetbrains.utils.* import org.jetbrains.report.json.* import org.jetbrains.report.* fun Iterable.isEmpty() = count() == 0 fun Iterable.isNotEmpty() = !isEmpty() inline fun T?.str(block: (T) -> String): String = if (this != null) block(this) else "" // Dispatcher to create and control benchmarks indexes separated by some feature. // Feature can be choosen as often used as filtering entity in case there is no need in separate indexes. // Default behaviour of dispatcher is working with one index (case when separating isn't needed). class BenchmarksIndexesDispatcher(connector: ElasticSearchConnector, val feature: String, featureValues: Iterable = emptyList()) { // Becnhmarks indexes to work with in case of existing feature values. private val benchmarksIndexes = if (featureValues.isNotEmpty()) featureValues.map { it to BenchmarksIndex("benchmarks_${it.replace(" ", "_").toLowerCase()}", connector) } .toMap() else emptyMap() // Single benchmark index. private val benchmarksSingleInstance = if (featureValues.isEmpty()) BenchmarksIndex("benchmarks", connector) else null // Get right index in ES. private fun getIndex(featureValue: String = "") = benchmarksSingleInstance ?: benchmarksIndexes[featureValue] ?: error("Used wrong feature value $featureValue. Indexes are separated using next values: ${benchmarksIndexes.keys}") // Used filter to get data with needed feature value. var featureFilter: ((String) -> String)? = null // Get benchmark reports corresponding to needed build number. fun getBenchmarksReports(buildNumber: String, featureValue: String): Promise> { val queryDescription = """ { "size": 1000, "query": { "bool": { "must": [ { "match": { "buildNumber": "$buildNumber" } } ] } } } """ return getIndex(featureValue).search(queryDescription, listOf("hits.hits._source")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject dbResponse.getObjectOrNull("hits")?.getArrayOrNull("hits")?.let { results -> results.map { val element = it as JsonObject element.getObject("_source").toString() } } ?: emptyList() } } // Get benchmarkes names corresponding to needed build number. fun getBenchmarksList(buildNumber: String, featureValue: String): Promise> { return getBenchmarksReports(buildNumber, featureValue).then { reports -> reports.map { val dbResponse = JsonTreeParser.parse(it).jsonObject parseBenchmarksArray(dbResponse.getArray("benchmarks")) .map { it.name } }.flatten() } } // Delete benchmarks from database. fun deleteBenchmarks(featureValue: String, buildNumber: String? = null): Promise { // Delete all or for choosen build number. val matchQuery = buildNumber?.let { """"match": { "buildNumber": "$it" }""" } ?: """"match_all": {}""" val queryDescription = """ { "query": { $matchQuery } } """.trimIndent() return getIndex(featureValue).delete(queryDescription) } // Get benchmarks values of needed metric for choosen build number. fun getSamples(metricName: String, featureValue: String = "", samples: List, buildsCountToShow: Int, buildNumbers: Iterable? = null, normalize: Boolean = false): Promise>>> { val queryDescription = """ { "_source": ["buildNumber"], "size": ${samples.size * buildsCountToShow}, "query": { "bool": { "must": [ ${buildNumbers.str { builds -> """ { "terms" : { "buildNumber" : [${builds.map { "\"$it\"" }.joinToString()}] } },""" } } ${featureFilter.str { "${it(featureValue)}," } } {"nested" : { "path" : "benchmarks", "query" : { "bool": { "must": [ { "match": { "benchmarks.metric": "$metricName" } }, { "terms": { "benchmarks.name": [${samples.map { "\"${it.toLowerCase()}\"" }.joinToString()}] }} ] } }, "inner_hits": { "size": ${samples.size}, "_source": ["benchmarks.name", "benchmarks.${if (normalize) "normalizedScore" else "score"}"] } } } ] } } }""" return getIndex(featureValue).search(queryDescription, listOf("hits.hits._source", "hits.hits.inner_hits")) .then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject val results = dbResponse.getObjectOrNull("hits")?.getArrayOrNull("hits") ?: error("Wrong response:\n$responseString") // Get indexes for provided samples. val indexesMap = samples.mapIndexed { index, it -> it to index }.toMap() val valuesMap = buildNumbers?.map { it to arrayOfNulls(samples.size) }?.toMap()?.toMutableMap() ?: mutableMapOf>() // Parse and save values in requested order. results.forEach { val element = it as JsonObject val build = element.getObject("_source").getPrimitive("buildNumber").content buildNumbers?.let { valuesMap.getOrPut(build) { arrayOfNulls(samples.size) } } element .getObject("inner_hits") .getObject("benchmarks") .getObject("hits") .getArray("hits").forEach { val source = (it as JsonObject).getObject("_source") valuesMap[build]!![indexesMap[source.getPrimitive("name").content]!!] = source.getPrimitive(if (normalize) "normalizedScore" else "score").double } } valuesMap.toList() } } fun insert(data: JsonSerializable, featureValue: String = "") = getIndex(featureValue).insert(data) fun delete(data: String, featureValue: String = "") = getIndex(featureValue).delete(data) // Get failures number happned during build. fun getFailuresNumber(featureValue: String = "", buildNumbers: Iterable? = null): Promise> { val queryDescription = """ { "_source": false, ${featureFilter.str { """ "query": { "bool": { "must": [ ${it(featureValue)} ] } }, """ } } ${buildNumbers.str { builds -> """ "aggs" : { "builds": { "filters" : { "filters": { ${builds.map { "\"$it\": { \"match\" : { \"buildNumber\" : \"$it\" }}" } .joinToString(",\n")} } },""" } } "aggs" : { "metric_build" : { "nested" : { "path" : "benchmarks" }, "aggs" : { "metric_samples": { "filters" : { "filters": { "samples": { "match": { "benchmarks.status": "FAILED" } } } }, "aggs" : { "failed_count": { "value_count": { "field" : "benchmarks.score" } } } } } ${buildNumbers.str { """ } }""" } } } } } """ return getIndex(featureValue).search(queryDescription, listOf("aggregations")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject val aggregations = dbResponse.getObjectOrNull("aggregations") ?: error("Wrong response:\n$responseString") buildNumbers?.let { // Get failed number for each provided build. val buckets = aggregations .getObjectOrNull("builds") ?.getObjectOrNull("buckets") ?: error("Wrong response:\n$responseString") buildNumbers.map { it to buckets .getObject(it) .getObject("metric_build") .getObject("metric_samples") .getObject("buckets") .getObject("samples") .getObject("failed_count") .getPrimitive("value") .int }.toMap() } ?: listOf("golden" to aggregations .getObject("metric_build") .getObject("metric_samples") .getObject("buckets") .getObject("samples") .getObject("failed_count") .getPrimitive("value") .int ).toMap() } } // Get geometric mean for benchmarks values of needed metric. fun getGeometricMean(metricName: String, featureValue: String = "", buildNumbers: Iterable? = null, normalize: Boolean = false, excludeNames: List = emptyList()): Promise>>> { // Filter only with metric or also with names. val filterBenchmarks = if (excludeNames.isEmpty()) """ "match": { "benchmarks.metric": "$metricName" } """ else """ "bool": { "must": { "match": { "benchmarks.metric": "$metricName" } }, "must_not": [ ${excludeNames.map { """{ "match_phrase" : { "benchmarks.name" : "$it" } }"""}.joinToString() } ] } """.trimIndent() val queryDescription = """ { "_source": false, ${featureFilter.str { """ "query": { "bool": { "must": [ ${it(featureValue)} ] } }, """ } } ${buildNumbers.str { builds -> """ "aggs" : { "builds": { "filters" : { "filters": { ${builds.map { "\"$it\": { \"match\" : { \"buildNumber\" : \"$it\" }}" } .joinToString(",\n")} } },""" } } "aggs" : { "metric_build" : { "nested" : { "path" : "benchmarks" }, "aggs" : { "metric_samples": { "filters" : { "filters": { "samples": { $filterBenchmarks } } }, "aggs" : { "sum_log_x": { "sum": { "field" : "benchmarks.${if (normalize) "normalizedScore" else "score"}", "script" : { "source": "if (_value == 0) { 0.0 } else { Math.log(_value) }" } } }, "geom_mean": { "bucket_script": { "buckets_path": { "sum_log_x": "sum_log_x", "x_cnt": "_count" }, "script": "Math.exp(params.sum_log_x/params.x_cnt)" } } } } } ${buildNumbers.str { """ } }""" } } } } } """ return getIndex(featureValue).search(queryDescription, listOf("aggregations")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject val aggregations = dbResponse.getObjectOrNull("aggregations") ?: error("Wrong response:\n$responseString") buildNumbers?.let { val buckets = aggregations .getObjectOrNull("builds") ?.getObjectOrNull("buckets") ?: error("Wrong response:\n$responseString") buildNumbers.map { it to listOf(buckets .getObject(it) .getObject("metric_build") .getObject("metric_samples") .getObject("buckets") .getObject("samples") .getObjectOrNull("geom_mean") ?.getPrimitive("value") ?.double ) } } ?: listOf("golden" to listOf(aggregations .getObject("metric_build") .getObject("metric_samples") .getObject("buckets") .getObject("samples") .getObjectOrNull("geom_mean") ?.getPrimitive("value") ?.double ) ) } } } ================================================ FILE: tools/performance-server/src/main/kotlin/database/DatabaseRequests.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.database import kotlin.js.Promise import org.jetbrains.elastic.* import org.jetbrains.utils.* import org.jetbrains.report.json.* import org.jetbrains.report.* // Delete build information from ES index. internal fun deleteBuildInfo(agentInfo: String, buildInfoIndex: ElasticSearchIndex, buildNumber: String? = null): Promise { val queryDescription = """ { "query": { "bool": { "must": [ { "match": { "agentInfo": "$agentInfo" } } ${buildNumber?.let { """, {"match": { "buildNumber": "$it" }} """ } ?: ""} ] } } } """.trimIndent() return buildInfoIndex.delete(queryDescription) } // Get infromation about builds details from database. internal fun getBuildsDescription(type: String?, branch: String?, agentInfo: String, buildInfoIndex: ElasticSearchIndex, buildsCountToShow: Int, beforeDate: String?, afterDate: String?, onlyNumbers: Boolean = false): Promise { val queryDescription = """ { "size": $buildsCountToShow, ${if (onlyNumbers) """"_source": ["buildNumber"],""" else ""} "sort": {"startTime": "desc" }, "query": { "bool": { "must": [ { "match": { "agentInfo": "$agentInfo" } } ${type?.let { """, { "regexp": { "buildNumber": { "value": "${if (it == "release") ".*eap.*|.*release.*|.*rc.*" else ".*dev.*"}" } } } """ } ?: ""} ${beforeDate?.let { """, { "range": { "startTime": { "lt": "$it" } } } """ } ?: ""} ${afterDate?.let { """, { "range": { "startTime": { "gt": "$it" } } } """ } ?: ""} ${branch?.let { """, {"match": { "branch": "$it" }} """ } ?: ""} ] } } } """.trimIndent() return buildInfoIndex.search(queryDescription, listOf("hits.hits._source")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject dbResponse.getObjectOrNull("hits")?.getArrayOrNull("hits") ?: error("Wrong response:\n$responseString") } } // Check if current build already exists. suspend fun buildExists(buildInfo: BuildInfo, buildInfoIndex: ElasticSearchIndex): Boolean { val queryDescription = """ { "size": 1, "_source": ["buildNumber"], "query": { "bool": { "must": [ { "match": { "buildNumber": "${buildInfo.buildNumber}" } }, { "match": { "agentInfo": "${buildInfo.agentInfo}" } }, { "match": { "branch": "${buildInfo.branch}" } } ] } } } """.trimIndent() return buildInfoIndex.search(queryDescription, listOf("hits.total.value")).then { responseString -> val response = JsonTreeParser.parse(responseString).jsonObject val value = response.getObjectOrNull("hits")?.getObjectOrNull("total")?.getPrimitiveOrNull("value")?.content ?: error("Error response from ElasticSearch:\n$responseString") value.toInt() > 0 }.await() } // Get builds numbers corresponding to machine and branch. fun getBuildsNumbers(type: String?, branch: String?, agentInfo: String, buildsCountToShow: Int, buildInfoIndex: ElasticSearchIndex, beforeDate: String? = null, afterDate: String? = null) = getBuildsDescription(type, branch, agentInfo, buildInfoIndex, buildsCountToShow, beforeDate, afterDate, true) .then { responseArray -> responseArray.map { (it as JsonObject).getObject("_source").getPrimitive("buildNumber").content } } // Get full builds information corresponding to machine and branch. fun getBuildsInfo(type: String?, branch: String?, agentInfo: String, buildsCountToShow: Int, buildInfoIndex: ElasticSearchIndex, beforeDate: String? = null, afterDate: String? = null) = getBuildsDescription(type, branch, agentInfo, buildInfoIndex, buildsCountToShow, beforeDate, afterDate).then { responseArray -> responseArray.map { BuildInfo.create((it as JsonObject).getObject("_source")) } } // Get golden results from database. fun getGoldenResults(goldenResultsIndex: GoldenResultsIndex): Promise>> { return goldenResultsIndex.search("", listOf("hits.hits._source")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject dbResponse.getObjectOrNull("hits")?.getArrayOrNull("hits")?.map { val reportDescription = (it as JsonObject).getObject("_source") BenchmarksReport.create(reportDescription).benchmarks }?.reduce { acc, it -> acc + it } ?: error("Wrong format of response:\n $responseString") } } // Get list of unstable benchmarks from database. fun getUnstableResults(goldenResultsIndex: GoldenResultsIndex): Promise> { val queryDescription = """ { "_source": ["env"], "query": { "nested" : { "path" : "benchmarks", "query" : { "match": { "benchmarks.unstable": true } }, "inner_hits": { "size": 100, "_source": ["benchmarks.name"] } } } } """.trimIndent() return goldenResultsIndex.search(queryDescription, listOf("hits.hits.inner_hits")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject val results = dbResponse.getObjectOrNull("hits")?.getArrayOrNull("hits") ?: error("Wrong response:\n$responseString") results.getObjectOrNull(0)?.let { it .getObject("inner_hits") .getObject("benchmarks") .getObject("hits") .getArray("hits").map { (it as JsonObject).getObject("_source").getPrimitive("name").content } } ?: listOf() } } // Get distinct values for needed field from database. fun distinctValues(field: String, index: ElasticSearchIndex): Promise> { val queryDescription = """ { "aggs": { "unique": {"terms": {"field": "$field", "size": 1000}} } } """.trimIndent() return index.search(queryDescription, listOf("aggregations.unique.buckets")).then { responseString -> val dbResponse = JsonTreeParser.parse(responseString).jsonObject dbResponse.getObjectOrNull("aggregations")?.getObjectOrNull("unique")?.getArrayOrNull("buckets") ?.map { (it as JsonObject).getPrimitiveOrNull("key")?.content }?.filterNotNull() ?: error("Wrong response:\n$responseString") } } ================================================ FILE: tools/performance-server/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ external fun require(module: String): dynamic external val process: dynamic external val __dirname: dynamic fun main(args: Array) { println("Server Starting!") val express = require("express") val app = express() val path = require("path") val bodyParser = require("body-parser") val http = require("http") // Get port from environment and store in Express. val port = normalizePort(process.env.PORT) app.use(bodyParser.json()) app.set("port", port) // View engine setup. app.set("views", path.join(__dirname, "../ui")) app.set("view engine", "ejs") app.use(express.static("ui")) val server = http.createServer(app) app.listen(port, { println("App listening on port " + port + "!") }) app.use("/", router()) } fun normalizePort(port: Int) = if (port >= 0) port else 3000 ================================================ FILE: tools/performance-server/src/main/kotlin/network/CachableResponseDispatcher.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ @file:OptIn(ExperimentalTime::class) package org.jetbrains.network import kotlin.js.Promise // TODO - migrate to multiplatform. import kotlin.time.* // Response saved in cache. data class CachedResponse(val cachedResult: Any, val time: TimeMark) // Dispatcher for work with cachable responses. object CachableResponseDispatcher { // Storage of cached responses. private val cachedResponses = mutableMapOf() private val cacheMaxSize = 200 // Get response. If response isn't cached, use provided action to get response. fun getResponse(request: dynamic, response: dynamic, action: (success: (result: Any) -> Unit, reject: () -> Unit) -> Unit) { cachedResponses[request.url]?.let { // Update cache value if needed. Update only if last result was get later than 2 minutes. if (it.time.elapsedNow().inMinutes > 2.0) { println("Cache update for ${request.url}...") action({ result: Any -> cachedResponses[request.url] = CachedResponse(result, TimeSource.Monotonic.markNow()) }, { println("Cache update for ${request.url} failed!") }) } response.json(it.cachedResult) } ?: run { action({ result: Any -> if (cachedResponses.size >= cacheMaxSize) { cachedResponses[request.url] = CachedResponse(result, TimeSource.Monotonic.markNow()) } response.json(result) }, { response.sendStatus(400) }) } } fun clear(): Unit { cachedResponses.clear() } } ================================================ FILE: tools/performance-server/src/main/kotlin/network/aws/AWSNetworkUtils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.network import kotlin.js.Promise // TODO - migrate to multiplatform. import kotlin.js.json // TODO - migrate to multiplatform. import kotlin.js.Date import org.jetbrains.report.json.* // Placeholder as analog for indexable type in TS. external interface `T$0` { @nativeGetter operator fun get(key: String): String? @nativeSetter operator fun set(key: String, value: String) } @JsModule("aws-sdk") @JsNonModule external object AWSInstance { // Replace dynamic with some real type class Endpoint(domain: String) open class HttpRequest(endpoint: Endpoint, region: String) { open fun pathname(): String open var search: String open var body: String? open var endpoint: Endpoint open var headers: `T$0` open var method: String open var path: String } class HttpClient() { val handleRequest: dynamic } interface Credentials class SharedIniFileCredentials(options: Map): Credentials { val accessKeyId: String } class EnvironmentCredentials(envPrefix: String): Credentials { val accessKeyId: String } class Signers() { class V4(request: HttpRequest, subsystem: String) { fun addAuthorization(credentials: Credentials, date: Date) } } } // Network connector to work with AWS resources. class AWSNetworkConnector : NetworkConnector() { val AWSDomain = "vpc-kotlin-perf-service-5e6ldakkdv526ii5hbclzcmpny.eu-west-1.es.amazonaws.com" val AWSRegion = "eu-west-1" override fun sendBaseRequest(method: RequestMethod, path: String, user: String?, password: String?, acceptJsonContentType: Boolean, body: String?, errorHandler: (url: String, response: dynamic) -> Nothing?): Promise { val useEnvironmentCredentials = true // For easy test on localhost change to false. val AWSEndpoint = AWSInstance.Endpoint(AWSDomain) var request = AWSInstance.HttpRequest(AWSEndpoint, AWSRegion) request.method = method.toString() request.path += path request.body = body request.headers["host"] = this.AWSDomain if (acceptJsonContentType) { request.headers["Content-Type"] = "application/json" request.headers["Content-Length"] = js("Buffer").byteLength(request.body) } val credentials = if (useEnvironmentCredentials) AWSInstance.EnvironmentCredentials("AWS") else AWSInstance.SharedIniFileCredentials(mapOf()) val signer = AWSInstance.Signers.V4(request, "es") signer.addAuthorization(credentials, Date()) val client = AWSInstance.HttpClient() return Promise { resolve, reject -> client.handleRequest(request, null, { response -> var responseBody = "" response.on("data") { chunk -> responseBody += chunk chunk } response.on("end") { _ -> val dbResponse = JsonTreeParser.parse(responseBody).jsonObject // Response can fail and return 400 error for ES. if (dbResponse.getPrimitiveOrNull("status")?.let { it.content != "200" } ?: false) { println(dbResponse) val errorMessage = dbResponse.getObject("error").toString() reject(Throwable(errorMessage)) } resolve(responseBody as T) } }, { error -> reject(error) }) } } } ================================================ FILE: tools/performance-server/src/main/kotlin/routes/route.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.w3c.xhr.* import kotlin.js.json import kotlin.js.Date import kotlin.js.Promise import org.jetbrains.database.* import org.jetbrains.report.json.* import org.jetbrains.elastic.* import org.jetbrains.network.* import org.jetbrains.buildInfo.Build import org.jetbrains.analyzer.* import org.jetbrains.report.* import org.jetbrains.utils.* // TODO - create DSL for ES requests? const val teamCityUrl = "https://buildserver.labs.intellij.net/app/rest" const val artifactoryUrl = "https://repo.labs.intellij.net/kotlin-native-benchmarks" operator fun Map?.get(key: K) = this?.get(key) fun getArtifactoryHeader(artifactoryApiKey: String) = Pair("X-JFrog-Art-Api", artifactoryApiKey) external fun decodeURIComponent(url: String): String // Convert saved old report to expected new format. internal fun convertToNewFormat(data: JsonObject): List { val env = Environment.create(data.getRequiredField("env")) val benchmarksObj = data.getRequiredField("benchmarks") val compilerDescription = data.getRequiredField("kotlin") val compiler = Compiler.create(compilerDescription) val backend = (compilerDescription as JsonObject).getRequiredField("backend") val flagsArray = (backend as JsonObject).getOptionalField("flags") var flags: List = emptyList() if (flagsArray != null && flagsArray is JsonArray) { flags = flagsArray.jsonArray.map { (it as JsonLiteral).unquoted() } } val benchmarksList = parseBenchmarksArray(benchmarksObj) return listOf(env, compiler, benchmarksList, flags) } // Convert data results to expected format. internal fun convert(json: String, buildNumber: String, target: String): List { val data = JsonTreeParser.parse(json) val reports = if (data is JsonArray) { data.map { convertToNewFormat(it as JsonObject) } } else listOf(convertToNewFormat(data as JsonObject)) // Restored flags for old reports. val knownFlags = mapOf( "Cinterop" to listOf("-opt"), "FrameworkBenchmarksAnalyzer" to listOf("-g"), "HelloWorld" to if (target == "Mac OS X") listOf("-Xcache-directory=/Users/teamcity/buildAgent/work/c104dee5223a31c5/test_dist/klib/cache/macos_x64-gSTATIC", "-g") else listOf("-g"), "Numerical" to listOf("-opt"), "ObjCInterop" to listOf("-opt"), "Ring" to listOf("-opt"), "Startup" to listOf("-opt"), "swiftInterop" to listOf("-opt"), "Videoplayer" to if (target == "Mac OS X") listOf("-Xcache-directory=/Users/teamcity/buildAgent/work/c104dee5223a31c5/test_dist/klib/cache/macos_x64-gSTATIC", "-g") else listOf("-g") ) return reports.map { elements -> val benchmarks = (elements[2] as List).groupBy { it.name.substringBefore('.').substringBefore(':') } val parsedFlags = elements[3] as List benchmarks.map { (setName, results) -> val flags = if (parsedFlags.isNotEmpty() && parsedFlags[0] == "-opt") knownFlags[setName]!! else parsedFlags val savedCompiler = elements[1] as Compiler val compiler = Compiler(Compiler.Backend(savedCompiler.backend.type, savedCompiler.backend.version, flags), savedCompiler.kotlinVersion) val newReport = BenchmarksReport(elements[0] as Environment, results, compiler) newReport.buildNumber = buildNumber newReport } }.flatten() } // Golden result value used to get normalized results. data class GoldenResult(val benchmarkName: String, val metric: String, val value: Double) data class GoldenResultsInfo(val goldenResults: Array) // Convert information about golden results to benchmarks report format. fun GoldenResultsInfo.toBenchmarksReport(): BenchmarksReport { val benchmarksSamples = goldenResults.map { BenchmarkResult(it.benchmarkName, BenchmarkResult.Status.PASSED, it.value, BenchmarkResult.metricFromString(it.metric)!!, it.value, 1, 0) } val compiler = Compiler(Compiler.Backend(Compiler.BackendType.NATIVE, "golden", emptyList()), "golden") val environment = Environment(Environment.Machine("golden", "golden"), Environment.JDKInstance("golden", "golden")) return BenchmarksReport(environment, benchmarksSamples, compiler) } // Build information provided from request. data class TCBuildInfo(val buildNumber: String, val branch: String, val startTime: String, val finishTime: String) data class BuildRegister(val buildId: String, val teamCityUser: String, val teamCityPassword: String, val bundleSize: String?, val fileWithResult: String) { companion object { fun create(json: String): BuildRegister { val requestDetails = JSON.parse(json) // Parse method doesn't create real instance with all methods. So create it by hands. return BuildRegister(requestDetails.buildId, requestDetails.teamCityUser, requestDetails.teamCityPassword, requestDetails.bundleSize, requestDetails.fileWithResult) } } private val teamCityBuildUrl: String by lazy { "builds/id:$buildId" } val changesListUrl: String by lazy { "changes/?locator=build:id:$buildId" } val teamCityArtifactsUrl: String by lazy { "builds/id:$buildId/artifacts/content/$fileWithResult" } fun sendTeamCityRequest(url: String, json: Boolean = false) = UrlNetworkConnector(teamCityUrl).sendRequest(RequestMethod.GET, url, teamCityUser, teamCityPassword, json) fun getBranchName(project: String): Promise { val url = "builds?locator=id:$buildId&fields=build(revisions(revision(vcsBranchName,vcs-root-instance)))" var branch: String? = null return sendTeamCityRequest(url, true).then { response -> val data = JsonTreeParser.parse(response).jsonObject data.getArray("build").forEach { (it as JsonObject).getObject("revisions").getArray("revision").forEach { val currentBranch = (it as JsonObject).getPrimitive("vcsBranchName").content.removePrefix("refs/heads/") val currentProject = (it as JsonObject).getObject("vcs-root-instance").getPrimitive("name").content if (project == currentProject) { branch = currentBranch } return@forEach } } branch ?: error("No project $project can be found in build $buildId") } } private fun format(timeValue: Int): String = if (timeValue < 10) "0$timeValue" else "$timeValue" fun getBuildInformation(): Promise { return Promise.all(arrayOf(sendTeamCityRequest("$teamCityBuildUrl/number"), getBranchName("Kotlin Native"), sendTeamCityRequest("$teamCityBuildUrl/startDate"))).then { results -> val (buildNumber, branch, startTime) = results val currentTime = Date() val timeZone = currentTime.getTimezoneOffset() / -60 // Convert to hours. // Get finish time as current time, because buid on TeamCity isn't finished. val finishTime = "${format(currentTime.getUTCFullYear())}" + "${format(currentTime.getUTCMonth() + 1)}" + "${format(currentTime.getUTCDate())}" + "T${format(currentTime.getUTCHours())}" + "${format(currentTime.getUTCMinutes())}" + "${format(currentTime.getUTCSeconds())}" + "${if (timeZone > 0) "+" else "-"}${format(timeZone)}${format(0)}" TCBuildInfo(buildNumber, branch, startTime, finishTime) } } } // Get builds numbers in right order. internal fun orderedValues(values: List, buildElement: (T) -> String = { it -> it.toString() }, skipMilestones: Boolean = false) = values.sortedWith( compareBy({ buildElement(it).substringBefore(".").toInt() }, { buildElement(it).substringAfter(".").substringBefore("-").toDouble() }, { if (skipMilestones) 0 else if (buildElement(it).substringAfter("-").startsWith("M")) buildElement(it).substringAfter("M").substringBefore("-").toInt() else Int.MAX_VALUE }, { buildElement(it).substringAfterLast("-").toDouble() } ) ) // ElasticSearch connector for work with custom instance. internal val localHostElasticConnector = UrlNetworkConnector("http://localhost", 9200) // ElasticSearch connector for work with AWS instance. internal val awsElasticConnector = AWSNetworkConnector() internal val networkConnector = awsElasticConnector fun urlParameterToBaseFormat(value: dynamic) = value.toString().replace("_", " ") // Routing of requests to current server. fun router() { val express = require("express") val router = express.Router() val connector = ElasticSearchConnector(networkConnector) val benchmarksDispatcher = BenchmarksIndexesDispatcher(connector, "env.machine.os", listOf("Linux", "Mac OS X", "Windows 10") ) val goldenIndex = GoldenResultsIndex(connector) val buildInfoIndex = BuildInfoIndex(connector) router.get("/createMapping") { _, response -> buildInfoIndex.createMapping().then { _ -> response.sendStatus(200) }.catch { _ -> response.sendStatus(400) } } // Get consistent build information in cases of rerunning the same build. suspend fun getConsistentBuildInfo(buildInfoInstance: BuildInfo, reports: List, rerunNumber: Int = 1): BuildInfo { var currentBuildInfo = buildInfoInstance if (buildExists(currentBuildInfo, buildInfoIndex)) { // Check if benchmarks aren't repeated. val existingBecnhmarks = benchmarksDispatcher.getBenchmarksList(currentBuildInfo.buildNumber, currentBuildInfo.agentInfo).await() val benchmarksToRegister = reports.map { it.benchmarks.keys }.flatten() if (existingBecnhmarks.toTypedArray().intersect(benchmarksToRegister).isNotEmpty()) { // Build was rerun. val buildNumber = "${currentBuildInfo.buildNumber}.$rerunNumber" currentBuildInfo = BuildInfo(buildNumber, currentBuildInfo.startTime, currentBuildInfo.endTime, currentBuildInfo.commitsList, currentBuildInfo.branch, currentBuildInfo.agentInfo) return getConsistentBuildInfo(currentBuildInfo, reports, rerunNumber + 1) } } return currentBuildInfo } // Register build on Artifactory. router.post("/register") { request, response -> val register = BuildRegister.create(JSON.stringify(request.body)) // Get information from TeamCity. register.getBuildInformation().then { buildInfo -> register.sendTeamCityRequest(register.changesListUrl, true).then { changes -> val commitsList = CommitsList(JsonTreeParser.parse(changes)) // Get artifact. val content = if(register.fileWithResult.contains("/")) UrlNetworkConnector(artifactoryUrl).sendRequest(RequestMethod.GET, register.fileWithResult) else register.sendTeamCityRequest(register.teamCityArtifactsUrl) content.then { resultsContent -> launch { val reportData = JsonTreeParser.parse(resultsContent) val reports = if (reportData is JsonArray) { reportData.map { BenchmarksReport.create(it as JsonObject) } } else listOf(BenchmarksReport.create(reportData as JsonObject)) val goldenResultPromise = getGoldenResults(goldenIndex) val goldenResults = goldenResultPromise.await() // Register build information. var buildInfoInstance = getConsistentBuildInfo( BuildInfo(buildInfo.buildNumber, buildInfo.startTime, buildInfo.finishTime, commitsList, buildInfo.branch, reports[0].env.machine.os), reports ) if (register.bundleSize != null) { // Add bundle size. val bundleSizeBenchmark = BenchmarkResult("KotlinNative", BenchmarkResult.Status.PASSED, register.bundleSize.toDouble(), BenchmarkResult.Metric.BUNDLE_SIZE, 0.0, 1, 0) val bundleSizeReport = BenchmarksReport(reports[0].env, listOf(bundleSizeBenchmark), reports[0].compiler) bundleSizeReport.buildNumber = buildInfoInstance.buildNumber benchmarksDispatcher.insert(bundleSizeReport, reports[0].env.machine.os).then { _ -> println("[BUNDLE] Success insert ${buildInfoInstance.buildNumber}") }.catch { errorResponse -> println("Failed to insert data for build") println(errorResponse) } } val insertResults = reports.map { val benchmarksReport = SummaryBenchmarksReport(it).getBenchmarksReport() .normalizeBenchmarksSet(goldenResults) benchmarksReport.buildNumber = buildInfoInstance.buildNumber // Save results in database. benchmarksDispatcher.insert(benchmarksReport, benchmarksReport.env.machine.os) } if (!buildExists(buildInfoInstance, buildInfoIndex)) { buildInfoIndex.insert(buildInfoInstance).then { _ -> println("Success insert build information for ${buildInfoInstance.buildNumber}") }.catch { response.sendStatus(400) } } Promise.all(insertResults.toTypedArray()).then { _ -> response.sendStatus(200) }.catch { response.sendStatus(400) } } } } } } // Register golden results to normalize on Artifactory. router.post("/registerGolden", { request, response -> val goldenResultsInfo: GoldenResultsInfo = JSON.parse(JSON.stringify(request.body)) val goldenReport = goldenResultsInfo.toBenchmarksReport() goldenIndex.insert(goldenReport).then { _ -> response.sendStatus(200) }.catch { response.sendStatus(400) } }) // Get builds description with additional information. router.get("/buildsDesc/:target", { request, response -> CachableResponseDispatcher.getResponse(request, response) { success, reject -> val target = request.params.target.toString().replace('_', ' ') var branch: String? = null var type: String? = null var buildsCountToShow = 200 var beforeDate: String? = null var afterDate: String? = null if (request.query != undefined) { if (request.query.branch != undefined) { branch = request.query.branch } if (request.query.type != undefined) { type = request.query.type } if (request.query.count != undefined) { buildsCountToShow = request.query.count.toString().toInt() } if (request.query.before != undefined) { beforeDate = decodeURIComponent(request.query.before) } if (request.query.after != undefined) { afterDate = decodeURIComponent(request.query.after) } } getBuildsInfo(type, branch, target, buildsCountToShow, buildInfoIndex, beforeDate, afterDate) .then { buildsInfo -> val buildNumbers = buildsInfo.map { it.buildNumber } // Get number of failed benchmarks for each build. benchmarksDispatcher.getFailuresNumber(target, buildNumbers).then { failures -> success(orderedValues(buildsInfo, { it -> it.buildNumber }, branch == "master").map { Build(it.buildNumber, it.startTime, it.endTime, it.branch, it.commitsList.serializeFields(), failures[it.buildNumber] ?: 0) }) }.catch { errorResponse -> println("Error during getting failures numbers") println(errorResponse) reject() } }.catch { reject() } } }) // Get values of current metric. router.get("/metricValue/:target/:metric", { request, response -> CachableResponseDispatcher.getResponse(request, response) { success, reject -> val metric = request.params.metric val target = request.params.target.toString().replace('_', ' ') var samples: List = emptyList() var aggregation = "geomean" var normalize = false var branch: String? = null var type: String? = null var excludeNames: List = emptyList() var buildsCountToShow = 200 var beforeDate: String? = null var afterDate: String? = null // Parse parameters from request if it exists. if (request.query != undefined) { if (request.query.samples != undefined) { samples = request.query.samples.toString().split(",").map { it.trim() } } if (request.query.agr != undefined) { aggregation = request.query.agr.toString() } if (request.query.normalize != undefined) { normalize = true } if (request.query.branch != undefined) { branch = request.query.branch } if (request.query.type != undefined) { type = request.query.type } if (request.query.exclude != undefined) { excludeNames = request.query.exclude.toString().split(",").map { it.trim() } } if (request.query.count != undefined) { buildsCountToShow = request.query.count.toString().toInt() } if (request.query.before != undefined) { beforeDate = decodeURIComponent(request.query.before) } if (request.query.after != undefined) { afterDate = decodeURIComponent(request.query.after) } } getBuildsNumbers(type, branch, target, buildsCountToShow, buildInfoIndex, beforeDate, afterDate).then { buildNumbers -> if (aggregation == "geomean") { // Get geometric mean for samples. benchmarksDispatcher.getGeometricMean(metric, target, buildNumbers, normalize, excludeNames).then { geoMeansValues -> success(orderedValues(geoMeansValues, { it -> it.first }, branch == "master")) }.catch { errorResponse -> println("Error during getting geometric mean") println(errorResponse) reject() } } else { benchmarksDispatcher.getSamples(metric, target, samples, buildsCountToShow, buildNumbers, normalize) .then { geoMeansValues -> success(orderedValues(geoMeansValues, { it -> it.first }, branch == "master")) }.catch { println("Error during getting samples") reject() } } }.catch { println("Error during getting builds information") reject() } } }) // Get branches for [target]. router.get("/branches", { request, response -> CachableResponseDispatcher.getResponse(request, response) { success, reject -> distinctValues("branch", buildInfoIndex).then { results -> success(results) }.catch { errorMessage -> error(errorMessage.message ?: "Failed getting branches list.") reject() } } }) // Get build numbers for [target]. router.get("/buildsNumbers/:target", { request, response -> CachableResponseDispatcher.getResponse(request, response) { success, reject -> distinctValues("buildNumber", buildInfoIndex).then { results -> success(results) }.catch { errorMessage -> println(errorMessage.message ?: "Failed getting branches list.") reject() } } }) // Conert data and migrate it from Artifactory to DB. router.get("/migrate/:target", { request, response -> val target = urlParameterToBaseFormat(request.params.target) val targetPathName = target.replace(" ", "") var buildNumber: String? = null if (request.query != undefined) { if (request.query.buildNumber != undefined) { buildNumber = request.query.buildNumber buildNumber = request.query.buildNumber } } getBuildsInfoFromArtifactory(targetPathName).then { buildInfo -> launch { val buildsDescription = buildInfo.lines().drop(1) var shouldConvert = buildNumber?.let { false } ?: true val goldenResultPromise = getGoldenResults(goldenIndex) val goldenResults = goldenResultPromise.await() val buildsSet = mutableSetOf() buildsDescription.forEach { if (!it.isEmpty()) { val currentBuildNumber = it.substringBefore(',') if (!"\\d+(\\.\\d+)+(-M\\d)?-\\w+-\\d+(\\.\\d+)?".toRegex().matches(currentBuildNumber)) { error("Build number $currentBuildNumber differs from expected format. File with data for " + "target $target could be corrupted.") } if (!shouldConvert && buildNumber != null && buildNumber == currentBuildNumber) { shouldConvert = true } if (shouldConvert) { // Save data from Artifactory into database. val artifactoryUrlConnector = UrlNetworkConnector(artifactoryUrl) val fileName = "nativeReport.json" val accessFileUrl = "$targetPathName/$currentBuildNumber/$fileName" val extrenalFileName = if (target == "Linux") "externalReport.json" else "spaceFrameworkReport.json" val accessExternalFileUrl = "$targetPathName/$currentBuildNumber/$extrenalFileName" val infoParts = it.split(", ") if ((infoParts[3] == "master" || "eap" in currentBuildNumber || "release" in currentBuildNumber) && currentBuildNumber !in buildsSet) { try { buildsSet.add(currentBuildNumber) val jsonReport = artifactoryUrlConnector.sendRequest(RequestMethod.GET, accessFileUrl).await() var reports = convert(jsonReport, currentBuildNumber, target) val buildInfoRecord = BuildInfo(currentBuildNumber, infoParts[1], infoParts[2], CommitsList.parse(infoParts[4]), infoParts[3], target) val externalJsonReport = artifactoryUrlConnector.sendOptionalRequest(RequestMethod.GET, accessExternalFileUrl) .await() buildInfoIndex.insert(buildInfoRecord).then { _ -> println("[BUILD INFO] Success insert build number ${buildInfoRecord.buildNumber}") externalJsonReport?.let { var externalReports = convert(externalJsonReport.replace("circlet_iosX64", "SpaceFramework_iosX64"), currentBuildNumber, target) externalReports.forEach { externalReport -> val extrenalAdditionalReport = SummaryBenchmarksReport(externalReport) .getBenchmarksReport().normalizeBenchmarksSet(goldenResults) extrenalAdditionalReport.buildNumber = currentBuildNumber benchmarksDispatcher.insert(extrenalAdditionalReport, target).then { _ -> println("[External] Success insert ${buildInfoRecord.buildNumber}") }.catch { errorResponse -> println("Failed to insert data for build") println(errorResponse) } } } val bundleSize = if (infoParts[10] != "-") infoParts[10] else null if (bundleSize != null) { // Add bundle size. val bundleSizeBenchmark = BenchmarkResult("KotlinNative", BenchmarkResult.Status.PASSED, bundleSize.toDouble(), BenchmarkResult.Metric.BUNDLE_SIZE, 0.0, 1, 0) val bundleSizeReport = BenchmarksReport(reports[0].env, listOf(bundleSizeBenchmark), reports[0].compiler) bundleSizeReport.buildNumber = currentBuildNumber benchmarksDispatcher.insert(bundleSizeReport, target).then { _ -> println("[BUNDLE] Success insert ${buildInfoRecord.buildNumber}") }.catch { errorResponse -> println("Failed to insert data for build") println(errorResponse) } } reports.forEach { report -> val summaryReport = SummaryBenchmarksReport(report).getBenchmarksReport() .normalizeBenchmarksSet(goldenResults) summaryReport.buildNumber = currentBuildNumber // Save results in database. benchmarksDispatcher.insert(summaryReport, target).then { _ -> println("Success insert ${buildInfoRecord.buildNumber}") }.catch { errorResponse -> println("Failed to insert data for build") println(errorResponse.message) } } }.catch { errorResponse -> println("Failed to insert data for build") println(errorResponse) } } catch (e: Exception) { println(e) } } } } } } response.sendStatus(200) }.catch { response.sendStatus(400) } }) router.get("/delete/:target", { request, response -> val target = urlParameterToBaseFormat(request.params.target) var buildNumber: String? = null if (request.query != undefined) { if (request.query.buildNumber != undefined) { buildNumber = request.query.buildNumber } } benchmarksDispatcher.deleteBenchmarks(target, buildNumber).then { deleteBuildInfo(target, buildInfoIndex, buildNumber).then { response.sendStatus(200) }.catch { response.sendStatus(400) } }.catch { response.sendStatus(400) } }) // Get builds description with additional information. router.get("/unstable", { request, response -> CachableResponseDispatcher.getResponse(request, response) { success, reject -> getUnstableResults(goldenIndex).then { unstableBenchmarks -> success(unstableBenchmarks) }.catch { println("Error during getting unstable benchmarks") reject() } } }) router.get("/report/:target/:buildNumber", { request, response -> val target = urlParameterToBaseFormat(request.params.target) val buildNumber = request.params.buildNumber.toString() benchmarksDispatcher.getBenchmarksReports(buildNumber, target).then { reports -> response.send(reports.joinToString(", ", "[", "]")) }.catch { response.sendStatus(400) } }) router.get("/clear", { _, response -> CachableResponseDispatcher.clear() response.sendStatus(200) }) // Main page. router.get("/", { _, response -> response.render("index") }) return router } fun getBuildsInfoFromArtifactory(target: String): Promise { val buildsFileName = "buildsSummary.csv" val artifactoryBuildsDirectory = "builds" return UrlNetworkConnector(artifactoryUrl).sendRequest(RequestMethod.GET, "$artifactoryBuildsDirectory/$target/$buildsFileName") } fun BenchmarksReport.normalizeBenchmarksSet(dataForNormalization: Map>): BenchmarksReport { val resultBenchmarksList = benchmarks.map { benchmarksList -> benchmarksList.value.map { NormalizedMeanVarianceBenchmark(it.name, it.status, it.score, it.metric, it.runtimeInUs, it.repeat, it.warmup, (it as MeanVarianceBenchmark).variance, dataForNormalization[benchmarksList.key]?.get(0)?.score?.let { golden -> it.score / golden } ?: 0.0) } }.flatten() return BenchmarksReport(env, resultBenchmarksList, compiler) } ================================================ FILE: tools/performance-server/src/main/kotlin/utils/AsyncUtils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.utils import kotlin.coroutines.* import kotlin.js.Promise suspend fun Promise.await(): T = suspendCoroutine { cont -> then({ cont.resume(it) }, { cont.resumeWithException(it) }) } fun launch(context: CoroutineContext = EmptyCoroutineContext, block: suspend () -> Unit) = block.startCoroutine(Continuation(context) { result -> result.onFailure { exception -> throw exception } }) ================================================ FILE: tools/performance-server/src/main/kotlin-js/org/jetbrains/analyzer/Utils.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.analyzer import org.w3c.xhr.* import kotlin.browser.* import kotlin.js.* actual fun readFile(fileName: String): String { error("Reading from local file for JS isn't supported") } actual fun writeToFile(fileName: String, text: String) { error("Writing to local file for JS isn't supported") } actual fun Double.format(decimalNumber: Int): String = this.asDynamic().toFixed(decimalNumber) actual fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) error(lazyMessage) } actual fun sendGetRequest(url: String, user: String?, password: String?, followLocation: Boolean) : String { error("Unsupported") } ================================================ FILE: tools/performance-server/ui/build.gradle ================================================ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig buildscript { ext.rootBuildDirectory = file('../../..') apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle" apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle" repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } maven { url "http://dl.bintray.com/kotlin/kotlin-eap" } maven { url "http://dl.bintray.com/kotlin/kotlin-dev" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } repositories { maven { url 'https://cache-redirector.jetbrains.com/jcenter' } jcenter() maven { url kotlinCompilerRepo } maven { url buildKotlinCompilerRepo } maven { url "http://dl.bintray.com/kotlin/kotlin-eap" } maven { url "http://dl.bintray.com/kotlin/kotlin-dev" } } apply plugin: 'kotlin-multiplatform' kotlin { js { browser { binaries.executable() distribution { directory = new File("$projectDir/js/") } } } sourceSets { commonMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion" } kotlin.srcDir '../../benchmarks/shared/src' } jsMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlinVersion" } kotlin.srcDir 'src/main/kotlin' kotlin.srcDir '../shared/src/main/kotlin' kotlin.srcDir '../src/main/kotlin-js' } } } ================================================ FILE: tools/performance-server/ui/css/style.css ================================================ .chart { height: 400px; } .ct-legend { position: relative; z-index: 10; list-style: none; text-align: center; } .ct-legend li { position: relative; padding-left: 23px; margin-right: 10px; margin-bottom: 3px; cursor: pointer; display: inline-block; } .ct-legend li:before { width: 12px; height: 12px; position: absolute; left: 0; content: ''; border: 3px solid transparent; border-radius: 2px; } .ct-legend li.inactive:before { background: transparent; } .ct-legend.ct-legend-inside { position: absolute; top: 0; right: 0; } .ct-legend.ct-legend-inside li{ display: block; margin: 0; } .ct-legend .ct-series-0:before { background-color: #d70206; border-color: #d70206; } .ct-legend .ct-series-1:before { background-color: gold; border-color: gold; } .ct-legend .ct-series-2:before { background-color: limegreen; border-color: limegreen; } .ct-legend .ct-series-3:before { background-color: lightsalmon; border-color: lightsalmon; } .ct-legend .ct-series-4:before { background-color: mediumorchid; border-color: mediumorchid; } .ct-legend .ct-series-5:before { background-color: navy; border-color: navy; } .ct-legend .ct-series-6:before { background-color: darkcyan; border-color: darkcyan; } .ct-series-b .ct-line, .ct-series-b .ct-point { /* Set the colour of this series line */ stroke: gold; } .ct-series-c .ct-line, .ct-series-c .ct-point { /* Set the colour of this series line */ stroke: limegreen; } .ct-series-d .ct-line, .ct-series-d .ct-point { /* Set the colour of this series line */ stroke: lightsalmon; } .ct-series-e .ct-line, .ct-series-e .ct-point { /* Set the colour of this series line */ stroke: mediumorchid; } .ct-series-f .ct-line, .ct-series-f .ct-point { /* Set the colour of this series line */ stroke: navy; } .ct-series-g .ct-line, .ct-series-g .ct-point { /* Set the colour of this series line */ stroke: darkcyan; } .tooltip { pointer-events: none; } ================================================ FILE: tools/performance-server/ui/index.ejs ================================================ Benchmarks report

Highlighted build

Normalized execution time

Compile time

Normalized code size

Bundle size

================================================ FILE: tools/performance-server/ui/settings.gradle ================================================ ================================================ FILE: tools/performance-server/ui/src/main/kotlin/main.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import kotlin.browser.* import org.w3c.fetch.* import org.jetbrains.report.json.* import org.jetbrains.buildInfo.Build import kotlin.js.* import kotlin.math.ceil import org.w3c.dom.* // API for interop with JS library Chartist. external class ChartistPlugins { fun legend(data: dynamic): dynamic fun ctAxisTitle(data: dynamic): dynamic } external object Chartist { class Svg(form: String, parameters: dynamic, chartArea: String) val plugins: ChartistPlugins val Interpolation: dynamic fun Line(query: String, data: dynamic, options: dynamic): dynamic } data class Commit(val revision: String, val developer: String) fun sendGetRequest(url: String) = window.fetch(url, RequestInit("GET")).then { response -> if (!response.ok) error("Error during getting response from $url\n" + "${response}") else response.text() }.then { text -> text } // Get data for chart in needed format. fun getChartData(labels: List, valuesList: Collection>, classNames: Array? = null): dynamic { val chartData: dynamic = object {} chartData["labels"] = labels.toTypedArray() chartData["series"] = valuesList.mapIndexed { index, it -> val series: dynamic = object {} series["data"] = it.toTypedArray() classNames?.let { series["className"] = classNames[index] } series }.toTypedArray() return chartData } // Create object with options of chart. fun getChartOptions(samples: Array, yTitle: String, classNames: Array? = null): dynamic { val chartOptions: dynamic = object {} chartOptions["fullWidth"] = true val paddingObject: dynamic = object {} paddingObject["right"] = 40 chartOptions["chartPadding"] = paddingObject val axisXObject: dynamic = object {} axisXObject["offset"] = 40 axisXObject["labelInterpolationFnc"] = { value, index, labels -> val labelsCount = 20 val skipNumber = ceil((labels.length as Int).toDouble() / labelsCount).toInt() if (skipNumber > 1) { if (index % skipNumber == 0) value else null } else { value } } chartOptions["axisX"] = axisXObject val axisYObject: dynamic = object {} axisYObject["offset"] = 90 chartOptions["axisY"] = axisYObject val legendObject: dynamic = object {} legendObject["legendNames"] = samples classNames?.let { legendObject["classNames"] = classNames.sliceArray(0 until samples.size) } val titleObject: dynamic = object {} val axisYTitle: dynamic = object {} axisYTitle["axisTitle"] = yTitle axisYTitle["axisClass"] = "ct-axis-title" val titleOffset: dynamic = {} titleOffset["x"] = 15 titleOffset["y"] = 15 axisYTitle["offset"] = titleOffset axisYTitle["textAnchor"] = "middle" axisYTitle["flipTitle"] = true titleObject["axisY"] = axisYTitle val interpolationObject: dynamic = {} interpolationObject["fillHoles"] = true chartOptions["lineSmooth"] = Chartist.Interpolation.simple(interpolationObject) chartOptions["plugins"] = arrayOf(Chartist.plugins.legend(legendObject), Chartist.plugins.ctAxisTitle(titleObject)) return chartOptions } fun redirect(url: String) { window.location.href = url } // Set customizations rules for chart. fun customizeChart(chart: dynamic, chartContainer: String, jquerySelector: dynamic, builds: List, parameters: Map) { chart.on("draw", { data -> var element = data.element if (data.type == "point") { val pointSize = 12 val currentBuild = builds.get(data.index) currentBuild?.let { currentBuild -> // Higlight builds with failures. if (currentBuild.failuresNumber > 0) { val svgParameters: dynamic = object {} svgParameters["d"] = arrayOf("M", data.x, data.y - pointSize, "L", data.x - pointSize, data.y + pointSize / 2, "L", data.x + pointSize, data.y + pointSize / 2, "z").joinToString(" ") svgParameters["style"] = "fill:rgb(255,0,0);stroke-width:0" val triangle = Chartist.Svg("path", svgParameters, chartContainer) element = data.element.replace(triangle) } else if (currentBuild.buildNumber == parameters["build"]) { // Higlight choosen build. val svgParameters: dynamic = object {} svgParameters["x"] = data.x - pointSize / 2 svgParameters["y"] = data.y - pointSize / 2 svgParameters["height"] = pointSize svgParameters["width"] = pointSize svgParameters["style"] = "fill:rgb(0,0,255);stroke-width:0" val rectangle = Chartist.Svg("rect", svgParameters, "ct-point") element = data.element.replace(rectangle) } // Add tooltips. var shift = 1 var previousBuild: Build? = null while (previousBuild == null && data.index - shift >= 0) { previousBuild = builds.get(data.index - shift) shift++ } val linkToDetailedInfo = "https://kotlin-native-performance.labs.jb.gg/?report=" + "${currentBuild.buildNumber}:${parameters["target"]}" + "${previousBuild?.let { "&compareTo=${previousBuild.buildNumber}:${parameters["target"]}" } ?: ""}" val information = buildString { append("${currentBuild.buildNumber}
") append("Value: ${data.value.y.toFixed(4)}
") if (currentBuild.failuresNumber > 0) { append("failures: ${currentBuild.failuresNumber}
") } append("branch: ${currentBuild.branch}
") append("date: ${currentBuild.date}
") append("time: ${currentBuild.formattedStartTime}-${currentBuild.formattedFinishTime}
") append("Commits:
") val commitsList = (JsonTreeParser.parse("{${currentBuild.commits}}") as JsonObject).getArray("commits").map { Commit( (it as JsonObject).getPrimitive("revision").content, (it as JsonObject).getPrimitive("developer").content ) } val commits = if (commitsList.size > 3) commitsList.slice(0..2) else commitsList commits.forEach { append("${it.revision.substring(0, 7)} by ${it.developer}
") } if (commitsList.size > 3) { append("...") } } element._node.setAttribute("title", information) element._node.setAttribute("data-chart-tooltip", chartContainer) element._node.addEventListener("click", { redirect(linkToDetailedInfo) }) } } }) chart.on("created", { val currentChart = jquerySelector val parameters: dynamic = object {} parameters["selector"] = "[data-chart-tooltip=\"$chartContainer\"]" parameters["container"] = "#$chartContainer" parameters["html"] = true currentChart.tooltip(parameters) }) } var buildsNumberToShow: Int = 200 var beforeDate: String? = null var afterDate: String? = null external fun decodeURIComponent(url: String): String external fun encodeURIComponent(url: String): String fun getDatesComponents() = "${beforeDate?.let {"&before=${encodeURIComponent(it)}"} ?: ""}" + "${afterDate?.let {"&after=${encodeURIComponent(it)}"} ?: ""}" fun main(args: Array) { val serverUrl = "https://kotlin-native-perf-summary.labs.jb.gg" val zoomRatio = 2 // Get parameters from request. val url = window.location.href val parametersPart = url.substringAfter("?").split('&') val parameters = mutableMapOf("target" to "Linux", "type" to "dev", "build" to "", "branch" to "master") parametersPart.forEach { val parsedParameter = it.split("=", limit = 2) if (parsedParameter.size == 2) { val (key, value) = parsedParameter parameters[key] = value } } buildsNumberToShow = parameters["count"]?.toInt() ?: buildsNumberToShow beforeDate = parameters["before"]?.let { decodeURIComponent(it) } afterDate = parameters["after"]?.let { decodeURIComponent(it) } // Get branches. val branchesUrl = "$serverUrl/branches" sendGetRequest(branchesUrl).then { response -> val branches: Array = JSON.parse(response) // Add release branches to selector. branches.filter { it != "master" }.forEach { if ("v(\\d|\\.)+(-M\\d)?-fixes".toRegex().matches(it)) { val option = Option(it, it) js("$('#inputGroupBranch')").append(js("$(option)")) } } document.querySelector("#inputGroupBranch [value=\"${parameters["branch"]}\"]")?.setAttribute("selected", "true") } // Fill autocomplete list with build numbers. val buildsNumbersUrl = "$serverUrl/buildsNumbers/${parameters["target"]}" sendGetRequest(buildsNumbersUrl).then { response -> val buildsNumbers: Array = JSON.parse(response) val autocompleteParameters: dynamic = object {} autocompleteParameters["lookup"] = buildsNumbers autocompleteParameters["onSelect"] = { suggestion -> if (suggestion.value != parameters["build"]) { val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}" + "${if ((suggestion.value as String).isEmpty()) "" else "&build=${suggestion.value}"}&count=$buildsNumberToShow" + getDatesComponents() window.location.href = newLink } } js("$( \"#highligted_build\" )").autocomplete(autocompleteParameters) js("$('#highligted_build')").change({ value -> val newValue = js("$(this).val()").toString() if (newValue.isEmpty() || newValue in buildsNumbers) { val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}" + "${if (newValue.isEmpty()) "" else "&build=$newValue"}&count=$buildsNumberToShow" + getDatesComponents() window.location.href = newLink } }) } // Change inputs values connected with parameters and add events listeners. document.querySelector("#inputGroupTarget [value=\"${parameters["target"]}\"]")?.setAttribute("selected", "true") document.querySelector("#inputGroupBuildType [value=\"${parameters["type"]}\"]")?.setAttribute("selected", "true") (document.getElementById("highligted_build") as HTMLInputElement).value = parameters["build"]!! // Add onChange events for fields. // Don't use AJAX to have opportunity to share results with simple links. js("$('#inputGroupTarget')").change({ val newValue = js("$(this).val()") if (newValue != parameters["target"]) { val newLink = "http://${window.location.host}/?target=$newValue&type=${parameters["type"]}&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" window.location.href = newLink } }) js("$('#inputGroupBuildType')").change({ val newValue = js("$(this).val()") if (newValue != parameters["type"]) { val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=$newValue&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" window.location.href = newLink } }) js("$('#inputGroupBranch')").change({ val newValue = js("$(this).val()") if (newValue != parameters["branch"]) { val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=$newValue" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" window.location.href = newLink } }) val platformSpecificBenchs = if (parameters["target"] == "Mac_OS_X") ",FrameworkBenchmarksAnalyzer,SpaceFramework_iosX64" else if (parameters["target"] == "Linux") ",kotlinx.coroutines" else "" var execData = listOf() to listOf>() var compileData = listOf() to listOf>() var codeSizeData = listOf() to listOf>() var bundleSizeData = listOf() to listOf>() val sizeClassNames = arrayOf("ct-series-e", "ct-series-f", "ct-series-g") // Draw charts. var execChart: dynamic = null var compileChart: dynamic = null var codeSizeChart: dynamic = null var bundleSizeChart: dynamic = null val descriptionUrl = "$serverUrl/buildsDesc/${parameters["target"]}?type=${parameters["type"]}" + "${if (parameters["branch"] != "all") "&branch=${parameters["branch"]}" else ""}&count=$buildsNumberToShow" + getDatesComponents() val metricUrl = "$serverUrl/metricValue/${parameters["target"]}/" val unstableBenchmarksPromise = sendGetRequest("$serverUrl/unstable").then { response -> val unstableList = response as String val data = JsonTreeParser.parse(unstableList) if (data !is JsonArray) { error("Response is expected to be an array.") } data.jsonArray.map { (it as JsonPrimitive).content } } // Get builds description. val buildsInfoPromise = sendGetRequest(descriptionUrl).then { response -> val buildsInfo = response as String val data = JsonTreeParser.parse(buildsInfo) if (data !is JsonArray) { error("Response is expected to be an array.") } data.jsonArray.map { val element = it as JsonElement if (element.isNull) null else Build.create(element as JsonObject) } } unstableBenchmarksPromise.then { unstableBenchmarks -> // Collect information for charts library. val valuesToShow = mapOf("EXECUTION_TIME" to listOf(mapOf( "normalize" to "true" ), mapOf( "normalize" to "true", "exclude" to unstableBenchmarks.joinToString(",") )), "COMPILE_TIME" to listOf(mapOf( "samples" to "HelloWorld,Videoplayer$platformSpecificBenchs", "agr" to "samples" )), "CODE_SIZE" to listOf(mapOf( "normalize" to "true", "exclude" to if (parameters["target"] == "Linux") "kotlinx.coroutines" else if (parameters["target"] == "Mac_OS_X") "SpaceFramework_iosX64" else "" ), if (platformSpecificBenchs.isNotEmpty()) mapOf( "normalize" to "true", "agr" to "samples", "samples" to platformSpecificBenchs.removePrefix(",") ) else null).filterNotNull(), "BUNDLE_SIZE" to listOf(mapOf("samples" to "KotlinNative", "agr" to "samples")) ) // Send requests to get all needed metric values. valuesToShow.map { (metric, listOfSettings) -> val resultValues = listOfSettings.map { settings -> val getParameters = with(StringBuilder()) { if (settings.isNotEmpty()) { append("?") } var prefix = "" settings.forEach { (key, value) -> if (value.isNotEmpty()) { append("$prefix$key=$value") prefix = "&" } } toString() } val branchParameter = if (parameters["branch"] != "all") (if (getParameters.isEmpty()) "?" else "&") + "branch=${parameters["branch"]}" else "" val url = "$metricUrl$metric$getParameters$branchParameter${ if (parameters["type"] != "all") (if (getParameters.isEmpty() && branchParameter.isEmpty()) "?" else "&") + "type=${parameters["type"]}" else "" }&count=$buildsNumberToShow${getDatesComponents()}" sendGetRequest(url) }.toTypedArray() // Get metrics values for charts. Promise.all(resultValues).then { responses -> val valuesList = responses.map { response -> val results = (JsonTreeParser.parse(response) as JsonArray).map { (it as JsonObject).getPrimitive("first").content to it.getArray("second").map { (it as JsonPrimitive).doubleOrNull } } val labels = results.map { it.first } val values = results[0]?.second?.size?.let { (0..it - 1).map { i -> results.map { it.second[i] } } } ?: emptyList() labels to values } val labels = valuesList[0].first val values = valuesList.map { it.second }.reduce { acc, valuesPart -> acc + valuesPart } when (metric) { // Update chart with gotten data. "COMPILE_TIME" -> { compileData = labels to values.map { it.map { it?.let { it / 1000 } } } compileChart = Chartist.Line("#compile_chart", getChartData(labels, compileData.second), getChartOptions(valuesToShow["COMPILE_TIME"]!![0]!!["samples"]!!.split(',').toTypedArray(), "Time, milliseconds")) buildsInfoPromise.then { builds -> customizeChart(compileChart, "compile_chart", js("$(\"#compile_chart\")"), builds, parameters) compileChart.update(getChartData(compileData.first, compileData.second)) } } "EXECUTION_TIME" -> { execData = labels to values execChart = Chartist.Line("#exec_chart", getChartData(labels, execData.second), getChartOptions(arrayOf("Geometric Mean (All)", "Geometric mean (Stable)"), "Normalized time")) buildsInfoPromise.then { builds -> customizeChart(execChart, "exec_chart", js("$(\"#exec_chart\")"), builds, parameters) execChart.update(getChartData(execData.first, execData.second)) } } "CODE_SIZE" -> { codeSizeData = labels to values codeSizeChart = Chartist.Line("#codesize_chart", getChartData(labels, codeSizeData.second), getChartOptions(arrayOf("Geometric Mean") + platformSpecificBenchs.split(',') .filter { it.isNotEmpty() }, "Normalized size", arrayOf("ct-series-4", "ct-series-5", "ct-series-6"))) buildsInfoPromise.then { builds -> customizeChart(codeSizeChart, "codesize_chart", js("$(\"#codesize_chart\")"), builds, parameters) codeSizeChart.update(getChartData(codeSizeData.first, codeSizeData.second, sizeClassNames)) } } "BUNDLE_SIZE" -> { bundleSizeData = labels to values.map { it.map { it?.let { it.toInt() / 1024 / 1024 } } } bundleSizeChart = Chartist.Line("#bundlesize_chart", getChartData(labels, bundleSizeData.second, sizeClassNames), getChartOptions(arrayOf("Bundle size"), "Size, MB", arrayOf("ct-series-4"))) buildsInfoPromise.then { builds -> customizeChart(bundleSizeChart, "bundlesize_chart", js("$(\"#bundlesize_chart\")"), builds, parameters) bundleSizeChart.update(getChartData(bundleSizeData.first, bundleSizeData.second, sizeClassNames)) } } else -> error("No chart for metric $metric") } true } } } // Update all charts with using same data. val updateAllCharts: () -> Unit = { execChart.update(getChartData(execData.first, execData.second)) compileChart.update(getChartData(compileData.first, compileData.second)) codeSizeChart.update(getChartData(codeSizeData.first, codeSizeData.second, sizeClassNames)) bundleSizeChart.update(getChartData(bundleSizeData.first, bundleSizeData.second, sizeClassNames)) } js("$('#plusBtn')").click({ buildsNumberToShow = if (buildsNumberToShow / zoomRatio > zoomRatio) { buildsNumberToShow / zoomRatio } else { buildsNumberToShow } val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" + getDatesComponents() window.location.href = newLink Unit }) js("$('#minusBtn')").click({ buildsNumberToShow = buildsNumberToShow * zoomRatio val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" + getDatesComponents() window.location.href = newLink Unit }) js("$('#prevBtn')").click({ buildsInfoPromise.then { builds -> beforeDate = builds.firstOrNull()?.startTime afterDate = null val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" + "${beforeDate?.let {"&before=${encodeURIComponent(it)}"} ?: ""}" window.location.href = newLink } }) js("$('#nextBtn')").click({ buildsInfoPromise.then { builds -> beforeDate = null afterDate = builds.lastOrNull()?.startTime val newLink = "http://${window.location.host}/?target=${parameters["target"]}&type=${parameters["type"]}&branch=${parameters["branch"]}" + "${if (parameters["build"]!!.isEmpty()) "" else "&build=${parameters["build"]}"}&count=$buildsNumberToShow" + "${afterDate?.let {"&after=${encodeURIComponent(it)}"} ?: ""}" window.location.href = newLink } }) // Auto reload. parameters["refresh"]?.let { // Set event. window.setInterval({ window.location.reload() }, it.toInt() * 1000) } } ================================================ FILE: tools/qemu/Dockerfile ================================================ FROM ubuntu:20.04 ENV TZ=Europe/Moscow RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN apt-get update && apt-get upgrade -y RUN apt-get install -y build-essential git gcc pkg-config glib-2.0 libglib2.0-dev libsdl1.2-dev libaio-dev libcap-dev libattr1-dev libpixman-1-dev RUN git clone --branch v5.1.0 --depth 1 git://git.qemu.org/qemu.git && \ cd qemu && \ git checkout d0ed6a69d399ae193959225cdeaa9382746c91cc && \ git submodule update --init --recursive WORKDIR /qemu COPY build.sh . ENV OUTPUT_DIR="/output" ENTRYPOINT "/bin/bash" "build.sh" ${OUTPUT_DIR} ================================================ FILE: tools/qemu/build.sh ================================================ #!/bin/bash set -eou pipefail INSTALL_PATH=$1 QEMU_VERSION=5.1.0 DEPENDENCY_VERSION=2 function build_qemu() { mkdir build ./configure \ --prefix="$PWD/build" \ --static \ --disable-debug-info \ --disable-werror \ --disable-system \ --enable-linux-user \ make -j"$(nproc)" make install } function build_archives() { cd build/bin for f in qemu-* ; do DEPENDENCY_NAME="$f-static-$QEMU_VERSION-linux-$DEPENDENCY_VERSION" mkdir -p $DEPENDENCY_NAME mv $f $DEPENDENCY_NAME/$f tar -czvf $INSTALL_PATH/"$DEPENDENCY_NAME.tar.gz" "$DEPENDENCY_NAME" done } build_qemu build_archives ================================================ FILE: tools/qemu/create_image.sh ================================================ #!/bin/sh docker build -t kotlin-qemu-builder . ================================================ FILE: tools/qemu/run_container.sh ================================================ #!/bin/bash set -eou pipefail CONTAINER_NAME=kotlin-qemu-builder IMAGE_NAME=kotlin-qemu-builder docker ps -a | grep $CONTAINER_NAME > /dev/null \ && docker stop $CONTAINER_NAME 1> /dev/null \ && docker rm $CONTAINER_NAME 1> /dev/null docker run -it -v "$PWD"/out:/output --name=$CONTAINER_NAME $IMAGE_NAME ================================================ FILE: tools/scripts/repack_bundles.py ================================================ #!/usr/bin/python import sys import os import os.path import shutil if len(sys.argv) != 2: print('Usage: ' + sys.argv[0] + ' ') sys.exit(0) kotlinVersion = sys.argv[1] print('Repacking bundles for Kotlin/Native version ' + kotlinVersion) bundles = [f for f in os.listdir('.') if f.startswith('kotlin-native-prebuilt-') and (f.endswith('.tar.gz') or f.endswith('.zip')) and os.path.isfile(f)] print('Found ' + str(len(bundles)) + ' bundle files to repack: ' + ', '.join(bundles)) for bundle in bundles: print('') print('Unpacking ' + bundle) unpackCommand = 'unzip -qq' if bundle.endswith('.zip') else 'tar -xzf' os.system(unpackCommand + ' ' + bundle) extractedDir = bundle.rstrip('.tar.gz').rstrip('.zip') renamedDir = extractedDir.replace('-prebuilt-', '-') print('Renaming ' + extractedDir + ' to ' + renamedDir) os.rename(extractedDir, renamedDir) repackedBundle = renamedDir + ('.zip' if bundle.endswith('.zip') else '.tar.gz') print('Packing ' + repackedBundle) packCommand = 'zip -qq -r' if bundle.endswith('.zip') else 'COPYFILE_DISABLE=true tar -czf' os.system(packCommand + ' ' + repackedBundle + ' ' + renamedDir) shutil.rmtree(renamedDir) print('Calculating SHA256') shaCommand = 'shasum -a 256' os.system(shaCommand + ' ' + repackedBundle + ' > ' + repackedBundle + '.sha256') print('') print('Done.') ================================================ FILE: tools/scripts/update_apple_frameworks.sh ================================================ #! /bin/bash # This script scans Xcode directores for unknown frameworks # and tries to add them as Kotlin/Native def files. # # Note that some frameworks are unsupported (e.g. swift-only) and marked as .disabled. # Others may be supported and manual adjustment required (.attention_required). # Don't consider this script as a fully automatic solution. It tries its best # to identify unsupported frameworks correctly, but the result still should be validated. # # jq is required to run the script. It can be installed via `brew install jq`. # # Args: # 1. Platform name: ios, tvos, osx or watchos # 2. Path to Kotlin/Native sources. set -e NATIVE_SRCDIR=$2 case $1 in tvos*) DEV_SDK=$(xcrun --show-sdk-path --sdk appletvos) SIM_SDK=$(xcrun --show-sdk-path --sdk appletvsimulator) OS_NAME="tvOS" DEVICES=("tvos_arm64") SIMULATORS=("tvos_x64") ;; ios*) DEV_SDK=$(xcrun --show-sdk-path --sdk iphoneos) SIM_SDK=$(xcrun --show-sdk-path --sdk iphonesimulator) OS_NAME="iOS" DEVICES=("ios_arm32" "ios_arm64") SIMULATORS=("ios_x64") ;; watchos*) DEV_SDK=$(xcrun --show-sdk-path --sdk watchos) SIM_SDK=$(xcrun --show-sdk-path --sdk watchsimulator) OS_NAME="watchOS" DEVICES=("watchos_arm32" "watchos_arm64") SIMULATORS=("watchos_i386") ;; osx*) DEV_SDK=$(xcrun --show-sdk-path) SIM_SDK=$DEV_SDK OS_NAME="macOS" ;; *) echo "Expected one of: osx ios watchos tvos. Got: $1" exit 1 esac DEFS=$NATIVE_SRCDIR/platformLibs/src/platform/$1 FRAMEWORKS_DEV=$DEV_SDK/System/Library/Frameworks FRAMEWORKS_SIM=$SIM_SDK/System/Library/Frameworks DEFS_FILE=$(mktemp) FRAMEWORKS_DEV_FILE=$(mktemp) FRAMEWORKS_SIM_FILE=$(mktemp) FRAMEWORKS_COMMON_FILE=$(mktemp) FRAMEWORKS_DEV_ONLY_FILE=$(mktemp) FRAMEWORKS_SIM_ONLY_FILE=$(mktemp) ls $DEFS | grep .def | cut -d '.' -f 1 > $DEFS_FILE ls $FRAMEWORKS_DEV | grep .framework | cut -d '.' -f 1 > $FRAMEWORKS_DEV_FILE ls $FRAMEWORKS_SIM | grep .framework | cut -d '.' -f 1 > $FRAMEWORKS_SIM_FILE comm -12 $FRAMEWORKS_DEV_FILE $FRAMEWORKS_SIM_FILE > $FRAMEWORKS_COMMON_FILE comm -13 $FRAMEWORKS_DEV_FILE $FRAMEWORKS_SIM_FILE > $FRAMEWORKS_SIM_ONLY_FILE comm -23 $FRAMEWORKS_DEV_FILE $FRAMEWORKS_SIM_FILE > $FRAMEWORKS_DEV_ONLY_FILE ABSENT_COMMON=$(comm -13 $DEFS_FILE $FRAMEWORKS_COMMON_FILE) ABSENT_SIM=$(comm -13 $DEFS_FILE $FRAMEWORKS_SIM_ONLY_FILE) ABSENT_DEV=$(comm -13 $DEFS_FILE $FRAMEWORKS_DEV_ONLY_FILE) rm $DEFS_FILE rm $FRAMEWORKS_DEV_FILE rm $FRAMEWORKS_SIM_FILE rm $FRAMEWORKS_COMMON_FILE rm $FRAMEWORKS_DEV_ONLY_FILE rm $FRAMEWORKS_SIM_ONLY_FILE AVAILABLE=() AVAILABLE_ON_DEV=() AVAILABLE_ON_SIM=() UNAVAILABLE=() SWIFT_ONLY=() DRIVER_KIT=() OS_UNSUPPORTED=() JSON=$(mktemp) # Use information about framework on developer.apple.com to put it into # appropriate bucket. function classify { FRAMEWORK_NAME=$1 KIND=$2 URL=https://developer.apple.com/tutorials/data/documentation # Try to force Objective-C documentation. Swift is used by default. STATUS=$(curl -s -o $JSON -w "%{http_code}" "$URL/$FRAMEWORK_NAME.json?language=objc") # Some old frameworks don't have a documentation page. if [[ $STATUS -ne 200 ]] then UNAVAILABLE+=($FRAMEWORK_NAME) return fi # DriverKit is C++. Drop it. if [[ $(cat $JSON | jq '.metadata.platforms[] | .name' | grep DriverKit) ]] then DRIVER_KIT+=($FRAMEWORK_NAME) return fi # Sometimes framework is present in SDK directory, but actually it isn't supported on # current OS. if [[ ! $(cat $JSON | jq '.metadata.platforms[] | .name' | grep $OS_NAME) ]] then OS_UNSUPPORTED+=($FRAMEWORK_NAME) return fi LANG=$(cat $JSON | jq '.identifier.interfaceLanguage' | grep swift || true) if [[ $LANG = \"swift\" ]] then SWIFT_ONLY+=($FRAMEWORK_NAME) return fi case $KIND in device*) AVAILABLE_ON_DEV+=($FRAMEWORK_NAME) ;; simulator*) AVAILABLE_ON_SIM+=($FRAMEWORK_NAME) ;; common*) AVAILABLE+=($FRAMEWORK_NAME) ;; esac } for framework in $ABSENT_COMMON do classify $framework common done for framework in $ABSENT_DEV do classify $framework device done for framework in $ABSENT_SIM do classify $framework simulator done rm $JSON PLATFORM_LIBS=$NATIVE_SRCDIR/platformLibs/src/platform/$1 function create_def_content { FRAMEWORK=$1 DEF_FILE=$2 echo "language = Objective-C" >> $DEF_FILE echo "package = platform.$FRAMEWORK" >> $DEF_FILE case $3 in devices*) TARGETS=("${DEVICES[@]}") ;; simulators*) TARGETS=("${SIMULATORS[@]}") ;; *) TARGETS=("") ;; esac for target in "${TARGETS[@]}" do if [[ -z "$target" ]] then SUFFIX="" else SUFFIX=".$target" fi echo "" >> $DEF_FILE echo "modules$SUFFIX = $FRAMEWORK" >> $DEF_FILE echo "compilerOpts$SUFFIX = -framework $FRAMEWORK" >> $DEF_FILE echo "linkerOpts$SUFFIX = -framework $FRAMEWORK" >> $DEF_FILE done } function create_def { FRAMEWORK=$1 TARGETS=$2 DEF_FILE=$PLATFORM_LIBS/$FRAMEWORK.def touch $DEF_FILE create_def_content $FRAMEWORK $DEF_FILE $TARGETS echo "Created $DEF_FILE" } # Creates def file with additional suffix # and adds an explanation comment. function create_disabled { FRAMEWORK=$1 REASON=$2 EXTENSION=$3 TARGETS=$4 DEF_FILE=$PLATFORM_LIBS/$FRAMEWORK.def.$EXTENSION touch $DEF_FILE create_def_content $FRAMEWORK $DEF_FILE $TARGETS echo "#Disabled: $REASON" >> $DEF_FILE echo "Created $DEF_FILE" } if [ ${#AVAILABLE[@]} -ne 0 ] then echo "New frameworks added." fi for framework in "${AVAILABLE[@]}" do if [[ -d $DEV_SDK/System/Library/Frameworks/$framework.framework/Modules ]] then create_def $framework else create_disabled $framework "Framework without module" attention_required fi done if [ ${#AVAILABLE_ON_SIM[@]} -ne 0 ] then echo "The following frameworks are available only for simulators." fi for framework in "${AVAILABLE_ON_SIM[@]}" do create_disabled $framework "Check that framework is not available for devices" attention_required simulators done if [ ${#AVAILABLE_ON_DEV[@]} -ne 0 ] then echo "The following frameworks are available only for devices." fi for framework in "${AVAILABLE_ON_DEV[@]}" do create_disabled $framework "Check that framework is not available for simulators" attention_required devices done if [ ${#UNAVAILABLE[@]} -ne 0 ] then echo "Documentation for the following frameworks is not directly accessible." echo "They may be deprecated or available by different name." echo "For example, AppClip is accessed as app_clips ¯\_(ツ)_/¯." fi for framework in "${UNAVAILABLE[@]}" do create_disabled $framework "Unavailable" attention_required done if [ ${#SWIFT_ONLY[@]} -ne 0 ] then echo "The following frameworks doesn't provide Objective-C API." fi for framework in "${SWIFT_ONLY[@]}" do create_disabled $framework "Swift-only framework" disabled done if [ ${#DRIVER_KIT[@]} -ne 0 ] then echo "The following frameworks are from DriverKit." fi for framework in "${DRIVER_KIT[@]}" do create_disabled $framework "part of DriverKit" disabled done if [ ${#OS_UNSUPPORTED[@]} -ne 0 ] then echo "The following frameworks are not officially provided for $1." fi for framework in "${OS_UNSUPPORTED[@]}" do create_disabled $framework "Not officially available for $1" disabled done ================================================ FILE: tools/scripts/update_xcode.sh ================================================ #!/usr/bin/env bash set -e # "brew install coreutils" for grealpath. KONAN_TOOLCHAIN_VERSION=xcode_12_2 SDKS="macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator" TARBALL_macosx=target-sysroot-$KONAN_TOOLCHAIN_VERSION-macos_x64 TARBALL_iphoneos=target-sysroot-$KONAN_TOOLCHAIN_VERSION-ios_arm64 TARBALL_iphonesimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-ios_x64 TARBALL_appletvos=target-sysroot-$KONAN_TOOLCHAIN_VERSION-tvos_arm64 TARBALL_appletvsimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-tvos_x64 TARBALL_watchos=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_arm32 TARBALL_watchsimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_x86 TARBALL_xcode=target-toolchain-$KONAN_TOOLCHAIN_VERSION-macos_x64 TARBALL_xcode_addon=xcode-addon-$KONAN_TOOLCHAIN_VERSION-macos_x64 OUT=`pwd` for s in $SDKS; do p=`xcrun --sdk $s --show-sdk-path` p=`grealpath $p` tarball_var=TARBALL_${s} tarball=${!tarball_var} echo "Packing SDK $s as $OUT/$tarball.tar.gz..." $SHELL -c "tar czf $OUT/$tarball.tar.gz -C $p -s '/^\./$tarball/HS' ." done t=`xcrun -f ld` t=`dirname $t` t=`grealpath $t/../..` tarball=$TARBALL_xcode echo "Packing toolchain $OUT/$tarball.tar.gz..." $SHELL -c "tar czf $OUT/$tarball.tar.gz -C $t -s '/^\./$tarball/HS' ." t=`xcrun -f bitcode-build-tool` t=`dirname $t` t=`grealpath $t/..` tarball=$TARBALL_xcode_addon echo "Packing additional tools $OUT/$tarball.tar.gz..." $SHELL -c "tar czf $OUT/$tarball.tar.gz -C $t -s '/^\./$tarball/HS' ." ================================================ FILE: tools/scripts/update_zephyr.sh ================================================ #!/usr/bin/env bash KONAN_TOOLCHAIN_VERSION=1 TARBALL_zephyr_arm=target-sysroot-$KONAN_TOOLCHAIN_VERSION-zephyr-arm OUT=`pwd` if [ -z "ZEPHYR_SDK_INSTALL_DIR" ]; then echo "Using default Zephyr SDK install location" export ZEPHYR_SDK_INSTALL_DIR="/opt/zephyr-sdk" fi sdk=armv5-zephyr-eabi p=$ZEPHYR_SDK_INSTALL_DIR/sysroots/$sdk/usr echo "Packing SDK $sdk as $OUT/$TARBALL_zephyr_arm.tar.gz..." tar -czvf $OUT/$TARBALL_zephyr_arm.tar.gz -C $p . ================================================ FILE: tools/toolchain_builder/Dockerfile ================================================ # We might want to switch to alpine, but it is not stable enough yet. FROM ubuntu:14.04 ENV TZ=Europe/Moscow RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # Install crosstool-ng deps. RUN apt-get update RUN apt-get install -y curl gcc git g++ gperf bison flex texinfo help2man make libncurses5-dev \ python3-dev autoconf automake libtool gawk wget bzip2 xz-utils unzip \ patch libstdc++6 rsync # Put a fix for strip. COPY patches/github_pull_1244.patch . # Install crosstool-ng. RUN git clone --branch crosstool-ng-1.24.0 --depth 1 https://github.com/crosstool-ng/crosstool-ng.git && \ cd crosstool-ng && \ git checkout b2151f1dba2b20c310adfe7198e461ec4469172b && \ git apply ../github_pull_1244.patch && \ ./bootstrap && ./configure && make && make install && \ cd .. && rm -rf crosstool-ng # Create a user. ARG USERNAME=ct RUN groupadd -g 1000 $USERNAME RUN useradd -r -u 1000 --create-home -g $USERNAME $USERNAME USER $USERNAME WORKDIR /home/$USERNAME # Download zlib sources. RUN curl -LO https://zlib.net/zlib-1.2.11.tar.gz && \ tar -xf zlib-1.2.11.tar.gz && \ rm zlib-1.2.11.tar.gz # Save crosstool-ng config files. COPY toolchains toolchains # Used by crosstool-ng. RUN mkdir src ENV TARGET=x86_64-unknown-linux-gnu ENV VERSION=gcc-8.3.0-glibc-2.19-kernel-4.9 ENV TOOLCHAIN_VERSION_SUFFIX="" # Add entry point. COPY build_toolchain.sh . ENTRYPOINT "/bin/bash" "build_toolchain.sh" ${TARGET} ${VERSION} ${TOOLCHAIN_VERSION_SUFFIX} ================================================ FILE: tools/toolchain_builder/README.md ================================================ # Kotlin/Native toolchains builder This directory contains a set of scripts and configuration files that allow one to build the same toolchain that is used by Kotlin/Native. ### System requirements * Docker ### Usage 1. First, you need to build a Docker image with crosstool-ng inside. Use `create_image.sh` for it. 2. Now you can build an actual toolchain. To pick one, take a look inside `toolchains` folder. It is organized as `$TARGET/$VERSION`. Then run `./run_container.sh $TARGET $VERSION $TOOLCHAIN_VERSION_SUFFIX`. Building a toolchain might take a while (~17 minutes on Ryzen 5 3600). Once ready, an archive will be placed in `artifacts` folder. `$TOOLCHAIN_VERSION_SUFFIX` is an optional argument that adds suffix to the end of toolchain name. ### Example ```bash ./create_image.sh && ./run_container.sh aarch64-unknown-linux-gnu gcc-8.3.0-glibc-2.25-kernel-4.9 ``` ### Notes Check that Docker can write to `artifacts` directory (where `build_toolchains.sh` places archives). ================================================ FILE: tools/toolchain_builder/build_toolchain.sh ================================================ #!/bin/bash set -eou pipefail TARGET=$1 VERSION=$2 TOOLCHAIN_VERSION_SUFFIX=$3 HOME=/home/ct ZLIB_VERSION=1.2.11 build_toolchain() { mkdir $HOME/build-"$TARGET" cd $HOME/build-"$TARGET" cp $HOME/toolchains/"$TARGET"/"$VERSION".config .config ct-ng build cd .. } build_zlib() { TOOLCHAINS_PATH=$HOME/x-tools INSTALL_PATH=$TOOLCHAINS_PATH/$TARGET/$TARGET/sysroot/usr TOOLCHAIN_BIN_PREFIX=$TOOLCHAINS_PATH/$TARGET/bin/$TARGET cd $HOME/zlib-$ZLIB_VERSION CHOST=$TARGET \ CC=$TOOLCHAIN_BIN_PREFIX-gcc \ AR=$TOOLCHAIN_BIN_PREFIX-ar \ RANLIB=$TOOLCHAIN_BIN_PREFIX-ranlib \ ./configure \ --prefix="$INSTALL_PATH" make && make install } build_archive() { cd $HOME/x-tools if [ -z "$TOOLCHAIN_VERSION_SUFFIX" ] then FULL_NAME="$TARGET-$VERSION" else FULL_NAME="$TARGET-$VERSION-$TOOLCHAIN_VERSION_SUFFIX" fi mv "$TARGET" "$FULL_NAME" ARCHIVE_NAME="$FULL_NAME.tar.gz" tar -czvf "$ARCHIVE_NAME" "$FULL_NAME" cp "$ARCHIVE_NAME" /artifacts/"$ARCHIVE_NAME" } echo "building toolchain for $TARGET" build_toolchain build_zlib build_archive ================================================ FILE: tools/toolchain_builder/create_image.sh ================================================ #!/bin/sh docker build -t kotlin-toolchain-builder . ================================================ FILE: tools/toolchain_builder/patches/github_pull_1244.patch ================================================ From 8ad4a8b83f3de8b7b283a845c5744147ba819c9d Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Sat, 14 Sep 2019 22:17:28 +1200 Subject: [PATCH] build/internals.sh: Handle pie executables Fixes: #887 On some systems the file command identifies a pie executable as a shared object. Update do_finish() to handle this case so that they are stripped as well. Signed-off-by: Chris Packham --- scripts/build/internals.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build/internals.sh b/scripts/build/internals.sh index 5d359979..821761c2 100644 --- a/scripts/build/internals.sh +++ b/scripts/build/internals.sh @@ -83,7 +83,7 @@ do_finish() { case "${_type}" in *script*executable*) ;; - *executable*) + *executable*|*shared*object*) CT_DoExecLog ALL ${CT_HOST}-strip ${strip_args} "${_t}" ;; esac -- 2.25.1 ================================================ FILE: tools/toolchain_builder/run_container.sh ================================================ #!/bin/bash set -eou pipefail CONTAINER_NAME=kotlin-toolchain-builder IMAGE_NAME=kotlin-toolchain-builder TARGET=$1 VERSION=$2 TOOLCHAIN_VERSION_SUFFIX="${3:-""}" docker ps -a | grep $CONTAINER_NAME > /dev/null \ && docker stop $CONTAINER_NAME > /dev/null \ && docker rm $CONTAINER_NAME > /dev/null echo "Running build script in container..." docker run -it -v "$PWD"/artifacts:/artifacts \ --env TARGET="$TARGET" \ --env VERSION="$VERSION" \ --env TOOLCHAIN_VERSION_SUFFIX="$TOOLCHAIN_VERSION_SUFFIX" \ --name=$CONTAINER_NAME $IMAGE_NAME echo "Done." ================================================ FILE: tools/toolchain_builder/toolchains/aarch64-unknown-linux-gnu/gcc-8.3.0-glibc-2.25-kernel-4.9.config ================================================ # # Automatically generated file; DO NOT EDIT. # crosstool-NG Configuration # CT_CONFIGURE_has_static_link=y CT_CONFIGURE_has_cxx11=y CT_CONFIGURE_has_wget=y CT_CONFIGURE_has_curl=y CT_CONFIGURE_has_make_3_81_or_newer=y CT_CONFIGURE_has_make_4_0_or_newer=y CT_CONFIGURE_has_libtool_2_4_or_newer=y CT_CONFIGURE_has_libtoolize_2_4_or_newer=y CT_CONFIGURE_has_autoconf_2_65_or_newer=y CT_CONFIGURE_has_autoreconf_2_65_or_newer=y CT_CONFIGURE_has_automake_1_15_or_newer=y CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y CT_CONFIGURE_has_python_3_4_or_newer=y CT_CONFIGURE_has_bison_2_7_or_newer=y CT_CONFIGURE_has_python=y CT_CONFIGURE_has_git=y CT_CONFIGURE_has_md5sum=y CT_CONFIGURE_has_sha1sum=y CT_CONFIGURE_has_sha256sum=y CT_CONFIGURE_has_sha512sum=y CT_CONFIGURE_has_install_with_strip_program=y CT_CONFIG_VERSION_CURRENT="3" CT_CONFIG_VERSION="3" CT_MODULES=y # # Paths and misc options # # # crosstool-NG behavior # # CT_OBSOLETE is not set # CT_EXPERIMENTAL is not set # CT_DEBUG_CT is not set # # Paths # CT_LOCAL_TARBALLS_DIR="${HOME}/src" CT_SAVE_TARBALLS=y # CT_TARBALLS_BUILDROOT_LAYOUT is not set CT_WORK_DIR="${CT_TOP_DIR}/.build" CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_RM_RF_PREFIX_DIR=y CT_REMOVE_DOCS=y CT_INSTALL_LICENSES=y # CT_PREFIX_DIR_RO is not set CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES=y # # Downloading # CT_DOWNLOAD_AGENT_WGET=y # CT_DOWNLOAD_AGENT_CURL is not set # CT_DOWNLOAD_AGENT_NONE is not set # CT_FORBID_DOWNLOAD is not set # CT_FORCE_DOWNLOAD is not set CT_CONNECT_TIMEOUT=10 CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" # CT_ONLY_DOWNLOAD is not set # CT_USE_MIRROR is not set CT_VERIFY_DOWNLOAD_DIGEST=y CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y # CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set # CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set # CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" # CT_VERIFY_DOWNLOAD_SIGNATURE is not set # # Extracting # # CT_FORCE_EXTRACT is not set CT_OVERRIDE_CONFIG_GUESS_SUB=y # CT_ONLY_EXTRACT is not set CT_PATCH_BUNDLED=y # CT_PATCH_BUNDLED_LOCAL is not set CT_PATCH_ORDER="bundled" # # Build behavior # CT_PARALLEL_JOBS=0 CT_LOAD="" CT_USE_PIPES=y CT_EXTRA_CFLAGS_FOR_BUILD="" CT_EXTRA_LDFLAGS_FOR_BUILD="" CT_EXTRA_CFLAGS_FOR_HOST="" CT_EXTRA_LDFLAGS_FOR_HOST="" # CT_CONFIG_SHELL_SH is not set # CT_CONFIG_SHELL_ASH is not set CT_CONFIG_SHELL_BASH=y # CT_CONFIG_SHELL_CUSTOM is not set CT_CONFIG_SHELL="${bash}" # # Logging # # CT_LOG_ERROR is not set # CT_LOG_WARN is not set # CT_LOG_INFO is not set CT_LOG_EXTRA=y # CT_LOG_ALL is not set # CT_LOG_DEBUG is not set CT_LOG_LEVEL_MAX="EXTRA" # CT_LOG_SEE_TOOLS_WARN is not set CT_LOG_PROGRESS_BAR=y CT_LOG_TO_FILE=y CT_LOG_FILE_COMPRESS=y # # Target options # # CT_ARCH_ALPHA is not set # CT_ARCH_ARC is not set CT_ARCH_ARM=y # CT_ARCH_AVR is not set # CT_ARCH_M68K is not set # CT_ARCH_MIPS is not set # CT_ARCH_NIOS2 is not set # CT_ARCH_POWERPC is not set # CT_ARCH_S390 is not set # CT_ARCH_SH is not set # CT_ARCH_SPARC is not set # CT_ARCH_X86 is not set # CT_ARCH_XTENSA is not set CT_ARCH="arm" CT_ARCH_CHOICE_KSYM="ARM" CT_ARCH_CPU="" CT_ARCH_TUNE="" CT_ARCH_ARM_SHOW=y # # Options for arm # CT_ARCH_ARM_PKG_KSYM="" CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" CT_ARCH_SUFFIX="" # CT_OMIT_TARGET_VENDOR is not set # # Generic target options # # CT_MULTILIB is not set CT_DEMULTILIB=y CT_ARCH_SUPPORTS_BOTH_MMU=y CT_ARCH_DEFAULT_HAS_MMU=y CT_ARCH_USE_MMU=y CT_ARCH_SUPPORTS_FLAT_FORMAT=y CT_ARCH_SUPPORTS_EITHER_ENDIAN=y CT_ARCH_DEFAULT_LE=y # CT_ARCH_BE is not set CT_ARCH_LE=y CT_ARCH_ENDIAN="little" CT_ARCH_SUPPORTS_32=y CT_ARCH_SUPPORTS_64=y CT_ARCH_DEFAULT_32=y CT_ARCH_BITNESS=64 # CT_ARCH_32 is not set CT_ARCH_64=y # # Target optimisations # CT_ARCH_SUPPORTS_WITH_ARCH=y CT_ARCH_SUPPORTS_WITH_CPU=y CT_ARCH_SUPPORTS_WITH_TUNE=y CT_ARCH_EXCLUSIVE_WITH_CPU=y CT_ARCH_ARCH="" CT_TARGET_CFLAGS="" CT_TARGET_LDFLAGS="" # # Toolchain options # # # General toolchain options # CT_FORCE_SYSROOT=y CT_USE_SYSROOT=y CT_SYSROOT_NAME="sysroot" CT_SYSROOT_DIR_PREFIX="" CT_WANTS_STATIC_LINK=y CT_WANTS_STATIC_LINK_CXX=y # CT_STATIC_TOOLCHAIN is not set CT_SHOW_CT_VERSION=y CT_TOOLCHAIN_PKGVERSION="" CT_TOOLCHAIN_BUGURL="" # # Tuple completion and aliasing # CT_TARGET_VENDOR="" CT_TARGET_ALIAS_SED_EXPR="" CT_TARGET_ALIAS="" # # Toolchain type # CT_CROSS=y # CT_CANADIAN is not set CT_TOOLCHAIN_TYPE="cross" # # Build system # CT_BUILD="" CT_BUILD_PREFIX="" CT_BUILD_SUFFIX="" # # Misc options # # CT_TOOLCHAIN_ENABLE_NLS is not set # # Operating System # CT_KERNEL_SUPPORTS_SHARED_LIBS=y # CT_KERNEL_BARE_METAL is not set CT_KERNEL_LINUX=y CT_KERNEL="linux" CT_KERNEL_CHOICE_KSYM="LINUX" CT_KERNEL_LINUX_SHOW=y # # Options for linux # CT_KERNEL_LINUX_PKG_KSYM="LINUX" CT_LINUX_DIR_NAME="linux" CT_LINUX_PKG_NAME="linux" CT_LINUX_SRC_RELEASE=y CT_LINUX_PATCH_ORDER="global" # CT_LINUX_V_4_20 is not set # CT_LINUX_V_4_19 is not set # CT_LINUX_V_4_18 is not set # CT_LINUX_V_4_17 is not set # CT_LINUX_V_4_16 is not set # CT_LINUX_V_4_15 is not set # CT_LINUX_V_4_14 is not set # CT_LINUX_V_4_13 is not set # CT_LINUX_V_4_12 is not set # CT_LINUX_V_4_11 is not set # CT_LINUX_V_4_10 is not set CT_LINUX_V_4_9=y # CT_LINUX_V_4_4 is not set # CT_LINUX_V_4_1 is not set # CT_LINUX_V_3_16 is not set # CT_LINUX_V_3_13 is not set # CT_LINUX_V_3_12 is not set # CT_LINUX_V_3_10 is not set # CT_LINUX_NO_VERSIONS is not set CT_LINUX_VERSION="4.9.156" CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" CT_LINUX_later_than_4_8=y CT_LINUX_4_8_or_later=y CT_LINUX_later_than_3_7=y CT_LINUX_3_7_or_later=y CT_LINUX_REQUIRE_3_7_or_later=y CT_LINUX_later_than_3_2=y CT_LINUX_3_2_or_later=y CT_LINUX_REQUIRE_3_2_or_later=y CT_KERNEL_LINUX_VERBOSITY_0=y # CT_KERNEL_LINUX_VERBOSITY_1 is not set # CT_KERNEL_LINUX_VERBOSITY_2 is not set CT_KERNEL_LINUX_VERBOSE_LEVEL=0 CT_KERNEL_LINUX_INSTALL_CHECK=y CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" # # Common kernel options # CT_SHARED_LIBS=y # # Binary utilities # CT_ARCH_BINFMT_ELF=y CT_BINUTILS_BINUTILS=y CT_BINUTILS="binutils" CT_BINUTILS_CHOICE_KSYM="BINUTILS" CT_BINUTILS_BINUTILS_SHOW=y # # Options for binutils # CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" CT_BINUTILS_DIR_NAME="binutils" CT_BINUTILS_USE_GNU=y CT_BINUTILS_USE="BINUTILS" CT_BINUTILS_PKG_NAME="binutils" CT_BINUTILS_SRC_RELEASE=y CT_BINUTILS_PATCH_ORDER="global" # CT_BINUTILS_V_2_32 is not set # CT_BINUTILS_V_2_31 is not set # CT_BINUTILS_V_2_30 is not set CT_BINUTILS_V_2_29=y # CT_BINUTILS_V_2_28 is not set # CT_BINUTILS_V_2_27 is not set # CT_BINUTILS_V_2_26 is not set # CT_BINUTILS_NO_VERSIONS is not set CT_BINUTILS_VERSION="2.29.1" CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" CT_BINUTILS_2_30_or_older=y CT_BINUTILS_older_than_2_30=y CT_BINUTILS_REQUIRE_older_than_2_30=y CT_BINUTILS_later_than_2_27=y CT_BINUTILS_2_27_or_later=y CT_BINUTILS_later_than_2_25=y CT_BINUTILS_2_25_or_later=y CT_BINUTILS_later_than_2_23=y CT_BINUTILS_2_23_or_later=y # # GNU binutils # CT_BINUTILS_HAS_HASH_STYLE=y CT_BINUTILS_HAS_GOLD=y CT_BINUTILS_HAS_PLUGINS=y CT_BINUTILS_HAS_PKGVERSION_BUGURL=y CT_BINUTILS_GOLD_SUPPORTS_ARCH=y CT_BINUTILS_GOLD_SUPPORT=y CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y # CT_BINUTILS_LINKER_LD is not set CT_BINUTILS_LINKER_LD_GOLD=y CT_BINUTILS_GOLD_INSTALLED=y CT_BINUTILS_GOLD_THREADS=y CT_BINUTILS_LINKER_BOTH=y CT_BINUTILS_LINKERS_LIST="ld,gold" CT_BINUTILS_LD_WRAPPER=y CT_BINUTILS_LINKER_DEFAULT="bfd" CT_BINUTILS_PLUGINS=y CT_BINUTILS_RELRO=m CT_BINUTILS_EXTRA_CONFIG_ARRAY="" # CT_BINUTILS_FOR_TARGET is not set CT_ALL_BINUTILS_CHOICES="BINUTILS" # # C-library # CT_LIBC_GLIBC=y # CT_LIBC_UCLIBC is not set CT_LIBC="glibc" CT_LIBC_CHOICE_KSYM="GLIBC" CT_THREADS="nptl" CT_LIBC_GLIBC_SHOW=y # # Options for glibc # CT_LIBC_GLIBC_PKG_KSYM="GLIBC" CT_GLIBC_DIR_NAME="glibc" CT_GLIBC_USE_GNU=y CT_GLIBC_USE="GLIBC" CT_GLIBC_PKG_NAME="glibc" CT_GLIBC_SRC_RELEASE=y CT_GLIBC_PATCH_ORDER="global" # CT_GLIBC_V_2_29 is not set # CT_GLIBC_V_2_28 is not set # CT_GLIBC_V_2_27 is not set # CT_GLIBC_V_2_26 is not set CT_GLIBC_V_2_25=y # CT_GLIBC_V_2_24 is not set # CT_GLIBC_V_2_23 is not set # CT_GLIBC_V_2_19 is not set # CT_GLIBC_V_2_17 is not set # CT_GLIBC_V_2_12_1 is not set # CT_GLIBC_NO_VERSIONS is not set CT_GLIBC_VERSION="2.25" CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" CT_GLIBC_2_29_or_older=y CT_GLIBC_older_than_2_29=y CT_GLIBC_2_27_or_older=y CT_GLIBC_older_than_2_27=y CT_GLIBC_2_26_or_older=y CT_GLIBC_older_than_2_26=y CT_GLIBC_2_25_or_later=y CT_GLIBC_2_25_or_older=y CT_GLIBC_later_than_2_24=y CT_GLIBC_2_24_or_later=y CT_GLIBC_later_than_2_23=y CT_GLIBC_2_23_or_later=y CT_GLIBC_later_than_2_20=y CT_GLIBC_2_20_or_later=y CT_GLIBC_later_than_2_17=y CT_GLIBC_2_17_or_later=y CT_GLIBC_later_than_2_14=y CT_GLIBC_2_14_or_later=y CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y CT_GLIBC_DEP_BINUTILS=y CT_GLIBC_DEP_GCC=y CT_GLIBC_DEP_PYTHON=y CT_GLIBC_BUILD_SSP=y CT_GLIBC_HAS_LIBIDN_ADDON=y # CT_GLIBC_USE_LIBIDN_ADDON is not set CT_GLIBC_NO_SPARC_V8=y CT_GLIBC_HAS_OBSOLETE_RPC=y CT_GLIBC_EXTRA_CONFIG_ARRAY="" CT_GLIBC_CONFIGPARMS="" CT_GLIBC_EXTRA_CFLAGS="" CT_GLIBC_ENABLE_OBSOLETE_RPC=y # CT_GLIBC_DISABLE_VERSIONING is not set CT_GLIBC_OLDEST_ABI="" CT_GLIBC_FORCE_UNWIND=y # CT_GLIBC_LOCALES is not set # CT_GLIBC_KERNEL_VERSION_NONE is not set CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y # CT_GLIBC_KERNEL_VERSION_CHOSEN is not set CT_GLIBC_MIN_KERNEL="4.9.156" CT_GLIBC_SSP_DEFAULT=y # CT_GLIBC_SSP_NO is not set # CT_GLIBC_SSP_YES is not set # CT_GLIBC_SSP_ALL is not set # CT_GLIBC_SSP_STRONG is not set # CT_GLIBC_ENABLE_WERROR is not set CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" CT_LIBC_SUPPORT_THREADS_ANY=y CT_LIBC_SUPPORT_THREADS_NATIVE=y # # Common C library options # CT_THREADS_NATIVE=y # CT_CREATE_LDSO_CONF is not set CT_LIBC_XLDD=y # # C compiler # CT_CC_CORE_PASSES_NEEDED=y CT_CC_CORE_PASS_1_NEEDED=y CT_CC_CORE_PASS_2_NEEDED=y CT_CC_SUPPORT_CXX=y CT_CC_SUPPORT_FORTRAN=y CT_CC_SUPPORT_ADA=y CT_CC_SUPPORT_OBJC=y CT_CC_SUPPORT_OBJCXX=y CT_CC_SUPPORT_GOLANG=y CT_CC_GCC=y CT_CC="gcc" CT_CC_CHOICE_KSYM="GCC" CT_CC_GCC_SHOW=y # # Options for gcc # CT_CC_GCC_PKG_KSYM="GCC" CT_GCC_DIR_NAME="gcc" CT_GCC_USE_GNU=y CT_GCC_USE="GCC" CT_GCC_PKG_NAME="gcc" CT_GCC_SRC_RELEASE=y CT_GCC_PATCH_ORDER="global" CT_GCC_V_8=y # CT_GCC_V_7 is not set # CT_GCC_V_6 is not set # CT_GCC_V_5 is not set # CT_GCC_V_4_9 is not set # CT_GCC_NO_VERSIONS is not set CT_GCC_VERSION="8.3.0" CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_GCC_SIGNATURE_FORMAT="" CT_GCC_later_than_7=y CT_GCC_7_or_later=y CT_GCC_later_than_6=y CT_GCC_6_or_later=y CT_GCC_later_than_5=y CT_GCC_5_or_later=y CT_GCC_later_than_4_9=y CT_GCC_4_9_or_later=y CT_GCC_later_than_4_8=y CT_GCC_4_8_or_later=y CT_CC_GCC_ENABLE_PLUGINS=y CT_CC_GCC_GOLD=y CT_CC_GCC_HAS_LIBMPX=y CT_CC_GCC_ENABLE_CXX_FLAGS="" CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_STATIC_LIBSTDCXX=y # CT_CC_GCC_SYSTEM_ZLIB is not set CT_CC_GCC_CONFIG_TLS=m # # Optimisation features # CT_CC_GCC_USE_GRAPHITE=y CT_CC_GCC_USE_LTO=y # # Settings for libraries running on target # CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y # CT_CC_GCC_LIBMUDFLAP is not set # CT_CC_GCC_LIBGOMP is not set # CT_CC_GCC_LIBSSP is not set # CT_CC_GCC_LIBQUADMATH is not set # CT_CC_GCC_LIBSANITIZER is not set # # Misc. obscure options. # CT_CC_CXA_ATEXIT=y # CT_CC_GCC_DISABLE_PCH is not set CT_CC_GCC_SJLJ_EXCEPTIONS=m CT_CC_GCC_LDBL_128=m # CT_CC_GCC_BUILD_ID is not set CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y # CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set # CT_CC_GCC_LNK_HASH_STYLE_GNU is not set # CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set CT_CC_GCC_LNK_HASH_STYLE="" CT_CC_GCC_DEC_FLOAT_AUTO=y # CT_CC_GCC_DEC_FLOAT_BID is not set # CT_CC_GCC_DEC_FLOAT_DPD is not set # CT_CC_GCC_DEC_FLOATS_NO is not set CT_ALL_CC_CHOICES="GCC" # # Additional supported languages: # CT_CC_LANG_CXX=y # CT_CC_LANG_FORTRAN is not set # # Debug facilities # # CT_DEBUG_DUMA is not set # CT_DEBUG_GDB is not set # CT_GDB_USE_GNU is not set # CT_GDB_SRC_RELEASE is not set # CT_GDB_V_8_2 is not set # CT_GDB_V_8_1 is not set # CT_GDB_V_8_0 is not set # CT_GDB_V_7_12 is not set # CT_GDB_V_7_11 is not set # CT_DEBUG_LTRACE is not set # CT_DEBUG_STRACE is not set CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" # # Companion libraries # # CT_COMPLIBS_CHECK is not set # CT_COMP_LIBS_CLOOG is not set CT_COMP_LIBS_EXPAT=y CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" CT_EXPAT_DIR_NAME="expat" CT_EXPAT_PKG_NAME="expat" CT_EXPAT_SRC_RELEASE=y CT_EXPAT_PATCH_ORDER="global" CT_EXPAT_V_2_2=y # CT_EXPAT_NO_VERSIONS is not set CT_EXPAT_VERSION="2.2.6" CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" CT_EXPAT_SIGNATURE_FORMAT="" CT_COMP_LIBS_GETTEXT=y CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" CT_GETTEXT_DIR_NAME="gettext" CT_GETTEXT_PKG_NAME="gettext" CT_GETTEXT_SRC_RELEASE=y CT_GETTEXT_PATCH_ORDER="global" CT_GETTEXT_V_0_19_8_1=y # CT_GETTEXT_NO_VERSIONS is not set CT_GETTEXT_VERSION="0.19.8.1" CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_GMP=y CT_COMP_LIBS_GMP_PKG_KSYM="GMP" CT_GMP_DIR_NAME="gmp" CT_GMP_PKG_NAME="gmp" CT_GMP_SRC_RELEASE=y CT_GMP_PATCH_ORDER="global" CT_GMP_V_6_1=y # CT_GMP_NO_VERSIONS is not set CT_GMP_VERSION="6.1.2" CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" CT_GMP_SIGNATURE_FORMAT="packed/.sig" CT_GMP_later_than_5_1_0=y CT_GMP_5_1_0_or_later=y CT_GMP_later_than_5_0_0=y CT_GMP_5_0_0_or_later=y CT_GMP_REQUIRE_5_0_0_or_later=y CT_COMP_LIBS_ISL=y CT_COMP_LIBS_ISL_PKG_KSYM="ISL" CT_ISL_DIR_NAME="isl" CT_ISL_PKG_NAME="isl" CT_ISL_SRC_RELEASE=y CT_ISL_PATCH_ORDER="global" CT_ISL_V_0_20=y # CT_ISL_V_0_19 is not set # CT_ISL_V_0_18 is not set # CT_ISL_V_0_17 is not set # CT_ISL_V_0_16 is not set # CT_ISL_V_0_15 is not set # CT_ISL_NO_VERSIONS is not set CT_ISL_VERSION="0.20" CT_ISL_MIRRORS="http://isl.gforge.inria.fr" CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_ISL_SIGNATURE_FORMAT="" CT_ISL_later_than_0_18=y CT_ISL_0_18_or_later=y CT_ISL_later_than_0_15=y CT_ISL_0_15_or_later=y CT_ISL_REQUIRE_0_15_or_later=y CT_ISL_later_than_0_14=y CT_ISL_0_14_or_later=y CT_ISL_REQUIRE_0_14_or_later=y CT_ISL_later_than_0_13=y CT_ISL_0_13_or_later=y CT_ISL_later_than_0_12=y CT_ISL_0_12_or_later=y CT_ISL_REQUIRE_0_12_or_later=y # CT_COMP_LIBS_LIBELF is not set CT_COMP_LIBS_LIBICONV=y CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" CT_LIBICONV_DIR_NAME="libiconv" CT_LIBICONV_PKG_NAME="libiconv" CT_LIBICONV_SRC_RELEASE=y CT_LIBICONV_PATCH_ORDER="global" CT_LIBICONV_V_1_15=y # CT_LIBICONV_NO_VERSIONS is not set CT_LIBICONV_VERSION="1.15" CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_MPC=y CT_COMP_LIBS_MPC_PKG_KSYM="MPC" CT_MPC_DIR_NAME="mpc" CT_MPC_PKG_NAME="mpc" CT_MPC_SRC_RELEASE=y CT_MPC_PATCH_ORDER="global" CT_MPC_V_1_1=y # CT_MPC_V_1_0 is not set # CT_MPC_NO_VERSIONS is not set CT_MPC_VERSION="1.1.0" CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_FORMATS=".tar.gz" CT_MPC_SIGNATURE_FORMAT="packed/.sig" CT_MPC_1_1_0_or_later=y CT_MPC_1_1_0_or_older=y CT_COMP_LIBS_MPFR=y CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" CT_MPFR_DIR_NAME="mpfr" CT_MPFR_PKG_NAME="mpfr" CT_MPFR_SRC_RELEASE=y CT_MPFR_PATCH_ORDER="global" CT_MPFR_V_4_0=y # CT_MPFR_V_3_1 is not set # CT_MPFR_NO_VERSIONS is not set CT_MPFR_VERSION="4.0.2" CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" CT_MPFR_SIGNATURE_FORMAT="packed/.asc" CT_MPFR_later_than_4_0_0=y CT_MPFR_4_0_0_or_later=y CT_MPFR_later_than_3_0_0=y CT_MPFR_3_0_0_or_later=y CT_MPFR_REQUIRE_3_0_0_or_later=y CT_COMP_LIBS_NCURSES=y CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" CT_NCURSES_DIR_NAME="ncurses" CT_NCURSES_PKG_NAME="ncurses" CT_NCURSES_SRC_RELEASE=y CT_NCURSES_PATCH_ORDER="global" CT_NCURSES_V_6_1=y # CT_NCURSES_V_6_0 is not set # CT_NCURSES_NO_VERSIONS is not set CT_NCURSES_VERSION="6.1" CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" CT_NCURSES_HOST_CONFIG_ARGS="" CT_NCURSES_HOST_DISABLE_DB=y CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" CT_NCURSES_TARGET_CONFIG_ARGS="" # CT_NCURSES_TARGET_DISABLE_DB is not set CT_NCURSES_TARGET_FALLBACKS="" CT_COMP_LIBS_ZLIB=y CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" CT_ZLIB_DIR_NAME="zlib" CT_ZLIB_PKG_NAME="zlib" CT_ZLIB_SRC_RELEASE=y CT_ZLIB_PATCH_ORDER="global" CT_ZLIB_V_1_2_11=y # CT_ZLIB_NO_VERSIONS is not set CT_ZLIB_VERSION="1.2.11" CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" CT_LIBICONV_NEEDED=y CT_GETTEXT_NEEDED=y CT_GMP_NEEDED=y CT_MPFR_NEEDED=y CT_ISL_NEEDED=y CT_MPC_NEEDED=y CT_NCURSES_NEEDED=y CT_ZLIB_NEEDED=y CT_LIBICONV=y CT_GETTEXT=y CT_GMP=y CT_MPFR=y CT_ISL=y CT_MPC=y CT_NCURSES=y CT_ZLIB=y # # Companion tools # # CT_COMP_TOOLS_FOR_HOST is not set # CT_COMP_TOOLS_AUTOCONF is not set # CT_COMP_TOOLS_AUTOMAKE is not set # CT_COMP_TOOLS_BISON is not set # CT_COMP_TOOLS_DTC is not set # CT_COMP_TOOLS_LIBTOOL is not set # CT_COMP_TOOLS_M4 is not set # CT_COMP_TOOLS_MAKE is not set CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" ================================================ FILE: tools/toolchain_builder/toolchains/arm-unknown-linux-gnueabihf/gcc-8.3.0-glibc-2.19-kernel-4.9.config ================================================ # # Automatically generated file; DO NOT EDIT. # crosstool-NG Configuration # CT_CONFIGURE_has_static_link=y CT_CONFIGURE_has_cxx11=y CT_CONFIGURE_has_wget=y CT_CONFIGURE_has_curl=y CT_CONFIGURE_has_make_3_81_or_newer=y CT_CONFIGURE_has_make_4_0_or_newer=y CT_CONFIGURE_has_libtool_2_4_or_newer=y CT_CONFIGURE_has_libtoolize_2_4_or_newer=y CT_CONFIGURE_has_autoconf_2_65_or_newer=y CT_CONFIGURE_has_autoreconf_2_65_or_newer=y CT_CONFIGURE_has_automake_1_15_or_newer=y CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y CT_CONFIGURE_has_python_3_4_or_newer=y CT_CONFIGURE_has_bison_2_7_or_newer=y CT_CONFIGURE_has_python=y CT_CONFIGURE_has_git=y CT_CONFIGURE_has_md5sum=y CT_CONFIGURE_has_sha1sum=y CT_CONFIGURE_has_sha256sum=y CT_CONFIGURE_has_sha512sum=y CT_CONFIGURE_has_install_with_strip_program=y CT_CONFIG_VERSION_CURRENT="3" CT_CONFIG_VERSION="3" CT_MODULES=y # # Paths and misc options # # # crosstool-NG behavior # # CT_OBSOLETE is not set # CT_EXPERIMENTAL is not set # CT_DEBUG_CT is not set # # Paths # CT_LOCAL_TARBALLS_DIR="${HOME}/src" CT_SAVE_TARBALLS=y # CT_TARBALLS_BUILDROOT_LAYOUT is not set CT_WORK_DIR="${CT_TOP_DIR}/.build" CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_RM_RF_PREFIX_DIR=y CT_REMOVE_DOCS=y CT_INSTALL_LICENSES=y # CT_PREFIX_DIR_RO is not set CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES=y # # Downloading # CT_DOWNLOAD_AGENT_WGET=y # CT_DOWNLOAD_AGENT_CURL is not set # CT_DOWNLOAD_AGENT_NONE is not set # CT_FORBID_DOWNLOAD is not set # CT_FORCE_DOWNLOAD is not set CT_CONNECT_TIMEOUT=10 CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" # CT_ONLY_DOWNLOAD is not set # CT_USE_MIRROR is not set CT_VERIFY_DOWNLOAD_DIGEST=y CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y # CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set # CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set # CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" # CT_VERIFY_DOWNLOAD_SIGNATURE is not set # # Extracting # # CT_FORCE_EXTRACT is not set CT_OVERRIDE_CONFIG_GUESS_SUB=y # CT_ONLY_EXTRACT is not set CT_PATCH_BUNDLED=y # CT_PATCH_BUNDLED_LOCAL is not set CT_PATCH_ORDER="bundled" # # Build behavior # CT_PARALLEL_JOBS=0 CT_LOAD="" CT_USE_PIPES=y CT_EXTRA_CFLAGS_FOR_BUILD="" CT_EXTRA_LDFLAGS_FOR_BUILD="" CT_EXTRA_CFLAGS_FOR_HOST="" CT_EXTRA_LDFLAGS_FOR_HOST="" # CT_CONFIG_SHELL_SH is not set # CT_CONFIG_SHELL_ASH is not set CT_CONFIG_SHELL_BASH=y # CT_CONFIG_SHELL_CUSTOM is not set CT_CONFIG_SHELL="${bash}" # # Logging # # CT_LOG_ERROR is not set # CT_LOG_WARN is not set # CT_LOG_INFO is not set CT_LOG_EXTRA=y # CT_LOG_ALL is not set # CT_LOG_DEBUG is not set CT_LOG_LEVEL_MAX="EXTRA" # CT_LOG_SEE_TOOLS_WARN is not set CT_LOG_PROGRESS_BAR=y CT_LOG_TO_FILE=y CT_LOG_FILE_COMPRESS=y # # Target options # # CT_ARCH_ALPHA is not set # CT_ARCH_ARC is not set CT_ARCH_ARM=y # CT_ARCH_AVR is not set # CT_ARCH_M68K is not set # CT_ARCH_MIPS is not set # CT_ARCH_NIOS2 is not set # CT_ARCH_POWERPC is not set # CT_ARCH_S390 is not set # CT_ARCH_SH is not set # CT_ARCH_SPARC is not set # CT_ARCH_X86 is not set # CT_ARCH_XTENSA is not set CT_ARCH="arm" CT_ARCH_CHOICE_KSYM="ARM" CT_ARCH_CPU="arm1136jf-s" CT_ARCH_ARM_SHOW=y # # Options for arm # CT_ARCH_ARM_PKG_KSYM="" CT_ARCH_ARM_MODE="arm" CT_ARCH_ARM_MODE_ARM=y # CT_ARCH_ARM_MODE_THUMB is not set # CT_ARCH_ARM_INTERWORKING is not set CT_ARCH_ARM_EABI_FORCE=y CT_ARCH_ARM_EABI=y CT_ARCH_ARM_TUPLE_USE_EABIHF=y CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" CT_ARCH_SUFFIX="" # CT_OMIT_TARGET_VENDOR is not set # # Generic target options # # CT_MULTILIB is not set CT_DEMULTILIB=y CT_ARCH_SUPPORTS_BOTH_MMU=y CT_ARCH_DEFAULT_HAS_MMU=y CT_ARCH_USE_MMU=y CT_ARCH_SUPPORTS_FLAT_FORMAT=y CT_ARCH_SUPPORTS_EITHER_ENDIAN=y CT_ARCH_DEFAULT_LE=y # CT_ARCH_BE is not set CT_ARCH_LE=y CT_ARCH_ENDIAN="little" CT_ARCH_SUPPORTS_32=y CT_ARCH_SUPPORTS_64=y CT_ARCH_DEFAULT_32=y CT_ARCH_BITNESS=32 CT_ARCH_32=y # CT_ARCH_64 is not set # # Target optimisations # CT_ARCH_SUPPORTS_WITH_ARCH=y CT_ARCH_SUPPORTS_WITH_CPU=y CT_ARCH_SUPPORTS_WITH_TUNE=y CT_ARCH_SUPPORTS_WITH_FLOAT=y CT_ARCH_SUPPORTS_WITH_FPU=y CT_ARCH_SUPPORTS_SOFTFP=y CT_ARCH_EXCLUSIVE_WITH_CPU=y CT_ARCH_FPU="vfp" # CT_ARCH_FLOAT_AUTO is not set CT_ARCH_FLOAT_HW=y # CT_ARCH_FLOAT_SOFTFP is not set # CT_ARCH_FLOAT_SW is not set CT_TARGET_CFLAGS="" CT_TARGET_LDFLAGS="" CT_ARCH_FLOAT="hard" # # Toolchain options # # # General toolchain options # CT_FORCE_SYSROOT=y CT_USE_SYSROOT=y CT_SYSROOT_NAME="sysroot" CT_SYSROOT_DIR_PREFIX="" CT_WANTS_STATIC_LINK=y CT_WANTS_STATIC_LINK_CXX=y # CT_STATIC_TOOLCHAIN is not set CT_SHOW_CT_VERSION=y CT_TOOLCHAIN_PKGVERSION="" CT_TOOLCHAIN_BUGURL="" # # Tuple completion and aliasing # CT_TARGET_VENDOR="" CT_TARGET_ALIAS_SED_EXPR="" CT_TARGET_ALIAS="" # # Toolchain type # CT_CROSS=y # CT_CANADIAN is not set CT_TOOLCHAIN_TYPE="cross" # # Build system # CT_BUILD="" CT_BUILD_PREFIX="" CT_BUILD_SUFFIX="" # # Misc options # # CT_TOOLCHAIN_ENABLE_NLS is not set # # Operating System # CT_KERNEL_SUPPORTS_SHARED_LIBS=y # CT_KERNEL_BARE_METAL is not set CT_KERNEL_LINUX=y CT_KERNEL="linux" CT_KERNEL_CHOICE_KSYM="LINUX" CT_KERNEL_LINUX_SHOW=y # # Options for linux # CT_KERNEL_LINUX_PKG_KSYM="LINUX" CT_LINUX_DIR_NAME="linux" CT_LINUX_PKG_NAME="linux" CT_LINUX_SRC_RELEASE=y CT_LINUX_PATCH_ORDER="global" # CT_LINUX_V_4_20 is not set # CT_LINUX_V_4_19 is not set # CT_LINUX_V_4_18 is not set # CT_LINUX_V_4_17 is not set # CT_LINUX_V_4_16 is not set # CT_LINUX_V_4_15 is not set # CT_LINUX_V_4_14 is not set # CT_LINUX_V_4_13 is not set # CT_LINUX_V_4_12 is not set # CT_LINUX_V_4_11 is not set # CT_LINUX_V_4_10 is not set CT_LINUX_V_4_9=y # CT_LINUX_V_4_4 is not set # CT_LINUX_V_4_1 is not set # CT_LINUX_V_3_16 is not set # CT_LINUX_V_3_13 is not set # CT_LINUX_V_3_12 is not set # CT_LINUX_V_3_10 is not set # CT_LINUX_V_3_4 is not set # CT_LINUX_V_3_2 is not set # CT_LINUX_V_2_6_32 is not set # CT_LINUX_NO_VERSIONS is not set CT_LINUX_VERSION="4.9.156" CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" CT_LINUX_later_than_4_8=y CT_LINUX_4_8_or_later=y CT_LINUX_later_than_3_7=y CT_LINUX_3_7_or_later=y CT_LINUX_later_than_3_2=y CT_LINUX_3_2_or_later=y CT_KERNEL_LINUX_VERBOSITY_0=y # CT_KERNEL_LINUX_VERBOSITY_1 is not set # CT_KERNEL_LINUX_VERBOSITY_2 is not set CT_KERNEL_LINUX_VERBOSE_LEVEL=0 CT_KERNEL_LINUX_INSTALL_CHECK=y CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" # # Common kernel options # CT_SHARED_LIBS=y # # Binary utilities # CT_ARCH_BINFMT_ELF=y CT_BINUTILS_BINUTILS=y CT_BINUTILS="binutils" CT_BINUTILS_CHOICE_KSYM="BINUTILS" CT_BINUTILS_BINUTILS_SHOW=y # # Options for binutils # CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" CT_BINUTILS_DIR_NAME="binutils" CT_BINUTILS_USE_GNU=y CT_BINUTILS_USE="BINUTILS" CT_BINUTILS_PKG_NAME="binutils" CT_BINUTILS_SRC_RELEASE=y CT_BINUTILS_PATCH_ORDER="global" CT_BINUTILS_V_2_32=y # CT_BINUTILS_V_2_31 is not set # CT_BINUTILS_V_2_30 is not set # CT_BINUTILS_V_2_29 is not set # CT_BINUTILS_V_2_28 is not set # CT_BINUTILS_V_2_27 is not set # CT_BINUTILS_V_2_26 is not set # CT_BINUTILS_NO_VERSIONS is not set CT_BINUTILS_VERSION="2.32" CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" CT_BINUTILS_later_than_2_30=y CT_BINUTILS_2_30_or_later=y CT_BINUTILS_later_than_2_27=y CT_BINUTILS_2_27_or_later=y CT_BINUTILS_later_than_2_25=y CT_BINUTILS_2_25_or_later=y CT_BINUTILS_later_than_2_23=y CT_BINUTILS_2_23_or_later=y # # GNU binutils # CT_BINUTILS_HAS_HASH_STYLE=y CT_BINUTILS_HAS_GOLD=y CT_BINUTILS_HAS_PLUGINS=y CT_BINUTILS_HAS_PKGVERSION_BUGURL=y CT_BINUTILS_GOLD_SUPPORTS_ARCH=y CT_BINUTILS_GOLD_SUPPORT=y CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y # CT_BINUTILS_LINKER_LD is not set CT_BINUTILS_LINKER_LD_GOLD=y CT_BINUTILS_GOLD_INSTALLED=y CT_BINUTILS_GOLD_THREADS=y CT_BINUTILS_LINKER_BOTH=y CT_BINUTILS_LINKERS_LIST="ld,gold" CT_BINUTILS_LD_WRAPPER=y CT_BINUTILS_LINKER_DEFAULT="bfd" CT_BINUTILS_PLUGINS=y CT_BINUTILS_RELRO=m CT_BINUTILS_EXTRA_CONFIG_ARRAY="" # CT_BINUTILS_FOR_TARGET is not set CT_ALL_BINUTILS_CHOICES="BINUTILS" # # C-library # CT_LIBC_GLIBC=y # CT_LIBC_UCLIBC is not set CT_LIBC="glibc" CT_LIBC_CHOICE_KSYM="GLIBC" CT_THREADS="nptl" CT_LIBC_GLIBC_SHOW=y # # Options for glibc # CT_LIBC_GLIBC_PKG_KSYM="GLIBC" CT_GLIBC_DIR_NAME="glibc" CT_GLIBC_USE_GNU=y CT_GLIBC_USE="GLIBC" CT_GLIBC_PKG_NAME="glibc" CT_GLIBC_SRC_RELEASE=y CT_GLIBC_PATCH_ORDER="global" # CT_GLIBC_V_2_29 is not set # CT_GLIBC_V_2_28 is not set # CT_GLIBC_V_2_27 is not set # CT_GLIBC_V_2_26 is not set # CT_GLIBC_V_2_25 is not set # CT_GLIBC_V_2_24 is not set # CT_GLIBC_V_2_23 is not set CT_GLIBC_V_2_19=y # CT_GLIBC_V_2_17 is not set # CT_GLIBC_V_2_12_1 is not set # CT_GLIBC_NO_VERSIONS is not set CT_GLIBC_VERSION="2.19" CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" CT_GLIBC_2_29_or_older=y CT_GLIBC_older_than_2_29=y CT_GLIBC_2_27_or_older=y CT_GLIBC_older_than_2_27=y CT_GLIBC_2_26_or_older=y CT_GLIBC_older_than_2_26=y CT_GLIBC_2_25_or_older=y CT_GLIBC_older_than_2_25=y CT_GLIBC_2_24_or_older=y CT_GLIBC_older_than_2_24=y CT_GLIBC_2_23_or_older=y CT_GLIBC_older_than_2_23=y CT_GLIBC_2_20_or_older=y CT_GLIBC_older_than_2_20=y CT_GLIBC_later_than_2_17=y CT_GLIBC_2_17_or_later=y CT_GLIBC_later_than_2_14=y CT_GLIBC_2_14_or_later=y CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y CT_GLIBC_DEP_BINUTILS=y CT_GLIBC_DEP_GCC=y CT_GLIBC_DEP_PYTHON=y CT_GLIBC_HAS_NPTL_ADDON=y CT_GLIBC_HAS_PORTS_ADDON=y CT_GLIBC_HAS_LIBIDN_ADDON=y CT_GLIBC_USE_PORTS_ADDON=y CT_GLIBC_USE_NPTL_ADDON=y # CT_GLIBC_USE_LIBIDN_ADDON is not set CT_GLIBC_HAS_OBSOLETE_RPC=y CT_GLIBC_EXTRA_CONFIG_ARRAY="" CT_GLIBC_CONFIGPARMS="" CT_GLIBC_EXTRA_CFLAGS="" CT_GLIBC_ENABLE_OBSOLETE_RPC=y # CT_GLIBC_DISABLE_VERSIONING is not set CT_GLIBC_OLDEST_ABI="" CT_GLIBC_FORCE_UNWIND=y # CT_GLIBC_LOCALES is not set # CT_GLIBC_KERNEL_VERSION_NONE is not set # CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set CT_GLIBC_KERNEL_VERSION_CHOSEN=y CT_GLIBC_MIN_KERNEL_VERSION="3.2.27" CT_GLIBC_MIN_KERNEL="3.2.27" CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" CT_LIBC_SUPPORT_THREADS_ANY=y CT_LIBC_SUPPORT_THREADS_NATIVE=y # # Common C library options # CT_THREADS_NATIVE=y # CT_CREATE_LDSO_CONF is not set CT_LIBC_XLDD=y # # C compiler # CT_CC_CORE_PASSES_NEEDED=y CT_CC_CORE_PASS_1_NEEDED=y CT_CC_CORE_PASS_2_NEEDED=y CT_CC_SUPPORT_CXX=y CT_CC_SUPPORT_FORTRAN=y CT_CC_SUPPORT_ADA=y CT_CC_SUPPORT_OBJC=y CT_CC_SUPPORT_OBJCXX=y CT_CC_SUPPORT_GOLANG=y CT_CC_GCC=y CT_CC="gcc" CT_CC_CHOICE_KSYM="GCC" CT_CC_GCC_SHOW=y # # Options for gcc # CT_CC_GCC_PKG_KSYM="GCC" CT_GCC_DIR_NAME="gcc" CT_GCC_USE_GNU=y CT_GCC_USE="GCC" CT_GCC_PKG_NAME="gcc" CT_GCC_SRC_RELEASE=y CT_GCC_PATCH_ORDER="global" CT_GCC_V_8=y # CT_GCC_V_7 is not set # CT_GCC_V_6 is not set # CT_GCC_V_5 is not set # CT_GCC_V_4_9 is not set # CT_GCC_NO_VERSIONS is not set CT_GCC_VERSION="8.3.0" CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_GCC_SIGNATURE_FORMAT="" CT_GCC_later_than_7=y CT_GCC_7_or_later=y CT_GCC_later_than_6=y CT_GCC_6_or_later=y CT_GCC_later_than_5=y CT_GCC_5_or_later=y CT_GCC_later_than_4_9=y CT_GCC_4_9_or_later=y CT_GCC_later_than_4_8=y CT_GCC_4_8_or_later=y CT_CC_GCC_ENABLE_PLUGINS=y CT_CC_GCC_GOLD=y CT_CC_GCC_HAS_LIBMPX=y CT_CC_GCC_ENABLE_CXX_FLAGS="" CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_STATIC_LIBSTDCXX=y # CT_CC_GCC_SYSTEM_ZLIB is not set CT_CC_GCC_CONFIG_TLS=m # # Optimisation features # CT_CC_GCC_USE_GRAPHITE=y CT_CC_GCC_USE_LTO=y # # Settings for libraries running on target # CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y # CT_CC_GCC_LIBMUDFLAP is not set # CT_CC_GCC_LIBGOMP is not set # CT_CC_GCC_LIBSSP is not set # CT_CC_GCC_LIBQUADMATH is not set # CT_CC_GCC_LIBSANITIZER is not set # # Misc. obscure options. # CT_CC_CXA_ATEXIT=y CT_CC_GCC_DISABLE_PCH=y CT_CC_GCC_SJLJ_EXCEPTIONS=m CT_CC_GCC_LDBL_128=m CT_CC_GCC_BUILD_ID=y # CT_CC_GCC_LNK_HASH_STYLE_DEFAULT is not set # CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set # CT_CC_GCC_LNK_HASH_STYLE_GNU is not set CT_CC_GCC_LNK_HASH_STYLE_BOTH=y CT_CC_GCC_LNK_HASH_STYLE="both" CT_CC_GCC_DEC_FLOAT_AUTO=y # CT_CC_GCC_DEC_FLOAT_BID is not set # CT_CC_GCC_DEC_FLOAT_DPD is not set # CT_CC_GCC_DEC_FLOATS_NO is not set CT_ALL_CC_CHOICES="GCC" # # Additional supported languages: # CT_CC_LANG_CXX=y # CT_CC_LANG_FORTRAN is not set # # Debug facilities # # CT_DEBUG_DUMA is not set # CT_DEBUG_GDB is not set # CT_DEBUG_LTRACE is not set # CT_DEBUG_STRACE is not set CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" # # Companion libraries # # CT_COMPLIBS_CHECK is not set # CT_COMP_LIBS_CLOOG is not set CT_COMP_LIBS_EXPAT=y CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" CT_EXPAT_DIR_NAME="expat" CT_EXPAT_PKG_NAME="expat" CT_EXPAT_SRC_RELEASE=y CT_EXPAT_PATCH_ORDER="global" CT_EXPAT_V_2_2=y # CT_EXPAT_NO_VERSIONS is not set CT_EXPAT_VERSION="2.2.6" CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" CT_EXPAT_SIGNATURE_FORMAT="" CT_COMP_LIBS_GETTEXT=y CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" CT_GETTEXT_DIR_NAME="gettext" CT_GETTEXT_PKG_NAME="gettext" CT_GETTEXT_SRC_RELEASE=y CT_GETTEXT_PATCH_ORDER="global" CT_GETTEXT_V_0_19_8_1=y # CT_GETTEXT_NO_VERSIONS is not set CT_GETTEXT_VERSION="0.19.8.1" CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_GMP=y CT_COMP_LIBS_GMP_PKG_KSYM="GMP" CT_GMP_DIR_NAME="gmp" CT_GMP_PKG_NAME="gmp" CT_GMP_SRC_RELEASE=y CT_GMP_PATCH_ORDER="global" CT_GMP_V_6_1=y # CT_GMP_NO_VERSIONS is not set CT_GMP_VERSION="6.1.2" CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" CT_GMP_SIGNATURE_FORMAT="packed/.sig" CT_GMP_later_than_5_1_0=y CT_GMP_5_1_0_or_later=y CT_GMP_later_than_5_0_0=y CT_GMP_5_0_0_or_later=y CT_GMP_REQUIRE_5_0_0_or_later=y CT_COMP_LIBS_ISL=y CT_COMP_LIBS_ISL_PKG_KSYM="ISL" CT_ISL_DIR_NAME="isl" CT_ISL_PKG_NAME="isl" CT_ISL_SRC_RELEASE=y CT_ISL_PATCH_ORDER="global" CT_ISL_V_0_20=y # CT_ISL_V_0_19 is not set # CT_ISL_V_0_18 is not set # CT_ISL_V_0_17 is not set # CT_ISL_V_0_16 is not set # CT_ISL_V_0_15 is not set # CT_ISL_NO_VERSIONS is not set CT_ISL_VERSION="0.20" CT_ISL_MIRRORS="http://isl.gforge.inria.fr" CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_ISL_SIGNATURE_FORMAT="" CT_ISL_later_than_0_18=y CT_ISL_0_18_or_later=y CT_ISL_later_than_0_15=y CT_ISL_0_15_or_later=y CT_ISL_REQUIRE_0_15_or_later=y CT_ISL_later_than_0_14=y CT_ISL_0_14_or_later=y CT_ISL_REQUIRE_0_14_or_later=y CT_ISL_later_than_0_13=y CT_ISL_0_13_or_later=y CT_ISL_later_than_0_12=y CT_ISL_0_12_or_later=y CT_ISL_REQUIRE_0_12_or_later=y # CT_COMP_LIBS_LIBELF is not set CT_COMP_LIBS_LIBICONV=y CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" CT_LIBICONV_DIR_NAME="libiconv" CT_LIBICONV_PKG_NAME="libiconv" CT_LIBICONV_SRC_RELEASE=y CT_LIBICONV_PATCH_ORDER="global" CT_LIBICONV_V_1_15=y # CT_LIBICONV_NO_VERSIONS is not set CT_LIBICONV_VERSION="1.15" CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_MPC=y CT_COMP_LIBS_MPC_PKG_KSYM="MPC" CT_MPC_DIR_NAME="mpc" CT_MPC_PKG_NAME="mpc" CT_MPC_SRC_RELEASE=y CT_MPC_PATCH_ORDER="global" CT_MPC_V_1_1=y # CT_MPC_V_1_0 is not set # CT_MPC_NO_VERSIONS is not set CT_MPC_VERSION="1.1.0" CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_FORMATS=".tar.gz" CT_MPC_SIGNATURE_FORMAT="packed/.sig" CT_MPC_1_1_0_or_later=y CT_MPC_1_1_0_or_older=y CT_COMP_LIBS_MPFR=y CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" CT_MPFR_DIR_NAME="mpfr" CT_MPFR_PKG_NAME="mpfr" CT_MPFR_SRC_RELEASE=y CT_MPFR_PATCH_ORDER="global" CT_MPFR_V_4_0=y # CT_MPFR_V_3_1 is not set # CT_MPFR_NO_VERSIONS is not set CT_MPFR_VERSION="4.0.2" CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" CT_MPFR_SIGNATURE_FORMAT="packed/.asc" CT_MPFR_later_than_4_0_0=y CT_MPFR_4_0_0_or_later=y CT_MPFR_later_than_3_0_0=y CT_MPFR_3_0_0_or_later=y CT_MPFR_REQUIRE_3_0_0_or_later=y CT_COMP_LIBS_NCURSES=y CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" CT_NCURSES_DIR_NAME="ncurses" CT_NCURSES_PKG_NAME="ncurses" CT_NCURSES_SRC_RELEASE=y CT_NCURSES_PATCH_ORDER="global" CT_NCURSES_V_6_1=y # CT_NCURSES_V_6_0 is not set # CT_NCURSES_NO_VERSIONS is not set CT_NCURSES_VERSION="6.1" CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" CT_NCURSES_HOST_CONFIG_ARGS="" CT_NCURSES_HOST_DISABLE_DB=y CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" CT_NCURSES_TARGET_CONFIG_ARGS="" # CT_NCURSES_TARGET_DISABLE_DB is not set CT_NCURSES_TARGET_FALLBACKS="" CT_COMP_LIBS_ZLIB=y CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" CT_ZLIB_DIR_NAME="zlib" CT_ZLIB_PKG_NAME="zlib" CT_ZLIB_SRC_RELEASE=y CT_ZLIB_PATCH_ORDER="global" CT_ZLIB_V_1_2_11=y # CT_ZLIB_NO_VERSIONS is not set CT_ZLIB_VERSION="1.2.11" CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" CT_LIBICONV_NEEDED=y CT_GETTEXT_NEEDED=y CT_GMP_NEEDED=y CT_MPFR_NEEDED=y CT_ISL_NEEDED=y CT_MPC_NEEDED=y CT_NCURSES_NEEDED=y CT_ZLIB_NEEDED=y CT_LIBICONV=y CT_GETTEXT=y CT_GMP=y CT_MPFR=y CT_ISL=y CT_MPC=y CT_NCURSES=y CT_ZLIB=y # # Companion tools # # CT_COMP_TOOLS_FOR_HOST is not set # CT_COMP_TOOLS_AUTOCONF is not set # CT_COMP_TOOLS_AUTOMAKE is not set # CT_COMP_TOOLS_BISON is not set # CT_COMP_TOOLS_DTC is not set # CT_COMP_TOOLS_LIBTOOL is not set # CT_COMP_TOOLS_M4 is not set # CT_COMP_TOOLS_MAKE is not set CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" ================================================ FILE: tools/toolchain_builder/toolchains/mips-unknown-linux-gnu/gcc-8.3.0-glibc-2.19-kernel-4.9.config ================================================ # # Automatically generated file; DO NOT EDIT. # crosstool-NG Configuration # CT_CONFIGURE_has_static_link=y CT_CONFIGURE_has_cxx11=y CT_CONFIGURE_has_wget=y CT_CONFIGURE_has_curl=y CT_CONFIGURE_has_make_3_81_or_newer=y CT_CONFIGURE_has_make_4_0_or_newer=y CT_CONFIGURE_has_libtool_2_4_or_newer=y CT_CONFIGURE_has_libtoolize_2_4_or_newer=y CT_CONFIGURE_has_autoconf_2_65_or_newer=y CT_CONFIGURE_has_autoreconf_2_65_or_newer=y CT_CONFIGURE_has_automake_1_15_or_newer=y CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y CT_CONFIGURE_has_python_3_4_or_newer=y CT_CONFIGURE_has_bison_2_7_or_newer=y CT_CONFIGURE_has_python=y CT_CONFIGURE_has_git=y CT_CONFIGURE_has_md5sum=y CT_CONFIGURE_has_sha1sum=y CT_CONFIGURE_has_sha256sum=y CT_CONFIGURE_has_sha512sum=y CT_CONFIGURE_has_install_with_strip_program=y CT_CONFIG_VERSION_CURRENT="3" CT_CONFIG_VERSION="3" CT_MODULES=y # # Paths and misc options # # # crosstool-NG behavior # # CT_OBSOLETE is not set # CT_EXPERIMENTAL is not set # CT_DEBUG_CT is not set # # Paths # CT_LOCAL_TARBALLS_DIR="${HOME}/src" CT_SAVE_TARBALLS=y # CT_TARBALLS_BUILDROOT_LAYOUT is not set CT_WORK_DIR="${CT_TOP_DIR}/.build" CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_RM_RF_PREFIX_DIR=y CT_REMOVE_DOCS=y CT_INSTALL_LICENSES=y # CT_PREFIX_DIR_RO is not set CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES=y # # Downloading # CT_DOWNLOAD_AGENT_WGET=y # CT_DOWNLOAD_AGENT_CURL is not set # CT_DOWNLOAD_AGENT_NONE is not set # CT_FORBID_DOWNLOAD is not set # CT_FORCE_DOWNLOAD is not set CT_CONNECT_TIMEOUT=10 CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" # CT_ONLY_DOWNLOAD is not set # CT_USE_MIRROR is not set CT_VERIFY_DOWNLOAD_DIGEST=y CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y # CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set # CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set # CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" # CT_VERIFY_DOWNLOAD_SIGNATURE is not set # # Extracting # # CT_FORCE_EXTRACT is not set CT_OVERRIDE_CONFIG_GUESS_SUB=y # CT_ONLY_EXTRACT is not set CT_PATCH_BUNDLED=y # CT_PATCH_BUNDLED_LOCAL is not set CT_PATCH_ORDER="bundled" # # Build behavior # CT_PARALLEL_JOBS=0 CT_LOAD="" CT_USE_PIPES=y CT_EXTRA_CFLAGS_FOR_BUILD="" CT_EXTRA_LDFLAGS_FOR_BUILD="" CT_EXTRA_CFLAGS_FOR_HOST="" CT_EXTRA_LDFLAGS_FOR_HOST="" # CT_CONFIG_SHELL_SH is not set # CT_CONFIG_SHELL_ASH is not set CT_CONFIG_SHELL_BASH=y # CT_CONFIG_SHELL_CUSTOM is not set CT_CONFIG_SHELL="${bash}" # # Logging # # CT_LOG_ERROR is not set # CT_LOG_WARN is not set # CT_LOG_INFO is not set CT_LOG_EXTRA=y # CT_LOG_ALL is not set # CT_LOG_DEBUG is not set CT_LOG_LEVEL_MAX="EXTRA" # CT_LOG_SEE_TOOLS_WARN is not set CT_LOG_PROGRESS_BAR=y CT_LOG_TO_FILE=y CT_LOG_FILE_COMPRESS=y # # Target options # # CT_ARCH_ALPHA is not set # CT_ARCH_ARC is not set # CT_ARCH_ARM is not set # CT_ARCH_AVR is not set # CT_ARCH_M68K is not set CT_ARCH_MIPS=y # CT_ARCH_NIOS2 is not set # CT_ARCH_POWERPC is not set # CT_ARCH_S390 is not set # CT_ARCH_SH is not set # CT_ARCH_SPARC is not set # CT_ARCH_X86 is not set # CT_ARCH_XTENSA is not set CT_ARCH="mips" CT_ARCH_CHOICE_KSYM="MIPS" CT_ARCH_TUNE="" CT_ARCH_MIPS_SHOW=y # # Options for mips # CT_ARCH_MIPS_PKG_KSYM="" CT_ARCH_mips_o32=y CT_ARCH_mips_ABI="32" CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" CT_ARCH_SUFFIX="" # CT_OMIT_TARGET_VENDOR is not set # # Generic target options # # CT_MULTILIB is not set CT_DEMULTILIB=y CT_ARCH_USE_MMU=y CT_ARCH_SUPPORTS_EITHER_ENDIAN=y CT_ARCH_DEFAULT_BE=y CT_ARCH_BE=y # CT_ARCH_LE is not set CT_ARCH_ENDIAN="big" CT_ARCH_SUPPORTS_32=y CT_ARCH_SUPPORTS_64=y CT_ARCH_DEFAULT_32=y CT_ARCH_BITNESS=32 CT_ARCH_32=y # CT_ARCH_64 is not set # # Target optimisations # CT_ARCH_SUPPORTS_WITH_ARCH=y CT_ARCH_SUPPORTS_WITH_TUNE=y CT_ARCH_SUPPORTS_WITH_FLOAT=y CT_ARCH_ARCH="mips1" # CT_ARCH_FLOAT_AUTO is not set # CT_ARCH_FLOAT_HW is not set CT_ARCH_FLOAT_SW=y CT_TARGET_CFLAGS="" CT_TARGET_LDFLAGS="" CT_ARCH_FLOAT="hard" # # Toolchain options # # # General toolchain options # CT_FORCE_SYSROOT=y CT_USE_SYSROOT=y CT_SYSROOT_NAME="sysroot" CT_SYSROOT_DIR_PREFIX="" CT_WANTS_STATIC_LINK=y CT_WANTS_STATIC_LINK_CXX=y # CT_STATIC_TOOLCHAIN is not set CT_SHOW_CT_VERSION=y CT_TOOLCHAIN_PKGVERSION="" CT_TOOLCHAIN_BUGURL="" # # Tuple completion and aliasing # CT_TARGET_VENDOR="unknown" CT_TARGET_ALIAS_SED_EXPR="" CT_TARGET_ALIAS="" # # Toolchain type # CT_CROSS=y # CT_CANADIAN is not set CT_TOOLCHAIN_TYPE="cross" # # Build system # CT_BUILD="" CT_BUILD_PREFIX="" CT_BUILD_SUFFIX="" # # Misc options # # CT_TOOLCHAIN_ENABLE_NLS is not set # # Operating System # CT_KERNEL_SUPPORTS_SHARED_LIBS=y # CT_KERNEL_BARE_METAL is not set CT_KERNEL_LINUX=y CT_KERNEL="linux" CT_KERNEL_CHOICE_KSYM="LINUX" CT_KERNEL_LINUX_SHOW=y # # Options for linux # CT_KERNEL_LINUX_PKG_KSYM="LINUX" CT_LINUX_DIR_NAME="linux" CT_LINUX_PKG_NAME="linux" CT_LINUX_SRC_RELEASE=y CT_LINUX_PATCH_ORDER="global" # CT_LINUX_V_4_20 is not set # CT_LINUX_V_4_19 is not set # CT_LINUX_V_4_18 is not set # CT_LINUX_V_4_17 is not set # CT_LINUX_V_4_16 is not set # CT_LINUX_V_4_15 is not set # CT_LINUX_V_4_14 is not set # CT_LINUX_V_4_13 is not set # CT_LINUX_V_4_12 is not set # CT_LINUX_V_4_11 is not set # CT_LINUX_V_4_10 is not set CT_LINUX_V_4_9=y # CT_LINUX_V_4_4 is not set # CT_LINUX_V_4_1 is not set # CT_LINUX_V_3_16 is not set # CT_LINUX_V_3_13 is not set # CT_LINUX_V_3_12 is not set # CT_LINUX_V_3_10 is not set # CT_LINUX_V_3_4 is not set # CT_LINUX_V_3_2 is not set # CT_LINUX_V_2_6_32 is not set # CT_LINUX_NO_VERSIONS is not set CT_LINUX_VERSION="4.9.156" CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" CT_LINUX_later_than_4_8=y CT_LINUX_4_8_or_later=y CT_LINUX_later_than_3_7=y CT_LINUX_3_7_or_later=y CT_LINUX_later_than_3_2=y CT_LINUX_3_2_or_later=y CT_KERNEL_LINUX_VERBOSITY_0=y # CT_KERNEL_LINUX_VERBOSITY_1 is not set # CT_KERNEL_LINUX_VERBOSITY_2 is not set CT_KERNEL_LINUX_VERBOSE_LEVEL=0 CT_KERNEL_LINUX_INSTALL_CHECK=y CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" # # Common kernel options # CT_SHARED_LIBS=y # # Binary utilities # CT_ARCH_BINFMT_ELF=y CT_BINUTILS_BINUTILS=y CT_BINUTILS="binutils" CT_BINUTILS_CHOICE_KSYM="BINUTILS" CT_BINUTILS_BINUTILS_SHOW=y # # Options for binutils # CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" CT_BINUTILS_DIR_NAME="binutils" CT_BINUTILS_USE_GNU=y CT_BINUTILS_USE="BINUTILS" CT_BINUTILS_PKG_NAME="binutils" CT_BINUTILS_SRC_RELEASE=y CT_BINUTILS_PATCH_ORDER="global" CT_BINUTILS_V_2_32=y # CT_BINUTILS_V_2_31 is not set # CT_BINUTILS_V_2_30 is not set # CT_BINUTILS_V_2_29 is not set # CT_BINUTILS_V_2_28 is not set # CT_BINUTILS_V_2_27 is not set # CT_BINUTILS_V_2_26 is not set # CT_BINUTILS_NO_VERSIONS is not set CT_BINUTILS_VERSION="2.32" CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" CT_BINUTILS_later_than_2_30=y CT_BINUTILS_2_30_or_later=y CT_BINUTILS_later_than_2_27=y CT_BINUTILS_2_27_or_later=y CT_BINUTILS_later_than_2_25=y CT_BINUTILS_2_25_or_later=y CT_BINUTILS_later_than_2_23=y CT_BINUTILS_2_23_or_later=y # # GNU binutils # CT_BINUTILS_HAS_HASH_STYLE=y CT_BINUTILS_HAS_GOLD=y CT_BINUTILS_HAS_PLUGINS=y CT_BINUTILS_HAS_PKGVERSION_BUGURL=y CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y CT_BINUTILS_LINKER_LD=y CT_BINUTILS_LINKERS_LIST="ld" CT_BINUTILS_LINKER_DEFAULT="bfd" CT_BINUTILS_PLUGINS=y CT_BINUTILS_RELRO=m CT_BINUTILS_EXTRA_CONFIG_ARRAY="" # CT_BINUTILS_FOR_TARGET is not set CT_ALL_BINUTILS_CHOICES="BINUTILS" # # C-library # CT_LIBC_GLIBC=y # CT_LIBC_UCLIBC is not set CT_LIBC="glibc" CT_LIBC_CHOICE_KSYM="GLIBC" CT_THREADS="nptl" CT_LIBC_GLIBC_SHOW=y # # Options for glibc # CT_LIBC_GLIBC_PKG_KSYM="GLIBC" CT_GLIBC_DIR_NAME="glibc" CT_GLIBC_USE_GNU=y CT_GLIBC_USE="GLIBC" CT_GLIBC_PKG_NAME="glibc" CT_GLIBC_SRC_RELEASE=y CT_GLIBC_PATCH_ORDER="global" # CT_GLIBC_V_2_29 is not set # CT_GLIBC_V_2_28 is not set # CT_GLIBC_V_2_27 is not set # CT_GLIBC_V_2_26 is not set # CT_GLIBC_V_2_25 is not set # CT_GLIBC_V_2_24 is not set # CT_GLIBC_V_2_23 is not set CT_GLIBC_V_2_19=y # CT_GLIBC_V_2_17 is not set # CT_GLIBC_V_2_12_1 is not set # CT_GLIBC_NO_VERSIONS is not set CT_GLIBC_VERSION="2.19" CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" CT_GLIBC_2_29_or_older=y CT_GLIBC_older_than_2_29=y CT_GLIBC_2_27_or_older=y CT_GLIBC_older_than_2_27=y CT_GLIBC_2_26_or_older=y CT_GLIBC_older_than_2_26=y CT_GLIBC_2_25_or_older=y CT_GLIBC_older_than_2_25=y CT_GLIBC_2_24_or_older=y CT_GLIBC_older_than_2_24=y CT_GLIBC_2_23_or_older=y CT_GLIBC_older_than_2_23=y CT_GLIBC_2_20_or_older=y CT_GLIBC_older_than_2_20=y CT_GLIBC_later_than_2_17=y CT_GLIBC_2_17_or_later=y CT_GLIBC_later_than_2_14=y CT_GLIBC_2_14_or_later=y CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y CT_GLIBC_DEP_BINUTILS=y CT_GLIBC_DEP_GCC=y CT_GLIBC_DEP_PYTHON=y CT_GLIBC_HAS_NPTL_ADDON=y CT_GLIBC_HAS_PORTS_ADDON=y CT_GLIBC_HAS_LIBIDN_ADDON=y CT_GLIBC_USE_PORTS_ADDON=y CT_GLIBC_USE_NPTL_ADDON=y # CT_GLIBC_USE_LIBIDN_ADDON is not set CT_GLIBC_HAS_OBSOLETE_RPC=y CT_GLIBC_EXTRA_CONFIG_ARRAY="" CT_GLIBC_CONFIGPARMS="" CT_GLIBC_EXTRA_CFLAGS="" CT_GLIBC_ENABLE_OBSOLETE_RPC=y # CT_GLIBC_DISABLE_VERSIONING is not set CT_GLIBC_OLDEST_ABI="" CT_GLIBC_FORCE_UNWIND=y # CT_GLIBC_LOCALES is not set # CT_GLIBC_KERNEL_VERSION_NONE is not set CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y # CT_GLIBC_KERNEL_VERSION_CHOSEN is not set CT_GLIBC_MIN_KERNEL="4.9.156" CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" CT_LIBC_SUPPORT_THREADS_ANY=y CT_LIBC_SUPPORT_THREADS_NATIVE=y # # Common C library options # CT_THREADS_NATIVE=y # CT_CREATE_LDSO_CONF is not set CT_LIBC_XLDD=y # # C compiler # CT_CC_CORE_PASSES_NEEDED=y CT_CC_CORE_PASS_1_NEEDED=y CT_CC_CORE_PASS_2_NEEDED=y CT_CC_SUPPORT_CXX=y CT_CC_SUPPORT_FORTRAN=y CT_CC_SUPPORT_ADA=y CT_CC_SUPPORT_OBJC=y CT_CC_SUPPORT_OBJCXX=y CT_CC_SUPPORT_GOLANG=y CT_CC_GCC=y CT_CC="gcc" CT_CC_CHOICE_KSYM="GCC" CT_CC_GCC_SHOW=y # # Options for gcc # CT_CC_GCC_PKG_KSYM="GCC" CT_GCC_DIR_NAME="gcc" CT_GCC_USE_GNU=y CT_GCC_USE="GCC" CT_GCC_PKG_NAME="gcc" CT_GCC_SRC_RELEASE=y CT_GCC_PATCH_ORDER="global" CT_GCC_V_8=y # CT_GCC_V_7 is not set # CT_GCC_V_6 is not set # CT_GCC_V_5 is not set # CT_GCC_V_4_9 is not set # CT_GCC_NO_VERSIONS is not set CT_GCC_VERSION="8.3.0" CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_GCC_SIGNATURE_FORMAT="" CT_GCC_later_than_7=y CT_GCC_7_or_later=y CT_GCC_later_than_6=y CT_GCC_6_or_later=y CT_GCC_later_than_5=y CT_GCC_5_or_later=y CT_GCC_later_than_4_9=y CT_GCC_4_9_or_later=y CT_GCC_later_than_4_8=y CT_GCC_4_8_or_later=y CT_CC_GCC_ENABLE_PLUGINS=y CT_CC_GCC_HAS_LIBMPX=y CT_CC_GCC_ENABLE_CXX_FLAGS="" CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_STATIC_LIBSTDCXX=y # CT_CC_GCC_SYSTEM_ZLIB is not set CT_CC_GCC_CONFIG_TLS=m # # Optimisation features # CT_CC_GCC_USE_GRAPHITE=y CT_CC_GCC_USE_LTO=y # # Settings for libraries running on target # CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y # CT_CC_GCC_LIBMUDFLAP is not set # CT_CC_GCC_LIBGOMP is not set # CT_CC_GCC_LIBSSP is not set # CT_CC_GCC_LIBQUADMATH is not set # CT_CC_GCC_LIBSANITIZER is not set # # Misc. obscure options. # CT_CC_CXA_ATEXIT=y # CT_CC_GCC_DISABLE_PCH is not set CT_CC_GCC_SJLJ_EXCEPTIONS=m CT_CC_GCC_LDBL_128=m # CT_CC_GCC_BUILD_ID is not set CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y # CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set # CT_CC_GCC_LNK_HASH_STYLE_GNU is not set # CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set CT_CC_GCC_LNK_HASH_STYLE="" CT_CC_GCC_DEC_FLOAT_AUTO=y # CT_CC_GCC_DEC_FLOAT_BID is not set # CT_CC_GCC_DEC_FLOAT_DPD is not set # CT_CC_GCC_DEC_FLOATS_NO is not set CT_CC_GCC_HAS_ARCH_OPTIONS=y # # archictecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m CT_CC_GCC_mips_plt=y CT_ALL_CC_CHOICES="GCC" # # Additional supported languages: # CT_CC_LANG_CXX=y # CT_CC_LANG_FORTRAN is not set # # Debug facilities # # CT_DEBUG_DUMA is not set # CT_DEBUG_GDB is not set # CT_DEBUG_LTRACE is not set # CT_DEBUG_STRACE is not set CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" # # Companion libraries # # CT_COMPLIBS_CHECK is not set # CT_COMP_LIBS_CLOOG is not set CT_COMP_LIBS_EXPAT=y CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" CT_EXPAT_DIR_NAME="expat" CT_EXPAT_PKG_NAME="expat" CT_EXPAT_SRC_RELEASE=y CT_EXPAT_PATCH_ORDER="global" CT_EXPAT_V_2_2=y # CT_EXPAT_NO_VERSIONS is not set CT_EXPAT_VERSION="2.2.6" CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" CT_EXPAT_SIGNATURE_FORMAT="" CT_COMP_LIBS_GETTEXT=y CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" CT_GETTEXT_DIR_NAME="gettext" CT_GETTEXT_PKG_NAME="gettext" CT_GETTEXT_SRC_RELEASE=y CT_GETTEXT_PATCH_ORDER="global" CT_GETTEXT_V_0_19_8_1=y # CT_GETTEXT_NO_VERSIONS is not set CT_GETTEXT_VERSION="0.19.8.1" CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_GMP=y CT_COMP_LIBS_GMP_PKG_KSYM="GMP" CT_GMP_DIR_NAME="gmp" CT_GMP_PKG_NAME="gmp" CT_GMP_SRC_RELEASE=y CT_GMP_PATCH_ORDER="global" CT_GMP_V_6_1=y # CT_GMP_NO_VERSIONS is not set CT_GMP_VERSION="6.1.2" CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" CT_GMP_SIGNATURE_FORMAT="packed/.sig" CT_GMP_later_than_5_1_0=y CT_GMP_5_1_0_or_later=y CT_GMP_later_than_5_0_0=y CT_GMP_5_0_0_or_later=y CT_GMP_REQUIRE_5_0_0_or_later=y CT_COMP_LIBS_ISL=y CT_COMP_LIBS_ISL_PKG_KSYM="ISL" CT_ISL_DIR_NAME="isl" CT_ISL_PKG_NAME="isl" CT_ISL_SRC_RELEASE=y CT_ISL_PATCH_ORDER="global" CT_ISL_V_0_20=y # CT_ISL_V_0_19 is not set # CT_ISL_V_0_18 is not set # CT_ISL_V_0_17 is not set # CT_ISL_V_0_16 is not set # CT_ISL_V_0_15 is not set # CT_ISL_NO_VERSIONS is not set CT_ISL_VERSION="0.20" CT_ISL_MIRRORS="http://isl.gforge.inria.fr" CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_ISL_SIGNATURE_FORMAT="" CT_ISL_later_than_0_18=y CT_ISL_0_18_or_later=y CT_ISL_later_than_0_15=y CT_ISL_0_15_or_later=y CT_ISL_REQUIRE_0_15_or_later=y CT_ISL_later_than_0_14=y CT_ISL_0_14_or_later=y CT_ISL_REQUIRE_0_14_or_later=y CT_ISL_later_than_0_13=y CT_ISL_0_13_or_later=y CT_ISL_later_than_0_12=y CT_ISL_0_12_or_later=y CT_ISL_REQUIRE_0_12_or_later=y # CT_COMP_LIBS_LIBELF is not set CT_COMP_LIBS_LIBICONV=y CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" CT_LIBICONV_DIR_NAME="libiconv" CT_LIBICONV_PKG_NAME="libiconv" CT_LIBICONV_SRC_RELEASE=y CT_LIBICONV_PATCH_ORDER="global" CT_LIBICONV_V_1_15=y # CT_LIBICONV_NO_VERSIONS is not set CT_LIBICONV_VERSION="1.15" CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_MPC=y CT_COMP_LIBS_MPC_PKG_KSYM="MPC" CT_MPC_DIR_NAME="mpc" CT_MPC_PKG_NAME="mpc" CT_MPC_SRC_RELEASE=y CT_MPC_PATCH_ORDER="global" CT_MPC_V_1_1=y # CT_MPC_V_1_0 is not set # CT_MPC_NO_VERSIONS is not set CT_MPC_VERSION="1.1.0" CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_FORMATS=".tar.gz" CT_MPC_SIGNATURE_FORMAT="packed/.sig" CT_MPC_1_1_0_or_later=y CT_MPC_1_1_0_or_older=y CT_COMP_LIBS_MPFR=y CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" CT_MPFR_DIR_NAME="mpfr" CT_MPFR_PKG_NAME="mpfr" CT_MPFR_SRC_RELEASE=y CT_MPFR_PATCH_ORDER="global" CT_MPFR_V_4_0=y # CT_MPFR_V_3_1 is not set # CT_MPFR_NO_VERSIONS is not set CT_MPFR_VERSION="4.0.2" CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" CT_MPFR_SIGNATURE_FORMAT="packed/.asc" CT_MPFR_later_than_4_0_0=y CT_MPFR_4_0_0_or_later=y CT_MPFR_later_than_3_0_0=y CT_MPFR_3_0_0_or_later=y CT_MPFR_REQUIRE_3_0_0_or_later=y CT_COMP_LIBS_NCURSES=y CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" CT_NCURSES_DIR_NAME="ncurses" CT_NCURSES_PKG_NAME="ncurses" CT_NCURSES_SRC_RELEASE=y CT_NCURSES_PATCH_ORDER="global" CT_NCURSES_V_6_1=y # CT_NCURSES_V_6_0 is not set # CT_NCURSES_NO_VERSIONS is not set CT_NCURSES_VERSION="6.1" CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" CT_NCURSES_HOST_CONFIG_ARGS="" CT_NCURSES_HOST_DISABLE_DB=y CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" CT_NCURSES_TARGET_CONFIG_ARGS="" # CT_NCURSES_TARGET_DISABLE_DB is not set CT_NCURSES_TARGET_FALLBACKS="" CT_COMP_LIBS_ZLIB=y CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" CT_ZLIB_DIR_NAME="zlib" CT_ZLIB_PKG_NAME="zlib" CT_ZLIB_SRC_RELEASE=y CT_ZLIB_PATCH_ORDER="global" CT_ZLIB_V_1_2_11=y # CT_ZLIB_NO_VERSIONS is not set CT_ZLIB_VERSION="1.2.11" CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" CT_LIBICONV_NEEDED=y CT_GETTEXT_NEEDED=y CT_GMP_NEEDED=y CT_MPFR_NEEDED=y CT_ISL_NEEDED=y CT_MPC_NEEDED=y CT_NCURSES_NEEDED=y CT_ZLIB_NEEDED=y CT_LIBICONV=y CT_GETTEXT=y CT_GMP=y CT_MPFR=y CT_ISL=y CT_MPC=y CT_NCURSES=y CT_ZLIB=y # # Companion tools # # CT_COMP_TOOLS_FOR_HOST is not set # CT_COMP_TOOLS_AUTOCONF is not set # CT_COMP_TOOLS_AUTOMAKE is not set # CT_COMP_TOOLS_BISON is not set # CT_COMP_TOOLS_DTC is not set # CT_COMP_TOOLS_LIBTOOL is not set # CT_COMP_TOOLS_M4 is not set # CT_COMP_TOOLS_MAKE is not set CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" ================================================ FILE: tools/toolchain_builder/toolchains/mipsel-unknown-linux-gnu/gcc-8.3.0-glibc-2.19-kernel-4.9.config ================================================ # # Automatically generated file; DO NOT EDIT. # crosstool-NG Configuration # CT_CONFIGURE_has_static_link=y CT_CONFIGURE_has_cxx11=y CT_CONFIGURE_has_wget=y CT_CONFIGURE_has_curl=y CT_CONFIGURE_has_make_3_81_or_newer=y CT_CONFIGURE_has_make_4_0_or_newer=y CT_CONFIGURE_has_libtool_2_4_or_newer=y CT_CONFIGURE_has_libtoolize_2_4_or_newer=y CT_CONFIGURE_has_autoconf_2_65_or_newer=y CT_CONFIGURE_has_autoreconf_2_65_or_newer=y CT_CONFIGURE_has_automake_1_15_or_newer=y CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y CT_CONFIGURE_has_python_3_4_or_newer=y CT_CONFIGURE_has_bison_2_7_or_newer=y CT_CONFIGURE_has_python=y CT_CONFIGURE_has_git=y CT_CONFIGURE_has_md5sum=y CT_CONFIGURE_has_sha1sum=y CT_CONFIGURE_has_sha256sum=y CT_CONFIGURE_has_sha512sum=y CT_CONFIGURE_has_install_with_strip_program=y CT_CONFIG_VERSION_CURRENT="3" CT_CONFIG_VERSION="3" CT_MODULES=y # # Paths and misc options # # # crosstool-NG behavior # # CT_OBSOLETE is not set # CT_EXPERIMENTAL is not set # CT_DEBUG_CT is not set # # Paths # CT_LOCAL_TARBALLS_DIR="${HOME}/src" CT_SAVE_TARBALLS=y # CT_TARBALLS_BUILDROOT_LAYOUT is not set CT_WORK_DIR="${CT_TOP_DIR}/.build" CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_RM_RF_PREFIX_DIR=y CT_REMOVE_DOCS=y CT_INSTALL_LICENSES=y # CT_PREFIX_DIR_RO is not set CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES=y # # Downloading # CT_DOWNLOAD_AGENT_WGET=y # CT_DOWNLOAD_AGENT_CURL is not set # CT_DOWNLOAD_AGENT_NONE is not set # CT_FORBID_DOWNLOAD is not set # CT_FORCE_DOWNLOAD is not set CT_CONNECT_TIMEOUT=10 CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" # CT_ONLY_DOWNLOAD is not set # CT_USE_MIRROR is not set CT_VERIFY_DOWNLOAD_DIGEST=y CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y # CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set # CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set # CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" # CT_VERIFY_DOWNLOAD_SIGNATURE is not set # # Extracting # # CT_FORCE_EXTRACT is not set CT_OVERRIDE_CONFIG_GUESS_SUB=y # CT_ONLY_EXTRACT is not set CT_PATCH_BUNDLED=y # CT_PATCH_BUNDLED_LOCAL is not set CT_PATCH_ORDER="bundled" # # Build behavior # CT_PARALLEL_JOBS=0 CT_LOAD="" CT_USE_PIPES=y CT_EXTRA_CFLAGS_FOR_BUILD="" CT_EXTRA_LDFLAGS_FOR_BUILD="" CT_EXTRA_CFLAGS_FOR_HOST="" CT_EXTRA_LDFLAGS_FOR_HOST="" # CT_CONFIG_SHELL_SH is not set # CT_CONFIG_SHELL_ASH is not set CT_CONFIG_SHELL_BASH=y # CT_CONFIG_SHELL_CUSTOM is not set CT_CONFIG_SHELL="${bash}" # # Logging # # CT_LOG_ERROR is not set # CT_LOG_WARN is not set # CT_LOG_INFO is not set CT_LOG_EXTRA=y # CT_LOG_ALL is not set # CT_LOG_DEBUG is not set CT_LOG_LEVEL_MAX="EXTRA" # CT_LOG_SEE_TOOLS_WARN is not set CT_LOG_PROGRESS_BAR=y CT_LOG_TO_FILE=y CT_LOG_FILE_COMPRESS=y # # Target options # # CT_ARCH_ALPHA is not set # CT_ARCH_ARC is not set # CT_ARCH_ARM is not set # CT_ARCH_AVR is not set # CT_ARCH_M68K is not set CT_ARCH_MIPS=y # CT_ARCH_NIOS2 is not set # CT_ARCH_POWERPC is not set # CT_ARCH_S390 is not set # CT_ARCH_SH is not set # CT_ARCH_SPARC is not set # CT_ARCH_X86 is not set # CT_ARCH_XTENSA is not set CT_ARCH="mips" CT_ARCH_CHOICE_KSYM="MIPS" CT_ARCH_TUNE="" CT_ARCH_MIPS_SHOW=y # # Options for mips # CT_ARCH_MIPS_PKG_KSYM="" CT_ARCH_mips_o32=y CT_ARCH_mips_ABI="32" CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" CT_ARCH_SUFFIX="" # CT_OMIT_TARGET_VENDOR is not set # # Generic target options # # CT_MULTILIB is not set CT_DEMULTILIB=y CT_ARCH_USE_MMU=y CT_ARCH_SUPPORTS_EITHER_ENDIAN=y CT_ARCH_DEFAULT_BE=y # CT_ARCH_BE is not set CT_ARCH_LE=y CT_ARCH_ENDIAN="little" CT_ARCH_SUPPORTS_32=y CT_ARCH_SUPPORTS_64=y CT_ARCH_DEFAULT_32=y CT_ARCH_BITNESS=32 CT_ARCH_32=y # CT_ARCH_64 is not set # # Target optimisations # CT_ARCH_SUPPORTS_WITH_ARCH=y CT_ARCH_SUPPORTS_WITH_TUNE=y CT_ARCH_SUPPORTS_WITH_FLOAT=y CT_ARCH_ARCH="mips1" # CT_ARCH_FLOAT_AUTO is not set # CT_ARCH_FLOAT_HW is not set CT_ARCH_FLOAT_SW=y CT_TARGET_CFLAGS="" CT_TARGET_LDFLAGS="" CT_ARCH_FLOAT="hard" # # Toolchain options # # # General toolchain options # CT_FORCE_SYSROOT=y CT_USE_SYSROOT=y CT_SYSROOT_NAME="sysroot" CT_SYSROOT_DIR_PREFIX="" CT_WANTS_STATIC_LINK=y CT_WANTS_STATIC_LINK_CXX=y # CT_STATIC_TOOLCHAIN is not set CT_SHOW_CT_VERSION=y CT_TOOLCHAIN_PKGVERSION="" CT_TOOLCHAIN_BUGURL="" # # Tuple completion and aliasing # CT_TARGET_VENDOR="unknown" CT_TARGET_ALIAS_SED_EXPR="" CT_TARGET_ALIAS="" # # Toolchain type # CT_CROSS=y # CT_CANADIAN is not set CT_TOOLCHAIN_TYPE="cross" # # Build system # CT_BUILD="" CT_BUILD_PREFIX="" CT_BUILD_SUFFIX="" # # Misc options # # CT_TOOLCHAIN_ENABLE_NLS is not set # # Operating System # CT_KERNEL_SUPPORTS_SHARED_LIBS=y # CT_KERNEL_BARE_METAL is not set CT_KERNEL_LINUX=y CT_KERNEL="linux" CT_KERNEL_CHOICE_KSYM="LINUX" CT_KERNEL_LINUX_SHOW=y # # Options for linux # CT_KERNEL_LINUX_PKG_KSYM="LINUX" CT_LINUX_DIR_NAME="linux" CT_LINUX_PKG_NAME="linux" CT_LINUX_SRC_RELEASE=y CT_LINUX_PATCH_ORDER="global" # CT_LINUX_V_4_20 is not set # CT_LINUX_V_4_19 is not set # CT_LINUX_V_4_18 is not set # CT_LINUX_V_4_17 is not set # CT_LINUX_V_4_16 is not set # CT_LINUX_V_4_15 is not set # CT_LINUX_V_4_14 is not set # CT_LINUX_V_4_13 is not set # CT_LINUX_V_4_12 is not set # CT_LINUX_V_4_11 is not set # CT_LINUX_V_4_10 is not set CT_LINUX_V_4_9=y # CT_LINUX_V_4_4 is not set # CT_LINUX_V_4_1 is not set # CT_LINUX_V_3_16 is not set # CT_LINUX_V_3_13 is not set # CT_LINUX_V_3_12 is not set # CT_LINUX_V_3_10 is not set # CT_LINUX_V_3_4 is not set # CT_LINUX_V_3_2 is not set # CT_LINUX_V_2_6_32 is not set # CT_LINUX_NO_VERSIONS is not set CT_LINUX_VERSION="4.9.156" CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" CT_LINUX_later_than_4_8=y CT_LINUX_4_8_or_later=y CT_LINUX_later_than_3_7=y CT_LINUX_3_7_or_later=y CT_LINUX_later_than_3_2=y CT_LINUX_3_2_or_later=y CT_KERNEL_LINUX_VERBOSITY_0=y # CT_KERNEL_LINUX_VERBOSITY_1 is not set # CT_KERNEL_LINUX_VERBOSITY_2 is not set CT_KERNEL_LINUX_VERBOSE_LEVEL=0 CT_KERNEL_LINUX_INSTALL_CHECK=y CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" # # Common kernel options # CT_SHARED_LIBS=y # # Binary utilities # CT_ARCH_BINFMT_ELF=y CT_BINUTILS_BINUTILS=y CT_BINUTILS="binutils" CT_BINUTILS_CHOICE_KSYM="BINUTILS" CT_BINUTILS_BINUTILS_SHOW=y # # Options for binutils # CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" CT_BINUTILS_DIR_NAME="binutils" CT_BINUTILS_USE_GNU=y CT_BINUTILS_USE="BINUTILS" CT_BINUTILS_PKG_NAME="binutils" CT_BINUTILS_SRC_RELEASE=y CT_BINUTILS_PATCH_ORDER="global" CT_BINUTILS_V_2_32=y # CT_BINUTILS_V_2_31 is not set # CT_BINUTILS_V_2_30 is not set # CT_BINUTILS_V_2_29 is not set # CT_BINUTILS_V_2_28 is not set # CT_BINUTILS_V_2_27 is not set # CT_BINUTILS_V_2_26 is not set # CT_BINUTILS_NO_VERSIONS is not set CT_BINUTILS_VERSION="2.32" CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" CT_BINUTILS_later_than_2_30=y CT_BINUTILS_2_30_or_later=y CT_BINUTILS_later_than_2_27=y CT_BINUTILS_2_27_or_later=y CT_BINUTILS_later_than_2_25=y CT_BINUTILS_2_25_or_later=y CT_BINUTILS_later_than_2_23=y CT_BINUTILS_2_23_or_later=y # # GNU binutils # CT_BINUTILS_HAS_HASH_STYLE=y CT_BINUTILS_HAS_GOLD=y CT_BINUTILS_HAS_PLUGINS=y CT_BINUTILS_HAS_PKGVERSION_BUGURL=y CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y CT_BINUTILS_LINKER_LD=y CT_BINUTILS_LINKERS_LIST="ld" CT_BINUTILS_LINKER_DEFAULT="bfd" CT_BINUTILS_PLUGINS=y CT_BINUTILS_RELRO=m CT_BINUTILS_EXTRA_CONFIG_ARRAY="" # CT_BINUTILS_FOR_TARGET is not set CT_ALL_BINUTILS_CHOICES="BINUTILS" # # C-library # CT_LIBC_GLIBC=y # CT_LIBC_UCLIBC is not set CT_LIBC="glibc" CT_LIBC_CHOICE_KSYM="GLIBC" CT_THREADS="nptl" CT_LIBC_GLIBC_SHOW=y # # Options for glibc # CT_LIBC_GLIBC_PKG_KSYM="GLIBC" CT_GLIBC_DIR_NAME="glibc" CT_GLIBC_USE_GNU=y CT_GLIBC_USE="GLIBC" CT_GLIBC_PKG_NAME="glibc" CT_GLIBC_SRC_RELEASE=y CT_GLIBC_PATCH_ORDER="global" # CT_GLIBC_V_2_29 is not set # CT_GLIBC_V_2_28 is not set # CT_GLIBC_V_2_27 is not set # CT_GLIBC_V_2_26 is not set # CT_GLIBC_V_2_25 is not set # CT_GLIBC_V_2_24 is not set # CT_GLIBC_V_2_23 is not set CT_GLIBC_V_2_19=y # CT_GLIBC_V_2_17 is not set # CT_GLIBC_V_2_12_1 is not set # CT_GLIBC_NO_VERSIONS is not set CT_GLIBC_VERSION="2.19" CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" CT_GLIBC_2_29_or_older=y CT_GLIBC_older_than_2_29=y CT_GLIBC_2_27_or_older=y CT_GLIBC_older_than_2_27=y CT_GLIBC_2_26_or_older=y CT_GLIBC_older_than_2_26=y CT_GLIBC_2_25_or_older=y CT_GLIBC_older_than_2_25=y CT_GLIBC_2_24_or_older=y CT_GLIBC_older_than_2_24=y CT_GLIBC_2_23_or_older=y CT_GLIBC_older_than_2_23=y CT_GLIBC_2_20_or_older=y CT_GLIBC_older_than_2_20=y CT_GLIBC_later_than_2_17=y CT_GLIBC_2_17_or_later=y CT_GLIBC_later_than_2_14=y CT_GLIBC_2_14_or_later=y CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y CT_GLIBC_DEP_BINUTILS=y CT_GLIBC_DEP_GCC=y CT_GLIBC_DEP_PYTHON=y CT_GLIBC_HAS_NPTL_ADDON=y CT_GLIBC_HAS_PORTS_ADDON=y CT_GLIBC_HAS_LIBIDN_ADDON=y CT_GLIBC_USE_PORTS_ADDON=y CT_GLIBC_USE_NPTL_ADDON=y # CT_GLIBC_USE_LIBIDN_ADDON is not set CT_GLIBC_HAS_OBSOLETE_RPC=y CT_GLIBC_EXTRA_CONFIG_ARRAY="" CT_GLIBC_CONFIGPARMS="" CT_GLIBC_EXTRA_CFLAGS="" CT_GLIBC_ENABLE_OBSOLETE_RPC=y # CT_GLIBC_DISABLE_VERSIONING is not set CT_GLIBC_OLDEST_ABI="" CT_GLIBC_FORCE_UNWIND=y # CT_GLIBC_LOCALES is not set # CT_GLIBC_KERNEL_VERSION_NONE is not set CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y # CT_GLIBC_KERNEL_VERSION_CHOSEN is not set CT_GLIBC_MIN_KERNEL="4.9.156" # CT_GLIBC_SSP_DEFAULT is not set # CT_GLIBC_SSP_NO is not set # CT_GLIBC_SSP_YES is not set # CT_GLIBC_SSP_ALL is not set # CT_GLIBC_SSP_STRONG is not set CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" CT_LIBC_SUPPORT_THREADS_ANY=y CT_LIBC_SUPPORT_THREADS_NATIVE=y # # Common C library options # CT_THREADS_NATIVE=y # CT_CREATE_LDSO_CONF is not set CT_LIBC_XLDD=y # # C compiler # CT_CC_CORE_PASSES_NEEDED=y CT_CC_CORE_PASS_1_NEEDED=y CT_CC_CORE_PASS_2_NEEDED=y CT_CC_SUPPORT_CXX=y CT_CC_SUPPORT_FORTRAN=y CT_CC_SUPPORT_ADA=y CT_CC_SUPPORT_OBJC=y CT_CC_SUPPORT_OBJCXX=y CT_CC_SUPPORT_GOLANG=y CT_CC_GCC=y CT_CC="gcc" CT_CC_CHOICE_KSYM="GCC" CT_CC_GCC_SHOW=y # # Options for gcc # CT_CC_GCC_PKG_KSYM="GCC" CT_GCC_DIR_NAME="gcc" CT_GCC_USE_GNU=y CT_GCC_USE="GCC" CT_GCC_PKG_NAME="gcc" CT_GCC_SRC_RELEASE=y CT_GCC_PATCH_ORDER="global" CT_GCC_V_8=y # CT_GCC_V_7 is not set # CT_GCC_V_6 is not set # CT_GCC_V_5 is not set # CT_GCC_V_4_9 is not set # CT_GCC_NO_VERSIONS is not set CT_GCC_VERSION="8.3.0" CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_GCC_SIGNATURE_FORMAT="" CT_GCC_later_than_7=y CT_GCC_7_or_later=y CT_GCC_later_than_6=y CT_GCC_6_or_later=y CT_GCC_later_than_5=y CT_GCC_5_or_later=y CT_GCC_later_than_4_9=y CT_GCC_4_9_or_later=y CT_GCC_later_than_4_8=y CT_GCC_4_8_or_later=y CT_CC_GCC_ENABLE_PLUGINS=y CT_CC_GCC_HAS_LIBMPX=y CT_CC_GCC_ENABLE_CXX_FLAGS="" CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_STATIC_LIBSTDCXX=y # CT_CC_GCC_SYSTEM_ZLIB is not set CT_CC_GCC_CONFIG_TLS=m # # Optimisation features # CT_CC_GCC_USE_GRAPHITE=y CT_CC_GCC_USE_LTO=y # # Settings for libraries running on target # CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y # CT_CC_GCC_LIBMUDFLAP is not set # CT_CC_GCC_LIBGOMP is not set # CT_CC_GCC_LIBSSP is not set # CT_CC_GCC_LIBQUADMATH is not set # CT_CC_GCC_LIBSANITIZER is not set # # Misc. obscure options. # CT_CC_CXA_ATEXIT=y # CT_CC_GCC_DISABLE_PCH is not set CT_CC_GCC_SJLJ_EXCEPTIONS=m CT_CC_GCC_LDBL_128=m # CT_CC_GCC_BUILD_ID is not set CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y # CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set # CT_CC_GCC_LNK_HASH_STYLE_GNU is not set # CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set CT_CC_GCC_LNK_HASH_STYLE="" CT_CC_GCC_DEC_FLOAT_AUTO=y # CT_CC_GCC_DEC_FLOAT_BID is not set # CT_CC_GCC_DEC_FLOAT_DPD is not set # CT_CC_GCC_DEC_FLOATS_NO is not set CT_CC_GCC_HAS_ARCH_OPTIONS=y # # archictecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m CT_CC_GCC_mips_plt=y CT_ALL_CC_CHOICES="GCC" # # Additional supported languages: # CT_CC_LANG_CXX=y # CT_CC_LANG_FORTRAN is not set # # Debug facilities # # CT_DEBUG_DUMA is not set # CT_DEBUG_GDB is not set # CT_DEBUG_LTRACE is not set # CT_DEBUG_STRACE is not set CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" # # Companion libraries # # CT_COMPLIBS_CHECK is not set # CT_COMP_LIBS_CLOOG is not set CT_COMP_LIBS_EXPAT=y CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" CT_EXPAT_DIR_NAME="expat" CT_EXPAT_PKG_NAME="expat" CT_EXPAT_SRC_RELEASE=y CT_EXPAT_PATCH_ORDER="global" CT_EXPAT_V_2_2=y # CT_EXPAT_NO_VERSIONS is not set CT_EXPAT_VERSION="2.2.6" CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" CT_EXPAT_SIGNATURE_FORMAT="" CT_COMP_LIBS_GETTEXT=y CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" CT_GETTEXT_DIR_NAME="gettext" CT_GETTEXT_PKG_NAME="gettext" CT_GETTEXT_SRC_RELEASE=y CT_GETTEXT_PATCH_ORDER="global" CT_GETTEXT_V_0_19_8_1=y # CT_GETTEXT_NO_VERSIONS is not set CT_GETTEXT_VERSION="0.19.8.1" CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_GMP=y CT_COMP_LIBS_GMP_PKG_KSYM="GMP" CT_GMP_DIR_NAME="gmp" CT_GMP_PKG_NAME="gmp" CT_GMP_SRC_RELEASE=y CT_GMP_PATCH_ORDER="global" CT_GMP_V_6_1=y # CT_GMP_NO_VERSIONS is not set CT_GMP_VERSION="6.1.2" CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" CT_GMP_SIGNATURE_FORMAT="packed/.sig" CT_GMP_later_than_5_1_0=y CT_GMP_5_1_0_or_later=y CT_GMP_later_than_5_0_0=y CT_GMP_5_0_0_or_later=y CT_GMP_REQUIRE_5_0_0_or_later=y CT_COMP_LIBS_ISL=y CT_COMP_LIBS_ISL_PKG_KSYM="ISL" CT_ISL_DIR_NAME="isl" CT_ISL_PKG_NAME="isl" CT_ISL_SRC_RELEASE=y CT_ISL_PATCH_ORDER="global" CT_ISL_V_0_20=y # CT_ISL_V_0_19 is not set # CT_ISL_V_0_18 is not set # CT_ISL_V_0_17 is not set # CT_ISL_V_0_16 is not set # CT_ISL_V_0_15 is not set # CT_ISL_NO_VERSIONS is not set CT_ISL_VERSION="0.20" CT_ISL_MIRRORS="http://isl.gforge.inria.fr" CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_ISL_SIGNATURE_FORMAT="" CT_ISL_later_than_0_18=y CT_ISL_0_18_or_later=y CT_ISL_later_than_0_15=y CT_ISL_0_15_or_later=y CT_ISL_REQUIRE_0_15_or_later=y CT_ISL_later_than_0_14=y CT_ISL_0_14_or_later=y CT_ISL_REQUIRE_0_14_or_later=y CT_ISL_later_than_0_13=y CT_ISL_0_13_or_later=y CT_ISL_later_than_0_12=y CT_ISL_0_12_or_later=y CT_ISL_REQUIRE_0_12_or_later=y # CT_COMP_LIBS_LIBELF is not set CT_COMP_LIBS_LIBICONV=y CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" CT_LIBICONV_DIR_NAME="libiconv" CT_LIBICONV_PKG_NAME="libiconv" CT_LIBICONV_SRC_RELEASE=y CT_LIBICONV_PATCH_ORDER="global" CT_LIBICONV_V_1_15=y # CT_LIBICONV_NO_VERSIONS is not set CT_LIBICONV_VERSION="1.15" CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_MPC=y CT_COMP_LIBS_MPC_PKG_KSYM="MPC" CT_MPC_DIR_NAME="mpc" CT_MPC_PKG_NAME="mpc" CT_MPC_SRC_RELEASE=y CT_MPC_PATCH_ORDER="global" CT_MPC_V_1_1=y # CT_MPC_V_1_0 is not set # CT_MPC_NO_VERSIONS is not set CT_MPC_VERSION="1.1.0" CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_FORMATS=".tar.gz" CT_MPC_SIGNATURE_FORMAT="packed/.sig" CT_MPC_1_1_0_or_later=y CT_MPC_1_1_0_or_older=y CT_COMP_LIBS_MPFR=y CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" CT_MPFR_DIR_NAME="mpfr" CT_MPFR_PKG_NAME="mpfr" CT_MPFR_SRC_RELEASE=y CT_MPFR_PATCH_ORDER="global" CT_MPFR_V_4_0=y # CT_MPFR_V_3_1 is not set # CT_MPFR_NO_VERSIONS is not set CT_MPFR_VERSION="4.0.2" CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" CT_MPFR_SIGNATURE_FORMAT="packed/.asc" CT_MPFR_later_than_4_0_0=y CT_MPFR_4_0_0_or_later=y CT_MPFR_later_than_3_0_0=y CT_MPFR_3_0_0_or_later=y CT_MPFR_REQUIRE_3_0_0_or_later=y CT_COMP_LIBS_NCURSES=y CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" CT_NCURSES_DIR_NAME="ncurses" CT_NCURSES_PKG_NAME="ncurses" CT_NCURSES_SRC_RELEASE=y CT_NCURSES_PATCH_ORDER="global" CT_NCURSES_V_6_1=y # CT_NCURSES_V_6_0 is not set # CT_NCURSES_NO_VERSIONS is not set CT_NCURSES_VERSION="6.1" CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" CT_NCURSES_HOST_CONFIG_ARGS="" CT_NCURSES_HOST_DISABLE_DB=y CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" CT_NCURSES_TARGET_CONFIG_ARGS="" # CT_NCURSES_TARGET_DISABLE_DB is not set CT_NCURSES_TARGET_FALLBACKS="" CT_COMP_LIBS_ZLIB=y CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" CT_ZLIB_DIR_NAME="zlib" CT_ZLIB_PKG_NAME="zlib" CT_ZLIB_SRC_RELEASE=y CT_ZLIB_PATCH_ORDER="global" CT_ZLIB_V_1_2_11=y # CT_ZLIB_NO_VERSIONS is not set CT_ZLIB_VERSION="1.2.11" CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" CT_LIBICONV_NEEDED=y CT_GETTEXT_NEEDED=y CT_GMP_NEEDED=y CT_MPFR_NEEDED=y CT_ISL_NEEDED=y CT_MPC_NEEDED=y CT_NCURSES_NEEDED=y CT_ZLIB_NEEDED=y CT_LIBICONV=y CT_GETTEXT=y CT_GMP=y CT_MPFR=y CT_ISL=y CT_MPC=y CT_NCURSES=y CT_ZLIB=y # # Companion tools # # CT_COMP_TOOLS_FOR_HOST is not set # CT_COMP_TOOLS_AUTOCONF is not set # CT_COMP_TOOLS_AUTOMAKE is not set # CT_COMP_TOOLS_BISON is not set # CT_COMP_TOOLS_DTC is not set # CT_COMP_TOOLS_LIBTOOL is not set # CT_COMP_TOOLS_M4 is not set # CT_COMP_TOOLS_MAKE is not set CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" ================================================ FILE: tools/toolchain_builder/toolchains/x86_64-unknown-linux-gnu/gcc-8.3.0-glibc-2.19-kernel-4.9.config ================================================ # # Automatically generated file; DO NOT EDIT. # crosstool-NG Configuration # CT_CONFIGURE_has_static_link=y CT_CONFIGURE_has_cxx11=y CT_CONFIGURE_has_wget=y CT_CONFIGURE_has_curl=y CT_CONFIGURE_has_make_3_81_or_newer=y CT_CONFIGURE_has_make_4_0_or_newer=y CT_CONFIGURE_has_libtool_2_4_or_newer=y CT_CONFIGURE_has_libtoolize_2_4_or_newer=y CT_CONFIGURE_has_autoconf_2_65_or_newer=y CT_CONFIGURE_has_autoreconf_2_65_or_newer=y CT_CONFIGURE_has_automake_1_15_or_newer=y CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y CT_CONFIGURE_has_python_3_4_or_newer=y CT_CONFIGURE_has_bison_2_7_or_newer=y CT_CONFIGURE_has_python=y CT_CONFIGURE_has_git=y CT_CONFIGURE_has_md5sum=y CT_CONFIGURE_has_sha1sum=y CT_CONFIGURE_has_sha256sum=y CT_CONFIGURE_has_sha512sum=y CT_CONFIGURE_has_install_with_strip_program=y CT_CONFIG_VERSION_CURRENT="3" CT_CONFIG_VERSION="3" CT_MODULES=y # # Paths and misc options # # # crosstool-NG behavior # # CT_OBSOLETE is not set # CT_EXPERIMENTAL is not set # CT_DEBUG_CT is not set # # Paths # CT_LOCAL_TARBALLS_DIR="${HOME}/src" CT_SAVE_TARBALLS=y # CT_TARBALLS_BUILDROOT_LAYOUT is not set CT_WORK_DIR="${CT_TOP_DIR}/.build" CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_PREFIX_DIR="${CT_PREFIX:-${HOME}/x-tools}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" CT_RM_RF_PREFIX_DIR=y CT_REMOVE_DOCS=y CT_INSTALL_LICENSES=y # CT_PREFIX_DIR_RO is not set CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES=y # # Downloading # CT_DOWNLOAD_AGENT_WGET=y # CT_DOWNLOAD_AGENT_CURL is not set # CT_DOWNLOAD_AGENT_NONE is not set # CT_FORBID_DOWNLOAD is not set # CT_FORCE_DOWNLOAD is not set CT_CONNECT_TIMEOUT=10 CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" # CT_ONLY_DOWNLOAD is not set # CT_USE_MIRROR is not set CT_VERIFY_DOWNLOAD_DIGEST=y CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y # CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set # CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set # CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" # CT_VERIFY_DOWNLOAD_SIGNATURE is not set # # Extracting # # CT_FORCE_EXTRACT is not set CT_OVERRIDE_CONFIG_GUESS_SUB=y # CT_ONLY_EXTRACT is not set CT_PATCH_BUNDLED=y # CT_PATCH_BUNDLED_LOCAL is not set CT_PATCH_ORDER="bundled" # # Build behavior # CT_PARALLEL_JOBS=0 CT_LOAD="" CT_USE_PIPES=y CT_EXTRA_CFLAGS_FOR_BUILD="" CT_EXTRA_LDFLAGS_FOR_BUILD="" CT_EXTRA_CFLAGS_FOR_HOST="" CT_EXTRA_LDFLAGS_FOR_HOST="" # CT_CONFIG_SHELL_SH is not set # CT_CONFIG_SHELL_ASH is not set CT_CONFIG_SHELL_BASH=y # CT_CONFIG_SHELL_CUSTOM is not set CT_CONFIG_SHELL="${bash}" # # Logging # # CT_LOG_ERROR is not set # CT_LOG_WARN is not set # CT_LOG_INFO is not set CT_LOG_EXTRA=y # CT_LOG_ALL is not set # CT_LOG_DEBUG is not set CT_LOG_LEVEL_MAX="EXTRA" # CT_LOG_SEE_TOOLS_WARN is not set CT_LOG_PROGRESS_BAR=y CT_LOG_TO_FILE=y CT_LOG_FILE_COMPRESS=y # # Target options # # CT_ARCH_ALPHA is not set # CT_ARCH_ARC is not set # CT_ARCH_ARM is not set # CT_ARCH_AVR is not set # CT_ARCH_M68K is not set # CT_ARCH_MIPS is not set # CT_ARCH_NIOS2 is not set # CT_ARCH_POWERPC is not set # CT_ARCH_S390 is not set # CT_ARCH_SH is not set # CT_ARCH_SPARC is not set CT_ARCH_X86=y # CT_ARCH_XTENSA is not set CT_ARCH="x86" CT_ARCH_CHOICE_KSYM="X86" CT_ARCH_CPU="" CT_ARCH_TUNE="" CT_ARCH_X86_SHOW=y # # Options for x86 # CT_ARCH_X86_PKG_KSYM="" CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" CT_ARCH_SUFFIX="" # CT_OMIT_TARGET_VENDOR is not set # # Generic target options # # CT_MULTILIB is not set CT_DEMULTILIB=y CT_ARCH_USE_MMU=y CT_ARCH_SUPPORTS_32=y CT_ARCH_SUPPORTS_64=y CT_ARCH_DEFAULT_32=y CT_ARCH_BITNESS=64 # CT_ARCH_32 is not set CT_ARCH_64=y # # Target optimisations # CT_ARCH_SUPPORTS_WITH_ARCH=y CT_ARCH_SUPPORTS_WITH_CPU=y CT_ARCH_SUPPORTS_WITH_TUNE=y CT_ARCH_ARCH="" CT_TARGET_CFLAGS="" CT_TARGET_LDFLAGS="" # # Toolchain options # # # General toolchain options # CT_FORCE_SYSROOT=y CT_USE_SYSROOT=y CT_SYSROOT_NAME="sysroot" CT_SYSROOT_DIR_PREFIX="" CT_WANTS_STATIC_LINK=y CT_WANTS_STATIC_LINK_CXX=y # CT_STATIC_TOOLCHAIN is not set CT_SHOW_CT_VERSION=y CT_TOOLCHAIN_PKGVERSION="" CT_TOOLCHAIN_BUGURL="" # # Tuple completion and aliasing # CT_TARGET_VENDOR="unknown" CT_TARGET_ALIAS_SED_EXPR="" CT_TARGET_ALIAS="" # # Toolchain type # CT_CROSS=y # CT_CANADIAN is not set CT_TOOLCHAIN_TYPE="cross" # # Build system # CT_BUILD="" CT_BUILD_PREFIX="" CT_BUILD_SUFFIX="" # # Misc options # # CT_TOOLCHAIN_ENABLE_NLS is not set # # Operating System # CT_KERNEL_SUPPORTS_SHARED_LIBS=y # CT_KERNEL_BARE_METAL is not set CT_KERNEL_LINUX=y CT_KERNEL="linux" CT_KERNEL_CHOICE_KSYM="LINUX" CT_KERNEL_LINUX_SHOW=y # # Options for linux # CT_KERNEL_LINUX_PKG_KSYM="LINUX" CT_LINUX_DIR_NAME="linux" CT_LINUX_PKG_NAME="linux" CT_LINUX_SRC_RELEASE=y CT_LINUX_PATCH_ORDER="global" # CT_LINUX_V_4_20 is not set # CT_LINUX_V_4_19 is not set # CT_LINUX_V_4_18 is not set # CT_LINUX_V_4_17 is not set # CT_LINUX_V_4_16 is not set # CT_LINUX_V_4_15 is not set # CT_LINUX_V_4_14 is not set # CT_LINUX_V_4_13 is not set # CT_LINUX_V_4_12 is not set # CT_LINUX_V_4_11 is not set # CT_LINUX_V_4_10 is not set CT_LINUX_V_4_9=y # CT_LINUX_V_4_4 is not set # CT_LINUX_V_4_1 is not set # CT_LINUX_V_3_16 is not set # CT_LINUX_V_3_13 is not set # CT_LINUX_V_3_12 is not set # CT_LINUX_V_3_10 is not set # CT_LINUX_V_3_4 is not set # CT_LINUX_V_3_2 is not set # CT_LINUX_V_2_6_32 is not set # CT_LINUX_NO_VERSIONS is not set CT_LINUX_VERSION="4.9.156" CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" CT_LINUX_later_than_4_8=y CT_LINUX_4_8_or_later=y CT_LINUX_later_than_3_7=y CT_LINUX_3_7_or_later=y CT_LINUX_later_than_3_2=y CT_LINUX_3_2_or_later=y CT_KERNEL_LINUX_VERBOSITY_0=y # CT_KERNEL_LINUX_VERBOSITY_1 is not set # CT_KERNEL_LINUX_VERBOSITY_2 is not set CT_KERNEL_LINUX_VERBOSE_LEVEL=0 CT_KERNEL_LINUX_INSTALL_CHECK=y CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" # # Common kernel options # CT_SHARED_LIBS=y # # Binary utilities # CT_ARCH_BINFMT_ELF=y CT_BINUTILS_BINUTILS=y CT_BINUTILS="binutils" CT_BINUTILS_CHOICE_KSYM="BINUTILS" CT_BINUTILS_BINUTILS_SHOW=y # # Options for binutils # CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" CT_BINUTILS_DIR_NAME="binutils" CT_BINUTILS_USE_GNU=y CT_BINUTILS_USE="BINUTILS" CT_BINUTILS_PKG_NAME="binutils" CT_BINUTILS_SRC_RELEASE=y CT_BINUTILS_PATCH_ORDER="global" CT_BINUTILS_V_2_32=y # CT_BINUTILS_V_2_31 is not set # CT_BINUTILS_V_2_30 is not set # CT_BINUTILS_V_2_29 is not set # CT_BINUTILS_V_2_28 is not set # CT_BINUTILS_V_2_27 is not set # CT_BINUTILS_V_2_26 is not set # CT_BINUTILS_NO_VERSIONS is not set CT_BINUTILS_VERSION="2.32" CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" CT_BINUTILS_later_than_2_30=y CT_BINUTILS_2_30_or_later=y CT_BINUTILS_later_than_2_27=y CT_BINUTILS_2_27_or_later=y CT_BINUTILS_later_than_2_25=y CT_BINUTILS_2_25_or_later=y CT_BINUTILS_later_than_2_23=y CT_BINUTILS_2_23_or_later=y # # GNU binutils # CT_BINUTILS_HAS_HASH_STYLE=y CT_BINUTILS_HAS_GOLD=y CT_BINUTILS_HAS_PLUGINS=y CT_BINUTILS_HAS_PKGVERSION_BUGURL=y CT_BINUTILS_GOLD_SUPPORTS_ARCH=y CT_BINUTILS_GOLD_SUPPORT=y CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y # CT_BINUTILS_LINKER_LD is not set CT_BINUTILS_LINKER_LD_GOLD=y CT_BINUTILS_GOLD_INSTALLED=y CT_BINUTILS_GOLD_THREADS=y CT_BINUTILS_LINKER_BOTH=y CT_BINUTILS_LINKERS_LIST="ld,gold" CT_BINUTILS_LD_WRAPPER=y CT_BINUTILS_LINKER_DEFAULT="bfd" CT_BINUTILS_PLUGINS=y CT_BINUTILS_RELRO=m CT_BINUTILS_EXTRA_CONFIG_ARRAY="" # CT_BINUTILS_FOR_TARGET is not set CT_ALL_BINUTILS_CHOICES="BINUTILS" # # C-library # CT_LIBC_GLIBC=y # CT_LIBC_UCLIBC is not set CT_LIBC="glibc" CT_LIBC_CHOICE_KSYM="GLIBC" CT_THREADS="nptl" CT_LIBC_GLIBC_SHOW=y # # Options for glibc # CT_LIBC_GLIBC_PKG_KSYM="GLIBC" CT_GLIBC_DIR_NAME="glibc" CT_GLIBC_USE_GNU=y CT_GLIBC_USE="GLIBC" CT_GLIBC_PKG_NAME="glibc" CT_GLIBC_SRC_RELEASE=y CT_GLIBC_PATCH_ORDER="global" # CT_GLIBC_V_2_29 is not set # CT_GLIBC_V_2_28 is not set # CT_GLIBC_V_2_27 is not set # CT_GLIBC_V_2_26 is not set # CT_GLIBC_V_2_25 is not set # CT_GLIBC_V_2_24 is not set # CT_GLIBC_V_2_23 is not set CT_GLIBC_V_2_19=y # CT_GLIBC_V_2_17 is not set # CT_GLIBC_V_2_12_1 is not set # CT_GLIBC_NO_VERSIONS is not set CT_GLIBC_VERSION="2.19" CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" CT_GLIBC_2_29_or_older=y CT_GLIBC_older_than_2_29=y CT_GLIBC_2_27_or_older=y CT_GLIBC_older_than_2_27=y CT_GLIBC_2_26_or_older=y CT_GLIBC_older_than_2_26=y CT_GLIBC_2_25_or_older=y CT_GLIBC_older_than_2_25=y CT_GLIBC_2_24_or_older=y CT_GLIBC_older_than_2_24=y CT_GLIBC_2_23_or_older=y CT_GLIBC_older_than_2_23=y CT_GLIBC_2_20_or_older=y CT_GLIBC_older_than_2_20=y CT_GLIBC_later_than_2_17=y CT_GLIBC_2_17_or_later=y CT_GLIBC_later_than_2_14=y CT_GLIBC_2_14_or_later=y CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y CT_GLIBC_DEP_BINUTILS=y CT_GLIBC_DEP_GCC=y CT_GLIBC_DEP_PYTHON=y CT_GLIBC_HAS_NPTL_ADDON=y CT_GLIBC_HAS_PORTS_ADDON=y CT_GLIBC_HAS_LIBIDN_ADDON=y CT_GLIBC_USE_NPTL_ADDON=y # CT_GLIBC_USE_LIBIDN_ADDON is not set CT_GLIBC_HAS_OBSOLETE_RPC=y CT_GLIBC_EXTRA_CONFIG_ARRAY="" CT_GLIBC_CONFIGPARMS="" CT_GLIBC_EXTRA_CFLAGS="" CT_GLIBC_ENABLE_OBSOLETE_RPC=y # CT_GLIBC_DISABLE_VERSIONING is not set CT_GLIBC_OLDEST_ABI="" CT_GLIBC_FORCE_UNWIND=y # CT_GLIBC_LOCALES is not set CT_GLIBC_KERNEL_VERSION_NONE=y # CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set # CT_GLIBC_KERNEL_VERSION_CHOSEN is not set CT_GLIBC_MIN_KERNEL="" CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" CT_LIBC_SUPPORT_THREADS_ANY=y CT_LIBC_SUPPORT_THREADS_NATIVE=y # # Common C library options # CT_THREADS_NATIVE=y # CT_CREATE_LDSO_CONF is not set CT_LIBC_XLDD=y # # C compiler # CT_CC_CORE_PASSES_NEEDED=y CT_CC_CORE_PASS_1_NEEDED=y CT_CC_CORE_PASS_2_NEEDED=y CT_CC_SUPPORT_CXX=y CT_CC_SUPPORT_FORTRAN=y CT_CC_SUPPORT_ADA=y CT_CC_SUPPORT_OBJC=y CT_CC_SUPPORT_OBJCXX=y CT_CC_SUPPORT_GOLANG=y CT_CC_GCC=y CT_CC="gcc" CT_CC_CHOICE_KSYM="GCC" CT_CC_GCC_SHOW=y # # Options for gcc # CT_CC_GCC_PKG_KSYM="GCC" CT_GCC_DIR_NAME="gcc" CT_GCC_USE_GNU=y CT_GCC_USE="GCC" CT_GCC_PKG_NAME="gcc" CT_GCC_SRC_RELEASE=y CT_GCC_PATCH_ORDER="global" CT_GCC_V_8=y # CT_GCC_V_7 is not set # CT_GCC_V_6 is not set # CT_GCC_V_5 is not set # CT_GCC_V_4_9 is not set # CT_GCC_NO_VERSIONS is not set CT_GCC_VERSION="8.3.0" CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_GCC_SIGNATURE_FORMAT="" CT_GCC_later_than_7=y CT_GCC_7_or_later=y CT_GCC_later_than_6=y CT_GCC_6_or_later=y CT_GCC_later_than_5=y CT_GCC_5_or_later=y CT_GCC_later_than_4_9=y CT_GCC_4_9_or_later=y CT_GCC_later_than_4_8=y CT_GCC_4_8_or_later=y CT_CC_GCC_ENABLE_PLUGINS=y CT_CC_GCC_GOLD=y CT_CC_GCC_HAS_LIBMPX=y CT_CC_GCC_ENABLE_CXX_FLAGS="" CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_EXTRA_CONFIG_ARRAY="" CT_CC_GCC_STATIC_LIBSTDCXX=y # CT_CC_GCC_SYSTEM_ZLIB is not set CT_CC_GCC_CONFIG_TLS=m # # Optimisation features # CT_CC_GCC_USE_GRAPHITE=y CT_CC_GCC_USE_LTO=y # # Settings for libraries running on target # CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y # CT_CC_GCC_LIBMUDFLAP is not set # CT_CC_GCC_LIBGOMP is not set # CT_CC_GCC_LIBSSP is not set # CT_CC_GCC_LIBQUADMATH is not set # CT_CC_GCC_LIBSANITIZER is not set CT_CC_GCC_LIBMPX=y # # Misc. obscure options. # CT_CC_CXA_ATEXIT=y # CT_CC_GCC_DISABLE_PCH is not set CT_CC_GCC_SJLJ_EXCEPTIONS=m CT_CC_GCC_LDBL_128=m # CT_CC_GCC_BUILD_ID is not set # CT_CC_GCC_LNK_HASH_STYLE_DEFAULT is not set # CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set # CT_CC_GCC_LNK_HASH_STYLE_GNU is not set CT_CC_GCC_LNK_HASH_STYLE_BOTH=y CT_CC_GCC_LNK_HASH_STYLE="both" CT_CC_GCC_DEC_FLOAT_AUTO=y # CT_CC_GCC_DEC_FLOAT_BID is not set # CT_CC_GCC_DEC_FLOAT_DPD is not set # CT_CC_GCC_DEC_FLOATS_NO is not set CT_ALL_CC_CHOICES="GCC" # # Additional supported languages: # CT_CC_LANG_CXX=y # CT_CC_LANG_FORTRAN is not set # # Debug facilities # # CT_DEBUG_DUMA is not set # CT_DEBUG_GDB is not set # CT_DEBUG_LTRACE is not set # CT_DEBUG_STRACE is not set CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" # # Companion libraries # # CT_COMPLIBS_CHECK is not set # CT_COMP_LIBS_CLOOG is not set CT_COMP_LIBS_EXPAT=y CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" CT_EXPAT_DIR_NAME="expat" CT_EXPAT_PKG_NAME="expat" CT_EXPAT_SRC_RELEASE=y CT_EXPAT_PATCH_ORDER="global" CT_EXPAT_V_2_2=y # CT_EXPAT_NO_VERSIONS is not set CT_EXPAT_VERSION="2.2.6" CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" CT_EXPAT_SIGNATURE_FORMAT="" CT_COMP_LIBS_GETTEXT=y CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" CT_GETTEXT_DIR_NAME="gettext" CT_GETTEXT_PKG_NAME="gettext" CT_GETTEXT_SRC_RELEASE=y CT_GETTEXT_PATCH_ORDER="global" CT_GETTEXT_V_0_19_8_1=y # CT_GETTEXT_NO_VERSIONS is not set CT_GETTEXT_VERSION="0.19.8.1" CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_GMP=y CT_COMP_LIBS_GMP_PKG_KSYM="GMP" CT_GMP_DIR_NAME="gmp" CT_GMP_PKG_NAME="gmp" CT_GMP_SRC_RELEASE=y CT_GMP_PATCH_ORDER="global" CT_GMP_V_6_1=y # CT_GMP_NO_VERSIONS is not set CT_GMP_VERSION="6.1.2" CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" CT_GMP_SIGNATURE_FORMAT="packed/.sig" CT_GMP_later_than_5_1_0=y CT_GMP_5_1_0_or_later=y CT_GMP_later_than_5_0_0=y CT_GMP_5_0_0_or_later=y CT_GMP_REQUIRE_5_0_0_or_later=y CT_COMP_LIBS_ISL=y CT_COMP_LIBS_ISL_PKG_KSYM="ISL" CT_ISL_DIR_NAME="isl" CT_ISL_PKG_NAME="isl" CT_ISL_SRC_RELEASE=y CT_ISL_PATCH_ORDER="global" CT_ISL_V_0_20=y # CT_ISL_V_0_19 is not set # CT_ISL_V_0_18 is not set # CT_ISL_V_0_17 is not set # CT_ISL_V_0_16 is not set # CT_ISL_V_0_15 is not set # CT_ISL_NO_VERSIONS is not set CT_ISL_VERSION="0.20" CT_ISL_MIRRORS="http://isl.gforge.inria.fr" CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" CT_ISL_SIGNATURE_FORMAT="" CT_ISL_later_than_0_18=y CT_ISL_0_18_or_later=y CT_ISL_later_than_0_15=y CT_ISL_0_15_or_later=y CT_ISL_REQUIRE_0_15_or_later=y CT_ISL_later_than_0_14=y CT_ISL_0_14_or_later=y CT_ISL_REQUIRE_0_14_or_later=y CT_ISL_later_than_0_13=y CT_ISL_0_13_or_later=y CT_ISL_later_than_0_12=y CT_ISL_0_12_or_later=y CT_ISL_REQUIRE_0_12_or_later=y # CT_COMP_LIBS_LIBELF is not set CT_COMP_LIBS_LIBICONV=y CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" CT_LIBICONV_DIR_NAME="libiconv" CT_LIBICONV_PKG_NAME="libiconv" CT_LIBICONV_SRC_RELEASE=y CT_LIBICONV_PATCH_ORDER="global" CT_LIBICONV_V_1_15=y # CT_LIBICONV_NO_VERSIONS is not set CT_LIBICONV_VERSION="1.15" CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" CT_COMP_LIBS_MPC=y CT_COMP_LIBS_MPC_PKG_KSYM="MPC" CT_MPC_DIR_NAME="mpc" CT_MPC_PKG_NAME="mpc" CT_MPC_SRC_RELEASE=y CT_MPC_PATCH_ORDER="global" CT_MPC_V_1_1=y # CT_MPC_V_1_0 is not set # CT_MPC_NO_VERSIONS is not set CT_MPC_VERSION="1.1.0" CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPC_ARCHIVE_FORMATS=".tar.gz" CT_MPC_SIGNATURE_FORMAT="packed/.sig" CT_MPC_1_1_0_or_later=y CT_MPC_1_1_0_or_older=y CT_COMP_LIBS_MPFR=y CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" CT_MPFR_DIR_NAME="mpfr" CT_MPFR_PKG_NAME="mpfr" CT_MPFR_SRC_RELEASE=y CT_MPFR_PATCH_ORDER="global" CT_MPFR_V_4_0=y # CT_MPFR_V_3_1 is not set # CT_MPFR_NO_VERSIONS is not set CT_MPFR_VERSION="4.0.2" CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" CT_MPFR_SIGNATURE_FORMAT="packed/.asc" CT_MPFR_later_than_4_0_0=y CT_MPFR_4_0_0_or_later=y CT_MPFR_later_than_3_0_0=y CT_MPFR_3_0_0_or_later=y CT_MPFR_REQUIRE_3_0_0_or_later=y CT_COMP_LIBS_NCURSES=y CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" CT_NCURSES_DIR_NAME="ncurses" CT_NCURSES_PKG_NAME="ncurses" CT_NCURSES_SRC_RELEASE=y CT_NCURSES_PATCH_ORDER="global" CT_NCURSES_V_6_1=y # CT_NCURSES_V_6_0 is not set # CT_NCURSES_NO_VERSIONS is not set CT_NCURSES_VERSION="6.1" CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" CT_NCURSES_HOST_CONFIG_ARGS="" CT_NCURSES_HOST_DISABLE_DB=y CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" CT_NCURSES_TARGET_CONFIG_ARGS="" # CT_NCURSES_TARGET_DISABLE_DB is not set CT_NCURSES_TARGET_FALLBACKS="" CT_COMP_LIBS_ZLIB=y CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" CT_ZLIB_DIR_NAME="zlib" CT_ZLIB_PKG_NAME="zlib" CT_ZLIB_SRC_RELEASE=y CT_ZLIB_PATCH_ORDER="global" CT_ZLIB_V_1_2_11=y # CT_ZLIB_NO_VERSIONS is not set CT_ZLIB_VERSION="1.2.11" CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" CT_LIBICONV_NEEDED=y CT_GETTEXT_NEEDED=y CT_GMP_NEEDED=y CT_MPFR_NEEDED=y CT_ISL_NEEDED=y CT_MPC_NEEDED=y CT_NCURSES_NEEDED=y CT_ZLIB_NEEDED=y CT_LIBICONV=y CT_GETTEXT=y CT_GMP=y CT_MPFR=y CT_ISL=y CT_MPC=y CT_NCURSES=y CT_ZLIB=y # # Companion tools # # CT_COMP_TOOLS_FOR_HOST is not set # CT_COMP_TOOLS_AUTOCONF is not set # CT_COMP_TOOLS_AUTOMAKE is not set # CT_COMP_TOOLS_BISON is not set # CT_COMP_TOOLS_DTC is not set # CT_COMP_TOOLS_LIBTOOL is not set # CT_COMP_TOOLS_M4 is not set # CT_COMP_TOOLS_MAKE is not set CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" ================================================ FILE: utilities/basic-utils/build.gradle.kts ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { apply(from = "$rootDir/gradle/kotlinGradlePlugin.gradle") } plugins { kotlin("jvm") } tasks.named("compileKotlin") { kotlinOptions { freeCompilerArgs = listOf("-Xskip-metadata-version-check") } } // Convert to normal strings since originally these properties contain GStrings. val kotlinCompilerModule = rootProject.ext["kotlinCompilerModule"].toString() val kotlinStdLibModule = rootProject.ext["kotlinStdLibModule"].toString() dependencies { api(kotlinStdLibModule) implementation(kotlinCompilerModule) } ================================================ FILE: utilities/basic-utils/src/main/kotlin/KonanHomeProvider.kt ================================================ package org.jetbrains.kotlin.konan.util import org.jetbrains.kotlin.utils.PathUtil import java.io.File import java.nio.file.Paths object KonanHomeProvider { /** * Determines a path to the current Kotlin/Native distribution. * * - If the system property "konan.home" is set, the method returns its value. * - Otherwise, it determines a path to a jar containing this class. If this path corresponds to the jar path * inside a distribution, the method calculates the path to the distribution on the basis of this jar path. * Otherwise an IllegalStateException is thrown. */ fun determineKonanHome(): String { val propertyValue = System.getProperty("konan.home") return if (propertyValue != null) { File(propertyValue).absolutePath } else { val jarPath = PathUtil.getResourcePathForClass(this::class.java) // Check that the path obtained really points to the distribution. val expectedRelativeJarPath = Paths.get("konan/lib/kotlin-native.jar") check(jarPath.toPath().endsWith(expectedRelativeJarPath)) { val classesPath = if (jarPath.extension == "jar") jarPath else jarPath.parentFile """ Cannot determine a compiler distribution directory. A path to compiler classes is not a part of a distribution: ${classesPath.absolutePath}. Please set the konan.home system property to specify the distribution path manually. """.trimIndent() } // The compiler jar is located in /konan/lib. jarPath.parentFile.parentFile.parentFile.absolutePath } } } ================================================ FILE: utilities/basic-utils/src/main/kotlin/NativeMemoryAllocator.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.konan.util import sun.misc.Unsafe private val allocatorHolder = ThreadLocal() val nativeMemoryAllocator: NativeMemoryAllocator get() = allocatorHolder.get() ?: NativeMemoryAllocator().also { allocatorHolder.set(it) } fun disposeNativeMemoryAllocator() { allocatorHolder.get()?.freeAll() allocatorHolder.remove() } // 256 buckets for sizes <= 2048 padded to 8 // 256 buckets for sizes <= 64KB padded to 256 // 256 buckets for sizes <= 1MB padded to 4096 private const val ChunkBucketSize = 256 // Alignments are such that overhead is approx 10%. private const val SmallChunksSizeAlignment = 8 private const val MediumChunksSizeAlignment = 256 private const val BigChunksSizeAlignment = 4096 private const val MaxSmallSize = ChunkBucketSize * SmallChunksSizeAlignment private const val MaxMediumSize = ChunkBucketSize * MediumChunksSizeAlignment private const val MaxBigSize = ChunkBucketSize * BigChunksSizeAlignment private const val ChunkHeaderSize = 2 * Int.SIZE_BYTES // chunk size + alignment hop size. private const val RawChunkSize: Long = 4 * 1024 * 1024 class NativeMemoryAllocator { private fun alignUp(x: Long, align: Int) = (x + align - 1) and (align - 1).toLong().inv() private fun alignUp(x: Int, align: Int) = (x + align - 1) and (align - 1).inv() private val smallChunks = LongArray(ChunkBucketSize) private val mediumChunks = LongArray(ChunkBucketSize) private val bigChunks = LongArray(ChunkBucketSize) // Chunk layout: [chunk size,...padding...,diff to start,aligned data start,.....data.....] fun alloc(size: Long, align: Int): Long { val totalChunkSize = ChunkHeaderSize + size + align val ptr = ChunkHeaderSize + when { totalChunkSize <= MaxSmallSize -> allocFromFreeList(totalChunkSize.toInt(), SmallChunksSizeAlignment, smallChunks) totalChunkSize <= MaxMediumSize -> allocFromFreeList(totalChunkSize.toInt(), MediumChunksSizeAlignment, mediumChunks) totalChunkSize <= MaxBigSize -> allocFromFreeList(totalChunkSize.toInt(), BigChunksSizeAlignment, bigChunks) else -> unsafe.allocateMemory(totalChunkSize).also { // The actual size is not used. Just put value bigger than the biggest threshold. unsafe.putInt(it, Int.MAX_VALUE) } } val alignedPtr = alignUp(ptr, align) unsafe.putInt(alignedPtr - Int.SIZE_BYTES, (alignedPtr - ptr).toInt()) return alignedPtr } private fun allocFromFreeList(size: Int, align: Int, freeList: LongArray): Long { val paddedSize = alignUp(size, align) val index = paddedSize / align - 1 val chunk = freeList[index] val ptr = if (chunk == 0L) allocRaw(paddedSize) else { val nextChunk = unsafe.getLong(chunk) freeList[index] = nextChunk chunk } unsafe.putInt(ptr, paddedSize) return ptr } private fun freeToFreeList(paddedSize: Int, align: Int, freeList: LongArray, chunk: Long) { require(paddedSize > 0 && paddedSize % align == 0) val index = paddedSize / align - 1 unsafe.putLong(chunk, freeList[index]) freeList[index] = chunk } private val rawChunks = mutableListOf() private var rawOffset = 0 private fun allocRaw(size: Int): Long { if (rawChunks.isEmpty() || rawOffset + size > RawChunkSize) { val newRawChunk = unsafe.allocateMemory(RawChunkSize) rawChunks.add(newRawChunk) rawOffset = size return newRawChunk } return (rawChunks.last() + rawOffset).also { rawOffset += size } } fun free(mem: Long) { val chunkStart = mem - ChunkHeaderSize - unsafe.getInt(mem - Int.SIZE_BYTES) val chunkSize = unsafe.getInt(chunkStart) when { chunkSize <= MaxSmallSize -> freeToFreeList(chunkSize, SmallChunksSizeAlignment, smallChunks, chunkStart) chunkSize <= MaxMediumSize -> freeToFreeList(chunkSize, MediumChunksSizeAlignment, mediumChunks, chunkStart) chunkSize <= MaxBigSize -> freeToFreeList(chunkSize, BigChunksSizeAlignment, bigChunks, chunkStart) else -> unsafe.freeMemory(chunkStart) } } fun freeAll() { for (i in 0 until ChunkBucketSize) { smallChunks[i] = 0L mediumChunks[i] = 0L bigChunks[i] = 0L } for (chunk in rawChunks) unsafe.freeMemory(chunk) rawChunks.clear() } private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) { isAccessible = true return@with this.get(null) as Unsafe } } ================================================ FILE: utilities/cli-runner/build.gradle ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ buildscript { apply from: "$rootDir/gradle/kotlinGradlePlugin.gradle" } apply plugin: 'kotlin' repositories { maven { url buildKotlinCompilerRepo } } compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xskip-metadata-version-check'] } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation project(':backend.native') implementation project(':Interop:StubGenerator') implementation project(':klib') implementation project(":utilities:basic-utils") } ================================================ FILE: utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/GeneratePlatformLibraries.kt ================================================ /* * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.utilities import org.jetbrains.kotlin.cli.bc.K2Native import org.jetbrains.kotlin.konan.file.File import java.util.concurrent.* import kotlinx.cli.* import org.jetbrains.kotlin.backend.konan.CachedLibraries import org.jetbrains.kotlin.backend.konan.OutputFiles import org.jetbrains.kotlin.backend.konan.files.renameAtomic import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.konan.util.PlatformLibsInfo import org.jetbrains.kotlin.konan.util.visibleName import org.jetbrains.kotlin.native.interop.gen.jvm.GenerationMode import org.jetbrains.kotlin.native.interop.tool.CommonInteropArguments.Companion.DEFAULT_MODE import org.jetbrains.kotlin.native.interop.tool.SHORT_MODULE_NAME import java.io.PrintWriter import java.io.StringWriter import java.nio.file.Files import java.nio.file.Paths import java.util.concurrent.atomic.AtomicInteger import kotlin.system.exitProcess // TODO: We definitely need to unify logging in different parts of the compiler. private class Logger(val level: Level = Level.NORMAL) { fun log(message: String) { println(message) } fun verbose(message: String) { if (level == Level.VERBOSE) { println(message) } } enum class Level { NORMAL, VERBOSE } } private fun Logger.logFailedLibraries(built: Map) { log("Processing platform libraries finished with errors.") built.forEach { (def, status) -> if (status is ProcessingStatus.FAIL) { log(" ${def.name}: ${status.error}") } } } private fun Logger.logStackTrace(error: Throwable) { val stringWriter = StringWriter() error.printStackTrace(PrintWriter(stringWriter)) verbose(stringWriter.toString()) } private enum class CacheKind(val outputKind: CompilerOutputKind) { DYNAMIC_CACHE(CompilerOutputKind.DYNAMIC_CACHE), STATIC_CACHE(CompilerOutputKind.STATIC_CACHE) } // TODO: Use Distribution's paths after compiler update. fun generatePlatformLibraries(args: Array) { // IMPORTANT! These command line keys are used by the Gradle plugin to configure platform libraries generation, // so any changes in them must be reflected at the Gradle plugin side too. // See org.jetbrains.kotlin.gradle.targets.native.internal.PlatformLibrariesGenerator in the Big Kotlin repo. val argParser = ArgParser("generate-platform", prefixStyle = ArgParser.OptionPrefixStyle.JVM) val inputDirectoryPath by argParser.option( ArgType.String, "input-directory", "i", "Input directory. Default value is /konan/platformDef/" ) val outputDirectoryPath by argParser.option( ArgType.String, "output-directory", "o", "Output directory. Default value is /klib/platform/" ) val targetName by argParser.option( ArgType.String, "target", "t", "Compilation target").required() val saveTemps by argParser.option( ArgType.Boolean, "save-temps", "s", "Save temporary files").default(false) val stdlibPath by argParser.option( ArgType.String, "stdlib-path", "S", "Place where stdlib is located. Default value is /klib/common/stdlib" ) val cacheKind by argParser.option( ArgType.Choice(toString = { it.outputKind.visibleName }), "cache-kind", "k", "Type of cache." ).default(CacheKind.DYNAMIC_CACHE) val cacheDirectoryPath by argParser.option( ArgType.String, "cache-directory", "c", "Cache output directory") val mode by argParser.option( ArgType.Choice(), fullName = "mode", shortName = "m", description = "The way interop library is generated." ).default(DEFAULT_MODE) val verbose by argParser.option( ArgType.Boolean, "verbose", "v", "Show verbose log messages" ).default(false) val cacheArgs by argParser.option( ArgType.String, "cache-arg", description = "An argument passed to compiler during cache building. Used only if -cache-directory is specified." ).multiple() val rebuild by argParser.option( ArgType.Boolean, fullName = "rebuild", description = "Rebuild already existing libraries" ).default(false) argParser.parse(args) val distribution = customerDistribution(KonanHomeProvider.determineKonanHome()) val platformManager = PlatformManager(distribution) val target = platformManager.targetByName(targetName) val targetCacheArgs = platformManager.let { target.let(it::loader).additionalCacheFlags } val inputDirectory = inputDirectoryPath?.File() ?: File(distribution.konanSubdir, "platformDef").child(target.visibleName) val outputDirectory = outputDirectoryPath?.File() ?: File(distribution.klib, "platform").child(target.visibleName) val cacheDirectory = cacheDirectoryPath?.File() if (!inputDirectory.exists) throw Error("input directory doesn't exist") if (!outputDirectory.exists) { outputDirectory.mkdirs() } if (cacheDirectory != null && !cacheDirectory.exists) { cacheDirectory.mkdirs() } val stdlibFile = stdlibPath?.File() ?: File(distribution.stdlib) val logger = Logger(if (verbose) Logger.Level.VERBOSE else Logger.Level.NORMAL) val cacheInfo = cacheDirectory?.let { CacheInfo(it, cacheKind.outputKind.visibleName, cacheArgs + targetCacheArgs) } generatePlatformLibraries( target, mode, DirectoriesInfo(inputDirectory, outputDirectory, stdlibFile), cacheInfo, rebuild, saveTemps, logger ) } private sealed class ProcessingStatus { object WAIT: ProcessingStatus() object SUCCESS: ProcessingStatus() object FAILED_DEPENDENCIES: ProcessingStatus() class FAIL(val error: Throwable) : ProcessingStatus() } private data class DirectoriesInfo(val inputDirectory: File, val outputDirectory: File, val stdlib: File) private data class CacheInfo(val cacheDirectory: File, val cacheKind: String, val cacheArgs: List) private class DefFile(val name: String, val depends: MutableList) { override fun toString(): String = "$name: [${depends.joinToString(separator = ", ") { it.name }}]" val libraryName: String get() = "${PlatformLibsInfo.namePrefix}$name" val shortLibraryName: String get() = name } private fun createTempDir(prefix: String, parent: File): File = File(Files.createTempDirectory(Paths.get(parent.absolutePath), prefix).toString()) private fun File.deleteAtomicallyIfPossible(tmpDirectory: File) { // Try to atomically delete the old directory. val tmpToDelete = Files.createTempFile(Paths.get(tmpDirectory.absolutePath), null, null).toFile() if (renameAtomic(this.absolutePath, tmpToDelete.absolutePath, replaceExisting = true)) { tmpToDelete.deleteRecursively() } else { // Can't move to a tmp directory -> delete in a regular way. this.deleteRecursively() } } private fun topoSort(defFiles: List): List { // Do DFS toposort. val markGray = mutableSetOf() val markBlack = mutableSetOf() val result = mutableListOf() fun visit(def: DefFile) { if (markBlack.contains(def)) return if (markGray.contains(def)) throw Error("$def is part of cycle") markGray += def def.depends.forEach { visit(it) } markGray -= def markBlack += def result += def } var index = 0 while (markBlack.size < defFiles.size) { visit(defFiles[index++]) } return result } private fun generateLibrary( target: KonanTarget, mode: GenerationMode, def: DefFile, directories: DirectoriesInfo, tmpDirectory: File, rebuild: Boolean, logger: Logger ) = with(directories) { val defFile = inputDirectory.child("${def.name}.def") val outKlib = outputDirectory.child(def.libraryName) if (outKlib.exists && !rebuild) { logger.verbose("Skip generating ${def.name} as it's already generated") return } val tmpKlib = tmpDirectory.child(def.libraryName) try { val cinteropArgs = arrayOf( "-o", tmpKlib.absolutePath, "-target", target.visibleName, "-def", defFile.absolutePath, "-compiler-option", "-fmodules-cache-path=${tmpDirectory.child("clangModulesCache").absolutePath}", "-repo", outputDirectory.absolutePath, "-no-default-libs", "-no-endorsed-libs", "-Xpurge-user-libs", "-nopack", "-mode", mode.modeName, "-$SHORT_MODULE_NAME", def.shortLibraryName, *def.depends.flatMap { listOf("-l", "$outputDirectory/${it.libraryName}") }.toTypedArray() ) logger.verbose("Run cinterop with args: ${cinteropArgs.joinToString(separator = " ")}") invokeInterop("native", cinteropArgs)?.let { K2Native.mainNoExit(it) } if (rebuild) { outKlib.deleteAtomicallyIfPossible(tmpDirectory) } // Atomically move the generated library to the destination path. if (!renameAtomic(tmpKlib.absolutePath, outKlib.absolutePath, replaceExisting = false)) { tmpKlib.deleteRecursively() } } finally { tmpKlib.deleteRecursively() } } private fun getLibraryCacheDir( libraryName: String, target: KonanTarget, cacheDirectory: File, cacheKind: String ): File { val cacheBaseName = CachedLibraries.getCachedLibraryName(libraryName) val cacheOutputKind = CompilerOutputKind.valueOf(cacheKind.toUpperCase()) return OutputFiles(cacheDirectory.child(cacheBaseName).absolutePath, target, cacheOutputKind).mainFile.File() } private fun buildCache( target: KonanTarget, def: DefFile, outputDirectory: File, cacheInfo: CacheInfo, rebuild: Boolean, logger: Logger ) = with(cacheInfo) { val libraryCacheDir = getLibraryCacheDir(def.name, target, cacheDirectory, cacheKind) if (libraryCacheDir.listFilesOrEmpty.isNotEmpty() && !rebuild) { logger.verbose("Skip precompiling ${def.name} as it's already precompiled") return } if (rebuild) { libraryCacheDir.deleteRecursively() } val compilerArgs = arrayOf( "-p", cacheKind, "-target", target.visibleName, "-repo", outputDirectory.absolutePath, "-Xadd-cache=${outputDirectory.absolutePath}/${def.libraryName}", "-Xcache-directory=${cacheDirectory.absolutePath}", *cacheArgs.toTypedArray() ) logger.verbose("Run compiler with args: ${compilerArgs.joinToString(separator = " ")}") K2Native.mainNoExit(compilerArgs) } private fun buildStdlibCache( target: KonanTarget, stdlib: File, cacheInfo: CacheInfo, logger: Logger ) = with(cacheInfo) { val stdlibCacheFile = getLibraryCacheDir("stdlib", target, cacheDirectory, cacheKind) if (stdlibCacheFile.exists) { logger.verbose("Skip precompiling standard library as it's already precompiled") return } logger.log("Precompiling standard library...") val compilerArgs = arrayOf( "-p", cacheKind, "-target", target.visibleName, "-Xadd-cache=${stdlib.absolutePath}", "-Xcache-directory=${cacheDirectory.absolutePath}", *cacheArgs.toTypedArray() ) logger.verbose("Run compiler with args: ${compilerArgs.joinToString(separator = " ")}") K2Native.mainNoExit(compilerArgs) } private fun generatePlatformLibraries(target: KonanTarget, mode: GenerationMode, directories: DirectoriesInfo, cacheInfo: CacheInfo?, rebuild: Boolean, saveTemps: Boolean, logger: Logger) = with(directories) { if (cacheInfo != null) { buildStdlibCache(target, stdlib, cacheInfo, logger) } logger.verbose("Generating platform libraries from $inputDirectory to $outputDirectory for ${target.visibleName}") if (cacheInfo != null) { logger.verbose("Precompiling platform libraries to ${cacheInfo.cacheDirectory} (cache kind: ${cacheInfo.cacheKind})") } val tmpDirectory = createTempDir("build-", outputDirectory) // Delete the tmp directory in case of execution interruption. val deleteTmpHook = Thread { if (!saveTemps) { tmpDirectory.deleteRecursively() } } Runtime.getRuntime().addShutdownHook(deleteTmpHook) // Build dependencies graph. val defFiles = mutableMapOf() val dependsRegex = Regex("^depends = (.*)") inputDirectory.listFilesOrEmpty.filter { it.extension == "def" }.forEach { file -> val name = file.name.split(".").also { assert(it.size == 2) }[0] val def = defFiles.getOrPut(name) { DefFile(name, mutableListOf()) } file.forEachLine { line -> val match = dependsRegex.matchEntire(line) if (match != null) { match.groupValues[1].split(" ").forEach { dependency -> def.depends.add(defFiles.getOrPut(dependency) { DefFile(dependency, mutableListOf()) }) } } } } val sorted = topoSort(defFiles.values.toList()) val numCores = Runtime.getRuntime().availableProcessors() val executorPool = ThreadPoolExecutor(numCores, numCores, 10, TimeUnit.SECONDS, ArrayBlockingQueue(1000), Executors.defaultThreadFactory(), RejectedExecutionHandler { r, _ -> logger.log("Execution rejected: $r") throw Error("Must not happen!") }) val built = ConcurrentHashMap(sorted.associateWith { ProcessingStatus.WAIT }) // Now run interop tool on toposorted dependencies. val countTotal = sorted.size val countProcessed = AtomicInteger(0) try { tmpDirectory.mkdirs() sorted.forEach { def -> executorPool.execute { // A bit ugly, we just block here until all dependencies are built. while (def.depends.any { built[it] == ProcessingStatus.WAIT }) { Thread.sleep(100) } try { if (def.depends.any { built[it] is ProcessingStatus.FAIL }) { built[def] = ProcessingStatus.FAILED_DEPENDENCIES return@execute } logger.log("Processing ${def.name} (${countProcessed.incrementAndGet()}/$countTotal)...") generateLibrary(target, mode, def, directories, tmpDirectory, rebuild, logger) if (cacheInfo != null) { buildCache(target, def, outputDirectory, cacheInfo, rebuild, logger) } built[def] = ProcessingStatus.SUCCESS } catch (e: Throwable) { built[def] = ProcessingStatus.FAIL(e) logger.logStackTrace(e) } } } executorPool.shutdown() executorPool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) if (built.values.any { it != ProcessingStatus.SUCCESS }) { logger.logFailedLibraries(built) exitProcess(-1) } } finally { if (!saveTemps) { tmpDirectory.deleteRecursively() } Runtime.getRuntime().removeShutdownHook(deleteTmpHook) } } ================================================ FILE: utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.utilities import org.jetbrains.kotlin.cli.bc.SHORT_MODULE_NAME_ARG import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.native.interop.gen.jvm.InternalInteropOptions import org.jetbrains.kotlin.native.interop.gen.jvm.interop import org.jetbrains.kotlin.native.interop.tool.* // TODO: this function should eventually be eliminated from 'utilities'. // The interaction of interop and the compiler should be streamlined. /** * @return null if there is no need in compiler invocation. * Otherwise returns array of compiler args. */ fun invokeInterop(flavor: String, args: Array): Array? { val arguments = if (flavor == "native") CInteropArguments() else JSInteropArguments() arguments.argParser.parse(args) val outputFileName = arguments.output val noDefaultLibs = arguments.nodefaultlibs || arguments.nodefaultlibsDeprecated val noEndorsedLibs = arguments.noendorsedlibs val purgeUserLibs = arguments.purgeUserLibs val nopack = arguments.nopack val temporaryFilesDir = arguments.tempDir val moduleName = (arguments as? CInteropArguments)?.moduleName val shortModuleName = (arguments as? CInteropArguments)?.shortModuleName val buildDir = File("$outputFileName-build") val generatedDir = File(buildDir, "kotlin") val nativesDir = File(buildDir,"natives") val manifest = File(buildDir, "manifest.properties") val cstubsName ="cstubs" val libraries = arguments.library val repos = arguments.repo val targetRequest = if (arguments is CInteropArguments) arguments.target else (arguments as JSInteropArguments).target.toString() val target = PlatformManager(KonanHomeProvider.determineKonanHome()).targetManager(targetRequest).target val cinteropArgsToCompiler = interop(flavor, args, InternalInteropOptions(generatedDir.absolutePath, nativesDir.absolutePath,manifest.path, cstubsName.takeIf { flavor == "native" } ) ) ?: return null // There is no need in compiler invocation if we're generating only metadata. val nativeStubs = if (flavor == "wasm") arrayOf("-include-binary", File(nativesDir, "js_stubs.js").path) else arrayOf("-native-library", File(nativesDir, "$cstubsName.bc").path) return arrayOf( generatedDir.path, "-produce", "library", "-o", outputFileName, "-target", target.visibleName, "-manifest", manifest.path, "-Xtemporary-files-dir=$temporaryFilesDir") + nativeStubs + cinteropArgsToCompiler + libraries.flatMap { listOf("-library", it) } + repos.flatMap { listOf("-repo", it) } + (if (noDefaultLibs) arrayOf("-$NODEFAULTLIBS") else emptyArray()) + (if (noEndorsedLibs) arrayOf("-$NOENDORSEDLIBS") else emptyArray()) + (if (purgeUserLibs) arrayOf("-$PURGE_USER_LIBS") else emptyArray()) + (if (nopack) arrayOf("-$NOPACK") else emptyArray()) + moduleName?.let { arrayOf("-module-name", it) }.orEmpty() + shortModuleName?.let { arrayOf("$SHORT_MODULE_NAME_ARG=$it") }.orEmpty() + arguments.kotlincOption } ================================================ FILE: utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/LlvmClang.kt ================================================ /* * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.utilities import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.target.PlatformManager import org.jetbrains.kotlin.konan.util.KonanHomeProvider fun runLlvmTool(args: Array) { val toolName = args[0] val toolArguments = args.drop(1) val platform = platformManager().hostPlatform val llvmHome = platform.configurables.absoluteLlvmHome val toolPath = "$llvmHome/bin/$toolName" runCommand(toolPath, *toolArguments.toTypedArray()) } fun runLlvmClangToolWithTarget(args: Array) { val toolName = args[0] val targetName = args[1] val toolArguments = args.drop(2) val platformManager = platformManager() val platform = platformManager.platform(platformManager.targetByName(targetName)) val llvmHome = platform.configurables.absoluteLlvmHome val toolPath = "$llvmHome/bin/$toolName" runCommand(toolPath, *platform.clang.clangArgs, *toolArguments.toTypedArray()) } private fun platformManager() = PlatformManager(KonanHomeProvider.determineKonanHome()) private fun runCommand(vararg args: String) { Command(*args) .logWith { println(it()) } .execute() } ================================================ FILE: utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt ================================================ /* * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ package org.jetbrains.kotlin.cli.utilities import org.jetbrains.kotlin.native.interop.gen.defFileDependencies import org.jetbrains.kotlin.cli.bc.main as konancMain import org.jetbrains.kotlin.cli.klib.main as klibMain import org.jetbrains.kotlin.cli.bc.mainNoExitWithGradleRenderer as konancMainForGradle private fun mainImpl(args: Array, konancMain: (Array) -> Unit) { val utilityName = args[0] val utilityArgs = args.drop(1).toTypedArray() when (utilityName) { "konanc" -> konancMain(utilityArgs) "kotlinc" -> { println(""" NOTE: you are running "kotlinc" CLI tool from Kotlin/Native distribution, it runs Kotlin/Native compiler that produces native binaries from Kotlin code. If your intention was to compile Kotlin code to JVM bytecode instead, then you need to use "kotlinc" from the main Kotlin distribution (e.g. it can be downloaded as kotlin-compiler-X.Y.ZZ.zip archive from https://github.com/JetBrains/kotlin/releases/latest, or installed using various package managers). WARNING: if your intention was to run Kotlin/Native compiler, then please use "kotlinc-native" CLI tool instead of "kotlinc". "kotlinc" tool will be removed from Kotlin/Native distribution, so it will stop clashing with "kotlinc" from the main Kotlin distribution. """.trimIndent()) konancMain(utilityArgs) } "cinterop" -> { val konancArgs = invokeInterop("native", utilityArgs) konancArgs?.let { konancMain(it) } } "jsinterop" -> { val konancArgs = invokeInterop("wasm", utilityArgs) konancArgs?.let { konancMain(it) } } "klib" -> klibMain(utilityArgs) "defFileDependencies" -> defFileDependencies(utilityArgs) "generatePlatformLibraries" -> generatePlatformLibraries(utilityArgs) "llvm" -> runLlvmTool(utilityArgs) "clang" -> runLlvmClangToolWithTarget(utilityArgs) else -> error("Unexpected utility name") } } fun main(args: Array) = mainImpl(args, ::konancMain) fun daemonMain(args: Array) = mainImpl(args, ::konancMainForGradle) ================================================ FILE: utilities/env_blacklist ================================================ ADDITIONAL_SDKS APPLICATION_EXTENSION_API_ONLY ARCHS ARCHS_STANDARD ARCHS_STANDARD_32_64_BIT ARCHS_STANDARD_32_BIT ARCHS_STANDARD_64_BIT ARCHS_STANDARD_INCLUDING_64_BIT ARCHS_UNIVERSAL_IPHONE_OS CLANG_ANALYZER_NONNULL CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION CLANG_CXX_LANGUAGE_STANDARD CLANG_CXX_LIBRARY CLANG_ENABLE_MODULES CLANG_ENABLE_OBJC_ARC CLANG_MODULES_BUILD_SESSION_FILE CLANG_WARN_BOOL_CONVERSION CLANG_WARN_CONSTANT_CONVERSION CLANG_WARN_DIRECT_OBJC_ISA_USAGE CLANG_WARN_DOCUMENTATION_COMMENTS CLANG_WARN_EMPTY_BODY CLANG_WARN_ENUM_CONVERSION CLANG_WARN_INFINITE_RECURSION CLANG_WARN_INT_CONVERSION CLANG_WARN_OBJC_ROOT_CLASS CLANG_WARN_SUSPICIOUS_MOVE CLANG_WARN_UNREACHABLE_CODE CLANG_WARN__DUPLICATE_METHOD_MATCH CURRENT_ARCH DEVELOPER_APPLICATIONS_DIR DEVELOPER_BIN_DIR DEVELOPER_FRAMEWORKS_DIR DEVELOPER_FRAMEWORKS_DIR_QUOTED DEVELOPER_LIBRARY_DIR DEVELOPER_SDK_DIR DEVELOPER_TOOLS_DIR DEVELOPER_USR_DIR DT_TOOLCHAIN_DIR ENABLE_BITCODE ENABLE_DEFAULT_HEADER_SEARCH_PATHS ENABLE_STRICT_OBJC_MSGSEND FRAMEWORK_SEARCH_PATHS GENERATE_MASTER_OBJECT_FILE GENERATE_PROFILING_CODE HEADER_SEARCH_PATHS INLINE_PRIVATE_FRAMEWORKS KEEP_PRIVATE_EXTERNS LD_NO_PIE LD_RUNPATH_SEARCH_PATHS LINK_WITH_STANDARD_LIBRARIES MACH_O_TYPE NATIVE_ARCH NATIVE_ARCH_32_BIT NATIVE_ARCH_64_BIT NATIVE_ARCH_ACTUAL NO_COMMON ONLY_ACTIVE_ARCH PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES PLATFORM_DEVELOPER_APPLICATIONS_DIR PLATFORM_DEVELOPER_BIN_DIR PLATFORM_DEVELOPER_LIBRARY_DIR PLATFORM_DEVELOPER_SDK_DIR PLATFORM_DEVELOPER_TOOLS_DIR PLATFORM_DEVELOPER_USR_DIR PLATFORM_DIR SDKROOT SDK_DIR SDK_DIR_iphoneos11_0 SDK_NAME SDK_NAMES SDK_PRODUCT_BUILD_VERSION SDK_VERSION SDK_VERSION_ACTUAL SDK_VERSION_MAJOR SDK_VERSION_MINOR SHARED_DERIVED_FILE_DIR SHARED_FRAMEWORKS_FOLDER_PATH SHARED_PRECOMPS_DIR SHARED_SUPPORT_FOLDER_PATH SYSTEM_ADMIN_APPS_DIR SYSTEM_APPS_DIR SYSTEM_CORE_SERVICES_DIR SYSTEM_DEMOS_DIR SYSTEM_DEVELOPER_APPS_DIR SYSTEM_DEVELOPER_BIN_DIR SYSTEM_DEVELOPER_DEMOS_DIR SYSTEM_DEVELOPER_DIR SYSTEM_DEVELOPER_DOC_DIR SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR SYSTEM_DEVELOPER_JAVA_TOOLS_DIR SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR SYSTEM_DEVELOPER_RELEASENOTES_DIR SYSTEM_DEVELOPER_TOOLS SYSTEM_DEVELOPER_TOOLS_DOC_DIR SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR SYSTEM_DEVELOPER_USR_DIR SYSTEM_DEVELOPER_UTILITIES_DIR SYSTEM_DOCUMENTATION_DIR SYSTEM_KEXT_INSTALL_PATH SYSTEM_LIBRARY_DIR TOOLCHAINS TOOLCHAIN_DIR USE_DYNAMIC_NO_PIC USE_HEADERMAP VALID_ARCHS XCODE_APP_SUPPORT_DIR